Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/xs
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2018-09-12 12:59:02 +0300
committerbubnikv <bubnikv@gmail.com>2018-09-12 12:59:02 +0300
commit0235f1a8211cfecf75ac0a585295bc1378747972 (patch)
tree9c1d06a43a691d9691c7eff6f21646b0dcc8cc74 /xs
parent41ce69f327a2fe3324dc47756b64a6fdb001cfa3 (diff)
parenta97df55592f524eb73bd7d04ef8b7c1b3525d27d (diff)
Merged with dev
Diffstat (limited to 'xs')
-rw-r--r--xs/CMakeLists.txt225
-rw-r--r--xs/lib/Slic3r/XS.pm15
-rw-r--r--xs/src/Shiny/ShinyPrereqs.h3
-rw-r--r--xs/src/Shiny/ShinyTools.c5
-rw-r--r--xs/src/admesh/connect.cpp335
-rw-r--r--xs/src/admesh/normals.cpp106
-rw-r--r--xs/src/admesh/shared.cpp8
-rw-r--r--xs/src/admesh/stl.h60
-rw-r--r--xs/src/admesh/stl_io.cpp95
-rw-r--r--xs/src/admesh/stlinit.cpp132
-rw-r--r--xs/src/admesh/util.cpp407
-rw-r--r--xs/src/agg/AUTHORS2
-rw-r--r--xs/src/agg/VERSION2
-rw-r--r--xs/src/agg/agg_array.h1119
-rw-r--r--xs/src/agg/agg_basics.h574
-rw-r--r--xs/src/agg/agg_bezier_arc.h159
-rw-r--r--xs/src/agg/agg_clip_liang_barsky.h333
-rw-r--r--xs/src/agg/agg_color_gray.h1047
-rw-r--r--xs/src/agg/agg_color_rgba.h1353
-rw-r--r--xs/src/agg/agg_config.h44
-rw-r--r--xs/src/agg/agg_conv_transform.h68
-rw-r--r--xs/src/agg/agg_gamma_functions.h132
-rw-r--r--xs/src/agg/agg_gamma_lut.h300
-rw-r--r--xs/src/agg/agg_math.h437
-rw-r--r--xs/src/agg/agg_path_storage.h1582
-rw-r--r--xs/src/agg/agg_pixfmt_base.h97
-rw-r--r--xs/src/agg/agg_pixfmt_gray.h738
-rw-r--r--xs/src/agg/agg_pixfmt_rgb.h995
-rw-r--r--xs/src/agg/agg_rasterizer_cells_aa.h741
-rw-r--r--xs/src/agg/agg_rasterizer_scanline_aa.h481
-rw-r--r--xs/src/agg/agg_rasterizer_scanline_aa_nogamma.h483
-rw-r--r--xs/src/agg/agg_rasterizer_sl_clip.h351
-rw-r--r--xs/src/agg/agg_renderer_base.h731
-rw-r--r--xs/src/agg/agg_renderer_scanline.h854
-rw-r--r--xs/src/agg/agg_rendering_buffer.h300
-rw-r--r--xs/src/agg/agg_scanline_p.h329
-rw-r--r--xs/src/agg/agg_trans_affine.h518
-rw-r--r--xs/src/agg/copying65
-rw-r--r--xs/src/avrdude/AUTHORS28
-rw-r--r--xs/src/avrdude/BUILD-FROM-SVN13
-rw-r--r--xs/src/avrdude/CMakeLists.txt87
-rw-r--r--xs/src/avrdude/COPYING339
-rw-r--r--xs/src/avrdude/ChangeLog90
-rw-r--r--xs/src/avrdude/ChangeLog-2001598
-rw-r--r--xs/src/avrdude/ChangeLog-2002237
-rw-r--r--xs/src/avrdude/ChangeLog-20031095
-rw-r--r--xs/src/avrdude/ChangeLog-2004-20061644
-rw-r--r--xs/src/avrdude/ChangeLog-2007364
-rw-r--r--xs/src/avrdude/ChangeLog-2008185
-rw-r--r--xs/src/avrdude/ChangeLog-2009411
-rw-r--r--xs/src/avrdude/ChangeLog-2010354
-rw-r--r--xs/src/avrdude/ChangeLog-2011489
-rw-r--r--xs/src/avrdude/ChangeLog-2012729
-rw-r--r--xs/src/avrdude/ChangeLog-2013618
-rw-r--r--xs/src/avrdude/ChangeLog-2014697
-rw-r--r--xs/src/avrdude/ChangeLog-201554
-rw-r--r--xs/src/avrdude/Makefile.am206
-rw-r--r--xs/src/avrdude/Makefile.standalone54
-rw-r--r--xs/src/avrdude/NEWS913
-rw-r--r--xs/src/avrdude/README64
-rw-r--r--xs/src/avrdude/ac_cfg.h206
-rw-r--r--xs/src/avrdude/ac_cfg.h.in194
-rw-r--r--xs/src/avrdude/arduino.c188
-rw-r--r--xs/src/avrdude/arduino.h29
-rw-r--r--xs/src/avrdude/atmel-docs/AVR109.pdfbin0 -> 94446 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/AVR910.pdfbin0 -> 224606 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/AVRISPmkII-AVR069.pdfbin0 -> 326430 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/browserDetect.js116
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/css/960.css1
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/css/docbook.css227
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/css/fluid_grid.css154
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/css/index.css59
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/css/positioning.css493
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/css/print.css28
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/css/reset.css1
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/css/text.css1
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.eotbin0 -> 78514 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.ttfbin0 -> 78296 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/Book_Closed.pngbin0 -> 3245 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/Book_Open.pngbin0 -> 703 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/Document_Text.pngbin0 -> 583 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/Library.pngbin0 -> 798 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/external_link.gifbin0 -> 98 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/loading.gifbin0 -> 1553 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/logo.pngbin0 -> 4305 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/minus.pngbin0 -> 156 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/next-arrow.pngbin0 -> 199 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/plus.pngbin0 -> 164 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/previous-arrow.pngbin0 -> 198 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/search-icon.pngbin0 -> 340 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/sidebar.pngbin0 -> 177 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/starsSmall.pngbin0 -> 1032 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/toc-icon.pngbin0 -> 3447 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/images/ui-icons_217bc0_256x240.pngbin0 -> 4369 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery-1.7.2.min.js4
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery.cookie.js93
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery.ui.all.js418
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/layout/jquery.layout.js5449
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-anim_basic_16x16.gifbin0 -> 1553 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_flat_0_aaaaaa_40x100.pngbin0 -> 180 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_flat_55_fbec88_40x100.pngbin0 -> 182 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_75_d0e5f5_1x400.pngbin0 -> 162 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_85_dfeffc_1x400.pngbin0 -> 123 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_95_fef1ec_1x400.pngbin0 -> 119 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.pngbin0 -> 3457 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.pngbin0 -> 104 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.pngbin0 -> 88 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_217bc0_256x240.pngbin0 -> 4369 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_2e83ff_256x240.pngbin0 -> 4369 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_469bdd_256x240.pngbin0 -> 4369 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_6da8d5_256x240.pngbin0 -> 5355 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_cd0a0a_256x240.pngbin0 -> 4369 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_d8e7f3_256x240.pngbin0 -> 4369 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_f9bd01_256x240.pngbin0 -> 5355 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css398
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/file.gifbin0 -> 1008 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/folder-closed.gifbin0 -> 631 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/folder.gifbin0 -> 631 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-black-line.gifbin0 -> 1877 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-black.gifbin0 -> 1216 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-default-line.gifbin0 -> 1993 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-default.gifbin0 -> 1222 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-famfamfam-line.gifbin0 -> 807 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-famfamfam.gifbin0 -> 1280 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-gray-line.gifbin0 -> 1877 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-gray.gifbin0 -> 1230 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-red-line.gifbin0 -> 1877 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-red.gifbin0 -> 1230 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/jquery.treeview.css85
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/jquery.treeview.min.js16
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/main.js282
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/common/splitterInit.js40
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch01s01.html218
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch01s02.html234
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s01.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02s01.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s03.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s04.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s01.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s02.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s03.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s04.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s05.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s06.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s07.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s08.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s09.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s01.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s02.html218
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s03.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s01.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s01.html~215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s02.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s03.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s03s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s03.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s04.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s01.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s02.html228
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s03.html218
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s01.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s03.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s04.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s05.html236
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s01.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s03.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s04.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s02.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s03.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s04.html217
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s05.html217
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s03.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s04.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s01.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s02.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s03.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s09.html220
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s10.html310
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s01.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s02.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s03.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s04.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s05.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s06.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s07.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s08.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s09.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s10.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s11.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s12.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s13.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s14.html217
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s15.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s03.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s04.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s05.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s06.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s01.html219
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s02.html224
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s03.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s04.html360
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s01.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s02.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s03.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s04.html217
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s05.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s06.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s07.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s08.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s09.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s10.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s11.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s12.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s13.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s14.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s15.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s16.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s17.html217
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s18.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s19.html220
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s20.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s21.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s22.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s23.html215
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s24.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s25.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s26.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s27.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s28.html216
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s29.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s03.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s04.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s05.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03s01.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s01.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s02.html219
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s03.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s01.html227
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s02.html231
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s03.html219
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s04.html220
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s05.html231
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s06.html423
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s03.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s04.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s05.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s06.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s07.html231
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s08.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s09.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s10.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s11.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s12.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s13.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s14.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s15.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s16.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s17.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s03.html253
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s01.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s03.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s04.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s05.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s06.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s02.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s03.html240
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/document.revisions.html209
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/index.html227
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/pr01.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.Introduction.html209
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avr32protocol.html212
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avr8protocol.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avrispprotocol.html219
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avrprotocol.Overview.html209
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.cmsis_dap.html209
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.edbg_ctrl_protocol.html210
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.tpiprotocol.html213
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/htmlFileInfoList.js392
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-1.js851
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-2.js850
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-3.js846
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/l10n.js3
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/nwSearchFnt.js886
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/stemmers/en_stemmer.js234
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr32_memtypes.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr32_setget_params.html217
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_memtypes.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_query_contexts.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_setget_params.html231
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_edbg_ctrl_setget_params.html368
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_edbg_query_contexts.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_housekeeping_start_session.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_i5v_3yz_rl.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_jdx_m11_sl.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_qhb_x1c_sl.html211
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_serial_trace.html214
-rw-r--r--xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_t1f_hb1_sl.html211
-rw-r--r--xs/src/avrdude/atmel-docs/JTAGICE-AVR060.pdfbin0 -> 139206 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/JTAGICEmkII-AVR067.pdfbin0 -> 327125 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/STK500-AVR061.pdfbin0 -> 814798 bytes
-rw-r--r--xs/src/avrdude/atmel-docs/STK500v2-AVR068.pdfbin0 -> 161607 bytes
-rw-r--r--xs/src/avrdude/avr.c1254
-rw-r--r--xs/src/avrdude/avr910.c777
-rw-r--r--xs/src/avrdude/avr910.h35
-rw-r--r--xs/src/avrdude/avrdude-slic3r.cpp258
-rw-r--r--xs/src/avrdude/avrdude-slic3r.hpp82
-rw-r--r--xs/src/avrdude/avrdude.11133
-rw-r--r--xs/src/avrdude/avrdude.conf14982
-rw-r--r--xs/src/avrdude/avrdude.conf.in14984
-rw-r--r--xs/src/avrdude/avrdude.conf.tmp14984
-rw-r--r--xs/src/avrdude/avrdude.h89
-rw-r--r--xs/src/avrdude/avrdude.spec.in113
-rw-r--r--xs/src/avrdude/avrftdi.c1275
-rw-r--r--xs/src/avrdude/avrftdi.h40
-rw-r--r--xs/src/avrdude/avrftdi_private.h86
-rw-r--r--xs/src/avrdude/avrftdi_tpi.c254
-rw-r--r--xs/src/avrdude/avrftdi_tpi.h9
-rw-r--r--xs/src/avrdude/avrpart.c686
-rw-r--r--xs/src/avrdude/bitbang.c655
-rw-r--r--xs/src/avrdude/bitbang.h58
-rwxr-xr-xxs/src/avrdude/bootstrap21
-rw-r--r--xs/src/avrdude/buspirate.c1372
-rw-r--r--xs/src/avrdude/buspirate.h32
-rw-r--r--xs/src/avrdude/butterfly.c763
-rw-r--r--xs/src/avrdude/butterfly.h37
-rw-r--r--xs/src/avrdude/config.c349
-rw-r--r--xs/src/avrdude/config.h103
-rw-r--r--xs/src/avrdude/config_gram.c3718
-rw-r--r--xs/src/avrdude/config_gram.h330
-rw-r--r--xs/src/avrdude/config_gram.y1571
-rw-r--r--xs/src/avrdude/configure.ac572
-rw-r--r--xs/src/avrdude/confwin.c54
-rw-r--r--xs/src/avrdude/crc16.c83
-rw-r--r--xs/src/avrdude/crc16.h34
-rw-r--r--xs/src/avrdude/dfu.c516
-rw-r--r--xs/src/avrdude/dfu.h137
-rw-r--r--xs/src/avrdude/doc/.cvsignore25
-rw-r--r--xs/src/avrdude/doc/Makefile.am94
-rw-r--r--xs/src/avrdude/doc/TODO26
-rw-r--r--xs/src/avrdude/doc/avrdude.texi2586
-rw-r--r--xs/src/avrdude/doc/parts_comments.txt5
-rw-r--r--xs/src/avrdude/fileio.c1663
-rw-r--r--xs/src/avrdude/flip1.c949
-rw-r--r--xs/src/avrdude/flip1.h35
-rw-r--r--xs/src/avrdude/flip2.c1002
-rw-r--r--xs/src/avrdude/flip2.h35
-rw-r--r--xs/src/avrdude/freebsd_ppi.h39
-rw-r--r--xs/src/avrdude/ft245r.c963
-rw-r--r--xs/src/avrdude/ft245r.h8
-rw-r--r--xs/src/avrdude/jtag3.c2286
-rw-r--r--xs/src/avrdude/jtag3.h60
-rw-r--r--xs/src/avrdude/jtag3_private.h319
-rw-r--r--xs/src/avrdude/jtagmkI.c1365
-rw-r--r--xs/src/avrdude/jtagmkI.h36
-rw-r--r--xs/src/avrdude/jtagmkII.c4023
-rw-r--r--xs/src/avrdude/jtagmkII.h63
-rw-r--r--xs/src/avrdude/jtagmkII_private.h385
-rw-r--r--xs/src/avrdude/jtagmkI_private.h168
-rw-r--r--xs/src/avrdude/lexer.c3068
-rw-r--r--xs/src/avrdude/lexer.l262
-rw-r--r--xs/src/avrdude/libavrdude.h973
-rw-r--r--xs/src/avrdude/linux_ppdev.h57
-rw-r--r--xs/src/avrdude/linuxgpio.c354
-rw-r--r--xs/src/avrdude/linuxgpio.h36
-rw-r--r--xs/src/avrdude/lists.c1407
-rw-r--r--xs/src/avrdude/main-standalone.c9
-rw-r--r--xs/src/avrdude/main.c1537
-rw-r--r--xs/src/avrdude/my_ddk_hidsdi.h48
-rw-r--r--xs/src/avrdude/par.c411
-rw-r--r--xs/src/avrdude/par.h35
-rw-r--r--xs/src/avrdude/pgm.c333
-rw-r--r--xs/src/avrdude/pgm_type.c153
-rw-r--r--xs/src/avrdude/pickit2.c1340
-rw-r--r--xs/src/avrdude/pickit2.h35
-rw-r--r--xs/src/avrdude/pindefs.c370
-rw-r--r--xs/src/avrdude/ppi.c236
-rw-r--r--xs/src/avrdude/ppi.h59
-rw-r--r--xs/src/avrdude/ppiwin.c417
-rw-r--r--xs/src/avrdude/safemode.c318
-rw-r--r--xs/src/avrdude/ser_avrdoper.c661
-rw-r--r--xs/src/avrdude/ser_posix.c524
-rw-r--r--xs/src/avrdude/ser_win32.c709
-rw-r--r--xs/src/avrdude/serbb.h37
-rw-r--r--xs/src/avrdude/serbb_posix.c321
-rw-r--r--xs/src/avrdude/serbb_win32.c366
-rw-r--r--xs/src/avrdude/solaris_ecpp.h50
-rw-r--r--xs/src/avrdude/stk500.c1349
-rw-r--r--xs/src/avrdude/stk500.h41
-rw-r--r--xs/src/avrdude/stk500_private.h103
-rw-r--r--xs/src/avrdude/stk500generic.c90
-rw-r--r--xs/src/avrdude/stk500generic.h29
-rw-r--r--xs/src/avrdude/stk500v2.c4798
-rw-r--r--xs/src/avrdude/stk500v2.h65
-rw-r--r--xs/src/avrdude/stk500v2_private.h331
-rw-r--r--xs/src/avrdude/term.c957
-rw-r--r--xs/src/avrdude/term.h37
-rwxr-xr-xxs/src/avrdude/tools/build-mingw32.sh54
-rw-r--r--xs/src/avrdude/tools/get-dw-params.xsl155
-rw-r--r--xs/src/avrdude/tools/get-hv-params.xsl254
-rw-r--r--xs/src/avrdude/tools/get-stk600-cards.xsl62
-rw-r--r--xs/src/avrdude/tools/get-stk600-devices.xsl51
-rw-r--r--xs/src/avrdude/tpi.h76
-rw-r--r--xs/src/avrdude/update.c412
-rw-r--r--xs/src/avrdude/usb_hidapi.c357
-rw-r--r--xs/src/avrdude/usb_libusb.c615
-rw-r--r--xs/src/avrdude/usbasp.c1221
-rw-r--r--xs/src/avrdude/usbasp.h137
-rw-r--r--xs/src/avrdude/usbdevs.h83
-rw-r--r--xs/src/avrdude/usbtiny.c589
-rw-r--r--xs/src/avrdude/usbtiny.h68
-rw-r--r--xs/src/avrdude/windows/.cvsignore4
-rw-r--r--xs/src/avrdude/windows/Makefile.am57
-rw-r--r--xs/src/avrdude/windows/getopt.c1258
-rw-r--r--xs/src/avrdude/windows/getopt.h188
-rw-r--r--xs/src/avrdude/windows/giveio.c168
-rw-r--r--xs/src/avrdude/windows/giveio.sysbin0 -> 5248 bytes
-rwxr-xr-xxs/src/avrdude/windows/install_giveio.bat34
-rw-r--r--xs/src/avrdude/windows/loaddrv.c460
-rw-r--r--xs/src/avrdude/windows/loaddrv.h20
-rwxr-xr-xxs/src/avrdude/windows/remove_giveio.bat14
-rwxr-xr-xxs/src/avrdude/windows/status_giveio.bat12
-rw-r--r--xs/src/avrdude/windows/unistd.cpp44
-rw-r--r--xs/src/avrdude/windows/unistd.h85
-rw-r--r--xs/src/avrdude/wiring.c224
-rw-r--r--xs/src/avrdude/wiring.h29
-rw-r--r--xs/src/benchmark.h58
-rw-r--r--xs/src/eigen/Eigen/Cholesky5
-rw-r--r--xs/src/eigen/Eigen/Core23
-rw-r--r--xs/src/eigen/Eigen/Eigenvalues4
-rw-r--r--xs/src/eigen/Eigen/LU4
-rw-r--r--xs/src/eigen/Eigen/QR4
-rw-r--r--xs/src/eigen/Eigen/QtAlignedMalloc2
-rw-r--r--xs/src/eigen/Eigen/SVD4
-rw-r--r--xs/src/eigen/Eigen/src/Cholesky/LDLT.h11
-rw-r--r--xs/src/eigen/Eigen/src/Cholesky/LLT.h26
-rw-r--r--xs/src/eigen/Eigen/src/Core/Array.h8
-rw-r--r--xs/src/eigen/Eigen/src/Core/ArrayBase.h8
-rw-r--r--xs/src/eigen/Eigen/src/Core/ArrayWrapper.h6
-rw-r--r--xs/src/eigen/Eigen/src/Core/AssignEvaluator.h4
-rw-r--r--xs/src/eigen/Eigen/src/Core/Assign_MKL.h6
-rw-r--r--xs/src/eigen/Eigen/src/Core/CoreEvaluators.h39
-rw-r--r--xs/src/eigen/Eigen/src/Core/CwiseNullaryOp.h80
-rw-r--r--xs/src/eigen/Eigen/src/Core/DenseBase.h8
-rw-r--r--xs/src/eigen/Eigen/src/Core/Diagonal.h5
-rw-r--r--xs/src/eigen/Eigen/src/Core/Dot.h17
-rw-r--r--xs/src/eigen/Eigen/src/Core/EigenBase.h4
-rw-r--r--xs/src/eigen/Eigen/src/Core/GeneralProduct.h21
-rw-r--r--xs/src/eigen/Eigen/src/Core/GenericPacketMath.h6
-rw-r--r--xs/src/eigen/Eigen/src/Core/Map.h17
-rw-r--r--xs/src/eigen/Eigen/src/Core/MathFunctions.h43
-rw-r--r--xs/src/eigen/Eigen/src/Core/MathFunctionsImpl.h23
-rw-r--r--xs/src/eigen/Eigen/src/Core/MatrixBase.h13
-rw-r--r--xs/src/eigen/Eigen/src/Core/NumTraits.h2
-rw-r--r--xs/src/eigen/Eigen/src/Core/PlainObjectBase.h4
-rw-r--r--xs/src/eigen/Eigen/src/Core/Product.h10
-rw-r--r--xs/src/eigen/Eigen/src/Core/ProductEvaluators.h37
-rw-r--r--xs/src/eigen/Eigen/src/Core/Redux.h2
-rw-r--r--xs/src/eigen/Eigen/src/Core/Ref.h2
-rw-r--r--xs/src/eigen/Eigen/src/Core/SelfAdjointView.h6
-rw-r--r--xs/src/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h12
-rw-r--r--xs/src/eigen/Eigen/src/Core/Solve.h4
-rw-r--r--xs/src/eigen/Eigen/src/Core/StableNorm.h5
-rw-r--r--xs/src/eigen/Eigen/src/Core/Transpositions.h2
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/AVX/Complex.h36
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/AVX/PacketMath.h11
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h33
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h6
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/AltiVec/Complex.h35
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h44
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/CUDA/Half.h112
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/CUDA/PacketMath.h2
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h2
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/Default/ConjHelper.h29
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/NEON/Complex.h12
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/NEON/PacketMath.h46
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/SSE/Complex.h40
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/SSE/PacketMath.h22
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/SSE/TypeCasting.h28
-rw-r--r--xs/src/eigen/Eigen/src/Core/arch/ZVector/Complex.h3
-rw-r--r--xs/src/eigen/Eigen/src/Core/functors/BinaryFunctors.h25
-rw-r--r--xs/src/eigen/Eigen/src/Core/functors/NullaryFunctors.h11
-rw-r--r--xs/src/eigen/Eigen/src/Core/functors/StlFunctors.h4
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h13
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h10
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h19
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/GeneralMatrixVector.h8
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h19
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h48
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h9
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h35
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h39
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/TriangularMatrixVector.h22
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h46
-rw-r--r--xs/src/eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h40
-rw-r--r--xs/src/eigen/Eigen/src/Core/util/MKL_support.h10
-rw-r--r--xs/src/eigen/Eigen/src/Core/util/Macros.h19
-rw-r--r--xs/src/eigen/Eigen/src/Core/util/Memory.h14
-rw-r--r--xs/src/eigen/Eigen/src/Core/util/Meta.h20
-rw-r--r--xs/src/eigen/Eigen/src/Core/util/StaticAssert.h120
-rw-r--r--xs/src/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h5
-rw-r--r--xs/src/eigen/Eigen/src/Eigenvalues/RealSchur.h4
-rw-r--r--xs/src/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h23
-rw-r--r--xs/src/eigen/Eigen/src/Geometry/AngleAxis.h2
-rw-r--r--xs/src/eigen/Eigen/src/Geometry/Quaternion.h39
-rw-r--r--xs/src/eigen/Eigen/src/Geometry/arch/Geometry_SSE.h60
-rw-r--r--xs/src/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h27
-rw-r--r--xs/src/eigen/Eigen/src/Jacobi/Jacobi.h236
-rw-r--r--xs/src/eigen/Eigen/src/LU/InverseImpl.h2
-rw-r--r--xs/src/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h2
-rw-r--r--xs/src/eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h8
-rw-r--r--xs/src/eigen/Eigen/src/QR/ColPivHouseholderQR.h12
-rw-r--r--xs/src/eigen/Eigen/src/SVD/BDCSVD.h114
-rw-r--r--xs/src/eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h5
-rw-r--r--xs/src/eigen/Eigen/src/SVD/UpperBidiagonalization.h4
-rw-r--r--xs/src/eigen/Eigen/src/SparseCore/AmbiVector.h2
-rw-r--r--xs/src/eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h67
-rw-r--r--xs/src/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h11
-rw-r--r--xs/src/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h22
-rw-r--r--xs/src/eigen/Eigen/src/SparseQR/SparseQR.h26
-rw-r--r--xs/src/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h101
-rw-r--r--xs/src/eigen/README.md2
-rw-r--r--xs/src/libnest2d/CMakeLists.txt135
-rw-r--r--xs/src/libnest2d/LICENSE.txt661
-rw-r--r--xs/src/libnest2d/README.md43
-rw-r--r--xs/src/libnest2d/cmake_modules/DownloadNLopt.cmake32
-rw-r--r--xs/src/libnest2d/cmake_modules/DownloadProject.CMakeLists.cmake.in17
-rw-r--r--xs/src/libnest2d/cmake_modules/DownloadProject.cmake182
-rw-r--r--xs/src/libnest2d/cmake_modules/FindClipper.cmake50
-rw-r--r--xs/src/libnest2d/cmake_modules/FindNLopt.cmake125
-rw-r--r--xs/src/libnest2d/cmake_modules/FindTBB.cmake322
-rw-r--r--xs/src/libnest2d/examples/main.cpp218
-rw-r--r--xs/src/libnest2d/libnest2d.h42
-rw-r--r--xs/src/libnest2d/libnest2d/boost_alg.hpp518
-rw-r--r--xs/src/libnest2d/libnest2d/clipper_backend/CMakeLists.txt48
-rw-r--r--xs/src/libnest2d/libnest2d/clipper_backend/clipper_backend.hpp460
-rw-r--r--xs/src/libnest2d/libnest2d/common.hpp202
-rw-r--r--xs/src/libnest2d/libnest2d/geometry_traits.hpp825
-rw-r--r--xs/src/libnest2d/libnest2d/geometry_traits_nfp.hpp558
-rw-r--r--xs/src/libnest2d/libnest2d/libnest2d.hpp980
-rw-r--r--xs/src/libnest2d/libnest2d/metaloop.hpp227
-rw-r--r--xs/src/libnest2d/libnest2d/optimizer.hpp247
-rw-r--r--xs/src/libnest2d/libnest2d/optimizers/genetic.hpp31
-rw-r--r--xs/src/libnest2d/libnest2d/optimizers/nlopt_boilerplate.hpp186
-rw-r--r--xs/src/libnest2d/libnest2d/optimizers/simplex.hpp20
-rw-r--r--xs/src/libnest2d/libnest2d/optimizers/subplex.hpp20
-rw-r--r--xs/src/libnest2d/libnest2d/placers/bottomleftplacer.hpp412
-rw-r--r--xs/src/libnest2d/libnest2d/placers/nfpplacer.hpp1205
-rw-r--r--xs/src/libnest2d/libnest2d/placers/placer_boilerplate.hpp134
-rw-r--r--xs/src/libnest2d/libnest2d/rotfinder.hpp41
-rw-r--r--xs/src/libnest2d/libnest2d/selections/djd_heuristic.hpp717
-rw-r--r--xs/src/libnest2d/libnest2d/selections/filler.hpp80
-rw-r--r--xs/src/libnest2d/libnest2d/selections/firstfit.hpp97
-rw-r--r--xs/src/libnest2d/libnest2d/selections/selection_boilerplate.hpp41
-rw-r--r--xs/src/libnest2d/tests/CMakeLists.txt51
-rw-r--r--xs/src/libnest2d/tests/printer_parts.cpp3175
-rw-r--r--xs/src/libnest2d/tests/printer_parts.h40
-rw-r--r--xs/src/libnest2d/tests/test.cpp847
-rw-r--r--xs/src/libnest2d/tools/benchmark.h58
-rw-r--r--xs/src/libnest2d/tools/libnfpglue.cpp157
-rw-r--r--xs/src/libnest2d/tools/libnfpglue.hpp46
-rw-r--r--xs/src/libnest2d/tools/libnfporb/LICENSE674
-rw-r--r--xs/src/libnest2d/tools/libnfporb/ORIGIN2
-rw-r--r--xs/src/libnest2d/tools/libnfporb/README.md89
-rw-r--r--xs/src/libnest2d/tools/libnfporb/libnfporb.hpp1547
-rw-r--r--xs/src/libnest2d/tools/nfp_svgnest.hpp1018
-rw-r--r--xs/src/libnest2d/tools/nfp_svgnest_glue.hpp75
-rw-r--r--xs/src/libnest2d/tools/svgtools.hpp122
-rw-r--r--xs/src/libslic3r/BoundingBox.cpp187
-rw-r--r--xs/src/libslic3r/BoundingBox.hpp95
-rw-r--r--xs/src/libslic3r/BridgeDetector.cpp26
-rw-r--r--xs/src/libslic3r/ClipperUtils.cpp45
-rw-r--r--xs/src/libslic3r/ClipperUtils.hpp3
-rw-r--r--xs/src/libslic3r/Config.cpp92
-rw-r--r--xs/src/libslic3r/Config.hpp90
-rw-r--r--xs/src/libslic3r/EdgeGrid.cpp298
-rw-r--r--xs/src/libslic3r/ExPolygon.cpp193
-rw-r--r--xs/src/libslic3r/ExPolygon.hpp1
-rw-r--r--xs/src/libslic3r/ExtrusionEntity.cpp2
-rw-r--r--xs/src/libslic3r/ExtrusionEntity.hpp4
-rw-r--r--xs/src/libslic3r/ExtrusionEntityCollection.cpp1
-rw-r--r--xs/src/libslic3r/ExtrusionEntityCollection.hpp12
-rw-r--r--xs/src/libslic3r/ExtrusionSimulator.cpp44
-rw-r--r--xs/src/libslic3r/FileParserError.hpp52
-rw-r--r--xs/src/libslic3r/Fill/Fill3DHoneycomb.cpp18
-rw-r--r--xs/src/libslic3r/Fill/FillBase.hpp4
-rw-r--r--xs/src/libslic3r/Fill/FillConcentric.cpp4
-rw-r--r--xs/src/libslic3r/Fill/FillGyroid.cpp168
-rw-r--r--xs/src/libslic3r/Fill/FillGyroid.hpp4
-rw-r--r--xs/src/libslic3r/Fill/FillHoneycomb.cpp8
-rw-r--r--xs/src/libslic3r/Fill/FillPlanePath.cpp60
-rw-r--r--xs/src/libslic3r/Fill/FillRectilinear.cpp28
-rw-r--r--xs/src/libslic3r/Fill/FillRectilinear2.cpp72
-rw-r--r--xs/src/libslic3r/Fill/FillRectilinear3.cpp132
-rw-r--r--xs/src/libslic3r/Format/3mf.cpp447
-rw-r--r--xs/src/libslic3r/Format/3mf.hpp2
-rw-r--r--xs/src/libslic3r/Format/AMF.cpp183
-rw-r--r--xs/src/libslic3r/Format/AMF.hpp2
-rw-r--r--xs/src/libslic3r/Format/OBJ.cpp34
-rw-r--r--xs/src/libslic3r/Format/PRUS.cpp22
-rw-r--r--xs/src/libslic3r/GCode.cpp760
-rw-r--r--xs/src/libslic3r/GCode.hpp55
-rw-r--r--xs/src/libslic3r/GCode/Analyzer.cpp123
-rw-r--r--xs/src/libslic3r/GCode/Analyzer.hpp34
-rw-r--r--xs/src/libslic3r/GCode/CoolingBuffer.cpp929
-rw-r--r--xs/src/libslic3r/GCode/CoolingBuffer.hpp28
-rw-r--r--xs/src/libslic3r/GCode/PreviewData.cpp103
-rw-r--r--xs/src/libslic3r/GCode/PreviewData.hpp35
-rw-r--r--xs/src/libslic3r/GCode/PrintExtents.cpp55
-rw-r--r--xs/src/libslic3r/GCode/ToolOrdering.cpp327
-rw-r--r--xs/src/libslic3r/GCode/ToolOrdering.hpp142
-rw-r--r--xs/src/libslic3r/GCode/WipeTower.hpp36
-rw-r--r--xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp1344
-rw-r--r--xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp305
-rw-r--r--xs/src/libslic3r/GCodeReader.cpp22
-rw-r--r--xs/src/libslic3r/GCodeReader.hpp1
-rw-r--r--xs/src/libslic3r/GCodeSender.cpp51
-rw-r--r--xs/src/libslic3r/GCodeSender.hpp2
-rw-r--r--xs/src/libslic3r/GCodeTimeEstimator.cpp513
-rw-r--r--xs/src/libslic3r/GCodeTimeEstimator.hpp111
-rw-r--r--xs/src/libslic3r/GCodeWriter.cpp64
-rw-r--r--xs/src/libslic3r/GCodeWriter.hpp17
-rw-r--r--xs/src/libslic3r/Geometry.cpp243
-rw-r--r--xs/src/libslic3r/Geometry.hpp38
-rw-r--r--xs/src/libslic3r/I18N.hpp18
-rw-r--r--xs/src/libslic3r/Int128.hpp17
-rw-r--r--xs/src/libslic3r/Layer.cpp8
-rw-r--r--xs/src/libslic3r/LayerRegion.cpp8
-rw-r--r--xs/src/libslic3r/Line.cpp265
-rw-r--r--xs/src/libslic3r/Line.hpp103
-rw-r--r--xs/src/libslic3r/Model.cpp392
-rw-r--r--xs/src/libslic3r/Model.hpp103
-rw-r--r--xs/src/libslic3r/ModelArrange.hpp788
-rw-r--r--xs/src/libslic3r/MotionPlanner.cpp10
-rw-r--r--xs/src/libslic3r/MultiPoint.cpp125
-rw-r--r--xs/src/libslic3r/MultiPoint.hpp12
-rw-r--r--xs/src/libslic3r/PerimeterGenerator.cpp414
-rw-r--r--xs/src/libslic3r/PerimeterGenerator.hpp5
-rw-r--r--xs/src/libslic3r/PlaceholderParser.cpp43
-rw-r--r--xs/src/libslic3r/Point.cpp318
-rw-r--r--xs/src/libslic3r/Point.hpp286
-rw-r--r--xs/src/libslic3r/Polygon.cpp67
-rw-r--r--xs/src/libslic3r/Polygon.hpp12
-rw-r--r--xs/src/libslic3r/Polyline.cpp126
-rw-r--r--xs/src/libslic3r/Polyline.hpp27
-rw-r--r--xs/src/libslic3r/PolylineCollection.cpp10
-rw-r--r--xs/src/libslic3r/Print.cpp326
-rw-r--r--xs/src/libslic3r/Print.hpp56
-rw-r--r--xs/src/libslic3r/PrintConfig.cpp688
-rw-r--r--xs/src/libslic3r/PrintConfig.hpp257
-rw-r--r--xs/src/libslic3r/PrintExport.hpp383
-rw-r--r--xs/src/libslic3r/PrintObject.cpp185
-rw-r--r--xs/src/libslic3r/Rasterizer/Rasterizer.cpp214
-rw-r--r--xs/src/libslic3r/Rasterizer/Rasterizer.hpp86
-rw-r--r--xs/src/libslic3r/SLABasePool.cpp531
-rw-r--r--xs/src/libslic3r/SLABasePool.hpp32
-rw-r--r--xs/src/libslic3r/SVG.cpp52
-rw-r--r--xs/src/libslic3r/Slicing.cpp54
-rw-r--r--xs/src/libslic3r/SlicingAdaptive.cpp6
-rw-r--r--xs/src/libslic3r/SupportMaterial.cpp60
-rw-r--r--xs/src/libslic3r/Surface.cpp6
-rw-r--r--xs/src/libslic3r/SurfaceCollection.cpp4
-rw-r--r--xs/src/libslic3r/TriangleMesh.cpp619
-rw-r--r--xs/src/libslic3r/TriangleMesh.hpp48
-rw-r--r--xs/src/libslic3r/Utils.hpp28
-rw-r--r--xs/src/libslic3r/libslic3r.h17
-rw-r--r--xs/src/libslic3r/utils.cpp256
-rw-r--r--xs/src/perlglue.cpp40
-rw-r--r--xs/src/png/AUTHORS4
-rw-r--r--xs/src/png/COPYING25
-rw-r--r--xs/src/png/NEWS60
-rw-r--r--xs/src/png/color.hpp65
-rw-r--r--xs/src/png/end_info.hpp74
-rw-r--r--xs/src/png/error.hpp125
-rw-r--r--xs/src/png/image_info.hpp215
-rw-r--r--xs/src/png/info.hpp186
-rw-r--r--xs/src/png/info_base.hpp77
-rw-r--r--xs/src/png/io_base.hpp467
-rw-r--r--xs/src/png/libpng/ANNOUNCE35
-rw-r--r--xs/src/png/libpng/CMakeLists.txt937
-rw-r--r--xs/src/png/libpng/LICENSE133
-rw-r--r--xs/src/png/libpng/arm/arm_init.c135
-rw-r--r--xs/src/png/libpng/arm/filter_neon.S253
-rw-r--r--xs/src/png/libpng/arm/filter_neon_intrinsics.c387
-rw-r--r--xs/src/png/libpng/intel/filter_sse2_intrinsics.c406
-rw-r--r--xs/src/png/libpng/intel/intel_init.c53
-rw-r--r--xs/src/png/libpng/libpng-config.in127
-rw-r--r--xs/src/png/libpng/libpng.pc.in12
-rw-r--r--xs/src/png/libpng/mips/filter_msa_intrinsics.c807
-rw-r--r--xs/src/png/libpng/mips/mips_init.c129
-rw-r--r--xs/src/png/libpng/png.c4614
-rw-r--r--xs/src/png/libpng/png.h3278
-rw-r--r--xs/src/png/libpng/pngconf.h622
-rw-r--r--xs/src/png/libpng/pngdebug.h153
-rw-r--r--xs/src/png/libpng/pngerror.c963
-rw-r--r--xs/src/png/libpng/pngget.c1248
-rw-r--r--xs/src/png/libpng/pnginfo.h267
-rw-r--r--xs/src/png/libpng/pngmem.c284
-rw-r--r--xs/src/png/libpng/pngpread.c1096
-rw-r--r--xs/src/png/libpng/pngpriv.h2120
-rw-r--r--xs/src/png/libpng/pngread.c4219
-rw-r--r--xs/src/png/libpng/pngrio.c120
-rw-r--r--xs/src/png/libpng/pngrtran.c5010
-rw-r--r--xs/src/png/libpng/pngrutil.c4661
-rw-r--r--xs/src/png/libpng/pngset.c1802
-rw-r--r--xs/src/png/libpng/pngstruct.h483
-rw-r--r--xs/src/png/libpng/pngtest.c2156
-rw-r--r--xs/src/png/libpng/pngtrans.c864
-rw-r--r--xs/src/png/libpng/pngusr.dfa14
-rw-r--r--xs/src/png/libpng/pngwio.c168
-rw-r--r--xs/src/png/libpng/pngwrite.c2396
-rw-r--r--xs/src/png/libpng/pngwtran.c576
-rw-r--r--xs/src/png/libpng/pngwutil.c2784
-rw-r--r--xs/src/png/libpng/powerpc/filter_vsx_intrinsics.c767
-rw-r--r--xs/src/png/libpng/powerpc/powerpc_init.c125
-rwxr-xr-xxs/src/png/libpng/scripts/checksym.awk173
-rw-r--r--xs/src/png/libpng/scripts/def.c29
-rwxr-xr-xxs/src/png/libpng/scripts/dfn.awk203
-rw-r--r--xs/src/png/libpng/scripts/genchk.cmake.in37
-rw-r--r--xs/src/png/libpng/scripts/genout.cmake.in93
-rw-r--r--xs/src/png/libpng/scripts/gensrc.cmake.in138
-rw-r--r--xs/src/png/libpng/scripts/intprefix.c22
-rw-r--r--xs/src/png/libpng/scripts/libpng-config-body.in96
-rw-r--r--xs/src/png/libpng/scripts/libpng-config-head.in24
-rw-r--r--xs/src/png/libpng/scripts/libpng.pc.in10
-rwxr-xr-xxs/src/png/libpng/scripts/options.awk898
-rw-r--r--xs/src/png/libpng/scripts/pnglibconf.dfa919
-rw-r--r--xs/src/png/libpng/scripts/pnglibconf.h.prebuilt220
-rw-r--r--xs/src/png/libpng/scripts/prefix.c24
-rw-r--r--xs/src/png/libpng/scripts/sym.c15
-rw-r--r--xs/src/png/libpng/scripts/symbols.c58
-rw-r--r--xs/src/png/libpng/scripts/symbols.def256
-rw-r--r--xs/src/png/libpng/scripts/test.cmake.in31
-rw-r--r--xs/src/png/libpng/scripts/vers.c19
-rw-r--r--xs/src/png/palette.hpp48
-rw-r--r--xs/src/png/pixel_traits.hpp103
-rw-r--r--xs/src/png/tRNS.hpp48
-rw-r--r--xs/src/png/types.hpp120
-rw-r--r--xs/src/png/writer.hpp199
-rw-r--r--xs/src/png/zlib/CMakeLists.txt253
-rw-r--r--xs/src/png/zlib/ChangeLog1515
-rw-r--r--xs/src/png/zlib/FAQ368
-rw-r--r--xs/src/png/zlib/INDEX68
-rw-r--r--xs/src/png/zlib/Makefile5
-rw-r--r--xs/src/png/zlib/Makefile.in410
-rw-r--r--xs/src/png/zlib/README115
-rw-r--r--xs/src/png/zlib/adler32.c186
-rw-r--r--xs/src/png/zlib/amiga/Makefile.pup69
-rw-r--r--xs/src/png/zlib/amiga/Makefile.sas68
-rw-r--r--xs/src/png/zlib/compress.c86
-rw-r--r--xs/src/png/zlib/configure921
-rw-r--r--xs/src/png/zlib/contrib/README.contrib78
-rw-r--r--xs/src/png/zlib/contrib/ada/buffer_demo.adb106
-rw-r--r--xs/src/png/zlib/contrib/ada/mtest.adb156
-rw-r--r--xs/src/png/zlib/contrib/ada/read.adb156
-rw-r--r--xs/src/png/zlib/contrib/ada/readme.txt65
-rw-r--r--xs/src/png/zlib/contrib/ada/test.adb463
-rw-r--r--xs/src/png/zlib/contrib/ada/zlib-streams.adb225
-rw-r--r--xs/src/png/zlib/contrib/ada/zlib-streams.ads114
-rw-r--r--xs/src/png/zlib/contrib/ada/zlib-thin.adb141
-rw-r--r--xs/src/png/zlib/contrib/ada/zlib-thin.ads450
-rw-r--r--xs/src/png/zlib/contrib/ada/zlib.adb701
-rw-r--r--xs/src/png/zlib/contrib/ada/zlib.ads328
-rw-r--r--xs/src/png/zlib/contrib/ada/zlib.gpr20
-rw-r--r--xs/src/png/zlib/contrib/amd64/amd64-match.S452
-rw-r--r--xs/src/png/zlib/contrib/asm686/README.68651
-rw-r--r--xs/src/png/zlib/contrib/asm686/match.S357
-rw-r--r--xs/src/png/zlib/contrib/blast/Makefile8
-rw-r--r--xs/src/png/zlib/contrib/blast/README4
-rw-r--r--xs/src/png/zlib/contrib/blast/blast.c466
-rw-r--r--xs/src/png/zlib/contrib/blast/blast.h83
-rw-r--r--xs/src/png/zlib/contrib/blast/test.pkbin0 -> 8 bytes
-rw-r--r--xs/src/png/zlib/contrib/blast/test.txt1
-rw-r--r--xs/src/png/zlib/contrib/delphi/ZLib.pas557
-rw-r--r--xs/src/png/zlib/contrib/delphi/ZLibConst.pas11
-rw-r--r--xs/src/png/zlib/contrib/delphi/readme.txt76
-rw-r--r--xs/src/png/zlib/contrib/delphi/zlibd32.mak99
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib.build33
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib.chmbin0 -> 72726 bytes
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib.sln21
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs58
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs202
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs83
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib/CodecBase.cs198
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib/Deflater.cs106
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib/DotZLib.cs288
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj141
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib/GZipStream.cs301
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib/Inflater.cs105
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/DotZLib/UnitTests.cs274
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/LICENSE_1_0.txt23
-rw-r--r--xs/src/png/zlib/contrib/dotzlib/readme.txt58
-rw-r--r--xs/src/png/zlib/contrib/gcc_gvmat64/gvmat64.S574
-rw-r--r--xs/src/png/zlib/contrib/infback9/README1
-rw-r--r--xs/src/png/zlib/contrib/infback9/infback9.c615
-rw-r--r--xs/src/png/zlib/contrib/infback9/infback9.h37
-rw-r--r--xs/src/png/zlib/contrib/infback9/inffix9.h107
-rw-r--r--xs/src/png/zlib/contrib/infback9/inflate9.h47
-rw-r--r--xs/src/png/zlib/contrib/infback9/inftree9.c324
-rw-r--r--xs/src/png/zlib/contrib/infback9/inftree9.h61
-rw-r--r--xs/src/png/zlib/contrib/inflate86/inffas86.c1157
-rw-r--r--xs/src/png/zlib/contrib/inflate86/inffast.S1368
-rw-r--r--xs/src/png/zlib/contrib/iostream/test.cpp24
-rw-r--r--xs/src/png/zlib/contrib/iostream/zfstream.cpp329
-rw-r--r--xs/src/png/zlib/contrib/iostream/zfstream.h128
-rw-r--r--xs/src/png/zlib/contrib/iostream2/zstream.h307
-rw-r--r--xs/src/png/zlib/contrib/iostream2/zstream_test.cpp25
-rw-r--r--xs/src/png/zlib/contrib/iostream3/README35
-rw-r--r--xs/src/png/zlib/contrib/iostream3/TODO17
-rw-r--r--xs/src/png/zlib/contrib/iostream3/test.cc50
-rw-r--r--xs/src/png/zlib/contrib/iostream3/zfstream.cc479
-rw-r--r--xs/src/png/zlib/contrib/iostream3/zfstream.h466
-rw-r--r--xs/src/png/zlib/contrib/masmx64/bld_ml64.bat2
-rw-r--r--xs/src/png/zlib/contrib/masmx64/gvmat64.asm553
-rw-r--r--xs/src/png/zlib/contrib/masmx64/inffas8664.c186
-rw-r--r--xs/src/png/zlib/contrib/masmx64/inffasx64.asm396
-rw-r--r--xs/src/png/zlib/contrib/masmx64/readme.txt31
-rw-r--r--xs/src/png/zlib/contrib/masmx86/bld_ml32.bat2
-rw-r--r--xs/src/png/zlib/contrib/masmx86/inffas32.asm1080
-rw-r--r--xs/src/png/zlib/contrib/masmx86/match686.asm479
-rw-r--r--xs/src/png/zlib/contrib/masmx86/readme.txt27
-rw-r--r--xs/src/png/zlib/contrib/minizip/Makefile25
-rw-r--r--xs/src/png/zlib/contrib/minizip/Makefile.am45
-rw-r--r--xs/src/png/zlib/contrib/minizip/MiniZip64_Changes.txt6
-rw-r--r--xs/src/png/zlib/contrib/minizip/MiniZip64_info.txt74
-rw-r--r--xs/src/png/zlib/contrib/minizip/configure.ac32
-rw-r--r--xs/src/png/zlib/contrib/minizip/crypt.h131
-rw-r--r--xs/src/png/zlib/contrib/minizip/ioapi.c247
-rw-r--r--xs/src/png/zlib/contrib/minizip/ioapi.h208
-rw-r--r--xs/src/png/zlib/contrib/minizip/iowin32.c462
-rw-r--r--xs/src/png/zlib/contrib/minizip/iowin32.h28
-rw-r--r--xs/src/png/zlib/contrib/minizip/make_vms.com25
-rw-r--r--xs/src/png/zlib/contrib/minizip/miniunz.c660
-rw-r--r--xs/src/png/zlib/contrib/minizip/miniunzip.163
-rw-r--r--xs/src/png/zlib/contrib/minizip/minizip.146
-rw-r--r--xs/src/png/zlib/contrib/minizip/minizip.c520
-rw-r--r--xs/src/png/zlib/contrib/minizip/minizip.pc.in12
-rw-r--r--xs/src/png/zlib/contrib/minizip/mztools.c291
-rw-r--r--xs/src/png/zlib/contrib/minizip/mztools.h37
-rw-r--r--xs/src/png/zlib/contrib/minizip/unzip.c2125
-rw-r--r--xs/src/png/zlib/contrib/minizip/unzip.h437
-rw-r--r--xs/src/png/zlib/contrib/minizip/zip.c2007
-rw-r--r--xs/src/png/zlib/contrib/minizip/zip.h362
-rw-r--r--xs/src/png/zlib/contrib/pascal/example.pas599
-rw-r--r--xs/src/png/zlib/contrib/pascal/readme.txt76
-rw-r--r--xs/src/png/zlib/contrib/pascal/zlibd32.mak99
-rw-r--r--xs/src/png/zlib/contrib/pascal/zlibpas.pas276
-rw-r--r--xs/src/png/zlib/contrib/puff/Makefile42
-rw-r--r--xs/src/png/zlib/contrib/puff/README63
-rw-r--r--xs/src/png/zlib/contrib/puff/puff.c840
-rw-r--r--xs/src/png/zlib/contrib/puff/puff.h35
-rw-r--r--xs/src/png/zlib/contrib/puff/pufftest.c165
-rw-r--r--xs/src/png/zlib/contrib/puff/zeros.rawbin0 -> 2517 bytes
-rw-r--r--xs/src/png/zlib/contrib/testzlib/testzlib.c275
-rw-r--r--xs/src/png/zlib/contrib/testzlib/testzlib.txt10
-rw-r--r--xs/src/png/zlib/contrib/untgz/Makefile14
-rw-r--r--xs/src/png/zlib/contrib/untgz/Makefile.msc17
-rw-r--r--xs/src/png/zlib/contrib/untgz/untgz.c674
-rw-r--r--xs/src/png/zlib/contrib/vstudio/readme.txt78
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/miniunz.vcxproj310
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters22
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/minizip.vcxproj307
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters22
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/testzlib.vcxproj420
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters58
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj310
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters22
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/zlib.rc32
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/zlibstat.vcxproj473
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters77
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.def153
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.sln135
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.vcxproj657
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters118
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc11/miniunz.vcxproj314
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc11/minizip.vcxproj311
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc11/testzlib.vcxproj426
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj314
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc11/zlib.rc32
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc11/zlibstat.vcxproj464
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.def153
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.sln117
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.vcxproj688
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc12/miniunz.vcxproj316
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc12/minizip.vcxproj313
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc12/testzlib.vcxproj430
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc12/testzlibdll.vcxproj316
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc12/zlib.rc32
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc12/zlibstat.vcxproj467
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.def153
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.sln119
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.vcxproj692
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc14/miniunz.vcxproj316
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc14/minizip.vcxproj313
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc14/testzlib.vcxproj430
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc14/testzlibdll.vcxproj316
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc14/zlib.rc32
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc14/zlibstat.vcxproj467
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.def153
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.sln119
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.vcxproj692
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc9/miniunz.vcproj565
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc9/minizip.vcproj562
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc9/testzlib.vcproj852
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc9/testzlibdll.vcproj565
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc9/zlib.rc32
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc9/zlibstat.vcproj835
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.def153
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.sln144
-rw-r--r--xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.vcproj1156
-rw-r--r--xs/src/png/zlib/crc32.c442
-rw-r--r--xs/src/png/zlib/crc32.h441
-rw-r--r--xs/src/png/zlib/deflate.c2163
-rw-r--r--xs/src/png/zlib/deflate.h349
-rw-r--r--xs/src/png/zlib/gzclose.c25
-rw-r--r--xs/src/png/zlib/gzguts.h218
-rw-r--r--xs/src/png/zlib/gzlib.c637
-rw-r--r--xs/src/png/zlib/gzread.c654
-rw-r--r--xs/src/png/zlib/gzwrite.c665
-rw-r--r--xs/src/png/zlib/infback.c640
-rw-r--r--xs/src/png/zlib/inffast.c323
-rw-r--r--xs/src/png/zlib/inffast.h11
-rw-r--r--xs/src/png/zlib/inffixed.h94
-rw-r--r--xs/src/png/zlib/inflate.c1561
-rw-r--r--xs/src/png/zlib/inflate.h125
-rw-r--r--xs/src/png/zlib/inftrees.c304
-rw-r--r--xs/src/png/zlib/inftrees.h62
-rw-r--r--xs/src/png/zlib/make_vms.com867
-rw-r--r--xs/src/png/zlib/msdos/Makefile.bor115
-rw-r--r--xs/src/png/zlib/msdos/Makefile.dj2104
-rw-r--r--xs/src/png/zlib/msdos/Makefile.emx69
-rw-r--r--xs/src/png/zlib/msdos/Makefile.msc112
-rw-r--r--xs/src/png/zlib/msdos/Makefile.tc100
-rw-r--r--xs/src/png/zlib/nintendods/Makefile126
-rw-r--r--xs/src/png/zlib/nintendods/README5
-rw-r--r--xs/src/png/zlib/old/Makefile.emx69
-rw-r--r--xs/src/png/zlib/old/Makefile.riscos151
-rw-r--r--xs/src/png/zlib/old/README3
-rw-r--r--xs/src/png/zlib/old/descrip.mms48
-rw-r--r--xs/src/png/zlib/old/os2/Makefile.os2136
-rw-r--r--xs/src/png/zlib/old/os2/zlib.def51
-rw-r--r--xs/src/png/zlib/old/visual-basic.txt160
-rw-r--r--xs/src/png/zlib/os400/README40048
-rw-r--r--xs/src/png/zlib/os400/bndsrc119
-rw-r--r--xs/src/png/zlib/os400/make.sh366
-rw-r--r--xs/src/png/zlib/os400/zlib.inc527
-rw-r--r--xs/src/png/zlib/qnx/package.qpg141
-rw-r--r--xs/src/png/zlib/treebuild.xml116
-rw-r--r--xs/src/png/zlib/trees.c1203
-rw-r--r--xs/src/png/zlib/trees.h128
-rw-r--r--xs/src/png/zlib/uncompr.c93
-rw-r--r--xs/src/png/zlib/watcom/watcom_f.mak43
-rw-r--r--xs/src/png/zlib/watcom/watcom_l.mak43
-rw-r--r--xs/src/png/zlib/win32/DLL_FAQ.txt397
-rw-r--r--xs/src/png/zlib/win32/Makefile.bor110
-rw-r--r--xs/src/png/zlib/win32/Makefile.gcc182
-rw-r--r--xs/src/png/zlib/win32/Makefile.msc163
-rw-r--r--xs/src/png/zlib/win32/README-WIN32.txt103
-rw-r--r--xs/src/png/zlib/win32/VisualC.txt3
-rw-r--r--xs/src/png/zlib/win32/zlib.def94
-rw-r--r--xs/src/png/zlib/win32/zlib1.rc40
-rw-r--r--xs/src/png/zlib/zconf.h.cmakein536
-rw-r--r--xs/src/png/zlib/zconf.h.in534
-rw-r--r--xs/src/png/zlib/zconf.h.included534
-rw-r--r--xs/src/png/zlib/zlib.3149
-rw-r--r--xs/src/png/zlib/zlib.3.pdfbin0 -> 19318 bytes
-rw-r--r--xs/src/png/zlib/zlib.h1912
-rw-r--r--xs/src/png/zlib/zlib.map94
-rw-r--r--xs/src/png/zlib/zlib.pc.cmakein13
-rw-r--r--xs/src/png/zlib/zlib.pc.in13
-rw-r--r--xs/src/png/zlib/zlib2ansi152
-rw-r--r--xs/src/png/zlib/zutil.c325
-rw-r--r--xs/src/png/zlib/zutil.h271
-rw-r--r--xs/src/poly2tri/common/utils.h4
-rw-r--r--xs/src/qhull/Announce.txt47
-rw-r--r--xs/src/qhull/CMakeLists.txt128
-rw-r--r--xs/src/qhull/COPYING.txt38
-rw-r--r--xs/src/qhull/README.txt623
-rw-r--r--xs/src/qhull/REGISTER.txt32
-rw-r--r--xs/src/qhull/html/index.htm935
-rw-r--r--xs/src/qhull/html/normal_voronoi_knauss_oesterle.jpgbin0 -> 23924 bytes
-rw-r--r--xs/src/qhull/html/qconvex.htm630
-rw-r--r--xs/src/qhull/html/qdelau_f.htm416
-rw-r--r--xs/src/qhull/html/qdelaun.htm628
-rw-r--r--xs/src/qhull/html/qh--4d.gifbin0 -> 4372 bytes
-rw-r--r--xs/src/qhull/html/qh--cone.gifbin0 -> 2946 bytes
-rw-r--r--xs/src/qhull/html/qh--dt.gifbin0 -> 3772 bytes
-rw-r--r--xs/src/qhull/html/qh--geom.gifbin0 -> 318 bytes
-rw-r--r--xs/src/qhull/html/qh--half.gifbin0 -> 2537 bytes
-rw-r--r--xs/src/qhull/html/qh--rand.gifbin0 -> 3875 bytes
-rw-r--r--xs/src/qhull/html/qh-code.htm1062
-rw-r--r--xs/src/qhull/html/qh-eg.htm693
-rw-r--r--xs/src/qhull/html/qh-faq.htm1547
-rw-r--r--xs/src/qhull/html/qh-get.htm106
-rw-r--r--xs/src/qhull/html/qh-impre.htm826
-rw-r--r--xs/src/qhull/html/qh-optc.htm292
-rw-r--r--xs/src/qhull/html/qh-optf.htm736
-rw-r--r--xs/src/qhull/html/qh-optg.htm274
-rw-r--r--xs/src/qhull/html/qh-opto.htm353
-rw-r--r--xs/src/qhull/html/qh-optp.htm253
-rw-r--r--xs/src/qhull/html/qh-optq.htm731
-rw-r--r--xs/src/qhull/html/qh-optt.htm278
-rw-r--r--xs/src/qhull/html/qh-quick.htm495
-rw-r--r--xs/src/qhull/html/qhalf.htm626
-rw-r--r--xs/src/qhull/html/qhull-cpp.xml214
-rw-r--r--xs/src/qhull/html/qhull.htm473
-rw-r--r--xs/src/qhull/html/qhull.man1008
-rw-r--r--xs/src/qhull/html/qhull.txt1263
-rw-r--r--xs/src/qhull/html/qvoron_f.htm396
-rw-r--r--xs/src/qhull/html/qvoronoi.htm667
-rw-r--r--xs/src/qhull/html/rbox.htm277
-rw-r--r--xs/src/qhull/html/rbox.man176
-rw-r--r--xs/src/qhull/html/rbox.txt195
-rw-r--r--xs/src/qhull/index.htm284
-rw-r--r--xs/src/qhull/origCMakeLists.txt426
-rw-r--r--xs/src/qhull/src/Changes.txt2129
-rw-r--r--xs/src/qhull/src/libqhull/DEPRECATED.txt29
-rw-r--r--xs/src/qhull/src/libqhull/Makefile240
-rw-r--r--xs/src/qhull/src/libqhull/Mborland206
-rw-r--r--xs/src/qhull/src/libqhull/geom.c1234
-rw-r--r--xs/src/qhull/src/libqhull/geom.h176
-rw-r--r--xs/src/qhull/src/libqhull/geom2.c2094
-rw-r--r--xs/src/qhull/src/libqhull/global.c2217
-rw-r--r--xs/src/qhull/src/libqhull/index.htm264
-rw-r--r--xs/src/qhull/src/libqhull/io.c4062
-rw-r--r--xs/src/qhull/src/libqhull/io.h159
-rw-r--r--xs/src/qhull/src/libqhull/libqhull.c1403
-rw-r--r--xs/src/qhull/src/libqhull/libqhull.h1140
-rw-r--r--xs/src/qhull/src/libqhull/libqhull.pro67
-rw-r--r--xs/src/qhull/src/libqhull/mem.c576
-rw-r--r--xs/src/qhull/src/libqhull/mem.h222
-rw-r--r--xs/src/qhull/src/libqhull/merge.c3628
-rw-r--r--xs/src/qhull/src/libqhull/merge.h178
-rw-r--r--xs/src/qhull/src/libqhull/poly.c1205
-rw-r--r--xs/src/qhull/src/libqhull/poly.h296
-rw-r--r--xs/src/qhull/src/libqhull/poly2.c3222
-rw-r--r--xs/src/qhull/src/libqhull/qh-geom.htm295
-rw-r--r--xs/src/qhull/src/libqhull/qh-globa.htm165
-rw-r--r--xs/src/qhull/src/libqhull/qh-io.htm305
-rw-r--r--xs/src/qhull/src/libqhull/qh-mem.htm145
-rw-r--r--xs/src/qhull/src/libqhull/qh-merge.htm366
-rw-r--r--xs/src/qhull/src/libqhull/qh-poly.htm485
-rw-r--r--xs/src/qhull/src/libqhull/qh-qhull.htm279
-rw-r--r--xs/src/qhull/src/libqhull/qh-set.htm308
-rw-r--r--xs/src/qhull/src/libqhull/qh-stat.htm163
-rw-r--r--xs/src/qhull/src/libqhull/qh-user.htm271
-rw-r--r--xs/src/qhull/src/libqhull/qhull-exports.def417
-rw-r--r--xs/src/qhull/src/libqhull/qhull_a.h150
-rw-r--r--xs/src/qhull/src/libqhull/qhull_p-exports.def418
-rw-r--r--xs/src/qhull/src/libqhull/qset.c1340
-rw-r--r--xs/src/qhull/src/libqhull/qset.h490
-rw-r--r--xs/src/qhull/src/libqhull/random.c245
-rw-r--r--xs/src/qhull/src/libqhull/random.h34
-rw-r--r--xs/src/qhull/src/libqhull/rboxlib.c870
-rw-r--r--xs/src/qhull/src/libqhull/stat.c717
-rw-r--r--xs/src/qhull/src/libqhull/stat.h543
-rw-r--r--xs/src/qhull/src/libqhull/user.c538
-rw-r--r--xs/src/qhull/src/libqhull/user.h909
-rw-r--r--xs/src/qhull/src/libqhull/usermem.c94
-rw-r--r--xs/src/qhull/src/libqhull/userprintf.c66
-rw-r--r--xs/src/qhull/src/libqhull/userprintf_rbox.c53
-rw-r--r--xs/src/qhull/src/libqhull_r/Makefile240
-rw-r--r--xs/src/qhull/src/libqhull_r/geom2_r.c2096
-rw-r--r--xs/src/qhull/src/libqhull_r/geom_r.c1234
-rw-r--r--xs/src/qhull/src/libqhull_r/geom_r.h184
-rw-r--r--xs/src/qhull/src/libqhull_r/global_r.c2100
-rw-r--r--xs/src/qhull/src/libqhull_r/index.htm266
-rw-r--r--xs/src/qhull/src/libqhull_r/io_r.c4062
-rw-r--r--xs/src/qhull/src/libqhull_r/io_r.h167
-rw-r--r--xs/src/qhull/src/libqhull_r/libqhull_r.c1403
-rw-r--r--xs/src/qhull/src/libqhull_r/libqhull_r.h1134
-rw-r--r--xs/src/qhull/src/libqhull_r/libqhull_r.pro67
-rw-r--r--xs/src/qhull/src/libqhull_r/mem_r.c562
-rw-r--r--xs/src/qhull/src/libqhull_r/mem_r.h234
-rw-r--r--xs/src/qhull/src/libqhull_r/merge_r.c3627
-rw-r--r--xs/src/qhull/src/libqhull_r/merge_r.h186
-rw-r--r--xs/src/qhull/src/libqhull_r/poly2_r.c3222
-rw-r--r--xs/src/qhull/src/libqhull_r/poly_r.c1205
-rw-r--r--xs/src/qhull/src/libqhull_r/poly_r.h303
-rw-r--r--xs/src/qhull/src/libqhull_r/qh-geom_r.htm295
-rw-r--r--xs/src/qhull/src/libqhull_r/qh-globa_r.htm163
-rw-r--r--xs/src/qhull/src/libqhull_r/qh-io_r.htm305
-rw-r--r--xs/src/qhull/src/libqhull_r/qh-mem_r.htm145
-rw-r--r--xs/src/qhull/src/libqhull_r/qh-merge_r.htm366
-rw-r--r--xs/src/qhull/src/libqhull_r/qh-poly_r.htm485
-rw-r--r--xs/src/qhull/src/libqhull_r/qh-qhull_r.htm279
-rw-r--r--xs/src/qhull/src/libqhull_r/qh-set_r.htm308
-rw-r--r--xs/src/qhull/src/libqhull_r/qh-stat_r.htm161
-rw-r--r--xs/src/qhull/src/libqhull_r/qh-user_r.htm271
-rw-r--r--xs/src/qhull/src/libqhull_r/qhull_r-exports.def404
-rw-r--r--xs/src/qhull/src/libqhull_r/qhull_ra.h158
-rw-r--r--xs/src/qhull/src/libqhull_r/qset_r.c1340
-rw-r--r--xs/src/qhull/src/libqhull_r/qset_r.h502
-rw-r--r--xs/src/qhull/src/libqhull_r/random_r.c247
-rw-r--r--xs/src/qhull/src/libqhull_r/random_r.h41
-rw-r--r--xs/src/qhull/src/libqhull_r/rboxlib_r.c842
-rw-r--r--xs/src/qhull/src/libqhull_r/stat_r.c682
-rw-r--r--xs/src/qhull/src/libqhull_r/stat_r.h533
-rw-r--r--xs/src/qhull/src/libqhull_r/user_r.c527
-rw-r--r--xs/src/qhull/src/libqhull_r/user_r.h882
-rw-r--r--xs/src/qhull/src/libqhull_r/usermem_r.c94
-rw-r--r--xs/src/qhull/src/libqhull_r/userprintf_r.c65
-rw-r--r--xs/src/qhull/src/libqhull_r/userprintf_rbox_r.c53
-rw-r--r--xs/src/qhull/src/libqhullcpp/Coordinates.cpp198
-rw-r--r--xs/src/qhull/src/libqhullcpp/Coordinates.h303
-rw-r--r--xs/src/qhull/src/libqhullcpp/PointCoordinates.cpp348
-rw-r--r--xs/src/qhull/src/libqhullcpp/PointCoordinates.h161
-rw-r--r--xs/src/qhull/src/libqhullcpp/Qhull.cpp352
-rw-r--r--xs/src/qhull/src/libqhullcpp/Qhull.h132
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullError.h62
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullFacet.cpp519
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullFacet.h151
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullFacetList.cpp174
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullFacetList.h106
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullFacetSet.cpp147
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullFacetSet.h97
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullHyperplane.cpp187
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullHyperplane.h123
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullIterator.h173
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullLinkedList.h388
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullPoint.cpp203
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullPoint.h136
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullPointSet.cpp62
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullPointSet.h77
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullPoints.cpp320
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullPoints.h266
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullQh.cpp237
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullQh.h110
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullRidge.cpp124
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullRidge.h112
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullSet.cpp62
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullSet.h462
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullSets.h27
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullStat.cpp42
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullStat.h49
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullVertex.cpp112
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullVertex.h104
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullVertexSet.cpp161
-rw-r--r--xs/src/qhull/src/libqhullcpp/QhullVertexSet.h86
-rw-r--r--xs/src/qhull/src/libqhullcpp/RboxPoints.cpp224
-rw-r--r--xs/src/qhull/src/libqhullcpp/RboxPoints.h69
-rw-r--r--xs/src/qhull/src/libqhullcpp/RoadError.cpp158
-rw-r--r--xs/src/qhull/src/libqhullcpp/RoadError.h88
-rw-r--r--xs/src/qhull/src/libqhullcpp/RoadLogEvent.cpp122
-rw-r--r--xs/src/qhull/src/libqhullcpp/RoadLogEvent.h77
-rw-r--r--xs/src/qhull/src/libqhullcpp/functionObjects.h67
-rw-r--r--xs/src/qhull/src/libqhullcpp/libqhullcpp.pro71
-rw-r--r--xs/src/qhull/src/libqhullcpp/qt-qhull.cpp130
-rw-r--r--xs/src/qhull/src/libqhullcpp/usermem_r-cpp.cpp93
-rw-r--r--xs/src/qhull/src/libqhullstatic/libqhullstatic.pro19
-rw-r--r--xs/src/qhull/src/libqhullstatic_r/libqhullstatic_r.pro21
-rw-r--r--xs/src/qhull/src/qconvex/qconvex.c326
-rw-r--r--xs/src/qhull/src/qconvex/qconvex.pro9
-rw-r--r--xs/src/qhull/src/qconvex/qconvex_r.c328
-rw-r--r--xs/src/qhull/src/qdelaunay/qdelaun.c315
-rw-r--r--xs/src/qhull/src/qdelaunay/qdelaun_r.c317
-rw-r--r--xs/src/qhull/src/qdelaunay/qdelaunay.pro9
-rw-r--r--xs/src/qhull/src/qhalf/qhalf.c316
-rw-r--r--xs/src/qhull/src/qhalf/qhalf.pro9
-rw-r--r--xs/src/qhull/src/qhalf/qhalf_r.c318
-rw-r--r--xs/src/qhull/src/qhull-all.pro94
-rw-r--r--xs/src/qhull/src/qhull-app-c.pri24
-rw-r--r--xs/src/qhull/src/qhull-app-c_r.pri26
-rw-r--r--xs/src/qhull/src/qhull-app-cpp.pri23
-rw-r--r--xs/src/qhull/src/qhull-app-shared.pri27
-rw-r--r--xs/src/qhull/src/qhull-app-shared_r.pri29
-rw-r--r--xs/src/qhull/src/qhull-libqhull-src.pri39
-rw-r--r--xs/src/qhull/src/qhull-libqhull-src_r.pri39
-rw-r--r--xs/src/qhull/src/qhull-warn.pri57
-rw-r--r--xs/src/qhull/src/qhull/qhull.pro9
-rw-r--r--xs/src/qhull/src/qhull/unix.c372
-rw-r--r--xs/src/qhull/src/qhull/unix_r.c374
-rw-r--r--xs/src/qhull/src/qhulltest/Coordinates_test.cpp539
-rw-r--r--xs/src/qhull/src/qhulltest/PointCoordinates_test.cpp478
-rw-r--r--xs/src/qhull/src/qhulltest/QhullFacetList_test.cpp196
-rw-r--r--xs/src/qhull/src/qhulltest/QhullFacetSet_test.cpp153
-rw-r--r--xs/src/qhull/src/qhulltest/QhullFacet_test.cpp283
-rw-r--r--xs/src/qhull/src/qhulltest/QhullHyperplane_test.cpp429
-rw-r--r--xs/src/qhull/src/qhulltest/QhullLinkedList_test.cpp330
-rw-r--r--xs/src/qhull/src/qhulltest/QhullPointSet_test.cpp378
-rw-r--r--xs/src/qhull/src/qhulltest/QhullPoint_test.cpp437
-rw-r--r--xs/src/qhull/src/qhulltest/QhullPoints_test.cpp561
-rw-r--r--xs/src/qhull/src/qhulltest/QhullRidge_test.cpp159
-rw-r--r--xs/src/qhull/src/qhulltest/QhullSet_test.cpp434
-rw-r--r--xs/src/qhull/src/qhulltest/QhullVertexSet_test.cpp152
-rw-r--r--xs/src/qhull/src/qhulltest/QhullVertex_test.cpp184
-rw-r--r--xs/src/qhull/src/qhulltest/Qhull_test.cpp360
-rw-r--r--xs/src/qhull/src/qhulltest/RboxPoints_test.cpp215
-rw-r--r--xs/src/qhull/src/qhulltest/RoadTest.cpp94
-rw-r--r--xs/src/qhull/src/qhulltest/RoadTest.h102
-rw-r--r--xs/src/qhull/src/qhulltest/qhulltest.cpp94
-rw-r--r--xs/src/qhull/src/qhulltest/qhulltest.pro36
-rw-r--r--xs/src/qhull/src/qvoronoi/qvoronoi.c303
-rw-r--r--xs/src/qhull/src/qvoronoi/qvoronoi.pro9
-rw-r--r--xs/src/qhull/src/qvoronoi/qvoronoi_r.c305
-rw-r--r--xs/src/qhull/src/rbox/rbox.c88
-rw-r--r--xs/src/qhull/src/rbox/rbox.pro9
-rw-r--r--xs/src/qhull/src/rbox/rbox_r.c78
-rw-r--r--xs/src/qhull/src/testqset/testqset.c891
-rw-r--r--xs/src/qhull/src/testqset/testqset.pro30
-rw-r--r--xs/src/qhull/src/testqset_r/testqset_r.c890
-rw-r--r--xs/src/qhull/src/testqset_r/testqset_r.pro30
-rw-r--r--xs/src/qhull/src/user_eg/user_eg.c330
-rw-r--r--xs/src/qhull/src/user_eg/user_eg.pro11
-rw-r--r--xs/src/qhull/src/user_eg/user_eg_r.c326
-rw-r--r--xs/src/qhull/src/user_eg2/user_eg2.c746
-rw-r--r--xs/src/qhull/src/user_eg2/user_eg2.pro11
-rw-r--r--xs/src/qhull/src/user_eg2/user_eg2_r.c742
-rw-r--r--xs/src/qhull/src/user_eg3/user_eg3.pro12
-rw-r--r--xs/src/qhull/src/user_eg3/user_eg3_r.cpp162
-rw-r--r--xs/src/semver/semver.c640
-rw-r--r--xs/src/semver/semver.h111
-rw-r--r--xs/src/slic3r/AppController.cpp502
-rw-r--r--xs/src/slic3r/AppController.hpp303
-rw-r--r--xs/src/slic3r/AppControllerWx.cpp302
-rw-r--r--xs/src/slic3r/Config/Snapshot.cpp532
-rw-r--r--xs/src/slic3r/Config/Snapshot.hpp129
-rw-r--r--xs/src/slic3r/Config/Version.cpp319
-rw-r--r--xs/src/slic3r/Config/Version.hpp88
-rw-r--r--xs/src/slic3r/GUI/2DBed.cpp130
-rw-r--r--xs/src/slic3r/GUI/2DBed.hpp25
-rw-r--r--xs/src/slic3r/GUI/3DScene.cpp2506
-rw-r--r--xs/src/slic3r/GUI/3DScene.hpp415
-rw-r--r--xs/src/slic3r/GUI/AboutDialog.cpp136
-rw-r--r--xs/src/slic3r/GUI/AboutDialog.hpp36
-rw-r--r--xs/src/slic3r/GUI/AppConfig.cpp106
-rw-r--r--xs/src/slic3r/GUI/AppConfig.hpp43
-rw-r--r--xs/src/slic3r/GUI/BackgroundSlicingProcess.cpp5
-rw-r--r--xs/src/slic3r/GUI/BedShapeDialog.cpp82
-rw-r--r--xs/src/slic3r/GUI/BedShapeDialog.hpp9
-rw-r--r--xs/src/slic3r/GUI/BitmapCache.cpp172
-rw-r--r--xs/src/slic3r/GUI/BitmapCache.hpp44
-rw-r--r--xs/src/slic3r/GUI/BonjourDialog.cpp2
-rw-r--r--xs/src/slic3r/GUI/ButtonsDescription.cpp84
-rw-r--r--xs/src/slic3r/GUI/ButtonsDescription.hpp27
-rw-r--r--xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp140
-rw-r--r--xs/src/slic3r/GUI/ConfigSnapshotDialog.hpp34
-rw-r--r--xs/src/slic3r/GUI/ConfigWizard.cpp915
-rw-r--r--xs/src/slic3r/GUI/ConfigWizard.hpp50
-rw-r--r--xs/src/slic3r/GUI/ConfigWizard_private.hpp241
-rw-r--r--xs/src/slic3r/GUI/Field.cpp389
-rw-r--r--xs/src/slic3r/GUI/Field.hpp256
-rw-r--r--xs/src/slic3r/GUI/FirmwareDialog.cpp839
-rw-r--r--xs/src/slic3r/GUI/FirmwareDialog.hpp31
-rw-r--r--xs/src/slic3r/GUI/GLCanvas3D.cpp5505
-rw-r--r--xs/src/slic3r/GUI/GLCanvas3D.hpp766
-rw-r--r--xs/src/slic3r/GUI/GLCanvas3DManager.cpp813
-rw-r--r--xs/src/slic3r/GUI/GLCanvas3DManager.hpp191
-rw-r--r--xs/src/slic3r/GUI/GLGizmo.cpp1476
-rw-r--r--xs/src/slic3r/GUI/GLGizmo.hpp359
-rw-r--r--xs/src/slic3r/GUI/GLShader.cpp51
-rw-r--r--xs/src/slic3r/GUI/GLShader.hpp5
-rw-r--r--xs/src/slic3r/GUI/GLTexture.cpp199
-rw-r--r--xs/src/slic3r/GUI/GLTexture.hpp60
-rw-r--r--xs/src/slic3r/GUI/GLToolbar.cpp722
-rw-r--r--xs/src/slic3r/GUI/GLToolbar.hpp175
-rw-r--r--xs/src/slic3r/GUI/GUI.cpp928
-rw-r--r--xs/src/slic3r/GUI/GUI.hpp161
-rw-r--r--xs/src/slic3r/GUI/GUI_ObjectParts.cpp1723
-rw-r--r--xs/src/slic3r/GUI/GUI_ObjectParts.hpp131
-rw-r--r--xs/src/slic3r/GUI/LambdaObjectDialog.cpp176
-rw-r--r--xs/src/slic3r/GUI/LambdaObjectDialog.hpp35
-rw-r--r--xs/src/slic3r/GUI/MsgDialog.cpp88
-rw-r--r--xs/src/slic3r/GUI/MsgDialog.hpp67
-rw-r--r--xs/src/slic3r/GUI/OptionsGroup.cpp229
-rw-r--r--xs/src/slic3r/GUI/OptionsGroup.hpp125
-rw-r--r--xs/src/slic3r/GUI/Preferences.cpp29
-rw-r--r--xs/src/slic3r/GUI/Preferences.hpp8
-rw-r--r--xs/src/slic3r/GUI/Preset.cpp604
-rw-r--r--xs/src/slic3r/GUI/Preset.hpp215
-rw-r--r--xs/src/slic3r/GUI/PresetBundle.cpp866
-rw-r--r--xs/src/slic3r/GUI/PresetBundle.hpp63
-rw-r--r--xs/src/slic3r/GUI/ProgressStatusBar.cpp151
-rw-r--r--xs/src/slic3r/GUI/ProgressStatusBar.hpp64
-rw-r--r--xs/src/slic3r/GUI/RammingChart.cpp279
-rw-r--r--xs/src/slic3r/GUI/RammingChart.hpp115
-rw-r--r--xs/src/slic3r/GUI/Tab.cpp1695
-rw-r--r--xs/src/slic3r/GUI/Tab.hpp192
-rw-r--r--xs/src/slic3r/GUI/TabIface.cpp1
-rw-r--r--xs/src/slic3r/GUI/TabIface.hpp8
-rw-r--r--xs/src/slic3r/GUI/UpdateDialogs.cpp196
-rw-r--r--xs/src/slic3r/GUI/UpdateDialogs.hpp81
-rw-r--r--xs/src/slic3r/GUI/WipeTowerDialog.cpp338
-rw-r--r--xs/src/slic3r/GUI/WipeTowerDialog.hpp90
-rw-r--r--xs/src/slic3r/GUI/wxExtensions.cpp1352
-rw-r--r--xs/src/slic3r/GUI/wxExtensions.hpp649
-rw-r--r--xs/src/slic3r/ProgressIndicator.hpp71
-rw-r--r--xs/src/slic3r/Strings.hpp10
-rw-r--r--xs/src/slic3r/Utils/Duet.cpp279
-rw-r--r--xs/src/slic3r/Utils/Duet.hpp47
-rw-r--r--xs/src/slic3r/Utils/FixModelByWin10.cpp402
-rw-r--r--xs/src/slic3r/Utils/FixModelByWin10.hpp26
-rw-r--r--xs/src/slic3r/Utils/HexFile.cpp106
-rw-r--r--xs/src/slic3r/Utils/HexFile.hpp33
-rw-r--r--xs/src/slic3r/Utils/Http.cpp198
-rw-r--r--xs/src/slic3r/Utils/Http.hpp63
-rw-r--r--xs/src/slic3r/Utils/OctoPrint.cpp156
-rw-r--r--xs/src/slic3r/Utils/OctoPrint.hpp14
-rw-r--r--xs/src/slic3r/Utils/PresetUpdater.cpp633
-rw-r--r--xs/src/slic3r/Utils/PresetUpdater.hpp42
-rw-r--r--xs/src/slic3r/Utils/PrintHost.cpp23
-rw-r--r--xs/src/slic3r/Utils/PrintHost.hpp35
-rw-r--r--xs/src/slic3r/Utils/PrintHostSendDialog.cpp52
-rw-r--r--xs/src/slic3r/Utils/PrintHostSendDialog.hpp38
-rw-r--r--xs/src/slic3r/Utils/Semver.hpp151
-rw-r--r--xs/src/slic3r/Utils/Serial.cpp490
-rw-r--r--xs/src/slic3r/Utils/Serial.hpp82
-rw-r--r--xs/src/slic3r/Utils/Time.cpp80
-rw-r--r--xs/src/slic3r/Utils/Time.hpp25
-rw-r--r--xs/src/xsinit.h51
-rw-r--r--xs/t/22_exception.t15
-rw-r--r--xs/xsp/AppController.xsp29
-rw-r--r--xs/xsp/BoundingBox.xsp68
-rw-r--r--xs/xsp/Config.xsp6
-rw-r--r--xs/xsp/GCode.xsp8
-rw-r--r--xs/xsp/GUI.xsp126
-rw-r--r--xs/xsp/GUI_3DScene.xsp673
-rw-r--r--xs/xsp/GUI_AppConfig.xsp2
-rw-r--r--xs/xsp/GUI_Preset.xsp52
-rw-r--r--xs/xsp/GUI_Tab.xsp1
-rw-r--r--xs/xsp/Geometry.xsp2
-rw-r--r--xs/xsp/Line.xsp15
-rw-r--r--xs/xsp/Model.xsp30
-rw-r--r--xs/xsp/PlaceholderParser.xsp4
-rw-r--r--xs/xsp/Point.xsp127
-rw-r--r--xs/xsp/Polygon.xsp1
-rw-r--r--xs/xsp/Polyline.xsp1
-rw-r--r--xs/xsp/Print.xsp32
-rw-r--r--xs/xsp/ProgressStatusBar.xsp48
-rw-r--r--xs/xsp/TriangleMesh.xsp48
-rw-r--r--xs/xsp/Utils_OctoPrint.xsp13
-rw-r--r--xs/xsp/Utils_PresetUpdater.xsp13
-rw-r--r--xs/xsp/Utils_PrintHost.xsp12
-rw-r--r--xs/xsp/my.map31
-rw-r--r--xs/xsp/typemap.xspt19
1371 files changed, 465166 insertions, 9768 deletions
diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt
index 0a76721a4..755856dde 100644
--- a/xs/CMakeLists.txt
+++ b/xs/CMakeLists.txt
@@ -2,17 +2,22 @@
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
+# Enable C11 language standard.
+set(CMAKE_C_STANDARD 11)
+set(CMAKE_C_STANDARD_REQUIRED ON)
+
# Add our own cmake module path.
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules/)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Workaround for an old CMake, which does not understand CMAKE_CXX_STANDARD.
- add_compile_options(-std=c++11 -Wall)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall" )
+ find_package(PkgConfig REQUIRED)
endif()
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX)
# Adding -fext-numeric-literals to enable GCC extensions on definitions of quad float literals, which are required by Boost.
- add_compile_options(-fext-numeric-literals)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fext-numeric-literals" )
endif()
# Where all the bundled libraries reside?
@@ -25,11 +30,18 @@ include_directories(${LIBDIR}/libslic3r)
if(WIN32)
# BOOST_ALL_NO_LIB: Avoid the automatic linking of Boost libraries on Windows. Rather rely on explicit linking.
- add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -DBOOST_ALL_NO_LIB)
+ add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -DBOOST_ALL_NO_LIB -DBOOST_USE_WINAPI_VERSION=0x601)
# -D_ITERATOR_DEBUG_LEVEL)
+ if(WIN10SDK_PATH)
+ message("Building with Win10 Netfabb STL fixing service support")
+ add_definitions(-DHAS_WIN10SDK)
+ include_directories("${WIN10SDK_PATH}/Include")
+ else()
+ message("Building without Win10 Netfabb STL fixing service support")
+ endif()
endif()
-add_definitions(-DwxUSE_UNICODE -D_UNICODE -DUNICODE)
+add_definitions(-DwxUSE_UNICODE -D_UNICODE -DUNICODE -DWXINTL_NO_GETTEXT_MACRO)
add_library(libslic3r STATIC
${LIBDIR}/libslic3r/BoundingBox.cpp
@@ -54,6 +66,7 @@ add_library(libslic3r STATIC
${LIBDIR}/libslic3r/ExtrusionEntityCollection.hpp
${LIBDIR}/libslic3r/ExtrusionSimulator.cpp
${LIBDIR}/libslic3r/ExtrusionSimulator.hpp
+ ${LIBDIR}/libslic3r/FileParserError.hpp
${LIBDIR}/libslic3r/Fill/Fill.cpp
${LIBDIR}/libslic3r/Fill/Fill.hpp
${LIBDIR}/libslic3r/Fill/Fill3DHoneycomb.cpp
@@ -127,6 +140,7 @@ add_library(libslic3r STATIC
${LIBDIR}/libslic3r/Line.hpp
${LIBDIR}/libslic3r/Model.cpp
${LIBDIR}/libslic3r/Model.hpp
+ ${LIBDIR}/libslic3r/ModelArrange.hpp
${LIBDIR}/libslic3r/MotionPlanner.cpp
${LIBDIR}/libslic3r/MotionPlanner.hpp
${LIBDIR}/libslic3r/MultiPoint.cpp
@@ -146,6 +160,7 @@ add_library(libslic3r STATIC
${LIBDIR}/libslic3r/PolylineCollection.hpp
${LIBDIR}/libslic3r/Print.cpp
${LIBDIR}/libslic3r/Print.hpp
+ ${LIBDIR}/libslic3r/PrintExport.hpp
${LIBDIR}/libslic3r/PrintConfig.cpp
${LIBDIR}/libslic3r/PrintConfig.hpp
${LIBDIR}/libslic3r/PrintObject.cpp
@@ -164,19 +179,38 @@ add_library(libslic3r STATIC
${LIBDIR}/libslic3r/SVG.hpp
${LIBDIR}/libslic3r/TriangleMesh.cpp
${LIBDIR}/libslic3r/TriangleMesh.hpp
+ ${LIBDIR}/libslic3r/SLABasePool.hpp
+ ${LIBDIR}/libslic3r/SLABasePool.cpp
# ${LIBDIR}/libslic3r/utils.cpp
${LIBDIR}/libslic3r/Utils.hpp
+
)
add_library(libslic3r_gui STATIC
+ ${LIBDIR}/slic3r/GUI/AboutDialog.cpp
+ ${LIBDIR}/slic3r/GUI/AboutDialog.hpp
${LIBDIR}/slic3r/GUI/AppConfig.cpp
${LIBDIR}/slic3r/GUI/AppConfig.hpp
${LIBDIR}/slic3r/GUI/BackgroundSlicingProcess.cpp
${LIBDIR}/slic3r/GUI/BackgroundSlicingProcess.hpp
+ ${LIBDIR}/slic3r/GUI/BitmapCache.cpp
+ ${LIBDIR}/slic3r/GUI/BitmapCache.hpp
+ ${LIBDIR}/slic3r/GUI/ConfigSnapshotDialog.cpp
+ ${LIBDIR}/slic3r/GUI/ConfigSnapshotDialog.hpp
${LIBDIR}/slic3r/GUI/3DScene.cpp
${LIBDIR}/slic3r/GUI/3DScene.hpp
${LIBDIR}/slic3r/GUI/GLShader.cpp
- ${LIBDIR}/slic3r/GUI/GLShader.hpp
+ ${LIBDIR}/slic3r/GUI/GLShader.hpp
+ ${LIBDIR}/slic3r/GUI/GLCanvas3D.hpp
+ ${LIBDIR}/slic3r/GUI/GLCanvas3D.cpp
+ ${LIBDIR}/slic3r/GUI/GLCanvas3DManager.hpp
+ ${LIBDIR}/slic3r/GUI/GLCanvas3DManager.cpp
+ ${LIBDIR}/slic3r/GUI/GLGizmo.hpp
+ ${LIBDIR}/slic3r/GUI/GLGizmo.cpp
+ ${LIBDIR}/slic3r/GUI/GLTexture.hpp
+ ${LIBDIR}/slic3r/GUI/GLTexture.cpp
+ ${LIBDIR}/slic3r/GUI/GLToolbar.hpp
+ ${LIBDIR}/slic3r/GUI/GLToolbar.cpp
${LIBDIR}/slic3r/GUI/Preferences.cpp
${LIBDIR}/slic3r/GUI/Preferences.hpp
${LIBDIR}/slic3r/GUI/Preset.cpp
@@ -187,6 +221,10 @@ add_library(libslic3r_gui STATIC
${LIBDIR}/slic3r/GUI/PresetHints.hpp
${LIBDIR}/slic3r/GUI/GUI.cpp
${LIBDIR}/slic3r/GUI/GUI.hpp
+ ${LIBDIR}/slic3r/GUI/GUI_ObjectParts.cpp
+ ${LIBDIR}/slic3r/GUI/GUI_ObjectParts.hpp
+ ${LIBDIR}/slic3r/GUI/LambdaObjectDialog.cpp
+ ${LIBDIR}/slic3r/GUI/LambdaObjectDialog.hpp
${LIBDIR}/slic3r/GUI/Tab.cpp
${LIBDIR}/slic3r/GUI/Tab.hpp
${LIBDIR}/slic3r/GUI/TabIface.cpp
@@ -201,16 +239,57 @@ add_library(libslic3r_gui STATIC
${LIBDIR}/slic3r/GUI/2DBed.hpp
${LIBDIR}/slic3r/GUI/wxExtensions.cpp
${LIBDIR}/slic3r/GUI/wxExtensions.hpp
+ ${LIBDIR}/slic3r/GUI/WipeTowerDialog.cpp
+ ${LIBDIR}/slic3r/GUI/WipeTowerDialog.hpp
+ ${LIBDIR}/slic3r/GUI/RammingChart.cpp
+ ${LIBDIR}/slic3r/GUI/RammingChart.hpp
${LIBDIR}/slic3r/GUI/BonjourDialog.cpp
${LIBDIR}/slic3r/GUI/BonjourDialog.hpp
+ ${LIBDIR}/slic3r/GUI/ButtonsDescription.cpp
+ ${LIBDIR}/slic3r/GUI/ButtonsDescription.hpp
+ ${LIBDIR}/slic3r/Config/Snapshot.cpp
+ ${LIBDIR}/slic3r/Config/Snapshot.hpp
+ ${LIBDIR}/slic3r/Config/Version.cpp
+ ${LIBDIR}/slic3r/Config/Version.hpp
${LIBDIR}/slic3r/Utils/ASCIIFolding.cpp
${LIBDIR}/slic3r/Utils/ASCIIFolding.hpp
+ ${LIBDIR}/slic3r/Utils/Serial.cpp
+ ${LIBDIR}/slic3r/Utils/Serial.hpp
+ ${LIBDIR}/slic3r/GUI/ConfigWizard.cpp
+ ${LIBDIR}/slic3r/GUI/ConfigWizard.hpp
+ ${LIBDIR}/slic3r/GUI/MsgDialog.cpp
+ ${LIBDIR}/slic3r/GUI/MsgDialog.hpp
+ ${LIBDIR}/slic3r/GUI/UpdateDialogs.cpp
+ ${LIBDIR}/slic3r/GUI/UpdateDialogs.hpp
+ ${LIBDIR}/slic3r/GUI/FirmwareDialog.cpp
+ ${LIBDIR}/slic3r/GUI/FirmwareDialog.hpp
+ ${LIBDIR}/slic3r/GUI/ProgressStatusBar.hpp
+ ${LIBDIR}/slic3r/GUI/ProgressStatusBar.cpp
${LIBDIR}/slic3r/Utils/Http.cpp
${LIBDIR}/slic3r/Utils/Http.hpp
+ ${LIBDIR}/slic3r/Utils/FixModelByWin10.cpp
+ ${LIBDIR}/slic3r/Utils/FixModelByWin10.hpp
+ ${LIBDIR}/slic3r/Utils/PrintHostSendDialog.cpp
+ ${LIBDIR}/slic3r/Utils/PrintHostSendDialog.hpp
${LIBDIR}/slic3r/Utils/OctoPrint.cpp
${LIBDIR}/slic3r/Utils/OctoPrint.hpp
+ ${LIBDIR}/slic3r/Utils/Duet.cpp
+ ${LIBDIR}/slic3r/Utils/Duet.hpp
+ ${LIBDIR}/slic3r/Utils/PrintHost.cpp
+ ${LIBDIR}/slic3r/Utils/PrintHost.hpp
${LIBDIR}/slic3r/Utils/Bonjour.cpp
${LIBDIR}/slic3r/Utils/Bonjour.hpp
+ ${LIBDIR}/slic3r/Utils/PresetUpdater.cpp
+ ${LIBDIR}/slic3r/Utils/PresetUpdater.hpp
+ ${LIBDIR}/slic3r/Utils/Time.cpp
+ ${LIBDIR}/slic3r/Utils/Time.hpp
+ ${LIBDIR}/slic3r/Utils/HexFile.cpp
+ ${LIBDIR}/slic3r/Utils/HexFile.hpp
+ ${LIBDIR}/slic3r/ProgressIndicator.hpp
+ ${LIBDIR}/slic3r/AppController.hpp
+ ${LIBDIR}/slic3r/AppController.cpp
+ ${LIBDIR}/slic3r/AppControllerWx.cpp
+ ${LIBDIR}/slic3r/Strings.hpp
)
add_library(admesh STATIC
@@ -301,12 +380,61 @@ add_library(Shiny STATIC
${LIBDIR}/Shiny/ShinyZone.h
)
+add_library(semver STATIC
+ ${LIBDIR}/semver/semver.h
+ ${LIBDIR}/semver/semver.c
+)
+
+# ##############################################################################
+# Configure rasterizer target
+# ##############################################################################
+
+find_package(PNG QUIET)
+
+option(RASTERIZER_FORCE_BUILTIN_LIBPNG "Force the usage of builting libpng instead of the system version." OFF)
+
+add_library(rasterizer STATIC
+ ${LIBDIR}/libslic3r/Rasterizer/Rasterizer.hpp
+ ${LIBDIR}/libslic3r/Rasterizer/Rasterizer.cpp
+)
+
+if(PNG_FOUND AND NOT RASTERIZER_FORCE_BUILTIN_LIBPNG)
+ message(STATUS "Using system libpng.")
+ target_link_libraries(rasterizer PRIVATE ${PNG_LIBRARIES})
+ target_include_directories(rasterizer PRIVATE ${PNG_INCLUDE_DIRS})
+ target_compile_definitions(rasterizer PRIVATE ${PNG_DEFINITIONS})
+else()
+ set(ZLIB_LIBRARY "")
+ message(WARNING "Using builtin libpng. This can cause crashes on some platforms.")
+ add_subdirectory( ${LIBDIR}/png/zlib)
+
+ set(ZLIB_INCLUDE_DIR
+ ${LIBDIR}/png/zlib
+ ${CMAKE_CURRENT_BINARY_DIR}/src/png/zlib
+ )
+
+ add_subdirectory( ${LIBDIR}/png/libpng )
+ set_target_properties(zlibstatic PROPERTIES POSITION_INDEPENDENT_CODE ON)
+ set_target_properties(png_static PROPERTIES POSITION_INDEPENDENT_CODE ON)
+
+ target_include_directories(rasterizer PRIVATE
+ ${LIBDIR}/png/libpng
+ ${CMAKE_CURRENT_BINARY_DIR}/src/png/libpng
+ )
+ target_link_libraries(rasterizer PRIVATE png_static zlibstatic)
+
+endif()
+
+target_link_libraries(libslic3r rasterizer )
+
+# ##############################################################################
+
# Generate the Slic3r Perl module (XS) typemap file.
set(MyTypemap ${CMAKE_CURRENT_BINARY_DIR}/typemap)
add_custom_command(
OUTPUT ${MyTypemap}
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/xsp/my.map
- COMMAND ${PERL_EXECUTABLE} -MExtUtils::Typemaps -MExtUtils::Typemaps::Basic -e "$typemap = ExtUtils::Typemaps->new(file => \"${CMAKE_CURRENT_LIST_DIR}/xsp/my.map\"); $typemap->merge(typemap => ExtUtils::Typemaps::Basic->new); $typemap->write(file => \"${MyTypemap}\")"
+ COMMAND ${PERL5LIB_ENV_CMD} ${PERL_EXECUTABLE} -MExtUtils::Typemaps -MExtUtils::Typemaps::Basic -e "$typemap = ExtUtils::Typemaps->new(file => \"${CMAKE_CURRENT_LIST_DIR}/xsp/my.map\"); $typemap->merge(typemap => ExtUtils::Typemaps::Basic->new); $typemap->write(file => \"${MyTypemap}\")"
VERBATIM
)
@@ -351,7 +479,10 @@ set(XS_XSP_FILES
${XSP_DIR}/Surface.xsp
${XSP_DIR}/SurfaceCollection.xsp
${XSP_DIR}/TriangleMesh.xsp
- ${XSP_DIR}/Utils_OctoPrint.xsp
+ ${XSP_DIR}/Utils_PrintHost.xsp
+ ${XSP_DIR}/Utils_PresetUpdater.xsp
+ ${XSP_DIR}/AppController.xsp
+ ${XSP_DIR}/ProgressStatusBar.xsp
${XSP_DIR}/XS.xsp
)
foreach (file ${XS_XSP_FILES})
@@ -370,7 +501,8 @@ set(XS_MAIN_CPP ${CMAKE_CURRENT_BINARY_DIR}/XS.cpp)
add_custom_command(
OUTPUT ${XS_MAIN_CPP}
DEPENDS ${MyTypemap} ${XS_XSP_FILES} ${CMAKE_CURRENT_LIST_DIR}/xsp/typemap.xspt
- COMMAND COMMAND xsubpp -typemap typemap -output ${XS_MAIN_CPP} -hiertype ${XS_MAIN_XS}
+ COMMAND ${PERL5LIB_ENV_CMD} xsubpp -typemap typemap -output ${XS_MAIN_CPP} -hiertype ${XS_MAIN_XS}
+ VERBATIM
)
# Define the Perl XS shared library.
@@ -397,7 +529,7 @@ if(APPLE)
# Ignore undefined symbols of the perl interpreter, they will be found in the caller image.
target_link_libraries(XS "-undefined dynamic_lookup")
endif()
-target_link_libraries(XS libslic3r libslic3r_gui admesh miniz clipper nowide polypartition poly2tri)
+target_link_libraries(XS libslic3r libslic3r_gui admesh miniz clipper nowide polypartition poly2tri semver avrdude qhull)
if(SLIC3R_PROFILE)
target_link_libraries(XS Shiny)
endif()
@@ -405,7 +537,7 @@ endif()
# Add the OpenGL and GLU libraries.
if (SLIC3R_GUI)
if (MSVC)
- target_link_libraries(XS OpenGL32.Lib GlU32.Lib)
+ target_link_libraries(XS user32.lib Setupapi.lib OpenGL32.Lib GlU32.Lib)
elseif (MINGW)
target_link_libraries(XS -lopengl32)
elseif (APPLE)
@@ -434,6 +566,14 @@ if (WIN32)
target_compile_definitions(XS PRIVATE -DNOGDI -DNOMINMAX -DHAS_BOOL)
endif ()
+# SLIC3R_MSVC_PDB
+if (MSVC AND SLIC3R_MSVC_PDB AND ${CMAKE_BUILD_TYPE} STREQUAL "Release")
+ set_target_properties(XS PROPERTIES
+ COMPILE_FLAGS "/Zi"
+ LINK_FLAGS "/DEBUG /OPT:REF /OPT:ICF"
+ )
+endif()
+
## Configuration flags
if (SLIC3R_GUI)
message("Slic3r will be built with GUI support")
@@ -445,10 +585,6 @@ if (SLIC3R_PROFILE)
add_definitions(-DSLIC3R_PROFILE)
endif ()
-if (SLIC3R_HAS_BROKEN_CROAK)
- target_compile_definitions(XS PRIVATE -DSLIC3R_HAS_BROKEN_CROAK)
-endif ()
-
if (CMAKE_BUILD_TYPE MATCHES DEBUG)
target_compile_definitions(XS PRIVATE -DSLIC3R_DEBUG -DDEBUG -D_DEBUG)
else ()
@@ -467,12 +603,12 @@ if (WIN32 AND ";${PerlEmbed_CCFLAGS};" MATCHES ";[-/]Od;")
message("Old CMAKE_CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}")
message("Old CMAKE_CXX_FLAGS_RELWITHDEBINFO: ${CMAKE_CXX_FLAGS_RELEASE}")
message("Old CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS_RELEASE}")
- set(CMAKE_CXX_FLAGS_RELEASE "/MD /Od /Zi /EHsc /DNDEBUG")
- set(CMAKE_C_FLAGS_RELEASE "/MD /Od /Zi /DNDEBUG")
- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MD /Od /Zi /EHsc /DNDEBUG")
- set(CMAKE_C_FLAGS_RELWITHDEBINFO "/MD /Od /Zi /DNDEBUG")
- set(CMAKE_CXX_FLAGS "/MD /Od /Zi /EHsc /DNDEBUG")
- set(CMAKE_C_FLAGS "/MD /Od /Zi /DNDEBUG")
+ set(CMAKE_CXX_FLAGS_RELEASE "/MD /Od /Zi /EHsc /DNDEBUG /DWIN32")
+ set(CMAKE_C_FLAGS_RELEASE "/MD /Od /Zi /DNDEBUG /DWIN32")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MD /Od /Zi /EHsc /DNDEBUG /DWIN32")
+ set(CMAKE_C_FLAGS_RELWITHDEBINFO "/MD /Od /Zi /DNDEBUG /DWIN32")
+ set(CMAKE_CXX_FLAGS "/MD /Od /Zi /EHsc /DNDEBUG /DWIN32")
+ set(CMAKE_C_FLAGS "/MD /Od /Zi /DNDEBUG /DWIN32")
endif()
# The following line will add -fPIC on Linux to make the XS.so rellocable.
add_definitions(${PerlEmbed_CCCDLFLAGS})
@@ -480,6 +616,12 @@ if (WIN32)
target_link_libraries(XS ${PERL_LIBRARY})
endif()
+add_subdirectory(src/avrdude)
+
+add_subdirectory(src/qhull)
+include_directories(${LIBDIR}/qhull/src)
+message(STATUS ${LIBDIR}/qhull/src)
+
## REQUIRED packages
# Find and configure boost
@@ -524,13 +666,22 @@ if (SLIC3R_PRUSACONTROL)
set(wxWidgets_UseAlienWx 1)
if (wxWidgets_UseAlienWx)
set(AlienWx_DEBUG 1)
- find_package(AlienWx REQUIRED COMPONENTS base core adv)
+ find_package(AlienWx REQUIRED COMPONENTS base core adv html gl)
include_directories(${AlienWx_INCLUDE_DIRS})
#add_compile_options(${AlienWx_CXX_FLAGS})
add_definitions(${AlienWx_DEFINITIONS})
set(wxWidgets_LIBRARIES ${AlienWx_LIBRARIES})
+ # On Linux / gtk, we need to have a direct access to gtk+ for some workarounds.
+ if (AlienWx_GUI_TOOLKIT STREQUAL "gtk2")
+ pkg_check_modules(GTK2 gtk+-2.0)
+ include_directories(${GTK2_INCLUDE_DIRS})
+ endif()
+ if (AlienWx_GUI_TOOLKIT STREQUAL "gtk3")
+ pkg_check_modules(GTK3 gtk+-3.0)
+ include_directories(${GTK3_INCLUDE_DIRS})
+ endif()
else ()
- find_package(wxWidgets REQUIRED COMPONENTS base core adv)
+ find_package(wxWidgets REQUIRED COMPONENTS base core adv html gl)
include(${wxWidgets_USE_FILE})
endif ()
add_definitions(-DSLIC3R_GUI -DSLIC3R_PRUS)
@@ -610,6 +761,7 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:XS>" "${PERL_LOCAL_LIB_DIR}/auto/Slic3r/XS/"
COMMAND ${CMAKE_COMMAND} -E make_directory "${PERL_LOCAL_LIB_DIR}/Slic3r/"
COMMAND ${CMAKE_COMMAND} -E copy "${PROJECT_SOURCE_DIR}/xs/lib/Slic3r/XS.pm" "${PERL_LOCAL_LIB_DIR}/Slic3r/"
+ COMMENT "Installing XS.pm and XS.{so,dll,bundle} into the local-lib directory ..."
)
if(APPLE)
add_custom_command(
@@ -620,9 +772,14 @@ if(APPLE)
endif()
# Create a slic3r executable
-add_executable(slic3r ${PROJECT_SOURCE_DIR}/src/slic3r.cpp)
+add_executable(slic3r EXCLUDE_FROM_ALL ${PROJECT_SOURCE_DIR}/src/slic3r.cpp)
target_include_directories(XS PRIVATE src src/libslic3r)
target_link_libraries(slic3r libslic3r libslic3r_gui admesh miniz ${Boost_LIBRARIES} clipper ${EXPAT_LIBRARIES} ${GLEW_LIBRARIES} polypartition poly2tri ${TBB_LIBRARIES} ${wxWidgets_LIBRARIES})
+
+add_executable(slabasebed EXCLUDE_FROM_ALL ${PROJECT_SOURCE_DIR}/src/slabasebed.cpp)
+target_include_directories(slabasebed PRIVATE src src/libslic3r)
+target_link_libraries(slabasebed libslic3r libslic3r_gui qhull admesh miniz ${Boost_LIBRARIES} clipper ${EXPAT_LIBRARIES} ${GLEW_LIBRARIES} polypartition poly2tri ${TBB_LIBRARIES} ${wxWidgets_LIBRARIES} ${CMAKE_DL_LIBS})
+
if(SLIC3R_PROFILE)
target_link_libraries(Shiny)
endif()
@@ -634,7 +791,12 @@ endif ()
if (MSVC)
# Here we associate some additional properties with the MSVC project to enable compilation and debugging out of the box.
- set_target_properties(XS PROPERTIES VS_USER_PROPS "${PROJECT_SOURCE_DIR}/cmake/msvc/xs.wperl64d.props")
+ get_filename_component(PROPS_PERL_BIN_PATH "${PERL_EXECUTABLE}" DIRECTORY)
+ string(REPLACE "/" "\\" PROPS_PERL_BIN_PATH "${PROPS_PERL_BIN_PATH}")
+ string(REPLACE "/" "\\" PROPS_PERL_EXECUTABLE "${PERL_EXECUTABLE}")
+ string(REPLACE "/" "\\" PROPS_CMAKE_SOURCE_DIR "${CMAKE_SOURCE_DIR}")
+ configure_file("${PROJECT_SOURCE_DIR}/cmake/msvc/xs.wperl.props.in" "${CMAKE_BINARY_DIR}/xs.wperl.props" NEWLINE_STYLE CRLF)
+ set_target_properties(XS PROPERTIES VS_USER_PROPS "${CMAKE_BINARY_DIR}/xs.wperl.props")
endif()
# l10n
@@ -647,6 +809,21 @@ add_custom_target(pot
COMMENT "Generate pot file from strings in the source tree"
)
+# ##############################################################################
+# Adding libnest2d project for bin packing...
+# ##############################################################################
+
+set(LIBNEST2D_UNITTESTS ON CACHE BOOL "Force generating unittests for libnest2d")
+
+add_subdirectory(${LIBDIR}/libnest2d)
+target_compile_definitions(libslic3r PUBLIC -DUSE_TBB)
+target_include_directories(libslic3r PUBLIC BEFORE ${LIBNEST2D_INCLUDES})
+target_include_directories(libslic3r_gui PUBLIC BEFORE ${LIBNEST2D_INCLUDES})
+
+message(STATUS "Libnest2D Libraries: ${LIBNEST2D_LIBRARIES}")
+target_link_libraries(libslic3r ${LIBNEST2D_LIBRARIES})
+# ##############################################################################
+
# Installation
install(TARGETS XS DESTINATION ${PERL_VENDORARCH}/auto/Slic3r/XS)
install(FILES lib/Slic3r/XS.pm DESTINATION ${PERL_VENDORLIB}/Slic3r)
diff --git a/xs/lib/Slic3r/XS.pm b/xs/lib/Slic3r/XS.pm
index 5105ee0ad..3073d068e 100644
--- a/xs/lib/Slic3r/XS.pm
+++ b/xs/lib/Slic3r/XS.pm
@@ -12,7 +12,9 @@ our $VERSION = '0.01';
BEGIN {
if ($^O eq 'MSWin32') {
eval "use Wx";
-# eval "use Wx::Html";
+ eval "use Wx::GLCanvas";
+ eval "use Wx::GLContext";
+ eval "use Wx::Html";
eval "use Wx::Print"; # because of some Wx bug, thread creation fails if we don't have this (looks like Wx::Printout is hard-coded in some thread cleanup code)
}
}
@@ -31,16 +33,6 @@ use overload
'@{}' => sub { $_[0]->arrayref },
'fallback' => 1;
-package Slic3r::Point3;
-use overload
- '@{}' => sub { [ $_[0]->x, $_[0]->y, $_[0]->z ] }, #,
- 'fallback' => 1;
-
-sub pp {
- my ($self) = @_;
- return [ @$self ];
-}
-
package Slic3r::Pointf;
use overload
'@{}' => sub { $_[0]->arrayref },
@@ -273,6 +265,7 @@ for my $class (qw(
Slic3r::Geometry::BoundingBox
Slic3r::Geometry::BoundingBoxf
Slic3r::Geometry::BoundingBoxf3
+ Slic3r::GUI::_3DScene::GLShader
Slic3r::GUI::_3DScene::GLVolume
Slic3r::GUI::Preset
Slic3r::GUI::PresetCollection
diff --git a/xs/src/Shiny/ShinyPrereqs.h b/xs/src/Shiny/ShinyPrereqs.h
index a392515c7..5a3044dbc 100644
--- a/xs/src/Shiny/ShinyPrereqs.h
+++ b/xs/src/Shiny/ShinyPrereqs.h
@@ -25,6 +25,9 @@ THE SOFTWARE.
#ifndef SHINY_PREREQS_H
#define SHINY_PREREQS_H
+
+#include <stdint.h>
+
/*---------------------------------------------------------------------------*/
#ifndef FALSE
diff --git a/xs/src/Shiny/ShinyTools.c b/xs/src/Shiny/ShinyTools.c
index bfc0bcdf5..4058e2285 100644
--- a/xs/src/Shiny/ShinyTools.c
+++ b/xs/src/Shiny/ShinyTools.c
@@ -93,8 +93,11 @@ float ShinyGetTickInvFreq(void) {
#elif SHINY_PLATFORM == SHINY_PLATFORM_POSIX
+//#include <time.h>
+//#include <sys/time.h>
+
void ShinyGetTicks(shinytick_t *p) {
- timeval time;
+ struct timeval time;
gettimeofday(&time, NULL);
*p = time.tv_sec * 1000000 + time.tv_usec;
diff --git a/xs/src/admesh/connect.cpp b/xs/src/admesh/connect.cpp
index e9129d007..da5b66720 100644
--- a/xs/src/admesh/connect.cpp
+++ b/xs/src/admesh/connect.cpp
@@ -25,11 +25,11 @@
#include <string.h>
#include <math.h>
+#include <boost/detail/endian.hpp>
+
#include "stl.h"
-static void stl_match_neighbors_exact(stl_file *stl,
- stl_hash_edge *edge_a, stl_hash_edge *edge_b);
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,
@@ -43,7 +43,6 @@ static int stl_load_edge_nearby(stl_file *stl, stl_hash_edge *edge,
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_get_hash_for_edge(int M, stl_hash_edge *edge);
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);
@@ -82,37 +81,20 @@ stl_check_facets_exact(stl_file *stl) {
for(i = 0; i < stl->stats.number_of_facets; i++) {
facet = stl->facet_start[i];
- // Positive and negative zeros are possible in the floats, which are considered equal by the FP unit.
- // When using a memcmp on raw floats, those numbers report to be different.
- // Unify all +0 and -0 to +0 to make the floats equal under memcmp.
- {
- uint32_t *f = (uint32_t*)&facet;
- for (int j = 0; j < 12; ++ j, ++ f) // 3x vertex + normal: 4x3 = 12 floats
- if (*f == 0x80000000)
- // Negative zero, switch to positive zero.
- *f = 0;
- }
-
- /* If any two of the three vertices are found to be exactally the same, call them degenerate and remove the facet. */
- if( !memcmp(&facet.vertex[0], &facet.vertex[1],
- sizeof(stl_vertex))
- || !memcmp(&facet.vertex[1], &facet.vertex[2],
- sizeof(stl_vertex))
- || !memcmp(&facet.vertex[0], &facet.vertex[2],
- sizeof(stl_vertex))) {
+ // 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--;
+ -- 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_match_neighbors_exact);
+ 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);
@@ -131,28 +113,33 @@ stl_load_edge_exact(stl_file *stl, stl_hash_edge *edge,
if (stl->error) return;
{
- float diff_x = ABS(a->x - b->x);
- float diff_y = ABS(a->y - b->y);
- float diff_z = ABS(a->z - b->z);
- float max_diff = STL_MAX(diff_x, diff_y);
- max_diff = STL_MAX(diff_z, max_diff);
- stl->stats.shortest_edge = STL_MIN(max_diff, stl->stats.shortest_edge);
+ 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 ((a->x != b->x) ?
- (a->x < b->x) :
- ((a->y != b->y) ?
- (a->y < b->y) :
- (a->z < b->z))) {
- memcpy(&edge->key[0], a, sizeof(stl_vertex));
- memcpy(&edge->key[3], b, sizeof(stl_vertex));
+ if (stl_vertex_lower(*a, *b)) {
} else {
- memcpy(&edge->key[0], b, sizeof(stl_vertex));
- memcpy(&edge->key[3], a, sizeof(stl_vertex));
+ 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
@@ -188,21 +175,17 @@ stl_initialize_facet_check_exact(stl_file *stl) {
}
}
-static void
-insert_hash_edge(stl_file *stl, stl_hash_edge edge,
+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)) {
- stl_hash_edge *link;
- stl_hash_edge *new_edge;
- stl_hash_edge *temp;
- int chain_number;
-
+ stl_hash_edge *edge_a, stl_hash_edge *edge_b))
+{
if (stl->error) return;
- chain_number = stl_get_hash_for_edge(stl->M, &edge);
-
- link = stl->heads[chain_number];
+ 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));
@@ -252,30 +235,17 @@ insert_hash_edge(stl_file *stl, stl_hash_edge edge,
}
}
-
-static int
-stl_get_hash_for_edge(int M, stl_hash_edge *edge) {
- return ((edge->key[0] / 23 + edge->key[1] / 19 + edge->key[2] / 17
- + edge->key[3] /13 + edge->key[4] / 11 + edge->key[5] / 7 ) % M);
-}
-
-static int
-stl_compare_function(stl_hash_edge *edge_a, stl_hash_edge *edge_b) {
- if(edge_a->facet_number == edge_b->facet_number) {
- return 1; /* Don't match edges of the same facet */
- } else {
- return memcmp(edge_a, edge_b, SIZEOF_EDGE_SORT);
- }
+// 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) {
- stl_hash_edge edge[3];
- stl_facet facet;
- int i;
- int j;
-
- if (stl->error) return;
+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)
@@ -286,27 +256,19 @@ stl_check_facets_nearby(stl_file *stl, float tolerance) {
stl_initialize_facet_check_nearby(stl);
- for(i = 0; i < stl->stats.number_of_facets; i++) {
- facet = stl->facet_start[i];
- // Positive and negative zeros are possible in the floats, which are considered equal by the FP unit.
- // When using a memcmp on raw floats, those numbers report to be different.
- // Unify all +0 and -0 to +0 to make the floats equal under memcmp.
- {
- uint32_t *f = (uint32_t*)&facet;
- for (int j = 0; j < 12; ++ j, ++ f) // 3x vertex + normal: 4x3 = 12 floats
- if (*f == 0x80000000)
- // Negative zero, switch to positive zero.
- *f = 0;
- }
- for(j = 0; j < 3; j++) {
+ 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) {
- edge[j].facet_number = i;
- edge[j].which_edge = j;
- if(stl_load_edge_nearby(stl, &edge[j], &facet.vertex[j],
+ 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[j], stl_match_neighbors_nearby);
+ insert_hash_edge(stl, edge, stl_match_neighbors_nearby);
}
}
}
@@ -315,27 +277,17 @@ stl_check_facets_nearby(stl_file *stl, float tolerance) {
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) {
+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.
- uint32_t vertex1[3] = {
- (uint32_t)((a->x - stl->stats.min.x) / tolerance),
- (uint32_t)((a->y - stl->stats.min.y) / tolerance),
- (uint32_t)((a->z - stl->stats.min.z) / tolerance)
- };
- uint32_t vertex2[3] = {
- (uint32_t)((b->x - stl->stats.min.x) / tolerance),
- (uint32_t)((b->y - stl->stats.min.y) / tolerance),
- (uint32_t)((b->z - stl->stats.min.z) / tolerance)
- };
-
- if( (vertex1[0] == vertex2[0])
- && (vertex1[1] == vertex2[1])
- && (vertex1[2] == vertex2[2])) {
- /* Both vertices hash to the same value */
+ 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.
@@ -344,30 +296,27 @@ stl_load_edge_nearby(stl_file *stl, stl_hash_edge *edge,
((vertex1[1] != vertex2[1]) ?
(vertex1[1] < vertex2[1]) :
(vertex1[2] < vertex2[2]))) {
- memcpy(&edge->key[0], vertex1, sizeof(stl_vertex));
- memcpy(&edge->key[3], vertex2, sizeof(stl_vertex));
+ 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, sizeof(stl_vertex));
- memcpy(&edge->key[3], vertex1, sizeof(stl_vertex));
+ 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) {
- int i;
- stl_hash_edge *temp;
-
- if (stl->error) return;
+static void stl_free_edges(stl_file *stl)
+{
+ if (stl->error)
+ return;
if(stl->stats.malloced != stl->stats.freed) {
- for(i = 0; i < stl->M; i++) {
- for(temp = stl->heads[i]; stl->heads[i] != stl->tail;
- temp = stl->heads[i]) {
+ 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++;
+ ++ stl->stats.freed;
}
}
}
@@ -375,8 +324,8 @@ stl_free_edges(stl_file *stl) {
free(stl->tail);
}
-static void
-stl_initialize_facet_check_nearby(stl_file *stl) {
+static void stl_initialize_facet_check_nearby(stl_file *stl)
+{
int i;
if (stl->error) return;
@@ -467,16 +416,8 @@ stl_record_neighbors(stl_file *stl,
}
}
-static void
-stl_match_neighbors_exact(stl_file *stl,
- stl_hash_edge *edge_a, stl_hash_edge *edge_b) {
- if (stl->error) return;
- stl_record_neighbors(stl, edge_a, edge_b);
-}
-
-static void
-stl_match_neighbors_nearby(stl_file *stl,
- stl_hash_edge *edge_a, stl_hash_edge *edge_b) {
+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;
@@ -517,9 +458,7 @@ stl_match_neighbors_nearby(stl_file *stl,
}
-static void
-stl_change_vertices(stl_file *stl, int facet_num, int vnot,
- stl_vertex new_vertex) {
+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;
@@ -551,30 +490,30 @@ stl_change_vertices(stl_file *stl, int facet_num, int vnot,
}
}
#if 0
- if (stl->facet_start[facet_num].vertex[pivot_vertex].x == new_vertex.x &&
- stl->facet_start[facet_num].vertex[pivot_vertex].y == new_vertex.y &&
- stl->facet_start[facet_num].vertex[pivot_vertex].z == new_vertex.z)
+ 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.x, new_vertex.y, new_vertex.z);
+ new_vertex(0), new_vertex(1), new_vertex(2));
else {
- if (stl->facet_start[facet_num].vertex[pivot_vertex].x != new_vertex.x)
+ 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].x,
- *reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex].x),
- new_vertex.x,
- *reinterpret_cast<const int*>(&new_vertex.x));
- if (stl->facet_start[facet_num].vertex[pivot_vertex].y != new_vertex.y)
+ 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].y,
- *reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex].y),
- new_vertex.y,
- *reinterpret_cast<const int*>(&new_vertex.y));
- if (stl->facet_start[facet_num].vertex[pivot_vertex].z != new_vertex.z)
+ 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].z,
- *reinterpret_cast<const int*>(&stl->facet_start[facet_num].vertex[pivot_vertex].z),
- new_vertex.z,
- *reinterpret_cast<const int*>(&new_vertex.z));
+ 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;
@@ -595,7 +534,6 @@ Try using a smaller tolerance or don't do a nearby check\n");
}
}
-
static void
stl_which_vertices_to_change(stl_file *stl, stl_hash_edge *edge_a,
stl_hash_edge *edge_b, int *facet1, int *vertex1,
@@ -622,11 +560,10 @@ stl_which_vertices_to_change(stl_file *stl, stl_hash_edge *edge_a,
v1b = (edge_b->which_edge + 1) % 3;
}
- /* Of the first pair, which vertex, if any, should be changed */
- if(!memcmp(&stl->facet_start[edge_a->facet_number].vertex[v1a],
- &stl->facet_start[edge_b->facet_number].vertex[v1b],
- sizeof(stl_vertex))) {
- /* These facets are already equal. No need to change. */
+ // 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)
@@ -644,10 +581,9 @@ stl_which_vertices_to_change(stl_file *stl, stl_hash_edge *edge_a,
}
/* Of the second pair, which vertex, if any, should be changed */
- if(!memcmp(&stl->facet_start[edge_a->facet_number].vertex[v2a],
- &stl->facet_start[edge_b->facet_number].vertex[v2b],
- sizeof(stl_vertex))) {
- /* These facets are already equal. No need to change. */
+ 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)
@@ -718,40 +654,35 @@ in stl_remove_facet: neighbor = %d numfacets = %d this is wrong\n",
}
}
-void
-stl_remove_unconnected_facets(stl_file *stl) {
+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;
- int i;
-
- if (stl->error) return;
-
- /* remove degenerate facets */
- for(i = 0; i < stl->stats.number_of_facets; i++) {
- if( !memcmp(&stl->facet_start[i].vertex[0],
- &stl->facet_start[i].vertex[1], sizeof(stl_vertex))
- || !memcmp(&stl->facet_start[i].vertex[1],
- &stl->facet_start[i].vertex[2], sizeof(stl_vertex))
- || !memcmp(&stl->facet_start[i].vertex[0],
- &stl->facet_start[i].vertex[2], sizeof(stl_vertex))) {
+ // 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(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. */
+ // 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--;
+ -- i;
}
}
}
@@ -771,30 +702,24 @@ stl_remove_degenerate(stl_file *stl, int facet) {
if (stl->error) return;
- if( !memcmp(&stl->facet_start[facet].vertex[0],
- &stl->facet_start[facet].vertex[1], sizeof(stl_vertex))
- && !memcmp(&stl->facet_start[facet].vertex[1],
- &stl->facet_start[facet].vertex[2], sizeof(stl_vertex))) {
+ 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(!memcmp(&stl->facet_start[facet].vertex[0],
- &stl->facet_start[facet].vertex[1], sizeof(stl_vertex))) {
+ if (stl->facet_start[facet].vertex[0] == stl->facet_start[facet].vertex[1]) {
edge1 = 1;
edge2 = 2;
edge3 = 0;
- } else if(!memcmp(&stl->facet_start[facet].vertex[1],
- &stl->facet_start[facet].vertex[2], sizeof(stl_vertex))) {
+ } else if (stl->facet_start[facet].vertex[1] == stl->facet_start[facet].vertex[2]) {
edge1 = 0;
edge2 = 2;
edge3 = 1;
- } else if(!memcmp(&stl->facet_start[facet].vertex[2],
- &stl->facet_start[facet].vertex[0], sizeof(stl_vertex))) {
+ } else if (stl->facet_start[facet].vertex[2] == stl->facet_start[facet].vertex[0]) {
edge1 = 0;
edge2 = 1;
edge3 = 2;
@@ -883,7 +808,7 @@ stl_fill_holes(stl_file *stl) {
stl_load_edge_exact(stl, &edge, &facet.vertex[j],
&facet.vertex[(j + 1) % 3]);
- insert_hash_edge(stl, edge, stl_match_neighbors_exact);
+ insert_hash_edge(stl, edge, stl_record_neighbors);
}
}
@@ -939,7 +864,7 @@ stl_fill_holes(stl_file *stl) {
stl_load_edge_exact(stl, &edge, &new_facet.vertex[k],
&new_facet.vertex[(k + 1) % 3]);
- insert_hash_edge(stl, edge, stl_match_neighbors_exact);
+ insert_hash_edge(stl, edge, stl_record_neighbors);
}
break;
} else {
@@ -977,9 +902,7 @@ stl_add_facet(stl_file *stl, stl_facet *new_facet) {
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.x = 0.0;
- stl->facet_start[stl->stats.number_of_facets].normal.y = 0.0;
- stl->facet_start[stl->stats.number_of_facets].normal.z = 0.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;
diff --git a/xs/src/admesh/normals.cpp b/xs/src/admesh/normals.cpp
index b7cf9a8ab..a8faa44bd 100644
--- a/xs/src/admesh/normals.cpp
+++ b/xs/src/admesh/normals.cpp
@@ -27,12 +27,6 @@
#include "stl.h"
-static void stl_reverse_vector(float v[]) {
- v[0] *= -1;
- v[1] *= -1;
- v[2] *= -1;
-}
-
static int stl_check_normal_vector(stl_file *stl, int facet_num, int normal_fix_flag);
static void
@@ -228,102 +222,52 @@ static int stl_check_normal_vector(stl_file *stl, int facet_num, int normal_fix_
/* Returns 2 if the normal is not within tolerance and backwards */
/* Returns 4 if the status is unknown. */
- float normal[3];
- float test_norm[3];
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();
- if( (ABS(normal[0] - facet->normal.x) < 0.001)
- && (ABS(normal[1] - facet->normal.y) < 0.001)
- && (ABS(normal[2] - facet->normal.z) < 0.001)) {
+ 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.x = normal[0];
- facet->normal.y = normal[1];
- facet->normal.z = normal[2];
+ facet->normal = normal;
return 0;
}
- test_norm[0] = facet->normal.x;
- test_norm[1] = facet->normal.y;
- test_norm[2] = facet->normal.z;
-
+ stl_normal test_norm = facet->normal;
stl_normalize_vector(test_norm);
- if( (ABS(normal[0] - test_norm[0]) < 0.001)
- && (ABS(normal[1] - test_norm[1]) < 0.001)
- && (ABS(normal[2] - test_norm[2]) < 0.001)) {
+ 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.x = normal[0];
- facet->normal.y = normal[1];
- facet->normal.z = normal[2];
+ facet->normal = normal;
stl->stats.normals_fixed += 1;
}
return 1;
}
- stl_reverse_vector(test_norm);
- if( (ABS(normal[0] - test_norm[0]) < 0.001)
- && (ABS(normal[1] - test_norm[1]) < 0.001)
- && (ABS(normal[2] - test_norm[2]) < 0.001)) {
- /* Facet is backwards. */
+ 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.x = normal[0];
- facet->normal.y = normal[1];
- facet->normal.z = normal[2];
+ facet->normal = normal;
stl->stats.normals_fixed += 1;
}
return 2;
}
if(normal_fix_flag) {
- facet->normal.x = normal[0];
- facet->normal.y = normal[1];
- facet->normal.z = normal[2];
+ facet->normal = normal;
stl->stats.normals_fixed += 1;
}
return 4;
}
-void stl_calculate_normal(float normal[], stl_facet *facet) {
- float v1[3] = {
- facet->vertex[1].x - facet->vertex[0].x,
- facet->vertex[1].y - facet->vertex[0].y,
- facet->vertex[1].z - facet->vertex[0].z
- };
- float v2[3] = {
- facet->vertex[2].x - facet->vertex[0].x,
- facet->vertex[2].y - facet->vertex[0].y,
- facet->vertex[2].z - facet->vertex[0].z
- };
- normal[0] = (float)((double)v1[1] * (double)v2[2]) - ((double)v1[2] * (double)v2[1]);
- normal[1] = (float)((double)v1[2] * (double)v2[0]) - ((double)v1[0] * (double)v2[2]);
- normal[2] = (float)((double)v1[0] * (double)v2[1]) - ((double)v1[1] * (double)v2[0]);
-}
-
-void stl_normalize_vector(float v[]) {
- double length;
- double factor;
- float min_normal_length;
-
- length = sqrt((double)v[0] * (double)v[0] + (double)v[1] * (double)v[1] + (double)v[2] * (double)v[2]);
- min_normal_length = 0.000000000001;
- if(length < min_normal_length) {
- v[0] = 0.0;
- v[1] = 0.0;
- v[2] = 0.0;
- return;
- }
- factor = 1.0 / length;
- v[0] *= factor;
- v[1] *= factor;
- v[2] *= factor;
-}
-
-void
-stl_fix_normal_values(stl_file *stl) {
+void stl_fix_normal_values(stl_file *stl) {
int i;
if (stl->error) return;
@@ -333,20 +277,16 @@ stl_fix_normal_values(stl_file *stl) {
}
}
-void
-stl_reverse_all_facets(stl_file *stl) {
- int i;
- float normal[3];
-
- if (stl->error) return;
+void stl_reverse_all_facets(stl_file *stl)
+{
+ if (stl->error)
+ return;
- for(i = 0; i < stl->stats.number_of_facets; i++) {
+ 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.x = normal[0];
- stl->facet_start[i].normal.y = normal[1];
- stl->facet_start[i].normal.z = normal[2];
+ stl->facet_start[i].normal = normal;
}
}
-
diff --git a/xs/src/admesh/shared.cpp b/xs/src/admesh/shared.cpp
index 8080f3574..91bb82e00 100644
--- a/xs/src/admesh/shared.cpp
+++ b/xs/src/admesh/shared.cpp
@@ -169,7 +169,7 @@ stl_write_off(stl_file *stl, char *file) {
for(i = 0; i < stl->stats.shared_vertices; i++) {
fprintf(fp, "\t%f %f %f\n",
- stl->v_shared[i].x, stl->v_shared[i].y, stl->v_shared[i].z);
+ 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],
@@ -216,10 +216,10 @@ stl_write_vrml(stl_file *stl, char *file) {
for(i = 0; i < (stl->stats.shared_vertices - 1); i++) {
fprintf(fp, "\t\t\t\t%f %f %f,\n",
- stl->v_shared[i].x, stl->v_shared[i].y, stl->v_shared[i].z);
+ 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].x, stl->v_shared[i].y, stl->v_shared[i].z);
+ 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");
@@ -254,7 +254,7 @@ void stl_write_obj (stl_file *stl, char *file) {
}
for (i = 0; i < stl->stats.shared_vertices; i++) {
- fprintf(fp, "v %f %f %f\n", stl->v_shared[i].x, stl->v_shared[i].y, stl->v_shared[i].z);
+ 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);
diff --git a/xs/src/admesh/stl.h b/xs/src/admesh/stl.h
index dc0f7ae19..096430d15 100644
--- a/xs/src/admesh/stl.h
+++ b/xs/src/admesh/stl.h
@@ -27,9 +27,7 @@
#include <stdint.h>
#include <stddef.h>
-#define STL_MAX(A,B) ((A)>(B)? (A):(B))
-#define STL_MIN(A,B) ((A)<(B)? (A):(B))
-#define ABS(X) ((X) < 0 ? -(X) : (X))
+#include <Eigen/Geometry>
// Size of the binary STL header, free form.
#define LABEL_SIZE 80
@@ -39,31 +37,16 @@
#define HEADER_SIZE 84
#define STL_MIN_FILE_SIZE 284
#define ASCII_LINES_PER_FACET 7
-// Comparing an edge by memcmp, 2x3x4 bytes = 24
-#define SIZEOF_EDGE_SORT 24
-
-typedef struct {
- float x;
- float y;
- float z;
-} stl_vertex;
+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");
-
-typedef struct {
- float x;
- float y;
- float z;
-} stl_normal;
-
static_assert(sizeof(stl_normal) == 12, "size of stl_normal incorrect");
-typedef char stl_extra[2];
-
typedef struct {
stl_normal normal;
stl_vertex vertex[3];
- stl_extra extra;
+ char extra[2];
} stl_facet;
#define SIZEOF_STL_FACET 50
@@ -81,8 +64,12 @@ typedef struct {
} stl_edge;
typedef struct stl_hash_edge {
- // Key of a hash edge: 2x binary copy of a floating point vertex.
- uint32_t key[6];
+ // 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.
@@ -91,8 +78,6 @@ typedef struct stl_hash_edge {
struct stl_hash_edge *next;
} stl_hash_edge;
-static_assert(offsetof(stl_hash_edge, facet_number) == SIZEOF_EDGE_SORT, "size of stl_hash_edge.key incorrect");
-
typedef struct {
// Index of a neighbor facet.
int neighbor[3];
@@ -179,8 +164,8 @@ 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, float versor[3]);
-extern void stl_scale(stl_file *stl, float factor);
+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);
@@ -188,6 +173,7 @@ 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);
@@ -195,8 +181,20 @@ 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);
-extern void stl_calculate_normal(float normal[], stl_facet *facet);
-extern void stl_normalize_vector(float v[]);
+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);
@@ -204,8 +202,8 @@ extern void stl_repair(stl_file *stl, int fixall_flag, int exact_flag, int toler
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, int first);
-extern void stl_facet_stats(stl_file *stl, stl_facet facet, int first);
+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);
diff --git a/xs/src/admesh/stl_io.cpp b/xs/src/admesh/stl_io.cpp
index 1603981fc..81e29d286 100644
--- a/xs/src/admesh/stl_io.cpp
+++ b/xs/src/admesh/stl_io.cpp
@@ -44,9 +44,9 @@ stl_print_edges(stl_file *stl, FILE *file) {
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.x, stl->edge_start[i].p1.y,
- stl->edge_start[i].p1.z, stl->edge_start[i].p2.x,
- stl->edge_start[i].p2.y, stl->edge_start[i].p2.z);
+ 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));
}
}
@@ -75,11 +75,11 @@ File type : ASCII STL file\n");
Header : %s\n", stl->stats.header);
fprintf(file, "============== Size ==============\n");
fprintf(file, "Min X = % f, Max X = % f\n",
- stl->stats.min.x, stl->stats.max.x);
+ stl->stats.min(0), stl->stats.max(0));
fprintf(file, "Min Y = % f, Max Y = % f\n",
- stl->stats.min.y, stl->stats.max.y);
+ stl->stats.min(1), stl->stats.max(1));
fprintf(file, "Min Z = % f, Max Z = % f\n",
- stl->stats.min.z, stl->stats.max.z);
+ stl->stats.min(2), stl->stats.max(2));
fprintf(file, "\
========= Facet Status ========== Original ============ Final ====\n");
@@ -149,18 +149,18 @@ stl_write_ascii(stl_file *stl, const char *file, const char *label) {
for(i = 0; i < stl->stats.number_of_facets; i++) {
fprintf(fp, " facet normal % .8E % .8E % .8E\n",
- stl->facet_start[i].normal.x, stl->facet_start[i].normal.y,
- stl->facet_start[i].normal.z);
+ 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].x, stl->facet_start[i].vertex[0].y,
- stl->facet_start[i].vertex[0].z);
+ 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].x, stl->facet_start[i].vertex[1].y,
- stl->facet_start[i].vertex[1].z);
+ 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].x, stl->facet_start[i].vertex[2].y,
- stl->facet_start[i].vertex[2].z);
+ 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");
}
@@ -264,9 +264,9 @@ 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].x,
- stl->facet_start[facet].vertex[vertex].y,
- stl->facet_start[facet].vertex[vertex].z);
+ stl->facet_start[facet].vertex[vertex](0),
+ stl->facet_start[facet].vertex[vertex](1),
+ stl->facet_start[facet].vertex[vertex](2));
}
void
@@ -309,10 +309,10 @@ stl_write_quad_object(stl_file *stl, char *file) {
int i;
int j;
char *error_msg;
- stl_vertex connect_color;
- stl_vertex uncon_1_color;
- stl_vertex uncon_2_color;
- stl_vertex uncon_3_color;
+ 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;
@@ -330,19 +330,6 @@ stl_write_quad_object(stl_file *stl, char *file) {
return;
}
- connect_color.x = 0.0;
- connect_color.y = 0.0;
- connect_color.z = 1.0;
- uncon_1_color.x = 0.0;
- uncon_1_color.y = 1.0;
- uncon_1_color.z = 0.0;
- uncon_2_color.x = 1.0;
- uncon_2_color.y = 1.0;
- uncon_2_color.z = 1.0;
- uncon_3_color.x = 1.0;
- uncon_3_color.y = 0.0;
- uncon_3_color.z = 0.0;
-
fprintf(fp, "CQUAD\n");
for(i = 0; i < stl->stats.number_of_facets; i++) {
j = ((stl->neighbors_start[i].neighbor[0] == -1) +
@@ -358,21 +345,21 @@ stl_write_quad_object(stl_file *stl, char *file) {
color = uncon_3_color;
}
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
- stl->facet_start[i].vertex[0].x,
- stl->facet_start[i].vertex[0].y,
- stl->facet_start[i].vertex[0].z, color.x, color.y, color.z);
+ 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].x,
- stl->facet_start[i].vertex[1].y,
- stl->facet_start[i].vertex[1].z, color.x, color.y, color.z);
+ 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].x,
- stl->facet_start[i].vertex[2].y,
- stl->facet_start[i].vertex[2].z, color.x, color.y, color.z);
+ 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].x,
- stl->facet_start[i].vertex[2].y,
- stl->facet_start[i].vertex[2].z, color.x, color.y, color.z);
+ 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);
}
@@ -409,17 +396,17 @@ stl_write_dxf(stl_file *stl, char *file, char *label) {
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].x, stl->facet_start[i].vertex[0].y,
- stl->facet_start[i].vertex[0].z);
+ 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].x, stl->facet_start[i].vertex[1].y,
- stl->facet_start[i].vertex[1].z);
+ 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].x, stl->facet_start[i].vertex[2].y,
- stl->facet_start[i].vertex[2].z);
+ 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].x, stl->facet_start[i].vertex[2].y,
- stl->facet_start[i].vertex[2].z);
+ 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");
diff --git a/xs/src/admesh/stlinit.cpp b/xs/src/admesh/stlinit.cpp
index e572ce930..e2939b8af 100644
--- a/xs/src/admesh/stlinit.cpp
+++ b/xs/src/admesh/stlinit.cpp
@@ -40,7 +40,7 @@ stl_open(stl_file *stl, const char *file) {
stl_initialize(stl);
stl_count_facets(stl, file);
stl_allocate(stl);
- stl_read(stl, 0, 1);
+ stl_read(stl, 0, true);
if (!stl->error) fclose(stl->fp);
}
@@ -227,7 +227,7 @@ stl_open_merge(stl_file *stl, char *file_to_merge) {
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, 0);
+ 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: */
@@ -255,8 +255,7 @@ stl_reallocate(stl_file *stl) {
/* 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, int first) {
+void stl_read(stl_file *stl, int first_facet, bool first) {
stl_facet facet;
int i;
@@ -287,18 +286,18 @@ stl_read(stl_file *stl, int first_facet, int first) {
{
// 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");
+ 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].x, &facet.vertex[0].y, &facet.vertex[0].z);
+ 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].x, &facet.vertex[1].y, &facet.vertex[1].z);
+ 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].x, &facet.vertex[2].y, &facet.vertex[2].z);
+ 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);
@@ -311,9 +310,9 @@ stl_read(stl_file *stl, int first_facet, int first) {
}
// 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.x) != 1 ||
- sscanf(normal_buf[1], "%f", &facet.normal.y) != 1 ||
- sscanf(normal_buf[2], "%f", &facet.normal.z) != 1) {
+ 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));
@@ -326,104 +325,45 @@ stl_read(stl_file *stl, int first_facet, int first) {
// 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].x > -1e-12f && facet.vertex[j].x < 1e-12f)
- printf("stl_read: facet %d.x = %e\r\n", j, facet.vertex[j].x);
- if (facet.vertex[j].y > -1e-12f && facet.vertex[j].y < 1e-12f)
- printf("stl_read: facet %d.y = %e\r\n", j, facet.vertex[j].y);
- if (facet.vertex[j].z > -1e-12f && facet.vertex[j].z < 1e-12f)
- printf("stl_read: facet %d.z = %e\r\n", j, facet.vertex[j].z);
+ 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
-#if 1
- {
- // Positive and negative zeros are possible in the floats, which are considered equal by the FP unit.
- // When using a memcmp on raw floats, those numbers report to be different.
- // Unify all +0 and -0 to +0 to make the floats equal under memcmp.
- uint32_t *f = (uint32_t*)&facet;
- for (int j = 0; j < 12; ++ j, ++ f) // 3x vertex + normal: 4x3 = 12 floats
- if (*f == 0x80000000)
- // Negative zero, switch to positive zero.
- *f = 0;
- }
-#else
- {
- // 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. Round them to zero.
- float *f = (float*)&facet;
- for (int j = 0; j < 12; ++ j, ++ f) // 3x vertex + normal: 4x3 = 12 floats
- if (*f > -1e-12f && *f < 1e-12f)
- // Negative zero, switch to positive zero.
- *f = 0;
- }
-#endif
/* Write the facet into memory. */
- memcpy(stl->facet_start+i, &facet, SIZEOF_STL_FACET);
+ stl->facet_start[i] = facet;
stl_facet_stats(stl, facet, first);
- first = 0;
}
- stl->stats.size.x = stl->stats.max.x - stl->stats.min.x;
- stl->stats.size.y = stl->stats.max.y - stl->stats.min.y;
- stl->stats.size.z = stl->stats.max.z - stl->stats.min.z;
- stl->stats.bounding_diameter = sqrt(
- stl->stats.size.x * stl->stats.size.x +
- stl->stats.size.y * stl->stats.size.y +
- stl->stats.size.z * stl->stats.size.z
- );
+ 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, int first) {
- float diff_x;
- float diff_y;
- float diff_z;
- float max_diff;
+void stl_facet_stats(stl_file *stl, stl_facet facet, bool &first)
+{
+ if (stl->error)
+ return;
- 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
- /* while we are going through all of the facets, let's find the */
- /* maximum and minimum values for x, y, and z */
-
- /* Initialize the max and min values the first time through*/
if (first) {
- stl->stats.max.x = facet.vertex[0].x;
- stl->stats.min.x = facet.vertex[0].x;
- stl->stats.max.y = facet.vertex[0].y;
- stl->stats.min.y = facet.vertex[0].y;
- stl->stats.max.z = facet.vertex[0].z;
- stl->stats.min.z = facet.vertex[0].z;
-
- diff_x = ABS(facet.vertex[0].x - facet.vertex[1].x);
- diff_y = ABS(facet.vertex[0].y - facet.vertex[1].y);
- diff_z = ABS(facet.vertex[0].z - facet.vertex[1].z);
- max_diff = STL_MAX(diff_x, diff_y);
- max_diff = STL_MAX(diff_z, max_diff);
- stl->stats.shortest_edge = max_diff;
-
- first = 0;
+ // 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 */
- stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[0].x);
- stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[0].x);
- stl->stats.max.y = STL_MAX(stl->stats.max.y, facet.vertex[0].y);
- stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[0].y);
- stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[0].z);
- stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[0].z);
-
- stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[1].x);
- stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[1].x);
- stl->stats.max.y = STL_MAX(stl->stats.max.y, facet.vertex[1].y);
- stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[1].y);
- stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[1].z);
- stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[1].z);
-
- stl->stats.max.x = STL_MAX(stl->stats.max.x, facet.vertex[2].x);
- stl->stats.min.x = STL_MIN(stl->stats.min.x, facet.vertex[2].x);
- stl->stats.max.y = STL_MAX(stl->stats.max.y, facet.vertex[2].y);
- stl->stats.min.y = STL_MIN(stl->stats.min.y, facet.vertex[2].y);
- stl->stats.max.z = STL_MAX(stl->stats.max.z, facet.vertex[2].z);
- stl->stats.min.z = STL_MIN(stl->stats.min.z, facet.vertex[2].z);
+ // 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
diff --git a/xs/src/admesh/util.cpp b/xs/src/admesh/util.cpp
index f3bf59b56..cc104fdd1 100644
--- a/xs/src/admesh/util.cpp
+++ b/xs/src/admesh/util.cpp
@@ -62,7 +62,7 @@ stl_verify_neighbors(stl_file *stl) {
edge_b.p1 = stl->facet_start[neighbor].vertex[(vnot + 1) % 3];
edge_b.p2 = stl->facet_start[neighbor].vertex[(vnot + 2) % 3];
}
- if(memcmp(&edge_a, &edge_b, SIZEOF_EDGE_SORT) != 0) {
+ 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);
@@ -73,114 +73,67 @@ stl_verify_neighbors(stl_file *stl) {
}
}
-void
-stl_translate(stl_file *stl, float x, float y, float z) {
- int i;
- int j;
-
- if (stl->error) return;
-
- for(i = 0; i < stl->stats.number_of_facets; i++) {
- for(j = 0; j < 3; j++) {
- stl->facet_start[i].vertex[j].x -= (stl->stats.min.x - x);
- stl->facet_start[i].vertex[j].y -= (stl->stats.min.y - y);
- stl->facet_start[i].vertex[j].z -= (stl->stats.min.z - z);
- }
- }
- stl->stats.max.x -= (stl->stats.min.x - x);
- stl->stats.max.y -= (stl->stats.min.y - y);
- stl->stats.max.z -= (stl->stats.min.z - z);
- stl->stats.min.x = x;
- stl->stats.min.y = y;
- stl->stats.min.z = z;
-
+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) {
- int i;
- int j;
-
- if (stl->error) return;
-
- for(i = 0; i < stl->stats.number_of_facets; i++) {
- for(j = 0; j < 3; j++) {
- stl->facet_start[i].vertex[j].x += x;
- stl->facet_start[i].vertex[j].y += y;
- stl->facet_start[i].vertex[j].z += z;
- }
- }
- stl->stats.min.x += x;
- stl->stats.min.y += y;
- stl->stats.min.z += z;
- stl->stats.max.x += x;
- stl->stats.max.y += y;
- stl->stats.max.z += z;
-
+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, float versor[3]) {
- int i;
- int j;
-
- if (stl->error) return;
-
- /* scale extents */
- stl->stats.min.x *= versor[0];
- stl->stats.min.y *= versor[1];
- stl->stats.min.z *= versor[2];
- stl->stats.max.x *= versor[0];
- stl->stats.max.y *= versor[1];
- stl->stats.max.z *= versor[2];
-
- /* scale size */
- stl->stats.size.x *= versor[0];
- stl->stats.size.y *= versor[1];
- stl->stats.size.z *= versor[2];
-
- /* scale volume */
- if (stl->stats.volume > 0.0) {
- stl->stats.volume *= (versor[0] * versor[1] * versor[2]);
- }
-
- for(i = 0; i < stl->stats.number_of_facets; i++) {
- for(j = 0; j < 3; j++) {
- stl->facet_start[i].vertex[j].x *= versor[0];
- stl->facet_start[i].vertex[j].y *= versor[1];
- stl->facet_start[i].vertex[j].z *= versor[2];
- }
- }
-
+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);
}
-void
-stl_scale(stl_file *stl, float factor) {
- float versor[3];
-
- if (stl->error) return;
-
- versor[0] = factor;
- versor[1] = factor;
- versor[2] = factor;
- stl_scale_versor(stl, versor);
-}
-
-static void calculate_normals(stl_file *stl) {
- float normal[3];
-
- if (stl->error) return;
+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.x = normal[0];
- stl->facet_start[i].normal.y = normal[1];
- stl->facet_start[i].normal.z = normal[2];
+ stl->facet_start[i].normal = normal;
}
}
@@ -193,15 +146,56 @@ void stl_transform(stl_file *stl, float *trafo3x4) {
for (i_vertex = 0; i_vertex < 3; ++ i_vertex) {
stl_vertex &v_dst = vertices[i_vertex];
stl_vertex v_src = v_dst;
- v_dst.x = trafo3x4[0] * v_src.x + trafo3x4[1] * v_src.y + trafo3x4[2] * v_src.z + trafo3x4[3];
- v_dst.y = trafo3x4[4] * v_src.x + trafo3x4[5] * v_src.y + trafo3x4[6] * v_src.z + trafo3x4[7];
- v_dst.z = trafo3x4[8] * v_src.x + trafo3x4[9] * v_src.y + trafo3x4[10] * v_src.z + trafo3x4[11];
+ 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;
@@ -214,8 +208,8 @@ stl_rotate_x(stl_file *stl, float angle) {
for(i = 0; i < stl->stats.number_of_facets; i++) {
for(j = 0; j < 3; j++) {
- stl_rotate(&stl->facet_start[i].vertex[j].y,
- &stl->facet_start[i].vertex[j].z, c, s);
+ stl_rotate(&stl->facet_start[i].vertex[j](1),
+ &stl->facet_start[i].vertex[j](2), c, s);
}
}
stl_get_size(stl);
@@ -234,8 +228,8 @@ stl_rotate_y(stl_file *stl, float angle) {
for(i = 0; i < stl->stats.number_of_facets; i++) {
for(j = 0; j < 3; j++) {
- stl_rotate(&stl->facet_start[i].vertex[j].z,
- &stl->facet_start[i].vertex[j].x, c, s);
+ stl_rotate(&stl->facet_start[i].vertex[j](2),
+ &stl->facet_start[i].vertex[j](0), c, s);
}
}
stl_get_size(stl);
@@ -254,8 +248,8 @@ stl_rotate_z(stl_file *stl, float angle) {
for(i = 0; i < stl->stats.number_of_facets; i++) {
for(j = 0; j < 3; j++) {
- stl_rotate(&stl->facet_start[i].vertex[j].x,
- &stl->facet_start[i].vertex[j].y, c, s);
+ stl_rotate(&stl->facet_start[i].vertex[j](0),
+ &stl->facet_start[i].vertex[j](1), c, s);
}
}
stl_get_size(stl);
@@ -272,142 +266,98 @@ stl_rotate(float *x, float *y, const double c, const double s) {
*y = float(s * xold + c * yold);
}
-extern void
-stl_get_size(stl_file *stl) {
- int i;
- int j;
-
- if (stl->error) return;
- if (stl->stats.number_of_facets == 0) return;
-
- stl->stats.min.x = stl->facet_start[0].vertex[0].x;
- stl->stats.min.y = stl->facet_start[0].vertex[0].y;
- stl->stats.min.z = stl->facet_start[0].vertex[0].z;
- stl->stats.max.x = stl->facet_start[0].vertex[0].x;
- stl->stats.max.y = stl->facet_start[0].vertex[0].y;
- stl->stats.max.z = stl->facet_start[0].vertex[0].z;
-
- for(i = 0; i < stl->stats.number_of_facets; i++) {
- for(j = 0; j < 3; j++) {
- stl->stats.min.x = STL_MIN(stl->stats.min.x,
- stl->facet_start[i].vertex[j].x);
- stl->stats.min.y = STL_MIN(stl->stats.min.y,
- stl->facet_start[i].vertex[j].y);
- stl->stats.min.z = STL_MIN(stl->stats.min.z,
- stl->facet_start[i].vertex[j].z);
- stl->stats.max.x = STL_MAX(stl->stats.max.x,
- stl->facet_start[i].vertex[j].x);
- stl->stats.max.y = STL_MAX(stl->stats.max.y,
- stl->facet_start[i].vertex[j].y);
- stl->stats.max.z = STL_MAX(stl->stats.max.z,
- stl->facet_start[i].vertex[j].z);
+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.x = stl->stats.max.x - stl->stats.min.x;
- stl->stats.size.y = stl->stats.max.y - stl->stats.min.y;
- stl->stats.size.z = stl->stats.max.z - stl->stats.min.z;
- stl->stats.bounding_diameter = sqrt(
- stl->stats.size.x * stl->stats.size.x +
- stl->stats.size.y * stl->stats.size.y +
- stl->stats.size.z * stl->stats.size.z
- );
+ stl->stats.size = stl->stats.max - stl->stats.min;
+ stl->stats.bounding_diameter = stl->stats.size.norm();
}
-void
-stl_mirror_xy(stl_file *stl) {
- int i;
- int j;
- float temp_size;
-
- if (stl->error) return;
+void stl_mirror_xy(stl_file *stl)
+{
+ if (stl->error)
+ return;
- for(i = 0; i < stl->stats.number_of_facets; i++) {
- for(j = 0; j < 3; j++) {
- stl->facet_start[i].vertex[j].z *= -1.0;
+ 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;
}
}
- temp_size = stl->stats.min.z;
- stl->stats.min.z = stl->stats.max.z;
- stl->stats.max.z = temp_size;
- stl->stats.min.z *= -1.0;
- stl->stats.max.z *= -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) {
- int i;
- int j;
- float temp_size;
-
+void stl_mirror_yz(stl_file *stl)
+{
if (stl->error) return;
- for(i = 0; i < stl->stats.number_of_facets; i++) {
- for(j = 0; j < 3; j++) {
- stl->facet_start[i].vertex[j].x *= -1.0;
+ 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;
}
}
- temp_size = stl->stats.min.x;
- stl->stats.min.x = stl->stats.max.x;
- stl->stats.max.x = temp_size;
- stl->stats.min.x *= -1.0;
- stl->stats.max.x *= -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) {
- int i;
- int j;
- float temp_size;
-
- if (stl->error) return;
+void stl_mirror_xz(stl_file *stl)
+{
+ if (stl->error)
+ return;
- for(i = 0; i < stl->stats.number_of_facets; i++) {
- for(j = 0; j < 3; j++) {
- stl->facet_start[i].vertex[j].y *= -1.0;
+ 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;
}
}
- temp_size = stl->stats.min.y;
- stl->stats.min.y = stl->stats.max.y;
- stl->stats.max.y = temp_size;
- stl->stats.min.y *= -1.0;
- stl->stats.max.y *= -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) {
- stl_vertex p0;
- stl_vertex p;
- stl_normal n;
- float height;
- float area;
- float volume = 0.0;
-
- if (stl->error) return 0;
-
- /* Choose a point, any point as the reference */
- p0.x = stl->facet_start[0].vertex[0].x;
- p0.y = stl->facet_start[0].vertex[0].y;
- p0.z = stl->facet_start[0].vertex[0].z;
-
- for(uint32_t i = 0; i < stl->stats.number_of_facets; i++) {
- p.x = stl->facet_start[i].vertex[0].x - p0.x;
- p.y = stl->facet_start[i].vertex[0].y - p0.y;
- p.z = stl->facet_start[i].vertex[0].z - p0.z;
- /* Do dot product to get distance from point to plane */
- n = stl->facet_start[i].normal;
- height = (n.x * p.x) + (n.y * p.y) + (n.z * p.z);
- area = get_area(&stl->facet_start[i]);
+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) {
+void stl_calculate_volume(stl_file *stl)
+{
if (stl->error) return;
stl->stats.volume = get_volume(stl);
if(stl->stats.volume < 0.0) {
@@ -416,35 +366,32 @@ void stl_calculate_volume(stl_file *stl) {
}
}
-static float get_area(stl_facet *facet) {
- double cross[3][3];
- float sum[3];
- float n[3];
- float area;
- int i;
-
+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) */
- for(i = 0; i < 3; i++) {
- cross[i][0]=(((double)facet->vertex[i].y * (double)facet->vertex[(i + 1) % 3].z) -
- ((double)facet->vertex[i].z * (double)facet->vertex[(i + 1) % 3].y));
- cross[i][1]=(((double)facet->vertex[i].z * (double)facet->vertex[(i + 1) % 3].x) -
- ((double)facet->vertex[i].x * (double)facet->vertex[(i + 1) % 3].z));
- cross[i][2]=(((double)facet->vertex[i].x * (double)facet->vertex[(i + 1) % 3].y) -
- ((double)facet->vertex[i].y * (double)facet->vertex[(i + 1) % 3].x));
+ 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)));
}
- 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];
+ 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 */
+ // 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);
-
- area = 0.5 * (n[0] * sum[0] + n[1] * sum[1] + n[2] * sum[2]);
- return area;
+ return 0.5f * n.dot(sum);
}
void stl_repair(stl_file *stl,
diff --git a/xs/src/agg/AUTHORS b/xs/src/agg/AUTHORS
new file mode 100644
index 000000000..2bb6518ec
--- /dev/null
+++ b/xs/src/agg/AUTHORS
@@ -0,0 +1,2 @@
+Anti-Grain Geometry - Version 2.4
+Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
diff --git a/xs/src/agg/VERSION b/xs/src/agg/VERSION
new file mode 100644
index 000000000..c5de3e3b0
--- /dev/null
+++ b/xs/src/agg/VERSION
@@ -0,0 +1,2 @@
+2.4
+svn revision 128 \ No newline at end of file
diff --git a/xs/src/agg/agg_array.h b/xs/src/agg/agg_array.h
new file mode 100644
index 000000000..8d5668384
--- /dev/null
+++ b/xs/src/agg/agg_array.h
@@ -0,0 +1,1119 @@
+//----------------------------------------------------------------------------
+// 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_ARRAY_INCLUDED
+#define AGG_ARRAY_INCLUDED
+
+#include <stddef.h>
+#include <string.h>
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //-------------------------------------------------------pod_array_adaptor
+ template<class T> class pod_array_adaptor
+ {
+ public:
+ typedef T value_type;
+ pod_array_adaptor(T* array, unsigned size) :
+ m_array(array), m_size(size) {}
+
+ unsigned size() const { return m_size; }
+ const T& operator [] (unsigned i) const { return m_array[i]; }
+ T& operator [] (unsigned i) { return m_array[i]; }
+ const T& at(unsigned i) const { return m_array[i]; }
+ T& at(unsigned i) { return m_array[i]; }
+ T value_at(unsigned i) const { return m_array[i]; }
+
+ private:
+ T* m_array;
+ unsigned m_size;
+ };
+
+
+ //---------------------------------------------------------pod_auto_array
+ template<class T, unsigned Size> class pod_auto_array
+ {
+ public:
+ typedef T value_type;
+ typedef pod_auto_array<T, Size> self_type;
+
+ pod_auto_array() {}
+ explicit pod_auto_array(const T* c)
+ {
+ memcpy(m_array, c, sizeof(T) * Size);
+ }
+
+ const self_type& operator = (const T* c)
+ {
+ memcpy(m_array, c, sizeof(T) * Size);
+ return *this;
+ }
+
+ static unsigned size() { return Size; }
+ const T& operator [] (unsigned i) const { return m_array[i]; }
+ T& operator [] (unsigned i) { return m_array[i]; }
+ const T& at(unsigned i) const { return m_array[i]; }
+ T& at(unsigned i) { return m_array[i]; }
+ T value_at(unsigned i) const { return m_array[i]; }
+
+ private:
+ T m_array[Size];
+ };
+
+
+ //--------------------------------------------------------pod_auto_vector
+ template<class T, unsigned Size> class pod_auto_vector
+ {
+ public:
+ typedef T value_type;
+ typedef pod_auto_vector<T, Size> self_type;
+
+ pod_auto_vector() : m_size(0) {}
+
+ void remove_all() { m_size = 0; }
+ void clear() { m_size = 0; }
+ void add(const T& v) { m_array[m_size++] = v; }
+ void push_back(const T& v) { m_array[m_size++] = v; }
+ void inc_size(unsigned size) { m_size += size; }
+
+ unsigned size() const { return m_size; }
+ const T& operator [] (unsigned i) const { return m_array[i]; }
+ T& operator [] (unsigned i) { return m_array[i]; }
+ const T& at(unsigned i) const { return m_array[i]; }
+ T& at(unsigned i) { return m_array[i]; }
+ T value_at(unsigned i) const { return m_array[i]; }
+
+ private:
+ T m_array[Size];
+ unsigned m_size;
+ };
+
+
+ //---------------------------------------------------------------pod_array
+ template<class T> class pod_array
+ {
+ public:
+ typedef T value_type;
+ typedef pod_array<T> self_type;
+
+ ~pod_array() { pod_allocator<T>::deallocate(m_array, m_size); }
+ pod_array() : m_array(0), m_size(0) {}
+
+ pod_array(unsigned size) :
+ m_array(pod_allocator<T>::allocate(size)),
+ m_size(size)
+ {}
+
+ pod_array(const self_type& v) :
+ m_array(pod_allocator<T>::allocate(v.m_size)),
+ m_size(v.m_size)
+ {
+ memcpy(m_array, v.m_array, sizeof(T) * m_size);
+ }
+
+ void resize(unsigned size)
+ {
+ if(size != m_size)
+ {
+ pod_allocator<T>::deallocate(m_array, m_size);
+ m_array = pod_allocator<T>::allocate(m_size = size);
+ }
+ }
+ const self_type& operator = (const self_type& v)
+ {
+ resize(v.size());
+ memcpy(m_array, v.m_array, sizeof(T) * m_size);
+ return *this;
+ }
+
+ unsigned size() const { return m_size; }
+ const T& operator [] (unsigned i) const { return m_array[i]; }
+ T& operator [] (unsigned i) { return m_array[i]; }
+ const T& at(unsigned i) const { return m_array[i]; }
+ T& at(unsigned i) { return m_array[i]; }
+ T value_at(unsigned i) const { return m_array[i]; }
+
+ const T* data() const { return m_array; }
+ T* data() { return m_array; }
+ private:
+ T* m_array;
+ unsigned m_size;
+ };
+
+
+
+ //--------------------------------------------------------------pod_vector
+ // A simple class template to store Plain Old Data, a vector
+ // of a fixed size. The data is continous in memory
+ //------------------------------------------------------------------------
+ template<class T> class pod_vector
+ {
+ public:
+ typedef T value_type;
+
+ ~pod_vector() { pod_allocator<T>::deallocate(m_array, m_capacity); }
+ pod_vector() : m_size(0), m_capacity(0), m_array(0) {}
+ pod_vector(unsigned cap, unsigned extra_tail=0);
+
+ // Copying
+ pod_vector(const pod_vector<T>&);
+ const pod_vector<T>& operator = (const pod_vector<T>&);
+
+ // Set new capacity. All data is lost, size is set to zero.
+ void capacity(unsigned cap, unsigned extra_tail=0);
+ unsigned capacity() const { return m_capacity; }
+
+ // Allocate n elements. All data is lost,
+ // but elements can be accessed in range 0...size-1.
+ void allocate(unsigned size, unsigned extra_tail=0);
+
+ // Resize keeping the content.
+ void resize(unsigned new_size);
+
+ void zero()
+ {
+ memset(m_array, 0, sizeof(T) * m_size);
+ }
+
+ void add(const T& v) { m_array[m_size++] = v; }
+ void push_back(const T& v) { m_array[m_size++] = v; }
+ void insert_at(unsigned pos, const T& val);
+ void inc_size(unsigned size) { m_size += size; }
+ unsigned size() const { return m_size; }
+ unsigned byte_size() const { return m_size * sizeof(T); }
+ void serialize(int8u* ptr) const;
+ void deserialize(const int8u* data, unsigned byte_size);
+ const T& operator [] (unsigned i) const { return m_array[i]; }
+ T& operator [] (unsigned i) { return m_array[i]; }
+ const T& at(unsigned i) const { return m_array[i]; }
+ T& at(unsigned i) { return m_array[i]; }
+ T value_at(unsigned i) const { return m_array[i]; }
+
+ const T* data() const { return m_array; }
+ T* data() { return m_array; }
+
+ void remove_all() { m_size = 0; }
+ void clear() { m_size = 0; }
+ void cut_at(unsigned num) { if(num < m_size) m_size = num; }
+
+ private:
+ unsigned m_size;
+ unsigned m_capacity;
+ T* m_array;
+ };
+
+ //------------------------------------------------------------------------
+ template<class T>
+ void pod_vector<T>::capacity(unsigned cap, unsigned extra_tail)
+ {
+ m_size = 0;
+ if(cap > m_capacity)
+ {
+ pod_allocator<T>::deallocate(m_array, m_capacity);
+ m_capacity = cap + extra_tail;
+ m_array = m_capacity ? pod_allocator<T>::allocate(m_capacity) : 0;
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class T>
+ void pod_vector<T>::allocate(unsigned size, unsigned extra_tail)
+ {
+ capacity(size, extra_tail);
+ m_size = size;
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T>
+ void pod_vector<T>::resize(unsigned new_size)
+ {
+ if(new_size > m_size)
+ {
+ if(new_size > m_capacity)
+ {
+ T* data = pod_allocator<T>::allocate(new_size);
+ memcpy(data, m_array, m_size * sizeof(T));
+ pod_allocator<T>::deallocate(m_array, m_capacity);
+ m_array = data;
+ }
+ }
+ else
+ {
+ m_size = new_size;
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class T> pod_vector<T>::pod_vector(unsigned cap, unsigned extra_tail) :
+ m_size(0),
+ m_capacity(cap + extra_tail),
+ m_array(pod_allocator<T>::allocate(m_capacity)) {}
+
+ //------------------------------------------------------------------------
+ template<class T> pod_vector<T>::pod_vector(const pod_vector<T>& v) :
+ m_size(v.m_size),
+ m_capacity(v.m_capacity),
+ m_array(v.m_capacity ? pod_allocator<T>::allocate(v.m_capacity) : 0)
+ {
+ memcpy(m_array, v.m_array, sizeof(T) * v.m_size);
+ }
+
+ //------------------------------------------------------------------------
+ template<class T> const pod_vector<T>&
+ pod_vector<T>::operator = (const pod_vector<T>&v)
+ {
+ allocate(v.m_size);
+ if(v.m_size) memcpy(m_array, v.m_array, sizeof(T) * v.m_size);
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T> void pod_vector<T>::serialize(int8u* ptr) const
+ {
+ if(m_size) memcpy(ptr, m_array, m_size * sizeof(T));
+ }
+
+ //------------------------------------------------------------------------
+ template<class T>
+ void pod_vector<T>::deserialize(const int8u* data, unsigned byte_size)
+ {
+ byte_size /= sizeof(T);
+ allocate(byte_size);
+ if(byte_size) memcpy(m_array, data, byte_size * sizeof(T));
+ }
+
+ //------------------------------------------------------------------------
+ template<class T>
+ void pod_vector<T>::insert_at(unsigned pos, const T& val)
+ {
+ if(pos >= m_size)
+ {
+ m_array[m_size] = val;
+ }
+ else
+ {
+ memmove(m_array + pos + 1, m_array + pos, (m_size - pos) * sizeof(T));
+ m_array[pos] = val;
+ }
+ ++m_size;
+ }
+
+ //---------------------------------------------------------------pod_bvector
+ // A simple class template to store Plain Old Data, similar to std::deque
+ // It doesn't reallocate memory but instead, uses blocks of data of size
+ // of (1 << S), that is, power of two. The data is NOT contiguous in memory,
+ // so the only valid access method is operator [] or curr(), prev(), next()
+ //
+ // There reallocs occure only when the pool of pointers to blocks needs
+ // to be extended (it happens very rarely). You can control the value
+ // of increment to reallocate the pointer buffer. See the second constructor.
+ // By default, the incremeent value equals (1 << S), i.e., the block size.
+ //------------------------------------------------------------------------
+ template<class T, unsigned S=6> class pod_bvector
+ {
+ public:
+ enum block_scale_e
+ {
+ block_shift = S,
+ block_size = 1 << block_shift,
+ block_mask = block_size - 1
+ };
+
+ typedef T value_type;
+
+ ~pod_bvector();
+ pod_bvector();
+ pod_bvector(unsigned block_ptr_inc);
+
+ // Copying
+ pod_bvector(const pod_bvector<T, S>& v);
+ const pod_bvector<T, S>& operator = (const pod_bvector<T, S>& v);
+
+ void remove_all() { m_size = 0; }
+ void clear() { m_size = 0; }
+ void free_all() { free_tail(0); }
+ void free_tail(unsigned size);
+ void add(const T& val);
+ void push_back(const T& val) { add(val); }
+ void modify_last(const T& val);
+ void remove_last();
+
+ int allocate_continuous_block(unsigned num_elements);
+
+ void add_array(const T* ptr, unsigned num_elem)
+ {
+ while(num_elem--)
+ {
+ add(*ptr++);
+ }
+ }
+
+ template<class DataAccessor> void add_data(DataAccessor& data)
+ {
+ while(data.size())
+ {
+ add(*data);
+ ++data;
+ }
+ }
+
+ void cut_at(unsigned size)
+ {
+ if(size < m_size) m_size = size;
+ }
+
+ unsigned size() const { return m_size; }
+
+ const T& operator [] (unsigned i) const
+ {
+ return m_blocks[i >> block_shift][i & block_mask];
+ }
+
+ T& operator [] (unsigned i)
+ {
+ return m_blocks[i >> block_shift][i & block_mask];
+ }
+
+ const T& at(unsigned i) const
+ {
+ return m_blocks[i >> block_shift][i & block_mask];
+ }
+
+ T& at(unsigned i)
+ {
+ return m_blocks[i >> block_shift][i & block_mask];
+ }
+
+ T value_at(unsigned i) const
+ {
+ return m_blocks[i >> block_shift][i & block_mask];
+ }
+
+ const T& curr(unsigned idx) const
+ {
+ return (*this)[idx];
+ }
+
+ T& curr(unsigned idx)
+ {
+ return (*this)[idx];
+ }
+
+ const T& prev(unsigned idx) const
+ {
+ return (*this)[(idx + m_size - 1) % m_size];
+ }
+
+ T& prev(unsigned idx)
+ {
+ return (*this)[(idx + m_size - 1) % m_size];
+ }
+
+ const T& next(unsigned idx) const
+ {
+ return (*this)[(idx + 1) % m_size];
+ }
+
+ T& next(unsigned idx)
+ {
+ return (*this)[(idx + 1) % m_size];
+ }
+
+ const T& last() const
+ {
+ return (*this)[m_size - 1];
+ }
+
+ T& last()
+ {
+ return (*this)[m_size - 1];
+ }
+
+ unsigned byte_size() const;
+ void serialize(int8u* ptr) const;
+ void deserialize(const int8u* data, unsigned byte_size);
+ void deserialize(unsigned start, const T& empty_val,
+ const int8u* data, unsigned byte_size);
+
+ template<class ByteAccessor>
+ void deserialize(ByteAccessor data)
+ {
+ remove_all();
+ unsigned elem_size = data.size() / sizeof(T);
+
+ for(unsigned i = 0; i < elem_size; ++i)
+ {
+ int8u* ptr = (int8u*)data_ptr();
+ for(unsigned j = 0; j < sizeof(T); ++j)
+ {
+ *ptr++ = *data;
+ ++data;
+ }
+ ++m_size;
+ }
+ }
+
+ template<class ByteAccessor>
+ void deserialize(unsigned start, const T& empty_val, ByteAccessor data)
+ {
+ while(m_size < start)
+ {
+ add(empty_val);
+ }
+
+ unsigned elem_size = data.size() / sizeof(T);
+ for(unsigned i = 0; i < elem_size; ++i)
+ {
+ int8u* ptr;
+ if(start + i < m_size)
+ {
+ ptr = (int8u*)(&((*this)[start + i]));
+ }
+ else
+ {
+ ptr = (int8u*)data_ptr();
+ ++m_size;
+ }
+ for(unsigned j = 0; j < sizeof(T); ++j)
+ {
+ *ptr++ = *data;
+ ++data;
+ }
+ }
+ }
+
+ const T* block(unsigned nb) const { return m_blocks[nb]; }
+
+ private:
+ void allocate_block(unsigned nb);
+ T* data_ptr();
+
+ unsigned m_size;
+ unsigned m_num_blocks;
+ unsigned m_max_blocks;
+ T** m_blocks;
+ unsigned m_block_ptr_inc;
+ };
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S> pod_bvector<T, S>::~pod_bvector()
+ {
+ if(m_num_blocks)
+ {
+ T** blk = m_blocks + m_num_blocks - 1;
+ while(m_num_blocks--)
+ {
+ pod_allocator<T>::deallocate(*blk, block_size);
+ --blk;
+ }
+ }
+ pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ void pod_bvector<T, S>::free_tail(unsigned size)
+ {
+ if(size < m_size)
+ {
+ unsigned nb = (size + block_mask) >> block_shift;
+ while(m_num_blocks > nb)
+ {
+ pod_allocator<T>::deallocate(m_blocks[--m_num_blocks], block_size);
+ }
+ if(m_num_blocks == 0)
+ {
+ pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
+ m_blocks = 0;
+ m_max_blocks = 0;
+ }
+ m_size = size;
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S> pod_bvector<T, S>::pod_bvector() :
+ m_size(0),
+ m_num_blocks(0),
+ m_max_blocks(0),
+ m_blocks(0),
+ m_block_ptr_inc(block_size)
+ {
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ pod_bvector<T, S>::pod_bvector(unsigned block_ptr_inc) :
+ m_size(0),
+ m_num_blocks(0),
+ m_max_blocks(0),
+ m_blocks(0),
+ m_block_ptr_inc(block_ptr_inc)
+ {
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ pod_bvector<T, S>::pod_bvector(const pod_bvector<T, S>& v) :
+ m_size(v.m_size),
+ m_num_blocks(v.m_num_blocks),
+ m_max_blocks(v.m_max_blocks),
+ m_blocks(v.m_max_blocks ?
+ pod_allocator<T*>::allocate(v.m_max_blocks) :
+ 0),
+ m_block_ptr_inc(v.m_block_ptr_inc)
+ {
+ unsigned i;
+ for(i = 0; i < v.m_num_blocks; ++i)
+ {
+ m_blocks[i] = pod_allocator<T>::allocate(block_size);
+ memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T));
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ const pod_bvector<T, S>&
+ pod_bvector<T, S>::operator = (const pod_bvector<T, S>& v)
+ {
+ unsigned i;
+ for(i = m_num_blocks; i < v.m_num_blocks; ++i)
+ {
+ allocate_block(i);
+ }
+ for(i = 0; i < v.m_num_blocks; ++i)
+ {
+ memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T));
+ }
+ m_size = v.m_size;
+ return *this;
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ void pod_bvector<T, S>::allocate_block(unsigned nb)
+ {
+ if(nb >= m_max_blocks)
+ {
+ T** new_blocks = pod_allocator<T*>::allocate(m_max_blocks + m_block_ptr_inc);
+
+ if(m_blocks)
+ {
+ memcpy(new_blocks,
+ m_blocks,
+ m_num_blocks * sizeof(T*));
+
+ pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
+ }
+ m_blocks = new_blocks;
+ m_max_blocks += m_block_ptr_inc;
+ }
+ m_blocks[nb] = pod_allocator<T>::allocate(block_size);
+ m_num_blocks++;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ inline T* pod_bvector<T, S>::data_ptr()
+ {
+ unsigned nb = m_size >> block_shift;
+ if(nb >= m_num_blocks)
+ {
+ allocate_block(nb);
+ }
+ return m_blocks[nb] + (m_size & block_mask);
+ }
+
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ inline void pod_bvector<T, S>::add(const T& val)
+ {
+ *data_ptr() = val;
+ ++m_size;
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ inline void pod_bvector<T, S>::remove_last()
+ {
+ if(m_size) --m_size;
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ void pod_bvector<T, S>::modify_last(const T& val)
+ {
+ remove_last();
+ add(val);
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ int pod_bvector<T, S>::allocate_continuous_block(unsigned num_elements)
+ {
+ if(num_elements < block_size)
+ {
+ data_ptr(); // Allocate initial block if necessary
+ unsigned rest = block_size - (m_size & block_mask);
+ unsigned index;
+ if(num_elements <= rest)
+ {
+ // The rest of the block is good, we can use it
+ //-----------------
+ index = m_size;
+ m_size += num_elements;
+ return index;
+ }
+
+ // New block
+ //---------------
+ m_size += rest;
+ data_ptr();
+ index = m_size;
+ m_size += num_elements;
+ return index;
+ }
+ return -1; // Impossible to allocate
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ unsigned pod_bvector<T, S>::byte_size() const
+ {
+ return m_size * sizeof(T);
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ void pod_bvector<T, S>::serialize(int8u* ptr) const
+ {
+ unsigned i;
+ for(i = 0; i < m_size; i++)
+ {
+ memcpy(ptr, &(*this)[i], sizeof(T));
+ ptr += sizeof(T);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ void pod_bvector<T, S>::deserialize(const int8u* data, unsigned byte_size)
+ {
+ remove_all();
+ byte_size /= sizeof(T);
+ for(unsigned i = 0; i < byte_size; ++i)
+ {
+ T* ptr = data_ptr();
+ memcpy(ptr, data, sizeof(T));
+ ++m_size;
+ data += sizeof(T);
+ }
+ }
+
+
+ // Replace or add a number of elements starting from "start" position
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ void pod_bvector<T, S>::deserialize(unsigned start, const T& empty_val,
+ const int8u* data, unsigned byte_size)
+ {
+ while(m_size < start)
+ {
+ add(empty_val);
+ }
+
+ byte_size /= sizeof(T);
+ for(unsigned i = 0; i < byte_size; ++i)
+ {
+ if(start + i < m_size)
+ {
+ memcpy(&((*this)[start + i]), data, sizeof(T));
+ }
+ else
+ {
+ T* ptr = data_ptr();
+ memcpy(ptr, data, sizeof(T));
+ ++m_size;
+ }
+ data += sizeof(T);
+ }
+ }
+
+
+ //---------------------------------------------------------block_allocator
+ // Allocator for arbitrary POD data. Most usable in different cache
+ // systems for efficient memory allocations.
+ // Memory is allocated with blocks of fixed size ("block_size" in
+ // the constructor). If required size exceeds the block size the allocator
+ // creates a new block of the required size. However, the most efficient
+ // use is when the average reqired size is much less than the block size.
+ //------------------------------------------------------------------------
+ class block_allocator
+ {
+ struct block_type
+ {
+ int8u* data;
+ unsigned size;
+ };
+
+ public:
+ void remove_all()
+ {
+ if(m_num_blocks)
+ {
+ block_type* blk = m_blocks + m_num_blocks - 1;
+ while(m_num_blocks--)
+ {
+ pod_allocator<int8u>::deallocate(blk->data, blk->size);
+ --blk;
+ }
+ pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks);
+ }
+ m_num_blocks = 0;
+ m_max_blocks = 0;
+ m_blocks = 0;
+ m_buf_ptr = 0;
+ m_rest = 0;
+ }
+
+ ~block_allocator()
+ {
+ remove_all();
+ }
+
+ block_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) :
+ m_block_size(block_size),
+ m_block_ptr_inc(block_ptr_inc),
+ m_num_blocks(0),
+ m_max_blocks(0),
+ m_blocks(0),
+ m_buf_ptr(0),
+ m_rest(0)
+ {
+ }
+
+
+ int8u* allocate(unsigned size, unsigned alignment=1)
+ {
+ if(size == 0) return 0;
+ if(size <= m_rest)
+ {
+ int8u* ptr = m_buf_ptr;
+ if(alignment > 1)
+ {
+ unsigned align =
+ (alignment - unsigned((size_t)ptr) % alignment) % alignment;
+
+ size += align;
+ ptr += align;
+ if(size <= m_rest)
+ {
+ m_rest -= size;
+ m_buf_ptr += size;
+ return ptr;
+ }
+ allocate_block(size);
+ return allocate(size - align, alignment);
+ }
+ m_rest -= size;
+ m_buf_ptr += size;
+ return ptr;
+ }
+ allocate_block(size + alignment - 1);
+ return allocate(size, alignment);
+ }
+
+
+ private:
+ void allocate_block(unsigned size)
+ {
+ if(size < m_block_size) size = m_block_size;
+ if(m_num_blocks >= m_max_blocks)
+ {
+ block_type* new_blocks =
+ pod_allocator<block_type>::allocate(m_max_blocks + m_block_ptr_inc);
+
+ if(m_blocks)
+ {
+ memcpy(new_blocks,
+ m_blocks,
+ m_num_blocks * sizeof(block_type));
+ pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks);
+ }
+ m_blocks = new_blocks;
+ m_max_blocks += m_block_ptr_inc;
+ }
+
+ m_blocks[m_num_blocks].size = size;
+ m_blocks[m_num_blocks].data =
+ m_buf_ptr =
+ pod_allocator<int8u>::allocate(size);
+
+ m_num_blocks++;
+ m_rest = size;
+ }
+
+ unsigned m_block_size;
+ unsigned m_block_ptr_inc;
+ unsigned m_num_blocks;
+ unsigned m_max_blocks;
+ block_type* m_blocks;
+ int8u* m_buf_ptr;
+ unsigned m_rest;
+ };
+
+
+
+
+
+
+
+
+ //------------------------------------------------------------------------
+ enum quick_sort_threshold_e
+ {
+ quick_sort_threshold = 9
+ };
+
+
+ //-----------------------------------------------------------swap_elements
+ template<class T> inline void swap_elements(T& a, T& b)
+ {
+ T temp = a;
+ a = b;
+ b = temp;
+ }
+
+
+ //--------------------------------------------------------------quick_sort
+ template<class Array, class Less>
+ void quick_sort(Array& arr, Less less)
+ {
+ if(arr.size() < 2) return;
+
+ typename Array::value_type* e1;
+ typename Array::value_type* e2;
+
+ int stack[80];
+ int* top = stack;
+ int limit = arr.size();
+ int base = 0;
+
+ for(;;)
+ {
+ int len = limit - base;
+
+ int i;
+ int j;
+ int pivot;
+
+ if(len > quick_sort_threshold)
+ {
+ // we use base + len/2 as the pivot
+ pivot = base + len / 2;
+ swap_elements(arr[base], arr[pivot]);
+
+ i = base + 1;
+ j = limit - 1;
+
+ // now ensure that *i <= *base <= *j
+ e1 = &(arr[j]);
+ e2 = &(arr[i]);
+ if(less(*e1, *e2)) swap_elements(*e1, *e2);
+
+ e1 = &(arr[base]);
+ e2 = &(arr[i]);
+ if(less(*e1, *e2)) swap_elements(*e1, *e2);
+
+ e1 = &(arr[j]);
+ e2 = &(arr[base]);
+ if(less(*e1, *e2)) swap_elements(*e1, *e2);
+
+ for(;;)
+ {
+ do i++; while( less(arr[i], arr[base]) );
+ do j--; while( less(arr[base], arr[j]) );
+
+ if( i > j )
+ {
+ break;
+ }
+
+ swap_elements(arr[i], arr[j]);
+ }
+
+ swap_elements(arr[base], arr[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(; less(*(e1 = &(arr[j + 1])), *(e2 = &(arr[j]))); j--)
+ {
+ swap_elements(*e1, *e2);
+ if(j == base)
+ {
+ break;
+ }
+ }
+ }
+ if(top > stack)
+ {
+ top -= 2;
+ base = top[0];
+ limit = top[1];
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+
+
+
+
+ //------------------------------------------------------remove_duplicates
+ // Remove duplicates from a sorted array. It doesn't cut the
+ // tail of the array, it just returns the number of remaining elements.
+ //-----------------------------------------------------------------------
+ template<class Array, class Equal>
+ unsigned remove_duplicates(Array& arr, Equal equal)
+ {
+ if(arr.size() < 2) return arr.size();
+
+ unsigned i, j;
+ for(i = 1, j = 1; i < arr.size(); i++)
+ {
+ typename Array::value_type& e = arr[i];
+ if(!equal(e, arr[i - 1]))
+ {
+ arr[j++] = e;
+ }
+ }
+ return j;
+ }
+
+ //--------------------------------------------------------invert_container
+ template<class Array> void invert_container(Array& arr)
+ {
+ int i = 0;
+ int j = arr.size() - 1;
+ while(i < j)
+ {
+ swap_elements(arr[i++], arr[j--]);
+ }
+ }
+
+ //------------------------------------------------------binary_search_pos
+ template<class Array, class Value, class Less>
+ unsigned binary_search_pos(const Array& arr, const Value& val, Less less)
+ {
+ if(arr.size() == 0) return 0;
+
+ unsigned beg = 0;
+ unsigned end = arr.size() - 1;
+
+ if(less(val, arr[0])) return 0;
+ if(less(arr[end], val)) return end + 1;
+
+ while(end - beg > 1)
+ {
+ unsigned mid = (end + beg) >> 1;
+ if(less(val, arr[mid])) end = mid;
+ else beg = mid;
+ }
+
+ //if(beg <= 0 && less(val, arr[0])) return 0;
+ //if(end >= arr.size() - 1 && less(arr[end], val)) ++end;
+
+ return end;
+ }
+
+ //----------------------------------------------------------range_adaptor
+ template<class Array> class range_adaptor
+ {
+ public:
+ typedef typename Array::value_type value_type;
+
+ range_adaptor(Array& array, unsigned start, unsigned size) :
+ m_array(array), m_start(start), m_size(size)
+ {}
+
+ unsigned size() const { return m_size; }
+ const value_type& operator [] (unsigned i) const { return m_array[m_start + i]; }
+ value_type& operator [] (unsigned i) { return m_array[m_start + i]; }
+ const value_type& at(unsigned i) const { return m_array[m_start + i]; }
+ value_type& at(unsigned i) { return m_array[m_start + i]; }
+ value_type value_at(unsigned i) const { return m_array[m_start + i]; }
+
+ private:
+ Array& m_array;
+ unsigned m_start;
+ unsigned m_size;
+ };
+
+ //---------------------------------------------------------------int_less
+ inline bool int_less(int a, int b) { return a < b; }
+
+ //------------------------------------------------------------int_greater
+ inline bool int_greater(int a, int b) { return a > b; }
+
+ //----------------------------------------------------------unsigned_less
+ inline bool unsigned_less(unsigned a, unsigned b) { return a < b; }
+
+ //-------------------------------------------------------unsigned_greater
+ inline bool unsigned_greater(unsigned a, unsigned b) { return a > b; }
+}
+
+#endif
diff --git a/xs/src/agg/agg_basics.h b/xs/src/agg/agg_basics.h
new file mode 100644
index 000000000..273850ba1
--- /dev/null
+++ b/xs/src/agg/agg_basics.h
@@ -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
+
diff --git a/xs/src/agg/agg_bezier_arc.h b/xs/src/agg/agg_bezier_arc.h
new file mode 100644
index 000000000..cfd9308ea
--- /dev/null
+++ b/xs/src/agg/agg_bezier_arc.h
@@ -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
diff --git a/xs/src/agg/agg_clip_liang_barsky.h b/xs/src/agg/agg_clip_liang_barsky.h
new file mode 100644
index 000000000..4b5fedbab
--- /dev/null
+++ b/xs/src/agg/agg_clip_liang_barsky.h
@@ -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
diff --git a/xs/src/agg/agg_color_gray.h b/xs/src/agg/agg_color_gray.h
new file mode 100644
index 000000000..f66588c11
--- /dev/null
+++ b/xs/src/agg/agg_color_gray.h
@@ -0,0 +1,1047 @@
+//----------------------------------------------------------------------------
+// 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.
+//
+//----------------------------------------------------------------------------
+//
+// color types gray8, gray16
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_COLOR_GRAY_INCLUDED
+#define AGG_COLOR_GRAY_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_color_rgba.h"
+
+namespace agg
+{
+
+ //===================================================================gray8
+ template<class Colorspace>
+ struct gray8T
+ {
+ typedef int8u value_type;
+ typedef int32u calc_type;
+ typedef int32 long_type;
+ enum base_scale_e
+ {
+ base_shift = 8,
+ base_scale = 1 << base_shift,
+ base_mask = base_scale - 1,
+ base_MSB = 1 << (base_shift - 1)
+ };
+ typedef gray8T self_type;
+
+ value_type v;
+ value_type a;
+
+ static value_type luminance(const rgba& c)
+ {
+ // Calculate grayscale value as per ITU-R BT.709.
+ return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask));
+ }
+
+ static value_type luminance(const rgba8& c)
+ {
+ // Calculate grayscale value as per ITU-R BT.709.
+ return value_type((55u * c.r + 184u * c.g + 18u * c.b) >> 8);
+ }
+
+ static void convert(gray8T<linear>& dst, const gray8T<sRGB>& src)
+ {
+ dst.v = sRGB_conv<value_type>::rgb_from_sRGB(src.v);
+ dst.a = src.a;
+ }
+
+ static void convert(gray8T<sRGB>& dst, const gray8T<linear>& src)
+ {
+ dst.v = sRGB_conv<value_type>::rgb_to_sRGB(src.v);
+ dst.a = src.a;
+ }
+
+ static void convert(gray8T<linear>& dst, const rgba8& src)
+ {
+ dst.v = luminance(src);
+ dst.a = src.a;
+ }
+
+ static void convert(gray8T<linear>& dst, const srgba8& src)
+ {
+ // The RGB weights are only valid for linear values.
+ convert(dst, rgba8(src));
+ }
+
+ static void convert(gray8T<sRGB>& dst, const rgba8& src)
+ {
+ dst.v = sRGB_conv<value_type>::rgb_to_sRGB(luminance(src));
+ dst.a = src.a;
+ }
+
+ static void convert(gray8T<sRGB>& dst, const srgba8& src)
+ {
+ // The RGB weights are only valid for linear values.
+ convert(dst, rgba8(src));
+ }
+
+ //--------------------------------------------------------------------
+ gray8T() {}
+
+ //--------------------------------------------------------------------
+ explicit gray8T(unsigned v_, unsigned a_ = base_mask) :
+ v(int8u(v_)), a(int8u(a_)) {}
+
+ //--------------------------------------------------------------------
+ gray8T(const self_type& c, unsigned a_) :
+ v(c.v), a(value_type(a_)) {}
+
+ //--------------------------------------------------------------------
+ gray8T(const rgba& c) :
+ v(luminance(c)),
+ a(value_type(uround(c.a * base_mask))) {}
+
+ //--------------------------------------------------------------------
+ template<class T>
+ gray8T(const gray8T<T>& c)
+ {
+ convert(*this, c);
+ }
+
+ //--------------------------------------------------------------------
+ template<class T>
+ gray8T(const rgba8T<T>& c)
+ {
+ convert(*this, c);
+ }
+
+ //--------------------------------------------------------------------
+ template<class T>
+ T convert_from_sRGB() const
+ {
+ typename T::value_type y = sRGB_conv<typename T::value_type>::rgb_from_sRGB(v);
+ return T(y, y, y, sRGB_conv<typename T::value_type>::alpha_from_sRGB(a));
+ }
+
+ template<class T>
+ T convert_to_sRGB() const
+ {
+ typename T::value_type y = sRGB_conv<typename T::value_type>::rgb_to_sRGB(v);
+ return T(y, y, y, sRGB_conv<typename T::value_type>::alpha_to_sRGB(a));
+ }
+
+ //--------------------------------------------------------------------
+ rgba8 make_rgba8(const linear&) const
+ {
+ return rgba8(v, v, v, a);
+ }
+
+ rgba8 make_rgba8(const sRGB&) const
+ {
+ return convert_from_sRGB<srgba8>();
+ }
+
+ operator rgba8() const
+ {
+ return make_rgba8(Colorspace());
+ }
+
+ //--------------------------------------------------------------------
+ srgba8 make_srgba8(const linear&) const
+ {
+ return convert_to_sRGB<rgba8>();
+ }
+
+ srgba8 make_srgba8(const sRGB&) const
+ {
+ return srgba8(v, v, v, a);
+ }
+
+ operator srgba8() const
+ {
+ return make_rgba8(Colorspace());
+ }
+
+ //--------------------------------------------------------------------
+ rgba16 make_rgba16(const linear&) const
+ {
+ rgba16::value_type rgb = (v << 8) | v;
+ return rgba16(rgb, rgb, rgb, (a << 8) | a);
+ }
+
+ rgba16 make_rgba16(const sRGB&) const
+ {
+ return convert_from_sRGB<rgba16>();
+ }
+
+ operator rgba16() const
+ {
+ return make_rgba16(Colorspace());
+ }
+
+ //--------------------------------------------------------------------
+ rgba32 make_rgba32(const linear&) const
+ {
+ rgba32::value_type v32 = v / 255.0f;
+ return rgba32(v32, v32, v32, a / 255.0f);
+ }
+
+ rgba32 make_rgba32(const sRGB&) const
+ {
+ return convert_from_sRGB<rgba32>();
+ }
+
+ operator rgba32() const
+ {
+ return make_rgba32(Colorspace());
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE double to_double(value_type a)
+ {
+ return double(a) / base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type from_double(double a)
+ {
+ return value_type(uround(a * base_mask));
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type empty_value()
+ {
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type full_value()
+ {
+ return base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_transparent() const
+ {
+ return a == 0;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_opaque() const
+ {
+ return a == base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ // Fixed-point multiply, exact over int8u.
+ static AGG_INLINE value_type multiply(value_type a, value_type b)
+ {
+ calc_type t = a * b + base_MSB;
+ return value_type(((t >> base_shift) + t) >> base_shift);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type demultiply(value_type a, value_type b)
+ {
+ if (a * b == 0)
+ {
+ return 0;
+ }
+ else if (a >= b)
+ {
+ return base_mask;
+ }
+ else return value_type((a * base_mask + (b >> 1)) / b);
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downscale(T a)
+ {
+ return a >> base_shift;
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downshift(T a, unsigned n)
+ {
+ return a >> n;
+ }
+
+ //--------------------------------------------------------------------
+ // Fixed-point multiply, exact over int8u.
+ // Specifically for multiplying a color component by a cover.
+ static AGG_INLINE value_type mult_cover(value_type a, value_type b)
+ {
+ return multiply(a, b);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
+ {
+ return multiply(b, a);
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a, assuming q is premultiplied by a.
+ static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
+ {
+ return p + q - multiply(p, a);
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a.
+ static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
+ {
+ int t = (q - p) * a + base_MSB - (p > q);
+ return value_type(p + (((t >> base_shift) + t) >> base_shift));
+ }
+
+ //--------------------------------------------------------------------
+ self_type& clear()
+ {
+ v = a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& transparent()
+ {
+ a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& opacity(double a_)
+ {
+ if (a_ < 0) a = 0;
+ else if (a_ > 1) a = 1;
+ else a = (value_type)uround(a_ * double(base_mask));
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ double opacity() const
+ {
+ return double(a) / double(base_mask);
+ }
+
+ //--------------------------------------------------------------------
+ self_type& premultiply()
+ {
+ if (a < base_mask)
+ {
+ if (a == 0) v = 0;
+ else v = multiply(v, a);
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& demultiply()
+ {
+ if (a < base_mask)
+ {
+ if (a == 0)
+ {
+ v = 0;
+ }
+ else
+ {
+ calc_type v_ = (calc_type(v) * base_mask) / a;
+ v = value_type((v_ > base_mask) ? (value_type)base_mask : v_);
+ }
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type gradient(self_type c, double k) const
+ {
+ self_type ret;
+ calc_type ik = uround(k * base_scale);
+ ret.v = lerp(v, c.v, ik);
+ ret.a = lerp(a, c.a, ik);
+ return ret;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void add(const self_type& c, unsigned cover)
+ {
+ calc_type cv, ca;
+ if (cover == cover_mask)
+ {
+ if (c.a == base_mask)
+ {
+ *this = c;
+ return;
+ }
+ else
+ {
+ cv = v + c.v;
+ ca = a + c.a;
+ }
+ }
+ else
+ {
+ cv = v + mult_cover(c.v, cover);
+ ca = a + mult_cover(c.a, cover);
+ }
+ v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv);
+ a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
+ }
+
+ //--------------------------------------------------------------------
+ static self_type no_color() { return self_type(0,0); }
+ };
+
+ typedef gray8T<linear> gray8;
+ typedef gray8T<sRGB> sgray8;
+
+
+ //==================================================================gray16
+ struct gray16
+ {
+ typedef int16u value_type;
+ typedef int32u calc_type;
+ typedef int64 long_type;
+ enum base_scale_e
+ {
+ base_shift = 16,
+ base_scale = 1 << base_shift,
+ base_mask = base_scale - 1,
+ base_MSB = 1 << (base_shift - 1)
+ };
+ typedef gray16 self_type;
+
+ value_type v;
+ value_type a;
+
+ static value_type luminance(const rgba& c)
+ {
+ // Calculate grayscale value as per ITU-R BT.709.
+ return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask));
+ }
+
+ static value_type luminance(const rgba16& c)
+ {
+ // Calculate grayscale value as per ITU-R BT.709.
+ return value_type((13933u * c.r + 46872u * c.g + 4732u * c.b) >> 16);
+ }
+
+ static value_type luminance(const rgba8& c)
+ {
+ return luminance(rgba16(c));
+ }
+
+ static value_type luminance(const srgba8& c)
+ {
+ return luminance(rgba16(c));
+ }
+
+ static value_type luminance(const rgba32& c)
+ {
+ return luminance(rgba(c));
+ }
+
+ //--------------------------------------------------------------------
+ gray16() {}
+
+ //--------------------------------------------------------------------
+ explicit gray16(unsigned v_, unsigned a_ = base_mask) :
+ v(int16u(v_)), a(int16u(a_)) {}
+
+ //--------------------------------------------------------------------
+ gray16(const self_type& c, unsigned a_) :
+ v(c.v), a(value_type(a_)) {}
+
+ //--------------------------------------------------------------------
+ gray16(const rgba& c) :
+ v(luminance(c)),
+ a((value_type)uround(c.a * double(base_mask))) {}
+
+ //--------------------------------------------------------------------
+ gray16(const rgba8& c) :
+ v(luminance(c)),
+ a((value_type(c.a) << 8) | c.a) {}
+
+ //--------------------------------------------------------------------
+ gray16(const srgba8& c) :
+ v(luminance(c)),
+ a((value_type(c.a) << 8) | c.a) {}
+
+ //--------------------------------------------------------------------
+ gray16(const rgba16& c) :
+ v(luminance(c)),
+ a(c.a) {}
+
+ //--------------------------------------------------------------------
+ gray16(const gray8& c) :
+ v((value_type(c.v) << 8) | c.v),
+ a((value_type(c.a) << 8) | c.a) {}
+
+ //--------------------------------------------------------------------
+ gray16(const sgray8& c) :
+ v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)),
+ a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
+
+ //--------------------------------------------------------------------
+ operator rgba8() const
+ {
+ return rgba8(v >> 8, v >> 8, v >> 8, a >> 8);
+ }
+
+ //--------------------------------------------------------------------
+ operator srgba8() const
+ {
+ value_type y = sRGB_conv<value_type>::rgb_to_sRGB(v);
+ return srgba8(y, y, y, sRGB_conv<value_type>::alpha_to_sRGB(a));
+ }
+
+ //--------------------------------------------------------------------
+ operator rgba16() const
+ {
+ return rgba16(v, v, v, a);
+ }
+
+ //--------------------------------------------------------------------
+ operator rgba32() const
+ {
+ rgba32::value_type v32 = v / 65535.0f;
+ return rgba32(v32, v32, v32, a / 65535.0f);
+ }
+
+ //--------------------------------------------------------------------
+ operator gray8() const
+ {
+ return gray8(v >> 8, a >> 8);
+ }
+
+ //--------------------------------------------------------------------
+ operator sgray8() const
+ {
+ return sgray8(
+ sRGB_conv<value_type>::rgb_to_sRGB(v),
+ sRGB_conv<value_type>::alpha_to_sRGB(a));
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE double to_double(value_type a)
+ {
+ return double(a) / base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type from_double(double a)
+ {
+ return value_type(uround(a * base_mask));
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type empty_value()
+ {
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type full_value()
+ {
+ return base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_transparent() const
+ {
+ return a == 0;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_opaque() const
+ {
+ return a == base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ // Fixed-point multiply, exact over int16u.
+ static AGG_INLINE value_type multiply(value_type a, value_type b)
+ {
+ calc_type t = a * b + base_MSB;
+ return value_type(((t >> base_shift) + t) >> base_shift);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type demultiply(value_type a, value_type b)
+ {
+ if (a * b == 0)
+ {
+ return 0;
+ }
+ else if (a >= b)
+ {
+ return base_mask;
+ }
+ else return value_type((a * base_mask + (b >> 1)) / b);
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downscale(T a)
+ {
+ return a >> base_shift;
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downshift(T a, unsigned n)
+ {
+ return a >> n;
+ }
+
+ //--------------------------------------------------------------------
+ // Fixed-point multiply, almost exact over int16u.
+ // Specifically for multiplying a color component by a cover.
+ static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
+ {
+ return multiply(a, b << 8 | b);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
+ {
+ return mult_cover(b, a) >> 8;
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a, assuming q is premultiplied by a.
+ static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
+ {
+ return p + q - multiply(p, a);
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a.
+ static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
+ {
+ int t = (q - p) * a + base_MSB - (p > q);
+ return value_type(p + (((t >> base_shift) + t) >> base_shift));
+ }
+
+ //--------------------------------------------------------------------
+ self_type& clear()
+ {
+ v = a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& transparent()
+ {
+ a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& opacity(double a_)
+ {
+ if (a_ < 0) a = 0;
+ else if(a_ > 1) a = 1;
+ else a = (value_type)uround(a_ * double(base_mask));
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ double opacity() const
+ {
+ return double(a) / double(base_mask);
+ }
+
+
+ //--------------------------------------------------------------------
+ self_type& premultiply()
+ {
+ if (a < base_mask)
+ {
+ if(a == 0) v = 0;
+ else v = multiply(v, a);
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& demultiply()
+ {
+ if (a < base_mask)
+ {
+ if (a == 0)
+ {
+ v = 0;
+ }
+ else
+ {
+ calc_type v_ = (calc_type(v) * base_mask) / a;
+ v = (v_ > base_mask) ? value_type(base_mask) : value_type(v_);
+ }
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type gradient(self_type c, double k) const
+ {
+ self_type ret;
+ calc_type ik = uround(k * base_scale);
+ ret.v = lerp(v, c.v, ik);
+ ret.a = lerp(a, c.a, ik);
+ return ret;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void add(const self_type& c, unsigned cover)
+ {
+ calc_type cv, ca;
+ if (cover == cover_mask)
+ {
+ if (c.a == base_mask)
+ {
+ *this = c;
+ return;
+ }
+ else
+ {
+ cv = v + c.v;
+ ca = a + c.a;
+ }
+ }
+ else
+ {
+ cv = v + mult_cover(c.v, cover);
+ ca = a + mult_cover(c.a, cover);
+ }
+ v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv);
+ a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
+ }
+
+ //--------------------------------------------------------------------
+ static self_type no_color() { return self_type(0,0); }
+ };
+
+
+ //===================================================================gray32
+ struct gray32
+ {
+ typedef float value_type;
+ typedef double calc_type;
+ typedef double long_type;
+ typedef gray32 self_type;
+
+ value_type v;
+ value_type a;
+
+ // Calculate grayscale value as per ITU-R BT.709.
+ static value_type luminance(double r, double g, double b)
+ {
+ return value_type(0.2126 * r + 0.7152 * g + 0.0722 * b);
+ }
+
+ static value_type luminance(const rgba& c)
+ {
+ return luminance(c.r, c.g, c.b);
+ }
+
+ static value_type luminance(const rgba32& c)
+ {
+ return luminance(c.r, c.g, c.b);
+ }
+
+ static value_type luminance(const rgba8& c)
+ {
+ return luminance(c.r / 255.0, c.g / 255.0, c.g / 255.0);
+ }
+
+ static value_type luminance(const rgba16& c)
+ {
+ return luminance(c.r / 65535.0, c.g / 65535.0, c.g / 65535.0);
+ }
+
+ //--------------------------------------------------------------------
+ gray32() {}
+
+ //--------------------------------------------------------------------
+ explicit gray32(value_type v_, value_type a_ = 1) :
+ v(v_), a(a_) {}
+
+ //--------------------------------------------------------------------
+ gray32(const self_type& c, value_type a_) :
+ v(c.v), a(a_) {}
+
+ //--------------------------------------------------------------------
+ gray32(const rgba& c) :
+ v(luminance(c)),
+ a(value_type(c.a)) {}
+
+ //--------------------------------------------------------------------
+ gray32(const rgba8& c) :
+ v(luminance(c)),
+ a(value_type(c.a / 255.0)) {}
+
+ //--------------------------------------------------------------------
+ gray32(const srgba8& c) :
+ v(luminance(rgba32(c))),
+ a(value_type(c.a / 255.0)) {}
+
+ //--------------------------------------------------------------------
+ gray32(const rgba16& c) :
+ v(luminance(c)),
+ a(value_type(c.a / 65535.0)) {}
+
+ //--------------------------------------------------------------------
+ gray32(const rgba32& c) :
+ v(luminance(c)),
+ a(value_type(c.a)) {}
+
+ //--------------------------------------------------------------------
+ gray32(const gray8& c) :
+ v(value_type(c.v / 255.0)),
+ a(value_type(c.a / 255.0)) {}
+
+ //--------------------------------------------------------------------
+ gray32(const sgray8& c) :
+ v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)),
+ a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
+
+ //--------------------------------------------------------------------
+ gray32(const gray16& c) :
+ v(value_type(c.v / 65535.0)),
+ a(value_type(c.a / 65535.0)) {}
+
+ //--------------------------------------------------------------------
+ operator rgba() const
+ {
+ return rgba(v, v, v, a);
+ }
+
+ //--------------------------------------------------------------------
+ operator gray8() const
+ {
+ return gray8(uround(v * 255.0), uround(a * 255.0));
+ }
+
+ //--------------------------------------------------------------------
+ operator sgray8() const
+ {
+ // Return (non-premultiplied) sRGB values.
+ return sgray8(
+ sRGB_conv<value_type>::rgb_to_sRGB(v),
+ sRGB_conv<value_type>::alpha_to_sRGB(a));
+ }
+
+ //--------------------------------------------------------------------
+ operator gray16() const
+ {
+ return gray16(uround(v * 65535.0), uround(a * 65535.0));
+ }
+
+ //--------------------------------------------------------------------
+ operator rgba8() const
+ {
+ rgba8::value_type y = uround(v * 255.0);
+ return rgba8(y, y, y, uround(a * 255.0));
+ }
+
+ //--------------------------------------------------------------------
+ operator srgba8() const
+ {
+ srgba8::value_type y = sRGB_conv<value_type>::rgb_to_sRGB(v);
+ return srgba8(y, y, y, sRGB_conv<value_type>::alpha_to_sRGB(a));
+ }
+
+ //--------------------------------------------------------------------
+ operator rgba16() const
+ {
+ rgba16::value_type y = uround(v * 65535.0);
+ return rgba16(y, y, y, uround(a * 65535.0));
+ }
+
+ //--------------------------------------------------------------------
+ operator rgba32() const
+ {
+ return rgba32(v, v, v, a);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE double to_double(value_type a)
+ {
+ return a;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type from_double(double a)
+ {
+ return value_type(a);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type empty_value()
+ {
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type full_value()
+ {
+ return 1;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_transparent() const
+ {
+ return a <= 0;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_opaque() const
+ {
+ return a >= 1;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type invert(value_type x)
+ {
+ return 1 - x;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type multiply(value_type a, value_type b)
+ {
+ return value_type(a * b);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type demultiply(value_type a, value_type b)
+ {
+ return (b == 0) ? 0 : value_type(a / b);
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downscale(T a)
+ {
+ return a;
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downshift(T a, unsigned n)
+ {
+ return n > 0 ? a / (1 << n) : a;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
+ {
+ return value_type(a * b / cover_mask);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
+ {
+ return cover_type(uround(a * b));
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a, assuming q is premultiplied by a.
+ static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
+ {
+ return (1 - a) * p + q; // more accurate than "p + q - p * a"
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a.
+ static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
+ {
+ // The form "p + a * (q - p)" avoids a multiplication, but may produce an
+ // inaccurate result. For example, "p + (q - p)" may not be exactly equal
+ // to q. Therefore, stick to the basic expression, which at least produces
+ // the correct result at either extreme.
+ return (1 - a) * p + a * q;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& clear()
+ {
+ v = a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& transparent()
+ {
+ a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& opacity(double a_)
+ {
+ if (a_ < 0) a = 0;
+ else if (a_ > 1) a = 1;
+ else a = value_type(a_);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ double opacity() const
+ {
+ return a;
+ }
+
+
+ //--------------------------------------------------------------------
+ self_type& premultiply()
+ {
+ if (a < 0) v = 0;
+ else if(a < 1) v *= a;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& demultiply()
+ {
+ if (a < 0) v = 0;
+ else if (a < 1) v /= a;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type gradient(self_type c, double k) const
+ {
+ return self_type(
+ value_type(v + (c.v - v) * k),
+ value_type(a + (c.a - a) * k));
+ }
+
+ //--------------------------------------------------------------------
+ static self_type no_color() { return self_type(0,0); }
+ };
+}
+
+
+
+
+#endif
diff --git a/xs/src/agg/agg_color_rgba.h b/xs/src/agg/agg_color_rgba.h
new file mode 100644
index 000000000..ff33a1179
--- /dev/null
+++ b/xs/src/agg/agg_color_rgba.h
@@ -0,0 +1,1353 @@
+//----------------------------------------------------------------------------
+// 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.
+//
+//----------------------------------------------------------------------------
+//
+// 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.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+
+#ifndef AGG_COLOR_RGBA_INCLUDED
+#define AGG_COLOR_RGBA_INCLUDED
+
+#include <math.h>
+#include "agg_basics.h"
+#include "agg_gamma_lut.h"
+
+namespace agg
+{
+ // Supported component orders for RGB and RGBA pixel formats
+ //=======================================================================
+ struct order_rgb { enum rgb_e { R=0, G=1, B=2, N=3 }; };
+ struct order_bgr { enum bgr_e { B=0, G=1, R=2, N=3 }; };
+ struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, N=4 }; };
+ struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, N=4 }; };
+ struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, N=4 }; };
+ struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, N=4 }; };
+
+ // Colorspace tag types.
+ struct linear {};
+ struct sRGB {};
+
+ //====================================================================rgba
+ struct rgba
+ {
+ typedef double value_type;
+
+ double r;
+ double g;
+ double b;
+ double a;
+
+ //--------------------------------------------------------------------
+ rgba() {}
+
+ //--------------------------------------------------------------------
+ rgba(double r_, double g_, double b_, double a_=1.0) :
+ r(r_), g(g_), b(b_), a(a_) {}
+
+ //--------------------------------------------------------------------
+ rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {}
+
+ //--------------------------------------------------------------------
+ rgba& clear()
+ {
+ r = g = b = a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ rgba& transparent()
+ {
+ a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ rgba& opacity(double a_)
+ {
+ if (a_ < 0) a = 0;
+ else if (a_ > 1) a = 1;
+ else a = a_;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ double opacity() const
+ {
+ return a;
+ }
+
+ //--------------------------------------------------------------------
+ rgba& premultiply()
+ {
+ r *= a;
+ g *= a;
+ b *= a;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ rgba& premultiply(double a_)
+ {
+ if (a <= 0 || a_ <= 0)
+ {
+ r = g = b = a = 0;
+ }
+ else
+ {
+ a_ /= a;
+ r *= a_;
+ g *= a_;
+ b *= a_;
+ a = a_;
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ rgba& demultiply()
+ {
+ if (a == 0)
+ {
+ r = g = b = 0;
+ }
+ else
+ {
+ double a_ = 1.0 / a;
+ r *= a_;
+ g *= a_;
+ b *= a_;
+ }
+ return *this;
+ }
+
+
+ //--------------------------------------------------------------------
+ rgba gradient(rgba c, double k) const
+ {
+ rgba ret;
+ ret.r = r + (c.r - r) * k;
+ ret.g = g + (c.g - g) * k;
+ ret.b = b + (c.b - b) * k;
+ ret.a = a + (c.a - a) * k;
+ return ret;
+ }
+
+ rgba& operator+=(const rgba& c)
+ {
+ r += c.r;
+ g += c.g;
+ b += c.b;
+ a += c.a;
+ return *this;
+ }
+
+ rgba& operator*=(double k)
+ {
+ r *= k;
+ g *= k;
+ b *= k;
+ a *= k;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ static rgba no_color() { return rgba(0,0,0,0); }
+
+ //--------------------------------------------------------------------
+ static rgba from_wavelength(double wl, double gamma = 1.0);
+
+ //--------------------------------------------------------------------
+ explicit rgba(double wavelen, double gamma=1.0)
+ {
+ *this = from_wavelength(wavelen, gamma);
+ }
+
+ };
+
+ inline rgba operator+(const rgba& a, const rgba& b)
+ {
+ return rgba(a) += b;
+ }
+
+ inline rgba operator*(const rgba& a, double b)
+ {
+ return rgba(a) *= b;
+ }
+
+ //------------------------------------------------------------------------
+ inline rgba rgba::from_wavelength(double wl, double gamma)
+ {
+ rgba t(0.0, 0.0, 0.0);
+
+ if (wl >= 380.0 && wl <= 440.0)
+ {
+ t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0);
+ t.b = 1.0;
+ }
+ else if (wl >= 440.0 && wl <= 490.0)
+ {
+ t.g = (wl - 440.0) / (490.0 - 440.0);
+ t.b = 1.0;
+ }
+ else if (wl >= 490.0 && wl <= 510.0)
+ {
+ t.g = 1.0;
+ t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0);
+ }
+ else if (wl >= 510.0 && wl <= 580.0)
+ {
+ t.r = (wl - 510.0) / (580.0 - 510.0);
+ t.g = 1.0;
+ }
+ else if (wl >= 580.0 && wl <= 645.0)
+ {
+ t.r = 1.0;
+ t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0);
+ }
+ else if (wl >= 645.0 && wl <= 780.0)
+ {
+ t.r = 1.0;
+ }
+
+ double s = 1.0;
+ if (wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0);
+ else if (wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0);
+
+ t.r = pow(t.r * s, gamma);
+ t.g = pow(t.g * s, gamma);
+ t.b = pow(t.b * s, gamma);
+ return t;
+ }
+
+ inline rgba rgba_pre(double r, double g, double b, double a)
+ {
+ return rgba(r, g, b, a).premultiply();
+ }
+
+
+ //===================================================================rgba8
+ template<class Colorspace>
+ struct rgba8T
+ {
+ typedef int8u value_type;
+ typedef int32u calc_type;
+ typedef int32 long_type;
+ enum base_scale_e
+ {
+ base_shift = 8,
+ base_scale = 1 << base_shift,
+ base_mask = base_scale - 1,
+ base_MSB = 1 << (base_shift - 1)
+ };
+ typedef rgba8T self_type;
+
+
+ value_type r;
+ value_type g;
+ value_type b;
+ value_type a;
+
+ static void convert(rgba8T<linear>& dst, const rgba8T<sRGB>& src)
+ {
+ dst.r = sRGB_conv<value_type>::rgb_from_sRGB(src.r);
+ dst.g = sRGB_conv<value_type>::rgb_from_sRGB(src.g);
+ dst.b = sRGB_conv<value_type>::rgb_from_sRGB(src.b);
+ dst.a = src.a;
+ }
+
+ static void convert(rgba8T<sRGB>& dst, const rgba8T<linear>& src)
+ {
+ dst.r = sRGB_conv<value_type>::rgb_to_sRGB(src.r);
+ dst.g = sRGB_conv<value_type>::rgb_to_sRGB(src.g);
+ dst.b = sRGB_conv<value_type>::rgb_to_sRGB(src.b);
+ dst.a = src.a;
+ }
+
+ static void convert(rgba8T<linear>& dst, const rgba& src)
+ {
+ dst.r = value_type(uround(src.r * base_mask));
+ dst.g = value_type(uround(src.g * base_mask));
+ dst.b = value_type(uround(src.b * base_mask));
+ dst.a = value_type(uround(src.a * base_mask));
+ }
+
+ static void convert(rgba8T<sRGB>& dst, const rgba& src)
+ {
+ // Use the "float" table.
+ dst.r = sRGB_conv<float>::rgb_to_sRGB(float(src.r));
+ dst.g = sRGB_conv<float>::rgb_to_sRGB(float(src.g));
+ dst.b = sRGB_conv<float>::rgb_to_sRGB(float(src.b));
+ dst.a = sRGB_conv<float>::alpha_to_sRGB(float(src.a));
+ }
+
+ static void convert(rgba& dst, const rgba8T<linear>& src)
+ {
+ dst.r = src.r / 255.0;
+ dst.g = src.g / 255.0;
+ dst.b = src.b / 255.0;
+ dst.a = src.a / 255.0;
+ }
+
+ static void convert(rgba& dst, const rgba8T<sRGB>& src)
+ {
+ // Use the "float" table.
+ dst.r = sRGB_conv<float>::rgb_from_sRGB(src.r);
+ dst.g = sRGB_conv<float>::rgb_from_sRGB(src.g);
+ dst.b = sRGB_conv<float>::rgb_from_sRGB(src.b);
+ dst.a = sRGB_conv<float>::alpha_from_sRGB(src.a);
+ }
+
+ //--------------------------------------------------------------------
+ rgba8T() {}
+
+ //--------------------------------------------------------------------
+ rgba8T(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask) :
+ r(value_type(r_)),
+ g(value_type(g_)),
+ b(value_type(b_)),
+ a(value_type(a_)) {}
+
+ //--------------------------------------------------------------------
+ rgba8T(const rgba& c)
+ {
+ convert(*this, c);
+ }
+
+ //--------------------------------------------------------------------
+ rgba8T(const self_type& c, unsigned a_) :
+ r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
+
+ //--------------------------------------------------------------------
+ template<class T>
+ rgba8T(const rgba8T<T>& c)
+ {
+ convert(*this, c);
+ }
+
+ //--------------------------------------------------------------------
+ operator rgba() const
+ {
+ rgba c;
+ convert(c, *this);
+ return c;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE double to_double(value_type a)
+ {
+ return double(a) / base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type from_double(double a)
+ {
+ return value_type(uround(a * base_mask));
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type empty_value()
+ {
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type full_value()
+ {
+ return base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_transparent() const
+ {
+ return a == 0;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_opaque() const
+ {
+ return a == base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type invert(value_type x)
+ {
+ return base_mask - x;
+ }
+
+ //--------------------------------------------------------------------
+ // Fixed-point multiply, exact over int8u.
+ static AGG_INLINE value_type multiply(value_type a, value_type b)
+ {
+ calc_type t = a * b + base_MSB;
+ return value_type(((t >> base_shift) + t) >> base_shift);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type demultiply(value_type a, value_type b)
+ {
+ if (a * b == 0)
+ {
+ return 0;
+ }
+ else if (a >= b)
+ {
+ return base_mask;
+ }
+ else return value_type((a * base_mask + (b >> 1)) / b);
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downscale(T a)
+ {
+ return a >> base_shift;
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downshift(T a, unsigned n)
+ {
+ return a >> n;
+ }
+
+ //--------------------------------------------------------------------
+ // Fixed-point multiply, exact over int8u.
+ // Specifically for multiplying a color component by a cover.
+ static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
+ {
+ return multiply(a, b);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
+ {
+ return multiply(b, a);
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a, assuming q is premultiplied by a.
+ static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
+ {
+ return p + q - multiply(p, a);
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a.
+ static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
+ {
+ int t = (q - p) * a + base_MSB - (p > q);
+ return value_type(p + (((t >> base_shift) + t) >> base_shift));
+ }
+
+ //--------------------------------------------------------------------
+ self_type& clear()
+ {
+ r = g = b = a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& transparent()
+ {
+ a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& opacity(double a_)
+ {
+ if (a_ < 0) a = 0;
+ else if (a_ > 1) a = 1;
+ else a = (value_type)uround(a_ * double(base_mask));
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ double opacity() const
+ {
+ return double(a) / double(base_mask);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type& premultiply()
+ {
+ if (a != base_mask)
+ {
+ if (a == 0)
+ {
+ r = g = b = 0;
+ }
+ else
+ {
+ r = multiply(r, a);
+ g = multiply(g, a);
+ b = multiply(b, a);
+ }
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type& premultiply(unsigned a_)
+ {
+ if (a != base_mask || a_ < base_mask)
+ {
+ if (a == 0 || a_ == 0)
+ {
+ r = g = b = a = 0;
+ }
+ else
+ {
+ calc_type r_ = (calc_type(r) * a_) / a;
+ calc_type g_ = (calc_type(g) * a_) / a;
+ calc_type b_ = (calc_type(b) * a_) / a;
+ r = value_type((r_ > a_) ? a_ : r_);
+ g = value_type((g_ > a_) ? a_ : g_);
+ b = value_type((b_ > a_) ? a_ : b_);
+ a = value_type(a_);
+ }
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type& demultiply()
+ {
+ if (a < base_mask)
+ {
+ if (a == 0)
+ {
+ r = g = b = 0;
+ }
+ else
+ {
+ calc_type r_ = (calc_type(r) * base_mask) / a;
+ calc_type g_ = (calc_type(g) * base_mask) / a;
+ calc_type b_ = (calc_type(b) * base_mask) / a;
+ r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
+ g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
+ b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
+ }
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type gradient(const self_type& c, double k) const
+ {
+ self_type ret;
+ calc_type ik = uround(k * base_mask);
+ ret.r = lerp(r, c.r, ik);
+ ret.g = lerp(g, c.g, ik);
+ ret.b = lerp(b, c.b, ik);
+ ret.a = lerp(a, c.a, ik);
+ return ret;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void add(const self_type& c, unsigned cover)
+ {
+ calc_type cr, cg, cb, ca;
+ if (cover == cover_mask)
+ {
+ if (c.a == base_mask)
+ {
+ *this = c;
+ return;
+ }
+ else
+ {
+ cr = r + c.r;
+ cg = g + c.g;
+ cb = b + c.b;
+ ca = a + c.a;
+ }
+ }
+ else
+ {
+ cr = r + mult_cover(c.r, cover);
+ cg = g + mult_cover(c.g, cover);
+ cb = b + mult_cover(c.b, cover);
+ ca = a + mult_cover(c.a, cover);
+ }
+ r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr);
+ g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg);
+ b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb);
+ a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
+ }
+
+ //--------------------------------------------------------------------
+ template<class GammaLUT>
+ AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma)
+ {
+ r = gamma.dir(r);
+ g = gamma.dir(g);
+ b = gamma.dir(b);
+ }
+
+ //--------------------------------------------------------------------
+ template<class GammaLUT>
+ AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma)
+ {
+ r = gamma.inv(r);
+ g = gamma.inv(g);
+ b = gamma.inv(b);
+ }
+
+ //--------------------------------------------------------------------
+ static self_type no_color() { return self_type(0,0,0,0); }
+
+ //--------------------------------------------------------------------
+ static self_type from_wavelength(double wl, double gamma = 1.0)
+ {
+ return self_type(rgba::from_wavelength(wl, gamma));
+ }
+ };
+
+ typedef rgba8T<linear> rgba8;
+ typedef rgba8T<sRGB> srgba8;
+
+
+ //-------------------------------------------------------------rgb8_packed
+ inline rgba8 rgb8_packed(unsigned v)
+ {
+ return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF);
+ }
+
+ //-------------------------------------------------------------bgr8_packed
+ inline rgba8 bgr8_packed(unsigned v)
+ {
+ return rgba8(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF);
+ }
+
+ //------------------------------------------------------------argb8_packed
+ inline rgba8 argb8_packed(unsigned v)
+ {
+ return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF, v >> 24);
+ }
+
+ //---------------------------------------------------------rgba8_gamma_dir
+ template<class GammaLUT>
+ rgba8 rgba8_gamma_dir(rgba8 c, const GammaLUT& gamma)
+ {
+ return rgba8(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a);
+ }
+
+ //---------------------------------------------------------rgba8_gamma_inv
+ template<class GammaLUT>
+ rgba8 rgba8_gamma_inv(rgba8 c, const GammaLUT& gamma)
+ {
+ return rgba8(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a);
+ }
+
+
+
+ //==================================================================rgba16
+ struct rgba16
+ {
+ typedef int16u value_type;
+ typedef int32u calc_type;
+ typedef int64 long_type;
+ enum base_scale_e
+ {
+ base_shift = 16,
+ base_scale = 1 << base_shift,
+ base_mask = base_scale - 1,
+ base_MSB = 1 << (base_shift - 1)
+ };
+ typedef rgba16 self_type;
+
+ value_type r;
+ value_type g;
+ value_type b;
+ value_type a;
+
+ //--------------------------------------------------------------------
+ rgba16() {}
+
+ //--------------------------------------------------------------------
+ rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) :
+ r(value_type(r_)),
+ g(value_type(g_)),
+ b(value_type(b_)),
+ a(value_type(a_)) {}
+
+ //--------------------------------------------------------------------
+ rgba16(const self_type& c, unsigned a_) :
+ r(c.r), g(c.g), b(c.b), a(value_type(a_)) {}
+
+ //--------------------------------------------------------------------
+ rgba16(const rgba& c) :
+ r((value_type)uround(c.r * double(base_mask))),
+ g((value_type)uround(c.g * double(base_mask))),
+ b((value_type)uround(c.b * double(base_mask))),
+ a((value_type)uround(c.a * double(base_mask))) {}
+
+ //--------------------------------------------------------------------
+ rgba16(const rgba8& c) :
+ r(value_type((value_type(c.r) << 8) | c.r)),
+ g(value_type((value_type(c.g) << 8) | c.g)),
+ b(value_type((value_type(c.b) << 8) | c.b)),
+ a(value_type((value_type(c.a) << 8) | c.a)) {}
+
+ //--------------------------------------------------------------------
+ rgba16(const srgba8& c) :
+ r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)),
+ g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)),
+ b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)),
+ a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
+
+ //--------------------------------------------------------------------
+ operator rgba() const
+ {
+ return rgba(
+ r / 65535.0,
+ g / 65535.0,
+ b / 65535.0,
+ a / 65535.0);
+ }
+
+ //--------------------------------------------------------------------
+ operator rgba8() const
+ {
+ return rgba8(r >> 8, g >> 8, b >> 8, a >> 8);
+ }
+
+ //--------------------------------------------------------------------
+ operator srgba8() const
+ {
+ // Return (non-premultiplied) sRGB values.
+ return srgba8(
+ sRGB_conv<value_type>::rgb_to_sRGB(r),
+ sRGB_conv<value_type>::rgb_to_sRGB(g),
+ sRGB_conv<value_type>::rgb_to_sRGB(b),
+ sRGB_conv<value_type>::alpha_to_sRGB(a));
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE double to_double(value_type a)
+ {
+ return double(a) / base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type from_double(double a)
+ {
+ return value_type(uround(a * base_mask));
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type empty_value()
+ {
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type full_value()
+ {
+ return base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_transparent() const
+ {
+ return a == 0;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_opaque() const
+ {
+ return a == base_mask;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type invert(value_type x)
+ {
+ return base_mask - x;
+ }
+
+ //--------------------------------------------------------------------
+ // Fixed-point multiply, exact over int16u.
+ static AGG_INLINE value_type multiply(value_type a, value_type b)
+ {
+ calc_type t = a * b + base_MSB;
+ return value_type(((t >> base_shift) + t) >> base_shift);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type demultiply(value_type a, value_type b)
+ {
+ if (a * b == 0)
+ {
+ return 0;
+ }
+ else if (a >= b)
+ {
+ return base_mask;
+ }
+ else return value_type((a * base_mask + (b >> 1)) / b);
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downscale(T a)
+ {
+ return a >> base_shift;
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downshift(T a, unsigned n)
+ {
+ return a >> n;
+ }
+
+ //--------------------------------------------------------------------
+ // Fixed-point multiply, almost exact over int16u.
+ // Specifically for multiplying a color component by a cover.
+ static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
+ {
+ return multiply(a, (b << 8) | b);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
+ {
+ return multiply((a << 8) | a, b) >> 8;
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a, assuming q is premultiplied by a.
+ static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
+ {
+ return p + q - multiply(p, a);
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a.
+ static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
+ {
+ int t = (q - p) * a + base_MSB - (p > q);
+ return value_type(p + (((t >> base_shift) + t) >> base_shift));
+ }
+
+ //--------------------------------------------------------------------
+ self_type& clear()
+ {
+ r = g = b = a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& transparent()
+ {
+ a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type& opacity(double a_)
+ {
+ if (a_ < 0) a = 0;
+ if (a_ > 1) a = 1;
+ a = value_type(uround(a_ * double(base_mask)));
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ double opacity() const
+ {
+ return double(a) / double(base_mask);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type& premultiply()
+ {
+ if (a != base_mask)
+ {
+ if (a == 0)
+ {
+ r = g = b = 0;
+ }
+ else
+ {
+ r = multiply(r, a);
+ g = multiply(g, a);
+ b = multiply(b, a);
+ }
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type& premultiply(unsigned a_)
+ {
+ if (a < base_mask || a_ < base_mask)
+ {
+ if (a == 0 || a_ == 0)
+ {
+ r = g = b = a = 0;
+ }
+ else
+ {
+ calc_type r_ = (calc_type(r) * a_) / a;
+ calc_type g_ = (calc_type(g) * a_) / a;
+ calc_type b_ = (calc_type(b) * a_) / a;
+ r = value_type((r_ > a_) ? a_ : r_);
+ g = value_type((g_ > a_) ? a_ : g_);
+ b = value_type((b_ > a_) ? a_ : b_);
+ a = value_type(a_);
+ }
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type& demultiply()
+ {
+ if (a < base_mask)
+ {
+ if (a == 0)
+ {
+ r = g = b = 0;
+ }
+ else
+ {
+ calc_type r_ = (calc_type(r) * base_mask) / a;
+ calc_type g_ = (calc_type(g) * base_mask) / a;
+ calc_type b_ = (calc_type(b) * base_mask) / a;
+ r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
+ g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
+ b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
+ }
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type gradient(const self_type& c, double k) const
+ {
+ self_type ret;
+ calc_type ik = uround(k * base_mask);
+ ret.r = lerp(r, c.r, ik);
+ ret.g = lerp(g, c.g, ik);
+ ret.b = lerp(b, c.b, ik);
+ ret.a = lerp(a, c.a, ik);
+ return ret;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void add(const self_type& c, unsigned cover)
+ {
+ calc_type cr, cg, cb, ca;
+ if (cover == cover_mask)
+ {
+ if (c.a == base_mask)
+ {
+ *this = c;
+ return;
+ }
+ else
+ {
+ cr = r + c.r;
+ cg = g + c.g;
+ cb = b + c.b;
+ ca = a + c.a;
+ }
+ }
+ else
+ {
+ cr = r + mult_cover(c.r, cover);
+ cg = g + mult_cover(c.g, cover);
+ cb = b + mult_cover(c.b, cover);
+ ca = a + mult_cover(c.a, cover);
+ }
+ r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr);
+ g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg);
+ b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb);
+ a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca);
+ }
+
+ //--------------------------------------------------------------------
+ template<class GammaLUT>
+ AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma)
+ {
+ r = gamma.dir(r);
+ g = gamma.dir(g);
+ b = gamma.dir(b);
+ }
+
+ //--------------------------------------------------------------------
+ template<class GammaLUT>
+ AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma)
+ {
+ r = gamma.inv(r);
+ g = gamma.inv(g);
+ b = gamma.inv(b);
+ }
+
+ //--------------------------------------------------------------------
+ static self_type no_color() { return self_type(0,0,0,0); }
+
+ //--------------------------------------------------------------------
+ static self_type from_wavelength(double wl, double gamma = 1.0)
+ {
+ return self_type(rgba::from_wavelength(wl, gamma));
+ }
+ };
+
+
+ //------------------------------------------------------rgba16_gamma_dir
+ template<class GammaLUT>
+ rgba16 rgba16_gamma_dir(rgba16 c, const GammaLUT& gamma)
+ {
+ return rgba16(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a);
+ }
+
+ //------------------------------------------------------rgba16_gamma_inv
+ template<class GammaLUT>
+ rgba16 rgba16_gamma_inv(rgba16 c, const GammaLUT& gamma)
+ {
+ return rgba16(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a);
+ }
+
+ //====================================================================rgba32
+ struct rgba32
+ {
+ typedef float value_type;
+ typedef double calc_type;
+ typedef double long_type;
+ typedef rgba32 self_type;
+
+ value_type r;
+ value_type g;
+ value_type b;
+ value_type a;
+
+ //--------------------------------------------------------------------
+ rgba32() {}
+
+ //--------------------------------------------------------------------
+ rgba32(value_type r_, value_type g_, value_type b_, value_type a_= 1) :
+ r(r_), g(g_), b(b_), a(a_) {}
+
+ //--------------------------------------------------------------------
+ rgba32(const self_type& c, float a_) :
+ r(c.r), g(c.g), b(c.b), a(a_) {}
+
+ //--------------------------------------------------------------------
+ rgba32(const rgba& c) :
+ r(value_type(c.r)), g(value_type(c.g)), b(value_type(c.b)), a(value_type(c.a)) {}
+
+ //--------------------------------------------------------------------
+ rgba32(const rgba8& c) :
+ r(value_type(c.r / 255.0)),
+ g(value_type(c.g / 255.0)),
+ b(value_type(c.b / 255.0)),
+ a(value_type(c.a / 255.0)) {}
+
+ //--------------------------------------------------------------------
+ rgba32(const srgba8& c) :
+ r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)),
+ g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)),
+ b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)),
+ a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {}
+
+ //--------------------------------------------------------------------
+ rgba32(const rgba16& c) :
+ r(value_type(c.r / 65535.0)),
+ g(value_type(c.g / 65535.0)),
+ b(value_type(c.b / 65535.0)),
+ a(value_type(c.a / 65535.0)) {}
+
+ //--------------------------------------------------------------------
+ operator rgba() const
+ {
+ return rgba(r, g, b, a);
+ }
+
+ //--------------------------------------------------------------------
+ operator rgba8() const
+ {
+ return rgba8(
+ uround(r * 255.0),
+ uround(g * 255.0),
+ uround(b * 255.0),
+ uround(a * 255.0));
+ }
+
+ //--------------------------------------------------------------------
+ operator srgba8() const
+ {
+ return srgba8(
+ sRGB_conv<value_type>::rgb_to_sRGB(r),
+ sRGB_conv<value_type>::rgb_to_sRGB(g),
+ sRGB_conv<value_type>::rgb_to_sRGB(b),
+ sRGB_conv<value_type>::alpha_to_sRGB(a));
+ }
+
+ //--------------------------------------------------------------------
+ operator rgba16() const
+ {
+ return rgba8(
+ uround(r * 65535.0),
+ uround(g * 65535.0),
+ uround(b * 65535.0),
+ uround(a * 65535.0));
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE double to_double(value_type a)
+ {
+ return a;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type from_double(double a)
+ {
+ return value_type(a);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type empty_value()
+ {
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type full_value()
+ {
+ return 1;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_transparent() const
+ {
+ return a <= 0;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE bool is_opaque() const
+ {
+ return a >= 1;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type invert(value_type x)
+ {
+ return 1 - x;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type multiply(value_type a, value_type b)
+ {
+ return value_type(a * b);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type demultiply(value_type a, value_type b)
+ {
+ return (b == 0) ? 0 : value_type(a / b);
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downscale(T a)
+ {
+ return a;
+ }
+
+ //--------------------------------------------------------------------
+ template<typename T>
+ static AGG_INLINE T downshift(T a, unsigned n)
+ {
+ return n > 0 ? a / (1 << n) : a;
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
+ {
+ return value_type(a * b / cover_mask);
+ }
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
+ {
+ return cover_type(uround(a * b));
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a, assuming q is premultiplied by a.
+ static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
+ {
+ return (1 - a) * p + q; // more accurate than "p + q - p * a"
+ }
+
+ //--------------------------------------------------------------------
+ // Interpolate p to q by a.
+ static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
+ {
+ // The form "p + a * (q - p)" avoids a multiplication, but may produce an
+ // inaccurate result. For example, "p + (q - p)" may not be exactly equal
+ // to q. Therefore, stick to the basic expression, which at least produces
+ // the correct result at either extreme.
+ return (1 - a) * p + a * q;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& clear()
+ {
+ r = g = b = a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ self_type& transparent()
+ {
+ a = 0;
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type& opacity(double a_)
+ {
+ if (a_ < 0) a = 0;
+ else if (a_ > 1) a = 1;
+ else a = value_type(a_);
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ double opacity() const
+ {
+ return a;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type& premultiply()
+ {
+ if (a < 1)
+ {
+ if (a <= 0)
+ {
+ r = g = b = 0;
+ }
+ else
+ {
+ r *= a;
+ g *= a;
+ b *= a;
+ }
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type& demultiply()
+ {
+ if (a < 1)
+ {
+ if (a <= 0)
+ {
+ r = g = b = 0;
+ }
+ else
+ {
+ r /= a;
+ g /= a;
+ b /= a;
+ }
+ }
+ return *this;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE self_type gradient(const self_type& c, double k) const
+ {
+ self_type ret;
+ ret.r = value_type(r + (c.r - r) * k);
+ ret.g = value_type(g + (c.g - g) * k);
+ ret.b = value_type(b + (c.b - b) * k);
+ ret.a = value_type(a + (c.a - a) * k);
+ return ret;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void add(const self_type& c, unsigned cover)
+ {
+ if (cover == cover_mask)
+ {
+ if (c.is_opaque())
+ {
+ *this = c;
+ return;
+ }
+ else
+ {
+ r += c.r;
+ g += c.g;
+ b += c.b;
+ a += c.a;
+ }
+ }
+ else
+ {
+ r += mult_cover(c.r, cover);
+ g += mult_cover(c.g, cover);
+ b += mult_cover(c.b, cover);
+ a += mult_cover(c.a, cover);
+ }
+ if (a > 1) a = 1;
+ if (r > a) r = a;
+ if (g > a) g = a;
+ if (b > a) b = a;
+ }
+
+ //--------------------------------------------------------------------
+ template<class GammaLUT>
+ AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma)
+ {
+ r = gamma.dir(r);
+ g = gamma.dir(g);
+ b = gamma.dir(b);
+ }
+
+ //--------------------------------------------------------------------
+ template<class GammaLUT>
+ AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma)
+ {
+ r = gamma.inv(r);
+ g = gamma.inv(g);
+ b = gamma.inv(b);
+ }
+
+ //--------------------------------------------------------------------
+ static self_type no_color() { return self_type(0,0,0,0); }
+
+ //--------------------------------------------------------------------
+ static self_type from_wavelength(double wl, double gamma = 1)
+ {
+ return self_type(rgba::from_wavelength(wl, gamma));
+ }
+ };
+}
+
+
+
+#endif
diff --git a/xs/src/agg/agg_config.h b/xs/src/agg/agg_config.h
new file mode 100644
index 000000000..fa1dae2ba
--- /dev/null
+++ b/xs/src/agg/agg_config.h
@@ -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
diff --git a/xs/src/agg/agg_conv_transform.h b/xs/src/agg/agg_conv_transform.h
new file mode 100644
index 000000000..0c88a245b
--- /dev/null
+++ b/xs/src/agg/agg_conv_transform.h
@@ -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
diff --git a/xs/src/agg/agg_gamma_functions.h b/xs/src/agg/agg_gamma_functions.h
new file mode 100644
index 000000000..5d720daa9
--- /dev/null
+++ b/xs/src/agg/agg_gamma_functions.h
@@ -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
+
+
+
diff --git a/xs/src/agg/agg_gamma_lut.h b/xs/src/agg/agg_gamma_lut.h
new file mode 100644
index 000000000..e30873632
--- /dev/null
+++ b/xs/src/agg/agg_gamma_lut.h
@@ -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
diff --git a/xs/src/agg/agg_math.h b/xs/src/agg/agg_math.h
new file mode 100644
index 000000000..2ec49cf3f
--- /dev/null
+++ b/xs/src/agg/agg_math.h
@@ -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
diff --git a/xs/src/agg/agg_path_storage.h b/xs/src/agg/agg_path_storage.h
new file mode 100644
index 000000000..f55c89957
--- /dev/null
+++ b/xs/src/agg/agg_path_storage.h
@@ -0,0 +1,1582 @@
+//----------------------------------------------------------------------------
+// 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_PATH_STORAGE_INCLUDED
+#define AGG_PATH_STORAGE_INCLUDED
+
+#include <string.h>
+#include <math.h>
+#include "agg_math.h"
+#include "agg_array.h"
+#include "agg_bezier_arc.h"
+
+namespace agg
+{
+
+
+ //----------------------------------------------------vertex_block_storage
+ template<class T, unsigned BlockShift=8, unsigned BlockPool=256>
+ class vertex_block_storage
+ {
+ public:
+ // Allocation parameters
+ enum block_scale_e
+ {
+ block_shift = BlockShift,
+ block_size = 1 << block_shift,
+ block_mask = block_size - 1,
+ block_pool = BlockPool
+ };
+
+ typedef T value_type;
+ typedef vertex_block_storage<T, BlockShift, BlockPool> self_type;
+
+ ~vertex_block_storage();
+ vertex_block_storage();
+ vertex_block_storage(const self_type& v);
+ const self_type& operator = (const self_type& ps);
+
+ void remove_all();
+ void free_all();
+
+ void add_vertex(double x, double y, unsigned cmd);
+ void modify_vertex(unsigned idx, double x, double y);
+ void modify_vertex(unsigned idx, double x, double y, unsigned cmd);
+ void modify_command(unsigned idx, unsigned cmd);
+ void swap_vertices(unsigned v1, unsigned v2);
+
+ unsigned last_command() const;
+ unsigned last_vertex(double* x, double* y) const;
+ unsigned prev_vertex(double* x, double* y) const;
+
+ double last_x() const;
+ double last_y() const;
+
+ unsigned total_vertices() const;
+ unsigned vertex(unsigned idx, double* x, double* y) const;
+ unsigned command(unsigned idx) const;
+
+ private:
+ void allocate_block(unsigned nb);
+ int8u* storage_ptrs(T** xy_ptr);
+
+ private:
+ unsigned m_total_vertices;
+ unsigned m_total_blocks;
+ unsigned m_max_blocks;
+ T** m_coord_blocks;
+ int8u** m_cmd_blocks;
+ };
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ void vertex_block_storage<T,S,P>::free_all()
+ {
+ if(m_total_blocks)
+ {
+ T** coord_blk = m_coord_blocks + m_total_blocks - 1;
+ while(m_total_blocks--)
+ {
+ pod_allocator<T>::deallocate(
+ *coord_blk,
+ block_size * 2 +
+ block_size / (sizeof(T) / sizeof(unsigned char)));
+ --coord_blk;
+ }
+ pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2);
+ m_total_blocks = 0;
+ m_max_blocks = 0;
+ m_coord_blocks = 0;
+ m_cmd_blocks = 0;
+ m_total_vertices = 0;
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ vertex_block_storage<T,S,P>::~vertex_block_storage()
+ {
+ free_all();
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ vertex_block_storage<T,S,P>::vertex_block_storage() :
+ m_total_vertices(0),
+ m_total_blocks(0),
+ m_max_blocks(0),
+ m_coord_blocks(0),
+ m_cmd_blocks(0)
+ {
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ vertex_block_storage<T,S,P>::vertex_block_storage(const vertex_block_storage<T,S,P>& v) :
+ m_total_vertices(0),
+ m_total_blocks(0),
+ m_max_blocks(0),
+ m_coord_blocks(0),
+ m_cmd_blocks(0)
+ {
+ *this = v;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ const vertex_block_storage<T,S,P>&
+ vertex_block_storage<T,S,P>::operator = (const vertex_block_storage<T,S,P>& v)
+ {
+ remove_all();
+ unsigned i;
+ for(i = 0; i < v.total_vertices(); i++)
+ {
+ double x, y;
+ unsigned cmd = v.vertex(i, &x, &y);
+ add_vertex(x, y, cmd);
+ }
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::remove_all()
+ {
+ m_total_vertices = 0;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::add_vertex(double x, double y,
+ unsigned cmd)
+ {
+ T* coord_ptr = 0;
+ *storage_ptrs(&coord_ptr) = (int8u)cmd;
+ coord_ptr[0] = T(x);
+ coord_ptr[1] = T(y);
+ m_total_vertices++;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx,
+ double x, double y)
+ {
+ T* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1);
+ pv[0] = T(x);
+ pv[1] = T(y);
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx,
+ double x, double y,
+ unsigned cmd)
+ {
+ unsigned block = idx >> block_shift;
+ unsigned offset = idx & block_mask;
+ T* pv = m_coord_blocks[block] + (offset << 1);
+ pv[0] = T(x);
+ pv[1] = T(y);
+ m_cmd_blocks[block][offset] = (int8u)cmd;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::modify_command(unsigned idx,
+ unsigned cmd)
+ {
+ m_cmd_blocks[idx >> block_shift][idx & block_mask] = (int8u)cmd;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::swap_vertices(unsigned v1, unsigned v2)
+ {
+ unsigned b1 = v1 >> block_shift;
+ unsigned b2 = v2 >> block_shift;
+ unsigned o1 = v1 & block_mask;
+ unsigned o2 = v2 & block_mask;
+ T* pv1 = m_coord_blocks[b1] + (o1 << 1);
+ T* pv2 = m_coord_blocks[b2] + (o2 << 1);
+ T val;
+ val = pv1[0]; pv1[0] = pv2[0]; pv2[0] = val;
+ val = pv1[1]; pv1[1] = pv2[1]; pv2[1] = val;
+ int8u cmd = m_cmd_blocks[b1][o1];
+ m_cmd_blocks[b1][o1] = m_cmd_blocks[b2][o2];
+ m_cmd_blocks[b2][o2] = cmd;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::last_command() const
+ {
+ if(m_total_vertices) return command(m_total_vertices - 1);
+ return path_cmd_stop;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::last_vertex(double* x, double* y) const
+ {
+ if(m_total_vertices) return vertex(m_total_vertices - 1, x, y);
+ return path_cmd_stop;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::prev_vertex(double* x, double* y) const
+ {
+ if(m_total_vertices > 1) return vertex(m_total_vertices - 2, x, y);
+ return path_cmd_stop;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline double vertex_block_storage<T,S,P>::last_x() const
+ {
+ if(m_total_vertices)
+ {
+ unsigned idx = m_total_vertices - 1;
+ return m_coord_blocks[idx >> block_shift][(idx & block_mask) << 1];
+ }
+ return 0.0;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline double vertex_block_storage<T,S,P>::last_y() const
+ {
+ if(m_total_vertices)
+ {
+ unsigned idx = m_total_vertices - 1;
+ return m_coord_blocks[idx >> block_shift][((idx & block_mask) << 1) + 1];
+ }
+ return 0.0;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::total_vertices() const
+ {
+ return m_total_vertices;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::vertex(unsigned idx,
+ double* x, double* y) const
+ {
+ unsigned nb = idx >> block_shift;
+ const T* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1);
+ *x = pv[0];
+ *y = pv[1];
+ return m_cmd_blocks[nb][idx & block_mask];
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::command(unsigned idx) const
+ {
+ return m_cmd_blocks[idx >> block_shift][idx & block_mask];
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ void vertex_block_storage<T,S,P>::allocate_block(unsigned nb)
+ {
+ if(nb >= m_max_blocks)
+ {
+ T** new_coords =
+ pod_allocator<T*>::allocate((m_max_blocks + block_pool) * 2);
+
+ unsigned char** new_cmds =
+ (unsigned char**)(new_coords + m_max_blocks + block_pool);
+
+ if(m_coord_blocks)
+ {
+ memcpy(new_coords,
+ m_coord_blocks,
+ m_max_blocks * sizeof(T*));
+
+ memcpy(new_cmds,
+ m_cmd_blocks,
+ m_max_blocks * sizeof(unsigned char*));
+
+ pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2);
+ }
+ m_coord_blocks = new_coords;
+ m_cmd_blocks = new_cmds;
+ m_max_blocks += block_pool;
+ }
+ m_coord_blocks[nb] =
+ pod_allocator<T>::allocate(block_size * 2 +
+ block_size / (sizeof(T) / sizeof(unsigned char)));
+
+ m_cmd_blocks[nb] =
+ (unsigned char*)(m_coord_blocks[nb] + block_size * 2);
+
+ m_total_blocks++;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ int8u* vertex_block_storage<T,S,P>::storage_ptrs(T** xy_ptr)
+ {
+ unsigned nb = m_total_vertices >> block_shift;
+ if(nb >= m_total_blocks)
+ {
+ allocate_block(nb);
+ }
+ *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1);
+ return m_cmd_blocks[nb] + (m_total_vertices & block_mask);
+ }
+
+
+
+
+ //-----------------------------------------------------poly_plain_adaptor
+ template<class T> class poly_plain_adaptor
+ {
+ public:
+ typedef T value_type;
+
+ poly_plain_adaptor() :
+ m_data(0),
+ m_ptr(0),
+ m_end(0),
+ m_closed(false),
+ m_stop(false)
+ {}
+
+ poly_plain_adaptor(const T* data, unsigned num_points, bool closed) :
+ m_data(data),
+ m_ptr(data),
+ m_end(data + num_points * 2),
+ m_closed(closed),
+ m_stop(false)
+ {}
+
+ void init(const T* data, unsigned num_points, bool closed)
+ {
+ m_data = data;
+ m_ptr = data;
+ m_end = data + num_points * 2;
+ m_closed = closed;
+ m_stop = false;
+ }
+
+ void rewind(unsigned)
+ {
+ m_ptr = m_data;
+ m_stop = false;
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_ptr < m_end)
+ {
+ bool first = m_ptr == m_data;
+ *x = *m_ptr++;
+ *y = *m_ptr++;
+ return first ? path_cmd_move_to : path_cmd_line_to;
+ }
+ *x = *y = 0.0;
+ if(m_closed && !m_stop)
+ {
+ m_stop = true;
+ return path_cmd_end_poly | path_flags_close;
+ }
+ return path_cmd_stop;
+ }
+
+ private:
+ const T* m_data;
+ const T* m_ptr;
+ const T* m_end;
+ bool m_closed;
+ bool m_stop;
+ };
+
+
+
+
+
+ //-------------------------------------------------poly_container_adaptor
+ template<class Container> class poly_container_adaptor
+ {
+ public:
+ typedef typename Container::value_type vertex_type;
+
+ poly_container_adaptor() :
+ m_container(0),
+ m_index(0),
+ m_closed(false),
+ m_stop(false)
+ {}
+
+ poly_container_adaptor(const Container& data, bool closed) :
+ m_container(&data),
+ m_index(0),
+ m_closed(closed),
+ m_stop(false)
+ {}
+
+ void init(const Container& data, bool closed)
+ {
+ m_container = &data;
+ m_index = 0;
+ m_closed = closed;
+ m_stop = false;
+ }
+
+ void rewind(unsigned)
+ {
+ m_index = 0;
+ m_stop = false;
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_index < m_container->size())
+ {
+ bool first = m_index == 0;
+ const vertex_type& v = (*m_container)[m_index++];
+ *x = v.x;
+ *y = v.y;
+ return first ? path_cmd_move_to : path_cmd_line_to;
+ }
+ *x = *y = 0.0;
+ if(m_closed && !m_stop)
+ {
+ m_stop = true;
+ return path_cmd_end_poly | path_flags_close;
+ }
+ return path_cmd_stop;
+ }
+
+ private:
+ const Container* m_container;
+ unsigned m_index;
+ bool m_closed;
+ bool m_stop;
+ };
+
+
+
+ //-----------------------------------------poly_container_reverse_adaptor
+ template<class Container> class poly_container_reverse_adaptor
+ {
+ public:
+ typedef typename Container::value_type vertex_type;
+
+ poly_container_reverse_adaptor() :
+ m_container(0),
+ m_index(-1),
+ m_closed(false),
+ m_stop(false)
+ {}
+
+ poly_container_reverse_adaptor(Container& data, bool closed) :
+ m_container(&data),
+ m_index(-1),
+ m_closed(closed),
+ m_stop(false)
+ {}
+
+ void init(Container& data, bool closed)
+ {
+ m_container = &data;
+ m_index = m_container->size() - 1;
+ m_closed = closed;
+ m_stop = false;
+ }
+
+ void rewind(unsigned)
+ {
+ m_index = m_container->size() - 1;
+ m_stop = false;
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_index >= 0)
+ {
+ bool first = m_index == int(m_container->size() - 1);
+ const vertex_type& v = (*m_container)[m_index--];
+ *x = v.x;
+ *y = v.y;
+ return first ? path_cmd_move_to : path_cmd_line_to;
+ }
+ *x = *y = 0.0;
+ if(m_closed && !m_stop)
+ {
+ m_stop = true;
+ return path_cmd_end_poly | path_flags_close;
+ }
+ return path_cmd_stop;
+ }
+
+ private:
+ Container* m_container;
+ int m_index;
+ bool m_closed;
+ bool m_stop;
+ };
+
+
+
+
+
+ //--------------------------------------------------------line_adaptor
+ class line_adaptor
+ {
+ public:
+ typedef double value_type;
+
+ line_adaptor() : m_line(m_coord, 2, false) {}
+ line_adaptor(double x1, double y1, double x2, double y2) :
+ m_line(m_coord, 2, false)
+ {
+ m_coord[0] = x1;
+ m_coord[1] = y1;
+ m_coord[2] = x2;
+ m_coord[3] = y2;
+ }
+
+ void init(double x1, double y1, double x2, double y2)
+ {
+ m_coord[0] = x1;
+ m_coord[1] = y1;
+ m_coord[2] = x2;
+ m_coord[3] = y2;
+ m_line.rewind(0);
+ }
+
+ void rewind(unsigned)
+ {
+ m_line.rewind(0);
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ return m_line.vertex(x, y);
+ }
+
+ private:
+ double m_coord[4];
+ poly_plain_adaptor<double> m_line;
+ };
+
+
+
+
+
+
+
+
+
+
+
+
+
+ //---------------------------------------------------------------path_base
+ // A container to store vertices with their flags.
+ // A path consists of a number of contours separated with "move_to"
+ // commands. The path storage can keep and maintain more than one
+ // path.
+ // To navigate to the beginning of a particular path, use rewind(path_id);
+ // Where path_id is what start_new_path() returns. So, when you call
+ // start_new_path() you need to store its return value somewhere else
+ // to navigate to the path afterwards.
+ //
+ // See also: vertex_source concept
+ //------------------------------------------------------------------------
+ template<class VertexContainer> class path_base
+ {
+ public:
+ typedef VertexContainer container_type;
+ typedef path_base<VertexContainer> self_type;
+
+ //--------------------------------------------------------------------
+ path_base() : m_vertices(), m_iterator(0) {}
+ void remove_all() { m_vertices.remove_all(); m_iterator = 0; }
+ void free_all() { m_vertices.free_all(); m_iterator = 0; }
+
+ // Make path functions
+ //--------------------------------------------------------------------
+ unsigned start_new_path();
+
+ void move_to(double x, double y);
+ void move_rel(double dx, double dy);
+
+ void line_to(double x, double y);
+ void line_rel(double dx, double dy);
+
+ void hline_to(double x);
+ void hline_rel(double dx);
+
+ void vline_to(double y);
+ void vline_rel(double dy);
+
+ void arc_to(double rx, double ry,
+ double angle,
+ bool large_arc_flag,
+ bool sweep_flag,
+ double x, double y);
+
+ void arc_rel(double rx, double ry,
+ double angle,
+ bool large_arc_flag,
+ bool sweep_flag,
+ double dx, double dy);
+
+ void curve3(double x_ctrl, double y_ctrl,
+ double x_to, double y_to);
+
+ void curve3_rel(double dx_ctrl, double dy_ctrl,
+ double dx_to, double dy_to);
+
+ void curve3(double x_to, double y_to);
+
+ void curve3_rel(double dx_to, double dy_to);
+
+ void curve4(double x_ctrl1, double y_ctrl1,
+ double x_ctrl2, double y_ctrl2,
+ double x_to, double y_to);
+
+ void curve4_rel(double dx_ctrl1, double dy_ctrl1,
+ double dx_ctrl2, double dy_ctrl2,
+ double dx_to, double dy_to);
+
+ void curve4(double x_ctrl2, double y_ctrl2,
+ double x_to, double y_to);
+
+ void curve4_rel(double x_ctrl2, double y_ctrl2,
+ double x_to, double y_to);
+
+
+ void end_poly(unsigned flags = path_flags_close);
+ void close_polygon(unsigned flags = path_flags_none);
+
+ // Accessors
+ //--------------------------------------------------------------------
+ const container_type& vertices() const { return m_vertices; }
+ container_type& vertices() { return m_vertices; }
+
+ unsigned total_vertices() const;
+
+ void rel_to_abs(double* x, double* y) const;
+
+ unsigned last_vertex(double* x, double* y) const;
+ unsigned prev_vertex(double* x, double* y) const;
+
+ double last_x() const;
+ double last_y() const;
+
+ unsigned vertex(unsigned idx, double* x, double* y) const;
+ unsigned command(unsigned idx) const;
+
+ void modify_vertex(unsigned idx, double x, double y);
+ void modify_vertex(unsigned idx, double x, double y, unsigned cmd);
+ void modify_command(unsigned idx, unsigned cmd);
+
+ // VertexSource interface
+ //--------------------------------------------------------------------
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ // Arrange the orientation of a polygon, all polygons in a path,
+ // or in all paths. After calling arrange_orientations() or
+ // arrange_orientations_all_paths(), all the polygons will have
+ // the same orientation, i.e. path_flags_cw or path_flags_ccw
+ //--------------------------------------------------------------------
+ unsigned arrange_polygon_orientation(unsigned start, path_flags_e orientation);
+ unsigned arrange_orientations(unsigned path_id, path_flags_e orientation);
+ void arrange_orientations_all_paths(path_flags_e orientation);
+ void invert_polygon(unsigned start);
+
+ // Flip all vertices horizontally or vertically,
+ // between x1 and x2, or between y1 and y2 respectively
+ //--------------------------------------------------------------------
+ void flip_x(double x1, double x2);
+ void flip_y(double y1, double y2);
+
+ // Concatenate path. The path is added as is.
+ //--------------------------------------------------------------------
+ template<class VertexSource>
+ void concat_path(VertexSource& vs, unsigned path_id = 0)
+ {
+ double x, y;
+ unsigned cmd;
+ vs.rewind(path_id);
+ while(!is_stop(cmd = vs.vertex(&x, &y)))
+ {
+ m_vertices.add_vertex(x, y, cmd);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ // Join path. The path is joined with the existing one, that is,
+ // it behaves as if the pen of a plotter was always down (drawing)
+ template<class VertexSource>
+ void join_path(VertexSource& vs, unsigned path_id = 0)
+ {
+ double x, y;
+ unsigned cmd;
+ vs.rewind(path_id);
+ cmd = vs.vertex(&x, &y);
+ if(!is_stop(cmd))
+ {
+ if(is_vertex(cmd))
+ {
+ double x0, y0;
+ unsigned cmd0 = last_vertex(&x0, &y0);
+ if(is_vertex(cmd0))
+ {
+ if(calc_distance(x, y, x0, y0) > vertex_dist_epsilon)
+ {
+ if(is_move_to(cmd)) cmd = path_cmd_line_to;
+ m_vertices.add_vertex(x, y, cmd);
+ }
+ }
+ else
+ {
+ if(is_stop(cmd0))
+ {
+ cmd = path_cmd_move_to;
+ }
+ else
+ {
+ if(is_move_to(cmd)) cmd = path_cmd_line_to;
+ }
+ m_vertices.add_vertex(x, y, cmd);
+ }
+ }
+ while(!is_stop(cmd = vs.vertex(&x, &y)))
+ {
+ m_vertices.add_vertex(x, y, is_move_to(cmd) ?
+ unsigned(path_cmd_line_to) :
+ cmd);
+ }
+ }
+ }
+
+ // Concatenate polygon/polyline.
+ //--------------------------------------------------------------------
+ template<class T> void concat_poly(const T* data,
+ unsigned num_points,
+ bool closed)
+ {
+ poly_plain_adaptor<T> poly(data, num_points, closed);
+ concat_path(poly);
+ }
+
+ // Join polygon/polyline continuously.
+ //--------------------------------------------------------------------
+ template<class T> void join_poly(const T* data,
+ unsigned num_points,
+ bool closed)
+ {
+ poly_plain_adaptor<T> poly(data, num_points, closed);
+ join_path(poly);
+ }
+
+ //--------------------------------------------------------------------
+ void translate(double dx, double dy, unsigned path_id=0);
+ void translate_all_paths(double dx, double dy);
+
+ //--------------------------------------------------------------------
+ template<class Trans>
+ void transform(const Trans& trans, unsigned path_id=0)
+ {
+ unsigned num_ver = m_vertices.total_vertices();
+ for(; path_id < num_ver; path_id++)
+ {
+ double x, y;
+ unsigned cmd = m_vertices.vertex(path_id, &x, &y);
+ if(is_stop(cmd)) break;
+ if(is_vertex(cmd))
+ {
+ trans.transform(&x, &y);
+ m_vertices.modify_vertex(path_id, x, y);
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ template<class Trans>
+ void transform_all_paths(const Trans& trans)
+ {
+ unsigned idx;
+ unsigned num_ver = m_vertices.total_vertices();
+ for(idx = 0; idx < num_ver; idx++)
+ {
+ double x, y;
+ if(is_vertex(m_vertices.vertex(idx, &x, &y)))
+ {
+ trans.transform(&x, &y);
+ m_vertices.modify_vertex(idx, x, y);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ // If the end points of a path are very, very close then make them
+ // exactly equal so that the stroke converter is not confused.
+ //--------------------------------------------------------------------
+ unsigned align_path(unsigned idx = 0)
+ {
+ if (idx >= total_vertices() || !is_move_to(command(idx)))
+ {
+ return total_vertices();
+ }
+
+ double start_x, start_y;
+ for (; idx < total_vertices() && is_move_to(command(idx)); ++idx)
+ {
+ vertex(idx, &start_x, &start_y);
+ }
+ while (idx < total_vertices() && is_drawing(command(idx)))
+ ++idx;
+
+ double x, y;
+ if (is_drawing(vertex(idx - 1, &x, &y)) &&
+ is_equal_eps(x, start_x, 1e-8) &&
+ is_equal_eps(y, start_y, 1e-8))
+ {
+ modify_vertex(idx - 1, start_x, start_y);
+ }
+
+ while (idx < total_vertices() && !is_move_to(command(idx)))
+ ++idx;
+ return idx;
+ }
+
+ void align_all_paths()
+ {
+ for (unsigned i = 0; i < total_vertices(); i = align_path(i));
+ }
+
+
+ private:
+ unsigned perceive_polygon_orientation(unsigned start, unsigned end);
+ void invert_polygon(unsigned start, unsigned end);
+
+ VertexContainer m_vertices;
+ unsigned m_iterator;
+ };
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ unsigned path_base<VC>::start_new_path()
+ {
+ if(!is_stop(m_vertices.last_command()))
+ {
+ m_vertices.add_vertex(0.0, 0.0, path_cmd_stop);
+ }
+ return m_vertices.total_vertices();
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::rel_to_abs(double* x, double* y) const
+ {
+ if(m_vertices.total_vertices())
+ {
+ double x2;
+ double y2;
+ if(is_vertex(m_vertices.last_vertex(&x2, &y2)))
+ {
+ *x += x2;
+ *y += y2;
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::move_to(double x, double y)
+ {
+ m_vertices.add_vertex(x, y, path_cmd_move_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::move_rel(double dx, double dy)
+ {
+ rel_to_abs(&dx, &dy);
+ m_vertices.add_vertex(dx, dy, path_cmd_move_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::line_to(double x, double y)
+ {
+ m_vertices.add_vertex(x, y, path_cmd_line_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::line_rel(double dx, double dy)
+ {
+ rel_to_abs(&dx, &dy);
+ m_vertices.add_vertex(dx, dy, path_cmd_line_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::hline_to(double x)
+ {
+ m_vertices.add_vertex(x, last_y(), path_cmd_line_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::hline_rel(double dx)
+ {
+ double dy = 0;
+ rel_to_abs(&dx, &dy);
+ m_vertices.add_vertex(dx, dy, path_cmd_line_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::vline_to(double y)
+ {
+ m_vertices.add_vertex(last_x(), y, path_cmd_line_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::vline_rel(double dy)
+ {
+ double dx = 0;
+ rel_to_abs(&dx, &dy);
+ m_vertices.add_vertex(dx, dy, path_cmd_line_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::arc_to(double rx, double ry,
+ double angle,
+ bool large_arc_flag,
+ bool sweep_flag,
+ double x, double y)
+ {
+ if(m_vertices.total_vertices() && is_vertex(m_vertices.last_command()))
+ {
+ const double epsilon = 1e-30;
+ double x0 = 0.0;
+ double y0 = 0.0;
+ m_vertices.last_vertex(&x0, &y0);
+
+ rx = fabs(rx);
+ ry = fabs(ry);
+
+ // Ensure radii are valid
+ //-------------------------
+ if(rx < epsilon || ry < epsilon)
+ {
+ line_to(x, y);
+ return;
+ }
+
+ if(calc_distance(x0, y0, x, y) < epsilon)
+ {
+ // If the endpoints (x, y) and (x0, y0) are identical, then this
+ // is equivalent to omitting the elliptical arc segment entirely.
+ return;
+ }
+ bezier_arc_svg a(x0, y0, rx, ry, angle, large_arc_flag, sweep_flag, x, y);
+ if(a.radii_ok())
+ {
+ join_path(a);
+ }
+ else
+ {
+ line_to(x, y);
+ }
+ }
+ else
+ {
+ move_to(x, y);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::arc_rel(double rx, double ry,
+ double angle,
+ bool large_arc_flag,
+ bool sweep_flag,
+ double dx, double dy)
+ {
+ rel_to_abs(&dx, &dy);
+ arc_to(rx, ry, angle, large_arc_flag, sweep_flag, dx, dy);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve3(double x_ctrl, double y_ctrl,
+ double x_to, double y_to)
+ {
+ m_vertices.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3);
+ m_vertices.add_vertex(x_to, y_to, path_cmd_curve3);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve3_rel(double dx_ctrl, double dy_ctrl,
+ double dx_to, double dy_to)
+ {
+ rel_to_abs(&dx_ctrl, &dy_ctrl);
+ rel_to_abs(&dx_to, &dy_to);
+ m_vertices.add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3);
+ m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve3);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve3(double x_to, double y_to)
+ {
+ double x0;
+ double y0;
+ if(is_vertex(m_vertices.last_vertex(&x0, &y0)))
+ {
+ double x_ctrl;
+ double y_ctrl;
+ unsigned cmd = m_vertices.prev_vertex(&x_ctrl, &y_ctrl);
+ if(is_curve(cmd))
+ {
+ x_ctrl = x0 + x0 - x_ctrl;
+ y_ctrl = y0 + y0 - y_ctrl;
+ }
+ else
+ {
+ x_ctrl = x0;
+ y_ctrl = y0;
+ }
+ curve3(x_ctrl, y_ctrl, x_to, y_to);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve3_rel(double dx_to, double dy_to)
+ {
+ rel_to_abs(&dx_to, &dy_to);
+ curve3(dx_to, dy_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve4(double x_ctrl1, double y_ctrl1,
+ double x_ctrl2, double y_ctrl2,
+ double x_to, double y_to)
+ {
+ m_vertices.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4);
+ m_vertices.add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4);
+ m_vertices.add_vertex(x_to, y_to, path_cmd_curve4);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve4_rel(double dx_ctrl1, double dy_ctrl1,
+ double dx_ctrl2, double dy_ctrl2,
+ double dx_to, double dy_to)
+ {
+ rel_to_abs(&dx_ctrl1, &dy_ctrl1);
+ rel_to_abs(&dx_ctrl2, &dy_ctrl2);
+ rel_to_abs(&dx_to, &dy_to);
+ m_vertices.add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4);
+ m_vertices.add_vertex(dx_ctrl2, dy_ctrl2, path_cmd_curve4);
+ m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve4);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve4(double x_ctrl2, double y_ctrl2,
+ double x_to, double y_to)
+ {
+ double x0;
+ double y0;
+ if(is_vertex(last_vertex(&x0, &y0)))
+ {
+ double x_ctrl1;
+ double y_ctrl1;
+ unsigned cmd = prev_vertex(&x_ctrl1, &y_ctrl1);
+ if(is_curve(cmd))
+ {
+ x_ctrl1 = x0 + x0 - x_ctrl1;
+ y_ctrl1 = y0 + y0 - y_ctrl1;
+ }
+ else
+ {
+ x_ctrl1 = x0;
+ y_ctrl1 = y0;
+ }
+ curve4(x_ctrl1, y_ctrl1, x_ctrl2, y_ctrl2, x_to, y_to);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve4_rel(double dx_ctrl2, double dy_ctrl2,
+ double dx_to, double dy_to)
+ {
+ rel_to_abs(&dx_ctrl2, &dy_ctrl2);
+ rel_to_abs(&dx_to, &dy_to);
+ curve4(dx_ctrl2, dy_ctrl2, dx_to, dy_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::end_poly(unsigned flags)
+ {
+ if(is_vertex(m_vertices.last_command()))
+ {
+ m_vertices.add_vertex(0.0, 0.0, path_cmd_end_poly | flags);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::close_polygon(unsigned flags)
+ {
+ end_poly(path_flags_close | flags);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline unsigned path_base<VC>::total_vertices() const
+ {
+ return m_vertices.total_vertices();
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline unsigned path_base<VC>::last_vertex(double* x, double* y) const
+ {
+ return m_vertices.last_vertex(x, y);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline unsigned path_base<VC>::prev_vertex(double* x, double* y) const
+ {
+ return m_vertices.prev_vertex(x, y);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline double path_base<VC>::last_x() const
+ {
+ return m_vertices.last_x();
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline double path_base<VC>::last_y() const
+ {
+ return m_vertices.last_y();
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline unsigned path_base<VC>::vertex(unsigned idx, double* x, double* y) const
+ {
+ return m_vertices.vertex(idx, x, y);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline unsigned path_base<VC>::command(unsigned idx) const
+ {
+ return m_vertices.command(idx);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::modify_vertex(unsigned idx, double x, double y)
+ {
+ m_vertices.modify_vertex(idx, x, y);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::modify_vertex(unsigned idx, double x, double y, unsigned cmd)
+ {
+ m_vertices.modify_vertex(idx, x, y, cmd);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::modify_command(unsigned idx, unsigned cmd)
+ {
+ m_vertices.modify_command(idx, cmd);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::rewind(unsigned path_id)
+ {
+ m_iterator = path_id;
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline unsigned path_base<VC>::vertex(double* x, double* y)
+ {
+ if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop;
+ return m_vertices.vertex(m_iterator++, x, y);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ unsigned path_base<VC>::perceive_polygon_orientation(unsigned start,
+ unsigned end)
+ {
+ // Calculate signed area (double area to be exact)
+ //---------------------
+ unsigned np = end - start;
+ double area = 0.0;
+ unsigned i;
+ for(i = 0; i < np; i++)
+ {
+ double x1, y1, x2, y2;
+ m_vertices.vertex(start + i, &x1, &y1);
+ m_vertices.vertex(start + (i + 1) % np, &x2, &y2);
+ area += x1 * y2 - y1 * x2;
+ }
+ return (area < 0.0) ? path_flags_cw : path_flags_ccw;
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::invert_polygon(unsigned start, unsigned end)
+ {
+ unsigned i;
+ unsigned tmp_cmd = m_vertices.command(start);
+
+ --end; // Make "end" inclusive
+
+ // Shift all commands to one position
+ for(i = start; i < end; i++)
+ {
+ m_vertices.modify_command(i, m_vertices.command(i + 1));
+ }
+
+ // Assign starting command to the ending command
+ m_vertices.modify_command(end, tmp_cmd);
+
+ // Reverse the polygon
+ while(end > start)
+ {
+ m_vertices.swap_vertices(start++, end--);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::invert_polygon(unsigned start)
+ {
+ // Skip all non-vertices at the beginning
+ while(start < m_vertices.total_vertices() &&
+ !is_vertex(m_vertices.command(start))) ++start;
+
+ // Skip all insignificant move_to
+ while(start+1 < m_vertices.total_vertices() &&
+ is_move_to(m_vertices.command(start)) &&
+ is_move_to(m_vertices.command(start+1))) ++start;
+
+ // Find the last vertex
+ unsigned end = start + 1;
+ while(end < m_vertices.total_vertices() &&
+ !is_next_poly(m_vertices.command(end))) ++end;
+
+ invert_polygon(start, end);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ unsigned path_base<VC>::arrange_polygon_orientation(unsigned start,
+ path_flags_e orientation)
+ {
+ if(orientation == path_flags_none) return start;
+
+ // Skip all non-vertices at the beginning
+ while(start < m_vertices.total_vertices() &&
+ !is_vertex(m_vertices.command(start))) ++start;
+
+ // Skip all insignificant move_to
+ while(start+1 < m_vertices.total_vertices() &&
+ is_move_to(m_vertices.command(start)) &&
+ is_move_to(m_vertices.command(start+1))) ++start;
+
+ // Find the last vertex
+ unsigned end = start + 1;
+ while(end < m_vertices.total_vertices() &&
+ !is_next_poly(m_vertices.command(end))) ++end;
+
+ if(end - start > 2)
+ {
+ if(perceive_polygon_orientation(start, end) != unsigned(orientation))
+ {
+ // Invert polygon, set orientation flag, and skip all end_poly
+ invert_polygon(start, end);
+ unsigned cmd;
+ while(end < m_vertices.total_vertices() &&
+ is_end_poly(cmd = m_vertices.command(end)))
+ {
+ m_vertices.modify_command(end++, set_orientation(cmd, orientation));
+ }
+ }
+ }
+ return end;
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ unsigned path_base<VC>::arrange_orientations(unsigned start,
+ path_flags_e orientation)
+ {
+ if(orientation != path_flags_none)
+ {
+ while(start < m_vertices.total_vertices())
+ {
+ start = arrange_polygon_orientation(start, orientation);
+ if(is_stop(m_vertices.command(start)))
+ {
+ ++start;
+ break;
+ }
+ }
+ }
+ return start;
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::arrange_orientations_all_paths(path_flags_e orientation)
+ {
+ if(orientation != path_flags_none)
+ {
+ unsigned start = 0;
+ while(start < m_vertices.total_vertices())
+ {
+ start = arrange_orientations(start, orientation);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::flip_x(double x1, double x2)
+ {
+ unsigned i;
+ double x, y;
+ for(i = 0; i < m_vertices.total_vertices(); i++)
+ {
+ unsigned cmd = m_vertices.vertex(i, &x, &y);
+ if(is_vertex(cmd))
+ {
+ m_vertices.modify_vertex(i, x2 - x + x1, y);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::flip_y(double y1, double y2)
+ {
+ unsigned i;
+ double x, y;
+ for(i = 0; i < m_vertices.total_vertices(); i++)
+ {
+ unsigned cmd = m_vertices.vertex(i, &x, &y);
+ if(is_vertex(cmd))
+ {
+ m_vertices.modify_vertex(i, x, y2 - y + y1);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::translate(double dx, double dy, unsigned path_id)
+ {
+ unsigned num_ver = m_vertices.total_vertices();
+ for(; path_id < num_ver; path_id++)
+ {
+ double x, y;
+ unsigned cmd = m_vertices.vertex(path_id, &x, &y);
+ if(is_stop(cmd)) break;
+ if(is_vertex(cmd))
+ {
+ x += dx;
+ y += dy;
+ m_vertices.modify_vertex(path_id, x, y);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::translate_all_paths(double dx, double dy)
+ {
+ unsigned idx;
+ unsigned num_ver = m_vertices.total_vertices();
+ for(idx = 0; idx < num_ver; idx++)
+ {
+ double x, y;
+ if(is_vertex(m_vertices.vertex(idx, &x, &y)))
+ {
+ x += dx;
+ y += dy;
+ m_vertices.modify_vertex(idx, x, y);
+ }
+ }
+ }
+
+ //-----------------------------------------------------vertex_stl_storage
+ template<class Container> class vertex_stl_storage
+ {
+ public:
+ typedef typename Container::value_type vertex_type;
+ typedef typename vertex_type::value_type value_type;
+
+ void remove_all() { m_vertices.clear(); }
+ void free_all() { m_vertices.clear(); }
+
+ void add_vertex(double x, double y, unsigned cmd)
+ {
+ m_vertices.push_back(vertex_type(value_type(x),
+ value_type(y),
+ int8u(cmd)));
+ }
+
+ void modify_vertex(unsigned idx, double x, double y)
+ {
+ vertex_type& v = m_vertices[idx];
+ v.x = value_type(x);
+ v.y = value_type(y);
+ }
+
+ void modify_vertex(unsigned idx, double x, double y, unsigned cmd)
+ {
+ vertex_type& v = m_vertices[idx];
+ v.x = value_type(x);
+ v.y = value_type(y);
+ v.cmd = int8u(cmd);
+ }
+
+ void modify_command(unsigned idx, unsigned cmd)
+ {
+ m_vertices[idx].cmd = int8u(cmd);
+ }
+
+ void swap_vertices(unsigned v1, unsigned v2)
+ {
+ vertex_type t = m_vertices[v1];
+ m_vertices[v1] = m_vertices[v2];
+ m_vertices[v2] = t;
+ }
+
+ unsigned last_command() const
+ {
+ return m_vertices.size() ?
+ m_vertices[m_vertices.size() - 1].cmd :
+ path_cmd_stop;
+ }
+
+ unsigned last_vertex(double* x, double* y) const
+ {
+ if(m_vertices.size() == 0)
+ {
+ *x = *y = 0.0;
+ return path_cmd_stop;
+ }
+ return vertex(m_vertices.size() - 1, x, y);
+ }
+
+ unsigned prev_vertex(double* x, double* y) const
+ {
+ if(m_vertices.size() < 2)
+ {
+ *x = *y = 0.0;
+ return path_cmd_stop;
+ }
+ return vertex(m_vertices.size() - 2, x, y);
+ }
+
+ double last_x() const
+ {
+ return m_vertices.size() ? m_vertices[m_vertices.size() - 1].x : 0.0;
+ }
+
+ double last_y() const
+ {
+ return m_vertices.size() ? m_vertices[m_vertices.size() - 1].y : 0.0;
+ }
+
+ unsigned total_vertices() const
+ {
+ return m_vertices.size();
+ }
+
+ unsigned vertex(unsigned idx, double* x, double* y) const
+ {
+ const vertex_type& v = m_vertices[idx];
+ *x = v.x;
+ *y = v.y;
+ return v.cmd;
+ }
+
+ unsigned command(unsigned idx) const
+ {
+ return m_vertices[idx].cmd;
+ }
+
+ private:
+ Container m_vertices;
+ };
+
+ //-----------------------------------------------------------path_storage
+ typedef path_base<vertex_block_storage<double> > path_storage;
+
+ // Example of declarations path_storage with pod_bvector as a container
+ //-----------------------------------------------------------------------
+ //typedef path_base<vertex_stl_storage<pod_bvector<vertex_d> > > path_storage;
+
+}
+
+
+
+// Example of declarations path_storage with std::vector as a container
+//---------------------------------------------------------------------------
+//#include <vector>
+//namespace agg
+//{
+// typedef path_base<vertex_stl_storage<std::vector<vertex_d> > > stl_path_storage;
+//}
+
+
+
+
+#endif
diff --git a/xs/src/agg/agg_pixfmt_base.h b/xs/src/agg/agg_pixfmt_base.h
new file mode 100644
index 000000000..57ae19cfe
--- /dev/null
+++ b/xs/src/agg/agg_pixfmt_base.h
@@ -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
diff --git a/xs/src/agg/agg_pixfmt_gray.h b/xs/src/agg/agg_pixfmt_gray.h
new file mode 100644
index 000000000..d03dc8650
--- /dev/null
+++ b/xs/src/agg/agg_pixfmt_gray.h
@@ -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
+
diff --git a/xs/src/agg/agg_pixfmt_rgb.h b/xs/src/agg/agg_pixfmt_rgb.h
new file mode 100644
index 000000000..6fa8772ce
--- /dev/null
+++ b/xs/src/agg/agg_pixfmt_rgb.h
@@ -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
+
diff --git a/xs/src/agg/agg_rasterizer_cells_aa.h b/xs/src/agg/agg_rasterizer_cells_aa.h
new file mode 100644
index 000000000..1147148fa
--- /dev/null
+++ b/xs/src/agg/agg_rasterizer_cells_aa.h
@@ -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
diff --git a/xs/src/agg/agg_rasterizer_scanline_aa.h b/xs/src/agg/agg_rasterizer_scanline_aa.h
new file mode 100644
index 000000000..ffc2ddf94
--- /dev/null
+++ b/xs/src/agg/agg_rasterizer_scanline_aa.h
@@ -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
+
diff --git a/xs/src/agg/agg_rasterizer_scanline_aa_nogamma.h b/xs/src/agg/agg_rasterizer_scanline_aa_nogamma.h
new file mode 100644
index 000000000..9a809aa5a
--- /dev/null
+++ b/xs/src/agg/agg_rasterizer_scanline_aa_nogamma.h
@@ -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
+
diff --git a/xs/src/agg/agg_rasterizer_sl_clip.h b/xs/src/agg/agg_rasterizer_sl_clip.h
new file mode 100644
index 000000000..3a7f3a103
--- /dev/null
+++ b/xs/src/agg/agg_rasterizer_sl_clip.h
@@ -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
diff --git a/xs/src/agg/agg_renderer_base.h b/xs/src/agg/agg_renderer_base.h
new file mode 100644
index 000000000..527c62f78
--- /dev/null
+++ b/xs/src/agg/agg_renderer_base.h
@@ -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
diff --git a/xs/src/agg/agg_renderer_scanline.h b/xs/src/agg/agg_renderer_scanline.h
new file mode 100644
index 000000000..311e9f739
--- /dev/null
+++ b/xs/src/agg/agg_renderer_scanline.h
@@ -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
diff --git a/xs/src/agg/agg_rendering_buffer.h b/xs/src/agg/agg_rendering_buffer.h
new file mode 100644
index 000000000..0eff6ff27
--- /dev/null
+++ b/xs/src/agg/agg_rendering_buffer.h
@@ -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
diff --git a/xs/src/agg/agg_scanline_p.h b/xs/src/agg/agg_scanline_p.h
new file mode 100644
index 000000000..1d1cbe72f
--- /dev/null
+++ b/xs/src/agg/agg_scanline_p.h
@@ -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
+
diff --git a/xs/src/agg/agg_trans_affine.h b/xs/src/agg/agg_trans_affine.h
new file mode 100644
index 000000000..1a6116388
--- /dev/null
+++ b/xs/src/agg/agg_trans_affine.h
@@ -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
+
diff --git a/xs/src/agg/copying b/xs/src/agg/copying
new file mode 100644
index 000000000..b6028e519
--- /dev/null
+++ b/xs/src/agg/copying
@@ -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.
+
diff --git a/xs/src/avrdude/AUTHORS b/xs/src/avrdude/AUTHORS
new file mode 100644
index 000000000..6abbec066
--- /dev/null
+++ b/xs/src/avrdude/AUTHORS
@@ -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.
+
diff --git a/xs/src/avrdude/BUILD-FROM-SVN b/xs/src/avrdude/BUILD-FROM-SVN
new file mode 100644
index 000000000..3a218f2d1
--- /dev/null
+++ b/xs/src/avrdude/BUILD-FROM-SVN
@@ -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
diff --git a/xs/src/avrdude/CMakeLists.txt b/xs/src/avrdude/CMakeLists.txt
new file mode 100644
index 000000000..d88563368
--- /dev/null
+++ b/xs/src/avrdude/CMakeLists.txt
@@ -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()
diff --git a/xs/src/avrdude/COPYING b/xs/src/avrdude/COPYING
new file mode 100644
index 000000000..e69cf7e6c
--- /dev/null
+++ b/xs/src/avrdude/COPYING
@@ -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.
diff --git a/xs/src/avrdude/ChangeLog b/xs/src/avrdude/ChangeLog
new file mode 100644
index 000000000..975f52317
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog
@@ -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.)
+
+
diff --git a/xs/src/avrdude/ChangeLog-2001 b/xs/src/avrdude/ChangeLog-2001
new file mode 100644
index 000000000..048dcf1c2
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2001
@@ -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.
+
diff --git a/xs/src/avrdude/ChangeLog-2002 b/xs/src/avrdude/ChangeLog-2002
new file mode 100644
index 000000000..9bfa030a9
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2002
@@ -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).
+
diff --git a/xs/src/avrdude/ChangeLog-2003 b/xs/src/avrdude/ChangeLog-2003
new file mode 100644
index 000000000..1115bdfbc
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2003
@@ -0,0 +1,1095 @@
+2003-12-01 Eric B. Weddington <eric@ecentral.com>
+
+ * doc/avrdude.texi: Update devices and programmers supported.
+
+2003-12-01 Eric B. Weddington <eric@ecentral.com>
+
+ * doc/avrdude.texi: Add missing -D option to user manual.
+ [This fixes bug #6804]
+
+2003-11-30 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * avrpart.c,main.c: Moved list_parts() and locate_part()
+ from main.c to avrpart.c.
+ * avrpart.h: Added prototypes for list_parts() and
+ locate_part().
+
+2003-11-30 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * avrpart.c, avr.c: Moved elementary functions on types
+ OPCODE, AVRMEM and AVRPART from avr.c to new file avrpart.c.
+ * avr.h: Removed prototypes for moved functions.
+ * avrpart.h: Added prototypes for functions in avrpart.c.
+ * Makefile.am: Added new file avrpart.c.
+
+2003-11-28 Michael Mayer <michael-mayer@gmx.de>
+
+ * lexer.l: New programmer type "butterfly".
+ * config_gram.y: New token K_BUTTERFLY.
+ * avrdude.conf.in: Added programmer definition.
+ * butterfly.c, butterfly.h: Cloned from avr910.?, changed to work
+ with the Atmel Butterfly device.
+ * Makefile.am: Added butterfly.[ch] to avrdude_SOURCES.
+
+2003-11-26 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * main.c: Make the -U parser tolerate colons in filenames.
+ * avrdude.1, doc/avrdude.texi: Document the -U changes.
+
+2003-11-21 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * ppi.c: Major speed tuning. Since ioctl() is expensive read from
+ shadowregisters where possible.
+
+2003-11-19 Eric B. Weddington <eric@ecentral.com>
+
+ * NEWS: Update news from items in ChangeLog.
+
+2003-11-19 Theodore A. Roth <troth@openavr.org>
+[Contributed by Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>]
+
+ * avr.c (avr_write_byte_default): Improve polling algorithm to speed up
+ programming of byte oriented parallel programmers.
+
+2003-11-14 Brian S. Dean <bsd@bsdhome.com>
+[Contributed by Erik Christiansen <erik@dd.nec.com.au>]
+
+ * avrdude.conf.in:
+ Add ATmega64 part.
+
+2003-11-08 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in:
+ Add "fuse" and "lock" definitions for the AT90S8535. Actually,
+ this is stolen from the AT90S8515 since the datasheet says it's
+ the same there.
+
+2003-10-13 Bill Somerville <bill@classdesign.com>
+
+ * stk500.c (stk500_paged_write): Limit blocks written to no bigger
+ than memory device size.
+ (stk500_paged_write): Send whole block at once.
+ (stk500_paged_load): Limit blocks read to no bigger than memory
+ device size.
+ [This fixes bug #5713.]
+
+2003-10-13 Eric B. Weddington <eric@ecentral.com>
+
+ * avrdude.conf.in: Fix for unterminated character error.
+
+2003-10-13 Eric B. Weddington <eric@ecentral.com>
+
+ * avrdude.conf.in: Add ATmega8515 definition.
+ Contributed by: Matthias Weißer <matthias@matwei.de>
+ * NEWS: Add note about ATmega8515 definition.
+
+2003-09-24 Eric B. Weddington <eric@ecentral.com>
+
+ * doc/TODO: Updated TODO list.
+
+2003-09-22 Eric B. Weddington <eric@ecentral.com>
+
+ * windows/Makefile.am: Correct makefile so loaddrv does not link
+ to Cygwin DLL.
+
+2003-09-18 Eric B. Weddington <eric@ecentral.com>
+
+ * doc/avrdude.texi: Minor corrections. Change description of -P
+ to reference platform dependencies.
+
+2003-09-16 Eric B. Weddington <eric@ecentral.com>
+
+ * stk500.c: If writing flash, skip empty pages in paged write.
+
+2003-09-06 Theodore A. Roth <troth@openavr.org>
+
+ * NEWS: Add 'Current:' header.
+ * configure.ac (AC_INIT): Add cvs back to version since we're
+ back in dev cycle (post release).
+
+2003-09-06 Theodore A. Roth <troth@openavr.org>
+
+ * AVRDUDE 4.2.0 has been released (cvs release tag is "release_4_2_0").
+
+2003-09-06 Theodore A. Roth <troth@openavr.org>
+
+ * NEWS: Update for 4.2.0 release. Add note about read/write of fuses
+ support for avr910.
+ * configure.ac (AC_INIT): Set version to 4.2.0.
+
+2003-09-05 Theodore A. Roth <troth@openavr.org>
+[Contributed by Jan-Hinnerk Reichert <jan-hinnerk_reichert@hamburg.de>]
+
+ * avr.c (avr_read_byte): If pgm->read_byte method fails, retry with
+ avr_read_byte_default.
+ * avr.c (avr_write_byte): If pgm->write_byte method fails, retry with
+ avr_write_byte_default.
+ * avr910.c (avr910_cmd): Implement using universal command.
+
+2003-09-04 Theodore A. Roth <troth@openavr.org>
+
+ * Makefile.am: Change AM_CPPFLAGS to avrdude_CPPFLAGS.
+ Define avrdude_CFLAGS.
+ * configure.ac: Set ENABLE_WARNINGS to "-Wall" if using gcc.
+
+2003-09-02 Eric B. Weddington <eric@ecentral.com>
+
+ * doc/avrdude.texi: Add note about privileges needed to load
+ the giveio driver for Windows.
+
+2003-08-29 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.1:
+ * main.c:
+ Perform an auto erase before programming if the flash memory is
+ anywhere specified to be written by any of the -U requests.
+
+ To remain backward compatible with previous versions, disable this
+ feature if any of the old-style memory specification operations are
+ specified (-i, -o).
+
+ Implement the -D option to explicitly disable the auto erase default.
+
+ Deprecate the old-style memory specification options (-f, -i, -I, -m,
+ and -o) in favor of the new -U option which allows one to operate on
+ multiple memories on a single command line.
+
+2003-08-28 Eric B. Weddington <eric@ecentral.com>
+
+ * avr910.c:
+ * fileio.c:
+ * main.c:
+ * stk500.c:
+ More code cleanup to remove warnings.
+
+2003-08-27 Theodore A. Roth <troth@openavr.org>
+
+ * main.c (update_progress_no_tty): Properly terminate progress. Also
+ fixes stk500 problem where number of bytes written is less than a page.
+
+2003-08-27 Theodore A. Roth <troth@openavr.org>
+
+ * avrdude.spec.in: Fix broken rpmbuild on RedHat-9.
+
+2003-08-25 Eric B. Weddington <eric@ecentral.com>
+
+ * fileio.c:
+ * main.c:
+ * ppiwin.c:
+ * ser_posix.c:
+ * stk500.c:
+ Minor code cleanup to remove warnings.
+
+2003-08-21 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.1:
+ * main.c:
+
+ Introduce a new option, -U, for performing memory operions.
+ Its argument is a 4 field string (fields seperated by colons)
+ which indicate what memory type to operate on, what operation
+ to perform is (read, write, or verify), the filename to read
+ from, write to, or verify against, and an optional file format
+ field. Multple -U options can be specified to operate on more
+ than one memory at a time with a single invocation. For
+ example, to update both the flash and the eeprom at the same
+ time one can now specify the following:
+
+ avrdude -p -e -U flash:w:main.hex:i -U eeprom:w:eeprom.hex:i
+
+2003-08-20 Brian S. Dean <bsd@bsdhome.com>
+
+ * ppiwin.c:
+ Timing related fixes for the Windows platform. Several folks have
+ reported that this patch fixes verify errors on the Windows platform
+ that are apparently timing related. Submitted by: Alex Shepherd
+ <ashepherd@wave.co.nz>, who indicates that this patch was based on
+ code from the UISP project.
+
+2003-08-01 Theodore A. Roth <troth@openavr.org>
+
+ * avrdude.1: Document the -q option.
+ * doc/avrdude.texi: Document the -q option.
+ Fix some typos left over from pasting in man output.
+
+2003-07-30 Brian S. Dean <bsd@bsdhome.com>
+
+ * main.c: Add elapsed time information to the new progress bar.
+
+2003-07-29 Theodore A. Roth <troth@openavr.org>
+
+ * avr.c:
+ * avr.h:
+ * avr910.c:
+ * main.c:
+ * stk500.c:
+ New progress reporting implementation.
+
+2003-07-24 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.1:
+ * doc/avrdude.texi:
+ * pgm.c:
+ * pgm.h:
+ * stk500.c:
+ * stk500_private.h:
+ * term.c: Add support for displaying and setting the various
+ operational parameters of the STK500 (Vtarget, Varef, clock).
+
+2003/07/22 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.conf.in:
+ Add 'picoweb' programming cable programmer.
+ Contributed by Rune Christensen <rune.christensen@adslhome.dk>.
+
+2003-06-18 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.conf.in:
+ Add the 'sp12' (Steve Bolt's) programmer.
+ Submitted by Larry Barello <larryba@barello.net>.
+
+2003-06-17 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.conf.in:
+ Properly identify the "ALF" programmer.
+
+ Extend ATmega8 calibration memory to support all 4 calibration bytes.
+ Savannah bug #3835. Submitted by Francisco T. A. Silva
+ <ftas@geodigitus.com.br>.
+
+ Add a few AVR910 programmer device codes. Savannah bug #3569 - sorry
+ I can't tell who submitted this to give proper credit.
+
+ Add support for the ATtiny12. Submitted by Pontifex <pontifex@isys.ca>
+
+2003-05-22 Brian S. Dean <bsd@bsdhome.com>
+
+ * avr.c:
+ * avr.h:
+ * fileio.c:
+ Optimize flash memory handling a little bit by ignoring 0xff data that
+ resides above the last non-0xff data value in the address space. Only
+ do this for flash memory since writing a 0xff to flash is a no-op.
+ This has the affect of creating smaller output files when dumping
+ memory contents from flash if the program in flash does not consume
+ the whole memory space. It also results in shorter programming times
+ when avrdude is asked to load a file into flash that has lots of 0xff
+ filled data past the last non-0xff data value.
+
+2003-05-13 Theodore A. Roth <troth@openavr.org>
+
+ * avr910.c (avr910_paged_write_flash): Add code to send the 'm'
+ command ("issue page write" cmd) for each page.
+
+2003-05-13 Theodore A. Roth <troth@openavr.org>
+
+ * avrdude.conf.in: Add pagel and bs2 entries for at90s1200 device.
+
+2003-05-13 Theodore A. Roth <troth@openavr.org>
+
+ * doc/TODO: Add note about avr910 device codes.
+
+2003-05-04 Theodore A. Roth <troth@openavr.org>
+
+ * configure.ac: Check for ncurses library (since it can be a
+ replacement for termcap).
+
+2003-05-02 Theodore A. Roth <troth@openavr.org>
+
+ * avrdude.conf.in: Add avr decodes for devices known in avr910
+ firmware version 2.3.
+ Add missing stk500 devocde for 2343.
+
+2003-04-23 Eric B. Weddington <eric@ecentral.com>
+
+ * fileio.c: Fix for bug #3293. Set correct open mode for raw format
+ for Windows.
+
+2003-04-19 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.1:
+ * fileio.c:
+ * fileio.h:
+ * main.c:
+ Implement and "immediate mode" for file input - this allows
+ one to specify byte values on the command line instead of via
+ a file. This can be good for specifying fuse bytes and
+ eliminates the need to create single-byte files or using
+ interactive terminal mode for these single-byte memories.
+ Requested by several folks on the mailing list.
+
+2003-04-18 Theodore A. Roth <troth@openavr.org>
+
+ * configure.ac: Add cvs suffix back to version.
+ * doc/TODO: Add a few items.
+
+2003-04-18 Theodore A. Roth <troth@openavr.org>
+
+ * AVRDUDE 4.1.0 has been released (cvs release tag is "release_4_1_0").
+
+2003-04-17 Theodore A. Roth <troth@openavr.org>
+
+ * configure.ac: Set version to 4.1.0.
+ * doc/avrdude.texi: Add note about avr910 programmer type.
+
+2003-04-17 Eric B. Weddington <eric@ecentral.com>
+
+ * NEWS: Replace TBD with new release version.
+
+2003-04-17 Eric B. Weddington <eric@ecentral.com>
+
+ * avrdude.conf.in: Change name of pony programmer to pony-stk200
+ to better describe the hardware (PonyProg is software that works
+ with various hardware).
+
+2003-04-16 Eric B. Weddington <eric@ecentral.com>
+
+ * avrdude.conf.in: Add support for ATtiny26
+ Submitted by Artur Lipowski <LAL@pro.onet.pl>
+ * NEWS: List new devices supported: ATtiny26
+
+2003-04-16 Eric B. Weddington <eric@ecentral.com>
+
+ * avrdude.conf.in: Add support for ATmega8535
+ Submitted by Alexander Peter <apeter@gmx.de>
+ * NEWS: List new devices supported: ATmega8535
+
+2003-04-09 Theodore A. Roth <troth@openavr.org>
+
+ * avr910.c: Reading a 16 bit word in paged load needs to swap the
+ bytes since the 'R' command returns MSB first and the internal buffer
+ stores LSB first.
+
+2003-04-07 Theodore A. Roth <troth@openavr.org>
+
+ * stk500.c: Don't print out read/write byte progress unless the verbose
+ option is given.
+
+2003-04-05 Theodore A. Roth <troth@openavr.org>
+
+ * avr910.c: Re-add the avr910 byte read/write methods which were
+ removed in my previous patch. Terminal mode read/writes are broken
+ without those methods. D'oh!
+
+2003-04-05 Theodore A. Roth <troth@openavr.org>
+
+ * avr910.c: Refactor to allow probing for auto addr increment. If auto
+ incr supported by programmer hw, don't send addr for every byte.
+
+2003-04-03 Eric B. Weddington <eric@ecentral.com>
+
+ * confwin.c: Fix bug that allows garbage for non-existent user
+ config filename on Windows.
+
+2003-03-29 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.conf.in:
+ Add the ATmega32 part. This part definition was contributed by:
+ Daniel Williamson <dannyw@maconmgt.co.uk> and
+ Ruwan Jayanetti <rjayanetti@sri.crossvue.com>
+ The resulting part definition used was actually somewhat of a merge of
+ the two submitted definitions.
+
+2003-03-24 Theodore A. Roth <troth@openavr.org>
+
+ * NEWS: Add note about avr910 support.
+
+2003-03-23 Theodore A. Roth <troth@openavr.org>
+
+ * avr.c (avr_write): Add call to pgm->write_setup() before the write
+ loop.
+ * avr910.c: Change all show_func_info() calls to no_show_func_info().
+ Add read/write to/from flash/eeprom memory functionality.
+ * pgm.c: Initialize pgm->write_setup.
+ * pgm.h: Add write_setup field to PROGRAMMER structure.
+ * ser_posix.c: Remove unneeded cast in verbosity code.
+
+2003-03-23 Theodore A. Roth <troth@openavr.org>
+
+ * ser_posix.c: Limit verbose output to 2 chars.
+
+2003-03-23 Theodore A. Roth <troth@openavr.org>
+
+ * ser_posix.c: Add verbose level > 3 output for send and recv functions.
+
+2003-03-23 Theodore A. Roth <troth@openavr.org>
+
+ * avr.c: Add avr_read_byte_default().
+ Have avr_read_byte() call pgm->read_byte() or avr_read_byte_default().
+ Add avr_write_byte_default().
+ Have avr_write_byte() call pgm->write_byte or avr_write_byte_default().
+ * pgm.c: Initialize pgm->write_byte and pgm->read_byte.
+ * pgm.h: Add write_byte and read_byte fields to struct programmer_t.
+
+2003-03-17 Theodore A. Roth <troth@openavr.org>
+
+ * avrdude.conf.in: Fix typo for devicecode deprecation comment.
+
+2003-03-17 Eric B. Weddington <eric@ecentral.com>
+
+ * avrdude.conf.in: Add Bascom SAMPLE programmer.
+ Submitted by Larry Barello <larryba@barrello.net>
+
+2003-03-16 Theodore A. Roth <troth@openavr.org>
+
+ * avr.c (avr_read): Use pgm->read_sig_bytes to read signature bytes if
+ available.
+ * avr910.c (avr910_vfy_cmd_sent): New function.
+ (avr910_chip_erase): Add support for chip erase.
+ (avr910_enter_prog_mode): New function.
+ (avr910_leave_prog_mode): New function.
+ (avr910_initialize): Add code to select device type and enter prog mode.
+ (avr910_close): Leave programming mode before closing serial port.
+ (avr910_read_sig_bytes): New function.
+ (avr910_initpgm): Add avr910_read_sig_bytes method to pgm initializer.
+ * avrdude.conf.in: Add note about deprecating devicecode.
+ Change all occurences of devicecode to stk500_devcode.
+ Add avr910_devcode to a few parts for testing.
+ * avrpart.h (struct avrpart): Change devicecode field to stk500_devcode.
+ (struct avrpart): Add avr910_devcode field.
+ * config_gram.y: Add K_STK500_DEVCODE and K_AVR910_DEVCODE tokens.
+ Generate an error if devicecode is found in the config file.
+ Handle parsing of avr910_devcode and stk500_devcode.
+ * lexer.l: Handle parsing of avr910_devcode and stk500_devcode.
+ * pgm.c: Initialize pgm->read_sig_bytes field.
+ * pgm.h: Add pgm->read_sig_bytes field.
+ * stk500.c: Use stk500_devcode instead of devicecode.
+
+2003-03-16 Theodore A. Roth <troth@openavr.org>
+
+ * avrdude.conf.in: Add avr910 and pavr programmers.
+ * config_gram.y: Add parsing of avr910 programmer.
+ * lexer.l: Add avr910 token.
+ * avr910.c: [this is still work in progress]
+ Add some debug output.
+ Add probe for programmer presense.
+ * main.c: Set port to default_serial if programmer type is avr910.
+
+2003-03-13 Theodore A. Roth <troth@openavr.org>
+
+ * ser_posix.c, ser_win32.c, serial.h:
+ Change baud from int to long to avoid a 16-bit int overflow.
+
+2003-03-12 Theodore A. Roth <troth@openavr.org>
+
+ * Makefile.am (avrdude_SOURCES): Add avr910.[ch], serial.h and
+ ser_posix.c files.
+ * avr910.c: New file (stubs for avr910 serial programmer).
+ * avr910.h: New file.
+ * ser_posix.c: New file.
+ * ser_win32.c: New file (just stubs for now).
+ * serial.h: New file.
+ * stk500.c: Move all the code for accessing the posix serial ports
+ into ser_posix. This will make a native win32 port easier and allows
+ the avr910 programmer to share the serial code.
+
+2003-03-12 Theodore A. Roth <troth@openavr.org>
+
+ * configure.ac (AC_INIT): Set version to 4.0.0cvs since we're done
+ with 4.0.0 release.
+
+2003-03-12
+
+ * AVRDUDE 4.0.0 has been released (cvs release tag is "release_4_0_0").
+
+2003-03-11 Theodore A. Roth <troth@openavr.org>
+
+ * Makefile.am: Add CLEANFILES to remove all files from a make.
+ * doc/Makefile.am: Ditto
+
+2003-03-11 Theodore A. Roth <troth@openavr.org>
+
+ * windows/Makefile.am: Fix uninstall-local rule (forget the $$file
+ part of the rm command).
+
+2003-03-11 Theodore A. Roth <troth@openavr.org>
+
+ * AUTHORS: Updated.
+ * CHANGELOG: Move contents to NEWS and remove file.
+ * ChangeLog: All of the changes for this year.
+ * ChangeLog-2001: All 2001 changes.
+ * ChangeLog-2002: All 2002 changes.
+ * Makefile.am (EXTRA_DIST): Remove CHANGELOG and and Change-200[12].
+ * NEWS: Moved contents of CHANGELOG file here.
+ * README: Add note pointing to savannah site.
+
+2003-03-11 Eric Weddington <eric@ecentral.com>
+
+ * doc/avrdude.texi:
+ Add Install and Documentation sections for Windows. Fix typo.
+
+2003-03-10 Theodore A. Roth <troth@openavr.org>
+
+ * Makefile.am: * Makefile.am (EXTRA_DIST): Add CHANGELOG.
+
+2003-03-10 Brian S. Dean <bsd@bsdhome.com>
+
+ * stk500.c: Disable debugging printf.
+
+ * configure.ac: Update version number in preparation for release.
+
+2003-03-10 Theodore A. Roth <troth@openavr.org>
+
+ * doc/avrdude.texi:
+ Add comment before each node to make them stand out better.
+ Use @option{} command for options instead of @code{}.
+ Merge FreeBSD and Linux platform dependent information.
+
+2003-03-10 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.1: Minor man page updates to better reflect reality.
+
+2003-03-10 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * bootstrap:
+ Export all the AUTO* variables. Hopefully, that way the generated
+ Makefile might get them correctly.
+
+ * bootstrap:
+ Export ${AUTOCONF} so automake will find it by whatever name it will be
+ called today.
+
+2003-03-06 Eric Weddington <eric@ecentral.com>
+
+ * doc/avrdude.texi:
+ Add notes about ability to list parts and list programmers in the
+ config file in -p and -c descriptions. Change info about where to
+ find Windows search method in -C description.
+
+ * main.c:
+ Change software version from hardcoded value to getting it from
+ the configuration.
+
+2003-03-06 Theodore A. Roth <troth@openavr.org>
+
+ * avrdude.spec.in: * avrdude.spec.in: Add docs sub-package.
+ Add %post and %preun scriptlets for handling info files.
+
+ * configure.ac, doc/Makefile.am:
+ * configure.ac: Add --enable-versioned-doc option and set DOC_INST_DIR.
+ * doc/Makefile.am: Add rules to install docs in DOC_INST_DIR.
+
+ * doc/Makefile.am:
+ Delete the lines which where commented out in previous commit.
+
+ * configure.ac, doc/Makefile.am:
+ * configure.ac: Remove hack to make work with automake-1.5.
+ * doc/Makefile.am: Remove extra rules that were needed to work with
+ automake-1.5.
+
+ * bootstrap:
+ * bootstrap: Force use of autoconf-2.57 and automake-1.7.x.
+
+2003-03-05 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add a definition for the popular Ponyprog dongle.
+
+ Submitted by: Daniel Williamson <dannyw@maconmgt.co.uk>
+
+2003-03-05 Brian S. Dean <bsd@bsdhome.com>
+
+ * main.c:
+ Check the programmer type against 'STK500' instead of the programmer
+ name when checking to see if we should default to the default_serial
+ port instead of the default_parallel port. This has us do the right
+ thing for the new 'avrisp' programmer.
+
+ * stk500.c:
+ Make the page size used for non-paged parts for the 'paged_write'
+ command be 128 bytes. This cuts 6 seconds off the programming time
+ for uploading a 6K file into an AT90S8515 vs the time loading the same
+ file using a 16 byte buffer, and the response feedback is still good.
+
+ * avr.c, stk500.c:
+ Fix stk500 page write (Program Page command). This is supported after
+ all on non-paged-memory parts. The problem was that the page size was
+ defaulting to 256 (maximum for the stk500), but the timeout for a
+ response from the stk500 before declaring it dead was only 0.5
+ seconds. But it takes much longer than 0.5 seconds to program 256
+ bytes, so we just weren't waiting long enough.
+
+ Fix this in two ways - increase the timeout to 5 seconds, and decrease
+ the page size to 16 bytes for non-paged parts. The programming time
+ for 16 bytes is short enough to provide the user with some feedback
+ that something is happening.
+
+ * avr.c, stk500.c:
+ Don't call the programmer's 'paged_write' routine unless the memory
+ itself is paged as it doesn't appear to work otherwise.
+
+ * avrdude.conf.in: Fix device codes for at90s8515 and at90s8535.
+
+ * avrdude.conf.in:
+ Add PAGEL and BS2 parms for parts I have datasheets for.
+
+ * config_gram.y:
+ Do that last commit slightly differently - this way results in no
+ shift-reduce conflicts.
+
+ * config_gram.y:
+ It shouldn't be an error to have an empty configuration file. This
+ causes some shift-reduce conflicts, but I think they are OK.
+
+ * main.c:
+ Print out a list of valid parts for '-p ?' and a list of valid
+ programmers for '-c ?'.
+
+2003-03-04 Eric Weddington <eric@ecentral.com>
+
+ * doc/avrdude.texi: Minor Windows doc corrections.
+
+ * doc/TODO: Add TODO file.
+
+ * avrdude.conf.in: Add AVR ISP programmer.
+
+2003-03-04 Brian S. Dean <bsd@bsdhome.com>
+
+ * stk500.c:
+ Don't try to set extended device programming parameters if they
+ haven't been specified in the config file for the part.
+
+ * stk500.c: Set extended device parameters for all firmware versions.
+
+ * stk500.c:
+ First attempt at supporting STK500 firmware past 1.10. Thanks to
+ Jason Kyle for the needed protocol information.
+
+2003-03-03 Theodore A. Roth <troth@openavr.org>
+
+ * doc/Makefile.am:
+ * doc/Makefile.am: Add ps and pdf rules since they aren't supplied by
+ automake versions prior to 1.7.
+
+ * doc/avrdude.texi:
+ * doc/avrdude.texi: Add node and menu information for the info system.
+
+ * Makefile.am, configure.ac, doc/Makefile.am, doc/avrdude.texi:
+ * Makefile.am (SUBDIRS): Add doc dir.
+ * configure.ac (AC_CONFIG_FILES): Add doc/Makefile.
+ * doc/Makefile.am: New file.
+ * doc/avrdude.texi: Use automatically generated version.texi.
+
+2003-03-02 Brian S. Dean <bsd@bsdhome.com>
+
+ * doc/avrdude.texi: Initial manual.
+
+2003-02-27 Theodore A. Roth <troth@openavr.org>
+
+ * term.c: * term.c: Use fgets() if readline() is not available.
+
+2003-02-27 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * bootstrap:
+ Oops, accidentally spammed the repository with my private version of
+ "bootstrap". Back out that change.
+
+ * bootstrap, lexer.l:
+ Ignore \r as white space, to make the Windows people happy.
+
+2003-02-27 Theodore A. Roth <troth@openavr.org>
+
+ * Makefile.am (EXTRA_DIST): Add avrdude.spec and make entries one
+ per line so future patches are obvious as to what changed.
+ * avrdude.spec.in: New file to support creation of binaries in rpm
+ format.
+ * configure.ac (AC_OUTPUT): Add avrdude.spec. Reorder so that
+ Makefile is the last entry.
+
+2003-02-26 Theodore A. Roth <troth@openavr.org>
+
+ * Makefile.am (SUBDIRS): Add windows dir.
+ * configure.ac: If $target is a windows system, build whats in
+ windows sub dir.
+ * windows/Makefile.am: New file.
+
+2003-02-25 Theodore A. Roth <troth@openavr.org>
+
+ * ChangeLog: Point reader to the CHANGELOG file.
+ * Makefile.am (EXTRA_DIST): Rename avrdude.conf.sample to
+ avrdude.conf.in.
+ Remove avrdude.conf and distclean-local rules.
+ Add install-exec-local and backup-avrdude-conf rules.
+ * avrdude.conf.in:
+ Set default_parallel to "@DEFAULT_PAR_PORT@" for autoconf expansion.
+ Set default_serial to "@DEFAULT_SER_PORT@" for autoconf expansion.
+ * configure.ac: Add call to AC_CANONICAL_{BUILD,HOST,TARGET} macros.
+ Set DEFAULT_PAR_PORT and DEFAULT_SER_PORT based on $host.
+ Add copyright header.
+ Define avrdude_version so AC_INIT and AM_INIT_AUTOMAKE are sure
+ to get the same version.
+
+ * avrdude.conf.in, avrdude.conf.sample:
+ Renamed avrdude.conf.sample to avrdude.conf.in.
+
+2003-02-25 Eric Weddington <eric@ecentral.com>
+
+ * ppiwin.c: CRs again.
+
+ * confwin.c, confwin.h: Get rid of CRs.
+
+ * main.c, Makefile.am: Get rid of CRs again.
+
+2003-02-24 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.1: Atmel has rearranged their web site, so now the AVR
+ docs have been moved to a more logically sounding URL.
+
+2003-02-24 Eric Weddington <eric@ecentral.com>
+
+ * Makefile.am, main.c: Integrate Windows search of config files.
+
+ * confwin.c, confwin.h: config file search on Windows.
+
+ * ppiwin.c: Change port value from lpt1alt to lpt3. Other
+ formatting changes.
+
+ * windows/giveio.c:
+ Add giveio device driver source. Requires MS DDK to build.
+
+ * windows/giveio.sys: Add giveio device driver binary.
+
+ * giveio.sys, install_giveio.bat, remove_giveio.bat, status_giveio.bat:
+ Move Windows specific files.
+
+ * windows/loaddrv.c, windows/loaddrv.h, windows/remove_giveio.bat:
+ * windows/status_giveio.bat, windows/install_giveio.bat:
+ Add Windows specific files.
+
+ * main.c: Usage back to stderr.
+
+2003-02-22 Brian S. Dean <bsd@bsdhome.com>
+
+ * CHANGELOG: Add note about .avrduderc.
+
+ * avr.c, avrdude.conf.sample, avrpart.h, config_gram.y, main.c,
+ * par.c, pgm.c, pgm.h:
+ Add the ability to read a per-user config file located at
+ $HOME/.avrduderc. Entries from .avrduderc take precedence over those
+ from the system wide config file in ${PREFIX}/etc/avrdude.conf.
+
+ Track and display the config file name and line number when we print
+ out the available parts and programmers. This is useful in case
+ someone has overridden a definition in their .avrduderc file and is
+ wondering why the definition in the system wide config file is not
+ being used.
+
+ Remove the default programmer 'stk500' from the distributed config
+ file.
+
+ * CHANGELOG: Spelling.
+
+2003-02-21 Brian S. Dean <bsd@bsdhome.com>
+
+ * CHANGELOG:
+ Put some stuff in the CHANGELOG for this upcoming new version before I
+ forget.
+
+ * main.c:
+ Update comment due to removal of the default parallel port pin config.
+
+ * config.c, config.h, config_gram.y, lexer.l, main.c:
+ * avrdude.conf.sample:
+ Introduce 'default_programmer' to the config file instead of requiring
+ one of the programmers to be tagged "default" within its definition.
+
+ Also, axe the notion of a compiled-in default programmer. It is
+ kind've pointless now that nearly all configuration comes from the
+ config file, thus, avrdude is not very useful without the config file,
+ and thus, having a programmer compiled-in offers little or no benefit.
+
+2003-02-21 Eric Weddington <eric@ecentral.com>
+
+ * main.c: Change usage text to be verbose.
+
+ * giveio.sys: Add Windows parallel port device driver (binary).
+
+ * install_giveio.bat, remove_giveio.bat, status_giveio.bat:
+ Windows batch files to work with giveio.sys.
+
+2003-02-21 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.conf.sample, config.c, config.h, config_gram.y, lexer.l:
+ * main.c:
+ Add port name defaults to the config file instead of hard-coding.
+ This adds 'default_parallel' and 'default_serial' keywords to the
+ grammar, which take quoted string arguments.
+
+ * avrdude.conf.sample:
+ Document the recent additions to the config file.
+
+ * stk500.c, avr.c, avrpart.h, config_gram.y, lexer.l, par.c:
+ Add the ability to specify which pin to pulse when retrying entry into
+ programming mode. Use 'retry_pulse' in the per-part specification
+ that can currently take values of 'reset' or 'sck', the default being
+ 'sck' which preserves the previous behaviour. Some newer parts
+ indicate that /RESET should be pulsed, while older parts say to pulse
+ SCK.
+
+2003-02-20 Eric Weddington <eric@ecentral.com>
+
+ * main.c, par.c:
+ Make verbose global. Make debug code in par_cmd() based on verbose=2.
+
+2003-02-20 Brian S. Dean <bsd@bsdhome.com>
+
+ * stk500.c: Fix pseudo/full parallel mode selection logic.
+
+ * avrdude.conf.sample:
+ Woops, didn't really mean to commit those changes that slipped in with
+ the last commit. Those were just there for testing.
+
+ * avr.c, avrdude.conf.sample, avrpart.h, config_gram.y, lexer.l:
+ * stk500.c:
+ Add 'serial' and 'parallel' keywords to the grammar so that one can
+ say whether parts support these programming modes or not. Possible
+ values for 'serial' are 'yes' or 'no'. Possible values for 'parallel'
+ are 'yes', 'no', or 'pseudo'. Add a bit mask of flags to the AVRPART
+ structure to capture these settings. Use these within
+ stk500_initialize() to set the device parameters correctly.
+
+ Defaults for 'serial' and 'parallel' are 'yes' unless specified
+ otherwise.
+
+2003-02-20 Eric Weddington <eric@ecentral.com>
+
+ * Makefile.am, ppiwin.c: Get rid of CRs.
+
+ * Makefile.am: Add ppiwin.c to avrdude_SOURCES.
+
+ * ppiwin.c: Added ppiwin.c: Windows parallel port driver.
+
+ * stk500.c:
+ Add error message for fail to enter programming mode. Fix typos.
+
+2003-02-20 Brian S. Dean <bsd@bsdhome.com>
+
+ * avr.c, avrdude.conf.sample, avrpart.h, config_gram.y, lexer.l:
+ Add a few parameters needed for parallel programming: assignment of
+ PAGEL and BS2 signals and the disposition of the reset pin
+ ('dedicated' or 'io').
+
+2003-02-20 Theodore A. Roth <troth@openavr.org>
+
+ * avrdude.1: Fix spacing for m169 entry. (tabs not spaces ;-)
+
+2003-02-20 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.1, fileio.c, main.c: Add Motorola S-record support.
+
+ Submitted by: "Alexey V.Levdikov" <tsar@kemford.com>
+
+2003-02-19 Theodore A. Roth <troth@openavr.org>
+
+ * avrdude.1: Add m169 to list of supported targets.
+
+2003-02-19 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.sample, avrdude.1:
+ My colleague contributed a part definition for the AT90S2343.
+
+ Submitted by: Mirko Kaffka <mirko@mkaffka.de>
+
+2003-02-18 Theodore A. Roth <troth@openavr.org>
+
+ * avrdude.conf.sample:
+ Add support for mega169. (tested with stk500 with 1.7 firmware)
+
+ * avrdude.conf.sample:
+ Add commments to separate parts (makes it easier for the eye to parse).
+
+2003-02-15 Theodore A. Roth <troth@openavr.org>
+
+ * Makefile.am: Add $srcdir to sample config filename so that
+ building in a separate dir works.
+
+2003-02-15 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * Makefile.am:
+ Only GNU make sets $< in non-inference rules, so rather explicitly
+ spell the source file(s) to remain compatible.
+
+2003-02-14 Theodore A. Roth <troth@openavr.org>
+
+ * Makefile.am: Add distclean rule and EXTRA_DIST list to get 'make
+ distcheck' to succeed.
+
+ These changes add basic support for a autoconf/automake based
+ build system.
+
+ * .cvsignore: Ignore autoconf files.
+ * AUTHORS: New file.
+ * ChangeLog: New file.
+ * Makefile: Removed file.
+ * Makefile.am: New file.
+ * NEWS: New file.
+ * README: New file.
+ * bootstrap: New file.
+ * configure.ac: New file.
+ * avr.c: Include ac_cfg.h (generated by autoconf).
+ * config.c: Include ac_cfg.h.
+ Include config_gram.h instead of y.tab.h.
+ * config.h: If HAS_YYSTYPE is not defined, define YYSTYPE.
+ * config_gram.y: Include ac_cfg.h.
+ * fileio.c: Include ac_cfg.h.
+ * lexer.l: Include config_gram.h instead of y.tab.h.
+ * lists.c: Include ac_cfg.h.
+ * main.c: Include ac_cfg.h.
+ * par.c: Include ac_cfg.h.
+ * pgm.c: Include ac_cfg.h.
+ * ppi.c: Include ac_cfg.h.
+ * stk500.c: Include ac_cfg.h.
+ * term.c: Include ac_cfg.h.
+
+2003-02-14 Brian S. Dean <bsd@bsdhome.com>
+
+ * stk500.c: Fix typos. Fix error messages.
+
+2003-02-13 Brian S. Dean <bsd@bsdhome.com>
+
+ * Makefile, avrdude.conf.sample, config_gram.y, lexer.l, main.c:
+ * par.c, par.h, ppi.c, ppi.h, stk500.c:
+ Split higher level parallel port programmer code off from ppi.c into
+ its own file par.c, leaving low level parallel port accessor routines
+ in ppi.c to help with portability. Change the programmer type to
+ 'PAR' now instead of 'PPI' - 'PAR' represents the parallel port
+ programmer type.
+
+ Be more liberal with 'static' function declarations within the
+ programmer implimentation files - these functions should never be
+ called directly - always use the programmer function references.
+
+ There are still a few places in 'main.c' that directly reference the
+ parallel programmer explicitly (par_getpinmask). These should be
+ fixed somehow.
+
+ Axe a few unused functions.
+
+2003-02-12 Theodore A. Roth <troth@openavr.org>
+
+ * .cvsignore: New file.
+
+ * stk500.c: Remove need for inttypes.h.
+
+ * lexer.l: Define YY_NO_UNPUT to quell a compiler warning.
+
+ * Makefile: Remove YACC assignment.
+ Add '-b y' options to YACC invocation.
+ Remove leading '-' from 'include .depend'.
+
+2003-02-12 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * config_gram.y:
+ Declare the internally used static functions on top, to get rid of the
+ compiler warnings.
+
+ Reported by: bison-generated parsers
+
+2003-02-11 Theodore A. Roth <troth@openavr.org>
+
+ * linux_ppdev.h: New file.
+ * ppi.c: Include system dependant parallel port interface file.
+ (ppi_open): Add call to ppi_claim().
+ (ppi_close): Add call to ppi_release().
+ * ppi.h: Define ppi_claim() and ppi_release() as NOPs if not previously
+ defined.
+ * stk500.c: Include inttypes header to quell compiler warning.
+
+2003-02-11 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * pgm.c, ppi.c, stk500.c: Fix some implicit declaration warnings.
+
+ * config_gram.y:
+ Move the C declarations to the top of the file. While [b]yacc doesn't
+ care, bison does, and this is normally the way it's meant to be
+ anyway.
+
+2003-02-11 Theodore A. Roth <troth@openavr.org>
+
+ * Makefile: Generate dependencies specific to the target system.
+ Explicitly use byacc.
+
+ * Makefile:
+ Remove reference to avr-gcc in depend rule (cut & paste error).
+
+2003-02-09 Brian S. Dean <bsd@bsdhome.com>
+
+ * main.c, pgm.c, pgm.h, pindefs.h, ppi.c, ppi.h, stk500.c:
+ * stk500.h, stk500_private.h, term.c, term.h, CHANGELOG, COPYING:
+ * Makefile, avr.c, avr.h, avrdude.1, avrdude.conf.sample:
+ * avrdude.pdf, avrpart.h, config.c, config.h, config_gram.y:
+ * fileio.c, fileio.h, lexer.l, lists.c, lists.h:
+ Test commit in new public repository. Before this time this repo
+ existed on a private system. Commits made by 'bsd' on the old system
+ were made by Brian Dean (bdean on the current system).
+
+2003-02-08 Brian S. Dean <bsd@bsdhome.com>
+
+ * Makefile, avr.c, avr.h, avrdude.1, avrpart.h, config.c,
+ * config.h, config_gram.y, fileio.c, fileio.h, lexer.l, lists.c:
+ * lists.h, main.c, pgm.c, pgm.h, pindefs.h, ppi.c, ppi.h:
+ * stk500.c, stk500.h, term.c, term.h:
+ The last part of that last commit message should read:
+
+ All others - modify program description.
+
+ * Makefile, avr.c, avr.h, avrdude.1, avrpart.h, config.c:
+ * config.h, config_gram.y, fileio.c, fileio.h, lexer.l, lists.c:
+ * lists.h, main.c, pgm.c, pgm.h, pindefs.h, ppi.c, ppi.h:
+ * stk500.c, stk500.h, term.c, term.h:
+ Makefile: include a target to automatically generate the dependency
+ list.
+
+ All others
+
+2003-02-06 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.1: Update license to GPL, permission by Joerg Wunsch.
+
+ * lexer.l: Add GPL.
+
+ * Makefile, config_gram.y: Add GPL to the Makefile and config_gram.y.
+
+ * Makefile, stk500.h:
+ Add stk500.h as a dependency for stk500.c. Remove carraige returns
+ from stk500.h - don't know how those got in there (pointed out by Ted
+ Roth).
+
+ * COPYING, avr.c, avr.h, avrpart.h, config.c, config.h, fileio.c:
+ * fileio.h, lists.c, lists.h, main.c, pgm.c, pgm.h, pindefs.h:
+ * ppi.c, ppi.h, stk500.c, stk500.h, term.c, term.h:
+ Re-license using the GNU GPL. Thanks to Ted Roth for the patch.
+
+ * avr.c, avr.h, config.c, config.h, config_gram.y, fileio.c:
+ * fileio.h, lexer.l, lists.c, lists.h, main.c, pgm.c, pgm.h:
+ * pindefs.h, ppi.c, ppi.h, stk500.c, stk500.h, term.c, term.h:
+ Get rid of the verbose printing of individual file CVS version ids.
+ This was intended to be used for identifying code in the field for
+ incoming bug reports, but I've never really found it all that useful.
+
+ * CHANGELOG, Makefile, Makefile.inc, avr.c, avrdude.1:
+ * avrdude.conf.sample, config_gram.y, lexer.l, main.c, stk500.c:
+ * term.c:
+ Change the name from AVRPROG to AVRDUDE.
+
+ 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!
diff --git a/xs/src/avrdude/ChangeLog-2004-2006 b/xs/src/avrdude/ChangeLog-2004-2006
new file mode 100644
index 000000000..20e5b2e8b
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2004-2006
@@ -0,0 +1,1644 @@
+2006-12-23 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * configure.ac (AC_INIT): Bump version to 5.3cvs (again).
+
+2006-12-22 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * configure.ac (AC_INIT): Bump version to 5.3.1.
+ * avrdude.conf.in (frank-stk200): Fix syntax error.
+ * ser_avrdoper.c: Make #ifdef for Win32/libhid
+ consistent with the initial check: use the HID driver
+ only iff found, otherwise use libusb.
+
+2006-12-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * configure.ac (AC_INIT): Bump version to 5.3cvs.
+
+2006-12-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Released AVRDUDE 5.3.
+
+2006-12-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * configure.ac (AC_INIT): Bump version to 5.3.
+
+2006-12-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by Vince VG:
+ * avrdude.conf.in (frank-stk200): New programmer added.
+ * doc/avrdude.texi: Mention frank-stk200.
+ Closes patch #5502: one other programmer
+
+2006-12-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by Christian Starkjohann:
+ * ser_avrdoper.c (usbOpenDevice): clear the error code when
+ returning successfully.
+
+2006-12-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by Christian Starkjohann:
+ patch #5507: Support for AVR-Doper USB programmer in HID mode
+ * configure.ac: Add hooks to detect the Win32 HID library,
+ as well as the existence of <ddk/hidsdi.h>.
+ * Makefile.am: Add new files.
+ * my_ddk_hidsdi.h: (New file.)
+ * ser_avrdoper.c: (New file.)
+ * serial.h: Add declaration for avrdoper_serdev.
+ * stk500v2.c: Add hook to divert to the AVR Doper code.
+ * avrdude.1: Document the AVR Doper support.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-12-15 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by ivanv at netman.ru
+ * jtagmkI.c: fix length for single-byte write operations.
+ Closes bug #18527 JTAG ICE: fuse bits have been writen incorrectly
+
+2006-12-11 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkII.c (jtagmkII_paged_write): Remove a debugging
+ usleep(1000000) that accidentally crept in in rev 1.19.
+
+2006-12-11 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * ser_posix.c (ser_open): Do fill in fdp->ifd before already
+ using it in ser_setspeed().
+
+2006-12-11 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkI.c (jtagmkI_close): revert baud rate to the initial
+ value in case we had changed it.
+ Fixes bug #18262: JTAGMKI/JTAG1 Reset Bug
+
+2006-12-11 Colin O'Flynn <coflynn@newae.com>
+
+ * safemode.c: Stop ignoring return values!
+ Closes bug #18339
+
+2006-12-11 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by Nick Lott:
+ * avrdude.conf.in: Fix signature for ATmega8515.
+ Closes bug #18348: ATMEGA8515 Signature is wrong in avrdude.conf
+
+2006-12-11 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avr.c: Fix a bug introduced in rev. 1.69, when implementing the
+ fallback from each programmer's paged_load() or paged_write()
+ method, respectively. The return value needs to be checked for
+ being greater or equal than 0 rather equal to 0 in order to
+ assume the operation has been successful.
+ Fixes bug #18489: avrdude is too slow (20 byte/s)
+
+2006-12-11 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avr910.c: Make the code compile warning-free:
+ - declare a dummy "struct timezone" for some Win32 systems (MinGW)
+ - fix a few printf() argument types
+ - get rid off the prevailing "all filedescriptors are of type int"
+ attitude
+ The last item required a large sweep across the code, in order to
+ replace all "int fd"s by "struct filedescriptor *fd"s, and pass
+ pointers (as we cannot pass a union directly). In return, the
+ code is now supposed to be fully 64-bit safe, rather than relying
+ on a 64-bit pointer being converted to a (32-bit) int and back
+ to a pointer as we did previously.
+ * butterfly.c: (Ditto.)
+ * jtagmkI.c: (Ditto.)
+ * jtagmkII.c: (Ditto.)
+ * lists.c: (Ditto.)
+ * par.c: (Ditto.)
+ * pgm.h: (Ditto.)
+ * ppi.c: (Ditto.)
+ * ppi.h: (Ditto.)
+ * ppiwin.c: (Ditto.)
+ * ser_posix.c: (Ditto.)
+ * ser_win32.c: (Ditto.)
+ * serbb_posix.c: (Ditto.)
+ * serbb_win32.c: (Ditto.)
+ * serial.h: (Ditto.)
+ * stk500.c: (Ditto.)
+ * stk500v2.c: (Ditto.)
+ * usb_libusb.c: (Ditto.)
+
+2006-11-23 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Implement EEPROM access through debugWire.
+ * jtagmkII.c: Extend the jtagmkII_read_byte() and
+ jtagmkII_write_byte() methods to handle EEPROM through
+ debugWire.
+ * avrpart.h: Implement the "flash instruction" parameter.
+ * config_gram.y: (Ditto.)
+ * lexer.l: (Ditto.)
+ * avrdude.conf.in: (Ditto.)
+ * avrdude.1: Document the EEPROM access through dW.
+ * doc/avrdude.texi: (Ditto.)
+ * tools/get-dw-params.xsl: Extend to extract the flash
+ instruction field.
+
+2006-11-23 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avr.c (avr_read, avr_write): if the paged access returns a
+ failure, fall back to byte access.
+
+2006-11-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkII.c: In jtagmkII_read_byte() and jtagmkII_write_byte(),
+ return an error upon failure now that the upper layers won't fall
+ back to the cmd() method anymore in that case.
+
+2006-11-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Implement debugWire programming support.
+ * avrpart.h: Implement debugWire support.
+ * config_gram.y: (Ditto.)
+ * jtagmkII.c: (Ditto.)
+ * jtagmkII.h: (Ditto.)
+ * lexer.l: (Ditto.)
+ * avrdude.conf.in: Add the new dW programmers.
+ * avrdude.1: Document the dW support.
+ * doc/avrdude.texi: (Ditto.)
+ * tools/get-dw-params.xsl: XSL stylesheet to extract the dW
+ parameters from the XML files.
+
+2006-11-20 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkI.c (jtagmkI_close): remove two unused variables.
+
+2006-11-20 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avr.c: Replace the fallback of avr_read_byte() and avr_write_byte() to
+ avr_read_byte_default() and avr_write_byte_default (resp.) by directly
+ calling the latter functions from within all programmers that don't
+ implement their own read_byte()/write_byte() methods. In turn, make the
+ read_byte() and write_byte() methods mandatory, and the cmd() method
+ (direct ISP command) optional instead (it's effectively mandatory for
+ any programmer using avr_read_byte_default()/avr_write_byte_default()
+ though). Remove all the pointless cmd() method stubs from those programmers
+ that don't need it.
+ Eliminate avr_read_byte() as it was now completely identical to
+ pgm->read_byte().
+ * avr.h: (Ditto.)
+ * bitbang.c: (Ditto.)
+ * butterfly.c: (Ditto.)
+ * jtagmkI.c: (Ditto.)
+ * jtagmkII.c: (Ditto.)
+ * par.c: (Ditto.)
+ * pgm.c: (Ditto.)
+ * safemode.c: (Ditto.)
+ * serbb_posix.c: (Ditto.)
+ * serbb_win32.c: (Ditto.)
+ * stk500.c: (Ditto.)
+ * stk500v2.c: (Ditto.)
+ * term.c: (Ditto.)
+ * usbasp.c: (Ditto.)
+
+2006-11-13 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkI.c: Avoid sending a CMD_RESET when leaving programming
+ mode, and CMD_GO when closing the connection. They cause the
+ activity LED on the ICE to continue to flicker, and are not
+ necessary anyway (the target starts to run by itself when leaving
+ programmng mode).
+ This is a partial fix for bug #18262: JTAGMKI/JTAG1 Reset Bug
+
+2006-11-12 Colin O'Flunn <coflynn@newae.com>
+
+ * avrdude.conf.in: Add read command for lockbits for Tiny2313.
+ Applies patch #5538
+
+2006-11-10 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add signatures for ATmega325/3250/645/6450.
+
+2006-11-08 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * configure.ac: Preserve ${LDFLAGS} inherited from environment
+ for Win32 environments.
+
+2006-11-07 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * configure.ac: Don't pretend --enable-doc were the default.
+
+2006-11-02 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Fix the width of the efuse memory area for a
+ number of AVRs.
+ Closes bug #18182: Wrong setting of eFuse configuration for
+ mega640/1280/1281/2560/2561 in avrdude 5.2
+
+2006-11-01 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Implement HVSP and PP modes for the AVR Dragon.
+ * config_gram.y: (Ditto.)
+ * jtagmkII.c: (Ditto.)
+ * jtagmkII_private.h: (Ditto.)
+ * lexer.l: (Ditto.)
+ * stk500v2.c: (Ditto.)
+ * stk500v2.h: (Ditto.)
+ * avrdude.1: Document the HVSP and PP support for the Dragon.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-10-27 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkI.c: Implement a flags field in struct serdev, and populate it
+ with a flag that indicates whether the underlying communication can
+ dynamically change its speed or not. This flag is set for true serial
+ communication but clear for USB communication. Don't try to adjust
+ the speed when talking over a communication channel that doesn't
+ support it. (The Dragon does not even support the respective parameter.)
+ * jtagmkII.c: (Ditto.)
+ * ser_posix.c: (Ditto.)
+ * ser_win32.c: (Ditto.)
+ * serial.h: (Ditto.)
+ * usb_libusb.c: (Ditto.)
+
+2006-10-26 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add support for the AVR Dragon (JTAG and ISP mode).
+ * config_gram.y: (Ditto.)
+ * jtagmkII.c: (Ditto.)
+ * jtagmkII.h: (Ditto.)
+ * lexer.l: (Ditto.)
+ * stk500v2.c: (Ditto.)
+ * stk500v2.h: (Ditto.)
+ * usbdevs.h: (Ditto.)
+ * avrdude.1: Document the AVR Dragon support.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-10-09 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Released AVRDUDE 5.2.
+
+2006-10-09 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * configure.ac: Bump version to 5.2
+
+2006-10-09 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by John Voltz: add AVR053 oscillator calibration.
+ * main.c: Add the -O option.
+ * pgm.c: Add the hook for the perform_osccal() method.
+ * pgm.h: (Ditto.)
+ * stk500v2.c: Implement perform_osccal().
+ * avrdude.1: Document the -O option.
+ * doc/avrdude.texi: (Ditto.)
+ Partially closes bug #17487: AVR RC oscillator calibration
+ routine not supported (feature request)
+
+2006-10-09 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by freckle@sf.net:
+ * stk500.c (stk500_paged_write): Send the command and the data
+ payload within a single write().
+ patch #5025: Improve stk500.c robustness
+
+ Submitted by Matthias Ringwald:
+ * stk500.c (stk500_open): do not flush the serial line after
+ getting in sync with the programmer.
+ patch #5293: stk500.c: no drain after sync (-> allow BTnode
+ Bootloader to work on cygwin)
+
+2006-09-29 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * pgm.h: Fix prototype for gettimeofday().
+ Closes bug #17884: another gettimeofday conflict under win32/cygwin
+
+2006-09-24 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by Thomas Fischl (initially):
+ * configure.ac: Add the CoreFoundation and IOKit framework
+ linker flags on MacOS X when configuring for USB support.
+ patch #4685: Libusb on MacOS X: detection and additional includes
+
+2006-09-20 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avr910.c: As there is a lot of ambiguity about the AVR910
+ device codes, allow the user to override the device code
+ verification with the -F option.
+ * main.c: Make ovsigck a global variable.
+
+2006-09-20 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Add the "stk500generic" programmer that auto-probes for STK500
+ either firmware version 1 or 2.
+ * Makefile.am (avrdude_SOURCES): add the new files
+ stk500generic.c and stk500generic.h.
+ * avrdude.conf.in: Add the stk500generic programmer type, and
+ change the "stk500" entry to point to this programmer.
+ * config_gram.y: Add the stk500generic keyword.
+ * lexer.l: (Ditto.)
+ * stk500.c: Change the stk500v1 code to not call exit()
+ prematurely when failing to open the programmer, but instead
+ return an error status.
+ * stk500generic.c: (New file.) Stub programmer implementation.
+ Probe for either stk500v1 or stk500v2, and adjust the current pgm
+ appropriately.
+ * stk500generic.h: (New file.) Declare the public interface(s)
+ of stk500generic.c.
+ * doc/avrdude.texi: Document the changed behaviour of stk500.
+
+2006-09-18 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Various fixes for ancient processors and their
+ capabilities. For the AT90S1200 and the AT90S8515, fuse bit
+ handling via ISP, and lock bit reading via ISP are not supported
+ at all. For the AT90S4414 (small brother of the AT90S8515), add
+ the ability to write the lock bits, and add a definition for the
+ fuse bits (usable for HV programming). For the AT90S2313, add the
+ "fuse" memory range, so it's available for HV programming.
+
+ Resolves bug #17796: avrdude will not program or verify lockbits
+ with Atmel STK protocol programmers
+
+2006-09-17 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by Thomas Fischl:
+ * usbasp.c: Check for USBasp with new as well as old VID/PID
+ pair, warn the user about upgrading the firmware in case an
+ old one has been found.
+ * usbasp.h: Add new VID/PID.
+
+2006-09-15 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Fix some mistakes for the ATtinyX61 family:
+ . high fuse has 8 bits
+ . there is an extended fuse (just one bit)
+ . the calibration area is only 1 byte
+
+2006-09-12 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * doc/avrdude.texi: Convert some of the tables to multitables
+ in order to beautify the result.
+
+2006-09-10 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Contributed by Thomas Fischl: add support for USBasp.
+ patch #4686: Add support for USBasp, a simple USB programmer
+ * usbasp.c: New file, implement the USBasp driver.
+ * usbasp.h: New file, interface declarations for USBasp.
+ * Makefile.am: Wire the new files into the build.
+ * avrdude.conf.in: Add the usbasp programmer entry.
+ * config_gram.y: Add the usbasp token.
+ * lexer.l: (Ditto.)
+ * avrdude.1: Document the USBasp programmer.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-09-08 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * main.c: Implement -U filename as a shorthand for
+ -U flash:w:filename:a.
+ * avrdude.1: Document this.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-09-08 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Implement numerical output formats for decimal, hexadecimal,
+ octal, and binary numbers.
+ Closes bug #16129: more output formats for fuse bits
+ (avrdude enhancement request)
+ * fileio.c: Implement fileio_num() and the itoa_simple()
+ helper function.
+ * fileio.h: Add new file formats to FILEFMT.
+ * main.c: Parse the new file formats.
+ * avrdude.1: Document all this.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-09-08 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * fileio.c: CPP statements start in column #1.
+ * stk500v2.c: Hide two debug/trace statements behind "verbose".
+
+2006-09-07 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.1: Describe how to disable the DWEN fuse.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-09-07 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkII.c: Translate numerical response codes to strings.
+
+2006-09-07 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.1: The avr109 programmer type no longer chokes on
+ a wrong avr910 device ID, so remove that description.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-09-07 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkII.c: When failing to start in ISP mode, try
+ debugWire instead. This requires the user to eventually
+ restart AVRDUE from scratch then.
+
+2006-09-06 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Add support for the JTAG ICE mkII in ISP mode.
+ * avrdude.conf.in (jtag2isp): New programmer entry.
+ * config_gram.y: Add K_JTAG_MKII_ISP.
+ * jtagmkII.c: Restructure and export some more functions.
+ * jtagmkII.h: Declare exported functions.
+ * jtagmkII_private.h: Prepare file to be included in stk500v2.c.
+ * lexer.l: Add jtagmkii_isp token.
+ * stk500v2.c: Implement glue to jtagmkII.c.
+ * stk500v2.h: Declare stk500v2_jtagmkII_initpgm().
+ * avrdude.1: Document the new programmer support.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-09-01 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * main.c: Add date and time of compilation to the verbose
+ greeting message.
+ Idea taken from patch #3172: Adds date and time of compile
+ to usage message
+
+2006-09-01 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Contributed by <avrdude@zevv.nl> as
+ patch #4372: Better synchronization for stk500
+ * stk500.c: Sync three times, and drop any noise inbetween.
+
+2006-09-01 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in (ATtiny261, ATtiny461, ATtiny861): new
+ entries.
+
+2006-09-01 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * butterfly.c: Remove the device support decision based on
+ the old AVR910 device codes; we've got signature verification
+ now so better rely on that.
+ * avr910.c: Revert the signature bytes returned, as it already
+ happened in butterfly.c. This closes bug #14998: Signature Bytes
+ read in wrong order (avr910 mode)
+
+2006-09-01 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by Wim Lewis.
+ * serbb_posix.c: Improve error handling.
+ patch #4923: Better error reporting for serial-bitbang programmers
+
+2006-08-31 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Introduce a "stk500v1" entry, so we
+ can switch the default "stk500" to "stk500v2" some day.
+
+2006-08-31 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ The major part of this change has been contributed by
+ <andyw@pobox.com>.
+ Implements patch #4635: Add support for terminal/console
+ servers for serial programmers
+ * ser_posix.c: Add net_open(), and divert to it for net:host:port.
+ * ser_win32.c: Recognize net:host:port, and bail out.
+ * avrdude.1: Document the net:host:port connection option.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-08-31 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Fix for bug #16627: Butterfly programmer does not reset after
+ programming
+ * butterfly.c: Wait for the device's response after sending
+ an "E" command.
+
+2006-08-31 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Tentative fix for bug #16156: Problem with Si-Prog
+ * serbb_posix.c: Disable reset before closing.
+ * serbb_win32.c: (Ditto.)
+
+2006-08-30 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Rewrite the serbb code so the pin numbering matches the
+ DB9 connector, and fix some related bugs in serbb_posix.c.
+ Closes bug #16265: dasa2 does not work under posix
+ * avrdude.conf.in: New serbb pin numbering; added "siprog"
+ as an alias for "ponyser".
+ * serbb_posix.c: New pin numbering, fix some confusion.
+ * serbb_win32.c: New pin numbering.
+ The generic and Posix-related parts of these changes have
+ been contributed by Hanns-Konrad Unger
+
+2006-08-30 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Contributed by the anonymous developer of patch #5096:
+ * avrdude.conf.in (blaster): Add an entry for the Altera
+ byteblaster.
+
+2006-08-30 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Rework the exit specs so they actually work again. It should be
+ possible to extend them for other programmers than PPI now (serbb,
+ stk500*).
+ * pgm.h: Keep the exit specs in an abstract form inside struct
+ programmer_t. (Should be moved out into some programmer-specific
+ structure.) Rename the getexitspecs() method into
+ parseexitspecs().
+ * main.c: Move the exit specs stuff out to the programmer
+ implementation.
+ * par.c: Implement the new exit spec handling. Everything is now
+ done using the generic abstraction layer.
+ Closes bug #16443: No disable Resetsignal at the end of
+ Programming Session
+ Obviates need for patch #5057: quick and dirty Hack to unset Reset
+ after Programming
+
+2006-08-29 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ This patch has been contributed by an anonymous developer
+ via the patch tracking system.
+ patch #5096: Allow VCC and BUFF to be any pin in parallel mode
+ * config_gram.y: Release the restriction to PPIDATA pins.
+ * par.c: Rework the code to introduce a function par_setmany()
+ that builds on top of par_setpin(), and use that function for the
+ PPI_AVR_VCC and PPI_AVR_BUFF pin collections. This also abstracts
+ the polarity of these signals appropriately.
+
+2006-08-28 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Contributed by Ned Konz:
+ * ser_posix.c: Open the serial port with O_NONBLOCK, and
+ save and restore the port state before exiting.
+ patch #5008: Patch for (5.1) ser_posix.c for O_NONBLOCK open
+ and restoring serial port state on close
+ Closes bug #12622: avrdude hangs on macosx/darwin with PL-2303
+ usb-to-serial and Butterfly
+
+2006-08-22 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * bitbang.c: Move the bitbang prerequisite checks out from
+ main() into their own bitbang_check_prerequisites().
+ * bitbang.h: (Ditto.)
+ * main.c: (Ditto.)
+ * par.c: (Ditto.)
+ * serbb_posix.c: (Ditto.)
+ * serbb_win32.c: (Ditto.)
+
+2006-08-22 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add page mode parameters for all "eeprom"
+ memory definitions that are organized in pages.
+ * avr.c (avr_write_byte_default): Consider using the loadpage
+ instructions only if the respective memory is marked "paged".
+ Closes bug #17199: EEPROM fails verification on ATmega645 with
+ pony-stk200 hardware
+ Closes bug #16849: EEPROM write fails for AT90USB1287 with
+ mode 0x41
+ Closes bug #15146: stk500v2_paged_write: loadpage instruction
+ not defined for part
+
+2006-08-22 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * doc/avrdude.info (-c): Change "avrispmk2" into "avrisp2" as that
+ is the programmer actually supported by avrdude.conf.in.
+ Closes bug #15677: documentation mentions wrong programmer-id
+ "avrispmk2"
+
+2006-08-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Fix various AVR910 device codes. Add the code
+ tables from both, AVR910 and AVR109. Change avr910_devcode of
+ the ATtiny2313 to 0x5e (ATtiny26).
+ Closes bug #16671: Tiny2313 avr910_devcode is bad
+ Closes bug #15826: avr910 device type for ATmega8 wrong
+
+2006-08-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add (rather conservative) write delay timing
+ values to the *fuse and lock memory spaces of all devices where
+ they have been missing. Add the lock memory space to the ATmega48
+ section.
+ Closes bug #14920: tiny2313 fuses and AVRDUDE 5.0
+ Closes bug #15751: atmega48: no lock bits defined
+
+2006-08-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Fix the size of the calibration memory space
+ for ATtiny13, ATmega64, ATmega16, ATmega32, ATmega8535, ATtiny25,
+ ATtiny45, ATtiny85.
+ Closes bug #17383: Wrong calibration section in avrdude.conf...
+
+2006-08-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in (ATmega324): Correct the pagesize from 256 to
+ 128.
+ This closes bug #16410: ATMega164/324/644 cannot be programmed
+
+2006-08-20 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * configure.ac: Check for gettimeofday().
+ * ppiwin.c (gettimeofday): Define gettimeofday() replacement
+ only if !defined(HAVE_GETTIMEOFDAY); use correct protype.
+
+2006-08-18 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * stk500v2: Minor cosmetic changes: STK500 firmware version
+ numbers are M.NN, so always display the minor number as two
+ digits. Examine the response to the sign-on command to see which
+ programmer hardware we are talking to, and then restrict the
+ STK500 topcard display to devices detected as STK500.
+
+2006-08-18 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * Makefile.am: Add a dist-hook, and make it remove lexer.c,
+ config_gram.c, and config_gram.h from the source distribution
+ archive. These files are supposed to be generated on the target
+ system.
+ Closes bug #15536: avrdude-5.1 compilation fails on Gentoo/amd64
+
+2006-08-17 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * stk500v2.c: unreverse the argument order for
+ CMD_CHIP_ERASE_HVSP; Atmel says AVR068 is right, and
+ stk500.exe is wrong.
+ * configure.ac (AC_CHECK_LIB[usb]): Fix the generation
+ of HAVE_LIBUSB in ac_cfg.h.
+
+2006-08-17 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by Neil Davey:
+ patch #4539: Ability to control the bit clock (usleep) delay
+ for ppi interface
+ * bitbang.c: Implement bitbang_delay() and its calibration.
+ * bitbang.h: Declare bitbang_delay().
+ * main.c: Add the ispdelay option (-i).
+ * pgm.h (struct programmer_t): Add the ispdelay parameter.
+ * par.c: Add calls to bitbang_delay() when requested.
+ * serbb_posix.c: (Ditto.)
+ * serbb_win32.c: (Ditto.)
+ * avrdude.1: Document the new -i option.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-08-14 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by <chris@awaretechs.com>:
+ * avrdude.conf.in (ATmega48, ATmega88, ATmega168): patch #5100:
+ mega88 EEPROM support (extended for ATmega48 and ATmega168 - jw).
+
+2006-08-14 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by <eolson@mit.edu>:
+ * stk500v2.c (stk500v2_open): patch #5273: Emit error message
+ if user requests usb and no libusb support
+
+2006-08-14 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add HVSP/PP mode parameters for all AVRs.
+
+2006-08-13 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * tools: New directory.
+ * tools/get-hv-params.xsl: New file, extract high-voltage
+ programming parameters from Atmel XML files, and produce
+ an avrdude.conf[.in] snippet.
+
+2006-08-11 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * configure.ac (AC_CHECK_LIB([usb]): implement a private LIBUSB
+ macro to add this library to, to prevent it from being
+ automatically linked to all binaries. This should fix the Win32
+ build of loaddrv.
+ * Makefile.am (avrdude_LDADD): add LIBUSB here.
+
+2006-08-10 Eric B. Weddington <eweddington@cso.atmel.com>
+
+ Contributed by Bob Paddock <graceindustries@gmail.com>
+ * avrdude.conf.in: Patch #4780. Provide support for mega325,
+ mega3250, mega645, mega6450.
+
+2006-08-10 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in (ATtiny11): fix the HVSP control stack,
+ add delay values required for flash and EEPROM.
+ * stk500v2.c: reverse the argument order for
+ CMD_CHIP_ERASE_HVSP; AVR068 and stk500.exe differ here.
+
+2006-08-09 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * stk500v2.c (stk500v2_program_enable): Fix a typo
+ (synchloops vs. synchcycles).
+
+2006-08-04 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add parallel programming definitions for
+ the ATmega8/48/88/168.
+
+2006-07-22 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add the ATtiny11, an HVSP-only device.
+
+2006-07-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Implement STK500 (v2) HVSP mode.
+ * stk500v2.c: Add new functions for HVSP support.
+ * stk500v2.h: Add prototype for the stk500hvsp programmer.
+ * avrpart.h: Add fields to struct avrpart for new features.
+ * config_gram.y: Extend the configuration syntax for new
+ features required for HVSP support.
+ * lexer.l: (Ditto.)
+ * avrdude.conf.in: Add HVSP support for ATtiny13 and
+ ATtiny45 as an example.
+ * avrdude.1: Document stk500hvsp.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-07-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrpart.c: Print the very verbose memory details only
+ in debug level > 4.
+
+2006-07-19 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * stk500v2.c: Add more parameters for PP mode. Fix the
+ non-paged write operations for old AVRs.
+ * lexer.l: Add more parameters for PP mode.
+ * config_gram.y: (Ditto.)
+ * avrpart.h: (Ditto.)
+ * avrdude.conf.in: Use the new PP mode parameters; add PP mode
+ definitions for AT90S8515.
+ * avrdude.1: Document the stk500pp support.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-07-19 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * stk500v2.c: Hide stk500v2_set_sck_period_mk2() behind an #if
+ defined(HAVE_LIBUSB) as it is only used there (for the AVRISP
+ mkII).
+
+2006-07-17 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * stk500v2.c: Fix all bugs in stk500pp. Eliminate pagebuf, and
+ use a stack-allocated buffer instead, as the pagesize can be at
+ most 256 for all current AVRs anyway.
+
+2006-07-17 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * main.c: Use mem->desc in place of upd->memtype in more places to
+ give the full name of the respective memory area, instead of
+ the (possibly abbreviated) name the user typed in the -U option.
+
+2006-07-16 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ First stab at an implementation of the STK500 parallel programming
+ feature (v2 firmware only), named "stk500pp". Still not yet
+ complete: EEPROM writes not working, documentation missing, only
+ ATmega16 parameters available in avrdude.conf.in, some parameters
+ not yet implemented.
+ * avrdude.conf.in: Add sample parameters for PP mode to ATmega16.
+ * avrpart.h: Add the parallel programming control parameters.
+ * avrpart.c: (Ditto.)
+ * config_gram.y: Add stk500pp configuration grammar.
+ * lexer.l: Add stk500pp token recognition.
+ * stk500v2.h: Add declaration for stk500pp_initpgm().
+ * stk500v2.c: Add stk500pp implementation.
+
+2006-07-11 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Fix the signatures for the
+ ATmega164/324 devices.
+
+2006-07-10 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Enter the signatures for the
+ ATmega164/324/644 devices.
+
+2006-05-25 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * stk500v2.c: Implement extended addressing needed
+ for the ATmega256x devices.
+ * avrdude.1: Document ATmega256x support.
+ * doc/avrdude.texi: Document ATmega256x support.
+ Also document Solaris port defaults.
+
+2006-05-24 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avr.c: Start implementing support for ATmega256x;
+ jtag2 and bitbang programmers are working, stk500v2
+ still needs to be done.
+ * avrdude.conf.in: (Ditto.)
+ * avrpart.c: (Ditto.)
+ * avrpart.h: (Ditto.)
+ * config_gram.y: (Ditto.)
+ * lexer.l: (Ditto.)
+
+2006-04-18 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Contributed by Julius Luukko <Julius.Luukko@lut.fi>:
+ * avrdude.conf.in: Add the "ere-isp-avr" programmer.
+
+2006-04-13 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * par.c: Add logic to negate parallel-port signals in
+ avrdude.conf using a tilde.
+
+ Contributed by Bram Daams:
+ * avrdude.conf.in: Add the "atisp" programmer entry that
+ makes use of negated signals.
+
+2006-03-28 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add entries for AT90USB{64,128}{6,7}
+
+2006-03-23 Colin O'Flynn <coflynn@newae.com>
+
+ Contributed by Wim Lewis, fix a few typos (patch #4987)
+ * avrdude.1: Typo fix
+
+2006-02-27 Colin O'Flynn <coflynn@newae.com>
+
+ Contributed by Wim Lewis, add support for checking device
+ signatures in detail (patch #4924 and #4925)
+ * avrdude.conf.in: Add signatures
+ * avrpart.c: Set default signature
+ * avrpart.h: Variable for signature
+ * config_gram.y: More signature reading
+ * lexer.l: Define that signatures exist
+ * main.c: Read signatures and check them against hardware
+
+2006-02-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Fix paged flash write for AT90PWMx
+ (error in datasheet).
+
+2006-01-23 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * configure.in: Bump version.
+
+2006-01-17 Colin O'Flynn <coflynn@newae.com>
+
+ * main.c: Fixed a typo in safemode variable names, fixed bug 15113
+ * avrdude.conf.in : Added BS2 and pagel to M162, Patch 4766
+ * main.c, stk500v2.c: Added patch 4804 from eolson@mit.edu
+ Which stops sck from being writtend needlessly
+
+2006-01-13 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Contributed by David Moore: add support for the
+ AVRISP mkII device. (Savannah patch #4789.)
+ * serial.h: Declare usb_serdev_frame device descriptor.
+ * stk500v2.c: Implementation of the AVRISP mkII handling.
+ * usb_libusb.c: Add USB handling for short-frame delimited
+ AVRISP mkII USB protocol; add distinction of different
+ devices in usbdev_open().
+ * jtagmkII.c: Tell usbdev_open() to search for the JTAG ICE mkII.
+ * usbdevs.h: (New file.)
+ * Makefile.am: Add usbdevs.h, as well as some other forgotten
+ files "make distcheck" complained about.
+ * avrdude.conf.in: Add more aliases for the AVRISP mkII.
+ * avrdude.1: Document how to use the AVRISP mkII.
+ * doc/avrdude.texi: (Ditto.)
+
+2006-01-12 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add EEPROM page instructions for the
+ ATmega169 so it will work for STK500v2.
+
+2005-12-16 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Added support for ATtiny24/44/84.
+
+2005-12-05 Colin O'Flynn <coflynn@newae.com>
+
+ * avrdude.conf.in: Added m162 support for stk500v2
+
+2005-12-01 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: fix the number of significant bits for
+ the efuse memory in ATmega48/88/168; the datasheet is a bit
+ off here as well.
+
+2005-11-29 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.1: update for JTAG ICE mkI support.
+ * doc/avrdude.texi: (Ditto.)
+
+2005-11-29 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by Galen Seitz:
+ patch #4459: Fix for rpm package builds
+ * avrdude.spec.in: update the RPM spec file:
+ - Default to enable-doc=yes during configure.
+ - Move info file to docs package.
+ - Make building of docs package conditional. Basic
+ idea copied from avr-gcc.
+
+2005-11-29 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Submitted by someone who thinks he's called "Daper":
+ Fix bug #15013: Wrong use of PPICLAIM (kernel: ppdev0: claim the
+ port first)
+ * par.c: don't claim/release here (thus win_ppdev.h not needed
+ anymore)
+ * ppi.c: claim/release here.
+ * freebsd_ppi.h: ppi_claim/ppi_release now take an fd as parameter.
+ * solaris_ecpp.h: (Ditto.)
+ * linux_ppdev.h: (Ditto.) (Also add copyright.)
+ * win_ppdev.h: Not needed anymore, remove.
+
+2005-11-28 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkI.c: Improve the communication startup with the ICE.
+
+2005-11-28 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * configure.ac: enable parport access on x86_64 Linux and
+ FreeBSD systems.
+
+2005-11-27 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: add the "calibration" space to ATmega16.
+
+2005-11-25 Colin O'Flynn <coflynn@newae.com>
+
+ Fixed bug 15051, building for Windows breaks.
+ * par.c: ppi_claim and ppi_release definitions now in a Windows header file
+ * ppi.c: Only included if you are building for Windows
+ * win_ppdev.h: Initial Commit, see par.c
+
+2005-11-24 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Add basic support for the Atmel JTAG ICE mkI:
+ * config_gram.y: add mkI support to config sytax.
+ * lexer.l: (Ditto.)
+ * avrdude.conf.in: add sample programmer entries.
+ * jtagmkI.c: New file
+ * jtagmkI.h: New file
+ * jtagmkI_private.h: New file
+ * Makefile.am: include new files in build.
+
+2005-11-24 Colin O'Flynn <coflynn@newae.com>
+
+ Fix bug 14681 - Serial Communication Fails on -vvvv with Windows
+ * ser_win32.c: Patched with Brian Dean's patch
+
+2005-11-05 Colin O'Flynn <coflynn@newae.com>
+
+ Patch #4532 by Manfred Bartz
+ * avrdude.conf.in: added support for ATMega168 (also added support
+ for the stk500v2 protocol which was not in the patch).
+
+2005-11-03 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Add ecpp(7D) (parallel port) for Solaris.
+ * configure.ac: add Solaris' default parallel port.
+ * linux_ppdev.h: change parallel port access to the new style.
+ * freebsd_ppi.h: New file, abstract FreeBSD's ppi(4).
+ * solaris_ecpp.h: New file, abstract Solaris' ecpp(7D).
+ * par.c: change header inclusion sequence.
+ * pgm.h: remove obsolete ppi_claim() and ppi_release() dummies.
+ * ppi.c: change header inclusion sequence, use new parport
+ abstraction, drop obsolete dummy implementation.
+
+2005-11-02 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * config.h: change YYSTYPE to be a single word, to work around
+ a bug in Solaris' yacc.
+ * lexer.l: remove incompatibilities with Solaris' default lex,
+ bump resource limits for lex.
+
+2005-11-01 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Make avrdude Solaris-compatible.
+ * Makefile.am: distclean avrdude.conf.
+ * avrdude.conf.in: make the parallel-port programmers optional.
+ * bitbang.c: move the bitbang features out into PROGRAMMER.
+ * configure.ac: introduce --enable-parport, add Solaris.
+ * lexer.l: replace str by strng to work around problems in some
+ versions of flex.
+ * main.c: move getexitspecs into the respective programmer's
+ domain; replace rindex by the C-standard strrchr.
+ * par.c: make parallel port optional.
+ * par.h: everything but par_initpgm() is private now.
+ * pgm.h: add setping/getping/highpulsepin/getexitspecs.
+ * serbb_posix.c: generalize bitbang interface; replace
+ cfmakeraw() by explicit code.
+ * serbb_win32.c: generalize bitbang interface.
+
+2005-10-20 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * butterfly.c: fix yet another sign extension bug.
+
+2005-10-14 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in (ATmega8515): fix size of calibration
+ memory.
+
+2005-10-09 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: add support for ATmega640/1280/1281.
+ * avrdude.1: document the above.
+ * doc/avrdude.texi: (Ditto.)
+
+2005-09-27 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * doc/avrdude.texi: Polish up the docs a bit. Use smallexample
+ instead of example for wide tty output. Document a trick to
+ find out about the serial numbers of all JTAG ICEs attached
+ to USB.
+
+2005-09-26 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkII.c (jtagmkII_paged_write): default the page size early so the
+ buffer will be allocated correctly.
+ * usb_libusb.c: fix libusb handling; now it works with libusb-win32 as
+ well.
+
+2005-09-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * main.c(do_op): use mem->desc in place of upd->memtype to
+ give the full name of the respective memory area, instead of
+ the (possibly abbreviated) name the user typed in the -U option.
+
+2005-09-21 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * main.c: Add the forgotten -B option to the option string in
+ getopt(); sort the -s option into order.
+
+2005/09/21 Brian S. Dean <bsd@bsdhome.com>
+
+ * avr.c:
+ * main.c:
+ * safemode.c:
+ * safemode.h:
+ * term.h:
+ This is Colin O'Flynn's mega patch for updating safemode support:
+
+ * add support for parts with just 'fuse' memory
+
+ * if any fuse memories are altered, reflect those changes in the
+ post-programming safemode check so that safemode no longer
+ complains about fuses which were intentionally altered; this
+ eliminates the need to completely disable safemode using -u in
+ order to program fuses.
+
+ * provide -s option which will not ask to restore fuses, it will
+ just do it
+
+2005-09-19 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * butterfly.c (butterfly_initialize): make the device code unsigned so
+ it wouldn't sign-extend when >= 0x80.
+
+2005-09-18 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ Add the serial bit-bang driver, contributed by Michael Holzt.
+ * bitbang.h: New file.
+ * bitbang.c: New file.
+ * serbb.h: New file.
+ * serbb_posix.c: New file.
+ * serbb_win32.c: New file.
+ * Makefile.am: Include new files.
+ * config_gram.y: Add serbb to configuration language.
+ * lexer.l: (Ditto.)
+ * par.c: Centralize bit-bang code in bitbang.c.
+ * par.h: Declare newly published functions.
+ * pgm.h (struct programmer_t): Add a flag field for private use
+ by the programmer.
+ * pindefs.h: Add definitions for negated serbb pins.
+ * avrdude.conf.in: Add serbb programmers ponyser, dasa, and dasa3.
+ * avrdude.1: Document serbb code.
+ * doc/avrdude.texi: (Ditto.)
+
+2005/09/18 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.conf.in: Patch #4078: add VCC pin definition for DAPA
+ programmer.
+
+2005/09/18 Brian S. Dean <bsd@bsdhome.com>
+
+ * avr910.c: This is patch #3277 which appears to fix a number of
+ issues with the avr910 programmer.
+
+ Fixes the following problems with paged writes in avr910.c:
+ - failure to re-set address after page writes;
+ - no polling or delay after page writes;
+ - no page writes when not using auto-increment;
+ - an extraneous page write when data ends on page boundary.
+
+2005-09-17 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Fix the poll values for the ATmega103's EEPROM
+ so they eventually match the XML file.
+ This fixes bug #7492: EEPROM writing fail on atmega103 with
+ atavrisp
+
+2005-09-17 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: The ATmega128 has four oscillator calibration
+ bytes, not only a single one.
+ This closes bug #11496: Memory bank calibration on atmega128
+ should have 4 bytes
+
+2005/09/17 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.1:
+ Document -q -q. Expand a little on the description of the 'part'
+ command.
+
+2005/09/16 Brian S. Dean <bsd@bsdhome.com>
+
+ * fileio.c:
+ * main.c:
+ Implement -q -q to be very very quiet.
+
+2005/09/16 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.conf.in:
+ Add DAPA programmer.
+
+2005/09/16 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.conf.in:
+ * stk500v2.c:
+ This fixes EEPROM access using the STK500V2 programmer, partially
+ undoing part of a previous general fixup commit. Choose the correct
+ read/write operations with the stk500v2 program function - the correct
+ one depends on the memory type. EEPROM is byte addressable so uses
+ read/write. FLASH is word addressable and so uses read_lo/write_lo.
+
+2005-09-16 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.1: document the memtypes for -U
+ * doc/avrdude.texi: (Ditto.)
+ Closes bug #13501: <memtype> should be listed in the man page
+
+2005-09-16 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * doc/Makefile.am: add logic to detect the misf^H^H^H^H
+ gratitous API change in recent versions of texi2html where
+ the output directory has changed names.
+ Fix for:
+ bug #13026: The build fails with texi2html 1.76
+ bug #12715: make issues during install
+ patch #3091: commandline fix for latest version of texi2html
+
+2005-09-16 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * usb_libusb.c (usbdev_drain): actually implement draining to aid
+ synchronizing against a JTAG ICE in weird state.
+
+2005-09-16 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * butterfly.c: improve the butterfly initialization so it is more likely
+ to synchonize; [bug #9787: avrdude 4.4.0 correct butterfly interface]
+
+2005-09-14 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkII.c (jtagmkII_paged_load): return the number of bytes read.
+ This makes EEPROM block reads work again.
+
+2005-09-14 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: add a jtag2slow programmer alias, and make
+ "jtag2" default to 115200 Bd.
+ * doc/avrdude.texi: document the above changes.
+
+2005/09/14 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.conf.in:
+ Change bit 0 of the ATmega169 efuse 'write' opcode from 'x' (ignore)
+ to 'i' (input). Even though this bit should be ignored, it should not
+ be changed. The 'x' setting sets the bit to zero which programs it
+ and could cause undefined behaviour. Setting to 'i' enables it to be
+ rewritten to its old value.
+
+ A better solution might be to read the fuse byte, apply the new value
+ while leaving the 'x' bit alone, then writing the value back. The
+ current fix is a workaround which allows the developer to change the
+ bit as desired.
+
+2005-08-30 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * usb_libusb.c: Consistently use unsigned char for buffers.
+
+2005-08-29 Brian S. Dean <bsd@bsdhome.com>
+
+ * avr910.c: Eliminate compiler warnings. GCC 4.x elicits many
+ signedness warnings when passing unsigned char * when char * is in
+ the prototype and vice versa. Clean these up along with a few
+ others.
+ * butterfly.c: (Ditto.)
+ * jtagmkII.c: (Ditto.)
+ * safemode.c: (Ditto.)
+ * safemode.h: (Ditto.)
+ * ser_posix.c: (Ditto.)
+ * serial.h: (Ditto.)
+ * stk500.c: (Ditto.)
+ * stk500v2.c: (Ditto.)
+
+2005-08-28 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add support for the ATtiny25/45/85. Note that
+ only the ATtiny45 appears to have a complete XML description right
+ now.
+ * avrdude.1: Mention all the recently added device support: AT90PWM2/3,
+ ATmega164/324/644, ATmega329x/649x, ATtiny25/45/85.
+ * doc/avrdude.texi: (Ditto.)
+
+2005/08/28 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.conf.in:
+ * stk500v2.c:
+ This is patch # 4338, obsoletes patch #4327, provides fixes for bugs
+ #13693, #13871, and #14212.
+
+ This provides bug fixes to the STK500V2 programmer type.
+
+ - incorrect token used from avrdude.conf.in
+ - wrong command sent to programmer, hence no write to eeprom.
+ - programmer was said to start writing at 0x0000 and continue
+ page by page and was not repositionned when a gap was found
+ in the hex file, or when the hex file start address was not
+ 0x0000. Hence the verify procedure was correct, not the
+ write procedure.
+ - speed up of flash write to skip empty pages (full of 0xFF)
+ by re-enabling a dedicated function for that task.
+ - stk500v2_paged_load() was not returning the number of byte
+ read, so empty hex files were generated when reading memory.
+
+2005-08-17 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: fix the EEPROM size for ATmega329x/649x.
+
+2005-08-16 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add support for the AT90PWM2/3.
+
+2005-07-27 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ (This work has been done as part of a contract with Atmel, Dresden.)
+ * butterfly.c: Implement full support for AVR109 boot loaders.
+ * avrdude.conf.in: add avr109 and avr911 as alias for butterfly.
+ * avrdude.1: Document the AVR109 addition.
+ * doc/avrdude.texi: (Ditto.)
+
+2005-07-26 Brian S. Dean <bsd@bsdhome.com>
+
+ * main.c:
+ Don't call exit() directly here - set the exit value and jump to the
+ main_exit: label to ensure the programmer is released correctly.
+
+ * stk500v2.c:
+ The stk500v2_getsync() function was improperly checking for success,
+ thus it was falsely reporting that it failed when it was actually
+ working correctly. Fixed.
+
+2005-07-25 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * usb_libusb.c: Catch benign errors when reading the serial #.
+
+2005-06-19 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * Makefile.am: Implement libusb-base USB transport for the
+ JTAG ICE mkII.
+ * configure.ac: ditto.
+ * jtagmkII.c: ditto.
+ * ser_posix.c: ditto.
+ * ser_win32.c: ditto.
+ * serial.h: ditto.
+ * usb_libusb.c: ditto (New file).
+ * avrdude.1: document the USB transport.
+ * doc/avrdude.texi: ditto.
+
+2005-06-15 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: The AT90CAN128 has AllowFullPageBitstream = no.
+
+2005-06-14 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add support for the ATmega164/324/644.
+ * jtagmkII.c: If enter_progmode fails with RSP_ILLEGAL_JTAG_ID, give
+ the user a hint that the JTAGEN fuse might be unset.
+
+2005-06-11 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Add support for the ATmega329x/649x.
+
+2005-05-27 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * jtagmkII.c: fix a signedness bug when shifting bits; when
+ discarding a packet for being overly long, restart the state
+ machine instead of attempting to drop a preposterous amount
+ of data.
+
+2005-05-19 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.1:
+ * doc/avrdude.texi: Document that the JTAG ICE mkII code currently
+ cannot write to flash one byte at a time. Also mention the bug
+ tracker interface on savannah.
+
+2005/05/14 Brian S. Dean <bsd@bsdhome.com>
+
+ * configure.ac:
+ * main.c:
+ Update version for beta release and copyright message.
+ Change the default port to 'serial' for the newly added serial
+ programmers stk500v2 and jtagmkii.
+
+2005-05-10 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * Makefile.am:
+ * avr910.c:
+ * avrdude.1:
+ * avrdude.conf.in:
+ * avrpart.c:
+ * avrpart.h:
+ * butterfly.c:
+ * config_gram.y:
+ * crc16.c:
+ * crc16.h:
+ * jtagmkII.c:
+ * jtagmkII.h:
+ * jtagmkII_private.h:
+ * lexer.l:
+ * main.c:
+ * pgm.h:
+ * serial.h:
+ * ser_posix.c:
+ * ser_win32.c:
+ * stk500.c:
+ * stk500v2.c:
+ * stk500v2.h:
+ * stk500v2_private.h:
+ * doc/avrdude.texi:
+
+ Mega-commit to bring in both, the STK500v2 support from Erik
+ Walthinsen, as well as JTAG ICE mkII support (by me).
+
+ Note that for the JTAG ICE, I did change a few things in the
+ internal API. Notably I made the serial receive timeout
+ configurable by the backends via an exported variable (done in
+ both the Posix and the Win32 implementation), and I made the
+ serial_recv() function return a -1 instead of bailing out with
+ exit(1) upon encountering a receive timeout (currently only done
+ in the Posix implementation). Both measures together allow me to
+ receive a datastreem from the ICE at 115 kbps on a somewhat lossy
+ PCI multi-UART card that occasionally drops a character. The JTAG
+ ICE mkII protocol has enough of safety layers to allow recovering
+ from these events, but the previous code wasn't prepared for any
+ kind of recovery. The Win32 change for this still has to be done.
+
+2005/02/11 Brian S. Dean <bsd@bsdhome.com>
+
+ * main.c:
+ Exit non-zero if safe-mode reverts fuse bits that were requested on
+ the command-line.
+
+ Variable declarations must only appear at the beginning of a block.
+
+2005/02/10 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.1:
+ Document -u option to disable safe mode.
+
+2005/02/10 Brian S. Dean <bsd@bsdhome.com>
+
+ * configure.ac:
+ doc/Makefile is now dependent on whether or not doc is enabled.
+
+2005/02/10 Brian S. Dean <bsd@bsdhome.com>
+
+ * Makefile.am:
+ * configure.ac:
+ Disable the doc build by default; the tools needed to build
+ doc are either not available on all systems or are at best
+ inconvenient to build and install. The doc can still be built, one
+ just needs to specify --enable-doc at configure time.
+
+2005-01-24 Colin O'Flynn <coflynn@newae.com>
+
+ * main.c: Add "safe mode". Fuse settings will be restored at the end
+ of a programming session unless the -u switch is specified.
+ * safemode.c: New file. Safe mode support.
+ * safemode.h: New file. Safe mode support.
+ * Makefile.am: Add new files.
+ * doc/avrdude.texi: Document new Safe Mode feature and switch.
+
+2004/12/22 Brian S. Dean <bsd@bsdhome.com>
+
+ * avrdude.conf.in:
+ Add support for "Xilinx JTAG cable". Contributed by:
+ Tymm <tymm@booyaka.com>
+
+ Add support for the AT90CAN128. Not sure if all the instruction
+ encoding is correct, specifically the address bits don't exactly match
+ those of the preliminary datasheet that I have, but I don't see how
+ they could be right. Tested with STK500 and it works there.
+ Instruction encodings have not been tested due to lack of a parallel
+ port on my Mac development box.
+
+2004-07-19 Theodore A. Roth <troth@openavr.org>
+
+ * avrdude.1: Remove reference to ppi programmer schematic.
+ * configure.ac (AC_INIT): Set version to "4.4.0cvs".
+
+2004-07-18 Theodore A. Roth <troth@openavr.org>
+
+ * AVRDUDE 4.4.0 has been released (cvs release tag is "release_4_4_0").
+
+2004-07-18 Theodore A. Roth <troth@openavr.org>
+
+ * Makefile.am (EXTRA_DIST): Remove avrdude.pdf since it is no longer
+ supplied.
+ * NEWS: Fix typo.
+ * bootstrap: Delete the autom4te.cache dir before running the
+ autotools.
+ * configure.ac (AC_INIT): Set version to 4.4.0.
+
+2004-07-17 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * avrdude.1: Fixed obvious copy and paste error
+ (Patch #3199 contributed by Galen Seitz)
+
+2004-07-15 Theodore A. Roth <troth@openavr.org>
+
+ * main.c (main): Don't indent CPP directives.
+ When showing update progress in a no tty situation, use unbuffered IO
+ for all systems, not just win32 native.
+ Update copyright year when printing version.
+ Remove warning about native win32 being experimental.
+ Split a line string.
+ * ppiwin.c: Update copyright year.
+ Add cvs Id keyword.
+ (usleep): Cleanup debug CPP directives to improve readability.
+ * ser_win32.c: Include <stdio.h> to fix failing build.
+
+2004-07-08 Theodore A. Roth <troth@openavr.org>
+
+ * AUTHORS: Add names of recent major contributors.
+ * ser_win32.c: Assign copyright to Martin J. Thomas since he did all
+ real work on this file.
+
+2004-07-07 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * NEWS, doc/TODO: Updated NEWS and TODO
+
+2004-07-07 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * stk500.c, term.c, doc/avrdude.texi, avrdude.1:
+ added "sck"-command to the terminal mode.
+ This command allows slowing down of the SCK of
+ STK500-programmers.
+
+2004-07-05 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * *.c, *.h: Removed unnecessary includes of
+ config.h
+
+2004-07-04 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * avr.h: Removed some unused prototypes
+
+2004-07-04 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * stk500.c: Fixed fosc behaviour for values exceeding
+ maximum frequency (contributed by Galen Seitz)
+
+2004-07-04 Jan-Hinnerk Reichert <hinni@despammed.com>
+ * avrdude.conf.in: Added support for
+ ATtiny2313 (contributed by Bob Paddock)
+
+2004-06-25 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * avrdude.conf.in: Fix efuse bits for ATmega169.
+
+2004-06-24 Alex Shepherd <maillists@ajsystems.co.nz>
+
+ Merged in Win32 Native changes contributed by Martin Thomas
+ Changed all instances of __CYGWIN__ conditional compilation to
+ WIN32NATIVE
+
+ * ser_win32.c: fleshed out all the previous stubs
+ * ser_posix.c: added WIN32NATIVE conditional compilation to skip
+ all function to allow ser_win32.c functions to operate
+ * ppi.h: removed commented code
+ * pgh.h: added usleep macros
+ * main.c: stdout,stderr tweaks for Win32
+ * configure.ac: added CFLAGS and LDFLAGS for Win32Native
+ * config_gram.y: added strtok_r macro
+ * buterfly.c: added various stub functions and EXIT processing
+ * avr910.c: added return 0 to avr910_open() and included time headers
+ * term.c: added warning about libreadline not supported in WIN32NATIVE
+
+2004-06-17 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * avrdude.conf.in: Added support for
+ - tiny13 (contributed by Pawel Moll)
+ - mega48 and mega88 (contributed by Galen Seitz)
+ However, the STK500-code for mega8 remains unchanged.
+
+2004-05-19 Brian S. Dean <bsd@bsdhome.com>
+
+ * main.c:
+ * stk500.c: Allow the baud rate to be specified on the command
+ line with a new -b switch. The specified baud rate will
+ override the default serial port baud rate for a particular
+ programmer.
+
+2004-05-19 Brian S. Dean <bsd@bsdhome.com>
+
+ * ppi.c: Stub-out the ppi_* functions in ppi.c with empty
+ wrappers that simply return an error code in order to build
+ successfully on MacOS X. This allows avrdude to work on MacOS
+ X and was tested using a USB<->RS232 cable adapter,
+ specifically Keyspan model USA-19HS.
+
+2004-04-23 Joerg Wunsch <j@uriah.heep.sax.de>
+
+ * lists.h, lists.c: Drop LISTSZ and the check for
+ it in lcreat().
+
+2004-04-17 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * avr910.c: Hopefully fixed that weird "first byte not
+ programmed"-error in a good way (previous fix was not
+ working with all firmwares)
+
+2004-02-10 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * avrdude.1, doc/avrdude.texi, doc/TODO:
+ Removed the deprecated options from documentation
+
+2004-02-10 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * main.c: Removed deprecated options.
+
+2004-01-28 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * pgm.c, main.c, avr910.c, butterfly.c, stk500.c:
+ Changed default for powerup, powerdown and LED-commands
+ to do nothing and return OK. Then removed these commands
+ from avr910, butterfly and stk500.
+ * pgm.c: Fixed wrong type for default_open introduced by
+ the cleanup yesterday.
+
+2004-01-29 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * par.c: changed order of port-read/writes in par_txrx().
+ This change should increase immunity to delays in the
+ programmer-hardware.
+ Also did some unrelated cleanup in par_txrx().
+
+2004-01-28 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * pgm.[ch], main.c, par.c, avr910.c, butterfly.c, stk500.c:
+ Move save/restore-functionality into open/close.
+ * par.c: open/close now saves/restores PPICTRL, too.
+ * TODO: exitspecs don't work if RESET is in PPICTRL.
+
+2004-01-26 Theodore A. Roth <troth@openavr.org>
+
+ * configure.ac (AC_INIT): Post release version update.
+
+2004-01-26 Theodore A. Roth <troth@openavr.org>
+
+ * AVRDUDE 4.3.0 has been released (cvs release tag is "release_4_3_0").
+
+2004-01-26 Theodore A. Roth <troth@openavr.org>
+
+ * configure.ac: Update copyright year.
+ (AC_INIT): Set version to 4.3.0.
+
+2004-01-25 Theodore A. Roth <troth@openavr.org>
+
+ * ChangeLog: Minor formatting cleanups.
+ Move to all 2003 entries to ChangeLog-2003.
+ * ChangeLog-2003: New file.
+ * Makefile.am: Update copyright year.
+ (EXTRA_DIST): Add ChangeLog-2003.
+
+2004-01-17 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * doc/avrdude.texi: Get rid of those black boxes marking "overfull
+ hbox".
+
+2004-01-17 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * doc/avrdude.texi: New appendix "Troubleshooting".
+
+2004-01-12 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * avr910.c, avrpart.c, avrpart.h, doc/TODO:
+ Look up devicecode and report device.
+
+2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * avr910.c, pgm.c, pgm.h, config_gram.y, lexer.l: Add new configuration
+ parameter baudrate to support avr910-programmers with non-standard
+ baudrates.
+ * avrdude.conf.in, doc/avrdude.texi: Added "baudrate" to documentation.
+
+2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * avr910.c: Removed debugging stuff that is no longer needed.
+
+2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * doc/TODO: Removed two items.
+
+2004-01-03 Jan-Hinnerk Reichert <hinni@despammed.com>
+
+ * main.c, avr.c, avr.h, par.c, stk500.c: Add function
+ avr_chip_erase() to unify handling of cycle-count.
+ Makes cycle-count work for avr910-programmers.
+
diff --git a/xs/src/avrdude/ChangeLog-2007 b/xs/src/avrdude/ChangeLog-2007
new file mode 100644
index 000000000..3514da7e0
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2007
@@ -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.
diff --git a/xs/src/avrdude/ChangeLog-2008 b/xs/src/avrdude/ChangeLog-2008
new file mode 100644
index 000000000..f43a10abb
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2008
@@ -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.
+
diff --git a/xs/src/avrdude/ChangeLog-2009 b/xs/src/avrdude/ChangeLog-2009
new file mode 100644
index 000000000..1f993cbcf
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2009
@@ -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.)
+
diff --git a/xs/src/avrdude/ChangeLog-2010 b/xs/src/avrdude/ChangeLog-2010
new file mode 100644
index 000000000..45effefa4
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2010
@@ -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.
diff --git a/xs/src/avrdude/ChangeLog-2011 b/xs/src/avrdude/ChangeLog-2011
new file mode 100644
index 000000000..d8fffba01
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2011
@@ -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.
diff --git a/xs/src/avrdude/ChangeLog-2012 b/xs/src/avrdude/ChangeLog-2012
new file mode 100644
index 000000000..bb5751a6d
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2012
@@ -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.
diff --git a/xs/src/avrdude/ChangeLog-2013 b/xs/src/avrdude/ChangeLog-2013
new file mode 100644
index 000000000..8e975ef6e
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2013
@@ -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
diff --git a/xs/src/avrdude/ChangeLog-2014 b/xs/src/avrdude/ChangeLog-2014
new file mode 100644
index 000000000..3fe7a53aa
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2014
@@ -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.
diff --git a/xs/src/avrdude/ChangeLog-2015 b/xs/src/avrdude/ChangeLog-2015
new file mode 100644
index 000000000..edc274188
--- /dev/null
+++ b/xs/src/avrdude/ChangeLog-2015
@@ -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.
diff --git a/xs/src/avrdude/Makefile.am b/xs/src/avrdude/Makefile.am
new file mode 100644
index 000000000..d1ed47845
--- /dev/null
+++ b/xs/src/avrdude/Makefile.am
@@ -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
diff --git a/xs/src/avrdude/Makefile.standalone b/xs/src/avrdude/Makefile.standalone
new file mode 100644
index 000000000..d9a773771
--- /dev/null
+++ b/xs/src/avrdude/Makefile.standalone
@@ -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)
diff --git a/xs/src/avrdude/NEWS b/xs/src/avrdude/NEWS
new file mode 100644
index 000000000..ced93cd35
--- /dev/null
+++ b/xs/src/avrdude/NEWS
@@ -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.
diff --git a/xs/src/avrdude/README b/xs/src/avrdude/README
new file mode 100644
index 000000000..2ca0009a3
--- /dev/null
+++ b/xs/src/avrdude/README
@@ -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.)
diff --git a/xs/src/avrdude/ac_cfg.h b/xs/src/avrdude/ac_cfg.h
new file mode 100644
index 000000000..2461bf307
--- /dev/null
+++ b/xs/src/avrdude/ac_cfg.h
@@ -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 */
diff --git a/xs/src/avrdude/ac_cfg.h.in b/xs/src/avrdude/ac_cfg.h.in
new file mode 100644
index 000000000..9dda33a53
--- /dev/null
+++ b/xs/src/avrdude/ac_cfg.h.in
@@ -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
diff --git a/xs/src/avrdude/arduino.c b/xs/src/avrdude/arduino.c
new file mode 100644
index 000000000..5a9cb465e
--- /dev/null
+++ b/xs/src/avrdude/arduino.c
@@ -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;
+}
diff --git a/xs/src/avrdude/arduino.h b/xs/src/avrdude/arduino.h
new file mode 100644
index 000000000..024d711b9
--- /dev/null
+++ b/xs/src/avrdude/arduino.h
@@ -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
+
+
diff --git a/xs/src/avrdude/atmel-docs/AVR109.pdf b/xs/src/avrdude/atmel-docs/AVR109.pdf
new file mode 100644
index 000000000..0942f44bc
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/AVR109.pdf
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/AVR910.pdf b/xs/src/avrdude/atmel-docs/AVR910.pdf
new file mode 100644
index 000000000..585703aac
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/AVR910.pdf
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/AVRISPmkII-AVR069.pdf b/xs/src/avrdude/atmel-docs/AVRISPmkII-AVR069.pdf
new file mode 100644
index 000000000..dc4254954
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/AVRISPmkII-AVR069.pdf
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/browserDetect.js b/xs/src/avrdude/atmel-docs/EDBG/common/browserDetect.js
new file mode 100644
index 000000000..2a7aa08a4
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/browserDetect.js
@@ -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(); \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/css/960.css b/xs/src/avrdude/atmel-docs/EDBG/common/css/960.css
new file mode 100644
index 000000000..635d7ba5f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/css/960.css
@@ -0,0 +1 @@
+body{min-width:960px}.container_12,.container_16{margin-left:auto;margin-right:auto;width:960px}.grid_1,.grid_2,.grid_3,.grid_4,.grid_5,.grid_6,.grid_7,.grid_8,.grid_9,.grid_10,.grid_11,.grid_12,.grid_13,.grid_14,.grid_15,.grid_16{display:inline;float:left;margin-left:10px;margin-right:10px}.push_1,.pull_1,.push_2,.pull_2,.push_3,.pull_3,.push_4,.pull_4,.push_5,.pull_5,.push_6,.pull_6,.push_7,.pull_7,.push_8,.pull_8,.push_9,.pull_9,.push_10,.pull_10,.push_11,.pull_11,.push_12,.pull_12,.push_13,.pull_13,.push_14,.pull_14,.push_15,.pull_15{position:relative}.container_12 .grid_3,.container_16 .grid_4{width:220px}.container_12 .grid_6,.container_16 .grid_8{width:460px}.container_12 .grid_9,.container_16 .grid_12{width:700px}.container_12 .grid_12,.container_16 .grid_16{width:940px}.alpha{margin-left:0}.omega{margin-right:0}.container_12 .grid_1{width:60px}.container_12 .grid_2{width:140px}.container_12 .grid_4{width:300px}.container_12 .grid_5{width:380px}.container_12 .grid_7{width:540px}.container_12 .grid_8{width:620px}.container_12 .grid_10{width:780px}.container_12 .grid_11{width:860px}.container_16 .grid_1{width:40px}.container_16 .grid_2{width:100px}.container_16 .grid_3{width:160px}.container_16 .grid_5{width:280px}.container_16 .grid_6{width:340px}.container_16 .grid_7{width:400px}.container_16 .grid_9{width:520px}.container_16 .grid_10{width:580px}.container_16 .grid_11{width:640px}.container_16 .grid_13{width:760px}.container_16 .grid_14{width:820px}.container_16 .grid_15{width:880px}.container_12 .prefix_3,.container_16 .prefix_4{padding-left:240px}.container_12 .prefix_6,.container_16 .prefix_8{padding-left:480px}.container_12 .prefix_9,.container_16 .prefix_12{padding-left:720px}.container_12 .prefix_1{padding-left:80px}.container_12 .prefix_2{padding-left:160px}.container_12 .prefix_4{padding-left:320px}.container_12 .prefix_5{padding-left:400px}.container_12 .prefix_7{padding-left:560px}.container_12 .prefix_8{padding-left:640px}.container_12 .prefix_10{padding-left:800px}.container_12 .prefix_11{padding-left:880px}.container_16 .prefix_1{padding-left:60px}.container_16 .prefix_2{padding-left:120px}.container_16 .prefix_3{padding-left:180px}.container_16 .prefix_5{padding-left:300px}.container_16 .prefix_6{padding-left:360px}.container_16 .prefix_7{padding-left:420px}.container_16 .prefix_9{padding-left:540px}.container_16 .prefix_10{padding-left:600px}.container_16 .prefix_11{padding-left:660px}.container_16 .prefix_13{padding-left:780px}.container_16 .prefix_14{padding-left:840px}.container_16 .prefix_15{padding-left:900px}.container_12 .suffix_3,.container_16 .suffix_4{padding-right:240px}.container_12 .suffix_6,.container_16 .suffix_8{padding-right:480px}.container_12 .suffix_9,.container_16 .suffix_12{padding-right:720px}.container_12 .suffix_1{padding-right:80px}.container_12 .suffix_2{padding-right:160px}.container_12 .suffix_4{padding-right:320px}.container_12 .suffix_5{padding-right:400px}.container_12 .suffix_7{padding-right:560px}.container_12 .suffix_8{padding-right:640px}.container_12 .suffix_10{padding-right:800px}.container_12 .suffix_11{padding-right:880px}.container_16 .suffix_1{padding-right:60px}.container_16 .suffix_2{padding-right:120px}.container_16 .suffix_3{padding-right:180px}.container_16 .suffix_5{padding-right:300px}.container_16 .suffix_6{padding-right:360px}.container_16 .suffix_7{padding-right:420px}.container_16 .suffix_9{padding-right:540px}.container_16 .suffix_10{padding-right:600px}.container_16 .suffix_11{padding-right:660px}.container_16 .suffix_13{padding-right:780px}.container_16 .suffix_14{padding-right:840px}.container_16 .suffix_15{padding-right:900px}.container_12 .push_3,.container_16 .push_4{left:240px}.container_12 .push_6,.container_16 .push_8{left:480px}.container_12 .push_9,.container_16 .push_12{left:720px}.container_12 .push_1{left:80px}.container_12 .push_2{left:160px}.container_12 .push_4{left:320px}.container_12 .push_5{left:400px}.container_12 .push_7{left:560px}.container_12 .push_8{left:640px}.container_12 .push_10{left:800px}.container_12 .push_11{left:880px}.container_16 .push_1{left:60px}.container_16 .push_2{left:120px}.container_16 .push_3{left:180px}.container_16 .push_5{left:300px}.container_16 .push_6{left:360px}.container_16 .push_7{left:420px}.container_16 .push_9{left:540px}.container_16 .push_10{left:600px}.container_16 .push_11{left:660px}.container_16 .push_13{left:780px}.container_16 .push_14{left:840px}.container_16 .push_15{left:900px}.container_12 .pull_3,.container_16 .pull_4{left:-240px}.container_12 .pull_6,.container_16 .pull_8{left:-480px}.container_12 .pull_9,.container_16 .pull_12{left:-720px}.container_12 .pull_1{left:-80px}.container_12 .pull_2{left:-160px}.container_12 .pull_4{left:-320px}.container_12 .pull_5{left:-400px}.container_12 .pull_7{left:-560px}.container_12 .pull_8{left:-640px}.container_12 .pull_10{left:-800px}.container_12 .pull_11{left:-880px}.container_16 .pull_1{left:-60px}.container_16 .pull_2{left:-120px}.container_16 .pull_3{left:-180px}.container_16 .pull_5{left:-300px}.container_16 .pull_6{left:-360px}.container_16 .pull_7{left:-420px}.container_16 .pull_9{left:-540px}.container_16 .pull_10{left:-600px}.container_16 .pull_11{left:-660px}.container_16 .pull_13{left:-780px}.container_16 .pull_14{left:-840px}.container_16 .pull_15{left:-900px}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.clearfix:before,.clearfix:after,.container_12:before,.container_12:after,.container_16:before,.container_16:after{content:'.';display:block;overflow:hidden;visibility:hidden;font-size:0;line-height:0;width:0;height:0}.clearfix:after,.container_12:after,.container_16:after{clear:both}.clearfix,.container_12,.container_16{zoom:1} \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/css/docbook.css b/xs/src/avrdude/atmel-docs/EDBG/common/css/docbook.css
new file mode 100644
index 000000000..9a9c8f2b8
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/css/docbook.css
@@ -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;
+} \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/css/fluid_grid.css b/xs/src/avrdude/atmel-docs/EDBG/common/css/fluid_grid.css
new file mode 100644
index 000000000..a1983655d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/css/fluid_grid.css
@@ -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;
+} \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/css/index.css b/xs/src/avrdude/atmel-docs/EDBG/common/css/index.css
new file mode 100644
index 000000000..eb1b8c24f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/css/index.css
@@ -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;
+}
+
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/css/positioning.css b/xs/src/avrdude/atmel-docs/EDBG/common/css/positioning.css
new file mode 100644
index 000000000..7c9658c41
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/css/positioning.css
@@ -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;
+} \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/css/print.css b/xs/src/avrdude/atmel-docs/EDBG/common/css/print.css
new file mode 100644
index 000000000..a52a074e7
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/css/print.css
@@ -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;
+} \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/css/reset.css b/xs/src/avrdude/atmel-docs/EDBG/common/css/reset.css
new file mode 100644
index 000000000..27802c681
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/css/reset.css
@@ -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} \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/css/text.css b/xs/src/avrdude/atmel-docs/EDBG/common/css/text.css
new file mode 100644
index 000000000..0ef67296a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/css/text.css
@@ -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} \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.eot b/xs/src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.eot
new file mode 100644
index 000000000..e4e3d1701
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.eot
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.ttf b/xs/src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.ttf
new file mode 100644
index 000000000..4546611d4
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/fonts/DroidSansMono.ttf
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/Book_Closed.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/Book_Closed.png
new file mode 100644
index 000000000..294fbf6b0
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/Book_Closed.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/Book_Open.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/Book_Open.png
new file mode 100644
index 000000000..d78710e77
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/Book_Open.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/Document_Text.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/Document_Text.png
new file mode 100644
index 000000000..416b5380d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/Document_Text.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/Library.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/Library.png
new file mode 100644
index 000000000..a2fa8fce4
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/Library.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/external_link.gif b/xs/src/avrdude/atmel-docs/EDBG/common/images/external_link.gif
new file mode 100644
index 000000000..177cbbc72
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/external_link.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/loading.gif b/xs/src/avrdude/atmel-docs/EDBG/common/images/loading.gif
new file mode 100644
index 000000000..085ccaeca
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/loading.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/logo.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/logo.png
new file mode 100644
index 000000000..df85ffbeb
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/logo.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/minus.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/minus.png
new file mode 100644
index 000000000..9b5244afb
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/minus.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/next-arrow.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/next-arrow.png
new file mode 100644
index 000000000..db595f465
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/next-arrow.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/plus.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/plus.png
new file mode 100644
index 000000000..31010fe96
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/plus.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/previous-arrow.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/previous-arrow.png
new file mode 100644
index 000000000..347bc5347
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/previous-arrow.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/search-icon.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/search-icon.png
new file mode 100644
index 000000000..715f62d08
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/search-icon.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/sidebar.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/sidebar.png
new file mode 100644
index 000000000..549267187
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/sidebar.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/starsSmall.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/starsSmall.png
new file mode 100644
index 000000000..490a27b92
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/starsSmall.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/toc-icon.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/toc-icon.png
new file mode 100644
index 000000000..40b34bce5
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/toc-icon.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/images/ui-icons_217bc0_256x240.png b/xs/src/avrdude/atmel-docs/EDBG/common/images/ui-icons_217bc0_256x240.png
new file mode 100644
index 000000000..6f4bd87c0
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/images/ui-icons_217bc0_256x240.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery-1.7.2.min.js b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery-1.7.2.min.js
new file mode 100644
index 000000000..93adea19f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery-1.7.2.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.7.2 jquery.com | jquery.org/license */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(
+a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f
+.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery.cookie.js b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery.cookie.js
new file mode 100644
index 000000000..bada7bff7
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery.cookie.js
@@ -0,0 +1,93 @@
+/**
+ * Cookie plugin
+ *
+ * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+
+/**
+ * Create a cookie with the given name and value and other optional parameters.
+ *
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Set the value of a cookie.
+ * @example $.cookie('the_cookie', 'the_value', {expires: 7, path: '/', domain: 'jquery.com', secure: true});
+ * @desc Create a cookie with all available options.
+ * @example $.cookie('the_cookie', 'the_value');
+ * @desc Create a session cookie.
+ * @example $.cookie('the_cookie', null);
+ * @desc Delete a cookie by passing null as value.
+ *
+ * @param String name The name of the cookie.
+ * @param String value The value of the cookie.
+ * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
+ * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
+ * If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
+ * If set to null or omitted, the cookie will be a session cookie and will not be retained
+ * when the the browser exits.
+ * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
+ * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
+ * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
+ * require a secure protocol (like HTTPS).
+ * @type undefined
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
+ */
+
+/**
+ * Get the value of a cookie with the given name.
+ *
+ * @example $.cookie('the_cookie');
+ * @desc Get the value of a cookie.
+ *
+ * @param String name The name of the cookie.
+ * @return The value of the cookie.
+ * @type String
+ *
+ * @name $.cookie
+ * @cat Plugins/Cookie
+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
+ */
+jQuery.cookie = function(name, value, options) {
+ if (typeof value != 'undefined') { // name and value given, set cookie
+ options = options || {};
+ if (value === null) {
+ value = '';
+ options.expires = -1;
+ }
+ var expires = '';
+ if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
+ var date;
+ if (typeof options.expires == 'number') {
+ date = new Date();
+ date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
+ } else {
+ date = options.expires;
+ }
+ expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
+ }
+ var path = options.path ? '; path=' + options.path : '';
+ var domain = options.domain ? '; domain=' + options.domain : '';
+ var secure = options.secure ? '; secure' : '';
+ document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
+
+ } else { // only name given, get cookie
+ var cookieValue = null;
+ if (document.cookie && document.cookie != '') {
+ var cookies = document.cookie.split(';');
+ for (var i = 0; i < cookies.length; i++) {
+ var cookie = jQuery.trim(cookies[i]);
+ // Does this cookie string begin with the name we want?
+ if (cookie.substring(0, name.length + 1) == (name + '=')) {
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+ break;
+ }
+ }
+ }
+ return cookieValue;
+ }
+}; \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery.ui.all.js b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery.ui.all.js
new file mode 100644
index 000000000..943d3b357
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/jquery.ui.all.js
@@ -0,0 +1,418 @@
+/*!
+ * jQuery UI 1.8.18
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function(b,a){function c(c,a){var e=c.nodeName.toLowerCase();if("area"===e){var e=c.parentNode,f=e.name;if(!c.href||!f||"map"!==e.nodeName.toLowerCase())return!1;e=b("img[usemap=#"+f+"]")[0];return!!e&&d(e)}return(/input|select|textarea|button|object/.test(e)?!c.disabled:"a"==e?c.href||a:a)&&d(c)}function d(c){return!b(c).parents().andSelf().filter(function(){return"hidden"===b.curCSS(this,"visibility")||b.expr.filters.hidden(this)}).length}b.ui=b.ui||{};b.ui.version||(b.extend(b.ui,{version:"1.8.14",
+keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),b.fn.extend({_focus:b.fn.focus,focus:function(c,a){return"number"===typeof c?this.each(function(){var d=this;setTimeout(function(){b(d).focus();
+a&&a.call(d)},c)}):this._focus.apply(this,arguments)},scrollParent:function(){var c;c=b.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(b.curCSS(this,"position",1))&&/(auto|scroll)/.test(b.curCSS(this,"overflow",1)+b.curCSS(this,"overflow-y",1)+b.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(b.curCSS(this,"overflow",1)+b.curCSS(this,
+"overflow-y",1)+b.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!c.length?b(document):c},zIndex:function(c){if(c!==a)return this.css("zIndex",c);if(this.length)for(var c=b(this[0]),d;c.length&&c[0]!==document;){d=c.css("position");if("absolute"===d||"relative"===d||"fixed"===d)if(d=parseInt(c.css("zIndex"),10),!isNaN(d)&&0!==d)return d;c=c.parent()}return 0},disableSelection:function(){return this.bind((b.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",
+function(b){b.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),b.each(["Width","Height"],function(c,d){function e(c,a,d,g){b.each(f,function(){a-=parseFloat(b.curCSS(c,"padding"+this,!0))||0;d&&(a-=parseFloat(b.curCSS(c,"border"+this+"Width",!0))||0);g&&(a-=parseFloat(b.curCSS(c,"margin"+this,!0))||0)});return a}var f="Width"===d?["Left","Right"]:["Top","Bottom"],i=d.toLowerCase(),j={innerWidth:b.fn.innerWidth,innerHeight:b.fn.innerHeight,outerWidth:b.fn.outerWidth,
+outerHeight:b.fn.outerHeight};b.fn["inner"+d]=function(f){return f===a?j["inner"+d].call(this):this.each(function(){b(this).css(i,e(this,f)+"px")})};b.fn["outer"+d]=function(f,c){return"number"!==typeof f?j["outer"+d].call(this,f):this.each(function(){b(this).css(i,e(this,f,!0,c)+"px")})}}),b.extend(b.expr[":"],{data:function(c,a,d){return!!b.data(c,d[3])},focusable:function(a){return c(a,!isNaN(b.attr(a,"tabindex")))},tabbable:function(a){var d=b.attr(a,"tabindex"),e=isNaN(d);return(e||0<=d)&&c(a,
+!e)}}),b(function(){var c=document.body,a=c.appendChild(a=document.createElement("div"));b.extend(a.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});b.support.minHeight=100===a.offsetHeight;b.support.selectstart="onselectstart"in a;c.removeChild(a).style.display="none"}),b.extend(b.ui,{plugin:{add:function(c,a,d){var c=b.ui[c].prototype,f;for(f in d)c.plugins[f]=c.plugins[f]||[],c.plugins[f].push([a,d[f]])},call:function(b,c,a){if((c=b.plugins[c])&&b.element[0].parentNode)for(var f=
+0;f<c.length;f++)b.options[c[f][0]]&&c[f][1].apply(b.element,a)}},contains:function(b,c){return document.compareDocumentPosition?b.compareDocumentPosition(c)&16:b!==c&&b.contains(c)},hasScroll:function(c,a){if("hidden"===b(c).css("overflow"))return!1;var d=a&&"left"===a?"scrollLeft":"scrollTop",f=!1;if(0<c[d])return!0;c[d]=1;f=0<c[d];c[d]=0;return f},isOverAxis:function(b,c,a){return b>c&&b<c+a},isOver:function(c,a,d,f,i,j){return b.ui.isOverAxis(c,d,i)&&b.ui.isOverAxis(a,f,j)}}))})(jQuery);
+(function(b,a){if(b.cleanData){var c=b.cleanData;b.cleanData=function(a){for(var d=0,e;null!=(e=a[d]);d++)b(e).triggerHandler("remove");c(a)}}else{var d=b.fn.remove;b.fn.remove=function(c,a){return this.each(function(){a||(!c||b.filter(c,[this]).length)&&b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return d.call(b(this),c,a)})}}b.widget=function(c,a,d){var f=c.split(".")[0],i,c=c.split(".")[1];i=f+"-"+c;d||(d=a,a=b.Widget);b.expr[":"][i]=function(f){return!!b.data(f,
+c)};b[f]=b[f]||{};b[f][c]=function(b,f){arguments.length&&this._createWidget(b,f)};a=new a;a.options=b.extend(!0,{},a.options);b[f][c].prototype=b.extend(!0,a,{namespace:f,widgetName:c,widgetEventPrefix:b[f][c].prototype.widgetEventPrefix||c,widgetBaseClass:i},d);b.widget.bridge(c,b[f][c])};b.widget.bridge=function(c,d){b.fn[c]=function(e){var f="string"===typeof e,i=Array.prototype.slice.call(arguments,1),j=this,e=!f&&i.length?b.extend.apply(null,[!0,e].concat(i)):e;if(f&&"_"===e.charAt(0))return j;
+f?this.each(function(){var f=b.data(this,c),d=f&&b.isFunction(f[e])?f[e].apply(f,i):f;if(d!==f&&d!==a)return j=d,!1}):this.each(function(){var f=b.data(this,c);f?f.option(e||{})._init():b.data(this,c,new d(e,this))});return j}};b.Widget=function(b,c){arguments.length&&this._createWidget(b,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:!1},_createWidget:function(c,a){b.data(a,this.widgetName,this);this.element=b(a);this.options=b.extend(!0,{},this.options,this._getCreateOptions(),
+c);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return b.metadata&&b.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},
+option:function(c,d){var e=c;if(0===arguments.length)return b.extend({},this.options);if("string"===typeof c){if(d===a)return this.options[c];e={};e[c]=d}this._setOptions(e);return this},_setOptions:function(c){var a=this;b.each(c,function(b,f){a._setOption(b,f)});return this},_setOption:function(b,c){this.options[b]=c;"disabled"===b&&this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",
+!1)},disable:function(){return this._setOption("disabled",!0)},_trigger:function(c,a,d){var f=this.options[c],a=b.Event(a);a.type=(c===this.widgetEventPrefix?c:this.widgetEventPrefix+c).toLowerCase();d=d||{};if(a.originalEvent)for(var c=b.event.props.length,i;c;)i=b.event.props[--c],a[i]=a.originalEvent[i];this.element.trigger(a,d);return!(b.isFunction(f)&&!1===f.call(this.element[0],a,d)||a.isDefaultPrevented())}}})(jQuery);
+(function(b){var a=!1;b(document).mousedown(function(){a=!1});b.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var c=this;this.element.bind("mousedown."+this.widgetName,function(b){return c._mouseDown(b)}).bind("click."+this.widgetName,function(a){if(!0===b.data(a.target,c.widgetName+".preventClickEvent"))return b.removeData(a.target,c.widgetName+".preventClickEvent"),a.stopImmediatePropagation(),!1});this.started=!1},_mouseDestroy:function(){this.element.unbind("."+
+this.widgetName)},_mouseDown:function(c){if(!a){this._mouseStarted&&this._mouseUp(c);this._mouseDownEvent=c;var d=this,g=1==c.which,h="string"==typeof this.options.cancel?b(c.target).closest(this.options.cancel).length:!1;if(!g||h||!this._mouseCapture(c))return!0;this.mouseDelayMet=!this.options.delay;this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){d.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(c)&&this._mouseDelayMet(c)&&(this._mouseStarted=!1!==this._mouseStart(c),
+!this._mouseStarted))return c.preventDefault(),!0;!0===b.data(c.target,this.widgetName+".preventClickEvent")&&b.removeData(c.target,this.widgetName+".preventClickEvent");this._mouseMoveDelegate=function(b){return d._mouseMove(b)};this._mouseUpDelegate=function(b){return d._mouseUp(b)};b(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.preventDefault();return a=!0}},_mouseMove:function(c){if(b.browser.msie&&!(9<=document.documentMode)&&
+!c.button)return this._mouseUp(c);if(this._mouseStarted)return this._mouseDrag(c),c.preventDefault();this._mouseDistanceMet(c)&&this._mouseDelayMet(c)&&((this._mouseStarted=!1!==this._mouseStart(this._mouseDownEvent,c))?this._mouseDrag(c):this._mouseUp(c));return!this._mouseStarted},_mouseUp:function(c){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);this._mouseStarted&&(this._mouseStarted=!1,c.target==this._mouseDownEvent.target&&
+b.data(c.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(c));return!1},_mouseDistanceMet:function(b){return Math.max(Math.abs(this._mouseDownEvent.pageX-b.pageX),Math.abs(this._mouseDownEvent.pageY-b.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);
+(function(b){b.ui=b.ui||{};var a=/left|center|right/,c=/top|center|bottom/,d=b.fn.position,g=b.fn.offset;b.fn.position=function(g){if(!g||!g.of)return d.apply(this,arguments);var g=b.extend({},g),e=b(g.of),f=e[0],i=(g.collision||"flip").split(" "),j=g.offset?g.offset.split(" "):[0,0],k,l,m;9===f.nodeType?(k=e.width(),l=e.height(),m={top:0,left:0}):f.setTimeout?(k=e.width(),l=e.height(),m={top:e.scrollTop(),left:e.scrollLeft()}):f.preventDefault?(g.at="left top",k=l=0,m={top:g.of.pageY,left:g.of.pageX}):
+(k=e.outerWidth(),l=e.outerHeight(),m=e.offset());b.each(["my","at"],function(){var b=(g[this]||"").split(" ");b.length===1&&(b=a.test(b[0])?b.concat(["center"]):c.test(b[0])?["center"].concat(b):["center","center"]);b[0]=a.test(b[0])?b[0]:"center";b[1]=c.test(b[1])?b[1]:"center";g[this]=b});1===i.length&&(i[1]=i[0]);j[0]=parseInt(j[0],10)||0;1===j.length&&(j[1]=j[0]);j[1]=parseInt(j[1],10)||0;"right"===g.at[0]?m.left+=k:"center"===g.at[0]&&(m.left+=k/2);"bottom"===g.at[1]?m.top+=l:"center"===g.at[1]&&
+(m.top+=l/2);m.left+=j[0];m.top+=j[1];return this.each(function(){var f=b(this),c=f.outerWidth(),a=f.outerHeight(),d=parseInt(b.curCSS(this,"marginLeft",true))||0,e=parseInt(b.curCSS(this,"marginTop",true))||0,r=c+d+(parseInt(b.curCSS(this,"marginRight",true))||0),u=a+e+(parseInt(b.curCSS(this,"marginBottom",true))||0),s=b.extend({},m),v;if(g.my[0]==="right")s.left=s.left-c;else if(g.my[0]==="center")s.left=s.left-c/2;if(g.my[1]==="bottom")s.top=s.top-a;else if(g.my[1]==="center")s.top=s.top-a/2;
+s.left=Math.round(s.left);s.top=Math.round(s.top);v={left:s.left-d,top:s.top-e};b.each(["left","top"],function(f,d){if(b.ui.position[i[f]])b.ui.position[i[f]][d](s,{targetWidth:k,targetHeight:l,elemWidth:c,elemHeight:a,collisionPosition:v,collisionWidth:r,collisionHeight:u,offset:j,my:g.my,at:g.at})});b.fn.bgiframe&&f.bgiframe();f.offset(b.extend(s,{using:g.using}))})};b.ui.position={fit:{left:function(c,a){var f=b(window),f=a.collisionPosition.left+a.collisionWidth-f.width()-f.scrollLeft();c.left=
+0<f?c.left-f:Math.max(c.left-a.collisionPosition.left,c.left)},top:function(c,a){var f=b(window),f=a.collisionPosition.top+a.collisionHeight-f.height()-f.scrollTop();c.top=0<f?c.top-f:Math.max(c.top-a.collisionPosition.top,c.top)}},flip:{left:function(c,a){if("center"!==a.at[0]){var f=b(window),f=a.collisionPosition.left+a.collisionWidth-f.width()-f.scrollLeft(),d="left"===a.my[0]?-a.elemWidth:"right"===a.my[0]?a.elemWidth:0,g="left"===a.at[0]?a.targetWidth:-a.targetWidth,k=-2*a.offset[0];c.left+=
+0>a.collisionPosition.left?d+g+k:0<f?d+g+k:0}},top:function(c,a){if("center"!==a.at[1]){var f=b(window),f=a.collisionPosition.top+a.collisionHeight-f.height()-f.scrollTop(),d="top"===a.my[1]?-a.elemHeight:"bottom"===a.my[1]?a.elemHeight:0,g="top"===a.at[1]?a.targetHeight:-a.targetHeight,k=-2*a.offset[1];c.top+=0>a.collisionPosition.top?d+g+k:0<f?d+g+k:0}}}};b.offset.setOffset||(b.offset.setOffset=function(c,a){/static/.test(b.curCSS(c,"position"))&&(c.style.position="relative");var f=b(c),d=f.offset(),
+g=parseInt(b.curCSS(c,"top",!0),10)||0,k=parseInt(b.curCSS(c,"left",!0),10)||0,d={top:a.top-d.top+g,left:a.left-d.left+k};"using"in a?a.using.call(c,d):f.css(d)},b.fn.offset=function(c){var a=this[0];return!a||!a.ownerDocument?null:c?this.each(function(){b.offset.setOffset(this,c)}):g.call(this)})})(jQuery);
+(function(b){b.widget("ui.draggable",b.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){"original"==this.options.helper&&!/^(?:r|a|f)/.test(this.element.css("position"))&&
+(this.element[0].style.position="relative");this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable"))return this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy(),this},_mouseCapture:function(a){var c=this.options;if(this.helper||c.disabled||b(a.target).is(".ui-resizable-handle"))return!1;
+this.handle=this._getHandle(a);if(!this.handle)return!1;b(!0===c.iframeFix?"iframe":c.iframeFix).each(function(){b('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(b(this).offset()).appendTo("body")});return!0},_mouseStart:function(a){var c=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();b.ui.ddmanager&&(b.ui.ddmanager.current=this);
+this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};b.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=
+a.pageY;c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt);c.containment&&this._setContainment();if(!1===this._trigger("start",a))return this._clear(),!1;this._cacheHelperProportions();b.ui.ddmanager&&!c.dropBehaviour&&b.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,!0);b.ui.ddmanager&&b.ui.ddmanager.dragStart(this,a);return!0},_mouseDrag:function(a,c){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");
+if(!c){var d=this._uiHash();if(!1===this._trigger("drag",a,d))return this._mouseUp({}),!1;this.position=d.position}if(!this.options.axis||"y"!=this.options.axis)this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||"x"!=this.options.axis)this.helper[0].style.top=this.position.top+"px";b.ui.ddmanager&&b.ui.ddmanager.drag(this,a);return!1},_mouseStop:function(a){var c=!1;b.ui.ddmanager&&!this.options.dropBehaviour&&(c=b.ui.ddmanager.drop(this,a));this.dropped&&(c=this.dropped,this.dropped=
+!1);if((!this.element[0]||!this.element[0].parentNode)&&"original"==this.options.helper)return!1;if("invalid"==this.options.revert&&!c||"valid"==this.options.revert&&c||!0===this.options.revert||b.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var d=this;b(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){d._trigger("stop",a)!==false&&d._clear()})}else!1!==this._trigger("stop",a)&&this._clear();return!1},_mouseUp:function(a){!0===
+this.options.iframeFix&&b("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});b.ui.ddmanager&&b.ui.ddmanager.dragStop(this,a);return b.ui.mouse.prototype._mouseUp.call(this,a)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var c=!this.options.handle||!b(this.options.handle,this.element).length?!0:!1;b(this.options.handle,this.element).find("*").andSelf().each(function(){this==a.target&&(c=
+!0)});return c},_createHelper:function(a){var c=this.options,a=b.isFunction(c.helper)?b(c.helper.apply(this.element[0],[a])):"clone"==c.helper?this.element.clone().removeAttr("id"):this.element;a.parents("body").length||a.appendTo("parent"==c.appendTo?this.element[0].parentNode:c.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){"string"==typeof a&&(a=a.split(" "));b.isArray(a)&&(a={left:+a[0],top:+a[1]||
+0});"left"in a&&(this.offset.click.left=a.left+this.margins.left);"right"in a&&(this.offset.click.left=this.helperProportions.width-a.right+this.margins.left);"top"in a&&(this.offset.click.top=a.top+this.margins.top);"bottom"in a&&(this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();"absolute"==this.cssPosition&&(this.scrollParent[0]!=document&&b.ui.contains(this.scrollParent[0],
+this.offsetParent[0]))&&(a.left+=this.scrollParent.scrollLeft(),a.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&"html"==this.offsetParent[0].tagName.toLowerCase()&&b.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"==this.cssPosition){var b=this.element.position();return{top:b.top-
+(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),
+height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;"parent"==a.containment&&(a.containment=this.helper[0].parentNode);if("document"==a.containment||"window"==a.containment)this.containment=["document"==a.containment?0:b(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,"document"==a.containment?0:b(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,("document"==a.containment?0:b(window).scrollLeft())+b("document"==a.containment?document:
+window).width()-this.helperProportions.width-this.margins.left,("document"==a.containment?0:b(window).scrollTop())+(b("document"==a.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){var a=b(a.containment),c=a[0];if(c){a.offset();var d="hidden"!=b(c).css("overflow");this.containment=[(parseInt(b(c).css("borderLeftWidth"),10)||0)+(parseInt(b(c).css("paddingLeft"),
+10)||0),(parseInt(b(c).css("borderTopWidth"),10)||0)+(parseInt(b(c).css("paddingTop"),10)||0),(d?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(b(c).css("borderLeftWidth"),10)||0)-(parseInt(b(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(d?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(b(c).css("borderTopWidth"),10)||0)-(parseInt(b(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];
+this.relative_container=a}}else a.containment.constructor==Array&&(this.containment=a.containment)},_convertPositionTo:function(a,c){c||(c=this.position);var d="absolute"==a?1:-1,g="absolute"==this.cssPosition&&!(this.scrollParent[0]!=document&&b.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,h=/(html|body)/i.test(g[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(b.browser.safari&&526>b.browser.version&&"fixed"==this.cssPosition?
+0:("fixed"==this.cssPosition?-this.scrollParent.scrollTop():h?0:g.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(b.browser.safari&&526>b.browser.version&&"fixed"==this.cssPosition?0:("fixed"==this.cssPosition?-this.scrollParent.scrollLeft():h?0:g.scrollLeft())*d)}},_generatePosition:function(a){var c=this.options,d="absolute"==this.cssPosition&&!(this.scrollParent[0]!=document&&b.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,
+g=/(html|body)/i.test(d[0].tagName),h=a.pageX,e=a.pageY;if(this.originalPosition){var f;this.containment&&(this.relative_container?(f=this.relative_container.offset(),f=[this.containment[0]+f.left,this.containment[1]+f.top,this.containment[2]+f.left,this.containment[3]+f.top]):f=this.containment,a.pageX-this.offset.click.left<f[0]&&(h=f[0]+this.offset.click.left),a.pageY-this.offset.click.top<f[1]&&(e=f[1]+this.offset.click.top),a.pageX-this.offset.click.left>f[2]&&(h=f[2]+this.offset.click.left),
+a.pageY-this.offset.click.top>f[3]&&(e=f[3]+this.offset.click.top));c.grid&&(e=c.grid[1]?this.originalPageY+Math.round((e-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY,e=f?!(e-this.offset.click.top<f[1]||e-this.offset.click.top>f[3])?e:!(e-this.offset.click.top<f[1])?e-c.grid[1]:e+c.grid[1]:e,h=c.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/c.grid[0])*c.grid[0]:this.originalPageX,h=f?!(h-this.offset.click.left<f[0]||h-this.offset.click.left>f[2])?h:!(h-this.offset.click.left<
+f[0])?h-c.grid[0]:h+c.grid[0]:h)}return{top:e-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(b.browser.safari&&526>b.browser.version&&"fixed"==this.cssPosition?0:"fixed"==this.cssPosition?-this.scrollParent.scrollTop():g?0:d.scrollTop()),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(b.browser.safari&&526>b.browser.version&&"fixed"==this.cssPosition?0:"fixed"==this.cssPosition?-this.scrollParent.scrollLeft():g?0:d.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");
+this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=!1},_trigger:function(a,c,d){d=d||this._uiHash();b.ui.plugin.call(this,a,[c,d]);"drag"==a&&(this.positionAbs=this._convertPositionTo("absolute"));return b.Widget.prototype._trigger.call(this,a,c,d)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});b.extend(b.ui.draggable,{version:"1.8.14"});
+b.ui.plugin.add("draggable","connectToSortable",{start:function(a,c){var d=b(this).data("draggable"),g=d.options,h=b.extend({},c,{item:d.element});d.sortables=[];b(g.connectToSortable).each(function(){var c=b.data(this,"sortable");c&&!c.options.disabled&&(d.sortables.push({instance:c,shouldRevert:c.options.revert}),c.refreshPositions(),c._trigger("activate",a,h))})},stop:function(a,c){var d=b(this).data("draggable"),g=b.extend({},c,{item:d.element});b.each(d.sortables,function(){this.instance.isOver?
+(this.instance.isOver=0,d.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(a),this.instance.options.helper=this.instance.options._helper,"original"==d.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",a,g))})},drag:function(a,c){var d=b(this).data("draggable"),g=this;b.each(d.sortables,function(){this.instance.positionAbs=
+d.positionAbs;this.instance.helperProportions=d.helperProportions;this.instance.offset.click=d.offset.click;this.instance._intersectsWith(this.instance.containerCache)?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=b(g).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return c.helper[0]},a.target=this.instance.currentItem[0],this.instance._mouseCapture(a,
+!0),this.instance._mouseStart(a,!0,!0),this.instance.offset.click.top=d.offset.click.top,this.instance.offset.click.left=d.offset.click.left,this.instance.offset.parent.left-=d.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=d.offset.parent.top-this.instance.offset.parent.top,d._trigger("toSortable",a),d.dropped=this.instance.element,d.currentItem=d.element,this.instance.fromOutside=d),this.instance.currentItem&&this.instance._mouseDrag(a)):this.instance.isOver&&
+(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",a,this.instance._uiHash(this.instance)),this.instance._mouseStop(a,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),d._trigger("fromSortable",a),d.dropped=!1)})}});b.ui.plugin.add("draggable","cursor",{start:function(){var a=b("body"),c=b(this).data("draggable").options;
+a.css("cursor")&&(c._cursor=a.css("cursor"));a.css("cursor",c.cursor)},stop:function(){var a=b(this).data("draggable").options;a._cursor&&b("body").css("cursor",a._cursor)}});b.ui.plugin.add("draggable","opacity",{start:function(a,c){var d=b(c.helper),g=b(this).data("draggable").options;d.css("opacity")&&(g._opacity=d.css("opacity"));d.css("opacity",g.opacity)},stop:function(a,c){var d=b(this).data("draggable").options;d._opacity&&b(c.helper).css("opacity",d._opacity)}});b.ui.plugin.add("draggable",
+"scroll",{start:function(){var a=b(this).data("draggable");a.scrollParent[0]!=document&&"HTML"!=a.scrollParent[0].tagName&&(a.overflowOffset=a.scrollParent.offset())},drag:function(a){var c=b(this).data("draggable"),d=c.options,g=!1;if(c.scrollParent[0]!=document&&"HTML"!=c.scrollParent[0].tagName){if(!d.axis||"x"!=d.axis)c.overflowOffset.top+c.scrollParent[0].offsetHeight-a.pageY<d.scrollSensitivity?c.scrollParent[0].scrollTop=g=c.scrollParent[0].scrollTop+d.scrollSpeed:a.pageY-c.overflowOffset.top<
+d.scrollSensitivity&&(c.scrollParent[0].scrollTop=g=c.scrollParent[0].scrollTop-d.scrollSpeed);if(!d.axis||"y"!=d.axis)c.overflowOffset.left+c.scrollParent[0].offsetWidth-a.pageX<d.scrollSensitivity?c.scrollParent[0].scrollLeft=g=c.scrollParent[0].scrollLeft+d.scrollSpeed:a.pageX-c.overflowOffset.left<d.scrollSensitivity&&(c.scrollParent[0].scrollLeft=g=c.scrollParent[0].scrollLeft-d.scrollSpeed)}else{if(!d.axis||"x"!=d.axis)a.pageY-b(document).scrollTop()<d.scrollSensitivity?g=b(document).scrollTop(b(document).scrollTop()-
+d.scrollSpeed):b(window).height()-(a.pageY-b(document).scrollTop())<d.scrollSensitivity&&(g=b(document).scrollTop(b(document).scrollTop()+d.scrollSpeed));if(!d.axis||"y"!=d.axis)a.pageX-b(document).scrollLeft()<d.scrollSensitivity?g=b(document).scrollLeft(b(document).scrollLeft()-d.scrollSpeed):b(window).width()-(a.pageX-b(document).scrollLeft())<d.scrollSensitivity&&(g=b(document).scrollLeft(b(document).scrollLeft()+d.scrollSpeed))}!1!==g&&(b.ui.ddmanager&&!d.dropBehaviour)&&b.ui.ddmanager.prepareOffsets(c,
+a)}});b.ui.plugin.add("draggable","snap",{start:function(){var a=b(this).data("draggable"),c=a.options;a.snapElements=[];b(c.snap.constructor!=String?c.snap.items||":data(draggable)":c.snap).each(function(){var c=b(this),g=c.offset();this!=a.element[0]&&a.snapElements.push({item:this,width:c.outerWidth(),height:c.outerHeight(),top:g.top,left:g.left})})},drag:function(a,c){for(var d=b(this).data("draggable"),g=d.options,h=g.snapTolerance,e=c.offset.left,f=e+d.helperProportions.width,i=c.offset.top,
+j=i+d.helperProportions.height,k=d.snapElements.length-1;0<=k;k--){var l=d.snapElements[k].left,m=l+d.snapElements[k].width,p=d.snapElements[k].top,n=p+d.snapElements[k].height;if(l-h<e&&e<m+h&&p-h<i&&i<n+h||l-h<e&&e<m+h&&p-h<j&&j<n+h||l-h<f&&f<m+h&&p-h<i&&i<n+h||l-h<f&&f<m+h&&p-h<j&&j<n+h){if("inner"!=g.snapMode){var q=Math.abs(p-j)<=h,o=Math.abs(n-i)<=h,w=Math.abs(l-f)<=h,r=Math.abs(m-e)<=h;q&&(c.position.top=d._convertPositionTo("relative",{top:p-d.helperProportions.height,left:0}).top-d.margins.top);
+o&&(c.position.top=d._convertPositionTo("relative",{top:n,left:0}).top-d.margins.top);w&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l-d.helperProportions.width}).left-d.margins.left);r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m}).left-d.margins.left)}var u=q||o||w||r;if("outer"!=g.snapMode&&(q=Math.abs(p-i)<=h,o=Math.abs(n-j)<=h,w=Math.abs(l-e)<=h,r=Math.abs(m-f)<=h,q&&(c.position.top=d._convertPositionTo("relative",{top:p,left:0}).top-d.margins.top),o&&(c.position.top=
+d._convertPositionTo("relative",{top:n-d.helperProportions.height,left:0}).top-d.margins.top),w&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l}).left-d.margins.left),r))c.position.left=d._convertPositionTo("relative",{top:0,left:m-d.helperProportions.width}).left-d.margins.left;!d.snapElements[k].snapping&&(q||o||w||r||u)&&d.options.snap.snap&&d.options.snap.snap.call(d.element,a,b.extend(d._uiHash(),{snapItem:d.snapElements[k].item}));d.snapElements[k].snapping=q||o||w||r||u}else d.snapElements[k].snapping&&
+d.options.snap.release&&d.options.snap.release.call(d.element,a,b.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=!1}}});b.ui.plugin.add("draggable","stack",{start:function(){var a=b(this).data("draggable").options,a=b.makeArray(b(a.stack)).sort(function(c,a){return(parseInt(b(c).css("zIndex"),10)||0)-(parseInt(b(a).css("zIndex"),10)||0)});if(a.length){var c=parseInt(a[0].style.zIndex)||0;b(a).each(function(b){this.style.zIndex=c+b});this[0].style.zIndex=c+a.length}}});
+b.ui.plugin.add("draggable","zIndex",{start:function(a,c){var d=b(c.helper),g=b(this).data("draggable").options;d.css("zIndex")&&(g._zIndex=d.css("zIndex"));d.css("zIndex",g.zIndex)},stop:function(a,c){var d=b(this).data("draggable").options;d._zIndex&&b(c.helper).css("zIndex",d._zIndex)}})})(jQuery);
+(function(b){b.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect"},_create:function(){var a=this.options,c=a.accept;this.isover=0;this.isout=1;this.accept=b.isFunction(c)?c:function(b){return b.is(c)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};b.ui.ddmanager.droppables[a.scope]=b.ui.ddmanager.droppables[a.scope]||[];b.ui.ddmanager.droppables[a.scope].push(this);
+a.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){for(var a=b.ui.ddmanager.droppables[this.options.scope],c=0;c<a.length;c++)a[c]==this&&a.splice(c,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(a,c){"accept"==a&&(this.accept=b.isFunction(c)?c:function(b){return b.is(c)});b.Widget.prototype._setOption.apply(this,arguments)},_activate:function(a){var c=b.ui.ddmanager.current;this.options.activeClass&&
+this.element.addClass(this.options.activeClass);c&&this._trigger("activate",a,this.ui(c))},_deactivate:function(a){var c=b.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass);c&&this._trigger("deactivate",a,this.ui(c))},_over:function(a){var c=b.ui.ddmanager.current;if(c&&(c.currentItem||c.element)[0]!=this.element[0])if(this.accept.call(this.element[0],c.currentItem||c.element))this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",
+a,this.ui(c))},_out:function(a){var c=b.ui.ddmanager.current;if(c&&(c.currentItem||c.element)[0]!=this.element[0])if(this.accept.call(this.element[0],c.currentItem||c.element))this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",a,this.ui(c))},_drop:function(a,c){var d=c||b.ui.ddmanager.current;if(!d||(d.currentItem||d.element)[0]==this.element[0])return!1;var g=!1;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var c=b.data(this,
+"droppable");if(c.options.greedy&&!c.options.disabled&&c.options.scope==d.options.scope&&c.accept.call(c.element[0],d.currentItem||d.element)&&b.ui.intersect(d,b.extend(c,{offset:c.element.offset()}),c.options.tolerance))return g=!0,!1});return g?!1:this.accept.call(this.element[0],d.currentItem||d.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",a,this.ui(d)),this.element):
+!1},ui:function(b){return{draggable:b.currentItem||b.element,helper:b.helper,position:b.position,offset:b.positionAbs}}});b.extend(b.ui.droppable,{version:"1.8.14"});b.ui.intersect=function(a,c,d){if(!c.offset)return!1;var g=(a.positionAbs||a.position.absolute).left,h=g+a.helperProportions.width,e=(a.positionAbs||a.position.absolute).top,f=e+a.helperProportions.height,i=c.offset.left,j=i+c.proportions.width,k=c.offset.top,l=k+c.proportions.height;switch(d){case "fit":return i<=g&&h<=j&&k<=e&&f<=l;
+case "intersect":return i<g+a.helperProportions.width/2&&h-a.helperProportions.width/2<j&&k<e+a.helperProportions.height/2&&f-a.helperProportions.height/2<l;case "pointer":return b.ui.isOver((a.positionAbs||a.position.absolute).top+(a.clickOffset||a.offset.click).top,(a.positionAbs||a.position.absolute).left+(a.clickOffset||a.offset.click).left,k,i,c.proportions.height,c.proportions.width);case "touch":return(e>=k&&e<=l||f>=k&&f<=l||e<k&&f>l)&&(g>=i&&g<=j||h>=i&&h<=j||g<i&&h>j);default:return!1}};
+b.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,c){var d=b.ui.ddmanager.droppables[a.options.scope]||[],g=c?c.type:null,h=(a.currentItem||a.element).find(":data(droppable)").andSelf(),e=0;a:for(;e<d.length;e++)if(!(d[e].options.disabled||a&&!d[e].accept.call(d[e].element[0],a.currentItem||a.element))){for(var f=0;f<h.length;f++)if(h[f]==d[e].element[0]){d[e].proportions.height=0;continue a}d[e].visible="none"!=d[e].element.css("display");d[e].visible&&("mousedown"==
+g&&d[e]._activate.call(d[e],c),d[e].offset=d[e].element.offset(),d[e].proportions={width:d[e].element[0].offsetWidth,height:d[e].element[0].offsetHeight})}},drop:function(a,c){var d=!1;b.each(b.ui.ddmanager.droppables[a.options.scope]||[],function(){if(this.options&&(!this.options.disabled&&(this.visible&&b.ui.intersect(a,this,this.options.tolerance))&&(d=d||this._drop.call(this,c)),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],a.currentItem||a.element)))this.isout=1,this.isover=
+0,this._deactivate.call(this,c)});return d},dragStart:function(a,c){a.element.parentsUntil("body").bind("scroll.droppable",function(){a.options.refreshPositions||b.ui.ddmanager.prepareOffsets(a,c)})},drag:function(a,c){a.options.refreshPositions&&b.ui.ddmanager.prepareOffsets(a,c);b.each(b.ui.ddmanager.droppables[a.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var d=b.ui.intersect(a,this,this.options.tolerance);if(d=!d&&1==this.isover?"isout":d&&0==this.isover?
+"isover":null){var g;if(this.options.greedy){var h=this.element.parents(":data(droppable):eq(0)");h.length&&(g=b.data(h[0],"droppable"),g.greedyChild="isover"==d?1:0)}g&&"isover"==d&&(g.isover=0,g.isout=1,g._out.call(g,c));this[d]=1;this["isout"==d?"isover":"isout"]=0;this["isover"==d?"_over":"_out"].call(this,c);g&&"isout"==d&&(g.isout=0,g.isover=1,g._over.call(g,c))}}})},dragStop:function(a,c){a.element.parentsUntil("body").unbind("scroll.droppable");a.options.refreshPositions||b.ui.ddmanager.prepareOffsets(a,
+c)}}})(jQuery);
+(function(b){b.widget("ui.resizable",b.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var c=this,a=this.options;this.element.addClass("ui-resizable");b.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],
+_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(/relative/.test(this.element.css("position"))&&b.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"}),this.element.wrap(b('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),
+this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize",
+"none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize());this.handles=a.handles||(!b(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){"all"==
+this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw");var h=this.handles.split(",");this.handles={};for(var e=0;e<h.length;e++){var f=b.trim(h[e]),i=b('<div class="ui-resizable-handle ui-resizable-'+f+'"></div>');/sw|se|ne|nw/.test(f)&&i.css({zIndex:++a.zIndex});"se"==f&&i.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(i)}}this._renderAxis=function(f){var f=f||this.element,c;for(c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=
+b(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var a=b(this.handles[c],this.element),d=0,d=/sw|ne|nw|se|n|s/.test(c)?a.outerHeight():a.outerWidth(),a=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");f.css(a,d);this._proportionallyResize()}b(this.handles[c])}};this._renderAxis(this.element);this._handles=b(".ui-resizable-handle",this.element).disableSelection();
+this._handles.mouseover(function(){if(!c.resizing){if(this.className)var b=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);c.axis=b&&b[1]?b[1]:"se"}});a.autoHide&&(this._handles.hide(),b(this.element).addClass("ui-resizable-autohide").hover(function(){if(!a.disabled){b(this).removeClass("ui-resizable-autohide");c._handles.show()}},function(){if(!a.disabled&&!c.resizing){b(this).addClass("ui-resizable-autohide");c._handles.hide()}}));this._mouseInit()},destroy:function(){this._mouseDestroy();
+var c=function(c){b(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){c(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);c(this.originalElement);return this},_mouseCapture:function(c){var a=
+!1,h;for(h in this.handles)b(this.handles[h])[0]==c.target&&(a=!0);return!this.options.disabled&&a},_mouseStart:function(c){var g=this.options,h=this.element.position(),e=this.element;this.resizing=!0;this.documentScroll={top:b(document).scrollTop(),left:b(document).scrollLeft()};(e.is(".ui-draggable")||/absolute/.test(e.css("position")))&&e.css({position:"absolute",top:h.top,left:h.left});b.browser.opera&&/relative/.test(e.css("position"))&&e.css({position:"relative",top:"auto",left:"auto"});this._renderProxy();
+var h=a(this.helper.css("left")),f=a(this.helper.css("top"));g.containment&&(h+=b(g.containment).scrollLeft()||0,f+=b(g.containment).scrollTop()||0);this.offset=this.helper.offset();this.position={left:h,top:f};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:h,top:f};this.sizeDiff={width:e.outerWidth()-
+e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:c.pageX,top:c.pageY};this.aspectRatio="number"==typeof g.aspectRatio?g.aspectRatio:this.originalSize.width/this.originalSize.height||1;g=b(".ui-resizable-"+this.axis).css("cursor");b("body").css("cursor","auto"==g?this.axis+"-resize":g);e.addClass("ui-resizable-resizing");this._propagate("start",c);return!0},_mouseDrag:function(b){var c=this.helper,a=this.originalMousePosition,e=this._change[this.axis];if(!e)return!1;a=
+e.apply(this,[b,b.pageX-a.left||0,b.pageY-a.top||0]);this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)a=this._updateRatio(a,b);a=this._respectSize(a,b);this._propagate("resize",b);c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(a);this._trigger("resize",b,this.ui());return!1},_mouseStop:function(c){this.resizing=
+!1;var a=this.options;if(this._helper){var h=this._proportionallyResizeElements,e=h.length&&/textarea/i.test(h[0].nodeName),h=e&&b.ui.hasScroll(h[0],"left")?0:this.sizeDiff.height,e=e?0:this.sizeDiff.width,e={width:this.helper.width()-e,height:this.helper.height()-h},h=parseInt(this.element.css("left"),10)+(this.position.left-this.originalPosition.left)||null,f=parseInt(this.element.css("top"),10)+(this.position.top-this.originalPosition.top)||null;a.animate||this.element.css(b.extend(e,{top:f,left:h}));
+this.helper.height(this.size.height);this.helper.width(this.size.width);this._helper&&!a.animate&&this._proportionallyResize()}b("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",c);this._helper&&this.helper.remove();return!1},_updateVirtualBoundaries:function(b){var a=this.options,h,e,f,a={minWidth:c(a.minWidth)?a.minWidth:0,maxWidth:c(a.maxWidth)?a.maxWidth:Infinity,minHeight:c(a.minHeight)?a.minHeight:0,maxHeight:c(a.maxHeight)?a.maxHeight:Infinity};
+if(this._aspectRatio||b)if(b=a.minHeight*this.aspectRatio,e=a.minWidth/this.aspectRatio,h=a.maxHeight*this.aspectRatio,f=a.maxWidth/this.aspectRatio,b>a.minWidth&&(a.minWidth=b),e>a.minHeight&&(a.minHeight=e),h<a.maxWidth&&(a.maxWidth=h),f<a.maxHeight)a.maxHeight=f;this._vBoundaries=a},_updateCache:function(b){this.offset=this.helper.offset();c(b.left)&&(this.position.left=b.left);c(b.top)&&(this.position.top=b.top);c(b.height)&&(this.size.height=b.height);c(b.width)&&(this.size.width=b.width)},_updateRatio:function(b){var a=
+this.position,h=this.size,e=this.axis;c(b.height)?b.width=b.height*this.aspectRatio:c(b.width)&&(b.height=b.width/this.aspectRatio);"sw"==e&&(b.left=a.left+(h.width-b.width),b.top=null);"nw"==e&&(b.top=a.top+(h.height-b.height),b.left=a.left+(h.width-b.width));return b},_respectSize:function(b){var a=this._vBoundaries,h=this.axis,e=c(b.width)&&a.maxWidth&&a.maxWidth<b.width,f=c(b.height)&&a.maxHeight&&a.maxHeight<b.height,i=c(b.width)&&a.minWidth&&a.minWidth>b.width,j=c(b.height)&&a.minHeight&&a.minHeight>
+b.height;i&&(b.width=a.minWidth);j&&(b.height=a.minHeight);e&&(b.width=a.maxWidth);f&&(b.height=a.maxHeight);var k=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,m=/sw|nw|w/.test(h),h=/nw|ne|n/.test(h);i&&m&&(b.left=k-a.minWidth);e&&m&&(b.left=k-a.maxWidth);j&&h&&(b.top=l-a.minHeight);f&&h&&(b.top=l-a.maxHeight);(a=!b.width&&!b.height)&&!b.left&&b.top?b.top=null:a&&(!b.top&&b.left)&&(b.left=null);return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var c=
+this.helper||this.element,a=0;a<this._proportionallyResizeElements.length;a++){var h=this._proportionallyResizeElements[a];if(!this.borderDif){var e=[h.css("borderTopWidth"),h.css("borderRightWidth"),h.css("borderBottomWidth"),h.css("borderLeftWidth")],f=[h.css("paddingTop"),h.css("paddingRight"),h.css("paddingBottom"),h.css("paddingLeft")];this.borderDif=b.map(e,function(b,c){var a=parseInt(b,10)||0,d=parseInt(f[c],10)||0;return a+d})}if(!b.browser.msie||!b(c).is(":hidden")&&!b(c).parents(":hidden").length)h.css({height:c.height()-
+this.borderDif[0]-this.borderDif[2]||0,width:c.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var c=this.options;this.elementOffset=this.element.offset();if(this._helper){this.helper=this.helper||b('<div style="overflow:hidden;"></div>');var a=b.browser.msie&&7>b.browser.version,h=a?1:0,a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-h+"px",top:this.elementOffset.top-
+h+"px",zIndex:++c.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,c){return{width:this.originalSize.width+c}},w:function(b,c){return{left:this.originalPosition.left+c,width:this.originalSize.width-c}},n:function(b,c,a){return{top:this.originalPosition.top+a,height:this.originalSize.height-a}},s:function(b,c,a){return{height:this.originalSize.height+a}},se:function(c,a,h){return b.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,
+[c,a,h]))},sw:function(c,a,h){return b.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[c,a,h]))},ne:function(c,a,h){return b.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[c,a,h]))},nw:function(c,a,h){return b.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[c,a,h]))}},_propagate:function(c,a){b.ui.plugin.call(this,c,[a,this.ui()]);"resize"!=c&&this._trigger(c,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,
+element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});b.extend(b.ui.resizable,{version:"1.8.14"});b.ui.plugin.add("resizable","alsoResize",{start:function(){var c=b(this).data("resizable").options,a=function(c){b(c).each(function(){var c=b(this);c.data("resizable-alsoresize",{width:parseInt(c.width(),10),height:parseInt(c.height(),10),left:parseInt(c.css("left"),10),top:parseInt(c.css("top"),10),position:c.css("position")})})};
+"object"==typeof c.alsoResize&&!c.alsoResize.parentNode?c.alsoResize.length?(c.alsoResize=c.alsoResize[0],a(c.alsoResize)):b.each(c.alsoResize,function(b){a(b)}):a(c.alsoResize)},resize:function(c,a){var h=b(this).data("resizable"),e=h.options,f=h.originalSize,i=h.originalPosition,j={height:h.size.height-f.height||0,width:h.size.width-f.width||0,top:h.position.top-i.top||0,left:h.position.left-i.left||0},k=function(c,f){b(c).each(function(){var c=b(this),d=b(this).data("resizable-alsoresize"),i={},
+e=f&&f.length?f:c.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];b.each(e,function(b,c){var a=(d[c]||0)+(j[c]||0);a&&0<=a&&(i[c]=a||null)});b.browser.opera&&/relative/.test(c.css("position"))&&(h._revertToRelativePosition=!0,c.css({position:"absolute",top:"auto",left:"auto"}));c.css(i)})};"object"==typeof e.alsoResize&&!e.alsoResize.nodeType?b.each(e.alsoResize,function(b,c){k(b,c)}):k(e.alsoResize)},stop:function(){var c=b(this).data("resizable"),a=c.options,
+h=function(c){b(c).each(function(){var c=b(this);c.css({position:c.data("resizable-alsoresize").position})})};c._revertToRelativePosition&&(c._revertToRelativePosition=!1,"object"==typeof a.alsoResize&&!a.alsoResize.nodeType?b.each(a.alsoResize,function(b){h(b)}):h(a.alsoResize));b(this).removeData("resizable-alsoresize")}});b.ui.plugin.add("resizable","animate",{stop:function(c){var a=b(this).data("resizable"),h=a.options,e=a._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),
+i=f&&b.ui.hasScroll(e[0],"left")?0:a.sizeDiff.height,f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-i},i=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null,j=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(b.extend(f,j&&i?{top:j,left:i}:{}),{duration:h.animateDuration,easing:h.animateEasing,step:function(){var f={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),
+top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};e&&e.length&&b(e[0]).css({width:f.width,height:f.height});a._updateCache(f);a._propagate("resize",c)}})}});b.ui.plugin.add("resizable","containment",{start:function(){var c=b(this).data("resizable"),g=c.element,h=c.options.containment;if(g=h instanceof b?h.get(0):/parent/.test(h)?g.parent().get(0):h)if(c.containerElement=b(g),/document/.test(h)||h==document)c.containerOffset={left:0,top:0},c.containerPosition={left:0,top:0},
+c.parentData={element:b(document),left:0,top:0,width:b(document).width(),height:b(document).height()||document.body.parentNode.scrollHeight};else{var e=b(g),f=[];b(["Top","Right","Left","Bottom"]).each(function(b,c){f[b]=a(e.css("padding"+c))});c.containerOffset=e.offset();c.containerPosition=e.position();c.containerSize={height:e.innerHeight()-f[3],width:e.innerWidth()-f[1]};var h=c.containerOffset,i=c.containerSize.height,j=c.containerSize.width,j=b.ui.hasScroll(g,"left")?g.scrollWidth:j,i=b.ui.hasScroll(g)?
+g.scrollHeight:i;c.parentData={element:g,left:h.left,top:h.top,width:j,height:i}}},resize:function(c){var a=b(this).data("resizable"),h=a.options,e=a.containerOffset,f=a.position,c=a._aspectRatio||c.shiftKey,i={top:0,left:0},j=a.containerElement;j[0]!=document&&/static/.test(j.css("position"))&&(i=e);if(f.left<(a._helper?e.left:0))a.size.width+=a._helper?a.position.left-e.left:a.position.left-i.left,c&&(a.size.height=a.size.width/h.aspectRatio),a.position.left=h.helper?e.left:0;if(f.top<(a._helper?
+e.top:0))a.size.height+=a._helper?a.position.top-e.top:a.position.top,c&&(a.size.width=a.size.height*h.aspectRatio),a.position.top=a._helper?e.top:0;a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;h=Math.abs(a.offset.left-i.left+a.sizeDiff.width);e=Math.abs((a._helper?a.offset.top-i.top:a.offset.top-e.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);i=/relative|absolute/.test(a.containerElement.css("position"));f&&i&&(h-=a.parentData.left);
+h+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-h,c&&(a.size.height=a.size.width/a.aspectRatio));e+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-e,c&&(a.size.width=a.size.height*a.aspectRatio))},stop:function(){var a=b(this).data("resizable"),c=a.options,h=a.containerOffset,e=a.containerPosition,f=a.containerElement,i=b(a.helper),j=i.offset(),k=i.outerWidth()-a.sizeDiff.width,i=i.outerHeight()-a.sizeDiff.height;a._helper&&(!c.animate&&/relative/.test(f.css("position")))&&
+b(this).css({left:j.left-e.left-h.left,width:k,height:i});a._helper&&(!c.animate&&/static/.test(f.css("position")))&&b(this).css({left:j.left-e.left-h.left,width:k,height:i})}});b.ui.plugin.add("resizable","ghost",{start:function(){var a=b(this).data("resizable"),c=a.options,h=a.size;a.ghost=a.originalElement.clone();a.ghost.css({opacity:0.25,display:"block",position:"relative",height:h.height,width:h.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof c.ghost?c.ghost:
+"");a.ghost.appendTo(a.helper)},resize:function(){var a=b(this).data("resizable");a.ghost&&a.ghost.css({position:"relative",height:a.size.height,width:a.size.width})},stop:function(){var a=b(this).data("resizable");a.ghost&&a.helper&&a.helper.get(0).removeChild(a.ghost.get(0))}});b.ui.plugin.add("resizable","grid",{resize:function(){var a=b(this).data("resizable"),c=a.options,h=a.size,e=a.originalSize,f=a.originalPosition,i=a.axis;c.grid="number"==typeof c.grid?[c.grid,c.grid]:c.grid;var j=Math.round((h.width-
+e.width)/(c.grid[0]||1))*(c.grid[0]||1),c=Math.round((h.height-e.height)/(c.grid[1]||1))*(c.grid[1]||1);/^(se|s|e)$/.test(i)?(a.size.width=e.width+j,a.size.height=e.height+c):/^(ne)$/.test(i)?(a.size.width=e.width+j,a.size.height=e.height+c,a.position.top=f.top-c):(/^(sw)$/.test(i)?(a.size.width=e.width+j,a.size.height=e.height+c):(a.size.width=e.width+j,a.size.height=e.height+c,a.position.top=f.top-c),a.position.left=f.left-j)}});var a=function(b){return parseInt(b,10)||0},c=function(b){return!isNaN(parseInt(b,
+10))}})(jQuery);
+(function(b){b.widget("ui.selectable",b.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var a=this;this.element.addClass("ui-selectable");this.dragged=!1;var c;this.refresh=function(){c=b(a.options.filter,a.element[0]);c.each(function(){var a=b(this),c=a.offset();b.data(this,"selectable-item",{element:this,$element:a,left:c.left,top:c.top,right:c.left+a.outerWidth(),bottom:c.top+a.outerHeight(),startselected:!1,selected:a.hasClass("ui-selected"),selecting:a.hasClass("ui-selecting"),
+unselecting:a.hasClass("ui-unselecting")})})};this.refresh();this.selectees=c.addClass("ui-selectee");this._mouseInit();this.helper=b("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(a){var c=this;this.opos=[a.pageX,a.pageY];if(!this.options.disabled){var d=
+this.options;this.selectees=b(d.filter,this.element[0]);this._trigger("start",a);b(d.appendTo).append(this.helper);this.helper.css({left:a.clientX,top:a.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var d=b.data(this,"selectable-item");d.startselected=!0;a.metaKey||(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",a,{unselecting:d.element}))});b(a.target).parents().andSelf().each(function(){var d=
+b.data(this,"selectable-item");if(d){var h=!a.metaKey||!d.$element.hasClass("ui-selected");d.$element.removeClass(h?"ui-unselecting":"ui-selected").addClass(h?"ui-selecting":"ui-unselecting");d.unselecting=!h;d.selecting=h;(d.selected=h)?c._trigger("selecting",a,{selecting:d.element}):c._trigger("unselecting",a,{unselecting:d.element});return!1}})}},_mouseDrag:function(a){var c=this;this.dragged=!0;if(!this.options.disabled){var d=this.options,g=this.opos[0],h=this.opos[1],e=a.pageX,f=a.pageY;if(g>
+e)var i=e,e=g,g=i;h>f&&(i=f,f=h,h=i);this.helper.css({left:g,top:h,width:e-g,height:f-h});this.selectees.each(function(){var i=b.data(this,"selectable-item");if(i&&i.element!=c.element[0]){var k=false;d.tolerance=="touch"?k=!(i.left>e||i.right<g||i.top>f||i.bottom<h):d.tolerance=="fit"&&(k=i.left>g&&i.right<e&&i.top>h&&i.bottom<f);if(k){if(i.selected){i.$element.removeClass("ui-selected");i.selected=false}if(i.unselecting){i.$element.removeClass("ui-unselecting");i.unselecting=false}if(!i.selecting){i.$element.addClass("ui-selecting");
+i.selecting=true;c._trigger("selecting",a,{selecting:i.element})}}else{if(i.selecting)if(a.metaKey&&i.startselected){i.$element.removeClass("ui-selecting");i.selecting=false;i.$element.addClass("ui-selected");i.selected=true}else{i.$element.removeClass("ui-selecting");i.selecting=false;if(i.startselected){i.$element.addClass("ui-unselecting");i.unselecting=true}c._trigger("unselecting",a,{unselecting:i.element})}if(i.selected&&!a.metaKey&&!i.startselected){i.$element.removeClass("ui-selected");i.selected=
+false;i.$element.addClass("ui-unselecting");i.unselecting=true;c._trigger("unselecting",a,{unselecting:i.element})}}}});return!1}},_mouseStop:function(a){var c=this;this.dragged=!1;b(".ui-unselecting",this.element[0]).each(function(){var d=b.data(this,"selectable-item");d.$element.removeClass("ui-unselecting");d.unselecting=!1;d.startselected=!1;c._trigger("unselected",a,{unselected:d.element})});b(".ui-selecting",this.element[0]).each(function(){var d=b.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected");
+d.selecting=!1;d.selected=!0;d.startselected=!0;c._trigger("selected",a,{selected:d.element})});this._trigger("stop",a);this.helper.remove();return!1}});b.extend(b.ui.selectable,{version:"1.8.14"})})(jQuery);
+(function(b){b.widget("ui.sortable",b.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var b=this.options;this.containerCache={};this.element.addClass("ui-sortable");this.refresh();
+this.floating=this.items.length?"x"===b.axis||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var b=this.items.length-1;0<=b;b--)this.items[b].item.removeData("sortable-item");return this},_setOption:function(a,c){"disabled"===a?(this.options[a]=
+c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):b.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,c){if(this.reverting||this.options.disabled||"static"==this.options.type)return!1;this._refreshItems(a);var d=null,g=this;b(a.target).parents().each(function(){if(b.data(this,"sortable-item")==g)return d=b(this),!1});b.data(a.target,"sortable-item")==g&&(d=b(a.target));if(!d)return!1;if(this.options.handle&&!c){var h=!1;b(this.options.handle,d).find("*").andSelf().each(function(){this==
+a.target&&(h=!0)});if(!h)return!1}this.currentItem=d;this._removeCurrentsFromItems();return!0},_mouseStart:function(a,c,d){c=this.options;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=
+this.helper.css("position");b.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();
+c.containment&&this._setContainment();c.cursor&&(b("body").css("cursor")&&(this._storedCursor=b("body").css("cursor")),b("body").css("cursor",c.cursor));c.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",c.opacity));c.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",c.zIndex));this.scrollParent[0]!=document&&"HTML"!=this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset());
+this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(d=this.containers.length-1;0<=d;d--)this.containers[d]._trigger("activate",a,this._uiHash(this));b.ui.ddmanager&&(b.ui.ddmanager.current=this);b.ui.ddmanager&&!c.dropBehaviour&&b.ui.ddmanager.prepareOffsets(this,a);this.dragging=!0;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a);return!0},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");
+this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&"HTML"!=this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY<c.scrollSensitivity?this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop+c.scrollSpeed:a.pageY-this.overflowOffset.top<c.scrollSensitivity&&(this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop-c.scrollSpeed),this.overflowOffset.left+
+this.scrollParent[0].offsetWidth-a.pageX<c.scrollSensitivity)?this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft+c.scrollSpeed:a.pageX-this.overflowOffset.left<c.scrollSensitivity&&(this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft-c.scrollSpeed):(a.pageY-b(document).scrollTop()<c.scrollSensitivity?d=b(document).scrollTop(b(document).scrollTop()-c.scrollSpeed):b(window).height()-(a.pageY-b(document).scrollTop())<c.scrollSensitivity&&(d=b(document).scrollTop(b(document).scrollTop()+
+c.scrollSpeed)),a.pageX-b(document).scrollLeft()<c.scrollSensitivity?d=b(document).scrollLeft(b(document).scrollLeft()-c.scrollSpeed):b(window).width()-(a.pageX-b(document).scrollLeft())<c.scrollSensitivity&&(d=b(document).scrollLeft(b(document).scrollLeft()+c.scrollSpeed)));!1!==d&&(b.ui.ddmanager&&!c.dropBehaviour)&&b.ui.ddmanager.prepareOffsets(this,a)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||"y"!=this.options.axis)this.helper[0].style.left=this.position.left+
+"px";if(!this.options.axis||"x"!=this.options.axis)this.helper[0].style.top=this.position.top+"px";for(c=this.items.length-1;0<=c;c--){var d=this.items[c],g=d.item[0],h=this._intersectsWithPointer(d);if(h&&g!=this.currentItem[0]&&this.placeholder[1==h?"next":"prev"]()[0]!=g&&!b.ui.contains(this.placeholder[0],g)&&("semi-dynamic"==this.options.type?!b.ui.contains(this.element[0],g):1)){this.direction=1==h?"down":"up";if("pointer"==this.options.tolerance||this._intersectsWithSides(d))this._rearrange(a,
+d);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);b.ui.ddmanager&&b.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return!1},_mouseStop:function(a,c){if(a){b.ui.ddmanager&&!this.options.dropBehaviour&&b.ui.ddmanager.drop(this,a);if(this.options.revert){var d=this,g=d.placeholder.offset();d.reverting=!0;b(this.helper).animate({left:g.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?
+0:this.offsetParent[0].scrollLeft),top:g.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(a)})}else this._clear(a,c);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null});"original"==this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var a=this.containers.length-1;0<=a;a--)this.containers[a]._trigger("deactivate",
+null,this._uiHash(this)),this.containers[a].containerCache.over&&(this.containers[a]._trigger("out",null,this._uiHash(this)),this.containers[a].containerCache.over=0)}this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!=this.options.helper&&(this.helper&&this.helper[0].parentNode)&&this.helper.remove(),b.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?b(this.domPosition.prev).after(this.currentItem):
+b(this.domPosition.parent).prepend(this.currentItem));return this},serialize:function(a){var c=this._getItemsAsjQuery(a&&a.connected),d=[],a=a||{};b(c).each(function(){var c=(b(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);c&&d.push((a.key||c[1]+"[]")+"="+(a.key&&a.expression?c[1]:c[2]))});!d.length&&a.key&&d.push(a.key+"=");return d.join("&")},toArray:function(a){var c=this._getItemsAsjQuery(a&&a.connected),d=[],a=a||{};c.each(function(){d.push(b(a.item||this).attr(a.attribute||
+"id")||"")});return d},_intersectsWith:function(b){var c=this.positionAbs.left,d=c+this.helperProportions.width,g=this.positionAbs.top,h=g+this.helperProportions.height,e=b.left,f=e+b.width,i=b.top,j=i+b.height,k=this.offset.click.top,l=this.offset.click.left;return"pointer"==this.options.tolerance||this.options.forcePointerForContainers||"pointer"!=this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>b[this.floating?"width":"height"]?g+k>i&&g+k<j&&c+l>e&&c+l<f:e<c+this.helperProportions.width/
+2&&d-this.helperProportions.width/2<f&&i<g+this.helperProportions.height/2&&h-this.helperProportions.height/2<j},_intersectsWithPointer:function(a){var c=b.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top,a.height),a=b.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left,a.width),c=c&&a,a=this._getDragVerticalDirection(),d=this._getDragHorizontalDirection();return!c?!1:this.floating?d&&"right"==d||"down"==a?2:1:a&&("down"==a?2:1)},_intersectsWithSides:function(a){var c=
+b.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,a.top+a.height/2,a.height),a=b.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,a.left+a.width/2,a.width),d=this._getDragVerticalDirection(),g=this._getDragHorizontalDirection();return this.floating&&g?"right"==g&&a||"left"==g&&!a:d&&("down"==d&&c||"up"==d&&!c)},_getDragVerticalDirection:function(){var b=this.positionAbs.top-this.lastPositionAbs.top;return 0!=b&&(0<b?"down":"up")},_getDragHorizontalDirection:function(){var b=this.positionAbs.left-
+this.lastPositionAbs.left;return 0!=b&&(0<b?"right":"left")},refresh:function(b){this._refreshItems(b);this.refreshPositions();return this},_connectWith:function(){var b=this.options;return b.connectWith.constructor==String?[b.connectWith]:b.connectWith},_getItemsAsjQuery:function(a){var c=[],d=[],g=this._connectWith();if(g&&a)for(a=g.length-1;0<=a;a--)for(var h=b(g[a]),e=h.length-1;0<=e;e--){var f=b.data(h[e],"sortable");f&&(f!=this&&!f.options.disabled)&&d.push([b.isFunction(f.options.items)?f.options.items.call(f.element):
+b(f.options.items,f.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),f])}d.push([b.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):b(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(a=d.length-1;0<=a;a--)d[a][0].each(function(){c.push(this)});return b(c)},_removeCurrentsFromItems:function(){for(var b=this.currentItem.find(":data(sortable-item)"),c=0;c<this.items.length;c++)for(var d=
+0;d<b.length;d++)b[d]==this.items[c].item[0]&&this.items.splice(c,1)},_refreshItems:function(a){this.items=[];this.containers=[this];var c=this.items,d=[[b.isFunction(this.options.items)?this.options.items.call(this.element[0],a,{item:this.currentItem}):b(this.options.items,this.element),this]],g=this._connectWith();if(g)for(var h=g.length-1;0<=h;h--)for(var e=b(g[h]),f=e.length-1;0<=f;f--){var i=b.data(e[f],"sortable");i&&(i!=this&&!i.options.disabled)&&(d.push([b.isFunction(i.options.items)?i.options.items.call(i.element[0],
+a,{item:this.currentItem}):b(i.options.items,i.element),i]),this.containers.push(i))}for(h=d.length-1;0<=h;h--){a=d[h][1];g=d[h][0];f=0;for(e=g.length;f<e;f++)i=b(g[f]),i.data("sortable-item",a),c.push({item:i,instance:a,width:0,height:0,left:0,top:0})}},refreshPositions:function(a){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());for(var c=this.items.length-1;0<=c;c--){var d=this.items[c];if(!(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])){var g=
+this.options.toleranceElement?b(this.options.toleranceElement,d.item):d.item;a||(d.width=g.outerWidth(),d.height=g.outerHeight());g=g.offset();d.left=g.left;d.top=g.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(c=this.containers.length-1;0<=c;c--)g=this.containers[c].element.offset(),this.containers[c].containerCache.left=g.left,this.containers[c].containerCache.top=g.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),
+this.containers[c].containerCache.height=this.containers[c].element.outerHeight();return this},_createPlaceholder:function(a){var c=a||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var g=d.placeholder;d.placeholder={element:function(){var a=b(document.createElement(c.currentItem[0].nodeName)).addClass(g||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];g||(a.style.visibility="hidden");return a},update:function(b,a){if(!g||d.forcePlaceholderSize)a.height()||
+a.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),a.width()||a.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=b(d.placeholder.element.call(c.element,c.currentItem));c.currentItem.after(c.placeholder);d.placeholder.update(c,c.placeholder)},_contactContainers:function(a){for(var c=null,d=null,g=this.containers.length-
+1;0<=g;g--)if(!b.ui.contains(this.currentItem[0],this.containers[g].element[0]))if(this._intersectsWith(this.containers[g].containerCache)){if(!c||!b.ui.contains(this.containers[g].element[0],c.element[0]))c=this.containers[g],d=g}else this.containers[g].containerCache.over&&(this.containers[g]._trigger("out",a,this._uiHash(this)),this.containers[g].containerCache.over=0);if(c)if(1===this.containers.length)this.containers[d]._trigger("over",a,this._uiHash(this)),this.containers[d].containerCache.over=
+1;else if(this.currentContainer!=this.containers[d]){for(var c=1E4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"],e=this.items.length-1;0<=e;e--)if(b.ui.contains(this.containers[d].element[0],this.items[e].item[0])){var f=this.items[e][this.containers[d].floating?"left":"top"];Math.abs(f-h)<c&&(c=Math.abs(f-h),g=this.items[e])}if(g||this.options.dropOnEmpty)this.currentContainer=this.containers[d],g?this._rearrange(a,g,null,!0):this._rearrange(a,null,this.containers[d].element,
+!0),this._trigger("change",a,this._uiHash()),this.containers[d]._trigger("change",a,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[d]._trigger("over",a,this._uiHash(this)),this.containers[d].containerCache.over=1}},_createHelper:function(a){var c=this.options,a=b.isFunction(c.helper)?b(c.helper.apply(this.element[0],[a,this.currentItem])):"clone"==c.helper?this.currentItem.clone():this.currentItem;a.parents("body").length||b("parent"!=c.appendTo?
+c.appendTo:this.currentItem[0].parentNode)[0].appendChild(a[0]);a[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")});(""==a[0].style.width||c.forceHelperSize)&&a.width(this.currentItem.width());(""==a[0].style.height||c.forceHelperSize)&&a.height(this.currentItem.height());return a},_adjustOffsetFromHelper:function(a){"string"==
+typeof a&&(a=a.split(" "));b.isArray(a)&&(a={left:+a[0],top:+a[1]||0});"left"in a&&(this.offset.click.left=a.left+this.margins.left);"right"in a&&(this.offset.click.left=this.helperProportions.width-a.right+this.margins.left);"top"in a&&(this.offset.click.top=a.top+this.margins.top);"bottom"in a&&(this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();"absolute"==this.cssPosition&&
+(this.scrollParent[0]!=document&&b.ui.contains(this.scrollParent[0],this.offsetParent[0]))&&(a.left+=this.scrollParent.scrollLeft(),a.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&"html"==this.offsetParent[0].tagName.toLowerCase()&&b.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"==
+this.cssPosition){var b=this.currentItem.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},
+_setContainment:function(){var a=this.options;"parent"==a.containment&&(a.containment=this.helper[0].parentNode);if("document"==a.containment||"window"==a.containment)this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,b("document"==a.containment?document:window).width()-this.helperProportions.width-this.margins.left,(b("document"==a.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-
+this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)){var c=b(a.containment)[0],a=b(a.containment).offset(),d="hidden"!=b(c).css("overflow");this.containment=[a.left+(parseInt(b(c).css("borderLeftWidth"),10)||0)+(parseInt(b(c).css("paddingLeft"),10)||0)-this.margins.left,a.top+(parseInt(b(c).css("borderTopWidth"),10)||0)+(parseInt(b(c).css("paddingTop"),10)||0)-this.margins.top,a.left+(d?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(b(c).css("borderLeftWidth"),10)||
+0)-(parseInt(b(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,a.top+(d?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(b(c).css("borderTopWidth"),10)||0)-(parseInt(b(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(a,c){c||(c=this.position);var d="absolute"==a?1:-1,g="absolute"==this.cssPosition&&!(this.scrollParent[0]!=document&&b.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:
+this.scrollParent,h=/(html|body)/i.test(g[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(b.browser.safari&&"fixed"==this.cssPosition?0:("fixed"==this.cssPosition?-this.scrollParent.scrollTop():h?0:g.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(b.browser.safari&&"fixed"==this.cssPosition?0:("fixed"==this.cssPosition?-this.scrollParent.scrollLeft():h?0:g.scrollLeft())*d)}},_generatePosition:function(a){var c=this.options,d="absolute"==
+this.cssPosition&&!(this.scrollParent[0]!=document&&b.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(d[0].tagName);"relative"==this.cssPosition&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var h=a.pageX,e=a.pageY;if(this.originalPosition&&(this.containment&&(a.pageX-this.offset.click.left<this.containment[0]&&(h=this.containment[0]+this.offset.click.left),
+a.pageY-this.offset.click.top<this.containment[1]&&(e=this.containment[1]+this.offset.click.top),a.pageX-this.offset.click.left>this.containment[2]&&(h=this.containment[2]+this.offset.click.left),a.pageY-this.offset.click.top>this.containment[3]&&(e=this.containment[3]+this.offset.click.top)),c.grid))e=this.originalPageY+Math.round((e-this.originalPageY)/c.grid[1])*c.grid[1],e=this.containment?!(e-this.offset.click.top<this.containment[1]||e-this.offset.click.top>this.containment[3])?e:!(e-this.offset.click.top<
+this.containment[1])?e-c.grid[1]:e+c.grid[1]:e,h=this.originalPageX+Math.round((h-this.originalPageX)/c.grid[0])*c.grid[0],h=this.containment?!(h-this.offset.click.left<this.containment[0]||h-this.offset.click.left>this.containment[2])?h:!(h-this.offset.click.left<this.containment[0])?h-c.grid[0]:h+c.grid[0]:h;return{top:e-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(b.browser.safari&&"fixed"==this.cssPosition?0:"fixed"==this.cssPosition?-this.scrollParent.scrollTop():g?
+0:d.scrollTop()),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(b.browser.safari&&"fixed"==this.cssPosition?0:"fixed"==this.cssPosition?-this.scrollParent.scrollLeft():g?0:d.scrollLeft())}},_rearrange:function(b,c,d,g){d?d[0].appendChild(this.placeholder[0]):c.item[0].parentNode.insertBefore(this.placeholder[0],"down"==this.direction?c.item[0]:c.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var h=this,e=this.counter;window.setTimeout(function(){e==
+h.counter&&h.refreshPositions(!g)},0)},_clear:function(a,c){this.reverting=!1;var d=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var g in this._storedCSS)if("auto"==this._storedCSS[g]||"static"==this._storedCSS[g])this._storedCSS[g]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!c&&d.push(function(b){this._trigger("receive",
+b,this._uiHash(this.fromOutside))});(this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!c&&d.push(function(b){this._trigger("update",b,this._uiHash())});if(!b.ui.contains(this.element[0],this.currentItem[0])){c||d.push(function(b){this._trigger("remove",b,this._uiHash())});for(g=this.containers.length-1;0<=g;g--)b.ui.contains(this.containers[g].element[0],this.currentItem[0])&&!c&&(d.push(function(b){return function(a){b._trigger("receive",
+a,this._uiHash(this))}}.call(this,this.containers[g])),d.push(function(b){return function(a){b._trigger("update",a,this._uiHash(this))}}.call(this,this.containers[g])))}for(g=this.containers.length-1;0<=g;g--)c||d.push(function(b){return function(a){b._trigger("deactivate",a,this._uiHash(this))}}.call(this,this.containers[g])),this.containers[g].containerCache.over&&(d.push(function(b){return function(a){b._trigger("out",a,this._uiHash(this))}}.call(this,this.containers[g])),this.containers[g].containerCache.over=
+0);this._storedCursor&&b("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);this._storedZIndex&&this.helper.css("zIndex","auto"==this._storedZIndex?"":this._storedZIndex);this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",a,this._uiHash());for(g=0;g<d.length;g++)d[g].call(this,a);this._trigger("stop",a,this._uiHash())}return!1}c||this._trigger("beforeStop",a,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!c){for(g=0;g<d.length;g++)d[g].call(this,a);this._trigger("stop",a,this._uiHash())}this.fromOutside=!1;return!0},_trigger:function(){!1===b.Widget.prototype._trigger.apply(this,arguments)&&this.cancel()},_uiHash:function(a){var c=a||this;return{helper:c.helper,placeholder:c.placeholder||b([]),position:c.position,originalPosition:c.originalPosition,offset:c.positionAbs,item:c.currentItem,sender:a?a.element:null}}});b.extend(b.ui.sortable,
+{version:"1.8.14"})})(jQuery);
+(function(b){b.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:!0,clearStyle:!1,collapsible:!1,event:"click",fillSpace:!1,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,c=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");a.headers=
+a.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){c.disabled||b(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){c.disabled||b(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){c.disabled||b(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){c.disabled||b(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
+if(c.navigation){var d=a.element.find("a").filter(c.navigationFilter).eq(0);if(d.length){var g=d.closest(".ui-accordion-header");a.active=g.length?g:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion",
+function(b){return a._keydown(b)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);b.browser.safari||a.headers.find("a").attr("tabIndex",-1);c.event&&a.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(b){a._clickHandler.call(a,b,this);b.preventDefault()})},_createIcons:function(){var a=
+this.options;a.icons&&(b("<span></span>").addClass("ui-icon "+a.icons.header).prependTo(this.headers),this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected),this.element.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex");
+this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");(a.autoHeight||a.fillHeight)&&c.css("height","");return b.Widget.prototype.destroy.call(this)},_setOption:function(a,c){b.Widget.prototype._setOption.apply(this,arguments);"active"==a&&this.activate(c);"icons"==a&&(this._destroyIcons(),
+c&&this._createIcons());if("disabled"==a)this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!this.options.disabled&&!a.altKey&&!a.ctrlKey){var c=b.ui.keyCode,d=this.headers.length,g=this.headers.index(a.target),h=!1;switch(a.keyCode){case c.RIGHT:case c.DOWN:h=this.headers[(g+1)%d];break;case c.LEFT:case c.UP:h=this.headers[(g-1+d)%d];break;case c.SPACE:case c.ENTER:this._clickHandler({target:a.target},a.target),a.preventDefault()}return h?
+(b(a.target).attr("tabIndex",-1),b(h).attr("tabIndex",0),h.focus(),!1):!0}},resize:function(){var a=this.options,c;if(a.fillSpace){if(b.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height();b.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){c-=b(this).outerHeight(!0)});this.headers.next().each(function(){b(this).height(Math.max(0,c-b(this).innerHeight()+b(this).height()))}).css("overflow",
+"auto")}else a.autoHeight&&(c=0,this.headers.next().each(function(){c=Math.max(c,b(this).height("").height())}).height(c));return this},activate:function(b){this.options.active=b;b=this._findActive(b)[0];this._clickHandler({target:b},b);return this},_findActive:function(a){return a?"number"===typeof a?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):!1===a?b([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,c){var d=this.options;if(!d.disabled)if(a.target){var g=b(a.currentTarget||
+c),h=g[0]===this.active[0];d.active=d.collapsible&&h?!1:this.headers.index(g);if(!(this.running||!d.collapsible&&h)){var e=this.active,f=g.next(),i=this.active.next(),j={options:d,newHeader:h&&d.collapsible?b([]):g,oldHeader:this.active,newContent:h&&d.collapsible?b([]):f,oldContent:i},k=this.headers.index(this.active[0])>this.headers.index(g[0]);this.active=h?b([]):g;this._toggle(f,i,j,h,k);e.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);
+h||(g.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected),g.next().addClass("ui-accordion-content-active"))}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var i=this.active.next(),
+j={options:d,newHeader:b([]),oldHeader:d.active,newContent:b([]),oldContent:i},f=this.active=b([]);this._toggle(f,i,j)}},_toggle:function(a,c,d,g,h){var e=this,f=e.options;e.toShow=a;e.toHide=c;e.data=d;var i=function(){if(e)return e._completed.apply(e,arguments)};e._trigger("changestart",null,e.data);e.running=0===c.size()?a.size():c.size();if(f.animated){d={};d=f.collapsible&&g?{toShow:b([]),toHide:c,complete:i,down:h,autoHeight:f.autoHeight||f.fillSpace}:{toShow:a,toHide:c,complete:i,down:h,autoHeight:f.autoHeight||
+f.fillSpace};f.proxied||(f.proxied=f.animated);f.proxiedDuration||(f.proxiedDuration=f.duration);f.animated=b.isFunction(f.proxied)?f.proxied(d):f.proxied;f.duration=b.isFunction(f.proxiedDuration)?f.proxiedDuration(d):f.proxiedDuration;var g=b.ui.accordion.animations,j=f.duration,k=f.animated;k&&(!g[k]&&!b.easing[k])&&(k="slide");g[k]||(g[k]=function(b){this.slide(b,{easing:k,duration:j||700})});g[k](d)}else f.collapsible&&g?a.toggle():(c.hide(),a.show()),i(!0);c.prev().attr({"aria-expanded":"false",
+"aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(b){this.running=b?0:--this.running;this.running||(this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data))}});b.extend(b.ui.accordion,{version:"1.8.14",
+animations:{slide:function(a,c){a=b.extend({easing:"swing",duration:300},a,c);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),g=0,h={},e={},f,i=a.toShow;f=i[0].style.width;i.width(parseInt(i.parent().width(),10)-parseInt(i.css("paddingLeft"),10)-parseInt(i.css("paddingRight"),10)-(parseInt(i.css("borderLeftWidth"),10)||0)-(parseInt(i.css("borderRightWidth"),10)||0));b.each(["height","paddingTop","paddingBottom"],function(c,f){e[f]="hide";var i=(""+b.css(a.toShow[0],f)).match(/^([\d+-.]+)(.*)$/);
+h[f]={value:i[1],unit:i[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(e,{step:function(b,c){"height"==c.prop&&(g=0===c.end-c.start?0:(c.now-c.start)/(c.end-c.start));a.toShow[0].style[c.prop]=g*h[c.prop].value+h[c.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:f,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide",
+paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(b){this.slide(b,{easing:b.down?"easeOutBounce":"swing",duration:b.down?1E3:200})}}})})(jQuery);
+(function(b){var a=0;b.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var c=this,a=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(a){if(!c.options.disabled&&!c.element.attr("readonly")){g=!1;var d=
+b.ui.keyCode;switch(a.keyCode){case d.PAGE_UP:c._move("previousPage",a);break;case d.PAGE_DOWN:c._move("nextPage",a);break;case d.UP:c._move("previous",a);a.preventDefault();break;case d.DOWN:c._move("next",a);a.preventDefault();break;case d.ENTER:case d.NUMPAD_ENTER:c.menu.active&&(g=!0,a.preventDefault());case d.TAB:if(!c.menu.active)break;c.menu.select(a);break;case d.ESCAPE:c.element.val(c.term);c.close(a);break;default:clearTimeout(c.searching),c.searching=setTimeout(function(){c.term!=c.element.val()&&
+(c.selectedItem=null,c.search(null,a))},c.options.delay)}}}).bind("keypress.autocomplete",function(b){g&&(g=!1,b.preventDefault())}).bind("focus.autocomplete",function(){c.options.disabled||(c.selectedItem=null,c.previous=c.element.val())}).bind("blur.autocomplete",function(b){c.options.disabled||(clearTimeout(c.searching),c.closing=setTimeout(function(){c.close(b);c._change(b)},150))});this._initSource();this.response=function(){return c._response.apply(c,arguments)};this.menu=b("<ul></ul>").addClass("ui-autocomplete").appendTo(b(this.options.appendTo||
+"body",a)[0]).mousedown(function(a){var d=c.menu.element[0];b(a.target).closest(".ui-menu-item").length||setTimeout(function(){b(document).one("mousedown",function(a){a.target!==c.element[0]&&(a.target!==d&&!b.ui.contains(d,a.target))&&c.close()})},1);setTimeout(function(){clearTimeout(c.closing)},13)}).menu({focus:function(b,a){var f=a.item.data("item.autocomplete");!1!==c._trigger("focus",b,{item:f})&&/^key/.test(b.originalEvent.type)&&c.element.val(f.value)},selected:function(b,e){var f=e.item.data("item.autocomplete"),
+i=c.previous;c.element[0]!==a.activeElement&&(c.element.focus(),c.previous=i,setTimeout(function(){c.previous=i;c.selectedItem=f},1));!1!==c._trigger("select",b,{item:f})&&c.element.val(f.value);c.term=c.element.val();c.close(b);c.selectedItem=f},blur:function(){c.menu.element.is(":visible")&&c.element.val()!==c.term&&c.element.val(c.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");b.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");
+this.menu.element.remove();b.Widget.prototype.destroy.call(this)},_setOption:function(a,d){b.Widget.prototype._setOption.apply(this,arguments);"source"===a&&this._initSource();"appendTo"===a&&this.menu.element.appendTo(b(d||"body",this.element[0].ownerDocument)[0]);"disabled"===a&&(d&&this.xhr)&&this.xhr.abort()},_initSource:function(){var c=this,d,g;b.isArray(this.options.source)?(d=this.options.source,this.source=function(a,c){c(b.ui.autocomplete.filter(d,a.term))}):"string"===typeof this.options.source?
+(g=this.options.source,this.source=function(d,e){c.xhr&&c.xhr.abort();c.xhr=b.ajax({url:g,data:d,dataType:"json",autocompleteRequest:++a,success:function(b){this.autocompleteRequest===a&&e(b)},error:function(){this.autocompleteRequest===a&&e([])}})}):this.source=this.options.source},search:function(b,a){b=null!=b?b:this.element.val();this.term=this.element.val();if(b.length<this.options.minLength)return this.close(a);clearTimeout(this.closing);if(!1!==this._trigger("search",a))return this._search(b)},
+_search:function(b){this.pending++;this.element.addClass("ui-autocomplete-loading");this.source({term:b},this.response)},_response:function(b){!this.options.disabled&&b&&b.length?(b=this._normalize(b),this._suggest(b),this._trigger("open")):this.close();this.pending--;this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(b){clearTimeout(this.closing);this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.deactivate(),this._trigger("close",b))},_change:function(b){this.previous!==
+this.element.val()&&this._trigger("change",b,{item:this.selectedItem})},_normalize:function(a){return a.length&&a[0].label&&a[0].value?a:b.map(a,function(a){return"string"===typeof a?{label:a,value:a}:b.extend({label:a.label||a.value,value:a.value||a.label},a)})},_suggest:function(a){var d=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(d,a);this.menu.deactivate();this.menu.refresh();d.show();this._resizeMenu();d.position(b.extend({of:this.element},this.options.position));
+this.options.autoFocus&&this.menu.next(new b.Event("mouseover"))},_resizeMenu:function(){var b=this.menu.element;b.outerWidth(Math.max(b.width("").outerWidth(),this.element.outerWidth()))},_renderMenu:function(a,d){var g=this;b.each(d,function(b,d){g._renderItem(a,d)})},_renderItem:function(a,d){return b("<li></li>").data("item.autocomplete",d).append(b("<a></a>").text(d.label)).appendTo(a)},_move:function(b,a){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(b)||this.menu.last()&&
+/^next/.test(b))this.element.val(this.term),this.menu.deactivate();else this.menu[b](a);else this.search(null,a)},widget:function(){return this.menu.element}});b.extend(b.ui.autocomplete,{escapeRegex:function(b){return b.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(a,d){var g=RegExp(b.ui.autocomplete.escapeRegex(d),"i");return b.grep(a,function(b){return g.test(b.label||b.value||b)})}})})(jQuery);
+(function(b){b.widget("ui.menu",{_create:function(){var a=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){b(c.target).closest(".ui-menu-item a").length&&(c.preventDefault(),a.select(c))});this.refresh()},refresh:function(){var a=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
+-1).mouseenter(function(c){a.activate(c,b(this).parent())}).mouseleave(function(){a.deactivate()})},activate:function(b,c){this.deactivate();if(this.hasScroll()){var d=c.offset().top-this.element.offset().top,g=this.element.scrollTop(),h=this.element.height();0>d?this.element.scrollTop(g+d):d>=h&&this.element.scrollTop(g+d-h+c.height())}this.active=c.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",b,{item:c})},deactivate:function(){this.active&&
+(this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null)},next:function(b){this.move("next",".ui-menu-item:first",b)},previous:function(b){this.move("prev",".ui-menu-item:last",b)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(b,c,d){this.active?(b=this.active[b+"All"](".ui-menu-item").eq(0),b.length?this.activate(d,
+b):this.activate(d,this.element.children(c))):this.activate(d,this.element.children(c))},nextPage:function(a){if(this.hasScroll())if(!this.active||this.last())this.activate(a,this.element.children(".ui-menu-item:first"));else{var c=this.active.offset().top,d=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var a=b(this).offset().top-c-d+b(this).height();return 10>a&&-10<a});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(a,g)}else this.activate(a,
+this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(a){if(this.hasScroll())if(!this.active||this.first())this.activate(a,this.element.children(".ui-menu-item:last"));else{var c=this.active.offset().top,d=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var a=b(this).offset().top-c+d-b(this).height();return 10>a&&-10<a});result.length||(result=this.element.children(".ui-menu-item:first"));this.activate(a,
+result)}else this.activate(a,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[b.fn.prop?"prop":"attr"]("scrollHeight")},select:function(b){this._trigger("selected",b,{item:this.active})}})})(jQuery);
+(function(b){var a,c,d,g,h=function(){var a=b(this).find(":ui-button");setTimeout(function(){a.button("refresh")},1)},e=function(a){var c=a.name,d=a.form,h=b([]);c&&(h=d?b(d).find("[name='"+c+"']"):b("[name='"+c+"']",a.ownerDocument).filter(function(){return!this.form}));return h};b.widget("ui.button",{options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",h);"boolean"!==typeof this.options.disabled&&
+(this.options.disabled=this.element.attr("disabled"));this._determineButtonType();this.hasTitle=!!this.buttonElement.attr("title");var f=this,i=this.options,j="checkbox"===this.type||"radio"===this.type,k="ui-state-hover"+(!j?" ui-state-active":"");null===i.label&&(i.label=this.buttonElement.html());this.element.is(":disabled")&&(i.disabled=!0);this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",function(){if(!i.disabled){b(this).addClass("ui-state-hover");
+this===a&&b(this).addClass("ui-state-active")}}).bind("mouseleave.button",function(){i.disabled||b(this).removeClass(k)}).bind("click.button",function(b){if(i.disabled){b.preventDefault();b.stopImmediatePropagation()}});this.element.bind("focus.button",function(){f.buttonElement.addClass("ui-state-focus")}).bind("blur.button",function(){f.buttonElement.removeClass("ui-state-focus")});j&&(this.element.bind("change.button",function(){g||f.refresh()}),this.buttonElement.bind("mousedown.button",function(b){if(!i.disabled){g=
+false;c=b.pageX;d=b.pageY}}).bind("mouseup.button",function(b){if(!i.disabled&&(c!==b.pageX||d!==b.pageY))g=true}));"checkbox"===this.type?this.buttonElement.bind("click.button",function(){if(i.disabled||g)return false;b(this).toggleClass("ui-state-active");f.buttonElement.attr("aria-pressed",f.element[0].checked)}):"radio"===this.type?this.buttonElement.bind("click.button",function(){if(i.disabled||g)return false;b(this).addClass("ui-state-active");f.buttonElement.attr("aria-pressed",true);var a=
+f.element[0];e(a).not(a).map(function(){return b(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed",false)}):(this.buttonElement.bind("mousedown.button",function(){if(i.disabled)return false;b(this).addClass("ui-state-active");a=this;b(document).one("mouseup",function(){a=null})}).bind("mouseup.button",function(){if(i.disabled)return false;b(this).removeClass("ui-state-active")}).bind("keydown.button",function(a){if(i.disabled)return false;(a.keyCode==b.ui.keyCode.SPACE||
+a.keyCode==b.ui.keyCode.ENTER)&&b(this).addClass("ui-state-active")}).bind("keyup.button",function(){b(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(a){a.keyCode===b.ui.keyCode.SPACE&&b(this).click()}));this._setOption("disabled",i.disabled);this._resetButton()},_determineButtonType:function(){this.type=this.element.is(":checkbox")?"checkbox":this.element.is(":radio")?"radio":this.element.is("input")?"input":"button";if("checkbox"===this.type||
+"radio"===this.type){var b=this.element.parents().filter(":last"),a="label[for="+this.element.attr("id")+"]";this.buttonElement=b.find(a);this.buttonElement.length||(b=b.length?b.siblings():this.element.siblings(),this.buttonElement=b.filter(a),this.buttonElement.length||(this.buttonElement=b.find(a)));this.element.addClass("ui-helper-hidden-accessible");(b=this.element.is(":checked"))&&this.buttonElement.addClass("ui-state-active");this.buttonElement.attr("aria-pressed",b)}else this.buttonElement=
+this.element},widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible");this.buttonElement.removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-active ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only").removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html());this.hasTitle||
+this.buttonElement.removeAttr("title");b.Widget.prototype.destroy.call(this)},_setOption:function(a,c){b.Widget.prototype._setOption.apply(this,arguments);"disabled"===a?c?this.element.attr("disabled",!0):this.element.removeAttr("disabled"):this._resetButton()},refresh:function(){var a=this.element.is(":disabled");a!==this.options.disabled&&this._setOption("disabled",a);"radio"===this.type?e(this.element[0]).each(function(){b(this).is(":checked")?b(this).button("widget").addClass("ui-state-active").attr("aria-pressed",
+!0):b(this).button("widget").removeClass("ui-state-active").attr("aria-pressed",!1)}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed",!0):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed",!1))},_resetButton:function(){if("input"===this.type)this.options.label&&this.element.val(this.options.label);else{var a=this.buttonElement.removeClass("ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only"),
+c=b("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(a.empty()).text(),d=this.options.icons,h=d.primary&&d.secondary,e=[];d.primary||d.secondary?(this.options.text&&e.push("ui-button-text-icon"+(h?"s":d.primary?"-primary":"-secondary")),d.primary&&a.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>"),d.secondary&&a.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>"),this.options.text||(e.push(h?"ui-button-icons-only":
+"ui-button-icon-only"),this.hasTitle||a.attr("title",c))):e.push("ui-button-text-only");a.addClass(e.join(" "))}}});b.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(a,c){"disabled"===a&&this.buttons.button("option",a,c);b.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var a="ltr"===this.element.css("direction");
+this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(a?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(a?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");
+b.Widget.prototype.destroy.call(this)}})})(jQuery);
+(function(b,a){var c={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},d={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},g=b.attrFn||{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0,click:!0};b.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(a){var c=
+b(this).css(a).offset().top;0>c&&b(this).css("top",a.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");"string"!==typeof this.originalTitle&&(this.originalTitle="");this.options.title=this.options.title||this.originalTitle;var a=this,c=a.options,f=c.title||"&#160;",i=b.ui.dialog.getTitleId(a.element),d=(a.uiDialog=b("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+
+c.dialogClass).css({zIndex:c.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(f){if(c.closeOnEscape&&f.keyCode&&f.keyCode===b.ui.keyCode.ESCAPE){a.close(f);f.preventDefault()}}).attr({role:"dialog","aria-labelledby":i}).mousedown(function(b){a.moveToTop(false,b)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(d);var g=(a.uiDialogTitlebar=b("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(d),
+l=b('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){l.addClass("ui-state-hover")},function(){l.removeClass("ui-state-hover")}).focus(function(){l.addClass("ui-state-focus")}).blur(function(){l.removeClass("ui-state-focus")}).click(function(b){a.close(b);return false}).appendTo(g);(a.uiDialogTitlebarCloseText=b("<span></span>")).addClass("ui-icon ui-icon-closethick").text(c.closeText).appendTo(l);b("<span></span>").addClass("ui-dialog-title").attr("id",
+i).html(f).prependTo(g);b.isFunction(c.beforeclose)&&!b.isFunction(c.beforeClose)&&(c.beforeClose=c.beforeclose);g.find("*").add(g).disableSelection();c.draggable&&b.fn.draggable&&a._makeDraggable();c.resizable&&b.fn.resizable&&a._makeResizable();a._createButtons(c.buttons);a._isOpen=!1;b.fn.bgiframe&&d.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){this.overlay&&this.overlay.destroy();this.uiDialog.hide();this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");
+this.uiDialog.remove();this.originalTitle&&this.element.attr("title",this.originalTitle);return this},widget:function(){return this.uiDialog},close:function(a){var c=this,f,d;if(!1!==c._trigger("beforeClose",a))return c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",a)}):(c.uiDialog.hide(),c._trigger("close",a)),b.ui.dialog.overlay.resize(),c.options.modal&&(f=0,b(".ui-dialog").each(function(){if(this!==
+c.uiDialog[0]){d=b(this).css("z-index");isNaN(d)||(f=Math.max(f,d))}}),b.ui.dialog.maxZ=f),c},isOpen:function(){return this._isOpen},moveToTop:function(a,c){var f=this.options;if(f.modal&&!a||!f.stack&&!f.modal)return this._trigger("focus",c);f.zIndex>b.ui.dialog.maxZ&&(b.ui.dialog.maxZ=f.zIndex);this.overlay&&(b.ui.dialog.maxZ+=1,this.overlay.$el.css("z-index",b.ui.dialog.overlay.maxZ=b.ui.dialog.maxZ));f={scrollTop:this.element.attr("scrollTop"),scrollLeft:this.element.attr("scrollLeft")};b.ui.dialog.maxZ+=
+1;this.uiDialog.css("z-index",b.ui.dialog.maxZ);this.element.attr(f);this._trigger("focus",c);return this},open:function(){if(!this._isOpen){var a=this.options,c=this.uiDialog;this.overlay=a.modal?new b.ui.dialog.overlay(this):null;this._size();this._position(a.position);c.show(a.show);this.moveToTop(!0);a.modal&&c.bind("keypress.ui-dialog",function(a){if(a.keyCode===b.ui.keyCode.TAB){var c=b(":tabbable",this),d=c.filter(":first"),c=c.filter(":last");if(a.target===c[0]&&!a.shiftKey)return d.focus(1),
+!1;if(a.target===d[0]&&a.shiftKey)return c.focus(1),!1}});b(this.element.find(":tabbable").get().concat(c.find(".ui-dialog-buttonpane :tabbable").get().concat(c.get()))).eq(0).focus();this._isOpen=!0;this._trigger("open");return this}},_createButtons:function(a){var c=this,f=!1,d=b("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),j=b("<div></div>").addClass("ui-dialog-buttonset").appendTo(d);c.uiDialog.find(".ui-dialog-buttonpane").remove();"object"===typeof a&&
+null!==a&&b.each(a,function(){return!(f=!0)});f&&(b.each(a,function(a,f){var f=b.isFunction(f)?{click:f,text:a}:f,d=b('<button type="button"></button>').click(function(){f.click.apply(c.element[0],arguments)}).appendTo(j);b.each(f,function(b,a){if("click"!==b)if(b in g)d[b](a);else d.attr(b,a)});b.fn.button&&d.button()}),d.appendTo(c.uiDialog))},_makeDraggable:function(){function a(b){return{position:b.position,offset:b.offset}}var c=this,f=c.options,d=b(document),g;c.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",
+handle:".ui-dialog-titlebar",containment:"document",start:function(d,i){g="auto"===f.height?"auto":b(this).height();b(this).height(b(this).height()).addClass("ui-dialog-dragging");c._trigger("dragStart",d,a(i))},drag:function(b,f){c._trigger("drag",b,a(f))},stop:function(k,l){f.position=[l.position.left-d.scrollLeft(),l.position.top-d.scrollTop()];b(this).removeClass("ui-dialog-dragging").height(g);c._trigger("dragStop",k,a(l));b.ui.dialog.overlay.resize()}})},_makeResizable:function(c){function d(b){return{originalPosition:b.originalPosition,
+originalSize:b.originalSize,position:b.position,size:b.size}}var c=c===a?this.options.resizable:c,f=this,i=f.options,g=f.uiDialog.css("position"),c="string"===typeof c?c:"n,e,s,w,se,sw,ne,nw";f.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:f.element,maxWidth:i.maxWidth,maxHeight:i.maxHeight,minWidth:i.minWidth,minHeight:f._minHeight(),handles:c,start:function(a,c){b(this).addClass("ui-dialog-resizing");f._trigger("resizeStart",a,d(c))},resize:function(b,a){f._trigger("resize",
+b,d(a))},stop:function(a,c){b(this).removeClass("ui-dialog-resizing");i.height=b(this).height();i.width=b(this).width();f._trigger("resizeStop",a,d(c));b.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var b=this.options;return"auto"===b.height?b.minHeight:Math.min(b.minHeight,b.height)},_position:function(a){var c=[],f=[0,0],d;if(a){if("string"===typeof a||"object"===typeof a&&"0"in a)c=a.split?a.split(" "):
+[a[0],a[1]],1===c.length&&(c[1]=c[0]),b.each(["left","top"],function(b,a){+c[b]===c[b]&&(f[b]=c[b],c[b]=a)}),a={my:c.join(" "),at:c.join(" "),offset:f.join(" ")};a=b.extend({},b.ui.dialog.prototype.options.position,a)}else a=b.ui.dialog.prototype.options.position;(d=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(b.extend({of:window},a));d||this.uiDialog.hide()},_setOptions:function(a){var g=this,f={},i=!1;b.each(a,function(b,a){g._setOption(b,a);b in
+c&&(i=!0);b in d&&(f[b]=a)});i&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(a,c){var f=this.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":this._createButtons(c);break;case "closeText":this.uiDialogTitlebarCloseText.text(""+c);break;case "dialogClass":f.removeClass(this.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+c);break;case "disabled":c?f.addClass("ui-dialog-disabled"):
+f.removeClass("ui-dialog-disabled");break;case "draggable":var d=f.is(":data(draggable)");d&&!c&&f.draggable("destroy");!d&&c&&this._makeDraggable();break;case "position":this._position(c);break;case "resizable":(d=f.is(":data(resizable)"))&&!c&&f.resizable("destroy");d&&"string"===typeof c&&f.resizable("option","handles",c);!d&&!1!==c&&this._makeResizable(c);break;case "title":b(".ui-dialog-title",this.uiDialogTitlebar).html(""+(c||"&#160;"))}b.Widget.prototype._setOption.apply(this,arguments)},
+_size:function(){var a=this.options,c,f,d=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});a.minWidth>a.width&&(a.width=a.minWidth);c=this.uiDialog.css({height:"auto",width:a.width}).height();f=Math.max(0,a.minHeight-c);"auto"===a.height?b.support.minHeight?this.element.css({minHeight:f,height:"auto"}):(this.uiDialog.show(),a=this.element.css("height","auto").height(),d||this.uiDialog.hide(),this.element.height(Math.max(a,f))):this.element.height(Math.max(a.height-
+c,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});b.extend(b.ui.dialog,{version:"1.8.14",uuid:0,maxZ:0,getTitleId:function(b){b=b.attr("id");b||(b=this.uuid+=1);return"ui-dialog-title-"+b},overlay:function(a){this.$el=b.ui.dialog.overlay.create(a)}});b.extend(b.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:b.map("focus mousedown mouseup keydown keypress click".split(" "),function(b){return b+".dialog-overlay"}).join(" "),
+create:function(a){0===this.instances.length&&(setTimeout(function(){b.ui.dialog.overlay.instances.length&&b(document).bind(b.ui.dialog.overlay.events,function(a){if(b(a.target).zIndex()<b.ui.dialog.overlay.maxZ)return!1})},1),b(document).bind("keydown.dialog-overlay",function(c){a.options.closeOnEscape&&(c.keyCode&&c.keyCode===b.ui.keyCode.ESCAPE)&&(a.close(c),c.preventDefault())}),b(window).bind("resize.dialog-overlay",b.ui.dialog.overlay.resize));var c=(this.oldInstances.pop()||b("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),
+height:this.height()});b.fn.bgiframe&&c.bgiframe();this.instances.push(c);return c},destroy:function(a){var c=b.inArray(a,this.instances);-1!=c&&this.oldInstances.push(this.instances.splice(c,1)[0]);0===this.instances.length&&b([document,window]).unbind(".dialog-overlay");a.remove();var f=0;b.each(this.instances,function(){f=Math.max(f,this.css("z-index"))});this.maxZ=f},height:function(){var a,c;return b.browser.msie&&7>b.browser.version?(a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),
+c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight),a<c?b(window).height()+"px":a+"px"):b(document).height()+"px"},width:function(){var a,c;return b.browser.msie?(a=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth),c=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth),a<c?b(window).width()+"px":a+"px"):b(document).width()+"px"},resize:function(){var a=b([]);b.each(b.ui.dialog.overlay.instances,function(){a=a.add(this)});a.css({width:0,
+height:0}).css({width:b.ui.dialog.overlay.width(),height:b.ui.dialog.overlay.height()})}});b.extend(b.ui.dialog.overlay.prototype,{destroy:function(){b.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
+(function(b){b.widget("ui.slider",b.ui.mouse,{widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var a=this,c=this.options,d=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),g=c.values&&c.values.length||1,h=[];this._mouseSliding=this._keySliding=!1;this._animateOff=!0;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+
+this.orientation+" ui-widget ui-widget-content ui-corner-all"+(c.disabled?" ui-slider-disabled ui-disabled":""));this.range=b([]);if(c.range){if(!0===c.range&&(c.values||(c.values=[this._valueMin(),this._valueMin()]),c.values.length&&2!==c.values.length))c.values=[c.values[0],c.values[0]];this.range=b("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+("min"===c.range||"max"===c.range?" ui-slider-range-"+c.range:""))}for(var e=d.length;e<g;e+=1)h.push("<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>");
+this.handles=d.add(b(h.join("")).appendTo(a.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(b){b.preventDefault()}).hover(function(){c.disabled||b(this).addClass("ui-state-hover")},function(){b(this).removeClass("ui-state-hover")}).focus(function(){c.disabled?b(this).blur():(b(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),b(this).addClass("ui-state-focus"))}).blur(function(){b(this).removeClass("ui-state-focus")});this.handles.each(function(a){b(this).data("index.ui-slider-handle",
+a)});this.handles.keydown(function(c){var d=!0,g=b(this).data("index.ui-slider-handle"),e,h,m;if(!a.options.disabled){switch(c.keyCode){case b.ui.keyCode.HOME:case b.ui.keyCode.END:case b.ui.keyCode.PAGE_UP:case b.ui.keyCode.PAGE_DOWN:case b.ui.keyCode.UP:case b.ui.keyCode.RIGHT:case b.ui.keyCode.DOWN:case b.ui.keyCode.LEFT:if(d=!1,!a._keySliding&&(a._keySliding=!0,b(this).addClass("ui-state-active"),e=a._start(c,g),!1===e))return}m=a.options.step;e=a.options.values&&a.options.values.length?h=a.values(g):
+h=a.value();switch(c.keyCode){case b.ui.keyCode.HOME:h=a._valueMin();break;case b.ui.keyCode.END:h=a._valueMax();break;case b.ui.keyCode.PAGE_UP:h=a._trimAlignValue(e+(a._valueMax()-a._valueMin())/5);break;case b.ui.keyCode.PAGE_DOWN:h=a._trimAlignValue(e-(a._valueMax()-a._valueMin())/5);break;case b.ui.keyCode.UP:case b.ui.keyCode.RIGHT:if(e===a._valueMax())return;h=a._trimAlignValue(e+m);break;case b.ui.keyCode.DOWN:case b.ui.keyCode.LEFT:if(e===a._valueMin())return;h=a._trimAlignValue(e-m)}a._slide(c,
+g,h);return d}}).keyup(function(c){var d=b(this).data("index.ui-slider-handle");a._keySliding&&(a._keySliding=!1,a._stop(c,d),a._change(c,d),b(this).removeClass("ui-state-active"))});this._refreshValue();this._animateOff=!1},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy();return this},_mouseCapture:function(a){var c=
+this.options,d,g,h,e,f;if(c.disabled)return!1;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();d=this._normValueFromMouse({x:a.pageX,y:a.pageY});g=this._valueMax()-this._valueMin()+1;e=this;this.handles.each(function(a){var c=Math.abs(d-e.values(a));g>c&&(g=c,h=b(this),f=a)});!0===c.range&&this.values(1)===c.min&&(f+=1,h=b(this.handles[f]));if(!1===this._start(a,f))return!1;this._mouseSliding=!0;e._handleIndex=f;h.addClass("ui-state-active").focus();
+c=h.offset();this._clickOffset=!b(a.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:a.pageX-c.left-h.width()/2,top:a.pageY-c.top-h.height()/2-(parseInt(h.css("borderTopWidth"),10)||0)-(parseInt(h.css("borderBottomWidth"),10)||0)+(parseInt(h.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(a,f,d);return this._animateOff=!0},_mouseStart:function(){return!0},_mouseDrag:function(b){var c=this._normValueFromMouse({x:b.pageX,y:b.pageY});this._slide(b,
+this._handleIndex,c);return!1},_mouseStop:function(b){this.handles.removeClass("ui-state-active");this._mouseSliding=!1;this._stop(b,this._handleIndex);this._change(b,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(b){var c;"horizontal"===this.orientation?(c=this.elementSize.width,b=b.x-this.elementOffset.left-(this._clickOffset?
+this._clickOffset.left:0)):(c=this.elementSize.height,b=b.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0));c=b/c;1<c&&(c=1);0>c&&(c=0);"vertical"===this.orientation&&(c=1-c);b=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+c*b)},_start:function(b,c){var d={handle:this.handles[c],value:this.value()};this.options.values&&this.options.values.length&&(d.value=this.values(c),d.values=this.values());return this._trigger("start",b,d)},_slide:function(b,
+c,d){var g;if(this.options.values&&this.options.values.length){g=this.values(c?0:1);if(2===this.options.values.length&&!0===this.options.range&&(0===c&&d>g||1===c&&d<g))d=g;d!==this.values(c)&&(g=this.values(),g[c]=d,b=this._trigger("slide",b,{handle:this.handles[c],value:d,values:g}),this.values(c?0:1),!1!==b&&this.values(c,d,!0))}else d!==this.value()&&(b=this._trigger("slide",b,{handle:this.handles[c],value:d}),!1!==b&&this.value(d))},_stop:function(b,c){var d={handle:this.handles[c],value:this.value()};
+this.options.values&&this.options.values.length&&(d.value=this.values(c),d.values=this.values());this._trigger("stop",b,d)},_change:function(b,c){if(!this._keySliding&&!this._mouseSliding){var d={handle:this.handles[c],value:this.value()};this.options.values&&this.options.values.length&&(d.value=this.values(c),d.values=this.values());this._trigger("change",b,d)}},value:function(b){if(arguments.length)this.options.value=this._trimAlignValue(b),this._refreshValue(),this._change(null,0);else return this._value()},
+values:function(a,c){var d,g,h;if(1<arguments.length)this.options.values[a]=this._trimAlignValue(c),this._refreshValue(),this._change(null,a);else if(arguments.length)if(b.isArray(arguments[0])){d=this.options.values;g=arguments[0];for(h=0;h<d.length;h+=1)d[h]=this._trimAlignValue(g[h]),this._change(null,h);this._refreshValue()}else return this.options.values&&this.options.values.length?this._values(a):this.value();else return this._values()},_setOption:function(a,c){var d,g=0;b.isArray(this.options.values)&&
+(g=this.options.values.length);b.Widget.prototype._setOption.apply(this,arguments);switch(a){case "disabled":c?(this.handles.filter(".ui-state-focus").blur(),this.handles.removeClass("ui-state-hover"),this.handles.attr("disabled","disabled"),this.element.addClass("ui-disabled")):(this.handles.removeAttr("disabled"),this.element.removeClass("ui-disabled"));break;case "orientation":this._detectOrientation();this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);
+this._refreshValue();break;case "value":this._animateOff=!0;this._refreshValue();this._change(null,0);this._animateOff=!1;break;case "values":this._animateOff=!0;this._refreshValue();for(d=0;d<g;d+=1)this._change(null,d);this._animateOff=!1}},_value:function(){var b=this.options.value;return b=this._trimAlignValue(b)},_values:function(b){var c,d;if(arguments.length)return c=this.options.values[b],c=this._trimAlignValue(c);c=this.options.values.slice();for(d=0;d<c.length;d+=1)c[d]=this._trimAlignValue(c[d]);
+return c},_trimAlignValue:function(b){if(b<=this._valueMin())return this._valueMin();if(b>=this._valueMax())return this._valueMax();var c=0<this.options.step?this.options.step:1,d=(b-this._valueMin())%c;alignValue=b-d;2*Math.abs(d)>=c&&(alignValue+=0<d?c:-c);return parseFloat(alignValue.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var a=this.options.range,c=this.options,d=this,g=!this._animateOff?c.animate:!1,h,e=
+{},f,i,j,k;if(this.options.values&&this.options.values.length)this.handles.each(function(a){h=100*((d.values(a)-d._valueMin())/(d._valueMax()-d._valueMin()));e["horizontal"===d.orientation?"left":"bottom"]=h+"%";b(this).stop(1,1)[g?"animate":"css"](e,c.animate);if(!0===d.options.range)if("horizontal"===d.orientation){if(0===a)d.range.stop(1,1)[g?"animate":"css"]({left:h+"%"},c.animate);if(1===a)d.range[g?"animate":"css"]({width:h-f+"%"},{queue:!1,duration:c.animate})}else{if(0===a)d.range.stop(1,
+1)[g?"animate":"css"]({bottom:h+"%"},c.animate);if(1===a)d.range[g?"animate":"css"]({height:h-f+"%"},{queue:!1,duration:c.animate})}f=h});else{i=this.value();j=this._valueMin();k=this._valueMax();h=k!==j?100*((i-j)/(k-j)):0;e["horizontal"===d.orientation?"left":"bottom"]=h+"%";this.handle.stop(1,1)[g?"animate":"css"](e,c.animate);if("min"===a&&"horizontal"===this.orientation)this.range.stop(1,1)[g?"animate":"css"]({width:h+"%"},c.animate);if("max"===a&&"horizontal"===this.orientation)this.range[g?
+"animate":"css"]({width:100-h+"%"},{queue:!1,duration:c.animate});if("min"===a&&"vertical"===this.orientation)this.range.stop(1,1)[g?"animate":"css"]({height:h+"%"},c.animate);if("max"===a&&"vertical"===this.orientation)this.range[g?"animate":"css"]({height:100-h+"%"},{queue:!1,duration:c.animate})}}});b.extend(b.ui.slider,{version:"1.8.14"})})(jQuery);
+(function(b,a){var c=0,d=0;b.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:!1,cookie:null,collapsible:!1,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(!0)},_setOption:function(b,a){"selected"==b?this.options.collapsible&&a==this.options.selected||this.select(a):
+(this.options[b]=a,this._tabify())},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+ ++c},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var a=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++d);return b.cookie.apply(null,[a].concat(b.makeArray(arguments)))},_ui:function(b,a){return{tab:b,panel:a,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var a=
+b(this);a.html(a.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function d(a,c){a.css("display","");!b.support.opacity&&c.opacity&&a[0].style.removeAttribute("filter")}var e=this,f=this.options,i=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=b(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return b("a",this)[0]});this.panels=b([]);this.anchors.each(function(a,c){var d=b(c).attr("href"),g=d.split("#")[0],h;if(g&&(g===location.toString().split("#")[0]||
+(h=b("base")[0])&&g===h.href))d=c.hash,c.href=d;i.test(d)?e.panels=e.panels.add(e.element.find(e._sanitizeSelector(d))):d&&"#"!==d?(b.data(c,"href.tabs",d),b.data(c,"load.tabs",d.replace(/#.*$/,"")),d=e._tabId(c),c.href="#"+d,g=e.element.find("#"+d),g.length||(g=b(f.panelTemplate).attr("id",d).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(e.panels[a-1]||e.list),g.data("destroy.tabs",!0)),e.panels=e.panels.add(g)):f.disabled.push(a)});c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),
+this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),f.selected===a?(location.hash&&this.anchors.each(function(b,a){if(a.hash==location.hash)return f.selected=b,!1}),"number"!==typeof f.selected&&f.cookie&&(f.selected=parseInt(e._cookie(),10)),"number"!==typeof f.selected&&this.lis.filter(".ui-tabs-selected").length&&(f.selected=
+this.lis.index(this.lis.filter(".ui-tabs-selected"))),f.selected=f.selected||(this.lis.length?0:-1)):null===f.selected&&(f.selected=-1),f.selected=0<=f.selected&&this.anchors[f.selected]||0>f.selected?f.selected:0,f.disabled=b.unique(f.disabled.concat(b.map(this.lis.filter(".ui-state-disabled"),function(b){return e.lis.index(b)}))).sort(),-1!=b.inArray(f.selected,f.disabled)&&f.disabled.splice(b.inArray(f.selected,f.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"),
+0<=f.selected&&this.anchors.length&&(e.element.find(e._sanitizeSelector(e.anchors[f.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(f.selected).addClass("ui-tabs-selected ui-state-active"),e.element.queue("tabs",function(){e._trigger("show",null,e._ui(e.anchors[f.selected],e.element.find(e._sanitizeSelector(e.anchors[f.selected].hash))[0]))}),this.load(f.selected)),b(window).bind("unload",function(){e.lis.add(e.anchors).unbind(".tabs");e.lis=e.anchors=e.panels=null})):f.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));
+this.element[f.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");f.cookie&&this._cookie(f.selected,f.cookie);for(var c=0,j;j=this.lis[c];c++)b(j)[-1!=b.inArray(c,f.disabled)&&!b(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");!1===f.cache&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if("mouseover"!==f.event){var k=function(b,a){a.is(":not(.ui-state-disabled)")&&a.addClass("ui-state-"+b)};this.lis.bind("mouseover.tabs",
+function(){k("hover",b(this))});this.lis.bind("mouseout.tabs",function(){b(this).removeClass("ui-state-hover")});this.anchors.bind("focus.tabs",function(){k("focus",b(this).closest("li"))});this.anchors.bind("blur.tabs",function(){b(this).closest("li").removeClass("ui-state-focus")})}var l,m;f.fx&&(b.isArray(f.fx)?(l=f.fx[0],m=f.fx[1]):l=m=f.fx);var p=m?function(a,c){b(a).closest("li").addClass("ui-tabs-selected ui-state-active");c.hide().removeClass("ui-tabs-hide").animate(m,m.duration||"normal",
+function(){d(c,m);e._trigger("show",null,e._ui(a,c[0]))})}:function(a,c){b(a).closest("li").addClass("ui-tabs-selected ui-state-active");c.removeClass("ui-tabs-hide");e._trigger("show",null,e._ui(a,c[0]))},n=l?function(b,a){a.animate(l,l.duration||"normal",function(){e.lis.removeClass("ui-tabs-selected ui-state-active");a.addClass("ui-tabs-hide");d(a,l);e.element.dequeue("tabs")})}:function(b,a){e.lis.removeClass("ui-tabs-selected ui-state-active");a.addClass("ui-tabs-hide");e.element.dequeue("tabs")};
+this.anchors.bind(f.event+".tabs",function(){var a=this,c=b(a).closest("li"),d=e.panels.filter(":not(.ui-tabs-hide)"),i=e.element.find(e._sanitizeSelector(a.hash));if(c.hasClass("ui-tabs-selected")&&!f.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||e.panels.filter(":animated").length||e._trigger("select",null,e._ui(this,i[0]))===false){this.blur();return false}f.selected=e.anchors.index(this);e.abort();if(f.collapsible){if(c.hasClass("ui-tabs-selected")){f.selected=
+-1;f.cookie&&e._cookie(f.selected,f.cookie);e.element.queue("tabs",function(){n(a,d)}).dequeue("tabs");this.blur();return false}if(!d.length){f.cookie&&e._cookie(f.selected,f.cookie);e.element.queue("tabs",function(){p(a,i)});e.load(e.anchors.index(this));this.blur();return false}}f.cookie&&e._cookie(f.selected,f.cookie);if(i.length){d.length&&e.element.queue("tabs",function(){n(a,d)});e.element.queue("tabs",function(){p(a,i)});e.load(e.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";
+b.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){"string"==typeof b&&(b=this.anchors.index(this.anchors.filter("[href$="+b+"]")));return b},destroy:function(){var a=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var a=
+b.data(this,"href.tabs");a&&(this.href=a);var c=b(this).unbind(".tabs");b.each(["href","load","cache"],function(b,a){c.removeData(a+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){b.data(this,"destroy.tabs")?b(this).remove():b(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});a.cookie&&this._cookie(null,a.cookie);return this},add:function(c,
+d,e){e===a&&(e=this.anchors.length);var f=this,i=this.options,d=b(i.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),c=!c.indexOf("#")?c.replace("#",""):this._tabId(b("a",d)[0]);d.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+c);j.length||(j=b(i.panelTemplate).attr("id",c).data("destroy.tabs",!0));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");e>=this.lis.length?(d.appendTo(this.list),j.appendTo(this.list[0].parentNode)):
+(d.insertBefore(this.lis[e]),j.insertBefore(this.panels[e]));i.disabled=b.map(i.disabled,function(b){return b>=e?++b:b});this._tabify();1==this.anchors.length&&(i.selected=0,d.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0));this._trigger("add",null,this._ui(this.anchors[e],this.panels[e]));return this},remove:function(a){var a=this._getIndex(a),c=this.options,d=this.lis.eq(a).remove(),
+f=this.panels.eq(a).remove();d.hasClass("ui-tabs-selected")&&1<this.anchors.length&&this.select(a+(a+1<this.anchors.length?1:-1));c.disabled=b.map(b.grep(c.disabled,function(b){return b!=a}),function(b){return b>=a?--b:b});this._tabify();this._trigger("remove",null,this._ui(d.find("a")[0],f[0]));return this},enable:function(a){var a=this._getIndex(a),c=this.options;if(-1!=b.inArray(a,c.disabled))return this.lis.eq(a).removeClass("ui-state-disabled"),c.disabled=b.grep(c.disabled,function(b){return b!=
+a}),this._trigger("enable",null,this._ui(this.anchors[a],this.panels[a])),this},disable:function(b){var b=this._getIndex(b),a=this.options;b!=a.selected&&(this.lis.eq(b).addClass("ui-state-disabled"),a.disabled.push(b),a.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b])));return this},select:function(b){b=this._getIndex(b);if(-1==b)if(this.options.collapsible&&-1!=this.options.selected)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+
+".tabs");return this},load:function(a){var a=this._getIndex(a),c=this,d=this.options,f=this.anchors.eq(a)[0],i=b.data(f,"load.tabs");this.abort();if(!i||0!==this.element.queue("tabs").length&&b.data(f,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(a).addClass("ui-state-processing");if(d.spinner){var j=b("span",f);j.data("label.tabs",j.html()).html(d.spinner)}this.xhr=b.ajax(b.extend({},d.ajaxOptions,{url:i,success:function(i,j){c.element.find(c._sanitizeSelector(f.hash)).html(i);c._cleanup();
+d.cache&&b.data(f,"cache.tabs",!0);c._trigger("load",null,c._ui(c.anchors[a],c.panels[a]));try{d.ajaxOptions.success(i,j)}catch(m){}},error:function(b,i){c._cleanup();c._trigger("load",null,c._ui(c.anchors[a],c.panels[a]));try{d.ajaxOptions.error(b,i,a,f)}catch(m){}}}));c.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(!1,!0);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));this.xhr&&(this.xhr.abort(),delete this.xhr);this._cleanup();
+return this},url:function(b,a){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",a);return this},length:function(){return this.anchors.length}});b.extend(b.ui.tabs,{version:"1.8.14"});b.extend(b.ui.tabs.prototype,{rotation:null,rotate:function(b,a){var c=this,f=this.options,d=c._rotate||(c._rotate=function(a){clearTimeout(c.rotation);c.rotation=setTimeout(function(){var b=f.selected;c.select(++b<c.anchors.length?b:0)},b);a&&a.stopPropagation()}),j=c._unrotate||(c._unrotate=!a?function(b){b.clientX&&
+c.rotate(null)}:function(){t=f.selected;d()});b?(this.element.bind("tabsshow",d),this.anchors.bind(f.event+".tabs",j),d()):(clearTimeout(c.rotation),this.element.unbind("tabsshow",d),this.anchors.unbind(f.event+".tabs",j),delete this._rotate,delete this._unrotate);return this}})})(jQuery);
+(function(b,a){function c(){this.debug=!1;this._curInst=null;this._keyEvent=!1;this._disabledInputs=[];this._inDialog=this._datepickerShowing=!1;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass=
+"ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:"January February March April May June July August September October November December".split(" "),monthNamesShort:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),dayNames:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),dayNamesShort:"Sun Mon Tue Wed Thu Fri Sat".split(" "),dayNamesMin:"Su Mo Tu We Th Fr Sa".split(" "),
+weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,
+beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1};b.extend(this._defaults,this.regional[""]);this.dpDiv=d(b('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function d(a){return a.bind("mouseout",function(a){a=b(a.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");
+a.length&&a.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){c=b(c.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!b.datepicker._isDisabledDatepicker(e.inline?a.parent()[0]:e.input[0])&&c.length)c.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),c.addClass("ui-state-hover"),c.hasClass("ui-datepicker-prev")&&c.addClass("ui-datepicker-prev-hover"),c.hasClass("ui-datepicker-next")&&
+c.addClass("ui-datepicker-next-hover")})}function g(c,d){b.extend(c,d);for(var e in d)if(null==d[e]||d[e]==a)c[e]=d[e];return c}b.extend(b.ui,{datepicker:{version:"1.8.14"}});var h=(new Date).getTime(),e;b.extend(c.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(b){g(this._defaults,b||{});return this},_attachDatepicker:function(a,c){var d=null,e;for(e in this._defaults){var g=
+a.getAttribute("date:"+e);if(g){d=d||{};try{d[e]=eval(g)}catch(m){d[e]=g}}}e=a.nodeName.toLowerCase();g="div"==e||"span"==e;a.id||(this.uuid+=1,a.id="dp"+this.uuid);var h=this._newInst(b(a),g);h.settings=b.extend({},c||{},d||{});"input"==e?this._connectDatepicker(a,h):g&&this._inlineDatepicker(a,h)},_newInst:function(a,c){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:c,dpDiv:!c?this.dpDiv:d(b('<div class="'+
+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(a,c){var d=b(a);c.append=b([]);c.trigger=b([]);d.hasClass(this.markerClassName)||(this._attachments(d,c),d.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(b,a,f){c.settings[a]=f}).bind("getData.datepicker",function(b,a){return this._get(c,a)}),this._autoSize(c),b.data(a,"datepicker",
+c))},_attachments:function(a,c){var d=this._get(c,"appendText"),e=this._get(c,"isRTL");c.append&&c.append.remove();d&&(c.append=b('<span class="'+this._appendClass+'">'+d+"</span>"),a[e?"before":"after"](c.append));a.unbind("focus",this._showDatepicker);c.trigger&&c.trigger.remove();d=this._get(c,"showOn");("focus"==d||"both"==d)&&a.focus(this._showDatepicker);if("button"==d||"both"==d){var d=this._get(c,"buttonText"),g=this._get(c,"buttonImage");c.trigger=b(this._get(c,"buttonImageOnly")?b("<img/>").addClass(this._triggerClass).attr({src:g,
+alt:d,title:d}):b('<button type="button"></button>').addClass(this._triggerClass).html(""==g?d:b("<img/>").attr({src:g,alt:d,title:d})));a[e?"before":"after"](c.trigger);c.trigger.click(function(){b.datepicker._datepickerShowing&&b.datepicker._lastInput==a[0]?b.datepicker._hideDatepicker():b.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(b){if(this._get(b,"autoSize")&&!b.inline){var a=new Date(2009,11,20),c=this._get(b,"dateFormat");if(c.match(/[DM]/)){var d=function(b){for(var a=
+0,c=0,f=0;f<b.length;f++)b[f].length>a&&(a=b[f].length,c=f);return c};a.setMonth(d(this._get(b,c.match(/MM/)?"monthNames":"monthNamesShort")));a.setDate(d(this._get(b,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-a.getDay())}b.input.attr("size",this._formatDate(b,a).length)}},_inlineDatepicker:function(a,c){var d=b(a);d.hasClass(this.markerClassName)||(d.addClass(this.markerClassName).append(c.dpDiv).bind("setData.datepicker",function(b,a,f){c.settings[a]=f}).bind("getData.datepicker",function(b,
+a){return this._get(c,a)}),b.data(a,"datepicker",c),this._setDate(c,this._getDefaultDate(c),!0),this._updateDatepicker(c),this._updateAlternate(c),c.dpDiv.show())},_dialogDatepicker:function(a,c,d,e,h){a=this._dialogInst;a||(this.uuid+=1,this._dialogInput=b('<input type="text" id="dp'+this.uuid+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>'),this._dialogInput.keydown(this._doKeyDown),b("body").append(this._dialogInput),a=this._dialogInst=this._newInst(this._dialogInput,!1),
+a.settings={},b.data(this._dialogInput[0],"datepicker",a));g(a.settings,e||{});c=c&&c.constructor==Date?this._formatDate(a,c):c;this._dialogInput.val(c);this._pos=h?h.length?h:[h.pageX,h.pageY]:null;this._pos||(this._pos=[document.documentElement.clientWidth/2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)]);this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+
+"px");a.settings.onSelect=d;this._inDialog=!0;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);b.blockUI&&b.blockUI(this.dpDiv);b.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var c=b(a),d=b.data(a,"datepicker");if(c.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();b.removeData(a,"datepicker");"input"==e?(d.append.remove(),d.trigger.remove(),c.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",
+this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"==e||"span"==e)&&c.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var c=b(a),d=b.data(a,"datepicker");if(c.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if("input"==e)a.disabled=!1,d.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if("div"==e||"span"==e)c=c.children("."+this._inlineClass),c.children().removeClass("ui-state-disabled"),
+c.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled");this._disabledInputs=b.map(this._disabledInputs,function(b){return b==a?null:b})}},_disableDatepicker:function(a){var c=b(a),d=b.data(a,"datepicker");if(c.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if("input"==e)a.disabled=!0,d.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if("div"==e||"span"==e)c=c.children("."+this._inlineClass),
+c.children().addClass("ui-state-disabled"),c.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled");this._disabledInputs=b.map(this._disabledInputs,function(b){return b==a?null:b});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(b){if(!b)return!1;for(var a=0;a<this._disabledInputs.length;a++)if(this._disabledInputs[a]==b)return!0;return!1},_getInst:function(a){try{return b.data(a,"datepicker")}catch(c){throw"Missing instance data for this datepicker";
+}},_optionDatepicker:function(c,d,e){var h=this._getInst(c);if(2==arguments.length&&"string"==typeof d)return"defaults"==d?b.extend({},b.datepicker._defaults):h?"all"==d?b.extend({},h.settings):this._get(h,d):null;var l=d||{};"string"==typeof d&&(l={},l[d]=e);if(h){this._curInst==h&&this._hideDatepicker();var m=this._getDateDatepicker(c,!0),p=this._getMinMaxDate(h,"min"),n=this._getMinMaxDate(h,"max");g(h.settings,l);null!==p&&(l.dateFormat!==a&&l.minDate===a)&&(h.settings.minDate=this._formatDate(h,
+p));null!==n&&(l.dateFormat!==a&&l.maxDate===a)&&(h.settings.maxDate=this._formatDate(h,n));this._attachments(b(c),h);this._autoSize(h);this._setDate(h,m);this._updateAlternate(h);this._updateDatepicker(h)}},_changeDatepicker:function(b,a,c){this._optionDatepicker(b,a,c)},_refreshDatepicker:function(b){(b=this._getInst(b))&&this._updateDatepicker(b)},_setDateDatepicker:function(b,a){var c=this._getInst(b);c&&(this._setDate(c,a),this._updateDatepicker(c),this._updateAlternate(c))},_getDateDatepicker:function(b,
+a){var c=this._getInst(b);c&&!c.inline&&this._setDateFromField(c,a);return c?this._getDate(c):null},_doKeyDown:function(a){var c=b.datepicker._getInst(a.target),d=!0,e=c.dpDiv.is(".ui-datepicker-rtl");c._keyEvent=!0;if(b.datepicker._datepickerShowing)switch(a.keyCode){case 9:b.datepicker._hideDatepicker();d=!1;break;case 13:return d=b("td."+b.datepicker._dayOverClass+":not(."+b.datepicker._currentClass+")",c.dpDiv),d[0]?b.datepicker._selectDay(a.target,c.selectedMonth,c.selectedYear,d[0]):b.datepicker._hideDatepicker(),
+!1;case 27:b.datepicker._hideDatepicker();break;case 33:b.datepicker._adjustDate(a.target,a.ctrlKey?-b.datepicker._get(c,"stepBigMonths"):-b.datepicker._get(c,"stepMonths"),"M");break;case 34:b.datepicker._adjustDate(a.target,a.ctrlKey?+b.datepicker._get(c,"stepBigMonths"):+b.datepicker._get(c,"stepMonths"),"M");break;case 35:(a.ctrlKey||a.metaKey)&&b.datepicker._clearDate(a.target);d=a.ctrlKey||a.metaKey;break;case 36:(a.ctrlKey||a.metaKey)&&b.datepicker._gotoToday(a.target);d=a.ctrlKey||a.metaKey;
+break;case 37:if(a.ctrlKey||a.metaKey)b.datepicker._adjustDate(a.target,e?1:-1,"D");d=a.ctrlKey||a.metaKey;a.originalEvent.altKey&&b.datepicker._adjustDate(a.target,a.ctrlKey?-b.datepicker._get(c,"stepBigMonths"):-b.datepicker._get(c,"stepMonths"),"M");break;case 38:(a.ctrlKey||a.metaKey)&&b.datepicker._adjustDate(a.target,-7,"D");d=a.ctrlKey||a.metaKey;break;case 39:if(a.ctrlKey||a.metaKey)b.datepicker._adjustDate(a.target,e?-1:1,"D");d=a.ctrlKey||a.metaKey;a.originalEvent.altKey&&b.datepicker._adjustDate(a.target,
+a.ctrlKey?+b.datepicker._get(c,"stepBigMonths"):+b.datepicker._get(c,"stepMonths"),"M");break;case 40:(a.ctrlKey||a.metaKey)&&b.datepicker._adjustDate(a.target,7,"D");d=a.ctrlKey||a.metaKey;break;default:d=!1}else 36==a.keyCode&&a.ctrlKey?b.datepicker._showDatepicker(this):d=!1;d&&(a.preventDefault(),a.stopPropagation())},_doKeyPress:function(c){var d=b.datepicker._getInst(c.target);if(b.datepicker._get(d,"constrainInput")){var d=b.datepicker._possibleChars(b.datepicker._get(d,"dateFormat")),e=String.fromCharCode(c.charCode==
+a?c.keyCode:c.charCode);return c.ctrlKey||c.metaKey||" ">e||!d||-1<d.indexOf(e)}},_doKeyUp:function(a){a=b.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(b.datepicker.parseDate(b.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,b.datepicker._getFormatConfig(a)))b.datepicker._setDateFromField(a),b.datepicker._updateAlternate(a),b.datepicker._updateDatepicker(a)}catch(c){b.datepicker.log(c)}return!0},_showDatepicker:function(a){a=a.target||a;"input"!=a.nodeName.toLowerCase()&&
+(a=b("input",a.parentNode)[0]);if(!(b.datepicker._isDisabledDatepicker(a)||b.datepicker._lastInput==a)){var c=b.datepicker._getInst(a);b.datepicker._curInst&&b.datepicker._curInst!=c&&(b.datepicker._datepickerShowing&&b.datepicker._triggerOnClose(b.datepicker._curInst),b.datepicker._curInst.dpDiv.stop(!0,!0));var d=b.datepicker._get(c,"beforeShow");g(c.settings,d?d.apply(a,[a,c]):{});c.lastVal=null;b.datepicker._lastInput=a;b.datepicker._setDateFromField(c);b.datepicker._inDialog&&(a.value="");b.datepicker._pos||
+(b.datepicker._pos=b.datepicker._findPos(a),b.datepicker._pos[1]+=a.offsetHeight);var e=!1;b(a).parents().each(function(){e=e|b(this).css("position")=="fixed";return!e});e&&b.browser.opera&&(b.datepicker._pos[0]-=document.documentElement.scrollLeft,b.datepicker._pos[1]-=document.documentElement.scrollTop);d={left:b.datepicker._pos[0],top:b.datepicker._pos[1]};b.datepicker._pos=null;c.dpDiv.empty();c.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});b.datepicker._updateDatepicker(c);d=
+b.datepicker._checkOffset(c,d,e);c.dpDiv.css({position:b.datepicker._inDialog&&b.blockUI?"static":e?"fixed":"absolute",display:"none",left:d.left+"px",top:d.top+"px"});if(!c.inline){var d=b.datepicker._get(c,"showAnim"),h=b.datepicker._get(c,"duration"),m=function(){var a=c.dpDiv.find("iframe.ui-datepicker-cover");if(a.length){var f=b.datepicker._getBorders(c.dpDiv);a.css({left:-f[0],top:-f[1],width:c.dpDiv.outerWidth(),height:c.dpDiv.outerHeight()})}};c.dpDiv.zIndex(b(a).zIndex()+1);b.datepicker._datepickerShowing=
+!0;if(b.effects&&b.effects[d])c.dpDiv.show(d,b.datepicker._get(c,"showOptions"),h,m);else c.dpDiv[d||"show"](d?h:null,m);(!d||!h)&&m();c.input.is(":visible")&&!c.input.is(":disabled")&&c.input.focus();b.datepicker._curInst=c}}},_updateDatepicker:function(a){this.maxRows=4;var c=b.datepicker._getBorders(a.dpDiv);e=a;a.dpDiv.empty().append(this._generateHTML(a));var d=a.dpDiv.find("iframe.ui-datepicker-cover");d.length&&d.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()});
+a.dpDiv.find("."+this._dayOverClass+" a").mouseover();c=this._getNumberOfMonths(a);d=c[1];a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");1<d&&a.dpDiv.addClass("ui-datepicker-multi-"+d).css("width",17*d+"em");a.dpDiv[(1!=c[0]||1!=c[1]?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==b.datepicker._curInst&&(b.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&
+!a.input.is(":disabled")&&a.input[0]!=document.activeElement)&&a.input.focus();if(a.yearshtml){var g=a.yearshtml;setTimeout(function(){g===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);g=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,c,d){var e=a.dpDiv.outerWidth(),g=a.dpDiv.outerHeight(),
+h=a.input?a.input.outerWidth():0,p=a.input?a.input.outerHeight():0,n=document.documentElement.clientWidth+b(document).scrollLeft(),q=document.documentElement.clientHeight+b(document).scrollTop();c.left-=this._get(a,"isRTL")?e-h:0;c.left-=d&&c.left==a.input.offset().left?b(document).scrollLeft():0;c.top-=d&&c.top==a.input.offset().top+p?b(document).scrollTop():0;c.left-=Math.min(c.left,c.left+e>n&&n>e?Math.abs(c.left+e-n):0);c.top-=Math.min(c.top,c.top+g>q&&q>g?Math.abs(g+p):0);return c},_findPos:function(a){for(var c=
+this._get(this._getInst(a),"isRTL");a&&("hidden"==a.type||1!=a.nodeType||b.expr.filters.hidden(a));)a=a[c?"previousSibling":"nextSibling"];a=b(a).offset();return[a.left,a.top]},_triggerOnClose:function(a){var b=this._get(a,"onClose");b&&b.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a])},_hideDatepicker:function(a){var c=this._curInst;if(c&&!(a&&c!=b.data(a,"datepicker"))&&this._datepickerShowing){var a=this._get(c,"showAnim"),d=this._get(c,"duration"),e=function(){b.datepicker._tidyDialog(c);
+this._curInst=null};if(b.effects&&b.effects[a])c.dpDiv.hide(a,b.datepicker._get(c,"showOptions"),d,e);else c.dpDiv["slideDown"==a?"slideUp":"fadeIn"==a?"fadeOut":"hide"](a?d:null,e);a||e();b.datepicker._triggerOnClose(c);this._datepickerShowing=!1;this._lastInput=null;this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),b.blockUI&&(b.unblockUI(),b("body").append(this.dpDiv)));this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},
+_checkExternalClick:function(a){b.datepicker._curInst&&(a=b(a.target),a[0].id!=b.datepicker._mainDivId&&(0==a.parents("#"+b.datepicker._mainDivId).length&&!a.hasClass(b.datepicker.markerClassName)&&!a.hasClass(b.datepicker._triggerClass)&&b.datepicker._datepickerShowing&&(!b.datepicker._inDialog||!b.blockUI))&&b.datepicker._hideDatepicker())},_adjustDate:function(a,c,d){var a=b(a),e=this._getInst(a[0]);this._isDisabledDatepicker(a[0])||(this._adjustInstDate(e,c+("M"==d?this._get(e,"showCurrentAtPos"):
+0),d),this._updateDatepicker(e))},_gotoToday:function(a){var a=b(a),c=this._getInst(a[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate();c.drawMonth=c.selectedMonth=d.getMonth();c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c);this._adjustDate(a)},_selectMonthYear:function(a,c,d){var a=b(a),e=this._getInst(a[0]);e._selectingMonthYear=
+!1;e["selected"+("M"==d?"Month":"Year")]=e["draw"+("M"==d?"Month":"Year")]=parseInt(c.options[c.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_clickMonthYear:function(a){var c=this._getInst(b(a)[0]);c.input&&c._selectingMonthYear&&setTimeout(function(){c.input.focus()},0);c._selectingMonthYear=!c._selectingMonthYear},_selectDay:function(a,c,d,e){var g=b(a);!b(e).hasClass(this._unselectableClass)&&!this._isDisabledDatepicker(g[0])&&(g=this._getInst(g[0]),g.selectedDay=g.currentDay=
+b("a",e).html(),g.selectedMonth=g.currentMonth=c,g.selectedYear=g.currentYear=d,this._selectDate(a,this._formatDate(g,g.currentDay,g.currentMonth,g.currentYear)))},_clearDate:function(a){a=b(a);this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,c){var d=this._getInst(b(a)[0]),c=null!=c?c:this._formatDate(d);d.input&&d.input.val(c);this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[c,d]):d.input&&d.input.trigger("change");d.inline?this._updateDatepicker(d):
+(this._hideDatepicker(),this._lastInput=d.input[0],"object"!=typeof d.input[0]&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var c=this._get(a,"altField");if(c){var d=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),g=this.formatDate(d,e,this._getFormatConfig(a));b(c).each(function(){b(this).val(g)})}},noWeekends:function(a){a=a.getDay();return[0<a&&6>a,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=
+a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,c,d){if(null==a||null==c)throw"Invalid arguments";c="object"==typeof c?c.toString():c+"";if(""==c)return null;for(var e=(d?d.shortYearCutoff:null)||this._defaults.shortYearCutoff,e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),g=(d?d.dayNamesShort:null)||this._defaults.dayNamesShort,h=(d?d.dayNames:null)||this._defaults.dayNames,p=(d?d.monthNamesShort:null)||this._defaults.monthNamesShort,
+n=(d?d.monthNames:null)||this._defaults.monthNames,q=d=-1,o=-1,w=-1,r=!1,u=function(b){(b=E+1<a.length&&a.charAt(E+1)==b)&&E++;return b},s=function(a){var b=u(a),a=RegExp("^\\d{1,"+("@"==a?14:"!"==a?20:"y"==a&&b?4:"o"==a?3:2)+"}"),a=c.substring(B).match(a);if(!a)throw"Missing number at position "+B;B+=a[0].length;return parseInt(a[0],10)},v=function(a,d,f){var a=b.map(u(a)?f:d,function(a,b){return[[b,a]]}).sort(function(a,b){return-(a[1].length-b[1].length)}),e=-1;b.each(a,function(a,b){var d=b[1];
+if(c.substr(B,d.length).toLowerCase()==d.toLowerCase())return e=b[0],B+=d.length,!1});if(-1!=e)return e+1;throw"Unknown name at position "+B;},z=function(){if(c.charAt(B)!=a.charAt(E))throw"Unexpected literal at position "+B;B++},B=0,E=0;E<a.length;E++)if(r)"'"==a.charAt(E)&&!u("'")?r=!1:z();else switch(a.charAt(E)){case "d":o=s("d");break;case "D":v("D",g,h);break;case "o":w=s("o");break;case "m":q=s("m");break;case "M":q=v("M",p,n);break;case "y":d=s("y");break;case "@":var C=new Date(s("@")),d=
+C.getFullYear(),q=C.getMonth()+1,o=C.getDate();break;case "!":C=new Date((s("!")-this._ticksTo1970)/1E4);d=C.getFullYear();q=C.getMonth()+1;o=C.getDate();break;case "'":u("'")?z():r=!0;break;default:z()}if(B<c.length)throw"Extra/unparsed characters found in date: "+c.substring(B);-1==d?d=(new Date).getFullYear():100>d&&(d+=(new Date).getFullYear()-(new Date).getFullYear()%100+(d<=e?0:-100));if(-1<w){q=1;o=w;do{e=this._getDaysInMonth(d,q-1);if(o<=e)break;q++;o-=e}while(1)}C=this._daylightSavingAdjust(new Date(d,
+q-1,o));if(C.getFullYear()!=d||C.getMonth()+1!=q||C.getDate()!=o)throw"Invalid date";return C},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:864E9*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(a,b,c){if(!b)return"";var d=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,e=(c?c.dayNames:
+null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,c=(c?c.monthNames:null)||this._defaults.monthNames,h=function(b){(b=r+1<a.length&&a.charAt(r+1)==b)&&r++;return b},n=function(a,b,c){b=""+b;if(h(a))for(;b.length<c;)b="0"+b;return b},q=function(a,b,c,d){return h(a)?d[b]:c[b]},o="",w=!1;if(b)for(var r=0;r<a.length;r++)if(w)"'"==a.charAt(r)&&!h("'")?w=!1:o+=a.charAt(r);else switch(a.charAt(r)){case "d":o+=n("d",b.getDate(),2);break;case "D":o+=q("D",b.getDay(),
+d,e);break;case "o":o+=n("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864E5),3);break;case "m":o+=n("m",b.getMonth()+1,2);break;case "M":o+=q("M",b.getMonth(),g,c);break;case "y":o+=h("y")?b.getFullYear():(10>b.getYear()%100?"0":"")+b.getYear()%100;break;case "@":o+=b.getTime();break;case "!":o+=1E4*b.getTime()+this._ticksTo1970;break;case "'":h("'")?o+="'":w=!0;break;default:o+=a.charAt(r)}return o},_possibleChars:function(a){for(var b=
+"",c=!1,d=function(b){(b=e+1<a.length&&a.charAt(e+1)==b)&&e++;return b},e=0;e<a.length;e++)if(c)"'"==a.charAt(e)&&!d("'")?c=!1:b+=a.charAt(e);else switch(a.charAt(e)){case "d":case "m":case "y":case "@":b+="0123456789";break;case "D":case "M":return null;case "'":d("'")?b+="'":c=!0;break;default:b+=a.charAt(e)}return b},_get:function(b,c){return b.settings[c]!==a?b.settings[c]:this._defaults[c]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),d=a.lastVal=
+a.input?a.input.val():null,e,g;e=g=this._getDefaultDate(a);var h=this._getFormatConfig(a);try{e=this.parseDate(c,d,h)||g}catch(n){this.log(n),d=b?"":d}a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();a.currentDay=d?e.getDate():0;a.currentMonth=d?e.getMonth():0;a.currentYear=d?e.getFullYear():0;this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,
+c,d){var e=function(a){var b=new Date;b.setDate(b.getDate()+a);return b},g=function(c){try{return b.datepicker.parseDate(b.datepicker._get(a,"dateFormat"),c,b.datepicker._getFormatConfig(a))}catch(d){}for(var e=(c.toLowerCase().match(/^c/)?b.datepicker._getDate(a):null)||new Date,g=e.getFullYear(),h=e.getMonth(),e=e.getDate(),i=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=i.exec(c);l;){switch(l[2]||"d"){case "d":case "D":e+=parseInt(l[1],10);break;case "w":case "W":e+=7*parseInt(l[1],10);break;case "m":case "M":h+=
+parseInt(l[1],10);e=Math.min(e,b.datepicker._getDaysInMonth(g,h));break;case "y":case "Y":g+=parseInt(l[1],10),e=Math.min(e,b.datepicker._getDaysInMonth(g,h))}l=i.exec(c)}return new Date(g,h,e)};if(c=(c=null==c||""===c?d:"string"==typeof c?g(c):"number"==typeof c?isNaN(c)?d:e(c):new Date(c.getTime()))&&"Invalid Date"==c.toString()?d:c)c.setHours(0),c.setMinutes(0),c.setSeconds(0),c.setMilliseconds(0);return this._daylightSavingAdjust(c)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(12<
+a.getHours()?a.getHours()+2:0);return a},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,g=a.selectedYear,b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();(e!=a.selectedMonth||g!=a.selectedYear)&&!c&&this._notifyChange(a);this._adjustInstDate(a);a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||
+a.input&&""==a.input.val()?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var c=new Date,c=this._daylightSavingAdjust(new Date(c.getFullYear(),c.getMonth(),c.getDate())),d=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),g=this._get(a,"hideIfNoPrevNext"),m=this._get(a,"navigationAsDateFormat"),p=this._getNumberOfMonths(a),n=this._get(a,"showCurrentAtPos"),q=this._get(a,"stepMonths"),o=1!=p[0]||1!=p[1],w=this._daylightSavingAdjust(!a.currentDay?
+new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),r=this._getMinMaxDate(a,"min"),u=this._getMinMaxDate(a,"max"),n=a.drawMonth-n,s=a.drawYear;0>n&&(n+=12,s--);if(u)for(var v=this._daylightSavingAdjust(new Date(u.getFullYear(),u.getMonth()-p[0]*p[1]+1,u.getDate())),v=r&&v<r?r:v;this._daylightSavingAdjust(new Date(s,n,1))>v;)n--,0>n&&(n=11,s--);a.drawMonth=n;a.drawYear=s;var v=this._get(a,"prevText"),v=!m?v:this.formatDate(v,this._daylightSavingAdjust(new Date(s,n-q,1)),this._getFormatConfig(a)),
+v=this._canAdjustMonth(a,-1,s,n)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+h+".datepicker._adjustDate('#"+a.id+"', -"+q+", 'M');\" title=\""+v+'"><span class="ui-icon ui-icon-circle-triangle-'+(d?"e":"w")+'">'+v+"</span></a>":g?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+v+'"><span class="ui-icon ui-icon-circle-triangle-'+(d?"e":"w")+'">'+v+"</span></a>",z=this._get(a,"nextText"),z=!m?z:this.formatDate(z,this._daylightSavingAdjust(new Date(s,
+n+q,1)),this._getFormatConfig(a)),g=this._canAdjustMonth(a,1,s,n)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+h+".datepicker._adjustDate('#"+a.id+"', +"+q+", 'M');\" title=\""+z+'"><span class="ui-icon ui-icon-circle-triangle-'+(d?"w":"e")+'">'+z+"</span></a>":g?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+z+'"><span class="ui-icon ui-icon-circle-triangle-'+(d?"w":"e")+'">'+z+"</span></a>",q=this._get(a,"currentText"),z=this._get(a,"gotoCurrent")&&
+a.currentDay?w:c,q=!m?q:this.formatDate(q,z,this._getFormatConfig(a)),m=!a.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+h+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>":"",e=e?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(d?m:"")+(this._isInRange(a,z)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+
+h+".datepicker._gotoToday('#"+a.id+"');\">"+q+"</button>":"")+(d?"":m)+"</div>":"",m=parseInt(this._get(a,"firstDay"),10),m=isNaN(m)?0:m,q=this._get(a,"showWeek"),z=this._get(a,"dayNames");this._get(a,"dayNamesShort");var B=this._get(a,"dayNamesMin"),E=this._get(a,"monthNames"),C=this._get(a,"monthNamesShort"),O=this._get(a,"beforeShowDay"),K=this._get(a,"showOtherMonths"),S=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var P=this._getDefaultDate(a),G="",H=0;H<p[0];H++){var L=
+"";this.maxRows=4;for(var I=0;I<p[1];I++){var Q=this._daylightSavingAdjust(new Date(s,n,a.selectedDay)),A=" ui-corner-all",y="";if(o){y+='<div class="ui-datepicker-group';if(1<p[1])switch(I){case 0:y+=" ui-datepicker-group-first";A=" ui-corner-"+(d?"right":"left");break;case p[1]-1:y+=" ui-datepicker-group-last";A=" ui-corner-"+(d?"left":"right");break;default:y+=" ui-datepicker-group-middle",A=""}y+='">'}for(var y=y+('<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+A+'">'+(/all|left/.test(A)&&
+0==H?d?g:v:"")+(/all|right/.test(A)&&0==H?d?v:g:"")+this._generateMonthYearHeader(a,n,s,r,u,0<H||0<I,E,C)+'</div><table class="ui-datepicker-calendar"><thead><tr>'),D=q?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"",A=0;7>A;A++)var x=(A+m)%7,D=D+("<th"+(5<=(A+m+6)%7?' class="ui-datepicker-week-end"':"")+'><span title="'+z[x]+'">'+B[x]+"</span></th>");y+=D+"</tr></thead><tbody>";D=this._getDaysInMonth(s,n);s==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,
+D));A=(this._getFirstDayOfMonth(s,n)-m+7)%7;D=Math.ceil((A+D)/7);this.maxRows=D=o?this.maxRows>D?this.maxRows:D:D;for(var x=this._daylightSavingAdjust(new Date(s,n,1-A)),R=0;R<D;R++){for(var y=y+"<tr>",M=!q?"":'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(x)+"</td>",A=0;7>A;A++){var J=O?O.apply(a.input?a.input[0]:null,[x]):[!0,""],F=x.getMonth()!=n,N=F&&!S||!J[0]||r&&x<r||u&&x>u,M=M+('<td class="'+(5<=(A+m+6)%7?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+
+(x.getTime()==Q.getTime()&&n==a.selectedMonth&&a._keyEvent||P.getTime()==x.getTime()&&P.getTime()==Q.getTime()?" "+this._dayOverClass:"")+(N?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!K?"":" "+J[1]+(x.getTime()==w.getTime()?" "+this._currentClass:"")+(x.getTime()==c.getTime()?" ui-datepicker-today":""))+'"'+((!F||K)&&J[2]?' title="'+J[2]+'"':"")+(N?"":' onclick="DP_jQuery_'+h+".datepicker._selectDay('#"+a.id+"',"+x.getMonth()+","+x.getFullYear()+', this);return false;"')+">"+(F&&!K?
+"&#xa0;":N?'<span class="ui-state-default">'+x.getDate()+"</span>":'<a class="ui-state-default'+(x.getTime()==c.getTime()?" ui-state-highlight":"")+(x.getTime()==w.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+'" href="#">'+x.getDate()+"</a>")+"</td>");x.setDate(x.getDate()+1);x=this._daylightSavingAdjust(x)}y+=M+"</tr>"}n++;11<n&&(n=0,s++);y+="</tbody></table>"+(o?"</div>"+(0<p[0]&&I==p[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");L+=y}G+=L}G+=e+(b.browser.msie&&
+7>parseInt(b.browser.version,10)&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':"");a._keyEvent=!1;return G},_generateMonthYearHeader:function(a,b,c,d,e,g,p,n){var q=this._get(a,"changeMonth"),o=this._get(a,"changeYear"),w=this._get(a,"showMonthAfterYear"),r='<div class="ui-datepicker-title">',u="";if(g||!q)u+='<span class="ui-datepicker-month">'+p[b]+"</span>";else{for(var p=d&&d.getFullYear()==c,s=e&&e.getFullYear()==c,u=u+('<select class="ui-datepicker-month" onchange="DP_jQuery_'+
+h+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" onclick=\"DP_jQuery_"+h+".datepicker._clickMonthYear('#"+a.id+"');\">"),v=0;12>v;v++)if((!p||v>=d.getMonth())&&(!s||v<=e.getMonth()))u+='<option value="'+v+'"'+(v==b?' selected="selected"':"")+">"+n[v]+"</option>";u+="</select>"}w||(r+=u+(g||!q||!o?"&#xa0;":""));if(!a.yearshtml)if(a.yearshtml="",g||!o)r+='<span class="ui-datepicker-year">'+c+"</span>";else{var n=this._get(a,"yearRange").split(":"),z=(new Date).getFullYear(),p=function(a){a=
+a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?z+parseInt(a,10):parseInt(a,10);return isNaN(a)?z:a},b=p(n[0]),n=Math.max(b,p(n[1]||"")),b=d?Math.max(b,d.getFullYear()):b,n=e?Math.min(n,e.getFullYear()):n;for(a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+h+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" onclick=\"DP_jQuery_"+h+".datepicker._clickMonthYear('#"+a.id+"');\">";b<=n;b++)a.yearshtml+='<option value="'+b+'"'+(b==c?' selected="selected"':
+"")+">"+b+"</option>";a.yearshtml+="</select>";r+=a.yearshtml;a.yearshtml=null}r+=this._get(a,"yearSuffix");w&&(r+=(g||!q||!o?"&#xa0;":"")+u);return r+"</div>"},_adjustInstDate:function(a,b,c){var d=a.drawYear+("Y"==c?b:0),e=a.drawMonth+("M"==c?b:0),b=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+("D"==c?b:0),d=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,b)));a.selectedDay=d.getDate();a.drawMonth=a.selectedMonth=d.getMonth();a.drawYear=a.selectedYear=d.getFullYear();("M"==c||
+"Y"==c)&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),c=c&&b<c?c:b;return d&&c>d?d:c},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return null==a?[1,1]:"number"==typeof a?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,
+b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),c=this._daylightSavingAdjust(new Date(c,d+(0>b?b:e[0]*e[1]),1));0>b&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=
+d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff"),b="string"!=typeof b?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);b=b?"object"==typeof b?b:this._daylightSavingAdjust(new Date(d,
+c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});b.fn.datepicker=function(a){if(!this.length)return this;b.datepicker.initialized||(b(document).mousedown(b.datepicker._checkExternalClick).find("body").append(b.datepicker.dpDiv),b.datepicker.initialized=!0);var c=Array.prototype.slice.call(arguments,1);return"string"==typeof a&&("isDisabled"==a||"getDate"==a||"widget"==a)||"option"==
+a&&2==arguments.length&&"string"==typeof arguments[1]?b.datepicker["_"+a+"Datepicker"].apply(b.datepicker,[this[0]].concat(c)):this.each(function(){typeof a=="string"?b.datepicker["_"+a+"Datepicker"].apply(b.datepicker,[this].concat(c)):b.datepicker._attachDatepicker(this,a)})};b.datepicker=new c;b.datepicker.initialized=!1;b.datepicker.uuid=(new Date).getTime();b.datepicker.version="1.8.14";window["DP_jQuery_"+h]=b})(jQuery);
+(function(b,a){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow");
+this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(b){if(b===a)return this._value();this._setOption("value",b);return this},_setOption:function(a,d){"value"===a&&(this.options.value=d,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete"));b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;"number"!==typeof a&&(a=0);return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*
+this._value()/this.options.max},_refreshValue:function(){var a=this.value(),b=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change"));this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(b.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.14"})})(jQuery);
+jQuery.effects||function(b,a){function c(a){var c;return a&&a.constructor==Array&&3==a.length?a:(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(a))?[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)]:(c=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(a))?[2.55*parseFloat(c[1]),2.55*parseFloat(c[2]),2.55*parseFloat(c[3])]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))?[parseInt(c[1],16),parseInt(c[2],
+16),parseInt(c[3],16)]:(c=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(a))?[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)]:/rgba\(0, 0, 0, 0\)/.exec(a)?i.transparent:i[b.trim(a).toLowerCase()]}function d(){var a=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,b={},c,d;if(a&&a.length&&a[0]&&a[a[0]])for(var e=a.length;e--;)c=a[e],"string"==typeof a[c]&&(d=c.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),b[d]=a[c]);else for(c in a)"string"===
+typeof a[c]&&(b[c]=a[c]);return b}function g(a){var c,d;for(c in a)d=a[c],(null==d||b.isFunction(d)||c in k||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete a[c];return a}function h(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function e(a,c,d,e){"object"==typeof a&&(e=c,d=null,c=a,a=c.effect);b.isFunction(c)&&(e=c,d=null,c={});if("number"==typeof c||b.fx.speeds[c])e=d,d=c,c={};b.isFunction(d)&&(e=d,d=null);c=c||{};d=d||c.duration;d=b.fx.off?0:"number"==typeof d?
+d:d in b.fx.speeds?b.fx.speeds[d]:b.fx.speeds._default;e=e||c.complete;return[a,c,d,e]}function f(a){return!a||("number"===typeof a||b.fx.speeds[a])||"string"===typeof a&&!b.effects[a]?!0:!1}b.effects={};b.each("backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor borderColor color outlineColor".split(" "),function(a,d){b.fx.step[d]=function(a){if(!a.colorInit){var e;e=a.elem;var f=d,g;do{g=b.curCSS(e,f);if(g!=""&&g!="transparent"||b.nodeName(e,"body"))break;f="backgroundColor"}while(e=
+e.parentNode);e=c(g);a.start=e;a.end=c(a.end);a.colorInit=true}a.elem.style[d]="rgb("+Math.max(Math.min(parseInt(a.pos*(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var i={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],
+darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],
+maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},j=["add","remove","toggle"],k={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};b.effects.animateClass=function(a,c,e,f){b.isFunction(e)&&(f=e,e=null);return this.queue(function(){var i=b(this),o=i.attr("style")||
+" ",k=g(d.call(this)),r,u=i.attr("class");b.each(j,function(b,c){if(a[c])i[c+"Class"](a[c])});r=g(d.call(this));i.attr("class",u);i.animate(h(k,r),{queue:false,duration:c,easing:e,complete:function(){b.each(j,function(b,c){if(a[c])i[c+"Class"](a[c])});if(typeof i.attr("style")=="object"){i.attr("style").cssText="";i.attr("style").cssText=o}else i.attr("style",o);f&&f.apply(this,arguments);b.dequeue(this)}})})};b.fn.extend({_addClass:b.fn.addClass,addClass:function(a,c,d,e){return c?b.effects.animateClass.apply(this,
+[{add:a},c,d,e]):this._addClass(a)},_removeClass:b.fn.removeClass,removeClass:function(a,c,d,e){return c?b.effects.animateClass.apply(this,[{remove:a},c,d,e]):this._removeClass(a)},_toggleClass:b.fn.toggleClass,toggleClass:function(c,d,e,f,g){return"boolean"==typeof d||d===a?e?b.effects.animateClass.apply(this,[d?{add:c}:{remove:c},e,f,g]):this._toggleClass(c,d):b.effects.animateClass.apply(this,[{toggle:c},d,e,f])},switchClass:function(a,c,d,e,f){return b.effects.animateClass.apply(this,[{add:c,
+remove:a},d,e,f])}});b.extend(b.effects,{version:"1.8.14",save:function(a,b){for(var c=0;c<b.length;c++)null!==b[c]&&a.data("ec.storage."+b[c],a[0].style[b[c]])},restore:function(a,b){for(var c=0;c<b.length;c++)null!==b[c]&&a.css(b[c],a.data("ec.storage."+b[c]))},setMode:function(a,b){"toggle"==b&&(b=a.is(":hidden")?"show":"hide");return b},getBaseline:function(a,b){var c,d;switch(a[0]){case "top":c=0;break;case "middle":c=0.5;break;case "bottom":c=1;break;default:c=a[0]/b.height}switch(a[1]){case "left":d=
+0;break;case "center":d=0.5;break;case "right":d=1;break;default:d=a[1]/b.width}return{x:d,y:c}},createWrapper:function(a){if(a.parent().is(".ui-effects-wrapper"))return a.parent();var c={width:a.outerWidth(!0),height:a.outerHeight(!0),"float":a.css("float")},d=b("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0});a.wrap(d);d=a.parent();"static"==a.css("position")?(d.css({position:"relative"}),a.css({position:"relative"})):
+(b.extend(c,{position:a.css("position"),zIndex:a.css("z-index")}),b.each(["top","left","bottom","right"],function(b,d){c[d]=a.css(d);isNaN(parseInt(c[d],10))&&(c[d]="auto")}),a.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"}));return d.css(c).show()},removeWrapper:function(a){return a.parent().is(".ui-effects-wrapper")?a.parent().replaceWith(a):a},setTransition:function(a,c,d,e){e=e||{};b.each(c,function(b,c){unit=a.cssUnit(c);0<unit[0]&&(e[c]=unit[0]*d+unit[1])});return e}});b.fn.extend({effect:function(a,
+c,d,f){var g=e.apply(this,arguments),h={options:g[1],duration:g[2],callback:g[3]},g=h.options.mode,i=b.effects[a];return b.fx.off||!i?g?this[g](h.duration,h.callback):this.each(function(){h.callback&&h.callback.call(this)}):i.call(this,h)},_show:b.fn.show,show:function(a){if(f(a))return this._show.apply(this,arguments);var b=e.apply(this,arguments);b[1].mode="show";return this.effect.apply(this,b)},_hide:b.fn.hide,hide:function(a){if(f(a))return this._hide.apply(this,arguments);var b=e.apply(this,
+arguments);b[1].mode="hide";return this.effect.apply(this,b)},__toggle:b.fn.toggle,toggle:function(a){if(f(a)||"boolean"===typeof a||b.isFunction(a))return this.__toggle.apply(this,arguments);var c=e.apply(this,arguments);c[1].mode="toggle";return this.effect.apply(this,c)},cssUnit:function(a){var c=this.css(a),d=[];b.each(["em","px","%","pt"],function(a,b){0<c.indexOf(b)&&(d=[parseFloat(c),b])});return d}});b.easing.jswing=b.easing.swing;b.extend(b.easing,{def:"easeOutQuad",swing:function(a,c,d,
+e,f){return b.easing[b.easing.def](a,c,d,e,f)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){return 1>(b/=e/2)?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){return 1>(b/=e/2)?d/2*b*b*b+c:d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},
+easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){return 1>(b/=e/2)?d/2*b*b*b*b+c:-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){return 1>(b/=e/2)?d/2*b*b*b*b*b+c:d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/
+e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return 0==b?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){return 0==b?c:b==e?c+d:1>(b/=e/2)?d/2*Math.pow(2,10*(b-1))+c:d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*
+b)+c},easeInOutCirc:function(a,b,c,d,e){return 1>(b/=e/2)?-d/2*(Math.sqrt(1-b*b)-1)+c:d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var a=1.70158,f=0,g=d;if(0==b)return c;if(1==(b/=e))return c+d;f||(f=0.3*e);g<Math.abs(d)?(g=d,a=f/4):a=f/(2*Math.PI)*Math.asin(d/g);return-(g*Math.pow(2,10*(b-=1))*Math.sin((b*e-a)*2*Math.PI/f))+c},easeOutElastic:function(a,b,c,d,e){var a=1.70158,f=0,g=d;if(0==b)return c;if(1==(b/=e))return c+d;f||(f=0.3*e);g<Math.abs(d)?(g=d,a=f/4):a=f/(2*Math.PI)*
+Math.asin(d/g);return g*Math.pow(2,-10*b)*Math.sin((b*e-a)*2*Math.PI/f)+d+c},easeInOutElastic:function(a,b,c,d,e){var a=1.70158,f=0,g=d;if(0==b)return c;if(2==(b/=e/2))return c+d;f||(f=e*0.3*1.5);g<Math.abs(d)?(g=d,a=f/4):a=f/(2*Math.PI)*Math.asin(d/g);return 1>b?-0.5*g*Math.pow(2,10*(b-=1))*Math.sin((b*e-a)*2*Math.PI/f)+c:0.5*g*Math.pow(2,-10*(b-=1))*Math.sin((b*e-a)*2*Math.PI/f)+d+c},easeInBack:function(b,c,d,e,f,g){g==a&&(g=1.70158);return e*(c/=f)*c*((g+1)*c-g)+d},easeOutBack:function(b,c,d,e,
+f,g){g==a&&(g=1.70158);return e*((c=c/f-1)*c*((g+1)*c+g)+1)+d},easeInOutBack:function(b,c,d,e,f,g){g==a&&(g=1.70158);return 1>(c/=f/2)?e/2*c*c*(((g*=1.525)+1)*c-g)+d:e/2*((c-=2)*c*(((g*=1.525)+1)*c+g)+2)+d},easeInBounce:function(a,c,d,e,f){return e-b.easing.easeOutBounce(a,f-c,0,e,f)+d},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?d*7.5625*b*b+c:b<2/2.75?d*(7.5625*(b-=1.5/2.75)*b+0.75)+c:b<2.5/2.75?d*(7.5625*(b-=2.25/2.75)*b+0.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+0.984375)+c},easeInOutBounce:function(a,
+c,d,e,f){return c<f/2?0.5*b.easing.easeInBounce(a,2*c,0,e,f)+d:0.5*b.easing.easeOutBounce(a,2*c-f,0,e,f)+0.5*e+d}})}(jQuery);
+(function(b){b.effects.blind=function(a){return this.queue(function(){var c=b(this),d=["position","top","bottom","left","right"],g=b.effects.setMode(c,a.options.mode||"hide"),h=a.options.direction||"vertical";b.effects.save(c,d);c.show();var e=b.effects.createWrapper(c).css({overflow:"hidden"}),f="vertical"==h?"height":"width",h="vertical"==h?e.height():e.width();"show"==g&&e.css(f,0);var i={};i[f]="show"==g?h:0;e.animate(i,a.duration,a.options.easing,function(){"hide"==g&&c.hide();b.effects.restore(c,
+d);b.effects.removeWrapper(c);a.callback&&a.callback.apply(c[0],arguments);c.dequeue()})})}})(jQuery);
+(function(b){b.effects.bounce=function(a){return this.queue(function(){var c=b(this),d=["position","top","bottom","left","right"],g=b.effects.setMode(c,a.options.mode||"effect"),h=a.options.direction||"up",e=a.options.distance||20,f=a.options.times||5,i=a.duration||250;/show|hide/.test(g)&&d.push("opacity");b.effects.save(c,d);c.show();b.effects.createWrapper(c);var j="up"==h||"down"==h?"top":"left",h="up"==h||"left"==h?"pos":"neg",e=a.options.distance||("top"==j?c.outerHeight({margin:!0})/3:c.outerWidth({margin:!0})/
+3);"show"==g&&c.css("opacity",0).css(j,"pos"==h?-e:e);"hide"==g&&(e/=2*f);"hide"!=g&&f--;if("show"==g){var k={opacity:1};k[j]=("pos"==h?"+=":"-=")+e;c.animate(k,i/2,a.options.easing);e/=2;f--}for(k=0;k<f;k++){var l={},m={};l[j]=("pos"==h?"-=":"+=")+e;m[j]=("pos"==h?"+=":"-=")+e;c.animate(l,i/2,a.options.easing).animate(m,i/2,a.options.easing);e="hide"==g?2*e:e/2}"hide"==g?(k={opacity:0},k[j]=("pos"==h?"-=":"+=")+e,c.animate(k,i/2,a.options.easing,function(){c.hide();b.effects.restore(c,d);b.effects.removeWrapper(c);
+a.callback&&a.callback.apply(this,arguments)})):(l={},m={},l[j]=("pos"==h?"-=":"+=")+e,m[j]=("pos"==h?"+=":"-=")+e,c.animate(l,i/2,a.options.easing).animate(m,i/2,a.options.easing,function(){b.effects.restore(c,d);b.effects.removeWrapper(c);a.callback&&a.callback.apply(this,arguments)}));c.queue("fx",function(){c.dequeue()});c.dequeue()})}})(jQuery);
+(function(b){b.effects.clip=function(a){return this.queue(function(){var c=b(this),d="position top bottom left right height width".split(" "),g=b.effects.setMode(c,a.options.mode||"hide"),h=a.options.direction||"vertical";b.effects.save(c,d);c.show();var e=b.effects.createWrapper(c).css({overflow:"hidden"}),e="IMG"==c[0].tagName?e:c,f="vertical"==h?"height":"width",i="vertical"==h?"top":"left",h="vertical"==h?e.height():e.width();"show"==g&&(e.css(f,0),e.css(i,h/2));var j={};j[f]="show"==g?h:0;j[i]=
+"show"==g?0:h/2;e.animate(j,{queue:!1,duration:a.duration,easing:a.options.easing,complete:function(){g=="hide"&&c.hide();b.effects.restore(c,d);b.effects.removeWrapper(c);a.callback&&a.callback.apply(c[0],arguments);c.dequeue()}})})}})(jQuery);
+(function(b){b.effects.drop=function(a){return this.queue(function(){var c=b(this),d="position top bottom left right opacity".split(" "),g=b.effects.setMode(c,a.options.mode||"hide"),h=a.options.direction||"left";b.effects.save(c,d);c.show();b.effects.createWrapper(c);var e="up"==h||"down"==h?"top":"left",h="up"==h||"left"==h?"pos":"neg",f=a.options.distance||("top"==e?c.outerHeight({margin:!0})/2:c.outerWidth({margin:!0})/2);"show"==g&&c.css("opacity",0).css(e,"pos"==h?-f:f);var i={opacity:"show"==
+g?1:0};i[e]=("show"==g?"pos"==h?"+=":"-=":"pos"==h?"-=":"+=")+f;c.animate(i,{queue:!1,duration:a.duration,easing:a.options.easing,complete:function(){"hide"==g&&c.hide();b.effects.restore(c,d);b.effects.removeWrapper(c);a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(b){b.effects.explode=function(a){return this.queue(function(){var c=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3,d=a.options.pieces?Math.round(Math.sqrt(a.options.pieces)):3;a.options.mode="toggle"==a.options.mode?b(this).is(":visible")?"hide":"show":a.options.mode;var g=b(this).show().css("visibility","hidden"),h=g.offset();h.top-=parseInt(g.css("marginTop"),10)||0;h.left-=parseInt(g.css("marginLeft"),10)||0;for(var e=g.outerWidth(!0),f=g.outerHeight(!0),i=0;i<c;i++)for(var j=
+0;j<d;j++)g.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-j*(e/d),top:-i*(f/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:e/d,height:f/c,left:h.left+j*(e/d)+("show"==a.options.mode?(j-Math.floor(d/2))*(e/d):0),top:h.top+i*(f/c)+("show"==a.options.mode?(i-Math.floor(c/2))*(f/c):0),opacity:"show"==a.options.mode?0:1}).animate({left:h.left+j*(e/d)+("show"==a.options.mode?0:(j-Math.floor(d/2))*(e/d)),top:h.top+
+i*(f/c)+("show"==a.options.mode?0:(i-Math.floor(c/2))*(f/c)),opacity:"show"==a.options.mode?1:0},a.duration||500);setTimeout(function(){"show"==a.options.mode?g.css({visibility:"visible"}):g.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(g[0]);g.dequeue();b("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery);
+(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:!1,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(b){b.effects.fold=function(a){return this.queue(function(){var c=b(this),d=["position","top","bottom","left","right"],g=b.effects.setMode(c,a.options.mode||"hide"),h=a.options.size||15,e=!!a.options.horizFirst,f=a.duration?a.duration/2:b.fx.speeds._default/2;b.effects.save(c,d);c.show();var i=b.effects.createWrapper(c).css({overflow:"hidden"}),j="show"==g!=e,k=j?["width","height"]:["height","width"],j=j?[i.width(),i.height()]:[i.height(),i.width()],l=/([0-9]+)%/.exec(h);l&&(h=parseInt(l[1],
+10)/100*j["hide"==g?0:1]);"show"==g&&i.css(e?{height:0,width:h}:{height:h,width:0});e={};l={};e[k[0]]="show"==g?j[0]:h;l[k[1]]="show"==g?j[1]:0;i.animate(e,f,a.options.easing).animate(l,f,a.options.easing,function(){"hide"==g&&c.hide();b.effects.restore(c,d);b.effects.removeWrapper(c);a.callback&&a.callback.apply(c[0],arguments);c.dequeue()})})}})(jQuery);
+(function(b){b.effects.highlight=function(a){return this.queue(function(){var c=b(this),d=["backgroundImage","backgroundColor","opacity"],g=b.effects.setMode(c,a.options.mode||"show"),h={backgroundColor:c.css("backgroundColor")};"hide"==g&&(h.opacity=0);b.effects.save(c,d);c.show().css({backgroundImage:"none",backgroundColor:a.options.color||"#ffff99"}).animate(h,{queue:!1,duration:a.duration,easing:a.options.easing,complete:function(){g=="hide"&&c.hide();b.effects.restore(c,d);g=="show"&&!b.support.opacity&&
+this.style.removeAttribute("filter");a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(b){b.effects.pulsate=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"show");times=2*(a.options.times||5)-1;duration=a.duration?a.duration/2:b.fx.speeds._default/2;isVisible=c.is(":visible");animateTo=0;isVisible||(c.css("opacity",0).show(),animateTo=1);("hide"==d&&isVisible||"show"==d&&!isVisible)&&times--;for(d=0;d<times;d++)c.animate({opacity:animateTo},duration,a.options.easing),animateTo=(animateTo+1)%2;c.animate({opacity:animateTo},duration,
+a.options.easing,function(){animateTo==0&&c.hide();a.callback&&a.callback.apply(this,arguments)});c.queue("fx",function(){c.dequeue()}).dequeue()})}})(jQuery);
+(function(b){b.effects.puff=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide"),g=parseInt(a.options.percent,10)||150,h=g/100,e={height:c.height(),width:c.width()};b.extend(a.options,{fade:!0,mode:d,percent:"hide"==d?g:100,from:"hide"==d?e:{height:e.height*h,width:e.width*h}});c.effect("scale",a.options,a.duration,a.callback);c.dequeue()})};b.effects.scale=function(a){return this.queue(function(){var c=b(this),d=b.extend(!0,{},a.options),g=b.effects.setMode(c,
+a.options.mode||"effect"),h=parseInt(a.options.percent,10)||(0==parseInt(a.options.percent,10)?0:"hide"==g?0:100),e=a.options.direction||"both",f=a.options.origin;"effect"!=g&&(d.origin=f||["middle","center"],d.restore=!0);f={height:c.height(),width:c.width()};c.from=a.options.from||("show"==g?{height:0,width:0}:f);c.to={height:f.height*("horizontal"!=e?h/100:1),width:f.width*("vertical"!=e?h/100:1)};if(a.options.fade&&("show"==g&&(c.from.opacity=0,c.to.opacity=1),"hide"==g))c.from.opacity=1,c.to.opacity=
+0;d.from=c.from;d.to=c.to;d.mode=g;c.effect("size",d,a.duration,a.callback);c.dequeue()})};b.effects.size=function(a){return this.queue(function(){var c=b(this),d="position top bottom left right width height overflow opacity".split(" "),g="position top bottom left right overflow opacity".split(" "),h=["width","height","overflow"],e=["fontSize"],f=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],i=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],j=b.effects.setMode(c,
+a.options.mode||"effect"),k=a.options.restore||!1,l=a.options.scale||"both",m=a.options.origin,p={height:c.height(),width:c.width()};c.from=a.options.from||p;c.to=a.options.to||p;m&&(m=b.effects.getBaseline(m,p),c.from.top=(p.height-c.from.height)*m.y,c.from.left=(p.width-c.from.width)*m.x,c.to.top=(p.height-c.to.height)*m.y,c.to.left=(p.width-c.to.width)*m.x);var n=c.from.height/p.height,q=c.from.width/p.width,o=c.to.height/p.height,w=c.to.width/p.width;if("box"==l||"both"==l)if(n!=o&&(d=d.concat(f),
+c.from=b.effects.setTransition(c,f,n,c.from),c.to=b.effects.setTransition(c,f,o,c.to)),q!=w)d=d.concat(i),c.from=b.effects.setTransition(c,i,q,c.from),c.to=b.effects.setTransition(c,i,w,c.to);if(("content"==l||"both"==l)&&n!=o)d=d.concat(e),c.from=b.effects.setTransition(c,e,n,c.from),c.to=b.effects.setTransition(c,e,o,c.to);b.effects.save(c,k?d:g);c.show();b.effects.createWrapper(c);c.css("overflow","hidden").css(c.from);if("content"==l||"both"==l)f=f.concat(["marginTop","marginBottom"]).concat(e),
+i=i.concat(["marginLeft","marginRight"]),h=d.concat(f).concat(i),c.find("*[width]").each(function(){child=b(this);k&&b.effects.save(child,h);var c=child.height(),d=child.width();child.from={height:c*n,width:d*q};child.to={height:c*o,width:d*w};if(n!=o){child.from=b.effects.setTransition(child,f,n,child.from);child.to=b.effects.setTransition(child,f,o,child.to)}if(q!=w){child.from=b.effects.setTransition(child,i,q,child.from);child.to=b.effects.setTransition(child,i,w,child.to)}child.css(child.from);
+child.animate(child.to,a.duration,a.options.easing,function(){k&&b.effects.restore(child,h)})});c.animate(c.to,{queue:!1,duration:a.duration,easing:a.options.easing,complete:function(){c.to.opacity===0&&c.css("opacity",c.from.opacity);j=="hide"&&c.hide();b.effects.restore(c,k?d:g);b.effects.removeWrapper(c);a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(b){b.effects.shake=function(a){return this.queue(function(){var c=b(this),d=["position","top","bottom","left","right"];b.effects.setMode(c,a.options.mode||"effect");var g=a.options.direction||"left",h=a.options.distance||20,e=a.options.times||3,f=a.duration||a.options.duration||140;b.effects.save(c,d);c.show();b.effects.createWrapper(c);var i="up"==g||"down"==g?"top":"left",j="up"==g||"left"==g?"pos":"neg",g={},k={},l={};g[i]=("pos"==j?"-=":"+=")+h;k[i]=("pos"==j?"+=":"-=")+2*h;l[i]=("pos"==
+j?"-=":"+=")+2*h;c.animate(g,f,a.options.easing);for(h=1;h<e;h++)c.animate(k,f,a.options.easing).animate(l,f,a.options.easing);c.animate(k,f,a.options.easing).animate(g,f/2,a.options.easing,function(){b.effects.restore(c,d);b.effects.removeWrapper(c);a.callback&&a.callback.apply(this,arguments)});c.queue("fx",function(){c.dequeue()});c.dequeue()})}})(jQuery);
+(function(b){b.effects.slide=function(a){return this.queue(function(){var c=b(this),d=["position","top","bottom","left","right"],g=b.effects.setMode(c,a.options.mode||"show"),h=a.options.direction||"left";b.effects.save(c,d);c.show();b.effects.createWrapper(c).css({overflow:"hidden"});var e="up"==h||"down"==h?"top":"left",h="up"==h||"left"==h?"pos":"neg",f=a.options.distance||("top"==e?c.outerHeight({margin:!0}):c.outerWidth({margin:!0}));"show"==g&&c.css(e,"pos"==h?isNaN(f)?"-"+f:-f:f);var i={};
+i[e]=("show"==g?"pos"==h?"+=":"-=":"pos"==h?"-=":"+=")+f;c.animate(i,{queue:!1,duration:a.duration,easing:a.options.easing,complete:function(){"hide"==g&&c.hide();b.effects.restore(c,d);b.effects.removeWrapper(c);a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(b){b.effects.transfer=function(a){return this.queue(function(){var c=b(this),d=b(a.options.to),g=d.offset(),d={top:g.top,left:g.left,height:d.innerHeight(),width:d.innerWidth()},g=c.offset(),h=b('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(a.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(d,a.duration,a.options.easing,function(){h.remove();a.callback&&a.callback.apply(c[0],arguments);c.dequeue()})})}})(jQuery);
+/*
+ * jQuery Highlight plugin
+ * Based on highlight v3 by Johann Burkard
+ * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
+ * Copyright (c) 2009 Bartek Szopka http://bartaz.github.com/sandbox.js/jquery.highlight.html
+ * Licensed under MIT license.
+ */
+jQuery.extend({highlight:function(a,c,b,e){if(a.nodeType===3){if(c=a.data.match(c)){b=document.createElement(b||"span");b.className=e||"highlight";a=a.splitText(c.index);a.splitText(c[0].length);e=a.cloneNode(true);b.appendChild(e);a.parentNode.replaceChild(b,a);return 1}}else if(a.nodeType===1&&a.childNodes&&!/(script|style)/i.test(a.tagName)&&!(a.tagName===b.toUpperCase()&&a.className===e))for(var d=0;d<a.childNodes.length;d++)d+=jQuery.highlight(a.childNodes[d],c,b,e);return 0}});
+jQuery.fn.unhighlight=function(a){var c={className:"highlight",element:"span"};jQuery.extend(c,a);return this.find(c.element+"."+c.className).each(function(){var b=this.parentNode;b.replaceChild(this.firstChild,this);b.normalize()}).end()};
+jQuery.fn.highlight=function(a,c){var b={className:"highlight",element:"span",caseSensitive:false,wordsOnly:false};jQuery.extend(b,c);if(a.constructor===String)a=[a];a=jQuery.grep(a,function(f){return f!=""});if(a.length==0)return this;var e=b.caseSensitive?"":"i",d="("+a.join("|")+")";if(b.wordsOnly)d="\\b"+d+"\\b";var g=RegExp(d,e);return this.each(function(){jQuery.highlight(this,g,b.element,b.className)})};
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/layout/jquery.layout.js b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/layout/jquery.layout.js
new file mode 100644
index 000000000..0b6d9d292
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/layout/jquery.layout.js
@@ -0,0 +1,5449 @@
+/**
+ * @preserve jquery.layout 1.3.0 - Release Candidate 30.51
+ * $Date$
+ * $Rev: 303005 $
+ *
+ * Copyright (c) 2012
+ * Fabrizio Balliano (http://www.fabrizioballiano.net)
+ * Kevin Dalman (http://allpro.net)
+ *
+ * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
+ * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
+ *
+ * Changelog: http://layout.jquery-dev.net/changelog.cfm#1.3.0.rc30.5
+ *
+ * Docs: http://layout.jquery-dev.net/documentation.html
+ * Tips: http://layout.jquery-dev.net/tips.html
+ * Help: http://groups.google.com/group/jquery-ui-layout
+ */
+
+/* JavaDoc Info: http://code.google.com/closure/compiler/docs/js-for-compiler.html
+ * {!Object} non-nullable type (never NULL)
+ * {?string} nullable type (sometimes NULL) - default for {Object}
+ * {number=} optional parameter
+ * {*} ALL types
+ */
+
+// NOTE: For best readability, view with a fixed-width font and tabs equal to 4-chars
+
+;(function ($) {
+
+// alias Math methods - used a lot!
+var min = Math.min
+, max = Math.max
+, round = Math.floor
+;
+function isStr (v) { return $.type(v) === "string"; }
+
+function runPluginCallbacks (Instance, a_fn) {
+ if ($.isArray(a_fn))
+ for (var i=0, c=a_fn.length; i<c; i++) {
+ var fn = a_fn[i];
+ try {
+ if (isStr(fn)) // 'name' of a function
+ fn = eval(fn);
+ if ($.isFunction(fn))
+ fn( Instance );
+ } catch (ex) {}
+ }
+};
+
+
+
+/*
+ * GENERIC $.layout METHODS - used by all layouts
+ */
+$.layout = {
+
+ version: "1.3.rc30.51"
+, revision: 0.033005 // 1.3.0 final = 1.0300 - major(n+).minor(nn)+patch(nn+)
+
+ // LANGUAGE CUSTOMIZATION
+, language: {
+ // Tips and messages for resizers, togglers, custom buttons, etc.
+ Open: "Open" // eg: "Open Pane"
+ , Close: "Close"
+ , Resize: "Resize"
+ , Slide: "Slide Open"
+ , Pin: "Pin"
+ , Unpin: "Un-Pin"
+ , noRoomToOpenTip: "Not enough room to show this pane."
+ , minSizeWarning: "Panel has reached its minimum size"
+ , maxSizeWarning: "Panel has reached its maximum size"
+ // Developer error messages
+ , pane: "pane" // description of "layout pane element"
+ , selector: "selector" // description of "jQuery-selector"
+ , errButton: "Error Adding Button \n\nInvalid "
+ , errContainerMissing: "UI Layout Initialization Error\n\nThe specified layout-container does not exist."
+ , errCenterPaneMissing: "UI Layout Initialization Error\n\nThe center-pane element does not exist.\n\nThe center-pane is a required element."
+ , errContainerHeight: "UI Layout Initialization Warning\n\nThe layout-container \"CONTAINER\" has no height.\n\nTherefore the layout is 0-height and hence 'invisible'!"
+ }
+
+ // can update code here if $.browser is phased out
+, browser: {
+ mozilla: !!$.browser.mozilla
+ , webkit: !!$.browser.webkit || !!$.browser.safari // webkit = jQ 1.4
+ , msie: !!$.browser.msie
+ , isIE6: !!$.browser.msie && $.browser.version == 6
+ , version: $.browser.version // not used in Layout core, but may be used by plugins
+ }
+
+ // *PREDEFINED* EFFECTS & DEFAULTS
+ // MUST list effect here - OR MUST set an fxSettings option (can be an empty hash: {})
+, effects: {
+
+ // Pane Open/Close Animations
+ slide: {
+ all: { duration: "fast" } // eg: duration: 1000, easing: "easeOutBounce"
+ , north: { direction: "up" }
+ , south: { direction: "down" }
+ , east: { direction: "right"}
+ , west: { direction: "left" }
+ }
+ , drop: {
+ all: { duration: "slow" }
+ , north: { direction: "up" }
+ , south: { direction: "down" }
+ , east: { direction: "right"}
+ , west: { direction: "left" }
+ }
+ , scale: {
+ all: { duration: "fast" }
+ }
+ // these are not recommended, but can be used
+ , blind: {}
+ , clip: {}
+ , explode: {}
+ , fade: {}
+ , fold: {}
+ , puff: {}
+
+ // Pane Resize Animations
+ , size: {
+ all: { easing: "swing" }
+ }
+ }
+
+ // INTERNAL CONFIG DATA - DO NOT CHANGE THIS!
+, config: {
+ optionRootKeys: "effects,panes,north,south,west,east,center".split(",")
+ , allPanes: "north,south,west,east,center".split(",")
+ , borderPanes: "north,south,west,east".split(",")
+ , oppositeEdge: {
+ north: "south"
+ , south: "north"
+ , east: "west"
+ , west: "east"
+ }
+ // offscreen data
+ , offscreenCSS: { left: "-99999px", right: "auto" } // used by hide/close if useOffscreenClose=true
+ , offscreenReset: "offscreenReset" // key used for data
+ // CSS used in multiple places
+ , hidden: { visibility: "hidden" }
+ , visible: { visibility: "visible" }
+ // layout element settings
+ , resizers: {
+ cssReq: {
+ position: "absolute"
+ , padding: 0
+ , margin: 0
+ , fontSize: "1px"
+ , textAlign: "left" // to counter-act "center" alignment!
+ , overflow: "hidden" // prevent toggler-button from overflowing
+ // SEE $.layout.defaults.zIndexes.resizer_normal
+ }
+ , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
+ background: "#DDD"
+ , border: "none"
+ }
+ }
+ , togglers: {
+ cssReq: {
+ position: "absolute"
+ , display: "block"
+ , padding: 0
+ , margin: 0
+ , overflow: "hidden"
+ , textAlign: "center"
+ , fontSize: "1px"
+ , cursor: "pointer"
+ , zIndex: 1
+ }
+ , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
+ background: "#AAA"
+ }
+ }
+ , content: {
+ cssReq: {
+ position: "relative" /* contain floated or positioned elements */
+ }
+ , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
+ overflow: "auto"
+ , padding: "10px"
+ }
+ , cssDemoPane: { // DEMO CSS - REMOVE scrolling from 'pane' when it has a content-div
+ overflow: "hidden"
+ , padding: 0
+ }
+ }
+ , panes: { // defaults for ALL panes - overridden by 'per-pane settings' below
+ cssReq: {
+ position: "absolute"
+ , margin: 0
+ // $.layout.defaults.zIndexes.pane_normal
+ }
+ , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true
+ padding: "10px"
+ , background: "#FFF"
+ , border: "1px solid #BBB"
+ , overflow: "auto"
+ }
+ }
+ , north: {
+ side: "Top"
+ , sizeType: "Height"
+ , dir: "horz"
+ , cssReq: {
+ top: 0
+ , bottom: "auto"
+ , left: 0
+ , right: 0
+ , width: "auto"
+ // height: DYNAMIC
+ }
+ }
+ , south: {
+ side: "Bottom"
+ , sizeType: "Height"
+ , dir: "horz"
+ , cssReq: {
+ top: "auto"
+ , bottom: 0
+ , left: 0
+ , right: 0
+ , width: "auto"
+ // height: DYNAMIC
+ }
+ }
+ , east: {
+ side: "Right"
+ , sizeType: "Width"
+ , dir: "vert"
+ , cssReq: {
+ left: "auto"
+ , right: 0
+ , top: "auto" // DYNAMIC
+ , bottom: "auto" // DYNAMIC
+ , height: "auto"
+ // width: DYNAMIC
+ }
+ }
+ , west: {
+ side: "Left"
+ , sizeType: "Width"
+ , dir: "vert"
+ , cssReq: {
+ left: 0
+ , right: "auto"
+ , top: "auto" // DYNAMIC
+ , bottom: "auto" // DYNAMIC
+ , height: "auto"
+ // width: DYNAMIC
+ }
+ }
+ , center: {
+ dir: "center"
+ , cssReq: {
+ left: "auto" // DYNAMIC
+ , right: "auto" // DYNAMIC
+ , top: "auto" // DYNAMIC
+ , bottom: "auto" // DYNAMIC
+ , height: "auto"
+ , width: "auto"
+ }
+ }
+ }
+
+ // CALLBACK FUNCTION NAMESPACE - used to store reusable callback functions
+, callbacks: {}
+
+, getParentPaneElem: function (el) {
+ // must pass either a container or pane element
+ var $el = $(el)
+ , layout = $el.data("layout") || $el.data("parentLayout");
+ if (layout) {
+ var $cont = layout.container;
+ // see if this container is directly-nested inside an outer-pane
+ if ($cont.data("layoutPane")) return $cont;
+ var $pane = $cont.closest("."+ $.layout.defaults.panes.paneClass);
+ // if a pane was found, return it
+ if ($pane.data("layoutPane")) return $pane;
+ }
+ return null;
+ }
+
+, getParentPaneInstance: function (el) {
+ // must pass either a container or pane element
+ var $pane = $.layout.getParentPaneElem(el);
+ return $pane ? $pane.data("layoutPane") : null;
+ }
+
+, getParentLayoutInstance: function (el) {
+ // must pass either a container or pane element
+ var $pane = $.layout.getParentPaneElem(el);
+ return $pane ? $pane.data("parentLayout") : null;
+ }
+
+, getEventObject: function (evt) {
+ return typeof evt === "object" && evt.stopPropagation ? evt : null;
+ }
+, parsePaneName: function (evt_or_pane) {
+ // getEventObject() automatically calls .stopPropagation(), WHICH MUST BE DONE!
+ var evt = $.layout.getEventObject( evt_or_pane );
+ if (evt) {
+ // ALWAYS stop propagation of events triggered in Layout!
+ evt.stopPropagation();
+ return $(this).data("layoutEdge");
+ }
+ else
+ return evt_or_pane;
+ }
+
+
+ // LAYOUT-PLUGIN REGISTRATION
+ // more plugins can added beyond this default list
+, plugins: {
+ draggable: !!$.fn.draggable // resizing
+ , effects: {
+ core: !!$.effects // animimations (specific effects tested by initOptions)
+ , slide: $.effects && $.effects.slide // default effect
+ }
+ }
+
+// arrays of plugin or other methods to be triggered for events in *each layout* - will be passed 'Instance'
+, onCreate: [] // runs when layout is just starting to be created - right after options are set
+, onLoad: [] // runs after layout container and global events init, but before initPanes is called
+, onReady: [] // runs after initialization *completes* - ie, after initPanes completes successfully
+, onDestroy: [] // runs after layout is destroyed
+, onUnload: [] // runs after layout is destroyed OR when page unloads
+, afterOpen: [] // runs after setAsOpen() completes
+, afterClose: [] // runs after setAsClosed() completes
+
+ /*
+ * GENERIC UTILITY METHODS
+ */
+
+ // calculate and return the scrollbar width, as an integer
+, scrollbarWidth: function () { return window.scrollbarWidth || $.layout.getScrollbarSize('width'); }
+, scrollbarHeight: function () { return window.scrollbarHeight || $.layout.getScrollbarSize('height'); }
+, getScrollbarSize: function (dim) {
+ var $c = $('<div style="position: absolute; top: -10000px; left: -10000px; width: 100px; height: 100px; overflow: scroll;"></div>').appendTo("body");
+ var d = { width: $c.width() - $c[0].clientWidth, height: $c.height() - $c[0].clientHeight };
+ $c.remove();
+ window.scrollbarWidth = d.width;
+ window.scrollbarHeight = d.height;
+ return dim.match(/^(width|height)$/) ? d[dim] : d;
+ }
+
+
+ /**
+ * Returns hash container 'display' and 'visibility'
+ *
+ * @see $.swap() - swaps CSS, runs callback, resets CSS
+ */
+, showInvisibly: function ($E, force) {
+ if (!$E) return {};
+ if (!$E.jquery) $E = $($E);
+ var CSS = {
+ display: $E.css('display')
+ , visibility: $E.css('visibility')
+ };
+ if (force || CSS.display === "none") { // only if not *already hidden*
+ $E.css({ display: "block", visibility: "hidden" }); // show element 'invisibly' so can be measured
+ return CSS;
+ }
+ else return {};
+ }
+
+ /**
+ * Returns data for setting size of an element (container or a pane).
+ *
+ * @see _create(), onWindowResize() for container, plus others for pane
+ * @return JSON Returns a hash of all dimensions: top, bottom, left, right, outerWidth, innerHeight, etc
+ */
+, getElementDimensions: function ($E) {
+ var
+ d = {} // dimensions hash
+ , x = d.css = {} // CSS hash
+ , i = {} // TEMP insets
+ , b, p // TEMP border, padding
+ , N = $.layout.cssNum
+ , off = $E.offset()
+ ;
+ d.offsetLeft = off.left;
+ d.offsetTop = off.top;
+
+ $.each("Left,Right,Top,Bottom".split(","), function (idx, e) { // e = edge
+ b = x["border" + e] = $.layout.borderWidth($E, e);
+ p = x["padding"+ e] = $.layout.cssNum($E, "padding"+e);
+ i[e] = b + p; // total offset of content from outer side
+ d["inset"+ e] = p;
+ });
+
+ d.offsetWidth = $E.innerWidth(); // offsetWidth is used in calc when doing manual resize
+ d.offsetHeight = $E.innerHeight(); // ditto
+ d.outerWidth = $E.outerWidth();
+ d.outerHeight = $E.outerHeight();
+ d.innerWidth = max(0, d.outerWidth - i.Left - i.Right);
+ d.innerHeight = max(0, d.outerHeight - i.Top - i.Bottom);
+
+ x.width = $E.width();
+ x.height = $E.height();
+ x.top = N($E,"top",true);
+ x.bottom = N($E,"bottom",true);
+ x.left = N($E,"left",true);
+ x.right = N($E,"right",true);
+
+ //d.visible = $E.is(":visible");// && x.width > 0 && x.height > 0;
+
+ return d;
+ }
+
+, getElementCSS: function ($E, list) {
+ var
+ CSS = {}
+ , style = $E[0].style
+ , props = list.split(",")
+ , sides = "Top,Bottom,Left,Right".split(",")
+ , attrs = "Color,Style,Width".split(",")
+ , p, s, a, i, j, k
+ ;
+ for (i=0; i < props.length; i++) {
+ p = props[i];
+ if (p.match(/(border|padding|margin)$/))
+ for (j=0; j < 4; j++) {
+ s = sides[j];
+ if (p === "border")
+ for (k=0; k < 3; k++) {
+ a = attrs[k];
+ CSS[p+s+a] = style[p+s+a];
+ }
+ else
+ CSS[p+s] = style[p+s];
+ }
+ else
+ CSS[p] = style[p];
+ };
+ return CSS
+ }
+
+ /**
+ * Return the innerWidth for the current browser/doctype
+ *
+ * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles()
+ * @param {Array.<Object>} $E Must pass a jQuery object - first element is processed
+ * @param {number=} outerWidth (optional) Can pass a width, allowing calculations BEFORE element is resized
+ * @return {number} Returns the innerWidth of the elem by subtracting padding and borders
+ */
+, cssWidth: function ($E, outerWidth) {
+ var
+ b = $.layout.borderWidth
+ , n = $.layout.cssNum
+ ;
+ // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed
+ if (outerWidth <= 0) return 0;
+
+ if (!$.support.boxModel) return outerWidth;
+
+ // strip border and padding from outerWidth to get CSS Width
+ var W = outerWidth
+ - b($E, "Left")
+ - b($E, "Right")
+ - n($E, "paddingLeft")
+ - n($E, "paddingRight")
+ ;
+
+ return max(0,W);
+ }
+
+ /**
+ * Return the innerHeight for the current browser/doctype
+ *
+ * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles()
+ * @param {Array.<Object>} $E Must pass a jQuery object - first element is processed
+ * @param {number=} outerHeight (optional) Can pass a width, allowing calculations BEFORE element is resized
+ * @return {number} Returns the innerHeight of the elem by subtracting padding and borders
+ */
+, cssHeight: function ($E, outerHeight) {
+ var
+ b = $.layout.borderWidth
+ , n = $.layout.cssNum
+ ;
+ // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed
+ if (outerHeight <= 0) return 0;
+
+ if (!$.support.boxModel) return outerHeight;
+
+ // strip border and padding from outerHeight to get CSS Height
+ var H = outerHeight
+ - b($E, "Top")
+ - b($E, "Bottom")
+ - n($E, "paddingTop")
+ - n($E, "paddingBottom")
+ ;
+
+ return max(0,H);
+ }
+
+ /**
+ * Returns the 'current CSS numeric value' for a CSS property - 0 if property does not exist
+ *
+ * @see Called by many methods
+ * @param {Array.<Object>} $E Must pass a jQuery object - first element is processed
+ * @param {string} prop The name of the CSS property, eg: top, width, etc.
+ * @param {boolean=} [allowAuto=false] true = return 'auto' if that is value; false = return 0
+ * @return {(string|number)} Usually used to get an integer value for position (top, left) or size (height, width)
+ */
+, cssNum: function ($E, prop, allowAuto) {
+ if (!$E.jquery) $E = $($E);
+ var CSS = $.layout.showInvisibly($E)
+ , p = $.curCSS($E[0], prop, true)
+ , v = allowAuto && p=="auto" ? p : (parseInt(p, 10) || 0);
+ $E.css( CSS ); // RESET
+ return v;
+ }
+
+, borderWidth: function (el, side) {
+ if (el.jquery) el = el[0];
+ var b = "border"+ side.substr(0,1).toUpperCase() + side.substr(1); // left => Left
+ return $.curCSS(el, b+"Style", true) === "none" ? 0 : (parseInt($.curCSS(el, b+"Width", true), 10) || 0);
+ }
+
+ /**
+ * Mouse-tracking utility - FUTURE REFERENCE
+ *
+ * init: if (!window.mouse) {
+ * window.mouse = { x: 0, y: 0 };
+ * $(document).mousemove( $.layout.trackMouse );
+ * }
+ *
+ * @param {Object} evt
+ *
+, trackMouse: function (evt) {
+ window.mouse = { x: evt.clientX, y: evt.clientY };
+ }
+ */
+
+ /**
+ * SUBROUTINE for preventPrematureSlideClose option
+ *
+ * @param {Object} evt
+ * @param {Object=} el
+ */
+, isMouseOverElem: function (evt, el) {
+ var
+ $E = $(el || this)
+ , d = $E.offset()
+ , T = d.top
+ , L = d.left
+ , R = L + $E.outerWidth()
+ , B = T + $E.outerHeight()
+ , x = evt.pageX // evt.clientX ?
+ , y = evt.pageY // evt.clientY ?
+ ;
+ // if X & Y are < 0, probably means is over an open SELECT
+ return ($.layout.browser.msie && x < 0 && y < 0) || ((x >= L && x <= R) && (y >= T && y <= B));
+ }
+
+ /**
+ * Message/Logging Utility
+ *
+ * @example $.layout.msg("My message"); // log text
+ * @example $.layout.msg("My message", true); // alert text
+ * @example $.layout.msg({ foo: "bar" }, "Title"); // log hash-data, with custom title
+ * @example $.layout.msg({ foo: "bar" }, true, "Title", { sort: false }); -OR-
+ * @example $.layout.msg({ foo: "bar" }, "Title", { sort: false, display: true }); // alert hash-data
+ *
+ * @param {(Object|string)} info String message OR Hash/Array
+ * @param {(Boolean|string|Object)=} [popup=false] True means alert-box - can be skipped
+ * @param {(Object|string)=} [debugTitle=""] Title for Hash data - can be skipped
+ * @param {Object=} [debutOpts={}] Extra options for debug output
+ */
+, msg: function (info, popup, debugTitle, debugOpts) {
+ if ($.isPlainObject(info) && window.debugData) {
+ if (typeof popup === "string") {
+ debugOpts = debugTitle;
+ debugTitle = popup;
+ }
+ else if (typeof debugTitle === "object") {
+ debugOpts = debugTitle;
+ debugTitle = null;
+ }
+ var t = debugTitle || "log( <object> )"
+ , o = $.extend({ sort: false, returnHTML: false, display: false }, debugOpts);
+ if (popup === true || o.display)
+ debugData( info, t, o );
+ else if (window.console)
+ console.log(debugData( info, t, o ));
+ }
+ else if (popup)
+ alert(info);
+ else if (window.console)
+ console.log(info);
+ else {
+ var id = "#layoutLogger"
+ , $l = $(id);
+ if (!$l.length)
+ $l = createLog();
+ $l.children("ul").append('<li style="padding: 4px 10px; margin: 0; border-top: 1px solid #CCC;">'+ info.replace(/\</g,"&lt;").replace(/\>/g,"&gt;") +'</li>');
+ }
+
+ function createLog () {
+ var pos = $.support.fixedPosition ? 'fixed' : 'absolute'
+ , $e = $('<div id="layoutLogger" style="position: '+ pos +'; top: 5px; z-index: 999999; max-width: 25%; overflow: hidden; border: 1px solid #000; border-radius: 5px; background: #FBFBFB; box-shadow: 0 2px 10px rgba(0,0,0,0.3);">'
+ + '<div style="font-size: 13px; font-weight: bold; padding: 5px 10px; background: #F6F6F6; border-radius: 5px 5px 0 0; cursor: move;">'
+ + '<span style="float: right; padding-left: 7px; cursor: pointer;" title="Remove Console" onclick="$(this).closest(\'#layoutLogger\').remove()">X</span>Layout console.log</div>'
+ + '<ul style="font-size: 13px; font-weight: none; list-style: none; margin: 0; padding: 0 0 2px;"></ul>'
+ + '</div>'
+ ).appendTo("body");
+ $e.css('left', $(window).width() - $e.outerWidth() - 5)
+ if ($.ui.draggable) $e.draggable({ handle: ':first-child' });
+ return $e;
+ };
+ }
+
+};
+
+var lang = $.layout.language; // alias used in defaults...
+
+// DEFAULT OPTIONS - CHANGE IF DESIRED
+$.layout.defaults = {
+/*
+ * LAYOUT & LAYOUT-CONTAINER OPTIONS
+ * - none of these options are applicable to individual panes
+ */
+ name: "" // Not required, but useful for buttons and used for the state-cookie
+, containerSelector: "" // ONLY used when specifying a childOptions - to find container-element that is NOT directly-nested
+, containerClass: "ui-layout-container" // layout-container element
+, scrollToBookmarkOnLoad: true // after creating a layout, scroll to bookmark in URL (.../page.htm#myBookmark)
+, resizeWithWindow: true // bind thisLayout.resizeAll() to the window.resize event
+, resizeWithWindowDelay: 200 // delay calling resizeAll because makes window resizing very jerky
+, resizeWithWindowMaxDelay: 0 // 0 = none - force resize every XX ms while window is being resized
+, onresizeall_start: null // CALLBACK when resizeAll() STARTS - NOT pane-specific
+, onresizeall_end: null // CALLBACK when resizeAll() ENDS - NOT pane-specific
+, onload_start: null // CALLBACK when Layout inits - after options initialized, but before elements
+, onload_end: null // CALLBACK when Layout inits - after EVERYTHING has been initialized
+, onunload_start: null // CALLBACK when Layout is destroyed OR onWindowUnload
+, onunload_end: null // CALLBACK when Layout is destroyed OR onWindowUnload
+, autoBindCustomButtons: false // search for buttons with ui-layout-button class and auto-bind them
+, initPanes: true // false = DO NOT initialize the panes onLoad - will init later
+, showErrorMessages: true // enables fatal error messages to warn developers of common errors
+, showDebugMessages: false // display console-and-alert debug msgs - IF this Layout version _has_ debugging code!
+// Changing this zIndex value will cause other zIndex values to automatically change
+, zIndex: null // the PANE zIndex - resizers and masks will be +1
+// DO NOT CHANGE the zIndex values below unless you clearly understand their relationships
+, zIndexes: { // set _default_ z-index values here...
+ pane_normal: 0 // normal z-index for panes
+ , content_mask: 1 // applied to overlays used to mask content INSIDE panes during resizing
+ , resizer_normal: 2 // normal z-index for resizer-bars
+ , pane_sliding: 100 // applied to *BOTH* the pane and its resizer when a pane is 'slid open'
+ , pane_animate: 1000 // applied to the pane when being animated - not applied to the resizer
+ , resizer_drag: 10000 // applied to the CLONED resizer-bar when being 'dragged'
+ }
+/*
+ * PANE DEFAULT SETTINGS
+ * - settings under the 'panes' key become the default settings for *all panes*
+ * - ALL pane-options can also be set specifically for each panes, which will override these 'default values'
+ */
+, panes: { // default options for 'all panes' - will be overridden by 'per-pane settings'
+ applyDemoStyles: false // NOTE: renamed from applyDefaultStyles for clarity
+ , closable: true // pane can open & close
+ , resizable: true // when open, pane can be resized
+ , slidable: true // when closed, pane can 'slide open' over other panes - closes on mouse-out
+ , initClosed: false // true = init pane as 'closed'
+ , initHidden: false // true = init pane as 'hidden' - no resizer-bar/spacing
+ // SELECTORS
+ //, paneSelector: "" // MUST be pane-specific - jQuery selector for pane
+ , contentSelector: ".ui-layout-content" // INNER div/element to auto-size so only it scrolls, not the entire pane!
+ , contentIgnoreSelector: ".ui-layout-ignore" // element(s) to 'ignore' when measuring 'content'
+ , findNestedContent: false // true = $P.find(contentSelector), false = $P.children(contentSelector)
+ // GENERIC ROOT-CLASSES - for auto-generated classNames
+ , paneClass: "ui-layout-pane" // Layout Pane
+ , resizerClass: "ui-layout-resizer" // Resizer Bar
+ , togglerClass: "ui-layout-toggler" // Toggler Button
+ , buttonClass: "ui-layout-button" // CUSTOM Buttons - eg: '[ui-layout-button]-toggle/-open/-close/-pin'
+ // ELEMENT SIZE & SPACING
+ //, size: 100 // MUST be pane-specific -initial size of pane
+ , minSize: 0 // when manually resizing a pane
+ , maxSize: 0 // ditto, 0 = no limit
+ , spacing_open: 6 // space between pane and adjacent panes - when pane is 'open'
+ , spacing_closed: 6 // ditto - when pane is 'closed'
+ , togglerLength_open: 50 // Length = WIDTH of toggler button on north/south sides - HEIGHT on east/west sides
+ , togglerLength_closed: 50 // 100% OR -1 means 'full height/width of resizer bar' - 0 means 'hidden'
+ , togglerAlign_open: "center" // top/left, bottom/right, center, OR...
+ , togglerAlign_closed: "center" // 1 => nn = offset from top/left, -1 => -nn == offset from bottom/right
+ , togglerTip_open: lang.Close // Toggler tool-tip (title)
+ , togglerTip_closed: lang.Open // ditto
+ , togglerContent_open: "" // text or HTML to put INSIDE the toggler
+ , togglerContent_closed: "" // ditto
+ // RESIZING OPTIONS
+ , resizerDblClickToggle: true //
+ , autoResize: true // IF size is 'auto' or a percentage, then recalc 'pixel size' whenever the layout resizes
+ , autoReopen: true // IF a pane was auto-closed due to noRoom, reopen it when there is room? False = leave it closed
+ , resizerDragOpacity: 1 // option for ui.draggable
+ //, resizerCursor: "" // MUST be pane-specific - cursor when over resizer-bar
+ , maskContents: false // true = add DIV-mask over-or-inside this pane so can 'drag' over IFRAMES
+ , maskObjects: false // true = add IFRAME-mask over-or-inside this pane to cover objects/applets - content-mask will overlay this mask
+ , maskZindex: null // will override zIndexes.content_mask if specified - not applicable to iframe-panes
+ , resizingGrid: false // grid size that the resizers will snap-to during resizing, eg: [20,20]
+ , livePaneResizing: false // true = LIVE Resizing as resizer is dragged
+ , liveContentResizing: false // true = re-measure header/footer heights as resizer is dragged
+ , liveResizingTolerance: 1 // how many px change before pane resizes, to control performance
+ // TIPS & MESSAGES - also see lang object
+ , noRoomToOpenTip: lang.noRoomToOpenTip
+ , resizerTip: lang.Resize // Resizer tool-tip (title)
+ , sliderTip: lang.Slide // resizer-bar triggers 'sliding' when pane is closed
+ , sliderCursor: "pointer" // cursor when resizer-bar will trigger 'sliding'
+ , slideTrigger_open: "click" // click, dblclick, mouseenter
+ , slideTrigger_close: "mouseleave"// click, mouseleave
+ , slideDelay_open: 300 // applies only for mouseenter event - 0 = instant open
+ , slideDelay_close: 300 // applies only for mouseleave event (300ms is the minimum!)
+ , hideTogglerOnSlide: false // when pane is slid-open, should the toggler show?
+ , preventQuickSlideClose: $.layout.browser.webkit // Chrome triggers slideClosed as it is opening
+ , preventPrematureSlideClose: false // handle incorrect mouseleave trigger, like when over a SELECT-list in IE
+ // HOT-KEYS & MISC
+ , showOverflowOnHover: false // will bind allowOverflow() utility to pane.onMouseOver
+ , enableCursorHotkey: true // enabled 'cursor' hotkeys
+ //, customHotkey: "" // MUST be pane-specific - EITHER a charCode OR a character
+ , customHotkeyModifier: "SHIFT" // either 'SHIFT', 'CTRL' or 'CTRL+SHIFT' - NOT 'ALT'
+ // PANE ANIMATION
+ // NOTE: fxSss_open, fxSss_close & fxSss_size options (eg: fxName_open) are auto-generated if not passed
+ , fxName: "slide" // ('none' or blank), slide, drop, scale -- only relevant to 'open' & 'close', NOT 'size'
+ , fxSpeed: null // slow, normal, fast, 200, nnn - if passed, will OVERRIDE fxSettings.duration
+ , fxSettings: {} // can be passed, eg: { easing: "easeOutBounce", duration: 1500 }
+ , fxOpacityFix: true // tries to fix opacity in IE to restore anti-aliasing after animation
+ , animatePaneSizing: false // true = animate resizing after dragging resizer-bar OR sizePane() is called
+ /* NOTE: Action-specific FX options are auto-generated from the options above if not specifically set:
+ fxName_open: "slide" // 'Open' pane animation
+ fnName_close: "slide" // 'Close' pane animation
+ fxName_size: "slide" // 'Size' pane animation - when animatePaneSizing = true
+ fxSpeed_open: null
+ fxSpeed_close: null
+ fxSpeed_size: null
+ fxSettings_open: {}
+ fxSettings_close: {}
+ fxSettings_size: {}
+ */
+ // CHILD/NESTED LAYOUTS
+ , childOptions: null // Layout-options for nested/child layout - even {} is valid as options
+ , initChildLayout: true // true = child layout will be created as soon as _this_ layout completes initialization
+ , destroyChildLayout: true // true = destroy child-layout if this pane is destroyed
+ , resizeChildLayout: true // true = trigger child-layout.resizeAll() when this pane is resized
+ // PANE CALLBACKS
+ , triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes
+ , triggerEventsDuringLiveResize: true // true = trigger onresize callback REPEATEDLY if livePaneResizing==true
+ , onshow_start: null // CALLBACK when pane STARTS to Show - BEFORE onopen/onhide_start
+ , onshow_end: null // CALLBACK when pane ENDS being Shown - AFTER onopen/onhide_end
+ , onhide_start: null // CALLBACK when pane STARTS to Close - BEFORE onclose_start
+ , onhide_end: null // CALLBACK when pane ENDS being Closed - AFTER onclose_end
+ , onopen_start: null // CALLBACK when pane STARTS to Open
+ , onopen_end: null // CALLBACK when pane ENDS being Opened
+ , onclose_start: null // CALLBACK when pane STARTS to Close
+ , onclose_end: null // CALLBACK when pane ENDS being Closed
+ , onresize_start: null // CALLBACK when pane STARTS being Resized ***FOR ANY REASON***
+ , onresize_end: null // CALLBACK when pane ENDS being Resized ***FOR ANY REASON***
+ , onsizecontent_start: null // CALLBACK when sizing of content-element STARTS
+ , onsizecontent_end: null // CALLBACK when sizing of content-element ENDS
+ , onswap_start: null // CALLBACK when pane STARTS to Swap
+ , onswap_end: null // CALLBACK when pane ENDS being Swapped
+ , ondrag_start: null // CALLBACK when pane STARTS being ***MANUALLY*** Resized
+ , ondrag_end: null // CALLBACK when pane ENDS being ***MANUALLY*** Resized
+ }
+/*
+ * PANE-SPECIFIC SETTINGS
+ * - options listed below MUST be specified per-pane - they CANNOT be set under 'panes'
+ * - all options under the 'panes' key can also be set specifically for any pane
+ * - most options under the 'panes' key apply only to 'border-panes' - NOT the the center-pane
+ */
+, north: {
+ paneSelector: ".ui-layout-north"
+ , size: "auto" // eg: "auto", "30%", .30, 200
+ , resizerCursor: "n-resize" // custom = url(myCursor.cur)
+ , customHotkey: "" // EITHER a charCode (43) OR a character ("o")
+ }
+, south: {
+ paneSelector: ".ui-layout-south"
+ , size: "auto"
+ , resizerCursor: "s-resize"
+ , customHotkey: ""
+ }
+, east: {
+ paneSelector: ".ui-layout-east"
+ , size: 200
+ , resizerCursor: "e-resize"
+ , customHotkey: ""
+ }
+, west: {
+ paneSelector: ".ui-layout-west"
+ , size: 200
+ , resizerCursor: "w-resize"
+ , customHotkey: ""
+ }
+, center: {
+ paneSelector: ".ui-layout-center"
+ , minWidth: 0
+ , minHeight: 0
+ }
+};
+
+$.layout.optionsMap = {
+ // layout/global options - NOT pane-options
+ layout: ("stateManagement,effects,zIndexes,"
+ + "name,zIndex,scrollToBookmarkOnLoad,showErrorMessages,"
+ + "resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay,"
+ + "onresizeall,onresizeall_start,onresizeall_end,onload,onunload,autoBindCustomButtons").split(",")
+// borderPanes: [ ALL options that are NOT specified as 'layout' ]
+ // default.panes options that apply to the center-pane (most options apply _only_ to border-panes)
+, center: ("paneClass,contentSelector,contentIgnoreSelector,findNestedContent,applyDemoStyles,triggerEventsOnLoad,"
+ + "showOverflowOnHover,maskContents,maskObjects,liveContentResizing,"
+ + "childOptions,initChildLayout,resizeChildLayout,destroyChildLayout,"
+ + "onresize,onresize_start,onresize_end,onsizecontent,onsizecontent_start,onsizecontent_end").split(",")
+ // options that MUST be specifically set 'per-pane' - CANNOT set in the panes (defaults) key
+, noDefault: ("paneSelector,resizerCursor,customHotkey").split(",")
+};
+
+/**
+ * Processes options passed in converts flat-format data into subkey (JSON) format
+ * In flat-format, subkeys are _currently_ separated with 2 underscores, like north__optName
+ * Plugins may also call this method so they can transform their own data
+ *
+ * @param {!Object} hash Data/options passed by user - may be a single level or nested levels
+ * @return {Object} Returns hash of minWidth & minHeight
+ */
+$.layout.transformData = function (hash) {
+ var json = { panes: {}, center: {} } // init return object
+ , data, branch, optKey, keys, key, val, i, c;
+
+ if (typeof hash !== "object") return json; // no options passed
+
+ // convert all 'flat-keys' to 'sub-key' format
+ for (optKey in hash) {
+ branch = json;
+ data = $.layout.optionsMap.layout;
+ val = hash[ optKey ];
+ keys = optKey.split("__"); // eg: west__size or north__fxSettings__duration
+ c = keys.length - 1;
+ // convert underscore-delimited to subkeys
+ for (i=0; i <= c; i++) {
+ key = keys[i];
+ if (i === c)
+ branch[key] = val;
+ else if (!branch[key])
+ branch[key] = {}; // create the subkey
+ // recurse to sub-key for next loop - if not done
+ branch = branch[key];
+ }
+ }
+
+ return json;
+}
+
+// INTERNAL CONFIG DATA - DO NOT CHANGE THIS!
+$.layout.backwardCompatibility = {
+ // data used by renameOldOptions()
+ map: {
+ // OLD Option Name: NEW Option Name
+ applyDefaultStyles: "applyDemoStyles"
+ , resizeNestedLayout: "resizeChildLayout"
+ , resizeWhileDragging: "livePaneResizing"
+ , resizeContentWhileDragging: "liveContentResizing"
+ , triggerEventsWhileDragging: "triggerEventsDuringLiveResize"
+ , maskIframesOnResize: "maskContents"
+ , useStateCookie: "stateManagement.enabled"
+ , "cookie.autoLoad": "stateManagement.autoLoad"
+ , "cookie.autoSave": "stateManagement.autoSave"
+ , "cookie.keys": "stateManagement.stateKeys"
+ , "cookie.name": "stateManagement.cookie.name"
+ , "cookie.domain": "stateManagement.cookie.domain"
+ , "cookie.path": "stateManagement.cookie.path"
+ , "cookie.expires": "stateManagement.cookie.expires"
+ , "cookie.secure": "stateManagement.cookie.secure"
+ }
+ /**
+ * @param {Object} opts
+ */
+, renameOptions: function (opts) {
+ var map = $.layout.backwardCompatibility.map
+ , oldData, newData, value
+ ;
+ for (var itemPath in map) {
+ oldData = getBranch( itemPath );
+ value = oldData.branch[ oldData.key ]
+ if (value !== undefined) {
+ newData = getBranch( map[itemPath], true )
+ newData.branch[ newData.key ] = value;
+ delete oldData.branch[ oldData.key ];
+ }
+ }
+
+ /**
+ * @param {string} path
+ * @param {boolean=} [create=false] Create path if does not exist
+ */
+ function getBranch (path, create) {
+ var a = path.split(".") // split keys into array
+ , c = a.length - 1
+ , D = { branch: opts, key: a[c] } // init branch at top & set key (last item)
+ , i = 0, k, undef;
+ for (; i<c; i++) { // skip the last key (data)
+ k = a[i];
+ if (D.branch[ k ] == undefined) { // child-key does not exist
+ if (create) {
+ D.branch = D.branch[ k ] = {}; // create child-branch
+ }
+ else // can't go any farther
+ D.branch = {}; // branch is undefined
+ }
+ else
+ D.branch = D.branch[ k ]; // get child-branch
+ }
+ return D;
+ };
+ }
+ /**
+ * @param {Object} opts
+ */
+, renameAllOptions: function (opts) {
+ var ren = $.layout.backwardCompatibility.renameOptions;
+ // rename root (layout) options
+ ren( opts );
+ // rename 'defaults' to 'panes'
+ if (opts.defaults) {
+ if (typeof opts.panes !== "object")
+ opts.panes = {};
+ $.extend(true, opts.panes, opts.defaults);
+ delete opts.defaults;
+ }
+ // rename options in the the options.panes key
+ if (opts.panes) ren( opts.panes );
+ // rename options inside *each pane key*, eg: options.west
+ $.each($.layout.config.allPanes, function (i, pane) {
+ if (opts[pane]) ren( opts[pane] );
+ });
+ return opts;
+ }
+};
+
+
+
+/* ============================================================
+ * BEGIN WIDGET: $( selector ).layout( {options} );
+ * ============================================================
+ */
+$.fn.layout = function (opts) {
+ var
+
+ // local aliases to global data
+ browser = $.layout.browser
+, lang = $.layout.language // internal alias
+, _c = $.layout.config
+
+ // local aliases to utlity methods
+, cssW = $.layout.cssWidth
+, cssH = $.layout.cssHeight
+, elDims = $.layout.getElementDimensions
+, elCSS = $.layout.getElementCSS
+, evtObj = $.layout.getEventObject
+, evtPane = $.layout.parsePaneName
+
+/**
+ * options - populated by initOptions()
+ */
+, options = $.extend(true, {}, $.layout.defaults)
+, effects = options.effects = $.extend(true, {}, $.layout.effects)
+
+/**
+ * layout-state object
+ */
+, state = {
+ // generate unique ID to use for event.namespace so can unbind only events added by 'this layout'
+ id: "layout"+ $.now() // code uses alias: sID
+ , initialized: false
+ , container: {} // init all keys
+ , north: {}
+ , south: {}
+ , east: {}
+ , west: {}
+ , center: {}
+ }
+
+/**
+ * parent/child-layout pointers
+ */
+//, hasParentLayout = false - exists ONLY inside Instance so can be set externally
+, children = {
+ north: null
+ , south: null
+ , east: null
+ , west: null
+ , center: null
+ }
+
+/*
+ * ###########################
+ * INTERNAL HELPER FUNCTIONS
+ * ###########################
+ */
+
+ /**
+ * Manages all internal timers
+ */
+, timer = {
+ data: {}
+ , set: function (s, fn, ms) { timer.clear(s); timer.data[s] = setTimeout(fn, ms); }
+ , clear: function (s) { var t=timer.data; if (t[s]) {clearTimeout(t[s]); delete t[s];} }
+ }
+
+, _log = function (msg, popup) {
+ $.layout.msg( options.name +' / '+ msg, (popup && options.showErrorMessages) );
+ }
+
+ /**
+ * Executes a Callback function after a trigger event, like resize, open or close
+ *
+ * @param {string} evtName Name of the layout callback, eg "onresize_start"
+ * @param {?string} pane This is passed only so we can pass the 'pane object' to the callback
+ * @param {?boolean} skipBoundEvents Accepts a function name, OR a comma-delimited array: [0]=function name, [1]=argument
+ */
+, _runCallbacks = function (evtName, pane, skipBoundEvents) {
+ var o = pane ? options[pane] : options
+ // names like onopen and onopen_end separate are interchangeable in options...
+ , lng = evtName + (evtName.match(/_/) ? "" : "_end")
+ , shrt = lng.match(/_end$/) ? lng.substr(0, lng.length - 4) : ""
+ , fn = o[lng]
+ , retVal = "NC" // NC = No Callback
+ , args = []
+ ;
+ if (!fn && shrt)
+ fn = o[shrt];
+
+ // first trigger the callback set in the options
+ if (fn) {
+ //try {
+ // convert function name (string) to function object
+ if (isStr( fn )) {
+ if (fn.match(/,/)) {
+ // function name cannot contain a comma,
+ // so must be a function name AND a parameter to pass
+ args = fn.split(",")
+ , fn = eval(args[0]);
+ }
+ else // just the name of an external function?
+ fn = eval(fn);
+ }
+ // execute the callback, if exists
+ if ($.isFunction( fn )) {
+ if (args.length)
+ retVal = fn(args[1]); // pass the argument parsed from 'list'
+ else if (pane && $Ps[pane])
+ // pass data: pane-name, pane-element, pane-state, pane-options, and layout-name
+ retVal = fn( pane, $Ps[pane], state[pane], options[pane], options.name );
+ else // must be a layout/container callback - pass suitable info
+ retVal = fn( Instance, state, options, options.name );
+ }
+ //}
+ //catch (ex) {}
+ }
+
+ // trigger additional events bound directly to the pane
+ if (!skipBoundEvents && retVal !== false) {
+ if (pane) { // PANE events can be bound to each pane-elements
+ $Ps[pane].triggerHandler('layoutpane'+ lng, [ pane, $Ps[pane], state[pane], options[pane], options.name ]);
+ if (shrt)
+ $Ps[pane].triggerHandler('layoutpane'+ shrt, [ pane, $Ps[pane], state[pane], options[pane], options.name ]);
+ }
+ else // LAYOUT events can be bound to the container-element
+ $N.triggerHandler('layout'+ lng, [ pane, $Ps[pane], state[pane], options[pane], options.name ]);
+ }
+
+ // ALWAYS resizeChildLayout after a resize event - even during initialization
+ if (evtName === "onresize_end" || evtName === "onsizecontent_end")
+ resizeChildLayout(pane);
+
+ return retVal;
+ }
+
+
+ /**
+ * cure iframe display issues in IE & other browsers
+ */
+, _fixIframe = function (pane) {
+ if (browser.mozilla) return; // skip FireFox - it auto-refreshes iframes onShow
+ var $P = $Ps[pane];
+ // if the 'pane' is an iframe, do it
+ if (state[pane].tagName === "IFRAME")
+ $P.css(_c.hidden).css(_c.visible);
+ else // ditto for any iframes INSIDE the pane
+ $P.find('IFRAME').css(_c.hidden).css(_c.visible);
+ }
+
+ /**
+ * @param {string} pane Can accept ONLY a 'pane' (east, west, etc)
+ * @param {number=} outerSize (optional) Can pass a width, allowing calculations BEFORE element is resized
+ * @return {number} Returns the innerHeight/Width of el by subtracting padding and borders
+ */
+, cssSize = function (pane, outerSize) {
+ var fn = _c[pane].dir=="horz" ? cssH : cssW;
+ return fn($Ps[pane], outerSize);
+ }
+
+ /**
+ * @param {string} pane Can accept ONLY a 'pane' (east, west, etc)
+ * @return {Object} Returns hash of minWidth & minHeight
+ */
+, cssMinDims = function (pane) {
+ // minWidth/Height means CSS width/height = 1px
+ var $P = $Ps[pane]
+ , dir = _c[pane].dir
+ , d = {
+ minWidth: 1001 - cssW($P, 1000)
+ , minHeight: 1001 - cssH($P, 1000)
+ }
+ ;
+ if (dir === "horz") d.minSize = d.minHeight;
+ if (dir === "vert") d.minSize = d.minWidth;
+ return d;
+ }
+
+ // TODO: see if these methods can be made more useful...
+ // TODO: *maybe* return cssW/H from these so caller can use this info
+
+ /**
+ * @param {(string|!Object)} el
+ * @param {number=} outerWidth
+ * @param {boolean=} [autoHide=false]
+ */
+, setOuterWidth = function (el, outerWidth, autoHide) {
+ var $E = el, w;
+ if (isStr(el)) $E = $Ps[el]; // west
+ else if (!el.jquery) $E = $(el);
+ w = cssW($E, outerWidth);
+ $E.css({ width: w });
+ if (w > 0) {
+ if (autoHide && $E.data('autoHidden') && $E.innerHeight() > 0) {
+ $E.show().data('autoHidden', false);
+ if (!browser.mozilla) // FireFox refreshes iframes - IE does not
+ // make hidden, then visible to 'refresh' display after animation
+ $E.css(_c.hidden).css(_c.visible);
+ }
+ }
+ else if (autoHide && !$E.data('autoHidden'))
+ $E.hide().data('autoHidden', true);
+ }
+
+ /**
+ * @param {(string|!Object)} el
+ * @param {number=} outerHeight
+ * @param {boolean=} [autoHide=false]
+ */
+, setOuterHeight = function (el, outerHeight, autoHide) {
+ var $E = el, h;
+ if (isStr(el)) $E = $Ps[el]; // west
+ else if (!el.jquery) $E = $(el);
+ h = cssH($E, outerHeight);
+ $E.css({ height: h, visibility: "visible" }); // may have been 'hidden' by sizeContent
+ if (h > 0 && $E.innerWidth() > 0) {
+ if (autoHide && $E.data('autoHidden')) {
+ $E.show().data('autoHidden', false);
+ if (!browser.mozilla) // FireFox refreshes iframes - IE does not
+ $E.css(_c.hidden).css(_c.visible);
+ }
+ }
+ else if (autoHide && !$E.data('autoHidden'))
+ $E.hide().data('autoHidden', true);
+ }
+
+ /**
+ * @param {(string|!Object)} el
+ * @param {number=} outerSize
+ * @param {boolean=} [autoHide=false]
+ */
+, setOuterSize = function (el, outerSize, autoHide) {
+ if (_c[pane].dir=="horz") // pane = north or south
+ setOuterHeight(el, outerSize, autoHide);
+ else // pane = east or west
+ setOuterWidth(el, outerSize, autoHide);
+ }
+
+
+ /**
+ * Converts any 'size' params to a pixel/integer size, if not already
+ * If 'auto' or a decimal/percentage is passed as 'size', a pixel-size is calculated
+ *
+ /**
+ * @param {string} pane
+ * @param {(string|number)=} size
+ * @param {string=} [dir]
+ * @return {number}
+ */
+, _parseSize = function (pane, size, dir) {
+ if (!dir) dir = _c[pane].dir;
+
+ if (isStr(size) && size.match(/%/))
+ size = (size === '100%') ? -1 : parseInt(size, 10) / 100; // convert % to decimal
+
+ if (size === 0)
+ return 0;
+ else if (size >= 1)
+ return parseInt(size, 10);
+
+ var o = options, avail = 0;
+ if (dir=="horz") // north or south or center.minHeight
+ avail = sC.innerHeight - ($Ps.north ? o.north.spacing_open : 0) - ($Ps.south ? o.south.spacing_open : 0);
+ else if (dir=="vert") // east or west or center.minWidth
+ avail = sC.innerWidth - ($Ps.west ? o.west.spacing_open : 0) - ($Ps.east ? o.east.spacing_open : 0);
+
+ if (size === -1) // -1 == 100%
+ return avail;
+ else if (size > 0) // percentage, eg: .25
+ return round(avail * size);
+ else if (pane=="center")
+ return 0;
+ else { // size < 0 || size=='auto' || size==Missing || size==Invalid
+ // auto-size the pane
+ var dim = (dir === "horz" ? "height" : "width")
+ , $P = $Ps[pane]
+ , $C = dim === 'height' ? $Cs[pane] : false
+ , vis = $.layout.showInvisibly($P) // show pane invisibly if hidden
+ , szP = $P.css(dim) // SAVE current pane size
+ , szC = $C ? $C.css(dim) : 0 // SAVE current content size
+ ;
+ $P.css(dim, "auto");
+ if ($C) $C.css(dim, "auto");
+ size = (dim === "height") ? $P.outerHeight() : $P.outerWidth(); // MEASURE
+ $P.css(dim, szP).css(vis); // RESET size & visibility
+ if ($C) $C.css(dim, szC);
+ return size;
+ }
+ }
+
+ /**
+ * Calculates current 'size' (outer-width or outer-height) of a border-pane - optionally with 'pane-spacing' added
+ *
+ * @param {(string|!Object)} pane
+ * @param {boolean=} [inclSpace=false]
+ * @return {number} Returns EITHER Width for east/west panes OR Height for north/south panes - adjusted for boxModel & browser
+ */
+, getPaneSize = function (pane, inclSpace) {
+ var
+ $P = $Ps[pane]
+ , o = options[pane]
+ , s = state[pane]
+ , oSp = (inclSpace ? o.spacing_open : 0)
+ , cSp = (inclSpace ? o.spacing_closed : 0)
+ ;
+ if (!$P || s.isHidden)
+ return 0;
+ else if (s.isClosed || (s.isSliding && inclSpace))
+ return cSp;
+ else if (_c[pane].dir === "horz")
+ return $P.outerHeight() + oSp;
+ else // dir === "vert"
+ return $P.outerWidth() + oSp;
+ }
+
+ /**
+ * Calculate min/max pane dimensions and limits for resizing
+ *
+ * @param {string} pane
+ * @param {boolean=} [slide=false]
+ */
+, setSizeLimits = function (pane, slide) {
+ if (!isInitialized()) return;
+ var
+ o = options[pane]
+ , s = state[pane]
+ , c = _c[pane]
+ , dir = c.dir
+ , side = c.side.toLowerCase()
+ , type = c.sizeType.toLowerCase()
+ , isSliding = (slide != undefined ? slide : s.isSliding) // only open() passes 'slide' param
+ , $P = $Ps[pane]
+ , paneSpacing = o.spacing_open
+ // measure the pane on the *opposite side* from this pane
+ , altPane = _c.oppositeEdge[pane]
+ , altS = state[altPane]
+ , $altP = $Ps[altPane]
+ , altPaneSize = (!$altP || altS.isVisible===false || altS.isSliding ? 0 : (dir=="horz" ? $altP.outerHeight() : $altP.outerWidth()))
+ , altPaneSpacing = ((!$altP || altS.isHidden ? 0 : options[altPane][ altS.isClosed !== false ? "spacing_closed" : "spacing_open" ]) || 0)
+ // limitSize prevents this pane from 'overlapping' opposite pane
+ , containerSize = (dir=="horz" ? sC.innerHeight : sC.innerWidth)
+ , minCenterDims = cssMinDims("center")
+ , minCenterSize = dir=="horz" ? max(options.center.minHeight, minCenterDims.minHeight) : max(options.center.minWidth, minCenterDims.minWidth)
+ // if pane is 'sliding', then ignore center and alt-pane sizes - because 'overlays' them
+ , limitSize = (containerSize - paneSpacing - (isSliding ? 0 : (_parseSize("center", minCenterSize, dir) + altPaneSize + altPaneSpacing)))
+ , minSize = s.minSize = max( _parseSize(pane, o.minSize), cssMinDims(pane).minSize )
+ , maxSize = s.maxSize = min( (o.maxSize ? _parseSize(pane, o.maxSize) : 100000), limitSize )
+ , r = s.resizerPosition = {} // used to set resizing limits
+ , top = sC.insetTop
+ , left = sC.insetLeft
+ , W = sC.innerWidth
+ , H = sC.innerHeight
+ , rW = o.spacing_open // subtract resizer-width to get top/left position for south/east
+ ;
+ switch (pane) {
+ case "north": r.min = top + minSize;
+ r.max = top + maxSize;
+ break;
+ case "west": r.min = left + minSize;
+ r.max = left + maxSize;
+ break;
+ case "south": r.min = top + H - maxSize - rW;
+ r.max = top + H - minSize - rW;
+ break;
+ case "east": r.min = left + W - maxSize - rW;
+ r.max = left + W - minSize - rW;
+ break;
+ };
+ }
+
+ /**
+ * Returns data for setting the size/position of center pane. Also used to set Height for east/west panes
+ *
+ * @return JSON Returns a hash of all dimensions: top, bottom, left, right, (outer) width and (outer) height
+ */
+, calcNewCenterPaneDims = function () {
+ var d = {
+ top: getPaneSize("north", true) // true = include 'spacing' value for pane
+ , bottom: getPaneSize("south", true)
+ , left: getPaneSize("west", true)
+ , right: getPaneSize("east", true)
+ , width: 0
+ , height: 0
+ };
+
+ // NOTE: sC = state.container
+ // calc center-pane outer dimensions
+ d.width = sC.innerWidth - d.left - d.right; // outerWidth
+ d.height = sC.innerHeight - d.bottom - d.top; // outerHeight
+ // add the 'container border/padding' to get final positions relative to the container
+ d.top += sC.insetTop;
+ d.bottom += sC.insetBottom;
+ d.left += sC.insetLeft;
+ d.right += sC.insetRight;
+
+ return d;
+ }
+
+
+ /**
+ * @param {!Object} el
+ * @param {boolean=} [allStates=false]
+ */
+, getHoverClasses = function (el, allStates) {
+ var
+ $El = $(el)
+ , type = $El.data("layoutRole")
+ , pane = $El.data("layoutEdge")
+ , o = options[pane]
+ , root = o[type +"Class"]
+ , _pane = "-"+ pane // eg: "-west"
+ , _open = "-open"
+ , _closed = "-closed"
+ , _slide = "-sliding"
+ , _hover = "-hover " // NOTE the trailing space
+ , _state = $El.hasClass(root+_closed) ? _closed : _open
+ , _alt = _state === _closed ? _open : _closed
+ , classes = (root+_hover) + (root+_pane+_hover) + (root+_state+_hover) + (root+_pane+_state+_hover)
+ ;
+ if (allStates) // when 'removing' classes, also remove alternate-state classes
+ classes += (root+_alt+_hover) + (root+_pane+_alt+_hover);
+
+ if (type=="resizer" && $El.hasClass(root+_slide))
+ classes += (root+_slide+_hover) + (root+_pane+_slide+_hover);
+
+ return $.trim(classes);
+ }
+, addHover = function (evt, el) {
+ var $E = $(el || this);
+ if (evt && $E.data("layoutRole") === "toggler")
+ evt.stopPropagation(); // prevent triggering 'slide' on Resizer-bar
+ $E.addClass( getHoverClasses($E) );
+ }
+, removeHover = function (evt, el) {
+ var $E = $(el || this);
+ $E.removeClass( getHoverClasses($E, true) );
+ }
+
+, onResizerEnter = function (evt) { // ALSO called by toggler.mouseenter
+ if ($.fn.disableSelection)
+ $("body").disableSelection();
+ }
+, onResizerLeave = function (evt, el) {
+ var
+ e = el || this // el is only passed when called by the timer
+ , pane = $(e).data("layoutEdge")
+ , name = pane +"ResizerLeave"
+ ;
+ timer.clear(pane+"_openSlider"); // cancel slideOpen timer, if set
+ timer.clear(name); // cancel enableSelection timer - may re/set below
+ // this method calls itself on a timer because it needs to allow
+ // enough time for dragging to kick-in and set the isResizing flag
+ // dragging has a 100ms delay set, so this delay must be >100
+ if (!el) // 1st call - mouseleave event
+ timer.set(name, function(){ onResizerLeave(evt, e); }, 200);
+ // if user is resizing, then dragStop will enableSelection(), so can skip it here
+ else if (!state[pane].isResizing && $.fn.enableSelection) // 2nd call - by timer
+ $("body").enableSelection();
+ }
+
+/*
+ * ###########################
+ * INITIALIZATION METHODS
+ * ###########################
+ */
+
+ /**
+ * Initialize the layout - called automatically whenever an instance of layout is created
+ *
+ * @see none - triggered onInit
+ * @return mixed true = fully initialized | false = panes not initialized (yet) | 'cancel' = abort
+ */
+, _create = function () {
+ // initialize config/options
+ initOptions();
+ var o = options;
+
+ // TEMP state so isInitialized returns true during init process
+ state.creatingLayout = true;
+
+ // init plugins for this layout, if there are any (eg: stateManagement)
+ runPluginCallbacks( Instance, $.layout.onCreate );
+
+ // options & state have been initialized, so now run beforeLoad callback
+ // onload will CANCEL layout creation if it returns false
+ if (false === _runCallbacks("onload_start"))
+ return 'cancel';
+
+ // initialize the container element
+ _initContainer();
+
+ // bind hotkey function - keyDown - if required
+ initHotkeys();
+
+ // bind window.onunload
+ $(window).bind("unload."+ sID, unload);
+
+ // init plugins for this layout, if there are any (eg: customButtons)
+ runPluginCallbacks( Instance, $.layout.onLoad );
+
+ // if layout elements are hidden, then layout WILL NOT complete initialization!
+ // initLayoutElements will set initialized=true and run the onload callback IF successful
+ if (o.initPanes) _initLayoutElements();
+
+ delete state.creatingLayout;
+
+ return state.initialized;
+ }
+
+ /**
+ * Initialize the layout IF not already
+ *
+ * @see All methods in Instance run this test
+ * @return boolean true = layoutElements have been initialized | false = panes are not initialized (yet)
+ */
+, isInitialized = function () {
+ if (state.initialized || state.creatingLayout) return true; // already initialized
+ else return _initLayoutElements(); // try to init panes NOW
+ }
+
+ /**
+ * Initialize the layout - called automatically whenever an instance of layout is created
+ *
+ * @see _create() & isInitialized
+ * @return An object pointer to the instance created
+ */
+, _initLayoutElements = function (retry) {
+ // initialize config/options
+ var o = options;
+
+ // CANNOT init panes inside a hidden container!
+ if (!$N.is(":visible")) {
+ // handle Chrome bug where popup window 'has no height'
+ // if layout is BODY element, try again in 50ms
+ // SEE: http://layout.jquery-dev.net/samples/test_popup_window.html
+ if ( !retry && browser.webkit && $N[0].tagName === "BODY" )
+ setTimeout(function(){ _initLayoutElements(true); }, 50);
+ return false;
+ }
+
+ // a center pane is required, so make sure it exists
+ if (!getPane("center").length) {
+ if (options.showErrorMessages)
+ _log( lang.errCenterPaneMissing, true );
+ return false;
+ }
+
+ // TEMP state so isInitialized returns true during init process
+ state.creatingLayout = true;
+
+ // update Container dims
+ $.extend(sC, elDims( $N ));
+
+ // initialize all layout elements
+ initPanes(); // size & position panes - calls initHandles() - which calls initResizable()
+
+ if (o.scrollToBookmarkOnLoad) {
+ var l = self.location;
+ if (l.hash) l.replace( l.hash ); // scrollTo Bookmark
+ }
+
+ // check to see if this layout 'nested' inside a pane
+ if (Instance.hasParentLayout)
+ o.resizeWithWindow = false;
+ // bind resizeAll() for 'this layout instance' to window.resize event
+ else if (o.resizeWithWindow)
+ $(window).bind("resize."+ sID, windowResize);
+
+ delete state.creatingLayout;
+ state.initialized = true;
+
+ // init plugins for this layout, if there are any
+ runPluginCallbacks( Instance, $.layout.onReady );
+
+ // now run the onload callback, if exists
+ _runCallbacks("onload_end");
+
+ return true; // elements initialized successfully
+ }
+
+ /**
+ * Initialize nested layouts - called when _initLayoutElements completes
+ *
+ * NOT CURRENTLY USED
+ *
+ * @see _initLayoutElements
+ * @return An object pointer to the instance created
+ */
+, _initChildLayouts = function () {
+ $.each(_c.allPanes, function (idx, pane) {
+ if (options[pane].initChildLayout)
+ createChildLayout( pane );
+ });
+ }
+
+ /**
+ * Initialize nested layouts for a specific pane - can optionally pass layout-options
+ *
+ * @see _initChildLayouts
+ * @param {string} pane The pane being opened, ie: north, south, east, or west
+ * @param {Object=} [opts] Layout-options - if passed, will OVERRRIDE options[pane].childOptions
+ * @return An object pointer to the layout instance created - or null
+ */
+, createChildLayout = function (evt_or_pane, opts) {
+ var pane = evtPane.call(this, evt_or_pane)
+ , $P = $Ps[pane]
+ , C = children
+ ;
+ if ($P) {
+ var $C = $Cs[pane]
+ , o = opts || options[pane].childOptions
+ , d = "layout"
+ // determine which element is supposed to be the 'child container'
+ // if pane has a 'containerSelector' OR a 'content-div', use those instead of the pane
+ , $Cont = o.containerSelector ? $P.find( o.containerSelector ) : ($C || $P)
+ , containerFound = $Cont.length
+ // see if a child-layout ALREADY exists on this element
+ , child = containerFound ? (C[pane] = $Cont.data(d) || null) : null
+ ;
+ // if no layout exists, but childOptions are set, try to create the layout now
+ if (!child && containerFound && o)
+ child = C[pane] = $Cont.eq(0).layout(o) || null;
+ if (child)
+ child.hasParentLayout = true; // set parent-flag in child
+ }
+ Instance[pane].child = C[pane]; // ALWAYS set pane-object pointer, even if null
+ }
+
+, windowResize = function () {
+ var delay = Number(options.resizeWithWindowDelay);
+ if (delay < 10) delay = 100; // MUST have a delay!
+ // resizing uses a delay-loop because the resize event fires repeatly - except in FF, but delay anyway
+ timer.clear("winResize"); // if already running
+ timer.set("winResize", function(){
+ timer.clear("winResize");
+ timer.clear("winResizeRepeater");
+ var dims = elDims( $N );
+ // only trigger resizeAll() if container has changed size
+ if (dims.innerWidth !== sC.innerWidth || dims.innerHeight !== sC.innerHeight)
+ resizeAll();
+ }, delay);
+ // ALSO set fixed-delay timer, if not already running
+ if (!timer.data["winResizeRepeater"]) setWindowResizeRepeater();
+ }
+
+, setWindowResizeRepeater = function () {
+ var delay = Number(options.resizeWithWindowMaxDelay);
+ if (delay > 0)
+ timer.set("winResizeRepeater", function(){ setWindowResizeRepeater(); resizeAll(); }, delay);
+ }
+
+, unload = function () {
+ var o = options;
+
+ _runCallbacks("onunload_start");
+
+ // trigger plugin callabacks for this layout (eg: stateManagement)
+ runPluginCallbacks( Instance, $.layout.onUnload );
+
+ _runCallbacks("onunload_end");
+ }
+
+ /**
+ * Validate and initialize container CSS and events
+ *
+ * @see _create()
+ */
+, _initContainer = function () {
+ var
+ N = $N[0]
+ , tag = sC.tagName = N.tagName
+ , id = sC.id = N.id
+ , cls = sC.className = N.className
+ , o = options
+ , name = o.name
+ , fullPage= (tag === "BODY")
+ , props = "overflow,position,margin,padding,border"
+ , css = "layoutCSS"
+ , CSS = {}
+ , hid = "hidden" // used A LOT!
+ // see if this container is a 'pane' inside an outer-layout
+ , parent = $N.data("parentLayout") // parent-layout Instance
+ , pane = $N.data("layoutEdge") // pane-name in parent-layout
+ , isChild = parent && pane
+ ;
+ // sC -> state.container
+ sC.selector = $N.selector.split(".slice")[0];
+ sC.ref = (o.name ? o.name +' layout / ' : '') + tag + (id ? "#"+id : cls ? '.['+cls+']' : ''); // used in messages
+
+ $N .data({
+ layout: Instance
+ , layoutContainer: sID // FLAG to indicate this is a layout-container - contains unique internal ID
+ })
+ .addClass(o.containerClass)
+ ;
+ var layoutMethods = {
+ destroy: ''
+ , initPanes: ''
+ , resizeAll: 'resizeAll'
+ , resize: 'resizeAll'
+ }
+ , name;
+ // loop hash and bind all methods - include layoutID namespacing
+ for (name in layoutMethods) {
+ $N.bind("layout"+ name.toLowerCase() +"."+ sID, Instance[ layoutMethods[name] || name ]);
+ }
+
+ // if this container is another layout's 'pane', then set child/parent pointers
+ if (isChild) {
+ // update parent flag
+ Instance.hasParentLayout = true;
+ // set pointers to THIS child-layout (Instance) in parent-layout
+ // NOTE: parent.PANE.child is an ALIAS to parent.children.PANE
+ parent[pane].child = parent.children[pane] = $N.data("layout");
+ }
+
+ // SAVE original container CSS for use in destroy()
+ if (!$N.data(css)) {
+ // handle props like overflow different for BODY & HTML - has 'system default' values
+ if (fullPage) {
+ CSS = $.extend( elCSS($N, props), {
+ height: $N.css("height")
+ , overflow: $N.css("overflow")
+ , overflowX: $N.css("overflowX")
+ , overflowY: $N.css("overflowY")
+ });
+ // ALSO SAVE <HTML> CSS
+ var $H = $("html");
+ $H.data(css, {
+ height: "auto" // FF would return a fixed px-size!
+ , overflow: $H.css("overflow")
+ , overflowX: $H.css("overflowX")
+ , overflowY: $H.css("overflowY")
+ });
+ }
+ else // handle props normally for non-body elements
+ CSS = elCSS($N, props+",top,bottom,left,right,width,height,overflow,overflowX,overflowY");
+
+ $N.data(css, CSS);
+ }
+
+ try { // format html/body if this is a full page layout
+ if (fullPage) {
+ $("html").css({
+ height: "100%"
+ , overflow: hid
+ , overflowX: hid
+ , overflowY: hid
+ });
+ $("body").css({
+ position: "relative"
+ , height: "100%"
+ , overflow: hid
+ , overflowX: hid
+ , overflowY: hid
+ , margin: 0
+ , padding: 0 // TODO: test whether body-padding could be handled?
+ , border: "none" // a body-border creates problems because it cannot be measured!
+ });
+
+ // set current layout-container dimensions
+ $.extend(sC, elDims( $N ));
+ }
+ else { // set required CSS for overflow and position
+ // ENSURE container will not 'scroll'
+ CSS = { overflow: hid, overflowX: hid, overflowY: hid }
+ var
+ p = $N.css("position")
+ , h = $N.css("height")
+ ;
+ // if this is a NESTED layout, then container/outer-pane ALREADY has position and height
+ if (!isChild) {
+ if (!p || !p.match(/fixed|absolute|relative/))
+ CSS.position = "relative"; // container MUST have a 'position'
+ /*
+ if (!h || h=="auto")
+ CSS.height = "100%"; // container MUST have a 'height'
+ */
+ }
+ $N.css( CSS );
+
+ // set current layout-container dimensions
+ if ( $N.is(":visible") ) {
+ $.extend(sC, elDims( $N ));
+ if (o.showErrorMessages && sC.innerHeight < 1)
+ _log( lang.errContainerHeight.replace(/CONTAINER/, sC.ref), true );
+ }
+ }
+ } catch (ex) {}
+ }
+
+ /**
+ * Bind layout hotkeys - if options enabled
+ *
+ * @see _create() and addPane()
+ * @param {string=} [panes=""] The edge(s) to process
+ */
+, initHotkeys = function (panes) {
+ panes = panes ? panes.split(",") : _c.borderPanes;
+ // bind keyDown to capture hotkeys, if option enabled for ANY pane
+ $.each(panes, function (i, pane) {
+ var o = options[pane];
+ if (o.enableCursorHotkey || o.customHotkey) {
+ $(document).bind("keydown."+ sID, keyDown); // only need to bind this ONCE
+ return false; // BREAK - binding was done
+ }
+ });
+ }
+
+ /**
+ * Build final OPTIONS data
+ *
+ * @see _create()
+ */
+, initOptions = function () {
+ var data, d, pane, key, val, i, c, o;
+
+ // reprocess user's layout-options to have correct options sub-key structure
+ opts = $.layout.transformData( opts ); // panes = default subkey
+
+ // auto-rename old options for backward compatibility
+ opts = $.layout.backwardCompatibility.renameAllOptions( opts );
+
+ // if user-options has 'panes' key (pane-defaults), process it...
+ if (!$.isEmptyObject(opts.panes)) {
+ // REMOVE any pane-defaults that MUST be set per-pane
+ data = $.layout.optionsMap.noDefault;
+ for (i=0, c=data.length; i<c; i++) {
+ key = data[i];
+ delete opts.panes[key]; // OK if does not exist
+ }
+ // REMOVE any layout-options specified under opts.panes
+ data = $.layout.optionsMap.layout;
+ for (i=0, c=data.length; i<c; i++) {
+ key = data[i];
+ delete opts.panes[key]; // OK if does not exist
+ }
+ }
+
+ // MOVE any NON-layout-options to opts.panes
+ data = $.layout.optionsMap.layout;
+ var rootKeys = $.layout.config.optionRootKeys;
+ for (key in opts) {
+ val = opts[key];
+ if ($.inArray(key, rootKeys) < 0 && $.inArray(key, data) < 0) {
+ if (!opts.panes[key])
+ opts.panes[key] = $.isPlainObject(val) ? $.extend(true, {}, val) : val;
+ delete opts[key]
+ }
+ }
+
+ // START by updating ALL options from opts
+ $.extend(true, options, opts);
+
+ // CREATE final options (and config) for EACH pane
+ $.each(_c.allPanes, function (i, pane) {
+
+ // apply 'pane-defaults' to CONFIG.[PANE]
+ _c[pane] = $.extend( true, {}, _c.panes, _c[pane] );
+
+ d = options.panes;
+ o = options[pane];
+
+ // center-pane uses SOME keys in defaults.panes branch
+ if (pane === 'center') {
+ // ONLY copy keys from opts.panes listed in: $.layout.optionsMap.center
+ data = $.layout.optionsMap.center; // list of 'center-pane keys'
+ for (i=0, c=data.length; i<c; i++) { // loop the list...
+ key = data[i];
+ // only need to use pane-default if pane-specific value not set
+ if (!opts.center[key] && (opts.panes[key] || !o[key]))
+ o[key] = d[key]; // pane-default
+ }
+ }
+ else {
+ // border-panes use ALL keys in defaults.panes branch
+ o = options[pane] = $.extend({}, d, o); // re-apply pane-specific opts AFTER pane-defaults
+ createFxOptions( pane );
+ // ensure all border-pane-specific base-classes exist
+ if (!o.resizerClass) o.resizerClass = "ui-layout-resizer";
+ if (!o.togglerClass) o.togglerClass = "ui-layout-toggler";
+ }
+ // ensure we have base pane-class (ALL panes)
+ if (!o.paneClass) o.paneClass = "ui-layout-pane";
+ });
+
+ // update options.zIndexes if a zIndex-option specified
+ var zo = opts.zIndex
+ , z = options.zIndexes;
+ if (zo > 0) {
+ z.pane_normal = zo;
+ z.content_mask = max(zo+1, z.content_mask); // MIN = +1
+ z.resizer_normal = max(zo+2, z.resizer_normal); // MIN = +2
+ }
+
+ function createFxOptions ( pane ) {
+ var o = options[pane]
+ , d = options.panes;
+ // ensure fxSettings key to avoid errors
+ if (!o.fxSettings) o.fxSettings = {};
+ if (!d.fxSettings) d.fxSettings = {};
+
+ $.each(["_open","_close","_size"], function (i,n) {
+ var
+ sName = "fxName"+ n
+ , sSpeed = "fxSpeed"+ n
+ , sSettings = "fxSettings"+ n
+ // recalculate fxName according to specificity rules
+ , fxName = o[sName] =
+ o[sName] // options.west.fxName_open
+ || d[sName] // options.panes.fxName_open
+ || o.fxName // options.west.fxName
+ || d.fxName // options.panes.fxName
+ || "none" // MEANS $.layout.defaults.panes.fxName == "" || false || null || 0
+ ;
+ // validate fxName to ensure is valid effect - MUST have effect-config data in options.effects
+ if (fxName === "none" || !$.effects || !$.effects[fxName] || !options.effects[fxName])
+ fxName = o[sName] = "none"; // effect not loaded OR unrecognized fxName
+
+ // set vars for effects subkeys to simplify logic
+ var fx = options.effects[fxName] || {} // effects.slide
+ , fx_all = fx.all || null // effects.slide.all
+ , fx_pane = fx[pane] || null // effects.slide.west
+ ;
+ // create fxSpeed[_open|_close|_size]
+ o[sSpeed] =
+ o[sSpeed] // options.west.fxSpeed_open
+ || d[sSpeed] // options.west.fxSpeed_open
+ || o.fxSpeed // options.west.fxSpeed
+ || d.fxSpeed // options.panes.fxSpeed
+ || null // DEFAULT - let fxSetting.duration control speed
+ ;
+ // create fxSettings[_open|_close|_size]
+ o[sSettings] = $.extend(
+ {}
+ , fx_all // effects.slide.all
+ , fx_pane // effects.slide.west
+ , d.fxSettings // options.panes.fxSettings
+ , o.fxSettings // options.west.fxSettings
+ , d[sSettings] // options.panes.fxSettings_open
+ , o[sSettings] // options.west.fxSettings_open
+ );
+ });
+
+ // DONE creating action-specific-settings for this pane,
+ // so DELETE generic options - are no longer meaningful
+ delete o.fxName;
+ delete o.fxSpeed;
+ delete o.fxSettings;
+ }
+
+ // DELETE 'panes' key now that we are done - values were copied to EACH pane
+ delete options.panes;
+ }
+
+ /**
+ * Initialize module objects, styling, size and position for all panes
+ *
+ * @see _initElements()
+ * @param {string} pane The pane to process
+ */
+, getPane = function (pane) {
+ var sel = options[pane].paneSelector
+ if (sel.substr(0,1)==="#") // ID selector
+ // NOTE: elements selected 'by ID' DO NOT have to be 'children'
+ return $N.find(sel).eq(0);
+ else { // class or other selector
+ var $P = $N.children(sel).eq(0);
+ // look for the pane nested inside a 'form' element
+ return $P.length ? $P : $N.children("form:first").children(sel).eq(0);
+ }
+ }
+
+, initPanes = function () {
+ // NOTE: do north & south FIRST so we can measure their height - do center LAST
+ $.each(_c.allPanes, function (idx, pane) {
+ addPane( pane, true );
+ });
+
+ // init the pane-handles NOW in case we have to hide or close the pane below
+ initHandles();
+
+ // now that all panes have been initialized and initially-sized,
+ // make sure there is really enough space available for each pane
+ $.each(_c.borderPanes, function (i, pane) {
+ if ($Ps[pane] && state[pane].isVisible) { // pane is OPEN
+ setSizeLimits(pane);
+ makePaneFit(pane); // pane may be Closed, Hidden or Resized by makePaneFit()
+ }
+ });
+ // size center-pane AGAIN in case we 'closed' a border-pane in loop above
+ sizeMidPanes("center");
+
+ // Chrome/Webkit sometimes fires callbacks BEFORE it completes resizing!
+ // Before RC30.3, there was a 10ms delay here, but that caused layout
+ // to load asynchrously, which is BAD, so try skipping delay for now
+
+ // process pane contents and callbacks, and init/resize child-layout if exists
+ $.each(_c.allPanes, function (i, pane) {
+ var o = options[pane];
+ if ($Ps[pane]) {
+ if (state[pane].isVisible) { // pane is OPEN
+ sizeContent(pane);
+ // trigger pane.onResize if triggerEventsOnLoad = true
+ if (o.triggerEventsOnLoad)
+ _runCallbacks("onresize_end", pane);
+ else // automatic if onresize called, otherwise call it specifically
+ // resize child - IF inner-layout already exists (created before this layout)
+ resizeChildLayout(pane);
+ }
+ // init childLayout - even if pane is not visible
+ if (o.initChildLayout && o.childOptions)
+ createChildLayout(pane);
+ }
+ });
+ }
+
+ /**
+ * Add a pane to the layout - subroutine of initPanes()
+ *
+ * @see initPanes()
+ * @param {string} pane The pane to process
+ * @param {boolean=} [force=false] Size content after init
+ */
+, addPane = function (pane, force) {
+ if (!force && !isInitialized()) return;
+ var
+ o = options[pane]
+ , s = state[pane]
+ , c = _c[pane]
+ , fx = s.fx
+ , dir = c.dir
+ , spacing = o.spacing_open || 0
+ , isCenter = (pane === "center")
+ , CSS = {}
+ , $P = $Ps[pane]
+ , size, minSize, maxSize
+ ;
+ // if pane-pointer already exists, remove the old one first
+ if ($P)
+ removePane( pane, false, true, false );
+ else
+ $Cs[pane] = false; // init
+
+ $P = $Ps[pane] = getPane(pane);
+ if (!$P.length) {
+ $Ps[pane] = false; // logic
+ return;
+ }
+
+ // SAVE original Pane CSS
+ if (!$P.data("layoutCSS")) {
+ var props = "position,top,left,bottom,right,width,height,overflow,zIndex,display,backgroundColor,padding,margin,border";
+ $P.data("layoutCSS", elCSS($P, props));
+ }
+
+ // create alias for pane data in Instance - initHandles will add more
+ Instance[pane] = { name: pane, pane: $Ps[pane], content: $Cs[pane], options: options[pane], state: state[pane], child: children[pane] };
+
+ // add classes, attributes & events
+ $P .data({
+ parentLayout: Instance // pointer to Layout Instance
+ , layoutPane: Instance[pane] // NEW pointer to pane-alias-object
+ , layoutEdge: pane
+ , layoutRole: "pane"
+ })
+ .css(c.cssReq).css("zIndex", options.zIndexes.pane_normal)
+ .css(o.applyDemoStyles ? c.cssDemo : {}) // demo styles
+ .addClass( o.paneClass +" "+ o.paneClass+"-"+pane ) // default = "ui-layout-pane ui-layout-pane-west" - may be a dupe of 'paneSelector'
+ .bind("mouseenter."+ sID, addHover )
+ .bind("mouseleave."+ sID, removeHover )
+ ;
+ var paneMethods = {
+ hide: ''
+ , show: ''
+ , toggle: ''
+ , close: ''
+ , open: ''
+ , slideOpen: ''
+ , slideClose: ''
+ , slideToggle: ''
+ , size: 'manualSizePane'
+ , sizePane: 'manualSizePane'
+ , sizeContent: ''
+ , sizeHandles: ''
+ , enableClosable: ''
+ , disableClosable: ''
+ , enableSlideable: ''
+ , disableSlideable: ''
+ , enableResizable: ''
+ , disableResizable: ''
+ , swapPanes: 'swapPanes'
+ , swap: 'swapPanes'
+ , move: 'swapPanes'
+ , removePane: 'removePane'
+ , remove: 'removePane'
+ , createChildLayout: ''
+ , resizeChildLayout: ''
+ , resizeAll: 'resizeAll'
+ , resizeLayout: 'resizeAll'
+ }
+ , name;
+ // loop hash and bind all methods - include layoutID namespacing
+ for (name in paneMethods) {
+ $P.bind("layoutpane"+ name.toLowerCase() +"."+ sID, Instance[ paneMethods[name] || name ]);
+ }
+
+ // see if this pane has a 'scrolling-content element'
+ initContent(pane, false); // false = do NOT sizeContent() - called later
+
+ if (!isCenter) {
+ // call _parseSize AFTER applying pane classes & styles - but before making visible (if hidden)
+ // if o.size is auto or not valid, then MEASURE the pane and use that as its 'size'
+ size = s.size = _parseSize(pane, o.size);
+ minSize = _parseSize(pane,o.minSize) || 1;
+ maxSize = _parseSize(pane,o.maxSize) || 100000;
+ if (size > 0) size = max(min(size, maxSize), minSize);
+
+ // state for border-panes
+ s.isClosed = false; // true = pane is closed
+ s.isSliding = false; // true = pane is currently open by 'sliding' over adjacent panes
+ s.isResizing= false; // true = pane is in process of being resized
+ s.isHidden = false; // true = pane is hidden - no spacing, resizer or toggler is visible!
+
+ // array for 'pin buttons' whose classNames are auto-updated on pane-open/-close
+ if (!s.pins) s.pins = [];
+ }
+ // states common to ALL panes
+ s.tagName = $P[0].tagName;
+ s.edge = pane; // useful if pane is (or about to be) 'swapped' - easy find out where it is (or is going)
+ s.noRoom = false; // true = pane 'automatically' hidden due to insufficient room - will unhide automatically
+ s.isVisible = true; // false = pane is invisible - closed OR hidden - simplify logic
+
+ // set css-position to account for container borders & padding
+ switch (pane) {
+ case "north": CSS.top = sC.insetTop;
+ CSS.left = sC.insetLeft;
+ CSS.right = sC.insetRight;
+ break;
+ case "south": CSS.bottom = sC.insetBottom;
+ CSS.left = sC.insetLeft;
+ CSS.right = sC.insetRight;
+ break;
+ case "west": CSS.left = sC.insetLeft; // top, bottom & height set by sizeMidPanes()
+ break;
+ case "east": CSS.right = sC.insetRight; // ditto
+ break;
+ case "center": // top, left, width & height set by sizeMidPanes()
+ }
+
+ if (dir === "horz") // north or south pane
+ CSS.height = cssH($P, size);
+ else if (dir === "vert") // east or west pane
+ CSS.width = cssW($P, size);
+ //else if (isCenter) {}
+
+ $P.css(CSS); // apply size -- top, bottom & height will be set by sizeMidPanes
+ if (dir != "horz") sizeMidPanes(pane, true); // true = skipCallback
+
+ // close or hide the pane if specified in settings
+ if (o.initClosed && o.closable && !o.initHidden)
+ close(pane, true, true); // true, true = force, noAnimation
+ else if (o.initHidden || o.initClosed)
+ hide(pane); // will be completely invisible - no resizer or spacing
+ else if (!s.noRoom)
+ // make the pane visible - in case was initially hidden
+ $P.css("display","block");
+ // ELSE setAsOpen() - called later by initHandles()
+
+ // RESET visibility now - pane will appear IF display:block
+ $P.css("visibility","visible");
+
+ // check option for auto-handling of pop-ups & drop-downs
+ if (o.showOverflowOnHover)
+ $P.hover( allowOverflow, resetOverflow );
+
+ // if manually adding a pane AFTER layout initialization, then...
+ if (state.initialized) {
+ initHandles( pane );
+ initHotkeys( pane );
+ resizeAll(); // will sizeContent if pane is visible
+ if (s.isVisible) { // pane is OPEN
+ if (o.triggerEventsOnLoad)
+ _runCallbacks("onresize_end", pane);
+ else // automatic if onresize called, otherwise call it specifically
+ // resize child - IF inner-layout already exists (created before this layout)
+ resizeChildLayout(pane); // a previously existing childLayout
+ }
+ if (o.initChildLayout && o.childOptions)
+ createChildLayout(pane);
+ }
+ }
+
+ /**
+ * Initialize module objects, styling, size and position for all resize bars and toggler buttons
+ *
+ * @see _create()
+ * @param {string=} [panes=""] The edge(s) to process
+ */
+, initHandles = function (panes) {
+ panes = panes ? panes.split(",") : _c.borderPanes;
+
+ // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV
+ $.each(panes, function (i, pane) {
+ var $P = $Ps[pane];
+ $Rs[pane] = false; // INIT
+ $Ts[pane] = false;
+ if (!$P) return; // pane does not exist - skip
+
+ var
+ o = options[pane]
+ , s = state[pane]
+ , c = _c[pane]
+ , rClass = o.resizerClass
+ , tClass = o.togglerClass
+ , side = c.side.toLowerCase()
+ , spacing = (s.isVisible ? o.spacing_open : o.spacing_closed)
+ , _pane = "-"+ pane // used for classNames
+ , _state = (s.isVisible ? "-open" : "-closed") // used for classNames
+ , I = Instance[pane]
+ // INIT RESIZER BAR
+ , $R = I.resizer = $Rs[pane] = $("<div></div>")
+ // INIT TOGGLER BUTTON
+ , $T = I.toggler = (o.closable ? $Ts[pane] = $("<div></div>") : false)
+ ;
+
+ //if (s.isVisible && o.resizable) ... handled by initResizable
+ if (!s.isVisible && o.slidable)
+ $R.attr("title", o.sliderTip).css("cursor", o.sliderCursor);
+
+ $R // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "paneLeft-resizer"
+ .attr("id", (o.paneSelector.substr(0,1)=="#" ? o.paneSelector.substr(1) + "-resizer" : ""))
+ .data({
+ parentLayout: Instance
+ , layoutPane: Instance[pane] // NEW pointer to pane-alias-object
+ , layoutEdge: pane
+ , layoutRole: "resizer"
+ })
+ .css(_c.resizers.cssReq).css("zIndex", options.zIndexes.resizer_normal)
+ .css(o.applyDemoStyles ? _c.resizers.cssDemo : {}) // add demo styles
+ .addClass(rClass +" "+ rClass+_pane)
+ .hover(addHover, removeHover) // ALWAYS add hover-classes, even if resizing is not enabled - handle with CSS instead
+ .hover(onResizerEnter, onResizerLeave) // ALWAYS NEED resizer.mouseleave to balance toggler.mouseenter
+ .appendTo($N) // append DIV to container
+ ;
+
+ if ($T) {
+ $T // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "#paneLeft-toggler"
+ .attr("id", (o.paneSelector.substr(0,1)=="#" ? o.paneSelector.substr(1) + "-toggler" : ""))
+ .data({
+ parentLayout: Instance
+ , layoutPane: Instance[pane] // NEW pointer to pane-alias-object
+ , layoutEdge: pane
+ , layoutRole: "toggler"
+ })
+ .css(_c.togglers.cssReq) // add base/required styles
+ .css(o.applyDemoStyles ? _c.togglers.cssDemo : {}) // add demo styles
+ .addClass(tClass +" "+ tClass+_pane)
+ .hover(addHover, removeHover) // ALWAYS add hover-classes, even if toggling is not enabled - handle with CSS instead
+ .bind("mouseenter", onResizerEnter) // NEED toggler.mouseenter because mouseenter MAY NOT fire on resizer
+ .appendTo($R) // append SPAN to resizer DIV
+ ;
+ // ADD INNER-SPANS TO TOGGLER
+ if (o.togglerContent_open) // ui-layout-open
+ $("<span>"+ o.togglerContent_open +"</span>")
+ .data({
+ layoutEdge: pane
+ , layoutRole: "togglerContent"
+ })
+ .data("layoutRole", "togglerContent")
+ .data("layoutEdge", pane)
+ .addClass("content content-open")
+ .css("display","none")
+ .appendTo( $T )
+ //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-open instead!
+ ;
+ if (o.togglerContent_closed) // ui-layout-closed
+ $("<span>"+ o.togglerContent_closed +"</span>")
+ .data({
+ layoutEdge: pane
+ , layoutRole: "togglerContent"
+ })
+ .addClass("content content-closed")
+ .css("display","none")
+ .appendTo( $T )
+ //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-closed instead!
+ ;
+ // ADD TOGGLER.click/.hover
+ enableClosable(pane);
+ }
+
+ // add Draggable events
+ initResizable(pane);
+
+ // ADD CLASSNAMES & SLIDE-BINDINGS - eg: class="resizer resizer-west resizer-open"
+ if (s.isVisible)
+ setAsOpen(pane); // onOpen will be called, but NOT onResize
+ else {
+ setAsClosed(pane); // onClose will be called
+ bindStartSlidingEvent(pane, true); // will enable events IF option is set
+ }
+
+ });
+
+ // SET ALL HANDLE DIMENSIONS
+ sizeHandles();
+ }
+
+
+ /**
+ * Initialize scrolling ui-layout-content div - if exists
+ *
+ * @see initPane() - or externally after an Ajax injection
+ * @param {string} [pane] The pane to process
+ * @param {boolean=} [resize=true] Size content after init
+ */
+, initContent = function (pane, resize) {
+ if (!isInitialized()) return;
+ var
+ o = options[pane]
+ , sel = o.contentSelector
+ , I = Instance[pane]
+ , $P = $Ps[pane]
+ , $C
+ ;
+ if (sel) $C = I.content = $Cs[pane] = (o.findNestedContent)
+ ? $P.find(sel).eq(0) // match 1-element only
+ : $P.children(sel).eq(0)
+ ;
+ if ($C && $C.length) {
+ $C.data("layoutRole", "content");
+ // SAVE original Pane CSS
+ if (!$C.data("layoutCSS"))
+ $C.data("layoutCSS", elCSS($C, "height"));
+ $C.css( _c.content.cssReq );
+ if (o.applyDemoStyles) {
+ $C.css( _c.content.cssDemo ); // add padding & overflow: auto to content-div
+ $P.css( _c.content.cssDemoPane ); // REMOVE padding/scrolling from pane
+ }
+ state[pane].content = {}; // init content state
+ if (resize !== false) sizeContent(pane);
+ // sizeContent() is called AFTER init of all elements
+ }
+ else
+ I.content = $Cs[pane] = false;
+ }
+
+
+ /**
+ * Add resize-bars to all panes that specify it in options
+ * -dependancy: $.fn.resizable - will skip if not found
+ *
+ * @see _create()
+ * @param {string=} [panes=""] The edge(s) to process
+ */
+, initResizable = function (panes) {
+ var draggingAvailable = $.layout.plugins.draggable
+ , side // set in start()
+ ;
+ panes = panes ? panes.split(",") : _c.borderPanes;
+
+ $.each(panes, function (idx, pane) {
+ var o = options[pane];
+ if (!draggingAvailable || !$Ps[pane] || !o.resizable) {
+ o.resizable = false;
+ return true; // skip to next
+ }
+
+ var s = state[pane]
+ , z = options.zIndexes
+ , c = _c[pane]
+ , side = c.dir=="horz" ? "top" : "left"
+ , opEdge = _c.oppositeEdge[pane]
+ , masks = pane +",center,"+ opEdge + (c.dir=="horz" ? ",west,east" : "")
+ , $P = $Ps[pane]
+ , $R = $Rs[pane]
+ , base = o.resizerClass
+ , lastPos = 0 // used when live-resizing
+ , r, live // set in start because may change
+ // 'drag' classes are applied to the ORIGINAL resizer-bar while dragging is in process
+ , resizerClass = base+"-drag" // resizer-drag
+ , resizerPaneClass = base+"-"+pane+"-drag" // resizer-north-drag
+ // 'helper' class is applied to the CLONED resizer-bar while it is being dragged
+ , helperClass = base+"-dragging" // resizer-dragging
+ , helperPaneClass = base+"-"+pane+"-dragging" // resizer-north-dragging
+ , helperLimitClass = base+"-dragging-limit" // resizer-drag
+ , helperPaneLimitClass = base+"-"+pane+"-dragging-limit" // resizer-north-drag
+ , helperClassesSet = false // logic var
+ ;
+
+ if (!s.isClosed)
+ $R.attr("title", o.resizerTip)
+ .css("cursor", o.resizerCursor); // n-resize, s-resize, etc
+
+ $R.draggable({
+ containment: $N[0] // limit resizing to layout container
+ , axis: (c.dir=="horz" ? "y" : "x") // limit resizing to horz or vert axis
+ , delay: 0
+ , distance: 1
+ , grid: o.resizingGrid
+ // basic format for helper - style it using class: .ui-draggable-dragging
+ , helper: "clone"
+ , opacity: o.resizerDragOpacity
+ , addClasses: false // avoid ui-state-disabled class when disabled
+ //, iframeFix: o.draggableIframeFix // TODO: consider using when bug is fixed
+ , zIndex: z.resizer_drag
+
+ , start: function (e, ui) {
+ // REFRESH options & state pointers in case we used swapPanes
+ o = options[pane];
+ s = state[pane];
+ // re-read options
+ live = o.livePaneResizing;
+
+ // ondrag_start callback - will CANCEL hide if returns false
+ // TODO: dragging CANNOT be cancelled like this, so see if there is a way?
+ if (false === _runCallbacks("ondrag_start", pane)) return false;
+
+ s.isResizing = true; // prevent pane from closing while resizing
+ timer.clear(pane+"_closeSlider"); // just in case already triggered
+
+ // SET RESIZER LIMITS - used in drag()
+ setSizeLimits(pane); // update pane/resizer state
+ r = s.resizerPosition;
+ lastPos = ui.position[ side ]
+
+ $R.addClass( resizerClass +" "+ resizerPaneClass ); // add drag classes
+ helperClassesSet = false; // reset logic var - see drag()
+
+ // DISABLE TEXT SELECTION (probably already done by resizer.mouseOver)
+ $('body').disableSelection();
+
+ // MASK PANES CONTAINING IFRAMES, APPLETS OR OTHER TROUBLESOME ELEMENTS
+ showMasks( masks );
+ }
+
+ , drag: function (e, ui) {
+ if (!helperClassesSet) { // can only add classes after clone has been added to the DOM
+ //$(".ui-draggable-dragging")
+ ui.helper
+ .addClass( helperClass +" "+ helperPaneClass ) // add helper classes
+ .css({ right: "auto", bottom: "auto" }) // fix dir="rtl" issue
+ .children().css("visibility","hidden") // hide toggler inside dragged resizer-bar
+ ;
+ helperClassesSet = true;
+ // draggable bug!? RE-SET zIndex to prevent E/W resize-bar showing through N/S pane!
+ if (s.isSliding) $Ps[pane].css("zIndex", z.pane_sliding);
+ }
+ // CONTAIN RESIZER-BAR TO RESIZING LIMITS
+ var limit = 0;
+ if (ui.position[side] < r.min) {
+ ui.position[side] = r.min;
+ limit = -1;
+ }
+ else if (ui.position[side] > r.max) {
+ ui.position[side] = r.max;
+ limit = 1;
+ }
+ // ADD/REMOVE dragging-limit CLASS
+ if (limit) {
+ ui.helper.addClass( helperLimitClass +" "+ helperPaneLimitClass ); // at dragging-limit
+ window.defaultStatus = (limit>0 && pane.match(/north|west/)) || (limit<0 && pane.match(/south|east/)) ? lang.maxSizeWarning : lang.minSizeWarning;
+ }
+ else {
+ ui.helper.removeClass( helperLimitClass +" "+ helperPaneLimitClass ); // not at dragging-limit
+ window.defaultStatus = "";
+ }
+ // DYNAMICALLY RESIZE PANES IF OPTION ENABLED
+ // won't trigger unless resizer has actually moved!
+ if (live && Math.abs(ui.position[side] - lastPos) >= o.liveResizingTolerance) {
+ lastPos = ui.position[side];
+ resizePanes(e, ui, pane)
+ }
+ }
+
+ , stop: function (e, ui) {
+ $('body').enableSelection(); // RE-ENABLE TEXT SELECTION
+ window.defaultStatus = ""; // clear 'resizing limit' message from statusbar
+ $R.removeClass( resizerClass +" "+ resizerPaneClass ); // remove drag classes from Resizer
+ s.isResizing = false;
+ resizePanes(e, ui, pane, true, masks); // true = resizingDone
+ }
+
+ });
+ });
+
+ /**
+ * resizePanes
+ *
+ * Sub-routine called from stop() - and drag() if livePaneResizing
+ *
+ * @param {!Object} evt
+ * @param {!Object} ui
+ * @param {string} pane
+ * @param {boolean=} [resizingDone=false]
+ */
+ var resizePanes = function (evt, ui, pane, resizingDone, masks) {
+ var dragPos = ui.position
+ , c = _c[pane]
+ , o = options[pane]
+ , s = state[pane]
+ , resizerPos
+ ;
+ switch (pane) {
+ case "north": resizerPos = dragPos.top; break;
+ case "west": resizerPos = dragPos.left; break;
+ case "south": resizerPos = sC.offsetHeight - dragPos.top - o.spacing_open; break;
+ case "east": resizerPos = sC.offsetWidth - dragPos.left - o.spacing_open; break;
+ };
+ // remove container margin from resizer position to get the pane size
+ var newSize = resizerPos - sC["inset"+ c.side];
+
+ // Disable OR Resize Mask(s) created in drag.start
+ if (!resizingDone) {
+ // ensure we meet liveResizingTolerance criteria
+ if (Math.abs(newSize - s.size) < o.liveResizingTolerance)
+ return; // SKIP resize this time
+ // resize the pane
+ manualSizePane(pane, newSize, false, true); // true = noAnimation
+ sizeMasks(); // resize all visible masks
+ }
+ else { // resizingDone
+ // ondrag_end callback
+ if (false !== _runCallbacks("ondrag_end", pane))
+ manualSizePane(pane, newSize, false, true); // true = noAnimation
+ hideMasks(); // hide all masks, which include panes with 'content/iframe-masks'
+ if (s.isSliding && masks) // RE-SHOW only 'object-masks' so objects won't show through sliding pane
+ showMasks( masks, true ); // true = onlyForObjects
+ }
+ };
+ }
+
+ /**
+ * sizeMask
+ *
+ * Needed to overlay a DIV over an IFRAME-pane because mask CANNOT be *inside* the pane
+ * Called when mask created, and during livePaneResizing
+ */
+, sizeMask = function () {
+ var $M = $(this)
+ , pane = $M.data("layoutMask") // eg: "west"
+ , s = state[pane]
+ ;
+ // only masks over an IFRAME-pane need manual resizing
+ if (s.tagName == "IFRAME" && s.isVisible) // no need to mask closed/hidden panes
+ $M.css({
+ top: s.offsetTop
+ , left: s.offsetLeft
+ , width: s.outerWidth
+ , height: s.outerHeight
+ });
+ /* ALT Method...
+ var $P = $Ps[pane];
+ $M.css( $P.position() ).css({ width: $P[0].offsetWidth, height: $P[0].offsetHeight });
+ */
+ }
+, sizeMasks = function () {
+ $Ms.each( sizeMask ); // resize all 'visible' masks
+ }
+
+, showMasks = function (panes, onlyForObjects) {
+ var a = panes ? panes.split(",") : $.layout.config.allPanes
+ , z = options.zIndexes
+ , o, s;
+ $.each(a, function(i,p){
+ s = state[p];
+ o = options[p];
+ if (s.isVisible && ( (!onlyForObjects && o.maskContents) || o.maskObjects )) {
+ getMasks(p).each(function(){
+ sizeMask.call(this);
+ this.style.zIndex = s.isSliding ? z.pane_sliding+1 : z.pane_normal+1
+ this.style.display = "block";
+ });
+ }
+ });
+ }
+
+, hideMasks = function () {
+ // ensure no pane is resizing - could be a timing issue
+ var skip;
+ $.each( $.layout.config.borderPanes, function(i,p){
+ if (state[p].isResizing) {
+ skip = true;
+ return false; // BREAK
+ }
+ });
+ if (!skip)
+ $Ms.hide(); // hide ALL masks
+ }
+
+, getMasks = function (pane) {
+ var $Masks = $([])
+ , $M, i = 0, c = $Ms.length
+ ;
+ for (; i<c; i++) {
+ $M = $Ms.eq(i);
+ if ($M.data("layoutMask") === pane)
+ $Masks = $Masks.add( $M );
+ }
+ if ($Masks.length)
+ return $Masks;
+ else
+ return createMasks(pane);
+ }
+
+ /**
+ * createMasks
+ *
+ * Generates both DIV (ALWAYS used) and IFRAME (optional) elements as masks
+ * An IFRAME mask is created *under* the DIV when maskObjects=true, because a DIV cannot mask an applet
+ */
+, createMasks = function (pane) {
+ var
+ $P = $Ps[pane]
+ , s = state[pane]
+ , o = options[pane]
+ , z = options.zIndexes
+ //, objMask = o.maskObjects && s.tagName != "IFRAME" // check for option
+ , $Masks = $([])
+ , isIframe, el, $M, css, i
+ ;
+ if (!o.maskContents && !o.maskObjects) return $Masks;
+ // if o.maskObjects=true, then loop TWICE to create BOTH kinds of mask, else only create a DIV
+ for (i=0; i < (o.maskObjects ? 2 : 1); i++) {
+ isIframe = o.maskObjects && i==0;
+ el = document.createElement( isIframe ? "iframe" : "div" );
+ $M = $(el).data("layoutMask", pane); // add data to relate mask to pane
+ el.className = "ui-layout-mask ui-layout-mask-"+ pane; // for user styling
+ css = el.style;
+ // styles common to both DIVs and IFRAMES
+ css.display = "block";
+ css.position = "absolute";
+ if (isIframe) { // IFRAME-only props
+ el.frameborder = 0;
+ el.src = "about:blank";
+ css.opacity = 0;
+ css.filter = "Alpha(Opacity='0')";
+ css.border = 0;
+ }
+ // if pane is an IFRAME, then must mask the pane itself
+ if (s.tagName == "IFRAME") {
+ // NOTE sizing done by a subroutine so can be called during live-resizing
+ css.zIndex = z.pane_normal+1; // 1-higher than pane
+ $N.append( el ); // append to LAYOUT CONTAINER
+ }
+ // otherwise put masks *inside the pane* to mask its contents
+ else {
+ $M.addClass("ui-layout-mask-inside-pane");
+ css.zIndex = o.maskZindex || z.content_mask; // usually 1, but customizable
+ css.top = 0;
+ css.left = 0;
+ css.width = "100%";
+ css.height = "100%";
+ $P.append( el ); // append INSIDE pane element
+ }
+ // add to return object
+ $Masks = $Masks.add( el );
+ // add Mask to cached array so can be resized & reused
+ $Ms = $Ms.add( el );
+ }
+ return $Masks;
+ }
+
+
+ /**
+ * Destroy this layout and reset all elements
+ *
+ * @param {boolean=} [destroyChildren=false] Destory Child-Layouts first?
+ */
+, destroy = function (destroyChildren) {
+ // UNBIND layout events and remove global object
+ $(window).unbind("."+ sID); // resize & unload
+ $(document).unbind("."+ sID); // keyDown (hotkeys)
+
+ // need to look for parent layout BEFORE we remove the container data, else skips a level
+ //var parentPane = Instance.hasParentLayout ? $.layout.getParentPaneInstance( $N ) : null;
+
+ // reset layout-container
+ $N .clearQueue()
+ .removeData("layout")
+ .removeData("layoutContainer")
+ .removeClass(options.containerClass)
+ .unbind("."+ sID) // remove ALL Layout events
+ ;
+
+ // remove all mask elements that have been created
+ $Ms.remove();
+
+ // loop all panes to remove layout classes, attributes and bindings
+ $.each(_c.allPanes, function (i, pane) {
+ removePane( pane, false, true, destroyChildren ); // true = skipResize
+ });
+
+ // do NOT reset container CSS if is a 'pane' (or 'content') in an outer-layout - ie, THIS layout is 'nested'
+ var css = "layoutCSS";
+ if ($N.data(css) && !$N.data("layoutRole")) // RESET CSS
+ $N.css( $N.data(css) ).removeData(css);
+
+ // for full-page layouts, also reset the <HTML> CSS
+ if (sC.tagName === "BODY" && ($N = $("html")).data(css)) // RESET <HTML> CSS
+ $N.css( $N.data(css) ).removeData(css);
+
+ // trigger plugins for this layout, if there are any
+ runPluginCallbacks( Instance, $.layout.onDestroy );
+
+ // trigger state-management and onunload callback
+ unload();
+
+ // clear the Instance of everything except for container & options (so could recreate)
+ // RE-CREATE: myLayout = myLayout.container.layout( myLayout.options );
+ for (n in Instance)
+ if (!n.match(/^(container|options)$/)) delete Instance[ n ];
+ // add a 'destroyed' flag to make it easy to check
+ Instance.destroyed = true;
+
+ // if this is a child layout, CLEAR the child-pointer in the parent
+ /* for now the pointer REMAINS, but with only container, options and destroyed keys
+ if (parentPane) {
+ var layout = parentPane.pane.data("parentLayout");
+ parentPane.child = layout.children[ parentPane.name ] = null;
+ }
+ */
+
+ return Instance; // for coding convenience
+ }
+
+ /**
+ * Remove a pane from the layout - subroutine of destroy()
+ *
+ * @see destroy()
+ * @param {string} pane The pane to process
+ * @param {boolean=} [remove=false] Remove the DOM element?
+ * @param {boolean=} [skipResize=false] Skip calling resizeAll()?
+ */
+, removePane = function (evt_or_pane, remove, skipResize, destroyChild) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane)
+ , $P = $Ps[pane]
+ , $C = $Cs[pane]
+ , $R = $Rs[pane]
+ , $T = $Ts[pane]
+ ;
+ //alert( '$P.length = '+ $P.length );
+ // NOTE: elements can still exist even after remove()
+ // so check for missing data(), which is cleared by removed()
+ if ($P && $.isEmptyObject( $P.data() )) $P = false;
+ if ($C && $.isEmptyObject( $C.data() )) $C = false;
+ if ($R && $.isEmptyObject( $R.data() )) $R = false;
+ if ($T && $.isEmptyObject( $T.data() )) $T = false;
+
+ if ($P) $P.stop(true, true);
+
+ // check for a child layout
+ var o = options[pane]
+ , s = state[pane]
+ , d = "layout"
+ , css = "layoutCSS"
+ , child = children[pane] || ($P ? $P.data(d) : 0) || ($C ? $C.data(d) : 0) || null
+ , destroy = destroyChild !== undefined ? destroyChild : o.destroyChildLayout
+ ;
+
+ // FIRST destroy the child-layout(s)
+ if (destroy && child && !child.destroyed) {
+ child.destroy(true); // tell child-layout to destroy ALL its child-layouts too
+ if (child.destroyed) // destroy was successful
+ child = null; // clear pointer for logic below
+ }
+
+ if ($P && remove && !child)
+ $P.remove();
+ else if ($P && $P[0]) {
+ // create list of ALL pane-classes that need to be removed
+ var root = o.paneClass // default="ui-layout-pane"
+ , pRoot = root +"-"+ pane // eg: "ui-layout-pane-west"
+ , _open = "-open"
+ , _sliding= "-sliding"
+ , _closed = "-closed"
+ , classes = [ root, root+_open, root+_closed, root+_sliding, // generic classes
+ pRoot, pRoot+_open, pRoot+_closed, pRoot+_sliding ] // pane-specific classes
+ ;
+ $.merge(classes, getHoverClasses($P, true)); // ADD hover-classes
+ // remove all Layout classes from pane-element
+ $P .removeClass( classes.join(" ") ) // remove ALL pane-classes
+ .removeData("parentLayout")
+ .removeData("layoutPane")
+ .removeData("layoutRole")
+ .removeData("layoutEdge")
+ .removeData("autoHidden") // in case set
+ .unbind("."+ sID) // remove ALL Layout events
+ // TODO: remove these extra unbind commands when jQuery is fixed
+ //.unbind("mouseenter"+ sID)
+ //.unbind("mouseleave"+ sID)
+ ;
+ // do NOT reset CSS if this pane/content is STILL the container of a nested layout!
+ // the nested layout will reset its 'container' CSS when/if it is destroyed
+ if ($C && $C.data(d)) {
+ // a content-div may not have a specific width, so give it one to contain the Layout
+ $C.width( $C.width() );
+ child.resizeAll(); // now resize the Layout
+ }
+ else if ($C)
+ $C.css( $C.data(css) ).removeData(css).removeData("layoutRole");
+ // remove pane AFTER content in case there was a nested layout
+ if (!$P.data(d))
+ $P.css( $P.data(css) ).removeData(css);
+ }
+
+ // REMOVE pane resizer and toggler elements
+ if ($T) $T.remove();
+ if ($R) $R.remove();
+
+ // CLEAR all pointers and state data
+ Instance[pane] = $Ps[pane] = $Cs[pane] = $Rs[pane] = $Ts[pane] = children[pane] = false;
+ s = { removed: true };
+
+ if (!skipResize)
+ resizeAll();
+ }
+
+
+/*
+ * ###########################
+ * ACTION METHODS
+ * ###########################
+ */
+
+, _hidePane = function (pane) {
+ var $P = $Ps[pane]
+ , o = options[pane]
+ , s = $P[0].style
+ ;
+ if (o.useOffscreenClose) {
+ if (!$P.data(_c.offscreenReset))
+ $P.data(_c.offscreenReset, { left: s.left, right: s.right });
+ $P.css( _c.offscreenCSS );
+ }
+ else
+ $P.hide().removeData(_c.offscreenReset);
+ }
+
+, _showPane = function (pane) {
+ var $P = $Ps[pane]
+ , o = options[pane]
+ , off = _c.offscreenCSS
+ , old = $P.data(_c.offscreenReset)
+ , s = $P[0].style
+ ;
+ $P .show() // ALWAYS show, just in case
+ .removeData(_c.offscreenReset);
+ if (o.useOffscreenClose && old) {
+ if (s.left == off.left)
+ s.left = old.left;
+ if (s.right == off.right)
+ s.right = old.right;
+ }
+ }
+
+
+ /**
+ * Completely 'hides' a pane, including its spacing - as if it does not exist
+ * The pane is not actually 'removed' from the source, so can use 'show' to un-hide it
+ *
+ * @param {string} pane The pane being hidden, ie: north, south, east, or west
+ * @param {boolean=} [noAnimation=false]
+ */
+, hide = function (evt_or_pane, noAnimation) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane)
+ , o = options[pane]
+ , s = state[pane]
+ , $P = $Ps[pane]
+ , $R = $Rs[pane]
+ ;
+ if (!$P || s.isHidden) return; // pane does not exist OR is already hidden
+
+ // onhide_start callback - will CANCEL hide if returns false
+ if (state.initialized && false === _runCallbacks("onhide_start", pane)) return;
+
+ s.isSliding = false; // just in case
+
+ // now hide the elements
+ if ($R) $R.hide(); // hide resizer-bar
+ if (!state.initialized || s.isClosed) {
+ s.isClosed = true; // to trigger open-animation on show()
+ s.isHidden = true;
+ s.isVisible = false;
+ if (!state.initialized)
+ _hidePane(pane); // no animation when loading page
+ sizeMidPanes(_c[pane].dir === "horz" ? "" : "center");
+ if (state.initialized || o.triggerEventsOnLoad)
+ _runCallbacks("onhide_end", pane);
+ }
+ else {
+ s.isHiding = true; // used by onclose
+ close(pane, false, noAnimation); // adjust all panes to fit
+ }
+ }
+
+ /**
+ * Show a hidden pane - show as 'closed' by default unless openPane = true
+ *
+ * @param {string} pane The pane being opened, ie: north, south, east, or west
+ * @param {boolean=} [openPane=false]
+ * @param {boolean=} [noAnimation=false]
+ * @param {boolean=} [noAlert=false]
+ */
+, show = function (evt_or_pane, openPane, noAnimation, noAlert) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane)
+ , o = options[pane]
+ , s = state[pane]
+ , $P = $Ps[pane]
+ , $R = $Rs[pane]
+ ;
+ if (!$P || !s.isHidden) return; // pane does not exist OR is not hidden
+
+ // onshow_start callback - will CANCEL show if returns false
+ if (false === _runCallbacks("onshow_start", pane)) return;
+
+ s.isSliding = false; // just in case
+ s.isShowing = true; // used by onopen/onclose
+ //s.isHidden = false; - will be set by open/close - if not cancelled
+
+ // now show the elements
+ //if ($R) $R.show(); - will be shown by open/close
+ if (openPane === false)
+ close(pane, true); // true = force
+ else
+ open(pane, false, noAnimation, noAlert); // adjust all panes to fit
+ }
+
+
+ /**
+ * Toggles a pane open/closed by calling either open or close
+ *
+ * @param {string} pane The pane being toggled, ie: north, south, east, or west
+ * @param {boolean=} [slide=false]
+ */
+, toggle = function (evt_or_pane, slide) {
+ if (!isInitialized()) return;
+ var evt = evtObj(evt_or_pane)
+ , pane = evtPane.call(this, evt_or_pane)
+ , s = state[pane]
+ ;
+ if (evt) // called from to $R.dblclick OR triggerPaneEvent
+ evt.stopImmediatePropagation();
+ if (s.isHidden)
+ show(pane); // will call 'open' after unhiding it
+ else if (s.isClosed)
+ open(pane, !!slide);
+ else
+ close(pane);
+ }
+
+
+ /**
+ * Utility method used during init or other auto-processes
+ *
+ * @param {string} pane The pane being closed
+ * @param {boolean=} [setHandles=false]
+ */
+, _closePane = function (pane, setHandles) {
+ var
+ $P = $Ps[pane]
+ , s = state[pane]
+ ;
+ _hidePane(pane);
+ s.isClosed = true;
+ s.isVisible = false;
+ // UNUSED: if (setHandles) setAsClosed(pane, true); // true = force
+ }
+
+ /**
+ * Close the specified pane (animation optional), and resize all other panes as needed
+ *
+ * @param {string} pane The pane being closed, ie: north, south, east, or west
+ * @param {boolean=} [force=false]
+ * @param {boolean=} [noAnimation=false]
+ * @param {boolean=} [skipCallback=false]
+ */
+, close = function (evt_or_pane, force, noAnimation, skipCallback) {
+ var pane = evtPane.call(this, evt_or_pane);
+ // if pane has been initialized, but NOT the complete layout, close pane instantly
+ if (!state.initialized && $Ps[pane]) {
+ _closePane(pane); // INIT pane as closed
+ return;
+ }
+ if (!isInitialized()) return;
+
+ var
+ $P = $Ps[pane]
+ , $R = $Rs[pane]
+ , $T = $Ts[pane]
+ , o = options[pane]
+ , s = state[pane]
+ , c = _c[pane]
+ , doFX, isShowing, isHiding, wasSliding;
+
+ // QUEUE in case another action/animation is in progress
+ $N.queue(function( queueNext ){
+
+ if ( !$P
+ || (!o.closable && !s.isShowing && !s.isHiding) // invalid request // (!o.resizable && !o.closable) ???
+ || (!force && s.isClosed && !s.isShowing) // already closed
+ ) return queueNext();
+
+ // onclose_start callback - will CANCEL hide if returns false
+ // SKIP if just 'showing' a hidden pane as 'closed'
+ var abort = !s.isShowing && false === _runCallbacks("onclose_start", pane);
+
+ // transfer logic vars to temp vars
+ isShowing = s.isShowing;
+ isHiding = s.isHiding;
+ wasSliding = s.isSliding;
+ // now clear the logic vars (REQUIRED before aborting)
+ delete s.isShowing;
+ delete s.isHiding;
+
+ if (abort) return queueNext();
+
+ doFX = !noAnimation && !s.isClosed && (o.fxName_close != "none");
+ s.isMoving = true;
+ s.isClosed = true;
+ s.isVisible = false;
+ // update isHidden BEFORE sizing panes
+ if (isHiding) s.isHidden = true;
+ else if (isShowing) s.isHidden = false;
+
+ if (s.isSliding) // pane is being closed, so UNBIND trigger events
+ bindStopSlidingEvents(pane, false); // will set isSliding=false
+ else // resize panes adjacent to this one
+ sizeMidPanes(_c[pane].dir === "horz" ? "" : "center", false); // false = NOT skipCallback
+
+ // if this pane has a resizer bar, move it NOW - before animation
+ setAsClosed(pane);
+
+ // CLOSE THE PANE
+ if (doFX) { // animate the close
+ // mask panes with objects
+ var masks = "center"+ (c.dir=="horz" ? ",west,east" : "");
+ showMasks( masks, true ); // true = ONLY mask panes with maskObjects=true
+ lockPaneForFX(pane, true); // need to set left/top so animation will work
+ $P.hide( o.fxName_close, o.fxSettings_close, o.fxSpeed_close, function () {
+ lockPaneForFX(pane, false); // undo
+ if (s.isClosed) close_2();
+ queueNext();
+ });
+ }
+ else { // hide the pane without animation
+ _hidePane(pane);
+ close_2();
+ queueNext();
+ };
+ });
+
+ // SUBROUTINE
+ function close_2 () {
+ s.isMoving = false;
+ bindStartSlidingEvent(pane, true); // will enable if o.slidable = true
+
+ // if opposite-pane was autoClosed, see if it can be autoOpened now
+ var altPane = _c.oppositeEdge[pane];
+ if (state[ altPane ].noRoom) {
+ setSizeLimits( altPane );
+ makePaneFit( altPane );
+ }
+
+ // hide any masks shown while closing
+ hideMasks();
+
+ if (!skipCallback && (state.initialized || o.triggerEventsOnLoad)) {
+ // onclose callback - UNLESS just 'showing' a hidden pane as 'closed'
+ if (!isShowing) _runCallbacks("onclose_end", pane);
+ // onhide OR onshow callback
+ if (isShowing) _runCallbacks("onshow_end", pane);
+ if (isHiding) _runCallbacks("onhide_end", pane);
+ }
+ }
+ }
+
+ /**
+ * @param {string} pane The pane just closed, ie: north, south, east, or west
+ */
+, setAsClosed = function (pane) {
+ var
+ $P = $Ps[pane]
+ , $R = $Rs[pane]
+ , $T = $Ts[pane]
+ , o = options[pane]
+ , s = state[pane]
+ , side = _c[pane].side.toLowerCase()
+ , inset = "inset"+ _c[pane].side
+ , rClass = o.resizerClass
+ , tClass = o.togglerClass
+ , _pane = "-"+ pane // used for classNames
+ , _open = "-open"
+ , _sliding= "-sliding"
+ , _closed = "-closed"
+ ;
+ $R
+ .css(side, sC[inset]) // move the resizer
+ .removeClass( rClass+_open +" "+ rClass+_pane+_open )
+ .removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding )
+ .addClass( rClass+_closed +" "+ rClass+_pane+_closed )
+ .unbind("dblclick."+ sID)
+ ;
+ // DISABLE 'resizing' when closed - do this BEFORE bindStartSlidingEvent?
+ if (o.resizable && $.layout.plugins.draggable)
+ $R
+ .draggable("disable")
+ .removeClass("ui-state-disabled") // do NOT apply disabled styling - not suitable here
+ .css("cursor", "default")
+ .attr("title","")
+ ;
+
+ // if pane has a toggler button, adjust that too
+ if ($T) {
+ $T
+ .removeClass( tClass+_open +" "+ tClass+_pane+_open )
+ .addClass( tClass+_closed +" "+ tClass+_pane+_closed )
+ .attr("title", o.togglerTip_closed) // may be blank
+ ;
+ // toggler-content - if exists
+ $T.children(".content-open").hide();
+ $T.children(".content-closed").css("display","block");
+ }
+
+ // sync any 'pin buttons'
+ syncPinBtns(pane, false);
+
+ if (state.initialized) {
+ // resize 'length' and position togglers for adjacent panes
+ sizeHandles();
+ }
+ }
+
+ /**
+ * Open the specified pane (animation optional), and resize all other panes as needed
+ *
+ * @param {string} pane The pane being opened, ie: north, south, east, or west
+ * @param {boolean=} [slide=false]
+ * @param {boolean=} [noAnimation=false]
+ * @param {boolean=} [noAlert=false]
+ */
+, open = function (evt_or_pane, slide, noAnimation, noAlert) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane)
+ , $P = $Ps[pane]
+ , $R = $Rs[pane]
+ , $T = $Ts[pane]
+ , o = options[pane]
+ , s = state[pane]
+ , c = _c[pane]
+ , doFX, isShowing
+ ;
+ // QUEUE in case another action/animation is in progress
+ $N.queue(function( queueNext ){
+
+ if ( !$P
+ || (!o.resizable && !o.closable && !s.isShowing) // invalid request
+ || (s.isVisible && !s.isSliding) // already open
+ ) return queueNext();
+
+ // pane can ALSO be unhidden by just calling show(), so handle this scenario
+ if (s.isHidden && !s.isShowing) {
+ queueNext(); // call before show() because it needs the queue free
+ show(pane, true);
+ return;
+ }
+
+ if (o.autoResize && s.size != o.size) // resize pane to original size set in options
+ sizePane(pane, o.size, true, true, true); // true=skipCallback/forceResize/noAnimation
+ else
+ // make sure there is enough space available to open the pane
+ setSizeLimits(pane, slide);
+
+ // onopen_start callback - will CANCEL open if returns false
+ var cbReturn = _runCallbacks("onopen_start", pane);
+
+ if (cbReturn === "abort")
+ return queueNext();
+
+ // update pane-state again in case options were changed in onopen_start
+ if (cbReturn !== "NC") // NC = "No Callback"
+ setSizeLimits(pane, slide);
+
+ if (s.minSize > s.maxSize) { // INSUFFICIENT ROOM FOR PANE TO OPEN!
+ syncPinBtns(pane, false); // make sure pin-buttons are reset
+ if (!noAlert && o.noRoomToOpenTip)
+ alert(o.noRoomToOpenTip);
+ return queueNext(); // ABORT
+ }
+
+ if (slide) // START Sliding - will set isSliding=true
+ bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane
+ else if (s.isSliding) // PIN PANE (stop sliding) - open pane 'normally' instead
+ bindStopSlidingEvents(pane, false); // UNBIND trigger events - will set isSliding=false
+ else if (o.slidable)
+ bindStartSlidingEvent(pane, false); // UNBIND trigger events
+
+ s.noRoom = false; // will be reset by makePaneFit if 'noRoom'
+ makePaneFit(pane);
+
+ // transfer logic var to temp var
+ isShowing = s.isShowing;
+ // now clear the logic var
+ delete s.isShowing;
+
+ doFX = !noAnimation && s.isClosed && (o.fxName_open != "none");
+ s.isMoving = true;
+ s.isVisible = true;
+ s.isClosed = false;
+ // update isHidden BEFORE sizing panes - WHY??? Old?
+ if (isShowing) s.isHidden = false;
+
+ if (doFX) { // ANIMATE
+ // mask panes with objects
+ var masks = "center"+ (c.dir=="horz" ? ",west,east" : "");
+ if (s.isSliding) masks += ","+ _c.oppositeEdge[pane];
+ showMasks( masks, true ); // true = ONLY mask panes with maskObjects=true
+ lockPaneForFX(pane, true); // need to set left/top so animation will work
+ $P.show( o.fxName_open, o.fxSettings_open, o.fxSpeed_open, function() {
+ lockPaneForFX(pane, false); // undo
+ if (s.isVisible) open_2(); // continue
+ queueNext();
+ });
+ }
+ else { // no animation
+ _showPane(pane);// just show pane and...
+ open_2(); // continue
+ queueNext();
+ };
+ });
+
+ // SUBROUTINE
+ function open_2 () {
+ s.isMoving = false;
+
+ // cure iframe display issues
+ _fixIframe(pane);
+
+ // NOTE: if isSliding, then other panes are NOT 'resized'
+ if (!s.isSliding) { // resize all panes adjacent to this one
+ hideMasks(); // remove any masks shown while opening
+ sizeMidPanes(_c[pane].dir=="vert" ? "center" : "", false); // false = NOT skipCallback
+ }
+
+ // set classes, position handles and execute callbacks...
+ setAsOpen(pane);
+ };
+
+ }
+
+ /**
+ * @param {string} pane The pane just opened, ie: north, south, east, or west
+ * @param {boolean=} [skipCallback=false]
+ */
+, setAsOpen = function (pane, skipCallback) {
+ var
+ $P = $Ps[pane]
+ , $R = $Rs[pane]
+ , $T = $Ts[pane]
+ , o = options[pane]
+ , s = state[pane]
+ , side = _c[pane].side.toLowerCase()
+ , inset = "inset"+ _c[pane].side
+ , rClass = o.resizerClass
+ , tClass = o.togglerClass
+ , _pane = "-"+ pane // used for classNames
+ , _open = "-open"
+ , _closed = "-closed"
+ , _sliding= "-sliding"
+ ;
+ $R
+ .css(side, sC[inset] + getPaneSize(pane)) // move the resizer
+ .removeClass( rClass+_closed +" "+ rClass+_pane+_closed )
+ .addClass( rClass+_open +" "+ rClass+_pane+_open )
+ ;
+ if (s.isSliding)
+ $R.addClass( rClass+_sliding +" "+ rClass+_pane+_sliding )
+ else // in case 'was sliding'
+ $R.removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding )
+
+ if (o.resizerDblClickToggle)
+ $R.bind("dblclick", toggle );
+ removeHover( 0, $R ); // remove hover classes
+ if (o.resizable && $.layout.plugins.draggable)
+ $R .draggable("enable")
+ .css("cursor", o.resizerCursor)
+ .attr("title", o.resizerTip);
+ else if (!s.isSliding)
+ $R.css("cursor", "default"); // n-resize, s-resize, etc
+
+ // if pane also has a toggler button, adjust that too
+ if ($T) {
+ $T .removeClass( tClass+_closed +" "+ tClass+_pane+_closed )
+ .addClass( tClass+_open +" "+ tClass+_pane+_open )
+ .attr("title", o.togglerTip_open); // may be blank
+ removeHover( 0, $T ); // remove hover classes
+ // toggler-content - if exists
+ $T.children(".content-closed").hide();
+ $T.children(".content-open").css("display","block");
+ }
+
+ // sync any 'pin buttons'
+ syncPinBtns(pane, !s.isSliding);
+
+ // update pane-state dimensions - BEFORE resizing content
+ $.extend(s, elDims($P));
+
+ if (state.initialized) {
+ // resize resizer & toggler sizes for all panes
+ sizeHandles();
+ // resize content every time pane opens - to be sure
+ sizeContent(pane, true); // true = remeasure headers/footers, even if 'pane.isMoving'
+ }
+
+ if (!skipCallback && (state.initialized || o.triggerEventsOnLoad) && $P.is(":visible")) {
+ // onopen callback
+ _runCallbacks("onopen_end", pane);
+ // onshow callback - TODO: should this be here?
+ if (s.isShowing) _runCallbacks("onshow_end", pane);
+
+ // ALSO call onresize because layout-size *may* have changed while pane was closed
+ if (state.initialized)
+ _runCallbacks("onresize_end", pane);
+ }
+
+ // TODO: Somehow sizePane("north") is being called after this point???
+ }
+
+
+ /**
+ * slideOpen / slideClose / slideToggle
+ *
+ * Pass-though methods for sliding
+ */
+, slideOpen = function (evt_or_pane) {
+ if (!isInitialized()) return;
+ var evt = evtObj(evt_or_pane)
+ , pane = evtPane.call(this, evt_or_pane)
+ , s = state[pane]
+ , delay = options[pane].slideDelay_open
+ ;
+ // prevent event from triggering on NEW resizer binding created below
+ if (evt) evt.stopImmediatePropagation();
+
+ if (s.isClosed && evt && evt.type === "mouseenter" && delay > 0)
+ // trigger = mouseenter - use a delay
+ timer.set(pane+"_openSlider", open_NOW, delay);
+ else
+ open_NOW(); // will unbind events if is already open
+
+ /**
+ * SUBROUTINE for timed open
+ */
+ function open_NOW () {
+ if (!s.isClosed) // skip if no longer closed!
+ bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane
+ else if (!s.isMoving)
+ open(pane, true); // true = slide - open() will handle binding
+ };
+ }
+
+, slideClose = function (evt_or_pane) {
+ if (!isInitialized()) return;
+ var evt = evtObj(evt_or_pane)
+ , pane = evtPane.call(this, evt_or_pane)
+ , o = options[pane]
+ , s = state[pane]
+ , delay = s.isMoving ? 1000 : 300 // MINIMUM delay - option may override
+ ;
+ if (s.isClosed || s.isResizing)
+ return; // skip if already closed OR in process of resizing
+ else if (o.slideTrigger_close === "click")
+ close_NOW(); // close immediately onClick
+ else if (o.preventQuickSlideClose && s.isMoving)
+ return; // handle Chrome quick-close on slide-open
+ else if (o.preventPrematureSlideClose && evt && $.layout.isMouseOverElem(evt, $Ps[pane]))
+ return; // handle incorrect mouseleave trigger, like when over a SELECT-list in IE
+ else if (evt) // trigger = mouseleave - use a delay
+ // 1 sec delay if 'opening', else .3 sec
+ timer.set(pane+"_closeSlider", close_NOW, max(o.slideDelay_close, delay));
+ else // called programically
+ close_NOW();
+
+ /**
+ * SUBROUTINE for timed close
+ */
+ function close_NOW () {
+ if (s.isClosed) // skip 'close' if already closed!
+ bindStopSlidingEvents(pane, false); // UNBIND trigger events - TODO: is this needed here?
+ else if (!s.isMoving)
+ close(pane); // close will handle unbinding
+ };
+ }
+
+ /**
+ * @param {string} pane The pane being opened, ie: north, south, east, or west
+ */
+, slideToggle = function (evt_or_pane) {
+ var pane = evtPane.call(this, evt_or_pane);
+ toggle(pane, true);
+ }
+
+
+ /**
+ * Must set left/top on East/South panes so animation will work properly
+ *
+ * @param {string} pane The pane to lock, 'east' or 'south' - any other is ignored!
+ * @param {boolean} doLock true = set left/top, false = remove
+ */
+, lockPaneForFX = function (pane, doLock) {
+ var $P = $Ps[pane]
+ , s = state[pane]
+ , o = options[pane]
+ , z = options.zIndexes
+ ;
+ if (doLock) {
+ $P.css({ zIndex: z.pane_animate }); // overlay all elements during animation
+ if (pane=="south")
+ $P.css({ top: sC.insetTop + sC.innerHeight - $P.outerHeight() });
+ else if (pane=="east")
+ $P.css({ left: sC.insetLeft + sC.innerWidth - $P.outerWidth() });
+ }
+ else { // animation DONE - RESET CSS
+ // TODO: see if this can be deleted. It causes a quick-close when sliding in Chrome
+ $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) });
+ if (pane=="south")
+ $P.css({ top: "auto" });
+ // if pane is positioned 'off-screen', then DO NOT screw with it!
+ else if (pane=="east" && !$P.css("left").match(/\-99999/))
+ $P.css({ left: "auto" });
+ // fix anti-aliasing in IE - only needed for animations that change opacity
+ if (browser.msie && o.fxOpacityFix && o.fxName_open != "slide" && $P.css("filter") && $P.css("opacity") == 1)
+ $P[0].style.removeAttribute('filter');
+ }
+ }
+
+
+ /**
+ * Toggle sliding functionality of a specific pane on/off by adding removing 'slide open' trigger
+ *
+ * @see open(), close()
+ * @param {string} pane The pane to enable/disable, 'north', 'south', etc.
+ * @param {boolean} enable Enable or Disable sliding?
+ */
+, bindStartSlidingEvent = function (pane, enable) {
+ var o = options[pane]
+ , $P = $Ps[pane]
+ , $R = $Rs[pane]
+ , evtName = o.slideTrigger_open.toLowerCase()
+ ;
+ if (!$R || (enable && !o.slidable)) return;
+
+ // make sure we have a valid event
+ if (evtName.match(/mouseover/))
+ evtName = o.slideTrigger_open = "mouseenter";
+ else if (!evtName.match(/click|dblclick|mouseenter/))
+ evtName = o.slideTrigger_open = "click";
+
+ $R
+ // add or remove event
+ [enable ? "bind" : "unbind"](evtName +'.'+ sID, slideOpen)
+ // set the appropriate cursor & title/tip
+ .css("cursor", enable ? o.sliderCursor : "default")
+ .attr("title", enable ? o.sliderTip : "")
+ ;
+ }
+
+ /**
+ * Add or remove 'mouseleave' events to 'slide close' when pane is 'sliding' open or closed
+ * Also increases zIndex when pane is sliding open
+ * See bindStartSlidingEvent for code to control 'slide open'
+ *
+ * @see slideOpen(), slideClose()
+ * @param {string} pane The pane to process, 'north', 'south', etc.
+ * @param {boolean} enable Enable or Disable events?
+ */
+, bindStopSlidingEvents = function (pane, enable) {
+ var o = options[pane]
+ , s = state[pane]
+ , c = _c[pane]
+ , z = options.zIndexes
+ , evtName = o.slideTrigger_close.toLowerCase()
+ , action = (enable ? "bind" : "unbind")
+ , $P = $Ps[pane]
+ , $R = $Rs[pane]
+ ;
+ s.isSliding = enable; // logic
+ timer.clear(pane+"_closeSlider"); // just in case
+
+ // remove 'slideOpen' event from resizer
+ // ALSO will raise the zIndex of the pane & resizer
+ if (enable) bindStartSlidingEvent(pane, false);
+
+ // RE/SET zIndex - increases when pane is sliding-open, resets to normal when not
+ $P.css("zIndex", enable ? z.pane_sliding : z.pane_normal);
+ $R.css("zIndex", enable ? z.pane_sliding+2 : z.resizer_normal); // NOTE: mask = pane_sliding+1
+
+ // make sure we have a valid event
+ if (!evtName.match(/click|mouseleave/))
+ evtName = o.slideTrigger_close = "mouseleave"; // also catches 'mouseout'
+
+ // add/remove slide triggers
+ $R[action](evtName, slideClose); // base event on resize
+ // need extra events for mouseleave
+ if (evtName === "mouseleave") {
+ // also close on pane.mouseleave
+ $P[action]("mouseleave."+ sID, slideClose);
+ // cancel timer when mouse moves between 'pane' and 'resizer'
+ $R[action]("mouseenter."+ sID, cancelMouseOut);
+ $P[action]("mouseenter."+ sID, cancelMouseOut);
+ }
+
+ if (!enable)
+ timer.clear(pane+"_closeSlider");
+ else if (evtName === "click" && !o.resizable) {
+ // IF pane is not resizable (which already has a cursor and tip)
+ // then set the a cursor & title/tip on resizer when sliding
+ $R.css("cursor", enable ? o.sliderCursor : "default");
+ $R.attr("title", enable ? o.togglerTip_open : ""); // use Toggler-tip, eg: "Close Pane"
+ }
+
+ // SUBROUTINE for mouseleave timer clearing
+ function cancelMouseOut (evt) {
+ timer.clear(pane+"_closeSlider");
+ evt.stopPropagation();
+ }
+ }
+
+
+ /**
+ * Hides/closes a pane if there is insufficient room - reverses this when there is room again
+ * MUST have already called setSizeLimits() before calling this method
+ *
+ * @param {string} pane The pane being resized
+ * @param {boolean=} [isOpening=false] Called from onOpen?
+ * @param {boolean=} [skipCallback=false] Should the onresize callback be run?
+ * @param {boolean=} [force=false]
+ */
+, makePaneFit = function (pane, isOpening, skipCallback, force) {
+ var
+ o = options[pane]
+ , s = state[pane]
+ , c = _c[pane]
+ , $P = $Ps[pane]
+ , $R = $Rs[pane]
+ , isSidePane = c.dir==="vert"
+ , hasRoom = false
+ ;
+ // special handling for center & east/west panes
+ if (pane === "center" || (isSidePane && s.noVerticalRoom)) {
+ // see if there is enough room to display the pane
+ // ERROR: hasRoom = s.minHeight <= s.maxHeight && (isSidePane || s.minWidth <= s.maxWidth);
+ hasRoom = (s.maxHeight >= 0);
+ if (hasRoom && s.noRoom) { // previously hidden due to noRoom, so show now
+ _showPane(pane);
+ if ($R) $R.show();
+ s.isVisible = true;
+ s.noRoom = false;
+ if (isSidePane) s.noVerticalRoom = false;
+ _fixIframe(pane);
+ }
+ else if (!hasRoom && !s.noRoom) { // not currently hidden, so hide now
+ _hidePane(pane);
+ if ($R) $R.hide();
+ s.isVisible = false;
+ s.noRoom = true;
+ }
+ }
+
+ // see if there is enough room to fit the border-pane
+ if (pane === "center") {
+ // ignore center in this block
+ }
+ else if (s.minSize <= s.maxSize) { // pane CAN fit
+ hasRoom = true;
+ if (s.size > s.maxSize) // pane is too big - shrink it
+ sizePane(pane, s.maxSize, skipCallback, force, true); // true = noAnimation
+ else if (s.size < s.minSize) // pane is too small - enlarge it
+ sizePane(pane, s.minSize, skipCallback, force, true);
+ // need s.isVisible because new pseudoClose method keeps pane visible, but off-screen
+ else if ($R && s.isVisible && $P.is(":visible")) {
+ // make sure resizer-bar is positioned correctly
+ // handles situation where nested layout was 'hidden' when initialized
+ var side = c.side.toLowerCase()
+ , pos = s.size + sC["inset"+ c.side]
+ ;
+ if ($.layout.cssNum($R, side) != pos) $R.css( side, pos );
+ }
+
+ // if was previously hidden due to noRoom, then RESET because NOW there is room
+ if (s.noRoom) {
+ // s.noRoom state will be set by open or show
+ if (s.wasOpen && o.closable) {
+ if (o.autoReopen)
+ open(pane, false, true, true); // true = noAnimation, true = noAlert
+ else // leave the pane closed, so just update state
+ s.noRoom = false;
+ }
+ else
+ show(pane, s.wasOpen, true, true); // true = noAnimation, true = noAlert
+ }
+ }
+ else { // !hasRoom - pane CANNOT fit
+ if (!s.noRoom) { // pane not set as noRoom yet, so hide or close it now...
+ s.noRoom = true; // update state
+ s.wasOpen = !s.isClosed && !s.isSliding;
+ if (s.isClosed){} // SKIP
+ else if (o.closable) // 'close' if possible
+ close(pane, true, true); // true = force, true = noAnimation
+ else // 'hide' pane if cannot just be closed
+ hide(pane, true); // true = noAnimation
+ }
+ }
+ }
+
+
+ /**
+ * sizePane / manualSizePane
+ * sizePane is called only by internal methods whenever a pane needs to be resized
+ * manualSizePane is an exposed flow-through method allowing extra code when pane is 'manually resized'
+ *
+ * @param {string} pane The pane being resized
+ * @param {number} size The *desired* new size for this pane - will be validated
+ * @param {boolean=} [skipCallback=false] Should the onresize callback be run?
+ * @param {boolean=} [noAnimation=false]
+ */
+, manualSizePane = function (evt_or_pane, size, skipCallback, noAnimation) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane)
+ , o = options[pane]
+ , s = state[pane]
+ // if resizing callbacks have been delayed and resizing is now DONE, force resizing to complete...
+ , forceResize = o.livePaneResizing && !s.isResizing
+ ;
+ // ANY call to manualSizePane disables autoResize - ie, percentage sizing
+ o.autoResize = false;
+ // flow-through...
+ sizePane(pane, size, skipCallback, forceResize, noAnimation); // will animate resize if option enabled
+ }
+
+ /**
+ * @param {string} pane The pane being resized
+ * @param {number} size The *desired* new size for this pane - will be validated
+ * @param {boolean=} [skipCallback=false] Should the onresize callback be run?
+ * @param {boolean=} [force=false] Force resizing even if does not seem necessary
+ * @param {boolean=} [noAnimation=false]
+ */
+, sizePane = function (evt_or_pane, size, skipCallback, force, noAnimation) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane) // probably NEVER called from event?
+ , o = options[pane]
+ , s = state[pane]
+ , $P = $Ps[pane]
+ , $R = $Rs[pane]
+ , side = _c[pane].side.toLowerCase()
+ , dimName = _c[pane].sizeType.toLowerCase()
+ , inset = "inset"+ _c[pane].side
+ , skipResizeWhileDragging = s.isResizing && !o.triggerEventsDuringLiveResize
+ , doFX = noAnimation !== true && o.animatePaneSizing
+ , oldSize, newSize
+ ;
+ // QUEUE in case another action/animation is in progress
+ $N.queue(function( queueNext ){
+ // calculate 'current' min/max sizes
+ setSizeLimits(pane); // update pane-state
+ oldSize = s.size;
+ size = _parseSize(pane, size); // handle percentages & auto
+ size = max(size, _parseSize(pane, o.minSize));
+ size = min(size, s.maxSize);
+ if (size < s.minSize) { // not enough room for pane!
+ queueNext(); // call before makePaneFit() because it needs the queue free
+ makePaneFit(pane, false, skipCallback); // will hide or close pane
+ return;
+ }
+
+ // IF newSize is same as oldSize, then nothing to do - abort
+ if (!force && size === oldSize)
+ return queueNext();
+
+ // onresize_start callback CANNOT cancel resizing because this would break the layout!
+ if (!skipCallback && state.initialized && s.isVisible)
+ _runCallbacks("onresize_start", pane);
+
+ // resize the pane, and make sure its visible
+ newSize = cssSize(pane, size);
+
+ if (doFX && $P.is(":visible")) { // ANIMATE
+ var fx = $.layout.effects.size[pane] || $.layout.effects.size.all
+ , easing = o.fxSettings_size.easing || fx.easing
+ , z = options.zIndexes
+ , props = {};
+ props[ dimName ] = newSize +'px';
+ s.isMoving = true;
+ // overlay all elements during animation
+ $P.css({ zIndex: z.pane_animate })
+ .show().animate( props, o.fxSpeed_size, easing, function(){
+ // reset zIndex after animation
+ $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) });
+ s.isMoving = false;
+ sizePane_2(); // continue
+ queueNext();
+ });
+ }
+ else { // no animation
+ $P.css( dimName, newSize ); // resize pane
+ // if pane is visible, then
+ if ($P.is(":visible"))
+ sizePane_2(); // continue
+ else {
+ // pane is NOT VISIBLE, so just update state data...
+ // when pane is *next opened*, it will have the new size
+ s.size = size; // update state.size
+ $.extend(s, elDims($P)); // update state dimensions
+ }
+ queueNext();
+ };
+
+ });
+
+ // SUBROUTINE
+ function sizePane_2 () {
+ /* Panes are sometimes not sized precisely in some browsers!?
+ * This code will resize the pane up to 3 times to nudge the pane to the correct size
+ */
+ var actual = dimName==='width' ? $P.outerWidth() : $P.outerHeight()
+ , tries = [{
+ pane: pane
+ , count: 1
+ , target: size
+ , actual: actual
+ , correct: (size === actual)
+ , attempt: size
+ , cssSize: newSize
+ }]
+ , lastTry = tries[0]
+ , msg = 'Inaccurate size after resizing the '+ pane +'-pane.'
+ ;
+ while ( !lastTry.correct ) {
+ thisTry = { pane: pane, count: lastTry.count+1, target: size };
+
+ if (lastTry.actual > size)
+ thisTry.attempt = max(0, lastTry.attempt - (lastTry.actual - size));
+ else // lastTry.actual < size
+ thisTry.attempt = max(0, lastTry.attempt + (size - lastTry.actual));
+
+ thisTry.cssSize = cssSize(pane, thisTry.attempt);
+ $P.css( dimName, thisTry.cssSize );
+
+ thisTry.actual = dimName=='width' ? $P.outerWidth() : $P.outerHeight();
+ thisTry.correct = (size === thisTry.actual);
+
+ // if showDebugMessages, log attempts and alert the user of this *non-fatal error*
+ if (options.showDebugMessages) {
+ if ( tries.length === 1) {
+ _log(msg, false);
+ _log(lastTry, false);
+ }
+ _log(thisTry, false);
+ }
+
+ // after 4 tries, is as close as its gonna get!
+ if (tries.length > 3) break;
+
+ tries.push( thisTry );
+ lastTry = tries[ tries.length - 1 ];
+ }
+ // END TESTING CODE
+
+ // update pane-state dimensions
+ s.size = size;
+ $.extend(s, elDims($P));
+
+ if (s.isVisible && $P.is(":visible")) {
+ // reposition the resizer-bar
+ if ($R) $R.css( side, size + sC[inset] );
+ // resize the content-div
+ sizeContent(pane);
+ }
+
+ if (!skipCallback && !skipResizeWhileDragging && state.initialized && s.isVisible)
+ _runCallbacks("onresize_end", pane);
+
+ // resize all the adjacent panes, and adjust their toggler buttons
+ // when skipCallback passed, it means the controlling method will handle 'other panes'
+ if (!skipCallback) {
+ // also no callback if live-resize is in progress and NOT triggerEventsDuringLiveResize
+ if (!s.isSliding) sizeMidPanes(_c[pane].dir=="horz" ? "" : "center", skipResizeWhileDragging, force);
+ sizeHandles();
+ }
+
+ // if opposite-pane was autoClosed, see if it can be autoOpened now
+ var altPane = _c.oppositeEdge[pane];
+ if (size < oldSize && state[ altPane ].noRoom) {
+ setSizeLimits( altPane );
+ makePaneFit( altPane, false, skipCallback );
+ }
+
+ // DEBUG - ALERT user/developer so they know there was a sizing problem
+ if (options.showDebugMessages && tries.length > 1)
+ _log(msg +'\nSee the Error Console for details.', true);
+ }
+ }
+
+ /**
+ * @see initPanes(), sizePane(), resizeAll(), open(), close(), hide()
+ * @param {string} panes The pane(s) being resized, comma-delmited string
+ * @param {boolean=} [skipCallback=false] Should the onresize callback be run?
+ * @param {boolean=} [force=false]
+ */
+, sizeMidPanes = function (panes, skipCallback, force) {
+ panes = (panes ? panes : "east,west,center").split(",");
+
+ $.each(panes, function (i, pane) {
+ if (!$Ps[pane]) return; // NO PANE - skip
+ var
+ o = options[pane]
+ , s = state[pane]
+ , $P = $Ps[pane]
+ , $R = $Rs[pane]
+ , isCenter= (pane=="center")
+ , hasRoom = true
+ , CSS = {}
+ , newCenter = calcNewCenterPaneDims()
+ ;
+ // update pane-state dimensions
+ $.extend(s, elDims($P));
+
+ if (pane === "center") {
+ if (!force && s.isVisible && newCenter.width === s.outerWidth && newCenter.height === s.outerHeight)
+ return true; // SKIP - pane already the correct size
+ // set state for makePaneFit() logic
+ $.extend(s, cssMinDims(pane), {
+ maxWidth: newCenter.width
+ , maxHeight: newCenter.height
+ });
+ CSS = newCenter;
+ // convert OUTER width/height to CSS width/height
+ CSS.width = cssW($P, CSS.width);
+ // NEW - allow pane to extend 'below' visible area rather than hide it
+ CSS.height = cssH($P, CSS.height);
+ hasRoom = CSS.width >= 0 && CSS.height >= 0; // height >= 0 = ALWAYS TRUE NOW
+ // during layout init, try to shrink east/west panes to make room for center
+ if (!state.initialized && o.minWidth > s.outerWidth) {
+ var
+ reqPx = o.minWidth - s.outerWidth
+ , minE = options.east.minSize || 0
+ , minW = options.west.minSize || 0
+ , sizeE = state.east.size
+ , sizeW = state.west.size
+ , newE = sizeE
+ , newW = sizeW
+ ;
+ if (reqPx > 0 && state.east.isVisible && sizeE > minE) {
+ newE = max( sizeE-minE, sizeE-reqPx );
+ reqPx -= sizeE-newE;
+ }
+ if (reqPx > 0 && state.west.isVisible && sizeW > minW) {
+ newW = max( sizeW-minW, sizeW-reqPx );
+ reqPx -= sizeW-newW;
+ }
+ // IF we found enough extra space, then resize the border panes as calculated
+ if (reqPx === 0) {
+ if (sizeE != minE)
+ sizePane('east', newE, true, force, true); // true = skipCallback/noAnimation - initPanes will handle when done
+ if (sizeW != minW)
+ sizePane('west', newW, true, force, true);
+ // now start over!
+ sizeMidPanes('center', skipCallback, force);
+ return; // abort this loop
+ }
+ }
+ }
+ else { // for east and west, set only the height, which is same as center height
+ // set state.min/maxWidth/Height for makePaneFit() logic
+ if (s.isVisible && !s.noVerticalRoom)
+ $.extend(s, elDims($P), cssMinDims(pane))
+ if (!force && !s.noVerticalRoom && newCenter.height === s.outerHeight)
+ return true; // SKIP - pane already the correct size
+ // east/west have same top, bottom & height as center
+ CSS.top = newCenter.top;
+ CSS.bottom = newCenter.bottom;
+ // NEW - allow pane to extend 'below' visible area rather than hide it
+ CSS.height = cssH($P, newCenter.height);
+ s.maxHeight = CSS.height;
+ hasRoom = (s.maxHeight >= 0); // ALWAYS TRUE NOW
+ if (!hasRoom) s.noVerticalRoom = true; // makePaneFit() logic
+ }
+
+ if (hasRoom) {
+ // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized
+ if (!skipCallback && state.initialized)
+ _runCallbacks("onresize_start", pane);
+
+ $P.css(CSS); // apply the CSS to pane
+ sizeHandles(pane); // also update resizer length
+ if (s.noRoom && !s.isClosed && !s.isHidden)
+ makePaneFit(pane); // will re-open/show auto-closed/hidden pane
+ if (s.isVisible) {
+ $.extend(s, elDims($P)); // update pane dimensions
+ if (state.initialized) sizeContent(pane); // also resize the contents, if exists
+ }
+ }
+ else if (!s.noRoom && s.isVisible) // no room for pane
+ makePaneFit(pane); // will hide or close pane
+
+ if (!s.isVisible)
+ return true; // DONE - next pane
+
+ /*
+ * Extra CSS for IE6 or IE7 in Quirks-mode - add 'width' to NORTH/SOUTH panes
+ * Normally these panes have only 'left' & 'right' positions so pane auto-sizes
+ * ALSO required when pane is an IFRAME because will NOT default to 'full width'
+ */
+ if (pane === "center") { // finished processing midPanes
+ var b = $.layout.browser;
+ var fix = b.isIE6 || (b.msie && !$.support.boxModel);
+ if ($Ps.north && (fix || state.north.tagName=="IFRAME"))
+ $Ps.north.css("width", cssW($Ps.north, sC.innerWidth));
+ if ($Ps.south && (fix || state.south.tagName=="IFRAME"))
+ $Ps.south.css("width", cssW($Ps.south, sC.innerWidth));
+ }
+
+ // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized
+ if (!skipCallback && state.initialized)
+ _runCallbacks("onresize_end", pane);
+ });
+ }
+
+
+ /**
+ * @see window.onresize(), callbacks or custom code
+ */
+, resizeAll = function () {
+ if (!state.initialized) {
+ _initLayoutElements();
+ return; // no need to resize since we just initialized!
+ }
+ var oldW = sC.innerWidth
+ , oldH = sC.innerHeight
+ ;
+ // cannot size layout when 'container' is hidden or collapsed
+ if (!$N.is(":visible:") ) return;
+ $.extend( state.container, elDims( $N ) ); // UPDATE container dimensions
+ if (!sC.outerHeight) return;
+
+ // onresizeall_start will CANCEL resizing if returns false
+ // state.container has already been set, so user can access this info for calcuations
+ if (false === _runCallbacks("onresizeall_start")) return false;
+
+ var // see if container is now 'smaller' than before
+ shrunkH = (sC.innerHeight < oldH)
+ , shrunkW = (sC.innerWidth < oldW)
+ , $P, o, s, dir
+ ;
+ // NOTE special order for sizing: S-N-E-W
+ $.each(["south","north","east","west"], function (i, pane) {
+ if (!$Ps[pane]) return; // no pane - SKIP
+ s = state[pane];
+ o = options[pane];
+ dir = _c[pane].dir;
+
+ if (o.autoResize && s.size != o.size) // resize pane to original size set in options
+ sizePane(pane, o.size, true, true, true); // true=skipCallback/forceResize/noAnimation
+ else {
+ setSizeLimits(pane);
+ makePaneFit(pane, false, true, true); // true=skipCallback/forceResize
+ }
+ });
+
+ sizeMidPanes("", true, true); // true=skipCallback, true=forceResize
+ sizeHandles(); // reposition the toggler elements
+
+ // trigger all individual pane callbacks AFTER layout has finished resizing
+ o = options; // reuse alias
+ $.each(_c.allPanes, function (i, pane) {
+ $P = $Ps[pane];
+ if (!$P) return; // SKIP
+ if (state[pane].isVisible) // undefined for non-existent panes
+ _runCallbacks("onresize_end", pane); // callback - if exists
+ });
+
+ _runCallbacks("onresizeall_end");
+ //_triggerLayoutEvent(pane, 'resizeall');
+ }
+
+ /**
+ * Whenever a pane resizes or opens that has a nested layout, trigger resizeAll
+ *
+ * @param {string} pane The pane just resized or opened
+ */
+, resizeChildLayout = function (evt_or_pane) {
+ var pane = evtPane.call(this, evt_or_pane);
+ if (!options[pane].resizeChildLayout) return;
+ var $P = $Ps[pane]
+ , $C = $Cs[pane]
+ , d = "layout"
+ , P = Instance[pane]
+ , L = children[pane]
+ ;
+ // user may have manually set EITHER instance pointer, so handle that
+ if (P.child && !L) {
+ // have to reverse the pointers!
+ var el = P.child.container;
+ L = children[pane] = (el ? el.data(d) : 0) || null; // set pointer _directly_ to layout instance
+ }
+
+ // if a layout-pointer exists, see if child has been destroyed
+ if (L && L.destroyed)
+ L = children[pane] = null; // clear child pointers
+ // no child layout pointer is set - see if there is a child layout NOW
+ if (!L) L = children[pane] = $P.data(d) || ($C ? $C.data(d) : 0) || null; // set/update child pointers
+
+ // ALWAYS refresh the pane.child alias
+ P.child = children[pane];
+
+ if (L) L.resizeAll();
+ }
+
+
+ /**
+ * IF pane has a content-div, then resize all elements inside pane to fit pane-height
+ *
+ * @param {string=} [panes=""] The pane(s) being resized
+ * @param {boolean=} [remeasure=false] Should the content (header/footer) be remeasured?
+ */
+, sizeContent = function (evt_or_panes, remeasure) {
+ if (!isInitialized()) return;
+
+ var panes = evtPane.call(this, evt_or_panes);
+ panes = panes ? panes.split(",") : _c.allPanes;
+
+ $.each(panes, function (idx, pane) {
+ var
+ $P = $Ps[pane]
+ , $C = $Cs[pane]
+ , o = options[pane]
+ , s = state[pane]
+ , m = s.content // m = measurements
+ ;
+ if (!$P || !$C || !$P.is(":visible")) return true; // NOT VISIBLE - skip
+
+ // if content-element was REMOVED, update OR remove the pointer
+ if (!$C.length) {
+ initContent(pane, false); // false = do NOT sizeContent() - already there!
+ if (!$C) return; // no replacement element found - pointer have been removed
+ }
+
+ // onsizecontent_start will CANCEL resizing if returns false
+ if (false === _runCallbacks("onsizecontent_start", pane)) return;
+
+ // skip re-measuring offsets if live-resizing
+ if ((!s.isMoving && !s.isResizing) || o.liveContentResizing || remeasure || m.top == undefined) {
+ _measure();
+ // if any footers are below pane-bottom, they may not measure correctly,
+ // so allow pane overflow and re-measure
+ if (m.hiddenFooters > 0 && $P.css("overflow") === "hidden") {
+ $P.css("overflow", "visible");
+ _measure(); // remeasure while overflowing
+ $P.css("overflow", "hidden");
+ }
+ }
+ // NOTE: spaceAbove/Below *includes* the pane paddingTop/Bottom, but not pane.borders
+ var newH = s.innerHeight - (m.spaceAbove - s.css.paddingTop) - (m.spaceBelow - s.css.paddingBottom);
+
+ if (!$C.is(":visible") || m.height != newH) {
+ // size the Content element to fit new pane-size - will autoHide if not enough room
+ setOuterHeight($C, newH, true); // true=autoHide
+ m.height = newH; // save new height
+ };
+
+ if (state.initialized)
+ _runCallbacks("onsizecontent_end", pane);
+
+ function _below ($E) {
+ return max(s.css.paddingBottom, (parseInt($E.css("marginBottom"), 10) || 0));
+ };
+
+ function _measure () {
+ var
+ ignore = options[pane].contentIgnoreSelector
+ , $Fs = $C.nextAll().not(ignore || ':lt(0)') // not :lt(0) = ALL
+ , $Fs_vis = $Fs.filter(':visible')
+ , $F = $Fs_vis.filter(':last')
+ ;
+ m = {
+ top: $C[0].offsetTop
+ , height: $C.outerHeight()
+ , numFooters: $Fs.length
+ , hiddenFooters: $Fs.length - $Fs_vis.length
+ , spaceBelow: 0 // correct if no content footer ($E)
+ }
+ m.spaceAbove = m.top; // just for state - not used in calc
+ m.bottom = m.top + m.height;
+ if ($F.length)
+ //spaceBelow = (LastFooter.top + LastFooter.height) [footerBottom] - Content.bottom + max(LastFooter.marginBottom, pane.paddingBotom)
+ m.spaceBelow = ($F[0].offsetTop + $F.outerHeight()) - m.bottom + _below($F);
+ else // no footer - check marginBottom on Content element itself
+ m.spaceBelow = _below($C);
+ };
+ });
+ }
+
+
+ /**
+ * Called every time a pane is opened, closed, or resized to slide the togglers to 'center' and adjust their length if necessary
+ *
+ * @see initHandles(), open(), close(), resizeAll()
+ * @param {string=} [panes=""] The pane(s) being resized
+ */
+, sizeHandles = function (evt_or_panes) {
+ var panes = evtPane.call(this, evt_or_panes)
+ panes = panes ? panes.split(",") : _c.borderPanes;
+
+ $.each(panes, function (i, pane) {
+ var
+ o = options[pane]
+ , s = state[pane]
+ , $P = $Ps[pane]
+ , $R = $Rs[pane]
+ , $T = $Ts[pane]
+ , $TC
+ ;
+ if (!$P || !$R) return;
+
+ var
+ dir = _c[pane].dir
+ , _state = (s.isClosed ? "_closed" : "_open")
+ , spacing = o["spacing"+ _state]
+ , togAlign = o["togglerAlign"+ _state]
+ , togLen = o["togglerLength"+ _state]
+ , paneLen
+ , left
+ , offset
+ , CSS = {}
+ ;
+
+ if (spacing === 0) {
+ $R.hide();
+ return;
+ }
+ else if (!s.noRoom && !s.isHidden) // skip if resizer was hidden for any reason
+ $R.show(); // in case was previously hidden
+
+ // Resizer Bar is ALWAYS same width/height of pane it is attached to
+ if (dir === "horz") { // north/south
+ //paneLen = $P.outerWidth(); // s.outerWidth ||
+ paneLen = sC.innerWidth; // handle offscreen-panes
+ s.resizerLength = paneLen;
+ left = $.layout.cssNum($P, "left")
+ $R.css({
+ width: cssW($R, paneLen) // account for borders & padding
+ , height: cssH($R, spacing) // ditto
+ , left: left > -9999 ? left : sC.insetLeft // handle offscreen-panes
+ });
+ }
+ else { // east/west
+ paneLen = $P.outerHeight(); // s.outerHeight ||
+ s.resizerLength = paneLen;
+ $R.css({
+ height: cssH($R, paneLen) // account for borders & padding
+ , width: cssW($R, spacing) // ditto
+ , top: sC.insetTop + getPaneSize("north", true) // TODO: what if no North pane?
+ //, top: $.layout.cssNum($Ps["center"], "top")
+ });
+ }
+
+ // remove hover classes
+ removeHover( o, $R );
+
+ if ($T) {
+ if (togLen === 0 || (s.isSliding && o.hideTogglerOnSlide)) {
+ $T.hide(); // always HIDE the toggler when 'sliding'
+ return;
+ }
+ else
+ $T.show(); // in case was previously hidden
+
+ if (!(togLen > 0) || togLen === "100%" || togLen > paneLen) {
+ togLen = paneLen;
+ offset = 0;
+ }
+ else { // calculate 'offset' based on options.PANE.togglerAlign_open/closed
+ if (isStr(togAlign)) {
+ switch (togAlign) {
+ case "top":
+ case "left": offset = 0;
+ break;
+ case "bottom":
+ case "right": offset = paneLen - togLen;
+ break;
+ case "middle":
+ case "center":
+ default: offset = round((paneLen - togLen) / 2); // 'default' catches typos
+ }
+ }
+ else { // togAlign = number
+ var x = parseInt(togAlign, 10); //
+ if (togAlign >= 0) offset = x;
+ else offset = paneLen - togLen + x; // NOTE: x is negative!
+ }
+ }
+
+ if (dir === "horz") { // north/south
+ var width = cssW($T, togLen);
+ $T.css({
+ width: width // account for borders & padding
+ , height: cssH($T, spacing) // ditto
+ , left: offset // TODO: VERIFY that toggler positions correctly for ALL values
+ , top: 0
+ });
+ // CENTER the toggler content SPAN
+ $T.children(".content").each(function(){
+ $TC = $(this);
+ $TC.css("marginLeft", round((width-$TC.outerWidth())/2)); // could be negative
+ });
+ }
+ else { // east/west
+ var height = cssH($T, togLen);
+ $T.css({
+ height: height // account for borders & padding
+ , width: cssW($T, spacing) // ditto
+ , top: offset // POSITION the toggler
+ , left: 0
+ });
+ // CENTER the toggler content SPAN
+ $T.children(".content").each(function(){
+ $TC = $(this);
+ $TC.css("marginTop", round((height-$TC.outerHeight())/2)); // could be negative
+ });
+ }
+
+ // remove ALL hover classes
+ removeHover( 0, $T );
+ }
+
+ // DONE measuring and sizing this resizer/toggler, so can be 'hidden' now
+ if (!state.initialized && (o.initHidden || s.noRoom)) {
+ $R.hide();
+ if ($T) $T.hide();
+ }
+ });
+ }
+
+
+ /**
+ * @param {string} pane
+ */
+, enableClosable = function (evt_or_pane) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane)
+ , $T = $Ts[pane]
+ , o = options[pane]
+ ;
+ if (!$T) return;
+ o.closable = true;
+ $T .bind("click."+ sID, function(evt){ evt.stopPropagation(); toggle(pane); })
+ .css("visibility", "visible")
+ .css("cursor", "pointer")
+ .attr("title", state[pane].isClosed ? o.togglerTip_closed : o.togglerTip_open) // may be blank
+ .show();
+ }
+ /**
+ * @param {string} pane
+ * @param {boolean=} [hide=false]
+ */
+, disableClosable = function (evt_or_pane, hide) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane)
+ , $T = $Ts[pane]
+ ;
+ if (!$T) return;
+ options[pane].closable = false;
+ // is closable is disable, then pane MUST be open!
+ if (state[pane].isClosed) open(pane, false, true);
+ $T .unbind("."+ sID)
+ .css("visibility", hide ? "hidden" : "visible") // instead of hide(), which creates logic issues
+ .css("cursor", "default")
+ .attr("title", "");
+ }
+
+
+ /**
+ * @param {string} pane
+ */
+, enableSlidable = function (evt_or_pane) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane)
+ , $R = $Rs[pane]
+ ;
+ if (!$R || !$R.data('draggable')) return;
+ options[pane].slidable = true;
+ if (s.isClosed)
+ bindStartSlidingEvent(pane, true);
+ }
+ /**
+ * @param {string} pane
+ */
+, disableSlidable = function (evt_or_pane) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane)
+ , $R = $Rs[pane]
+ ;
+ if (!$R) return;
+ options[pane].slidable = false;
+ if (state[pane].isSliding)
+ close(pane, false, true);
+ else {
+ bindStartSlidingEvent(pane, false);
+ $R .css("cursor", "default")
+ .attr("title", "");
+ removeHover(null, $R[0]); // in case currently hovered
+ }
+ }
+
+
+ /**
+ * @param {string} pane
+ */
+, enableResizable = function (evt_or_pane) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane)
+ , $R = $Rs[pane]
+ , o = options[pane]
+ ;
+ if (!$R || !$R.data('draggable')) return;
+ o.resizable = true;
+ $R.draggable("enable");
+ if (!state[pane].isClosed)
+ $R .css("cursor", o.resizerCursor)
+ .attr("title", o.resizerTip);
+ }
+ /**
+ * @param {string} pane
+ */
+, disableResizable = function (evt_or_pane) {
+ if (!isInitialized()) return;
+ var pane = evtPane.call(this, evt_or_pane)
+ , $R = $Rs[pane]
+ ;
+ if (!$R || !$R.data('draggable')) return;
+ options[pane].resizable = false;
+ $R .draggable("disable")
+ .css("cursor", "default")
+ .attr("title", "");
+ removeHover(null, $R[0]); // in case currently hovered
+ }
+
+
+ /**
+ * Move a pane from source-side (eg, west) to target-side (eg, east)
+ * If pane exists on target-side, move that to source-side, ie, 'swap' the panes
+ *
+ * @param {string} pane1 The pane/edge being swapped
+ * @param {string} pane2 ditto
+ */
+, swapPanes = function (evt_or_pane1, pane2) {
+ if (!isInitialized()) return;
+ var pane1 = evtPane.call(this, evt_or_pane1);
+ // change state.edge NOW so callbacks can know where pane is headed...
+ state[pane1].edge = pane2;
+ state[pane2].edge = pane1;
+ // run these even if NOT state.initialized
+ if (false === _runCallbacks("onswap_start", pane1)
+ || false === _runCallbacks("onswap_start", pane2)
+ ) {
+ state[pane1].edge = pane1; // reset
+ state[pane2].edge = pane2;
+ return;
+ }
+
+ var
+ oPane1 = copy( pane1 )
+ , oPane2 = copy( pane2 )
+ , sizes = {}
+ ;
+ sizes[pane1] = oPane1 ? oPane1.state.size : 0;
+ sizes[pane2] = oPane2 ? oPane2.state.size : 0;
+
+ // clear pointers & state
+ $Ps[pane1] = false;
+ $Ps[pane2] = false;
+ state[pane1] = {};
+ state[pane2] = {};
+
+ // ALWAYS remove the resizer & toggler elements
+ if ($Ts[pane1]) $Ts[pane1].remove();
+ if ($Ts[pane2]) $Ts[pane2].remove();
+ if ($Rs[pane1]) $Rs[pane1].remove();
+ if ($Rs[pane2]) $Rs[pane2].remove();
+ $Rs[pane1] = $Rs[pane2] = $Ts[pane1] = $Ts[pane2] = false;
+
+ // transfer element pointers and data to NEW Layout keys
+ move( oPane1, pane2 );
+ move( oPane2, pane1 );
+
+ // cleanup objects
+ oPane1 = oPane2 = sizes = null;
+
+ // make panes 'visible' again
+ if ($Ps[pane1]) $Ps[pane1].css(_c.visible);
+ if ($Ps[pane2]) $Ps[pane2].css(_c.visible);
+
+ // fix any size discrepancies caused by swap
+ resizeAll();
+
+ // run these even if NOT state.initialized
+ _runCallbacks("onswap_end", pane1);
+ _runCallbacks("onswap_end", pane2);
+
+ return;
+
+ function copy (n) { // n = pane
+ var
+ $P = $Ps[n]
+ , $C = $Cs[n]
+ ;
+ return !$P ? false : {
+ pane: n
+ , P: $P ? $P[0] : false
+ , C: $C ? $C[0] : false
+ , state: $.extend(true, {}, state[n])
+ , options: $.extend(true, {}, options[n])
+ }
+ };
+
+ function move (oPane, pane) {
+ if (!oPane) return;
+ var
+ P = oPane.P
+ , C = oPane.C
+ , oldPane = oPane.pane
+ , c = _c[pane]
+ , side = c.side.toLowerCase()
+ , inset = "inset"+ c.side
+ // save pane-options that should be retained
+ , s = $.extend({}, state[pane])
+ , o = options[pane]
+ // RETAIN side-specific FX Settings - more below
+ , fx = { resizerCursor: o.resizerCursor }
+ , re, size, pos
+ ;
+ $.each("fxName,fxSpeed,fxSettings".split(","), function (i, k) {
+ fx[k +"_open"] = o[k +"_open"];
+ fx[k +"_close"] = o[k +"_close"];
+ fx[k +"_size"] = o[k +"_size"];
+ });
+
+ // update object pointers and attributes
+ $Ps[pane] = $(P)
+ .data({
+ layoutPane: Instance[pane] // NEW pointer to pane-alias-object
+ , layoutEdge: pane
+ })
+ .css(_c.hidden)
+ .css(c.cssReq)
+ ;
+ $Cs[pane] = C ? $(C) : false;
+
+ // set options and state
+ options[pane] = $.extend({}, oPane.options, fx);
+ state[pane] = $.extend({}, oPane.state);
+
+ // change classNames on the pane, eg: ui-layout-pane-east ==> ui-layout-pane-west
+ re = new RegExp(o.paneClass +"-"+ oldPane, "g");
+ P.className = P.className.replace(re, o.paneClass +"-"+ pane);
+
+ // ALWAYS regenerate the resizer & toggler elements
+ initHandles(pane); // create the required resizer & toggler
+
+ // if moving to different orientation, then keep 'target' pane size
+ if (c.dir != _c[oldPane].dir) {
+ size = sizes[pane] || 0;
+ setSizeLimits(pane); // update pane-state
+ size = max(size, state[pane].minSize);
+ // use manualSizePane to disable autoResize - not useful after panes are swapped
+ manualSizePane(pane, size, true, true); // true/true = skipCallback/noAnimation
+ }
+ else // move the resizer here
+ $Rs[pane].css(side, sC[inset] + (state[pane].isVisible ? getPaneSize(pane) : 0));
+
+
+ // ADD CLASSNAMES & SLIDE-BINDINGS
+ if (oPane.state.isVisible && !s.isVisible)
+ setAsOpen(pane, true); // true = skipCallback
+ else {
+ setAsClosed(pane);
+ bindStartSlidingEvent(pane, true); // will enable events IF option is set
+ }
+
+ // DESTROY the object
+ oPane = null;
+ };
+ }
+
+
+ /**
+ * INTERNAL method to sync pin-buttons when pane is opened or closed
+ * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes
+ *
+ * @see open(), setAsOpen(), setAsClosed()
+ * @param {string} pane These are the params returned to callbacks by layout()
+ * @param {boolean} doPin True means set the pin 'down', False means 'up'
+ */
+, syncPinBtns = function (pane, doPin) {
+ if ($.layout.plugins.buttons)
+ $.each(state[pane].pins, function (i, selector) {
+ $.layout.buttons.setPinState(Instance, $(selector), pane, doPin);
+ });
+ }
+
+; // END var DECLARATIONS
+
+ /**
+ * Capture keys when enableCursorHotkey - toggle pane if hotkey pressed
+ *
+ * @see document.keydown()
+ */
+ function keyDown (evt) {
+ if (!evt) return true;
+ var code = evt.keyCode;
+ if (code < 33) return true; // ignore special keys: ENTER, TAB, etc
+
+ var
+ PANE = {
+ 38: "north" // Up Cursor - $.ui.keyCode.UP
+ , 40: "south" // Down Cursor - $.ui.keyCode.DOWN
+ , 37: "west" // Left Cursor - $.ui.keyCode.LEFT
+ , 39: "east" // Right Cursor - $.ui.keyCode.RIGHT
+ }
+ , ALT = evt.altKey // no worky!
+ , SHIFT = evt.shiftKey
+ , CTRL = evt.ctrlKey
+ , CURSOR = (CTRL && code >= 37 && code <= 40)
+ , o, k, m, pane
+ ;
+
+ if (CURSOR && options[PANE[code]].enableCursorHotkey) // valid cursor-hotkey
+ pane = PANE[code];
+ else if (CTRL || SHIFT) // check to see if this matches a custom-hotkey
+ $.each(_c.borderPanes, function (i, p) { // loop each pane to check its hotkey
+ o = options[p];
+ k = o.customHotkey;
+ m = o.customHotkeyModifier; // if missing or invalid, treated as "CTRL+SHIFT"
+ if ((SHIFT && m=="SHIFT") || (CTRL && m=="CTRL") || (CTRL && SHIFT)) { // Modifier matches
+ if (k && code === (isNaN(k) || k <= 9 ? k.toUpperCase().charCodeAt(0) : k)) { // Key matches
+ pane = p;
+ return false; // BREAK
+ }
+ }
+ });
+
+ // validate pane
+ if (!pane || !$Ps[pane] || !options[pane].closable || state[pane].isHidden)
+ return true;
+
+ toggle(pane);
+
+ evt.stopPropagation();
+ evt.returnValue = false; // CANCEL key
+ return false;
+ };
+
+
+/*
+ * ######################################
+ * UTILITY METHODS
+ * called externally or by initButtons
+ * ######################################
+ */
+
+ /**
+ * Change/reset a pane overflow setting & zIndex to allow popups/drop-downs to work
+ *
+ * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event
+ */
+ function allowOverflow (el) {
+ if (!isInitialized()) return;
+ if (this && this.tagName) el = this; // BOUND to element
+ var $P;
+ if (isStr(el))
+ $P = $Ps[el];
+ else if ($(el).data("layoutRole"))
+ $P = $(el);
+ else
+ $(el).parents().each(function(){
+ if ($(this).data("layoutRole")) {
+ $P = $(this);
+ return false; // BREAK
+ }
+ });
+ if (!$P || !$P.length) return; // INVALID
+
+ var
+ pane = $P.data("layoutEdge")
+ , s = state[pane]
+ ;
+
+ // if pane is already raised, then reset it before doing it again!
+ // this would happen if allowOverflow is attached to BOTH the pane and an element
+ if (s.cssSaved)
+ resetOverflow(pane); // reset previous CSS before continuing
+
+ // if pane is raised by sliding or resizing, or its closed, then abort
+ if (s.isSliding || s.isResizing || s.isClosed) {
+ s.cssSaved = false;
+ return;
+ }
+
+ var
+ newCSS = { zIndex: (options.zIndexes.resizer_normal + 1) }
+ , curCSS = {}
+ , of = $P.css("overflow")
+ , ofX = $P.css("overflowX")
+ , ofY = $P.css("overflowY")
+ ;
+ // determine which, if any, overflow settings need to be changed
+ if (of != "visible") {
+ curCSS.overflow = of;
+ newCSS.overflow = "visible";
+ }
+ if (ofX && !ofX.match(/visible|auto/)) {
+ curCSS.overflowX = ofX;
+ newCSS.overflowX = "visible";
+ }
+ if (ofY && !ofY.match(/visible|auto/)) {
+ curCSS.overflowY = ofX;
+ newCSS.overflowY = "visible";
+ }
+
+ // save the current overflow settings - even if blank!
+ s.cssSaved = curCSS;
+
+ // apply new CSS to raise zIndex and, if necessary, make overflow 'visible'
+ $P.css( newCSS );
+
+ // make sure the zIndex of all other panes is normal
+ $.each(_c.allPanes, function(i, p) {
+ if (p != pane) resetOverflow(p);
+ });
+
+ };
+ /**
+ * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event
+ */
+ function resetOverflow (el) {
+ if (!isInitialized()) return;
+ if (this && this.tagName) el = this; // BOUND to element
+ var $P;
+ if (isStr(el))
+ $P = $Ps[el];
+ else if ($(el).data("layoutRole"))
+ $P = $(el);
+ else
+ $(el).parents().each(function(){
+ if ($(this).data("layoutRole")) {
+ $P = $(this);
+ return false; // BREAK
+ }
+ });
+ if (!$P || !$P.length) return; // INVALID
+
+ var
+ pane = $P.data("layoutEdge")
+ , s = state[pane]
+ , CSS = s.cssSaved || {}
+ ;
+ // reset the zIndex
+ if (!s.isSliding && !s.isResizing)
+ $P.css("zIndex", options.zIndexes.pane_normal);
+
+ // reset Overflow - if necessary
+ $P.css( CSS );
+
+ // clear var
+ s.cssSaved = false;
+ };
+
+/*
+ * #####################
+ * CREATE/RETURN LAYOUT
+ * #####################
+ */
+
+ // validate that container exists
+ var $N = $(this).eq(0); // FIRST matching Container element
+ if (!$N.length) {
+ if (options.showErrorMessages)
+ _log( lang.errContainerMissing, true );
+ return null;
+ };
+
+ // Users retrieve Instance of a layout with: $N.layout() OR $N.data("layout")
+ // return the Instance-pointer if layout has already been initialized
+ if ($N.data("layoutContainer") && $N.data("layout"))
+ return $N.data("layout"); // cached pointer
+
+ // init global vars
+ var
+ $Ps = {} // Panes x5 - set in initPanes()
+ , $Cs = {} // Content x5 - set in initPanes()
+ , $Rs = {} // Resizers x4 - set in initHandles()
+ , $Ts = {} // Togglers x4 - set in initHandles()
+ , $Ms = $([]) // Masks - up to 2 masks per pane (IFRAME + DIV)
+ // aliases for code brevity
+ , sC = state.container // alias for easy access to 'container dimensions'
+ , sID = state.id // alias for unique layout ID/namespace - eg: "layout435"
+ ;
+
+ // create Instance object to expose data & option Properties, and primary action Methods
+ var Instance = {
+ // layout data
+ options: options // property - options hash
+ , state: state // property - dimensions hash
+ // object pointers
+ , container: $N // property - object pointers for layout container
+ , panes: $Ps // property - object pointers for ALL Panes: panes.north, panes.center
+ , contents: $Cs // property - object pointers for ALL Content: contents.north, contents.center
+ , resizers: $Rs // property - object pointers for ALL Resizers, eg: resizers.north
+ , togglers: $Ts // property - object pointers for ALL Togglers, eg: togglers.north
+ // border-pane open/close
+ , hide: hide // method - ditto
+ , show: show // method - ditto
+ , toggle: toggle // method - pass a 'pane' ("north", "west", etc)
+ , open: open // method - ditto
+ , close: close // method - ditto
+ , slideOpen: slideOpen // method - ditto
+ , slideClose: slideClose // method - ditto
+ , slideToggle: slideToggle // method - ditto
+ // pane actions
+ , setSizeLimits: setSizeLimits // method - pass a 'pane' - update state min/max data
+ , _sizePane: sizePane // method -intended for user by plugins only!
+ , sizePane: manualSizePane // method - pass a 'pane' AND an 'outer-size' in pixels or percent, or 'auto'
+ , sizeContent: sizeContent // method - pass a 'pane'
+ , swapPanes: swapPanes // method - pass TWO 'panes' - will swap them
+ // pane element methods
+ , initContent: initContent // method - ditto
+ , addPane: addPane // method - pass a 'pane'
+ , removePane: removePane // method - pass a 'pane' to remove from layout, add 'true' to delete the pane-elem
+ , createChildLayout: createChildLayout// method - pass a 'pane' and (optional) layout-options (OVERRIDES options[pane].childOptions
+ // special pane option setting
+ , enableClosable: enableClosable // method - pass a 'pane'
+ , disableClosable: disableClosable // method - ditto
+ , enableSlidable: enableSlidable // method - ditto
+ , disableSlidable: disableSlidable // method - ditto
+ , enableResizable: enableResizable // method - ditto
+ , disableResizable: disableResizable// method - ditto
+ // utility methods for panes
+ , allowOverflow: allowOverflow // utility - pass calling element (this)
+ , resetOverflow: resetOverflow // utility - ditto
+ // layout control
+ , destroy: destroy // method - no parameters
+ , initPanes: isInitialized // method - no parameters
+ , resizeAll: resizeAll // method - no parameters
+ // callback triggering
+ , runCallbacks: _runCallbacks // method - pass evtName & pane (if a pane-event), eg: trigger("onopen", "west")
+ // alias collections of options, state and children - created in addPane and extended elsewhere
+ , hasParentLayout: false // set by initContainer()
+ , children: children // pointers to child-layouts, eg: Instance.children["west"]
+ , north: false // alias group: { name: pane, pane: $Ps[pane], options: options[pane], state: state[pane], child: children[pane] }
+ , south: false // ditto
+ , west: false // ditto
+ , east: false // ditto
+ , center: false // ditto
+ };
+
+ // create the border layout NOW
+ if (_create() === 'cancel') // onload_start callback returned false to CANCEL layout creation
+ return null;
+ else // true OR false -- if layout-elements did NOT init (hidden or do not exist), can auto-init later
+ return Instance; // return the Instance object
+
+}
+
+
+
+
+/**
+ * jquery.layout.state 1.0
+ * $Date$
+ *
+ * Copyright (c) 2010
+ * Kevin Dalman (http://allpro.net)
+ *
+ * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
+ * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
+ *
+ * @dependancies: UI Layout 1.3.0.rc30.1 or higher
+ * @dependancies: $.ui.cookie (above)
+ *
+ * @support: http://groups.google.com/group/jquery-ui-layout
+ */
+/*
+ * State-management options stored in options.stateManagement, which includes a .cookie hash
+ * Default options saves ALL KEYS for ALL PANES, ie: pane.size, pane.isClosed, pane.isHidden
+ *
+ * // STATE/COOKIE OPTIONS
+ * @example $(el).layout({
+ stateManagement: {
+ enabled: true
+ , stateKeys: "east.size,west.size,east.isClosed,west.isClosed"
+ , cookie: { name: "appLayout", path: "/" }
+ }
+ })
+ * @example $(el).layout({ stateManagement__enabled: true }) // enable auto-state-management using cookies
+ * @example $(el).layout({ stateManagement__cookie: { name: "appLayout", path: "/" } })
+ * @example $(el).layout({ stateManagement__cookie__name: "appLayout", stateManagement__cookie__path: "/" })
+ *
+ * // STATE/COOKIE METHODS
+ * @example myLayout.saveCookie( "west.isClosed,north.size,south.isHidden", {expires: 7} );
+ * @example myLayout.loadCookie();
+ * @example myLayout.deleteCookie();
+ * @example var JSON = myLayout.readState(); // CURRENT Layout State
+ * @example var JSON = myLayout.readCookie(); // SAVED Layout State (from cookie)
+ * @example var JSON = myLayout.state.stateData; // LAST LOADED Layout State (cookie saved in layout.state hash)
+ *
+ * CUSTOM STATE-MANAGEMENT (eg, saved in a database)
+ * @example var JSON = myLayout.readState( "west.isClosed,north.size,south.isHidden" );
+ * @example myLayout.loadState( JSON );
+ */
+
+/**
+ * UI COOKIE UTILITY
+ *
+ * A $.cookie OR $.ui.cookie namespace *should be standard*, but until then...
+ * This creates $.ui.cookie so Layout does not need the cookie.jquery.js plugin
+ * NOTE: This utility is REQUIRED by the layout.state plugin
+ *
+ * Cookie methods in Layout are created as part of State Management
+ */
+if (!$.ui) $.ui = {};
+$.ui.cookie = {
+
+ // cookieEnabled is not in DOM specs, but DOES works in all browsers,including IE6
+ acceptsCookies: !!navigator.cookieEnabled
+
+, read: function (name) {
+ var
+ c = document.cookie
+ , cs = c ? c.split(';') : []
+ , pair // loop var
+ ;
+ for (var i=0, n=cs.length; i < n; i++) {
+ pair = $.trim(cs[i]).split('='); // name=value pair
+ if (pair[0] == name) // found the layout cookie
+ return decodeURIComponent(pair[1]);
+
+ }
+ return null;
+ }
+
+, write: function (name, val, cookieOpts) {
+ var
+ params = ''
+ , date = ''
+ , clear = false
+ , o = cookieOpts || {}
+ , x = o.expires
+ ;
+ if (x && x.toUTCString)
+ date = x;
+ else if (x === null || typeof x === 'number') {
+ date = new Date();
+ if (x > 0)
+ date.setDate(date.getDate() + x);
+ else {
+ date.setFullYear(1970);
+ clear = true;
+ }
+ }
+ if (date) params += ';expires='+ date.toUTCString();
+ if (o.path) params += ';path='+ o.path;
+ if (o.domain) params += ';domain='+ o.domain;
+ if (o.secure) params += ';secure';
+ document.cookie = name +'='+ (clear ? "" : encodeURIComponent( val )) + params; // write or clear cookie
+ }
+
+, clear: function (name) {
+ $.ui.cookie.write(name, '', {expires: -1});
+ }
+
+};
+// if cookie.jquery.js is not loaded, create an alias to replicate it
+// this may be useful to other plugins or code dependent on that plugin
+if (!$.cookie) $.cookie = function (k, v, o) {
+ var C = $.ui.cookie;
+ if (v === null)
+ C.clear(k);
+ else if (v === undefined)
+ return C.read(k);
+ else
+ C.write(k, v, o);
+};
+
+
+// tell Layout that the state plugin is available
+$.layout.plugins.stateManagement = true;
+
+// Add State-Management options to layout.defaults
+$.layout.config.optionRootKeys.push("stateManagement");
+$.layout.defaults.stateManagement = {
+ enabled: false // true = enable state-management, even if not using cookies
+, autoSave: true // Save a state-cookie when page exits?
+, autoLoad: true // Load the state-cookie when Layout inits?
+ // List state-data to save - must be pane-specific
+, stateKeys: "north.size,south.size,east.size,west.size,"+
+ "north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+
+ "north.isHidden,south.isHidden,east.isHidden,west.isHidden"
+, cookie: {
+ name: "" // If not specified, will use Layout.name, else just "Layout"
+ , domain: "" // blank = current domain
+ , path: "" // blank = current page, '/' = entire website
+ , expires: "" // 'days' to keep cookie - leave blank for 'session cookie'
+ , secure: false
+ }
+};
+// Set stateManagement as a layout-option, NOT a pane-option
+$.layout.optionsMap.layout.push("stateManagement");
+
+/*
+ * State Management methods
+ */
+$.layout.state = {
+
+ /**
+ * Get the current layout state and save it to a cookie
+ *
+ * myLayout.saveCookie( keys, cookieOpts )
+ *
+ * @param {Object} inst
+ * @param {(string|Array)=} keys
+ * @param {Object=} opts
+ */
+ saveCookie: function (inst, keys, cookieOpts) {
+ var o = inst.options
+ , oS = o.stateManagement
+ , oC = $.extend(true, {}, oS.cookie, cookieOpts || null)
+ , data = inst.state.stateData = inst.readState( keys || oS.stateKeys ) // read current panes-state
+ ;
+ $.ui.cookie.write( oC.name || o.name || "Layout", $.layout.state.encodeJSON(data), oC );
+ return $.extend(true, {}, data); // return COPY of state.stateData data
+ }
+
+ /**
+ * Remove the state cookie
+ *
+ * @param {Object} inst
+ */
+, deleteCookie: function (inst) {
+ var o = inst.options;
+ $.ui.cookie.clear( o.stateManagement.cookie.name || o.name || "Layout" );
+ }
+
+ /**
+ * Read & return data from the cookie - as JSON
+ *
+ * @param {Object} inst
+ */
+, readCookie: function (inst) {
+ var o = inst.options;
+ var c = $.ui.cookie.read( o.stateManagement.cookie.name || o.name || "Layout" );
+ // convert cookie string back to a hash and return it
+ return c ? $.layout.state.decodeJSON(c) : {};
+ }
+
+ /**
+ * Get data from the cookie and USE IT to loadState
+ *
+ * @param {Object} inst
+ */
+, loadCookie: function (inst) {
+ var c = $.layout.state.readCookie(inst); // READ the cookie
+ if (c) {
+ inst.state.stateData = $.extend(true, {}, c); // SET state.stateData
+ inst.loadState(c); // LOAD the retrieved state
+ }
+ return c;
+ }
+
+ /**
+ * Update layout options from the cookie, if one exists
+ *
+ * @param {Object} inst
+ * @param {Object=} stateData
+ * @param {boolean=} animate
+ */
+, loadState: function (inst, stateData, animate) {
+ stateData = $.layout.transformData( stateData ); // panes = default subkey
+ if ($.isEmptyObject( stateData )) return;
+ $.extend(true, inst.options, stateData); // update layout options
+ // if layout has already been initialized, then UPDATE layout state
+ if (inst.state.initialized) {
+ var pane, vis, o, s, h, c
+ , noAnimate = (animate===false)
+ ;
+ $.each($.layout.config.borderPanes, function (idx, pane) {
+ state = inst.state[pane];
+ o = stateData[ pane ];
+ if (typeof o != 'object') return; // no key, continue
+ s = o.size;
+ c = o.initClosed;
+ h = o.initHidden;
+ vis = state.isVisible;
+ // resize BEFORE opening
+ if (!vis)
+ inst.sizePane(pane, s, false, false);
+ if (h === true) inst.hide(pane, noAnimate);
+ else if (c === false) inst.open (pane, false, noAnimate);
+ else if (c === true) inst.close(pane, false, noAnimate);
+ else if (h === false) inst.show (pane, false, noAnimate);
+ // resize AFTER any other actions
+ if (vis)
+ inst.sizePane(pane, s, false, noAnimate); // animate resize if option passed
+ });
+ };
+ }
+
+ /**
+ * Get the *current layout state* and return it as a hash
+ *
+ * @param {Object=} inst
+ * @param {(string|Array)=} keys
+ */
+, readState: function (inst, keys) {
+ var
+ data = {}
+ , alt = { isClosed: 'initClosed', isHidden: 'initHidden' }
+ , state = inst.state
+ , panes = $.layout.config.allPanes
+ , pair, pane, key, val
+ ;
+ if (!keys) keys = inst.options.stateManagement.stateKeys; // if called by user
+ if ($.isArray(keys)) keys = keys.join(",");
+ // convert keys to an array and change delimiters from '__' to '.'
+ keys = keys.replace(/__/g, ".").split(',');
+ // loop keys and create a data hash
+ for (var i=0, n=keys.length; i < n; i++) {
+ pair = keys[i].split(".");
+ pane = pair[0];
+ key = pair[1];
+ if ($.inArray(pane, panes) < 0) continue; // bad pane!
+ val = state[ pane ][ key ];
+ if (val == undefined) continue;
+ if (key=="isClosed" && state[pane]["isSliding"])
+ val = true; // if sliding, then *really* isClosed
+ ( data[pane] || (data[pane]={}) )[ alt[key] ? alt[key] : key ] = val;
+ }
+ return data;
+ }
+
+ /**
+ * Stringify a JSON hash so can save in a cookie or db-field
+ */
+, encodeJSON: function (JSON) {
+ return parse(JSON);
+ function parse (h) {
+ var D=[], i=0, k, v, t; // k = key, v = value
+ for (k in h) {
+ v = h[k];
+ t = typeof v;
+ if (t == 'string') // STRING - add quotes
+ v = '"'+ v +'"';
+ else if (t == 'object') // SUB-KEY - recurse into it
+ v = parse(v);
+ D[i++] = '"'+ k +'":'+ v;
+ }
+ return '{'+ D.join(',') +'}';
+ };
+ }
+
+ /**
+ * Convert stringified JSON back to a hash object
+ * @see $.parseJSON(), adding in jQuery 1.4.1
+ */
+, decodeJSON: function (str) {
+ try { return $.parseJSON ? $.parseJSON(str) : window["eval"]("("+ str +")") || {}; }
+ catch (e) { return {}; }
+ }
+
+
+, _create: function (inst) {
+ var _ = $.layout.state;
+ // ADD State-Management plugin methods to inst
+ $.extend( inst, {
+ // readCookie - update options from cookie - returns hash of cookie data
+ readCookie: function () { return _.readCookie(inst); }
+ // deleteCookie
+ , deleteCookie: function () { _.deleteCookie(inst); }
+ // saveCookie - optionally pass keys-list and cookie-options (hash)
+ , saveCookie: function (keys, cookieOpts) { return _.saveCookie(inst, keys, cookieOpts); }
+ // loadCookie - readCookie and use to loadState() - returns hash of cookie data
+ , loadCookie: function () { return _.loadCookie(inst); }
+ // loadState - pass a hash of state to use to update options
+ , loadState: function (stateData, animate) { _.loadState(inst, stateData, animate); }
+ // readState - returns hash of current layout-state
+ , readState: function (keys) { return _.readState(inst, keys); }
+ // add JSON utility methods too...
+ , encodeJSON: _.encodeJSON
+ , decodeJSON: _.decodeJSON
+ });
+
+ // init state.stateData key, even if plugin is initially disabled
+ inst.state.stateData = {};
+
+ // read and load cookie-data per options
+ var oS = inst.options.stateManagement;
+ if (oS.enabled) {
+ if (oS.autoLoad) // update the options from the cookie
+ inst.loadCookie();
+ else // don't modify options - just store cookie data in state.stateData
+ inst.state.stateData = inst.readCookie();
+ }
+ }
+
+, _unload: function (inst) {
+ var oS = inst.options.stateManagement;
+ if (oS.enabled) {
+ if (oS.autoSave) // save a state-cookie automatically
+ inst.saveCookie();
+ else // don't save a cookie, but do store state-data in state.stateData key
+ inst.state.stateData = inst.readState();
+ }
+ }
+
+};
+
+// add state initialization method to Layout's onCreate array of functions
+$.layout.onCreate.push( $.layout.state._create );
+$.layout.onUnload.push( $.layout.state._unload );
+
+
+
+
+/**
+ * jquery.layout.buttons 1.0
+ * $Date$
+ *
+ * Copyright (c) 2010
+ * Kevin Dalman (http://allpro.net)
+ *
+ * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
+ * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
+ *
+ * @dependancies: UI Layout 1.3.0.rc30.1 or higher
+ *
+ * @support: http://groups.google.com/group/jquery-ui-layout
+ *
+ * Docs: [ to come ]
+ * Tips: [ to come ]
+ */
+
+// tell Layout that the state plugin is available
+$.layout.plugins.buttons = true;
+
+// Add buttons options to layout.defaults
+$.layout.defaults.autoBindCustomButtons = false;
+// Specify autoBindCustomButtons as a layout-option, NOT a pane-option
+$.layout.optionsMap.layout.push("autoBindCustomButtons");
+
+var lang = $.layout.language;
+
+/*
+ * Button methods
+ */
+$.layout.buttons = {
+
+ /**
+ * Searches for .ui-layout-button-xxx elements and auto-binds them as layout-buttons
+ *
+ * @see _create()
+ *
+ * @param {Object} inst Layout Instance object
+ */
+ init: function (inst) {
+ var pre = "ui-layout-button-"
+ , layout = inst.options.name || ""
+ , name;
+ $.each("toggle,open,close,pin,toggle-slide,open-slide".split(","), function (i, action) {
+ $.each($.layout.config.borderPanes, function (ii, pane) {
+ $("."+pre+action+"-"+pane).each(function(){
+ // if button was previously 'bound', data.layoutName was set, but is blank if layout has no 'name'
+ name = $(this).data("layoutName") || $(this).attr("layoutName");
+ if (name == undefined || name === layout)
+ inst.bindButton(this, action, pane);
+ });
+ });
+ });
+ }
+
+ /**
+ * Helper function to validate params received by addButton utilities
+ *
+ * Two classes are added to the element, based on the buttonClass...
+ * The type of button is appended to create the 2nd className:
+ * - ui-layout-button-pin // action btnClass
+ * - ui-layout-button-pin-west // action btnClass + pane
+ * - ui-layout-button-toggle
+ * - ui-layout-button-open
+ * - ui-layout-button-close
+ *
+ * @param {Object} inst Layout Instance object
+ * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
+ * @param {string} pane Name of the pane the button is for: 'north', 'south', etc.
+ *
+ * @return {Array.<Object>} If both params valid, the element matching 'selector' in a jQuery wrapper - otherwise returns null
+ */
+, get: function (inst, selector, pane, action) {
+ var $E = $(selector)
+ , o = inst.options
+ , err = o.showErrorMessages
+ ;
+ if (!$E.length) { // element not found
+ if (err) $.layout.msg(lang.errButton + lang.selector +": "+ selector, true);
+ }
+ else if ($.inArray(pane, $.layout.config.borderPanes) < 0) { // invalid 'pane' sepecified
+ if (err) $.layout.msg(lang.errButton + lang.pane +": "+ pane, true);
+ $E = $(""); // NO BUTTON
+ }
+ else { // VALID
+ var btn = o[pane].buttonClass +"-"+ action;
+ $E .addClass( btn +" "+ btn +"-"+ pane )
+ .data("layoutName", o.name); // add layout identifier - even if blank!
+ }
+ return $E;
+ }
+
+
+ /**
+ * NEW syntax for binding layout-buttons - will eventually replace addToggle, addOpen, etc.
+ *
+ * @param {Object} inst Layout Instance object
+ * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
+ * @param {string} action
+ * @param {string} pane
+ */
+, bind: function (inst, selector, action, pane) {
+ var _ = $.layout.buttons;
+ switch (action.toLowerCase()) {
+ case "toggle": _.addToggle (inst, selector, pane); break;
+ case "open": _.addOpen (inst, selector, pane); break;
+ case "close": _.addClose (inst, selector, pane); break;
+ case "pin": _.addPin (inst, selector, pane); break;
+ case "toggle-slide": _.addToggle (inst, selector, pane, true); break;
+ case "open-slide": _.addOpen (inst, selector, pane, true); break;
+ }
+ return inst;
+ }
+
+ /**
+ * Add a custom Toggler button for a pane
+ *
+ * @param {Object} inst Layout Instance object
+ * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
+ * @param {string} pane Name of the pane the button is for: 'north', 'south', etc.
+ * @param {boolean=} slide true = slide-open, false = pin-open
+ */
+, addToggle: function (inst, selector, pane, slide) {
+ $.layout.buttons.get(inst, selector, pane, "toggle")
+ .click(function(evt){
+ inst.toggle(pane, !!slide);
+ evt.stopPropagation();
+ });
+ return inst;
+ }
+
+ /**
+ * Add a custom Open button for a pane
+ *
+ * @param {Object} inst Layout Instance object
+ * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
+ * @param {string} pane Name of the pane the button is for: 'north', 'south', etc.
+ * @param {boolean=} slide true = slide-open, false = pin-open
+ */
+, addOpen: function (inst, selector, pane, slide) {
+ $.layout.buttons.get(inst, selector, pane, "open")
+ .attr("title", lang.Open)
+ .click(function (evt) {
+ inst.open(pane, !!slide);
+ evt.stopPropagation();
+ });
+ return inst;
+ }
+
+ /**
+ * Add a custom Close button for a pane
+ *
+ * @param {Object} inst Layout Instance object
+ * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
+ * @param {string} pane Name of the pane the button is for: 'north', 'south', etc.
+ */
+, addClose: function (inst, selector, pane) {
+ $.layout.buttons.get(inst, selector, pane, "close")
+ .attr("title", lang.Close)
+ .click(function (evt) {
+ inst.close(pane);
+ evt.stopPropagation();
+ });
+ return inst;
+ }
+
+ /**
+ * Add a custom Pin button for a pane
+ *
+ * Four classes are added to the element, based on the paneClass for the associated pane...
+ * Assuming the default paneClass and the pin is 'up', these classes are added for a west-pane pin:
+ * - ui-layout-pane-pin
+ * - ui-layout-pane-west-pin
+ * - ui-layout-pane-pin-up
+ * - ui-layout-pane-west-pin-up
+ *
+ * @param {Object} inst Layout Instance object
+ * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button"
+ * @param {string} pane Name of the pane the pin is for: 'north', 'south', etc.
+ */
+, addPin: function (inst, selector, pane) {
+ var _ = $.layout.buttons
+ , $E = _.get(inst, selector, pane, "pin");
+ if ($E.length) {
+ var s = inst.state[pane];
+ $E.click(function (evt) {
+ _.setPinState(inst, $(this), pane, (s.isSliding || s.isClosed));
+ if (s.isSliding || s.isClosed) inst.open( pane ); // change from sliding to open
+ else inst.close( pane ); // slide-closed
+ evt.stopPropagation();
+ });
+ // add up/down pin attributes and classes
+ _.setPinState(inst, $E, pane, (!s.isClosed && !s.isSliding));
+ // add this pin to the pane data so we can 'sync it' automatically
+ // PANE.pins key is an array so we can store multiple pins for each pane
+ s.pins.push( selector ); // just save the selector string
+ }
+ return inst;
+ }
+
+ /**
+ * Change the class of the pin button to make it look 'up' or 'down'
+ *
+ * @see addPin(), syncPins()
+ *
+ * @param {Object} inst Layout Instance object
+ * @param {Array.<Object>} $Pin The pin-span element in a jQuery wrapper
+ * @param {string} pane These are the params returned to callbacks by layout()
+ * @param {boolean} doPin true = set the pin 'down', false = set it 'up'
+ */
+, setPinState: function (inst, $Pin, pane, doPin) {
+ var updown = $Pin.attr("pin");
+ if (updown && doPin === (updown=="down")) return; // already in correct state
+ var
+ pin = inst.options[pane].buttonClass +"-pin"
+ , side = pin +"-"+ pane
+ , UP = pin +"-up "+ side +"-up"
+ , DN = pin +"-down "+side +"-down"
+ ;
+ $Pin
+ .attr("pin", doPin ? "down" : "up") // logic
+ .attr("title", doPin ? lang.Unpin : lang.Pin)
+ .removeClass( doPin ? UP : DN )
+ .addClass( doPin ? DN : UP )
+ ;
+ }
+
+ /**
+ * INTERNAL function to sync 'pin buttons' when pane is opened or closed
+ * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes
+ *
+ * @see open(), close()
+ *
+ * @param {Object} inst Layout Instance object
+ * @param {string} pane These are the params returned to callbacks by layout()
+ * @param {boolean} doPin True means set the pin 'down', False means 'up'
+ */
+, syncPinBtns: function (inst, pane, doPin) {
+ // REAL METHOD IS _INSIDE_ LAYOUT - THIS IS HERE JUST FOR REFERENCE
+ $.each(state[pane].pins, function (i, selector) {
+ $.layout.buttons.setPinState(inst, $(selector), pane, doPin);
+ });
+ }
+
+
+, _load: function (inst) {
+ var _ = $.layout.buttons;
+ // ADD Button methods to Layout Instance
+ // Note: sel = jQuery Selector string
+ $.extend( inst, {
+ bindButton: function (sel, action, pane) { return _.bind(inst, sel, action, pane); }
+ // DEPRECATED METHODS
+ , addToggleBtn: function (sel, pane, slide) { return _.addToggle(inst, sel, pane, slide); }
+ , addOpenBtn: function (sel, pane, slide) { return _.addOpen(inst, sel, pane, slide); }
+ , addCloseBtn: function (sel, pane) { return _.addClose(inst, sel, pane); }
+ , addPinBtn: function (sel, pane) { return _.addPin(inst, sel, pane); }
+ });
+
+ // init state array to hold pin-buttons
+ for (var i=0; i<4; i++) {
+ var pane = $.layout.config.borderPanes[i];
+ inst.state[pane].pins = [];
+ }
+
+ // auto-init buttons onLoad if option is enabled
+ if ( inst.options.autoBindCustomButtons )
+ _.init(inst);
+ }
+
+, _unload: function (inst) {
+ // TODO: unbind all buttons???
+ }
+
+};
+
+// add initialization method to Layout's onLoad array of functions
+$.layout.onLoad.push( $.layout.buttons._load );
+//$.layout.onUnload.push( $.layout.buttons._unload );
+
+
+
+/**
+ * jquery.layout.browserZoom 1.0
+ * $Date$
+ *
+ * Copyright (c) 2012
+ * Kevin Dalman (http://allpro.net)
+ *
+ * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
+ * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
+ *
+ * @dependancies: UI Layout 1.3.0.rc30.1 or higher
+ *
+ * @support: http://groups.google.com/group/jquery-ui-layout
+ *
+ * @todo: Extend logic to handle other problematic zooming in browsers
+ * @todo: Add hotkey/mousewheel bindings to _instantly_ respond to these zoom event
+ */
+
+// tell Layout that the plugin is available
+$.layout.plugins.browserZoom = true;
+
+$.layout.defaults.browserZoomCheckInterval = 1000;
+$.layout.optionsMap.layout.push("browserZoomCheckInterval");
+
+/*
+ * browserZoom methods
+ */
+$.layout.browserZoom = {
+
+ _init: function (inst) {
+ // abort if browser does not need this check
+ if ($.layout.browserZoom.ratio() !== false)
+ $.layout.browserZoom._setTimer(inst);
+ }
+
+, _setTimer: function (inst) {
+ // abort if layout destroyed or browser does not need this check
+ if (inst.destroyed) return;
+ var o = inst.options
+ , s = inst.state
+ // don't need check if inst has parentLayout, but check occassionally in case parent destroyed!
+ // MINIMUM 100ms interval, for performance
+ , ms = inst.hasParentLayout ? 5000 : Math.max( o.browserZoomCheckInterval, 100 )
+ ;
+ // set the timer
+ setTimeout(function(){
+ if (inst.destroyed || !o.resizeWithWindow) return;
+ var d = $.layout.browserZoom.ratio();
+ if (d !== s.browserZoom) {
+ s.browserZoom = d;
+ inst.resizeAll();
+ }
+ // set a NEW timeout
+ $.layout.browserZoom._setTimer(inst);
+ }
+ , ms );
+ }
+
+, ratio: function () {
+ var w = window
+ , s = screen
+ , d = document
+ , dE = d.documentElement || d.body
+ , b = $.layout.browser
+ , v = b.version
+ , r, sW, cW
+ ;
+ // we can ignore all browsers that fire window.resize event onZoom
+ if ((b.msie && v > 8)
+ || !b.msie
+ ) return false; // don't need to track zoom
+
+ if (s.deviceXDPI)
+ return calc(s.deviceXDPI, s.systemXDPI);
+ // everything below is just for future reference!
+ if (b.webkit && (r = d.body.getBoundingClientRect))
+ return calc((r.left - r.right), d.body.offsetWidth);
+ if (b.webkit && (sW = w.outerWidth))
+ return calc(sW, w.innerWidth);
+ if ((sW = s.width) && (cW = dE.clientWidth))
+ return calc(sW, cW);
+ return false; // no match, so cannot - or don't need to - track zoom
+
+ function calc (x,y) { return (parseInt(x,10) / parseInt(y,10) * 100).toFixed(); }
+ }
+
+};
+// add initialization method to Layout's onLoad array of functions
+$.layout.onReady.push( $.layout.browserZoom._init );
+
+
+
+})( jQuery ); \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-anim_basic_16x16.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-anim_basic_16x16.gif
new file mode 100644
index 000000000..085ccaeca
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-anim_basic_16x16.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_flat_0_aaaaaa_40x100.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 000000000..5b5dab2ab
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_flat_0_aaaaaa_40x100.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_flat_55_fbec88_40x100.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_flat_55_fbec88_40x100.png
new file mode 100644
index 000000000..47acaadd7
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_flat_55_fbec88_40x100.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_75_d0e5f5_1x400.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_75_d0e5f5_1x400.png
new file mode 100644
index 000000000..9d149b1c6
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_75_d0e5f5_1x400.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_85_dfeffc_1x400.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_85_dfeffc_1x400.png
new file mode 100644
index 000000000..014951529
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_85_dfeffc_1x400.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_95_fef1ec_1x400.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644
index 000000000..4443fdc1a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_glass_95_fef1ec_1x400.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png
new file mode 100644
index 000000000..81ecc362d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png
new file mode 100644
index 000000000..4f3faf8aa
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
new file mode 100644
index 000000000..38c38335d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_217bc0_256x240.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_217bc0_256x240.png
new file mode 100644
index 000000000..6f4bd87c0
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_217bc0_256x240.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_2e83ff_256x240.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_2e83ff_256x240.png
new file mode 100644
index 000000000..09d1cdc85
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_2e83ff_256x240.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_469bdd_256x240.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_469bdd_256x240.png
new file mode 100644
index 000000000..bd2cf079a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_469bdd_256x240.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_6da8d5_256x240.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_6da8d5_256x240.png
new file mode 100644
index 000000000..3d6f567f4
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_6da8d5_256x240.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_cd0a0a_256x240.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_cd0a0a_256x240.png
new file mode 100644
index 000000000..2ab019b73
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_cd0a0a_256x240.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_d8e7f3_256x240.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_d8e7f3_256x240.png
new file mode 100644
index 000000000..ad2dc6f9d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_d8e7f3_256x240.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_f9bd01_256x240.png b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_f9bd01_256x240.png
new file mode 100644
index 000000000..c7c53cb11
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/images/ui-icons_f9bd01_256x240.png
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css
new file mode 100644
index 000000000..0b1736320
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css
@@ -0,0 +1,398 @@
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+*/
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
+*/
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; }
+.ui-widget-content a { color: #222222; }
+.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
+.ui-widget-header a { color: #ffffff; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2e6e9e; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #1d5987; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); }
+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); }
+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); }
+.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); }
+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; }
+.ui-corner-tr { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; }
+.ui-corner-br { -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
+.ui-corner-top { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
+.ui-corner-right { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; }
+.ui-corner-left { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; }
+.ui-corner-all { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* Resizable
+----------------------------------*/
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Selectable
+----------------------------------*/
+.ui-selectable-helper { border:1px dotted black }
+/* Autocomplete
+----------------------------------*/
+.ui-autocomplete { position: absolute; cursor: default; }
+.ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; }
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+
+/* Menu
+----------------------------------*/
+.ui-menu {
+ list-style:none;
+ padding: 2px;
+ margin: 0;
+ display:block;
+}
+.ui-menu .ui-menu {
+ margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+ margin:0;
+ padding: 0;
+ zoom: 1;
+ float: left;
+ clear: left;
+ width: 100%;
+}
+.ui-menu .ui-menu-item a {
+ text-decoration:none;
+ display:block;
+ padding:.2em .4em;
+ line-height:1.5;
+ zoom:1;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+ font-weight: normal;
+ margin: -1px;
+}
+/* Button
+----------------------------------*/
+
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; }
+button.ui-button-icons-only { width: 3.7em; }
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4; }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+
+
+
+
+
+/* Dialog
+----------------------------------*/
+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
+.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }
+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/* Tabs
+----------------------------------*/
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/file.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/file.gif
new file mode 100644
index 000000000..bd4f96549
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/file.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/folder-closed.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/folder-closed.gif
new file mode 100644
index 000000000..be6b59c2b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/folder-closed.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/folder.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/folder.gif
new file mode 100644
index 000000000..be6b59c2b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/folder.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-black-line.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-black-line.gif
new file mode 100644
index 000000000..e5496877a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-black-line.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-black.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-black.gif
new file mode 100644
index 000000000..d549b9fc5
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-black.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-default-line.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-default-line.gif
new file mode 100644
index 000000000..37114d306
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-default-line.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-default.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-default.gif
new file mode 100644
index 000000000..a12ac52ff
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-default.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-famfamfam-line.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-famfamfam-line.gif
new file mode 100644
index 000000000..6e289cecc
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-famfamfam-line.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-famfamfam.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-famfamfam.gif
new file mode 100644
index 000000000..0cb178e89
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-famfamfam.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-gray-line.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-gray-line.gif
new file mode 100644
index 000000000..37600447d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-gray-line.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-gray.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-gray.gif
new file mode 100644
index 000000000..cfb8a2f09
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-gray.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-red-line.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-red-line.gif
new file mode 100644
index 000000000..df9e749a8
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-red-line.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-red.gif b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-red.gif
new file mode 100644
index 000000000..3bbb3a157
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/images/treeview-red.gif
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/jquery.treeview.css b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/jquery.treeview.css
new file mode 100644
index 000000000..d7e2c002a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/jquery.treeview.css
@@ -0,0 +1,85 @@
+.treeview, .treeview ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+.treeview ul {
+ background-color: white;
+ margin-top: 4px;
+}
+
+.treeview .hitarea {
+ background: url(images/treeview-default.gif) -64px -25px no-repeat;
+ height: 16px;
+ width: 16px;
+ margin-left: -16px;
+ float: left;
+ cursor: pointer;
+}
+/* fix for IE6 */
+* html .hitarea {
+ display: inline;
+ float:none;
+}
+
+.treeview li {
+ margin: 0;
+ padding: 3px 0 3px 16px;
+}
+
+.treeview a.selected {
+ background-color: #eee;
+}
+
+#treecontrol { margin: 1em 0; display: none; }
+
+.treeview .hover { color: red; cursor: pointer; }
+
+.treeview li { background: url(images/treeview-default-line.gif) 0 0 no-repeat; }
+.treeview li.collapsable, .treeview li.expandable { background-position: 0 -176px; }
+
+.treeview .expandable-hitarea { background-position: -80px -3px; }
+
+.treeview li.last { background-position: 0 -1766px }
+.treeview li.lastCollapsable, .treeview li.lastExpandable { background-image: url(images/treeview-default.gif); }
+.treeview li.lastCollapsable { background-position: 0 -111px }
+.treeview li.lastExpandable { background-position: -32px -67px }
+
+.treeview div.lastCollapsable-hitarea, .treeview div.lastExpandable-hitarea { background-position: 0; }
+
+.treeview-red li { background-image: url(images/treeview-red-line.gif); }
+.treeview-red .hitarea, .treeview-red li.lastCollapsable, .treeview-red li.lastExpandable { background-image: url(images/treeview-red.gif); }
+
+.treeview-black li { background-image: url(images/treeview-black-line.gif); }
+.treeview-black .hitarea, .treeview-black li.lastCollapsable, .treeview-black li.lastExpandable { background-image: url(images/treeview-black.gif); }
+
+.treeview-gray li { background-image: url(images/treeview-gray-line.gif); }
+.treeview-gray .hitarea, .treeview-gray li.lastCollapsable, .treeview-gray li.lastExpandable { background-image: url(images/treeview-gray.gif); }
+
+.treeview-famfamfam li { background-image: url(images/treeview-famfamfam-line.gif); }
+.treeview-famfamfam .hitarea, .treeview-famfamfam li.lastCollapsable, .treeview-famfamfam li.lastExpandable { background-image: url(images/treeview-famfamfam.gif); }
+
+
+.filetree li { padding: 3px 0 2px 16px; }
+.filetree span.folder, .filetree span.file { padding: 1px 0 1px 16px; display: block; }
+.filetree span.folder { background: url(images/folder.gif) 0 0 no-repeat; }
+.filetree li.expandable span.folder { background: url(images/folder-closed.gif) 0 0 no-repeat; }
+.filetree span.file { background: url(images/file.gif) 0 0 no-repeat; }
+
+html, body {height:100%; margin: 0; padding: 0; }
+
+/*
+html>body {
+ font-size: 16px;
+ font-size: 68.75%;
+} Reset Base Font Size */
+ /*
+body {
+ font-family: Verdana, helvetica, arial, sans-serif;
+ font-size: 68.75%;
+ background: #fff;
+ color: #333;
+} */
+
+a img { border: none; } \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/jquery.treeview.min.js b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/jquery.treeview.min.js
new file mode 100644
index 000000000..f9b490d3e
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/jquery/treeview/jquery.treeview.min.js
@@ -0,0 +1,16 @@
+/*
+ * Treeview 1.4 - jQuery plugin to hide and show branches of a tree
+ *
+ * http://bassistance.de/jquery-plugins/jquery-plugin-treeview/
+ * http://docs.jquery.com/Plugins/Treeview
+ *
+ * Copyright (c) 2007 Jörn Zaefferer
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Revision: $Id$
+ * kasunbg: changed the cookieid name
+ *
+ */;(function($){$.extend($.fn,{swapClass:function(c1,c2){var c1Elements=this.filter('.'+c1);this.filter('.'+c2).removeClass(c2).addClass(c1);c1Elements.removeClass(c1).addClass(c2);return this;},replaceClass:function(c1,c2){return this.filter('.'+c1).removeClass(c1).addClass(c2).end();},hoverClass:function(className){className=className||"hover";return this.hover(function(){$(this).addClass(className);},function(){$(this).removeClass(className);});},heightToggle:function(animated,callback){animated?this.animate({height:"toggle"},animated,callback):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();if(callback)callback.apply(this,arguments);});},heightHide:function(animated,callback){if(animated){this.animate({height:"hide"},animated,callback);}else{this.hide();if(callback)this.each(callback);}},prepareBranches:function(settings){if(!settings.prerendered){this.filter(":last-child:not(ul)").addClass(CLASSES.last);this.filter((settings.collapsed?"":"."+CLASSES.closed)+":not(."+CLASSES.open+")").find(">ul").hide();}return this.filter(":has(>ul)");},applyClasses:function(settings,toggler){this.filter(":has(>ul):not(:has(>a))").find(">span").click(function(event){toggler.apply($(this).next());}).add($("a",this)).hoverClass();if(!settings.prerendered){this.filter(":has(>ul:hidden)").addClass(CLASSES.expandable).replaceClass(CLASSES.last,CLASSES.lastExpandable);this.not(":has(>ul:hidden)").addClass(CLASSES.collapsable).replaceClass(CLASSES.last,CLASSES.lastCollapsable);this.prepend("<div class=\""+CLASSES.hitarea+"\"/>").find("div."+CLASSES.hitarea).each(function(){var classes="";$.each($(this).parent().attr("class").split(" "),function(){classes+=this+"-hitarea ";});$(this).addClass(classes);});}this.find("div."+CLASSES.hitarea).click(toggler);},treeview:function(settings){if(typeof(window.treeCookieId) === 'undefined' || window.treeCookieId === ""){treeCookieId = "treeview";} settings=$.extend({cookieId: treeCookieId},settings);if(settings.add){return this.trigger("add",[settings.add]);}if(settings.toggle){var callback=settings.toggle;settings.toggle=function(){return callback.apply($(this).parent()[0],arguments);};}function treeController(tree,control){function handler(filter){return function(){toggler.apply($("div."+CLASSES.hitarea,tree).filter(function(){return filter?$(this).parent("."+filter).length:true;}));return false;};}$("a:eq(0)",control).click(handler(CLASSES.collapsable));$("a:eq(1)",control).click(handler(CLASSES.expandable));$("a:eq(2)",control).click(handler());}function toggler(){$(this).parent().find(">.hitarea").swapClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea).swapClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea).end().swapClass(CLASSES.collapsable,CLASSES.expandable).swapClass(CLASSES.lastCollapsable,CLASSES.lastExpandable).find(">ul").heightToggle(settings.animated,settings.toggle);if(settings.unique){$(this).parent().siblings().find(">.hitarea").replaceClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea).replaceClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea).end().replaceClass(CLASSES.collapsable,CLASSES.expandable).replaceClass(CLASSES.lastCollapsable,CLASSES.lastExpandable).find(">ul").heightHide(settings.animated,settings.toggle);}}function serialize(){function binary(arg){return arg?1:0;}var data=[];branches.each(function(i,e){data[i]=$(e).is(":has(>ul:visible)")?1:0;});$.cookie(settings.cookieId,data.join(""));}function deserialize(){var stored=$.cookie(settings.cookieId);if(stored){var data=stored.split("");branches.each(function(i,e){$(e).find(">ul")[parseInt(data[i])?"show":"hide"]();});}}this.addClass("treeview");var branches=this.find("li").prepareBranches(settings);switch(settings.persist){case"cookie":var toggleCallback=settings.toggle;settings.toggle=function(){serialize();if(toggleCallback){toggleCallback.apply(this,arguments);}};deserialize();break;case"location":var current=this.find("a").filter(function(){return this.href.toLowerCase()==location.href.toLowerCase();});if(current.length){current.addClass("selected").parents("ul, li").add(current.next()).show();}break;}branches.applyClasses(settings,toggler);if(settings.control){treeController(this,settings.control);$(settings.control).show();}return this.bind("add",function(event,branches){$(branches).prev().removeClass(CLASSES.last).removeClass(CLASSES.lastCollapsable).removeClass(CLASSES.lastExpandable).find(">.hitarea").removeClass(CLASSES.lastCollapsableHitarea).removeClass(CLASSES.lastExpandableHitarea);$(branches).find("li").andSelf().prepareBranches(settings).applyClasses(settings,toggler);});}});var CLASSES=$.fn.treeview.classes={open:"open",closed:"closed",expandable:"expandable",expandableHitarea:"expandable-hitarea",lastExpandableHitarea:"lastExpandable-hitarea",collapsable:"collapsable",collapsableHitarea:"collapsable-hitarea",lastCollapsableHitarea:"lastCollapsable-hitarea",lastCollapsable:"lastCollapsable",lastExpandable:"lastExpandable",last:"last",hitarea:"hitarea"};$.fn.Treeview=$.fn.treeview;})(jQuery); \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/main.js b/xs/src/avrdude/atmel-docs/EDBG/common/main.js
new file mode 100644
index 000000000..96b6a86c6
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/main.js
@@ -0,0 +1,282 @@
+/**
+ * Miscellaneous js functions for WebHelp
+ * Kasun Gajasinghe, http://kasunbg.blogspot.com
+ * David Cramer, http://www.thingbag.net
+ *
+ */
+
+//Turn ON and OFF the animations for Show/Hide Sidebar. Extend this to other anime as well if any.
+var noAnimations=false;
+
+$(document).ready(function() {
+
+ /* Local addition */
+ $("a").filter(function() {
+ return this.hostname && this.hostname !== location.hostname;
+ }).addClass('external');
+
+ // When you click on a link to an anchor, scroll down
+ // 105 px to cope with the fact that the banner
+ // hides the top 95px or so of the page.
+ // This code deals with the problem when
+ // you click on a link within a page.
+ $('a[href*=#]').click(function() {
+ if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'')
+ && location.hostname == this.hostname) {
+ var $target = $(this.hash);
+ $target = $target.length && $target
+ || $('[name=' + this.hash.slice(1) +']');
+ if (!(this.hash == "#searchDiv" || this.hash == "#treeDiv" || this.hash == "") && $target.length) {
+ var targetOffset = $target.offset().top - 120;
+ $('html,body')
+ .animate({scrollTop: targetOffset}, 200);
+ return false;
+ }
+ }
+ });
+
+ // $("#showHideHighlight").button(); //add jquery button styling to 'Go' button
+ //Generate tabs in nav-pane with JQuery
+ $(function() {
+ $("#tabs").tabs({
+ cookie: {
+ expires: 2 // store cookie for 2 days.
+ }
+ });
+ });
+
+ //Generate the tree
+ $("#ulTreeDiv").attr("style", "");
+ $("#tree").treeview({
+ collapsed: true,
+ animated: "medium",
+ control: "#sidetreecontrol",
+ persist: "cookie"
+ });
+
+ //after toc fully styled, display it. Until loading, a 'loading' image will be displayed
+ $("#tocLoading").attr("style", "display:none;");
+ // $("#ulTreeDiv").attr("style","display:block;");
+
+ //.searchButton is the css class applied to 'Go' button
+ $(function() {
+ $("button", ".searchButton").button();
+
+ $("button", ".searchButton").click(function() {
+ return false;
+ });
+ });
+
+ //'ui-tabs-1' is the cookie name which is used for the persistence of the tabs.(Content/Search tab)
+ if ($.cookie('ui-tabs-1') === '1') { //search tab is active
+ if ($.cookie('textToSearch') != undefined && $.cookie('textToSearch').length > 0) {
+ document.getElementById('textToSearch').value = $.cookie('textToSearch');
+ Verifie('searchForm');
+ searchHighlight($.cookie('textToSearch'));
+ $("#showHideHighlight").css("display", "block");
+ }
+ }
+
+ syncToc(); //Synchronize the toc tree with the content pane, when loading the page.
+ //$("#doSearch").button(); //add jquery button styling to 'Go' button
+
+ // When you click on a link to an anchor, scroll down
+ // 120 px to cope with the fact that the banner
+ // hides the top 95px or so of the page.
+ // This code deals with the problem when
+ // you click on a link from another page.
+ var hash = window.location.hash;
+ if(hash){
+ var targetOffset = $(hash).offset().top - 120;
+ $('html,body').animate({scrollTop: targetOffset}, 200);
+ return false;
+ }
+});
+
+
+/**
+ * If an user moved to another page by clicking on a toc link, and then clicked on #searchDiv,
+ * search should be performed if the cookie textToSearch is not empty.
+ */
+function doSearch() {
+//'ui-tabs-1' is the cookie name which is used for the persistence of the tabs.(Content/Search tab)
+ if ($.cookie('textToSearch') != undefined && $.cookie('textToSearch').length > 0) {
+ document.getElementById('textToSearch').value = $.cookie('textToSearch');
+ Verifie('searchForm');
+ }
+}
+
+/**
+ * Synchronize with the tableOfContents
+ */
+function syncToc() {
+ var a = document.getElementById("webhelp-currentid");
+ if (a != undefined) {
+ //Expanding the child sections of the selected node.
+ var nodeClass = a.getAttribute("class");
+ if (nodeClass != null && !nodeClass.match(/collapsable/)) {
+ a.setAttribute("class", "collapsable");
+ //remove display:none; css style from <ul> block in the selected node.
+ var ulNode = a.getElementsByTagName("ul")[0];
+ if (ulNode != undefined) {
+ if (ulNode.hasAttribute("style")) {
+ ulNode.setAttribute("style", "display: block; background-color: #D8D8D8 !important;");
+ } else {
+ var ulStyle = document.createAttribute("style");
+ ulStyle.nodeValue = "display: block; background-color: #D8D8D8 !important;";
+ ulNode.setAttributeNode(ulStyle);
+ } }
+ //adjust tree's + sign to -
+ var divNode = a.getElementsByTagName("div")[0];
+ if (divNode != undefined) {
+ if (divNode.hasAttribute("class")) {
+ divNode.setAttribute("class", "hitarea collapsable-hitarea");
+ } else {
+ var divClass = document.createAttribute("class");
+ divClass.nodeValue = "hitarea collapsable-hitarea";
+ divNode.setAttributeNode(divClass);
+ } }
+ //set persistence cookie when a node is auto expanded
+ // setCookieForExpandedNode("webhelp-currentid");
+ }
+ var b = a.getElementsByTagName("a")[0];
+
+ if (b != undefined) {
+ //Setting the background for selected node.
+ var style = a.getAttribute("style", 2);
+ if (style != null && !style.match(/background-color: Background;/)) {
+ a.setAttribute("style", "background-color: #D8D8D8; " + style);
+ b.setAttribute("style", "color: black;");
+ } else if (style != null) {
+ a.setAttribute("style", "background-color: #D8D8D8; " + style);
+ b.setAttribute("style", "color: black;");
+ } else {
+ a.setAttribute("style", "background-color: #D8D8D8; ");
+ b.setAttribute("style", "color: black;");
+ }
+ }
+
+ //shows the node related to current content.
+ //goes a recursive call from current node to ancestor nodes, displaying all of them.
+ while (a.parentNode && a.parentNode.nodeName) {
+ var parentNode = a.parentNode;
+ var nodeName = parentNode.nodeName;
+
+ if (nodeName.toLowerCase() == "ul") {
+ parentNode.setAttribute("style", "display: block;");
+ } else if (nodeName.toLocaleLowerCase() == "li") {
+ parentNode.setAttribute("class", "collapsable");
+ parentNode.firstChild.setAttribute("class", "hitarea collapsable-hitarea ");
+ }
+ a = parentNode;
+} } }
+/*
+ function setCookieForExpandedNode(nodeName) {
+ var tocDiv = document.getElementById("tree"); //get table of contents Div
+ var divs = tocDiv.getElementsByTagName("div");
+ var matchedDivNumber;
+ var i;
+ for (i = 0; i < divs.length; i++) { //1101001
+ var div = divs[i];
+ var liNode = div.parentNode;
+ }
+//create a new cookie if a treeview does not exist
+ if ($.cookie(treeCookieId) == null || $.cookie(treeCookieId) == "") {
+ var branches = $("#tree").find("li");//.prepareBranches(treesettings);
+ var data = [];
+ branches.each(function(i, e) {
+ data[i] = $(e).is(":has(>ul:visible)") ? 1 : 0;
+ });
+ $.cookie(treeCookieId, data.join(""));
+
+ }
+
+ if (i < divs.length) {
+ var treeviewCookie = $.cookie(treeCookieId);
+ var tvCookie1 = treeviewCookie.substring(0, i);
+ var tvCookie2 = treeviewCookie.substring(i + 1);
+ var newTVCookie = tvCookie1 + "1" + tvCookie2;
+ $.cookie(treeCookieId, newTVCookie);
+ }
+ } */
+
+/**
+ * Code for Show/Hide TOC
+ *
+ */
+function showHideToc() {
+ var showHideButton = $("#showHideButton");
+ var leftNavigation = $("#sidebar"); //hide the parent div of leftnavigation, ie sidebar
+ var content = $("#content");
+ var animeTime=75
+
+ if (showHideButton != undefined && showHideButton.hasClass("pointLeft")) {
+ //Hide TOC
+ showHideButton.removeClass('pointLeft').addClass('pointRight');
+
+ if(noAnimations) {
+ leftNavigation.css("display", "none");
+ content.css("margin", "125px 0 0 0");
+ } else {
+ leftNavigation.hide(animeTime);
+ content.animate( { "margin-left": 0 }, animeTime);
+ }
+ showHideButton.attr("title", "Show Sidebar");
+ } else {
+ //Show the TOC
+ showHideButton.removeClass('pointRight').addClass('pointLeft');
+ if(noAnimations) {
+ content.css("margin", "125px 0 0 280px");
+ leftNavigation.css("display", "block");
+ } else {
+ content.animate( { "margin-left": '280px' }, animeTime);
+ leftNavigation.show(animeTime);
+ }
+ showHideButton.attr("title", "Hide Sidebar");
+ }
+}
+
+/**
+ * Code for search highlighting
+ */
+var highlightOn = true;
+function searchHighlight(searchText) {
+ highlightOn = true;
+ if (searchText != undefined) {
+ var wList;
+ var sList = new Array(); //stem list
+ //Highlight the search terms
+ searchText = searchText.toLowerCase().replace(/<\//g, "_st_").replace(/\$_/g, "_di_").replace(/\.|%2C|%3B|%21|%3A|@|\/|\*/g, " ").replace(/(%20)+/g, " ").replace(/_st_/g, "</").replace(/_di_/g, "%24_")
+ searchText = searchText.replace(/ +/g, " ");
+ searchText = searchText.replace(/ $/, "").replace(/^ /, "");
+
+ wList = searchText.split(" ");
+ $("#content").highlight(wList); //Highlight the search input
+
+ if (typeof stemmer != "undefined") {
+ //Highlight the stems
+ for (var i = 0; i < wList.length; i++) {
+ var stemW = stemmer(wList[i]);
+ sList.push(stemW);
+ }
+ } else {
+ sList = wList;
+ }
+ $("#content").highlight(sList); //Highlight the search input's all stems
+ }
+}
+
+function searchUnhighlight() {
+ highlightOn = false;
+ //unhighlight the search input's all stems
+ $("#content").unhighlight();
+ $("#content").unhighlight();
+}
+
+function toggleHighlight() {
+ if (highlightOn) {
+ searchUnhighlight();
+ } else {
+ searchHighlight($.cookie('textToSearch'));
+ }
+} \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/common/splitterInit.js b/xs/src/avrdude/atmel-docs/EDBG/common/splitterInit.js
new file mode 100644
index 000000000..090b81485
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/common/splitterInit.js
@@ -0,0 +1,40 @@
+
+ var myLayout;
+
+ jQuery(document).ready(function ($) {
+
+ myLayout = $('body').layout({
+ //Defining panes
+ west__paneSelector: "#sidebar"
+ , north__paneSelector: "#header"
+ , center__paneSelector: "#content"
+
+ // some resizing/toggling settings
+ , north__resizable: false // OVERRIDE the pane-default of 'resizable=true'
+ , north__spacing_open: 0 // no resizer-bar when open (zero height)
+ , west__slideable: false
+ , west__spacing_closed: 6
+ , west__spacing_open: 4
+
+ ,
+ // some pane-size settings
+ west__minSize: 280
+ , north__minSize: 99
+
+ // some pane animation settings
+ , west__animatePaneSizing: false
+ , west__fxSpeed_size: "normal"
+ , west__fxSpeed_open: 10
+ , west__fxSettings_open: {easing: ""}
+ , west__fxName_close: "none"
+
+
+ , stateManagement__enabled: true // automatic cookie load & save enabled by default
+ , stateManagement__cookie__name: "sidebar_state"
+ });
+
+
+
+
+ });
+
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch01s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch01s01.html
new file mode 100644
index 000000000..470b46f0e
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch01s01.html
@@ -0,0 +1,218 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>EDBG interface overview - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.Introduction.html" title="Introduction" /><link rel="prev" href="protocoldocs.Introduction.html" title="Introduction" /><link rel="next" href="ch01s02.html" title="Atmel EDBG-based tool implementations" /><meta content="EDBG interface overview" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Introduction</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="protocoldocs.Introduction.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.Introduction.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch01s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N1004F" />EDBG interface overview</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The Atmel Embedded Debugger (EDBG) implements a composite USB device consisting of three interfaces:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Programming &amp; debugging interface (HID)</p></li><li class="listitem"><p>CDC Virtual COM port</p></li><li class="listitem"><p>Atmel Data Gateway Interface</p></li></ul></div><p>The programming and debugging interface is an implementation of the CMSIS-DAP
+ interface defined by <span class="trademark">Keil</span>&reg;. CMSIS-DAP supports access
+ to any ARM Coresight Debug Access Port. CMSIS-DAP supports a set of "vendor" commands, which
+ are used by EDBG for accessing special functions not natively supported by CMSIS-DAP, as well
+ as for debugging and programming Atmel AVR device families.</p><p>The CDC Virtual COM port implementation provides a simple link between a COM port
+ registered on the host PC and a RX-TX pin pair on the EDBG. This pair is connected to a UART
+ pin pair on the board on which the EDBG is embedded.</p><p>The DGI is a bidirectional interface for streaming data to and from the EDBG. It is a
+ custom interface with input and output BULK endpoints.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>mEDBG is a scaled-down EDBG implementation and does not support the DGI.</p></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="protocoldocs.Introduction.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.Introduction.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch01s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch01s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch01s02.html
new file mode 100644
index 000000000..d59bf2d5e
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch01s02.html
@@ -0,0 +1,234 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Atmel EDBG-based tool implementations - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.Introduction.html" title="Introduction" /><link rel="prev" href="ch01s01.html" title="EDBG interface overview" /><link rel="next" href="protocoldocs.cmsis_dap.html" title="CMSIS-DAP" /><meta content="Atmel EDBG-based tool implementations" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Introduction</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch01s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.Introduction.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="protocoldocs.cmsis_dap.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N1006B" />Atmel EDBG-based tool implementations</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The protocol-set described in this document is intended for use on EDBG platforms as well
+ as standalone debuggers. The JTAGICE3 firmware version 3 upgrades that tool to support SAMD20,
+ and implements parts of the protocol-set described here. EDBG implementations are very limited
+ subsets os this protocol which support the particular Atmel controller mounted on that board. </p><div class="table"><a id="N10070" /><p class="title"><strong>Table&nbsp;1.&nbsp;Atmel EDBG-based tool implementations</strong></p><div class="table-contents"><table summary="Atmel EDBG-based tool implementations" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Tool</th><th>USB PID</th><th>Supports</th><th>Notes</th></tr></thead><tbody><tr><td>EDBG</td><td>0x2111</td><td>
+ <p>Only the Atmel device mounted on that board</p>
+ <p>CDC Virtual COM port and Atmel Data Gateway Interface support varies between different kits</p>
+ </td><td>
+ <p>As used on Xplained Pro boards</p>
+ </td></tr><tr><td>mEDBG</td><td>0x2145</td><td>
+ <p>Only the Atmel device mounted on that board</p>
+ <p>CDC Virtual COM port</p>
+ </td><td>
+ <p>As used on Xplained Mini boards</p>
+ </td></tr><tr><td>JTAGICE3</td><td>0x2140</td><td>
+ <p>Programming of all Atmel AVR devices using SPI, PDI, JTAG and aWire</p>
+ <p>Debugging of all Atmel AVR devices with on-chip debug capability using debugWIRE, PDI, JTAG and aWire</p>
+ <p>Programming and debugging of all Atmel SAMD, SAM3 and SAM4 devices using SWD and JTAG</p>
+ </td><td><p>FW version 3 and later</p></td></tr><tr><td>Atmel-ICE</td><td>0x2141</td><td>
+ <p>Programming of all Atmel AVR devices using SPI, TPI, PDI, JTAG and aWire</p>
+ <p>Debugging of all Atmel AVR devices with on-chip debug capability using debugWIRE, PDI, JTAG and aWire</p>
+ <p>Programming and debugging of all Atmel SAMD, SAM3 and SAM4 devices using SWD and JTAG</p>
+ </td><td>&nbsp;</td></tr></tbody></table></div></div><br class="table-break" /><p>Note that capability of each implementation should be queried from the tool itself rather than based upon the lists here.</p><p>Future Atmel standalone debuggers will also implement the same CMSIS-DAP based protocol as
+ described here.</p><p>JTAGICE3 (FW version 2 and earlier) implements a custom USB interface which is no
+ longer supported.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch01s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.Introduction.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="protocoldocs.cmsis_dap.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s01.html
new file mode 100644
index 000000000..234c40886
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s01.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>CMSIS-DAP protocol - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.cmsis_dap.html" title="CMSIS-DAP" /><link rel="prev" href="protocoldocs.cmsis_dap.html" title="CMSIS-DAP" /><link rel="next" href="ch02s02.html" title="CMSIS-DAP vendor commands" /><meta content="CMSIS-DAP protocol" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />CMSIS-DAP</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="protocoldocs.cmsis_dap.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.cmsis_dap.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N100E3" />CMSIS-DAP protocol</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml"> The CMSIS-DAP protocol belongs to ARM. Further information can be found at <a xmlns="http://www.w3.org/1999/xhtml" class="link" href="http://www.keil.com/support/man/docs/dapdebug/" target="_top">Keil</a>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="protocoldocs.cmsis_dap.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.cmsis_dap.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02.html
new file mode 100644
index 000000000..1ae5aac6a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>CMSIS-DAP vendor commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.cmsis_dap.html" title="CMSIS-DAP" /><link rel="prev" href="ch02s01.html" title="CMSIS-DAP protocol" /><link rel="next" href="ch02s02s01.html" title="AVR-target specific vendor commands" /><meta content="CMSIS-DAP vendor commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />CMSIS-DAP</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.cmsis_dap.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s02s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N100ED" />CMSIS-DAP vendor commands</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch02s02s01.html">AVR-target specific vendor commands</a></span></dt><dt><span class="section"><a href="ch02s02s02.html">ARM-target specific vendor commands</a></span></dt><dt><span class="section"><a href="ch02s02s03.html">EDBG-specific vendor commands</a></span></dt></dl></div><p>The CMSIS-DAP protocol contains a section of "vendor commands" which are free to use for
+ performing special functions. This section defines the vendor commands used by EDBG-based
+ tools.</p><p>A summary of vendor commands is given here:</p><div class="table"><a id="N100F5" /><p class="title"><strong>Table&nbsp;2.&nbsp;Vendor command summary</strong></p><div class="table-contents"><table summary="Vendor command summary" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>ID value</th><th>Command</th><th>Usage</th><th>Description</th></tr></thead><tbody><tr><td>0x80</td><td>AVR_CMD</td><td>AVR</td><td>Enveloped AVR protocol command</td></tr><tr><td>0x81</td><td>AVR_RSP</td><td>AVR</td><td>Enveloped AVR protocol response poll</td></tr><tr><td>0x82</td><td>AVR_EVT</td><td>AVR</td><td>Enveloped AVR protocol event poll</td></tr><tr><td>0x83</td><td>GET_CONFIG</td><td>EDBG</td><td>Retrieve EDBG board configuration</td></tr><tr><td>0x84</td><td>SET_CONFIG</td><td>EDBG</td><td>Set EDBG board configuration (only on HHB suffixed parts)</td></tr><tr><td>0x85</td><td>RESET</td><td>ARM</td><td>Perform custom reset sequence</td></tr><tr><td>0x86</td><td>ERASE_PIN</td><td>ARM/EDBG</td><td>Control the erase pin</td></tr><tr><td>0x87</td><td>SERIAL_TRACE</td><td>ARM</td><td>Serial trace capture commands</td></tr><tr><td>0x88</td><td>GET_REQUEST</td><td>EDBG</td><td>Enveloped EDBG GET command</td></tr><tr><td>0x89</td><td>SET_REQUEST</td><td>EDBG</td><td>Enveloped EDBG SET command</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.cmsis_dap.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s02s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s01.html
new file mode 100644
index 000000000..ab2191d46
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>AVR-target specific vendor commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s02.html" title="CMSIS-DAP vendor commands" /><link rel="prev" href="ch02s02.html" title="CMSIS-DAP vendor commands" /><link rel="next" href="ch02s02s02.html" title="ARM-target specific vendor commands" /><meta content="AVR-target specific vendor commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />CMSIS-DAP vendor commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s02s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1016C" />AVR-target specific vendor commands</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N1016F" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;3.&nbsp;AVR vendor-commands</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="AVR vendor-commands" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Command</th><th>ID value</th><th>Description</th></tr></thead><tbody><tr><td>AVR_CMD</td><td>0x80</td><td>Send enveloped AVR-specific protocol command</td></tr><tr><td>AVR_RSP</td><td>0x81</td><td>Retrieve (poll for) enveloped AVR-specific protocol response</td></tr><tr><td>AVR_EVT</td><td>0x82</td><td>Poll for enveloped AVR-specific protocol event</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s02s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02.html
new file mode 100644
index 000000000..0396afd8b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>ARM-target specific vendor commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s02.html" title="CMSIS-DAP vendor commands" /><link rel="prev" href="ch02s02s01.html" title="AVR-target specific vendor commands" /><link rel="next" href="ch02s02s02s01.html" title="Erase pin" /><meta content="ARM-target specific vendor commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />CMSIS-DAP vendor commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s02s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s02s02s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1019C" />ARM-target specific vendor commands</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch02s02s02s01.html">Erase pin</a></span></dt><dt><span class="section"><a href="ch02s02s02s02.html">Serial trace</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s02s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s02s02s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02s01.html
new file mode 100644
index 000000000..94e442177
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02s01.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Erase pin - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s02s02.html" title="ARM-target specific vendor commands" /><link rel="prev" href="ch02s02s02.html" title="ARM-target specific vendor commands" /><link rel="next" href="ch02s02s02s02.html" title="Serial trace" /><meta content="Erase pin" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />ARM-target specific vendor commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s02s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s02s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s02s02s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1019F" />Erase pin</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Pulses the ERASE pin high for about 300ms. Required by some SAM devices to gain
+ access when the device is secured. EDBG only.</p><div class="table"><a id="N101A4" /><p class="title"><strong>Table&nbsp;4.&nbsp;Erase pin command</strong></p><div class="table-contents"><table summary="Erase pin command" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>ERASE_PIN</td><td>1 byte</td><td>0x86</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N101C5" /><p class="title"><strong>Table&nbsp;5.&nbsp;Custom erase response</strong></p><div class="table-contents"><table summary="Custom erase response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>ERASE_PIN</td><td>1 byte</td><td>0x86</td></tr><tr><td>Status</td><td>1 byte</td><td><p>0x00: success</p><p>0x01: failed</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s02s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s02s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s02s02s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02s02.html
new file mode 100644
index 000000000..443f008f0
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s02s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Serial trace - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s02s02.html" title="ARM-target specific vendor commands" /><link rel="prev" href="ch02s02s02s01.html" title="Erase pin" /><link rel="next" href="ch02s02s03.html" title="EDBG-specific vendor commands" /><meta content="Serial trace" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />ARM-target specific vendor commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s02s02s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s02s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s02s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N101EF" />Serial trace</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Provides access to ITM trace output from an ARM device's SWO pin</p><p>For more details on the serial trace protocol API, see <a class="xref" href="section_serial_trace.html" title="Serial trace commands">the section called &ldquo;Serial trace commands&rdquo;</a></p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s02s02s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s02s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s02s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03.html
new file mode 100644
index 000000000..ce86f07b8
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>EDBG-specific vendor commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s02.html" title="CMSIS-DAP vendor commands" /><link rel="prev" href="ch02s02s02s02.html" title="Serial trace" /><link rel="next" href="ch02s02s03s01.html" title="Get configuration" /><meta content="EDBG-specific vendor commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />CMSIS-DAP vendor commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s02s02s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s02s03s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N101F9" />EDBG-specific vendor commands</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch02s02s03s01.html">Get configuration</a></span></dt><dt><span class="section"><a href="ch02s02s03s02.html">Set configuration</a></span></dt><dt><span class="section"><a href="ch02s02s03s03.html">EDBG GET request</a></span></dt><dt><span class="section"><a href="ch02s02s03s04.html">EDBG SET request</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s02s02s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s02s03s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s01.html
new file mode 100644
index 000000000..666fa6f3b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Get configuration - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s02s03.html" title="EDBG-specific vendor commands" /><link rel="prev" href="ch02s02s03.html" title="EDBG-specific vendor commands" /><link rel="next" href="ch02s02s03s02.html" title="Set configuration" /><meta content="Get configuration" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />EDBG-specific vendor commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s02s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s02s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s02s03s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N101FC" />Get configuration</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Retrieves board configuration information. EDBG only.</p><div class="table"><a id="N10201" /><p class="title"><strong>Table&nbsp;6.&nbsp;Get configuration command</strong></p><div class="table-contents"><table summary="Get configuration command" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>GET_CONFIG</td><td>1 byte</td><td>0x83</td></tr><tr><td>Count</td><td>1 byte</td><td>Number of configuration packets to retrieve</td></tr><tr><td>ConfigID</td><td>1 byte</td><td>Starting configuration packet ID</td></tr><tr><td>Parameter</td><td>1 byte</td><td>Config packet dependant parameter</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N10237" /><p class="title"><strong>Table&nbsp;7.&nbsp;Get configuration response</strong></p><div class="table-contents"><table summary="Get configuration response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>GET_CONFIG</td><td>1 byte</td><td>0x83</td></tr><tr><td>Status</td><td>1 byte</td><td><p>0x00: success</p><p>other values: failed</p></td></tr><tr><td>NumBytes</td><td>2 byte, MSB first</td><td>Number of bytes of config packet data</td></tr><tr><td>ConfigPackets</td><td>N bytes</td><td>Configuration data returned</td></tr></tbody></table></div></div><br class="table-break" /><p>Configuration packet format is described here:</p><div class="table"><a id="N10270" /><p class="title"><strong>Table&nbsp;8.&nbsp;Configuration packet format (get)</strong></p><div class="table-contents"><table summary="Configuration packet format (get)" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>ConfigID</td><td>1 byte</td><td>Configuration ID</td></tr><tr><td>DataType</td><td>1 byte</td><td>Datatype of the configuration parameter</td></tr><tr><td>Data</td><td>N bytes</td><td>Configuration data according to the data type</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s02s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s02s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s02s03s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s02.html
new file mode 100644
index 000000000..f513f9656
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Set configuration - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s02s03.html" title="EDBG-specific vendor commands" /><link rel="prev" href="ch02s02s03s01.html" title="Get configuration" /><link rel="next" href="ch02s02s03s03.html" title="EDBG GET request" /><meta content="Set configuration" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />EDBG-specific vendor commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s02s03s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s02s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s02s03s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1029D" />Set configuration</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Sets board configuration parameters. Will only work with devices with HHB suffix.</p><div class="table"><a id="N102A2" /><p class="title"><strong>Table&nbsp;9.&nbsp;Set configuration command</strong></p><div class="table-contents"><table summary="Set configuration command" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SET_CONFIG</td><td>1 byte</td><td>0x84</td></tr><tr><td>Count</td><td>1 byte</td><td>Number of bytes to write</td></tr><tr><td>ConfigID</td><td>1 byte</td><td>Configuration packet ID</td></tr><tr><td>Data</td><td>N bytes</td><td>Configuration data</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N102D8" /><p class="title"><strong>Table&nbsp;10.&nbsp;Set configuration response</strong></p><div class="table-contents"><table summary="Set configuration response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SET_CONFIG</td><td>1 byte</td><td>0x84</td></tr><tr><td>Status</td><td>1 byte</td><td><p>0x00: success</p><p>other values: failed</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s02s03s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s02s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s02s03s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s03.html
new file mode 100644
index 000000000..feb2e2aff
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s03.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>EDBG GET request - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s02s03.html" title="EDBG-specific vendor commands" /><link rel="prev" href="ch02s02s03s02.html" title="Set configuration" /><link rel="next" href="ch02s02s03s04.html" title="EDBG SET request" /><meta content="EDBG GET request" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />EDBG-specific vendor commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s02s03s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s02s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s02s03s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10301" />EDBG GET request</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Maps directly to EDBG_GET on the EDBGCTRL protocol</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s02s03s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s02s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s02s03s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s04.html
new file mode 100644
index 000000000..0ad83b637
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s02s03s04.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>EDBG SET request - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s02s03.html" title="EDBG-specific vendor commands" /><link rel="prev" href="ch02s02s03s03.html" title="EDBG GET request" /><link rel="next" href="section_serial_trace.html" title="Serial trace commands" /><meta content="EDBG SET request" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />EDBG-specific vendor commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s02s03s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s02s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_serial_trace.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10306" />EDBG SET request</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Maps directly to EDBG_SET on the EDBGCTRL protocol</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s02s03s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s02s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_serial_trace.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s01.html
new file mode 100644
index 000000000..69c34b0a0
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s01.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Set transport mode - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_serial_trace.html" title="Serial trace commands" /><link rel="prev" href="section_serial_trace.html" title="Serial trace commands" /><link rel="next" href="ch02s03s02.html" title="Set capture mode" /><meta content="Set transport mode" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Serial trace commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_serial_trace.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_serial_trace.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s03s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10315" />Set transport mode</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Sets the transport mode for sending data from the hardware tool to the host computer.
+ Currently only HID transport is supported.</p><div class="table"><a id="N1031A" /><p class="title"><strong>Table&nbsp;11.&nbsp;Set transport mode</strong></p><div class="table-contents"><table summary="Set transport mode" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>SET_TRANSPORT_MODE</td><td>1 byte</td><td>0x00</td></tr><tr><td>Mode</td><td>1 byte</td><td><p>Transport mode to transfer data to host PC</p>
+ <p>0x00: OFF (default)</p><p>0x01: HID</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N1034F" /><p class="title"><strong>Table&nbsp;12.&nbsp;Set transport mode response</strong></p><div class="table-contents"><table summary="Set transport mode response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>SET_TRANSPORT_MODE</td><td>1 byte</td><td>0x00</td></tr><tr><td>Status</td><td>1 byte</td><td><p>Status code</p>
+ <p>0x00: OK</p><p>0xFF: Error</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_serial_trace.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_serial_trace.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s03s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s02.html
new file mode 100644
index 000000000..df5f82436
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s02.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Set capture mode - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_serial_trace.html" title="Serial trace commands" /><link rel="prev" href="ch02s03s01.html" title="Set transport mode" /><link rel="next" href="ch02s03s03.html" title="Set baud rate" /><meta content="Set capture mode" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Serial trace commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s03s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_serial_trace.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s03s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10382" />Set capture mode</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Sets the capture mode for sampling data sent from the target. Currently only UART is
+ supported.</p><div class="table"><a id="N10387" /><p class="title"><strong>Table&nbsp;13.&nbsp;Set capture mode</strong></p><div class="table-contents"><table summary="Set capture mode" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>SET_CAPTURE_MODE</td><td>1 byte</td><td>0x01</td></tr><tr><td>Mode</td><td>1 byte</td><td><p>Capture mode for incoming data</p>
+ <p>0x00: OFF (default)</p><p>0x02: UART</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N103BC" /><p class="title"><strong>Table&nbsp;14.&nbsp;Set capture mode response</strong></p><div class="table-contents"><table summary="Set capture mode response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>SET_CAPTURE_MODE</td><td>1 byte</td><td>0x01</td></tr><tr><td>Status</td><td>1 byte</td><td><p>Status code</p>
+ <p>0x00: OK</p><p>0xFF: Error</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s03s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_serial_trace.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s03s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s03.html
new file mode 100644
index 000000000..60e231822
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s03.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Set baud rate - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_serial_trace.html" title="Serial trace commands" /><link rel="prev" href="ch02s03s02.html" title="Set capture mode" /><link rel="next" href="ch02s03s04.html" title="Start" /><meta content="Set baud rate" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Serial trace commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s03s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_serial_trace.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s03s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N103EF" />Set baud rate</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Sets the baud rate for capturing data. Can be called iteratively to build a table of
+ supported baud-rates which can be sampled by the hardware.</p><div class="table"><a id="N103F4" /><p class="title"><strong>Table&nbsp;15.&nbsp;Set baud rate</strong></p><div class="table-contents"><table summary="Set baud rate" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>SET_BAUD</td><td>1 byte</td><td>0x02</td></tr><tr><td>Baud</td><td>4 bytes, MSB first</td><td>Requested baud rate</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N10423" /><p class="title"><strong>Table&nbsp;16.&nbsp;Set baud rate response</strong></p><div class="table-contents"><table summary="Set baud rate response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>SET_BAUD</td><td>1 byte</td><td>0x02</td></tr><tr><td>Baud</td><td>4 bytes, MSB first</td><td>Actual baud rate achievable</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s03s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_serial_trace.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s03s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s04.html
new file mode 100644
index 000000000..ca57b115e
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s04.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Start - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_serial_trace.html" title="Serial trace commands" /><link rel="prev" href="ch02s03s03.html" title="Set baud rate" /><link rel="next" href="ch02s03s05.html" title="Stop" /><meta content="Start" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Serial trace commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s03s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_serial_trace.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s03s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10450" />Start</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Starts the data capture</p><div class="table"><a id="N10455" /><p class="title"><strong>Table&nbsp;17.&nbsp;Start</strong></p><div class="table-contents"><table summary="Start" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>START</td><td>1 byte</td><td>0x03</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N1047D" /><p class="title"><strong>Table&nbsp;18.&nbsp;Start response</strong></p><div class="table-contents"><table summary="Start response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>START</td><td>1 byte</td><td>0x03</td></tr><tr><td>Status</td><td>1 byte</td><td><p>Status code</p>
+ <p>0x00: OK</p><p>0xFF: Error</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s03s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_serial_trace.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s03s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s05.html
new file mode 100644
index 000000000..8fdf2a10a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s05.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Stop - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_serial_trace.html" title="Serial trace commands" /><link rel="prev" href="ch02s03s04.html" title="Start" /><link rel="next" href="ch02s03s06.html" title="Get data" /><meta content="Stop" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Serial trace commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s03s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_serial_trace.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s03s06.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N104B0" />Stop</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Stops the data capture</p><div class="table"><a id="N104B5" /><p class="title"><strong>Table&nbsp;19.&nbsp;Stop</strong></p><div class="table-contents"><table summary="Stop" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>STOP</td><td>1 byte</td><td>0x04</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N104DD" /><p class="title"><strong>Table&nbsp;20.&nbsp;Stop response</strong></p><div class="table-contents"><table summary="Stop response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>STOP</td><td>1 byte</td><td>0x04</td></tr><tr><td>Status</td><td>1 byte</td><td><p>Status code</p>
+ <p>0x00: OK</p><p>0xFF: Error</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s03s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_serial_trace.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s03s06.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s06.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s06.html
new file mode 100644
index 000000000..b18020202
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s06.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Get data - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_serial_trace.html" title="Serial trace commands" /><link rel="prev" href="ch02s03s05.html" title="Stop" /><link rel="next" href="ch02s03s07.html" title="Get status" /><meta content="Get data" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Serial trace commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s03s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_serial_trace.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s03s07.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10511" />Get data</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Retrieves captured data along with status information. Note that up to 508 bytes can
+ be retrieved at a time.</p><div class="table"><a id="N10516" /><p class="title"><strong>Table&nbsp;21.&nbsp;Get data</strong></p><div class="table-contents"><table summary="Get data" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>GET_DATA</td><td>1 byte</td><td>0x08</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N1053E" /><p class="title"><strong>Table&nbsp;22.&nbsp;Get data response</strong></p><div class="table-contents"><table summary="Get data response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>GET_DATA</td><td>1 byte</td><td>0x08</td></tr><tr><td>STATUS</td><td>2 bytes, MSB first</td><td><p>Status encoding</p>
+ <p>Bit 15: overrun error (buffer not read fast enough)</p>
+ <p>Bit 14: receive error (framing or baud rate error)</p>
+ <p>Bit 9: receive disabled (receiver has been disabled)</p>
+ <p>Bits 8..0: number of data bytes received</p></td></tr><tr><td>DATA</td><td>N bytes</td><td>Data streamed from the target device</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s03s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_serial_trace.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s03s07.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s07.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s07.html
new file mode 100644
index 000000000..3f894396e
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s07.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Get status - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_serial_trace.html" title="Serial trace commands" /><link rel="prev" href="ch02s03s06.html" title="Get data" /><link rel="next" href="ch02s03s08.html" title="Get buffer size" /><meta content="Get status" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Serial trace commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s03s06.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_serial_trace.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s03s08.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1057F" />Get status</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads out status information.</p><div class="table"><a id="N10584" /><p class="title"><strong>Table&nbsp;23.&nbsp;Get status</strong></p><div class="table-contents"><table summary="Get status" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>GET_STATUS</td><td>1 byte</td><td>0x09</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N105AC" /><p class="title"><strong>Table&nbsp;24.&nbsp;Get status response</strong></p><div class="table-contents"><table summary="Get status response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>GET_STATUS</td><td>1 byte</td><td>0x09</td></tr><tr><td>STATUS</td><td>1 byte</td><td><p>Status encoding</p>
+ <p>Bit 7: overrun error (buffer not read fast enough)</p>
+ <p>Bit 6: receive error (framing or baud rate error)</p>
+ <p>Bit 1: receive disabled (receiver has been disabled)</p></td></tr><tr><td>BYTES</td><td>2 byte, MSB first</td><td>Number of bytes available to read</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s03s06.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_serial_trace.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s03s08.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s08.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s08.html
new file mode 100644
index 000000000..01fda3281
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s08.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Get buffer size - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_serial_trace.html" title="Serial trace commands" /><link rel="prev" href="ch02s03s07.html" title="Get status" /><link rel="next" href="ch02s03s09.html" title="Signon" /><meta content="Get buffer size" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Serial trace commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s03s07.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_serial_trace.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s03s09.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N105EA" />Get buffer size</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads out the buffer size available on the hardware.</p><div class="table"><a id="N105EF" /><p class="title"><strong>Table&nbsp;25.&nbsp;Get buffer size</strong></p><div class="table-contents"><table summary="Get buffer size" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>GET_BUFFER_SIZE</td><td>1 byte</td><td>0x0A</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N10617" /><p class="title"><strong>Table&nbsp;26.&nbsp;Get buffer size response</strong></p><div class="table-contents"><table summary="Get buffer size response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>GET_BUFFER_SIZE</td><td>1 byte</td><td>0x0A</td></tr><tr><td>Buffer size</td><td>4 bytes, MSB first</td><td>Total size of receive buffer</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s03s07.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_serial_trace.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s03s09.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s09.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s09.html
new file mode 100644
index 000000000..7508ace3f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s03s09.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Signon - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_serial_trace.html" title="Serial trace commands" /><link rel="prev" href="ch02s03s08.html" title="Get buffer size" /><link rel="next" href="ch02s04.html" title="Enveloped AVR commands, responses &amp; events" /><meta content="Signon" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Serial trace commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s03s08.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_serial_trace.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10644" />Signon</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Used to check that serial trace is supoorted by the hardware.</p><div class="table"><a id="N10649" /><p class="title"><strong>Table&nbsp;27.&nbsp;Signon</strong></p><div class="table-contents"><table summary="Signon" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>SIGNON</td><td>1 byte</td><td>0x0F</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N10671" /><p class="title"><strong>Table&nbsp;28.&nbsp;Signon response</strong></p><div class="table-contents"><table summary="Signon response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SERIAL_TRACE</td><td>1 byte</td><td>0x87</td></tr><tr><td>SIGNON</td><td>1 byte</td><td>0x0F</td></tr><tr><td>Signon string</td><td>3 bytes</td><td>"OK\0"</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s03s08.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_serial_trace.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04.html
new file mode 100644
index 000000000..7f0e6c37a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Enveloped AVR commands, responses &amp; events - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.cmsis_dap.html" title="CMSIS-DAP" /><link rel="prev" href="ch02s03s09.html" title="Signon" /><link rel="next" href="ch02s04s01.html" title="Wrapping AVR commands" /><meta content="Enveloped AVR commands, responses &amp; events" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />CMSIS-DAP</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s03s09.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.cmsis_dap.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s04s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N1069E" />Enveloped AVR commands, responses &amp; events</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch02s04s01.html">Wrapping AVR commands</a></span></dt><dt><span class="section"><a href="ch02s04s02.html">Unwrapping AVR responses</a></span></dt><dt><span class="section"><a href="ch02s04s03.html">Unwrapping AVR events</a></span></dt></dl></div><p>In order to support programing and debugging AVR devices over the same interface as
+ ARM-based devices, three vendor commands are used. Commands are send using the AVR_CMD vendor
+ command. All commands are synchronous and result in one and only one response. The response is
+ however buffered on the tool and must be polled for using the AVR_RSP vendor command. Events
+ occur asynchronously to commands, and must be periodically polled for using the AVR_EVT vendor
+ command.</p><p>The AVR command set is described in <a class="xref" href="protocoldocs.avrprotocol.Overview.html" title="AVR communication protocol"><em>AVR communication protocol</em></a>.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s03s09.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.cmsis_dap.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s04s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s01.html
new file mode 100644
index 000000000..410b1cd2d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s01.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Wrapping AVR commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s04.html" title="Enveloped AVR commands, responses &amp; events" /><link rel="prev" href="ch02s04.html" title="Enveloped AVR commands, responses &amp; events" /><link rel="next" href="ch02s04s02.html" title="Unwrapping AVR responses" /><meta content="Wrapping AVR commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Enveloped AVR commands, responses &amp; events</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s04.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s04s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N106A9" />Wrapping AVR commands</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">So to SEND an AVR command to the EDBG, it is wrapped as:</p><div class="table"><a id="N106AE" /><p class="title"><strong>Table&nbsp;29.&nbsp;Wrapping AVR_CMD</strong></p><div class="table-contents"><table summary="Wrapping AVR_CMD" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR_CMD</td><td>1 byte</td><td>0x80</td></tr><tr><td>FragmentInfo</td><td>1 byte</td><td>Fragment number</td></tr><tr><td>Size</td><td>2 bytes, MSB first</td><td>Number of bytes in the wrapped AVR packet</td></tr><tr><td>CommandPacket</td><td>N bytes</td><td>Enveloped AVR packet</td></tr></tbody></table></div></div><br class="table-break" /><p>Large packets must be chopped up according to the HID interface&rsquo;s REPORT_SIZE. The
+ fragment number envelope field is two 4-bit nibbles indicating a "packet m of n packets"
+ relationship: </p><p>(packet_number &lt;&lt; 4) | total_number_of_packets</p><p>
+ Each SEND fragment responds with:</p><div class="table"><a id="N106E8" /><p class="title"><strong>Table&nbsp;30.&nbsp;Unwrapping AVR_CMD</strong></p><div class="table-contents"><table summary="Unwrapping AVR_CMD" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR_CMD</td><td>1 byte</td><td>0x80</td></tr><tr><td>FragmentCode</td><td>1 byte</td><td><p>0x00: More fragments required (m &lt; n)</p>
+ <p>0x01: Full packet received, will be processed (m == n)</p></td></tr></tbody></table></div></div><br class="table-break" /><p>This is not to be confused with the AVR_RSP, which is the response
+ to the command itself, which is detailed next.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s04.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s04s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s02.html
new file mode 100644
index 000000000..16c752df3
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s02.html
@@ -0,0 +1,218 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Unwrapping AVR responses - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s04.html" title="Enveloped AVR commands, responses &amp; events" /><link rel="prev" href="ch02s04s01.html" title="Wrapping AVR commands" /><link rel="next" href="ch02s04s03.html" title="Unwrapping AVR events" /><meta content="Unwrapping AVR responses" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Enveloped AVR commands, responses &amp; events</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s04s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s04.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s04s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10714" />Unwrapping AVR responses</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">To RECEIVE an AVR response from the EDBG, a AVR_RSP packet must be sent
+ (ie: polling for responses)</p><div class="table"><a id="N10719" /><p class="title"><strong>Table&nbsp;31.&nbsp;Wrapping AVR_RSP</strong></p><div class="table-contents"><table summary="Wrapping AVR_RSP" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR_RSP</td><td>1 byte</td><td>0x81</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The response to this send is:</p><div class="table"><a id="N1073A" /><p class="title"><strong>Table&nbsp;32.&nbsp;Unwrapping AVR_RSP</strong></p><div class="table-contents"><table summary="Unwrapping AVR_RSP" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR_RSP</td><td>1 byte</td><td>0x81</td></tr><tr><td>FragmentInfo</td><td>1 byte</td><td><p>0x00: More fragments required (m &lt; n)</p>
+ <p>0x01: Full packet received, will be processed (m == n)</p></td></tr><tr><td>Size</td><td>2 byte, MSB first</td><td>Number of response bytes</td></tr><tr><td>Response</td><td>N bytes</td><td>Enveloped AVR response</td></tr></tbody></table></div></div><br class="table-break" /><p>FragmentInfo 0x00 indicates that no response data is available,
+ and the rest of the packet is ignored.</p><p>Note that the "synchronous" nature of the AVR CMD-RSP functionality
+ must be preserved even when running over this CMSIS-DAP wrapper &ndash; this
+ means that every one command results in one and only one response, and
+ that response must be read out before the following command can be issued.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s04s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s04.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s04s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s03.html
new file mode 100644
index 000000000..012c91dcb
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch02s04s03.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Unwrapping AVR events - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch02s04.html" title="Enveloped AVR commands, responses &amp; events" /><link rel="prev" href="ch02s04s02.html" title="Unwrapping AVR responses" /><link rel="next" href="protocoldocs.edbg_ctrl_protocol.html" title="EDBG Control Protocol" /><meta content="Unwrapping AVR events" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Enveloped AVR commands, responses &amp; events</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s04s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch02s04.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="protocoldocs.edbg_ctrl_protocol.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10776" />Unwrapping AVR events</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">To RECEIVE an AVR event from the EDBG, a AVR_EVT packet must be sent
+ (ie: polling for events) in the same manner as described for responses.</p><div class="table"><a id="N1077B" /><p class="title"><strong>Table&nbsp;33.&nbsp;Wrapping AVR_EVT</strong></p><div class="table-contents"><table summary="Wrapping AVR_EVT" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR_EVT</td><td>1 byte</td><td>0x82</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The response to this send is:</p><div class="table"><a id="N1079C" /><p class="title"><strong>Table&nbsp;34.&nbsp;Unwrapping AVR_EVT</strong></p><div class="table-contents"><table summary="Unwrapping AVR_EVT" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR_EVT</td><td>1 byte</td><td>0x82</td></tr><tr><td>Size</td><td>2 byte, MSB first</td><td>Number of event bytes</td></tr><tr><td>Event</td><td>N bytes</td><td>Enveloped AVR event</td></tr></tbody></table></div></div><br class="table-break" /><p>Size of 0x0000 indicates that no event data is available,
+ and the rest of the packet is ignored.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s04s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch02s04.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="protocoldocs.edbg_ctrl_protocol.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01.html
new file mode 100644
index 000000000..6bd694495
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Protocol commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.edbg_ctrl_protocol.html" title="EDBG Control Protocol" /><link rel="prev" href="protocoldocs.edbg_ctrl_protocol.html" title="EDBG Control Protocol" /><link rel="next" href="ch03s01s01.html" title="QUERY" /><meta content="Protocol commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />EDBG Control Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="protocoldocs.edbg_ctrl_protocol.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.edbg_ctrl_protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch03s01s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N107D3" />Protocol commands</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch03s01s01.html">QUERY</a></span></dt><dt><span class="section"><a href="ch03s01s02.html">SET</a></span></dt><dt><span class="section"><a href="ch03s01s03.html">GET</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="protocoldocs.edbg_ctrl_protocol.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.edbg_ctrl_protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch03s01s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s01.html
new file mode 100644
index 000000000..1a5e37f0a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s01.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>QUERY - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch03s01.html" title="Protocol commands" /><link rel="prev" href="ch03s01.html" title="Protocol commands" /><link rel="next" href="section_edbg_query_contexts.html" title="EDBG QUERY contexts" /><meta content="QUERY" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch03s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch03s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_edbg_query_contexts.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N107D6" />QUERY</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></dt></dl></div><p>Used to discover the capabilities of the tool.</p><p>For lists of valid query types, see <a class="xref" href="section_edbg_query_contexts.html" title="EDBG QUERY contexts">the section called &ldquo;EDBG QUERY contexts&rdquo;</a></p><p>
+ </p><div class="table"><a id="N107E2" /><p class="title"><strong>Table&nbsp;35.&nbsp;Query</strong></p><div class="table-contents"><table summary="Query" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>QUERY (0x00)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Query context</td><td>1 byte</td><td>Type of query to execute</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>LIST</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch03s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch03s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_edbg_query_contexts.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html>
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s01.html~ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s01.html~
new file mode 100644
index 000000000..20b5c4514
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s01.html~
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>QUERY - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch03s01.html" title="Protocol commands" /><link rel="prev" href="ch03s01.html" title="Protocol commands" /><link rel="next" href="section_edbg_query_contexts.html" title="EDBG QUERY contexts" /><meta content="QUERY" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch03s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch03s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_edbg_query_contexts.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N107D6" />QUERY</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></dt></dl></div><p>Used to discover the capabilities of the tool.</p><p>For lists of valid query types, see <a class="xref" href="section_edbg_query_contexts.html" title="EDBG QUERY contexts">the section called &ldquo;EDBG QUERY contexts&rdquo;</a></p><p>
+ </p><div class="table"><a id="N107E2" /><p class="title"><strong>Table&nbsp;35.&nbsp;Query</strong></p><div class="table-contents"><table summary="Query" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>QUERY (0x00)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Query context</td><td>1 byte</td><td>Type of query to execute</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>LIST</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch03s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch03s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_edbg_query_contexts.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s02.html
new file mode 100644
index 000000000..dbb58ccee
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s02.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SET - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch03s01.html" title="Protocol commands" /><link rel="prev" href="section_edbg_query_contexts.html" title="EDBG QUERY contexts" /><link rel="next" href="ch03s01s03.html" title="GET" /><meta content="SET" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_edbg_query_contexts.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch03s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch03s01s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1083C" />SET</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Used to set parameters on the tool.</p><p>For lists of valid get / set paramters, see <a class="xref" href="section_edbg_ctrl_setget_params.html" title="EDBGCTRL ID definitions">the section called &ldquo;EDBGCTRL ID definitions&rdquo;</a>.</p><p>
+ </p><div class="table"><a id="N10849" /><p class="title"><strong>Table&nbsp;37.&nbsp;Set</strong></p><div class="table-contents"><table summary="Set" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SET (0x01)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Set context</td><td>1 byte</td><td>Context of the parameter to set</td></tr><tr><td>Address</td><td>1 byte</td><td>Parameter ID / start address</td></tr><tr><td>Bytes</td><td>1 byte</td><td>Number of bytes to write</td></tr><tr><td>Data</td><td>N bytes</td><td>Data to write</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p><p>Note: Setting multiple parameters in one set call can only be done when all fields
+ are in the same context.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_edbg_query_contexts.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch03s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch03s01s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s03.html
new file mode 100644
index 000000000..04fb2403d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s03.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>GET - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch03s01.html" title="Protocol commands" /><link rel="prev" href="ch03s01s02.html" title="SET" /><link rel="next" href="ch03s01s03s01.html" title="SET/GET parameters" /><meta content="GET" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch03s01s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch03s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch03s01s03s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10897" />GET</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch03s01s03s01.html">SET/GET parameters</a></span></dt></dl></div><p>Used to get parameters on the tool..</p><p>For lists of valid get / set paramters, see <a class="xref" href="section_edbg_ctrl_setget_params.html" title="EDBGCTRL ID definitions">the section called &ldquo;EDBGCTRL ID definitions&rdquo;</a>.</p><p>
+ </p><div class="table"><a id="N108A4" /><p class="title"><strong>Table&nbsp;38.&nbsp;Get</strong></p><div class="table-contents"><table summary="Get" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>GET (0x02)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Get context</td><td>1 byte</td><td>Context of the parameter to get</td></tr><tr><td>Address</td><td>1 byte</td><td>Parameter ID / start address</td></tr><tr><td>Bytes</td><td>1 byte</td><td>Number of bytes to read</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p><p>Note: Getting multiple parameters in one set call can only be done when all fields
+ are in the same context.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch03s01s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch03s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch03s01s03s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s03s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s03s01.html
new file mode 100644
index 000000000..37174b6cc
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s01s03s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SET/GET parameters - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch03s01s03.html" title="GET" /><link rel="prev" href="ch03s01s03.html" title="GET" /><link rel="next" href="ch03s02.html" title="Responses" /><meta content="SET/GET parameters" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />GET</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch03s01s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch03s01s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch03s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N108EB" />SET/GET parameters</h4></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N108EE" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;39.&nbsp;EDBG SET/GET parameters</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="EDBG SET/GET parameters" border="1"><colgroup><col /><col /><col /><col /><col /></colgroup><thead><tr><th>Context</th><th>ID</th><th>Description</th><th>Acc</th><th>Size</th></tr></thead><tbody><tr><td rowspan="3">EDBG_CTXT_CTRL</td><td>EDBG_CTRL_LED_USAGE</td><td><p>Enables or disables LED usage (for power saving).</p><p>0x00: LEDs disabled</p><p>0x01: LEDs enabled</p></td><td>RW</td><td>1 byte</td></tr><tr><td>EDBG_CTRL_EXT_PROG</td><td><p>Enables or disables the external debug interface, if present.</p><p>0x00: external interface disabled</p><p>0x01: external interface enabled</p></td><td>RW</td><td>1 byte </td></tr><tr><td>EDBG_CTRL_TARGET_POWER</td><td><p>Enables or disables power for target device, if present.</p><p>0x00: power disabled</p><p>0x01: power enabled</p></td><td>RW</td><td>1 byte </td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch03s01s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch03s01s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch03s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02.html
new file mode 100644
index 000000000..2716e63a4
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Responses - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.edbg_ctrl_protocol.html" title="EDBG Control Protocol" /><link rel="prev" href="ch03s01s03s01.html" title="SET/GET parameters" /><link rel="next" href="ch03s02s01.html" title="OK" /><meta content="Responses" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />EDBG Control Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch03s01s03s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.edbg_ctrl_protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch03s02s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N10937" />Responses</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch03s02s01.html">OK</a></span></dt><dt><span class="section"><a href="ch03s02s02.html">LIST</a></span></dt><dt><span class="section"><a href="ch03s02s03.html">DATA</a></span></dt><dt><span class="section"><a href="ch03s02s04.html">FAILED</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch03s01s03s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.edbg_ctrl_protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch03s02s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s01.html
new file mode 100644
index 000000000..11e766ec2
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>OK - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch03s02.html" title="Responses" /><link rel="prev" href="ch03s02.html" title="Responses" /><link rel="next" href="ch03s02s02.html" title="LIST" /><meta content="OK" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch03s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch03s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch03s02s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1093A" />OK</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The command was executed successfully</p><div class="table"><a id="N1093F" /><p class="title"><strong>Table&nbsp;40.&nbsp;OK response format</strong></p><div class="table-contents"><table summary="OK response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>EDBG_RSP_OK</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch03s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch03s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch03s02s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s02.html
new file mode 100644
index 000000000..fee95a4d4
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>LIST - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch03s02.html" title="Responses" /><link rel="prev" href="ch03s02s01.html" title="OK" /><link rel="next" href="ch03s02s03.html" title="DATA" /><meta content="LIST" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch03s02s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch03s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch03s02s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10962" />LIST</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">List of data returned</p><div class="table"><a id="N10967" /><p class="title"><strong>Table&nbsp;41.&nbsp;LIST response format</strong></p><div class="table-contents"><table summary="LIST response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>EDBG_RSP_LIST</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version</td><td>1 byte</td><td>Response version</td></tr><tr><td>Data (0x00)</td><td>n bytes</td><td>Data returned</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch03s02s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch03s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch03s02s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s03.html
new file mode 100644
index 000000000..a5f5ea0ae
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s03.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>DATA - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch03s02.html" title="Responses" /><link rel="prev" href="ch03s02s02.html" title="LIST" /><link rel="next" href="ch03s02s04.html" title="FAILED" /><meta content="DATA" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch03s02s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch03s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch03s02s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10991" />DATA</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Data is returned.</p><div class="table"><a id="N10996" /><p class="title"><strong>Table&nbsp;42.&nbsp;DATA response format version 0</strong></p><div class="table-contents"><table summary="DATA response format version 0" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>EDBG_RSP_DATA</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version</td><td>1 byte</td><td>Response version</td></tr><tr><td>Data (0x01)</td><td>n bytes</td><td>Data returned</td></tr><tr><td>Status code</td><td>1 byte</td><td>Trailing status of the read operation indicating whether
+ the data returned is in fact valid. 0x00 = OK.</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch03s02s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch03s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch03s02s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s04.html
new file mode 100644
index 000000000..be4e8e65a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch03s02s04.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>FAILED - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch03s02.html" title="Responses" /><link rel="prev" href="ch03s02s03.html" title="DATA" /><link rel="next" href="section_edbg_ctrl_setget_params.html" title="EDBGCTRL ID definitions" /><meta content="FAILED" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch03s02s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch03s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_edbg_ctrl_setget_params.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N109C7" />FAILED</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The command failed to execute</p><div class="table"><a id="N109CC" /><p class="title"><strong>Table&nbsp;43.&nbsp;FAILED response format</strong></p><div class="table-contents"><table summary="FAILED response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>EDBG_RSP_FAILED</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr><tr><td>Failure Code</td><td>1 byte</td><td>Instance code for failure; 0xFF = unknown</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch03s02s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch03s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_edbg_ctrl_setget_params.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s01.html
new file mode 100644
index 000000000..661b07998
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s01.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Overview - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avrprotocol.Overview.html" title="AVR communication protocol" /><link rel="prev" href="protocoldocs.avrprotocol.Overview.html" title="AVR communication protocol" /><link rel="next" href="ch04s02.html" title="Framing" /><meta content="Overview" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR communication protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="protocoldocs.avrprotocol.Overview.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avrprotocol.Overview.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N10A06" />Overview</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The communication protocol of the AVR functionality of EDBG is based on sub-protocols
+ which may or may not be available depending upon the physical capabilities of the tool. </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="protocoldocs.avrprotocol.Overview.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avrprotocol.Overview.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s02.html
new file mode 100644
index 000000000..928910efc
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s02.html
@@ -0,0 +1,228 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Framing - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avrprotocol.Overview.html" title="AVR communication protocol" /><link rel="prev" href="ch04s01.html" title="Overview" /><link rel="next" href="ch04s03.html" title="Protocol sub-set overview" /><meta content="Framing" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR communication protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avrprotocol.Overview.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N10A0B" />Framing</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">This section outlines the general frame format used by all sub-protocols.</p><p>The protocol handler ID field identifies which sub-protocol to decode the packet
+ by, and this which command handler to forward the packet to. </p><p>In general, <code class="code">ID == 0x00</code> is used as a &ldquo;query&rdquo; function in order for
+ the host to &ldquo;discover&rdquo; the feature set of the tool. </p><p>
+ </p><div class="table"><a id="N10A19" /><p class="title"><strong>Table&nbsp;44.&nbsp;Command frame format</strong></p><div class="table-contents"><table summary="Command frame format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Value</th></tr></thead><tbody><tr><td>SOF</td><td>1 byte</td><td>0x0E</td></tr><tr><td>Protocol version</td><td>1 byte</td><td>0x00 in this version (all packets)</td></tr><tr><td>Sequence ID</td><td>2 bytes</td><td>Incrementing from 0x00 (least significant byte sent first)</td></tr><tr><td>Protocol handler ID</td><td>1 byte</td><td>Destination sub-protocol handler ID</td></tr><tr><td>Payload</td><td>N bytes</td><td>Data</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>
+ </p><div class="table"><a id="N10A54" /><p class="title"><strong>Table&nbsp;45.&nbsp;Response frame format</strong></p><div class="table-contents"><table summary="Response frame format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Value</th></tr></thead><tbody><tr><td>SOF</td><td>1 byte</td><td>0x0E</td></tr><tr><td>Sequence ID</td><td>2 bytes</td><td>Echo of incoming ID (least significant byte sent first)</td></tr><tr><td>Protocol handler ID</td><td>1 byte</td><td>Source sub-protocol handler ID</td></tr><tr><td>Payload</td><td>N bytes</td><td>Data</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>
+ </p><div class="table"><a id="N10A88" /><p class="title"><strong>Table&nbsp;46.&nbsp;Event frame format</strong></p><div class="table-contents"><table summary="Event frame format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Value</th></tr></thead><tbody><tr><td>SOF</td><td>1 byte</td><td>0x0E</td></tr><tr><td>Protocol version</td><td>1 byte</td><td>0x00 in this version (all packets)</td></tr><tr><td>Sequence ID</td><td>2 bytes</td><td>Incrementing from 0x00 (least significant byte sent first)</td></tr><tr><td>Protocol handler ID</td><td>1 byte</td><td>Source sub-protocol handler ID</td></tr><tr><td>Payload</td><td>N bytes</td><td>Data</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>The protocol handler ID field identifies which sub-protocol to decode the packet
+ by, and this which command handler to forward the packet to. </p><p>In general, <code class="code">ID == 0x00</code> is used as a &ldquo;query&rdquo; function in order for
+ the host to &ldquo;discover&rdquo; the feature set of the tool. </p><p>If there is a condition where the EDBG AVR command handler expects more data
+ for a command than is available, then the next incoming command will be rejected and an
+ error response (<code class="code">RSP_FAILED</code> with failure code
+ <code class="code">FAILURE_USB_PREVIOUS_UNDERRUN</code>) will be returned . Note that such an
+ underrun situation will result in unknown values for the parameters of the failing
+ command and the host will have to do the necessary cleanup to undo any undesired
+ behaviour. The underrun error reporting is done by transport layer and is independent of
+ the sub-protocol being used.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avrprotocol.Overview.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s03.html
new file mode 100644
index 000000000..4fd01391c
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s03.html
@@ -0,0 +1,218 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Protocol sub-set overview - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avrprotocol.Overview.html" title="AVR communication protocol" /><link rel="prev" href="ch04s02.html" title="Framing" /><link rel="next" href="ch04s04.html" title="Discovery Protocol Definition" /><meta content="Protocol sub-set overview" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR communication protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avrprotocol.Overview.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N10AD0" />Protocol sub-set overview</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">One or more of the sub-protocols listed in the table below may be implemented by
+ EDBG. Each one implements its own command handler, and is self-contained in terms of
+ configuration parameters. Which protocol to use is given by the ID being put into the
+ "Protocol handler ID" field in the main frame format. Then the command or response
+ follows as the "Payload" field in the main frame format. </p><p>
+ </p><div class="table"><a id="N10AD7" /><p class="title"><strong>Table&nbsp;47.&nbsp;Protocol sub-sets</strong></p><div class="table-contents"><table summary="Protocol sub-sets" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>ID</th><th>Name</th><th>Description</th></tr></thead><tbody><tr><td>0x00</td><td>DISCOVERY</td><td>For discovering the feature set of the tool</td></tr><tr><td>0x01</td><td>HOUSEKEEPING (HK)</td><td>Housekeeping functions</td></tr><tr><td>0x11</td><td>AVRISP</td><td>Programming of tinyAVR and megaAVR using AVRISP commands (SPI-based programming)</td></tr><tr><td>0x12</td><td>AVR8GENERIC</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Debugging of tinyAVR using debugWIRE</p></li><li class="listitem"><p>Programming and debugging of megaAVR and XMEGA using JTAG and PDI</p></li></ul></div></td></tr><tr><td>0x13</td><td>AVR32GENERIC</td><td>Programming and debugging of AVR UC3 32-bit microcontrollers
+ using JTAG and aWire</td></tr><tr><td>0x14</td><td>TPI</td><td>Programming of tinyAVR devices using TPI</td></tr><tr><td>0x20</td><td>EDBG_CTRL</td><td>Control and configuration of EDBG</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avrprotocol.Overview.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04.html
new file mode 100644
index 000000000..0a5ee21bf
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Discovery Protocol Definition - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avrprotocol.Overview.html" title="AVR communication protocol" /><link rel="prev" href="ch04s03.html" title="Protocol sub-set overview" /><link rel="next" href="ch04s04s01.html" title="CMD: QUERY" /><meta content="Discovery Protocol Definition" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR communication protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avrprotocol.Overview.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s04s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N10B24" />Discovery Protocol Definition</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch04s04s01.html">CMD: QUERY</a></span></dt><dt><span class="section"><a href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></dt><dt><span class="section"><a href="ch04s04s03.html">RSP: LIST</a></span></dt><dt><span class="section"><a href="ch04s04s04.html">RSP: FAILED</a></span></dt><dt><span class="section"><a href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></dt></dl></div><p>The discovery handler only supports the QUERY command. It is used to interrogate
+ the tool for its supported functionality and other fixed information.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avrprotocol.Overview.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s04s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s01.html
new file mode 100644
index 000000000..5604043c7
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s01.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>CMD: QUERY - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s04.html" title="Discovery Protocol Definition" /><link rel="prev" href="ch04s04.html" title="Discovery Protocol Definition" /><link rel="next" href="section_jdx_m11_sl.html" title="Discovery QUERY contexts" /><meta content="CMD: QUERY" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Discovery Protocol Definition</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s04.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_jdx_m11_sl.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10B29" />CMD: QUERY</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Used to discover the capabilities of the tool.</p><p>For lists of valid query types, see <a class="xref" href="section_jdx_m11_sl.html" title="Discovery QUERY contexts">the section called &ldquo;Discovery QUERY contexts&rdquo;</a>.</p><p>
+ </p><div class="table"><a id="N10B36" /><p class="title"><strong>Table&nbsp;48.&nbsp;Query</strong></p><div class="table-contents"><table summary="Query" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>QUERY (0x00)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Query context</td><td>1 byte</td><td>Type of query to execute</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>LIST</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s04.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_jdx_m11_sl.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s03.html
new file mode 100644
index 000000000..c2eb3844f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s03.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>RSP: LIST - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s04.html" title="Discovery Protocol Definition" /><link rel="prev" href="section_jdx_m11_sl.html" title="Discovery QUERY contexts" /><link rel="next" href="ch04s04s04.html" title="RSP: FAILED" /><meta content="RSP: LIST" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Discovery Protocol Definition</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_jdx_m11_sl.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s04.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s04s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10BA5" />RSP: LIST</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">List of data returned</p><div class="table"><a id="N10BAA" /><p class="title"><strong>Table&nbsp;50.&nbsp;LIST response format</strong></p><div class="table-contents"><table summary="LIST response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>RSP_LIST</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr><tr><td>Data</td><td>n bytes</td><td>Data returned</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_jdx_m11_sl.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s04.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s04s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s04.html
new file mode 100644
index 000000000..0dc44a78d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s04.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>RSP: FAILED - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s04.html" title="Discovery Protocol Definition" /><link rel="prev" href="ch04s04s03.html" title="RSP: LIST" /><link rel="next" href="ch04s04s05.html" title="Discovery Protocol ID definitions" /><meta content="RSP: FAILED" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Discovery Protocol Definition</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s04s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s04.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s04s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10BD4" />RSP: FAILED</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The command failed to execute</p><div class="table"><a id="N10BD9" /><p class="title"><strong>Table&nbsp;51.&nbsp;FAILED response format</strong></p><div class="table-contents"><table summary="FAILED response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>RSP_FAILED</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr><tr><td>Failure Code</td><td>1 byte</td><td>Instance code for failure; 0xFF = unknown</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s04s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s04.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s04s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s05.html
new file mode 100644
index 000000000..6b10f7ebe
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s04s05.html
@@ -0,0 +1,236 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Discovery Protocol ID definitions - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s04.html" title="Discovery Protocol Definition" /><link rel="prev" href="ch04s04s04.html" title="RSP: FAILED" /><link rel="next" href="ch04s05.html" title="Housekeeping Protocol" /><meta content="Discovery Protocol ID definitions" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Discovery Protocol Definition</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s04s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s04.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10C03" />Discovery Protocol ID definitions</h3></div></div></div><pre xmlns="http://www.w3.org/1999/xhtml" class="programlisting"><span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3DiscoveryCommands {
+ CMD_QUERY = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Capability discovery </em>
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3DiscoveryResponses {
+ RSP_DISCOVERY_LIST = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x81</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! List of items returned</em>
+ RSP_DISCOVERY_FAILED = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0xA0</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Command failed to execute</em>
+};
+
+<em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">// Generic failure codes</em>
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3FailureCodes {
+ FAILURE_OK = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! No error</em>
+ FAILURE_USB_PREVIOUS_UNDERRUN = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0xE0</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Previous command had too few bytes</em>
+ FAILURE_UNKNOWN = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0xFF</span> <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Unknown failure</em>
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3Discovery {
+ DISCOVERY_COMMAND_HANDLERS = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! List available command handlers</em>
+ DISCOVERY_TOOL_NAME = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x80</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Query tool name</em>
+ DISCOVERY_SERIAL_NUMBER = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x81</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Query tool serial number</em>
+ DISCOVERY_MNF_DATE = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x82</span> <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Query tool manufacturing date</em>
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3DiscoveryFailureCodes {
+ DISCOVERY_FAILED_NOT_SUPPORTED = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x10</span> <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Unsupported function</em>
+};</pre></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s04s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s04.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05.html
new file mode 100644
index 000000000..70efa405c
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Housekeeping Protocol - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avrprotocol.Overview.html" title="AVR communication protocol" /><link rel="prev" href="ch04s04s05.html" title="Discovery Protocol ID definitions" /><link rel="next" href="ch04s05s01.html" title="CMD: QUERY" /><meta content="Housekeeping Protocol" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR communication protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s04s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avrprotocol.Overview.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N10C0A" />Housekeeping Protocol</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch04s05s01.html">CMD: QUERY</a></span></dt><dt><span class="section"><a href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></dt><dt><span class="section"><a href="ch04s05s03.html">CMD: SET</a></span></dt><dt><span class="section"><a href="ch04s05s04.html">CMD: GET</a></span></dt><dt><span class="section"><a href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></dt><dt><span class="section"><a href="ch04s05s06.html">Housekeeping Commands</a></span></dt><dt><span class="section"><a href="ch04s05s07.html">Housekeeping Responses</a></span></dt><dt><span class="section"><a href="ch04s05s08.html">Events</a></span></dt><dt><span class="section"><a href="ch04s05s09.html">
+ Hints and tips
+ </a></span></dt><dt><span class="section"><a href="ch04s05s10.html">Housekeeping ID definitions</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s04s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avrprotocol.Overview.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s01.html
new file mode 100644
index 000000000..3f46ac85c
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s01.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>CMD: QUERY - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05.html" title="Housekeeping Protocol" /><link rel="prev" href="ch04s05.html" title="Housekeeping Protocol" /><link rel="next" href="section_i5v_3yz_rl.html" title="Housekeeping QUERY contexts" /><meta content="CMD: QUERY" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_i5v_3yz_rl.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10C0D" />CMD: QUERY</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Used to discover the capabilities of the tool.</p><p>For lists of valid query types, see <a class="xref" href="section_i5v_3yz_rl.html" title="Housekeeping QUERY contexts">the section called &ldquo;Housekeeping QUERY contexts&rdquo;</a>.</p><p>
+ </p><div class="table"><a id="N10C1A" /><p class="title"><strong>Table&nbsp;52.&nbsp;Query</strong></p><div class="table-contents"><table summary="Query" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>QUERY (0x00)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Query context</td><td>1 byte</td><td>Type of query to execute</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>LIST</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_i5v_3yz_rl.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s03.html
new file mode 100644
index 000000000..713c57c0c
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s03.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>CMD: SET - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05.html" title="Housekeeping Protocol" /><link rel="prev" href="section_i5v_3yz_rl.html" title="Housekeeping QUERY contexts" /><link rel="next" href="ch04s05s04.html" title="CMD: GET" /><meta content="CMD: SET" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_i5v_3yz_rl.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10C6B" />CMD: SET</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Used to set parameters on the tool..</p><p>For lists of valid get / set paramters, see <a class="xref" href="section_t1f_hb1_sl.html" title="Housekeeping SET/GET parameters">the section called &ldquo;Housekeeping SET/GET parameters&rdquo;</a>.</p><p>
+ </p><div class="table"><a id="N10C78" /><p class="title"><strong>Table&nbsp;54.&nbsp;Set</strong></p><div class="table-contents"><table summary="Set" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SET (0x01)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Set context</td><td>1 byte</td><td>Context of the parameter to set</td></tr><tr><td>Address</td><td>1 byte</td><td>Parameter ID / start address</td></tr><tr><td>Bytes</td><td>1 byte</td><td>Number of bytes to write</td></tr><tr><td>Data</td><td>N bytes</td><td>Data to write</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p><p>Note: Setting multiple parameters in one set call can only be done when all fields
+ are in the same context.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_i5v_3yz_rl.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s04.html
new file mode 100644
index 000000000..adb176dd9
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s04.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>CMD: GET - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05.html" title="Housekeeping Protocol" /><link rel="prev" href="ch04s05s03.html" title="CMD: SET" /><link rel="next" href="section_t1f_hb1_sl.html" title="Housekeeping SET/GET parameters" /><meta content="CMD: GET" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_t1f_hb1_sl.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10CC6" />CMD: GET</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Used to get parameters on the tool..</p><p>For lists of valid get / set paramters, see <a class="xref" href="section_t1f_hb1_sl.html" title="Housekeeping SET/GET parameters">the section called &ldquo;Housekeeping SET/GET parameters&rdquo;</a>.</p><p>
+ </p><div class="table"><a id="N10CD3" /><p class="title"><strong>Table&nbsp;55.&nbsp;Get</strong></p><div class="table-contents"><table summary="Get" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>GET (0x02)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Get context</td><td>1 byte</td><td>Context of the parameter to get</td></tr><tr><td>Address</td><td>1 byte</td><td>Parameter ID / start address</td></tr><tr><td>Bytes</td><td>1 byte</td><td>Number of bytes to read</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p><p>Note: Getting multiple parameters in one set call can only be done when all fields
+ are in the same context.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_t1f_hb1_sl.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06.html
new file mode 100644
index 000000000..254c04931
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Housekeeping Commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05.html" title="Housekeeping Protocol" /><link rel="prev" href="section_t1f_hb1_sl.html" title="Housekeeping SET/GET parameters" /><link rel="next" href="section_housekeeping_start_session.html" title="Start session" /><meta content="Housekeeping Commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_t1f_hb1_sl.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_housekeeping_start_session.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10D69" />Housekeeping Commands</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="section_housekeeping_start_session.html">Start session</a></span></dt><dt><span class="section"><a href="ch04s05s06s02.html">End Session</a></span></dt><dt><span class="section"><a href="ch04s05s06s03.html">Firmware Upgrade</a></span></dt><dt><span class="section"><a href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></dt><dt><span class="section"><a href="ch04s05s06s05.html">Calibrate Oscillator</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_t1f_hb1_sl.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_housekeeping_start_session.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s02.html
new file mode 100644
index 000000000..9a01e3c48
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s02.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>End Session - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s06.html" title="Housekeeping Commands" /><link rel="prev" href="section_housekeeping_start_session.html" title="Start session" /><link rel="next" href="ch04s05s06s03.html" title="Firmware Upgrade" /><meta content="End Session" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_housekeeping_start_session.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s06.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s06s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10DA1" />End Session</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Signs off the tool. The tool will cease to publish events.</p><div class="table"><a id="N10DA6" /><p class="title"><strong>Table&nbsp;58.&nbsp;End session command format</strong></p><div class="table-contents"><table summary="End session command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_HOUSEKEEPING_END_SESSION</td><td>Version</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Reset</td><td>1 byte</td><td>0 = no action; 1 = reset tool </td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_housekeeping_start_session.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s06.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s06s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s03.html
new file mode 100644
index 000000000..8278b2627
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s03.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Firmware Upgrade - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s06.html" title="Housekeeping Commands" /><link rel="prev" href="ch04s05s06s02.html" title="End Session" /><link rel="next" href="ch04s05s06s04.html" title="JTAG scan-chain detection" /><meta content="Firmware Upgrade" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s06s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s06.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s06s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10DDC" />Firmware Upgrade</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Invokes upgrade mode. No further communication is required.</p><div class="table"><a id="N10DE1" /><p class="title"><strong>Table&nbsp;59.&nbsp;Firmware upgrade command format</strong></p><div class="table-contents"><table summary="Firmware upgrade command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_HOUSEKEEPING_FW_UPGRADE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Upgrade key</td><td>4 bytes</td><td>Key for enabling upgrade mode</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s06s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s06.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s06s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s04.html
new file mode 100644
index 000000000..75f289697
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s04.html
@@ -0,0 +1,217 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>JTAG scan-chain detection - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s06.html" title="Housekeeping Commands" /><link rel="prev" href="ch04s05s06s03.html" title="Firmware Upgrade" /><link rel="next" href="ch04s05s06s05.html" title="Calibrate Oscillator" /><meta content="JTAG scan-chain detection" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s06s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s06.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s06s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10E17" />JTAG scan-chain detection</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Performs an auto detection of JTAG devices. If no devices are found, JTAG
+ enable sequences for various families are applied and the detection retried. If
+ any device on the scan chain does not have JTAG enabled, the "use reset"
+ parameter can help to enable JTAG. (This will not necessarily work with devices
+ not manufactured by Atmel.)</p><div class="table"><a id="N10E1C" /><p class="title"><strong>Table&nbsp;60.&nbsp;JTAG scan-chain detection command format</strong></p><div class="table-contents"><table summary="JTAG scan-chain detection command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_HOUSEKEEPING_JTAG_DETECT</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Use reset</td><td>1 byte</td><td><p>0 = External reset will NOT be applied</p><p>1 = External reset will be applied</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>LIST of 32-bit JTAG IDs</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s06s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s06.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s06s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s05.html
new file mode 100644
index 000000000..3bf798fb6
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s06s05.html
@@ -0,0 +1,217 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Calibrate Oscillator - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s06.html" title="Housekeeping Commands" /><link rel="prev" href="ch04s05s06s04.html" title="JTAG scan-chain detection" /><link rel="next" href="ch04s05s07.html" title="Housekeeping Responses" /><meta content="Calibrate Oscillator" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s06s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s06.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s07.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10E55" />Calibrate Oscillator</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Performs oscillator calibration on the target. Protocol and target code is
+ described in appnotes AVR053 (megaAVR and tinyAVR) and AVR1606 (AVR XMEGA). Note
+ that this command must be called without any physical activated, or an error
+ will be returned. The reference clock for the calibration is running at 32.120
+ kHz</p><div class="table"><a id="N10E5A" /><p class="title"><strong>Table&nbsp;61.&nbsp;Calibrate Oscillator command format</strong></p><div class="table-contents"><table summary="Calibrate Oscillator command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_HOUSEKEEPING_CAL_OSC</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s06s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s06.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s07.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07.html
new file mode 100644
index 000000000..df1d7fef4
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Housekeeping Responses - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05.html" title="Housekeeping Protocol" /><link rel="prev" href="ch04s05s06s05.html" title="Calibrate Oscillator" /><link rel="next" href="ch04s05s07s01.html" title="OK" /><meta content="Housekeeping Responses" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s06s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s07s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10E89" />Housekeeping Responses</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch04s05s07s01.html">OK</a></span></dt><dt><span class="section"><a href="ch04s05s07s02.html">LIST</a></span></dt><dt><span class="section"><a href="ch04s05s07s03.html">DATA</a></span></dt><dt><span class="section"><a href="ch04s05s07s04.html">FAILED</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s06s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s07s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s01.html
new file mode 100644
index 000000000..ddd7e13ed
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>OK - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s07.html" title="Housekeeping Responses" /><link rel="prev" href="ch04s05s07.html" title="Housekeeping Responses" /><link rel="next" href="ch04s05s07s02.html" title="LIST" /><meta content="OK" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s07.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s07.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s07s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10E8C" />OK</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The command was executed successfully</p><div class="table"><a id="N10E91" /><p class="title"><strong>Table&nbsp;62.&nbsp;OK response format</strong></p><div class="table-contents"><table summary="OK response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>RSP_HOUSEKEEPING_OK</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s07.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s07.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s07s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s02.html
new file mode 100644
index 000000000..1f18a73d0
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>LIST - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s07.html" title="Housekeeping Responses" /><link rel="prev" href="ch04s05s07s01.html" title="OK" /><link rel="next" href="ch04s05s07s03.html" title="DATA" /><meta content="LIST" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s07s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s07.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s07s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10EB4" />LIST</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">List of data returned</p><div class="table"><a id="N10EB9" /><p class="title"><strong>Table&nbsp;63.&nbsp;LIST response format</strong></p><div class="table-contents"><table summary="LIST response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>RSP_HOUSEKEEPING_LIST</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr><tr><td>Data</td><td>n bytes</td><td>Data returned</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s07s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s07.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s07s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s03.html
new file mode 100644
index 000000000..92b8b3f50
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s03.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>DATA - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s07.html" title="Housekeeping Responses" /><link rel="prev" href="ch04s05s07s02.html" title="LIST" /><link rel="next" href="ch04s05s07s04.html" title="FAILED" /><meta content="DATA" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s07s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s07.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s07s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10EE3" />DATA</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Data is returned</p><div class="table"><a id="N10EE8" /><p class="title"><strong>Table&nbsp;64.&nbsp;DATA response format version 0</strong></p><div class="table-contents"><table summary="DATA response format version 0" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>RSP_HOUSEKEEPING_DATA</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x01)</td><td>1 byte</td><td>Response version</td></tr><tr><td>Data</td><td>n bytes</td><td>Data returned</td></tr><tr><td>Status code</td><td>1 byte</td><td>Trailing status of the read operation indicating whether
+ the data returned is in fact valid. 0x00 = OK.</td></tr></tbody></table></div></div><br class="table-break" /><p>Note: RSP_HOUSEKEEPING_DATA version 0 does not have the trailing status
+ code.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s07s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s07.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s07s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s04.html
new file mode 100644
index 000000000..19fc5eb04
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s07s04.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>FAILED - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s07.html" title="Housekeeping Responses" /><link rel="prev" href="ch04s05s07s03.html" title="DATA" /><link rel="next" href="ch04s05s08.html" title="Events" /><meta content="FAILED" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s07s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s07.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s08.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10F1B" />FAILED</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The command failed to execute</p><div class="table"><a id="N10F20" /><p class="title"><strong>Table&nbsp;65.&nbsp;FAILED response format</strong></p><div class="table-contents"><table summary="FAILED response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>RSP_HOUSEKEEPING_FAILED</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr><tr><td>Failure Code</td><td>1 byte</td><td>Instance code for failure; 0xFF = unknown</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s07s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s07.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s08.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08.html
new file mode 100644
index 000000000..f0efdf9b8
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Events - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05.html" title="Housekeeping Protocol" /><link rel="prev" href="ch04s05s07s04.html" title="FAILED" /><link rel="next" href="ch04s05s08s01.html" title="Event: power" /><meta content="Events" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s07s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s08s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10F4A" />Events</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch04s05s08s01.html">Event: power</a></span></dt><dt><span class="section"><a href="ch04s05s08s02.html">Event: sleep</a></span></dt><dt><span class="section"><a href="ch04s05s08s03.html">Event: external reset</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s07s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s08s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s01.html
new file mode 100644
index 000000000..91fbfb8ed
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s01.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Event: power - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s08.html" title="Events" /><link rel="prev" href="ch04s05s08.html" title="Events" /><link rel="next" href="ch04s05s08s02.html" title="Event: sleep" /><meta content="Event: power" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Events</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s08.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s08.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s08s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10F4D" />Event: power</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Indicates a target power event has occurred. Note: Debouncing is
+ implemented, but several alternating events could still appear in some
+ cases.</p><div class="table"><a id="N10F52" /><p class="title"><strong>Table&nbsp;66.&nbsp;POWER event format</strong></p><div class="table-contents"><table summary="POWER event format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>EVT_HOUSEKEEPING_POWER</td><td>1 byte</td><td>Event ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Event version</td></tr><tr><td>State</td><td>1 byte</td><td><p>0x00 = Power has gone OFF</p><p>0x01 = Power has been restored</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s08.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s08.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s08s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s02.html
new file mode 100644
index 000000000..395e3a4ae
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s02.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Event: sleep - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s08.html" title="Events" /><link rel="prev" href="ch04s05s08s01.html" title="Event: power" /><link rel="next" href="ch04s05s08s03.html" title="Event: external reset" /><meta content="Event: sleep" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Events</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s08s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s08.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s08s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10F7F" />Event: sleep</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Indicates target sleep status. Note: This value is polled from the target
+ at a fixed frequency. Entering and exiting SLEEP states rapidly will not
+ generate the same number of event messages as the actual state
+ transitions.</p><div class="table"><a id="N10F84" /><p class="title"><strong>Table&nbsp;67.&nbsp;SLEEP event format</strong></p><div class="table-contents"><table summary="SLEEP event format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>EVT_HOUSEKEEPING_SLEEP</td><td>1 byte</td><td>Event ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Event version</td></tr><tr><td>State</td><td>1 byte</td><td><p>0x00 = Target is now AWAKE</p><p>0x01 = Target is now ASLEEP</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s08s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s08.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s08s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s03.html
new file mode 100644
index 000000000..128c2b8c8
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s08s03.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Event: external reset - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s08.html" title="Events" /><link rel="prev" href="ch04s05s08s02.html" title="Event: sleep" /><link rel="next" href="ch04s05s09.html" title="Hints and tips" /><meta content="Event: external reset" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Events</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s08s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s08.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s09.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10FB1" />Event: external reset</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Indicates target external reset status</p><div class="table"><a id="N10FB6" /><p class="title"><strong>Table&nbsp;68.&nbsp;EXTERNAL RESET event format</strong></p><div class="table-contents"><table summary="EXTERNAL RESET event format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>EVT_HOUSEKEEPING_EXT_RESET</td><td>1 byte</td><td>Event ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Event version</td></tr><tr><td>State</td><td>1 byte</td><td><p>0x00 = External reset has been released (rising edge)</p><p>0x01 = External reset has been applied (falling edge)</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s08s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s08.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s09.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s09.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s09.html
new file mode 100644
index 000000000..3588ca655
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s09.html
@@ -0,0 +1,220 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Hints and tips - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05.html" title="Housekeeping Protocol" /><link rel="prev" href="ch04s05s08s03.html" title="Event: external reset" /><link rel="next" href="ch04s05s10.html" title="Housekeeping ID definitions" /><meta content="Hints and tips" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s08s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s10.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10FE3" />
+ Hints and tips
+ </h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Using the housekeeping protocol:</p><p>Housekeeping functions are performed using the Housekeeping protocol handler. All
+ housekeeping functions are independent of any target functionality. This
+ includes VTref reading, version checking etc. </p><p>Session control is done on the housekeeping interface using CMD_START_SESSION
+ and CMD_END_SESSION, (aka: sign on and sign off). </p><p>JTAG scan-chain auto-detection is supported on the housekeeping interface, but is
+ restricted exclusively to JTAG detection &ndash; all other interfaces must be detected
+ manually by trial and error, or selected by the user directly. Scan-chain
+ auto-detection <span class="italic">must</span> be executed before activating
+ the JTAG physical using any protocol.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s08s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s10.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s10.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s10.html
new file mode 100644
index 000000000..80f23e797
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch04s05s10.html
@@ -0,0 +1,310 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Housekeeping ID definitions - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05.html" title="Housekeeping Protocol" /><link rel="prev" href="ch04s05s09.html" title="Hints and tips" /><link rel="next" href="protocoldocs.avr32protocol.html" title="AVR32 generic protocol" /><meta content="Housekeeping ID definitions" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s09.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="protocoldocs.avr32protocol.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10FF2" />Housekeeping ID definitions</h3></div></div></div><pre xmlns="http://www.w3.org/1999/xhtml" class="programlisting"><span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3HousekeepingCommands {
+
+ <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">// Basics</em>
+ CMD_HOUSEKEEPING_QUERY = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Capability discovery </em>
+ CMD_HOUSEKEEPING_SET = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x01</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Set parameters</em>
+ CMD_HOUSEKEEPING_GET = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x02</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Get parameters</em>
+
+ <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">// Session</em>
+ CMD_HOUSEKEEPING_START_SESSION = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x10</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Start a session</em>
+ CMD_HOUSEKEEPING_END_SESSION = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x11</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Terminate a session</em>
+
+ <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">// Misc target-related</em>
+ CMD_HOUSEKEEPING_JTAG_DETECT = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x30</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Scan for JTAG devices</em>
+ CMD_HOUSEKEEPING_CAL_OSC = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x31</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Oscillator calibration </em>
+
+ <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">// Internal commands</em>
+ CMD_HOUSEKEEPING_FW_UPGRADE = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x50</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Enter upgrade mode</em>
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3HousekeepingResponses {
+ RSP_HOUSEKEEPING_OK = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x80</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! All OK</em>
+ RSP_HOUSEKEEPING_LIST = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x81</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! List of items returned</em>
+ RSP_HOUSEKEEPING_DATA = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x84</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Data returned</em>
+ RSP_HOUSEKEEPING_FAILED = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0xA0</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Command failed to execute</em>
+ RSP_HOUSEKEEPING_FAILED_WITH_DATA = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0xA1</span> <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Failed with more info</em>
+
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3HousekeepingEvents {
+ EVT_HOUSEKEEPING_POWER = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x10</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Power event occurred</em>
+ EVT_HOUSEKEEPING_SLEEP = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x11</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Sleep event detected</em>
+ EVT_HOUSEKEEPING_EXT_RESET = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x12</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! External reset event</em>
+};
+
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3HousekeepingFailureCodes {
+ HOUSEKEEPING_FAILED_OK = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! All OK</em>
+ HOUSEKEEPING_FAILED_NOT_SUPPORTED = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x10</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Not supported</em>
+ HOUSEKEEPING_FAILED_INVALID_KEY = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x11</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Wrong key</em>
+ HOUSEKEEPING_FAILED_INVALID_PARAMETER = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x12</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Wrong parameter</em>
+ HOUSEKEEPING_FAILED_INVALID_PARAMETER_VALUE = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x13</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Wrong value</em>
+
+ HOUSEKEEPING_FAILED_JTAG_DETECT_NO_DEVICES = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x30</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! No devices</em>
+ HOUSEKEEPING_FAILED_JTAG_DETECT_TOO_MANY_DEVICES = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x31</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Too many devices</em>
+ HOUSEKEEPING_FAILED_JTAG_DETECT_JTAGM_INIT_ERROR = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x32</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Init failed</em>
+ HOUSEKEEPING_FAILED_JTAG_DETECT_JTAGM_ERROR = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x33</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! JTAGM error</em>
+
+ HOUSEKEEPING_FAILED_NO_TARGET_POWER = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x38</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Apply power</em>
+
+ HOUSEKEEPING_FAILED_OSCCAL_INVALID_MODE = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x40</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Wrong mode</em>
+ HOUSEKEEPING_FAILED_OSCCAL_INVALID_PHYSICAL = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x41</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Wrong phy</em>
+ HOUSEKEEPING_FAILED_OSCCAL_FW_ERROR = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x42</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Firmware error</em>
+ HOUSEKEEPING_FAILED_OSCCAL_FAILED = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x43</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! OSCCAL error</em>
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3SetGetFailureCodes {
+ SETGET_FAILURE_OK = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! All OK</em>
+ SETGET_FAILURE_NOT_IMPLEMENTED = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x10</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Command not implented</em>
+ SETGET_FAILURE_NOT_SUPPORTED = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x11</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Parameter not supported</em>
+ SETGET_FAILURE_INVALID_CLOCK_SPEED = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x20</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Clock out of range</em>
+ SETGET_FAILURE_ILLEGAL_STATE = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x21</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Wrong state to access the parameter</em>
+ SETGET_FAILURE_JTAGM_INIT_ERROR = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x22</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! JTAG initialisation error</em>
+ SETGET_FAILURE_INVALID_VALUE = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x23</span> <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Value out of range</em>
+};
+
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3HousekeepingQueryContexts {
+ HK_QUERY_COMMANDS = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span> <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Supported command list</em>
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3HousekeepingSetGetContexts {
+ HK_CONTEXT_CONFIG = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Config parameter</em>
+ HK_CONTEXT_ANALOG = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x01</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Analog parameters</em>
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3HousekeepingConfigContextParameters {
+ HOUSEKEEPING_CONFIG_HWREV = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Hardware revision </em>
+ HOUSEKEEPING_CONFIG_FWREV_MAJ = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x01</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Firmware revision high</em>
+ HOUSEKEEPING_CONFIG_FWREV_MIN = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x02</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Firmware revision low</em>
+ HOUSEKEEPING_CONFIG_BUILD = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x03</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Firmware build number</em>
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3HousekeepingAnalogContextParameters {
+ HOUSEKEEPING_ANALOG_VTREF = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span> <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Target reference voltage</em>
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3HousekeepingPowerEvents {
+ HOUSEKEEPING_POWER_OFF = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Power went off</em>
+ HOUSEKEEPING_POWER_ON = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x01</span> <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Power went on</em>
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3HousekeepingSleepEvents {
+ HOUSEKEEPING_AWAKE = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Target woke up</em>
+ HOUSEKEEPING_SLEEP = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x01</span> <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! Target fell asleep</em>
+};
+
+<span xmlns="http://www.w3.org/1999/xhtml" class="hl-keyword" style="color: #0000FF">enum</span> Jtagice3HousekeepingResetEvents {
+ HOUSEKEEPING_RESET_RELEASED = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x00</span>, <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! External reset released</em>
+ HOUSEKEEPING_RESET_APPLIED = <span xmlns="http://www.w3.org/1999/xhtml" class="hl-number">0x01</span> <em xmlns="http://www.w3.org/1999/xhtml" class="hl-comment" style="color: #008000">//! External reset applied</em>
+};</pre></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s09.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="protocoldocs.avr32protocol.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01.html
new file mode 100644
index 000000000..3cb080a26
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Protocol commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avr32protocol.html" title="AVR32 generic protocol" /><link rel="prev" href="protocoldocs.avr32protocol.html" title="AVR32 generic protocol" /><link rel="next" href="ch05s01s01.html" title="QUERY" /><meta content="Protocol commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR32 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="protocoldocs.avr32protocol.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avr32protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N11003" />Protocol commands</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch05s01s01.html">QUERY</a></span></dt><dt><span class="section"><a href="ch05s01s02.html">SET</a></span></dt><dt><span class="section"><a href="ch05s01s03.html">GET</a></span></dt><dt><span class="section"><a href="ch05s01s04.html">Activate Physical</a></span></dt><dt><span class="section"><a href="ch05s01s05.html">Deactivate Physical</a></span></dt><dt><span class="section"><a href="ch05s01s06.html">Get ID</a></span></dt><dt><span class="section"><a href="ch05s01s07.html">Erase</a></span></dt><dt><span class="section"><a href="ch05s01s08.html">Halt</a></span></dt><dt><span class="section"><a href="ch05s01s09.html">Reset</a></span></dt><dt><span class="section"><a href="ch05s01s10.html">Step</a></span></dt><dt><span class="section"><a href="ch05s01s11.html">Read</a></span></dt><dt><span class="section"><a href="ch05s01s12.html">Write</a></span></dt><dt><span class="section"><a href="ch05s01s13.html">TAP</a></span></dt><dt><span class="section"><a href="ch05s01s14.html">Is protected</a></span></dt><dt><span class="section"><a href="ch05s01s15.html">Erase Section</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="protocoldocs.avr32protocol.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avr32protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s01.html
new file mode 100644
index 000000000..4e07d5716
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s01.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>QUERY - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01.html" title="Protocol commands" /><link rel="next" href="section_qhb_x1c_sl.html" title="AVR32 QUERY contexts" /><meta content="QUERY" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_qhb_x1c_sl.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11006" />QUERY</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></dt></dl></div><p>Used to discover the capabilities of the tool.</p><p>For lists of valid query types, see <a class="xref" href="section_qhb_x1c_sl.html" title="AVR32 QUERY contexts">the section called &ldquo;AVR32 QUERY contexts&rdquo;</a>.</p><p>
+ </p><div class="table"><a id="N11013" /><p class="title"><strong>Table&nbsp;69.&nbsp;Query</strong></p><div class="table-contents"><table summary="Query" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>QUERY (0x00)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Query context</td><td>1 byte</td><td>Type of query to execute</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>LIST</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_qhb_x1c_sl.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s02.html
new file mode 100644
index 000000000..51d7f260d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s02.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SET - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="section_qhb_x1c_sl.html" title="AVR32 QUERY contexts" /><link rel="next" href="ch05s01s03.html" title="GET" /><meta content="SET" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_qhb_x1c_sl.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11082" />SET</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Used to set parameters on the tool..</p><p>For lists of valid get / set paramters, see <a class="xref" href="section_avr32_setget_params.html" title="SET/GET parameters">the section called &ldquo;SET/GET parameters&rdquo;</a> .</p><p>
+ </p><div class="table"><a id="N1108F" /><p class="title"><strong>Table&nbsp;71.&nbsp;Set</strong></p><div class="table-contents"><table summary="Set" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SET (0x01)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Set context</td><td>1 byte</td><td>Context of the parameter to set</td></tr><tr><td>Address</td><td>1 byte</td><td>Parameter ID / start address</td></tr><tr><td>Bytes</td><td>1 byte</td><td>Number of bytes to write</td></tr><tr><td>Data</td><td>N bytes</td><td>Data to write</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p><p>Note: Setting multiple parameters in one set call can only be done when all fields
+ are in the same context.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_qhb_x1c_sl.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s03.html
new file mode 100644
index 000000000..0a8ae1f5a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s03.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>GET - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01s02.html" title="SET" /><link rel="next" href="section_avr32_setget_params.html" title="SET/GET parameters" /><meta content="GET" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_avr32_setget_params.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N110DD" />GET</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="section_avr32_setget_params.html">SET/GET parameters</a></span></dt></dl></div><p>Used to get parameters on the tool..</p><p>For lists of valid get / set paramters, see <a class="xref" href="section_avr32_setget_params.html" title="SET/GET parameters">the section called &ldquo;SET/GET parameters&rdquo;</a> .</p><p>
+ </p><div class="table"><a id="N110EA" /><p class="title"><strong>Table&nbsp;72.&nbsp;Get</strong></p><div class="table-contents"><table summary="Get" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>GET (0x02)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Get context</td><td>1 byte</td><td>Context of the parameter to get</td></tr><tr><td>Address</td><td>1 byte</td><td>Parameter ID / start address</td></tr><tr><td>Bytes</td><td>1 byte</td><td>Number of bytes to read</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p><p>Note: Getting multiple parameters in one set call can only be done when all fields
+ are in the same context.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_avr32_setget_params.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s04.html
new file mode 100644
index 000000000..aa8419adc
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s04.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Activate Physical - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="section_avr32_setget_params.html" title="SET/GET parameters" /><link rel="next" href="ch05s01s05.html" title="Deactivate Physical" /><meta content="Activate Physical" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_avr32_setget_params.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N111FA" />Activate Physical</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Activates the selected physical interface, if necessary, and makes contact
+ with the target interface. If no interface is detected, a FAILED response is
+ returned else the device ID is returned. </p><div class="table"><a id="N111FF" /><p class="title"><strong>Table&nbsp;74.&nbsp;Activate Physical command format</strong></p><div class="table-contents"><table summary="Activate Physical command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_ACTIVATE_PHYSICAL</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Reset</td><td>1 bytes</td><td><p>0x00: no NOT use external reset</p><p>0x01: apply external reset during activation</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA containing the 32-bit device ID (JTAGID or
+ aWireID)</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_avr32_setget_params.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s05.html
new file mode 100644
index 000000000..53c5b4661
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s05.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Deactivate Physical - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01s04.html" title="Activate Physical" /><link rel="next" href="ch05s01s06.html" title="Get ID" /><meta content="Deactivate Physical" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s06.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11238" />Deactivate Physical</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">De-activates the physical interface and disconnects from the target. After this, the debugger has no connection to the target.</p><p>Note: This may be done implicitly by another command.</p><div class="table"><a id="N1123F" /><p class="title"><strong>Table&nbsp;75.&nbsp;Deactivate Physical command format</strong></p><div class="table-contents"><table summary="Deactivate Physical command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_DEACTIVATE_PHYSICAL</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s06.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s06.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s06.html
new file mode 100644
index 000000000..7cd708933
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s06.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Get ID - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01s05.html" title="Deactivate Physical" /><link rel="next" href="ch05s01s07.html" title="Erase" /><meta content="Get ID" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s07.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1126E" />Get ID</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Retrieves the ID of the target. The same ID is returned by Activate
+ Physical command. Any previously read value is not cached, but re-read from the
+ target.</p><div class="table"><a id="N11273" /><p class="title"><strong>Table&nbsp;76.&nbsp;Get ID command format</strong></p><div class="table-contents"><table summary="Get ID command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_GET_ID</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>ID - 32-bit device ID (JTAGID or aWire ID)</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s07.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s07.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s07.html
new file mode 100644
index 000000000..0c8fd69cf
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s07.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Erase - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01s06.html" title="Get ID" /><link rel="next" href="ch05s01s08.html" title="Halt" /><meta content="Erase" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s06.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s08.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N112A2" />Erase</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Performs a chip erase on the target</p><div class="table"><a id="N112A7" /><p class="title"><strong>Table&nbsp;77.&nbsp;Erase command format</strong></p><div class="table-contents"><table summary="Erase command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_ERASE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s06.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s08.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s08.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s08.html
new file mode 100644
index 000000000..33458079f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s08.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Halt - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01s07.html" title="Erase" /><link rel="next" href="ch05s01s09.html" title="Reset" /><meta content="Halt" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s07.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s09.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N112D6" />Halt</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Writes the target halt register</p><div class="table"><a id="N112DB" /><p class="title"><strong>Table&nbsp;78.&nbsp;Halt command format</strong></p><div class="table-contents"><table summary="Halt command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_HALT</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Action</td><td>1 byte</td><td><p>0x00: Resume</p><p>0x01: Halt</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s07.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s09.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s09.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s09.html
new file mode 100644
index 000000000..5b1a92485
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s09.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Reset - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01s08.html" title="Halt" /><link rel="next" href="ch05s01s10.html" title="Step" /><meta content="Reset" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s08.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s10.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11314" />Reset</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Resets the target</p><div class="table"><a id="N11319" /><p class="title"><strong>Table&nbsp;79.&nbsp;Writes the target reset register</strong></p><div class="table-contents"><table summary="Writes the target reset register" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_RESET</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Action</td><td>1 byte</td><td>Device specific bits for reset register depending upon
+ the number of reset domains specified for the device.</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s08.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s10.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s10.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s10.html
new file mode 100644
index 000000000..c34fdc8f9
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s10.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Step - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01s09.html" title="Reset" /><link rel="next" href="ch05s01s11.html" title="Read" /><meta content="Step" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s09.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s11.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1134F" />Step</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Performs one low level instruction single step</p><div class="table"><a id="N11354" /><p class="title"><strong>Table&nbsp;80.&nbsp;Step command format</strong></p><div class="table-contents"><table summary="Step command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_STEP</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>PC</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s09.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s11.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s11.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s11.html
new file mode 100644
index 000000000..d0e20a1f4
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s11.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Read - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01s10.html" title="Step" /><link rel="next" href="ch05s01s12.html" title="Write" /><meta content="Read" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s10.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s12.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11383" />Read</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Read memory</p><div class="table"><a id="N11388" /><p class="title"><strong>Table&nbsp;81.&nbsp;Read command format</strong></p><div class="table-contents"><table summary="Read command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_READ</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Memory type</td><td>1 byte</td><td>Memory type to access; see <a class="xref" href="section_avr32_memtypes.html" title="Memory Types">the section called &ldquo;Memory Types&rdquo;</a></td></tr><tr><td>Address</td><td>5 bytes</td><td>Memory type dependent, usually SAB address.</td></tr><tr><td>Bytes</td><td>4 bytes</td><td>Number of bytes to read. Note that memory type might put
+ restrictions on number of bytes.</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s10.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s12.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s12.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s12.html
new file mode 100644
index 000000000..9a083c7fc
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s12.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Write - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01s11.html" title="Read" /><link rel="next" href="section_avr32_memtypes.html" title="Memory Types" /><meta content="Write" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s11.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_avr32_memtypes.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N113CF" />Write</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="section_avr32_memtypes.html">Memory Types</a></span></dt></dl></div><p>Write memory</p><div class="table"><a id="N113D4" /><p class="title"><strong>Table&nbsp;82.&nbsp;Write command format</strong></p><div class="table-contents"><table summary="Write command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_WRITE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Memory type</td><td>1 byte</td><td>Memory type to access; see <a class="xref" href="section_avr32_memtypes.html" title="Memory Types">the section called &ldquo;Memory Types&rdquo;</a></td></tr><tr><td>Address</td><td>5 bytes</td><td>Memory type dependent, usually SAB address</td></tr><tr><td>Bytes</td><td>4 bytes</td><td>Number of bytes to read. Note that memory type might put
+ restrictions on number of bytes.</td></tr><tr><td>Data</td><td>N bytes</td><td>The data to be written</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s11.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_avr32_memtypes.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s13.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s13.html
new file mode 100644
index 000000000..d7f9e2899
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s13.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>TAP - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="section_avr32_memtypes.html" title="Memory Types" /><link rel="next" href="ch05s01s14.html" title="Is protected" /><meta content="TAP" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_avr32_memtypes.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s14.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N114BA" />TAP</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Low level TAP commands (JTAG only) </p><p>The TAP command shifts N bits of DATA into the specified shift register (IR or DR).
+ The output of the shift is captured and returned in the DATA response.
+ Bits are shifted LSB first both in and out.</p><div class="table"><a id="N114C1" /><p class="title"><strong>Table&nbsp;84.&nbsp;TAP command format</strong></p><div class="table-contents"><table summary="TAP command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_TAP</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Register/Signal</td><td>1 byte</td><td><p>AVR32_TAP_IR</p><p>AVR32_TAP_DR</p></td></tr><tr><td>Bits</td><td>1 byte</td><td>Number of bits to shift</td></tr><tr><td>Data</td><td>N bytes</td><td>N = bits / 8; data to scan in.</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_avr32_memtypes.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s14.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s14.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s14.html
new file mode 100644
index 000000000..07d724a3b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s14.html
@@ -0,0 +1,217 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Is protected - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01s13.html" title="TAP" /><link rel="next" href="ch05s01s15.html" title="Erase Section" /><meta content="Is protected" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s13.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s15.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1150A" />Is protected</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Checks whether the device's protected bit is set. When using aWire the
+ explicit isProtected command is called. When using JTAG the MEMORY_WORD_ACCESS
+ instruction is clocked into the IR. The pattern "peb01" is clocked out during
+ this operation. The value of "p" is returned, or a failure returned if the "01"
+ token is not received.</p><div class="table"><a id="N1150F" /><p class="title"><strong>Table&nbsp;85.&nbsp;Is protected command format</strong></p><div class="table-contents"><table summary="Is protected command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_IS_PROTECTED</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s13.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s15.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s15.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s15.html
new file mode 100644
index 000000000..75d4fc8ea
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s01s15.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Erase Section - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01.html" title="Protocol commands" /><link rel="prev" href="ch05s01s14.html" title="Is protected" /><link rel="next" href="ch05s02.html" title="Responses" /><meta content="Erase Section" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s14.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1153E" />Erase Section</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Erases a contiguous flash section</p><p>The Page Erase command will first unlock all regions which are within the requested flash range to erase.
+ If the requested flash area (start address; pages) constitutes the entire flash of the device, the Erase All command
+ will be used. Otherwise a sequence of page erases will be performed.</p><p>Note: erasing sections can also be done by writing to the flash controller
+ directly.</p><div class="table"><a id="N11547" /><p class="title"><strong>Table&nbsp;86.&nbsp;Erase section command format</strong></p><div class="table-contents"><table summary="Erase section command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_CMD_ERASE_SECTION</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Unlock</td><td>1 byte</td><td>Boolean flag indicating whether to unlock flash regions before erase</td></tr><tr><td>Memory type</td><td>1 byte</td><td>Memory type to access; see <a class="xref" href="section_avr32_memtypes.html" title="Memory Types">the section called &ldquo;Memory Types&rdquo;</a></td></tr><tr><td>Start address</td><td>4 bytes</td><td>Start address of flash section to erase</td></tr><tr><td>Pages</td><td>2 bytes</td><td>Number of pages to erase</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s14.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02.html
new file mode 100644
index 000000000..d7ecd1244
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Responses - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avr32protocol.html" title="AVR32 generic protocol" /><link rel="prev" href="ch05s01s15.html" title="Erase Section" /><link rel="next" href="ch05s02s01.html" title="OK" /><meta content="Responses" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR32 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s15.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avr32protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s02s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N11595" />Responses</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch05s02s01.html">OK</a></span></dt><dt><span class="section"><a href="ch05s02s02.html">LIST</a></span></dt><dt><span class="section"><a href="ch05s02s03.html">ID</a></span></dt><dt><span class="section"><a href="ch05s02s04.html">PC</a></span></dt><dt><span class="section"><a href="ch05s02s05.html">DATA</a></span></dt><dt><span class="section"><a href="ch05s02s06.html">FAILED</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s15.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avr32protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s02s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s01.html
new file mode 100644
index 000000000..ca3957a18
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>OK - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s02.html" title="Responses" /><link rel="prev" href="ch05s02.html" title="Responses" /><link rel="next" href="ch05s02s02.html" title="LIST" /><meta content="OK" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s02s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11598" />OK</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The command was executed successfully</p><div class="table"><a id="N1159D" /><p class="title"><strong>Table&nbsp;87.&nbsp;OK response format</strong></p><div class="table-contents"><table summary="OK response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_RSP_OK</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s02s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s02.html
new file mode 100644
index 000000000..53534183b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>LIST - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s02.html" title="Responses" /><link rel="prev" href="ch05s02s01.html" title="OK" /><link rel="next" href="ch05s02s03.html" title="ID" /><meta content="LIST" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s02s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s02s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N115C0" />LIST</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">List of data returned</p><div class="table"><a id="N115C5" /><p class="title"><strong>Table&nbsp;88.&nbsp;LIST response format</strong></p><div class="table-contents"><table summary="LIST response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_RSP_LIST</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version</td><td>1 byte</td><td>Response version</td></tr><tr><td>Data (0x00)</td><td>n bytes</td><td>Data returned</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s02s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s02s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s03.html
new file mode 100644
index 000000000..cc729e727
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s03.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>ID - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s02.html" title="Responses" /><link rel="prev" href="ch05s02s02.html" title="LIST" /><link rel="next" href="ch05s02s04.html" title="PC" /><meta content="ID" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s02s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s02s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N115EF" />ID</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Device ID</p><div class="table"><a id="N115F4" /><p class="title"><strong>Table&nbsp;89.&nbsp;ID response format</strong></p><div class="table-contents"><table summary="ID response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_RSP_ID</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr><tr><td>Device ID</td><td>4 bytes</td><td>Device ID as given in the datasheet</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s02s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s02s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s04.html
new file mode 100644
index 000000000..be920ef5d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s04.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>PC - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s02.html" title="Responses" /><link rel="prev" href="ch05s02s03.html" title="ID" /><link rel="next" href="ch05s02s05.html" title="DATA" /><meta content="PC" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s02s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s02s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1161B" />PC</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Program counter value is returned</p><div class="table"><a id="N11620" /><p class="title"><strong>Table&nbsp;90.&nbsp;PC response format</strong></p><div class="table-contents"><table summary="PC response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_RSP_PC</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr><tr><td>PC</td><td>4 bytes</td><td>Program Counter value</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s02s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s02s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s05.html
new file mode 100644
index 000000000..a08bf7070
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s05.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>DATA - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s02.html" title="Responses" /><link rel="prev" href="ch05s02s04.html" title="PC" /><link rel="next" href="ch05s02s06.html" title="FAILED" /><meta content="DATA" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s02s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s02s06.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11647" />DATA</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Data is returned. Two versions exists:</p><div class="table"><a id="N1164C" /><p class="title"><strong>Table&nbsp;91.&nbsp;DATA response format version 0</strong></p><div class="table-contents"><table summary="DATA response format version 0" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_RSP_DATA</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version</td><td>1 byte</td><td>Response version</td></tr><tr><td>Data (0x00)</td><td>n bytes</td><td>Data returned</td></tr></tbody></table></div></div><br class="table-break" /><div class="table"><a id="N11676" /><p class="title"><strong>Table&nbsp;92.&nbsp;DATA response format version 1</strong></p><div class="table-contents"><table summary="DATA response format version 1" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_RSP_DATA</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version</td><td>1 byte</td><td>Response version</td></tr><tr><td>Data (0x01)</td><td>n bytes</td><td>Data returned</td></tr><tr><td>Status code</td><td>1 byte</td><td>Trailing status of the read operation indicating whether
+ the data returned is in fact valid. 0x00 = OK.</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s02s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s02s06.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s06.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s06.html
new file mode 100644
index 000000000..6f64eee57
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s02s06.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>FAILED - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s02.html" title="Responses" /><link rel="prev" href="ch05s02s05.html" title="DATA" /><link rel="next" href="ch05s03.html" title="Hints and tips" /><meta content="FAILED" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s02s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N116A7" />FAILED</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The command failed to execute</p><div class="table"><a id="N116AC" /><p class="title"><strong>Table&nbsp;93.&nbsp;FAILED response format</strong></p><div class="table-contents"><table summary="FAILED response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR32_RSP_FAILED</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr><tr><td>Failure Code</td><td>1 byte</td><td>Instance code for failure; 0xFF = unknown</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s02s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03.html
new file mode 100644
index 000000000..7d02558fa
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Hints and tips - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avr32protocol.html" title="AVR32 generic protocol" /><link rel="prev" href="ch05s02s06.html" title="FAILED" /><link rel="next" href="ch05s03s01.html" title="Configuration" /><meta content="Hints and tips" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR32 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s02s06.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avr32protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s03s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N116D6" />Hints and tips</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch05s03s01.html">Configuration</a></span></dt><dt><span class="section"><a href="ch05s03s02.html">Activate and deactivate physical</a></span></dt><dt><span class="section"><a href="ch05s03s03.html">Programming and debugging commands</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s02s06.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avr32protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s03s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s01.html
new file mode 100644
index 000000000..0097735a7
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s01.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Configuration - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s03.html" title="Hints and tips" /><link rel="prev" href="ch05s03.html" title="Hints and tips" /><link rel="next" href="ch05s03s02.html" title="Activate and deactivate physical" /><meta content="Configuration" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Hints and tips</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s03s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N116D9" />Configuration</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Configuration takes place before or during a session is active by using the
+ Query, Set and Get commands. The following configuration elements are
+ required:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>PHYSICAL / INTERFACE: the host must specify whether JTAG or aWire
+ physical interface is to be used</p></li><li class="listitem"><p>PHYSICAL / JTAG_CLOCK: the JTAG clock frequency (in kHz) must be
+ specified when using JTAG mode</p></li><li class="listitem"><p>PHYSICAL / JTAG_DAISY: the JTAG daisy chain parameters must be
+ specified when using a daisy chained target</p></li><li class="listitem"><p>PHYSICAL / AWIRE_BAUD_MAX: the maximum aWire baud rate can be
+ specified when using aWire mode.</p></li></ul></div><p>
+ </p><p>Note that before continuing with activation of physical the CMD_HOUSEKEEPING_START_SESSION must be called, see <a class="xref" href="section_housekeeping_start_session.html" title="Start session">the section called &ldquo;Start session&rdquo;</a>.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s03s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s02.html
new file mode 100644
index 000000000..635e4d02c
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s02.html
@@ -0,0 +1,224 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Activate and deactivate physical - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s03.html" title="Hints and tips" /><link rel="prev" href="ch05s03s01.html" title="Configuration" /><link rel="next" href="ch05s03s03.html" title="Programming and debugging commands" /><meta content="Activate and deactivate physical" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Hints and tips</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s03s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s03s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N116F4" />Activate and deactivate physical</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Once configuration is complete, the host requests that the tool makes a
+ connection to the target by calling the &ldquo;activate physical&rdquo; command. In many
+ interfaces, the physical can be disabled by default or overridden by user
+ code, which implies that an external reset sequence must be applied in order
+ to gain access. In other cases, the external reset must not be used, for
+ example when attaching to a running process. The use of external reset must be
+ specified in the command parameter. </p><p>Activating the physical must be followed by device ID validation, to
+ ensure that the session is capable of starting with the device that is
+ expected. For this reason, the activation command returns an ID packet
+ containing the device ID of the target, as read directly from the target. If
+ no valid device is detected, the command will return FAILED. </p><p>The GET_ID command can also be used to retrieve this value at any stage
+ during the session. It is read out on demand and not cached. </p><p>On completion of a session, the physical must be deactivated. The tool
+ disconnects from the target at this point. In order to re-connect, the
+ physical must be activated again. </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s03s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s03s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s03.html
new file mode 100644
index 000000000..88856f5b8
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s03s03.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Programming and debugging commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s03.html" title="Hints and tips" /><link rel="prev" href="ch05s03s02.html" title="Activate and deactivate physical" /><link rel="next" href="ch05s04.html" title="AVR32GENERIC ID definitions" /><meta content="Programming and debugging commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Hints and tips</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s03s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N116FF" />Programming and debugging commands</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Programming and debugging of AVR UC3 devices is done using the
+ protocol commands described in this document. Very little processing is done
+ on the debugger, leaving the host to control the session. aWire and JTAG
+ functionality is equivalent.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s03s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s04.html
new file mode 100644
index 000000000..4294de672
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch05s04.html
@@ -0,0 +1,360 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>AVR32GENERIC ID definitions - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avr32protocol.html" title="AVR32 generic protocol" /><link rel="prev" href="ch05s03s03.html" title="Programming and debugging commands" /><link rel="next" href="protocoldocs.avr8protocol.html" title="AVR8 generic protocol" /><meta content="AVR32GENERIC ID definitions" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR32 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s03s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avr32protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="protocoldocs.avr8protocol.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N11704" />AVR32GENERIC ID definitions</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">
+ This sections includes the header file defining the different command and
+ response IDs for the AVR32 protocol. It also defines the different possible failure codes.
+ </p><pre class="programlisting"><span class="hl-keyword" style="color: #0000FF">enum</span> Avr32GenericCommands {
+ AVR32_CMD_QUERY = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Capability discovery </em>
+ AVR32_CMD_SET = <span class="hl-number">0x01</span>, <em class="hl-comment" style="color: #008000">//! Set parameters</em>
+ AVR32_CMD_GET = <span class="hl-number">0x02</span>, <em class="hl-comment" style="color: #008000">//! Get parameters</em>
+ AVR32_CMD_ACTIVATE_PHYSICAL = <span class="hl-number">0x03</span>, <em class="hl-comment" style="color: #008000">//! Connect physically</em>
+ AVR32_CMD_DEACTIVATE_PHYSICAL = <span class="hl-number">0x04</span>, <em class="hl-comment" style="color: #008000">//! Disconnect physically</em>
+ AVR32_CMD_GET_ID = <span class="hl-number">0x10</span>, <em class="hl-comment" style="color: #008000">//! Read the ID</em>
+ AVR32_CMD_ERASE = <span class="hl-number">0x11</span>, <em class="hl-comment" style="color: #008000">//! Erase the device</em>
+ AVR32_CMD_HALT = <span class="hl-number">0x12</span>, <em class="hl-comment" style="color: #008000">//! Stop or start execution</em>
+ AVR32_CMD_RESET = <span class="hl-number">0x13</span>, <em class="hl-comment" style="color: #008000">//! Apply or release reset</em>
+ AVR32_CMD_STEP = <span class="hl-number">0x14</span>, <em class="hl-comment" style="color: #008000">//! Single step</em>
+ AVR32_CMD_READ = <span class="hl-number">0x15</span>, <em class="hl-comment" style="color: #008000">//! Read memory</em>
+ AVR32_CMD_WRITE = <span class="hl-number">0x16</span>, <em class="hl-comment" style="color: #008000">//! Write memory</em>
+ AVR32_CMD_TAP = <span class="hl-number">0x17</span>, <em class="hl-comment" style="color: #008000">//! Low-level JTAG commands</em>
+ AVR32_CMD_IS_PROTECTED = <span class="hl-number">0x18</span>, <em class="hl-comment" style="color: #008000">//! Check protected bit</em>
+ AVR32_CMD_ERASE_SECTION = <span class="hl-number">0x19</span> <em class="hl-comment" style="color: #008000">//! Partial erase</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr32GenericResponses {
+ AVR32_RSP_FAILED = <span class="hl-number">0xA0</span>, <em class="hl-comment" style="color: #008000">//! Execution failed</em>
+ AVR32_RSP_OK = <span class="hl-number">0x80</span>, <em class="hl-comment" style="color: #008000">//! All OK</em>
+ AVR32_RSP_LIST = <span class="hl-number">0x81</span>, <em class="hl-comment" style="color: #008000">//! List of items returned</em>
+ AVR32_RSP_ID = <span class="hl-number">0x82</span>, <em class="hl-comment" style="color: #008000">//! ID value returned</em>
+ AVR32_RSP_PC = <span class="hl-number">0x83</span>, <em class="hl-comment" style="color: #008000">//! PC value returned</em>
+ AVR32_RSP_DATA = <span class="hl-number">0x84</span> <em class="hl-comment" style="color: #008000">//! Data returned</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr32GenericQueryContexts {
+ AVR32_QUERY_COMMANDS = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Supported command list</em>
+ AVR32_QUERY_CONFIGURATION = <span class="hl-number">0x05</span>, <em class="hl-comment" style="color: #008000">//! Supported configuration list</em>
+ AVR32_QUERY_READ_MEMTYPES = <span class="hl-number">0x06</span>, <em class="hl-comment" style="color: #008000">//! Supported read memtypes list</em>
+ AVR32_QUERY_WRITE_MEMTYPES = <span class="hl-number">0x07</span>, <em class="hl-comment" style="color: #008000">//! Supported write memtypes list</em>
+ AVR32_QUERY_COMMAND_VERSIONS = <span class="hl-number">0x08</span> <em class="hl-comment" style="color: #008000">//! Version map of command list</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr32GenericSetGetContexts {
+ AVR32_CTXT_USB = <span class="hl-number">0x03</span>, <em class="hl-comment" style="color: #008000">//! Transport-related settings</em>
+ AVR32_CTXT_SESSION = <span class="hl-number">0x04</span>, <em class="hl-comment" style="color: #008000">//! Session-related settings</em>
+ AVR32_CTXT_PHYSICAL = <span class="hl-number">0x80</span>, <em class="hl-comment" style="color: #008000">//! Physical interface related</em>
+ AVR32_CTXT_DEVICE = <span class="hl-number">0x82</span>, <em class="hl-comment" style="color: #008000">//! Device specific settings</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr32GenericSessionContextParameters {
+ AVR32_SESS_RUN_LED = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Control the LED</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr32GenericUsbContextParameters {
+ AVR32_USB_MAX_READ = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Read payload size</em>
+ AVR32_USB_MAX_WRITE = <span class="hl-number">0x01</span> <em class="hl-comment" style="color: #008000">//! Write payload size</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr32GenericPhysicalContextParameters {
+ AVR32_PHY_PHYSICAL = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Physical interface selector</em>
+ AVR32_PHYL_JTAG_CLOCK = <span class="hl-number">0x01</span>, <em class="hl-comment" style="color: #008000">//! JTAG clock value</em>
+ AVR32_PHY_AW_MAXBAUD = <span class="hl-number">0x02</span>, <em class="hl-comment" style="color: #008000">//! Maximum aWire baud</em>
+ AVR32_PHY_DAISY = <span class="hl-number">0x03</span>, <em class="hl-comment" style="color: #008000">//! JTAG daisy chain settings</em>
+ AVR32_PHY_AWIRE_BAUD = <span class="hl-number">0x04</span>, <em class="hl-comment" style="color: #008000">//! Current aWire baud</em>
+ AVR32_PHY_AWIRE_VERSION = <span class="hl-number">0x05</span>, <em class="hl-comment" style="color: #008000">//! aWire slave version</em>
+ AVR32_PHY_EXT_RESET = <span class="hl-number">0x0C</span>, <em class="hl-comment" style="color: #008000">//! External reset control</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr32GenericDeviceContext {
+ AVR32_FLASH_CTRL_BASE = <span class="hl-number">0x02</span>, <em class="hl-comment" style="color: #008000">//! Flash controller base address</em>
+ AVR32_FLASH_PAGEBYTES = <span class="hl-number">0x06</span>, <em class="hl-comment" style="color: #008000">//! Number of bytes in one flash page</em>
+ AVR32_RESET_DOMAINS = <span class="hl-number">0x0A</span>, <em class="hl-comment" style="color: #008000">//! Number of reset domains</em>
+ AVR32_FLASH_PAGES = <span class="hl-number">0x0B</span>, <em class="hl-comment" style="color: #008000">//! Number of pages in the flash block</em>
+ AVR32_AWIRE_BASE = <span class="hl-number">0x10</span> <em class="hl-comment" style="color: #008000">//! Base address for aWire module</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr32GenericMemoryTypes {
+ AVR32_MEMTYPE_SAB = <span class="hl-number">0x80</span>, <em class="hl-comment" style="color: #008000">//! Service Access Bus (SAB) word access</em>
+ AVR32_MEMTYPE_NEXUS = <span class="hl-number">0x81</span>, <em class="hl-comment" style="color: #008000">//! Nexus mode access to SAB</em>
+ AVR32_MEMTYPE_MEMORY_SERVICE = <span class="hl-number">0x82</span>, <em class="hl-comment" style="color: #008000">//! Memory Service mode access to SAB</em>
+ AVR32_MEMTYPE_BLOCK = <span class="hl-number">0x83</span>, <em class="hl-comment" style="color: #008000">//! Block access to SAB</em>
+ AVR32_MEMTYPE_BYTE = <span class="hl-number">0x84</span>, <em class="hl-comment" style="color: #008000">//! 8-bit access to SAB</em>
+ AVR32_MEMTYPE_HALF_WORD = <span class="hl-number">0x85</span>, <em class="hl-comment" style="color: #008000">//! 16-bit access to SAB</em>
+ AVR32_MEMTYPE_INTERNAL_FLASH = <span class="hl-number">0x90</span>, <em class="hl-comment" style="color: #008000">//! Write access to internal FLASH</em>
+ AVR32_MEMTYPE_SYSREG = <span class="hl-number">0x91</span>, <em class="hl-comment" style="color: #008000">//! Access to system registers</em>
+ AVR32_MEMTYPE_REGFILE = <span class="hl-number">0x92</span>, <em class="hl-comment" style="color: #008000">//! Access to register file</em>
+ AVR32_MEMTYPE_USER_PAGE = <span class="hl-number">0x93</span> <em class="hl-comment" style="color: #008000">//! Access to User Page in flash</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr32GenericPhysicalInterfaces {
+ AVR32_PHYSICAL_INTERFACE_NONE = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! No physical</em>
+ AVR32_PHYSICAL_INTERFACE_JTAG = <span class="hl-number">0x04</span>, <em class="hl-comment" style="color: #008000">//! JTAG physical</em>
+ AVR32_PHYSICAL_INTERFACE_AWIRE = <span class="hl-number">0x07</span> <em class="hl-comment" style="color: #008000">//! aWire physical</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr32TapCommands {
+ AVR32_TAP_IR = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! JTAG Instruction Register access</em>
+ AVR32_TAP_DR = <span class="hl-number">0x01</span> <em class="hl-comment" style="color: #008000">//! JTAG Data Register access</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr32GenericFailureCodes {
+ AVR32_FAILURE_OK = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! All OK</em>
+ AVR32_FAILURE_NACK = <span class="hl-number">0x01</span>, <em class="hl-comment" style="color: #008000">//! NACK received from target</em>
+ AVR32_FAILURE_LENGTH = <span class="hl-number">0x02</span>, <em class="hl-comment" style="color: #008000">//! Incorrect packet length</em>
+ AVR32_FAILURE_RECEIVE_TIMEOUT = <span class="hl-number">0x03</span>, <em class="hl-comment" style="color: #008000">//! Receive function timeout</em>
+ AVR32_FAILURE_RECEIVE_SYNC = <span class="hl-number">0x04</span>, <em class="hl-comment" style="color: #008000">//! Receive did not sync</em>
+ AVR32_FAILURE_RECEIVE_LENGTH = <span class="hl-number">0x05</span>, <em class="hl-comment" style="color: #008000">//! Incorrect packet length</em>
+ AVR32_FAILURE_TRANSMIT_OVERFLOW = <span class="hl-number">0x06</span>, <em class="hl-comment" style="color: #008000">//! Transmit buffer overflow</em>
+ AVR32_FAILURE_INVALID_MEMTYPE = <span class="hl-number">0x07</span>, <em class="hl-comment" style="color: #008000">//! Invalid memtype given</em>
+ AVR32_FAILURE_WRITE_ERROR = <span class="hl-number">0x08</span>, <em class="hl-comment" style="color: #008000">//! A write error occurred </em>
+ AVR32_FAILURE_WRITE_BUSY = <span class="hl-number">0x09</span>, <em class="hl-comment" style="color: #008000">//! Busy signal received</em>
+ AVR32_FAILURE_READ_SHORT = <span class="hl-number">0x0A</span>, <em class="hl-comment" style="color: #008000">//! Short-packet received</em>
+ AVR32_FAILURE_ERASE_TIMEOUT = <span class="hl-number">0x0B</span>, <em class="hl-comment" style="color: #008000">//! Erase command timeout </em>
+ AVR32_FAILURE_FLASHREADY_TIMEOUT = <span class="hl-number">0x0C</span>, <em class="hl-comment" style="color: #008000">//! Flash controller busy</em>
+ AVR32_FAILURE_ILLEGAL_STATE = <span class="hl-number">0x0D</span>, <em class="hl-comment" style="color: #008000">//! Illegal state specified</em>
+ AVR32_FAILURE_NOT_SUPPORTED = <span class="hl-number">0x0E</span>, <em class="hl-comment" style="color: #008000">//! Feature not supported</em>
+ AVR32_FAILURE_PROGE = <span class="hl-number">0x0F</span>, <em class="hl-comment" style="color: #008000">//! Programming error</em>
+ AVR32_FAILURE_LOCKE = <span class="hl-number">0x10</span>, <em class="hl-comment" style="color: #008000">//! Lock error</em>
+ AVR32_FAILURE_STEP_TIMEOUT = <span class="hl-number">0x11</span>, <em class="hl-comment" style="color: #008000">//! Single stepping timeout</em>
+ AVR32_FAILURE_READ_BUSY = <span class="hl-number">0x12</span>, <em class="hl-comment" style="color: #008000">//! Busy bit was set</em>
+ AVR32_FAILURE_READ_ERROR = <span class="hl-number">0x13</span>, <em class="hl-comment" style="color: #008000">//! Error bit was set</em>
+ AVR32_FAILURE_HARDWARE_ERROR = <span class="hl-number">0x14</span>, <em class="hl-comment" style="color: #008000">//! aWire hardware init error</em>
+ AVR32_FAILURE_NO_CONTACT = <span class="hl-number">0x15</span>, <em class="hl-comment" style="color: #008000">//! No response from aWire </em>
+ AVR32_FAILURE_NO_TARGET_POWER = <span class="hl-number">0x16</span>, <em class="hl-comment" style="color: #008000">//! No target power </em>
+ AVR32_FAILURE_NOT_IMPLEMENTED = <span class="hl-number">0x17</span>, <em class="hl-comment" style="color: #008000">//! Command not implemented</em>
+ AVR32_FAILURE_UNSUPPORTED_HARDWARE = <span class="hl-number">0x18</span>, <em class="hl-comment" style="color: #008000">//! Hardware not supported</em>
+ AVR32_FAILURE_JTAGM_INIT_ERROR = <span class="hl-number">0x19</span>, <em class="hl-comment" style="color: #008000">//! JTAG master init error</em>
+ AVR32_FAILURE_NO_DEVICE_FOUND = <span class="hl-number">0x1A</span>, <em class="hl-comment" style="color: #008000">//! devices == 0! </em>
+ AVR32_FAILURE_JTAGM_ERROR = <span class="hl-number">0x1B</span>, <em class="hl-comment" style="color: #008000">//! JTAG master error</em>
+ AVR32_FAILURE_INVALID_SIZE = <span class="hl-number">0x1D</span>, <em class="hl-comment" style="color: #008000">//! Too many or too few bytes</em>
+ AVR32_FAILURE_INVALID_ADDRESS = <span class="hl-number">0x1E</span>, <em class="hl-comment" style="color: #008000">//! Bad address requested</em>
+ AVR32_FAILURE_AWIRE_SET_BAUD_ERROR = <span class="hl-number">0x1F</span>, <em class="hl-comment" style="color: #008000">//! Failure setting baud </em>
+ AVR32_FAILURE_INVALID_DATA = <span class="hl-number">0x20</span>, <em class="hl-comment" style="color: #008000">//! Data invalid, discard it</em>
+ AVR32_FAILURE_INVALID_PHYSICAL_MODE = <span class="hl-number">0x21</span>, <em class="hl-comment" style="color: #008000">//! Physical mode not valid </em>
+ AVR32_FAILURE_INVALID_CLOCK_SPEED = <span class="hl-number">0x22</span>, <em class="hl-comment" style="color: #008000">//! The clock is not valid</em>
+ AVR32_FAILURE_AWIRE_ERROR_RESPONSE = <span class="hl-number">0x23</span>, <em class="hl-comment" style="color: #008000">//! Error response received</em>
+ AVR32_FAILURE_AWIRE_OVERFLOW = <span class="hl-number">0x24</span>, <em class="hl-comment" style="color: #008000">//! Overflow data RX overflow</em>
+ AVR32_FAILURE_AWM_ERROR = <span class="hl-number">0x24</span>, <em class="hl-comment" style="color: #008000">//! aWire master error</em>
+ AVR32_FAILURE_AWIRE_CRC = <span class="hl-number">0x25</span>, <em class="hl-comment" style="color: #008000">//! aWire CRC error</em>
+ AVR32_FAILURE_AWIRE_TUNE = <span class="hl-number">0x26</span>, <em class="hl-comment" style="color: #008000">//! aWire TUNE error</em>
+ AVR32_FAILURE_JTAGM_WAS_BUSY = <span class="hl-number">0x29</span>, <em class="hl-comment" style="color: #008000">//! JTAG master busy </em>
+ AVR32_FAILURE_JTAGM_TIMEOUT = <span class="hl-number">0x2A</span>, <em class="hl-comment" style="color: #008000">//! JTAG master timeout</em>
+ AVR32_FAILURE_BAD_VALUE = <span class="hl-number">0x2B</span>, <em class="hl-comment" style="color: #008000">//! Invalid parameter value</em>
+ AVR32_FAILURE_ERASE_ERROR = <span class="hl-number">0x2C</span>, <em class="hl-comment" style="color: #008000">//! Erase error</em>
+ AVR32_FAILURE_CONFIG_ERROR = <span class="hl-number">0x2D</span>, <em class="hl-comment" style="color: #008000">//! Insufficient config info</em>
+ AVR32_FAILURE_INVALID_EMULATOR_MODE = <span class="hl-number">0x2E</span>, <em class="hl-comment" style="color: #008000">//! Mode is not valid </em>
+ AVR32_FAILURE_CPU_DIRTY_TIMEOUT = <span class="hl-number">0x2F</span>, <em class="hl-comment" style="color: #008000">//! CPU wait timeout</em>
+ AVR32_FAILURE_CPU_MODE = <span class="hl-number">0x30</span>, <em class="hl-comment" style="color: #008000">//! CPU not in debug mode </em>
+ AVR32_FAILURE_CPU_DEBUG_MODE_TIMEOUT = <span class="hl-number">0x31</span>, <em class="hl-comment" style="color: #008000">//! CPU debug mode timeout</em>
+ AVR32_FAILURE_AWIRE_RW_STATUS = <span class="hl-number">0x32</span>, <em class="hl-comment" style="color: #008000">//! Unexpected status</em>
+ AVR32_FAILURE_TRANSMIT_TIMEOUT = <span class="hl-number">0x33</span>, <em class="hl-comment" style="color: #008000">//! Data TX timeout</em>
+ AVR32_FAILURE_INTERNAL_RESPONSE_ERROR = <span class="hl-number">0xFE</span>, <em class="hl-comment" style="color: #008000">//! Near disaster</em>
+ AVR32_FAILURE_UNKNOWN = <span class="hl-number">0xFF</span>, <em class="hl-comment" style="color: #008000">//! Disaster</em>
+};</pre></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s03s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avr32protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="protocoldocs.avr8protocol.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01.html
new file mode 100644
index 000000000..e1c6693ce
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Protocol Commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avr8protocol.html" title="AVR8 generic protocol" /><link rel="prev" href="protocoldocs.avr8protocol.html" title="AVR8 generic protocol" /><link rel="next" href="ch06s01s01.html" title="QUERY" /><meta content="Protocol Commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR8 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="protocoldocs.avr8protocol.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avr8protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N11715" />Protocol Commands</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch06s01s01.html">QUERY</a></span></dt><dt><span class="section"><a href="ch06s01s02.html">SET</a></span></dt><dt><span class="section"><a href="ch06s01s03.html">GET</a></span></dt><dt><span class="section"><a href="ch06s01s04.html">Activate Physical</a></span></dt><dt><span class="section"><a href="ch06s01s05.html">Deactivate Physical</a></span></dt><dt><span class="section"><a href="ch06s01s06.html">Get ID</a></span></dt><dt><span class="section"><a href="ch06s01s07.html">Attach</a></span></dt><dt><span class="section"><a href="ch06s01s08.html">Detach</a></span></dt><dt><span class="section"><a href="ch06s01s09.html">Reset</a></span></dt><dt><span class="section"><a href="ch06s01s10.html">Stop</a></span></dt><dt><span class="section"><a href="ch06s01s11.html">Run</a></span></dt><dt><span class="section"><a href="ch06s01s12.html">Run To</a></span></dt><dt><span class="section"><a href="ch06s01s13.html">Step</a></span></dt><dt><span class="section"><a href="ch06s01s14.html">PC read</a></span></dt><dt><span class="section"><a href="ch06s01s15.html">PC write</a></span></dt><dt><span class="section"><a href="ch06s01s16.html">Prog Mode Enter</a></span></dt><dt><span class="section"><a href="ch06s01s17.html">Prog Mode Leave</a></span></dt><dt><span class="section"><a href="ch06s01s18.html">Disable debugWIRE</a></span></dt><dt><span class="section"><a href="ch06s01s19.html">Erase</a></span></dt><dt><span class="section"><a href="ch06s01s20.html">CRC</a></span></dt><dt><span class="section"><a href="ch06s01s21.html">Memory Read</a></span></dt><dt><span class="section"><a href="ch06s01s22.html">Memory Read masked</a></span></dt><dt><span class="section"><a href="ch06s01s23.html">Memory Write</a></span></dt><dt><span class="section"><a href="ch06s01s24.html">Page Erase</a></span></dt><dt><span class="section"><a href="ch06s01s25.html">Hardware Breakpoint Set</a></span></dt><dt><span class="section"><a href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></dt><dt><span class="section"><a href="ch06s01s27.html">Software Breakpoint Set</a></span></dt><dt><span class="section"><a href="ch06s01s28.html">Software Breakpoint Clear</a></span></dt><dt><span class="section"><a href="ch06s01s29.html">Software Breakpoint Clear All</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="protocoldocs.avr8protocol.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avr8protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s01.html
new file mode 100644
index 000000000..160dad9d2
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s01.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>QUERY - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01.html" title="Protocol Commands" /><link rel="next" href="section_avr8_query_contexts.html" title="AVR8 QUERY contexts" /><meta content="QUERY" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_avr8_query_contexts.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11718" />QUERY</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></dt></dl></div><p>Used to discover the capabilities of the tool.</p><p>For lists of valid query types, see <a class="xref" href="section_avr8_query_contexts.html" title="AVR8 QUERY contexts">the section called &ldquo;AVR8 QUERY contexts&rdquo;</a></p><p>
+ </p><div class="table"><a id="N11724" /><p class="title"><strong>Table&nbsp;94.&nbsp;Query</strong></p><div class="table-contents"><table summary="Query" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>QUERY (0x00)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Query context</td><td>1 byte</td><td>Type of query to execute</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>LIST</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_avr8_query_contexts.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s02.html
new file mode 100644
index 000000000..566a0e63f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s02.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SET - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="section_avr8_query_contexts.html" title="AVR8 QUERY contexts" /><link rel="next" href="ch06s01s03.html" title="GET" /><meta content="SET" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_avr8_query_contexts.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11792" />SET</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Used to set parameters on the tool..</p><p>For lists of valid get / set paramters, see <a class="xref" href="section_avr8_setget_params.html" title="SET/GET parameters">the section called &ldquo;SET/GET parameters&rdquo;</a></p><p>
+ </p><div class="table"><a id="N1179E" /><p class="title"><strong>Table&nbsp;96.&nbsp;Set</strong></p><div class="table-contents"><table summary="Set" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SET (0x01)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Set context</td><td>1 byte</td><td>Context of the parameter to set</td></tr><tr><td>Address</td><td>1 byte</td><td>Parameter ID / start address</td></tr><tr><td>Bytes</td><td>1 byte</td><td>Number of bytes to write</td></tr><tr><td>Data</td><td>N bytes</td><td>Data to write</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p><p>Note: Setting multiple parameters in one set call can only be done when all fields
+ are in the same context.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_avr8_query_contexts.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s03.html
new file mode 100644
index 000000000..b93f1df0d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s03.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>GET - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s02.html" title="SET" /><link rel="next" href="section_avr8_setget_params.html" title="SET/GET parameters" /><meta content="GET" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_avr8_setget_params.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N117E9" />GET</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="section_avr8_setget_params.html">SET/GET parameters</a></span></dt></dl></div><p>Used to get parameters on the tool..</p><p>For lists of valid get / set paramters, see <a class="xref" href="section_avr8_setget_params.html" title="SET/GET parameters">the section called &ldquo;SET/GET parameters&rdquo;</a>.</p><p>
+ </p><div class="table"><a id="N117F6" /><p class="title"><strong>Table&nbsp;97.&nbsp;Get</strong></p><div class="table-contents"><table summary="Get" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>GET (0x02)</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Get context</td><td>1 byte</td><td>Context of the parameter to get</td></tr><tr><td>Address</td><td>1 byte</td><td>Parameter ID / start address</td></tr><tr><td>Bytes</td><td>1 byte</td><td>Number of bytes to read</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p><p>Note: Getting multiple parameters in one set call can only be done when all fields
+ are in the same context.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_avr8_setget_params.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s04.html
new file mode 100644
index 000000000..4bb7f0dec
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s04.html
@@ -0,0 +1,217 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Activate Physical - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="section_avr8_setget_params.html" title="SET/GET parameters" /><link rel="next" href="ch06s01s05.html" title="Deactivate Physical" /><meta content="Activate Physical" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_avr8_setget_params.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11B16" />Activate Physical</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Activates the selected physical interface, if necessary, and makes contact
+ with the target interface. If no interface is detected, a FAILED response is
+ returned. If it is possible to read out the device ID, then this value is
+ returned (length depends on the interface). If not, a simple OK is
+ returned.</p><div class="table"><a id="N11B1B" /><p class="title"><strong>Table&nbsp;102.&nbsp;Activate Physical command format</strong></p><div class="table-contents"><table summary="Activate Physical command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>RSP_AVR8_ACTIVATE_PHYSICAL</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Reset</td><td>1 bytes</td><td><p>0x00: no NOT use external reset</p><p>0x01: apply external reset during activation</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_avr8_setget_params.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s05.html
new file mode 100644
index 000000000..91c248e1a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s05.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Deactivate Physical - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s04.html" title="Activate Physical" /><link rel="next" href="ch06s01s06.html" title="Get ID" /><meta content="Deactivate Physical" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s06.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11B57" />Deactivate Physical</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">De-activates the physical interface and disconnects from the target. After this, the debugger has no connection to the target.</p><p>Note: This may be done implicitly by another command.</p><div class="table"><a id="N11B5E" /><p class="title"><strong>Table&nbsp;103.&nbsp;Deactivate Physical command format</strong></p><div class="table-contents"><table summary="Deactivate Physical command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_DEACTIVATE_PHYSICAL</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s06.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s06.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s06.html
new file mode 100644
index 000000000..f6d33e77b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s06.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Get ID - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s05.html" title="Deactivate Physical" /><link rel="next" href="ch06s01s07.html" title="Attach" /><meta content="Get ID" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s07.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11B8D" />Get ID</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Retrieves the ID of the target. The same ID is returned by Activate
+ Physical command. Any previously read value is not cached, but re-read from the
+ target.</p><div class="table"><a id="N11B92" /><p class="title"><strong>Table&nbsp;104.&nbsp;Get ID command format</strong></p><div class="table-contents"><table summary="Get ID command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_GET_ID</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s07.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s07.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s07.html
new file mode 100644
index 000000000..a315297c1
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s07.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Attach - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s06.html" title="Get ID" /><link rel="next" href="ch06s01s08.html" title="Detach" /><meta content="Attach" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s06.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s08.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11BC1" />Attach</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Enters debug mode on the target</p><div class="table"><a id="N11BC6" /><p class="title"><strong>Table&nbsp;105.&nbsp;Attach command format</strong></p><div class="table-contents"><table summary="Attach command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_ATTACH</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Break</td><td>1 byte</td><td><p>0x00 = Continue running</p><p>0x01 = Break after attach</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s06.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s08.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s08.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s08.html
new file mode 100644
index 000000000..e72779d9b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s08.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Detach - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s07.html" title="Attach" /><link rel="next" href="ch06s01s09.html" title="Reset" /><meta content="Detach" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s07.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s09.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11BFF" />Detach</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Terminates a debug session on the target. </p><div class="table"><a id="N11C04" /><p class="title"><strong>Table&nbsp;106.&nbsp;Detach command format</strong></p><div class="table-contents"><table summary="Detach command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_DETACH</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s07.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s09.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s09.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s09.html
new file mode 100644
index 000000000..d2fc1967d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s09.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Reset - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s08.html" title="Detach" /><link rel="next" href="ch06s01s10.html" title="Stop" /><meta content="Reset" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s08.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s10.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11C33" />Reset</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Resets the target and holds it stopped, in reset. A break event will be
+ sent when the reset is done and the target is stopped.</p><div class="table"><a id="N11C38" /><p class="title"><strong>Table&nbsp;107.&nbsp;Reset command format</strong></p><div class="table-contents"><table summary="Reset command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_RESET</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Level</td><td>1 byte</td><td><p>0x01: stop at boot reset vector</p><p>0x02: stop at main
+ address (deprecated)</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s08.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s10.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s10.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s10.html
new file mode 100644
index 000000000..d3f4e9525
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s10.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Stop - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s09.html" title="Reset" /><link rel="next" href="ch06s01s11.html" title="Run" /><meta content="Stop" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s09.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s11.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11C71" />Stop</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Stops execution on the target. A break event will be sent when the target
+ is stopped.</p><div class="table"><a id="N11C76" /><p class="title"><strong>Table&nbsp;108.&nbsp;Stop command format</strong></p><div class="table-contents"><table summary="Stop command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_STOP</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Level</td><td>1 byte</td><td><p>0x01: stop immediately</p><p>0x02: stop at next symbol (deprecated)</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s09.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s11.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s11.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s11.html
new file mode 100644
index 000000000..9838850fb
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s11.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Run - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s10.html" title="Stop" /><link rel="next" href="ch06s01s12.html" title="Run To" /><meta content="Run" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s10.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s12.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11CAF" />Run</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Resumes execution on the target</p><div class="table"><a id="N11CB4" /><p class="title"><strong>Table&nbsp;109.&nbsp;Run command format</strong></p><div class="table-contents"><table summary="Run command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_RUN</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s10.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s12.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s12.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s12.html
new file mode 100644
index 000000000..3c82c435c
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s12.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Run To - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s11.html" title="Run" /><link rel="next" href="ch06s01s13.html" title="Step" /><meta content="Run To" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s11.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s13.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11CE3" />Run To</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Resumes execution on the target, with an internal breakpoint at the given
+ location. A break event is sent when the target has reached the
+ breakpoint. (This breakpoint cannot be accessed by any other means.)</p><div class="table"><a id="N11CE8" /><p class="title"><strong>Table&nbsp;110.&nbsp;Run To command format</strong></p><div class="table-contents"><table summary="Run To command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_RUN_TO_ADDRESS</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Address</td><td>4 bytes</td><td>Address to run to (word address)</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s11.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s13.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s13.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s13.html
new file mode 100644
index 000000000..361df065f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s13.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Step - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s12.html" title="Run To" /><link rel="next" href="ch06s01s14.html" title="PC read" /><meta content="Step" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s12.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s14.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11D1E" />Step</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Performs a single step on the target. Returns OK once the step has
+ successfully been initiated. Once the step has completed a BREAK event is generated
+ asynchronously.</p><div class="table"><a id="N11D23" /><p class="title"><strong>Table&nbsp;111.&nbsp;Step command format</strong></p><div class="table-contents"><table summary="Step command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_STEP</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Level</td><td>1 byte</td><td><p>0x01: instruction level step</p><p>0x02: statement level
+ step (deprecated)</p></td></tr><tr><td>Mode</td><td>1 byte</td><td><p>0x00: step over (deprecated)</p><p>0x01: step into</p><p>0x02: step out (deprecated)</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s12.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s14.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s14.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s14.html
new file mode 100644
index 000000000..ea3525247
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s14.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>PC read - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s13.html" title="Step" /><link rel="next" href="ch06s01s15.html" title="PC write" /><meta content="PC read" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s13.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s15.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11D68" />PC read</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads the PC (word address) on the target.</p><div class="table"><a id="N11D6D" /><p class="title"><strong>Table&nbsp;112.&nbsp;PC read command format</strong></p><div class="table-contents"><table summary="PC read command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_PC_READ</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>PC</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s13.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s15.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s15.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s15.html
new file mode 100644
index 000000000..c9c76a1f0
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s15.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>PC write - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s14.html" title="PC read" /><link rel="next" href="ch06s01s16.html" title="Prog Mode Enter" /><meta content="PC write" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s14.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s16.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11D9C" />PC write</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Modifies the PC on the target. </p><div class="table"><a id="N11DA1" /><p class="title"><strong>Table&nbsp;113.&nbsp;PC write command format</strong></p><div class="table-contents"><table summary="PC write command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_PC_WRITE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>PC</td><td>4 bytes</td><td>Program Counter value (word address)</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s14.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s16.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s16.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s16.html
new file mode 100644
index 000000000..fe394e6ba
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s16.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Prog Mode Enter - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s15.html" title="PC write" /><link rel="next" href="ch06s01s17.html" title="Prog Mode Leave" /><meta content="Prog Mode Enter" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s15.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s17.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11DD7" />Prog Mode Enter</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Enters programming mode on the target.</p><div class="table"><a id="N11DDC" /><p class="title"><strong>Table&nbsp;114.&nbsp;Prog Mode Enter command format</strong></p><div class="table-contents"><table summary="Prog Mode Enter command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_PROG_MODE_ENTER</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s15.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s17.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s17.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s17.html
new file mode 100644
index 000000000..939388d18
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s17.html
@@ -0,0 +1,217 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Prog Mode Leave - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s16.html" title="Prog Mode Enter" /><link rel="next" href="ch06s01s18.html" title="Disable debugWIRE" /><meta content="Prog Mode Leave" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s16.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s18.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11E0B" />Prog Mode Leave</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Exits programming mode on the target.</p><p>If the &lsquo;programming&rsquo; flag is set in
+ the config context, the target will be released to run, and the debugger
+ deactivates the physical. This is the desired behaviour for a pure programming session.</p><p>If the &lsquo;debugging&rsquo; flag is set, the target will be stopped at the reset vector . A Break
+ event will always be sent when 'debugging' flag is set. If the 'debugging' flag
+ is set and the Attach command has not yet been run it will be run automatically during Prog Mode Leave.</p><div class="table"><a id="N11E14" /><p class="title"><strong>Table&nbsp;115.&nbsp;Prog Mode Leave command format</strong></p><div class="table-contents"><table summary="Prog Mode Leave command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_PROG_MODE_LEAVE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s16.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s18.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s18.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s18.html
new file mode 100644
index 000000000..64ff30f74
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s18.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Disable debugWIRE - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s17.html" title="Prog Mode Leave" /><link rel="next" href="ch06s01s19.html" title="Erase" /><meta content="Disable debugWIRE" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s17.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s19.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11E43" />Disable debugWIRE</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Resets the target and temporarily disables the debugwire interface.</p><p>In this state the debugWIRE module will no longer be in control of the /RESET pin.
+ The value of the DWEN fuse is unaffected.
+ Cycling power in this state will cause the debugWIRE module to regain control of the /RESET pin</p><div class="table"><a id="N11E4A" /><p class="title"><strong>Table&nbsp;116.&nbsp;Disable debugWIRE command format</strong></p><div class="table-contents"><table summary="Disable debugWIRE command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_DISABLE_DEBUGWIRE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s17.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s19.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s19.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s19.html
new file mode 100644
index 000000000..48853cb9b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s19.html
@@ -0,0 +1,220 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Erase - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s18.html" title="Disable debugWIRE" /><link rel="next" href="ch06s01s20.html" title="CRC" /><meta content="Erase" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s18.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s20.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11E79" />Erase</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Performs an erase on the target. Functionality varies according to target family.</p><div class="table"><a id="N11E7E" /><p class="title"><strong>Table&nbsp;117.&nbsp;Erase command format</strong></p><div class="table-contents"><table summary="Erase command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_ERASE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Mode</td><td>1 byte</td><td><p>0x00 = Chip erase</p>
+ <p>0x01 = Application erase</p>
+ <p>0x02 = Boot section erase</p>
+ <p>0x03 = EEPROM erase</p>
+ <p>0x04 = Applicaton page erase</p>
+ <p>0x05 = Boot page erase</p>
+ <p>0x06 = EEPROM page erase</p>
+ <p>0x07 = User signature erase</p></td></tr><tr><td>Address</td><td>4 bytes</td><td>Start address of section to erase (byte address)</td></tr></tbody></table></div></div><br class="table-break" /><p>Note: tinyAVR and megaAVR (debugWIRE) does not support any erase functionlity - flash pages are erased automatically before programming.</p><p>Note: megaAVR (JTAG) support only chip erase mode - Mode and Address parameters are ignored.</p><p>Note: AVR XMEGA requires Mode and Address parameters.</p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s18.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s20.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s20.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s20.html
new file mode 100644
index 000000000..0be622a45
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s20.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>CRC - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s19.html" title="Erase" /><link rel="next" href="ch06s01s21.html" title="Memory Read" /><meta content="CRC" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s19.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s21.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11ED7" />CRC</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Calculates a CRC checksum on the target flash.</p><div class="table"><a id="N11EDC" /><p class="title"><strong>Table&nbsp;118.&nbsp;CRC command format</strong></p><div class="table-contents"><table summary="CRC command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_CRC</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Mode</td><td>1 byte</td><td><p>0x00 = use address range</p>
+ <p>0x01 = application section</p>
+ <p>0x02 = boot section</p>
+ <p>0x03 = entire flash</p></td></tr><tr><td>Start Address</td><td>4 bytes</td><td>First address for CRC (byte address)</td></tr><tr><td>End Address</td><td>4 bytes</td><td>Last address for CRC (byte address)</td></tr></tbody></table></div></div><br class="table-break" /><p>Note: This command applies to only some AVR XMEGA targets.</p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s19.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s21.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s21.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s21.html
new file mode 100644
index 000000000..a7d6b7d95
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s21.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Memory Read - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s20.html" title="CRC" /><link rel="next" href="ch06s01s22.html" title="Memory Read masked" /><meta content="Memory Read" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s20.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s22.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11F2C" />Memory Read</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads memory from the target. </p><p>Memories can only be accessed when the device is in STOPPED mode.</p><div class="table"><a id="N11F33" /><p class="title"><strong>Table&nbsp;119.&nbsp;Memory Read command format</strong></p><div class="table-contents"><table summary="Memory Read command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_MEMORY_READ</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Type</td><td>1 byte</td><td>Memory type to access. For overview of memory types see <a class="xref" href="section_avr8_memtypes.html" title="Memory Types">the section called &ldquo;Memory Types&rdquo;</a>.</td></tr><tr><td>Address</td><td>4 bytes</td><td>Start address (byte address) of memory to access.</td></tr><tr><td>Bytes</td><td>4 bytes</td><td>Number of bytes to access. Payload restrictions
+ apply</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s20.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s22.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s22.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s22.html
new file mode 100644
index 000000000..857cfaeb8
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s22.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Memory Read masked - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s21.html" title="Memory Read" /><link rel="next" href="ch06s01s23.html" title="Memory Write" /><meta content="Memory Read masked" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s21.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s23.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11F7B" />Memory Read masked</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads memory on the target, skipping some locations by applying a
+ mask. Can be used, for example, to prevent reading locations which are
+ implemented as FIFO pointers which are altered by reading them.</p><p>Memories can only be accessed when the device is in STOPPED mode.</p><div class="table"><a id="N11F82" /><p class="title"><strong>Table&nbsp;120.&nbsp;Memory Read masked command format</strong></p><div class="table-contents"><table summary="Memory Read masked command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_MEMORY_READ</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Type</td><td>1 byte</td><td>Memory type to access. For overview of memory types see <a class="xref" href="section_avr8_memtypes.html" title="Memory Types">the section called &ldquo;Memory Types&rdquo;</a>.</td></tr><tr><td>Address</td><td>4 bytes</td><td>Start address (byte address) of memory to access.</td></tr><tr><td>Bytes</td><td>4 bytes</td><td>Number of bytes to access. Payload restrictions apply</td></tr><tr><td>Mask</td><td>n/8 bytes</td><td><p>Mask to apply while reading.</p><p>1 bit per location byte, 0 = skip location, 1 = read location</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>DATA</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s21.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s23.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s23.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s23.html
new file mode 100644
index 000000000..66ef8e9e8
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s23.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Memory Write - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s22.html" title="Memory Read masked" /><link rel="next" href="ch06s01s24.html" title="Page Erase" /><meta content="Memory Write" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s22.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s24.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11FD4" />Memory Write</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Writes memory on the target.</p><p>Memories can only be accessed when the device is in STOPPED mode.</p><div class="table"><a id="N11FDB" /><p class="title"><strong>Table&nbsp;121.&nbsp;Memory Write command format</strong></p><div class="table-contents"><table summary="Memory Write command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_MEMORY_WRITE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Type</td><td>1 byte</td><td>Memory type to access. For overview of memory types see <a class="xref" href="section_avr8_memtypes.html" title="Memory Types">the section called &ldquo;Memory Types&rdquo;</a>.</td></tr><tr><td>Address</td><td>4 bytes</td><td>Start address [byte address] of memory to access.</td></tr><tr><td>Bytes</td><td>4 bytes</td><td>Number of bytes to access. Payload restrictions
+ apply</td></tr><tr><td>Asynchronous</td><td>1 byte</td><td><p>0x00 = write first, then reply</p>
+ <p>0x01 = reply first, then write</p></td></tr><tr><td>Data</td><td>n bytes</td><td>Payload restrictions apply</td></tr></tbody></table></div></div><br class="table-break" /><p>Note: Any error encountered during an asynchronous write will be reported on the following write.</p><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s22.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s24.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s24.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s24.html
new file mode 100644
index 000000000..08ac0851d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s24.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Page Erase - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s23.html" title="Memory Write" /><link rel="next" href="ch06s01s25.html" title="Hardware Breakpoint Set" /><meta content="Page Erase" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s23.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s25.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12037" />Page Erase</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Performs a page-erase on the target. </p><p>Note: This can only be done during debug mode, not programming mode, and only applies to megaAVR (JTAG)</p><div class="table"><a id="N1203E" /><p class="title"><strong>Table&nbsp;122.&nbsp;Page Erase command format</strong></p><div class="table-contents"><table summary="Page Erase command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_PAGE_ERASE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Address</td><td>4 bytes</td><td>Start address (byte address) of flash page to
+ erase</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s23.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s25.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s25.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s25.html
new file mode 100644
index 000000000..ffcd1f490
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s25.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Hardware Breakpoint Set - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s24.html" title="Page Erase" /><link rel="next" href="ch06s01s26.html" title="Hardware Breakpoint Clear" /><meta content="Hardware Breakpoint Set" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s24.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s26.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12074" />Hardware Breakpoint Set</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Allocates hardware breakpoint resources on the target OCD module.</p><p>Note: tinyAVR and megaAVR(debugWIRE) has no hardware breakpoint resources.</p><p>Note: megaAVR (JTAG) supports 3 hardware breakpoints.</p><p>Note: AVR XMEGA supports 2 hardware breakpoints.</p><div class="table"><a id="N1207F" /><p class="title"><strong>Table&nbsp;123.&nbsp;Hardware Breakpoint Set command format</strong></p><div class="table-contents"><table summary="Hardware Breakpoint Set command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_HW_BREAK_SET</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Type</td><td>1 byte</td><td><p>0x01: program break</p></td></tr><tr><td>Number</td><td>1 byte</td><td>Breakpoint number to set (1, 2 or 3)</td></tr><tr><td>Address</td><td>4 bytes</td><td>Address (word address)/ value to use</td></tr><tr><td>Mode</td><td>1 byte</td><td><p>0x03: program break</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s24.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s26.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s26.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s26.html
new file mode 100644
index 000000000..568f099f5
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s26.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Hardware Breakpoint Clear - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s25.html" title="Hardware Breakpoint Set" /><link rel="next" href="ch06s01s27.html" title="Software Breakpoint Set" /><meta content="Hardware Breakpoint Clear" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s25.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s27.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N120CE" />Hardware Breakpoint Clear</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Clears hardware breakpoint resources on the target OCD module.</p><p>Note: tinyAVR and megaAVR(debugWIRE) has no hardware breakpoint resources.</p><p>Note: megaAVR (JTAG) supports 3 hardware breakpoints.</p><p>Note: AVR XMEGA supports 2 hardware breakpoints.</p><div class="table"><a id="N120D9" /><p class="title"><strong>Table&nbsp;124.&nbsp;Hardware Breakpoint Clear command format</strong></p><div class="table-contents"><table summary="Hardware Breakpoint Clear command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_HW_BREAK_CLR</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>Number</td><td>1 byte</td><td>Breakpoint number to clear (1, 2 or 3)</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s25.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s27.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s27.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s27.html
new file mode 100644
index 000000000..3567113c7
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s27.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Software Breakpoint Set - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s26.html" title="Hardware Breakpoint Clear" /><link rel="next" href="ch06s01s28.html" title="Software Breakpoint Clear" /><meta content="Software Breakpoint Set" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s26.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s28.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12110" />Software Breakpoint Set</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Inserts a set of software breakpoints on the target. Breakpoints are only
+ inserted to flash when the next flow control command is executed.</p><div class="table"><a id="N12115" /><p class="title"><strong>Table&nbsp;125.&nbsp;Software Breakpoint Set command format</strong></p><div class="table-contents"><table summary="Software Breakpoint Set command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_SW_BREAKPOINT_SET</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>n x Address</td><td>n x 4 bytes</td><td><p>Address (byte address) list to break at. </p>
+ <p>Note: n &gt; 0; n &lt; MAX_SW_BREAKS</p>
+ <p>payload restrictions apply</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s26.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s28.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s28.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s28.html
new file mode 100644
index 000000000..90793d9e6
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s28.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Software Breakpoint Clear - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s27.html" title="Software Breakpoint Set" /><link rel="next" href="ch06s01s29.html" title="Software Breakpoint Clear All" /><meta content="Software Breakpoint Clear" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s27.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s29.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12152" />Software Breakpoint Clear</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Clears a set of software breakpoints on the target. Breakpoints are only
+ removed from flash when the next flow control command is executed.</p><div class="table"><a id="N12157" /><p class="title"><strong>Table&nbsp;126.&nbsp;Software Breakpoint Clear command format</strong></p><div class="table-contents"><table summary="Software Breakpoint Clear command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_SW_BREAKPOINT_CLR</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr><tr><td>n x Address</td><td>n x 4 bytes</td><td><p>Address (byte address) list to clear at. </p>
+ <p>Note: n &gt; 0; n &lt; MAX_SW_BREAKS</p>
+ <p>payload restrictions apply</p></td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s27.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s29.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s29.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s29.html
new file mode 100644
index 000000000..05c04de12
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s01s29.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Software Breakpoint Clear All - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01.html" title="Protocol Commands" /><link rel="prev" href="ch06s01s28.html" title="Software Breakpoint Clear" /><link rel="next" href="ch06s02.html" title="Responses" /><meta content="Software Breakpoint Clear All" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Protocol Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s28.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12194" />Software Breakpoint Clear All</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Removes all software breakpoints immediately. Useful if you have
+ forgotten where you put them.</p><div class="table"><a id="N12199" /><p class="title"><strong>Table&nbsp;127.&nbsp;Software Breakpoint Clear All command format</strong></p><div class="table-contents"><table summary="Software Breakpoint Clear All command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_AVR8_SW_BREAKPOINT_CLR_ALL</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s28.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02.html
new file mode 100644
index 000000000..762bf9846
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Responses - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avr8protocol.html" title="AVR8 generic protocol" /><link rel="prev" href="ch06s01s29.html" title="Software Breakpoint Clear All" /><link rel="next" href="ch06s02s01.html" title="OK" /><meta content="Responses" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR8 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s29.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avr8protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s02s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N121C8" />Responses</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch06s02s01.html">OK</a></span></dt><dt><span class="section"><a href="ch06s02s02.html">LIST</a></span></dt><dt><span class="section"><a href="ch06s02s03.html">PC</a></span></dt><dt><span class="section"><a href="ch06s02s04.html">DATA</a></span></dt><dt><span class="section"><a href="ch06s02s05.html">FAILED</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s29.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avr8protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s02s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s01.html
new file mode 100644
index 000000000..25b97f941
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>OK - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s02.html" title="Responses" /><link rel="prev" href="ch06s02.html" title="Responses" /><link rel="next" href="ch06s02s02.html" title="LIST" /><meta content="OK" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s02s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N121CB" />OK</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The command was executed successfully</p><div class="table"><a id="N121D0" /><p class="title"><strong>Table&nbsp;128.&nbsp;OK response format</strong></p><div class="table-contents"><table summary="OK response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>RSP_AVR8_OK</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s02s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s02.html
new file mode 100644
index 000000000..0004271e5
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>LIST - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s02.html" title="Responses" /><link rel="prev" href="ch06s02s01.html" title="OK" /><link rel="next" href="ch06s02s03.html" title="PC" /><meta content="LIST" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s02s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s02s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N121F3" />LIST</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">List of data returned</p><div class="table"><a id="N121F8" /><p class="title"><strong>Table&nbsp;129.&nbsp;LIST response format</strong></p><div class="table-contents"><table summary="LIST response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>AVR8_RSP_LIST</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr><tr><td>Data</td><td>n bytes</td><td>Data returned</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s02s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s02s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s03.html
new file mode 100644
index 000000000..bac30cb2f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s03.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>PC - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s02.html" title="Responses" /><link rel="prev" href="ch06s02s02.html" title="LIST" /><link rel="next" href="ch06s02s04.html" title="DATA" /><meta content="PC" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s02s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s02s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12222" />PC</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Program counter value is returned</p><div class="table"><a id="N12227" /><p class="title"><strong>Table&nbsp;130.&nbsp;PC response format</strong></p><div class="table-contents"><table summary="PC response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>RSP_AVR8_PC</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr><tr><td>PC</td><td>4 bytes</td><td>Program Counter value</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s02s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s02s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s04.html
new file mode 100644
index 000000000..8ac473d49
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s04.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>DATA - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s02.html" title="Responses" /><link rel="prev" href="ch06s02s03.html" title="PC" /><link rel="next" href="ch06s02s05.html" title="FAILED" /><meta content="DATA" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s02s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s02s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12251" />DATA</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Data is returned</p><div class="table"><a id="N12256" /><p class="title"><strong>Table&nbsp;131.&nbsp;DATA response format version 0</strong></p><div class="table-contents"><table summary="DATA response format version 0" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>RSP_AVR8_DATA</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x01)</td><td>1 byte</td><td>Response version</td></tr><tr><td>Data</td><td>n bytes</td><td>Data returned</td></tr><tr><td>Status code</td><td>1 byte</td><td>Trailing status of the read operation indicating whether the data returned is in fact valid. 0x00 = OK.</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s02s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s02s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s05.html
new file mode 100644
index 000000000..0d39d303b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s02s05.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>FAILED - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s02.html" title="Responses" /><link rel="prev" href="ch06s02s04.html" title="DATA" /><link rel="next" href="ch06s03.html" title="Events" /><meta content="FAILED" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Responses</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s02s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s02.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12287" />FAILED</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The command failed to execute</p><div class="table"><a id="N1228C" /><p class="title"><strong>Table&nbsp;132.&nbsp;FAILED response format</strong></p><div class="table-contents"><table summary="FAILED response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>RSP_AVR8_FAILED</td><td>1 byte</td><td>Response ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Response version</td></tr><tr><td>Failure Code</td><td>1 byte</td><td>Instance code for failure; 0xFF = unknown</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s02s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s02.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03.html
new file mode 100644
index 000000000..1dd6d123a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Events - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avr8protocol.html" title="AVR8 generic protocol" /><link rel="prev" href="ch06s02s05.html" title="FAILED" /><link rel="next" href="ch06s03s01.html" title="Event: Break" /><meta content="Events" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR8 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s02s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avr8protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s03s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N122B6" />Events</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch06s03s01.html">Event: Break</a></span></dt><dt><span class="section"><a href="ch06s03s02.html">Event: IDR message</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s02s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avr8protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s03s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03s01.html
new file mode 100644
index 000000000..0381d127f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03s01.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Event: Break - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s03.html" title="Events" /><link rel="prev" href="ch06s03.html" title="Events" /><link rel="next" href="ch06s03s02.html" title="Event: IDR message" /><meta content="Event: Break" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Events</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s03s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N122B9" />Event: Break</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Indicates that the target has stopped</p><div class="table"><a id="N122BE" /><p class="title"><strong>Table&nbsp;133.&nbsp;Event: Break event format</strong></p><div class="table-contents"><table summary="Event: Break event format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>EVT_AVR8_BREAK</td><td>1 byte</td><td>Event ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Event version</td></tr><tr><td>PC</td><td>4 byte</td><td>Program Counter value (word address)</td></tr><tr><td>Break cause</td><td>1 byte</td><td><p>0x00 = unspecified</p>
+ <p>0x01 = program breakpoint</p>
+ </td></tr><tr><td>Extended info</td><td>2 bytes</td><td>N/A</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s03s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03s02.html
new file mode 100644
index 000000000..fbd7f8852
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s03s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Event: IDR message - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s03.html" title="Events" /><link rel="prev" href="ch06s03s01.html" title="Event: Break" /><link rel="next" href="section_avr8_memtypes.html" title="Memory Types" /><meta content="Event: IDR message" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Events</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s03s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="section_avr8_memtypes.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N122FD" />Event: IDR message</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Transports IDR messages from the target to the host. </p><div class="table"><a id="N12302" /><p class="title"><strong>Table&nbsp;134.&nbsp;Event: IDR message command format</strong></p><div class="table-contents"><table summary="Event: IDR message command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>EVT_AVR8_IDR</td><td>1 byte</td><td>Event ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Event version</td></tr><tr><td>Message</td><td>1 byte</td><td>Message from MCU</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s03s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="section_avr8_memtypes.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s01.html
new file mode 100644
index 000000000..6be4d4417
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s01.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>debugWIRE memtypes - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_avr8_memtypes.html" title="Memory Types" /><link rel="prev" href="section_avr8_memtypes.html" title="Memory Types" /><link rel="next" href="ch06s04s02.html" title="megaAVR (JTAG) OCD memtypes" /><meta content="debugWIRE memtypes" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Memory Types</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_avr8_memtypes.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_avr8_memtypes.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s04s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12330" />debugWIRE memtypes</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N12333" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;135.&nbsp;debugWIRE memtypes</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="debugWIRE memtypes" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>ID</th><th>Prog Access</th><th>Debug Access</th><th>Usage / Rules</th></tr></thead><tbody><tr><td>MEMTYPE_FLASH_PAGE</td><td>-</td><td>RW</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used for writing FLASH before a debug session, and reading FLASH during a debug session. </p></li><li class="listitem"><p>Only FULL PAGE access is allowed.</p></li><li class="listitem"><p>If the number of bytes requested does not match the flash page size, an error is returned (AVR8_FAILURE_INVALID_SIZE).</p></li><li class="listitem"><p>Software breakpoints are NOT filtered out.</p></li></ul></div>
+ </td></tr><tr><td>MEMTYPE_SIGNATURE</td><td>-</td><td>R</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read the device signature stored in the debugWIRE module itself. </p></li><li class="listitem"><p>This signature may differ from the signature stored in FLASH and accessed through SPI programming interface.</p></li><li class="listitem"><p>A read MUST be for exactly 3 bytes from address 0x00. </p></li><li class="listitem"><p>Violating this will results in an error (AVR8_FAILURE_INVALID_SIZE / AVR8_FAILURE_INVALID_ADDRESS).</p></li><li class="listitem"><p>Byte 2 will always read 0x1E.</p></li></ul></div></td></tr><tr><td>MEMTYPE_SRAM</td><td>-</td><td>RW</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Accesses SRAM and IO space during debugging.</p></li><li class="listitem"><p>If used in programming mode, an error is returned (AVR8_FAILURE_ILLEGAL_STATE)</p></li><li class="listitem"><p>If a read attempts to read an area containing the OCDR register, an error is returned (AVR8_FAILURE_INVALID_ADDRESS). </p></li><li class="listitem"><p>A masked read must be used in this case.</p></li><li class="listitem"><p>Any number of bytes (within payload restrictions) can be written or read in one operation.</p></li></ul></div></td></tr><tr><td>MEMTYPE_EEPROM</td><td>-</td><td>RW</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read and write EEPROM during a debug session. </p></li><li class="listitem"><p>Any number of bytes can be written or read in one operation.</p></li><li class="listitem"><p>Uses monitor code heavily - may take some time to complete, depending proportionally upon the number of bytes being accessed.</p></li></ul></div></td></tr><tr><td>MEMTYPE_SPM</td><td>-</td><td>R</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to access small amounts of FLASH during a debug session.</p></li><li class="listitem"><p>If an odd number of bytes is requested, an error is returned
+ <a href="#ftn.N123B1" class="footnote" id="N123B1"><sup class="footnote">[a]</sup></a>.</p></li><li class="listitem"><p>This memtype is efficient for reading full pages, or single words from FLASH. </p></li><li class="listitem"><p>Multiple word requests are inefficient and may take time to complete.</p></li><li class="listitem"><p>Software breakpoints are filtered out.</p></li></ul></div></td></tr></tbody><tbody class="footnotes"><tr><td colspan="4"><div id="ftn.N123B1" class="footnote"><p><a href="#N123B1" class="para"><sup class="para">[a] </sup></a>AVR8_FAILURE_ILLEGAL_MEMORY_RANGE</p></div></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_avr8_memtypes.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_avr8_memtypes.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s04s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s02.html
new file mode 100644
index 000000000..9437fc24a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s02.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>megaAVR (JTAG) OCD memtypes - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_avr8_memtypes.html" title="Memory Types" /><link rel="prev" href="ch06s04s01.html" title="debugWIRE memtypes" /><link rel="next" href="ch06s04s03.html" title="AVR XMEGA memtypes" /><meta content="megaAVR (JTAG) OCD memtypes" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Memory Types</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s04s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_avr8_memtypes.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s04s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N123BE" />megaAVR (JTAG) OCD memtypes</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N123C1" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;136.&nbsp;megaAVR (JTAG) OCD memtypes</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="megaAVR (JTAG) OCD memtypes" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>ID</th><th>Prog Access</th><th>Debug Access</th><th>Usage / Rules</th></tr></thead><tbody><tr><td>MEMTYPE_FLASH_PAGE</td><td>RW</td><td>-</td><td>
+ <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used for reading and writing FLASH pages in programming mode. </p></li><li class="listitem"><p>Writing it restricted to single full FLASH pages.</p></li><li class="listitem"><p>Reading is restricted to multiple full FLASH pages.</p></li><li class="listitem"><p>If access is attempted outside of programming mode, an error is returned.
+ <a href="#ftn.AVR8_FAILURE_ILLEGAL_STATE" class="footnote" id="AVR8_FAILURE_ILLEGAL_STATE"><sup class="footnote">[a]</sup></a></p></li></ul></div>
+ </td></tr><tr><td>MEMTYPE_EEPROM_PAGE</td><td>RW</td><td>-</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read and write EEPROM in programming mode.</p></li><li class="listitem"><p>Writing is restricted to single full pages.</p></li><li class="listitem"><p>Reading is restricted to multiple full pages.</p></li><li class="listitem"><p>If access is attempted outside of programming mode, an error is returned<a href="ch06s04s02.html#ftn.AVR8_FAILURE_ILLEGAL_STATE" class="footnoteref"><sup class="footnoteref">[a]</sup></a></p></li></ul></div></td></tr><tr><td>MEMTYPE_FUSES</td><td>RW</td><td>-</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read and write FUSES in programming mode.</p></li><li class="listitem"><p>Up to 3 fuses can be written/read in one operation. More than 3 results in an error
+ <a href="#ftn.AVR8_FAILURE_INVALID_SIZE" class="footnote" id="AVR8_FAILURE_INVALID_SIZE"><sup class="footnote">[b]</sup></a></p></li><li class="listitem"><p>Up to address 0x02 can be accessed. Outside of this range results in an error
+ <a href="#ftn.AVR8_FAILURE_INVALID_ADDRESS" class="footnote" id="AVR8_FAILURE_INVALID_ADDRESS"><sup class="footnote">[c]</sup></a></p></li><li class="listitem"><p>If access is attempted outside of programming mode, an error is returned<a href="ch06s04s02.html#ftn.AVR8_FAILURE_ILLEGAL_STATE" class="footnoteref"><sup class="footnoteref">[a]</sup></a></p></li></ul></div></td></tr><tr><td>MEMTYPE_LOCKBITS</td><td>RW</td><td>-</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read and write LOCKBITS in programming mode.</p></li><li class="listitem"><p>Only a single lockbit is available to read, at address 0.</p></li><li class="listitem"><p>Violating this results in an error
+ <a href="ch06s04s02.html#ftn.AVR8_FAILURE_INVALID_SIZE" class="footnoteref"><sup class="footnoteref">[b]</sup></a><a href="ch06s04s02.html#ftn.AVR8_FAILURE_INVALID_ADDRESS" class="footnoteref"><sup class="footnoteref">[c]</sup></a></p></li><li class="listitem"><p>If access is attempted outside of programming mode, an error is returned<a href="ch06s04s02.html#ftn.AVR8_FAILURE_ILLEGAL_STATE" class="footnoteref"><sup class="footnoteref">[a]</sup></a></p></li></ul></div></td></tr><tr><td>MEMTYPE_SIGNATURE</td><td>R</td><td>-</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read the device SIGNATURE in programming mode.</p></li><li class="listitem"><p>Up to 3 signature bytes can be read in one operation. More than 3 results in an error<a href="ch06s04s02.html#ftn.AVR8_FAILURE_INVALID_SIZE" class="footnoteref"><sup class="footnoteref">[b]</sup></a></p></li><li class="listitem"><p>Up to address 0x02 can be accessed. Outside of this range results in an error<a href="ch06s04s02.html#ftn.AVR8_FAILURE_INVALID_ADDRESS" class="footnoteref"><sup class="footnoteref">[c]</sup></a></p></li><li class="listitem"><p>If access is attempted outside of programming mode, an error is returned<a href="ch06s04s02.html#ftn.AVR8_FAILURE_ILLEGAL_STATE" class="footnoteref"><sup class="footnoteref">[a]</sup></a></p></li></ul></div></td></tr><tr><td>MEMTYPE_OSCCAL</td><td>R</td><td>-</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read the device OSCCAL VALUES in programming mode.</p></li><li class="listitem"><p>Up to 4 bytes can be read in one operation. More than 4 results in an error<a href="ch06s04s02.html#ftn.AVR8_FAILURE_INVALID_SIZE" class="footnoteref"><sup class="footnoteref">[b]</sup></a></p></li><li class="listitem"><p>Up to address 0x03 can be accessed. Outside of this range results in an error<a href="ch06s04s02.html#ftn.AVR8_FAILURE_INVALID_ADDRESS" class="footnoteref"><sup class="footnoteref">[c]</sup></a></p></li><li class="listitem"><p>If access is attempted outside of programming mode, an error is returned<a href="ch06s04s02.html#ftn.AVR8_FAILURE_ILLEGAL_STATE" class="footnoteref"><sup class="footnoteref">[a]</sup></a></p></li></ul></div></td></tr><tr><td>MEMTYPE_SRAM</td><td>-</td><td>RW</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Accesses SRAM and IO space during debugging.</p></li><li class="listitem"><p>If used in programming mode, an error is returned<a href="ch06s04s02.html#ftn.AVR8_FAILURE_ILLEGAL_STATE" class="footnoteref"><sup class="footnoteref">[a]</sup></a></p></li><li class="listitem"><p>If a read attempts to read an area containing the OCDR register, an error is returned<a href="ch06s04s02.html#ftn.AVR8_FAILURE_INVALID_ADDRESS" class="footnoteref"><sup class="footnoteref">[c]</sup></a>. </p></li><li class="listitem"><p>A masked read must be used in this case.</p></li><li class="listitem"><p>Any number of bytes (within payload restrictions) can be written or read in one operation.</p></li></ul></div></td></tr><tr><td>MEMTYPE_EEPROM</td><td>-</td><td>RW</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read and write EEPROM during a debug session. </p></li><li class="listitem"><p>Any number of bytes can be written or read in one operation.</p></li><li class="listitem"><p>Uses monitor code heavily - may take some time to complete, depending proportionally upon the number of bytes being accessed</p></li></ul></div></td></tr><tr><td>MEMTYPE_SPM</td><td>-</td><td>R</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read FLASH during a debug session.</p></li><li class="listitem"><p>If an odd number of bytes is requested, an error is returned
+ <a href="#ftn.AVR8_FAILURE_ILLEGAL_MEMORY_RANGE" class="footnote" id="AVR8_FAILURE_ILLEGAL_MEMORY_RANGE"><sup class="footnote">[d]</sup></a>.</p></li><li class="listitem"><p>If a mal-aligned address is requested, an error is returned
+ <a href="#ftn.AVR8_FAILURE_INVALID_ALIGNMENT" class="footnote" id="AVR8_FAILURE_INVALID_ALIGNMENT"><sup class="footnote">[e]</sup></a>.</p></li><li class="listitem"><p>Software breakpoints are filtered out.</p></li></ul></div></td></tr><tr><td>MEMTYPE_USER_SIGNATURE</td><td>RW</td><td>RW</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read/write the USER SIGNATURE in programming mode. NB: applies to ATmegaxxxRFR2 devices only!</p></li><li class="listitem"><p>Writing it restricted to single full FLASH pages.</p></li><li class="listitem"><p>Reading is restricted to multiple full FLASH pages.</p></li></ul></div></td></tr></tbody><tbody class="footnotes"><tr><td colspan="4"><div id="ftn.AVR8_FAILURE_ILLEGAL_STATE" class="footnote"><p><a href="#AVR8_FAILURE_ILLEGAL_STATE" class="para"><sup class="para">[a] </sup></a>AVR8_FAILURE_ILLEGAL_STATE</p></div><div id="ftn.AVR8_FAILURE_INVALID_SIZE" class="footnote"><p><a href="#AVR8_FAILURE_INVALID_SIZE" class="para"><sup class="para">[b] </sup></a>AVR8_FAILURE_INVALID_SIZE</p></div><div id="ftn.AVR8_FAILURE_INVALID_ADDRESS" class="footnote"><p><a href="#AVR8_FAILURE_INVALID_ADDRESS" class="para"><sup class="para">[c] </sup></a>AVR8_FAILURE_INVALID_ADDRESS</p></div><div id="ftn.AVR8_FAILURE_ILLEGAL_MEMORY_RANGE" class="footnote"><p><a href="#AVR8_FAILURE_ILLEGAL_MEMORY_RANGE" class="para"><sup class="para">[d] </sup></a>AVR8_FAILURE_ILLEGAL_MEMORY_RANGE</p></div><div id="ftn.AVR8_FAILURE_INVALID_ALIGNMENT" class="footnote"><p><a href="#AVR8_FAILURE_INVALID_ALIGNMENT" class="para"><sup class="para">[e] </sup></a>AVR8_FAILURE_INVALID_ALIGNMENT</p></div></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s04s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_avr8_memtypes.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s04s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s03.html
new file mode 100644
index 000000000..908842f76
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s04s03.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>AVR XMEGA memtypes - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="section_avr8_memtypes.html" title="Memory Types" /><link rel="prev" href="ch06s04s02.html" title="megaAVR (JTAG) OCD memtypes" /><link rel="next" href="ch06s05.html" title="Hints and tips:" /><meta content="AVR XMEGA memtypes" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Memory Types</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s04s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="section_avr8_memtypes.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N124DA" />AVR XMEGA memtypes</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N124DD" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;137.&nbsp;AVR XMEGA memtypes</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="AVR XMEGA memtypes" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>ID</th><th>Prog Access</th><th>Debug Access</th><th>Usage / Rules</th></tr></thead><tbody><tr><td>MEMTYPE_APPL_FLASH</td><td>RW</td><td>R</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read/write FLASH in the application section in programming or debugging mode</p></li><li class="listitem"><p>Address is from base 0x000000, provided that APPL_BASE_ADDR is configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Any number of bytes can be accessed.</p></li></ul></div></td></tr><tr><td>MEMTYPE_BOOT_FLASH</td><td>RW</td><td>R</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read/write FLASH in the boot section in programming or debugging mode</p></li><li class="listitem"><p>Address is from base 0x000000, provided that BOOT_BASE_ADDR is configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Any number of bytes can be accessed.</p></li></ul></div></td></tr><tr><td>MEMTYPE_APPL_FLASH_ATOMIC</td><td>W</td><td>-</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to write a full FLASH page in the application section in programming mode</p></li><li class="listitem"><p>The page is automatically erased before writing</p></li><li class="listitem"><p>Address is from base 0x000000, provided that APPL_BASE_ADDR is configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Writes are restricted to full pages only.</p></li></ul></div></td></tr><tr><td>MEMTYPE_BOOT_FLASH_ATOMIC</td><td>W</td><td>-</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to write a full FLASH page in the boot section in programming mode</p></li><li class="listitem"><p>The page is automatically erased before writing</p></li><li class="listitem"><p>Address is from base 0x000000, provided that BOOT_BASE_ADDR is configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Writes are restricted to full pages only.</p></li></ul></div></td></tr><tr><td>MEMTYPE_EEPROM_ATOMIC</td><td>W</td><td>W</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to write a full EEPROM page in programming or debugging mode</p></li><li class="listitem"><p>The page is automatically erased before writing</p></li><li class="listitem"><p>Address is from base 0x000000, provided that EEPROM_BASE_ADDR is configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Writes are restricted to full pages only.</p></li></ul></div></td></tr><tr><td>MEMTYPE_EEPROM</td><td>RW</td><td>RW</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read/write a EEPROM data in programming or debugging mode</p></li><li class="listitem"><p>Address is from base 0x000000, provided that EEPROM_BASE_ADDR is configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Any number of bytes can be accessed</p></li></ul></div></td></tr><tr><td>MEMTYPE_FUSES</td><td>RW</td><td>-</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read/write a FUSES in programming or debugging mode</p></li><li class="listitem"><p>Address is from base 0x000000, provided that FUSE_BASE_ADDR is configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Any number of bytes can be accessed</p></li></ul></div></td></tr><tr><td>MEMTYPE_LOCK_BITS</td><td>RW</td><td>R</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read/write a LOCKBITS in programming or debugging mode</p></li><li class="listitem"><p>Address is from base 0x000000, provided that LOCKBIT_BASE_ADDR is configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Any number of bytes can be accessed</p></li></ul></div></td></tr><tr><td>MEMTYPE_SIGNATURE</td><td>R</td><td>R</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read the device SIGNATURE in programming or debugging mode</p></li><li class="listitem"><p>Address is from base 0x000000, provided that NVM_BASE and SIGNATURE_OFFSET are configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Any number of bytes can be accessed</p></li></ul></div></td></tr><tr><td>MEMTYPE_USER_SIGNATURE</td><td>RW</td><td>RW</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read/write the USER SIGNATURE in programming or debugging mode</p></li><li class="listitem"><p>Address is from base 0x000000, provided that USER_SIGN_BASE_ADDR is configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Any number of bytes can be accessed</p></li></ul></div></td></tr><tr><td>MEMTYPE_CALIBRATION_SIGNATURE</td><td>R</td><td>R</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read/write the CALIBRATION SIGNATURE in programming or debugging mode</p></li><li class="listitem"><p>Address is from base 0x000000, provided that PROD_SIGN_BASE_ADDR is configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Any number of bytes can be accessed</p></li></ul></div></td></tr><tr><td>MEMTYPE_REGFILE</td><td>-</td><td>RW</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read/write the general purpose registers in debugging mode</p></li><li class="listitem"><p>Address is from base 0x00</p></li><li class="listitem"><p>Any number of bytes can be accessed</p></li></ul></div></td></tr><tr><td>MEMTYPE_SRAM</td><td>-</td><td>RW</td><td><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>Used to read/write the SRAM data space in debugging mode</p></li><li class="listitem"><p>Address is from base 0x000000, provided that DATA_BASE_ADDR is configured correctly (<a class="xref" href="section_avr8_setget_params.html#section_avr8_xmega_device_context" title="Device context: AVR XMEGA targets">the section called &ldquo;Device context: AVR XMEGA targets&rdquo;</a>).</p></li><li class="listitem"><p>Any number of bytes can be accessed</p></li></ul></div></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s04s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="section_avr8_memtypes.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05.html
new file mode 100644
index 000000000..698298a23
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Hints and tips: - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avr8protocol.html" title="AVR8 generic protocol" /><link rel="prev" href="ch06s04s03.html" title="AVR XMEGA memtypes" /><link rel="next" href="ch06s05s01.html" title="Configuration" /><meta content="Hints and tips:" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR8 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s04s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avr8protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s05s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N12617" />Hints and tips:</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch06s05s01.html">Configuration</a></span></dt><dt><span class="section"><a href="ch06s05s02.html">Activate and deactivate physical</a></span></dt><dt><span class="section"><a href="ch06s05s03.html">Programming session control</a></span></dt><dt><span class="section"><a href="ch06s05s04.html">Debug session control</a></span></dt><dt><span class="section"><a href="ch06s05s05.html">Flow control</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s04s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avr8protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s05s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s01.html
new file mode 100644
index 000000000..a44f60f4b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s01.html
@@ -0,0 +1,227 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Configuration - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s05.html" title="Hints and tips:" /><link rel="prev" href="ch06s05.html" title="Hints and tips:" /><link rel="next" href="ch06s05s02.html" title="Activate and deactivate physical" /><meta content="Configuration" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Hints and tips:</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s05s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1261A" />Configuration</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Configuration takes place before or during a session is active by using the
+ Query, Set and Get commands. The following configuration elements are
+ required:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>CONFIG / VARIANT: the host must specify which AVR8 target type is
+ being used. Note that the target type refers to the OCD type rather
+ than the marketing name. (Eg: mega48 has the tinyOCD module)</p></li><li class="listitem"><p>CONFIG / FUNCTION: the host must specify what the purpose of
+ the session is. Programming sessions do not require OCD access, and
+ typically release the target to run freely upon completion, whereas
+ debugging sessions may hold the target in reset when required in order
+ to prevent runaway code.</p></li><li class="listitem"><p>PHYSICAL: the physical context must be configured with the correct
+ physical interface as well as the necessary clock information.
+ Stored values may be read out, if required. Only the clocks for the
+ relevant interface need be set.</p></li><li class="listitem"><p>DEVICE: the device context provides the tool with an array of
+ device-specific data which will be needed during the session. It can be
+ typically read from XML files deployed with the front-end, and can be
+ changed on the fly in case the incorrect device is detected.</p></li><li class="listitem"><p>OPTIONS: any relevant options can be set in this context </p></li></ul></div><p>
+ </p><p>Note that before continuing with activation of physical the CMD_HOUSEKEEPING_START_SESSION must be called, see <a class="xref" href="section_housekeeping_start_session.html" title="Start session">the section called &ldquo;Start session&rdquo;</a>.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s05s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s02.html
new file mode 100644
index 000000000..f6077325d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s02.html
@@ -0,0 +1,231 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Activate and deactivate physical - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s05.html" title="Hints and tips:" /><link rel="prev" href="ch06s05s01.html" title="Configuration" /><link rel="next" href="ch06s05s03.html" title="Programming session control" /><meta content="Activate and deactivate physical" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Hints and tips:</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s05s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s05s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12638" />Activate and deactivate physical</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Once configuration is complete, the host requests that the tool makes
+ a connection to the target by calling the &ldquo;activate physical&rdquo; command. In many
+ interfaces, the physical can be disabled by default or overridden by user code,
+ which implies that the external reset must be applied in order to gain access. In
+ other cases, the external reset may not be used, for example when attaching to a
+ running process. The use of external reset must be specified in the command
+ parameter. </p><p>Activating the physical must be followed by device ID validation, to
+ ensure that the session is capable of starting with the device that is
+ expected. For this reason, the activation command returns a DATA packet
+ containing the device ID of the target, as read directly from the target. If
+ no valid device is detected, the command will return FAILED. Device ID
+ return format is given here: </p><p>
+ </p><div class="table"><a id="N12641" /><p class="title"><strong>Table&nbsp;138.&nbsp;ID formats</strong></p><div class="table-contents"><table summary="ID formats" border="1"><colgroup><col class="Interface" /><col class="Format" /><col class="Example" /></colgroup><thead><tr><th>Interface</th><th>Format</th><th>Example</th></tr></thead><tbody><tr><td>debugWire</td><td>00 1E xx yy</td><td>00 1E 94 05</td></tr><tr><td>JTAG</td><td>JTAG ID</td><td>09 74 C0 3F</td></tr><tr><td>PDI</td><td>JTAG ID equivalent</td><td>09 74 C0 3F</td></tr></tbody></table></div></div><p><br class="table-break" />
+ </p><p>The Get ID command can also be used to retrieve this value at any stage
+ during the session. It is read out on demand and not cached, so be aware
+ that the IR value will be altered during this process when using JTAG. </p><p>On completion of a session, the physical must be deactivated. The tool
+ disconnects from the target at this point. In order to re-connect, the
+ physical must be activated again. </p><p>Commands for leaving programming mode or detaching from a debug session
+ may implicitly require that the physical is deactivated. If this is the
+ case, the deactivation should be performed as usual. To start a new session,
+ the physical should be activated again. </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s05s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s05s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s03.html
new file mode 100644
index 000000000..3ac632e84
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s03.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Programming session control - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s05.html" title="Hints and tips:" /><link rel="prev" href="ch06s05s02.html" title="Activate and deactivate physical" /><link rel="next" href="ch06s05s04.html" title="Debug session control" /><meta content="Programming session control" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Hints and tips:</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s05s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s05s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12675" />Programming session control</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">To start a programming session, the &ldquo;enter programming mode&rdquo; command is
+ used. At this point, the target is held in reset and can be accessed for
+ programming purposes using read and write memory functions etc. Leaving
+ programming mode is used to restore the target into normal operating mode.
+ If the &ldquo;function&rdquo; is specified as &ldquo;programming&rdquo;, the target will be set into
+ run mode at this point, and the physical deactivated. If the &ldquo;function&rdquo; is
+ specified as &ldquo;debugging&rdquo; however, the target will be held in reset, if
+ possible, so that code does not execute. The physical is not deactivated in
+ this case.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s05s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s05s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s04.html
new file mode 100644
index 000000000..a68ec01e3
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s04.html
@@ -0,0 +1,220 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Debug session control - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s05.html" title="Hints and tips:" /><link rel="prev" href="ch06s05s03.html" title="Programming session control" /><link rel="next" href="ch06s05s05.html" title="Flow control" /><meta content="Debug session control" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Hints and tips:</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s05s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s05s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1267A" />Debug session control</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Starting a debug session is done using the &ldquo;attach&rdquo; function. This can
+ be done simply after configuration and activation of physical(in the case of attaching to a running process,
+ or when programming is not required), or it can follow after a &ldquo;leave programming
+ mode&rdquo; command. A parameter specifies whether the target should break immediately
+ (normal) or continue running, if possible. Attaching to a target will start a
+ polling process to monitor the state of the OCD module. </p><p>After completion of a session, a detach command should be executed. This
+ stops the polling process and puts the target into run mode. The &ldquo;deactivate physical&rdquo;
+ command should be executed afterwards. If reprogramming of the target is required
+ during or after (fuses) a debug session, the &ldquo;enter programming mode&rdquo; command can be
+ executed in place of a &ldquo;detach&rdquo; command. </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s05s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s05s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s05.html
new file mode 100644
index 000000000..cbbca98bd
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s05s05.html
@@ -0,0 +1,231 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Flow control - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s05.html" title="Hints and tips:" /><link rel="prev" href="ch06s05s04.html" title="Debug session control" /><link rel="next" href="ch06s06.html" title="AVR8GENERIC ID definitions" /><meta content="Flow control" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Hints and tips:</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s05s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s06.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12681" />Flow control</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The following flow control functions are supported:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>RESET: resets the target and stops it at the reset vector
+ address.</p></li><li class="listitem"><p>STOP: stops the target at the next instruction
+ (low-level stop).</p></li><li class="listitem"><p>RUN: puts the target into run mode unconditionally.</p></li><li class="listitem"><p>STEP: performs a single instruction step on the target.
+ Instruction-level stepping must be used repetitively to perform
+ statement-level stepping.</p></li><li class="listitem"><p>PC read/write: reads and adjusts the program counter</p></li><li class="listitem"><p>Erase: performs an erase on the target. To be used in
+ programming mode only.</p></li><li class="listitem"><p>CRC: performs a CRC calculation on the target (XMEGA
+ only).</p></li><li class="listitem"><p>Memory Read and Write: provides access to memory areas in
+ programming mode and when stopped in a debug session. Rules are
+ provided per memory-type in the communication protocol
+ specification.</p></li><li class="listitem"><p>Hardware breakpoint set / clear: Provides access to
+ add and remove hardware breakpoints. Resources are family / OCD
+ specific.</p></li><li class="listitem"><p>Software breakpoint set / clear: Inserts and removed software
+ breakpoints from a control table in the tool. On the next flow
+ control command executed, the flash memory on the target is
+ updated.</p></li><li class="listitem"><p>Software breakpoints clear all: Immediately restores all
+ software breakpoints to their original values.</p></li></ul></div><p>
+ </p><p>All flow control functions will return a success or failure based on the
+ ability to perform that command. The target state is
+ assumed to be running until a BREAK event is received, indicating the
+ transition to a stopped state.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s05s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s06.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s06.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s06.html
new file mode 100644
index 000000000..237404283
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch06s06.html
@@ -0,0 +1,423 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>AVR8GENERIC ID definitions - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avr8protocol.html" title="AVR8 generic protocol" /><link rel="prev" href="ch06s05s05.html" title="Flow control" /><link rel="next" href="protocoldocs.avrispprotocol.html" title="AVR ISP protocol" /><meta content="AVR8GENERIC ID definitions" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR8 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s05s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avr8protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="protocoldocs.avrispprotocol.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N126AD" />AVR8GENERIC ID definitions</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">
+ This section includes the header file defining the different command,
+ response and event IDs for the AVR8 protocol. It also defines the different possible failure codes.
+ </p><pre class="programlisting"><span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericCommands {
+ CMD_AVR8_QUERY = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Capability discovery </em>
+ CMD_AVR8_SET = <span class="hl-number">0x01</span>, <em class="hl-comment" style="color: #008000">//! Set parameters</em>
+ CMD_AVR8_GET = <span class="hl-number">0x02</span>, <em class="hl-comment" style="color: #008000">//! Get parameters</em>
+ CMD_AVR8_ACTIVATE_PHYSICAL = <span class="hl-number">0x10</span>, <em class="hl-comment" style="color: #008000">//! Connect physically</em>
+ CMD_AVR8_DEACTIVATE_PHYSICAL = <span class="hl-number">0x11</span>, <em class="hl-comment" style="color: #008000">//! Disconnect physically</em>
+ CMD_AVR8_GET_ID = <span class="hl-number">0x12</span>, <em class="hl-comment" style="color: #008000">//! Read the ID</em>
+ CMD_AVR8_ATTACH = <span class="hl-number">0x13</span>, <em class="hl-comment" style="color: #008000">//! Attach to OCD module</em>
+ CMD_AVR8_DETACH = <span class="hl-number">0x14</span>, <em class="hl-comment" style="color: #008000">//! Detach from OCD module</em>
+ CMD_AVR8_PROG_MODE_ENTER = <span class="hl-number">0x15</span>, <em class="hl-comment" style="color: #008000">//! Enter programming mode</em>
+ CMD_AVR8_PROG_MODE_LEAVE = <span class="hl-number">0x16</span>, <em class="hl-comment" style="color: #008000">//! Leave programming mode</em>
+ CMD_AVR8_DISABLE_DEBUGWIRE = <span class="hl-number">0x17</span>, <em class="hl-comment" style="color: #008000">//! Disable debugWIRE interface</em>
+ CMD_AVR8_ERASE = <span class="hl-number">0x20</span>, <em class="hl-comment" style="color: #008000">//! Erase the chip</em>
+ CMD_AVR8_MEMORY_READ = <span class="hl-number">0x21</span>, <em class="hl-comment" style="color: #008000">//! Read memory</em>
+ CMD_AVR8_MEMORY_READ_MASKED = <span class="hl-number">0x22</span>, <em class="hl-comment" style="color: #008000">//! Read memory while via a mask</em>
+ CMD_AVR8_MEMORY_WRITE = <span class="hl-number">0x23</span>, <em class="hl-comment" style="color: #008000">//! Write memory</em>
+ CMD_AVR8_CRC = <span class="hl-number">0x24</span>, <em class="hl-comment" style="color: #008000">//! Calculate CRC</em>
+ CMD_AVR8_RESET = <span class="hl-number">0x30</span>, <em class="hl-comment" style="color: #008000">//! Reset the MCU</em>
+ CMD_AVR8_STOP = <span class="hl-number">0x31</span>, <em class="hl-comment" style="color: #008000">//! Stop the MCU</em>
+ CMD_AVR8_RUN = <span class="hl-number">0x32</span>, <em class="hl-comment" style="color: #008000">//! Resume execution</em>
+ CMD_AVR8_RUN_TO_ADDRESS = <span class="hl-number">0x33</span>, <em class="hl-comment" style="color: #008000">//! Resume with breakpoint </em>
+ CMD_AVR8_STEP = <span class="hl-number">0x34</span>, <em class="hl-comment" style="color: #008000">//! Single step</em>
+ CMD_AVR8_PC_READ = <span class="hl-number">0x35</span>, <em class="hl-comment" style="color: #008000">//! Read PC</em>
+ CMD_AVR8_PC_WRITE = <span class="hl-number">0x36</span>, <em class="hl-comment" style="color: #008000">//! Write PC</em>
+ CMD_AVR8_HW_BREAK_SET = <span class="hl-number">0x40</span>, <em class="hl-comment" style="color: #008000">//! Set breakpoints</em>
+ CMD_AVR8_HW_BREAK_CLEAR = <span class="hl-number">0x41</span>, <em class="hl-comment" style="color: #008000">//! Clear breakpoints</em>
+ CMD_AVR8_SW_BREAK_SET = <span class="hl-number">0x43</span>, <em class="hl-comment" style="color: #008000">//! Set software breakpoints</em>
+ CMD_AVR8_SW_BREAK_CLEAR = <span class="hl-number">0x44</span>, <em class="hl-comment" style="color: #008000">//! Clear software breakpoints</em>
+ CMD_AVR8_SW_BREAK_CLEAR_ALL = <span class="hl-number">0x45</span>, <em class="hl-comment" style="color: #008000">//! Clear all software breakpoints</em>
+ CMD_AVR8_PAGE_ERASE = <span class="hl-number">0x50</span> <em class="hl-comment" style="color: #008000">//! Erase page</em>
+};
+
+<em class="hl-comment" style="color: #008000">// Protocol responses</em>
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericResponses {
+ RSP_AVR8_OK = <span class="hl-number">0x80</span>, <em class="hl-comment" style="color: #008000">//! All OK</em>
+ RSP_AVR8_LIST = <span class="hl-number">0x81</span>, <em class="hl-comment" style="color: #008000">//! List of items returned</em>
+ RSP_AVR8_DATA = <span class="hl-number">0x84</span>, <em class="hl-comment" style="color: #008000">//! Data returned</em>
+ RSP_AVR8_PC = <span class="hl-number">0x83</span>, <em class="hl-comment" style="color: #008000">//! PC value returned</em>
+ RSP_AVR8_FAILED = <span class="hl-number">0xA0</span> <em class="hl-comment" style="color: #008000">//! Command failed to execute</em>
+};
+
+<em class="hl-comment" style="color: #008000">// Protocol events</em>
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericEvents {
+ EVT_AVR8_BREAK = <span class="hl-number">0x40</span>, <em class="hl-comment" style="color: #008000">//! Break message</em>
+ EVT_AVR8_IDR = <span class="hl-number">0x41</span> <em class="hl-comment" style="color: #008000">//! IO Data Register message</em>
+};
+
+<em class="hl-comment" style="color: #008000">// Failure response codes (RSP_FAILED)</em>
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericFailureCodes {
+ AVR8_FAILURE_OK = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! All OK</em>
+ AVR8_FAILURE_DW_PHY_ERROR = <span class="hl-number">0x10</span>, <em class="hl-comment" style="color: #008000">//! debugWIRE physical error</em>
+ AVR8_FAILURE_JTAGM_INIT_ERROR = <span class="hl-number">0x11</span>, <em class="hl-comment" style="color: #008000">//! JTAGM failed to initialise</em>
+ AVR8_FAILURE_JTAGM_ERROR = <span class="hl-number">0x12</span>, <em class="hl-comment" style="color: #008000">//! JTAGM did something strange</em>
+ AVR8_FAILURE_JTAG_ERROR = <span class="hl-number">0x13</span>, <em class="hl-comment" style="color: #008000">//! JTAG low level error</em>
+ AVR8_FAILURE_JTAGM_VERSION = <span class="hl-number">0x14</span>, <em class="hl-comment" style="color: #008000">//! Unsupported version of JTAGM</em>
+ AVR8_FAILURE_JTAGM_TIMEOUT = <span class="hl-number">0x15</span>, <em class="hl-comment" style="color: #008000">//! JTAG master timed out</em>
+ AVR8_FAILURE_JTAG_BIT_BANGER_TIMEOUT = <span class="hl-number">0x16</span>, <em class="hl-comment" style="color: #008000">//! JTAG bit banger timed out</em>
+ AVR8_FAILURE_PARITY_ERROR = <span class="hl-number">0x17</span>, <em class="hl-comment" style="color: #008000">//! Parity error in received data</em>
+ AVR8_FAILURE_EB_ERROR = <span class="hl-number">0x18</span>, <em class="hl-comment" style="color: #008000">//! Did not receive EMPTY byte</em>
+ AVR8_FAILURE_PDI_TIMEOUT = <span class="hl-number">0x19</span>, <em class="hl-comment" style="color: #008000">//! PDI physical timed out</em>
+ AVR8_FAILURE_COLLISION = <span class="hl-number">0x1A</span>, <em class="hl-comment" style="color: #008000">//! Collision on physical level</em>
+ AVR8_FAILURE_PDI_ENABLE = <span class="hl-number">0x1B</span>, <em class="hl-comment" style="color: #008000">//! PDI enable failed</em>
+ AVR8_FAILURE_NO_DEVICE_FOUND = <span class="hl-number">0x20</span>, <em class="hl-comment" style="color: #008000">//! devices == 0!</em>
+ AVR8_FAILURE_CLOCK_ERROR = <span class="hl-number">0x21</span>, <em class="hl-comment" style="color: #008000">//! Failure when increasing baud</em>
+ AVR8_FAILURE_NO_TARGET_POWER = <span class="hl-number">0x22</span>, <em class="hl-comment" style="color: #008000">//! Target power not detected</em>
+ AVR8_FAILURE_NOT_ATTACHED = <span class="hl-number">0x23</span>, <em class="hl-comment" style="color: #008000">//! Must run attach command first</em>
+ AVR8_FAILURE_INVALID_PHYSICAL_STATE = <span class="hl-number">0x31</span>, <em class="hl-comment" style="color: #008000">//! Physical not activated</em>
+ AVR8_FAILURE_ILLEGAL_STATE = <span class="hl-number">0x32</span>, <em class="hl-comment" style="color: #008000">//! Illegal run / stopped state</em>
+ AVR8_FAILURE_INVALID_CONFIG = <span class="hl-number">0x33</span>, <em class="hl-comment" style="color: #008000">//! Invalid config for activate phy</em>
+ AVR8_FAILURE_INVALID_MEMTYPE = <span class="hl-number">0x34</span>, <em class="hl-comment" style="color: #008000">//! Not a valid memtype</em>
+ AVR8_FAILURE_INVALID_SIZE = <span class="hl-number">0x35</span>, <em class="hl-comment" style="color: #008000">//! Too many or too few bytes</em>
+ AVR8_FAILURE_INVALID_ADDRESS = <span class="hl-number">0x36</span>, <em class="hl-comment" style="color: #008000">//! Asked for a bad address</em>
+ AVR8_FAILURE_INVALID_ALIGNMENT = <span class="hl-number">0x37</span>, <em class="hl-comment" style="color: #008000">//! Asked for badly aligned data</em>
+ AVR8_FAILURE_ILLEGAL_MEMORY_RANGE = <span class="hl-number">0x38</span>, <em class="hl-comment" style="color: #008000">//! Address not within legal range</em>
+ AVR8_FAILURE_ILLEGAL_VALUE = <span class="hl-number">0x39</span>, <em class="hl-comment" style="color: #008000">//! Illegal value given</em>
+ AVR8_FAILURE_ILLEGAL_ID = <span class="hl-number">0x3A</span>, <em class="hl-comment" style="color: #008000">//! Illegal target ID</em>
+ AVR8_FAILURE_INVALID_CLOCK_SPEED = <span class="hl-number">0x3B</span>, <em class="hl-comment" style="color: #008000">//! Clock value out of range</em>
+ AVR8_FAILURE_TIMEOUT = <span class="hl-number">0x3C</span>, <em class="hl-comment" style="color: #008000">//! A timeout occurred</em>
+ AVR8_FAILURE_ILLEGAL_OCD_STATUS = <span class="hl-number">0x3D</span>, <em class="hl-comment" style="color: #008000">//! Read an illegal OCD status </em>
+ AVR8_FAILURE_NVM_ENABLE = <span class="hl-number">0x40</span>, <em class="hl-comment" style="color: #008000">//! NVM failed to be enabled</em>
+ AVR8_FAILURE_NVM_DISABLE = <span class="hl-number">0x41</span>, <em class="hl-comment" style="color: #008000">//! NVM failed to be disabled</em>
+ AVR8_FAILURE_CS_ERROR = <span class="hl-number">0x42</span>, <em class="hl-comment" style="color: #008000">//! Illegal control/status bits </em>
+ AVR8_FAILURE_CRC_FAILURE = <span class="hl-number">0x43</span>, <em class="hl-comment" style="color: #008000">//! CRC mismatch</em>
+ AVR8_FAILURE_OCD_LOCKED = <span class="hl-number">0x44</span>, <em class="hl-comment" style="color: #008000">//! Failed to enable OCD</em>
+ AVR8_FAILURE_NO_OCD_CONTROL = <span class="hl-number">0x50</span>, <em class="hl-comment" style="color: #008000">//! Device is not under control</em>
+ AVR8_FAILURE_PC_READ_FAILED = <span class="hl-number">0x60</span>, <em class="hl-comment" style="color: #008000">//! Error when reading PC</em>
+ AVR8_FAILURE_REGISTER_READ_FAILED = <span class="hl-number">0x61</span>, <em class="hl-comment" style="color: #008000">//! Error when reading register</em>
+ AVR8_FAILURE_READ_ERROR = <span class="hl-number">0x70</span>, <em class="hl-comment" style="color: #008000">//! Error while reading</em>
+ AVR8_FAILURE_WRITE_ERROR = <span class="hl-number">0x71</span>, <em class="hl-comment" style="color: #008000">//! Error while writing</em>
+ AVR8_FAILURE_WRITE_TIMEOUT = <span class="hl-number">0x72</span>, <em class="hl-comment" style="color: #008000">//! Timeout while reading</em>
+ AVR8_FAILURE_ILLEGAL_BREAKPOINT = <span class="hl-number">0x80</span>, <em class="hl-comment" style="color: #008000">//! Invalid breakpoint configuration</em>
+ AVR8_FAILURE_TOO_MANY_BREAKPOINTS = <span class="hl-number">0x81</span>, <em class="hl-comment" style="color: #008000">//! Not enough available resources</em>
+ AVR8_FAILURE_NOT_SUPPORTED = <span class="hl-number">0x90</span>, <em class="hl-comment" style="color: #008000">//! This feature is not available</em>
+ AVR8_FAILURE_NOT_IMPLEMENTED = <span class="hl-number">0x91</span>, <em class="hl-comment" style="color: #008000">//! Command has not been implemented</em>
+ AVR8_FAILURE_UNKNOWN = <span class="hl-number">0xFF</span> <em class="hl-comment" style="color: #008000">//! Disaster.</em>
+};
+
+<em class="hl-comment" style="color: #008000">// QUERY types on this protocol</em>
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericQueryContexts {
+ AVR8_QUERY_COMMANDS = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Supported command list</em>
+ AVR8_QUERY_CONFIGURATION = <span class="hl-number">0x05</span>, <em class="hl-comment" style="color: #008000">//! Supported configuration list</em>
+ AVR8_QUERY_READ_MEMTYPES = <span class="hl-number">0x07</span>, <em class="hl-comment" style="color: #008000">//! Supported read memtypes list</em>
+ AVR8_QUERY_WRITE_MEMTYPES = <span class="hl-number">0x08</span> <em class="hl-comment" style="color: #008000">//! Supported write memtypes list</em>
+};
+
+<em class="hl-comment" style="color: #008000">// Context definitions </em>
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericSetGetContexts {
+ AVR8_CTXT_CONFIG = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Configuration</em>
+ AVR8_CTXT_PHYSICAL = <span class="hl-number">0x01</span>, <em class="hl-comment" style="color: #008000">//! Physical interface related</em>
+ AVR8_CTXT_DEVICE = <span class="hl-number">0x02</span>, <em class="hl-comment" style="color: #008000">//! Device specific settings</em>
+ AVR8_CTXT_OPTIONS = <span class="hl-number">0x03</span>, <em class="hl-comment" style="color: #008000">//! Option-related settings</em>
+ AVR8_CTXT_SESSION = <span class="hl-number">0x04</span>, <em class="hl-comment" style="color: #008000">//! Session-related settings</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericConfigContextParameters {
+ AVR8_CONFIG_VARIANT = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Device family/variant</em>
+ AVR8_CONFIG_FUNCTION = <span class="hl-number">0x01</span> <em class="hl-comment" style="color: #008000">//! Functional intent</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericPhysicalContextParameters {
+ AVR8_PHY_INTERFACE = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Physical interface selector</em>
+ AVR8_PHY_JTAG_DAISY = <span class="hl-number">0x01</span>, <em class="hl-comment" style="color: #008000">//! JTAG daisy chain settings</em>
+ AVR8_PHY_DW_CLK_DIV = <span class="hl-number">0x10</span>, <em class="hl-comment" style="color: #008000">//! debugWIRE clock divide ratio</em>
+ AVR8_PHY_MEGA_PRG_CLK = <span class="hl-number">0x20</span>, <em class="hl-comment" style="color: #008000">//! Clock for programming megaAVR</em>
+ AVR8_PHY_MEGA_DBG_CLK = <span class="hl-number">0x21</span>, <em class="hl-comment" style="color: #008000">//! Clock for debugging megaAVR</em>
+ AVR8_PHY_XM_JTAG_CLK = <span class="hl-number">0x30</span>, <em class="hl-comment" style="color: #008000">//! JTAG clock for AVR XMEGA</em>
+ AVR8_PHY_XM_PDI_CLK = <span class="hl-number">0x31</span> <em class="hl-comment" style="color: #008000">//! PDI clock for AVR XMEGA</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericOptionsContextParameters {
+ AVR8_OPT_RUN_TIMERS = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Keep timers running when stopped</em>
+ AVR8_OPT_DISABLE_DBP = <span class="hl-number">0x01</span>, <em class="hl-comment" style="color: #008000">//! No data breaks during reset</em>
+ AVR8_OPT_ENABLE_IDR = <span class="hl-number">0x03</span>, <em class="hl-comment" style="color: #008000">//! Relay IDR messages</em>
+ AVR8_OPT_POLL_INT = <span class="hl-number">0x04</span> <em class="hl-comment" style="color: #008000">//! Configure polling speed</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericSessionContextParameters {
+ AVR8_SESS_MAIN_PC = <span class="hl-number">0x00</span> <em class="hl-comment" style="color: #008000">//! Address of main() function</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericConfigTestParameters {
+ AVR8_TEST_TGT_RUNNING = <span class="hl-number">0x00</span> <em class="hl-comment" style="color: #008000">//! Is target running?</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericVariantValues {
+ AVR8_VARIANT_LOOPBACK = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Dummy device</em>
+ AVR8_VARIANT_TINYOCD = <span class="hl-number">0x01</span>, <em class="hl-comment" style="color: #008000">//! tinyAVR or megaAVR with debugWIRE</em>
+ AVR8_VARIANT_MEGAOCD = <span class="hl-number">0x02</span>, <em class="hl-comment" style="color: #008000">//! megaAVR with JTAG</em>
+ AVR8_VARIANT_XMEGA = <span class="hl-number">0x03</span>, <em class="hl-comment" style="color: #008000">//! AVR XMEGA</em>
+ AVR8_VARIANT_NONE = <span class="hl-number">0xFF</span> <em class="hl-comment" style="color: #008000">//! No device</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericFunctionValues {
+ AVR8_FUNC_NONE = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Not configured</em>
+ AVR8_FUNC_PROGRAMMING = <span class="hl-number">0x01</span>, <em class="hl-comment" style="color: #008000">//! I want to program only</em>
+ AVR8_FUNC_DEBUGGING = <span class="hl-number">0x02</span> <em class="hl-comment" style="color: #008000">//! I want a debug session</em>
+};
+
+<em class="hl-comment" style="color: #008000">// Physical modes</em>
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericPhysicalInterfaces {
+ AVR8_PHY_INTF_NONE = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Not configured</em>
+ AVR8_PHY_INTF_JTAG = <span class="hl-number">0x04</span>, <em class="hl-comment" style="color: #008000">//! JTAG</em>
+ AVR8_PHY_INTF_DW = <span class="hl-number">0x05</span>, <em class="hl-comment" style="color: #008000">//! debugWIRE</em>
+ AVR8_PHY_INTF_PDI = <span class="hl-number">0x06</span> <em class="hl-comment" style="color: #008000">//! PDI</em>
+};
+
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericMegaBreakpointTypes {
+ AVR8_HWBP_PROG_BP = <span class="hl-number">0x01</span> <em class="hl-comment" style="color: #008000">//! Program breaks</em>
+
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericMegaBreakCauses {
+ AVR8_BREAK_CAUSE_UNKNOWN = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Unspecified</em>
+ AVR8_BREAK_CAUSE_PROGRAM = <span class="hl-number">0x01</span> <em class="hl-comment" style="color: #008000">//! Program break</em>
+
+};
+
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericXmegaEraseModes {
+ XMEGA_ERASE_CHIP = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! Erase entire chip </em>
+ XMEGA_ERASE_APP = <span class="hl-number">0x01</span>, <em class="hl-comment" style="color: #008000">//! Erase application section only</em>
+ XMEGA_ERASE_BOOT = <span class="hl-number">0x02</span>, <em class="hl-comment" style="color: #008000">//! Erase boot section only</em>
+ XMEGA_ERASE_EEPROM = <span class="hl-number">0x03</span>, <em class="hl-comment" style="color: #008000">//! Erase EEPROM section only</em>
+ XMEGA_ERASE_APP_PAGE = <span class="hl-number">0x04</span>, <em class="hl-comment" style="color: #008000">//! Erase a single app section page</em>
+ XMEGA_ERASE_BOOT_PAGE = <span class="hl-number">0x05</span>, <em class="hl-comment" style="color: #008000">//! Erase a single boot section page</em>
+ XMEGA_ERASE_EEPROM_PAGE = <span class="hl-number">0x06</span>, <em class="hl-comment" style="color: #008000">//! Erase a single EEPROM page</em>
+ XMEGA_ERASE_USERSIG = <span class="hl-number">0x07</span> <em class="hl-comment" style="color: #008000">//! Erase the user signature section</em>
+};
+
+<em class="hl-comment" style="color: #008000">// Memory types</em>
+<span class="hl-keyword" style="color: #0000FF">enum</span> Avr8GenericMemtypes {
+ MEMTYPE_SRAM = <span class="hl-number">0x20</span>, <em class="hl-comment" style="color: #008000">//! SRAM</em>
+ MEMTYPE_EEPROM = <span class="hl-number">0x22</span>, <em class="hl-comment" style="color: #008000">//! EEPROM memory</em>
+ MEMTYPE_SPM = <span class="hl-number">0xA0</span>, <em class="hl-comment" style="color: #008000">//! Flash memory in a debug session</em>
+ MEMTYPE_FLASH_PAGE = <span class="hl-number">0xB0</span>, <em class="hl-comment" style="color: #008000">//! Flash memory programming</em>
+ MEMTYPE_EEPROM_PAGE = <span class="hl-number">0xB1</span>, <em class="hl-comment" style="color: #008000">//! EEPROM memory pages</em>
+ MEMTYPE_FUSES = <span class="hl-number">0xB2</span>, <em class="hl-comment" style="color: #008000">//! Fuse memory</em>
+ MEMTYPE_LOCKBITS = <span class="hl-number">0xB3</span>, <em class="hl-comment" style="color: #008000">//! Lock bits</em>
+ MEMTYPE_SIGNATURE = <span class="hl-number">0xB4</span>, <em class="hl-comment" style="color: #008000">//! Device signature</em>
+ MEMTYPE_OSCCAL = <span class="hl-number">0xB5</span>, <em class="hl-comment" style="color: #008000">//! Oscillator calibration values</em>
+ MEMTYPE_REGFILE = <span class="hl-number">0xB8</span>, <em class="hl-comment" style="color: #008000">//! Register file</em>
+ MEMTYPE_APPL_FLASH = <span class="hl-number">0xC0</span>, <em class="hl-comment" style="color: #008000">//! Application section flash</em>
+ MEMTYPE_BOOT_FLASH = <span class="hl-number">0xC1</span>, <em class="hl-comment" style="color: #008000">//! Boot section flash</em>
+ MEMTYPE_APPL_FLASH_ATOMIC = <span class="hl-number">0xC2</span>, <em class="hl-comment" style="color: #008000">//! Application page with auto-erase</em>
+ MEMTYPE_BOOT_FLASH_ATOMIC = <span class="hl-number">0xC3</span>, <em class="hl-comment" style="color: #008000">//! Boot page with auto-erase</em>
+ MEMTYPE_EEPROM_ATOMIC = <span class="hl-number">0xC4</span>, <em class="hl-comment" style="color: #008000">//! EEPROM page with auto-erase</em>
+ MEMTYPE_USER_SIGNATURE = <span class="hl-number">0xC5</span>, <em class="hl-comment" style="color: #008000">//! User signature secion</em>
+ MEMTYPE_CALIBRATION_SIGNATURE = <span class="hl-number">0xC6</span> <em class="hl-comment" style="color: #008000">//! Calibration section</em>
+ };</pre></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s05s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avr8protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="protocoldocs.avrispprotocol.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01.html
new file mode 100644
index 000000000..979b8fb37
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI programming protocol commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avrispprotocol.html" title="AVR ISP protocol" /><link rel="prev" href="protocoldocs.avrispprotocol.html" title="AVR ISP protocol" /><link rel="next" href="ch07s01s01.html" title="SPI Load Address" /><meta content="SPI programming protocol commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR ISP protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="protocoldocs.avrispprotocol.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avrispprotocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N126D0" />SPI programming protocol commands</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch07s01s01.html">SPI Load Address</a></span></dt><dt><span class="section"><a href="ch07s01s02.html">SPI Set Baud</a></span></dt><dt><span class="section"><a href="ch07s01s03.html">SPI Get Baud</a></span></dt><dt><span class="section"><a href="ch07s01s04.html">SPI Enter Programming Mode</a></span></dt><dt><span class="section"><a href="ch07s01s05.html">SPI Leave Programming Mode</a></span></dt><dt><span class="section"><a href="ch07s01s06.html">SPI Chip Erase</a></span></dt><dt><span class="section"><a href="ch07s01s07.html">SPI Program Flash</a></span></dt><dt><span class="section"><a href="ch07s01s08.html">SPI Read Flash</a></span></dt><dt><span class="section"><a href="ch07s01s09.html">SPI Program EEPROM</a></span></dt><dt><span class="section"><a href="ch07s01s10.html">SPI Read EEPROM</a></span></dt><dt><span class="section"><a href="ch07s01s11.html">SPI Program Fuse</a></span></dt><dt><span class="section"><a href="ch07s01s12.html">SPI Read Fuse</a></span></dt><dt><span class="section"><a href="ch07s01s13.html">SPI Program Lock</a></span></dt><dt><span class="section"><a href="ch07s01s14.html">SPI Read Lock</a></span></dt><dt><span class="section"><a href="ch07s01s15.html">SPI Read Signature</a></span></dt><dt><span class="section"><a href="ch07s01s16.html">SPI Read OSCCAL</a></span></dt><dt><span class="section"><a href="ch07s01s17.html">SPI Multi</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="protocoldocs.avrispprotocol.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avrispprotocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s01.html
new file mode 100644
index 000000000..70756cf66
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Load Address - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="next" href="ch07s01s02.html" title="SPI Set Baud" /><meta content="SPI Load Address" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N126D3" />SPI Load Address</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Loads address to be used for SPI programming</p><div class="table"><a id="N126D8" /><p class="title"><strong>Table&nbsp;139.&nbsp;SPI Load Address command format</strong></p><div class="table-contents"><table summary="SPI Load Address command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_LOAD_ADDRESS</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Address</td><td>4 bytes</td><td>Start address of next command. MSB first</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N126FD" /><p class="title"><strong>Table&nbsp;140.&nbsp;SPI Load Address response format</strong></p><div class="table-contents"><table summary="SPI Load Address response format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_LOAD_ADDRESS</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td>SPI_STATUS_CMD_OK</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s02.html
new file mode 100644
index 000000000..3f9e3a398
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Set Baud - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s01.html" title="SPI Load Address" /><link rel="next" href="ch07s01s03.html" title="SPI Get Baud" /><meta content="SPI Set Baud" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12720" />SPI Set Baud</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Sets the clock frequency to be used for SPI programming</p><div class="table"><a id="N12725" /><p class="title"><strong>Table&nbsp;141.&nbsp;SPI Set Baud command format</strong></p><div class="table-contents"><table summary="SPI Set Baud command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_SET_BAUD</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Baud</td><td>2 bytes</td><td>Baud rate to use (kbit/s)</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N1274A" /><p class="title"><strong>Table&nbsp;142.&nbsp;SPI Set Baud response</strong></p><div class="table-contents"><table summary="SPI Set Baud response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_SET_BAUD</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td><p>SPI_STATUS_CMD_OK or</p><p>SPI_STATUS_BAUD_INVALID</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s03.html
new file mode 100644
index 000000000..64b8e2452
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s03.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Get Baud - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s02.html" title="SPI Set Baud" /><link rel="next" href="ch07s01s04.html" title="SPI Enter Programming Mode" /><meta content="SPI Get Baud" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12770" />SPI Get Baud</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads the clock frequency used for SPI programming</p><div class="table"><a id="N12775" /><p class="title"><strong>Table&nbsp;143.&nbsp;SPI Get Baud command format</strong></p><div class="table-contents"><table summary="SPI Get Baud command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_GET_BAUD</td><td>1 byte</td><td>Command ID</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N12793" /><p class="title"><strong>Table&nbsp;144.&nbsp;SPI Get Baud response</strong></p><div class="table-contents"><table summary="SPI Get Baud response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_GET_BAUD</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Baud</td><td>2 bytes</td><td>Current baud (kbit/s)</td></tr><tr><td>Status</td><td>1 byte</td><td>SPI_STATUS_CMD_OK</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s04.html
new file mode 100644
index 000000000..be105b8c2
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s04.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Enter Programming Mode - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s03.html" title="SPI Get Baud" /><link rel="next" href="ch07s01s05.html" title="SPI Leave Programming Mode" /><meta content="SPI Enter Programming Mode" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N127BD" />SPI Enter Programming Mode</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Enters programming mode to start SPI programming</p><div class="table"><a id="N127C2" /><p class="title"><strong>Table&nbsp;145.&nbsp;SPI Enter Programming mode command format</strong></p><div class="table-contents"><table summary="SPI Enter Programming mode command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_ENTER_PROGMODE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>timeout</td><td>1 byte</td><td>XML: timeout. Command time-out (in ms)</td></tr><tr><td>stabDelay</td><td>1 byte</td><td>XML: stabDelay. Delay (in ms) used for pin stabilization</td></tr><tr><td>cmdexeDelay</td><td>1 byte</td><td>XML: cmdexeDelay. Delay (in ms) in connection with the EnterProgMode command execution</td></tr><tr><td>synchLoops</td><td>1 byte</td><td>XML: synchLoops. Number of synchronization loops</td></tr><tr><td>byteDelay</td><td>1 byte</td><td>XML: byteDelay. Delay (in ms) between each byte in the EnterProgMode command. </td></tr><tr><td>pollValue</td><td>1 byte</td><td>XML: pollValue. 0x53</td></tr><tr><td>pollIndex</td><td>1 byte</td><td>XML: pollIndex. Start address, received byte: 0 = no polling, 3 = AVR</td></tr><tr><td>cmd1</td><td>1 byte</td><td>Command Byte # 1 to be transmitted</td></tr><tr><td>cmd2</td><td>1 byte</td><td>Command Byte # 2 to be transmitted</td></tr><tr><td>cmd3</td><td>1 byte</td><td>Command Byte # 3 to be transmitted</td></tr><tr><td>cmd4</td><td>1 byte</td><td>Command Byte # 4 to be transmitted</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N1282D" /><p class="title"><strong>Table&nbsp;146.&nbsp;SPI Enter Programming Mode response</strong></p><div class="table-contents"><table summary="SPI Enter Programming Mode response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_ENTER_PROGMODE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td><p>SPI_STATUS_CMD_OK or</p><p>SPI_STATUS_CMD_TOUT or</p><p>SPI_STATUS_FAILED</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s05.html
new file mode 100644
index 000000000..5355bee9f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s05.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Leave Programming Mode - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s04.html" title="SPI Enter Programming Mode" /><link rel="next" href="ch07s01s06.html" title="SPI Chip Erase" /><meta content="SPI Leave Programming Mode" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s06.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12855" />SPI Leave Programming Mode</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Leaves programming mode to complete SPI programming</p><div class="table"><a id="N1285A" /><p class="title"><strong>Table&nbsp;147.&nbsp;SPI Leave Programming mode command format</strong></p><div class="table-contents"><table summary="SPI Leave Programming mode command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_LEAVE_PROGMODE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>preDelay</td><td>1 byte</td><td>XML: preDelay. Pre-delay (in ms)</td></tr><tr><td>postDelay</td><td>1 byte</td><td>XML: postDelay. Post-delay (in ms)</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N12886" /><p class="title"><strong>Table&nbsp;148.&nbsp;SPI Leave Programming Mode response</strong></p><div class="table-contents"><table summary="SPI Leave Programming Mode response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_ENTER_PROGMODE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td>SPI_STATUS_CMD_OK</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s06.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s06.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s06.html
new file mode 100644
index 000000000..9fef3f72b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s06.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Chip Erase - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s05.html" title="SPI Leave Programming Mode" /><link rel="next" href="ch07s01s07.html" title="SPI Program Flash" /><meta content="SPI Chip Erase" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s07.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N128A9" />SPI Chip Erase</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Perform a chip erase</p><div class="table"><a id="N128AE" /><p class="title"><strong>Table&nbsp;149.&nbsp;SPI Chip Erase command format</strong></p><div class="table-contents"><table summary="SPI Chip Erase command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_CHIP_ERASE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>eraseDelay</td><td>1 byte</td><td>XML: eraseDelay. Delay (in ms) to ensure that the erase is finished</td></tr><tr><td>pollMethod</td><td>1 byte</td><td>XML: pollMethod. Poll method: 0 = use delay; 1= use RDY/BSY
+ command </td></tr><tr><td>cmd1</td><td>1 byte</td><td>Command Byte # 1 to be transmitted</td></tr><tr><td>cmd2</td><td>1 byte</td><td>Command Byte # 2 to be transmitted</td></tr><tr><td>cmd3</td><td>1 byte</td><td>Command Byte # 3 to be transmitted</td></tr><tr><td>cmd4</td><td>1 byte</td><td>Command Byte # 4 to be transmitted</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N128F6" /><p class="title"><strong>Table&nbsp;150.&nbsp;SPI Chip Erase response</strong></p><div class="table-contents"><table summary="SPI Chip Erase response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_CHIP_ERASE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td><p>SPI_STATUS_CMD_OK or</p><p>SPI_STATUS_CMD_TOUT</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s07.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s07.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s07.html
new file mode 100644
index 000000000..ad752fcee
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s07.html
@@ -0,0 +1,231 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Program Flash - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s06.html" title="SPI Chip Erase" /><link rel="next" href="ch07s01s08.html" title="SPI Read Flash" /><meta content="SPI Program Flash" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s06.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s08.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N1291C" />SPI Program Flash</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Programs data into flash memory using SPI programming</p><div class="table"><a id="N12921" /><p class="title"><strong>Table&nbsp;151.&nbsp;SPI Program Flash command format</strong></p><div class="table-contents"><table summary="SPI Program Flash command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_PROGRAM_FLASH</td><td>1 byte</td><td>Command ID</td></tr><tr><td>NumBytes</td><td>2 byte</td><td>Total number of bytes to program, MSB first</td></tr><tr><td>mode</td><td>1 byte</td><td>XML: mode*. Mode byte*</td></tr><tr><td>delay</td><td>1 byte</td><td>XML: delay. Delay, used for different types of programming termination, according to mode byte</td></tr><tr><td>cmd1</td><td>1 byte</td><td>Command 1 (Load Page, Write Program Memory)</td></tr><tr><td>cmd2</td><td>1 byte</td><td>Command 2 (Write Program Memory Page) </td></tr><tr><td>cmd3</td><td>1 byte</td><td>Command 3 (Read Program Memory)</td></tr><tr><td>poll1</td><td>1 byte</td><td>Poll Value #1</td></tr><tr><td>poll2</td><td>1 byte</td><td>Poll Value #2 (not used for flash programming)</td></tr><tr><td>Data</td><td>1 byte</td><td>N data</td></tr></tbody></table></div></div><br class="table-break" /><p>*Mode byte: The mode parameter is essential for how this command works. The bits
+ in the mode byte have the following meanings:</p><div class="table"><a id="N1297E" /><p class="title"><strong>Table&nbsp;152.&nbsp;SPI Flash Programming Mode byte values</strong></p><div class="table-contents"><table summary="SPI Flash Programming Mode byte values" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Bit</th><th>Description</th><th>Mode</th></tr></thead><tbody><tr><td>0</td><td>Word/Page Mode (0 = word, 1 = page)</td><td>&nbsp;</td></tr><tr><td>1</td><td>Timed delay</td><td>Word Mode</td></tr><tr><td>2</td><td>Value polling</td><td>Word Mode</td></tr><tr><td>3</td><td>RDY/BSY polling</td><td>Word Mode</td></tr><tr><td>4</td><td>Timed delay</td><td>Page Mode</td></tr><tr><td>5</td><td>Value polling</td><td>Page Mode</td></tr><tr><td>6</td><td>RDY/BSY polling</td><td>Page Mode</td></tr><tr><td>7</td><td>Write page</td><td>Page Mode</td></tr></tbody></table></div></div><br class="table-break" /><p>The Word/Page Modebit selects if the device supports page programming or not. The
+ command bytes are different for word and page mode. In word mode, the SPI commands
+ Write Program Memory and Read Program Memory are used. In page mode, Load Page, Write
+ Program Memory Page and Read Program Memory are used. The read instruction is used if
+ Value Polling is specified in the mode bit. The Low/High byte selection bit (3rd bit
+ in the Load Page, Write Program Memory commands) is handled by EDBG automatically, so leave
+ this bit cleared. </p><p>
+ According to the mode, different termination methods are selected &ndash; Timed delay,
+ Value polling or RDY/BSY polling.</p><p>
+ For paged operation, the Write pagebit decides if a Write Program Memory Page
+ command should be issued after the data has been loaded into the page buffer. For
+ devices with page size bigger than what can be transferred to EDBG in one
+ command, several SPI_CMD_PROGRAM_FLASH commands must be issued. In
+ such a case, only the last command should have the Write Page mode bit set. </p><p>
+ NOTE: Only bit 0-6 are set in the XML file, because bit 7 is not constant and must be controlled
+ by the PC software. </p><p>
+ When value polling is used to determine when a programming operation is complete,
+ poll1 must be supplied. This value indicates which value will be read from the device
+ until the programmed value is read. This indicates end of programming. poll2 is used
+ only for EEPROM programming. </p><p>Response:</p><div class="table"><a id="N129D3" /><p class="title"><strong>Table&nbsp;153.&nbsp;SPI Program Flash response</strong></p><div class="table-contents"><table summary="SPI Program Flash response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_PROGRAM_FLASH</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td><p>SPI_STATUS_CMD_OK or</p><p>SPI_STATUS_CMD_TOUT or</p><p>SPI_STATUS_RDY_BSY_TOUT</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s06.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s08.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s08.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s08.html
new file mode 100644
index 000000000..4f76886e8
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s08.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Read Flash - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s07.html" title="SPI Program Flash" /><link rel="next" href="ch07s01s09.html" title="SPI Program EEPROM" /><meta content="SPI Read Flash" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s07.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s09.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N129FB" />SPI Read Flash</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads data from flash memory using SPI programming</p><div class="table"><a id="N12A00" /><p class="title"><strong>Table&nbsp;154.&nbsp;SPI Read Flash command format</strong></p><div class="table-contents"><table summary="SPI Read Flash command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_READ_FLASH</td><td>1 byte</td><td>Command ID</td></tr><tr><td>NumBytes</td><td>2 byte</td><td>Total number of bytes to read, MSB first</td></tr><tr><td>cmd1</td><td>1 byte</td><td><p>Read Program Memory command byte #1.</p><p>Low/high byte selection bit (bit 3) is handled by firmware.</p> </td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N12A30" /><p class="title"><strong>Table&nbsp;155.&nbsp;SPI Read Flash response</strong></p><div class="table-contents"><table summary="SPI Read Flash response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_READ_FLASH</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status1</td><td>1 byte</td><td>SPI_STATUS_CMD_OK</td></tr><tr><td>Data</td><td>1 byte</td><td>Data read from flash</td></tr><tr><td>Status</td><td>1 byte</td><td><p>SPI_STATUS_CMD_OK or</p><p>SPI_STATUS_RDY_BSY_TOUT</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s07.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s09.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s09.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s09.html
new file mode 100644
index 000000000..8baeae716
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s09.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Program EEPROM - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s08.html" title="SPI Read Flash" /><link rel="next" href="ch07s01s10.html" title="SPI Read EEPROM" /><meta content="SPI Program EEPROM" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s08.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s10.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12A64" />SPI Program EEPROM</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Programs data into EEPROM memory using SPI programming</p><p>Identical to SPI Program Flash command, but using SPI_CMD_PROGRAM_EEPROM</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s08.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s10.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s10.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s10.html
new file mode 100644
index 000000000..38bf91143
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s10.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Read EEPROM - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s09.html" title="SPI Program EEPROM" /><link rel="next" href="ch07s01s11.html" title="SPI Program Fuse" /><meta content="SPI Read EEPROM" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s09.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s11.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12A6B" />SPI Read EEPROM</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads data from EEPROM memory using SPI programming</p><p>Identical to SPI Read Flash command, but using SPI_CMD_READ_EEPROM</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s09.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s11.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s11.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s11.html
new file mode 100644
index 000000000..5044b87fc
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s11.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Program Fuse - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s10.html" title="SPI Read EEPROM" /><link rel="next" href="ch07s01s12.html" title="SPI Read Fuse" /><meta content="SPI Program Fuse" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s10.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s12.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12A72" />SPI Program Fuse</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Programs fuses using SPI programming</p><div class="table"><a id="N12A77" /><p class="title"><strong>Table&nbsp;156.&nbsp;SPI Program Fuse command format</strong></p><div class="table-contents"><table summary="SPI Program Fuse command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_PROGRAM_FUSE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>cmd1</td><td>1 byte</td><td>Command Byte # 1 to be transmitted</td></tr><tr><td>cmd2</td><td>1 byte</td><td>Command Byte # 2 to be transmitted</td></tr><tr><td>cmd3</td><td>1 byte</td><td>Command Byte # 3 to be transmitted</td></tr><tr><td>cmd4</td><td>1 byte</td><td>Command Byte # 4 to be transmitted</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N12AB1" /><p class="title"><strong>Table&nbsp;157.&nbsp;SPI Program Fuse response</strong></p><div class="table-contents"><table summary="SPI Program Fuse response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_PROGRAM_FUSE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td><p>SPI_STATUS_CMD_OK or</p><p>SPI_STATUS_RDY_BSY_TOUT</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s10.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s12.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s12.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s12.html
new file mode 100644
index 000000000..d36aeaf66
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s12.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Read Fuse - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s11.html" title="SPI Program Fuse" /><link rel="next" href="ch07s01s13.html" title="SPI Program Lock" /><meta content="SPI Read Fuse" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s11.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s13.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12AD7" />SPI Read Fuse</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads fuses using SPI programming</p><div class="table"><a id="N12ADC" /><p class="title"><strong>Table&nbsp;158.&nbsp;SPI Read Fuse command format</strong></p><div class="table-contents"><table summary="SPI Read Fuse command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_READ_FUSE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>RetAddr</td><td>1 byte</td><td>XML: pollIndex. Return address</td></tr><tr><td>cmd1</td><td>1 byte</td><td>Command Byte # 1 to be transmitted</td></tr><tr><td>cmd2</td><td>1 byte</td><td>Command Byte # 2 to be transmitted</td></tr><tr><td>cmd3</td><td>1 byte</td><td>Command Byte # 3 to be transmitted</td></tr><tr><td>cmd4</td><td>1 byte</td><td>Command Byte # 4 to be transmitted</td></tr></tbody></table></div></div><br class="table-break" /><p>Note: RetAddr indicates which of the transmitted bytes on the SPI interface contains the return value,
+ since the SPI interface is implemented as a ring buffer (one byte in, one byte out) </p><p>Response:</p><div class="table"><a id="N12B1F" /><p class="title"><strong>Table&nbsp;159.&nbsp;SPI Read Fuse response</strong></p><div class="table-contents"><table summary="SPI Read Fuse response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>SPI_CMD_READ_FUSE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status1</td><td>1 byte</td><td>SPI_STATUS_CMD_OK</td></tr><tr><td>Data</td><td>1 byte</td><td>Data read from the device</td></tr><tr><td>Status2</td><td>1 byte</td><td><p>SPI_STATUS_CMD_OK or</p><p>SPI_STATUS_RDY_BSY_TOUT</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s11.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s13.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s13.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s13.html
new file mode 100644
index 000000000..5d314e462
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s13.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Program Lock - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s12.html" title="SPI Read Fuse" /><link rel="next" href="ch07s01s14.html" title="SPI Read Lock" /><meta content="SPI Program Lock" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s12.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s14.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12B53" />SPI Program Lock</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Programs lock bits using SPI programming</p><p>Identical to SPI Program Fuse command, but using SPI_CMD_PROGRAM_LOCK</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s12.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s14.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s14.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s14.html
new file mode 100644
index 000000000..98dc07000
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s14.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Read Lock - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s13.html" title="SPI Program Lock" /><link rel="next" href="ch07s01s15.html" title="SPI Read Signature" /><meta content="SPI Read Lock" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s13.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s15.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12B5A" />SPI Read Lock</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads lock bits using SPI programming</p><p>Identical to SPI Read Fuse command, but using SPI_CMD_READ_LOCK</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s13.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s15.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s15.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s15.html
new file mode 100644
index 000000000..b116fcda6
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s15.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Read Signature - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s14.html" title="SPI Read Lock" /><link rel="next" href="ch07s01s16.html" title="SPI Read OSCCAL" /><meta content="SPI Read Signature" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s14.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s16.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12B61" />SPI Read Signature</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads signature bytes using SPI programming</p><p>Identical to SPI Read Fuse command, but using SPI_CMD_READ_SIGNATURE.</p><p>In addition the SPI commands for reading the signature must be supplied.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s14.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s16.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s16.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s16.html
new file mode 100644
index 000000000..fdc2d8ece
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s16.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Read OSCCAL - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s15.html" title="SPI Read Signature" /><link rel="next" href="ch07s01s17.html" title="SPI Multi" /><meta content="SPI Read OSCCAL" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s15.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01s17.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12B6A" />SPI Read OSCCAL</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads OSCCAL bytes using SPI programming</p><p>Identical to SPI Read Fuse command, but using SPI_CMD_READ_OSCCAL.</p><p>In addition the SPI commands for reading the OSCCAL byte must be supplied.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s15.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01s17.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s17.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s17.html
new file mode 100644
index 000000000..e0a212842
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s01s17.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI Multi - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch07s01.html" title="SPI programming protocol commands" /><link rel="prev" href="ch07s01s16.html" title="SPI Read OSCCAL" /><link rel="next" href="ch07s02.html" title="SPI programming protocol responses" /><meta content="SPI Multi" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />SPI programming protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s16.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch07s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12B73" />SPI Multi</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The SPI_MULTI command is not supported by this implementation.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s16.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch07s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s02.html
new file mode 100644
index 000000000..6dc0922fd
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SPI programming protocol responses - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avrispprotocol.html" title="AVR ISP protocol" /><link rel="prev" href="ch07s01s17.html" title="SPI Multi" /><link rel="next" href="ch07s03.html" title="ID definitions" /><meta content="SPI programming protocol responses" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR ISP protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s01s17.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avrispprotocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N12B78" />SPI programming protocol responses</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Response packets are described after each command.</p><div class="table"><a id="N12B7D" /><p class="title"><strong>Table&nbsp;160.&nbsp;SPI response types</strong></p><div class="table-contents"><table summary="SPI response types" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Type</th><th>Value</th><th>Description</th></tr></thead><tbody><tr><td>Success</td><td>SPI_STATUS_CMD_OK</td><td>Command executed OK</td></tr><tr><td rowspan="2">Warnings</td><td>SPI_STATUS_CMD_TOUT</td><td>Command timed out</td></tr><tr><td>SPI_STATUS_RDY_BSY_TOUT</td><td>Sampling of the RDY/nBSY pin timed out </td></tr><tr><td rowspan="5">Errors</td><td>SPI_STATUS_CMD_FAILED</td><td>The command did not execute</td></tr><tr><td>SPI_STATUS_CMD_UNKNOWN</td><td>Unknown command</td></tr><tr><td>SPI_STATUS_PHY_ERROR</td><td>SPI hardware error</td></tr><tr><td>SPI_STATUS_CLOCK_ERROR</td><td>Lower the clock and retry</td></tr><tr><td>SPI_STATUS_BAUD_INVALID</td><td>Baud rate out of range</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s01s17.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avrispprotocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s03.html
new file mode 100644
index 000000000..080363476
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch07s03.html
@@ -0,0 +1,253 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>ID definitions - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avrispprotocol.html" title="AVR ISP protocol" /><link rel="prev" href="ch07s02.html" title="SPI programming protocol responses" /><link rel="next" href="protocoldocs.tpiprotocol.html" title="TPI Protocol" /><meta content="ID definitions" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR ISP protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avrispprotocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="protocoldocs.tpiprotocol.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N12BC3" />ID definitions</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">
+ This sections includes the header file defining the different command,
+ response and event IDs for the AVRISP protocol. It also defines the different possible failure codes.
+ </p><pre class="programlisting"><span class="hl-keyword" style="color: #0000FF">enum</span> SpiProgrammingProtocolCommands {
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+ <em class="hl-comment" style="color: #008000">// Protocol commands</em>
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+ SPI_CMD_LOAD_ADDRESS = <span class="hl-number">0x06</span>, <em class="hl-comment" style="color: #008000">//! Load address</em>
+ SPI_CMD_ENTER_PROGMODE = <span class="hl-number">0x10</span>, <em class="hl-comment" style="color: #008000">//! Enter programming mode</em>
+ SPI_CMD_LEAVE_PROGMODE = <span class="hl-number">0x11</span>, <em class="hl-comment" style="color: #008000">//! Leave programming mode</em>
+ SPI_CMD_CHIP_ERASE = <span class="hl-number">0x12</span>, <em class="hl-comment" style="color: #008000">//! Erase device</em>
+ SPI_CMD_PROGRAM_FLASH = <span class="hl-number">0x13</span>, <em class="hl-comment" style="color: #008000">//! Program flash data</em>
+ SPI_CMD_READ_FLASH = <span class="hl-number">0x14</span>, <em class="hl-comment" style="color: #008000">//! Read flash data</em>
+ SPI_CMD_PROGRAM_EEPROM = <span class="hl-number">0x15</span>, <em class="hl-comment" style="color: #008000">//! Program EEPROM data</em>
+ SPI_CMD_READ_EEPROM = <span class="hl-number">0x16</span>, <em class="hl-comment" style="color: #008000">//! Read EEPROM data</em>
+ SPI_CMD_PROGRAM_FUSE = <span class="hl-number">0x17</span>, <em class="hl-comment" style="color: #008000">//! Program a fuse byte</em>
+ SPI_CMD_READ_FUSE = <span class="hl-number">0x18</span>, <em class="hl-comment" style="color: #008000">//! Read a fuse byte</em>
+ SPI_CMD_PROGRAM_LOCK = <span class="hl-number">0x19</span>, <em class="hl-comment" style="color: #008000">//! Program lock bits</em>
+ SPI_CMD_READ_LOCK = <span class="hl-number">0x1A</span>, <em class="hl-comment" style="color: #008000">//! Read lock bits</em>
+ SPI_CMD_READ_SIGNATURE = <span class="hl-number">0x1B</span>, <em class="hl-comment" style="color: #008000">//! Read a signature byte</em>
+ SPI_CMD_READ_OSCCAL = <span class="hl-number">0x1C</span>, <em class="hl-comment" style="color: #008000">//! Read an OSCCAL byte</em>
+ SPI_CMD_SET_BAUD = <span class="hl-number">0x1D</span>, <em class="hl-comment" style="color: #008000">//! Set baud rate</em>
+ SPI_CMD_GET_BAUD = <span class="hl-number">0x1E</span> <em class="hl-comment" style="color: #008000">//! Read baud rate</em>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> SpiProgrammingProtocolResponses {
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+ <em class="hl-comment" style="color: #008000">// Protocol responses</em>
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+ <em class="hl-comment" style="color: #008000">// Success</em>
+ SPI_STATUS_CMD_OK = <span class="hl-number">0x00</span>, <em class="hl-comment" style="color: #008000">//! All OK</em>
+
+ <em class="hl-comment" style="color: #008000">// Warnings</em>
+ SPI_STATUS_CMD_TOUT = <span class="hl-number">0x80</span>, <em class="hl-comment" style="color: #008000">//! Command timeout</em>
+ SPI_STATUS_RDY_BSY_TOUT = <span class="hl-number">0x81</span>, <em class="hl-comment" style="color: #008000">//! Device busy</em>
+
+ <em class="hl-comment" style="color: #008000">// Errors</em>
+ SPI_STATUS_CMD_FAILED = <span class="hl-number">0xC0</span>, <em class="hl-comment" style="color: #008000">//! Command failed</em>
+ SPI_STATUS_CMD_UNKNOWN = <span class="hl-number">0xC9</span>, <em class="hl-comment" style="color: #008000">//! Unknown error</em>
+ SPI_STATUS_PHY_ERROR = <span class="hl-number">0xCB</span>, <em class="hl-comment" style="color: #008000">//! Physical error</em>
+ SPI_STATUS_CLOCK_ERROR = <span class="hl-number">0xCC</span>, <em class="hl-comment" style="color: #008000">//! Speed error</em>
+ SPI_STATUS_BAUD_INVALID = <span class="hl-number">0xCD</span> <em class="hl-comment" style="color: #008000">//! Baud value error</em>
+};</pre></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avrispprotocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="protocoldocs.tpiprotocol.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01.html
new file mode 100644
index 000000000..cffed6d67
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>TPI protocol commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.tpiprotocol.html" title="TPI Protocol" /><link rel="prev" href="protocoldocs.tpiprotocol.html" title="TPI Protocol" /><link rel="next" href="ch08s01s01.html" title="TPI Enter Programming Mode" /><meta content="TPI protocol commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />TPI Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="protocoldocs.tpiprotocol.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.tpiprotocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch08s01s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N12BDA" />TPI protocol commands</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch08s01s01.html">TPI Enter Programming Mode</a></span></dt><dt><span class="section"><a href="ch08s01s02.html">TPI Leave Programming Mode</a></span></dt><dt><span class="section"><a href="ch08s01s03.html">TPI Set Parameter</a></span></dt><dt><span class="section"><a href="ch08s01s04.html">TPI Erase</a></span></dt><dt><span class="section"><a href="ch08s01s05.html">TPI Write Memory</a></span></dt><dt><span class="section"><a href="ch08s01s06.html">TPI Read Memory</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="protocoldocs.tpiprotocol.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.tpiprotocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch08s01s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s01.html
new file mode 100644
index 000000000..896cd5abd
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s01.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>TPI Enter Programming Mode - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch08s01.html" title="TPI protocol commands" /><link rel="prev" href="ch08s01.html" title="TPI protocol commands" /><link rel="next" href="ch08s01s02.html" title="TPI Leave Programming Mode" /><meta content="TPI Enter Programming Mode" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />TPI protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch08s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch08s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch08s01s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12BDD" />TPI Enter Programming Mode</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Enters programming mode to start TPI programming</p><div class="table"><a id="N12BE2" /><p class="title"><strong>Table&nbsp;161.&nbsp;TPI Enter Programming Mode command format</strong></p><div class="table-contents"><table summary="TPI Enter Programming Mode command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_ENTER_PROGMODE</td><td>1 byte</td><td>Command ID</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N12C00" /><p class="title"><strong>Table&nbsp;162.&nbsp;TPI Enter Programming Mode response</strong></p><div class="table-contents"><table summary="TPI Enter Programming Mode response" border="1"><colgroup><col /><col class="c2" /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_ENTER_PROGMODE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td><p>TPI_RSP_ERR_FAILED or</p><p>TPI_RSP_ERR_COLLISION or</p><p>TPI_RSP_ERR_OK</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch08s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch08s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch08s01s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s02.html
new file mode 100644
index 000000000..b3aaba663
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>TPI Leave Programming Mode - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch08s01.html" title="TPI protocol commands" /><link rel="prev" href="ch08s01s01.html" title="TPI Enter Programming Mode" /><link rel="next" href="ch08s01s03.html" title="TPI Set Parameter" /><meta content="TPI Leave Programming Mode" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />TPI protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch08s01s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch08s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch08s01s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12C2C" />TPI Leave Programming Mode</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Leaves programming mode to complete TPI programming</p><div class="table"><a id="N12C31" /><p class="title"><strong>Table&nbsp;163.&nbsp;TPI Leave Programming Mode command format</strong></p><div class="table-contents"><table summary="TPI Leave Programming Mode command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_LEAVE_PROGMODE</td><td>1 byte</td><td>Command ID</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N12C4F" /><p class="title"><strong>Table&nbsp;164.&nbsp;TPI Leave Programming Mode response</strong></p><div class="table-contents"><table summary="TPI Leave Programming Mode response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_LEAVE_PROGMODE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td>TPI_RSP_ERR_OK</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch08s01s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch08s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch08s01s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s03.html
new file mode 100644
index 000000000..48757b5d2
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s03.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>TPI Set Parameter - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch08s01.html" title="TPI protocol commands" /><link rel="prev" href="ch08s01s02.html" title="TPI Leave Programming Mode" /><link rel="next" href="ch08s01s04.html" title="TPI Erase" /><meta content="TPI Set Parameter" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />TPI protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch08s01s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch08s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch08s01s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12C72" />TPI Set Parameter</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Initialises the TPI interface with parameters</p><div class="table"><a id="N12C77" /><p class="title"><strong>Table&nbsp;165.&nbsp;TPI Set Parameter command format</strong></p><div class="table-contents"><table summary="TPI Set Parameter command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_SET_PARAM</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Parameter ID</td><td>1 byte</td><td>Parameter to set</td></tr><tr><td>Parameter Value</td><td>1-4 bytes</td><td>Value to write</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N12CA3" /><p class="title"><strong>Table&nbsp;166.&nbsp;TPI Set Parameter response</strong></p><div class="table-contents"><table summary="TPI Set Parameter response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_SET_PARAM</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td><p>TPI_RSP_ERR_FAILED or</p><p>TPI_RSP_ERR_ILLEGAL_PARAM or</p><p>TPI_RSP_ERR_OK</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch08s01s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch08s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch08s01s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s04.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s04.html
new file mode 100644
index 000000000..fc6f8a8ae
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s04.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>TPI Erase - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch08s01.html" title="TPI protocol commands" /><link rel="prev" href="ch08s01s03.html" title="TPI Set Parameter" /><link rel="next" href="ch08s01s05.html" title="TPI Write Memory" /><meta content="TPI Erase" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />TPI protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch08s01s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch08s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch08s01s05.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12CCB" />TPI Erase</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Perform an erase</p><div class="table"><a id="N12CD0" /><p class="title"><strong>Table&nbsp;167.&nbsp;TPI Erase command format</strong></p><div class="table-contents"><table summary="TPI Erase command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_ERASE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Erase Mode</td><td>1 byte</td><td><p>TPI_ERASE_CHIP or</p><p>TPI_ERASE_APP or</p><p>TPI_ERASE_CONFIG</p></td></tr><tr><td>Address</td><td>4 bytes</td><td>Address or area to erase</td></tr></tbody></table></div></div><br class="table-break" /><div class="table"><a id="N12CFF" /><p class="title"><strong>Table&nbsp;168.&nbsp;TPI Erase Modes</strong></p><div class="table-contents"><table summary="TPI Erase Modes" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Mode</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_ERASE_CHIP</td><td>Erases the whole chip and clears lockbits</td></tr><tr><td>TPI_ERASE_APP</td><td>Erases the application section</td></tr><tr><td>TPI_ERASE_CONFIG</td><td>Clear the configuration bits</td></tr></tbody></table></div></div><br class="table-break" /><p>Address is ignored for TPI_ERASE_CHIP. For other erase modes the address must be provided.</p><p>Response:</p><div class="table"><a id="N12D22" /><p class="title"><strong>Table&nbsp;169.&nbsp;TPI Erase response</strong></p><div class="table-contents"><table summary="TPI Erase response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_ERASE</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td><p>TPI_RSP_ERR_FAILED or</p><p>TPI_RSP_ERR_COLLISION or</p><p>TPI_RSP_ERR_TIMEOUT or</p><p>TPI_RSP_ERR_OK</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch08s01s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch08s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch08s01s05.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s05.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s05.html
new file mode 100644
index 000000000..fe082b12c
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s05.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>TPI Write Memory - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch08s01.html" title="TPI protocol commands" /><link rel="prev" href="ch08s01s04.html" title="TPI Erase" /><link rel="next" href="ch08s01s06.html" title="TPI Read Memory" /><meta content="TPI Write Memory" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />TPI protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch08s01s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch08s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch08s01s06.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12D4C" />TPI Write Memory</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Writes data into memory using TPI programming</p><div class="table"><a id="N12D51" /><p class="title"><strong>Table&nbsp;170.&nbsp;TPI Write Memory command format</strong></p><div class="table-contents"><table summary="TPI Write Memory command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_WRITE_MEM</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Memory Type</td><td>1 byte</td><td><p>TPI_MEM_TYPE_APPL or</p><p>TPI_MEM_TYPE_FUSE or</p><p>TPI_MEM_TYPE_LOCKBITS</p></td></tr><tr><td>Page Mode</td><td>1 byte</td><td>Not used - ignored</td></tr><tr><td>Address</td><td>4 bytes</td><td>Address to write to</td></tr><tr><td>Length</td><td>2 bytes</td><td>Number of bytes to write(1 to 512)</td></tr><tr><td>Data</td><td>N bytes</td><td>Data to write</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N12D97" /><p class="title"><strong>Table&nbsp;171.&nbsp;TPI Write Memory response</strong></p><div class="table-contents"><table summary="TPI Write Memory response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_WRITE_MEM</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td><p>TPI_RSP_ERR_FAILED or</p><p>TPI_RSP_ERR_COLLISION or</p><p>TPI_RSP_ERR_TIMEOUT or</p><p>TPI_RSP_ERR_OK</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch08s01s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch08s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch08s01s06.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s06.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s06.html
new file mode 100644
index 000000000..dbcda2ca7
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s01s06.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>TPI Read Memory - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch08s01.html" title="TPI protocol commands" /><link rel="prev" href="ch08s01s05.html" title="TPI Write Memory" /><link rel="next" href="ch08s02.html" title="TPI programming protocol responses" /><meta content="TPI Read Memory" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />TPI protocol commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch08s01s05.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch08s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch08s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N12DC1" />TPI Read Memory</h3></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Reads data from memory using TPI programming</p><div class="table"><a id="N12DC6" /><p class="title"><strong>Table&nbsp;172.&nbsp;TPI Read Memory command format</strong></p><div class="table-contents"><table summary="TPI Read Memory command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_READ_MEM</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Memory Type</td><td>1 byte</td><td><p>TPI_MEM_TYPE_APPL or</p><p>TPI_MEM_TYPE_FUSE or</p><p>TPI_MEM_TYPE_LOCKBITS</p></td></tr><tr><td>Address</td><td>4 bytes</td><td>Address to start reading from</td></tr><tr><td>Length</td><td>2 bytes</td><td>Number of bytes to read (1 to 256)</td></tr></tbody></table></div></div><br class="table-break" /><p>Response:</p><div class="table"><a id="N12DFE" /><p class="title"><strong>Table&nbsp;173.&nbsp;TPI Read Memory response</strong></p><div class="table-contents"><table summary="TPI Read Memory response" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>TPI_CMD_READ_MEM</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Status</td><td>1 byte</td><td><p>TPI_RSP_ERR_FAILED or</p><p>TPI_RSP_ERR_COLLISION or</p><p>TPI_RSP_ERR_OK</p></td></tr><tr><td>Data</td><td>1 byte</td><td>Data read from memory</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch08s01s05.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch08s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch08s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s02.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s02.html
new file mode 100644
index 000000000..0b1a19b5f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s02.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>TPI programming protocol responses - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.tpiprotocol.html" title="TPI Protocol" /><link rel="prev" href="ch08s01s06.html" title="TPI Read Memory" /><link rel="next" href="ch08s03.html" title="ID definitions" /><meta content="TPI programming protocol responses" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />TPI Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch08s01s06.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.tpiprotocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch08s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N12E2D" />TPI programming protocol responses</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Response packets are described after each command.</p><div class="table"><a id="N12E32" /><p class="title"><strong>Table&nbsp;174.&nbsp;TPI response types</strong></p><div class="table-contents"><table summary="TPI response types" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Value</th><th>Description</th></tr></thead><tbody><tr><td>TPI_RSP_ERR_OK</td><td>Command executed OK</td></tr><tr><td>TPI_RSP_ERR_FAILED</td><td>Execution failed</td></tr><tr><td>TPI_RSP_ERR_COLLISION</td><td>Physical collision detected</td></tr><tr><td>TPI_RSP_ERR_TIMEOUT</td><td>The command timed out</td></tr><tr><td>TPI_RSP_ERR_ILLEGAL_PARAM</td><td>Unknown parameter</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch08s01s06.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.tpiprotocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch08s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s03.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s03.html
new file mode 100644
index 000000000..fb6afa569
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/ch08s03.html
@@ -0,0 +1,240 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>ID definitions - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.tpiprotocol.html" title="TPI Protocol" /><link rel="prev" href="ch08s02.html" title="TPI programming protocol responses" /><link rel="next" href="document.revisions.html" title="Document Revisions" /><meta content="ID definitions" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />TPI Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch08s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.tpiprotocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="document.revisions.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="N12E5E" />ID definitions</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml"> This section includes the header file defining the different command, response and
+ event IDs for the TPIPROTOCOL. It also defines the different possible failure codes. </p><pre class="programlisting"><em class="hl-comment" style="color: #008000">// TPI commands</em>
+<span style="color: maroon" class="hl-directive">#define TPI_CMD_ENTER_PROGMODE 0x01</span>
+<span style="color: maroon" class="hl-directive">#define TPI_CMD_LEAVE_PROGMODE 0x02</span>
+<span style="color: maroon" class="hl-directive">#define TPI_CMD_ERASE 0x03</span>
+<span style="color: maroon" class="hl-directive">#define TPI_CMD_WRITE_MEM 0x04</span>
+<span style="color: maroon" class="hl-directive">#define TPI_CMD_READ_MEM 0x05</span>
+<span style="color: maroon" class="hl-directive">#define TPI_CMD_SET_PARAM 0x07</span>
+
+<em class="hl-comment" style="color: #008000">// Memory types</em>
+<span style="color: maroon" class="hl-directive">#define TPI_MEM_TYPE_APPL 1</span>
+<span style="color: maroon" class="hl-directive">#define TPI_MEM_TYPE_FUSE 4</span>
+<span style="color: maroon" class="hl-directive">#define TPI_MEM_TYPE_LOCKBITS 5</span>
+
+<em class="hl-comment" style="color: #008000">// Erase modes</em>
+<span style="color: maroon" class="hl-directive">#define TPI_ERASE_CHIP 1</span>
+<span style="color: maroon" class="hl-directive">#define TPI_ERASE_APP 2</span>
+<span style="color: maroon" class="hl-directive">#define TPI_ERASE_CONFIG 9</span>
+
+<em class="hl-comment" style="color: #008000">// Error codes</em>
+<span style="color: maroon" class="hl-directive">#define TPI_RSP_ERR_OK 0</span>
+<span style="color: maroon" class="hl-directive">#define TPI_RSP_ERR_FAILED 1</span>
+<span style="color: maroon" class="hl-directive">#define TPI_RSP_ERR_COLLISION 2</span>
+<span style="color: maroon" class="hl-directive">#define TPI_RSP_ERR_TIMEOUT 3</span>
+<span style="color: maroon" class="hl-directive">#define TPI_RSP_ERR_ILLEGAL_PARAM 4</span>
+
+<em class="hl-comment" style="color: #008000">// TPI parameters </em>
+<span style="color: maroon" class="hl-directive">#define TPI_PARAM_NVMCMD_ADDR 0x03</span>
+<span style="color: maroon" class="hl-directive">#define TPI_PARAM_NVMCSR_ADDR 0x04</span>
+</pre></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch08s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.tpiprotocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="document.revisions.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/document.revisions.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/document.revisions.html
new file mode 100644
index 000000000..5e2418811
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/document.revisions.html
@@ -0,0 +1,209 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Document Revisions - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="prev" href="ch08s03.html" title="ID definitions" /><meta content="Document Revisions" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Document Revisions</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch08s03.html">Prev</a>&nbsp;</td></tr></table></div></div><div id="content"><!----><div class="chapter"><div xmlns="" class="titlepage"><div><div><h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="document.revisions" />Document Revisions</h1></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">
+ </p><div class="revhistory"><div class="table"><div class="table-content"><table><colgroup><col class="c1" /><col class="c2" /><col class="c2" /></colgroup><thead><tr><th>Document revision</th><th>Date</th><th>Comment</th></tr></thead><tbody><tr background-color="color: #D9D9D9"><td>42197A</td><td>09.10.2013</td><td>Preliminary (internal) release.</td></tr><tr background-color="color: #F2F2F2"><td>42197B</td><td>28.01.2014</td><td>Preliminary (beta) release.</td></tr></tbody></table></div></div></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch08s03.html">Prev</a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;</td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/index.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/index.html
new file mode 100644
index 000000000..7d4c0901c
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/index.html
@@ -0,0 +1,227 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Atmel EDBG-based Tools Protocols - </title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><meta name="keywords" content="Atmel, EDBG, Advanced, MCU, Protocol" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="next" href="pr01.html" title="Preface" /><meta content="Atmel EDBG-based Tools Protocols" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />&nbsp;</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td>&nbsp;
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="pr01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="book"><div xmlns="" class="titlepage"><div><div><h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="protocoldocs" />Atmel EDBG-based Tools Protocols</h1></div>Atmel Corporation<div></div><div xmlns="http://www.w3.org/1999/xhtml" class="disclaimer"><p>&copy; 2014 Atmel Corporation. All rights reserved. / Rev.: 42197AX-MCU-10/2014</p><div class="legalnotice"><p>Atmel&reg;, Atmel logo and combinations thereof, Enabling Unlimited Possibilities&reg;, <span class="trademark">AVR</span>&reg;, and others are registered trademarks or trademarks of Atmel Corporation in U.S. and other countries. <span class="trademark">Windows</span>&reg; is a registered trademark of Microsoft Corporation in U.S. and or other countries. <span class="trademark">ARM</span>&reg; is a registered trademark of ARM Ltd. Other terms and product names may be trademarks of others.</p></div><p>
+ Disclaimer: The information in this
+ document is provided in connection with Atmel products. No license, express or implied, by estoppel
+ or otherwise, to any intellectual property right is granted by this document or in connection with
+ the sale of Atmel products. EXCEPT AS SET FORTH IN THE ATMEL TERMS AND CONDITIONS OF SALES LOCATED
+ ON THE ATMEL WEBSITE, ATMEL ASSUMES NO LIABILITY WHATSOEVER AND DISCLAIMS ANY EXPRESS, IMPLIED OR
+ STATUTORY WARRANTY RELATING TO ITS PRODUCTS INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTY OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL ATMEL BE
+ LIABLE FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, PUNITIVE, SPECIAL OR INCIDENTAL DAMAGES (INCLUDING,
+ WITHOUT LIMITATION, DAMAGES FOR LOSS AND PROFITS, BUSINESS INTERRUPTION, OR LOSS OF INFORMATION)
+ ARISING OUT OF THE USE OR INABILITY TO USE THIS DOCUMENT, EVEN IF ATMEL HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES. Atmel makes no representations or warranties with respect to the
+ accuracy or completeness of the contents of this document and reserves the right to make changes to
+ specifications and products descriptions at any time without notice. Atmel does not make any
+ commitment to update the information contained herein. Unless specifically provided otherwise, Atmel
+ products are not suitable for, and shall not be used in, automotive applications. Atmel products are
+ not intended, authorized, or warranted for use as components in applications intended to support or
+ sustain life.
+ </p></div></div><hr></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="preface"><a href="pr01.html">Preface</a></span></dt><dt><span class="chapter"><a href="protocoldocs.Introduction.html">Introduction</a></span></dt><dt><span class="chapter"><a href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span></dt><dt><span class="chapter"><a href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span></dt><dt><span class="chapter"><a href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span></dt><dt><span class="chapter"><a href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span></dt><dt><span class="chapter"><a href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span></dt><dt><span class="chapter"><a href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span></dt><dt><span class="chapter"><a href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span></dt><dt><span class="chapter"><a href="document.revisions.html">Document Revisions</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%">&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="pr01.html">Next</a></td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/pr01.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/pr01.html
new file mode 100644
index 000000000..53f993d3f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/pr01.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Preface - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="prev" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="next" href="protocoldocs.Introduction.html" title="Introduction" /><meta content="Preface" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Preface</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="index.html">Prev</a>&nbsp;
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="protocoldocs.Introduction.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="preface"><div xmlns="" class="titlepage"><div><div><h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N10031" />Preface</h1></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">The <span xmlns="http://www.w3.org/1999/xhtml" class="trademark">Atmel</span>&reg; Embedded Debugger (EDBG) offers on-board programming and debugging support to all Atmel kits in which it is embedded.</p><p>EDBG is supported natively in Atmel Studio.</p><p>This documentation provides details on the EDBG communication protocol, and is
+ intended for advanced users who want to develop their own software components which
+ interact with EDBG and other Atmel tools based on EDBG.</p><p>The protocol defined here is to be used at your own risk. Not all EDBG commands are
+ documented here. Errors or questions can be addressed to <a class="link" href="mailto:edbg@atmel.com" target="_top">edbg@atmel.com</a>.</p><p>Although efforts will be made to keep the contents of this document accurate,
+ Atmel reserves the right to change or extend the protocol without prior notice.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="index.html">Prev</a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="protocoldocs.Introduction.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.Introduction.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.Introduction.html
new file mode 100644
index 000000000..c0ff81420
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.Introduction.html
@@ -0,0 +1,209 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Introduction - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="prev" href="pr01.html" title="Preface" /><link rel="next" href="ch01s01.html" title="EDBG interface overview" /><meta content="Introduction" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Introduction</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="pr01.html">Prev</a>&nbsp;
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch01s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="chapter"><div xmlns="" class="titlepage"><div><div><h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="protocoldocs.Introduction" />Introduction</h1></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch01s01.html">EDBG interface overview</a></span></dt><dt><span class="section"><a href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="pr01.html">Prev</a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch01s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avr32protocol.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avr32protocol.html
new file mode 100644
index 000000000..e5f43a972
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avr32protocol.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>AVR32 generic protocol - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="prev" href="ch04s05s10.html" title="Housekeeping ID definitions" /><link rel="next" href="ch05s01.html" title="Protocol commands" /><meta content="AVR32 generic protocol" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR32 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s10.html">Prev</a>&nbsp;
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="chapter"><div xmlns="" class="titlepage"><div><div><h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="protocoldocs.avr32protocol" />AVR32 generic protocol</h1></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch05s01.html">Protocol commands</a></span></dt><dt><span class="section"><a href="ch05s02.html">Responses</a></span></dt><dt><span class="section"><a href="ch05s03.html">Hints and tips</a></span></dt><dt><span class="section"><a href="ch05s04.html">AVR32GENERIC ID definitions</a></span></dt></dl></div><p>The AVR32GENERIC protocol is the single protocol for programming and debugging
+ Atmel AVR UC3 32-bit microcontrollers using all relevant tools. </p><p>UC3 devices are big endian meaning that byte address 0 is most significant byte. The
+ AVR32GENERIC protocol is little endian, i.e. least significant byte is sent first. Words are
+ sent in ascending order, i.e. lowest word address first. </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s10.html">Prev</a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avr8protocol.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avr8protocol.html
new file mode 100644
index 000000000..a93a23c7f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avr8protocol.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>AVR8 generic protocol - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="prev" href="ch05s04.html" title="AVR32GENERIC ID definitions" /><link rel="next" href="ch06s01.html" title="Protocol Commands" /><meta content="AVR8 generic protocol" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR8 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s04.html">Prev</a>&nbsp;
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="chapter"><div xmlns="" class="titlepage"><div><div><h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="protocoldocs.avr8protocol" />AVR8 generic protocol</h1></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch06s01.html">Protocol Commands</a></span></dt><dt><span class="section"><a href="ch06s02.html">Responses</a></span></dt><dt><span class="section"><a href="ch06s03.html">Events</a></span></dt><dt><span class="section"><a href="section_avr8_memtypes.html">Memory Types</a></span></dt><dt><span class="section"><a href="ch06s05.html">Hints and tips:</a></span></dt><dt><span class="section"><a href="ch06s06.html">AVR8GENERIC ID definitions</a></span></dt></dl></div><p>The AVR8 generic protocol is the single protocol for programming and debugging
+ 8-bit AVR devices on all NEW tools (JTAGICE3 and newer).
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s04.html">Prev</a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avrispprotocol.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avrispprotocol.html
new file mode 100644
index 000000000..660b1e669
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avrispprotocol.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>AVR ISP protocol - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="prev" href="ch06s06.html" title="AVR8GENERIC ID definitions" /><link rel="next" href="ch07s01.html" title="SPI programming protocol commands" /><meta content="AVR ISP protocol" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR ISP protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s06.html">Prev</a>&nbsp;
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch07s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="chapter"><div xmlns="" class="titlepage"><div><div><h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="protocoldocs.avrispprotocol" />AVR ISP protocol</h1></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch07s01.html">SPI programming protocol commands</a></span></dt><dt><span class="section"><a href="ch07s02.html">SPI programming protocol responses</a></span></dt><dt><span class="section"><a href="ch07s03.html">ID definitions</a></span></dt></dl></div><p>The AVR ISP protocol is based upon the communication protocol used by all Atmel
+ AVR tools as far back as the STK500. It is used for programming tinyAVR and megaAVR devices
+ using the SPI interface</p><p>Timing parameter
+ values are extracted from XML files and included in the protocol command function
+ calls.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>This protocol is also described in the Application Note <a class="link" href="http://www.atmel.com/Images/doc8015.pdf" target="_top">AVR069: AVRISP mkII
+ Communication Protocol</a>, although not all commands are supported. The
+ SPI_MULTI command is not supported by this implementation.</p></div><p>The protocol commands are put in the payload of EDBG commands with the handler
+ set to SPI. The responses are also sent as the payload of EDBG commands.</p><p>Note that the SPI protocol has no CMD_ACTIVATE_PHYSICAL. The ENTER_PROGMODE command will
+ enable the physical and LEAVE_PROGMODE will deactivate it.</p><p>The SPI_MULTI command is not supported by this implementation.</p><p>In addition to the SPI commands the general CMD_LOAD_ADDRESS from the STK500 communication
+ protocol is supported. This command is used to set the start address for the following write
+ or read command. This command is described below.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s06.html">Prev</a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch07s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avrprotocol.Overview.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avrprotocol.Overview.html
new file mode 100644
index 000000000..599ac4895
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.avrprotocol.Overview.html
@@ -0,0 +1,209 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>AVR communication protocol - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="prev" href="section_edbg_ctrl_setget_params.html" title="EDBGCTRL ID definitions" /><link rel="next" href="ch04s01.html" title="Overview" /><meta content="AVR communication protocol" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR communication protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="section_edbg_ctrl_setget_params.html">Prev</a>&nbsp;
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="chapter"><div xmlns="" class="titlepage"><div><div><h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="protocoldocs.avrprotocol.Overview" />AVR communication protocol</h1></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch04s01.html">Overview</a></span></dt><dt><span class="section"><a href="ch04s02.html">Framing</a></span></dt><dt><span class="section"><a href="ch04s03.html">Protocol sub-set overview</a></span></dt><dt><span class="section"><a href="ch04s04.html">Discovery Protocol Definition</a></span></dt><dt><span class="section"><a href="ch04s05.html">Housekeeping Protocol</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="section_edbg_ctrl_setget_params.html">Prev</a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.cmsis_dap.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.cmsis_dap.html
new file mode 100644
index 000000000..828c6d2e7
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.cmsis_dap.html
@@ -0,0 +1,209 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>CMSIS-DAP - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="prev" href="ch01s02.html" title="Atmel EDBG-based tool implementations" /><link rel="next" href="ch02s01.html" title="CMSIS-DAP protocol" /><meta content="CMSIS-DAP" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />CMSIS-DAP</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch01s02.html">Prev</a>&nbsp;
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="chapter"><div xmlns="" class="titlepage"><div><div><h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="protocoldocs.cmsis_dap" />CMSIS-DAP</h1></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch02s01.html">CMSIS-DAP protocol</a></span></dt><dt><span class="section"><a href="ch02s02.html">CMSIS-DAP vendor commands</a></span></dt><dt><span class="section"><a href="section_serial_trace.html">Serial trace commands</a></span></dt><dt><span class="section"><a href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch01s02.html">Prev</a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.edbg_ctrl_protocol.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.edbg_ctrl_protocol.html
new file mode 100644
index 000000000..5d8211df7
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.edbg_ctrl_protocol.html
@@ -0,0 +1,210 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>EDBG Control Protocol - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="prev" href="ch02s04s03.html" title="Unwrapping AVR events" /><link rel="next" href="ch03s01.html" title="Protocol commands" /><meta content="EDBG Control Protocol" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />EDBG Control Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s04s03.html">Prev</a>&nbsp;
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch03s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="chapter"><div xmlns="" class="titlepage"><div><div><h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="protocoldocs.edbg_ctrl_protocol" />EDBG Control Protocol</h1></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch03s01.html">Protocol commands</a></span></dt><dt><span class="section"><a href="ch03s02.html">Responses</a></span></dt><dt><span class="section"><a href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></dt></dl></div><p>The EDBG Control protocol is used to query and configure parameters relevant to EDBG
+ and the board in which EDBG is embedded.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s04s03.html">Prev</a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch03s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.tpiprotocol.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.tpiprotocol.html
new file mode 100644
index 000000000..442c2b337
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/protocoldocs.tpiprotocol.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>TPI Protocol - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="prev" href="ch07s03.html" title="ID definitions" /><link rel="next" href="ch08s01.html" title="TPI protocol commands" /><meta content="TPI Protocol" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />TPI Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch07s03.html">Prev</a>&nbsp;
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch08s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="chapter"><div xmlns="" class="titlepage"><div><div><h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="protocoldocs.tpiprotocol" />TPI Protocol</h1></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch08s01.html">TPI protocol commands</a></span></dt><dt><span class="section"><a href="ch08s02.html">TPI programming protocol responses</a></span></dt><dt><span class="section"><a href="ch08s03.html">ID definitions</a></span></dt></dl></div><p>The TPI protocol is based upon the communication protocol used by STK600 and
+ AVRISP mkII. In those tools it is used for programming tinyAVR using TPI interface as well
+ as AVR XMEGA devices using PDI and/or JTAG. This implementation supports only programming of
+ tinyAVR devices using the TPI interface.</p><p>All multi-byte values (e.g. address and length fields) are big endian.</p><p>The protocol commands are put in the payload of EDBG commands with the handler set to TPIPROTOCOL. The responses are also sent as the payload of EDBG commands.</p><p>Note that the TPIPROTOCOL has no CMD_ACTIVATE_PHYSICAL. The ENTER_PROGMODE command will
+ enable the physical and LEAVE_PROGMODE will deactivate it.</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch07s03.html">Prev</a>&nbsp;</td><td align="center" width="20%">&nbsp;</td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch08s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/htmlFileInfoList.js b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/htmlFileInfoList.js
new file mode 100644
index 000000000..d1d8fbc2c
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/htmlFileInfoList.js
@@ -0,0 +1,392 @@
+var doStem = true;
+//List of indexed files.
+fl = new Array();
+fl["0"]= "ch01s01.html";
+fl["1"]= "ch01s02.html";
+fl["2"]= "ch02s01.html";
+fl["3"]= "ch02s02.html";
+fl["4"]= "ch02s02s01.html";
+fl["5"]= "ch02s02s02.html";
+fl["6"]= "ch02s02s02s01.html";
+fl["7"]= "ch02s02s02s02.html";
+fl["8"]= "ch02s02s03.html";
+fl["9"]= "ch02s02s03s01.html";
+fl["10"]= "ch02s02s03s02.html";
+fl["11"]= "ch02s02s03s03.html";
+fl["12"]= "ch02s02s03s04.html";
+fl["13"]= "ch02s03s01.html";
+fl["14"]= "ch02s03s02.html";
+fl["15"]= "ch02s03s03.html";
+fl["16"]= "ch02s03s04.html";
+fl["17"]= "ch02s03s05.html";
+fl["18"]= "ch02s03s06.html";
+fl["19"]= "ch02s03s07.html";
+fl["20"]= "ch02s03s08.html";
+fl["21"]= "ch02s03s09.html";
+fl["22"]= "ch02s04.html";
+fl["23"]= "ch02s04s01.html";
+fl["24"]= "ch02s04s02.html";
+fl["25"]= "ch02s04s03.html";
+fl["26"]= "ch03s01.html";
+fl["27"]= "ch03s01s01.html";
+fl["28"]= "ch03s01s02.html";
+fl["29"]= "ch03s01s03.html";
+fl["30"]= "ch03s01s03s01.html";
+fl["31"]= "ch03s02.html";
+fl["32"]= "ch03s02s01.html";
+fl["33"]= "ch03s02s02.html";
+fl["34"]= "ch03s02s03.html";
+fl["35"]= "ch03s02s04.html";
+fl["36"]= "ch04s01.html";
+fl["37"]= "ch04s02.html";
+fl["38"]= "ch04s03.html";
+fl["39"]= "ch04s04.html";
+fl["40"]= "ch04s04s01.html";
+fl["41"]= "ch04s04s03.html";
+fl["42"]= "ch04s04s04.html";
+fl["43"]= "ch04s04s05.html";
+fl["44"]= "ch04s05.html";
+fl["45"]= "ch04s05s01.html";
+fl["46"]= "ch04s05s03.html";
+fl["47"]= "ch04s05s04.html";
+fl["48"]= "ch04s05s06.html";
+fl["49"]= "ch04s05s06s02.html";
+fl["50"]= "ch04s05s06s03.html";
+fl["51"]= "ch04s05s06s04.html";
+fl["52"]= "ch04s05s06s05.html";
+fl["53"]= "ch04s05s07.html";
+fl["54"]= "ch04s05s07s01.html";
+fl["55"]= "ch04s05s07s02.html";
+fl["56"]= "ch04s05s07s03.html";
+fl["57"]= "ch04s05s07s04.html";
+fl["58"]= "ch04s05s08.html";
+fl["59"]= "ch04s05s08s01.html";
+fl["60"]= "ch04s05s08s02.html";
+fl["61"]= "ch04s05s08s03.html";
+fl["62"]= "ch04s05s09.html";
+fl["63"]= "ch04s05s10.html";
+fl["64"]= "ch05s01.html";
+fl["65"]= "ch05s01s01.html";
+fl["66"]= "ch05s01s02.html";
+fl["67"]= "ch05s01s03.html";
+fl["68"]= "ch05s01s04.html";
+fl["69"]= "ch05s01s05.html";
+fl["70"]= "ch05s01s06.html";
+fl["71"]= "ch05s01s07.html";
+fl["72"]= "ch05s01s08.html";
+fl["73"]= "ch05s01s09.html";
+fl["74"]= "ch05s01s10.html";
+fl["75"]= "ch05s01s11.html";
+fl["76"]= "ch05s01s12.html";
+fl["77"]= "ch05s01s13.html";
+fl["78"]= "ch05s01s14.html";
+fl["79"]= "ch05s01s15.html";
+fl["80"]= "ch05s02.html";
+fl["81"]= "ch05s02s01.html";
+fl["82"]= "ch05s02s02.html";
+fl["83"]= "ch05s02s03.html";
+fl["84"]= "ch05s02s04.html";
+fl["85"]= "ch05s02s05.html";
+fl["86"]= "ch05s02s06.html";
+fl["87"]= "ch05s03.html";
+fl["88"]= "ch05s03s01.html";
+fl["89"]= "ch05s03s02.html";
+fl["90"]= "ch05s03s03.html";
+fl["91"]= "ch05s04.html";
+fl["92"]= "ch06s01.html";
+fl["93"]= "ch06s01s01.html";
+fl["94"]= "ch06s01s02.html";
+fl["95"]= "ch06s01s03.html";
+fl["96"]= "ch06s01s04.html";
+fl["97"]= "ch06s01s05.html";
+fl["98"]= "ch06s01s06.html";
+fl["99"]= "ch06s01s07.html";
+fl["100"]= "ch06s01s08.html";
+fl["101"]= "ch06s01s09.html";
+fl["102"]= "ch06s01s10.html";
+fl["103"]= "ch06s01s11.html";
+fl["104"]= "ch06s01s12.html";
+fl["105"]= "ch06s01s13.html";
+fl["106"]= "ch06s01s14.html";
+fl["107"]= "ch06s01s15.html";
+fl["108"]= "ch06s01s16.html";
+fl["109"]= "ch06s01s17.html";
+fl["110"]= "ch06s01s18.html";
+fl["111"]= "ch06s01s19.html";
+fl["112"]= "ch06s01s20.html";
+fl["113"]= "ch06s01s21.html";
+fl["114"]= "ch06s01s22.html";
+fl["115"]= "ch06s01s23.html";
+fl["116"]= "ch06s01s24.html";
+fl["117"]= "ch06s01s25.html";
+fl["118"]= "ch06s01s26.html";
+fl["119"]= "ch06s01s27.html";
+fl["120"]= "ch06s01s28.html";
+fl["121"]= "ch06s01s29.html";
+fl["122"]= "ch06s02.html";
+fl["123"]= "ch06s02s01.html";
+fl["124"]= "ch06s02s02.html";
+fl["125"]= "ch06s02s03.html";
+fl["126"]= "ch06s02s04.html";
+fl["127"]= "ch06s02s05.html";
+fl["128"]= "ch06s03.html";
+fl["129"]= "ch06s03s01.html";
+fl["130"]= "ch06s03s02.html";
+fl["131"]= "ch06s04s01.html";
+fl["132"]= "ch06s04s02.html";
+fl["133"]= "ch06s04s03.html";
+fl["134"]= "ch06s05.html";
+fl["135"]= "ch06s05s01.html";
+fl["136"]= "ch06s05s02.html";
+fl["137"]= "ch06s05s03.html";
+fl["138"]= "ch06s05s04.html";
+fl["139"]= "ch06s05s05.html";
+fl["140"]= "ch06s06.html";
+fl["141"]= "ch07s01.html";
+fl["142"]= "ch07s01s01.html";
+fl["143"]= "ch07s01s02.html";
+fl["144"]= "ch07s01s03.html";
+fl["145"]= "ch07s01s04.html";
+fl["146"]= "ch07s01s05.html";
+fl["147"]= "ch07s01s06.html";
+fl["148"]= "ch07s01s07.html";
+fl["149"]= "ch07s01s08.html";
+fl["150"]= "ch07s01s09.html";
+fl["151"]= "ch07s01s10.html";
+fl["152"]= "ch07s01s11.html";
+fl["153"]= "ch07s01s12.html";
+fl["154"]= "ch07s01s13.html";
+fl["155"]= "ch07s01s14.html";
+fl["156"]= "ch07s01s15.html";
+fl["157"]= "ch07s01s16.html";
+fl["158"]= "ch07s01s17.html";
+fl["159"]= "ch07s02.html";
+fl["160"]= "ch07s03.html";
+fl["161"]= "ch08s01.html";
+fl["162"]= "ch08s01s01.html";
+fl["163"]= "ch08s01s02.html";
+fl["164"]= "ch08s01s03.html";
+fl["165"]= "ch08s01s04.html";
+fl["166"]= "ch08s01s05.html";
+fl["167"]= "ch08s01s06.html";
+fl["168"]= "ch08s02.html";
+fl["169"]= "ch08s03.html";
+fl["170"]= "document.revisions.html";
+fl["171"]= "index.html";
+fl["172"]= "pr01.html";
+fl["173"]= "protocoldocs.avr32protocol.html";
+fl["174"]= "protocoldocs.avr8protocol.html";
+fl["175"]= "protocoldocs.avrispprotocol.html";
+fl["176"]= "protocoldocs.avrprotocol.Overview.html";
+fl["177"]= "protocoldocs.cmsis_dap.html";
+fl["178"]= "protocoldocs.edbg_ctrl_protocol.html";
+fl["179"]= "protocoldocs.Introduction.html";
+fl["180"]= "protocoldocs.tpiprotocol.html";
+fl["181"]= "section_avr32_memtypes.html";
+fl["182"]= "section_avr32_setget_params.html";
+fl["183"]= "section_avr8_memtypes.html";
+fl["184"]= "section_avr8_query_contexts.html";
+fl["185"]= "section_avr8_setget_params.html";
+fl["186"]= "section_edbg_ctrl_setget_params.html";
+fl["187"]= "section_edbg_query_contexts.html";
+fl["188"]= "section_housekeeping_start_session.html";
+fl["189"]= "section_i5v_3yz_rl.html";
+fl["190"]= "section_jdx_m11_sl.html";
+fl["191"]= "section_qhb_x1c_sl.html";
+fl["192"]= "section_serial_trace.html";
+fl["193"]= "section_t1f_hb1_sl.html";
+fil = new Array();
+fil["0"]= "ch01s01.html@@@EDBG interface overview@@@null";
+fil["1"]= "ch01s02.html@@@Atmel EDBG-based tool implementations@@@null";
+fil["2"]= "ch02s01.html@@@CMSIS-DAP protocol@@@null";
+fil["3"]= "ch02s02.html@@@CMSIS-DAP vendor commands@@@null";
+fil["4"]= "ch02s02s01.html@@@AVR-target specific vendor commands@@@null";
+fil["5"]= "ch02s02s02.html@@@ARM-target specific vendor commands@@@null";
+fil["6"]= "ch02s02s02s01.html@@@Erase pin@@@null";
+fil["7"]= "ch02s02s02s02.html@@@Serial trace@@@null";
+fil["8"]= "ch02s02s03.html@@@EDBG-specific vendor commands@@@null";
+fil["9"]= "ch02s02s03s01.html@@@Get configuration@@@null";
+fil["10"]= "ch02s02s03s02.html@@@Set configuration@@@null";
+fil["11"]= "ch02s02s03s03.html@@@EDBG GET request@@@null";
+fil["12"]= "ch02s02s03s04.html@@@EDBG SET request@@@null";
+fil["13"]= "ch02s03s01.html@@@Set transport mode@@@null";
+fil["14"]= "ch02s03s02.html@@@Set capture mode@@@null";
+fil["15"]= "ch02s03s03.html@@@Set baud rate@@@null";
+fil["16"]= "ch02s03s04.html@@@Start@@@null";
+fil["17"]= "ch02s03s05.html@@@Stop@@@null";
+fil["18"]= "ch02s03s06.html@@@Get data@@@null";
+fil["19"]= "ch02s03s07.html@@@Get status@@@null";
+fil["20"]= "ch02s03s08.html@@@Get buffer size@@@null";
+fil["21"]= "ch02s03s09.html@@@Signon@@@null";
+fil["22"]= "ch02s04.html@@@Enveloped AVR commands, responses & events@@@null";
+fil["23"]= "ch02s04s01.html@@@Wrapping AVR commands@@@null";
+fil["24"]= "ch02s04s02.html@@@Unwrapping AVR responses@@@null";
+fil["25"]= "ch02s04s03.html@@@Unwrapping AVR events@@@null";
+fil["26"]= "ch03s01.html@@@Protocol commands@@@null";
+fil["27"]= "ch03s01s01.html@@@QUERY@@@null";
+fil["28"]= "ch03s01s02.html@@@SET@@@null";
+fil["29"]= "ch03s01s03.html@@@GET@@@null";
+fil["30"]= "ch03s01s03s01.html@@@SET/GET parameters@@@null";
+fil["31"]= "ch03s02.html@@@Responses@@@null";
+fil["32"]= "ch03s02s01.html@@@OK@@@null";
+fil["33"]= "ch03s02s02.html@@@LIST@@@null";
+fil["34"]= "ch03s02s03.html@@@DATA@@@null";
+fil["35"]= "ch03s02s04.html@@@FAILED@@@null";
+fil["36"]= "ch04s01.html@@@Overview@@@null";
+fil["37"]= "ch04s02.html@@@Framing@@@null";
+fil["38"]= "ch04s03.html@@@Protocol sub-set overview@@@null";
+fil["39"]= "ch04s04.html@@@Discovery Protocol Definition@@@null";
+fil["40"]= "ch04s04s01.html@@@CMD: QUERY@@@null";
+fil["41"]= "ch04s04s03.html@@@RSP: LIST@@@null";
+fil["42"]= "ch04s04s04.html@@@RSP: FAILED@@@null";
+fil["43"]= "ch04s04s05.html@@@Discovery Protocol ID definitions@@@null";
+fil["44"]= "ch04s05.html@@@Housekeeping Protocol@@@null";
+fil["45"]= "ch04s05s01.html@@@CMD: QUERY@@@null";
+fil["46"]= "ch04s05s03.html@@@CMD: SET@@@null";
+fil["47"]= "ch04s05s04.html@@@CMD: GET@@@null";
+fil["48"]= "ch04s05s06.html@@@Housekeeping Commands@@@null";
+fil["49"]= "ch04s05s06s02.html@@@End Session@@@null";
+fil["50"]= "ch04s05s06s03.html@@@Firmware Upgrade@@@null";
+fil["51"]= "ch04s05s06s04.html@@@JTAG scan-chain detection@@@null";
+fil["52"]= "ch04s05s06s05.html@@@Calibrate Oscillator@@@null";
+fil["53"]= "ch04s05s07.html@@@Housekeeping Responses@@@null";
+fil["54"]= "ch04s05s07s01.html@@@OK@@@null";
+fil["55"]= "ch04s05s07s02.html@@@LIST@@@null";
+fil["56"]= "ch04s05s07s03.html@@@DATA@@@null";
+fil["57"]= "ch04s05s07s04.html@@@FAILED@@@null";
+fil["58"]= "ch04s05s08.html@@@Events@@@null";
+fil["59"]= "ch04s05s08s01.html@@@Event: power@@@null";
+fil["60"]= "ch04s05s08s02.html@@@Event: sleep@@@null";
+fil["61"]= "ch04s05s08s03.html@@@Event: external reset@@@null";
+fil["62"]= "ch04s05s09.html@@@Hints and tips@@@null";
+fil["63"]= "ch04s05s10.html@@@Housekeeping ID definitions@@@null";
+fil["64"]= "ch05s01.html@@@Protocol commands@@@null";
+fil["65"]= "ch05s01s01.html@@@QUERY@@@null";
+fil["66"]= "ch05s01s02.html@@@SET@@@null";
+fil["67"]= "ch05s01s03.html@@@GET@@@null";
+fil["68"]= "ch05s01s04.html@@@Activate Physical@@@null";
+fil["69"]= "ch05s01s05.html@@@Deactivate Physical@@@null";
+fil["70"]= "ch05s01s06.html@@@Get ID@@@null";
+fil["71"]= "ch05s01s07.html@@@Erase@@@null";
+fil["72"]= "ch05s01s08.html@@@Halt@@@null";
+fil["73"]= "ch05s01s09.html@@@Reset@@@null";
+fil["74"]= "ch05s01s10.html@@@Step@@@null";
+fil["75"]= "ch05s01s11.html@@@Read@@@null";
+fil["76"]= "ch05s01s12.html@@@Write@@@null";
+fil["77"]= "ch05s01s13.html@@@TAP@@@null";
+fil["78"]= "ch05s01s14.html@@@Is protected@@@null";
+fil["79"]= "ch05s01s15.html@@@Erase Section@@@null";
+fil["80"]= "ch05s02.html@@@Responses@@@null";
+fil["81"]= "ch05s02s01.html@@@OK@@@null";
+fil["82"]= "ch05s02s02.html@@@LIST@@@null";
+fil["83"]= "ch05s02s03.html@@@ID@@@null";
+fil["84"]= "ch05s02s04.html@@@PC@@@null";
+fil["85"]= "ch05s02s05.html@@@DATA@@@null";
+fil["86"]= "ch05s02s06.html@@@FAILED@@@null";
+fil["87"]= "ch05s03.html@@@Hints and tips@@@null";
+fil["88"]= "ch05s03s01.html@@@Configuration@@@null";
+fil["89"]= "ch05s03s02.html@@@Activate and deactivate physical@@@null";
+fil["90"]= "ch05s03s03.html@@@Programming and debugging commands@@@null";
+fil["91"]= "ch05s04.html@@@AVR32GENERIC ID definitions@@@null";
+fil["92"]= "ch06s01.html@@@Protocol Commands@@@null";
+fil["93"]= "ch06s01s01.html@@@QUERY@@@null";
+fil["94"]= "ch06s01s02.html@@@SET@@@null";
+fil["95"]= "ch06s01s03.html@@@GET@@@null";
+fil["96"]= "ch06s01s04.html@@@Activate Physical@@@null";
+fil["97"]= "ch06s01s05.html@@@Deactivate Physical@@@null";
+fil["98"]= "ch06s01s06.html@@@Get ID@@@null";
+fil["99"]= "ch06s01s07.html@@@Attach@@@null";
+fil["100"]= "ch06s01s08.html@@@Detach@@@null";
+fil["101"]= "ch06s01s09.html@@@Reset@@@null";
+fil["102"]= "ch06s01s10.html@@@Stop@@@null";
+fil["103"]= "ch06s01s11.html@@@Run@@@null";
+fil["104"]= "ch06s01s12.html@@@Run To@@@null";
+fil["105"]= "ch06s01s13.html@@@Step@@@null";
+fil["106"]= "ch06s01s14.html@@@PC read@@@null";
+fil["107"]= "ch06s01s15.html@@@PC write@@@null";
+fil["108"]= "ch06s01s16.html@@@Prog Mode Enter@@@null";
+fil["109"]= "ch06s01s17.html@@@Prog Mode Leave@@@null";
+fil["110"]= "ch06s01s18.html@@@Disable debugWIRE@@@null";
+fil["111"]= "ch06s01s19.html@@@Erase@@@null";
+fil["112"]= "ch06s01s20.html@@@CRC@@@null";
+fil["113"]= "ch06s01s21.html@@@Memory Read@@@null";
+fil["114"]= "ch06s01s22.html@@@Memory Read masked@@@null";
+fil["115"]= "ch06s01s23.html@@@Memory Write@@@null";
+fil["116"]= "ch06s01s24.html@@@Page Erase@@@null";
+fil["117"]= "ch06s01s25.html@@@Hardware Breakpoint Set@@@null";
+fil["118"]= "ch06s01s26.html@@@Hardware Breakpoint Clear@@@null";
+fil["119"]= "ch06s01s27.html@@@Software Breakpoint Set@@@null";
+fil["120"]= "ch06s01s28.html@@@Software Breakpoint Clear@@@null";
+fil["121"]= "ch06s01s29.html@@@Software Breakpoint Clear All@@@null";
+fil["122"]= "ch06s02.html@@@Responses@@@null";
+fil["123"]= "ch06s02s01.html@@@OK@@@null";
+fil["124"]= "ch06s02s02.html@@@LIST@@@null";
+fil["125"]= "ch06s02s03.html@@@PC@@@null";
+fil["126"]= "ch06s02s04.html@@@DATA@@@null";
+fil["127"]= "ch06s02s05.html@@@FAILED@@@null";
+fil["128"]= "ch06s03.html@@@Events@@@null";
+fil["129"]= "ch06s03s01.html@@@Event: Break@@@null";
+fil["130"]= "ch06s03s02.html@@@Event: IDR message@@@null";
+fil["131"]= "ch06s04s01.html@@@debugWIRE memtypes@@@null";
+fil["132"]= "ch06s04s02.html@@@megaAVR (JTAG) OCD memtypes@@@null";
+fil["133"]= "ch06s04s03.html@@@AVR XMEGA memtypes@@@null";
+fil["134"]= "ch06s05.html@@@Hints and tips:@@@null";
+fil["135"]= "ch06s05s01.html@@@Configuration@@@null";
+fil["136"]= "ch06s05s02.html@@@Activate and deactivate physical@@@null";
+fil["137"]= "ch06s05s03.html@@@Programming session control@@@null";
+fil["138"]= "ch06s05s04.html@@@Debug session control@@@null";
+fil["139"]= "ch06s05s05.html@@@Flow control@@@null";
+fil["140"]= "ch06s06.html@@@AVR8GENERIC ID definitions@@@null";
+fil["141"]= "ch07s01.html@@@SPI programming protocol commands@@@null";
+fil["142"]= "ch07s01s01.html@@@SPI Load Address@@@null";
+fil["143"]= "ch07s01s02.html@@@SPI Set Baud@@@null";
+fil["144"]= "ch07s01s03.html@@@SPI Get Baud@@@null";
+fil["145"]= "ch07s01s04.html@@@SPI Enter Programming Mode@@@null";
+fil["146"]= "ch07s01s05.html@@@SPI Leave Programming Mode@@@null";
+fil["147"]= "ch07s01s06.html@@@SPI Chip Erase@@@null";
+fil["148"]= "ch07s01s07.html@@@SPI Program Flash@@@null";
+fil["149"]= "ch07s01s08.html@@@SPI Read Flash@@@null";
+fil["150"]= "ch07s01s09.html@@@SPI Program EEPROM@@@null";
+fil["151"]= "ch07s01s10.html@@@SPI Read EEPROM@@@null";
+fil["152"]= "ch07s01s11.html@@@SPI Program Fuse@@@null";
+fil["153"]= "ch07s01s12.html@@@SPI Read Fuse@@@null";
+fil["154"]= "ch07s01s13.html@@@SPI Program Lock@@@null";
+fil["155"]= "ch07s01s14.html@@@SPI Read Lock@@@null";
+fil["156"]= "ch07s01s15.html@@@SPI Read Signature@@@null";
+fil["157"]= "ch07s01s16.html@@@SPI Read OSCCAL@@@null";
+fil["158"]= "ch07s01s17.html@@@SPI Multi@@@null";
+fil["159"]= "ch07s02.html@@@SPI programming protocol responses@@@null";
+fil["160"]= "ch07s03.html@@@ID definitions@@@null";
+fil["161"]= "ch08s01.html@@@TPI protocol commands@@@null";
+fil["162"]= "ch08s01s01.html@@@TPI Enter Programming Mode@@@null";
+fil["163"]= "ch08s01s02.html@@@TPI Leave Programming Mode@@@null";
+fil["164"]= "ch08s01s03.html@@@TPI Set Parameter@@@null";
+fil["165"]= "ch08s01s04.html@@@TPI Erase@@@null";
+fil["166"]= "ch08s01s05.html@@@TPI Write Memory@@@null";
+fil["167"]= "ch08s01s06.html@@@TPI Read Memory@@@null";
+fil["168"]= "ch08s02.html@@@TPI programming protocol responses@@@null";
+fil["169"]= "ch08s03.html@@@ID definitions@@@null";
+fil["170"]= "document.revisions.html@@@Document Revisions@@@null";
+fil["171"]= "index.html@@@Atmel EDBG-based Tools Protocols@@@null";
+fil["172"]= "pr01.html@@@Preface@@@null";
+fil["173"]= "protocoldocs.avr32protocol.html@@@AVR32 generic protocol@@@null";
+fil["174"]= "protocoldocs.avr8protocol.html@@@AVR8 generic protocol@@@null";
+fil["175"]= "protocoldocs.avrispprotocol.html@@@AVR ISP protocol@@@null";
+fil["176"]= "protocoldocs.avrprotocol.Overview.html@@@AVR communication protocol@@@null";
+fil["177"]= "protocoldocs.cmsis_dap.html@@@CMSIS-DAP@@@null";
+fil["178"]= "protocoldocs.edbg_ctrl_protocol.html@@@EDBG Control Protocol@@@null";
+fil["179"]= "protocoldocs.Introduction.html@@@Introduction@@@null";
+fil["180"]= "protocoldocs.tpiprotocol.html@@@TPI Protocol@@@null";
+fil["181"]= "section_avr32_memtypes.html@@@Memory Types@@@null";
+fil["182"]= "section_avr32_setget_params.html@@@SET/GET parameters@@@null";
+fil["183"]= "section_avr8_memtypes.html@@@Memory Types@@@null";
+fil["184"]= "section_avr8_query_contexts.html@@@AVR8 QUERY contexts@@@null";
+fil["185"]= "section_avr8_setget_params.html@@@SET/GET parameters@@@null";
+fil["186"]= "section_edbg_ctrl_setget_params.html@@@EDBGCTRL ID definitions@@@null";
+fil["187"]= "section_edbg_query_contexts.html@@@EDBG QUERY contexts@@@null";
+fil["188"]= "section_housekeeping_start_session.html@@@Start session@@@null";
+fil["189"]= "section_i5v_3yz_rl.html@@@Housekeeping QUERY contexts@@@null";
+fil["190"]= "section_jdx_m11_sl.html@@@Discovery QUERY contexts@@@null";
+fil["191"]= "section_qhb_x1c_sl.html@@@AVR32 QUERY contexts@@@null";
+fil["192"]= "section_serial_trace.html@@@Serial trace commands@@@null";
+fil["193"]= "section_t1f_hb1_sl.html@@@Housekeeping SET/GET parameters@@@null";
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-1.js b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-1.js
new file mode 100644
index 000000000..c708ea8c9
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-1.js
@@ -0,0 +1,851 @@
+var indexerLanguage="en";
+//Auto generated index for searching by xsl-webhelpindexer for DocBook Webhelp.# Kasun Gajasinghe, University of Moratuwa
+w["-"]="0*2,1*2,2*2,3*2,4*2,5*2,6*2,7*2,8*2,9*2,10*2,11*2,12*2,13*2,14*2,15*2,16*2,17*2,18*2,19*2,20*2,21*2,22*2,23*2,24*2,25*2,26*2,27*2,28*2,29*2,30*2,31*2,32*2,33*2,34*2,35*2,36*2,37*2,38*2,39*2,40*2,41*2,42*2,43*2,44*2,45*2,46*2,47*2,48*2,49*2,50*2,51*2,52*2,53*2,54*2,55*2,56*2,57*2,58*2,59*2,60*2,61*2,62*2,63*2,64*2,65*2,66*2,67*2,68*2,69*2,70*3,71*2,72*2,73*2,74*2,75*2,76*2,77*2,78*2,79*2,80*2,81*2,82*2,83*2,84*2,85*2,86*2,87*2,88*2,89*2,90*2,91*2,92*2,93*2,94*2,95*2,96*2,97*2,98*2,99*2,100*2,101*2,102*2,103*2,104*2,105*2,106*2,107*2,108*2,109*2,110*2,111*4,112*2,113*2,114*2,115*2,116*2,117*2,118*2,119*2,120*2,121*2,122*2,123*2,124*2,125*2,126*2,127*2,128*2,129*2,130*2,131*8,132*12,133*7,134*2,135*2,136*2,137*2,138*2,139*2,140*2,141*2,142*2,143*2,144*2,145*2,146*2,147*2,148*2,149*2,150*2,151*2,152*2,153*2,154*2,155*2,156*2,157*2,158*2,159*2,160*2,161*2,162*2,163*2,164*2,165*2,166*3,167*2,168*2,169*2,170*2,171*1,173*2,174*2,175*2,176*2,177*2,178*2,179*2,180*2,181*2,182*2,183*2,184*2,185*2,186*2,187*2,188*2,189*2,190*2,191*2,192*2,193*2";
+w["-board"]="172*1";
+w["-chip"]="1*2";
+w["."]="22*1,30*1,37*3,52*1,62*1,77*2,96*1,109*1,119*1,120*1,131*4,132*3,133*12,135*1,139*2,148*2,171*1,172*1,174*1,175*1,180*1";
+w[".e."]="173*2";
+w["0"]="21*1,34*5,49*1,51*1,56*6,85*5,91*3,114*1,119*1,120*1,126*5,132*1,140*3,145*1,147*1,148*3,169*1,173*1,181*1,182*1,185*1,186*1";
+w["0-6"]="148*1";
+w["0."]="132*1";
+w["00"]="136*2";
+w["01"]="78*1,170*1";
+w["05"]="136*1";
+w["09"]="136*2,170*1";
+w["09.10.2013"]="170*1";
+w["0:"]="18*1";
+w["0x00"]="6*1,9*1,10*1,13*4,14*2,16*1,17*1,23*1,24*2,27*2,28*1,29*1,30*3,32*1,33*1,34*1,35*1,37*6,38*1,40*2,41*1,42*1,43*3,45*2,46*1,47*1,49*1,50*1,51*1,52*1,54*1,55*1,56*1,57*1,59*2,60*2,61*2,63*10,65*2,66*1,67*1,68*2,69*1,71*1,72*2,73*1,74*1,75*1,76*1,77*1,78*1,79*1,81*1,82*1,83*1,84*1,85*2,86*1,91*8,93*2,94*1,95*1,96*2,97*1,98*1,99*2,100*1,101*1,102*1,103*1,104*1,105*2,106*1,107*1,108*1,109*1,110*1,111*2,112*2,113*1,114*1,115*2,116*1,117*1,118*1,119*1,120*1,121*1,123*1,124*1,125*1,126*1,127*1,129*2,130*1,131*1,133*1,140*14,160*1,182*2,185*4,186*10,188*1";
+w["0x00."]="131*1";
+w["0x0000"]="25*1";
+w["0x000000"]="133*12";
+w["0x00:"]="6*1,9*1,10*1,13*2,14*2,16*1,17*1,23*1,24*1,30*3,68*1,72*1,96*1,105*1";
+w["0x01"]="6*1,13*1,14*2,23*1,24*1,28*1,30*3,34*1,38*1,46*1,56*1,59*1,60*1,61*1,63*6,66*1,68*1,72*1,85*1,91*5,94*1,96*1,99*1,101*1,102*1,105*2,111*1,112*1,115*1,117*1,126*1,129*1,140*10,169*1,182*3,185*1,186*7";
+w["0x01:"]="6*1,13*1,23*1,24*1,30*3,68*1,72*1,96*1,101*1,102*1,105*2,117*1,182*2";
+w["0x02"]="14*1,15*2,29*1,47*1,63*2,67*1,91*4,95*1,101*1,102*1,105*2,111*1,112*1,132*2,140*5,169*1,185*2,186*5";
+w["0x02:"]="14*1,101*1,102*1,105*2";
+w["0x03"]="16*2,63*1,91*4,111*1,112*1,117*1,132*1,140*4,169*2,186*3";
+w["0x03:"]="117*1";
+w["0x04"]="17*2,91*5,111*1,140*4,169*2,182*1,185*1,186*2";
+w["0x05"]="91*3,111*1,140*3,169*1,186*1";
+w["0x06"]="91*3,111*1,140*2,160*1,185*2,186*1";
+w["0x07"]="91*3,111*1,140*2,169*1,182*1,186*1";
+w["0x08"]="18*2,91*2,140*1,185*1,186*2";
+w["0x09"]="19*2,91*1,186*2";
+w["0x0a"]="20*2,91*2,185*2,186*2";
+w["0x0b"]="91*2,186*1";
+w["0x0c"]="91*2,185*1,186*1";
+w["0x0d"]="91*1,186*1";
+w["0x0e"]="37*3,91*1,185*2,186*1";
+w["0x0f"]="21*2,91*1,186*2";
+w["0x10"]="43*1,63*4,91*3,140*3,160*1,185*3,186*5";
+w["0x11"]="38*1,63*4,91*2,140*2,160*1,186*3";
+w["0x12"]="38*1,63*2,91*2,140*2,160*1,185*2,186*2";
+w["0x13"]="38*1,63*1,91*2,140*2,160*1,185*2,186*2";
+w["0x14"]="38*1,91*2,140*2,160*1,185*1,186*2";
+w["0x15"]="91*2,140*2,160*1,186*2";
+w["0x16"]="91*2,140*2,160*1,186*2";
+w["0x17"]="91*2,140*2,160*1,186*2";
+w["0x18"]="91*2,140*1,160*1,185*3,186*1";
+w["0x19"]="91*2,140*1,160*1,185*2,186*1";
+w["0x1a"]="91*1,140*1,160*1,185*2";
+w["0x1b"]="91*1,140*1,160*1,185*2";
+w["0x1c"]="160*1,185*3";
+w["0x1d"]="91*1,160*1,185*2";
+w["0x1e"]="91*1,131*1,160*1,185*2";
+w["0x1e."]="131*1";
+w["0x1f"]="91*1";
+w["0x20"]="38*1,63*1,91*1,140*4,185*1,186*3";
+w["0x21"]="63*1,91*1,140*3";
+w["0x2111"]="1*1";
+w["0x2140"]="1*1";
+w["0x2141"]="1*1";
+w["0x2145"]="1*1";
+w["0x22"]="63*1,91*1,140*3";
+w["0x23"]="63*1,91*1,140*2";
+w["0x24"]="91*2,140*1,185*1";
+w["0x25"]="91*1";
+w["0x26"]="91*1,185*1";
+w["0x28"]="185*1";
+w["0x29"]="91*1";
+w["0x2a"]="91*1,185*1";
+w["0x2b"]="91*1,185*1";
+w["0x2c"]="91*1";
+w["0x2d"]="91*1,185*1";
+w["0x2e"]="91*1";
+w["0x2f"]="91*1";
+w["0x30"]="63*2,91*1,140*2,186*1";
+w["0x31"]="63*2,91*1,140*3";
+w["0x32"]="63*1,91*1,140*2";
+w["0x33"]="63*1,91*1,140*2";
+w["0x34"]="140*2";
+w["0x35"]="140*2";
+w["0x36"]="140*2";
+w["0x37"]="140*1";
+w["0x38"]="63*1,140*1";
+w["0x39"]="140*1";
+w["0x3a"]="140*1";
+w["0x3b"]="140*1";
+w["0x3c"]="140*1";
+w["0x3d"]="140*1";
+w["0x40"]="63*1,140*3";
+w["0x41"]="63*1,140*3";
+w["0x42"]="63*1,140*1";
+w["0x43"]="63*1,140*2";
+w["0x44"]="140*2";
+w["0x45"]="140*1";
+w["0x50"]="63*1,140*2";
+w["0x53"]="145*1";
+w["0x60"]="140*1";
+w["0x61"]="140*1";
+w["0x70"]="140*1";
+w["0x71"]="140*1";
+w["0x72"]="140*1";
+w["0x80"]="3*1,4*1,23*2,43*1,63*1,91*3,140*2,160*1,186*1";
+w["0x81"]="3*1,4*1,24*2,43*2,63*1,91*2,140*2,160*1,186*1";
+w["0x82"]="3*1,4*1,25*2,43*1,91*3";
+w["0x83"]="3*1,9*2,91*2,140*1";
+w["0x84"]="3*1,10*2,63*1,91*2,140*1,186*1";
+w["0x85"]="3*1,91*1";
+w["0x86"]="3*1,6*2";
+w["0x87"]="3*1,13*2,14*2,15*2,16*2,17*2,18*2,19*2,20*2,21*2,192*1";
+w["0x88"]="3*1";
+w["0x89"]="3*1";
+w["0x90"]="91*1,140*1";
+w["0x91"]="91*1,140*1";
+w["0x92"]="91*1";
+w["0x93"]="91*1";
+w["0xa0"]="43*1,63*1,91*1,140*2,186*1";
+w["0xa1"]="63*1";
+w["0xb0"]="140*1";
+w["0xb1"]="140*1";
+w["0xb2"]="140*1";
+w["0xb3"]="140*1";
+w["0xb4"]="140*1";
+w["0xb5"]="140*1";
+w["0xb8"]="140*1";
+w["0xc0"]="140*1,160*1";
+w["0xc1"]="140*1";
+w["0xc2"]="140*1";
+w["0xc3"]="140*1";
+w["0xc4"]="140*1";
+w["0xc5"]="140*1";
+w["0xc6"]="140*1";
+w["0xc9"]="160*1";
+w["0xcb"]="160*1";
+w["0xcc"]="160*1";
+w["0xcd"]="160*1";
+w["0xe0"]="43*1";
+w["0xfe"]="91*1";
+w["0xff"]="13*1,14*1,16*1,17*1,35*1,42*1,43*1,57*1,86*1,91*1,127*1,140*2,186*1";
+w["0xff:"]="13*1,14*1,16*1,17*1";
+w["1"]="6*3,9*8,10*5,13*6,14*6,15*4,16*5,17*5,18*4,19*6,20*4,21*4,23*4,24*3,25*2,27*3,28*5,29*5,30*3,32*2,33*2,34*3,35*3,37*8,40*3,41*2,42*3,45*3,46*5,47*5,49*3,50*2,51*4,52*2,54*2,55*2,56*3,57*3,59*3,60*3,61*3,65*3,66*5,67*5,68*3,69*2,70*2,71*2,72*3,73*3,74*2,75*3,76*3,77*4,78*2,79*4,81*2,82*2,83*2,84*2,85*10,86*3,93*3,94*5,95*5,96*3,97*2,98*2,99*3,100*2,101*3,102*3,103*2,104*2,105*4,106*2,107*2,108*2,109*2,110*2,111*3,112*3,113*3,114*5,115*4,116*2,117*6,118*4,119*2,120*2,121*2,123*2,124*2,125*2,126*3,127*3,129*3,130*3,142*3,143*3,144*3,145*15,146*5,147*11,148*15,149*7,152*8,153*11,162*3,163*3,164*5,165*4,166*6,167*6,169*3,181*1,182*7,185*27,186*1,188*2,193*3";
+w["1-4"]="164*1";
+w["1."]="149*1";
+w["10"]="170*1,171*1,185*1,186*1";
+w["100"]="185*1";
+w["100."]="185*1";
+w["1024"]="181*1";
+w["11"]="186*1";
+w["12"]="186*1";
+w["120"]="52*1";
+w["13"]="186*1";
+w["14"]="18*1,186*2";
+w["14:"]="18*1";
+w["15"]="18*1,186*2";
+w["15:"]="18*1";
+w["16"]="91*3,181*1,182*1,185*1";
+w["16-bit"]="91*3";
+w["1:"]="19*1";
+w["1byte"]="185*2";
+w["1e"]="136*2";
+w["2"]="1*1,9*1,18*1,19*1,23*1,24*1,25*1,37*3,79*1,117*2,118*2,129*1,131*1,143*1,144*1,145*1,147*1,148*4,149*1,152*1,153*1,166*1,167*1,169*2,181*1,182*4,185*15,186*1,193*2";
+w["20"]="185*1";
+w["2013"]="170*1";
+w["2014"]="170*1,171*3";
+w["24"]="182*1,185*1";
+w["256"]="167*1";
+w["28"]="170*1";
+w["28.01.2014"]="170*1";
+w["2^max_read"]="182*1";
+w["2^max_writ"]="182*1";
+w["3"]="1*2,21*1,117*2,118*2,131*1,132*4,145*2,147*1,148*2,149*1,152*1,153*1,169*1,186*1";
+w["300ms"]="6*1";
+w["300ms."]="6*1";
+w["32"]="38*1,51*1,52*1,68*1,70*1,173*1";
+w["32-bit"]="38*1,51*1,68*1,70*1,173*1";
+w["32.120"]="52*1";
+w["3f"]="136*2";
+w["3rd"]="148*1";
+w["4"]="15*2,20*1,23*2,50*1,75*1,76*1,79*1,83*1,84*1,104*1,107*1,111*1,112*2,113*2,114*2,115*2,116*1,117*1,119*1,120*1,125*1,129*1,132*2,142*1,145*1,147*1,148*1,152*1,153*1,164*1,165*1,166*1,167*1,169*2,181*6,182*3,185*17,186*1";
+w["4-bit"]="23*1";
+w["42197a"]="170*1";
+w["42197ax"]="171*1";
+w["42197ax-mcu-10"]="171*1";
+w["42197b"]="170*1";
+w["5"]="75*1,76*1,148*1,169*1,182*1,185*1,186*1";
+w["50"]="185*1";
+w["508"]="18*1";
+w["512"]="166*1";
+w["6"]="19*1,148*2";
+w["6:"]="19*1";
+w["7"]="19*1,148*2,186*1,192*1";
+w["74"]="136*2";
+w["7:"]="19*1";
+w["8"]="18*1,77*1,91*3,114*1,174*1,182*1,185*1,186*1";
+w["8-bit"]="91*3,174*1";
+w["8..0"]="18*1";
+w["8..0:"]="18*1";
+w["9"]="18*1,169*1,186*2";
+w["94"]="136*1";
+w["9:"]="18*1";
+w[":"]="23*2,24*1,25*1";
+w["_byte"]="185*1";
+w["abil"]="139*1";
+w["about"]="6*1";
+w["acc"]="30*1,181*1,182*1,193*1";
+w["access"]="0*3,6*1,7*1,63*3,75*1,76*1,79*1,89*1,91*39,104*1,113*4,114*4,115*4,131*7,132*13,133*12,135*1,136*1,137*1,139*2,181*11,185*1";
+w["access."]="89*1,113*3,114*3,115*3,136*1";
+w["accessed."]="131*1,132*3,133*2";
+w["accord"]="9*1,23*1,111*1,148*2";
+w["accur"]="172*1";
+w["accuraci"]="171*1";
+w["achiev"]="15*1";
+w["action"]="49*1,72*1,73*1";
+w["activ"]="52*1,62*1,64*1,68*43,69*1,70*1,87*1,88*2,89*44,92*1,96*43,97*1,98*1,134*1,135*2,136*45,138*1,140*6,182*1,185*3";
+w["actual"]="15*1,60*1";
+w["add"]="139*1";
+w["addit"]="156*1,157*1,175*1";
+w["addr"]="185*3";
+w["address"]="28*2,29*2,46*2,47*2,66*2,67*2,75*2,76*2,79*3,91*9,94*2,95*2,101*1,104*3,106*1,107*1,111*5,112*7,113*3,114*3,115*3,116*3,117*3,119*3,120*3,129*1,131*1,132*5,133*13,139*1,140*9,141*1,142*54,145*1,153*1,160*3,165*4,166*2,167*2,172*1,173*2,175*1,180*1,181*19,182*3,185*38";
+w["address."]="75*1,139*1";
+w["adjust"]="139*1,185*1";
+w["advanc"]="171*100,172*1";
+w["advis"]="171*1";
+w["after"]="69*1,97*1,99*1,138*4,148*1,159*1,168*1,182*3,185*2";
+w["afterward"]="138*1";
+w["afterwards."]="138*1";
+w["again"]="89*1,136*1";
+w["again."]="89*1,136*2";
+w["aka"]="62*1";
+w["aka:"]="62*1";
+w["al"]="136*1";
+w["align"]="132*1,140*3,181*1";
+w["all"]="1*6,22*1,28*1,29*1,37*3,46*1,47*1,62*2,63*9,66*1,67*1,79*2,91*6,92*1,94*1,95*1,121*47,139*3,140*9,160*3,171*1,172*2,173*1,174*1,175*2,180*1,192*1";
+w["all:"]="139*1";
+w["alloc"]="117*1";
+w["allow"]="131*1,185*1";
+w["allowed."]="131*1";
+w["along"]="18*1";
+w["also"]="1*1,79*1,89*1,91*1,136*1,140*1,160*1,169*1,175*2,180*1,186*1";
+w["alter"]="114*1,136*1";
+w["altern"]="59*1";
+w["although"]="172*1,175*1";
+w["alway"]="109*1,131*1";
+w["amount"]="131*1";
+w["analog"]="63*3";
+w["ani"]="0*1,37*1,51*1,52*1,62*2,70*1,89*1,98*1,104*1,111*1,115*1,131*2,132*2,133*10,135*1,136*1,171*5";
+w["anoth"]="69*1,97*1";
+w["api"]="7*1";
+w["app"]="136*1,140*3";
+w["appear"]="59*1";
+w["appl_base_addr"]="133*2,185*1";
+w["appli"]="51*3,61*1,63*6,68*1,89*1,91*3,96*1,112*1,113*1,114*3,115*2,116*1,119*1,120*1,132*1,182*1";
+w["applic"]="111*1,112*1,133*2,140*9,165*1,171*2,175*1,185*4";
+w["applications."]="185*1";
+w["applicaton"]="111*1";
+w["appnot"]="52*1";
+w["area"]="79*1,131*1,132*1,139*1,165*1";
+w["aris"]="171*1";
+w["arm"]="0*1,2*1,3*4,5*41,7*1,22*1,171*2,192*1";
+w["arm-bas"]="22*1,192*1";
+w["arm-target"]="3*1,5*41";
+w["arm."]="2*1";
+w["armjtag"]="186*3";
+w["array"]="135*1";
+w["ascend"]="173*1";
+w["ase"]="3*1";
+w["ask"]="140*6";
+w["asleep"]="60*1,63*3";
+w["assum"]="139*1,171*1";
+w["asynchron"]="22*1,105*1,115*2";
+w["asynchronously."]="105*1";
+w["ate"]="171*1";
+w["atmegaxxxrfr2"]="132*1";
+w["atmel"]="0*4,1*59,2*1,3*1,4*1,5*1,6*1,7*1,8*1,9*1,10*1,11*1,12*1,13*1,14*1,15*1,16*1,17*1,18*1,19*1,20*1,21*1,22*1,23*1,24*1,25*1,26*1,27*1,28*1,29*1,30*1,31*1,32*1,33*1,34*1,35*1,36*1,37*1,38*1,39*1,40*1,41*1,42*1,43*1,44*1,45*1,46*1,47*1,48*1,49*1,50*1,51*2,52*1,53*1,54*1,55*1,56*1,57*1,58*1,59*1,60*1,61*1,62*1,63*1,64*1,65*1,66*1,67*1,68*1,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,80*1,81*1,82*1,83*1,84*1,85*1,86*1,87*1,88*1,89*1,90*1,91*1,92*1,93*1,94*1,95*1,96*1,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,122*1,123*1,124*1,125*1,126*1,127*1,128*1,129*1,130*1,131*1,132*1,133*1,134*1,135*1,136*1,137*1,138*1,139*1,140*1,141*1,142*1,143*1,144*1,145*1,146*1,147*1,148*1,149*1,150*1,151*1,152*1,153*1,154*1,155*1,156*1,157*1,158*1,159*1,160*1,161*1,162*1,163*1,164*1,165*1,166*1,167*1,168*1,169*1,170*1,171*167,172*5,173*2,174*1,175*2,176*1,177*1,178*1,179*2,180*1,181*1,182*1,183*1,184*1,185*1,186*1,187*1,188*1,189*1,190*1,191*1,192*1,193*1";
+w["atmel-ic"]="1*1";
+w["atmel."]="51*1";
+w["attach"]="92*1,99*42,109*1,136*1,138*2,140*6";
+w["attachin"]="89*1";
+w["attempt"]="131*1,132*7";
+w["author"]="171*1";
+w["auto"]="51*1,62*2,140*9";
+w["auto-detect"]="62*2";
+w["auto-eras"]="140*9";
+w["automat"]="109*1,111*1,133*3,148*1,182*1";
+w["automot"]="171*1";
+w["avail"]="19*1,20*1,24*1,25*1,36*1,37*1,43*3,132*1,140*6,185*1,192*1";
+w["avr"]="0*1,1*4,3*7,4*44,22*54,23*44,24*44,25*43,36*1,37*1,38*1,52*1,90*1,111*1,112*1,117*1,118*1,133*53,140*9,145*1,171*3,173*1,174*1,175*53,176*51,177*1,180*1,183*1,185*34";
+w["avr-specif"]="4*3";
+w["avr-target"]="3*1,4*41";
+w["avr053"]="52*1";
+w["avr069"]="175*1";
+w["avr069:"]="175*1";
+w["avr1606"]="52*1";
+w["avr32"]="65*1,91*1,171*1,173*51,191*36";
+w["avr32_awire_bas"]="91*1,182*1";
+w["avr32_cmd_activate_phys"]="68*1,91*1";
+w["avr32_cmd_deactivate_phys"]="69*1,91*1";
+w["avr32_cmd_eras"]="71*1,91*1";
+w["avr32_cmd_erase_sect"]="79*1,91*1";
+w["avr32_cmd_get"]="91*1";
+w["avr32_cmd_get_id"]="70*1,91*1";
+w["avr32_cmd_halt"]="72*1,91*1";
+w["avr32_cmd_is_protect"]="78*1,91*1";
+w["avr32_cmd_queri"]="91*1";
+w["avr32_cmd_read"]="75*1,91*1";
+w["avr32_cmd_reset"]="73*1,91*1";
+w["avr32_cmd_set"]="91*1";
+w["avr32_cmd_step"]="74*1,91*1";
+w["avr32_cmd_tap"]="77*1,91*1";
+w["avr32_cmd_writ"]="76*1,91*1";
+w["avr32_ctxt_devic"]="91*1,182*1";
+w["avr32_ctxt_phys"]="91*1,182*1";
+w["avr32_ctxt_sess"]="91*1,182*1";
+w["avr32_ctxt_usb"]="91*1,182*1";
+w["avr32_failure_awire_crc"]="91*1";
+w["avr32_failure_awire_error_respons"]="91*1";
+w["avr32_failure_awire_overflow"]="91*1";
+w["avr32_failure_awire_rw_status"]="91*1";
+w["avr32_failure_awire_set_baud_error"]="91*1";
+w["avr32_failure_awire_tun"]="91*1";
+w["avr32_failure_awm_error"]="91*1";
+w["avr32_failure_bad_valu"]="91*1";
+w["avr32_failure_config_error"]="91*1";
+w["avr32_failure_cpu_debug_mode_timeout"]="91*1";
+w["avr32_failure_cpu_dirty_timeout"]="91*1";
+w["avr32_failure_cpu_mod"]="91*1";
+w["avr32_failure_erase_error"]="91*1";
+w["avr32_failure_erase_timeout"]="91*1";
+w["avr32_failure_flashready_timeout"]="91*1";
+w["avr32_failure_hardware_error"]="91*1";
+w["avr32_failure_illegal_st"]="91*1";
+w["avr32_failure_internal_response_error"]="91*1";
+w["avr32_failure_invalid_address"]="91*1";
+w["avr32_failure_invalid_clock_spe"]="91*1";
+w["avr32_failure_invalid_data"]="91*1";
+w["avr32_failure_invalid_emulator_mod"]="91*1";
+w["avr32_failure_invalid_memtyp"]="91*1";
+w["avr32_failure_invalid_physical_mod"]="91*1";
+w["avr32_failure_invalid_s"]="91*1";
+w["avr32_failure_jtagm_error"]="91*1";
+w["avr32_failure_jtagm_init_error"]="91*1";
+w["avr32_failure_jtagm_timeout"]="91*1";
+w["avr32_failure_jtagm_was_busi"]="91*1";
+w["avr32_failure_length"]="91*1";
+w["avr32_failure_lock"]="91*1";
+w["avr32_failure_nack"]="91*1";
+w["avr32_failure_no_contact"]="91*1";
+w["avr32_failure_no_device_found"]="91*1";
+w["avr32_failure_no_target_pow"]="91*1";
+w["avr32_failure_not_impl"]="91*1";
+w["avr32_failure_not_support"]="91*1";
+w["avr32_failure_ok"]="91*1";
+w["avr32_failure_prog"]="91*1";
+w["avr32_failure_read_busi"]="91*1";
+w["avr32_failure_read_error"]="91*1";
+w["avr32_failure_read_short"]="91*1";
+w["avr32_failure_receive_length"]="91*1";
+w["avr32_failure_receive_sync"]="91*1";
+w["avr32_failure_receive_timeout"]="91*1";
+w["avr32_failure_step_timeout"]="91*1";
+w["avr32_failure_transmit_overflow"]="91*1";
+w["avr32_failure_transmit_timeout"]="91*1";
+w["avr32_failure_unknown"]="91*1";
+w["avr32_failure_unsupported_hardwar"]="91*1";
+w["avr32_failure_write_busi"]="91*1";
+w["avr32_failure_write_error"]="91*1";
+w["avr32_flash_ctrl_bas"]="91*1,182*1";
+w["avr32_flash_pag"]="91*1,182*1";
+w["avr32_flash_pagebyt"]="91*1,182*1";
+w["avr32_memtype_block"]="91*1,181*1";
+w["avr32_memtype_byt"]="91*1,181*1";
+w["avr32_memtype_half_word"]="91*1,181*1";
+w["avr32_memtype_internal_flash"]="91*1,181*1";
+w["avr32_memtype_memory_servic"]="91*1,181*1";
+w["avr32_memtype_nexus"]="91*1,181*1";
+w["avr32_memtype_regfil"]="91*1,181*1";
+w["avr32_memtype_sab"]="91*1,181*1";
+w["avr32_memtype_sysreg"]="91*1,181*1";
+w["avr32_memtype_user_pag"]="91*1,181*1";
+w["avr32_phy_aw_maxbaud"]="91*1,182*1";
+w["avr32_phy_awire_baud"]="91*1";
+w["avr32_phy_awire_vers"]="91*1";
+w["avr32_phy_daisi"]="91*1,182*1";
+w["avr32_phy_ext_reset"]="91*1,182*1";
+w["avr32_phy_jtag_clock"]="182*1";
+w["avr32_phy_phys"]="91*1,182*1";
+w["avr32_phyl_jtag_clock"]="91*1";
+w["avr32_physical_interface_awir"]="91*1";
+w["avr32_physical_interface_jtag"]="91*1";
+w["avr32_physical_interface_non"]="91*1";
+w["avr32_query_command"]="91*1,191*1";
+w["avr32_query_command_vers"]="91*1";
+w["avr32_query_configur"]="91*1,191*1";
+w["avr32_query_read_memtyp"]="91*1,191*1";
+w["avr32_query_write_memtyp"]="91*1,191*1";
+w["avr32_reset_domain"]="91*1,182*1";
+w["avr32_rsp_data"]="85*2,91*1";
+w["avr32_rsp_fail"]="86*1,91*1";
+w["avr32_rsp_id"]="83*1,91*1";
+w["avr32_rsp_list"]="82*1,91*1";
+w["avr32_rsp_ok"]="81*1,91*1";
+w["avr32_rsp_pc"]="84*1,91*1";
+w["avr32_sess_run_l"]="91*1,182*1";
+w["avr32_tap_dr"]="77*1,91*1";
+w["avr32_tap_ir"]="77*1,91*1";
+w["avr32_usb_max_read"]="91*1,182*1";
+w["avr32_usb_max_writ"]="91*1,182*1";
+w["avr32gener"]="38*1,91*46,173*3";
+w["avr32genericcommand"]="91*1";
+w["avr32genericdevicecontext"]="91*1";
+w["avr32genericfailurecod"]="91*1";
+w["avr32genericmemorytyp"]="91*1";
+w["avr32genericphysicalcontextparamet"]="91*1";
+w["avr32genericphysicalinterfac"]="91*1";
+w["avr32genericquerycontext"]="91*1";
+w["avr32genericrespons"]="91*1";
+w["avr32genericsessioncontextparamet"]="91*1";
+w["avr32genericsetgetcontext"]="91*1";
+w["avr32genericusbcontextparamet"]="91*1";
+w["avr32tapcommand"]="91*1";
+w["avr8"]="93*1,135*1,140*1,171*1,174*52,184*36";
+w["avr8_break_cause_program"]="140*1";
+w["avr8_break_cause_unknown"]="140*1";
+w["avr8_config_funct"]="140*1,185*1";
+w["avr8_config_vari"]="140*1,185*1";
+w["avr8_ctxt_config"]="140*1,185*1";
+w["avr8_ctxt_devic"]="140*1,185*1";
+w["avr8_ctxt_opt"]="140*1,185*1";
+w["avr8_ctxt_phys"]="140*1,185*1";
+w["avr8_ctxt_sess"]="140*1,185*1";
+w["avr8_ctxt_test"]="185*1";
+w["avr8_failure_clock_error"]="140*1";
+w["avr8_failure_collis"]="140*1";
+w["avr8_failure_crc_failur"]="140*1";
+w["avr8_failure_cs_error"]="140*1";
+w["avr8_failure_dw_phy_error"]="140*1";
+w["avr8_failure_eb_error"]="140*1";
+w["avr8_failure_illegal_breakpoint"]="140*1";
+w["avr8_failure_illegal_id"]="140*1";
+w["avr8_failure_illegal_memory_rang"]="131*1,132*1,140*1";
+w["avr8_failure_illegal_ocd_status"]="140*1";
+w["avr8_failure_illegal_st"]="131*1,132*1,140*1";
+w["avr8_failure_illegal_valu"]="140*1";
+w["avr8_failure_invalid_address"]="131*4,132*1,140*1";
+w["avr8_failure_invalid_align"]="132*1,140*1";
+w["avr8_failure_invalid_clock_spe"]="140*1";
+w["avr8_failure_invalid_config"]="140*1";
+w["avr8_failure_invalid_memtyp"]="140*1";
+w["avr8_failure_invalid_physical_st"]="140*1";
+w["avr8_failure_invalid_s"]="131*3,132*1,140*1";
+w["avr8_failure_jtag_bit_banger_timeout"]="140*1";
+w["avr8_failure_jtag_error"]="140*1";
+w["avr8_failure_jtagm_error"]="140*1";
+w["avr8_failure_jtagm_init_error"]="140*1";
+w["avr8_failure_jtagm_timeout"]="140*1";
+w["avr8_failure_jtagm_vers"]="140*1";
+w["avr8_failure_no_device_found"]="140*1";
+w["avr8_failure_no_ocd_control"]="140*1";
+w["avr8_failure_no_target_pow"]="140*1";
+w["avr8_failure_not_attach"]="140*1";
+w["avr8_failure_not_impl"]="140*1";
+w["avr8_failure_not_support"]="140*1";
+w["avr8_failure_nvm_dis"]="140*1";
+w["avr8_failure_nvm_en"]="140*1";
+w["avr8_failure_ocd_lock"]="140*1";
+w["avr8_failure_ok"]="140*1";
+w["avr8_failure_parity_error"]="140*1";
+w["avr8_failure_pc_read_fail"]="140*1";
+w["avr8_failure_pdi_en"]="140*1";
+w["avr8_failure_pdi_timeout"]="140*1";
+w["avr8_failure_read_error"]="140*1";
+w["avr8_failure_register_read_fail"]="140*1";
+w["avr8_failure_timeout"]="140*1";
+w["avr8_failure_too_many_breakpoint"]="140*1";
+w["avr8_failure_unknown"]="140*1";
+w["avr8_failure_write_error"]="140*1";
+w["avr8_failure_write_timeout"]="140*1";
+w["avr8_func_debug"]="140*1,185*1";
+w["avr8_func_non"]="140*1,185*1";
+w["avr8_func_program"]="140*1,185*1";
+w["avr8_hwbp_prog_bp"]="140*1";
+w["avr8_opt_disable_dbp"]="140*1,185*1";
+w["avr8_opt_enable_idr"]="140*1,185*1";
+w["avr8_opt_poll_int"]="140*1,185*1";
+w["avr8_opt_run_tim"]="140*1,185*1";
+w["avr8_phy_dw_clk_div"]="140*1,185*1";
+w["avr8_phy_interfac"]="140*1";
+w["avr8_phy_intf_dw"]="140*1,185*1";
+w["avr8_phy_intf_jtag"]="140*1,185*1";
+w["avr8_phy_intf_non"]="140*1,185*1";
+w["avr8_phy_intf_pdi"]="140*1,185*1";
+w["avr8_phy_jtag_daisi"]="140*1,185*1";
+w["avr8_phy_mega_dbg_clk"]="140*1,185*1";
+w["avr8_phy_mega_prg_clk"]="140*1,185*1";
+w["avr8_phy_phys"]="185*1";
+w["avr8_phy_xm_jtag_clk"]="140*1,185*1";
+w["avr8_phy_xm_pdi_clk"]="140*1,185*1";
+w["avr8_query_command"]="140*1,184*1";
+w["avr8_query_configur"]="140*1,184*1";
+w["avr8_query_read_memtyp"]="140*1,184*1";
+w["avr8_query_write_memtyp"]="140*1,184*1";
+w["avr8_rsp_list"]="124*1";
+w["avr8_sess_main_pc"]="140*1,185*1";
+w["avr8_test_tgt_run"]="140*1,185*1";
+w["avr8_variant_loopback"]="140*1,185*1";
+w["avr8_variant_megaocd"]="140*1,185*1";
+w["avr8_variant_non"]="140*1,185*1";
+w["avr8_variant_tinyocd"]="140*1,185*1";
+w["avr8_variant_xmega"]="140*1,185*1";
+w["avr8gener"]="38*1,140*46,174*1";
+w["avr8genericcommand"]="140*1";
+w["avr8genericconfigcontextparamet"]="140*1";
+w["avr8genericconfigtestparamet"]="140*1";
+w["avr8genericev"]="140*1";
+w["avr8genericfailurecod"]="140*1";
+w["avr8genericfunctionvalu"]="140*1";
+w["avr8genericmegabreakcaus"]="140*1";
+w["avr8genericmegabreakpointtyp"]="140*1";
+w["avr8genericmemtyp"]="140*1";
+w["avr8genericoptionscontextparamet"]="140*1";
+w["avr8genericphysicalcontextparamet"]="140*1";
+w["avr8genericphysicalinterfac"]="140*1";
+w["avr8genericquerycontext"]="140*1";
+w["avr8genericrespons"]="140*1";
+w["avr8genericsessioncontextparamet"]="140*1";
+w["avr8genericsetgetcontext"]="140*1";
+w["avr8genericvariantvalu"]="140*1";
+w["avr8genericxmegaerasemod"]="140*1";
+w["avr_cmd"]="3*1,4*1,22*1,23*12";
+w["avr_evt"]="3*1,4*1,22*1,25*13";
+w["avr_rsp"]="3*1,4*1,22*1,23*1,24*13";
+w["avrisp"]="38*2,160*1,175*1,180*1";
+w["avrjtag"]="186*3";
+w["aw"]="186*3";
+w["awak"]="60*1";
+w["awar"]="136*1";
+w["awir"]="1*4,38*1,70*1,78*1,88*3,90*1,91*30,182*3";
+w["awire_baud_max"]="88*1";
+w["awire_baud_max:"]="88*1";
+w["awireid"]="68*1";
+w["b"]="3*1,132*5,182*1";
+w["back"]="175*1";
+w["bad"]="91*3,140*6";
+w["banger"]="140*3";
+w["base"]="0*1,1*54,2*1,3*1,4*1,5*1,6*1,7*1,8*1,9*1,10*1,11*1,12*1,13*1,14*1,15*1,16*1,17*1,18*1,19*1,20*1,21*1,22*2,23*1,24*1,25*1,26*1,27*1,28*1,29*1,30*1,31*1,32*1,33*1,34*1,35*1,36*2,37*1,38*2,39*1,40*1,41*1,42*1,43*1,44*1,45*1,46*1,47*1,48*1,49*1,50*1,51*1,52*1,53*1,54*1,55*1,56*1,57*1,58*1,59*1,60*1,61*1,62*1,63*1,64*1,65*1,66*1,67*1,68*1,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,80*1,81*1,82*1,83*1,84*1,85*1,86*1,87*1,88*1,89*1,90*1,91*7,92*1,93*1,94*1,95*1,96*1,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,122*1,123*1,124*1,125*1,126*1,127*1,128*1,129*1,130*1,131*1,132*1,133*14,134*1,135*1,136*1,137*1,138*1,139*2,140*1,141*1,142*1,143*1,144*1,145*1,146*1,147*1,148*1,149*1,150*1,151*1,152*1,153*1,154*1,155*1,156*1,157*1,158*1,159*1,160*1,161*1,162*1,163*1,164*1,165*1,166*1,167*1,168*1,169*1,170*1,171*51,172*1,173*1,174*1,175*2,176*1,177*1,178*1,179*2,180*2,181*1,182*3,183*1,184*1,185*4,186*1,187*1,188*1,189*1,190*1,191*1,192*2,193*1";
+w["basic"]="63*3,186*3";
+w["baud"]="15*57,18*1,19*1,88*1,91*9,140*3,141*2,143*53,144*53,159*1,160*9,182*2,192*1";
+w["baud-rat"]="15*1";
+w["be"]="38*1,131*1,132*1,135*1";
+w["becaus"]="148*1";
+w["been"]="18*1,19*1,59*1,61*2,105*1,109*1,140*3,148*1,171*1";
+w["befor"]="24*1,62*1,79*1,88*2,111*1,131*1,133*3,135*2,182*3,185*3";
+w["behaviour"]="37*1,109*1";
+w["behaviour."]="37*1";
+w["bei"]="37*1";
+w["belong"]="2*1";
+w["below"]="38*1,185*1";
+w["below."]="175*1";
+w["beta"]="170*1";
+w["between"]="0*1,1*1,145*1";
+w["bidirect"]="0*1";
+w["big"]="173*1,180*1";
+w["bigger"]="148*1";
+w["bit"]="18*4,19*3,23*1,38*1,51*1,68*1,70*1,73*1,77*5,78*1,91*15,114*1,140*9,148*9,149*2,154*1,155*1,160*6,165*1,173*1,174*1,182*2,185*3";
+w["bit."]="148*1";
+w["ble"]="160*1";
+w["block"]="91*6,181*1,182*1";
+w["board"]="0*1,1*5,3*2,9*1,10*1,172*1,178*1";
+w["board."]="1*1";
+w["boolean"]="79*1";
+w["boot"]="101*1,111*2,112*1,133*2,140*12,185*4";
+w["boot_base_addr"]="133*2,185*1";
+w["boot_byt"]="185*1";
+w["boot_section_start"]="185*2";
+w["both"]="77*1";
+w["break"]="99*2,101*1,102*1,104*1,105*1,109*1,117*2,119*1,128*1,129*47,138*1,139*1,140*12,185*1";
+w["breakpoint"]="92*5,104*3,117*51,118*51,119*48,120*48,121*47,129*1,131*2,132*1,139*6,140*21";
+w["breakpoint."]="104*1";
+w["breakpoints."]="117*2,118*2,139*1,185*1";
+w["bsi"]="147*1,148*3";
+w["buffer"]="18*1,19*1,20*54,22*1,91*3,148*1,153*1,192*1";
+w["buffer."]="148*1";
+w["build"]="15*1,63*3,193*2";
+w["bulk"]="0*1";
+w["bus"]="91*3";
+w["busi"]="91*12,160*3,171*1";
+w["but"]="59*1,62*1,70*1,98*1,150*1,151*1,154*1,155*1,156*1,157*1,171*1,182*1";
+w["byte"]="6*3,9*12,10*7,13*6,14*6,15*6,16*5,17*5,18*8,19*8,20*5,21*5,23*7,24*6,25*5,27*3,28*8,29*7,30*3,32*2,33*3,34*4,35*3,37*17,40*3,41*3,42*3,43*3,45*3,46*8,47*7,49*2,50*3,51*3,52*2,54*2,55*3,56*4,57*3,59*3,60*3,61*3,65*3,66*8,67*7,68*3,69*2,70*2,71*2,72*3,73*3,74*2,75*7,76*8,77*5,78*2,79*6,81*2,82*3,83*3,84*3,85*7,86*3,91*6,93*3,94*8,95*7,96*3,97*2,98*2,99*3,100*2,101*3,102*3,103*2,104*3,105*4,106*2,107*3,108*2,109*2,110*2,111*5,112*7,113*8,114*10,115*10,116*4,117*6,118*3,119*4,120*4,121*2,123*2,124*3,125*3,126*4,127*3,129*5,130*3,131*7,132*6,133*10,140*6,142*4,143*4,144*4,145*20,146*5,147*13,148*24,149*10,152*11,153*17,156*1,157*2,160*12,162*3,163*3,164*5,165*5,166*9,167*8,173*3,180*1,181*18,182*15,184*4,185*85,187*1,188*2,189*1,190*3,191*4,193*5";
+w["byte."]="173*1";
+w["byte:"]="145*1,148*1";
+w["bytedelay"]="145*2";
+w["bytedelay."]="145*1";
+w["bytes."]="75*1,76*1";
+w["c"]="132*6,171*1";
+w["c0"]="136*2";
+w["cach"]="70*1,98*1,136*1";
+w["cached."]="89*1";
+w["calcul"]="112*1,139*1,140*3";
+w["calibr"]="48*1,52*38,63*3,133*1,140*6";
+w["call"]="7*1,15*1,27*1,28*2,29*2,40*1,45*1,46*2,47*2,52*1,65*1,66*2,67*2,75*1,76*1,79*1,88*2,89*1,93*1,94*2,95*2,113*1,114*1,115*1,133*12,135*2,136*1,175*1";
+w["called."]="78*1";
+w["calls."]="175*1";
+w["cannot"]="104*1";
+w["capabl"]="1*3,27*1,36*1,40*1,43*3,45*1,63*3,65*1,89*1,91*3,93*1,136*1,140*3";
+w["captur"]="3*1,14*53,15*1,16*1,17*1,18*1,77*1,192*4";
+w["capture_off"]="186*1";
+w["capture_uart"]="186*1";
+w["cas"]="59*1";
+w["case"]="89*1,131*1,132*1,135*1,136*2,137*1,138*1,148*1";
+w["case."]="131*1,132*1,137*1";
+w["caus"]="110*1,129*1";
+w["cdc"]="0*2,1*2,186*3";
+w["ceas"]="49*1";
+w["ceil"]="182*1";
+w["chain"]="48*1,51*42,62*2,88*2,91*3,140*3,182*1,185*1";
+w["chang"]="135*1,171*1,172*1";
+w["channel."]="188*1";
+w["check"]="21*1,62*1,78*1,91*3";
+w["checksum"]="112*1";
+w["chip"]="1*2,71*1,111*2,140*6,141*1,147*52,165*1";
+w["chop"]="23*1";
+w["cleanup"]="37*1";
+w["clear"]="92*3,118*48,120*48,121*46,139*3,140*9,148*1,165*2";
+w["clear:"]="139*2";
+w["cleared."]="148*1";
+w["clock"]="52*1,63*3,78*2,88*1,91*6,135*2,140*18,143*1,144*1,159*1,182*1,185*6";
+w["cmd"]="24*1,39*1,40*41,44*3,45*41,46*41,47*41";
+w["cmd-rsp"]="24*1";
+w["cmd1"]="145*1,147*1,148*1,149*1,152*1,153*1";
+w["cmd2"]="145*1,147*1,148*1,152*1,153*1";
+w["cmd3"]="145*1,147*1,148*1,152*1,153*1";
+w["cmd4"]="145*1,147*1,152*1,153*1";
+w["cmd:"]="39*1,40*41,44*3,45*41,46*41,47*41";
+w["cmd_activate_phys"]="175*1,180*1";
+w["cmd_activate_physical."]="175*1,180*1";
+w["cmd_avr8_activate_phys"]="140*1";
+w["cmd_avr8_attach"]="99*1,140*1";
+w["cmd_avr8_crc"]="112*1,140*1";
+w["cmd_avr8_deactivate_phys"]="97*1,140*1";
+w["cmd_avr8_detach"]="100*1,140*1";
+w["cmd_avr8_disable_debugwir"]="110*1,140*1";
+w["cmd_avr8_eras"]="111*1,140*1";
+w["cmd_avr8_get"]="140*1";
+w["cmd_avr8_get_id"]="98*1,140*1";
+w["cmd_avr8_hw_break_clear"]="140*1";
+w["cmd_avr8_hw_break_clr"]="118*1";
+w["cmd_avr8_hw_break_set"]="117*1,140*1";
+w["cmd_avr8_memory_read"]="113*1,114*1,140*1";
+w["cmd_avr8_memory_read_mask"]="140*1";
+w["cmd_avr8_memory_writ"]="115*1,140*1";
+w["cmd_avr8_page_eras"]="116*1,140*1";
+w["cmd_avr8_pc_read"]="106*1,140*1";
+w["cmd_avr8_pc_writ"]="107*1,140*1";
+w["cmd_avr8_prog_mode_ent"]="108*1,140*1";
+w["cmd_avr8_prog_mode_leav"]="109*1,140*1";
+w["cmd_avr8_queri"]="140*1";
+w["cmd_avr8_reset"]="101*1,140*1";
+w["cmd_avr8_run"]="103*1,140*1";
+w["cmd_avr8_run_to_address"]="104*1,140*1";
+w["cmd_avr8_set"]="140*1";
+w["cmd_avr8_step"]="105*1,140*1";
+w["cmd_avr8_stop"]="102*1,140*1";
+w["cmd_avr8_sw_break_clear"]="140*1";
+w["cmd_avr8_sw_break_clear_al"]="140*1";
+w["cmd_avr8_sw_break_set"]="140*1";
+w["cmd_avr8_sw_breakpoint_clr"]="120*1";
+w["cmd_avr8_sw_breakpoint_clr_al"]="121*1";
+w["cmd_avr8_sw_breakpoint_set"]="119*1";
+w["cmd_edbg_get"]="186*1";
+w["cmd_edbg_queri"]="186*1";
+w["cmd_edbg_set"]="186*1";
+w["cmd_end_sess"]="62*1";
+w["cmd_housekeeping_cal_osc"]="52*1,63*1";
+w["cmd_housekeeping_end_sess"]="49*1,63*1";
+w["cmd_housekeeping_fw_upgrad"]="50*1,63*1";
+w["cmd_housekeeping_get"]="63*1";
+w["cmd_housekeeping_jtag_detect"]="51*1,63*1";
+w["cmd_housekeeping_queri"]="63*1";
+w["cmd_housekeeping_set"]="63*1";
+w["cmd_housekeeping_start_sess"]="63*1,88*1,135*1,188*1";
+w["cmd_load_address"]="175*1";
+w["cmd_queri"]="43*1";
+w["cmd_start_sess"]="62*1";
+w["cmdexedelay"]="145*2";
+w["cmdexedelay."]="145*1";
+w["cmsis"]="0*4,1*1,2*47,3*47,24*1,171*1,177*53";
+w["cmsis-dap"]="0*4,1*1,2*47,3*47,24*1,171*1,177*53";
+w["co"]="1*1";
+w["code"]="13*1,14*1,16*1,17*1,34*1,35*2,37*1,42*2,43*3,52*1,56*2,57*2,85*1,86*2,89*1,91*1,126*1,127*2,131*1,132*1,135*1,136*1,137*1,140*4,160*1,169*3,186*4";
+w["code."]="56*1,135*1";
+w["codes."]="91*1,140*1,160*1,169*1,186*1";
+w["collis"]="140*3,168*1";
+w["com"]="0*3,1*2,172*1";
+w["combin"]="171*1";
+w["command"]="0*1,3*62,4*48,5*41,6*5,7*1,8*41,9*5,10*5,22*54,23*43,24*2,26*46,27*2,28*2,29*2,32*1,35*1,37*6,38*3,39*1,40*2,42*1,43*9,44*1,45*2,46*2,47*2,48*41,49*7,50*7,51*7,52*8,54*1,57*1,63*12,64*46,65*2,66*2,67*2,68*7,69*8,70*7,71*7,72*7,73*2,74*7,75*7,76*7,77*9,78*8,79*9,81*1,86*1,87*1,88*1,89*5,90*42,91*16,92*46,93*2,94*2,95*2,96*7,97*8,98*7,99*7,100*7,101*7,102*7,103*7,104*7,105*7,106*7,107*7,108*7,109*8,110*7,111*7,112*8,113*7,114*7,115*7,116*7,117*7,118*7,119*8,120*8,121*7,123*1,127*1,130*5,135*1,136*6,137*1,138*5,139*2,140*13,141*46,142*8,143*7,144*7,145*13,146*7,147*12,148*18,149*8,150*1,151*1,152*11,153*11,154*1,155*1,156*2,157*2,158*1,159*5,160*10,161*46,162*7,163*7,164*7,165*7,166*7,167*7,168*3,169*4,172*1,173*1,174*1,175*12,177*3,178*1,180*4,184*1,186*4,187*1,188*7,189*1,190*1,191*1,192*48";
+w["command."]="22*3,39*1,69*1,70*1,89*1,97*1,98*1,136*1,138*2,139*1,142*1,145*1,159*1,168*1,175*1";
+w["command_handl"]="190*1";
+w["commandpacket"]="23*1";
+w["commands."]="88*1,135*1,175*1,180*1";
+w["comment"]="170*1";
+w["commit"]="171*1";
+w["communic"]="22*3,36*1,50*1,139*1,171*1,172*1,175*3,176*51,180*1";
+w["complet"]="89*2,105*1,131*2,132*1,135*1,136*2,138*1,146*1,148*1,163*1,171*1,181*1";
+w["complete."]="131*1";
+w["compon"]="171*1,172*1";
+w["composit"]="0*1";
+w["comput"]="13*1";
+w["computer."]="13*1";
+w["con"]="79*1";
+w["condit"]="37*1";
+w["config"]="9*2,63*3,91*3,109*1,135*2,140*3";
+w["configid"]="9*2,10*1";
+w["configpacket"]="9*1";
+w["configur"]="3*2,8*2,9*54,10*49,38*2,87*1,88*43,89*1,91*3,133*12,134*1,135*44,136*1,138*1,140*18,165*1,178*1,182*1,184*1,186*6,191*1,192*1";
+w["confus"]="23*1";
+w["connect"]="0*1,69*1,89*2,91*3,97*1,136*2,140*3,145*1,171*2";
+w["consequenti"]="171*1";
+w["consist"]="0*1";
+w["constant"]="148*1";
+w["contact"]="68*1,96*1";
+w["contain"]="3*1,38*1,68*1,89*1,131*1,132*1,136*1,153*1,171*1";
+w["content"]="3*5,5*5,8*5,22*5,26*5,27*5,29*5,31*5,39*5,44*5,48*5,53*5,58*5,64*5,65*5,67*5,76*5,80*5,87*5,92*5,93*5,95*5,122*5,128*5,134*5,141*5,161*5,171*6,172*1,173*5,174*5,175*5,176*5,177*5,178*5,179*5,180*5,183*5,185*5,192*5";
+w["context"]="27*3,28*3,29*3,30*1,39*1,40*2,44*1,45*2,46*3,47*3,65*3,66*3,67*3,93*3,94*3,95*3,109*1,133*12,135*3,140*3,182*1,184*41,185*110,187*41,189*46,190*46,191*41,193*1";
+w["context."]="28*1,29*1,46*1,47*1,66*1,67*1,94*1,95*1";
+w["context:"]="133*12,185*108";
+w["contigu"]="79*1";
+w["continu"]="88*1,99*1,135*1,138*1,185*1";
+w["control"]="3*1,38*1,62*1,79*1,90*1,91*12,110*2,119*1,120*1,134*3,137*41,138*41,139*45,140*6,148*1,171*1,178*52,182*1,185*2";
+w["core"]="185*1";
+w["core."]="185*1";
+w["coresight"]="0*1";
+w["corpor"]="171*4";
+w["corporation."]="171*1";
+w["correct"]="133*12,135*1";
+w["could"]="59*1";
+w["count"]="9*1,10*1";
+w["counter"]="84*2,107*1,125*2,129*1,139*1,185*1";
+w["countries."]="171*2";
+w["cpu"]="91*9";
+w["crc"]="91*3,92*1,112*44,139*2,140*6";
+w["crc:"]="139*1";
+w["current"]="13*1,14*1,91*3,144*1";
+w["custom"]="0*1,1*1,3*1";
+w["cyc"]="110*1";
+w["d"]="132*2,148*1";
+w["daisi"]="88*2,91*3,140*3,182*1,185*1";
+w["damag"]="171*3";
+w["damages."]="171*1";
+w["dap"]="0*4,1*1,2*47,3*47,24*1,171*1,177*53";
+w["data"]="0*2,1*1,9*5,10*2,13*2,14*2,15*1,16*1,17*1,18*55,24*1,25*1,28*2,29*1,31*1,33*3,34*45,37*4,41*3,46*2,47*1,53*1,55*3,56*40,63*3,66*2,67*1,68*1,75*1,76*2,77*5,78*1,80*1,82*3,85*47,91*15,94*2,95*1,96*1,98*1,112*1,113*1,114*1,115*1,122*1,124*3,126*45,133*2,135*1,136*1,140*15,148*4,149*3,150*1,151*1,153*2,160*12,166*3,167*3,185*4,192*3";
+w["data."]="15*1";
+w["data_base_addr"]="133*1,185*1";
+w["datasheet"]="83*1";
+w["datatyp"]="9*2";
+w["date"]="43*3,170*1,190*1";
+w["dbg_en"]="186*3";
+w["de"]="69*1,97*1";
+w["de-activ"]="69*1,97*1";
+w["deactiv"]="64*1,69*41,87*1,89*42,92*1,97*41,109*1,134*1,136*44,137*2,175*1,180*1";
+w["deactivated."]="89*1,136*2,137*1";
+w["debounc"]="59*1";
+w["debug"]="0*4,1*6,22*1,30*1,38*3,87*1,90*42,91*6,99*1,100*1,109*2,116*1,131*6,132*4,133*12,134*1,135*1,136*1,138*43,139*1,140*9,172*1,173*1,174*1,185*3";
+w["debugg"]="0*1,1*2,69*1,90*1,97*1,109*1,172*1,185*1";
+w["debuggers."]="1*1";
+w["debugging."]="131*1,132*1";
+w["debugwir"]="1*2,38*1,92*1,110*49,111*1,117*1,118*1,131*42,136*1,140*15,183*1,185*37";
+w["decid"]="148*1";
+w["decod"]="37*2";
+w["default"]="13*1,14*1,89*1,136*1";
+w["defin"]="0*1,3*1,91*2,140*2,160*2,169*21,172*1,186*2";
+w["definit"]="28*1,29*1,39*47,43*41,44*1,63*41,91*46,140*49,160*46,169*46,173*1,174*1,175*1,176*1,178*1,180*1,186*46";
+w["delay"]="145*3,146*2,147*2,148*6";
+w["delay."]="148*1";
+w["demand"]="89*1,136*1";
+w["depend"]="9*1,36*1,73*1,75*1,76*1,96*1,131*1,132*1";
+w["deploy"]="135*1";
+w["deprec"]="101*1,102*1,105*3,185*1";
+w["des"]="109*1";
+w["describ"]="1*3,9*1,22*1,25*1,52*1,90*1,159*1,168*1,175*2,192*1";
+w["descript"]="3*1,4*1,6*2,9*3,10*2,13*2,14*2,15*2,16*2,17*2,18*2,19*2,20*2,21*2,23*2,24*2,25*2,27*1,28*1,29*1,30*1,32*1,33*1,34*1,35*1,38*1,40*1,41*1,42*1,45*1,46*1,47*1,49*1,50*1,51*1,52*1,54*1,55*1,56*1,57*1,59*1,60*1,61*1,65*1,66*1,67*1,68*1,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,81*1,82*1,83*1,84*1,85*2,86*1,93*1,94*1,95*1,96*1,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,123*1,124*1,125*1,126*1,127*1,129*1,130*1,142*2,143*2,144*2,145*2,146*2,147*2,148*3,149*2,152*2,153*2,159*1,162*2,163*2,164*2,165*3,166*2,167*2,168*1,171*1,181*1,182*1,184*1,185*4,187*1,188*1,189*1,190*1,191*1,193*1";
+w["destin"]="37*1";
+w["detach"]="92*1,100*41,136*1,138*1,140*3";
+w["detail"]="7*1,23*1,172*1";
+w["detect"]="48*1,51*43,62*4,63*3,68*1,89*1,96*1,135*1,136*1,140*3,168*1";
+w["detected."]="135*1";
+w["determin"]="148*1";
+w["develop"]="172*1";
+w["devic"]="0*2,1*8,6*2,7*1,10*1,18*1,22*2,30*1,38*1,51*4,63*9,68*2,70*1,73*2,78*1,79*1,83*3,89*4,90*1,91*9,96*1,113*1,114*1,115*1,131*1,132*3,133*1,135*4,136*5,140*21,148*3,153*1,160*6,173*1,174*1,175*1,180*2,182*3,185*96,192*1";
+w["device-specif"]="135*1";
+w["device."]="73*1,182*1";
+w["device:"]="135*1";
+w["devices."]="51*1";
+w["dgi"]="0*2";
+w["dgi."]="0*1";
+w["did"]="91*3,140*6,159*1";
+w["differ"]="1*1,91*2,131*1,140*2,148*3,160*2,169*2,186*2";
+w["direct"]="11*1,12*1,62*1,79*1,89*1,136*1,171*1";
+w["directly."]="62*1,79*1";
+w["disabl"]="18*2,19*2,30*6,89*1,92*1,110*42,136*1,140*6,185*1";
+w["disast"]="91*6,140*3";
+w["disaster."]="140*3";
+w["discard"]="91*3";
+w["disclaim"]="171*2";
+w["disclaimer:"]="171*1";
+w["disconnect"]="69*1,89*1,91*3,97*1,136*1,140*3";
+w["discov"]="27*1,38*1,40*1,45*1,65*1,93*1";
+w["discoveri"]="38*1,39*49,43*44,63*3,91*3,140*3,176*1,190*41";
+w["discovery_command_handl"]="43*1";
+w["discovery_failed_not_support"]="43*1";
+w["discovery_mnf_d"]="43*1";
+w["discovery_serial_numb"]="43*1";
+w["discovery_tool_nam"]="43*1";
+w["divid"]="140*3";
+w["divis"]="185*1";
+w["do"]="37*1,135*1";
+w["document"]="1*1,90*1,170*52,171*5,172*3";
+w["document."]="90*1";
+w["doe"]="0*1,51*1,56*1,111*1,131*1,137*1,171*1";
+w["domain"]="73*1,91*3,182*1";
+w["done"]="28*1,29*1,37*1,46*1,47*1,62*1,66*1,67*1,69*1,79*1,90*2,94*1,95*1,97*1,101*1,116*1,138*2";
+w["dor"]="22*1";
+w["down"]="0*1";
+w["dr"]="77*2";
+w["dummi"]="140*3";
+w["dure"]="68*1,78*1,88*1,89*1,96*1,109*1,115*1,116*1,131*4,132*3,135*2,136*2,138*1,140*3,185*1";
+w["dw"]="186*3";
+w["dwen"]="110*1";
+w["e"]="132*2,136*1,153*1,173*1,180*1";
+w["e.g."]="180*1";
+w["earlier"]="1*1";
+w["echo"]="37*1";
+w["edbg"]="0*53,1*55,2*1,3*12,4*1,5*1,6*2,7*1,8*44,9*2,10*1,11*37,12*37,13*1,14*1,15*1,16*1,17*1,18*1,19*1,20*1,21*1,22*1,23*2,24*2,25*2,26*1,27*2,28*1,29*1,30*1,31*1,32*1,33*1,34*1,35*1,36*2,37*2,38*3,39*1,40*1,41*1,42*1,43*1,44*1,45*1,46*1,47*1,48*1,49*1,50*1,51*1,52*1,53*1,54*1,55*1,56*1,57*1,58*1,59*1,60*1,61*1,62*1,63*1,64*1,65*1,66*1,67*1,68*1,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,80*1,81*1,82*1,83*1,84*1,85*1,86*1,87*1,88*1,89*1,90*1,91*1,92*1,93*1,94*1,95*1,96*1,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,122*1,123*1,124*1,125*1,126*1,127*1,128*1,129*1,130*1,131*1,132*1,133*1,134*1,135*1,136*1,137*1,138*1,139*1,140*1,141*1,142*1,143*1,144*1,145*1,146*1,147*1,148*3,149*1,150*1,151*1,152*1,153*1,154*1,155*1,156*1,157*1,158*1,159*1,160*1,161*1,162*1,163*1,164*1,165*1,166*1,167*1,168*1,169*1,170*1,171*152,172*6,173*1,174*1,175*3,176*1,177*1,178*55,179*3,180*3,181*1,182*1,183*1,184*1,185*1,186*7,187*37,188*1,189*1,190*1,191*1,192*1,193*1";
+w["edbg-b"]="3*1";
+w["edbg-bas"]="0*1,1*52,2*1,3*1,4*1,5*1,6*1,7*1,8*1,9*1,10*1,11*1,12*1,13*1,14*1,15*1,16*1,17*1,18*1,19*1,20*1,21*1,22*1,23*1,24*1,25*1,26*1,27*1,28*1,29*1,30*1,31*1,32*1,33*1,34*1,35*1,36*1,37*1,38*1,39*1,40*1,41*1,42*1,43*1,44*1,45*1,46*1,47*1,48*1,49*1,50*1,51*1,52*1,53*1,54*1,55*1,56*1,57*1,58*1,59*1,60*1,61*1,62*1,63*1,64*1,65*1,66*1,67*1,68*1,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,80*1,81*1,82*1,83*1,84*1,85*1,86*1,87*1,88*1,89*1,90*1,91*1,92*1,93*1,94*1,95*1,96*1,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,122*1,123*1,124*1,125*1,126*1,127*1,128*1,129*1,130*1,131*1,132*1,133*1,134*1,135*1,136*1,137*1,138*1,139*1,140*1,141*1,142*1,143*1,144*1,145*1,146*1,147*1,148*1,149*1,150*1,151*1,152*1,153*1,154*1,155*1,156*1,157*1,158*1,159*1,160*1,161*1,162*1,163*1,164*1,165*1,166*1,167*1,168*1,169*1,170*1,171*51,173*1,174*1,175*1,176*1,177*1,178*1,179*2,180*1,181*1,182*1,183*1,184*1,185*1,186*1,187*1,188*1,189*1,190*1,191*1,192*1,193*1";
+w["edbg-specif"]="3*1,8*41";
+w["edbg."]="0*2,38*1,172*1";
+w["edbg@atmel"]="172*1";
+w["edbg@atmel.com"]="172*1";
+w["edbg_config_board_nam"]="186*1";
+w["edbg_config_board_typ"]="186*1";
+w["edbg_config_dgi_gpio_map"]="186*1";
+w["edbg_config_extension_curr"]="186*1";
+w["edbg_config_extension_manufactur"]="186*1";
+w["edbg_config_extension_map"]="186*1";
+w["edbg_config_extension_max_voltag"]="186*1";
+w["edbg_config_extension_min_voltag"]="186*1";
+w["edbg_config_extension_product"]="186*1";
+w["edbg_config_extension_revis"]="186*1";
+w["edbg_config_extension_seri"]="186*1";
+w["edbg_config_extension_status"]="186*1";
+
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-2.js b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-2.js
new file mode 100644
index 000000000..b929f20ac
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-2.js
@@ -0,0 +1,850 @@
+//Auto generated index for searching by xsl-webhelpindexer for DocBook Webhelp.# Kasun Gajasinghe, University of Moratuwa
+w["edbg_config_family_nam"]="186*1";
+w["edbg_config_interfac"]="186*1";
+w["edbg_config_kit_data"]="186*1";
+w["edbg_config_manufacturer_nam"]="186*1";
+w["edbg_config_serial_numb"]="186*1";
+w["edbg_config_target_chipid"]="186*1";
+w["edbg_config_target_jtagid"]="186*1";
+w["edbg_config_target_nam"]="186*1";
+w["edbg_config_target_signatur"]="186*1";
+w["edbg_config_tv"]="186*1";
+w["edbg_config_usb_id"]="186*1";
+w["edbg_config_vers"]="186*1";
+w["edbg_config_version_minor"]="186*1";
+w["edbg_configtype_array"]="186*1";
+w["edbg_configtype_bit"]="186*1";
+w["edbg_configtype_char"]="186*1";
+w["edbg_configtype_short"]="186*1";
+w["edbg_configtype_str"]="186*1";
+w["edbg_configtype_word"]="186*1";
+w["edbg_context_config0"]="186*1";
+w["edbg_context_config1"]="186*1";
+w["edbg_context_control"]="186*1";
+w["edbg_control_ext_prog"]="186*1";
+w["edbg_control_led_usag"]="186*1";
+w["edbg_control_target_pow"]="186*1";
+w["edbg_ctrl"]="38*1";
+w["edbg_ctrl_ext_prog"]="30*1";
+w["edbg_ctrl_led_usag"]="30*1";
+w["edbg_ctrl_target_pow"]="30*1";
+w["edbg_ctxt_ctrl"]="30*1";
+w["edbg_failed_flash_writ"]="186*1";
+w["edbg_failed_illegal_act"]="186*1";
+w["edbg_failed_illegal_flag"]="186*1";
+w["edbg_failed_illegal_frequ"]="186*1";
+w["edbg_failed_illegal_gpio_mod"]="186*1";
+w["edbg_failed_illegal_gpio_pin"]="186*1";
+w["edbg_failed_illegal_interv"]="186*1";
+w["edbg_failed_illegal_max_threshold"]="186*1";
+w["edbg_failed_illegal_min_threshold"]="186*1";
+w["edbg_failed_illegal_mod"]="186*1";
+w["edbg_failed_illegal_voltage_rang"]="186*1";
+w["edbg_failed_not_support"]="186*1";
+w["edbg_failed_ok"]="186*1";
+w["edbg_failed_overflow"]="186*1";
+w["edbg_failed_unknown"]="186*1";
+w["edbg_get"]="11*1";
+w["edbg_if_cdc"]="186*1";
+w["edbg_if_dbg_armjtag"]="186*1";
+w["edbg_if_dbg_avrjtag"]="186*1";
+w["edbg_if_dbg_aw"]="186*1";
+w["edbg_if_dbg_dw"]="186*1";
+w["edbg_if_dbg_en"]="186*1";
+w["edbg_if_dbg_isp"]="186*1";
+w["edbg_if_dbg_pdi"]="186*1";
+w["edbg_if_dbg_swd"]="186*1";
+w["edbg_if_dgi_gpio"]="186*1";
+w["edbg_if_dgi_spi"]="186*1";
+w["edbg_if_dgi_twi"]="186*1";
+w["edbg_if_dgi_uart"]="186*1";
+w["edbg_if_dgi_usart"]="186*1";
+w["edbg_if_erase_pin"]="186*1";
+w["edbg_query_command"]="186*1,187*1";
+w["edbg_rsp_data"]="34*1";
+w["edbg_rsp_fail"]="35*1";
+w["edbg_rsp_list"]="33*1";
+w["edbg_rsp_ok"]="32*1";
+w["edbg_set"]="12*1";
+w["edbgcommand"]="186*1";
+w["edbgconfigtag"]="186*1";
+w["edbgconfigtyp"]="186*1";
+w["edbgcontrolcontextparamet"]="186*1";
+w["edbgctrl"]="11*1,12*1,178*1,186*47";
+w["edbgfailurecod"]="186*1";
+w["edbginterfac"]="186*1";
+w["edbgquerycontext"]="186*1";
+w["edbgrespons"]="186*1";
+w["edbgsetgetcontext"]="186*1";
+w["edg"]="61*2";
+w["eear"]="185*8";
+w["eearh"]="185*2";
+w["eearh_addr"]="185*2";
+w["eearl"]="185*2";
+w["eearl_addr"]="185*2";
+w["eecr"]="185*2";
+w["eecr_addr"]="185*2";
+w["eedr"]="185*2";
+w["eedr_addr"]="185*2";
+w["eeprom"]="111*2,131*1,132*2,133*2,140*15,141*2,148*1,150*42,151*42,160*6,185*7";
+w["eeprom_base_addr"]="133*2,185*1";
+w["eeprom_page_s"]="185*3";
+w["eeprom_s"]="185*3";
+w["effici"]="131*1";
+w["effort"]="172*1";
+w["eg"]="135*1";
+w["eg:"]="135*1";
+w["element"]="88*1,135*1";
+w["els"]="68*1";
+w["embed"]="0*2,172*2,178*1";
+w["embedded."]="0*1,172*1,178*1";
+w["ement"]="139*1";
+w["ement-level"]="139*1";
+w["empti"]="140*3";
+w["enabl"]="30*6,50*1,51*3,140*9,171*1,175*1,180*1,185*2";
+w["encod"]="18*1,19*1";
+w["encount"]="115*1";
+w["end"]="48*1,49*36,112*1,135*1,148*1";
+w["endian"]="173*2";
+w["endian."]="180*1";
+w["endpoints."]="0*1";
+w["enough"]="18*1,19*1,140*3";
+w["ensur"]="89*1,136*1,147*1";
+w["enter"]="60*1,63*3,92*1,99*1,108*47,140*3,141*1,145*52,160*3,161*1,162*52,185*2";
+w["enter_progmod"]="175*1,180*1";
+w["entered."]="185*1";
+w["enterprogmod"]="145*2";
+w["entir"]="79*1,112*1,140*3";
+w["enum"]="43*5,63*12,91*12,140*18,160*2,186*13";
+w["envelop"]="3*5,4*3,22*46,23*2,24*1,25*1,177*1";
+w["equival"]="136*1";
+w["equivalent."]="90*1";
+w["eras"]="3*1,5*1,6*42,64*2,71*42,79*50,91*12,92*2,111*54,116*48,133*3,139*2,140*39,141*1,147*53,160*3,161*1,165*62,169*3";
+w["erase."]="79*1";
+w["erase:"]="139*1";
+w["erase_pin"]="3*1,6*2";
+w["erasedelay"]="147*2";
+w["erasedelay."]="147*1";
+w["error"]="13*1,14*1,16*1,17*1,18*3,19*3,37*2,43*3,52*1,62*1,63*12,91*36,115*1,131*5,132*17,140*21,159*2,160*15,169*3,172*1";
+w["error_overflow"]="186*1";
+w["error_receiv"]="186*1";
+w["es"]="59*1";
+w["es."]="59*1";
+w["especi"]="185*1";
+w["essenti"]="148*1";
+w["estoppel"]="171*1";
+w["etc"]="62*1,137*1";
+w["etc."]="62*1,137*1";
+w["even"]="24*1,171*1,185*1";
+w["event"]="3*1,4*1,22*48,25*47,44*1,58*44,59*45,60*44,61*43,63*9,101*1,102*1,104*1,105*1,109*1,128*48,129*48,130*43,139*1,140*4,160*1,169*1,171*1,174*1,177*1,185*1,188*2";
+w["event:"]="58*3,59*36,60*36,61*36,128*2,129*41,130*41";
+w["events."]="49*1";
+w["everi"]="24*1";
+w["evt_avr8_break"]="129*1,140*1";
+w["evt_avr8_idr"]="130*1,140*1";
+w["evt_housekeeping_ext_reset"]="61*1,63*1";
+w["evt_housekeeping_pow"]="59*1,63*1";
+w["evt_housekeeping_sleep"]="60*1,63*1";
+w["exact"]="131*1";
+w["exampl"]="89*1,114*1,136*2,185*1";
+w["except"]="171*1";
+w["exclus"]="62*1";
+w["execut"]="27*1,32*1,35*1,40*1,42*1,43*3,45*1,54*1,57*1,62*1,63*3,65*1,81*1,86*1,91*6,93*1,102*1,103*1,104*1,123*1,127*1,137*1,138*3,139*1,140*6,145*1,159*2,168*2";
+w["execute."]="137*1";
+w["executed."]="119*1,120*1,138*1";
+w["exist"]="85*1";
+w["exists:"]="85*1";
+w["exit"]="60*1,109*1";
+w["expect"]="37*1,89*1,136*1";
+w["expected."]="89*1,136*1";
+w["explicit"]="78*1";
+w["express"]="171*2";
+w["extend"]="129*1,172*1";
+w["extern"]="30*3,51*2,58*1,61*39,63*9,68*2,89*3,91*3,96*2,136*3";
+w["extract"]="175*1";
+w["fact"]="34*1,56*1,85*1,126*1";
+w["factor"]="185*1";
+w["fail"]="6*1,9*1,10*1,27*1,28*1,29*1,31*1,35*42,37*1,39*1,40*1,42*42,43*3,45*1,46*1,47*1,49*1,50*1,51*1,52*1,53*1,57*37,63*9,65*1,66*1,67*1,68*2,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,80*1,86*42,89*1,91*3,93*1,94*1,95*1,96*2,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,122*1,127*42,140*18,160*3,168*1,188*1";
+w["failed."]="89*1,136*1";
+w["failur"]="35*2,37*1,42*2,43*6,57*2,78*1,86*2,91*4,127*2,139*1,140*7,160*1,169*1,186*4";
+w["failure_ok"]="43*1";
+w["failure_unknown"]="43*1";
+w["failure_usb_previous_underrun"]="37*1,43*1";
+w["fall"]="61*1";
+w["famili"]="0*1,51*1,139*1,140*3,185*1";
+w["families."]="0*1";
+w["family."]="111*1";
+w["far"]="175*1";
+w["fast"]="18*1,19*1";
+w["featur"]="37*2,38*1,91*3,140*3";
+w["fell"]="63*3";
+w["few"]="43*3,91*3,140*3";
+w["field"]="6*2,9*3,10*2,13*2,14*2,15*2,16*2,17*2,18*2,19*2,20*2,21*2,23*3,24*2,25*2,27*1,28*2,29*2,32*1,33*1,34*1,35*1,37*5,38*2,40*1,41*1,42*1,45*1,46*2,47*2,49*1,50*1,51*1,52*1,54*1,55*1,56*1,57*1,59*1,60*1,61*1,65*1,66*2,67*2,68*1,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,81*1,82*1,83*1,84*1,85*2,86*1,93*1,94*2,95*2,96*1,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,123*1,124*1,125*1,126*1,127*1,129*1,130*1,142*2,143*2,144*2,145*2,146*2,147*2,148*2,149*2,152*2,153*2,162*2,163*2,164*2,165*2,166*2,167*2,180*1,188*1";
+w["fifo"]="114*1";
+w["file"]="91*4,135*1,140*4,148*1,160*1,169*1,175*1,181*2,186*1";
+w["filter"]="131*2,132*1";
+w["finish"]="147*1";
+w["firmwar"]="1*1,48*1,50*36,63*12,149*1,193*3";
+w["firmware."]="149*1";
+w["first"]="9*1,15*2,18*1,19*1,20*1,23*1,24*1,25*1,37*3,77*1,79*1,112*1,115*2,140*3,142*1,148*1,149*1";
+w["first."]="173*2";
+w["fit"]="171*1";
+w["fix"]="39*1,60*1";
+w["flag"]="79*1,109*4";
+w["flash"]="79*7,91*18,111*1,112*2,116*1,119*1,120*1,131*6,132*6,133*4,139*1,140*12,141*2,148*58,149*53,150*1,151*1,160*6,181*2,182*3,185*9";
+w["flash."]="112*1,131*1";
+w["flash_bas"]="185*2";
+w["flash_byt"]="185*2";
+w["flash_page_byt"]="185*3";
+w["fli"]="135*1";
+w["flow"]="119*1,120*1,134*1,139*44";
+w["foll"]="175*1";
+w["follow"]="24*1,38*1,88*1,89*1,115*1,135*1,136*1,138*1,139*1,148*1";
+w["forgotten"]="121*1";
+w["form"]="190*1";
+w["format"]="9*6,32*5,33*5,34*5,35*5,37*16,38*1,41*5,42*5,49*5,50*5,51*5,52*5,54*5,55*5,56*5,57*5,59*5,60*5,61*5,68*5,69*5,70*5,71*5,72*5,74*5,75*5,76*5,77*5,78*5,79*5,81*5,82*5,83*5,84*5,85*10,86*5,96*5,97*5,98*5,99*5,100*5,101*5,102*5,103*5,104*5,105*5,106*5,107*5,108*5,109*5,110*5,111*5,112*5,113*5,114*5,115*5,116*5,117*5,118*5,119*5,120*5,121*5,123*5,124*5,125*5,126*5,127*5,129*5,130*5,136*7,142*10,143*5,144*5,145*5,146*5,147*5,148*5,149*5,152*5,153*5,162*5,163*5,164*5,165*5,166*5,167*5,188*5";
+w["format."]="38*2";
+w["forth"]="171*1";
+w["forward"]="37*2,192*1";
+w["forwarding."]="192*1";
+w["found"]="2*1,51*1";
+w["fragment"]="23*4,24*1";
+w["fragmentcod"]="23*1";
+w["fragmentinfo"]="23*1,24*2";
+w["frame"]="18*1,19*1,37*62,38*2,176*1";
+w["free"]="3*1";
+w["freeli"]="135*1";
+w["frequenc"]="88*1,143*1,144*1,182*1,185*8";
+w["frequency."]="60*1";
+w["from"]="0*1,1*1,7*1,13*1,14*1,18*1,24*1,25*1,37*2,60*1,69*1,70*1,89*2,91*6,97*1,98*1,113*1,120*1,130*2,131*3,133*13,135*1,136*3,139*1,140*3,148*1,149*2,151*1,153*1,167*3,175*2,185*3";
+w["front"]="135*1";
+w["front-end"]="135*1";
+w["full"]="23*1,24*1,131*2,132*6,133*6,181*2";
+w["functi"]="0*1";
+w["function"]="3*1,24*1,36*1,37*2,38*1,39*1,43*3,62*2,90*1,91*3,111*1,135*1,137*1,138*1,139*2,140*6,175*1,185*1";
+w["function."]="138*1";
+w["function:"]="135*1";
+w["functionality."]="62*1";
+w["functionl"]="111*1";
+w["functions."]="3*1";
+w["further"]="2*1,50*1";
+w["fuse"]="110*1,132*2,133*1,138*1,140*3,141*2,152*52,153*52,154*1,155*1,156*1,157*1,160*6,185*1";
+w["fuse_base_addr"]="133*1,185*1";
+w["futur"]="1*1";
+w["fw"]="1*2";
+w["fwrev_maj"]="193*1";
+w["fwrev_min"]="193*1";
+w["g"]="52*1,89*1,138*1,180*1";
+w["gain"]="6*1,89*1,136*1";
+w["gateway"]="0*1,1*1";
+w["general"]="37*3,133*1,175*1";
+w["generat"]="60*1,105*1";
+w["generic"]="43*3,171*2,173*51,174*52";
+w["get"]="3*1,8*2,9*41,11*36,18*41,19*41,20*41,26*1,28*1,29*48,30*41,44*2,46*2,47*48,63*3,64*2,66*2,67*49,70*41,88*1,91*3,92*2,94*2,95*49,98*41,135*1,136*1,140*3,141*1,144*51,182*41,185*41,192*3,193*46";
+w["get_buffer_s"]="20*2";
+w["get_config"]="3*1,9*2";
+w["get_data"]="18*2";
+w["get_id"]="89*1";
+w["get_request"]="3*1";
+w["get_status"]="19*2";
+w["given"]="3*1,38*1,83*1,91*3,104*1,136*1,140*3,185*1";
+w["gone"]="59*1";
+w["gpio"]="186*3";
+w["grant"]="171*1";
+w["ground"]="182*1";
+w["had"]="43*3";
+w["half"]="181*1";
+w["half-word"]="181*1";
+w["halt"]="64*1,72*43";
+w["handl"]="148*1,149*1";
+w["handler"]="37*11,38*2,39*1,43*3,62*1,175*1,180*1,190*1";
+w["handler."]="62*1";
+w["hardwar"]="13*1,20*1,21*1,63*3,91*6,92*2,117*45,118*45,139*2,159*1,192*1,193*1";
+w["hardware."]="15*1,20*1,21*1";
+w["header"]="91*1,140*1,160*1,169*1,186*1";
+w["heavili"]="131*1,132*1";
+w["held"]="137*2";
+w["help"]="51*1";
+w["here"]="1*3,3*1,9*1,136*1,172*1";
+w["here."]="1*3,172*1";
+w["here:"]="3*1,9*1,136*1";
+w["herein"]="171*1";
+w["herein."]="171*1";
+w["hhb"]="3*1,10*1";
+w["hid"]="0*1,13*2,23*1";
+w["high"]="6*1,63*3,148*1,149*1";
+w["hint"]="44*1,62*41,87*46,134*46,173*1,174*1";
+w["hk"]="38*1";
+w["hk_context_analog"]="63*1,193*1";
+w["hk_context_config"]="63*1,193*1";
+w["hk_query_command"]="63*1,189*1";
+w["hold"]="101*1,135*1";
+w["host"]="0*1,13*2,37*3,88*1,89*1,90*1,130*1,135*2,136*1,188*1";
+w["host."]="130*1";
+w["housekeep"]="38*2,44*51,48*41,53*41,62*6,63*41,176*1,189*41,193*41";
+w["housekeeping_analog_vtref"]="63*1";
+w["housekeeping_awak"]="63*1";
+w["housekeeping_config_build"]="63*1";
+w["housekeeping_config_fwrev_maj"]="63*1";
+w["housekeeping_config_fwrev_min"]="63*1";
+w["housekeeping_config_hwrev"]="63*1";
+w["housekeeping_failed_invalid_key"]="63*1";
+w["housekeeping_failed_invalid_paramet"]="63*1";
+w["housekeeping_failed_invalid_parameter_valu"]="63*1";
+w["housekeeping_failed_jtag_detect_jtagm_error"]="63*1";
+w["housekeeping_failed_jtag_detect_jtagm_init_error"]="63*1";
+w["housekeeping_failed_jtag_detect_no_devic"]="63*1";
+w["housekeeping_failed_jtag_detect_too_many_devic"]="63*1";
+w["housekeeping_failed_no_target_pow"]="63*1";
+w["housekeeping_failed_not_support"]="63*1";
+w["housekeeping_failed_ok"]="63*1";
+w["housekeeping_failed_osccal_fail"]="63*1";
+w["housekeeping_failed_osccal_fw_error"]="63*1";
+w["housekeeping_failed_osccal_invalid_mod"]="63*1";
+w["housekeeping_failed_osccal_invalid_phys"]="63*1";
+w["housekeeping_power_off"]="63*1";
+w["housekeeping_power_on"]="63*1";
+w["housekeeping_reset_appli"]="63*1";
+w["housekeeping_reset_releas"]="63*1";
+w["housekeeping_sleep"]="63*1";
+w["how"]="148*1,185*1,192*2";
+w["howev"]="22*1,137*1";
+w["hwrev"]="193*1";
+w["ice"]="1*1";
+w["id"]="3*1,4*1,9*2,10*1,27*1,28*3,29*3,30*1,32*1,33*1,34*1,35*1,37*14,38*3,39*1,40*1,41*1,42*1,43*41,44*1,45*1,46*2,47*2,49*1,50*1,51*2,52*1,54*1,55*1,56*1,57*1,59*1,60*1,61*1,63*41,64*1,65*1,66*2,67*2,68*3,69*1,70*52,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,80*1,81*1,82*1,83*45,84*1,85*2,86*1,89*3,91*53,92*1,93*1,94*2,95*2,96*2,97*1,98*49,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,123*1,124*1,125*1,126*1,127*1,129*1,130*1,131*1,132*1,133*1,136*6,140*53,142*2,143*2,144*2,145*2,146*2,147*2,148*2,149*2,152*2,153*2,160*47,162*2,163*2,164*3,165*2,166*2,167*2,169*47,173*1,174*1,175*1,178*1,180*1,181*1,182*1,184*1,185*1,186*47,187*1,188*1,189*1,190*1,191*1,193*1";
+w["ident"]="150*1,151*1,154*1,155*1,156*1,157*1";
+w["identifi"]="37*2";
+w["idr"]="128*1,130*47,140*3,185*1";
+w["ie"]="24*1,25*1";
+w["ie:"]="24*1,25*1";
+w["if"]="30*2,37*1,51*2,68*2,78*1,79*1,89*1,96*4,109*3,121*1,131*4,132*10,135*1,136*2,137*3,138*2,148*3,171*1,185*4";
+w["ignor"]="24*1,25*1,111*1,165*1,166*1";
+w["ignored."]="24*1,25*1,111*1";
+w["illeg"]="91*3,140*15";
+w["immedi"]="102*1,121*1,138*1,139*1";
+w["immediately."]="121*1";
+w["implement"]="0*4,1*56,38*2,59*1,91*3,114*1,140*3,153*1,158*1,175*1,179*1,180*1,192*1";
+w["implementation."]="158*1,175*2";
+w["implent"]="63*3";
+w["impli"]="89*1,136*1,171*3";
+w["implicit"]="69*1,97*1,136*1";
+w["inabl"]="171*1";
+w["incident"]="171*1";
+w["includ"]="62*1,91*1,140*1,160*1,169*1,171*2,175*1,186*1";
+w["incom"]="14*1,37*2";
+w["incorrect"]="91*6,135*1";
+w["increas"]="140*3";
+w["increment"]="37*2";
+w["independ"]="37*1,62*1";
+w["index"]="181*2";
+w["indic"]="23*1,24*1,25*1,34*1,56*1,59*1,60*1,61*1,79*1,85*1,126*1,129*1,139*1,148*2,153*1,182*1";
+w["indirect"]="171*1";
+w["ineffici"]="131*1";
+w["info"]="63*3,91*3,129*1";
+w["inform"]="2*1,9*1,18*1,19*1,135*1,171*3";
+w["information."]="9*1,18*1,19*1,39*1,135*1";
+w["infringement."]="171*1";
+w["init"]="63*3,91*6";
+w["initialis"]="63*3,140*3,164*1,185*1";
+w["initiated."]="105*1";
+w["input"]="0*1";
+w["insert"]="119*2,139*1";
+w["instanc"]="35*1,42*1,57*1,86*1,127*1";
+w["instruct"]="74*1,78*1,91*3,105*1,139*3,148*1";
+w["instruction-level"]="139*1";
+w["insuffici"]="91*3";
+w["intellectu"]="171*1";
+w["intend"]="1*1,171*2,172*1";
+w["intent"]="140*3";
+w["interact"]="172*1";
+w["interfac"]="0*53,1*2,22*1,23*1,30*3,62*3,68*3,69*1,88*2,89*1,91*6,96*4,97*1,110*1,131*1,135*2,136*2,140*9,153*2,164*1,175*1,179*1,180*1,182*1,192*1";
+w["interface."]="68*1,96*1,110*1,131*1,180*1";
+w["interface:"]="88*1";
+w["interfaces:"]="0*1";
+w["intern"]="63*3,91*3,104*1,170*1,185*1";
+w["interrog"]="39*1";
+w["interrupt"]="171*1,185*1";
+w["interv"]="185*1";
+w["into"]="38*1,77*1,78*1,105*1,137*2,138*1,139*1,148*2,150*1,166*1";
+w["introduct"]="171*1,179*51";
+w["invalid"]="91*9,140*6";
+w["invok"]="50*1";
+w["io"]="131*1,132*1,140*3";
+w["ir"]="77*1,78*1,136*1,182*2,185*2";
+w["ir-bit"]="182*2,185*2";
+w["ir."]="78*1";
+w["ire"]="109*1";
+w["isp"]="171*1,175*52,186*3";
+w["isprotect"]="78*1";
+w["iss"]="148*1";
+w["issu"]="24*1,148*1";
+w["issued."]="24*1";
+w["it"]="38*1,39*1,171*1";
+w["ite"]="137*1";
+w["item"]="43*3,63*3,91*3,140*3";
+w["iter"]="15*1";
+w["itm"]="7*1";
+w["itself"]="1*1,23*1,131*1,185*3";
+w["itself."]="131*1";
+w["jtag"]="1*6,38*2,48*1,51*41,62*3,63*6,77*1,78*1,88*4,90*1,91*30,111*1,116*1,117*1,118*1,132*46,136*4,140*21,180*1,182*3,183*1,185*35,192*1";
+w["jtag."]="51*1,136*1,180*1";
+w["jtag_clock"]="88*1";
+w["jtag_clock:"]="88*1";
+w["jtag_daisi"]="88*1";
+w["jtag_daisy:"]="88*1";
+w["jtagice3"]="1*3,174*1";
+w["jtagice3discoveri"]="43*1";
+w["jtagice3discoverycommand"]="43*1";
+w["jtagice3discoveryfailurecod"]="43*1";
+w["jtagice3discoveryrespons"]="43*1";
+w["jtagice3failurecod"]="43*1";
+w["jtagice3housekeepinganalogcontextparamet"]="63*1";
+w["jtagice3housekeepingcommand"]="63*1";
+w["jtagice3housekeepingconfigcontextparamet"]="63*1";
+w["jtagice3housekeepingev"]="63*1";
+w["jtagice3housekeepingfailurecod"]="63*1";
+w["jtagice3housekeepingpowerev"]="63*1";
+w["jtagice3housekeepingquerycontext"]="63*1";
+w["jtagice3housekeepingresetev"]="63*1";
+w["jtagice3housekeepingrespons"]="63*1";
+w["jtagice3housekeepingsetgetcontext"]="63*1";
+w["jtagice3housekeepingsleepev"]="63*1";
+w["jtagice3setgetfailurecod"]="63*1";
+w["jtagid"]="68*1,70*1";
+w["jtagm"]="63*3,140*9";
+w["k"]="96*1";
+w["kbit"]="143*1,144*1";
+w["kbps"]="182*1";
+w["keep"]="140*3,172*1";
+w["keil"]="0*1,2*1";
+w["key"]="50*2,63*3";
+w["khz"]="52*1,88*1,182*1,185*4";
+w["kit"]="1*1,172*1";
+w["l"]="171*1,182*1";
+w["l."]="182*1";
+w["larg"]="23*1";
+w["last"]="112*1,148*1";
+w["later"]="1*1";
+w["layer"]="37*1";
+w["le"]="192*1";
+w["least"]="37*3,173*1";
+w["leav"]="90*1,92*1,109*47,136*1,137*1,140*3,141*1,146*52,148*1,160*3,161*1,163*52";
+w["leave."]="109*1";
+w["leave_progmod"]="175*1,180*1";
+w["led"]="30*3,91*3";
+w["legal"]="140*3";
+w["length"]="91*6,96*1,166*1,167*1,180*1";
+w["less"]="185*1";
+w["level"]="74*1,77*1,91*3,101*1,102*1,105*3,139*3,140*6";
+w["liabil"]="171*1";
+w["liabl"]="171*1";
+w["licens"]="171*1";
+w["lie"]="136*1";
+w["life."]="171*1";
+w["limit"]="1*1,171*2,185*3";
+w["line"]="182*2";
+w["line:"]="182*1";
+w["ling"]="110*1";
+w["link"]="0*1";
+w["list"]="1*1,27*2,28*1,29*1,31*1,33*42,38*1,39*1,40*2,41*42,43*6,45*2,46*1,47*1,51*1,53*1,55*37,63*6,65*2,66*1,67*1,80*1,82*42,91*18,93*2,94*1,95*1,119*1,120*1,122*1,124*42,140*15,184*8,187*2,189*2,190*2,191*8";
+w["littl"]="90*1,173*1";
+w["load"]="141*1,142*52,148*4,160*3";
+w["locat"]="104*1,114*5,171*1";
+w["location."]="104*1";
+w["lock"]="91*3,140*3,141*2,154*42,155*42,160*6,185*1";
+w["lockbit"]="132*2,133*1,165*1";
+w["lockbit_base_addr"]="133*1,185*1";
+w["logo"]="171*1";
+w["longer"]="1*1,110*1";
+w["loop"]="145*1";
+w["loss"]="171*2";
+w["low"]="63*3,74*1,77*1,91*3,139*1,140*3,148*1,149*1,182*1";
+w["low-level"]="91*3,139*1";
+w["lower"]="159*1";
+w["lowest"]="173*1";
+w["lsb"]="77*1";
+w["ltd"]="171*1";
+w["ltd."]="171*1";
+w["m"]="23*3,24*2";
+w["made"]="172*1";
+w["main"]="38*2,101*1,140*3,185*1";
+w["maintain"]="185*1";
+w["major"]="193*1";
+w["make"]="68*1,89*1,96*1,136*1,171*3";
+w["mal"]="132*1";
+w["mal-align"]="132*1";
+w["mani"]="63*3,89*1,91*3,136*1,140*3";
+w["manner"]="25*1";
+w["manual"]="62*1";
+w["manufactur"]="43*3,51*1,190*1";
+w["map"]="11*1,12*1,91*3";
+w["market"]="135*1";
+w["mask"]="92*1,114*49,131*1,132*1,140*3";
+w["mask."]="114*1";
+w["master"]="91*15,140*3";
+w["match"]="131*1";
+w["max_sw_break"]="119*1,120*1";
+w["maximum"]="88*1,91*3,182*3";
+w["may"]="36*2,38*1,69*1,97*1,131*3,132*1,135*2,136*2,171*1,188*1";
+w["mcu"]="130*1,140*6,171*101";
+w["mean"]="24*1,148*1,173*1";
+w["meanings:"]="148*1";
+w["means."]="104*1";
+w["medbg"]="0*1,1*1";
+w["mega"]="185*5";
+w["mega48"]="135*1";
+w["megaavr"]="38*2,52*1,111*2,116*1,117*2,118*2,132*41,140*12,175*1,183*1,185*33";
+w["memori"]="75*5,76*6,79*2,91*9,92*3,113*46,114*46,115*46,137*1,139*4,140*27,148*10,149*2,150*1,151*1,161*2,166*53,167*54,169*3,174*1,181*37,183*46";
+w["memory-typ"]="139*1";
+w["memory_word_access"]="78*1";
+w["memtyp"]="91*9,131*47,132*46,133*46,140*9,181*5,183*3,184*2,191*2";
+w["memtype_appl_flash"]="133*1,140*1";
+w["memtype_appl_flash_atom"]="133*1,140*1";
+w["memtype_boot_flash"]="133*1,140*1";
+w["memtype_boot_flash_atom"]="133*1,140*1";
+w["memtype_calibration_signatur"]="133*1,140*1";
+w["memtype_eeprom"]="131*1,132*1,133*1,140*1";
+w["memtype_eeprom_atom"]="133*1,140*1";
+w["memtype_eeprom_pag"]="132*1,140*1";
+w["memtype_flash_pag"]="131*1,132*1,140*1";
+w["memtype_fus"]="132*1,133*1,140*1";
+w["memtype_lock_bit"]="133*1";
+w["memtype_lockbit"]="132*1,140*1";
+w["memtype_oscc"]="132*1,140*1";
+w["memtype_regfil"]="133*1,140*1";
+w["memtype_signatur"]="131*1,132*1,133*1,140*1";
+w["memtype_spm"]="131*1,132*1,140*1";
+w["memtype_sram"]="131*1,132*1,133*1,140*1";
+w["memtype_user_signatur"]="132*1,133*1,140*1";
+w["merchant"]="171*1";
+w["messag"]="60*1,128*1,130*49,140*9,185*3";
+w["messages."]="185*1";
+w["method"]="147*1,148*1";
+w["method:"]="147*1";
+w["microcontrol"]="38*1,173*1";
+w["microsoft"]="171*1";
+w["might"]="75*1,76*1";
+w["mini"]="1*1";
+w["minor"]="193*1";
+w["misc"]="63*3";
+w["mismatch"]="140*3";
+w["mkii"]="175*1,180*1";
+w["mkii."]="180*1";
+w["mnf_date"]="190*1";
+w["mode"]="13*54,14*54,50*2,63*6,88*2,91*18,92*2,99*1,105*1,108*47,109*48,111*4,112*1,113*1,114*1,115*1,116*2,117*1,131*1,132*14,133*13,136*1,137*3,138*2,139*3,140*9,141*2,145*52,146*52,148*27,160*6,161*2,162*52,163*52,165*8,166*1,169*3,185*2,192*2";
+w["mode."]="50*1,88*1,113*1,114*1,115*1,132*7,137*1,138*1,148*1,185*3";
+w["modebit"]="148*1";
+w["modifi"]="107*1";
+w["modul"]="91*3,110*2,117*1,118*1,131*1,135*1,138*1,140*6,182*1,185*1";
+w["module."]="117*1,118*1,138*1";
+w["monitor"]="131*1,132*1,138*1";
+w["more"]="7*1,23*1,24*1,37*1,38*1,63*3,132*3";
+w["most"]="173*1";
+w["motor"]="185*1";
+w["mount"]="1*3";
+w["ms"]="145*4,146*2,147*1";
+w["ms."]="185*1";
+w["msb"]="9*1,15*2,18*1,19*1,20*1,23*1,24*1,25*1,142*1,148*1,149*1";
+w["multi"]="141*1,158*41,180*1";
+w["multi-byt"]="180*1";
+w["multipl"]="28*1,29*1,46*1,47*1,66*1,67*1,94*1,95*1,131*1,132*3";
+w["must"]="22*2,23*1,24*3,25*1,52*1,62*2,88*4,89*6,131*2,132*1,135*4,136*5,139*1,140*3,148*3,156*1,157*1,165*1,181*1,182*1,185*2";
+w["mv"]="193*1";
+w["n"]="9*2,10*1,18*1,23*4,24*3,25*1,28*1,33*1,34*1,37*3,41*1,46*1,55*1,56*1,66*1,76*1,77*3,82*1,85*2,94*1,114*1,115*1,119*4,120*4,124*1,126*1,129*1,138*1,148*1,166*1,181*1,184*4,187*1,189*1,190*3,191*4";
+w["nack"]="91*3";
+w["name"]="38*1,43*3,135*1,171*1,185*3,190*1";
+w["name."]="135*1";
+w["nativ"]="0*1,172*1";
+w["natur"]="24*1";
+w["nb"]="132*1";
+w["nb:"]="132*1";
+w["nbsi"]="159*1";
+w["near"]="91*3";
+w["necessari"]="37*1,68*1,96*1,135*1";
+w["necessarili"]="51*1";
+w["need"]="135*2";
+w["new"]="136*1,174*1";
+w["newer"]="174*2";
+w["next"]="23*1,37*1,102*1,119*1,120*1,139*2,142*1";
+w["next."]="23*1";
+w["nexus"]="91*3,181*3";
+w["ng"]="37*1";
+w["nibbl"]="23*1";
+w["no"]="1*1,24*1,25*1,43*3,49*1,50*1,51*1,63*3,68*2,69*1,89*1,91*9,96*2,97*1,110*1,117*1,118*1,136*1,140*6,145*1,171*4,175*1,180*1";
+w["non"]="171*1";
+w["non-infring"]="171*1";
+w["non-infringement."]="171*1";
+w["none"]="182*1";
+w["normal"]="137*1,138*1";
+w["note"]="0*40,1*2,18*1,24*1,28*1,29*1,37*1,46*1,47*1,52*1,56*1,59*1,60*1,66*1,67*1,69*1,75*1,76*1,79*1,88*1,94*1,95*1,97*1,111*3,112*1,115*1,116*1,117*3,118*3,119*1,120*1,135*2,148*1,153*1,175*42,180*1,182*1,185*6,192*1";
+w["note:"]="28*1,29*1,46*1,47*1,56*1,59*1,60*1,66*1,67*1,69*1,79*1,94*1,95*1,97*1,111*3,112*1,115*1,116*1,117*3,118*3,119*1,120*1,148*1,153*1,185*4";
+w["notic"]="171*1,172*1";
+w["notice."]="171*1,172*1";
+w["now"]="60*2,188*1";
+w["ntroller"]="1*1";
+w["number"]="9*2,10*1,18*1,19*1,23*3,24*1,25*1,28*1,29*1,43*3,46*1,47*1,60*1,63*3,66*1,67*1,73*1,75*2,76*2,77*1,79*1,91*9,94*1,95*1,113*1,114*1,115*1,117*2,118*2,131*5,132*4,133*10,145*1,148*1,149*1,166*1,167*1,182*3,190*1,193*1";
+w["numbyt"]="9*1,148*1,149*1";
+w["nvm"]="140*6,185*1";
+w["nvm_base"]="133*1,185*1";
+w["o"]="38*1,96*1";
+w["occur"]="22*1,59*1,63*3,91*3,140*3";
+w["occurred."]="59*1";
+w["ocd"]="117*1,118*1,132*46,135*2,138*1,139*1,140*12,183*1,185*3";
+w["ocd_rev"]="185*2";
+w["ocdr"]="131*1,132*1,185*2";
+w["ocdr_addr"]="185*2";
+w["odd"]="131*1,132*1";
+w["off"]="13*1,14*1,49*1,59*1,62*2,63*3";
+w["offer"]="172*1";
+w["offset"]="185*9";
+w["often"]="185*1";
+w["ok"]="13*1,14*1,16*1,17*1,21*1,28*1,31*1,32*41,46*1,49*1,50*1,52*1,53*1,54*36,63*9,66*1,69*1,71*1,72*1,73*1,76*1,79*1,80*1,81*41,91*6,94*1,96*1,97*1,99*1,100*1,101*1,102*1,103*1,104*1,105*2,107*1,108*1,109*1,110*1,111*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,122*1,123*41,140*6,159*1,160*3,168*1,188*1";
+w["ok."]="34*1,56*1,85*1,126*1";
+w["on"]="0*1";
+w["onc"]="89*1,105*2,136*1";
+w["ondit"]="171*1";
+w["one"]="22*2,24*3,28*1,29*1,38*2,46*1,47*1,66*1,67*1,74*1,91*3,94*1,95*1,131*2,132*5,148*1,153*1,182*1,185*4";
+w["onli"]="1*2,3*1,10*1,13*1,14*1,22*1,24*1,28*1,29*1,39*1,46*1,47*1,66*1,67*1,77*1,94*1,95*1,111*1,112*1,113*1,114*1,115*1,116*2,119*1,120*1,131*1,132*2,133*3,135*1,139*2,140*12,148*3,180*1,181*1,185*4,192*2";
+w["only."]="6*1,9*1,133*3,139*1";
+w["onto"]="188*1";
+w["oper"]="34*1,56*1,85*1,126*1,131*2,132*5,137*1,148*2";
+w["operation."]="78*1,131*2,132*5";
+w["option"]="135*2,140*3,185*2";
+w["option-rel"]="140*3";
+w["options:"]="135*1";
+w["order"]="22*1,37*2,89*2,135*1,136*2,173*1";
+w["origin"]="139*1";
+w["os"]="1*1";
+w["osccal"]="63*3,132*1,141*1,157*43,160*3,185*2";
+w["osccal_addr"]="185*2";
+w["oscil"]="48*1,52*42,63*3,140*3";
+w["oth"]="171*1";
+w["other"]="9*1,10*1,39*1,62*1,89*1,104*1,136*1,165*1,171*4,172*1";
+w["others."]="171*1";
+w["otherwis"]="79*1,171*1";
+w["out"]="19*1,20*1,24*1,63*6,77*1,78*1,89*1,96*1,105*1,131*2,132*1,135*1,136*1,140*12,145*1,153*1,159*3,168*1,171*1,192*1";
+w["out."]="77*1,131*2,132*1";
+w["outlin"]="37*1";
+w["output"]="0*1,7*1,77*1,185*1,192*1";
+w["outsid"]="132*9";
+w["over"]="22*1,24*1,105*1";
+w["overflow"]="91*9";
+w["overridden"]="89*1,136*1";
+w["overrun"]="18*1,19*1";
+w["overview"]="0*46,36*46,38*46,113*1,114*1,115*1,176*2,179*1";
+w["owe"]="175*1";
+w["own"]="38*1,172*2";
+w["p"]="78*1";
+w["packet"]="9*10,10*1,23*6,24*3,25*2,37*6,89*1,91*9,136*1,159*1,168*1";
+w["packet_numb"]="23*1";
+w["page"]="79*5,91*9,92*1,111*4,116*43,131*3,132*7,133*9,140*24,148*21,166*1,181*4,182*2,185*6";
+w["page-eras"]="116*1";
+w["page."]="182*1";
+w["pagebit"]="148*1";
+w["pages."]="132*6";
+w["pair"]="0*3";
+w["paramet"]="9*3,10*1,28*4,29*5,30*41,37*1,38*1,44*1,46*5,47*5,51*1,63*21,66*5,67*6,88*1,91*9,94*5,95*6,111*2,136*1,138*1,140*6,148*1,161*1,164*55,168*1,169*3,175*1,178*1,182*41,184*1,185*41,191*1,193*46";
+w["parameter."]="89*1,136*1";
+w["parameters."]="10*1,38*1,111*1";
+w["paramt"]="28*1,29*1,46*1,47*1,66*1,67*1,94*1,95*1";
+w["pariti"]="140*3";
+w["part"]="1*1,3*1,185*2";
+w["partial"]="91*3";
+w["particular"]="1*1,171*1";
+w["pattern"]="78*1";
+w["payload"]="37*3,38*1,91*6,113*1,114*1,115*2,119*1,120*1,131*1,132*1,175*2,180*2,182*2";
+w["pc"]="0*1,13*1,74*1,80*1,84*42,91*3,92*2,106*43,107*43,122*1,125*42,129*1,139*1,140*12,148*1";
+w["pdi"]="1*4,38*1,136*1,140*12,180*1,185*10,186*3";
+w["peb01"]="78*1";
+w["per"]="114*1,139*1";
+w["perform"]="3*2,51*1,52*1,62*1,71*1,74*1,105*1,111*1,116*1,136*1,139*5,147*1,165*1,192*1";
+w["performed."]="79*1";
+w["period"]="22*1";
+w["phi"]="63*3,140*3";
+w["physic"]="36*1,52*1,62*1,64*2,68*47,69*47,70*1,87*1,88*6,89*46,91*24,92*2,96*47,97*47,98*1,109*1,134*1,135*4,136*48,137*2,138*2,140*27,160*3,168*1,175*1,180*1,182*2,185*1";
+w["physical."]="109*1,182*1,185*1";
+w["physical:"]="135*1";
+w["pid"]="1*1";
+w["pin"]="0*2,3*1,5*1,6*42,7*1,110*2,145*1,159*1,192*2";
+w["pin."]="110*1,192*1";
+w["place"]="88*1,135*1,138*1";
+w["platform"]="1*1";
+w["point"]="137*2";
+w["point."]="89*1,136*1";
+w["pointer"]="114*1";
+w["poll"]="3*2,4*2,22*2,24*1,25*1,60*1,138*2,140*3,145*1,147*1,148*10,185*3";
+w["poll1"]="148*2";
+w["poll2"]="148*2";
+w["pollindex"]="145*2,153*1";
+w["pollindex."]="145*1,153*1";
+w["polling."]="148*1";
+w["pollmethod"]="147*2";
+w["pollmethod."]="147*1";
+w["pollvalu"]="145*2";
+w["pollvalue."]="145*1";
+w["port"]="0*3,1*2";
+w["port."]="0*1";
+w["possi"]="160*1";
+w["possibl"]="91*1,96*1,137*1,140*1,169*1,171*2,185*1,186*1";
+w["possible."]="138*1";
+w["post"]="146*1";
+w["post-delay"]="146*1";
+w["postdelay"]="146*2";
+w["postdelay."]="146*1";
+w["power"]="30*4,58*1,59*39,63*12,91*3,110*1,140*3";
+w["pre"]="146*1";
+w["pre-delay"]="146*1";
+w["predelay"]="146*2";
+w["predelay."]="146*1";
+w["prefac"]="171*1,172*50";
+w["preliminari"]="170*2";
+w["present"]="30*2";
+w["present."]="30*2";
+w["preserv"]="24*1";
+w["prevent"]="114*1,135*1,185*1";
+w["previous"]="43*3,70*1,98*1";
+w["prior"]="172*1";
+w["pro"]="1*1";
+w["process"]="23*1,24*1,89*1,90*1,136*1,138*3";
+w["process."]="89*1,136*1";
+w["prod_sign_base_addr"]="133*1,185*1";
+w["product"]="171*7,185*1";
+w["products."]="171*2";
+w["profit"]="171*1";
+w["prog"]="92*2,108*41,109*42,131*1,132*1,133*1";
+w["program"]="0*3,1*4,22*1,38*5,84*2,87*1,90*42,91*3,107*1,108*1,109*2,111*1,116*1,117*2,125*2,129*2,131*2,132*14,133*11,134*1,135*1,136*1,137*45,138*2,139*3,140*21,141*52,142*1,143*1,144*1,145*53,146*53,148*73,149*2,150*44,151*1,152*53,153*1,154*44,155*1,156*1,157*1,159*46,160*18,161*2,162*53,163*53,166*1,167*1,168*46,172*1,173*1,174*1,175*3,180*3,185*4";
+w["programmin"]="138*1";
+w["programming."]="111*1,148*2";
+w["properti"]="171*1";
+w["proport"]="131*1,132*1";
+w["protect"]="64*1,78*47,91*3";
+w["protocol"]="0*1,1*5,2*48,3*5,4*4,5*1,6*1,7*2,8*1,9*1,10*1,11*2,12*2,13*1,14*1,15*1,16*1,17*1,18*1,19*1,20*1,21*1,22*4,23*1,24*1,25*1,26*47,27*1,28*1,29*1,30*1,31*1,32*1,33*1,34*1,35*1,36*3,37*14,38*50,39*48,40*1,41*1,42*1,43*42,44*47,45*1,46*1,47*1,48*1,49*1,50*1,51*1,52*2,53*1,54*1,55*1,56*1,57*1,58*1,59*1,60*1,61*1,62*4,63*1,64*47,65*1,66*1,67*1,68*1,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,80*1,81*1,82*1,83*1,84*1,85*1,86*1,87*1,88*1,89*1,90*2,91*2,92*47,93*1,94*1,95*1,96*1,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,122*1,123*1,124*1,125*1,126*1,127*1,128*1,129*1,130*1,131*1,132*1,133*1,134*1,135*1,136*1,137*1,138*1,139*2,140*11,141*47,142*1,143*1,144*1,145*1,146*1,147*1,148*1,149*1,150*1,151*1,152*1,153*1,154*1,155*1,156*1,157*1,158*1,159*47,160*8,161*47,162*1,163*1,164*1,165*1,166*1,167*1,168*47,169*1,170*1,171*157,172*3,173*56,174*55,175*62,176*55,177*2,178*54,179*1,180*57,181*1,182*1,183*1,184*2,185*1,186*11,187*2,188*1,189*2,190*2,191*2,192*1,193*1";
+w["protocol-set"]="1*2";
+w["protocol."]="62*1,91*1,140*1,160*1,186*1";
+w["protocol:"]="62*1";
+w["protocols."]="37*1";
+w["provid"]="0*1,7*1,133*12,135*1,139*3,171*2,172*1";
+w["provided."]="165*1";
+w["publish"]="49*1,188*1";
+w["pull"]="182*2";
+w["puls"]="6*1";
+w["punit"]="171*1";
+w["pure"]="109*1";
+w["purpos"]="133*1,135*1,137*1,171*1";
+w["put"]="38*1,75*1,76*1,121*1,138*1,139*1,175*1,180*1";
+w["pwm"]="185*1";
+w["quarter"]="185*1";
+w["queri"]="1*1,26*1,27*47,39*3,40*46,43*9,44*2,45*46,64*1,65*47,88*1,92*1,93*47,135*1,140*3,178*1,184*41,186*3,187*41,189*46,190*46,191*41";
+w["question"]="172*1";
+w["r"]="38*1,131*2,132*3,133*7,182*2,185*1,193*5";
+w["rang"]="63*6,79*1,112*1,132*3,140*6,159*1";
+w["rapid"]="60*1";
+w["rate"]="15*55,18*1,19*1,88*1,143*1,159*1,160*6,182*1,192*1";
+w["rather"]="1*1,135*1";
+w["ratio"]="140*3";
+w["raw"]="192*1";
+w["rdi"]="147*1,148*3,159*1";
+w["re"]="70*1,89*2,98*1,136*1";
+w["re-connect"]="89*1,136*1";
+w["re-read"]="70*1,98*1";
+w["rea"]="148*1";
+w["reach"]="104*1";
+w["read"]="18*1,19*3,20*1,24*1,29*1,34*1,47*1,56*1,62*1,64*1,67*1,70*2,75*43,76*1,85*1,89*2,91*12,92*3,95*1,96*1,98*2,106*47,113*47,114*51,126*1,131*11,132*21,133*10,135*2,136*2,137*1,139*4,140*30,141*6,144*1,148*5,149*55,151*43,153*53,155*43,156*44,157*44,160*21,161*1,167*55,175*1,182*1,192*1,193*1";
+w["read."]="75*1,76*1,148*1";
+w["readabl"]="184*1,191*1";
+w["reading."]="114*1";
+w["reason"]="89*1,136*1";
+w["receiv"]="18*4,19*3,20*1,23*1,24*2,25*1,78*1,91*18,139*1,140*6,145*1";
+w["received."]="78*1";
+w["receiver_dis"]="186*1";
+w["refer"]="52*1,63*3,135*1";
+w["regain"]="110*1";
+w["region"]="79*2";
+w["regist"]="0*1,72*1,73*6,77*2,91*12,131*1,132*1,133*1,140*9,171*3,181*4,185*5";
+w["reject"]="37*1";
+w["rela"]="171*1";
+w["relat"]="63*3,91*9,140*9";
+w["relationship"]="23*1";
+w["relationship:"]="23*1";
+w["relay"]="140*3";
+w["releas"]="61*1,63*3,91*3,109*1,135*1,170*2,182*3";
+w["release."]="170*2";
+w["relev"]="135*2,173*1,178*1";
+w["remov"]="120*1,121*1,139*2";
+w["repetit"]="139*1";
+w["repli"]="115*2";
+w["report"]="37*1,115*1";
+w["report_s"]="23*1";
+w["report_size."]="23*1";
+w["represent"]="171*1";
+w["reprogram"]="138*1";
+w["request"]="8*2,11*36,12*36,15*1,79*2,89*1,91*3,131*3,132*2,136*1";
+w["requir"]="6*1,23*1,24*1,88*1,111*1,135*4,136*1,138*2";
+w["required."]="50*1,135*1";
+w["required:"]="88*1,135*1";
+w["reserv"]="171*1,172*1";
+w["reserved."]="171*1";
+w["reset"]="3*2,49*2,51*4,58*1,61*44,63*9,64*1,68*3,73*49,89*2,91*9,92*1,96*3,101*45,109*1,110*3,135*1,136*3,137*2,139*3,140*6,182*5,185*1";
+w["reset."]="101*1,182*1";
+w["reset:"]="139*1";
+w["resetting."]="185*1";
+w["resourc"]="117*2,118*2,139*1,140*3";
+w["resources."]="117*1,118*1";
+w["respect"]="171*1";
+w["respond"]="23*1";
+w["respons"]="3*1,4*1,6*6,9*6,10*6,13*6,14*6,15*6,16*6,17*6,18*6,19*6,20*6,21*6,22*48,23*1,24*50,25*2,27*1,28*1,29*1,31*46,32*7,33*7,34*7,35*7,37*1,38*1,40*1,41*7,42*7,44*1,45*1,46*1,47*1,49*1,50*1,51*1,52*1,53*41,54*7,55*7,56*7,57*7,65*1,66*1,67*1,68*2,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,80*46,81*7,82*7,83*7,84*7,85*14,86*7,91*7,93*1,94*1,95*1,96*2,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,122*46,123*7,124*7,125*7,126*7,127*7,140*7,142*6,143*6,144*6,145*6,146*6,147*6,148*6,149*6,152*6,153*6,159*52,160*4,162*6,163*6,164*6,165*6,166*6,167*6,168*52,169*1,173*1,174*1,175*2,177*1,178*1,180*2,182*1,184*1,186*7,187*1,188*1,189*1,190*1,191*1";
+w["response."]="22*1,77*1";
+w["response:"]="6*1,9*1,10*1,13*1,14*1,15*1,16*1,17*1,18*1,19*1,20*1,21*1,142*1,143*1,144*1,145*1,146*1,147*1,148*1,149*1,152*1,153*1,162*1,163*1,164*1,165*1,166*1,167*1";
+w["responses."]="25*1";
+w["responses:"]="27*1,28*1,29*1,40*1,45*1,46*1,47*1,49*1,50*1,51*1,52*1,65*1,66*1,67*1,68*1,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,93*1,94*1,95*1,96*1,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,188*1";
+w["rest"]="24*1,25*1";
+w["restor"]="59*1,137*1,139*1";
+w["restrict"]="62*1,75*1,76*1,113*1,114*1,115*2,119*1,120*1,131*1,132*7,133*3,181*1";
+w["result"]="22*1,24*1,37*1,131*1,132*7";
+w["resum"]="72*1,103*1,104*1,140*6";
+w["retaddr"]="153*2";
+w["retri"]="159*1";
+w["retried."]="51*1";
+w["retriev"]="3*1,4*1,9*2,18*2,70*1,89*1,98*1,136*1";
+w["return"]="9*1,33*2,34*3,37*1,41*2,43*3,52*1,55*2,56*3,63*6,68*2,70*1,77*1,78*2,82*2,84*1,85*4,89*2,91*12,96*3,98*1,105*1,124*2,125*1,126*3,131*4,132*10,136*3,139*1,140*9,153*2";
+w["returned."]="34*1,52*1,68*1,85*1,96*2,132*1";
+w["rev."]="171*1";
+w["rev.:"]="171*1";
+w["revis"]="63*9,170*52,171*1,185*2";
+w["right"]="171*3,172*1";
+w["ring"]="153*1";
+w["rise"]="61*1";
+w["risk"]="172*1";
+w["risk."]="172*1";
+w["rout"]="185*1";
+w["routin"]="185*1";
+w["rsp"]="24*1,39*2,41*41,42*41";
+w["rsp:"]="39*2,41*41,42*41";
+w["rsp_avr8_activate_phys"]="96*1";
+w["rsp_avr8_data"]="126*1,140*1";
+w["rsp_avr8_fail"]="127*1,140*1";
+w["rsp_avr8_list"]="140*1";
+w["rsp_avr8_ok"]="123*1,140*1";
+w["rsp_avr8_pc"]="125*1,140*1";
+w["rsp_discovery_fail"]="43*1";
+w["rsp_discovery_list"]="43*1";
+w["rsp_edbg_data"]="186*1";
+w["rsp_edbg_fail"]="186*1";
+w["rsp_edbg_list"]="186*1";
+w["rsp_edbg_ok"]="186*1";
+w["rsp_fail"]="37*1,42*1,140*3,186*3";
+w["rsp_housekeeping_data"]="56*2,63*1";
+w["rsp_housekeeping_fail"]="57*1,63*1";
+w["rsp_housekeeping_failed_with_data"]="63*1";
+w["rsp_housekeeping_list"]="55*1,63*1";
+w["rsp_housekeeping_ok"]="54*1,63*1";
+w["rsp_list"]="41*1";
+w["rt"]="1*1";
+w["rule"]="131*1,132*1,133*1,139*1";
+w["run"]="24*1,89*1,92*2,99*1,103*41,104*42,109*3,135*1,136*1,137*1,138*3,139*3,140*12,182*2,185*6";
+w["run:"]="139*1";
+w["runaway"]="135*1";
+w["runnin"]="52*1";
+w["rw"]="30*3,131*3,132*8,133*10,181*8,182*4,185*1";
+w["rwise"]="171*1";
+
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-3.js b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-3.js
new file mode 100644
index 000000000..88d71a25a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/index-3.js
@@ -0,0 +1,846 @@
+//Auto generated index for searching by xsl-webhelpindexer for DocBook Webhelp.# Kasun Gajasinghe, University of Moratuwa
+w["rx"]="0*1,91*3";
+w["rx-tx"]="0*1";
+w["s"]="7*1,78*1,140*1,143*1,144*1,171*2,173*1,185*2";
+w["sab"]="75*1,76*1,91*18,181*7";
+w["sale"]="171*2";
+w["sam"]="6*1";
+w["sam3"]="1*2";
+w["sam4"]="1*2";
+w["samd"]="1*2";
+w["samd20"]="1*1";
+w["same"]="1*1,22*1,25*1,28*1,29*1,46*1,47*1,60*1,66*1,67*1,70*1,94*1,95*1,98*1";
+w["samp"]="192*1";
+w["sampl"]="14*1,15*1,159*1";
+w["save"]="30*2";
+w["scale"]="0*1";
+w["scaled-down"]="0*1";
+w["scan"]="48*1,51*42,62*2,63*3,77*1";
+w["scan-chain"]="48*1,51*41,62*2";
+w["secion"]="140*3";
+w["section"]="3*2,7*1,27*1,28*1,29*1,37*1,40*1,45*1,46*1,47*1,64*1,65*1,66*1,67*1,75*1,76*1,79*50,88*1,91*1,93*1,94*1,95*1,111*2,112*2,113*1,114*1,115*1,133*16,135*1,140*28,160*1,165*1,169*1,185*4,186*1,192*1";
+w["secured."]="6*1";
+w["see"]="7*1,27*1,28*1,29*1,40*1,45*1,46*1,47*1,65*1,66*1,67*1,75*1,76*1,79*1,88*1,93*1,94*1,95*1,113*1,114*1,115*1,135*1,185*1";
+w["select"]="62*1,68*1,96*1,148*3,149*1,182*1";
+w["selector"]="91*3,140*3";
+w["self"]="38*1";
+w["self-contain"]="38*1";
+w["send"]="4*1,13*1,22*1,23*2,24*1,25*1";
+w["sent"]="14*1,24*1,25*1,37*3,101*1,102*1,104*1,109*1,173*2,175*1,180*1,185*1";
+w["sequenc"]="3*1,37*3,51*1,79*1,89*1";
+w["serial"]="3*1,5*1,7*37,21*1,43*3,177*1,190*1,192*50";
+w["serial_numb"]="190*1";
+w["serial_trac"]="3*1,13*2,14*2,15*2,16*2,17*2,18*2,19*2,20*2,21*2";
+w["serialtracecommand"]="186*1";
+w["serialtraceerrorbit"]="186*1";
+w["serialtracetransportmod"]="186*2";
+w["servic"]="91*6,181*1,185*1";
+w["sessio"]="138*1";
+w["session"]="48*2,49*41,62*1,63*9,88*2,89*3,90*1,91*3,100*1,109*1,131*4,132*2,134*2,135*6,136*5,137*42,138*43,139*1,140*9,188*41";
+w["session-rel"]="91*3,140*3";
+w["session."]="89*1,90*1,109*1,131*3,132*2,135*1,136*1,139*1";
+w["set"]="0*1,1*2,3*2,8*2,10*37,12*36,13*42,14*42,15*42,22*1,26*1,28*48,29*3,30*41,37*2,38*52,44*2,46*49,47*3,63*3,64*1,66*48,67*3,78*1,88*1,89*1,91*24,92*3,94*48,95*3,109*3,117*47,119*47,120*1,135*2,137*1,139*2,140*21,141*1,143*52,148*1,160*3,161*1,164*52,171*1,175*2,176*1,180*1,182*44,185*42,192*3,193*46";
+w["set."]="78*1,109*1,135*1,148*1,182*1";
+w["set_baud"]="15*2";
+w["set_capture_mod"]="14*2";
+w["set_config"]="3*1,10*2";
+w["set_request"]="3*1";
+w["set_transport_mod"]="13*2";
+w["setget_failure_illegal_st"]="63*1";
+w["setget_failure_invalid_clock_spe"]="63*1";
+w["setget_failure_invalid_valu"]="63*1";
+w["setget_failure_jtagm_init_error"]="63*1";
+w["setget_failure_not_impl"]="63*1";
+w["setget_failure_not_support"]="63*1";
+w["setget_failure_ok"]="63*1";
+w["sever"]="59*1,148*1";
+w["shal"]="171*1";
+w["shall"]="171*1";
+w["shift"]="77*5";
+w["short"]="91*3";
+w["short-packet"]="91*3";
+w["should"]="1*1,136*2,138*3,148*2";
+w["sign"]="49*1,62*2,188*1";
+w["signal"]="77*1,91*3,192*1";
+w["signal."]="192*1";
+w["signatur"]="111*1,131*3,132*3,133*3,140*9,141*1,156*43,160*3,185*3";
+w["signature_offset"]="133*1,185*1";
+w["signific"]="37*3,173*2";
+w["signon"]="21*44,192*1";
+w["silicon"]="185*3";
+w["simpl"]="0*1,96*1";
+w["simpli"]="138*1";
+w["sinc"]="153*1";
+w["singl"]="74*1,91*6,105*1,131*1,132*4,139*1,140*12,173*1,174*1";
+w["situat"]="37*1";
+w["size"]="6*2,9*3,10*2,13*2,14*2,15*2,16*2,17*2,18*2,19*2,20*56,21*2,23*3,24*3,25*4,27*1,28*1,29*1,30*1,32*1,33*1,34*1,35*1,37*3,40*1,41*1,42*1,45*1,46*1,47*1,49*1,50*1,51*1,52*1,54*1,55*1,56*1,57*1,59*1,60*1,61*1,65*1,66*1,67*1,68*1,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,81*1,82*1,83*1,84*1,85*2,86*1,91*6,93*1,94*1,95*1,96*1,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,123*1,124*1,125*1,126*1,127*1,129*1,130*1,131*1,142*2,143*2,144*2,145*2,146*2,147*2,148*3,149*2,152*2,153*2,162*2,163*2,164*2,165*2,166*2,167*2,181*2,182*1,185*17,188*1,192*1,193*1";
+w["skip"]="114*2";
+w["slave"]="91*3";
+w["sleep"]="58*1,60*38,63*3";
+w["small"]="131*1";
+w["sof"]="37*3";
+w["softwar"]="92*3,119*42,120*42,121*42,131*2,132*1,139*4,140*9,148*1,172*1";
+w["software."]="148*1";
+w["some"]="6*1,59*1,112*1,114*1,131*1,132*1,185*1,192*1";
+w["someth"]="140*3";
+w["sourc"]="37*2";
+w["space"]="131*1,132*1,133*1";
+w["special"]="0*1,3*1,171*1";
+w["specif"]="3*3,4*44,5*41,8*41,73*1,91*3,135*1,139*2,140*3,171*2,185*1";
+w["specifi"]="73*1,77*1,88*4,89*1,91*3,135*2,136*1,137*2,138*1,148*1";
+w["specific."]="139*1";
+w["specification."]="139*1";
+w["speed"]="140*3,160*3";
+w["spi"]="1*2,38*1,131*1,141*63,142*42,143*42,144*42,145*42,146*42,147*41,148*43,149*42,150*43,151*43,152*42,153*44,154*43,155*43,156*44,157*44,158*41,159*47,175*6,186*3";
+w["spi-bas"]="38*1";
+w["spi."]="175*1";
+w["spi_cmd_chip_eras"]="147*2,160*1";
+w["spi_cmd_enter_progmod"]="145*2,146*1,160*1";
+w["spi_cmd_get_baud"]="144*2,160*1";
+w["spi_cmd_leave_progmod"]="146*1,160*1";
+w["spi_cmd_load_address"]="142*2,160*1";
+w["spi_cmd_program_eeprom"]="150*1,160*1";
+w["spi_cmd_program_flash"]="148*3,160*1";
+w["spi_cmd_program_fus"]="152*2,160*1";
+w["spi_cmd_program_lock"]="154*1,160*1";
+w["spi_cmd_read_eeprom"]="151*1,160*1";
+w["spi_cmd_read_flash"]="149*2,160*1";
+w["spi_cmd_read_fus"]="153*2,160*1";
+w["spi_cmd_read_lock"]="155*1,160*1";
+w["spi_cmd_read_oscc"]="157*1,160*1";
+w["spi_cmd_read_osccal."]="157*1";
+w["spi_cmd_read_signatur"]="156*1,160*1";
+w["spi_cmd_read_signature."]="156*1";
+w["spi_cmd_set_baud"]="143*2,160*1";
+w["spi_multi"]="158*1,175*2";
+w["spi_status_baud_invalid"]="143*1,159*1,160*1";
+w["spi_status_clock_error"]="159*1,160*1";
+w["spi_status_cmd_fail"]="159*1,160*1";
+w["spi_status_cmd_ok"]="142*1,143*1,144*1,145*1,146*1,147*1,148*1,149*2,152*1,153*2,159*1,160*1";
+w["spi_status_cmd_tout"]="145*1,147*1,148*1,159*1,160*1";
+w["spi_status_cmd_unknown"]="159*1,160*1";
+w["spi_status_fail"]="145*1";
+w["spi_status_phy_error"]="159*1,160*1";
+w["spi_status_rdy_bsy_tout"]="148*1,149*1,152*1,153*1,159*1,160*1";
+w["spiprogrammingprotocolcommand"]="160*1";
+w["spiprogrammingprotocolrespons"]="160*1";
+w["spmcr"]="185*2";
+w["spmcr_addr"]="185*2";
+w["sram"]="131*1,132*1,133*1,140*3,185*3";
+w["sram_start"]="185*2";
+w["st_get_buffer_s"]="186*1";
+w["st_get_data"]="186*1";
+w["st_get_status"]="186*1";
+w["st_set_baud"]="186*1";
+w["st_set_capture_mod"]="186*1";
+w["st_set_transport_mod"]="186*1";
+w["st_signon"]="186*1";
+w["st_start"]="186*1";
+w["st_stop"]="186*1";
+w["stabdelay"]="145*2";
+w["stabdelay."]="145*1";
+w["stabil"]="145*1";
+w["stage"]="89*1,136*1";
+w["standalon"]="1*2";
+w["start"]="9*1,16*44,28*1,29*1,46*1,47*1,48*1,63*3,66*1,67*1,79*3,89*1,91*3,94*1,95*1,111*1,112*1,113*1,114*1,115*1,116*1,136*2,137*1,138*2,142*1,145*2,162*1,167*1,175*1,185*4,188*36,192*1";
+w["stat"]="139*1";
+w["state"]="59*1,60*3,61*1,63*3,91*3,110*2,138*1,139*2,140*3,185*2";
+w["state."]="139*1,185*2";
+w["statement"]="105*1";
+w["status"]="6*1,9*1,10*1,13*2,14*2,16*2,17*2,18*3,19*54,34*2,56*3,60*1,61*1,85*2,91*3,126*2,140*6,142*1,143*1,144*1,145*1,146*1,147*1,148*1,149*1,152*1,162*1,163*1,164*1,165*1,166*1,167*1,192*1";
+w["status."]="60*1";
+w["status1"]="149*1,153*1";
+w["status2"]="153*1";
+w["statutori"]="171*1";
+w["step"]="64*1,74*42,91*6,92*1,105*49,139*4,140*3";
+w["step:"]="139*1";
+w["stepping."]="139*1";
+w["still"]="59*1";
+w["stitut"]="79*1";
+w["stk500"]="175*2";
+w["stk500."]="175*1";
+w["stk600"]="180*1";
+w["stop"]="17*44,91*3,92*1,101*3,102*44,109*1,113*1,114*1,115*1,129*1,138*1,139*7,140*9,182*1,185*4,192*1";
+w["stop:"]="139*1";
+w["stopped."]="101*1,102*1";
+w["storag"]="192*1";
+w["store"]="131*2,135*1";
+w["strang"]="140*3";
+w["stream"]="0*1,18*1";
+w["string"]="21*1,190*3";
+w["studio"]="172*1";
+w["studio."]="172*1";
+w["sub"]="36*1,37*7,38*52,176*1";
+w["sub-protocol"]="36*1,37*7,38*1";
+w["sub-protocols."]="37*1";
+w["sub-set"]="38*51,176*1";
+w["subset"]="1*1";
+w["success"]="6*1,9*1,10*1,32*1,54*1,81*1,105*1,123*1,139*1,159*1,160*3";
+w["such"]="37*1,148*1,171*1";
+w["suffix"]="3*1";
+w["suffix."]="10*1";
+w["suitabl"]="171*1";
+w["summari"]="3*6";
+w["supoort"]="21*1";
+w["suppli"]="148*1,156*1,157*1";
+w["supplied."]="148*1,156*1,157*1";
+w["suppo"]="1*1";
+w["support"]="0*4,1*4,15*1,22*1,39*2,62*1,63*9,91*18,111*2,117*2,118*2,139*1,140*12,148*1,158*1,171*1,172*2,175*4,180*1,184*2,187*1,189*1,190*1,191*2";
+w["supported."]="1*1,13*1,14*1,175*2";
+w["supported:"]="139*1";
+w["sustain"]="171*1";
+w["swd"]="1*2,186*3,192*1";
+w["swo"]="7*1,192*1";
+w["symbol"]="102*1";
+w["sync"]="91*3";
+w["synchloop"]="145*2";
+w["synchloops."]="145*1";
+w["synchron"]="22*1,24*1,145*1";
+w["system"]="91*3,181*2";
+w["t"]="0*1";
+w["tabl"]="1*5,3*10,4*5,5*5,6*10,8*5,9*15,10*10,13*10,14*10,15*11,16*10,17*10,18*10,19*10,20*10,21*10,22*5,23*10,24*10,25*10,26*5,27*10,28*5,29*10,30*5,31*5,32*5,33*5,34*5,35*5,37*15,38*6,39*5,40*5,41*5,42*5,44*5,45*5,46*5,47*5,48*5,49*5,50*5,51*5,52*5,53*5,54*5,55*5,56*5,57*5,58*5,59*5,60*5,61*5,64*5,65*10,66*5,67*10,68*5,69*5,70*5,71*5,72*5,73*5,74*5,75*5,76*10,77*5,78*5,79*5,80*5,81*5,82*5,83*5,84*5,85*10,86*5,87*5,92*5,93*10,94*5,95*10,96*5,97*5,98*5,99*5,100*5,101*5,102*5,103*5,104*5,105*5,106*5,107*5,108*5,109*5,110*5,111*5,112*5,113*5,114*5,115*5,116*5,117*5,118*5,119*5,120*5,121*5,122*5,123*5,124*5,125*5,126*5,127*5,128*5,129*5,130*5,131*5,132*5,133*5,134*5,136*5,139*1,141*5,142*10,143*10,144*10,145*10,146*10,147*10,148*15,149*10,152*10,153*10,159*5,161*5,162*10,163*10,164*10,165*15,166*10,167*10,168*5,171*5,173*5,174*5,175*5,176*5,177*5,178*5,179*5,180*5,181*5,182*5,183*5,184*5,185*26,187*5,188*5,189*5,190*5,191*5,192*5,193*5";
+w["tag"]="186*6";
+w["take"]="88*1,131*2,132*1,135*1";
+w["tap"]="64*1,77*43";
+w["target"]="3*2,4*41,5*41,14*1,18*1,30*1,52*2,59*1,60*4,61*1,62*1,63*12,68*1,69*1,70*2,71*1,72*1,73*6,88*1,89*3,91*6,96*1,97*1,98*2,99*1,100*1,101*2,102*2,103*1,104*2,105*1,106*1,107*1,108*1,109*3,110*1,111*2,112*2,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,129*1,130*1,133*12,135*4,136*4,137*4,138*4,139*8,140*9,182*1,185*116,193*1";
+w["target-rel"]="63*3";
+w["target."]="14*1,52*1,69*2,70*2,89*1,97*2,98*2,100*1,102*1,105*1,106*1,107*1,108*1,109*1,111*1,113*1,115*1,116*1,119*1,120*1,136*1,139*2";
+w["targets."]="112*1";
+w["tdo"]="192*1";
+w["temporarili"]="110*1";
+w["term"]="38*1,171*2";
+w["termin"]="63*3,100*1,148*2";
+w["th"]="136*1,192*1";
+w["than"]="1*1,37*1,132*3,135*1,148*1,185*1";
+w["that"]="1*5,18*1,21*1,24*4,25*1,37*1,52*1,75*1,76*1,88*1,89*4,129*1,133*12,135*2,136*6,137*1,139*1,147*1,173*1,175*1,180*1,182*1,185*2,192*1";
+w["their"]="139*1,172*1";
+w["them"]="114*1";
+w["them."]="114*1,121*1";
+w["then"]="37*1,38*1,96*1,115*2";
+w["there"]="37*1";
+w["thereof"]="171*1";
+w["these"]="185*1";
+w["those"]="180*1";
+w["three"]="0*1,22*1";
+w["through"]="131*1";
+w["time"]="131*2,132*1,140*9,145*1,148*3,159*2,168*1,171*1,175*1";
+w["time-out"]="145*1";
+w["time."]="18*1";
+w["timeout"]="91*21,140*6,145*2,160*3";
+w["timeout."]="145*1";
+w["timer"]="140*3,185*3";
+w["ting"]="171*1";
+w["tinyavr"]="38*3,52*1,111*1,117*1,118*1,140*3,175*1,180*2";
+w["tinyocd"]="135*1";
+w["tip"]="44*1,62*41,87*46,134*46,173*1,174*1";
+w["tips:"]="134*46,174*1";
+w["token"]="78*1";
+w["too"]="43*3,63*3,91*6,140*6";
+w["tool"]="0*1,1*55,2*1,3*2,4*1,5*1,6*1,7*1,8*1,9*1,10*1,11*1,12*1,13*2,14*1,15*1,16*1,17*1,18*1,19*1,20*1,21*1,22*2,23*1,24*1,25*1,26*1,27*2,28*2,29*2,30*1,31*1,32*1,33*1,34*1,35*1,36*2,37*3,38*2,39*2,40*2,41*1,42*1,43*10,44*1,45*2,46*2,47*2,48*1,49*4,50*1,51*1,52*1,53*1,54*1,55*1,56*1,57*1,58*1,59*1,60*1,61*1,62*1,63*1,64*1,65*2,66*2,67*2,68*1,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,80*1,81*1,82*1,83*1,84*1,85*1,86*1,87*1,88*1,89*3,90*1,91*1,92*1,93*2,94*2,95*2,96*1,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,122*1,123*1,124*1,125*1,126*1,127*1,128*1,129*1,130*1,131*1,132*1,133*1,134*1,135*2,136*3,137*1,138*1,139*2,140*1,141*1,142*1,143*1,144*1,145*1,146*1,147*1,148*1,149*1,150*1,151*1,152*1,153*1,154*1,155*1,156*1,157*1,158*1,159*1,160*1,161*1,162*1,163*1,164*1,165*1,166*1,167*1,168*1,169*1,170*1,171*51,172*1,173*2,174*2,175*2,176*1,177*1,178*1,179*2,180*2,181*1,182*1,183*1,184*1,185*1,186*1,187*1,188*3,189*1,190*2,191*1,192*4,193*1";
+w["tool."]="27*1,28*1,36*1,37*2,40*1,45*1,49*1,65*1,93*1,139*1,188*1,192*1";
+w["tool.."]="29*1,46*1,47*1,66*1,67*1,94*1,95*1";
+w["tool_nam"]="190*1";
+w["tools."]="3*1,173*1";
+w["total"]="20*1,148*1,149*1";
+w["total_number_of_packet"]="23*1";
+w["tpi"]="1*1,38*2,161*52,162*42,163*42,164*42,165*41,166*42,167*42,168*46,169*6,171*1,180*56";
+w["tpi_cmd_enter_progmod"]="162*2,169*1";
+w["tpi_cmd_eras"]="165*2,169*1";
+w["tpi_cmd_erase_chip"]="165*1";
+w["tpi_cmd_leave_progmod"]="163*2,169*1";
+w["tpi_cmd_read_mem"]="167*2,169*1";
+w["tpi_cmd_set_param"]="164*2,169*1";
+w["tpi_cmd_write_mem"]="166*2,169*1";
+w["tpi_erase_app"]="165*2,169*1";
+w["tpi_erase_chip"]="165*2,169*1";
+w["tpi_erase_chip."]="165*1";
+w["tpi_erase_config"]="165*2,169*1";
+w["tpi_mem_type_appl"]="166*1,167*1,169*1";
+w["tpi_mem_type_fus"]="166*1,167*1,169*1";
+w["tpi_mem_type_lockbit"]="166*1,167*1,169*1";
+w["tpi_param_nvmcmd_addr"]="169*1";
+w["tpi_param_nvmcsr_addr"]="169*1";
+w["tpi_rsp_err_collis"]="162*1,165*1,166*1,167*1,168*1,169*1";
+w["tpi_rsp_err_fail"]="162*1,164*1,165*1,166*1,167*1,168*1,169*1";
+w["tpi_rsp_err_illegal_param"]="164*1,168*1,169*1";
+w["tpi_rsp_err_ok"]="162*1,163*1,164*1,165*1,166*1,167*1,168*1,169*1";
+w["tpi_rsp_err_timeout"]="165*1,166*1,168*1,169*1";
+w["tpiprotocol"]="169*1,180*2";
+w["tpiprotocol."]="169*1,180*1";
+w["trace"]="3*1,5*1,7*39,21*1,177*1,192*50";
+w["trademark"]="171*5";
+w["trail"]="34*1,56*2,85*1,126*1";
+w["transfer"]="13*1,148*1";
+w["transit"]="60*1,139*1";
+w["transitions."]="60*1";
+w["transmit"]="91*3,145*4,147*4,152*4,153*5";
+w["transport"]="13*54,37*1,91*3,130*1,192*1";
+w["transport-rel"]="91*3";
+w["transport_hid"]="186*1";
+w["transport_off"]="186*1";
+w["trial"]="62*1";
+w["trigger"]="185*1";
+w["tune"]="91*3";
+w["twi"]="186*3";
+w["two"]="23*1,85*1";
+w["tx"]="0*1,91*3";
+w["type"]="9*1,27*2,40*2,45*2,65*2,75*5,76*6,79*3,93*2,113*4,114*4,115*4,117*1,135*3,139*1,140*6,148*1,159*6,166*1,167*1,168*5,169*3,174*1,181*36,183*46,185*1,186*3";
+w["typic"]="135*2";
+w["u"]="148*1,171*2";
+w["u.s."]="171*2";
+w["uar"]="0*1";
+w["uart"]="14*2,186*3";
+w["uc3"]="38*1,90*1,173*2";
+w["uc3a"]="182*1";
+w["uc3c"]="182*2";
+w["ued."]="148*1";
+w["unaffected."]="110*1";
+w["uncondit"]="139*1";
+w["unconditionally."]="139*1";
+w["under"]="140*3";
+w["underrun"]="37*2";
+w["undesir"]="37*1";
+w["undo"]="37*1";
+w["unexpect"]="91*3";
+w["unknown"]="35*1,37*1,42*1,43*3,57*1,86*1,127*1,159*1,160*3,168*1";
+w["unless"]="171*1";
+w["unlimit"]="171*1";
+w["unlock"]="79*3";
+w["unspecifi"]="129*1,140*3";
+w["unsupport"]="43*3,140*3";
+w["until"]="139*1,148*1,185*1";
+w["unwrap"]="22*2,24*41,25*41";
+w["up"]="0*1,1*1,2*1,3*1,4*1,5*1,6*1,7*1,8*1,9*1,10*1,11*1,12*1,13*1,14*1,15*1,16*1,17*1,18*2,19*1,20*1,21*1,22*1,23*2,24*1,25*1,26*1,27*1,28*1,29*1,30*1,31*1,32*1,33*1,34*1,35*1,36*1,37*1,38*1,39*1,40*1,41*1,42*1,43*1,44*1,45*1,46*1,47*1,48*1,49*1,50*1,51*1,52*1,53*1,54*1,55*1,56*1,57*1,58*1,59*1,60*1,61*1,62*1,63*4,64*1,65*1,66*1,67*1,68*1,69*1,70*1,71*1,72*1,73*1,74*1,75*1,76*1,77*1,78*1,79*1,80*1,81*1,82*1,83*1,84*1,85*1,86*1,87*1,88*1,89*1,90*1,91*1,92*1,93*1,94*1,95*1,96*1,97*1,98*1,99*1,100*1,101*1,102*1,103*1,104*1,105*1,106*1,107*1,108*1,109*1,110*1,111*1,112*1,113*1,114*1,115*1,116*1,117*1,118*1,119*1,120*1,121*1,122*1,123*1,124*1,125*1,126*1,127*1,128*1,129*1,130*1,131*1,132*7,133*1,134*1,135*1,136*1,137*1,138*1,139*1,140*1,141*1,142*1,143*1,144*1,145*1,146*1,147*1,148*1,149*1,150*1,151*1,152*1,153*1,154*1,155*1,156*1,157*1,158*1,159*1,160*1,161*1,162*1,163*1,164*1,165*1,166*1,167*1,168*1,169*1,181*1,182*1,183*1,184*1,185*1,186*1,187*1,188*1,189*1,190*1,191*1,192*1,193*1";
+w["upd"]="171*1";
+w["updat"]="139*1";
+w["updated."]="139*1";
+w["upgrad"]="1*1,48*1,50*44,63*3";
+w["upon"]="1*1,36*1,73*1,131*1,132*1,135*1,175*1,180*1";
+w["usag"]="3*1,30*1,131*1,132*1,133*1";
+w["usart"]="186*3";
+w["usb"]="0*1,1*2,185*1";
+w["use"]="0*1,1*9,3*2,21*1,22*4,27*1,28*1,29*1,37*4,38*6,39*1,40*1,45*1,46*1,47*1,51*2,62*4,65*1,66*1,67*1,68*1,78*2,79*1,88*5,89*3,90*1,93*1,94*1,95*1,96*1,112*1,114*1,117*1,121*1,131*7,132*12,133*13,135*2,136*4,137*3,138*1,139*2,142*1,143*2,144*1,145*1,147*2,148*7,149*1,150*2,151*2,152*1,153*1,154*2,155*2,156*2,157*2,166*2,167*1,171*4,172*1,173*1,175*4,178*1,180*5,185*2,192*4";
+w["used."]="22*1,37*1,79*1,135*1,137*1,148*2";
+w["user"]="62*1,89*1,91*3,111*1,132*1,133*1,136*1,140*6,172*1,181*1,182*1,185*1";
+w["user_sign_base_addr"]="133*1,185*1";
+w["usual"]="75*1,76*1,136*1,182*1";
+w["usual."]="136*1";
+w["valid"]="27*1,28*1,29*1,34*1,40*1,45*1,46*1,47*1,56*1,65*1,66*1,67*1,85*1,89*2,91*9,93*1,94*1,95*1,126*1,136*2,140*3";
+w["valid."]="34*1,56*1,85*1,126*1";
+w["valu"]="3*1,4*1,9*1,10*1,37*4,60*1,63*6,70*1,78*1,84*2,89*1,91*12,96*1,98*1,107*1,110*1,117*1,125*2,129*1,132*1,135*1,136*2,139*1,140*12,148*15,153*1,159*1,160*3,164*2,168*1,175*1,180*1,182*1,185*6,193*1";
+w["values."]="139*1";
+w["values:"]="9*1,10*1,185*1";
+w["vari"]="1*1,111*1";
+w["variabl"]="185*1";
+w["variant"]="135*1,140*3";
+w["variant:"]="135*1";
+w["various"]="51*1";
+w["vector"]="101*1,109*1,139*1";
+w["ven"]="22*1";
+w["vendor"]="0*1,3*52,4*46,5*41,8*41,22*3,177*1,192*1";
+w["vendor-command"]="4*5";
+w["veri"]="1*1,90*1";
+w["version"]="1*3,27*2,28*2,29*2,32*2,33*2,34*7,35*2,37*4,40*2,41*2,42*2,45*2,46*2,47*2,49*3,50*2,51*2,52*2,54*2,55*2,56*8,57*2,59*2,60*2,61*2,62*1,65*2,66*2,67*2,68*2,69*2,70*2,71*2,72*2,73*2,74*2,75*2,76*2,77*2,78*2,79*2,81*2,82*2,83*2,84*2,85*15,86*2,91*6,93*2,94*2,95*2,96*2,97*2,98*2,99*2,100*2,101*2,102*2,103*2,104*2,105*2,106*2,107*2,108*2,109*2,110*2,111*2,112*2,113*2,114*2,115*2,116*2,117*2,118*2,119*2,120*2,121*2,123*2,124*2,125*2,126*7,127*2,129*2,130*2,140*3,188*2,193*3";
+w["via"]="140*3";
+w["violat"]="131*1,132*1";
+w["virtual"]="0*2,1*2";
+w["voltag"]="63*3,193*1";
+w["vtg"]="193*1";
+w["vtref"]="62*1";
+w["w"]="133*4,181*2,182*7,185*14";
+w["wait"]="91*3";
+w["want"]="140*6,172*1";
+w["warn"]="159*1,160*3";
+w["warrant"]="171*1";
+w["warranti"]="171*3";
+w["was"]="32*1,54*1,81*1,91*6,123*1";
+w["way"]="182*1";
+w["way."]="182*1";
+w["websit"]="171*1";
+w["well"]="0*1,1*1,135*1,180*1";
+w["went"]="63*6";
+w["what"]="135*1,148*1";
+w["whatsoev"]="171*1";
+w["when"]="6*1,24*1,28*1,29*1,46*1,47*1,66*1,67*1,78*2,88*3,89*1,94*1,95*1,101*1,102*1,104*1,109*1,113*1,114*1,115*1,119*1,120*1,135*1,136*2,138*1,139*1,140*12,148*2,185*3,192*1";
+w["where"]="37*1,121*1";
+w["wherea"]="135*1";
+w["whether"]="34*1,56*1,78*1,79*1,85*1,88*1,126*1,138*1";
+w["which"]="0*2,1*2,3*1,15*1,23*2,36*1,37*4,38*1,79*1,89*1,114*2,135*2,136*1,148*1,153*1,172*2,178*1";
+w["while"]="114*1,140*12";
+w["who"]="172*1";
+w["whole"]="165*1";
+w["will"]="1*1,10*1,23*1,24*1,37*4,49*1,51*3,52*1,60*1,79*3,89*1,101*1,102*1,109*4,110*2,115*1,131*2,135*1,136*2,137*2,138*1,139*1,148*1,172*1,175*2,180*2,185*2";
+w["window"]="171*1";
+w["within"]="79*1,131*1,132*1,140*3";
+w["without"]="52*1,171*2,172*1";
+w["woke"]="63*3";
+w["word"]="91*3,104*1,106*1,107*1,117*1,129*1,131*2,148*8,173*2,181*5,185*3";
+w["work"]="10*1,51*1,148*1";
+w["works."]="148*1";
+w["wr"]="137*1";
+w["wrap"]="22*1,23*43";
+w["wrapper"]="24*1";
+w["write"]="10*1,28*2,46*2,64*1,66*2,72*1,76*42,79*1,91*15,92*2,94*2,107*46,115*51,131*2,132*9,133*18,139*2,140*12,148*9,161*1,164*1,166*55,175*1,182*1,185*1";
+w["write."]="115*1";
+w["write:"]="139*2";
+w["writeabl"]="184*1,191*1";
+w["written"]="76*1,131*2,132*3,182*1,185*1";
+w["wrong"]="63*18";
+w["x"]="119*2,120*2,193*1";
+w["xmega"]="38*1,52*1,111*1,112*1,117*1,118*1,133*58,139*1,140*9,180*1,183*1,185*39";
+w["xmega_erase_app"]="140*1";
+w["xmega_erase_app_pag"]="140*1";
+w["xmega_erase_boot"]="140*1";
+w["xmega_erase_boot_pag"]="140*1";
+w["xmega_erase_chip"]="140*1";
+w["xmega_erase_eeprom"]="140*1";
+w["xmega_erase_eeprom_pag"]="140*1";
+w["xmega_erase_usersig"]="140*1";
+w["xml"]="135*1,145*7,146*2,147*2,148*3,153*1,175*1";
+w["xml:"]="145*7,146*2,147*2,148*2,153*1";
+w["xplain"]="1*2";
+w["xx"]="136*1";
+w["yet"]="109*1";
+w["yy"]="136*1";
+w["yyyymmddhhmmss"]="190*1";
+w[" "]="0*3,1*4,2*3,3*3,4*3,5*3,6*3,7*3,8*3,9*3,10*3,11*3,12*3,13*3,14*3,15*3,16*3,17*3,18*3,19*3,20*3,21*3,22*3,23*3,24*3,25*3,26*3,27*3,28*3,29*3,30*3,31*3,32*3,33*3,34*3,35*3,36*3,37*3,38*3,39*3,40*3,41*3,42*3,43*3,44*3,45*3,46*3,47*3,48*3,49*3,50*3,51*3,52*3,53*3,54*3,55*3,56*3,57*3,58*3,59*3,60*3,61*3,62*3,63*3,64*3,65*3,66*3,67*3,68*3,69*3,70*3,71*3,72*3,73*3,74*3,75*3,76*3,77*3,78*4,79*3,80*3,81*3,82*3,83*3,84*3,85*3,86*3,87*3,88*3,89*3,90*3,91*3,92*3,93*3,94*3,95*3,96*3,97*3,98*3,99*3,100*3,101*3,102*3,103*3,104*3,105*3,106*3,107*3,108*3,109*3,110*3,111*3,112*3,113*3,114*3,115*3,116*3,117*3,118*3,119*3,120*3,121*3,122*3,123*3,124*3,125*3,126*3,127*3,128*3,129*3,130*3,131*3,132*3,133*3,134*3,135*3,136*3,137*3,138*3,139*3,140*3,141*3,142*3,143*3,144*3,145*3,146*3,147*3,148*4,149*3,150*3,151*3,152*3,153*3,154*3,155*3,156*3,157*3,158*3,159*3,160*3,161*3,162*3,163*3,164*3,165*3,166*3,167*3,168*3,169*3,170*4,171*3,172*4,173*4,174*4,175*4,176*4,177*4,178*4,179*4,180*4,181*3,182*3,183*3,184*3,185*5,186*3,187*3,188*3,189*3,190*3,191*3,192*3,193*3";
+w[" 1"]="1*5";
+w[" 1."]="1*5";
+w[" 10"]="10*5";
+w[" 10."]="10*5";
+w[" 100"]="185*5";
+w[" 100."]="185*5";
+w[" 101"]="185*5";
+w[" 101."]="185*5";
+w[" 102"]="96*5";
+w[" 102."]="96*5";
+w[" 103"]="97*5";
+w[" 103."]="97*5";
+w[" 104"]="98*5";
+w[" 104."]="98*5";
+w[" 105"]="99*5";
+w[" 105."]="99*5";
+w[" 106"]="100*5";
+w[" 106."]="100*5";
+w[" 107"]="101*5";
+w[" 107."]="101*5";
+w[" 108"]="102*5";
+w[" 108."]="102*5";
+w[" 109"]="103*5";
+w[" 109."]="103*5";
+w[" 11"]="13*5";
+w[" 11."]="13*5";
+w[" 110"]="104*5";
+w[" 110."]="104*5";
+w[" 111"]="105*5";
+w[" 111."]="105*5";
+w[" 112"]="106*5";
+w[" 112."]="106*5";
+w[" 113"]="107*5";
+w[" 113."]="107*5";
+w[" 114"]="108*5";
+w[" 114."]="108*5";
+w[" 115"]="109*5";
+w[" 115."]="109*5";
+w[" 116"]="110*5";
+w[" 116."]="110*5";
+w[" 117"]="111*5";
+w[" 117."]="111*5";
+w[" 118"]="112*5";
+w[" 118."]="112*5";
+w[" 119"]="113*5";
+w[" 119."]="113*5";
+w[" 12"]="13*5";
+w[" 12."]="13*5";
+w[" 120"]="114*5";
+w[" 120."]="114*5";
+w[" 121"]="115*5";
+w[" 121."]="115*5";
+w[" 122"]="116*5";
+w[" 122."]="116*5";
+w[" 123"]="117*5";
+w[" 123."]="117*5";
+w[" 124"]="118*5";
+w[" 124."]="118*5";
+w[" 125"]="119*5";
+w[" 125."]="119*5";
+w[" 126"]="120*5";
+w[" 126."]="120*5";
+w[" 127"]="121*5";
+w[" 127."]="121*5";
+w[" 128"]="123*5";
+w[" 128."]="123*5";
+w[" 129"]="124*5";
+w[" 129."]="124*5";
+w[" 13"]="14*5";
+w[" 13."]="14*5";
+w[" 130"]="125*5";
+w[" 130."]="125*5";
+w[" 131"]="126*5";
+w[" 131."]="126*5";
+w[" 132"]="127*5";
+w[" 132."]="127*5";
+w[" 133"]="129*5";
+w[" 133."]="129*5";
+w[" 134"]="130*5";
+w[" 134."]="130*5";
+w[" 135"]="131*5";
+w[" 135."]="131*5";
+w[" 136"]="132*5";
+w[" 136."]="132*5";
+w[" 137"]="133*5";
+w[" 137."]="133*5";
+w[" 138"]="136*5";
+w[" 138."]="136*5";
+w[" 139"]="142*5";
+w[" 139."]="142*5";
+w[" 14"]="14*5";
+w[" 14."]="14*5";
+w[" 140"]="142*5";
+w[" 140."]="142*5";
+w[" 141"]="143*5";
+w[" 141."]="143*5";
+w[" 142"]="143*5";
+w[" 142."]="143*5";
+w[" 143"]="144*5";
+w[" 143."]="144*5";
+w[" 144"]="144*5";
+w[" 144."]="144*5";
+w[" 145"]="145*5";
+w[" 145."]="145*5";
+w[" 146"]="145*5";
+w[" 146."]="145*5";
+w[" 147"]="146*5";
+w[" 147."]="146*5";
+w[" 148"]="146*5";
+w[" 148."]="146*5";
+w[" 149"]="147*5";
+w[" 149."]="147*5";
+w[" 15"]="15*5";
+w[" 15."]="15*5";
+w[" 150"]="147*5";
+w[" 150."]="147*5";
+w[" 151"]="148*5";
+w[" 151."]="148*5";
+w[" 152"]="148*5";
+w[" 152."]="148*5";
+w[" 153"]="148*5";
+w[" 153."]="148*5";
+w[" 154"]="149*5";
+w[" 154."]="149*5";
+w[" 155"]="149*5";
+w[" 155."]="149*5";
+w[" 156"]="152*5";
+w[" 156."]="152*5";
+w[" 157"]="152*5";
+w[" 157."]="152*5";
+w[" 158"]="153*5";
+w[" 158."]="153*5";
+w[" 159"]="153*5";
+w[" 159."]="153*5";
+w[" 16"]="15*5";
+w[" 16."]="15*5";
+w[" 160"]="159*5";
+w[" 160."]="159*5";
+w[" 161"]="162*5";
+w[" 161."]="162*5";
+w[" 162"]="162*5";
+w[" 162."]="162*5";
+w[" 163"]="163*5";
+w[" 163."]="163*5";
+w[" 164"]="163*5";
+w[" 164."]="163*5";
+w[" 165"]="164*5";
+w[" 165."]="164*5";
+w[" 166"]="164*5";
+w[" 166."]="164*5";
+w[" 167"]="165*5";
+w[" 167."]="165*5";
+w[" 168"]="165*5";
+w[" 168."]="165*5";
+w[" 169"]="165*5";
+w[" 169."]="165*5";
+w[" 17"]="16*5";
+w[" 17."]="16*5";
+w[" 170"]="166*5";
+w[" 170."]="166*5";
+w[" 171"]="166*5";
+w[" 171."]="166*5";
+w[" 172"]="167*5";
+w[" 172."]="167*5";
+w[" 173"]="167*5";
+w[" 173."]="167*5";
+w[" 174"]="168*5";
+w[" 174."]="168*5";
+w[" 18"]="16*5";
+w[" 18."]="16*5";
+w[" 19"]="17*5";
+w[" 19."]="17*5";
+w[" 2"]="3*5";
+w[" 2."]="3*5";
+w[" 20"]="17*5";
+w[" 20."]="17*5";
+w[" 21"]="18*5";
+w[" 21."]="18*5";
+w[" 22"]="18*5";
+w[" 22."]="18*5";
+w[" 23"]="19*5";
+w[" 23."]="19*5";
+w[" 24"]="19*5";
+w[" 24."]="19*5";
+w[" 25"]="20*5";
+w[" 25."]="20*5";
+w[" 26"]="20*5";
+w[" 26."]="20*5";
+w[" 27"]="21*5";
+w[" 27."]="21*5";
+w[" 28"]="21*5";
+w[" 28."]="21*5";
+w[" 29"]="23*5";
+w[" 29."]="23*5";
+w[" 3"]="4*5";
+w[" 3."]="4*5";
+w[" 30"]="23*5";
+w[" 30."]="23*5";
+w[" 31"]="24*5";
+w[" 31."]="24*5";
+w[" 32"]="24*5";
+w[" 32."]="24*5";
+w[" 33"]="25*5";
+w[" 33."]="25*5";
+w[" 34"]="25*5";
+w[" 34."]="25*5";
+w[" 35"]="27*5";
+w[" 35."]="27*5";
+w[" 36"]="187*5";
+w[" 36."]="187*5";
+w[" 37"]="28*5";
+w[" 37."]="28*5";
+w[" 38"]="29*5";
+w[" 38."]="29*5";
+w[" 39"]="30*5";
+w[" 39."]="30*5";
+w[" 4"]="6*5";
+w[" 4."]="6*5";
+w[" 40"]="32*5";
+w[" 40."]="32*5";
+w[" 41"]="33*5";
+w[" 41."]="33*5";
+w[" 42"]="34*5";
+w[" 42."]="34*5";
+w[" 43"]="35*5";
+w[" 43."]="35*5";
+w[" 44"]="37*5";
+w[" 44."]="37*5";
+w[" 45"]="37*5";
+w[" 45."]="37*5";
+w[" 46"]="37*5";
+w[" 46."]="37*5";
+w[" 47"]="38*5";
+w[" 47."]="38*5";
+w[" 48"]="40*5";
+w[" 48."]="40*5";
+w[" 49"]="190*5";
+w[" 49."]="190*5";
+w[" 5"]="6*5";
+w[" 5."]="6*5";
+w[" 50"]="41*5";
+w[" 50."]="41*5";
+w[" 51"]="42*5";
+w[" 51."]="42*5";
+w[" 52"]="45*5";
+w[" 52."]="45*5";
+w[" 53"]="189*5";
+w[" 53."]="189*5";
+w[" 54"]="46*5";
+w[" 54."]="46*5";
+w[" 55"]="47*5";
+w[" 55."]="47*5";
+w[" 56"]="193*5";
+w[" 56."]="193*5";
+w[" 57"]="188*5";
+w[" 57."]="188*5";
+w[" 58"]="49*5";
+w[" 58."]="49*5";
+w[" 59"]="50*5";
+w[" 59."]="50*5";
+w[" 6"]="9*5";
+w[" 6."]="9*5";
+w[" 60"]="51*5";
+w[" 60."]="51*5";
+w[" 61"]="52*5";
+w[" 61."]="52*5";
+w[" 62"]="54*5";
+w[" 62."]="54*5";
+w[" 63"]="55*5";
+w[" 63."]="55*5";
+w[" 64"]="56*5";
+w[" 64."]="56*5";
+w[" 65"]="57*5";
+w[" 65."]="57*5";
+w[" 66"]="59*5";
+w[" 66."]="59*5";
+w[" 67"]="60*5";
+w[" 67."]="60*5";
+w[" 68"]="61*5";
+w[" 68."]="61*5";
+w[" 69"]="65*5";
+w[" 69."]="65*5";
+w[" 7"]="9*5";
+w[" 7."]="9*5";
+w[" 70"]="191*5";
+w[" 70."]="191*5";
+w[" 71"]="66*5";
+w[" 71."]="66*5";
+w[" 72"]="67*5";
+w[" 72."]="67*5";
+w[" 73"]="182*5";
+w[" 73."]="182*5";
+w[" 74"]="68*5";
+w[" 74."]="68*5";
+w[" 75"]="69*5";
+w[" 75."]="69*5";
+w[" 76"]="70*5";
+w[" 76."]="70*5";
+w[" 77"]="71*5";
+w[" 77."]="71*5";
+w[" 78"]="72*5";
+w[" 78."]="72*5";
+w[" 79"]="73*5";
+w[" 79."]="73*5";
+w[" 8"]="9*5";
+w[" 8."]="9*5";
+w[" 80"]="74*5";
+w[" 80."]="74*5";
+w[" 81"]="75*5";
+w[" 81."]="75*5";
+w[" 82"]="76*5";
+w[" 82."]="76*5";
+w[" 83"]="181*5";
+w[" 83."]="181*5";
+w[" 84"]="77*5";
+w[" 84."]="77*5";
+w[" 85"]="78*5";
+w[" 85."]="78*5";
+w[" 86"]="79*5";
+w[" 86."]="79*5";
+w[" 87"]="81*5";
+w[" 87."]="81*5";
+w[" 88"]="82*5";
+w[" 88."]="82*5";
+w[" 89"]="83*5";
+w[" 89."]="83*5";
+w[" 9"]="10*5";
+w[" 9."]="10*5";
+w[" 90"]="84*5";
+w[" 90."]="84*5";
+w[" 91"]="85*5";
+w[" 91."]="85*5";
+w[" 92"]="85*5";
+w[" 92."]="85*5";
+w[" 93"]="86*5";
+w[" 93."]="86*5";
+w[" 94"]="93*5";
+w[" 94."]="93*5";
+w[" 95"]="184*5";
+w[" 95."]="184*5";
+w[" 96"]="94*5";
+w[" 96."]="94*5";
+w[" 97"]="95*5";
+w[" 97."]="95*5";
+w[" 98"]="185*5";
+w[" 98."]="185*5";
+w[" 99"]="185*5";
+w[" 99."]="185*5";
+w[" activ"]="68*5,96*5";
+w[" atmel"]="1*5";
+w[" attach"]="99*5";
+w[" avr"]="4*5,133*5";
+w[" avr32"]="181*5,182*5,191*5";
+w[" avr8"]="184*5,185*5";
+w[" calibr"]="52*5";
+w[" command"]="37*5";
+w[" configur"]="9*5";
+w[" crc"]="112*5";
+w[" custom"]="6*5";
+w[" data"]="34*5,56*5,85*10,126*5";
+w[" deactiv"]="69*5,97*5";
+w[" debugwir"]="131*5";
+w[" detach"]="100*5";
+w[" devic"]="185*15";
+w[" disabl"]="110*5";
+w[" discoveri"]="190*5";
+w[" edbg"]="30*5,187*5";
+w[" end"]="49*5";
+w[" eras"]="6*5,71*5,79*5,111*5";
+w[" event"]="37*5,129*5,130*5";
+w[" event:"]="129*5,130*5";
+w[" extern"]="61*5";
+w[" fail"]="35*5,42*5,57*5,86*5,127*5";
+w[" firmwar"]="50*5";
+w[" get"]="9*10,18*10,19*10,20*10,29*5,47*5,67*5,70*5,95*5,98*5";
+w[" halt"]="72*5";
+w[" hardwar"]="117*5,118*5";
+w[" houekeep"]="189*5,193*5";
+w[" id"]="83*5,136*5";
+w[" jtag"]="51*5";
+w[" list"]="33*5,41*5,55*5,82*5,124*5";
+w[" megaavr"]="132*5";
+w[" memori"]="113*5,114*5,115*5";
+w[" ok"]="32*5,54*5,81*5,123*5";
+w[" page"]="116*5";
+w[" pc"]="84*5,106*5,107*5,125*5";
+w[" power"]="59*5";
+w[" prog"]="108*5,109*5";
+w[" protocol"]="38*5";
+w[" queri"]="27*5,40*5,45*5,65*5,93*5";
+w[" read"]="75*5";
+w[" reset"]="101*5";
+w[" respons"]="37*5";
+w[" run"]="103*5,104*5";
+w[" set"]="10*10,13*10,14*10,15*10,28*5,46*5,66*5,94*5";
+w[" signon"]="21*10";
+w[" sleep"]="60*5";
+w[" softwar"]="119*5,120*5,121*5";
+w[" spi"]="142*10,143*10,144*10,145*10,146*10,147*10,148*15,149*10,152*10,153*10,159*5";
+w[" start"]="16*10,188*5";
+w[" step"]="74*5,105*5";
+w[" stop"]="17*10,102*5";
+w[" tap"]="77*5";
+w[" tpi"]="162*10,163*10,164*10,165*15,166*10,167*10,168*5";
+w[" unwrap"]="23*5,24*5,25*5";
+w[" vendor"]="3*5";
+w[" wrap"]="23*5,24*5,25*5";
+w[" write"]="73*5,76*5";
+w["©"]="171*1";
+w["®"]="0*1,171*5,172*1";
+w["®."]="0*1";
+w["–"]="24*1,62*1,148*1";
+w["‘debug"]="109*1";
+w["‘program"]="109*1";
+w["’"]="109*2";
+w["’s"]="23*1";
+w["“activ"]="89*1,136*1";
+w["“attach"]="138*1";
+w["“avr32"]="65*1";
+w["“avr8"]="93*1";
+w["“deactiv"]="138*1";
+w["“debug"]="137*1";
+w["“detach"]="138*1";
+w["“devic"]="133*12";
+w["“discov"]="37*2";
+w["“discoveri"]="40*1";
+w["“edbg"]="27*1";
+w["“edbgctrl"]="28*1,29*1";
+w["“enter"]="137*1,138*1";
+w["“function"]="137*2";
+w["“housekeep"]="45*1,46*1,47*1";
+w["“leav"]="138*1";
+w["“memori"]="75*1,76*1,79*1,113*1,114*1,115*1";
+w["“program"]="137*1";
+w["“queri"]="37*2";
+w["“serial"]="7*1";
+w["“set"]="66*1,67*1,94*1,95*1";
+w["“start"]="88*1,135*1";
+w["â€"]="7*1,27*1,37*4,75*1,76*1,79*1,89*1,93*1,94*1,133*12,136*1,137*5,138*5";
+
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/l10n.js b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/l10n.js
new file mode 100644
index 000000000..3147f961f
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/l10n.js
@@ -0,0 +1,3 @@
+//Resource strings for localization
+var localeresource = new Object;
+localeresource["search_no_results"]="Your search returned no results.";
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/nwSearchFnt.js b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/nwSearchFnt.js
new file mode 100644
index 000000000..bf4aa3fd2
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/nwSearchFnt.js
@@ -0,0 +1,886 @@
+/*----------------------------------------------------------------------------
+ * JavaScript for webhelp search
+ *----------------------------------------------------------------------------
+ This file is part of the webhelpsearch plugin for DocBook WebHelp
+ Copyright (c) 2007-2008 NexWave Solutions All Rights Reserved.
+ www.nexwave.biz Nadege Quaine
+ http://kasunbg.blogspot.com/ Kasun Gajasinghe
+ */
+
+//string initialization
+var htmlfileList = "htmlFileInfoList.js";
+var htmlfileinfoList = "htmlFileInfoList.js";
+var useCJKTokenizing = false;
+
+var w = new Object();
+var scoring = new Object();
+
+var searchTextField = '';
+var no = 0;
+var noWords = 0;
+var partialSearch = "<font class=\"highlightText\">There is no page containing all the search terms.<br>Partial results:</font>";
+var warningMsg = '<div style="padding: 5px;margin-right:5px;;background-color:#FFFF00;">';
+warningMsg+='<b>Please note that due to security settings, Google Chrome does not highlight';
+warningMsg+=' the search results in the right frame.</b><br>';
+warningMsg+='This happens only when the WebHelp files are loaded from the local file system.<br>';
+warningMsg+='Workarounds:';
+warningMsg+='<ul>';
+warningMsg+='<li>Try using another web browser.</li>';
+warningMsg+='<li>Deploy the WebHelp files on a web server.</li>';
+warningMsg+='</div>';
+txt_filesfound = 'Results';
+txt_enter_at_least_1_char = "You must enter at least one character.";
+txt_enter_more_than_10_words = "Only first 10 words will be processed.";
+txt_browser_not_supported = "Your browser is not supported. Use of Mozilla Firefox is recommended.";
+txt_please_wait = "Please wait. Search in progress...";
+txt_results_for = "Results for: ";
+
+/* This function verify the validity of search input by the user
+ Cette fonction verifie la validite de la recherche entrre par l utilisateur */
+function Verifie(searchForm) {
+
+ // Check browser compatibility
+ if (navigator.userAgent.indexOf("Konquerer") > -1) {
+
+ alert(txt_browser_not_supported);
+ return;
+ }
+
+ searchTextField = trim(document.searchForm.textToSearch.value);
+ searchTextField = searchTextField.replace(/['"]/g,'');
+ var expressionInput = searchTextField;
+ $.cookie('textToSearch', expressionInput);
+
+ if (expressionInput.length < 1) {
+
+ // expression is invalid
+ alert(txt_enter_at_least_1_char);
+ // reactive la fenetre de search (utile car cadres)
+
+ document.searchForm.textToSearch.focus();
+ }
+ else {
+ var splitSpace = searchTextField.split(" ");
+ var splitWords = [];
+ for (var i = 0 ; i < splitSpace.length ; i++) {
+ var splitDot = splitSpace[i].split(".");
+
+ if(!(splitDot.length == 1)){
+ splitWords.push(splitSpace[i]);
+ }
+
+ for (var i1 = 0; i1 < splitDot.length; i1++) {
+ var splitColon = splitDot[i1].split(":");
+ for (var i2 = 0; i2 < splitColon.length; i2++) {
+ var splitDash = splitColon[i2].split("-");
+ for (var i3 = 0; i3 < splitDash.length; i3++) {
+ if (splitDash[i3].split("").length > 0) {
+ splitWords.push(splitDash[i3]);
+ }
+ }
+ }
+ }
+ }
+ noWords = splitWords;
+ if (noWords.length > 9){
+ // Allow to search maximum 10 words
+ alert(txt_enter_more_than_10_words);
+ expressionInput = '';
+ for (var x = 0 ; x < 10 ; x++){
+ expressionInput = expressionInput + " " + noWords[x];
+ }
+ Effectuer_recherche(expressionInput);
+ document.searchForm.textToSearch.focus();
+ } else {
+ // Effectuer la recherche
+ expressionInput = '';
+ for (var x = 0 ; x < noWords.length ; x++) {
+ expressionInput = expressionInput + " " + noWords[x];
+ }
+ Effectuer_recherche(expressionInput);
+ // reactive la fenetre de search (utile car cadres)
+ document.searchForm.textToSearch.focus();
+ }
+ }
+}
+
+var stemQueryMap = new Array(); // A hashtable which maps stems to query words
+
+/* This function parses the search expression, loads the indices and displays the results*/
+function Effectuer_recherche(expressionInput) {
+
+ /* Display a waiting message */
+ //DisplayWaitingMessage();
+
+ /*data initialisation*/
+ var searchFor = ""; // expression en lowercase et sans les caracte res speciaux
+ //w = new Object(); // hashtable, key=word, value = list of the index of the html files
+ scriptLetterTab = new Scriptfirstchar(); // Array containing the first letter of each word to look for
+ var wordsList = new Array(); // Array with the words to look for
+ var finalWordsList = new Array(); // Array with the words to look for after removing spaces
+ var linkTab = new Array();
+ var fileAndWordList = new Array();
+ var txt_wordsnotfound = "";
+
+
+ // --------------------------------------
+ // Begin Thu's patch
+ /*nqu: expressionInput, la recherche est lower cased, plus remplacement des char speciaux*/
+ //The original replacement expression is:
+ //searchFor = expressionInput.toLowerCase().replace(/<\//g, "_st_").replace(/\$_/g, "_di_").replace(/\.|%2C|%3B|%21|%3A|@|\/|\*/g, " ").replace(/(%20)+/g, " ").replace(/_st_/g, "</").replace(/_di_/g, "%24_");
+ //The above expression was error prone because it did not deal with words that have a . as part of the word correctly, for example, document.txt
+
+ //Do not automatically replace a . with a space
+ searchFor = expressionInput.toLowerCase().replace(/<\//g, "_st_").replace(/\$_/g, "_di_").replace(/%2C|%3B|%21|%3A|@|\/|\*/g, " ").replace(/(%20)+/g, " ").replace(/_st_/g, "</").replace(/_di_/g, "%24_");
+
+ //If it ends with a period, replace it with a space
+ searchFor = searchFor.replace(/[.]$/,"");
+ // End Thu's Patch
+ // ------------------------------------------
+
+ searchFor = searchFor.replace(/ +/g, " ");
+ searchFor = searchFor.replace(/ $/, "").replace(/^ /, "");
+
+ wordsList = searchFor.split(" ");
+ wordsList.sort();
+
+ //set the tokenizing method
+ useCJKTokenizing = typeof indexerLanguage != "undefined" && (indexerLanguage == "zh" || indexerLanguage == "ja" || indexerLanguage == "ko");
+ //If Lucene CJKTokenizer was used as the indexer, then useCJKTokenizing will be true. Else, do normal tokenizing.
+ // 2-gram tokenizinghappens in CJKTokenizing,
+ //If doStem then make tokenize with Stemmer
+ var finalArray;
+ if (doStem){
+ if(useCJKTokenizing){
+ finalWordsList = cjkTokenize(wordsList);
+ finalArray = finalWordsList;
+ } else {
+ finalWordsList = tokenize(wordsList);
+ finalArray = finalWordsList;
+ }
+ } else if(useCJKTokenizing){
+ finalWordsList = cjkTokenize(wordsList);
+ finalArray = finalWordsList;
+ } else{
+
+ //load the scripts with the indices: the following lines do not work on the server. To be corrected
+ /*if (IEBrowser) {
+ scriptsarray = loadTheIndexScripts (scriptLetterTab);
+ } */
+
+ /**
+ * Compare with the indexed words (in the w[] array), and push words that are in it to tempTab.
+ */
+ var tempTab = new Array();
+
+ // ---------------------------------------
+ // Thu's patch
+ //Do not use associative array in for loop, for example:
+ //for(var t in finalWordsList)
+ //it causes errors when finalWordList contains
+ //stemmed words such as: kei from the stemmed word: key
+ for(var t=0;t<finalWordsList.length;++t){
+ var aWord=finalWordsList[t];
+ //w is a Map like Object, use the current word in finalWordList as the key
+ if(w[aWord] == undefined){
+ txt_wordsnotfound += aWord + " ";
+ }
+ else{
+ tempTab.push(aWord);
+ }
+ }
+ finalWordsList = tempTab;
+ //Check all the inputs to see if the root words are in the finalWordsList, if not add them there
+ var inputs = expressionInput.split(' ');
+ // Thu's Patch
+ // -------------------------------------------
+
+
+ txt_wordsnotfound = expressionInput;
+ finalWordsList = removeDuplicate(finalWordsList);
+
+ }
+ if (finalWordsList.length) {
+ //search 'and' and 'or' one time
+ fileAndWordList = SortResults(finalWordsList);
+
+ if (fileAndWordList == undefined){
+ var cpt = 0;
+ } else {
+ var cpt = fileAndWordList.length;
+ var maxNumberOfWords = fileAndWordList[0][0].motsnb;
+ }
+ if (cpt > 0){
+ var searchedWords = noWords.length;
+ var foundedWords = fileAndWordList[0][0].motslisteDisplay.split(",").length;
+ //console.info("search : " + noWords.length + " found : " + fileAndWordList[0][0].motslisteDisplay.split(",").length);
+ if (searchedWords != foundedWords){
+ linkTab.push(partialSearch);
+ }
+ }
+
+
+ for (var i = 0; i < cpt; i++) {
+
+ var hundredProcent = fileAndWordList[i][0].scoring + 100 * fileAndWordList[i][0].motsnb;
+ var ttScore_first = fileAndWordList[i][0].scoring;
+ var numberOfWords = fileAndWordList[i][0].motsnb;
+
+ if (fileAndWordList[i] != undefined) {
+ linkTab.push("<p>" + txt_results_for + " " + "<span class=\"searchExpression\">" + fileAndWordList[i][0].motslisteDisplay + "</span>" + "</p>");
+
+ linkTab.push("<ul class='searchresult'>");
+ for (t in fileAndWordList[i]) {
+ //linkTab.push("<li><a href=\"../"+fl[fileAndWordList[i][t].filenb]+"\">"+fl[fileAndWordList[i][t].filenb]+"</a></li>");
+
+ var ttInfo = fileAndWordList[i][t].filenb;
+ // Get scoring
+ var ttScore = fileAndWordList[i][t].scoring;
+ var tempInfo = fil[ttInfo];
+
+ var pos1 = tempInfo.indexOf("@@@");
+ var pos2 = tempInfo.lastIndexOf("@@@");
+ var tempPath = tempInfo.substring(0, pos1);
+ var tempTitle = tempInfo.substring(pos1 + 3, pos2);
+ var tempShortdesc = tempInfo.substring(pos2 + 3, tempInfo.length);
+
+
+ // toc.html will not be displayed on search result
+ if (tempPath == 'toc.html'){
+ continue;
+ }
+ /*
+ //file:///home/kasun/docbook/WEBHELP/webhelp-draft-output-format-idea/src/main/resources/web/webhelp/installation.html
+ var linkString = "<li><a href=" + tempPath + ">" + tempTitle + "</a>";
+ // var linkString = "<li><a href=\"installation.html\">" + tempTitle + "</a>";
+ */
+ var split = fileAndWordList[i][t].motsliste.split(",");
+ // var splitedValues = expressionInput.split(" ");
+ // var finalArray = split.concat(splitedValues);
+
+ arrayString = 'Array(';
+ for(var x in finalArray){
+ if (finalArray[x].length > 2 || useCJKTokenizing){
+ arrayString+= "'" + finalArray[x] + "',";
+ }
+ }
+ arrayString = arrayString.substring(0,arrayString.length - 1) + ")";
+ var idLink = 'foundLink' + no;
+ var linkString = '<li><a id="' + idLink + '" href="' + tempPath + '" class="foundResult">' + tempTitle + '</a>';
+ var starWidth = (ttScore * 100/ hundredProcent)/(ttScore_first/hundredProcent) * (numberOfWords/maxNumberOfWords);
+ starWidth = starWidth < 10 ? (starWidth + 5) : starWidth;
+ // Keep the 5 stars format
+ if (starWidth > 85){
+ starWidth = 85;
+ }
+ /*
+ var noFullStars = Math.ceil(starWidth/17);
+ var fullStar = "curr";
+ var emptyStar = "";
+ if (starWidth % 17 == 0){
+ // am stea plina
+
+ } else {
+
+ }
+ console.info(noFullStars);
+ */
+ // Also check if we have a valid description
+ if ((tempShortdesc != "null" && tempShortdesc != '...')) {
+
+ linkString += "\n<div class=\"shortdesclink\">" + tempShortdesc + "</div>";
+ }
+ linkString += "</li>";
+
+ // Add rating values for scoring at the list of matches
+ linkString += "<div id=\"rightDiv\">";
+ linkString += "<div id=\"star\">";
+ //linkString += "<div style=\"color: rgb(136, 136, 136);\" id=\"starUser0\" class=\"user\">"
+ // + ((ttScore * 100/ hundredProcent)/(ttScore_first/hundredProcent)) * 1 + "</div>";
+ linkString += "<ul id=\"star0\" class=\"star\">";
+ linkString += "<li id=\"starCur0\" class=\"curr\" style=\"width: " + starWidth + "px;\"></li>";
+ linkString += "</ul>";
+
+ linkString += "<br style=\"clear: both;\">";
+ linkString += "</div>";
+ linkString += "</div>";
+ //linkString += '<b>Rating: ' + ttScore + '</b>';
+
+ linkTab.push(linkString);
+ no++;
+ }
+ linkTab.push("</ul>");
+ }
+ }
+ }
+
+ var results = "";
+ if (linkTab.length > 0) {
+ /*writeln ("<p>" + txt_results_for + " " + "<span class=\"searchExpression\">" + cleanwordsList + "</span>" + "<br/>"+"</p>");*/
+ results = "<p>";
+ //write("<ul class='searchresult'>");
+ for (t in linkTab) {
+ results += linkTab[t].toString();
+ }
+ results += "</p>";
+ } else {
+ results = "<p>" + localeresource.search_no_results + " <span class=\"searchExpression\">" + txt_wordsnotfound + "</span>" + "</p>";
+ }
+
+
+ // Verify if the browser is Google Chrome and the WebHelp is used on a local machine
+ // If browser is Google Chrome and WebHelp is used on a local machine a warning message will appear
+ // Highlighting will not work in this conditions. There is 2 workarounds
+ if (verifyBrowser()){
+ document.getElementById('searchResults').innerHTML = results;
+ } else {
+ document.getElementById('searchResults').innerHTML = warningMsg + results;
+ }
+
+}
+
+
+// Verify if the stemmed word is aproximately the same as the searched word
+function verifyWord(word, arr){
+ for (var i = 0 ; i < arr.length ; i++){
+ if (word[0] == arr[i][0]
+ && word[1] == arr[i][1]
+ //&& word[2] == arr[i][2]
+ ){
+ return true;
+ }
+ }
+ return false;
+}
+
+// Look for elements that start with searchedValue.
+function wordsStartsWith(searchedValue){
+ var toReturn = '';
+ for (var sv in w){
+ if (searchedValue.length < 3){
+ continue;
+ } else {
+ if (sv.toLowerCase().indexOf(searchedValue.toLowerCase()) == 0){
+ toReturn+=sv + ",";
+ }
+ }
+ }
+ return toReturn.length > 0 ? toReturn : undefined;
+}
+
+
+function tokenize(wordsList){
+ var stemmedWordsList = new Array(); // Array with the words to look for after removing spaces
+ var cleanwordsList = new Array(); // Array with the words to look for
+ // -------------------------------------------------
+ // Thu's patch
+ for(var j=0;j<wordsList.length;++j){
+ var word = wordsList[j];
+ var originalWord=word;
+ if(typeof stemmer != "undefined" ){
+ var stemmedWord=stemmer(word);
+ if(w[stemmedWord]!=undefined){
+ stemQueryMap[stemmer(word)] = word;
+ }
+ else{
+ stemQueryMap[originalWord]=originalWord;
+ }
+ } else {
+ if(w[word]!=undefined){
+ stemQueryMap[word] = word;
+ }
+ else{
+ stemQueryMap[originalWord]=originalWord;
+ }
+ }
+ }
+ //stemmedWordsList is the stemmed list of words separated by spaces.
+ for (var t=0;t<wordsList.length;++t) {
+ wordsList[t] = wordsList[t].replace(/(%22)|^-/g, "");
+ if (wordsList[t] != "%20") {
+ scriptLetterTab.add(wordsList[t].charAt(0));
+ cleanwordsList.push(wordsList[t]);
+ }
+ }
+
+ if(typeof stemmer != "undefined" ){
+ //Do the stemming using Porter's stemming algorithm
+ for (var i = 0; i < cleanwordsList.length; i++) {
+ var stemWord = stemmer(cleanwordsList[i]);
+ if(w[stemWord]!=undefined){
+ stemmedWordsList.push(stemWord);
+ }
+ else{
+ stemmedWordsList.push(cleanwordsList[i]);
+ }
+ }
+ // End Thu's patch
+ // -------------------------------------------
+ } else {
+ stemmedWordsList = cleanwordsList;
+ }
+ return stemmedWordsList;
+}
+
+//Invoker of CJKTokenizer class methods.
+function cjkTokenize(wordsList){
+ var allTokens= new Array();
+ var notCJKTokens= new Array();
+ var j=0;
+ for(j=0;j<wordsList.length;j++){
+ var word = wordsList[j];
+ if(getAvgAsciiValue(word) < 127){
+ notCJKTokens.push(word);
+ } else {
+ var tokenizer = new CJKTokenizer(word);
+ var tokensTmp = tokenizer.getAllTokens();
+ allTokens = allTokens.concat(tokensTmp);
+ }
+ }
+ allTokens = allTokens.concat(tokenize(notCJKTokens));
+ return allTokens;
+}
+
+//A simple way to determine whether the query is in english or not.
+function getAvgAsciiValue(word){
+ var tmp = 0;
+ var num = word.length < 5 ? word.length:5;
+ for(var i=0;i<num;i++){
+ if(i==5) break;
+ tmp += word.charCodeAt(i);
+ }
+ return tmp/num;
+}
+
+//CJKTokenizer
+function CJKTokenizer(input){
+ this.input = input;
+ this.offset=-1;
+ this.tokens = new Array();
+ this.incrementToken = incrementToken;
+ this.tokenize = tokenize;
+ this.getAllTokens = getAllTokens;
+ this.unique = unique;
+
+ function incrementToken(){
+ if(this.input.length - 2 <= this.offset){
+ // console.log("false "+offset);
+ return false;
+ }
+ else {
+ this.offset+=1;
+ return true;
+ }
+ }
+
+ function tokenize(){
+ //document.getElementById("content").innerHTML += x.substring(offset,offset+2)+"<br>";
+ return this.input.substring(this.offset,this.offset+2);
+ }
+
+ function getAllTokens(){
+ while(this.incrementToken()){
+ var tmp = this.tokenize();
+ this.tokens.push(tmp);
+ }
+ return this.unique(this.tokens);
+// document.getElementById("content").innerHTML += tokens+" ";
+// document.getElementById("content").innerHTML += "<br>dada"+sortedTokens+" ";
+// console.log(tokens.length+"dsdsds");
+ /*for(i=0;i<tokens.length;i++){
+ console.log(tokens[i]);
+ var ss = tokens[i] == sortedTokens[i];
+
+// document.getElementById("content").innerHTML += "<br>dada"+un[i]+"- "+stems[i]+"&nbsp;&nbsp;&nbsp;"+ ss;
+ document.getElementById("content").innerHTML += "<br>"+sortedTokens[i];
+ }*/
+ }
+
+ function unique(a)
+ {
+ var r = new Array();
+ o:for(var i = 0, n = a.length; i < n; i++)
+ {
+ for(var x = 0, y = r.length; x < y; x++)
+ {
+ if(r[x]==a[i]) continue o;
+ }
+ r[r.length] = a[i];
+ }
+ return r;
+ }
+}
+
+
+/* Scriptfirstchar: to gather the first letter of index js files to upload */
+function Scriptfirstchar() {
+ this.strLetters = "";
+ this.add = addLettre;
+}
+
+function addLettre(caract) {
+
+ if (this.strLetters == 'undefined') {
+ this.strLetters = caract;
+ } else if (this.strLetters.indexOf(caract) < 0) {
+ this.strLetters += caract;
+ }
+
+ return 0;
+}
+/* end of scriptfirstchar */
+
+/*main loader function*/
+/*tab contains the first letters of each word looked for*/
+function loadTheIndexScripts(tab) {
+
+ //alert (tab.strLetters);
+ var scriptsarray = new Array();
+
+ for (var i = 0; i < tab.strLetters.length; i++) {
+
+ scriptsarray[i] = "..\/search" + "\/" + tab.strLetters.charAt(i) + ".js";
+ }
+ // add the list of html files
+ i++;
+ scriptsarray[i] = "..\/search" + "\/" + htmlfileList;
+
+ //debug
+ for (var t in scriptsarray) {
+ //alert (scriptsarray[t]);
+ }
+
+ tab = new ScriptLoader();
+ for (t in scriptsarray) {
+ tab.add(scriptsarray[t]);
+ }
+ tab.load();
+ //alert ("scripts loaded");
+ return (scriptsarray);
+}
+
+/* ScriptLoader: to load the scripts and wait that it's finished */
+function ScriptLoader() {
+ this.cpt = 0;
+ this.scriptTab = new Array();
+ this.add = addAScriptInTheList;
+ this.load = loadTheScripts;
+ this.onScriptLoaded = onScriptLoadedFunc;
+}
+
+function addAScriptInTheList(scriptPath) {
+ this.scriptTab.push(scriptPath);
+}
+
+function loadTheScripts() {
+ var script;
+ var head;
+
+ head = document.getElementsByTagName('head').item(0);
+
+ //script = document.createElement('script');
+
+ for (var el in this.scriptTab) {
+ //alert (el+this.scriptTab[el]);
+ script = document.createElement('script');
+ script.src = this.scriptTab[el];
+ script.type = 'text/javascript';
+ script.defer = false;
+
+ head.appendChild(script);
+ }
+
+}
+
+function onScriptLoadedFunc(e) {
+ e = e || window.event;
+ var target = e.target || e.srcElement;
+ var isComplete = true;
+ if (typeof target.readyState != undefined) {
+
+ isComplete = (target.readyState == "complete" || target.readyState == "loaded");
+ }
+ if (isComplete) {
+ ScriptLoader.cpt++;
+ if (ScriptLoader.cpt == ScriptLoader.scripts.length) {
+ ScriptLoader.onLoadComplete();
+ }
+ }
+}
+
+/*
+function onLoadComplete() {
+ alert("loaded !!");
+} */
+
+/* End of scriptloader functions */
+
+// Array.unique( strict ) - Remove duplicate values
+function unique(tab) {
+ var a = new Array();
+ var i;
+ var l = tab.length;
+
+ if (tab[0] != undefined) {
+ a[0] = tab[0];
+ }
+ else {
+ return -1;
+ }
+
+ for (i = 1; i < l; i++) {
+ if (indexof(a, tab[i], 0) < 0) {
+ a.push(tab[i]);
+ }
+ }
+ return a;
+}
+function indexof(tab, element, begin) {
+ for (var i = begin; i < tab.length; i++) {
+ if (tab[i] == element) {
+ return i;
+ }
+ }
+ return -1;
+
+}
+/* end of Array functions */
+
+
+/*
+ Param: mots= list of words to look for.
+ This function creates an hashtable:
+ - The key is the index of a html file which contains a word to look for.
+ - The value is the list of all words contained in the html file.
+
+ Return value: the hashtable fileAndWordList
+ */
+function SortResults(mots) {
+
+ var fileAndWordList = new Object();
+ if (mots.length == 0 || mots[0].length == 0) {
+ return null;
+ }
+
+
+ // In generated js file we add scoring at the end of the word
+ // Example word1*scoringForWord1,word2*scoringForWord2 and so on
+ // Split after * to obtain the right values
+ var scoringArr = Array();
+ for (var t in mots) {
+ // get the list of the indices of the files.
+ var listNumerosDesFicStr = w[mots[t].toString()];
+
+ if (listNumerosDesFicStr != undefined) {
+
+ //alert ("listNumerosDesFicStr "+listNumerosDesFicStr);
+ var tab = listNumerosDesFicStr.split(",");
+ //for each file (file's index):
+ for (var t2 in tab) {
+ var tmp = '';
+ var idx = '';
+ var temp = tab[t2].toString();
+ if (temp.indexOf('*') != -1) {
+ idx = temp.indexOf('*');
+ tmp = temp.substring(idx + 3, temp.length);
+ temp = temp.substring(0, idx);
+ }
+ scoringArr.push(tmp);
+ if (fileAndWordList[temp] == undefined) {
+ fileAndWordList[temp] = "" + mots[t];
+ } else {
+ fileAndWordList[temp] += "," + mots[t];
+ }
+ //console.info("fileAndWordList[" + temp + "]=" + fileAndWordList[temp] + " : " + tmp);
+ }
+
+ }
+ }
+ var fileAndWordListValuesOnly = new Array();
+ // sort results according to values
+ var temptab = new Array();
+ finalObj = new Array();
+ for (t in fileAndWordList) {
+ finalObj.push(new newObj(t,fileAndWordList[t]));
+ }
+
+ if ( finalObj.length == 0 ) { // None of the queried words are not in the index (stemmed or not)
+ return null;
+ }
+ finalObj = removeDerivates(finalObj);
+ for (t in finalObj) {
+ tab = finalObj[t].wordList.split(',');
+ var tempDisplay = new Array();
+ for (var x in tab) {
+ if(stemQueryMap[tab[x]] != undefined && doStem){
+ tempDisplay.push(stemQueryMap[tab[x]]); //get the original word from the stem word.
+ } else {
+ tempDisplay.push(tab[x]); //no stem is available. (probably a CJK language)
+ }
+ }
+ var tempDispString = tempDisplay.join(", ");
+ var index;
+ for (x in fileAndWordList) {
+ if (x === finalObj[t].filesNo) {
+ index = x;
+ break;
+ }
+ }
+ var scoring = findRating(fileAndWordList[index], index);
+ temptab.push(new resultPerFile(finalObj[t].filesNo, finalObj[t].wordList, tab.length, tempDispString, scoring));
+ fileAndWordListValuesOnly.push(finalObj[t].wordList);
+ }
+ fileAndWordListValuesOnly = unique(fileAndWordListValuesOnly);
+ fileAndWordListValuesOnly = fileAndWordListValuesOnly.sort(compare_nbMots);
+
+ var listToOutput = new Array();
+ for (var fawlvoIdx in fileAndWordListValuesOnly) {
+ for (t in temptab) {
+ if (temptab[t].motsliste == fileAndWordListValuesOnly[fawlvoIdx]) {
+ if (listToOutput[fawlvoIdx] == undefined) {
+ listToOutput[fawlvoIdx] = new Array(temptab[t]);
+ } else {
+ listToOutput[fawlvoIdx].push(temptab[t]);
+ }
+ }
+ }
+ }
+ // Sort results by scoring, descending on the same group
+ for (var ltoIdx in listToOutput) {
+ listToOutput[ltoIdx].sort(function(a, b){
+ return b.scoring - a.scoring;
+ });
+ }
+ // If we have groups with same number of words,
+ // will sort groups by higher scoring of each group
+ for (var i = 0; i < listToOutput.length - 1; i++) {
+ for (var j = i + 1; j < listToOutput.length; j++) {
+ if (listToOutput[i][0].motsnb < listToOutput[j][0].motsnb
+ || (listToOutput[i][0].motsnb == listToOutput[j][0].motsnb
+ && listToOutput[i][0].scoring < listToOutput[j][0].scoring)
+ ) {
+ var x = listToOutput[i];
+ listToOutput[i] = listToOutput[j];
+ listToOutput[j] = x;
+ }
+ }
+ }
+
+ return listToOutput;
+}
+
+// Remove derivates words from the list of words
+function removeDerivates(obj){
+ var toResultObject = new Array();
+ for (i in obj){
+ var filesNo = obj[i].filesNo;
+ var wordList = obj[i].wordList;
+ var wList = wordList.split(",");
+ var searchedWords = searchTextField.toLowerCase().split(" ");
+ for (var k = 0 ; k < searchedWords.length ; k++){
+ for (var j = 0 ; j < wList.length ; j++){
+ if (wList[j].startsWith(searchedWords[k])){
+ wList[j] = searchedWords[k];
+ }
+ }
+ }
+ wList = removeDuplicate(wList);
+ var recreateList = '';
+ for(var x in wList){
+ recreateList+=wList[x] + ",";
+ }
+ recreateList = recreateList.substr(0, recreateList.length - 1);
+ toResultObject.push(new newObj(filesNo, recreateList));
+ }
+ return toResultObject;
+}
+
+function newObj(filesNo, wordList){
+ this.filesNo = filesNo;
+ this.wordList = wordList;
+}
+
+// Add a new parameter. Scoring.
+function resultPerFile(filenb, motsliste, motsnb, motslisteDisplay, scoring, group) {
+ //10 - spring,time - 2 - spring, time - 55 - 3
+ this.filenb = filenb;
+ this.motsliste = motsliste;
+ this.motsnb = motsnb;
+ this.motslisteDisplay= motslisteDisplay;
+
+ this.scoring = scoring;
+
+}
+
+
+function findRating(words, nr){
+ var sum = 0;
+ var xx = words.split(',');
+ for (jj = 0 ; jj < xx.length ; jj++){
+ var wrd = w[xx[jj]].split(',');
+ for (var ii = 0 ; ii < wrd.length ; ii++){
+ var wrdno = wrd[ii].split('*');
+ if (wrdno[0] == nr){
+ sum+=parseInt(wrdno[1]);
+ }
+ }
+ }
+ return sum;
+}
+
+function compare_nbMots(s1, s2) {
+ var t1 = s1.split(',');
+ var t2 = s2.split(',');
+ //alert ("s1:"+t1.length + " " +t2.length)
+ if (t1.length == t2.length) {
+ return 0;
+ } else if (t1.length > t2.length) {
+ return 1;
+ } else {
+ return -1;
+ }
+ //return t1.length - t2.length);
+}
+
+// return false if browser is Google Chrome and WebHelp is used on a local machine, not a web server
+function verifyBrowser(){
+ var returnedValue = true;
+ var browser = BrowserDetect.browser;
+ var addressBar = window.location.href;
+ if (browser == 'Chrome' && addressBar.indexOf('file://') === 0){
+ returnedValue = false;
+ }
+
+ return returnedValue;
+}
+
+// Remove duplicate values from an array
+function removeDuplicate(arr) {
+ var r = new Array();
+ o:for(var i = 0, n = arr.length; i < n; i++) {
+ for(var x = 0, y = r.length; x < y; x++) {
+ if(r[x]==arr[i]) continue o;
+ }
+ r[r.length] = arr[i];
+ }
+ return r;
+}
+
+// Create startsWith method
+String.prototype.startsWith = function(str) {
+ return (this.match("^"+str)==str);
+}
+
+function trim(str, chars) {
+ return ltrim(rtrim(str, chars), chars);
+}
+
+function ltrim(str, chars) {
+ chars = chars || "\\s";
+ return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
+}
+
+function rtrim(str, chars) {
+ chars = chars || "\\s";
+ return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
+}
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/stemmers/en_stemmer.js b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/stemmers/en_stemmer.js
new file mode 100644
index 000000000..2117c1bfb
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/search/stemmers/en_stemmer.js
@@ -0,0 +1,234 @@
+// Porter stemmer in Javascript. Few comments, but it's easy to follow against the rules in the original
+// paper, in
+//
+// Porter, 1980, An algorithm for suffix stripping, Program, Vol. 14,
+// no. 3, pp 130-137,
+//
+// see also http://www.tartarus.org/~martin/PorterStemmer
+
+// Release 1
+// Derived from (http://tartarus.org/~martin/PorterStemmer/js.txt) - cjm (iizuu) Aug 24, 2009
+
+var stemmer = (function(){
+ var step2list = {
+ "ational" : "ate",
+ "tional" : "tion",
+ "enci" : "ence",
+ "anci" : "ance",
+ "izer" : "ize",
+ "bli" : "ble",
+ "alli" : "al",
+ "entli" : "ent",
+ "eli" : "e",
+ "ousli" : "ous",
+ "ization" : "ize",
+ "ation" : "ate",
+ "ator" : "ate",
+ "alism" : "al",
+ "iveness" : "ive",
+ "fulness" : "ful",
+ "ousness" : "ous",
+ "aliti" : "al",
+ "iviti" : "ive",
+ "biliti" : "ble",
+ "logi" : "log"
+ },
+
+ step3list = {
+ "icate" : "ic",
+ "ative" : "",
+ "alize" : "al",
+ "iciti" : "ic",
+ "ical" : "ic",
+ "ful" : "",
+ "ness" : ""
+ },
+
+ c = "[^aeiou]", // consonant
+ v = "[aeiouy]", // vowel
+ C = c + "[^aeiouy]*", // consonant sequence
+ V = v + "[aeiou]*", // vowel sequence
+
+ mgr0 = "^(" + C + ")?" + V + C, // [C]VC... is m>0
+ meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$", // [C]VC[V] is m=1
+ mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1
+ s_v = "^(" + C + ")?" + v; // vowel in stem
+
+ return function (w) {
+ var stem,
+ suffix,
+ firstch,
+ re,
+ re2,
+ re3,
+ re4,
+ origword = w;
+
+ if (w.length < 3) { return w; }
+
+ firstch = w.substr(0,1);
+ if (firstch == "y") {
+ w = firstch.toUpperCase() + w.substr(1);
+ }
+
+ // Step 1a
+ re = /^(.+?)(ss|i)es$/;
+ re2 = /^(.+?)([^s])s$/;
+
+ if (re.test(w)) { w = w.replace(re,"$1$2"); }
+ else if (re2.test(w)) { w = w.replace(re2,"$1$2"); }
+
+ // Step 1b
+ re = /^(.+?)eed$/;
+ re2 = /^(.+?)(ed|ing)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ re = new RegExp(mgr0);
+ if (re.test(fp[1])) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ } else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1];
+ re2 = new RegExp(s_v);
+ if (re2.test(stem)) {
+ w = stem;
+ re2 = /(at|bl|iz)$/;
+ re3 = new RegExp("([^aeiouylsz])\\1$");
+ re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re2.test(w)) { w = w + "e"; }
+ else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); }
+ else if (re4.test(w)) { w = w + "e"; }
+ }
+ }
+
+ // Step 1c
+ re = new RegExp("^(.+" + c + ")y$");
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ w = stem + "i";
+ }
+
+ // Step 2
+ re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem)) {
+ w = stem + step2list[suffix];
+ }
+ }
+
+ // Step 3
+ re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem)) {
+ w = stem + step3list[suffix];
+ }
+ }
+
+ // Step 4
+ re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+ re2 = /^(.+?)(s|t)(ion)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ if (re.test(stem)) {
+ w = stem;
+ }
+ } else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1] + fp[2];
+ re2 = new RegExp(mgr1);
+ if (re2.test(stem)) {
+ w = stem;
+ }
+ }
+
+ // Step 5
+ re = /^(.+?)e$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ re2 = new RegExp(meq1);
+ re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) {
+ w = stem;
+ }
+ }
+
+ re = /ll$/;
+ re2 = new RegExp(mgr1);
+ if (re.test(w) && re2.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+
+ // and turn initial Y back to y
+
+ if (firstch == "y") {
+ w = firstch.toLowerCase() + w.substr(1);
+ }
+
+ // See http://snowball.tartarus.org/algorithms/english/stemmer.html
+ // "Exceptional forms in general"
+ var specialWords = {
+ "skis" : "ski",
+ "skies" : "sky",
+ "dying" : "die",
+ "lying" : "lie",
+ "tying" : "tie",
+ "idly" : "idl",
+ "gently" : "gentl",
+ "ugly" : "ugli",
+ "early": "earli",
+ "only": "onli",
+ "singly": "singl"
+ };
+
+ if(specialWords[origword]){
+ w = specialWords[origword];
+ }
+
+ if( "sky news howe atlas cosmos bias \
+ andes inning outing canning herring \
+ earring proceed exceed succeed".indexOf(origword) !== -1 ){
+ w = origword;
+ }
+
+ // Address words overstemmed as gener-
+ re = /.*generate?s?d?(ing)?$/;
+ if( re.test(origword) ){
+ w = w + 'at';
+ }
+ re = /.*general(ly)?$/;
+ if( re.test(origword) ){
+ w = w + 'al';
+ }
+ re = /.*generic(ally)?$/;
+ if( re.test(origword) ){
+ w = w + 'ic';
+ }
+ re = /.*generous(ly)?$/;
+ if( re.test(origword) ){
+ w = w + 'ous';
+ }
+ // Address words overstemmed as commun-
+ re = /.*communit(ies)?y?/;
+ if( re.test(origword) ){
+ w = w + 'iti';
+ }
+
+ return w;
+ }
+})();
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr32_memtypes.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr32_memtypes.html
new file mode 100644
index 000000000..2020681c5
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr32_memtypes.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Memory Types - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01s12.html" title="Write" /><link rel="prev" href="ch05s01s12.html" title="Write" /><link rel="next" href="ch05s01s13.html" title="TAP" /><meta content="Memory Types" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Write</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s12.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01s12.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s13.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="section_avr32_memtypes" />Memory Types</h4></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N11426" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;83.&nbsp;AVR32 memtypes</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="AVR32 memtypes" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>ID</th><th>Acc</th><th>Description</th><th>Restrictions</th></tr></thead><tbody><tr><td>AVR32_MEMTYPE_SAB</td><td>RW</td><td>SAB word access</td><td><p>Bytes = 4</p><p>Address = SAB (byte) address</p></td></tr><tr><td>AVR32_MEMTYPE_NEXUS</td><td>RW</td><td>Nexus word access</td><td><p>Bytes = 4</p><p>Address = Nexus address (index)</p></td></tr><tr><td>AVR32_MEMTYPE_MEMORY_SERVICE</td><td>RW</td><td>Memory service word access</td><td><p>Bytes = 4</p><p>Address = Nexus address (index)</p></td></tr><tr><td>AVR32_MEMTYPE_BLOCK</td><td>RW</td><td>Block access</td><td><p>Bytes = n * 4</p><p>Address = SAB (byte) address</p></td></tr><tr><td>AVR32_MEMTYPE_BYTE</td><td>RW</td><td>Byte (sized) access</td><td><p>Bytes = 1</p><p>Address = SAB (byte) address</p></td></tr><tr><td>AVR32_MEMTYPE_HALF_WORD</td><td>RW</td><td>Half-word (sized) access</td><td><p>Bytes = 2</p><p>Address = SAB (byte) address</p><p>Must be word aligned!</p></td></tr><tr><td>AVR32_MEMTYPE_INTERNAL_FLASH</td><td>W</td><td>Flash page access</td><td><p>Bytes = full page</p><p>Address = SAB (byte) address</p></td></tr><tr><td>AVR32_MEMTYPE_SYSREG</td><td>RW</td><td>System register access</td><td><p>Bytes = 4</p><p>Address &lt; 1024</p><p>system register (byte) address</p></td></tr><tr><td>AVR32_MEMTYPE_REGFILE</td><td>RW</td><td>Register file access (only complete register file can be accessed)</td><td><p>Bytes = 16*4</p><p>address = 0</p></td></tr><tr><td>AVR32_MEMTYPE_USER_PAGE</td><td>W</td><td>Flash user page access</td><td><p>Bytes = full page</p><p>Address = SAB (byte) address</p></td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s12.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01s12.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s13.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr32_setget_params.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr32_setget_params.html
new file mode 100644
index 000000000..ba0618af9
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr32_setget_params.html
@@ -0,0 +1,217 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SET/GET parameters - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01s03.html" title="GET" /><link rel="prev" href="ch05s01s03.html" title="GET" /><link rel="next" href="ch05s01s04.html" title="Activate Physical" /><meta content="SET/GET parameters" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />GET</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="section_avr32_setget_params" />SET/GET parameters</h4></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N11135" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;73.&nbsp;AVR32 SET/GET parameters</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="AVR32 SET/GET parameters" border="1"><colgroup><col /><col /><col /><col /><col /></colgroup><thead><tr><th>Context</th><th>ID</th><th>Description</th><th>Acc</th><th>Size</th></tr></thead><tbody><tr><td rowspan="2">AVR32_CTXT_USB</td><td>AVR32_USB_MAX_READ</td><td>Maximum payload for reading is (2^MAX_READ)</td><td>R</td><td>1 byte</td></tr><tr><td>AVR32_USB_MAX_WRITE</td><td>Maximum payload for writing is (2^MAX_WRITE)</td><td>R</td><td>1 byte </td></tr><tr><td>AVR32_CTXT_SESSION</td><td>AVR32_SESS_RUN_LED</td><td><p>Sets the RUN indicator</p><p>0x00 = stopped</p><p>0x01 = running</p></td><td>W</td><td>1 byte</td></tr><tr><td rowspan="5">AVR32_CTXT_PHYSICAL</td><td>AVR32_PHY_PHYSICAL</td><td><p>Selects the physical interface</p><p>0x00 = None</p><p>0x04 = JTAG</p><p>0x07 = aWire</p></td><td>RW</td><td>1 byte</td></tr><tr><td>AVR32_PHY_JTAG_CLOCK</td><td>JTAG clock frequency [kHz]</td><td>RW</td><td>2 bytes </td></tr><tr><td>AVR32_PHY_AW_MAXBAUD</td><td><p>Maximum aWire baud [kbps]</p><p>Baud rate is configured automatically, but a ceiling value can be set.</p></td><td>RW</td><td>2 bytes </td></tr><tr><td>AVR32_PHY_DAISY</td><td>
+ <p>Devices before &lt;&lt; 24</p>
+ <p>Devices after &lt;&lt; 16</p>
+ <p>IR-bits before &lt;&lt; 8</p>
+ <p>IR-bits after &lt;&lt; 0</p>
+ <p>Note that daisy chain settings must be written before activating the JTAG physical. </p></td><td>RW</td><td>4 bytes</td></tr><tr><td>AVR32_PHY_EXT_RESET</td><td><p>Applies or releases the /RESET line:</p><p>0x01: pulls the /RESET line to ground</p><p>0x01: releases /RESET. </p>
+ <p>The user is responsible for releasing /RESET after pulling it low in this way.</p></td><td>W</td><td>1 byte</td></tr><tr><td rowspan="5">AVR32_CTXT_DEVICE</td><td>AVR32_FLASH_CTRL_BASE</td><td>Flash controller base address [byte address] </td><td>W</td><td>4 bytes</td></tr><tr><td>AVR32_FLASH_PAGEBYTES</td><td>Number of bytes in one flash page.</td><td>W</td><td>2 bytes</td></tr><tr><td>AVR32_RESET_DOMAINS</td><td><p>Number of reset domains in target device.</p><p>Usually 5 for UC3A/B and 1 for UC3C/L.</p></td><td>W</td><td>1 byte</td></tr><tr><td>AVR32_FLASH_PAGES</td><td>Number of pages in the flash block</td><td>W</td><td>2 bytes</td></tr><tr><td>AVR32_AWIRE_BASE</td><td>Base address for aWire module</td><td>W</td><td>4 bytes</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_memtypes.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_memtypes.html
new file mode 100644
index 000000000..e2c655212
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_memtypes.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Memory Types - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.avr8protocol.html" title="AVR8 generic protocol" /><link rel="prev" href="ch06s03s02.html" title="Event: IDR message" /><link rel="next" href="ch06s04s01.html" title="debugWIRE memtypes" /><meta content="Memory Types" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />AVR8 generic protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s03s02.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.avr8protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s04s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="section_avr8_memtypes" />Memory Types</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch06s04s01.html">debugWIRE memtypes</a></span></dt><dt><span class="section"><a href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></dt><dt><span class="section"><a href="ch06s04s03.html">AVR XMEGA memtypes</a></span></dt></dl></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s03s02.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.avr8protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s04s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_query_contexts.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_query_contexts.html
new file mode 100644
index 000000000..cd053c49e
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_query_contexts.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>AVR8 QUERY contexts - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01s01.html" title="QUERY" /><link rel="prev" href="ch06s01s01.html" title="QUERY" /><link rel="next" href="ch06s01s02.html" title="SET" /><meta content="AVR8 QUERY contexts" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />QUERY</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="section_avr8_query_contexts" />AVR8 QUERY contexts</h4></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N1175C" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;95.&nbsp;AVR8 QUERY contexts</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="AVR8 QUERY contexts" border="1"><colgroup><col class="c1" /><col class="c2" /><col /></colgroup><thead><tr><th>ID</th><th>Description</th><th>Response</th></tr></thead><tbody><tr><td>AVR8_QUERY_COMMANDS</td><td>Lists protocol commands supported</td><td>List of n * [byte]</td></tr><tr><td>AVR8_QUERY_CONFIGURATION</td><td>Lists configuration parameters supported</td><td>List of n * [byte]</td></tr><tr><td>AVR8_QUERY_READ_MEMTYPES</td><td>Lists readable memtypes</td><td>List of n * [byte]</td></tr><tr><td>AVR8_QUERY_WRITE_MEMTYPES</td><td>Lists writeable memtypes</td><td>List of n * [byte]</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_setget_params.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_setget_params.html
new file mode 100644
index 000000000..50639ee46
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_avr8_setget_params.html
@@ -0,0 +1,231 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>SET/GET parameters - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch06s01s03.html" title="GET" /><link rel="prev" href="ch06s01s03.html" title="GET" /><link rel="next" href="ch06s01s04.html" title="Activate Physical" /><meta content="SET/GET parameters" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />GET</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch06s01s03.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch06s01s03.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch06s01s04.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="section_avr8_setget_params" />SET/GET parameters</h4></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></dt><dt><span class="section"><a href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></dt><dt><span class="section"><a href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></dt></dl></div><div class="table"><a id="N1183E" /><p class="title"><strong>Table&nbsp;98.&nbsp;AVR8 SET/GET parameters</strong></p><div class="table-contents"><table summary="AVR8 SET/GET parameters" border="1"><colgroup><col /><col /><col /><col /><col /></colgroup><thead><tr><th>Context</th><th>ID</th><th>Description / values</th><th>Access</th><th>Size</th></tr></thead><tbody><tr><td rowspan="2">AVR8_CTXT_CONFIG </td><td>AVR8_CONFIG_VARIANT</td><td><p>AVR8_VARIANT_LOOPBACK</p><p>AVR8_VARIANT_TINYOCD</p><p>AVR8_VARIANT_MEGAOCD</p><p>AVR8_VARIANT_XMEGA</p><p>AVR8_VARIANT_NONE</p></td><td>W</td><td>1 byte</td></tr><tr><td>AVR8_CONFIG_FUNCTION</td><td><p>AVR8_FUNC_NONE</p><p>AVR8_FUNC_PROGRAMMING</p>
+ <p>AVR8_FUNC_DEBUGGING</p></td><td>W</td><td>1 byte</td></tr><tr><td rowspan="7">AVR8_CTXT_PHYSICAL</td><td>AVR8_PHY_PHYSICAL</td><td><p>AVR8_PHY_INTF_NONE</p><p>AVR8_PHY_INTF_JTAG</p><p>AVR8_PHY_INTF_DW</p><p>AVR8_PHY_INTF_PDI</p></td><td>W</td><td>1 byte</td></tr><tr><td>AVR8_PHY_JTAG_DAISY</td><td><p>Devices before &lt;&lt; 24</p>
+ <p>Devices after &lt;&lt; 16</p>
+ <p>IR-bits before &lt;&lt; 8</p>
+ <p>IR-bits after &lt;&lt; 0</p>
+ <p>Note that daisy chain settings must be written before activating the JTAG physical. </p></td><td>RW</td><td>4 bytes</td></tr><tr><td>AVR8_PHY_DW_CLK_DIV</td><td>debugWIRE clock division factor</td><td>W</td><td>1 byte </td></tr><tr><td>AVR8_PHY_MEGA_PRG_CLK</td><td><p>JTAG clock frequency (kHz) for programming megaAVR</p>
+ <p>Note: this frequency is limited by the target silicon itself</p></td><td>W</td><td>2 bytes </td></tr><tr><td>AVR8_PHY_MEGA_DBG_CLK</td><td><p>JTAG clock frequency (kHz) for debugging megaAVR</p>
+ <p>Note: this frequency must be less than a quarter of the active target clock</p></td><td>W</td><td>2 bytes </td></tr><tr><td>AVR8_PHY_XM_JTAG_CLK</td><td><p>JTAG clock frequency (kHz) for programming and debugging AVR XMEGA</p>
+ <p>Note: this frequency is limited by the target silicon itself</p></td><td>W</td><td>2 bytes </td></tr><tr><td>AVR8_PHY_XM_PDI_CLK</td><td><p>PDI clock frequency (kHz) for programming and debugging AVR XMEGA</p>
+ <p>Note: this frequency is limited by the target silicon itself</p></td><td>W</td><td>2 bytes </td></tr><tr><td>AVR8_CTXT_DEVICE</td><td>&nbsp;</td><td>see tables below for family specific contexts</td><td>W</td><td>&nbsp;</td></tr><tr><td rowspan="4">AVR8_CTXT_OPTIONS</td><td>AVR8_OPT_RUN_TIMERS</td><td>Run timers in stopped mode.
+ This option allows timers to continue to run even when the device has entered stopped mode.
+ This is especially useful for maintaining PWM output values for example in motor control applications.
+ Note that timer interrupts will NOT be serviced until RUN mode is entered. (Not available in AVR XMEGA)
+ </td><td>W</td><td>1 byte</td></tr><tr><td>AVR8_OPT_DISABLE_DBP</td><td>Disables data breaks when resetting.
+ Used internally to prevent variable initialisation routines from triggerring data breakpoints.</td><td>W</td><td>1 byte</td></tr><tr><td>AVR8_OPT_ENABLE_IDR</td><td>Enables messages from the target core.
+ IDR messages can be sent from some target types by writing to the OCD data register during RUN mode.
+ When this option is enabled, these data values will be routed to USB EVENT messages.</td><td>W</td><td>1byte</td></tr><tr><td>AVR8_OPT_POLL_INT</td><td>Adjusts how often the debugger polls the target's state. Value
+ given as polling interval in ms. Possible values: 1, 5, 10, 20, 50
+ and 100.</td><td>W</td><td>1byte</td></tr><tr><td>AVR8_CTXT_SESSION</td><td>AVR8_SESS_MAIN_PC (deprecated)</td><td>Program counter value [word address] of main() function</td><td>W</td><td>4 bytes</td></tr><tr><td>AVR8_CTXT_TEST</td><td>AVR8_TEST_TGT_RUNNING</td><td><p>Actively polls the targets RUN/STOP state.</p><p>0x00 = STOPPED</p><p>0x01 = RUNNING</p></td><td>R</td><td>1 byte</td></tr></tbody></table></div></div><br class="table-break" /><div class="section"><div xmlns="" class="titlepage"><div><div><h5 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N11932" />Device context: debugWIRE targets</h5></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N11935" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;99.&nbsp;Device context: debugWIRE targets</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="Device context: debugWIRE targets" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Addr</th><th>Name</th><th>Description</th><th>Size</th></tr></thead><tbody><tr><td>0x00</td><td>FLASH_PAGE_BYTES</td><td>Flash page size (bytes)</td><td>2 bytes</td></tr><tr><td>0x02</td><td>FLASH_BYTES</td><td>Flash size (bytes)</td><td>4 bytes</td></tr><tr><td>0x06</td><td>FLASH_BASE</td><td>Base address of flash </td><td>4 bytes</td></tr><tr><td>0x0A</td><td>BOOT_SECTION_START</td><td>Start address of boot section</td><td>4 bytes</td></tr><tr><td>0x0E</td><td>SRAM_START</td><td>Start address of SRAM</td><td>2 bytes</td></tr><tr><td>0x10</td><td>EEPROM_SIZE</td><td>EEPROM size (bytes)</td><td>2 bytes</td></tr><tr><td>0x12</td><td>EEPROM_PAGE_SIZE</td><td>EEPROM page size (bytes)</td><td>1 byte</td></tr><tr><td>0x13</td><td>OCD_REV</td><td>OCD revision</td><td>1 byte</td></tr><tr><td>0x18</td><td>OCDR_ADDR</td><td>OCDR address</td><td>1 byte</td></tr><tr><td>0x19</td><td>EEARH_ADDR</td><td>EEARH address (or EEAR address if only one byte EEAR register)</td><td>1 byte</td></tr><tr><td>0x1A</td><td>EEARL_ADDR</td><td>EEARL address (or EEAR address if only one byte EEAR register)</td><td>1 byte</td></tr><tr><td>0x1B</td><td>EECR_ADDR</td><td>EECR address</td><td>1 byte</td></tr><tr><td>0x1C</td><td>EEDR_ADDR</td><td>EEDR address</td><td>1 byte</td></tr><tr><td>0x1D</td><td>SPMCR_ADDR</td><td>SPMCR address</td><td>1 byte</td></tr><tr><td>0x1E</td><td>OSCCAL_ADDR</td><td>OSCCAL address</td><td>1 byte</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="section"><div xmlns="" class="titlepage"><div><div><h5 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="N119D3" />Device context: megaAVR JTAG targets</h5></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N119D6" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;100.&nbsp;Device context: Mega targets</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="Device context: Mega targets" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Addr</th><th>Name</th><th>Description</th><th>Size</th></tr></thead><tbody><tr><td>0x00</td><td>FLASH_PAGE_BYTES</td><td>Flash page size (bytes)</td><td>2 bytes</td></tr><tr><td>0x02</td><td>FLASH_BYTES</td><td>Flash size (bytes)</td><td>4 bytes</td></tr><tr><td>0x06</td><td>FLASH_BASE</td><td>Base address of flash (word address)</td><td>4 bytes</td></tr><tr><td>0x0A</td><td>BOOT_SECTION_START</td><td>Start address of boot section (word address)</td><td>4 bytes</td></tr><tr><td>0x0E</td><td>SRAM_START</td><td>Start address of SRAM (byte address)</td><td>2 bytes</td></tr><tr><td>0x10</td><td>EEPROM_SIZE</td><td>EEPROM size (bytes)</td><td>2 bytes</td></tr><tr><td>0x12</td><td>EEPROM_PAGE_SIZE</td><td>EEPROM page size (bytes)</td><td>1 byte</td></tr><tr><td>0x13</td><td>OCD_REV</td><td>OCD revision</td><td>1 byte</td></tr><tr><td>0x18</td><td>OCDR_ADDR</td><td>OCDR address</td><td>1 byte</td></tr><tr><td>0x19</td><td>EEARH_ADDR</td><td>EEARH address (or EEAR address if only one byte EEAR register)</td><td>1 byte</td></tr><tr><td>0x1A</td><td>EEARL_ADDR</td><td>EEARL address (or EEAR address if only one byte EEAR register)</td><td>1 byte</td></tr><tr><td>0x1B</td><td>EECR_ADDR</td><td>EECR address</td><td>1 byte</td></tr><tr><td>0x1C</td><td>EEDR_ADDR</td><td>EEDR address</td><td>1 byte</td></tr><tr><td>0x1D</td><td>SPMCR_ADDR</td><td>SPMCR address</td><td>1 byte</td></tr><tr><td>0x1E</td><td>OSCCAL_ADDR</td><td>OSCCAL address</td><td>1 byte</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="section"><div xmlns="" class="titlepage"><div><div><h5 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="section_avr8_xmega_device_context" />Device context: AVR XMEGA targets</h5></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N11A78" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;101.&nbsp;Device context: XMEGA targets</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="Device context: XMEGA targets" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Addr</th><th>Name</th><th>Description</th><th>Size</th></tr></thead><tbody><tr><td>0x00</td><td>APPL_BASE_ADDR</td><td>PDI offset for application part of flash (byte
+ address)</td><td>4 bytes</td></tr><tr><td>0x04</td><td>BOOT_BASE_ADDR</td><td>PDI offset for boot part of flash (byte address)</td><td>4 bytes</td></tr><tr><td>0x08</td><td>EEPROM_BASE_ADDR</td><td>PDI offset for EEPROM (byte address)</td><td>4 bytes</td></tr><tr><td>0x0C</td><td>FUSE_BASE_ADDR</td><td>PDI offset for fuses (byte address)</td><td>4 bytes</td></tr><tr><td>0x10</td><td>LOCKBIT_BASE_ADDR</td><td>PDI offset for lock bits (byte address)</td><td>4 bytes</td></tr><tr><td>0x14</td><td>USER_SIGN_BASE_ADDR</td><td>PDI offset for user signature (byte address)</td><td>4 bytes</td></tr><tr><td>0x18</td><td>PROD_SIGN_BASE_ADDR</td><td>PDI offset for production signature (byte
+ address)</td><td>4 bytes</td></tr><tr><td>0x1C</td><td>DATA_BASE_ADDR</td><td>PDI offset for SRAM (byte address)</td><td>4 bytes</td></tr><tr><td>0x20</td><td>APPLICATION _BYTES</td><td>Application section size (bytes)</td><td>4 bytes</td></tr><tr><td>0x24</td><td>BOOT_BYTES</td><td>Boot section size (bytes)</td><td>2 bytes</td></tr><tr><td>0x26</td><td>FLASH_PAGE_BYTES</td><td>Flash page size (bytes)</td><td>2 bytes</td></tr><tr><td>0x28</td><td>EEPROM_SIZE</td><td>EEPROM size (bytes)</td><td>2 bytes</td></tr><tr><td>0x2A</td><td>EEPROM_PAGE_SIZE</td><td>EEPROM page size (bytes)</td><td>1 byte</td></tr><tr><td>0x2B</td><td>NVM_BASE</td><td>NVM controller module base address</td><td>2 bytes</td></tr><tr><td>0x2D</td><td>SIGNATURE_OFFSET</td><td>PDI offset for signature (byte address)</td><td>2 bytes</td></tr></tbody></table></div></div><br class="table-break" /></div></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch06s01s03.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch06s01s03.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch06s01s04.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_edbg_ctrl_setget_params.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_edbg_ctrl_setget_params.html
new file mode 100644
index 000000000..26e6e639e
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_edbg_ctrl_setget_params.html
@@ -0,0 +1,368 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>EDBGCTRL ID definitions - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.edbg_ctrl_protocol.html" title="EDBG Control Protocol" /><link rel="prev" href="ch03s02s04.html" title="FAILED" /><link rel="next" href="protocoldocs.avrprotocol.Overview.html" title="AVR communication protocol" /><meta content="EDBGCTRL ID definitions" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />EDBG Control Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch03s02s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.edbg_ctrl_protocol.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="protocoldocs.avrprotocol.Overview.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="section_edbg_ctrl_setget_params" />EDBGCTRL ID definitions</h2></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">
+ This sections includes the header file defining the different command and
+ response IDs for the EDBGCTRL protocol. It also defines the different possible failure codes.
+ </p><pre class="programlisting"><span class="hl-keyword" style="color: #0000FF">enum</span> EdbgCommands {
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+ <em class="hl-comment" style="color: #008000">// Protocol commands</em>
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+
+ <em class="hl-comment" style="color: #008000">// Basics</em>
+ CMD_EDBG_QUERY = <span class="hl-number">0x00</span>,
+ CMD_EDBG_SET = <span class="hl-number">0x01</span>,
+ CMD_EDBG_GET = <span class="hl-number">0x02</span>,
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> EdbgResponses {
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+ <em class="hl-comment" style="color: #008000">// Protocol responses</em>
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+
+ RSP_EDBG_OK = <span class="hl-number">0x80</span>,
+ RSP_EDBG_LIST = <span class="hl-number">0x81</span>,
+ RSP_EDBG_DATA = <span class="hl-number">0x84</span>,
+ RSP_EDBG_FAILED = <span class="hl-number">0xA0</span>
+};
+
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> EdbgFailureCodes {
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+ <em class="hl-comment" style="color: #008000">// Failure response codes (RSP_FAILED)</em>
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+
+ EDBG_FAILED_OK = <span class="hl-number">0x00</span>,
+ EDBG_FAILED_NOT_SUPPORTED = <span class="hl-number">0x01</span>,
+ EDBG_FAILED_ILLEGAL_GPIO_PIN = <span class="hl-number">0x10</span>,
+ EDBG_FAILED_ILLEGAL_GPIO_MODE = <span class="hl-number">0x11</span>,
+ EDBG_FAILED_ILLEGAL_VOLTAGE_RANGE = <span class="hl-number">0x12</span>,
+ EDBG_FAILED_ILLEGAL_INTERVAL = <span class="hl-number">0x13</span>,
+ EDBG_FAILED_ILLEGAL_MAX_THRESHOLD = <span class="hl-number">0x14</span>,
+ EDBG_FAILED_ILLEGAL_MIN_THRESHOLD = <span class="hl-number">0x15</span>,
+ EDBG_FAILED_ILLEGAL_ACTION = <span class="hl-number">0x16</span>,
+ EDBG_FAILED_ILLEGAL_FREQUENCY = <span class="hl-number">0x17</span>,
+ EDBG_FAILED_ILLEGAL_MODE = <span class="hl-number">0x18</span>,
+ EDBG_FAILED_ILLEGAL_FLAGS = <span class="hl-number">0x19</span>,
+ EDBG_FAILED_FLASH_WRITE = <span class="hl-number">0x20</span>,
+ EDBG_FAILED_OVERFLOW = <span class="hl-number">0x30</span>,
+ EDBG_FAILED_UNKNOWN = <span class="hl-number">0xFF</span>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> EdbgConfigTypes {
+ EDBG_CONFIGTYPE_CHAR = <span class="hl-number">0x00</span>,
+ EDBG_CONFIGTYPE_SHORT = <span class="hl-number">0x01</span>,
+ EDBG_CONFIGTYPE_WORD = <span class="hl-number">0x02</span>,
+ EDBG_CONFIGTYPE_BIT = <span class="hl-number">0x03</span>,
+ EDBG_CONFIGTYPE_STRING = <span class="hl-number">0x10</span>,
+ EDBG_CONFIGTYPE_ARRAY = <span class="hl-number">0x20</span>,
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> EdbgConfigTags {
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+ <em class="hl-comment" style="color: #008000">// EDBG Configuration Tags</em>
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+
+ EDBG_CONFIG_VERSION = <span class="hl-number">0x00</span>,
+ EDBG_CONFIG_SERIAL_NUMBER = <span class="hl-number">0x01</span>,
+ EDBG_CONFIG_BOARD_NAME = <span class="hl-number">0x02</span>,
+ EDBG_CONFIG_MANUFACTURER_NAME = <span class="hl-number">0x03</span>,
+ EDBG_CONFIG_TARGET_NAME = <span class="hl-number">0x04</span>,
+ EDBG_CONFIG_TARGET_SIGNATURE = <span class="hl-number">0x05</span>,
+ EDBG_CONFIG_TARGET_JTAGID = <span class="hl-number">0x06</span>,
+ EDBG_CONFIG_TARGET_CHIPID = <span class="hl-number">0x07</span>,
+ EDBG_CONFIG_INTERFACES = <span class="hl-number">0x08</span>,
+ EDBG_CONFIG_DGI_GPIO_MAP = <span class="hl-number">0x09</span>,
+ EDBG_CONFIG_EXTENSION_MAP = <span class="hl-number">0x0A</span>,
+ EDBG_CONFIG_EXTENSION_STATUS = <span class="hl-number">0x0B</span>,
+ EDBG_CONFIG_EXTENSION_MANUFACTURER = <span class="hl-number">0x0C</span>,
+ EDBG_CONFIG_EXTENSION_PRODUCT = <span class="hl-number">0x0D</span>,
+ EDBG_CONFIG_EXTENSION_REVISION = <span class="hl-number">0x0E</span>,
+ EDBG_CONFIG_EXTENSION_SERIAL = <span class="hl-number">0x0F</span>,
+ EDBG_CONFIG_EXTENSION_MIN_VOLTAGE = <span class="hl-number">0x10</span>,
+ EDBG_CONFIG_EXTENSION_MAX_VOLTAGE = <span class="hl-number">0x11</span>,
+ EDBG_CONFIG_EXTENSION_CURRENT = <span class="hl-number">0x12</span>,
+ EDBG_CONFIG_BOARD_TYPE = <span class="hl-number">0x13</span>,
+ EDBG_CONFIG_FAMILY_NAME = <span class="hl-number">0x14</span>,
+ EDBG_CONFIG_TVS = <span class="hl-number">0x15</span>,
+ EDBG_CONFIG_VERSION_MINOR = <span class="hl-number">0x16</span>,
+ EDBG_CONFIG_USB_ID = <span class="hl-number">0x17</span>,
+ EDBG_CONFIG_KIT_DATA = <span class="hl-number">0x20</span>,
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> EdbgInterfaces {
+ <em class="hl-comment" style="color: #008000">//**********************************************************</em>
+ <em class="hl-comment" style="color: #008000">// EDBG Configuration Tags</em>
+ <em class="hl-comment" style="color: #008000">//********************************************************** </em>
+ <em class="hl-comment" style="color: #008000">// GPIO, USART, UART, TWI, SPI, CDC</em>
+ <em class="hl-comment" style="color: #008000">// SWD, ARMJTAG, AVRJTAG, aW, dW, PDI, ISP, DBG_EN</em>
+
+ EDBG_IF_DBG_EN = <span class="hl-number">15</span>,
+ EDBG_IF_DBG_ISP = <span class="hl-number">14</span>,
+ EDBG_IF_DBG_PDI = <span class="hl-number">13</span>,
+ EDBG_IF_DBG_DW = <span class="hl-number">12</span>,
+ EDBG_IF_DBG_AW = <span class="hl-number">11</span>,
+ EDBG_IF_DBG_AVRJTAG = <span class="hl-number">10</span>,
+ EDBG_IF_DBG_ARMJTAG = <span class="hl-number">9</span>,
+ EDBG_IF_DBG_SWD = <span class="hl-number">8</span>,
+
+ EDBG_IF_DGI_SPI = <span class="hl-number">0</span>,
+ EDBG_IF_DGI_TWI = <span class="hl-number">1</span>,
+ EDBG_IF_DGI_UART = <span class="hl-number">2</span>,
+ EDBG_IF_DGI_USART = <span class="hl-number">3</span>,
+ EDBG_IF_DGI_GPIO = <span class="hl-number">4</span>,
+ EDBG_IF_CDC = <span class="hl-number">5</span>,
+
+ EDBG_IF_ERASE_PIN = <span class="hl-number">7</span>,
+};
+<span class="hl-keyword" style="color: #0000FF">enum</span> EDBGQueryContexts {
+ <em class="hl-comment" style="color: #008000">// QUERY types on this protocol</em>
+ EDBG_QUERY_COMMANDS = <span class="hl-number">0x00</span>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> EDBGSetGetContexts {
+ EDBG_CONTEXT_CONTROL = <span class="hl-number">0x00</span>,
+ EDBG_CONTEXT_CONFIG0 = <span class="hl-number">0x10</span>,
+ EDBG_CONTEXT_CONFIG1 = <span class="hl-number">0x11</span>,
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> EDBGControlContextParameters {
+ EDBG_CONTROL_LED_USAGE = <span class="hl-number">0x00</span>,
+ EDBG_CONTROL_EXT_PROG = <span class="hl-number">0x01</span>,
+ EDBG_CONTROL_TARGET_POWER = <span class="hl-number">0x10</span>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> SerialTraceCommands {
+ ST_SET_TRANSPORT_MODE = <span class="hl-number">0x00</span>,
+ ST_SET_CAPTURE_MODE = <span class="hl-number">0x01</span>,
+ ST_SET_BAUD = <span class="hl-number">0x02</span>,
+ ST_START = <span class="hl-number">0x03</span>,
+ ST_STOP = <span class="hl-number">0x04</span>,
+ ST_GET_DATA = <span class="hl-number">0x08</span>,
+ ST_GET_STATUS = <span class="hl-number">0x09</span>,
+ ST_GET_BUFFER_SIZE = <span class="hl-number">0x0A</span>,
+ ST_SIGNON = <span class="hl-number">0x0F</span>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> SerialTraceTransportModes {
+ TRANSPORT_OFF = <span class="hl-number">0x00</span>,
+ TRANSPORT_HID = <span class="hl-number">0x01</span>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> SerialTraceTransportModes {
+ CAPTURE_OFF = <span class="hl-number">0x00</span>,
+ CAPTURE_UART = <span class="hl-number">0x02</span>
+};
+
+<span class="hl-keyword" style="color: #0000FF">enum</span> SerialTraceErrorBits {
+ ERROR_OVERFLOW = <span class="hl-number">15</span>,
+ ERROR_RECEIVER = <span class="hl-number">14</span>,
+ RECEIVER_DISABLED = <span class="hl-number">9</span>
+};</pre></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch03s02s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.edbg_ctrl_protocol.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="protocoldocs.avrprotocol.Overview.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_edbg_query_contexts.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_edbg_query_contexts.html
new file mode 100644
index 000000000..e533d16ad
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_edbg_query_contexts.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>EDBG QUERY contexts - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch03s01s01.html" title="QUERY" /><link rel="prev" href="ch03s01s01.html" title="QUERY" /><link rel="next" href="ch03s01s02.html" title="SET" /><meta content="EDBG QUERY contexts" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />QUERY</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch03s01s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch03s01s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch03s01s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="section_edbg_query_contexts" />EDBG QUERY contexts</h4></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N1081D" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;36.&nbsp;EDBG QUERY contexts</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="EDBG QUERY contexts" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>ID</th><th>Description</th><th>Response</th></tr></thead><tbody><tr><td>EDBG_QUERY_COMMANDS</td><td>Lists protocol commands supported</td><td>List of n * [byte]</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch03s01s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch03s01s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch03s01s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_housekeeping_start_session.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_housekeeping_start_session.html
new file mode 100644
index 000000000..0bafe24d8
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_housekeeping_start_session.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Start session - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05s06.html" title="Housekeeping Commands" /><link rel="prev" href="ch04s05s06.html" title="Housekeeping Commands" /><link rel="next" href="ch04s05s06s02.html" title="End Session" /><meta content="Start session" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Commands</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s06.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05s06.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s06s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="section_housekeeping_start_session" />Start session</h4></div></div></div><p xmlns="http://www.w3.org/1999/xhtml">Signs onto the tool. The tool may now publish events to the host on the
+ EVENT channel.</p><div class="table"><a id="N10D72" /><p class="title"><strong>Table&nbsp;57.&nbsp;Start session command format</strong></p><div class="table-contents"><table summary="Start session command format" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Size</th><th>Description</th></tr></thead><tbody><tr><td>CMD_HOUSEKEEPING_START_SESSION</td><td>1 byte</td><td>Command ID</td></tr><tr><td>Version (0x00)</td><td>1 byte</td><td>Command version</td></tr></tbody></table></div></div><br class="table-break" /><p>Responses:</p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>OK</p></li><li class="listitem"><p>FAILED</p></li></ul></div><p>
+ </p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s06.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05s06.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s06s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_i5v_3yz_rl.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_i5v_3yz_rl.html
new file mode 100644
index 000000000..370df774d
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_i5v_3yz_rl.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Housekeeping QUERY contexts - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05.html" title="Housekeeping Protocol" /><link rel="prev" href="ch04s05s01.html" title="CMD: QUERY" /><link rel="next" href="ch04s05s03.html" title="CMD: SET" /><meta content="Housekeeping QUERY contexts" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="section_i5v_3yz_rl" />Housekeeping QUERY contexts</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N10C55" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;53.&nbsp;Houekeeping QUERY contexts</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="Houekeeping QUERY contexts" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>ID</th><th>Description</th><th>Response</th></tr></thead><tbody><tr><td>HK_QUERY_COMMANDS</td><td>Lists protocol commands supported</td><td>List of n * [byte]</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_jdx_m11_sl.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_jdx_m11_sl.html
new file mode 100644
index 000000000..0f51f8c43
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_jdx_m11_sl.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Discovery QUERY contexts - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s04.html" title="Discovery Protocol Definition" /><link rel="prev" href="ch04s04s01.html" title="CMD: QUERY" /><link rel="next" href="ch04s04s03.html" title="RSP: LIST" /><meta content="Discovery QUERY contexts" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Discovery Protocol Definition</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s04s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s04.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s04s03.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="section_jdx_m11_sl" />Discovery QUERY contexts</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N10B71" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;49.&nbsp;Discovery QUERY contexts</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="Discovery QUERY contexts" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>ID</th><th>Description</th><th>Response</th></tr></thead><tbody><tr><td>COMMAND_HANDLERS</td><td>Lists protocol command handlers supported</td><td>List of n * [byte]</td></tr><tr><td>TOOL_NAME</td><td>Name of this tool</td><td>String of n * [byte]</td></tr><tr><td>SERIAL_NUMBER</td><td>Serial number</td><td>String of n * [byte]</td></tr><tr><td>MNF_DATE</td><td>Manufacture date</td><td>String of form YYYYMMDDHHMMSS</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s04s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s04.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s04s03.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_qhb_x1c_sl.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_qhb_x1c_sl.html
new file mode 100644
index 000000000..02f90b827
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_qhb_x1c_sl.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>AVR32 QUERY contexts - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch05s01s01.html" title="QUERY" /><link rel="prev" href="ch05s01s01.html" title="QUERY" /><link rel="next" href="ch05s01s02.html" title="SET" /><meta content="AVR32 QUERY contexts" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />QUERY</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch05s01s01.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch05s01s01.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch05s01s02.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h4 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="section_qhb_x1c_sl" />AVR32 QUERY contexts</h4></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N1104E" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;70.&nbsp;AVR32 QUERY contexts</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="AVR32 QUERY contexts" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>ID</th><th>Description</th><th>Response</th></tr></thead><tbody><tr><td>AVR32_QUERY_COMMANDS</td><td>Lists protocol commands supported</td><td>List of n * [byte]</td></tr><tr><td>AVR32_QUERY_CONFIGURATION</td><td>Lists configuration parameters supported</td><td>List of n * [byte]</td></tr><tr><td>AVR32_QUERY_READ_MEMTYPES</td><td>Lists readable memtypes</td><td>List of n * [byte]</td></tr><tr><td>AVR32_QUERY_WRITE_MEMTYPES</td><td>Lists writeable memtypes</td><td>List of n * [byte]</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch05s01s01.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch05s01s01.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch05s01s02.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_serial_trace.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_serial_trace.html
new file mode 100644
index 000000000..9067bd286
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_serial_trace.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Serial trace commands - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="protocoldocs.cmsis_dap.html" title="CMSIS-DAP" /><link rel="prev" href="ch02s02s03s04.html" title="EDBG SET request" /><link rel="next" href="ch02s03s01.html" title="Set transport mode" /><meta content="Serial trace commands" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />CMSIS-DAP</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch02s02s03s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="protocoldocs.cmsis_dap.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch02s03s01.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a id="section_serial_trace" />Serial trace commands</h2></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="toc"><p xmlns="http://www.w3.org/1999/xhtml"><strong>Table of Contents</strong></p><dl xmlns="http://www.w3.org/1999/xhtml" class="toc"><dt><span class="section"><a href="ch02s03s01.html">Set transport mode</a></span></dt><dt><span class="section"><a href="ch02s03s02.html">Set capture mode</a></span></dt><dt><span class="section"><a href="ch02s03s03.html">Set baud rate</a></span></dt><dt><span class="section"><a href="ch02s03s04.html">Start</a></span></dt><dt><span class="section"><a href="ch02s03s05.html">Stop</a></span></dt><dt><span class="section"><a href="ch02s03s06.html">Get data</a></span></dt><dt><span class="section"><a href="ch02s03s07.html">Get status</a></span></dt><dt><span class="section"><a href="ch02s03s08.html">Get buffer size</a></span></dt><dt><span class="section"><a href="ch02s03s09.html">Signon</a></span></dt></dl></div><p>Some ARM-based devices implement a serial trace output using the SWO pin. This is available
+ only when using th SWD interface, and it uses the JTAG TDO pin on the tool to sample the signal.
+ This section describes how to configure the tool for capturing serial trace and how to read the
+ captured serial trace data out of the tool.</p><p>Note that the hardware tool performs only raw data capture, storage and forwarding.</p><p>All serial trace commands use vendor command 7 (0x87)</p></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch02s02s03s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="protocoldocs.cmsis_dap.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch02s03s01.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_t1f_hb1_sl.html b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_t1f_hb1_sl.html
new file mode 100644
index 000000000..a5a163146
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/EDBG/protocoldocs/section_t1f_hb1_sl.html
@@ -0,0 +1,211 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta content="IE=edge" http-equiv="X-UA-Compatible" />
+<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+<title>Housekeeping SET/GET parameters - - Atmel EDBG-based Tools Protocols</title><meta content="DocBook XSL Stylesheets V1.78.1" name="generator" /><link rel="home" href="index.html" title="Atmel EDBG-based Tools Protocols" /><link rel="up" href="ch04s05.html" title="Housekeeping Protocol" /><link rel="prev" href="ch04s05s04.html" title="CMD: GET" /><link rel="next" href="ch04s05s06.html" title="Housekeeping Commands" /><meta content="Housekeeping SET/GET parameters" name="Section-title" /><script type="text/javascript">
+ //The id for tree cookie
+ var treeCookieId = "treeview-10619";
+ var language = "en";
+ var w = new Object();
+ //Localization
+ txt_filesfound = 'Results';
+ txt_enter_at_least_1_char = "You must enter at least one character.";
+ txt_browser_not_supported = "JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.";
+ txt_please_wait = "Please wait. Search in progress...";
+ txt_results_for = "Results for: ";
+ </script><link type="image/x-icon" href="../favicon.ico" rel="shortcut icon" /><link href="../common/css/positioning.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css" type="text/css" rel="stylesheet" /><link href="../common/jquery/treeview/jquery.treeview.css" type="text/css" rel="stylesheet" /><style type="text/css">
+ #noscript{
+ font-weight:bold;
+ background-color:#55AA55;
+ font-weight:bold;
+ height:25spx;
+ z-index:3000;
+ top:0px;
+ width:100%;
+ position:relative;
+ border-bottom:solid 5px black;
+ text-align:center;
+ color:white;
+ }
+
+ input{
+ margin-bottom:5px;
+ margin-top:2px;
+ }
+ .folder{
+ display:block;
+ height:22px;
+ padding-left:20px;
+ background:transparent url(../common/jquery/treeview/images/folder.gif) 0 0px no-repeat;
+ }
+ .dochome{
+ display:block;
+ margin:10px 0 0 0;
+ padding-left:20px;
+ background:transparent url(../common/images/Library.png) 0 0px no-repeat;
+ }
+ .root{
+ display:block;
+ margin:10px 0 0 2px;
+ padding-left:20px;
+ background:transparent url(../common/images/Book_Open.png) 0 0px no-repeat;
+ }
+ .dochome a,
+ .root a {
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+ span.contentsTab{
+ padding-left:20px;
+ background:url(../common/images/toc-icon.png) no-repeat 0 center;
+ }
+ span.searchTab{
+ padding-left:20px;
+ background:url(../common/images/search-icon.png) no-repeat 0 center;
+ }
+
+ /* Overide jquery treeview's defaults for ul. */
+ .treeview ul{
+ background-color:transparent;
+ margin-top:4px;
+ }
+ #webhelp-currentid{
+ background-color:#D8D8D8 !important;
+ }
+ .treeview .hover{
+ color:black;
+ }
+ .filetree li span a{
+ text-decoration:none;
+ font-size:12px;
+ color:#517291;
+ }
+
+ .filetree span.file {
+ background: url(../common/images/Document_Text.png) 0 0 no-repeat;
+ }
+
+ /* Override jquery-ui's default css customizations. These are supposed to take precedence over those.*/
+ .ui-widget-content{
+ border:0px;
+ background:none;
+ color:none;
+ }
+ .ui-widget-header{
+ color:#e9e8e9;
+ border-left:1px solid #e5e5e5;
+ border-right:1px solid #e5e5e5;
+ border-bottom:1px solid #bbc4c5;
+ border-top:4px solid #e5e5e5;
+ border:medium none;
+ background:#F4F4F4; /* old browsers */
+ background:-moz-linear-gradient(top, #F4F4F4 0%, #E6E4E5 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #F4F4F4), color-stop(100%, #E6E4E5)); /* webkit */
+ font-weight:none;
+ }
+ .ui-widget-header a{
+ color:none;
+ }
+ .ui-state-default,
+ .ui-widget-content .ui-state-default,
+ .ui-widget-header .ui-state-default{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-default a,
+ .ui-state-default a:link,
+ .ui-state-default a:visited{
+ color:black;
+ text-decoration:none;
+ }
+ .ui-state-hover,
+ .ui-widget-content .ui-state-hover,
+ .ui-widget-header .ui-state-hover,
+ .ui-state-focus,
+ .ui-widget-content .ui-state-focus,
+ .ui-widget-header .ui-state-focus{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+
+ .ui-state-active,
+ .ui-widget-content .ui-state-active,
+ .ui-widget-header .ui-state-active{
+ border:none;
+ background:none;
+ font-weight:none;
+ color:none;
+ }
+ .ui-state-active a,
+ .ui-state-active a:link,
+ .ui-state-active a:visited{
+ color:black;
+ text-decoration:none;
+ background:#C6C6C6; /* old browsers */
+ background:-moz-linear-gradient(top, #C6C6C6 0%, #D8D8D8 100%); /* firefox */
+ background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #C6C6C6), color-stop(100%, #D8D8D8)); /* webkit */
+ -webkit-border-radius:15px;
+ -moz-border-radius:10px;
+ border:1px solid #f1f1f1;
+ }
+ .ui-corner-all{
+ border-radius:0 0 0 0;
+ }
+
+ .ui-tabs{
+ padding:.2em;
+ }
+ .ui-tabs .ui-tabs-panel {
+ padding-top: 6px;
+ }
+ .ui-tabs .ui-tabs-nav li{
+ top:0px;
+ margin:-2px 0 1px;
+ text-transform:uppercase;
+ font-size:10.5px;
+ }
+ .ui-tabs .ui-tabs-nav li a{
+ padding:.25em 2em .25em 1em;
+ margin:.5em;
+ text-shadow:0 1px 0 rgba(255, 255, 255, .5);
+ }
+ /**
+ * Basic Layout Theme
+ *
+ * This theme uses the default layout class-names for all classes
+ * Add any 'custom class-names', from options: paneClass, resizerClass, togglerClass
+ */
+
+ .ui-layout-resizer{ /* all 'resizer-bars' */
+ background:#DDD;
+ top:100px
+ }
+
+ .ui-layout-toggler{ /* all 'toggler-buttons' */
+ background:#AAA;
+ }
+ </style><!--[if IE]>
+ <link rel="stylesheet" type="text/css" href="../common/css/ie.css"/>
+ <![endif]--><script src="../common/browserDetect.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery-1.7.2.min.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.ui.all.js" type="text/javascript"><!----></script><script src="../common/jquery/jquery.cookie.js" type="text/javascript"><!----></script><script src="../common/jquery/treeview/jquery.treeview.min.js" type="text/javascript"><!----></script><script src="../common/jquery/layout/jquery.layout.js" type="text/javascript"><!----></script><script src="search/l10n.js" type="text/javascript"><!----></script><script src="search/htmlFileInfoList.js" type="text/javascript"><!----></script><script src="search/nwSearchFnt.js" type="text/javascript"><!----></script><script src="search/stemmers/en_stemmer.js" type="text/javascript" /><script src="search/index-1.js" type="text/javascript"><!----></script><script src="search/index-2.js" type="text/javascript"><!----></script><script src="search/index-3.js" type="text/javascript"><!----></script><meta name="date" content="" /><meta name="dc.date.created" content="" /><link rel="stylesheet" type="text/css" href="../common/css/docbook.css" /><link media="print" rel="stylesheet" type="text/css" href="../common/css/print.css" /><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-41389295-1']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+ </script></head><body><noscript><link rel="stylesheet" type="text/css" href="../common/css/print.css" /><div id="noscript">JavaScript is disabled on your browser. Please enable JavaScript to enjoy all the features of this site.</div></noscript><div id="header"><a href="http://www.atmel.com/webdoc"><img id="logo" alt="Atmel Logo" src="../common/images/logo.png" /></a><h1>Atmel EDBG-based Tools Protocols<br />Housekeeping Protocol</h1><div id="navheader"><!----><table class="navLinks"><tr><td><a title="Hide TOC tree" tabindex="5" class="pointLeft" onclick="myLayout.toggle('west')" href="#" id="showHideButton">Sidebar
+ </a></td><td><a tabindex="5" class="navLinkPrevious" accesskey="p" href="ch04s05s04.html">Prev</a>
+ |
+ <a tabindex="5" class="navLinkUp" accesskey="u" href="ch04s05.html">Up</a>
+ |
+ <a tabindex="5" class="navLinkNext" accesskey="n" href="ch04s05s06.html">Next</a></td></tr></table></div></div><div id="content"><!----><div class="section"><div xmlns="" class="titlepage"><div><div><h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a id="section_t1f_hb1_sl" />Housekeeping SET/GET parameters</h3></div></div></div><div xmlns="http://www.w3.org/1999/xhtml" class="table"><a xmlns="http://www.w3.org/1999/xhtml" id="N10D1E" /><p xmlns="http://www.w3.org/1999/xhtml" class="title"><strong>Table&nbsp;56.&nbsp;Houekeeping SET/GET parameters</strong></p><div xmlns="http://www.w3.org/1999/xhtml" class="table-contents"><table summary="Houekeeping SET/GET parameters" border="1"><colgroup><col /><col /><col /><col /><col /></colgroup><thead><tr><th>Context</th><th>ID</th><th>Description</th><th>Acc</th><th>Size</th></tr></thead><tbody><tr><td rowspan="4">HK_CONTEXT_CONFIG</td><td>HWREV</td><td>Hardware version</td><td>R</td><td>1 byte</td></tr><tr><td>FWREV_MAJ</td><td>Firmware major version</td><td>R</td><td>1 byte</td></tr><tr><td>FWREV_MIN</td><td>Firmware minor version</td><td>R</td><td>1 byte</td></tr><tr><td>BUILD</td><td>Firmware build number</td><td>R</td><td>2 x [byte]</td></tr><tr><td>HK_CONTEXT_ANALOG</td><td>VTG</td><td>Target voltage reading</td><td>R</td><td>2 bytes (mV value)</td></tr></tbody></table></div></div><br class="table-break" /></div><script src="../common/main.js" type="text/javascript"><!----></script><script src="../common/splitterInit.js" type="text/javascript"><!----></script><div class="navfooter"><table summary="Navigation footer" width="100%"><tr><td align="left" width="40%"><a accesskey="p" href="ch04s05s04.html">Prev</a>&nbsp;</td><td align="center" width="20%"><a accesskey="u" href="ch04s05.html">Up</a></td><td align="right" width="40%">&nbsp;<a accesskey="n" href="ch04s05s06.html">Next</a></td></tr><tr><td valign="top" align="left" width="40%">&nbsp;</td><td align="center" width="20%"><a accesskey="h" href="index.html">Home</a></td><td valign="top" align="right" width="40%">&nbsp;</td></tr></table></div></div><div id="sidebar"><div style="padding-top:3px;" id="leftnavigation"><div id="tabs"><ul><li><a tabindex="1" style="outline:0;" href="#treeDiv"><span class="contentsTab">Contents</span></a></li><li><a onclick="doSearch()" tabindex="1" style="outline:0;" href="#searchDiv"><span class="searchTab">Search</span></a></li></ul><div id="treeDiv"><img style="display:block;" id="tocLoading" alt="loading table of contents..." src="../common/images/loading.gif" /><span class="dochome"><a href="../index.html" tabindex="1">Documentation Home</a></span><span class="root"><a href="index.html" tabindex="1">Atmel EDBG-based Tools Protocols</a></span><div style="display:none" id="ulTreeDiv"><ul class="filetree" id="tree"><li><span class="file"><a tabindex="1" href="pr01.html">Preface</a></span></li><li><span class="file"><a tabindex="1" href="protocoldocs.Introduction.html">Introduction</a></span><ul><li><span class="file"><a tabindex="1" href="ch01s01.html">EDBG interface overview</a></span></li><li><span class="file"><a tabindex="1" href="ch01s02.html">Atmel EDBG-based tool implementations</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.cmsis_dap.html">CMSIS-DAP</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s01.html">CMSIS-DAP protocol</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02.html">CMSIS-DAP vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s01.html">AVR-target specific vendor commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02.html">ARM-target specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s02s01.html">Erase pin</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s02s02.html">Serial trace</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s02s03.html">EDBG-specific vendor commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s02s03s01.html">Get configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s02.html">Set configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s03.html">EDBG GET request</a></span></li><li><span class="file"><a tabindex="1" href="ch02s02s03s04.html">EDBG SET request</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="section_serial_trace.html">Serial trace commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s03s01.html">Set transport mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s02.html">Set capture mode</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s03.html">Set baud rate</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s04.html">Start</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s05.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s06.html">Get data</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s07.html">Get status</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s08.html">Get buffer size</a></span></li><li><span class="file"><a tabindex="1" href="ch02s03s09.html">Signon</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch02s04.html">Enveloped AVR commands, responses &amp; events</a></span><ul><li><span class="file"><a tabindex="1" href="ch02s04s01.html">Wrapping AVR commands</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s02.html">Unwrapping AVR responses</a></span></li><li><span class="file"><a tabindex="1" href="ch02s04s03.html">Unwrapping AVR events</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.edbg_ctrl_protocol.html">EDBG Control Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_edbg_query_contexts.html">EDBG QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch03s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s01s03s01.html">SET/GET parameters</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch03s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch03s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch03s02s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_edbg_ctrl_setget_params.html">EDBGCTRL ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrprotocol.Overview.html">AVR communication protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s01.html">Overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s02.html">Framing</a></span></li><li><span class="file"><a tabindex="1" href="ch04s03.html">Protocol sub-set overview</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04.html">Discovery Protocol Definition</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s04s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_jdx_m11_sl.html">Discovery QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s03.html">RSP: LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s04.html">RSP: FAILED</a></span></li><li><span class="file"><a tabindex="1" href="ch04s04s05.html">Discovery Protocol ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05.html">Housekeeping Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s01.html">CMD: QUERY</a></span></li><li><span class="file"><a tabindex="1" href="section_i5v_3yz_rl.html">Housekeeping QUERY contexts</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s03.html">CMD: SET</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s04.html">CMD: GET</a></span></li><li id="webhelp-currentid"><span class="file"><a tabindex="1" href="section_t1f_hb1_sl.html">Housekeeping SET/GET parameters</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06.html">Housekeeping Commands</a></span><ul><li><span class="file"><a tabindex="1" href="section_housekeeping_start_session.html">Start session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s02.html">End Session</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s03.html">Firmware Upgrade</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s04.html">JTAG scan-chain detection</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s06s05.html">Calibrate Oscillator</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s07.html">Housekeeping Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s07s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s03.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s07s04.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s08.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch04s05s08s01.html">Event: power</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s02.html">Event: sleep</a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s08s03.html">Event: external reset</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch04s05s09.html">
+ Hints and tips
+ </a></span></li><li><span class="file"><a tabindex="1" href="ch04s05s10.html">Housekeeping ID definitions</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr32protocol.html">AVR32 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01.html">Protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_qhb_x1c_sl.html">AVR32 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_setget_params.html">SET/GET parameters</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s07.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s08.html">Halt</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s10.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s11.html">Read</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s12.html">Write</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr32_memtypes.html">Memory Types</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s01s13.html">TAP</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s14.html">Is protected</a></span></li><li><span class="file"><a tabindex="1" href="ch05s01s15.html">Erase Section</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s03.html">ID</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s04.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s05.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch05s02s06.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s03.html">Hints and tips</a></span><ul><li><span class="file"><a tabindex="1" href="ch05s03s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch05s03s03.html">Programming and debugging commands</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch05s04.html">AVR32GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avr8protocol.html">AVR8 generic protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01.html">Protocol Commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s01s01.html">QUERY</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_query_contexts.html">AVR8 QUERY contexts</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s02.html">SET</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s03.html">GET</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html">SET/GET parameters</a></span><ul><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N11932">Device context: debugWIRE targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#N119D3">Device context: megaAVR JTAG targets</a></span></li><li><span class="file"><a tabindex="1" href="section_avr8_setget_params.html#section_avr8_xmega_device_context">Device context: AVR XMEGA targets</a></span></li></ul></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s01s04.html">Activate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s05.html">Deactivate Physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s06.html">Get ID</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s07.html">Attach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s08.html">Detach</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s09.html">Reset</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s10.html">Stop</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s11.html">Run</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s12.html">Run To</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s13.html">Step</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s14.html">PC read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s15.html">PC write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s16.html">Prog Mode Enter</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s17.html">Prog Mode Leave</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s18.html">Disable debugWIRE</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s19.html">Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s20.html">CRC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s21.html">Memory Read</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s22.html">Memory Read masked</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s23.html">Memory Write</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s24.html">Page Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s25.html">Hardware Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s26.html">Hardware Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s27.html">Software Breakpoint Set</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s28.html">Software Breakpoint Clear</a></span></li><li><span class="file"><a tabindex="1" href="ch06s01s29.html">Software Breakpoint Clear All</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s02.html">Responses</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s02s01.html">OK</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s02.html">LIST</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s03.html">PC</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s04.html">DATA</a></span></li><li><span class="file"><a tabindex="1" href="ch06s02s05.html">FAILED</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s03.html">Events</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s03s01.html">Event: Break</a></span></li><li><span class="file"><a tabindex="1" href="ch06s03s02.html">Event: IDR message</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="section_avr8_memtypes.html">Memory Types</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s04s01.html">debugWIRE memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s02.html">megaAVR (JTAG) OCD memtypes</a></span></li><li><span class="file"><a tabindex="1" href="ch06s04s03.html">AVR XMEGA memtypes</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s05.html">Hints and tips:</a></span><ul><li><span class="file"><a tabindex="1" href="ch06s05s01.html">Configuration</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s02.html">Activate and deactivate physical</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s03.html">Programming session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s04.html">Debug session control</a></span></li><li><span class="file"><a tabindex="1" href="ch06s05s05.html">Flow control</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch06s06.html">AVR8GENERIC ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.avrispprotocol.html">AVR ISP protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01.html">SPI programming protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch07s01s01.html">SPI Load Address</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s02.html">SPI Set Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s03.html">SPI Get Baud</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s04.html">SPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s05.html">SPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s06.html">SPI Chip Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s07.html">SPI Program Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s08.html">SPI Read Flash</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s09.html">SPI Program EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s10.html">SPI Read EEPROM</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s11.html">SPI Program Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s12.html">SPI Read Fuse</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s13.html">SPI Program Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s14.html">SPI Read Lock</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s15.html">SPI Read Signature</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s16.html">SPI Read OSCCAL</a></span></li><li><span class="file"><a tabindex="1" href="ch07s01s17.html">SPI Multi</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch07s02.html">SPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch07s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="protocoldocs.tpiprotocol.html">TPI Protocol</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01.html">TPI protocol commands</a></span><ul><li><span class="file"><a tabindex="1" href="ch08s01s01.html">TPI Enter Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s02.html">TPI Leave Programming Mode</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s03.html">TPI Set Parameter</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s04.html">TPI Erase</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s05.html">TPI Write Memory</a></span></li><li><span class="file"><a tabindex="1" href="ch08s01s06.html">TPI Read Memory</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="ch08s02.html">TPI programming protocol responses</a></span></li><li><span class="file"><a tabindex="1" href="ch08s03.html">ID definitions</a></span></li></ul></li><li><span class="file"><a tabindex="1" href="document.revisions.html">Document Revisions</a></span></li></ul></div></div><div id="searchDiv"><div id="search"><form class="searchForm" name="searchForm" onsubmit="Verifie(searchForm);return false"><div><input tabindex="1" class="searchText" placeholder="Search" type="search" name="textToSearch" id="textToSearch" /> &nbsp; <input tabindex="1" id="doSearch" value="Go" class="searchButton" type="button" onclick="Verifie(searchForm)" /></div></form></div><div id="searchResults"><center /></div><p class="searchHighlight"><a onclick="toggleHighlight()" href="#">Search Highlighter (On/Off)</a></p></div></div></div></div></body></html> \ No newline at end of file
diff --git a/xs/src/avrdude/atmel-docs/JTAGICE-AVR060.pdf b/xs/src/avrdude/atmel-docs/JTAGICE-AVR060.pdf
new file mode 100644
index 000000000..1b4cac8a9
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/JTAGICE-AVR060.pdf
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/JTAGICEmkII-AVR067.pdf b/xs/src/avrdude/atmel-docs/JTAGICEmkII-AVR067.pdf
new file mode 100644
index 000000000..c72ccde8a
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/JTAGICEmkII-AVR067.pdf
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/STK500-AVR061.pdf b/xs/src/avrdude/atmel-docs/STK500-AVR061.pdf
new file mode 100644
index 000000000..03e0ddf6b
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/STK500-AVR061.pdf
Binary files differ
diff --git a/xs/src/avrdude/atmel-docs/STK500v2-AVR068.pdf b/xs/src/avrdude/atmel-docs/STK500v2-AVR068.pdf
new file mode 100644
index 000000000..1a8485655
--- /dev/null
+++ b/xs/src/avrdude/atmel-docs/STK500v2-AVR068.pdf
Binary files differ
diff --git a/xs/src/avrdude/avr.c b/xs/src/avrdude/avr.c
new file mode 100644
index 000000000..73dcaf4ff
--- /dev/null
+++ b/xs/src/avrdude/avr.c
@@ -0,0 +1,1254 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2011 Darell Tan <darell.tan@gmail.com>
+ *
+ * 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$ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+
+#if !defined(WIN32NATIVE)
+# include <sys/time.h>
+#endif
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "tpi.h"
+
+FP_UpdateProgress update_progress;
+
+#define DEBUG 0
+
+/* TPI: returns 1 if NVM controller busy, 0 if free */
+int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm)
+{
+ unsigned char cmd;
+ unsigned char res;
+
+ cmd = TPI_CMD_SIN | TPI_SIO_ADDR(TPI_IOREG_NVMCSR);
+ (void)pgm->cmd_tpi(pgm, &cmd, 1, &res, 1);
+ return (res & TPI_IOREG_NVMCSR_NVMBSY);
+}
+
+/* TPI chip erase sequence */
+int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ int err;
+ AVRMEM *mem;
+
+ if (p->flags & AVRPART_HAS_TPI) {
+ pgm->pgm_led(pgm, ON);
+
+ /* Set Pointer Register */
+ mem = avr_locate_mem(p, "flash");
+ if (mem == NULL) {
+ avrdude_message(MSG_INFO, "No flash memory to erase for part %s\n",
+ p->desc);
+ return -1;
+ }
+
+ unsigned char cmd[] = {
+ /* write pointer register high byte */
+ (TPI_CMD_SSTPR | 0),
+ ((mem->offset & 0xFF) | 1),
+ /* and low byte */
+ (TPI_CMD_SSTPR | 1),
+ ((mem->offset >> 8) & 0xFF),
+ /* write CHIP_ERASE command to NVMCMD register */
+ (TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD)),
+ TPI_NVMCMD_CHIP_ERASE,
+ /* write dummy value to start erase */
+ TPI_CMD_SST,
+ 0xFF
+ };
+
+ while (avr_tpi_poll_nvmbsy(pgm));
+
+ err = pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
+ if(err)
+ return err;
+
+ while (avr_tpi_poll_nvmbsy(pgm));
+
+ pgm->pgm_led(pgm, OFF);
+
+ return 0;
+ } else {
+ avrdude_message(MSG_INFO, "%s called for a part that has no TPI\n", __func__);
+ return -1;
+ }
+}
+
+/* TPI program enable sequence */
+int avr_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p, unsigned char guard_time)
+{
+ int err, retry;
+ unsigned char cmd[2];
+ unsigned char response;
+
+ if(p->flags & AVRPART_HAS_TPI) {
+ /* set guard time */
+ cmd[0] = (TPI_CMD_SSTCS | TPI_REG_TPIPCR);
+ cmd[1] = guard_time;
+
+ err = pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
+ if(err)
+ return err;
+
+ /* read TPI ident reg */
+ cmd[0] = (TPI_CMD_SLDCS | TPI_REG_TPIIR);
+ err = pgm->cmd_tpi(pgm, cmd, 1, &response, sizeof(response));
+ if (err || response != TPI_IDENT_CODE) {
+ avrdude_message(MSG_INFO, "TPIIR not correct\n");
+ return -1;
+ }
+
+ /* send SKEY command + SKEY */
+ err = pgm->cmd_tpi(pgm, tpi_skey_cmd, sizeof(tpi_skey_cmd), NULL, 0);
+ if(err)
+ return err;
+
+ /* check if device is ready */
+ for(retry = 0; retry < 10; retry++)
+ {
+ cmd[0] = (TPI_CMD_SLDCS | TPI_REG_TPISR);
+ err = pgm->cmd_tpi(pgm, cmd, 1, &response, sizeof(response));
+ if(err || !(response & TPI_REG_TPISR_NVMEN))
+ continue;
+
+ return 0;
+ }
+
+ avrdude_message(MSG_INFO, "Error enabling TPI external programming mode:");
+ avrdude_message(MSG_INFO, "Target does not reply\n");
+ return -1;
+
+ } else {
+ avrdude_message(MSG_INFO, "%s called for a part that has no TPI\n", __func__);
+ return -1;
+ }
+}
+
+/* TPI: setup NVMCMD register and pointer register (PR) for read/write/erase */
+static int avr_tpi_setup_rw(PROGRAMMER * pgm, AVRMEM * mem,
+ unsigned long addr, unsigned char nvmcmd)
+{
+ unsigned char cmd[4];
+ int rc;
+
+ /* set NVMCMD register */
+ cmd[0] = TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD);
+ cmd[1] = nvmcmd;
+ rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+ if (rc == -1)
+ return -1;
+
+ /* set Pointer Register (PR) */
+ cmd[0] = TPI_CMD_SSTPR | 0;
+ cmd[1] = (mem->offset + addr) & 0xFF;
+ rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+ if (rc == -1)
+ return -1;
+
+ cmd[0] = TPI_CMD_SSTPR | 1;
+ cmd[1] = ((mem->offset + addr) >> 8) & 0xFF;
+ rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+ if (rc == -1)
+ return -1;
+
+ return 0;
+}
+
+int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+ unsigned char data;
+ int r;
+ OPCODE * readop, * lext;
+
+ if (pgm->cmd == NULL) {
+ avrdude_message(MSG_INFO, "%s: Error: %s programmer uses avr_read_byte_default() but does not\n"
+ "provide a cmd() method.\n",
+ progname, pgm->type);
+ return -1;
+ }
+
+ pgm->pgm_led(pgm, ON);
+ pgm->err_led(pgm, OFF);
+
+ if (p->flags & AVRPART_HAS_TPI) {
+ if (pgm->cmd_tpi == NULL) {
+ avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n",
+ progname, pgm->type);
+ return -1;
+ }
+
+ while (avr_tpi_poll_nvmbsy(pgm));
+
+ /* setup for read */
+ avr_tpi_setup_rw(pgm, mem, addr, TPI_NVMCMD_NO_OPERATION);
+
+ /* load byte */
+ cmd[0] = TPI_CMD_SLD;
+ r = pgm->cmd_tpi(pgm, cmd, 1, value, 1);
+ if (r == -1)
+ return -1;
+
+ return 0;
+ }
+
+ /*
+ * figure out what opcode to use
+ */
+ if (mem->op[AVR_OP_READ_LO]) {
+ if (addr & 0x00000001)
+ readop = mem->op[AVR_OP_READ_HI];
+ else
+ readop = mem->op[AVR_OP_READ_LO];
+ addr = addr / 2;
+ }
+ else {
+ readop = mem->op[AVR_OP_READ];
+ }
+
+ if (readop == NULL) {
+#if DEBUG
+ avrdude_message(MSG_INFO, "avr_read_byte(): operation not supported on memory type \"%s\"\n",
+ mem->desc);
+#endif
+ return -1;
+ }
+
+ /*
+ * If this device has a "load extended address" command, issue it.
+ */
+ lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
+ if (lext != NULL) {
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(lext, cmd);
+ avr_set_addr(lext, cmd, addr);
+ r = pgm->cmd(pgm, cmd, res);
+ if (r < 0)
+ return r;
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(readop, cmd);
+ avr_set_addr(readop, cmd, addr);
+ r = pgm->cmd(pgm, cmd, res);
+ if (r < 0)
+ return r;
+ data = 0;
+ avr_get_output(readop, res, &data);
+
+ pgm->pgm_led(pgm, OFF);
+
+ *value = data;
+
+ return 0;
+}
+
+
+/*
+ * Return the number of "interesting" bytes in a memory buffer,
+ * "interesting" being defined as up to the last non-0xff data
+ * value. This is useful for determining where to stop when dealing
+ * with "flash" memory, since writing 0xff to flash is typically a
+ * no-op. Always return an even number since flash is word addressed.
+ */
+int avr_mem_hiaddr(AVRMEM * mem)
+{
+ int i, n;
+
+ /* return the highest non-0xff address regardless of how much
+ memory was read */
+ for (i=mem->size-1; i>0; i--) {
+ if (mem->buf[i] != 0xff) {
+ n = i+1;
+ if (n & 0x01)
+ return n+1;
+ else
+ return n;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * Read the entirety of the specified memory type into the
+ * corresponding buffer of the avrpart pointed to by 'p'.
+ * If v is non-NULL, verify against v's memory area, only
+ * those cells that are tagged TAG_ALLOCATED are verified.
+ *
+ * Return the number of bytes read, or < 0 if an error occurs.
+ */
+int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype,
+ AVRPART * v)
+{
+ unsigned long i, lastaddr;
+ unsigned char cmd[4];
+ AVRMEM * mem, * vmem = NULL;
+ int rc;
+
+ mem = avr_locate_mem(p, memtype);
+ if (v != NULL)
+ vmem = avr_locate_mem(v, memtype);
+ if (mem == NULL) {
+ avrdude_message(MSG_INFO, "No \"%s\" memory for part %s\n",
+ memtype, p->desc);
+ return -1;
+ }
+
+ /*
+ * start with all 0xff
+ */
+ memset(mem->buf, 0xff, mem->size);
+
+ /* supports "paged load" thru post-increment */
+ if ((p->flags & AVRPART_HAS_TPI) && mem->page_size != 0 &&
+ pgm->cmd_tpi != NULL) {
+
+ while (avr_tpi_poll_nvmbsy(pgm));
+
+ /* setup for read (NOOP) */
+ avr_tpi_setup_rw(pgm, mem, 0, TPI_NVMCMD_NO_OPERATION);
+
+ /* load bytes */
+ for (lastaddr = i = 0; i < mem->size; i++) {
+ RETURN_IF_CANCEL();
+ if (vmem == NULL ||
+ (vmem->tags[i] & TAG_ALLOCATED) != 0)
+ {
+ if (lastaddr != i) {
+ /* need to setup new address */
+ avr_tpi_setup_rw(pgm, mem, i, TPI_NVMCMD_NO_OPERATION);
+ lastaddr = i;
+ }
+ cmd[0] = TPI_CMD_SLD_PI;
+ rc = pgm->cmd_tpi(pgm, cmd, 1, mem->buf + i, 1);
+ lastaddr++;
+ if (rc == -1) {
+ avrdude_message(MSG_INFO, "avr_read(): error reading address 0x%04lx\n", i);
+ return -1;
+ }
+ }
+ report_progress(i, mem->size, NULL);
+ }
+ return avr_mem_hiaddr(mem);
+ }
+
+ if (pgm->paged_load != NULL && mem->page_size != 0) {
+ /*
+ * the programmer supports a paged mode read
+ */
+ int need_read, failure;
+ unsigned int pageaddr;
+ unsigned int npages, nread;
+
+ /* quickly scan number of pages to be written to first */
+ for (pageaddr = 0, npages = 0;
+ pageaddr < mem->size;
+ pageaddr += mem->page_size) {
+ /* check whether this page must be read */
+ for (i = pageaddr;
+ i < pageaddr + mem->page_size;
+ i++)
+ if (vmem == NULL /* no verify, read everything */ ||
+ (mem->tags[i] & TAG_ALLOCATED) != 0 /* verify, do only
+ read pages that
+ are needed in
+ input file */) {
+ npages++;
+ break;
+ }
+ }
+
+ for (pageaddr = 0, failure = 0, nread = 0;
+ !failure && pageaddr < mem->size;
+ pageaddr += mem->page_size) {
+ RETURN_IF_CANCEL();
+ /* check whether this page must be read */
+ for (i = pageaddr, need_read = 0;
+ i < pageaddr + mem->page_size;
+ i++)
+ if (vmem == NULL /* no verify, read everything */ ||
+ (vmem->tags[i] & TAG_ALLOCATED) != 0 /* verify, do only
+ read pages that
+ are needed in
+ input file */) {
+ need_read = 1;
+ break;
+ }
+ if (need_read) {
+ rc = pgm->paged_load(pgm, p, mem, mem->page_size,
+ pageaddr, mem->page_size);
+ if (rc < 0)
+ /* paged load failed, fall back to byte-at-a-time read below */
+ failure = 1;
+ } else {
+ avrdude_message(MSG_DEBUG, "%s: avr_read(): skipping page %u: no interesting data\n",
+ progname, pageaddr / mem->page_size);
+ }
+ nread++;
+ report_progress(nread, npages, NULL);
+ }
+ if (!failure) {
+ if (strcasecmp(mem->desc, "flash") == 0 ||
+ strcasecmp(mem->desc, "application") == 0 ||
+ strcasecmp(mem->desc, "apptable") == 0 ||
+ strcasecmp(mem->desc, "boot") == 0)
+ return avr_mem_hiaddr(mem);
+ else
+ return mem->size;
+ }
+ /* else: fall back to byte-at-a-time write, for historical reasons */
+ }
+
+ if (strcmp(mem->desc, "signature") == 0) {
+ if (pgm->read_sig_bytes) {
+ return pgm->read_sig_bytes(pgm, p, mem);
+ }
+ }
+
+ for (i=0; i < mem->size; i++) {
+ RETURN_IF_CANCEL();
+ if (vmem == NULL ||
+ (vmem->tags[i] & TAG_ALLOCATED) != 0)
+ {
+ rc = pgm->read_byte(pgm, p, mem, i, mem->buf + i);
+ if (rc != 0) {
+ avrdude_message(MSG_INFO, "avr_read(): error reading address 0x%04lx\n", i);
+ if (rc == -1)
+ avrdude_message(MSG_INFO, " read operation not supported for memory \"%s\"\n",
+ memtype);
+ return -2;
+ }
+ }
+ report_progress(i, mem->size, NULL);
+ }
+
+ if (strcasecmp(mem->desc, "flash") == 0 ||
+ strcasecmp(mem->desc, "application") == 0 ||
+ strcasecmp(mem->desc, "apptable") == 0 ||
+ strcasecmp(mem->desc, "boot") == 0)
+ return avr_mem_hiaddr(mem);
+ else
+ return i;
+}
+
+
+/*
+ * write a page data at the specified address
+ */
+int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+ OPCODE * wp, * lext;
+
+ if (pgm->cmd == NULL) {
+ avrdude_message(MSG_INFO, "%s: Error: %s programmer uses avr_write_page() but does not\n"
+ "provide a cmd() method.\n",
+ progname, pgm->type);
+ return -1;
+ }
+
+ wp = mem->op[AVR_OP_WRITEPAGE];
+ if (wp == NULL) {
+ avrdude_message(MSG_INFO, "avr_write_page(): memory \"%s\" not configured for page writes\n",
+ mem->desc);
+ return -1;
+ }
+
+ /*
+ * if this memory is word-addressable, adjust the address
+ * accordingly
+ */
+ if ((mem->op[AVR_OP_LOADPAGE_LO]) || (mem->op[AVR_OP_READ_LO]))
+ addr = addr / 2;
+
+ pgm->pgm_led(pgm, ON);
+ pgm->err_led(pgm, OFF);
+
+ /*
+ * If this device has a "load extended address" command, issue it.
+ */
+ lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
+ if (lext != NULL) {
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(lext, cmd);
+ avr_set_addr(lext, cmd, addr);
+ pgm->cmd(pgm, cmd, res);
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(wp, cmd);
+ avr_set_addr(wp, cmd, addr);
+ pgm->cmd(pgm, cmd, res);
+
+ /*
+ * since we don't know what voltage the target AVR is powered by, be
+ * conservative and delay the max amount the spec says to wait
+ */
+ usleep(mem->max_write_delay);
+
+ pgm->pgm_led(pgm, OFF);
+ return 0;
+}
+
+
+int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+ unsigned char r;
+ int ready;
+ int tries;
+ unsigned long start_time;
+ unsigned long prog_time;
+ unsigned char b;
+ unsigned short caddr;
+ OPCODE * writeop;
+ int rc;
+ int readok=0;
+ struct timeval tv;
+
+ if (pgm->cmd == NULL) {
+ avrdude_message(MSG_INFO, "%s: Error: %s programmer uses avr_write_byte_default() but does not\n"
+ "provide a cmd() method.\n",
+ progname, pgm->type);
+ return -1;
+ }
+
+ if (p->flags & AVRPART_HAS_TPI) {
+ if (pgm->cmd_tpi == NULL) {
+ avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n",
+ progname, pgm->type);
+ return -1;
+ }
+
+ if (strcmp(mem->desc, "flash") == 0) {
+ avrdude_message(MSG_INFO, "Writing a byte to flash is not supported for %s\n", p->desc);
+ return -1;
+ } else if ((mem->offset + addr) & 1) {
+ avrdude_message(MSG_INFO, "Writing a byte to an odd location is not supported for %s\n", p->desc);
+ return -1;
+ }
+
+ while (avr_tpi_poll_nvmbsy(pgm));
+
+ /* must erase fuse first */
+ if (strcmp(mem->desc, "fuse") == 0) {
+ /* setup for SECTION_ERASE (high byte) */
+ avr_tpi_setup_rw(pgm, mem, addr | 1, TPI_NVMCMD_SECTION_ERASE);
+
+ /* write dummy byte */
+ cmd[0] = TPI_CMD_SST;
+ cmd[1] = 0xFF;
+ rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+
+ while (avr_tpi_poll_nvmbsy(pgm));
+ }
+
+ /* setup for WORD_WRITE */
+ avr_tpi_setup_rw(pgm, mem, addr, TPI_NVMCMD_WORD_WRITE);
+
+ cmd[0] = TPI_CMD_SST_PI;
+ cmd[1] = data;
+ rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+ /* dummy high byte to start WORD_WRITE */
+ cmd[0] = TPI_CMD_SST_PI;
+ cmd[1] = data;
+ rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+
+ while (avr_tpi_poll_nvmbsy(pgm));
+
+ return 0;
+ }
+
+ if (!mem->paged &&
+ (p->flags & AVRPART_IS_AT90S1200) == 0) {
+ /*
+ * check to see if the write is necessary by reading the existing
+ * value and only write if we are changing the value; we can't
+ * use this optimization for paged addressing.
+ *
+ * For mysterious reasons, on the AT90S1200, this read operation
+ * sometimes causes the high byte of the same word to be
+ * programmed to the value of the low byte that has just been
+ * programmed before. Avoid that optimization on this device.
+ */
+ rc = pgm->read_byte(pgm, p, mem, addr, &b);
+ if (rc != 0) {
+ if (rc != -1) {
+ return -2;
+ }
+ /*
+ * the read operation is not support on this memory type
+ */
+ }
+ else {
+ readok = 1;
+ if (b == data) {
+ return 0;
+ }
+ }
+ }
+
+ /*
+ * determine which memory opcode to use
+ */
+ if (mem->op[AVR_OP_WRITE_LO]) {
+ if (addr & 0x01)
+ writeop = mem->op[AVR_OP_WRITE_HI];
+ else
+ writeop = mem->op[AVR_OP_WRITE_LO];
+ caddr = addr / 2;
+ }
+ else if (mem->paged && mem->op[AVR_OP_LOADPAGE_LO]) {
+ if (addr & 0x01)
+ writeop = mem->op[AVR_OP_LOADPAGE_HI];
+ else
+ writeop = mem->op[AVR_OP_LOADPAGE_LO];
+ caddr = addr / 2;
+ }
+ else {
+ writeop = mem->op[AVR_OP_WRITE];
+ caddr = addr;
+ }
+
+ if (writeop == NULL) {
+#if DEBUG
+ avrdude_message(MSG_INFO, "avr_write_byte(): write not supported for memory type \"%s\"\n",
+ mem->desc);
+#endif
+ return -1;
+ }
+
+
+ pgm->pgm_led(pgm, ON);
+ pgm->err_led(pgm, OFF);
+
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(writeop, cmd);
+ avr_set_addr(writeop, cmd, caddr);
+ avr_set_input(writeop, cmd, data);
+ pgm->cmd(pgm, cmd, res);
+
+ if (mem->paged) {
+ /*
+ * in paged addressing, single bytes to be written to the memory
+ * page complete immediately, we only need to delay when we commit
+ * the whole page via the avr_write_page() routine.
+ */
+ pgm->pgm_led(pgm, OFF);
+ return 0;
+ }
+
+ if (readok == 0) {
+ /*
+ * read operation not supported for this memory type, just wait
+ * the max programming time and then return
+ */
+ usleep(mem->max_write_delay); /* maximum write delay */
+ pgm->pgm_led(pgm, OFF);
+ return 0;
+ }
+
+ tries = 0;
+ ready = 0;
+ while (!ready) {
+
+ if ((data == mem->readback[0]) ||
+ (data == mem->readback[1])) {
+ /*
+ * use an extra long delay when we happen to be writing values
+ * used for polled data read-back. In this case, polling
+ * doesn't work, and we need to delay the worst case write time
+ * specified for the chip.
+ */
+ usleep(mem->max_write_delay);
+ rc = pgm->read_byte(pgm, p, mem, addr, &r);
+ if (rc != 0) {
+ pgm->pgm_led(pgm, OFF);
+ pgm->err_led(pgm, OFF);
+ return -5;
+ }
+ }
+ else {
+ gettimeofday (&tv, NULL);
+ start_time = (tv.tv_sec * 1000000) + tv.tv_usec;
+ do {
+ /*
+ * Do polling, but timeout after max_write_delay.
+ */
+ rc = pgm->read_byte(pgm, p, mem, addr, &r);
+ if (rc != 0) {
+ pgm->pgm_led(pgm, OFF);
+ pgm->err_led(pgm, ON);
+ return -4;
+ }
+ gettimeofday (&tv, NULL);
+ prog_time = (tv.tv_sec * 1000000) + tv.tv_usec;
+ } while ((r != data) &&
+ ((prog_time-start_time) < mem->max_write_delay));
+ }
+
+ /*
+ * At this point we either have a valid readback or the
+ * max_write_delay is expired.
+ */
+
+ if (r == data) {
+ ready = 1;
+ }
+ else if (mem->pwroff_after_write) {
+ /*
+ * The device has been flagged as power-off after write to this
+ * memory type. The reason we don't just blindly follow the
+ * flag is that the power-off advice may only apply to some
+ * memory bits but not all. We only actually power-off the
+ * device if the data read back does not match what we wrote.
+ */
+ pgm->pgm_led(pgm, OFF);
+ avrdude_message(MSG_INFO, "%s: this device must be powered off and back on to continue\n",
+ progname);
+ if (pgm->pinno[PPI_AVR_VCC]) {
+ avrdude_message(MSG_INFO, "%s: attempting to do this now ...\n", progname);
+ pgm->powerdown(pgm);
+ usleep(250000);
+ rc = pgm->initialize(pgm, p);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: initialization failed, rc=%d\n", progname, rc);
+ avrdude_message(MSG_INFO, "%s: can't re-initialize device after programming the "
+ "%s bits\n", progname, mem->desc);
+ avrdude_message(MSG_INFO, "%s: you must manually power-down the device and restart\n"
+ "%s: %s to continue.\n",
+ progname, progname, progname);
+ return -3;
+ }
+
+ avrdude_message(MSG_INFO, "%s: device was successfully re-initialized\n",
+ progname);
+ return 0;
+ }
+ }
+
+ tries++;
+ if (!ready && tries > 5) {
+ /*
+ * we wrote the data, but after waiting for what should have
+ * been plenty of time, the memory cell still doesn't match what
+ * we wrote. Indicate a write error.
+ */
+ pgm->pgm_led(pgm, OFF);
+ pgm->err_led(pgm, ON);
+
+ return -6;
+ }
+ }
+
+ pgm->pgm_led(pgm, OFF);
+ return 0;
+}
+
+
+/*
+ * write a byte of data at the specified address
+ */
+int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data)
+{
+
+ unsigned char safemode_lfuse;
+ unsigned char safemode_hfuse;
+ unsigned char safemode_efuse;
+ unsigned char safemode_fuse;
+
+ /* If we write the fuses, then we need to tell safemode that they *should* change */
+ safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
+
+ if (strcmp(mem->desc, "fuse")==0) {
+ safemode_fuse = data;
+ }
+ if (strcmp(mem->desc, "lfuse")==0) {
+ safemode_lfuse = data;
+ }
+ if (strcmp(mem->desc, "hfuse")==0) {
+ safemode_hfuse = data;
+ }
+ if (strcmp(mem->desc, "efuse")==0) {
+ safemode_efuse = data;
+ }
+
+ safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
+
+ return pgm->write_byte(pgm, p, mem, addr, data);
+}
+
+
+/*
+ * Write the whole memory region of the specified memory from the
+ * corresponding buffer of the avrpart pointed to by 'p'. Write up to
+ * 'size' bytes from the buffer. Data is only written if the new data
+ * value is different from the existing data value. Data beyond
+ * 'size' bytes is not affected.
+ *
+ * Return the number of bytes written, or -1 if an error occurs.
+ */
+int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
+ int auto_erase)
+{
+ int rc;
+ int newpage, page_tainted, flush_page, do_write;
+ int wsize;
+ unsigned int i, lastaddr;
+ unsigned char data;
+ int werror;
+ unsigned char cmd[4];
+ AVRMEM * m;
+
+ m = avr_locate_mem(p, memtype);
+ if (m == NULL) {
+ avrdude_message(MSG_INFO, "No \"%s\" memory for part %s\n",
+ memtype, p->desc);
+ return -1;
+ }
+
+ pgm->err_led(pgm, OFF);
+
+ werror = 0;
+
+ wsize = m->size;
+ if (size < wsize) {
+ wsize = size;
+ }
+ else if (size > wsize) {
+ avrdude_message(MSG_INFO, "%s: WARNING: %d bytes requested, but memory region is only %d"
+ "bytes\n"
+ "%sOnly %d bytes will actually be written\n",
+ progname, size, wsize,
+ progbuf, wsize);
+ }
+
+
+ if ((p->flags & AVRPART_HAS_TPI) && m->page_size != 0 &&
+ pgm->cmd_tpi != NULL) {
+
+ while (avr_tpi_poll_nvmbsy(pgm));
+
+ /* setup for WORD_WRITE */
+ avr_tpi_setup_rw(pgm, m, 0, TPI_NVMCMD_WORD_WRITE);
+
+ /* make sure it's aligned to a word boundary */
+ if (wsize & 0x1) {
+ wsize++;
+ }
+
+ /* write words, low byte first */
+ for (lastaddr = i = 0; i < wsize; i += 2) {
+ RETURN_IF_CANCEL();
+ if ((m->tags[i] & TAG_ALLOCATED) != 0 ||
+ (m->tags[i + 1] & TAG_ALLOCATED) != 0) {
+
+ if (lastaddr != i) {
+ /* need to setup new address */
+ avr_tpi_setup_rw(pgm, m, i, TPI_NVMCMD_WORD_WRITE);
+ lastaddr = i;
+ }
+
+ cmd[0] = TPI_CMD_SST_PI;
+ cmd[1] = m->buf[i];
+ rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+
+ cmd[1] = m->buf[i + 1];
+ rc = pgm->cmd_tpi(pgm, cmd, 2, NULL, 0);
+
+ lastaddr += 2;
+
+ while (avr_tpi_poll_nvmbsy(pgm));
+ }
+ report_progress(i, wsize, NULL);
+ }
+ return i;
+ }
+
+ if (pgm->paged_write != NULL && m->page_size != 0) {
+ /*
+ * the programmer supports a paged mode write
+ */
+ int need_write, failure;
+ unsigned int pageaddr;
+ unsigned int npages, nwritten;
+
+ /* quickly scan number of pages to be written to first */
+ for (pageaddr = 0, npages = 0;
+ pageaddr < wsize;
+ pageaddr += m->page_size) {
+ /* check whether this page must be written to */
+ for (i = pageaddr;
+ i < pageaddr + m->page_size;
+ i++)
+ if ((m->tags[i] & TAG_ALLOCATED) != 0) {
+ npages++;
+ break;
+ }
+ }
+
+ for (pageaddr = 0, failure = 0, nwritten = 0;
+ !failure && pageaddr < wsize;
+ pageaddr += m->page_size) {
+ RETURN_IF_CANCEL();
+ /* check whether this page must be written to */
+ for (i = pageaddr, need_write = 0;
+ i < pageaddr + m->page_size;
+ i++)
+ if ((m->tags[i] & TAG_ALLOCATED) != 0) {
+ need_write = 1;
+ break;
+ }
+ if (need_write) {
+ rc = 0;
+ if (auto_erase)
+ rc = pgm->page_erase(pgm, p, m, pageaddr);
+ if (rc >= 0)
+ rc = pgm->paged_write(pgm, p, m, m->page_size, pageaddr, m->page_size);
+ if (rc < 0)
+ /* paged write failed, fall back to byte-at-a-time write below */
+ failure = 1;
+ } else {
+ avrdude_message(MSG_DEBUG, "%s: avr_write(): skipping page %u: no interesting data\n",
+ progname, pageaddr / m->page_size);
+ }
+ nwritten++;
+ report_progress(nwritten, npages, NULL);
+ }
+ if (!failure)
+ return wsize;
+ /* else: fall back to byte-at-a-time write, for historical reasons */
+ }
+
+ if (pgm->write_setup) {
+ pgm->write_setup(pgm, p, m);
+ }
+
+ newpage = 1;
+ page_tainted = 0;
+ flush_page = 0;
+
+ for (i=0; i<wsize; i++) {
+ RETURN_IF_CANCEL();
+ data = m->buf[i];
+ report_progress(i, wsize, NULL);
+
+ /*
+ * Find out whether the write action must be invoked for this
+ * byte.
+ *
+ * For non-paged memory, this only happens if TAG_ALLOCATED is
+ * set for the byte.
+ *
+ * For paged memory, TAG_ALLOCATED also invokes the write
+ * operation, which is actually a page buffer fill only. This
+ * "taints" the page, and upon encountering the last byte of each
+ * tainted page, the write operation must also be invoked in order
+ * to actually write the page buffer to memory.
+ */
+ do_write = (m->tags[i] & TAG_ALLOCATED) != 0;
+ if (m->paged) {
+ if (newpage) {
+ page_tainted = do_write;
+ } else {
+ page_tainted |= do_write;
+ }
+ if (i % m->page_size == m->page_size - 1 ||
+ i == wsize - 1) {
+ /* last byte this page */
+ flush_page = page_tainted;
+ newpage = 1;
+ } else {
+ flush_page = newpage = 0;
+ }
+ }
+
+ if (!do_write && !flush_page) {
+ continue;
+ }
+
+ if (do_write) {
+ rc = avr_write_byte(pgm, p, m, i, data);
+ if (rc) {
+ avrdude_message(MSG_INFO, " ***failed; ");
+ avrdude_message(MSG_INFO, "\n");
+ pgm->err_led(pgm, ON);
+ werror = 1;
+ }
+ }
+
+ /*
+ * check to see if it is time to flush the page with a page
+ * write
+ */
+ if (flush_page) {
+ rc = avr_write_page(pgm, p, m, i);
+ if (rc) {
+ avrdude_message(MSG_INFO, " *** page %d (addresses 0x%04x - 0x%04x) failed "
+ "to write\n",
+ i % m->page_size,
+ i - m->page_size + 1, i);
+ avrdude_message(MSG_INFO, "\n");
+ pgm->err_led(pgm, ON);
+ werror = 1;
+ }
+ }
+
+ if (werror) {
+ /*
+ * make sure the error led stay on if there was a previous write
+ * error, otherwise it gets cleared in avr_write_byte()
+ */
+ pgm->err_led(pgm, ON);
+ return -1;
+ }
+ }
+
+ return i;
+}
+
+
+
+/*
+ * read the AVR device's signature bytes
+ */
+int avr_signature(PROGRAMMER * pgm, AVRPART * p)
+{
+ int rc;
+
+ report_progress(0,1,"Reading");
+ rc = avr_read(pgm, p, "signature", 0);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: error reading signature data for part \"%s\", rc=%d\n",
+ progname, p->desc, rc);
+ return -1;
+ }
+ report_progress(1,1,NULL);
+
+ return 0;
+}
+
+
+/*
+ * Verify the memory buffer of p with that of v. The byte range of v,
+ * may be a subset of p. The byte range of p should cover the whole
+ * chip's memory size.
+ *
+ * Return the number of bytes verified, or -1 if they don't match.
+ */
+int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size)
+{
+ int i;
+ unsigned char * buf1, * buf2;
+ int vsize;
+ AVRMEM * a, * b;
+
+ a = avr_locate_mem(p, memtype);
+ if (a == NULL) {
+ avrdude_message(MSG_INFO, "avr_verify(): memory type \"%s\" not defined for part %s\n",
+ memtype, p->desc);
+ return -1;
+ }
+
+ b = avr_locate_mem(v, memtype);
+ if (b == NULL) {
+ avrdude_message(MSG_INFO, "avr_verify(): memory type \"%s\" not defined for part %s\n",
+ memtype, v->desc);
+ return -1;
+ }
+
+ buf1 = a->buf;
+ buf2 = b->buf;
+ vsize = a->size;
+
+ if (vsize < size) {
+ avrdude_message(MSG_INFO, "%s: WARNING: requested verification for %d bytes\n"
+ "%s%s memory region only contains %d bytes\n"
+ "%sOnly %d bytes will be verified.\n",
+ progname, size,
+ progbuf, memtype, vsize,
+ progbuf, vsize);
+ size = vsize;
+ }
+
+ for (i=0; i<size; i++) {
+ RETURN_IF_CANCEL();
+ if ((b->tags[i] & TAG_ALLOCATED) != 0 &&
+ buf1[i] != buf2[i]) {
+ avrdude_message(MSG_INFO, "%s: verification error, first mismatch at byte 0x%04x\n"
+ "%s0x%02x != 0x%02x\n",
+ progname, i,
+ progbuf, buf1[i], buf2[i]);
+ return -1;
+ }
+ }
+
+ return size;
+}
+
+
+int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles)
+{
+ AVRMEM * a;
+ unsigned int cycle_count = 0;
+ unsigned char v1;
+ int rc;
+ int i;
+
+ a = avr_locate_mem(p, "eeprom");
+ if (a == NULL) {
+ return -1;
+ }
+
+ for (i=4; i>0; i--) {
+ rc = pgm->read_byte(pgm, p, a, a->size-i, &v1);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: WARNING: can't read memory for cycle count, rc=%d\n",
+ progname, rc);
+ return -1;
+ }
+ cycle_count = (cycle_count << 8) | v1;
+ }
+
+ /*
+ * If the EEPROM is erased, the cycle count reads 0xffffffff.
+ * In this case we return a cycle_count of zero.
+ * So, the calling function don't have to care about whether or not
+ * the cycle count was initialized.
+ */
+ if (cycle_count == 0xffffffff) {
+ cycle_count = 0;
+ }
+
+ *cycles = (int) cycle_count;
+
+ return 0;
+}
+
+
+int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles)
+{
+ AVRMEM * a;
+ unsigned char v1;
+ int rc;
+ int i;
+
+ a = avr_locate_mem(p, "eeprom");
+ if (a == NULL) {
+ return -1;
+ }
+
+ for (i=1; i<=4; i++) {
+ v1 = cycles & 0xff;
+ cycles = cycles >> 8;
+
+ rc = avr_write_byte(pgm, p, a, a->size-i, v1);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: WARNING: can't write memory for cycle count, rc=%d\n",
+ progname, rc);
+ return -1;
+ }
+ }
+
+ return 0;
+ }
+
+int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ int rc;
+
+ rc = pgm->chip_erase(pgm, p);
+
+ return rc;
+}
+
+/*
+ * Report the progress of a read or write operation from/to the
+ * device.
+ *
+ * The first call of report_progress() should look like this (for a write op):
+ *
+ * report_progress (0, 1, "Writing");
+ *
+ * Then hdr should be passed NULL on subsequent calls while the
+ * operation is progressing. Once the operation is complete, a final
+ * call should be made as such to ensure proper termination of the
+ * progress report:
+ *
+ * report_progress (1, 1, NULL);
+ *
+ * It would be nice if we could reduce the usage to one and only one
+ * call for each of start, during and end cases. As things stand now,
+ * that is not possible and makes maintenance a bit more work.
+ */
+void report_progress (int completed, int total, char *hdr)
+{
+ static int last = 0;
+ static double start_time;
+ int percent = (total > 0) ? ((completed * 100) / total) : 100;
+ struct timeval tv;
+ double t;
+
+ if (update_progress == NULL)
+ return;
+
+ gettimeofday(&tv, NULL);
+ t = tv.tv_sec + ((double)tv.tv_usec)/1000000;
+
+ if (hdr) {
+ last = 0;
+ start_time = t;
+ update_progress (percent, t - start_time, hdr);
+ }
+
+ if (percent > 100)
+ percent = 100;
+
+ if (percent > last) {
+ last = percent;
+ update_progress (percent, t - start_time, hdr);
+ }
+
+ if (percent == 100)
+ last = 0; /* Get ready for next time. */
+}
diff --git a/xs/src/avrdude/avr910.c b/xs/src/avrdude/avr910.c
new file mode 100644
index 000000000..aa5cc07a9
--- /dev/null
+++ b/xs/src/avrdude/avr910.c
@@ -0,0 +1,777 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
+ * Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
+ * Copyright 2008 Klaus Leidinger <klaus@mikrocontroller-projekte.de>
+ *
+ * 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 Atmel Low Cost Serial programmers which adher to the
+ * protocol described in application note avr910.
+ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#if !defined(WIN32NATIVE)
+# include <sys/time.h>
+#endif
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "avr910.h"
+
+/*
+ * Private data for this programmer.
+ */
+struct pdata
+{
+ char has_auto_incr_addr;
+ unsigned char devcode;
+ unsigned int buffersize;
+ unsigned char test_blockmode;
+ unsigned char use_blockmode;
+};
+
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
+static void avr910_setup(PROGRAMMER * pgm)
+{
+ if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
+ avrdude_message(MSG_INFO, "%s: avr910_setup(): Out of memory allocating private data\n",
+ progname);
+ exit(1);
+ }
+ memset(pgm->cookie, 0, sizeof(struct pdata));
+ PDATA(pgm)->test_blockmode = 1;
+}
+
+static void avr910_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+}
+
+
+static int avr910_send(PROGRAMMER * pgm, char * buf, size_t len)
+{
+ return serial_send(&pgm->fd, (unsigned char *)buf, len);
+}
+
+
+static int avr910_recv(PROGRAMMER * pgm, char * buf, size_t len)
+{
+ int rv;
+
+ rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
+ if (rv < 0) {
+ avrdude_message(MSG_INFO, "%s: avr910_recv(): programmer is not responding\n",
+ progname);
+ return 1;
+ }
+ return 0;
+}
+
+
+static int avr910_drain(PROGRAMMER * pgm, int display)
+{
+ return serial_drain(&pgm->fd, display);
+}
+
+
+static int avr910_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
+{
+ char c;
+
+ avr910_recv(pgm, &c, 1);
+ if (c != '\r') {
+ avrdude_message(MSG_INFO, "%s: error: programmer did not respond to command: %s\n",
+ progname, errmsg);
+ return 1;
+ }
+ return 0;
+}
+
+
+/*
+ * issue the 'chip erase' command to the AVR device
+ */
+static int avr910_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ avr910_send(pgm, "e", 1);
+ if (avr910_vfy_cmd_sent(pgm, "chip erase") < 0)
+ return -1;
+
+ /*
+ * avr910 firmware may not delay long enough
+ */
+ usleep (p->chip_erase_delay);
+
+ return 0;
+}
+
+
+static int avr910_enter_prog_mode(PROGRAMMER * pgm)
+{
+ avr910_send(pgm, "P", 1);
+ return avr910_vfy_cmd_sent(pgm, "enter prog mode");
+}
+
+
+static int avr910_leave_prog_mode(PROGRAMMER * pgm)
+{
+ avr910_send(pgm, "L", 1);
+ return avr910_vfy_cmd_sent(pgm, "leave prog mode");
+}
+
+
+/*
+ * issue the 'program enable' command to the AVR device
+ */
+static int avr910_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ return -1;
+}
+
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ char id[8];
+ char sw[2];
+ char hw[2];
+ char buf[10];
+ char type;
+ char c;
+ AVRPART * part;
+
+ /* Get the programmer identifier. Programmer returns exactly 7 chars
+ _without_ the null.*/
+
+ avr910_send(pgm, "S", 1);
+ memset (id, 0, sizeof(id));
+ avr910_recv(pgm, id, sizeof(id)-1);
+
+ /* Get the HW and SW versions to see if the programmer is present. */
+
+ avr910_send(pgm, "V", 1);
+ avr910_recv(pgm, sw, sizeof(sw));
+
+ avr910_send(pgm, "v", 1);
+ avr910_recv(pgm, hw, sizeof(hw));
+
+ /* Get the programmer type (serial or parallel). Expect serial. */
+
+ avr910_send(pgm, "p", 1);
+ avr910_recv(pgm, &type, 1);
+
+ avrdude_message(MSG_INFO, "Found programmer: Id = \"%s\"; type = %c\n", id, type);
+ avrdude_message(MSG_INFO, " Software Version = %c.%c; ", sw[0], sw[1]);
+ avrdude_message(MSG_INFO, "Hardware Version = %c.%c\n", hw[0], hw[1]);
+
+ /* See if programmer supports autoincrement of address. */
+
+ avr910_send(pgm, "a", 1);
+ avr910_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
+ if (PDATA(pgm)->has_auto_incr_addr == 'Y')
+ avrdude_message(MSG_INFO, "Programmer supports auto addr increment.\n");
+
+ /* Check support for buffered memory access, ignore if not available */
+
+ if (PDATA(pgm)->test_blockmode == 1) {
+ avr910_send(pgm, "b", 1);
+ avr910_recv(pgm, &c, 1);
+ if (c == 'Y') {
+ avr910_recv(pgm, &c, 1);
+ PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
+ avr910_recv(pgm, &c, 1);
+ PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
+ avrdude_message(MSG_INFO, "Programmer supports buffered memory access with "
+ "buffersize = %u bytes.\n",
+ PDATA(pgm)->buffersize);
+ PDATA(pgm)->use_blockmode = 1;
+ } else {
+ PDATA(pgm)->use_blockmode = 0;
+ }
+ } else {
+ PDATA(pgm)->use_blockmode = 0;
+ }
+
+ if (PDATA(pgm)->devcode == 0) {
+ char devtype_1st;
+ int dev_supported = 0;
+
+ /* Get list of devices that the programmer supports. */
+
+ avr910_send(pgm, "t", 1);
+ avrdude_message(MSG_INFO, "\nProgrammer supports the following devices:\n");
+ devtype_1st = 0;
+ while (1) {
+ avr910_recv(pgm, &c, 1);
+ if (devtype_1st == 0)
+ devtype_1st = c;
+ if (c == 0)
+ break;
+ part = locate_part_by_avr910_devcode(part_list, c);
+
+ avrdude_message(MSG_INFO, " Device code: 0x%02x = %s\n", c, part ? part->desc : "(unknown)");
+
+ /* FIXME: Need to lookup devcode and report the device. */
+
+ if (p->avr910_devcode == c)
+ dev_supported = 1;
+ };
+ avrdude_message(MSG_INFO, "\n");
+
+ if (!dev_supported) {
+ avrdude_message(MSG_INFO, "%s: %s: selected device is not supported by programmer: %s\n",
+ progname, ovsigck? "warning": "error", p->id);
+ if (!ovsigck)
+ return -1;
+ }
+ /* If the user forced the selection, use the first device
+ type that is supported by the programmer. */
+ buf[1] = ovsigck? devtype_1st: p->avr910_devcode;
+ } else {
+ /* devcode overridden by -x devcode= option */
+ buf[1] = (char)(PDATA(pgm)->devcode);
+ }
+
+ /* Tell the programmer which part we selected. */
+ buf[0] = 'T';
+ /* buf[1] has been set up above */
+
+ avr910_send(pgm, buf, 2);
+ avr910_vfy_cmd_sent(pgm, "select device");
+
+ avrdude_message(MSG_NOTICE, "%s: avr910_devcode selected: 0x%02x\n",
+ progname, (unsigned)buf[1]);
+
+ avr910_enter_prog_mode(pgm);
+
+ return 0;
+}
+
+
+static void avr910_disable(PROGRAMMER * pgm)
+{
+ /* Do nothing. */
+
+ return;
+}
+
+
+static void avr910_enable(PROGRAMMER * pgm)
+{
+ /* Do nothing. */
+
+ return;
+}
+
+
+/*
+ * transmit an AVR device command and return the results; 'cmd' and
+ * 'res' must point to at least a 4 byte data buffer
+ */
+static int avr910_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+ unsigned char *res)
+{
+ char buf[5];
+
+ /* FIXME: Insert version check here */
+
+ buf[0] = '.'; /* New Universal Command */
+ buf[1] = cmd[0];
+ buf[2] = cmd[1];
+ buf[3] = cmd[2];
+ buf[4] = cmd[3];
+
+ avr910_send (pgm, buf, 5);
+ avr910_recv (pgm, buf, 2);
+
+ res[0] = 0x00; /* Dummy value */
+ res[1] = cmd[0];
+ res[2] = cmd[1];
+ res[3] = buf[0];
+
+ return 0;
+}
+
+
+static int avr910_parseextparms(PROGRAMMER * pgm, LISTID extparms)
+{
+ LNODEID ln;
+ const char *extended_param;
+ int rv = 0;
+
+ for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
+ extended_param = ldata(ln);
+
+ if (strncmp(extended_param, "devcode=", strlen("devcode=")) == 0) {
+ int devcode;
+ if (sscanf(extended_param, "devcode=%i", &devcode) != 1 ||
+ devcode <= 0 || devcode > 255) {
+ avrdude_message(MSG_INFO, "%s: avr910_parseextparms(): invalid devcode '%s'\n",
+ progname, extended_param);
+ rv = -1;
+ continue;
+ }
+ avrdude_message(MSG_NOTICE2, "%s: avr910_parseextparms(): devcode overwritten as 0x%02x\n",
+ progname, devcode);
+ PDATA(pgm)->devcode = devcode;
+
+ continue;
+ }
+ if (strncmp(extended_param, "no_blockmode", strlen("no_blockmode")) == 0) {
+ avrdude_message(MSG_NOTICE2, "%s: avr910_parseextparms(-x): no testing for Blockmode\n",
+ progname);
+ PDATA(pgm)->test_blockmode = 0;
+
+ continue;
+ }
+
+ avrdude_message(MSG_INFO, "%s: avr910_parseextparms(): invalid extended parameter '%s'\n",
+ progname, extended_param);
+ rv = -1;
+ }
+
+ return rv;
+}
+
+
+static int avr910_open(PROGRAMMER * pgm, char * port)
+{
+ union pinfo pinfo;
+ /*
+ * If baudrate was not specified use 19.200 Baud
+ */
+ if(pgm->baudrate == 0) {
+ pgm->baudrate = 19200;
+ }
+
+ strcpy(pgm->port, port);
+ pinfo.baud = pgm->baudrate;
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ avr910_drain (pgm, 0);
+
+ return 0;
+}
+
+static void avr910_close(PROGRAMMER * pgm)
+{
+ avr910_leave_prog_mode(pgm);
+
+ serial_close(&pgm->fd);
+ pgm->fd.ifd = -1;
+}
+
+
+static void avr910_display(PROGRAMMER * pgm, const char * p)
+{
+ return;
+}
+
+
+static void avr910_set_addr(PROGRAMMER * pgm, unsigned long addr)
+{
+ char cmd[3];
+
+ cmd[0] = 'A';
+ cmd[1] = (addr >> 8) & 0xff;
+ cmd[2] = addr & 0xff;
+
+ avr910_send(pgm, cmd, sizeof(cmd));
+ avr910_vfy_cmd_sent(pgm, "set addr");
+}
+
+
+static int avr910_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char value)
+{
+ char cmd[2];
+
+ if (strcmp(m->desc, "flash") == 0) {
+ if (addr & 0x01) {
+ cmd[0] = 'C'; /* Write Program Mem high byte */
+ }
+ else {
+ cmd[0] = 'c';
+ }
+
+ addr >>= 1;
+ }
+ else if (strcmp(m->desc, "eeprom") == 0) {
+ cmd[0] = 'D';
+ }
+ else {
+ return avr_write_byte_default(pgm, p, m, addr, value);
+ }
+
+ cmd[1] = value;
+
+ avr910_set_addr(pgm, addr);
+
+ avr910_send(pgm, cmd, sizeof(cmd));
+ avr910_vfy_cmd_sent(pgm, "write byte");
+
+ return 0;
+}
+
+
+static int avr910_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char * value)
+{
+ char buf[2];
+
+ avr910_set_addr(pgm, addr >> 1);
+
+ avr910_send(pgm, "R", 1);
+
+ /* Read back the program mem word (MSB first) */
+ avr910_recv(pgm, buf, sizeof(buf));
+
+ if ((addr & 0x01) == 0) {
+ *value = buf[1];
+ }
+ else {
+ *value = buf[0];
+ }
+
+ return 0;
+}
+
+
+static int avr910_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char * value)
+{
+ avr910_set_addr(pgm, addr);
+ avr910_send(pgm, "d", 1);
+ avr910_recv(pgm, (char *)value, 1);
+
+ return 0;
+}
+
+
+static int avr910_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char * value)
+{
+ if (strcmp(m->desc, "flash") == 0) {
+ return avr910_read_byte_flash(pgm, p, m, addr, value);
+ }
+
+ if (strcmp(m->desc, "eeprom") == 0) {
+ return avr910_read_byte_eeprom(pgm, p, m, addr, value);
+ }
+
+ return avr_read_byte_default(pgm, p, m, addr, value);
+}
+
+
+static int avr910_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned char cmd[] = {'c', 'C'};
+ char buf[2];
+ unsigned int max_addr = addr + n_bytes;
+ unsigned int page_addr;
+ int page_bytes = page_size;
+ int page_wr_cmd_pending = 0;
+
+ page_addr = addr;
+ avr910_set_addr(pgm, addr>>1);
+
+ while (addr < max_addr) {
+ page_wr_cmd_pending = 1;
+ buf[0] = cmd[addr & 0x01];
+ buf[1] = m->buf[addr];
+ avr910_send(pgm, buf, sizeof(buf));
+ avr910_vfy_cmd_sent(pgm, "write byte");
+
+ addr++;
+ page_bytes--;
+
+ if (m->paged && (page_bytes == 0)) {
+ /* Send the "Issue Page Write" if we have sent a whole page. */
+
+ avr910_set_addr(pgm, page_addr>>1);
+ avr910_send(pgm, "m", 1);
+ avr910_vfy_cmd_sent(pgm, "flush page");
+
+ page_wr_cmd_pending = 0;
+ usleep(m->max_write_delay);
+ avr910_set_addr(pgm, addr>>1);
+
+ /* Set page address for next page. */
+
+ page_addr = addr;
+ page_bytes = page_size;
+ }
+ else if ((PDATA(pgm)->has_auto_incr_addr != 'Y') && ((addr & 0x01) == 0)) {
+ avr910_set_addr(pgm, addr>>1);
+ }
+ }
+
+ /* If we didn't send the page wr cmd after the last byte written in the
+ loop, send it now. */
+
+ if (page_wr_cmd_pending) {
+ avr910_set_addr(pgm, page_addr>>1);
+ avr910_send(pgm, "m", 1);
+ avr910_vfy_cmd_sent(pgm, "flush final page");
+ usleep(m->max_write_delay);
+ }
+
+ return addr;
+}
+
+
+static int avr910_paged_write_eeprom(PROGRAMMER * pgm, AVRPART * p,
+ AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ char cmd[2];
+ unsigned int max_addr = addr + n_bytes;
+
+ avr910_set_addr(pgm, addr);
+
+ cmd[0] = 'D';
+
+ while (addr < max_addr) {
+ cmd[1] = m->buf[addr];
+ avr910_send(pgm, cmd, sizeof(cmd));
+ avr910_vfy_cmd_sent(pgm, "write byte");
+ usleep(m->max_write_delay);
+
+ addr++;
+
+ if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
+ avr910_set_addr(pgm, addr);
+ }
+ }
+
+ return addr;
+}
+
+
+static int avr910_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ int rval = 0;
+ if (PDATA(pgm)->use_blockmode == 0) {
+ if (strcmp(m->desc, "flash") == 0) {
+ rval = avr910_paged_write_flash(pgm, p, m, page_size, addr, n_bytes);
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ rval = avr910_paged_write_eeprom(pgm, p, m, page_size, addr, n_bytes);
+ } else {
+ rval = -2;
+ }
+ }
+
+ if (PDATA(pgm)->use_blockmode == 1) {
+ unsigned int max_addr = addr + n_bytes;
+ char *cmd;
+ unsigned int blocksize = PDATA(pgm)->buffersize;
+ int wr_size;
+
+ if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
+ return -2;
+
+ if (m->desc[0] == 'e') {
+ blocksize = 1; /* Write to eeprom single bytes only */
+ wr_size = 1;
+ } else {
+ wr_size = 2;
+ }
+
+ avr910_set_addr(pgm, addr / wr_size);
+
+ cmd = malloc(4 + blocksize);
+ if (!cmd) return -1;
+
+ cmd[0] = 'B';
+ cmd[3] = toupper((int)(m->desc[0]));
+
+ while (addr < max_addr) {
+ if ((max_addr - addr) < blocksize) {
+ blocksize = max_addr - addr;
+ };
+ memcpy(&cmd[4], &m->buf[addr], blocksize);
+ cmd[1] = (blocksize >> 8) & 0xff;
+ cmd[2] = blocksize & 0xff;
+
+ avr910_send(pgm, cmd, 4 + blocksize);
+ avr910_vfy_cmd_sent(pgm, "write block");
+
+ addr += blocksize;
+ } /* while */
+ free(cmd);
+
+ rval = addr;
+ }
+ return rval;
+}
+
+
+static int avr910_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ char cmd[4];
+ int rd_size;
+ unsigned int max_addr;
+ char buf[2];
+ int rval=0;
+
+ max_addr = addr + n_bytes;
+
+ if (strcmp(m->desc, "flash") == 0) {
+ cmd[0] = 'R';
+ rd_size = 2; /* read two bytes per addr */
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ cmd[0] = 'd';
+ rd_size = 1;
+ } else {
+ return -2;
+ }
+
+ if (PDATA(pgm)->use_blockmode) {
+ /* use buffered mode */
+ int blocksize = PDATA(pgm)->buffersize;
+
+ cmd[0] = 'g';
+ cmd[3] = toupper((int)(m->desc[0]));
+
+ avr910_set_addr(pgm, addr / rd_size);
+
+ while (addr < max_addr) {
+ if ((max_addr - addr) < blocksize) {
+ blocksize = max_addr - addr;
+ }
+ cmd[1] = (blocksize >> 8) & 0xff;
+ cmd[2] = blocksize & 0xff;
+
+ avr910_send(pgm, cmd, 4);
+ avr910_recv(pgm, (char *)&m->buf[addr], blocksize);
+
+ addr += blocksize;
+ }
+
+ rval = addr;
+ } else {
+
+ avr910_set_addr(pgm, addr / rd_size);
+
+ while (addr < max_addr) {
+ avr910_send(pgm, cmd, 1);
+ if (rd_size == 2) {
+ /* The 'R' command returns two bytes, MSB first, we need to put the data
+ into the memory buffer LSB first. */
+ avr910_recv(pgm, buf, 2);
+ m->buf[addr] = buf[1]; /* LSB */
+ m->buf[addr + 1] = buf[0]; /* MSB */
+ }
+ else {
+ avr910_recv(pgm, (char *)&m->buf[addr], 1);
+ }
+
+ addr += rd_size;
+
+ if (PDATA(pgm)->has_auto_incr_addr != 'Y') {
+ avr910_set_addr(pgm, addr / rd_size);
+ }
+ }
+
+ rval = addr;
+ }
+
+ return rval;
+}
+
+/* Signature byte reads are always 3 bytes. */
+
+static int avr910_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
+{
+ unsigned char tmp;
+
+ if (m->size < 3) {
+ avrdude_message(MSG_INFO, "%s: memsize too small for sig byte read", progname);
+ return -1;
+ }
+
+ avr910_send(pgm, "s", 1);
+ avr910_recv(pgm, (char *)m->buf, 3);
+ /* Returned signature has wrong order. */
+ tmp = m->buf[2];
+ m->buf[2] = m->buf[0];
+ m->buf[0] = tmp;
+
+ return 3;
+}
+
+const char avr910_desc[] = "Serial programmers using protocol described in application note AVR910";
+
+void avr910_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "avr910");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = avr910_initialize;
+ pgm->display = avr910_display;
+ pgm->enable = avr910_enable;
+ pgm->disable = avr910_disable;
+ pgm->program_enable = avr910_program_enable;
+ pgm->chip_erase = avr910_chip_erase;
+ pgm->cmd = avr910_cmd;
+ pgm->open = avr910_open;
+ pgm->close = avr910_close;
+
+ /*
+ * optional functions
+ */
+
+ pgm->write_byte = avr910_write_byte;
+ pgm->read_byte = avr910_read_byte;
+
+ pgm->paged_write = avr910_paged_write;
+ pgm->paged_load = avr910_paged_load;
+
+ pgm->read_sig_bytes = avr910_read_sig_bytes;
+
+ pgm->parseextparams = avr910_parseextparms;
+ pgm->setup = avr910_setup;
+ pgm->teardown = avr910_teardown;
+}
diff --git a/xs/src/avrdude/avr910.h b/xs/src/avrdude/avr910.h
new file mode 100644
index 000000000..808f7e68f
--- /dev/null
+++ b/xs/src/avrdude/avr910.h
@@ -0,0 +1,35 @@
+/*
+ * 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$ */
+
+#ifndef avr910_h
+#define avr910_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char avr910_desc[];
+void avr910_initpgm (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* avr910_h */
diff --git a/xs/src/avrdude/avrdude-slic3r.cpp b/xs/src/avrdude/avrdude-slic3r.cpp
new file mode 100644
index 000000000..3037f5284
--- /dev/null
+++ b/xs/src/avrdude/avrdude-slic3r.cpp
@@ -0,0 +1,258 @@
+#include "avrdude-slic3r.hpp"
+
+#include <deque>
+#include <thread>
+#include <cstring>
+#include <cstdlib>
+#include <new>
+#include <exception>
+
+extern "C" {
+#include "ac_cfg.h"
+#include "avrdude.h"
+}
+
+
+namespace Slic3r {
+
+
+// C callbacks
+
+// Used by our custom code in avrdude to receive messages that avrdude normally outputs on stdout (see avrdude_message())
+static void avrdude_message_handler_closure(const char *msg, unsigned size, void *user_p)
+{
+ auto *message_fn = reinterpret_cast<AvrDude::MessageFn*>(user_p);
+ (*message_fn)(msg, size);
+}
+
+// Used by our custom code in avrdude to report progress in the GUI
+static void avrdude_progress_handler_closure(const char *task, unsigned progress, void *user_p)
+{
+ auto *progress_fn = reinterpret_cast<AvrDude::ProgressFn*>(user_p);
+ (*progress_fn)(task, progress);
+}
+
+static void avrdude_oom_handler(const char *context, void *user_p)
+{
+ throw std::bad_alloc();
+}
+
+
+// Private
+
+struct AvrDude::priv
+{
+ std::string sys_config;
+ std::deque<std::vector<std::string>> args;
+ bool cancelled = false;
+ int exit_code = 0;
+ size_t current_args_set = 0;
+ RunFn run_fn;
+ MessageFn message_fn;
+ ProgressFn progress_fn;
+ CompleteFn complete_fn;
+
+ std::thread avrdude_thread;
+
+ priv(std::string &&sys_config) : sys_config(sys_config) {}
+
+ void set_handlers();
+ void unset_handlers();
+ int run_one(const std::vector<std::string> &args);
+ int run();
+
+ struct HandlerGuard
+ {
+ priv &p;
+
+ HandlerGuard(priv &p) : p(p) { p.set_handlers(); }
+ ~HandlerGuard() { p.unset_handlers(); }
+ };
+};
+
+void AvrDude::priv::set_handlers()
+{
+ if (message_fn) {
+ ::avrdude_message_handler_set(avrdude_message_handler_closure, reinterpret_cast<void*>(&message_fn));
+ } else {
+ ::avrdude_message_handler_set(nullptr, nullptr);
+ }
+
+ if (progress_fn) {
+ ::avrdude_progress_handler_set(avrdude_progress_handler_closure, reinterpret_cast<void*>(&progress_fn));
+ } else {
+ ::avrdude_progress_handler_set(nullptr, nullptr);
+ }
+
+ ::avrdude_oom_handler_set(avrdude_oom_handler, nullptr);
+}
+
+void AvrDude::priv::unset_handlers()
+{
+ ::avrdude_message_handler_set(nullptr, nullptr);
+ ::avrdude_progress_handler_set(nullptr, nullptr);
+ ::avrdude_oom_handler_set(nullptr, nullptr);
+}
+
+
+int AvrDude::priv::run_one(const std::vector<std::string> &args) {
+ std::vector<char*> c_args {{ const_cast<char*>(PACKAGE_NAME) }};
+ for (const auto &arg : args) {
+ c_args.push_back(const_cast<char*>(arg.data()));
+ }
+
+ HandlerGuard guard(*this);
+
+ const auto res = ::avrdude_main(static_cast<int>(c_args.size()), c_args.data(), sys_config.c_str());
+
+ return res;
+}
+
+int AvrDude::priv::run() {
+ for (; args.size() > 0; current_args_set++) {
+ int res = run_one(args.front());
+ args.pop_front();
+ if (res != 0) {
+ return res;
+ }
+ }
+
+ return 0;
+}
+
+
+// Public
+
+AvrDude::AvrDude(std::string sys_config) : p(new priv(std::move(sys_config))) {}
+
+AvrDude::AvrDude(AvrDude &&other) : p(std::move(other.p)) {}
+
+AvrDude::~AvrDude()
+{
+ if (p && p->avrdude_thread.joinable()) {
+ p->avrdude_thread.detach();
+ }
+}
+
+AvrDude& AvrDude::push_args(std::vector<std::string> args)
+{
+ if (p) { p->args.push_back(std::move(args)); }
+ return *this;
+}
+
+AvrDude& AvrDude::on_run(RunFn fn)
+{
+ if (p) { p->run_fn = std::move(fn); }
+ return *this;
+}
+
+AvrDude& AvrDude::on_message(MessageFn fn)
+{
+ if (p) { p->message_fn = std::move(fn); }
+ return *this;
+}
+
+AvrDude& AvrDude::on_progress(ProgressFn fn)
+{
+ if (p) { p->progress_fn = std::move(fn); }
+ return *this;
+}
+
+AvrDude& AvrDude::on_complete(CompleteFn fn)
+{
+ if (p) { p->complete_fn = std::move(fn); }
+ return *this;
+}
+
+int AvrDude::run_sync()
+{
+ return p ? p->run() : -1;
+}
+
+AvrDude::Ptr AvrDude::run()
+{
+ auto self = std::make_shared<AvrDude>(std::move(*this));
+
+ if (self->p) {
+ auto avrdude_thread = std::thread([self]() {
+ try {
+ if (self->p->run_fn) {
+ self->p->run_fn(self);
+ }
+
+ if (! self->p->cancelled) {
+ self->p->exit_code = self->p->run();
+ }
+
+ if (self->p->complete_fn) {
+ self->p->complete_fn();
+ }
+ } catch (const std::exception &ex) {
+ self->p->exit_code = EXIT_EXCEPTION;
+
+ static const char *msg = "An exception was thrown in the background thread:\n";
+
+ const char *what = ex.what();
+ auto &message_fn = self->p->message_fn;
+ if (message_fn) {
+ message_fn(msg, sizeof(msg));
+ message_fn(what, std::strlen(what));
+ message_fn("\n", 1);
+ }
+
+ if (self->p->complete_fn) {
+ self->p->complete_fn();
+ }
+ } catch (...) {
+ self->p->exit_code = EXIT_EXCEPTION;
+
+ static const char *msg = "An unkown exception was thrown in the background thread.\n";
+
+ if (self->p->message_fn) {
+ self->p->message_fn(msg, sizeof(msg));
+ }
+
+ if (self->p->complete_fn) {
+ self->p->complete_fn();
+ }
+ }
+ });
+
+ self->p->avrdude_thread = std::move(avrdude_thread);
+ }
+
+ return self;
+}
+
+void AvrDude::cancel()
+{
+ if (p) {
+ p->cancelled = true;
+ ::avrdude_cancel();
+ }
+}
+
+void AvrDude::join()
+{
+ if (p && p->avrdude_thread.joinable()) {
+ p->avrdude_thread.join();
+ }
+}
+
+bool AvrDude::cancelled()
+{
+ return p ? p->cancelled : false;
+}
+
+int AvrDude::exit_code()
+{
+ return p ? p->exit_code : 0;
+}
+
+size_t AvrDude::last_args_set()
+{
+ return p ? p->current_args_set : 0;
+}
+
+
+}
diff --git a/xs/src/avrdude/avrdude-slic3r.hpp b/xs/src/avrdude/avrdude-slic3r.hpp
new file mode 100644
index 000000000..754e1e345
--- /dev/null
+++ b/xs/src/avrdude/avrdude-slic3r.hpp
@@ -0,0 +1,82 @@
+#ifndef slic3r_avrdude_slic3r_hpp_
+#define slic3r_avrdude_slic3r_hpp_
+
+#include <memory>
+#include <vector>
+#include <string>
+#include <functional>
+
+namespace Slic3r {
+
+class AvrDude
+{
+public:
+ enum {
+ EXIT_SUCCEESS = 0,
+ EXIT_EXCEPTION = -1000,
+ };
+
+ typedef std::shared_ptr<AvrDude> Ptr;
+ typedef std::function<void(Ptr /* avrdude */)> RunFn;
+ typedef std::function<void(const char * /* msg */, unsigned /* size */)> MessageFn;
+ typedef std::function<void(const char * /* task */, unsigned /* progress */)> ProgressFn;
+ typedef std::function<void()> CompleteFn;
+
+ // Main c-tor, sys_config is the location of avrdude's main configuration file
+ AvrDude(std::string sys_config);
+ AvrDude(AvrDude &&);
+ AvrDude(const AvrDude &) = delete;
+ AvrDude &operator=(AvrDude &&) = delete;
+ AvrDude &operator=(const AvrDude &) = delete;
+ ~AvrDude();
+
+ // Push a set of avrdude cli arguments
+ // Each set makes one avrdude invocation - use this method multiple times to push
+ // more than one avrdude invocations.
+ AvrDude& push_args(std::vector<std::string> args);
+
+ // Set a callback to be called just after run() before avrdude is ran
+ // This can be used to perform any needed setup tasks from the background thread,
+ // and, optionally, to cancel by writing true to the `cancel` argument.
+ // This has no effect when using run_sync().
+ AvrDude& on_run(RunFn fn);
+
+ // Set message output callback
+ AvrDude& on_message(MessageFn fn);
+
+ // Set progress report callback
+ // Progress is reported per each task (reading / writing) in percents.
+ AvrDude& on_progress(ProgressFn fn);
+
+ // Called when the last avrdude invocation finishes with the exit status of zero,
+ // or earlier, if one of the invocations return a non-zero status.
+ // The second argument contains the sequential id of the last avrdude invocation argument set.
+ // This has no effect when using run_sync().
+ AvrDude& on_complete(CompleteFn fn);
+
+ // Perform AvrDude invocation(s) synchronously on the current thread
+ int run_sync();
+
+ // Perform AvrDude invocation(s) on a background thread.
+ // Current instance is moved into a shared_ptr which is returned (and also passed in on_run, if any).
+ Ptr run();
+
+ // Cancel current operation
+ void cancel();
+
+ // If there is a background thread and it is joinable, join() it,
+ // that is, wait for it to finish.
+ void join();
+
+ bool cancelled(); // Whether avrdude run was cancelled
+ int exit_code(); // The exit code of the last invocation
+ size_t last_args_set(); // Index of the last argument set that was processsed
+private:
+ struct priv;
+ std::unique_ptr<priv> p;
+};
+
+
+}
+
+#endif
diff --git a/xs/src/avrdude/avrdude.1 b/xs/src/avrdude/avrdude.1
new file mode 100644
index 000000000..65fc7b1d6
--- /dev/null
+++ b/xs/src/avrdude/avrdude.1
@@ -0,0 +1,1133 @@
+.\"
+.\" avrdude - A Downloader/Uploader for AVR device programmers
+.\" Copyright (C) 2001, 2002, 2003, 2005 - 2016 Joerg Wunsch
+.\"
+.\" 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$
+.\"
+.Dd DATE February 15, 2016
+.Os
+.Dt AVRDUDE 1
+.Sh NAME
+.Nm avrdude
+.Nd driver program for ``simple'' Atmel AVR MCU programmer
+.Sh SYNOPSIS
+.Nm
+.Fl p Ar partno
+.Op Fl b Ar baudrate
+.Op Fl B Ar bitclock
+.Op Fl c Ar programmer-id
+.Op Fl C Ar config-file
+.Op Fl D
+.Op Fl e
+.Oo Fl E Ar exitspec Ns
+.Op \&, Ns Ar exitspec
+.Oc
+.Op Fl F
+.Op Fl i Ar delay
+.Op Fl n logfile
+.Op Fl n
+.Op Fl O
+.Op Fl P Ar port
+.Op Fl q
+.Op Fl s
+.Op Fl t
+.Op Fl u
+.Op Fl U Ar memtype:op:filename:filefmt
+.Op Fl v
+.Op Fl x Ar extended_param
+.Op Fl V
+.Sh DESCRIPTION
+.Nm Avrdude
+is a program for downloading code and data to Atmel AVR
+microcontrollers.
+.Nm Avrdude
+supports Atmel's STK500 programmer,
+Atmel's AVRISP and AVRISP mkII devices,
+Atmel's STK600,
+Atmel's JTAG ICE (mkI, mkII and 3, the latter two also in ISP mode),
+programmers complying to AppNote AVR910 and AVR109 (including the Butterfly),
+as well as a simple hard-wired
+programmer connected directly to a
+.Xr ppi 4
+or
+.Xr parport 4
+parallel port, or to a standard serial port.
+In the simplest case, the hardware consists just of a
+cable connecting the respective AVR signal lines to the parallel port.
+.Pp
+The MCU is programmed in
+.Em serial programming mode ,
+so, for the
+.Xr ppi 4
+based programmer, the MCU signals
+.Ql /RESET ,
+.Ql SCK ,
+.Ql MISO
+and
+.Ql MOSI
+need to be connected to the parallel port. Optionally, some otherwise
+unused output pins of the parallel port can be used to supply power
+for the MCU part, so it is also possible to construct a passive
+stand-alone programming device. Some status LEDs indicating the
+current operating state of the programmer can be connected, and a
+signal is available to control a buffer/driver IC 74LS367 (or
+74HCT367). The latter can be useful to decouple the parallel port
+from the MCU when in-system programming is used.
+.Pp
+A number of equally simple bit-bang programming adapters that connect
+to a serial port are supported as well, among them the popular
+Ponyprog serial adapter, and the DASA and DASA3 adapters that used to
+be supported by uisp(1).
+Note that these adapters are meant to be attached to a physical serial
+port.
+Connecting to a serial port emulated on top of USB is likely to not
+work at all, or to work abysmally slow.
+.Pp
+If you happen to have a Linux system with at least 4 hardware GPIOs
+available (like almost all embedded Linux boards) you can do without
+any additional hardware - just connect them to the MOSI, MISO, RESET
+and SCK pins on the AVR and use the linuxgpio programmer type. It bitbangs
+the lines using the Linux sysfs GPIO interface. Of course, care should
+be taken about voltage level compatibility. Also, although not strictrly
+required, it is strongly advisable to protect the GPIO pins from
+overcurrent situations in some way. The simplest would be to just put
+some resistors in series or better yet use a 3-state buffer driver like
+the 74HC244. Have a look at http://kolev.info/avrdude-linuxgpio for a more
+detailed tutorial about using this programmer type.
+.Pp
+Atmel's STK500 programmer is also supported and connects to a serial
+port.
+Both, firmware versions 1.x and 2.x can be handled, but require a
+different programmer type specification (by now).
+Using firmware version 2, high-voltage programming is also supported,
+both parallel and serial
+(programmer types stk500pp and stk500hvsp).
+.Pp
+Wiring boards are supported, utilizing STK500 V2.x protocol, but
+a simple DTR/RTS toggle is used to set the boards into programming mode.
+The programmer type is ``wiring''.
+.Pp
+The Arduino (which is very similar to the STK500 1.x) is supported via
+its own programmer type specification ``arduino''.
+.Pp
+The BusPirate is a versatile tool that can also be used as an AVR programmer.
+A single BusPirate can be connected to up to 3 independent AVRs. See
+the section on
+.Em extended parameters
+below for details.
+.Pp
+Atmel's STK600 programmer is supported in ISP and high-voltage
+programming modes, and connects through the USB.
+For ATxmega devices, the STK600 is supported in PDI mode.
+For ATtiny4/5/9/10 devices, the STK600 and AVRISP mkII are supported in TPI mode.
+.Pp
+The simple serial programmer described in Atmel's application note
+AVR910, and the bootloader described in Atmel's application note
+AVR109 (which is also used by the AVR Butterfly evaluation board), are
+supported on a serial port.
+.Pp
+Atmel's JTAG ICE (mkI, mkII, and 3) is supported as well to up- or download memory
+areas from/to an AVR target (no support for on-chip debugging).
+For the JTAG ICE mkII, JTAG, debugWire and ISP mode are supported, provided
+it has a firmware revision of at least 4.14 (decimal).
+JTAGICE3 also supports all of JTAG, debugWIRE, and ISP mode.
+See below for the limitations of debugWire.
+For ATxmega devices, the JTAG ICE mkII is supported in PDI mode, provided it
+has a revision 1 hardware and firmware version of at least 5.37 (decimal).
+For ATxmega devices, the JTAGICE3 is supported in PDI mode.
+.Pp
+Atmel-ICE (ARM/AVR) is supported in all modes (JTAG, PDI for Xmega, debugWIRE,
+ISP).
+.Pp
+Atmel's XplainedPro boards, using the EDBG protocol (CMSIS-DAP compatible),
+are supported using the "jtag3" programmer type.
+.Pp
+Atmel's XplainedMini boards, using the mEDBG protocol,
+are also supported using the "jtag3" programmer type.
+.Pp
+The AVR Dragon is supported in all modes (ISP, JTAG, HVSP, PP, debugWire).
+When used in JTAG and debugWire mode, the AVR Dragon behaves similar to a
+JTAG ICE mkII, so all device-specific comments for that device
+will apply as well.
+When used in ISP mode, the AVR Dragon behaves similar to an
+AVRISP mkII (or JTAG ICE mkII in ISP mode), so all device-specific
+comments will apply there.
+In particular, the Dragon starts out with a rather fast ISP clock
+frequency, so the
+.Fl B Ar bitclock
+option might be required to achieve a stable ISP communication.
+For ATxmega devices, the AVR Dragon is supported in PDI mode, provided it
+has a firmware version of at least 6.11 (decimal).
+.Pp
+The avrftdi, USBasp ISP and USBtinyISP adapters are also supported, provided
+.Nm avrdude
+has been compiled with libusb support.
+USBasp ISP and USBtinyISP both feature simple firmware-only USB implementations,
+running on an ATmega8 (or ATmega88), or ATtiny2313, respectively. If libftdi has
+has been compiled in
+.Nm avrdude ,
+the avrftdi device adds support for many programmers using FTDI's 2232C/D/H
+and 4232H parts running in MPSSE mode, which hard-codes (in the chip)
+SCK to bit 1, MOSI to bit 2, and MISO to bit 3. Reset is usually bit 4.
+.Pp
+The Atmel DFU bootloader is supported in both, FLIP protocol version 1
+(AT90USB* and ATmega*U* devices), as well as version 2 (Xmega devices).
+See below for some hints about FLIP version 1 protocol behaviour.
+.Pp
+Input files can be provided, and output files can be written in
+different file formats, such as raw binary files containing the data
+to download to the chip, Intel hex format, or Motorola S-record
+format. There are a number of tools available to produce those files,
+like
+.Xr asl 1
+as a standalone assembler, or
+.Xr avr-objcopy 1
+for the final stage of the GNU toolchain for the AVR microcontroller.
+.Pp
+Provided
+.Xr libelf 3
+was present when compiling
+.Nm avrdude ,
+the input file can also be the final ELF file as produced by the linker.
+The appropriate ELF section(s) will be examined, according to the memory
+area to write to.
+.Pp
+.Nm Avrdude
+can program the EEPROM and flash ROM memory cells of supported AVR
+parts. Where supported by the serial instruction set, fuse bits and
+lock bits can be programmed as well. These are implemented within
+.Nm
+as separate memory types and can be programmed using data from a file
+(see the
+.Fl m
+option) or from terminal mode (see the
+.Ar dump
+and
+.Ar write
+commands). It is also possible to read the chip (provided it has not
+been code-protected previously, of course) and store the data in a
+file. Finally, a ``terminal'' mode is available that allows one to
+interactively communicate with the MCU, and to display or program
+individual memory cells.
+On the STK500 and STK600 programmer, several operational parameters (target supply
+voltage, target Aref voltage, master clock) can be examined and changed
+from within terminal mode as well.
+.Ss Options
+In order to control all the different operation modi, a number of options
+need to be specified to
+.Nm avrdude .
+.Bl -tag -offset indent -width indent
+.It Fl p Ar partno
+This is the only option that is mandatory for every invocation of
+.Nm avrdude .
+It specifies the type of the MCU connected to the programmer. These are read from the config file.
+For currently supported MCU types use ? as partno, this will print a list of partno ids and official part names on the terminal. (Both can be used with the -p option.)
+.Pp
+Following parts need special attention:
+.Bl -tag -width "ATmega1234"
+.It "AT90S1200"
+The ISP programming protocol of the AT90S1200 differs in subtle ways
+from that of other AVRs. Thus, not all programmers support this
+device. Known to work are all direct bitbang programmers, and all
+programmers talking the STK500v2 protocol.
+.It "AT90S2343"
+The AT90S2323 and ATtiny22 use the same algorithm.
+.It "ATmega2560, ATmega2561"
+Flash addressing above 128 KB is not supported by all
+programming hardware. Known to work are jtag2, stk500v2,
+and bit-bang programmers.
+.It "ATtiny11"
+The ATtiny11 can only be
+programmed in high-voltage serial mode.
+.El
+.It Fl b Ar baudrate
+Override the RS-232 connection baud rate specified in the respective
+programmer's entry of the configuration file.
+.It Fl B Ar bitclock
+Specify the bit clock period for the JTAG interface or the ISP clock (JTAG ICE only).
+The value is a floating-point number in microseconds.
+Alternatively, the value might be suffixed with "Hz", "kHz", or "MHz",
+in order to specify the bit clock frequency, rather than a period.
+The default value of the JTAG ICE results in about 1 microsecond bit
+clock period, suitable for target MCUs running at 4 MHz clock and
+above.
+Unlike certain parameters in the STK500, the JTAG ICE resets all its
+parameters to default values when the programming software signs
+off from the ICE, so for MCUs running at lower clock speeds, this
+parameter must be specified on the command-line.
+You can use the 'default_bitclock' keyword in your
+.Pa ${HOME}/.avrduderc
+file to assign a default value to keep from having to specify this
+option on every invocation.
+.It Fl c Ar programmer-id
+Use the programmer specified by the argument. Programmers and their pin
+configurations are read from the config file (see the
+.Fl C
+option). New pin configurations can be easily added or modified
+through the use of a config file to make
+.Nm avrdude
+work with different programmers as long as the programmer supports the
+Atmel AVR serial program method. You can use the 'default_programmer'
+keyword in your
+.Pa ${HOME}/.avrduderc
+file to assign a default programmer to keep from having to specify
+this option on every invocation.
+A full list of all supported programmers is output to the terminal
+by using ? as programmer-id.
+.It Fl C Ar config-file
+Use the specified config file to load configuration data. This file
+contains all programmer and part definitions that
+.Nm avrdude
+knows about.
+See the config file, located at
+.Pa ${PREFIX}/etc/avrdude.conf ,
+which contains a description of the format.
+.Pp
+If
+.Ar config-file
+is written as
+.Pa +filename
+then this file is read after the system wide and user configuration
+files. This can be used to add entries to the configuration
+without patching your system wide configuration file. It can be used
+several times, the files are read in same order as given on the command
+line.
+.It Fl D
+Disable auto erase for flash. When the
+.Fl U
+option with flash memory is specified,
+.Nm
+will perform a chip erase before starting any of the programming
+operations, since it generally is a mistake to program the flash
+without performing an erase first. This option disables that.
+Auto erase is not used for ATxmega devices as these devices can
+use page erase before writing each page so no explicit chip erase
+is required.
+Note however that any page not affected by the current operation
+will retain its previous contents.
+.It Fl e
+Causes a chip erase to be executed. This will reset the contents of the
+flash ROM and EEPROM to the value
+.Ql 0xff ,
+and clear all lock bits.
+Except for ATxmega devices which can use page erase,
+it is basically a prerequisite command before the flash ROM can be
+reprogrammed again. The only exception would be if the new
+contents would exclusively cause bits to be programmed from the value
+.Ql 1
+to
+.Ql 0 .
+Note that in order to reprogram EERPOM cells, no explicit prior chip
+erase is required since the MCU provides an auto-erase cycle in that
+case before programming the cell.
+.It Xo Fl E Ar exitspec Ns
+.Op \&, Ns Ar exitspec
+.Xc
+By default,
+.Nm
+leaves the parallel port in the same state at exit as it has been
+found at startup. This option modifies the state of the
+.Ql /RESET
+and
+.Ql Vcc
+lines the parallel port is left at, according to the
+.Ar exitspec
+arguments provided, as follows:
+.Bl -tag -width noreset
+.It Ar reset
+The
+.Ql /RESET
+signal will be left activated at program exit, that is it will be held
+.Em low ,
+in order to keep the MCU in reset state afterwards. Note in particular
+that the programming algorithm for the AT90S1200 device mandates that
+the
+.Ql /RESET
+signal is active
+.Em before
+powering up the MCU, so in case an external power supply is used for this
+MCU type, a previous invocation of
+.Nm
+with this option specified is one of the possible ways to guarantee this
+condition.
+.It Ar noreset
+The
+.Ql /RESET
+line will be deactivated at program exit, thus allowing the MCU target
+program to run while the programming hardware remains connected.
+.It Ar vcc
+This option will leave those parallel port pins active
+.Pq \&i. \&e. Em high
+that can be used to supply
+.Ql Vcc
+power to the MCU.
+.It Ar novcc
+This option will pull the
+.Ql Vcc
+pins of the parallel port down at program exit.
+.It Ar d_high
+This option will leave the 8 data pins on the parallel port active.
+.Pq \&i. \&e. Em high
+.It Ar d_low
+This option will leave the 8 data pins on the parallel port inactive.
+.Pq \&i. \&e. Em low
+.El
+.Pp
+Multiple
+.Ar exitspec
+arguments can be separated with commas.
+.It Fl F
+Normally,
+.Nm
+tries to verify that the device signature read from the part is
+reasonable before continuing. Since it can happen from time to time
+that a device has a broken (erased or overwritten) device signature
+but is otherwise operating normally, this options is provided to
+override the check.
+Also, for programmers like the Atmel STK500 and STK600 which can
+adjust parameters local to the programming tool (independent of an
+actual connection to a target controller), this option can be used
+together with
+.Fl t
+to continue in terminal mode.
+.It Fl i Ar delay
+For bitbang-type programmers, delay for approximately
+.Ar delay
+microseconds between each bit state change.
+If the host system is very fast, or the target runs off a slow clock
+(like a 32 kHz crystal, or the 128 kHz internal RC oscillator), this
+can become necessary to satisfy the requirement that the ISP clock
+frequency must not be higher than 1/4 of the CPU clock frequency.
+This is implemented as a spin-loop delay to allow even for very
+short delays.
+On Unix-style operating systems, the spin loop is initially calibrated
+against a system timer, so the number of microseconds might be rather
+realistic, assuming a constant system load while
+.Nm
+is running.
+On Win32 operating systems, a preconfigured number of cycles per
+microsecond is assumed that might be off a bit for very fast or very
+slow machines.
+.It Fl l Ar logfile
+Use
+.Ar logfile
+rather than
+.Va stderr
+for diagnostics output.
+Note that initial diagnostic messages (during option parsing) are still
+written to
+.Va stderr
+anyway.
+.It Fl n
+No-write - disables actually writing data to the MCU (useful for debugging
+.Nm avrdude
+).
+.It Fl O
+Perform a RC oscillator run-time calibration according to Atmel
+application note AVR053.
+This is only supported on the STK500v2, AVRISP mkII, and JTAG ICE mkII
+hardware.
+Note that the result will be stored in the EEPROM cell at address 0.
+.It Fl P Ar port
+Use
+.Ar port
+to identify the device to which the programmer is attached. By
+default the
+.Pa /dev/ppi0
+port is used, but if the programmer type normally connects to the
+serial port, the
+.Pa /dev/cuaa0
+port is the default. If you need to use a different parallel or
+serial port, use this option to specify the alternate port name.
+.Pp
+On Win32 operating systems, the parallel ports are referred to as lpt1
+through lpt3, referring to the addresses 0x378, 0x278, and 0x3BC,
+respectively. If the parallel port can be accessed through a different
+address, this address can be specified directly, using the common C
+language notation (i. e., hexadecimal values are prefixed by
+.Ql 0x
+).
+.Pp
+For the JTAG ICE mkII and JTAGICE3, if
+.Nm
+has been configured with libusb support,
+.Ar port
+can alternatively be specified as
+.Pa usb Ns Op \&: Ns Ar serialno .
+This will cause
+.Nm
+to search the programmer on USB.
+If
+.Ar serialno
+is also specified, it will be matched against the serial number read
+from any JTAG ICE mkII found on USB.
+The match is done after stripping any existing colons from the given
+serial number, and right-to-left, so only the least significant bytes
+from the serial number need to be given.
+.Pp
+As the AVRISP mkII device can only be talked to over USB, the very
+same method of specifying the port is required there.
+.Pp
+For the USB programmer "AVR-Doper" running in HID mode, the port must
+be specified as
+.Ar avrdoper.
+Libusb support is required on Unix but not on Windows. For more
+information about AVR-Doper see http://www.obdev.at/avrusb/avrdoper.html.
+.Pp
+For the USBtinyISP, which is a simplicistic device not implementing
+serial numbers, multiple devices can be distinguished by their
+location in the USB hierarchy. See the the respective
+.Em Troubleshooting
+entry in the detailed documentation for examples.
+.Pp
+For programmers that attach to a serial port using some kind of
+higher level protocol (as opposed to bit-bang style programmers),
+.Ar port
+can be specified as
+.Pa net Ns \&: Ns Ar host Ns \&: Ns Ar port .
+In this case, instead of trying to open a local device, a TCP
+network connection to (TCP)
+.Ar port
+on
+.Ar host
+is established.
+The remote endpoint is assumed to be a terminal or console server
+that connects the network stream to a local serial port where the
+actual programmer has been attached to.
+The port is assumed to be properly configured, for example using a
+transparent 8-bit data connection without parity at 115200 Baud
+for a STK500.
+.It Fl q
+Disable (or quell) output of the progress bar while reading or writing
+to the device. Specify it a second time for even quieter operation.
+.It Fl s
+Disable safemode prompting. When safemode discovers that one or more
+fuse bits have unintentionally changed, it will prompt for
+confirmation regarding whether or not it should attempt to recover the
+fuse bit(s). Specifying this flag disables the prompt and assumes
+that the fuse bit(s) should be recovered without asking for
+confirmation first.
+.It Fl t
+Tells
+.Nm
+to enter the interactive ``terminal'' mode instead of up- or downloading
+files. See below for a detailed description of the terminal mode.
+.It Fl u
+Disable the safemode fuse bit checks. Safemode is enabled by default
+and is intended to prevent unintentional fuse bit changes. When
+enabled, safemode will issue a warning if the any fuse bits are found
+to be different at program exit than they were when
+.Nm
+was invoked. Safemode won't alter fuse bits itself, but rather will
+prompt for instructions, unless the terminal is non-interactive, in
+which case safemode is disabled. See the
+.Fl s
+option to disable safemode prompting.
+.Pp
+If one of the configuration files has a line
+.Dl "default_safemode = no;"
+safemode is disabled by default.
+The
+.Fl u
+option's effect is negated in that case, i. e. it
+.Em enables
+safemode.
+.Pp
+Safemode is always disabled for AVR32, Xmega and TPI devices.
+.It Xo Fl U Ar memtype Ns
+.Ar \&: Ns Ar op Ns
+.Ar \&: Ns Ar filename Ns
+.Op \&: Ns Ar format
+.Xc
+Perform a memory operation as indicated. The
+.Ar memtype
+field specifies the memory type to operate on.
+The available memory types are device-dependent, the actual
+configuration can be viewed with the
+.Cm part
+command in terminal mode.
+Typically, a device's memory configuration at least contains
+the memory types
+.Ar flash
+and
+.Ar eeprom .
+All memory types currently known are:
+.Bl -tag -width "calibration" -compact
+.It calibration
+One or more bytes of RC oscillator calibration data.
+.It eeprom
+The EEPROM of the device.
+.It efuse
+The extended fuse byte.
+.It flash
+The flash ROM of the device.
+.It fuse
+The fuse byte in devices that have only a single fuse byte.
+.It hfuse
+The high fuse byte.
+.It lfuse
+The low fuse byte.
+.It lock
+The lock byte.
+.It signature
+The three device signature bytes (device ID).
+.It fuse Ns Em N
+The fuse bytes of ATxmega devices,
+.Em N
+is an integer number
+for each fuse supported by the device.
+.It application
+The application flash area of ATxmega devices.
+.It apptable
+The application table flash area of ATxmega devices.
+.It boot
+The boot flash area of ATxmega devices.
+.It prodsig
+The production signature (calibration) area of ATxmega devices.
+.It usersig
+The user signature area of ATxmega devices.
+.El
+.Pp
+The
+.Ar op
+field specifies what operation to perform:
+.Bl -tag -width noreset
+.It Ar r
+read device memory and write to the specified file
+.It Ar w
+read data from the specified file and write to the device memory
+.It Ar v
+read data from both the device and the specified file and perform a verify
+.El
+.Pp
+The
+.Ar filename
+field indicates the name of the file to read or write.
+The
+.Ar format
+field is optional and contains the format of the file to read or
+write.
+.Ar Format
+can be one of:
+.Bl -tag -width sss
+.It Ar i
+Intel Hex
+.It Ar s
+Motorola S-record
+.It Ar r
+raw binary; little-endian byte order, in the case of the flash ROM data
+.It Ar e
+ELF (Executable and Linkable Format)
+.It Ar m
+immediate; actual byte values specified on the command line, separated
+by commas or spaces. This is good for programming fuse bytes without
+having to create a single-byte file or enter terminal mode.
+.It Ar a
+auto detect; valid for input only, and only if the input is not
+provided at
+.Em stdin .
+.It Ar d
+decimal; this and the following formats are only valid on output.
+They generate one line of output for the respective memory section,
+forming a comma-separated list of the values.
+This can be particularly useful for subsequent processing, like for
+fuse bit settings.
+.It Ar h
+hexadecimal; each value will get the string
+.Em 0x
+prepended.
+.It Ar o
+octal; each value will get a
+.Em 0
+prepended unless it is less than 8 in which case it gets no prefix.
+.It Ar b
+binary; each value will get the string
+.Em 0b
+prepended.
+.El
+.Pp
+The default is to use auto detection for input files, and raw binary
+format for output files.
+Note that if
+.Ar filename
+contains a colon, the
+.Ar format
+field is no longer optional since the filename part following the colon
+would otherwise be misinterpreted as
+.Ar format .
+.Pp
+When reading any kind of flash memory area (including the various sub-areas
+in Xmega devices), the resulting output file will be truncated to not contain
+trailing 0xFF bytes which indicate unprogrammed (erased) memory.
+Thus, if the entire memory is unprogrammed, this will result in an output
+file that has no contents at all.
+.Pp
+As an abbreviation, the form
+.Fl U Ar filename
+is equivalent to specifying
+.Fl U Em flash:w: Ns Ar filename Ns :a .
+This will only work if
+.Ar filename
+does not have a colon in it.
+.It Fl v
+Enable verbose output.
+More
+.Fl v
+options increase verbosity level.
+.It Fl V
+Disable automatic verify check when uploading data.
+.It Fl x Ar extended_param
+Pass
+.Ar extended_param
+to the chosen programmer implementation as an extended parameter.
+The interpretation of the extended parameter depends on the
+programmer itself.
+See below for a list of programmers accepting extended parameters.
+.El
+.Ss Terminal mode
+In this mode,
+.Nm
+only initializes communication with the MCU, and then awaits user
+commands on standard input. Commands and parameters may be
+abbreviated to the shortest unambiguous form. Terminal mode provides
+a command history using
+.Xr readline 3 ,
+so previously entered command lines can be recalled and edited. The
+following commands are currently implemented:
+.Bl -tag -offset indent -width indent
+.It Ar dump memtype addr nbytes
+Read
+.Ar nbytes
+bytes from the specified memory area, and display them in the usual
+hexadecimal and ASCII form.
+.It Ar dump
+Continue dumping the memory contents for another
+.Ar nbytes
+where the previous
+.Ar dump
+command left off.
+.It Ar write memtype addr byte1 ... byteN
+Manually program the respective memory cells, starting at address
+.Ar addr ,
+using the values
+.Ar byte1
+through
+.Ar byteN .
+This feature is not implemented for bank-addressed memories such as
+the flash memory of ATMega devices.
+.It Ar erase
+Perform a chip erase.
+.It Ar send b1 b2 b3 b4
+Send raw instruction codes to the AVR device. If you need access to a
+feature of an AVR part that is not directly supported by
+.Nm ,
+this command allows you to use it, even though
+.Nm
+does not implement the command. When using direct SPI mode, up to 3 bytes
+can be omitted.
+.It Ar sig
+Display the device signature bytes.
+.It Ar spi
+Enter direct SPI mode. The
+.Em pgmled
+pin acts as slave select.
+.Em Only supported on parallel bitbang programmers.
+.It Ar part
+Display the current part settings and parameters. Includes chip
+specific information including all memory types supported by the
+device, read/write timing, etc.
+.It Ar pgm
+Return to programming mode (from direct SPI mode).
+.It Ar vtarg voltage
+Set the target's supply voltage to
+.Ar voltage
+Volts.
+.Em Only supported on the STK500 and STK600 programmer.
+.It Ar varef Oo Ar channel Oc Ar voltage
+Set the adjustable voltage source to
+.Ar voltage
+Volts.
+This voltage is normally used to drive the target's
+.Em Aref
+input on the STK500.
+On the Atmel STK600, two reference voltages are available, which
+can be selected by the optional
+.Ar channel
+argument (either 0 or 1).
+.Em Only supported on the STK500 and STK600 programmer.
+.It Ar fosc freq Ns Op M Ns \&| Ns k
+Set the master oscillator to
+.Ar freq
+Hz.
+An optional trailing letter
+.Ar \&M
+multiplies by 1E6, a trailing letter
+.Ar \&k
+by 1E3.
+.Em Only supported on the STK500 and STK600 programmer.
+.It Ar fosc off
+Turn the master oscillator off.
+.Em Only supported on the STK500 and STK600 programmer.
+.It Ar sck period
+.Em STK500 and STK600 programmer only:
+Set the SCK clock period to
+.Ar period
+microseconds.
+.Pp
+.Em JTAG ICE only:
+Set the JTAG ICE bit clock period to
+.Ar period
+microseconds.
+Note that unlike STK500 settings, this setting will be reverted to
+its default value (approximately 1 microsecond) when the programming
+software signs off from the JTAG ICE.
+This parameter can also be used on the JTAG ICE mkII, JTAGICE3, and Atmel-ICE to specify the
+ISP clock period when operating the ICE in ISP mode.
+.It Ar parms
+.Em STK500 and STK600 programmer only:
+Display the current voltage and master oscillator parameters.
+.Pp
+.Em JTAG ICE only:
+Display the current target supply voltage and JTAG bit clock rate/period.
+.It Ar verbose Op Ar level
+Change (when
+.Ar level
+is provided), or display the verbosity level.
+The initial verbosity level is controlled by the number of
+.Fl v
+options given on the commandline.
+.It Ar \&?
+.It Ar help
+Give a short on-line summary of the available commands.
+.It Ar quit
+Leave terminal mode and thus
+.Nm avrdude .
+.El
+.Ss Default Parallel port pin connections
+(these can be changed, see the
+.Fl c
+option)
+.TS
+ll.
+\fBPin number\fP \fBFunction\fP
+2-5 Vcc (optional power supply to MCU)
+7 /RESET (to MCU)
+8 SCK (to MCU)
+9 MOSI (to MCU)
+10 MISO (from MCU)
+18-25 GND
+.TE
+.Ss debugWire limitations
+The debugWire protocol is Atmel's proprietary one-wire (plus ground)
+protocol to allow an in-circuit emulation of the smaller AVR devices,
+using the
+.Ql /RESET
+line.
+DebugWire mode is initiated by activating the
+.Ql DWEN
+fuse, and then power-cycling the target.
+While this mode is mainly intended for debugging/emulation, it
+also offers limited programming capabilities.
+Effectively, the only memory areas that can be read or programmed
+in this mode are flash ROM and EEPROM.
+It is also possible to read out the signature.
+All other memory areas cannot be accessed.
+There is no
+.Em chip erase
+functionality in debugWire mode; instead, while reprogramming the
+flash ROM, each flash ROM page is erased right before updating it.
+This is done transparently by the JTAG ICE mkII (or AVR Dragon).
+The only way back from debugWire mode is to initiate a special
+sequence of commands to the JTAG ICE mkII (or AVR Dragon), so the
+debugWire mode will be temporarily disabled, and the target can
+be accessed using normal ISP programming.
+This sequence is automatically initiated by using the JTAG ICE mkII
+or AVR Dragon in ISP mode, when they detect that ISP mode cannot be
+entered.
+.Ss FLIP version 1 idiosyncrasies
+Bootloaders using the FLIP protocol version 1 experience some very
+specific behaviour.
+.Pp
+These bootloaders have no option to access memory areas other than
+Flash and EEPROM.
+.Pp
+When the bootloader is started, it enters a
+.Em security mode
+where the only acceptable access is to query the device configuration
+parameters (which are used for the signature on AVR devices).
+The only way to leave this mode is a
+.Em chip erase .
+As a chip erase is normally implied by the
+.Fl U
+option when reprogramming the flash, this peculiarity might not be
+very obvious immediately.
+.Pp
+Sometimes, a bootloader with security mode already disabled seems to
+no longer respond with sensible configuration data, but only 0xFF for
+all queries.
+As these queries are used to obtain the equivalent of a signature,
+.Nm
+can only continue in that situation by forcing the signature check
+to be overridden with the
+.Fl F
+option.
+.Pp
+A
+.Em chip erase
+might leave the EEPROM unerased, at least on some
+versions of the bootloader.
+.Ss Programmers accepting extended parameters
+.Bl -tag -offset indent -width indent
+.It Ar JTAG ICE mkII
+.It Ar JTAGICE3
+.It Ar Atmel-ICE
+.It Ar AVR Dragon
+When using the JTAG ICE mkII, JTAGICE3, Atmel-ICE or AVR Dragon in JTAG mode, the
+following extended parameter is accepted:
+.Bl -tag -offset indent -width indent
+.It Ar jtagchain=UB,UA,BB,BA
+Setup the JTAG scan chain for
+.Ar UB
+units before,
+.Ar UA
+units after,
+.Ar BB
+bits before, and
+.Ar BA
+bits after the target AVR, respectively.
+Each AVR unit within the chain shifts by 4 bits.
+Other JTAG units might require a different bit shift count.
+.El
+.It Ar AVR910
+.Bl -tag -offset indent -width indent
+.It Ar devcode=VALUE
+Override the device code selection by using
+.Ar VALUE
+as the device code.
+The programmer is not queried for the list of supported
+device codes, and the specified
+.Ar VALUE
+is not verified but used directly within the
+.Ql T
+command sent to the programmer.
+.Ar VALUE
+can be specified using the conventional number notation of the
+C programming language.
+.El
+.Bl -tag -offset indent -width indent
+.It Ar no_blockmode
+Disables the default checking for block transfer capability.
+Use
+.Ar no_blockmode
+only if your
+.Ar AVR910
+programmer creates errors during initial sequence.
+.El
+.It Ar buspirate
+.Bl -tag -offset indent -width indent
+.It Ar reset={cs,aux,aux2}
+The default setup assumes the BusPirate's CS output pin connected to
+the RESET pin on AVR side. It is however possible to have multiple AVRs
+connected to the same BP with MISO, MOSI and SCK lines common for all of them.
+In such a case one AVR should have its RESET connected to BusPirate's
+.Pa CS
+pin, second AVR's RESET connected to BusPirate's
+.Pa AUX
+pin and if your BusPirate has an
+.Pa AUX2
+pin (only available on BusPirate version v1a with firmware 3.0 or newer)
+use that to activate RESET on the third AVR.
+.Pp
+It may be a good idea to decouple the BusPirate and the AVR's SPI buses from
+each other using a 3-state bus buffer. For example 74HC125 or 74HC244 are some
+good candidates with the latches driven by the appropriate reset pin (cs,
+aux or aux2). Otherwise the SPI traffic in one active circuit may interfere
+with programming the AVR in the other design.
+.It Ar spifreq=<0..7>
+The SPI speed for the Bus Pirate's binary SPI mode:
+.Bd -literal
+0 .. 30 kHz (default)
+1 .. 125 kHz
+2 .. 250 kHz
+3 .. 1 MHz
+4 .. 2 MHz
+5 .. 2.6 MHz
+6 .. 4 MHz
+7 .. 8 MHz
+.Ed
+.It Ar rawfreq=<0..3>
+Sets the SPI speed and uses the Bus Pirate's binary "raw-wire" mode:
+.Bd -literal
+0 .. 5 kHz
+1 .. 50 kHz
+2 .. 100 kHz (Firmware v4.2+ only)
+3 .. 400 kHz (v4.2+)
+.Ed
+.Pp
+The only advantage of the "raw-wire" mode is the different SPI frequencies
+available. Paged writing is not implemented in this mode.
+.It Ar ascii
+Attempt to use ASCII mode even when the firmware supports BinMode (binary
+mode).
+BinMode is supported in firmware 2.7 and newer, older FW's either don't
+have BinMode or their BinMode is buggy. ASCII mode is slower and makes
+the above
+.Ar reset= , spifreq=
+and
+.Ar rawfreq=
+parameters unavailable. Be aware that ASCII mode is not guaranteed to work
+with newer firmware versions, and is retained only to maintain compatibility
+with older firmware versions.
+.It Ar nopagedwrite
+Firmware versions 5.10 and newer support a binary mode SPI command that enables
+whole pages to be written to AVR flash memory at once, resulting in a
+significant write speed increase. If use of this mode is not desirable for some
+reason, this option disables it.
+.It Ar nopagedread
+Newer firmware versions support in binary mode SPI command some AVR Extended
+Commands. Using the "Bulk Memory Read from Flash" results in a
+significant read speed increase. If use of this mode is not desirable for some
+reason, this option disables it.
+.It Ar cpufreq=<125..4000>
+This sets the AUX pin to output a frequency of
+.Ar n
+kHz. Connecting
+the AUX pin to the XTAL1 pin of your MCU, you can provide it a clock,
+for example when it needs an external clock because of wrong fuses settings.
+Make sure the CPU frequency is at least four times the SPI frequency.
+.It Ar serial_recv_timeout=<1...>
+This sets the serial receive timeout to the given value.
+The timeout happens every time avrdude waits for the BusPirate prompt.
+Especially in ascii mode this happens very often, so setting a smaller value
+can speed up programming a lot.
+The default value is 100ms. Using 10ms might work in most cases.
+.El
+.It Ar Wiring
+When using the Wiring programmer type, the
+following optional extended parameter is accepted:
+.Bl -tag -offset indent -width indent
+.It Ar snooze=<0..32767>
+After performing the port open phase, AVRDUDE will wait/snooze for
+.Ar snooze
+milliseconds before continuing to the protocol sync phase.
+No toggling of DTR/RTS is performed if
+.Ar snooze
+is greater than 0.
+.El
+.It Ar PICkit2
+Connection to the PICkit2 programmer:
+.Bd -literal
+(AVR) (PICkit2)
+RST - VPP/MCLR (1)
+VDD - VDD Target (2) -- possibly optional if AVR self powered
+GND - GND (3)
+MISO - PGD (4)
+SCLK - PDC (5)
+MOSI - AUX (6)
+
+.Ed
+Extended commandline parameters:
+.Bl -tag -offset indent -width indent
+.It Ar clockrate=<rate>
+Sets the SPI clocking rate in Hz (default is 100kHz). Alternately the -B or -i options can be used to set the period.
+.It Ar timeout=<usb-transaction-timeout>
+Sets the timeout for USB reads and writes in milliseconds (default is 1500 ms).
+.El
+.El
+.Sh FILES
+.Bl -tag -offset indent -width /dev/ppi0XXX
+.It Pa /dev/ppi0
+default device to be used for communication with the programming
+hardware
+.It Pa ${PREFIX}/etc/avrdude.conf
+programmer and parts configuration file
+.It Pa ${HOME}/.avrduderc
+programmer and parts configuration file (per-user overrides)
+.It Pa ~/.inputrc
+Initialization file for the
+.Xr readline 3
+library
+.It Pa ${PREFIX}/share/doc/avrdude/avrdude.pdf
+Schematic of programming hardware
+.El
+.\" .Sh EXAMPLES
+.Sh DIAGNOSTICS
+.Bd -literal
+avrdude: jtagmkII_setparm(): bad response to set parameter command: RSP_FAILED
+avrdude: jtagmkII_getsync(): ISP activation failed, trying debugWire
+avrdude: Target prepared for ISP, signed off.
+avrdude: Please restart avrdude without power-cycling the target.
+.Ed
+.Pp
+If the target AVR has been set up for debugWire mode (i. e. the
+.Em DWEN
+fuse is programmed), normal ISP connection attempts will fail as
+the
+.Em /RESET
+pin is not available.
+When using the JTAG ICE mkII in ISP mode, the message shown indicates
+that
+.Nm
+has guessed this condition, and tried to initiate a debugWire reset
+to the target.
+When successful, this will leave the target AVR in a state where it
+can respond to normal ISP communication again (until the next power
+cycle).
+Typically, the same command is going to be retried again immediately
+afterwards, and will then succeed connecting to the target using
+normal ISP communication.
+.Sh SEE ALSO
+.Xr avr-objcopy 1 ,
+.Xr ppi 4 ,
+.Xr libelf 3,
+.Xr readline 3
+.Pp
+The AVR microcontroller product description can be found at
+.Pp
+.Dl "http://www.atmel.com/products/AVR/"
+.\" .Sh HISTORY
+.Sh AUTHORS
+.Nm Avrdude
+was written by Brian S. Dean <bsd@bsdhome.com>.
+.Pp
+This man page by
+.ie t J\(:org Wunsch.
+.el Joerg Wunsch.
+.Sh BUGS
+Please report bugs via
+.Dl "http://savannah.nongnu.org/bugs/?group=avrdude" .
+.Pp
+The JTAG ICE programmers currently cannot write to the flash ROM
+one byte at a time.
+For that reason, updating the flash ROM from terminal mode does not
+work.
+.Pp
+Page-mode programming the EEPROM through JTAG (i.e. through an
+.Fl U
+option) requires a prior chip erase.
+This is an inherent feature of the way JTAG EEPROM programming works.
+This also applies to the STK500 and STK600 in parallel programming mode.
+.Pp
+The USBasp and USBtinyISP drivers do not offer any option to distinguish multiple
+devices connected simultaneously, so effectively only a single device
+is supported.
+.Pp
+The avrftdi driver allows one to select specific devices using any combination of vid,pid
+serial number (usbsn) vendor description (usbvendoror part description (usbproduct)
+as seen with lsusb or whatever tool used to view USB device information. Multiple
+devices can be on the bus at the same time. For the H parts, which have multiple MPSSE
+interfaces, the interface can also be selected. It defaults to interface 'A'.
diff --git a/xs/src/avrdude/avrdude.conf b/xs/src/avrdude/avrdude.conf
new file mode 100644
index 000000000..991a1dcee
--- /dev/null
+++ b/xs/src/avrdude/avrdude.conf
@@ -0,0 +1,14982 @@
+# $Id$ -*- text -*-
+#
+# AVRDUDE Configuration File
+#
+# This file contains configuration data used by AVRDUDE which describes
+# the programming hardware pinouts and also provides part definitions.
+# AVRDUDE's "-C" command line option specifies the location of the
+# configuration file. The "-c" option names the programmer configuration
+# which must match one of the entry's "id" parameter. The "-p" option
+# identifies which part AVRDUDE is going to be programming and must match
+# one of the parts' "id" parameter.
+#
+# DO NOT MODIFY THIS FILE. Modifications will be overwritten the next
+# time a "make install" is run. For user-specific additions, use the
+# "-C +filename" commandline option.
+#
+# Possible entry formats are:
+#
+# programmer
+# parent <id> # optional parent
+# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
+# desc = <description> ; # quoted string
+# type = <type>; # programmer type, quoted string
+# # supported programmer types can be listed by "-c ?type"
+# connection_type = parallel | serial | usb
+# baudrate = <num> ; # baudrate for avr910-programmer
+# vcc = <num1> [, <num2> ... ] ; # pin number(s)
+# buff = <num1> [, <num2> ... ] ; # pin number(s)
+# reset = <num> ; # pin number
+# sck = <num> ; # pin number
+# mosi = <num> ; # pin number
+# miso = <num> ; # pin number
+# errled = <num> ; # pin number
+# rdyled = <num> ; # pin number
+# pgmled = <num> ; # pin number
+# vfyled = <num> ; # pin number
+# usbvid = <hexnum>; # USB VID (Vendor ID)
+# usbpid = <hexnum> [, <hexnum> ...] # USB PID (Product ID) (1)
+# usbdev = <interface>; # USB interface or other device info
+# usbvendor = <vendorname>; # USB Vendor Name
+# usbproduct = <productname>; # USB Product Name
+# usbsn = <serialno>; # USB Serial Number
+#
+# To invert a bit, use = ~ <num>, the spaces are important.
+# For a pin list all pins must be inverted.
+# A single pin can be specified as usual = ~ <num>, for lists
+# specify it as follows = ~ ( <num> [, <num2> ... ] ) .
+#
+# (1) Not all programmer types can process a list of PIDs.
+# ;
+#
+# part
+# id = <id> ; # quoted string
+# desc = <description> ; # quoted string
+# has_jtag = <yes/no> ; # part has JTAG i/f
+# has_debugwire = <yes/no> ; # part has debugWire i/f
+# has_pdi = <yes/no> ; # part has PDI i/f
+# has_tpi = <yes/no> ; # part has TPI i/f
+# devicecode = <num> ; # deprecated, use stk500_devcode
+# stk500_devcode = <num> ; # numeric
+# avr910_devcode = <num> ; # numeric
+# signature = <num> <num> <num> ; # signature bytes
+# usbpid = <num> ; # DFU USB PID
+# chip_erase_delay = <num> ; # micro-seconds
+# reset = dedicated | io;
+# retry_pulse = reset | sck;
+# pgm_enable = <instruction format> ;
+# chip_erase = <instruction format> ;
+# chip_erase_delay = <num> ; # chip erase delay (us)
+# # STK500 parameters (parallel programming IO lines)
+# pagel = <num> ; # pin name in hex, i.e., 0xD7
+# bs2 = <num> ; # pin name in hex, i.e., 0xA0
+# serial = <yes/no> ; # can use serial downloading
+# parallel = <yes/no/pseudo>; # can use par. programming
+# # STK500v2 parameters, to be taken from Atmel's XML files
+# timeout = <num> ;
+# stabdelay = <num> ;
+# cmdexedelay = <num> ;
+# synchloops = <num> ;
+# bytedelay = <num> ;
+# pollvalue = <num> ;
+# pollindex = <num> ;
+# predelay = <num> ;
+# postdelay = <num> ;
+# pollmethod = <num> ;
+# mode = <num> ;
+# delay = <num> ;
+# blocksize = <num> ;
+# readsize = <num> ;
+# hvspcmdexedelay = <num> ;
+# # STK500v2 HV programming parameters, from XML
+# pp_controlstack = <num>, <num>, ...; # PP only
+# hvsp_controlstack = <num>, <num>, ...; # HVSP only
+# hventerstabdelay = <num>;
+# progmodedelay = <num>; # PP only
+# latchcycles = <num>;
+# togglevtg = <num>;
+# poweroffdelay = <num>;
+# resetdelayms = <num>;
+# resetdelayus = <num>;
+# hvleavestabdelay = <num>;
+# resetdelay = <num>;
+# synchcycles = <num>; # HVSP only
+# chiperasepulsewidth = <num>; # PP only
+# chiperasepolltimeout = <num>;
+# chiperasetime = <num>; # HVSP only
+# programfusepulsewidth = <num>; # PP only
+# programfusepolltimeout = <num>;
+# programlockpulsewidth = <num>; # PP only
+# programlockpolltimeout = <num>;
+# # JTAG ICE mkII parameters, also from XML files
+# allowfullpagebitstream = <yes/no> ;
+# enablepageprogramming = <yes/no> ;
+# idr = <num> ; # IO addr of IDR (OCD) reg.
+# rampz = <num> ; # IO addr of RAMPZ reg.
+# spmcr = <num> ; # mem addr of SPMC[S]R reg.
+# eecr = <num> ; # mem addr of EECR reg.
+# # (only when != 0x3c)
+# is_at90s1200 = <yes/no> ; # AT90S1200 part
+# is_avr32 = <yes/no> ; # AVR32 part
+#
+# memory <memtype>
+# paged = <yes/no> ; # yes / no
+# size = <num> ; # bytes
+# page_size = <num> ; # bytes
+# num_pages = <num> ; # numeric
+# min_write_delay = <num> ; # micro-seconds
+# max_write_delay = <num> ; # micro-seconds
+# readback_p1 = <num> ; # byte value
+# readback_p2 = <num> ; # byte value
+# pwroff_after_write = <yes/no> ; # yes / no
+# read = <instruction format> ;
+# write = <instruction format> ;
+# read_lo = <instruction format> ;
+# read_hi = <instruction format> ;
+# write_lo = <instruction format> ;
+# write_hi = <instruction format> ;
+# loadpage_lo = <instruction format> ;
+# loadpage_hi = <instruction format> ;
+# writepage = <instruction format> ;
+# ;
+# ;
+#
+# If any of the above parameters are not specified, the default value
+# of 0 is used for numerics or the empty string ("") for string
+# values. If a required parameter is left empty, AVRDUDE will
+# complain.
+#
+# Parts can also inherit parameters from previously defined parts
+# using the following syntax. In this case specified integer and
+# string values override parameter values from the parent part. New
+# memory definitions are added to the definitions inherited from the
+# parent.
+#
+# part parent <id> # quoted string
+# id = <id> ; # quoted string
+# <any set of other parameters from the list above>
+# ;
+#
+# NOTES:
+# * 'devicecode' is the device code used by the STK500 (see codes
+# listed below)
+# * Not all memory types will implement all instructions.
+# * AVR Fuse bits and Lock bits are implemented as a type of memory.
+# * Example memory types are:
+# "flash", "eeprom", "fuse", "lfuse" (low fuse), "hfuse" (high
+# fuse), "signature", "calibration", "lock"
+# * The memory type specified on the avrdude command line must match
+# one of the memory types defined for the specified chip.
+# * The pwroff_after_write flag causes avrdude to attempt to
+# power the device off and back on after an unsuccessful write to
+# the affected memory area if VCC programmer pins are defined. If
+# VCC pins are not defined for the programmer, a message
+# indicating that the device needs a power-cycle is printed out.
+# This flag was added to work around a problem with the
+# at90s4433/2333's; see the at90s4433 errata at:
+#
+# http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf
+#
+# INSTRUCTION FORMATS
+#
+# Instruction formats are specified as a comma seperated list of
+# string values containing information (bit specifiers) about each
+# of the 32 bits of the instruction. Bit specifiers may be one of
+# the following formats:
+#
+# '1' = the bit is always set on input as well as output
+#
+# '0' = the bit is always clear on input as well as output
+#
+# 'x' = the bit is ignored on input and output
+#
+# 'a' = the bit is an address bit, the bit-number matches this bit
+# specifier's position within the current instruction byte
+#
+# 'aN' = the bit is the Nth address bit, bit-number = N, i.e., a12
+# is address bit 12 on input, a0 is address bit 0.
+#
+# 'i' = the bit is an input data bit
+#
+# 'o' = the bit is an output data bit
+#
+# Each instruction must be composed of 32 bit specifiers. The
+# instruction specification closely follows the instruction data
+# provided in Atmel's data sheets for their parts.
+#
+# See below for some examples.
+#
+#
+# The following are STK500 part device codes to use for the
+# "devicecode" field of the part. These came from Atmel's software
+# section avr061.zip which accompanies the application note
+# AVR061 available from:
+#
+# http://www.atmel.com/dyn/resources/prod_documents/doc2525.pdf
+#
+
+#define ATTINY10 0x10 /* the _old_ one that never existed! */
+#define ATTINY11 0x11
+#define ATTINY12 0x12
+#define ATTINY15 0x13
+#define ATTINY13 0x14
+
+#define ATTINY22 0x20
+#define ATTINY26 0x21
+#define ATTINY28 0x22
+#define ATTINY2313 0x23
+
+#define AT90S1200 0x33
+
+#define AT90S2313 0x40
+#define AT90S2323 0x41
+#define AT90S2333 0x42
+#define AT90S2343 0x43
+
+#define AT90S4414 0x50
+#define AT90S4433 0x51
+#define AT90S4434 0x52
+#define ATMEGA48 0x59
+
+#define AT90S8515 0x60
+#define AT90S8535 0x61
+#define AT90C8534 0x62
+#define ATMEGA8515 0x63
+#define ATMEGA8535 0x64
+
+#define ATMEGA8 0x70
+#define ATMEGA88 0x73
+#define ATMEGA168 0x86
+
+#define ATMEGA161 0x80
+#define ATMEGA163 0x81
+#define ATMEGA16 0x82
+#define ATMEGA162 0x83
+#define ATMEGA169 0x84
+
+#define ATMEGA323 0x90
+#define ATMEGA32 0x91
+
+#define ATMEGA64 0xA0
+
+#define ATMEGA103 0xB1
+#define ATMEGA128 0xB2
+#define AT90CAN128 0xB3
+#define AT90CAN64 0xB3
+#define AT90CAN32 0xB3
+
+#define AT86RF401 0xD0
+
+#define AT89START 0xE0
+#define AT89S51 0xE0
+#define AT89S52 0xE1
+
+# The following table lists the devices in the original AVR910
+# appnote:
+# |Device |Signature | Code |
+# +-------+----------+------+
+# |tiny12 | 1E 90 05 | 0x55 |
+# |tiny15 | 1E 90 06 | 0x56 |
+# | | | |
+# | S1200 | 1E 90 01 | 0x13 |
+# | | | |
+# | S2313 | 1E 91 01 | 0x20 |
+# | S2323 | 1E 91 02 | 0x48 |
+# | S2333 | 1E 91 05 | 0x34 |
+# | S2343 | 1E 91 03 | 0x4C |
+# | | | |
+# | S4414 | 1E 92 01 | 0x28 |
+# | S4433 | 1E 92 03 | 0x30 |
+# | S4434 | 1E 92 02 | 0x6C |
+# | | | |
+# | S8515 | 1E 93 01 | 0x38 |
+# | S8535 | 1E 93 03 | 0x68 |
+# | | | |
+# |mega32 | 1E 95 01 | 0x72 |
+# |mega83 | 1E 93 05 | 0x65 |
+# |mega103| 1E 97 01 | 0x41 |
+# |mega161| 1E 94 01 | 0x60 |
+# |mega163| 1E 94 02 | 0x64 |
+
+# Appnote AVR109 also has a table of AVR910 device codes, which
+# lists:
+# dev avr910 signature
+# ATmega8 0x77 0x1E 0x93 0x07
+# ATmega8515 0x3B 0x1E 0x93 0x06
+# ATmega8535 0x6A 0x1E 0x93 0x08
+# ATmega16 0x75 0x1E 0x94 0x03
+# ATmega162 0x63 0x1E 0x94 0x04
+# ATmega163 0x66 0x1E 0x94 0x02
+# ATmega169 0x79 0x1E 0x94 0x05
+# ATmega32 0x7F 0x1E 0x95 0x02
+# ATmega323 0x73 0x1E 0x95 0x01
+# ATmega64 0x46 0x1E 0x96 0x02
+# ATmega128 0x44 0x1E 0x97 0x02
+#
+# These codes refer to "BOOT" device codes which are apparently
+# different than standard device codes, for whatever reasons
+# (often one above the standard code).
+
+# There are several extended versions of AVR910 implementations around
+# in the Internet. These add the following codes (only devices that
+# actually exist are listed):
+
+# ATmega8515 0x3A
+# ATmega128 0x43
+# ATmega64 0x45
+# ATtiny26 0x5E
+# ATmega8535 0x69
+# ATmega32 0x72
+# ATmega16 0x74
+# ATmega8 0x76
+# ATmega169 0x78
+
+#
+# Overall avrdude defaults; suitable for ~/.avrduderc
+#
+default_parallel = "/dev/parport0";
+default_serial = "/dev/ttyS0";
+# default_bitclock = 2.5;
+
+# Turn off safemode by default
+#default_safemode = no;
+
+
+#
+# PROGRAMMER DEFINITIONS
+#
+
+# http://wiring.org.co/
+# Basically STK500v2 protocol, with some glue to trigger the
+# bootloader.
+programmer
+ id = "wiring";
+ desc = "Wiring";
+ type = "wiring";
+ connection_type = serial;
+;
+
+programmer
+ id = "arduino";
+ desc = "Arduino";
+ type = "arduino";
+ connection_type = serial;
+;
+# this will interface with the chips on these programmers:
+#
+# http://real.kiev.ua/old/avreal/en/adapters
+# http://www.amontec.com/jtagkey.shtml, jtagkey-tiny.shtml
+# http://www.olimex.com/dev/arm-usb-ocd.html, arm-usb-tiny.html
+# http://www.ethernut.de/en/hardware/turtelizer/index.html
+# http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html
+# http://dangerousprototypes.com/docs/FT2232_breakout_board
+# http://www.ftdichip.com/Products/Modules/DLPModules.htm,DLP-2232*,DLP-USB1232H
+# http://flashrom.org/FT2232SPI_Programmer
+#
+# The drivers will look for a specific device and use the first one found.
+# If you have mulitple devices, then look for unique information (like SN)
+# And fill that in here.
+#
+# Note that the pin numbers for the main ISP signals (reset, sck,
+# mosi, miso) are fixed and cannot be changed, since they must match
+# the way the Multi-Protocol Synchronous Serial Engine (MPSSE) of
+# these FTDI ICs has been designed.
+
+programmer
+ id = "avrftdi";
+ desc = "FT2232D based generic programmer";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+ usbpid = 0x6010;
+ usbvendor = "";
+ usbproduct = "";
+ usbdev = "A";
+ usbsn = "";
+#ISP-signals - lower ADBUS-Nibble (default)
+ reset = 3;
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+#LED SIGNALs - higher ADBUS-Nibble
+# errled = 4;
+# rdyled = 5;
+# pgmled = 6;
+# vfyled = 7;
+#Buffer Signal - ACBUS - Nibble
+# buff = 8;
+;
+# This is an implementation of the above with a buffer IC (74AC244) and
+# 4 LEDs directly attached, all active low.
+programmer
+ id = "2232HIO";
+ desc = "FT2232H based generic programmer";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+# Note: This PID is reserved for generic H devices and
+# should be programmed into the EEPROM
+# usbpid = 0x8A48;
+ usbpid = 0x6010;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals
+ reset = 3;
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+ buff = ~4;
+#LED SIGNALs
+ errled = ~ 11;
+ rdyled = ~ 14;
+ pgmled = ~ 13;
+ vfyled = ~ 12;
+;
+
+#The FT4232H can be treated as FT2232H, but it has a different USB
+#device ID of 0x6011.
+programmer parent "avrftdi"
+ id = "4232h";
+ desc = "FT4232H based generic programmer";
+ usbpid = 0x6011;
+;
+
+programmer
+ id = "jtagkey";
+ desc = "Amontec JTAGKey, JTAGKey-Tiny and JTAGKey2";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+# Note: This PID is used in all JTAGKey variants
+ usbpid = 0xCFF8;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals => 20 - Pin connector on JTAGKey
+ reset = 3; # TMS 7 violet
+ sck = 0; # TCK 9 white
+ mosi = 1; # TDI 5 green
+ miso = 2; # TDO 13 orange
+ buff = ~4;
+# VTG VREF 1 brown with red tip
+# GND GND 20 black
+# The colors are on the 20 pin breakout cable
+# from Amontec
+;
+
+# UM232H module from FTDI and Glyn.com.au.
+# See helix.air.net.au for detailed usage information.
+# J1: Connect pin 2 and 3 for USB power.
+# J2: Connect pin 2 and 3 for USB power.
+# J2: Pin 7 is SCK
+# : Pin 8 is MOSI
+# : Pin 9 is MISO
+# : Pin 11 is RST
+# : Pin 6 is ground
+# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get
+# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant.
+programmer
+ id = "UM232H";
+ desc = "FT232H based module from FTDI and Glyn.com.au";
+ type = "avrftdi";
+ usbvid = 0x0403;
+# Note: This PID is reserved for generic 232H devices and
+# should be programmed into the EEPROM
+ usbpid = 0x6014;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+ reset = 3;
+;
+
+# C232HM module from FTDI and Glyn.com.au.
+# : Orange is SCK
+# : Yellow is MOSI
+# : Green is MISO
+# : Brown is RST
+# : Black is ground
+# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get
+# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant.
+programmer
+ id = "C232HM";
+ desc = "FT232H based module from FTDI and Glyn.com.au";
+ type = "avrftdi";
+ usbvid = 0x0403;
+# Note: This PID is reserved for generic 232H devices and
+# should be programmed into the EEPROM
+ usbpid = 0x6014;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+ reset = 3;
+;
+
+
+# On the adapter you can read "O-Link". On the PCB is printed "OpenJTAG v3.1"
+# You can find it as "OpenJTAG ARM JTAG USB" in the internet.
+# (But there are also several projects called Open JTAG, eg.
+# http://www.openjtag.org, which are completely different.)
+# http://www.100ask.net/shop/english.html (website seems to be outdated)
+# http://item.taobao.com/item.htm?id=1559277013
+# http://www.micro4you.com/store/openjtag-arm-jtag-usb.html (schematics!)
+# some other sources which call it O-Link
+# http://www.andahammer.com/olink/
+# http://www.developmentboard.net/31-o-link-debugger.html
+# http://armwerks.com/catalog/o-link-debugger-copy/
+# or just have a look at ebay ...
+# It is basically the same entry as jtagkey with different usb ids.
+programmer parent "jtagkey"
+ id = "o-link";
+ desc = "O-Link, OpenJTAG from www.100ask.net";
+ usbvid = 0x1457;
+ usbpid = 0x5118;
+ usbvendor = "www.100ask.net";
+ usbproduct = "USB<=>JTAG&RS232";
+;
+
+# http://wiki.openmoko.org/wiki/Debug_Board_v3
+programmer
+ id = "openmoko";
+ desc = "Openmoko debug board (v3)";
+ type = "avrftdi";
+ usbvid = 0x1457;
+ usbpid = 0x5118;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+ reset = 3; # TMS 7
+ sck = 0; # TCK 9
+ mosi = 1; # TDI 5
+ miso = 2; # TDO 13
+;
+
+# Only Rev. A boards.
+# Schematic and user manual: http://www.cs.put.poznan.pl/wswitala/download/pdf/811EVBK.pdf
+programmer
+ id = "lm3s811";
+ desc = "Luminary Micro LM3S811 Eval Board (Rev. A)";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+ usbpid = 0xbcd9;
+ usbvendor = "LMI";
+ usbproduct = "LM3S811 Evaluation Board";
+ usbdev = "A";
+ usbsn = "";
+#ISP-signals - lower ACBUS-Nibble (default)
+ reset = 3;
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+# Enable correct buffers
+ buff = 7;
+;
+
+# submitted as bug #46020
+programmer
+ id = "tumpa";
+ desc = "TIAO USB Multi-Protocol Adapter";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+ usbpid = 0x8A98;
+ usbdev = "A";
+ usbvendor = "TIAO";
+ usbproduct = "";
+ usbsn = "";
+ sck = 0; # TCK 9
+ mosi = 1; # TDI 5
+ miso = 2; # TDO 13
+ reset = 3; # TMS 7
+;
+
+programmer
+ id = "avrisp";
+ desc = "Atmel AVR ISP";
+ type = "stk500";
+ connection_type = serial;
+;
+
+programmer
+ id = "avrispv2";
+ desc = "Atmel AVR ISP V2";
+ type = "stk500v2";
+ connection_type = serial;
+;
+
+programmer
+ id = "avrispmkII";
+ desc = "Atmel AVR ISP mkII";
+ type = "stk500v2";
+ connection_type = usb;
+;
+
+programmer parent "avrispmkII"
+ id = "avrisp2";
+;
+
+programmer
+ id = "buspirate";
+ desc = "The Bus Pirate";
+ type = "buspirate";
+ connection_type = serial;
+;
+
+programmer
+ id = "buspirate_bb";
+ desc = "The Bus Pirate (bitbang interface, supports TPI)";
+ type = "buspirate_bb";
+ connection_type = serial;
+ # pins are bits in bitbang byte (numbers are 87654321)
+ # 1|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS
+ reset = 1;
+ sck = 3;
+ mosi = 4;
+ miso = 2;
+ #vcc = 7; This is internally set independent of this setting.
+;
+
+# This is supposed to be the "default" STK500 entry.
+# Attempts to select the correct firmware version
+# by probing for it. Better use one of the entries
+# below instead.
+programmer
+ id = "stk500";
+ desc = "Atmel STK500";
+ type = "stk500generic";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500v1";
+ desc = "Atmel STK500 Version 1.x firmware";
+ type = "stk500";
+ connection_type = serial;
+;
+
+programmer
+ id = "mib510";
+ desc = "Crossbow MIB510 programming board";
+ type = "stk500";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500v2";
+ desc = "Atmel STK500 Version 2.x firmware";
+ type = "stk500v2";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500pp";
+ desc = "Atmel STK500 V2 in parallel programming mode";
+ type = "stk500pp";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500hvsp";
+ desc = "Atmel STK500 V2 in high-voltage serial programming mode";
+ type = "stk500hvsp";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk600";
+ desc = "Atmel STK600";
+ type = "stk600";
+ connection_type = usb;
+;
+
+programmer
+ id = "stk600pp";
+ desc = "Atmel STK600 in parallel programming mode";
+ type = "stk600pp";
+ connection_type = usb;
+;
+
+programmer
+ id = "stk600hvsp";
+ desc = "Atmel STK600 in high-voltage serial programming mode";
+ type = "stk600hvsp";
+ connection_type = usb;
+;
+
+programmer
+ id = "avr910";
+ desc = "Atmel Low Cost Serial Programmer";
+ type = "avr910";
+ connection_type = serial;
+;
+
+programmer
+ id = "ft245r";
+ desc = "FT245R Synchronous BitBang";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 1; # D1
+ sck = 0; # D0
+ mosi = 2; # D2
+ reset = 4; # D4
+;
+
+programmer
+ id = "ft232r";
+ desc = "FT232R Synchronous BitBang";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 1; # RxD
+ sck = 0; # TxD
+ mosi = 2; # RTS
+ reset = 4; # DTR
+;
+
+# see http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega
+programmer
+ id = "bwmega";
+ desc = "BitWizard ftdi_atmega builtin programmer";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 5; # DSR
+ sck = 6; # DCD
+ mosi = 3; # CTS
+ reset = 7; # RI
+;
+
+# see http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html
+# Note: pins are numbered from 1!
+programmer
+ id = "arduino-ft232r";
+ desc = "Arduino: FT232R connected to ISP";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 3; # CTS X3(1)
+ sck = 5; # DSR X3(2)
+ mosi = 6; # DCD X3(3)
+ reset = 7; # RI X3(4)
+;
+
+# website mentioned above uses this id
+programmer parent "arduino-ft232r"
+ id = "diecimila";
+ desc = "alias for arduino-ft232r";
+;
+
+# There is a ATmega328P kit PCB called "uncompatino".
+# This board allows ISP via its on-board FT232R.
+# This is designed like Arduino Duemilanove but has no standard ICPS header.
+# Its 4 pairs of pins are shorted to enable ftdi_syncbb.
+# http://akizukidenshi.com/catalog/g/gP-07487/
+# http://akizukidenshi.com/download/ds/akizuki/k6096_manual_20130816.pdf
+programmer
+ id = "uncompatino";
+ desc = "uncompatino with all pairs of pins shorted";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 3; # cts
+ sck = 5; # dsr
+ mosi = 6; # dcd
+ reset = 7; # ri
+;
+
+# FTDI USB to serial cable TTL-232R-5V with a custom adapter for ICSP
+# http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm
+# http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232R_CABLES.pdf
+# For ICSP pinout see for example http://www.atmel.com/images/doc2562.pdf
+# (Figure 1. ISP6PIN header pinout and Table 1. Connections required for ISP ...)
+# TTL-232R GND 1 Black -> ICPS GND (pin 6)
+# TTL-232R CTS 2 Brown -> ICPS MOSI (pin 4)
+# TTL-232R VCC 3 Red -> ICPS VCC (pin 2)
+# TTL-232R TXD 4 Orange -> ICPS RESET (pin 5)
+# TTL-232R RXD 5 Yellow -> ICPS SCK (pin 3)
+# TTL-232R RTS 6 Green -> ICPS MISO (pin 1)
+# Except for VCC and GND, you can connect arbitual pairs as long as
+# the following table is adjusted.
+programmer
+ id = "ttl232r";
+ desc = "FTDI TTL232R-5V with ICSP adapter";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 2; # rts
+ sck = 1; # rxd
+ mosi = 3; # cts
+ reset = 0; # txd
+;
+
+programmer
+ id = "usbasp";
+ desc = "USBasp, http://www.fischl.de/usbasp/";
+ type = "usbasp";
+ connection_type = usb;
+ usbvid = 0x16C0; # VOTI
+ usbpid = 0x05DC; # Obdev's free shared PID
+ usbvendor = "www.fischl.de";
+ usbproduct = "USBasp";
+
+ # following variants are autodetected for id "usbasp"
+
+ # original usbasp from fischl.de
+ # see above "usbasp"
+
+ # old usbasp from fischl.de
+ #usbvid = 0x03EB; # ATMEL
+ #usbpid = 0xC7B4; # (unoffical) USBasp
+ #usbvendor = "www.fischl.de";
+ #usbproduct = "USBasp";
+
+ # NIBObee (only if -P nibobee is given on command line)
+ # see below "nibobee"
+;
+
+programmer
+ id = "nibobee";
+ desc = "NIBObee";
+ type = "usbasp";
+ connection_type = usb;
+ usbvid = 0x16C0; # VOTI
+ usbpid = 0x092F; # NIBObee PID
+ usbvendor = "www.nicai-systems.com";
+ usbproduct = "NIBObee";
+;
+
+programmer
+ id = "usbasp-clone";
+ desc = "Any usbasp clone with correct VID/PID";
+ type = "usbasp";
+ connection_type = usb;
+ usbvid = 0x16C0; # VOTI
+ usbpid = 0x05DC; # Obdev's free shared PID
+ #usbvendor = "";
+ #usbproduct = "";
+;
+
+programmer
+ id = "usbtiny";
+ desc = "USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/";
+ type = "usbtiny";
+ connection_type = usb;
+ usbvid = 0x1781;
+ usbpid = 0x0c9f;
+;
+
+# commercial version of USBtiny, using a separate VID/PID
+programmer
+ id = "ehajo-isp";
+ desc = "avr-isp-programmer from eHaJo, http://www.eHaJo.de";
+ type = "usbtiny";
+ connection_type = usb;
+ usbvid = 0x16D0;
+ usbpid = 0x0BA5;
+;
+
+programmer
+ id = "butterfly";
+ desc = "Atmel Butterfly Development Board";
+ type = "butterfly";
+ connection_type = serial;
+;
+
+programmer
+ id = "avr109";
+ desc = "Atmel AppNote AVR109 Boot Loader";
+ type = "butterfly";
+ connection_type = serial;
+;
+
+programmer
+ id = "avr911";
+ desc = "Atmel AppNote AVR911 AVROSP";
+ type = "butterfly";
+ connection_type = serial;
+;
+
+# suggested in http://forum.mikrokopter.de/topic-post48317.html
+programmer
+ id = "mkbutterfly";
+ desc = "Mikrokopter.de Butterfly";
+ type = "butterfly_mk";
+ connection_type = serial;
+;
+
+programmer parent "mkbutterfly"
+ id = "butterfly_mk";
+;
+
+programmer
+ id = "jtagmkI";
+ desc = "Atmel JTAG ICE (mkI)";
+ baudrate = 115200; # default is 115200
+ type = "jtagmki";
+ connection_type = serial;
+;
+
+# easier to type
+programmer parent "jtagmkI"
+ id = "jtag1";
+;
+
+# easier to type
+programmer parent "jtag1"
+ id = "jtag1slow";
+ baudrate = 19200;
+;
+
+# The JTAG ICE mkII has both, serial and USB connectivity. As it is
+# mostly used through USB these days (AVR Studio 5 only supporting it
+# that way), we make connection_type = usb the default. Users are
+# still free to use a serial port with the -P option.
+
+programmer
+ id = "jtagmkII";
+ desc = "Atmel JTAG ICE mkII";
+ baudrate = 19200; # default is 19200
+ type = "jtagmkii";
+ connection_type = usb;
+;
+
+# easier to type
+programmer parent "jtagmkII"
+ id = "jtag2slow";
+;
+
+# JTAG ICE mkII @ 115200 Bd
+programmer parent "jtag2slow"
+ id = "jtag2fast";
+ baudrate = 115200;
+;
+
+# make the fast one the default, people will love that
+programmer parent "jtag2fast"
+ id = "jtag2";
+;
+
+# JTAG ICE mkII in ISP mode
+programmer
+ id = "jtag2isp";
+ desc = "Atmel JTAG ICE mkII in ISP mode";
+ baudrate = 115200;
+ type = "jtagmkii_isp";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in debugWire mode
+programmer
+ id = "jtag2dw";
+ desc = "Atmel JTAG ICE mkII in debugWire mode";
+ baudrate = 115200;
+ type = "jtagmkii_dw";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in AVR32 mode
+programmer
+ id = "jtagmkII_avr32";
+ desc = "Atmel JTAG ICE mkII im AVR32 mode";
+ baudrate = 115200;
+ type = "jtagmkii_avr32";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in AVR32 mode
+programmer
+ id = "jtag2avr32";
+ desc = "Atmel JTAG ICE mkII im AVR32 mode";
+ baudrate = 115200;
+ type = "jtagmkii_avr32";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in PDI mode
+programmer
+ id = "jtag2pdi";
+ desc = "Atmel JTAG ICE mkII PDI mode";
+ baudrate = 115200;
+ type = "jtagmkii_pdi";
+ connection_type = usb;
+;
+
+# AVR Dragon in JTAG mode
+programmer
+ id = "dragon_jtag";
+ desc = "Atmel AVR Dragon in JTAG mode";
+ baudrate = 115200;
+ type = "dragon_jtag";
+ connection_type = usb;
+;
+
+# AVR Dragon in ISP mode
+programmer
+ id = "dragon_isp";
+ desc = "Atmel AVR Dragon in ISP mode";
+ baudrate = 115200;
+ type = "dragon_isp";
+ connection_type = usb;
+;
+
+# AVR Dragon in PP mode
+programmer
+ id = "dragon_pp";
+ desc = "Atmel AVR Dragon in PP mode";
+ baudrate = 115200;
+ type = "dragon_pp";
+ connection_type = usb;
+;
+
+# AVR Dragon in HVSP mode
+programmer
+ id = "dragon_hvsp";
+ desc = "Atmel AVR Dragon in HVSP mode";
+ baudrate = 115200;
+ type = "dragon_hvsp";
+ connection_type = usb;
+;
+
+# AVR Dragon in debugWire mode
+programmer
+ id = "dragon_dw";
+ desc = "Atmel AVR Dragon in debugWire mode";
+ baudrate = 115200;
+ type = "dragon_dw";
+ connection_type = usb;
+;
+
+# AVR Dragon in PDI mode
+programmer
+ id = "dragon_pdi";
+ desc = "Atmel AVR Dragon in PDI mode";
+ baudrate = 115200;
+ type = "dragon_pdi";
+ connection_type = usb;
+;
+
+programmer
+ id = "jtag3";
+ desc = "Atmel AVR JTAGICE3 in JTAG mode";
+ type = "jtagice3";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "jtag3pdi";
+ desc = "Atmel AVR JTAGICE3 in PDI mode";
+ type = "jtagice3_pdi";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "jtag3dw";
+ desc = "Atmel AVR JTAGICE3 in debugWIRE mode";
+ type = "jtagice3_dw";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "jtag3isp";
+ desc = "Atmel AVR JTAGICE3 in ISP mode";
+ type = "jtagice3_isp";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "xplainedpro";
+ desc = "Atmel AVR XplainedPro in JTAG mode";
+ type = "jtagice3";
+ connection_type = usb;
+ usbpid = 0x2111;
+;
+
+programmer
+ id = "xplainedmini";
+ desc = "Atmel AVR XplainedMini in ISP mode";
+ type = "jtagice3_isp";
+ connection_type = usb;
+ usbpid = 0x2145;
+;
+
+programmer
+ id = "xplainedmini_dw";
+ desc = "Atmel AVR XplainedMini in debugWIRE mode";
+ type = "jtagice3_dw";
+ connection_type = usb;
+ usbpid = 0x2145;
+;
+
+programmer
+ id = "atmelice";
+ desc = "Atmel-ICE (ARM/AVR) in JTAG mode";
+ type = "jtagice3";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+programmer
+ id = "atmelice_pdi";
+ desc = "Atmel-ICE (ARM/AVR) in PDI mode";
+ type = "jtagice3_pdi";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+programmer
+ id = "atmelice_dw";
+ desc = "Atmel-ICE (ARM/AVR) in debugWIRE mode";
+ type = "jtagice3_dw";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+programmer
+ id = "atmelice_isp";
+ desc = "Atmel-ICE (ARM/AVR) in ISP mode";
+ type = "jtagice3_isp";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+
+programmer
+ id = "pavr";
+ desc = "Jason Kyle's pAVR Serial Programmer";
+ type = "avr910";
+ connection_type = serial;
+;
+
+programmer
+ id = "pickit2";
+ desc = "MicroChip's PICkit2 Programmer";
+ type = "pickit2";
+ connection_type = usb;
+;
+
+programmer
+ id = "flip1";
+ desc = "FLIP USB DFU protocol version 1 (doc7618)";
+ type = "flip1";
+ connection_type = usb;
+;
+
+programmer
+ id = "flip2";
+ desc = "FLIP USB DFU protocol version 2 (AVR4023)";
+ type = "flip2";
+ connection_type = usb;
+;
+
+# Parallel port programmers.
+
+programmer
+ id = "bsd";
+ desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/";
+ type = "par";
+ connection_type = parallel;
+ vcc = 2, 3, 4, 5;
+ reset = 7;
+ sck = 8;
+ mosi = 9;
+ miso = 10;
+;
+
+programmer
+ id = "stk200";
+ desc = "STK200";
+ type = "par";
+ connection_type = parallel;
+ buff = 4, 5;
+ sck = 6;
+ mosi = 7;
+ reset = 9;
+ miso = 10;
+;
+
+# The programming dongle used by the popular Ponyprog
+# utility. It is almost similar to the STK200 one,
+# except that there is a LED indicating that the
+# programming is currently in progress.
+
+programmer parent "stk200"
+ id = "pony-stk200";
+ desc = "Pony Prog STK200";
+ pgmled = 8;
+;
+
+programmer
+ id = "dt006";
+ desc = "Dontronics DT006";
+ type = "par";
+ connection_type = parallel;
+ reset = 4;
+ sck = 5;
+ mosi = 2;
+ miso = 11;
+;
+
+programmer parent "dt006"
+ id = "bascom";
+ desc = "Bascom SAMPLE programming cable";
+;
+
+programmer
+ id = "alf";
+ desc = "Nightshade ALF-PgmAVR, http://nightshade.homeip.net/";
+ type = "par";
+ connection_type = parallel;
+ vcc = 2, 3, 4, 5;
+ buff = 6;
+ reset = 7;
+ sck = 8;
+ mosi = 9;
+ miso = 10;
+ errled = 1;
+ rdyled = 14;
+ pgmled = 16;
+ vfyled = 17;
+;
+
+programmer
+ id = "sp12";
+ desc = "Steve Bolt's Programmer";
+ type = "par";
+ connection_type = parallel;
+ vcc = 4,5,6,7,8;
+ reset = 3;
+ sck = 2;
+ mosi = 9;
+ miso = 11;
+;
+
+programmer
+ id = "picoweb";
+ desc = "Picoweb Programming Cable, http://www.picoweb.net/";
+ type = "par";
+ connection_type = parallel;
+ reset = 2;
+ sck = 3;
+ mosi = 4;
+ miso = 13;
+;
+
+programmer
+ id = "abcmini";
+ desc = "ABCmini Board, aka Dick Smith HOTCHIP";
+ type = "par";
+ connection_type = parallel;
+ reset = 4;
+ sck = 3;
+ mosi = 2;
+ miso = 10;
+;
+
+programmer
+ id = "futurlec";
+ desc = "Futurlec.com programming cable.";
+ type = "par";
+ connection_type = parallel;
+ reset = 3;
+ sck = 2;
+ mosi = 1;
+ miso = 10;
+;
+
+
+# From the contributor of the "xil" jtag cable:
+# The "vcc" definition isn't really vcc (the cable gets its power from
+# the programming circuit) but is necessary to switch one of the
+# buffer lines (trying to add it to the "buff" lines doesn't work in
+# avrdude versions before 5.5j).
+# With this, TMS connects to RESET, TDI to MOSI, TDO to MISO and TCK
+# to SCK (plus vcc/gnd of course)
+programmer
+ id = "xil";
+ desc = "Xilinx JTAG cable";
+ type = "par";
+ connection_type = parallel;
+ mosi = 2;
+ sck = 3;
+ reset = 4;
+ buff = 5;
+ miso = 13;
+ vcc = 6;
+;
+
+
+programmer
+ id = "dapa";
+ desc = "Direct AVR Parallel Access cable";
+ type = "par";
+ connection_type = parallel;
+ vcc = 3;
+ reset = 16;
+ sck = 1;
+ mosi = 2;
+ miso = 11;
+;
+
+programmer
+ id = "atisp";
+ desc = "AT-ISP V1.1 programming cable for AVR-SDK1 from <http://micro-research.co.th/> micro-research.co.th";
+ type = "par";
+ connection_type = parallel;
+ reset = ~6;
+ sck = ~8;
+ mosi = ~7;
+ miso = ~10;
+;
+
+programmer
+ id = "ere-isp-avr";
+ desc = "ERE ISP-AVR <http://www.ere.co.th/download/sch050713.pdf>";
+ type = "par";
+ connection_type = parallel;
+ reset = ~4;
+ sck = 3;
+ mosi = 2;
+ miso = 10;
+;
+
+programmer
+ id = "blaster";
+ desc = "Altera ByteBlaster";
+ type = "par";
+ connection_type = parallel;
+ sck = 2;
+ miso = 11;
+ reset = 3;
+ mosi = 8;
+ buff = 14;
+;
+
+# It is almost same as pony-stk200, except vcc on pin 5 to auto
+# disconnect port (download on http://electropol.free.fr/spip/spip.php?article27)
+programmer parent "pony-stk200"
+ id = "frank-stk200";
+ desc = "Frank STK200";
+ buff = ; # delete buff pin assignment
+ vcc = 5;
+;
+
+# The AT98ISP Cable is a simple parallel dongle for AT89 family.
+# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2877
+programmer
+ id = "89isp";
+ desc = "Atmel at89isp cable";
+ type = "par";
+ connection_type = parallel;
+ reset = 17;
+ sck = 1;
+ mosi = 2;
+ miso = 10;
+;
+
+
+#This programmer bitbangs GPIO lines using the Linux sysfs GPIO interface
+#
+#To enable it set the configuration below to match the GPIO lines connected to the
+#relevant ISP header pins and uncomment the entry definition. In case you don't
+#have the required permissions to edit this system wide config file put the
+#entry in a separate <your name>.conf file and use it with -C+<your name>.conf
+#on the command line.
+#
+#To check if your avrdude build has support for the linuxgpio programmer compiled in,
+#use -c?type on the command line and look for linuxgpio in the list. If it's not available
+#you need pass the --enable-linuxgpio=yes option to configure and recompile avrdude.
+#
+#programmer
+# id = "linuxgpio";
+# desc = "Use the Linux sysfs interface to bitbang GPIO lines";
+# type = "linuxgpio";
+# reset = ?;
+# sck = ?;
+# mosi = ?;
+# miso = ?;
+#;
+
+# some ultra cheap programmers use bitbanging on the
+# serialport.
+#
+# PC - DB9 - Pins for RS232:
+#
+# GND 5 -- |O
+# | O| <- 9 RI
+# DTR 4 <- |O |
+# | O| <- 8 CTS
+# TXD 3 <- |O |
+# | O| -> 7 RTS
+# RXD 2 -> |O |
+# | O| <- 6 DSR
+# DCD 1 -> |O
+#
+# Using RXD is currently not supported.
+# Using RI is not supported under Win32 but is supported under Posix.
+
+# serial ponyprog design (dasa2 in uisp)
+# reset=!txd sck=rts mosi=dtr miso=cts
+
+programmer
+ id = "ponyser";
+ desc = "design ponyprog serial, reset=!txd sck=rts mosi=dtr miso=cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = ~3;
+ sck = 7;
+ mosi = 4;
+ miso = 8;
+;
+
+# Same as above, different name
+# reset=!txd sck=rts mosi=dtr miso=cts
+
+programmer parent "ponyser"
+ id = "siprog";
+ desc = "Lancos SI-Prog <http://www.lancos.com/siprogsch.html>";
+;
+
+# unknown (dasa in uisp)
+# reset=rts sck=dtr mosi=txd miso=cts
+
+programmer
+ id = "dasa";
+ desc = "serial port banging, reset=rts sck=dtr mosi=txd miso=cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = 7;
+ sck = 4;
+ mosi = 3;
+ miso = 8;
+;
+
+# unknown (dasa3 in uisp)
+# reset=!dtr sck=rts mosi=txd miso=cts
+
+programmer
+ id = "dasa3";
+ desc = "serial port banging, reset=!dtr sck=rts mosi=txd miso=cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = ~4;
+ sck = 7;
+ mosi = 3;
+ miso = 8;
+;
+
+# C2N232i (jumper configuration "auto")
+# reset=dtr sck=!rts mosi=!txd miso=!cts
+
+programmer
+ id = "c2n232i";
+ desc = "serial port banging, reset=dtr sck=!rts mosi=!txd miso=!cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = 4;
+ sck = ~7;
+ mosi = ~3;
+ miso = ~8;
+;
+
+#
+# PART DEFINITIONS
+#
+
+#------------------------------------------------------------
+# ATtiny11
+#------------------------------------------------------------
+
+# This is an HVSP-only device.
+
+part
+ id = "t11";
+ desc = "ATtiny11";
+ stk500_devcode = 0x11;
+ signature = 0x1e 0x90 0x04;
+ chip_erase_delay = 20000;
+
+ timeout = 200;
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 64;
+ blocksize = 64;
+ readsize = 256;
+ delay = 5;
+ ;
+
+ memory "flash"
+ size = 1024;
+ blocksize = 128;
+ readsize = 256;
+ delay = 3;
+ ;
+
+ memory "signature"
+ size = 3;
+ ;
+
+ memory "lock"
+ size = 1;
+ ;
+
+ memory "calibration"
+ size = 1;
+ ;
+
+ memory "fuse"
+ size = 1;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny12
+#------------------------------------------------------------
+
+part
+ id = "t12";
+ desc = "ATtiny12";
+ stk500_devcode = 0x12;
+ avr910_devcode = 0x55;
+ signature = 0x1e 0x90 0x05;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 8;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4500;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 5;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny13
+#------------------------------------------------------------
+
+part
+ id = "t13";
+ desc = "ATtiny13";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x0E, 0x1E;
+ eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x0E, 0xB4, 0x0E, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x14;
+ signature = 0x1e 0x90 0x07;
+ chip_erase_delay = 4000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 90;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 0;
+
+ memory "eeprom"
+ size = 64;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 5;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 1024;
+ page_size = 32;
+ num_pages = 32;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny15
+#------------------------------------------------------------
+
+part
+ id = "t15";
+ desc = "ATtiny15";
+ stk500_devcode = 0x13;
+ avr910_devcode = 0x56;
+ signature = 0x1e 0x90 0x06;
+ chip_erase_delay = 8200;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 5;
+ synchcycles = 6;
+ latchcycles = 16;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 8200;
+ max_write_delay = 8200;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4100;
+ max_write_delay = 4100;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 5;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o o x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x i i i i 1 1 i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+;
+
+#------------------------------------------------------------
+# AT90s1200
+#------------------------------------------------------------
+
+part
+ id = "1200";
+ desc = "AT90S1200";
+ is_at90s1200 = yes;
+ stk500_devcode = 0x33;
+ avr910_devcode = 0x13;
+ signature = 0x1e 0x90 0x01;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 1;
+ bytedelay = 0;
+ pollindex = 0;
+ pollvalue = 0xFF;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 32;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x02;
+ delay = 15;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s4414
+#------------------------------------------------------------
+
+part
+ id = "4414";
+ desc = "AT90S4414";
+ stk500_devcode = 0x50;
+ avr910_devcode = 0x28;
+ signature = 0x1e 0x92 0x01;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s2313
+#------------------------------------------------------------
+
+part
+ id = "2313";
+ desc = "AT90S2313";
+ stk500_devcode = 0x40;
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x91 0x01;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 2048;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x i i x",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s2333
+#------------------------------------------------------------
+
+part
+ id = "2333";
+##### WARNING: No XML file for device 'AT90S2333'! #####
+ desc = "AT90S2333";
+ stk500_devcode = 0x42;
+ avr910_devcode = 0x34;
+ signature = 0x1e 0x91 0x05;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ pwroff_after_write = yes;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# AT90s2343 (also AT90s2323 and ATtiny22)
+#------------------------------------------------------------
+
+part
+ id = "2343";
+ desc = "AT90S2343";
+ stk500_devcode = 0x43;
+ avr910_devcode = 0x4c;
+ signature = 0x1e 0x91 0x03;
+ chip_erase_delay = 18000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 0;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 128;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o x x x x o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o x x x x o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# AT90s4433
+#------------------------------------------------------------
+
+part
+ id = "4433";
+ desc = "AT90S4433";
+ stk500_devcode = 0x51;
+ avr910_devcode = 0x30;
+ signature = 0x1e 0x92 0x03;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ pwroff_after_write = yes;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s4434
+#------------------------------------------------------------
+
+part
+ id = "4434";
+##### WARNING: No XML file for device 'AT90S4434'! #####
+ desc = "AT90S4434";
+ stk500_devcode = 0x52;
+ avr910_devcode = 0x6c;
+ signature = 0x1e 0x92 0x02;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s8515
+#------------------------------------------------------------
+
+part
+ id = "8515";
+ desc = "AT90S8515";
+ stk500_devcode = 0x60;
+ avr910_devcode = 0x38;
+ signature = 0x1e 0x93 0x01;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 8192;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s8535
+#------------------------------------------------------------
+
+part
+ id = "8535";
+ desc = "AT90S8535";
+ stk500_devcode = 0x61;
+ avr910_devcode = 0x68;
+ signature = 0x1e 0x93 0x03;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 8192;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x x o";
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o x x x x x x";
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega103
+#------------------------------------------------------------
+
+part
+ id = "m103";
+ desc = "ATmega103";
+ stk500_devcode = 0xB1;
+ avr910_devcode = 0x41;
+ signature = 0x1e 0x97 0x01;
+ chip_erase_delay = 112000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x8E, 0x9E, 0x2E, 0x3E, 0xAE, 0xBE,
+ 0x4E, 0x5E, 0xCE, 0xDE, 0x6E, 0x7E, 0xEE, 0xDE,
+ 0x66, 0x76, 0xE6, 0xF6, 0x6A, 0x7A, 0xEA, 0x7A,
+ 0x7F, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 10;
+
+ memory "eeprom"
+ size = 4096;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 22000;
+ max_write_delay = 56000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x11;
+ delay = 70;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o x o 1 o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 i 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega64
+#------------------------------------------------------------
+
+part
+ id = "m64";
+ desc = "ATmega64";
+ has_jtag = yes;
+ stk500_devcode = 0xA0;
+ avr910_devcode = 0x45;
+ signature = 0x1e 0x96 0x02;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x22;
+ spmcr = 0x68;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+
+#------------------------------------------------------------
+# ATmega128
+#------------------------------------------------------------
+
+part
+ id = "m128";
+ desc = "ATmega128";
+ has_jtag = yes;
+ stk500_devcode = 0xB2;
+ avr910_devcode = 0x43;
+ signature = 0x1e 0x97 0x02;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x22;
+ spmcr = 0x68;
+ rampz = 0x3b;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90CAN128
+#------------------------------------------------------------
+
+part
+ id = "c128";
+ desc = "AT90CAN128";
+ has_jtag = yes;
+ stk500_devcode = 0xB3;
+# avr910_devcode = 0x43;
+ signature = 0x1e 0x97 0x81;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ eecr = 0x3f;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90CAN64
+#------------------------------------------------------------
+
+part
+ id = "c64";
+ desc = "AT90CAN64";
+ has_jtag = yes;
+ stk500_devcode = 0xB3;
+# avr910_devcode = 0x43;
+ signature = 0x1e 0x96 0x81;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ eecr = 0x3f;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90CAN32
+#------------------------------------------------------------
+
+part
+ id = "c32";
+ desc = "AT90CAN32";
+ has_jtag = yes;
+ stk500_devcode = 0xB3;
+# avr910_devcode = 0x43;
+ signature = 0x1e 0x95 0x81;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ eecr = 0x3f;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 256;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega16
+#------------------------------------------------------------
+
+part
+ id = "m16";
+ desc = "ATmega16";
+ has_jtag = yes;
+ stk500_devcode = 0x82;
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x94 0x03;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 100;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "calibration"
+ size = 4;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega164P
+#------------------------------------------------------------
+
+# close to ATmega16
+
+part parent "m16"
+ id = "m164p";
+ desc = "ATmega164P";
+ signature = 0x1e 0x94 0x0a;
+
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ allowfullpagebitstream = no;
+ chip_erase_delay = 55000;
+
+ ocdrev = 3;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega324P
+#------------------------------------------------------------
+
+# similar to ATmega164P
+
+part
+ id = "m324p";
+ desc = "ATmega324P";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x95 0x08;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega324PA
+#------------------------------------------------------------
+
+# similar to ATmega324P
+
+part parent "m324p"
+ id = "m324pa";
+ desc = "ATmega324PA";
+ signature = 0x1e 0x95 0x11;
+
+ ocdrev = 3;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega644
+#------------------------------------------------------------
+
+# similar to ATmega164
+
+part
+ id = "m644";
+ desc = "ATmega644";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x96 0x09;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega644P
+#------------------------------------------------------------
+
+# similar to ATmega164p
+
+part parent "m644"
+ id = "m644p";
+ desc = "ATmega644P";
+ signature = 0x1e 0x96 0x0a;
+
+ ocdrev = 3;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega1284
+#------------------------------------------------------------
+
+# similar to ATmega164
+
+part
+ id = "m1284";
+ desc = "ATmega1284";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x97 0x06;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega1284P
+#------------------------------------------------------------
+
+# similar to ATmega164p
+
+part
+ id = "m1284p";
+ desc = "ATmega1284P";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x97 0x05;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega162
+#------------------------------------------------------------
+
+part
+ id = "m162";
+ desc = "ATmega162";
+ has_jtag = yes;
+ stk500_devcode = 0x83;
+ avr910_devcode = 0x63;
+ signature = 0x1e 0x94 0x04;
+ chip_erase_delay = 9000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+
+ idr = 0x04;
+ spmcr = 0x57;
+ allowfullpagebitstream = yes;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ ocdrev = 2;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+
+ read = "0 0 1 1 0 0 0 0 0 0 x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+;
+
+
+
+#------------------------------------------------------------
+# ATmega163
+#------------------------------------------------------------
+
+part
+ id = "m163";
+ desc = "ATmega163";
+ stk500_devcode = 0x81;
+ avr910_devcode = 0x64;
+ signature = 0x1e 0x94 0x02;
+ chip_erase_delay = 32000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 30;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 2;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 2;
+
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x11;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o x x o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i 1 1 i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x x x x x 1 o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x 0 x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega169
+#------------------------------------------------------------
+
+part
+ id = "m169";
+ desc = "ATmega169";
+ has_jtag = yes;
+ stk500_devcode = 0x85;
+ avr910_devcode = 0x78;
+ signature = 0x1e 0x94 0x05;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega329
+#------------------------------------------------------------
+
+part
+ id = "m329";
+ desc = "ATmega329";
+ has_jtag = yes;
+# stk500_devcode = 0x85; # no STK500 support, only STK500v2
+# avr910_devcode = 0x?; # try the ATmega169 one:
+ avr910_devcode = 0x75;
+ signature = 0x1e 0x95 0x03;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega329P
+#------------------------------------------------------------
+# Identical to ATmega329 except of the signature
+
+part parent "m329"
+ id = "m329p";
+ desc = "ATmega329P";
+ signature = 0x1e 0x95 0x0b;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega3290
+#------------------------------------------------------------
+
+# identical to ATmega329
+
+part parent "m329"
+ id = "m3290";
+ desc = "ATmega3290";
+ signature = 0x1e 0x95 0x04;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega3290P
+#------------------------------------------------------------
+
+# identical to ATmega3290 except of the signature
+
+part parent "m3290"
+ id = "m3290p";
+ desc = "ATmega3290P";
+ signature = 0x1e 0x95 0x0c;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega649
+#------------------------------------------------------------
+
+part
+ id = "m649";
+ desc = "ATmega649";
+ has_jtag = yes;
+# stk500_devcode = 0x85; # no STK500 support, only STK500v2
+# avr910_devcode = 0x?; # try the ATmega169 one:
+ avr910_devcode = 0x75;
+ signature = 0x1e 0x96 0x03;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega6490
+#------------------------------------------------------------
+
+# identical to ATmega649
+
+part parent "m649"
+ id = "m6490";
+ desc = "ATmega6490";
+ signature = 0x1e 0x96 0x04;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega32
+#------------------------------------------------------------
+
+part
+ id = "m32";
+ desc = "ATmega32";
+ has_jtag = yes;
+ stk500_devcode = 0x91;
+ avr910_devcode = 0x72;
+ signature = 0x1e 0x95 0x02;
+ chip_erase_delay = 9000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega161
+#------------------------------------------------------------
+
+part
+ id = "m161";
+ desc = "ATmega161";
+ stk500_devcode = 0x80;
+ avr910_devcode = 0x60;
+ signature = 0x1e 0x94 0x01;
+ chip_erase_delay = 28000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 30;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 2;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 2;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 3400;
+ max_write_delay = 3400;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 5;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 14000;
+ max_write_delay = 14000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 16;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "fuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x o x o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x 1 i 1 i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega8
+#------------------------------------------------------------
+
+part
+ id = "m8";
+ desc = "ATmega8";
+ stk500_devcode = 0x70;
+ avr910_devcode = 0x76;
+ signature = 0x1e 0x93 0x07;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 10000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ page_size = 4;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega8515
+#------------------------------------------------------------
+
+part
+ id = "m8515";
+ desc = "ATmega8515";
+ stk500_devcode = 0x63;
+ avr910_devcode = 0x3A;
+ signature = 0x1e 0x93 0x06;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+
+#------------------------------------------------------------
+# ATmega8535
+#------------------------------------------------------------
+
+part
+ id = "m8535";
+ desc = "ATmega8535";
+ stk500_devcode = 0x64;
+ avr910_devcode = 0x69;
+ signature = 0x1e 0x93 0x08;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATtiny26
+#------------------------------------------------------------
+
+part
+ id = "t26";
+ desc = "ATtiny26";
+ stk500_devcode = 0x21;
+ avr910_devcode = 0x5e;
+ signature = 0x1e 0x91 0x09;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 16;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x x x x i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny261
+#------------------------------------------------------------
+# Close to ATtiny26
+
+part
+ id = "t261";
+ desc = "ATtiny261";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x00, 0x10;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+# stk500_devcode = 0x21;
+# avr910_devcode = 0x5e;
+ signature = 0x1e 0x91 0x0c;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 4000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ size = 128;
+ page_size = 4;
+ num_pages = 32;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny461
+#------------------------------------------------------------
+# Close to ATtiny261
+
+part
+ id = "t461";
+ desc = "ATtiny461";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x00, 0x10;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+# stk500_devcode = 0x21;
+# avr910_devcode = 0x5e;
+ signature = 0x1e 0x92 0x08;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 4000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ size = 256;
+ page_size = 4;
+ num_pages = 64;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny861
+#------------------------------------------------------------
+# Close to ATtiny461
+
+part
+ id = "t861";
+ desc = "ATtiny861";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x00, 0x10;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+# stk500_devcode = 0x21;
+# avr910_devcode = 0x5e;
+ signature = 0x1e 0x93 0x0d;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 4000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ size = 512;
+ num_pages = 128;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny28
+#------------------------------------------------------------
+
+# This is an HVPP-only device.
+
+part
+ id = "t28";
+ desc = "ATtiny28";
+ stk500_devcode = 0x22;
+ avr910_devcode = 0x5c;
+ signature = 0x1e 0x91 0x07;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "flash"
+ size = 2048;
+ page_size = 2;
+ readsize = 256;
+ delay = 5;
+ ;
+
+ memory "signature"
+ size = 3;
+ ;
+
+ memory "lock"
+ size = 1;
+ ;
+
+ memory "calibration"
+ size = 1;
+ ;
+
+ memory "fuse"
+ size = 1;
+ ;
+;
+
+
+
+#------------------------------------------------------------
+# ATmega48
+#------------------------------------------------------------
+
+part
+ id = "m48";
+ desc = "ATmega48";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x59;
+# avr910_devcode = 0x;
+ signature = 0x1e 0x92 0x05;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 45000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 256;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega48P
+#------------------------------------------------------------
+
+part parent "m48"
+ id = "m48p";
+ desc = "ATmega48P";
+ signature = 0x1e 0x92 0x0a;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega48PB
+#------------------------------------------------------------
+
+part parent "m48"
+ id = "m48pb";
+ desc = "ATmega48PB";
+ signature = 0x1e 0x92 0x10;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega88
+#------------------------------------------------------------
+
+part
+ id = "m88";
+ desc = "ATmega88";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x73;
+# avr910_devcode = 0x;
+ signature = 0x1e 0x93 0x0a;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 512;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega88P
+#------------------------------------------------------------
+
+part parent "m88"
+ id = "m88p";
+ desc = "ATmega88P";
+ signature = 0x1e 0x93 0x0f;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega88PB
+#------------------------------------------------------------
+
+part parent "m88"
+ id = "m88pb";
+ desc = "ATmega88PB";
+ signature = 0x1e 0x93 0x16;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega168
+#------------------------------------------------------------
+
+part
+ id = "m168";
+ desc = "ATmega168";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x86;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x94 0x06;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 512;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+;
+
+#------------------------------------------------------------
+# ATmega168P
+#------------------------------------------------------------
+
+part parent "m168"
+ id = "m168p";
+ desc = "ATmega168P";
+ signature = 0x1e 0x94 0x0b;
+
+ ocdrev = 1;
+;
+
+#------------------------------------------------------------
+# ATmega168PB
+#------------------------------------------------------------
+
+part parent "m168"
+ id = "m168pb";
+ desc = "ATmega168PB";
+ signature = 0x1e 0x94 0x15;
+
+ ocdrev = 1;
+;
+
+#------------------------------------------------------------
+# ATtiny88
+#------------------------------------------------------------
+
+part
+ id = "t88";
+ desc = "ATtiny88";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x73;
+# avr910_devcode = 0x;
+ signature = 0x1e 0x93 0x11;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 64;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 64;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega328
+#------------------------------------------------------------
+
+part
+ id = "m328";
+ desc = "ATmega328";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x86;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x95 0x14;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 1024;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+;
+
+part parent "m328"
+ id = "m328p";
+ desc = "ATmega328P";
+ signature = 0x1e 0x95 0x0F;
+
+ ocdrev = 1;
+;
+
+#------------------------------------------------------------
+# ATmega32m1
+#------------------------------------------------------------
+
+part parent "m328"
+ id = "m32m1";
+ desc = "ATmega32M1";
+ # stk500_devcode = 0x;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x95 0x84;
+ bs2 = 0xe2;
+
+ memory "efuse"
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x i i i i i i";
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny2313
+#------------------------------------------------------------
+
+part
+ id = "t2313";
+ desc = "ATtiny2313";
+ has_debugwire = yes;
+ flash_instr = 0xB2, 0x0F, 0x1F;
+ eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x23;
+## Use the ATtiny26 devcode:
+ avr910_devcode = 0x5e;
+ signature = 0x1e 0x91 0x0a;
+ pagel = 0xD4;
+ bs2 = 0xD6;
+ reset = io;
+ chip_erase_delay = 9000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
+ 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
+ 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
+ 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 0;
+
+ memory "eeprom"
+ size = 128;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny2313 has Signature Bytes: 0x1E 0x91 0x0A.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+# The Tiny2313 has calibration data for both 4 MHz and 8 MHz.
+# The information in the data sheet of April/2004 is wrong, this works:
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny4313
+#------------------------------------------------------------
+
+part
+ id = "t4313";
+ desc = "ATtiny4313";
+ has_debugwire = yes;
+ flash_instr = 0xB2, 0x0F, 0x1F;
+ eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x23;
+## Use the ATtiny26 devcode:
+ avr910_devcode = 0x5e;
+ signature = 0x1e 0x92 0x0d;
+ pagel = 0xD4;
+ bs2 = 0xD6;
+ reset = io;
+ chip_erase_delay = 9000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
+ 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
+ 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
+ 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 0;
+
+ memory "eeprom"
+ size = 256;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny4313 has Signature Bytes: 0x1E 0x92 0x0D.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM2
+#------------------------------------------------------------
+
+part
+ id = "pwm2";
+ desc = "AT90PWM2";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x65;
+## avr910_devcode = ?;
+ signature = 0x1e 0x93 0x81;
+ pagel = 0xD8;
+ bs2 = 0xE2;
+ reset = io;
+ chip_erase_delay = 9000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+# AT90PWM2 has Signature Bytes: 0x1E 0x93 0x81.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM3
+#------------------------------------------------------------
+
+# Completely identical to AT90PWM2 (including the signature!)
+
+part parent "pwm2"
+ id = "pwm3";
+ desc = "AT90PWM3";
+ ;
+
+#------------------------------------------------------------
+# AT90PWM2B
+#------------------------------------------------------------
+# Same as AT90PWM2 but different signature.
+
+part parent "pwm2"
+ id = "pwm2b";
+ desc = "AT90PWM2B";
+ signature = 0x1e 0x93 0x83;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM3B
+#------------------------------------------------------------
+
+# Completely identical to AT90PWM2B (including the signature!)
+
+part parent "pwm2b"
+ id = "pwm3b";
+ desc = "AT90PWM3B";
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM316
+#------------------------------------------------------------
+
+# Similar to AT90PWM3B, but with 16 kiB flash, 512 B EEPROM, and 1024 B SRAM.
+
+part parent "pwm3b"
+ id = "pwm316";
+ desc = "AT90PWM316";
+ signature = 0x1e 0x94 0x83;
+
+ ocdrev = 1;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM216
+#------------------------------------------------------------
+# Completely identical to AT90PWM316 (including the signature!)
+
+part parent "pwm316"
+ id = "pwm216";
+ desc = "AT90PWM216";
+ ;
+
+#------------------------------------------------------------
+# ATtiny25
+#------------------------------------------------------------
+
+part
+ id = "t25";
+ desc = "ATtiny25";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x02, 0x12;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x91 0x08;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 128;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny25 has Signature Bytes: 0x1E 0x91 0x08.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny45
+#------------------------------------------------------------
+
+part
+ id = "t45";
+ desc = "ATtiny45";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x02, 0x12;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x92 0x06;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 256;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny45 has Signature Bytes: 0x1E 0x92 0x08. (Data sheet 2586C-AVR-06/05 (doc2586.pdf) indicates otherwise!)
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny85
+#------------------------------------------------------------
+
+part
+ id = "t85";
+ desc = "ATtiny85";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x02, 0x12;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x93 0x0b;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 512;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny85 has Signature Bytes: 0x1E 0x93 0x08.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega640
+#------------------------------------------------------------
+# Almost same as ATmega1280, except for different memory sizes
+
+part
+ id = "m640";
+ desc = "ATmega640";
+ signature = 0x1e 0x96 0x08;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega1280
+#------------------------------------------------------------
+
+part
+ id = "m1280";
+ desc = "ATmega1280";
+ signature = 0x1e 0x97 0x03;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega1281
+#------------------------------------------------------------
+# Identical to ATmega1280
+
+part parent "m1280"
+ id = "m1281";
+ desc = "ATmega1281";
+ signature = 0x1e 0x97 0x04;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega2560
+#------------------------------------------------------------
+
+part
+ id = "m2560";
+ desc = "ATmega2560";
+ signature = 0x1e 0x98 0x01;
+ has_jtag = yes;
+ stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 4;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 262144;
+ page_size = 256;
+ num_pages = 1024;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ load_ext_addr = " 0 1 0 0 1 1 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 a16",
+ " 0 0 0 0 0 0 0 0";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega2561
+#------------------------------------------------------------
+
+part parent "m2560"
+ id = "m2561";
+ desc = "ATmega2561";
+ signature = 0x1e 0x98 0x02;
+
+ ocdrev = 4;
+ ;
+
+#------------------------------------------------------------
+# ATmega128RFA1
+#------------------------------------------------------------
+# Identical to ATmega2561 but half the ROM
+
+part parent "m2561"
+ id = "m128rfa1";
+ desc = "ATmega128RFA1";
+ signature = 0x1e 0xa7 0x01;
+ chip_erase_delay = 55000;
+ bs2 = 0xE2;
+
+ ocdrev = 3;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 50000;
+ max_write_delay = 50000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 256;
+ readsize = 256;
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega256RFR2
+#------------------------------------------------------------
+
+part parent "m2561"
+ id = "m256rfr2";
+ desc = "ATmega256RFR2";
+ signature = 0x1e 0xa8 0x02;
+ chip_erase_delay = 18500;
+ bs2 = 0xE2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 8192;
+ min_write_delay = 13000;
+ max_write_delay = 13000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+
+ ocdrev = 4;
+ ;
+
+#------------------------------------------------------------
+# ATmega128RFR2
+#------------------------------------------------------------
+
+part parent "m128rfa1"
+ id = "m128rfr2";
+ desc = "ATmega128RFR2";
+ signature = 0x1e 0xa7 0x02;
+
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega64RFR2
+#------------------------------------------------------------
+
+part parent "m128rfa1"
+ id = "m64rfr2";
+ desc = "ATmega64RFR2";
+ signature = 0x1e 0xa6 0x02;
+
+
+ ocdrev = 3;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 50000;
+ max_write_delay = 50000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 13000;
+ max_write_delay = 13000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+
+ ;
+
+#------------------------------------------------------------
+# ATmega2564RFR2
+#------------------------------------------------------------
+
+part parent "m256rfr2"
+ id = "m2564rfr2";
+ desc = "ATmega2564RFR2";
+ signature = 0x1e 0xa8 0x03;
+ ;
+
+#------------------------------------------------------------
+# ATmega1284RFR2
+#------------------------------------------------------------
+
+part parent "m128rfr2"
+ id = "m1284rfr2";
+ desc = "ATmega1284RFR2";
+ signature = 0x1e 0xa7 0x03;
+ ;
+
+#------------------------------------------------------------
+# ATmega644RFR2
+#------------------------------------------------------------
+
+part parent "m64rfr2"
+ id = "m644rfr2";
+ desc = "ATmega644RFR2";
+ signature = 0x1e 0xa6 0x03;
+ ;
+
+#------------------------------------------------------------
+# ATtiny24
+#------------------------------------------------------------
+
+part
+ id = "t24";
+ desc = "ATtiny24";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x91 0x0b;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 70;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 128;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny24 has Signature Bytes: 0x1E 0x91 0x0B.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x x x x x x x i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny44
+#------------------------------------------------------------
+
+part
+ id = "t44";
+ desc = "ATtiny44";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x92 0x07;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 70;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 256;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny44 has Signature Bytes: 0x1E 0x92 0x07.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x x x x x x x i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny84
+#------------------------------------------------------------
+
+part
+ id = "t84";
+ desc = "ATtiny84";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x93 0x0c;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 70;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 512;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny84 has Signature Bytes: 0x1E 0x93 0x0C.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x x x x x x x i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny43U
+#------------------------------------------------------------
+
+part
+ id = "t43u";
+ desc = "ATtiny43u";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x92 0x0C;
+ reset = io;
+ chip_erase_delay = 1000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack = 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, 0x4E, 0x5E,
+ 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, 0x06, 0x16, 0x46, 0x56,
+ 0x0A, 0x1A, 0x4A, 0x5A, 0x1E, 0x7C, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 20;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+ memory "eeprom"
+ size = 64;
+ paged = yes;
+ page_size = 4;
+ num_pages = 16;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "0 0 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "0 0 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " 0 0 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 5;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+;
+
+#------------------------------------------------------------
+# ATmega32u4
+#------------------------------------------------------------
+
+part
+ id = "m32u4";
+ desc = "ATmega32U4";
+ signature = 0x1e 0x95 0x87;
+ usbpid = 0x2ff4;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB646
+#------------------------------------------------------------
+
+part
+ id = "usb646";
+ desc = "AT90USB646";
+ signature = 0x1e 0x96 0x82;
+ usbpid = 0x2ff9;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB647
+#------------------------------------------------------------
+# identical to AT90USB646
+
+part parent "usb646"
+ id = "usb647";
+ desc = "AT90USB647";
+ signature = 0x1e 0x96 0x82;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# AT90USB1286
+#------------------------------------------------------------
+
+part
+ id = "usb1286";
+ desc = "AT90USB1286";
+ signature = 0x1e 0x97 0x82;
+ usbpid = 0x2ffb;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB1287
+#------------------------------------------------------------
+# identical to AT90USB1286
+
+part parent "usb1286"
+ id = "usb1287";
+ desc = "AT90USB1287";
+ signature = 0x1e 0x97 0x82;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# AT90USB162
+#------------------------------------------------------------
+
+part
+ id = "usb162";
+ desc = "AT90USB162";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x94 0x82;
+ usbpid = 0x2ffa;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB82
+#------------------------------------------------------------
+# Changes against AT90USB162 (beside IDs)
+# memory "flash"
+# size = 8192;
+# num_pages = 64;
+
+part
+ id = "usb82";
+ desc = "AT90USB82";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x93 0x82;
+ usbpid = 0x2ff7;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 128;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega32U2
+#------------------------------------------------------------
+# Changes against AT90USB162 (beside IDs)
+# memory "flash"
+# size = 32768;
+# num_pages = 256;
+# memory "eeprom"
+# size = 1024;
+# num_pages = 256;
+part
+ id = "m32u2";
+ desc = "ATmega32U2";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x95 0x8a;
+ usbpid = 0x2ff0;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ num_pages = 256;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+#------------------------------------------------------------
+# ATmega16U2
+#------------------------------------------------------------
+# Changes against ATmega32U2 (beside IDs)
+# memory "flash"
+# size = 16384;
+# num_pages = 128;
+# memory "eeprom"
+# size = 512;
+# num_pages = 128;
+part
+ id = "m16u2";
+ desc = "ATmega16U2";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x94 0x89;
+ usbpid = 0x2fef;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega8U2
+#------------------------------------------------------------
+# Changes against ATmega16U2 (beside IDs)
+# memory "flash"
+# size = 8192;
+# page_size = 64;
+# blocksize = 64;
+
+part
+ id = "m8u2";
+ desc = "ATmega8U2";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x93 0x89;
+ usbpid = 0x2fee;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 128;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+#------------------------------------------------------------
+# ATmega325
+#------------------------------------------------------------
+
+part
+ id = "m325";
+ desc = "ATmega325";
+ signature = 0x1e 0x95 0x05;
+ has_jtag = yes;
+# stk500_devcode = 0x??; # No STK500v1 support?
+# avr910_devcode = 0x??; # Try the ATmega16 one
+ avr910_devcode = 0x74;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega645
+#------------------------------------------------------------
+
+part
+ id = "m645";
+ desc = "ATmega645";
+ signature = 0x1E 0x96 0x05;
+ has_jtag = yes;
+# stk500_devcode = 0x??; # No STK500v1 support?
+# avr910_devcode = 0x??; # Try the ATmega16 one
+ avr910_devcode = 0x74;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " 0 0 0 0 0 0 0 0";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega3250
+#------------------------------------------------------------
+
+part parent "m325"
+ id = "m3250";
+ desc = "ATmega3250";
+ signature = 0x1E 0x95 0x06;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega6450
+#------------------------------------------------------------
+
+part parent "m645"
+ id = "m6450";
+ desc = "ATmega6450";
+ signature = 0x1E 0x96 0x06;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# AVR XMEGA family common values
+#------------------------------------------------------------
+
+part
+ id = ".xmega";
+ desc = "AVR XMEGA family common values";
+ has_pdi = yes;
+ nvm_base = 0x01c0;
+ mcu_base = 0x0090;
+
+ memory "signature"
+ size = 3;
+ offset = 0x1000090;
+ ;
+
+ memory "prodsig"
+ size = 0x32;
+ offset = 0x8e0200;
+ page_size = 0x32;
+ readsize = 0x32;
+ ;
+
+ memory "fuse1"
+ size = 1;
+ offset = 0x8f0021;
+ ;
+
+ memory "fuse2"
+ size = 1;
+ offset = 0x8f0022;
+ ;
+
+ memory "fuse4"
+ size = 1;
+ offset = 0x8f0024;
+ ;
+
+ memory "fuse5"
+ size = 1;
+ offset = 0x8f0025;
+ ;
+
+ memory "lock"
+ size = 1;
+ offset = 0x8f0027;
+ ;
+
+ memory "data"
+ # SRAM, only used to supply the offset
+ offset = 0x1000000;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega16A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x16a4u";
+ desc = "ATxmega16A4U";
+ signature = 0x1e 0x94 0x41;
+ usbpid = 0x2fe3;
+
+ memory "eeprom"
+ size = 0x400;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x4000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x803000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x804000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x5000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega16C4
+#------------------------------------------------------------
+
+part parent "x16a4u"
+ id = "x16c4";
+ desc = "ATxmega16C4";
+ signature = 0x1e 0x95 0x44;
+;
+
+#------------------------------------------------------------
+# ATxmega16D4
+#------------------------------------------------------------
+
+part parent "x16a4u"
+ id = "x16d4";
+ desc = "ATxmega16D4";
+ signature = 0x1e 0x94 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega16A4
+#------------------------------------------------------------
+
+part parent "x16a4u"
+ id = "x16a4";
+ desc = "ATxmega16A4";
+ signature = 0x1e 0x94 0x41;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega32A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x32a4u";
+ desc = "ATxmega32A4U";
+ signature = 0x1e 0x95 0x41;
+ usbpid = 0x2fe4;
+
+ memory "eeprom"
+ size = 0x400;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x8000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x807000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x808000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x9000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega32C4
+#------------------------------------------------------------
+
+part parent "x32a4u"
+ id = "x32c4";
+ desc = "ATxmega32C4";
+ signature = 0x1e 0x94 0x43;
+;
+
+#------------------------------------------------------------
+# ATxmega32D4
+#------------------------------------------------------------
+
+part parent "x32a4u"
+ id = "x32d4";
+ desc = "ATxmega32D4";
+ signature = 0x1e 0x95 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega32A4
+#------------------------------------------------------------
+
+part parent "x32a4u"
+ id = "x32a4";
+ desc = "ATxmega32A4";
+ signature = 0x1e 0x95 0x41;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega64A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x64a4u";
+ desc = "ATxmega64A4U";
+ signature = 0x1e 0x96 0x46;
+ usbpid = 0x2fe5;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x10000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x80f000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x810000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x11000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega64C3
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64c3";
+ desc = "ATxmega64C3";
+ signature = 0x1e 0x96 0x49;
+ usbpid = 0x2fd6;
+;
+
+#------------------------------------------------------------
+# ATxmega64D3
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64d3";
+ desc = "ATxmega64D3";
+ signature = 0x1e 0x96 0x4a;
+;
+
+#------------------------------------------------------------
+# ATxmega64D4
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64d4";
+ desc = "ATxmega64D4";
+ signature = 0x1e 0x96 0x47;
+;
+
+#------------------------------------------------------------
+# ATxmega64A1
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64a1";
+ desc = "ATxmega64A1";
+ signature = 0x1e 0x96 0x4e;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega64A1U
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a1u";
+ desc = "ATxmega64A1U";
+ signature = 0x1e 0x96 0x4e;
+ usbpid = 0x2fe8;
+;
+
+#------------------------------------------------------------
+# ATxmega64A3
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a3";
+ desc = "ATxmega64A3";
+ signature = 0x1e 0x96 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega64A3U
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a3u";
+ desc = "ATxmega64A3U";
+ signature = 0x1e 0x96 0x42;
+ usbpid = 0x2fe5;
+;
+
+#------------------------------------------------------------
+# ATxmega64A4
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a4";
+ desc = "ATxmega64A4";
+ signature = 0x1e 0x96 0x46;
+;
+
+#------------------------------------------------------------
+# ATxmega64B1
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64b1";
+ desc = "ATxmega64B1";
+ signature = 0x1e 0x96 0x52;
+ usbpid = 0x2fe1;
+;
+
+#------------------------------------------------------------
+# ATxmega64B3
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64b3";
+ desc = "ATxmega64B3";
+ signature = 0x1e 0x96 0x51;
+ usbpid = 0x2fdf;
+;
+
+#------------------------------------------------------------
+# ATxmega128C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128c3";
+ desc = "ATxmega128C3";
+ signature = 0x1e 0x97 0x52;
+ usbpid = 0x2fd7;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x81e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128D3
+#------------------------------------------------------------
+
+part parent "x128c3"
+ id = "x128d3";
+ desc = "ATxmega128D3";
+ signature = 0x1e 0x97 0x48;
+;
+
+#------------------------------------------------------------
+# ATxmega128D4
+#------------------------------------------------------------
+
+part parent "x128c3"
+ id = "x128d4";
+ desc = "ATxmega128D4";
+ signature = 0x1e 0x97 0x47;
+;
+
+#------------------------------------------------------------
+# ATxmega128A1
+#------------------------------------------------------------
+
+part parent "x128c3"
+ id = "x128a1";
+ desc = "ATxmega128A1";
+ signature = 0x1e 0x97 0x4c;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128A1 revision D
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a1d";
+ desc = "ATxmega128A1revD";
+ signature = 0x1e 0x97 0x41;
+;
+
+#------------------------------------------------------------
+# ATxmega128A1U
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a1u";
+ desc = "ATxmega128A1U";
+ signature = 0x1e 0x97 0x4c;
+ usbpid = 0x2fed;
+;
+
+#------------------------------------------------------------
+# ATxmega128A3
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a3";
+ desc = "ATxmega128A3";
+ signature = 0x1e 0x97 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega128A3U
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a3u";
+ desc = "ATxmega128A3U";
+ signature = 0x1e 0x97 0x42;
+ usbpid = 0x2fe6;
+;
+
+#------------------------------------------------------------
+# ATxmega128A4
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128a4";
+ desc = "ATxmega128A4";
+ signature = 0x1e 0x97 0x46;
+ has_jtag = yes;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x81f000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128a4u";
+ desc = "ATxmega128A4U";
+ signature = 0x1e 0x97 0x46;
+ usbpid = 0x2fde;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x81f000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128B1
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128b1";
+ desc = "ATxmega128B1";
+ signature = 0x1e 0x97 0x4d;
+ usbpid = 0x2fea;
+ has_jtag = yes;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x81e000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128B3
+#------------------------------------------------------------
+
+part parent "x128b1"
+ id = "x128b3";
+ desc = "ATxmega128B3";
+ signature = 0x1e 0x97 0x4b;
+ usbpid = 0x2fe0;
+;
+
+#------------------------------------------------------------
+# ATxmega192C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x192c3";
+ desc = "ATxmega192C3";
+ signature = 0x1e 0x97 0x51;
+ # usbpid = 0x2f??;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x30000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x82e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x830000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x32000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega192D3
+#------------------------------------------------------------
+
+part parent "x192c3"
+ id = "x192d3";
+ desc = "ATxmega192D3";
+ signature = 0x1e 0x97 0x49;
+;
+
+#------------------------------------------------------------
+# ATxmega192A1
+#------------------------------------------------------------
+
+part parent "x192c3"
+ id = "x192a1";
+ desc = "ATxmega192A1";
+ signature = 0x1e 0x97 0x4e;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega192A3
+#------------------------------------------------------------
+
+part parent "x192a1"
+ id = "x192a3";
+ desc = "ATxmega192A3";
+ signature = 0x1e 0x97 0x44;
+;
+
+#------------------------------------------------------------
+# ATxmega192A3U
+#------------------------------------------------------------
+
+part parent "x192a1"
+ id = "x192a3u";
+ desc = "ATxmega192A3U";
+ signature = 0x1e 0x97 0x44;
+ usbpid = 0x2fe7;
+;
+
+#------------------------------------------------------------
+# ATxmega256C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x256c3";
+ desc = "ATxmega256C3";
+ signature = 0x1e 0x98 0x46;
+ usbpid = 0x2fda;
+
+ memory "eeprom"
+ size = 0x1000;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x40000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x83e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x840000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x42000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega256D3
+#------------------------------------------------------------
+
+part parent "x256c3"
+ id = "x256d3";
+ desc = "ATxmega256D3";
+ signature = 0x1e 0x98 0x44;
+;
+
+#------------------------------------------------------------
+# ATxmega256A1
+#------------------------------------------------------------
+
+part parent "x256c3"
+ id = "x256a1";
+ desc = "ATxmega256A1";
+ signature = 0x1e 0x98 0x46;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3";
+ desc = "ATxmega256A3";
+ signature = 0x1e 0x98 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3U
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3u";
+ desc = "ATxmega256A3U";
+ signature = 0x1e 0x98 0x42;
+ usbpid = 0x2fec;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3B
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3b";
+ desc = "ATxmega256A3B";
+ signature = 0x1e 0x98 0x43;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3BU
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3bu";
+ desc = "ATxmega256A3BU";
+ signature = 0x1e 0x98 0x43;
+ usbpid = 0x2fe2;
+;
+
+#------------------------------------------------------------
+# ATxmega384C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x384c3";
+ desc = "ATxmega384C3";
+ signature = 0x1e 0x98 0x45;
+ usbpid = 0x2fdb;
+
+ memory "eeprom"
+ size = 0x1000;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x60000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x85e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x860000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x62000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega384D3
+#------------------------------------------------------------
+
+part parent "x384c3"
+ id = "x384d3";
+ desc = "ATxmega384D3";
+ signature = 0x1e 0x98 0x47;
+;
+
+#------------------------------------------------------------
+# ATxmega8E5
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x8e5";
+ desc = "ATxmega8E5";
+ signature = 0x1e 0x93 0x41;
+
+ memory "eeprom"
+ size = 0x0200;
+ offset = 0x08c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x2000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x800;
+ offset = 0x00801800;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x800;
+ offset = 0x00802000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x2800;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x80;
+ offset = 0x8e0400;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega16E5
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x16e5";
+ desc = "ATxmega16E5";
+ signature = 0x1e 0x94 0x45;
+
+ memory "eeprom"
+ size = 0x0200;
+ offset = 0x08c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x4000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x00803000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x00804000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x5000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x80;
+ offset = 0x8e0400;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega32E5
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x32e5";
+ desc = "ATxmega32E5";
+ signature = 0x1e 0x95 0x4c;
+
+ memory "eeprom"
+ size = 0x0400;
+ offset = 0x08c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x8000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x00807000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x00808000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x9000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x80;
+ offset = 0x8e0400;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# AVR32UC3A0512
+#------------------------------------------------------------
+
+part
+ id = "uc3a0512";
+ desc = "AT32UC3A0512";
+ signature = 0xED 0xC0 0x3F;
+ has_jtag = yes;
+ is_avr32 = yes;
+
+ memory "flash"
+ paged = yes;
+ page_size = 512; # bytes
+ readsize = 512; # bytes
+ num_pages = 1024; # could be set dynamicly
+ size = 0x00080000; # could be set dynamicly
+ offset = 0x80000000;
+ ;
+;
+
+part parent "uc3a0512"
+ id = "ucr2";
+ desc = "deprecated, use 'uc3a0512'";
+;
+
+#------------------------------------------------------------
+# ATtiny1634.
+#------------------------------------------------------------
+
+part
+ id = "t1634";
+ desc = "ATtiny1634";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x86;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x94 0x12;
+ pagel = 0xB3;
+ bs2 = 0xB1;
+ reset = io;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
+ 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
+ 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
+ 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 256;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 5;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 32;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 1 1 1 1 i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+;
+
+#------------------------------------------------------------
+# Common values for reduced core tinys (4/5/9/10/20/40)
+#------------------------------------------------------------
+
+part
+ id = ".reduced_core_tiny";
+ desc = "Common values for reduced core tinys";
+ has_tpi = yes;
+
+ memory "signature"
+ size = 3;
+ offset = 0x3fc0;
+ page_size = 16;
+ ;
+
+ memory "fuse"
+ size = 1;
+ offset = 0x3f40;
+ page_size = 16;
+ blocksize = 4;
+ ;
+
+ memory "calibration"
+ size = 1;
+ offset = 0x3f80;
+ page_size = 16;
+ ;
+
+ memory "lockbits"
+ size = 1;
+ offset = 0x3f00;
+ page_size = 16;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny4
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t4";
+ desc = "ATtiny4";
+ signature = 0x1e 0x8f 0x0a;
+
+ memory "flash"
+ size = 512;
+ offset = 0x4000;
+ page_size = 16;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny5
+#------------------------------------------------------------
+
+part parent "t4"
+ id = "t5";
+ desc = "ATtiny5";
+ signature = 0x1e 0x8f 0x09;
+;
+
+#------------------------------------------------------------
+# ATtiny9
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t9";
+ desc = "ATtiny9";
+ signature = 0x1e 0x90 0x08;
+
+ memory "flash"
+ size = 1024;
+ offset = 0x4000;
+ page_size = 16;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny10
+#------------------------------------------------------------
+
+part parent "t9"
+ id = "t10";
+ desc = "ATtiny10";
+ signature = 0x1e 0x90 0x03;
+;
+
+#------------------------------------------------------------
+# ATtiny20
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t20";
+ desc = "ATtiny20";
+ signature = 0x1e 0x91 0x0F;
+
+ memory "flash"
+ size = 2048;
+ offset = 0x4000;
+ page_size = 16;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny40
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t40";
+ desc = "ATtiny40";
+ signature = 0x1e 0x92 0x0E;
+
+ memory "flash"
+ size = 4096;
+ offset = 0x4000;
+ page_size = 64;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATmega406
+#------------------------------------------------------------
+
+part
+ id = "m406";
+ desc = "ATMEGA406";
+ has_jtag = yes;
+ signature = 0x1e 0x95 0x07;
+
+ # STK500 parameters (parallel programming IO lines)
+ pagel = 0xa7;
+ bs2 = 0xa0;
+ serial = no;
+ parallel = yes;
+
+ # STK500v2 HV programming parameters, from XML
+ pp_controlstack = 0x0e, 0x1e, 0x0f, 0x1f, 0x2e, 0x3e, 0x2f, 0x3f,
+ 0x4e, 0x5e, 0x4f, 0x5f, 0x6e, 0x7e, 0x6f, 0x7f,
+ 0x66, 0x76, 0x67, 0x77, 0x6a, 0x7a, 0x6b, 0x7b,
+ 0xbe, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+
+ # JTAG ICE mkII parameters, also from XML files
+ allowfullpagebitstream = no;
+ enablepageprogramming = yes;
+ idr = 0x51;
+ rampz = 0x00;
+ spmcr = 0x57;
+ eecr = 0x3f;
+
+ memory "eeprom"
+ paged = no;
+ size = 512;
+ page_size = 4;
+ blocksize = 4;
+ readsize = 4;
+ num_pages = 128;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 40960;
+ page_size = 128;
+ blocksize = 128;
+ readsize = 128;
+ num_pages = 320;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ ;
+
+ memory "lockbits"
+ size = 1;
+ ;
+
+ memory "signature"
+ size = 3;
+ ;
+;
+
+
diff --git a/xs/src/avrdude/avrdude.conf.in b/xs/src/avrdude/avrdude.conf.in
new file mode 100644
index 000000000..b247e5225
--- /dev/null
+++ b/xs/src/avrdude/avrdude.conf.in
@@ -0,0 +1,14984 @@
+# $Id$ -*- text -*-
+#
+# AVRDUDE Configuration File
+#
+# This file contains configuration data used by AVRDUDE which describes
+# the programming hardware pinouts and also provides part definitions.
+# AVRDUDE's "-C" command line option specifies the location of the
+# configuration file. The "-c" option names the programmer configuration
+# which must match one of the entry's "id" parameter. The "-p" option
+# identifies which part AVRDUDE is going to be programming and must match
+# one of the parts' "id" parameter.
+#
+# DO NOT MODIFY THIS FILE. Modifications will be overwritten the next
+# time a "make install" is run. For user-specific additions, use the
+# "-C +filename" commandline option.
+#
+# Possible entry formats are:
+#
+# programmer
+# parent <id> # optional parent
+# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
+# desc = <description> ; # quoted string
+# type = <type>; # programmer type, quoted string
+# # supported programmer types can be listed by "-c ?type"
+# connection_type = parallel | serial | usb
+# baudrate = <num> ; # baudrate for avr910-programmer
+# vcc = <num1> [, <num2> ... ] ; # pin number(s)
+# buff = <num1> [, <num2> ... ] ; # pin number(s)
+# reset = <num> ; # pin number
+# sck = <num> ; # pin number
+# mosi = <num> ; # pin number
+# miso = <num> ; # pin number
+# errled = <num> ; # pin number
+# rdyled = <num> ; # pin number
+# pgmled = <num> ; # pin number
+# vfyled = <num> ; # pin number
+# usbvid = <hexnum>; # USB VID (Vendor ID)
+# usbpid = <hexnum> [, <hexnum> ...] # USB PID (Product ID) (1)
+# usbdev = <interface>; # USB interface or other device info
+# usbvendor = <vendorname>; # USB Vendor Name
+# usbproduct = <productname>; # USB Product Name
+# usbsn = <serialno>; # USB Serial Number
+#
+# To invert a bit, use = ~ <num>, the spaces are important.
+# For a pin list all pins must be inverted.
+# A single pin can be specified as usual = ~ <num>, for lists
+# specify it as follows = ~ ( <num> [, <num2> ... ] ) .
+#
+# (1) Not all programmer types can process a list of PIDs.
+# ;
+#
+# part
+# id = <id> ; # quoted string
+# desc = <description> ; # quoted string
+# has_jtag = <yes/no> ; # part has JTAG i/f
+# has_debugwire = <yes/no> ; # part has debugWire i/f
+# has_pdi = <yes/no> ; # part has PDI i/f
+# has_tpi = <yes/no> ; # part has TPI i/f
+# devicecode = <num> ; # deprecated, use stk500_devcode
+# stk500_devcode = <num> ; # numeric
+# avr910_devcode = <num> ; # numeric
+# signature = <num> <num> <num> ; # signature bytes
+# usbpid = <num> ; # DFU USB PID
+# chip_erase_delay = <num> ; # micro-seconds
+# reset = dedicated | io;
+# retry_pulse = reset | sck;
+# pgm_enable = <instruction format> ;
+# chip_erase = <instruction format> ;
+# chip_erase_delay = <num> ; # chip erase delay (us)
+# # STK500 parameters (parallel programming IO lines)
+# pagel = <num> ; # pin name in hex, i.e., 0xD7
+# bs2 = <num> ; # pin name in hex, i.e., 0xA0
+# serial = <yes/no> ; # can use serial downloading
+# parallel = <yes/no/pseudo>; # can use par. programming
+# # STK500v2 parameters, to be taken from Atmel's XML files
+# timeout = <num> ;
+# stabdelay = <num> ;
+# cmdexedelay = <num> ;
+# synchloops = <num> ;
+# bytedelay = <num> ;
+# pollvalue = <num> ;
+# pollindex = <num> ;
+# predelay = <num> ;
+# postdelay = <num> ;
+# pollmethod = <num> ;
+# mode = <num> ;
+# delay = <num> ;
+# blocksize = <num> ;
+# readsize = <num> ;
+# hvspcmdexedelay = <num> ;
+# # STK500v2 HV programming parameters, from XML
+# pp_controlstack = <num>, <num>, ...; # PP only
+# hvsp_controlstack = <num>, <num>, ...; # HVSP only
+# hventerstabdelay = <num>;
+# progmodedelay = <num>; # PP only
+# latchcycles = <num>;
+# togglevtg = <num>;
+# poweroffdelay = <num>;
+# resetdelayms = <num>;
+# resetdelayus = <num>;
+# hvleavestabdelay = <num>;
+# resetdelay = <num>;
+# synchcycles = <num>; # HVSP only
+# chiperasepulsewidth = <num>; # PP only
+# chiperasepolltimeout = <num>;
+# chiperasetime = <num>; # HVSP only
+# programfusepulsewidth = <num>; # PP only
+# programfusepolltimeout = <num>;
+# programlockpulsewidth = <num>; # PP only
+# programlockpolltimeout = <num>;
+# # JTAG ICE mkII parameters, also from XML files
+# allowfullpagebitstream = <yes/no> ;
+# enablepageprogramming = <yes/no> ;
+# idr = <num> ; # IO addr of IDR (OCD) reg.
+# rampz = <num> ; # IO addr of RAMPZ reg.
+# spmcr = <num> ; # mem addr of SPMC[S]R reg.
+# eecr = <num> ; # mem addr of EECR reg.
+# # (only when != 0x3c)
+# is_at90s1200 = <yes/no> ; # AT90S1200 part
+# is_avr32 = <yes/no> ; # AVR32 part
+#
+# memory <memtype>
+# paged = <yes/no> ; # yes / no
+# size = <num> ; # bytes
+# page_size = <num> ; # bytes
+# num_pages = <num> ; # numeric
+# min_write_delay = <num> ; # micro-seconds
+# max_write_delay = <num> ; # micro-seconds
+# readback_p1 = <num> ; # byte value
+# readback_p2 = <num> ; # byte value
+# pwroff_after_write = <yes/no> ; # yes / no
+# read = <instruction format> ;
+# write = <instruction format> ;
+# read_lo = <instruction format> ;
+# read_hi = <instruction format> ;
+# write_lo = <instruction format> ;
+# write_hi = <instruction format> ;
+# loadpage_lo = <instruction format> ;
+# loadpage_hi = <instruction format> ;
+# writepage = <instruction format> ;
+# ;
+# ;
+#
+# If any of the above parameters are not specified, the default value
+# of 0 is used for numerics or the empty string ("") for string
+# values. If a required parameter is left empty, AVRDUDE will
+# complain.
+#
+# Parts can also inherit parameters from previously defined parts
+# using the following syntax. In this case specified integer and
+# string values override parameter values from the parent part. New
+# memory definitions are added to the definitions inherited from the
+# parent.
+#
+# part parent <id> # quoted string
+# id = <id> ; # quoted string
+# <any set of other parameters from the list above>
+# ;
+#
+# NOTES:
+# * 'devicecode' is the device code used by the STK500 (see codes
+# listed below)
+# * Not all memory types will implement all instructions.
+# * AVR Fuse bits and Lock bits are implemented as a type of memory.
+# * Example memory types are:
+# "flash", "eeprom", "fuse", "lfuse" (low fuse), "hfuse" (high
+# fuse), "signature", "calibration", "lock"
+# * The memory type specified on the avrdude command line must match
+# one of the memory types defined for the specified chip.
+# * The pwroff_after_write flag causes avrdude to attempt to
+# power the device off and back on after an unsuccessful write to
+# the affected memory area if VCC programmer pins are defined. If
+# VCC pins are not defined for the programmer, a message
+# indicating that the device needs a power-cycle is printed out.
+# This flag was added to work around a problem with the
+# at90s4433/2333's; see the at90s4433 errata at:
+#
+# http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf
+#
+# INSTRUCTION FORMATS
+#
+# Instruction formats are specified as a comma seperated list of
+# string values containing information (bit specifiers) about each
+# of the 32 bits of the instruction. Bit specifiers may be one of
+# the following formats:
+#
+# '1' = the bit is always set on input as well as output
+#
+# '0' = the bit is always clear on input as well as output
+#
+# 'x' = the bit is ignored on input and output
+#
+# 'a' = the bit is an address bit, the bit-number matches this bit
+# specifier's position within the current instruction byte
+#
+# 'aN' = the bit is the Nth address bit, bit-number = N, i.e., a12
+# is address bit 12 on input, a0 is address bit 0.
+#
+# 'i' = the bit is an input data bit
+#
+# 'o' = the bit is an output data bit
+#
+# Each instruction must be composed of 32 bit specifiers. The
+# instruction specification closely follows the instruction data
+# provided in Atmel's data sheets for their parts.
+#
+# See below for some examples.
+#
+#
+# The following are STK500 part device codes to use for the
+# "devicecode" field of the part. These came from Atmel's software
+# section avr061.zip which accompanies the application note
+# AVR061 available from:
+#
+# http://www.atmel.com/dyn/resources/prod_documents/doc2525.pdf
+#
+
+#define ATTINY10 0x10 /* the _old_ one that never existed! */
+#define ATTINY11 0x11
+#define ATTINY12 0x12
+#define ATTINY15 0x13
+#define ATTINY13 0x14
+
+#define ATTINY22 0x20
+#define ATTINY26 0x21
+#define ATTINY28 0x22
+#define ATTINY2313 0x23
+
+#define AT90S1200 0x33
+
+#define AT90S2313 0x40
+#define AT90S2323 0x41
+#define AT90S2333 0x42
+#define AT90S2343 0x43
+
+#define AT90S4414 0x50
+#define AT90S4433 0x51
+#define AT90S4434 0x52
+#define ATMEGA48 0x59
+
+#define AT90S8515 0x60
+#define AT90S8535 0x61
+#define AT90C8534 0x62
+#define ATMEGA8515 0x63
+#define ATMEGA8535 0x64
+
+#define ATMEGA8 0x70
+#define ATMEGA88 0x73
+#define ATMEGA168 0x86
+
+#define ATMEGA161 0x80
+#define ATMEGA163 0x81
+#define ATMEGA16 0x82
+#define ATMEGA162 0x83
+#define ATMEGA169 0x84
+
+#define ATMEGA323 0x90
+#define ATMEGA32 0x91
+
+#define ATMEGA64 0xA0
+
+#define ATMEGA103 0xB1
+#define ATMEGA128 0xB2
+#define AT90CAN128 0xB3
+#define AT90CAN64 0xB3
+#define AT90CAN32 0xB3
+
+#define AT86RF401 0xD0
+
+#define AT89START 0xE0
+#define AT89S51 0xE0
+#define AT89S52 0xE1
+
+# The following table lists the devices in the original AVR910
+# appnote:
+# |Device |Signature | Code |
+# +-------+----------+------+
+# |tiny12 | 1E 90 05 | 0x55 |
+# |tiny15 | 1E 90 06 | 0x56 |
+# | | | |
+# | S1200 | 1E 90 01 | 0x13 |
+# | | | |
+# | S2313 | 1E 91 01 | 0x20 |
+# | S2323 | 1E 91 02 | 0x48 |
+# | S2333 | 1E 91 05 | 0x34 |
+# | S2343 | 1E 91 03 | 0x4C |
+# | | | |
+# | S4414 | 1E 92 01 | 0x28 |
+# | S4433 | 1E 92 03 | 0x30 |
+# | S4434 | 1E 92 02 | 0x6C |
+# | | | |
+# | S8515 | 1E 93 01 | 0x38 |
+# | S8535 | 1E 93 03 | 0x68 |
+# | | | |
+# |mega32 | 1E 95 01 | 0x72 |
+# |mega83 | 1E 93 05 | 0x65 |
+# |mega103| 1E 97 01 | 0x41 |
+# |mega161| 1E 94 01 | 0x60 |
+# |mega163| 1E 94 02 | 0x64 |
+
+# Appnote AVR109 also has a table of AVR910 device codes, which
+# lists:
+# dev avr910 signature
+# ATmega8 0x77 0x1E 0x93 0x07
+# ATmega8515 0x3B 0x1E 0x93 0x06
+# ATmega8535 0x6A 0x1E 0x93 0x08
+# ATmega16 0x75 0x1E 0x94 0x03
+# ATmega162 0x63 0x1E 0x94 0x04
+# ATmega163 0x66 0x1E 0x94 0x02
+# ATmega169 0x79 0x1E 0x94 0x05
+# ATmega32 0x7F 0x1E 0x95 0x02
+# ATmega323 0x73 0x1E 0x95 0x01
+# ATmega64 0x46 0x1E 0x96 0x02
+# ATmega128 0x44 0x1E 0x97 0x02
+#
+# These codes refer to "BOOT" device codes which are apparently
+# different than standard device codes, for whatever reasons
+# (often one above the standard code).
+
+# There are several extended versions of AVR910 implementations around
+# in the Internet. These add the following codes (only devices that
+# actually exist are listed):
+
+# ATmega8515 0x3A
+# ATmega128 0x43
+# ATmega64 0x45
+# ATtiny26 0x5E
+# ATmega8535 0x69
+# ATmega32 0x72
+# ATmega16 0x74
+# ATmega8 0x76
+# ATmega169 0x78
+
+#
+# Overall avrdude defaults; suitable for ~/.avrduderc
+#
+default_parallel = "@DEFAULT_PAR_PORT@";
+default_serial = "@DEFAULT_SER_PORT@";
+# default_bitclock = 2.5;
+
+# Turn off safemode by default
+#default_safemode = no;
+
+
+#
+# PROGRAMMER DEFINITIONS
+#
+
+# http://wiring.org.co/
+# Basically STK500v2 protocol, with some glue to trigger the
+# bootloader.
+programmer
+ id = "wiring";
+ desc = "Wiring";
+ type = "wiring";
+ connection_type = serial;
+;
+
+programmer
+ id = "arduino";
+ desc = "Arduino";
+ type = "arduino";
+ connection_type = serial;
+;
+# this will interface with the chips on these programmers:
+#
+# http://real.kiev.ua/old/avreal/en/adapters
+# http://www.amontec.com/jtagkey.shtml, jtagkey-tiny.shtml
+# http://www.olimex.com/dev/arm-usb-ocd.html, arm-usb-tiny.html
+# http://www.ethernut.de/en/hardware/turtelizer/index.html
+# http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html
+# http://dangerousprototypes.com/docs/FT2232_breakout_board
+# http://www.ftdichip.com/Products/Modules/DLPModules.htm,DLP-2232*,DLP-USB1232H
+# http://flashrom.org/FT2232SPI_Programmer
+#
+# The drivers will look for a specific device and use the first one found.
+# If you have mulitple devices, then look for unique information (like SN)
+# And fill that in here.
+#
+# Note that the pin numbers for the main ISP signals (reset, sck,
+# mosi, miso) are fixed and cannot be changed, since they must match
+# the way the Multi-Protocol Synchronous Serial Engine (MPSSE) of
+# these FTDI ICs has been designed.
+
+programmer
+ id = "avrftdi";
+ desc = "FT2232D based generic programmer";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+ usbpid = 0x6010;
+ usbvendor = "";
+ usbproduct = "";
+ usbdev = "A";
+ usbsn = "";
+#ISP-signals - lower ADBUS-Nibble (default)
+ reset = 3;
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+#LED SIGNALs - higher ADBUS-Nibble
+# errled = 4;
+# rdyled = 5;
+# pgmled = 6;
+# vfyled = 7;
+#Buffer Signal - ACBUS - Nibble
+# buff = 8;
+;
+# This is an implementation of the above with a buffer IC (74AC244) and
+# 4 LEDs directly attached, all active low.
+programmer
+ id = "2232HIO";
+ desc = "FT2232H based generic programmer";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+# Note: This PID is reserved for generic H devices and
+# should be programmed into the EEPROM
+# usbpid = 0x8A48;
+ usbpid = 0x6010;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals
+ reset = 3;
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+ buff = ~4;
+#LED SIGNALs
+ errled = ~ 11;
+ rdyled = ~ 14;
+ pgmled = ~ 13;
+ vfyled = ~ 12;
+;
+
+#The FT4232H can be treated as FT2232H, but it has a different USB
+#device ID of 0x6011.
+programmer parent "avrftdi"
+ id = "4232h";
+ desc = "FT4232H based generic programmer";
+ usbpid = 0x6011;
+;
+
+programmer
+ id = "jtagkey";
+ desc = "Amontec JTAGKey, JTAGKey-Tiny and JTAGKey2";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+# Note: This PID is used in all JTAGKey variants
+ usbpid = 0xCFF8;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals => 20 - Pin connector on JTAGKey
+ reset = 3; # TMS 7 violet
+ sck = 0; # TCK 9 white
+ mosi = 1; # TDI 5 green
+ miso = 2; # TDO 13 orange
+ buff = ~4;
+# VTG VREF 1 brown with red tip
+# GND GND 20 black
+# The colors are on the 20 pin breakout cable
+# from Amontec
+;
+
+# UM232H module from FTDI and Glyn.com.au.
+# See helix.air.net.au for detailed usage information.
+# J1: Connect pin 2 and 3 for USB power.
+# J2: Connect pin 2 and 3 for USB power.
+# J2: Pin 7 is SCK
+# : Pin 8 is MOSI
+# : Pin 9 is MISO
+# : Pin 11 is RST
+# : Pin 6 is ground
+# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get
+# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant.
+programmer
+ id = "UM232H";
+ desc = "FT232H based module from FTDI and Glyn.com.au";
+ type = "avrftdi";
+ usbvid = 0x0403;
+# Note: This PID is reserved for generic 232H devices and
+# should be programmed into the EEPROM
+ usbpid = 0x6014;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+ reset = 3;
+;
+
+# C232HM module from FTDI and Glyn.com.au.
+# : Orange is SCK
+# : Yellow is MOSI
+# : Green is MISO
+# : Brown is RST
+# : Black is ground
+# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get
+# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant.
+programmer
+ id = "C232HM";
+ desc = "FT232H based module from FTDI and Glyn.com.au";
+ type = "avrftdi";
+ usbvid = 0x0403;
+# Note: This PID is reserved for generic 232H devices and
+# should be programmed into the EEPROM
+ usbpid = 0x6014;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+ reset = 3;
+;
+
+
+# On the adapter you can read "O-Link". On the PCB is printed "OpenJTAG v3.1"
+# You can find it as "OpenJTAG ARM JTAG USB" in the internet.
+# (But there are also several projects called Open JTAG, eg.
+# http://www.openjtag.org, which are completely different.)
+# http://www.100ask.net/shop/english.html (website seems to be outdated)
+# http://item.taobao.com/item.htm?id=1559277013
+# http://www.micro4you.com/store/openjtag-arm-jtag-usb.html (schematics!)
+# some other sources which call it O-Link
+# http://www.andahammer.com/olink/
+# http://www.developmentboard.net/31-o-link-debugger.html
+# http://armwerks.com/catalog/o-link-debugger-copy/
+# or just have a look at ebay ...
+# It is basically the same entry as jtagkey with different usb ids.
+programmer parent "jtagkey"
+ id = "o-link";
+ desc = "O-Link, OpenJTAG from www.100ask.net";
+ usbvid = 0x1457;
+ usbpid = 0x5118;
+ usbvendor = "www.100ask.net";
+ usbproduct = "USB<=>JTAG&RS232";
+;
+
+# http://wiki.openmoko.org/wiki/Debug_Board_v3
+programmer
+ id = "openmoko";
+ desc = "Openmoko debug board (v3)";
+ type = "avrftdi";
+ usbvid = 0x1457;
+ usbpid = 0x5118;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+ reset = 3; # TMS 7
+ sck = 0; # TCK 9
+ mosi = 1; # TDI 5
+ miso = 2; # TDO 13
+;
+
+# Only Rev. A boards.
+# Schematic and user manual: http://www.cs.put.poznan.pl/wswitala/download/pdf/811EVBK.pdf
+programmer
+ id = "lm3s811";
+ desc = "Luminary Micro LM3S811 Eval Board (Rev. A)";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+ usbpid = 0xbcd9;
+ usbvendor = "LMI";
+ usbproduct = "LM3S811 Evaluation Board";
+ usbdev = "A";
+ usbsn = "";
+#ISP-signals - lower ACBUS-Nibble (default)
+ reset = 3;
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+# Enable correct buffers
+ buff = 7;
+;
+
+# submitted as bug #46020
+programmer
+ id = "tumpa";
+ desc = "TIAO USB Multi-Protocol Adapter";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+ usbpid = 0x8A98;
+ usbdev = "A";
+ usbvendor = "TIAO";
+ usbproduct = "";
+ usbsn = "";
+ sck = 0; # TCK 9
+ mosi = 1; # TDI 5
+ miso = 2; # TDO 13
+ reset = 3; # TMS 7
+;
+
+programmer
+ id = "avrisp";
+ desc = "Atmel AVR ISP";
+ type = "stk500";
+ connection_type = serial;
+;
+
+programmer
+ id = "avrispv2";
+ desc = "Atmel AVR ISP V2";
+ type = "stk500v2";
+ connection_type = serial;
+;
+
+programmer
+ id = "avrispmkII";
+ desc = "Atmel AVR ISP mkII";
+ type = "stk500v2";
+ connection_type = usb;
+;
+
+programmer parent "avrispmkII"
+ id = "avrisp2";
+;
+
+programmer
+ id = "buspirate";
+ desc = "The Bus Pirate";
+ type = "buspirate";
+ connection_type = serial;
+;
+
+programmer
+ id = "buspirate_bb";
+ desc = "The Bus Pirate (bitbang interface, supports TPI)";
+ type = "buspirate_bb";
+ connection_type = serial;
+ # pins are bits in bitbang byte (numbers are 87654321)
+ # 1|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS
+ reset = 1;
+ sck = 3;
+ mosi = 4;
+ miso = 2;
+ #vcc = 7; This is internally set independent of this setting.
+;
+
+# This is supposed to be the "default" STK500 entry.
+# Attempts to select the correct firmware version
+# by probing for it. Better use one of the entries
+# below instead.
+programmer
+ id = "stk500";
+ desc = "Atmel STK500";
+ type = "stk500generic";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500v1";
+ desc = "Atmel STK500 Version 1.x firmware";
+ type = "stk500";
+ connection_type = serial;
+;
+
+programmer
+ id = "mib510";
+ desc = "Crossbow MIB510 programming board";
+ type = "stk500";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500v2";
+ desc = "Atmel STK500 Version 2.x firmware";
+ type = "stk500v2";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500pp";
+ desc = "Atmel STK500 V2 in parallel programming mode";
+ type = "stk500pp";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500hvsp";
+ desc = "Atmel STK500 V2 in high-voltage serial programming mode";
+ type = "stk500hvsp";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk600";
+ desc = "Atmel STK600";
+ type = "stk600";
+ connection_type = usb;
+;
+
+programmer
+ id = "stk600pp";
+ desc = "Atmel STK600 in parallel programming mode";
+ type = "stk600pp";
+ connection_type = usb;
+;
+
+programmer
+ id = "stk600hvsp";
+ desc = "Atmel STK600 in high-voltage serial programming mode";
+ type = "stk600hvsp";
+ connection_type = usb;
+;
+
+programmer
+ id = "avr910";
+ desc = "Atmel Low Cost Serial Programmer";
+ type = "avr910";
+ connection_type = serial;
+;
+
+programmer
+ id = "ft245r";
+ desc = "FT245R Synchronous BitBang";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 1; # D1
+ sck = 0; # D0
+ mosi = 2; # D2
+ reset = 4; # D4
+;
+
+programmer
+ id = "ft232r";
+ desc = "FT232R Synchronous BitBang";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 1; # RxD
+ sck = 0; # TxD
+ mosi = 2; # RTS
+ reset = 4; # DTR
+;
+
+# see http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega
+programmer
+ id = "bwmega";
+ desc = "BitWizard ftdi_atmega builtin programmer";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 5; # DSR
+ sck = 6; # DCD
+ mosi = 3; # CTS
+ reset = 7; # RI
+;
+
+# see http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html
+# Note: pins are numbered from 1!
+programmer
+ id = "arduino-ft232r";
+ desc = "Arduino: FT232R connected to ISP";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 3; # CTS X3(1)
+ sck = 5; # DSR X3(2)
+ mosi = 6; # DCD X3(3)
+ reset = 7; # RI X3(4)
+;
+
+# website mentioned above uses this id
+programmer parent "arduino-ft232r"
+ id = "diecimila";
+ desc = "alias for arduino-ft232r";
+;
+
+# There is a ATmega328P kit PCB called "uncompatino".
+# This board allows ISP via its on-board FT232R.
+# This is designed like Arduino Duemilanove but has no standard ICPS header.
+# Its 4 pairs of pins are shorted to enable ftdi_syncbb.
+# http://akizukidenshi.com/catalog/g/gP-07487/
+# http://akizukidenshi.com/download/ds/akizuki/k6096_manual_20130816.pdf
+programmer
+ id = "uncompatino";
+ desc = "uncompatino with all pairs of pins shorted";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 3; # cts
+ sck = 5; # dsr
+ mosi = 6; # dcd
+ reset = 7; # ri
+;
+
+# FTDI USB to serial cable TTL-232R-5V with a custom adapter for ICSP
+# http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm
+# http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232R_CABLES.pdf
+# For ICSP pinout see for example http://www.atmel.com/images/doc2562.pdf
+# (Figure 1. ISP6PIN header pinout and Table 1. Connections required for ISP ...)
+# TTL-232R GND 1 Black -> ICPS GND (pin 6)
+# TTL-232R CTS 2 Brown -> ICPS MOSI (pin 4)
+# TTL-232R VCC 3 Red -> ICPS VCC (pin 2)
+# TTL-232R TXD 4 Orange -> ICPS RESET (pin 5)
+# TTL-232R RXD 5 Yellow -> ICPS SCK (pin 3)
+# TTL-232R RTS 6 Green -> ICPS MISO (pin 1)
+# Except for VCC and GND, you can connect arbitual pairs as long as
+# the following table is adjusted.
+programmer
+ id = "ttl232r";
+ desc = "FTDI TTL232R-5V with ICSP adapter";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 2; # rts
+ sck = 1; # rxd
+ mosi = 3; # cts
+ reset = 0; # txd
+;
+
+programmer
+ id = "usbasp";
+ desc = "USBasp, http://www.fischl.de/usbasp/";
+ type = "usbasp";
+ connection_type = usb;
+ usbvid = 0x16C0; # VOTI
+ usbpid = 0x05DC; # Obdev's free shared PID
+ usbvendor = "www.fischl.de";
+ usbproduct = "USBasp";
+
+ # following variants are autodetected for id "usbasp"
+
+ # original usbasp from fischl.de
+ # see above "usbasp"
+
+ # old usbasp from fischl.de
+ #usbvid = 0x03EB; # ATMEL
+ #usbpid = 0xC7B4; # (unoffical) USBasp
+ #usbvendor = "www.fischl.de";
+ #usbproduct = "USBasp";
+
+ # NIBObee (only if -P nibobee is given on command line)
+ # see below "nibobee"
+;
+
+programmer
+ id = "nibobee";
+ desc = "NIBObee";
+ type = "usbasp";
+ connection_type = usb;
+ usbvid = 0x16C0; # VOTI
+ usbpid = 0x092F; # NIBObee PID
+ usbvendor = "www.nicai-systems.com";
+ usbproduct = "NIBObee";
+;
+
+programmer
+ id = "usbasp-clone";
+ desc = "Any usbasp clone with correct VID/PID";
+ type = "usbasp";
+ connection_type = usb;
+ usbvid = 0x16C0; # VOTI
+ usbpid = 0x05DC; # Obdev's free shared PID
+ #usbvendor = "";
+ #usbproduct = "";
+;
+
+programmer
+ id = "usbtiny";
+ desc = "USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/";
+ type = "usbtiny";
+ connection_type = usb;
+ usbvid = 0x1781;
+ usbpid = 0x0c9f;
+;
+
+# commercial version of USBtiny, using a separate VID/PID
+programmer
+ id = "ehajo-isp";
+ desc = "avr-isp-programmer from eHaJo, http://www.eHaJo.de";
+ type = "usbtiny";
+ connection_type = usb;
+ usbvid = 0x16D0;
+ usbpid = 0x0BA5;
+;
+
+programmer
+ id = "butterfly";
+ desc = "Atmel Butterfly Development Board";
+ type = "butterfly";
+ connection_type = serial;
+;
+
+programmer
+ id = "avr109";
+ desc = "Atmel AppNote AVR109 Boot Loader";
+ type = "butterfly";
+ connection_type = serial;
+;
+
+programmer
+ id = "avr911";
+ desc = "Atmel AppNote AVR911 AVROSP";
+ type = "butterfly";
+ connection_type = serial;
+;
+
+# suggested in http://forum.mikrokopter.de/topic-post48317.html
+programmer
+ id = "mkbutterfly";
+ desc = "Mikrokopter.de Butterfly";
+ type = "butterfly_mk";
+ connection_type = serial;
+;
+
+programmer parent "mkbutterfly"
+ id = "butterfly_mk";
+;
+
+programmer
+ id = "jtagmkI";
+ desc = "Atmel JTAG ICE (mkI)";
+ baudrate = 115200; # default is 115200
+ type = "jtagmki";
+ connection_type = serial;
+;
+
+# easier to type
+programmer parent "jtagmkI"
+ id = "jtag1";
+;
+
+# easier to type
+programmer parent "jtag1"
+ id = "jtag1slow";
+ baudrate = 19200;
+;
+
+# The JTAG ICE mkII has both, serial and USB connectivity. As it is
+# mostly used through USB these days (AVR Studio 5 only supporting it
+# that way), we make connection_type = usb the default. Users are
+# still free to use a serial port with the -P option.
+
+programmer
+ id = "jtagmkII";
+ desc = "Atmel JTAG ICE mkII";
+ baudrate = 19200; # default is 19200
+ type = "jtagmkii";
+ connection_type = usb;
+;
+
+# easier to type
+programmer parent "jtagmkII"
+ id = "jtag2slow";
+;
+
+# JTAG ICE mkII @ 115200 Bd
+programmer parent "jtag2slow"
+ id = "jtag2fast";
+ baudrate = 115200;
+;
+
+# make the fast one the default, people will love that
+programmer parent "jtag2fast"
+ id = "jtag2";
+;
+
+# JTAG ICE mkII in ISP mode
+programmer
+ id = "jtag2isp";
+ desc = "Atmel JTAG ICE mkII in ISP mode";
+ baudrate = 115200;
+ type = "jtagmkii_isp";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in debugWire mode
+programmer
+ id = "jtag2dw";
+ desc = "Atmel JTAG ICE mkII in debugWire mode";
+ baudrate = 115200;
+ type = "jtagmkii_dw";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in AVR32 mode
+programmer
+ id = "jtagmkII_avr32";
+ desc = "Atmel JTAG ICE mkII im AVR32 mode";
+ baudrate = 115200;
+ type = "jtagmkii_avr32";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in AVR32 mode
+programmer
+ id = "jtag2avr32";
+ desc = "Atmel JTAG ICE mkII im AVR32 mode";
+ baudrate = 115200;
+ type = "jtagmkii_avr32";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in PDI mode
+programmer
+ id = "jtag2pdi";
+ desc = "Atmel JTAG ICE mkII PDI mode";
+ baudrate = 115200;
+ type = "jtagmkii_pdi";
+ connection_type = usb;
+;
+
+# AVR Dragon in JTAG mode
+programmer
+ id = "dragon_jtag";
+ desc = "Atmel AVR Dragon in JTAG mode";
+ baudrate = 115200;
+ type = "dragon_jtag";
+ connection_type = usb;
+;
+
+# AVR Dragon in ISP mode
+programmer
+ id = "dragon_isp";
+ desc = "Atmel AVR Dragon in ISP mode";
+ baudrate = 115200;
+ type = "dragon_isp";
+ connection_type = usb;
+;
+
+# AVR Dragon in PP mode
+programmer
+ id = "dragon_pp";
+ desc = "Atmel AVR Dragon in PP mode";
+ baudrate = 115200;
+ type = "dragon_pp";
+ connection_type = usb;
+;
+
+# AVR Dragon in HVSP mode
+programmer
+ id = "dragon_hvsp";
+ desc = "Atmel AVR Dragon in HVSP mode";
+ baudrate = 115200;
+ type = "dragon_hvsp";
+ connection_type = usb;
+;
+
+# AVR Dragon in debugWire mode
+programmer
+ id = "dragon_dw";
+ desc = "Atmel AVR Dragon in debugWire mode";
+ baudrate = 115200;
+ type = "dragon_dw";
+ connection_type = usb;
+;
+
+# AVR Dragon in PDI mode
+programmer
+ id = "dragon_pdi";
+ desc = "Atmel AVR Dragon in PDI mode";
+ baudrate = 115200;
+ type = "dragon_pdi";
+ connection_type = usb;
+;
+
+programmer
+ id = "jtag3";
+ desc = "Atmel AVR JTAGICE3 in JTAG mode";
+ type = "jtagice3";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "jtag3pdi";
+ desc = "Atmel AVR JTAGICE3 in PDI mode";
+ type = "jtagice3_pdi";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "jtag3dw";
+ desc = "Atmel AVR JTAGICE3 in debugWIRE mode";
+ type = "jtagice3_dw";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "jtag3isp";
+ desc = "Atmel AVR JTAGICE3 in ISP mode";
+ type = "jtagice3_isp";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "xplainedpro";
+ desc = "Atmel AVR XplainedPro in JTAG mode";
+ type = "jtagice3";
+ connection_type = usb;
+ usbpid = 0x2111;
+;
+
+programmer
+ id = "xplainedmini";
+ desc = "Atmel AVR XplainedMini in ISP mode";
+ type = "jtagice3_isp";
+ connection_type = usb;
+ usbpid = 0x2145;
+;
+
+programmer
+ id = "xplainedmini_dw";
+ desc = "Atmel AVR XplainedMini in debugWIRE mode";
+ type = "jtagice3_dw";
+ connection_type = usb;
+ usbpid = 0x2145;
+;
+
+programmer
+ id = "atmelice";
+ desc = "Atmel-ICE (ARM/AVR) in JTAG mode";
+ type = "jtagice3";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+programmer
+ id = "atmelice_pdi";
+ desc = "Atmel-ICE (ARM/AVR) in PDI mode";
+ type = "jtagice3_pdi";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+programmer
+ id = "atmelice_dw";
+ desc = "Atmel-ICE (ARM/AVR) in debugWIRE mode";
+ type = "jtagice3_dw";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+programmer
+ id = "atmelice_isp";
+ desc = "Atmel-ICE (ARM/AVR) in ISP mode";
+ type = "jtagice3_isp";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+
+programmer
+ id = "pavr";
+ desc = "Jason Kyle's pAVR Serial Programmer";
+ type = "avr910";
+ connection_type = serial;
+;
+
+programmer
+ id = "pickit2";
+ desc = "MicroChip's PICkit2 Programmer";
+ type = "pickit2";
+ connection_type = usb;
+;
+
+programmer
+ id = "flip1";
+ desc = "FLIP USB DFU protocol version 1 (doc7618)";
+ type = "flip1";
+ connection_type = usb;
+;
+
+programmer
+ id = "flip2";
+ desc = "FLIP USB DFU protocol version 2 (AVR4023)";
+ type = "flip2";
+ connection_type = usb;
+;
+
+@HAVE_PARPORT_BEGIN@ Inclusion of the following depends on --enable-parport
+# Parallel port programmers.
+
+programmer
+ id = "bsd";
+ desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/";
+ type = "par";
+ connection_type = parallel;
+ vcc = 2, 3, 4, 5;
+ reset = 7;
+ sck = 8;
+ mosi = 9;
+ miso = 10;
+;
+
+programmer
+ id = "stk200";
+ desc = "STK200";
+ type = "par";
+ connection_type = parallel;
+ buff = 4, 5;
+ sck = 6;
+ mosi = 7;
+ reset = 9;
+ miso = 10;
+;
+
+# The programming dongle used by the popular Ponyprog
+# utility. It is almost similar to the STK200 one,
+# except that there is a LED indicating that the
+# programming is currently in progress.
+
+programmer parent "stk200"
+ id = "pony-stk200";
+ desc = "Pony Prog STK200";
+ pgmled = 8;
+;
+
+programmer
+ id = "dt006";
+ desc = "Dontronics DT006";
+ type = "par";
+ connection_type = parallel;
+ reset = 4;
+ sck = 5;
+ mosi = 2;
+ miso = 11;
+;
+
+programmer parent "dt006"
+ id = "bascom";
+ desc = "Bascom SAMPLE programming cable";
+;
+
+programmer
+ id = "alf";
+ desc = "Nightshade ALF-PgmAVR, http://nightshade.homeip.net/";
+ type = "par";
+ connection_type = parallel;
+ vcc = 2, 3, 4, 5;
+ buff = 6;
+ reset = 7;
+ sck = 8;
+ mosi = 9;
+ miso = 10;
+ errled = 1;
+ rdyled = 14;
+ pgmled = 16;
+ vfyled = 17;
+;
+
+programmer
+ id = "sp12";
+ desc = "Steve Bolt's Programmer";
+ type = "par";
+ connection_type = parallel;
+ vcc = 4,5,6,7,8;
+ reset = 3;
+ sck = 2;
+ mosi = 9;
+ miso = 11;
+;
+
+programmer
+ id = "picoweb";
+ desc = "Picoweb Programming Cable, http://www.picoweb.net/";
+ type = "par";
+ connection_type = parallel;
+ reset = 2;
+ sck = 3;
+ mosi = 4;
+ miso = 13;
+;
+
+programmer
+ id = "abcmini";
+ desc = "ABCmini Board, aka Dick Smith HOTCHIP";
+ type = "par";
+ connection_type = parallel;
+ reset = 4;
+ sck = 3;
+ mosi = 2;
+ miso = 10;
+;
+
+programmer
+ id = "futurlec";
+ desc = "Futurlec.com programming cable.";
+ type = "par";
+ connection_type = parallel;
+ reset = 3;
+ sck = 2;
+ mosi = 1;
+ miso = 10;
+;
+
+
+# From the contributor of the "xil" jtag cable:
+# The "vcc" definition isn't really vcc (the cable gets its power from
+# the programming circuit) but is necessary to switch one of the
+# buffer lines (trying to add it to the "buff" lines doesn't work in
+# avrdude versions before 5.5j).
+# With this, TMS connects to RESET, TDI to MOSI, TDO to MISO and TCK
+# to SCK (plus vcc/gnd of course)
+programmer
+ id = "xil";
+ desc = "Xilinx JTAG cable";
+ type = "par";
+ connection_type = parallel;
+ mosi = 2;
+ sck = 3;
+ reset = 4;
+ buff = 5;
+ miso = 13;
+ vcc = 6;
+;
+
+
+programmer
+ id = "dapa";
+ desc = "Direct AVR Parallel Access cable";
+ type = "par";
+ connection_type = parallel;
+ vcc = 3;
+ reset = 16;
+ sck = 1;
+ mosi = 2;
+ miso = 11;
+;
+
+programmer
+ id = "atisp";
+ desc = "AT-ISP V1.1 programming cable for AVR-SDK1 from <http://micro-research.co.th/> micro-research.co.th";
+ type = "par";
+ connection_type = parallel;
+ reset = ~6;
+ sck = ~8;
+ mosi = ~7;
+ miso = ~10;
+;
+
+programmer
+ id = "ere-isp-avr";
+ desc = "ERE ISP-AVR <http://www.ere.co.th/download/sch050713.pdf>";
+ type = "par";
+ connection_type = parallel;
+ reset = ~4;
+ sck = 3;
+ mosi = 2;
+ miso = 10;
+;
+
+programmer
+ id = "blaster";
+ desc = "Altera ByteBlaster";
+ type = "par";
+ connection_type = parallel;
+ sck = 2;
+ miso = 11;
+ reset = 3;
+ mosi = 8;
+ buff = 14;
+;
+
+# It is almost same as pony-stk200, except vcc on pin 5 to auto
+# disconnect port (download on http://electropol.free.fr/spip/spip.php?article27)
+programmer parent "pony-stk200"
+ id = "frank-stk200";
+ desc = "Frank STK200";
+ buff = ; # delete buff pin assignment
+ vcc = 5;
+;
+
+# The AT98ISP Cable is a simple parallel dongle for AT89 family.
+# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2877
+programmer
+ id = "89isp";
+ desc = "Atmel at89isp cable";
+ type = "par";
+ connection_type = parallel;
+ reset = 17;
+ sck = 1;
+ mosi = 2;
+ miso = 10;
+;
+
+@HAVE_PARPORT_END@
+
+#This programmer bitbangs GPIO lines using the Linux sysfs GPIO interface
+#
+#To enable it set the configuration below to match the GPIO lines connected to the
+#relevant ISP header pins and uncomment the entry definition. In case you don't
+#have the required permissions to edit this system wide config file put the
+#entry in a separate <your name>.conf file and use it with -C+<your name>.conf
+#on the command line.
+#
+#To check if your avrdude build has support for the linuxgpio programmer compiled in,
+#use -c?type on the command line and look for linuxgpio in the list. If it's not available
+#you need pass the --enable-linuxgpio=yes option to configure and recompile avrdude.
+#
+#programmer
+# id = "linuxgpio";
+# desc = "Use the Linux sysfs interface to bitbang GPIO lines";
+# type = "linuxgpio";
+# reset = ?;
+# sck = ?;
+# mosi = ?;
+# miso = ?;
+#;
+
+# some ultra cheap programmers use bitbanging on the
+# serialport.
+#
+# PC - DB9 - Pins for RS232:
+#
+# GND 5 -- |O
+# | O| <- 9 RI
+# DTR 4 <- |O |
+# | O| <- 8 CTS
+# TXD 3 <- |O |
+# | O| -> 7 RTS
+# RXD 2 -> |O |
+# | O| <- 6 DSR
+# DCD 1 -> |O
+#
+# Using RXD is currently not supported.
+# Using RI is not supported under Win32 but is supported under Posix.
+
+# serial ponyprog design (dasa2 in uisp)
+# reset=!txd sck=rts mosi=dtr miso=cts
+
+programmer
+ id = "ponyser";
+ desc = "design ponyprog serial, reset=!txd sck=rts mosi=dtr miso=cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = ~3;
+ sck = 7;
+ mosi = 4;
+ miso = 8;
+;
+
+# Same as above, different name
+# reset=!txd sck=rts mosi=dtr miso=cts
+
+programmer parent "ponyser"
+ id = "siprog";
+ desc = "Lancos SI-Prog <http://www.lancos.com/siprogsch.html>";
+;
+
+# unknown (dasa in uisp)
+# reset=rts sck=dtr mosi=txd miso=cts
+
+programmer
+ id = "dasa";
+ desc = "serial port banging, reset=rts sck=dtr mosi=txd miso=cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = 7;
+ sck = 4;
+ mosi = 3;
+ miso = 8;
+;
+
+# unknown (dasa3 in uisp)
+# reset=!dtr sck=rts mosi=txd miso=cts
+
+programmer
+ id = "dasa3";
+ desc = "serial port banging, reset=!dtr sck=rts mosi=txd miso=cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = ~4;
+ sck = 7;
+ mosi = 3;
+ miso = 8;
+;
+
+# C2N232i (jumper configuration "auto")
+# reset=dtr sck=!rts mosi=!txd miso=!cts
+
+programmer
+ id = "c2n232i";
+ desc = "serial port banging, reset=dtr sck=!rts mosi=!txd miso=!cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = 4;
+ sck = ~7;
+ mosi = ~3;
+ miso = ~8;
+;
+
+#
+# PART DEFINITIONS
+#
+
+#------------------------------------------------------------
+# ATtiny11
+#------------------------------------------------------------
+
+# This is an HVSP-only device.
+
+part
+ id = "t11";
+ desc = "ATtiny11";
+ stk500_devcode = 0x11;
+ signature = 0x1e 0x90 0x04;
+ chip_erase_delay = 20000;
+
+ timeout = 200;
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 64;
+ blocksize = 64;
+ readsize = 256;
+ delay = 5;
+ ;
+
+ memory "flash"
+ size = 1024;
+ blocksize = 128;
+ readsize = 256;
+ delay = 3;
+ ;
+
+ memory "signature"
+ size = 3;
+ ;
+
+ memory "lock"
+ size = 1;
+ ;
+
+ memory "calibration"
+ size = 1;
+ ;
+
+ memory "fuse"
+ size = 1;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny12
+#------------------------------------------------------------
+
+part
+ id = "t12";
+ desc = "ATtiny12";
+ stk500_devcode = 0x12;
+ avr910_devcode = 0x55;
+ signature = 0x1e 0x90 0x05;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 8;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4500;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 5;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny13
+#------------------------------------------------------------
+
+part
+ id = "t13";
+ desc = "ATtiny13";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x0E, 0x1E;
+ eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x0E, 0xB4, 0x0E, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x14;
+ signature = 0x1e 0x90 0x07;
+ chip_erase_delay = 4000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 90;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 0;
+
+ memory "eeprom"
+ size = 64;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 5;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 1024;
+ page_size = 32;
+ num_pages = 32;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny15
+#------------------------------------------------------------
+
+part
+ id = "t15";
+ desc = "ATtiny15";
+ stk500_devcode = 0x13;
+ avr910_devcode = 0x56;
+ signature = 0x1e 0x90 0x06;
+ chip_erase_delay = 8200;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 5;
+ synchcycles = 6;
+ latchcycles = 16;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 8200;
+ max_write_delay = 8200;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4100;
+ max_write_delay = 4100;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 5;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o o x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x i i i i 1 1 i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+;
+
+#------------------------------------------------------------
+# AT90s1200
+#------------------------------------------------------------
+
+part
+ id = "1200";
+ desc = "AT90S1200";
+ is_at90s1200 = yes;
+ stk500_devcode = 0x33;
+ avr910_devcode = 0x13;
+ signature = 0x1e 0x90 0x01;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 1;
+ bytedelay = 0;
+ pollindex = 0;
+ pollvalue = 0xFF;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 32;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x02;
+ delay = 15;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s4414
+#------------------------------------------------------------
+
+part
+ id = "4414";
+ desc = "AT90S4414";
+ stk500_devcode = 0x50;
+ avr910_devcode = 0x28;
+ signature = 0x1e 0x92 0x01;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s2313
+#------------------------------------------------------------
+
+part
+ id = "2313";
+ desc = "AT90S2313";
+ stk500_devcode = 0x40;
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x91 0x01;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 2048;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x i i x",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s2333
+#------------------------------------------------------------
+
+part
+ id = "2333";
+##### WARNING: No XML file for device 'AT90S2333'! #####
+ desc = "AT90S2333";
+ stk500_devcode = 0x42;
+ avr910_devcode = 0x34;
+ signature = 0x1e 0x91 0x05;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ pwroff_after_write = yes;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# AT90s2343 (also AT90s2323 and ATtiny22)
+#------------------------------------------------------------
+
+part
+ id = "2343";
+ desc = "AT90S2343";
+ stk500_devcode = 0x43;
+ avr910_devcode = 0x4c;
+ signature = 0x1e 0x91 0x03;
+ chip_erase_delay = 18000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 0;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 128;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o x x x x o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o x x x x o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# AT90s4433
+#------------------------------------------------------------
+
+part
+ id = "4433";
+ desc = "AT90S4433";
+ stk500_devcode = 0x51;
+ avr910_devcode = 0x30;
+ signature = 0x1e 0x92 0x03;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ pwroff_after_write = yes;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s4434
+#------------------------------------------------------------
+
+part
+ id = "4434";
+##### WARNING: No XML file for device 'AT90S4434'! #####
+ desc = "AT90S4434";
+ stk500_devcode = 0x52;
+ avr910_devcode = 0x6c;
+ signature = 0x1e 0x92 0x02;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s8515
+#------------------------------------------------------------
+
+part
+ id = "8515";
+ desc = "AT90S8515";
+ stk500_devcode = 0x60;
+ avr910_devcode = 0x38;
+ signature = 0x1e 0x93 0x01;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 8192;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s8535
+#------------------------------------------------------------
+
+part
+ id = "8535";
+ desc = "AT90S8535";
+ stk500_devcode = 0x61;
+ avr910_devcode = 0x68;
+ signature = 0x1e 0x93 0x03;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 8192;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x x o";
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o x x x x x x";
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega103
+#------------------------------------------------------------
+
+part
+ id = "m103";
+ desc = "ATmega103";
+ stk500_devcode = 0xB1;
+ avr910_devcode = 0x41;
+ signature = 0x1e 0x97 0x01;
+ chip_erase_delay = 112000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x8E, 0x9E, 0x2E, 0x3E, 0xAE, 0xBE,
+ 0x4E, 0x5E, 0xCE, 0xDE, 0x6E, 0x7E, 0xEE, 0xDE,
+ 0x66, 0x76, 0xE6, 0xF6, 0x6A, 0x7A, 0xEA, 0x7A,
+ 0x7F, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 10;
+
+ memory "eeprom"
+ size = 4096;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 22000;
+ max_write_delay = 56000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x11;
+ delay = 70;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o x o 1 o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 i 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega64
+#------------------------------------------------------------
+
+part
+ id = "m64";
+ desc = "ATmega64";
+ has_jtag = yes;
+ stk500_devcode = 0xA0;
+ avr910_devcode = 0x45;
+ signature = 0x1e 0x96 0x02;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x22;
+ spmcr = 0x68;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+
+#------------------------------------------------------------
+# ATmega128
+#------------------------------------------------------------
+
+part
+ id = "m128";
+ desc = "ATmega128";
+ has_jtag = yes;
+ stk500_devcode = 0xB2;
+ avr910_devcode = 0x43;
+ signature = 0x1e 0x97 0x02;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x22;
+ spmcr = 0x68;
+ rampz = 0x3b;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90CAN128
+#------------------------------------------------------------
+
+part
+ id = "c128";
+ desc = "AT90CAN128";
+ has_jtag = yes;
+ stk500_devcode = 0xB3;
+# avr910_devcode = 0x43;
+ signature = 0x1e 0x97 0x81;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ eecr = 0x3f;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90CAN64
+#------------------------------------------------------------
+
+part
+ id = "c64";
+ desc = "AT90CAN64";
+ has_jtag = yes;
+ stk500_devcode = 0xB3;
+# avr910_devcode = 0x43;
+ signature = 0x1e 0x96 0x81;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ eecr = 0x3f;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90CAN32
+#------------------------------------------------------------
+
+part
+ id = "c32";
+ desc = "AT90CAN32";
+ has_jtag = yes;
+ stk500_devcode = 0xB3;
+# avr910_devcode = 0x43;
+ signature = 0x1e 0x95 0x81;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ eecr = 0x3f;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 256;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega16
+#------------------------------------------------------------
+
+part
+ id = "m16";
+ desc = "ATmega16";
+ has_jtag = yes;
+ stk500_devcode = 0x82;
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x94 0x03;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 100;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "calibration"
+ size = 4;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega164P
+#------------------------------------------------------------
+
+# close to ATmega16
+
+part parent "m16"
+ id = "m164p";
+ desc = "ATmega164P";
+ signature = 0x1e 0x94 0x0a;
+
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ allowfullpagebitstream = no;
+ chip_erase_delay = 55000;
+
+ ocdrev = 3;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega324P
+#------------------------------------------------------------
+
+# similar to ATmega164P
+
+part
+ id = "m324p";
+ desc = "ATmega324P";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x95 0x08;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega324PA
+#------------------------------------------------------------
+
+# similar to ATmega324P
+
+part parent "m324p"
+ id = "m324pa";
+ desc = "ATmega324PA";
+ signature = 0x1e 0x95 0x11;
+
+ ocdrev = 3;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega644
+#------------------------------------------------------------
+
+# similar to ATmega164
+
+part
+ id = "m644";
+ desc = "ATmega644";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x96 0x09;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega644P
+#------------------------------------------------------------
+
+# similar to ATmega164p
+
+part parent "m644"
+ id = "m644p";
+ desc = "ATmega644P";
+ signature = 0x1e 0x96 0x0a;
+
+ ocdrev = 3;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega1284
+#------------------------------------------------------------
+
+# similar to ATmega164
+
+part
+ id = "m1284";
+ desc = "ATmega1284";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x97 0x06;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega1284P
+#------------------------------------------------------------
+
+# similar to ATmega164p
+
+part
+ id = "m1284p";
+ desc = "ATmega1284P";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x97 0x05;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega162
+#------------------------------------------------------------
+
+part
+ id = "m162";
+ desc = "ATmega162";
+ has_jtag = yes;
+ stk500_devcode = 0x83;
+ avr910_devcode = 0x63;
+ signature = 0x1e 0x94 0x04;
+ chip_erase_delay = 9000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+
+ idr = 0x04;
+ spmcr = 0x57;
+ allowfullpagebitstream = yes;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ ocdrev = 2;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+
+ read = "0 0 1 1 0 0 0 0 0 0 x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+;
+
+
+
+#------------------------------------------------------------
+# ATmega163
+#------------------------------------------------------------
+
+part
+ id = "m163";
+ desc = "ATmega163";
+ stk500_devcode = 0x81;
+ avr910_devcode = 0x64;
+ signature = 0x1e 0x94 0x02;
+ chip_erase_delay = 32000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 30;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 2;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 2;
+
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x11;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o x x o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i 1 1 i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x x x x x 1 o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x 0 x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega169
+#------------------------------------------------------------
+
+part
+ id = "m169";
+ desc = "ATmega169";
+ has_jtag = yes;
+ stk500_devcode = 0x85;
+ avr910_devcode = 0x78;
+ signature = 0x1e 0x94 0x05;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega329
+#------------------------------------------------------------
+
+part
+ id = "m329";
+ desc = "ATmega329";
+ has_jtag = yes;
+# stk500_devcode = 0x85; # no STK500 support, only STK500v2
+# avr910_devcode = 0x?; # try the ATmega169 one:
+ avr910_devcode = 0x75;
+ signature = 0x1e 0x95 0x03;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega329P
+#------------------------------------------------------------
+# Identical to ATmega329 except of the signature
+
+part parent "m329"
+ id = "m329p";
+ desc = "ATmega329P";
+ signature = 0x1e 0x95 0x0b;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega3290
+#------------------------------------------------------------
+
+# identical to ATmega329
+
+part parent "m329"
+ id = "m3290";
+ desc = "ATmega3290";
+ signature = 0x1e 0x95 0x04;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega3290P
+#------------------------------------------------------------
+
+# identical to ATmega3290 except of the signature
+
+part parent "m3290"
+ id = "m3290p";
+ desc = "ATmega3290P";
+ signature = 0x1e 0x95 0x0c;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega649
+#------------------------------------------------------------
+
+part
+ id = "m649";
+ desc = "ATmega649";
+ has_jtag = yes;
+# stk500_devcode = 0x85; # no STK500 support, only STK500v2
+# avr910_devcode = 0x?; # try the ATmega169 one:
+ avr910_devcode = 0x75;
+ signature = 0x1e 0x96 0x03;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega6490
+#------------------------------------------------------------
+
+# identical to ATmega649
+
+part parent "m649"
+ id = "m6490";
+ desc = "ATmega6490";
+ signature = 0x1e 0x96 0x04;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega32
+#------------------------------------------------------------
+
+part
+ id = "m32";
+ desc = "ATmega32";
+ has_jtag = yes;
+ stk500_devcode = 0x91;
+ avr910_devcode = 0x72;
+ signature = 0x1e 0x95 0x02;
+ chip_erase_delay = 9000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega161
+#------------------------------------------------------------
+
+part
+ id = "m161";
+ desc = "ATmega161";
+ stk500_devcode = 0x80;
+ avr910_devcode = 0x60;
+ signature = 0x1e 0x94 0x01;
+ chip_erase_delay = 28000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 30;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 2;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 2;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 3400;
+ max_write_delay = 3400;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 5;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 14000;
+ max_write_delay = 14000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 16;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "fuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x o x o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x 1 i 1 i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega8
+#------------------------------------------------------------
+
+part
+ id = "m8";
+ desc = "ATmega8";
+ stk500_devcode = 0x70;
+ avr910_devcode = 0x76;
+ signature = 0x1e 0x93 0x07;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 10000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ page_size = 4;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega8515
+#------------------------------------------------------------
+
+part
+ id = "m8515";
+ desc = "ATmega8515";
+ stk500_devcode = 0x63;
+ avr910_devcode = 0x3A;
+ signature = 0x1e 0x93 0x06;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+
+#------------------------------------------------------------
+# ATmega8535
+#------------------------------------------------------------
+
+part
+ id = "m8535";
+ desc = "ATmega8535";
+ stk500_devcode = 0x64;
+ avr910_devcode = 0x69;
+ signature = 0x1e 0x93 0x08;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATtiny26
+#------------------------------------------------------------
+
+part
+ id = "t26";
+ desc = "ATtiny26";
+ stk500_devcode = 0x21;
+ avr910_devcode = 0x5e;
+ signature = 0x1e 0x91 0x09;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 16;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x x x x i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny261
+#------------------------------------------------------------
+# Close to ATtiny26
+
+part
+ id = "t261";
+ desc = "ATtiny261";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x00, 0x10;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+# stk500_devcode = 0x21;
+# avr910_devcode = 0x5e;
+ signature = 0x1e 0x91 0x0c;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 4000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ size = 128;
+ page_size = 4;
+ num_pages = 32;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny461
+#------------------------------------------------------------
+# Close to ATtiny261
+
+part
+ id = "t461";
+ desc = "ATtiny461";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x00, 0x10;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+# stk500_devcode = 0x21;
+# avr910_devcode = 0x5e;
+ signature = 0x1e 0x92 0x08;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 4000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ size = 256;
+ page_size = 4;
+ num_pages = 64;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny861
+#------------------------------------------------------------
+# Close to ATtiny461
+
+part
+ id = "t861";
+ desc = "ATtiny861";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x00, 0x10;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+# stk500_devcode = 0x21;
+# avr910_devcode = 0x5e;
+ signature = 0x1e 0x93 0x0d;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 4000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ size = 512;
+ num_pages = 128;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny28
+#------------------------------------------------------------
+
+# This is an HVPP-only device.
+
+part
+ id = "t28";
+ desc = "ATtiny28";
+ stk500_devcode = 0x22;
+ avr910_devcode = 0x5c;
+ signature = 0x1e 0x91 0x07;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "flash"
+ size = 2048;
+ page_size = 2;
+ readsize = 256;
+ delay = 5;
+ ;
+
+ memory "signature"
+ size = 3;
+ ;
+
+ memory "lock"
+ size = 1;
+ ;
+
+ memory "calibration"
+ size = 1;
+ ;
+
+ memory "fuse"
+ size = 1;
+ ;
+;
+
+
+
+#------------------------------------------------------------
+# ATmega48
+#------------------------------------------------------------
+
+part
+ id = "m48";
+ desc = "ATmega48";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x59;
+# avr910_devcode = 0x;
+ signature = 0x1e 0x92 0x05;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 45000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 256;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega48P
+#------------------------------------------------------------
+
+part parent "m48"
+ id = "m48p";
+ desc = "ATmega48P";
+ signature = 0x1e 0x92 0x0a;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega48PB
+#------------------------------------------------------------
+
+part parent "m48"
+ id = "m48pb";
+ desc = "ATmega48PB";
+ signature = 0x1e 0x92 0x10;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega88
+#------------------------------------------------------------
+
+part
+ id = "m88";
+ desc = "ATmega88";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x73;
+# avr910_devcode = 0x;
+ signature = 0x1e 0x93 0x0a;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 512;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega88P
+#------------------------------------------------------------
+
+part parent "m88"
+ id = "m88p";
+ desc = "ATmega88P";
+ signature = 0x1e 0x93 0x0f;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega88PB
+#------------------------------------------------------------
+
+part parent "m88"
+ id = "m88pb";
+ desc = "ATmega88PB";
+ signature = 0x1e 0x93 0x16;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega168
+#------------------------------------------------------------
+
+part
+ id = "m168";
+ desc = "ATmega168";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x86;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x94 0x06;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 512;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+;
+
+#------------------------------------------------------------
+# ATmega168P
+#------------------------------------------------------------
+
+part parent "m168"
+ id = "m168p";
+ desc = "ATmega168P";
+ signature = 0x1e 0x94 0x0b;
+
+ ocdrev = 1;
+;
+
+#------------------------------------------------------------
+# ATmega168PB
+#------------------------------------------------------------
+
+part parent "m168"
+ id = "m168pb";
+ desc = "ATmega168PB";
+ signature = 0x1e 0x94 0x15;
+
+ ocdrev = 1;
+;
+
+#------------------------------------------------------------
+# ATtiny88
+#------------------------------------------------------------
+
+part
+ id = "t88";
+ desc = "ATtiny88";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x73;
+# avr910_devcode = 0x;
+ signature = 0x1e 0x93 0x11;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 64;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 64;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega328
+#------------------------------------------------------------
+
+part
+ id = "m328";
+ desc = "ATmega328";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x86;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x95 0x14;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 1024;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+;
+
+part parent "m328"
+ id = "m328p";
+ desc = "ATmega328P";
+ signature = 0x1e 0x95 0x0F;
+
+ ocdrev = 1;
+;
+
+#------------------------------------------------------------
+# ATmega32m1
+#------------------------------------------------------------
+
+part parent "m328"
+ id = "m32m1";
+ desc = "ATmega32M1";
+ # stk500_devcode = 0x;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x95 0x84;
+ bs2 = 0xe2;
+
+ memory "efuse"
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x i i i i i i";
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny2313
+#------------------------------------------------------------
+
+part
+ id = "t2313";
+ desc = "ATtiny2313";
+ has_debugwire = yes;
+ flash_instr = 0xB2, 0x0F, 0x1F;
+ eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x23;
+## Use the ATtiny26 devcode:
+ avr910_devcode = 0x5e;
+ signature = 0x1e 0x91 0x0a;
+ pagel = 0xD4;
+ bs2 = 0xD6;
+ reset = io;
+ chip_erase_delay = 9000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
+ 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
+ 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
+ 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 0;
+
+ memory "eeprom"
+ size = 128;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny2313 has Signature Bytes: 0x1E 0x91 0x0A.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+# The Tiny2313 has calibration data for both 4 MHz and 8 MHz.
+# The information in the data sheet of April/2004 is wrong, this works:
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny4313
+#------------------------------------------------------------
+
+part
+ id = "t4313";
+ desc = "ATtiny4313";
+ has_debugwire = yes;
+ flash_instr = 0xB2, 0x0F, 0x1F;
+ eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x23;
+## Use the ATtiny26 devcode:
+ avr910_devcode = 0x5e;
+ signature = 0x1e 0x92 0x0d;
+ pagel = 0xD4;
+ bs2 = 0xD6;
+ reset = io;
+ chip_erase_delay = 9000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
+ 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
+ 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
+ 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 0;
+
+ memory "eeprom"
+ size = 256;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny4313 has Signature Bytes: 0x1E 0x92 0x0D.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM2
+#------------------------------------------------------------
+
+part
+ id = "pwm2";
+ desc = "AT90PWM2";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x65;
+## avr910_devcode = ?;
+ signature = 0x1e 0x93 0x81;
+ pagel = 0xD8;
+ bs2 = 0xE2;
+ reset = io;
+ chip_erase_delay = 9000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+# AT90PWM2 has Signature Bytes: 0x1E 0x93 0x81.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM3
+#------------------------------------------------------------
+
+# Completely identical to AT90PWM2 (including the signature!)
+
+part parent "pwm2"
+ id = "pwm3";
+ desc = "AT90PWM3";
+ ;
+
+#------------------------------------------------------------
+# AT90PWM2B
+#------------------------------------------------------------
+# Same as AT90PWM2 but different signature.
+
+part parent "pwm2"
+ id = "pwm2b";
+ desc = "AT90PWM2B";
+ signature = 0x1e 0x93 0x83;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM3B
+#------------------------------------------------------------
+
+# Completely identical to AT90PWM2B (including the signature!)
+
+part parent "pwm2b"
+ id = "pwm3b";
+ desc = "AT90PWM3B";
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM316
+#------------------------------------------------------------
+
+# Similar to AT90PWM3B, but with 16 kiB flash, 512 B EEPROM, and 1024 B SRAM.
+
+part parent "pwm3b"
+ id = "pwm316";
+ desc = "AT90PWM316";
+ signature = 0x1e 0x94 0x83;
+
+ ocdrev = 1;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM216
+#------------------------------------------------------------
+# Completely identical to AT90PWM316 (including the signature!)
+
+part parent "pwm316"
+ id = "pwm216";
+ desc = "AT90PWM216";
+ ;
+
+#------------------------------------------------------------
+# ATtiny25
+#------------------------------------------------------------
+
+part
+ id = "t25";
+ desc = "ATtiny25";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x02, 0x12;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x91 0x08;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 128;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny25 has Signature Bytes: 0x1E 0x91 0x08.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny45
+#------------------------------------------------------------
+
+part
+ id = "t45";
+ desc = "ATtiny45";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x02, 0x12;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x92 0x06;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 256;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny45 has Signature Bytes: 0x1E 0x92 0x08. (Data sheet 2586C-AVR-06/05 (doc2586.pdf) indicates otherwise!)
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny85
+#------------------------------------------------------------
+
+part
+ id = "t85";
+ desc = "ATtiny85";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x02, 0x12;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x93 0x0b;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 512;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny85 has Signature Bytes: 0x1E 0x93 0x08.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega640
+#------------------------------------------------------------
+# Almost same as ATmega1280, except for different memory sizes
+
+part
+ id = "m640";
+ desc = "ATmega640";
+ signature = 0x1e 0x96 0x08;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega1280
+#------------------------------------------------------------
+
+part
+ id = "m1280";
+ desc = "ATmega1280";
+ signature = 0x1e 0x97 0x03;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega1281
+#------------------------------------------------------------
+# Identical to ATmega1280
+
+part parent "m1280"
+ id = "m1281";
+ desc = "ATmega1281";
+ signature = 0x1e 0x97 0x04;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega2560
+#------------------------------------------------------------
+
+part
+ id = "m2560";
+ desc = "ATmega2560";
+ signature = 0x1e 0x98 0x01;
+ has_jtag = yes;
+ stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 4;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 262144;
+ page_size = 256;
+ num_pages = 1024;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ load_ext_addr = " 0 1 0 0 1 1 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 a16",
+ " 0 0 0 0 0 0 0 0";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega2561
+#------------------------------------------------------------
+
+part parent "m2560"
+ id = "m2561";
+ desc = "ATmega2561";
+ signature = 0x1e 0x98 0x02;
+
+ ocdrev = 4;
+ ;
+
+#------------------------------------------------------------
+# ATmega128RFA1
+#------------------------------------------------------------
+# Identical to ATmega2561 but half the ROM
+
+part parent "m2561"
+ id = "m128rfa1";
+ desc = "ATmega128RFA1";
+ signature = 0x1e 0xa7 0x01;
+ chip_erase_delay = 55000;
+ bs2 = 0xE2;
+
+ ocdrev = 3;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 50000;
+ max_write_delay = 50000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 256;
+ readsize = 256;
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega256RFR2
+#------------------------------------------------------------
+
+part parent "m2561"
+ id = "m256rfr2";
+ desc = "ATmega256RFR2";
+ signature = 0x1e 0xa8 0x02;
+ chip_erase_delay = 18500;
+ bs2 = 0xE2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 8192;
+ min_write_delay = 13000;
+ max_write_delay = 13000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+
+ ocdrev = 4;
+ ;
+
+#------------------------------------------------------------
+# ATmega128RFR2
+#------------------------------------------------------------
+
+part parent "m128rfa1"
+ id = "m128rfr2";
+ desc = "ATmega128RFR2";
+ signature = 0x1e 0xa7 0x02;
+
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega64RFR2
+#------------------------------------------------------------
+
+part parent "m128rfa1"
+ id = "m64rfr2";
+ desc = "ATmega64RFR2";
+ signature = 0x1e 0xa6 0x02;
+
+
+ ocdrev = 3;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 50000;
+ max_write_delay = 50000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 13000;
+ max_write_delay = 13000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+
+ ;
+
+#------------------------------------------------------------
+# ATmega2564RFR2
+#------------------------------------------------------------
+
+part parent "m256rfr2"
+ id = "m2564rfr2";
+ desc = "ATmega2564RFR2";
+ signature = 0x1e 0xa8 0x03;
+ ;
+
+#------------------------------------------------------------
+# ATmega1284RFR2
+#------------------------------------------------------------
+
+part parent "m128rfr2"
+ id = "m1284rfr2";
+ desc = "ATmega1284RFR2";
+ signature = 0x1e 0xa7 0x03;
+ ;
+
+#------------------------------------------------------------
+# ATmega644RFR2
+#------------------------------------------------------------
+
+part parent "m64rfr2"
+ id = "m644rfr2";
+ desc = "ATmega644RFR2";
+ signature = 0x1e 0xa6 0x03;
+ ;
+
+#------------------------------------------------------------
+# ATtiny24
+#------------------------------------------------------------
+
+part
+ id = "t24";
+ desc = "ATtiny24";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x91 0x0b;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 70;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 128;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny24 has Signature Bytes: 0x1E 0x91 0x0B.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x x x x x x x i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny44
+#------------------------------------------------------------
+
+part
+ id = "t44";
+ desc = "ATtiny44";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x92 0x07;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 70;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 256;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny44 has Signature Bytes: 0x1E 0x92 0x07.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x x x x x x x i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny84
+#------------------------------------------------------------
+
+part
+ id = "t84";
+ desc = "ATtiny84";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x93 0x0c;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 70;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 512;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny84 has Signature Bytes: 0x1E 0x93 0x0C.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x x x x x x x i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny43U
+#------------------------------------------------------------
+
+part
+ id = "t43u";
+ desc = "ATtiny43u";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x92 0x0C;
+ reset = io;
+ chip_erase_delay = 1000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack = 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, 0x4E, 0x5E,
+ 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, 0x06, 0x16, 0x46, 0x56,
+ 0x0A, 0x1A, 0x4A, 0x5A, 0x1E, 0x7C, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 20;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+ memory "eeprom"
+ size = 64;
+ paged = yes;
+ page_size = 4;
+ num_pages = 16;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "0 0 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "0 0 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " 0 0 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 5;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+;
+
+#------------------------------------------------------------
+# ATmega32u4
+#------------------------------------------------------------
+
+part
+ id = "m32u4";
+ desc = "ATmega32U4";
+ signature = 0x1e 0x95 0x87;
+ usbpid = 0x2ff4;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB646
+#------------------------------------------------------------
+
+part
+ id = "usb646";
+ desc = "AT90USB646";
+ signature = 0x1e 0x96 0x82;
+ usbpid = 0x2ff9;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB647
+#------------------------------------------------------------
+# identical to AT90USB646
+
+part parent "usb646"
+ id = "usb647";
+ desc = "AT90USB647";
+ signature = 0x1e 0x96 0x82;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# AT90USB1286
+#------------------------------------------------------------
+
+part
+ id = "usb1286";
+ desc = "AT90USB1286";
+ signature = 0x1e 0x97 0x82;
+ usbpid = 0x2ffb;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB1287
+#------------------------------------------------------------
+# identical to AT90USB1286
+
+part parent "usb1286"
+ id = "usb1287";
+ desc = "AT90USB1287";
+ signature = 0x1e 0x97 0x82;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# AT90USB162
+#------------------------------------------------------------
+
+part
+ id = "usb162";
+ desc = "AT90USB162";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x94 0x82;
+ usbpid = 0x2ffa;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB82
+#------------------------------------------------------------
+# Changes against AT90USB162 (beside IDs)
+# memory "flash"
+# size = 8192;
+# num_pages = 64;
+
+part
+ id = "usb82";
+ desc = "AT90USB82";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x93 0x82;
+ usbpid = 0x2ff7;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 128;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega32U2
+#------------------------------------------------------------
+# Changes against AT90USB162 (beside IDs)
+# memory "flash"
+# size = 32768;
+# num_pages = 256;
+# memory "eeprom"
+# size = 1024;
+# num_pages = 256;
+part
+ id = "m32u2";
+ desc = "ATmega32U2";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x95 0x8a;
+ usbpid = 0x2ff0;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ num_pages = 256;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+#------------------------------------------------------------
+# ATmega16U2
+#------------------------------------------------------------
+# Changes against ATmega32U2 (beside IDs)
+# memory "flash"
+# size = 16384;
+# num_pages = 128;
+# memory "eeprom"
+# size = 512;
+# num_pages = 128;
+part
+ id = "m16u2";
+ desc = "ATmega16U2";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x94 0x89;
+ usbpid = 0x2fef;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega8U2
+#------------------------------------------------------------
+# Changes against ATmega16U2 (beside IDs)
+# memory "flash"
+# size = 8192;
+# page_size = 64;
+# blocksize = 64;
+
+part
+ id = "m8u2";
+ desc = "ATmega8U2";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x93 0x89;
+ usbpid = 0x2fee;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 128;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+#------------------------------------------------------------
+# ATmega325
+#------------------------------------------------------------
+
+part
+ id = "m325";
+ desc = "ATmega325";
+ signature = 0x1e 0x95 0x05;
+ has_jtag = yes;
+# stk500_devcode = 0x??; # No STK500v1 support?
+# avr910_devcode = 0x??; # Try the ATmega16 one
+ avr910_devcode = 0x74;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega645
+#------------------------------------------------------------
+
+part
+ id = "m645";
+ desc = "ATmega645";
+ signature = 0x1E 0x96 0x05;
+ has_jtag = yes;
+# stk500_devcode = 0x??; # No STK500v1 support?
+# avr910_devcode = 0x??; # Try the ATmega16 one
+ avr910_devcode = 0x74;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " 0 0 0 0 0 0 0 0";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega3250
+#------------------------------------------------------------
+
+part parent "m325"
+ id = "m3250";
+ desc = "ATmega3250";
+ signature = 0x1E 0x95 0x06;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega6450
+#------------------------------------------------------------
+
+part parent "m645"
+ id = "m6450";
+ desc = "ATmega6450";
+ signature = 0x1E 0x96 0x06;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# AVR XMEGA family common values
+#------------------------------------------------------------
+
+part
+ id = ".xmega";
+ desc = "AVR XMEGA family common values";
+ has_pdi = yes;
+ nvm_base = 0x01c0;
+ mcu_base = 0x0090;
+
+ memory "signature"
+ size = 3;
+ offset = 0x1000090;
+ ;
+
+ memory "prodsig"
+ size = 0x32;
+ offset = 0x8e0200;
+ page_size = 0x32;
+ readsize = 0x32;
+ ;
+
+ memory "fuse1"
+ size = 1;
+ offset = 0x8f0021;
+ ;
+
+ memory "fuse2"
+ size = 1;
+ offset = 0x8f0022;
+ ;
+
+ memory "fuse4"
+ size = 1;
+ offset = 0x8f0024;
+ ;
+
+ memory "fuse5"
+ size = 1;
+ offset = 0x8f0025;
+ ;
+
+ memory "lock"
+ size = 1;
+ offset = 0x8f0027;
+ ;
+
+ memory "data"
+ # SRAM, only used to supply the offset
+ offset = 0x1000000;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega16A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x16a4u";
+ desc = "ATxmega16A4U";
+ signature = 0x1e 0x94 0x41;
+ usbpid = 0x2fe3;
+
+ memory "eeprom"
+ size = 0x400;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x4000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x803000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x804000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x5000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega16C4
+#------------------------------------------------------------
+
+part parent "x16a4u"
+ id = "x16c4";
+ desc = "ATxmega16C4";
+ signature = 0x1e 0x95 0x44;
+;
+
+#------------------------------------------------------------
+# ATxmega16D4
+#------------------------------------------------------------
+
+part parent "x16a4u"
+ id = "x16d4";
+ desc = "ATxmega16D4";
+ signature = 0x1e 0x94 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega16A4
+#------------------------------------------------------------
+
+part parent "x16a4u"
+ id = "x16a4";
+ desc = "ATxmega16A4";
+ signature = 0x1e 0x94 0x41;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega32A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x32a4u";
+ desc = "ATxmega32A4U";
+ signature = 0x1e 0x95 0x41;
+ usbpid = 0x2fe4;
+
+ memory "eeprom"
+ size = 0x400;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x8000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x807000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x808000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x9000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega32C4
+#------------------------------------------------------------
+
+part parent "x32a4u"
+ id = "x32c4";
+ desc = "ATxmega32C4";
+ signature = 0x1e 0x94 0x43;
+;
+
+#------------------------------------------------------------
+# ATxmega32D4
+#------------------------------------------------------------
+
+part parent "x32a4u"
+ id = "x32d4";
+ desc = "ATxmega32D4";
+ signature = 0x1e 0x95 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega32A4
+#------------------------------------------------------------
+
+part parent "x32a4u"
+ id = "x32a4";
+ desc = "ATxmega32A4";
+ signature = 0x1e 0x95 0x41;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega64A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x64a4u";
+ desc = "ATxmega64A4U";
+ signature = 0x1e 0x96 0x46;
+ usbpid = 0x2fe5;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x10000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x80f000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x810000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x11000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega64C3
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64c3";
+ desc = "ATxmega64C3";
+ signature = 0x1e 0x96 0x49;
+ usbpid = 0x2fd6;
+;
+
+#------------------------------------------------------------
+# ATxmega64D3
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64d3";
+ desc = "ATxmega64D3";
+ signature = 0x1e 0x96 0x4a;
+;
+
+#------------------------------------------------------------
+# ATxmega64D4
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64d4";
+ desc = "ATxmega64D4";
+ signature = 0x1e 0x96 0x47;
+;
+
+#------------------------------------------------------------
+# ATxmega64A1
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64a1";
+ desc = "ATxmega64A1";
+ signature = 0x1e 0x96 0x4e;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega64A1U
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a1u";
+ desc = "ATxmega64A1U";
+ signature = 0x1e 0x96 0x4e;
+ usbpid = 0x2fe8;
+;
+
+#------------------------------------------------------------
+# ATxmega64A3
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a3";
+ desc = "ATxmega64A3";
+ signature = 0x1e 0x96 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega64A3U
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a3u";
+ desc = "ATxmega64A3U";
+ signature = 0x1e 0x96 0x42;
+ usbpid = 0x2fe5;
+;
+
+#------------------------------------------------------------
+# ATxmega64A4
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a4";
+ desc = "ATxmega64A4";
+ signature = 0x1e 0x96 0x46;
+;
+
+#------------------------------------------------------------
+# ATxmega64B1
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64b1";
+ desc = "ATxmega64B1";
+ signature = 0x1e 0x96 0x52;
+ usbpid = 0x2fe1;
+;
+
+#------------------------------------------------------------
+# ATxmega64B3
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64b3";
+ desc = "ATxmega64B3";
+ signature = 0x1e 0x96 0x51;
+ usbpid = 0x2fdf;
+;
+
+#------------------------------------------------------------
+# ATxmega128C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128c3";
+ desc = "ATxmega128C3";
+ signature = 0x1e 0x97 0x52;
+ usbpid = 0x2fd7;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x81e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128D3
+#------------------------------------------------------------
+
+part parent "x128c3"
+ id = "x128d3";
+ desc = "ATxmega128D3";
+ signature = 0x1e 0x97 0x48;
+;
+
+#------------------------------------------------------------
+# ATxmega128D4
+#------------------------------------------------------------
+
+part parent "x128c3"
+ id = "x128d4";
+ desc = "ATxmega128D4";
+ signature = 0x1e 0x97 0x47;
+;
+
+#------------------------------------------------------------
+# ATxmega128A1
+#------------------------------------------------------------
+
+part parent "x128c3"
+ id = "x128a1";
+ desc = "ATxmega128A1";
+ signature = 0x1e 0x97 0x4c;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128A1 revision D
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a1d";
+ desc = "ATxmega128A1revD";
+ signature = 0x1e 0x97 0x41;
+;
+
+#------------------------------------------------------------
+# ATxmega128A1U
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a1u";
+ desc = "ATxmega128A1U";
+ signature = 0x1e 0x97 0x4c;
+ usbpid = 0x2fed;
+;
+
+#------------------------------------------------------------
+# ATxmega128A3
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a3";
+ desc = "ATxmega128A3";
+ signature = 0x1e 0x97 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega128A3U
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a3u";
+ desc = "ATxmega128A3U";
+ signature = 0x1e 0x97 0x42;
+ usbpid = 0x2fe6;
+;
+
+#------------------------------------------------------------
+# ATxmega128A4
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128a4";
+ desc = "ATxmega128A4";
+ signature = 0x1e 0x97 0x46;
+ has_jtag = yes;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x81f000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128a4u";
+ desc = "ATxmega128A4U";
+ signature = 0x1e 0x97 0x46;
+ usbpid = 0x2fde;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x81f000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128B1
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128b1";
+ desc = "ATxmega128B1";
+ signature = 0x1e 0x97 0x4d;
+ usbpid = 0x2fea;
+ has_jtag = yes;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x81e000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128B3
+#------------------------------------------------------------
+
+part parent "x128b1"
+ id = "x128b3";
+ desc = "ATxmega128B3";
+ signature = 0x1e 0x97 0x4b;
+ usbpid = 0x2fe0;
+;
+
+#------------------------------------------------------------
+# ATxmega192C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x192c3";
+ desc = "ATxmega192C3";
+ signature = 0x1e 0x97 0x51;
+ # usbpid = 0x2f??;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x30000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x82e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x830000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x32000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega192D3
+#------------------------------------------------------------
+
+part parent "x192c3"
+ id = "x192d3";
+ desc = "ATxmega192D3";
+ signature = 0x1e 0x97 0x49;
+;
+
+#------------------------------------------------------------
+# ATxmega192A1
+#------------------------------------------------------------
+
+part parent "x192c3"
+ id = "x192a1";
+ desc = "ATxmega192A1";
+ signature = 0x1e 0x97 0x4e;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega192A3
+#------------------------------------------------------------
+
+part parent "x192a1"
+ id = "x192a3";
+ desc = "ATxmega192A3";
+ signature = 0x1e 0x97 0x44;
+;
+
+#------------------------------------------------------------
+# ATxmega192A3U
+#------------------------------------------------------------
+
+part parent "x192a1"
+ id = "x192a3u";
+ desc = "ATxmega192A3U";
+ signature = 0x1e 0x97 0x44;
+ usbpid = 0x2fe7;
+;
+
+#------------------------------------------------------------
+# ATxmega256C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x256c3";
+ desc = "ATxmega256C3";
+ signature = 0x1e 0x98 0x46;
+ usbpid = 0x2fda;
+
+ memory "eeprom"
+ size = 0x1000;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x40000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x83e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x840000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x42000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega256D3
+#------------------------------------------------------------
+
+part parent "x256c3"
+ id = "x256d3";
+ desc = "ATxmega256D3";
+ signature = 0x1e 0x98 0x44;
+;
+
+#------------------------------------------------------------
+# ATxmega256A1
+#------------------------------------------------------------
+
+part parent "x256c3"
+ id = "x256a1";
+ desc = "ATxmega256A1";
+ signature = 0x1e 0x98 0x46;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3";
+ desc = "ATxmega256A3";
+ signature = 0x1e 0x98 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3U
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3u";
+ desc = "ATxmega256A3U";
+ signature = 0x1e 0x98 0x42;
+ usbpid = 0x2fec;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3B
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3b";
+ desc = "ATxmega256A3B";
+ signature = 0x1e 0x98 0x43;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3BU
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3bu";
+ desc = "ATxmega256A3BU";
+ signature = 0x1e 0x98 0x43;
+ usbpid = 0x2fe2;
+;
+
+#------------------------------------------------------------
+# ATxmega384C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x384c3";
+ desc = "ATxmega384C3";
+ signature = 0x1e 0x98 0x45;
+ usbpid = 0x2fdb;
+
+ memory "eeprom"
+ size = 0x1000;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x60000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x85e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x860000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x62000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega384D3
+#------------------------------------------------------------
+
+part parent "x384c3"
+ id = "x384d3";
+ desc = "ATxmega384D3";
+ signature = 0x1e 0x98 0x47;
+;
+
+#------------------------------------------------------------
+# ATxmega8E5
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x8e5";
+ desc = "ATxmega8E5";
+ signature = 0x1e 0x93 0x41;
+
+ memory "eeprom"
+ size = 0x0200;
+ offset = 0x08c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x2000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x800;
+ offset = 0x00801800;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x800;
+ offset = 0x00802000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x2800;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x80;
+ offset = 0x8e0400;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega16E5
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x16e5";
+ desc = "ATxmega16E5";
+ signature = 0x1e 0x94 0x45;
+
+ memory "eeprom"
+ size = 0x0200;
+ offset = 0x08c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x4000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x00803000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x00804000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x5000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x80;
+ offset = 0x8e0400;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega32E5
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x32e5";
+ desc = "ATxmega32E5";
+ signature = 0x1e 0x95 0x4c;
+
+ memory "eeprom"
+ size = 0x0400;
+ offset = 0x08c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x8000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x00807000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x00808000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x9000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x80;
+ offset = 0x8e0400;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# AVR32UC3A0512
+#------------------------------------------------------------
+
+part
+ id = "uc3a0512";
+ desc = "AT32UC3A0512";
+ signature = 0xED 0xC0 0x3F;
+ has_jtag = yes;
+ is_avr32 = yes;
+
+ memory "flash"
+ paged = yes;
+ page_size = 512; # bytes
+ readsize = 512; # bytes
+ num_pages = 1024; # could be set dynamicly
+ size = 0x00080000; # could be set dynamicly
+ offset = 0x80000000;
+ ;
+;
+
+part parent "uc3a0512"
+ id = "ucr2";
+ desc = "deprecated, use 'uc3a0512'";
+;
+
+#------------------------------------------------------------
+# ATtiny1634.
+#------------------------------------------------------------
+
+part
+ id = "t1634";
+ desc = "ATtiny1634";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x86;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x94 0x12;
+ pagel = 0xB3;
+ bs2 = 0xB1;
+ reset = io;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
+ 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
+ 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
+ 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 256;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 5;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 32;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 1 1 1 1 i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+;
+
+#------------------------------------------------------------
+# Common values for reduced core tinys (4/5/9/10/20/40)
+#------------------------------------------------------------
+
+part
+ id = ".reduced_core_tiny";
+ desc = "Common values for reduced core tinys";
+ has_tpi = yes;
+
+ memory "signature"
+ size = 3;
+ offset = 0x3fc0;
+ page_size = 16;
+ ;
+
+ memory "fuse"
+ size = 1;
+ offset = 0x3f40;
+ page_size = 16;
+ blocksize = 4;
+ ;
+
+ memory "calibration"
+ size = 1;
+ offset = 0x3f80;
+ page_size = 16;
+ ;
+
+ memory "lockbits"
+ size = 1;
+ offset = 0x3f00;
+ page_size = 16;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny4
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t4";
+ desc = "ATtiny4";
+ signature = 0x1e 0x8f 0x0a;
+
+ memory "flash"
+ size = 512;
+ offset = 0x4000;
+ page_size = 16;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny5
+#------------------------------------------------------------
+
+part parent "t4"
+ id = "t5";
+ desc = "ATtiny5";
+ signature = 0x1e 0x8f 0x09;
+;
+
+#------------------------------------------------------------
+# ATtiny9
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t9";
+ desc = "ATtiny9";
+ signature = 0x1e 0x90 0x08;
+
+ memory "flash"
+ size = 1024;
+ offset = 0x4000;
+ page_size = 16;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny10
+#------------------------------------------------------------
+
+part parent "t9"
+ id = "t10";
+ desc = "ATtiny10";
+ signature = 0x1e 0x90 0x03;
+;
+
+#------------------------------------------------------------
+# ATtiny20
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t20";
+ desc = "ATtiny20";
+ signature = 0x1e 0x91 0x0F;
+
+ memory "flash"
+ size = 2048;
+ offset = 0x4000;
+ page_size = 16;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny40
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t40";
+ desc = "ATtiny40";
+ signature = 0x1e 0x92 0x0E;
+
+ memory "flash"
+ size = 4096;
+ offset = 0x4000;
+ page_size = 64;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATmega406
+#------------------------------------------------------------
+
+part
+ id = "m406";
+ desc = "ATMEGA406";
+ has_jtag = yes;
+ signature = 0x1e 0x95 0x07;
+
+ # STK500 parameters (parallel programming IO lines)
+ pagel = 0xa7;
+ bs2 = 0xa0;
+ serial = no;
+ parallel = yes;
+
+ # STK500v2 HV programming parameters, from XML
+ pp_controlstack = 0x0e, 0x1e, 0x0f, 0x1f, 0x2e, 0x3e, 0x2f, 0x3f,
+ 0x4e, 0x5e, 0x4f, 0x5f, 0x6e, 0x7e, 0x6f, 0x7f,
+ 0x66, 0x76, 0x67, 0x77, 0x6a, 0x7a, 0x6b, 0x7b,
+ 0xbe, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+
+ # JTAG ICE mkII parameters, also from XML files
+ allowfullpagebitstream = no;
+ enablepageprogramming = yes;
+ idr = 0x51;
+ rampz = 0x00;
+ spmcr = 0x57;
+ eecr = 0x3f;
+
+ memory "eeprom"
+ paged = no;
+ size = 512;
+ page_size = 4;
+ blocksize = 4;
+ readsize = 4;
+ num_pages = 128;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 40960;
+ page_size = 128;
+ blocksize = 128;
+ readsize = 128;
+ num_pages = 320;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ ;
+
+ memory "lockbits"
+ size = 1;
+ ;
+
+ memory "signature"
+ size = 3;
+ ;
+;
+
+
diff --git a/xs/src/avrdude/avrdude.conf.tmp b/xs/src/avrdude/avrdude.conf.tmp
new file mode 100644
index 000000000..82c73afa2
--- /dev/null
+++ b/xs/src/avrdude/avrdude.conf.tmp
@@ -0,0 +1,14984 @@
+# $Id$ -*- text -*-
+#
+# AVRDUDE Configuration File
+#
+# This file contains configuration data used by AVRDUDE which describes
+# the programming hardware pinouts and also provides part definitions.
+# AVRDUDE's "-C" command line option specifies the location of the
+# configuration file. The "-c" option names the programmer configuration
+# which must match one of the entry's "id" parameter. The "-p" option
+# identifies which part AVRDUDE is going to be programming and must match
+# one of the parts' "id" parameter.
+#
+# DO NOT MODIFY THIS FILE. Modifications will be overwritten the next
+# time a "make install" is run. For user-specific additions, use the
+# "-C +filename" commandline option.
+#
+# Possible entry formats are:
+#
+# programmer
+# parent <id> # optional parent
+# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
+# desc = <description> ; # quoted string
+# type = <type>; # programmer type, quoted string
+# # supported programmer types can be listed by "-c ?type"
+# connection_type = parallel | serial | usb
+# baudrate = <num> ; # baudrate for avr910-programmer
+# vcc = <num1> [, <num2> ... ] ; # pin number(s)
+# buff = <num1> [, <num2> ... ] ; # pin number(s)
+# reset = <num> ; # pin number
+# sck = <num> ; # pin number
+# mosi = <num> ; # pin number
+# miso = <num> ; # pin number
+# errled = <num> ; # pin number
+# rdyled = <num> ; # pin number
+# pgmled = <num> ; # pin number
+# vfyled = <num> ; # pin number
+# usbvid = <hexnum>; # USB VID (Vendor ID)
+# usbpid = <hexnum> [, <hexnum> ...] # USB PID (Product ID) (1)
+# usbdev = <interface>; # USB interface or other device info
+# usbvendor = <vendorname>; # USB Vendor Name
+# usbproduct = <productname>; # USB Product Name
+# usbsn = <serialno>; # USB Serial Number
+#
+# To invert a bit, use = ~ <num>, the spaces are important.
+# For a pin list all pins must be inverted.
+# A single pin can be specified as usual = ~ <num>, for lists
+# specify it as follows = ~ ( <num> [, <num2> ... ] ) .
+#
+# (1) Not all programmer types can process a list of PIDs.
+# ;
+#
+# part
+# id = <id> ; # quoted string
+# desc = <description> ; # quoted string
+# has_jtag = <yes/no> ; # part has JTAG i/f
+# has_debugwire = <yes/no> ; # part has debugWire i/f
+# has_pdi = <yes/no> ; # part has PDI i/f
+# has_tpi = <yes/no> ; # part has TPI i/f
+# devicecode = <num> ; # deprecated, use stk500_devcode
+# stk500_devcode = <num> ; # numeric
+# avr910_devcode = <num> ; # numeric
+# signature = <num> <num> <num> ; # signature bytes
+# usbpid = <num> ; # DFU USB PID
+# chip_erase_delay = <num> ; # micro-seconds
+# reset = dedicated | io;
+# retry_pulse = reset | sck;
+# pgm_enable = <instruction format> ;
+# chip_erase = <instruction format> ;
+# chip_erase_delay = <num> ; # chip erase delay (us)
+# # STK500 parameters (parallel programming IO lines)
+# pagel = <num> ; # pin name in hex, i.e., 0xD7
+# bs2 = <num> ; # pin name in hex, i.e., 0xA0
+# serial = <yes/no> ; # can use serial downloading
+# parallel = <yes/no/pseudo>; # can use par. programming
+# # STK500v2 parameters, to be taken from Atmel's XML files
+# timeout = <num> ;
+# stabdelay = <num> ;
+# cmdexedelay = <num> ;
+# synchloops = <num> ;
+# bytedelay = <num> ;
+# pollvalue = <num> ;
+# pollindex = <num> ;
+# predelay = <num> ;
+# postdelay = <num> ;
+# pollmethod = <num> ;
+# mode = <num> ;
+# delay = <num> ;
+# blocksize = <num> ;
+# readsize = <num> ;
+# hvspcmdexedelay = <num> ;
+# # STK500v2 HV programming parameters, from XML
+# pp_controlstack = <num>, <num>, ...; # PP only
+# hvsp_controlstack = <num>, <num>, ...; # HVSP only
+# hventerstabdelay = <num>;
+# progmodedelay = <num>; # PP only
+# latchcycles = <num>;
+# togglevtg = <num>;
+# poweroffdelay = <num>;
+# resetdelayms = <num>;
+# resetdelayus = <num>;
+# hvleavestabdelay = <num>;
+# resetdelay = <num>;
+# synchcycles = <num>; # HVSP only
+# chiperasepulsewidth = <num>; # PP only
+# chiperasepolltimeout = <num>;
+# chiperasetime = <num>; # HVSP only
+# programfusepulsewidth = <num>; # PP only
+# programfusepolltimeout = <num>;
+# programlockpulsewidth = <num>; # PP only
+# programlockpolltimeout = <num>;
+# # JTAG ICE mkII parameters, also from XML files
+# allowfullpagebitstream = <yes/no> ;
+# enablepageprogramming = <yes/no> ;
+# idr = <num> ; # IO addr of IDR (OCD) reg.
+# rampz = <num> ; # IO addr of RAMPZ reg.
+# spmcr = <num> ; # mem addr of SPMC[S]R reg.
+# eecr = <num> ; # mem addr of EECR reg.
+# # (only when != 0x3c)
+# is_at90s1200 = <yes/no> ; # AT90S1200 part
+# is_avr32 = <yes/no> ; # AVR32 part
+#
+# memory <memtype>
+# paged = <yes/no> ; # yes / no
+# size = <num> ; # bytes
+# page_size = <num> ; # bytes
+# num_pages = <num> ; # numeric
+# min_write_delay = <num> ; # micro-seconds
+# max_write_delay = <num> ; # micro-seconds
+# readback_p1 = <num> ; # byte value
+# readback_p2 = <num> ; # byte value
+# pwroff_after_write = <yes/no> ; # yes / no
+# read = <instruction format> ;
+# write = <instruction format> ;
+# read_lo = <instruction format> ;
+# read_hi = <instruction format> ;
+# write_lo = <instruction format> ;
+# write_hi = <instruction format> ;
+# loadpage_lo = <instruction format> ;
+# loadpage_hi = <instruction format> ;
+# writepage = <instruction format> ;
+# ;
+# ;
+#
+# If any of the above parameters are not specified, the default value
+# of 0 is used for numerics or the empty string ("") for string
+# values. If a required parameter is left empty, AVRDUDE will
+# complain.
+#
+# Parts can also inherit parameters from previously defined parts
+# using the following syntax. In this case specified integer and
+# string values override parameter values from the parent part. New
+# memory definitions are added to the definitions inherited from the
+# parent.
+#
+# part parent <id> # quoted string
+# id = <id> ; # quoted string
+# <any set of other parameters from the list above>
+# ;
+#
+# NOTES:
+# * 'devicecode' is the device code used by the STK500 (see codes
+# listed below)
+# * Not all memory types will implement all instructions.
+# * AVR Fuse bits and Lock bits are implemented as a type of memory.
+# * Example memory types are:
+# "flash", "eeprom", "fuse", "lfuse" (low fuse), "hfuse" (high
+# fuse), "signature", "calibration", "lock"
+# * The memory type specified on the avrdude command line must match
+# one of the memory types defined for the specified chip.
+# * The pwroff_after_write flag causes avrdude to attempt to
+# power the device off and back on after an unsuccessful write to
+# the affected memory area if VCC programmer pins are defined. If
+# VCC pins are not defined for the programmer, a message
+# indicating that the device needs a power-cycle is printed out.
+# This flag was added to work around a problem with the
+# at90s4433/2333's; see the at90s4433 errata at:
+#
+# http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf
+#
+# INSTRUCTION FORMATS
+#
+# Instruction formats are specified as a comma seperated list of
+# string values containing information (bit specifiers) about each
+# of the 32 bits of the instruction. Bit specifiers may be one of
+# the following formats:
+#
+# '1' = the bit is always set on input as well as output
+#
+# '0' = the bit is always clear on input as well as output
+#
+# 'x' = the bit is ignored on input and output
+#
+# 'a' = the bit is an address bit, the bit-number matches this bit
+# specifier's position within the current instruction byte
+#
+# 'aN' = the bit is the Nth address bit, bit-number = N, i.e., a12
+# is address bit 12 on input, a0 is address bit 0.
+#
+# 'i' = the bit is an input data bit
+#
+# 'o' = the bit is an output data bit
+#
+# Each instruction must be composed of 32 bit specifiers. The
+# instruction specification closely follows the instruction data
+# provided in Atmel's data sheets for their parts.
+#
+# See below for some examples.
+#
+#
+# The following are STK500 part device codes to use for the
+# "devicecode" field of the part. These came from Atmel's software
+# section avr061.zip which accompanies the application note
+# AVR061 available from:
+#
+# http://www.atmel.com/dyn/resources/prod_documents/doc2525.pdf
+#
+
+#define ATTINY10 0x10 /* the _old_ one that never existed! */
+#define ATTINY11 0x11
+#define ATTINY12 0x12
+#define ATTINY15 0x13
+#define ATTINY13 0x14
+
+#define ATTINY22 0x20
+#define ATTINY26 0x21
+#define ATTINY28 0x22
+#define ATTINY2313 0x23
+
+#define AT90S1200 0x33
+
+#define AT90S2313 0x40
+#define AT90S2323 0x41
+#define AT90S2333 0x42
+#define AT90S2343 0x43
+
+#define AT90S4414 0x50
+#define AT90S4433 0x51
+#define AT90S4434 0x52
+#define ATMEGA48 0x59
+
+#define AT90S8515 0x60
+#define AT90S8535 0x61
+#define AT90C8534 0x62
+#define ATMEGA8515 0x63
+#define ATMEGA8535 0x64
+
+#define ATMEGA8 0x70
+#define ATMEGA88 0x73
+#define ATMEGA168 0x86
+
+#define ATMEGA161 0x80
+#define ATMEGA163 0x81
+#define ATMEGA16 0x82
+#define ATMEGA162 0x83
+#define ATMEGA169 0x84
+
+#define ATMEGA323 0x90
+#define ATMEGA32 0x91
+
+#define ATMEGA64 0xA0
+
+#define ATMEGA103 0xB1
+#define ATMEGA128 0xB2
+#define AT90CAN128 0xB3
+#define AT90CAN64 0xB3
+#define AT90CAN32 0xB3
+
+#define AT86RF401 0xD0
+
+#define AT89START 0xE0
+#define AT89S51 0xE0
+#define AT89S52 0xE1
+
+# The following table lists the devices in the original AVR910
+# appnote:
+# |Device |Signature | Code |
+# +-------+----------+------+
+# |tiny12 | 1E 90 05 | 0x55 |
+# |tiny15 | 1E 90 06 | 0x56 |
+# | | | |
+# | S1200 | 1E 90 01 | 0x13 |
+# | | | |
+# | S2313 | 1E 91 01 | 0x20 |
+# | S2323 | 1E 91 02 | 0x48 |
+# | S2333 | 1E 91 05 | 0x34 |
+# | S2343 | 1E 91 03 | 0x4C |
+# | | | |
+# | S4414 | 1E 92 01 | 0x28 |
+# | S4433 | 1E 92 03 | 0x30 |
+# | S4434 | 1E 92 02 | 0x6C |
+# | | | |
+# | S8515 | 1E 93 01 | 0x38 |
+# | S8535 | 1E 93 03 | 0x68 |
+# | | | |
+# |mega32 | 1E 95 01 | 0x72 |
+# |mega83 | 1E 93 05 | 0x65 |
+# |mega103| 1E 97 01 | 0x41 |
+# |mega161| 1E 94 01 | 0x60 |
+# |mega163| 1E 94 02 | 0x64 |
+
+# Appnote AVR109 also has a table of AVR910 device codes, which
+# lists:
+# dev avr910 signature
+# ATmega8 0x77 0x1E 0x93 0x07
+# ATmega8515 0x3B 0x1E 0x93 0x06
+# ATmega8535 0x6A 0x1E 0x93 0x08
+# ATmega16 0x75 0x1E 0x94 0x03
+# ATmega162 0x63 0x1E 0x94 0x04
+# ATmega163 0x66 0x1E 0x94 0x02
+# ATmega169 0x79 0x1E 0x94 0x05
+# ATmega32 0x7F 0x1E 0x95 0x02
+# ATmega323 0x73 0x1E 0x95 0x01
+# ATmega64 0x46 0x1E 0x96 0x02
+# ATmega128 0x44 0x1E 0x97 0x02
+#
+# These codes refer to "BOOT" device codes which are apparently
+# different than standard device codes, for whatever reasons
+# (often one above the standard code).
+
+# There are several extended versions of AVR910 implementations around
+# in the Internet. These add the following codes (only devices that
+# actually exist are listed):
+
+# ATmega8515 0x3A
+# ATmega128 0x43
+# ATmega64 0x45
+# ATtiny26 0x5E
+# ATmega8535 0x69
+# ATmega32 0x72
+# ATmega16 0x74
+# ATmega8 0x76
+# ATmega169 0x78
+
+#
+# Overall avrdude defaults; suitable for ~/.avrduderc
+#
+default_parallel = "/dev/parport0";
+default_serial = "/dev/ttyS0";
+# default_bitclock = 2.5;
+
+# Turn off safemode by default
+#default_safemode = no;
+
+
+#
+# PROGRAMMER DEFINITIONS
+#
+
+# http://wiring.org.co/
+# Basically STK500v2 protocol, with some glue to trigger the
+# bootloader.
+programmer
+ id = "wiring";
+ desc = "Wiring";
+ type = "wiring";
+ connection_type = serial;
+;
+
+programmer
+ id = "arduino";
+ desc = "Arduino";
+ type = "arduino";
+ connection_type = serial;
+;
+# this will interface with the chips on these programmers:
+#
+# http://real.kiev.ua/old/avreal/en/adapters
+# http://www.amontec.com/jtagkey.shtml, jtagkey-tiny.shtml
+# http://www.olimex.com/dev/arm-usb-ocd.html, arm-usb-tiny.html
+# http://www.ethernut.de/en/hardware/turtelizer/index.html
+# http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html
+# http://dangerousprototypes.com/docs/FT2232_breakout_board
+# http://www.ftdichip.com/Products/Modules/DLPModules.htm,DLP-2232*,DLP-USB1232H
+# http://flashrom.org/FT2232SPI_Programmer
+#
+# The drivers will look for a specific device and use the first one found.
+# If you have mulitple devices, then look for unique information (like SN)
+# And fill that in here.
+#
+# Note that the pin numbers for the main ISP signals (reset, sck,
+# mosi, miso) are fixed and cannot be changed, since they must match
+# the way the Multi-Protocol Synchronous Serial Engine (MPSSE) of
+# these FTDI ICs has been designed.
+
+programmer
+ id = "avrftdi";
+ desc = "FT2232D based generic programmer";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+ usbpid = 0x6010;
+ usbvendor = "";
+ usbproduct = "";
+ usbdev = "A";
+ usbsn = "";
+#ISP-signals - lower ADBUS-Nibble (default)
+ reset = 3;
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+#LED SIGNALs - higher ADBUS-Nibble
+# errled = 4;
+# rdyled = 5;
+# pgmled = 6;
+# vfyled = 7;
+#Buffer Signal - ACBUS - Nibble
+# buff = 8;
+;
+# This is an implementation of the above with a buffer IC (74AC244) and
+# 4 LEDs directly attached, all active low.
+programmer
+ id = "2232HIO";
+ desc = "FT2232H based generic programmer";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+# Note: This PID is reserved for generic H devices and
+# should be programmed into the EEPROM
+# usbpid = 0x8A48;
+ usbpid = 0x6010;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals
+ reset = 3;
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+ buff = ~4;
+#LED SIGNALs
+ errled = ~ 11;
+ rdyled = ~ 14;
+ pgmled = ~ 13;
+ vfyled = ~ 12;
+;
+
+#The FT4232H can be treated as FT2232H, but it has a different USB
+#device ID of 0x6011.
+programmer parent "avrftdi"
+ id = "4232h";
+ desc = "FT4232H based generic programmer";
+ usbpid = 0x6011;
+;
+
+programmer
+ id = "jtagkey";
+ desc = "Amontec JTAGKey, JTAGKey-Tiny and JTAGKey2";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+# Note: This PID is used in all JTAGKey variants
+ usbpid = 0xCFF8;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals => 20 - Pin connector on JTAGKey
+ reset = 3; # TMS 7 violet
+ sck = 0; # TCK 9 white
+ mosi = 1; # TDI 5 green
+ miso = 2; # TDO 13 orange
+ buff = ~4;
+# VTG VREF 1 brown with red tip
+# GND GND 20 black
+# The colors are on the 20 pin breakout cable
+# from Amontec
+;
+
+# UM232H module from FTDI and Glyn.com.au.
+# See helix.air.net.au for detailed usage information.
+# J1: Connect pin 2 and 3 for USB power.
+# J2: Connect pin 2 and 3 for USB power.
+# J2: Pin 7 is SCK
+# : Pin 8 is MOSI
+# : Pin 9 is MISO
+# : Pin 11 is RST
+# : Pin 6 is ground
+# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get
+# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant.
+programmer
+ id = "UM232H";
+ desc = "FT232H based module from FTDI and Glyn.com.au";
+ type = "avrftdi";
+ usbvid = 0x0403;
+# Note: This PID is reserved for generic 232H devices and
+# should be programmed into the EEPROM
+ usbpid = 0x6014;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+ reset = 3;
+;
+
+# C232HM module from FTDI and Glyn.com.au.
+# : Orange is SCK
+# : Yellow is MOSI
+# : Green is MISO
+# : Brown is RST
+# : Black is ground
+# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get
+# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant.
+programmer
+ id = "C232HM";
+ desc = "FT232H based module from FTDI and Glyn.com.au";
+ type = "avrftdi";
+ usbvid = 0x0403;
+# Note: This PID is reserved for generic 232H devices and
+# should be programmed into the EEPROM
+ usbpid = 0x6014;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+#ISP-signals
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+ reset = 3;
+;
+
+
+# On the adapter you can read "O-Link". On the PCB is printed "OpenJTAG v3.1"
+# You can find it as "OpenJTAG ARM JTAG USB" in the internet.
+# (But there are also several projects called Open JTAG, eg.
+# http://www.openjtag.org, which are completely different.)
+# http://www.100ask.net/shop/english.html (website seems to be outdated)
+# http://item.taobao.com/item.htm?id=1559277013
+# http://www.micro4you.com/store/openjtag-arm-jtag-usb.html (schematics!)
+# some other sources which call it O-Link
+# http://www.andahammer.com/olink/
+# http://www.developmentboard.net/31-o-link-debugger.html
+# http://armwerks.com/catalog/o-link-debugger-copy/
+# or just have a look at ebay ...
+# It is basically the same entry as jtagkey with different usb ids.
+programmer parent "jtagkey"
+ id = "o-link";
+ desc = "O-Link, OpenJTAG from www.100ask.net";
+ usbvid = 0x1457;
+ usbpid = 0x5118;
+ usbvendor = "www.100ask.net";
+ usbproduct = "USB<=>JTAG&RS232";
+;
+
+# http://wiki.openmoko.org/wiki/Debug_Board_v3
+programmer
+ id = "openmoko";
+ desc = "Openmoko debug board (v3)";
+ type = "avrftdi";
+ usbvid = 0x1457;
+ usbpid = 0x5118;
+ usbdev = "A";
+ usbvendor = "";
+ usbproduct = "";
+ usbsn = "";
+ reset = 3; # TMS 7
+ sck = 0; # TCK 9
+ mosi = 1; # TDI 5
+ miso = 2; # TDO 13
+;
+
+# Only Rev. A boards.
+# Schematic and user manual: http://www.cs.put.poznan.pl/wswitala/download/pdf/811EVBK.pdf
+programmer
+ id = "lm3s811";
+ desc = "Luminary Micro LM3S811 Eval Board (Rev. A)";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+ usbpid = 0xbcd9;
+ usbvendor = "LMI";
+ usbproduct = "LM3S811 Evaluation Board";
+ usbdev = "A";
+ usbsn = "";
+#ISP-signals - lower ACBUS-Nibble (default)
+ reset = 3;
+ sck = 0;
+ mosi = 1;
+ miso = 2;
+# Enable correct buffers
+ buff = 7;
+;
+
+# submitted as bug #46020
+programmer
+ id = "tumpa";
+ desc = "TIAO USB Multi-Protocol Adapter";
+ type = "avrftdi";
+ connection_type = usb;
+ usbvid = 0x0403;
+ usbpid = 0x8A98;
+ usbdev = "A";
+ usbvendor = "TIAO";
+ usbproduct = "";
+ usbsn = "";
+ sck = 0; # TCK 9
+ mosi = 1; # TDI 5
+ miso = 2; # TDO 13
+ reset = 3; # TMS 7
+;
+
+programmer
+ id = "avrisp";
+ desc = "Atmel AVR ISP";
+ type = "stk500";
+ connection_type = serial;
+;
+
+programmer
+ id = "avrispv2";
+ desc = "Atmel AVR ISP V2";
+ type = "stk500v2";
+ connection_type = serial;
+;
+
+programmer
+ id = "avrispmkII";
+ desc = "Atmel AVR ISP mkII";
+ type = "stk500v2";
+ connection_type = usb;
+;
+
+programmer parent "avrispmkII"
+ id = "avrisp2";
+;
+
+programmer
+ id = "buspirate";
+ desc = "The Bus Pirate";
+ type = "buspirate";
+ connection_type = serial;
+;
+
+programmer
+ id = "buspirate_bb";
+ desc = "The Bus Pirate (bitbang interface, supports TPI)";
+ type = "buspirate_bb";
+ connection_type = serial;
+ # pins are bits in bitbang byte (numbers are 87654321)
+ # 1|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS
+ reset = 1;
+ sck = 3;
+ mosi = 4;
+ miso = 2;
+ #vcc = 7; This is internally set independent of this setting.
+;
+
+# This is supposed to be the "default" STK500 entry.
+# Attempts to select the correct firmware version
+# by probing for it. Better use one of the entries
+# below instead.
+programmer
+ id = "stk500";
+ desc = "Atmel STK500";
+ type = "stk500generic";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500v1";
+ desc = "Atmel STK500 Version 1.x firmware";
+ type = "stk500";
+ connection_type = serial;
+;
+
+programmer
+ id = "mib510";
+ desc = "Crossbow MIB510 programming board";
+ type = "stk500";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500v2";
+ desc = "Atmel STK500 Version 2.x firmware";
+ type = "stk500v2";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500pp";
+ desc = "Atmel STK500 V2 in parallel programming mode";
+ type = "stk500pp";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk500hvsp";
+ desc = "Atmel STK500 V2 in high-voltage serial programming mode";
+ type = "stk500hvsp";
+ connection_type = serial;
+;
+
+programmer
+ id = "stk600";
+ desc = "Atmel STK600";
+ type = "stk600";
+ connection_type = usb;
+;
+
+programmer
+ id = "stk600pp";
+ desc = "Atmel STK600 in parallel programming mode";
+ type = "stk600pp";
+ connection_type = usb;
+;
+
+programmer
+ id = "stk600hvsp";
+ desc = "Atmel STK600 in high-voltage serial programming mode";
+ type = "stk600hvsp";
+ connection_type = usb;
+;
+
+programmer
+ id = "avr910";
+ desc = "Atmel Low Cost Serial Programmer";
+ type = "avr910";
+ connection_type = serial;
+;
+
+programmer
+ id = "ft245r";
+ desc = "FT245R Synchronous BitBang";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 1; # D1
+ sck = 0; # D0
+ mosi = 2; # D2
+ reset = 4; # D4
+;
+
+programmer
+ id = "ft232r";
+ desc = "FT232R Synchronous BitBang";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 1; # RxD
+ sck = 0; # TxD
+ mosi = 2; # RTS
+ reset = 4; # DTR
+;
+
+# see http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega
+programmer
+ id = "bwmega";
+ desc = "BitWizard ftdi_atmega builtin programmer";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 5; # DSR
+ sck = 6; # DCD
+ mosi = 3; # CTS
+ reset = 7; # RI
+;
+
+# see http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html
+# Note: pins are numbered from 1!
+programmer
+ id = "arduino-ft232r";
+ desc = "Arduino: FT232R connected to ISP";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 3; # CTS X3(1)
+ sck = 5; # DSR X3(2)
+ mosi = 6; # DCD X3(3)
+ reset = 7; # RI X3(4)
+;
+
+# website mentioned above uses this id
+programmer parent "arduino-ft232r"
+ id = "diecimila";
+ desc = "alias for arduino-ft232r";
+;
+
+# There is a ATmega328P kit PCB called "uncompatino".
+# This board allows ISP via its on-board FT232R.
+# This is designed like Arduino Duemilanove but has no standard ICPS header.
+# Its 4 pairs of pins are shorted to enable ftdi_syncbb.
+# http://akizukidenshi.com/catalog/g/gP-07487/
+# http://akizukidenshi.com/download/ds/akizuki/k6096_manual_20130816.pdf
+programmer
+ id = "uncompatino";
+ desc = "uncompatino with all pairs of pins shorted";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 3; # cts
+ sck = 5; # dsr
+ mosi = 6; # dcd
+ reset = 7; # ri
+;
+
+# FTDI USB to serial cable TTL-232R-5V with a custom adapter for ICSP
+# http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm
+# http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232R_CABLES.pdf
+# For ICSP pinout see for example http://www.atmel.com/images/doc2562.pdf
+# (Figure 1. ISP6PIN header pinout and Table 1. Connections required for ISP ...)
+# TTL-232R GND 1 Black -> ICPS GND (pin 6)
+# TTL-232R CTS 2 Brown -> ICPS MOSI (pin 4)
+# TTL-232R VCC 3 Red -> ICPS VCC (pin 2)
+# TTL-232R TXD 4 Orange -> ICPS RESET (pin 5)
+# TTL-232R RXD 5 Yellow -> ICPS SCK (pin 3)
+# TTL-232R RTS 6 Green -> ICPS MISO (pin 1)
+# Except for VCC and GND, you can connect arbitual pairs as long as
+# the following table is adjusted.
+programmer
+ id = "ttl232r";
+ desc = "FTDI TTL232R-5V with ICSP adapter";
+ type = "ftdi_syncbb";
+ connection_type = usb;
+ miso = 2; # rts
+ sck = 1; # rxd
+ mosi = 3; # cts
+ reset = 0; # txd
+;
+
+programmer
+ id = "usbasp";
+ desc = "USBasp, http://www.fischl.de/usbasp/";
+ type = "usbasp";
+ connection_type = usb;
+ usbvid = 0x16C0; # VOTI
+ usbpid = 0x05DC; # Obdev's free shared PID
+ usbvendor = "www.fischl.de";
+ usbproduct = "USBasp";
+
+ # following variants are autodetected for id "usbasp"
+
+ # original usbasp from fischl.de
+ # see above "usbasp"
+
+ # old usbasp from fischl.de
+ #usbvid = 0x03EB; # ATMEL
+ #usbpid = 0xC7B4; # (unoffical) USBasp
+ #usbvendor = "www.fischl.de";
+ #usbproduct = "USBasp";
+
+ # NIBObee (only if -P nibobee is given on command line)
+ # see below "nibobee"
+;
+
+programmer
+ id = "nibobee";
+ desc = "NIBObee";
+ type = "usbasp";
+ connection_type = usb;
+ usbvid = 0x16C0; # VOTI
+ usbpid = 0x092F; # NIBObee PID
+ usbvendor = "www.nicai-systems.com";
+ usbproduct = "NIBObee";
+;
+
+programmer
+ id = "usbasp-clone";
+ desc = "Any usbasp clone with correct VID/PID";
+ type = "usbasp";
+ connection_type = usb;
+ usbvid = 0x16C0; # VOTI
+ usbpid = 0x05DC; # Obdev's free shared PID
+ #usbvendor = "";
+ #usbproduct = "";
+;
+
+programmer
+ id = "usbtiny";
+ desc = "USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/";
+ type = "usbtiny";
+ connection_type = usb;
+ usbvid = 0x1781;
+ usbpid = 0x0c9f;
+;
+
+# commercial version of USBtiny, using a separate VID/PID
+programmer
+ id = "ehajo-isp";
+ desc = "avr-isp-programmer from eHaJo, http://www.eHaJo.de";
+ type = "usbtiny";
+ connection_type = usb;
+ usbvid = 0x16D0;
+ usbpid = 0x0BA5;
+;
+
+programmer
+ id = "butterfly";
+ desc = "Atmel Butterfly Development Board";
+ type = "butterfly";
+ connection_type = serial;
+;
+
+programmer
+ id = "avr109";
+ desc = "Atmel AppNote AVR109 Boot Loader";
+ type = "butterfly";
+ connection_type = serial;
+;
+
+programmer
+ id = "avr911";
+ desc = "Atmel AppNote AVR911 AVROSP";
+ type = "butterfly";
+ connection_type = serial;
+;
+
+# suggested in http://forum.mikrokopter.de/topic-post48317.html
+programmer
+ id = "mkbutterfly";
+ desc = "Mikrokopter.de Butterfly";
+ type = "butterfly_mk";
+ connection_type = serial;
+;
+
+programmer parent "mkbutterfly"
+ id = "butterfly_mk";
+;
+
+programmer
+ id = "jtagmkI";
+ desc = "Atmel JTAG ICE (mkI)";
+ baudrate = 115200; # default is 115200
+ type = "jtagmki";
+ connection_type = serial;
+;
+
+# easier to type
+programmer parent "jtagmkI"
+ id = "jtag1";
+;
+
+# easier to type
+programmer parent "jtag1"
+ id = "jtag1slow";
+ baudrate = 19200;
+;
+
+# The JTAG ICE mkII has both, serial and USB connectivity. As it is
+# mostly used through USB these days (AVR Studio 5 only supporting it
+# that way), we make connection_type = usb the default. Users are
+# still free to use a serial port with the -P option.
+
+programmer
+ id = "jtagmkII";
+ desc = "Atmel JTAG ICE mkII";
+ baudrate = 19200; # default is 19200
+ type = "jtagmkii";
+ connection_type = usb;
+;
+
+# easier to type
+programmer parent "jtagmkII"
+ id = "jtag2slow";
+;
+
+# JTAG ICE mkII @ 115200 Bd
+programmer parent "jtag2slow"
+ id = "jtag2fast";
+ baudrate = 115200;
+;
+
+# make the fast one the default, people will love that
+programmer parent "jtag2fast"
+ id = "jtag2";
+;
+
+# JTAG ICE mkII in ISP mode
+programmer
+ id = "jtag2isp";
+ desc = "Atmel JTAG ICE mkII in ISP mode";
+ baudrate = 115200;
+ type = "jtagmkii_isp";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in debugWire mode
+programmer
+ id = "jtag2dw";
+ desc = "Atmel JTAG ICE mkII in debugWire mode";
+ baudrate = 115200;
+ type = "jtagmkii_dw";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in AVR32 mode
+programmer
+ id = "jtagmkII_avr32";
+ desc = "Atmel JTAG ICE mkII im AVR32 mode";
+ baudrate = 115200;
+ type = "jtagmkii_avr32";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in AVR32 mode
+programmer
+ id = "jtag2avr32";
+ desc = "Atmel JTAG ICE mkII im AVR32 mode";
+ baudrate = 115200;
+ type = "jtagmkii_avr32";
+ connection_type = usb;
+;
+
+# JTAG ICE mkII in PDI mode
+programmer
+ id = "jtag2pdi";
+ desc = "Atmel JTAG ICE mkII PDI mode";
+ baudrate = 115200;
+ type = "jtagmkii_pdi";
+ connection_type = usb;
+;
+
+# AVR Dragon in JTAG mode
+programmer
+ id = "dragon_jtag";
+ desc = "Atmel AVR Dragon in JTAG mode";
+ baudrate = 115200;
+ type = "dragon_jtag";
+ connection_type = usb;
+;
+
+# AVR Dragon in ISP mode
+programmer
+ id = "dragon_isp";
+ desc = "Atmel AVR Dragon in ISP mode";
+ baudrate = 115200;
+ type = "dragon_isp";
+ connection_type = usb;
+;
+
+# AVR Dragon in PP mode
+programmer
+ id = "dragon_pp";
+ desc = "Atmel AVR Dragon in PP mode";
+ baudrate = 115200;
+ type = "dragon_pp";
+ connection_type = usb;
+;
+
+# AVR Dragon in HVSP mode
+programmer
+ id = "dragon_hvsp";
+ desc = "Atmel AVR Dragon in HVSP mode";
+ baudrate = 115200;
+ type = "dragon_hvsp";
+ connection_type = usb;
+;
+
+# AVR Dragon in debugWire mode
+programmer
+ id = "dragon_dw";
+ desc = "Atmel AVR Dragon in debugWire mode";
+ baudrate = 115200;
+ type = "dragon_dw";
+ connection_type = usb;
+;
+
+# AVR Dragon in PDI mode
+programmer
+ id = "dragon_pdi";
+ desc = "Atmel AVR Dragon in PDI mode";
+ baudrate = 115200;
+ type = "dragon_pdi";
+ connection_type = usb;
+;
+
+programmer
+ id = "jtag3";
+ desc = "Atmel AVR JTAGICE3 in JTAG mode";
+ type = "jtagice3";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "jtag3pdi";
+ desc = "Atmel AVR JTAGICE3 in PDI mode";
+ type = "jtagice3_pdi";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "jtag3dw";
+ desc = "Atmel AVR JTAGICE3 in debugWIRE mode";
+ type = "jtagice3_dw";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "jtag3isp";
+ desc = "Atmel AVR JTAGICE3 in ISP mode";
+ type = "jtagice3_isp";
+ connection_type = usb;
+ usbpid = 0x2110, 0x2140;
+;
+
+programmer
+ id = "xplainedpro";
+ desc = "Atmel AVR XplainedPro in JTAG mode";
+ type = "jtagice3";
+ connection_type = usb;
+ usbpid = 0x2111;
+;
+
+programmer
+ id = "xplainedmini";
+ desc = "Atmel AVR XplainedMini in ISP mode";
+ type = "jtagice3_isp";
+ connection_type = usb;
+ usbpid = 0x2145;
+;
+
+programmer
+ id = "xplainedmini_dw";
+ desc = "Atmel AVR XplainedMini in debugWIRE mode";
+ type = "jtagice3_dw";
+ connection_type = usb;
+ usbpid = 0x2145;
+;
+
+programmer
+ id = "atmelice";
+ desc = "Atmel-ICE (ARM/AVR) in JTAG mode";
+ type = "jtagice3";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+programmer
+ id = "atmelice_pdi";
+ desc = "Atmel-ICE (ARM/AVR) in PDI mode";
+ type = "jtagice3_pdi";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+programmer
+ id = "atmelice_dw";
+ desc = "Atmel-ICE (ARM/AVR) in debugWIRE mode";
+ type = "jtagice3_dw";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+programmer
+ id = "atmelice_isp";
+ desc = "Atmel-ICE (ARM/AVR) in ISP mode";
+ type = "jtagice3_isp";
+ connection_type = usb;
+ usbpid = 0x2141;
+;
+
+
+programmer
+ id = "pavr";
+ desc = "Jason Kyle's pAVR Serial Programmer";
+ type = "avr910";
+ connection_type = serial;
+;
+
+programmer
+ id = "pickit2";
+ desc = "MicroChip's PICkit2 Programmer";
+ type = "pickit2";
+ connection_type = usb;
+;
+
+programmer
+ id = "flip1";
+ desc = "FLIP USB DFU protocol version 1 (doc7618)";
+ type = "flip1";
+ connection_type = usb;
+;
+
+programmer
+ id = "flip2";
+ desc = "FLIP USB DFU protocol version 2 (AVR4023)";
+ type = "flip2";
+ connection_type = usb;
+;
+
+@HAVE_PARPORT_BEGIN@ Inclusion of the following depends on --enable-parport
+# Parallel port programmers.
+
+programmer
+ id = "bsd";
+ desc = "Brian Dean's Programmer, http://www.bsdhome.com/avrdude/";
+ type = "par";
+ connection_type = parallel;
+ vcc = 2, 3, 4, 5;
+ reset = 7;
+ sck = 8;
+ mosi = 9;
+ miso = 10;
+;
+
+programmer
+ id = "stk200";
+ desc = "STK200";
+ type = "par";
+ connection_type = parallel;
+ buff = 4, 5;
+ sck = 6;
+ mosi = 7;
+ reset = 9;
+ miso = 10;
+;
+
+# The programming dongle used by the popular Ponyprog
+# utility. It is almost similar to the STK200 one,
+# except that there is a LED indicating that the
+# programming is currently in progress.
+
+programmer parent "stk200"
+ id = "pony-stk200";
+ desc = "Pony Prog STK200";
+ pgmled = 8;
+;
+
+programmer
+ id = "dt006";
+ desc = "Dontronics DT006";
+ type = "par";
+ connection_type = parallel;
+ reset = 4;
+ sck = 5;
+ mosi = 2;
+ miso = 11;
+;
+
+programmer parent "dt006"
+ id = "bascom";
+ desc = "Bascom SAMPLE programming cable";
+;
+
+programmer
+ id = "alf";
+ desc = "Nightshade ALF-PgmAVR, http://nightshade.homeip.net/";
+ type = "par";
+ connection_type = parallel;
+ vcc = 2, 3, 4, 5;
+ buff = 6;
+ reset = 7;
+ sck = 8;
+ mosi = 9;
+ miso = 10;
+ errled = 1;
+ rdyled = 14;
+ pgmled = 16;
+ vfyled = 17;
+;
+
+programmer
+ id = "sp12";
+ desc = "Steve Bolt's Programmer";
+ type = "par";
+ connection_type = parallel;
+ vcc = 4,5,6,7,8;
+ reset = 3;
+ sck = 2;
+ mosi = 9;
+ miso = 11;
+;
+
+programmer
+ id = "picoweb";
+ desc = "Picoweb Programming Cable, http://www.picoweb.net/";
+ type = "par";
+ connection_type = parallel;
+ reset = 2;
+ sck = 3;
+ mosi = 4;
+ miso = 13;
+;
+
+programmer
+ id = "abcmini";
+ desc = "ABCmini Board, aka Dick Smith HOTCHIP";
+ type = "par";
+ connection_type = parallel;
+ reset = 4;
+ sck = 3;
+ mosi = 2;
+ miso = 10;
+;
+
+programmer
+ id = "futurlec";
+ desc = "Futurlec.com programming cable.";
+ type = "par";
+ connection_type = parallel;
+ reset = 3;
+ sck = 2;
+ mosi = 1;
+ miso = 10;
+;
+
+
+# From the contributor of the "xil" jtag cable:
+# The "vcc" definition isn't really vcc (the cable gets its power from
+# the programming circuit) but is necessary to switch one of the
+# buffer lines (trying to add it to the "buff" lines doesn't work in
+# avrdude versions before 5.5j).
+# With this, TMS connects to RESET, TDI to MOSI, TDO to MISO and TCK
+# to SCK (plus vcc/gnd of course)
+programmer
+ id = "xil";
+ desc = "Xilinx JTAG cable";
+ type = "par";
+ connection_type = parallel;
+ mosi = 2;
+ sck = 3;
+ reset = 4;
+ buff = 5;
+ miso = 13;
+ vcc = 6;
+;
+
+
+programmer
+ id = "dapa";
+ desc = "Direct AVR Parallel Access cable";
+ type = "par";
+ connection_type = parallel;
+ vcc = 3;
+ reset = 16;
+ sck = 1;
+ mosi = 2;
+ miso = 11;
+;
+
+programmer
+ id = "atisp";
+ desc = "AT-ISP V1.1 programming cable for AVR-SDK1 from <http://micro-research.co.th/> micro-research.co.th";
+ type = "par";
+ connection_type = parallel;
+ reset = ~6;
+ sck = ~8;
+ mosi = ~7;
+ miso = ~10;
+;
+
+programmer
+ id = "ere-isp-avr";
+ desc = "ERE ISP-AVR <http://www.ere.co.th/download/sch050713.pdf>";
+ type = "par";
+ connection_type = parallel;
+ reset = ~4;
+ sck = 3;
+ mosi = 2;
+ miso = 10;
+;
+
+programmer
+ id = "blaster";
+ desc = "Altera ByteBlaster";
+ type = "par";
+ connection_type = parallel;
+ sck = 2;
+ miso = 11;
+ reset = 3;
+ mosi = 8;
+ buff = 14;
+;
+
+# It is almost same as pony-stk200, except vcc on pin 5 to auto
+# disconnect port (download on http://electropol.free.fr/spip/spip.php?article27)
+programmer parent "pony-stk200"
+ id = "frank-stk200";
+ desc = "Frank STK200";
+ buff = ; # delete buff pin assignment
+ vcc = 5;
+;
+
+# The AT98ISP Cable is a simple parallel dongle for AT89 family.
+# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2877
+programmer
+ id = "89isp";
+ desc = "Atmel at89isp cable";
+ type = "par";
+ connection_type = parallel;
+ reset = 17;
+ sck = 1;
+ mosi = 2;
+ miso = 10;
+;
+
+@HAVE_PARPORT_END@
+
+#This programmer bitbangs GPIO lines using the Linux sysfs GPIO interface
+#
+#To enable it set the configuration below to match the GPIO lines connected to the
+#relevant ISP header pins and uncomment the entry definition. In case you don't
+#have the required permissions to edit this system wide config file put the
+#entry in a separate <your name>.conf file and use it with -C+<your name>.conf
+#on the command line.
+#
+#To check if your avrdude build has support for the linuxgpio programmer compiled in,
+#use -c?type on the command line and look for linuxgpio in the list. If it's not available
+#you need pass the --enable-linuxgpio=yes option to configure and recompile avrdude.
+#
+#programmer
+# id = "linuxgpio";
+# desc = "Use the Linux sysfs interface to bitbang GPIO lines";
+# type = "linuxgpio";
+# reset = ?;
+# sck = ?;
+# mosi = ?;
+# miso = ?;
+#;
+
+# some ultra cheap programmers use bitbanging on the
+# serialport.
+#
+# PC - DB9 - Pins for RS232:
+#
+# GND 5 -- |O
+# | O| <- 9 RI
+# DTR 4 <- |O |
+# | O| <- 8 CTS
+# TXD 3 <- |O |
+# | O| -> 7 RTS
+# RXD 2 -> |O |
+# | O| <- 6 DSR
+# DCD 1 -> |O
+#
+# Using RXD is currently not supported.
+# Using RI is not supported under Win32 but is supported under Posix.
+
+# serial ponyprog design (dasa2 in uisp)
+# reset=!txd sck=rts mosi=dtr miso=cts
+
+programmer
+ id = "ponyser";
+ desc = "design ponyprog serial, reset=!txd sck=rts mosi=dtr miso=cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = ~3;
+ sck = 7;
+ mosi = 4;
+ miso = 8;
+;
+
+# Same as above, different name
+# reset=!txd sck=rts mosi=dtr miso=cts
+
+programmer parent "ponyser"
+ id = "siprog";
+ desc = "Lancos SI-Prog <http://www.lancos.com/siprogsch.html>";
+;
+
+# unknown (dasa in uisp)
+# reset=rts sck=dtr mosi=txd miso=cts
+
+programmer
+ id = "dasa";
+ desc = "serial port banging, reset=rts sck=dtr mosi=txd miso=cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = 7;
+ sck = 4;
+ mosi = 3;
+ miso = 8;
+;
+
+# unknown (dasa3 in uisp)
+# reset=!dtr sck=rts mosi=txd miso=cts
+
+programmer
+ id = "dasa3";
+ desc = "serial port banging, reset=!dtr sck=rts mosi=txd miso=cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = ~4;
+ sck = 7;
+ mosi = 3;
+ miso = 8;
+;
+
+# C2N232i (jumper configuration "auto")
+# reset=dtr sck=!rts mosi=!txd miso=!cts
+
+programmer
+ id = "c2n232i";
+ desc = "serial port banging, reset=dtr sck=!rts mosi=!txd miso=!cts";
+ type = "serbb";
+ connection_type = serial;
+ reset = 4;
+ sck = ~7;
+ mosi = ~3;
+ miso = ~8;
+;
+
+#
+# PART DEFINITIONS
+#
+
+#------------------------------------------------------------
+# ATtiny11
+#------------------------------------------------------------
+
+# This is an HVSP-only device.
+
+part
+ id = "t11";
+ desc = "ATtiny11";
+ stk500_devcode = 0x11;
+ signature = 0x1e 0x90 0x04;
+ chip_erase_delay = 20000;
+
+ timeout = 200;
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 64;
+ blocksize = 64;
+ readsize = 256;
+ delay = 5;
+ ;
+
+ memory "flash"
+ size = 1024;
+ blocksize = 128;
+ readsize = 256;
+ delay = 3;
+ ;
+
+ memory "signature"
+ size = 3;
+ ;
+
+ memory "lock"
+ size = 1;
+ ;
+
+ memory "calibration"
+ size = 1;
+ ;
+
+ memory "fuse"
+ size = 1;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny12
+#------------------------------------------------------------
+
+part
+ id = "t12";
+ desc = "ATtiny12";
+ stk500_devcode = 0x12;
+ avr910_devcode = 0x55;
+ signature = 0x1e 0x90 0x05;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 8;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4500;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 5;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny13
+#------------------------------------------------------------
+
+part
+ id = "t13";
+ desc = "ATtiny13";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x0E, 0x1E;
+ eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x0E, 0xB4, 0x0E, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x14;
+ signature = 0x1e 0x90 0x07;
+ chip_erase_delay = 4000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 90;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 0;
+
+ memory "eeprom"
+ size = 64;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 5;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 1024;
+ page_size = 32;
+ num_pages = 32;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 0 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny15
+#------------------------------------------------------------
+
+part
+ id = "t15";
+ desc = "ATtiny15";
+ stk500_devcode = 0x13;
+ avr910_devcode = 0x56;
+ signature = 0x1e 0x90 0x06;
+ chip_erase_delay = 8200;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 5;
+ synchcycles = 6;
+ latchcycles = 16;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 8200;
+ max_write_delay = 8200;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4100;
+ max_write_delay = 4100;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 5;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o o x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x i i i i 1 1 i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+;
+
+#------------------------------------------------------------
+# AT90s1200
+#------------------------------------------------------------
+
+part
+ id = "1200";
+ desc = "AT90S1200";
+ is_at90s1200 = yes;
+ stk500_devcode = 0x33;
+ avr910_devcode = 0x13;
+ signature = 0x1e 0x90 0x01;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 1;
+ bytedelay = 0;
+ pollindex = 0;
+ pollvalue = 0xFF;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 64;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 32;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 1024;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x02;
+ delay = 15;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s4414
+#------------------------------------------------------------
+
+part
+ id = "4414";
+ desc = "AT90S4414";
+ stk500_devcode = 0x50;
+ avr910_devcode = 0x28;
+ signature = 0x1e 0x92 0x01;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s2313
+#------------------------------------------------------------
+
+part
+ id = "2313";
+ desc = "AT90S2313";
+ stk500_devcode = 0x40;
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x91 0x01;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 2048;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x i i x",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s2333
+#------------------------------------------------------------
+
+part
+ id = "2333";
+##### WARNING: No XML file for device 'AT90S2333'! #####
+ desc = "AT90S2333";
+ stk500_devcode = 0x42;
+ avr910_devcode = 0x34;
+ signature = 0x1e 0x91 0x05;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ pwroff_after_write = yes;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# AT90s2343 (also AT90s2323 and ATtiny22)
+#------------------------------------------------------------
+
+part
+ id = "2343";
+ desc = "AT90S2343";
+ stk500_devcode = 0x43;
+ avr910_devcode = 0x4c;
+ signature = 0x1e 0x91 0x03;
+ chip_erase_delay = 18000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
+ 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
+ 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 0;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 50;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 128;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o x x x x o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o o x x x x o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# AT90s4433
+#------------------------------------------------------------
+
+part
+ id = "4433";
+ desc = "AT90S4433";
+ stk500_devcode = 0x51;
+ avr910_devcode = 0x30;
+ signature = 0x1e 0x92 0x03;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ pwroff_after_write = yes;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s4434
+#------------------------------------------------------------
+
+part
+ id = "4434";
+##### WARNING: No XML file for device 'AT90S4434'! #####
+ desc = "AT90S4434";
+ stk500_devcode = 0x52;
+ avr910_devcode = 0x6c;
+ signature = 0x1e 0x92 0x02;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ memory "eeprom"
+ size = 256;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+ ;
+ memory "flash"
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ memory "lock"
+ size = 1;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s8515
+#------------------------------------------------------------
+
+part
+ id = "8515";
+ desc = "AT90S8515";
+ stk500_devcode = 0x60;
+ avr910_devcode = 0x38;
+ signature = 0x1e 0x93 0x01;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 8192;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x7f;
+ readback_p2 = 0x7f;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90s8535
+#------------------------------------------------------------
+
+part
+ id = "8535";
+ desc = "AT90S8535";
+ stk500_devcode = 0x61;
+ avr910_devcode = 0x68;
+ signature = 0x1e 0x93 0x03;
+ chip_erase_delay = 20000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 1;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0x00;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ size = 8192;
+ min_write_delay = 9000;
+ max_write_delay = 20000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ write_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x x o";
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x o o x x x x x x";
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega103
+#------------------------------------------------------------
+
+part
+ id = "m103";
+ desc = "ATmega103";
+ stk500_devcode = 0xB1;
+ avr910_devcode = 0x41;
+ signature = 0x1e 0x97 0x01;
+ chip_erase_delay = 112000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x8E, 0x9E, 0x2E, 0x3E, 0xAE, 0xBE,
+ 0x4E, 0x5E, 0xCE, 0xDE, 0x6E, 0x7E, 0xEE, 0xDE,
+ 0x66, 0x76, 0xE6, 0xF6, 0x6A, 0x7A, 0xEA, 0x7A,
+ 0x7F, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 15;
+ chiperasepolltimeout = 0;
+ programfusepulsewidth = 2;
+ programfusepolltimeout = 0;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 10;
+
+ memory "eeprom"
+ size = 4096;
+ min_write_delay = 4000;
+ max_write_delay = 9000;
+ readback_p1 = 0x80;
+ readback_p2 = 0x7f;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 22000;
+ max_write_delay = 56000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x11;
+ delay = 70;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "fuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x o x o 1 o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 1 i 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x o o x";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega64
+#------------------------------------------------------------
+
+part
+ id = "m64";
+ desc = "ATmega64";
+ has_jtag = yes;
+ stk500_devcode = 0xA0;
+ avr910_devcode = 0x45;
+ signature = 0x1e 0x96 0x02;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x22;
+ spmcr = 0x68;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+
+#------------------------------------------------------------
+# ATmega128
+#------------------------------------------------------------
+
+part
+ id = "m128";
+ desc = "ATmega128";
+ has_jtag = yes;
+ stk500_devcode = 0xB2;
+ avr910_devcode = 0x43;
+ signature = 0x1e 0x97 0x02;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x22;
+ spmcr = 0x68;
+ rampz = 0x3b;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 12;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90CAN128
+#------------------------------------------------------------
+
+part
+ id = "c128";
+ desc = "AT90CAN128";
+ has_jtag = yes;
+ stk500_devcode = 0xB3;
+# avr910_devcode = 0x43;
+ signature = 0x1e 0x97 0x81;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ eecr = 0x3f;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90CAN64
+#------------------------------------------------------------
+
+part
+ id = "c64";
+ desc = "AT90CAN64";
+ has_jtag = yes;
+ stk500_devcode = 0xB3;
+# avr910_devcode = 0x43;
+ signature = 0x1e 0x96 0x81;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ eecr = 0x3f;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90CAN32
+#------------------------------------------------------------
+
+part
+ id = "c32";
+ desc = "AT90CAN32";
+ has_jtag = yes;
+ stk500_devcode = 0xB3;
+# avr910_devcode = 0x43;
+ signature = 0x1e 0x95 0x81;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ eecr = 0x3f;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 256;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega16
+#------------------------------------------------------------
+
+part
+ id = "m16";
+ desc = "ATmega16";
+ has_jtag = yes;
+ stk500_devcode = 0x82;
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x94 0x03;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 100;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "calibration"
+ size = 4;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega164P
+#------------------------------------------------------------
+
+# close to ATmega16
+
+part parent "m16"
+ id = "m164p";
+ desc = "ATmega164P";
+ signature = 0x1e 0x94 0x0a;
+
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ allowfullpagebitstream = no;
+ chip_erase_delay = 55000;
+
+ ocdrev = 3;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega324P
+#------------------------------------------------------------
+
+# similar to ATmega164P
+
+part
+ id = "m324p";
+ desc = "ATmega324P";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x95 0x08;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega324PA
+#------------------------------------------------------------
+
+# similar to ATmega324P
+
+part parent "m324p"
+ id = "m324pa";
+ desc = "ATmega324PA";
+ signature = 0x1e 0x95 0x11;
+
+ ocdrev = 3;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega644
+#------------------------------------------------------------
+
+# similar to ATmega164
+
+part
+ id = "m644";
+ desc = "ATmega644";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x96 0x09;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega644P
+#------------------------------------------------------------
+
+# similar to ATmega164p
+
+part parent "m644"
+ id = "m644p";
+ desc = "ATmega644P";
+ signature = 0x1e 0x96 0x0a;
+
+ ocdrev = 3;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega1284
+#------------------------------------------------------------
+
+# similar to ATmega164
+
+part
+ id = "m1284";
+ desc = "ATmega1284";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x97 0x06;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega1284P
+#------------------------------------------------------------
+
+# similar to ATmega164p
+
+part
+ id = "m1284p";
+ desc = "ATmega1284P";
+ has_jtag = yes;
+ stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
+ avr910_devcode = 0x74;
+ signature = 0x1e 0x97 0x05;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 55000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega162
+#------------------------------------------------------------
+
+part
+ id = "m162";
+ desc = "ATmega162";
+ has_jtag = yes;
+ stk500_devcode = 0x83;
+ avr910_devcode = 0x63;
+ signature = 0x1e 0x94 0x04;
+ chip_erase_delay = 9000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+
+ idr = 0x04;
+ spmcr = 0x57;
+ allowfullpagebitstream = yes;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ ocdrev = 2;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+
+ read = "0 0 1 1 0 0 0 0 0 0 x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+;
+
+
+
+#------------------------------------------------------------
+# ATmega163
+#------------------------------------------------------------
+
+part
+ id = "m163";
+ desc = "ATmega163";
+ stk500_devcode = 0x81;
+ avr910_devcode = 0x64;
+ signature = 0x1e 0x94 0x02;
+ chip_erase_delay = 32000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 30;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 2;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 2;
+
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 16000;
+ max_write_delay = 16000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x11;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o x x o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i 1 1 i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x x x x x 1 o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x 1 1 1 1 1 i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x 0 x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega169
+#------------------------------------------------------------
+
+part
+ id = "m169";
+ desc = "ATmega169";
+ has_jtag = yes;
+ stk500_devcode = 0x85;
+ avr910_devcode = 0x78;
+ signature = 0x1e 0x94 0x05;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega329
+#------------------------------------------------------------
+
+part
+ id = "m329";
+ desc = "ATmega329";
+ has_jtag = yes;
+# stk500_devcode = 0x85; # no STK500 support, only STK500v2
+# avr910_devcode = 0x?; # try the ATmega169 one:
+ avr910_devcode = 0x75;
+ signature = 0x1e 0x95 0x03;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega329P
+#------------------------------------------------------------
+# Identical to ATmega329 except of the signature
+
+part parent "m329"
+ id = "m329p";
+ desc = "ATmega329P";
+ signature = 0x1e 0x95 0x0b;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega3290
+#------------------------------------------------------------
+
+# identical to ATmega329
+
+part parent "m329"
+ id = "m3290";
+ desc = "ATmega3290";
+ signature = 0x1e 0x95 0x04;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega3290P
+#------------------------------------------------------------
+
+# identical to ATmega3290 except of the signature
+
+part parent "m3290"
+ id = "m3290p";
+ desc = "ATmega3290P";
+ signature = 0x1e 0x95 0x0c;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega649
+#------------------------------------------------------------
+
+part
+ id = "m649";
+ desc = "ATmega649";
+ has_jtag = yes;
+# stk500_devcode = 0x85; # no STK500 support, only STK500v2
+# avr910_devcode = 0x?; # try the ATmega169 one:
+ avr910_devcode = 0x75;
+ signature = 0x1e 0x96 0x03;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega6490
+#------------------------------------------------------------
+
+# identical to ATmega649
+
+part parent "m649"
+ id = "m6490";
+ desc = "ATmega6490";
+ signature = 0x1e 0x96 0x04;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega32
+#------------------------------------------------------------
+
+part
+ id = "m32";
+ desc = "ATmega32";
+ has_jtag = yes;
+ stk500_devcode = 0x91;
+ avr910_devcode = 0x72;
+ signature = 0x1e 0x95 0x02;
+ chip_erase_delay = 9000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = yes;
+
+ ocdrev = 2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega161
+#------------------------------------------------------------
+
+part
+ id = "m161";
+ desc = "ATmega161";
+ stk500_devcode = 0x80;
+ avr910_devcode = 0x60;
+ signature = 0x1e 0x94 0x01;
+ chip_erase_delay = 28000;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 30;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 2;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 2;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 3400;
+ max_write_delay = 3400;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 5;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 14000;
+ max_write_delay = 14000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 16;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "fuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x x x x o x o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
+ "x x x x x x x x 1 i 1 i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATmega8
+#------------------------------------------------------------
+
+part
+ id = "m8";
+ desc = "ATmega8";
+ stk500_devcode = 0x70;
+ avr910_devcode = 0x76;
+ signature = 0x1e 0x93 0x07;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 10000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ page_size = 4;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+#------------------------------------------------------------
+# ATmega8515
+#------------------------------------------------------------
+
+part
+ id = "m8515";
+ desc = "ATmega8515";
+ stk500_devcode = 0x63;
+ avr910_devcode = 0x3A;
+ signature = 0x1e 0x93 0x06;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+
+
+#------------------------------------------------------------
+# ATmega8535
+#------------------------------------------------------------
+
+part
+ id = "m8535";
+ desc = "ATmega8535";
+ stk500_devcode = 0x64;
+ avr910_devcode = 0x69;
+ signature = 0x1e 0x93 0x08;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 6;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ mode = 0x04;
+ delay = 20;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 2000;
+ max_write_delay = 2000;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+
+#------------------------------------------------------------
+# ATtiny26
+#------------------------------------------------------------
+
+part
+ id = "t26";
+ desc = "ATtiny26";
+ stk500_devcode = 0x21;
+ avr910_devcode = 0x5e;
+ signature = 0x1e 0x91 0x09;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ mode = 0x04;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 16;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x x x x i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 4;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny261
+#------------------------------------------------------------
+# Close to ATtiny26
+
+part
+ id = "t261";
+ desc = "ATtiny261";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x00, 0x10;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+# stk500_devcode = 0x21;
+# avr910_devcode = 0x5e;
+ signature = 0x1e 0x91 0x0c;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 4000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ size = 128;
+ page_size = 4;
+ num_pages = 32;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x x x a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny461
+#------------------------------------------------------------
+# Close to ATtiny261
+
+part
+ id = "t461";
+ desc = "ATtiny461";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x00, 0x10;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+# stk500_devcode = 0x21;
+# avr910_devcode = 0x5e;
+ signature = 0x1e 0x92 0x08;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 4000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ size = 256;
+ page_size = 4;
+ num_pages = 64;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny861
+#------------------------------------------------------------
+# Close to ATtiny461
+
+part
+ id = "t861";
+ desc = "ATtiny861";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x00, 0x10;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+# stk500_devcode = 0x21;
+# avr910_devcode = 0x5e;
+ signature = 0x1e 0x93 0x0d;
+ pagel = 0xb3;
+ bs2 = 0xb2;
+ chip_erase_delay = 4000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 0;
+
+ pp_controlstack =
+ 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
+ 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
+ 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
+ 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 2;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ size = 512;
+ num_pages = 128;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 x x x x x x x x",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
+ "x x x x x x x x x x x x x x x x";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+;
+
+
+#------------------------------------------------------------
+# ATtiny28
+#------------------------------------------------------------
+
+# This is an HVPP-only device.
+
+part
+ id = "t28";
+ desc = "ATtiny28";
+ stk500_devcode = 0x22;
+ avr910_devcode = 0x5c;
+ signature = 0x1e 0x91 0x07;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 0;
+ poweroffdelay = 0;
+ resetdelayms = 0;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "flash"
+ size = 2048;
+ page_size = 2;
+ readsize = 256;
+ delay = 5;
+ ;
+
+ memory "signature"
+ size = 3;
+ ;
+
+ memory "lock"
+ size = 1;
+ ;
+
+ memory "calibration"
+ size = 1;
+ ;
+
+ memory "fuse"
+ size = 1;
+ ;
+;
+
+
+
+#------------------------------------------------------------
+# ATmega48
+#------------------------------------------------------------
+
+part
+ id = "m48";
+ desc = "ATmega48";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x59;
+# avr910_devcode = 0x;
+ signature = 0x1e 0x92 0x05;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 45000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 256;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega48P
+#------------------------------------------------------------
+
+part parent "m48"
+ id = "m48p";
+ desc = "ATmega48P";
+ signature = 0x1e 0x92 0x0a;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega48PB
+#------------------------------------------------------------
+
+part parent "m48"
+ id = "m48pb";
+ desc = "ATmega48PB";
+ signature = 0x1e 0x92 0x10;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega88
+#------------------------------------------------------------
+
+part
+ id = "m88";
+ desc = "ATmega88";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x73;
+# avr910_devcode = 0x;
+ signature = 0x1e 0x93 0x0a;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 512;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega88P
+#------------------------------------------------------------
+
+part parent "m88"
+ id = "m88p";
+ desc = "ATmega88P";
+ signature = 0x1e 0x93 0x0f;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega88PB
+#------------------------------------------------------------
+
+part parent "m88"
+ id = "m88pb";
+ desc = "ATmega88PB";
+ signature = 0x1e 0x93 0x16;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# ATmega168
+#------------------------------------------------------------
+
+part
+ id = "m168";
+ desc = "ATmega168";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x86;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x94 0x06;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 512;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+;
+
+#------------------------------------------------------------
+# ATmega168P
+#------------------------------------------------------------
+
+part parent "m168"
+ id = "m168p";
+ desc = "ATmega168P";
+ signature = 0x1e 0x94 0x0b;
+
+ ocdrev = 1;
+;
+
+#------------------------------------------------------------
+# ATmega168PB
+#------------------------------------------------------------
+
+part parent "m168"
+ id = "m168pb";
+ desc = "ATmega168PB";
+ signature = 0x1e 0x94 0x15;
+
+ ocdrev = 1;
+;
+
+#------------------------------------------------------------
+# ATtiny88
+#------------------------------------------------------------
+
+part
+ id = "t88";
+ desc = "ATtiny88";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x73;
+# avr910_devcode = 0x;
+ signature = 0x1e 0x93 0x11;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 64;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 64;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega328
+#------------------------------------------------------------
+
+part
+ id = "m328";
+ desc = "ATmega328";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x86;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x95 0x14;
+ pagel = 0xd7;
+ bs2 = 0xc2;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 1024;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+;
+
+part parent "m328"
+ id = "m328p";
+ desc = "ATmega328P";
+ signature = 0x1e 0x95 0x0F;
+
+ ocdrev = 1;
+;
+
+#------------------------------------------------------------
+# ATmega32m1
+#------------------------------------------------------------
+
+part parent "m328"
+ id = "m32m1";
+ desc = "ATmega32M1";
+ # stk500_devcode = 0x;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x95 0x84;
+ bs2 = 0xe2;
+
+ memory "efuse"
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x i i i i i i";
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny2313
+#------------------------------------------------------------
+
+part
+ id = "t2313";
+ desc = "ATtiny2313";
+ has_debugwire = yes;
+ flash_instr = 0xB2, 0x0F, 0x1F;
+ eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x23;
+## Use the ATtiny26 devcode:
+ avr910_devcode = 0x5e;
+ signature = 0x1e 0x91 0x0a;
+ pagel = 0xD4;
+ bs2 = 0xD6;
+ reset = io;
+ chip_erase_delay = 9000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
+ 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
+ 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
+ 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 0;
+
+ memory "eeprom"
+ size = 128;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+# The information in the data sheet of April/2004 is wrong, this works:
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny2313 has Signature Bytes: 0x1E 0x91 0x0A.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+# The Tiny2313 has calibration data for both 4 MHz and 8 MHz.
+# The information in the data sheet of April/2004 is wrong, this works:
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny4313
+#------------------------------------------------------------
+
+part
+ id = "t4313";
+ desc = "ATtiny4313";
+ has_debugwire = yes;
+ flash_instr = 0xB2, 0x0F, 0x1F;
+ eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x23;
+## Use the ATtiny26 devcode:
+ avr910_devcode = 0x5e;
+ signature = 0x1e 0x92 0x0d;
+ pagel = 0xD4;
+ bs2 = 0xD6;
+ reset = io;
+ chip_erase_delay = 9000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
+ 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
+ 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
+ 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 0;
+
+ memory "eeprom"
+ size = 256;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny4313 has Signature Bytes: 0x1E 0x92 0x0D.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM2
+#------------------------------------------------------------
+
+part
+ id = "pwm2";
+ desc = "AT90PWM2";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x65;
+## avr910_devcode = ?;
+ signature = 0x1e 0x93 0x81;
+ pagel = 0xD8;
+ bs2 = 0xE2;
+ reset = io;
+ chip_erase_delay = 9000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ size = 512;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 64;
+ readsize = 256;
+ ;
+# AT90PWM2 has Signature Bytes: 0x1E 0x93 0x81.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM3
+#------------------------------------------------------------
+
+# Completely identical to AT90PWM2 (including the signature!)
+
+part parent "pwm2"
+ id = "pwm3";
+ desc = "AT90PWM3";
+ ;
+
+#------------------------------------------------------------
+# AT90PWM2B
+#------------------------------------------------------------
+# Same as AT90PWM2 but different signature.
+
+part parent "pwm2"
+ id = "pwm2b";
+ desc = "AT90PWM2B";
+ signature = 0x1e 0x93 0x83;
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM3B
+#------------------------------------------------------------
+
+# Completely identical to AT90PWM2B (including the signature!)
+
+part parent "pwm2b"
+ id = "pwm3b";
+ desc = "AT90PWM3B";
+
+ ocdrev = 1;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM316
+#------------------------------------------------------------
+
+# Similar to AT90PWM3B, but with 16 kiB flash, 512 B EEPROM, and 1024 B SRAM.
+
+part parent "pwm3b"
+ id = "pwm316";
+ desc = "AT90PWM316";
+ signature = 0x1e 0x94 0x83;
+
+ ocdrev = 1;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x21;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90PWM216
+#------------------------------------------------------------
+# Completely identical to AT90PWM316 (including the signature!)
+
+part parent "pwm316"
+ id = "pwm216";
+ desc = "AT90PWM216";
+ ;
+
+#------------------------------------------------------------
+# ATtiny25
+#------------------------------------------------------------
+
+part
+ id = "t25";
+ desc = "ATtiny25";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x02, 0x12;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x91 0x08;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 128;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny25 has Signature Bytes: 0x1E 0x91 0x08.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny45
+#------------------------------------------------------------
+
+part
+ id = "t45";
+ desc = "ATtiny45";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x02, 0x12;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x92 0x06;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 256;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny45 has Signature Bytes: 0x1E 0x92 0x08. (Data sheet 2586C-AVR-06/05 (doc2586.pdf) indicates otherwise!)
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny85
+#------------------------------------------------------------
+
+part
+ id = "t85";
+ desc = "ATtiny85";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x02, 0x12;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x93 0x0b;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 512;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny85 has Signature Bytes: 0x1E 0x93 0x08.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega640
+#------------------------------------------------------------
+# Almost same as ATmega1280, except for different memory sizes
+
+part
+ id = "m640";
+ desc = "ATmega640";
+ signature = 0x1e 0x96 0x08;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega1280
+#------------------------------------------------------------
+
+part
+ id = "m1280";
+ desc = "ATmega1280";
+ signature = 0x1e 0x97 0x03;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega1281
+#------------------------------------------------------------
+# Identical to ATmega1280
+
+part parent "m1280"
+ id = "m1281";
+ desc = "ATmega1281";
+ signature = 0x1e 0x97 0x04;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega2560
+#------------------------------------------------------------
+
+part
+ id = "m2560";
+ desc = "ATmega2560";
+ signature = 0x1e 0x98 0x01;
+ has_jtag = yes;
+ stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 4;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 262144;
+ page_size = 256;
+ num_pages = 1024;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ load_ext_addr = " 0 1 0 0 1 1 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 a16",
+ " 0 0 0 0 0 0 0 0";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega2561
+#------------------------------------------------------------
+
+part parent "m2560"
+ id = "m2561";
+ desc = "ATmega2561";
+ signature = 0x1e 0x98 0x02;
+
+ ocdrev = 4;
+ ;
+
+#------------------------------------------------------------
+# ATmega128RFA1
+#------------------------------------------------------------
+# Identical to ATmega2561 but half the ROM
+
+part parent "m2561"
+ id = "m128rfa1";
+ desc = "ATmega128RFA1";
+ signature = 0x1e 0xa7 0x01;
+ chip_erase_delay = 55000;
+ bs2 = 0xE2;
+
+ ocdrev = 3;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 50000;
+ max_write_delay = 50000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 256;
+ readsize = 256;
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega256RFR2
+#------------------------------------------------------------
+
+part parent "m2561"
+ id = "m256rfr2";
+ desc = "ATmega256RFR2";
+ signature = 0x1e 0xa8 0x02;
+ chip_erase_delay = 18500;
+ bs2 = 0xE2;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 8192;
+ min_write_delay = 13000;
+ max_write_delay = 13000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+
+ ocdrev = 4;
+ ;
+
+#------------------------------------------------------------
+# ATmega128RFR2
+#------------------------------------------------------------
+
+part parent "m128rfa1"
+ id = "m128rfr2";
+ desc = "ATmega128RFR2";
+ signature = 0x1e 0xa7 0x02;
+
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega64RFR2
+#------------------------------------------------------------
+
+part parent "m128rfa1"
+ id = "m64rfr2";
+ desc = "ATmega64RFR2";
+ signature = 0x1e 0xa6 0x02;
+
+
+ ocdrev = 3;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 50000;
+ max_write_delay = 50000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 13000;
+ max_write_delay = 13000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+
+ ;
+
+#------------------------------------------------------------
+# ATmega2564RFR2
+#------------------------------------------------------------
+
+part parent "m256rfr2"
+ id = "m2564rfr2";
+ desc = "ATmega2564RFR2";
+ signature = 0x1e 0xa8 0x03;
+ ;
+
+#------------------------------------------------------------
+# ATmega1284RFR2
+#------------------------------------------------------------
+
+part parent "m128rfr2"
+ id = "m1284rfr2";
+ desc = "ATmega1284RFR2";
+ signature = 0x1e 0xa7 0x03;
+ ;
+
+#------------------------------------------------------------
+# ATmega644RFR2
+#------------------------------------------------------------
+
+part parent "m64rfr2"
+ id = "m644rfr2";
+ desc = "ATmega644RFR2";
+ signature = 0x1e 0xa6 0x03;
+ ;
+
+#------------------------------------------------------------
+# ATtiny24
+#------------------------------------------------------------
+
+part
+ id = "t24";
+ desc = "ATtiny24";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x91 0x0b;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 70;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 128;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 2048;
+ page_size = 32;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x x a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny24 has Signature Bytes: 0x1E 0x91 0x0B.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x x x x x x x i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny44
+#------------------------------------------------------------
+
+part
+ id = "t44";
+ desc = "ATtiny44";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x92 0x07;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 70;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 256;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny44 has Signature Bytes: 0x1E 0x92 0x07.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x x x x x x x i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny84
+#------------------------------------------------------------
+
+part
+ id = "t84";
+ desc = "ATtiny84";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+## no STK500 devcode in XML file, use the ATtiny45 one
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x93 0x0c;
+ reset = io;
+ chip_erase_delay = 4500;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ hvsp_controlstack =
+ 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
+ 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
+ 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
+ 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
+ hventerstabdelay = 100;
+ hvspcmdexedelay = 0;
+ synchcycles = 6;
+ latchcycles = 1;
+ togglevtg = 1;
+ poweroffdelay = 25;
+ resetdelayms = 0;
+ resetdelayus = 70;
+ hvleavestabdelay = 100;
+ resetdelay = 25;
+ chiperasepolltimeout = 40;
+ chiperasetime = 0;
+ programfusepolltimeout = 25;
+ programlockpolltimeout = 25;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ size = 512;
+ paged = no;
+ page_size = 4;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
+ "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " x a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 64;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 32;
+ readsize = 256;
+ ;
+# ATtiny84 has Signature Bytes: 0x1E 0x93 0x0C.
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x x x x x x x i i";
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATtiny43U
+#------------------------------------------------------------
+
+part
+ id = "t43u";
+ desc = "ATtiny43u";
+ has_debugwire = yes;
+ flash_instr = 0xB4, 0x07, 0x17;
+ eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+ 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+ 0x99, 0xE1, 0xBB, 0xAC;
+ stk500_devcode = 0x14;
+## avr910_devcode = ?;
+## Try the AT90S2313 devcode:
+ avr910_devcode = 0x20;
+ signature = 0x1e 0x92 0x0C;
+ reset = io;
+ chip_erase_delay = 1000;
+
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack = 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, 0x4E, 0x5E,
+ 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, 0x06, 0x16, 0x46, 0x56,
+ 0x0A, 0x1A, 0x4A, 0x5A, 0x1E, 0x7C, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ hvspcmdexedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 20;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+ memory "eeprom"
+ size = 64;
+ paged = yes;
+ page_size = 4;
+ num_pages = 16;
+ min_write_delay = 4000;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
+ "0 0 a4 a3 a2 a1 a0 o o o o o o o o";
+
+ write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
+ "0 0 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x x",
+ " 0 0 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 5;
+ blocksize = 4;
+ readsize = 256;
+ ;
+ memory "flash"
+ paged = yes;
+ size = 4096;
+ page_size = 64;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x x a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 64;
+ readsize = 256;
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ memory "lock"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x x x x i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ ;
+
+ memory "calibration"
+ size = 2;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 a0 o o o o o o o o";
+ ;
+;
+
+#------------------------------------------------------------
+# ATmega32u4
+#------------------------------------------------------------
+
+part
+ id = "m32u4";
+ desc = "ATmega32U4";
+ signature = 0x1e 0x95 0x87;
+ usbpid = 0x2ff4;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB646
+#------------------------------------------------------------
+
+part
+ id = "usb646";
+ desc = "AT90USB646";
+ signature = 0x1e 0x96 0x82;
+ usbpid = 0x2ff9;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB647
+#------------------------------------------------------------
+# identical to AT90USB646
+
+part parent "usb646"
+ id = "usb647";
+ desc = "AT90USB647";
+ signature = 0x1e 0x96 0x82;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# AT90USB1286
+#------------------------------------------------------------
+
+part
+ id = "usb1286";
+ desc = "AT90USB1286";
+ signature = 0x1e 0x97 0x82;
+ usbpid = 0x2ffb;
+ has_jtag = yes;
+# stk500_devcode = 0xB2;
+# avr910_devcode = 0x43;
+ chip_erase_delay = 9000;
+ pagel = 0xD7;
+ bs2 = 0xA0;
+ reset = dedicated;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ rampz = 0x3b;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 4096;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " x x x x a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 131072;
+ page_size = 256;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 x x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 256;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x x i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 x x x x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 x x x x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB1287
+#------------------------------------------------------------
+# identical to AT90USB1286
+
+part parent "usb1286"
+ id = "usb1287";
+ desc = "AT90USB1287";
+ signature = 0x1e 0x97 0x82;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# AT90USB162
+#------------------------------------------------------------
+
+part
+ id = "usb162";
+ desc = "AT90USB162";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x94 0x82;
+ usbpid = 0x2ffa;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# AT90USB82
+#------------------------------------------------------------
+# Changes against AT90USB162 (beside IDs)
+# memory "flash"
+# size = 8192;
+# num_pages = 64;
+
+part
+ id = "usb82";
+ desc = "AT90USB82";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x93 0x82;
+ usbpid = 0x2ff7;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 128;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega32U2
+#------------------------------------------------------------
+# Changes against AT90USB162 (beside IDs)
+# memory "flash"
+# size = 32768;
+# num_pages = 256;
+# memory "eeprom"
+# size = 1024;
+# num_pages = 256;
+part
+ id = "m32u2";
+ desc = "ATmega32U2";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x95 0x8a;
+ usbpid = 0x2ff0;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ num_pages = 256;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+#------------------------------------------------------------
+# ATmega16U2
+#------------------------------------------------------------
+# Changes against ATmega32U2 (beside IDs)
+# memory "flash"
+# size = 16384;
+# num_pages = 128;
+# memory "eeprom"
+# size = 512;
+# num_pages = 128;
+part
+ id = "m16u2";
+ desc = "ATmega16U2";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x94 0x89;
+ usbpid = 0x2fef;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 128;
+ num_pages = 128;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega8U2
+#------------------------------------------------------------
+# Changes against ATmega16U2 (beside IDs)
+# memory "flash"
+# size = 8192;
+# page_size = 64;
+# blocksize = 64;
+
+part
+ id = "m8u2";
+ desc = "ATmega8U2";
+ has_jtag = no;
+ has_debugwire = yes;
+ signature = 0x1e 0x93 0x89;
+ usbpid = 0x2fee;
+ chip_erase_delay = 9000;
+ reset = io;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+ pagel = 0xD7;
+ bs2 = 0xC6;
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ ocdrev = 1;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 512;
+ num_pages = 128;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 20;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 8192;
+ page_size = 128;
+ num_pages = 64;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0x00;
+ readback_p2 = 0x00;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " x x x x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ "a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x i i i i i i i i";
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+ ;
+#------------------------------------------------------------
+# ATmega325
+#------------------------------------------------------------
+
+part
+ id = "m325";
+ desc = "ATmega325";
+ signature = 0x1e 0x95 0x05;
+ has_jtag = yes;
+# stk500_devcode = 0x??; # No STK500v1 support?
+# avr910_devcode = 0x??; # Try the ATmega16 one
+ avr910_devcode = 0x74;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 4; /* for parallel programming */
+ size = 1024;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 0 0 a9 a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 32768;
+ page_size = 128;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega645
+#------------------------------------------------------------
+
+part
+ id = "m645";
+ desc = "ATmega645";
+ signature = 0x1E 0x96 0x05;
+ has_jtag = yes;
+# stk500_devcode = 0x??; # No STK500v1 support?
+# avr910_devcode = 0x??; # Try the ATmega16 one
+ avr910_devcode = 0x74;
+ pagel = 0xd7;
+ bs2 = 0xa0;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 5;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ idr = 0x31;
+ spmcr = 0x57;
+ allowfullpagebitstream = no;
+
+ ocdrev = 3;
+
+ memory "eeprom"
+ paged = no; /* leave this "no" */
+ page_size = 8; /* for parallel programming */
+ size = 2048;
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 0 0 0 a10 a9 a8",
+ " a7 a6 a5 a4 a3 0 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 8;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 65536;
+ page_size = 256;
+ num_pages = 256;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 0 0 0 0 0",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " a15 a14 a13 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " 0 0 0 0 0 0 0 0";
+
+ mode = 0x41;
+ delay = 10;
+ blocksize = 128;
+ readsize = 256;
+ ;
+
+ memory "lock"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 1 1 i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 i i i i i i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "efuse"
+ size = 1;
+
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i";
+ min_write_delay = 9000;
+ max_write_delay = 9000;
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 a1 a0 o o o o o o o o";
+ ;
+
+ memory "calibration"
+ size = 1;
+
+ read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+ ;
+
+#------------------------------------------------------------
+# ATmega3250
+#------------------------------------------------------------
+
+part parent "m325"
+ id = "m3250";
+ desc = "ATmega3250";
+ signature = 0x1E 0x95 0x06;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# ATmega6450
+#------------------------------------------------------------
+
+part parent "m645"
+ id = "m6450";
+ desc = "ATmega6450";
+ signature = 0x1E 0x96 0x06;
+
+ ocdrev = 3;
+ ;
+
+#------------------------------------------------------------
+# AVR XMEGA family common values
+#------------------------------------------------------------
+
+part
+ id = ".xmega";
+ desc = "AVR XMEGA family common values";
+ has_pdi = yes;
+ nvm_base = 0x01c0;
+ mcu_base = 0x0090;
+
+ memory "signature"
+ size = 3;
+ offset = 0x1000090;
+ ;
+
+ memory "prodsig"
+ size = 0x32;
+ offset = 0x8e0200;
+ page_size = 0x32;
+ readsize = 0x32;
+ ;
+
+ memory "fuse1"
+ size = 1;
+ offset = 0x8f0021;
+ ;
+
+ memory "fuse2"
+ size = 1;
+ offset = 0x8f0022;
+ ;
+
+ memory "fuse4"
+ size = 1;
+ offset = 0x8f0024;
+ ;
+
+ memory "fuse5"
+ size = 1;
+ offset = 0x8f0025;
+ ;
+
+ memory "lock"
+ size = 1;
+ offset = 0x8f0027;
+ ;
+
+ memory "data"
+ # SRAM, only used to supply the offset
+ offset = 0x1000000;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega16A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x16a4u";
+ desc = "ATxmega16A4U";
+ signature = 0x1e 0x94 0x41;
+ usbpid = 0x2fe3;
+
+ memory "eeprom"
+ size = 0x400;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x4000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x803000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x804000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x5000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega16C4
+#------------------------------------------------------------
+
+part parent "x16a4u"
+ id = "x16c4";
+ desc = "ATxmega16C4";
+ signature = 0x1e 0x95 0x44;
+;
+
+#------------------------------------------------------------
+# ATxmega16D4
+#------------------------------------------------------------
+
+part parent "x16a4u"
+ id = "x16d4";
+ desc = "ATxmega16D4";
+ signature = 0x1e 0x94 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega16A4
+#------------------------------------------------------------
+
+part parent "x16a4u"
+ id = "x16a4";
+ desc = "ATxmega16A4";
+ signature = 0x1e 0x94 0x41;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega32A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x32a4u";
+ desc = "ATxmega32A4U";
+ signature = 0x1e 0x95 0x41;
+ usbpid = 0x2fe4;
+
+ memory "eeprom"
+ size = 0x400;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x8000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x807000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x808000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x9000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega32C4
+#------------------------------------------------------------
+
+part parent "x32a4u"
+ id = "x32c4";
+ desc = "ATxmega32C4";
+ signature = 0x1e 0x94 0x43;
+;
+
+#------------------------------------------------------------
+# ATxmega32D4
+#------------------------------------------------------------
+
+part parent "x32a4u"
+ id = "x32d4";
+ desc = "ATxmega32D4";
+ signature = 0x1e 0x95 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega32A4
+#------------------------------------------------------------
+
+part parent "x32a4u"
+ id = "x32a4";
+ desc = "ATxmega32A4";
+ signature = 0x1e 0x95 0x41;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega64A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x64a4u";
+ desc = "ATxmega64A4U";
+ signature = 0x1e 0x96 0x46;
+ usbpid = 0x2fe5;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x10000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x80f000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x810000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x11000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega64C3
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64c3";
+ desc = "ATxmega64C3";
+ signature = 0x1e 0x96 0x49;
+ usbpid = 0x2fd6;
+;
+
+#------------------------------------------------------------
+# ATxmega64D3
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64d3";
+ desc = "ATxmega64D3";
+ signature = 0x1e 0x96 0x4a;
+;
+
+#------------------------------------------------------------
+# ATxmega64D4
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64d4";
+ desc = "ATxmega64D4";
+ signature = 0x1e 0x96 0x47;
+;
+
+#------------------------------------------------------------
+# ATxmega64A1
+#------------------------------------------------------------
+
+part parent "x64a4u"
+ id = "x64a1";
+ desc = "ATxmega64A1";
+ signature = 0x1e 0x96 0x4e;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega64A1U
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a1u";
+ desc = "ATxmega64A1U";
+ signature = 0x1e 0x96 0x4e;
+ usbpid = 0x2fe8;
+;
+
+#------------------------------------------------------------
+# ATxmega64A3
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a3";
+ desc = "ATxmega64A3";
+ signature = 0x1e 0x96 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega64A3U
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a3u";
+ desc = "ATxmega64A3U";
+ signature = 0x1e 0x96 0x42;
+ usbpid = 0x2fe5;
+;
+
+#------------------------------------------------------------
+# ATxmega64A4
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64a4";
+ desc = "ATxmega64A4";
+ signature = 0x1e 0x96 0x46;
+;
+
+#------------------------------------------------------------
+# ATxmega64B1
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64b1";
+ desc = "ATxmega64B1";
+ signature = 0x1e 0x96 0x52;
+ usbpid = 0x2fe1;
+;
+
+#------------------------------------------------------------
+# ATxmega64B3
+#------------------------------------------------------------
+
+part parent "x64a1"
+ id = "x64b3";
+ desc = "ATxmega64B3";
+ signature = 0x1e 0x96 0x51;
+ usbpid = 0x2fdf;
+;
+
+#------------------------------------------------------------
+# ATxmega128C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128c3";
+ desc = "ATxmega128C3";
+ signature = 0x1e 0x97 0x52;
+ usbpid = 0x2fd7;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x81e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128D3
+#------------------------------------------------------------
+
+part parent "x128c3"
+ id = "x128d3";
+ desc = "ATxmega128D3";
+ signature = 0x1e 0x97 0x48;
+;
+
+#------------------------------------------------------------
+# ATxmega128D4
+#------------------------------------------------------------
+
+part parent "x128c3"
+ id = "x128d4";
+ desc = "ATxmega128D4";
+ signature = 0x1e 0x97 0x47;
+;
+
+#------------------------------------------------------------
+# ATxmega128A1
+#------------------------------------------------------------
+
+part parent "x128c3"
+ id = "x128a1";
+ desc = "ATxmega128A1";
+ signature = 0x1e 0x97 0x4c;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128A1 revision D
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a1d";
+ desc = "ATxmega128A1revD";
+ signature = 0x1e 0x97 0x41;
+;
+
+#------------------------------------------------------------
+# ATxmega128A1U
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a1u";
+ desc = "ATxmega128A1U";
+ signature = 0x1e 0x97 0x4c;
+ usbpid = 0x2fed;
+;
+
+#------------------------------------------------------------
+# ATxmega128A3
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a3";
+ desc = "ATxmega128A3";
+ signature = 0x1e 0x97 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega128A3U
+#------------------------------------------------------------
+
+part parent "x128a1"
+ id = "x128a3u";
+ desc = "ATxmega128A3U";
+ signature = 0x1e 0x97 0x42;
+ usbpid = 0x2fe6;
+;
+
+#------------------------------------------------------------
+# ATxmega128A4
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128a4";
+ desc = "ATxmega128A4";
+ signature = 0x1e 0x97 0x46;
+ has_jtag = yes;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x81f000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128A4U
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128a4u";
+ desc = "ATxmega128A4U";
+ signature = 0x1e 0x97 0x46;
+ usbpid = 0x2fde;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x81f000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128B1
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x128b1";
+ desc = "ATxmega128B1";
+ signature = 0x1e 0x97 0x4d;
+ usbpid = 0x2fea;
+ has_jtag = yes;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x20000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x81e000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x820000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x22000;
+ offset = 0x800000;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x100;
+ offset = 0x8e0400;
+ page_size = 0x100;
+ readsize = 0x100;
+ ;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega128B3
+#------------------------------------------------------------
+
+part parent "x128b1"
+ id = "x128b3";
+ desc = "ATxmega128B3";
+ signature = 0x1e 0x97 0x4b;
+ usbpid = 0x2fe0;
+;
+
+#------------------------------------------------------------
+# ATxmega192C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x192c3";
+ desc = "ATxmega192C3";
+ signature = 0x1e 0x97 0x51;
+ # usbpid = 0x2f??;
+
+ memory "eeprom"
+ size = 0x800;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x30000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x82e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x830000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x32000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega192D3
+#------------------------------------------------------------
+
+part parent "x192c3"
+ id = "x192d3";
+ desc = "ATxmega192D3";
+ signature = 0x1e 0x97 0x49;
+;
+
+#------------------------------------------------------------
+# ATxmega192A1
+#------------------------------------------------------------
+
+part parent "x192c3"
+ id = "x192a1";
+ desc = "ATxmega192A1";
+ signature = 0x1e 0x97 0x4e;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega192A3
+#------------------------------------------------------------
+
+part parent "x192a1"
+ id = "x192a3";
+ desc = "ATxmega192A3";
+ signature = 0x1e 0x97 0x44;
+;
+
+#------------------------------------------------------------
+# ATxmega192A3U
+#------------------------------------------------------------
+
+part parent "x192a1"
+ id = "x192a3u";
+ desc = "ATxmega192A3U";
+ signature = 0x1e 0x97 0x44;
+ usbpid = 0x2fe7;
+;
+
+#------------------------------------------------------------
+# ATxmega256C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x256c3";
+ desc = "ATxmega256C3";
+ signature = 0x1e 0x98 0x46;
+ usbpid = 0x2fda;
+
+ memory "eeprom"
+ size = 0x1000;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x40000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x83e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x840000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x42000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega256D3
+#------------------------------------------------------------
+
+part parent "x256c3"
+ id = "x256d3";
+ desc = "ATxmega256D3";
+ signature = 0x1e 0x98 0x44;
+;
+
+#------------------------------------------------------------
+# ATxmega256A1
+#------------------------------------------------------------
+
+part parent "x256c3"
+ id = "x256a1";
+ desc = "ATxmega256A1";
+ signature = 0x1e 0x98 0x46;
+ has_jtag = yes;
+
+ memory "fuse0"
+ size = 1;
+ offset = 0x8f0020;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3";
+ desc = "ATxmega256A3";
+ signature = 0x1e 0x98 0x42;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3U
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3u";
+ desc = "ATxmega256A3U";
+ signature = 0x1e 0x98 0x42;
+ usbpid = 0x2fec;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3B
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3b";
+ desc = "ATxmega256A3B";
+ signature = 0x1e 0x98 0x43;
+;
+
+#------------------------------------------------------------
+# ATxmega256A3BU
+#------------------------------------------------------------
+
+part parent "x256a1"
+ id = "x256a3bu";
+ desc = "ATxmega256A3BU";
+ signature = 0x1e 0x98 0x43;
+ usbpid = 0x2fe2;
+;
+
+#------------------------------------------------------------
+# ATxmega384C3
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x384c3";
+ desc = "ATxmega384C3";
+ signature = 0x1e 0x98 0x45;
+ usbpid = 0x2fdb;
+
+ memory "eeprom"
+ size = 0x1000;
+ offset = 0x8c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x60000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x2000;
+ offset = 0x85e000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x2000;
+ offset = 0x860000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x62000;
+ offset = 0x800000;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x200;
+ offset = 0x8e0400;
+ page_size = 0x200;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega384D3
+#------------------------------------------------------------
+
+part parent "x384c3"
+ id = "x384d3";
+ desc = "ATxmega384D3";
+ signature = 0x1e 0x98 0x47;
+;
+
+#------------------------------------------------------------
+# ATxmega8E5
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x8e5";
+ desc = "ATxmega8E5";
+ signature = 0x1e 0x93 0x41;
+
+ memory "eeprom"
+ size = 0x0200;
+ offset = 0x08c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x2000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x800;
+ offset = 0x00801800;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x800;
+ offset = 0x00802000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x2800;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x80;
+ offset = 0x8e0400;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega16E5
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x16e5";
+ desc = "ATxmega16E5";
+ signature = 0x1e 0x94 0x45;
+
+ memory "eeprom"
+ size = 0x0200;
+ offset = 0x08c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x4000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x00803000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x00804000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x5000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x80;
+ offset = 0x8e0400;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# ATxmega32E5
+#------------------------------------------------------------
+
+part parent ".xmega"
+ id = "x32e5";
+ desc = "ATxmega32E5";
+ signature = 0x1e 0x95 0x4c;
+
+ memory "eeprom"
+ size = 0x0400;
+ offset = 0x08c0000;
+ page_size = 0x20;
+ readsize = 0x100;
+ ;
+
+ memory "application"
+ size = 0x8000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "apptable"
+ size = 0x1000;
+ offset = 0x00807000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "boot"
+ size = 0x1000;
+ offset = 0x00808000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "flash"
+ size = 0x9000;
+ offset = 0x0800000;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+
+ memory "usersig"
+ size = 0x80;
+ offset = 0x8e0400;
+ page_size = 0x80;
+ readsize = 0x100;
+ ;
+;
+
+#------------------------------------------------------------
+# AVR32UC3A0512
+#------------------------------------------------------------
+
+part
+ id = "uc3a0512";
+ desc = "AT32UC3A0512";
+ signature = 0xED 0xC0 0x3F;
+ has_jtag = yes;
+ is_avr32 = yes;
+
+ memory "flash"
+ paged = yes;
+ page_size = 512; # bytes
+ readsize = 512; # bytes
+ num_pages = 1024; # could be set dynamicly
+ size = 0x00080000; # could be set dynamicly
+ offset = 0x80000000;
+ ;
+;
+
+part parent "uc3a0512"
+ id = "ucr2";
+ desc = "deprecated, use 'uc3a0512'";
+;
+
+#------------------------------------------------------------
+# ATtiny1634.
+#------------------------------------------------------------
+
+part
+ id = "t1634";
+ desc = "ATtiny1634";
+ has_debugwire = yes;
+ flash_instr = 0xB6, 0x01, 0x11;
+ eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+ 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+ 0x99, 0xF9, 0xBB, 0xAF;
+ stk500_devcode = 0x86;
+ # avr910_devcode = 0x;
+ signature = 0x1e 0x94 0x12;
+ pagel = 0xB3;
+ bs2 = 0xB1;
+ reset = io;
+ chip_erase_delay = 9000;
+ pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
+ "x x x x x x x x x x x x x x x x";
+
+ chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
+ "x x x x x x x x x x x x x x x x";
+
+ timeout = 200;
+ stabdelay = 100;
+ cmdexedelay = 25;
+ synchloops = 32;
+ bytedelay = 0;
+ pollindex = 3;
+ pollvalue = 0x53;
+ predelay = 1;
+ postdelay = 1;
+ pollmethod = 1;
+
+ pp_controlstack =
+ 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
+ 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
+ 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
+ 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+ hventerstabdelay = 100;
+ progmodedelay = 0;
+ latchcycles = 0;
+ togglevtg = 1;
+ poweroffdelay = 15;
+ resetdelayms = 1;
+ resetdelayus = 0;
+ hvleavestabdelay = 15;
+ resetdelay = 15;
+ chiperasepulsewidth = 0;
+ chiperasepolltimeout = 10;
+ programfusepulsewidth = 0;
+ programfusepolltimeout = 5;
+ programlockpulsewidth = 0;
+ programlockpolltimeout = 5;
+
+ memory "eeprom"
+ paged = no;
+ page_size = 4;
+ size = 256;
+ min_write_delay = 3600;
+ max_write_delay = 3600;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read = " 1 0 1 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ write = " 1 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_lo = " 1 1 0 0 0 0 0 1",
+ " 0 0 0 0 0 0 0 0",
+ " 0 0 0 0 0 0 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 1 1 0 0 0 0 1 0",
+ " 0 0 x x x x x a8",
+ " a7 a6 a5 a4 a3 a2 0 0",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 5;
+ blocksize = 4;
+ readsize = 256;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 16384;
+ page_size = 32;
+ num_pages = 512;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ readback_p1 = 0xff;
+ readback_p2 = 0xff;
+ read_lo = " 0 0 1 0 0 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ read_hi = " 0 0 1 0 1 0 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 a5 a4 a3 a2 a1 a0",
+ " o o o o o o o o";
+
+ loadpage_lo = " 0 1 0 0 0 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ loadpage_hi = " 0 1 0 0 1 0 0 0",
+ " 0 0 0 x x x x x",
+ " x x a5 a4 a3 a2 a1 a0",
+ " i i i i i i i i";
+
+ writepage = " 0 1 0 0 1 1 0 0",
+ " 0 0 0 a12 a11 a10 a9 a8",
+ " a7 a6 x x x x x x",
+ " x x x x x x x x";
+
+ mode = 0x41;
+ delay = 6;
+ blocksize = 128;
+ readsize = 256;
+
+ ;
+
+ memory "lfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "hfuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
+ "x x x x x x x x i i i i i i i i";
+ ;
+
+ memory "efuse"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
+ "x x x x x x x x o o o o o o o o";
+
+ write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
+ "x x x x x x x x x x x i i i i i";
+ ;
+
+ memory "lock"
+ size = 1;
+ min_write_delay = 4500;
+ max_write_delay = 4500;
+ read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
+ "x x x x x x x x x x x x x x o o";
+
+ write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
+ "x x x x x x x x 1 1 1 1 1 1 i i";
+ ;
+
+ memory "calibration"
+ size = 1;
+ read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
+ "0 0 0 0 0 0 0 0 o o o o o o o o";
+ ;
+
+ memory "signature"
+ size = 3;
+ read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
+ "x x x x x x a1 a0 o o o o o o o o";
+ ;
+;
+
+#------------------------------------------------------------
+# Common values for reduced core tinys (4/5/9/10/20/40)
+#------------------------------------------------------------
+
+part
+ id = ".reduced_core_tiny";
+ desc = "Common values for reduced core tinys";
+ has_tpi = yes;
+
+ memory "signature"
+ size = 3;
+ offset = 0x3fc0;
+ page_size = 16;
+ ;
+
+ memory "fuse"
+ size = 1;
+ offset = 0x3f40;
+ page_size = 16;
+ blocksize = 4;
+ ;
+
+ memory "calibration"
+ size = 1;
+ offset = 0x3f80;
+ page_size = 16;
+ ;
+
+ memory "lockbits"
+ size = 1;
+ offset = 0x3f00;
+ page_size = 16;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny4
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t4";
+ desc = "ATtiny4";
+ signature = 0x1e 0x8f 0x0a;
+
+ memory "flash"
+ size = 512;
+ offset = 0x4000;
+ page_size = 16;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny5
+#------------------------------------------------------------
+
+part parent "t4"
+ id = "t5";
+ desc = "ATtiny5";
+ signature = 0x1e 0x8f 0x09;
+;
+
+#------------------------------------------------------------
+# ATtiny9
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t9";
+ desc = "ATtiny9";
+ signature = 0x1e 0x90 0x08;
+
+ memory "flash"
+ size = 1024;
+ offset = 0x4000;
+ page_size = 16;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny10
+#------------------------------------------------------------
+
+part parent "t9"
+ id = "t10";
+ desc = "ATtiny10";
+ signature = 0x1e 0x90 0x03;
+;
+
+#------------------------------------------------------------
+# ATtiny20
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t20";
+ desc = "ATtiny20";
+ signature = 0x1e 0x91 0x0F;
+
+ memory "flash"
+ size = 2048;
+ offset = 0x4000;
+ page_size = 16;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATtiny40
+#------------------------------------------------------------
+
+part parent ".reduced_core_tiny"
+ id = "t40";
+ desc = "ATtiny40";
+ signature = 0x1e 0x92 0x0E;
+
+ memory "flash"
+ size = 4096;
+ offset = 0x4000;
+ page_size = 64;
+ blocksize = 128;
+ ;
+;
+
+#------------------------------------------------------------
+# ATmega406
+#------------------------------------------------------------
+
+part
+ id = "m406";
+ desc = "ATMEGA406";
+ has_jtag = yes;
+ signature = 0x1e 0x95 0x07;
+
+ # STK500 parameters (parallel programming IO lines)
+ pagel = 0xa7;
+ bs2 = 0xa0;
+ serial = no;
+ parallel = yes;
+
+ # STK500v2 HV programming parameters, from XML
+ pp_controlstack = 0x0e, 0x1e, 0x0f, 0x1f, 0x2e, 0x3e, 0x2f, 0x3f,
+ 0x4e, 0x5e, 0x4f, 0x5f, 0x6e, 0x7e, 0x6f, 0x7f,
+ 0x66, 0x76, 0x67, 0x77, 0x6a, 0x7a, 0x6b, 0x7b,
+ 0xbe, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
+
+ # JTAG ICE mkII parameters, also from XML files
+ allowfullpagebitstream = no;
+ enablepageprogramming = yes;
+ idr = 0x51;
+ rampz = 0x00;
+ spmcr = 0x57;
+ eecr = 0x3f;
+
+ memory "eeprom"
+ paged = no;
+ size = 512;
+ page_size = 4;
+ blocksize = 4;
+ readsize = 4;
+ num_pages = 128;
+ ;
+
+ memory "flash"
+ paged = yes;
+ size = 40960;
+ page_size = 128;
+ blocksize = 128;
+ readsize = 128;
+ num_pages = 320;
+ ;
+
+ memory "hfuse"
+ size = 1;
+ ;
+
+ memory "lfuse"
+ size = 1;
+ ;
+
+ memory "lockbits"
+ size = 1;
+ ;
+
+ memory "signature"
+ size = 3;
+ ;
+;
+
+
diff --git a/xs/src/avrdude/avrdude.h b/xs/src/avrdude/avrdude.h
new file mode 100644
index 000000000..f4c92a75d
--- /dev/null
+++ b/xs/src/avrdude/avrdude.h
@@ -0,0 +1,89 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2007 Joerg Wunsch
+ *
+ * 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 avrdude_h
+#define avrdude_h
+
+
+extern char * progname; /* name of program, for messages */
+extern char progbuf[]; /* spaces same length as progname */
+
+extern int ovsigck; /* override signature check (-F) */
+extern int verbose; /* verbosity level (-v, -vv, ...) */
+extern int quell_progress; /* quiteness level (-q, -qq) */
+
+typedef void (*avrdude_message_handler_t)(const char *msg, unsigned size, void *user_p);
+void avrdude_message_handler_set(avrdude_message_handler_t newhandler, void *user_p);
+int avrdude_message(const int msglvl, const char *format, ...);
+
+// Progress reporting callback
+// `progress` is in range 0 ~ 100 percent
+typedef void (*avrdude_progress_handler_t)(const char *task, unsigned progress, void *user_p);
+void avrdude_progress_handler_set(avrdude_progress_handler_t newhandler, void *user_p);
+void avrdude_progress_external(const char *task, unsigned progress);
+
+// OOM handler
+typedef void (*avrdude_oom_handler_t)(const char *context, void *user_p);
+void avrdude_oom_handler_set(avrdude_oom_handler_t newhandler, void *user_p);
+void avrdude_oom(const char *context);
+
+
+// Cancellation
+void avrdude_cancel();
+
+#define MSG_INFO (0) /* no -v option, can be supressed with -qq */
+#define MSG_NOTICE (1) /* displayed with -v */
+#define MSG_NOTICE2 (2) /* displayed with -vv, used rarely */
+#define MSG_DEBUG (3) /* displayed with -vvv */
+#define MSG_TRACE (4) /* displayed with -vvvv, show trace commuication */
+#define MSG_TRACE2 (5) /* displayed with -vvvvv */
+
+int avrdude_main(int argc, char * argv [], const char *sys_config);
+
+#if defined(WIN32NATIVE)
+
+// #include "ac_cfg.h"
+
+#include <windows.h>
+#include <unistd.h>
+
+#ifdef UNICODE
+#error "UNICODE should not be defined for avrdude bits on Windows"
+#endif
+
+// #ifdef __cplusplus
+// extern "C" {
+// #endif
+
+// #if !defined(HAVE_USLEEP)
+// int usleep(unsigned int us);
+// #endif
+
+// #if !defined(HAVE_GETTIMEOFDAY)
+// struct timezone;
+// int gettimeofday(struct timeval *tv, struct timezone *tz);
+// #endif /* HAVE_GETTIMEOFDAY */
+
+// #ifdef __cplusplus
+// }
+// #endif
+#endif /* defined(WIN32NATIVE) */
+
+#endif
diff --git a/xs/src/avrdude/avrdude.spec.in b/xs/src/avrdude/avrdude.spec.in
new file mode 100644
index 000000000..ff9879f6f
--- /dev/null
+++ b/xs/src/avrdude/avrdude.spec.in
@@ -0,0 +1,113 @@
+## -*- mode: rpm-spec; -*-
+##
+## $Id$
+##
+## @configure_input@
+##
+
+%define debug_package %{nil}
+
+%define _with_docs 1
+%{?_without_docs: %define _with_docs 0}
+
+Summary: AVRDUDE is software for programming Atmel AVR Microcontrollers.
+Name: avrdude
+Version: @VERSION@
+Release: 1
+URL: http://savannah.nongnu.org/projects/avrdude
+Source0: %{name}-%{version}.tar.gz
+License: GPL
+Group: Development/Tools
+BuildRoot: %{_tmppath}/%{name}-%{version}-root
+
+%description
+AVRDUDE is software for programming Atmel AVR Microcontrollers.
+
+%if %{_with_docs}
+## The avrdude-docs subpackage
+%package docs
+Summary: Documentation for AVRDUDE.
+Group: Documentation
+%description docs
+Documentation for avrdude in info, html, postscript and pdf formats.
+%endif
+
+%prep
+%setup -q
+
+%build
+
+./configure --prefix=%{_prefix} --sysconfdir=/etc --mandir=%{_mandir} \
+ --infodir=%{_infodir} \
+%if %{_with_docs}
+ --enable-doc=yes
+%else
+ --enable-doc=no
+%endif
+
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make prefix=$RPM_BUILD_ROOT%{_prefix} \
+ sysconfdir=$RPM_BUILD_ROOT/etc \
+ mandir=$RPM_BUILD_ROOT%{_mandir} \
+ infodir=$RPM_BUILD_ROOT%{_infodir} \
+ install
+
+rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/%{name}-%{version}
+rm -f $RPM_BUILD_ROOT%{_infodir}/dir
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%if %{_with_docs}
+%post docs
+[ -f %{_infodir}/avrdude.info ] && \
+ /sbin/install-info %{_infodir}/avrdude.info %{_infodir}/dir || :
+[ -f %{_infodir}/avrdude.info.gz ] && \
+ /sbin/install-info %{_infodir}/avrdude.info.gz %{_infodir}/dir || :
+
+%preun docs
+if [ $1 = 0 ]; then
+ [ -f %{_infodir}/avrdude.info ] && \
+ /sbin/install-info --delete %{_infodir}/avrdude.info %{_infodir}/dir || :
+ [ -f %{_infodir}/avrdude.info.gz ] && \
+ /sbin/install-info --delete %{_infodir}/avrdude.info.gz %{_infodir}/dir || :
+fi
+%endif
+
+%files
+%defattr(-,root,root)
+%{_prefix}/bin/avrdude
+%{_mandir}/man1/avrdude.1.gz
+%attr(0644,root,root) %config /etc/avrdude.conf
+
+%if %{_with_docs}
+%files docs
+%doc %{_infodir}/*info*
+%doc doc/avrdude-html/*.html
+%doc doc/TODO
+%doc doc/avrdude.ps
+%doc doc/avrdude.pdf
+%endif
+
+%changelog
+* Fri Sep 23 2005 Galen Seitz <galens@seitzassoc.com>
+- Default to enable-doc=yes during configure.
+- Move info file to docs package.
+- Make building of docs package conditional. Basic idea copied from avr-gcc.
+
+* Wed Aug 27 2003 Theodore A. Roth <troth@openavr.org>
+ [Thanks to Artur Lipowski <LAL@pro.onet.pl>]
+- Do not build debug package.
+- Remove files not packaged to quell RH9 rpmbuild complaints.
+
+* Wed Mar 05 2003 Theodore A. Roth <troth@openavr.org>
+- Add docs sub-package.
+- Add %post and %preun scriptlets for handling info files.
+
+* Wed Feb 26 2003 Theodore A. Roth <troth@openavr.org>
+- Initial build.
+
+
diff --git a/xs/src/avrdude/avrftdi.c b/xs/src/avrdude/avrftdi.c
new file mode 100644
index 000000000..29d10332a
--- /dev/null
+++ b/xs/src/avrdude/avrftdi.c
@@ -0,0 +1,1275 @@
+/*
+ * avrftdi - extension for avrdude, Wolfgang Moser, Ville Voipio
+ * Copyright (C) 2011 Hannes Weisbach, Doug Springer
+ *
+ * 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$ */
+/*
+ * Interface to the MPSSE Engine of FTDI Chips using libftdi.
+ */
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdarg.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "avrftdi.h"
+#include "avrftdi_tpi.h"
+#include "avrftdi_private.h"
+#include "usbdevs.h"
+
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+#ifdef DO_NOT_BUILD_AVRFTDI
+
+static int avrftdi_noftdi_open (struct programmer_t *pgm, char * name)
+{
+ avrdude_message(MSG_INFO, "%s: Error: no libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.\n",
+ progname);
+
+ return -1;
+}
+
+void avrftdi_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "avrftdi");
+ pgm->open = avrftdi_noftdi_open;
+}
+
+#else
+
+enum { FTDI_SCK = 0, FTDI_MOSI, FTDI_MISO, FTDI_RESET };
+
+static int write_flush(avrftdi_t *);
+
+/*
+ * returns a human-readable name for a pin number. the name should match with
+ * the pin names used in FTDI datasheets.
+ */
+static char*
+ftdi_pin_name(avrftdi_t* pdata, struct pindef_t pin)
+{
+ static char str[128];
+
+ char interface = '@';
+
+ /* INTERFACE_ANY is zero, so @ is used
+ * INTERFACE_A is one, so '@' + 1 = 'A'
+ * and so forth ...
+ * be aware, there is an 'interface' member in ftdi_context,
+ * however, we really want the 'index' member here.
+ */
+ interface += pdata->ftdic->index;
+
+ int pinno;
+ int n = 0;
+ int mask = pin.mask[0];
+
+ const char * fmt;
+
+ str[0] = 0;
+
+ for(pinno = 0; mask; mask >>= 1, pinno++) {
+ if(!(mask & 1))
+ continue;
+
+ int chars = 0;
+
+ char port;
+ /* This is FTDI's naming scheme.
+ * probably 'D' is for data and 'C' for control
+ */
+ if(pinno < 8)
+ port = 'D';
+ else
+ port = 'C';
+
+ if(str[0] == 0)
+ fmt = "%c%cBUS%d%n";
+ else
+ fmt = ", %c%cBUS%d%n";
+
+ snprintf(&str[n], sizeof(str) - n, fmt, interface, port, pinno, &chars);
+ n += chars;
+ }
+
+ return str;
+}
+
+/*
+ * output function, to save if(vebose>level)-constructs. also prefixes output
+ * with "avrftdi function-name(line-number):" to identify were messages came
+ * from.
+ * This function is the backend of the log_*-macros, but it can be used
+ * directly.
+ */
+void avrftdi_log(int level, const char * func, int line,
+ const char * fmt, ...) {
+ static int skip_prefix = 0;
+ const char *p = fmt;
+ va_list ap;
+
+ if(verbose >= level)
+ {
+ if(!skip_prefix)
+ {
+ switch(level) {
+ case ERR: avrdude_message(MSG_INFO, "E "); break;
+ case WARN: avrdude_message(MSG_INFO, "W "); break;
+ case INFO: avrdude_message(MSG_INFO, "I "); break;
+ case DEBUG: avrdude_message(MSG_INFO, "D "); break;
+ case TRACE: avrdude_message(MSG_INFO, "T "); break;
+ default: avrdude_message(MSG_INFO, " "); break;
+ }
+ avrdude_message(MSG_INFO, "%s(%d): ", func, line);
+ }
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ }
+
+ skip_prefix = 1;
+ while(*p++)
+ if(*p == '\n' && !(*(p+1)))
+ skip_prefix = 0;
+}
+
+/*
+ * helper function to print a binary buffer *buf of size len. begin and end of
+ * the dump are enclosed in the string contained in *desc. offset denotes the
+ * number of bytes which are printed on the first line (may be 0). after that
+ * width bytes are printed on each line
+ */
+static void buf_dump(const unsigned char *buf, int len, char *desc,
+ int offset, int width)
+{
+ int i;
+ avrdude_message(MSG_INFO, "%s begin:\n", desc);
+ for (i = 0; i < offset; i++)
+ avrdude_message(MSG_INFO, "%02x ", buf[i]);
+ avrdude_message(MSG_INFO, "\n");
+ for (i++; i <= len; i++) {
+ avrdude_message(MSG_INFO, "%02x ", buf[i-1]);
+ if((i-offset) != 0 && (i-offset)%width == 0)
+ avrdude_message(MSG_INFO, "\n");
+ }
+ avrdude_message(MSG_INFO, "%s end\n", desc);
+}
+
+/*
+ * calculates the so-called 'divisor'-value from a given frequency.
+ * the divisor is sent to the chip.
+ */
+static int set_frequency(avrftdi_t* ftdi, uint32_t freq)
+{
+ int32_t divisor;
+ uint8_t buf[3];
+
+ /* divisor on 6000000 / freq - 1 */
+ divisor = (6000000 / freq) - 1;
+ if (divisor < 0) {
+ log_warn("Frequency too high (%u > 6 MHz)\n", freq);
+ log_warn("Resetting Frequency to 6MHz\n");
+ divisor = 0;
+ }
+
+ if (divisor > 65535) {
+ log_warn("Frequency too low (%u < 91.553 Hz)\n", freq);
+ log_warn("Resetting Frequency to 91.553Hz\n");
+ divisor = 65535;
+ }
+
+ log_info("Using frequency: %d\n", 6000000/(divisor+1));
+ log_info("Clock divisor: 0x%04x\n", divisor);
+
+ buf[0] = TCK_DIVISOR;
+ buf[1] = (uint8_t)(divisor & 0xff);
+ buf[2] = (uint8_t)((divisor >> 8) & 0xff);
+
+ E(ftdi_write_data(ftdi->ftdic, buf, 3) < 0, ftdi->ftdic);
+
+ return 0;
+}
+
+/*
+ * This function sets or clears any pin, except SCK, MISO and MOSI. Depending
+ * on the pin configuration, a non-zero value sets the pin in the 'active'
+ * state (high active, low active) and a zero value sets the pin in the
+ * inactive state.
+ * Because we configured the pin direction mask earlier, nothing bad can happen
+ * here.
+ */
+static int set_pin(PROGRAMMER * pgm, int pinfunc, int value)
+{
+ avrftdi_t* pdata = to_pdata(pgm);
+ struct pindef_t pin = pgm->pin[pinfunc];
+
+ if (pin.mask[0] == 0) {
+ // ignore not defined pins (might be the led or vcc or buff if not needed)
+ return 0;
+ }
+
+ log_debug("Setting pin %s (%s) as %s: %s (%s active)\n",
+ pinmask_to_str(pin.mask), ftdi_pin_name(pdata, pin),
+ avr_pin_name(pinfunc),
+ (value) ? "high" : "low", (pin.inverse[0]) ? "low" : "high");
+
+ pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, pinfunc, value);
+
+ return write_flush(pdata);
+}
+
+/*
+ * Mandatory callbacks which boil down to GPIO.
+ */
+static int set_led_pgm(struct programmer_t * pgm, int value)
+{
+ return set_pin(pgm, PIN_LED_PGM, value);
+}
+
+static int set_led_rdy(struct programmer_t * pgm, int value)
+{
+ return set_pin(pgm, PIN_LED_RDY, value);
+}
+
+static int set_led_err(struct programmer_t * pgm, int value)
+{
+ return set_pin(pgm, PIN_LED_ERR, value);
+}
+
+static int set_led_vfy(struct programmer_t * pgm, int value)
+{
+ return set_pin(pgm, PIN_LED_VFY, value);
+}
+
+static void avrftdi_enable(PROGRAMMER * pgm)
+{
+ set_pin(pgm, PPI_AVR_BUFF, ON);
+}
+
+static void avrftdi_disable(PROGRAMMER * pgm)
+{
+ set_pin(pgm, PPI_AVR_BUFF, OFF);
+}
+
+static void avrftdi_powerup(PROGRAMMER * pgm)
+{
+ set_pin(pgm, PPI_AVR_VCC, ON);
+}
+
+static void avrftdi_powerdown(PROGRAMMER * pgm)
+{
+ set_pin(pgm, PPI_AVR_VCC, OFF);
+}
+
+static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char data, bool read_data) {
+ int j;
+ int buf_pos = 0;
+ unsigned char bit = 0x80;
+ avrftdi_t* pdata = to_pdata(pgm);
+
+ for (j=0; j<8; j++) {
+ pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_MOSI,data & bit);
+ pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SCK,0);
+ buf[buf_pos++] = SET_BITS_LOW;
+ buf[buf_pos++] = (pdata->pin_value) & 0xff;
+ buf[buf_pos++] = (pdata->pin_direction) & 0xff;
+ buf[buf_pos++] = SET_BITS_HIGH;
+ buf[buf_pos++] = ((pdata->pin_value) >> 8) & 0xff;
+ buf[buf_pos++] = ((pdata->pin_direction) >> 8) & 0xff;
+
+ pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SCK,1);
+ buf[buf_pos++] = SET_BITS_LOW;
+ buf[buf_pos++] = (pdata->pin_value) & 0xff;
+ buf[buf_pos++] = (pdata->pin_direction) & 0xff;
+ buf[buf_pos++] = SET_BITS_HIGH;
+ buf[buf_pos++] = ((pdata->pin_value) >> 8) & 0xff;
+ buf[buf_pos++] = ((pdata->pin_direction) >> 8) & 0xff;
+
+ if (read_data) {
+ buf[buf_pos++] = GET_BITS_LOW;
+ buf[buf_pos++] = GET_BITS_HIGH;
+ }
+
+ bit >>= 1;
+ }
+ return buf_pos;
+}
+
+static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, int offset) {
+ int j;
+ unsigned char bit = 0x80;
+ unsigned char r = 0;
+
+ buf += offset * 16; // 2 bytes per bit, 8 bits
+ for (j=0; j<8; j++) {
+ uint16_t in = buf[0] | (buf[1] << 8);
+ if (GET_BITS_0(in,pgm,PIN_AVR_MISO)) {
+ r |= bit;
+ }
+ buf += 2; // 2 bytes per input
+ bit >>= 1;
+ }
+ return r;
+}
+
+
+static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, const unsigned char *buf,
+ unsigned char *data, int buf_size)
+{
+ size_t remaining = buf_size;
+ size_t written = 0;
+ avrftdi_t* pdata = to_pdata(pgm);
+ size_t blocksize = pdata->rx_buffer_size/2; // we are reading 2 bytes per data byte
+
+ // determine a maximum size of data block
+ size_t max_size = MIN(pdata->ftdic->max_packet_size,pdata->tx_buffer_size);
+ // select block size so that resulting commands does not exceed max_size if possible
+ blocksize = MAX(1,(max_size-7)/((8*2*6)+(8*1*2)));
+ //avrdude_message(MSG_INFO, "blocksize %d \n",blocksize);
+
+ while(remaining)
+ {
+
+ size_t transfer_size = (remaining > blocksize) ? blocksize : remaining;
+
+ // (8*2) outputs per data byte, 6 transmit bytes per output (SET_BITS_LOW/HIGH),
+ // (8*1) inputs per data byte, 2 transmit bytes per input (GET_BITS_LOW/HIGH),
+ // 1x SEND_IMMEDIATE
+ unsigned char send_buffer[(8*2*6)*transfer_size+(8*1*2)*transfer_size+7];
+ int len = 0;
+ int i;
+
+ for(i = 0 ; i< transfer_size; i++) {
+ len += set_data(pgm, send_buffer + len, buf[written+i], (mode & MPSSE_DO_READ) != 0);
+ }
+
+ pdata->pin_value = SET_BITS_0(pdata->pin_value,pgm,PIN_AVR_SCK,0);
+ send_buffer[len++] = SET_BITS_LOW;
+ send_buffer[len++] = (pdata->pin_value) & 0xff;
+ send_buffer[len++] = (pdata->pin_direction) & 0xff;
+ send_buffer[len++] = SET_BITS_HIGH;
+ send_buffer[len++] = ((pdata->pin_value) >> 8) & 0xff;
+ send_buffer[len++] = ((pdata->pin_direction) >> 8) & 0xff;
+
+ send_buffer[len++] = SEND_IMMEDIATE;
+
+ E(ftdi_write_data(pdata->ftdic, send_buffer, len) != len, pdata->ftdic);
+ if (mode & MPSSE_DO_READ) {
+ unsigned char recv_buffer[2*16*transfer_size];
+ int n;
+ int k = 0;
+ do {
+ n = ftdi_read_data(pdata->ftdic, &recv_buffer[k], 2*16*transfer_size - k);
+ E(n < 0, pdata->ftdic);
+ k += n;
+ } while (k < transfer_size);
+
+ for(i = 0 ; i< transfer_size; i++) {
+ data[written + i] = extract_data(pgm, recv_buffer, i);
+ }
+ }
+
+ written += transfer_size;
+ remaining -= transfer_size;
+ }
+
+ return written;
+}
+
+/* Send 'buf_size' bytes from 'cmd' to device and return data from device in
+ * buffer 'data'.
+ * Write is only performed when mode contains MPSSE_DO_WRITE.
+ * Read is only performed when mode contains MPSSE_DO_WRITE and MPSSE_DO_READ.
+ */
+static int avrftdi_transmit_mpsse(avrftdi_t* pdata, unsigned char mode, const unsigned char *buf,
+ unsigned char *data, int buf_size)
+{
+ size_t blocksize;
+ size_t remaining = buf_size;
+ size_t written = 0;
+
+ unsigned char cmd[3];
+// unsigned char si = SEND_IMMEDIATE;
+
+ cmd[0] = mode | MPSSE_WRITE_NEG;
+ cmd[1] = ((buf_size - 1) & 0xff);
+ cmd[2] = (((buf_size - 1) >> 8) & 0xff);
+
+ //if we are not reading back, we can just write the data out
+ if(!(mode & MPSSE_DO_READ))
+ blocksize = buf_size;
+ else
+ blocksize = pdata->rx_buffer_size;
+
+ E(ftdi_write_data(pdata->ftdic, cmd, sizeof(cmd)) != sizeof(cmd), pdata->ftdic);
+
+ while(remaining)
+ {
+ size_t transfer_size = (remaining > blocksize) ? blocksize : remaining;
+
+ E(ftdi_write_data(pdata->ftdic, (unsigned char*)&buf[written], transfer_size) != transfer_size, pdata->ftdic);
+#if 0
+ if(remaining < blocksize)
+ E(ftdi_write_data(pdata->ftdic, &si, sizeof(si)) != sizeof(si), pdata->ftdic);
+#endif
+
+ if (mode & MPSSE_DO_READ) {
+ int n;
+ int k = 0;
+ do {
+ n = ftdi_read_data(pdata->ftdic, &data[written + k], transfer_size - k);
+ E(n < 0, pdata->ftdic);
+ k += n;
+ } while (k < transfer_size);
+
+ }
+
+ written += transfer_size;
+ remaining -= transfer_size;
+ }
+
+ return written;
+}
+
+static inline int avrftdi_transmit(PROGRAMMER * pgm, unsigned char mode, const unsigned char *buf,
+ unsigned char *data, int buf_size)
+{
+ avrftdi_t* pdata = to_pdata(pgm);
+ if (pdata->use_bitbanging)
+ return avrftdi_transmit_bb(pgm, mode, buf, data, buf_size);
+ else
+ return avrftdi_transmit_mpsse(pdata, mode, buf, data, buf_size);
+}
+
+static int write_flush(avrftdi_t* pdata)
+{
+ unsigned char buf[6];
+
+ log_debug("Setting pin direction (0x%04x) and value (0x%04x)\n",
+ pdata->pin_direction, pdata->pin_value);
+
+ buf[0] = SET_BITS_LOW;
+ buf[1] = (pdata->pin_value) & 0xff;
+ buf[2] = (pdata->pin_direction) & 0xff;
+ buf[3] = SET_BITS_HIGH;
+ buf[4] = ((pdata->pin_value) >> 8) & 0xff;
+ buf[5] = ((pdata->pin_direction) >> 8) & 0xff;
+
+ E(ftdi_write_data(pdata->ftdic, buf, 6) != 6, pdata->ftdic);
+
+ log_trace("Set pins command: %02x %02x %02x %02x %02x %02x\n",
+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
+
+ /* we need to flush here, because set_pin is used as reset.
+ * if we want to sleep reset periods, we must be certain the
+ * avr has got the reset signal when we start sleeping.
+ * (it may be stuck in the USB stack or some USB hub)
+ *
+ * Add.: purge does NOT flush. It clears. Also, it is unknown, when the purge
+ * command actually arrives at the chip.
+ * Use read pin status command as sync.
+ */
+ //E(ftdi_usb_purge_buffers(pdata->ftdic), pdata->ftdic);
+
+ unsigned char cmd[] = { GET_BITS_LOW, SEND_IMMEDIATE };
+ E(ftdi_write_data(pdata->ftdic, cmd, sizeof(cmd)) != sizeof(cmd), pdata->ftdic);
+
+ int num = 0;
+ do
+ {
+ int n = ftdi_read_data(pdata->ftdic, buf, sizeof(buf));
+ if(n > 0)
+ num += n;
+ E(n < 0, pdata->ftdic);
+ } while(num < 1);
+
+ if(num > 1)
+ log_warn("Read %d extra bytes\n", num-1);
+
+ return 0;
+
+}
+
+static int avrftdi_check_pins_bb(PROGRAMMER * pgm, bool output)
+{
+ int pin;
+
+ /* pin checklist. */
+ struct pin_checklist_t pin_checklist[N_PINS];
+
+ avrftdi_t* pdata = to_pdata(pgm);
+
+ /* value for 8/12/16 bit wide interface */
+ int valid_mask = ((1 << pdata->pin_limit) - 1);
+
+ log_debug("Using valid mask bibanging: 0x%08x\n", valid_mask);
+ static struct pindef_t valid_pins;
+ valid_pins.mask[0] = valid_mask;
+ valid_pins.inverse[0] = valid_mask ;
+
+ /* build pin checklist */
+ for(pin = 0; pin < N_PINS; ++pin) {
+ pin_checklist[pin].pinname = pin;
+ pin_checklist[pin].mandatory = 0;
+ pin_checklist[pin].valid_pins = &valid_pins;
+ }
+
+ /* assumes all checklists above have same number of entries */
+ return pins_check(pgm, pin_checklist, N_PINS, output);
+}
+
+static int avrftdi_check_pins_mpsse(PROGRAMMER * pgm, bool output)
+{
+ int pin;
+
+ /* pin checklist. */
+ struct pin_checklist_t pin_checklist[N_PINS];
+
+ avrftdi_t* pdata = to_pdata(pgm);
+
+ /* SCK/MOSI/MISO are fixed and not invertable?*/
+ /* TODO: inverted SCK/MISO/MOSI */
+ static const struct pindef_t valid_pins_SCK = {{0x01},{0x00}} ;
+ static const struct pindef_t valid_pins_MOSI = {{0x02},{0x00}} ;
+ static const struct pindef_t valid_pins_MISO = {{0x04},{0x00}} ;
+
+ /* value for 8/12/16 bit wide interface for other pins */
+ int valid_mask = ((1 << pdata->pin_limit) - 1);
+ /* mask out SCK/MISO/MOSI */
+ valid_mask &= ~((1 << FTDI_SCK) | (1 << FTDI_MOSI) | (1 << FTDI_MISO));
+
+ log_debug("Using valid mask mpsse: 0x%08x\n", valid_mask);
+ static struct pindef_t valid_pins_others;
+ valid_pins_others.mask[0] = valid_mask;
+ valid_pins_others.inverse[0] = valid_mask ;
+
+ /* build pin checklist */
+ for(pin = 0; pin < N_PINS; ++pin) {
+ pin_checklist[pin].pinname = pin;
+ pin_checklist[pin].mandatory = 0;
+ pin_checklist[pin].valid_pins = &valid_pins_others;
+ }
+
+ /* now set mpsse specific pins */
+ pin_checklist[PIN_AVR_SCK].mandatory = 1;
+ pin_checklist[PIN_AVR_SCK].valid_pins = &valid_pins_SCK;
+ pin_checklist[PIN_AVR_MOSI].mandatory = 1;
+ pin_checklist[PIN_AVR_MOSI].valid_pins = &valid_pins_MOSI;
+ pin_checklist[PIN_AVR_MISO].mandatory = 1;
+ pin_checklist[PIN_AVR_MISO].valid_pins = &valid_pins_MISO;
+ pin_checklist[PIN_AVR_RESET].mandatory = 1;
+
+ /* assumes all checklists above have same number of entries */
+ return pins_check(pgm, pin_checklist, N_PINS, output);
+}
+
+static int avrftdi_pin_setup(PROGRAMMER * pgm)
+{
+ int pin;
+
+ /*************
+ * pin setup *
+ *************/
+
+ avrftdi_t* pdata = to_pdata(pgm);
+
+ bool pin_check_mpsse = (0 == avrftdi_check_pins_mpsse(pgm, verbose>3));
+
+ bool pin_check_bitbanging = (0 == avrftdi_check_pins_bb(pgm, verbose>3));
+
+ if (!pin_check_mpsse && !pin_check_bitbanging) {
+ log_err("No valid pin configuration found.\n");
+ avrftdi_check_pins_bb(pgm, true);
+ log_err("Pin configuration for FTDI MPSSE must be:\n");
+ log_err("%s: 0, %s: 1, %s: 2 (is: %s, %s, %s)\n", avr_pin_name(PIN_AVR_SCK),
+ avr_pin_name(PIN_AVR_MOSI), avr_pin_name(PIN_AVR_MISO),
+ pins_to_str(&pgm->pin[PIN_AVR_SCK]),
+ pins_to_str(&pgm->pin[PIN_AVR_MOSI]),
+ pins_to_str(&pgm->pin[PIN_AVR_MISO]));
+ log_err("If other pin configuration is used, fallback to slower bitbanging mode is used.\n");
+
+ return -1;
+ }
+
+ pdata->use_bitbanging = !pin_check_mpsse;
+ if (pdata->use_bitbanging) log_info("Because of pin configuration fallback to bitbanging mode.\n");
+
+ /*
+ * TODO: No need to fail for a wrongly configured led or something.
+ * Maybe we should only fail for SCK; MISO, MOSI, RST (and probably
+ * VCC and BUFF).
+ */
+
+ /* everything is an output, except MISO */
+ for(pin = 0; pin < N_PINS; ++pin) {
+ pdata->pin_direction |= pgm->pin[pin].mask[0];
+ pdata->pin_value = SET_BITS_0(pdata->pin_value, pgm, pin, OFF);
+ }
+ pdata->pin_direction &= ~pgm->pin[PIN_AVR_MISO].mask[0];
+
+ for(pin = PIN_LED_ERR; pin < N_PINS; ++pin) {
+ pdata->led_mask |= pgm->pin[pin].mask[0];
+ }
+
+
+ log_info("Pin direction mask: %04x\n", pdata->pin_direction);
+ log_info("Pin value mask: %04x\n", pdata->pin_value);
+
+ return 0;
+}
+
+static int avrftdi_open(PROGRAMMER * pgm, char *port)
+{
+ int vid, pid, interface, index, err;
+ char * serial, *desc;
+
+ avrftdi_t* pdata = to_pdata(pgm);
+
+ /************************
+ * parameter validation *
+ ************************/
+
+ /* use vid/pid in following priority: config,
+ * defaults. cmd-line is currently not supported */
+
+ if (pgm->usbvid)
+ vid = pgm->usbvid;
+ else
+ vid = USB_VENDOR_FTDI;
+
+ LNODEID usbpid = lfirst(pgm->usbpid);
+ if (usbpid) {
+ pid = *(int *)(ldata(usbpid));
+ if (lnext(usbpid))
+ avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
+ progname, pid);
+ } else
+ pid = USB_DEVICE_FT2232;
+
+ if (0 == pgm->usbsn[0]) /* we don't care about SN. Use first avail. */
+ serial = NULL;
+ else
+ serial = pgm->usbsn;
+
+ /* not used yet, but i put them here, just in case someone does needs or
+ * wants to implement this.
+ */
+ desc = NULL;
+ index = 0;
+
+ if (pgm->usbdev[0] == 'a' || pgm->usbdev[0] == 'A')
+ interface = INTERFACE_A;
+ else if (pgm->usbdev[0] == 'b' || pgm->usbdev[0] == 'B')
+ interface = INTERFACE_B;
+ else {
+ log_warn("Invalid interface '%s'. Setting to Interface A\n", pgm->usbdev);
+ interface = INTERFACE_A;
+ }
+
+ /****************
+ * Device setup *
+ ****************/
+
+ E(ftdi_set_interface(pdata->ftdic, interface) < 0, pdata->ftdic);
+
+ err = ftdi_usb_open_desc_index(pdata->ftdic, vid, pid, desc, serial, index);
+ if(err) {
+ log_err("Error %d occurred: %s\n", err, ftdi_get_error_string(pdata->ftdic));
+ //stupid hack, because avrdude calls pgm->close() even when pgm->open() fails
+ //and usb_dev is intialized to the last usb device from probing
+ pdata->ftdic->usb_dev = NULL;
+ return err;
+ } else {
+ log_info("Using device VID:PID %04x:%04x and SN '%s' on interface %c.\n",
+ vid, pid, serial, INTERFACE_A == interface? 'A': 'B');
+ }
+
+ ftdi_set_latency_timer(pdata->ftdic, 1);
+ //ftdi_write_data_set_chunksize(pdata->ftdic, 16);
+ //ftdi_read_data_set_chunksize(pdata->ftdic, 16);
+
+ /* set SPI mode */
+ E(ftdi_set_bitmode(pdata->ftdic, 0, BITMODE_RESET) < 0, pdata->ftdic);
+ E(ftdi_set_bitmode(pdata->ftdic, pdata->pin_direction & 0xff, BITMODE_MPSSE) < 0, pdata->ftdic);
+ E(ftdi_usb_purge_buffers(pdata->ftdic), pdata->ftdic);
+
+ write_flush(pdata);
+
+ if (pgm->baudrate) {
+ set_frequency(pdata, pgm->baudrate);
+ } else if(pgm->bitclock) {
+ set_frequency(pdata, (uint32_t)(1.0f/pgm->bitclock));
+ } else {
+ set_frequency(pdata, pgm->baudrate ? pgm->baudrate : 150000);
+ }
+
+ /* set pin limit depending on chip type */
+ switch(pdata->ftdic->type) {
+ case TYPE_AM:
+ case TYPE_BM:
+ case TYPE_R:
+ log_err("Found unsupported device type AM, BM or R. avrftdi ");
+ log_err("cannot work with your chip. Try the 'synbb' programmer.\n");
+ return -1;
+ case TYPE_2232C:
+ pdata->pin_limit = 12;
+ pdata->rx_buffer_size = 384;
+ pdata->tx_buffer_size = 128;
+ break;
+ case TYPE_2232H:
+ pdata->pin_limit = 16;
+ pdata->rx_buffer_size = 4096;
+ pdata->tx_buffer_size = 4096;
+ break;
+#ifdef HAVE_LIBFTDI_TYPE_232H
+ case TYPE_232H:
+ pdata->pin_limit = 16;
+ pdata->rx_buffer_size = 1024;
+ pdata->tx_buffer_size = 1024;
+ break;
+#else
+#warning No support for 232H, use a newer libftdi, version >= 0.20
+#endif
+ case TYPE_4232H:
+ pdata->pin_limit = 8;
+ pdata->rx_buffer_size = 2048;
+ pdata->tx_buffer_size = 2048;
+ break;
+ default:
+ log_warn("Found unknown device %x. I will do my ", pdata->ftdic->type);
+ log_warn("best to work with it, but no guarantees ...\n");
+ pdata->pin_limit = 8;
+ pdata->rx_buffer_size = pdata->ftdic->max_packet_size;
+ pdata->tx_buffer_size = pdata->ftdic->max_packet_size;
+ break;
+ }
+
+ if(avrftdi_pin_setup(pgm))
+ return -1;
+
+ /**********************************************
+ * set the ready LED and set our direction up *
+ **********************************************/
+
+ set_led_rdy(pgm,0);
+ set_led_pgm(pgm,1);
+
+ return 0;
+}
+
+static void avrftdi_close(PROGRAMMER * pgm)
+{
+ avrftdi_t* pdata = to_pdata(pgm);
+
+ if(pdata->ftdic->usb_dev) {
+ set_pin(pgm, PIN_AVR_RESET, ON);
+
+ /* Stop driving the pins - except for the LEDs */
+ log_info("LED Mask=0x%04x value =0x%04x &=0x%04x\n",
+ pdata->led_mask, pdata->pin_value, pdata->led_mask & pdata->pin_value);
+
+ pdata->pin_direction = pdata->led_mask;
+ pdata->pin_value &= pdata->led_mask;
+ write_flush(pdata);
+ /* reset state recommended by FTDI */
+ ftdi_set_bitmode(pdata->ftdic, 0, BITMODE_RESET);
+ E_VOID(ftdi_usb_close(pdata->ftdic), pdata->ftdic);
+ }
+
+ return;
+}
+
+static int avrftdi_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ avrftdi_powerup(pgm);
+
+ if(p->flags & AVRPART_HAS_TPI)
+ {
+ /* see avrftdi_tpi.c */
+ avrftdi_tpi_initialize(pgm, p);
+ }
+ else
+ {
+ set_pin(pgm, PIN_AVR_RESET, OFF);
+ set_pin(pgm, PIN_AVR_SCK, OFF);
+ /*use speed optimization with CAUTION*/
+ usleep(20 * 1000);
+
+ /* giving rst-pulse of at least 2 avr-clock-cycles, for
+ * security (2us @ 1MHz) */
+ set_pin(pgm, PIN_AVR_RESET, ON);
+ usleep(20 * 1000);
+
+ /*setting rst back to 0 */
+ set_pin(pgm, PIN_AVR_RESET, OFF);
+ /*wait at least 20ms bevor issuing spi commands to avr */
+ usleep(20 * 1000);
+ }
+
+ return pgm->program_enable(pgm, p);
+}
+
+static void avrftdi_display(PROGRAMMER * pgm, const char *p)
+{
+ // print the full pin definitiions as in ft245r ?
+ return;
+}
+
+
+static int avrftdi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res)
+{
+ return avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, res, 4);
+}
+
+
+static int avrftdi_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ int i;
+ unsigned char buf[4];
+
+ memset(buf, 0, sizeof(buf));
+
+ if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
+ log_err("AVR_OP_PGM_ENABLE command not defined for %s\n", p->desc);
+ return -1;
+ }
+
+ avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf);
+
+ for(i = 0; i < 4; i++) {
+ pgm->cmd(pgm, buf, buf);
+ if (buf[p->pollindex-1] != p->pollvalue) {
+ log_warn("Program enable command not successful. Retrying.\n");
+ set_pin(pgm, PIN_AVR_RESET, ON);
+ usleep(20);
+ set_pin(pgm, PIN_AVR_RESET, OFF);
+ avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf);
+ } else
+ return 0;
+ }
+
+ log_err("Device is not responding to program enable. Check connection.\n");
+
+ return -1;
+}
+
+
+static int avrftdi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+
+ if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
+ log_err("AVR_OP_CHIP_ERASE command not defined for %s\n", p->desc);
+ return -1;
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
+ pgm->cmd(pgm, cmd, res);
+ usleep(p->chip_erase_delay);
+ pgm->initialize(pgm, p);
+
+ return 0;
+}
+
+
+/* Load extended address byte command */
+static int
+avrftdi_lext(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m, unsigned int address)
+{
+ unsigned char buf[] = { 0x00, 0x00, 0x00, 0x00 };
+
+ avr_set_bits(m->op[AVR_OP_LOAD_EXT_ADDR], buf);
+ avr_set_addr(m->op[AVR_OP_LOAD_EXT_ADDR], buf, address);
+
+ if(verbose > TRACE)
+ buf_dump(buf, sizeof(buf),
+ "load extended address command", 0, 16 * 3);
+
+ if (0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, 4))
+ return -1;
+
+ return 0;
+}
+
+static int avrftdi_eeprom_write(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
+ unsigned int page_size, unsigned int addr, unsigned int len)
+{
+ unsigned char cmd[] = { 0x00, 0x00, 0x00, 0x00 };
+ unsigned char *data = &m->buf[addr];
+ unsigned int add;
+
+ avr_set_bits(m->op[AVR_OP_WRITE], cmd);
+
+ for (add = addr; add < addr + len; add++)
+ {
+ avr_set_addr(m->op[AVR_OP_WRITE], cmd, add);
+ avr_set_input(m->op[AVR_OP_WRITE], cmd, *data++);
+
+ if (0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, cmd, cmd, 4))
+ return -1;
+ usleep((m->max_write_delay));
+
+ }
+ return len;
+}
+
+static int avrftdi_eeprom_read(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m,
+ unsigned int page_size, unsigned int addr, unsigned int len)
+{
+ unsigned char cmd[4];
+ unsigned char buffer[len], *bufptr = buffer;
+ unsigned int add;
+
+ memset(buffer, 0, sizeof(buffer));
+ for (add = addr; add < addr + len; add++)
+ {
+ memset(cmd, 0, sizeof(cmd));
+ avr_set_bits(m->op[AVR_OP_READ], cmd);
+ avr_set_addr(m->op[AVR_OP_READ], cmd, add);
+
+ if (0 > avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, cmd, cmd, 4))
+ return -1;
+
+ avr_get_output(m->op[AVR_OP_READ], cmd, bufptr++);
+ }
+
+ memcpy(m->buf + addr, buffer, len);
+ return len;
+}
+
+static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size, unsigned int addr, unsigned int len)
+{
+ int use_lext_address = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
+
+ unsigned int word;
+ unsigned int poll_index;
+ unsigned int buf_size;
+
+ unsigned char poll_byte;
+ unsigned char *buffer = &m->buf[addr];
+ unsigned char buf[4*len+4], *bufptr = buf;
+
+ memset(buf, 0, sizeof(buf));
+
+ /* pre-check opcodes */
+ if (m->op[AVR_OP_LOADPAGE_LO] == NULL) {
+ log_err("AVR_OP_LOADPAGE_LO command not defined for %s\n", p->desc);
+ return -1;
+ }
+ if (m->op[AVR_OP_LOADPAGE_HI] == NULL) {
+ log_err("AVR_OP_LOADPAGE_HI command not defined for %s\n", p->desc);
+ return -1;
+ }
+
+ if(page_size != m->page_size) {
+ log_warn("Parameter page_size is %d, ", page_size);
+ log_warn("but m->page_size is %d. Using the latter.\n", m->page_size);
+ }
+
+ page_size = m->page_size;
+
+ /* if we do cross a 64k word boundary (or write the
+ * first page), we need to issue a 'load extended
+ * address byte' command, which is defined as 0x4d
+ * 0x00 <address byte> 0x00. As far as i know, this
+ * is only available on 256k parts. 64k word is 128k
+ * bytes.
+ * write the command only once.
+ */
+ if(use_lext_address && (((addr/2) & 0xffff0000))) {
+ if (0 > avrftdi_lext(pgm, p, m, addr/2))
+ return -1;
+ }
+
+ /* prepare the command stream for the whole page */
+ /* addr is in bytes, but we program in words. addr/2 should be something
+ * like addr >> WORD_SHIFT, though */
+ for(word = addr/2; word < (len + addr)/2; word++)
+ {
+ log_debug("-< bytes = %d of %d\n", word * 2, len + addr);
+
+ /*setting word*/
+ avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], bufptr);
+ /* here is the second byte increment, just if you're wondering */
+ avr_set_addr(m->op[AVR_OP_LOADPAGE_LO], bufptr, word);
+ avr_set_input(m->op[AVR_OP_LOADPAGE_LO], bufptr, *buffer++);
+ bufptr += 4;
+ avr_set_bits(m->op[AVR_OP_LOADPAGE_HI], bufptr);
+ avr_set_addr(m->op[AVR_OP_LOADPAGE_HI], bufptr, word);
+ avr_set_input(m->op[AVR_OP_LOADPAGE_HI], bufptr, *buffer++);
+ bufptr += 4;
+ }
+
+ /* issue write page command, if available */
+ if (m->op[AVR_OP_WRITEPAGE] == NULL) {
+ log_err("AVR_OP_WRITEPAGE command not defined for %s\n", p->desc);
+ return -1;
+ } else {
+ avr_set_bits(m->op[AVR_OP_WRITEPAGE], bufptr);
+ /* setting page address highbyte */
+ avr_set_addr(m->op[AVR_OP_WRITEPAGE],
+ bufptr, addr/2);
+ bufptr += 4;
+ }
+
+ buf_size = bufptr - buf;
+
+ if(verbose > TRACE)
+ buf_dump(buf, buf_size, "command buffer", 0, 16*2);
+
+ log_info("Transmitting buffer of size: %d\n", buf_size);
+ if (0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, buf_size))
+ return -1;
+
+ bufptr = buf;
+ /* find a poll byte. we cannot poll a value of 0xff, so look
+ * for a value != 0xff
+ */
+ for(poll_index = addr+len-1; poll_index > addr-1; poll_index--)
+ if(m->buf[poll_index] != 0xff)
+ break;
+
+ if((poll_index < addr + len) && m->buf[poll_index] != 0xff)
+ {
+ log_info("Using m->buf[%d] = 0x%02x as polling value ", poll_index,
+ m->buf[poll_index]);
+ /* poll page write ready */
+ do {
+ log_info(".");
+
+ pgm->read_byte(pgm, p, m, poll_index, &poll_byte);
+ } while (m->buf[poll_index] != poll_byte);
+
+ log_info("\n");
+ }
+ else
+ {
+ log_warn("No suitable byte (!=0xff) for polling found.\n");
+ log_warn("Trying to sleep instead, but programming errors may occur.\n");
+ log_warn("Be sure to verify programmed memory (no -V option)\n");
+ /* TODO sync write */
+ /* sleep */
+ usleep((m->max_write_delay));
+ }
+
+ return len;
+}
+
+/*
+ *Reading from flash
+ */
+static int avrftdi_flash_read(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size, unsigned int addr, unsigned int len)
+{
+ OPCODE * readop;
+ int byte, word;
+ int use_lext_address = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
+ unsigned int address = addr/2;
+
+ unsigned char o_buf[4*len+4];
+ unsigned char i_buf[4*len+4];
+ unsigned int index;
+
+
+ memset(o_buf, 0, sizeof(o_buf));
+ memset(i_buf, 0, sizeof(i_buf));
+
+ /* pre-check opcodes */
+ if (m->op[AVR_OP_READ_LO] == NULL) {
+ log_err("AVR_OP_READ_LO command not defined for %s\n", p->desc);
+ return -1;
+ }
+ if (m->op[AVR_OP_READ_HI] == NULL) {
+ log_err("AVR_OP_READ_HI command not defined for %s\n", p->desc);
+ return -1;
+ }
+
+ if(use_lext_address && ((address & 0xffff0000))) {
+ if (0 > avrftdi_lext(pgm, p, m, address))
+ return -1;
+ }
+
+ /* word addressing! */
+ for(word = addr/2, index = 0; word < (addr + len)/2; word++)
+ {
+ /* one byte is transferred via a 4-byte opcode.
+ * TODO: reduce magic numbers
+ */
+ avr_set_bits(m->op[AVR_OP_READ_LO], &o_buf[index*4]);
+ avr_set_addr(m->op[AVR_OP_READ_LO], &o_buf[index*4], word);
+ index++;
+ avr_set_bits(m->op[AVR_OP_READ_HI], &o_buf[index*4]);
+ avr_set_addr(m->op[AVR_OP_READ_HI], &o_buf[index*4], word);
+ index++;
+ }
+
+ /* transmit,
+ * if there was an error, we did not see, memory validation will
+ * subsequently fail.
+ */
+ if(verbose > TRACE) {
+ buf_dump(o_buf, sizeof(o_buf), "o_buf", 0, 32);
+ }
+
+ if (0 > avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4))
+ return -1;
+
+ if(verbose > TRACE) {
+ buf_dump(i_buf, sizeof(i_buf), "i_buf", 0, 32);
+ }
+
+ memset(&m->buf[addr], 0, page_size);
+
+ /* every (read) op is 4 bytes in size and yields one byte of memory data */
+ for(byte = 0; byte < page_size; byte++) {
+ if(byte & 1)
+ readop = m->op[AVR_OP_READ_HI];
+ else
+ readop = m->op[AVR_OP_READ_LO];
+
+ /* take 4 bytes and put the memory byte in the buffer at
+ * offset addr + offset of the current byte
+ */
+ avr_get_output(readop, &i_buf[byte*4], &m->buf[addr+byte]);
+ }
+
+ if(verbose > TRACE)
+ buf_dump(&m->buf[addr], page_size, "page:", 0, 32);
+
+ return len;
+}
+
+static int avrftdi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ if (strcmp(m->desc, "flash") == 0)
+ return avrftdi_flash_write(pgm, p, m, page_size, addr, n_bytes);
+ else if (strcmp(m->desc, "eeprom") == 0)
+ return avrftdi_eeprom_write(pgm, p, m, page_size, addr, n_bytes);
+ else
+ return -2;
+}
+
+static int avrftdi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ if (strcmp(m->desc, "flash") == 0)
+ return avrftdi_flash_read(pgm, p, m, page_size, addr, n_bytes);
+ else if(strcmp(m->desc, "eeprom") == 0)
+ return avrftdi_eeprom_read(pgm, p, m, page_size, addr, n_bytes);
+ else
+ return -2;
+}
+
+static void
+avrftdi_setup(PROGRAMMER * pgm)
+{
+ avrftdi_t* pdata;
+
+ pgm->cookie = malloc(sizeof(avrftdi_t));
+ pdata = to_pdata(pgm);
+
+ pdata->ftdic = ftdi_new();
+ if(!pdata->ftdic)
+ {
+ log_err("Error allocating memory.\n");
+ exit(1);
+ }
+ E_VOID(ftdi_init(pdata->ftdic), pdata->ftdic);
+
+ pdata->pin_value = 0;
+ pdata->pin_direction = 0;
+ pdata->led_mask = 0;
+}
+
+static void
+avrftdi_teardown(PROGRAMMER * pgm)
+{
+ avrftdi_t* pdata = to_pdata(pgm);
+
+ if(pdata) {
+ ftdi_deinit(pdata->ftdic);
+ ftdi_free(pdata->ftdic);
+ free(pdata);
+ }
+}
+
+void avrftdi_initpgm(PROGRAMMER * pgm)
+{
+
+ strcpy(pgm->type, "avrftdi");
+
+ /*
+ * mandatory functions
+ */
+
+ pgm->initialize = avrftdi_initialize;
+ pgm->display = avrftdi_display;
+ pgm->enable = avrftdi_enable;
+ pgm->disable = avrftdi_disable;
+ pgm->powerup = avrftdi_powerup;
+ pgm->powerdown = avrftdi_powerdown;
+ pgm->program_enable = avrftdi_program_enable;
+ pgm->chip_erase = avrftdi_chip_erase;
+ pgm->cmd = avrftdi_cmd;
+ pgm->open = avrftdi_open;
+ pgm->close = avrftdi_close;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+
+ /*
+ * optional functions
+ */
+
+ pgm->paged_write = avrftdi_paged_write;
+ pgm->paged_load = avrftdi_paged_load;
+
+ pgm->setpin = set_pin;
+
+ pgm->setup = avrftdi_setup;
+ pgm->teardown = avrftdi_teardown;
+
+ pgm->rdy_led = set_led_rdy;
+ pgm->err_led = set_led_err;
+ pgm->pgm_led = set_led_pgm;
+ pgm->vfy_led = set_led_vfy;
+}
+
+#endif /* DO_NOT_BUILD_AVRFTDI */
+
+
+const char avrftdi_desc[] = "Interface to the MPSSE Engine of FTDI Chips using libftdi.";
+
diff --git a/xs/src/avrdude/avrftdi.h b/xs/src/avrdude/avrftdi.h
new file mode 100644
index 000000000..af3233528
--- /dev/null
+++ b/xs/src/avrdude/avrftdi.h
@@ -0,0 +1,40 @@
+/*
+ * avrftdi - extension for avrdude, Wolfgang Moser, Ville Voipio
+ * Copyright (C) 2011 Hannes Weisbach, Doug Springer
+ *
+ * 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 avrftdi_h
+#define avrftdi_h
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern const char avrftdi_desc[];
+void avrftdi_initpgm (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/xs/src/avrdude/avrftdi_private.h b/xs/src/avrdude/avrftdi_private.h
new file mode 100644
index 000000000..e89d250e7
--- /dev/null
+++ b/xs/src/avrdude/avrftdi_private.h
@@ -0,0 +1,86 @@
+#pragma once
+#include "ac_cfg.h"
+
+#include <stdint.h>
+
+#if defined(HAVE_LIBFTDI1) && defined(HAVE_LIBUSB_1_0)
+# if defined(HAVE_LIBUSB_1_0_LIBUSB_H)
+# include <libusb-1.0/libusb.h>
+# else
+# include <libusb.h>
+# endif
+# include <libftdi1/ftdi.h>
+# undef HAVE_LIBFTDI_TYPE_232H
+# define HAVE_LIBFTDI_TYPE_232H 1
+#elif defined(HAVE_LIBFTDI) && defined(HAVE_USB_H)
+/* ftdi.h includes usb.h */
+#include <ftdi.h>
+#else
+#warning No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.
+#define DO_NOT_BUILD_AVRFTDI
+#endif
+
+#ifndef DO_NOT_BUILD_AVRFTDI
+
+enum { ERR, WARN, INFO, DEBUG, TRACE };
+
+#define __log(lvl, fmt, ...) \
+ do { \
+ avrftdi_log(lvl, __func__, __LINE__, fmt, ##__VA_ARGS__); \
+ } while(0)
+
+
+#define log_err(fmt, ...) __log(ERR, fmt, ##__VA_ARGS__)
+#define log_warn(fmt, ...) __log(WARN, fmt, ##__VA_ARGS__)
+#define log_info(fmt, ...) __log(INFO, fmt, ##__VA_ARGS__)
+#define log_debug(fmt, ...) __log(DEBUG, fmt, ##__VA_ARGS__)
+#define log_trace(fmt, ...) __log(TRACE, fmt, ##__VA_ARGS__)
+
+#define E(x, ftdi) \
+ do { \
+ if ((x)) \
+ { \
+ avrdude_message(MSG_INFO, "%s:%d %s() %s: %s (%d)\n\t%s\n", \
+ __FILE__, __LINE__, __FUNCTION__, \
+ #x, strerror(errno), errno, ftdi_get_error_string(ftdi)); \
+ return -1; \
+ } \
+ } while(0)
+
+#define E_VOID(x, ftdi) \
+ do { \
+ if ((x)) \
+ { \
+ avrdude_message(MSG_INFO, "%s:%d %s() %s: %s (%d)\n\t%s\n", \
+ __FILE__, __LINE__, __FUNCTION__, \
+ #x, strerror(errno), errno, ftdi_get_error_string(ftdi)); \
+ } \
+ } while(0)
+
+
+#define to_pdata(pgm) \
+ ((avrftdi_t *)((pgm)->cookie))
+
+typedef struct avrftdi_s {
+ /* pointer to struct maintained by libftdi to identify the device */
+ struct ftdi_context* ftdic;
+ /* bitmask of values for pins. bit 0 represents pin 0 ([A|B]DBUS0) */
+ uint16_t pin_value;
+ /* bitmask of pin direction. a '1' make a pin an output.
+ * bit 0 corresponds to pin 0. */
+ uint16_t pin_direction;
+ /* don't know. not useful. someone put it in. */
+ uint16_t led_mask;
+ /* total number of pins supported by a programmer. varies with FTDI chips */
+ int pin_limit;
+ /* internal RX buffer of the device. needed for INOUT transfers */
+ int rx_buffer_size;
+ int tx_buffer_size;
+ /* use bitbanging instead of mpsse spi */
+ bool use_bitbanging;
+} avrftdi_t;
+
+void avrftdi_log(int level, const char * func, int line, const char * fmt, ...);
+
+#endif /* DO_NOT_BUILD_AVRFDTI */
+
diff --git a/xs/src/avrdude/avrftdi_tpi.c b/xs/src/avrdude/avrftdi_tpi.c
new file mode 100644
index 000000000..d82444e89
--- /dev/null
+++ b/xs/src/avrdude/avrftdi_tpi.c
@@ -0,0 +1,254 @@
+#include "ac_cfg.h"
+
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "usbasp.h"
+
+#include "avrftdi_tpi.h"
+#include "avrftdi_private.h"
+
+#ifndef DO_NOT_BUILD_AVRFTDI
+
+static void avrftdi_tpi_disable(PROGRAMMER *);
+static int avrftdi_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p);
+
+#ifdef notyet
+static void
+avrftdi_debug_frame(uint16_t frame)
+{
+ static char bit_name[] = "IDLES01234567PSS";
+ //static char bit_name[] = "SSP76543210SELDI";
+ char line0[34], line1[34], line2[34];
+ int bit, pos;
+
+ for(bit = 0; bit < 16; bit++)
+ {
+ pos = 16 - bit - 1;
+ if(frame & (1 << pos))
+ {
+ line0[2*pos] = '_';
+ line0[2*pos+1] = ' ';
+
+ line2[2*pos] = ' ';
+ line2[2*pos+1] = ' ';
+ }
+ else
+ {
+ line0[2*pos] = ' ';
+ line0[2*pos+1] = ' ';
+
+ line2[2*pos] = '-';
+ line2[2*pos+1] = ' ';
+ }
+
+ line1[2*pos] = bit_name[pos];
+ line1[2*pos+1] = ' ';
+
+ }
+
+ line0[32] = 0;
+ line1[32] = 0;
+ line2[32] = 0;
+
+ log_debug("%s\n", line0);
+ log_debug("%s\n", line1);
+ //log_debug("%s\n", line2);
+}
+#endif /* notyet */
+
+int
+avrftdi_tpi_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ int ret;
+
+ avrftdi_t* pdata = to_pdata(pgm);
+ unsigned char buf[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 0x01, 0x00, 0xff, 0xff };
+
+ log_info("Using TPI interface\n");
+
+ pgm->program_enable = avrftdi_tpi_program_enable;
+ pgm->cmd_tpi = avrftdi_cmd_tpi;
+ pgm->chip_erase = avr_tpi_chip_erase;
+ pgm->disable = avrftdi_tpi_disable;
+
+ pgm->paged_load = NULL;
+ pgm->paged_write = NULL;
+
+ log_info("Setting /Reset pin low\n");
+ pgm->setpin(pgm, PIN_AVR_RESET, OFF);
+ pgm->setpin(pgm, PIN_AVR_SCK, OFF);
+ pgm->setpin(pgm, PIN_AVR_MOSI, ON);
+ usleep(20 * 1000);
+
+ pgm->setpin(pgm, PIN_AVR_RESET, ON);
+ /* worst case 128ms */
+ usleep(2 * 128 * 1000);
+
+ /*setting rst back to 0 */
+ pgm->setpin(pgm, PIN_AVR_RESET, OFF);
+ /*wait at least 20ms bevor issuing spi commands to avr */
+ usleep(20 * 1000);
+
+ log_info("Sending 16 init clock cycles ...\n");
+ ret = ftdi_write_data(pdata->ftdic, buf, sizeof(buf));
+
+ return ret;
+}
+
+#define TPI_PARITY_MASK 0x2000
+
+static uint16_t
+tpi_byte2frame(uint8_t byte)
+{
+ uint16_t frame = 0xc00f;
+ int parity = __builtin_popcount(byte) & 1;
+
+ frame |= ((byte << 5) & 0x1fe0);
+
+ if(parity)
+ frame |= TPI_PARITY_MASK;
+
+ return frame;
+}
+
+static int
+tpi_frame2byte(uint16_t frame, uint8_t * byte)
+{
+ /* drop idle and start bit(s) */
+ *byte = (frame >> 5) & 0xff;
+
+ int parity = __builtin_popcount(*byte) & 1;
+ int parity_rcvd = (frame & TPI_PARITY_MASK) ? 1 : 0;
+
+ return parity != parity_rcvd;
+}
+
+#ifdef notyet
+static int
+avrftdi_tpi_break(PROGRAMMER * pgm)
+{
+ unsigned char buffer[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 1, 0, 0, 0 };
+ E(ftdi_write_data(to_pdata(pgm)->ftdic, buffer, sizeof(buffer)) != sizeof(buffer), to_pdata(pgm)->ftdic);
+
+ return 0;
+}
+#endif /* notyet */
+
+static int
+avrftdi_tpi_write_byte(PROGRAMMER * pgm, unsigned char byte)
+{
+ uint16_t frame;
+
+ struct ftdi_context* ftdic = to_pdata(pgm)->ftdic;
+
+ unsigned char buffer[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 1, 0, 0, 0 };
+
+ frame = tpi_byte2frame(byte);
+
+ buffer[3] = frame & 0xff;
+ buffer[4] = frame >> 8;
+
+ log_trace("Byte %02x, frame: %04x, MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ byte, frame, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]);
+
+ //avrftdi_debug_frame(frame);
+
+ E(ftdi_write_data(ftdic, buffer, sizeof(buffer)) != sizeof(buffer), ftdic);
+
+ return 0;
+}
+
+#define TPI_FRAME_SIZE 12
+#define TPI_IDLE_BITS 2
+
+static int
+avrftdi_tpi_read_byte(PROGRAMMER * pgm, unsigned char * byte)
+{
+ uint16_t frame;
+
+ /* use 2 guard bits, 2 default idle bits + 12 frame bits = 16 bits total */
+ const int bytes = 3;
+ int err, i = 0;
+
+ unsigned char buffer[4];
+
+ buffer[0] = MPSSE_DO_READ | MPSSE_LSB;
+ buffer[1] = (bytes-1) & 0xff;
+ buffer[2] = ((bytes-1) >> 8) & 0xff;
+ buffer[3] = SEND_IMMEDIATE;
+
+ log_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n",
+ buffer[0], buffer[1], buffer[2], buffer[3]);
+
+ ftdi_write_data(to_pdata(pgm)->ftdic, buffer, 4);
+
+ memset(buffer, 0, sizeof(buffer));
+
+ i = 0;
+ do {
+ int err = ftdi_read_data(to_pdata(pgm)->ftdic, &buffer[i], bytes - i);
+ E(err < 0, to_pdata(pgm)->ftdic);
+ i += err;
+ } while(i < bytes);
+
+
+ log_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n",
+ buffer[0], buffer[1], buffer[2], buffer[3]);
+
+
+ frame = buffer[0] | (buffer[1] << 8);
+
+ err = tpi_frame2byte(frame, byte);
+ log_trace("Frame: 0x%04x, byte: 0x%02x\n", frame, *byte);
+
+ //avrftdi_debug_frame(frame);
+
+ return err;
+}
+
+static int
+avrftdi_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ return avr_tpi_program_enable(pgm, p, TPIPCR_GT_2b);
+}
+
+int
+avrftdi_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd, int cmd_len,
+ unsigned char *res, int res_len)
+{
+ int i, err = 0;
+
+ for(i = 0; i < cmd_len; i++)
+ {
+ err = avrftdi_tpi_write_byte(pgm, cmd[i]);
+ if(err)
+ return err;
+ }
+
+ for(i = 0; i < res_len; i++)
+ {
+ err = avrftdi_tpi_read_byte(pgm, &res[i]);
+ if(err)
+ return err;
+ }
+
+ return 0;
+}
+
+static void
+avrftdi_tpi_disable(PROGRAMMER * pgm)
+{
+ unsigned char cmd[] = {TPI_OP_SSTCS(TPIPCR), 0};
+ pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
+
+ log_info("Leaving Programming mode.\n");
+}
+
+#endif /* DO_NOT_BUILD_AVRFTDI */
+
diff --git a/xs/src/avrdude/avrftdi_tpi.h b/xs/src/avrdude/avrftdi_tpi.h
new file mode 100644
index 000000000..6082a379d
--- /dev/null
+++ b/xs/src/avrdude/avrftdi_tpi.h
@@ -0,0 +1,9 @@
+#pragma once
+
+//int avrftdi_tpi_write_byte(PROGRAMMER * pgm, unsigned char byte);
+//int avrftdi_tpi_read_byte(PROGRAMMER * pgm, unsigned char * byte);
+int avrftdi_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd, int cmd_len,
+ unsigned char *res, int res_len);
+int avrftdi_tpi_initialize(PROGRAMMER * pgm, AVRPART * p);
+
+
diff --git a/xs/src/avrdude/avrpart.c b/xs/src/avrdude/avrpart.c
new file mode 100644
index 000000000..d0bb951ee
--- /dev/null
+++ b/xs/src/avrdude/avrpart.c
@@ -0,0 +1,686 @@
+
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+/***
+ *** Elementary functions dealing with OPCODE structures
+ ***/
+
+OPCODE * avr_new_opcode(void)
+{
+ OPCODE * m;
+
+ m = (OPCODE *)malloc(sizeof(*m));
+ if (m == NULL) {
+ // avrdude_message(MSG_INFO, "avr_new_opcode(): out of memory\n");
+ // exit(1);
+ avrdude_oom("avr_new_opcode(): out of memory\n");
+ }
+
+ memset(m, 0, sizeof(*m));
+
+ return m;
+}
+
+static OPCODE * avr_dup_opcode(OPCODE * op)
+{
+ OPCODE * m;
+
+ /* this makes life easier */
+ if (op == NULL) {
+ return NULL;
+ }
+
+ m = (OPCODE *)malloc(sizeof(*m));
+ if (m == NULL) {
+ // avrdude_message(MSG_INFO, "avr_dup_opcode(): out of memory\n");
+ // exit(1);
+ avrdude_oom("avr_dup_opcode(): out of memory\n");
+ }
+
+ memcpy(m, op, sizeof(*m));
+
+ return m;
+}
+
+void avr_free_opcode(OPCODE * op)
+{
+ free(op);
+}
+
+/*
+ * avr_set_bits()
+ *
+ * Set instruction bits in the specified command based on the opcode.
+ */
+int avr_set_bits(OPCODE * op, unsigned char * cmd)
+{
+ int i, j, bit;
+ unsigned char mask;
+
+ for (i=0; i<32; i++) {
+ if (op->bit[i].type == AVR_CMDBIT_VALUE) {
+ j = 3 - i / 8;
+ bit = i % 8;
+ mask = 1 << bit;
+ if (op->bit[i].value)
+ cmd[j] = cmd[j] | mask;
+ else
+ cmd[j] = cmd[j] & ~mask;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * avr_set_addr()
+ *
+ * Set address bits in the specified command based on the opcode, and
+ * the address.
+ */
+int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr)
+{
+ int i, j, bit;
+ unsigned long value;
+ unsigned char mask;
+
+ for (i=0; i<32; i++) {
+ if (op->bit[i].type == AVR_CMDBIT_ADDRESS) {
+ j = 3 - i / 8;
+ bit = i % 8;
+ mask = 1 << bit;
+ value = addr >> op->bit[i].bitno & 0x01;
+ if (value)
+ cmd[j] = cmd[j] | mask;
+ else
+ cmd[j] = cmd[j] & ~mask;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * avr_set_input()
+ *
+ * Set input data bits in the specified command based on the opcode,
+ * and the data byte.
+ */
+int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data)
+{
+ int i, j, bit;
+ unsigned char value;
+ unsigned char mask;
+
+ for (i=0; i<32; i++) {
+ if (op->bit[i].type == AVR_CMDBIT_INPUT) {
+ j = 3 - i / 8;
+ bit = i % 8;
+ mask = 1 << bit;
+ value = data >> op->bit[i].bitno & 0x01;
+ if (value)
+ cmd[j] = cmd[j] | mask;
+ else
+ cmd[j] = cmd[j] & ~mask;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * avr_get_output()
+ *
+ * Retreive output data bits from the command results based on the
+ * opcode data.
+ */
+int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data)
+{
+ int i, j, bit;
+ unsigned char value;
+ unsigned char mask;
+
+ for (i=0; i<32; i++) {
+ if (op->bit[i].type == AVR_CMDBIT_OUTPUT) {
+ j = 3 - i / 8;
+ bit = i % 8;
+ mask = 1 << bit;
+ value = ((res[j] & mask) >> bit) & 0x01;
+ value = value << op->bit[i].bitno;
+ if (value)
+ *data = *data | value;
+ else
+ *data = *data & ~value;
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * avr_get_output_index()
+ *
+ * Calculate the byte number of the output data based on the
+ * opcode data.
+ */
+int avr_get_output_index(OPCODE * op)
+{
+ int i, j;
+
+ for (i=0; i<32; i++) {
+ if (op->bit[i].type == AVR_CMDBIT_OUTPUT) {
+ j = 3 - i / 8;
+ return j;
+ }
+ }
+
+ return -1;
+}
+
+
+static char * avr_op_str(int op)
+{
+ switch (op) {
+ case AVR_OP_READ : return "READ"; break;
+ case AVR_OP_WRITE : return "WRITE"; break;
+ case AVR_OP_READ_LO : return "READ_LO"; break;
+ case AVR_OP_READ_HI : return "READ_HI"; break;
+ case AVR_OP_WRITE_LO : return "WRITE_LO"; break;
+ case AVR_OP_WRITE_HI : return "WRITE_HI"; break;
+ case AVR_OP_LOADPAGE_LO : return "LOADPAGE_LO"; break;
+ case AVR_OP_LOADPAGE_HI : return "LOADPAGE_HI"; break;
+ case AVR_OP_LOAD_EXT_ADDR : return "LOAD_EXT_ADDR"; break;
+ case AVR_OP_WRITEPAGE : return "WRITEPAGE"; break;
+ case AVR_OP_CHIP_ERASE : return "CHIP_ERASE"; break;
+ case AVR_OP_PGM_ENABLE : return "PGM_ENABLE"; break;
+ default : return "<unknown opcode>"; break;
+ }
+}
+
+
+static char * bittype(int type)
+{
+ switch (type) {
+ case AVR_CMDBIT_IGNORE : return "IGNORE"; break;
+ case AVR_CMDBIT_VALUE : return "VALUE"; break;
+ case AVR_CMDBIT_ADDRESS : return "ADDRESS"; break;
+ case AVR_CMDBIT_INPUT : return "INPUT"; break;
+ case AVR_CMDBIT_OUTPUT : return "OUTPUT"; break;
+ default : return "<unknown bit type>"; break;
+ }
+}
+
+
+
+/***
+ *** Elementary functions dealing with AVRMEM structures
+ ***/
+
+AVRMEM * avr_new_memtype(void)
+{
+ AVRMEM * m;
+
+ m = (AVRMEM *)malloc(sizeof(*m));
+ if (m == NULL) {
+ // avrdude_message(MSG_INFO, "avr_new_memtype(): out of memory\n");
+ // exit(1);
+ avrdude_oom("avr_new_memtype(): out of memory\n");
+ }
+
+ memset(m, 0, sizeof(*m));
+
+ return m;
+}
+
+
+/*
+ * Allocate and initialize memory buffers for each of the device's
+ * defined memory regions.
+ */
+int avr_initmem(AVRPART * p)
+{
+ LNODEID ln;
+ AVRMEM * m;
+
+ for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
+ m = ldata(ln);
+ m->buf = (unsigned char *) malloc(m->size);
+ if (m->buf == NULL) {
+ avrdude_message(MSG_INFO, "%s: can't alloc buffer for %s size of %d bytes\n",
+ progname, m->desc, m->size);
+ return -1;
+ }
+ m->tags = (unsigned char *) malloc(m->size);
+ if (m->tags == NULL) {
+ avrdude_message(MSG_INFO, "%s: can't alloc buffer for %s size of %d bytes\n",
+ progname, m->desc, m->size);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+AVRMEM * avr_dup_mem(AVRMEM * m)
+{
+ AVRMEM * n;
+ int i;
+
+ n = avr_new_memtype();
+
+ *n = *m;
+
+ if (m->buf != NULL) {
+ n->buf = (unsigned char *)malloc(n->size);
+ if (n->buf == NULL) {
+ // avrdude_message(MSG_INFO, "avr_dup_mem(): out of memory (memsize=%d)\n",
+ // n->size);
+ // exit(1);
+ avrdude_oom("avr_dup_mem(): out of memory");
+ }
+ memcpy(n->buf, m->buf, n->size);
+ }
+
+ if (m->tags != NULL) {
+ n->tags = (unsigned char *)malloc(n->size);
+ if (n->tags == NULL) {
+ // avrdude_message(MSG_INFO, "avr_dup_mem(): out of memory (memsize=%d)\n",
+ // n->size);
+ // exit(1);
+ avrdude_oom("avr_dup_mem(): out of memory");
+ }
+ memcpy(n->tags, m->tags, n->size);
+ }
+
+ for (i = 0; i < AVR_OP_MAX; i++) {
+ n->op[i] = avr_dup_opcode(n->op[i]);
+ }
+
+ return n;
+}
+
+void avr_free_mem(AVRMEM * m)
+{
+ int i;
+ if (m->buf != NULL) {
+ free(m->buf);
+ m->buf = NULL;
+ }
+ if (m->tags != NULL) {
+ free(m->tags);
+ m->tags = NULL;
+ }
+ for(i=0;i<sizeof(m->op)/sizeof(m->op[0]);i++)
+ {
+ if (m->op[i] != NULL)
+ {
+ avr_free_opcode(m->op[i]);
+ m->op[i] = NULL;
+ }
+ }
+ free(m);
+}
+
+AVRMEM * avr_locate_mem(AVRPART * p, char * desc)
+{
+ AVRMEM * m, * match;
+ LNODEID ln;
+ int matches;
+ int l;
+
+ l = strlen(desc);
+ matches = 0;
+ match = NULL;
+ for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
+ m = ldata(ln);
+ if (strncmp(desc, m->desc, l) == 0) {
+ match = m;
+ matches++;
+ }
+ }
+
+ if (matches == 1)
+ return match;
+
+ return NULL;
+}
+
+
+void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, int type,
+ int verbose)
+{
+ int i, j;
+ char * optr;
+
+ if (m == NULL) {
+ avrdude_message(MSG_INFO,
+ "%s Block Poll Page Polled\n"
+ "%sMemory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack\n"
+ "%s----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------\n",
+ prefix, prefix, prefix);
+ }
+ else {
+ if (verbose > 2) {
+ avrdude_message(MSG_INFO,
+ "%s Block Poll Page Polled\n"
+ "%sMemory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack\n"
+ "%s----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------\n",
+ prefix, prefix, prefix);
+ }
+ avrdude_message(MSG_INFO,
+ "%s%-11s %4d %5d %5d %4d %-6s %6d %4d %6d %5d %5d 0x%02x 0x%02x\n",
+ prefix, m->desc, m->mode, m->delay, m->blocksize, m->pollindex,
+ m->paged ? "yes" : "no",
+ m->size,
+ m->page_size,
+ m->num_pages,
+ m->min_write_delay,
+ m->max_write_delay,
+ m->readback[0],
+ m->readback[1]);
+ if (verbose > 4) {
+ avrdude_message(MSG_TRACE2, "%s Memory Ops:\n"
+ "%s Oeration Inst Bit Bit Type Bitno Value\n"
+ "%s ----------- -------- -------- ----- -----\n",
+ prefix, prefix, prefix);
+ for (i=0; i<AVR_OP_MAX; i++) {
+ if (m->op[i]) {
+ for (j=31; j>=0; j--) {
+ if (j==31)
+ optr = avr_op_str(i);
+ else
+ optr = " ";
+ avrdude_message(MSG_INFO,
+ "%s %-11s %8d %8s %5d %5d\n",
+ prefix, optr, j,
+ bittype(m->op[i]->bit[j].type),
+ m->op[i]->bit[j].bitno,
+ m->op[i]->bit[j].value);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+/*
+ * Elementary functions dealing with AVRPART structures
+ */
+
+
+AVRPART * avr_new_part(void)
+{
+ AVRPART * p;
+
+ p = (AVRPART *)malloc(sizeof(AVRPART));
+ if (p == NULL) {
+ // avrdude_message(MSG_INFO, "new_part(): out of memory\n");
+ // exit(1);
+ avrdude_oom("new_part(): out of memory\n");
+ }
+
+ memset(p, 0, sizeof(*p));
+
+ p->id[0] = 0;
+ p->desc[0] = 0;
+ p->reset_disposition = RESET_DEDICATED;
+ p->retry_pulse = PIN_AVR_SCK;
+ p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK | AVRPART_ENABLEPAGEPROGRAMMING;
+ p->config_file[0] = 0;
+ p->lineno = 0;
+ memset(p->signature, 0xFF, 3);
+ p->ctl_stack_type = CTL_STACK_NONE;
+ p->ocdrev = -1;
+
+ p->mem = lcreat(NULL, 0);
+
+ return p;
+}
+
+
+AVRPART * avr_dup_part(AVRPART * d)
+{
+ AVRPART * p;
+ LISTID save;
+ LNODEID ln;
+ int i;
+
+ p = avr_new_part();
+ save = p->mem;
+
+ *p = *d;
+
+ p->mem = save;
+
+ for (ln=lfirst(d->mem); ln; ln=lnext(ln)) {
+ ladd(p->mem, avr_dup_mem(ldata(ln)));
+ }
+
+ for (i = 0; i < AVR_OP_MAX; i++) {
+ p->op[i] = avr_dup_opcode(p->op[i]);
+ }
+
+ return p;
+}
+
+void avr_free_part(AVRPART * d)
+{
+int i;
+ ldestroy_cb(d->mem, (void(*)(void *))avr_free_mem);
+ d->mem = NULL;
+ for(i=0;i<sizeof(d->op)/sizeof(d->op[0]);i++)
+ {
+ if (d->op[i] != NULL)
+ {
+ avr_free_opcode(d->op[i]);
+ d->op[i] = NULL;
+ }
+ }
+ free(d);
+}
+
+AVRPART * locate_part(LISTID parts, char * partdesc)
+{
+ LNODEID ln1;
+ AVRPART * p = NULL;
+ int found;
+
+ found = 0;
+
+ for (ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) {
+ p = ldata(ln1);
+ if ((strcasecmp(partdesc, p->id) == 0) ||
+ (strcasecmp(partdesc, p->desc) == 0))
+ found = 1;
+ }
+
+ if (found)
+ return p;
+
+ return NULL;
+}
+
+AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode)
+{
+ LNODEID ln1;
+ AVRPART * p = NULL;
+
+ for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
+ p = ldata(ln1);
+ if (p->avr910_devcode == devcode)
+ return p;
+ }
+
+ return NULL;
+}
+
+AVRPART * locate_part_by_signature(LISTID parts, unsigned char * sig,
+ int sigsize)
+{
+ LNODEID ln1;
+ AVRPART * p = NULL;
+ int i;
+
+ if (sigsize == 3) {
+ for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) {
+ p = ldata(ln1);
+ for (i=0; i<3; i++)
+ if (p->signature[i] != sig[i])
+ break;
+ if (i == 3)
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * Iterate over the list of avrparts given as "avrparts", and
+ * call the callback function cb for each entry found. cb is being
+ * passed the following arguments:
+ * . the name of the avrpart (for -p)
+ * . the descriptive text given in the config file
+ * . the name of the config file this avrpart has been defined in
+ * . the line number of the config file this avrpart has been defined at
+ * . the "cookie" passed into walk_avrparts() (opaque client data)
+ */
+void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie)
+{
+ LNODEID ln1;
+ AVRPART * p;
+
+ for (ln1 = lfirst(avrparts); ln1; ln1 = lnext(ln1)) {
+ p = ldata(ln1);
+ cb(p->id, p->desc, p->config_file, p->lineno, cookie);
+ }
+}
+
+/*
+ * Compare function to sort the list of programmers
+ */
+static int sort_avrparts_compare(AVRPART * p1,AVRPART * p2)
+{
+ if(p1 == NULL || p2 == NULL) {
+ return 0;
+ }
+ return strncasecmp(p1->desc,p2->desc,AVR_DESCLEN);
+}
+
+/*
+ * Sort the list of programmers given as "programmers"
+ */
+void sort_avrparts(LISTID avrparts)
+{
+ lsort(avrparts,(int (*)(void*, void*)) sort_avrparts_compare);
+}
+
+
+static char * reset_disp_str(int r)
+{
+ switch (r) {
+ case RESET_DEDICATED : return "dedicated";
+ case RESET_IO : return "possible i/o";
+ default : return "<invalid>";
+ }
+}
+
+
+void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose)
+{
+ int i;
+ char * buf;
+ const char * px;
+ LNODEID ln;
+ AVRMEM * m;
+
+ avrdude_message(MSG_INFO,
+ "%sAVR Part : %s\n"
+ "%sChip Erase delay : %d us\n"
+ "%sPAGEL : P%02X\n"
+ "%sBS2 : P%02X\n"
+ "%sRESET disposition : %s\n"
+ "%sRETRY pulse : %s\n"
+ "%sserial program mode : %s\n"
+ "%sparallel program mode : %s\n"
+ "%sTimeout : %d\n"
+ "%sStabDelay : %d\n"
+ "%sCmdexeDelay : %d\n"
+ "%sSyncLoops : %d\n"
+ "%sByteDelay : %d\n"
+ "%sPollIndex : %d\n"
+ "%sPollValue : 0x%02x\n"
+ "%sMemory Detail :\n\n",
+ prefix, p->desc,
+ prefix, p->chip_erase_delay,
+ prefix, p->pagel,
+ prefix, p->bs2,
+ prefix, reset_disp_str(p->reset_disposition),
+ prefix, avr_pin_name(p->retry_pulse),
+ prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no",
+ prefix, (p->flags & AVRPART_PARALLELOK) ?
+ ((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no",
+ prefix, p->timeout,
+ prefix, p->stabdelay,
+ prefix, p->cmdexedelay,
+ prefix, p->synchloops,
+ prefix, p->bytedelay,
+ prefix, p->pollindex,
+ prefix, p->pollvalue,
+ prefix);
+
+ px = prefix;
+ i = strlen(prefix) + 5;
+ buf = (char *)malloc(i);
+ if (buf == NULL) {
+ /* ugh, this is not important enough to bail, just ignore it */
+ }
+ else {
+ strcpy(buf, prefix);
+ strcat(buf, " ");
+ px = buf;
+ }
+
+ if (verbose <= 2) {
+ avr_mem_display(px, f, NULL, 0, verbose);
+ }
+ for (ln=lfirst(p->mem); ln; ln=lnext(ln)) {
+ m = ldata(ln);
+ avr_mem_display(px, f, m, i, verbose);
+ }
+
+ if (buf)
+ free(buf);
+}
diff --git a/xs/src/avrdude/bitbang.c b/xs/src/avrdude/bitbang.c
new file mode 100644
index 000000000..b943c3cea
--- /dev/null
+++ b/xs/src/avrdude/bitbang.c
@@ -0,0 +1,655 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
+ * Copyright (C) 2011 Darell Tan <darell.tan@gmail.com>
+ *
+ * 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$ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#if !defined(WIN32NATIVE)
+# include <signal.h>
+# include <sys/time.h>
+#endif
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "par.h"
+#include "serbb.h"
+#include "tpi.h"
+#include "bitbang.h"
+
+static int delay_decrement;
+
+#if defined(WIN32NATIVE)
+static int has_perfcount;
+static LARGE_INTEGER freq;
+#else
+static volatile int done;
+
+typedef void (*mysighandler_t)(int);
+static mysighandler_t saved_alarmhandler;
+
+static void alarmhandler(int signo)
+{
+ done = 1;
+ signal(SIGALRM, saved_alarmhandler);
+}
+#endif /* WIN32NATIVE */
+
+/*
+ * Calibrate the microsecond delay loop below.
+ */
+static void bitbang_calibrate_delay(void)
+{
+#if defined(WIN32NATIVE)
+ /*
+ * If the hardware supports a high-resolution performance counter,
+ * we ultimately prefer that one, as it gives quite accurate delays
+ * on modern high-speed CPUs.
+ */
+ if (QueryPerformanceFrequency(&freq))
+ {
+ has_perfcount = 1;
+ avrdude_message(MSG_NOTICE2, "%s: Using performance counter for bitbang delays\n",
+ progname);
+ }
+ else
+ {
+ /*
+ * If a high-resolution performance counter is not available, we
+ * don't have any Win32 implementation for setting up the
+ * per-microsecond delay count, so we can only run on a
+ * preconfigured delay stepping there. The figure below should at
+ * least be correct within an order of magnitude, judging from the
+ * auto-calibration figures seen on various Unix systems on
+ * comparable hardware.
+ */
+ avrdude_message(MSG_NOTICE2, "%s: Using guessed per-microsecond delay count for bitbang delays\n",
+ progname);
+ delay_decrement = 100;
+ }
+#else /* !WIN32NATIVE */
+ struct itimerval itv;
+ volatile int i;
+
+ avrdude_message(MSG_NOTICE2, "%s: Calibrating delay loop...",
+ progname);
+ i = 0;
+ done = 0;
+ saved_alarmhandler = signal(SIGALRM, alarmhandler);
+ /*
+ * Set ITIMER_REAL to 100 ms. All known systems have a timer
+ * granularity of 10 ms or better, so counting the delay cycles
+ * accumulating over 100 ms should give us a rather realistic
+ * picture, without annoying the user by a lengthy startup time (as
+ * an alarm(1) would do). Of course, if heavy system activity
+ * happens just during calibration but stops before the remaining
+ * part of AVRDUDE runs, this will yield wrong values. There's not
+ * much we can do about this.
+ */
+ itv.it_value.tv_sec = 0;
+ itv.it_value.tv_usec = 100000;
+ itv.it_interval.tv_sec = itv.it_interval.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, 0);
+ while (!done)
+ i--;
+ itv.it_value.tv_sec = itv.it_value.tv_usec = 0;
+ setitimer(ITIMER_REAL, &itv, 0);
+ /*
+ * Calculate back from 100 ms to 1 us.
+ */
+ delay_decrement = -i / 100000;
+ avrdude_message(MSG_NOTICE2, " calibrated to %d cycles per us\n",
+ delay_decrement);
+#endif /* WIN32NATIVE */
+}
+
+/*
+ * Delay for approximately the number of microseconds specified.
+ * usleep()'s granularity is usually like 1 ms or 10 ms, so it's not
+ * really suitable for short delays in bit-bang algorithms.
+ */
+void bitbang_delay(unsigned int us)
+{
+#if defined(WIN32NATIVE)
+ LARGE_INTEGER countNow, countEnd;
+
+ if (has_perfcount)
+ {
+ QueryPerformanceCounter(&countNow);
+ countEnd.QuadPart = countNow.QuadPart + freq.QuadPart * us / 1000000ll;
+
+ while (countNow.QuadPart < countEnd.QuadPart)
+ QueryPerformanceCounter(&countNow);
+ }
+ else /* no performance counters -- run normal uncalibrated delay */
+ {
+#endif /* WIN32NATIVE */
+ volatile unsigned int del = us * delay_decrement;
+
+ while (del > 0)
+ del--;
+#if defined(WIN32NATIVE)
+ }
+#endif /* WIN32NATIVE */
+}
+
+/*
+ * transmit and receive a byte of data to/from the AVR device
+ */
+static unsigned char bitbang_txrx(PROGRAMMER * pgm, unsigned char byte)
+{
+ int i;
+ unsigned char r, b, rbyte;
+
+ rbyte = 0;
+ for (i=7; i>=0; i--) {
+ /*
+ * Write and read one bit on SPI.
+ * Some notes on timing: Let T be the time it takes to do
+ * one pgm->setpin()-call resp. par clrpin()-call, then
+ * - SCK is high for 2T
+ * - SCK is low for 2T
+ * - MOSI setuptime is 1T
+ * - MOSI holdtime is 3T
+ * - SCK low to MISO read is 2T to 3T
+ * So we are within programming specs (expect for AT90S1200),
+ * if and only if T>t_CLCL (t_CLCL=clock period of target system).
+ *
+ * Due to the delay introduced by "IN" and "OUT"-commands,
+ * T is greater than 1us (more like 2us) on x86-architectures.
+ * So programming works safely down to 1MHz target clock.
+ */
+
+ b = (byte >> i) & 0x01;
+
+ /* set the data input line as desired */
+ pgm->setpin(pgm, PIN_AVR_MOSI, b);
+
+ pgm->setpin(pgm, PIN_AVR_SCK, 1);
+
+ /*
+ * read the result bit (it is either valid from a previous falling
+ * edge or it is ignored in the current context)
+ */
+ r = pgm->getpin(pgm, PIN_AVR_MISO);
+
+ pgm->setpin(pgm, PIN_AVR_SCK, 0);
+
+ rbyte |= r << i;
+ }
+
+ return rbyte;
+}
+
+static int bitbang_tpi_clk(PROGRAMMER * pgm)
+{
+ unsigned char r = 0;
+ pgm->setpin(pgm, PIN_AVR_SCK, 1);
+
+ r = pgm->getpin(pgm, PIN_AVR_MISO);
+
+ pgm->setpin(pgm, PIN_AVR_SCK, 0);
+
+ return r;
+}
+
+void bitbang_tpi_tx(PROGRAMMER * pgm, unsigned char byte)
+{
+ int i;
+ unsigned char b, parity;
+
+ /* start bit */
+ pgm->setpin(pgm, PIN_AVR_MOSI, 0);
+ bitbang_tpi_clk(pgm);
+
+ parity = 0;
+ for (i = 0; i <= 7; i++) {
+ b = (byte >> i) & 0x01;
+ parity ^= b;
+
+ /* set the data input line as desired */
+ pgm->setpin(pgm, PIN_AVR_MOSI, b);
+ bitbang_tpi_clk(pgm);
+ }
+
+ /* parity bit */
+ pgm->setpin(pgm, PIN_AVR_MOSI, parity);
+ bitbang_tpi_clk(pgm);
+
+ /* 2 stop bits */
+ pgm->setpin(pgm, PIN_AVR_MOSI, 1);
+ bitbang_tpi_clk(pgm);
+ bitbang_tpi_clk(pgm);
+}
+
+int bitbang_tpi_rx(PROGRAMMER * pgm)
+{
+ int i;
+ unsigned char b, rbyte, parity;
+
+ /* make sure pin is on for "pullup" */
+ pgm->setpin(pgm, PIN_AVR_MOSI, 1);
+
+ /* wait for start bit (up to 10 bits) */
+ b = 1;
+ for (i = 0; i < 10; i++) {
+ b = bitbang_tpi_clk(pgm);
+ if (b == 0)
+ break;
+ }
+ if (b != 0) {
+ avrdude_message(MSG_INFO, "bitbang_tpi_rx: start bit not received correctly\n");
+ return -1;
+ }
+
+ rbyte = 0;
+ parity = 0;
+ for (i=0; i<=7; i++) {
+ b = bitbang_tpi_clk(pgm);
+ parity ^= b;
+
+ rbyte |= b << i;
+ }
+
+ /* parity bit */
+ if (bitbang_tpi_clk(pgm) != parity) {
+ avrdude_message(MSG_INFO, "bitbang_tpi_rx: parity bit is wrong\n");
+ return -1;
+ }
+
+ /* 2 stop bits */
+ b = 1;
+ b &= bitbang_tpi_clk(pgm);
+ b &= bitbang_tpi_clk(pgm);
+ if (b != 1) {
+ avrdude_message(MSG_INFO, "bitbang_tpi_rx: stop bits not received correctly\n");
+ return -1;
+ }
+
+ return rbyte;
+}
+
+int bitbang_rdy_led(PROGRAMMER * pgm, int value)
+{
+ pgm->setpin(pgm, PIN_LED_RDY, !value);
+ return 0;
+}
+
+int bitbang_err_led(PROGRAMMER * pgm, int value)
+{
+ pgm->setpin(pgm, PIN_LED_ERR, !value);
+ return 0;
+}
+
+int bitbang_pgm_led(PROGRAMMER * pgm, int value)
+{
+ pgm->setpin(pgm, PIN_LED_PGM, !value);
+ return 0;
+}
+
+int bitbang_vfy_led(PROGRAMMER * pgm, int value)
+{
+ pgm->setpin(pgm, PIN_LED_VFY, !value);
+ return 0;
+}
+
+
+/*
+ * transmit an AVR device command and return the results; 'cmd' and
+ * 'res' must point to at least a 4 byte data buffer
+ */
+int bitbang_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+ unsigned char *res)
+{
+ int i;
+
+ for (i=0; i<4; i++) {
+ res[i] = bitbang_txrx(pgm, cmd[i]);
+ }
+
+ if(verbose >= 2)
+ {
+ avrdude_message(MSG_NOTICE2, "bitbang_cmd(): [ ");
+ for(i = 0; i < 4; i++)
+ avrdude_message(MSG_NOTICE2, "%02X ", cmd[i]);
+ avrdude_message(MSG_NOTICE2, "] [ ");
+ for(i = 0; i < 4; i++)
+ {
+ avrdude_message(MSG_NOTICE2, "%02X ", res[i]);
+ }
+ avrdude_message(MSG_NOTICE2, "]\n");
+ }
+
+ return 0;
+}
+
+int bitbang_cmd_tpi(PROGRAMMER * pgm, const unsigned char *cmd,
+ int cmd_len, unsigned char *res, int res_len)
+{
+ int i, r;
+
+ pgm->pgm_led(pgm, ON);
+
+ for (i=0; i<cmd_len; i++) {
+ bitbang_tpi_tx(pgm, cmd[i]);
+ }
+
+ r = 0;
+ for (i=0; i<res_len; i++) {
+ r = bitbang_tpi_rx(pgm);
+ if (r == -1)
+ break;
+ res[i] = r;
+ }
+
+ if(verbose >= 2)
+ {
+ avrdude_message(MSG_NOTICE2, "bitbang_cmd_tpi(): [ ");
+ for(i = 0; i < cmd_len; i++)
+ avrdude_message(MSG_NOTICE2, "%02X ", cmd[i]);
+ avrdude_message(MSG_NOTICE2, "] [ ");
+ for(i = 0; i < res_len; i++)
+ {
+ avrdude_message(MSG_NOTICE2, "%02X ", res[i]);
+ }
+ avrdude_message(MSG_NOTICE2, "]\n");
+ }
+
+ pgm->pgm_led(pgm, OFF);
+ if (r == -1)
+ return -1;
+ return 0;
+}
+
+/*
+ * transmit bytes via SPI and return the results; 'cmd' and
+ * 'res' must point to data buffers
+ */
+int bitbang_spi(PROGRAMMER * pgm, const unsigned char *cmd,
+ unsigned char *res, int count)
+{
+ int i;
+
+ pgm->setpin(pgm, PIN_LED_PGM, 0);
+
+ for (i=0; i<count; i++) {
+ res[i] = bitbang_txrx(pgm, cmd[i]);
+ }
+
+ pgm->setpin(pgm, PIN_LED_PGM, 1);
+
+ if(verbose >= 2)
+ {
+ avrdude_message(MSG_NOTICE2, "bitbang_cmd(): [ ");
+ for(i = 0; i < count; i++)
+ avrdude_message(MSG_NOTICE2, "%02X ", cmd[i]);
+ avrdude_message(MSG_NOTICE2, "] [ ");
+ for(i = 0; i < count; i++)
+ {
+ avrdude_message(MSG_NOTICE2, "%02X ", res[i]);
+ }
+ avrdude_message(MSG_NOTICE2, "]\n");
+ }
+
+ return 0;
+}
+
+
+/*
+ * issue the 'chip erase' command to the AVR device
+ */
+int bitbang_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+ AVRMEM *mem;
+
+ if (p->flags & AVRPART_HAS_TPI) {
+ pgm->pgm_led(pgm, ON);
+
+ while (avr_tpi_poll_nvmbsy(pgm));
+
+ /* NVMCMD <- CHIP_ERASE */
+ bitbang_tpi_tx(pgm, TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD));
+ bitbang_tpi_tx(pgm, TPI_NVMCMD_CHIP_ERASE); /* CHIP_ERASE */
+
+ /* Set Pointer Register */
+ mem = avr_locate_mem(p, "flash");
+ if (mem == NULL) {
+ avrdude_message(MSG_INFO, "No flash memory to erase for part %s\n",
+ p->desc);
+ return -1;
+ }
+ bitbang_tpi_tx(pgm, TPI_CMD_SSTPR | 0);
+ bitbang_tpi_tx(pgm, (mem->offset & 0xFF) | 1); /* high byte */
+ bitbang_tpi_tx(pgm, TPI_CMD_SSTPR | 1);
+ bitbang_tpi_tx(pgm, (mem->offset >> 8) & 0xFF);
+
+ /* write dummy value to start erase */
+ bitbang_tpi_tx(pgm, TPI_CMD_SST);
+ bitbang_tpi_tx(pgm, 0xFF);
+
+ while (avr_tpi_poll_nvmbsy(pgm));
+
+ pgm->pgm_led(pgm, OFF);
+
+ return 0;
+ }
+
+ if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
+ avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
+ p->desc);
+ return -1;
+ }
+
+ pgm->pgm_led(pgm, ON);
+
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
+ pgm->cmd(pgm, cmd, res);
+ usleep(p->chip_erase_delay);
+ pgm->initialize(pgm, p);
+
+ pgm->pgm_led(pgm, OFF);
+
+ return 0;
+}
+
+/*
+ * issue the 'program enable' command to the AVR device
+ */
+int bitbang_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+ int i;
+
+ if (p->flags & AVRPART_HAS_TPI) {
+ /* enable NVM programming */
+ bitbang_tpi_tx(pgm, TPI_CMD_SKEY);
+ for (i = sizeof(tpi_skey) - 1; i >= 0; i--)
+ bitbang_tpi_tx(pgm, tpi_skey[i]);
+
+ /* check NVMEN bit */
+ bitbang_tpi_tx(pgm, TPI_CMD_SLDCS | TPI_REG_TPISR);
+ i = bitbang_tpi_rx(pgm);
+ return (i != -1 && (i & TPI_REG_TPISR_NVMEN)) ? 0 : -2;
+ }
+
+ if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
+ avrdude_message(MSG_INFO, "program enable instruction not defined for part \"%s\"\n",
+ p->desc);
+ return -1;
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+ avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd);
+ pgm->cmd(pgm, cmd, res);
+
+ if (res[2] != cmd[1])
+ return -2;
+
+ return 0;
+}
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+int bitbang_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ int rc;
+ int tries;
+ int i;
+
+ bitbang_calibrate_delay();
+
+ pgm->powerup(pgm);
+ usleep(20000);
+
+ /* TPIDATA is a single line, so MISO & MOSI should be connected */
+ if (p->flags & AVRPART_HAS_TPI) {
+ /* make sure cmd_tpi() is defined */
+ if (pgm->cmd_tpi == NULL) {
+ avrdude_message(MSG_INFO, "%s: Error: %s programmer does not support TPI\n",
+ progname, pgm->type);
+ return -1;
+ }
+
+ /* bring RESET high first */
+ pgm->setpin(pgm, PIN_AVR_RESET, 1);
+ usleep(1000);
+
+ avrdude_message(MSG_NOTICE2, "doing MOSI-MISO link check\n");
+
+ pgm->setpin(pgm, PIN_AVR_MOSI, 0);
+ if (pgm->getpin(pgm, PIN_AVR_MISO) != 0) {
+ avrdude_message(MSG_INFO, "MOSI->MISO 0 failed\n");
+ return -1;
+ }
+ pgm->setpin(pgm, PIN_AVR_MOSI, 1);
+ if (pgm->getpin(pgm, PIN_AVR_MISO) != 1) {
+ avrdude_message(MSG_INFO, "MOSI->MISO 1 failed\n");
+ return -1;
+ }
+
+ avrdude_message(MSG_NOTICE2, "MOSI-MISO link present\n");
+ }
+
+ pgm->setpin(pgm, PIN_AVR_SCK, 0);
+ pgm->setpin(pgm, PIN_AVR_RESET, 0);
+ usleep(20000);
+
+ if (p->flags & AVRPART_HAS_TPI) {
+ /* keep TPIDATA high for 16 clock cycles */
+ pgm->setpin(pgm, PIN_AVR_MOSI, 1);
+ for (i = 0; i < 16; i++)
+ pgm->highpulsepin(pgm, PIN_AVR_SCK);
+
+ /* remove extra guard timing bits */
+ bitbang_tpi_tx(pgm, TPI_CMD_SSTCS | TPI_REG_TPIPCR);
+ bitbang_tpi_tx(pgm, 0x7);
+
+ /* read TPI ident reg */
+ bitbang_tpi_tx(pgm, TPI_CMD_SLDCS | TPI_REG_TPIIR);
+ rc = bitbang_tpi_rx(pgm);
+ if (rc != 0x80) {
+ avrdude_message(MSG_INFO, "TPIIR not correct\n");
+ return -1;
+ }
+ } else {
+ pgm->highpulsepin(pgm, PIN_AVR_RESET);
+ }
+
+ usleep(20000); /* 20 ms XXX should be a per-chip parameter */
+
+ /*
+ * Enable programming mode. If we are programming an AT90S1200, we
+ * can only issue the command and hope it worked. If we are using
+ * one of the other chips, the chip will echo 0x53 when issuing the
+ * third byte of the command. In this case, try up to 32 times in
+ * order to possibly get back into sync with the chip if we are out
+ * of sync.
+ */
+ if (p->flags & AVRPART_IS_AT90S1200) {
+ pgm->program_enable(pgm, p);
+ }
+ else {
+ tries = 0;
+ do {
+ rc = pgm->program_enable(pgm, p);
+ if ((rc == 0)||(rc == -1))
+ break;
+ pgm->highpulsepin(pgm, p->retry_pulse/*PIN_AVR_SCK*/);
+ tries++;
+ } while (tries < 65);
+
+ /*
+ * can't sync with the device, maybe it's not attached?
+ */
+ if (rc) {
+ avrdude_message(MSG_INFO, "%s: AVR device not responding\n", progname);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int verify_pin_assigned(PROGRAMMER * pgm, int pin, char * desc)
+{
+ if (pgm->pinno[pin] == 0) {
+ avrdude_message(MSG_INFO, "%s: error: no pin has been assigned for %s\n",
+ progname, desc);
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ * Verify all prerequisites for a bit-bang programmer are present.
+ */
+int bitbang_check_prerequisites(PROGRAMMER *pgm)
+{
+
+ if (verify_pin_assigned(pgm, PIN_AVR_RESET, "AVR RESET") < 0)
+ return -1;
+ if (verify_pin_assigned(pgm, PIN_AVR_SCK, "AVR SCK") < 0)
+ return -1;
+ if (verify_pin_assigned(pgm, PIN_AVR_MISO, "AVR MISO") < 0)
+ return -1;
+ if (verify_pin_assigned(pgm, PIN_AVR_MOSI, "AVR MOSI") < 0)
+ return -1;
+
+ if (pgm->cmd == NULL) {
+ avrdude_message(MSG_INFO, "%s: error: no cmd() method defined for bitbang programmer\n",
+ progname);
+ return -1;
+ }
+ return 0;
+}
diff --git a/xs/src/avrdude/bitbang.h b/xs/src/avrdude/bitbang.h
new file mode 100644
index 000000000..300f52fd5
--- /dev/null
+++ b/xs/src/avrdude/bitbang.h
@@ -0,0 +1,58 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
+ * Copyright (C) 2011 Darell Tan <darell.tan@gmail.com>
+ *
+ * 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 bitbang_h
+#define bitbang_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int bitbang_setpin(int fd, int pin, int value);
+int bitbang_getpin(int fd, int pin);
+int bitbang_highpulsepin(int fd, int pin);
+void bitbang_delay(unsigned int us);
+
+int bitbang_check_prerequisites(PROGRAMMER *pgm);
+
+int bitbang_rdy_led (PROGRAMMER * pgm, int value);
+int bitbang_err_led (PROGRAMMER * pgm, int value);
+int bitbang_pgm_led (PROGRAMMER * pgm, int value);
+int bitbang_vfy_led (PROGRAMMER * pgm, int value);
+int bitbang_cmd (PROGRAMMER * pgm, const unsigned char *cmd,
+ unsigned char *res);
+int bitbang_cmd_tpi (PROGRAMMER * pgm, const unsigned char *cmd,
+ int cmd_len, unsigned char *res, int res_len);
+int bitbang_spi (PROGRAMMER * pgm, const unsigned char *cmd,
+ unsigned char *res, int count);
+int bitbang_chip_erase (PROGRAMMER * pgm, AVRPART * p);
+int bitbang_program_enable (PROGRAMMER * pgm, AVRPART * p);
+void bitbang_powerup (PROGRAMMER * pgm);
+void bitbang_powerdown (PROGRAMMER * pgm);
+int bitbang_initialize (PROGRAMMER * pgm, AVRPART * p);
+void bitbang_disable (PROGRAMMER * pgm);
+void bitbang_enable (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/xs/src/avrdude/bootstrap b/xs/src/avrdude/bootstrap
new file mode 100755
index 000000000..0c1f84cc7
--- /dev/null
+++ b/xs/src/avrdude/bootstrap
@@ -0,0 +1,21 @@
+#! /bin/sh
+
+: ${AUTOHEADER="autoheader${AC_VER}"}
+: ${AUTOCONF="autoconf${AC_VER}"}
+: ${ACLOCAL="aclocal${AM_VER}"}
+: ${AUTOMAKE="automake${AM_VER}"}
+
+export ACLOCAL AUTOHEADER AUTOCONF AUTOMAKE
+
+# Bootstrap the build system.
+
+set -x
+
+rm -rf autom4te.cache
+
+libtoolize
+
+${ACLOCAL}
+${AUTOHEADER}
+${AUTOCONF}
+${AUTOMAKE} -a -c
diff --git a/xs/src/avrdude/buspirate.c b/xs/src/avrdude/buspirate.c
new file mode 100644
index 000000000..5875d4283
--- /dev/null
+++ b/xs/src/avrdude/buspirate.c
@@ -0,0 +1,1372 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ *
+ * avrdude support for The Bus Pirate - universal serial interface
+ *
+ * Copyright (C) 2009 Michal Ludvig <mludvig@logix.net.nz>
+ *
+ * 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/>.
+ */
+
+/*
+ * BusPirate AVR Chip
+ * --------- --------
+ * GND <-> GND
+ * +5V <-> Vcc
+ * CS <-> RESET
+ * MOSI <-> MOSI
+ * MISO <-> MISO
+ * SCL/CLK <-> SCK
+ * ( AUX <-> XTAL1 )
+ *
+ * Tested with BusPirate PTH, firmware version 2.1 programming ATmega328P
+ */
+
+/* $Id$ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "bitbang.h"
+#include "buspirate.h"
+
+/* ====== Private data structure ====== */
+/* CS and AUX pin bitmasks in
+ * 0100wxyz - Configure peripherals command */
+#define BP_RESET_CS 0x01
+#define BP_RESET_AUX 0x02
+#define BP_RESET_AUX2 0x04
+
+#define BP_FLAG_IN_BINMODE (1<<0)
+#define BP_FLAG_XPARM_FORCE_ASCII (1<<1)
+#define BP_FLAG_XPARM_RESET (1<<2)
+#define BP_FLAG_XPARM_SPIFREQ (1<<3)
+#define BP_FLAG_NOPAGEDWRITE (1<<4)
+#define BP_FLAG_XPARM_CPUFREQ (1<<5)
+#define BP_FLAG_XPARM_RAWFREQ (1<<6)
+#define BP_FLAG_NOPAGEDREAD (1<<7)
+
+struct pdata
+{
+ int binmode_version;
+ int submode_version;
+ int current_peripherals_config;
+ int spifreq; /* For "set speed" commands */
+ int cpufreq; /* (125)..4000 kHz - see buspirate manual */
+ int serial_recv_timeout; /* timeout in ms, default 100 */
+ int reset; /* See BP_RESET_* above */
+ unsigned char pin_dir; /* Last written pin direction for bitbang mode */
+ unsigned char pin_val; /* Last written pin values for bitbang mode */
+ int unread_bytes; /* How many bytes we expected, but ignored */
+};
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
+/* ====== Feature checks ====== */
+static inline int
+buspirate_uses_ascii(struct programmer_t *pgm)
+{
+ return (pgm->flag & BP_FLAG_XPARM_FORCE_ASCII);
+}
+
+/* ====== Serial talker functions - binmode ====== */
+
+static void dump_mem(const int msglvl, const unsigned char *buf, size_t len)
+{
+ size_t i;
+
+ for (i = 0; i<len; i++) {
+ if (i % 8 == 0)
+ avrdude_message(msglvl, "\t");
+ avrdude_message(msglvl, "0x%02x ", buf[i]);
+ if (i % 8 == 3)
+ avrdude_message(msglvl, " ");
+ else if (i % 8 == 7)
+ avrdude_message(msglvl, "\n");
+ }
+ if (i % 8 != 7)
+ avrdude_message(msglvl, "\n");
+}
+
+static int buspirate_send_bin(struct programmer_t *pgm, const unsigned char *data, size_t len)
+{
+ int rc;
+
+ avrdude_message(MSG_DEBUG, "%s: buspirate_send_bin():\n", progname);
+ dump_mem(MSG_DEBUG, data, len);
+
+ rc = serial_send(&pgm->fd, data, len);
+
+ return rc;
+}
+
+static int buspirate_recv_bin(struct programmer_t *pgm, unsigned char *buf, size_t len)
+{
+ int rc;
+
+ rc = serial_recv(&pgm->fd, buf, len);
+ if (rc < 0)
+ return EOF;
+
+ avrdude_message(MSG_DEBUG, "%s: buspirate_recv_bin():\n", progname);
+ dump_mem(MSG_DEBUG, buf, len);
+
+ return len;
+}
+
+static int buspirate_expect_bin(struct programmer_t *pgm,
+ unsigned char *send_data, size_t send_len,
+ unsigned char *expect_data, size_t expect_len)
+{
+ unsigned char *recv_buf = alloca(expect_len);
+ if ((pgm->flag & BP_FLAG_IN_BINMODE) == 0) {
+ avrdude_message(MSG_INFO, "BusPirate: Internal error: buspirate_send_bin() called from ascii mode\n");
+ return -1;
+ }
+
+ buspirate_send_bin(pgm, send_data, send_len);
+ buspirate_recv_bin(pgm, recv_buf, expect_len);
+ if (memcmp(expect_data, recv_buf, expect_len) != 0)
+ return 0;
+ return 1;
+}
+
+static int buspirate_expect_bin_byte(struct programmer_t *pgm,
+ unsigned char send_byte, unsigned char expect_byte)
+{
+ return buspirate_expect_bin(pgm, &send_byte, 1, &expect_byte, 1);
+}
+
+/* ====== Serial talker functions - ascii mode ====== */
+
+static int buspirate_getc(struct programmer_t *pgm)
+{
+ int rc;
+ unsigned char ch = 0;
+
+ if (pgm->flag & BP_FLAG_IN_BINMODE) {
+ avrdude_message(MSG_INFO, "BusPirate: Internal error: buspirate_getc() called from binmode\n");
+ return EOF;
+ }
+
+ rc = serial_recv(&pgm->fd, &ch, 1);
+ if (rc < 0)
+ return EOF;
+ return ch;
+}
+
+static char *buspirate_readline_noexit(struct programmer_t *pgm, char *buf, size_t len)
+{
+ char *buf_p;
+ long orig_serial_recv_timeout = serial_recv_timeout;
+
+ /* Static local buffer - this may come handy at times */
+ static char buf_local[100];
+
+ if (buf == NULL) {
+ buf = buf_local;
+ len = sizeof(buf_local);
+ }
+ buf_p = buf;
+ memset(buf, 0, len);
+ while (buf_p < (buf + len - 1)) { /* keep the very last byte == 0 */
+ *buf_p = buspirate_getc(pgm);
+ if (*buf_p == '\r')
+ continue;
+ if (*buf_p == '\n')
+ break;
+ if (*buf_p == EOF) {
+ *buf_p = '\0';
+ break;
+ }
+ buf_p++;
+ serial_recv_timeout = PDATA(pgm)->serial_recv_timeout;
+ }
+ serial_recv_timeout = orig_serial_recv_timeout;
+ avrdude_message(MSG_DEBUG, "%s: buspirate_readline(): %s%s",
+ progname, buf,
+ buf[strlen(buf) - 1] == '\n' ? "" : "\n");
+ if (! buf[0])
+ return NULL;
+
+ return buf;
+}
+
+static char *buspirate_readline(struct programmer_t *pgm, char *buf, size_t len)
+{
+ char *ret;
+
+ ret = buspirate_readline_noexit(pgm, buf, len);
+ if (! ret) {
+ avrdude_message(MSG_INFO, "%s: buspirate_readline(): programmer is not responding\n",
+ progname);
+ return NULL;
+ }
+ return ret;
+}
+static int buspirate_send(struct programmer_t *pgm, const char *str)
+{
+ int rc;
+ const char * readline;
+
+ avrdude_message(MSG_DEBUG, "%s: buspirate_send(): %s", progname, str);
+
+ if (pgm->flag & BP_FLAG_IN_BINMODE) {
+ avrdude_message(MSG_INFO, "BusPirate: Internal error: buspirate_send() called from binmode\n");
+ return -1;
+ }
+
+ rc = serial_send(&pgm->fd, (const unsigned char*)str, strlen(str));
+ if (rc)
+ return rc;
+ do {
+ readline = buspirate_readline(pgm, NULL, 0);
+ if (readline == NULL)
+ return -1;
+ /* keep reading until we get what we sent there */
+ } while (strcmp(readline, str) != 0);
+
+ /* by now we should be in sync */
+ return 0;
+}
+
+static int buspirate_is_prompt(const char *str)
+{
+ int strlen_str = strlen(str);
+ /* Prompt ends with '>' or '> '
+ * all other input probably ends with '\n' */
+ return (str[strlen_str - 1] == '>' || str[strlen_str - 2] == '>');
+}
+
+static int buspirate_expect(struct programmer_t *pgm, char *send,
+ char *expect, int wait_for_prompt)
+{
+ int got_it = 0;
+ size_t expect_len = strlen(expect);
+ char *rcvd;
+
+ buspirate_send(pgm, send);
+ while (1) {
+ rcvd = buspirate_readline(pgm, NULL, 0);
+ if (rcvd == NULL) {
+ return -1;
+ }
+ if (strncmp(rcvd, expect, expect_len) == 0) {
+ if (! wait_for_prompt) {
+ serial_drain(&pgm->fd, 0);
+ return 1;
+ } else {
+ got_it = 1;
+ }
+ }
+
+ if (buspirate_is_prompt(rcvd))
+ break;
+ }
+ return got_it;
+}
+
+/* ====== Do-nothing functions ====== */
+static void buspirate_dummy_6(struct programmer_t *pgm, const char *p)
+{
+}
+
+/* ====== Config / parameters handling functions ====== */
+static int
+buspirate_parseextparms(struct programmer_t *pgm, LISTID extparms)
+{
+ LNODEID ln;
+ const char *extended_param;
+ char reset[10];
+ char *preset = reset; /* for strtok() */
+ unsigned int spifreq;
+ unsigned int rawfreq;
+ unsigned int cpufreq;
+ int serial_recv_timeout;
+
+ for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
+ extended_param = ldata(ln);
+ if (strcmp(extended_param, "ascii") == 0) {
+ pgm->flag |= BP_FLAG_XPARM_FORCE_ASCII;
+ continue;
+ }
+
+ if (sscanf(extended_param, "spifreq=%u", &spifreq) == 1) {
+ if (spifreq & (~0x07)) {
+ avrdude_message(MSG_INFO, "BusPirate: spifreq must be between 0 and 7.\n");
+ avrdude_message(MSG_INFO, "BusPirate: see BusPirate manual for details.\n");
+ return -1;
+ }
+ if (pgm->flag & BP_FLAG_XPARM_RAWFREQ) {
+ avrdude_message(MSG_INFO, "BusPirate: set either spifreq or rawfreq\n");
+ return -1;
+ }
+ pgm->flag |= BP_FLAG_XPARM_SPIFREQ;
+ PDATA(pgm)->spifreq = spifreq;
+ continue;
+ }
+
+ if (sscanf(extended_param, "rawfreq=%u", &rawfreq) == 1) {
+ if (rawfreq >= 4) {
+ avrdude_message(MSG_INFO, "BusPirate: rawfreq must be "
+ "between 0 and 3.\n");
+ return -1;
+ }
+ if (pgm->flag & BP_FLAG_XPARM_SPIFREQ) {
+ avrdude_message(MSG_INFO, "BusPirate: set either spifreq or rawfreq\n");
+ return -1;
+ }
+ pgm->flag |= BP_FLAG_XPARM_RAWFREQ;
+ PDATA(pgm)->spifreq = rawfreq;
+ continue;
+ }
+
+ if (sscanf(extended_param, "cpufreq=%u", &cpufreq) == 1) {
+ /* lower limit comes from 'cpufreq > 4 * spifreq', spifreq in ascii mode is 30kHz. */
+ if (cpufreq < 125 || cpufreq > 4000) {
+ avrdude_message(MSG_INFO, "BusPirate: cpufreq must be between 125 and 4000 kHz.\n");
+ avrdude_message(MSG_INFO, "BusPirate: see BusPirate manual for details.\n");
+ return -1;
+ }
+ PDATA(pgm)->cpufreq = cpufreq;
+ pgm->flag |= BP_FLAG_XPARM_CPUFREQ;
+ continue;
+ }
+
+ if (sscanf(extended_param, "reset=%9s", reset) == 1) {
+ char *resetpin;
+ while ((resetpin = strtok(preset, ","))) {
+ preset = NULL; /* for subsequent strtok() calls */
+ if (strcasecmp(resetpin, "cs") == 0)
+ PDATA(pgm)->reset |= BP_RESET_CS;
+ else if (strcasecmp(resetpin, "aux") == 0 || strcasecmp(reset, "aux1") == 0)
+ PDATA(pgm)->reset |= BP_RESET_AUX;
+ else if (strcasecmp(resetpin, "aux2") == 0)
+ PDATA(pgm)->reset |= BP_RESET_AUX2;
+ else {
+ avrdude_message(MSG_INFO, "BusPirate: reset must be either CS or AUX.\n");
+ return -1;
+ }
+ }
+ pgm->flag |= BP_FLAG_XPARM_RESET;
+ continue;
+ }
+
+ if (strcmp(extended_param, "nopagedwrite") == 0) {
+ pgm->flag |= BP_FLAG_NOPAGEDWRITE;
+ continue;
+ }
+
+ if (strcmp(extended_param, "nopagedread") == 0) {
+ pgm->flag |= BP_FLAG_NOPAGEDREAD;
+ continue;
+ }
+
+ if (sscanf(extended_param, "serial_recv_timeout=%d", &serial_recv_timeout) == 1) {
+ if (serial_recv_timeout < 1) {
+ avrdude_message(MSG_INFO, "BusPirate: serial_recv_timeout must be greater 0.\n");
+ return -1;
+ }
+ PDATA(pgm)->serial_recv_timeout = serial_recv_timeout;
+ continue;
+ }
+
+ avrdude_message(MSG_INFO, "BusPirate: do not understand extended param '%s'.\n", extended_param);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+buspirate_verifyconfig(struct programmer_t *pgm)
+{
+ /* Default reset pin is CS */
+ if (PDATA(pgm)->reset == 0x00)
+ PDATA(pgm)->reset |= BP_RESET_CS;
+
+ if ((PDATA(pgm)->reset != BP_RESET_CS) && buspirate_uses_ascii(pgm)) {
+ avrdude_message(MSG_INFO, "BusPirate: RESET pin other than CS is not supported in ASCII mode\n");
+ return -1;
+ }
+
+ if ( ((pgm->flag & BP_FLAG_XPARM_SPIFREQ) || (pgm->flag & BP_FLAG_XPARM_RAWFREQ))
+ && buspirate_uses_ascii(pgm)) {
+ avrdude_message(MSG_INFO, "BusPirate: SPI speed selection is not supported in ASCII mode\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/* ====== Programmer methods ======= */
+static int buspirate_open(struct programmer_t *pgm, char * port)
+{
+ union pinfo pinfo;
+ /* BusPirate runs at 115200 by default */
+ if(pgm->baudrate == 0)
+ pgm->baudrate = 115200;
+
+ pinfo.baud = pgm->baudrate;
+ strcpy(pgm->port, port);
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /* drain any extraneous input */
+ serial_drain(&pgm->fd, 0);
+
+ return 0;
+}
+
+static void buspirate_close(struct programmer_t *pgm)
+{
+ serial_close(&pgm->fd);
+ pgm->fd.ifd = -1;
+}
+
+static void buspirate_reset_from_binmode(struct programmer_t *pgm)
+{
+ unsigned char buf[10];
+
+ buf[0] = 0x00; /* BinMode: revert to raw bitbang mode */
+ buspirate_send_bin(pgm, buf, 1);
+ buspirate_recv_bin(pgm, buf, 5);
+
+ if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
+ /* disable pwm */
+ if (buspirate_expect_bin_byte(pgm, 0x13, 0x01) != 1) {
+ avrdude_message(MSG_INFO, "%s: warning: did not get a response to stop PWM command.\n", progname);
+ }
+ }
+ /* 0b0100wxyz - Configure peripherals w=power, x=pull-ups, y=AUX, z=CS
+ * we want everything off -- 0b01000000 = 0x40 */
+ if (buspirate_expect_bin_byte(pgm, 0x40, 0x00) == 1) {
+ avrdude_message(MSG_INFO, "%s: warning: did not get a response to power off command.\n", progname);
+ }
+
+ buf[0] = 0x0F; /* BinMode: reset */
+ buspirate_send_bin(pgm, buf, 1);
+
+ /* read back all output */
+ memset(buf, '\0', sizeof(buf));
+ for (;;) {
+ int rc;
+ rc = buspirate_recv_bin(pgm, buf, sizeof(buf) - 1);
+
+ if (buspirate_is_prompt((const char*)buf)) {
+ pgm->flag &= ~BP_FLAG_IN_BINMODE;
+ break;
+ }
+ if (rc == EOF)
+ break;
+ memset(buf, '\0', sizeof(buf));
+ }
+
+ if (pgm->flag & BP_FLAG_IN_BINMODE) {
+ avrdude_message(MSG_INFO, "BusPirate reset failed. You may need to powercycle it.\n");
+ return;
+ }
+
+ avrdude_message(MSG_NOTICE, "BusPirate is back in the text mode\n");
+}
+
+static int buspirate_start_mode_bin(struct programmer_t *pgm)
+{
+ const struct submode {
+ const char *name; /* Name of mode for user messages */
+ char enter; /* Command to enter from base binary mode */
+ const char *entered_format; /* Response, for "scanf" */
+ char config; /* Command to setup submode parameters */
+ } *submode;
+
+ if (pgm->flag & BP_FLAG_XPARM_RAWFREQ) {
+ submode = &(const struct submode){
+ .name = "Raw-wire",
+ .enter = 0x05,
+ .entered_format = "RAW%1d",
+ .config = 0x8C,
+ };
+ pgm->flag |= BP_FLAG_NOPAGEDWRITE;
+ pgm->flag |= BP_FLAG_NOPAGEDREAD;
+ } else {
+ submode = &(const struct submode){
+ .name = "SPI",
+ .enter = 0x01,
+ .entered_format = "SPI%1d",
+
+ /* 1000wxyz - SPI config, w=HiZ(0)/3.3v(1), x=CLK idle, y=CLK edge, z=SMP sample
+ * we want: 3.3V(1), idle low(0), data change on
+ * trailing edge (1), sample in the middle
+ * of the pulse (0)
+ * => 0b10001010 = 0x8a */
+ .config = 0x8A,
+ };
+ }
+
+ unsigned char buf[20] = { '\0' };
+
+ /* == Switch to binmode - send 20x '\0' == */
+ buspirate_send_bin(pgm, buf, sizeof(buf));
+
+ /* Expecting 'BBIOx' reply */
+ memset(buf, 0, sizeof(buf));
+ buspirate_recv_bin(pgm, buf, 5);
+ if (sscanf((const char*)buf, "BBIO%1d", &PDATA(pgm)->binmode_version) != 1) {
+ avrdude_message(MSG_INFO, "Binary mode not confirmed: '%s'\n", buf);
+ buspirate_reset_from_binmode(pgm);
+ return -1;
+ }
+ avrdude_message(MSG_NOTICE, "BusPirate binmode version: %d\n",
+ PDATA(pgm)->binmode_version);
+
+ pgm->flag |= BP_FLAG_IN_BINMODE;
+
+ if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
+ unsigned short pwm_duty;
+ unsigned short pwm_period;
+
+ pwm_period = 16000/(PDATA(pgm)->cpufreq) - 1; // oscillator runs at 32MHz, we don't use a prescaler
+ pwm_duty = pwm_period/2; // 50% duty cycle
+
+ avrdude_message(MSG_NOTICE, "Setting up PWM for cpufreq\n");
+ avrdude_message(MSG_DEBUG, "PWM settings: Prescaler=1, Duty Cycle=%hd, Period=%hd\n", pwm_duty, pwm_period);
+
+ buf[0] = 0x12; // pwm setup
+ buf[1] = 0; // prescaler 1
+ buf[2] = (char) ((pwm_duty >> 8) & 0xff); // duty cycle register, high byte
+ buf[3] = (char) pwm_duty & 0xff; // duty cycle register, low byte
+ buf[4] = (char) ((pwm_period >> 8) & 0xff); // period register, high byte
+ buf[5] = (char) pwm_period & 0xff; // period register, low byte
+ buspirate_send_bin(pgm, buf, 6);
+
+ buspirate_recv_bin(pgm, buf, 1);
+ if (buf[0] != 0x01)
+ avrdude_message(MSG_INFO, "cpufreq (PWM) setup failed\n");
+ }
+
+ /* == Set protocol sub-mode of binary mode == */
+ buf[0] = submode->enter;
+ buspirate_send_bin(pgm, buf, 1);
+ memset(buf, 0, sizeof(buf));
+ buspirate_recv_bin(pgm, buf, 4);
+ if (sscanf((const char*)buf, submode->entered_format, &PDATA(pgm)->submode_version) != 1) {
+ avrdude_message(MSG_INFO, "%s mode not confirmed: '%s'\n",
+ submode->name, buf);
+ buspirate_reset_from_binmode(pgm);
+ return -1;
+ }
+ avrdude_message(MSG_NOTICE, "BusPirate %s version: %d\n",
+ submode->name, PDATA(pgm)->submode_version);
+
+ if (pgm->flag & BP_FLAG_NOPAGEDWRITE) {
+ avrdude_message(MSG_NOTICE, "%s: Paged flash write disabled.\n", progname);
+ pgm->paged_write = NULL;
+ } else {
+ /* Check for write-then-read without !CS/CS and disable paged_write if absent: */
+ static const unsigned char buf2[] = {5,0,0,0,0};
+ buspirate_send_bin(pgm, buf2, sizeof(buf2));
+ buspirate_recv_bin(pgm, buf, 1);
+ if (buf[0] != 0x01) {
+
+ /* Disable paged write: */
+ pgm->flag |= BP_FLAG_NOPAGEDWRITE;
+ pgm->paged_write = NULL;
+
+ /* Return to SPI mode (0x00s have landed us back in binary bitbang mode): */
+ buf[0] = 0x1;
+ buspirate_send_bin(pgm, buf, 1);
+
+ avrdude_message(MSG_NOTICE, "%s: Disabling paged flash write. (Need BusPirate firmware >=v5.10.)\n", progname);
+
+ /* Flush serial buffer: */
+ serial_drain(&pgm->fd, 0);
+ } else {
+ avrdude_message(MSG_INFO, "%s: Paged flash write enabled.\n", progname);
+ }
+ }
+
+ /* 0b0100wxyz - Configure peripherals w=power, x=pull-ups/aux2, y=AUX, z=CS
+ * we want power (0x48) and all reset pins high. */
+ PDATA(pgm)->current_peripherals_config = 0x48 | PDATA(pgm)->reset;
+ if (buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01) < 0)
+ return -1;
+ usleep(50000); // sleep for 50ms after power up
+
+ /* 01100xxx - Set speed */
+ if (buspirate_expect_bin_byte(pgm, 0x60 | PDATA(pgm)->spifreq, 0x01) < 0)
+ return -1;
+
+ /* Submode config */
+ if (buspirate_expect_bin_byte(pgm, submode->config, 0x01) < 0)
+ return -1;
+
+ /* AVR Extended Commands - test for existence */
+ if (pgm->flag & BP_FLAG_NOPAGEDREAD) {
+ avrdude_message(MSG_NOTICE, "%s: Paged flash read disabled.\n", progname);
+ pgm->paged_load = NULL;
+ } else {
+ int rv = buspirate_expect_bin_byte(pgm, 0x06, 0x01);
+ if (rv < 0)
+ return -1;
+ if (rv) {
+ unsigned int ver = 0;
+ static const unsigned char buf2[] = {1};
+ buspirate_send_bin(pgm, buf2, sizeof(buf2));
+ buspirate_recv_bin(pgm, buf, 3);
+ ver = buf[1] << 8 | buf[2];
+ avrdude_message(MSG_NOTICE, "AVR Extended Commands version %d\n", ver);
+ } else {
+ avrdude_message(MSG_NOTICE, "AVR Extended Commands not found.\n");
+ pgm->flag |= BP_FLAG_NOPAGEDREAD;
+ pgm->paged_load = NULL;
+ }
+ }
+
+ return 0;
+}
+
+static int buspirate_start_spi_mode_ascii(struct programmer_t *pgm)
+{
+ int spi_cmd = -1;
+ int cmd;
+ char *rcvd;
+ char buf[5];
+ char mode[11];
+
+ buspirate_send(pgm, "m\n");
+ while(1) {
+ rcvd = buspirate_readline(pgm, NULL, 0);
+ if (rcvd == NULL) {
+ return -1;
+ }
+ if (spi_cmd == -1 && sscanf(rcvd, "%2d. %10s", &cmd, mode)) {
+ if (strcmp(mode, "SPI") == 0)
+ spi_cmd = cmd;
+ }
+ if (buspirate_is_prompt(rcvd))
+ break;
+ }
+ if (spi_cmd == -1) {
+ avrdude_message(MSG_INFO, "%s: SPI mode number not found. Does your BusPirate support SPI?\n",
+ progname);
+ avrdude_message(MSG_INFO, "%s: Try powercycling your BusPirate and try again.\n",
+ progname);
+ return -1;
+ }
+ snprintf(buf, sizeof(buf), "%d\n", spi_cmd);
+ buspirate_send(pgm, buf);
+ buf[0] = '\0';
+ while (1) {
+ rcvd = buspirate_readline(pgm, NULL, 0);
+ if (rcvd == NULL) {
+ return -1;
+ }
+ if (strstr(rcvd, "Normal (H=3.3V, L=GND)")) {
+ /* BP firmware 2.1 defaults to Open-drain output.
+ * That doesn't work on my board, even with pull-up
+ * resistors. Select 3.3V output mode instead. */
+ sscanf(rcvd, " %2d.", &cmd);
+ snprintf(buf, sizeof(buf), "%d\n", cmd);
+ }
+ if (buspirate_is_prompt(rcvd)) {
+ if (strncmp(rcvd, "SPI>", 4) == 0) {
+ avrdude_message(MSG_INFO, "BusPirate is now configured for SPI\n");
+ break;
+ }
+ /* Not yet 'SPI>' prompt */
+ if (buf[0]) {
+ buspirate_send(pgm, buf);
+ buf[0] = '\0';
+ } else
+ buspirate_send(pgm, "\n");
+ }
+ }
+ return 0;
+}
+
+static void buspirate_enable(struct programmer_t *pgm)
+{
+ static const char *reset_str = "#\n";
+ static const char *accept_str = "y\n";
+ char *rcvd;
+ int rc, print_banner = 0;
+
+ /* Ensure configuration is self-consistant: */
+ if (buspirate_verifyconfig(pgm)<0)
+ return; /* XXX should handle error */
+
+ /* Attempt to start binary SPI mode unless explicitly told otherwise: */
+ if (!buspirate_uses_ascii(pgm)) {
+ avrdude_message(MSG_INFO, "Attempting to initiate BusPirate binary mode...\n");
+
+ /* Send two CRs to ensure we're not in a sub-menu of the UI if we're in ASCII mode: */
+ buspirate_send_bin(pgm, (const unsigned char*)"\n\n", 2);
+
+ /* Clear input buffer: */
+ serial_drain(&pgm->fd, 0);
+
+ /* Attempt to enter binary mode: */
+ if (buspirate_start_mode_bin(pgm) >= 0)
+ return;
+ else
+ avrdude_message(MSG_INFO, "%s: Failed to start binary mode, falling back to ASCII...\n", progname);
+ }
+
+ avrdude_message(MSG_INFO, "Attempting to initiate BusPirate ASCII mode...\n");
+
+ /* Call buspirate_send_bin() instead of buspirate_send()
+ * because we don't know if BP is in text or bin mode */
+ rc = buspirate_send_bin(pgm, (const unsigned char*)reset_str, strlen(reset_str));
+ if (rc) {
+ avrdude_message(MSG_INFO, "BusPirate is not responding. Serial port error: %d\n", rc);
+ return;
+ }
+
+ while(1) {
+ rcvd = buspirate_readline_noexit(pgm, NULL, 0);
+ if (! rcvd) {
+ avrdude_message(MSG_INFO, "%s: Fatal: Programmer is not responding.\n", progname);
+ return;
+ }
+ if (strncmp(rcvd, "Are you sure?", 13) == 0) {
+ buspirate_send_bin(pgm, (const unsigned char*)accept_str, strlen(accept_str));
+ }
+ if (strncmp(rcvd, "RESET", 5) == 0) {
+ print_banner = 1;
+ continue;
+ }
+ if (buspirate_is_prompt(rcvd)) {
+ avrdude_message(MSG_DEBUG, "**\n");
+ break;
+ }
+ if (print_banner)
+ avrdude_message(MSG_DEBUG, "** %s", rcvd);
+ }
+
+ if (!(pgm->flag & BP_FLAG_IN_BINMODE)) {
+ avrdude_message(MSG_INFO, "BusPirate: using ASCII mode\n");
+ if (buspirate_start_spi_mode_ascii(pgm) < 0) {
+ avrdude_message(MSG_INFO, "%s: Failed to start ascii SPI mode\n", progname);
+ return;
+ }
+ }
+}
+
+static void buspirate_disable(struct programmer_t *pgm)
+{
+ if (pgm->flag & BP_FLAG_IN_BINMODE) {
+ serial_recv_timeout = 100;
+ buspirate_reset_from_binmode(pgm);
+ } else {
+ buspirate_expect(pgm, "#\n", "RESET", 1);
+ }
+}
+
+static int buspirate_initialize(struct programmer_t *pgm, AVRPART * p)
+{
+ pgm->powerup(pgm);
+
+ return pgm->program_enable(pgm, p);
+}
+
+static void buspirate_powerup(struct programmer_t *pgm)
+{
+ if (pgm->flag & BP_FLAG_IN_BINMODE) {
+ /* Powerup in BinMode is handled in binary mode init */
+ return;
+ } else {
+ if (buspirate_expect(pgm, "W\n", "POWER SUPPLIES ON", 1)) {
+ if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
+ char buf[25];
+ int ok = 0;
+ snprintf(buf, sizeof(buf), "%d\n", PDATA(pgm)->cpufreq);
+ if (buspirate_expect(pgm, "g\n", "Frequency in KHz", 1)) {
+ if (buspirate_expect(pgm, buf, "Duty cycle in %", 1)) {
+ if (buspirate_expect(pgm, "50\n", "PWM active", 1)) {
+ ok = 1;
+ }
+ }
+ }
+ if(!ok) {
+ avrdude_message(MSG_INFO, "%s: warning: did not get a response to start PWM command.\n", progname);
+ }
+ }
+ return;
+ }
+ }
+
+ avrdude_message(MSG_INFO, "%s: warning: did not get a response to PowerUp command.\n", progname);
+ avrdude_message(MSG_INFO, "%s: warning: Trying to continue anyway...\n", progname);
+}
+
+static void buspirate_powerdown(struct programmer_t *pgm)
+{
+ if (pgm->flag & BP_FLAG_IN_BINMODE) {
+ /* Powerdown in BinMode is handled in binary mode init */
+ return;
+ } else {
+ if (pgm->flag & BP_FLAG_XPARM_CPUFREQ) {
+ if (!buspirate_expect(pgm, "g\n", "PWM disabled", 1)) {
+ avrdude_message(MSG_INFO, "%s: warning: did not get a response to stop PWM command.\n", progname);
+ }
+ }
+ if (buspirate_expect(pgm, "w\n", "POWER SUPPLIES OFF", 1))
+ return;
+ }
+
+ avrdude_message(MSG_INFO, "%s: warning: did not get a response to PowerDown command.\n", progname);
+}
+
+static int buspirate_cmd_bin(struct programmer_t *pgm,
+ const unsigned char *cmd,
+ unsigned char *res)
+{
+ /* 0001xxxx - Bulk transfer, send/read 1-16 bytes (0=1byte!)
+ * we are sending 4 bytes -> 0x13 */
+ int rv = buspirate_expect_bin_byte(pgm, 0x13, 0x01);
+ if (rv < 0)
+ return -1;
+ if (rv == 0)
+ return -1;
+
+ buspirate_send_bin(pgm, cmd, 4);
+ buspirate_recv_bin(pgm, res, 4);
+
+ return 0;
+}
+
+static int buspirate_cmd_ascii(struct programmer_t *pgm,
+ const unsigned char *cmd,
+ unsigned char *res)
+{
+ char buf[25];
+ char *rcvd;
+ int spi_write, spi_read, i = 0;
+
+ snprintf(buf, sizeof(buf), "0x%02x 0x%02x 0x%02x 0x%02x\n",
+ cmd[0], cmd[1], cmd[2], cmd[3]);
+ buspirate_send(pgm, buf);
+ while (i < 4) {
+ rcvd = buspirate_readline(pgm, NULL, 0);
+ if (rcvd == NULL) {
+ return -1;
+ }
+ /* WRITE: 0xAC READ: 0x04 */
+ if (sscanf(rcvd, "WRITE: 0x%2x READ: 0x%2x", &spi_write, &spi_read) == 2) {
+ res[i++] = spi_read;
+ }
+ if (buspirate_is_prompt(rcvd))
+ break;
+ }
+
+ if (i != 4) {
+ avrdude_message(MSG_INFO, "%s: error: SPI has not read 4 bytes back\n", progname);
+ return -1;
+ }
+
+ /* wait for prompt */
+ while (buspirate_getc(pgm) != '>')
+ /* do nothing */;
+
+ return 0;
+}
+
+static int buspirate_cmd(struct programmer_t *pgm,
+ const unsigned char *cmd,
+ unsigned char *res)
+{
+ if (pgm->flag & BP_FLAG_IN_BINMODE)
+ return buspirate_cmd_bin(pgm, cmd, res);
+ else
+ return buspirate_cmd_ascii(pgm, cmd, res);
+}
+
+/* Paged load function which utilizes the AVR Extended Commands set */
+static int buspirate_paged_load(
+ PROGRAMMER *pgm,
+ AVRPART *p,
+ AVRMEM *m,
+ unsigned int page_size,
+ unsigned int address,
+ unsigned int n_bytes)
+{
+ unsigned char commandbuf[10];
+ unsigned char buf[275];
+ unsigned int addr = 0;
+
+ avrdude_message(MSG_NOTICE, "BusPirate: buspirate_paged_load(..,%s,%d,%d,%d)\n",m->desc,m->page_size,address,n_bytes);
+
+ // This should never happen, but still...
+ if (pgm->flag & BP_FLAG_NOPAGEDREAD) {
+ avrdude_message(MSG_INFO, "BusPirate: buspirate_paged_load() called while in nopagedread mode!\n");
+ return -1;
+ }
+
+ // determine what type of memory to read, only flash is supported
+ if (strcmp(m->desc, "flash") != 0) {
+ return -1;
+ }
+
+ // send command to read data
+ commandbuf[0] = 6;
+ commandbuf[1] = 2;
+
+ // send start address (in WORDS, not bytes!)
+ commandbuf[2] = (address >> 1 >> 24) & 0xff;
+ commandbuf[3] = (address >> 1>> 16) & 0xff;
+ commandbuf[4] = (address >> 1 >> 8) & 0xff;
+ commandbuf[5] = (address >> 1) & 0xff;
+
+ // send number of bytes to fetch (in BYTES)
+ commandbuf[6] = (n_bytes >> 24) & 0xff;
+ commandbuf[7] = (n_bytes >> 16) & 0xff;
+ commandbuf[8] = (n_bytes >> 8) & 0xff;
+ commandbuf[9] = (n_bytes) & 0xff;
+
+ buspirate_send_bin(pgm, commandbuf, 10);
+ buspirate_recv_bin(pgm, buf, 1);
+ buspirate_recv_bin(pgm, buf, 1);
+
+ if (buf[0] != 0x01) {
+ avrdude_message(MSG_INFO, "BusPirate: Paged Read command returned zero.\n");
+ return -1;
+ }
+
+ for (addr = 0; addr < n_bytes; addr++) {
+ buspirate_recv_bin(pgm, &m->buf[addr+address], 1);
+ }
+
+ return n_bytes;
+}
+/* Paged write function which utilizes the Bus Pirate's "Write then Read" binary SPI instruction */
+static int buspirate_paged_write(struct programmer_t *pgm,
+ AVRPART *p,
+ AVRMEM *m,
+ unsigned int page_size,
+ unsigned int base_addr,
+ unsigned int n_data_bytes)
+{
+ int page, i;
+ int addr = base_addr;
+ int n_page_writes;
+ int this_page_size;
+ unsigned char cmd_buf[4096] = {'\0'};
+ unsigned char send_byte, recv_byte;
+
+ if (!(pgm->flag & BP_FLAG_IN_BINMODE)) {
+ /* Return if we are not in binary mode. */
+ return -1;
+ }
+
+ if (pgm->flag & BP_FLAG_NOPAGEDWRITE) {
+ /* Return if we've nominated not to use paged writes. */
+ return -1;
+ }
+
+ if (page_size>1024) {
+ /* Page sizes greater than 1kB not yet supported. */
+ return -1;
+ }
+
+ if (strcmp(m->desc,"flash") != 0) {
+ /* Only flash memory currently supported. */
+ return -1;
+ }
+
+ /* pre-check opcodes */
+ if (m->op[AVR_OP_LOADPAGE_LO] == NULL) {
+ avrdude_message(MSG_INFO, "%s failure: %s command not defined for %s\n",
+ progname, "AVR_OP_LOADPAGE_LO", p->desc);
+ return -1;
+ }
+ if (m->op[AVR_OP_LOADPAGE_HI] == NULL) {
+ avrdude_message(MSG_INFO, "%s failure: %s command not defined for %s\n",
+ progname, "AVR_OP_LOADPAGE_HI", p->desc);
+ return -1;
+ }
+
+ /* Calculate total number of page writes needed: */
+ n_page_writes = n_data_bytes/page_size;
+ if (n_data_bytes%page_size >0)
+ n_page_writes++;
+
+ /* Ensure error LED is off: */
+ pgm->err_led(pgm, OFF);
+
+ /* Loop over pages: */
+ for (page=0; page<n_page_writes; page++) {
+
+ /* Determine bytes to write in this page: */
+ this_page_size = page_size;
+ if (page == n_page_writes-1)
+ this_page_size = n_data_bytes - page_size*page;
+
+ /* Set up command buffer: */
+ memset(cmd_buf, 0, 4*this_page_size);
+ for (i=0; i<this_page_size; i++) {
+
+ addr = base_addr + page*page_size + i;
+
+ if (i%2 == 0) {
+ avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]));
+ avr_set_addr(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), addr/2);
+ avr_set_input(m->op[AVR_OP_LOADPAGE_LO], &(cmd_buf[4*i]), m->buf[addr]);
+ } else {
+ avr_set_bits(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]));
+ avr_set_addr(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), addr/2);
+ avr_set_input(m->op[AVR_OP_LOADPAGE_HI], &(cmd_buf[4*i]), m->buf[addr]);
+ }
+ }
+
+ /* 00000100 - Write then read */
+ send_byte = 0x05;
+ buspirate_send_bin(pgm, &send_byte, 1);
+
+ /* Number of bytes to write: */
+ send_byte = (4*this_page_size)/0x100;
+ buspirate_send_bin(pgm, &send_byte, 1); /* High byte */
+ send_byte = (4*this_page_size)%0x100;
+ buspirate_send_bin(pgm, &send_byte, 1); /* Low byte */
+
+ /* Number of bytes to read: */
+ send_byte = 0x0;
+ buspirate_send_bin(pgm, &send_byte, 1); /* High byte */
+ buspirate_send_bin(pgm, &send_byte, 1); /* Low byte */
+
+ /* Set programming LED: */
+ pgm->pgm_led(pgm, ON);
+
+ /* Send command buffer: */
+ buspirate_send_bin(pgm, cmd_buf, 4*this_page_size);
+
+ /* Check for write failure: */
+ if ((buspirate_recv_bin(pgm, &recv_byte, 1) == EOF) || (recv_byte != 0x01)) {
+ avrdude_message(MSG_INFO, "BusPirate: Fatal error: Write Then Read did not succeed.\n");
+ pgm->pgm_led(pgm, OFF);
+ pgm->err_led(pgm, ON);
+ return -1;
+ }
+
+ /* Unset programming LED: */
+ pgm->pgm_led(pgm, OFF);
+
+ /* Write loaded page to flash: */
+ avr_write_page(pgm, p, m, addr);
+ }
+
+ return n_data_bytes;
+}
+
+static int buspirate_program_enable(struct programmer_t *pgm, AVRPART * p)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+
+ if (pgm->flag & BP_FLAG_IN_BINMODE) {
+ /* Clear configured reset pin(s): CS and/or AUX and/or AUX2 */
+ PDATA(pgm)->current_peripherals_config &= ~PDATA(pgm)->reset;
+ if (buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01) < 0)
+ return -1;
+ }
+ else
+ buspirate_expect(pgm, "{\n", "CS ENABLED", 1);
+
+ if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
+ avrdude_message(MSG_INFO, "program enable instruction not defined for part \"%s\"\n",
+ p->desc);
+ return -1;
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+ avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd);
+ pgm->cmd(pgm, cmd, res);
+
+ if (res[2] != cmd[1])
+ return -2;
+
+ return 0;
+}
+
+static int buspirate_chip_erase(struct programmer_t *pgm, AVRPART * p)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+
+ if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
+ avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
+ p->desc);
+ return -1;
+ }
+
+ pgm->pgm_led(pgm, ON);
+
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
+ pgm->cmd(pgm, cmd, res);
+ usleep(p->chip_erase_delay);
+ pgm->initialize(pgm, p);
+
+ pgm->pgm_led(pgm, OFF);
+
+ return 0;
+}
+
+/* Interface - management */
+static void buspirate_setup(struct programmer_t *pgm)
+{
+ /* Allocate private data */
+ if ((pgm->cookie = calloc(1, sizeof(struct pdata))) == 0) {
+ // avrdude_message(MSG_INFO, "%s: buspirate_initpgm(): Out of memory allocating private data\n",
+ // progname);
+ // exit(1);
+ avrdude_oom("buspirate_initpgm(): Out of memory allocating private data\n");
+ }
+ PDATA(pgm)->serial_recv_timeout = 100;
+}
+
+static void buspirate_teardown(struct programmer_t *pgm)
+{
+ free(pgm->cookie);
+}
+const char buspirate_desc[] = "Using the Bus Pirate's SPI interface for programming";
+
+void buspirate_initpgm(struct programmer_t *pgm)
+{
+ strcpy(pgm->type, "BusPirate");
+
+ pgm->display = buspirate_dummy_6;
+
+ /* BusPirate itself related methods */
+ pgm->open = buspirate_open;
+ pgm->close = buspirate_close;
+ pgm->enable = buspirate_enable;
+ pgm->disable = buspirate_disable;
+ pgm->initialize = buspirate_initialize;
+
+ /* Chip related methods */
+ pgm->powerup = buspirate_powerup;
+ pgm->powerdown = buspirate_powerdown;
+ pgm->program_enable = buspirate_program_enable;
+ pgm->chip_erase = buspirate_chip_erase;
+ pgm->cmd = buspirate_cmd;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+
+ pgm->paged_write = buspirate_paged_write;
+ pgm->paged_load = buspirate_paged_load;
+
+ /* Support functions */
+ pgm->parseextparams = buspirate_parseextparms;
+
+ pgm->setup = buspirate_setup;
+ pgm->teardown = buspirate_teardown;
+}
+
+/* Bitbang support */
+
+static void buspirate_bb_enable(struct programmer_t *pgm)
+{
+ unsigned char buf[20] = { '\0' };
+
+ if (bitbang_check_prerequisites(pgm) < 0)
+ return; /* XXX should treat as error */
+
+ avrdude_message(MSG_INFO, "Attempting to initiate BusPirate bitbang binary mode...\n");
+
+ /* Send two CRs to ensure we're not in a sub-menu of the UI if we're in ASCII mode: */
+ buspirate_send_bin(pgm, (const unsigned char*)"\n\n", 2);
+
+ /* Clear input buffer: */
+ serial_drain(&pgm->fd, 0);
+
+ /* == Switch to binmode - send 20x '\0' == */
+ buspirate_send_bin(pgm, buf, sizeof(buf));
+
+ /* Expecting 'BBIOx' reply */
+ memset(buf, 0, sizeof(buf));
+ buspirate_recv_bin(pgm, buf, 5);
+ if (sscanf((char*)buf, "BBIO%1d", &PDATA(pgm)->binmode_version) != 1) {
+ avrdude_message(MSG_INFO, "Binary mode not confirmed: '%s'\n", buf);
+ buspirate_reset_from_binmode(pgm);
+ return;
+ }
+ avrdude_message(MSG_INFO, "BusPirate binmode version: %d\n",
+ PDATA(pgm)->binmode_version);
+
+ pgm->flag |= BP_FLAG_IN_BINMODE;
+
+ /* Set pin directions and an initial pin status (all high) */
+ PDATA(pgm)->pin_dir = 0x12; /* AUX, MISO input; everything else output */
+ buf[0] = PDATA(pgm)->pin_dir | 0x40;
+ buspirate_send_bin(pgm, buf, 1);
+ buspirate_recv_bin(pgm, buf, 1);
+
+ PDATA(pgm)->pin_val = 0x3f; /* PULLUP, AUX, MOSI, CLK, MISO, CS high */
+ buf[0] = PDATA(pgm)->pin_val | 0x80;
+ buspirate_send_bin(pgm, buf, 1);
+ buspirate_recv_bin(pgm, buf, 1);
+
+ /* Done */
+ return;
+}
+
+/*
+ Direction:
+ 010xxxxx
+ Input (1) or output (0):
+ AUX|MOSI|CLK|MISO|CS
+
+ Output value:
+ 1xxxxxxx
+ High (1) or low(0):
+ 1|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS
+
+ Both respond with a byte with current status:
+ 0|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS
+*/
+static int buspirate_bb_getpin(struct programmer_t *pgm, int pinfunc)
+{
+ unsigned char buf[10];
+ int value = 0;
+ int pin = pgm->pinno[pinfunc];
+
+ if (pin & PIN_INVERSE) {
+ pin &= PIN_MASK;
+ value = 1;
+ }
+
+ if (pin < 1 || pin > 5)
+ return -1;
+
+ buf[0] = PDATA(pgm)->pin_dir | 0x40;
+ if (buspirate_send_bin(pgm, buf, 1) < 0)
+ return -1;
+ /* Read all of the previously-expected-but-unread bytes */
+ while (PDATA(pgm)->unread_bytes > 0) {
+ if (buspirate_recv_bin(pgm, buf, 1) < 0)
+ return -1;
+ PDATA(pgm)->unread_bytes--;
+ }
+
+ /* Now read the actual response */
+ if (buspirate_recv_bin(pgm, buf, 1) < 0)
+ return -1;
+
+ if (buf[0] & (1 << (pin - 1)))
+ value ^= 1;
+
+ avrdude_message(MSG_DEBUG, "get pin %d = %d\n", pin, value);
+
+ return value;
+}
+
+static int buspirate_bb_setpin_internal(struct programmer_t *pgm, int pin, int value)
+{
+ unsigned char buf[10];
+
+ if (pin & PIN_INVERSE) {
+ value = !value;
+ pin &= PIN_MASK;
+ }
+
+ if ((pin < 1 || pin > 5) && (pin != 7)) // 7 is POWER
+ return -1;
+
+ avrdude_message(MSG_DEBUG, "set pin %d = %d\n", pin, value);
+
+ if (value)
+ PDATA(pgm)->pin_val |= (1 << (pin - 1));
+ else
+ PDATA(pgm)->pin_val &= ~(1 << (pin - 1));
+
+ buf[0] = PDATA(pgm)->pin_val | 0x80;
+ if (buspirate_send_bin(pgm, buf, 1) < 0)
+ return -1;
+ /* We'll get a byte back, but we don't need to read it now.
+ This is just a quick optimization that saves some USB
+ round trips, improving read times by a factor of 3. */
+ PDATA(pgm)->unread_bytes++;
+
+ return 0;
+}
+
+static int buspirate_bb_setpin(struct programmer_t *pgm, int pinfunc, int value)
+{
+ return buspirate_bb_setpin_internal(pgm, pgm->pinno[pinfunc], value);
+}
+
+
+static int buspirate_bb_highpulsepin(struct programmer_t *pgm, int pinfunc)
+{
+ int ret;
+ ret = buspirate_bb_setpin(pgm, pinfunc, 1);
+ if (ret < 0)
+ return ret;
+ return buspirate_bb_setpin(pgm, pinfunc, 0);
+}
+
+static void buspirate_bb_powerup(struct programmer_t *pgm)
+{
+ buspirate_bb_setpin_internal(pgm, 7, 1);
+}
+
+static void buspirate_bb_powerdown(struct programmer_t *pgm)
+{
+ buspirate_bb_setpin_internal(pgm, 7, 0);
+}
+
+const char buspirate_bb_desc[] = "Using the Bus Pirate's bitbang interface for programming";
+
+void buspirate_bb_initpgm(struct programmer_t *pgm)
+{
+ strcpy(pgm->type, "BusPirate_BB");
+
+ pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
+
+ pgm->display = buspirate_dummy_6;
+
+ /* BusPirate itself related methods */
+ pgm->setup = buspirate_setup;
+ pgm->teardown = buspirate_teardown;
+ pgm->open = buspirate_open;
+ pgm->close = buspirate_close;
+ pgm->enable = buspirate_bb_enable;
+ pgm->disable = buspirate_disable;
+
+ /* Chip related methods */
+ pgm->initialize = bitbang_initialize;
+ pgm->rdy_led = bitbang_rdy_led;
+ pgm->err_led = bitbang_err_led;
+ pgm->pgm_led = bitbang_pgm_led;
+ pgm->vfy_led = bitbang_vfy_led;
+ pgm->program_enable = bitbang_program_enable;
+ pgm->chip_erase = bitbang_chip_erase;
+ pgm->cmd = bitbang_cmd;
+ pgm->cmd_tpi = bitbang_cmd_tpi;
+ pgm->powerup = buspirate_bb_powerup;
+ pgm->powerdown = buspirate_bb_powerdown;
+ pgm->setpin = buspirate_bb_setpin;
+ pgm->getpin = buspirate_bb_getpin;
+ pgm->highpulsepin = buspirate_bb_highpulsepin;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+}
diff --git a/xs/src/avrdude/buspirate.h b/xs/src/avrdude/buspirate.h
new file mode 100644
index 000000000..835334a20
--- /dev/null
+++ b/xs/src/avrdude/buspirate.h
@@ -0,0 +1,32 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ *
+ * avrdude support for The Bus Pirate - universal serial interface
+ *
+ * Copyright (C) 2009 Michal Ludvig <mludvig@logix.net.nz>
+ *
+ * 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 buspirate_h
+#define buspirate_h
+
+extern const char buspirate_desc[];
+extern const char buspirate_bb_desc[];
+void buspirate_initpgm (struct programmer_t *pgm);
+void buspirate_bb_initpgm (struct programmer_t *pgm);
+
+#endif
diff --git a/xs/src/avrdude/butterfly.c b/xs/src/avrdude/butterfly.c
new file mode 100644
index 000000000..beb5e04de
--- /dev/null
+++ b/xs/src/avrdude/butterfly.c
@@ -0,0 +1,763 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
+ * Copyright (C) 2005, 2007 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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 the serial programming mode of the Atmel butterfly
+ * evaluation board. This board features a bootloader which uses a protocol
+ * very similar, but not identical, to the one described in application note
+ * avr910.
+ *
+ * Actually, the butterfly uses a predecessor of the avr910 protocol
+ * which is described in application notes avr109 (generic AVR
+ * bootloader) and avr911 (opensource programmer). This file now
+ * fully handles the features present in avr109. It should probably
+ * be renamed to avr109, but we rather stick with the old name inside
+ * the file. We'll provide aliases for "avr109" and "avr911" in
+ * avrdude.conf so users could call it by these name as well.
+ */
+
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "butterfly.h"
+
+/*
+ * Private data for this programmer.
+ */
+struct pdata
+{
+ char has_auto_incr_addr;
+ unsigned int buffersize;
+};
+
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
+static void butterfly_setup(PROGRAMMER * pgm)
+{
+ if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
+ // avrdude_message(MSG_INFO, "%s: butterfly_setup(): Out of memory allocating private data\n",
+ // progname);
+ // exit(1);
+ avrdude_oom("butterfly_setup(): Out of memory allocating private data\n");
+ }
+ memset(pgm->cookie, 0, sizeof(struct pdata));
+}
+
+static void butterfly_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+}
+
+static int butterfly_send(PROGRAMMER * pgm, char * buf, size_t len)
+{
+ return serial_send(&pgm->fd, (unsigned char *)buf, len);
+}
+
+
+static int butterfly_recv(PROGRAMMER * pgm, char * buf, size_t len)
+{
+ int rv;
+
+ rv = serial_recv(&pgm->fd, (unsigned char *)buf, len);
+ if (rv < 0) {
+ avrdude_message(MSG_INFO, "%s: butterfly_recv(): programmer is not responding\n",
+ progname);
+ return -1;
+ }
+ return 0;
+}
+
+
+static int butterfly_drain(PROGRAMMER * pgm, int display)
+{
+ return serial_drain(&pgm->fd, display);
+}
+
+
+static int butterfly_vfy_cmd_sent(PROGRAMMER * pgm, char * errmsg)
+{
+ char c;
+
+ butterfly_recv(pgm, &c, 1);
+ if (c != '\r') {
+ avrdude_message(MSG_INFO, "%s: error: programmer did not respond to command: %s\n",
+ progname, errmsg);
+ return -1;
+ }
+ return 0;
+}
+
+
+static int butterfly_rdy_led(PROGRAMMER * pgm, int value)
+{
+ /* Do nothing. */
+
+ return 0;
+}
+
+
+static int butterfly_err_led(PROGRAMMER * pgm, int value)
+{
+ /* Do nothing. */
+
+ return 0;
+}
+
+
+static int butterfly_pgm_led(PROGRAMMER * pgm, int value)
+{
+ /* Do nothing. */
+
+ return 0;
+}
+
+
+static int butterfly_vfy_led(PROGRAMMER * pgm, int value)
+{
+ /* Do nothing. */
+
+ return 0;
+}
+
+
+/*
+ * issue the 'chip erase' command to the butterfly board
+ */
+static int butterfly_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ butterfly_send(pgm, "e", 1);
+ if (butterfly_vfy_cmd_sent(pgm, "chip erase") < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static void butterfly_enter_prog_mode(PROGRAMMER * pgm)
+{
+ butterfly_send(pgm, "P", 1);
+ butterfly_vfy_cmd_sent(pgm, "enter prog mode");
+}
+
+
+static void butterfly_leave_prog_mode(PROGRAMMER * pgm)
+{
+ butterfly_send(pgm, "L", 1);
+ butterfly_vfy_cmd_sent(pgm, "leave prog mode");
+}
+
+
+/*
+ * issue the 'program enable' command to the AVR device
+ */
+static int butterfly_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ return -1;
+}
+
+
+/*
+ * apply power to the AVR processor
+ */
+static void butterfly_powerup(PROGRAMMER * pgm)
+{
+ /* Do nothing. */
+
+ return;
+}
+
+
+/*
+ * remove power from the AVR processor
+ */
+static void butterfly_powerdown(PROGRAMMER * pgm)
+{
+ /* Do nothing. */
+
+ return;
+}
+
+#define IS_BUTTERFLY_MK 0x0001
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+static int butterfly_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ char id[8];
+ char sw[2];
+ char hw[2];
+ char buf[10];
+ char type;
+ char c, devtype_1st;
+
+ /*
+ * Send some ESC to activate butterfly bootloader. This is not needed
+ * for plain avr109 bootloaders but does not harm there either.
+ */
+ avrdude_message(MSG_INFO, "Connecting to programmer: ");
+ if (pgm->flag & IS_BUTTERFLY_MK)
+ {
+ char mk_reset_cmd[6] = {"#aR@S\r"};
+ unsigned char mk_timeout = 0;
+
+ putc('.', stderr);
+ butterfly_send(pgm, mk_reset_cmd, sizeof(mk_reset_cmd));
+ usleep(20000);
+
+ do
+ {
+ c = 27;
+ butterfly_send(pgm, &c, 1);
+ usleep(20000);
+ c = 0xaa;
+ usleep(80000);
+ butterfly_send(pgm, &c, 1);
+ if (mk_timeout % 10 == 0) putc('.', stderr);
+ } while (mk_timeout++ < 10);
+
+ butterfly_recv(pgm, &c, 1);
+ if ( c != 'M' && c != '?')
+ {
+ avrdude_message(MSG_INFO, "\nConnection FAILED.");
+ return -1;
+ }
+ else
+ {
+ id[0] = 'M'; id[1] = 'K'; id[2] = '2'; id[3] = 0;
+ }
+ }
+ else
+ {
+ do {
+ putc('.', stderr);
+ butterfly_send(pgm, "\033", 1);
+ butterfly_drain(pgm, 0);
+ butterfly_send(pgm, "S", 1);
+ butterfly_recv(pgm, &c, 1);
+ if (c != '?') {
+ putc('\n', stderr);
+ /*
+ * Got a useful response, continue getting the programmer
+ * identifier. Programmer returns exactly 7 chars _without_
+ * the null.
+ */
+ id[0] = c;
+ butterfly_recv(pgm, &id[1], sizeof(id)-2);
+ id[sizeof(id)-1] = '\0';
+ }
+ } while (c == '?');
+ }
+
+ /* Get the HW and SW versions to see if the programmer is present. */
+ butterfly_drain(pgm, 0);
+
+ butterfly_send(pgm, "V", 1);
+ butterfly_recv(pgm, sw, sizeof(sw));
+
+ butterfly_send(pgm, "v", 1);
+ butterfly_recv(pgm, hw, 1); /* first, read only _one_ byte */
+ if (hw[0]!='?') {
+ butterfly_recv(pgm, &hw[1], 1);/* now, read second byte */
+ };
+
+ /* Get the programmer type (serial or parallel). Expect serial. */
+
+ butterfly_send(pgm, "p", 1);
+ butterfly_recv(pgm, &type, 1);
+
+ avrdude_message(MSG_INFO, "Found programmer: Id = \"%s\"; type = %c\n", id, type);
+ avrdude_message(MSG_INFO, " Software Version = %c.%c; ", sw[0], sw[1]);
+ if (hw[0]=='?') {
+ avrdude_message(MSG_INFO, "No Hardware Version given.\n");
+ } else {
+ avrdude_message(MSG_INFO, "Hardware Version = %c.%c\n", hw[0], hw[1]);
+ };
+
+ /* See if programmer supports autoincrement of address. */
+
+ butterfly_send(pgm, "a", 1);
+ butterfly_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1);
+ if (PDATA(pgm)->has_auto_incr_addr == 'Y')
+ avrdude_message(MSG_INFO, "Programmer supports auto addr increment.\n");
+
+ /* Check support for buffered memory access, abort if not available */
+
+ butterfly_send(pgm, "b", 1);
+ butterfly_recv(pgm, &c, 1);
+ if (c != 'Y') {
+ avrdude_message(MSG_INFO, "%s: error: buffered memory access not supported. Maybe it isn't\n"\
+ "a butterfly/AVR109 but a AVR910 device?\n", progname);
+ return -1;
+ };
+ butterfly_recv(pgm, &c, 1);
+ PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8;
+ butterfly_recv(pgm, &c, 1);
+ PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c;
+ avrdude_message(MSG_INFO, "Programmer supports buffered memory access with buffersize=%i bytes.\n",
+ PDATA(pgm)->buffersize);
+
+ /* Get list of devices that the programmer supports. */
+
+ butterfly_send(pgm, "t", 1);
+ avrdude_message(MSG_INFO, "\nProgrammer supports the following devices:\n");
+ devtype_1st = 0;
+ while (1) {
+ butterfly_recv(pgm, &c, 1);
+ if (devtype_1st == 0)
+ devtype_1st = c;
+
+ if (c == 0)
+ break;
+ avrdude_message(MSG_INFO, " Device code: 0x%02x\n", (unsigned int)(unsigned char)c);
+ };
+ avrdude_message(MSG_INFO, "\n");
+
+ /* Tell the programmer which part we selected.
+ According to the AVR109 code, this is ignored by the bootloader. As
+ some early versions might not properly ignore it, rather pick up the
+ first device type as reported above than anything out of avrdude.conf,
+ so to avoid a potential conflict. There appears to be no general
+ agreement on AVR910 device IDs beyond the ones from the original
+ appnote 910. */
+
+ buf[0] = 'T';
+ buf[1] = devtype_1st;
+
+ butterfly_send(pgm, buf, 2);
+ if (butterfly_vfy_cmd_sent(pgm, "select device") < 0)
+ return -1;
+
+ if (verbose)
+ avrdude_message(MSG_INFO, "%s: devcode selected: 0x%02x\n",
+ progname, (unsigned)buf[1]);
+
+ butterfly_enter_prog_mode(pgm);
+ butterfly_drain(pgm, 0);
+
+ return 0;
+}
+
+
+
+static void butterfly_disable(PROGRAMMER * pgm)
+{
+ butterfly_leave_prog_mode(pgm);
+
+ return;
+}
+
+
+static void butterfly_enable(PROGRAMMER * pgm)
+{
+ return;
+}
+
+
+static int butterfly_open(PROGRAMMER * pgm, char * port)
+{
+ union pinfo pinfo;
+ strcpy(pgm->port, port);
+ /*
+ * If baudrate was not specified use 19200 Baud
+ */
+ if(pgm->baudrate == 0) {
+ pgm->baudrate = 19200;
+ }
+ pinfo.baud = pgm->baudrate;
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ butterfly_drain (pgm, 0);
+
+ return 0;
+}
+
+
+static void butterfly_close(PROGRAMMER * pgm)
+{
+ /* "exit programmer" */
+ butterfly_send(pgm, "E", 1);
+ butterfly_vfy_cmd_sent(pgm, "exit bootloader");
+
+ serial_close(&pgm->fd);
+ pgm->fd.ifd = -1;
+}
+
+
+static void butterfly_display(PROGRAMMER * pgm, const char * p)
+{
+ return;
+}
+
+
+static void butterfly_set_addr(PROGRAMMER * pgm, unsigned long addr)
+{
+ char cmd[3];
+
+ cmd[0] = 'A';
+ cmd[1] = (addr >> 8) & 0xff;
+ cmd[2] = addr & 0xff;
+
+ butterfly_send(pgm, cmd, sizeof(cmd));
+ butterfly_vfy_cmd_sent(pgm, "set addr");
+}
+
+
+static void butterfly_set_extaddr(PROGRAMMER * pgm, unsigned long addr)
+{
+ char cmd[4];
+
+ cmd[0] = 'H';
+ cmd[1] = (addr >> 16) & 0xff;
+ cmd[2] = (addr >> 8) & 0xff;
+ cmd[3] = addr & 0xff;
+
+ butterfly_send(pgm, cmd, sizeof(cmd));
+ butterfly_vfy_cmd_sent(pgm, "set extaddr");
+}
+
+
+
+static int butterfly_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char value)
+{
+ char cmd[6];
+ int size;
+ int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
+
+ if ((strcmp(m->desc, "flash") == 0) || (strcmp(m->desc, "eeprom") == 0))
+ {
+ cmd[0] = 'B';
+ cmd[1] = 0;
+ if ((cmd[3] = toupper((int)(m->desc[0]))) == 'E') { /* write to eeprom */
+ cmd[2] = 1;
+ cmd[4] = value;
+ size = 5;
+ } else { /* write to flash */
+ /* @@@ not yet implemented */
+ cmd[2] = 2;
+ size = 6;
+ return -1;
+ }
+ if (use_ext_addr) {
+ butterfly_set_extaddr(pgm, addr);
+ } else {
+ butterfly_set_addr(pgm, addr);
+ }
+ }
+ else if (strcmp(m->desc, "lock") == 0)
+ {
+ cmd[0] = 'l';
+ cmd[1] = value;
+ size = 2;
+ }
+ else
+ return -1;
+
+ butterfly_send(pgm, cmd, size);
+ if (butterfly_vfy_cmd_sent(pgm, "write byte") < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int butterfly_read_byte_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char * value)
+{
+ static int cached = 0;
+ static unsigned char cvalue;
+ static unsigned long caddr;
+ int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
+
+ if (cached && ((caddr + 1) == addr)) {
+ *value = cvalue;
+ cached = 0;
+ }
+ else {
+ char buf[2];
+
+ if (use_ext_addr) {
+ butterfly_set_extaddr(pgm, addr >> 1);
+ } else {
+ butterfly_set_addr(pgm, addr >> 1);
+ }
+
+ butterfly_send(pgm, "g\000\002F", 4);
+
+ /* Read back the program mem word (MSB first) */
+ butterfly_recv(pgm, buf, sizeof(buf));
+
+ if ((addr & 0x01) == 0) {
+ *value = buf[0];
+ cached = 1;
+ cvalue = buf[1];
+ caddr = addr;
+ }
+ else {
+ *value = buf[1];
+ }
+ }
+
+ return 0;
+}
+
+
+static int butterfly_read_byte_eeprom(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char * value)
+{
+ butterfly_set_addr(pgm, addr);
+ butterfly_send(pgm, "g\000\001E", 4);
+ butterfly_recv(pgm, (char *)value, 1);
+ return 0;
+}
+
+static int butterfly_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned int addr)
+{
+ if (strcmp(m->desc, "flash") == 0)
+ return -1; /* not supported */
+ if (strcmp(m->desc, "eeprom") == 0)
+ return 0; /* nothing to do */
+ avrdude_message(MSG_INFO, "%s: butterfly_page_erase() called on memory type \"%s\"\n",
+ progname, m->desc);
+ return -1;
+}
+
+static int butterfly_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char * value)
+{
+ char cmd;
+
+ if (strcmp(m->desc, "flash") == 0) {
+ return butterfly_read_byte_flash(pgm, p, m, addr, value);
+ }
+
+ if (strcmp(m->desc, "eeprom") == 0) {
+ return butterfly_read_byte_eeprom(pgm, p, m, addr, value);
+ }
+
+ if (strcmp(m->desc, "lfuse") == 0) {
+ cmd = 'F';
+ }
+ else if (strcmp(m->desc, "hfuse") == 0) {
+ cmd = 'N';
+ }
+ else if (strcmp(m->desc, "efuse") == 0) {
+ cmd = 'Q';
+ }
+ else if (strcmp(m->desc, "lock") == 0) {
+ cmd = 'r';
+ }
+ else
+ return -1;
+
+ butterfly_send(pgm, &cmd, 1);
+ butterfly_recv(pgm, (char *)value, 1);
+
+ return *value == '?'? -1: 0;
+}
+
+
+
+static int butterfly_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned int max_addr = addr + n_bytes;
+ char *cmd;
+ unsigned int blocksize = PDATA(pgm)->buffersize;
+ int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
+ unsigned int wr_size = 2;
+
+ if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
+ return -2;
+
+ if (m->desc[0] == 'e')
+ wr_size = blocksize = 1; /* Write to eeprom single bytes only */
+
+ if (use_ext_addr) {
+ butterfly_set_extaddr(pgm, addr / wr_size);
+ } else {
+ butterfly_set_addr(pgm, addr / wr_size);
+ }
+
+#if 0
+ usleep(1000000);
+ butterfly_send(pgm, "y", 1);
+ if (butterfly_vfy_cmd_sent(pgm, "clear LED") < 0)
+ return -1;
+#endif
+
+ cmd = malloc(4+blocksize);
+ if (!cmd) return -1;
+ cmd[0] = 'B';
+ cmd[3] = toupper((int)(m->desc[0]));
+
+ while (addr < max_addr) {
+ if ((max_addr - addr) < blocksize) {
+ blocksize = max_addr - addr;
+ };
+ memcpy(&cmd[4], &m->buf[addr], blocksize);
+ cmd[1] = (blocksize >> 8) & 0xff;
+ cmd[2] = blocksize & 0xff;
+
+ butterfly_send(pgm, cmd, 4+blocksize);
+ if (butterfly_vfy_cmd_sent(pgm, "write block") < 0)
+ return -1;
+
+ addr += blocksize;
+ } /* while */
+ free(cmd);
+
+ return addr;
+}
+
+
+
+static int butterfly_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned int max_addr = addr + n_bytes;
+ int rd_size = 2;
+ int blocksize = PDATA(pgm)->buffersize;
+ int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL;
+
+ /* check parameter syntax: only "flash" or "eeprom" is allowed */
+ if (strcmp(m->desc, "flash") && strcmp(m->desc, "eeprom"))
+ return -2;
+
+ if (m->desc[0] == 'e')
+ rd_size = blocksize = 1; /* Read from eeprom single bytes only */
+
+ { /* use buffered mode */
+ char cmd[4];
+
+ cmd[0] = 'g';
+ cmd[3] = toupper((int)(m->desc[0]));
+
+ if (use_ext_addr) {
+ butterfly_set_extaddr(pgm, addr / rd_size);
+ } else {
+ butterfly_set_addr(pgm, addr / rd_size);
+ }
+ while (addr < max_addr) {
+ if ((max_addr - addr) < blocksize) {
+ blocksize = max_addr - addr;
+ };
+ cmd[1] = (blocksize >> 8) & 0xff;
+ cmd[2] = blocksize & 0xff;
+
+ butterfly_send(pgm, cmd, 4);
+ butterfly_recv(pgm, (char *)&m->buf[addr], blocksize);
+
+ addr += blocksize;
+ } /* while */
+ }
+
+ return addr * rd_size;
+}
+
+
+/* Signature byte reads are always 3 bytes. */
+static int butterfly_read_sig_bytes(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m)
+{
+ unsigned char tmp;
+
+ if (m->size < 3) {
+ avrdude_message(MSG_INFO, "%s: memsize too small for sig byte read", progname);
+ return -1;
+ }
+
+ butterfly_send(pgm, "s", 1);
+ butterfly_recv(pgm, (char *)m->buf, 3);
+ /* Returned signature has wrong order. */
+ tmp = m->buf[2];
+ m->buf[2] = m->buf[0];
+ m->buf[0] = tmp;
+
+ return 3;
+}
+
+const char butterfly_desc[] = "Atmel Butterfly evaluation board; Atmel AppNotes AVR109, AVR911";
+
+void butterfly_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "butterfly");
+
+ /*
+ * mandatory functions
+ */
+ pgm->rdy_led = butterfly_rdy_led;
+ pgm->err_led = butterfly_err_led;
+ pgm->pgm_led = butterfly_pgm_led;
+ pgm->vfy_led = butterfly_vfy_led;
+ pgm->initialize = butterfly_initialize;
+ pgm->display = butterfly_display;
+ pgm->enable = butterfly_enable;
+ pgm->disable = butterfly_disable;
+ pgm->powerup = butterfly_powerup;
+ pgm->powerdown = butterfly_powerdown;
+ pgm->program_enable = butterfly_program_enable;
+ pgm->chip_erase = butterfly_chip_erase;
+ pgm->open = butterfly_open;
+ pgm->close = butterfly_close;
+ pgm->read_byte = butterfly_read_byte;
+ pgm->write_byte = butterfly_write_byte;
+
+ /*
+ * optional functions
+ */
+
+ pgm->page_erase = butterfly_page_erase;
+ pgm->paged_write = butterfly_paged_write;
+ pgm->paged_load = butterfly_paged_load;
+
+ pgm->read_sig_bytes = butterfly_read_sig_bytes;
+
+ pgm->setup = butterfly_setup;
+ pgm->teardown = butterfly_teardown;
+ pgm->flag = 0;
+}
+
+const char butterfly_mk_desc[] = "Mikrokopter.de Butterfly";
+
+void butterfly_mk_initpgm(PROGRAMMER * pgm)
+{
+ butterfly_initpgm(pgm);
+ strcpy(pgm->type, "butterfly_mk");
+ pgm->flag = IS_BUTTERFLY_MK;
+}
diff --git a/xs/src/avrdude/butterfly.h b/xs/src/avrdude/butterfly.h
new file mode 100644
index 000000000..6f6a54c84
--- /dev/null
+++ b/xs/src/avrdude/butterfly.h
@@ -0,0 +1,37 @@
+/*
+ * 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$ */
+
+#ifndef butterfly_h
+#define butterfly_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char butterfly_desc[];
+extern const char butterfly_mk_desc[];
+void butterfly_initpgm (PROGRAMMER * pgm);
+void butterfly_mk_initpgm (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* butterfly_h */
diff --git a/xs/src/avrdude/config.c b/xs/src/avrdude/config.c
new file mode 100644
index 000000000..08193cfc5
--- /dev/null
+++ b/xs/src/avrdude/config.c
@@ -0,0 +1,349 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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$ */
+
+#include "ac_cfg.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+#include "config.h"
+
+#include "config_gram.h"
+
+char default_programmer[MAX_STR_CONST];
+char default_parallel[PATH_MAX];
+char default_serial[PATH_MAX];
+double default_bitclock;
+int default_safemode;
+
+char string_buf[MAX_STR_CONST];
+char *string_buf_ptr;
+
+LISTID string_list;
+LISTID number_list;
+PROGRAMMER * current_prog;
+AVRPART * current_part;
+AVRMEM * current_mem;
+LISTID part_list;
+LISTID programmers;
+
+int lineno;
+const char * infile;
+
+extern char * yytext;
+
+#define DEBUG 0
+
+void cleanup_config(void)
+{
+ ldestroy_cb(part_list, (void(*)(void*))avr_free_part);
+ ldestroy_cb(programmers, (void(*)(void*))pgm_free);
+ ldestroy_cb(string_list, (void(*)(void*))free_token);
+ ldestroy_cb(number_list, (void(*)(void*))free_token);
+}
+
+int init_config(void)
+{
+ string_list = lcreat(NULL, 0);
+ number_list = lcreat(NULL, 0);
+ current_prog = NULL;
+ current_part = NULL;
+ current_mem = NULL;
+ part_list = lcreat(NULL, 0);
+ programmers = lcreat(NULL, 0);
+
+ lineno = 1;
+ infile = NULL;
+
+ return 0;
+}
+
+
+
+int yywrap()
+{
+ return 1;
+}
+
+
+int yyerror(char * errmsg, ...)
+{
+ va_list args;
+
+ char message[512];
+
+ va_start(args, errmsg);
+
+ vsnprintf(message, sizeof(message), errmsg, args);
+ avrdude_message(MSG_INFO, "%s: error at %s:%d: %s\n", progname, infile, lineno, message);
+
+ va_end(args);
+
+ return 0;
+}
+
+
+int yywarning(char * errmsg, ...)
+{
+ va_list args;
+
+ char message[512];
+
+ va_start(args, errmsg);
+
+ vsnprintf(message, sizeof(message), errmsg, args);
+ avrdude_message(MSG_INFO, "%s: warning at %s:%d: %s\n", progname, infile, lineno, message);
+
+ va_end(args);
+
+ return 0;
+}
+
+
+TOKEN * new_token(int primary)
+{
+ TOKEN * tkn;
+
+ tkn = (TOKEN *)malloc(sizeof(TOKEN));
+ if (tkn == NULL) {
+ yyerror("new_token(): out of memory");
+ return NULL;
+ }
+
+ memset(tkn, 0, sizeof(TOKEN));
+
+ tkn->primary = primary;
+
+ return tkn;
+}
+
+
+void free_token(TOKEN * tkn)
+{
+ if (tkn) {
+ switch (tkn->value.type) {
+ case V_STR:
+ if (tkn->value.string)
+ free(tkn->value.string);
+ tkn->value.string = NULL;
+ break;
+ }
+
+ free(tkn);
+ }
+}
+
+
+void free_tokens(int n, ...)
+{
+ TOKEN * t;
+ va_list ap;
+
+ va_start(ap, n);
+ while (n--) {
+ t = va_arg(ap, TOKEN *);
+ free_token(t);
+ }
+ va_end(ap);
+}
+
+
+
+TOKEN * number(char * text)
+{
+ struct token_t * tkn;
+
+ tkn = new_token(TKN_NUMBER);
+ if (tkn == NULL) {
+ return NULL; /* yyerror already called */
+ }
+ tkn->value.type = V_NUM;
+ tkn->value.number = atoi(text);
+
+#if DEBUG
+ avrdude_message(MSG_INFO, "NUMBER(%d)\n", tkn->value.number);
+#endif
+
+ return tkn;
+}
+
+TOKEN * number_real(char * text)
+{
+ struct token_t * tkn;
+
+ tkn = new_token(TKN_NUMBER);
+ tkn->value.type = V_NUM_REAL;
+ tkn->value.number_real = atof(text);
+
+#if DEBUG
+ avrdude_message(MSG_INFO, "NUMBER(%g)\n", tkn->value.number_real);
+#endif
+
+ return tkn;
+}
+
+TOKEN * hexnumber(char * text)
+{
+ struct token_t * tkn;
+ char * e;
+
+ tkn = new_token(TKN_NUMBER);
+ if (tkn == NULL) {
+ return NULL; /* yyerror already called */
+ }
+ tkn->value.type = V_NUM;
+ tkn->value.number = strtoul(text, &e, 16);
+ if ((e == text) || (*e != 0)) {
+ yyerror("can't scan hex number \"%s\"", text);
+ return NULL;
+ }
+
+#if DEBUG
+ avrdude_message(MSG_INFO, "HEXNUMBER(%g)\n", tkn->value.number);
+#endif
+
+ return tkn;
+}
+
+
+TOKEN * string(char * text)
+{
+ struct token_t * tkn;
+ int len;
+
+ tkn = new_token(TKN_STRING);
+ if (tkn == NULL) {
+ return NULL; /* yyerror already called */
+ }
+
+ len = strlen(text);
+
+ tkn->value.type = V_STR;
+ tkn->value.string = (char *) malloc(len+1);
+ if (tkn->value.string == NULL) {
+ yyerror("string(): out of memory");
+ return NULL;
+ }
+ strcpy(tkn->value.string, text);
+
+#if DEBUG
+ avrdude_message(MSG_INFO, "STRING(%s)\n", tkn->value.string);
+#endif
+
+ return tkn;
+}
+
+
+TOKEN * keyword(int primary)
+{
+ struct token_t * tkn;
+
+ tkn = new_token(primary);
+
+ return tkn;
+}
+
+
+void print_token(TOKEN * tkn)
+{
+ if (!tkn)
+ return;
+
+ avrdude_message(MSG_INFO, "token = %d = ", tkn->primary);
+ switch (tkn->value.type) {
+ case V_NUM:
+ avrdude_message(MSG_INFO, "NUMBER, value=%d", tkn->value.number);
+ break;
+
+ case V_NUM_REAL:
+ avrdude_message(MSG_INFO, "NUMBER, value=%g", tkn->value.number_real);
+ break;
+
+ case V_STR:
+ avrdude_message(MSG_INFO, "STRING, value=%s", tkn->value.string);
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "<other>");
+ break;
+ }
+
+ avrdude_message(MSG_INFO, "\n");
+}
+
+
+void pyytext(void)
+{
+#if DEBUG
+ avrdude_message(MSG_INFO, "TOKEN: \"%s\"\n", yytext);
+#endif
+}
+
+
+char * dup_string(const char * str)
+{
+ char * s;
+
+ s = strdup(str);
+ if (s == NULL) {
+ yyerror("dup_string(): out of memory");
+ return NULL;
+ }
+
+ return s;
+}
+
+#ifdef HAVE_YYLEX_DESTROY
+/* reset lexer and free any allocated memory */
+extern int yylex_destroy(void);
+#endif
+
+int read_config(const char * file)
+{
+ FILE * f;
+ int r;
+
+ f = fopen(file, "r");
+ if (f == NULL) {
+ avrdude_message(MSG_INFO, "%s: can't open config file \"%s\": %s\n",
+ progname, file, strerror(errno));
+ return -1;
+ }
+
+ lineno = 1;
+ infile = file;
+ yyin = f;
+
+ r = yyparse();
+
+#ifdef HAVE_YYLEX_DESTROY
+ /* reset lexer and free any allocated memory */
+ yylex_destroy();
+#endif
+
+ fclose(f);
+
+ return r;
+}
diff --git a/xs/src/avrdude/config.h b/xs/src/avrdude/config.h
new file mode 100644
index 000000000..d0d65ae20
--- /dev/null
+++ b/xs/src/avrdude/config.h
@@ -0,0 +1,103 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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$ */
+
+/* These are the internal definitions needed for config parsing */
+
+#ifndef config_h
+#define config_h
+
+#include "libavrdude.h"
+
+
+#define MAX_STR_CONST 1024
+
+enum { V_NONE, V_NUM, V_NUM_REAL, V_STR };
+typedef struct value_t {
+ int type;
+ /*union { TODO: use an anonymous union here ? */
+ int number;
+ double number_real;
+ char * string;
+ /*};*/
+} VALUE;
+
+
+typedef struct token_t {
+ int primary;
+ VALUE value;
+} TOKEN;
+typedef struct token_t *token_p;
+
+
+extern FILE * yyin;
+extern PROGRAMMER * current_prog;
+extern AVRPART * current_part;
+extern AVRMEM * current_mem;
+extern int lineno;
+extern const char * infile;
+extern LISTID string_list;
+extern LISTID number_list;
+
+
+#if !defined(HAS_YYSTYPE)
+#define YYSTYPE token_p
+#endif
+extern YYSTYPE yylval;
+
+extern char string_buf[MAX_STR_CONST];
+extern char *string_buf_ptr;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int yyparse(void);
+
+int yyerror(char * errmsg, ...);
+
+int yywarning(char * errmsg, ...);
+
+TOKEN * new_token(int primary);
+
+void free_token(TOKEN * tkn);
+
+void free_tokens(int n, ...);
+
+TOKEN * number(char * text);
+
+TOKEN * number_real(char * text);
+
+TOKEN * hexnumber(char * text);
+
+TOKEN * string(char * text);
+
+TOKEN * keyword(int primary);
+
+void print_token(TOKEN * tkn);
+
+void pyytext(void);
+
+char * dup_string(const char * str);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/xs/src/avrdude/config_gram.c b/xs/src/avrdude/config_gram.c
new file mode 100644
index 000000000..c1a65b13e
--- /dev/null
+++ b/xs/src/avrdude/config_gram.c
@@ -0,0 +1,3718 @@
+/* A Bison parser, made by GNU Bison 3.0.4. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+ 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 3 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/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "3.0.4"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 21 "config_gram.y" /* yacc.c:339 */
+
+
+#include "ac_cfg.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+#include "config.h"
+
+#if defined(WIN32NATIVE)
+#define strtok_r( _s, _sep, _lasts ) \
+ ( *(_lasts) = strtok( (_s), (_sep) ) )
+#endif
+
+#define STRINGIFY(x) #x
+#define TOSTRING(x) STRINGIFY(x)
+
+int yylex(void);
+int yyerror(char * errmsg, ...);
+int yywarning(char * errmsg, ...);
+
+static int assign_pin(int pinno, TOKEN * v, int invert);
+static int assign_pin_list(int invert);
+static int which_opcode(TOKEN * opcode);
+static int parse_cmdbits(OPCODE * op);
+
+static int pin_name;
+
+#line 98 "config_gram.c" /* yacc.c:339 */
+
+# ifndef YY_NULLPTR
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* In a future release of Bison, this section will be replaced
+ by #include "y.tab.h". */
+#ifndef YY_YY_CONFIG_GRAM_H_INCLUDED
+# define YY_YY_CONFIG_GRAM_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token type. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ K_READ = 258,
+ K_WRITE = 259,
+ K_READ_LO = 260,
+ K_READ_HI = 261,
+ K_WRITE_LO = 262,
+ K_WRITE_HI = 263,
+ K_LOADPAGE_LO = 264,
+ K_LOADPAGE_HI = 265,
+ K_LOAD_EXT_ADDR = 266,
+ K_WRITEPAGE = 267,
+ K_CHIP_ERASE = 268,
+ K_PGM_ENABLE = 269,
+ K_MEMORY = 270,
+ K_PAGE_SIZE = 271,
+ K_PAGED = 272,
+ K_BAUDRATE = 273,
+ K_BS2 = 274,
+ K_BUFF = 275,
+ K_CHIP_ERASE_DELAY = 276,
+ K_CONNTYPE = 277,
+ K_DEDICATED = 278,
+ K_DEFAULT_BITCLOCK = 279,
+ K_DEFAULT_PARALLEL = 280,
+ K_DEFAULT_PROGRAMMER = 281,
+ K_DEFAULT_SAFEMODE = 282,
+ K_DEFAULT_SERIAL = 283,
+ K_DESC = 284,
+ K_DEVICECODE = 285,
+ K_STK500_DEVCODE = 286,
+ K_AVR910_DEVCODE = 287,
+ K_EEPROM = 288,
+ K_ERRLED = 289,
+ K_FLASH = 290,
+ K_ID = 291,
+ K_IO = 292,
+ K_LOADPAGE = 293,
+ K_MAX_WRITE_DELAY = 294,
+ K_MCU_BASE = 295,
+ K_MIN_WRITE_DELAY = 296,
+ K_MISO = 297,
+ K_MOSI = 298,
+ K_NUM_PAGES = 299,
+ K_NVM_BASE = 300,
+ K_OCDREV = 301,
+ K_OFFSET = 302,
+ K_PAGEL = 303,
+ K_PARALLEL = 304,
+ K_PARENT = 305,
+ K_PART = 306,
+ K_PGMLED = 307,
+ K_PROGRAMMER = 308,
+ K_PSEUDO = 309,
+ K_PWROFF_AFTER_WRITE = 310,
+ K_RDYLED = 311,
+ K_READBACK_P1 = 312,
+ K_READBACK_P2 = 313,
+ K_READMEM = 314,
+ K_RESET = 315,
+ K_RETRY_PULSE = 316,
+ K_SERIAL = 317,
+ K_SCK = 318,
+ K_SIGNATURE = 319,
+ K_SIZE = 320,
+ K_USB = 321,
+ K_USBDEV = 322,
+ K_USBSN = 323,
+ K_USBPID = 324,
+ K_USBPRODUCT = 325,
+ K_USBVENDOR = 326,
+ K_USBVID = 327,
+ K_TYPE = 328,
+ K_VCC = 329,
+ K_VFYLED = 330,
+ K_NO = 331,
+ K_YES = 332,
+ K_TIMEOUT = 333,
+ K_STABDELAY = 334,
+ K_CMDEXEDELAY = 335,
+ K_HVSPCMDEXEDELAY = 336,
+ K_SYNCHLOOPS = 337,
+ K_BYTEDELAY = 338,
+ K_POLLVALUE = 339,
+ K_POLLINDEX = 340,
+ K_PREDELAY = 341,
+ K_POSTDELAY = 342,
+ K_POLLMETHOD = 343,
+ K_MODE = 344,
+ K_DELAY = 345,
+ K_BLOCKSIZE = 346,
+ K_READSIZE = 347,
+ K_HVENTERSTABDELAY = 348,
+ K_PROGMODEDELAY = 349,
+ K_LATCHCYCLES = 350,
+ K_TOGGLEVTG = 351,
+ K_POWEROFFDELAY = 352,
+ K_RESETDELAYMS = 353,
+ K_RESETDELAYUS = 354,
+ K_HVLEAVESTABDELAY = 355,
+ K_RESETDELAY = 356,
+ K_SYNCHCYCLES = 357,
+ K_HVCMDEXEDELAY = 358,
+ K_CHIPERASEPULSEWIDTH = 359,
+ K_CHIPERASEPOLLTIMEOUT = 360,
+ K_CHIPERASETIME = 361,
+ K_PROGRAMFUSEPULSEWIDTH = 362,
+ K_PROGRAMFUSEPOLLTIMEOUT = 363,
+ K_PROGRAMLOCKPULSEWIDTH = 364,
+ K_PROGRAMLOCKPOLLTIMEOUT = 365,
+ K_PP_CONTROLSTACK = 366,
+ K_HVSP_CONTROLSTACK = 367,
+ K_ALLOWFULLPAGEBITSTREAM = 368,
+ K_ENABLEPAGEPROGRAMMING = 369,
+ K_HAS_JTAG = 370,
+ K_HAS_DW = 371,
+ K_HAS_PDI = 372,
+ K_HAS_TPI = 373,
+ K_IDR = 374,
+ K_IS_AT90S1200 = 375,
+ K_IS_AVR32 = 376,
+ K_RAMPZ = 377,
+ K_SPMCR = 378,
+ K_EECR = 379,
+ K_FLASH_INSTR = 380,
+ K_EEPROM_INSTR = 381,
+ TKN_COMMA = 382,
+ TKN_EQUAL = 383,
+ TKN_SEMI = 384,
+ TKN_TILDE = 385,
+ TKN_LEFT_PAREN = 386,
+ TKN_RIGHT_PAREN = 387,
+ TKN_NUMBER = 388,
+ TKN_NUMBER_REAL = 389,
+ TKN_STRING = 390
+ };
+#endif
+/* Tokens. */
+#define K_READ 258
+#define K_WRITE 259
+#define K_READ_LO 260
+#define K_READ_HI 261
+#define K_WRITE_LO 262
+#define K_WRITE_HI 263
+#define K_LOADPAGE_LO 264
+#define K_LOADPAGE_HI 265
+#define K_LOAD_EXT_ADDR 266
+#define K_WRITEPAGE 267
+#define K_CHIP_ERASE 268
+#define K_PGM_ENABLE 269
+#define K_MEMORY 270
+#define K_PAGE_SIZE 271
+#define K_PAGED 272
+#define K_BAUDRATE 273
+#define K_BS2 274
+#define K_BUFF 275
+#define K_CHIP_ERASE_DELAY 276
+#define K_CONNTYPE 277
+#define K_DEDICATED 278
+#define K_DEFAULT_BITCLOCK 279
+#define K_DEFAULT_PARALLEL 280
+#define K_DEFAULT_PROGRAMMER 281
+#define K_DEFAULT_SAFEMODE 282
+#define K_DEFAULT_SERIAL 283
+#define K_DESC 284
+#define K_DEVICECODE 285
+#define K_STK500_DEVCODE 286
+#define K_AVR910_DEVCODE 287
+#define K_EEPROM 288
+#define K_ERRLED 289
+#define K_FLASH 290
+#define K_ID 291
+#define K_IO 292
+#define K_LOADPAGE 293
+#define K_MAX_WRITE_DELAY 294
+#define K_MCU_BASE 295
+#define K_MIN_WRITE_DELAY 296
+#define K_MISO 297
+#define K_MOSI 298
+#define K_NUM_PAGES 299
+#define K_NVM_BASE 300
+#define K_OCDREV 301
+#define K_OFFSET 302
+#define K_PAGEL 303
+#define K_PARALLEL 304
+#define K_PARENT 305
+#define K_PART 306
+#define K_PGMLED 307
+#define K_PROGRAMMER 308
+#define K_PSEUDO 309
+#define K_PWROFF_AFTER_WRITE 310
+#define K_RDYLED 311
+#define K_READBACK_P1 312
+#define K_READBACK_P2 313
+#define K_READMEM 314
+#define K_RESET 315
+#define K_RETRY_PULSE 316
+#define K_SERIAL 317
+#define K_SCK 318
+#define K_SIGNATURE 319
+#define K_SIZE 320
+#define K_USB 321
+#define K_USBDEV 322
+#define K_USBSN 323
+#define K_USBPID 324
+#define K_USBPRODUCT 325
+#define K_USBVENDOR 326
+#define K_USBVID 327
+#define K_TYPE 328
+#define K_VCC 329
+#define K_VFYLED 330
+#define K_NO 331
+#define K_YES 332
+#define K_TIMEOUT 333
+#define K_STABDELAY 334
+#define K_CMDEXEDELAY 335
+#define K_HVSPCMDEXEDELAY 336
+#define K_SYNCHLOOPS 337
+#define K_BYTEDELAY 338
+#define K_POLLVALUE 339
+#define K_POLLINDEX 340
+#define K_PREDELAY 341
+#define K_POSTDELAY 342
+#define K_POLLMETHOD 343
+#define K_MODE 344
+#define K_DELAY 345
+#define K_BLOCKSIZE 346
+#define K_READSIZE 347
+#define K_HVENTERSTABDELAY 348
+#define K_PROGMODEDELAY 349
+#define K_LATCHCYCLES 350
+#define K_TOGGLEVTG 351
+#define K_POWEROFFDELAY 352
+#define K_RESETDELAYMS 353
+#define K_RESETDELAYUS 354
+#define K_HVLEAVESTABDELAY 355
+#define K_RESETDELAY 356
+#define K_SYNCHCYCLES 357
+#define K_HVCMDEXEDELAY 358
+#define K_CHIPERASEPULSEWIDTH 359
+#define K_CHIPERASEPOLLTIMEOUT 360
+#define K_CHIPERASETIME 361
+#define K_PROGRAMFUSEPULSEWIDTH 362
+#define K_PROGRAMFUSEPOLLTIMEOUT 363
+#define K_PROGRAMLOCKPULSEWIDTH 364
+#define K_PROGRAMLOCKPOLLTIMEOUT 365
+#define K_PP_CONTROLSTACK 366
+#define K_HVSP_CONTROLSTACK 367
+#define K_ALLOWFULLPAGEBITSTREAM 368
+#define K_ENABLEPAGEPROGRAMMING 369
+#define K_HAS_JTAG 370
+#define K_HAS_DW 371
+#define K_HAS_PDI 372
+#define K_HAS_TPI 373
+#define K_IDR 374
+#define K_IS_AT90S1200 375
+#define K_IS_AVR32 376
+#define K_RAMPZ 377
+#define K_SPMCR 378
+#define K_EECR 379
+#define K_FLASH_INSTR 380
+#define K_EEPROM_INSTR 381
+#define TKN_COMMA 382
+#define TKN_EQUAL 383
+#define TKN_SEMI 384
+#define TKN_TILDE 385
+#define TKN_LEFT_PAREN 386
+#define TKN_RIGHT_PAREN 387
+#define TKN_NUMBER 388
+#define TKN_NUMBER_REAL 389
+#define TKN_STRING 390
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef int YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+int yyparse (void);
+
+#endif /* !YY_YY_CONFIG_GRAM_H_INCLUDED */
+
+/* Copy the second part of user declarations. */
+
+#line 419 "config_gram.c" /* yacc.c:358 */
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE
+# if (defined __GNUC__ \
+ && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
+ || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
+# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
+# else
+# define YY_ATTRIBUTE(Spec) /* empty */
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
+#endif
+
+#if !defined _Noreturn \
+ && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
+# if defined _MSC_VER && 1200 <= _MSC_VER
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(E) ((void) (E))
+#else
+# define YYUSE(E) /* empty */
+#endif
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined EXIT_SUCCESS \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined EXIT_SUCCESS
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined EXIT_SUCCESS
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 22
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 401
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 136
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 45
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 182
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 418
+
+/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
+ by yylex, with out-of-bounds checking. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 390
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, without out-of-bounds checking. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135
+};
+
+#if YYDEBUG
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 211, 211, 217, 221, 222, 226, 227, 232, 234,
+ 236, 242, 248, 254, 259, 270, 303, 313, 335, 393,
+ 403, 426, 427, 432, 433, 437, 438, 442, 465, 467,
+ 469, 471, 473, 478, 487, 491, 501, 509, 513, 514,
+ 515, 519, 526, 532, 533, 540, 547, 557, 572, 585,
+ 587, 591, 593, 597, 599, 603, 605, 610, 612, 616,
+ 616, 617, 617, 618, 618, 619, 619, 620, 620, 621,
+ 621, 622, 622, 623, 623, 624, 624, 625, 625, 629,
+ 630, 631, 632, 633, 634, 635, 636, 637, 638, 639,
+ 640, 645, 646, 651, 651, 655, 655, 659, 659, 663,
+ 670, 677, 685, 692, 699, 710, 717, 748, 779, 809,
+ 839, 845, 851, 857, 867, 873, 879, 885, 891, 897,
+ 903, 909, 915, 921, 927, 933, 939, 945, 951, 957,
+ 963, 969, 975, 981, 987, 993, 999, 1005, 1011, 1017,
+ 1023, 1029, 1035, 1045, 1055, 1065, 1075, 1085, 1095, 1105,
+ 1115, 1121, 1127, 1133, 1139, 1145, 1151, 1157, 1167, 1186,
+ 1210, 1209, 1234, 1261, 1261, 1266, 1267, 1272, 1278, 1285,
+ 1291, 1297, 1303, 1309, 1315, 1321, 1327, 1334, 1340, 1346,
+ 1352, 1358, 1365
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 0
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "K_READ", "K_WRITE", "K_READ_LO",
+ "K_READ_HI", "K_WRITE_LO", "K_WRITE_HI", "K_LOADPAGE_LO",
+ "K_LOADPAGE_HI", "K_LOAD_EXT_ADDR", "K_WRITEPAGE", "K_CHIP_ERASE",
+ "K_PGM_ENABLE", "K_MEMORY", "K_PAGE_SIZE", "K_PAGED", "K_BAUDRATE",
+ "K_BS2", "K_BUFF", "K_CHIP_ERASE_DELAY", "K_CONNTYPE", "K_DEDICATED",
+ "K_DEFAULT_BITCLOCK", "K_DEFAULT_PARALLEL", "K_DEFAULT_PROGRAMMER",
+ "K_DEFAULT_SAFEMODE", "K_DEFAULT_SERIAL", "K_DESC", "K_DEVICECODE",
+ "K_STK500_DEVCODE", "K_AVR910_DEVCODE", "K_EEPROM", "K_ERRLED",
+ "K_FLASH", "K_ID", "K_IO", "K_LOADPAGE", "K_MAX_WRITE_DELAY",
+ "K_MCU_BASE", "K_MIN_WRITE_DELAY", "K_MISO", "K_MOSI", "K_NUM_PAGES",
+ "K_NVM_BASE", "K_OCDREV", "K_OFFSET", "K_PAGEL", "K_PARALLEL",
+ "K_PARENT", "K_PART", "K_PGMLED", "K_PROGRAMMER", "K_PSEUDO",
+ "K_PWROFF_AFTER_WRITE", "K_RDYLED", "K_READBACK_P1", "K_READBACK_P2",
+ "K_READMEM", "K_RESET", "K_RETRY_PULSE", "K_SERIAL", "K_SCK",
+ "K_SIGNATURE", "K_SIZE", "K_USB", "K_USBDEV", "K_USBSN", "K_USBPID",
+ "K_USBPRODUCT", "K_USBVENDOR", "K_USBVID", "K_TYPE", "K_VCC", "K_VFYLED",
+ "K_NO", "K_YES", "K_TIMEOUT", "K_STABDELAY", "K_CMDEXEDELAY",
+ "K_HVSPCMDEXEDELAY", "K_SYNCHLOOPS", "K_BYTEDELAY", "K_POLLVALUE",
+ "K_POLLINDEX", "K_PREDELAY", "K_POSTDELAY", "K_POLLMETHOD", "K_MODE",
+ "K_DELAY", "K_BLOCKSIZE", "K_READSIZE", "K_HVENTERSTABDELAY",
+ "K_PROGMODEDELAY", "K_LATCHCYCLES", "K_TOGGLEVTG", "K_POWEROFFDELAY",
+ "K_RESETDELAYMS", "K_RESETDELAYUS", "K_HVLEAVESTABDELAY", "K_RESETDELAY",
+ "K_SYNCHCYCLES", "K_HVCMDEXEDELAY", "K_CHIPERASEPULSEWIDTH",
+ "K_CHIPERASEPOLLTIMEOUT", "K_CHIPERASETIME", "K_PROGRAMFUSEPULSEWIDTH",
+ "K_PROGRAMFUSEPOLLTIMEOUT", "K_PROGRAMLOCKPULSEWIDTH",
+ "K_PROGRAMLOCKPOLLTIMEOUT", "K_PP_CONTROLSTACK", "K_HVSP_CONTROLSTACK",
+ "K_ALLOWFULLPAGEBITSTREAM", "K_ENABLEPAGEPROGRAMMING", "K_HAS_JTAG",
+ "K_HAS_DW", "K_HAS_PDI", "K_HAS_TPI", "K_IDR", "K_IS_AT90S1200",
+ "K_IS_AVR32", "K_RAMPZ", "K_SPMCR", "K_EECR", "K_FLASH_INSTR",
+ "K_EEPROM_INSTR", "TKN_COMMA", "TKN_EQUAL", "TKN_SEMI", "TKN_TILDE",
+ "TKN_LEFT_PAREN", "TKN_RIGHT_PAREN", "TKN_NUMBER", "TKN_NUMBER_REAL",
+ "TKN_STRING", "$accept", "number_real", "configuration", "config", "def",
+ "prog_def", "prog_decl", "part_def", "part_decl", "string_list",
+ "num_list", "prog_parms", "prog_parm", "prog_parm_type",
+ "prog_parm_type_id", "prog_parm_conntype", "prog_parm_conntype_id",
+ "prog_parm_usb", "usb_pid_list", "pin_number_non_empty", "pin_number",
+ "pin_list_element", "pin_list_non_empty", "pin_list", "prog_parm_pins",
+ "$@1", "$@2", "$@3", "$@4", "$@5", "$@6", "$@7", "$@8", "$@9", "$@10",
+ "opcode", "part_parms", "reset_disposition", "parallel_modes",
+ "retry_lines", "part_parm", "$@11", "yesno", "mem_specs", "mem_spec", YY_NULLPTR
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[NUM] -- (External) token number corresponding to the
+ (internal) symbol number NUM (which must be that of a token). */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+ 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
+ 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
+ 385, 386, 387, 388, 389, 390
+};
+# endif
+
+#define YYPACT_NINF -258
+
+#define yypact_value_is_default(Yystate) \
+ (!!((Yystate) == (-258)))
+
+#define YYTABLE_NINF -1
+
+#define yytable_value_is_error(Yytable_value) \
+ 0
+
+ /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int16 yypact[] =
+{
+ 23, -119, -83, -82, -68, -50, 2, 31, 82, 23,
+ -258, -39, 55, -37, 166, -99, -42, -41, -63, -40,
+ -35, -34, -258, -258, -258, -43, -32, -26, -20, -19,
+ -18, -15, -14, -12, -11, -9, -8, -7, 3, 5,
+ 6, 7, 8, 9, 10, 12, 55, 13, -258, -258,
+ -258, -258, -258, -258, -258, -258, -258, -258, -258, -258,
+ -258, -258, -258, -258, -258, -3, 15, 17, 18, 20,
+ 22, 24, 25, 26, 27, 28, 29, 30, 32, 33,
+ 34, 35, 37, 38, 39, 54, 56, 58, 60, 61,
+ 62, 63, 64, 65, 66, 71, 72, 73, 76, 77,
+ 79, 81, 85, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 101, 103, 104, 105, 106, 108, 109,
+ 110, 111, 112, 113, 114, 115, 127, 128, 166, 129,
+ -258, -258, 140, 164, 165, -258, -258, 167, 168, -258,
+ -258, 16, -258, 21, 48, -258, 75, -258, -258, -258,
+ -258, -258, -258, 122, 160, 169, 163, 170, 171, 4,
+ -258, -258, 172, -258, -258, 173, 174, 175, 176, 178,
+ 179, 180, 181, 183, 184, 185, -44, 19, -52, -63,
+ 186, 187, 188, 189, 190, 191, 192, 193, 194, 195,
+ 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
+ 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
+ 216, 216, -63, -63, -63, -63, -63, -63, 217, -63,
+ -63, 218, 219, 220, 216, 216, 75, 225, -258, -258,
+ -258, -258, -258, -258, -258, -76, -258, -258, -258, -258,
+ -258, -71, -258, 228, -71, -71, -71, -71, -71, -71,
+ -258, -258, -258, 229, -258, -258, -258, -258, -258, -258,
+ -76, -71, -258, 14, -258, -258, -258, -258, -258, -258,
+ -258, -258, -258, -258, -258, -258, -258, -258, -258, -258,
+ -258, -258, -258, -258, -258, 224, -258, -258, -258, -258,
+ -258, -258, -258, -258, -258, -258, -258, -258, -258, -258,
+ -258, -258, -258, -258, -258, -258, -258, -258, -258, -258,
+ -258, -258, -258, -258, -258, -258, 231, 231, -258, -258,
+ -258, -258, -258, -258, -258, -258, -258, -258, -258, -258,
+ 231, 231, 228, -258, -45, -258, -258, -258, 232, -258,
+ 227, -258, -258, 226, -258, -258, -258, -258, -258, -258,
+ 230, -258, -258, 234, 236, 237, 238, 239, 240, 241,
+ 242, 243, 244, 245, 246, 247, 248, 249, 250, 14,
+ 251, 252, 253, 216, -258, -76, -258, -258, 254, -63,
+ 255, 256, 257, 258, -63, 259, 260, 261, 262, 263,
+ 264, 265, 266, 75, 271, -258, -258, -258, -120, -258,
+ -258, -258, -258, -258, -258, -258, -258, -258, -258, -258,
+ -258, -258, -258, -258, -258, 228, -258, -258
+};
+
+ /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 4, 0, 0, 0, 0, 0, 19, 16, 0, 5,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 7, 8, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 15, 0, 28, 31,
+ 30, 29, 9, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 18, 0,
+ 2, 3, 0, 0, 0, 164, 163, 0, 0, 20,
+ 17, 0, 61, 0, 0, 71, 0, 69, 67, 75,
+ 73, 63, 65, 0, 0, 0, 0, 0, 0, 0,
+ 59, 77, 0, 25, 160, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 91, 13,
+ 11, 10, 14, 12, 33, 58, 38, 39, 40, 37,
+ 32, 52, 21, 27, 52, 52, 52, 52, 52, 52,
+ 41, 44, 47, 43, 46, 45, 42, 36, 35, 34,
+ 58, 52, 26, 0, 112, 110, 100, 101, 102, 103,
+ 99, 154, 155, 156, 111, 96, 158, 95, 93, 94,
+ 113, 97, 98, 159, 157, 0, 105, 114, 115, 116,
+ 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
+ 127, 128, 129, 130, 131, 132, 133, 141, 134, 135,
+ 136, 137, 138, 139, 140, 23, 106, 107, 148, 149,
+ 142, 143, 144, 145, 150, 146, 147, 151, 152, 153,
+ 108, 109, 162, 92, 0, 49, 53, 55, 57, 62,
+ 0, 51, 72, 0, 70, 68, 76, 74, 64, 66,
+ 0, 60, 78, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 161,
+ 0, 0, 0, 0, 50, 0, 22, 48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 165, 104, 24, 0, 56,
+ 169, 167, 173, 172, 170, 171, 174, 175, 176, 168,
+ 181, 177, 178, 179, 180, 182, 166, 54
+};
+
+ /* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -258, -258, -258, -258, 132, -258, -258, -258, -258, -225,
+ -209, -258, 267, -258, -258, -258, -258, -258, -258, -231,
+ -181, -228, -258, -109, -258, -258, -258, -258, -258, -258,
+ -258, -258, -258, -258, -258, -257, -258, -258, -258, -258,
+ 273, -258, -176, -258, -210
+};
+
+ /* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 132, 8, 9, 10, 11, 12, 13, 14, 243,
+ 316, 46, 47, 48, 259, 49, 239, 50, 253, 341,
+ 342, 337, 338, 339, 51, 260, 235, 248, 249, 245,
+ 244, 241, 247, 246, 261, 127, 128, 280, 276, 283,
+ 129, 263, 137, 369, 370
+};
+
+ /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_uint16 yytable[] =
+{
+ 277, 332, 317, 284, 336, 257, 368, 372, 281, 15,
+ 275, 282, 417, 135, 136, 330, 331, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 336,
+ 353, 354, 135, 136, 130, 131, 318, 319, 320, 321,
+ 322, 323, 278, 325, 326, 16, 17, 1, 2, 3,
+ 4, 5, 20, 355, 334, 356, 279, 335, 357, 340,
+ 18, 358, 335, 344, 345, 346, 347, 348, 349, 359,
+ 236, 360, 361, 25, 6, 26, 7, 27, 19, 362,
+ 352, 21, 22, 237, 28, 141, 373, 238, 374, 29,
+ 24, 30, 52, 133, 134, 138, 142, 31, 32, 363,
+ 139, 140, 143, 364, 365, 366, 367, 33, 144, 145,
+ 146, 34, 368, 147, 148, 35, 149, 150, 36, 151,
+ 152, 153, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 154, 164, 155, 156, 157, 158, 159, 160, 258,
+ 161, 23, 163, 165, 336, 166, 167, 399, 168, 234,
+ 169, 351, 170, 171, 172, 173, 174, 175, 176, 394,
+ 177, 178, 179, 180, 398, 181, 182, 183, 415, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 184, 240, 185, 66, 186, 67, 187, 188,
+ 189, 190, 191, 192, 193, 68, 69, 70, 71, 194,
+ 195, 196, 72, 401, 197, 198, 73, 199, 406, 200,
+ 242, 74, 75, 201, 76, 77, 202, 203, 204, 205,
+ 206, 207, 208, 209, 210, 211, 78, 79, 80, 212,
+ 81, 213, 214, 215, 216, 82, 217, 218, 219, 220,
+ 221, 222, 223, 224, 83, 84, 85, 86, 87, 88,
+ 89, 90, 91, 92, 93, 225, 226, 250, 228, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 229,
+ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
+ 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+ 124, 125, 126, 230, 231, 251, 232, 233, 254, 0,
+ 0, 262, 252, 0, 256, 255, 264, 265, 0, 267,
+ 266, 268, 269, 162, 271, 270, 272, 273, 274, 285,
+ 286, 287, 288, 289, 290, 291, 292, 293, 294, 295,
+ 296, 297, 298, 299, 300, 301, 302, 303, 304, 305,
+ 306, 307, 308, 309, 310, 311, 312, 313, 314, 315,
+ 324, 327, 328, 329, 333, 343, 350, 371, 372, 375,
+ 374, 376, 378, 377, 379, 380, 381, 382, 383, 384,
+ 385, 386, 387, 388, 389, 390, 391, 392, 393, 0,
+ 395, 0, 0, 0, 0, 396, 397, 400, 402, 403,
+ 404, 405, 407, 408, 409, 410, 411, 412, 413, 414,
+ 416, 227
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 176, 226, 211, 179, 235, 1, 263, 127, 60, 128,
+ 54, 63, 132, 76, 77, 224, 225, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 260,
+ 16, 17, 76, 77, 133, 134, 212, 213, 214, 215,
+ 216, 217, 23, 219, 220, 128, 128, 24, 25, 26,
+ 27, 28, 50, 39, 130, 41, 37, 133, 44, 130,
+ 128, 47, 133, 244, 245, 246, 247, 248, 249, 55,
+ 49, 57, 58, 18, 51, 20, 53, 22, 128, 65,
+ 261, 50, 0, 62, 29, 128, 131, 66, 133, 34,
+ 129, 36, 129, 135, 135, 135, 128, 42, 43, 85,
+ 135, 135, 128, 89, 90, 91, 92, 52, 128, 128,
+ 128, 56, 369, 128, 128, 60, 128, 128, 63, 128,
+ 128, 128, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 128, 135, 128, 128, 128, 128, 128, 128, 135,
+ 128, 9, 129, 128, 375, 128, 128, 375, 128, 133,
+ 128, 260, 128, 128, 128, 128, 128, 128, 128, 369,
+ 128, 128, 128, 128, 373, 128, 128, 128, 393, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 128, 135, 128, 19, 128, 21, 128, 128,
+ 128, 128, 128, 128, 128, 29, 30, 31, 32, 128,
+ 128, 128, 36, 379, 128, 128, 40, 128, 384, 128,
+ 135, 45, 46, 128, 48, 49, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 60, 61, 62, 128,
+ 64, 128, 128, 128, 128, 69, 128, 128, 128, 128,
+ 128, 128, 128, 128, 78, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, 88, 128, 128, 135, 129, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 129,
+ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
+ 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+ 124, 125, 126, 129, 129, 135, 129, 129, 135, -1,
+ -1, 129, 133, -1, 133, 135, 133, 133, -1, 133,
+ 135, 133, 133, 46, 133, 135, 133, 133, 133, 133,
+ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
+ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
+ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
+ 133, 133, 133, 133, 129, 127, 127, 133, 127, 127,
+ 133, 135, 128, 133, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, -1,
+ 129, -1, -1, -1, -1, 133, 133, 133, 133, 133,
+ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
+ 129, 128
+};
+
+ /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 24, 25, 26, 27, 28, 51, 53, 138, 139,
+ 140, 141, 142, 143, 144, 128, 128, 128, 128, 128,
+ 50, 50, 0, 140, 129, 18, 20, 22, 29, 34,
+ 36, 42, 43, 52, 56, 60, 63, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 147, 148, 149, 151,
+ 153, 160, 129, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 19, 21, 29, 30,
+ 31, 32, 36, 40, 45, 46, 48, 49, 60, 61,
+ 62, 64, 69, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 93, 94, 95, 96, 97, 98,
+ 99, 100, 101, 102, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 171, 172, 176,
+ 133, 134, 137, 135, 135, 76, 77, 178, 135, 135,
+ 135, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 148, 129, 135, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 176, 129, 129,
+ 129, 129, 129, 129, 133, 162, 49, 62, 66, 152,
+ 135, 167, 135, 145, 166, 165, 169, 168, 163, 164,
+ 135, 135, 133, 154, 135, 135, 133, 1, 135, 150,
+ 161, 170, 129, 177, 133, 133, 135, 133, 133, 133,
+ 135, 133, 133, 133, 133, 54, 174, 178, 23, 37,
+ 173, 60, 63, 175, 178, 133, 133, 133, 133, 133,
+ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
+ 133, 133, 133, 133, 133, 133, 133, 133, 133, 133,
+ 133, 133, 133, 133, 133, 133, 146, 146, 178, 178,
+ 178, 178, 178, 178, 133, 178, 178, 133, 133, 133,
+ 146, 146, 145, 129, 130, 133, 155, 157, 158, 159,
+ 130, 155, 156, 127, 156, 156, 156, 156, 156, 156,
+ 127, 159, 156, 16, 17, 39, 41, 44, 47, 55,
+ 57, 58, 65, 85, 89, 90, 91, 92, 171, 179,
+ 180, 133, 127, 131, 133, 127, 135, 133, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 180, 129, 133, 133, 146, 157,
+ 133, 178, 133, 133, 133, 133, 178, 133, 133, 133,
+ 133, 133, 133, 133, 133, 145, 129, 132
+};
+
+ /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 136, 137, 137, 138, 138, 139, 139, 140, 140,
+ 140, 140, 140, 140, 140, 141, 142, 142, 143, 144,
+ 144, 145, 145, 146, 146, 147, 147, 148, 148, 148,
+ 148, 148, 148, 148, 149, 150, 150, 151, 152, 152,
+ 152, 153, 153, 153, 153, 153, 153, 154, 154, 155,
+ 155, 156, 156, 157, 157, 158, 158, 159, 159, 161,
+ 160, 162, 160, 163, 160, 164, 160, 165, 160, 166,
+ 160, 167, 160, 168, 160, 169, 160, 170, 160, 171,
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+ 171, 172, 172, 173, 173, 174, 174, 175, 175, 176,
+ 176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
+ 176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
+ 176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
+ 176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
+ 176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
+ 176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
+ 177, 176, 176, 178, 178, 179, 179, 180, 180, 180,
+ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180
+};
+
+ /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 1, 0, 1, 1, 2, 2, 2,
+ 4, 4, 4, 4, 4, 2, 1, 3, 2, 1,
+ 3, 1, 3, 1, 3, 2, 3, 3, 1, 1,
+ 1, 1, 3, 3, 3, 1, 1, 3, 1, 1,
+ 1, 3, 3, 3, 3, 3, 3, 1, 3, 1,
+ 2, 1, 0, 1, 4, 1, 3, 1, 0, 0,
+ 4, 0, 4, 0, 4, 0, 4, 0, 4, 0,
+ 4, 0, 4, 0, 4, 0, 4, 0, 4, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 3, 1, 1, 1, 1, 1, 1, 3,
+ 3, 3, 3, 3, 5, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 0, 4, 3, 1, 1, 2, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3
+};
+
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (0)
+
+/* Error token number */
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+/* This macro is provided for backward compatibility. */
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+
+/*----------------------------------------.
+| Print this symbol's value on YYOUTPUT. |
+`----------------------------------------*/
+
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ YYUSE (yytype);
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+{
+ YYFPRINTF (yyoutput, "%s %s (",
+ yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void
+yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
+{
+ unsigned long int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr,
+ yystos[yyssp[yyi + 1 - yynrhs]],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyssp, yyvsp, Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+yystrlen (const char *yystr)
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+ about the unexpected token YYTOKEN for the state stack whose top is
+ YYSSP.
+
+ Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
+ not large enough to hold the message. In that case, also set
+ *YYMSG_ALLOC to the required number of bytes. Return 2 if the
+ required number of bytes is too large to store. */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ yytype_int16 *yyssp, int yytoken)
+{
+ YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
+ YYSIZE_T yysize = yysize0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ /* Internationalized format string. */
+ const char *yyformat = YY_NULLPTR;
+ /* Arguments of yyformat. */
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ /* Number of reported tokens (one for the "unexpected", one per
+ "expected"). */
+ int yycount = 0;
+
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action, then
+ the only way this function was invoked is if the default action
+ is an error action. In that case, don't check for expected
+ tokens because there are none.
+ - The only way there can be no lookahead present (in yychar) is if
+ this state is a consistent state with a default action. Thus,
+ detecting the absence of a lookahead is sufficient to determine
+ that there is no unexpected or expected token to report. In that
+ case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this state is a
+ consistent state with a default action. There might have been a
+ previous inconsistent state, consistent state with a non-default
+ action, or user semantic action that manipulated yychar.
+ - Of course, the expected token list depends on states to have
+ correct lookahead information, and it depends on the parser not
+ to perform extra reductions after fetching a lookahead from the
+ scanner and before detecting a syntax error. Thus, state merging
+ (from LALR or IELR) and default reductions corrupt the expected
+ token list. However, the list is correct for canonical LR with
+ one exception: it will still contain any token that will not be
+ accepted due to an error action in a later state.
+ */
+ if (yytoken != YYEMPTY)
+ {
+ int yyn = yypact[*yyssp];
+ yyarg[yycount++] = yytname[yytoken];
+ if (!yypact_value_is_default (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. In other words, skip the first -YYN actions for
+ this state because they are default actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yyx;
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+ && !yytable_value_is_error (yytable[yyx + yyn]))
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ {
+ YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
+ if (! (yysize <= yysize1
+ && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+ }
+ }
+ }
+
+ switch (yycount)
+ {
+# define YYCASE_(N, S) \
+ case N: \
+ yyformat = S; \
+ break
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+ YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+ YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+ YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+ }
+
+ {
+ YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+ if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+ return 2;
+ yysize = yysize1;
+ }
+
+ if (*yymsg_alloc < yysize)
+ {
+ *yymsg_alloc = 2 * yysize;
+ if (! (yysize <= *yymsg_alloc
+ && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+ *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+ return 1;
+ }
+
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ {
+ char *yyp = *yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyformat) != '\0')
+ if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyformat += 2;
+ }
+ else
+ {
+ yyp++;
+ yyformat++;
+ }
+ }
+ return 0;
+}
+#endif /* YYERROR_VERBOSE */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+{
+ YYUSE (yyvaluep);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int
+yyparse (void)
+{
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ 'yyss': related to states.
+ 'yyvs': related to semantic values.
+
+ Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yyssp = yyss = yyssa;
+ yyvsp = yyvs = yyvsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default (yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = yylex ();
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error (yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+#line 211 "config_gram.y" /* yacc.c:1646 */
+ {
+ (yyval) = (yyvsp[0]);
+ /* convert value to real */
+ (yyval)->value.number_real = (yyval)->value.number;
+ (yyval)->value.type = V_NUM_REAL;
+ }
+#line 1819 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 3:
+#line 217 "config_gram.y" /* yacc.c:1646 */
+ {
+ (yyval) = (yyvsp[0]);
+ }
+#line 1827 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 10:
+#line 236 "config_gram.y" /* yacc.c:1646 */
+ {
+ strncpy(default_programmer, (yyvsp[-1])->value.string, MAX_STR_CONST);
+ default_programmer[MAX_STR_CONST-1] = 0;
+ free_token((yyvsp[-1]));
+ }
+#line 1837 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 11:
+#line 242 "config_gram.y" /* yacc.c:1646 */
+ {
+ strncpy(default_parallel, (yyvsp[-1])->value.string, PATH_MAX);
+ default_parallel[PATH_MAX-1] = 0;
+ free_token((yyvsp[-1]));
+ }
+#line 1847 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 12:
+#line 248 "config_gram.y" /* yacc.c:1646 */
+ {
+ strncpy(default_serial, (yyvsp[-1])->value.string, PATH_MAX);
+ default_serial[PATH_MAX-1] = 0;
+ free_token((yyvsp[-1]));
+ }
+#line 1857 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 13:
+#line 254 "config_gram.y" /* yacc.c:1646 */
+ {
+ default_bitclock = (yyvsp[-1])->value.number_real;
+ free_token((yyvsp[-1]));
+ }
+#line 1866 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 14:
+#line 259 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[-1])->primary == K_YES)
+ default_safemode = 1;
+ else if ((yyvsp[-1])->primary == K_NO)
+ default_safemode = 0;
+ free_token((yyvsp[-1]));
+ }
+#line 1878 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 15:
+#line 271 "config_gram.y" /* yacc.c:1646 */
+ {
+ PROGRAMMER * existing_prog;
+ char * id;
+ if (lsize(current_prog->id) == 0) {
+ yyerror("required parameter id not specified");
+ YYABORT;
+ }
+ if (current_prog->initpgm == NULL) {
+ yyerror("programmer type not specified");
+ YYABORT;
+ }
+ id = ldata(lfirst(current_prog->id));
+ existing_prog = locate_programmer(programmers, id);
+ if (existing_prog) {
+ { /* temporarly set lineno to lineno of programmer start */
+ int temp = lineno; lineno = current_prog->lineno;
+ yywarning("programmer %s overwrites previous definition %s:%d.",
+ id, existing_prog->config_file, existing_prog->lineno);
+ lineno = temp;
+ }
+ lrmv_d(programmers, existing_prog);
+ pgm_free(existing_prog);
+ }
+ PUSH(programmers, current_prog);
+// pgm_fill_old_pins(current_prog); // TODO to be removed if old pin data no longer needed
+// pgm_display_generic(current_prog, id);
+ current_prog = NULL;
+ }
+#line 1911 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 16:
+#line 304 "config_gram.y" /* yacc.c:1646 */
+ { current_prog = pgm_new();
+ if (current_prog == NULL) {
+ yyerror("could not create pgm instance");
+ YYABORT;
+ }
+ strcpy(current_prog->config_file, infile);
+ current_prog->lineno = lineno;
+ }
+#line 1924 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 17:
+#line 314 "config_gram.y" /* yacc.c:1646 */
+ {
+ struct programmer_t * pgm = locate_programmer(programmers, (yyvsp[0])->value.string);
+ if (pgm == NULL) {
+ yyerror("parent programmer %s not found", (yyvsp[0])->value.string);
+ free_token((yyvsp[0]));
+ YYABORT;
+ }
+ current_prog = pgm_dup(pgm);
+ if (current_prog == NULL) {
+ yyerror("could not duplicate pgm instance");
+ free_token((yyvsp[0]));
+ YYABORT;
+ }
+ strcpy(current_prog->config_file, infile);
+ current_prog->lineno = lineno;
+ free_token((yyvsp[0]));
+ }
+#line 1946 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 18:
+#line 336 "config_gram.y" /* yacc.c:1646 */
+ {
+ LNODEID ln;
+ AVRMEM * m;
+ AVRPART * existing_part;
+
+ if (current_part->id[0] == 0) {
+ yyerror("required parameter id not specified");
+ YYABORT;
+ }
+
+ /*
+ * perform some sanity checking, and compute the number of bits
+ * to shift a page for constructing the page address for
+ * page-addressed memories.
+ */
+ for (ln=lfirst(current_part->mem); ln; ln=lnext(ln)) {
+ m = ldata(ln);
+ if (m->paged) {
+ if (m->page_size == 0) {
+ yyerror("must specify page_size for paged memory");
+ YYABORT;
+ }
+ if (m->num_pages == 0) {
+ yyerror("must specify num_pages for paged memory");
+ YYABORT;
+ }
+ if (m->size != m->page_size * m->num_pages) {
+ yyerror("page size (%u) * num_pages (%u) = "
+ "%u does not match memory size (%u)",
+ m->page_size,
+ m->num_pages,
+ m->page_size * m->num_pages,
+ m->size);
+ YYABORT;
+ }
+
+ }
+ }
+
+ existing_part = locate_part(part_list, current_part->id);
+ if (existing_part) {
+ { /* temporarly set lineno to lineno of part start */
+ int temp = lineno; lineno = current_part->lineno;
+ yywarning("part %s overwrites previous definition %s:%d.",
+ current_part->id,
+ existing_part->config_file, existing_part->lineno);
+ lineno = temp;
+ }
+ lrmv_d(part_list, existing_part);
+ avr_free_part(existing_part);
+ }
+ PUSH(part_list, current_part);
+ current_part = NULL;
+ }
+#line 2005 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 19:
+#line 394 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part = avr_new_part();
+ if (current_part == NULL) {
+ yyerror("could not create part instance");
+ YYABORT;
+ }
+ strcpy(current_part->config_file, infile);
+ current_part->lineno = lineno;
+ }
+#line 2019 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 20:
+#line 404 "config_gram.y" /* yacc.c:1646 */
+ {
+ AVRPART * parent_part = locate_part(part_list, (yyvsp[0])->value.string);
+ if (parent_part == NULL) {
+ yyerror("can't find parent part");
+ free_token((yyvsp[0]));
+ YYABORT;
+ }
+
+ current_part = avr_dup_part(parent_part);
+ if (current_part == NULL) {
+ yyerror("could not duplicate part instance");
+ free_token((yyvsp[0]));
+ YYABORT;
+ }
+ strcpy(current_part->config_file, infile);
+ current_part->lineno = lineno;
+
+ free_token((yyvsp[0]));
+ }
+#line 2043 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 21:
+#line 426 "config_gram.y" /* yacc.c:1646 */
+ { ladd(string_list, (yyvsp[0])); }
+#line 2049 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 22:
+#line 427 "config_gram.y" /* yacc.c:1646 */
+ { ladd(string_list, (yyvsp[0])); }
+#line 2055 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 23:
+#line 432 "config_gram.y" /* yacc.c:1646 */
+ { ladd(number_list, (yyvsp[0])); }
+#line 2061 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 24:
+#line 433 "config_gram.y" /* yacc.c:1646 */
+ { ladd(number_list, (yyvsp[0])); }
+#line 2067 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 27:
+#line 442 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ TOKEN * t;
+ char *s;
+ int do_yyabort = 0;
+ while (lsize(string_list)) {
+ t = lrmv_n(string_list, 1);
+ if (!do_yyabort) {
+ s = dup_string(t->value.string);
+ if (s == NULL) {
+ do_yyabort = 1;
+ } else {
+ ladd(current_prog->id, s);
+ }
+ }
+ /* if do_yyabort == 1 just make the list empty */
+ free_token(t);
+ }
+ if (do_yyabort) {
+ YYABORT;
+ }
+ }
+ }
+#line 2095 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 32:
+#line 473 "config_gram.y" /* yacc.c:1646 */
+ {
+ strncpy(current_prog->desc, (yyvsp[0])->value.string, PGM_DESCLEN);
+ current_prog->desc[PGM_DESCLEN-1] = 0;
+ free_token((yyvsp[0]));
+ }
+#line 2105 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 33:
+#line 478 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ current_prog->baudrate = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2116 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 35:
+#line 491 "config_gram.y" /* yacc.c:1646 */
+ {
+ const struct programmer_type_t * pgm_type = locate_programmer_type((yyvsp[0])->value.string);
+ if (pgm_type == NULL) {
+ yyerror("programmer type %s not found", (yyvsp[0])->value.string);
+ free_token((yyvsp[0]));
+ YYABORT;
+ }
+ current_prog->initpgm = pgm_type->initpgm;
+ free_token((yyvsp[0]));
+}
+#line 2131 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 36:
+#line 502 "config_gram.y" /* yacc.c:1646 */
+ {
+ yyerror("programmer type must be written as \"id_type\"");
+ YYABORT;
+}
+#line 2140 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 38:
+#line 513 "config_gram.y" /* yacc.c:1646 */
+ { current_prog->conntype = CONNTYPE_PARALLEL; }
+#line 2146 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 39:
+#line 514 "config_gram.y" /* yacc.c:1646 */
+ { current_prog->conntype = CONNTYPE_SERIAL; }
+#line 2152 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 40:
+#line 515 "config_gram.y" /* yacc.c:1646 */
+ { current_prog->conntype = CONNTYPE_USB; }
+#line 2158 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 41:
+#line 519 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ strncpy(current_prog->usbdev, (yyvsp[0])->value.string, PGM_USBSTRINGLEN);
+ current_prog->usbdev[PGM_USBSTRINGLEN-1] = 0;
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2170 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 42:
+#line 526 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ current_prog->usbvid = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2181 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 44:
+#line 533 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ strncpy(current_prog->usbsn, (yyvsp[0])->value.string, PGM_USBSTRINGLEN);
+ current_prog->usbsn[PGM_USBSTRINGLEN-1] = 0;
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2193 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 45:
+#line 540 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ strncpy(current_prog->usbvendor, (yyvsp[0])->value.string, PGM_USBSTRINGLEN);
+ current_prog->usbvendor[PGM_USBSTRINGLEN-1] = 0;
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2205 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 46:
+#line 547 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ strncpy(current_prog->usbproduct, (yyvsp[0])->value.string, PGM_USBSTRINGLEN);
+ current_prog->usbproduct[PGM_USBSTRINGLEN-1] = 0;
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2217 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 47:
+#line 557 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ /* overwrite pids, so clear the existing entries */
+ ldestroy_cb(current_prog->usbpid, free);
+ current_prog->usbpid = lcreat(NULL, 0);
+ }
+ {
+ int *ip = malloc(sizeof(int));
+ if (ip) {
+ *ip = (yyvsp[0])->value.number;
+ ladd(current_prog->usbpid, ip);
+ }
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2237 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 48:
+#line 572 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ int *ip = malloc(sizeof(int));
+ if (ip) {
+ *ip = (yyvsp[0])->value.number;
+ ladd(current_prog->usbpid, ip);
+ }
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2252 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 49:
+#line 585 "config_gram.y" /* yacc.c:1646 */
+ { if(0 != assign_pin(pin_name, (yyvsp[0]), 0)) YYABORT; }
+#line 2258 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 50:
+#line 587 "config_gram.y" /* yacc.c:1646 */
+ { if(0 != assign_pin(pin_name, (yyvsp[0]), 1)) YYABORT; }
+#line 2264 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 52:
+#line 593 "config_gram.y" /* yacc.c:1646 */
+ { pin_clear_all(&(current_prog->pin[pin_name])); }
+#line 2270 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 54:
+#line 599 "config_gram.y" /* yacc.c:1646 */
+ { if(0 != assign_pin_list(1)) YYABORT; }
+#line 2276 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 58:
+#line 612 "config_gram.y" /* yacc.c:1646 */
+ { pin_clear_all(&(current_prog->pin[pin_name])); }
+#line 2282 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 59:
+#line 616 "config_gram.y" /* yacc.c:1646 */
+ {pin_name = PPI_AVR_VCC; }
+#line 2288 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 61:
+#line 617 "config_gram.y" /* yacc.c:1646 */
+ {pin_name = PPI_AVR_BUFF; }
+#line 2294 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 63:
+#line 618 "config_gram.y" /* yacc.c:1646 */
+ {pin_name = PIN_AVR_RESET;}
+#line 2300 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 64:
+#line 618 "config_gram.y" /* yacc.c:1646 */
+ { free_token((yyvsp[-3])); }
+#line 2306 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 65:
+#line 619 "config_gram.y" /* yacc.c:1646 */
+ {pin_name = PIN_AVR_SCK; }
+#line 2312 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 66:
+#line 619 "config_gram.y" /* yacc.c:1646 */
+ { free_token((yyvsp[-3])); }
+#line 2318 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 67:
+#line 620 "config_gram.y" /* yacc.c:1646 */
+ {pin_name = PIN_AVR_MOSI; }
+#line 2324 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 69:
+#line 621 "config_gram.y" /* yacc.c:1646 */
+ {pin_name = PIN_AVR_MISO; }
+#line 2330 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 71:
+#line 622 "config_gram.y" /* yacc.c:1646 */
+ {pin_name = PIN_LED_ERR; }
+#line 2336 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 73:
+#line 623 "config_gram.y" /* yacc.c:1646 */
+ {pin_name = PIN_LED_RDY; }
+#line 2342 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 75:
+#line 624 "config_gram.y" /* yacc.c:1646 */
+ {pin_name = PIN_LED_PGM; }
+#line 2348 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 77:
+#line 625 "config_gram.y" /* yacc.c:1646 */
+ {pin_name = PIN_LED_VFY; }
+#line 2354 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 99:
+#line 664 "config_gram.y" /* yacc.c:1646 */
+ {
+ strncpy(current_part->id, (yyvsp[0])->value.string, AVR_IDLEN);
+ current_part->id[AVR_IDLEN-1] = 0;
+ free_token((yyvsp[0]));
+ }
+#line 2364 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 100:
+#line 671 "config_gram.y" /* yacc.c:1646 */
+ {
+ strncpy(current_part->desc, (yyvsp[0])->value.string, AVR_DESCLEN);
+ current_part->desc[AVR_DESCLEN-1] = 0;
+ free_token((yyvsp[0]));
+ }
+#line 2374 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 101:
+#line 677 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ yyerror("devicecode is deprecated, use "
+ "stk500_devcode instead");
+ YYABORT;
+ }
+ }
+#line 2386 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 102:
+#line 685 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ current_part->stk500_devcode = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2397 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 103:
+#line 692 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ current_part->avr910_devcode = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2408 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 104:
+#line 699 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ current_part->signature[0] = (yyvsp[-2])->value.number;
+ current_part->signature[1] = (yyvsp[-1])->value.number;
+ current_part->signature[2] = (yyvsp[0])->value.number;
+ free_token((yyvsp[-2]));
+ free_token((yyvsp[-1]));
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2423 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 105:
+#line 710 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ current_part->usbpid = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+ }
+#line 2434 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 106:
+#line 717 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ TOKEN * t;
+ unsigned nbytes;
+ int ok;
+
+ current_part->ctl_stack_type = CTL_STACK_PP;
+ nbytes = 0;
+ ok = 1;
+
+ memset(current_part->controlstack, 0, CTL_STACK_SIZE);
+ while (lsize(number_list)) {
+ t = lrmv_n(number_list, 1);
+ if (nbytes < CTL_STACK_SIZE)
+ {
+ current_part->controlstack[nbytes] = t->value.number;
+ nbytes++;
+ }
+ else
+ {
+ ok = 0;
+ }
+ free_token(t);
+ }
+ if (!ok)
+ {
+ yywarning("too many bytes in control stack");
+ }
+ }
+ }
+#line 2469 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 107:
+#line 748 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ TOKEN * t;
+ unsigned nbytes;
+ int ok;
+
+ current_part->ctl_stack_type = CTL_STACK_HVSP;
+ nbytes = 0;
+ ok = 1;
+
+ memset(current_part->controlstack, 0, CTL_STACK_SIZE);
+ while (lsize(number_list)) {
+ t = lrmv_n(number_list, 1);
+ if (nbytes < CTL_STACK_SIZE)
+ {
+ current_part->controlstack[nbytes] = t->value.number;
+ nbytes++;
+ }
+ else
+ {
+ ok = 0;
+ }
+ free_token(t);
+ }
+ if (!ok)
+ {
+ yywarning("too many bytes in control stack");
+ }
+ }
+ }
+#line 2504 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 108:
+#line 779 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ TOKEN * t;
+ unsigned nbytes;
+ int ok;
+
+ nbytes = 0;
+ ok = 1;
+
+ memset(current_part->flash_instr, 0, FLASH_INSTR_SIZE);
+ while (lsize(number_list)) {
+ t = lrmv_n(number_list, 1);
+ if (nbytes < FLASH_INSTR_SIZE)
+ {
+ current_part->flash_instr[nbytes] = t->value.number;
+ nbytes++;
+ }
+ else
+ {
+ ok = 0;
+ }
+ free_token(t);
+ }
+ if (!ok)
+ {
+ yywarning("too many bytes in flash instructions");
+ }
+ }
+ }
+#line 2538 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 109:
+#line 809 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ TOKEN * t;
+ unsigned nbytes;
+ int ok;
+
+ nbytes = 0;
+ ok = 1;
+
+ memset(current_part->eeprom_instr, 0, EEPROM_INSTR_SIZE);
+ while (lsize(number_list)) {
+ t = lrmv_n(number_list, 1);
+ if (nbytes < EEPROM_INSTR_SIZE)
+ {
+ current_part->eeprom_instr[nbytes] = t->value.number;
+ nbytes++;
+ }
+ else
+ {
+ ok = 0;
+ }
+ free_token(t);
+ }
+ if (!ok)
+ {
+ yywarning("too many bytes in EEPROM instructions");
+ }
+ }
+ }
+#line 2572 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 110:
+#line 840 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->chip_erase_delay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2581 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 111:
+#line 846 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->pagel = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2590 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 112:
+#line 852 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->bs2 = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2599 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 113:
+#line 858 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0])->primary == K_DEDICATED)
+ current_part->reset_disposition = RESET_DEDICATED;
+ else if ((yyvsp[0])->primary == K_IO)
+ current_part->reset_disposition = RESET_IO;
+
+ free_tokens(2, (yyvsp[-2]), (yyvsp[0]));
+ }
+#line 2612 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 114:
+#line 868 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->timeout = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2621 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 115:
+#line 874 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->stabdelay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2630 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 116:
+#line 880 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->cmdexedelay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2639 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 117:
+#line 886 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->hvspcmdexedelay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2648 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 118:
+#line 892 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->synchloops = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2657 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 119:
+#line 898 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->bytedelay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2666 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 120:
+#line 904 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->pollvalue = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2675 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 121:
+#line 910 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->pollindex = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2684 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 122:
+#line 916 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->predelay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2693 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 123:
+#line 922 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->postdelay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2702 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 124:
+#line 928 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->pollmethod = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2711 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 125:
+#line 934 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->hventerstabdelay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2720 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 126:
+#line 940 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->progmodedelay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2729 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 127:
+#line 946 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->latchcycles = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2738 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 128:
+#line 952 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->togglevtg = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2747 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 129:
+#line 958 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->poweroffdelay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2756 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 130:
+#line 964 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->resetdelayms = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2765 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 131:
+#line 970 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->resetdelayus = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2774 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 132:
+#line 976 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->hvleavestabdelay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2783 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 133:
+#line 982 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->resetdelay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2792 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 134:
+#line 988 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->chiperasepulsewidth = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2801 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 135:
+#line 994 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->chiperasepolltimeout = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2810 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 136:
+#line 1000 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->chiperasetime = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2819 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 137:
+#line 1006 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->programfusepulsewidth = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2828 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 138:
+#line 1012 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->programfusepolltimeout = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2837 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 139:
+#line 1018 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->programlockpulsewidth = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2846 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 140:
+#line 1024 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->programlockpolltimeout = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2855 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 141:
+#line 1030 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->synchcycles = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2864 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 142:
+#line 1036 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0])->primary == K_YES)
+ current_part->flags |= AVRPART_HAS_JTAG;
+ else if ((yyvsp[0])->primary == K_NO)
+ current_part->flags &= ~AVRPART_HAS_JTAG;
+
+ free_token((yyvsp[0]));
+ }
+#line 2877 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 143:
+#line 1046 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0])->primary == K_YES)
+ current_part->flags |= AVRPART_HAS_DW;
+ else if ((yyvsp[0])->primary == K_NO)
+ current_part->flags &= ~AVRPART_HAS_DW;
+
+ free_token((yyvsp[0]));
+ }
+#line 2890 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 144:
+#line 1056 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0])->primary == K_YES)
+ current_part->flags |= AVRPART_HAS_PDI;
+ else if ((yyvsp[0])->primary == K_NO)
+ current_part->flags &= ~AVRPART_HAS_PDI;
+
+ free_token((yyvsp[0]));
+ }
+#line 2903 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 145:
+#line 1066 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0])->primary == K_YES)
+ current_part->flags |= AVRPART_HAS_TPI;
+ else if ((yyvsp[0])->primary == K_NO)
+ current_part->flags &= ~AVRPART_HAS_TPI;
+
+ free_token((yyvsp[0]));
+ }
+#line 2916 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 146:
+#line 1076 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0])->primary == K_YES)
+ current_part->flags |= AVRPART_IS_AT90S1200;
+ else if ((yyvsp[0])->primary == K_NO)
+ current_part->flags &= ~AVRPART_IS_AT90S1200;
+
+ free_token((yyvsp[0]));
+ }
+#line 2929 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 147:
+#line 1086 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0])->primary == K_YES)
+ current_part->flags |= AVRPART_AVR32;
+ else if ((yyvsp[0])->primary == K_NO)
+ current_part->flags &= ~AVRPART_AVR32;
+
+ free_token((yyvsp[0]));
+ }
+#line 2942 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 148:
+#line 1096 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0])->primary == K_YES)
+ current_part->flags |= AVRPART_ALLOWFULLPAGEBITSTREAM;
+ else if ((yyvsp[0])->primary == K_NO)
+ current_part->flags &= ~AVRPART_ALLOWFULLPAGEBITSTREAM;
+
+ free_token((yyvsp[0]));
+ }
+#line 2955 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 149:
+#line 1106 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0])->primary == K_YES)
+ current_part->flags |= AVRPART_ENABLEPAGEPROGRAMMING;
+ else if ((yyvsp[0])->primary == K_NO)
+ current_part->flags &= ~AVRPART_ENABLEPAGEPROGRAMMING;
+
+ free_token((yyvsp[0]));
+ }
+#line 2968 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 150:
+#line 1116 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->idr = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2977 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 151:
+#line 1122 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->rampz = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2986 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 152:
+#line 1128 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->spmcr = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 2995 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 153:
+#line 1134 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->eecr = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3004 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 154:
+#line 1140 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->mcu_base = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3013 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 155:
+#line 1146 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->nvm_base = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3022 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 156:
+#line 1152 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_part->ocdrev = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3031 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 157:
+#line 1158 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0])->primary == K_YES)
+ current_part->flags |= AVRPART_SERIALOK;
+ else if ((yyvsp[0])->primary == K_NO)
+ current_part->flags &= ~AVRPART_SERIALOK;
+
+ free_token((yyvsp[0]));
+ }
+#line 3044 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 158:
+#line 1168 "config_gram.y" /* yacc.c:1646 */
+ {
+ if ((yyvsp[0])->primary == K_YES) {
+ current_part->flags |= AVRPART_PARALLELOK;
+ current_part->flags &= ~AVRPART_PSEUDOPARALLEL;
+ }
+ else if ((yyvsp[0])->primary == K_NO) {
+ current_part->flags &= ~AVRPART_PARALLELOK;
+ current_part->flags &= ~AVRPART_PSEUDOPARALLEL;
+ }
+ else if ((yyvsp[0])->primary == K_PSEUDO) {
+ current_part->flags |= AVRPART_PARALLELOK;
+ current_part->flags |= AVRPART_PSEUDOPARALLEL;
+ }
+
+
+ free_token((yyvsp[0]));
+ }
+#line 3066 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 159:
+#line 1187 "config_gram.y" /* yacc.c:1646 */
+ {
+ switch ((yyvsp[0])->primary) {
+ case K_RESET :
+ current_part->retry_pulse = PIN_AVR_RESET;
+ break;
+ case K_SCK :
+ current_part->retry_pulse = PIN_AVR_SCK;
+ break;
+ }
+
+ free_token((yyvsp[-2]));
+ }
+#line 3083 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 160:
+#line 1210 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem = avr_new_memtype();
+ if (current_mem == NULL) {
+ yyerror("could not create mem instance");
+ free_token((yyvsp[0]));
+ YYABORT;
+ }
+ strncpy(current_mem->desc, (yyvsp[0])->value.string, AVR_MEMDESCLEN);
+ current_mem->desc[AVR_MEMDESCLEN-1] = 0;
+ free_token((yyvsp[0]));
+ }
+#line 3099 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 161:
+#line 1222 "config_gram.y" /* yacc.c:1646 */
+ {
+ AVRMEM * existing_mem;
+
+ existing_mem = avr_locate_mem(current_part, current_mem->desc);
+ if (existing_mem != NULL) {
+ lrmv_d(current_part->mem, existing_mem);
+ avr_free_mem(existing_mem);
+ }
+ ladd(current_part->mem, current_mem);
+ current_mem = NULL;
+ }
+#line 3115 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 162:
+#line 1234 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ int opnum;
+ OPCODE * op;
+
+ opnum = which_opcode((yyvsp[-2]));
+ if (opnum < 0) YYABORT;
+ op = avr_new_opcode();
+ if (op == NULL) {
+ yyerror("could not create opcode instance");
+ free_token((yyvsp[-2]));
+ YYABORT;
+ }
+ if(0 != parse_cmdbits(op)) YYABORT;
+ if (current_part->op[opnum] != NULL) {
+ /*yywarning("operation redefined");*/
+ avr_free_opcode(current_part->op[opnum]);
+ }
+ current_part->op[opnum] = op;
+
+ free_token((yyvsp[-2]));
+ }
+ }
+#line 3143 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 167:
+#line 1273 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->paged = (yyvsp[0])->primary == K_YES ? 1 : 0;
+ free_token((yyvsp[0]));
+ }
+#line 3152 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 168:
+#line 1279 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->size = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3161 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 169:
+#line 1286 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->page_size = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3170 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 170:
+#line 1292 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->num_pages = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3179 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 171:
+#line 1298 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->offset = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3188 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 172:
+#line 1304 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->min_write_delay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3197 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 173:
+#line 1310 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->max_write_delay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3206 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 174:
+#line 1316 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->pwroff_after_write = (yyvsp[0])->primary == K_YES ? 1 : 0;
+ free_token((yyvsp[0]));
+ }
+#line 3215 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 175:
+#line 1322 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->readback[0] = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3224 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 176:
+#line 1328 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->readback[1] = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3233 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 177:
+#line 1335 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->mode = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3242 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 178:
+#line 1341 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->delay = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3251 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 179:
+#line 1347 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->blocksize = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3260 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 180:
+#line 1353 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->readsize = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3269 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 181:
+#line 1359 "config_gram.y" /* yacc.c:1646 */
+ {
+ current_mem->pollindex = (yyvsp[0])->value.number;
+ free_token((yyvsp[0]));
+ }
+#line 3278 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+ case 182:
+#line 1365 "config_gram.y" /* yacc.c:1646 */
+ {
+ {
+ int opnum;
+ OPCODE * op;
+
+ opnum = which_opcode((yyvsp[-2]));
+ if (opnum < 0) YYABORT;
+ op = avr_new_opcode();
+ if (op == NULL) {
+ yyerror("could not create opcode instance");
+ free_token((yyvsp[-2]));
+ YYABORT;
+ }
+ if(0 != parse_cmdbits(op)) YYABORT;
+ if (current_mem->op[opnum] != NULL) {
+ /*yywarning("operation redefined");*/
+ avr_free_opcode(current_mem->op[opnum]);
+ }
+ current_mem->op[opnum] = op;
+
+ free_token((yyvsp[-2]));
+ }
+ }
+#line 3306 "config_gram.c" /* yacc.c:1646 */
+ break;
+
+
+#line 3310 "config_gram.c" /* yacc.c:1646 */
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+ yyssp, yytoken)
+ {
+ char const *yymsgp = YY_("syntax error");
+ int yysyntax_error_status;
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ if (yysyntax_error_status == 0)
+ yymsgp = yymsg;
+ else if (yysyntax_error_status == 1)
+ {
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+ if (!yymsg)
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ yysyntax_error_status = 2;
+ }
+ else
+ {
+ yysyntax_error_status = YYSYNTAX_ERROR;
+ yymsgp = yymsg;
+ }
+ }
+ yyerror (yymsgp);
+ if (yysyntax_error_status == 2)
+ goto yyexhaustedlab;
+ }
+# undef YYSYNTAX_ERROR
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default (yyn))
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ return yyresult;
+}
+#line 1391 "config_gram.y" /* yacc.c:1906 */
+
+
+#if 0
+static char * vtypestr(int type)
+{
+ switch (type) {
+ case V_NUM : return "INTEGER";
+ case V_NUM_REAL: return "REAL";
+ case V_STR : return "STRING";
+ default:
+ return "<UNKNOWN>";
+ }
+}
+#endif
+
+
+static int assign_pin(int pinno, TOKEN * v, int invert)
+{
+ int value;
+
+ value = v->value.number;
+ free_token(v);
+
+ if ((value < PIN_MIN) || (value > PIN_MAX)) {
+ yyerror("pin must be in the range " TOSTRING(PIN_MIN) "-" TOSTRING(PIN_MAX));
+ return -1;
+ }
+
+ pin_set_value(&(current_prog->pin[pinno]), value, invert);
+
+ return 0;
+}
+
+static int assign_pin_list(int invert)
+{
+ TOKEN * t;
+ int pin;
+ int rv = 0;
+
+ current_prog->pinno[pin_name] = 0;
+ while (lsize(number_list)) {
+ t = lrmv_n(number_list, 1);
+ if (rv == 0) {
+ pin = t->value.number;
+ if ((pin < PIN_MIN) || (pin > PIN_MAX)) {
+ yyerror("pin must be in the range " TOSTRING(PIN_MIN) "-" TOSTRING(PIN_MAX));
+ rv = -1;
+ /* loop clears list and frees tokens */
+ }
+ pin_set_value(&(current_prog->pin[pin_name]), pin, invert);
+ }
+ free_token(t);
+ }
+ return rv;
+}
+
+static int which_opcode(TOKEN * opcode)
+{
+ switch (opcode->primary) {
+ case K_READ : return AVR_OP_READ; break;
+ case K_WRITE : return AVR_OP_WRITE; break;
+ case K_READ_LO : return AVR_OP_READ_LO; break;
+ case K_READ_HI : return AVR_OP_READ_HI; break;
+ case K_WRITE_LO : return AVR_OP_WRITE_LO; break;
+ case K_WRITE_HI : return AVR_OP_WRITE_HI; break;
+ case K_LOADPAGE_LO : return AVR_OP_LOADPAGE_LO; break;
+ case K_LOADPAGE_HI : return AVR_OP_LOADPAGE_HI; break;
+ case K_LOAD_EXT_ADDR : return AVR_OP_LOAD_EXT_ADDR; break;
+ case K_WRITEPAGE : return AVR_OP_WRITEPAGE; break;
+ case K_CHIP_ERASE : return AVR_OP_CHIP_ERASE; break;
+ case K_PGM_ENABLE : return AVR_OP_PGM_ENABLE; break;
+ default :
+ yyerror("invalid opcode");
+ return -1;
+ break;
+ }
+}
+
+
+static int parse_cmdbits(OPCODE * op)
+{
+ TOKEN * t;
+ int bitno;
+ char ch;
+ char * e;
+ char * q;
+ int len;
+ char * s, *brkt = NULL;
+ int rv = 0;
+
+ bitno = 32;
+ while (lsize(string_list)) {
+
+ t = lrmv_n(string_list, 1);
+
+ s = strtok_r(t->value.string, " ", &brkt);
+ while (rv == 0 && s != NULL) {
+
+ bitno--;
+ if (bitno < 0) {
+ yyerror("too many opcode bits for instruction");
+ rv = -1;
+ break;
+ }
+
+ len = strlen(s);
+
+ if (len == 0) {
+ yyerror("invalid bit specifier \"\"");
+ rv = -1;
+ break;
+ }
+
+ ch = s[0];
+
+ if (len == 1) {
+ switch (ch) {
+ case '1':
+ op->bit[bitno].type = AVR_CMDBIT_VALUE;
+ op->bit[bitno].value = 1;
+ op->bit[bitno].bitno = bitno % 8;
+ break;
+ case '0':
+ op->bit[bitno].type = AVR_CMDBIT_VALUE;
+ op->bit[bitno].value = 0;
+ op->bit[bitno].bitno = bitno % 8;
+ break;
+ case 'x':
+ op->bit[bitno].type = AVR_CMDBIT_IGNORE;
+ op->bit[bitno].value = 0;
+ op->bit[bitno].bitno = bitno % 8;
+ break;
+ case 'a':
+ op->bit[bitno].type = AVR_CMDBIT_ADDRESS;
+ op->bit[bitno].value = 0;
+ op->bit[bitno].bitno = 8*(bitno/8) + bitno % 8;
+ break;
+ case 'i':
+ op->bit[bitno].type = AVR_CMDBIT_INPUT;
+ op->bit[bitno].value = 0;
+ op->bit[bitno].bitno = bitno % 8;
+ break;
+ case 'o':
+ op->bit[bitno].type = AVR_CMDBIT_OUTPUT;
+ op->bit[bitno].value = 0;
+ op->bit[bitno].bitno = bitno % 8;
+ break;
+ default :
+ yyerror("invalid bit specifier '%c'", ch);
+ rv = -1;
+ break;
+ }
+ }
+ else {
+ if (ch == 'a') {
+ q = &s[1];
+ op->bit[bitno].bitno = strtol(q, &e, 0);
+ if ((e == q)||(*e != 0)) {
+ yyerror("can't parse bit number from \"%s\"", q);
+ rv = -1;
+ break;
+ }
+ op->bit[bitno].type = AVR_CMDBIT_ADDRESS;
+ op->bit[bitno].value = 0;
+ }
+ else {
+ yyerror("invalid bit specifier \"%s\"", s);
+ rv = -1;
+ break;
+ }
+ }
+
+ s = strtok_r(NULL, " ", &brkt);
+ } /* while */
+
+ free_token(t);
+
+ } /* while */
+
+ return rv;
+}
diff --git a/xs/src/avrdude/config_gram.h b/xs/src/avrdude/config_gram.h
new file mode 100644
index 000000000..036d67ebe
--- /dev/null
+++ b/xs/src/avrdude/config_gram.h
@@ -0,0 +1,330 @@
+/* A Bison parser, made by GNU Bison 3.0.4. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+ 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 3 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/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+#ifndef YY_YY_CONFIG_GRAM_H_INCLUDED
+# define YY_YY_CONFIG_GRAM_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+
+/* Token type. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ enum yytokentype
+ {
+ K_READ = 258,
+ K_WRITE = 259,
+ K_READ_LO = 260,
+ K_READ_HI = 261,
+ K_WRITE_LO = 262,
+ K_WRITE_HI = 263,
+ K_LOADPAGE_LO = 264,
+ K_LOADPAGE_HI = 265,
+ K_LOAD_EXT_ADDR = 266,
+ K_WRITEPAGE = 267,
+ K_CHIP_ERASE = 268,
+ K_PGM_ENABLE = 269,
+ K_MEMORY = 270,
+ K_PAGE_SIZE = 271,
+ K_PAGED = 272,
+ K_BAUDRATE = 273,
+ K_BS2 = 274,
+ K_BUFF = 275,
+ K_CHIP_ERASE_DELAY = 276,
+ K_CONNTYPE = 277,
+ K_DEDICATED = 278,
+ K_DEFAULT_BITCLOCK = 279,
+ K_DEFAULT_PARALLEL = 280,
+ K_DEFAULT_PROGRAMMER = 281,
+ K_DEFAULT_SAFEMODE = 282,
+ K_DEFAULT_SERIAL = 283,
+ K_DESC = 284,
+ K_DEVICECODE = 285,
+ K_STK500_DEVCODE = 286,
+ K_AVR910_DEVCODE = 287,
+ K_EEPROM = 288,
+ K_ERRLED = 289,
+ K_FLASH = 290,
+ K_ID = 291,
+ K_IO = 292,
+ K_LOADPAGE = 293,
+ K_MAX_WRITE_DELAY = 294,
+ K_MCU_BASE = 295,
+ K_MIN_WRITE_DELAY = 296,
+ K_MISO = 297,
+ K_MOSI = 298,
+ K_NUM_PAGES = 299,
+ K_NVM_BASE = 300,
+ K_OCDREV = 301,
+ K_OFFSET = 302,
+ K_PAGEL = 303,
+ K_PARALLEL = 304,
+ K_PARENT = 305,
+ K_PART = 306,
+ K_PGMLED = 307,
+ K_PROGRAMMER = 308,
+ K_PSEUDO = 309,
+ K_PWROFF_AFTER_WRITE = 310,
+ K_RDYLED = 311,
+ K_READBACK_P1 = 312,
+ K_READBACK_P2 = 313,
+ K_READMEM = 314,
+ K_RESET = 315,
+ K_RETRY_PULSE = 316,
+ K_SERIAL = 317,
+ K_SCK = 318,
+ K_SIGNATURE = 319,
+ K_SIZE = 320,
+ K_USB = 321,
+ K_USBDEV = 322,
+ K_USBSN = 323,
+ K_USBPID = 324,
+ K_USBPRODUCT = 325,
+ K_USBVENDOR = 326,
+ K_USBVID = 327,
+ K_TYPE = 328,
+ K_VCC = 329,
+ K_VFYLED = 330,
+ K_NO = 331,
+ K_YES = 332,
+ K_TIMEOUT = 333,
+ K_STABDELAY = 334,
+ K_CMDEXEDELAY = 335,
+ K_HVSPCMDEXEDELAY = 336,
+ K_SYNCHLOOPS = 337,
+ K_BYTEDELAY = 338,
+ K_POLLVALUE = 339,
+ K_POLLINDEX = 340,
+ K_PREDELAY = 341,
+ K_POSTDELAY = 342,
+ K_POLLMETHOD = 343,
+ K_MODE = 344,
+ K_DELAY = 345,
+ K_BLOCKSIZE = 346,
+ K_READSIZE = 347,
+ K_HVENTERSTABDELAY = 348,
+ K_PROGMODEDELAY = 349,
+ K_LATCHCYCLES = 350,
+ K_TOGGLEVTG = 351,
+ K_POWEROFFDELAY = 352,
+ K_RESETDELAYMS = 353,
+ K_RESETDELAYUS = 354,
+ K_HVLEAVESTABDELAY = 355,
+ K_RESETDELAY = 356,
+ K_SYNCHCYCLES = 357,
+ K_HVCMDEXEDELAY = 358,
+ K_CHIPERASEPULSEWIDTH = 359,
+ K_CHIPERASEPOLLTIMEOUT = 360,
+ K_CHIPERASETIME = 361,
+ K_PROGRAMFUSEPULSEWIDTH = 362,
+ K_PROGRAMFUSEPOLLTIMEOUT = 363,
+ K_PROGRAMLOCKPULSEWIDTH = 364,
+ K_PROGRAMLOCKPOLLTIMEOUT = 365,
+ K_PP_CONTROLSTACK = 366,
+ K_HVSP_CONTROLSTACK = 367,
+ K_ALLOWFULLPAGEBITSTREAM = 368,
+ K_ENABLEPAGEPROGRAMMING = 369,
+ K_HAS_JTAG = 370,
+ K_HAS_DW = 371,
+ K_HAS_PDI = 372,
+ K_HAS_TPI = 373,
+ K_IDR = 374,
+ K_IS_AT90S1200 = 375,
+ K_IS_AVR32 = 376,
+ K_RAMPZ = 377,
+ K_SPMCR = 378,
+ K_EECR = 379,
+ K_FLASH_INSTR = 380,
+ K_EEPROM_INSTR = 381,
+ TKN_COMMA = 382,
+ TKN_EQUAL = 383,
+ TKN_SEMI = 384,
+ TKN_TILDE = 385,
+ TKN_LEFT_PAREN = 386,
+ TKN_RIGHT_PAREN = 387,
+ TKN_NUMBER = 388,
+ TKN_NUMBER_REAL = 389,
+ TKN_STRING = 390
+ };
+#endif
+/* Tokens. */
+#define K_READ 258
+#define K_WRITE 259
+#define K_READ_LO 260
+#define K_READ_HI 261
+#define K_WRITE_LO 262
+#define K_WRITE_HI 263
+#define K_LOADPAGE_LO 264
+#define K_LOADPAGE_HI 265
+#define K_LOAD_EXT_ADDR 266
+#define K_WRITEPAGE 267
+#define K_CHIP_ERASE 268
+#define K_PGM_ENABLE 269
+#define K_MEMORY 270
+#define K_PAGE_SIZE 271
+#define K_PAGED 272
+#define K_BAUDRATE 273
+#define K_BS2 274
+#define K_BUFF 275
+#define K_CHIP_ERASE_DELAY 276
+#define K_CONNTYPE 277
+#define K_DEDICATED 278
+#define K_DEFAULT_BITCLOCK 279
+#define K_DEFAULT_PARALLEL 280
+#define K_DEFAULT_PROGRAMMER 281
+#define K_DEFAULT_SAFEMODE 282
+#define K_DEFAULT_SERIAL 283
+#define K_DESC 284
+#define K_DEVICECODE 285
+#define K_STK500_DEVCODE 286
+#define K_AVR910_DEVCODE 287
+#define K_EEPROM 288
+#define K_ERRLED 289
+#define K_FLASH 290
+#define K_ID 291
+#define K_IO 292
+#define K_LOADPAGE 293
+#define K_MAX_WRITE_DELAY 294
+#define K_MCU_BASE 295
+#define K_MIN_WRITE_DELAY 296
+#define K_MISO 297
+#define K_MOSI 298
+#define K_NUM_PAGES 299
+#define K_NVM_BASE 300
+#define K_OCDREV 301
+#define K_OFFSET 302
+#define K_PAGEL 303
+#define K_PARALLEL 304
+#define K_PARENT 305
+#define K_PART 306
+#define K_PGMLED 307
+#define K_PROGRAMMER 308
+#define K_PSEUDO 309
+#define K_PWROFF_AFTER_WRITE 310
+#define K_RDYLED 311
+#define K_READBACK_P1 312
+#define K_READBACK_P2 313
+#define K_READMEM 314
+#define K_RESET 315
+#define K_RETRY_PULSE 316
+#define K_SERIAL 317
+#define K_SCK 318
+#define K_SIGNATURE 319
+#define K_SIZE 320
+#define K_USB 321
+#define K_USBDEV 322
+#define K_USBSN 323
+#define K_USBPID 324
+#define K_USBPRODUCT 325
+#define K_USBVENDOR 326
+#define K_USBVID 327
+#define K_TYPE 328
+#define K_VCC 329
+#define K_VFYLED 330
+#define K_NO 331
+#define K_YES 332
+#define K_TIMEOUT 333
+#define K_STABDELAY 334
+#define K_CMDEXEDELAY 335
+#define K_HVSPCMDEXEDELAY 336
+#define K_SYNCHLOOPS 337
+#define K_BYTEDELAY 338
+#define K_POLLVALUE 339
+#define K_POLLINDEX 340
+#define K_PREDELAY 341
+#define K_POSTDELAY 342
+#define K_POLLMETHOD 343
+#define K_MODE 344
+#define K_DELAY 345
+#define K_BLOCKSIZE 346
+#define K_READSIZE 347
+#define K_HVENTERSTABDELAY 348
+#define K_PROGMODEDELAY 349
+#define K_LATCHCYCLES 350
+#define K_TOGGLEVTG 351
+#define K_POWEROFFDELAY 352
+#define K_RESETDELAYMS 353
+#define K_RESETDELAYUS 354
+#define K_HVLEAVESTABDELAY 355
+#define K_RESETDELAY 356
+#define K_SYNCHCYCLES 357
+#define K_HVCMDEXEDELAY 358
+#define K_CHIPERASEPULSEWIDTH 359
+#define K_CHIPERASEPOLLTIMEOUT 360
+#define K_CHIPERASETIME 361
+#define K_PROGRAMFUSEPULSEWIDTH 362
+#define K_PROGRAMFUSEPOLLTIMEOUT 363
+#define K_PROGRAMLOCKPULSEWIDTH 364
+#define K_PROGRAMLOCKPOLLTIMEOUT 365
+#define K_PP_CONTROLSTACK 366
+#define K_HVSP_CONTROLSTACK 367
+#define K_ALLOWFULLPAGEBITSTREAM 368
+#define K_ENABLEPAGEPROGRAMMING 369
+#define K_HAS_JTAG 370
+#define K_HAS_DW 371
+#define K_HAS_PDI 372
+#define K_HAS_TPI 373
+#define K_IDR 374
+#define K_IS_AT90S1200 375
+#define K_IS_AVR32 376
+#define K_RAMPZ 377
+#define K_SPMCR 378
+#define K_EECR 379
+#define K_FLASH_INSTR 380
+#define K_EEPROM_INSTR 381
+#define TKN_COMMA 382
+#define TKN_EQUAL 383
+#define TKN_SEMI 384
+#define TKN_TILDE 385
+#define TKN_LEFT_PAREN 386
+#define TKN_RIGHT_PAREN 387
+#define TKN_NUMBER 388
+#define TKN_NUMBER_REAL 389
+#define TKN_STRING 390
+
+/* Value type. */
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef int YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+extern YYSTYPE yylval;
+
+int yyparse (void);
+
+#endif /* !YY_YY_CONFIG_GRAM_H_INCLUDED */
diff --git a/xs/src/avrdude/config_gram.y b/xs/src/avrdude/config_gram.y
new file mode 100644
index 000000000..0aa95a8e8
--- /dev/null
+++ b/xs/src/avrdude/config_gram.y
@@ -0,0 +1,1571 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+%{
+
+#include "ac_cfg.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+#include "config.h"
+
+#if defined(WIN32NATIVE)
+#define strtok_r( _s, _sep, _lasts ) \
+ ( *(_lasts) = strtok( (_s), (_sep) ) )
+#endif
+
+#define STRINGIFY(x) #x
+#define TOSTRING(x) STRINGIFY(x)
+
+int yylex(void);
+int yyerror(char * errmsg, ...);
+int yywarning(char * errmsg, ...);
+
+static int assign_pin(int pinno, TOKEN * v, int invert);
+static int assign_pin_list(int invert);
+static int which_opcode(TOKEN * opcode);
+static int parse_cmdbits(OPCODE * op);
+
+static int pin_name;
+%}
+
+%token K_READ
+%token K_WRITE
+%token K_READ_LO
+%token K_READ_HI
+%token K_WRITE_LO
+%token K_WRITE_HI
+%token K_LOADPAGE_LO
+%token K_LOADPAGE_HI
+%token K_LOAD_EXT_ADDR
+%token K_WRITEPAGE
+%token K_CHIP_ERASE
+%token K_PGM_ENABLE
+
+%token K_MEMORY
+
+%token K_PAGE_SIZE
+%token K_PAGED
+
+%token K_BAUDRATE
+%token K_BS2
+%token K_BUFF
+%token K_CHIP_ERASE_DELAY
+%token K_CONNTYPE
+%token K_DEDICATED
+%token K_DEFAULT_BITCLOCK
+%token K_DEFAULT_PARALLEL
+%token K_DEFAULT_PROGRAMMER
+%token K_DEFAULT_SAFEMODE
+%token K_DEFAULT_SERIAL
+%token K_DESC
+%token K_DEVICECODE
+%token K_STK500_DEVCODE
+%token K_AVR910_DEVCODE
+%token K_EEPROM
+%token K_ERRLED
+%token K_FLASH
+%token K_ID
+%token K_IO
+%token K_LOADPAGE
+%token K_MAX_WRITE_DELAY
+%token K_MCU_BASE
+%token K_MIN_WRITE_DELAY
+%token K_MISO
+%token K_MOSI
+%token K_NUM_PAGES
+%token K_NVM_BASE
+%token K_OCDREV
+%token K_OFFSET
+%token K_PAGEL
+%token K_PARALLEL
+%token K_PARENT
+%token K_PART
+%token K_PGMLED
+%token K_PROGRAMMER
+%token K_PSEUDO
+%token K_PWROFF_AFTER_WRITE
+%token K_RDYLED
+%token K_READBACK_P1
+%token K_READBACK_P2
+%token K_READMEM
+%token K_RESET
+%token K_RETRY_PULSE
+%token K_SERIAL
+%token K_SCK
+%token K_SIGNATURE
+%token K_SIZE
+%token K_USB
+%token K_USBDEV
+%token K_USBSN
+%token K_USBPID
+%token K_USBPRODUCT
+%token K_USBVENDOR
+%token K_USBVID
+%token K_TYPE
+%token K_VCC
+%token K_VFYLED
+
+%token K_NO
+%token K_YES
+
+/* stk500 v2 xml file parameters */
+/* ISP */
+%token K_TIMEOUT
+%token K_STABDELAY
+%token K_CMDEXEDELAY
+%token K_HVSPCMDEXEDELAY
+%token K_SYNCHLOOPS
+%token K_BYTEDELAY
+%token K_POLLVALUE
+%token K_POLLINDEX
+%token K_PREDELAY
+%token K_POSTDELAY
+%token K_POLLMETHOD
+%token K_MODE
+%token K_DELAY
+%token K_BLOCKSIZE
+%token K_READSIZE
+/* HV mode */
+%token K_HVENTERSTABDELAY
+%token K_PROGMODEDELAY
+%token K_LATCHCYCLES
+%token K_TOGGLEVTG
+%token K_POWEROFFDELAY
+%token K_RESETDELAYMS
+%token K_RESETDELAYUS
+%token K_HVLEAVESTABDELAY
+%token K_RESETDELAY
+%token K_SYNCHCYCLES
+%token K_HVCMDEXEDELAY
+
+%token K_CHIPERASEPULSEWIDTH
+%token K_CHIPERASEPOLLTIMEOUT
+%token K_CHIPERASETIME
+%token K_PROGRAMFUSEPULSEWIDTH
+%token K_PROGRAMFUSEPOLLTIMEOUT
+%token K_PROGRAMLOCKPULSEWIDTH
+%token K_PROGRAMLOCKPOLLTIMEOUT
+
+%token K_PP_CONTROLSTACK
+%token K_HVSP_CONTROLSTACK
+
+/* JTAG ICE mkII specific parameters */
+%token K_ALLOWFULLPAGEBITSTREAM /*
+ * Internal parameter for the JTAG
+ * ICE; describes the internal JTAG
+ * streaming behaviour inside the MCU.
+ * 1 for all older chips, 0 for newer
+ * MCUs.
+ */
+%token K_ENABLEPAGEPROGRAMMING /* ? yes for mega256*, mega406 */
+%token K_HAS_JTAG /* MCU has JTAG i/f. */
+%token K_HAS_DW /* MCU has debugWire i/f. */
+%token K_HAS_PDI /* MCU has PDI i/f rather than ISP (ATxmega). */
+%token K_HAS_TPI /* MCU has TPI i/f rather than ISP (ATtiny4/5/9/10). */
+%token K_IDR /* address of OCD register in IO space */
+%token K_IS_AT90S1200 /* chip is an AT90S1200 (needs special treatment) */
+%token K_IS_AVR32 /* chip is in the avr32 family */
+%token K_RAMPZ /* address of RAMPZ reg. in IO space */
+%token K_SPMCR /* address of SPMC[S]R in memory space */
+%token K_EECR /* address of EECR in memory space */
+%token K_FLASH_INSTR /* flash instructions */
+%token K_EEPROM_INSTR /* EEPROM instructions */
+
+%token TKN_COMMA
+%token TKN_EQUAL
+%token TKN_SEMI
+%token TKN_TILDE
+%token TKN_LEFT_PAREN
+%token TKN_RIGHT_PAREN
+%token TKN_NUMBER
+%token TKN_NUMBER_REAL
+%token TKN_STRING
+
+%start configuration
+
+%%
+
+number_real :
+ TKN_NUMBER {
+ $$ = $1;
+ /* convert value to real */
+ $$->value.number_real = $$->value.number;
+ $$->value.type = V_NUM_REAL;
+ } |
+ TKN_NUMBER_REAL {
+ $$ = $1;
+ }
+
+configuration :
+ /* empty */ | config
+;
+
+config :
+ def |
+ config def
+;
+
+
+def :
+ prog_def TKN_SEMI |
+
+ part_def TKN_SEMI |
+
+ K_DEFAULT_PROGRAMMER TKN_EQUAL TKN_STRING TKN_SEMI {
+ strncpy(default_programmer, $3->value.string, MAX_STR_CONST);
+ default_programmer[MAX_STR_CONST-1] = 0;
+ free_token($3);
+ } |
+
+ K_DEFAULT_PARALLEL TKN_EQUAL TKN_STRING TKN_SEMI {
+ strncpy(default_parallel, $3->value.string, PATH_MAX);
+ default_parallel[PATH_MAX-1] = 0;
+ free_token($3);
+ } |
+
+ K_DEFAULT_SERIAL TKN_EQUAL TKN_STRING TKN_SEMI {
+ strncpy(default_serial, $3->value.string, PATH_MAX);
+ default_serial[PATH_MAX-1] = 0;
+ free_token($3);
+ } |
+
+ K_DEFAULT_BITCLOCK TKN_EQUAL number_real TKN_SEMI {
+ default_bitclock = $3->value.number_real;
+ free_token($3);
+ } |
+
+ K_DEFAULT_SAFEMODE TKN_EQUAL yesno TKN_SEMI {
+ if ($3->primary == K_YES)
+ default_safemode = 1;
+ else if ($3->primary == K_NO)
+ default_safemode = 0;
+ free_token($3);
+ }
+;
+
+
+prog_def :
+ prog_decl prog_parms
+ {
+ PROGRAMMER * existing_prog;
+ char * id;
+ if (lsize(current_prog->id) == 0) {
+ yyerror("required parameter id not specified");
+ YYABORT;
+ }
+ if (current_prog->initpgm == NULL) {
+ yyerror("programmer type not specified");
+ YYABORT;
+ }
+ id = ldata(lfirst(current_prog->id));
+ existing_prog = locate_programmer(programmers, id);
+ if (existing_prog) {
+ { /* temporarly set lineno to lineno of programmer start */
+ int temp = lineno; lineno = current_prog->lineno;
+ yywarning("programmer %s overwrites previous definition %s:%d.",
+ id, existing_prog->config_file, existing_prog->lineno);
+ lineno = temp;
+ }
+ lrmv_d(programmers, existing_prog);
+ pgm_free(existing_prog);
+ }
+ PUSH(programmers, current_prog);
+// pgm_fill_old_pins(current_prog); // TODO to be removed if old pin data no longer needed
+// pgm_display_generic(current_prog, id);
+ current_prog = NULL;
+ }
+;
+
+
+prog_decl :
+ K_PROGRAMMER
+ { current_prog = pgm_new();
+ if (current_prog == NULL) {
+ yyerror("could not create pgm instance");
+ YYABORT;
+ }
+ strcpy(current_prog->config_file, infile);
+ current_prog->lineno = lineno;
+ }
+ |
+ K_PROGRAMMER K_PARENT TKN_STRING
+ {
+ struct programmer_t * pgm = locate_programmer(programmers, $3->value.string);
+ if (pgm == NULL) {
+ yyerror("parent programmer %s not found", $3->value.string);
+ free_token($3);
+ YYABORT;
+ }
+ current_prog = pgm_dup(pgm);
+ if (current_prog == NULL) {
+ yyerror("could not duplicate pgm instance");
+ free_token($3);
+ YYABORT;
+ }
+ strcpy(current_prog->config_file, infile);
+ current_prog->lineno = lineno;
+ free_token($3);
+ }
+;
+
+
+part_def :
+ part_decl part_parms
+ {
+ LNODEID ln;
+ AVRMEM * m;
+ AVRPART * existing_part;
+
+ if (current_part->id[0] == 0) {
+ yyerror("required parameter id not specified");
+ YYABORT;
+ }
+
+ /*
+ * perform some sanity checking, and compute the number of bits
+ * to shift a page for constructing the page address for
+ * page-addressed memories.
+ */
+ for (ln=lfirst(current_part->mem); ln; ln=lnext(ln)) {
+ m = ldata(ln);
+ if (m->paged) {
+ if (m->page_size == 0) {
+ yyerror("must specify page_size for paged memory");
+ YYABORT;
+ }
+ if (m->num_pages == 0) {
+ yyerror("must specify num_pages for paged memory");
+ YYABORT;
+ }
+ if (m->size != m->page_size * m->num_pages) {
+ yyerror("page size (%u) * num_pages (%u) = "
+ "%u does not match memory size (%u)",
+ m->page_size,
+ m->num_pages,
+ m->page_size * m->num_pages,
+ m->size);
+ YYABORT;
+ }
+
+ }
+ }
+
+ existing_part = locate_part(part_list, current_part->id);
+ if (existing_part) {
+ { /* temporarly set lineno to lineno of part start */
+ int temp = lineno; lineno = current_part->lineno;
+ yywarning("part %s overwrites previous definition %s:%d.",
+ current_part->id,
+ existing_part->config_file, existing_part->lineno);
+ lineno = temp;
+ }
+ lrmv_d(part_list, existing_part);
+ avr_free_part(existing_part);
+ }
+ PUSH(part_list, current_part);
+ current_part = NULL;
+ }
+;
+
+part_decl :
+ K_PART
+ {
+ current_part = avr_new_part();
+ if (current_part == NULL) {
+ yyerror("could not create part instance");
+ YYABORT;
+ }
+ strcpy(current_part->config_file, infile);
+ current_part->lineno = lineno;
+ } |
+ K_PART K_PARENT TKN_STRING
+ {
+ AVRPART * parent_part = locate_part(part_list, $3->value.string);
+ if (parent_part == NULL) {
+ yyerror("can't find parent part");
+ free_token($3);
+ YYABORT;
+ }
+
+ current_part = avr_dup_part(parent_part);
+ if (current_part == NULL) {
+ yyerror("could not duplicate part instance");
+ free_token($3);
+ YYABORT;
+ }
+ strcpy(current_part->config_file, infile);
+ current_part->lineno = lineno;
+
+ free_token($3);
+ }
+;
+
+string_list :
+ TKN_STRING { ladd(string_list, $1); } |
+ string_list TKN_COMMA TKN_STRING { ladd(string_list, $3); }
+;
+
+
+num_list :
+ TKN_NUMBER { ladd(number_list, $1); } |
+ num_list TKN_COMMA TKN_NUMBER { ladd(number_list, $3); }
+;
+
+prog_parms :
+ prog_parm TKN_SEMI |
+ prog_parms prog_parm TKN_SEMI
+;
+
+prog_parm :
+ K_ID TKN_EQUAL string_list {
+ {
+ TOKEN * t;
+ char *s;
+ int do_yyabort = 0;
+ while (lsize(string_list)) {
+ t = lrmv_n(string_list, 1);
+ if (!do_yyabort) {
+ s = dup_string(t->value.string);
+ if (s == NULL) {
+ do_yyabort = 1;
+ } else {
+ ladd(current_prog->id, s);
+ }
+ }
+ /* if do_yyabort == 1 just make the list empty */
+ free_token(t);
+ }
+ if (do_yyabort) {
+ YYABORT;
+ }
+ }
+ } |
+ prog_parm_type
+ |
+ prog_parm_pins
+ |
+ prog_parm_usb
+ |
+ prog_parm_conntype
+ |
+ K_DESC TKN_EQUAL TKN_STRING {
+ strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
+ current_prog->desc[PGM_DESCLEN-1] = 0;
+ free_token($3);
+ } |
+ K_BAUDRATE TKN_EQUAL TKN_NUMBER {
+ {
+ current_prog->baudrate = $3->value.number;
+ free_token($3);
+ }
+ }
+;
+
+prog_parm_type:
+ K_TYPE TKN_EQUAL prog_parm_type_id
+;
+
+prog_parm_type_id:
+ TKN_STRING {
+ const struct programmer_type_t * pgm_type = locate_programmer_type($1->value.string);
+ if (pgm_type == NULL) {
+ yyerror("programmer type %s not found", $1->value.string);
+ free_token($1);
+ YYABORT;
+ }
+ current_prog->initpgm = pgm_type->initpgm;
+ free_token($1);
+}
+ | error
+{
+ yyerror("programmer type must be written as \"id_type\"");
+ YYABORT;
+}
+;
+
+prog_parm_conntype:
+ K_CONNTYPE TKN_EQUAL prog_parm_conntype_id
+;
+
+prog_parm_conntype_id:
+ K_PARALLEL { current_prog->conntype = CONNTYPE_PARALLEL; } |
+ K_SERIAL { current_prog->conntype = CONNTYPE_SERIAL; } |
+ K_USB { current_prog->conntype = CONNTYPE_USB; }
+;
+
+prog_parm_usb:
+ K_USBDEV TKN_EQUAL TKN_STRING {
+ {
+ strncpy(current_prog->usbdev, $3->value.string, PGM_USBSTRINGLEN);
+ current_prog->usbdev[PGM_USBSTRINGLEN-1] = 0;
+ free_token($3);
+ }
+ } |
+ K_USBVID TKN_EQUAL TKN_NUMBER {
+ {
+ current_prog->usbvid = $3->value.number;
+ free_token($3);
+ }
+ } |
+ K_USBPID TKN_EQUAL usb_pid_list |
+ K_USBSN TKN_EQUAL TKN_STRING {
+ {
+ strncpy(current_prog->usbsn, $3->value.string, PGM_USBSTRINGLEN);
+ current_prog->usbsn[PGM_USBSTRINGLEN-1] = 0;
+ free_token($3);
+ }
+ } |
+ K_USBVENDOR TKN_EQUAL TKN_STRING {
+ {
+ strncpy(current_prog->usbvendor, $3->value.string, PGM_USBSTRINGLEN);
+ current_prog->usbvendor[PGM_USBSTRINGLEN-1] = 0;
+ free_token($3);
+ }
+ } |
+ K_USBPRODUCT TKN_EQUAL TKN_STRING {
+ {
+ strncpy(current_prog->usbproduct, $3->value.string, PGM_USBSTRINGLEN);
+ current_prog->usbproduct[PGM_USBSTRINGLEN-1] = 0;
+ free_token($3);
+ }
+ }
+;
+
+usb_pid_list:
+ TKN_NUMBER {
+ {
+ /* overwrite pids, so clear the existing entries */
+ ldestroy_cb(current_prog->usbpid, free);
+ current_prog->usbpid = lcreat(NULL, 0);
+ }
+ {
+ int *ip = malloc(sizeof(int));
+ if (ip) {
+ *ip = $1->value.number;
+ ladd(current_prog->usbpid, ip);
+ }
+ free_token($1);
+ }
+ } |
+ usb_pid_list TKN_COMMA TKN_NUMBER {
+ {
+ int *ip = malloc(sizeof(int));
+ if (ip) {
+ *ip = $3->value.number;
+ ladd(current_prog->usbpid, ip);
+ }
+ free_token($3);
+ }
+ }
+;
+
+pin_number_non_empty:
+ TKN_NUMBER { if(0 != assign_pin(pin_name, $1, 0)) YYABORT; }
+ |
+ TKN_TILDE TKN_NUMBER { if(0 != assign_pin(pin_name, $2, 1)) YYABORT; }
+;
+
+pin_number:
+ pin_number_non_empty
+ |
+ /* empty */ { pin_clear_all(&(current_prog->pin[pin_name])); }
+;
+
+pin_list_element:
+ pin_number_non_empty
+ |
+ TKN_TILDE TKN_LEFT_PAREN num_list TKN_RIGHT_PAREN { if(0 != assign_pin_list(1)) YYABORT; }
+;
+
+pin_list_non_empty:
+ pin_list_element
+ |
+ pin_list_non_empty TKN_COMMA pin_list_element
+;
+
+
+pin_list:
+ pin_list_non_empty
+ |
+ /* empty */ { pin_clear_all(&(current_prog->pin[pin_name])); }
+;
+
+prog_parm_pins:
+ K_VCC TKN_EQUAL {pin_name = PPI_AVR_VCC; } pin_list |
+ K_BUFF TKN_EQUAL {pin_name = PPI_AVR_BUFF; } pin_list |
+ K_RESET TKN_EQUAL {pin_name = PIN_AVR_RESET;} pin_number { free_token($1); } |
+ K_SCK TKN_EQUAL {pin_name = PIN_AVR_SCK; } pin_number { free_token($1); } |
+ K_MOSI TKN_EQUAL {pin_name = PIN_AVR_MOSI; } pin_number |
+ K_MISO TKN_EQUAL {pin_name = PIN_AVR_MISO; } pin_number |
+ K_ERRLED TKN_EQUAL {pin_name = PIN_LED_ERR; } pin_number |
+ K_RDYLED TKN_EQUAL {pin_name = PIN_LED_RDY; } pin_number |
+ K_PGMLED TKN_EQUAL {pin_name = PIN_LED_PGM; } pin_number |
+ K_VFYLED TKN_EQUAL {pin_name = PIN_LED_VFY; } pin_number
+;
+
+opcode :
+ K_READ |
+ K_WRITE |
+ K_READ_LO |
+ K_READ_HI |
+ K_WRITE_LO |
+ K_WRITE_HI |
+ K_LOADPAGE_LO |
+ K_LOADPAGE_HI |
+ K_LOAD_EXT_ADDR |
+ K_WRITEPAGE |
+ K_CHIP_ERASE |
+ K_PGM_ENABLE
+;
+
+
+part_parms :
+ part_parm TKN_SEMI |
+ part_parms part_parm TKN_SEMI
+;
+
+
+reset_disposition :
+ K_DEDICATED | K_IO
+;
+
+parallel_modes :
+ yesno | K_PSEUDO
+;
+
+retry_lines :
+ K_RESET | K_SCK
+;
+
+part_parm :
+ K_ID TKN_EQUAL TKN_STRING
+ {
+ strncpy(current_part->id, $3->value.string, AVR_IDLEN);
+ current_part->id[AVR_IDLEN-1] = 0;
+ free_token($3);
+ } |
+
+ K_DESC TKN_EQUAL TKN_STRING
+ {
+ strncpy(current_part->desc, $3->value.string, AVR_DESCLEN);
+ current_part->desc[AVR_DESCLEN-1] = 0;
+ free_token($3);
+ } |
+
+ K_DEVICECODE TKN_EQUAL TKN_NUMBER {
+ {
+ yyerror("devicecode is deprecated, use "
+ "stk500_devcode instead");
+ YYABORT;
+ }
+ } |
+
+ K_STK500_DEVCODE TKN_EQUAL TKN_NUMBER {
+ {
+ current_part->stk500_devcode = $3->value.number;
+ free_token($3);
+ }
+ } |
+
+ K_AVR910_DEVCODE TKN_EQUAL TKN_NUMBER {
+ {
+ current_part->avr910_devcode = $3->value.number;
+ free_token($3);
+ }
+ } |
+
+ K_SIGNATURE TKN_EQUAL TKN_NUMBER TKN_NUMBER TKN_NUMBER {
+ {
+ current_part->signature[0] = $3->value.number;
+ current_part->signature[1] = $4->value.number;
+ current_part->signature[2] = $5->value.number;
+ free_token($3);
+ free_token($4);
+ free_token($5);
+ }
+ } |
+
+ K_USBPID TKN_EQUAL TKN_NUMBER {
+ {
+ current_part->usbpid = $3->value.number;
+ free_token($3);
+ }
+ } |
+
+ K_PP_CONTROLSTACK TKN_EQUAL num_list {
+ {
+ TOKEN * t;
+ unsigned nbytes;
+ int ok;
+
+ current_part->ctl_stack_type = CTL_STACK_PP;
+ nbytes = 0;
+ ok = 1;
+
+ memset(current_part->controlstack, 0, CTL_STACK_SIZE);
+ while (lsize(number_list)) {
+ t = lrmv_n(number_list, 1);
+ if (nbytes < CTL_STACK_SIZE)
+ {
+ current_part->controlstack[nbytes] = t->value.number;
+ nbytes++;
+ }
+ else
+ {
+ ok = 0;
+ }
+ free_token(t);
+ }
+ if (!ok)
+ {
+ yywarning("too many bytes in control stack");
+ }
+ }
+ } |
+
+ K_HVSP_CONTROLSTACK TKN_EQUAL num_list {
+ {
+ TOKEN * t;
+ unsigned nbytes;
+ int ok;
+
+ current_part->ctl_stack_type = CTL_STACK_HVSP;
+ nbytes = 0;
+ ok = 1;
+
+ memset(current_part->controlstack, 0, CTL_STACK_SIZE);
+ while (lsize(number_list)) {
+ t = lrmv_n(number_list, 1);
+ if (nbytes < CTL_STACK_SIZE)
+ {
+ current_part->controlstack[nbytes] = t->value.number;
+ nbytes++;
+ }
+ else
+ {
+ ok = 0;
+ }
+ free_token(t);
+ }
+ if (!ok)
+ {
+ yywarning("too many bytes in control stack");
+ }
+ }
+ } |
+
+ K_FLASH_INSTR TKN_EQUAL num_list {
+ {
+ TOKEN * t;
+ unsigned nbytes;
+ int ok;
+
+ nbytes = 0;
+ ok = 1;
+
+ memset(current_part->flash_instr, 0, FLASH_INSTR_SIZE);
+ while (lsize(number_list)) {
+ t = lrmv_n(number_list, 1);
+ if (nbytes < FLASH_INSTR_SIZE)
+ {
+ current_part->flash_instr[nbytes] = t->value.number;
+ nbytes++;
+ }
+ else
+ {
+ ok = 0;
+ }
+ free_token(t);
+ }
+ if (!ok)
+ {
+ yywarning("too many bytes in flash instructions");
+ }
+ }
+ } |
+
+ K_EEPROM_INSTR TKN_EQUAL num_list {
+ {
+ TOKEN * t;
+ unsigned nbytes;
+ int ok;
+
+ nbytes = 0;
+ ok = 1;
+
+ memset(current_part->eeprom_instr, 0, EEPROM_INSTR_SIZE);
+ while (lsize(number_list)) {
+ t = lrmv_n(number_list, 1);
+ if (nbytes < EEPROM_INSTR_SIZE)
+ {
+ current_part->eeprom_instr[nbytes] = t->value.number;
+ nbytes++;
+ }
+ else
+ {
+ ok = 0;
+ }
+ free_token(t);
+ }
+ if (!ok)
+ {
+ yywarning("too many bytes in EEPROM instructions");
+ }
+ }
+ } |
+
+ K_CHIP_ERASE_DELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->chip_erase_delay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_PAGEL TKN_EQUAL TKN_NUMBER
+ {
+ current_part->pagel = $3->value.number;
+ free_token($3);
+ } |
+
+ K_BS2 TKN_EQUAL TKN_NUMBER
+ {
+ current_part->bs2 = $3->value.number;
+ free_token($3);
+ } |
+
+ K_RESET TKN_EQUAL reset_disposition
+ {
+ if ($3->primary == K_DEDICATED)
+ current_part->reset_disposition = RESET_DEDICATED;
+ else if ($3->primary == K_IO)
+ current_part->reset_disposition = RESET_IO;
+
+ free_tokens(2, $1, $3);
+ } |
+
+ K_TIMEOUT TKN_EQUAL TKN_NUMBER
+ {
+ current_part->timeout = $3->value.number;
+ free_token($3);
+ } |
+
+ K_STABDELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->stabdelay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_CMDEXEDELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->cmdexedelay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_HVSPCMDEXEDELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->hvspcmdexedelay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_SYNCHLOOPS TKN_EQUAL TKN_NUMBER
+ {
+ current_part->synchloops = $3->value.number;
+ free_token($3);
+ } |
+
+ K_BYTEDELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->bytedelay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_POLLVALUE TKN_EQUAL TKN_NUMBER
+ {
+ current_part->pollvalue = $3->value.number;
+ free_token($3);
+ } |
+
+ K_POLLINDEX TKN_EQUAL TKN_NUMBER
+ {
+ current_part->pollindex = $3->value.number;
+ free_token($3);
+ } |
+
+ K_PREDELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->predelay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_POSTDELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->postdelay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_POLLMETHOD TKN_EQUAL TKN_NUMBER
+ {
+ current_part->pollmethod = $3->value.number;
+ free_token($3);
+ } |
+
+ K_HVENTERSTABDELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->hventerstabdelay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_PROGMODEDELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->progmodedelay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_LATCHCYCLES TKN_EQUAL TKN_NUMBER
+ {
+ current_part->latchcycles = $3->value.number;
+ free_token($3);
+ } |
+
+ K_TOGGLEVTG TKN_EQUAL TKN_NUMBER
+ {
+ current_part->togglevtg = $3->value.number;
+ free_token($3);
+ } |
+
+ K_POWEROFFDELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->poweroffdelay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_RESETDELAYMS TKN_EQUAL TKN_NUMBER
+ {
+ current_part->resetdelayms = $3->value.number;
+ free_token($3);
+ } |
+
+ K_RESETDELAYUS TKN_EQUAL TKN_NUMBER
+ {
+ current_part->resetdelayus = $3->value.number;
+ free_token($3);
+ } |
+
+ K_HVLEAVESTABDELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->hvleavestabdelay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_RESETDELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_part->resetdelay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_CHIPERASEPULSEWIDTH TKN_EQUAL TKN_NUMBER
+ {
+ current_part->chiperasepulsewidth = $3->value.number;
+ free_token($3);
+ } |
+
+ K_CHIPERASEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
+ {
+ current_part->chiperasepolltimeout = $3->value.number;
+ free_token($3);
+ } |
+
+ K_CHIPERASETIME TKN_EQUAL TKN_NUMBER
+ {
+ current_part->chiperasetime = $3->value.number;
+ free_token($3);
+ } |
+
+ K_PROGRAMFUSEPULSEWIDTH TKN_EQUAL TKN_NUMBER
+ {
+ current_part->programfusepulsewidth = $3->value.number;
+ free_token($3);
+ } |
+
+ K_PROGRAMFUSEPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
+ {
+ current_part->programfusepolltimeout = $3->value.number;
+ free_token($3);
+ } |
+
+ K_PROGRAMLOCKPULSEWIDTH TKN_EQUAL TKN_NUMBER
+ {
+ current_part->programlockpulsewidth = $3->value.number;
+ free_token($3);
+ } |
+
+ K_PROGRAMLOCKPOLLTIMEOUT TKN_EQUAL TKN_NUMBER
+ {
+ current_part->programlockpolltimeout = $3->value.number;
+ free_token($3);
+ } |
+
+ K_SYNCHCYCLES TKN_EQUAL TKN_NUMBER
+ {
+ current_part->synchcycles = $3->value.number;
+ free_token($3);
+ } |
+
+ K_HAS_JTAG TKN_EQUAL yesno
+ {
+ if ($3->primary == K_YES)
+ current_part->flags |= AVRPART_HAS_JTAG;
+ else if ($3->primary == K_NO)
+ current_part->flags &= ~AVRPART_HAS_JTAG;
+
+ free_token($3);
+ } |
+
+ K_HAS_DW TKN_EQUAL yesno
+ {
+ if ($3->primary == K_YES)
+ current_part->flags |= AVRPART_HAS_DW;
+ else if ($3->primary == K_NO)
+ current_part->flags &= ~AVRPART_HAS_DW;
+
+ free_token($3);
+ } |
+
+ K_HAS_PDI TKN_EQUAL yesno
+ {
+ if ($3->primary == K_YES)
+ current_part->flags |= AVRPART_HAS_PDI;
+ else if ($3->primary == K_NO)
+ current_part->flags &= ~AVRPART_HAS_PDI;
+
+ free_token($3);
+ } |
+
+ K_HAS_TPI TKN_EQUAL yesno
+ {
+ if ($3->primary == K_YES)
+ current_part->flags |= AVRPART_HAS_TPI;
+ else if ($3->primary == K_NO)
+ current_part->flags &= ~AVRPART_HAS_TPI;
+
+ free_token($3);
+ } |
+
+ K_IS_AT90S1200 TKN_EQUAL yesno
+ {
+ if ($3->primary == K_YES)
+ current_part->flags |= AVRPART_IS_AT90S1200;
+ else if ($3->primary == K_NO)
+ current_part->flags &= ~AVRPART_IS_AT90S1200;
+
+ free_token($3);
+ } |
+
+ K_IS_AVR32 TKN_EQUAL yesno
+ {
+ if ($3->primary == K_YES)
+ current_part->flags |= AVRPART_AVR32;
+ else if ($3->primary == K_NO)
+ current_part->flags &= ~AVRPART_AVR32;
+
+ free_token($3);
+ } |
+
+ K_ALLOWFULLPAGEBITSTREAM TKN_EQUAL yesno
+ {
+ if ($3->primary == K_YES)
+ current_part->flags |= AVRPART_ALLOWFULLPAGEBITSTREAM;
+ else if ($3->primary == K_NO)
+ current_part->flags &= ~AVRPART_ALLOWFULLPAGEBITSTREAM;
+
+ free_token($3);
+ } |
+
+ K_ENABLEPAGEPROGRAMMING TKN_EQUAL yesno
+ {
+ if ($3->primary == K_YES)
+ current_part->flags |= AVRPART_ENABLEPAGEPROGRAMMING;
+ else if ($3->primary == K_NO)
+ current_part->flags &= ~AVRPART_ENABLEPAGEPROGRAMMING;
+
+ free_token($3);
+ } |
+
+ K_IDR TKN_EQUAL TKN_NUMBER
+ {
+ current_part->idr = $3->value.number;
+ free_token($3);
+ } |
+
+ K_RAMPZ TKN_EQUAL TKN_NUMBER
+ {
+ current_part->rampz = $3->value.number;
+ free_token($3);
+ } |
+
+ K_SPMCR TKN_EQUAL TKN_NUMBER
+ {
+ current_part->spmcr = $3->value.number;
+ free_token($3);
+ } |
+
+ K_EECR TKN_EQUAL TKN_NUMBER
+ {
+ current_part->eecr = $3->value.number;
+ free_token($3);
+ } |
+
+ K_MCU_BASE TKN_EQUAL TKN_NUMBER
+ {
+ current_part->mcu_base = $3->value.number;
+ free_token($3);
+ } |
+
+ K_NVM_BASE TKN_EQUAL TKN_NUMBER
+ {
+ current_part->nvm_base = $3->value.number;
+ free_token($3);
+ } |
+
+ K_OCDREV TKN_EQUAL TKN_NUMBER
+ {
+ current_part->ocdrev = $3->value.number;
+ free_token($3);
+ } |
+
+ K_SERIAL TKN_EQUAL yesno
+ {
+ if ($3->primary == K_YES)
+ current_part->flags |= AVRPART_SERIALOK;
+ else if ($3->primary == K_NO)
+ current_part->flags &= ~AVRPART_SERIALOK;
+
+ free_token($3);
+ } |
+
+ K_PARALLEL TKN_EQUAL parallel_modes
+ {
+ if ($3->primary == K_YES) {
+ current_part->flags |= AVRPART_PARALLELOK;
+ current_part->flags &= ~AVRPART_PSEUDOPARALLEL;
+ }
+ else if ($3->primary == K_NO) {
+ current_part->flags &= ~AVRPART_PARALLELOK;
+ current_part->flags &= ~AVRPART_PSEUDOPARALLEL;
+ }
+ else if ($3->primary == K_PSEUDO) {
+ current_part->flags |= AVRPART_PARALLELOK;
+ current_part->flags |= AVRPART_PSEUDOPARALLEL;
+ }
+
+
+ free_token($3);
+ } |
+
+ K_RETRY_PULSE TKN_EQUAL retry_lines
+ {
+ switch ($3->primary) {
+ case K_RESET :
+ current_part->retry_pulse = PIN_AVR_RESET;
+ break;
+ case K_SCK :
+ current_part->retry_pulse = PIN_AVR_SCK;
+ break;
+ }
+
+ free_token($1);
+ } |
+
+
+/*
+ K_EEPROM { current_mem = AVR_M_EEPROM; }
+ mem_specs |
+
+ K_FLASH { current_mem = AVR_M_FLASH; }
+ mem_specs |
+*/
+
+ K_MEMORY TKN_STRING
+ {
+ current_mem = avr_new_memtype();
+ if (current_mem == NULL) {
+ yyerror("could not create mem instance");
+ free_token($2);
+ YYABORT;
+ }
+ strncpy(current_mem->desc, $2->value.string, AVR_MEMDESCLEN);
+ current_mem->desc[AVR_MEMDESCLEN-1] = 0;
+ free_token($2);
+ }
+ mem_specs
+ {
+ AVRMEM * existing_mem;
+
+ existing_mem = avr_locate_mem(current_part, current_mem->desc);
+ if (existing_mem != NULL) {
+ lrmv_d(current_part->mem, existing_mem);
+ avr_free_mem(existing_mem);
+ }
+ ladd(current_part->mem, current_mem);
+ current_mem = NULL;
+ } |
+
+ opcode TKN_EQUAL string_list {
+ {
+ int opnum;
+ OPCODE * op;
+
+ opnum = which_opcode($1);
+ if (opnum < 0) YYABORT;
+ op = avr_new_opcode();
+ if (op == NULL) {
+ yyerror("could not create opcode instance");
+ free_token($1);
+ YYABORT;
+ }
+ if(0 != parse_cmdbits(op)) YYABORT;
+ if (current_part->op[opnum] != NULL) {
+ /*yywarning("operation redefined");*/
+ avr_free_opcode(current_part->op[opnum]);
+ }
+ current_part->op[opnum] = op;
+
+ free_token($1);
+ }
+ }
+;
+
+
+yesno :
+ K_YES | K_NO
+;
+
+
+mem_specs :
+ mem_spec TKN_SEMI |
+ mem_specs mem_spec TKN_SEMI
+;
+
+
+mem_spec :
+ K_PAGED TKN_EQUAL yesno
+ {
+ current_mem->paged = $3->primary == K_YES ? 1 : 0;
+ free_token($3);
+ } |
+
+ K_SIZE TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->size = $3->value.number;
+ free_token($3);
+ } |
+
+
+ K_PAGE_SIZE TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->page_size = $3->value.number;
+ free_token($3);
+ } |
+
+ K_NUM_PAGES TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->num_pages = $3->value.number;
+ free_token($3);
+ } |
+
+ K_OFFSET TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->offset = $3->value.number;
+ free_token($3);
+ } |
+
+ K_MIN_WRITE_DELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->min_write_delay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_MAX_WRITE_DELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->max_write_delay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_PWROFF_AFTER_WRITE TKN_EQUAL yesno
+ {
+ current_mem->pwroff_after_write = $3->primary == K_YES ? 1 : 0;
+ free_token($3);
+ } |
+
+ K_READBACK_P1 TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->readback[0] = $3->value.number;
+ free_token($3);
+ } |
+
+ K_READBACK_P2 TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->readback[1] = $3->value.number;
+ free_token($3);
+ } |
+
+
+ K_MODE TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->mode = $3->value.number;
+ free_token($3);
+ } |
+
+ K_DELAY TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->delay = $3->value.number;
+ free_token($3);
+ } |
+
+ K_BLOCKSIZE TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->blocksize = $3->value.number;
+ free_token($3);
+ } |
+
+ K_READSIZE TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->readsize = $3->value.number;
+ free_token($3);
+ } |
+
+ K_POLLINDEX TKN_EQUAL TKN_NUMBER
+ {
+ current_mem->pollindex = $3->value.number;
+ free_token($3);
+ } |
+
+
+ opcode TKN_EQUAL string_list {
+ {
+ int opnum;
+ OPCODE * op;
+
+ opnum = which_opcode($1);
+ if (opnum < 0) YYABORT;
+ op = avr_new_opcode();
+ if (op == NULL) {
+ yyerror("could not create opcode instance");
+ free_token($1);
+ YYABORT;
+ }
+ if(0 != parse_cmdbits(op)) YYABORT;
+ if (current_mem->op[opnum] != NULL) {
+ /*yywarning("operation redefined");*/
+ avr_free_opcode(current_mem->op[opnum]);
+ }
+ current_mem->op[opnum] = op;
+
+ free_token($1);
+ }
+ }
+;
+
+
+%%
+
+#if 0
+static char * vtypestr(int type)
+{
+ switch (type) {
+ case V_NUM : return "INTEGER";
+ case V_NUM_REAL: return "REAL";
+ case V_STR : return "STRING";
+ default:
+ return "<UNKNOWN>";
+ }
+}
+#endif
+
+
+static int assign_pin(int pinno, TOKEN * v, int invert)
+{
+ int value;
+
+ value = v->value.number;
+ free_token(v);
+
+ if ((value < PIN_MIN) || (value > PIN_MAX)) {
+ yyerror("pin must be in the range " TOSTRING(PIN_MIN) "-" TOSTRING(PIN_MAX));
+ return -1;
+ }
+
+ pin_set_value(&(current_prog->pin[pinno]), value, invert);
+
+ return 0;
+}
+
+static int assign_pin_list(int invert)
+{
+ TOKEN * t;
+ int pin;
+ int rv = 0;
+
+ current_prog->pinno[pin_name] = 0;
+ while (lsize(number_list)) {
+ t = lrmv_n(number_list, 1);
+ if (rv == 0) {
+ pin = t->value.number;
+ if ((pin < PIN_MIN) || (pin > PIN_MAX)) {
+ yyerror("pin must be in the range " TOSTRING(PIN_MIN) "-" TOSTRING(PIN_MAX));
+ rv = -1;
+ /* loop clears list and frees tokens */
+ }
+ pin_set_value(&(current_prog->pin[pin_name]), pin, invert);
+ }
+ free_token(t);
+ }
+ return rv;
+}
+
+static int which_opcode(TOKEN * opcode)
+{
+ switch (opcode->primary) {
+ case K_READ : return AVR_OP_READ; break;
+ case K_WRITE : return AVR_OP_WRITE; break;
+ case K_READ_LO : return AVR_OP_READ_LO; break;
+ case K_READ_HI : return AVR_OP_READ_HI; break;
+ case K_WRITE_LO : return AVR_OP_WRITE_LO; break;
+ case K_WRITE_HI : return AVR_OP_WRITE_HI; break;
+ case K_LOADPAGE_LO : return AVR_OP_LOADPAGE_LO; break;
+ case K_LOADPAGE_HI : return AVR_OP_LOADPAGE_HI; break;
+ case K_LOAD_EXT_ADDR : return AVR_OP_LOAD_EXT_ADDR; break;
+ case K_WRITEPAGE : return AVR_OP_WRITEPAGE; break;
+ case K_CHIP_ERASE : return AVR_OP_CHIP_ERASE; break;
+ case K_PGM_ENABLE : return AVR_OP_PGM_ENABLE; break;
+ default :
+ yyerror("invalid opcode");
+ return -1;
+ break;
+ }
+}
+
+
+static int parse_cmdbits(OPCODE * op)
+{
+ TOKEN * t;
+ int bitno;
+ char ch;
+ char * e;
+ char * q;
+ int len;
+ char * s, *brkt = NULL;
+ int rv = 0;
+
+ bitno = 32;
+ while (lsize(string_list)) {
+
+ t = lrmv_n(string_list, 1);
+
+ s = strtok_r(t->value.string, " ", &brkt);
+ while (rv == 0 && s != NULL) {
+
+ bitno--;
+ if (bitno < 0) {
+ yyerror("too many opcode bits for instruction");
+ rv = -1;
+ break;
+ }
+
+ len = strlen(s);
+
+ if (len == 0) {
+ yyerror("invalid bit specifier \"\"");
+ rv = -1;
+ break;
+ }
+
+ ch = s[0];
+
+ if (len == 1) {
+ switch (ch) {
+ case '1':
+ op->bit[bitno].type = AVR_CMDBIT_VALUE;
+ op->bit[bitno].value = 1;
+ op->bit[bitno].bitno = bitno % 8;
+ break;
+ case '0':
+ op->bit[bitno].type = AVR_CMDBIT_VALUE;
+ op->bit[bitno].value = 0;
+ op->bit[bitno].bitno = bitno % 8;
+ break;
+ case 'x':
+ op->bit[bitno].type = AVR_CMDBIT_IGNORE;
+ op->bit[bitno].value = 0;
+ op->bit[bitno].bitno = bitno % 8;
+ break;
+ case 'a':
+ op->bit[bitno].type = AVR_CMDBIT_ADDRESS;
+ op->bit[bitno].value = 0;
+ op->bit[bitno].bitno = 8*(bitno/8) + bitno % 8;
+ break;
+ case 'i':
+ op->bit[bitno].type = AVR_CMDBIT_INPUT;
+ op->bit[bitno].value = 0;
+ op->bit[bitno].bitno = bitno % 8;
+ break;
+ case 'o':
+ op->bit[bitno].type = AVR_CMDBIT_OUTPUT;
+ op->bit[bitno].value = 0;
+ op->bit[bitno].bitno = bitno % 8;
+ break;
+ default :
+ yyerror("invalid bit specifier '%c'", ch);
+ rv = -1;
+ break;
+ }
+ }
+ else {
+ if (ch == 'a') {
+ q = &s[1];
+ op->bit[bitno].bitno = strtol(q, &e, 0);
+ if ((e == q)||(*e != 0)) {
+ yyerror("can't parse bit number from \"%s\"", q);
+ rv = -1;
+ break;
+ }
+ op->bit[bitno].type = AVR_CMDBIT_ADDRESS;
+ op->bit[bitno].value = 0;
+ }
+ else {
+ yyerror("invalid bit specifier \"%s\"", s);
+ rv = -1;
+ break;
+ }
+ }
+
+ s = strtok_r(NULL, " ", &brkt);
+ } /* while */
+
+ free_token(t);
+
+ } /* while */
+
+ return rv;
+}
diff --git a/xs/src/avrdude/configure.ac b/xs/src/avrdude/configure.ac
new file mode 100644
index 000000000..a23a959f2
--- /dev/null
+++ b/xs/src/avrdude/configure.ac
@@ -0,0 +1,572 @@
+#
+# 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$
+#
+
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.60)
+AC_INIT(avrdude, 6.3-20160220, avrdude-dev@nongnu.org)
+
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+AC_CONFIG_SRCDIR([main.c])
+AM_INIT_AUTOMAKE
+AC_CONFIG_HEADERS(ac_cfg.h)
+AC_CONFIG_MACRO_DIR([m4])
+
+LT_INIT()
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_SED
+AC_PROG_YACC
+AC_PROG_LEX
+AN_MAKEVAR([AR], [AC_PROG_AR])
+AN_PROGRAM([ar], [AC_PROG_AR])
+AC_DEFUN([AC_PROG_AR], [AC_CHECK_TARGET_TOOL(AR, ar, :)])
+AC_PROG_AR
+AH_TEMPLATE([HAVE_YYLEX_DESTROY],
+ [Define if lex/flex has yylex_destroy])
+# flex should have this
+if test "x$LEX" == xflex; then
+ AC_MSG_CHECKING([whether yylex_destroy is generated by flex])
+ flex_version=`$LEX -V -v --version 2>/dev/null | $SED -e 's/^.* //'`
+ case $flex_version in
+ [[0-1].*)]
+ AC_MSG_RESULT([version $flex_version => no])
+ ;;
+ [2.[0-4].*)]
+ AC_MSG_RESULT([version $flex_version => no])
+ ;;
+ [2.5.[0-8])]
+ AC_MSG_RESULT([version $flex_version => no])
+ ;;
+ [2.5.[0-8][A-Za-z]*)]
+ AC_MSG_RESULT([version $flex_version => no])
+ ;;
+ *)
+ AC_MSG_RESULT([version $flex_version => yes])
+ AC_DEFINE([HAVE_YYLEX_DESTROY])
+ ;;
+ esac
+fi
+
+dnl Makefile.am:77: compiling `config_gram.c' with per-target flags requires `AM_PROG_CC_C_O' in `configure.ac'
+AM_PROG_CC_C_O
+
+# Checks for libraries.
+AC_CHECK_LIB([termcap], [tputs])
+AC_CHECK_LIB([ncurses], [tputs])
+AC_CHECK_LIB([readline], [readline])
+AH_TEMPLATE([HAVE_LIBELF],
+ [Define if ELF support is enabled via libelf])
+AC_CHECK_LIB([elf], [elf_getshdrstrndx], [have_libelf=yes])
+if test x$have_libelf = xyes; then
+ case $target in
+ *)
+ LIBELF="-lelf"
+ ;;
+ esac
+ AC_DEFINE([HAVE_LIBELF])
+ AC_CHECK_HEADERS([libelf.h libelf/libelf.h])
+fi
+AC_SUBST(LIBELF, $LIBELF)
+
+AC_SEARCH_LIBS([gethostent], [nsl])
+AC_SEARCH_LIBS([setsockopt], [socket])
+AH_TEMPLATE([HAVE_LIBUSB],
+ [Define if USB support is enabled via libusb])
+AC_CHECK_LIB([usb], [usb_get_string_simple], [have_libusb=yes])
+if test x$have_libusb = xyes; then
+ case $target in
+ *-*-darwin*)
+ LIBUSB="-lusb -framework CoreFoundation -framework IOKit"
+ ;;
+ *)
+ LIBUSB="-lusb"
+ ;;
+ esac
+ AC_DEFINE([HAVE_LIBUSB])
+ AC_CHECK_HEADERS([usb.h])
+ AC_CHECK_HEADERS([lusb0_usb.h])
+fi
+AC_SUBST(LIBUSB, $LIBUSB)
+
+AH_TEMPLATE([HAVE_LIBUSB_1_0],
+ [Define if USB support is enabled via libusb 1.0])
+AC_CHECK_LIB([usb-1.0], [libusb_init], [have_libusb_1_0=yes])
+if test x$have_libusb_1_0 = xyes; then
+ case $target in
+ *-*-darwin*)
+ LIBUSB_1_0="-lusb-1.0 -framework CoreFoundation -framework IOKit"
+ ;;
+ *)
+ LIBUSB_1_0="-lusb-1.0"
+ ;;
+ esac
+ AC_DEFINE([HAVE_LIBUSB_1_0])
+ AC_CHECK_HEADERS([libusb-1.0/libusb.h])
+ AC_CHECK_HEADERS([libusb.h])
+fi
+AH_TEMPLATE([HAVE_LIBUSB_1_0],
+ [Define if USB support is enabled via a libusb-1.0 compatible libusb])
+AC_CHECK_LIB([usb], [libusb_init], [have_libusb_1_0=yes])
+if test x$have_libusb_1_0 = xyes; then
+ case $target in
+ *-*-freebsd*)
+ # FreeBSD 8+ has a native libusb-1.0 API compatible
+ # library offered by -lusb (which is also libusb-0.1
+ # compatible). FreeBSD <8 does not have a libusb-1.0
+ # at all so probing will fail but we do not have to
+ # special-case that.
+ LIBUSB_1_0="-lusb"
+ ;;
+ *)
+ LIBUSB_1_0="-lusb-1.0"
+ ;;
+ esac
+ AC_DEFINE([HAVE_LIBUSB_1_0])
+ AC_CHECK_HEADERS([libusb.h])
+fi
+AC_SUBST(LIBUSB_1_0, $LIBUSB_1_0)
+
+AH_TEMPLATE([HAVE_LIBHIDAPI],
+ [Define if HID support is enabled via libhidapi])
+AC_SEARCH_LIBS([hid_init], [hidapi hidapi-libusb hidapi-hidraw], [have_libhidapi=yes])
+if test x$have_libhidapi = xyes; then
+ case $target in
+ *-*-darwin*)
+ LIBHIDAPI="-lhidapi -iframework CoreFoundation -framework IOKit"
+ ;;
+ *)
+ LIBHIDAPI="$ac_cv_lib_hid_init"
+ ;;
+ esac
+ AC_DEFINE([HAVE_LIBHIDAPI])
+ AC_CHECK_HEADERS([hidapi/hidapi.h])
+fi
+AC_SUBST(LIBHIDAPI, $LIBHIDAPI)
+
+
+AH_TEMPLATE([HAVE_LIBFTDI1],
+ [Define if FTDI support is enabled via libftdi1])
+AH_TEMPLATE([HAVE_LIBFTDI],
+ [Define if FTDI support is enabled via libftdi])
+AH_TEMPLATE([HAVE_LIBFTDI_TYPE_232H],
+ [Define if libftdi supports FT232H, libftdi version >= 0.20])
+AC_CHECK_LIB([ftdi1], [ftdi_new], [have_libftdi1=yes], [], [$LIBUSB_1_0])
+AC_CHECK_LIB([ftdi], [ftdi_usb_get_strings], [have_libftdi=yes], [], [-lusb])
+if test x$have_libftdi1 = xyes; then
+ LIBFTDI1="-lftdi1"
+ AC_DEFINE([HAVE_LIBFTDI1])
+ AC_SUBST(LIBFTDI1, $LIBFTDI1)
+else
+ if test x$have_libftdi = xyes; then
+ LIBFTDI="-lftdi -lusb"
+ AC_DEFINE([HAVE_LIBFTDI])
+ AC_SUBST(LIBFTDI, $LIBFTDI)
+ AC_CHECK_DECL(TYPE_232H,[have_libftdi_FT232H=yes], [], [[#include <ftdi.h>]])
+ if test x$have_libftdi_FT232H = xyes; then
+ AC_DEFINE([HAVE_LIBFTDI_TYPE_232H])
+ fi
+ fi
+fi
+AC_CHECK_HEADERS([pthread.h])
+# as there exits header file only pthread implementations for Windows, check if we have a library
+AC_CHECK_LIB([pthread], [pthread_create], [have_pthread=yes])
+if test x$have_pthread = xyes; then
+ LIBPTHREAD="-lpthread"
+fi
+AC_SUBST(LIBPTHREAD, $LIBPTHREAD)
+# Checks for header files.
+AC_CHECK_HEADERS([limits.h stdlib.h string.h])
+AC_CHECK_HEADERS([fcntl.h sys/ioctl.h sys/time.h termios.h unistd.h])
+AC_CHECK_HEADERS([ddk/hidsdi.h],,,[#include <windows.h>
+#include <setupapi.h>])
+
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_HEADER_TIME
+
+# WinSock2
+AC_CHECK_LIB([ws2_32], [puts])
+
+# Checks for library functions.
+AC_CHECK_FUNCS([memset select strcasecmp strdup strerror strncasecmp strtol strtoul gettimeofday usleep])
+
+AC_MSG_CHECKING([for a Win32 HID libray])
+SAVED_LIBS="${LIBS}"
+case $target in
+ *-*-mingw32* | *-*-cygwin* | *-*-windows*)
+ LIBHID="-lhid -lsetupapi"
+ if test $ac_cv_header_ddk_hidsdi_h = yes
+ then
+ HIDINCLUDE="#include <ddk/hidsdi.h>"
+ else
+ HIDINCLUDE="#include \"my_ddk_hidsdi.h\""
+ fi
+ ;;
+ *)
+ LIBHID=""
+ ;;
+esac
+LIBS="${LIBS} ${LIBHID}"
+
+AH_TEMPLATE([HAVE_LIBHID],
+ [Define if HID support is enabled via the Win32 DDK])
+AC_TRY_LINK([#include <windows.h>
+#include <setupapi.h>
+$HIDINCLUDE],
+[int
+main(void)
+{
+ GUID hidGuid;
+ HidD_GetHidGuid(&hidGuid);
+
+ return 0;
+}
+], [have_libhid=yes], [have_libhid=no])
+AC_MSG_RESULT([$have_libhid])
+if test x$have_libhid = xyes; then
+ AC_DEFINE([HAVE_LIBHID])
+else
+ LIBHID=""
+fi
+LIBS="${SAVED_LIBS}"
+AC_SUBST(LIBHID, $LIBHID)
+
+# Check for types
+
+# Solaris has uint_t and ulong_t typedefs in <sys/types.h>, avoid
+# the redeclaration in usbtiny.c.
+AC_CHECK_TYPES([uint_t], [], [], [#include <sys/types.h>])
+AC_CHECK_TYPES([ulong_t], [], [], [#include <sys/types.h>])
+
+# Checks for misc stuff.
+
+AC_ARG_ENABLE(
+ [versioned-doc],
+ AC_HELP_STRING(
+ [--enable-versioned-doc],
+ [install docs in directory with version name (default)]),
+ [case "${enableval}" in
+ yes) versioned_doc=yes ;;
+ no) versioned_doc=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for versioned-doc option) ;;
+ esac],
+ [versioned_doc=yes])
+
+if test "$versioned_doc" = "yes"; then
+ DOC_INST_DIR='$(DESTDIR)$(datadir)/doc/avrdude-$(VERSION)'
+else
+ DOC_INST_DIR='$(DESTDIR)$(datadir)/doc/avrdude'
+fi
+
+AC_ARG_ENABLE(
+ [doc],
+ AC_HELP_STRING(
+ [--enable-doc],
+ [Enable building documents]),
+ [case "${enableval}" in
+ yes) enabled_doc=yes ;;
+ no) enabled_doc=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for disable-doc option) ;;
+ esac],
+ [enabled_doc=no])
+
+AC_ARG_ENABLE(
+ [parport],
+ AC_HELP_STRING(
+ [--enable-parport],
+ [Enable accessing parallel ports(default)]),
+ [case "${enableval}" in
+ yes) enabled_parport=yes ;;
+ no) enabled_parport=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for enable-parport option) ;;
+ esac],
+ [enabled_parport=yes])
+
+AC_ARG_ENABLE(
+ [linuxgpio],
+ AC_HELP_STRING(
+ [--enable-linuxgpio],
+ [Enable the Linux sysfs GPIO interface programmer type]),
+ [case "${enableval}" in
+ yes) enabled_linuxgpio=yes ;;
+ no) enabled_linuxgpio=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for enable-linuxgpio option) ;;
+ esac],
+ [enabled_linuxgpio=no])
+
+DIST_SUBDIRS_AC='doc windows'
+
+if test "$enabled_doc" = "yes"; then
+ SUBDIRS_AC='doc'
+else
+ SUBDIRS_AC=''
+fi
+
+AC_SUBST(DOC_INST_DIR, $DOC_INST_DIR)
+AC_SUBST(SUBDIRS_AC, $SUBDIRS_AC)
+AC_SUBST(DIST_SUBDIRS_AC, $DIST_SUBDIRS_AC)
+
+
+# Find the parallel serial device files based on target system
+# If a system doesn't have a PC style parallel, mark it as unknown.
+case $target in
+ i[[3456]]86-*-linux*|x86_64-*-linux*)
+ DEFAULT_PAR_PORT="/dev/parport0"
+ DEFAULT_SER_PORT="/dev/ttyS0"
+ ;;
+ *-*-linux*)
+ DEFAULT_PAR_PORT="unknown"
+ DEFAULT_SER_PORT="/dev/ttyS0"
+ ;;
+ i[[3456]]86-*-*freebsd*|amd64-*-*freebsd*)
+ DEFAULT_PAR_PORT="/dev/ppi0"
+ DEFAULT_SER_PORT="/dev/cuad0"
+ ;;
+ *-*-*freebsd*)
+ DEFAULT_PAR_PORT="unknown"
+ DEFAULT_SER_PORT="/dev/cuad0"
+ ;;
+ *-*-solaris*)
+ DEFAULT_PAR_PORT="/dev/printers/0"
+ DEFAULT_SER_PORT="/dev/term/a"
+ ;;
+ *-*-msdos* | *-*-mingw32* | *-*-cygwin* | *-*-windows*)
+ DEFAULT_PAR_PORT="lpt1"
+ DEFAULT_SER_PORT="com1"
+ ;;
+ *)
+ DEFAULT_PAR_PORT="unknown"
+ DEFAULT_SER_PORT="unknown"
+ ;;
+esac
+
+if test "$enabled_parport" = "yes"; then
+ AC_MSG_CHECKING([for parallel device])
+ if test "$DEFAULT_PAR_PORT" = "unknown"; then
+ AC_MSG_NOTICE([parallel port access disabled for this system])
+ enabled_parport=no
+ else
+ AC_MSG_RESULT([$DEFAULT_PAR_PORT])
+ fi
+ AC_SUBST(DEFAULT_PAR_PORT, $DEFAULT_PAR_PORT)
+fi
+
+AC_MSG_CHECKING([for serial device])
+AC_MSG_RESULT([$DEFAULT_SER_PORT])
+AC_SUBST(DEFAULT_SER_PORT, $DEFAULT_SER_PORT)
+
+if test "$enabled_parport" = "yes"; then
+ AC_DEFINE(HAVE_PARPORT, 1, [parallel port access enabled])
+ confsubst="-e /^@HAVE_PARPORT_/d"
+else
+ confsubst="-e /^@HAVE_PARPORT_BEGIN@/,/^@HAVE_PARPORT_END@/d"
+fi
+
+
+if test "$enabled_linuxgpio" = "yes"; then
+ AC_DEFINE(HAVE_LINUXGPIO, 1, [Linux sysfs GPIO support enabled])
+ confsubst="$confsubst -e /^@HAVE_LINUXGPIO_/d"
+else
+ confsubst="$confsubst -e /^@HAVE_LINUXGPIO_BEGIN@/,/^@HAVE_LINUXGPIO_END@/d"
+fi
+
+
+# If we are compiling with gcc, enable all warning and make warnings errors.
+if test "$GCC" = yes; then
+ ENABLE_WARNINGS="-Wall"
+
+ # does this compiler support -Wno-pointer-sign ?
+ AC_MSG_CHECKING([if gcc accepts -Wno-pointer-sign ])
+
+ safe_CFLAGS=$CFLAGS
+ CFLAGS="$ENABLE_WARNINGS -Wno-pointer-sign"
+
+ AC_TRY_COMPILE(, [ int main () { return 0 ; } ], [
+ no_pointer_sign=yes
+ AC_MSG_RESULT([yes])
+ ], [
+ no_pointer_sign=no
+ AC_MSG_RESULT([no])
+ ])
+ CFLAGS=$safe_CFLAGS
+
+ if test x$no_pointer_sign = xyes; then
+ ENABLE_WARNINGS="$ENABLE_WARNINGS -Wno-pointer-sign"
+ fi
+fi
+AC_SUBST(ENABLE_WARNINGS,$ENABLE_WARNINGS)
+
+# See if we need to drop into the windows subdir.
+case $target in
+ *-*-mingw32* | *-*-cygwin* | *-*-windows*)
+ if test "$GCC" = yes -a \( "$CC" = "cc" -o "$CC" = "gcc" \); then
+ # does this compiler support -mno-cygwin?
+ AC_MSG_CHECKING([if $CC accepts -mno-cygwin])
+
+ safe_CFLAGS="$CFLAGS"
+ CFLAGS="$ENABLE_WARNINGS -mno-cygwin"
+
+ AC_TRY_COMPILE(, [ int main () { return 0 ; } ], [
+ no_cygwin=yes
+ AC_MSG_RESULT([yes])
+ ], [
+ no_cygwin=no
+ AC_MSG_RESULT([no])
+ ])
+ CFLAGS="$safe_CFLAGS"
+
+ if test x$no_cygwin = xyes; then
+ CFLAGS="${CFLAGS} -mno-cygwin"
+ else
+ AC_MSG_NOTICE([Your compiler does not understand the -mno-cygwin option.])
+ AC_MSG_NOTICE([You might want to select an alternative compiler, like])
+ AC_MSG_NOTICE([])
+ AC_MSG_NOTICE([CC=mingw32-gcc ./configure])
+ AC_MSG_NOTICE([])
+ fi
+ fi
+
+ AC_MSG_CHECKING([if linker accepts -static])
+
+ safe_LDFLAGS="$LDFLAGS"
+ LDFLAGS="${LDFLAGS} -static"
+ AC_TRY_LINK(, [ int main () { return 0 ; } ], [
+ can_link_static=yes
+ AC_MSG_RESULT([yes])
+ ], [
+ can_link_static_cygwin=no
+ AC_MSG_RESULT([no])
+ ])
+ LDFLAGS="$safe_LDFLAGS"
+
+ if test x$can_link_static = xyes; then
+ LDFLAGS="${LDFLAGS} -static"
+ fi
+
+ WINDOWS_DIRS="windows"
+ CFLAGS="${CFLAGS} -DWIN32NATIVE"
+ ;;
+esac
+AC_SUBST(WINDOWS_DIRS,$WINDOWS_DIRS)
+
+AC_CONFIG_FILES([
+ doc/Makefile
+ windows/Makefile
+ avrdude.spec
+ Makefile
+])
+
+# The procedure to create avrdude.conf involves two steps. First,
+# normal autoconf substitution will be applied, resulting in
+# avrdude.conf.tmp. Finally, a sed command will be applied to filter
+# out unwanted parts (currently the parallel port programmer types)
+# based on previous configuration results, thereby producing the final
+# avrdude.conf file.
+
+AC_CONFIG_FILES([avrdude.conf.tmp:avrdude.conf.in],
+ [sed $confsubst avrdude.conf.tmp > avrdude.conf],
+ [confsubst="$confsubst"])
+
+AC_OUTPUT
+
+echo ""
+echo ""
+echo "Configuration summary:"
+echo "----------------------"
+
+if test x$have_libelf = xyes; then
+ echo "DO HAVE libelf"
+else
+ echo "DON'T HAVE libelf"
+fi
+
+if test x$have_libusb = xyes; then
+ echo "DO HAVE libusb"
+else
+ echo "DON'T HAVE libusb"
+fi
+
+if test x$have_libusb_1_0 = xyes; then
+ echo "DO HAVE libusb_1_0"
+else
+ echo "DON'T HAVE libusb_1_0"
+fi
+
+if test x$have_libftdi1 = xyes; then
+ echo "DO HAVE libftdi1"
+else
+ echo "DON'T HAVE libftdi1"
+fi
+
+if test x$have_libftdi = xyes; then
+ if test x$have_libftdi1 = xyes; then
+ echo "DO HAVE libftdi (but prefer to use libftdi1)"
+ else
+ echo "DO HAVE libftdi"
+ fi
+else
+ echo "DON'T HAVE libftdi"
+fi
+
+if test x$have_libhid = xyes; then
+ echo "DO HAVE libhid"
+else
+ echo "DON'T HAVE libhid"
+fi
+
+if test x$have_libhidapi = xyes; then
+ echo "DO HAVE libhidapi"
+else
+ echo "DON'T HAVE libhidapi"
+fi
+
+if test x$have_pthread = xyes; then
+ echo "DO HAVE pthread"
+else
+ echo "DON'T HAVE pthread"
+fi
+
+if test x$enabled_doc = xyes; then
+ echo "ENABLED doc"
+else
+ echo "DISABLED doc"
+fi
+
+if test x$enabled_parport = xyes; then
+ echo "ENABLED parport"
+else
+ echo "DISABLED parport"
+fi
+
+if test x$enabled_linuxgpio = xyes; then
+ echo "ENABLED linuxgpio"
+else
+ echo "DISABLED linuxgpio"
+fi
+
diff --git a/xs/src/avrdude/confwin.c b/xs/src/avrdude/confwin.c
new file mode 100644
index 000000000..95446156d
--- /dev/null
+++ b/xs/src/avrdude/confwin.c
@@ -0,0 +1,54 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003-2004 Eric B. Weddington <eric@ecentral.com>
+ *
+ * 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/>.
+ */
+
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#if defined(WIN32NATIVE)
+
+#include <limits.h>
+#include <windows.h>
+
+
+static char *filename;
+
+
+void win_sys_config_set(char sys_config[PATH_MAX])
+{
+ sys_config[0] = 0;
+
+ /* Use Windows API call to search for the Windows default system config file.*/
+ SearchPath(NULL, "avrdude.conf", NULL, PATH_MAX, sys_config, &filename);
+ return;
+}
+
+
+void win_usr_config_set(char usr_config[PATH_MAX])
+{
+ usr_config[0] = 0;
+
+ /* Use Windows API call to search for the Windows default user config file. */
+ SearchPath(NULL, "avrdude.rc", NULL, PATH_MAX, usr_config, &filename);
+ return;
+}
+
+
+#endif
+
+
diff --git a/xs/src/avrdude/crc16.c b/xs/src/avrdude/crc16.c
new file mode 100644
index 000000000..0177c9dab
--- /dev/null
+++ b/xs/src/avrdude/crc16.c
@@ -0,0 +1,83 @@
+/*
+ * Derived from CRC algorithm for JTAG ICE mkII, published in Atmel
+ * Appnote AVR067. Converted from C++ to C.
+ */
+#include "crc16.h"
+
+/* CRC16 Definitions */
+static const unsigned short crc_table[256] = {
+ 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+ 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+ 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+ 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+ 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+ 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+ 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+ 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+ 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+ 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+ 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+ 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+ 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+ 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+ 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+ 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+ 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+ 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+ 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+ 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+ 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+ 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+ 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+ 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+ 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+ 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+ 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+ 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+ 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+ 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+ 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+ 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+/* CRC calculation macros */
+#define CRC_INIT 0xFFFF
+#define CRC(crcval,newchar) crcval = (crcval >> 8) ^ \
+ crc_table[(crcval ^ newchar) & 0x00ff]
+
+unsigned short
+crcsum(const unsigned char* message, unsigned long length,
+ unsigned short crc)
+{
+ unsigned long i;
+
+ for(i = 0; i < length; i++)
+ {
+ CRC(crc, message[i]);
+ }
+ return crc;
+}
+
+int
+crcverify(const unsigned char* message, unsigned long length)
+{
+ /*
+ * Returns true if the last two bytes in a message is the crc of the
+ * preceding bytes.
+ */
+ unsigned short expected;
+
+ expected = crcsum(message, length - 2, CRC_INIT);
+ return (expected & 0xff) == message[length - 2] &&
+ ((expected >> 8) & 0xff) == message[length - 1];
+}
+
+void
+crcappend(unsigned char* message, unsigned long length)
+{
+ unsigned long crc;
+
+ crc = crcsum(message, length, CRC_INIT);
+ message[length] = (unsigned char)(crc & 0xff);
+ message[length+1] = (unsigned char)((crc >> 8) & 0xff);
+}
diff --git a/xs/src/avrdude/crc16.h b/xs/src/avrdude/crc16.h
new file mode 100644
index 000000000..db10131de
--- /dev/null
+++ b/xs/src/avrdude/crc16.h
@@ -0,0 +1,34 @@
+#ifndef CRC16_H
+#define CRC16_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Derived from CRC algorithm for JTAG ICE mkII, published in Atmel
+ * Appnote AVR067. Converted from C++ to C.
+ */
+
+extern unsigned short crcsum(const unsigned char* message,
+ unsigned long length,
+ unsigned short crc);
+/*
+ * Verify that the last two bytes is a (LSB first) valid CRC of the
+ * message.
+ */
+extern int crcverify(const unsigned char* message,
+ unsigned long length);
+/*
+ * Append a two byte CRC (LSB first) to message. length is size of
+ * message excluding crc. Space for the CRC bytes must be allocated
+ * in advance!
+ */
+extern void crcappend(unsigned char* message,
+ unsigned long length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/xs/src/avrdude/dfu.c b/xs/src/avrdude/dfu.c
new file mode 100644
index 000000000..8e014e3c0
--- /dev/null
+++ b/xs/src/avrdude/dfu.c
@@ -0,0 +1,516 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2012 Kirill Levchenko
+ *
+ * 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$ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "dfu.h"
+
+#include "usbdevs.h" /* for USB_VENDOR_ATMEL */
+
+/* If we don't have LibUSB, define dummy functions that report an error. */
+
+#ifndef HAVE_LIBUSB
+
+struct dfu_dev *dfu_open(char *port_name) {
+ avrdude_message(MSG_INFO, "%s: Error: No USB support in this compile of avrdude\n",
+ progname);
+ return NULL;
+}
+
+int dfu_init(struct dfu_dev *dfu, unsigned short usb_vid, unsigned short usb_pid) {
+ return -1;
+}
+
+void dfu_close(struct dfu_dev *dfu) {
+ /* nothing */
+}
+
+int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status)
+{
+ return -1;
+}
+
+int dfu_clrstatus(struct dfu_dev *dfu) {
+ return -1;
+}
+
+int dfu_download(struct dfu_dev *dfu, void * ptr, int size) {
+ return -1;
+}
+
+int dfu_upload(struct dfu_dev *dfu, void * ptr, int size) {
+ return -1;
+}
+
+#else
+
+/* If we DO have LibUSB, we can define the real functions. */
+
+/* DFU data structures and constants.
+ */
+
+#define DFU_TIMEOUT 200 /* ms */
+
+#define DFU_DNLOAD 1
+#define DFU_UPLOAD 2
+#define DFU_GETSTATUS 3
+#define DFU_CLRSTATUS 4
+#define DFU_GETSTATE 5 /* FLIPv1 only; not used */
+#define DFU_ABORT 6 /* FLIPv1 only */
+
+/* Block counter global variable. Incremented each time a DFU_DNLOAD command
+ * is sent to the device.
+ */
+
+static uint16_t wIndex = 0;
+
+/* INTERNAL FUNCTION PROTOTYPES
+ */
+
+static char * get_usb_string(usb_dev_handle * dev_handle, int index);
+
+/* EXPORTED FUNCTION DEFINITIONS
+ */
+
+struct dfu_dev * dfu_open(char *port_spec)
+{
+ struct dfu_dev *dfu;
+ char *bus_name = NULL;
+ char *dev_name = NULL;
+
+ /* The following USB device spec parsing code was copied from usbtiny.c. The
+ * expected format is "usb:BUS:DEV" where BUS and DEV are the bus and device
+ * names. We stash these away in the dfu_dev structure for the dfu_init()
+ * function, where we actually open the device.
+ */
+
+ if (strncmp(port_spec, "usb", 3) != 0) {
+ avrdude_message(MSG_INFO, "%s: Error: "
+ "Invalid port specification \"%s\" for USB device\n",
+ progname, port_spec);
+ return NULL;
+ }
+
+ if(':' == port_spec[3]) {
+ bus_name = strdup(port_spec + 3 + 1);
+ if (bus_name == NULL) {
+ avrdude_message(MSG_INFO, "%s: Out of memory in strdup\n", progname);
+ return NULL;
+ }
+
+ dev_name = strchr(bus_name, ':');
+ if(NULL != dev_name)
+ *dev_name++ = '\0';
+ }
+
+ /* Allocate the dfu_dev structure and save the bus_name and dev_name
+ * strings for use in dfu_initialize().
+ */
+
+ dfu = calloc(1, sizeof(struct dfu_dev));
+
+ if (dfu == NULL)
+ {
+ avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
+ free(bus_name);
+ return NULL;
+ }
+
+ dfu->bus_name = bus_name;
+ dfu->dev_name = dev_name;
+ dfu->timeout = DFU_TIMEOUT;
+
+ /* LibUSB initialization. */
+
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ return dfu;
+}
+
+int dfu_init(struct dfu_dev *dfu, unsigned short vid, unsigned short pid)
+{
+ struct usb_device *found = NULL;
+ struct usb_device *dev;
+ struct usb_bus *bus;
+
+ /* At last, we reach out through the USB bus to the part. There are three
+ * ways to specify the part: by USB address, by USB vendor and product id,
+ * and by part name. To specify the part by USB address, the user specifies
+ * a port parameter in the form "usb:BUS:DEV" (see dfu_open()). To specify
+ * the part by vendor and product, the user must specify a usbvid and usbpid
+ * in the configuration file. Finally, if the user specifies the part only,
+ * we use the default vendor and product id.
+ */
+
+ if (pid == 0 && dfu->dev_name == NULL) {
+ avrdude_message(MSG_INFO, "%s: Error: No DFU support for part; "
+ "specify PID in config or USB address (via -P) to override.\n",
+ progname);
+ return -1;
+ }
+
+ /* Scan through all the devices for the part. The matching rules are:
+ *
+ * 1. If the user specified a USB bus name, it must match.
+ * 2. If the user specified a USB device name, it must match.
+ * 3. If the user didn't specify a USB device name and specified a vendor
+ * id, the vendor id must match.
+ * 4. If the user didn't specify a USB device name and specified a product
+ * id, the product id must match.
+ */
+
+ for (bus = usb_busses; !found && bus != NULL; bus = bus->next) {
+ for (dev = bus->devices; !found && dev != NULL; dev = dev->next) {
+ if (dfu->bus_name != NULL && strcmp(bus->dirname, dfu->bus_name))
+ continue;
+ if (dfu->dev_name != NULL) {
+ if (strcmp(dev->filename, dfu->dev_name))
+ continue;
+ } else if (vid != dev->descriptor.idVendor)
+ continue;
+ else if (pid != 0 && pid != dev->descriptor.idProduct)
+ continue;
+
+ found = dev;
+ }
+ }
+
+ if (found == NULL) {
+ /* We could try to be more informative here. For example, we could report
+ * why the match failed, and if we came across another DFU-capable part.
+ */
+
+ avrdude_message(MSG_INFO, "%s: Error: No matching USB device found\n", progname);
+ return -1;
+ }
+
+ if(verbose)
+ avrdude_message(MSG_INFO, "%s: Found VID=0x%04x PID=0x%04x at %s:%s\n",
+ progname, found->descriptor.idVendor, found->descriptor.idProduct,
+ found->bus->dirname, found->filename);
+
+ dfu->dev_handle = usb_open(found);
+
+ if (dfu->dev_handle == NULL) {
+ avrdude_message(MSG_INFO, "%s: Error: USB device at %s:%s: %s\n",
+ progname, found->bus->dirname, found->filename, usb_strerror());
+ return -1;
+ }
+
+ /* Save device, configuration, interface and endpoint descriptors. */
+
+ memcpy(&dfu->dev_desc, &found->descriptor, sizeof(dfu->dev_desc));
+ memcpy(&dfu->conf_desc, found->config, sizeof(dfu->conf_desc));
+ dfu->conf_desc.interface = NULL;
+
+ memcpy(&dfu->intf_desc, found->config->interface->altsetting,
+ sizeof(dfu->intf_desc));
+ dfu->intf_desc.endpoint = &dfu->endp_desc;
+
+ if (found->config->interface->altsetting->endpoint != 0)
+ memcpy(&dfu->endp_desc, found->config->interface->altsetting->endpoint,
+ sizeof(dfu->endp_desc));
+
+ /* Get strings. */
+
+ dfu->manf_str = get_usb_string(dfu->dev_handle,
+ dfu->dev_desc.iManufacturer);
+
+ dfu->prod_str = get_usb_string(dfu->dev_handle,
+ dfu->dev_desc.iProduct);
+
+ dfu->serno_str = get_usb_string(dfu->dev_handle,
+ dfu->dev_desc.iSerialNumber);
+
+ return 0;
+}
+
+void dfu_close(struct dfu_dev *dfu)
+{
+ if (dfu->dev_handle != NULL)
+ usb_close(dfu->dev_handle);
+ if (dfu->bus_name != NULL)
+ free(dfu->bus_name);
+ if (dfu->manf_str != NULL)
+ free(dfu->manf_str);
+ if (dfu->prod_str != NULL)
+ free(dfu->prod_str);
+ if (dfu->serno_str != NULL)
+ free(dfu->serno_str);
+}
+
+int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status)
+{
+ int result;
+
+ avrdude_message(MSG_TRACE, "%s: dfu_getstatus(): issuing control IN message\n",
+ progname);
+
+ result = usb_control_msg(dfu->dev_handle,
+ 0x80 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_GETSTATUS, 0, 0,
+ (char*) status, sizeof(struct dfu_status), dfu->timeout);
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: Error: Failed to get DFU status: %s\n",
+ progname, usb_strerror());
+ return -1;
+ }
+
+ if (result < sizeof(struct dfu_status)) {
+ avrdude_message(MSG_INFO, "%s: Error: Failed to get DFU status: %s\n",
+ progname, "short read");
+ return -1;
+ }
+
+ if (result > sizeof(struct dfu_status)) {
+ avrdude_message(MSG_INFO, "%s: Error: Oversize read (should not happen); "
+ "exiting\n", progname);
+ exit(1);
+ }
+
+ avrdude_message(MSG_TRACE, "%s: dfu_getstatus(): bStatus 0x%02x, bwPollTimeout %d, bState 0x%02x, iString %d\n",
+ progname,
+ status->bStatus,
+ status->bwPollTimeout[0] | (status->bwPollTimeout[1] << 8) | (status->bwPollTimeout[2] << 16),
+ status->bState,
+ status->iString);
+
+ return 0;
+}
+
+int dfu_clrstatus(struct dfu_dev *dfu)
+{
+ int result;
+
+ avrdude_message(MSG_TRACE, "%s: dfu_clrstatus(): issuing control OUT message\n",
+ progname);
+
+ result = usb_control_msg(dfu->dev_handle,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_CLRSTATUS, 0, 0,
+ NULL, 0, dfu->timeout);
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: Error: Failed to clear DFU status: %s\n",
+ progname, usb_strerror());
+ return -1;
+ }
+
+ return 0;
+}
+
+int dfu_abort(struct dfu_dev *dfu)
+{
+ int result;
+
+ avrdude_message(MSG_TRACE, "%s: dfu_abort(): issuing control OUT message\n",
+ progname);
+
+ result = usb_control_msg(dfu->dev_handle,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_ABORT, 0, 0,
+ NULL, 0, dfu->timeout);
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: Error: Failed to reset DFU state: %s\n",
+ progname, usb_strerror());
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size)
+{
+ int result;
+
+ avrdude_message(MSG_TRACE, "%s: dfu_dnload(): issuing control OUT message, wIndex = %d, ptr = %p, size = %d\n",
+ progname, wIndex, ptr, size);
+
+ result = usb_control_msg(dfu->dev_handle,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_DNLOAD, wIndex++, 0,
+ ptr, size, dfu->timeout);
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: Error: DFU_DNLOAD failed: %s\n",
+ progname, usb_strerror());
+ return -1;
+ }
+
+ if (result < size) {
+ avrdude_message(MSG_INFO, "%s: Error: DFU_DNLOAD failed: %s\n",
+ progname, "short write");
+ return -1;
+ }
+
+ if (result > size) {
+ avrdude_message(MSG_INFO, "%s: Error: Oversize write (should not happen); " \
+ "exiting\n", progname);
+ exit(1);
+ }
+
+ return 0;
+}
+
+int dfu_upload(struct dfu_dev *dfu, void *ptr, int size)
+{
+ int result;
+
+ avrdude_message(MSG_TRACE, "%s: dfu_upload(): issuing control IN message, wIndex = %d, ptr = %p, size = %d\n",
+ progname, wIndex, ptr, size);
+
+ result = usb_control_msg(dfu->dev_handle,
+ 0x80 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, DFU_UPLOAD, wIndex++, 0,
+ ptr, size, dfu->timeout);
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: Error: DFU_UPLOAD failed: %s\n",
+ progname, usb_strerror());
+ return -1;
+ }
+
+ if (result < size) {
+ avrdude_message(MSG_INFO, "%s: Error: DFU_UPLOAD failed: %s\n",
+ progname, "short read");
+ return -1;
+ }
+
+ if (result > size) {
+ avrdude_message(MSG_INFO, "%s: Error: Oversize read (should not happen); "
+ "exiting\n", progname);
+ exit(1);
+ }
+
+ return 0;
+}
+
+void dfu_show_info(struct dfu_dev *dfu)
+{
+ if (dfu->manf_str != NULL)
+ avrdude_message(MSG_INFO, " USB Vendor : %s (0x%04hX)\n",
+ dfu->manf_str, (unsigned short) dfu->dev_desc.idVendor);
+ else
+ avrdude_message(MSG_INFO, " USB Vendor : 0x%04hX\n",
+ (unsigned short) dfu->dev_desc.idVendor);
+
+ if (dfu->prod_str != NULL)
+ avrdude_message(MSG_INFO, " USB Product : %s (0x%04hX)\n",
+ dfu->prod_str, (unsigned short) dfu->dev_desc.idProduct);
+ else
+ avrdude_message(MSG_INFO, " USB Product : 0x%04hX\n",
+ (unsigned short) dfu->dev_desc.idProduct);
+
+ avrdude_message(MSG_INFO, " USB Release : %hu.%hu.%hu\n",
+ ((unsigned short) dfu->dev_desc.bcdDevice >> 8) & 0xFF,
+ ((unsigned short) dfu->dev_desc.bcdDevice >> 4) & 0xF,
+ ((unsigned short) dfu->dev_desc.bcdDevice >> 0) & 0xF);
+
+ if (dfu->serno_str != NULL)
+ avrdude_message(MSG_INFO, " USB Serial No : %s\n", dfu->serno_str);
+}
+
+/* INTERNAL FUNCTION DEFINITIONS
+ */
+
+char * get_usb_string(usb_dev_handle * dev_handle, int index) {
+ char buffer[256];
+ char * str;
+ int result;
+
+ if (index == 0)
+ return NULL;
+
+ result = usb_get_string_simple(dev_handle, index, buffer, sizeof(buffer)-1);
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: Warning: Failed to read USB device string %d: %s\n",
+ progname, index, usb_strerror());
+ return NULL;
+ }
+
+ str = malloc(result+1);
+
+ if (str == NULL) {
+ avrdude_message(MSG_INFO, "%s: Out of memory allocating a string\n", progname);
+ return 0;
+ }
+
+ memcpy(str, buffer, result);
+ str[result] = '\0';
+ return str;
+}
+
+#endif /* defined(HAVE_LIBUSB) */
+
+/* EXPORTED FUNCTIONS THAT DO NO REQUIRE LIBUSB
+ */
+
+const char * dfu_status_str(int bStatus)
+{
+ switch (bStatus) {
+ case DFU_STATUS_OK: return "OK";
+ case DFU_STATUS_ERR_TARGET: return "ERR_TARGET";
+ case DFU_STATUS_ERR_FILE: return "ERR_FILE";
+ case DFU_STATUS_ERR_WRITE: return "ERR_WRITE";
+ case DFU_STATUS_ERR_ERASE: return "ERR_ERASE";
+ case DFU_STATUS_ERR_CHECK_ERASED: return "ERR_CHECK_ERASED";
+ case DFU_STATUS_ERR_PROG: return "ERR_PROG";
+ case DFU_STATUS_ERR_VERIFY: return "ERR_VERIFY";
+ case DFU_STATUS_ERR_ADDRESS: return "ERR_ADDRESS";
+ case DFU_STATUS_ERR_NOTDONE: return "ERR_NOTDONE";
+ case DFU_STATUS_ERR_FIRMWARE: return "ERR_FIRMWARE";
+ case DFU_STATUS_ERR_VENDOR: return "ERR_VENDOR";
+ case DFU_STATUS_ERR_USBR: return "ERR_USBR";
+ case DFU_STATUS_ERR_POR: return "ERR_POR";
+ case DFU_STATUS_ERR_UNKNOWN: return "ERR_UNKNOWN";
+ case DFU_STATUS_ERR_STALLEDPKT: return "ERR_STALLEDPKT";
+ default: return "Unknown";
+ }
+}
+
+const char * dfu_state_str(int bState)
+{
+ switch (bState) {
+ case DFU_STATE_APP_IDLE: return "APP_IDLE";
+ case DFU_STATE_APP_DETACH: return "APP_DETACH";
+ case DFU_STATE_DFU_IDLE: return "DFU_IDLE";
+ case DFU_STATE_DFU_DLOAD_SYNC: return "DFU_DLOAD_SYNC";
+ case DFU_STATE_DFU_DNBUSY: return "DFU_DNBUSY";
+ case DFU_STATE_DFU_DNLOAD_IDLE: return "DFU_DNLOAD_IDLE";
+ case DFU_STATE_DFU_MANIFEST_SYNC: return "DFU_MANIFEST_SYNC";
+ case DFU_STATE_DFU_MANIFEST: return "DFU_MANIFEST";
+ case DFU_STATE_DFU_MANIFEST_WAIT_RESET: return "DFU_MANIFEST_WAIT_RESET";
+ case DFU_STATE_DFU_UPLOAD_IDLE: return "DFU_UPLOAD_IDLE";
+ case DFU_STATE_DFU_ERROR: return "DFU_ERROR";
+ default: return "Unknown";
+ }
+}
+
diff --git a/xs/src/avrdude/dfu.h b/xs/src/avrdude/dfu.h
new file mode 100644
index 000000000..020a75f2e
--- /dev/null
+++ b/xs/src/avrdude/dfu.h
@@ -0,0 +1,137 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2012 Kirill Levchenko
+ *
+ * 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 dfu_h
+#define dfu_h
+
+#include "ac_cfg.h"
+
+#ifdef HAVE_LIBUSB
+#if defined(HAVE_USB_H)
+# include <usb.h>
+#elif defined(HAVE_LUSB0_USB_H)
+# include <lusb0_usb.h>
+#else
+# error "libusb needs either <usb.h> or <lusb0_usb.h>"
+#endif
+#endif
+
+#include <limits.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* If we have LIBUSB, define the dfu_dev struct normally. Otherwise, declare
+ * it as an empty struct so that code compiles, but we generate an error at
+ * run time.
+ */
+
+#ifdef HAVE_LIBUSB
+
+struct dfu_dev
+{
+ char *bus_name, *dev_name;
+ usb_dev_handle *dev_handle;
+ struct usb_device_descriptor dev_desc;
+ struct usb_config_descriptor conf_desc;
+ struct usb_interface_descriptor intf_desc;
+ struct usb_endpoint_descriptor endp_desc;
+ char *manf_str, *prod_str, *serno_str;
+ unsigned int timeout;
+};
+
+#else
+
+struct dfu_dev {
+ // empty
+};
+
+#endif
+
+/* We assume unsigned char is 1 byte. */
+
+#if UCHAR_MAX != 255
+#error UCHAR_MAX != 255
+#endif
+
+struct dfu_status {
+ unsigned char bStatus;
+ unsigned char bwPollTimeout[3];
+ unsigned char bState;
+ unsigned char iString;
+};
+
+// Values of bStatus field.
+
+#define DFU_STATUS_OK 0x0
+#define DFU_STATUS_ERR_TARGET 0x1
+#define DFU_STATUS_ERR_FILE 0x2
+#define DFU_STATUS_ERR_WRITE 0x3
+#define DFU_STATUS_ERR_ERASE 0x4
+#define DFU_STATUS_ERR_CHECK_ERASED 0x5
+#define DFU_STATUS_ERR_PROG 0x6
+#define DFU_STATUS_ERR_VERIFY 0x7
+#define DFU_STATUS_ERR_ADDRESS 0x8
+#define DFU_STATUS_ERR_NOTDONE 0x9
+#define DFU_STATUS_ERR_FIRMWARE 0xA
+#define DFU_STATUS_ERR_VENDOR 0xB
+#define DFU_STATUS_ERR_USBR 0xC
+#define DFU_STATUS_ERR_POR 0xD
+#define DFU_STATUS_ERR_UNKNOWN 0xE
+#define DFU_STATUS_ERR_STALLEDPKT 0xF
+
+// Values of bState field.
+
+#define DFU_STATE_APP_IDLE 0
+#define DFU_STATE_APP_DETACH 1
+#define DFU_STATE_DFU_IDLE 2
+#define DFU_STATE_DFU_DLOAD_SYNC 3
+#define DFU_STATE_DFU_DNBUSY 4
+#define DFU_STATE_DFU_DNLOAD_IDLE 5
+#define DFU_STATE_DFU_MANIFEST_SYNC 6
+#define DFU_STATE_DFU_MANIFEST 7
+#define DFU_STATE_DFU_MANIFEST_WAIT_RESET 8
+#define DFU_STATE_DFU_UPLOAD_IDLE 9
+#define DFU_STATE_DFU_ERROR 10
+
+// FUNCTIONS
+
+extern struct dfu_dev * dfu_open(char *port_spec);
+extern int dfu_init(struct dfu_dev *dfu,
+ unsigned short vid, unsigned short pid);
+extern void dfu_close(struct dfu_dev *dfu);
+
+extern int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status);
+extern int dfu_clrstatus(struct dfu_dev *dfu);
+extern int dfu_dnload(struct dfu_dev *dfu, void *ptr, int size);
+extern int dfu_upload(struct dfu_dev *dfu, void *ptr, int size);
+extern int dfu_abort(struct dfu_dev *dfu);
+
+extern void dfu_show_info(struct dfu_dev *dfu);
+
+extern const char * dfu_status_str(int bStatus);
+extern const char * dfu_state_str(int bState);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* dfu_h */
diff --git a/xs/src/avrdude/doc/.cvsignore b/xs/src/avrdude/doc/.cvsignore
new file mode 100644
index 000000000..afe95fe92
--- /dev/null
+++ b/xs/src/avrdude/doc/.cvsignore
@@ -0,0 +1,25 @@
+.cvsignore
+Makefile
+Makefile.in
+avrdude-html
+avrdude.aux
+avrdude.cp
+avrdude.cps
+avrdude.dvi
+avrdude.fn
+avrdude.info
+avrdude.ky
+avrdude.log
+avrdude.pdf
+avrdude.pg
+avrdude.ps
+avrdude.toc
+avrdude.tp
+avrdude.vr
+mdate-sh
+stamp-vti
+texinfo.tex
+version.texi
+programmer_types.texi
+parts.texi
+programmers.texi
diff --git a/xs/src/avrdude/doc/Makefile.am b/xs/src/avrdude/doc/Makefile.am
new file mode 100644
index 000000000..bee799f74
--- /dev/null
+++ b/xs/src/avrdude/doc/Makefile.am
@@ -0,0 +1,94 @@
+#
+# avrdude - A Downloader/Uploader for AVR device programmers
+# Copyright (C) 2003 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$
+#
+
+GENERATED_TEXINFOS = \
+ $(builddir)/programmers.texi \
+ $(builddir)/parts.texi \
+ $(builddir)/programmer_types.texi \
+ $(builddir)/version.texi
+
+CLEANFILES = \
+ $(GENERATED_TEXINFOS) \
+ $(builddir)/stamp-vti
+
+info_TEXINFOS = avrdude.texi
+
+EXTRA_DIST = \
+ parts_comments.txt
+
+all-local: info html ps pdf
+
+html: avrdude-html/avrdude.html
+
+avrdude-html/avrdude.html: $(srcdir)/$(info_TEXINFOS) $(GENERATED_TEXINFOS)
+ texi2html -split_node $(srcdir)/$(info_TEXINFOS)
+ if [ -e ./avrdude.html -o -e ./avrdude_1.html ]; then \
+ mkdir -p avrdude-html ; \
+ mv -f *.html avrdude-html ; \
+ else \
+ mv -f avrdude avrdude-html; \
+ fi;
+
+$(builddir)/avrdude.info: $(GENERATED_TEXINFOS)
+$(builddir)/avrdude.dvi: $(GENERATED_TEXINFOS)
+$(builddir)/avrdude.pdf: $(GENERATED_TEXINFOS)
+
+# if it does not exist make this first
+../avrdude$(EXEEXT):
+ $(MAKE) -C .. avrdude$(EXEEXT)
+
+$(builddir)/programmers.texi: ../avrdude$(EXEEXT) ../avrdude.conf Makefile
+ ../avrdude$(EXEEXT) -C ../avrdude.conf -c \? 2>&1 \
+ | $(AWK) '$$2 ~ /^=$$/ {printf("@item @code{%s} @tab %s\n",$$1,gensub("[^=]+=[ \t]*","",1))}' \
+ | sed "s# *,\? *<\?\(http://[^ \t>]*\)>\?#,@*\n@url{\1}#g" \
+ >programmers.texi
+
+$(builddir)/programmer_types.texi: ../avrdude$(EXEEXT) ../avrdude.conf Makefile
+ ../avrdude$(EXEEXT) -C ../avrdude.conf -c \?type 2>&1 \
+ | $(AWK) '$$2 ~ /^=$$/ {printf("@item @code{%s} @tab %s\n",$$1,gensub("[^=]+=[ \t]*","",1))}' \
+ | sed "s#<\?\(http://[^ \t,>]*\)>\?#@url{\1}#g" \
+ >programmer_types.texi
+
+$(builddir)/parts.texi: ../avrdude$(EXEEXT) ../avrdude.conf parts_comments.txt Makefile
+ ../avrdude$(EXEEXT) -C ../avrdude.conf -p \? 2>&1 \
+ | $(AWK) '$$2 ~ /^=$$/ {printf("@item @code{%s} @tab %s\n",$$1,$$3)}' \
+ | sed -e "`sed 's:\([^ \t]*\)[ \t]*\(.*\):s/\1$$/\1 \2/g:g' <parts_comments.txt`" \
+ >parts.texi
+
+clean-local:
+ rm -rf avrdude-html *.info
+
+install-data-local: install-docs
+
+install-docs: html ps pdf
+ $(mkinstalldirs) $(DOC_INST_DIR)
+ $(INSTALL_DATA) avrdude.ps $(DOC_INST_DIR)/avrdude.ps
+ $(INSTALL_DATA) avrdude.pdf $(DOC_INST_DIR)/avrdude.pdf
+ $(mkinstalldirs) $(DOC_INST_DIR)/avrdude-html
+ @list=`echo avrdude-html/*.html`; \
+ for file in $$list; \
+ do \
+ $(INSTALL_DATA) $$file $(DOC_INST_DIR)/$$file; \
+ done
+
+uninstall-local:
+ rm -rf $(DOC_INST_DIR)
diff --git a/xs/src/avrdude/doc/TODO b/xs/src/avrdude/doc/TODO
new file mode 100644
index 000000000..6c57c5ade
--- /dev/null
+++ b/xs/src/avrdude/doc/TODO
@@ -0,0 +1,26 @@
+
+- Man page needs updated for avr910 info.
+
+- Website needs to link to docs:
+ http://savannah.nongnu.org/download/avrdude/doc/avrdude-html/
+
+- Add "skip empty pages" optimization on avr910 paged write. The stk500 has
+ this optimization already.
+
+- Fix "overfull \hbox" issues in building documentation.
+
+- FIXME: term.c: terminal_get_input(): strip newlines in non-readline input
+ code.
+
+- FIXME: avr910.c: avr910_cmd(): Insert version check here.
+
+- FIXME: ser_posix.c: serial_close(): Should really restore the terminal to
+ original state here.
+
+- FIXME: main.c, par.c: exitspecs don't work if RESET-pin is controlled over
+ PPICTRL.
+
+- transfer ppi-speedtuning to the windows version (CAVEAT: This will make
+ programming too fast for chips with 500kHz clock)
+
+- make SCK-period configurable for PPI-programmers
diff --git a/xs/src/avrdude/doc/avrdude.texi b/xs/src/avrdude/doc/avrdude.texi
new file mode 100644
index 000000000..6941389df
--- /dev/null
+++ b/xs/src/avrdude/doc/avrdude.texi
@@ -0,0 +1,2586 @@
+%% -*-texinfo-*-
+\input texinfo
+
+@c $Id$
+
+@setfilename avrdude.info
+@settitle AVRDUDE
+@finalout
+
+@include version.texi
+
+@c
+@c These are set in version.texi which is automatically generated by automake.
+@c
+@c @set UPDATED 26 Febuary 2003
+@c @set EDITION 3.2.0
+@c @set VERSION 3.2.0
+
+@c This is a dir.info fragment to support semi-automated addition of
+@c manuals to an info tree.
+@dircategory AVR Programming & development tools.
+@direntry
+* AvrDude: (avrdude). AVR program downloader/uploader.
+@end direntry
+
+@ifinfo
+This file documents the avrdude program.
+
+For avrdude version @value{VERSION}, @value{UPDATED}.
+
+Copyright @copyright{} 2003, 2005 Brian Dean
+
+Copyright @copyright{} 2006 - 2016 J@"org Wunsch
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Free Software Foundation.
+
+Alternatively, this documentation may be copied and distributed under
+the terms of the GNU Free Documentation License (FDL), version 1.3.
+@end ifinfo
+
+@titlepage
+@title AVRDUDE
+@subtitle A program for download/uploading AVR microcontroller flash and eeprom.
+@subtitle For AVRDUDE, Version @value{VERSION}, @value{UPDATED}.
+@author by Brian S. Dean
+
+@page
+Send comments on AVRDUDE to @w{@email{avrdude-dev@@nongnu.org}}.
+
+Use @uref{http://savannah.nongnu.org/bugs/?group=avrdude} to report bugs.
+
+Copyright @copyright{} 2003,2005 Brian S. Dean
+
+Copyright @copyright{} 2006 - 2013 J@"org Wunsch
+@sp 2
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Free Software Foundation.
+@end titlepage
+
+@contents
+
+@c
+@c Top Node
+@c
+@node Top, Introduction, (dir), (dir)
+@comment node-name, next, previous, up
+
+@ifinfo
+This file documents the avrdude program for downloading/uploading
+programs to Atmel AVR microcontrollers.
+
+For avrdude version @value{VERSION}, @value{UPDATED}.
+
+Send comments on AVRDUDE to @w{@email{avrdude-dev@@nongnu.org}}.
+
+Use @uref{http://savannah.nongnu.org/bugs/?group=avrdude} to report bugs.
+
+Copyright @copyright{} 2003,2005 Brian S. Dean
+
+Copyright @copyright{} 2006 J@"org Wunsch
+@end ifinfo
+
+@menu
+* Introduction::
+* Command Line Options::
+* Terminal Mode Operation::
+* Configuration File::
+* Programmer Specific Information::
+* Platform Dependent Information::
+* Troubleshooting::
+@end menu
+
+@c
+@c Node
+@c
+@node Introduction, Command Line Options, Top, Top
+@comment node-name, next, previous, up
+@chapter Introduction
+@cindex introduction
+
+AVRDUDE - AVR Downloader Uploader - is a program for downloading and
+uploading the on-chip memories of Atmel's AVR microcontrollers. It can
+program the Flash and EEPROM, and where supported by the serial
+programming protocol, it can program fuse and lock bits. AVRDUDE also
+supplies a direct instruction mode allowing one to issue any programming
+instruction to the AVR chip regardless of whether AVRDUDE implements
+that specific feature of a particular chip.
+
+AVRDUDE can be used effectively via the command line to read or write
+all chip memory types (eeprom, flash, fuse bits, lock bits, signature
+bytes) or via an interactive (terminal) mode. Using AVRDUDE from the
+command line works well for programming the entire memory of the chip
+from the contents of a file, while interactive mode is useful for
+exploring memory contents, modifying individual bytes of eeprom,
+programming fuse/lock bits, etc.
+
+AVRDUDE supports the following basic programmer types: Atmel's STK500,
+Atmel's AVRISP and AVRISP mkII devices,
+Atmel's STK600,
+Atmel's JTAG ICE (the original one, mkII, and 3, the latter two also in ISP mode), appnote
+avr910, appnote avr109 (including the AVR Butterfly),
+serial bit-bang adapters,
+and the PPI (parallel port interface). PPI represents a class
+of simple programmers where the programming lines are directly
+connected to the PC parallel port. Several pin configurations exist
+for several variations of the PPI programmers, and AVRDUDE can be
+configured to work with them by either specifying the appropriate
+programmer on the command line or by creating a new entry in its
+configuration file. All that's usually required for a new entry is to
+tell AVRDUDE which pins to use for each programming function.
+
+A number of equally simple bit-bang programming adapters that connect
+to a serial port are supported as well, among them the popular
+Ponyprog serial adapter, and the DASA and DASA3 adapters that used to
+be supported by uisp(1). Note that these adapters are meant to be
+attached to a physical serial port. Connecting to a serial port
+emulated on top of USB is likely to not work at all, or to work
+abysmally slow.
+
+If you happen to have a Linux system with at least 4 hardware GPIOs
+available (like almost all embedded Linux boards) you can do without
+any additional hardware - just connect them to the MOSI, MISO, RESET
+and SCK pins on the AVR and use the linuxgpio programmer type. It bitbangs
+the lines using the Linux sysfs GPIO interface. Of course, care should
+be taken about voltage level compatibility. Also, although not strictly
+required, it is strongly advisable to protect the GPIO pins from
+overcurrent situations in some way. The simplest would be to just put
+some resistors in series or better yet use a 3-state buffer driver like
+the 74HC244. Have a look at http://kolev.info/avrdude-linuxgpio for a more
+detailed tutorial about using this programmer type.
+
+The STK500, JTAG ICE, avr910, and avr109/butterfly use the serial port to communicate with the PC.
+The STK600, JTAG ICE mkII/3, AVRISP mkII, USBasp, avrftdi (and derivatives), and USBtinyISP
+programmers communicate through the USB, using @code{libusb} as a
+platform abstraction layer.
+The avrftdi adds support for the FT2232C/D, FT2232H, and FT4232H devices. These all use
+the MPSSE mode, which has a specific pin mapping. Bit 1 (the lsb of the byte in the config
+file) is SCK. Bit 2 is MOSI, and Bit 3 is MISO. Bit 4 usually reset. The 2232C/D parts
+are only supported on interface A, but the H parts can be either A or B (specified by the
+usbdev config parameter).
+The STK500, STK600, JTAG ICE, and avr910 contain on-board logic to control the programming of the target
+device.
+The avr109 bootloader implements a protocol similar to avr910, but is
+actually implemented in the boot area of the target's flash ROM, as
+opposed to being an external device.
+The fundamental difference between the two types lies in the
+protocol used to control the programmer. The avr910 protocol is very
+simplistic and can easily be used as the basis for a simple, home made
+programmer since the firmware is available online. On the other hand,
+the STK500 protocol is more robust and complicated and the firmware is
+not openly available.
+The JTAG ICE also uses a serial communication protocol which is similar
+to the STK500 firmware version 2 one. However, as the JTAG ICE is
+intended to allow on-chip debugging as well as memory programming, the
+protocol is more sophisticated.
+(The JTAG ICE mkII protocol can also be run on top of USB.)
+Only the memory programming functionality of the JTAG ICE is supported
+by AVRDUDE.
+For the JTAG ICE mkII/3, JTAG, debugWire and ISP mode are supported, provided
+it has a firmware revision of at least 4.14 (decimal).
+See below for the limitations of debugWire.
+For ATxmega devices, the JTAG ICE mkII/3 is supported in PDI mode, provided it
+has a revision 1 hardware and firmware version of at least 5.37 (decimal).
+
+The Atmel-ICE (ARM/AVR) is supported (JTAG, PDI for Xmega, debugWIRE, ISP modes).
+
+Atmel's XplainedPro boards, using EDBG protocol (CMSIS-DAP compliant), are
+supported by the ``jtag3'' programmer type.
+
+Atmel's XplainedMini boards, using mEDBG protocol, are also
+supported by the ``jtag3'' programmer type.
+
+The AVR Dragon is supported in all modes (ISP, JTAG, PDI, HVSP, PP, debugWire).
+When used in JTAG and debugWire mode, the AVR Dragon behaves similar to a
+JTAG ICE mkII, so all device-specific comments for that device
+will apply as well.
+When used in ISP and PDI mode, the AVR Dragon behaves similar to an
+AVRISP mkII (or JTAG ICE mkII in ISP mode), so all device-specific
+comments will apply there.
+In particular, the Dragon starts out with a rather fast ISP clock
+frequency, so the @code{-B @var{bitclock}}
+option might be required to achieve a stable ISP communication.
+For ATxmega devices, the AVR Dragon is supported in PDI mode, provided it
+has a firmware version of at least 6.11 (decimal).
+
+Wiring boards are supported, utilizing STK500 V2.x protocol, but
+a simple DTR/RTS toggle to set the boards into programming mode.
+The programmer type is ``wiring''.
+
+The Arduino (which is very similar to the STK500 1.x) is supported via
+its own programmer type specification ``arduino''.
+
+The BusPirate is a versatile tool that can also be used as an AVR programmer.
+A single BusPirate can be connected to up to 3 independent AVRs. See
+the section on
+@emph{extended parameters}
+below for details.
+
+The USBasp ISP and USBtinyISP adapters are also supported, provided AVRDUDE
+has been compiled with libusb support.
+They both feature simple firmware-only USB implementations, running on
+an ATmega8 (or ATmega88), or ATtiny2313, respectively.
+
+The Atmel DFU bootloader is supported in both, FLIP protocol version 1
+(AT90USB* and ATmega*U* devices), as well as version 2 (Xmega devices).
+See below for some hints about FLIP version 1 protocol behaviour.
+
+
+@menu
+* History::
+@end menu
+
+@c
+@c Node
+@c
+@node History, , Introduction, Introduction
+@section History and Credits
+
+AVRDUDE was written by Brian S. Dean under the name of AVRPROG to run on
+the FreeBSD Operating System. Brian renamed the software to be called
+AVRDUDE when interest grew in a Windows port of the software so that the
+name did not conflict with AVRPROG.EXE which is the name of Atmel's
+Windows programming software.
+
+The AVRDUDE source now resides in the public CVS repository on
+savannah.gnu.org (@url{http://savannah.gnu.org/projects/avrdude/}),
+where it continues to be enhanced and ported to other systems. In
+addition to FreeBSD, AVRDUDE now runs on Linux and Windows. The
+developers behind the porting effort primarily were Ted Roth, Eric
+Weddington, and Joerg Wunsch.
+
+And in the spirit of many open source projects, this manual also draws
+on the work of others. The initial revision was composed of parts of
+the original Unix manual page written by Joerg Wunsch, the original web
+site documentation by Brian Dean, and from the comments describing the
+fields in the AVRDUDE configuration file by Brian Dean. The texi
+formatting was modeled after that of the Simulavr documentation by Ted
+Roth.
+
+
+@c
+@c Node
+@c
+@node Command Line Options, Terminal Mode Operation, Introduction, Top
+@chapter Command Line Options
+@cindex options
+
+@menu
+* Option Descriptions::
+* Programmers accepting extended parameters::
+* Example Command Line Invocations::
+@end menu
+
+@c
+@c Node
+@c
+@node Option Descriptions, Programmers accepting extended parameters, Command Line Options, Command Line Options
+@section Option Descriptions
+
+@noindent
+AVRDUDE is a command line tool, used as follows:
+
+@smallexample
+avrdude -p partno @var{options} @dots{}
+@end smallexample
+
+@noindent
+Command line options are used to control AVRDUDE's behaviour. The
+following options are recognized:
+
+@table @code
+@item -p @var{partno}
+This is the only mandatory option and it tells AVRDUDE what type of part
+(MCU) that is connected to the programmer. The @var{partno} parameter
+is the part's id listed in the configuration file. Specify -p ? to list
+all parts in the configuration file. If a part is unknown
+to AVRDUDE, it means that there is no config file entry for that part,
+but it can be added to the configuration file if you have the Atmel
+datasheet so that you can enter the programming specifications.
+Currently, the following MCU types are understood:
+
+@multitable @columnfractions .15 .3
+@include parts.texi
+@end multitable
+
+(*) The AT90S2323 and ATtiny22 use the same algorithm.
+
+(**) Flash addressing above 128 KB is not supported by all
+programming hardware. Known to work are jtag2, stk500v2,
+and bit-bang programmers.
+
+(***)
+The ATtiny11 can only be
+programmed in high-voltage serial mode.
+
+(****)
+The ISP programming protocol of the AT90S1200 differs in subtle ways
+from that of other AVRs. Thus, not all programmers support this
+device. Known to work are all direct bitbang programmers, and all
+programmers talking the STK500v2 protocol.
+
+@item -b @var{baudrate}
+Override the RS-232 connection baud rate specified in the respective
+programmer's entry of the configuration file.
+
+@item -B @var{bitclock}
+Specify the bit clock period for the JTAG interface or the ISP clock (JTAG ICE only).
+The value is a floating-point number in microseconds.
+Alternatively, the value might be suffixed with "Hz", "kHz", or "MHz",
+in order to specify the bit clock frequency, rather than a period.
+The default value of the JTAG ICE results in about 1 microsecond bit
+clock period, suitable for target MCUs running at 4 MHz clock and
+above.
+Unlike certain parameters in the STK500, the JTAG ICE resets all its
+parameters to default values when the programming software signs
+off from the ICE, so for MCUs running at lower clock speeds, this
+parameter must be specified on the command-line.
+It can also be set in the configuration file by using the 'default_bitclock'
+keyword.
+
+@item -c @var{programmer-id}
+Specify the programmer to be used. AVRDUDE knows about several common
+programmers. Use this option to specify which one to use. The
+@var{programmer-id} parameter is the programmer's id listed in the
+configuration file. Specify -c ? to list all programmers in the
+configuration file. If you have a programmer that is unknown to
+AVRDUDE, and the programmer is controlled via the PC parallel port,
+there's a good chance that it can be easily added to the configuration
+file without any code changes to AVRDUDE. Simply copy an existing entry
+and change the pin definitions to match that of the unknown programmer.
+Currently, the following programmer ids are understood and supported:
+
+@multitable @columnfractions .2 .6
+@include programmers.texi
+@end multitable
+
+
+
+@item -C @var{config-file}
+Use the specified config file for configuration data. This file
+contains all programmer and part definitions that AVRDUDE knows about.
+If not
+specified, AVRDUDE reads the configuration file from
+/usr/local/etc/avrdude.conf (FreeBSD and Linux). See Appendix A for
+the method of searching for the configuration file for Windows.
+
+If @var{config-file} is written as @var{+filename}
+then this file is read after the system wide and user configuration
+files. This can be used to add entries to the configuration
+without patching your system wide configuration file. It can be used
+several times, the files are read in same order as given on the command
+line.
+
+
+@item -D
+Disable auto erase for flash. When the -U option with flash memory is
+specified, avrdude will perform a chip erase before starting any of the
+programming operations, since it generally is a mistake to program the flash
+without performing an erase first. This option disables that.
+Auto erase is not used for ATxmega devices as these devices can
+use page erase before writing each page so no explicit chip erase
+is required.
+Note however that any page not affected by the current operation
+will retain its previous contents.
+
+@item -e
+Causes a chip erase to be executed. This will reset the contents of the
+flash ROM and EEPROM to the value `0xff', and clear all lock bits.
+Except for ATxmega devices which can use page erase,
+it is basically a
+prerequisite command before the flash ROM can be reprogrammed again.
+The only exception would be if the new contents would exclusively cause
+bits to be programmed from the value `1' to `0'. Note that in order
+to reprogram EERPOM cells, no explicit prior chip erase is required
+since the MCU provides an auto-erase cycle in that case before
+programming the cell.
+
+
+@item -E @var{exitspec}[,@dots{}]
+By default, AVRDUDE leaves the parallel port in the same state at exit
+as it has been found at startup. This option modifies the state of the
+`/RESET' and `Vcc' lines the parallel port is left at, according to
+the exitspec arguments provided, as follows:
+
+@table @code
+@item reset
+The `/RESET' signal will be left activated at program exit, that is it
+will be held low, in order to keep the MCU in reset state afterwards.
+Note in particular that the programming algorithm for the AT90S1200
+device mandates that the `/RESET' signal is active before powering up
+the MCU, so in case an external power supply is used for this MCU type,
+a previous invocation of AVRDUDE with this option specified is one of
+the possible ways to guarantee this condition.
+
+@item noreset
+The `/RESET' line will be deactivated at program exit, thus allowing the
+MCU target program to run while the programming hardware remains
+connected.
+
+@item vcc
+This option will leave those parallel port pins active (i. e. high) that
+can be used to supply `Vcc' power to the MCU.
+
+@item novcc
+This option will pull the `Vcc' pins of the parallel port down at
+program exit.
+
+@item d_high
+This option will leave the 8 data pins on the parallel port active
+(i. e. high).
+
+@item d_low
+This option will leave the 8 data pins on the parallel port inactive
+(i. e. low).
+
+@end table
+
+Multiple @var{exitspec} arguments can be separated with commas.
+
+
+@item -F
+Normally, AVRDUDE tries to verify that the device signature read from
+the part is reasonable before continuing. Since it can happen from time
+to time that a device has a broken (erased or overwritten) device
+signature but is otherwise operating normally, this options is provided
+to override the check.
+Also, for programmers like the Atmel STK500 and STK600 which can
+adjust parameters local to the programming tool (independent of an
+actual connection to a target controller), this option can be used
+together with @option{-t} to continue in terminal mode.
+
+@item -i @var{delay}
+For bitbang-type programmers, delay for approximately
+@var{delay}
+microseconds between each bit state change.
+If the host system is very fast, or the target runs off a slow clock
+(like a 32 kHz crystal, or the 128 kHz internal RC oscillator), this
+can become necessary to satisfy the requirement that the ISP clock
+frequency must not be higher than 1/4 of the CPU clock frequency.
+This is implemented as a spin-loop delay to allow even for very
+short delays.
+On Unix-style operating systems, the spin loop is initially calibrated
+against a system timer, so the number of microseconds might be rather
+realistic, assuming a constant system load while AVRDUDE is running.
+On Win32 operating systems, a preconfigured number of cycles per
+microsecond is assumed that might be off a bit for very fast or very
+slow machines.
+
+@item -l @var{logfile}
+Use @var{logfile} rather than @var{stderr} for diagnostics output.
+Note that initial diagnostic messages (during option parsing) are still
+written to @var{stderr} anyway.
+
+@item -n
+No-write - disables actually writing data to the MCU (useful for
+debugging AVRDUDE).
+
+@item -O
+Perform a RC oscillator run-time calibration according to Atmel
+application note AVR053.
+This is only supported on the STK500v2, AVRISP mkII, and JTAG ICE mkII
+hardware.
+Note that the result will be stored in the EEPROM cell at address 0.
+
+@item -P @var{port}
+Use port to identify the device to which the programmer is attached.
+Normally, the default parallel port is used, but if the programmer type
+normally connects to the serial port, the default serial port will be
+used. See Appendix A, Platform Dependent Information, to find out the
+default port names for your platform. If you need to use a different
+parallel or serial port, use this option to specify the alternate port name.
+
+On Win32 operating systems, the parallel ports are referred to as lpt1
+through lpt3, referring to the addresses 0x378, 0x278, and 0x3BC,
+respectively. If the parallel port can be accessed through a different
+address, this address can be specified directly, using the common C
+language notation (i. e., hexadecimal values are prefixed by @var{0x}).
+
+For the JTAG ICE mkII, if AVRDUDE has been built with libusb support,
+@var{port} may alternatively be specified as
+@code{usb}[:@var{serialno}]. In that case, the JTAG ICE mkII will be
+looked up on USB. If @var{serialno} is also specified, it will be
+matched against the serial number read from any JTAG ICE mkII found on
+USB. The match is done after stripping any existing colons from the
+given serial number, and right-to-left, so only the least significant
+bytes from the serial number need to be given.
+For a trick how to find out the serial numbers of all JTAG ICEs
+attached to USB, see @ref{Example Command Line Invocations}.
+
+As the AVRISP mkII device can only be talked to over USB, the very
+same method of specifying the port is required there.
+
+For the USB programmer "AVR-Doper" running in HID mode, the port must
+be specified as @var{avrdoper}. Libusb support is required on Unix
+but not on Windows. For more information about AVR-Doper see
+@url{http://www.obdev.at/avrusb/avrdoper.html}.
+
+For the USBtinyISP, which is a simplistic device not implementing
+serial numbers, multiple devices can be distinguished by their
+location in the USB hierarchy.
+@xref{Troubleshooting}, for examples.
+
+For programmers that attach to a serial port using some kind of
+higher level protocol (as opposed to bit-bang style programmers),
+@var{port} can be specified as @code{net}:@var{host}:@var{port}.
+In this case, instead of trying to open a local device, a TCP
+network connection to (TCP) @var{port} on @var{host}
+is established.
+The remote endpoint is assumed to be a terminal or console server
+that connects the network stream to a local serial port where the
+actual programmer has been attached to.
+The port is assumed to be properly configured, for example using a
+transparent 8-bit data connection without parity at 115200 Baud
+for a STK500.
+
+
+@item -q
+Disable (or quell) output of the progress bar while reading or writing
+to the device. Specify it a second time for even quieter operation.
+
+@item -u
+Disables the default behaviour of reading out the fuses three times before
+programming, then verifying at the end of programming that the fuses have not
+changed. If you want to change fuses you will need to specify this option,
+as avrdude will see the fuses have changed (even though you wanted to) and
+will change them back for your "safety". This option was designed to
+prevent cases of fuse bits magically changing (usually called @emph{safemode}).
+
+If one of the configuration files contains a line
+
+@code{default_safemode = no;}
+
+safemode is disabled by default.
+The @option{-u} option's effect is negated in that case, i. e. it
+@emph{enables} safemode.
+
+Safemode is always disabled for AVR32, Xmega and TPI devices.
+
+@item -s
+Disable safemode prompting. When safemode discovers that one or more
+fuse bits have unintentionally changed, it will prompt for
+confirmation regarding whether or not it should attempt to recover the
+fuse bit(s). Specifying this flag disables the prompt and assumes
+that the fuse bit(s) should be recovered without asking for
+confirmation first.
+
+@item -t
+Tells AVRDUDE to enter the interactive ``terminal'' mode instead of up-
+or downloading files. See below for a detailed description of the
+terminal mode.
+
+@item -U @var{memtype}:@var{op}:@var{filename}[:@var{format}]
+Perform a memory operation.
+Multiple @option{-U} options can be specified in order to operate on
+multiple memories on the same command-line invocation. The
+@var{memtype} field specifies the memory type to operate on. Use
+the @option{-v} option on the command line or the @code{part} command from
+terminal mode to display all the memory types supported by a particular
+device.
+Typically, a device's memory configuration at least contains
+the memory types
+@code{flash}
+and
+@code{eeprom}.
+All memory types currently known are:
+@table @code
+@item calibration
+One or more bytes of RC oscillator calibration data.
+@item eeprom
+The EEPROM of the device.
+@item efuse
+The extended fuse byte.
+@item flash
+The flash ROM of the device.
+@item fuse
+The fuse byte in devices that have only a single fuse byte.
+@item hfuse
+The high fuse byte.
+@item lfuse
+The low fuse byte.
+@item lock
+The lock byte.
+@item signature
+The three device signature bytes (device ID).
+@item fuse@emph{N}
+The fuse bytes of ATxmega devices, @emph{N} is an integer number
+for each fuse supported by the device.
+@item application
+The application flash area of ATxmega devices.
+@item apptable
+The application table flash area of ATxmega devices.
+@item boot
+The boot flash area of ATxmega devices.
+@item prodsig
+The production signature (calibration) area of ATxmega devices.
+@item usersig
+The user signature area of ATxmega devices.
+@end table
+
+The @var{op} field specifies what operation to perform:
+
+@table @code
+@item r
+read the specified device memory and write to the specified file
+
+@item w
+read the specified file and write it to the specified device memory
+
+@item v
+read the specified device memory and the specified file and perform a verify operation
+
+@end table
+
+The @var{filename} field indicates the name of the file to read or
+write. The @var{format} field is optional and contains the format of
+the file to read or write. Possible values are:
+
+@table @code
+@item i
+Intel Hex
+
+@item s
+Motorola S-record
+
+@item r
+raw binary; little-endian byte order, in the case of the flash ROM data
+
+@item e
+ELF (Executable and Linkable Format), the final output file from the
+linker; currently only accepted as an input file
+
+@item m
+immediate mode; actual byte values specified on the command line,
+separated by commas or spaces in place of the @var{filename} field of
+the @option{-U} option. This is useful
+for programming fuse bytes without having to create a single-byte file
+or enter terminal mode. If the number specified begins with @code{0x},
+it is treated as a hex value. If the number otherwise begins with a
+leading zero (@code{0}) it is treated as octal. Otherwise, the value is
+treated as decimal.
+
+@item a
+auto detect; valid for input only, and only if the input is not provided
+at stdin.
+
+@item d
+decimal; this and the following formats are only valid on output.
+They generate one line of output for the respective memory section,
+forming a comma-separated list of the values.
+This can be particularly useful for subsequent processing, like for
+fuse bit settings.
+
+@item h
+hexadecimal; each value will get the string @emph{0x} prepended.
+
+@item o
+octal; each value will get a @emph{0}
+prepended unless it is less than 8 in which case it gets no prefix.
+
+@item b
+binary; each value will get the string @emph{0b} prepended.
+
+@end table
+
+The default is to use auto detection for input files, and raw binary
+format for output files.
+
+Note that if @var{filename} contains a colon, the @var{format} field is
+no longer optional since the filename part following the colon would
+otherwise be misinterpreted as @var{format}.
+
+When reading any kind of flash memory area (including the various sub-areas
+in Xmega devices), the resulting output file will be truncated to not contain
+trailing 0xFF bytes which indicate unprogrammed (erased) memory.
+Thus, if the entire memory is unprogrammed, this will result in an output
+file that has no contents at all.
+
+As an abbreviation, the form @code{-U} @var{filename}
+is equivalent to specifying
+@code{-U} @emph{flash:w:}@var{filename}@emph{:a}.
+This will only work if @var{filename} does not have a colon in it.
+
+@item -v
+Enable verbose output.
+More @code{-v} options increase verbosity level.
+
+@item -V
+Disable automatic verify check when uploading data.
+
+@item -x @var{extended_param}
+Pass @var{extended_param} to the chosen programmer implementation as
+an extended parameter. The interpretation of the extended parameter
+depends on the programmer itself. See below for a list of programmers
+accepting extended parameters.
+
+@end table
+
+@page
+@c
+@c Node
+@c
+@node Programmers accepting extended parameters, Example Command Line Invocations, Option Descriptions, Command Line Options
+@section Programmers accepting extended parameters
+
+@table @code
+
+@item JTAG ICE mkII/3
+@itemx AVR Dragon
+
+When using the JTAG ICE mkII/3 or AVR Dragon in JTAG mode, the
+following extended parameter is accepted:
+@table @code
+@item @samp{jtagchain=UB,UA,BB,BA}
+Setup the JTAG scan chain for @var{UB} units before, @var{UA} units
+after, @var{BB} bits before, and @var{BA} bits after the target AVR,
+respectively.
+Each AVR unit within the chain shifts by 4 bits.
+Other JTAG units might require a different bit shift count.
+@end table
+
+@item AVR910
+
+The AVR910 programmer type accepts the following extended parameter:
+@table @code
+@item @samp{devcode=VALUE}
+Override the device code selection by using @var{VALUE}
+as the device code.
+The programmer is not queried for the list of supported
+device codes, and the specified @var{VALUE}
+is not verified but used directly within the
+@code{T} command sent to the programmer.
+@var{VALUE} can be specified using the conventional number notation of the
+C programming language.
+@item @samp{no_blockmode}
+Disables the default checking for block transfer capability.
+Use
+@samp{no_blockmode} only if your @samp{AVR910}
+programmer creates errors during initial sequence.
+@end table
+
+@item BusPirate
+
+The BusPirate programmer type accepts the following extended parameters:
+@table @code
+@item @samp{reset=cs,aux,aux2}
+The default setup assumes the BusPirate's CS output pin connected to
+the RESET pin on AVR side. It is however possible to have multiple AVRs
+connected to the same BP with MISO, MOSI and SCK lines common for all of them.
+In such a case one AVR should have its RESET connected to BusPirate's
+@emph{CS}
+pin, second AVR's RESET connected to BusPirate's
+@emph{AUX}
+pin and if your BusPirate has an
+@emph{AUX2}
+pin (only available on BusPirate version v1a with firmware 3.0 or newer)
+use that to activate RESET on the third AVR.
+
+It may be a good idea to decouple the BusPirate and the AVR's SPI buses from
+each other using a 3-state bus buffer. For example 74HC125 or 74HC244 are some
+good candidates with the latches driven by the appropriate reset pin (cs,
+aux or aux2). Otherwise the SPI traffic in one active circuit may interfere
+with programming the AVR in the other design.
+
+@item @samp{spifreq=@var{0..7}}
+@multitable @columnfractions .05 .3
+@item @code{0} @tab 30 kHz (default)
+@item @code{1} @tab 125 kHz
+@item @code{2} @tab 250 kHz
+@item @code{3} @tab 1 MHz
+@item @code{4} @tab 2 MHz
+@item @code{5} @tab 2.6 MHz
+@item @code{6} @tab 4 MHz
+@item @code{7} @tab 8 MHz
+@end multitable
+
+@item @samp{rawfreq=0..3}
+Sets the SPI speed and uses the Bus Pirate's binary ``raw-wire'' mode instead
+of the default binary SPI mode:
+
+@multitable @columnfractions .05 .3
+@item @code{0} @tab 5 kHz
+@item @code{1} @tab 50 kHz
+@item @code{2} @tab 100 kHz (Firmware v4.2+ only)
+@item @code{3} @tab 400 kHz (v4.2+)
+@end multitable
+
+The only advantage of the ``raw-wire'' mode is that different SPI frequencies
+are available. Paged writing is not implemented in this mode.
+
+@item @samp{ascii}
+Attempt to use ASCII mode even when the firmware supports BinMode (binary
+mode).
+BinMode is supported in firmware 2.7 and newer, older FW's either don't
+have BinMode or their BinMode is buggy. ASCII mode is slower and makes
+the above
+@samp{reset=}, @samp{spifreq=}
+and
+@samp{rawfreq=}
+parameters unavailable. Be aware that ASCII mode is not guaranteed to work
+with newer firmware versions, and is retained only to maintain compatibility
+with older firmware versions.
+
+@item @samp{nopagedwrite}
+Firmware versions 5.10 and newer support a binary mode SPI command that enables
+whole pages to be written to AVR flash memory at once, resulting in a
+significant write speed increase. If use of this mode is not desirable for some
+reason, this option disables it.
+
+@item @samp{nopagedread}
+Newer firmware versions support in binary mode SPI command some AVR Extended
+Commands. Using the ``Bulk Memory Read from Flash'' results in a
+significant read speed increase. If use of this mode is not desirable for some
+reason, this option disables it.
+
+@item @samp{cpufreq=@var{125..4000}}
+This sets the @emph{AUX} pin to output a frequency of @var{n} kHz. Connecting
+the @emph{AUX} pin to the XTAL1 pin of your MCU, you can provide it a clock,
+for example when it needs an external clock because of wrong fuses settings.
+Make sure the CPU frequency is at least four times the SPI frequency.
+
+@item @samp{serial_recv_timeout=@var{1...}}
+This sets the serial receive timeout to the given value.
+The timeout happens every time avrdude waits for the BusPirate prompt.
+Especially in ascii mode this happens very often, so setting a smaller value
+can speed up programming a lot.
+The default value is 100ms. Using 10ms might work in most cases.
+
+@end table
+
+@item Wiring
+
+When using the Wiring programmer type, the
+following optional extended parameter is accepted:
+@table @code
+@item @samp{snooze=@var{0..32767}}
+After performing the port open phase, AVRDUDE will wait/snooze for
+@var{snooze} milliseconds before continuing to the protocol sync phase.
+No toggling of DTR/RTS is performed if @var{snooze} > 0.
+@end table
+
+@item PICkit2
+Connection to the PICkit2 programmer:
+@multitable @columnfractions .05 .3
+@item @code{(AVR)} @tab @code{(PICkit2)}
+@item @code{RST} @tab @code{VPP/MCLR (1) }
+@item @code{VDD} @tab @code{VDD Target (2) -- possibly optional if AVR self powered }
+@item @code{GND} @tab @code{GND (3) }
+@item @code{MISO} @tab @code{PGD (4) }
+@item @code{SCLK} @tab @code{PDC (5) }
+@item @code{OSI} @tab @code{AUX (6) }
+@end multitable
+
+Extended command line parameters:
+@table @code
+@item @samp{clockrate=@var{rate}}
+Sets the SPI clocking rate in Hz (default is 100kHz). Alternately the -B or -i options can be used to set the period.
+@item @samp{timeout=@var{usb-transaction-timeout}}
+Sets the timeout for USB reads and writes in milliseconds (default is 1500 ms).
+@end table
+
+@end table
+
+@page
+@c
+@c Node
+@c
+@node Example Command Line Invocations, , Programmers accepting extended parameters, Command Line Options
+@section Example Command Line Invocations
+
+@noindent
+Download the file @code{diag.hex} to the ATmega128 chip using the
+STK500 programmer connected to the default serial port:
+
+@smallexample
+@cartouche
+% avrdude -p m128 -c stk500 -e -U flash:w:diag.hex
+
+avrdude: AVR device initialized and ready to accept instructions
+
+Reading | ################################################## | 100% 0.03s
+
+avrdude: Device signature = 0x1e9702
+avrdude: erasing chip
+avrdude: done.
+avrdude: performing op: 1, flash, 0, diag.hex
+avrdude: reading input file "diag.hex"
+avrdude: input file diag.hex auto detected as Intel Hex
+avrdude: writing flash (19278 bytes):
+
+Writing | ################################################## | 100% 7.60s
+
+avrdude: 19456 bytes of flash written
+avrdude: verifying flash memory against diag.hex:
+avrdude: load data flash data from input file diag.hex:
+avrdude: input file diag.hex auto detected as Intel Hex
+avrdude: input file diag.hex contains 19278 bytes
+avrdude: reading on-chip flash data:
+
+Reading | ################################################## | 100% 6.83s
+
+avrdude: verifying ...
+avrdude: 19278 bytes of flash verified
+
+avrdude: safemode: Fuses OK
+
+avrdude done. Thank you.
+
+%
+@end cartouche
+@end smallexample
+
+@page
+@noindent
+Upload the flash memory from the ATmega128 connected to the STK500
+programmer and save it in raw binary format in the file named
+@code{c:/diag flash.bin}:
+
+@smallexample
+@cartouche
+% avrdude -p m128 -c stk500 -U flash:r:"c:/diag flash.bin":r
+
+avrdude: AVR device initialized and ready to accept instructions
+
+Reading | ################################################## | 100% 0.03s
+
+avrdude: Device signature = 0x1e9702
+avrdude: reading flash memory:
+
+Reading | ################################################## | 100% 46.10s
+
+avrdude: writing output file "c:/diag flash.bin"
+
+avrdude: safemode: Fuses OK
+
+avrdude done. Thank you.
+
+%
+@end cartouche
+@end smallexample
+
+@page
+@noindent
+Using the default programmer, download the file @code{diag.hex} to
+flash, @code{eeprom.hex} to EEPROM, and set the Extended, High, and Low
+fuse bytes to 0xff, 0x89, and 0x2e respectively:
+
+@smallexample
+@cartouche
+
+% avrdude -p m128 -u -U flash:w:diag.hex \
+> -U eeprom:w:eeprom.hex \
+> -U efuse:w:0xff:m \
+> -U hfuse:w:0x89:m \
+> -U lfuse:w:0x2e:m
+
+avrdude: AVR device initialized and ready to accept instructions
+
+Reading | ################################################## | 100% 0.03s
+
+avrdude: Device signature = 0x1e9702
+avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
+ To disable this feature, specify the -D option.
+avrdude: erasing chip
+avrdude: reading input file "diag.hex"
+avrdude: input file diag.hex auto detected as Intel Hex
+avrdude: writing flash (19278 bytes):
+
+Writing | ################################################## | 100% 7.60s
+
+avrdude: 19456 bytes of flash written
+avrdude: verifying flash memory against diag.hex:
+avrdude: load data flash data from input file diag.hex:
+avrdude: input file diag.hex auto detected as Intel Hex
+avrdude: input file diag.hex contains 19278 bytes
+avrdude: reading on-chip flash data:
+
+Reading | ################################################## | 100% 6.84s
+
+avrdude: verifying ...
+avrdude: 19278 bytes of flash verified
+
+[ ... other memory status output skipped for brevity ... ]
+
+avrdude done. Thank you.
+
+%
+@end cartouche
+@end smallexample
+
+@page
+@noindent
+Connect to the JTAG ICE mkII which serial number ends up in 1C37 via
+USB, and enter terminal mode:
+
+@smallexample
+@cartouche
+
+% avrdude -c jtag2 -p m649 -P usb:1c:37 -t
+
+avrdude: AVR device initialized and ready to accept instructions
+
+Reading | ################################################## | 100% 0.03s
+
+avrdude: Device signature = 0x1e9603
+
+[ ... terminal mode output skipped for brevity ... ]
+
+avrdude done. Thank you.
+
+@end cartouche
+@end smallexample
+
+@noindent
+List the serial numbers of all JTAG ICEs attached to USB. This is
+done by specifying an invalid serial number, and increasing the
+verbosity level.
+
+@smallexample
+@cartouche
+
+% avrdude -c jtag2 -p m128 -P usb:xx -v
+[...]
+ Using Port : usb:xxx
+ Using Programmer : jtag2
+avrdude: usbdev_open(): Found JTAG ICE, serno: 00A000001C6B
+avrdude: usbdev_open(): Found JTAG ICE, serno: 00A000001C3A
+avrdude: usbdev_open(): Found JTAG ICE, serno: 00A000001C30
+avrdude: usbdev_open(): did not find any (matching) USB device "usb:xxx"
+
+@end cartouche
+@end smallexample
+
+
+@c
+@c Node
+@c
+@node Terminal Mode Operation, Configuration File, Command Line Options, Top
+@chapter Terminal Mode Operation
+
+AVRDUDE has an interactive mode called @var{terminal mode} that is
+enabled by the @option{-t} option. This mode allows one to enter
+interactive commands to display and modify the various device memories,
+perform a chip erase, display the device signature bytes and part
+parameters, and to send raw programming commands. Commands and
+parameters may be abbreviated to their shortest unambiguous form.
+Terminal mode also supports a command history so that previously entered
+commands can be recalled and edited.
+
+@menu
+* Terminal Mode Commands::
+* Terminal Mode Examples::
+@end menu
+
+@node Terminal Mode Commands, Terminal Mode Examples, Terminal Mode Operation, Terminal Mode Operation
+@section Terminal Mode Commands
+
+@noindent
+The following commands are implemented:
+
+@table @code
+
+@item dump @var{memtype} @var{addr} @var{nbytes}
+Read @var{nbytes} from the specified memory area, and display them in
+the usual hexadecimal and ASCII form.
+
+@item dump
+Continue dumping the memory contents for another @var{nbytes} where the
+previous dump command left off.
+
+@item write @var{memtype} @var{addr} @var{byte1} @dots{} @var{byteN}
+Manually program the respective memory cells, starting at address addr,
+using the values @var{byte1} through @var{byteN}. This feature is not
+implemented for bank-addressed memories such as the flash memory of
+ATMega devices.
+
+@item erase
+Perform a chip erase.
+
+@item send @var{b1} @var{b2} @var{b3} @var{b4}
+Send raw instruction codes to the AVR device. If you need access to a
+feature of an AVR part that is not directly supported by AVRDUDE, this
+command allows you to use it, even though AVRDUDE does not implement the
+command. When using direct SPI mode, up to 3 bytes
+can be omitted.
+
+@item sig
+Display the device signature bytes.
+
+@item spi
+Enter direct SPI mode. The @emph{pgmled} pin acts as slave select.
+@emph{Only supported on parallel bitbang programmers.}
+
+@item part
+Display the current part settings and parameters. Includes chip
+specific information including all memory types supported by the
+device, read/write timing, etc.
+
+@item pgm
+Return to programming mode (from direct SPI mode).
+
+@item verbose [@var{level}]
+Change (when @var{level} is provided), or display the verbosity
+level.
+The initial verbosity level is controlled by the number of @code{-v} options
+given on the command line.
+
+@item ?
+@itemx help
+Give a short on-line summary of the available commands.
+
+@item quit
+Leave terminal mode and thus AVRDUDE.
+
+@end table
+
+@noindent
+In addition, the following commands are supported on the STK500
+and STK600 programmer:
+
+@table @code
+
+@item vtarg @var{voltage}
+Set the target's supply voltage to @var{voltage} Volts.
+
+@item varef [@var{channel}] @var{voltage}
+Set the adjustable voltage source to @var{voltage} Volts.
+This voltage is normally used to drive the target's
+@emph{Aref} input on the STK500 and STK600.
+The STK600 offers two reference voltages, which can be
+selected by the optional parameter @var{channel} (either
+0 or 1).
+
+@item fosc @var{freq}[@code{M}|@code{k}]
+Set the master oscillator to @var{freq} Hz.
+An optional trailing letter @code{M}
+multiplies by 1E6, a trailing letter @code{k} by 1E3.
+
+@item fosc off
+Turn the master oscillator off.
+
+@item sck @var{period}
+@emph{STK500 and STK600 only:}
+Set the SCK clock period to @var{period} microseconds.
+
+@emph{JTAG ICE only:}
+Set the JTAG ICE bit clock period to @var{period} microseconds.
+Note that unlike STK500 settings, this setting will be reverted to
+its default value (approximately 1 microsecond) when the programming
+software signs off from the JTAG ICE.
+This parameter can also be used on the JTAG ICE mkII/3 to specify the
+ISP clock period when operating the ICE in ISP mode.
+
+@item parms
+@emph{STK500 and STK600 only:}
+Display the current voltage and master oscillator parameters.
+
+@emph{JTAG ICE only:}
+Display the current target supply voltage and JTAG bit clock rate/period.
+
+@end table
+
+@c
+@c Node
+@c
+@node Terminal Mode Examples, , Terminal Mode Commands, Terminal Mode Operation
+@section Terminal Mode Examples
+
+@noindent
+Display part parameters, modify eeprom cells, perform a chip erase:
+
+@smallexample
+@cartouche
+% avrdude -p m128 -c stk500 -t
+
+avrdude: AVR device initialized and ready to accept instructions
+avrdude: Device signature = 0x1e9702
+avrdude: current erase-rewrite cycle count is 52 (if being tracked)
+avrdude> part
+>>> part
+
+AVR Part : ATMEGA128
+Chip Erase delay : 9000 us
+PAGEL : PD7
+BS2 : PA0
+RESET disposition : dedicated
+RETRY pulse : SCK
+serial program mode : yes
+parallel program mode : yes
+Memory Detail :
+
+ Page Polled
+ Memory Type Paged Size Size #Pages MinW MaxW ReadBack
+ ----------- ------ ------ ---- ------ ----- ----- ---------
+ eeprom no 4096 8 0 9000 9000 0xff 0xff
+ flash yes 131072 256 512 4500 9000 0xff 0x00
+ lfuse no 1 0 0 0 0 0x00 0x00
+ hfuse no 1 0 0 0 0 0x00 0x00
+ efuse no 1 0 0 0 0 0x00 0x00
+ lock no 1 0 0 0 0 0x00 0x00
+ calibration no 1 0 0 0 0 0x00 0x00
+ signature no 3 0 0 0 0 0x00 0x00
+
+avrdude> dump eeprom 0 16
+>>> dump eeprom 0 16
+0000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
+
+avrdude> write eeprom 0 1 2 3 4
+>>> write eeprom 0 1 2 3 4
+
+avrdude> dump eeprom 0 16
+>>> dump eeprom 0 16
+0000 01 02 03 04 ff ff ff ff ff ff ff ff ff ff ff ff |................|
+
+avrdude> erase
+>>> erase
+avrdude: erasing chip
+avrdude> dump eeprom 0 16
+>>> dump eeprom 0 16
+0000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
+
+avrdude>
+@end cartouche
+@end smallexample
+
+
+@noindent
+Program the fuse bits of an ATmega128 (disable M103 compatibility,
+enable high speed external crystal, enable brown-out detection, slowly
+rising power). Note since we are working with fuse bits the -u (unsafe)
+option is specified, which allows you to modify the fuse bits. First
+display the factory defaults, then reprogram:
+
+@smallexample
+@cartouche
+% avrdude -p m128 -u -c stk500 -t
+
+avrdude: AVR device initialized and ready to accept instructions
+avrdude: Device signature = 0x1e9702
+avrdude: current erase-rewrite cycle count is 52 (if being tracked)
+avrdude> d efuse
+>>> d efuse
+0000 fd |. |
+
+avrdude> d hfuse
+>>> d hfuse
+0000 99 |. |
+
+avrdude> d lfuse
+>>> d lfuse
+0000 e1 |. |
+
+avrdude> w efuse 0 0xff
+>>> w efuse 0 0xff
+
+avrdude> w hfuse 0 0x89
+>>> w hfuse 0 0x89
+
+avrdude> w lfuse 0 0x2f
+>>> w lfuse 0 0x2f
+
+avrdude>
+@end cartouche
+@end smallexample
+
+
+@c
+@c Node
+@c
+@node Configuration File, Programmer Specific Information, Terminal Mode Operation, Top
+@chapter Configuration File
+
+@noindent
+AVRDUDE reads a configuration file upon startup which describes all of
+the parts and programmers that it knows about. The advantage of this is
+that if you have a chip that is not currently supported by AVRDUDE, you
+can add it to the configuration file without waiting for a new release
+of AVRDUDE. Likewise, if you have a parallel port programmer that is
+not supported by AVRDUDE, chances are good that you can copy and
+existing programmer definition, and with only a few changes, make your
+programmer work with AVRDUDE.
+
+AVRDUDE first looks for a system wide configuration file in a platform
+dependent location. On Unix, this is usually
+@code{/usr/local/etc/avrdude.conf}, while on Windows it is usually in the
+same location as the executable file. The name of this file can be
+changed using the @option{-C} command line option. After the system wide
+configuration file is parsed, AVRDUDE looks for a per-user configuration
+file to augment or override the system wide defaults. On Unix, the
+per-user file is @code{.avrduderc} within the user's home directory. On
+Windows, this file is the @code{avrdude.rc} file located in the same
+directory as the executable.
+
+@menu
+* AVRDUDE Defaults::
+* Programmer Definitions::
+* Part Definitions::
+* Other Notes::
+@end menu
+
+@c
+@c Node
+@c
+@node AVRDUDE Defaults, Programmer Definitions, Configuration File, Configuration File
+@section AVRDUDE Defaults
+
+@table @code
+
+@item default_parallel = "@var{default-parallel-device}";
+Assign the default parallel port device. Can be overridden using the
+@option{-P} option.
+
+@item default_serial = "@var{default-serial-device}";
+Assign the default serial port device. Can be overridden using the
+@option{-P} option.
+
+@item default_programmer = "@var{default-programmer-id}";
+Assign the default programmer id. Can be overridden using the @option{-c}
+option.
+
+@item default_bitclock = "@var{default-bitclock}";
+Assign the default bitclock value. Can be overridden using the @option{-B}
+option.
+
+@end table
+
+
+@c
+@c Node
+@c
+@node Programmer Definitions, Part Definitions, AVRDUDE Defaults, Configuration File
+@section Programmer Definitions
+
+@noindent
+The format of the programmer definition is as follows:
+
+@smallexample
+programmer
+ parent <id> # <id> is a quoted string
+ id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
+ desc = <description> ; # quoted string
+ type = "par" | "stk500" | ... ; # programmer type (see below for a list)
+ baudrate = <num> ; # baudrate for serial ports
+ vcc = <num1> [, <num2> ... ] ; # pin number(s)
+ buff = <num1> [, <num2> ... ] ; # pin number(s)
+ reset = <num> ; # pin number
+ sck = <num> ; # pin number
+ mosi = <num> ; # pin number
+ miso = <num> ; # pin number
+ errled = <num> ; # pin number
+ rdyled = <num> ; # pin number
+ pgmled = <num> ; # pin number
+ vfyled = <num> ; # pin number
+ usbvid = <hexnum>; # USB VID (Vendor ID)
+ usbpid = <hexnum> [, <hexnum> ...]; # USB PID (Product ID)
+ usbdev = <interface>; # USB interface or other device info
+ usbvendor = <vendorname>; # USB Vendor Name
+ usbproduct = <productname>; # USB Product Name
+ usbsn = <serialno>; # USB Serial Number
+ ;
+@end smallexample
+
+@noindent
+If a parent is specified, all settings of it (except its ids) are used for the new
+programmer. These values can be changed by new setting them for the new programmer.
+
+@noindent
+To invert a bit in the pin definitions, use @code{= ~ <num>}.
+
+@noindent
+Not all programmer types can handle a list of USB PIDs.
+
+@noindent
+Following programmer types are currently implemented:
+
+@multitable @columnfractions .25 .6
+@include programmer_types.texi
+@end multitable
+
+@c
+@c Node
+@c
+@node Part Definitions, Other Notes, Programmer Definitions, Configuration File
+@section Part Definitions
+
+@smallexample
+part
+ id = <id> ; # quoted string
+ desc = <description> ; # quoted string
+ has_jtag = <yes/no> ; # part has JTAG i/f
+ has_debugwire = <yes/no> ; # part has debugWire i/f
+ has_pdi = <yes/no> ; # part has PDI i/f
+ has_tpi = <yes/no> ; # part has TPI i/f
+ devicecode = <num> ; # numeric
+ stk500_devcode = <num> ; # numeric
+ avr910_devcode = <num> ; # numeric
+ signature = <num> <num> <num> ; # signature bytes
+ usbpid = <num> ; # DFU USB PID
+ reset = dedicated | io;
+ retry_pulse = reset | sck;
+ pgm_enable = <instruction format> ;
+ chip_erase = <instruction format> ;
+ chip_erase_delay = <num> ; # micro-seconds
+ # STK500 parameters (parallel programming IO lines)
+ pagel = <num> ; # pin name in hex, i.e., 0xD7
+ bs2 = <num> ; # pin name in hex, i.e., 0xA0
+ serial = <yes/no> ; # can use serial downloading
+ parallel = <yes/no/pseudo>; # can use par. programming
+ # STK500v2 parameters, to be taken from Atmel's XML files
+ timeout = <num> ;
+ stabdelay = <num> ;
+ cmdexedelay = <num> ;
+ synchloops = <num> ;
+ bytedelay = <num> ;
+ pollvalue = <num> ;
+ pollindex = <num> ;
+ predelay = <num> ;
+ postdelay = <num> ;
+ pollmethod = <num> ;
+ mode = <num> ;
+ delay = <num> ;
+ blocksize = <num> ;
+ readsize = <num> ;
+ hvspcmdexedelay = <num> ;
+ # STK500v2 HV programming parameters, from XML
+ pp_controlstack = <num>, <num>, ...; # PP only
+ hvsp_controlstack = <num>, <num>, ...; # HVSP only
+ hventerstabdelay = <num>;
+ progmodedelay = <num>; # PP only
+ latchcycles = <num>;
+ togglevtg = <num>;
+ poweroffdelay = <num>;
+ resetdelayms = <num>;
+ resetdelayus = <num>;
+ hvleavestabdelay = <num>;
+ resetdelay = <num>;
+ synchcycles = <num>; # HVSP only
+ chiperasepulsewidth = <num>; # PP only
+ chiperasepolltimeout = <num>;
+ chiperasetime = <num>; # HVSP only
+ programfusepulsewidth = <num>; # PP only
+ programfusepolltimeout = <num>;
+ programlockpulsewidth = <num>; # PP only
+ programlockpolltimeout = <num>;
+ # JTAG ICE mkII parameters, also from XML files
+ allowfullpagebitstream = <yes/no> ;
+ enablepageprogramming = <yes/no> ;
+ idr = <num> ; # IO addr of IDR (OCD) reg.
+ rampz = <num> ; # IO addr of RAMPZ reg.
+ spmcr = <num> ; # mem addr of SPMC[S]R reg.
+ eecr = <num> ; # mem addr of EECR reg.
+ # (only when != 0x3c)
+ is_at90s1200 = <yes/no> ; # AT90S1200 part
+ is_avr32 = <yes/no> ; # AVR32 part
+
+ memory <memtype>
+ paged = <yes/no> ; # yes / no
+ size = <num> ; # bytes
+ page_size = <num> ; # bytes
+ num_pages = <num> ; # numeric
+ min_write_delay = <num> ; # micro-seconds
+ max_write_delay = <num> ; # micro-seconds
+ readback_p1 = <num> ; # byte value
+ readback_p2 = <num> ; # byte value
+ pwroff_after_write = <yes/no> ; # yes / no
+ read = <instruction format> ;
+ write = <instruction format> ;
+ read_lo = <instruction format> ;
+ read_hi = <instruction format> ;
+ write_lo = <instruction format> ;
+ write_hi = <instruction format> ;
+ loadpage_lo = <instruction format> ;
+ loadpage_hi = <instruction format> ;
+ writepage = <instruction format> ;
+ ;
+ ;
+@end smallexample
+
+@menu
+* Parent Part::
+* Instruction Format::
+@end menu
+
+@c
+@c Node
+@c
+@node Parent Part, Instruction Format, Part Definitions, Part Definitions
+@subsection Parent Part
+
+@noindent
+Parts can also inherit parameters from previously defined parts
+using the following syntax. In this case specified integer and
+string values override parameter values from the parent part. New
+memory definitions are added to the definitions inherited from the
+parent.
+
+@smallexample
+ part parent <id> # quoted string
+ id = <id> ; # quoted string
+ <any set of other parameters from the list above>
+ ;
+@end smallexample
+
+@c
+@c Node
+@c
+@node Instruction Format, , Parent Part, Part Definitions
+@subsection Instruction Format
+
+@noindent
+Instruction formats are specified as a comma separated list of string
+values containing information (bit specifiers) about each of the 32 bits
+of the instruction. Bit specifiers may be one of the following formats:
+
+@table @code
+
+@item 1
+The bit is always set on input as well as output
+
+@item 0
+the bit is always clear on input as well as output
+
+@item x
+the bit is ignored on input and output
+
+@item a
+the bit is an address bit, the bit-number matches this bit specifier's
+position within the current instruction byte
+
+@item a@var{N}
+the bit is the @var{N}th address bit, bit-number = N, i.e., @code{a12}
+is address bit 12 on input, @code{a0} is address bit 0.
+
+@item i
+the bit is an input data bit
+
+@item o
+the bit is an output data bit
+
+@end table
+
+Each instruction must be composed of 32 bit specifiers. The instruction
+specification closely follows the instruction data provided in Atmel's
+data sheets for their parts. For example, the EEPROM read and write
+instruction for an AT90S2313 AVR part could be encoded as:
+
+@smallexample
+
+read = "1 0 1 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
+
+write = "1 1 0 0 0 0 0 0 x x x x x x x x",
+ "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
+
+@end smallexample
+
+
+
+@c
+@c Node
+@c
+@node Other Notes, , Part Definitions, Configuration File
+@section Other Notes
+
+
+@itemize @bullet
+@item
+The @code{devicecode} parameter is the device code used by the STK500
+and is obtained from the software section (@code{avr061.zip}) of
+Atmel's AVR061 application note available from
+@url{http://www.atmel.com/dyn/resources/prod_documents/doc2525.pdf}.
+
+@item
+Not all memory types will implement all instructions.
+
+@item
+AVR Fuse bits and Lock bits are implemented as a type of memory.
+
+@item
+Example memory types are: @code{flash}, @code{eeprom}, @code{fuse},
+@code{lfuse} (low fuse), @code{hfuse} (high fuse), @code{efuse}
+(extended fuse), @code{signature}, @code{calibration}, @code{lock}.
+
+@item
+The memory type specified on the AVRDUDE command line must match one of
+the memory types defined for the specified chip.
+
+@item
+The @code{pwroff_after_write} flag causes AVRDUDE to attempt to power
+the device off and back on after an unsuccessful write to the affected
+memory area if VCC programmer pins are defined. If VCC pins are not
+defined for the programmer, a message indicating that the device needs a
+power-cycle is printed out. This flag was added to work around a
+problem with the at90s4433/2333's; see the at90s4433 errata at:
+
+ @url{http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf}
+
+@item
+The boot loader from application note AVR109 (and thus also the AVR
+Butterfly) does not support writing of fuse bits. Writing lock bits
+is supported, but is restricted to the boot lock bits (BLBxx). These
+are restrictions imposed by the underlying SPM instruction that is used
+to program the device from inside the boot loader. Note that programming
+the boot lock bits can result in a ``shoot-into-your-foot'' scenario as
+the only way to unprogram these bits is a chip erase, which will also
+erase the boot loader code.
+
+The boot loader implements the ``chip erase'' function by erasing the
+flash pages of the application section.
+
+Reading fuse and lock bits is fully supported.
+
+Note that due to the inability to write the fuse bits, the safemode
+functionality does not make sense for these boot loaders.
+
+@end itemize
+
+@c
+@c Node
+@c
+@node Programmer Specific Information, Platform Dependent Information, Configuration File, Top
+@chapter Programmer Specific Information
+
+@menu
+* Atmel STK600::
+* Atmel DFU bootloader using FLIP version 1::
+@end menu
+
+@c
+@c Node
+@c
+@node Atmel STK600, Atmel DFU bootloader using FLIP version 1, Programmer Specific Information, Programmer Specific Information
+@section Atmel STK600
+
+@c
+@c Update the table below by running the tools/get-stk600-devices.xsl
+@c XSLT transformation on targetboard.xml as shipped by the latest
+@c release of AVR Studio.
+@c
+The following devices are supported by the respective STK600 routing
+and socket card:
+
+@multitable @columnfractions .25 .25 .5
+@headitem Routing card @tab Socket card @tab Devices
+@item @code{} @tab @code{STK600-ATTINY10} @tab ATtiny4 ATtiny5 ATtiny9 ATtiny10
+@item @code{STK600-RC008T-2} @tab @code{STK600-DIP} @tab ATtiny11 ATtiny12 ATtiny13 ATtiny13A ATtiny25 ATtiny45 ATtiny85
+@item @code{STK600-RC008T-7} @tab @code{STK600-DIP} @tab ATtiny15
+@item @code{STK600-RC014T-42} @tab @code{STK600-SOIC} @tab ATtiny20
+@item @code{STK600-RC020T-1} @tab @code{STK600-DIP} @tab ATtiny2313 ATtiny2313A ATtiny4313
+@item @code{} @tab @code{STK600-TinyX3U} @tab ATtiny43U
+@item @code{STK600-RC014T-12} @tab @code{STK600-DIP} @tab ATtiny24 ATtiny44 ATtiny84 ATtiny24A ATtiny44A
+@item @code{STK600-RC020T-8} @tab @code{STK600-DIP} @tab ATtiny26 ATtiny261 ATtiny261A ATtiny461 ATtiny861 ATtiny861A
+@item @code{STK600-RC020T-43} @tab @code{STK600-SOIC} @tab ATtiny261 ATtiny261A ATtiny461 ATtiny461A ATtiny861 ATtiny861A
+@item @code{STK600-RC020T-23} @tab @code{STK600-SOIC} @tab ATtiny87 ATtiny167
+@item @code{STK600-RC028T-3} @tab @code{STK600-DIP} @tab ATtiny28
+@item @code{STK600-RC028M-6} @tab @code{STK600-DIP} @tab ATtiny48 ATtiny88 ATmega8 ATmega8A ATmega48 ATmega88 ATmega168 ATmega48P ATmega48PA ATmega88P ATmega88PA ATmega168P ATmega168PA ATmega328P
+@item @code{} @tab @code{QT600-ATTINY88-QT8} @tab ATtiny88
+@item @code{STK600-RC040M-4} @tab @code{STK600-DIP} @tab ATmega8515 ATmega162
+@item @code{STK600-RC044M-30} @tab @code{STK600-TQFP44} @tab ATmega8515 ATmega162
+@item @code{STK600-RC040M-5} @tab @code{STK600-DIP} @tab ATmega8535 ATmega16 ATmega16A ATmega32 ATmega32A ATmega164P ATmega164PA ATmega324P ATmega324PA ATmega644 ATmega644P ATmega644PA ATmega1284P
+@item @code{STK600-RC044M-31} @tab @code{STK600-TQFP44} @tab ATmega8535 ATmega16 ATmega16A ATmega32 ATmega32A ATmega164P ATmega164PA ATmega324P ATmega324PA ATmega644 ATmega644P ATmega644PA ATmega1284P
+@item @code{} @tab @code{QT600-ATMEGA324-QM64} @tab ATmega324PA
+@item @code{STK600-RC032M-29} @tab @code{STK600-TQFP32} @tab ATmega8 ATmega8A ATmega48 ATmega88 ATmega168 ATmega48P ATmega48PA ATmega88P ATmega88PA ATmega168P ATmega168PA ATmega328P
+@item @code{STK600-RC064M-9} @tab @code{STK600-TQFP64} @tab ATmega64 ATmega64A ATmega128 ATmega128A ATmega1281 ATmega2561 AT90CAN32 AT90CAN64 AT90CAN128
+@item @code{STK600-RC064M-10} @tab @code{STK600-TQFP64} @tab ATmega165 ATmega165P ATmega169 ATmega169P ATmega169PA ATmega325 ATmega325P ATmega329 ATmega329P ATmega645 ATmega649 ATmega649P
+@item @code{STK600-RC100M-11} @tab @code{STK600-TQFP100} @tab ATmega640 ATmega1280 ATmega2560
+@item @code{} @tab @code{STK600-ATMEGA2560} @tab ATmega2560
+@item @code{STK600-RC100M-18} @tab @code{STK600-TQFP100} @tab ATmega3250 ATmega3250P ATmega3290 ATmega3290P ATmega6450 ATmega6490
+@item @code{STK600-RC032U-20} @tab @code{STK600-TQFP32} @tab AT90USB82 AT90USB162 ATmega8U2 ATmega16U2 ATmega32U2
+@item @code{STK600-RC044U-25} @tab @code{STK600-TQFP44} @tab ATmega16U4 ATmega32U4
+@item @code{STK600-RC064U-17} @tab @code{STK600-TQFP64} @tab ATmega32U6 AT90USB646 AT90USB1286 AT90USB647 AT90USB1287
+@item @code{STK600-RCPWM-22} @tab @code{STK600-TQFP32} @tab ATmega32C1 ATmega64C1 ATmega16M1 ATmega32M1 ATmega64M1
+@item @code{STK600-RCPWM-19} @tab @code{STK600-SOIC} @tab AT90PWM2 AT90PWM3 AT90PWM2B AT90PWM3B AT90PWM216 AT90PWM316
+@item @code{STK600-RCPWM-26} @tab @code{STK600-SOIC} @tab AT90PWM81
+@item @code{STK600-RC044M-24} @tab @code{STK600-TSSOP44} @tab ATmega16HVB ATmega32HVB
+@item @code{} @tab @code{STK600-HVE2} @tab ATmega64HVE
+@item @code{} @tab @code{STK600-ATMEGA128RFA1} @tab ATmega128RFA1
+@item @code{STK600-RC100X-13} @tab @code{STK600-TQFP100} @tab ATxmega64A1 ATxmega128A1 ATxmega128A1_revD ATxmega128A1U
+@item @code{} @tab @code{STK600-ATXMEGA1281A1} @tab ATxmega128A1
+@item @code{} @tab @code{QT600-ATXMEGA128A1-QT16} @tab ATxmega128A1
+@item @code{STK600-RC064X-14} @tab @code{STK600-TQFP64} @tab ATxmega64A3 ATxmega128A3 ATxmega256A3 ATxmega64D3 ATxmega128D3 ATxmega192D3 ATxmega256D3
+@item @code{STK600-RC064X-14} @tab @code{STK600-MLF64} @tab ATxmega256A3B
+@item @code{STK600-RC044X-15} @tab @code{STK600-TQFP44} @tab ATxmega32A4 ATxmega16A4 ATxmega16D4 ATxmega32D4
+@item @code{} @tab @code{STK600-ATXMEGAT0} @tab ATxmega32T0
+@item @code{} @tab @code{STK600-uC3-144} @tab AT32UC3A0512 AT32UC3A0256 AT32UC3A0128
+@item @code{STK600-RCUC3A144-33} @tab @code{STK600-TQFP144} @tab AT32UC3A0512 AT32UC3A0256 AT32UC3A0128
+@item @code{STK600-RCuC3A100-28} @tab @code{STK600-TQFP100} @tab AT32UC3A1512 AT32UC3A1256 AT32UC3A1128
+@item @code{STK600-RCuC3B0-21} @tab @code{STK600-TQFP64-2} @tab AT32UC3B0256 AT32UC3B0512RevC AT32UC3B0512 AT32UC3B0128 AT32UC3B064 AT32UC3D1128
+@item @code{STK600-RCuC3B48-27} @tab @code{STK600-TQFP48} @tab AT32UC3B1256 AT32UC3B164
+@item @code{STK600-RCUC3A144-32} @tab @code{STK600-TQFP144} @tab AT32UC3A3512 AT32UC3A3256 AT32UC3A3128 AT32UC3A364 AT32UC3A3256S AT32UC3A3128S AT32UC3A364S
+@item @code{STK600-RCUC3C0-36} @tab @code{STK600-TQFP144} @tab AT32UC3C0512 AT32UC3C0256 AT32UC3C0128 AT32UC3C064
+@item @code{STK600-RCUC3C1-38} @tab @code{STK600-TQFP100} @tab AT32UC3C1512 AT32UC3C1256 AT32UC3C1128 AT32UC3C164
+@item @code{STK600-RCUC3C2-40} @tab @code{STK600-TQFP64-2} @tab AT32UC3C2512 AT32UC3C2256 AT32UC3C2128 AT32UC3C264
+@item @code{STK600-RCUC3C0-37} @tab @code{STK600-TQFP144} @tab AT32UC3C0512 AT32UC3C0256 AT32UC3C0128 AT32UC3C064
+@item @code{STK600-RCUC3C1-39} @tab @code{STK600-TQFP100} @tab AT32UC3C1512 AT32UC3C1256 AT32UC3C1128 AT32UC3C164
+@item @code{STK600-RCUC3C2-41} @tab @code{STK600-TQFP64-2} @tab AT32UC3C2512 AT32UC3C2256 AT32UC3C2128 AT32UC3C264
+@item @code{STK600-RCUC3L0-34} @tab @code{STK600-TQFP48} @tab AT32UC3L064 AT32UC3L032 AT32UC3L016
+@item @code{} @tab @code{QT600-AT32UC3L-QM64} @tab AT32UC3L064
+@end multitable
+
+Ensure the correct socket and routing card are mounted @emph{before}
+powering on the STK600. While the STK600 firmware ensures the socket
+and routing card mounted match each other (using a table stored
+internally in nonvolatile memory), it cannot handle the case where a
+wrong routing card is used, e. g. the routing card
+@code{STK600-RC040M-5} (which is meant for 40-pin DIP AVRs that have
+an ADC, with the power supply pins in the center of the package) was
+used but an ATmega8515 inserted (which uses the ``industry standard''
+pinout with Vcc and GND at opposite corners).
+
+Note that for devices that use the routing card @code{STK600-RC008T-2},
+in order to use ISP mode, the jumper for @code{AREF0} must be removed
+as it would otherwise block one of the ISP signals. High-voltage
+serial programming can be used even with that jumper installed.
+
+The ISP system of the STK600 contains a detection against shortcuts
+and other wiring errors. AVRDUDE initiates a connection check before
+trying to enter ISP programming mode, and display the result if the
+target is not found ready to be ISP programmed.
+
+High-voltage programming requires the target voltage to be set to at
+least 4.5 V in order to work. This can be done using
+@emph{Terminal Mode}, see @ref{Terminal Mode Operation}.
+
+@c
+@c Node
+@c
+@node Atmel DFU bootloader using FLIP version 1, , Atmel STK600, Programmer Specific Information
+@section Atmel DFU bootloader using FLIP version 1
+
+Bootloaders using the FLIP protocol version 1 experience some very
+specific behaviour.
+
+These bootloaders have no option to access memory areas other than
+Flash and EEPROM.
+
+When the bootloader is started, it enters a @emph{security mode} where
+the only acceptable access is to query the device configuration
+parameters (which are used for the signature on AVR devices). The
+only way to leave this mode is a @emph{chip erase}. As a chip erase
+is normally implied by the @option{-U} option when reprogramming the
+flash, this peculiarity might not be very obvious immediately.
+
+Sometimes, a bootloader with security mode already disabled seems to
+no longer respond with sensible configuration data, but only 0xFF for
+all queries. As these queries are used to obtain the equivalent of a
+signature, AVRDUDE can only continue in that situation by forcing the
+signature check to be overridden with the @option{-F} option.
+
+A @emph{chip erase} might leave the EEPROM unerased, at least on some
+versions of the bootloader.
+
+@c
+@c Node
+@c
+@node Platform Dependent Information, Troubleshooting, Programmer Specific Information, Top
+@appendix Platform Dependent Information
+
+@menu
+* Unix::
+* Windows::
+@end menu
+
+@c
+@c Node
+@c
+@node Unix, Windows, Platform Dependent Information, Platform Dependent Information
+@section Unix
+
+@menu
+* Unix Installation::
+* Unix Configuration Files::
+* Unix Port Names::
+* Unix Documentation::
+@end menu
+
+@c
+@c Node
+@c
+@node Unix Installation, Unix Configuration Files, Unix, Unix
+@subsection Unix Installation
+
+@noindent
+To build and install from the source tarball on Unix like systems:
+
+@example
+$ gunzip -c avrdude-@value{VERSION}.tar.gz | tar xf -
+$ cd avrdude-@value{VERSION}
+$ ./configure
+$ make
+$ su root -c 'make install'
+@end example
+
+The default location of the install is into @code{/usr/local} so you
+will need to be sure that @code{/usr/local/bin} is in your @code{PATH}
+environment variable.
+
+If you do not have root access to your system, you can do the
+following instead:
+
+@example
+$ gunzip -c avrdude-@value{VERSION}.tar.gz | tar xf -
+$ cd avrdude-@value{VERSION}
+$ ./configure --prefix=$HOME/local
+$ make
+$ make install
+@end example
+
+@menu
+* FreeBSD Installation::
+* Linux Installation::
+@end menu
+
+@c
+@c Node
+@c
+@node FreeBSD Installation, Linux Installation, Unix Installation, Unix Installation
+@subsubsection FreeBSD Installation
+
+@noindent
+AVRDUDE is installed via the FreeBSD Ports Tree as follows:
+
+@example
+% su - root
+# cd /usr/ports/devel/avrdude
+# make install
+@end example
+
+If you wish to install from a pre-built package instead of the source,
+you can use the following instead:
+
+@example
+% su - root
+# pkg_add -r avrdude
+@end example
+
+Of course, you must be connected to the Internet for these methods to
+work, since that is where the source as well as the pre-built package is
+obtained.
+
+@c
+@c Node
+@c
+@node Linux Installation, , FreeBSD Installation, Unix Installation
+@subsubsection Linux Installation
+
+@noindent
+On rpm based Linux systems (such as RedHat, SUSE, Mandrake, etc.), you
+can build and install the rpm binaries directly from the tarball:
+
+@example
+$ su - root
+# rpmbuild -tb avrdude-@value{VERSION}.tar.gz
+# rpm -Uvh /usr/src/redhat/RPMS/i386/avrdude-@value{VERSION}-1.i386.rpm
+@end example
+
+Note that the path to the resulting rpm package, differs from system
+to system. The above example is specific to RedHat.
+
+@c
+@c Node
+@c
+@node Unix Configuration Files, Unix Port Names, Unix Installation, Unix
+@subsection Unix Configuration Files
+
+@noindent
+When AVRDUDE is build using the default @option{--prefix} configure
+option, the default configuration file for a Unix system is located at
+@code{/usr/local/etc/avrdude.conf}. This can be overridden by using the
+@option{-C} command line option. Additionally, the user's home directory
+is searched for a file named @code{.avrduderc}, and if found, is used to
+augment the system default configuration file.
+
+@menu
+* FreeBSD Configuration Files::
+* Linux Configuration Files::
+@end menu
+
+@c
+@c Node
+@c
+@node FreeBSD Configuration Files, Linux Configuration Files, Unix Configuration Files, Unix Configuration Files
+@subsubsection FreeBSD Configuration Files
+
+@noindent
+When AVRDUDE is installed using the FreeBSD ports system, the system
+configuration file is always @code{/usr/local/etc/avrdude.conf}.
+
+@c
+@c Node
+@c
+@node Linux Configuration Files, , FreeBSD Configuration Files, Unix Configuration Files
+@subsubsection Linux Configuration Files
+
+@noindent
+When AVRDUDE is installed using from an rpm package, the system
+configuration file will be always be @code{/etc/avrdude.conf}.
+
+@c
+@c Node
+@c
+@node Unix Port Names, Unix Documentation, Unix Configuration Files, Unix
+@subsection Unix Port Names
+
+@noindent
+The parallel and serial port device file names are system specific.
+The following table lists the default names for a given system.
+
+@multitable @columnfractions .30 .30 .30
+@item @strong{System}
+ @tab @strong{Default Parallel Port}
+ @tab @strong{Default Serial Port}
+@item FreeBSD
+ @tab @code{/dev/ppi0}
+ @tab @code{/dev/cuad0}
+@item Linux
+ @tab @code{/dev/parport0}
+ @tab @code{/dev/ttyS0}
+@item Solaris
+ @tab @code{/dev/printers/0}
+ @tab @code{/dev/term/a}
+@end multitable
+
+On FreeBSD systems, AVRDUDE uses the ppi(4) interface for
+accessing the parallel port and the sio(4) driver for serial port
+access.
+
+On Linux systems, AVRDUDE uses the ppdev interface for
+accessing the parallel port and the tty driver for serial port
+access.
+
+On Solaris systems, AVRDUDE uses the ecpp(7D) driver for
+accessing the parallel port and the asy(7D) driver for serial port
+access.
+
+@c
+@c Node
+@c
+@node Unix Documentation, , Unix Port Names, Unix
+@subsection Unix Documentation
+
+@noindent
+AVRDUDE installs a manual page as well as info, HTML and PDF
+documentation. The manual page is installed in
+@code{/usr/local/man/man1} area, while the HTML and PDF documentation
+is installed in @code{/usr/local/share/doc/avrdude} directory. The
+info manual is installed in @code{/usr/local/info/avrdude.info}.
+
+Note that these locations can be altered by various configure options
+such as @option{--prefix}.
+
+@c
+@c Node
+@c
+@node Windows, , Unix, Platform Dependent Information
+@section Windows
+
+@menu
+* Windows Installation::
+* Windows Configuration Files::
+* Windows Port Names::
+* Using the parallel port::
+* Documentation::
+* Credits.::
+@end menu
+
+@c
+@c Node
+@c
+@node Windows Installation, Windows Configuration Files, Windows, Windows
+@subsection Installation
+
+@noindent
+A Windows executable of avrdude is included in WinAVR which can be found at
+@url{http://sourceforge.net/projects/winavr}. WinAVR is a suite of executable,
+open source software development tools for the AVR for the Windows platform.
+
+There are two options to build avrdude from source under Windows.
+The first one is to use Cygwin (@url{http://www.cygwin.com/}).
+
+To build and install from the source tarball for Windows (using Cygwin):
+
+@example
+$ set PREFIX=<your install directory path>
+$ export PREFIX
+$ gunzip -c avrdude-@value{VERSION}.tar.gz | tar xf -
+$ cd avrdude-@value{VERSION}
+$ ./configure LDFLAGS="-static" --prefix=$PREFIX --datadir=$PREFIX
+--sysconfdir=$PREFIX/bin --enable-versioned-doc=no
+$ make
+$ make install
+@end example
+
+Note that recent versions of Cygwin (starting with 1.7) removed the
+MinGW support from the compiler that is needed in order to build a
+native Win32 API binary that does not require to install the Cygwin
+library @code{cygwin1.dll} at run-time. Either try using an older
+compiler version that still supports MinGW builds, or use MinGW
+(@url{http://www.mingw.org/}) directly.
+
+@c
+@c XXX Please add more detailed instructions here.
+@c
+
+
+@c
+@c Node
+@c
+@node Windows Configuration Files, Windows Port Names, Windows Installation, Windows
+@subsection Configuration Files
+
+@menu
+* Configuration file names::
+* How AVRDUDE finds the configuration files.::
+@end menu
+
+@c
+@c Node
+@c
+@node Configuration file names, How AVRDUDE finds the configuration files., Windows Configuration Files, Windows Configuration Files
+@subsubsection Configuration file names
+
+@noindent
+AVRDUDE on Windows looks for a system configuration file name of
+@code{avrdude.conf} and looks for a user override configuration file of
+@code{avrdude.rc}.
+
+@c
+@c Node
+@c
+@node How AVRDUDE finds the configuration files., , Configuration file names, Windows Configuration Files
+@subsubsection How AVRDUDE finds the configuration files.
+
+@noindent
+AVRDUDE on Windows has a different way of searching for the system and
+user configuration files. Below is the search method for locating the
+configuration files:
+
+@enumerate
+
+@item
+The directory from which the application loaded.
+
+@item
+The current directory.
+
+@item
+The Windows system directory. On Windows NT, the name of this directory
+is @code{SYSTEM32}.
+
+@item
+Windows NT: The 16-bit Windows system directory. The name of this
+directory is @code{SYSTEM}.
+
+@item
+The Windows directory.
+
+@item
+The directories that are listed in the PATH environment variable.
+
+@end enumerate
+
+
+@c
+@c Node
+@c
+@node Windows Port Names, Using the parallel port, Windows Configuration Files, Windows
+@subsection Port Names
+
+@menu
+* Serial Ports::
+* Parallel Ports::
+@end menu
+
+@c
+@c Node
+@c
+@node Serial Ports, Parallel Ports, Windows Port Names, Windows Port Names
+@subsubsection Serial Ports
+
+@noindent
+When you select a serial port (i.e. when using an STK500) use the
+Windows serial port device names such as: com1, com2, etc.
+
+@c
+@c Node
+@c
+@node Parallel Ports, , Serial Ports, Windows Port Names
+@subsubsection Parallel Ports
+
+@noindent
+AVRDUDE will accept 3 Windows parallel port names: lpt1, lpt2, or
+lpt3. Each of these names corresponds to a fixed parallel port base
+address:
+
+@table @code
+@item lpt1
+0x378
+
+@item lpt2
+0x278
+
+@item lpt3
+0x3BC
+
+@end table
+
+On your desktop PC, lpt1 will be the most common choice. If you are
+using a laptop, you might have to use lpt3 instead of lpt1. Select the
+name of the port the corresponds to the base address of the parallel
+port that you want.
+
+If the parallel port can be accessed through a different
+address, this address can be specified directly, using the common C
+language notation (i. e., hexadecimal values are prefixed by @code{0x}).
+
+@c
+@c Node
+@c
+@node Using the parallel port, Documentation, Windows Port Names, Windows
+@subsection Using the parallel port
+
+@menu
+* Windows NT/2K/XP::
+* Windows 95/98::
+@end menu
+
+@c
+@c Node
+@c
+@node Windows NT/2K/XP, Windows 95/98, Using the parallel port, Using the parallel port
+@subsubsection Windows NT/2K/XP
+
+@noindent
+On Windows NT, 2000, and XP user applications cannot directly access the
+parallel port. However, kernel mode drivers can access the parallel port.
+giveio.sys is a driver that can allow user applications to set the state
+of the parallel port pins.
+
+Before using AVRDUDE, the giveio.sys driver must be loaded. The
+accompanying command-line program, loaddrv.exe, can do just that.
+
+To make things even easier there are 3 batch files that are also
+included:
+
+@enumerate
+@item install_giveio.bat
+Install and start the giveio driver.
+
+@item status_giveio.bat
+Check on the status of the giveio driver.
+
+@item remove_giveio.bat
+Stop and remove the giveio driver from memory.
+@end enumerate
+
+These 3 batch files calls the loaddrv program with various options to
+install, start, stop, and remove the driver.
+
+When you first execute install_giveio.bat, loaddrv.exe and giveio.sys
+must be in the current directory. When install_giveio.bat is executed it
+will copy giveio.sys from your current directory to your Windows
+directory. It will then load the driver from the Windows directory. This
+means that after the first time install_giveio is executed, you should
+be able to subsequently execute the batch file from any directory and have
+it successfully start the driver.
+
+Note that you must have administrator privilege to load the giveio driver.
+
+@c
+@c Node
+@c
+@node Windows 95/98, , Windows NT/2K/XP, Using the parallel port
+@subsubsection Windows 95/98
+
+@noindent
+On Windows 95 and 98 the giveio.sys driver is not needed.
+
+
+@c
+@c Node
+@c
+@node Documentation, Credits., Using the parallel port, Windows
+@subsection Documentation
+
+@noindent
+AVRDUDE installs a manual page as well as info, HTML and PDF
+documentation. The manual page is installed in
+@code{/usr/local/man/man1} area, while the HTML and PDF documentation
+is installed in @code{/usr/local/share/doc/avrdude} directory. The
+info manual is installed in @code{/usr/local/info/avrdude.info}.
+
+Note that these locations can be altered by various configure options
+such as @option{--prefix} and @option{--datadir}.
+
+
+@c
+@c Node
+@c
+@node Credits., , Documentation, Windows
+@subsection Credits.
+
+@noindent
+Thanks to:
+
+@itemize @bullet
+@item
+Dale Roberts for the giveio driver.
+
+@item
+Paula Tomlinson for the loaddrv sources.
+
+@item
+Chris Liechti <cliechti@@gmx.net> for modifying loaddrv to be command
+line driven and for writing the batch files.
+
+@end itemize
+
+@c
+@c Node
+@c
+@node Troubleshooting, ,Platform Dependent Information ,Top
+@appendix Troubleshooting
+
+@noindent
+In general, please report any bugs encountered via
+@*
+@url{http://savannah.nongnu.org/bugs/?group=avrdude}.
+
+
+@itemize @bullet
+
+@item
+Problem: I'm using a serial programmer under Windows and get the following
+error:
+
+@code{avrdude: serial_open(): can't set attributes for device "com1"},
+
+Solution: This problem seems to appear with certain versions of Cygwin. Specifying
+@code{"/dev/com1"} instead of @code{"com1"} should help.
+
+
+@item
+Problem: I'm using Linux and my AVR910 programmer is really slow.
+
+Solution (short): @code{setserial @var{port} low_latency}
+
+Solution (long):
+There are two problems here. First, the system may wait some time before it
+passes data from the serial port to the program. Under Linux the following
+command works around this (you may need root privileges for this).
+
+@code{setserial @var{port} low_latency}
+
+Secondly, the serial interface chip may delay the interrupt for some time.
+This behaviour can be changed by setting the FIFO-threshold to one. Under Linux this
+can only be done by changing the kernel source in @code{drivers/char/serial.c}.
+Search the file for @code{UART_FCR_TRIGGER_8} and replace it with @code{UART_FCR_TRIGGER_1}. Note that overall performance might suffer if there
+is high throughput on serial lines. Also note that you are modifying the kernel at
+your own risk.
+
+
+@item
+Problem: I'm not using Linux and my AVR910 programmer is really slow.
+
+Solutions: The reasons for this are the same as above.
+If you know how to work around this on your OS, please let us know.
+
+@item
+Problem: Updating the flash ROM from terminal mode does not work with the
+JTAG ICEs.
+
+Solution: None at this time. Currently, the JTAG ICE code cannot
+write to the flash ROM one byte at a time.
+
+@item
+Problem: Page-mode programming the EEPROM (using the -U option) does
+not erase EEPROM cells before writing, and thus cannot overwrite any
+previous value != 0xff.
+
+Solution: None. This is an inherent feature of the way JTAG EEPROM
+programming works, and is documented that way in the Atmel AVR
+datasheets.
+In order to successfully program the EEPROM that way, a prior chip
+erase (with the EESAVE fuse unprogrammed) is required.
+This also applies to the STK500 and STK600 in high-voltage programming mode.
+
+@item
+Problem: How do I turn off the @var{DWEN} fuse?
+
+Solution: If the @var{DWEN} (debugWire enable) fuse is activated,
+the @var{/RESET} pin is not functional anymore, so normal ISP
+communication cannot be established.
+There are two options to deactivate that fuse again: high-voltage
+programming, or getting the JTAG ICE mkII talk debugWire, and
+prepare the target AVR to accept normal ISP communication again.
+
+The first option requires a programmer that is capable of high-voltage
+programming (either serial or parallel, depending on the AVR device),
+for example the STK500. In high-voltage programming mode, the
+@var{/RESET} pin is activated initially using a 12 V pulse (thus the
+name @emph{high voltage}), so the target AVR can subsequently be
+reprogrammed, and the @var{DWEN} fuse can be cleared. Typically, this
+operation cannot be performed while the AVR is located in the target
+circuit though.
+
+The second option requires a JTAG ICE mkII that can talk the debugWire
+protocol. The ICE needs to be connected to the target using the
+JTAG-to-ISP adapter, so the JTAG ICE mkII can be used as a debugWire
+initiator as well as an ISP programmer. AVRDUDE will then be activated
+using the @var{jtag2isp} programmer type. The initial ISP
+communication attempt will fail, but AVRDUDE then tries to initiate a
+debugWire reset. When successful, this will leave the target AVR in a
+state where it can accept standard ISP communication. The ICE is then
+signed off (which will make it signing off from the USB as well), so
+AVRDUDE has to be called again afterwards. This time, standard ISP
+communication can work, so the @var{DWEN} fuse can be cleared.
+
+The pin mapping for the JTAG-to-ISP adapter is:
+
+@multitable @columnfractions .2 .2
+@item @strong{JTAG pin} @tab @strong{ISP pin}
+@item 1 @tab 3
+@item 2 @tab 6
+@item 3 @tab 1
+@item 4 @tab 2
+@item 6 @tab 5
+@item 9 @tab 4
+@end multitable
+
+@item
+Problem: Multiple USBasp or USBtinyISP programmers connected simultaneously are not
+found.
+
+Solution: The USBtinyISP code supports distinguishing multiple
+programmers based on their bus:device connection tuple that describes
+their place in the USB hierarchy on a specific host. This tuple can
+be added to the @var{-P usb} option, similar to adding a serial number
+on other USB-based programmers.
+
+The actual naming convention for the bus and device names is
+operating-system dependent; AVRDUDE will print out what it found
+on the bus when running it with (at least) one @var{-v} option.
+By specifying a string that cannot match any existing device
+(for example, @var{-P usb:xxx}), the scan will list all possible
+candidate devices found on the bus.
+
+Examples:
+@example
+avrdude -c usbtiny -p atmega8 -P usb:003:025 (Linux)
+avrdude -c usbtiny -p atmega8 -P usb:/dev/usb:/dev/ugen1.3 (FreeBSD 8+)
+avrdude -c usbtiny -p atmega8 \
+ -P usb:bus-0:\\.\libusb0-0001--0x1781-0x0c9f (Windows)
+@end example
+
+@item
+Problem: I cannot do @dots{} when the target is in debugWire mode.
+
+Solution: debugWire mode imposes several limitations.
+
+The debugWire protocol is Atmel's proprietary one-wire (plus ground)
+protocol to allow an in-circuit emulation of the smaller AVR devices,
+using the @var{/RESET} line.
+DebugWire mode is initiated by activating the @var{DWEN}
+fuse, and then power-cycling the target.
+While this mode is mainly intended for debugging/emulation, it
+also offers limited programming capabilities.
+Effectively, the only memory areas that can be read or programmed
+in this mode are flash ROM and EEPROM.
+It is also possible to read out the signature.
+All other memory areas cannot be accessed.
+There is no
+@emph{chip erase}
+functionality in debugWire mode; instead, while reprogramming the
+flash ROM, each flash ROM page is erased right before updating it.
+This is done transparently by the JTAG ICE mkII (or AVR Dragon).
+The only way back from debugWire mode is to initiate a special
+sequence of commands to the JTAG ICE mkII (or AVR Dragon), so the
+debugWire mode will be temporarily disabled, and the target can
+be accessed using normal ISP programming.
+This sequence is automatically initiated by using the JTAG ICE mkII
+or AVR Dragon in ISP mode, when they detect that ISP mode cannot be
+entered.
+
+@item
+Problem: I want to use my JTAG ICE mkII to program an
+Xmega device through PDI. The documentation tells me to use the
+@emph{XMEGA PDI adapter for JTAGICE mkII} that is supposed to ship
+with the kit, yet I don't have it.
+
+Solution: Use the following pin mapping:
+
+@multitable @columnfractions .2 .2 .2 .2
+@item @strong{JTAGICE} @tab @strong{Target} @tab @strong{Squid cab-} @tab @strong{PDI}
+@item @strong{mkII probe} @tab @strong{pins} @tab @strong{le colors} @tab @strong{header}
+@item 1 (TCK) @tab @tab Black @tab
+@item 2 (GND) @tab GND @tab White @tab 6
+@item 3 (TDO) @tab @tab Grey @tab
+@item 4 (VTref) @tab VTref @tab Purple @tab 2
+@item 5 (TMS) @tab @tab Blue @tab
+@item 6 (nSRST) @tab PDI_CLK @tab Green @tab 5
+@item 7 (N.C.) @tab @tab Yellow @tab
+@item 8 (nTRST) @tab @tab Orange @tab
+@item 9 (TDI) @tab PDI_DATA @tab Red @tab 1
+@item 10 (GND) @tab @tab Brown @tab
+@end multitable
+
+@item
+Problem: I want to use my AVR Dragon to program an
+Xmega device through PDI.
+
+Solution: Use the 6 pin ISP header on the Dragon and the following pin mapping:
+
+@multitable @columnfractions .2 .2
+@item @strong{Dragon} @tab @strong{Target}
+@item @strong{ISP Header} @tab @strong{pins}
+@item 1 (MISO) @tab PDI_DATA
+@item 2 (VCC) @tab VCC
+@item 3 (SCK) @tab
+@item 4 (MOSI) @tab
+@item 5 (RESET) @tab PDI_CLK / RST
+@item 6 (GND) @tab GND
+@end multitable
+
+@item
+Problem: I want to use my AVRISP mkII to program an
+ATtiny4/5/9/10 device through TPI. How to connect the pins?
+
+Solution: Use the following pin mapping:
+
+@multitable @columnfractions .2 .2 .2
+@item @strong{AVRISP} @tab @strong{Target} @tab @strong{ATtiny}
+@item @strong{connector} @tab @strong{pins} @tab @strong{pin #}
+@item 1 (MISO) @tab TPIDATA @tab 1
+@item 2 (VTref) @tab Vcc @tab 5
+@item 3 (SCK) @tab TPICLK @tab 3
+@item 4 (MOSI) @tab @tab
+@item 5 (RESET) @tab /RESET @tab 6
+@item 6 (GND) @tab GND @tab 2
+@end multitable
+
+@item
+Problem: I want to program an ATtiny4/5/9/10 device using a serial/parallel
+bitbang programmer. How to connect the pins?
+
+Solution: Since TPI has only 1 pin for bi-directional data transfer, both
+@var{MISO} and @var{MOSI} pins should be connected to the @var{TPIDATA} pin
+on the ATtiny device.
+However, a 1K resistor should be placed between the @var{MOSI} and @var{TPIDATA}.
+The @var{MISO} pin connects to @var{TPIDATA} directly.
+The @var{SCK} pin is connected to @var{TPICLK}.
+
+In addition, the @var{Vcc}, @var{/RESET} and @var{GND} pins should
+be connected to their respective ports on the ATtiny device.
+
+@item
+Problem: How can I use a FTDI FT232R USB-to-Serial device for bitbang programming?
+
+Solution: When connecting the FT232 directly to the pins of the target Atmel device,
+the polarity of the pins defined in the @code{programmer} definition should be
+inverted by prefixing a tilde. For example, the @var{dasa} programmer would
+look like this when connected via a FT232R device (notice the tildes in
+front of pins 7, 4, 3 and 8):
+
+@example
+programmer
+ id = "dasa_ftdi";
+ desc = "serial port banging, reset=rts sck=dtr mosi=txd miso=cts";
+ type = serbb;
+ reset = ~7;
+ sck = ~4;
+ mosi = ~3;
+ miso = ~8;
+;
+@end example
+
+Note that this uses the FT232 device as a normal serial port, not using the
+FTDI drivers in the special bitbang mode.
+
+@item
+Problem: My ATtiny4/5/9/10 reads out fine, but any attempt to program
+it (through TPI) fails. Instead, the memory retains the old contents.
+
+Solution: Mind the limited programming supply voltage range of these
+devices.
+
+In-circuit programming through TPI is only guaranteed by the datasheet
+at Vcc = 5 V.
+
+@item
+Problem: My ATxmega@dots{}A1/A2/A3 cannot be programmed through PDI with
+my AVR Dragon. Programming through a JTAG ICE mkII works though, as does
+programming through JTAG.
+
+Solution: None by this time (2010 Q1).
+
+It is said that the AVR Dragon can only program devices from the A4
+Xmega sub-family.
+
+@item
+Problem: when programming with an AVRISPmkII or STK600, AVRDUDE hangs
+when programming files of a certain size (e.g. 246 bytes). Other
+(larger or smaller) sizes work though.
+
+Solution: This is a bug caused by an incorrect handling of zero-length
+packets (ZLPs) in some versions of the libusb 0.1 API wrapper that ships
+with libusb 1.x in certain Linux distributions. All Linux systems with
+kernel versions < 2.6.31 and libusb >= 1.0.0 < 1.0.3 are reported to be
+affected by this.
+
+See also: @url{http://www.libusb.org/ticket/6}
+
+@item
+Problem: after flashing a firmware that reduces the target's clock
+speed (e.g. through the @code{CLKPR} register), further ISP connection
+attempts fail.
+
+Solution: Even though ISP starts with pulling @var{/RESET} low, the
+target continues to run at the internal clock speed as defined by the
+firmware running before. Therefore, the ISP clock speed must be
+reduced appropriately (to less than 1/4 of the internal clock speed)
+using the -B option before the ISP initialization sequence will
+succeed.
+
+As that slows down the entire subsequent ISP session, it might make
+sense to just issue a @emph{chip erase} using the slow ISP clock
+(option @code{-e}), and then start a new session at higher speed.
+Option @code{-D} might be used there, to prevent another unneeded
+erase cycle.
+
+@end itemize
+
+
+
+@bye
+
diff --git a/xs/src/avrdude/doc/parts_comments.txt b/xs/src/avrdude/doc/parts_comments.txt
new file mode 100644
index 000000000..d83bb4312
--- /dev/null
+++ b/xs/src/avrdude/doc/parts_comments.txt
@@ -0,0 +1,5 @@
+AT90S1200 (****)
+AT90S2343 (*)
+ATmega2560 (**)
+ATmega2561 (**)
+ATtiny11 (***)
diff --git a/xs/src/avrdude/fileio.c b/xs/src/avrdude/fileio.c
new file mode 100644
index 000000000..708159295
--- /dev/null
+++ b/xs/src/avrdude/fileio.c
@@ -0,0 +1,1663 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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$ */
+
+#include "ac_cfg.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+
+#ifdef HAVE_LIBELF
+#ifdef HAVE_LIBELF_H
+#include <libelf.h>
+#elif defined(HAVE_LIBELF_LIBELF_H)
+#include <libelf/libelf.h>
+#endif
+#define EM_AVR32 0x18ad /* inofficial */
+#endif
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+
+#define IHEX_MAXDATA 256
+
+#define MAX_LINE_LEN 256 /* max line length for ASCII format input files */
+
+#define MAX_MODE_LEN 32 // For fopen_and_seek()
+
+
+struct ihexrec {
+ unsigned char reclen;
+ unsigned int loadofs;
+ unsigned char rectyp;
+ unsigned char data[IHEX_MAXDATA];
+ unsigned char cksum;
+};
+
+
+static int b2ihex(unsigned char * inbuf, int bufsize,
+ int recsize, int startaddr,
+ char * outfile, FILE * outf);
+
+static int ihex2b(char * infile, FILE * inf,
+ AVRMEM * mem, int bufsize, unsigned int fileoffset);
+
+static int b2srec(unsigned char * inbuf, int bufsize,
+ int recsize, int startaddr,
+ char * outfile, FILE * outf);
+
+static int srec2b(char * infile, FILE * inf,
+ AVRMEM * mem, int bufsize, unsigned int fileoffset);
+
+static int ihex_readrec(struct ihexrec * ihex, char * rec);
+
+static int srec_readrec(struct ihexrec * srec, char * rec);
+
+static int fileio_rbin(struct fioparms * fio,
+ char * filename, FILE * f, AVRMEM * mem, int size);
+
+static int fileio_ihex(struct fioparms * fio,
+ char * filename, FILE * f, AVRMEM * mem, int size);
+
+static int fileio_srec(struct fioparms * fio,
+ char * filename, FILE * f, AVRMEM * mem, int size);
+
+#ifdef HAVE_LIBELF
+static int elf2b(char * infile, FILE * inf,
+ AVRMEM * mem, struct avrpart * p,
+ int bufsize, unsigned int fileoffset);
+
+static int fileio_elf(struct fioparms * fio,
+ char * filename, FILE * f, AVRMEM * mem,
+ struct avrpart * p, int size);
+#endif
+
+static int fileio_num(struct fioparms * fio,
+ char * filename, FILE * f, AVRMEM * mem, int size,
+ FILEFMT fmt);
+
+static int fmt_autodetect(char * fname, unsigned section);
+
+
+
+static FILE *fopen_and_seek(const char *filename, const char *mode, unsigned section)
+{
+ FILE *file;
+ // On Windows we need to convert the filename to UTF-16
+#if defined(WIN32NATIVE)
+ static wchar_t fname_buffer[PATH_MAX];
+ static wchar_t mode_buffer[MAX_MODE_LEN];
+
+ if (MultiByteToWideChar(CP_UTF8, 0, filename, -1, fname_buffer, PATH_MAX) == 0) { return NULL; }
+ if (MultiByteToWideChar(CP_ACP, 0, mode, -1, mode_buffer, MAX_MODE_LEN) == 0) { return NULL; }
+
+ file = _wfopen(fname_buffer, mode_buffer);
+#else
+ file = fopen(filename, mode);
+#endif
+
+ if (file == NULL) {
+ return NULL;
+ }
+
+ // Seek to the specified 'section'
+ static const char *hex_terminator = ":00000001FF\r";
+ unsigned terms_seen = 0;
+ char buffer[MAX_LINE_LEN + 1];
+
+ while (terms_seen < section && fgets(buffer, MAX_LINE_LEN, file) != NULL) {
+ size_t len = strlen(buffer);
+
+ if (buffer[len - 1] == '\n') {
+ len--;
+ buffer[len] = 0;
+ }
+ if (buffer[len - 1] != '\r') {
+ buffer[len] = '\r';
+ len++;
+ buffer[len] = 0;
+ }
+
+ if (strcmp(buffer, hex_terminator) == 0) {
+ // Found a section terminator
+ terms_seen++;
+ }
+ }
+
+ if (feof(file)) {
+ // Section not found
+ fclose(file);
+ return NULL;
+ }
+
+ return file;
+}
+
+
+char * fmtstr(FILEFMT format)
+{
+ switch (format) {
+ case FMT_AUTO : return "auto-detect"; break;
+ case FMT_SREC : return "Motorola S-Record"; break;
+ case FMT_IHEX : return "Intel Hex"; break;
+ case FMT_RBIN : return "raw binary"; break;
+ case FMT_ELF : return "ELF"; break;
+ default : return "invalid format"; break;
+ };
+}
+
+
+
+static int b2ihex(unsigned char * inbuf, int bufsize,
+ int recsize, int startaddr,
+ char * outfile, FILE * outf)
+{
+ unsigned char * buf;
+ unsigned int nextaddr;
+ int n, nbytes, n_64k;
+ int i;
+ unsigned char cksum;
+
+ if (recsize > 255) {
+ avrdude_message(MSG_INFO, "%s: recsize=%d, must be < 256\n",
+ progname, recsize);
+ return -1;
+ }
+
+ n_64k = 0;
+ nextaddr = startaddr;
+ buf = inbuf;
+ nbytes = 0;
+
+ while (bufsize) {
+ n = recsize;
+ if (n > bufsize)
+ n = bufsize;
+
+ if ((nextaddr + n) > 0x10000)
+ n = 0x10000 - nextaddr;
+
+ if (n) {
+ cksum = 0;
+ fprintf(outf, ":%02X%04X00", n, nextaddr);
+ cksum += n + ((nextaddr >> 8) & 0x0ff) + (nextaddr & 0x0ff);
+ for (i=0; i<n; i++) {
+ fprintf(outf, "%02X", buf[i]);
+ cksum += buf[i];
+ }
+ cksum = -cksum;
+ fprintf(outf, "%02X\n", cksum);
+
+ nextaddr += n;
+ nbytes += n;
+ }
+
+ if (nextaddr >= 0x10000) {
+ int lo, hi;
+ /* output an extended address record */
+ n_64k++;
+ lo = n_64k & 0xff;
+ hi = (n_64k >> 8) & 0xff;
+ cksum = 0;
+ fprintf(outf, ":02000004%02X%02X", hi, lo);
+ cksum += 2 + 0 + 4 + hi + lo;
+ cksum = -cksum;
+ fprintf(outf, "%02X\n", cksum);
+ nextaddr = 0;
+ }
+
+ /* advance to next 'recsize' bytes */
+ buf += n;
+ bufsize -= n;
+ }
+
+ /*-----------------------------------------------------------------
+ add the end of record data line
+ -----------------------------------------------------------------*/
+ cksum = 0;
+ n = 0;
+ nextaddr = 0;
+ fprintf(outf, ":%02X%04X01", n, nextaddr);
+ cksum += n + ((nextaddr >> 8) & 0x0ff) + (nextaddr & 0x0ff) + 1;
+ cksum = -cksum;
+ fprintf(outf, "%02X\n", cksum);
+
+ return nbytes;
+}
+
+
+static int ihex_readrec(struct ihexrec * ihex, char * rec)
+{
+ int i, j;
+ char buf[8];
+ int offset, len;
+ char * e;
+ unsigned char cksum;
+ int rc;
+
+ len = strlen(rec);
+ offset = 1;
+ cksum = 0;
+
+ /* reclen */
+ if (offset + 2 > len)
+ return -1;
+ for (i=0; i<2; i++)
+ buf[i] = rec[offset++];
+ buf[i] = 0;
+ ihex->reclen = strtoul(buf, &e, 16);
+ if (e == buf || *e != 0)
+ return -1;
+
+ /* load offset */
+ if (offset + 4 > len)
+ return -1;
+ for (i=0; i<4; i++)
+ buf[i] = rec[offset++];
+ buf[i] = 0;
+ ihex->loadofs = strtoul(buf, &e, 16);
+ if (e == buf || *e != 0)
+ return -1;
+
+ /* record type */
+ if (offset + 2 > len)
+ return -1;
+ for (i=0; i<2; i++)
+ buf[i] = rec[offset++];
+ buf[i] = 0;
+ ihex->rectyp = strtoul(buf, &e, 16);
+ if (e == buf || *e != 0)
+ return -1;
+
+ cksum = ihex->reclen + ((ihex->loadofs >> 8) & 0x0ff) +
+ (ihex->loadofs & 0x0ff) + ihex->rectyp;
+
+ /* data */
+ for (j=0; j<ihex->reclen; j++) {
+ if (offset + 2 > len)
+ return -1;
+ for (i=0; i<2; i++)
+ buf[i] = rec[offset++];
+ buf[i] = 0;
+ ihex->data[j] = strtoul(buf, &e, 16);
+ if (e == buf || *e != 0)
+ return -1;
+ cksum += ihex->data[j];
+ }
+
+ /* cksum */
+ if (offset + 2 > len)
+ return -1;
+ for (i=0; i<2; i++)
+ buf[i] = rec[offset++];
+ buf[i] = 0;
+ ihex->cksum = strtoul(buf, &e, 16);
+ if (e == buf || *e != 0)
+ return -1;
+
+ rc = -cksum & 0x000000ff;
+
+ return rc;
+}
+
+
+
+/*
+ * Intel Hex to binary buffer
+ *
+ * Given an open file 'inf' which contains Intel Hex formated data,
+ * parse the file and lay it out within the memory buffer pointed to
+ * by outbuf. The size of outbuf, 'bufsize' is honored; if data would
+ * fall outsize of the memory buffer outbuf, an error is generated.
+ *
+ * Return the maximum memory address within 'outbuf' that was written.
+ * If an error occurs, return -1.
+ *
+ * */
+static int ihex2b(char * infile, FILE * inf,
+ AVRMEM * mem, int bufsize, unsigned int fileoffset)
+{
+ char buffer [ MAX_LINE_LEN ];
+ unsigned int nextaddr, baseaddr, maxaddr;
+ int i;
+ int lineno;
+ int len;
+ struct ihexrec ihex;
+ int rc;
+
+ lineno = 0;
+ baseaddr = 0;
+ maxaddr = 0;
+ nextaddr = 0;
+
+ while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
+ lineno++;
+ len = strlen(buffer);
+ if (buffer[len-1] == '\n')
+ buffer[--len] = 0;
+ if (buffer[0] != ':')
+ continue;
+ rc = ihex_readrec(&ihex, buffer);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: invalid record at line %d of \"%s\"\n",
+ progname, lineno, infile);
+ return -1;
+ }
+ else if (rc != ihex.cksum) {
+ avrdude_message(MSG_INFO, "%s: ERROR: checksum mismatch at line %d of \"%s\"\n",
+ progname, lineno, infile);
+ avrdude_message(MSG_INFO, "%s: checksum=0x%02x, computed checksum=0x%02x\n",
+ progname, ihex.cksum, rc);
+ return -1;
+ }
+
+ switch (ihex.rectyp) {
+ case 0: /* data record */
+ if (fileoffset != 0 && baseaddr < fileoffset) {
+ avrdude_message(MSG_INFO, "%s: ERROR: address 0x%04x out of range (below fileoffset 0x%x) at line %d of %s\n",
+ progname, baseaddr, fileoffset, lineno, infile);
+ return -1;
+ }
+ nextaddr = ihex.loadofs + baseaddr - fileoffset;
+ if (nextaddr + ihex.reclen > bufsize) {
+ avrdude_message(MSG_INFO, "%s: ERROR: address 0x%04x out of range at line %d of %s\n",
+ progname, nextaddr+ihex.reclen, lineno, infile);
+ return -1;
+ }
+ for (i=0; i<ihex.reclen; i++) {
+ mem->buf[nextaddr+i] = ihex.data[i];
+ mem->tags[nextaddr+i] = TAG_ALLOCATED;
+ }
+ if (nextaddr+ihex.reclen > maxaddr)
+ maxaddr = nextaddr+ihex.reclen;
+ break;
+
+ case 1: /* end of file record */
+ return maxaddr;
+ break;
+
+ case 2: /* extended segment address record */
+ baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 4;
+ break;
+
+ case 3: /* start segment address record */
+ /* we don't do anything with the start address */
+ break;
+
+ case 4: /* extended linear address record */
+ baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 16;
+ break;
+
+ case 5: /* start linear address record */
+ /* we don't do anything with the start address */
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "%s: don't know how to deal with rectype=%d "
+ "at line %d of %s\n",
+ progname, ihex.rectyp, lineno, infile);
+ return -1;
+ break;
+ }
+
+ } /* while */
+
+ if (maxaddr == 0) {
+ avrdude_message(MSG_INFO, "%s: ERROR: No valid record found in Intel Hex "
+ "file \"%s\"\n",
+ progname, infile);
+
+ return -1;
+ }
+ else {
+ avrdude_message(MSG_INFO, "%s: WARNING: no end of file record found for Intel Hex "
+ "file \"%s\"\n",
+ progname, infile);
+
+ return maxaddr;
+ }
+}
+
+static int b2srec(unsigned char * inbuf, int bufsize,
+ int recsize, int startaddr,
+ char * outfile, FILE * outf)
+{
+ unsigned char * buf;
+ unsigned int nextaddr;
+ int n, nbytes, addr_width;
+ int i;
+ unsigned char cksum;
+
+ char * tmpl=0;
+
+ if (recsize > 255) {
+ avrdude_message(MSG_INFO, "%s: ERROR: recsize=%d, must be < 256\n",
+ progname, recsize);
+ return -1;
+ }
+
+ nextaddr = startaddr;
+ buf = inbuf;
+ nbytes = 0;
+
+ addr_width = 0;
+
+ while (bufsize) {
+
+ n = recsize;
+
+ if (n > bufsize)
+ n = bufsize;
+
+ if (n) {
+ cksum = 0;
+ if (nextaddr + n <= 0xffff) {
+ addr_width = 2;
+ tmpl="S1%02X%04X";
+ }
+ else if (nextaddr + n <= 0xffffff) {
+ addr_width = 3;
+ tmpl="S2%02X%06X";
+ }
+ else if (nextaddr + n <= 0xffffffff) {
+ addr_width = 4;
+ tmpl="S3%02X%08X";
+ }
+ else {
+ avrdude_message(MSG_INFO, "%s: ERROR: address=%d, out of range\n",
+ progname, nextaddr);
+ return -1;
+ }
+
+ fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
+
+ cksum += n + addr_width + 1;
+
+ for (i=addr_width; i>0; i--)
+ cksum += (nextaddr >> (i-1) * 8) & 0xff;
+
+ for (i=nextaddr; i<nextaddr + n; i++) {
+ fprintf(outf, "%02X", buf[i]);
+ cksum += buf[i];
+ }
+
+ cksum = 0xff - cksum;
+ fprintf(outf, "%02X\n", cksum);
+
+ nextaddr += n;
+ nbytes +=n;
+ }
+
+ /* advance to next 'recsize' bytes */
+ bufsize -= n;
+ }
+
+ /*-----------------------------------------------------------------
+ add the end of record data line
+ -----------------------------------------------------------------*/
+ cksum = 0;
+ n = 0;
+ nextaddr = 0;
+
+ if (startaddr <= 0xffff) {
+ addr_width = 2;
+ tmpl="S9%02X%04X";
+ }
+ else if (startaddr <= 0xffffff) {
+ addr_width = 3;
+ tmpl="S9%02X%06X";
+ }
+ else if (startaddr <= 0xffffffff) {
+ addr_width = 4;
+ tmpl="S9%02X%08X";
+ }
+
+ fprintf(outf, tmpl, n + addr_width + 1, nextaddr);
+
+ cksum += n + addr_width +1;
+ for (i=addr_width; i>0; i--)
+ cksum += (nextaddr >> (i - 1) * 8) & 0xff;
+ cksum = 0xff - cksum;
+ fprintf(outf, "%02X\n", cksum);
+
+ return nbytes;
+}
+
+
+static int srec_readrec(struct ihexrec * srec, char * rec)
+{
+ int i, j;
+ char buf[8];
+ int offset, len, addr_width;
+ char * e;
+ unsigned char cksum;
+ int rc;
+
+ len = strlen(rec);
+ offset = 1;
+ cksum = 0;
+ addr_width = 2;
+
+ /* record type */
+ if (offset + 1 > len)
+ return -1;
+ srec->rectyp = rec[offset++];
+ if (srec->rectyp == 0x32 || srec->rectyp == 0x38)
+ addr_width = 3; /* S2,S8-record */
+ else if (srec->rectyp == 0x33 || srec->rectyp == 0x37)
+ addr_width = 4; /* S3,S7-record */
+
+ /* reclen */
+ if (offset + 2 > len)
+ return -1;
+ for (i=0; i<2; i++)
+ buf[i] = rec[offset++];
+ buf[i] = 0;
+ srec->reclen = strtoul(buf, &e, 16);
+ cksum += srec->reclen;
+ srec->reclen -= (addr_width+1);
+ if (e == buf || *e != 0)
+ return -1;
+
+ /* load offset */
+ if (offset + addr_width > len)
+ return -1;
+ for (i=0; i<addr_width*2; i++)
+ buf[i] = rec[offset++];
+ buf[i] = 0;
+ srec->loadofs = strtoull(buf, &e, 16);
+ if (e == buf || *e != 0)
+ return -1;
+
+ for (i=addr_width; i>0; i--)
+ cksum += (srec->loadofs >> (i - 1) * 8) & 0xff;
+
+ /* data */
+ for (j=0; j<srec->reclen; j++) {
+ if (offset+2 > len)
+ return -1;
+ for (i=0; i<2; i++)
+ buf[i] = rec[offset++];
+ buf[i] = 0;
+ srec->data[j] = strtoul(buf, &e, 16);
+ if (e == buf || *e != 0)
+ return -1;
+ cksum += srec->data[j];
+ }
+
+ /* cksum */
+ if (offset + 2 > len)
+ return -1;
+ for (i=0; i<2; i++)
+ buf[i] = rec[offset++];
+ buf[i] = 0;
+ srec->cksum = strtoul(buf, &e, 16);
+ if (e == buf || *e != 0)
+ return -1;
+
+ rc = 0xff - cksum;
+ return rc;
+}
+
+
+static int srec2b(char * infile, FILE * inf,
+ AVRMEM * mem, int bufsize, unsigned int fileoffset)
+{
+ char buffer [ MAX_LINE_LEN ];
+ unsigned int nextaddr, maxaddr;
+ int i;
+ int lineno;
+ int len;
+ struct ihexrec srec;
+ int rc;
+ int reccount;
+ unsigned char datarec;
+
+ char * msg = 0;
+
+ lineno = 0;
+ maxaddr = 0;
+ reccount = 0;
+
+ while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
+ lineno++;
+ len = strlen(buffer);
+ if (buffer[len-1] == '\n')
+ buffer[--len] = 0;
+ if (buffer[0] != 0x53)
+ continue;
+ rc = srec_readrec(&srec, buffer);
+
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: ERROR: invalid record at line %d of \"%s\"\n",
+ progname, lineno, infile);
+ return -1;
+ }
+ else if (rc != srec.cksum) {
+ avrdude_message(MSG_INFO, "%s: ERROR: checksum mismatch at line %d of \"%s\"\n",
+ progname, lineno, infile);
+ avrdude_message(MSG_INFO, "%s: checksum=0x%02x, computed checksum=0x%02x\n",
+ progname, srec.cksum, rc);
+ return -1;
+ }
+
+ datarec=0;
+ switch (srec.rectyp) {
+ case 0x30: /* S0 - header record*/
+ /* skip */
+ break;
+
+ case 0x31: /* S1 - 16 bit address data record */
+ datarec=1;
+ msg="%s: ERROR: address 0x%04x out of range %sat line %d of %s\n";
+ break;
+
+ case 0x32: /* S2 - 24 bit address data record */
+ datarec=1;
+ msg="%s: ERROR: address 0x%06x out of range %sat line %d of %s\n";
+ break;
+
+ case 0x33: /* S3 - 32 bit address data record */
+ datarec=1;
+ msg="%s: ERROR: address 0x%08x out of range %sat line %d of %s\n";
+ break;
+
+ case 0x34: /* S4 - symbol record (LSI extension) */
+ avrdude_message(MSG_INFO, "%s: ERROR: not supported record at line %d of %s\n",
+ progname, lineno, infile);
+ return -1;
+
+ case 0x35: /* S5 - count of S1,S2 and S3 records previously tx'd */
+ if (srec.loadofs != reccount){
+ avrdude_message(MSG_INFO, "%s: ERROR: count of transmitted data records mismatch "
+ "at line %d of \"%s\"\n",
+ progname, lineno, infile);
+ avrdude_message(MSG_INFO, "%s: transmitted data records= %d, expected "
+ "value= %d\n",
+ progname, reccount, srec.loadofs);
+ return -1;
+ }
+ break;
+
+ case 0x37: /* S7 Record - end record for 32 bit address data */
+ case 0x38: /* S8 Record - end record for 24 bit address data */
+ case 0x39: /* S9 Record - end record for 16 bit address data */
+ return maxaddr;
+
+ default:
+ avrdude_message(MSG_INFO, "%s: ERROR: don't know how to deal with rectype S%d "
+ "at line %d of %s\n",
+ progname, srec.rectyp, lineno, infile);
+ return -1;
+ }
+
+ if (datarec == 1) {
+ nextaddr = srec.loadofs;
+ if (nextaddr < fileoffset) {
+ avrdude_message(MSG_INFO, msg, progname, nextaddr,
+ "(below fileoffset) ",
+ lineno, infile);
+ return -1;
+ }
+ nextaddr -= fileoffset;
+ if (nextaddr + srec.reclen > bufsize) {
+ avrdude_message(MSG_INFO, msg, progname, nextaddr+srec.reclen, "",
+ lineno, infile);
+ return -1;
+ }
+ for (i=0; i<srec.reclen; i++) {
+ mem->buf[nextaddr+i] = srec.data[i];
+ mem->tags[nextaddr+i] = TAG_ALLOCATED;
+ }
+ if (nextaddr+srec.reclen > maxaddr)
+ maxaddr = nextaddr+srec.reclen;
+ reccount++;
+ }
+
+ }
+
+ avrdude_message(MSG_INFO, "%s: WARNING: no end of file record found for Motorola S-Records "
+ "file \"%s\"\n",
+ progname, infile);
+
+ return maxaddr;
+}
+
+#ifdef HAVE_LIBELF
+/*
+ * Determine whether the ELF file section pointed to by `sh' fits
+ * completely into the program header segment pointed to by `ph'.
+ *
+ * Assumes the section has been checked already before to actually
+ * contain data (SHF_ALLOC, SHT_PROGBITS, sh_size > 0).
+ *
+ * Sometimes, program header segments might be larger than the actual
+ * file sections. On VM architectures, this is used to allow mmapping
+ * the entire ELF file "as is" (including things like the program
+ * header table itself).
+ */
+static inline
+int is_section_in_segment(Elf32_Shdr *sh, Elf32_Phdr *ph)
+{
+ if (sh->sh_offset < ph->p_offset)
+ return 0;
+ if (sh->sh_offset + sh->sh_size > ph->p_offset + ph->p_filesz)
+ return 0;
+ return 1;
+}
+
+/*
+ * Return the ELF section descriptor that corresponds to program
+ * header `ph'. The program header is expected to be of p_type
+ * PT_LOAD, and to have a nonzero p_filesz. (PT_LOAD sections with a
+ * zero p_filesz are typically RAM sections that are not initialized
+ * by file data, e.g. ".bss".)
+ */
+static Elf_Scn *elf_get_scn(Elf *e, Elf32_Phdr *ph, Elf32_Shdr **shptr)
+{
+ Elf_Scn *s = NULL;
+
+ while ((s = elf_nextscn(e, s)) != NULL) {
+ Elf32_Shdr *sh;
+ size_t ndx = elf_ndxscn(s);
+ if ((sh = elf32_getshdr(s)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: ERROR: Error reading section #%u header: %s\n",
+ progname, (unsigned int)ndx, elf_errmsg(-1));
+ continue;
+ }
+ if ((sh->sh_flags & SHF_ALLOC) == 0 ||
+ sh->sh_type != SHT_PROGBITS)
+ /* we are only interested in PROGBITS, ALLOC sections */
+ continue;
+ if (sh->sh_size == 0)
+ /* we are not interested in empty sections */
+ continue;
+ if (is_section_in_segment(sh, ph)) {
+ /* yeah, we found it */
+ *shptr = sh;
+ return s;
+ }
+ }
+
+ avrdude_message(MSG_INFO, "%s: ERROR: Cannot find a matching section for "
+ "program header entry @p_vaddr 0x%x\n",
+ progname, ph->p_vaddr);
+ return NULL;
+}
+
+static int elf_mem_limits(AVRMEM *mem, struct avrpart * p,
+ unsigned int *lowbound,
+ unsigned int *highbound,
+ unsigned int *fileoff)
+{
+ int rv = 0;
+
+ if (p->flags & AVRPART_AVR32) {
+ if (strcmp(mem->desc, "flash") == 0) {
+ *lowbound = 0x80000000;
+ *highbound = 0xffffffff;
+ *fileoff = 0;
+ } else {
+ rv = -1;
+ }
+ } else {
+ if (strcmp(mem->desc, "flash") == 0 ||
+ strcmp(mem->desc, "boot") == 0 ||
+ strcmp(mem->desc, "application") == 0 ||
+ strcmp(mem->desc, "apptable") == 0) {
+ *lowbound = 0;
+ *highbound = 0x7ffff; /* max 8 MiB */
+ *fileoff = 0;
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ *lowbound = 0x810000;
+ *highbound = 0x81ffff; /* max 64 KiB */
+ *fileoff = 0;
+ } else if (strcmp(mem->desc, "lfuse") == 0) {
+ *lowbound = 0x820000;
+ *highbound = 0x82ffff;
+ *fileoff = 0;
+ } else if (strcmp(mem->desc, "hfuse") == 0) {
+ *lowbound = 0x820000;
+ *highbound = 0x82ffff;
+ *fileoff = 1;
+ } else if (strcmp(mem->desc, "efuse") == 0) {
+ *lowbound = 0x820000;
+ *highbound = 0x82ffff;
+ *fileoff = 2;
+ } else if (strncmp(mem->desc, "fuse", 4) == 0 &&
+ (mem->desc[4] >= '0' && mem->desc[4] <= '9')) {
+ /* Xmega fuseN */
+ *lowbound = 0x820000;
+ *highbound = 0x82ffff;
+ *fileoff = mem->desc[4] - '0';
+ } else if (strncmp(mem->desc, "lock", 4) == 0) {
+ *lowbound = 0x830000;
+ *highbound = 0x83ffff;
+ *fileoff = 0;
+ } else {
+ rv = -1;
+ }
+ }
+
+ return rv;
+}
+
+
+static int elf2b(char * infile, FILE * inf,
+ AVRMEM * mem, struct avrpart * p,
+ int bufsize, unsigned int fileoffset)
+{
+ Elf *e;
+ int rv = -1;
+ unsigned int low, high, foff;
+
+ if (elf_mem_limits(mem, p, &low, &high, &foff) != 0) {
+ avrdude_message(MSG_INFO, "%s: ERROR: Cannot handle \"%s\" memory region from ELF file\n",
+ progname, mem->desc);
+ return -1;
+ }
+
+ /*
+ * The Xmega memory regions for "boot", "application", and
+ * "apptable" are actually sub-regions of "flash". Refine the
+ * applicable limits. This allows to select only the appropriate
+ * sections out of an ELF file that contains section data for more
+ * than one sub-segment.
+ */
+ if ((p->flags & AVRPART_HAS_PDI) != 0 &&
+ (strcmp(mem->desc, "boot") == 0 ||
+ strcmp(mem->desc, "application") == 0 ||
+ strcmp(mem->desc, "apptable") == 0)) {
+ AVRMEM *flashmem = avr_locate_mem(p, "flash");
+ if (flashmem == NULL) {
+ avrdude_message(MSG_INFO, "%s: ERROR: No \"flash\" memory region found, "
+ "cannot compute bounds of \"%s\" sub-region.\n",
+ progname, mem->desc);
+ return -1;
+ }
+ /* The config file offsets are PDI offsets, rebase to 0. */
+ low = mem->offset - flashmem->offset;
+ high = low + mem->size - 1;
+ }
+
+ if (elf_version(EV_CURRENT) == EV_NONE) {
+ avrdude_message(MSG_INFO, "%s: ERROR: ELF library initialization failed: %s\n",
+ progname, elf_errmsg(-1));
+ return -1;
+ }
+ if ((e = elf_begin(fileno(inf), ELF_C_READ, NULL)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: ERROR: Cannot open \"%s\" as an ELF file: %s\n",
+ progname, infile, elf_errmsg(-1));
+ return -1;
+ }
+ if (elf_kind(e) != ELF_K_ELF) {
+ avrdude_message(MSG_INFO, "%s: ERROR: Cannot use \"%s\" as an ELF input file\n",
+ progname, infile);
+ goto done;
+ }
+
+ size_t i, isize;
+ const char *id = elf_getident(e, &isize);
+
+ if (id == NULL) {
+ avrdude_message(MSG_INFO, "%s: ERROR: Error reading ident area of \"%s\": %s\n",
+ progname, infile, elf_errmsg(-1));
+ goto done;
+ }
+
+ const char *endianname;
+ unsigned char endianess;
+ if (p->flags & AVRPART_AVR32) {
+ endianess = ELFDATA2MSB;
+ endianname = "little";
+ } else {
+ endianess = ELFDATA2LSB;
+ endianname = "big";
+ }
+ if (id[EI_CLASS] != ELFCLASS32 ||
+ id[EI_DATA] != endianess) {
+ avrdude_message(MSG_INFO, "%s: ERROR: ELF file \"%s\" is not a "
+ "32-bit, %s-endian file that was expected\n",
+ progname, infile, endianname);
+ goto done;
+ }
+
+ Elf32_Ehdr *eh;
+ if ((eh = elf32_getehdr(e)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: ERROR: Error reading ehdr of \"%s\": %s\n",
+ progname, infile, elf_errmsg(-1));
+ goto done;
+ }
+
+ if (eh->e_type != ET_EXEC) {
+ avrdude_message(MSG_INFO, "%s: ERROR: ELF file \"%s\" is not an executable file\n",
+ progname, infile);
+ goto done;
+ }
+
+ const char *mname;
+ uint16_t machine;
+ if (p->flags & AVRPART_AVR32) {
+ machine = EM_AVR32;
+ mname = "AVR32";
+ } else {
+ machine = EM_AVR;
+ mname = "AVR";
+ }
+ if (eh->e_machine != machine) {
+ avrdude_message(MSG_INFO, "%s: ERROR: ELF file \"%s\" is not for machine %s\n",
+ progname, infile, mname);
+ goto done;
+ }
+ if (eh->e_phnum == 0xffff /* PN_XNUM */) {
+ avrdude_message(MSG_INFO, "%s: ERROR: ELF file \"%s\" uses extended "
+ "program header numbers which are not expected\n",
+ progname, infile);
+ goto done;
+ }
+
+ Elf32_Phdr *ph;
+ if ((ph = elf32_getphdr(e)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: ERROR: Error reading program header table of \"%s\": %s\n",
+ progname, infile, elf_errmsg(-1));
+ goto done;
+ }
+
+ size_t sndx;
+ if (elf_getshdrstrndx(e, &sndx) != 0) {
+ avrdude_message(MSG_INFO, "%s: ERROR: Error obtaining section name string table: %s\n",
+ progname, elf_errmsg(-1));
+ sndx = 0;
+ }
+
+ /*
+ * Walk the program header table, pick up entries that are of type
+ * PT_LOAD, and have a non-zero p_filesz.
+ */
+ for (i = 0; i < eh->e_phnum; i++) {
+ if (ph[i].p_type != PT_LOAD ||
+ ph[i].p_filesz == 0)
+ continue;
+
+ avrdude_message(MSG_NOTICE2, "%s: Considering PT_LOAD program header entry #%d:\n"
+ " p_vaddr 0x%x, p_paddr 0x%x, p_filesz %d\n",
+ progname, i, ph[i].p_vaddr, ph[i].p_paddr, ph[i].p_filesz);
+
+ Elf32_Shdr *sh;
+ Elf_Scn *s = elf_get_scn(e, ph + i, &sh);
+ if (s == NULL)
+ continue;
+
+ if ((sh->sh_flags & SHF_ALLOC) && sh->sh_size) {
+ const char *sname;
+
+ if (sndx != 0) {
+ sname = elf_strptr(e, sndx, sh->sh_name);
+ } else {
+ sname = "*unknown*";
+ }
+
+ unsigned int lma;
+ lma = ph[i].p_paddr + sh->sh_offset - ph[i].p_offset;
+
+ avrdude_message(MSG_NOTICE2, "%s: Found section \"%s\", LMA 0x%x, sh_size %u\n",
+ progname, sname, lma, sh->sh_size);
+
+ if (lma >= low &&
+ lma + sh->sh_size < high) {
+ /* OK */
+ } else {
+ avrdude_message(MSG_NOTICE2, " => skipping, inappropriate for \"%s\" memory region\n",
+ mem->desc);
+ continue;
+ }
+ /*
+ * 1-byte sized memory regions are special: they are used for fuse
+ * bits, where multiple regions (in the config file) map to a
+ * single, larger region in the ELF file (e.g. "lfuse", "hfuse",
+ * and "efuse" all map to ".fuse"). We silently accept a larger
+ * ELF file region for these, and extract the actual byte to write
+ * from it, using the "foff" offset obtained above.
+ */
+ if (mem->size != 1 &&
+ sh->sh_size > mem->size) {
+ avrdude_message(MSG_INFO, "%s: ERROR: section \"%s\" does not fit into \"%s\" memory:\n"
+ " 0x%x + %u > %u\n",
+ progname, sname, mem->desc,
+ lma, sh->sh_size, mem->size);
+ continue;
+ }
+
+ Elf_Data *d = NULL;
+ while ((d = elf_getdata(s, d)) != NULL) {
+ avrdude_message(MSG_NOTICE2, " Data block: d_buf %p, d_off 0x%x, d_size %d\n",
+ d->d_buf, (unsigned int)d->d_off, d->d_size);
+ if (mem->size == 1) {
+ if (d->d_off != 0) {
+ avrdude_message(MSG_INFO, "%s: ERROR: unexpected data block at offset != 0\n",
+ progname);
+ } else if (foff >= d->d_size) {
+ avrdude_message(MSG_INFO, "%s: ERROR: ELF file section does not contain byte at offset %d\n",
+ progname, foff);
+ } else {
+ avrdude_message(MSG_NOTICE2, " Extracting one byte from file offset %d\n",
+ foff);
+ mem->buf[0] = ((unsigned char *)d->d_buf)[foff];
+ mem->tags[0] = TAG_ALLOCATED;
+ rv = 1;
+ }
+ } else {
+ unsigned int idx;
+
+ idx = lma - low + d->d_off;
+ if ((int)(idx + d->d_size) > rv)
+ rv = idx + d->d_size;
+ avrdude_message(MSG_DEBUG, " Writing %d bytes to mem offset 0x%x\n",
+ d->d_size, idx);
+ memcpy(mem->buf + idx, d->d_buf, d->d_size);
+ memset(mem->tags + idx, TAG_ALLOCATED, d->d_size);
+ }
+ }
+ }
+ }
+done:
+ (void)elf_end(e);
+ return rv;
+}
+#endif /* HAVE_LIBELF */
+
+/*
+ * Simple itoa() implementation. Caller needs to allocate enough
+ * space in buf. Only positive integers are handled.
+ */
+static char *itoa_simple(int n, char *buf, int base)
+{
+ div_t q;
+ char c, *cp, *cp2;
+
+ cp = buf;
+ /*
+ * Divide by base until the number disappeared, but ensure at least
+ * one digit will be emitted.
+ */
+ do {
+ q = div(n, base);
+ n = q.quot;
+ if (q.rem >= 10)
+ c = q.rem - 10 + 'a';
+ else
+ c = q.rem + '0';
+ *cp++ = c;
+ } while (q.quot != 0);
+
+ /* Terminate the string. */
+ *cp-- = '\0';
+
+ /* Now revert the result string. */
+ cp2 = buf;
+ while (cp > cp2) {
+ c = *cp;
+ *cp-- = *cp2;
+ *cp2++ = c;
+ }
+
+ return buf;
+}
+
+
+
+static int fileio_rbin(struct fioparms * fio,
+ char * filename, FILE * f, AVRMEM * mem, int size)
+{
+ int rc;
+ unsigned char *buf = mem->buf;
+
+ switch (fio->op) {
+ case FIO_READ:
+ rc = fread(buf, 1, size, f);
+ if (rc > 0)
+ memset(mem->tags, TAG_ALLOCATED, rc);
+ break;
+ case FIO_WRITE:
+ rc = fwrite(buf, 1, size, f);
+ break;
+ default:
+ avrdude_message(MSG_INFO, "%s: fileio: invalid operation=%d\n",
+ progname, fio->op);
+ return -1;
+ }
+
+ if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) {
+ avrdude_message(MSG_INFO, "%s: %s error %s %s: %s; %s %d of the expected %d bytes\n",
+ progname, fio->iodesc, fio->dir, filename, strerror(errno),
+ fio->rw, rc, size);
+ return -1;
+ }
+
+ return rc;
+}
+
+
+static int fileio_imm(struct fioparms * fio,
+ char * filename, FILE * f, AVRMEM * mem, int size)
+{
+ int rc = 0;
+ char * e, * p;
+ unsigned long b;
+ int loc;
+
+ switch (fio->op) {
+ case FIO_READ:
+ loc = 0;
+ p = strtok(filename, " ,");
+ while (p != NULL && loc < size) {
+ b = strtoul(p, &e, 0);
+ /* check for binary formated (0b10101001) strings */
+ b = (strncmp (p, "0b", 2))?
+ strtoul (p, &e, 0):
+ strtoul (p + 2, &e, 2);
+ if (*e != 0) {
+ avrdude_message(MSG_INFO, "%s: invalid byte value (%s) specified for immediate mode\n",
+ progname, p);
+ return -1;
+ }
+ mem->buf[loc] = b;
+ mem->tags[loc++] = TAG_ALLOCATED;
+ p = strtok(NULL, " ,");
+ rc = loc;
+ }
+ break;
+ default:
+ avrdude_message(MSG_INFO, "%s: fileio: invalid operation=%d\n",
+ progname, fio->op);
+ return -1;
+ }
+
+ if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) {
+ avrdude_message(MSG_INFO, "%s: %s error %s %s: %s; %s %d of the expected %d bytes\n",
+ progname, fio->iodesc, fio->dir, filename, strerror(errno),
+ fio->rw, rc, size);
+ return -1;
+ }
+
+ return rc;
+}
+
+
+static int fileio_ihex(struct fioparms * fio,
+ char * filename, FILE * f, AVRMEM * mem, int size)
+{
+ int rc;
+
+ switch (fio->op) {
+ case FIO_WRITE:
+ rc = b2ihex(mem->buf, size, 32, fio->fileoffset, filename, f);
+ if (rc < 0) {
+ return -1;
+ }
+ break;
+
+ case FIO_READ:
+ rc = ihex2b(filename, f, mem, size, fio->fileoffset);
+ if (rc < 0)
+ return -1;
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "%s: invalid Intex Hex file I/O operation=%d\n",
+ progname, fio->op);
+ return -1;
+ break;
+ }
+
+ return rc;
+}
+
+
+static int fileio_srec(struct fioparms * fio,
+ char * filename, FILE * f, AVRMEM * mem, int size)
+{
+ int rc;
+
+ switch (fio->op) {
+ case FIO_WRITE:
+ rc = b2srec(mem->buf, size, 32, fio->fileoffset, filename, f);
+ if (rc < 0) {
+ return -1;
+ }
+ break;
+
+ case FIO_READ:
+ rc = srec2b(filename, f, mem, size, fio->fileoffset);
+ if (rc < 0)
+ return -1;
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "%s: ERROR: invalid Motorola S-Records file I/O "
+ "operation=%d\n",
+ progname, fio->op);
+ return -1;
+ break;
+ }
+
+ return rc;
+}
+
+
+#ifdef HAVE_LIBELF
+static int fileio_elf(struct fioparms * fio,
+ char * filename, FILE * f, AVRMEM * mem,
+ struct avrpart * p, int size)
+{
+ int rc;
+
+ switch (fio->op) {
+ case FIO_WRITE:
+ avrdude_message(MSG_INFO, "%s: ERROR: write operation not (yet) "
+ "supported for ELF\n",
+ progname);
+ return -1;
+ break;
+
+ case FIO_READ:
+ rc = elf2b(filename, f, mem, p, size, fio->fileoffset);
+ return rc;
+
+ default:
+ avrdude_message(MSG_INFO, "%s: ERROR: invalid ELF file I/O "
+ "operation=%d\n",
+ progname, fio->op);
+ return -1;
+ break;
+ }
+}
+
+#endif
+
+static int fileio_num(struct fioparms * fio,
+ char * filename, FILE * f, AVRMEM * mem, int size,
+ FILEFMT fmt)
+{
+ const char *prefix;
+ char cbuf[20];
+ int base, i, num;
+
+ switch (fmt) {
+ case FMT_HEX:
+ prefix = "0x";
+ base = 16;
+ break;
+
+ default:
+ case FMT_DEC:
+ prefix = "";
+ base = 10;
+ break;
+
+ case FMT_OCT:
+ prefix = "0";
+ base = 8;
+ break;
+
+ case FMT_BIN:
+ prefix = "0b";
+ base = 2;
+ break;
+
+ }
+
+ switch (fio->op) {
+ case FIO_WRITE:
+ break;
+ default:
+ avrdude_message(MSG_INFO, "%s: fileio: invalid operation=%d\n",
+ progname, fio->op);
+ return -1;
+ }
+
+ for (i = 0; i < size; i++) {
+ if (i > 0) {
+ if (putc(',', f) == EOF)
+ goto writeerr;
+ }
+ num = (unsigned int)(mem->buf[i]);
+ /*
+ * For a base of 8 and a value < 8 to convert, don't write the
+ * prefix. The conversion will be indistinguishable from a
+ * decimal one then.
+ */
+ if (prefix[0] != '\0' && !(base == 8 && num < 8)) {
+ if (fputs(prefix, f) == EOF)
+ goto writeerr;
+ }
+ itoa_simple(num, cbuf, base);
+ if (fputs(cbuf, f) == EOF)
+ goto writeerr;
+ }
+ if (putc('\n', f) == EOF)
+ goto writeerr;
+
+ return 0;
+
+ writeerr:
+ avrdude_message(MSG_INFO, "%s: error writing to %s: %s\n",
+ progname, filename, strerror(errno));
+ return -1;
+}
+
+
+int fileio_setparms(int op, struct fioparms * fp,
+ struct avrpart * p, AVRMEM * m)
+{
+ fp->op = op;
+
+ switch (op) {
+ case FIO_READ:
+ fp->mode = "r";
+ fp->iodesc = "input";
+ fp->dir = "from";
+ fp->rw = "read";
+ break;
+
+ case FIO_WRITE:
+ fp->mode = "w";
+ fp->iodesc = "output";
+ fp->dir = "to";
+ fp->rw = "wrote";
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "%s: invalid I/O operation %d\n",
+ progname, op);
+ return -1;
+ break;
+ }
+
+ /*
+ * AVR32 devices maintain their load offset within the file itself,
+ * but AVRDUDE maintains all memory images 0-based.
+ */
+ if ((p->flags & AVRPART_AVR32) != 0)
+ {
+ fp->fileoffset = m->offset;
+ }
+ else
+ {
+ fp->fileoffset = 0;
+ }
+
+ return 0;
+}
+
+
+
+static int fmt_autodetect(char * fname, unsigned section)
+{
+ FILE * f;
+ unsigned char buf[MAX_LINE_LEN];
+ int i;
+ int len;
+ int found;
+ int first = 1;
+
+#if defined(WIN32NATIVE)
+ f = fopen_and_seek(fname, "r", section);
+#else
+ f = fopen_and_seek(fname, "rb", section);
+#endif
+
+ if (f == NULL) {
+ avrdude_message(MSG_INFO, "%s: error opening %s: %s\n",
+ progname, fname, strerror(errno));
+ return -1;
+ }
+
+ while (fgets((char *)buf, MAX_LINE_LEN, f)!=NULL) {
+ /* check for ELF file */
+ if (first &&
+ (buf[0] == 0177 && buf[1] == 'E' &&
+ buf[2] == 'L' && buf[3] == 'F')) {
+ fclose(f);
+ return FMT_ELF;
+ }
+
+ buf[MAX_LINE_LEN-1] = 0;
+ len = strlen((char *)buf);
+ if (buf[len-1] == '\n')
+ buf[--len] = 0;
+
+ /* check for binary data */
+ found = 0;
+ for (i=0; i<len; i++) {
+ if (buf[i] > 127) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ fclose(f);
+ return FMT_RBIN;
+ }
+
+ /* check for lines that look like intel hex */
+ if ((buf[0] == ':') && (len >= 11)) {
+ found = 1;
+ for (i=1; i<len; i++) {
+ if (!isxdigit(buf[1])) {
+ found = 0;
+ break;
+ }
+ }
+ if (found) {
+ fclose(f);
+ return FMT_IHEX;
+ }
+ }
+
+ /* check for lines that look like motorola s-record */
+ if ((buf[0] == 'S') && (len >= 10) && isdigit(buf[1])) {
+ found = 1;
+ for (i=1; i<len; i++) {
+ if (!isxdigit(buf[1])) {
+ found = 0;
+ break;
+ }
+ }
+ if (found) {
+ fclose(f);
+ return FMT_SREC;
+ }
+ }
+
+ first = 0;
+ }
+
+ fclose(f);
+ return -1;
+}
+
+
+
+int fileio(int op, char * filename, FILEFMT format,
+ struct avrpart * p, char * memtype, int size, unsigned section)
+{
+ int rc;
+ FILE * f;
+ char * fname;
+ struct fioparms fio;
+ AVRMEM * mem;
+ int using_stdio;
+
+ mem = avr_locate_mem(p, memtype);
+ if (mem == NULL) {
+ avrdude_message(MSG_INFO, "fileio(): memory type \"%s\" not configured for device \"%s\"\n",
+ memtype, p->desc);
+ return -1;
+ }
+
+ rc = fileio_setparms(op, &fio, p, mem);
+ if (rc < 0)
+ return -1;
+
+ if (fio.op == FIO_READ)
+ size = mem->size;
+
+ if (fio.op == FIO_READ) {
+ /* 0xff fill unspecified memory */
+ memset(mem->buf, 0xff, size);
+ }
+ memset(mem->tags, 0, size);
+
+ using_stdio = 0;
+
+ if (strcmp(filename, "-")==0) {
+ return -1;
+ // Note: we don't want to read stdin or write to stdout as part of Slic3r
+ // if (fio.op == FIO_READ) {
+ // fname = "<stdin>";
+ // f = stdin;
+ // }
+ // else {
+ // fname = "<stdout>";
+ // f = stdout;
+ // }
+ // using_stdio = 1;
+ }
+ else {
+ fname = filename;
+ f = NULL;
+ }
+
+ if (format == FMT_AUTO) {
+ int format_detect;
+
+ if (using_stdio) {
+ avrdude_message(MSG_INFO, "%s: can't auto detect file format when using stdin/out.\n"
+ "%s Please specify a file format and try again.\n",
+ progname, progbuf);
+ return -1;
+ }
+
+ format_detect = fmt_autodetect(fname, section);
+ if (format_detect < 0) {
+ avrdude_message(MSG_INFO, "%s: can't determine file format for %s, specify explicitly\n",
+ progname, fname);
+ return -1;
+ }
+ format = format_detect;
+
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: %s file %s auto detected as %s\n",
+ progname, fio.iodesc, fname, fmtstr(format));
+ }
+ }
+
+#if defined(WIN32NATIVE)
+ /* Open Raw Binary and ELF format in binary mode on Windows.*/
+ if(format == FMT_RBIN || format == FMT_ELF)
+ {
+ if(fio.op == FIO_READ)
+ {
+ fio.mode = "rb";
+ }
+ if(fio.op == FIO_WRITE)
+ {
+ fio.mode = "wb";
+ }
+ }
+#endif
+
+ if (format != FMT_IMM) {
+ if (!using_stdio) {
+ f = fopen_and_seek(fname, fio.mode, section);
+ if (f == NULL) {
+ avrdude_message(MSG_INFO, "%s: can't open %s file %s: %s\n",
+ progname, fio.iodesc, fname, strerror(errno));
+ return -1;
+ }
+ }
+ }
+
+ switch (format) {
+ case FMT_IHEX:
+ rc = fileio_ihex(&fio, fname, f, mem, size);
+ break;
+
+ case FMT_SREC:
+ rc = fileio_srec(&fio, fname, f, mem, size);
+ break;
+
+ case FMT_RBIN:
+ rc = fileio_rbin(&fio, fname, f, mem, size);
+ break;
+
+ case FMT_ELF:
+#ifdef HAVE_LIBELF
+ rc = fileio_elf(&fio, fname, f, mem, p, size);
+#else
+ avrdude_message(MSG_INFO, "%s: can't handle ELF file %s, "
+ "ELF file support was not compiled in\n",
+ progname, fname);
+ rc = -1;
+#endif
+ break;
+
+ case FMT_IMM:
+ rc = fileio_imm(&fio, fname, f, mem, size);
+ break;
+
+ case FMT_HEX:
+ case FMT_DEC:
+ case FMT_OCT:
+ case FMT_BIN:
+ rc = fileio_num(&fio, fname, f, mem, size, format);
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "%s: invalid %s file format: %d\n",
+ progname, fio.iodesc, format);
+ return -1;
+ }
+
+ if (rc > 0) {
+ if ((op == FIO_READ) && (strcasecmp(mem->desc, "flash") == 0 ||
+ strcasecmp(mem->desc, "application") == 0 ||
+ strcasecmp(mem->desc, "apptable") == 0 ||
+ strcasecmp(mem->desc, "boot") == 0)) {
+ /*
+ * if we are reading flash, just mark the size as being the
+ * highest non-0xff byte
+ */
+ rc = avr_mem_hiaddr(mem);
+ }
+ }
+ if (format != FMT_IMM && !using_stdio) {
+ fclose(f);
+ }
+
+ return rc;
+}
+
diff --git a/xs/src/avrdude/flip1.c b/xs/src/avrdude/flip1.c
new file mode 100644
index 000000000..220a94266
--- /dev/null
+++ b/xs/src/avrdude/flip1.c
@@ -0,0 +1,949 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2014 Joerg Wunsch
+ *
+ * This implementation has been cloned from FLIPv2 implementation
+ * written by Kirill Levchenko.
+ *
+ * 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$ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "flip1.h"
+#include "dfu.h"
+#include "usbdevs.h" /* for USB_VENDOR_ATMEL */
+
+/* There are three versions of the FLIP protocol:
+ *
+ * Version 0: C51 parts
+ * Version 1: megaAVR parts ("USB DFU Bootloader Datasheet" [doc7618])
+ * Version 2: XMEGA parts (AVR4023 [doc8457])
+ *
+ * This implementation handles protocol version 1.
+ *
+ * Protocol version 1 has some, erm, "interesting" features:
+ *
+ * When contacting the fresh bootloader, the only allowed actions are
+ * requesting the configuration/manufacturer information (which is
+ * used to read the signature on AVRs), and to issue a "chip erase".
+ * All operations on flash and EEPROM are restricted before a chip
+ * erase has been seen (security protection).
+ *
+ * However, after the chip erase, the configuration/manufacturer
+ * information can no longer be obtained ... they all respond with
+ * 0xff. Essentially, the device needs a power cycle then, after
+ * which the only actual command to access is a chip erase.
+ *
+ * Quite cumbersome to the user.
+ */
+
+/* EXPORTED CONSTANT STRINGS */
+
+const char flip1_desc[] = "FLIP USB DFU protocol version 1 (doc7618)";
+
+/* PRIVATE DATA STRUCTURES */
+
+struct flip1
+{
+ struct dfu_dev *dfu;
+ unsigned char part_sig[3];
+ unsigned char part_rev;
+ unsigned char boot_ver;
+ unsigned char security_mode_flag; /* indicates the user has already
+ * been hinted about security
+ * mode */
+};
+
+#define FLIP1(pgm) ((struct flip1 *)(pgm->cookie))
+
+/* FLIP1 data structures and constants. */
+
+struct flip1_cmd
+{
+ unsigned char cmd;
+ unsigned char args[5];
+};
+
+struct flip1_cmd_header /* for memory read/write */
+{
+ unsigned char cmd;
+ unsigned char memtype;
+ unsigned char start_addr[2];
+ unsigned char end_addr[2];
+ unsigned char padding[26];
+};
+
+struct flip1_prog_footer
+{
+ unsigned char crc[4]; /* not really used */
+ unsigned char ftr_length; /* 0x10 */
+ unsigned char signature[3]; /* "DFU" */
+ unsigned char bcdversion[2]; /* 0x01, 0x10 */
+ unsigned char vendor[2]; /* or 0xff, 0xff */
+ unsigned char product[2]; /* or 0xff, 0xff */
+ unsigned char device[2]; /* or 0xff, 0xff */
+};
+
+#define FLIP1_CMD_PROG_START 0x01
+#define FLIP1_CMD_DISPLAY_DATA 0x03
+#define FLIP1_CMD_WRITE_COMMAND 0x04
+#define FLIP1_CMD_READ_COMMAND 0x05
+#define FLIP1_CMD_CHANGE_BASE_ADDRESS 0x06
+
+/* args[1:0] for FLIP1_CMD_READ_COMMAND */
+#define FLIP1_READ_BOOTLOADER_VERSION { 0x00, 0x00 }
+#define FLIP1_READ_DEVICE_BOOT_ID1 { 0x00, 0x01 }
+#define FLIP1_READ_DEVICE_BOOT_ID2 { 0x00, 0x02 }
+#define FLIP1_READ_MANUFACTURER_CODE { 0x01, 0x30 }
+#define FLIP1_READ_FAMILY_CODE { 0x01, 0x31 }
+#define FLIP1_READ_PRODUCT_NAME { 0x01, 0x60 }
+#define FLIP1_READ_PRODUCT_REVISION { 0x01, 0x61 }
+
+enum flip1_mem_unit {
+ FLIP1_MEM_UNIT_FLASH = 0x00,
+ FLIP1_MEM_UNIT_EEPROM = 0x01,
+ FLIP1_MEM_UNIT_UNKNOWN = -1
+};
+
+#define STATE_dfuERROR 10 /* bState; requires a DFU_CLRSTATUS */
+
+#define LONG_DFU_TIMEOUT 10000 /* 10 s for program and erase */
+
+/* EXPORTED PROGRAMMER FUNCTION PROTOTYPES */
+
+static int flip1_open(PROGRAMMER *pgm, char *port_spec);
+static int flip1_initialize(PROGRAMMER* pgm, AVRPART *part);
+static void flip1_close(PROGRAMMER* pgm);
+static void flip1_enable(PROGRAMMER* pgm);
+static void flip1_disable(PROGRAMMER* pgm);
+static void flip1_display(PROGRAMMER* pgm, const char *prefix);
+static int flip1_program_enable(PROGRAMMER* pgm, AVRPART *part);
+static int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part);
+static int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char *value);
+static int flip1_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char value);
+static int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes);
+static int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes);
+static int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem);
+static void flip1_setup(PROGRAMMER * pgm);
+static void flip1_teardown(PROGRAMMER * pgm);
+
+/* INTERNAL PROGRAMMER FUNCTION PROTOTYPES */
+#ifdef HAVE_LIBUSB
+// The internal ones are made conditional, as they're not defined further down #ifndef HAVE_LIBUSB
+
+static void flip1_show_info(struct flip1 *flip1);
+
+static int flip1_read_memory(PROGRAMMER * pgm,
+ enum flip1_mem_unit mem_unit, uint32_t addr, void *ptr, int size);
+static int flip1_write_memory(struct dfu_dev *dfu,
+ enum flip1_mem_unit mem_unit, uint32_t addr, const void *ptr, int size);
+
+static const char * flip1_status_str(const struct dfu_status *status);
+static const char * flip1_mem_unit_str(enum flip1_mem_unit mem_unit);
+static int flip1_set_mem_page(struct dfu_dev *dfu, unsigned short page_addr);
+static enum flip1_mem_unit flip1_mem_unit(const char *name);
+
+#endif /* HAVE_LIBUSB */
+
+/* THE INITPGM FUNCTION DEFINITIONS */
+
+void flip1_initpgm(PROGRAMMER *pgm)
+{
+ strcpy(pgm->type, "flip1");
+
+ /* Mandatory Functions */
+ pgm->initialize = flip1_initialize;
+ pgm->enable = flip1_enable;
+ pgm->disable = flip1_disable;
+ pgm->display = flip1_display;
+ pgm->program_enable = flip1_program_enable;
+ pgm->chip_erase = flip1_chip_erase;
+ pgm->open = flip1_open;
+ pgm->close = flip1_close;
+ pgm->paged_load = flip1_paged_load;
+ pgm->paged_write = flip1_paged_write;
+ pgm->read_byte = flip1_read_byte;
+ pgm->write_byte = flip1_write_byte;
+ pgm->read_sig_bytes = flip1_read_sig_bytes;
+ pgm->setup = flip1_setup;
+ pgm->teardown = flip1_teardown;
+}
+
+#ifdef HAVE_LIBUSB
+/* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
+
+int flip1_open(PROGRAMMER *pgm, char *port_spec)
+{
+ FLIP1(pgm)->dfu = dfu_open(port_spec);
+ return (FLIP1(pgm)->dfu != NULL) ? 0 : -1;
+}
+
+int flip1_initialize(PROGRAMMER* pgm, AVRPART *part)
+{
+ unsigned short vid, pid;
+ int result;
+ struct dfu_dev *dfu = FLIP1(pgm)->dfu;
+
+ /* A note about return values. Negative return values from this function are
+ * interpreted as failure by main(), from where this function is called.
+ * However such failures are interpreted as a device signature check failure
+ * and the user is adviced to use the -F option to override this check. In
+ * our case, this is misleading, so we defer reporting an error until another
+ * function is called. Thus, we always return 0 (success) from initialize().
+ * I don't like this, but I don't want to mess with main().
+ */
+
+ /* The dfu_init() function will try to find the target part either based on
+ * a USB address provided by the user with the -P option or by matching the
+ * VID and PID of the device. The VID may be specified in the programmer
+ * definition; if not specified, it defaults to USB_VENDOR_ATMEL (defined
+ * in usbdevs.h). The PID may be specified either in the programmer
+ * definition or the part definition; the programmer definition takes
+ * priority. The default PID value is 0, which causes dfu_init() to ignore
+ * the PID when matching a target device.
+ */
+
+ vid = (pgm->usbvid != 0) ? pgm->usbvid : USB_VENDOR_ATMEL;
+ LNODEID usbpid = lfirst(pgm->usbpid);
+ if (usbpid) {
+ pid = *(int *)(ldata(usbpid));
+ if (lnext(usbpid))
+ avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
+ progname, pid);
+ } else {
+ pid = part->usbpid;
+ }
+ if (!ovsigck && (part->flags & AVRPART_HAS_PDI)) {
+ avrdude_message(MSG_INFO, "%s: \"flip1\" (FLIP protocol version 1) is for AT90USB* and ATmega*U* devices.\n"
+ "%s For Xmega devices, use \"flip2\".\n"
+ "%s (Use -F to bypass this check.)\n",
+ progname, progbuf, progbuf);
+ return -1;
+ }
+
+ result = dfu_init(FLIP1(pgm)->dfu, vid, pid);
+
+ if (result != 0)
+ goto flip1_initialize_fail;
+
+ /* Check if descriptor values are what we expect. */
+
+ if (dfu->dev_desc.idVendor != vid)
+ avrdude_message(MSG_INFO, "%s: Warning: USB idVendor = 0x%04X (expected 0x%04X)\n",
+ progname, dfu->dev_desc.idVendor, vid);
+
+ if (pid != 0 && dfu->dev_desc.idProduct != pid)
+ avrdude_message(MSG_INFO, "%s: Warning: USB idProduct = 0x%04X (expected 0x%04X)\n",
+ progname, dfu->dev_desc.idProduct, pid);
+
+ if (dfu->dev_desc.bNumConfigurations != 1)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bNumConfigurations = %d (expected 1)\n",
+ progname, (int) dfu->dev_desc.bNumConfigurations);
+
+ if (dfu->conf_desc.bNumInterfaces != 1)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bNumInterfaces = %d (expected 1)\n",
+ progname, (int) dfu->conf_desc.bNumInterfaces);
+
+ if (dfu->dev_desc.bDeviceClass != 254)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceClass = %d (expected 254)\n",
+ progname, (int) dfu->dev_desc.bDeviceClass);
+
+ if (dfu->dev_desc.bDeviceSubClass != 1)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceSubClass = %d (expected 1)\n",
+ progname, (int) dfu->dev_desc.bDeviceSubClass);
+
+ if (dfu->dev_desc.bDeviceProtocol != 0)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceProtocol = %d (expected 0)\n",
+ progname, (int) dfu->dev_desc.bDeviceProtocol);
+
+ /*
+ * doc7618 claims an interface class of FEh and a subclas 01h.
+ * However, as of today (2014-01-16), all values in the interface
+ * descriptor (except of bLength and bDescriptorType) are actually
+ * 0. So rather don't check these.
+ */
+ if (0) {
+ if (dfu->intf_desc.bInterfaceClass != 254)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceClass = %d (expected 254)\n",
+ progname, (int) dfu->intf_desc.bInterfaceClass);
+
+ if (dfu->intf_desc.bInterfaceSubClass != 1)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceSubClass = %d (expected 1)\n",
+ progname, (int) dfu->intf_desc.bInterfaceSubClass);
+
+ if (dfu->intf_desc.bInterfaceProtocol != 0)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceSubClass = %d (expected 0)\n",
+ progname, (int) dfu->intf_desc.bInterfaceProtocol);
+ }
+
+ if (dfu->dev_desc.bMaxPacketSize0 != 32)
+ avrdude_message(MSG_INFO, "%s: Warning: bMaxPacketSize0 (%d) != 32, things might go wrong\n",
+ progname, dfu->dev_desc.bMaxPacketSize0);
+
+ if (verbose)
+ flip1_show_info(FLIP1(pgm));
+
+ dfu_abort(dfu);
+
+ return 0;
+
+flip1_initialize_fail:
+ dfu_close(FLIP1(pgm)->dfu);
+ FLIP1(pgm)->dfu = NULL;
+ return 0;
+}
+
+void flip1_close(PROGRAMMER* pgm)
+{
+ if (FLIP1(pgm)->dfu != NULL) {
+ dfu_close(FLIP1(pgm)->dfu);
+ FLIP1(pgm)->dfu = NULL;
+ }
+}
+
+void flip1_enable(PROGRAMMER* pgm)
+{
+ /* Nothing to do. */
+}
+
+void flip1_disable(PROGRAMMER* pgm)
+{
+ /* Nothing to do. */
+}
+
+void flip1_display(PROGRAMMER* pgm, const char *prefix)
+{
+ /* Nothing to do. */
+}
+
+int flip1_program_enable(PROGRAMMER* pgm, AVRPART *part)
+{
+ /* I couldn't find anything that uses this function, although it is marked
+ * as "mandatory" in pgm.c. In case anyone does use it, we'll report an
+ * error if we failed to initialize.
+ */
+
+ return (FLIP1(pgm)->dfu != NULL) ? 0 : -1;
+}
+
+int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part)
+{
+ struct dfu_status status;
+ int cmd_result = 0;
+ int aux_result;
+ unsigned int default_timeout = FLIP1(pgm)->dfu->timeout;
+
+ avrdude_message(MSG_NOTICE2, "%s: flip_chip_erase()\n", progname);
+
+ struct flip1_cmd cmd = {
+ FLIP1_CMD_WRITE_COMMAND, { 0, 0xff }
+ };
+
+ FLIP1(pgm)->dfu->timeout = LONG_DFU_TIMEOUT;
+ cmd_result = dfu_dnload(FLIP1(pgm)->dfu, &cmd, 3);
+ aux_result = dfu_getstatus(FLIP1(pgm)->dfu, &status);
+ FLIP1(pgm)->dfu->timeout = default_timeout;
+
+ if (cmd_result < 0 || aux_result < 0)
+ return -1;
+
+ if (status.bStatus != DFU_STATUS_OK) {
+ avrdude_message(MSG_INFO, "%s: failed to send chip erase command: %s\n",
+ progname, flip1_status_str(&status));
+ if (status.bState == STATE_dfuERROR)
+ dfu_clrstatus(FLIP1(pgm)->dfu);
+ return -1;
+ }
+
+ return 0;
+}
+
+int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char *value)
+{
+ enum flip1_mem_unit mem_unit;
+
+ if (FLIP1(pgm)->dfu == NULL)
+ return -1;
+
+ if (strcasecmp(mem->desc, "signature") == 0) {
+ if (flip1_read_sig_bytes(pgm, part, mem) < 0)
+ return -1;
+ if (addr > mem->size) {
+ avrdude_message(MSG_INFO, "%s: flip1_read_byte(signature): address %lu out of range\n",
+ progname, addr);
+ return -1;
+ }
+ *value = mem->buf[addr];
+ return 0;
+ }
+
+ mem_unit = flip1_mem_unit(mem->desc);
+
+ if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) {
+ avrdude_message(MSG_INFO, "%s: Error: "
+ "\"%s\" memory not accessible using FLIP",
+ progname, mem->desc);
+ avrdude_message(MSG_INFO, "\n");
+ return -1;
+ }
+
+ if (mem_unit == FLIP1_MEM_UNIT_EEPROM)
+ /* 0x01 is used for blank check when reading, 0x02 is EEPROM */
+ mem_unit = 2;
+
+ return flip1_read_memory(pgm, mem_unit, addr, value, 1);
+}
+
+int flip1_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char value)
+{
+ enum flip1_mem_unit mem_unit;
+
+ if (FLIP1(pgm)->dfu == NULL)
+ return -1;
+
+ mem_unit = flip1_mem_unit(mem->desc);
+
+ if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) {
+ avrdude_message(MSG_INFO, "%s: Error: "
+ "\"%s\" memory not accessible using FLIP",
+ progname, mem->desc);
+ avrdude_message(MSG_INFO, "\n");
+ return -1;
+ }
+
+ return flip1_write_memory(FLIP1(pgm)->dfu, mem_unit, addr, &value, 1);
+}
+
+int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ enum flip1_mem_unit mem_unit;
+
+ if (FLIP1(pgm)->dfu == NULL)
+ return -1;
+
+ mem_unit = flip1_mem_unit(mem->desc);
+
+ if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) {
+ avrdude_message(MSG_INFO, "%s: Error: "
+ "\"%s\" memory not accessible using FLIP",
+ progname, mem->desc);
+ avrdude_message(MSG_INFO, "\n");
+ return -1;
+ }
+
+ if (mem_unit == FLIP1_MEM_UNIT_EEPROM)
+ /* 0x01 is used for blank check when reading, 0x02 is EEPROM */
+ mem_unit = 2;
+
+ return flip1_read_memory(pgm, mem_unit, addr, mem->buf + addr, n_bytes);
+}
+
+int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ enum flip1_mem_unit mem_unit;
+ int result;
+
+ if (FLIP1(pgm)->dfu == NULL)
+ return -1;
+
+ mem_unit = flip1_mem_unit(mem->desc);
+
+ if (mem_unit == FLIP1_MEM_UNIT_UNKNOWN) {
+ avrdude_message(MSG_INFO, "%s: Error: "
+ "\"%s\" memory not accessible using FLIP",
+ progname, mem->desc);
+ avrdude_message(MSG_INFO, "\n");
+ return -1;
+ }
+
+ if (n_bytes > INT_MAX) {
+ /* This should never happen, unless the int type is only 16 bits. */
+ avrdude_message(MSG_INFO, "%s: Error: Attempting to read more than %d bytes\n",
+ progname, INT_MAX);
+ exit(1);
+ }
+
+ result = flip1_write_memory(FLIP1(pgm)->dfu, mem_unit, addr,
+ mem->buf + addr, n_bytes);
+
+ return (result == 0) ? n_bytes : -1;
+}
+
+int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
+{
+ avrdude_message(MSG_NOTICE2, "%s: flip1_read_sig_bytes(): ", progname);
+
+ if (FLIP1(pgm)->dfu == NULL)
+ return -1;
+
+ if (mem->size < sizeof(FLIP1(pgm)->part_sig)) {
+ avrdude_message(MSG_INFO, "%s: Error: Signature read must be at least %u bytes\n",
+ progname, (unsigned int) sizeof(FLIP1(pgm)->part_sig));
+ return -1;
+ }
+
+ if (FLIP1(pgm)->part_sig[0] == 0 &&
+ FLIP1(pgm)->part_sig[1] == 0 &&
+ FLIP1(pgm)->part_sig[2] == 0)
+ {
+ /* signature not yet cached */
+ struct dfu_status status;
+ int cmd_result = 0;
+ int aux_result;
+ int i;
+ struct flip1_cmd cmd = {
+ FLIP1_CMD_READ_COMMAND, FLIP1_READ_FAMILY_CODE
+ };
+
+ avrdude_message(MSG_NOTICE2, "from device\n");
+
+ for (i = 0; i < 3; i++)
+ {
+ if (i == 1)
+ cmd.args[1] = 0x60; /* product name */
+ else if (i == 2)
+ cmd.args[1] = 0x61; /* product revision */
+
+ cmd_result = dfu_dnload(FLIP1(pgm)->dfu, &cmd, 3);
+ aux_result = dfu_getstatus(FLIP1(pgm)->dfu, &status);
+
+ if (cmd_result < 0 || aux_result < 0)
+ return -1;
+
+ if (status.bStatus != DFU_STATUS_OK)
+ {
+ avrdude_message(MSG_INFO, "%s: failed to send cmd for signature byte %d: %s\n",
+ progname, i, flip1_status_str(&status));
+ if (status.bState == STATE_dfuERROR)
+ dfu_clrstatus(FLIP1(pgm)->dfu);
+ return -1;
+ }
+
+ cmd_result = dfu_upload(FLIP1(pgm)->dfu, &(FLIP1(pgm)->part_sig[i]), 1);
+ aux_result = dfu_getstatus(FLIP1(pgm)->dfu, &status);
+
+ if (cmd_result < 0 || aux_result < 0)
+ return -1;
+
+ if (status.bStatus != DFU_STATUS_OK)
+ {
+ avrdude_message(MSG_INFO, "%s: failed to read signature byte %d: %s\n",
+ progname, i, flip1_status_str(&status));
+ if (status.bState == STATE_dfuERROR)
+ dfu_clrstatus(FLIP1(pgm)->dfu);
+ return -1;
+ }
+ }
+ }
+ else
+ {
+ avrdude_message(MSG_NOTICE2, "cached\n");
+ }
+
+ memcpy(mem->buf, FLIP1(pgm)->part_sig, sizeof(FLIP1(pgm)->part_sig));
+
+ return 0;
+}
+
+void flip1_setup(PROGRAMMER * pgm)
+{
+ pgm->cookie = calloc(1, sizeof(struct flip1));
+
+ if (pgm->cookie == NULL) {
+ avrdude_message(MSG_INFO, "%s: Out of memory allocating private data structure\n",
+ progname);
+ exit(1);
+ }
+}
+
+void flip1_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+ pgm->cookie = NULL;
+}
+
+/* INTERNAL FUNCTION DEFINITIONS
+ */
+
+void flip1_show_info(struct flip1 *flip1)
+{
+ dfu_show_info(flip1->dfu);
+ avrdude_message(MSG_INFO, " USB max packet size : %hu\n",
+ (unsigned short) flip1->dfu->dev_desc.bMaxPacketSize0);
+}
+
+int flip1_read_memory(PROGRAMMER * pgm,
+ enum flip1_mem_unit mem_unit, uint32_t addr, void *ptr, int size)
+{
+ struct dfu_dev *dfu = FLIP1(pgm)->dfu;
+ unsigned short page_addr;
+ struct dfu_status status;
+ int cmd_result = 0;
+ int aux_result;
+ struct flip1_cmd cmd = {
+ FLIP1_CMD_DISPLAY_DATA, { mem_unit }
+ };
+ unsigned int default_timeout = dfu->timeout;
+
+
+ avrdude_message(MSG_NOTICE2, "%s: flip_read_memory(%s, 0x%04x, %d)\n",
+ progname, flip1_mem_unit_str(mem_unit), addr, size);
+
+ /*
+ * As this function is called once per page, no need to handle 64
+ * KiB border crossing below.
+ *
+ * Also, on AVRs, no page size is larger than 1 KiB, so no need to
+ * split the request into multiple 1 KiB chunks.
+ */
+ if (mem_unit == FLIP1_MEM_UNIT_FLASH) {
+ page_addr = addr >> 16;
+ if (flip1_set_mem_page(dfu, page_addr) < 0)
+ return -1;
+ }
+
+ cmd.args[1] = (addr >> 8) & 0xFF;
+ cmd.args[2] = addr & 0xFF;
+ cmd.args[3] = ((addr + size - 1) >> 8) & 0xFF;
+ cmd.args[4] = (addr + size - 1) & 0xFF;
+
+ dfu->timeout = LONG_DFU_TIMEOUT;
+ cmd_result = dfu_dnload(dfu, &cmd, 6);
+ dfu->timeout = default_timeout;
+ aux_result = dfu_getstatus(dfu, &status);
+
+ if (cmd_result < 0 || aux_result < 0)
+ return -1;
+
+ if (status.bStatus != DFU_STATUS_OK)
+ {
+ avrdude_message(MSG_INFO, "%s: failed to read %u bytes of %s memory @%u: %s\n",
+ progname, size, flip1_mem_unit_str(mem_unit), addr,
+ flip1_status_str(&status));
+ if (status.bState == STATE_dfuERROR)
+ dfu_clrstatus(dfu);
+ return -1;
+ }
+
+ cmd_result = dfu_upload(dfu, (char*) ptr, size);
+ aux_result = dfu_getstatus(dfu, &status);
+
+ if (cmd_result < 0 && aux_result == 0 &&
+ status.bStatus == DFU_STATUS_ERR_WRITE) {
+ if (FLIP1(pgm)->security_mode_flag == 0)
+ avrdude_message(MSG_INFO, "\n%s:\n"
+ "%s***********************************************************************\n"
+ "%sMaybe the device is in ``security mode´´, and needs a chip erase first?\n"
+ "%s***********************************************************************\n"
+ "\n",
+ progname, progbuf, progbuf, progbuf);
+ FLIP1(pgm)->security_mode_flag = 1;
+ }
+
+ if (cmd_result < 0 || aux_result < 0)
+ return -1;
+
+ if (status.bStatus != DFU_STATUS_OK)
+ {
+ avrdude_message(MSG_INFO, "%s: failed to read %u bytes of %s memory @%u: %s\n",
+ progname, size, flip1_mem_unit_str(mem_unit), addr,
+ flip1_status_str(&status));
+ if (status.bState == STATE_dfuERROR)
+ dfu_clrstatus(dfu);
+ return -1;
+ }
+
+ return 0;
+}
+
+int flip1_write_memory(struct dfu_dev *dfu,
+ enum flip1_mem_unit mem_unit, uint32_t addr, const void *ptr, int size)
+{
+ unsigned short page_addr;
+ int write_size;
+ struct dfu_status status;
+ int cmd_result = 0;
+ int aux_result;
+ struct flip1_cmd_header cmd_header = {
+ FLIP1_CMD_PROG_START, mem_unit
+ };
+ struct flip1_prog_footer cmd_footer = {
+ { 0, 0, 0, 0 }, /* CRC */
+ 0x10, /* footer length */
+ { 'D', 'F', 'U' }, /* signature */
+ { 0x01, 0x10 }, /* BCD version */
+ { 0xff, 0xff }, /* vendor */
+ { 0xff, 0xff }, /* product */
+ { 0xff, 0xff } /* device */
+ };
+ unsigned int default_timeout = dfu->timeout;
+ unsigned char *buf;
+
+ avrdude_message(MSG_NOTICE2, "%s: flip_write_memory(%s, 0x%04x, %d)\n",
+ progname, flip1_mem_unit_str(mem_unit), addr, size);
+
+ if (size < 32) {
+ /* presumably single-byte updates; must be padded to USB endpoint size */
+ if ((addr + size - 1) / 32 != addr / 32) {
+ avrdude_message(MSG_INFO, "%s: flip_write_memory(): begin (0x%x) and end (0x%x) not within same 32-byte block\n",
+ progname, addr, addr + size - 1);
+ return -1;
+ }
+ write_size = 32;
+ } else {
+ write_size = size;
+ }
+
+ if ((buf = malloc(sizeof(struct flip1_cmd_header) +
+ write_size +
+ sizeof(struct flip1_prog_footer))) == 0) {
+ avrdude_message(MSG_INFO, "%s: Out of memory\n", progname);
+ return -1;
+ }
+
+ /*
+ * As this function is called once per page, no need to handle 64
+ * KiB border crossing below.
+ *
+ * Also, on AVRs, no page size is larger than 1 KiB, so no need to
+ * split the request into multiple 1 KiB chunks.
+ */
+ if (mem_unit == FLIP1_MEM_UNIT_FLASH) {
+ page_addr = addr >> 16;
+ if (flip1_set_mem_page(dfu, page_addr) < 0) {
+ free(buf);
+ return -1;
+ }
+ }
+
+ cmd_header.start_addr[0] = (addr >> 8) & 0xFF;
+ cmd_header.start_addr[1] = addr & 0xFF;
+ cmd_header.end_addr[0] = ((addr + size - 1) >> 8) & 0xFF;
+ cmd_header.end_addr[1] = (addr + size - 1) & 0xFF;
+
+ memcpy(buf, &cmd_header, sizeof(struct flip1_cmd_header));
+ if (size < 32) {
+ memset(buf + sizeof(struct flip1_cmd_header), 0xff, 32);
+ memcpy(buf + sizeof(struct flip1_cmd_header) + (addr % 32), ptr, size);
+ } else {
+ memcpy(buf + sizeof(struct flip1_cmd_header), ptr, size);
+ }
+ memcpy(buf + sizeof(struct flip1_cmd_header) + write_size,
+ &cmd_footer, sizeof(struct flip1_prog_footer));
+
+ dfu->timeout = LONG_DFU_TIMEOUT;
+ cmd_result = dfu_dnload(dfu, buf,
+ sizeof(struct flip1_cmd_header) +
+ write_size +
+ sizeof(struct flip1_prog_footer));
+ aux_result = dfu_getstatus(dfu, &status);
+ dfu->timeout = default_timeout;
+
+ free(buf);
+
+ if (aux_result < 0 || cmd_result < 0)
+ return -1;
+
+ if (status.bStatus != DFU_STATUS_OK)
+ {
+ avrdude_message(MSG_INFO, "%s: failed to write %u bytes of %s memory @%u: %s\n",
+ progname, size, flip1_mem_unit_str(mem_unit), addr,
+ flip1_status_str(&status));
+ if (status.bState == STATE_dfuERROR)
+ dfu_clrstatus(dfu);
+ return -1;
+ }
+
+ return 0;
+}
+
+int flip1_set_mem_page(struct dfu_dev *dfu,
+ unsigned short page_addr)
+{
+ struct dfu_status status;
+ int cmd_result = 0;
+ int aux_result;
+
+ struct flip1_cmd cmd = {
+ FLIP1_CMD_CHANGE_BASE_ADDRESS, { 0, page_addr }
+ };
+
+ cmd_result = dfu_dnload(dfu, &cmd, 3);
+
+ aux_result = dfu_getstatus(dfu, &status);
+
+ if (cmd_result < 0 || aux_result < 0)
+ return -1;
+
+ if (status.bStatus != DFU_STATUS_OK)
+ {
+ avrdude_message(MSG_INFO, "%s: failed to set memory page: %s\n",
+ progname, flip1_status_str(&status));
+ if (status.bState == STATE_dfuERROR)
+ dfu_clrstatus(dfu);
+ return -1;
+ }
+
+ return 0;
+}
+
+const char * flip1_status_str(const struct dfu_status *status)
+{
+ static const char *msg[] = {
+ "No error condition is present",
+ "File is not targeted for use by this device",
+ "File is for this device but fails some vendor-specific verification test",
+ "Device id unable to write memory",
+ "Memory erase function failed",
+ "Memory erase check failed",
+ "Program memory function failed",
+ "Programmed memory failed verification",
+ "Cannot program memory due to received address that is out of range",
+ "Received DFU_DNLOAD with wLength = 0, but device does not think it has all the data yet.",
+ "Device's firmware is corrupted. It cannot return to run-time operations",
+ "iString indicates a vendor-specific error",
+ "Device detected unexpected USB reset signaling",
+ "Device detected unexpected power on reset",
+ "Something went wrong, but the device does not know what it was",
+ "Device stalled an unexpected request",
+ };
+ if (status->bStatus < sizeof msg / sizeof msg[0])
+ return msg[status->bStatus];
+
+ return "Unknown status code";
+}
+
+const char * flip1_mem_unit_str(enum flip1_mem_unit mem_unit)
+{
+ switch (mem_unit) {
+ case FLIP1_MEM_UNIT_FLASH: return "Flash";
+ case FLIP1_MEM_UNIT_EEPROM: return "EEPROM";
+ default: return "unknown";
+ }
+}
+
+enum flip1_mem_unit flip1_mem_unit(const char *name) {
+ if (strcasecmp(name, "flash") == 0)
+ return FLIP1_MEM_UNIT_FLASH;
+ if (strcasecmp(name, "eeprom") == 0)
+ return FLIP1_MEM_UNIT_EEPROM;
+ return FLIP1_MEM_UNIT_UNKNOWN;
+}
+#else /* HAVE_LIBUSB */
+// Dummy functions
+int flip1_open(PROGRAMMER *pgm, char *port_spec)
+{
+ fprintf(stderr, "%s: Error: No USB support in this compile of avrdude\n",
+ progname);
+ return -1;
+}
+
+int flip1_initialize(PROGRAMMER* pgm, AVRPART *part)
+{
+ return -1;
+}
+
+void flip1_close(PROGRAMMER* pgm)
+{
+}
+
+void flip1_enable(PROGRAMMER* pgm)
+{
+}
+
+void flip1_disable(PROGRAMMER* pgm)
+{
+}
+
+void flip1_display(PROGRAMMER* pgm, const char *prefix)
+{
+}
+
+int flip1_program_enable(PROGRAMMER* pgm, AVRPART *part)
+{
+ return -1;
+}
+
+int flip1_chip_erase(PROGRAMMER* pgm, AVRPART *part)
+{
+ return -1;
+}
+
+int flip1_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char *value)
+{
+ return -1;
+}
+
+int flip1_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char value)
+{
+ return -1;
+}
+
+int flip1_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ return -1;
+}
+
+int flip1_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ return -1;
+}
+
+int flip1_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
+{
+ return -1;
+}
+
+void flip1_setup(PROGRAMMER * pgm)
+{
+}
+
+void flip1_teardown(PROGRAMMER * pgm)
+{
+}
+
+
+#endif /* HAVE_LIBUSB */
diff --git a/xs/src/avrdude/flip1.h b/xs/src/avrdude/flip1.h
new file mode 100644
index 000000000..c5f4986b6
--- /dev/null
+++ b/xs/src/avrdude/flip1.h
@@ -0,0 +1,35 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2014 Joerg Wunsch
+ *
+ * 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 flip1_h
+#define flip1_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char flip1_desc[];
+extern void flip1_initpgm(PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* flip1_h */
diff --git a/xs/src/avrdude/flip2.c b/xs/src/avrdude/flip2.c
new file mode 100644
index 000000000..ba90086a3
--- /dev/null
+++ b/xs/src/avrdude/flip2.c
@@ -0,0 +1,1002 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2012 Kirill Levchenko
+ *
+ * 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$ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "flip2.h"
+#include "dfu.h"
+#include "usbdevs.h" /* for USB_VENDOR_ATMEL */
+
+/* There are three versions of the FLIP protocol:
+ *
+ * Version 0: C51 parts
+ * Version 1: megaAVR parts ("USB DFU Bootloader Datasheet" [doc7618])
+ * Version 2: XMEGA parts (AVR4023 [doc8457])
+ *
+ * We currently only support Version 2, as documented in AVR4023.
+ *
+ * Additional references:
+ * flip_protocol.h from the Atmel Software Framework.
+ * udi_dfu_atmel.c from XMEGA bootloaders archive.
+ */
+
+/* EXPORTED CONSTANT STRINGS */
+
+const char flip2_desc[] = "FLIP USB DFU protocol version 2 (AVR4023)";
+
+/* PRIVATE DATA STRUCTURES */
+
+struct flip2
+{
+ struct dfu_dev *dfu;
+ unsigned char part_sig[3];
+ unsigned char part_rev;
+ unsigned char boot_ver;
+};
+
+#define FLIP2(pgm) ((struct flip2 *)(pgm->cookie))
+
+/* The FLIP2 protocol assigns specific meaning to certain combinations of
+ * status and state bytes in the DFU_GETSTATUS response. These constants en-
+ * code these combinations as a 16-bit value: the high order byte is the
+ * status and the low order byte is the state of the status-state pairing.
+ */
+
+#define FLIP2_STATUS_OK 0x0000
+#define FLIP2_STATUS_STALL 0x0F0A
+#define FLIP2_STATUS_MEM_UKNOWN 0x030A
+#define FLIP2_STATUS_MEM_PROTECTED 0x0300
+#define FLIP2_STATUS_OUTOFRANGE 0x080A
+#define FLIP2_STATUS_BLANK_FAIL 0x0500
+#define FLIP2_STATUS_ERASE_ONGOING 0x0904
+
+/* FLIP2 data structures and constants. */
+
+struct flip2_cmd {
+ unsigned char group_id;
+ unsigned char cmd_id;
+ unsigned char args[4];
+};
+
+#define FLIP2_CMD_GROUP_DOWNLOAD 0x01
+#define FLIP2_CMD_GROUP_UPLOAD 0x03
+#define FLIP2_CMD_GROUP_EXEC 0x04
+#define FLIP2_CMD_GROUP_SELECT 0x06
+
+#define FLIP2_CMD_PROG_START 0x00
+#define FLIP2_CMD_READ_MEMORY 0x00
+#define FLIP2_CMD_SELECT_MEMORY 0x03
+#define FLIP2_CMD_CHIP_ERASE 0x00
+#define FLIP2_CMD_START_APP 0x03
+
+#define FLIP2_SELECT_MEMORY_UNIT 0x00
+#define FLIP2_SELECT_MEMORY_PAGE 0x01
+
+enum flip2_mem_unit {
+ FLIP2_MEM_UNIT_UNKNOWN = -1,
+ FLIP2_MEM_UNIT_FLASH = 0x00,
+ FLIP2_MEM_UNIT_EEPROM = 0x01,
+ FLIP2_MEM_UNIT_SECURITY = 0x02,
+ FLIP2_MEM_UNIT_CONFIGURATION = 0x03,
+ FLIP2_MEM_UNIT_BOOTLOADER = 0x04,
+ FLIP2_MEM_UNIT_SIGNATURE = 0x05,
+ FLIP2_MEM_UNIT_USER = 0x06,
+ FLIP2_MEM_UNIT_INT_RAM = 0x07,
+ FLIP2_MEM_UNIT_EXT_MEM_CS0 = 0x08,
+ FLIP2_MEM_UNIT_EXT_MEM_CS1 = 0x09,
+ FLIP2_MEM_UNIT_EXT_MEM_CS2 = 0x0A,
+ FLIP2_MEM_UNIT_EXT_MEM_CS3 = 0x0B,
+ FLIP2_MEM_UNIT_EXT_MEM_CS4 = 0x0C,
+ FLIP2_MEM_UNIT_EXT_MEM_CS5 = 0x0D,
+ FLIP2_MEM_UNIT_EXT_MEM_CS6 = 0x0E,
+ FLIP2_MEM_UNIT_EXT_MEM_CS7 = 0x0F,
+ FLIP2_MEM_UNIT_EXT_MEM_DF = 0x10
+};
+
+/* EXPORTED PROGRAMMER FUNCTION PROTOTYPES */
+
+static int flip2_open(PROGRAMMER *pgm, char *port_spec);
+static int flip2_initialize(PROGRAMMER* pgm, AVRPART *part);
+static void flip2_close(PROGRAMMER* pgm);
+static void flip2_enable(PROGRAMMER* pgm);
+static void flip2_disable(PROGRAMMER* pgm);
+static void flip2_display(PROGRAMMER* pgm, const char *prefix);
+static int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part);
+static int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part);
+static int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char *value);
+static int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char value);
+static int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes);
+static int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes);
+static int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem);
+static void flip2_setup(PROGRAMMER * pgm);
+static void flip2_teardown(PROGRAMMER * pgm);
+
+/* INTERNAL PROGRAMMER FUNCTION PROTOTYPES */
+#ifdef HAVE_LIBUSB
+// The internal ones are made conditional, as they're not defined further down #ifndef HAVE_LIBUSB
+
+static void flip2_show_info(struct flip2 *flip2);
+
+static int flip2_read_memory(struct dfu_dev *dfu,
+ enum flip2_mem_unit mem_unit, uint32_t addr, void *ptr, int size);
+static int flip2_write_memory(struct dfu_dev *dfu,
+ enum flip2_mem_unit mem_unit, uint32_t addr, const void *ptr, int size);
+
+static int flip2_set_mem_unit(struct dfu_dev *dfu,
+ enum flip2_mem_unit mem_unit);
+static int flip2_set_mem_page(struct dfu_dev *dfu, unsigned short page_addr);
+static int flip2_read_max1k(struct dfu_dev *dfu,
+ unsigned short offset, void *ptr, unsigned short size);
+static int flip2_write_max1k(struct dfu_dev *dfu,
+ unsigned short offset, const void *ptr, unsigned short size);
+
+static const char * flip2_status_str(const struct dfu_status *status);
+static const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit);
+static enum flip2_mem_unit flip2_mem_unit(const char *name);
+
+#endif /* HAVE_LIBUSB */
+
+/* THE INITPGM FUNCTION DEFINITIONS */
+
+void flip2_initpgm(PROGRAMMER *pgm)
+{
+ strcpy(pgm->type, "flip2");
+
+ /* Mandatory Functions */
+ pgm->initialize = flip2_initialize;
+ pgm->enable = flip2_enable;
+ pgm->disable = flip2_disable;
+ pgm->display = flip2_display;
+ pgm->program_enable = flip2_program_enable;
+ pgm->chip_erase = flip2_chip_erase;
+ pgm->open = flip2_open;
+ pgm->close = flip2_close;
+ pgm->paged_load = flip2_paged_load;
+ pgm->paged_write = flip2_paged_write;
+ pgm->read_byte = flip2_read_byte;
+ pgm->write_byte = flip2_write_byte;
+ pgm->read_sig_bytes = flip2_read_sig_bytes;
+ pgm->setup = flip2_setup;
+ pgm->teardown = flip2_teardown;
+}
+
+#ifdef HAVE_LIBUSB
+/* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
+
+int flip2_open(PROGRAMMER *pgm, char *port_spec)
+{
+ FLIP2(pgm)->dfu = dfu_open(port_spec);
+ return (FLIP2(pgm)->dfu != NULL) ? 0 : -1;
+}
+
+int flip2_initialize(PROGRAMMER* pgm, AVRPART *part)
+{
+ unsigned short vid, pid;
+ int result;
+ struct dfu_dev *dfu = FLIP2(pgm)->dfu;
+
+ /* A note about return values. Negative return values from this function are
+ * interpreted as failure by main(), from where this function is called.
+ * However such failures are interpreted as a device signature check failure
+ * and the user is adviced to use the -F option to override this check. In
+ * our case, this is misleading, so we defer reporting an error until another
+ * function is called. Thus, we always return 0 (success) from initialize().
+ * I don't like this, but I don't want to mess with main().
+ */
+
+ /* The dfu_init() function will try to find the target part either based on
+ * a USB address provided by the user with the -P option or by matching the
+ * VID and PID of the device. The VID may be specified in the programmer
+ * definition; if not specified, it defaults to USB_VENDOR_ATMEL (defined
+ * in usbdevs.h). The PID may be specified either in the programmer
+ * definition or the part definition; the programmer definition takes
+ * priority. The default PID value is 0, which causes dfu_init() to ignore
+ * the PID when matching a target device.
+ */
+
+ vid = (pgm->usbvid != 0) ? pgm->usbvid : USB_VENDOR_ATMEL;
+ LNODEID usbpid = lfirst(pgm->usbpid);
+ if (usbpid) {
+ pid = *(int *)(ldata(usbpid));
+ if (lnext(usbpid))
+ avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
+ progname, pid);
+ } else {
+ pid = part->usbpid;
+ }
+
+ if (!ovsigck && !(part->flags & AVRPART_HAS_PDI)) {
+ avrdude_message(MSG_INFO, "%s: \"flip2\" (FLIP protocol version 2) is for Xmega devices.\n"
+ "%s For AT90USB* or ATmega*U* devices, use \"flip1\".\n"
+ "%s (Use -F to bypass this check.)\n",
+ progname, progbuf, progbuf);
+ return -1;
+ }
+
+ result = dfu_init(dfu, vid, pid);
+
+ if (result != 0)
+ goto flip2_initialize_fail;
+
+ /* Check if descriptor values are what we expect. */
+
+ if (dfu->dev_desc.idVendor != vid)
+ avrdude_message(MSG_INFO, "%s: Warning: USB idVendor = 0x%04X (expected 0x%04X)\n",
+ progname, dfu->dev_desc.idVendor, vid);
+
+ if (pid != 0 && dfu->dev_desc.idProduct != pid)
+ avrdude_message(MSG_INFO, "%s: Warning: USB idProduct = 0x%04X (expected 0x%04X)\n",
+ progname, dfu->dev_desc.idProduct, pid);
+
+ if (dfu->dev_desc.bNumConfigurations != 1)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bNumConfigurations = %d (expected 1)\n",
+ progname, (int) dfu->dev_desc.bNumConfigurations);
+
+ if (dfu->conf_desc.bNumInterfaces != 1)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bNumInterfaces = %d (expected 1)\n",
+ progname, (int) dfu->conf_desc.bNumInterfaces);
+
+ if (dfu->dev_desc.bDeviceClass != 0)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceClass = %d (expected 0)\n",
+ progname, (int) dfu->dev_desc.bDeviceClass);
+
+ if (dfu->dev_desc.bDeviceSubClass != 0)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceSubClass = %d (expected 0)\n",
+ progname, (int) dfu->dev_desc.bDeviceSubClass);
+
+ if (dfu->dev_desc.bDeviceProtocol != 0)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bDeviceProtocol = %d (expected 0)\n",
+ progname, (int) dfu->dev_desc.bDeviceProtocol);
+
+ if (dfu->intf_desc.bInterfaceClass != 0xFF)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceClass = %d (expected 255)\n",
+ progname, (int) dfu->intf_desc.bInterfaceClass);
+
+ if (dfu->intf_desc.bInterfaceSubClass != 0)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceSubClass = %d (expected 0)\n",
+ progname, (int) dfu->intf_desc.bInterfaceSubClass);
+
+ if (dfu->intf_desc.bInterfaceProtocol != 0)
+ avrdude_message(MSG_INFO, "%s: Warning: USB bInterfaceSubClass = %d (expected 0)\n",
+ progname, (int) dfu->intf_desc.bInterfaceProtocol);
+
+ result = flip2_read_memory(FLIP2(pgm)->dfu,
+ FLIP2_MEM_UNIT_SIGNATURE, 0, FLIP2(pgm)->part_sig, 4);
+
+ if (result != 0)
+ goto flip2_initialize_fail;
+
+ result = flip2_read_memory(FLIP2(pgm)->dfu,
+ FLIP2_MEM_UNIT_BOOTLOADER, 0, &FLIP2(pgm)->boot_ver, 1);
+
+ if (result != 0)
+ goto flip2_initialize_fail;
+
+ if (verbose)
+ flip2_show_info(FLIP2(pgm));
+
+ return 0;
+
+flip2_initialize_fail:
+ dfu_close(FLIP2(pgm)->dfu);
+ FLIP2(pgm)->dfu = NULL;
+ return 0;
+}
+
+void flip2_close(PROGRAMMER* pgm)
+{
+ if (FLIP2(pgm)->dfu != NULL) {
+ dfu_close(FLIP2(pgm)->dfu);
+ FLIP2(pgm)->dfu = NULL;
+ }
+}
+
+void flip2_enable(PROGRAMMER* pgm)
+{
+ /* Nothing to do. */
+}
+
+void flip2_disable(PROGRAMMER* pgm)
+{
+ /* Nothing to do. */
+}
+
+void flip2_display(PROGRAMMER* pgm, const char *prefix)
+{
+ /* Nothing to do. */
+}
+
+int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part)
+{
+ /* I couldn't find anything that uses this function, although it is marked
+ * as "mandatory" in pgm.c. In case anyone does use it, we'll report an
+ * error if we failed to initialize.
+ */
+
+ return (FLIP2(pgm)->dfu != NULL) ? 0 : -1;
+}
+
+int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part)
+{
+ struct dfu_status status;
+ int cmd_result = 0;
+ int aux_result;
+
+ avrdude_message(MSG_NOTICE2, "%s: flip_chip_erase()\n", progname);
+
+ struct flip2_cmd cmd = {
+ FLIP2_CMD_GROUP_EXEC, FLIP2_CMD_CHIP_ERASE, { 0xFF, 0, 0, 0 }
+ };
+
+ for (;;) {
+ cmd_result = dfu_dnload(FLIP2(pgm)->dfu, &cmd, sizeof(cmd));
+ aux_result = dfu_getstatus(FLIP2(pgm)->dfu, &status);
+
+ if (aux_result != 0)
+ return aux_result;
+
+ if (status.bStatus != DFU_STATUS_OK) {
+ if (status.bStatus == ((FLIP2_STATUS_ERASE_ONGOING >> 8) & 0xFF) &&
+ status.bState == ((FLIP2_STATUS_ERASE_ONGOING >> 0) & 0xFF))
+ {
+ continue;
+ } else
+ avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
+ flip2_status_str(&status));
+ dfu_clrstatus(FLIP2(pgm)->dfu);
+ } else
+ break;
+ }
+
+ return cmd_result;
+}
+
+int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char *value)
+{
+ enum flip2_mem_unit mem_unit;
+
+ if (FLIP2(pgm)->dfu == NULL)
+ return -1;
+
+ mem_unit = flip2_mem_unit(mem->desc);
+
+ if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
+ avrdude_message(MSG_INFO, "%s: Error: "
+ "\"%s\" memory not accessible using FLIP",
+ progname, mem->desc);
+ if (strcmp(mem->desc, "flash") == 0)
+ avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
+ avrdude_message(MSG_INFO, "\n");
+ return -1;
+ }
+
+ return flip2_read_memory(FLIP2(pgm)->dfu, mem_unit, addr, value, 1);
+}
+
+int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char value)
+{
+ enum flip2_mem_unit mem_unit;
+
+ if (FLIP2(pgm)->dfu == NULL)
+ return -1;
+
+ mem_unit = flip2_mem_unit(mem->desc);
+
+ if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
+ avrdude_message(MSG_INFO, "%s: Error: "
+ "\"%s\" memory not accessible using FLIP",
+ progname, mem->desc);
+ if (strcmp(mem->desc, "flash") == 0)
+ avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
+ avrdude_message(MSG_INFO, "\n");
+ return -1;
+ }
+
+ return flip2_write_memory(FLIP2(pgm)->dfu, mem_unit, addr, &value, 1);
+}
+
+int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ enum flip2_mem_unit mem_unit;
+ int result;
+
+ if (FLIP2(pgm)->dfu == NULL)
+ return -1;
+
+ mem_unit = flip2_mem_unit(mem->desc);
+
+ if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
+ avrdude_message(MSG_INFO, "%s: Error: "
+ "\"%s\" memory not accessible using FLIP",
+ progname, mem->desc);
+ if (strcmp(mem->desc, "flash") == 0)
+ avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
+ avrdude_message(MSG_INFO, "\n");
+ return -1;
+ }
+
+ if (n_bytes > INT_MAX) {
+ /* This should never happen, unless the int type is only 16 bits. */
+ avrdude_message(MSG_INFO, "%s: Error: Attempting to read more than %d bytes\n",
+ progname, INT_MAX);
+ exit(1);
+ }
+
+ result = flip2_read_memory(FLIP2(pgm)->dfu, mem_unit, addr,
+ mem->buf + addr, n_bytes);
+
+ return (result == 0) ? n_bytes : -1;
+}
+
+int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ enum flip2_mem_unit mem_unit;
+ int result;
+
+ if (FLIP2(pgm)->dfu == NULL)
+ return -1;
+
+ mem_unit = flip2_mem_unit(mem->desc);
+
+ if (mem_unit == FLIP2_MEM_UNIT_UNKNOWN) {
+ avrdude_message(MSG_INFO, "%s: Error: "
+ "\"%s\" memory not accessible using FLIP",
+ progname, mem->desc);
+ if (strcmp(mem->desc, "flash") == 0)
+ avrdude_message(MSG_INFO, " (did you mean \"application\"?)");
+ avrdude_message(MSG_INFO, "\n");
+ return -1;
+ }
+
+ if (n_bytes > INT_MAX) {
+ /* This should never happen, unless the int type is only 16 bits. */
+ avrdude_message(MSG_INFO, "%s: Error: Attempting to read more than %d bytes\n",
+ progname, INT_MAX);
+ exit(1);
+ }
+
+ result = flip2_write_memory(FLIP2(pgm)->dfu, mem_unit, addr,
+ mem->buf + addr, n_bytes);
+
+ return (result == 0) ? n_bytes : -1;
+}
+
+int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
+{
+ if (FLIP2(pgm)->dfu == NULL)
+ return -1;
+
+ if (mem->size < sizeof(FLIP2(pgm)->part_sig)) {
+ avrdude_message(MSG_INFO, "%s: Error: Signature read must be at least %u bytes\n",
+ progname, (unsigned int) sizeof(FLIP2(pgm)->part_sig));
+ return -1;
+ }
+
+ memcpy(mem->buf, FLIP2(pgm)->part_sig, sizeof(FLIP2(pgm)->part_sig));
+ return 0;
+}
+
+void flip2_setup(PROGRAMMER * pgm)
+{
+ pgm->cookie = calloc(1, sizeof(struct flip2));
+
+ if (pgm->cookie == NULL) {
+ avrdude_message(MSG_INFO, "%s: Out of memory allocating private data structure\n",
+ progname);
+ exit(1);
+ }
+}
+
+void flip2_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+ pgm->cookie = NULL;
+}
+
+/* INTERNAL FUNCTION DEFINITIONS
+ */
+
+void flip2_show_info(struct flip2 *flip2)
+{
+ dfu_show_info(flip2->dfu);
+
+ avrdude_message(MSG_INFO, " Part signature : 0x%02X%02X%02X\n",
+ (int) flip2->part_sig[0],
+ (int) flip2->part_sig[1],
+ (int) flip2->part_sig[2]);
+
+ if (flip2->part_rev < 26)
+ avrdude_message(MSG_INFO, " Part revision : %c\n",
+ (char) (flip2->part_rev + 'A'));
+ else
+ avrdude_message(MSG_INFO, " Part revision : %c%c\n",
+ (char) (flip2->part_rev / 26 - 1 + 'A'),
+ (char) (flip2->part_rev % 26 + 'A'));
+
+ avrdude_message(MSG_INFO, " Bootloader version : 2.%hu.%hu\n",
+ ((unsigned short) flip2->boot_ver >> 4) & 0xF,
+ ((unsigned short) flip2->boot_ver >> 0) & 0xF);
+
+ avrdude_message(MSG_INFO, " USB max packet size : %hu\n",
+ (unsigned short) flip2->dfu->dev_desc.bMaxPacketSize0);
+}
+
+int flip2_read_memory(struct dfu_dev *dfu,
+ enum flip2_mem_unit mem_unit, uint32_t addr, void *ptr, int size)
+{
+ unsigned short prev_page_addr;
+ unsigned short page_addr;
+ const char * mem_name;
+ int read_size;
+ int result;
+
+ avrdude_message(MSG_NOTICE2, "%s: flip_read_memory(%s, 0x%04x, %d)\n",
+ progname, flip2_mem_unit_str(mem_unit), addr, size);
+
+ result = flip2_set_mem_unit(dfu, mem_unit);
+
+ if (result != 0) {
+ if ((mem_name = flip2_mem_unit_str(mem_unit)) != NULL)
+ avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X (%s)\n",
+ progname, (int) mem_unit, mem_name);
+ else
+ avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X\n",
+ progname, (int) mem_unit);
+ return -1;
+ }
+
+ page_addr = addr >> 16;
+ result = flip2_set_mem_page(dfu, page_addr);
+
+ if (result != 0) {
+ avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
+ progname, page_addr);
+ return -1;
+ }
+
+ while (size > 0) {
+ prev_page_addr = page_addr;
+ page_addr = addr >> 16;
+
+ if (page_addr != prev_page_addr) {
+ result = flip2_set_mem_page(dfu, page_addr);
+ if (result != 0) {
+ avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
+ progname, page_addr);
+ return -1;
+ }
+ }
+
+ read_size = (size > 0x400) ? 0x400 : size;
+ result = flip2_read_max1k(dfu, addr & 0xFFFF, ptr, read_size);
+
+ if (result != 0) {
+ avrdude_message(MSG_INFO, "%s: Error: Failed to read 0x%04X bytes at 0x%04lX\n",
+ progname, read_size, (unsigned long) addr);
+ return -1;
+ }
+
+ ptr += read_size;
+ addr += read_size;
+ size -= read_size;
+ }
+
+ return 0;
+}
+
+int flip2_write_memory(struct dfu_dev *dfu,
+ enum flip2_mem_unit mem_unit, uint32_t addr, const void *ptr, int size)
+{
+ unsigned short prev_page_addr;
+ unsigned short page_addr;
+ const char * mem_name;
+ int write_size;
+ int result;
+
+ avrdude_message(MSG_NOTICE2, "%s: flip_write_memory(%s, 0x%04x, %d)\n",
+ progname, flip2_mem_unit_str(mem_unit), addr, size);
+
+ result = flip2_set_mem_unit(dfu, mem_unit);
+
+ if (result != 0) {
+ if ((mem_name = flip2_mem_unit_str(mem_unit)) != NULL)
+ avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X (%s)\n",
+ progname, (int) mem_unit, mem_name);
+ else
+ avrdude_message(MSG_INFO, "%s: Error: Failed to set memory unit 0x%02X\n",
+ progname, (int) mem_unit);
+ return -1;
+ }
+
+ page_addr = addr >> 16;
+ result = flip2_set_mem_page(dfu, page_addr);
+
+ if (result != 0) {
+ avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
+ progname, page_addr);
+ return -1;
+ }
+
+ while (size > 0) {
+ prev_page_addr = page_addr;
+ page_addr = addr >> 16;
+
+ if (page_addr != prev_page_addr) {
+ result = flip2_set_mem_page(dfu, page_addr);
+ if (result != 0) {
+ avrdude_message(MSG_INFO, "%s: Error: Failed to set memory page 0x%04hX\n",
+ progname, page_addr);
+ return -1;
+ }
+ }
+
+ write_size = (size > 0x800) ? 0x800 : size;
+ result = flip2_write_max1k(dfu, addr & 0xFFFF, ptr, write_size);
+
+ if (result != 0) {
+ avrdude_message(MSG_INFO, "%s: Error: Failed to write 0x%04X bytes at 0x%04lX\n",
+ progname, write_size, (unsigned long) addr);
+ return -1;
+ }
+
+ ptr += write_size;
+ addr += write_size;
+ size -= write_size;
+ }
+
+ return 0;
+}
+
+int flip2_set_mem_unit(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit)
+{
+ struct dfu_status status;
+ int cmd_result = 0;
+ int aux_result;
+
+ struct flip2_cmd cmd = {
+ FLIP2_CMD_GROUP_SELECT, FLIP2_CMD_SELECT_MEMORY, { 0, 0, 0, 0 }
+ };
+
+ cmd.args[0] = FLIP2_SELECT_MEMORY_UNIT;
+ cmd.args[1] = mem_unit;
+
+ cmd_result = dfu_dnload(dfu, &cmd, sizeof(cmd));
+
+ aux_result = dfu_getstatus(dfu, &status);
+
+ if (aux_result != 0)
+ return aux_result;
+
+ if (status.bStatus != DFU_STATUS_OK) {
+ if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
+ status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
+ {
+ avrdude_message(MSG_INFO, "%s: Error: Unknown memory unit (0x%02x)\n",
+ progname, (unsigned int) mem_unit);
+ } else
+ avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
+ flip2_status_str(&status));
+ dfu_clrstatus(dfu);
+ }
+
+ return cmd_result;
+}
+
+int flip2_set_mem_page(struct dfu_dev *dfu,
+ unsigned short page_addr)
+{
+ struct dfu_status status;
+ int cmd_result = 0;
+ int aux_result;
+
+ struct flip2_cmd cmd = {
+ FLIP2_CMD_GROUP_SELECT, FLIP2_CMD_SELECT_MEMORY, { 0, 0, 0, 0 }
+ };
+
+ cmd.args[0] = FLIP2_SELECT_MEMORY_PAGE;
+ cmd.args[1] = (page_addr >> 8) & 0xFF;
+ cmd.args[2] = (page_addr >> 0) & 0xFF;
+
+ cmd_result = dfu_dnload(dfu, &cmd, sizeof(cmd));
+
+ aux_result = dfu_getstatus(dfu, &status);
+
+ if (aux_result != 0)
+ return aux_result;
+
+ if (status.bStatus != DFU_STATUS_OK) {
+ if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
+ status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
+ {
+ avrdude_message(MSG_INFO, "%s: Error: Page address out of range (0x%04hx)\n",
+ progname, page_addr);
+ } else
+ avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
+ flip2_status_str(&status));
+ dfu_clrstatus(dfu);
+ }
+
+ return cmd_result;
+}
+
+int flip2_read_max1k(struct dfu_dev *dfu,
+ unsigned short offset, void *ptr, unsigned short size)
+{
+ struct dfu_status status;
+ int cmd_result = 0;
+ int aux_result;
+
+ struct flip2_cmd cmd = {
+ FLIP2_CMD_GROUP_UPLOAD, FLIP2_CMD_READ_MEMORY, { 0, 0, 0, 0 }
+ };
+
+ cmd.args[0] = (offset >> 8) & 0xFF;
+ cmd.args[1] = (offset >> 0) & 0xFF;
+ cmd.args[2] = ((offset+size-1) >> 8) & 0xFF;
+ cmd.args[3] = ((offset+size-1) >> 0) & 0xFF;
+
+ cmd_result = dfu_dnload(dfu, &cmd, sizeof(cmd));
+
+ if (cmd_result != 0)
+ goto flip2_read_max1k_status;
+
+ cmd_result = dfu_upload(dfu, (char*) ptr, size);
+
+flip2_read_max1k_status:
+
+ aux_result = dfu_getstatus(dfu, &status);
+
+ if (aux_result != 0)
+ return aux_result;
+
+ if (status.bStatus != DFU_STATUS_OK) {
+ if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
+ status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
+ {
+ avrdude_message(MSG_INFO, "%s: Error: Address out of range [0x%04hX,0x%04hX]\n",
+ progname, offset, offset+size-1);
+ } else
+ avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
+ flip2_status_str(&status));
+ dfu_clrstatus(dfu);
+ }
+
+ return cmd_result;
+}
+
+int flip2_write_max1k(struct dfu_dev *dfu,
+ unsigned short offset, const void *ptr, unsigned short size)
+{
+ char buffer[64+64+0x400];
+ unsigned short data_offset;
+ struct dfu_status status;
+ int cmd_result = 0;
+ int aux_result;
+
+ struct flip2_cmd cmd = {
+ FLIP2_CMD_GROUP_DOWNLOAD, FLIP2_CMD_PROG_START, { 0, 0, 0, 0 }
+ };
+
+ cmd.args[0] = (offset >> 8) & 0xFF;
+ cmd.args[1] = (offset >> 0) & 0xFF;
+ cmd.args[2] = ((offset+size-1) >> 8) & 0xFF;
+ cmd.args[3] = ((offset+size-1) >> 0) & 0xFF;
+
+ if (size > 0x400) {
+ avrdude_message(MSG_INFO, "%s: Error: Write block too large (%hu > 1024)\n",
+ progname, size);
+ return -1;
+ }
+
+ /* There are some special padding requirements for writes. The first packet
+ * must consist only of the FLIP2 command data, which must be padded to
+ * fill out the USB packet (the packet size is given by bMaxPacketSize0 in
+ * the device descriptor). In addition, the data must be padded so that the
+ * first byte of data to be written is at located at position (offset mod
+ * bMaxPacketSize0) within the packet.
+ */
+
+ data_offset = dfu->dev_desc.bMaxPacketSize0;
+ data_offset += offset % dfu->dev_desc.bMaxPacketSize0;
+
+ memcpy(buffer, &cmd, sizeof(cmd));
+ memset(buffer + sizeof(cmd), 0, data_offset - sizeof(cmd));
+ memcpy(buffer + data_offset, ptr, size);
+
+ cmd_result = dfu_dnload(dfu, buffer, data_offset + size);
+
+ aux_result = dfu_getstatus(dfu, &status);
+
+ if (aux_result != 0)
+ return aux_result;
+
+ if (status.bStatus != DFU_STATUS_OK) {
+ if (status.bStatus == ((FLIP2_STATUS_OUTOFRANGE >> 8) & 0xFF) &&
+ status.bState == ((FLIP2_STATUS_OUTOFRANGE >> 0) & 0xFF))
+ {
+ avrdude_message(MSG_INFO, "%s: Error: Address out of range [0x%04hX,0x%04hX]\n",
+ progname, offset, offset+size-1);
+ } else
+ avrdude_message(MSG_INFO, "%s: Error: DFU status %s\n", progname,
+ flip2_status_str(&status));
+ dfu_clrstatus(dfu);
+ }
+
+ return cmd_result;
+}
+
+const char * flip2_status_str(const struct dfu_status *status)
+{
+ unsigned short selector;
+
+ selector = (unsigned short) status->bStatus << 8;
+ selector |= status->bState;
+
+ switch (selector) {
+ case FLIP2_STATUS_OK: return "OK";
+ case FLIP2_STATUS_STALL: return "STALL";
+ case FLIP2_STATUS_MEM_UKNOWN: return "MEM_UKNOWN";
+ case FLIP2_STATUS_MEM_PROTECTED: return "MEM_PROTECTED";
+ case FLIP2_STATUS_OUTOFRANGE: return "OUTOFRANGE";
+ case FLIP2_STATUS_BLANK_FAIL: return "BLANK_FAIL";
+ case FLIP2_STATUS_ERASE_ONGOING: return "ERASE_ONGOING";
+ default: return dfu_status_str(status->bStatus);
+ }
+}
+
+const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit)
+{
+ switch (mem_unit) {
+ case FLIP2_MEM_UNIT_FLASH: return "Flash";
+ case FLIP2_MEM_UNIT_EEPROM: return "EEPROM";
+ case FLIP2_MEM_UNIT_SECURITY: return "security";
+ case FLIP2_MEM_UNIT_CONFIGURATION: return "configuration";
+ case FLIP2_MEM_UNIT_BOOTLOADER: return "bootloader version";
+ case FLIP2_MEM_UNIT_SIGNATURE: return "signature";
+ case FLIP2_MEM_UNIT_USER: return "user";
+ case FLIP2_MEM_UNIT_INT_RAM: return "internal RAM";
+ case FLIP2_MEM_UNIT_EXT_MEM_CS0: return "EXT_MEM_CS0";
+ case FLIP2_MEM_UNIT_EXT_MEM_CS1: return "EXT_MEM_CS1";
+ case FLIP2_MEM_UNIT_EXT_MEM_CS2: return "EXT_MEM_CS2";
+ case FLIP2_MEM_UNIT_EXT_MEM_CS3: return "EXT_MEM_CS3";
+ case FLIP2_MEM_UNIT_EXT_MEM_CS4: return "EXT_MEM_CS4";
+ case FLIP2_MEM_UNIT_EXT_MEM_CS5: return "EXT_MEM_CS5";
+ case FLIP2_MEM_UNIT_EXT_MEM_CS6: return "EXT_MEM_CS6";
+ case FLIP2_MEM_UNIT_EXT_MEM_CS7: return "EXT_MEM_CS7";
+ case FLIP2_MEM_UNIT_EXT_MEM_DF: return "EXT_MEM_DF";
+ default: return "unknown";
+ }
+}
+
+enum flip2_mem_unit flip2_mem_unit(const char *name) {
+ if (strcasecmp(name, "application") == 0)
+ return FLIP2_MEM_UNIT_FLASH;
+ if (strcasecmp(name, "eeprom") == 0)
+ return FLIP2_MEM_UNIT_EEPROM;
+ if (strcasecmp(name, "signature") == 0)
+ return FLIP2_MEM_UNIT_SIGNATURE;
+ return FLIP2_MEM_UNIT_UNKNOWN;
+}
+
+#else /* HAVE_LIBUSB */
+
+/* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
+
+int flip2_open(PROGRAMMER *pgm, char *port_spec)
+{
+ fprintf(stderr, "%s: Error: No USB support in this compile of avrdude\n",
+ progname);
+ return -1;
+}
+
+int flip2_initialize(PROGRAMMER* pgm, AVRPART *part)
+{
+ return -1;
+}
+
+void flip2_close(PROGRAMMER* pgm)
+{
+}
+
+void flip2_enable(PROGRAMMER* pgm)
+{
+}
+
+void flip2_disable(PROGRAMMER* pgm)
+{
+}
+
+void flip2_display(PROGRAMMER* pgm, const char *prefix)
+{
+}
+
+int flip2_program_enable(PROGRAMMER* pgm, AVRPART *part)
+{
+ return -1;
+}
+
+int flip2_chip_erase(PROGRAMMER* pgm, AVRPART *part)
+{
+ return -1;
+}
+
+int flip2_read_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char *value)
+{
+ return -1;
+}
+
+int flip2_write_byte(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned long addr, unsigned char value)
+{
+ return -1;
+}
+
+int flip2_paged_load(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ return -1;
+}
+
+int flip2_paged_write(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ return -1;
+}
+
+int flip2_read_sig_bytes(PROGRAMMER* pgm, AVRPART *part, AVRMEM *mem)
+{
+ return -1;
+}
+
+void flip2_setup(PROGRAMMER * pgm)
+{
+}
+
+void flip2_teardown(PROGRAMMER * pgm)
+{
+}
+
+
+#endif /* HAVE_LIBUSB */
diff --git a/xs/src/avrdude/flip2.h b/xs/src/avrdude/flip2.h
new file mode 100644
index 000000000..4b1e576d5
--- /dev/null
+++ b/xs/src/avrdude/flip2.h
@@ -0,0 +1,35 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2012 Kirill Levchenko
+ *
+ * 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 flip2_h
+#define flip2_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char flip2_desc[];
+extern void flip2_initpgm(PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* flip2_h */
diff --git a/xs/src/avrdude/freebsd_ppi.h b/xs/src/avrdude/freebsd_ppi.h
new file mode 100644
index 000000000..016bf1826
--- /dev/null
+++ b/xs/src/avrdude/freebsd_ppi.h
@@ -0,0 +1,39 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2005 Joerg Wunsch
+ *
+ * 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 freebsd_ppi_h
+#define freebsd_ppi_h
+
+#include <dev/ppbus/ppi.h>
+
+#define ppi_claim(fd) {}
+
+#define ppi_release(fd) {}
+
+#define DO_PPI_READ(fd, reg, valp) \
+ (void)ioctl(fd, \
+ (reg) == PPIDATA? PPIGDATA: ((reg) == PPICTRL? PPIGCTRL: PPIGSTATUS), \
+ valp)
+#define DO_PPI_WRITE(fd, reg, valp) \
+ (void)ioctl(fd, \
+ (reg) == PPIDATA? PPISDATA: ((reg) == PPICTRL? PPISCTRL: PPISSTATUS), \
+ valp)
+
+#endif /* freebsd_ppi_h */
diff --git a/xs/src/avrdude/ft245r.c b/xs/src/avrdude/ft245r.c
new file mode 100644
index 000000000..cc1061df4
--- /dev/null
+++ b/xs/src/avrdude/ft245r.c
@@ -0,0 +1,963 @@
+
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
+ * some code:
+ * Copyright (C) 2011-2012 Roger E. Wolff <R.E.Wolff@BitWizard.nl>
+ *
+ * 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$ */
+
+/* ft245r -- FT245R/FT232R Synchronous BitBangMode Programmer
+ default pin assign
+ FT232R / FT245R
+ miso = 1; # RxD / D1
+ sck = 0; # RTS / D0
+ mosi = 2; # TxD / D2
+ reset = 4; # DTR / D4
+*/
+
+/*
+ The ft232r is very similar, or even "identical" in the synchronous
+ bitbang mode that we use here.
+
+ This allows boards that have an ft232r for communication and an avr
+ as the processor to function as their own "ICSP". Boards that fit
+ this description include the Arduino Duemilanove, Arduino Diecimila,
+ Arduino NG (http://arduino.cc/it/main/boards) and the BitWizard
+ ftdi_atmega board (http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega)
+
+ The Arduinos have to be patched to bring some of the control lines
+ to the ICSP header. The BitWizard board already has the neccessary
+ wiring on the PCB.
+
+ How to add the wires to an arduino is documented here:
+ http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html
+*/
+
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "bitbang.h"
+#include "ft245r.h"
+#include "usbdevs.h"
+
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
+#if defined(HAVE_LIBFTDI1) && defined(HAVE_LIBUSB_1_0)
+# if defined(HAVE_LIBUSB_1_0_LIBUSB_H)
+# include <libusb-1.0/libusb.h>
+# else
+# include <libusb.h>
+# endif
+# include <libftdi1/ftdi.h>
+#elif defined(HAVE_LIBFTDI) && defined(HAVE_USB_H)
+/* ftdi.h includes usb.h */
+#include <ftdi.h>
+#else
+#warning No libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.
+#define DO_NOT_BUILD_FT245R
+#endif
+
+#ifndef HAVE_PTHREAD_H
+
+static int ft245r_nopthread_open (struct programmer_t *pgm, char * name) {
+ avrdude_message(MSG_INFO, "%s: error: no pthread support. Please compile again with pthread installed."
+#if defined(_WIN32)
+ " See http://sourceware.org/pthreads-win32/."
+#endif
+ "\n",
+ progname);
+
+ return -1;
+}
+
+void ft245r_initpgm(PROGRAMMER * pgm) {
+ strcpy(pgm->type, "ftdi_syncbb");
+ pgm->open = ft245r_nopthread_open;
+}
+
+#elif defined(DO_NOT_BUILD_FT245R)
+
+static int ft245r_noftdi_open (struct programmer_t *pgm, char * name) {
+ avrdude_message(MSG_INFO, "%s: error: no libftdi or libusb support. Install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again.\n",
+ progname);
+
+ return -1;
+}
+
+void ft245r_initpgm(PROGRAMMER * pgm) {
+ strcpy(pgm->type, "ftdi_syncbb");
+ pgm->open = ft245r_noftdi_open;
+}
+
+#else
+
+#include <pthread.h>
+
+#ifdef __APPLE__
+/* Mac OS X defines sem_init but actually does not implement them */
+#include <dispatch/dispatch.h>
+
+typedef dispatch_semaphore_t sem_t;
+
+#define sem_init(psem,x,val) *psem = dispatch_semaphore_create(val)
+#define sem_post(psem) dispatch_semaphore_signal(*psem)
+#define sem_wait(psem) dispatch_semaphore_wait(*psem, DISPATCH_TIME_FOREVER)
+#else
+#include <semaphore.h>
+#endif
+
+#define FT245R_CYCLES 2
+#define FT245R_FRAGMENT_SIZE 512
+#define REQ_OUTSTANDINGS 10
+//#define USE_INLINE_WRITE_PAGE
+
+#define FT245R_DEBUG 0
+
+static struct ftdi_context *handle;
+
+static unsigned char ft245r_ddr;
+static unsigned char ft245r_out;
+static unsigned char ft245r_in;
+
+#define BUFSIZE 0x2000
+
+// libftdi / libftd2xx compatibility functions.
+
+static pthread_t readerthread;
+static sem_t buf_data, buf_space;
+static unsigned char buffer[BUFSIZE];
+static int head, tail;
+
+static void add_to_buf (unsigned char c) {
+ int nh;
+
+ sem_wait (&buf_space);
+ if (head == (BUFSIZE -1)) nh = 0;
+ else nh = head + 1;
+
+ if (nh == tail) {
+ avrdude_message(MSG_INFO, "buffer overflow. Cannot happen!\n");
+ }
+ buffer[head] = c;
+ head = nh;
+ sem_post (&buf_data);
+}
+
+static void *reader (void *arg) {
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
+ struct ftdi_context *handle = (struct ftdi_context *)(arg);
+ unsigned char buf[0x1000];
+ int br, i;
+
+ while (1) {
+ pthread_testcancel();
+ br = ftdi_read_data (handle, buf, sizeof(buf));
+ for (i=0; i<br; i++)
+ add_to_buf (buf[i]);
+ }
+ return NULL;
+}
+
+static int ft245r_send(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
+ int rv;
+
+ rv = ftdi_write_data(handle, buf, len);
+ if (len != rv) return -1;
+ return 0;
+}
+
+static int ft245r_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len) {
+ int i;
+
+ // Copy over data from the circular buffer..
+ // XXX This should timeout, and return error if there isn't enough
+ // data.
+ for (i=0; i<len; i++) {
+ sem_wait (&buf_data);
+ buf[i] = buffer[tail];
+ if (tail == (BUFSIZE -1)) tail = 0;
+ else tail++;
+ sem_post (&buf_space);
+ }
+
+ return 0;
+}
+
+
+static int ft245r_drain(PROGRAMMER * pgm, int display) {
+ int r;
+ unsigned char t;
+
+ // flush the buffer in the chip by changing the mode.....
+ r = ftdi_set_bitmode(handle, 0, BITMODE_RESET); // reset
+ if (r) return -1;
+ r = ftdi_set_bitmode(handle, ft245r_ddr, BITMODE_SYNCBB); // set Synchronuse BitBang
+ if (r) return -1;
+
+ // drain our buffer.
+ while (head != tail) {
+ ft245r_recv (pgm, &t, 1);
+ }
+ return 0;
+}
+
+
+static int ft245r_chip_erase(PROGRAMMER * pgm, AVRPART * p) {
+ unsigned char cmd[4] = {0,0,0,0};
+ unsigned char res[4];
+
+ if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
+ avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
+ p->desc);
+ return -1;
+ }
+
+ avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
+ pgm->cmd(pgm, cmd, res);
+ usleep(p->chip_erase_delay);
+ return pgm->initialize(pgm, p);
+}
+
+
+static int ft245r_set_bitclock(PROGRAMMER * pgm) {
+ int r;
+ int rate = 0;
+
+ /* bitclock is second. 1us = 0.000001. Max rate for ft232r 750000 */
+ if(pgm->bitclock) {
+ rate = (uint32_t)(1.0/pgm->bitclock) * 2;
+ } else if (pgm->baudrate) {
+ rate = pgm->baudrate * 2;
+ } else {
+ rate = 150000; /* should work for all ftdi chips and the avr default internal clock of 1MHz */
+ }
+
+ if (FT245R_DEBUG) {
+ avrdude_message(MSG_NOTICE2, " ft245r: spi bitclk %d -> ft baudrate %d\n",
+ rate / 2, rate);
+ }
+ r = ftdi_set_baudrate(handle, rate);
+ if (r) {
+ avrdude_message(MSG_INFO, "Set baudrate (%d) failed with error '%s'.\n",
+ rate, ftdi_get_error_string (handle));
+ return -1;
+ }
+ return 0;
+}
+
+static int set_pin(PROGRAMMER * pgm, int pinname, int val) {
+ unsigned char buf[1];
+
+ if (pgm->pin[pinname].mask[0] == 0) {
+ // ignore not defined pins (might be the led or vcc or buff if not needed)
+ return 0;
+ }
+
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,pinname,val);
+ buf[0] = ft245r_out;
+
+ ft245r_send (pgm, buf, 1);
+ ft245r_recv (pgm, buf, 1);
+
+ ft245r_in = buf[0];
+ return 0;
+}
+
+static int set_sck(PROGRAMMER * pgm, int value) {
+ return set_pin(pgm, PIN_AVR_SCK, value);
+}
+
+static int set_reset(PROGRAMMER * pgm, int value) {
+ return set_pin(pgm, PIN_AVR_RESET, value);
+}
+
+static int set_buff(PROGRAMMER * pgm, int value) {
+ return set_pin(pgm, PPI_AVR_BUFF, value);
+}
+
+static int set_vcc(PROGRAMMER * pgm, int value) {
+ return set_pin(pgm, PPI_AVR_VCC, value);
+}
+
+/* these functions are callbacks, which go into the
+ * PROGRAMMER data structure ("optional functions")
+ */
+static int set_led_pgm(struct programmer_t * pgm, int value) {
+ return set_pin(pgm, PIN_LED_PGM, value);
+}
+
+static int set_led_rdy(struct programmer_t * pgm, int value) {
+ return set_pin(pgm, PIN_LED_RDY, value);
+}
+
+static int set_led_err(struct programmer_t * pgm, int value) {
+ return set_pin(pgm, PIN_LED_ERR, value);
+}
+
+static int set_led_vfy(struct programmer_t * pgm, int value) {
+ return set_pin(pgm, PIN_LED_VFY, value);
+}
+
+/*
+ * apply power to the AVR processor
+ */
+static void ft245r_powerup(PROGRAMMER * pgm)
+{
+ set_vcc(pgm, ON); /* power up */
+ usleep(100);
+}
+
+
+/*
+ * remove power from the AVR processor
+ */
+static void ft245r_powerdown(PROGRAMMER * pgm)
+{
+ set_vcc(pgm, OFF); /* power down */
+}
+
+
+static void ft245r_disable(PROGRAMMER * pgm) {
+ set_buff(pgm, OFF);
+}
+
+
+static void ft245r_enable(PROGRAMMER * pgm) {
+ /*
+ * Prepare to start talking to the connected device - pull reset low
+ * first, delay a few milliseconds, then enable the buffer. 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.
+ */
+ set_reset(pgm, OFF);
+ usleep(1);
+ set_buff(pgm, ON);
+}
+
+static int ft245r_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+ unsigned char *res);
+/*
+ * issue the 'program enable' command to the AVR device
+ */
+static int ft245r_program_enable(PROGRAMMER * pgm, AVRPART * p) {
+ unsigned char cmd[4] = {0,0,0,0};
+ unsigned char res[4];
+ int i;
+
+ if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
+ avrdude_message(MSG_INFO, "%s: AVR_OP_PGM_ENABLE command not defined for %s\n",
+ progname, p->desc);
+ fflush(stderr);
+ return -1;
+ }
+
+ avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd);
+
+ for(i = 0; i < 4; i++) {
+ ft245r_cmd(pgm, cmd, res);
+
+ if (res[p->pollindex-1] == p->pollvalue) return 0;
+
+ if (FT245R_DEBUG) {
+ avrdude_message(MSG_NOTICE, "%s: Program enable command not successful. Retrying.\n",
+ progname);
+ fflush(stderr);
+ }
+ set_pin(pgm, PIN_AVR_RESET, ON);
+ usleep(20);
+ set_pin(pgm, PIN_AVR_RESET, OFF);
+
+ if (i == 3) {
+ ft245r_drain(pgm, 0);
+ tail = head;
+ }
+ }
+
+ avrdude_message(MSG_INFO, "%s: Device is not responding to program enable. Check connection.\n",
+ progname);
+ fflush(stderr);
+
+ return -1;
+}
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+static int ft245r_initialize(PROGRAMMER * pgm, AVRPART * p) {
+
+ /* Apply power between VCC and GND while RESET and SCK are set to “0â€. In some systems,
+ * the programmer can not guarantee that SCK is held low during power-up. In this
+ * case, RESET must be given a positive pulse of at least two CPU clock cycles duration
+ * after SCK has been set to “0â€.
+ */
+ set_sck(pgm, OFF);
+ ft245r_powerup(pgm);
+
+ set_reset(pgm, OFF);
+ usleep(5000); // 5ms
+ set_reset(pgm, ON);
+ usleep(5000); // 5ms
+ set_reset(pgm, OFF);
+
+ /* Wait for at least 20 ms and enable serial programming by sending the Programming
+ * Enable serial instruction to pin MOSI.
+ */
+ usleep(20000); // 20ms
+
+ return ft245r_program_enable(pgm, p);
+}
+
+static inline int set_data(PROGRAMMER * pgm, unsigned char *buf, unsigned char data) {
+ int j;
+ int buf_pos = 0;
+ unsigned char bit = 0x80;
+
+ for (j=0; j<8; j++) {
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI,data & bit);
+
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
+ buf[buf_pos] = ft245r_out;
+ buf_pos++;
+
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,1);
+ buf[buf_pos] = ft245r_out;
+ buf_pos++;
+
+ bit >>= 1;
+ }
+ return buf_pos;
+}
+
+static inline unsigned char extract_data(PROGRAMMER * pgm, unsigned char *buf, int offset) {
+ int j;
+ int buf_pos = 1;
+ unsigned char bit = 0x80;
+ unsigned char r = 0;
+
+ buf += offset * (8 * FT245R_CYCLES);
+ for (j=0; j<8; j++) {
+ if (GET_BITS_0(buf[buf_pos],pgm,PIN_AVR_MISO)) {
+ r |= bit;
+ }
+ buf_pos += FT245R_CYCLES;
+ bit >>= 1;
+ }
+ return r;
+}
+
+/* to check data */
+static inline unsigned char extract_data_out(PROGRAMMER * pgm, unsigned char *buf, int offset) {
+ int j;
+ int buf_pos = 1;
+ unsigned char bit = 0x80;
+ unsigned char r = 0;
+
+ buf += offset * (8 * FT245R_CYCLES);
+ for (j=0; j<8; j++) {
+ if (GET_BITS_0(buf[buf_pos],pgm,PIN_AVR_MOSI)) {
+ r |= bit;
+ }
+ buf_pos += FT245R_CYCLES;
+ bit >>= 1;
+ }
+ return r;
+}
+
+
+/*
+ * transmit an AVR device command and return the results; 'cmd' and
+ * 'res' must point to at least a 4 byte data buffer
+ */
+static int ft245r_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+ unsigned char *res) {
+ int i,buf_pos;
+ unsigned char buf[128];
+
+ buf_pos = 0;
+ for (i=0; i<4; i++) {
+ buf_pos += set_data(pgm, buf+buf_pos, cmd[i]);
+ }
+ buf[buf_pos] = 0;
+ buf_pos++;
+
+ ft245r_send (pgm, buf, buf_pos);
+ ft245r_recv (pgm, buf, buf_pos);
+ res[0] = extract_data(pgm, buf, 0);
+ res[1] = extract_data(pgm, buf, 1);
+ res[2] = extract_data(pgm, buf, 2);
+ res[3] = extract_data(pgm, buf, 3);
+
+ return 0;
+}
+
+/* lower 8 pins are accepted, they might be also inverted */
+static const struct pindef_t valid_pins = {{0xff},{0xff}} ;
+
+static const struct pin_checklist_t pin_checklist[] = {
+ { PIN_AVR_SCK, 1, &valid_pins},
+ { PIN_AVR_MOSI, 1, &valid_pins},
+ { PIN_AVR_MISO, 1, &valid_pins},
+ { PIN_AVR_RESET,1, &valid_pins},
+ { PPI_AVR_BUFF, 0, &valid_pins},
+};
+
+static int ft245r_open(PROGRAMMER * pgm, char * port) {
+ int rv;
+ int devnum = -1;
+
+ rv = pins_check(pgm,pin_checklist,sizeof(pin_checklist)/sizeof(pin_checklist[0]), true);
+ if(rv) {
+ pgm->display(pgm, progbuf);
+ return rv;
+ }
+
+ strcpy(pgm->port, port);
+
+ if (strcmp(port,DEFAULT_USB) != 0) {
+ if (strncasecmp("ft", port, 2) == 0) {
+ char *startptr = port + 2;
+ char *endptr = NULL;
+ devnum = strtol(startptr,&endptr,10);
+ if ((startptr==endptr) || (*endptr != '\0')) {
+ devnum = -1;
+ }
+ }
+ if (devnum < 0) {
+ avrdude_message(MSG_INFO, "%s: invalid portname '%s': use 'ft[0-9]+'\n",
+ progname,port);
+ return -1;
+ }
+ } else {
+ devnum = 0;
+ }
+
+ handle = malloc (sizeof (struct ftdi_context));
+ ftdi_init(handle);
+ LNODEID usbpid = lfirst(pgm->usbpid);
+ int pid;
+ if (usbpid) {
+ pid = *(int *)(ldata(usbpid));
+ if (lnext(usbpid))
+ avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
+ progname, pid);
+ } else {
+ pid = USB_DEVICE_FT245;
+ }
+ rv = ftdi_usb_open_desc_index(handle,
+ pgm->usbvid?pgm->usbvid:USB_VENDOR_FTDI,
+ pid,
+ pgm->usbproduct[0]?pgm->usbproduct:NULL,
+ pgm->usbsn[0]?pgm->usbsn:NULL,
+ devnum);
+ if (rv) {
+ avrdude_message(MSG_INFO, "can't open ftdi device %d. (%s)\n", devnum, ftdi_get_error_string(handle));
+ goto cleanup_no_usb;
+ }
+
+ ft245r_ddr =
+ pgm->pin[PIN_AVR_SCK].mask[0]
+ | pgm->pin[PIN_AVR_MOSI].mask[0]
+ | pgm->pin[PIN_AVR_RESET].mask[0]
+ | pgm->pin[PPI_AVR_BUFF].mask[0]
+ | pgm->pin[PPI_AVR_VCC].mask[0]
+ | pgm->pin[PIN_LED_ERR].mask[0]
+ | pgm->pin[PIN_LED_RDY].mask[0]
+ | pgm->pin[PIN_LED_PGM].mask[0]
+ | pgm->pin[PIN_LED_VFY].mask[0];
+
+ /* set initial values for outputs, no reset everything else is off */
+ ft245r_out = 0;
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_RESET,1);
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0);
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_MOSI,0);
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_BUFF,0);
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_VCC,0);
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_ERR,0);
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_RDY,0);
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_PGM,0);
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_VFY,0);
+
+
+ rv = ftdi_set_bitmode(handle, ft245r_ddr, BITMODE_SYNCBB); // set Synchronous BitBang
+ if (rv) {
+ avrdude_message(MSG_INFO, "%s: Synchronous BitBangMode is not supported (%s)\n",
+ progname, ftdi_get_error_string(handle));
+ goto cleanup;
+ }
+
+ rv = ft245r_set_bitclock(pgm);
+ if (rv) {
+ goto cleanup;
+ }
+
+ /* We start a new thread to read the output from the FTDI. This is
+ * necessary because otherwise we'll deadlock. We cannot finish
+ * writing because the ftdi cannot send the results because we
+ * haven't provided a read buffer yet. */
+
+ sem_init (&buf_data, 0, 0);
+ sem_init (&buf_space, 0, BUFSIZE);
+ pthread_create (&readerthread, NULL, reader, handle);
+
+ /*
+ * drain any extraneous input
+ */
+ ft245r_drain (pgm, 0);
+
+ ft245r_send (pgm, &ft245r_out, 1);
+ ft245r_recv (pgm, &ft245r_in, 1);
+
+ return 0;
+
+cleanup:
+ ftdi_usb_close(handle);
+cleanup_no_usb:
+ ftdi_deinit (handle);
+ free(handle);
+ handle = NULL;
+ return -1;
+}
+
+
+static void ft245r_close(PROGRAMMER * pgm) {
+ if (handle) {
+ // I think the switch to BB mode and back flushes the buffer.
+ ftdi_set_bitmode(handle, 0, BITMODE_SYNCBB); // set Synchronous BitBang, all in puts
+ ftdi_set_bitmode(handle, 0, BITMODE_RESET); // disable Synchronous BitBang
+ ftdi_usb_close(handle);
+ ftdi_deinit (handle);
+ pthread_cancel(readerthread);
+ pthread_join(readerthread, NULL);
+ free(handle);
+ handle = NULL;
+ }
+}
+
+static void ft245r_display(PROGRAMMER * pgm, const char * p) {
+ avrdude_message(MSG_INFO, "%sPin assignment : 0..7 = DBUS0..7\n",p);/* , 8..11 = GPIO0..3\n",p);*/
+ pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS);
+}
+
+static int ft245r_paged_write_gen(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size, unsigned int addr,
+ unsigned int n_bytes) {
+ unsigned long i, pa;
+ int rc;
+
+ for (i=0; i<n_bytes; i++, addr++) {
+ rc = avr_write_byte_default(pgm, p, m, addr, m->buf[addr]);
+ if (rc != 0) {
+ return -2;
+ }
+
+ if (m->paged) {
+ // Can this piece of code ever be activated?? Do AVRs exist that
+ // have paged non-flash memories? -- REW
+ // XXX Untested code below.
+ /*
+ * check to see if it is time to flush the page with a page
+ * write
+ */
+
+ if (((addr % m->page_size) == m->page_size-1) || (i == n_bytes-1)) {
+ pa = addr - (addr % m->page_size);
+
+ rc = avr_write_page(pgm, p, m, pa);
+ if (rc != 0) {
+ return -2;
+ }
+ }
+ }
+ }
+ return i;
+}
+
+static struct ft245r_request {
+ int addr;
+ int bytes;
+ int n;
+ struct ft245r_request *next;
+} *req_head,*req_tail,*req_pool;
+
+static void put_request(int addr, int bytes, int n) {
+ struct ft245r_request *p;
+ if (req_pool) {
+ p = req_pool;
+ req_pool = p->next;
+ } else {
+ p = malloc(sizeof(struct ft245r_request));
+ if (!p) {
+ avrdude_message(MSG_INFO, "can't alloc memory\n");
+ exit(1);
+ }
+ }
+ memset(p, 0, sizeof(struct ft245r_request));
+ p->addr = addr;
+ p->bytes = bytes;
+ p->n = n;
+ if (req_tail) {
+ req_tail->next = p;
+ req_tail = p;
+ } else {
+ req_head = req_tail = p;
+ }
+}
+
+static int do_request(PROGRAMMER * pgm, AVRMEM *m) {
+ struct ft245r_request *p;
+ int addr, bytes, j, n;
+ unsigned char buf[FT245R_FRAGMENT_SIZE+1+128];
+
+ if (!req_head) return 0;
+ p = req_head;
+ req_head = p->next;
+ if (!req_head) req_tail = req_head;
+
+ addr = p->addr;
+ bytes = p->bytes;
+ n = p->n;
+ memset(p, 0, sizeof(struct ft245r_request));
+ p->next = req_pool;
+ req_pool = p;
+
+ ft245r_recv(pgm, buf, bytes);
+ for (j=0; j<n; j++) {
+ m->buf[addr++] = extract_data(pgm, buf , (j * 4 + 3));
+ }
+ return 1;
+}
+
+static int ft245r_paged_write_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ int page_size, int addr, int n_bytes) {
+ unsigned int i,j;
+ int addr_save,buf_pos,do_page_write,req_count;
+ unsigned char buf[FT245R_FRAGMENT_SIZE+1+128];
+
+ req_count = 0;
+ for (i=0; i<n_bytes; ) {
+ addr_save = addr;
+ buf_pos = 0;
+ do_page_write = 0;
+ for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) {
+ buf_pos += set_data(pgm, buf+buf_pos, (addr & 1)?0x48:0x40 );
+ buf_pos += set_data(pgm, buf+buf_pos, (addr >> 9) & 0xff );
+ buf_pos += set_data(pgm, buf+buf_pos, (addr >> 1) & 0xff );
+ buf_pos += set_data(pgm, buf+buf_pos, m->buf[addr]);
+ addr ++;
+ i++;
+ if ( (m->paged) &&
+ (((i % m->page_size) == 0) || (i == n_bytes))) {
+ do_page_write = 1;
+ break;
+ }
+ }
+#if defined(USE_INLINE_WRITE_PAGE)
+ if (do_page_write) {
+ int addr_wk = addr_save - (addr_save % m->page_size);
+ /* If this device has a "load extended address" command, issue it. */
+ if (m->op[AVR_OP_LOAD_EXT_ADDR]) {
+ unsigned char cmd[4];
+ OPCODE *lext = m->op[AVR_OP_LOAD_EXT_ADDR];
+
+ memset(cmd, 0, 4);
+ avr_set_bits(lext, cmd);
+ avr_set_addr(lext, cmd, addr_wk/2);
+ buf_pos += set_data(pgm, buf+buf_pos, cmd[0]);
+ buf_pos += set_data(pgm, buf+buf_pos, cmd[1]);
+ buf_pos += set_data(pgm, buf+buf_pos, cmd[2]);
+ buf_pos += set_data(pgm, buf+buf_pos, cmd[3]);
+ }
+ buf_pos += set_data(pgm, buf+buf_pos, 0x4C); /* Issue Page Write */
+ buf_pos += set_data(pgm, buf+buf_pos,(addr_wk >> 9) & 0xff);
+ buf_pos += set_data(pgm, buf+buf_pos,(addr_wk >> 1) & 0xff);
+ buf_pos += set_data(pgm, buf+buf_pos, 0);
+ }
+#endif
+ if (i >= n_bytes) {
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); // sck down
+ buf[buf_pos++] = ft245r_out;
+ }
+ ft245r_send(pgm, buf, buf_pos);
+ put_request(addr_save, buf_pos, 0);
+ //ft245r_sync(pgm);
+#if 0
+ avrdude_message(MSG_INFO, "send addr 0x%04x bufsize %d [%02x %02x] page_write %d\n",
+ addr_save,buf_pos,
+ extract_data_out(pgm, buf , (0*4 + 3) ),
+ extract_data_out(pgm, buf , (1*4 + 3) ),
+ do_page_write);
+#endif
+ req_count++;
+ if (req_count > REQ_OUTSTANDINGS)
+ do_request(pgm, m);
+ if (do_page_write) {
+#if defined(USE_INLINE_WRITE_PAGE)
+ while (do_request(pgm, m))
+ ;
+ usleep(m->max_write_delay);
+#else
+ int addr_wk = addr_save - (addr_save % m->page_size);
+ int rc;
+ while (do_request(pgm, m))
+ ;
+ rc = avr_write_page(pgm, p, m, addr_wk);
+ if (rc != 0) {
+ return -2;
+ }
+#endif
+ req_count = 0;
+ }
+ }
+ while (do_request(pgm, m))
+ ;
+ return i;
+}
+
+
+static int ft245r_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes) {
+ if (strcmp(m->desc, "flash") == 0) {
+ return ft245r_paged_write_flash(pgm, p, m, page_size, addr, n_bytes);
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ return ft245r_paged_write_gen(pgm, p, m, page_size, addr, n_bytes);
+ } else {
+ return -2;
+ }
+}
+
+static int ft245r_paged_load_gen(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size, unsigned int addr,
+ int n_bytes) {
+ unsigned char rbyte;
+ unsigned long i;
+ int rc;
+
+ for (i=0; i<n_bytes; i++) {
+ rc = avr_read_byte_default(pgm, p, m, i+addr, &rbyte);
+ if (rc != 0) {
+ return -2;
+ }
+ m->buf[i+addr] = rbyte;
+ }
+ return 0;
+}
+
+static int ft245r_paged_load_flash(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size, unsigned int addr,
+ unsigned int n_bytes) {
+ unsigned long i,j,n;
+ int addr_save,buf_pos;
+ int req_count = 0;
+ unsigned char buf[FT245R_FRAGMENT_SIZE+1];
+
+ for (i=0; i<n_bytes; ) {
+ buf_pos = 0;
+ addr_save = addr;
+ for (j=0; j< FT245R_FRAGMENT_SIZE/8/FT245R_CYCLES/4; j++) {
+ if (i >= n_bytes) break;
+ buf_pos += set_data(pgm, buf+buf_pos, (addr & 1)?0x28:0x20 );
+ buf_pos += set_data(pgm, buf+buf_pos, (addr >> 9) & 0xff );
+ buf_pos += set_data(pgm, buf+buf_pos, (addr >> 1) & 0xff );
+ buf_pos += set_data(pgm, buf+buf_pos, 0);
+ addr ++;
+ i++;
+ }
+ if (i >= n_bytes) {
+ ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); // sck down
+ buf[buf_pos++] = ft245r_out;
+ }
+ n = j;
+ ft245r_send(pgm, buf, buf_pos);
+ put_request(addr_save, buf_pos, n);
+ req_count++;
+ if (req_count > REQ_OUTSTANDINGS)
+ do_request(pgm, m);
+
+ }
+ while (do_request(pgm, m))
+ ;
+ return 0;
+}
+
+static int ft245r_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size, unsigned int addr,
+ unsigned int n_bytes) {
+ if (strcmp(m->desc, "flash") == 0) {
+ return ft245r_paged_load_flash(pgm, p, m, page_size, addr, n_bytes);
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ return ft245r_paged_load_gen(pgm, p, m, page_size, addr, n_bytes);
+ } else {
+ return -2;
+ }
+}
+
+void ft245r_initpgm(PROGRAMMER * pgm) {
+ strcpy(pgm->type, "ftdi_syncbb");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = ft245r_initialize;
+ pgm->display = ft245r_display;
+ pgm->enable = ft245r_enable;
+ pgm->disable = ft245r_disable;
+ pgm->program_enable = ft245r_program_enable;
+ pgm->chip_erase = ft245r_chip_erase;
+ pgm->cmd = ft245r_cmd;
+ pgm->open = ft245r_open;
+ pgm->close = ft245r_close;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = ft245r_paged_write;
+ pgm->paged_load = ft245r_paged_load;
+
+ pgm->rdy_led = set_led_rdy;
+ pgm->err_led = set_led_err;
+ pgm->pgm_led = set_led_pgm;
+ pgm->vfy_led = set_led_vfy;
+ pgm->powerup = ft245r_powerup;
+ pgm->powerdown = ft245r_powerdown;
+
+ handle = NULL;
+}
+
+#endif
+
+const char ft245r_desc[] = "FT245R/FT232R Synchronous BitBangMode Programmer";
diff --git a/xs/src/avrdude/ft245r.h b/xs/src/avrdude/ft245r.h
new file mode 100644
index 000000000..40602e220
--- /dev/null
+++ b/xs/src/avrdude/ft245r.h
@@ -0,0 +1,8 @@
+#ifndef ft245r_h
+#define ft245r_h
+
+extern const char ft245r_desc[];
+void ft245r_initpgm (PROGRAMMER * pgm);
+
+
+#endif /* ft245r_h */
diff --git a/xs/src/avrdude/jtag3.c b/xs/src/avrdude/jtag3.c
new file mode 100644
index 000000000..3084c3201
--- /dev/null
+++ b/xs/src/avrdude/jtag3.c
@@ -0,0 +1,2286 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2012 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ *
+ * 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 Atmel JTAGICE3 programmer
+ */
+
+#include "ac_cfg.h"
+
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "crc16.h"
+#include "jtag3.h"
+#include "jtag3_private.h"
+#include "usbdevs.h"
+
+/*
+ * Private data for this programmer.
+ */
+struct pdata
+{
+ unsigned short command_sequence; /* Next cmd seqno to issue. */
+
+ /*
+ * See jtag3_read_byte() for an explanation of the flash and
+ * EEPROM page caches.
+ */
+ unsigned char *flash_pagecache;
+ unsigned long flash_pageaddr;
+ unsigned int flash_pagesize;
+
+ unsigned char *eeprom_pagecache;
+ unsigned long eeprom_pageaddr;
+ unsigned int eeprom_pagesize;
+
+ int prog_enabled; /* Cached value of PROGRAMMING status. */
+
+ /* JTAG chain stuff */
+ unsigned char jtagchain[4];
+
+ /* Start address of Xmega boot area */
+ unsigned long boot_start;
+
+ /* Function to set the appropriate clock parameter */
+ int (*set_sck)(PROGRAMMER *, unsigned char *);
+};
+
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
+/*
+ * pgm->flag is marked as "for private use of the programmer".
+ * The following defines this programmer's use of that field.
+ */
+#define PGM_FL_IS_DW (0x0001)
+#define PGM_FL_IS_PDI (0x0002)
+#define PGM_FL_IS_JTAG (0x0004)
+#define PGM_FL_IS_EDBG (0x0008)
+
+static int jtag3_open(PROGRAMMER * pgm, char * port);
+static int jtag3_edbg_prepare(PROGRAMMER * pgm);
+static int jtag3_edbg_signoff(PROGRAMMER * pgm);
+static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
+static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg);
+
+static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p);
+static int jtag3_chip_erase(PROGRAMMER * pgm, AVRPART * p);
+static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value);
+static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data);
+static int jtag3_set_sck_period(PROGRAMMER * pgm, double v);
+static void jtag3_print_parms1(PROGRAMMER * pgm, const char * p);
+static int jtag3_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes);
+static unsigned char jtag3_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr);
+static unsigned int jtag3_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr);
+
+
+void jtag3_setup(PROGRAMMER * pgm)
+{
+ if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
+ avrdude_message(MSG_INFO, "%s: jtag3_setup(): Out of memory allocating private data\n",
+ progname);
+ exit(1);
+ }
+ memset(pgm->cookie, 0, sizeof(struct pdata));
+}
+
+void jtag3_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+}
+
+
+static unsigned long
+b4_to_u32(unsigned char *b)
+{
+ unsigned long l;
+ l = b[0];
+ l += (unsigned)b[1] << 8;
+ l += (unsigned)b[2] << 16;
+ l += (unsigned)b[3] << 24;
+
+ return l;
+}
+
+static void
+u32_to_b4(unsigned char *b, unsigned long l)
+{
+ b[0] = l & 0xff;
+ b[1] = (l >> 8) & 0xff;
+ b[2] = (l >> 16) & 0xff;
+ b[3] = (l >> 24) & 0xff;
+}
+
+static unsigned short
+b2_to_u16(unsigned char *b)
+{
+ unsigned short l;
+ l = b[0];
+ l += (unsigned)b[1] << 8;
+
+ return l;
+}
+
+static void
+u16_to_b2(unsigned char *b, unsigned short l)
+{
+ b[0] = l & 0xff;
+ b[1] = (l >> 8) & 0xff;
+}
+
+static void jtag3_print_data(unsigned char *b, size_t s)
+{
+ int i;
+
+ if (s < 2)
+ return;
+
+ for (i = 0; i < s; i++) {
+ avrdude_message(MSG_INFO, "0x%02x", b[i]);
+ if (i % 16 == 15)
+ putc('\n', stderr);
+ else
+ putc(' ', stderr);
+ }
+ if (i % 16 != 0)
+ putc('\n', stderr);
+}
+
+static void jtag3_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ int i;
+
+ if (verbose >= 4) {
+ avrdude_message(MSG_TRACE, "Raw message:\n");
+
+ for (i = 0; i < len; i++) {
+ avrdude_message(MSG_TRACE, "%02x ", data[i]);
+ if (i % 16 == 15)
+ putc('\n', stderr);
+ else
+ putc(' ', stderr);
+ }
+ if (i % 16 != 0)
+ putc('\n', stderr);
+ }
+
+ switch (data[0]) {
+ case SCOPE_INFO:
+ avrdude_message(MSG_INFO, "[info] ");
+ break;
+
+ case SCOPE_GENERAL:
+ avrdude_message(MSG_INFO, "[general] ");
+ break;
+
+ case SCOPE_AVR_ISP:
+ avrdude_message(MSG_INFO, "[AVRISP] ");
+ jtag3_print_data(data + 1, len - 1);
+ return;
+
+ case SCOPE_AVR:
+ avrdude_message(MSG_INFO, "[AVR] ");
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "[scope 0x%02x] ", data[0]);
+ break;
+ }
+
+ switch (data[1]) {
+ case RSP3_OK:
+ avrdude_message(MSG_INFO, "OK\n");
+ break;
+
+ case RSP3_FAILED:
+ avrdude_message(MSG_INFO, "FAILED");
+ if (len > 3)
+ {
+ char reason[50];
+ sprintf(reason, "0x%02x", data[3]);
+ switch (data[3])
+ {
+ case RSP3_FAIL_NO_ANSWER:
+ strcpy(reason, "target does not answer");
+ break;
+
+ case RSP3_FAIL_NO_TARGET_POWER:
+ strcpy(reason, "no target power");
+ break;
+
+ case RSP3_FAIL_NOT_UNDERSTOOD:
+ strcpy(reason, "command not understood");
+ break;
+
+ case RSP3_FAIL_WRONG_MODE:
+ strcpy(reason, "wrong (programming) mode");
+ break;
+
+ case RSP3_FAIL_PDI:
+ strcpy(reason, "PDI failure");
+ break;
+
+ case RSP3_FAIL_UNSUPP_MEMORY:
+ strcpy(reason, "unsupported memory type");
+ break;
+
+ case RSP3_FAIL_WRONG_LENGTH:
+ strcpy(reason, "wrong length in memory access");
+ break;
+
+ case RSP3_FAIL_DEBUGWIRE:
+ strcpy(reason, "debugWIRE communication failed");
+ break;
+ }
+ avrdude_message(MSG_INFO, ", reason: %s\n", reason);
+ }
+ else
+ {
+ avrdude_message(MSG_INFO, ", unspecified reason\n");
+ }
+ break;
+
+ case RSP3_DATA:
+ avrdude_message(MSG_INFO, "Data returned:\n");
+ jtag3_print_data(data + 2, len - 2);
+ break;
+
+ case RSP3_INFO:
+ avrdude_message(MSG_INFO, "Info returned:\n");
+ for (i = 2; i < len; i++) {
+ if (isprint(data[i]))
+ putc(data[i], stderr);
+ else
+ avrdude_message(MSG_INFO, "\\%03o", data[i]);
+ }
+ putc('\n', stderr);
+ break;
+
+ case RSP3_PC:
+ if (len < 7)
+ {
+ avrdude_message(MSG_INFO, "PC reply too short\n");
+ }
+ else
+ {
+ unsigned long pc = (data[6] << 24) | (data[5] << 16)
+ | (data[4] << 8) | data[3];
+ avrdude_message(MSG_INFO, "PC 0x%0lx\n", pc);
+ }
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "unknown message 0x%02x\n", data[1]);
+ }
+}
+
+static void jtag3_prevent(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ int i;
+
+ if (verbose >= 4) {
+ avrdude_message(MSG_TRACE, "Raw event:\n");
+
+ for (i = 0; i < len; i++) {
+ avrdude_message(MSG_TRACE, "%02x ", data[i]);
+ if (i % 16 == 15)
+ putc('\n', stderr);
+ else
+ putc(' ', stderr);
+ }
+ if (i % 16 != 0)
+ putc('\n', stderr);
+ }
+
+ avrdude_message(MSG_INFO, "Event serial 0x%04x, ",
+ (data[3] << 8) | data[2]);
+
+ switch (data[4]) {
+ case SCOPE_INFO:
+ avrdude_message(MSG_INFO, "[info] ");
+ break;
+
+ case SCOPE_GENERAL:
+ avrdude_message(MSG_INFO, "[general] ");
+ break;
+
+ case SCOPE_AVR:
+ avrdude_message(MSG_INFO, "[AVR] ");
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "[scope 0x%02x] ", data[0]);
+ break;
+ }
+
+ switch (data[5]) {
+ case EVT3_BREAK:
+ avrdude_message(MSG_INFO, "BREAK");
+ if (len >= 11) {
+ avrdude_message(MSG_INFO, ", PC = 0x%lx, reason ", b4_to_u32(data + 6));
+ switch (data[10]) {
+ case 0x00:
+ avrdude_message(MSG_INFO, "unspecified");
+ break;
+ case 0x01:
+ avrdude_message(MSG_INFO, "program break");
+ break;
+ case 0x02:
+ avrdude_message(MSG_INFO, "data break PDSB");
+ break;
+ case 0x03:
+ avrdude_message(MSG_INFO, "data break PDMSB");
+ break;
+ default:
+ avrdude_message(MSG_INFO, "unknown: 0x%02x", data[10]);
+ }
+ /* There are two more bytes of data which always appear to be
+ * 0x01, 0x00. Purpose unknown. */
+ }
+ break;
+
+ case EVT3_SLEEP:
+ if (len >= 8 && data[7] == 0)
+ avrdude_message(MSG_INFO, "sleeping");
+ else if (len >= 8 && data[7] == 1)
+ avrdude_message(MSG_INFO, "wakeup");
+ else
+ avrdude_message(MSG_INFO, "unknown SLEEP event");
+ break;
+
+ case EVT3_POWER:
+ if (len >= 8 && data[7] == 0)
+ avrdude_message(MSG_INFO, "power-down");
+ else if (len >= 8 && data[7] == 1)
+ avrdude_message(MSG_INFO, "power-up");
+ else
+ avrdude_message(MSG_INFO, "unknown POWER event");
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "UNKNOWN 0x%02x", data[5]);
+ break;
+ }
+ putc('\n', stderr);
+}
+
+
+
+int jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ unsigned char *buf;
+
+ if (pgm->flag & PGM_FL_IS_EDBG)
+ return jtag3_edbg_send(pgm, data, len);
+
+ avrdude_message(MSG_DEBUG, "\n%s: jtag3_send(): sending %lu bytes\n",
+ progname, (unsigned long)len);
+
+ if ((buf = malloc(len + 4)) == NULL)
+ {
+ avrdude_message(MSG_INFO, "%s: jtag3_send(): out of memory",
+ progname);
+ return -1;
+ }
+
+ buf[0] = TOKEN;
+ buf[1] = 0; /* dummy */
+ u16_to_b2(buf + 2, PDATA(pgm)->command_sequence);
+ memcpy(buf + 4, data, len);
+
+ if (serial_send(&pgm->fd, buf, len + 4) != 0) {
+ avrdude_message(MSG_INFO, "%s: jtag3_send(): failed to send command to serial port\n",
+ progname);
+ return -1;
+ }
+
+ free(buf);
+
+ return 0;
+}
+
+static int jtag3_edbg_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ unsigned char buf[USBDEV_MAX_XFER_3];
+ unsigned char status[USBDEV_MAX_XFER_3];
+ int rv;
+
+ if (verbose >= 4)
+ {
+ memset(buf, 0, USBDEV_MAX_XFER_3);
+ memset(status, 0, USBDEV_MAX_XFER_3);
+ }
+
+ avrdude_message(MSG_DEBUG, "\n%s: jtag3_edbg_send(): sending %lu bytes\n",
+ progname, (unsigned long)len);
+
+ /* 4 bytes overhead for CMD, fragment #, and length info */
+ int max_xfer = pgm->fd.usb.max_xfer;
+ int nfragments = (len + max_xfer - 1) / max_xfer;
+ if (nfragments > 1)
+ {
+ avrdude_message(MSG_DEBUG, "%s: jtag3_edbg_send(): fragmenting into %d packets\n",
+ progname, nfragments);
+ }
+ int frag;
+ for (frag = 0; frag < nfragments; frag++)
+ {
+ int this_len;
+
+ /* All fragments have the (CMSIS-DAP layer) CMD, the fragment
+ * identifier, and the length field. */
+ buf[0] = EDBG_VENDOR_AVR_CMD;
+ buf[1] = ((frag + 1) << 4) | nfragments;
+
+ if (frag == 0)
+ {
+ /* Only first fragment has TOKEN and seq#, thus four bytes
+ * less payload than subsequent fragments. */
+ this_len = len < max_xfer - 8? len: max_xfer - 8;
+ buf[2] = (this_len + 4) >> 8;
+ buf[3] = (this_len + 4) & 0xff;
+ buf[4] = TOKEN;
+ buf[5] = 0; /* dummy */
+ u16_to_b2(buf + 6, PDATA(pgm)->command_sequence);
+ memcpy(buf + 8, data, this_len);
+ }
+ else
+ {
+ this_len = len < max_xfer - 4? len: max_xfer - 4;
+ buf[2] = (this_len) >> 8;
+ buf[3] = (this_len) & 0xff;
+ memcpy(buf + 4, data, this_len);
+ }
+
+ if (serial_send(&pgm->fd, buf, max_xfer) != 0) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): failed to send command to serial port\n",
+ progname);
+ return -1;
+ }
+ rv = serial_recv(&pgm->fd, status, max_xfer);
+
+ if (rv < 0) {
+ /* timeout in receive */
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_edbg_send(): Timeout receiving packet\n",
+ progname);
+ return -1;
+ }
+ if (status[0] != EDBG_VENDOR_AVR_CMD ||
+ (frag == nfragments - 1 && status[1] != 0x01))
+ {
+ /* what to do in this case? */
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_send(): Unexpected response 0x%02x, 0x%02x\n",
+ progname, status[0], status[1]);
+ }
+ data += this_len;
+ len -= this_len;
+ }
+
+ return 0;
+}
+
+/*
+ * Send out all the CMSIS-DAP stuff needed to prepare the ICE.
+ */
+static int jtag3_edbg_prepare(PROGRAMMER * pgm)
+{
+ unsigned char buf[USBDEV_MAX_XFER_3];
+ unsigned char status[USBDEV_MAX_XFER_3];
+ int rv;
+
+ avrdude_message(MSG_DEBUG, "\n%s: jtag3_edbg_prepare()\n",
+ progname);
+
+ if (verbose >= 4)
+ memset(buf, 0, USBDEV_MAX_XFER_3);
+
+ buf[0] = CMSISDAP_CMD_CONNECT;
+ buf[1] = CMSISDAP_CONN_SWD;
+ if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): failed to send command to serial port\n",
+ progname);
+ return -1;
+ }
+ rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
+ if (rv != pgm->fd.usb.max_xfer) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): failed to read from serial port (%d)\n",
+ progname, rv);
+ return -1;
+ }
+ if (status[0] != CMSISDAP_CMD_CONNECT ||
+ status[1] == 0)
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): unexpected response 0x%02x, 0x%02x\n",
+ progname, status[0], status[1]);
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_edbg_prepare(): connection status 0x%02x\n",
+ progname, status[1]);
+
+ buf[0] = CMSISDAP_CMD_LED;
+ buf[1] = CMSISDAP_LED_CONNECT;
+ buf[2] = 1;
+ if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): failed to send command to serial port\n",
+ progname);
+ return -1;
+ }
+ rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
+ if (rv != pgm->fd.usb.max_xfer) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): failed to read from serial port (%d)\n",
+ progname, rv);
+ return -1;
+ }
+ if (status[0] != CMSISDAP_CMD_LED ||
+ status[1] != 0)
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_prepare(): unexpected response 0x%02x, 0x%02x\n",
+ progname, status[0], status[1]);
+
+ return 0;
+}
+
+
+/*
+ * Send out all the CMSIS-DAP stuff when signing off.
+ */
+static int jtag3_edbg_signoff(PROGRAMMER * pgm)
+{
+ unsigned char buf[USBDEV_MAX_XFER_3];
+ unsigned char status[USBDEV_MAX_XFER_3];
+ int rv;
+
+ avrdude_message(MSG_DEBUG, "\n%s: jtag3_edbg_signoff()\n",
+ progname);
+
+ if (verbose >= 4)
+ memset(buf, 0, USBDEV_MAX_XFER_3);
+
+ buf[0] = CMSISDAP_CMD_LED;
+ buf[1] = CMSISDAP_LED_CONNECT;
+ buf[2] = 0;
+ if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
+ progname);
+ return -1;
+ }
+ rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
+ if (rv != pgm->fd.usb.max_xfer) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
+ progname, rv);
+ return -1;
+ }
+ if (status[0] != CMSISDAP_CMD_LED ||
+ status[1] != 0)
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
+ progname, status[0], status[1]);
+
+ buf[0] = CMSISDAP_CMD_DISCONNECT;
+ if (serial_send(&pgm->fd, buf, pgm->fd.usb.max_xfer) != 0) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to send command to serial port\n",
+ progname);
+ return -1;
+ }
+ rv = serial_recv(&pgm->fd, status, pgm->fd.usb.max_xfer);
+ if (rv != pgm->fd.usb.max_xfer) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): failed to read from serial port (%d)\n",
+ progname, rv);
+ return -1;
+ }
+ if (status[0] != CMSISDAP_CMD_DISCONNECT ||
+ status[1] != 0)
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_signoff(): unexpected response 0x%02x, 0x%02x\n",
+ progname, status[0], status[1]);
+
+ return 0;
+}
+
+
+static int jtag3_drain(PROGRAMMER * pgm, int display)
+{
+ return serial_drain(&pgm->fd, display);
+}
+
+
+/*
+ * Receive one frame, return it in *msg. Received sequence number is
+ * returned in seqno. Any valid frame will be returned, regardless
+ * whether it matches the expected sequence number, including event
+ * notification frames (seqno == 0xffff).
+ *
+ * Caller must eventually free the buffer.
+ */
+static int jtag3_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
+ int rv;
+ unsigned char *buf = NULL;
+
+ if (pgm->flag & PGM_FL_IS_EDBG)
+ return jtag3_edbg_recv_frame(pgm, msg);
+
+ avrdude_message(MSG_TRACE, "%s: jtag3_recv():\n", progname);
+
+ if ((buf = malloc(pgm->fd.usb.max_xfer)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtag3_recv(): out of memory\n",
+ progname);
+ return -1;
+ }
+ if (verbose >= 4)
+ memset(buf, 0, pgm->fd.usb.max_xfer);
+
+ rv = serial_recv(&pgm->fd, buf, pgm->fd.usb.max_xfer);
+
+ if (rv < 0) {
+ /* timeout in receive */
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_recv(): Timeout receiving packet\n",
+ progname);
+ free(buf);
+ return -1;
+ }
+
+ *msg = buf;
+
+ return rv;
+}
+
+static int jtag3_edbg_recv_frame(PROGRAMMER * pgm, unsigned char **msg) {
+ int rv, len = 0;
+ unsigned char *buf = NULL;
+ unsigned char *request;
+
+ avrdude_message(MSG_TRACE, "%s: jtag3_edbg_recv():\n", progname);
+
+ if ((buf = malloc(USBDEV_MAX_XFER_3)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): out of memory\n",
+ progname);
+ return -1;
+ }
+ if ((request = malloc(pgm->fd.usb.max_xfer)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): out of memory\n",
+ progname);
+ free(buf);
+ return -1;
+ }
+
+ *msg = buf;
+
+ int nfrags = 0;
+ int thisfrag = 0;
+
+ do {
+ request[0] = EDBG_VENDOR_AVR_RSP;
+
+ if (serial_send(&pgm->fd, request, pgm->fd.usb.max_xfer) != 0) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): error sending CMSIS-DAP vendor command\n",
+ progname);
+ free(request);
+ free(*msg);
+ return -1;
+ }
+
+ rv = serial_recv(&pgm->fd, buf, pgm->fd.usb.max_xfer);
+
+ if (rv < 0) {
+ /* timeout in receive */
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_edbg_recv(): Timeout receiving packet\n",
+ progname);
+ free(*msg);
+ free(request);
+ return -1;
+ }
+
+ if (buf[0] != EDBG_VENDOR_AVR_RSP) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected response 0x%02x\n",
+ progname, buf[0]);
+ free(*msg);
+ free(request);
+ return -1;
+ }
+
+ /* calculate fragment information */
+ if (thisfrag == 0) {
+ /* first fragment */
+ nfrags = buf[1] & 0x0F;
+ thisfrag = 1;
+ } else {
+ if (nfrags != (buf[1] & 0x0F)) {
+ avrdude_message(MSG_INFO,
+ "%s: jtag3_edbg_recv(): "
+ "Inconsistent # of fragments; had %d, now %d\n",
+ progname, nfrags, (buf[1] & 0x0F));
+ free(*msg);
+ free(request);
+ return -1;
+ }
+ }
+ if (thisfrag != ((buf[1] >> 4) & 0x0F)) {
+ avrdude_message(MSG_INFO,
+ "%s: jtag3_edbg_recv(): "
+ "Inconsistent fragment number; expect %d, got %d\n",
+ progname, thisfrag, ((buf[1] >> 4) & 0x0F));
+ free(*msg);
+ free(request);
+ return -1;
+ }
+
+ int thislen = (buf[2] << 8) | buf[3];
+ if (thislen > rv + 4) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Unexpected length value (%d > %d)\n",
+ progname, thislen, rv + 4);
+ thislen = rv + 4;
+ }
+ if (len + thislen > USBDEV_MAX_XFER_3) {
+ avrdude_message(MSG_INFO, "%s: jtag3_edbg_recv(): Length exceeds max size (%d > %d)\n",
+ progname, len + thislen, USBDEV_MAX_XFER_3);
+ thislen = USBDEV_MAX_XFER_3 - len;
+ }
+ memmove(buf, buf + 4, thislen);
+ thisfrag++;
+ len += thislen;
+ buf += thislen;
+ } while (thisfrag <= nfrags);
+
+ free(request);
+ return len;
+}
+
+int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg) {
+ unsigned short r_seqno;
+ int rv;
+
+ for (;;) {
+ if ((rv = jtag3_recv_frame(pgm, msg)) <= 0)
+ return rv;
+
+ if ((rv & USB_RECV_FLAG_EVENT) != 0) {
+ if (verbose >= 3)
+ jtag3_prevent(pgm, *msg, rv & USB_RECV_LENGTH_MASK);
+
+ free(*msg);
+ continue;
+ }
+
+ rv &= USB_RECV_LENGTH_MASK;
+ r_seqno = ((*msg)[2] << 8) | (*msg)[1];
+ avrdude_message(MSG_DEBUG, "%s: jtag3_recv(): "
+ "Got message seqno %d (command_sequence == %d)\n",
+ progname, r_seqno, PDATA(pgm)->command_sequence);
+ if (r_seqno == PDATA(pgm)->command_sequence) {
+ if (++(PDATA(pgm)->command_sequence) == 0xffff)
+ PDATA(pgm)->command_sequence = 0;
+ /*
+ * We move the payload to the beginning of the buffer, to make
+ * the job easier for the caller. We have to return the
+ * original pointer though, as the caller must free() it.
+ */
+ rv -= 3;
+ memmove(*msg, *msg + 3, rv);
+
+ return rv;
+ }
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_recv(): "
+ "got wrong sequence number, %u != %u\n",
+ progname, r_seqno, PDATA(pgm)->command_sequence);
+
+ free(*msg);
+ }
+}
+
+ int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
+ unsigned char **resp, const char *descr)
+{
+ int status;
+ unsigned char c;
+
+ avrdude_message(MSG_NOTICE2, "%s: Sending %s command: ",
+ progname, descr);
+ jtag3_send(pgm, cmd, cmdlen);
+
+ status = jtag3_recv(pgm, resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_NOTICE2, "%s: %s command: timeout/error communicating with programmer (status %d)\n",
+ progname, descr, status);
+ return -1;
+ } else if (verbose >= 3) {
+ putc('\n', stderr);
+ jtag3_prmsg(pgm, *resp, status);
+ } else {
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", (*resp)[1], status);
+ }
+
+ c = (*resp)[1];
+ if ((c & RSP3_STATUS_MASK) != RSP3_OK) {
+ avrdude_message(MSG_INFO, "%s: bad response to %s command: 0x%02x\n",
+ progname, descr, c);
+ free(*resp);
+ resp = 0;
+ return -1;
+ }
+
+ return status;
+}
+
+
+int jtag3_getsync(PROGRAMMER * pgm, int mode) {
+
+ unsigned char buf[3], *resp;
+
+ avrdude_message(MSG_DEBUG, "%s: jtag3_getsync()\n", progname);
+
+ if (pgm->flag & PGM_FL_IS_EDBG) {
+ if (jtag3_edbg_prepare(pgm) < 0)
+ return -1;
+ }
+
+ /* Get the sign-on information. */
+ buf[0] = SCOPE_GENERAL;
+ buf[1] = CMD3_SIGN_ON;
+ buf[2] = 0;
+
+ if (jtag3_command(pgm, buf, 3, &resp, "sign-on") < 0)
+ return -1;
+
+ free(resp);
+
+ return 0;
+}
+
+/*
+ * issue the 'chip erase' command to the AVR device
+ */
+static int jtag3_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char buf[8], *resp;
+
+ buf[0] = SCOPE_AVR;
+ buf[1] = CMD3_ERASE_MEMORY;
+ buf[2] = 0;
+ buf[3] = XMEGA_ERASE_CHIP;
+ buf[4] = buf[5] = buf[6] = buf[7] = 0; /* page address */
+
+ if (jtag3_command(pgm, buf, 8, &resp, "chip erase") < 0)
+ return -1;
+
+ free(resp);
+ return 0;
+}
+
+/*
+ * There is no chip erase functionality in debugWire mode.
+ */
+static int jtag3_chip_erase_dw(PROGRAMMER * pgm, AVRPART * p)
+{
+
+ avrdude_message(MSG_INFO, "%s: Chip erase not supported in debugWire mode\n",
+ progname);
+
+ return 0;
+}
+
+static int jtag3_program_enable_dummy(PROGRAMMER * pgm, AVRPART * p)
+{
+ return 0;
+}
+
+static int jtag3_program_enable(PROGRAMMER * pgm)
+{
+ unsigned char buf[3], *resp;
+
+ if (PDATA(pgm)->prog_enabled)
+ return 0;
+
+ buf[0] = SCOPE_AVR;
+ buf[1] = CMD3_ENTER_PROGMODE;
+ buf[2] = 0;
+
+ if (jtag3_command(pgm, buf, 3, &resp, "enter progmode") >= 0) {
+ free(resp);
+ PDATA(pgm)->prog_enabled = 1;
+
+ return 0;
+ }
+
+ return -1;
+}
+
+static int jtag3_program_disable(PROGRAMMER * pgm)
+{
+ unsigned char buf[3], *resp;
+
+ if (!PDATA(pgm)->prog_enabled)
+ return 0;
+
+ buf[0] = SCOPE_AVR;
+ buf[1] = CMD3_LEAVE_PROGMODE;
+ buf[2] = 0;
+
+ if (jtag3_command(pgm, buf, 3, &resp, "leave progmode") < 0)
+ return -1;
+
+ free(resp);
+
+ PDATA(pgm)->prog_enabled = 0;
+
+ return 0;
+}
+
+static int jtag3_set_sck_xmega_pdi(PROGRAMMER *pgm, unsigned char *clk)
+{
+ return jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, clk, 2);
+}
+
+static int jtag3_set_sck_xmega_jtag(PROGRAMMER *pgm, unsigned char *clk)
+{
+ return jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, clk, 2);
+}
+
+static int jtag3_set_sck_mega_jtag(PROGRAMMER *pgm, unsigned char *clk)
+{
+ return jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, clk, 2);
+}
+
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char conn = 0, parm[4];
+ const char *ifname;
+ unsigned char cmd[4], *resp;
+ int status;
+
+ /*
+ * At least, as of firmware 2.12, the JTAGICE3 doesn't handle
+ * splitting packets correctly. On a large transfer, the first
+ * split packets are correct, but remaining packets contain just
+ * garbage.
+ *
+ * We move the check here so in case future firmware versions fix
+ * this, the check below can be made dependended on the actual
+ * firmware level. Retrieving the firmware version can always be
+ * accomplished with USB 1.1 (64 byte max) packets.
+ *
+ * Allow to override the check by -F (so users could try on newer
+ * firmware), but warn loudly.
+ */
+ if (jtag3_getparm(pgm, SCOPE_GENERAL, 0, PARM3_FW_MAJOR, parm, 2) < 0)
+ return -1;
+ if (pgm->fd.usb.max_xfer < USBDEV_MAX_XFER_3 && (pgm->flag & PGM_FL_IS_EDBG) == 0) {
+ avrdude_message(MSG_INFO, "%s: the JTAGICE3's firmware %d.%d is broken on USB 1.1 connections, sorry\n",
+ progname, parm[0], parm[1]);
+ if (ovsigck) {
+ avrdude_message(MSG_INFO, "%s: forced to continue by option -F; THIS PUTS THE DEVICE'S DATA INTEGRITY AT RISK!\n",
+ progname);
+ } else {
+ return -1;
+ }
+ }
+
+ if (pgm->flag & PGM_FL_IS_DW) {
+ ifname = "debugWire";
+ if (p->flags & AVRPART_HAS_DW)
+ conn = PARM3_CONN_DW;
+ } else if (pgm->flag & PGM_FL_IS_PDI) {
+ ifname = "PDI";
+ if (p->flags & AVRPART_HAS_PDI)
+ conn = PARM3_CONN_PDI;
+ } else {
+ ifname = "JTAG";
+ if (p->flags & AVRPART_HAS_JTAG)
+ conn = PARM3_CONN_JTAG;
+ }
+
+ if (conn == 0) {
+ avrdude_message(MSG_INFO, "%s: jtag3_initialize(): part %s has no %s interface\n",
+ progname, p->desc, ifname);
+ return -1;
+ }
+
+ if (p->flags & AVRPART_HAS_PDI)
+ parm[0] = PARM3_ARCH_XMEGA;
+ else if (p->flags & AVRPART_HAS_DW)
+ parm[0] = PARM3_ARCH_TINY;
+ else
+ parm[0] = PARM3_ARCH_MEGA;
+ if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, parm, 1) < 0)
+ return -1;
+
+ parm[0] = PARM3_SESS_PROGRAMMING;
+ if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_SESS_PURPOSE, parm, 1) < 0)
+ return -1;
+
+ parm[0] = conn;
+ if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0)
+ return -1;
+
+ if (conn == PARM3_CONN_PDI)
+ PDATA(pgm)->set_sck = jtag3_set_sck_xmega_pdi;
+ else if (conn == PARM3_CONN_JTAG) {
+ if (p->flags & AVRPART_HAS_PDI)
+ PDATA(pgm)->set_sck = jtag3_set_sck_xmega_jtag;
+ else
+ PDATA(pgm)->set_sck = jtag3_set_sck_mega_jtag;
+ }
+ if (pgm->bitclock != 0.0 && PDATA(pgm)->set_sck != NULL)
+ {
+ unsigned int clock = 1E-3 / pgm->bitclock; /* kHz */
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_initialize(): "
+ "trying to set JTAG clock to %u kHz\n",
+ progname, clock);
+ parm[0] = clock & 0xff;
+ parm[1] = (clock >> 8) & 0xff;
+ if (PDATA(pgm)->set_sck(pgm, parm) < 0)
+ return -1;
+ }
+
+ if (conn == PARM3_CONN_JTAG)
+ {
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_initialize(): "
+ "trying to set JTAG daisy-chain info to %d,%d,%d,%d\n",
+ progname,
+ PDATA(pgm)->jtagchain[0], PDATA(pgm)->jtagchain[1],
+ PDATA(pgm)->jtagchain[2], PDATA(pgm)->jtagchain[3]);
+ if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_JTAGCHAIN, PDATA(pgm)->jtagchain, 4) < 0)
+ return -1;
+ }
+
+ /* set device descriptor data */
+ if ((p->flags & AVRPART_HAS_PDI))
+ {
+ struct xmega_device_desc xd;
+ LNODEID ln;
+ AVRMEM * m;
+
+ u16_to_b2(xd.nvm_base_addr, p->nvm_base);
+ u16_to_b2(xd.mcu_base_addr, p->mcu_base);
+
+ for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
+ m = ldata(ln);
+ if (strcmp(m->desc, "flash") == 0) {
+ if (m->readsize != 0 && m->readsize < m->page_size)
+ PDATA(pgm)->flash_pagesize = m->readsize;
+ else
+ PDATA(pgm)->flash_pagesize = m->page_size;
+ u16_to_b2(xd.flash_page_size, m->page_size);
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ PDATA(pgm)->eeprom_pagesize = m->page_size;
+ xd.eeprom_page_size = m->page_size;
+ u16_to_b2(xd.eeprom_size, m->size);
+ u32_to_b4(xd.nvm_eeprom_offset, m->offset);
+ } else if (strcmp(m->desc, "application") == 0) {
+ u32_to_b4(xd.app_size, m->size);
+ u32_to_b4(xd.nvm_app_offset, m->offset);
+ } else if (strcmp(m->desc, "boot") == 0) {
+ u16_to_b2(xd.boot_size, m->size);
+ u32_to_b4(xd.nvm_boot_offset, m->offset);
+ } else if (strcmp(m->desc, "fuse1") == 0) {
+ u32_to_b4(xd.nvm_fuse_offset, m->offset & ~7);
+ } else if (strncmp(m->desc, "lock", 4) == 0) {
+ u32_to_b4(xd.nvm_lock_offset, m->offset);
+ } else if (strcmp(m->desc, "usersig") == 0) {
+ u32_to_b4(xd.nvm_user_sig_offset, m->offset);
+ } else if (strcmp(m->desc, "prodsig") == 0) {
+ u32_to_b4(xd.nvm_prod_sig_offset, m->offset);
+ } else if (strcmp(m->desc, "data") == 0) {
+ u32_to_b4(xd.nvm_data_offset, m->offset);
+ }
+ }
+
+ if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&xd, sizeof xd) < 0)
+ return -1;
+ }
+ else
+ {
+ struct mega_device_desc md;
+ LNODEID ln;
+ AVRMEM * m;
+ unsigned int flashsize = 0;
+
+ memset(&md, 0, sizeof md);
+
+ for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
+ m = ldata(ln);
+ if (strcmp(m->desc, "flash") == 0) {
+ if (m->readsize != 0 && m->readsize < m->page_size)
+ PDATA(pgm)->flash_pagesize = m->readsize;
+ else
+ PDATA(pgm)->flash_pagesize = m->page_size;
+ u16_to_b2(md.flash_page_size, m->page_size);
+ u32_to_b4(md.flash_size, (flashsize = m->size));
+ // do we need it? just a wild guess
+ u32_to_b4(md.boot_address, (m->size - m->page_size * 4) / 2);
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ PDATA(pgm)->eeprom_pagesize = m->page_size;
+ md.eeprom_page_size = m->page_size;
+ u16_to_b2(md.eeprom_size, m->size);
+ }
+ }
+
+ //md.sram_offset[2] = p->sram; // do we need it?
+ if (p->ocdrev == -1) {
+ int ocdrev;
+
+ /* lacking a proper definition, guess the OCD revision */
+ if (p->flags & AVRPART_HAS_DW)
+ ocdrev = 1; /* exception: ATtiny13, 2313, 4313 */
+ else if (flashsize > 128 * 1024)
+ ocdrev = 4;
+ else
+ ocdrev = 3; /* many exceptions from that, actually */
+ avrdude_message(MSG_INFO, "%s: part definition for %s lacks \"ocdrev\"; guessing %d\n",
+ progname, p->desc, ocdrev);
+ md.ocd_revision = ocdrev;
+ } else {
+ md.ocd_revision = p->ocdrev;
+ }
+ md.always_one = 1;
+ md.allow_full_page_bitstream = (p->flags & AVRPART_ALLOWFULLPAGEBITSTREAM) != 0;
+ md.idr_address = p->idr;
+
+ if (p->eecr == 0)
+ p->eecr = 0x3f; /* matches most "modern" mega/tiny AVRs */
+ md.eearh_address = p->eecr - 0x20 + 3;
+ md.eearl_address = p->eecr - 0x20 + 2;
+ md.eecr_address = p->eecr - 0x20;
+ md.eedr_address = p->eecr - 0x20 + 1;
+ md.spmcr_address = p->spmcr;
+ //md.osccal_address = p->osccal; // do we need it at all?
+
+ if (jtag3_setparm(pgm, SCOPE_AVR, 2, PARM3_DEVICEDESC, (unsigned char *)&md, sizeof md) < 0)
+ return -1;
+ }
+
+ int use_ext_reset;
+
+ for (use_ext_reset = 0; use_ext_reset <= 1; use_ext_reset++) {
+ cmd[0] = SCOPE_AVR;
+ cmd[1] = CMD3_SIGN_ON;
+ cmd[2] = 0;
+ cmd[3] = use_ext_reset; /* external reset */
+
+ if ((status = jtag3_command(pgm, cmd, 4, &resp, "AVR sign-on")) >= 0)
+ break;
+
+ avrdude_message(MSG_INFO, "%s: retrying with external reset applied\n",
+ progname);
+ }
+
+ if (use_ext_reset > 1) {
+ avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname);
+ return -1;
+ }
+
+ /*
+ * Depending on the target connection, there are two different
+ * possible replies of the ICE. For a JTAG connection, the reply
+ * format is RSP3_DATA, followed by 4 bytes of the JTAG ID read from
+ * the device (followed by a trailing 0). For all other connections
+ * (except ISP which is handled completely differently, but that
+ * doesn't apply here anyway), the response is just RSP_OK.
+ */
+ if (resp[1] == RSP3_DATA && status >= 7)
+ /* JTAG ID has been returned */
+ avrdude_message(MSG_NOTICE, "%s: JTAG ID returned: 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ progname, resp[3], resp[4], resp[5], resp[6]);
+
+ free(resp);
+
+ PDATA(pgm)->boot_start = ULONG_MAX;
+ if ((p->flags & AVRPART_HAS_PDI)) {
+ /*
+ * Find out where the border between application and boot area
+ * is.
+ */
+ AVRMEM *bootmem = avr_locate_mem(p, "boot");
+ AVRMEM *flashmem = avr_locate_mem(p, "flash");
+ if (bootmem == NULL || flashmem == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmk3_initialize(): Cannot locate \"flash\" and \"boot\" memories in description\n",
+ progname);
+ } else {
+ PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset;
+ }
+ }
+
+ free(PDATA(pgm)->flash_pagecache);
+ free(PDATA(pgm)->eeprom_pagecache);
+ if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtag3_initialize(): Out of memory\n",
+ progname);
+ return -1;
+ }
+ if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtag3_initialize(): Out of memory\n",
+ progname);
+ free(PDATA(pgm)->flash_pagecache);
+ return -1;
+ }
+ PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+
+ return 0;
+}
+
+static void jtag3_disable(PROGRAMMER * pgm)
+{
+
+ free(PDATA(pgm)->flash_pagecache);
+ PDATA(pgm)->flash_pagecache = NULL;
+ free(PDATA(pgm)->eeprom_pagecache);
+ PDATA(pgm)->eeprom_pagecache = NULL;
+
+ /*
+ * jtag3_program_disable() doesn't do anything if the
+ * device is currently not in programming mode, so just
+ * call it unconditionally here.
+ */
+ (void)jtag3_program_disable(pgm);
+}
+
+static void jtag3_enable(PROGRAMMER * pgm)
+{
+ return;
+}
+
+static int jtag3_parseextparms(PROGRAMMER * pgm, LISTID extparms)
+{
+ LNODEID ln;
+ const char *extended_param;
+ int rv = 0;
+
+ for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
+ extended_param = ldata(ln);
+
+ if (strncmp(extended_param, "jtagchain=", strlen("jtagchain=")) == 0) {
+ unsigned int ub, ua, bb, ba;
+ if (sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba)
+ != 4) {
+ avrdude_message(MSG_INFO, "%s: jtag3_parseextparms(): invalid JTAG chain '%s'\n",
+ progname, extended_param);
+ rv = -1;
+ continue;
+ }
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_parseextparms(): JTAG chain parsed as:\n"
+ "%s %u units before, %u units after, %u bits before, %u bits after\n",
+ progname,
+ progbuf, ub, ua, bb, ba);
+ PDATA(pgm)->jtagchain[0] = ub;
+ PDATA(pgm)->jtagchain[1] = ua;
+ PDATA(pgm)->jtagchain[2] = bb;
+ PDATA(pgm)->jtagchain[3] = ba;
+
+ continue;
+ }
+
+ avrdude_message(MSG_INFO, "%s: jtag3_parseextparms(): invalid extended parameter '%s'\n",
+ progname, extended_param);
+ rv = -1;
+ }
+
+ return rv;
+}
+
+int jtag3_open_common(PROGRAMMER * pgm, char * port)
+{
+ union pinfo pinfo;
+ LNODEID usbpid;
+ int rv = -1;
+
+#if !defined(HAVE_LIBUSB) && !defined(HAVE_LIBHIDAPI)
+ avrdude_message(MSG_INFO, "avrdude was compiled without USB or HIDAPI support.\n");
+ return -1;
+#endif
+
+ if (strncmp(port, "usb", 3) != 0) {
+ avrdude_message(MSG_INFO, "%s: jtag3_open_common(): JTAGICE3/EDBG port names must start with \"usb\"\n",
+ progname);
+ return -1;
+ }
+
+ if (pgm->usbvid)
+ pinfo.usbinfo.vid = pgm->usbvid;
+ else
+ pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+
+ /* If the config entry did not specify a USB PID, insert the default one. */
+ if (lfirst(pgm->usbpid) == NULL)
+ ladd(pgm->usbpid, (void *)USB_DEVICE_JTAGICE3);
+
+#if defined(HAVE_LIBHIDAPI)
+ /*
+ * Try HIDAPI first. LibUSB is more generic, but might then cause
+ * troubles for HID-class devices in some OSes (like Windows).
+ */
+ serdev = &usbhid_serdev;
+ for (usbpid = lfirst(pgm->usbpid); rv < 0 && usbpid != NULL; usbpid = lnext(usbpid)) {
+ pinfo.usbinfo.flags = PINFO_FL_SILENT;
+ pinfo.usbinfo.pid = *(int *)(ldata(usbpid));
+ pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3;
+ pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3;
+ pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3;
+ pgm->fd.usb.eep = 0;
+
+ strcpy(pgm->port, port);
+ rv = serial_open(port, pinfo, &pgm->fd);
+ }
+ if (rv < 0) {
+#endif /* HAVE_LIBHIDAPI */
+#if defined(HAVE_LIBUSB)
+ serdev = &usb_serdev_frame;
+ for (usbpid = lfirst(pgm->usbpid); rv < 0 && usbpid != NULL; usbpid = lnext(usbpid)) {
+ pinfo.usbinfo.flags = PINFO_FL_SILENT;
+ pinfo.usbinfo.pid = *(int *)(ldata(usbpid));
+ pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_3;
+ pgm->fd.usb.rep = USBDEV_BULK_EP_READ_3;
+ pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_3;
+ pgm->fd.usb.eep = USBDEV_EVT_EP_READ_3;
+
+ strcpy(pgm->port, port);
+ rv = serial_open(port, pinfo, &pgm->fd);
+ }
+#endif /* HAVE_LIBUSB */
+#if defined(HAVE_LIBHIDAPI)
+ }
+#endif
+ if (rv < 0) {
+ avrdude_message(MSG_INFO, "%s: jtag3_open_common(): Did not find any device matching VID 0x%04x and PID list: ",
+ progname, (unsigned)pinfo.usbinfo.vid);
+ int notfirst = 0;
+ for (usbpid = lfirst(pgm->usbpid); usbpid != NULL; usbpid = lnext(usbpid)) {
+ if (notfirst)
+ avrdude_message(MSG_INFO, ", ");
+ avrdude_message(MSG_INFO, "0x%04x", (unsigned int)(*(int *)(ldata(usbpid))));
+ notfirst = 1;
+ }
+ fputc('\n', stderr);
+
+ return -1;
+ }
+
+ if (pgm->fd.usb.eep == 0)
+ {
+ /* The event EP has been deleted by usb_open(), so we are
+ running on a CMSIS-DAP device, using EDBG protocol */
+ pgm->flag |= PGM_FL_IS_EDBG;
+ avrdude_message(MSG_NOTICE, "%s: Found CMSIS-DAP compliant device, using EDBG protocol\n",
+ progname);
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ jtag3_drain(pgm, 0);
+
+ return 0;
+}
+
+
+
+static int jtag3_open(PROGRAMMER * pgm, char * port)
+{
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_open()\n", progname);
+
+ if (jtag3_open_common(pgm, port) < 0)
+ return -1;
+
+ if (jtag3_getsync(pgm, PARM3_CONN_JTAG) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int jtag3_open_dw(PROGRAMMER * pgm, char * port)
+{
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_open_dw()\n", progname);
+
+ if (jtag3_open_common(pgm, port) < 0)
+ return -1;
+
+ if (jtag3_getsync(pgm, PARM3_CONN_DW) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int jtag3_open_pdi(PROGRAMMER * pgm, char * port)
+{
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_open_pdi()\n", progname);
+
+ if (jtag3_open_common(pgm, port) < 0)
+ return -1;
+
+ if (jtag3_getsync(pgm, PARM3_CONN_PDI) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+void jtag3_close(PROGRAMMER * pgm)
+{
+ unsigned char buf[4], *resp;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_close()\n", progname);
+
+ buf[0] = SCOPE_AVR;
+ buf[1] = CMD3_SIGN_OFF;
+ buf[2] = buf[3] = 0;
+
+ if (jtag3_command(pgm, buf, 3, &resp, "AVR sign-off") >= 0)
+ free(resp);
+
+ buf[0] = SCOPE_GENERAL;
+ buf[1] = CMD3_SIGN_OFF;
+
+ if (jtag3_command(pgm, buf, 4, &resp, "sign-off") >= 0)
+ free(resp);
+
+ if (pgm->flag & PGM_FL_IS_EDBG)
+ jtag3_edbg_signoff(pgm);
+
+ serial_close(&pgm->fd);
+ pgm->fd.ifd = -1;
+}
+
+static int jtag3_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int addr)
+{
+ unsigned char cmd[8], *resp;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_page_erase(.., %s, 0x%x)\n",
+ progname, m->desc, addr);
+
+ if (!(p->flags & AVRPART_HAS_PDI)) {
+ avrdude_message(MSG_INFO, "%s: jtag3_page_erase: not an Xmega device\n",
+ progname);
+ return -1;
+ }
+
+ if (jtag3_program_enable(pgm) < 0)
+ return -1;
+
+ cmd[0] = SCOPE_AVR;
+ cmd[1] = CMD3_ERASE_MEMORY;
+ cmd[2] = 0;
+
+ if (strcmp(m->desc, "flash") == 0) {
+ if (jtag3_memtype(pgm, p, addr) == MTYPE_FLASH)
+ cmd[3] = XMEGA_ERASE_APP_PAGE;
+ else
+ cmd[3] = XMEGA_ERASE_BOOT_PAGE;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ cmd[3] = XMEGA_ERASE_EEPROM_PAGE;
+ } else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
+ cmd[3] = XMEGA_ERASE_USERSIG;
+ } else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
+ cmd[3] = XMEGA_ERASE_BOOT_PAGE;
+ } else {
+ cmd[3] = XMEGA_ERASE_APP_PAGE;
+ }
+
+ u32_to_b4(cmd + 4, addr + m->offset);
+
+ if (jtag3_command(pgm, cmd, 8, &resp, "page erase") < 0)
+ return -1;
+
+ free(resp);
+ return 0;
+}
+
+static int jtag3_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned int block_size;
+ unsigned int maxaddr = addr + n_bytes;
+ unsigned char *cmd;
+ unsigned char *resp;
+ int status, dynamic_memtype = 0;
+ long otimeout = serial_recv_timeout;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_paged_write(.., %s, %d, %d)\n",
+ progname, m->desc, page_size, n_bytes);
+
+ if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0)
+ return -1;
+
+ if (page_size == 0) page_size = 256;
+
+ if ((cmd = malloc(page_size + 13)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtag3_paged_write(): Out of memory\n",
+ progname);
+ return -1;
+ }
+
+ cmd[0] = SCOPE_AVR;
+ cmd[1] = CMD3_WRITE_MEMORY;
+ cmd[2] = 0;
+ if (strcmp(m->desc, "flash") == 0) {
+ PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
+ cmd[3] = jtag3_memtype(pgm, p, addr);
+ if (p->flags & AVRPART_HAS_PDI)
+ /* dynamically decide between flash/boot memtype */
+ dynamic_memtype = 1;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ if (pgm->flag & PGM_FL_IS_DW) {
+ /*
+ * jtag3_paged_write() to EEPROM attempted while in
+ * DW mode. Use jtag3_write_byte() instead.
+ */
+ for (; addr < maxaddr; addr++) {
+ status = jtag3_write_byte(pgm, p, m, addr, m->buf[addr]);
+ if (status < 0) {
+ free(cmd);
+ return -1;
+ }
+ }
+ free(cmd);
+ return n_bytes;
+ }
+ cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM_XMEGA : MTYPE_EEPROM_PAGE;
+ PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+ } else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
+ cmd[3] = MTYPE_USERSIG;
+ } else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
+ cmd[3] = MTYPE_BOOT_FLASH;
+ } else if ( p->flags & AVRPART_HAS_PDI ) {
+ cmd[3] = MTYPE_FLASH;
+ } else {
+ cmd[3] = MTYPE_SPM;
+ }
+ serial_recv_timeout = 100;
+ for (; addr < maxaddr; addr += page_size) {
+ if ((maxaddr - addr) < page_size)
+ block_size = maxaddr - addr;
+ else
+ block_size = page_size;
+ avrdude_message(MSG_DEBUG, "%s: jtag3_paged_write(): "
+ "block_size at addr %d is %d\n",
+ progname, addr, block_size);
+
+ if (dynamic_memtype)
+ cmd[3] = jtag3_memtype(pgm, p, addr);
+
+ u32_to_b4(cmd + 8, page_size);
+ u32_to_b4(cmd + 4, jtag3_memaddr(pgm, p, m, addr));
+ cmd[12] = 0;
+
+ /*
+ * The JTAG ICE will refuse to write anything but a full page, at
+ * least for the flash ROM. If a partial page has been requested,
+ * set the remainder to 0xff. (Maybe we should rather read back
+ * the existing contents instead before? Doesn't matter much, as
+ * bits cannot be written to 1 anyway.)
+ */
+ memset(cmd + 13, 0xff, page_size);
+ memcpy(cmd + 13, m->buf + addr, block_size);
+
+ if ((status = jtag3_command(pgm, cmd, page_size + 13,
+ &resp, "write memory")) < 0) {
+ free(cmd);
+ serial_recv_timeout = otimeout;
+ return -1;
+ }
+
+ free(resp);
+ }
+
+ free(cmd);
+ serial_recv_timeout = otimeout;
+
+ return n_bytes;
+}
+
+static int jtag3_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned int block_size;
+ unsigned int maxaddr = addr + n_bytes;
+ unsigned char cmd[12];
+ unsigned char *resp;
+ int status, dynamic_memtype = 0;
+ long otimeout = serial_recv_timeout;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_paged_load(.., %s, %d, %d)\n",
+ progname, m->desc, page_size, n_bytes);
+
+ if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0)
+ return -1;
+
+ page_size = m->readsize;
+
+ cmd[0] = SCOPE_AVR;
+ cmd[1] = CMD3_READ_MEMORY;
+ cmd[2] = 0;
+
+ if (strcmp(m->desc, "flash") == 0) {
+ cmd[3] = jtag3_memtype(pgm, p, addr);
+ if (p->flags & AVRPART_HAS_PDI)
+ /* dynamically decide between flash/boot memtype */
+ dynamic_memtype = 1;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
+ if (pgm->flag & PGM_FL_IS_DW)
+ return -1;
+ } else if ( ( strcmp(m->desc, "prodsig") == 0 ) ) {
+ cmd[3] = MTYPE_PRODSIG;
+ } else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
+ cmd[3] = MTYPE_USERSIG;
+ } else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
+ cmd[3] = MTYPE_BOOT_FLASH;
+ } else if ( p->flags & AVRPART_HAS_PDI ) {
+ cmd[3] = MTYPE_FLASH;
+ } else {
+ cmd[3] = MTYPE_SPM;
+ }
+ serial_recv_timeout = 100;
+ for (; addr < maxaddr; addr += page_size) {
+ if ((maxaddr - addr) < page_size)
+ block_size = maxaddr - addr;
+ else
+ block_size = page_size;
+ avrdude_message(MSG_DEBUG, "%s: jtag3_paged_load(): "
+ "block_size at addr %d is %d\n",
+ progname, addr, block_size);
+
+ if (dynamic_memtype)
+ cmd[3] = jtag3_memtype(pgm, p, addr);
+
+ u32_to_b4(cmd + 8, block_size);
+ u32_to_b4(cmd + 4, jtag3_memaddr(pgm, p, m, addr));
+
+ if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0)
+ return -1;
+
+ if (resp[1] != RSP3_DATA ||
+ status < block_size + 4) {
+ avrdude_message(MSG_INFO, "%s: wrong/short reply to read memory command\n",
+ progname);
+ serial_recv_timeout = otimeout;
+ free(resp);
+ return -1;
+ }
+ memcpy(m->buf + addr, resp + 3, status - 4);
+ free(resp);
+ }
+ serial_recv_timeout = otimeout;
+
+ return n_bytes;
+}
+
+static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value)
+{
+ unsigned char cmd[12];
+ unsigned char *resp, *cache_ptr = NULL;
+ int status, unsupp = 0;
+ unsigned long paddr = 0UL, *paddr_ptr = NULL;
+ unsigned int pagesize = 0;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_read_byte(.., %s, 0x%lx, ...)\n",
+ progname, mem->desc, addr);
+
+ if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0)
+ return -1;
+
+ cmd[0] = SCOPE_AVR;
+ cmd[1] = CMD3_READ_MEMORY;
+ cmd[2] = 0;
+
+ cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE;
+ if (strcmp(mem->desc, "flash") == 0 ||
+ strcmp(mem->desc, "application") == 0 ||
+ strcmp(mem->desc, "apptable") == 0 ||
+ strcmp(mem->desc, "boot") == 0) {
+ addr += mem->offset & (512 * 1024 - 1); /* max 512 KiB flash */
+ pagesize = PDATA(pgm)->flash_pagesize;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->flash_pageaddr;
+ cache_ptr = PDATA(pgm)->flash_pagecache;
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ if ( (pgm->flag & PGM_FL_IS_DW) || ( p->flags & AVRPART_HAS_PDI ) ) {
+ cmd[3] = MTYPE_EEPROM;
+ } else {
+ cmd[3] = MTYPE_EEPROM_PAGE;
+ }
+ pagesize = mem->page_size;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
+ cache_ptr = PDATA(pgm)->eeprom_pagecache;
+ } else if (strcmp(mem->desc, "lfuse") == 0) {
+ cmd[3] = MTYPE_FUSE_BITS;
+ addr = 0;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "hfuse") == 0) {
+ cmd[3] = MTYPE_FUSE_BITS;
+ addr = 1;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "efuse") == 0) {
+ cmd[3] = MTYPE_FUSE_BITS;
+ addr = 2;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strncmp(mem->desc, "lock", 4) == 0) {
+ cmd[3] = MTYPE_LOCK_BITS;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
+ cmd[3] = MTYPE_FUSE_BITS;
+ addr = mem->offset & 7;
+ } else if (strcmp(mem->desc, "usersig") == 0) {
+ cmd[3] = MTYPE_USERSIG;
+ } else if (strcmp(mem->desc, "prodsig") == 0) {
+ cmd[3] = MTYPE_PRODSIG;
+ } else if (strcmp(mem->desc, "calibration") == 0) {
+ cmd[3] = MTYPE_OSCCAL_BYTE;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "signature") == 0) {
+ static unsigned char signature_cache[2];
+
+ cmd[3] = MTYPE_SIGN_JTAG;
+
+ /*
+ * dW can read out the signature on JTAGICE3, but only allows
+ * for a full three-byte read. We cache them in a local
+ * variable to avoid multiple reads. This optimization does not
+ * harm for other connection types either.
+ */
+ u32_to_b4(cmd + 8, 3);
+ u32_to_b4(cmd + 4, 0);
+
+ if (addr == 0) {
+ if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0)
+ return -1;
+
+ signature_cache[0] = resp[4];
+ signature_cache[1] = resp[5];
+ *value = resp[3];
+ free(resp);
+ return 0;
+ } else if (addr <= 2) {
+ *value = signature_cache[addr - 1];
+ return 0;
+ } else {
+ /* should not happen */
+ avrdude_message(MSG_INFO, "address out of range for signature memory: %lu\n", addr);
+ return -1;
+ }
+ }
+
+ /*
+ * If the respective memory area is not supported under debugWire,
+ * leave here.
+ */
+ if (unsupp) {
+ *value = 42;
+ return -1;
+ }
+
+ /*
+ * To improve the read speed, we used paged reads for flash and
+ * EEPROM, and cache the results in a page cache.
+ *
+ * Page cache validation is based on "{flash,eeprom}_pageaddr"
+ * (holding the base address of the most recent cache fill
+ * operation). This variable is set to (unsigned long)-1L when the
+ * cache needs to be invalidated.
+ */
+ if (pagesize && paddr == *paddr_ptr) {
+ *value = cache_ptr[addr & (pagesize - 1)];
+ return 0;
+ }
+
+ if (pagesize) {
+ u32_to_b4(cmd + 8, pagesize);
+ u32_to_b4(cmd + 4, paddr);
+ } else {
+ u32_to_b4(cmd + 8, 1);
+ u32_to_b4(cmd + 4, addr);
+ }
+
+ if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0)
+ return -1;
+
+ if (resp[1] != RSP3_DATA ||
+ status < (pagesize? pagesize: 1) + 4) {
+ avrdude_message(MSG_INFO, "%s: wrong/short reply to read memory command\n",
+ progname);
+ free(resp);
+ return -1;
+ }
+
+ if (pagesize) {
+ *paddr_ptr = paddr;
+ memcpy(cache_ptr, resp + 3, pagesize);
+ *value = cache_ptr[addr & (pagesize - 1)];
+ } else
+ *value = resp[3];
+
+ free(resp);
+ return 0;
+}
+
+static int jtag3_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data)
+{
+ unsigned char cmd[14];
+ unsigned char *resp;
+ unsigned char *cache_ptr = 0;
+ int status, unsupp = 0;
+ unsigned int pagesize = 0;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_write_byte(.., %s, 0x%lx, ...)\n",
+ progname, mem->desc, addr);
+
+ cmd[0] = SCOPE_AVR;
+ cmd[1] = CMD3_WRITE_MEMORY;
+ cmd[2] = 0;
+ cmd[3] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_SPM;
+ if (strcmp(mem->desc, "flash") == 0) {
+ cache_ptr = PDATA(pgm)->flash_pagecache;
+ pagesize = PDATA(pgm)->flash_pagesize;
+ PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ if (pgm->flag & PGM_FL_IS_DW) {
+ cmd[3] = MTYPE_EEPROM;
+ } else {
+ cache_ptr = PDATA(pgm)->eeprom_pagecache;
+ pagesize = PDATA(pgm)->eeprom_pagesize;
+ }
+ PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+ } else if (strcmp(mem->desc, "lfuse") == 0) {
+ cmd[3] = MTYPE_FUSE_BITS;
+ addr = 0;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "hfuse") == 0) {
+ cmd[3] = MTYPE_FUSE_BITS;
+ addr = 1;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "efuse") == 0) {
+ cmd[3] = MTYPE_FUSE_BITS;
+ addr = 2;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
+ cmd[3] = MTYPE_FUSE_BITS;
+ addr = mem->offset & 7;
+ } else if (strcmp(mem->desc, "usersig") == 0) {
+ cmd[3] = MTYPE_USERSIG;
+ } else if (strcmp(mem->desc, "prodsig") == 0) {
+ cmd[3] = MTYPE_PRODSIG;
+ } else if (strncmp(mem->desc, "lock", 4) == 0) {
+ cmd[3] = MTYPE_LOCK_BITS;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "calibration") == 0) {
+ cmd[3] = MTYPE_OSCCAL_BYTE;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "signature") == 0) {
+ cmd[3] = MTYPE_SIGN_JTAG;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ }
+
+ if (unsupp)
+ return -1;
+
+ if (pagesize != 0) {
+ /* flash or EEPROM write: use paged algorithm */
+ unsigned char dummy;
+ int i;
+
+ /* step #1: ensure the page cache is up to date */
+ if (jtag3_read_byte(pgm, p, mem, addr, &dummy) < 0)
+ return -1;
+ /* step #2: update our value in page cache, and copy
+ * cache to mem->buf */
+ cache_ptr[addr & (pagesize - 1)] = data;
+ addr &= ~(pagesize - 1); /* page base address */
+ memcpy(mem->buf + addr, cache_ptr, pagesize);
+ /* step #3: write back */
+ i = jtag3_paged_write(pgm, p, mem, pagesize, addr, pagesize);
+ if (i < 0)
+ return -1;
+ else
+ return 0;
+ }
+
+ /* non-paged writes go here */
+ if (!(pgm->flag & PGM_FL_IS_DW) && jtag3_program_enable(pgm) < 0)
+ return -1;
+
+ u32_to_b4(cmd + 8, 1);
+ u32_to_b4(cmd + 4, addr);
+ cmd[12] = 0;
+ cmd[13] = data;
+
+ if ((status = jtag3_command(pgm, cmd, 14, &resp, "write memory")) < 0)
+ return -1;
+
+ free(resp);
+
+ return 0;
+}
+
+
+/*
+ * Set the JTAG clock. The actual frequency is quite a bit of
+ * guesswork, based on the values claimed by AVR Studio. Inside the
+ * JTAG ICE, the value is the delay count of a delay loop between the
+ * JTAG clock edges. A count of 0 bypasses the delay loop.
+ *
+ * As the STK500 expresses it as a period length (and we actualy do
+ * program a period length as well), we rather call it by that name.
+ */
+static int jtag3_set_sck_period(PROGRAMMER * pgm, double v)
+{
+ unsigned char parm[2];
+ unsigned int clock = 1E-3 / v; /* kHz */
+
+ parm[0] = clock & 0xff;
+ parm[1] = (clock >> 8) & 0xff;
+
+ if (PDATA(pgm)->set_sck == NULL) {
+ avrdude_message(MSG_INFO, "%s: No backend to set the SCK period for\n",
+ progname);
+ return -1;
+ }
+
+ return (PDATA(pgm)->set_sck(pgm, parm) < 0)? -1: 0;
+}
+
+
+/*
+ * Read (an) emulator parameter(s).
+ */
+int jtag3_getparm(PROGRAMMER * pgm, unsigned char scope,
+ unsigned char section, unsigned char parm,
+ unsigned char *value, unsigned char length)
+{
+ int status;
+ unsigned char buf[6], *resp, c;
+ char descr[60];
+
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_getparm()\n", progname);
+
+ buf[0] = scope;
+ buf[1] = CMD3_GET_PARAMETER;
+ buf[2] = 0;
+ buf[3] = section;
+ buf[4] = parm;
+ buf[5] = length;
+
+ sprintf(descr, "get parameter (scope 0x%02x, section %d, parm %d)",
+ scope, section, parm);
+
+ if ((status = jtag3_command(pgm, buf, 6, &resp, descr)) < 0)
+ return -1;
+
+ c = resp[1];
+ if (c != RSP3_DATA || status < 3) {
+ avrdude_message(MSG_INFO, "%s: jtag3_getparm(): "
+ "bad response to %s\n",
+ progname, descr);
+ free(resp);
+ return -1;
+ }
+
+ status -= 3;
+ memcpy(value, resp + 3, (length < status? length: status));
+ free(resp);
+
+ return 0;
+}
+
+/*
+ * Write an emulator parameter.
+ */
+int jtag3_setparm(PROGRAMMER * pgm, unsigned char scope,
+ unsigned char section, unsigned char parm,
+ unsigned char *value, unsigned char length)
+{
+ int status;
+ unsigned char *buf, *resp;
+ char descr[60];
+
+ avrdude_message(MSG_NOTICE2, "%s: jtag3_setparm()\n", progname);
+
+ sprintf(descr, "set parameter (scope 0x%02x, section %d, parm %d)",
+ scope, section, parm);
+
+ if ((buf = malloc(6 + length)) == NULL)
+ {
+ avrdude_message(MSG_INFO, "%s: jtag3_setparm(): Out of memory\n",
+ progname);
+ return -1;
+ }
+
+ buf[0] = scope;
+ buf[1] = CMD3_SET_PARAMETER;
+ buf[2] = 0;
+ buf[3] = section;
+ buf[4] = parm;
+ buf[5] = length;
+ memcpy(buf + 6, value, length);
+
+ status = jtag3_command(pgm, buf, length + 6, &resp, descr);
+
+ free(buf);
+ if (status > 0)
+ free(resp);
+
+ return status;
+}
+
+
+static void jtag3_display(PROGRAMMER * pgm, const char * p)
+{
+ unsigned char parms[5];
+ unsigned char cmd[4], *resp, c;
+ int status;
+
+ /*
+ * Ask for:
+ * PARM3_HW_VER (1 byte)
+ * PARM3_FW_MAJOR (1 byte)
+ * PARM3_FW_MINOR (1 byte)
+ * PARM3_FW_RELEASE (2 bytes)
+ */
+ if (jtag3_getparm(pgm, SCOPE_GENERAL, 0, PARM3_HW_VER, parms, 5) < 0)
+ return;
+
+ cmd[0] = SCOPE_INFO;
+ cmd[1] = CMD3_GET_INFO;
+ cmd[2] = 0;
+ cmd[3] = CMD3_INFO_SERIAL;
+
+ if ((status = jtag3_command(pgm, cmd, 4, &resp, "get info (serial number)")) < 0)
+ return;
+
+ c = resp[1];
+ if (c != RSP3_INFO) {
+ avrdude_message(MSG_INFO, "%s: jtag3_display(): response is not RSP3_INFO\n",
+ progname);
+ free(resp);
+ return;
+ }
+ memmove(resp, resp + 3, status - 3);
+ resp[status - 3] = 0;
+
+ avrdude_message(MSG_INFO, "%sICE hardware version: %d\n", p, parms[0]);
+ avrdude_message(MSG_INFO, "%sICE firmware version: %d.%02d (rel. %d)\n", p,
+ parms[1], parms[2],
+ (parms[3] | (parms[4] << 8)));
+ avrdude_message(MSG_INFO, "%sSerial number : %s\n", p, resp);
+ free(resp);
+
+ jtag3_print_parms1(pgm, p);
+}
+
+
+static void jtag3_print_parms1(PROGRAMMER * pgm, const char * p)
+{
+ unsigned char buf[2];
+
+ if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0)
+ return;
+
+ avrdude_message(MSG_INFO, "%sVtarget : %.2f V\n", p,
+ b2_to_u16(buf) / 1000.0);
+
+ if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_PROG, buf, 2) < 0)
+ return;
+ avrdude_message(MSG_INFO, "%sJTAG clock megaAVR/program: %u kHz\n", p,
+ b2_to_u16(buf));
+
+ if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_DEBUG, buf, 2) < 0)
+ return;
+ avrdude_message(MSG_INFO, "%sJTAG clock megaAVR/debug: %u kHz\n", p,
+ b2_to_u16(buf));
+
+ if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, buf, 2) < 0)
+ return;
+ avrdude_message(MSG_INFO, "%sJTAG clock Xmega: %u kHz\n", p,
+ b2_to_u16(buf));
+
+ if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, buf, 2) < 0)
+ return;
+ avrdude_message(MSG_INFO, "%sPDI clock Xmega : %u kHz\n", p,
+ b2_to_u16(buf));
+}
+
+static void jtag3_print_parms(PROGRAMMER * pgm)
+{
+ jtag3_print_parms1(pgm, "");
+}
+
+static unsigned char jtag3_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr)
+{
+ if ( p->flags & AVRPART_HAS_PDI ) {
+ if (addr >= PDATA(pgm)->boot_start)
+ return MTYPE_BOOT_FLASH;
+ else
+ return MTYPE_FLASH;
+ } else {
+ return MTYPE_FLASH_PAGE;
+ }
+}
+
+static unsigned int jtag3_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr)
+{
+ if ((p->flags & AVRPART_HAS_PDI) != 0) {
+ if (addr >= PDATA(pgm)->boot_start)
+ /*
+ * all memories but "flash" are smaller than boot_start anyway, so
+ * no need for an extra check we are operating on "flash"
+ */
+ return addr - PDATA(pgm)->boot_start;
+ else
+ /* normal flash, or anything else */
+ return addr;
+ }
+ /*
+ * Non-Xmega device.
+ */
+ return addr;
+}
+
+
+const char jtag3_desc[] = "Atmel JTAGICE3";
+
+void jtag3_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "JTAGICE3");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = jtag3_initialize;
+ pgm->display = jtag3_display;
+ pgm->enable = jtag3_enable;
+ pgm->disable = jtag3_disable;
+ pgm->program_enable = jtag3_program_enable_dummy;
+ pgm->chip_erase = jtag3_chip_erase;
+ pgm->open = jtag3_open;
+ pgm->close = jtag3_close;
+ pgm->read_byte = jtag3_read_byte;
+ pgm->write_byte = jtag3_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = jtag3_paged_write;
+ pgm->paged_load = jtag3_paged_load;
+ pgm->page_erase = jtag3_page_erase;
+ pgm->print_parms = jtag3_print_parms;
+ pgm->set_sck_period = jtag3_set_sck_period;
+ pgm->parseextparams = jtag3_parseextparms;
+ pgm->setup = jtag3_setup;
+ pgm->teardown = jtag3_teardown;
+ pgm->page_size = 256;
+ pgm->flag = PGM_FL_IS_JTAG;
+}
+
+const char jtag3_dw_desc[] = "Atmel JTAGICE3 in debugWire mode";
+
+void jtag3_dw_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "JTAGICE3_DW");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = jtag3_initialize;
+ pgm->display = jtag3_display;
+ pgm->enable = jtag3_enable;
+ pgm->disable = jtag3_disable;
+ pgm->program_enable = jtag3_program_enable_dummy;
+ pgm->chip_erase = jtag3_chip_erase_dw;
+ pgm->open = jtag3_open_dw;
+ pgm->close = jtag3_close;
+ pgm->read_byte = jtag3_read_byte;
+ pgm->write_byte = jtag3_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = jtag3_paged_write;
+ pgm->paged_load = jtag3_paged_load;
+ pgm->print_parms = jtag3_print_parms;
+ pgm->setup = jtag3_setup;
+ pgm->teardown = jtag3_teardown;
+ pgm->page_size = 256;
+ pgm->flag = PGM_FL_IS_DW;
+}
+
+const char jtag3_pdi_desc[] = "Atmel JTAGICE3 in PDI mode";
+
+void jtag3_pdi_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "JTAGICE3_PDI");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = jtag3_initialize;
+ pgm->display = jtag3_display;
+ pgm->enable = jtag3_enable;
+ pgm->disable = jtag3_disable;
+ pgm->program_enable = jtag3_program_enable_dummy;
+ pgm->chip_erase = jtag3_chip_erase;
+ pgm->open = jtag3_open_pdi;
+ pgm->close = jtag3_close;
+ pgm->read_byte = jtag3_read_byte;
+ pgm->write_byte = jtag3_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = jtag3_paged_write;
+ pgm->paged_load = jtag3_paged_load;
+ pgm->page_erase = jtag3_page_erase;
+ pgm->print_parms = jtag3_print_parms;
+ pgm->set_sck_period = jtag3_set_sck_period;
+ pgm->setup = jtag3_setup;
+ pgm->teardown = jtag3_teardown;
+ pgm->page_size = 256;
+ pgm->flag = PGM_FL_IS_PDI;
+}
+
diff --git a/xs/src/avrdude/jtag3.h b/xs/src/avrdude/jtag3.h
new file mode 100644
index 000000000..fef3be011
--- /dev/null
+++ b/xs/src/avrdude/jtag3.h
@@ -0,0 +1,60 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2012 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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 jtag3_h
+#define jtag3_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int jtag3_open_common(PROGRAMMER * pgm, char * port);
+int jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
+int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg);
+void jtag3_close(PROGRAMMER * pgm);
+int jtag3_getsync(PROGRAMMER * pgm, int mode);
+int jtag3_getparm(PROGRAMMER * pgm, unsigned char scope,
+ unsigned char section, unsigned char parm,
+ unsigned char *value, unsigned char length);
+int jtag3_setparm(PROGRAMMER * pgm, unsigned char scope,
+ unsigned char section, unsigned char parm,
+ unsigned char *value, unsigned char length);
+int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
+ unsigned char **resp, const char *descr);
+extern const char jtag3_desc[];
+extern const char jtag3_dw_desc[];
+extern const char jtag3_pdi_desc[];
+void jtag3_initpgm (PROGRAMMER * pgm);
+void jtag3_dw_initpgm (PROGRAMMER * pgm);
+void jtag3_pdi_initpgm (PROGRAMMER * pgm);
+
+/*
+ * These functions are referenced from stk500v2.c for JTAGICE3 in
+ * one of the STK500v2 modi.
+ */
+void jtag3_setup(PROGRAMMER * pgm);
+void jtag3_teardown(PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/xs/src/avrdude/jtag3_private.h b/xs/src/avrdude/jtag3_private.h
new file mode 100644
index 000000000..8ee37505d
--- /dev/null
+++ b/xs/src/avrdude/jtag3_private.h
@@ -0,0 +1,319 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2012 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ *
+ * 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$ */
+
+
+/*
+ * JTAGICE3 definitions
+ * Reverse-engineered from various USB traces.
+ */
+
+#if !defined(JTAG3_PRIVATE_EXPORTED)
+/*
+ * Communication with the JTAGICE3 uses three data endpoints:
+ *
+ * Endpoint 0x01 (OUT) and 0x82 (IN) are the usual conversation
+ * endpoints, with a maximal packet size of 512 octets. The
+ * JTAGICE3 does *not* work on older USB 1.1 hubs that would only
+ * allow for 64-octet max packet size.
+ *
+ * Endpoint 0x83 (IN) is also a bulk endpoint, with a max packetsize
+ * of 64 octets. This endpoint is used by the ICE to deliver events
+ * from the ICE.
+ *
+ * The request (host -> ICE, EP 0x01) format is:
+ *
+ * +---------------------------------------------
+ * | 0 | 1 | 2 . 3 | 4 | 5 | 6 | ...
+ * | | | | | | |
+ * | token |dummy|serial# |scope| cmd |dummy| optional data
+ * | 0x0e | 0 | NNNN | SS | CC | 0 | ...
+ * +---------------------------------------------
+ *
+ * Both dummy bytes are always 0. The "scope" identifier appears
+ * to distinguish commands (responses, events, parameters) roughly:
+ *
+ * 0x01 - general scope ("hello", "goodbye", firmware info, target
+ * voltage readout)
+ * 0x11 - scope for AVR in ISP mode (basically a wrapper around
+ * the AVRISPmkII commands, as usual)
+ * 0x12 - scope for AVR (JTAG, PDI, debugWIRE)
+ *
+ * The serial number is counted up.
+ *
+ *
+ * The response (ICE -> host, EP 0x82) format is:
+ *
+ * +--------------------------------------------------+
+ * | 0 | 1 . 2 | 3 | 4 | ... | N |
+ * | | | | | | |
+ * | token |serial# |scope| rsp | optional data |dummy|
+ * | 0x0e | NNNN | SS | RR | ... | 0 |
+ * +--------------------------------------------------+
+ *
+ * The response's serial number is mirrored from the request, but the
+ * dummy byte before the serial number is left out. However, another
+ * zero dummy byte is always attached to the end of the response data.
+ * Response codes are similar to the JTAGICEmkII, 0x80 is a generic
+ * "OK" response, other responses above 0x80 indicate various data
+ * responses (parameter read, memory read, PC value), and 0xa0 is a
+ * generic "failure" response. It appears the failure response gets
+ * another byte appended (probably indicating the reason) after the
+ * 0 dummy byte, but there's not enough analysis material so far.
+ *
+ *
+ * The event format (EP 0x83) is:
+ *
+ * +----------------------------------------
+ * | 0 | 1 | 2 . 3 | 4 | 5 | ...
+ * | | | | | |
+ * | token |dummy|serial# |scope| evt | data
+ * | 0x0e | 0 | NNNN | SS | EV | ...
+ * +----------------------------------------
+ */
+#define TOKEN 0x0e
+
+#endif /* JTAG3_PRIVATE_EXPORTED */
+
+#define SCOPE_INFO 0x00
+#define SCOPE_GENERAL 0x01
+#define SCOPE_AVR_ISP 0x11
+#define SCOPE_AVR 0x12
+
+/* Info scope */
+#define CMD3_GET_INFO 0x00
+
+/* byte after GET_INFO is always 0, next is: */
+# define CMD3_INFO_NAME 0x80 /* JTAGICE3 */
+# define CMD3_INFO_SERIAL 0x81 /* J3xxxxxxxxxx */
+
+/* Generic scope */
+#define CMD3_SET_PARAMETER 0x01
+#define CMD3_GET_PARAMETER 0x02
+#define CMD3_SIGN_ON 0x10
+#define CMD3_SIGN_OFF 0x11 /* takes one parameter? */
+#define CMD3_START_DW_DEBUG 0x13
+#define CMD3_MONCON_DISABLE 0x17
+
+/* AVR ISP scope: no commands of its own */
+
+/* AVR scope */
+//#define CMD3_SET_PARAMETER 0x01
+//#define CMD3_GET_PARAMETER 0x02
+//#define CMD3_SIGN_ON 0x10 /* an additional signon/-off pair */
+//#define CMD3_SIGN_OFF 0x11
+#define CMD3_ENTER_PROGMODE 0x15
+#define CMD3_LEAVE_PROGMODE 0x16
+#define CMD3_ERASE_MEMORY 0x20
+#define CMD3_READ_MEMORY 0x21
+#define CMD3_WRITE_MEMORY 0x23
+#define CMD3_READ_PC 0x35
+
+/* ICE responses */
+#define RSP3_OK 0x80
+#define RSP3_INFO 0x81
+#define RSP3_PC 0x83
+#define RSP3_DATA 0x84
+#define RSP3_FAILED 0xA0
+
+#define RSP3_STATUS_MASK 0xE0
+
+/* possible failure codes that could be appended to RSP3_FAILED: */
+# define RSP3_FAIL_DEBUGWIRE 0x10
+# define RSP3_FAIL_PDI 0x1B
+# define RSP3_FAIL_NO_ANSWER 0x20
+# define RSP3_FAIL_NO_TARGET_POWER 0x22
+# define RSP3_FAIL_WRONG_MODE 0x32 /* progmode vs. non-prog */
+# define RSP3_FAIL_UNSUPP_MEMORY 0x34 /* unsupported memory type */
+# define RSP3_FAIL_WRONG_LENGTH 0x35 /* wrong lenth for mem access */
+# define RSP3_FAIL_NOT_UNDERSTOOD 0x91
+
+/* ICE events */
+#define EVT3_BREAK 0x40 /* AVR scope */
+#define EVT3_SLEEP 0x11 /* General scope, also wakeup */
+#define EVT3_POWER 0x10 /* General scope */
+
+/* memory types */
+#define MTYPE_SRAM 0x20 /* target's SRAM or [ext.] IO registers */
+#define MTYPE_EEPROM 0x22 /* EEPROM, what way? */
+#define MTYPE_SPM 0xA0 /* flash through LPM/SPM */
+#define MTYPE_FLASH_PAGE 0xB0 /* flash in programming mode */
+#define MTYPE_EEPROM_PAGE 0xB1 /* EEPROM in programming mode */
+#define MTYPE_FUSE_BITS 0xB2 /* fuse bits in programming mode */
+#define MTYPE_LOCK_BITS 0xB3 /* lock bits in programming mode */
+#define MTYPE_SIGN_JTAG 0xB4 /* signature in programming mode */
+#define MTYPE_OSCCAL_BYTE 0xB5 /* osccal cells in programming mode */
+#define MTYPE_FLASH 0xc0 /* xmega (app.) flash - undocumented in AVR067 */
+#define MTYPE_BOOT_FLASH 0xc1 /* xmega boot flash - undocumented in AVR067 */
+#define MTYPE_EEPROM_XMEGA 0xc4 /* xmega EEPROM in debug mode - undocumented in AVR067 */
+#define MTYPE_USERSIG 0xc5 /* xmega user signature - undocumented in AVR067 */
+#define MTYPE_PRODSIG 0xc6 /* xmega production signature - undocumented in AVR067 */
+
+/*
+ * Parameters are divided into sections, where the section number
+ * precedes each parameter address. There are distinct parameter
+ * sets for generic and AVR scope.
+ */
+#define PARM3_HW_VER 0x00 /* section 0, generic scope, 1 byte */
+#define PARM3_FW_MAJOR 0x01 /* section 0, generic scope, 1 byte */
+#define PARM3_FW_MINOR 0x02 /* section 0, generic scope, 1 byte */
+#define PARM3_FW_RELEASE 0x03 /* section 0, generic scope, 1 byte;
+ * always asked for by Atmel Studio,
+ * but never displayed there */
+#define PARM3_VTARGET 0x00 /* section 1, generic scope, 2 bytes,
+ * in millivolts */
+#define PARM3_DEVICEDESC 0x00 /* section 2, memory etc. configuration,
+ * 31 bytes for tiny/mega AVR, 47 bytes
+ * for Xmega; is also used in command
+ * 0x36 in JTAGICEmkII, starting with
+ * firmware 7.x */
+
+#define PARM3_ARCH 0x00 /* section 0, AVR scope, 1 byte */
+# define PARM3_ARCH_TINY 1 /* also small megaAVR with ISP/DW only */
+# define PARM3_ARCH_MEGA 2
+# define PARM3_ARCH_XMEGA 3
+
+#define PARM3_SESS_PURPOSE 0x01 /* section 0, AVR scope, 1 byte */
+# define PARM3_SESS_PROGRAMMING 1
+# define PARM3_SESS_DEBUGGING 2
+
+#define PARM3_CONNECTION 0x00 /* section 1, AVR scope, 1 byte */
+# define PARM3_CONN_ISP 1
+# define PARM3_CONN_JTAG 4
+# define PARM3_CONN_DW 5
+# define PARM3_CONN_PDI 6
+
+
+#define PARM3_JTAGCHAIN 0x01 /* JTAG chain info, AVR scope (units
+ * before/after, bits before/after), 4
+ * bytes */
+
+#define PARM3_CLK_MEGA_PROG 0x20 /* section 1, AVR scope, 2 bytes (kHz) */
+#define PARM3_CLK_MEGA_DEBUG 0x21 /* section 1, AVR scope, 2 bytes (kHz) */
+#define PARM3_CLK_XMEGA_JTAG 0x30 /* section 1, AVR scope, 2 bytes (kHz) */
+#define PARM3_CLK_XMEGA_PDI 0x31 /* section 1, AVR scope, 2 bytes (kHz) */
+
+
+
+/* Xmega erase memory types, for CMND_XMEGA_ERASE */
+#define XMEGA_ERASE_CHIP 0x00
+#define XMEGA_ERASE_APP 0x01
+#define XMEGA_ERASE_BOOT 0x02
+#define XMEGA_ERASE_EEPROM 0x03
+#define XMEGA_ERASE_APP_PAGE 0x04
+#define XMEGA_ERASE_BOOT_PAGE 0x05
+#define XMEGA_ERASE_EEPROM_PAGE 0x06
+#define XMEGA_ERASE_USERSIG 0x07
+
+/* EDBG vendor commands */
+#define EDBG_VENDOR_AVR_CMD 0x80
+#define EDBG_VENDOR_AVR_RSP 0x81
+#define EDBG_VENDOR_AVR_EVT 0x82
+
+/* CMSIS-DAP commands */
+#define CMSISDAP_CMD_INFO 0x00 /* get info, followed by INFO byte */
+# define CMSISDAP_INFO_VID 0x01 /* vendor ID (string) */
+# define CMSISDAP_INFO_PID 0x02 /* product ID (string) */
+# define CMSISDAP_INFO_SERIAL 0x03 /* serial number (string) */
+# define CMSISDAP_INFO_FIRMWARE 0x04 /* firmware version (string) */
+# define CMSISDAP_INFO_TARGET_VENDOR 0x05 /* target device vendor (string) */
+# define CMSISDAP_INFO_TARGET_NAME 0x06 /* target device name (string) */
+# define CMSISDAP_INFO_CAPABILITIES 0xF0 /* debug unit capabilities (byte) */
+# define CMSISDAP_INFO_PACKET_COUNT 0xFE /* packet count (byte) (which packets, anyway?) */
+# define CMSISDAP_INFO_PACKET_SIZE 0xFF /* packet size (short) */
+
+#define CMSISDAP_CMD_LED 0x01 /* LED control, followed by LED number and on/off byte */
+# define CMSISDAP_LED_CONNECT 0x00 /* connect LED */
+# define CMSISDAP_LED_RUNNING 0x01 /* running LED */
+
+#define CMSISDAP_CMD_CONNECT 0x02 /* connect to target, followed by DAP mode */
+# define CMSISDAP_CONN_DEFAULT 0x00
+# define CMSISDAP_CONN_SWD 0x01 /* serial wire debug */
+# define CMSISDAP_CONN_JTAG 0x02 /* JTAG mode */
+
+#define CMSISDAP_CMD_DISCONNECT 0x03 /* disconnect from target */
+
+#define CMSISDAP_XFR_CONFIGURE 0x04 /* configure transfers; idle cycles (byte);
+ wait retry (short); match retry (short) */
+
+#define CMSISDAP_CMD_WRITEAPBORT 0x08 /* write to CoreSight ABORT register of target */
+
+#define CMSISDAP_CMD_DELAY 0x09 /* delay for number of microseconds (short) */
+
+#define CMSISDAP_CMD_RESET 0x0A /* reset target */
+
+#define CMSISDAP_CMD_SWJ_CLOCK 0x11 /* SWD/JTAG clock, (word) */
+
+#define CMSISDAP_CMD_SWD_CONFIGURE 0x13 /* configure SWD protocol; (byte) */
+
+#if !defined(JTAG3_PRIVATE_EXPORTED)
+
+struct mega_device_desc {
+ unsigned char flash_page_size[2]; // in bytes
+ unsigned char flash_size[4]; // in bytes
+ unsigned char dummy1[4]; // always 0
+ unsigned char boot_address[4]; // maximal (BOOTSZ = 3) bootloader
+ // address, in 16-bit words (!)
+ unsigned char sram_offset[2]; // pointing behind IO registers
+ unsigned char eeprom_size[2];
+ unsigned char eeprom_page_size;
+ unsigned char ocd_revision; // see XML; basically:
+ // t13*, t2313*, t4313: 0
+ // all other DW devices: 1
+ // ATmega128(A): 1 (!)
+ // ATmega16*,162,169*,32*,64*: 2
+ // ATmega2560/2561: 4
+ // all other megaAVR devices: 3
+ unsigned char always_one; // always = 1
+ unsigned char allow_full_page_bitstream; // old AVRs, see XML
+ unsigned char dummy2[2]; // always 0
+ // all IO addresses below are given
+ // in IO number space (without
+ // offset 0x20), even though e.g.
+ // OSCCAL always resides outside
+ unsigned char idr_address; // IDR, aka. OCDR
+ unsigned char eearh_address; // EEPROM access
+ unsigned char eearl_address;
+ unsigned char eecr_address;
+ unsigned char eedr_address;
+ unsigned char spmcr_address;
+ unsigned char osccal_address;
+};
+
+
+/* Xmega device descriptor */
+struct xmega_device_desc {
+ unsigned char nvm_app_offset[4]; // NVM offset for application flash
+ unsigned char nvm_boot_offset[4]; // NVM offset for boot flash
+ unsigned char nvm_eeprom_offset[4]; // NVM offset for EEPROM
+ unsigned char nvm_fuse_offset[4]; // NVM offset for fuses
+ unsigned char nvm_lock_offset[4]; // NVM offset for lock bits
+ unsigned char nvm_user_sig_offset[4]; // NVM offset for user signature row
+ unsigned char nvm_prod_sig_offset[4]; // NVM offset for production sign. row
+ unsigned char nvm_data_offset[4]; // NVM offset for data memory (SRAM + IO)
+ unsigned char app_size[4]; // size of application flash
+ unsigned char boot_size[2]; // size of boot flash
+ unsigned char flash_page_size[2]; // flash page size
+ unsigned char eeprom_size[2]; // size of EEPROM
+ unsigned char eeprom_page_size; // EEPROM page size
+ unsigned char nvm_base_addr[2]; // IO space base address of NVM controller
+ unsigned char mcu_base_addr[2]; // IO space base address of MCU control
+};
+#endif /* JTAG3_PRIVATE_EXPORTED */
diff --git a/xs/src/avrdude/jtagmkI.c b/xs/src/avrdude/jtagmkI.c
new file mode 100644
index 000000000..2a5f27e4a
--- /dev/null
+++ b/xs/src/avrdude/jtagmkI.c
@@ -0,0 +1,1365 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2005, 2007 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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 Atmel JTAG ICE (mkI) programmer
+ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "crc16.h"
+#include "jtagmkI.h"
+#include "jtagmkI_private.h"
+
+/*
+ * Private data for this programmer.
+ */
+struct pdata
+{
+ int initial_baudrate;
+
+ /*
+ * See jtagmkI_read_byte() for an explanation of the flash and
+ * EEPROM page caches.
+ */
+ unsigned char *flash_pagecache;
+ unsigned long flash_pageaddr;
+ unsigned int flash_pagesize;
+
+ unsigned char *eeprom_pagecache;
+ unsigned long eeprom_pageaddr;
+ unsigned int eeprom_pagesize;
+
+ int prog_enabled; /* Cached value of PROGRAMMING status. */
+};
+
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
+/*
+ * The OCDEN fuse is bit 7 of the high fuse (hfuse). In order to
+ * perform memory operations on MTYPE_SPM and MTYPE_EEPROM, OCDEN
+ * needs to be programmed.
+ *
+ * OCDEN should probably rather be defined via the configuration, but
+ * if this ever changes to a different fuse byte for one MCU, quite
+ * some code here needs to be generalized anyway.
+ */
+#define OCDEN (1 << 7)
+
+/*
+ * Table of baud rates supported by the mkI ICE, accompanied by their
+ * internal parameter value.
+ *
+ * 19200 is the initial value of the ICE after powerup, and virtually
+ * all connections then switch to 115200. As the table is also used
+ * to try connecting at startup, we keep these two entries on top to
+ * speedup the program start.
+ */
+const static struct {
+ long baud;
+ unsigned char val;
+} baudtab[] = {
+ { 19200L, 0xfa },
+ { 115200L, 0xff },
+ { 9600L, 0xf4 },
+ { 38400L, 0xfd },
+ { 57600L, 0xfe },
+/* { 14400L, 0xf8 }, */ /* not supported by serial driver */
+};
+
+static int jtagmkI_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value);
+static int jtagmkI_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data);
+static int jtagmkI_set_sck_period(PROGRAMMER * pgm, double v);
+static int jtagmkI_getparm(PROGRAMMER * pgm, unsigned char parm,
+ unsigned char * value);
+static int jtagmkI_setparm(PROGRAMMER * pgm, unsigned char parm,
+ unsigned char value);
+static void jtagmkI_print_parms1(PROGRAMMER * pgm, const char * p);
+
+static int jtagmkI_resync(PROGRAMMER *pgm, int maxtries, int signon);
+
+static void jtagmkI_setup(PROGRAMMER * pgm)
+{
+ if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_setup(): Out of memory allocating private data\n",
+ progname);
+ exit(1);
+ }
+ memset(pgm->cookie, 0, sizeof(struct pdata));
+}
+
+static void jtagmkI_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+}
+
+
+static void
+u32_to_b3(unsigned char *b, unsigned long l)
+{
+ b[2] = l & 0xff;
+ b[1] = (l >> 8) & 0xff;
+ b[0] = (l >> 16) & 0xff;
+}
+
+static void
+u16_to_b2(unsigned char *b, unsigned short l)
+{
+ b[0] = l & 0xff;
+ b[1] = (l >> 8) & 0xff;
+}
+
+static void jtagmkI_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ int i;
+
+ if (verbose >= 4) {
+ avrdude_message(MSG_TRACE, "Raw message:\n");
+
+ for (i = 0; i < len; i++) {
+ avrdude_message(MSG_TRACE, "0x%02x ", data[i]);
+ if (i % 16 == 15)
+ putc('\n', stderr);
+ else
+ putc(' ', stderr);
+ }
+ if (i % 16 != 0)
+ putc('\n', stderr);
+ }
+
+ switch (data[0]) {
+ case RESP_OK:
+ avrdude_message(MSG_INFO, "OK\n");
+ break;
+
+ case RESP_FAILED:
+ avrdude_message(MSG_INFO, "FAILED\n");
+ break;
+
+ case RESP_BREAK:
+ avrdude_message(MSG_INFO, "breakpoint hit\n");
+ break;
+
+ case RESP_INFO:
+ avrdude_message(MSG_INFO, "IDR dirty\n");
+ break;
+
+ case RESP_SYNC_ERROR:
+ avrdude_message(MSG_INFO, "Synchronization lost\n");
+ break;
+
+ case RESP_SLEEP:
+ avrdude_message(MSG_INFO, "sleep instruction hit\n");
+ break;
+
+ case RESP_POWER:
+ avrdude_message(MSG_INFO, "target power lost\n");
+
+ default:
+ avrdude_message(MSG_INFO, "unknown message 0x%02x\n", data[0]);
+ }
+
+ putc('\n', stderr);
+}
+
+
+static int jtagmkI_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ unsigned char *buf;
+
+ avrdude_message(MSG_DEBUG, "\n%s: jtagmkI_send(): sending %u bytes\n",
+ progname, (unsigned int)len);
+
+ if ((buf = malloc(len + 2)) == NULL)
+ {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_send(): out of memory",
+ progname);
+ exit(1);
+ }
+
+ memcpy(buf, data, len);
+ buf[len] = ' '; /* "CRC" */
+ buf[len + 1] = ' '; /* EOP */
+
+ if (serial_send(&pgm->fd, buf, len + 2) != 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_send(): failed to send command to serial port\n",
+ progname);
+ return -1;
+ }
+
+ free(buf);
+
+ return 0;
+}
+
+static int jtagmkI_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
+{
+ if (serial_recv(&pgm->fd, buf, len) != 0) {
+ avrdude_message(MSG_INFO, "\n%s: jtagmkI_recv(): failed to send command to serial port\n",
+ progname);
+ return -1;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkI_prmsg(pgm, buf, len);
+ }
+ return 0;
+}
+
+
+static int jtagmkI_drain(PROGRAMMER * pgm, int display)
+{
+ return serial_drain(&pgm->fd, display);
+}
+
+
+static int jtagmkI_resync(PROGRAMMER * pgm, int maxtries, int signon)
+{
+ int tries;
+ unsigned char buf[4], resp[9];
+ long otimeout = serial_recv_timeout;
+
+ serial_recv_timeout = 200;
+
+ avrdude_message(MSG_TRACE, "%s: jtagmkI_resync()\n", progname);
+
+ jtagmkI_drain(pgm, 0);
+
+ for (tries = 0; tries < maxtries; tries++) {
+
+ /* Get the sign-on information. */
+ buf[0] = CMD_GET_SYNC;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_resync(): Sending sync command: ",
+ progname);
+
+ if (serial_send(&pgm->fd, buf, 1) != 0) {
+ avrdude_message(MSG_INFO, "\n%s: jtagmkI_resync(): failed to send command to serial port\n",
+ progname);
+ serial_recv_timeout = otimeout;
+ return -1;
+ }
+ if (serial_recv(&pgm->fd, resp, 1) == 0 && resp[0] == RESP_OK) {
+ avrdude_message(MSG_NOTICE2, "got RESP_OK\n");
+ break;
+ }
+
+ if (signon) {
+ /*
+ * The following is black magic, the idea has been taken from
+ * AVaRICE.
+ *
+ * Apparently, the ICE behaves differently right after a
+ * power-up vs. when reconnecting to an ICE that has already
+ * been worked with. The undocumented 'E' command (or
+ * subcommand) occasionally helps in getting the connection into
+ * sync.
+ */
+ buf[0] = CMD_GET_SIGNON;
+ buf[1] = 'E';
+ buf[2] = ' ';
+ buf[3] = ' ';
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_resync(): Sending sign-on command: ",
+ progname);
+
+ if (serial_send(&pgm->fd, buf, 4) != 0) {
+ avrdude_message(MSG_INFO, "\n%s: jtagmkI_resync(): failed to send command to serial port\n",
+ progname);
+ serial_recv_timeout = otimeout;
+ return -1;
+ }
+ if (serial_recv(&pgm->fd, resp, 9) == 0 && resp[0] == RESP_OK) {
+ avrdude_message(MSG_NOTICE2, "got RESP_OK\n");
+ break;
+ }
+ }
+ }
+ if (tries >= maxtries) {
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_resync(): "
+ "timeout/error communicating with programmer\n",
+ progname);
+ serial_recv_timeout = otimeout;
+ return -1;
+ }
+
+ serial_recv_timeout = otimeout;
+ return 0;
+}
+
+static int jtagmkI_getsync(PROGRAMMER * pgm)
+{
+ unsigned char buf[1], resp[9];
+
+ if (jtagmkI_resync(pgm, 5, 1) < 0) {
+ jtagmkI_drain(pgm, 0);
+ return -1;
+ }
+
+ jtagmkI_drain(pgm, 0);
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_getsync(): Sending sign-on command: ",
+ progname);
+
+ buf[0] = CMD_GET_SIGNON;
+ jtagmkI_send(pgm, buf, 1);
+ if (jtagmkI_recv(pgm, resp, 9) < 0)
+ return -1;
+ if (verbose >= 2) {
+ resp[8] = '\0';
+ avrdude_message(MSG_NOTICE2, "got %s\n", resp + 1);
+ }
+
+ return 0;
+}
+
+/*
+ * issue the 'chip erase' command to the AVR device
+ */
+static int jtagmkI_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char buf[1], resp[2];
+
+ buf[0] = CMD_CHIP_ERASE;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_chip_erase(): Sending chip erase command: ",
+ progname);
+ jtagmkI_send(pgm, buf, 1);
+ if (jtagmkI_recv(pgm, resp, 2) < 0)
+ return -1;
+ if (resp[0] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_chip_erase(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+
+ pgm->initialize(pgm, p);
+
+ return 0;
+}
+
+static void jtagmkI_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char resp[2];
+ LNODEID ln;
+ AVRMEM * m;
+ struct {
+ unsigned char cmd;
+ struct device_descriptor dd;
+ } sendbuf;
+
+ memset(&sendbuf, 0, sizeof sendbuf);
+ sendbuf.cmd = CMD_SET_DEVICE_DESCRIPTOR;
+ sendbuf.dd.ucSPMCRAddress = p->spmcr;
+ sendbuf.dd.ucRAMPZAddress = p->rampz;
+ sendbuf.dd.ucIDRAddress = p->idr;
+ for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
+ m = ldata(ln);
+ if (strcmp(m->desc, "flash") == 0) {
+ PDATA(pgm)->flash_pagesize = m->page_size;
+ u16_to_b2(sendbuf.dd.uiFlashPageSize, PDATA(pgm)->flash_pagesize);
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ sendbuf.dd.ucEepromPageSize = PDATA(pgm)->eeprom_pagesize = m->page_size;
+ }
+ }
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_set_devdescr(): "
+ "Sending set device descriptor command: ",
+ progname);
+ jtagmkI_send(pgm, (unsigned char *)&sendbuf, sizeof(sendbuf));
+
+ if (jtagmkI_recv(pgm, resp, 2) < 0)
+ return;
+ if (resp[0] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_set_devdescr(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+}
+
+/*
+ * Reset the target.
+ */
+static int jtagmkI_reset(PROGRAMMER * pgm)
+{
+ unsigned char buf[1], resp[2];
+
+ buf[0] = CMD_RESET;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_reset(): Sending reset command: ",
+ progname);
+ jtagmkI_send(pgm, buf, 1);
+
+ if (jtagmkI_recv(pgm, resp, 2) < 0)
+ return -1;
+ if (resp[0] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_reset(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+
+ return 0;
+}
+
+static int jtagmkI_program_enable_dummy(PROGRAMMER * pgm, AVRPART * p)
+{
+
+ return 0;
+}
+
+static int jtagmkI_program_enable(PROGRAMMER * pgm)
+{
+ unsigned char buf[1], resp[2];
+
+ if (PDATA(pgm)->prog_enabled)
+ return 0;
+
+ buf[0] = CMD_ENTER_PROGMODE;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_program_enable(): "
+ "Sending enter progmode command: ",
+ progname);
+ jtagmkI_send(pgm, buf, 1);
+
+ if (jtagmkI_recv(pgm, resp, 2) < 0)
+ return -1;
+ if (resp[0] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_program_enable(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+
+ PDATA(pgm)->prog_enabled = 1;
+
+ return 0;
+}
+
+static int jtagmkI_program_disable(PROGRAMMER * pgm)
+{
+ unsigned char buf[1], resp[2];
+
+ if (!PDATA(pgm)->prog_enabled)
+ return 0;
+
+ if (pgm->fd.ifd != -1) {
+ buf[0] = CMD_LEAVE_PROGMODE;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_program_disable(): "
+ "Sending leave progmode command: ",
+ progname);
+ jtagmkI_send(pgm, buf, 1);
+
+ if (jtagmkI_recv(pgm, resp, 2) < 0)
+ return -1;
+ if (resp[0] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_program_disable(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+ }
+ PDATA(pgm)->prog_enabled = 0;
+
+ return 0;
+}
+
+static unsigned char jtagmkI_get_baud(long baud)
+{
+ int i;
+
+ for (i = 0; i < sizeof baudtab / sizeof baudtab[0]; i++)
+ if (baud == baudtab[i].baud)
+ return baudtab[i].val;
+
+ return 0;
+}
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+static int jtagmkI_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ AVRMEM hfuse;
+ unsigned char cmd[1], resp[5];
+ unsigned char b;
+
+ if (!(p->flags & AVRPART_HAS_JTAG)) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_initialize(): part %s has no JTAG interface\n",
+ progname, p->desc);
+ return -1;
+ }
+
+ jtagmkI_drain(pgm, 0);
+
+ if ((serdev->flags & SERDEV_FL_CANSETSPEED) && PDATA(pgm)->initial_baudrate != pgm->baudrate) {
+ if ((b = jtagmkI_get_baud(pgm->baudrate)) == 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_initialize(): unsupported baudrate %d\n",
+ progname, pgm->baudrate);
+ } else {
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_initialize(): "
+ "trying to set baudrate to %d\n",
+ progname, pgm->baudrate);
+ if (jtagmkI_setparm(pgm, PARM_BITRATE, b) == 0) {
+ PDATA(pgm)->initial_baudrate = pgm->baudrate; /* don't adjust again later */
+ serial_setspeed(&pgm->fd, pgm->baudrate);
+ }
+ }
+ }
+
+ if (pgm->bitclock != 0.0) {
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_initialize(): "
+ "trying to set JTAG clock period to %.1f us\n",
+ progname, pgm->bitclock);
+ if (jtagmkI_set_sck_period(pgm, pgm->bitclock) != 0)
+ return -1;
+ }
+
+ cmd[0] = CMD_STOP;
+ jtagmkI_send(pgm, cmd, 1);
+ if (jtagmkI_recv(pgm, resp, 5) < 0)
+ return -1;
+ if (resp[0] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_initialize(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+
+ /*
+ * Must set the device descriptor before entering programming mode.
+ */
+ jtagmkI_set_devdescr(pgm, p);
+
+ jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_LOW, PDATA(pgm)->flash_pagesize & 0xff);
+ jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_HIGH, PDATA(pgm)->flash_pagesize >> 8);
+ jtagmkI_setparm(pgm, PARM_EEPROM_PAGESIZE, PDATA(pgm)->eeprom_pagesize & 0xff);
+
+ free(PDATA(pgm)->flash_pagecache);
+ free(PDATA(pgm)->eeprom_pagecache);
+ if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_initialize(): Out of memory\n",
+ progname);
+ return -1;
+ }
+ if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_initialize(): Out of memory\n",
+ progname);
+ free(PDATA(pgm)->flash_pagecache);
+ return -1;
+ }
+ PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+
+ if (jtagmkI_reset(pgm) < 0)
+ return -1;
+
+ strcpy(hfuse.desc, "hfuse");
+ if (jtagmkI_read_byte(pgm, p, &hfuse, 1, &b) < 0)
+ return -1;
+ if ((b & OCDEN) != 0)
+ avrdude_message(MSG_INFO, "%s: jtagmkI_initialize(): warning: OCDEN fuse not programmed, "
+ "single-byte EEPROM updates not possible\n",
+ progname);
+
+ return 0;
+}
+
+
+static void jtagmkI_disable(PROGRAMMER * pgm)
+{
+
+ free(PDATA(pgm)->flash_pagecache);
+ PDATA(pgm)->flash_pagecache = NULL;
+ free(PDATA(pgm)->eeprom_pagecache);
+ PDATA(pgm)->eeprom_pagecache = NULL;
+
+ (void)jtagmkI_program_disable(pgm);
+}
+
+static void jtagmkI_enable(PROGRAMMER * pgm)
+{
+ return;
+}
+
+
+static int jtagmkI_open(PROGRAMMER * pgm, char * port)
+{
+ size_t i;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_open()\n", progname);
+
+ strcpy(pgm->port, port);
+ PDATA(pgm)->initial_baudrate = -1L;
+
+ for (i = 0; i < sizeof(baudtab) / sizeof(baudtab[0]); i++) {
+ union pinfo pinfo;
+ pinfo.baud = baudtab[i].baud;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_open(): trying to sync at baud rate %ld:\n",
+ progname, pinfo.baud);
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ jtagmkI_drain(pgm, 0);
+
+ if (jtagmkI_getsync(pgm) == 0) {
+ PDATA(pgm)->initial_baudrate = baudtab[i].baud;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_open(): succeeded\n", progname);
+ return 0;
+ }
+
+ serial_close(&pgm->fd);
+ }
+
+ avrdude_message(MSG_INFO, "%s: jtagmkI_open(): failed to synchronize to ICE\n",
+ progname);
+ pgm->fd.ifd = -1;
+
+ return -1;
+}
+
+
+static void jtagmkI_close(PROGRAMMER * pgm)
+{
+ unsigned char b;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_close()\n", progname);
+
+ /*
+ * Revert baud rate to what it used to be when we started. This
+ * appears to make AVR Studio happier when it is about to access the
+ * ICE later on.
+ */
+ if ((serdev->flags & SERDEV_FL_CANSETSPEED) && PDATA(pgm)->initial_baudrate != pgm->baudrate) {
+ if ((b = jtagmkI_get_baud(PDATA(pgm)->initial_baudrate)) == 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_close(): unsupported baudrate %d\n",
+ progname, PDATA(pgm)->initial_baudrate);
+ } else {
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_close(): "
+ "trying to set baudrate to %d\n",
+ progname, PDATA(pgm)->initial_baudrate);
+ if (jtagmkI_setparm(pgm, PARM_BITRATE, b) == 0) {
+ serial_setspeed(&pgm->fd, pgm->baudrate);
+ }
+ }
+ }
+
+ if (pgm->fd.ifd != -1) {
+ serial_close(&pgm->fd);
+ }
+
+ pgm->fd.ifd = -1;
+}
+
+
+static int jtagmkI_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ int block_size, send_size, tries;
+ unsigned int maxaddr = addr + n_bytes;
+ unsigned char cmd[6], *datacmd;
+ unsigned char resp[2];
+ int is_flash = 0;
+ long otimeout = serial_recv_timeout;
+#define MAXTRIES 3
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_paged_write(.., %s, %d, %d)\n",
+ progname, m->desc, page_size, n_bytes);
+
+ if (jtagmkI_program_enable(pgm) < 0)
+ return -1;
+
+ if (page_size == 0) page_size = 256;
+
+ if (page_size > 256) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_paged_write(): page size %d too large\n",
+ progname, page_size);
+ return -1;
+ }
+
+ if ((datacmd = malloc(page_size + 1)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_paged_write(): Out of memory\n",
+ progname);
+ return -1;
+ }
+
+ cmd[0] = CMD_WRITE_MEM;
+ if (strcmp(m->desc, "flash") == 0) {
+ cmd[1] = MTYPE_FLASH_PAGE;
+ PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
+ page_size = PDATA(pgm)->flash_pagesize;
+ is_flash = 1;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ cmd[1] = MTYPE_EEPROM_PAGE;
+ PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+ page_size = PDATA(pgm)->eeprom_pagesize;
+ }
+ datacmd[0] = CMD_DATA;
+
+ serial_recv_timeout = 1000;
+ for (; addr < maxaddr; addr += page_size) {
+ tries = 0;
+ again:
+
+ if (tries != 0 && jtagmkI_resync(pgm, 2000, 0) < 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_paged_write(): sync loss, retries exhausted\n",
+ progname);
+ return -1;
+ }
+
+ if (n_bytes < page_size)
+ block_size = n_bytes;
+ else
+ block_size = page_size;
+ avrdude_message(MSG_DEBUG, "%s: jtagmkI_paged_write(): "
+ "block_size at addr %d is %d\n",
+ progname, addr, block_size);
+
+ /* We always write full pages. */
+ send_size = page_size;
+ if (is_flash) {
+ cmd[2] = send_size / 2 - 1;
+ u32_to_b3(cmd + 3, addr / 2);
+ } else {
+ cmd[2] = send_size - 1;
+ u32_to_b3(cmd + 3, addr);
+ }
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_paged_write(): "
+ "Sending write memory command: ",
+ progname);
+
+ /* First part, send the write command. */
+ jtagmkI_send(pgm, cmd, 6);
+ if (jtagmkI_recv(pgm, resp, 1) < 0)
+ return -1;
+ if (resp[0] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_paged_write(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ if (tries++ < MAXTRIES)
+ goto again;
+ serial_recv_timeout = otimeout;
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+
+ /*
+ * The JTAG ICE will refuse to write anything but a full page, at
+ * least for the flash ROM. If a partial page has been requested,
+ * set the remainder to 0xff. (Maybe we should rather read back
+ * the existing contents instead before? Doesn't matter much, as
+ * bits cannot be written to 1 anyway.)
+ */
+ memset(datacmd + 1, 0xff, page_size);
+ memcpy(datacmd + 1, m->buf + addr, block_size);
+
+ /* Second, send the data command. */
+ jtagmkI_send(pgm, datacmd, send_size + 1);
+ if (jtagmkI_recv(pgm, resp, 2) < 0)
+ return -1;
+ if (resp[1] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_paged_write(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ if (tries++ < MAXTRIES)
+ goto again;
+ serial_recv_timeout = otimeout;
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+ }
+
+ free(datacmd);
+ serial_recv_timeout = otimeout;
+
+#undef MAXTRIES
+ return n_bytes;
+}
+
+static int jtagmkI_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ int block_size, read_size, is_flash = 0, tries;
+ unsigned int maxaddr = addr + n_bytes;
+ unsigned char cmd[6], resp[256 * 2 + 3];
+ long otimeout = serial_recv_timeout;
+#define MAXTRIES 3
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_paged_load(.., %s, %d, %d)\n",
+ progname, m->desc, page_size, n_bytes);
+
+ if (jtagmkI_program_enable(pgm) < 0)
+ return -1;
+
+ page_size = m->readsize;
+
+ cmd[0] = CMD_READ_MEM;
+ if (strcmp(m->desc, "flash") == 0) {
+ cmd[1] = MTYPE_FLASH_PAGE;
+ is_flash = 1;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ cmd[1] = MTYPE_EEPROM_PAGE;
+ }
+
+ if (page_size > (is_flash? 512: 256)) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_paged_load(): page size %d too large\n",
+ progname, page_size);
+ return -1;
+ }
+
+ serial_recv_timeout = 1000;
+ for (; addr < maxaddr; addr += page_size) {
+ tries = 0;
+ again:
+ if (tries != 0 && jtagmkI_resync(pgm, 2000, 0) < 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkI_paged_load(): sync loss, retries exhausted\n",
+ progname);
+ return -1;
+ }
+
+ if (n_bytes < page_size)
+ block_size = n_bytes;
+ else
+ block_size = page_size;
+ avrdude_message(MSG_DEBUG, "%s: jtagmkI_paged_load(): "
+ "block_size at addr %d is %d\n",
+ progname, addr, block_size);
+
+ if (is_flash) {
+ read_size = 2 * ((block_size + 1) / 2); /* round up */
+ cmd[2] = read_size / 2 - 1;
+ u32_to_b3(cmd + 3, addr / 2);
+ } else {
+ read_size = page_size;
+ cmd[2] = page_size - 1;
+ u32_to_b3(cmd + 3, addr);
+ }
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_paged_load(): Sending read memory command: ",
+ progname);
+
+ jtagmkI_send(pgm, cmd, 6);
+ if (jtagmkI_recv(pgm, resp, read_size + 3) < 0)
+ return -1;
+
+ if (resp[read_size + 3 - 1] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_paged_load(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[read_size + 3 - 1]);
+ if (tries++ < MAXTRIES)
+ goto again;
+
+ serial_recv_timeout = otimeout;
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+
+ memcpy(m->buf + addr, resp + 1, block_size);
+ }
+ serial_recv_timeout = otimeout;
+
+#undef MAXTRIES
+ return n_bytes;
+}
+
+static int jtagmkI_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value)
+{
+ unsigned char cmd[6];
+ unsigned char resp[256 * 2 + 3], *cache_ptr = NULL;
+ unsigned long paddr = 0UL, *paddr_ptr = NULL;
+ unsigned int pagesize = 0;
+ int respsize = 3 + 1;
+ int is_flash = 0;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_read_byte(.., %s, 0x%lx, ...)\n",
+ progname, mem->desc, addr);
+
+ if (jtagmkI_program_enable(pgm) < 0)
+ return -1;
+
+ cmd[0] = CMD_READ_MEM;
+
+ if (strcmp(mem->desc, "flash") == 0) {
+ cmd[1] = MTYPE_FLASH_PAGE;
+ pagesize = mem->page_size;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->flash_pageaddr;
+ cache_ptr = PDATA(pgm)->flash_pagecache;
+ is_flash = 1;
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ cmd[1] = MTYPE_EEPROM_PAGE;
+ pagesize = mem->page_size;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
+ cache_ptr = PDATA(pgm)->eeprom_pagecache;
+ } else if (strcmp(mem->desc, "lfuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 0;
+ } else if (strcmp(mem->desc, "hfuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 1;
+ } else if (strcmp(mem->desc, "efuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 2;
+ } else if (strcmp(mem->desc, "lock") == 0) {
+ cmd[1] = MTYPE_LOCK_BITS;
+ } else if (strcmp(mem->desc, "calibration") == 0) {
+ cmd[1] = MTYPE_OSCCAL_BYTE;
+ } else if (strcmp(mem->desc, "signature") == 0) {
+ cmd[1] = MTYPE_SIGN_JTAG;
+ }
+
+ /*
+ * To improve the read speed, we used paged reads for flash and
+ * EEPROM, and cache the results in a page cache.
+ *
+ * Page cache validation is based on "{flash,eeprom}_pageaddr"
+ * (holding the base address of the most recent cache fill
+ * operation). This variable is set to (unsigned long)-1L when the
+ * cache needs to be invalidated.
+ */
+ if (pagesize && paddr == *paddr_ptr) {
+ *value = cache_ptr[addr & (pagesize - 1)];
+ return 0;
+ }
+
+ if (pagesize) {
+ if (is_flash) {
+ cmd[2] = pagesize / 2 - 1;
+ u32_to_b3(cmd + 3, paddr / 2);
+ } else {
+ cmd[2] = pagesize - 1;
+ u32_to_b3(cmd + 3, paddr);
+ }
+ respsize = 3 + pagesize;
+ } else {
+ if (cmd[1] == MTYPE_FUSE_BITS) {
+ /*
+ * The mkI ICE has a bug where it doesn't read efuse correctly
+ * when reading it as a single byte @offset 2, while reading all
+ * fuses at once does work.
+ */
+ cmd[2] = 3 - 1;
+ u32_to_b3(cmd + 3, 0);
+ respsize = 3 + 3;
+ } else {
+ cmd[2] = 1 - 1;
+ u32_to_b3(cmd + 3, addr);
+ }
+ }
+
+ jtagmkI_send(pgm, cmd, 6);
+ if (jtagmkI_recv(pgm, resp, respsize) < 0)
+ return -1;
+
+ if (resp[respsize - 1] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_read_byte(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[respsize - 1]);
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+
+ if (pagesize) {
+ *paddr_ptr = paddr;
+ memcpy(cache_ptr, resp + 1, pagesize);
+ *value = cache_ptr[addr & (pagesize - 1)];
+ } else if (cmd[1] == MTYPE_FUSE_BITS) {
+ /* extract the desired fuse */
+ *value = resp[1 + addr];
+ } else
+ *value = resp[1];
+
+ return 0;
+}
+
+static int jtagmkI_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data)
+{
+ unsigned char cmd[6], datacmd[1 * 2 + 1];
+ unsigned char resp[1], writedata;
+ int len, need_progmode = 1;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_write_byte(.., %s, 0x%lx, ...)\n",
+ progname, mem->desc, addr);
+
+ writedata = data;
+ cmd[0] = CMD_WRITE_MEM;
+ if (strcmp(mem->desc, "flash") == 0) {
+ cmd[1] = MTYPE_SPM;
+ need_progmode = 0;
+ PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ cmd[1] = MTYPE_EEPROM;
+ need_progmode = 0;
+ PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+ } else if (strcmp(mem->desc, "lfuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 0;
+ } else if (strcmp(mem->desc, "hfuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 1;
+ } else if (strcmp(mem->desc, "efuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 2;
+ } else if (strcmp(mem->desc, "lock") == 0) {
+ cmd[1] = MTYPE_LOCK_BITS;
+ } else if (strcmp(mem->desc, "calibration") == 0) {
+ cmd[1] = MTYPE_OSCCAL_BYTE;
+ } else if (strcmp(mem->desc, "signature") == 0) {
+ cmd[1] = MTYPE_SIGN_JTAG;
+ }
+
+ if (need_progmode) {
+ if (jtagmkI_program_enable(pgm) < 0)
+ return -1;
+ } else {
+ if (jtagmkI_program_disable(pgm) < 0)
+ return -1;
+ }
+
+ cmd[2] = 1 - 1;
+ if (cmd[1] == MTYPE_SPM) {
+ /*
+ * Flash is word-addressed, but we cannot handle flash anyway
+ * here, as it needs to be written one page at a time...
+ */
+ u32_to_b3(cmd + 3, addr / 2);
+ } else {
+ u32_to_b3(cmd + 3, addr);
+ }
+ /* First part, send the write command. */
+ jtagmkI_send(pgm, cmd, 6);
+ if (jtagmkI_recv(pgm, resp, 1) < 0)
+ return -1;
+ if (resp[0] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_write_byte(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+
+ /* Now, send the data buffer. */
+ datacmd[0] = CMD_DATA;
+ if (cmd[1] == MTYPE_SPM) {
+ len = 3;
+ if ((addr & 1) != 0) {
+ datacmd[1] = 0;
+ datacmd[2] = writedata;
+ } else {
+ datacmd[1] = writedata;
+ datacmd[2] = 0;
+ }
+ } else {
+ len = 2;
+ datacmd[1] = writedata;
+ }
+ jtagmkI_send(pgm, datacmd, len);
+ if (jtagmkI_recv(pgm, resp, 1) < 0)
+ return -1;
+ if (resp[0] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_write_byte(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+
+ return 0;
+}
+
+
+/*
+ * Set the JTAG clock. The actual frequency is quite a bit of
+ * guesswork, based on the values claimed by AVR Studio. Inside the
+ * JTAG ICE, the value is the delay count of a delay loop between the
+ * JTAG clock edges. A count of 0 bypasses the delay loop.
+ *
+ * As the STK500 expresses it as a period length (and we actualy do
+ * program a period length as well), we rather call it by that name.
+ */
+static int jtagmkI_set_sck_period(PROGRAMMER * pgm, double v)
+{
+ unsigned char dur;
+
+ v = 1 / v; /* convert to frequency */
+ if (v >= 1e6)
+ dur = JTAG_BITRATE_1_MHz;
+ else if (v >= 499e3)
+ dur = JTAG_BITRATE_500_kHz;
+ else if (v >= 249e3)
+ dur = JTAG_BITRATE_250_kHz;
+ else
+ dur = JTAG_BITRATE_125_kHz;
+
+ return jtagmkI_setparm(pgm, PARM_CLOCK, dur);
+}
+
+
+/*
+ * Read an emulator parameter. The result is exactly one byte,
+ * multi-byte parameters get two different parameter names for
+ * their components.
+ */
+static int jtagmkI_getparm(PROGRAMMER * pgm, unsigned char parm,
+ unsigned char * value)
+{
+ unsigned char buf[2], resp[3];
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_getparm()\n", progname);
+
+ buf[0] = CMD_GET_PARAM;
+ buf[1] = parm;
+ if (verbose >= 2)
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_getparm(): "
+ "Sending get parameter command (parm 0x%02x): ",
+ progname, parm);
+ jtagmkI_send(pgm, buf, 2);
+
+ if (jtagmkI_recv(pgm, resp, 3) < 0)
+ return -1;
+ if (resp[0] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_getparm(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ return -1;
+ } else if (resp[2] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_getparm(): "
+ "unknown parameter 0x%02x\n",
+ progname, parm);
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK, value 0x%02x\n", resp[1]);
+ }
+
+ *value = resp[1];
+
+ return 0;
+}
+
+/*
+ * Write an emulator parameter.
+ */
+static int jtagmkI_setparm(PROGRAMMER * pgm, unsigned char parm,
+ unsigned char value)
+{
+ unsigned char buf[3], resp[2];
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_setparm()\n", progname);
+
+ buf[0] = CMD_SET_PARAM;
+ buf[1] = parm;
+ buf[2] = value;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkI_setparm(): "
+ "Sending set parameter command (parm 0x%02x): ",
+ progname, parm);
+ jtagmkI_send(pgm, buf, 3);
+ if (jtagmkI_recv(pgm, resp, 2) < 0)
+ return -1;
+ if (resp[0] != RESP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkI_setparm(): "
+ "timeout/error communicating with programmer (resp %c)\n",
+ progname, resp[0]);
+ return -1;
+ } else {
+ if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "OK\n");
+ }
+
+ return 0;
+}
+
+
+static void jtagmkI_display(PROGRAMMER * pgm, const char * p)
+{
+
+ unsigned char hw, fw;
+
+ if (jtagmkI_getparm(pgm, PARM_HW_VERSION, &hw) < 0 ||
+ jtagmkI_getparm(pgm, PARM_SW_VERSION, &fw) < 0)
+ return;
+
+ avrdude_message(MSG_INFO, "%sICE hardware version: 0x%02x\n", p, hw);
+ avrdude_message(MSG_INFO, "%sICE firmware version: 0x%02x\n", p, fw);
+
+ jtagmkI_print_parms1(pgm, p);
+
+ return;
+}
+
+
+static void jtagmkI_print_parms1(PROGRAMMER * pgm, const char * p)
+{
+ unsigned char vtarget, jtag_clock;
+ const char *clkstr;
+ double clk;
+
+ if (jtagmkI_getparm(pgm, PARM_OCD_VTARGET, &vtarget) < 0 ||
+ jtagmkI_getparm(pgm, PARM_CLOCK, &jtag_clock) < 0)
+ return;
+
+ switch ((unsigned)jtag_clock) {
+ case JTAG_BITRATE_1_MHz:
+ clkstr = "1 MHz";
+ clk = 1e6;
+ break;
+
+ case JTAG_BITRATE_500_kHz:
+ clkstr = "500 kHz";
+ clk = 500e3;
+ break;
+
+ case JTAG_BITRATE_250_kHz:
+ clkstr = "250 kHz";
+ clk = 250e3;
+ break;
+
+ case JTAG_BITRATE_125_kHz:
+ clkstr = "125 kHz";
+ clk = 125e3;
+ break;
+
+ default:
+ clkstr = "???";
+ clk = 1e6;
+ }
+
+ avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p,
+ 6.25 * (unsigned)vtarget / 255.0);
+ avrdude_message(MSG_INFO, "%sJTAG clock : %s (%.1f us)\n", p, clkstr,
+ 1.0e6 / clk);
+
+ return;
+}
+
+
+static void jtagmkI_print_parms(PROGRAMMER * pgm)
+{
+ jtagmkI_print_parms1(pgm, "");
+}
+
+const char jtagmkI_desc[] = "Atmel JTAG ICE mkI";
+
+void jtagmkI_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "JTAGMKI");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = jtagmkI_initialize;
+ pgm->display = jtagmkI_display;
+ pgm->enable = jtagmkI_enable;
+ pgm->disable = jtagmkI_disable;
+ pgm->program_enable = jtagmkI_program_enable_dummy;
+ pgm->chip_erase = jtagmkI_chip_erase;
+ pgm->open = jtagmkI_open;
+ pgm->close = jtagmkI_close;
+ pgm->read_byte = jtagmkI_read_byte;
+ pgm->write_byte = jtagmkI_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = jtagmkI_paged_write;
+ pgm->paged_load = jtagmkI_paged_load;
+ pgm->print_parms = jtagmkI_print_parms;
+ pgm->set_sck_period = jtagmkI_set_sck_period;
+ pgm->setup = jtagmkI_setup;
+ pgm->teardown = jtagmkI_teardown;
+ pgm->page_size = 256;
+}
diff --git a/xs/src/avrdude/jtagmkI.h b/xs/src/avrdude/jtagmkI.h
new file mode 100644
index 000000000..fbc0d161d
--- /dev/null
+++ b/xs/src/avrdude/jtagmkI.h
@@ -0,0 +1,36 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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 jtagmkI_h
+#define jtagmkI_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char jtagmkI_desc[];
+void jtagmkI_initpgm (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/xs/src/avrdude/jtagmkII.c b/xs/src/avrdude/jtagmkII.c
new file mode 100644
index 000000000..78c412ce6
--- /dev/null
+++ b/xs/src/avrdude/jtagmkII.c
@@ -0,0 +1,4023 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2005-2007 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * Derived from stk500 code which is:
+ * Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2005 Erik Walthinsen
+ *
+ *
+ * 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 Atmel JTAG ICE mkII programmer
+ *
+ * The AVR Dragon also uses the same protocol, so it is handled here
+ * as well.
+ */
+
+#include "ac_cfg.h"
+
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "crc16.h"
+#include "jtagmkII.h"
+#include "jtagmkII_private.h"
+#include "usbdevs.h"
+
+/*
+ * Private data for this programmer.
+ */
+struct pdata
+{
+ unsigned short command_sequence; /* Next cmd seqno to issue. */
+
+ /*
+ * See jtagmkII_read_byte() for an explanation of the flash and
+ * EEPROM page caches.
+ */
+ unsigned char *flash_pagecache;
+ unsigned long flash_pageaddr;
+ unsigned int flash_pagesize;
+
+ unsigned char *eeprom_pagecache;
+ unsigned long eeprom_pageaddr;
+ unsigned int eeprom_pagesize;
+
+ int prog_enabled; /* Cached value of PROGRAMMING status. */
+ unsigned char serno[6]; /* JTAG ICE serial number. */
+
+ /* JTAG chain stuff */
+ unsigned char jtagchain[4];
+
+ /* The length of the device descriptor is firmware-dependent. */
+ size_t device_descriptor_length;
+
+ /* Start address of Xmega boot area */
+ unsigned long boot_start;
+
+ /* Major firmware version (needed for Xmega programming) */
+ unsigned int fwver;
+};
+
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
+/*
+ * The OCDEN fuse is bit 7 of the high fuse (hfuse). In order to
+ * perform memory operations on MTYPE_SPM and MTYPE_EEPROM, OCDEN
+ * needs to be programmed.
+ *
+ * OCDEN should probably rather be defined via the configuration, but
+ * if this ever changes to a different fuse byte for one MCU, quite
+ * some code here needs to be generalized anyway.
+ */
+#define OCDEN (1 << 7)
+
+#define RC(x) { x, #x },
+static struct {
+ unsigned int code;
+ const char *descr;
+} jtagresults[] = {
+ RC(RSP_DEBUGWIRE_SYNC_FAILED)
+ RC(RSP_FAILED)
+ RC(RSP_ILLEGAL_BREAKPOINT)
+ RC(RSP_ILLEGAL_COMMAND)
+ RC(RSP_ILLEGAL_EMULATOR_MODE)
+ RC(RSP_ILLEGAL_JTAG_ID)
+ RC(RSP_ILLEGAL_MCU_STATE)
+ RC(RSP_ILLEGAL_MEMORY_TYPE)
+ RC(RSP_ILLEGAL_MEMORY_RANGE)
+ RC(RSP_ILLEGAL_PARAMETER)
+ RC(RSP_ILLEGAL_POWER_STATE)
+ RC(RSP_ILLEGAL_VALUE)
+ RC(RSP_NO_TARGET_POWER)
+ RC(RSP_SET_N_PARAMETERS)
+};
+
+/*
+ * pgm->flag is marked as "for private use of the programmer".
+ * The following defines this programmer's use of that field.
+ */
+#define PGM_FL_IS_DW (0x0001)
+#define PGM_FL_IS_PDI (0x0002)
+#define PGM_FL_IS_JTAG (0x0004)
+
+static int jtagmkII_open(PROGRAMMER * pgm, char * port);
+
+static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p);
+static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p);
+static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value);
+static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data);
+static int jtagmkII_reset(PROGRAMMER * pgm, unsigned char flags);
+static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v);
+static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
+ unsigned char * value);
+static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p);
+static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes);
+static unsigned char jtagmkII_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr);
+static unsigned int jtagmkII_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr);
+
+// AVR32
+#define ERROR_SAB 0xFFFFFFFF
+
+static int jtagmkII_open32(PROGRAMMER * pgm, char * port);
+static void jtagmkII_close32(PROGRAMMER * pgm);
+static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags);
+static int jtagmkII_initialize32(PROGRAMMER * pgm, AVRPART * p);
+static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p);
+static unsigned long jtagmkII_read_SABaddr(PROGRAMMER * pgm, unsigned long addr,
+ unsigned int prefix); // ERROR_SAB illegal
+static int jtagmkII_write_SABaddr(PROGRAMMER * pgm, unsigned long addr,
+ unsigned int prefix, unsigned long val);
+static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val,
+ unsigned char ret1, unsigned char ret2);
+static int jtagmkII_smc_init32(PROGRAMMER * pgm);
+static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes);
+static int jtagmkII_flash_lock32(PROGRAMMER * pgm, unsigned char lock,
+ unsigned int page);
+static int jtagmkII_flash_erase32(PROGRAMMER * pgm, unsigned int page);
+static int jtagmkII_flash_write_page32(PROGRAMMER * pgm, unsigned int page);
+static int jtagmkII_flash_clear_pagebuffer32(PROGRAMMER * pgm);
+static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes);
+
+void jtagmkII_setup(PROGRAMMER * pgm)
+{
+ if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_setup(): Out of memory allocating private data\n",
+ progname);
+ exit(1);
+ }
+ memset(pgm->cookie, 0, sizeof(struct pdata));
+}
+
+void jtagmkII_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+}
+
+
+static unsigned long
+b4_to_u32(unsigned char *b)
+{
+ unsigned long l;
+ l = b[0];
+ l += (unsigned)b[1] << 8;
+ l += (unsigned)b[2] << 16;
+ l += (unsigned)b[3] << 24;
+
+ return l;
+}
+static unsigned long
+b4_to_u32r(unsigned char *b)
+{
+ unsigned long l;
+ l = b[3];
+ l += (unsigned)b[2] << 8;
+ l += (unsigned)b[1] << 16;
+ l += (unsigned)b[0] << 24;
+
+ return l;
+}
+
+static void
+u32_to_b4(unsigned char *b, unsigned long l)
+{
+ b[0] = l & 0xff;
+ b[1] = (l >> 8) & 0xff;
+ b[2] = (l >> 16) & 0xff;
+ b[3] = (l >> 24) & 0xff;
+}
+static void
+u32_to_b4r(unsigned char *b, unsigned long l)
+{
+ b[3] = l & 0xff;
+ b[2] = (l >> 8) & 0xff;
+ b[1] = (l >> 16) & 0xff;
+ b[0] = (l >> 24) & 0xff;
+}
+
+static unsigned short
+b2_to_u16(unsigned char *b)
+{
+ unsigned short l;
+ l = b[0];
+ l += (unsigned)b[1] << 8;
+
+ return l;
+}
+
+static void
+u16_to_b2(unsigned char *b, unsigned short l)
+{
+ b[0] = l & 0xff;
+ b[1] = (l >> 8) & 0xff;
+}
+
+static const char *
+jtagmkII_get_rc(unsigned int rc)
+{
+ int i;
+ static char msg[50];
+
+ for (i = 0; i < sizeof jtagresults / sizeof jtagresults[0]; i++)
+ if (jtagresults[i].code == rc)
+ return jtagresults[i].descr;
+
+ sprintf(msg, "Unknown JTAG ICE mkII result code 0x%02x", rc);
+ return msg;
+}
+
+
+static void jtagmkII_print_memory(unsigned char *b, size_t s)
+{
+ int i;
+
+ if (s < 2)
+ return;
+
+ for (i = 0; i < s - 1; i++) {
+ avrdude_message(MSG_INFO, "0x%02x ", b[i + 1]);
+ if (i % 16 == 15)
+ putc('\n', stderr);
+ else
+ putc(' ', stderr);
+ }
+ if (i % 16 != 0)
+ putc('\n', stderr);
+}
+
+static void jtagmkII_prmsg(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ int i;
+
+ if (verbose >= 4) {
+ avrdude_message(MSG_TRACE, "Raw message:\n");
+
+ for (i = 0; i < len; i++) {
+ avrdude_message(MSG_TRACE, "0x%02x", data[i]);
+ if (i % 16 == 15)
+ putc('\n', stderr);
+ else
+ putc(' ', stderr);
+ }
+ if (i % 16 != 0)
+ putc('\n', stderr);
+ }
+
+ switch (data[0]) {
+ case RSP_OK:
+ avrdude_message(MSG_INFO, "OK\n");
+ break;
+
+ case RSP_FAILED:
+ avrdude_message(MSG_INFO, "FAILED\n");
+ break;
+
+ case RSP_ILLEGAL_BREAKPOINT:
+ avrdude_message(MSG_INFO, "Illegal breakpoint\n");
+ break;
+
+ case RSP_ILLEGAL_COMMAND:
+ avrdude_message(MSG_INFO, "Illegal command\n");
+ break;
+
+ case RSP_ILLEGAL_EMULATOR_MODE:
+ avrdude_message(MSG_INFO, "Illegal emulator mode");
+ if (len > 1)
+ switch (data[1]) {
+ case EMULATOR_MODE_DEBUGWIRE: avrdude_message(MSG_INFO, ": DebugWire"); break;
+ case EMULATOR_MODE_JTAG: avrdude_message(MSG_INFO, ": JTAG"); break;
+ case EMULATOR_MODE_HV: avrdude_message(MSG_INFO, ": HVSP/PP"); break;
+ case EMULATOR_MODE_SPI: avrdude_message(MSG_INFO, ": SPI"); break;
+ case EMULATOR_MODE_JTAG_XMEGA: avrdude_message(MSG_INFO, ": JTAG/Xmega"); break;
+ }
+ putc('\n', stderr);
+ break;
+
+ case RSP_ILLEGAL_JTAG_ID:
+ avrdude_message(MSG_INFO, "Illegal JTAG ID\n");
+ break;
+
+ case RSP_ILLEGAL_MCU_STATE:
+ avrdude_message(MSG_INFO, "Illegal MCU state");
+ if (len > 1)
+ switch (data[1]) {
+ case STOPPED: avrdude_message(MSG_INFO, ": Stopped"); break;
+ case RUNNING: avrdude_message(MSG_INFO, ": Running"); break;
+ case PROGRAMMING: avrdude_message(MSG_INFO, ": Programming"); break;
+ }
+ putc('\n', stderr);
+ break;
+
+ case RSP_ILLEGAL_MEMORY_TYPE:
+ avrdude_message(MSG_INFO, "Illegal memory type\n");
+ break;
+
+ case RSP_ILLEGAL_MEMORY_RANGE:
+ avrdude_message(MSG_INFO, "Illegal memory range\n");
+ break;
+
+ case RSP_ILLEGAL_PARAMETER:
+ avrdude_message(MSG_INFO, "Illegal parameter\n");
+ break;
+
+ case RSP_ILLEGAL_POWER_STATE:
+ avrdude_message(MSG_INFO, "Illegal power state\n");
+ break;
+
+ case RSP_ILLEGAL_VALUE:
+ avrdude_message(MSG_INFO, "Illegal value\n");
+ break;
+
+ case RSP_NO_TARGET_POWER:
+ avrdude_message(MSG_INFO, "No target power\n");
+ break;
+
+ case RSP_SIGN_ON:
+ avrdude_message(MSG_INFO, "Sign-on succeeded\n");
+ /* Sign-on data will be printed below anyway. */
+ break;
+
+ case RSP_MEMORY:
+ avrdude_message(MSG_INFO, "memory contents:\n");
+ jtagmkII_print_memory(data, len);
+ break;
+
+ case RSP_PARAMETER:
+ avrdude_message(MSG_INFO, "parameter values:\n");
+ jtagmkII_print_memory(data, len);
+ break;
+
+ case RSP_SPI_DATA:
+ avrdude_message(MSG_INFO, "SPI data returned:\n");
+ for (i = 1; i < len; i++)
+ avrdude_message(MSG_INFO, "0x%02x ", data[i]);
+ putc('\n', stderr);
+ break;
+
+ case EVT_BREAK:
+ avrdude_message(MSG_INFO, "BREAK event");
+ if (len >= 6) {
+ avrdude_message(MSG_INFO, ", PC = 0x%lx, reason ", b4_to_u32(data + 1));
+ switch (data[5]) {
+ case 0x00:
+ avrdude_message(MSG_INFO, "unspecified");
+ break;
+ case 0x01:
+ avrdude_message(MSG_INFO, "program break");
+ break;
+ case 0x02:
+ avrdude_message(MSG_INFO, "data break PDSB");
+ break;
+ case 0x03:
+ avrdude_message(MSG_INFO, "data break PDMSB");
+ break;
+ default:
+ avrdude_message(MSG_INFO, "unknown: 0x%02x", data[5]);
+ }
+ }
+ putc('\n', stderr);
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "unknown message 0x%02x\n", data[0]);
+ }
+
+ putc('\n', stderr);
+}
+
+
+int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ unsigned char *buf;
+
+ avrdude_message(MSG_DEBUG, "\n%s: jtagmkII_send(): sending %lu bytes\n",
+ progname, (unsigned long)len);
+
+ if ((buf = malloc(len + 10)) == NULL)
+ {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_send(): out of memory",
+ progname);
+ return -1;
+ }
+
+ buf[0] = MESSAGE_START;
+ u16_to_b2(buf + 1, PDATA(pgm)->command_sequence);
+ u32_to_b4(buf + 3, len);
+ buf[7] = TOKEN;
+ memcpy(buf + 8, data, len);
+
+ crcappend(buf, len + 8);
+
+ if (serial_send(&pgm->fd, buf, len + 10) != 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_send(): failed to send command to serial port\n",
+ progname);
+ free(buf);
+ return -1;
+ }
+
+ free(buf);
+
+ return 0;
+}
+
+
+static int jtagmkII_drain(PROGRAMMER * pgm, int display)
+{
+ return serial_drain(&pgm->fd, display);
+}
+
+
+/*
+ * Receive one frame, return it in *msg. Received sequence number is
+ * returned in seqno. Any valid frame will be returned, regardless
+ * whether it matches the expected sequence number, including event
+ * notification frames (seqno == 0xffff).
+ *
+ * Caller must eventually free the buffer.
+ */
+static int jtagmkII_recv_frame(PROGRAMMER * pgm, unsigned char **msg,
+ unsigned short * seqno) {
+ enum states { sSTART,
+ /* NB: do NOT change the sequence of the following: */
+ sSEQNUM1, sSEQNUM2,
+ sSIZE1, sSIZE2, sSIZE3, sSIZE4,
+ sTOKEN,
+ sDATA,
+ sCSUM1, sCSUM2,
+ /* end NB */
+ sDONE
+ } state = sSTART;
+ unsigned long msglen = 0, l = 0;
+ int headeridx = 0;
+ int timeout = 0;
+ int ignorpkt = 0;
+ int rv;
+ unsigned char c, *buf = NULL, header[8];
+ unsigned short r_seqno = 0;
+ unsigned short checksum = 0;
+
+ struct timeval tv;
+ double timeoutval = 100; /* seconds */
+ double tstart, tnow;
+
+ avrdude_message(MSG_TRACE, "%s: jtagmkII_recv():\n", progname);
+
+ gettimeofday(&tv, NULL);
+ tstart = tv.tv_sec;
+
+ while ( (state != sDONE ) && (!timeout) ) {
+ if (state == sDATA) {
+ rv = 0;
+ if (ignorpkt) {
+ /* skip packet's contents */
+ for(l = 0; l < msglen; l++)
+ rv += serial_recv(&pgm->fd, &c, 1);
+ } else {
+ rv += serial_recv(&pgm->fd, buf + 8, msglen);
+ }
+ if (rv != 0) {
+ timedout:
+ /* timeout in receive */
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_recv(): Timeout receiving packet\n",
+ progname);
+ free(buf);
+ return -1;
+ }
+ } else {
+ if (serial_recv(&pgm->fd, &c, 1) != 0)
+ goto timedout;
+ }
+ checksum ^= c;
+
+ if (state < sDATA)
+ header[headeridx++] = c;
+
+ switch (state) {
+ case sSTART:
+ if (c == MESSAGE_START) {
+ state = sSEQNUM1;
+ } else {
+ headeridx = 0;
+ }
+ break;
+ case sSEQNUM1:
+ case sSEQNUM2:
+ r_seqno >>= 8;
+ r_seqno |= ((unsigned)c << 8);
+ state++;
+ break;
+ case sSIZE1:
+ case sSIZE2:
+ case sSIZE3:
+ case sSIZE4:
+ msglen >>= 8;
+ msglen |= ((unsigned)c << 24);
+ state++;
+ break;
+ case sTOKEN:
+ if (c == TOKEN) {
+ state = sDATA;
+ if (msglen > MAX_MESSAGE) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): msglen %lu exceeds max message "
+ "size %u, ignoring message\n",
+ progname, msglen, MAX_MESSAGE);
+ state = sSTART;
+ headeridx = 0;
+ } else if ((buf = malloc(msglen + 10)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): out of memory\n",
+ progname);
+ ignorpkt++;
+ } else {
+ memcpy(buf, header, 8);
+ }
+ } else {
+ state = sSTART;
+ headeridx = 0;
+ }
+ break;
+ case sDATA:
+ /* The entire payload has been read above. */
+ l = msglen + 8;
+ state = sCSUM1;
+ break;
+ case sCSUM1:
+ case sCSUM2:
+ buf[l++] = c;
+ if (state == sCSUM2) {
+ if (crcverify(buf, msglen + 10)) {
+ if (verbose >= 9)
+ avrdude_message(MSG_TRACE2, "%s: jtagmkII_recv(): CRC OK",
+ progname);
+ state = sDONE;
+ } else {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): checksum error\n",
+ progname);
+ free(buf);
+ return -4;
+ }
+ } else
+ state++;
+ break;
+ default:
+ avrdude_message(MSG_INFO, "%s: jtagmkII_recv(): unknown state\n",
+ progname);
+ free(buf);
+ return -5;
+ }
+
+ gettimeofday(&tv, NULL);
+ tnow = tv.tv_sec;
+ if (tnow - tstart > timeoutval) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_recv_frame(): timeout\n",
+ progname);
+ return -1;
+ }
+
+ }
+ avrdude_message(MSG_DEBUG, "\n");
+
+ *seqno = r_seqno;
+ *msg = buf;
+
+ return msglen;
+}
+
+int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg) {
+ unsigned short r_seqno;
+ int rv;
+
+ for (;;) {
+ if ((rv = jtagmkII_recv_frame(pgm, msg, &r_seqno)) <= 0)
+ return rv;
+ avrdude_message(MSG_DEBUG, "%s: jtagmkII_recv(): "
+ "Got message seqno %d (command_sequence == %d)\n",
+ progname, r_seqno, PDATA(pgm)->command_sequence);
+ if (r_seqno == PDATA(pgm)->command_sequence) {
+ if (++(PDATA(pgm)->command_sequence) == 0xffff)
+ PDATA(pgm)->command_sequence = 0;
+ /*
+ * We move the payload to the beginning of the buffer, to make
+ * the job easier for the caller. We have to return the
+ * original pointer though, as the caller must free() it.
+ */
+ memmove(*msg, *msg + 8, rv);
+
+ if (verbose == 4)
+ {
+ int i = rv;
+ unsigned char *p = *msg;
+ avrdude_message(MSG_TRACE, "%s: Recv: ", progname);
+
+ while (i) {
+ unsigned char c = *p;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE, "%c ", c);
+ }
+ else {
+ avrdude_message(MSG_TRACE, ". ");
+ }
+ avrdude_message(MSG_TRACE, "[%02x] ", c);
+
+ p++;
+ i--;
+ }
+ avrdude_message(MSG_TRACE, "\n");
+ }
+ return rv;
+ }
+ if (r_seqno == 0xffff) {
+ avrdude_message(MSG_DEBUG, "%s: jtagmkII_recv(): got asynchronous event\n",
+ progname);
+ } else {
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_recv(): "
+ "got wrong sequence number, %u != %u\n",
+ progname, r_seqno, PDATA(pgm)->command_sequence);
+ }
+ free(*msg);
+ }
+}
+
+
+int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
+ int tries;
+#define MAXTRIES 33
+ unsigned char buf[3], *resp, c = 0xff;
+ int status;
+ unsigned int fwver, hwver;
+ int is_dragon;
+
+ avrdude_message(MSG_DEBUG, "%s: jtagmkII_getsync()\n", progname);
+
+ if (strncmp(pgm->type, "JTAG", strlen("JTAG")) == 0) {
+ is_dragon = 0;
+ } else if (strncmp(pgm->type, "DRAGON", strlen("DRAGON")) == 0) {
+ is_dragon = 1;
+ } else {
+ avrdude_message(MSG_INFO, "%s: Programmer is neither JTAG ICE mkII nor AVR Dragon\n",
+ progname);
+ return -1;
+ }
+ for (tries = 0; tries < MAXTRIES; tries++) {
+
+ /* Get the sign-on information. */
+ buf[0] = CMND_GET_SIGN_ON;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getsync(): Sending sign-on command: ",
+ progname);
+ jtagmkII_send(pgm, buf, 1);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): sign-on command: "
+ "status %d\n",
+ progname, status);
+ } else if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+
+ if (status > 0) {
+ if ((c = resp[0]) == RSP_SIGN_ON) {
+ fwver = ((unsigned)resp[8] << 8) | (unsigned)resp[7];
+ PDATA(pgm)->fwver = fwver;
+ hwver = (unsigned)resp[9];
+ memcpy(PDATA(pgm)->serno, resp + 10, 6);
+ if (status > 17) {
+ avrdude_message(MSG_NOTICE, "JTAG ICE mkII sign-on message:\n");
+ avrdude_message(MSG_NOTICE, "Communications protocol version: %u\n",
+ (unsigned)resp[1]);
+ avrdude_message(MSG_NOTICE, "M_MCU:\n");
+ avrdude_message(MSG_NOTICE, " boot-loader FW version: %u\n",
+ (unsigned)resp[2]);
+ avrdude_message(MSG_NOTICE, " firmware version: %u.%02u\n",
+ (unsigned)resp[4], (unsigned)resp[3]);
+ avrdude_message(MSG_NOTICE, " hardware version: %u\n",
+ (unsigned)resp[5]);
+ avrdude_message(MSG_NOTICE, "S_MCU:\n");
+ avrdude_message(MSG_NOTICE, " boot-loader FW version: %u\n",
+ (unsigned)resp[6]);
+ avrdude_message(MSG_NOTICE, " firmware version: %u.%02u\n",
+ (unsigned)resp[8], (unsigned)resp[7]);
+ avrdude_message(MSG_NOTICE, " hardware version: %u\n",
+ (unsigned)resp[9]);
+ avrdude_message(MSG_NOTICE, "Serial number: "
+ "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]);
+ resp[status - 1] = '\0';
+ avrdude_message(MSG_NOTICE, "Device ID: %s\n",
+ resp + 16);
+ }
+ break;
+ }
+ free(resp);
+ }
+ }
+ if (tries >= MAXTRIES) {
+ if (status <= 0)
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ else
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
+ "bad response to sign-on command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ return -1;
+ }
+
+ PDATA(pgm)->device_descriptor_length = sizeof(struct device_descriptor);
+ /*
+ * There's no official documentation from Atmel about what firmware
+ * revision matches what device descriptor length. The algorithm
+ * below has been found empirically.
+ */
+#define FWVER(maj, min) ((maj << 8) | (min))
+ if (!is_dragon && fwver < FWVER(3, 16)) {
+ PDATA(pgm)->device_descriptor_length -= 2;
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
+ "S_MCU firmware version might be too old to work correctly\n",
+ progname);
+ } else if (!is_dragon && fwver < FWVER(4, 0)) {
+ PDATA(pgm)->device_descriptor_length -= 2;
+ }
+ if (mode != EMULATOR_MODE_SPI)
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getsync(): Using a %u-byte device descriptor\n",
+ progname, (unsigned)PDATA(pgm)->device_descriptor_length);
+ if (mode == EMULATOR_MODE_SPI) {
+ PDATA(pgm)->device_descriptor_length = 0;
+ if (!is_dragon && fwver < FWVER(4, 14)) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): ISP functionality requires firmware "
+ "version >= 4.14\n",
+ progname);
+ return -1;
+ }
+ }
+ if (mode == EMULATOR_MODE_PDI || mode == EMULATOR_MODE_JTAG_XMEGA) {
+ if (!is_dragon && mode == EMULATOR_MODE_PDI && hwver < 1) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): Xmega PDI support requires hardware "
+ "revision >= 1\n",
+ progname);
+ return -1;
+ }
+ if (!is_dragon && fwver < FWVER(5, 37)) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): Xmega support requires firmware "
+ "version >= 5.37\n",
+ progname);
+ return -1;
+ }
+ if (is_dragon && fwver < FWVER(6, 11)) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): Xmega support requires firmware "
+ "version >= 6.11\n",
+ progname);
+ return -1;
+ }
+ }
+#undef FWVER
+
+ if(mode < 0) return 0; // for AVR32
+
+ tries = 0;
+retry:
+ /* Turn the ICE into JTAG or ISP mode as requested. */
+ buf[0] = mode;
+ if (jtagmkII_setparm(pgm, PAR_EMULATOR_MODE, buf) < 0) {
+ if (mode == EMULATOR_MODE_SPI) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
+ "ISP activation failed, trying debugWire\n",
+ progname);
+ buf[0] = EMULATOR_MODE_DEBUGWIRE;
+ if (jtagmkII_setparm(pgm, PAR_EMULATOR_MODE, buf) < 0)
+ return -1;
+ else {
+ /*
+ * We are supposed to send a CMND_RESET with the
+ * MONCOM_DISABLE flag set right now, and then
+ * restart from scratch.
+ *
+ * As this will make the ICE sign off from USB, so
+ * we risk losing our USB connection, it's easier
+ * to instruct the user to restart AVRDUDE rather
+ * than trying to cope with all this inside the
+ * program.
+ */
+ (void)jtagmkII_reset(pgm, 0x04);
+ if (tries++ > 3) {
+ avrdude_message(MSG_INFO, "%s: Failed to return from debugWIRE to ISP.\n",
+ progname);
+ return -1;
+ }
+ avrdude_message(MSG_INFO, "%s: Target prepared for ISP, signed off.\n"
+ "%s: Now retrying without power-cycling the target.\n",
+ progname, progname);
+ goto retry;
+ }
+ } else {
+ return -1;
+ }
+ }
+
+ /* GET SYNC forces the target into STOPPED mode */
+ buf[0] = CMND_GET_SYNC;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getsync(): Sending get sync command: ",
+ progname);
+ jtagmkII_send(pgm, buf, 1);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return -1;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ free(resp);
+ if (c != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getsync(): "
+ "bad response to set parameter command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * issue the 'chip erase' command to the AVR device
+ */
+static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ int status, len;
+ unsigned char buf[6], *resp, c;
+
+ if (p->flags & AVRPART_HAS_PDI) {
+ buf[0] = CMND_XMEGA_ERASE;
+ buf[1] = XMEGA_ERASE_CHIP;
+ memset(buf + 2, 0, 4); /* address of area to be erased */
+ len = 6;
+ } else {
+ buf[0] = CMND_CHIP_ERASE;
+ len = 1;
+ }
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_chip_erase(): Sending %schip erase command: ",
+ progname,
+ (p->flags & AVRPART_HAS_PDI)? "Xmega ": "");
+ jtagmkII_send(pgm, buf, len);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_chip_erase(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return -1;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ free(resp);
+ if (c != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_chip_erase(): "
+ "bad response to chip erase command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ return -1;
+ }
+
+ if (!(p->flags & AVRPART_HAS_PDI))
+ pgm->initialize(pgm, p);
+
+ return 0;
+}
+
+/*
+ * There is no chip erase functionality in debugWire mode.
+ */
+static int jtagmkII_chip_erase_dw(PROGRAMMER * pgm, AVRPART * p)
+{
+
+ avrdude_message(MSG_INFO, "%s: Chip erase not supported in debugWire mode\n",
+ progname);
+
+ return 0;
+}
+
+static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
+{
+ int status;
+ unsigned char *resp, c;
+ LNODEID ln;
+ AVRMEM * m;
+ struct {
+ unsigned char cmd;
+ struct device_descriptor dd;
+ } sendbuf;
+
+ memset(&sendbuf, 0, sizeof sendbuf);
+ sendbuf.cmd = CMND_SET_DEVICE_DESCRIPTOR;
+ sendbuf.dd.ucSPMCRAddress = p->spmcr;
+ sendbuf.dd.ucRAMPZAddress = p->rampz;
+ sendbuf.dd.ucIDRAddress = p->idr;
+ u16_to_b2(sendbuf.dd.EECRAddress, p->eecr);
+ sendbuf.dd.ucAllowFullPageBitstream =
+ (p->flags & AVRPART_ALLOWFULLPAGEBITSTREAM) != 0;
+ sendbuf.dd.EnablePageProgramming =
+ (p->flags & AVRPART_ENABLEPAGEPROGRAMMING) != 0;
+ for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
+ m = ldata(ln);
+ if (strcmp(m->desc, "flash") == 0) {
+ if (m->page_size > 256)
+ PDATA(pgm)->flash_pagesize = 256;
+ else
+ PDATA(pgm)->flash_pagesize = m->page_size;
+ u32_to_b4(sendbuf.dd.ulFlashSize, m->size);
+ u16_to_b2(sendbuf.dd.uiFlashPageSize, m->page_size);
+ u16_to_b2(sendbuf.dd.uiFlashpages, m->size / m->page_size);
+ if (p->flags & AVRPART_HAS_DW) {
+ memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE);
+ memcpy(sendbuf.dd.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE);
+ }
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ sendbuf.dd.ucEepromPageSize = PDATA(pgm)->eeprom_pagesize = m->page_size;
+ }
+ }
+ sendbuf.dd.ucCacheType =
+ (p->flags & AVRPART_HAS_PDI)? 0x02 /* ATxmega */: 0x00;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_set_devdescr(): "
+ "Sending set device descriptor command: ",
+ progname);
+ jtagmkII_send(pgm, (unsigned char *)&sendbuf,
+ PDATA(pgm)->device_descriptor_length + sizeof(unsigned char));
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_set_devdescr(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ free(resp);
+ if (c != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_set_devdescr(): "
+ "bad response to set device descriptor command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ }
+}
+
+static void jtagmkII_set_xmega_params(PROGRAMMER * pgm, AVRPART * p)
+{
+ int status;
+ unsigned char *resp, c;
+ LNODEID ln;
+ AVRMEM * m;
+ struct {
+ unsigned char cmd;
+ struct xmega_device_desc dd;
+ } sendbuf;
+
+ memset(&sendbuf, 0, sizeof sendbuf);
+ sendbuf.cmd = CMND_SET_XMEGA_PARAMS;
+ u16_to_b2(sendbuf.dd.whatever, 0x0002);
+ sendbuf.dd.datalen = 47;
+ u16_to_b2(sendbuf.dd.nvm_base_addr, p->nvm_base);
+ u16_to_b2(sendbuf.dd.mcu_base_addr, p->mcu_base);
+
+ for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
+ m = ldata(ln);
+ if (strcmp(m->desc, "flash") == 0) {
+ if (m->page_size > 256)
+ PDATA(pgm)->flash_pagesize = 256;
+ else
+ PDATA(pgm)->flash_pagesize = m->page_size;
+ u16_to_b2(sendbuf.dd.flash_page_size, m->page_size);
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ sendbuf.dd.eeprom_page_size = m->page_size;
+ u16_to_b2(sendbuf.dd.eeprom_size, m->size);
+ u32_to_b4(sendbuf.dd.nvm_eeprom_offset, m->offset);
+ } else if (strcmp(m->desc, "application") == 0) {
+ u32_to_b4(sendbuf.dd.app_size, m->size);
+ u32_to_b4(sendbuf.dd.nvm_app_offset, m->offset);
+ } else if (strcmp(m->desc, "boot") == 0) {
+ u16_to_b2(sendbuf.dd.boot_size, m->size);
+ u32_to_b4(sendbuf.dd.nvm_boot_offset, m->offset);
+ } else if (strcmp(m->desc, "fuse1") == 0) {
+ u32_to_b4(sendbuf.dd.nvm_fuse_offset, m->offset & ~7);
+ } else if (strncmp(m->desc, "lock", 4) == 0) {
+ u32_to_b4(sendbuf.dd.nvm_lock_offset, m->offset);
+ } else if (strcmp(m->desc, "usersig") == 0) {
+ u32_to_b4(sendbuf.dd.nvm_user_sig_offset, m->offset);
+ } else if (strcmp(m->desc, "prodsig") == 0) {
+ u32_to_b4(sendbuf.dd.nvm_prod_sig_offset, m->offset);
+ } else if (strcmp(m->desc, "data") == 0) {
+ u32_to_b4(sendbuf.dd.nvm_data_offset, m->offset);
+ }
+ }
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_set_xmega_params(): "
+ "Sending set Xmega params command: ",
+ progname);
+ jtagmkII_send(pgm, (unsigned char *)&sendbuf, sizeof sendbuf);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_set_xmega_params(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ free(resp);
+ if (c != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_set_xmega_params(): "
+ "bad response to set device descriptor command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ }
+}
+
+/*
+ * Reset the target.
+ */
+static int jtagmkII_reset(PROGRAMMER * pgm, unsigned char flags)
+{
+ int status;
+ unsigned char buf[2], *resp, c;
+
+ /*
+ * In debugWire mode, don't reset. Do a forced stop, and tell the
+ * ICE to stop any timers, too.
+ */
+ if (pgm->flag & PGM_FL_IS_DW) {
+ unsigned char parm[] = { 0 };
+
+ (void)jtagmkII_setparm(pgm, PAR_TIMERS_RUNNING, parm);
+ }
+
+ buf[0] = (pgm->flag & PGM_FL_IS_DW)? CMND_FORCED_STOP: CMND_RESET;
+ buf[1] = (pgm->flag & PGM_FL_IS_DW)? 1: flags;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_reset(): Sending %s command: ",
+ progname, (pgm->flag & PGM_FL_IS_DW)? "stop": "reset");
+ jtagmkII_send(pgm, buf, 2);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_reset(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return -1;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ free(resp);
+ if (c != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_reset(): "
+ "bad response to reset command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int jtagmkII_program_enable_INFO(PROGRAMMER * pgm, AVRPART * p)
+{
+ return 0;
+}
+
+static int jtagmkII_program_enable(PROGRAMMER * pgm)
+{
+ int status;
+ unsigned char buf[1], *resp, c;
+ int use_ext_reset;
+
+ if (PDATA(pgm)->prog_enabled)
+ return 0;
+
+ for (use_ext_reset = 0; use_ext_reset <= 1; use_ext_reset++) {
+ buf[0] = CMND_ENTER_PROGMODE;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_program_enable(): "
+ "Sending enter progmode command: ",
+ progname);
+ jtagmkII_send(pgm, buf, 1);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_program_enable(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return -1;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ free(resp);
+ if (c != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_program_enable(): "
+ "bad response to enter progmode command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ if (c == RSP_ILLEGAL_JTAG_ID) {
+ if (use_ext_reset == 0) {
+ unsigned char parm[] = { 1};
+ avrdude_message(MSG_INFO, "%s: retrying with external reset applied\n",
+ progname);
+
+ (void)jtagmkII_setparm(pgm, PAR_EXTERNAL_RESET, parm);
+ continue;
+ }
+
+ avrdude_message(MSG_INFO, "%s: JTAGEN fuse disabled?\n", progname);
+ return -1;
+ }
+ }
+ }
+
+ PDATA(pgm)->prog_enabled = 1;
+ return 0;
+}
+
+static int jtagmkII_program_disable(PROGRAMMER * pgm)
+{
+ int status;
+ unsigned char buf[1], *resp, c;
+
+ if (!PDATA(pgm)->prog_enabled)
+ return 0;
+
+ buf[0] = CMND_LEAVE_PROGMODE;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_program_disable(): "
+ "Sending leave progmode command: ",
+ progname);
+ jtagmkII_send(pgm, buf, 1);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_program_disable(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return -1;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ free(resp);
+ if (c != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_program_disable(): "
+ "bad response to leave progmode command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ return -1;
+ }
+
+ PDATA(pgm)->prog_enabled = 0;
+ (void)jtagmkII_reset(pgm, 0x01);
+
+ return 0;
+}
+
+static unsigned char jtagmkII_get_baud(long baud)
+{
+ static struct {
+ long baud;
+ unsigned char val;
+ } baudtab[] = {
+ { 2400L, PAR_BAUD_2400 },
+ { 4800L, PAR_BAUD_4800 },
+ { 9600L, PAR_BAUD_9600 },
+ { 19200L, PAR_BAUD_19200 },
+ { 38400L, PAR_BAUD_38400 },
+ { 57600L, PAR_BAUD_57600 },
+ { 115200L, PAR_BAUD_115200 },
+ { 14400L, PAR_BAUD_14400 },
+ };
+ int i;
+
+ for (i = 0; i < sizeof baudtab / sizeof baudtab[0]; i++)
+ if (baud == baudtab[i].baud)
+ return baudtab[i].val;
+
+ return 0;
+}
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ AVRMEM hfuse;
+ unsigned char b;
+ int ok;
+ const char *ifname;
+
+ ok = 0;
+ if (pgm->flag & PGM_FL_IS_DW) {
+ ifname = "debugWire";
+ if (p->flags & AVRPART_HAS_DW)
+ ok = 1;
+ } else if (pgm->flag & PGM_FL_IS_PDI) {
+ ifname = "PDI";
+ if (p->flags & AVRPART_HAS_PDI)
+ ok = 1;
+ } else {
+ ifname = "JTAG";
+ if (p->flags & AVRPART_HAS_JTAG)
+ ok = 1;
+ }
+
+ if (!ok) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): part %s has no %s interface\n",
+ progname, p->desc, ifname);
+ return -1;
+ }
+
+ if ((serdev->flags & SERDEV_FL_CANSETSPEED) && pgm->baudrate && pgm->baudrate != 19200) {
+ if ((b = jtagmkII_get_baud(pgm->baudrate)) == 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): unsupported baudrate %d\n",
+ progname, pgm->baudrate);
+ } else {
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_initialize(): "
+ "trying to set baudrate to %d\n",
+ progname, pgm->baudrate);
+ if (jtagmkII_setparm(pgm, PAR_BAUD_RATE, &b) == 0)
+ serial_setspeed(&pgm->fd, pgm->baudrate);
+ }
+ }
+ if ((pgm->flag & PGM_FL_IS_JTAG) && pgm->bitclock != 0.0) {
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_initialize(): "
+ "trying to set JTAG clock period to %.1f us\n",
+ progname, pgm->bitclock);
+ if (jtagmkII_set_sck_period(pgm, pgm->bitclock) != 0)
+ return -1;
+ }
+
+ if ((pgm->flag & PGM_FL_IS_JTAG) &&
+ jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, PDATA(pgm)->jtagchain) < 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Failed to setup JTAG chain\n",
+ progname);
+ return -1;
+ }
+
+ /*
+ * If this is an ATxmega device in JTAG mode, change the emulator
+ * mode from JTAG to JTAG_XMEGA.
+ */
+ if ((pgm->flag & PGM_FL_IS_JTAG) &&
+ (p->flags & AVRPART_HAS_PDI)) {
+ if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG_XMEGA) < 0)
+ return -1;
+ }
+ /*
+ * Must set the device descriptor before entering programming mode.
+ */
+ if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI) != 0)
+ jtagmkII_set_xmega_params(pgm, p);
+ else
+ jtagmkII_set_devdescr(pgm, p);
+
+ PDATA(pgm)->boot_start = ULONG_MAX;
+ /*
+ * If this is an ATxmega device in JTAG mode, change the emulator
+ * mode from JTAG to JTAG_XMEGA.
+ */
+ if ((pgm->flag & PGM_FL_IS_JTAG) &&
+ (p->flags & AVRPART_HAS_PDI)) {
+ /*
+ * Find out where the border between application and boot area
+ * is.
+ */
+ AVRMEM *bootmem = avr_locate_mem(p, "boot");
+ AVRMEM *flashmem = avr_locate_mem(p, "flash");
+ if (bootmem == NULL || flashmem == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Cannot locate \"flash\" and \"boot\" memories in description\n",
+ progname);
+ } else {
+ if (PDATA(pgm)->fwver < 0x700) {
+ /* V7+ firmware does not need this anymore */
+ unsigned char par[4];
+
+ u32_to_b4(par, flashmem->offset);
+ (void) jtagmkII_setparm(pgm, PAR_PDI_OFFSET_START, par);
+ u32_to_b4(par, bootmem->offset);
+ (void) jtagmkII_setparm(pgm, PAR_PDI_OFFSET_END, par);
+ }
+
+ PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset;
+ }
+ }
+
+ free(PDATA(pgm)->flash_pagecache);
+ free(PDATA(pgm)->eeprom_pagecache);
+ if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Out of memory\n",
+ progname);
+ return -1;
+ }
+ if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Out of memory\n",
+ progname);
+ free(PDATA(pgm)->flash_pagecache);
+ return -1;
+ }
+ PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+
+ if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI)) {
+ /*
+ * Work around for
+ * https://savannah.nongnu.org/bugs/index.php?37942
+ *
+ * Firmware version 7.24 (at least) on the Dragon behaves very
+ * strange when it gets a RESET request here. All subsequent
+ * responses are completely off, so the emulator becomes unusable.
+ * This appears to be a firmware bug (earlier versions, at least
+ * 7.14, didn't experience this), but by omitting the RESET for
+ * Xmega devices, we can work around it.
+ */
+ } else {
+ if (jtagmkII_reset(pgm, 0x01) < 0)
+ return -1;
+ }
+
+ if ((pgm->flag & PGM_FL_IS_JTAG) && !(p->flags & AVRPART_HAS_PDI)) {
+ strcpy(hfuse.desc, "hfuse");
+ if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0)
+ return -1;
+ if ((b & OCDEN) != 0)
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): warning: OCDEN fuse not programmed, "
+ "single-byte EEPROM updates not possible\n",
+ progname);
+ }
+
+ return 0;
+}
+
+static void jtagmkII_disable(PROGRAMMER * pgm)
+{
+
+ free(PDATA(pgm)->flash_pagecache);
+ PDATA(pgm)->flash_pagecache = NULL;
+ free(PDATA(pgm)->eeprom_pagecache);
+ PDATA(pgm)->eeprom_pagecache = NULL;
+
+ /*
+ * jtagmkII_program_disable() doesn't do anything if the
+ * device is currently not in programming mode, so just
+ * call it unconditionally here.
+ */
+ (void)jtagmkII_program_disable(pgm);
+}
+
+static void jtagmkII_enable(PROGRAMMER * pgm)
+{
+ return;
+}
+
+static int jtagmkII_parseextparms(PROGRAMMER * pgm, LISTID extparms)
+{
+ LNODEID ln;
+ const char *extended_param;
+ int rv = 0;
+
+ for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
+ extended_param = ldata(ln);
+
+ if (strncmp(extended_param, "jtagchain=", strlen("jtagchain=")) == 0) {
+ unsigned int ub, ua, bb, ba;
+ if (sscanf(extended_param, "jtagchain=%u,%u,%u,%u", &ub, &ua, &bb, &ba)
+ != 4) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_parseextparms(): invalid JTAG chain '%s'\n",
+ progname, extended_param);
+ rv = -1;
+ continue;
+ }
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_parseextparms(): JTAG chain parsed as:\n"
+ "%s %u units before, %u units after, %u bits before, %u bits after\n",
+ progname,
+ progbuf, ub, ua, bb, ba);
+ PDATA(pgm)->jtagchain[0] = ub;
+ PDATA(pgm)->jtagchain[1] = ua;
+ PDATA(pgm)->jtagchain[2] = bb;
+ PDATA(pgm)->jtagchain[3] = ba;
+
+ continue;
+ }
+
+ avrdude_message(MSG_INFO, "%s: jtagmkII_parseextparms(): invalid extended parameter '%s'\n",
+ progname, extended_param);
+ rv = -1;
+ }
+
+ return rv;
+}
+
+
+static int jtagmkII_open(PROGRAMMER * pgm, char * port)
+{
+ union pinfo pinfo;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open()\n", progname);
+
+ /*
+ * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+ * attaching. If the config file or command-line parameters specify
+ * a higher baud rate, we switch to it later on, after establishing
+ * the connection with the ICE.
+ */
+ pinfo.baud = 19200;
+
+ /*
+ * If the port name starts with "usb", divert the serial routines
+ * to the USB ones. The serial_open() function for USB overrides
+ * the meaning of the "baud" parameter to be the USB device ID to
+ * search for.
+ */
+ if (strncmp(port, "usb", 3) == 0) {
+#if defined(HAVE_LIBUSB)
+ serdev = &usb_serdev;
+ pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+ pinfo.usbinfo.flags = 0;
+ pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
+ pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+ pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
+ pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
+ pgm->fd.usb.eep = 0; /* no seperate EP for events */
+#else
+ avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+ return -1;
+#endif
+ }
+
+ strcpy(pgm->port, port);
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ jtagmkII_drain(pgm, 0);
+
+ if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int jtagmkII_open_dw(PROGRAMMER * pgm, char * port)
+{
+ union pinfo pinfo;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open_dw()\n", progname);
+
+ /*
+ * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+ * attaching. If the config file or command-line parameters specify
+ * a higher baud rate, we switch to it later on, after establishing
+ * the connection with the ICE.
+ */
+ pinfo.baud = 19200;
+
+ /*
+ * If the port name starts with "usb", divert the serial routines
+ * to the USB ones. The serial_open() function for USB overrides
+ * the meaning of the "baud" parameter to be the USB device ID to
+ * search for.
+ */
+ if (strncmp(port, "usb", 3) == 0) {
+#if defined(HAVE_LIBUSB)
+ serdev = &usb_serdev;
+ pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+ pinfo.usbinfo.flags = 0;
+ pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
+ pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+ pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
+ pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
+ pgm->fd.usb.eep = 0; /* no seperate EP for events */
+#else
+ avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+ return -1;
+#endif
+ }
+
+ strcpy(pgm->port, port);
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ jtagmkII_drain(pgm, 0);
+
+ if (jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int jtagmkII_open_pdi(PROGRAMMER * pgm, char * port)
+{
+ union pinfo pinfo;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open_pdi()\n", progname);
+
+ /*
+ * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+ * attaching. If the config file or command-line parameters specify
+ * a higher baud rate, we switch to it later on, after establishing
+ * the connection with the ICE.
+ */
+ pinfo.baud = 19200;
+
+ /*
+ * If the port name starts with "usb", divert the serial routines
+ * to the USB ones. The serial_open() function for USB overrides
+ * the meaning of the "baud" parameter to be the USB device ID to
+ * search for.
+ */
+ if (strncmp(port, "usb", 3) == 0) {
+#if defined(HAVE_LIBUSB)
+ serdev = &usb_serdev;
+ pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+ pinfo.usbinfo.flags = 0;
+ pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
+ pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+ pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
+ pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
+ pgm->fd.usb.eep = 0; /* no seperate EP for events */
+#else
+ avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+ return -1;
+#endif
+ }
+
+ strcpy(pgm->port, port);
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ jtagmkII_drain(pgm, 0);
+
+ if (jtagmkII_getsync(pgm, EMULATOR_MODE_PDI) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int jtagmkII_dragon_open(PROGRAMMER * pgm, char * port)
+{
+ union pinfo pinfo;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open()\n", progname);
+
+ /*
+ * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+ * attaching. If the config file or command-line parameters specify
+ * a higher baud rate, we switch to it later on, after establishing
+ * the connection with the ICE.
+ */
+ pinfo.baud = 19200;
+
+ /*
+ * If the port name starts with "usb", divert the serial routines
+ * to the USB ones. The serial_open() function for USB overrides
+ * the meaning of the "baud" parameter to be the USB device ID to
+ * search for.
+ */
+ if (strncmp(port, "usb", 3) == 0) {
+#if defined(HAVE_LIBUSB)
+ serdev = &usb_serdev;
+ pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+ pinfo.usbinfo.flags = 0;
+ pinfo.usbinfo.pid = USB_DEVICE_AVRDRAGON;
+ pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+ pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
+ pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
+ pgm->fd.usb.eep = 0; /* no seperate EP for events */
+#else
+ avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+ return -1;
+#endif
+ }
+
+ strcpy(pgm->port, port);
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ jtagmkII_drain(pgm, 0);
+
+ if (jtagmkII_getsync(pgm, EMULATOR_MODE_JTAG) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int jtagmkII_dragon_open_dw(PROGRAMMER * pgm, char * port)
+{
+ union pinfo pinfo;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open_dw()\n", progname);
+
+ /*
+ * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+ * attaching. If the config file or command-line parameters specify
+ * a higher baud rate, we switch to it later on, after establishing
+ * the connection with the ICE.
+ */
+ pinfo.baud = 19200;
+
+ /*
+ * If the port name starts with "usb", divert the serial routines
+ * to the USB ones. The serial_open() function for USB overrides
+ * the meaning of the "baud" parameter to be the USB device ID to
+ * search for.
+ */
+ if (strncmp(port, "usb", 3) == 0) {
+#if defined(HAVE_LIBUSB)
+ serdev = &usb_serdev;
+ pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+ pinfo.usbinfo.flags = 0;
+ pinfo.usbinfo.pid = USB_DEVICE_AVRDRAGON;
+ pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+ pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
+ pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
+ pgm->fd.usb.eep = 0; /* no seperate EP for events */
+#else
+ avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+ return -1;
+#endif
+ }
+
+ strcpy(pgm->port, port);
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ jtagmkII_drain(pgm, 0);
+
+ if (jtagmkII_getsync(pgm, EMULATOR_MODE_DEBUGWIRE) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int jtagmkII_dragon_open_pdi(PROGRAMMER * pgm, char * port)
+{
+ union pinfo pinfo;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_dragon_open_pdi()\n", progname);
+
+ /*
+ * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+ * attaching. If the config file or command-line parameters specify
+ * a higher baud rate, we switch to it later on, after establishing
+ * the connection with the ICE.
+ */
+ pinfo.baud = 19200;
+
+ /*
+ * If the port name starts with "usb", divert the serial routines
+ * to the USB ones. The serial_open() function for USB overrides
+ * the meaning of the "baud" parameter to be the USB device ID to
+ * search for.
+ */
+ if (strncmp(port, "usb", 3) == 0) {
+#if defined(HAVE_LIBUSB)
+ serdev = &usb_serdev;
+ pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+ pinfo.usbinfo.flags = 0;
+ pinfo.usbinfo.pid = USB_DEVICE_AVRDRAGON;
+ pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+ pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
+ pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
+ pgm->fd.usb.eep = 0; /* no seperate EP for events */
+#else
+ avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+ return -1;
+#endif
+ }
+
+ strcpy(pgm->port, port);
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ jtagmkII_drain(pgm, 0);
+
+ if (jtagmkII_getsync(pgm, EMULATOR_MODE_PDI) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+void jtagmkII_close(PROGRAMMER * pgm)
+{
+ int status;
+ unsigned char buf[1], *resp, c;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close()\n", progname);
+
+ if (pgm->flag & PGM_FL_IS_PDI) {
+ /* When in PDI mode, restart target. */
+ buf[0] = CMND_GO;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close(): Sending GO command: ",
+ progname);
+ jtagmkII_send(pgm, buf, 1);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ } else {
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ free(resp);
+ if (c != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
+ "bad response to GO command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ }
+ }
+ }
+
+ buf[0] = CMND_SIGN_OFF;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close(): Sending sign-off command: ",
+ progname);
+ jtagmkII_send(pgm, buf, 1);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ free(resp);
+ if (c != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
+ "bad response to sign-off command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ }
+
+ serial_close(&pgm->fd);
+ pgm->fd.ifd = -1;
+}
+
+static int jtagmkII_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int addr)
+{
+ unsigned char cmd[6];
+ unsigned char *resp;
+ int status, tries;
+ long otimeout = serial_recv_timeout;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_page_erase(.., %s, 0x%x)\n",
+ progname, m->desc, addr);
+
+ if (!(p->flags & AVRPART_HAS_PDI)) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase: not an Xmega device\n",
+ progname);
+ return -1;
+ }
+ if ((pgm->flag & PGM_FL_IS_DW)) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase: not applicable to debugWIRE\n",
+ progname);
+ return -1;
+ }
+
+ if (jtagmkII_program_enable(pgm) < 0)
+ return -1;
+
+ cmd[0] = CMND_XMEGA_ERASE;
+ if (strcmp(m->desc, "flash") == 0) {
+ if (jtagmkII_memtype(pgm, p, addr) == MTYPE_FLASH)
+ cmd[1] = XMEGA_ERASE_APP_PAGE;
+ else
+ cmd[1] = XMEGA_ERASE_BOOT_PAGE;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ cmd[1] = XMEGA_ERASE_EEPROM_PAGE;
+ } else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
+ cmd[1] = XMEGA_ERASE_USERSIG;
+ } else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
+ cmd[1] = XMEGA_ERASE_BOOT_PAGE;
+ } else {
+ cmd[1] = XMEGA_ERASE_APP_PAGE;
+ }
+ serial_recv_timeout = 100;
+
+ /*
+ * Don't use jtagmkII_memaddr() here. While with all other
+ * commands, firmware 7+ doesn't require the NVM offsets being
+ * applied, the erase page commands make an exception, and do
+ * require the NVM offsets as part of the (page) address.
+ */
+ u32_to_b4(cmd + 2, addr + m->offset);
+
+ tries = 0;
+
+ retry:
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_page_erase(): "
+ "Sending xmega erase command: ",
+ progname);
+ jtagmkII_send(pgm, cmd, sizeof cmd);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ if (tries++ < 4) {
+ serial_recv_timeout *= 2;
+ goto retry;
+ }
+ avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase(): fatal timeout/"
+ "error communicating with programmer (status %d)\n",
+ progname, status);
+ serial_recv_timeout = otimeout;
+ return -1;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ if (resp[0] != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_page_erase(): "
+ "bad response to xmega erase command: %s\n",
+ progname, jtagmkII_get_rc(resp[0]));
+ free(resp);
+ serial_recv_timeout = otimeout;
+ return -1;
+ }
+ free(resp);
+
+ serial_recv_timeout = otimeout;
+
+ return 0;
+}
+
+static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned int block_size;
+ unsigned int maxaddr = addr + n_bytes;
+ unsigned char *cmd;
+ unsigned char *resp;
+ int status, tries, dynamic_memtype = 0;
+ long otimeout = serial_recv_timeout;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_write(.., %s, %d, %d)\n",
+ progname, m->desc, page_size, n_bytes);
+
+ if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
+ return -1;
+
+ if (page_size == 0) page_size = 256;
+ else if (page_size > 256) page_size = 256;
+
+ if ((cmd = malloc(page_size + 10)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): Out of memory\n",
+ progname);
+ return -1;
+ }
+
+ cmd[0] = CMND_WRITE_MEMORY;
+ if (strcmp(m->desc, "flash") == 0) {
+ PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
+ cmd[1] = jtagmkII_memtype(pgm, p, addr);
+ if (p->flags & AVRPART_HAS_PDI)
+ /* dynamically decide between flash/boot memtype */
+ dynamic_memtype = 1;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ if (pgm->flag & PGM_FL_IS_DW) {
+ /*
+ * jtagmkII_paged_write() to EEPROM attempted while in
+ * DW mode. Use jtagmkII_write_byte() instead.
+ */
+ for (; addr < maxaddr; addr++) {
+ status = jtagmkII_write_byte(pgm, p, m, addr, m->buf[addr]);
+ if (status < 0) {
+ free(cmd);
+ return -1;
+ }
+ }
+ free(cmd);
+ return n_bytes;
+ }
+ cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
+ PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+ } else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
+ cmd[1] = MTYPE_USERSIG;
+ } else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
+ cmd[1] = MTYPE_BOOT_FLASH;
+ } else if ( p->flags & AVRPART_HAS_PDI ) {
+ cmd[1] = MTYPE_FLASH;
+ } else {
+ cmd[1] = MTYPE_SPM;
+ }
+ serial_recv_timeout = 100;
+ for (; addr < maxaddr; addr += page_size) {
+ if ((maxaddr - addr) < page_size)
+ block_size = maxaddr - addr;
+ else
+ block_size = page_size;
+ avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_write(): "
+ "block_size at addr %d is %d\n",
+ progname, addr, block_size);
+
+ if (dynamic_memtype)
+ cmd[1] = jtagmkII_memtype(pgm, p, addr);
+
+ u32_to_b4(cmd + 2, page_size);
+ u32_to_b4(cmd + 6, jtagmkII_memaddr(pgm, p, m, addr));
+
+ /*
+ * The JTAG ICE will refuse to write anything but a full page, at
+ * least for the flash ROM. If a partial page has been requested,
+ * set the remainder to 0xff. (Maybe we should rather read back
+ * the existing contents instead before? Doesn't matter much, as
+ * bits cannot be written to 1 anyway.)
+ */
+ memset(cmd + 10, 0xff, page_size);
+ memcpy(cmd + 10, m->buf + addr, block_size);
+
+ tries = 0;
+
+ retry:
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_write(): "
+ "Sending write memory command: ",
+ progname);
+ jtagmkII_send(pgm, cmd, page_size + 10);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ if (tries++ < 4) {
+ serial_recv_timeout *= 2;
+ goto retry;
+ }
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): fatal timeout/"
+ "error communicating with programmer (status %d)\n",
+ progname, status);
+ free(cmd);
+ serial_recv_timeout = otimeout;
+ return -1;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ if (resp[0] != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write(): "
+ "bad response to write memory command: %s\n",
+ progname, jtagmkII_get_rc(resp[0]));
+ free(resp);
+ free(cmd);
+ serial_recv_timeout = otimeout;
+ return -1;
+ }
+ free(resp);
+ }
+
+ free(cmd);
+ serial_recv_timeout = otimeout;
+
+ return n_bytes;
+}
+
+static int jtagmkII_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned int block_size;
+ unsigned int maxaddr = addr + n_bytes;
+ unsigned char cmd[10];
+ unsigned char *resp;
+ int status, tries, dynamic_memtype = 0;
+ long otimeout = serial_recv_timeout;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_load(.., %s, %d, %d)\n",
+ progname, m->desc, page_size, n_bytes);
+
+ if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
+ return -1;
+
+ page_size = m->readsize;
+
+ cmd[0] = CMND_READ_MEMORY;
+ if (strcmp(m->desc, "flash") == 0) {
+ cmd[1] = jtagmkII_memtype(pgm, p, addr);
+ if (p->flags & AVRPART_HAS_PDI)
+ /* dynamically decide between flash/boot memtype */
+ dynamic_memtype = 1;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM : MTYPE_EEPROM_PAGE;
+ if (pgm->flag & PGM_FL_IS_DW)
+ return -1;
+ } else if ( ( strcmp(m->desc, "prodsig") == 0 ) ) {
+ cmd[1] = MTYPE_PRODSIG;
+ } else if ( ( strcmp(m->desc, "usersig") == 0 ) ) {
+ cmd[1] = MTYPE_USERSIG;
+ } else if ( ( strcmp(m->desc, "boot") == 0 ) ) {
+ cmd[1] = MTYPE_BOOT_FLASH;
+ } else if ( p->flags & AVRPART_HAS_PDI ) {
+ cmd[1] = MTYPE_FLASH;
+ } else {
+ cmd[1] = MTYPE_SPM;
+ }
+ serial_recv_timeout = 100;
+ for (; addr < maxaddr; addr += page_size) {
+ if ((maxaddr - addr) < page_size)
+ block_size = maxaddr - addr;
+ else
+ block_size = page_size;
+ avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_load(): "
+ "block_size at addr %d is %d\n",
+ progname, addr, block_size);
+
+ if (dynamic_memtype)
+ cmd[1] = jtagmkII_memtype(pgm, p, addr);
+
+ u32_to_b4(cmd + 2, block_size);
+ u32_to_b4(cmd + 6, jtagmkII_memaddr(pgm, p, m, addr));
+
+ tries = 0;
+
+ retry:
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_load(): Sending read memory command: ",
+ progname);
+ jtagmkII_send(pgm, cmd, 10);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ if (tries++ < 4) {
+ serial_recv_timeout *= 2;
+ goto retry;
+ }
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load(): fatal timeout/"
+ "error communicating with programmer (status %d)\n",
+ progname, status);
+ serial_recv_timeout = otimeout;
+ return -1;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ if (resp[0] != RSP_MEMORY) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load(): "
+ "bad response to read memory command: %s\n",
+ progname, jtagmkII_get_rc(resp[0]));
+ free(resp);
+ serial_recv_timeout = otimeout;
+ return -1;
+ }
+ memcpy(m->buf + addr, resp + 1, status-1);
+ free(resp);
+ }
+ serial_recv_timeout = otimeout;
+
+ return n_bytes;
+}
+
+static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value)
+{
+ unsigned char cmd[10];
+ unsigned char *resp = NULL, *cache_ptr = NULL;
+ int status, tries, unsupp;
+ unsigned long paddr = 0UL, *paddr_ptr = NULL;
+ unsigned int pagesize = 0;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_read_byte(.., %s, 0x%lx, ...)\n",
+ progname, mem->desc, addr);
+
+ if (!(pgm->flag & PGM_FL_IS_DW) && jtagmkII_program_enable(pgm) < 0)
+ return -1;
+
+ cmd[0] = CMND_READ_MEMORY;
+ unsupp = 0;
+
+ addr += mem->offset;
+ cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_FLASH_PAGE;
+ if (strcmp(mem->desc, "flash") == 0 ||
+ strcmp(mem->desc, "application") == 0 ||
+ strcmp(mem->desc, "apptable") == 0 ||
+ strcmp(mem->desc, "boot") == 0) {
+ pagesize = PDATA(pgm)->flash_pagesize;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->flash_pageaddr;
+ cache_ptr = PDATA(pgm)->flash_pagecache;
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ if ( (pgm->flag & PGM_FL_IS_DW) || ( p->flags & AVRPART_HAS_PDI ) ) {
+ /* debugWire cannot use page access for EEPROM */
+ cmd[1] = MTYPE_EEPROM;
+ } else {
+ cmd[1] = MTYPE_EEPROM_PAGE;
+ pagesize = mem->page_size;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
+ cache_ptr = PDATA(pgm)->eeprom_pagecache;
+ }
+ } else if (strcmp(mem->desc, "lfuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 0;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "hfuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 1;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "efuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 2;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strncmp(mem->desc, "lock", 4) == 0) {
+ cmd[1] = MTYPE_LOCK_BITS;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ } else if (strcmp(mem->desc, "usersig") == 0) {
+ cmd[1] = MTYPE_USERSIG;
+ } else if (strcmp(mem->desc, "prodsig") == 0) {
+ cmd[1] = MTYPE_PRODSIG;
+ } else if (strcmp(mem->desc, "calibration") == 0) {
+ cmd[1] = MTYPE_OSCCAL_BYTE;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "signature") == 0) {
+ cmd[1] = MTYPE_SIGN_JTAG;
+
+ if (pgm->flag & PGM_FL_IS_DW) {
+ /*
+ * In debugWire mode, there is no accessible memory area to read
+ * the signature from, but the essential two bytes can be read
+ * as a parameter from the ICE.
+ */
+ unsigned char parm[4];
+
+ switch (addr) {
+ case 0:
+ *value = 0x1E; /* Atmel vendor ID */
+ break;
+
+ case 1:
+ case 2:
+ if (jtagmkII_getparm(pgm, PAR_TARGET_SIGNATURE, parm) < 0)
+ return -1;
+ *value = parm[2 - addr];
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "%s: illegal address %lu for signature memory\n",
+ progname, addr);
+ return -1;
+ }
+ return 0;
+ }
+
+ }
+
+ /*
+ * If the respective memory area is not supported under debugWire,
+ * leave here.
+ */
+ if (unsupp) {
+ *value = 42;
+ return -1;
+ }
+
+ /*
+ * To improve the read speed, we used paged reads for flash and
+ * EEPROM, and cache the results in a page cache.
+ *
+ * Page cache validation is based on "{flash,eeprom}_pageaddr"
+ * (holding the base address of the most recent cache fill
+ * operation). This variable is set to (unsigned long)-1L when the
+ * cache needs to be invalidated.
+ */
+ if (pagesize && paddr == *paddr_ptr) {
+ *value = cache_ptr[addr & (pagesize - 1)];
+ return 0;
+ }
+
+ if (pagesize) {
+ u32_to_b4(cmd + 2, pagesize);
+ u32_to_b4(cmd + 6, paddr);
+ } else {
+ u32_to_b4(cmd + 2, 1);
+ u32_to_b4(cmd + 6, addr);
+ }
+
+ tries = 0;
+ retry:
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_read_byte(): Sending read memory command: ",
+ progname);
+ jtagmkII_send(pgm, cmd, 10);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_read_byte(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ if (tries++ < 3)
+ goto retry;
+ avrdude_message(MSG_INFO, "%s: jtagmkII_read_byte(): "
+ "fatal timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ if (status < 0)
+ resp = 0;
+ goto fail;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ if (resp[0] != RSP_MEMORY) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_read_byte(): "
+ "bad response to read memory command: %s\n",
+ progname, jtagmkII_get_rc(resp[0]));
+ goto fail;
+ }
+
+ if (pagesize) {
+ *paddr_ptr = paddr;
+ memcpy(cache_ptr, resp + 1, pagesize);
+ *value = cache_ptr[addr & (pagesize - 1)];
+ } else
+ *value = resp[1];
+
+ free(resp);
+ return 0;
+
+fail:
+ free(resp);
+ return -1;
+}
+
+static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data)
+{
+ unsigned char cmd[12];
+ unsigned char *resp = NULL, writedata, writedata2 = 0xFF;
+ int status, tries, need_progmode = 1, unsupp = 0, writesize = 1;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_write_byte(.., %s, 0x%lx, ...)\n",
+ progname, mem->desc, addr);
+
+ addr += mem->offset;
+
+ writedata = data;
+ cmd[0] = CMND_WRITE_MEMORY;
+ cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_SPM;
+ if (strcmp(mem->desc, "flash") == 0) {
+ if ((addr & 1) == 1) {
+ /* odd address = high byte */
+ writedata = 0xFF; /* don't modify the low byte */
+ writedata2 = data;
+ addr &= ~1L;
+ }
+ writesize = 2;
+ need_progmode = 0;
+ PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM;
+ need_progmode = 0;
+ PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+ } else if (strcmp(mem->desc, "lfuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 0;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "hfuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 1;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "efuse") == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ addr = 2;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
+ cmd[1] = MTYPE_FUSE_BITS;
+ } else if (strcmp(mem->desc, "usersig") == 0) {
+ cmd[1] = MTYPE_USERSIG;
+ } else if (strcmp(mem->desc, "prodsig") == 0) {
+ cmd[1] = MTYPE_PRODSIG;
+ } else if (strncmp(mem->desc, "lock", 4) == 0) {
+ cmd[1] = MTYPE_LOCK_BITS;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "calibration") == 0) {
+ cmd[1] = MTYPE_OSCCAL_BYTE;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ } else if (strcmp(mem->desc, "signature") == 0) {
+ cmd[1] = MTYPE_SIGN_JTAG;
+ if (pgm->flag & PGM_FL_IS_DW)
+ unsupp = 1;
+ }
+
+ if (unsupp)
+ return -1;
+
+ if (need_progmode) {
+ if (jtagmkII_program_enable(pgm) < 0)
+ return -1;
+ } else {
+ if (jtagmkII_program_disable(pgm) < 0)
+ return -1;
+ }
+
+ u32_to_b4(cmd + 2, writesize);
+ u32_to_b4(cmd + 6, addr);
+ cmd[10] = writedata;
+ cmd[11] = writedata2;
+
+ tries = 0;
+ retry:
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_write_byte(): Sending write memory command: ",
+ progname);
+ jtagmkII_send(pgm, cmd, 10 + writesize);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_write_byte(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ if (tries++ < 3)
+ goto retry;
+ avrdude_message(MSG_INFO, "%s: jtagmkII_write_byte(): "
+ "fatal timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ goto fail;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ if (resp[0] != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_write_byte(): "
+ "bad response to write memory command: %s\n",
+ progname, jtagmkII_get_rc(resp[0]));
+ goto fail;
+ }
+
+ free(resp);
+ return 0;
+
+fail:
+ free(resp);
+ return -1;
+}
+
+
+/*
+ * Set the JTAG clock. The actual frequency is quite a bit of
+ * guesswork, based on the values claimed by AVR Studio. Inside the
+ * JTAG ICE, the value is the delay count of a delay loop between the
+ * JTAG clock edges. A count of 0 bypasses the delay loop.
+ *
+ * As the STK500 expresses it as a period length (and we actualy do
+ * program a period length as well), we rather call it by that name.
+ */
+static int jtagmkII_set_sck_period(PROGRAMMER * pgm, double v)
+{
+ unsigned char dur;
+
+ v = 1 / v; /* convert to frequency */
+ if (v >= 6.4e6)
+ dur = 0;
+ else if (v >= 2.8e6)
+ dur = 1;
+ else if (v >= 20.9e3)
+ dur = (unsigned char)(5.35e6 / v);
+ else
+ dur = 255;
+
+ return jtagmkII_setparm(pgm, PAR_OCD_JTAG_CLK, &dur);
+}
+
+
+/*
+ * Read an emulator parameter. As the maximal parameter length is 4
+ * bytes by now, we always copy out 4 bytes to *value, so the caller
+ * must have allocated sufficient space.
+ */
+int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
+ unsigned char * value)
+{
+ int status;
+ unsigned char buf[2], *resp, c;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getparm()\n", progname);
+
+ buf[0] = CMND_GET_PARAMETER;
+ buf[1] = parm;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_getparm(): "
+ "Sending get parameter command (parm 0x%02x): ",
+ progname, parm);
+ jtagmkII_send(pgm, buf, 2);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getparm(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return -1;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ if (c != RSP_PARAMETER) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_getparm(): "
+ "bad response to get parameter command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ free(resp);
+ return -1;
+ }
+
+ memcpy(value, resp + 1, 4);
+ free(resp);
+
+ return 0;
+}
+
+/*
+ * Write an emulator parameter.
+ */
+static int jtagmkII_setparm(PROGRAMMER * pgm, unsigned char parm,
+ unsigned char * value)
+{
+ int status;
+ /*
+ * As the maximal parameter length is 4 bytes, we use a fixed-length
+ * buffer, as opposed to malloc()ing it.
+ */
+ unsigned char buf[2 + 4], *resp, c;
+ size_t size;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_setparm()\n", progname);
+
+ switch (parm) {
+ case PAR_HW_VERSION: size = 2; break;
+ case PAR_FW_VERSION: size = 4; break;
+ case PAR_EMULATOR_MODE: size = 1; break;
+ case PAR_BAUD_RATE: size = 1; break;
+ case PAR_OCD_VTARGET: size = 2; break;
+ case PAR_OCD_JTAG_CLK: size = 1; break;
+ case PAR_TIMERS_RUNNING: size = 1; break;
+ case PAR_EXTERNAL_RESET: size = 1; break;
+ case PAR_DAISY_CHAIN_INFO: size = 4; break;
+ case PAR_PDI_OFFSET_START:
+ case PAR_PDI_OFFSET_END: size = 4; break;
+ default:
+ avrdude_message(MSG_INFO, "%s: jtagmkII_setparm(): unknown parameter 0x%02x\n",
+ progname, parm);
+ return -1;
+ }
+
+ buf[0] = CMND_SET_PARAMETER;
+ buf[1] = parm;
+ memcpy(buf + 2, value, size);
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_setparm(): "
+ "Sending set parameter command (parm 0x%02x, %u bytes): ",
+ progname, parm, (unsigned)size);
+ jtagmkII_send(pgm, buf, size + 2);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_setparm(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return -1;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ free(resp);
+ if (c != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_setparm(): "
+ "bad response to set parameter command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static void jtagmkII_display(PROGRAMMER * pgm, const char * p)
+{
+ unsigned char hw[4], fw[4];
+
+ if (jtagmkII_getparm(pgm, PAR_HW_VERSION, hw) < 0 ||
+ jtagmkII_getparm(pgm, PAR_FW_VERSION, fw) < 0)
+ return;
+
+ avrdude_message(MSG_INFO, "%sM_MCU hardware version: %d\n", p, hw[0]);
+ avrdude_message(MSG_INFO, "%sM_MCU firmware version: %d.%02d\n", p, fw[1], fw[0]);
+ avrdude_message(MSG_INFO, "%sS_MCU hardware version: %d\n", p, hw[1]);
+ avrdude_message(MSG_INFO, "%sS_MCU firmware version: %d.%02d\n", p, fw[3], fw[2]);
+ avrdude_message(MSG_INFO, "%sSerial number: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ p, PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2], PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]);
+
+ jtagmkII_print_parms1(pgm, p);
+
+ return;
+}
+
+
+static void jtagmkII_print_parms1(PROGRAMMER * pgm, const char * p)
+{
+ unsigned char vtarget[4], jtag_clock[4];
+ char clkbuf[20];
+ double clk;
+
+ if (jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget) < 0)
+ return;
+
+ avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p,
+ b2_to_u16(vtarget) / 1000.0);
+
+ if ((pgm->flag & PGM_FL_IS_JTAG)) {
+ if (jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, jtag_clock) < 0)
+ return;
+
+ if (jtag_clock[0] == 0) {
+ strcpy(clkbuf, "6.4 MHz");
+ clk = 6.4e6;
+ } else if (jtag_clock[0] == 1) {
+ strcpy(clkbuf, "2.8 MHz");
+ clk = 2.8e6;
+ } else if (jtag_clock[0] <= 5) {
+ sprintf(clkbuf, "%.1f MHz", 5.35 / (double)jtag_clock[0]);
+ clk = 5.35e6 / (double)jtag_clock[0];
+ } else {
+ sprintf(clkbuf, "%.1f kHz", 5.35e3 / (double)jtag_clock[0]);
+ clk = 5.35e6 / (double)jtag_clock[0];
+
+ avrdude_message(MSG_INFO, "%sJTAG clock : %s (%.1f us)\n", p, clkbuf,
+ 1.0e6 / clk);
+ }
+ }
+
+ return;
+}
+
+static void jtagmkII_print_parms(PROGRAMMER * pgm)
+{
+ jtagmkII_print_parms1(pgm, "");
+}
+
+static unsigned char jtagmkII_memtype(PROGRAMMER * pgm, AVRPART * p, unsigned long addr)
+{
+ if ( p->flags & AVRPART_HAS_PDI ) {
+ if (addr >= PDATA(pgm)->boot_start)
+ return MTYPE_BOOT_FLASH;
+ else
+ return MTYPE_FLASH;
+ } else {
+ return MTYPE_FLASH_PAGE;
+ }
+}
+
+static unsigned int jtagmkII_memaddr(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr)
+{
+ /*
+ * Xmega devices handled by V7+ firmware don't want to be told their
+ * m->offset within the write memory command.
+ */
+ if (PDATA(pgm)->fwver >= 0x700 && (p->flags & AVRPART_HAS_PDI) != 0) {
+ if (addr >= PDATA(pgm)->boot_start)
+ /*
+ * all memories but "flash" are smaller than boot_start anyway, so
+ * no need for an extra check we are operating on "flash"
+ */
+ return addr - PDATA(pgm)->boot_start;
+ else
+ /* normal flash, or anything else */
+ return addr;
+ }
+ /*
+ * Old firmware, or non-Xmega device. Non-Xmega (and non-AVR32)
+ * devices always have an m->offset of 0, so we don't have to
+ * distinguish them here.
+ */
+ return addr + m->offset;
+}
+
+
+#ifdef __OBJC__
+#pragma mark -
+#endif
+
+static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val,
+ unsigned char ret1, unsigned char ret2)
+{
+ int status;
+ unsigned char buf[3], *resp;
+
+ avrdude_message(MSG_NOTICE, "%s: jtagmkII_avr32_reset(%2.2x)\n",
+ progname, val);
+
+ buf[0] = CMND_GET_IR;
+ buf[1] = 0x0C;
+ status = jtagmkII_send(pgm, buf, 2);
+ if(status < 0) return -1;
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status != 2 || resp[0] != 0x87 || resp[1] != ret1) {
+ avrdude_message(MSG_NOTICE, "%s: jtagmkII_avr32_reset(): "
+ "Get_IR, expecting %2.2x but got %2.2x\n",
+ progname, ret1, resp[1]);
+
+ //return -1;
+ }
+
+ buf[0] = CMND_GET_xxx;
+ buf[1] = 5;
+ buf[2] = val;
+ status = jtagmkII_send(pgm, buf, 3);
+ if(status < 0) return -1;
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status != 2 || resp[0] != 0x87 || resp[1] != ret2) {
+ avrdude_message(MSG_NOTICE, "%s: jtagmkII_avr32_reset(): "
+ "Get_XXX, expecting %2.2x but got %2.2x\n",
+ progname, ret2, resp[1]);
+ //return -1;
+ }
+
+ return 0;
+}
+
+// At init: AVR32_RESET_READ_IR | AVR32_RESET_READ_READ_CHIPINFO
+static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags)
+{
+ int status, j, lineno;
+ unsigned char *resp, buf[3];
+ unsigned long val=0;
+
+ avrdude_message(MSG_NOTICE, "%s: jtagmkII_reset32(%2.2x)\n",
+ progname, flags);
+
+ status = -1;
+
+ // Happens at the start of a programming operation
+ if(flags & AVR32_RESET_READ) {
+ buf[0] = CMND_GET_IR;
+ buf[1] = 0x11;
+ status = jtagmkII_send(pgm, buf, 2);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status != 2 || resp[0] != 0x87 || resp[1] != 01)
+ {lineno = __LINE__; goto eRR;};
+ }
+
+ if(flags & (AVR32_RESET_WRITE | AVR32_SET4RUNNING)) {
+ // AVR_RESET(0x1F)
+ status = jtagmkII_avr32_reset(pgm, 0x1F, 0x01, 0x00);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+ // AVR_RESET(0x07)
+ status = jtagmkII_avr32_reset(pgm, 0x07, 0x11, 0x1F);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+ }
+
+ //if(flags & AVR32_RESET_COMMON)
+ {
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
+ if(val != 0) {lineno = __LINE__; goto eRR;}
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DC, 0x01);
+ if(val != 0) {lineno = __LINE__; goto eRR;}
+ }
+
+ if(flags & (AVR32_RESET_READ | AVR32_RESET_CHIP_ERASE)) {
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01,
+ AVR32_DC_DBE | AVR32_DC_DBR);
+ if(status < 0) return -1;
+ }
+
+ if(flags & (AVR32_RESET_WRITE | AVR32_SET4RUNNING)) {
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01,
+ AVR32_DC_ABORT | AVR32_DC_RESET | AVR32_DC_DBE | AVR32_DC_DBR);
+ if(status < 0) return -1;
+ for(j=0; j<21; ++j) {
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
+ }
+ if(val != 0x04000000) {lineno = __LINE__; goto eRR;}
+
+ // AVR_RESET(0x00)
+ status = jtagmkII_avr32_reset(pgm, 0x00, 0x01, 0x07);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+ }
+// if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE))
+ {
+ for(j=0; j<2; ++j) {
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+ if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
+ }
+ }
+
+ //if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE))
+ {
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
+ if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
+ if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
+ }
+
+ // Read chip configuration - common for all
+ if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE)) {
+ for(j=0; j<2; ++j) {
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+ if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
+ }
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
+ if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
+ if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00040); // mfsr R0, 256
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
+ if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mtdr R0, 276
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+ if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
+ if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
+ if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00041); // mfsr R0, 260
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
+ if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mtdr R0, 276
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06); // need to recheck who does this...
+ if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
+ }
+
+ if(flags & AVR32_RESET_CHIP_ERASE) {
+ status = jtagmkII_avr32_reset(pgm, 0x1f, 0x01, 0x00);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_avr32_reset(pgm, 0x01, 0x11, 0x1f);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+ }
+
+ if(flags & AVR32_SET4RUNNING) {
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00014); // mfsr R0, 80
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044); // mtdr 272, R0
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
+ if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045); // mfdr R0, 276
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+ if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xd623d703); // retd
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+ }
+
+ return 0;
+
+ eRR:
+ avrdude_message(MSG_INFO, "%s: jtagmkII_reset32(): "
+ "failed at line %d (status=%x val=%lx)\n",
+ progname, lineno, status, val);
+ return -1;
+}
+
+static int jtagmkII_smc_init32(PROGRAMMER * pgm)
+{
+ int status, lineno;
+ unsigned long val;
+
+ // HMATRIX 0xFFFF1000
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x04000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x04000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x04000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x04000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x04000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x08000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x08000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x08000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x08000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x08000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x10000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x10000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x10000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x10000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x10000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x00020000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x00020000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x00020000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x00020000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x00020000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1018, 0x05, 0x02000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1024, 0x05, 0x02000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1008, 0x05, 0x02000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1078, 0x05, 0x02000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xffff1088, 0x05, 0x02000000);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_write_SABaddr(pgm, 0xfffe1c00, 0x05, 0x00010001);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xfffe1c04, 0x05, 0x05070a0b);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xfffe1c08, 0x05, 0x000b000c);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_write_SABaddr(pgm, 0xfffe1c0c, 0x05, 0x00031103);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+
+ // switchToClockSource
+ val = jtagmkII_read_SABaddr(pgm, 0xffff0c28, 0x05);
+ if (val != 0x00000000) {lineno = __LINE__; goto eRR;} // OSC 0
+ status = jtagmkII_write_SABaddr(pgm, 0xffff0c28, 0x05, 0x0000607);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+ val = jtagmkII_read_SABaddr(pgm, 0xffff0c00, 0x05);
+ if (val != 0x00000000) {lineno = __LINE__; goto eRR;} // PLL 0
+ status = jtagmkII_write_SABaddr(pgm, 0xffff0c00, 0x05, 0x0000004);
+ if (status < 0) {lineno = __LINE__; goto eRR;} // Power Manager
+ status = jtagmkII_write_SABaddr(pgm, 0xffff0c00, 0x05, 0x0000005);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+
+ usleep(1000000);
+
+ val = jtagmkII_read_SABaddr(pgm, 0xfffe1408, 0x05);
+ if (val != 0x0000a001) {lineno = __LINE__; goto eRR;} // PLL 0
+
+ // need a small delay to let clock stabliize
+ usleep(50*1000);
+
+ return 0;
+
+ eRR:
+ avrdude_message(MSG_INFO, "%s: jtagmkII_smc_init32(): "
+ "failed at line %d\n",
+ progname, lineno);
+ return -1;
+}
+
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+static int jtagmkII_initialize32(PROGRAMMER * pgm, AVRPART * p)
+{
+ int status, j;
+ unsigned char buf[6], *resp;
+
+ if (jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, PDATA(pgm)->jtagchain) < 0) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Failed to setup JTAG chain\n",
+ progname);
+ return -1;
+ }
+
+ free(PDATA(pgm)->flash_pagecache);
+ free(PDATA(pgm)->eeprom_pagecache);
+ if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize(): Out of memory\n",
+ progname);
+ return -1;
+ }
+ if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize32(): Out of memory\n",
+ progname);
+ free(PDATA(pgm)->flash_pagecache);
+ return -1;
+ }
+ PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+
+ for(j=0; j<2; ++j) {
+ buf[0] = CMND_GET_IR;
+ buf[1] = 0x1;
+ if(jtagmkII_send(pgm, buf, 2) < 0)
+ return -1;
+ status = jtagmkII_recv(pgm, &resp);
+ if(status <= 0 || resp[0] != 0x87) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize32(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return -1;
+ }
+ free(resp);
+
+ memset(buf, 0, sizeof(buf));
+ buf[0] = CMND_GET_xxx;
+ buf[1] = 0x20;
+ if(jtagmkII_send(pgm, buf, 6) < 0)
+ return -1;
+ status = jtagmkII_recv(pgm, &resp);
+ if(status <= 0 || resp[0] != 0x87) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_initialize32(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return -1;
+ }
+
+ if (status != 5 ||
+ resp[2] != p->signature[0] ||
+ resp[3] != p->signature[1] ||
+ resp[4] != p->signature[2]) {
+ avrdude_message(MSG_INFO, "%s: Expected signature for %s is %02X %02X %02X\n",
+ progname, p->desc,
+ p->signature[0], p->signature[1], p->signature[2]);
+ if (!ovsigck) {
+ avrdude_message(MSG_INFO, "%sDouble check chip, "
+ "or use -F to override this check.\n",
+ progbuf);
+ return -1;
+ }
+ }
+ free(resp);
+ }
+
+ return 0;
+}
+
+static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p)
+{
+ int status=0, loops;
+ unsigned char *resp, buf[3], x, ret[4], *retP;
+ unsigned long val=0;
+ unsigned int lineno;
+
+ avrdude_message(MSG_NOTICE, "%s: jtagmkII_chip_erase32()\n",
+ progname);
+
+ status = jtagmkII_reset32(pgm, AVR32_RESET_CHIP_ERASE);
+ if(status != 0) {lineno = __LINE__; goto eRR;}
+
+ // sequence of IR transitions
+ ret[0] = 0x01;
+ ret[1] = 0x05;
+ ret[2] = 0x01;
+ ret[3] = 0x00;
+
+ retP = ret;
+ for(loops=0; loops<1000; ++loops) {
+ buf[0] = CMND_GET_IR;
+ buf[1] = 0x0F;
+ status = jtagmkII_send(pgm, buf, 2);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status != 2 || resp[0] != 0x87) {
+ {lineno = __LINE__; goto eRR;}
+ }
+ x = resp[1];
+ free(resp);
+ if(x == *retP) ++retP;
+ if(*retP == 0x00) break;
+ }
+ if(loops == 1000) {lineno = __LINE__; goto eRR;}
+
+ status = jtagmkII_avr32_reset(pgm, 0x00, 0x01, 0x01);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06);
+ if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
+
+ // AVR32 "special"
+ buf[0] = CMND_SET_PARAMETER;
+ buf[1] = 0x03;
+ buf[2] = 0x02;
+ jtagmkII_send(pgm, buf, 3);
+ status = jtagmkII_recv(pgm, &resp);
+ if(status < 0 || resp[0] != RSP_OK) {lineno = __LINE__; goto eRR;}
+ free(resp);
+
+ return 0;
+
+ eRR:
+ avrdude_message(MSG_INFO, "%s: jtagmkII_reset32(): "
+ "failed at line %d (status=%x val=%lx)\n",
+ progname, lineno, status, val);
+ return -1;
+}
+
+static unsigned long jtagmkII_read_SABaddr(PROGRAMMER * pgm, unsigned long addr,
+ unsigned int prefix)
+{
+ unsigned char buf[6], *resp;
+ int status;
+ unsigned long val;
+ unsigned long otimeout = serial_recv_timeout;
+
+ serial_recv_timeout = 256;
+
+ buf[0] = CMND_READ_SAB;
+ buf[1] = prefix;
+ u32_to_b4r(&buf[2], addr);
+
+ if(jtagmkII_send(pgm, buf, 6) < 0)
+ return ERROR_SAB;
+
+ status = jtagmkII_recv(pgm, &resp);
+ if(status <= 0 || resp[0] != 0x87) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_read_SABaddr(): "
+ "timeout/error communicating with programmer (status %d) resp=%x\n",
+ progname, status, resp[0]);
+ serial_recv_timeout = otimeout;
+
+ if(status > 0) {
+ int i;
+ avrdude_message(MSG_INFO, "Cmd: ");
+ for(i=0; i<6; ++i) avrdude_message(MSG_INFO, "%2.2x ", buf[i]);
+ avrdude_message(MSG_INFO, "\n");
+ avrdude_message(MSG_INFO, "Data: ");
+ for(i=0; i<status; ++i) avrdude_message(MSG_INFO, "%2.2x ", resp[i]);
+ avrdude_message(MSG_INFO, "\n");
+ }
+ return ERROR_SAB;
+ }
+
+ if(status != 5) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_read_SABaddr(): "
+ "wrong number of bytes (status %d)\n",
+ progname, status);
+ serial_recv_timeout = otimeout;
+ return ERROR_SAB;
+ }
+
+ val = b4_to_u32r(&resp[1]);
+ free(resp);
+
+ if (verbose) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_read_SABaddr(): "
+ "OCD Register %lx -> %4.4lx\n",
+ progname, addr, val);
+ }
+ serial_recv_timeout = otimeout;
+ return val;
+}
+
+static int jtagmkII_write_SABaddr(PROGRAMMER * pgm, unsigned long addr,
+ unsigned int prefix, unsigned long val)
+{
+ unsigned char buf[10], *resp;
+ int status;
+
+ buf[0] = CMND_WRITE_SAB;
+ buf[1] = prefix;
+ u32_to_b4r(&buf[2], addr);
+ u32_to_b4r(&buf[6], val);
+
+ if(jtagmkII_send(pgm, buf, 10) < 0)
+ return -1;
+
+ status = jtagmkII_recv(pgm, &resp);
+ if(status <= 0 || resp[0] != RSP_OK) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_write_SABaddr(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return -1;
+ }
+
+
+ if (verbose) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_write_SABaddr(): "
+ "OCD Register %lx -> %4.4lx\n",
+ progname, addr, val);
+ }
+ return 0;
+}
+
+static int jtagmkII_open32(PROGRAMMER * pgm, char * port)
+{
+ int status;
+ unsigned char buf[6], *resp;
+ union pinfo pinfo;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_open32()\n", progname);
+
+ /*
+ * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+ * attaching. If the config file or command-line parameters specify
+ * a higher baud rate, we switch to it later on, after establishing
+ * the connection with the ICE.
+ */
+ pinfo.baud = 19200;
+
+ /*
+ * If the port name starts with "usb", divert the serial routines
+ * to the USB ones. The serial_open() function for USB overrides
+ * the meaning of the "baud" parameter to be the USB device ID to
+ * search for.
+ */
+ if (strncmp(port, "usb", 3) == 0) {
+#if defined(HAVE_LIBUSB)
+ serdev = &usb_serdev;
+ pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+ pinfo.usbinfo.flags = 0;
+ pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
+ pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+ pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
+ pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
+ pgm->fd.usb.eep = 0; /* no seperate EP for events */
+#else
+ avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+ return -1;
+#endif
+ }
+
+ strcpy(pgm->port, port);
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ jtagmkII_drain(pgm, 0);
+
+ status = jtagmkII_getsync(pgm, -1);
+ if(status < 0) return -1;
+
+ // AVR32 "special"
+ buf[0] = CMND_SET_PARAMETER;
+ buf[1] = 0x2D;
+ buf[2] = 0x03;
+ jtagmkII_send(pgm, buf, 3);
+ status = jtagmkII_recv(pgm, &resp);
+ if(status < 0 || resp[0] != RSP_OK)
+ return -1;
+ free(resp);
+
+ buf[1] = 0x03;
+ buf[2] = 0x02;
+ jtagmkII_send(pgm, buf, 3);
+ status = jtagmkII_recv(pgm, &resp);
+ if(status < 0 || resp[0] != RSP_OK)
+ return -1;
+ free(resp);
+
+ buf[1] = 0x03;
+ buf[2] = 0x04;
+ jtagmkII_send(pgm, buf, 3);
+ status = jtagmkII_recv(pgm, &resp);
+ if(status < 0 || resp[0] != RSP_OK)
+ return -1;
+ free(resp);
+
+ return 0;
+}
+
+static void jtagmkII_close32(PROGRAMMER * pgm)
+{
+ int status, lineno;
+ unsigned char *resp, buf[3], c;
+ unsigned long val=0;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close32()\n", progname);
+
+ // AVR32 "special"
+ buf[0] = CMND_SET_PARAMETER;
+ buf[1] = 0x03;
+ buf[2] = 0x02;
+ jtagmkII_send(pgm, buf, 3);
+ status = jtagmkII_recv(pgm, &resp);
+ if(status < 0 || resp[0] != RSP_OK) {lineno = __LINE__; goto eRR;}
+ free(resp);
+
+ buf[0] = CMND_SIGN_OFF;
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_close(): Sending sign-off command: ",
+ progname);
+ jtagmkII_send(pgm, buf, 1);
+
+ status = jtagmkII_recv(pgm, &resp);
+ if (status <= 0) {
+ if (verbose >= 2)
+ putc('\n', stderr);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
+ "timeout/error communicating with programmer (status %d)\n",
+ progname, status);
+ return;
+ }
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ c = resp[0];
+ free(resp);
+ if (c != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_close(): "
+ "bad response to sign-off command: %s\n",
+ progname, jtagmkII_get_rc(c));
+ }
+
+ ret:
+ serial_close(&pgm->fd);
+ pgm->fd.ifd = -1;
+ return;
+
+ eRR:
+ avrdude_message(MSG_INFO, "%s: jtagmkII_reset32(): "
+ "failed at line %d (status=%x val=%lx)\n",
+ progname, lineno, status, val);
+ goto ret;
+}
+
+static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned int block_size;
+ unsigned int maxaddr = addr + n_bytes;
+ unsigned char cmd[7];
+ unsigned char *resp;
+ int lineno, status;
+ unsigned long val=0;
+ long otimeout = serial_recv_timeout;
+
+ avrdude_message(MSG_NOTICE2, "%s: jtagmkII_paged_load32(.., %s, %d, %d)\n",
+ progname, m->desc, page_size, n_bytes);
+
+ serial_recv_timeout = 256;
+
+ if(!(p->flags & AVRPART_WRITE)) {
+ status = jtagmkII_reset32(pgm, AVR32_RESET_READ);
+ if(status != 0) {lineno = __LINE__; goto eRR;}
+ }
+
+ // Init SMC and set clocks
+ if(!(p->flags & AVRPART_INIT_SMC)) {
+ status = jtagmkII_smc_init32(pgm);
+ if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
+ p->flags |= AVRPART_INIT_SMC;
+ }
+
+ // Init SMC and set clocks
+ if(!(p->flags & AVRPART_INIT_SMC)) {
+ status = jtagmkII_smc_init32(pgm);
+ if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
+ p->flags |= AVRPART_INIT_SMC;
+ }
+
+ //avrdude_message(MSG_INFO, "\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n",
+ // page_size, n_bytes, pages, m->offset, pgm->page_size);
+
+ cmd[0] = CMND_READ_MEMORY32;
+ cmd[1] = 0x40;
+ cmd[2] = 0x05;
+
+ for (; addr < maxaddr; addr += block_size) {
+ block_size = ((maxaddr-addr) < pgm->page_size) ? (maxaddr - addr) : pgm->page_size;
+ avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_load32(): "
+ "block_size at addr %d is %d\n",
+ progname, addr, block_size);
+
+ u32_to_b4r(cmd + 3, m->offset + addr);
+
+ status = jtagmkII_send(pgm, cmd, 7);
+ if(status<0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_recv(pgm, &resp);
+ if(status<0) {lineno = __LINE__; goto eRR;}
+
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ if (resp[0] != 0x87) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load32(): "
+ "bad response to write memory command: %s\n",
+ progname, jtagmkII_get_rc(resp[0]));
+ free(resp);
+ return -1;
+ }
+ memcpy(m->buf + addr, resp + 1, block_size);
+ free(resp);
+
+ }
+
+ serial_recv_timeout = otimeout;
+
+ status = jtagmkII_reset32(pgm, AVR32_SET4RUNNING);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ return addr;
+
+ eRR:
+ serial_recv_timeout = otimeout;
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_load32(): "
+ "failed at line %d (status=%x val=%lx)\n",
+ progname, lineno, status, val);
+ return -1;
+}
+
+static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned int block_size;
+ unsigned char *cmd=NULL;
+ unsigned char *resp;
+ int lineno, status, pages, sPageNum, pageNum, blocks;
+ unsigned long val=0;
+ unsigned long otimeout = serial_recv_timeout;
+ unsigned int maxaddr = addr + n_bytes;
+
+ serial_recv_timeout = 256;
+
+ if(n_bytes == 0) return -1;
+
+ status = jtagmkII_reset32(pgm, AVR32_RESET_WRITE);
+ if(status != 0) {lineno = __LINE__; goto eRR;}
+ p->flags |= AVRPART_WRITE;
+
+ pages = (n_bytes - addr - 1)/page_size + 1;
+ sPageNum = addr/page_size;
+ //avrdude_message(MSG_INFO, "\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n",
+ // page_size, n_bytes, pages, m->offset, pgm->page_size);
+
+ // Before any errors can happen
+ if ((cmd = malloc(pgm->page_size + 10)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write32(): Out of memory\n", progname);
+ return -1;
+ }
+
+ // Init SMC and set clocks
+ if(!(p->flags & AVRPART_INIT_SMC)) {
+ status = jtagmkII_smc_init32(pgm);
+ if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
+ p->flags |= AVRPART_INIT_SMC;
+ }
+
+ // First unlock the pages
+ for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
+ status =jtagmkII_flash_lock32(pgm, 0, pageNum);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+ }
+
+ // Then erase them (guess could do this in the same loop above?)
+ for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
+ status =jtagmkII_flash_erase32(pgm, pageNum);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+ }
+
+ cmd[0] = CMND_WRITE_MEMORY32;
+ u32_to_b4r(&cmd[1], 0x40000000); // who knows
+ cmd[5] = 0x5;
+
+ for(pageNum=sPageNum; pageNum < pages; ++pageNum) {
+
+ status = jtagmkII_flash_clear_pagebuffer32(pgm);
+ if(status != 0) {lineno = __LINE__; goto eRR;}
+
+ for(blocks=0; blocks<2; ++blocks) {
+ block_size = ((maxaddr-addr) < pgm->page_size) ? (maxaddr - addr) : pgm->page_size;
+ avrdude_message(MSG_DEBUG, "%s: jtagmkII_paged_write32(): "
+ "block_size at addr %d is %d\n",
+ progname, addr, block_size);
+
+ u32_to_b4r(cmd + 6, m->offset + addr);
+ memset(cmd + 10, 0xff, pgm->page_size);
+ memcpy(cmd + 10, m->buf + addr, block_size);
+
+ status = jtagmkII_send(pgm, cmd, pgm->page_size + 10);
+ if(status<0) {lineno = __LINE__; goto eRR;}
+ status = jtagmkII_recv(pgm, &resp);
+ if (status<0) {lineno = __LINE__; goto eRR;}
+
+ if (verbose >= 3) {
+ putc('\n', stderr);
+ jtagmkII_prmsg(pgm, resp, status);
+ } else if (verbose == 2)
+ avrdude_message(MSG_NOTICE2, "0x%02x (%d bytes msg)\n", resp[0], status);
+ if (resp[0] != RSP_OK) {
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write32(): "
+ "bad response to write memory command: %s\n",
+ progname, jtagmkII_get_rc(resp[0]));
+ free(resp);
+ free(cmd);
+ return -1;
+ }
+ free(resp);
+
+ addr += block_size;
+
+
+ }
+ status = jtagmkII_flash_write_page32(pgm, pageNum);
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+ }
+ free(cmd);
+ serial_recv_timeout = otimeout;
+
+ status = jtagmkII_reset32(pgm, AVR32_SET4RUNNING); // AVR32_SET4RUNNING | AVR32_RELEASE_JTAG
+ if(status < 0) {lineno = __LINE__; goto eRR;}
+
+ return addr;
+
+ eRR:
+ serial_recv_timeout = otimeout;
+ free(cmd);
+ avrdude_message(MSG_INFO, "%s: jtagmkII_paged_write32(): "
+ "failed at line %d (status=%x val=%lx)\n",
+ progname, lineno, status, val);
+ return -1;
+}
+
+
+static int jtagmkII_flash_lock32(PROGRAMMER * pgm, unsigned char lock, unsigned int page)
+{
+ int status, lineno, i;
+ unsigned long val, cmd=0;
+
+ for(i=0; i<256; ++i) {
+ val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
+ if(val == ERROR_SAB) continue;
+ if(val & AVR32_FLASHC_FSR_RDY) break;
+ }
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+ if(!(val&AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;} // Flash better be ready
+
+ page <<= 8;
+ cmd = AVR32_FLASHC_FCMD_KEY | page | (lock ? AVR32_FLASHC_FCMD_LOCK : AVR32_FLASHC_FCMD_UNLOCK);
+ status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+
+ return 0;
+
+ eRR:
+ avrdude_message(MSG_INFO, "%s: jtagmkII_flash_lock32(): "
+ "failed at line %d page %d cmd %8.8lx\n",
+ progname, lineno, page, cmd);
+ return -1;
+}
+
+static int jtagmkII_flash_erase32(PROGRAMMER * pgm, unsigned int page)
+{
+ int status, lineno, i;
+ unsigned long val=0, cmd=0, err=0;
+
+ for(i=0; i<256; ++i) {
+ val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
+ if(val == ERROR_SAB) continue;
+ if(val & AVR32_FLASHC_FSR_RDY) break;
+ }
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+ if(!(val&AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;} // Flash better be ready
+
+ page <<= 8;
+ cmd = AVR32_FLASHC_FCMD_KEY | page | AVR32_FLASHC_FCMD_ERASE_PAGE;
+ status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+
+//avrdude_message(MSG_INFO, "ERASE %x -> %x\n", cmd, AVR32_FLASHC_FCMD);
+
+ err = 0;
+ for(i=0; i<256; ++i) {
+ val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
+ if(val == ERROR_SAB) continue;
+ err |= val;
+ if(val & AVR32_FLASHC_FSR_RDY) break;
+ }
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+ if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;}
+ if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;}
+
+ return 0;
+
+ eRR:
+ avrdude_message(MSG_INFO, "%s: jtagmkII_flash_erase32(): "
+ "failed at line %d page %d cmd %8.8lx val %lx\n",
+ progname, lineno, page, cmd, val);
+ return -1;
+}
+
+static int jtagmkII_flash_write_page32(PROGRAMMER * pgm, unsigned int page)
+{
+ int status, lineno, i;
+ unsigned long val=0, cmd, err;
+
+ page <<= 8;
+ cmd = AVR32_FLASHC_FCMD_KEY | page | AVR32_FLASHC_FCMD_WRITE_PAGE;
+ status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+
+ err = 0;
+ for(i=0; i<256; ++i) {
+ val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
+ if(val == ERROR_SAB) continue;
+ err |= val;
+ if(val & AVR32_FLASHC_FSR_RDY) break;
+ }
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+ if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;}
+ if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;}
+
+ return 0;
+
+ eRR:
+ avrdude_message(MSG_INFO, "%s: jtagmkII_flash_write_page32(): "
+ "failed at line %d page %d cmd %8.8lx val %lx\n",
+ progname, lineno, page, cmd, val);
+ return -1;
+}
+
+static int jtagmkII_flash_clear_pagebuffer32(PROGRAMMER * pgm)
+{
+ int status, lineno, i;
+ unsigned long val=0, cmd, err;
+
+ cmd = AVR32_FLASHC_FCMD_KEY | AVR32_FLASHC_FCMD_CLEAR_PAGE_BUFFER;
+ status = jtagmkII_write_SABaddr(pgm, AVR32_FLASHC_FCMD, 0x05, cmd);
+ if (status < 0) {lineno = __LINE__; goto eRR;}
+
+ err = 0;
+ for(i=0; i<256; ++i) {
+ val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
+ if(val == ERROR_SAB) continue;
+ err |= val;
+ if(val & AVR32_FLASHC_FSR_RDY) break;
+ }
+ if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+ if(!(val & AVR32_FLASHC_FSR_RDY)) {lineno = __LINE__; goto eRR;}
+ if(err & AVR32_FLASHC_FSR_ERR) {lineno = __LINE__; goto eRR;}
+
+ return 0;
+
+ eRR:
+ avrdude_message(MSG_INFO, "%s: jtagmkII_flash_clear_pagebuffer32(): "
+ "failed at line %d cmd %8.8lx val %lx\n",
+ progname, lineno, cmd, val);
+ return -1;
+}
+
+#ifdef __OBJC__
+#pragma mark -
+#endif
+
+const char jtagmkII_desc[] = "Atmel JTAG ICE mkII";
+
+void jtagmkII_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "JTAGMKII");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = jtagmkII_initialize;
+ pgm->display = jtagmkII_display;
+ pgm->enable = jtagmkII_enable;
+ pgm->disable = jtagmkII_disable;
+ pgm->program_enable = jtagmkII_program_enable_INFO;
+ pgm->chip_erase = jtagmkII_chip_erase;
+ pgm->open = jtagmkII_open;
+ pgm->close = jtagmkII_close;
+ pgm->read_byte = jtagmkII_read_byte;
+ pgm->write_byte = jtagmkII_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = jtagmkII_paged_write;
+ pgm->paged_load = jtagmkII_paged_load;
+ pgm->page_erase = jtagmkII_page_erase;
+ pgm->print_parms = jtagmkII_print_parms;
+ pgm->set_sck_period = jtagmkII_set_sck_period;
+ pgm->parseextparams = jtagmkII_parseextparms;
+ pgm->setup = jtagmkII_setup;
+ pgm->teardown = jtagmkII_teardown;
+ pgm->page_size = 256;
+ pgm->flag = PGM_FL_IS_JTAG;
+}
+
+const char jtagmkII_dw_desc[] = "Atmel JTAG ICE mkII in debugWire mode";
+
+void jtagmkII_dw_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "JTAGMKII_DW");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = jtagmkII_initialize;
+ pgm->display = jtagmkII_display;
+ pgm->enable = jtagmkII_enable;
+ pgm->disable = jtagmkII_disable;
+ pgm->program_enable = jtagmkII_program_enable_INFO;
+ pgm->chip_erase = jtagmkII_chip_erase_dw;
+ pgm->open = jtagmkII_open_dw;
+ pgm->close = jtagmkII_close;
+ pgm->read_byte = jtagmkII_read_byte;
+ pgm->write_byte = jtagmkII_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = jtagmkII_paged_write;
+ pgm->paged_load = jtagmkII_paged_load;
+ pgm->print_parms = jtagmkII_print_parms;
+ pgm->setup = jtagmkII_setup;
+ pgm->teardown = jtagmkII_teardown;
+ pgm->page_size = 256;
+ pgm->flag = PGM_FL_IS_DW;
+}
+
+const char jtagmkII_pdi_desc[] = "Atmel JTAG ICE mkII in PDI mode";
+
+void jtagmkII_pdi_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "JTAGMKII_PDI");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = jtagmkII_initialize;
+ pgm->display = jtagmkII_display;
+ pgm->enable = jtagmkII_enable;
+ pgm->disable = jtagmkII_disable;
+ pgm->program_enable = jtagmkII_program_enable_INFO;
+ pgm->chip_erase = jtagmkII_chip_erase;
+ pgm->open = jtagmkII_open_pdi;
+ pgm->close = jtagmkII_close;
+ pgm->read_byte = jtagmkII_read_byte;
+ pgm->write_byte = jtagmkII_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = jtagmkII_paged_write;
+ pgm->paged_load = jtagmkII_paged_load;
+ pgm->page_erase = jtagmkII_page_erase;
+ pgm->print_parms = jtagmkII_print_parms;
+ pgm->setup = jtagmkII_setup;
+ pgm->teardown = jtagmkII_teardown;
+ pgm->page_size = 256;
+ pgm->flag = PGM_FL_IS_PDI;
+}
+
+const char jtagmkII_dragon_desc[] = "Atmel AVR Dragon in JTAG mode";
+
+void jtagmkII_dragon_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "DRAGON_JTAG");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = jtagmkII_initialize;
+ pgm->display = jtagmkII_display;
+ pgm->enable = jtagmkII_enable;
+ pgm->disable = jtagmkII_disable;
+ pgm->program_enable = jtagmkII_program_enable_INFO;
+ pgm->chip_erase = jtagmkII_chip_erase;
+ pgm->open = jtagmkII_dragon_open;
+ pgm->close = jtagmkII_close;
+ pgm->read_byte = jtagmkII_read_byte;
+ pgm->write_byte = jtagmkII_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = jtagmkII_paged_write;
+ pgm->paged_load = jtagmkII_paged_load;
+ pgm->page_erase = jtagmkII_page_erase;
+ pgm->print_parms = jtagmkII_print_parms;
+ pgm->set_sck_period = jtagmkII_set_sck_period;
+ pgm->parseextparams = jtagmkII_parseextparms;
+ pgm->setup = jtagmkII_setup;
+ pgm->teardown = jtagmkII_teardown;
+ pgm->page_size = 256;
+ pgm->flag = PGM_FL_IS_JTAG;
+}
+
+const char jtagmkII_dragon_dw_desc[] = "Atmel AVR Dragon in debugWire mode";
+
+void jtagmkII_dragon_dw_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "DRAGON_DW");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = jtagmkII_initialize;
+ pgm->display = jtagmkII_display;
+ pgm->enable = jtagmkII_enable;
+ pgm->disable = jtagmkII_disable;
+ pgm->program_enable = jtagmkII_program_enable_INFO;
+ pgm->chip_erase = jtagmkII_chip_erase_dw;
+ pgm->open = jtagmkII_dragon_open_dw;
+ pgm->close = jtagmkII_close;
+ pgm->read_byte = jtagmkII_read_byte;
+ pgm->write_byte = jtagmkII_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = jtagmkII_paged_write;
+ pgm->paged_load = jtagmkII_paged_load;
+ pgm->print_parms = jtagmkII_print_parms;
+ pgm->setup = jtagmkII_setup;
+ pgm->teardown = jtagmkII_teardown;
+ pgm->page_size = 256;
+ pgm->flag = PGM_FL_IS_DW;
+}
+
+const char jtagmkII_avr32_desc[] = "Atmel JTAG ICE mkII in AVR32 mode";
+
+void jtagmkII_avr32_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "JTAGMKII_AVR32");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = jtagmkII_initialize32;
+ pgm->display = jtagmkII_display;
+ pgm->enable = jtagmkII_enable;
+ pgm->disable = jtagmkII_disable;
+ pgm->program_enable = jtagmkII_program_enable_INFO;
+ pgm->chip_erase = jtagmkII_chip_erase32;
+ pgm->open = jtagmkII_open32;
+ pgm->close = jtagmkII_close32;
+ pgm->read_byte = jtagmkII_read_byte;
+ pgm->write_byte = jtagmkII_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = jtagmkII_paged_write32;
+ pgm->paged_load = jtagmkII_paged_load32;
+ pgm->print_parms = jtagmkII_print_parms;
+ //pgm->set_sck_period = jtagmkII_set_sck_period;
+ //pgm->parseextparams = jtagmkII_parseextparms;
+ pgm->setup = jtagmkII_setup;
+ pgm->teardown = jtagmkII_teardown;
+ pgm->page_size = 256;
+ pgm->flag = PGM_FL_IS_JTAG;
+}
+
+const char jtagmkII_dragon_pdi_desc[] = "Atmel AVR Dragon in PDI mode";
+
+void jtagmkII_dragon_pdi_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "DRAGON_PDI");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = jtagmkII_initialize;
+ pgm->display = jtagmkII_display;
+ pgm->enable = jtagmkII_enable;
+ pgm->disable = jtagmkII_disable;
+ pgm->program_enable = jtagmkII_program_enable_INFO;
+ pgm->chip_erase = jtagmkII_chip_erase;
+ pgm->open = jtagmkII_dragon_open_pdi;
+ pgm->close = jtagmkII_close;
+ pgm->read_byte = jtagmkII_read_byte;
+ pgm->write_byte = jtagmkII_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = jtagmkII_paged_write;
+ pgm->paged_load = jtagmkII_paged_load;
+ pgm->page_erase = jtagmkII_page_erase;
+ pgm->print_parms = jtagmkII_print_parms;
+ pgm->setup = jtagmkII_setup;
+ pgm->teardown = jtagmkII_teardown;
+ pgm->page_size = 256;
+ pgm->flag = PGM_FL_IS_PDI;
+}
+
diff --git a/xs/src/avrdude/jtagmkII.h b/xs/src/avrdude/jtagmkII.h
new file mode 100644
index 000000000..aa79c18d2
--- /dev/null
+++ b/xs/src/avrdude/jtagmkII.h
@@ -0,0 +1,63 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2002-2004, 2006 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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 jtagmkII_h
+#define jtagmkII_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len);
+int jtagmkII_recv(PROGRAMMER * pgm, unsigned char **msg);
+void jtagmkII_close(PROGRAMMER * pgm);
+int jtagmkII_getsync(PROGRAMMER * pgm, int mode);
+int jtagmkII_getparm(PROGRAMMER * pgm, unsigned char parm,
+ unsigned char * value);
+
+extern const char jtagmkII_desc[];
+extern const char jtagmkII_avr32_desc[];
+extern const char jtagmkII_dw_desc[];
+extern const char jtagmkII_pdi_desc[];
+extern const char jtagmkII_dragon_desc[];
+extern const char jtagmkII_dragon_dw_desc[];
+extern const char jtagmkII_dragon_pdi_desc[];
+void jtagmkII_initpgm (PROGRAMMER * pgm);
+void jtagmkII_avr32_initpgm (PROGRAMMER * pgm);
+void jtagmkII_dw_initpgm (PROGRAMMER * pgm);
+void jtagmkII_pdi_initpgm (PROGRAMMER * pgm);
+void jtagmkII_dragon_initpgm (PROGRAMMER * pgm);
+void jtagmkII_dragon_dw_initpgm (PROGRAMMER * pgm);
+void jtagmkII_dragon_pdi_initpgm (PROGRAMMER * pgm);
+
+/*
+ * These functions are referenced from stk500v2.c for JTAG ICE mkII
+ * and AVR Dragon programmers running in one of the STK500v2
+ * modi.
+ */
+void jtagmkII_setup(PROGRAMMER * pgm);
+void jtagmkII_teardown(PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/xs/src/avrdude/jtagmkII_private.h b/xs/src/avrdude/jtagmkII_private.h
new file mode 100644
index 000000000..6df8f6f23
--- /dev/null
+++ b/xs/src/avrdude/jtagmkII_private.h
@@ -0,0 +1,385 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2005, 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ *
+ * 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$ */
+
+
+/*
+ * JTAG ICE mkII definitions
+ * Taken from Appnote AVR067
+ */
+
+#if !defined(JTAGMKII_PRIVATE_EXPORTED)
+/*
+ * Communication with the JTAG ICE works in frames. The protocol
+ * somewhat resembles the STK500v2 protocol, yet it is sufficiently
+ * different to prevent a direct code reuse. :-(
+ *
+ * Frame format:
+ *
+ * +---------------------------------------------------------------+
+ * | 0 | 1 . 2 | 3 . 4 . 5 . 6 | 7 | ... | N-1 . N |
+ * | | | | | | |
+ * | start | LSB MSB | LSB ....... MSB | token | msg | LSB MSB |
+ * | 0x1B | sequence# | message size | 0x0E | | CRC16 |
+ * +---------------------------------------------------------------+
+ *
+ * Each request message will be returned by a response with a matching
+ * sequence #. Sequence # 0xffff is reserved for asynchronous event
+ * notifications that will be sent by the ICE without a request
+ * message (e.g. when the target hit a breakpoint).
+ *
+ * The message size excludes the framing overhead (10 bytes).
+ *
+ * The first byte of the message is always the request or response
+ * code, which is roughly classified as:
+ *
+ * . Messages (commands) use 0x00 through 0x3f. (The documentation
+ * claims that messages start at 0x01, but actually CMND_SIGN_OFF is
+ * 0x00.)
+ * . Internal commands use 0x40 through 0x7f (not documented).
+ * . Success responses use 0x80 through 0x9f.
+ * . Failure responses use 0xa0 through 0xbf.
+ * . Events use 0xe0 through 0xff.
+ */
+#define MESSAGE_START 0x1b
+#define TOKEN 0x0e
+
+/*
+ * Max message size we are willing to accept. Prevents us from trying
+ * to allocate too much VM in case we received a nonsensical packet
+ * length. We have to allocate the buffer as soon as we've got the
+ * length information (and thus have to trust that information by that
+ * time at first), as the final CRC check can only be done once the
+ * entire packet came it.
+ */
+#define MAX_MESSAGE 100000
+
+#endif /* JTAGMKII_PRIVATE_EXPORTED */
+
+/* ICE command codes */
+#define CMND_SIGN_OFF 0x00
+#define CMND_GET_SIGN_ON 0x01
+#define CMND_SET_PARAMETER 0x02
+#define CMND_GET_PARAMETER 0x03
+#define CMND_WRITE_MEMORY 0x04
+#define CMND_READ_MEMORY 0x05
+#define CMND_WRITE_PC 0x06
+#define CMND_READ_PC 0x07
+#define CMND_GO 0x08
+#define CMND_SINGLE_STEP 0x09
+#define CMND_FORCED_STOP 0x0A
+#define CMND_RESET 0x0B
+#define CMND_SET_DEVICE_DESCRIPTOR 0x0C
+#define CMND_ERASEPAGE_SPM 0x0D
+#define CMND_GET_SYNC 0x0f
+#define CMND_SELFTEST 0x10
+#define CMND_SET_BREAK 0x11
+#define CMND_GET_BREAK 0x12
+#define CMND_CHIP_ERASE 0x13
+#define CMND_ENTER_PROGMODE 0x14
+#define CMND_LEAVE_PROGMODE 0x15
+#define CMND_SET_N_PARAMETERS 0x16
+#define CMND_CLR_BREAK 0x1A
+#define CMND_RUN_TO_ADDR 0x1C
+#define CMND_SPI_CMD 0x1D
+#define CMND_CLEAR_EVENTS 0x22
+#define CMND_RESTORE_TARGET 0x23
+#define CMND_GET_IR 0x24
+#define CMND_GET_xxx 0x25
+#define CMND_WRITE_SAB 0x28
+#define CMND_READ_SAB 0x29
+#define CMND_RESET_AVR 0x2B
+#define CMND_READ_MEMORY32 0x2C
+#define CMND_WRITE_MEMORY32 0x2D
+#define CMND_ISP_PACKET 0x2F
+#define CMND_XMEGA_ERASE 0x34
+#define CMND_SET_XMEGA_PARAMS 0x36 // undocumented in AVR067
+
+
+/* ICE responses */
+#define RSP_OK 0x80
+#define RSP_PARAMETER 0x81
+#define RSP_MEMORY 0x82
+#define RSP_GET_BREAK 0x83
+#define RSP_PC 0x84
+#define RSP_SELFTEST 0x85
+#define RSP_SIGN_ON 0x86
+#define RSP_SPI_DATA 0x88
+#define RSP_FAILED 0xA0
+#define RSP_ILLEGAL_PARAMETER 0xA1
+#define RSP_ILLEGAL_MEMORY_TYPE 0xA2
+#define RSP_ILLEGAL_MEMORY_RANGE 0xA3
+#define RSP_ILLEGAL_EMULATOR_MODE 0xA4
+#define RSP_ILLEGAL_MCU_STATE 0xA5
+#define RSP_ILLEGAL_VALUE 0xA6
+#define RSP_SET_N_PARAMETERS 0xA7
+#define RSP_ILLEGAL_BREAKPOINT 0xA8
+#define RSP_ILLEGAL_JTAG_ID 0xA9
+#define RSP_ILLEGAL_COMMAND 0xAA
+#define RSP_NO_TARGET_POWER 0xAB
+#define RSP_DEBUGWIRE_SYNC_FAILED 0xAC
+#define RSP_ILLEGAL_POWER_STATE 0xAD
+
+/* ICE events */
+#define EVT_BREAK 0xE0
+#define EVT_RUN 0xE1
+#define EVT_ERROR_PHY_FORCE_BREAK_TIMEOUT 0xE2
+#define EVT_ERROR_PHY_RELEASE_BREAK_TIMEOUT 0xE3
+#define EVT_TARGET_POWER_ON 0xE4
+#define EVT_TARGET_POWER_OFF 0xE5
+#define EVT_DEBUG 0xE6
+#define EVT_EXT_RESET 0xE7
+#define EVT_TARGET_SLEEP 0xE8
+#define EVT_TARGET_WAKEUP 0xE9
+#define EVT_ICE_POWER_ERROR_STATE 0xEA
+#define EVT_ICE_POWER_OK 0xEB
+#define EVT_IDR_DIRTY 0xEC
+#define EVT_ERROR_PHY_MAX_BIT_LENGTH_DIFF 0xED
+#define EVT_NONE 0xEF
+#define EVT_ERROR_PHY_SYNC_TIMEOUT 0xF0
+#define EVT_PROGRAM_BREAK 0xF1
+#define EVT_PDSB_BREAK 0xF2
+#define EVT_PDSMB_BREAK 0xF3
+#define EVT_ERROR_PHY_SYNC_TIMEOUT_BAUD 0xF4
+#define EVT_ERROR_PHY_SYNC_OUT_OF_RANGE 0xF5
+#define EVT_ERROR_PHY_SYNC_WAIT_TIMEOUT 0xF6
+#define EVT_ERROR_PHY_RECEIVE_TIMEOUT 0xF7
+#define EVT_ERROR_PHY_RECEIVED_BREAK 0xF8
+#define EVT_ERROR_PHY_OPT_RECEIVE_TIMEOUT 0xF9
+#define EVT_ERROR_PHY_OPT_RECEIVED_BREAK 0xFA
+#define EVT_RESULT_PHY_NO_ACTIVITY 0xFB
+
+/* memory types for CMND_{READ,WRITE}_MEMORY */
+#define MTYPE_IO_SHADOW 0x30 /* cached IO registers? */
+#define MTYPE_SRAM 0x20 /* target's SRAM or [ext.] IO registers */
+#define MTYPE_EEPROM 0x22 /* EEPROM, what way? */
+#define MTYPE_EVENT 0x60 /* ICE event memory */
+#define MTYPE_SPM 0xA0 /* flash through LPM/SPM */
+#define MTYPE_FLASH_PAGE 0xB0 /* flash in programming mode */
+#define MTYPE_EEPROM_PAGE 0xB1 /* EEPROM in programming mode */
+#define MTYPE_FUSE_BITS 0xB2 /* fuse bits in programming mode */
+#define MTYPE_LOCK_BITS 0xB3 /* lock bits in programming mode */
+#define MTYPE_SIGN_JTAG 0xB4 /* signature in programming mode */
+#define MTYPE_OSCCAL_BYTE 0xB5 /* osccal cells in programming mode */
+#define MTYPE_CAN 0xB6 /* CAN mailbox */
+#define MTYPE_FLASH 0xc0 /* xmega (app.) flash - undocumented in AVR067 */
+#define MTYPE_BOOT_FLASH 0xc1 /* xmega boot flash - undocumented in AVR067 */
+#define MTYPE_EEPROM_XMEGA 0xc4 /* xmega EEPROM in debug mode - undocumented in AVR067 */
+#define MTYPE_USERSIG 0xc5 /* xmega user signature - undocumented in AVR067 */
+#define MTYPE_PRODSIG 0xc6 /* xmega production signature - undocumented in AVR067 */
+
+/* (some) ICE parameters, for CMND_{GET,SET}_PARAMETER */
+#define PAR_HW_VERSION 0x01
+#define PAR_FW_VERSION 0x02
+#define PAR_EMULATOR_MODE 0x03
+# define EMULATOR_MODE_DEBUGWIRE 0x00
+# define EMULATOR_MODE_JTAG 0x01
+# define EMULATOR_MODE_HV 0x02 /* HVSP or PP mode of AVR Dragon */
+# define EMULATOR_MODE_SPI 0x03
+# define EMULATOR_MODE_JTAG_AVR32 0x04
+# define EMULATOR_MODE_JTAG_XMEGA 0x05
+# define EMULATOR_MODE_PDI 0x06
+#define PAR_IREG 0x04
+#define PAR_BAUD_RATE 0x05
+# define PAR_BAUD_2400 0x01
+# define PAR_BAUD_4800 0x02
+# define PAR_BAUD_9600 0x03
+# define PAR_BAUD_19200 0x04 /* default */
+# define PAR_BAUD_38400 0x05
+# define PAR_BAUD_57600 0x06
+# define PAR_BAUD_115200 0x07
+# define PAR_BAUD_14400 0x08
+#define PAR_OCD_VTARGET 0x06
+#define PAR_OCD_JTAG_CLK 0x07
+#define PAR_OCD_BREAK_CAUSE 0x08
+#define PAR_TIMERS_RUNNING 0x09
+#define PAR_BREAK_ON_CHANGE_FLOW 0x0A
+#define PAR_BREAK_ADDR1 0x0B
+#define PAR_BREAK_ADDR2 0x0C
+#define PAR_COMBBREAKCTRL 0x0D
+#define PAR_JTAGID 0x0E
+#define PAR_UNITS_BEFORE 0x0F
+#define PAR_UNITS_AFTER 0x10
+#define PAR_BIT_BEFORE 0x11
+#define PAR_BIT_ATER 0x12
+#define PAR_EXTERNAL_RESET 0x13
+#define PAR_FLASH_PAGE_SIZE 0x14
+#define PAR_EEPROM_PAGE_SIZE 0x15
+#define PAR_UNUSED1 0x16
+#define PAR_PSB0 0x17
+#define PAR_PSB1 0x18
+#define PAR_PROTOCOL_DEBUG_EVENT 0x19
+#define PAR_MCU_STATE 0x1A
+# define STOPPED 0x00
+# define RUNNING 0x01
+# define PROGRAMMING 0x02
+#define PAR_DAISY_CHAIN_INFO 0x1B
+#define PAR_BOOT_ADDRESS 0x1C
+#define PAR_TARGET_SIGNATURE 0x1D
+#define PAR_DEBUGWIRE_BAUDRATE 0x1E
+#define PAR_PROGRAM_ENTRY_POINT 0x1F
+#define PAR_PDI_OFFSET_START 0x32
+#define PAR_PDI_OFFSET_END 0x33
+#define PAR_PACKET_PARSING_ERRORS 0x40
+#define PAR_VALID_PACKETS_RECEIVED 0x41
+#define PAR_INTERCOMMUNICATION_TX_FAILURES 0x42
+#define PAR_INTERCOMMUNICATION_RX_FAILURES 0x43
+#define PAR_CRC_ERRORS 0x44
+#define PAR_POWER_SOURCE 0x45
+# define POWER_EXTERNAL 0x00
+# define POWER_USB 0x01
+#define PAR_CAN_FLAG 0x22
+# define DONT_READ_CAN_MAILBOX 0x00
+# define READ_CAN_MAILBOX 0x01
+#define PAR_ENABLE_IDR_IN_RUN_MODE 0x23
+# define ACCESS_OSCCAL 0x00
+# define ACCESS_IDR 0x01
+#define PAR_ALLOW_PAGEPROGRAMMING_IN_SCANCHAIN 0x24
+# define PAGEPROG_NOT_ALLOWED 0x00
+# define PAGEPROG_ALLOWED 0x01
+
+/* Xmega erase memory types, for CMND_XMEGA_ERASE */
+#define XMEGA_ERASE_CHIP 0x00
+#define XMEGA_ERASE_APP 0x01
+#define XMEGA_ERASE_BOOT 0x02
+#define XMEGA_ERASE_EEPROM 0x03
+#define XMEGA_ERASE_APP_PAGE 0x04
+#define XMEGA_ERASE_BOOT_PAGE 0x05
+#define XMEGA_ERASE_EEPROM_PAGE 0x06
+#define XMEGA_ERASE_USERSIG 0x07
+
+/* AVR32 related definitions */
+#define AVR32_FLASHC_FCR 0xFFFE1400
+#define AVR32_FLASHC_FCMD 0xFFFE1404
+#define AVR32_FLASHC_FCMD_KEY 0xA5000000
+#define AVR32_FLASHC_FCMD_WRITE_PAGE 1
+#define AVR32_FLASHC_FCMD_ERASE_PAGE 2
+#define AVR32_FLASHC_FCMD_CLEAR_PAGE_BUFFER 3
+#define AVR32_FLASHC_FCMD_LOCK 4
+#define AVR32_FLASHC_FCMD_UNLOCK 5
+#define AVR32_FLASHC_FSR 0xFFFE1408
+#define AVR32_FLASHC_FSR_RDY 0x00000001
+#define AVR32_FLASHC_FSR_ERR 0x00000008
+#define AVR32_FLASHC_FGPFRHI 0xFFFE140C
+#define AVR32_FLASHC_FGPFRLO 0xFFFE1410
+
+#define AVR32_DC 0x00000008
+#define AVR32_DS 0x00000010
+#define AVR32_DINST 0x00000104
+#define AVR32_DCCPU 0x00000110
+#define AVR32_DCEMU 0x00000114
+#define AVR32_DCSR 0x00000118
+
+#define AVR32_DC_ABORT 0x80000000
+#define AVR32_DC_RESET 0x40000000
+#define AVR32_DC_DBE 0x00002000
+#define AVR32_DC_DBR 0x00001000
+
+#define AVR32_RESET_READ 0x0001
+#define AVR32_RESET_WRITE 0x0002
+#define AVR32_RESET_CHIP_ERASE 0x0004
+#define AVR32_SET4RUNNING 0x0008
+//#define AVR32_RESET_COMMON (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE )
+
+
+#if !defined(JTAGMKII_PRIVATE_EXPORTED)
+/*
+ * In appnote AVR067, struct device_descriptor is written with
+ * int/long field types. We cannot use them directly, as they were
+ * neither properly aligned for portability, nor did they care for
+ * endianess issues. We thus use arrays of unsigned chars, plus
+ * conversion macros.
+ */
+struct device_descriptor
+{
+ unsigned char ucReadIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
+ unsigned char ucReadIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
+ unsigned char ucWriteIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
+ unsigned char ucWriteIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
+ unsigned char ucReadExtIO[52]; /*LSB = IOloc 96, MSB = IOloc511 */
+ unsigned char ucReadIOExtShadow[52]; /*LSB = IOloc 96, MSB = IOloc511 */
+ unsigned char ucWriteExtIO[52]; /*LSB = IOloc 96, MSB = IOloc511 */
+ unsigned char ucWriteIOExtShadow[52];/*LSB = IOloc 96, MSB = IOloc511 */
+ unsigned char ucIDRAddress; /*IDR address */
+ unsigned char ucSPMCRAddress; /*SPMCR Register address and dW BasePC */
+ unsigned char ucRAMPZAddress; /*RAMPZ Register address in SRAM I/O */
+ /*space */
+ unsigned char uiFlashPageSize[2]; /*Device Flash Page Size, Size = */
+ /*2 exp ucFlashPageSize */
+ unsigned char ucEepromPageSize; /*Device Eeprom Page Size in bytes */
+ unsigned char ulBootAddress[4]; /*Device Boot Loader Start Address */
+ unsigned char uiUpperExtIOLoc[2]; /*Topmost (last) extended I/O */
+ /*location, 0 if no external I/O */
+ unsigned char ulFlashSize[4]; /*Device Flash Size */
+ unsigned char ucEepromInst[20]; /*Instructions for W/R EEPROM */
+ unsigned char ucFlashInst[3]; /*Instructions for W/R FLASH */
+ unsigned char ucSPHaddr; /* stack pointer high */
+ unsigned char ucSPLaddr; /* stack pointer low */
+ /* new as of 16-02-2004 */
+ unsigned char uiFlashpages[2]; /* number of pages in flash */
+ unsigned char ucDWDRAddress; /* DWDR register address */
+ unsigned char ucDWBasePC; /* base/mask value of the PC */
+ /* new as of 30-04-2004 */
+ unsigned char ucAllowFullPageBitstream; /* FALSE on ALL new */
+ /*parts */
+ unsigned char uiStartSmallestBootLoaderSection[2]; /* */
+ /* new as of 18-10-2004 */
+ unsigned char EnablePageProgramming; /* For JTAG parts only, */
+ /* default TRUE */
+ unsigned char ucCacheType; /* CacheType_Normal 0x00, */
+ /* CacheType_CAN 0x01, */
+ /* CacheType_HEIMDALL 0x02 */
+ /* new as of 27-10-2004 */
+ unsigned char uiSramStartAddr[2]; /* Start of SRAM */
+ unsigned char ucResetType; /* Selects reset type. ResetNormal = 0x00 */
+ /* ResetAT76CXXX = 0x01 */
+ unsigned char ucPCMaskExtended; /* For parts with extended PC */
+ unsigned char ucPCMaskHigh; /* PC high mask */
+ unsigned char ucEindAddress; /* Selects reset type. [EIND address...] */
+ /* new as of early 2005, firmware 4.x */
+ unsigned char EECRAddress[2]; /* EECR memory-mapped IO address */
+};
+
+/* New Xmega device descriptor, for firmware version 7 and above */
+struct xmega_device_desc {
+ unsigned char whatever[2]; // cannot guess; must be 0x0002
+ unsigned char datalen; // length of the following data, = 47
+ unsigned char nvm_app_offset[4]; // NVM offset for application flash
+ unsigned char nvm_boot_offset[4]; // NVM offset for boot flash
+ unsigned char nvm_eeprom_offset[4]; // NVM offset for EEPROM
+ unsigned char nvm_fuse_offset[4]; // NVM offset for fuses
+ unsigned char nvm_lock_offset[4]; // NVM offset for lock bits
+ unsigned char nvm_user_sig_offset[4]; // NVM offset for user signature row
+ unsigned char nvm_prod_sig_offset[4]; // NVM offset for production sign. row
+ unsigned char nvm_data_offset[4]; // NVM offset for data memory (SRAM + IO)
+ unsigned char app_size[4]; // size of application flash
+ unsigned char boot_size[2]; // size of boot flash
+ unsigned char flash_page_size[2]; // flash page size
+ unsigned char eeprom_size[2]; // size of EEPROM
+ unsigned char eeprom_page_size; // EEPROM page size
+ unsigned char nvm_base_addr[2]; // IO space base address of NVM controller
+ unsigned char mcu_base_addr[2]; // IO space base address of MCU control
+};
+#endif /* JTAGMKII_PRIVATE_EXPORTED */
+
+/* return code from jtagmkII_getsync() to indicate a "graceful"
+ * failure, i.e. an attempt to enable ISP failed and should be
+ * eventually retried */
+#define JTAGII_GETSYNC_FAIL_GRACEFUL (-2)
diff --git a/xs/src/avrdude/jtagmkI_private.h b/xs/src/avrdude/jtagmkI_private.h
new file mode 100644
index 000000000..7d5e247a9
--- /dev/null
+++ b/xs/src/avrdude/jtagmkI_private.h
@@ -0,0 +1,168 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2005 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ *
+ * 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$ */
+
+
+/*
+ * JTAG ICE mkI definitions
+ */
+
+/* ICE command codes */
+/* 0x20 Get Synch [Resp_OK] */
+#define CMD_GET_SYNC ' '
+
+/* 0x31 Single Step [Sync_CRC/EOP] [Resp_OK] */
+/* 0x32 Read PC [Sync_CRC/EOP] [Resp_OK] [program counter]
+ * [Resp_OK] */
+/* 0x33 Write PC [program counter] [Sync_CRC/EOP] [Resp_OK]
+ * [Resp_OK] */
+/* 0xA2 Firmware Upgrade [upgrade string] [Sync_CRC/EOP] [Resp_OK]
+ * [Resp_OK] */
+/* 0xA0 Set Device Descriptor [device info] [Sync_CRC/EOP] [Resp_OK]
+ * [Resp_OK] */
+#define CMD_SET_DEVICE_DESCRIPTOR 0xA0
+
+/* 0x42 Set Parameter [parameter] [setting] [Sync_CRC/EOP] [Resp_OK]
+ * [Resp_OK] */
+#define CMD_SET_PARAM 'B'
+
+/* 0x46 Forced Stop [Sync_CRC/EOP] [Resp_OK] [checksum][program
+ * counter] [Resp_OK] */
+#define CMD_STOP 'F'
+
+/* 0x47 Go [Sync_CRC/EOP] [Resp_OK] */
+#define CMD_GO 'G'
+
+/* 0x52 Read Memory [memory type] [word count] [start address]
+ * [Sync_CRC/EOP] [Resp_OK] [word 0] ... [word n] [checksum]
+ * [Resp_OK] */
+#define CMD_READ_MEM 'R'
+
+/* 0x53 Get Sign On [Sync_CRC/EOP] [Resp_OK] ["AVRNOCD"] [Resp_OK] */
+#define CMD_GET_SIGNON 'S'
+
+/* 0XA1 Erase Page spm [address] [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
+
+/* 0x57 Write Memory [memory type] [word count] [start address]
+ * [Sync_CRC/EOP] [Resp_OK] [Cmd_DATA] [word 0] ... [word n] */
+#define CMD_WRITE_MEM 'W'
+
+/* Second half of write memory: the data command. Undocumented. */
+#define CMD_DATA 'h'
+
+/* 0x64 Get Debug Info [Sync_CRC/EOP] [Resp_OK] [0x00] [Resp_OK] */
+/* 0x71 Get Parameter [parameter] [Sync_CRC/EOP] [Resp_OK] [setting]
+ * [Resp_OK] */
+#define CMD_GET_PARAM 'q'
+
+/* 0x78 Reset [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
+#define CMD_RESET 'x'
+
+/* 0xA3 Enter Progmode [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
+#define CMD_ENTER_PROGMODE 0xa3
+
+/* 0xA4 Leave Progmode [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
+#define CMD_LEAVE_PROGMODE 0xa4
+
+/* 0xA5 Chip Erase [Sync_CRC/EOP] [Resp_OK] [Resp_OK] */
+#define CMD_CHIP_ERASE 0xa5
+
+
+/* ICE responses */
+#define RESP_OK 'A'
+#define RESP_BREAK 'B'
+#define RESP_INFO 'G'
+#define RESP_FAILED 'F'
+#define RESP_SYNC_ERROR 'E'
+#define RESP_SLEEP 'H'
+#define RESP_POWER 'I'
+
+#define PARM_BITRATE 'b'
+#define PARM_SW_VERSION 0x7b
+#define PARM_HW_VERSION 0x7a
+#define PARM_IREG_HIGH 0x81
+#define PARM_IREG_LOW 0x82
+#define PARM_OCD_VTARGET 0x84
+#define PARM_OCD_BREAK_CAUSE 0x85
+#define PARM_CLOCK 0x86
+#define PARM_EXTERNAL_RESET 0x8b
+#define PARM_FLASH_PAGESIZE_LOW 0x88
+#define PARM_FLASH_PAGESIZE_HIGH 0x89
+#define PARM_EEPROM_PAGESIZE 0x8a
+#define PARM_TIMERS_RUNNING 0xa0
+#define PARM_BP_FLOW 0xa1
+#define PARM_BP_X_HIGH 0xa2
+#define PARM_BP_X_LOW 0xa3
+#define PARM_BP_Y_HIGH 0xa4
+#define PARM_BP_Y_LOW 0xa5
+#define PARM_BP_MODE 0xa6
+#define PARM_JTAGID_BYTE0 0xa7
+#define PARM_JTAGID_BYTE1 0xa8
+#define PARM_JTAGID_BYTE2 0xa9
+#define PARM_JTAGID_BYTE3 0xaa
+#define PARM_UNITS_BEFORE 0xab
+#define PARM_UNITS_AFTER 0xac
+#define PARM_BIT_BEFORE 0xad
+#define PARM_BIT_AFTER 0xae
+#define PARM_PSB0_LOW 0xaf
+#define PARM_PSBO_HIGH 0xb0
+#define PARM_PSB1_LOW 0xb1
+#define PARM_PSB1_HIGH 0xb2
+#define PARM_MCU_MODE 0xb3
+
+#define JTAG_BITRATE_1_MHz 0xff
+#define JTAG_BITRATE_500_kHz 0xfe
+#define JTAG_BITRATE_250_kHz 0xfd
+#define JTAG_BITRATE_125_kHz 0xfb
+
+/* memory types for CMND_{READ,WRITE}_MEMORY */
+#define MTYPE_IO_SHADOW 0x30 /* cached IO registers? */
+#define MTYPE_SRAM 0x20 /* target's SRAM or [ext.] IO registers */
+#define MTYPE_EEPROM 0x22 /* EEPROM, what way? */
+#define MTYPE_EVENT 0x60 /* ICE event memory */
+#define MTYPE_SPM 0xA0 /* flash through LPM/SPM */
+#define MTYPE_FLASH_PAGE 0xB0 /* flash in programming mode */
+#define MTYPE_EEPROM_PAGE 0xB1 /* EEPROM in programming mode */
+#define MTYPE_FUSE_BITS 0xB2 /* fuse bits in programming mode */
+#define MTYPE_LOCK_BITS 0xB3 /* lock bits in programming mode */
+#define MTYPE_SIGN_JTAG 0xB4 /* signature in programming mode */
+#define MTYPE_OSCCAL_BYTE 0xB5 /* osccal cells in programming mode */
+
+struct device_descriptor
+{
+ unsigned char ucReadIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
+ unsigned char ucWriteIO[8]; /*LSB = IOloc 0, MSB = IOloc63 */
+ unsigned char ucReadIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
+ unsigned char ucWriteIOShadow[8]; /*LSB = IOloc 0, MSB = IOloc63 */
+ unsigned char ucReadExtIO[20]; /*LSB = IOloc 96, MSB = IOloc255 */
+ unsigned char ucWriteExtIO[20]; /*LSB = IOloc 96, MSB = IOloc255 */
+ unsigned char ucReadIOExtShadow[20]; /*LSB = IOloc 96, MSB = IOloc255 */
+ unsigned char ucWriteIOExtShadow[20];/*LSB = IOloc 96, MSB = IOloc255 */
+ unsigned char ucIDRAddress; /*IDR address */
+ unsigned char ucSPMCRAddress; /*SPMCR Register address and dW BasePC */
+ unsigned char ucRAMPZAddress; /*RAMPZ Register address in SRAM I/O */
+ /*space */
+ unsigned char uiFlashPageSize[2]; /*Device Flash Page Size, Size = */
+ /*2 exp ucFlashPageSize */
+ unsigned char ucEepromPageSize; /*Device Eeprom Page Size in bytes */
+ unsigned char ulBootAddress[4]; /*Device Boot Loader Start Address */
+ unsigned char uiUpperExtIOLoc; /*Topmost (last) extended I/O */
+ /*location, 0 if no external I/O */
+};
diff --git a/xs/src/avrdude/lexer.c b/xs/src/avrdude/lexer.c
new file mode 100644
index 000000000..f2d8adb4b
--- /dev/null
+++ b/xs/src/avrdude/lexer.c
@@ -0,0 +1,3068 @@
+
+#line 2 "lexer.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 4
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
+#else
+#define yynoreturn
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
+ */
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin )
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+ #define YY_LINENO_REWIND_TO(ptr)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = NULL;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart ( FILE *input_file );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
+void yy_delete_buffer ( YY_BUFFER_STATE b );
+void yy_flush_buffer ( YY_BUFFER_STATE b );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state ( void );
+
+static void yyensure_buffer_stack ( void );
+static void yy_load_buffer_state ( void );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len );
+
+void *yyalloc ( yy_size_t );
+void *yyrealloc ( void *, yy_size_t );
+void yyfree ( void * );
+
+#define yy_new_buffer yy_create_buffer
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+typedef flex_uint8_t YY_CHAR;
+
+FILE *yyin = NULL, *yyout = NULL;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+int yylineno = 1;
+
+extern char *yytext;
+#ifdef yytext_ptr
+#undef yytext_ptr
+#endif
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state ( void );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state );
+static int yy_get_next_buffer ( void );
+static void yynoreturn yy_fatal_error ( const char* msg );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+#define YY_NUM_RULES 156
+#define YY_END_OF_BUFFER 157
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static const flex_int16_t yy_accept[877] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 157, 155,
+ 153, 152, 7, 9, 150, 151, 146, 155, 155, 4,
+ 4, 148, 147, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 155, 155, 155, 155, 155, 155, 155,
+ 155, 155, 155, 149, 20, 21, 13, 156, 156, 10,
+ 11, 153, 0, 3, 1, 6, 12, 5, 4, 0,
+ 0, 0, 0, 0, 0, 0, 0, 154, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 62, 64,
+ 0, 0, 0, 0, 0, 0, 0, 0, 78, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 20, 19, 17,
+ 18, 14, 16, 15, 3, 2, 5, 8, 0, 0,
+ 0, 0, 0, 28, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 63, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 120, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 132, 139, 0, 0, 145,
+
+ 2, 0, 0, 0, 0, 0, 29, 0, 0, 0,
+ 0, 0, 0, 0, 45, 0, 47, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 75, 76, 77, 0, 0, 0, 0, 0,
+ 0, 0, 89, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 109, 0, 0, 0, 0,
+ 123, 0, 0, 0, 0, 0, 0, 131, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 44, 0, 0,
+ 0, 0, 52, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 85, 86, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 107, 0, 0, 0, 0, 115, 0,
+ 0, 0, 124, 0, 0, 0, 0, 0, 0, 0,
+ 0, 136, 0, 0, 0, 141, 0, 0, 0, 25,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 48, 0, 51, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 73,
+ 0, 0, 0, 0, 82, 83, 0, 0, 88, 0,
+
+ 91, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 105, 0, 108, 0, 0, 0, 0, 0, 0, 121,
+ 0, 0, 0, 0, 0, 0, 0, 133, 134, 0,
+ 0, 138, 140, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 56, 57, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 110, 111, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 129, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 26, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 55, 0,
+ 0, 0, 0, 0, 66, 0, 0, 0, 0, 72,
+ 0, 0, 0, 81, 0, 87, 0, 0, 0, 0,
+ 0, 0, 0, 98, 0, 0, 0, 0, 0, 0,
+ 114, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 142, 143, 0, 0, 0, 24, 27, 30, 0,
+ 0, 0, 0, 38, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 79, 80, 84, 0, 92, 0, 94, 95,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 122, 125, 0, 0, 0, 130, 0, 137, 144, 0,
+ 0, 31, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 46, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 90, 93, 0,
+ 0, 0, 0, 0, 104, 0, 0, 116, 0, 0,
+ 0, 128, 135, 0, 0, 0, 0, 0, 0, 36,
+ 0, 0, 0, 0, 0, 0, 0, 0, 53, 0,
+ 0, 0, 0, 0, 0, 67, 0, 69, 70, 0,
+ 0, 0, 0, 0, 0, 0, 0, 112, 113, 0,
+
+ 0, 119, 0, 127, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 49, 0, 0, 0,
+ 0, 0, 0, 65, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 117, 118, 0, 0, 0, 0, 0,
+ 0, 35, 0, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 0, 0, 68, 0, 0, 96, 0, 99,
+ 0, 0, 0, 0, 0, 0, 0, 23, 0, 0,
+ 0, 0, 0, 0, 0, 0, 43, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 126, 0, 0, 0, 0, 37, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 61, 71, 74, 97, 0, 0,
+ 0, 0, 0, 0, 32, 0, 0, 39, 40, 0,
+ 42, 0, 58, 59, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
+ 106, 0, 0, 34, 0, 0, 0, 0, 0, 0,
+ 33, 0, 0, 0, 0, 0, 0, 50, 0, 101,
+ 0, 103, 22, 100, 102, 0
+ } ;
+
+static const YY_CHAR yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 4, 5, 1, 1, 1, 1, 6,
+ 7, 8, 9, 10, 9, 11, 12, 13, 14, 15,
+ 16, 17, 18, 17, 17, 17, 19, 20, 21, 1,
+ 22, 1, 1, 1, 23, 23, 23, 23, 23, 23,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 24, 1, 1, 25, 1, 26, 27, 28, 29,
+
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 1, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 1, 1, 1, 51, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static const YY_CHAR yy_meta[52] =
+ { 0,
+ 1, 1, 2, 2, 1, 1, 1, 1, 3, 1,
+ 4, 1, 5, 5, 5, 5, 5, 5, 5, 1,
+ 1, 1, 6, 2, 1, 6, 6, 6, 6, 6,
+ 6, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 7, 1, 1,
+ 1
+ } ;
+
+static const flex_int16_t yy_base[885] =
+ { 0,
+ 0, 0, 49, 51, 0, 0, 976, 975, 977, 980,
+ 974, 980, 980, 47, 980, 980, 980, 46, 967, 46,
+ 55, 980, 980, 30, 42, 50, 944, 39, 936, 46,
+ 53, 58, 71, 62, 43, 74, 83, 90, 46, 929,
+ 91, 929, 940, 980, 0, 980, 980, 96, 980, 980,
+ 980, 967, 117, 128, 121, 135, 980, 142, 0, 0,
+ 931, 925, 65, 926, 950, 933, 919, 980, 928, 932,
+ 921, 133, 137, 933, 916, 931, 913, 137, 913, 980,
+ 929, 909, 926, 903, 905, 911, 86, 134, 980, 910,
+ 909, 917, 914, 139, 906, 145, 918, 143, 912, 899,
+
+ 902, 890, 142, 902, 895, 134, 898, 161, 896, 896,
+ 901, 891, 904, 902, 880, 894, 884, 0, 980, 980,
+ 980, 980, 980, 980, 185, 192, 199, 0, 886, 906,
+ 888, 894, 894, 980, 890, 890, 878, 888, 878, 882,
+ 889, 888, 885, 878, 869, 868, 882, 871, 864, 881,
+ 866, 874, 862, 980, 876, 873, 871, 874, 873, 857,
+ 871, 855, 864, 859, 867, 866, 848, 846, 858, 193,
+ 52, 850, 842, 855, 856, 854, 850, 836, 840, 838,
+ 841, 848, 846, 833, 980, 840, 834, 842, 843, 843,
+ 851, 840, 837, 834, 835, 192, 980, 827, 819, 980,
+
+ 211, 815, 847, 164, 818, 823, 980, 829, 165, 809,
+ 826, 827, 809, 804, 980, 824, 980, 811, 813, 819,
+ 815, 205, 803, 820, 108, 147, 812, 195, 797, 816,
+ 800, 794, 980, 980, 980, 204, 813, 809, 808, 214,
+ 800, 797, 980, 805, 804, 210, 804, 790, 791, 800,
+ 212, 800, 797, 777, 796, 228, 781, 775, 797, 796,
+ 980, 779, 791, 806, 785, 777, 779, 980, 785, 218,
+ 775, 227, 783, 782, 780, 797, 766, 779, 781, 763,
+ 775, 774, 761, 772, 773, 774, 762, 980, 768, 759,
+ 766, 766, 769, 763, 748, 762, 749, 759, 742, 759,
+
+ 748, 766, 742, 755, 752, 755, 738, 753, 729, 735,
+ 750, 749, 748, 727, 728, 728, 980, 980, 733, 725,
+ 729, 738, 727, 735, 738, 733, 722, 722, 723, 719,
+ 732, 717, 725, 980, 726, 225, 728, 719, 723, 726,
+ 713, 705, 980, 718, 734, 204, 701, 715, 698, 714,
+ 702, 980, 702, 711, 710, 222, 693, 712, 702, 980,
+ 691, 700, 696, 690, 705, 701, 685, 684, 683, 698,
+ 700, 683, 980, 689, 695, 695, 686, 685, 676, 687,
+ 676, 686, 701, 697, 663, 663, 678, 675, 665, 980,
+ 673, 667, 673, 661, 980, 980, 669, 672, 980, 675,
+
+ 980, 671, 655, 661, 660, 665, 651, 668, 664, 654,
+ 980, 666, 980, 656, 649, 660, 637, 656, 644, 980,
+ 639, 646, 657, 632, 640, 635, 632, 980, 980, 648,
+ 647, 980, 980, 231, 649, 637, 644, 622, 641, 620,
+ 643, 642, 624, 636, 631, 634, 638, 622, 627, 634,
+ 620, 613, 625, 980, 980, 613, 612, 615, 623, 609,
+ 636, 622, 605, 618, 603, 616, 601, 608, 613, 612,
+ 591, 603, 612, 608, 604, 591, 609, 603, 591, 583,
+ 601, 228, 604, 980, 980, 593, 598, 590, 581, 583,
+ 598, 594, 594, 581, 980, 576, 574, 578, 583, 576,
+
+ 583, 577, 583, 582, 980, 581, 561, 566, 578, 570,
+ 566, 576, 240, 575, 564, 570, 558, 568, 980, 555,
+ 554, 553, 548, 581, 980, 557, 568, 567, 561, 980,
+ 560, 546, 545, 980, 557, 980, 549, 537, 544, 553,
+ 533, 552, 540, 980, 550, 533, 537, 546, 544, 549,
+ 980, 547, 535, 541, 521, 539, 531, 526, 534, 537,
+ 522, 980, 980, 533, 521, 515, 980, 980, 980, 530,
+ 128, 533, 519, 980, 523, 243, 244, 526, 512, 524,
+ 509, 505, 525, 524, 507, 518, 532, 516, 519, 239,
+ 519, 518, 980, 980, 980, 512, 980, 512, 980, 980,
+
+ 510, 502, 508, 494, 508, 493, 490, 492, 483, 488,
+ 980, 980, 484, 499, 485, 980, 483, 980, 980, 500,
+ 497, 499, 233, 489, 473, 496, 476, 477, 478, 486,
+ 474, 980, 471, 473, 471, 478, 484, 483, 469, 479,
+ 494, 463, 476, 470, 463, 473, 472, 980, 980, 463,
+ 456, 461, 467, 460, 980, 465, 265, 237, 464, 465,
+ 449, 980, 980, 459, 450, 460, 451, 450, 448, 980,
+ 441, 456, 457, 436, 435, 103, 133, 154, 980, 180,
+ 213, 248, 247, 256, 274, 980, 259, 980, 980, 259,
+ 260, 265, 248, 267, 253, 254, 254, 980, 980, 254,
+
+ 255, 980, 259, 980, 270, 272, 272, 266, 261, 275,
+ 257, 270, 271, 267, 272, 285, 980, 272, 283, 284,
+ 285, 273, 280, 980, 276, 282, 283, 272, 296, 274,
+ 284, 285, 301, 980, 980, 298, 301, 301, 295, 289,
+ 304, 980, 294, 296, 300, 312, 299, 303, 309, 980,
+ 305, 306, 300, 319, 980, 320, 321, 980, 320, 980,
+ 312, 313, 314, 315, 306, 324, 321, 980, 330, 323,
+ 311, 329, 332, 331, 324, 334, 980, 322, 339, 340,
+ 341, 319, 320, 321, 335, 335, 330, 337, 332, 334,
+ 980, 333, 329, 341, 346, 980, 345, 345, 345, 354,
+
+ 359, 337, 338, 360, 980, 980, 980, 980, 345, 360,
+ 347, 362, 359, 351, 980, 365, 367, 980, 980, 367,
+ 980, 360, 980, 980, 363, 366, 354, 368, 356, 360,
+ 361, 366, 363, 366, 371, 980, 372, 377, 374, 379,
+ 384, 373, 371, 384, 980, 384, 389, 391, 391, 393,
+ 980, 393, 380, 980, 386, 386, 383, 388, 385, 404,
+ 980, 399, 387, 400, 389, 402, 398, 980, 393, 980,
+ 394, 980, 980, 980, 980, 980, 438, 445, 452, 457,
+ 459, 466, 473, 476
+ } ;
+
+static const flex_int16_t yy_def[885] =
+ { 0,
+ 876, 1, 877, 877, 878, 878, 879, 879, 876, 876,
+ 876, 876, 876, 880, 876, 876, 876, 876, 876, 881,
+ 881, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 882, 876, 876, 883, 876, 876,
+ 876, 876, 880, 876, 880, 876, 876, 876, 21, 884,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 882, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 884, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 0, 876, 876, 876, 876,
+ 876, 876, 876, 876
+ } ;
+
+static const flex_int16_t yy_nxt[1032] =
+ { 0,
+ 10, 11, 12, 13, 14, 15, 16, 10, 10, 17,
+ 18, 19, 20, 21, 21, 21, 21, 21, 21, 10,
+ 22, 23, 10, 10, 10, 24, 25, 26, 27, 28,
+ 29, 10, 30, 31, 10, 10, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 10, 43, 10,
+ 44, 46, 47, 46, 47, 53, 58, 54, 56, 56,
+ 56, 56, 56, 56, 56, 58, 61, 63, 73, 68,
+ 92, 77, 48, 93, 48, 62, 244, 74, 64, 110,
+ 75, 79, 69, 82, 65, 111, 66, 70, 245, 71,
+ 67, 78, 80, 60, 112, 81, 84, 83, 85, 94,
+
+ 86, 89, 876, 131, 87, 95, 90, 91, 101, 132,
+ 88, 102, 103, 96, 97, 98, 99, 104, 114, 105,
+ 100, 115, 120, 106, 161, 53, 121, 54, 162, 876,
+ 107, 126, 300, 108, 122, 301, 716, 123, 109, 124,
+ 125, 125, 125, 125, 125, 125, 125, 56, 56, 56,
+ 56, 56, 56, 56, 127, 127, 127, 127, 127, 127,
+ 127, 140, 163, 141, 145, 187, 151, 182, 623, 142,
+ 169, 624, 176, 152, 717, 143, 164, 146, 144, 153,
+ 170, 172, 177, 188, 183, 184, 190, 173, 277, 282,
+ 302, 174, 303, 278, 283, 718, 191, 125, 125, 125,
+
+ 125, 125, 125, 125, 201, 201, 201, 201, 201, 201,
+ 201, 127, 127, 127, 127, 127, 127, 127, 241, 305,
+ 269, 719, 242, 201, 201, 201, 201, 201, 201, 201,
+ 311, 424, 270, 294, 271, 306, 243, 272, 316, 295,
+ 425, 720, 317, 323, 312, 296, 434, 324, 297, 330,
+ 318, 350, 336, 331, 337, 325, 353, 414, 546, 351,
+ 354, 415, 435, 499, 547, 548, 575, 500, 628, 630,
+ 338, 644, 667, 631, 700, 645, 721, 668, 698, 699,
+ 576, 701, 577, 722, 629, 723, 724, 725, 726, 727,
+ 728, 729, 730, 731, 732, 733, 734, 735, 736, 737,
+
+ 738, 739, 740, 741, 742, 743, 744, 745, 746, 747,
+ 748, 749, 750, 751, 752, 753, 754, 755, 756, 757,
+ 758, 759, 760, 761, 763, 765, 766, 767, 762, 764,
+ 768, 769, 770, 771, 772, 773, 774, 775, 776, 777,
+ 778, 779, 780, 781, 782, 783, 784, 785, 786, 787,
+ 788, 789, 790, 791, 792, 793, 794, 795, 796, 797,
+ 798, 799, 800, 801, 802, 803, 804, 805, 806, 807,
+ 808, 809, 810, 811, 812, 813, 814, 815, 816, 817,
+ 818, 819, 820, 821, 822, 823, 824, 825, 826, 827,
+ 828, 829, 830, 831, 832, 833, 834, 835, 836, 837,
+
+ 838, 839, 840, 841, 842, 843, 844, 845, 846, 847,
+ 848, 849, 850, 851, 852, 853, 854, 855, 856, 857,
+ 858, 859, 860, 861, 862, 863, 864, 865, 866, 867,
+ 868, 869, 870, 871, 872, 873, 874, 875, 45, 45,
+ 45, 45, 45, 45, 45, 49, 49, 49, 49, 49,
+ 49, 49, 50, 50, 50, 50, 50, 50, 50, 55,
+ 55, 55, 59, 59, 715, 59, 118, 714, 118, 118,
+ 118, 118, 118, 119, 119, 119, 119, 119, 119, 119,
+ 128, 128, 713, 712, 711, 710, 709, 708, 707, 706,
+ 705, 704, 703, 702, 697, 696, 695, 694, 693, 692,
+
+ 691, 690, 689, 688, 687, 686, 685, 684, 683, 682,
+ 681, 680, 679, 678, 677, 676, 675, 674, 673, 672,
+ 671, 670, 669, 666, 665, 664, 663, 662, 661, 660,
+ 659, 658, 657, 656, 655, 654, 653, 652, 651, 650,
+ 649, 648, 647, 646, 643, 642, 641, 640, 639, 638,
+ 637, 636, 635, 634, 633, 632, 627, 626, 625, 622,
+ 621, 620, 619, 618, 617, 616, 615, 614, 613, 612,
+ 611, 610, 609, 608, 607, 606, 605, 604, 603, 602,
+ 601, 600, 599, 598, 597, 596, 595, 594, 593, 592,
+ 591, 590, 589, 588, 587, 586, 585, 584, 583, 582,
+
+ 581, 580, 579, 578, 574, 573, 572, 571, 570, 569,
+ 568, 567, 566, 565, 564, 563, 562, 561, 560, 559,
+ 558, 557, 556, 555, 554, 553, 552, 551, 550, 549,
+ 545, 544, 543, 542, 541, 540, 539, 538, 537, 536,
+ 535, 534, 533, 532, 531, 530, 529, 528, 527, 526,
+ 525, 524, 523, 522, 521, 520, 519, 518, 517, 516,
+ 515, 514, 513, 512, 511, 510, 509, 508, 507, 506,
+ 505, 504, 503, 502, 501, 498, 497, 496, 495, 494,
+ 493, 492, 491, 490, 489, 488, 487, 486, 485, 484,
+ 483, 482, 481, 480, 479, 478, 477, 476, 475, 474,
+
+ 473, 472, 471, 470, 469, 468, 467, 466, 465, 464,
+ 463, 462, 461, 460, 459, 458, 457, 456, 455, 454,
+ 453, 452, 451, 450, 449, 448, 447, 446, 445, 444,
+ 443, 442, 441, 440, 439, 438, 437, 436, 433, 432,
+ 431, 430, 429, 428, 427, 426, 423, 422, 421, 420,
+ 419, 418, 417, 416, 413, 412, 411, 410, 409, 408,
+ 407, 406, 405, 404, 403, 402, 401, 400, 399, 398,
+ 397, 396, 395, 394, 393, 392, 391, 390, 389, 388,
+ 387, 386, 385, 384, 383, 382, 381, 380, 379, 378,
+ 377, 376, 375, 374, 373, 372, 371, 370, 369, 368,
+
+ 367, 366, 365, 364, 363, 362, 361, 360, 359, 358,
+ 357, 356, 355, 352, 349, 348, 347, 346, 345, 344,
+ 343, 342, 341, 340, 339, 335, 334, 333, 332, 329,
+ 328, 327, 326, 322, 321, 320, 319, 315, 314, 313,
+ 310, 309, 308, 307, 304, 299, 298, 293, 292, 291,
+ 290, 289, 288, 287, 286, 285, 284, 281, 280, 279,
+ 276, 275, 274, 273, 268, 267, 266, 265, 264, 263,
+ 262, 261, 260, 259, 258, 257, 256, 255, 254, 253,
+ 252, 251, 250, 249, 248, 247, 246, 240, 239, 238,
+ 237, 236, 235, 234, 233, 232, 231, 230, 229, 228,
+
+ 227, 226, 225, 224, 223, 222, 221, 220, 219, 218,
+ 217, 216, 215, 214, 213, 212, 211, 210, 209, 208,
+ 207, 206, 205, 204, 203, 202, 200, 199, 198, 197,
+ 196, 195, 194, 193, 192, 189, 186, 185, 181, 180,
+ 179, 178, 175, 171, 168, 167, 166, 165, 160, 159,
+ 158, 157, 156, 155, 154, 150, 149, 148, 147, 139,
+ 138, 137, 136, 135, 134, 133, 130, 129, 52, 117,
+ 116, 113, 76, 72, 57, 52, 876, 51, 51, 9,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876
+ } ;
+
+static const flex_int16_t yy_chk[1032] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3, 3, 4, 4, 14, 20, 14, 18, 18,
+ 18, 18, 18, 18, 18, 21, 24, 25, 28, 26,
+ 35, 30, 3, 35, 4, 24, 171, 28, 25, 39,
+ 28, 31, 26, 32, 25, 39, 25, 26, 171, 26,
+ 25, 30, 31, 20, 39, 31, 33, 32, 33, 36,
+
+ 33, 34, 21, 63, 33, 36, 34, 34, 37, 63,
+ 33, 37, 37, 36, 36, 36, 36, 38, 41, 38,
+ 36, 41, 48, 38, 87, 53, 48, 53, 87, 55,
+ 38, 55, 225, 38, 48, 225, 676, 48, 38, 48,
+ 54, 54, 54, 54, 54, 54, 54, 56, 56, 56,
+ 56, 56, 56, 56, 58, 58, 58, 58, 58, 58,
+ 58, 72, 88, 72, 73, 106, 78, 103, 571, 72,
+ 94, 571, 98, 78, 677, 72, 88, 73, 72, 78,
+ 94, 96, 98, 106, 103, 103, 108, 96, 204, 209,
+ 226, 96, 226, 204, 209, 678, 108, 125, 125, 125,
+
+ 125, 125, 125, 125, 126, 126, 126, 126, 126, 126,
+ 126, 127, 127, 127, 127, 127, 127, 127, 170, 228,
+ 196, 680, 170, 201, 201, 201, 201, 201, 201, 201,
+ 236, 346, 196, 222, 196, 228, 170, 196, 240, 222,
+ 346, 681, 240, 246, 236, 222, 356, 246, 222, 251,
+ 240, 270, 256, 251, 256, 246, 272, 336, 482, 270,
+ 272, 336, 356, 434, 482, 482, 513, 434, 576, 577,
+ 256, 590, 623, 577, 658, 590, 682, 623, 657, 657,
+ 513, 658, 513, 683, 576, 684, 685, 687, 690, 691,
+ 692, 693, 694, 695, 696, 697, 700, 701, 703, 705,
+
+ 706, 707, 708, 709, 710, 711, 712, 713, 714, 715,
+ 716, 718, 719, 720, 721, 722, 723, 725, 726, 727,
+ 728, 729, 730, 731, 732, 733, 736, 737, 731, 732,
+ 738, 739, 740, 741, 743, 744, 745, 746, 747, 748,
+ 749, 751, 752, 753, 754, 756, 757, 759, 761, 762,
+ 763, 764, 765, 766, 767, 769, 770, 771, 772, 773,
+ 774, 775, 776, 778, 779, 780, 781, 782, 783, 784,
+ 785, 786, 787, 788, 789, 790, 792, 793, 794, 795,
+ 797, 798, 799, 800, 801, 802, 803, 804, 809, 810,
+ 811, 812, 813, 814, 816, 817, 820, 822, 825, 826,
+
+ 827, 828, 829, 830, 831, 832, 833, 834, 835, 837,
+ 838, 839, 840, 841, 842, 843, 844, 846, 847, 848,
+ 849, 850, 852, 853, 855, 856, 857, 858, 859, 860,
+ 862, 863, 864, 865, 866, 867, 869, 871, 877, 877,
+ 877, 877, 877, 877, 877, 878, 878, 878, 878, 878,
+ 878, 878, 879, 879, 879, 879, 879, 879, 879, 880,
+ 880, 880, 881, 881, 675, 881, 882, 674, 882, 882,
+ 882, 882, 882, 883, 883, 883, 883, 883, 883, 883,
+ 884, 884, 673, 672, 671, 669, 668, 667, 666, 665,
+ 664, 661, 660, 659, 656, 654, 653, 652, 651, 650,
+
+ 647, 646, 645, 644, 643, 642, 641, 640, 639, 638,
+ 637, 636, 635, 634, 633, 631, 630, 629, 628, 627,
+ 626, 625, 624, 622, 621, 620, 617, 615, 614, 613,
+ 610, 609, 608, 607, 606, 605, 604, 603, 602, 601,
+ 598, 596, 592, 591, 589, 588, 587, 586, 585, 584,
+ 583, 582, 581, 580, 579, 578, 575, 573, 572, 570,
+ 566, 565, 564, 561, 560, 559, 558, 557, 556, 555,
+ 554, 553, 552, 550, 549, 548, 547, 546, 545, 543,
+ 542, 541, 540, 539, 538, 537, 535, 533, 532, 531,
+ 529, 528, 527, 526, 524, 523, 522, 521, 520, 518,
+
+ 517, 516, 515, 514, 512, 511, 510, 509, 508, 507,
+ 506, 504, 503, 502, 501, 500, 499, 498, 497, 496,
+ 494, 493, 492, 491, 490, 489, 488, 487, 486, 483,
+ 481, 480, 479, 478, 477, 476, 475, 474, 473, 472,
+ 471, 470, 469, 468, 467, 466, 465, 464, 463, 462,
+ 461, 460, 459, 458, 457, 456, 453, 452, 451, 450,
+ 449, 448, 447, 446, 445, 444, 443, 442, 441, 440,
+ 439, 438, 437, 436, 435, 431, 430, 427, 426, 425,
+ 424, 423, 422, 421, 419, 418, 417, 416, 415, 414,
+ 412, 410, 409, 408, 407, 406, 405, 404, 403, 402,
+
+ 400, 398, 397, 394, 393, 392, 391, 389, 388, 387,
+ 386, 385, 384, 383, 382, 381, 380, 379, 378, 377,
+ 376, 375, 374, 372, 371, 370, 369, 368, 367, 366,
+ 365, 364, 363, 362, 361, 359, 358, 357, 355, 354,
+ 353, 351, 350, 349, 348, 347, 345, 344, 342, 341,
+ 340, 339, 338, 337, 335, 333, 332, 331, 330, 329,
+ 328, 327, 326, 325, 324, 323, 322, 321, 320, 319,
+ 316, 315, 314, 313, 312, 311, 310, 309, 308, 307,
+ 306, 305, 304, 303, 302, 301, 300, 299, 298, 297,
+ 296, 295, 294, 293, 292, 291, 290, 289, 287, 286,
+
+ 285, 284, 283, 282, 281, 280, 279, 278, 277, 276,
+ 275, 274, 273, 271, 269, 267, 266, 265, 264, 263,
+ 262, 260, 259, 258, 257, 255, 254, 253, 252, 250,
+ 249, 248, 247, 245, 244, 242, 241, 239, 238, 237,
+ 232, 231, 230, 229, 227, 224, 223, 221, 220, 219,
+ 218, 216, 214, 213, 212, 211, 210, 208, 206, 205,
+ 203, 202, 199, 198, 195, 194, 193, 192, 191, 190,
+ 189, 188, 187, 186, 184, 183, 182, 181, 180, 179,
+ 178, 177, 176, 175, 174, 173, 172, 169, 168, 167,
+ 166, 165, 164, 163, 162, 161, 160, 159, 158, 157,
+
+ 156, 155, 153, 152, 151, 150, 149, 148, 147, 146,
+ 145, 144, 143, 142, 141, 140, 139, 138, 137, 136,
+ 135, 133, 132, 131, 130, 129, 117, 116, 115, 114,
+ 113, 112, 111, 110, 109, 107, 105, 104, 102, 101,
+ 100, 99, 97, 95, 93, 92, 91, 90, 86, 85,
+ 84, 83, 82, 81, 79, 77, 76, 75, 74, 71,
+ 70, 69, 67, 66, 65, 64, 62, 61, 52, 43,
+ 42, 40, 29, 27, 19, 11, 9, 8, 7, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876, 876, 876, 876, 876, 876, 876, 876, 876, 876,
+ 876
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "lexer.l"
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+#line 23 "lexer.l"
+/* need this for the call to atof() below */
+#include <math.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+#include "config.h"
+
+#include "config_gram.h"
+
+#ifndef YYERRCODE
+#define YYERRCODE 256
+#endif
+
+#line 996 "lexer.c"
+
+/* Bump resources for classic lex. */
+#line 999 "lexer.c"
+
+#define INITIAL 0
+#define strng 1
+#define incl 2
+#define comment 3
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals ( void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy ( void );
+
+int yyget_debug ( void );
+
+void yyset_debug ( int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra ( void );
+
+void yyset_extra ( YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in ( void );
+
+void yyset_in ( FILE * _in_str );
+
+FILE *yyget_out ( void );
+
+void yyset_out ( FILE * _out_str );
+
+ int yyget_leng ( void );
+
+char *yyget_text ( void );
+
+int yyget_lineno ( void );
+
+void yyset_lineno ( int _line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap ( void );
+#else
+extern int yywrap ( void );
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy ( char *, const char *, int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen ( const char * );
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput ( void );
+#else
+static int input ( void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ int n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK /*LINTED*/break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ {
+#line 57 "lexer.l"
+
+
+#line 1220 "lexer.c"
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 877 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 980 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 59 "lexer.l"
+{ yylval = number(yytext); return TKN_NUMBER; }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 60 "lexer.l"
+{ yylval = number_real(yytext); return TKN_NUMBER_REAL; }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 61 "lexer.l"
+{ yylval = number_real(yytext); return TKN_NUMBER_REAL; }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 62 "lexer.l"
+{ yylval = number(yytext); return TKN_NUMBER; }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 63 "lexer.l"
+{ yylval = number_real(yytext); return TKN_NUMBER_REAL; }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 64 "lexer.l"
+{ yylval = number_real(yytext); return TKN_NUMBER_REAL; }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 66 "lexer.l"
+{ string_buf_ptr = string_buf; BEGIN(strng); }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 68 "lexer.l"
+{ yylval = hexnumber(yytext); return TKN_NUMBER; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 72 "lexer.l"
+{ /* The following eats '#' style comments to end of line */
+ BEGIN(comment); }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 74 "lexer.l"
+{ /* eat comments */ }
+ YY_BREAK
+case 11:
+/* rule 11 can match eol */
+YY_RULE_SETUP
+#line 75 "lexer.l"
+{ lineno++; BEGIN(INITIAL); }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 78 "lexer.l"
+{ /* The following eats multiline C style comments */
+ int c;
+ int comment_start;
+
+ comment_start = lineno;
+ while (1) {
+ while (((c = input()) != '*') && (c != EOF)) {
+ /* eat up text of comment, but keep counting lines */
+ if (c == '\n')
+ lineno++;
+ }
+
+ if (c == '*') {
+ while ((c = input()) == '*')
+ ;
+ if (c == '/')
+ break; /* found the end */
+ }
+
+ if (c == EOF) {
+ yyerror("EOF in comment (started on line %d)", comment_start);
+ return YYERRCODE;
+ }
+ }
+ }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 105 "lexer.l"
+{ *string_buf_ptr = 0; string_buf_ptr = string_buf;
+ yylval = string(string_buf_ptr); BEGIN(INITIAL); return TKN_STRING; }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 107 "lexer.l"
+*string_buf_ptr++ = '\n';
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 108 "lexer.l"
+*string_buf_ptr++ = '\t';
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 109 "lexer.l"
+*string_buf_ptr++ = '\r';
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 110 "lexer.l"
+*string_buf_ptr++ = '\b';
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 111 "lexer.l"
+*string_buf_ptr++ = '\f';
+ YY_BREAK
+case 19:
+/* rule 19 can match eol */
+YY_RULE_SETUP
+#line 112 "lexer.l"
+*(string_buf_ptr++) = yytext[1];
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 113 "lexer.l"
+{ char *yptr = yytext; while (*yptr)
+ *(string_buf_ptr++) = *(yptr++); }
+ YY_BREAK
+case 21:
+/* rule 21 can match eol */
+YY_RULE_SETUP
+#line 116 "lexer.l"
+{ yyerror("unterminated character constant");
+ return YYERRCODE; }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 119 "lexer.l"
+{ yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 120 "lexer.l"
+{ yylval=NULL; return K_AVR910_DEVCODE; }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 121 "lexer.l"
+{ yylval=NULL; return K_PAGE_SIZE; }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 122 "lexer.l"
+{ yylval=NULL; return K_PAGED; }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 123 "lexer.l"
+{ yylval=NULL; return K_BAUDRATE; }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 124 "lexer.l"
+{ yylval=NULL; return K_BLOCKSIZE; }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 125 "lexer.l"
+{ yylval=NULL; return K_BS2; }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 126 "lexer.l"
+{ yylval=NULL; return K_BUFF; }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 127 "lexer.l"
+{ yylval=NULL; return K_BYTEDELAY; }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 128 "lexer.l"
+{ yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 129 "lexer.l"
+{ yylval=NULL; return K_CHIP_ERASE_DELAY; }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 130 "lexer.l"
+{ yylval=NULL; return K_CHIPERASEPOLLTIMEOUT; }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 131 "lexer.l"
+{ yylval=NULL; return K_CHIPERASEPULSEWIDTH; }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 132 "lexer.l"
+{ yylval=NULL; return K_CHIPERASETIME; }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 133 "lexer.l"
+{ yylval=NULL; return K_CMDEXEDELAY; }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 134 "lexer.l"
+{ yylval=NULL; return K_CONNTYPE; }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 135 "lexer.l"
+{ yylval=new_token(K_DEDICATED); return K_DEDICATED; }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 136 "lexer.l"
+{ yylval=NULL; return K_DEFAULT_BITCLOCK; }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 137 "lexer.l"
+{ yylval=NULL; return K_DEFAULT_PARALLEL; }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 138 "lexer.l"
+{ yylval=NULL; return K_DEFAULT_PROGRAMMER; }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 139 "lexer.l"
+{ yylval=NULL; return K_DEFAULT_SAFEMODE; }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 140 "lexer.l"
+{ yylval=NULL; return K_DEFAULT_SERIAL; }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 141 "lexer.l"
+{ yylval=NULL; return K_DELAY; }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 142 "lexer.l"
+{ yylval=NULL; return K_DESC; }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 143 "lexer.l"
+{ yylval=NULL; return K_DEVICECODE; }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 144 "lexer.l"
+{ yylval=NULL; return K_EECR; }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 145 "lexer.l"
+{ yylval=NULL; return K_EEPROM; }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 146 "lexer.l"
+{ yylval=NULL; return K_EEPROM_INSTR; }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 147 "lexer.l"
+{ yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 148 "lexer.l"
+{ yylval=NULL; return K_ERRLED; }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 149 "lexer.l"
+{ yylval=NULL; return K_FLASH; }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 150 "lexer.l"
+{ yylval=NULL; return K_FLASH_INSTR; }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 151 "lexer.l"
+{ yylval=NULL; return K_HAS_DW; }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 152 "lexer.l"
+{ yylval=NULL; return K_HAS_JTAG; }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 153 "lexer.l"
+{ yylval=NULL; return K_HAS_PDI; }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 154 "lexer.l"
+{ yylval=NULL; return K_HAS_TPI; }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 155 "lexer.l"
+{ yylval=NULL; return K_HVENTERSTABDELAY; }
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 156 "lexer.l"
+{ yylval=NULL; return K_HVLEAVESTABDELAY; }
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 157 "lexer.l"
+{ yylval=NULL; return K_HVSP_CONTROLSTACK; }
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 158 "lexer.l"
+{ yylval=NULL; return K_HVSPCMDEXEDELAY; }
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 159 "lexer.l"
+{ yylval=NULL; return K_ID; }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 160 "lexer.l"
+{ yylval=NULL; return K_IDR; }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 161 "lexer.l"
+{ yylval=new_token(K_IO); return K_IO; }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 162 "lexer.l"
+{ yylval=NULL; return K_IS_AT90S1200; }
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 163 "lexer.l"
+{ yylval=NULL; return K_IS_AVR32; }
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 164 "lexer.l"
+{ yylval=NULL; return K_LATCHCYCLES; }
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 165 "lexer.l"
+{ yylval=new_token(K_LOAD_EXT_ADDR); return K_LOAD_EXT_ADDR; }
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 166 "lexer.l"
+{ yylval=new_token(K_LOADPAGE_HI); return K_LOADPAGE_HI; }
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 167 "lexer.l"
+{ yylval=new_token(K_LOADPAGE_LO); return K_LOADPAGE_LO; }
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 168 "lexer.l"
+{ yylval=NULL; return K_MAX_WRITE_DELAY; }
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 169 "lexer.l"
+{ yylval=NULL; return K_MCU_BASE; }
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 170 "lexer.l"
+{ yylval=NULL; return K_MEMORY; }
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 171 "lexer.l"
+{ yylval=NULL; return K_MIN_WRITE_DELAY; }
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 172 "lexer.l"
+{ yylval=NULL; return K_MISO; }
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 173 "lexer.l"
+{ yylval=NULL; return K_MODE; }
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 174 "lexer.l"
+{ yylval=NULL; return K_MOSI; }
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 175 "lexer.l"
+{ yylval=new_token(K_NO); return K_NO; }
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 176 "lexer.l"
+{ yylval=NULL; return K_NUM_PAGES; }
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 177 "lexer.l"
+{ yylval=NULL; return K_NUM_PAGES; }
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 178 "lexer.l"
+{ yylval=NULL; return K_NVM_BASE; }
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 179 "lexer.l"
+{ yylval=NULL; return K_OCDREV; }
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 180 "lexer.l"
+{ yylval=NULL; return K_OFFSET; }
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 181 "lexer.l"
+{ yylval=NULL; return K_PAGE_SIZE; }
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 182 "lexer.l"
+{ yylval=NULL; return K_PAGED; }
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 183 "lexer.l"
+{ yylval=NULL; return K_PAGEL; }
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 184 "lexer.l"
+{ yylval=NULL; return K_PARALLEL; }
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 185 "lexer.l"
+{ yylval=NULL; return K_PARENT; }
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 186 "lexer.l"
+{ yylval=NULL; return K_PART; }
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 187 "lexer.l"
+{ yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; }
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 188 "lexer.l"
+{ yylval=NULL; return K_PGMLED; }
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 189 "lexer.l"
+{ yylval=NULL; return K_POLLINDEX; }
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 190 "lexer.l"
+{ yylval=NULL; return K_POLLMETHOD; }
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 191 "lexer.l"
+{ yylval=NULL; return K_POLLVALUE; }
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 192 "lexer.l"
+{ yylval=NULL; return K_POSTDELAY; }
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 193 "lexer.l"
+{ yylval=NULL; return K_POWEROFFDELAY; }
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 194 "lexer.l"
+{ yylval=NULL; return K_PP_CONTROLSTACK; }
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 195 "lexer.l"
+{ yylval=NULL; return K_PREDELAY; }
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 196 "lexer.l"
+{ yylval=NULL; return K_PROGMODEDELAY; }
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 197 "lexer.l"
+{ yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; }
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 198 "lexer.l"
+{ yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; }
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 199 "lexer.l"
+{ yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; }
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 200 "lexer.l"
+{ yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; }
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 201 "lexer.l"
+{ yylval=NULL; return K_PROGRAMMER; }
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 202 "lexer.l"
+{ yylval=new_token(K_PSEUDO); return K_PSEUDO; }
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 203 "lexer.l"
+{ yylval=NULL; return K_PWROFF_AFTER_WRITE; }
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 204 "lexer.l"
+{ yylval=NULL; return K_RAMPZ; }
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 205 "lexer.l"
+{ yylval=NULL; return K_RDYLED; }
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 206 "lexer.l"
+{ yylval=new_token(K_READ); return K_READ; }
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 207 "lexer.l"
+{ yylval=new_token(K_READ_HI); return K_READ_HI; }
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 208 "lexer.l"
+{ yylval=new_token(K_READ_LO); return K_READ_LO; }
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 209 "lexer.l"
+{ yylval=NULL; return K_READBACK_P1; }
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 210 "lexer.l"
+{ yylval=NULL; return K_READBACK_P2; }
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 211 "lexer.l"
+{ yylval=NULL; return K_READSIZE; }
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 212 "lexer.l"
+{ yylval=new_token(K_RESET); return K_RESET; }
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 213 "lexer.l"
+{ yylval=NULL; return K_RESETDELAY; }
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 214 "lexer.l"
+{ yylval=NULL; return K_RESETDELAYMS; }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 215 "lexer.l"
+{ yylval=NULL; return K_RESETDELAYUS; }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 216 "lexer.l"
+{ yylval=NULL; return K_RETRY_PULSE; }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 217 "lexer.l"
+{ yylval=new_token(K_SCK); return K_SCK; }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 218 "lexer.l"
+{ yylval=NULL; return K_SERIAL; }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 219 "lexer.l"
+{ yylval=NULL; return K_SIGNATURE; }
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 220 "lexer.l"
+{ yylval=NULL; return K_SIZE; }
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 221 "lexer.l"
+{ yylval=NULL; return K_SPMCR; }
+ YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 222 "lexer.l"
+{ yylval=NULL; return K_STABDELAY; }
+ YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 223 "lexer.l"
+{ yylval=NULL; return K_STK500_DEVCODE; }
+ YY_BREAK
+case 127:
+YY_RULE_SETUP
+#line 224 "lexer.l"
+{ yylval=NULL; return K_SYNCHCYCLES; }
+ YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 225 "lexer.l"
+{ yylval=NULL; return K_SYNCHLOOPS; }
+ YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 226 "lexer.l"
+{ yylval=NULL; return K_TIMEOUT; }
+ YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 227 "lexer.l"
+{ yylval=NULL; return K_TOGGLEVTG; }
+ YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 228 "lexer.l"
+{ yylval=NULL; return K_TYPE; }
+ YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 229 "lexer.l"
+{ yylval=NULL; return K_USB; }
+ YY_BREAK
+case 133:
+YY_RULE_SETUP
+#line 230 "lexer.l"
+{ yylval=NULL; return K_USBDEV; }
+ YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 231 "lexer.l"
+{ yylval=NULL; return K_USBPID; }
+ YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 232 "lexer.l"
+{ yylval=NULL; return K_USBPRODUCT; }
+ YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 233 "lexer.l"
+{ yylval=NULL; return K_USBSN; }
+ YY_BREAK
+case 137:
+YY_RULE_SETUP
+#line 234 "lexer.l"
+{ yylval=NULL; return K_USBVENDOR; }
+ YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 235 "lexer.l"
+{ yylval=NULL; return K_USBVID; }
+ YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 236 "lexer.l"
+{ yylval=NULL; return K_VCC; }
+ YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 237 "lexer.l"
+{ yylval=NULL; return K_VFYLED; }
+ YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 238 "lexer.l"
+{ yylval=new_token(K_WRITE); return K_WRITE; }
+ YY_BREAK
+case 142:
+YY_RULE_SETUP
+#line 239 "lexer.l"
+{ yylval=new_token(K_WRITE_HI); return K_WRITE_HI; }
+ YY_BREAK
+case 143:
+YY_RULE_SETUP
+#line 240 "lexer.l"
+{ yylval=new_token(K_WRITE_LO); return K_WRITE_LO; }
+ YY_BREAK
+case 144:
+YY_RULE_SETUP
+#line 241 "lexer.l"
+{ yylval=new_token(K_WRITEPAGE); return K_WRITEPAGE; }
+ YY_BREAK
+case 145:
+YY_RULE_SETUP
+#line 242 "lexer.l"
+{ yylval=new_token(K_YES); return K_YES; }
+ YY_BREAK
+case 146:
+YY_RULE_SETUP
+#line 244 "lexer.l"
+{ yylval = NULL; pyytext(); return TKN_COMMA; }
+ YY_BREAK
+case 147:
+YY_RULE_SETUP
+#line 245 "lexer.l"
+{ yylval = NULL; pyytext(); return TKN_EQUAL; }
+ YY_BREAK
+case 148:
+YY_RULE_SETUP
+#line 246 "lexer.l"
+{ yylval = NULL; pyytext(); return TKN_SEMI; }
+ YY_BREAK
+case 149:
+YY_RULE_SETUP
+#line 247 "lexer.l"
+{ yylval = NULL; pyytext(); return TKN_TILDE; }
+ YY_BREAK
+case 150:
+YY_RULE_SETUP
+#line 248 "lexer.l"
+{ yylval = NULL; pyytext(); return TKN_LEFT_PAREN; }
+ YY_BREAK
+case 151:
+YY_RULE_SETUP
+#line 249 "lexer.l"
+{ yylval = NULL; pyytext(); return TKN_RIGHT_PAREN; }
+ YY_BREAK
+case 152:
+/* rule 152 can match eol */
+YY_RULE_SETUP
+#line 251 "lexer.l"
+{ lineno++; }
+ YY_BREAK
+case 153:
+YY_RULE_SETUP
+#line 252 "lexer.l"
+{ /* ignore whitespace */ }
+ YY_BREAK
+case 154:
+YY_RULE_SETUP
+#line 254 "lexer.l"
+{ yyerror("possible old-style config file entry\n"
+ " Update your config file (see " CONFIG_DIR
+ "/avrdude.conf.sample for a sample)");
+ return YYERRCODE; }
+ YY_BREAK
+case 155:
+YY_RULE_SETUP
+#line 259 "lexer.l"
+{ return YYERRCODE; }
+ YY_BREAK
+case 156:
+YY_RULE_SETUP
+#line 261 "lexer.l"
+ECHO;
+ YY_BREAK
+#line 2092 "lexer.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(strng):
+case YY_STATE_EOF(incl):
+case YY_STATE_EOF(comment):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = (yytext_ptr);
+ int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc( (void *) b->yy_ch_buf,
+ (yy_size_t) (b->yy_buf_size + 2) );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = NULL;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 877 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ int yy_is_jam;
+ char *yy_cp = (yy_c_buf_p);
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 877 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 876);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (int) ((yy_c_buf_p) - (yytext_ptr));
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return 0;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE );
+ }
+
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree( (void *) b->yy_ch_buf );
+
+ yyfree( (void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer( b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ yy_size_t num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ yy_size_t grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return NULL;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = NULL;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (const char * yystr )
+{
+
+ return yy_scan_bytes( yystr, (int) strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n );
+ if ( ! buf )
+ // YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+ avrdude_oom("out of dynamic memory in yy_scan_bytes()");
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yynoreturn yy_fatal_error (const char* msg )
+{
+ fprintf( stderr, "%s\n", msg );
+ // exit( YY_EXIT_FAILURE );
+ abort();
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param _line_number line number
+ *
+ */
+void yyset_lineno (int _line_number )
+{
+
+ yylineno = _line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * _in_str )
+{
+ yyin = _in_str ;
+}
+
+void yyset_out (FILE * _out_str )
+{
+ yyout = _out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int _bdebug )
+{
+ yy_flex_debug = _bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = NULL;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = NULL;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = NULL;
+ yyout = NULL;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer( YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, const char * s2, int n )
+{
+
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (const char * s )
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return malloc(size);
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return realloc(ptr, size);
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 261 "lexer.l"
+
+
+
diff --git a/xs/src/avrdude/lexer.l b/xs/src/avrdude/lexer.l
new file mode 100644
index 000000000..34af33d64
--- /dev/null
+++ b/xs/src/avrdude/lexer.l
@@ -0,0 +1,262 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+
+%{
+/* need this for the call to atof() below */
+#include <math.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+#include "config.h"
+
+#include "config_gram.h"
+
+#ifndef YYERRCODE
+#define YYERRCODE 256
+#endif
+
+%}
+
+DIGIT [0-9]
+HEXDIGIT [0-9a-fA-F]
+SIGN [+-]
+
+%x strng
+%x incl
+%x comment
+%option nounput
+
+/* Bump resources for classic lex. */
+%e2000
+%p10000
+%n1000
+
+%%
+
+#{SIGN}*{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
+#{SIGN}*{DIGIT}+"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
+#{SIGN}*"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
+{DIGIT}+ { yylval = number(yytext); return TKN_NUMBER; }
+{DIGIT}+"."{DIGIT}* { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
+"."{DIGIT}+ { yylval = number_real(yytext); return TKN_NUMBER_REAL; }
+
+"\"" { string_buf_ptr = string_buf; BEGIN(strng); }
+
+0x{HEXDIGIT}+ { yylval = hexnumber(yytext); return TKN_NUMBER; }
+
+
+
+# { /* The following eats '#' style comments to end of line */
+ BEGIN(comment); }
+<comment>[^\n] { /* eat comments */ }
+<comment>\n { lineno++; BEGIN(INITIAL); }
+
+
+"/*" { /* The following eats multiline C style comments */
+ int c;
+ int comment_start;
+
+ comment_start = lineno;
+ while (1) {
+ while (((c = input()) != '*') && (c != EOF)) {
+ /* eat up text of comment, but keep counting lines */
+ if (c == '\n')
+ lineno++;
+ }
+
+ if (c == '*') {
+ while ((c = input()) == '*')
+ ;
+ if (c == '/')
+ break; /* found the end */
+ }
+
+ if (c == EOF) {
+ yyerror("EOF in comment (started on line %d)", comment_start);
+ return YYERRCODE;
+ }
+ }
+ }
+
+
+<strng>\" { *string_buf_ptr = 0; string_buf_ptr = string_buf;
+ yylval = string(string_buf_ptr); BEGIN(INITIAL); return TKN_STRING; }
+<strng>\\n *string_buf_ptr++ = '\n';
+<strng>\\t *string_buf_ptr++ = '\t';
+<strng>\\r *string_buf_ptr++ = '\r';
+<strng>\\b *string_buf_ptr++ = '\b';
+<strng>\\f *string_buf_ptr++ = '\f';
+<strng>\\(.|\n) *(string_buf_ptr++) = yytext[1];
+<strng>[^\\\n\"]+ { char *yptr = yytext; while (*yptr)
+ *(string_buf_ptr++) = *(yptr++); }
+
+<strng>\n { yyerror("unterminated character constant");
+ return YYERRCODE; }
+
+allowfullpagebitstream { yylval=NULL; return K_ALLOWFULLPAGEBITSTREAM; }
+avr910_devcode { yylval=NULL; return K_AVR910_DEVCODE; }
+bank_size { yylval=NULL; return K_PAGE_SIZE; }
+banked { yylval=NULL; return K_PAGED; }
+baudrate { yylval=NULL; return K_BAUDRATE; }
+blocksize { yylval=NULL; return K_BLOCKSIZE; }
+bs2 { yylval=NULL; return K_BS2; }
+buff { yylval=NULL; return K_BUFF; }
+bytedelay { yylval=NULL; return K_BYTEDELAY; }
+chip_erase { yylval=new_token(K_CHIP_ERASE); return K_CHIP_ERASE; }
+chip_erase_delay { yylval=NULL; return K_CHIP_ERASE_DELAY; }
+chiperasepolltimeout { yylval=NULL; return K_CHIPERASEPOLLTIMEOUT; }
+chiperasepulsewidth { yylval=NULL; return K_CHIPERASEPULSEWIDTH; }
+chiperasetime { yylval=NULL; return K_CHIPERASETIME; }
+cmdexedelay { yylval=NULL; return K_CMDEXEDELAY; }
+connection_type { yylval=NULL; return K_CONNTYPE; }
+dedicated { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
+default_bitclock { yylval=NULL; return K_DEFAULT_BITCLOCK; }
+default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
+default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
+default_safemode { yylval=NULL; return K_DEFAULT_SAFEMODE; }
+default_serial { yylval=NULL; return K_DEFAULT_SERIAL; }
+delay { yylval=NULL; return K_DELAY; }
+desc { yylval=NULL; return K_DESC; }
+devicecode { yylval=NULL; return K_DEVICECODE; }
+eecr { yylval=NULL; return K_EECR; }
+eeprom { yylval=NULL; return K_EEPROM; }
+eeprom_instr { yylval=NULL; return K_EEPROM_INSTR; }
+enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }
+errled { yylval=NULL; return K_ERRLED; }
+flash { yylval=NULL; return K_FLASH; }
+flash_instr { yylval=NULL; return K_FLASH_INSTR; }
+has_debugwire { yylval=NULL; return K_HAS_DW; }
+has_jtag { yylval=NULL; return K_HAS_JTAG; }
+has_pdi { yylval=NULL; return K_HAS_PDI; }
+has_tpi { yylval=NULL; return K_HAS_TPI; }
+hventerstabdelay { yylval=NULL; return K_HVENTERSTABDELAY; }
+hvleavestabdelay { yylval=NULL; return K_HVLEAVESTABDELAY; }
+hvsp_controlstack { yylval=NULL; return K_HVSP_CONTROLSTACK; }
+hvspcmdexedelay { yylval=NULL; return K_HVSPCMDEXEDELAY; }
+id { yylval=NULL; return K_ID; }
+idr { yylval=NULL; return K_IDR; }
+io { yylval=new_token(K_IO); return K_IO; }
+is_at90s1200 { yylval=NULL; return K_IS_AT90S1200; }
+is_avr32 { yylval=NULL; return K_IS_AVR32; }
+latchcycles { yylval=NULL; return K_LATCHCYCLES; }
+load_ext_addr { yylval=new_token(K_LOAD_EXT_ADDR); return K_LOAD_EXT_ADDR; }
+loadpage_hi { yylval=new_token(K_LOADPAGE_HI); return K_LOADPAGE_HI; }
+loadpage_lo { yylval=new_token(K_LOADPAGE_LO); return K_LOADPAGE_LO; }
+max_write_delay { yylval=NULL; return K_MAX_WRITE_DELAY; }
+mcu_base { yylval=NULL; return K_MCU_BASE; }
+memory { yylval=NULL; return K_MEMORY; }
+min_write_delay { yylval=NULL; return K_MIN_WRITE_DELAY; }
+miso { yylval=NULL; return K_MISO; }
+mode { yylval=NULL; return K_MODE; }
+mosi { yylval=NULL; return K_MOSI; }
+no { yylval=new_token(K_NO); return K_NO; }
+num_banks { yylval=NULL; return K_NUM_PAGES; }
+num_pages { yylval=NULL; return K_NUM_PAGES; }
+nvm_base { yylval=NULL; return K_NVM_BASE; }
+ocdrev { yylval=NULL; return K_OCDREV; }
+offset { yylval=NULL; return K_OFFSET; }
+page_size { yylval=NULL; return K_PAGE_SIZE; }
+paged { yylval=NULL; return K_PAGED; }
+pagel { yylval=NULL; return K_PAGEL; }
+parallel { yylval=NULL; return K_PARALLEL; }
+parent { yylval=NULL; return K_PARENT; }
+part { yylval=NULL; return K_PART; }
+pgm_enable { yylval=new_token(K_PGM_ENABLE); return K_PGM_ENABLE; }
+pgmled { yylval=NULL; return K_PGMLED; }
+pollindex { yylval=NULL; return K_POLLINDEX; }
+pollmethod { yylval=NULL; return K_POLLMETHOD; }
+pollvalue { yylval=NULL; return K_POLLVALUE; }
+postdelay { yylval=NULL; return K_POSTDELAY; }
+poweroffdelay { yylval=NULL; return K_POWEROFFDELAY; }
+pp_controlstack { yylval=NULL; return K_PP_CONTROLSTACK; }
+predelay { yylval=NULL; return K_PREDELAY; }
+progmodedelay { yylval=NULL; return K_PROGMODEDELAY; }
+programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; }
+programfusepulsewidth { yylval=NULL; return K_PROGRAMFUSEPULSEWIDTH; }
+programlockpolltimeout { yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; }
+programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; }
+programmer { yylval=NULL; return K_PROGRAMMER; }
+pseudo { yylval=new_token(K_PSEUDO); return K_PSEUDO; }
+pwroff_after_write { yylval=NULL; return K_PWROFF_AFTER_WRITE; }
+rampz { yylval=NULL; return K_RAMPZ; }
+rdyled { yylval=NULL; return K_RDYLED; }
+read { yylval=new_token(K_READ); return K_READ; }
+read_hi { yylval=new_token(K_READ_HI); return K_READ_HI; }
+read_lo { yylval=new_token(K_READ_LO); return K_READ_LO; }
+readback_p1 { yylval=NULL; return K_READBACK_P1; }
+readback_p2 { yylval=NULL; return K_READBACK_P2; }
+readsize { yylval=NULL; return K_READSIZE; }
+reset { yylval=new_token(K_RESET); return K_RESET; }
+resetdelay { yylval=NULL; return K_RESETDELAY; }
+resetdelayms { yylval=NULL; return K_RESETDELAYMS; }
+resetdelayus { yylval=NULL; return K_RESETDELAYUS; }
+retry_pulse { yylval=NULL; return K_RETRY_PULSE; }
+sck { yylval=new_token(K_SCK); return K_SCK; }
+serial { yylval=NULL; return K_SERIAL; }
+signature { yylval=NULL; return K_SIGNATURE; }
+size { yylval=NULL; return K_SIZE; }
+spmcr { yylval=NULL; return K_SPMCR; }
+stabdelay { yylval=NULL; return K_STABDELAY; }
+stk500_devcode { yylval=NULL; return K_STK500_DEVCODE; }
+synchcycles { yylval=NULL; return K_SYNCHCYCLES; }
+synchloops { yylval=NULL; return K_SYNCHLOOPS; }
+timeout { yylval=NULL; return K_TIMEOUT; }
+togglevtg { yylval=NULL; return K_TOGGLEVTG; }
+type { yylval=NULL; return K_TYPE; }
+usb { yylval=NULL; return K_USB; }
+usbdev { yylval=NULL; return K_USBDEV; }
+usbpid { yylval=NULL; return K_USBPID; }
+usbproduct { yylval=NULL; return K_USBPRODUCT; }
+usbsn { yylval=NULL; return K_USBSN; }
+usbvendor { yylval=NULL; return K_USBVENDOR; }
+usbvid { yylval=NULL; return K_USBVID; }
+vcc { yylval=NULL; return K_VCC; }
+vfyled { yylval=NULL; return K_VFYLED; }
+write { yylval=new_token(K_WRITE); return K_WRITE; }
+write_hi { yylval=new_token(K_WRITE_HI); return K_WRITE_HI; }
+write_lo { yylval=new_token(K_WRITE_LO); return K_WRITE_LO; }
+writepage { yylval=new_token(K_WRITEPAGE); return K_WRITEPAGE; }
+yes { yylval=new_token(K_YES); return K_YES; }
+
+"," { yylval = NULL; pyytext(); return TKN_COMMA; }
+"=" { yylval = NULL; pyytext(); return TKN_EQUAL; }
+";" { yylval = NULL; pyytext(); return TKN_SEMI; }
+"~" { yylval = NULL; pyytext(); return TKN_TILDE; }
+"(" { yylval = NULL; pyytext(); return TKN_LEFT_PAREN; }
+")" { yylval = NULL; pyytext(); return TKN_RIGHT_PAREN; }
+
+"\n" { lineno++; }
+[ \r\t]+ { /* ignore whitespace */ }
+
+c: { yyerror("possible old-style config file entry\n"
+ " Update your config file (see " CONFIG_DIR
+ "/avrdude.conf.sample for a sample)");
+ return YYERRCODE; }
+
+. { return YYERRCODE; }
+
+%%
+
diff --git a/xs/src/avrdude/libavrdude.h b/xs/src/avrdude/libavrdude.h
new file mode 100644
index 000000000..aef792476
--- /dev/null
+++ b/xs/src/avrdude/libavrdude.h
@@ -0,0 +1,973 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) Joerg Wunsch
+ *
+ * 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 libavrdude_h
+#define libavrdude_h
+
+/* XXX should go away */
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <limits.h>
+#include <stdbool.h>
+
+/* lets try to select at least 32 bits */
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+typedef uint32_t pinmask_t;
+#else
+#if UINT_MAX >= 0xFFFFFFFF
+typedef unsigned int pinmask_t;
+#else
+typedef unsigned long pinmask_t;
+#endif
+#endif
+
+
+// PATH_MAX is used throughout avrdude for various purposes.
+// It is problematic though as it may or may not be defined on various systems
+// and even when it is, it tends to be somewhat arbitrary.
+// So instead we just define a value here that should be fine in most cases.
+#ifdef PATH_MAX
+#undef PATH_MAX
+#endif
+#define PATH_MAX 4096
+
+
+/* formerly lists.h */
+
+/*----------------------------------------------------------------------
+ General purpose linked list routines - header file declarations.
+
+ Author : Brian Dean
+ Date : 10 January, 1990
+ ----------------------------------------------------------------------*/
+
+typedef void * LISTID;
+typedef void * LNODEID;
+
+
+/*----------------------------------------------------------------------
+ several defines to access the LIST structure as as stack or a queue
+ --- use for program readability
+ ----------------------------------------------------------------------*/
+#define STACKID LISTID
+#define SNODEID LNODEID
+#define QUEUEID LISTID
+#define QNODEID LNODEID
+
+
+#define PUSH(s,d) lins_n(s,d,1) /* push 'd' onto the stack */
+#define POP(s) lrmv_n(s,1) /* pop the stack */
+#define LOOKSTACK(s) lget_n(s,1) /* look at the top of the stack,
+ but don't pop */
+
+
+#define ENQUEUE(q,d) lins_n(q,d,1) /* put 'd' on the end of the queue */
+#define DEQUEUE(q) lrmv(q) /* remove next item from the front of
+ the queue */
+#define REQUEUE(q,d) ladd(q,d) /* re-insert (push) item back on the
+ front of the queue */
+#define LOOKQUEUE(q) lget(q) /* return next item on the queue,
+ but don't dequeue */
+#define QUEUELEN(q) lsize(q) /* length of the queue */
+
+
+#define LISTADD(l,d) ladd(l,d) /* add to end of the list */
+#define LISTRMV(l,d) lrmv_d(l,d) /* remove from end of the list */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* .................... Function Prototypes .................... */
+
+LISTID lcreat ( void * liststruct, int poolsize );
+void ldestroy ( LISTID lid );
+void ldestroy_cb ( LISTID lid, void (*ucleanup)(void * data_ptr) );
+
+LNODEID lfirst ( LISTID ); /* head of the list */
+LNODEID llast ( LISTID ); /* tail of the list */
+LNODEID lnext ( LNODEID ); /* next item in the list */
+LNODEID lprev ( LNODEID ); /* previous item in the list */
+void * ldata ( LNODEID ); /* data at the current position */
+int lsize ( LISTID ); /* number of elements in the list */
+
+int ladd ( LISTID lid, void * p );
+int laddo ( LISTID lid, void *p,
+ int (*compare)(const void *p1,const void *p2),
+ LNODEID * firstdup );
+int laddu ( LISTID lid, void * p,
+ int (*compare)(const void *p1,const void *p2));
+int lins_n ( LISTID lid, void * d, unsigned int n );
+int lins_ln ( LISTID lid, LNODEID lnid, void * data_ptr );
+
+void * lget ( LISTID lid );
+void * lget_n ( LISTID lid, unsigned int n );
+LNODEID lget_ln ( LISTID lid, unsigned int n );
+
+void * lrmv ( LISTID lid );
+void * lrmv_n ( LISTID lid, unsigned int n );
+void * lrmv_ln ( LISTID lid, LNODEID lnid );
+void * lrmv_d ( LISTID lid, void * data_ptr );
+
+LISTID lcat ( LISTID lid1, LISTID lid2 );
+
+void lsort ( LISTID lid, int (*compare)(void * p1, void * p2));
+
+void * lsrch ( LISTID lid, void * p, int (*compare)(void *p1,void *p2));
+
+int lprint ( FILE * f, LISTID lid );
+
+#ifdef __cplusplus
+}
+#endif
+
+/* formerly avrpart.h */
+
+/*
+ * AVR serial programming instructions
+ */
+enum {
+ AVR_OP_READ,
+ AVR_OP_WRITE,
+ AVR_OP_READ_LO,
+ AVR_OP_READ_HI,
+ AVR_OP_WRITE_LO,
+ AVR_OP_WRITE_HI,
+ AVR_OP_LOADPAGE_LO,
+ AVR_OP_LOADPAGE_HI,
+ AVR_OP_LOAD_EXT_ADDR,
+ AVR_OP_WRITEPAGE,
+ AVR_OP_CHIP_ERASE,
+ AVR_OP_PGM_ENABLE,
+ AVR_OP_MAX
+};
+
+
+enum {
+ AVR_CMDBIT_IGNORE, /* bit is ignored on input and output */
+ AVR_CMDBIT_VALUE, /* bit is set to 0 or 1 for input or output */
+ AVR_CMDBIT_ADDRESS, /* this bit represents an input address bit */
+ AVR_CMDBIT_INPUT, /* this bit is an input bit */
+ AVR_CMDBIT_OUTPUT /* this bit is an output bit */
+};
+
+enum { /* these are assigned to reset_disposition of AVRPART */
+ RESET_DEDICATED, /* reset pin is dedicated */
+ RESET_IO /* reset pin might be configured as an I/O pin */
+};
+
+enum ctl_stack_t {
+ CTL_STACK_NONE, /* no control stack defined */
+ CTL_STACK_PP, /* parallel programming control stack */
+ CTL_STACK_HVSP /* high voltage serial programming control stack */
+};
+
+/*
+ * serial programming instruction bit specifications
+ */
+typedef struct cmdbit {
+ int type; /* AVR_CMDBIT_* */
+ int bitno; /* which input bit to use for this command bit */
+ int value; /* bit value if type == AVR_CMDBIT_VALUD */
+} CMDBIT;
+
+typedef struct opcode {
+ CMDBIT bit[32]; /* opcode bit specs */
+} OPCODE;
+
+
+#define AVRPART_SERIALOK 0x0001 /* part supports serial programming */
+#define AVRPART_PARALLELOK 0x0002 /* part supports parallel programming */
+#define AVRPART_PSEUDOPARALLEL 0x0004 /* part has pseudo parallel support */
+#define AVRPART_HAS_JTAG 0x0008 /* part has a JTAG i/f */
+#define AVRPART_ALLOWFULLPAGEBITSTREAM 0x0010 /* JTAG ICE mkII param. */
+#define AVRPART_ENABLEPAGEPROGRAMMING 0x0020 /* JTAG ICE mkII param. */
+#define AVRPART_HAS_DW 0x0040 /* part has a debugWire i/f */
+#define AVRPART_HAS_PDI 0x0080 /* part has PDI i/f rather than ISP (ATxmega) */
+#define AVRPART_AVR32 0x0100 /* part is in AVR32 family */
+#define AVRPART_INIT_SMC 0x0200 /* part will undergo chip erase */
+#define AVRPART_WRITE 0x0400 /* at least one write operation specified */
+#define AVRPART_HAS_TPI 0x0800 /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */
+#define AVRPART_IS_AT90S1200 0x1000 /* part is an AT90S1200 (needs special treatment) */
+
+#define AVR_DESCLEN 64
+#define AVR_IDLEN 32
+#define CTL_STACK_SIZE 32
+#define FLASH_INSTR_SIZE 3
+#define EEPROM_INSTR_SIZE 20
+
+#define TAG_ALLOCATED 1 /* memory byte is allocated */
+
+typedef struct avrpart {
+ char desc[AVR_DESCLEN]; /* long part name */
+ char id[AVR_IDLEN]; /* short part name */
+ int stk500_devcode; /* stk500 device code */
+ int avr910_devcode; /* avr910 device code */
+ int chip_erase_delay; /* microseconds */
+ unsigned char pagel; /* for parallel programming */
+ unsigned char bs2; /* for parallel programming */
+ unsigned char signature[3]; /* expected value of signature bytes */
+ unsigned short usbpid; /* USB DFU product ID (0 = none) */
+ int reset_disposition; /* see RESET_ enums */
+ int retry_pulse; /* retry program enable by pulsing
+ this pin (PIN_AVR_*) */
+ unsigned flags; /* see AVRPART_ masks */
+
+ int timeout; /* stk500 v2 xml file parameter */
+ int stabdelay; /* stk500 v2 xml file parameter */
+ int cmdexedelay; /* stk500 v2 xml file parameter */
+ int synchloops; /* stk500 v2 xml file parameter */
+ int bytedelay; /* stk500 v2 xml file parameter */
+ int pollindex; /* stk500 v2 xml file parameter */
+ unsigned char pollvalue; /* stk500 v2 xml file parameter */
+ int predelay; /* stk500 v2 xml file parameter */
+ int postdelay; /* stk500 v2 xml file parameter */
+ int pollmethod; /* stk500 v2 xml file parameter */
+
+ enum ctl_stack_t ctl_stack_type; /* what to use the ctl stack for */
+ unsigned char controlstack[CTL_STACK_SIZE]; /* stk500v2 PP/HVSP ctl stack */
+ unsigned char flash_instr[FLASH_INSTR_SIZE]; /* flash instructions (debugWire, JTAG) */
+ unsigned char eeprom_instr[EEPROM_INSTR_SIZE]; /* EEPROM instructions (debugWire, JTAG) */
+
+ int hventerstabdelay; /* stk500 v2 hv mode parameter */
+ int progmodedelay; /* stk500 v2 hv mode parameter */
+ int latchcycles; /* stk500 v2 hv mode parameter */
+ int togglevtg; /* stk500 v2 hv mode parameter */
+ int poweroffdelay; /* stk500 v2 hv mode parameter */
+ int resetdelayms; /* stk500 v2 hv mode parameter */
+ int resetdelayus; /* stk500 v2 hv mode parameter */
+ int hvleavestabdelay; /* stk500 v2 hv mode parameter */
+ int resetdelay; /* stk500 v2 hv mode parameter */
+ int chiperasepulsewidth; /* stk500 v2 hv mode parameter */
+ int chiperasepolltimeout; /* stk500 v2 hv mode parameter */
+ int chiperasetime; /* stk500 v2 hv mode parameter */
+ int programfusepulsewidth; /* stk500 v2 hv mode parameter */
+ int programfusepolltimeout; /* stk500 v2 hv mode parameter */
+ int programlockpulsewidth; /* stk500 v2 hv mode parameter */
+ int programlockpolltimeout; /* stk500 v2 hv mode parameter */
+ int synchcycles; /* stk500 v2 hv mode parameter */
+ int hvspcmdexedelay; /* stk500 v2 xml file parameter */
+
+ unsigned char idr; /* JTAG ICE mkII XML file parameter */
+ unsigned char rampz; /* JTAG ICE mkII XML file parameter */
+ unsigned char spmcr; /* JTAG ICE mkII XML file parameter */
+ unsigned short eecr; /* JTAC ICE mkII XML file parameter */
+ unsigned int mcu_base; /* Base address of MCU control block in ATxmega devices */
+ unsigned int nvm_base; /* Base address of NVM controller in ATxmega devices */
+ int ocdrev; /* OCD revision (JTAGICE3 parameter, from AS6 XML files) */
+
+ OPCODE * op[AVR_OP_MAX]; /* opcodes */
+
+ LISTID mem; /* avr memory definitions */
+ char config_file[PATH_MAX]; /* config file where defined */
+ int lineno; /* config file line number */
+} AVRPART;
+
+#define AVR_MEMDESCLEN 64
+typedef struct avrmem {
+ char desc[AVR_MEMDESCLEN]; /* memory description ("flash", "eeprom", etc) */
+ int paged; /* page addressed (e.g. ATmega flash) */
+ int size; /* total memory size in bytes */
+ int page_size; /* size of memory page (if page addressed) */
+ int num_pages; /* number of pages (if page addressed) */
+ unsigned int offset; /* offset in IO memory (ATxmega) */
+ int min_write_delay; /* microseconds */
+ int max_write_delay; /* microseconds */
+ int pwroff_after_write; /* after this memory type is written to,
+ the device must be powered off and
+ back on, see errata
+ http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf */
+ unsigned char readback[2]; /* polled read-back values */
+
+ int mode; /* stk500 v2 xml file parameter */
+ int delay; /* stk500 v2 xml file parameter */
+ int blocksize; /* stk500 v2 xml file parameter */
+ int readsize; /* stk500 v2 xml file parameter */
+ int pollindex; /* stk500 v2 xml file parameter */
+
+ unsigned char * buf; /* pointer to memory buffer */
+ unsigned char * tags; /* allocation tags */
+ OPCODE * op[AVR_OP_MAX]; /* opcodes */
+} AVRMEM;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Functions for OPCODE structures */
+OPCODE * avr_new_opcode(void);
+void avr_free_opcode(OPCODE * op);
+int avr_set_bits(OPCODE * op, unsigned char * cmd);
+int avr_set_addr(OPCODE * op, unsigned char * cmd, unsigned long addr);
+int avr_set_input(OPCODE * op, unsigned char * cmd, unsigned char data);
+int avr_get_output(OPCODE * op, unsigned char * res, unsigned char * data);
+int avr_get_output_index(OPCODE * op);
+
+/* Functions for AVRMEM structures */
+AVRMEM * avr_new_memtype(void);
+int avr_initmem(AVRPART * p);
+AVRMEM * avr_dup_mem(AVRMEM * m);
+void avr_free_mem(AVRMEM * m);
+AVRMEM * avr_locate_mem(AVRPART * p, char * desc);
+void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, int type,
+ int verbose);
+
+/* Functions for AVRPART structures */
+AVRPART * avr_new_part(void);
+AVRPART * avr_dup_part(AVRPART * d);
+void avr_free_part(AVRPART * d);
+AVRPART * locate_part(LISTID parts, char * partdesc);
+AVRPART * locate_part_by_avr910_devcode(LISTID parts, int devcode);
+AVRPART * locate_part_by_signature(LISTID parts, unsigned char * sig,
+ int sigsize);
+void avr_display(FILE * f, AVRPART * p, const char * prefix, int verbose);
+
+typedef void (*walk_avrparts_cb)(const char *name, const char *desc,
+ const char *cfgname, int cfglineno,
+ void *cookie);
+void walk_avrparts(LISTID avrparts, walk_avrparts_cb cb, void *cookie);
+void sort_avrparts(LISTID avrparts);
+#ifdef __cplusplus
+}
+#endif
+
+/* formerly pindefs.h */
+
+enum {
+ PPI_AVR_VCC = 1,
+ PPI_AVR_BUFF,
+ PIN_AVR_RESET,
+ PIN_AVR_SCK,
+ PIN_AVR_MOSI,
+ PIN_AVR_MISO,
+ PIN_LED_ERR,
+ PIN_LED_RDY,
+ PIN_LED_PGM,
+ PIN_LED_VFY,
+ N_PINS
+};
+
+#define PIN_MASK (UINT_MAX>>1)
+#define PIN_INVERSE (~(PIN_MASK)) /* flag for inverted pin in serbb */
+#define PIN_MIN 0 /* smallest allowed pin number */
+#define PIN_MAX 31 /* largest allowed pin number */
+
+#ifdef HAVE_LINUXGPIO
+/* Embedded systems might have a lot more gpio than only 0-31 */
+#undef PIN_MAX
+#define PIN_MAX 255 /* largest allowed pin number */
+#endif
+
+/** Number of pins in each element of the bitfield */
+#define PIN_FIELD_ELEMENT_SIZE (sizeof(pinmask_t) * 8)
+/** Numer of elements to store the complete bitfield of all pins */
+#define PIN_FIELD_SIZE ((PIN_MAX + PIN_FIELD_ELEMENT_SIZE)/PIN_FIELD_ELEMENT_SIZE)
+
+/**
+ * This sets the corresponding bits to 1 or 0, the inverse mask is used to invert the value in necessary.
+ * It uses only the lowest element (index=0) of the bitfield, which should be enough for most
+ * programmers.
+ *
+ * @param[in] x input value
+ * @param[in] pgm the programmer whose pin definitions to use
+ * @param[in] pinname the logical name of the pin (PIN_AVR_*, ...)
+ * @param[in] level the logical level (level != 0 => 1, level == 0 => 0),
+ * if the pin is defined as inverted the resulting bit is also inverted
+ * @returns the input value with the relevant bits modified
+ */
+#define SET_BITS_0(x,pgm,pinname,level) (((x) & ~(pgm)->pin[pinname].mask[0]) \
+ | (\
+ (pgm)->pin[pinname].mask[0] & ( \
+ (level) \
+ ?~((pgm)->pin[pinname].inverse[0]) \
+ : ((pgm)->pin[pinname].inverse[0]) \
+ ) \
+ ) \
+)
+
+/**
+ * Check if the corresponding bit is set (returns != 0) or cleared.
+ * The inverse mask is used, to invert the relevant bits.
+ * If the pin definition contains multiple pins, then a single set pin leads to return value != 0.
+ * Then you have to check the relevant bits of the returned value, if you need more information.
+ * It uses only the lowest element (index=0) of the bitfield, which should be enough for most
+ * programmers.
+ *
+ * @param[in] x input value
+ * @param[in] pgm the programmer whose pin definitions to use
+ * @param[in] pinname the logical name of the pin (PIN_AVR_*, ...)
+ * @returns the input value with only the relevant bits (which are already inverted,
+ * so you get always the logical level)
+ */
+#define GET_BITS_0(x,pgm,pinname) (((x) ^ (pgm)->pin[pinname].inverse[0]) & (pgm)->pin[pinname].mask[0])
+
+/**
+ * Data structure to hold used pins by logical function (PIN_AVR_*, ...)
+ */
+struct pindef_t {
+ pinmask_t mask[PIN_FIELD_SIZE]; ///< bitfield of used pins
+ pinmask_t inverse[PIN_FIELD_SIZE]; ///< bitfield of inverse/normal usage of used pins
+};
+
+/**
+ * Data structure to define a checklist of valid pins for each function.
+ */
+struct pin_checklist_t {
+ int pinname; ///< logical pinname eg. PIN_AVR_SCK
+ int mandatory; ///< is this a mandatory pin
+ const struct pindef_t* valid_pins; ///< mask defines allowed pins, inverse define is they might be used inverted
+};
+
+/**
+ * Adds a pin in the pin definition as normal or inverse pin.
+ *
+ * @param[out] pindef pin definition to update
+ * @param[in] pin number of pin [0..PIN_MAX]
+ * @param[in] inverse inverse (true) or normal (false) pin
+ */
+void pin_set_value(struct pindef_t * const pindef, const int pin, const bool inverse);
+
+/**
+ * Clear all defined pins in pindef.
+ *
+ * @param[out] pindef pin definition to clear
+ */
+void pin_clear_all(struct pindef_t * const pindef);
+
+struct programmer_t; /* forward declaration */
+
+/**
+ * Convert for given programmer new pin definitions to old pin definitions.
+ *
+ * @param[inout] pgm programmer whose pins shall be converted.
+ */
+int pgm_fill_old_pins(struct programmer_t * const pgm);
+
+/**
+ * This function checks all pin of pgm against the constraints given in the checklist.
+ * It checks if
+ * @li any invalid pins are used
+ * @li valid pins are used inverted when not allowed
+ * @li any pins are used by more than one function
+ * @li any mandatory pin is not set all.
+ *
+ * In case of any error it report the wrong function and the pin numbers.
+ * For verbose >= 2 it also reports the possible correct values.
+ * For verbose >=3 it shows also which pins were ok.
+ *
+ * @param[in] pgm the programmer to check
+ * @param[in] checklist the constraint for the pins
+ * @param[in] size the number of entries in checklist
+ * @param[in] output false suppresses error messages to the user
+ * @returns 0 if all pin definitions are valid, -1 otherwise
+ */
+int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size, const bool output);
+
+/**
+ * Returns the name of the pin as string.
+ *
+ * @param pinname the pinname which we want as string.
+ * @returns a string with the pinname, or <unknown> if pinname is invalid.
+ */
+const char * avr_pin_name(int pinname);
+
+/**
+ * This function returns a string representation of defined pins eg. ~1,2,~4,~5,7
+ * Another execution of this function will overwrite the previous result in the static buffer.
+ *
+ * @param[in] pindef the pin definition for which we want the string representation
+ * @returns pointer to a static string.
+ */
+const char * pins_to_str(const struct pindef_t * const pindef);
+
+/**
+ * This function returns a string representation of pins in the mask eg. 1,3,5-7,9,12
+ * Another execution of this function will overwrite the previous result in the static buffer.
+ * Consecutive pin number are representated as start-end.
+ *
+ * @param[in] pinmask the pin mask for which we want the string representation
+ * @returns pointer to a static string.
+ */
+const char * pinmask_to_str(const pinmask_t * const pinmask);
+
+/* formerly serial.h */
+
+/* This is the API for the generic serial interface. The implementations are
+ actually provided by the target dependant files:
+
+ ser_posix.c : posix serial interface.
+ ser_win32.c : native win32 serial interface.
+
+ The target file will be selected at configure time. */
+
+extern long serial_recv_timeout;
+union filedescriptor
+{
+ int ifd;
+ void *pfd;
+ struct
+ {
+ void *handle;
+ int rep; /* bulk read endpoint */
+ int wep; /* bulk write endpoint */
+ int eep; /* event read endpoint */
+ int max_xfer; /* max transfer size */
+ int use_interrupt_xfer; /* device uses interrupt transfers */
+ } usb;
+};
+
+union pinfo
+{
+ long baud;
+ struct
+ {
+ unsigned short vid;
+ unsigned short pid;
+ unsigned short flags;
+#define PINFO_FL_USEHID 0x0001
+#define PINFO_FL_SILENT 0x0002 /* don't complain if not found */
+ } usbinfo;
+};
+
+
+struct serial_device
+{
+ // open should return -1 on error, other values on success
+ int (*open)(char * port, union pinfo pinfo, union filedescriptor *fd);
+ int (*setspeed)(union filedescriptor *fd, long baud);
+ void (*close)(union filedescriptor *fd);
+
+ int (*send)(union filedescriptor *fd, const unsigned char * buf, size_t buflen);
+ int (*recv)(union filedescriptor *fd, unsigned char * buf, size_t buflen);
+ int (*drain)(union filedescriptor *fd, int display);
+
+ int (*set_dtr_rts)(union filedescriptor *fd, int is_on);
+
+ int flags;
+#define SERDEV_FL_NONE 0x0000 /* no flags */
+#define SERDEV_FL_CANSETSPEED 0x0001 /* device can change speed */
+};
+
+extern struct serial_device *serdev;
+extern struct serial_device serial_serdev;
+extern struct serial_device usb_serdev;
+extern struct serial_device usb_serdev_frame;
+extern struct serial_device avrdoper_serdev;
+extern struct serial_device usbhid_serdev;
+
+#define serial_open (serdev->open)
+#define serial_setspeed (serdev->setspeed)
+#define serial_close (serdev->close)
+#define serial_send (serdev->send)
+#define serial_recv (serdev->recv)
+#define serial_drain (serdev->drain)
+#define serial_set_dtr_rts (serdev->set_dtr_rts)
+
+/* formerly pgm.h */
+
+#define ON 1
+#define OFF 0
+
+#define PGM_DESCLEN 80
+#define PGM_PORTLEN PATH_MAX
+#define PGM_TYPELEN 32
+#define PGM_USBSTRINGLEN 256
+
+typedef enum {
+ EXIT_VCC_UNSPEC,
+ EXIT_VCC_ENABLED,
+ EXIT_VCC_DISABLED
+} exit_vcc_t;
+
+typedef enum {
+ EXIT_RESET_UNSPEC,
+ EXIT_RESET_ENABLED,
+ EXIT_RESET_DISABLED
+} exit_reset_t;
+
+typedef enum {
+ EXIT_DATAHIGH_UNSPEC,
+ EXIT_DATAHIGH_ENABLED,
+ EXIT_DATAHIGH_DISABLED
+} exit_datahigh_t;
+
+typedef enum {
+ CONNTYPE_PARALLEL,
+ CONNTYPE_SERIAL,
+ CONNTYPE_USB
+} conntype_t;
+
+typedef struct programmer_t {
+ LISTID id;
+ char desc[PGM_DESCLEN];
+ char type[PGM_TYPELEN];
+ char port[PGM_PORTLEN];
+ void (*initpgm)(struct programmer_t * pgm);
+ unsigned int pinno[N_PINS];
+ struct pindef_t pin[N_PINS];
+ exit_vcc_t exit_vcc;
+ exit_reset_t exit_reset;
+ exit_datahigh_t exit_datahigh;
+ conntype_t conntype;
+ int ppidata;
+ int ppictrl;
+ int baudrate;
+ int usbvid;
+ LISTID usbpid;
+ char usbdev[PGM_USBSTRINGLEN], usbsn[PGM_USBSTRINGLEN];
+ char usbvendor[PGM_USBSTRINGLEN], usbproduct[PGM_USBSTRINGLEN];
+ double bitclock; /* JTAG ICE clock period in microseconds */
+ int ispdelay; /* ISP clock delay */
+ union filedescriptor fd;
+ int page_size; /* page size if the programmer supports paged write/load */
+ int (*rdy_led) (struct programmer_t * pgm, int value);
+ int (*err_led) (struct programmer_t * pgm, int value);
+ int (*pgm_led) (struct programmer_t * pgm, int value);
+ int (*vfy_led) (struct programmer_t * pgm, int value);
+ int (*initialize) (struct programmer_t * pgm, AVRPART * p);
+ void (*display) (struct programmer_t * pgm, const char * p);
+ void (*enable) (struct programmer_t * pgm);
+ void (*disable) (struct programmer_t * pgm);
+ void (*powerup) (struct programmer_t * pgm);
+ void (*powerdown) (struct programmer_t * pgm);
+ int (*program_enable) (struct programmer_t * pgm, AVRPART * p);
+ int (*chip_erase) (struct programmer_t * pgm, AVRPART * p);
+ int (*cmd) (struct programmer_t * pgm, const unsigned char *cmd,
+ unsigned char *res);
+ int (*cmd_tpi) (struct programmer_t * pgm, const unsigned char *cmd,
+ int cmd_len, unsigned char res[], int res_len);
+ int (*spi) (struct programmer_t * pgm, const unsigned char *cmd,
+ unsigned char *res, int count);
+ int (*open) (struct programmer_t * pgm, char * port);
+ void (*close) (struct programmer_t * pgm);
+ int (*paged_write) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size, unsigned int baseaddr,
+ unsigned int n_bytes);
+ int (*paged_load) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size, unsigned int baseaddr,
+ unsigned int n_bytes);
+ int (*page_erase) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int baseaddr);
+ void (*write_setup) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
+ int (*write_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char value);
+ int (*read_byte) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m,
+ unsigned long addr, unsigned char * value);
+ int (*read_sig_bytes) (struct programmer_t * pgm, AVRPART * p, AVRMEM * m);
+ void (*print_parms) (struct programmer_t * pgm);
+ int (*set_vtarget) (struct programmer_t * pgm, double v);
+ int (*set_varef) (struct programmer_t * pgm, unsigned int chan, double v);
+ int (*set_fosc) (struct programmer_t * pgm, double v);
+ int (*set_sck_period) (struct programmer_t * pgm, double v);
+ int (*setpin) (struct programmer_t * pgm, int pinfunc, int value);
+ int (*getpin) (struct programmer_t * pgm, int pinfunc);
+ int (*highpulsepin) (struct programmer_t * pgm, int pinfunc);
+ int (*parseexitspecs) (struct programmer_t * pgm, char *s);
+ int (*perform_osccal) (struct programmer_t * pgm);
+ int (*parseextparams) (struct programmer_t * pgm, LISTID xparams);
+ void (*setup) (struct programmer_t * pgm);
+ void (*teardown) (struct programmer_t * pgm);
+ void (*set_upload_size)(struct programmer_t * pgm, int size);
+ char config_file[PATH_MAX]; /* config file where defined */
+ int lineno; /* config file line number */
+ void *cookie; /* for private use by the programmer */
+ char flag; /* for private use of the programmer */
+} PROGRAMMER;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PROGRAMMER * pgm_new(void);
+PROGRAMMER * pgm_dup(const PROGRAMMER * const src);
+void pgm_free(PROGRAMMER * const p);
+
+void programmer_display(PROGRAMMER * pgm, const char * p);
+
+/* show is a mask like this (1<<PIN_AVR_SCK)|(1<<PIN_AVR_MOSI)| ... */
+#define SHOW_ALL_PINS (~0u)
+#define SHOW_PPI_PINS ((1<<PPI_AVR_VCC)|(1<<PPI_AVR_BUFF))
+#define SHOW_AVR_PINS ((1<<PIN_AVR_RESET)|(1<<PIN_AVR_SCK)|(1<<PIN_AVR_MOSI)|(1<<PIN_AVR_MISO))
+#define SHOW_LED_PINS ((1<<PIN_LED_ERR)|(1<<PIN_LED_RDY)|(1<<PIN_LED_PGM)|(1<<PIN_LED_VFY))
+void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show);
+void pgm_display_generic(PROGRAMMER * pgm, const char * p);
+
+PROGRAMMER * locate_programmer(LISTID programmers, const char * configid);
+
+typedef void (*walk_programmers_cb)(const char *name, const char *desc,
+ const char *cfgname, int cfglineno,
+ void *cookie);
+void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie);
+
+void sort_programmers(LISTID programmers);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* formerly avr.h */
+
+typedef void (*FP_UpdateProgress)(int percent, double etime, char *hdr);
+
+extern struct avrpart parts[];
+
+extern FP_UpdateProgress update_progress;
+
+extern bool cancel_flag;
+#define RETURN_IF_CANCEL() \
+ do { \
+ if (cancel_flag) { \
+ avrdude_message(MSG_INFO, "avrdude: %s(): Cancelled, exiting...\n", __func__); \
+ return -99; \
+ } \
+ } while (0)
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int avr_tpi_poll_nvmbsy(PROGRAMMER *pgm);
+int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
+int avr_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p, unsigned char guard_time);
+int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value);
+
+int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, AVRPART * v);
+
+int avr_write_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr);
+
+int avr_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data);
+
+int avr_write_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data);
+
+int avr_write(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size,
+ int auto_erase);
+
+int avr_signature(PROGRAMMER * pgm, AVRPART * p);
+
+int avr_verify(AVRPART * p, AVRPART * v, char * memtype, int size);
+
+int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles);
+
+int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);
+
+int avr_mem_hiaddr(AVRMEM * mem);
+
+int avr_chip_erase(PROGRAMMER * pgm, AVRPART * p);
+
+void report_progress (int completed, int total, char *hdr);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* formerly fileio.h */
+
+typedef enum {
+ FMT_AUTO,
+ FMT_SREC,
+ FMT_IHEX,
+ FMT_RBIN,
+ FMT_IMM,
+ FMT_HEX,
+ FMT_DEC,
+ FMT_OCT,
+ FMT_BIN,
+ FMT_ELF
+} FILEFMT;
+
+struct fioparms {
+ int op;
+ char * mode;
+ char * iodesc;
+ char * dir;
+ char * rw;
+ unsigned int fileoffset;
+};
+
+enum {
+ FIO_READ,
+ FIO_WRITE
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char * fmtstr(FILEFMT format);
+
+int fileio(int op, char * filename, FILEFMT format,
+ struct avrpart * p, char * memtype, int size, unsigned section);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* formerly safemode.h */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Writes the specified fuse in fusename (can be "lfuse", "hfuse", or "efuse") and verifies it. Will try up to tries
+amount of times before giving up */
+int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm, AVRPART * p, int tries);
+
+/* Reads the fuses three times, checking that all readings are the same. This will ensure that the before values aren't in error! */
+int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse, PROGRAMMER * pgm, AVRPART * p);
+
+/* This routine will store the current values pointed to by lfuse, hfuse, and efuse into an internal buffer in this routine
+when save is set to 1. When save is 0 (or not 1 really) it will copy the values from the internal buffer into the locations
+pointed to be lfuse, hfuse, and efuse. This allows you to change the fuse bits if needed from another routine (ie: have it so
+if user requests fuse bits are changed, the requested value is now verified */
+int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse, unsigned char * efuse, unsigned char * fuse);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* formerly update.h */
+
+enum {
+ DEVICE_READ,
+ DEVICE_WRITE,
+ DEVICE_VERIFY
+};
+
+enum updateflags {
+ UF_NONE = 0,
+ UF_NOWRITE = 1,
+ UF_AUTO_ERASE = 2,
+};
+
+
+typedef struct update_t {
+ char * memtype;
+ int op;
+ unsigned section;
+ char * filename;
+ int format;
+} UPDATE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern UPDATE * parse_op(char * s);
+extern UPDATE * dup_update(UPDATE * upd);
+extern UPDATE * new_update(int op, char * memtype, int filefmt,
+ char * filename, unsigned section);
+extern void free_update(UPDATE * upd);
+extern int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd,
+ enum updateflags flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* formerly pgm_type.h */
+
+/*LISTID programmer_types;*/
+
+typedef struct programmer_type_t {
+ const char * const id;
+ void (*initpgm)(struct programmer_t * pgm);
+ const char * const desc;
+} PROGRAMMER_TYPE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const PROGRAMMER_TYPE * locate_programmer_type(/*LISTID programmer_types, */const char * id);
+
+typedef void (*walk_programmer_types_cb)(const char *id, const char *desc,
+ void *cookie);
+void walk_programmer_types(/*LISTID programmer_types,*/ walk_programmer_types_cb cb, void *cookie);
+
+#ifdef __cplusplus
+}
+#endif
+
+/* formerly config.h */
+
+extern LISTID part_list;
+extern LISTID programmers;
+extern char default_programmer[];
+extern char default_parallel[];
+extern char default_serial[];
+extern double default_bitclock;
+extern int default_safemode;
+
+/* This name is fixed, it's only here for symmetry with
+ * default_parallel and default_serial. */
+#define DEFAULT_USB "usb"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int init_config(void);
+
+void cleanup_config(void);
+
+int read_config(const char * file);
+
+#ifdef __cplusplus
+}
+#endif
+
+// Header file for alloca()
+#if defined(WIN32NATIVE)
+# include <malloc.h>
+#else
+# include <alloca.h>
+#endif
+
+
+/* formerly confwin.h */
+
+// #if defined(WIN32NATIVE)
+
+// #ifdef __cplusplus
+// extern "C" {
+// #endif
+
+// void win_sys_config_set(char sys_config[PATH_MAX]);
+// void win_usr_config_set(char usr_config[PATH_MAX]);
+
+// #ifdef __cplusplus
+// }
+// #endif
+
+// #endif /* WIN32NATIVE */
+
+
+#endif /* libavrdude_h */
diff --git a/xs/src/avrdude/linux_ppdev.h b/xs/src/avrdude/linux_ppdev.h
new file mode 100644
index 000000000..1d2e6e2ec
--- /dev/null
+++ b/xs/src/avrdude/linux_ppdev.h
@@ -0,0 +1,57 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003, 2005 Theodore A. Roth
+ *
+ * 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 linux_ppdev_h
+#define linux_ppdev_h
+
+#define OBSOLETE__IOW _IOW
+
+#include <sys/ioctl.h>
+#ifdef HAVE_PARPORT
+#include <linux/parport.h>
+#include <linux/ppdev.h>
+#endif
+
+#include <stdlib.h>
+
+#define ppi_claim(fd) \
+ if (ioctl(fd, PPCLAIM)) { \
+ avrdude_message(MSG_INFO, "%s: can't claim device \"%s\": %s\n\n", \
+ progname, port, strerror(errno)); \
+ close(fd); \
+ return; \
+ }
+
+#define ppi_release(fd) \
+ if (ioctl(fd, PPRELEASE)) { \
+ avrdude_message(MSG_INFO, "%s: can't release device: %s\n\n", \
+ progname, strerror(errno)); \
+ }
+
+#define DO_PPI_READ(fd, reg, valp) \
+ (void)ioctl(fd, \
+ (reg) == PPIDATA? PPRDATA: ((reg) == PPICTRL? PPRCONTROL: PPRSTATUS), \
+ valp)
+#define DO_PPI_WRITE(fd, reg, valp) \
+ (void)ioctl(fd, \
+ (reg) == PPIDATA? PPWDATA: ((reg) == PPICTRL? PPWCONTROL: PPWSTATUS), \
+ valp)
+
+#endif /* linux_ppdev_h */
diff --git a/xs/src/avrdude/linuxgpio.c b/xs/src/avrdude/linuxgpio.c
new file mode 100644
index 000000000..b61631174
--- /dev/null
+++ b/xs/src/avrdude/linuxgpio.c
@@ -0,0 +1,354 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Support for bitbanging GPIO pins using the /sys/class/gpio interface
+ *
+ * Copyright (C) 2013 Radoslav Kolev <radoslav@kolev.info>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "bitbang.h"
+
+#if HAVE_LINUXGPIO
+
+/*
+ * GPIO user space helpers
+ *
+ * Copyright 2009 Analog Devices Inc.
+ * Michael Hennerich (hennerich@blackfin.uclinux.org)
+ *
+ * Licensed under the GPL-2 or later
+ */
+
+/*
+ * GPIO user space helpers
+ * The following functions are acting on an "unsigned gpio" argument, which corresponds to the
+ * gpio numbering scheme in the kernel (starting from 0).
+ * The higher level functions use "int pin" to specify the pins with an offset of 1:
+ * gpio = pin - 1;
+ */
+
+#define GPIO_DIR_IN 0
+#define GPIO_DIR_OUT 1
+
+static int linuxgpio_export(unsigned int gpio)
+{
+ int fd, len, r;
+ char buf[11];
+
+ fd = open("/sys/class/gpio/export", O_WRONLY);
+ if (fd < 0) {
+ perror("Can't open /sys/class/gpio/export");
+ return fd;
+ }
+
+ len = snprintf(buf, sizeof(buf), "%u", gpio);
+ r = write(fd, buf, len);
+ close(fd);
+
+ return r;
+}
+
+static int linuxgpio_unexport(unsigned int gpio)
+{
+ int fd, len, r;
+ char buf[11];
+
+ fd = open("/sys/class/gpio/unexport", O_WRONLY);
+ if (fd < 0) {
+ perror("Can't open /sys/class/gpio/unexport");
+ return fd;
+ }
+
+ len = snprintf(buf, sizeof(buf), "%u", gpio);
+ r = write(fd, buf, len);
+ close(fd);
+
+ return r;
+}
+
+static int linuxgpio_openfd(unsigned int gpio)
+{
+ char filepath[60];
+
+ snprintf(filepath, sizeof(filepath), "/sys/class/gpio/gpio%u/value", gpio);
+ return (open(filepath, O_RDWR));
+}
+
+static int linuxgpio_dir(unsigned int gpio, unsigned int dir)
+{
+ int fd, r;
+ char buf[60];
+
+ snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%u/direction", gpio);
+
+ fd = open(buf, O_WRONLY);
+ if (fd < 0) {
+ perror("Can't open gpioX/direction");
+ return fd;
+ }
+
+ if (dir == GPIO_DIR_OUT)
+ r = write(fd, "out", 4);
+ else
+ r = write(fd, "in", 3);
+
+ close(fd);
+
+ return r;
+}
+
+static int linuxgpio_dir_out(unsigned int gpio)
+{
+ return linuxgpio_dir(gpio, GPIO_DIR_OUT);
+}
+
+static int linuxgpio_dir_in(unsigned int gpio)
+{
+ return linuxgpio_dir(gpio, GPIO_DIR_IN);
+}
+
+/*
+ * End of GPIO user space helpers
+ */
+
+#define N_GPIO (PIN_MAX + 1)
+
+/*
+* an array which holds open FDs to /sys/class/gpio/gpioXX/value for all needed pins
+*/
+static int linuxgpio_fds[N_GPIO] ;
+
+
+static int linuxgpio_setpin(PROGRAMMER * pgm, int pinfunc, int value)
+{
+ int r;
+ int pin = pgm->pinno[pinfunc]; // TODO
+
+ if (pin & PIN_INVERSE)
+ {
+ value = !value;
+ pin &= PIN_MASK;
+ }
+
+ if ( linuxgpio_fds[pin] < 0 )
+ return -1;
+
+ if (value)
+ r = write(linuxgpio_fds[pin], "1", 1);
+ else
+ r = write(linuxgpio_fds[pin], "0", 1);
+
+ if (r!=1) return -1;
+
+ if (pgm->ispdelay > 1)
+ bitbang_delay(pgm->ispdelay);
+
+ return 0;
+}
+
+static int linuxgpio_getpin(PROGRAMMER * pgm, int pinfunc)
+{
+ unsigned char invert=0;
+ char c;
+ int pin = pgm->pinno[pinfunc]; // TODO
+
+ if (pin & PIN_INVERSE)
+ {
+ invert = 1;
+ pin &= PIN_MASK;
+ }
+
+ if ( linuxgpio_fds[pin] < 0 )
+ return -1;
+
+ if (lseek(linuxgpio_fds[pin], 0, SEEK_SET)<0)
+ return -1;
+
+ if (read(linuxgpio_fds[pin], &c, 1)!=1)
+ return -1;
+
+ if (c=='0')
+ return 0+invert;
+ else if (c=='1')
+ return 1-invert;
+ else
+ return -1;
+
+}
+
+static int linuxgpio_highpulsepin(PROGRAMMER * pgm, int pinfunc)
+{
+ int pin = pgm->pinno[pinfunc]; // TODO
+
+ if ( linuxgpio_fds[pin & PIN_MASK] < 0 )
+ return -1;
+
+ linuxgpio_setpin(pgm, pinfunc, 1);
+ linuxgpio_setpin(pgm, pinfunc, 0);
+
+ return 0;
+}
+
+
+
+static void linuxgpio_display(PROGRAMMER *pgm, const char *p)
+{
+ avrdude_message(MSG_INFO, "%sPin assignment : /sys/class/gpio/gpio{n}\n",p);
+ pgm_display_generic_mask(pgm, p, SHOW_AVR_PINS);
+}
+
+static void linuxgpio_enable(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void linuxgpio_disable(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void linuxgpio_powerup(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void linuxgpio_powerdown(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static int linuxgpio_open(PROGRAMMER *pgm, char *port)
+{
+ int r, i, pin;
+
+ if (bitbang_check_prerequisites(pgm) < 0)
+ return -1;
+
+
+ for (i=0; i<N_GPIO; i++)
+ linuxgpio_fds[i] = -1;
+ //Avrdude assumes that if a pin number is 0 it means not used/available
+ //this causes a problem because 0 is a valid GPIO number in Linux sysfs.
+ //To avoid annoying off by one pin numbering we assume SCK, MOSI, MISO
+ //and RESET pins are always defined in avrdude.conf, even as 0. If they're
+ //not programming will not work anyway. The drawbacks of this approach are
+ //that unwanted toggling of GPIO0 can occur and that other optional pins
+ //mostry LED status, can't be set to GPIO0. It can be fixed when a better
+ //solution exists.
+ for (i=0; i<N_PINS; i++) {
+ if ( (pgm->pinno[i] & PIN_MASK) != 0 ||
+ i == PIN_AVR_RESET ||
+ i == PIN_AVR_SCK ||
+ i == PIN_AVR_MOSI ||
+ i == PIN_AVR_MISO ) {
+ pin = pgm->pinno[i] & PIN_MASK;
+ if ((r=linuxgpio_export(pin)) < 0) {
+ avrdude_message(MSG_INFO, "Can't export GPIO %d, already exported/busy?: %s",
+ pin, strerror(errno));
+ return r;
+ }
+ if (i == PIN_AVR_MISO)
+ r=linuxgpio_dir_in(pin);
+ else
+ r=linuxgpio_dir_out(pin);
+
+ if (r < 0)
+ return r;
+
+ if ((linuxgpio_fds[pin]=linuxgpio_openfd(pin)) < 0)
+ return linuxgpio_fds[pin];
+ }
+ }
+
+ return(0);
+}
+
+static void linuxgpio_close(PROGRAMMER *pgm)
+{
+ int i, reset_pin;
+
+ reset_pin = pgm->pinno[PIN_AVR_RESET] & PIN_MASK;
+
+ //first configure all pins as input, except RESET
+ //this should avoid possible conflicts when AVR firmware starts
+ for (i=0; i<N_GPIO; i++) {
+ if (linuxgpio_fds[i] >= 0 && i != reset_pin) {
+ close(linuxgpio_fds[i]);
+ linuxgpio_dir_in(i);
+ linuxgpio_unexport(i);
+ }
+ }
+ //configure RESET as input, if there's external pull up it will go high
+ if (linuxgpio_fds[reset_pin] >= 0) {
+ close(linuxgpio_fds[reset_pin]);
+ linuxgpio_dir_in(reset_pin);
+ linuxgpio_unexport(reset_pin);
+ }
+}
+
+void linuxgpio_initpgm(PROGRAMMER *pgm)
+{
+ strcpy(pgm->type, "linuxgpio");
+
+ pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
+
+ pgm->rdy_led = bitbang_rdy_led;
+ pgm->err_led = bitbang_err_led;
+ pgm->pgm_led = bitbang_pgm_led;
+ pgm->vfy_led = bitbang_vfy_led;
+ pgm->initialize = bitbang_initialize;
+ pgm->display = linuxgpio_display;
+ pgm->enable = linuxgpio_enable;
+ pgm->disable = linuxgpio_disable;
+ pgm->powerup = linuxgpio_powerup;
+ pgm->powerdown = linuxgpio_powerdown;
+ pgm->program_enable = bitbang_program_enable;
+ pgm->chip_erase = bitbang_chip_erase;
+ pgm->cmd = bitbang_cmd;
+ pgm->open = linuxgpio_open;
+ pgm->close = linuxgpio_close;
+ pgm->setpin = linuxgpio_setpin;
+ pgm->getpin = linuxgpio_getpin;
+ pgm->highpulsepin = linuxgpio_highpulsepin;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+}
+
+const char linuxgpio_desc[] = "GPIO bitbanging using the Linux sysfs interface";
+
+#else /* !HAVE_LINUXGPIO */
+
+void linuxgpio_initpgm(PROGRAMMER * pgm)
+{
+ avrdude_message(MSG_INFO, "%s: Linux sysfs GPIO support not available in this configuration\n",
+ progname);
+}
+
+const char linuxgpio_desc[] = "GPIO bitbanging using the Linux sysfs interface (not available)";
+
+#endif /* HAVE_LINUXGPIO */
diff --git a/xs/src/avrdude/linuxgpio.h b/xs/src/avrdude/linuxgpio.h
new file mode 100644
index 000000000..dc477982a
--- /dev/null
+++ b/xs/src/avrdude/linuxgpio.h
@@ -0,0 +1,36 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2013 Radoslav Kolev <radoslav@kolev.info>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: par.h 722 2007-01-24 22:43:46Z joerg_wunsch $ */
+
+#ifndef linuxgpio_h
+#define linuxgpio_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char linuxgpio_desc[];
+void linuxgpio_initpgm (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/xs/src/avrdude/lists.c b/xs/src/avrdude/lists.c
new file mode 100644
index 000000000..cab88364e
--- /dev/null
+++ b/xs/src/avrdude/lists.c
@@ -0,0 +1,1407 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 1990-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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$ */
+
+
+
+/*----------------------------------------------------------------------
+ Id: lists.c,v 1.4 2001/08/19 23:26:20 bsd Exp $
+ ----------------------------------------------------------------------*/
+/*------------------------------------------------------------------------
+ lists.c
+
+ General purpose linked list routines. These routines implement a
+ generic doubly linked list. Any data type may be placed in the
+ lists. Stacking and Queuing routines are provided via #defines
+ declared in 'lists.h'.
+
+ Author : Brian Dean
+ Date : 10 January, 1990
+ ------------------------------------------------------------------------*/
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "libavrdude.h"
+
+#define MAGIC 0xb05b05b0
+
+#define CHECK_MAGIC 0 /* set to 1 to enable memory overwrite detection */
+
+#ifdef BOS
+#define MALLOC(size,x) kmalloc(size,x)
+#define FREE kfree
+#else
+#define MALLOC(size,x) malloc(size)
+#define FREE free
+#endif
+
+
+/*------------------------------------------------------------
+| required private data structures
+ ------------------------------------------------------------*/
+typedef struct LISTNODE {
+#if CHECK_MAGIC
+ unsigned int magic1;
+#endif
+ struct LISTNODE * next; /* chain to next item in the list */
+ struct LISTNODE * prev; /* chain to previous item in the list */
+ void * data; /* pointer to user data */
+#if CHECK_MAGIC
+ unsigned int magic2;
+#endif
+} LISTNODE;
+
+
+typedef struct NODEPOOL {
+#if CHECK_MAGIC
+ unsigned int magic1;
+#endif
+ struct NODEPOOL * chain_next; /* chain to next node pool */
+ struct NODEPOOL * chain_prev; /* chain to previous node pool */
+#if CHECK_MAGIC
+ unsigned int magic2;
+#endif
+} NODEPOOL;
+
+
+typedef struct LIST {
+#if CHECK_MAGIC
+ unsigned int magic1;
+#endif
+ int num; /* number of elements in the list */
+ short int free_on_close; /* free the LIST memory on close T/F */
+ short int poolsize; /* list node allocation size */
+ int n_ln_pool; /* number of listnodes in a pool */
+ LISTNODE * top; /* top of the list */
+ LISTNODE * bottom; /* bottom of the list */
+ LISTNODE * next_ln; /* next available list node */
+ NODEPOOL * np_top; /* top of the node pool chain */
+ NODEPOOL * np_bottom; /* bottom of the node pool chain */
+#if CHECK_MAGIC
+ unsigned int magic2;
+#endif
+} LIST;
+
+
+/* allocate list nodes in 512 byte chunks, giving 42 elements */
+#define DEFAULT_POOLSIZE 512
+
+
+#if CHECK_MAGIC
+#define CKMAGIC(p) { if (p->magic1 != MAGIC) breakpoint(); \
+ if (p->magic2 != MAGIC) breakpoint(); }
+
+#define CKNPMAGIC(p) cknpmagic(p)
+
+#define CKLNMAGIC(p) cklnmagic(p)
+
+#define CKLMAGIC(p) cklmagic(p)
+#else
+#define CKMAGIC(p)
+
+#define CKNPMAGIC(p)
+
+#define CKLNMAGIC(p)
+
+#define CKLMAGIC(p)
+#endif
+
+
+static int insert_ln ( LIST * l, LISTNODE * ln, void * data_ptr );
+
+
+#if CHECK_MAGIC
+static int cknpmagic ( LIST * l )
+{
+ NODEPOOL * np;
+ int i;
+
+ i = 0;
+ np = l->np_top;
+ while (np) {
+ i++;
+ CKMAGIC(np);
+ np = np->chain_next;
+ }
+
+ i = 0;
+ np = l->np_bottom;
+ while (np) {
+ i++;
+ CKMAGIC(np);
+ np = np->chain_prev;
+ }
+
+ return 0;
+}
+
+
+
+static int cklnmagic ( LIST * l )
+{
+ LISTNODE * ln;
+ int i;
+
+ i = 0;
+ ln = l->top;
+ while (ln) {
+ i++;
+ CKMAGIC(ln);
+ ln = ln->next;
+ }
+
+ i = 0;
+ ln = l->bottom;
+ while (ln) {
+ i++;
+ CKMAGIC(ln);
+ ln = ln->prev;
+ }
+
+ return 0;
+}
+
+
+static int cklmagic ( LIST * l )
+{
+ CKMAGIC(l);
+ CKNPMAGIC(l);
+ CKLNMAGIC(l);
+ CKMAGIC(l);
+ return 0;
+}
+#endif
+
+
+/*------------------------------------------------------------
+| new_node_pool
+|
+| Create and initialize a new pool of list nodes. This is
+| just a big block of memory with the first sizeof(NODEPOOL)
+| bytes reserved. The first available list node resides at
+| offset sizeof(NODEPOOL).
+ ------------------------------------------------------------*/
+static
+NODEPOOL *
+new_nodepool ( LIST * l )
+{
+ NODEPOOL * np;
+ LISTNODE * ln;
+ int i;
+
+ CKLMAGIC(l);
+
+ /*--------------------------------------------------
+ | get a block of memory for the new pool
+ --------------------------------------------------*/
+ np = (NODEPOOL *) MALLOC ( l->poolsize, "list node pool" );
+ if (np == NULL) {
+ return NULL;
+ }
+
+ /*--------------------------------------------------
+ | initialize the chaining information at the
+ | beginning of the pool.
+ --------------------------------------------------*/
+#if CHECK_MAGIC
+ np->magic1 = MAGIC;
+#endif
+ np->chain_next = NULL;
+ np->chain_prev = NULL;
+#if CHECK_MAGIC
+ np->magic2 = MAGIC;
+#endif
+
+ /*--------------------------------------------------
+ | initialize all the list nodes within the node
+ | pool, which begin just after the NODEPOOL
+ | structure at the beginning of the memory block
+ --------------------------------------------------*/
+ ln = (LISTNODE *) (&np[1]);
+
+#if CHECK_MAGIC
+ ln[0].magic1 = MAGIC;
+#endif
+ ln[0].data = NULL;
+ ln[0].next = &ln[1];
+ ln[0].prev = NULL;
+#if CHECK_MAGIC
+ ln[0].magic2 = MAGIC;
+#endif
+
+ for (i=1; i<l->n_ln_pool-1; i++) {
+#if CHECK_MAGIC
+ ln[i].magic1 = MAGIC;
+#endif
+ ln[i].data = NULL;
+ ln[i].next = &ln[i+1];
+ ln[i].prev = &ln[i-1];
+#if CHECK_MAGIC
+ ln[i].magic2 = MAGIC;
+#endif
+ }
+
+#if CHECK_MAGIC
+ ln[l->n_ln_pool-1].magic1 = MAGIC;
+#endif
+ ln[l->n_ln_pool-1].data = NULL;
+ ln[l->n_ln_pool-1].next = NULL;
+ ln[l->n_ln_pool-1].prev = &ln[l->n_ln_pool-2];
+#if CHECK_MAGIC
+ ln[l->n_ln_pool-1].magic2 = MAGIC;
+#endif
+
+ CKMAGIC(np);
+
+ CKLMAGIC(l);
+
+ return np;
+}
+
+
+
+/*------------------------------------------------------------
+| get_listnode
+|
+| Get the next available list node. If there are no more
+| list nodes, another pool of list nodes is allocated. If
+| that fails, NULL is returned.
+ ------------------------------------------------------------*/
+static
+LISTNODE *
+get_listnode ( LIST * l )
+{
+ LISTNODE * ln;
+ NODEPOOL * np;
+
+ CKLMAGIC(l);
+
+ if (l->next_ln == NULL) {
+ /*--------------------------------------------------
+ | allocate a new node pool and chain to the others
+ --------------------------------------------------*/
+ np = new_nodepool(l);
+ if (np == NULL) {
+ CKLMAGIC(l);
+ return NULL;
+ }
+
+ if (l->np_top == NULL) {
+ /*--------------------------------------------------
+ | this is the first node pool for this list,
+ | directly assign to the top and bottom.
+ --------------------------------------------------*/
+ l->np_top = np;
+ l->np_bottom = np;
+ np->chain_next = NULL;
+ np->chain_prev = NULL;
+ }
+ else {
+ /*--------------------------------------------------
+ | this is an additional node pool, add it to the
+ | chain.
+ --------------------------------------------------*/
+ np->chain_next = NULL;
+ np->chain_prev = l->np_bottom;
+ l->np_bottom->chain_next = np;
+ l->np_bottom = np;
+ }
+
+ /*--------------------------------------------------
+ | set the list's pointer to the next available
+ | list node to the first list node in this new
+ | pool.
+ --------------------------------------------------*/
+ l->next_ln = (LISTNODE *)&np[1];
+
+ CKMAGIC(np);
+ }
+
+ /*--------------------------------------------------
+ | get the next available list node, set the list's
+ | next available list node to the next one in the
+ | list.
+ --------------------------------------------------*/
+ ln = l->next_ln;
+ l->next_ln = ln->next;
+
+ CKMAGIC(ln);
+
+ /*--------------------------------------------------
+ | initialize the new list node and return
+ --------------------------------------------------*/
+ ln->next = NULL;
+ ln->prev = NULL;
+ ln->data = NULL;
+
+ CKLMAGIC(l);
+
+ return ln;
+}
+
+
+
+/*------------------------------------------------------------
+| free_listnode
+|
+| Return a list node to the pool of list nodes. This puts
+| the node at the head of the free list, so that the next
+| call to 'get_listnode', with return the most recently
+| freed one.
+ ------------------------------------------------------------*/
+static
+int
+free_listnode ( LIST * l, LISTNODE * ln )
+{
+ CKLMAGIC(l);
+
+ /*--------------------------------------------------
+ | insert the list node at the head of the list of
+ | free list nodes.
+ --------------------------------------------------*/
+ ln->prev = NULL;
+ ln->data = NULL;
+ ln->next = l->next_ln;
+ l->next_ln = ln;
+
+ CKLMAGIC(l);
+
+ return 0;
+}
+
+
+
+/*----------------------------------------------------------------------
+ lcreat
+
+ Create a new list data structure.
+
+ If liststruct is not NULL, it is used to provide the memory space
+ for the list structure instance, otherwise, the necessary memory is
+ malloc'd.
+
+ If elements is zero, the default poolsize is used, otherwise,
+ poolsizes of 'elements' elements are malloc'd to obtain the memory
+ for list nodes. Minimum element count is 5.
+
+ The first node pool is not preallocated; instead it is malloc'd at
+ the time of the first use.
+ ----------------------------------------------------------------------*/
+LISTID
+lcreat ( void * liststruct, int elements )
+{
+ LIST * l;
+
+ if (liststruct == NULL) {
+ /*--------------------------------------------------
+ allocate memory for the list itself
+ --------------------------------------------------*/
+ l = (LIST *) MALLOC ( sizeof(LIST), "list struct" );
+ if (l == NULL) {
+ return NULL;
+ }
+ l->free_on_close = 1;
+ }
+ else {
+ /*-----------------------------------------------------------------
+ use the memory given to us for the list structure
+ -----------------------------------------------------------------*/
+ l = liststruct;
+ l->free_on_close = 0;
+ }
+
+ /*--------------------------------------------------
+ | initialize the list
+ --------------------------------------------------*/
+#if CHECK_MAGIC
+ l->magic1 = MAGIC;
+ l->magic2 = MAGIC;
+#endif
+ l->top = NULL;
+ l->bottom = NULL;
+ l->num = 0;
+
+ if (elements == 0) {
+ l->poolsize = DEFAULT_POOLSIZE;
+ }
+ else {
+ l->poolsize = elements*sizeof(LISTNODE)+sizeof(NODEPOOL);
+ }
+
+ l->n_ln_pool = (l->poolsize-sizeof(NODEPOOL))/sizeof(LISTNODE);
+
+ if (l->n_ln_pool < 5) {
+ if (!liststruct) {
+ FREE(l);
+ }
+ return NULL;
+ }
+
+ l->np_top = NULL;
+ l->np_bottom = NULL;
+ l->next_ln = NULL;
+
+ CKLMAGIC(l);
+
+ return (LISTID)l;
+}
+
+
+/*--------------------------------------------------
+| ldestroy_cb
+|
+| destroy an existing list data structure, calling
+| the user routine 'ucleanup' on the data pointer
+| of each list element. Allows the user to free
+| up a list data structure and have this routine
+| call their function to free up each list element
+| at the same time.
+ --------------------------------------------------*/
+void
+ldestroy_cb ( LISTID lid, void (*ucleanup)(void * data_ptr) )
+{
+ LIST * l;
+ LISTNODE * ln;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ ln = l->top;
+ while (ln != NULL) {
+ ucleanup ( ln->data );
+ ln = ln->next;
+ }
+
+ ldestroy ( l );
+}
+
+
+
+/*--------------------------------------------------
+| ldestroy
+|
+| destroy an existing list data structure.
+|
+| assumes that each data element does not need to
+| be freed.
+ --------------------------------------------------*/
+void
+ldestroy ( LISTID lid )
+{
+ LIST * l;
+ NODEPOOL * p1, * p2;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ /*--------------------------------------------------
+ | free each node pool - start at the first node
+ | pool and free each successive until there are
+ | no more.
+ --------------------------------------------------*/
+ p1 = l->np_top;
+ while (p1 != NULL) {
+ p2 = p1->chain_next;
+ FREE(p1);
+ p1 = p2;
+ }
+
+ /*--------------------------------------------------
+ | now free the memory occupied by the list itself
+ --------------------------------------------------*/
+ if (l->free_on_close) {
+ FREE ( l );
+ }
+}
+
+
+
+
+/*------------------------------------------------------------
+| ladd
+|
+| add list - add item p to the list
+ ------------------------------------------------------------*/
+int
+ladd ( LISTID lid, void * p )
+{
+ LIST * l;
+ LISTNODE *lnptr;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ lnptr = get_listnode(l);
+ if (lnptr==NULL) {
+#ifdef BOS
+ breakpoint();
+#endif
+ return -1;
+ }
+
+ CKMAGIC(lnptr);
+
+ lnptr->data = p;
+
+ if (l->top == NULL) {
+ l->top = lnptr;
+ l->bottom = lnptr;
+ lnptr->next = NULL;
+ lnptr->prev = NULL;
+ }
+ else {
+ lnptr->prev = l->bottom;
+ lnptr->next = NULL;
+ l->bottom->next = lnptr;
+ l->bottom = lnptr;
+ }
+ l->num++;
+
+ CKLMAGIC(l);
+
+ return 0;
+}
+
+
+
+/*------------------------------------------------------------
+| laddo
+|
+| add list, ordered - add item p to the list, use 'compare'
+| function to place 'p' when the comparison 'p' is less than
+| the next item. Return 0 if this was a unique entry,
+| else return 1 indicating a duplicate entry, i.e., the
+| compare function returned 0 while inserting the element.
+ ------------------------------------------------------------*/
+int
+laddo ( LISTID lid, void * p, int (*compare)(const void *p1,const void *p2),
+ LNODEID * firstdup )
+{
+ LIST * l;
+ LISTNODE * ln;
+ int dup, cmp;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ dup = 0;
+ ln = l->top;
+
+ while (ln!=NULL) {
+ CKMAGIC(ln);
+ cmp = compare(p,ln->data);
+ if (cmp == 0) {
+ dup = 1;
+ if (firstdup)
+ *firstdup = ln;
+ }
+ if (cmp < 0) {
+ insert_ln(l,ln,p);
+ CKLMAGIC(l);
+ return dup;
+ }
+ else {
+ ln = ln->next;
+ }
+ }
+
+ ladd(l,p);
+
+ CKLMAGIC(l);
+
+ return dup;
+}
+
+
+/*---------------------------------------------------------------------------
+| laddu
+|
+| add list, ordered, unique - add item p to the list, use 'compare'
+| function to place 'p' when the comparison 'p' is less than the next
+| item. Return 1 if the item was added, 0 if not.
+|
+ --------------------------------------------------------------------------*/
+int
+laddu ( LISTID lid, void * p, int (*compare)(const void *p1,const void *p2) )
+{
+ LIST * l;
+ LISTNODE * ln;
+ int cmp;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ ln = l->top;
+
+ while (ln!=NULL) {
+ CKMAGIC(ln);
+ cmp = compare(p,ln->data);
+ if (cmp == 0) {
+ CKLMAGIC(l);
+ return 0;
+ }
+ if (cmp < 0) {
+ insert_ln(l,ln,p);
+ CKLMAGIC(l);
+ return 1;
+ }
+ else {
+ ln = ln->next;
+ }
+ }
+
+ ladd(l,p);
+
+ CKLMAGIC(l);
+
+ return 1;
+}
+
+
+
+
+LNODEID
+lfirst ( LISTID lid )
+{
+ CKLMAGIC(((LIST *)lid));
+ return ((LIST *)lid)->top;
+}
+
+
+LNODEID
+llast ( LISTID lid )
+{
+ CKLMAGIC(((LIST *)lid));
+ return ((LIST *)lid)->bottom;
+}
+
+
+LNODEID
+lnext ( LNODEID lnid )
+{
+ CKMAGIC(((LISTNODE *)lnid));
+ return ((LISTNODE *)lnid)->next;
+}
+
+
+LNODEID
+lprev ( LNODEID lnid )
+{
+ CKMAGIC(((LISTNODE *)lnid));
+ return ((LISTNODE *)lnid)->prev;
+}
+
+
+void *
+ldata ( LNODEID lnid )
+{
+ CKMAGIC(((LISTNODE *)lnid));
+ return ((LISTNODE *)lnid)->data;
+}
+
+
+
+int
+lsize ( LISTID lid )
+{
+ CKLMAGIC(((LIST *)lid));
+ return ((LIST *)lid)->num;
+}
+
+
+
+/*------------------------------------------------------------
+| lcat
+|
+| catenate - catenate l2 to l1, return pointer to l1.
+ ------------------------------------------------------------*/
+LISTID
+lcat ( LISTID lid1, LISTID lid2 )
+{
+ CKLMAGIC(((LIST *)lid1));
+ CKLMAGIC(((LIST *)lid2));
+ while (lsize(lid2)) {
+ ladd ( lid1, lrmv_n(lid2,1) );
+ }
+
+ CKLMAGIC(((LIST *)lid1));
+ CKLMAGIC(((LIST *)lid2));
+
+ return lid1;
+}
+
+
+
+/*----------------------------------------------------------------------
+| lget
+|
+| get from list, last item - return pointer to the data of the last
+| item in the list, non-destructive
+ ----------------------------------------------------------------------*/
+void *
+lget ( LISTID lid )
+{
+ LIST * l;
+ LISTNODE * p;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ p = l->bottom;
+
+ if (p == NULL) {
+ CKLMAGIC(l);
+ return NULL;
+ }
+ else {
+ CKLMAGIC(l);
+ return p->data;
+ }
+}
+
+
+
+/*---------------------------------------------------------------
+| lget_n
+|
+| get from list, index - return the nth list item,
+| non-destructive
+ ---------------------------------------------------------------*/
+void *
+lget_n ( LISTID lid, unsigned int n )
+{
+ int i;
+ LIST * l;
+ LISTNODE * ln;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ if ((n<1)||(n>lsize(l))) {
+ return NULL;
+ }
+
+ ln = l->top;
+ i = 1;
+ while (ln && (i!=n)) {
+ CKMAGIC(ln);
+ ln = ln->next;
+ i++;
+ }
+
+ if (ln) {
+ CKLMAGIC(l);
+ return ln->data;
+ }
+ else {
+ CKLMAGIC(l);
+ return NULL;
+ }
+}
+
+
+
+/*---------------------------------------------------------------
+| lget_ln
+|
+| get from list, listnode - return the nth list item, the
+| listnode is returned instead of the data, non-destructive
+ ---------------------------------------------------------------*/
+LNODEID
+lget_ln ( LISTID lid, unsigned int n )
+{
+ int i;
+ LIST * l;
+ LISTNODE * ln;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ if ((n<1)||(n>lsize(l))) {
+ return NULL;
+ }
+
+ ln = l->top;
+ i = 1;
+ while (i!=n) {
+ CKMAGIC(ln);
+ ln = ln->next;
+ i++;
+ }
+
+ CKLMAGIC(l);
+ return (LNODEID)ln;
+}
+
+
+
+/*----------------------------------------------------------------------
+| insert_ln
+|
+| insert data, listnode - insert data just before the list item
+| pointed to by 'ln'.
+|
+| This routine is not intended to be called directly by the user
+| because the validity of ln is not checked. This routine is called
+| by list manipulation routines within this module, in which ln is
+| known to point to a valid list node.
+ ----------------------------------------------------------------------*/
+static
+int
+insert_ln ( LIST * l, LISTNODE * ln, void * data_ptr )
+{
+ LISTNODE * lnptr;
+
+ CKLMAGIC(l);
+
+ if (ln==NULL) {
+ ladd ( l, data_ptr );
+ CKLMAGIC(l);
+ return 0;
+ }
+
+ lnptr = get_listnode(l);
+ if (lnptr == NULL) {
+#ifdef BOS
+ breakpoint();
+#endif
+ return -1;
+ }
+
+ CKMAGIC(lnptr);
+
+ lnptr->data = data_ptr;
+
+ if (ln==l->top) {
+ /*------------------------------
+ | insert before the list head
+ ------------------------------*/
+ lnptr->next = ln;
+ lnptr->prev = NULL;
+ ln->prev = lnptr;
+ l->top = lnptr;
+ }
+ else if (ln==NULL) {
+ /*-----------------
+ | list was empty
+ -----------------*/
+ lnptr->next = NULL;
+ lnptr->prev = l->bottom;
+ l->bottom->next = lnptr;
+ l->bottom = lnptr;
+ }
+ else {
+ /*-----------------------------------
+ | insert in the middle of the list
+ -----------------------------------*/
+ lnptr->next = ln;
+ lnptr->prev = ln->prev;
+ lnptr->next->prev = lnptr;
+ lnptr->prev->next = lnptr;
+ }
+
+ l->num++;
+
+ CKLMAGIC(l);
+
+ return 0;
+}
+
+
+
+/*-----------------------------------------------------------------
+| lins_n
+|
+| Insert data before the nth item in the list.
+ -----------------------------------------------------------------*/
+int
+lins_n ( LISTID lid, void * data_ptr, unsigned int n )
+{
+ int i;
+ LIST * l;
+ LISTNODE * ln;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ if ((n<1)||(n>(l->num+1))) {
+ return -1;
+ }
+
+ if (l->num == 0) {
+ return ladd ( lid, data_ptr );
+ }
+
+ /*----------------------------------
+ | locate the nth item in the list
+ ----------------------------------*/
+ ln = l->top;
+ i = 1;
+ while (ln && (i!=n)) {
+ CKMAGIC(ln);
+ ln = ln->next;
+ i++;
+ }
+
+ if (!ln) {
+ CKLMAGIC(l);
+ return -1;
+ }
+
+ CKLMAGIC(l);
+
+ /*-----------------------------------------
+ | insert before the nth item in the list
+ -----------------------------------------*/
+ return insert_ln ( l, ln, data_ptr );
+}
+
+
+/*-----------------------------------------------------------------
+| lins_ln
+|
+| Insert data before the list node pointed to by ln.
+ -----------------------------------------------------------------*/
+int
+lins_ln ( LISTID lid, LNODEID lnid, void * data_ptr )
+{
+ LIST * l;
+ LISTNODE * ln;
+ LISTNODE * ln_ptr;
+
+ l = (LIST *)lid;
+ ln = (LISTNODE *)lnid;
+
+ CKLMAGIC(l);
+
+ CKMAGIC(ln);
+
+ /*-----------------------------------------
+ | validate that ln is indeed in the list
+ -----------------------------------------*/
+ ln_ptr = l->top;
+ while ((ln_ptr!=NULL)&&(ln_ptr!=ln)) {
+ CKMAGIC(ln_ptr);
+ ln_ptr = ln_ptr->next;
+ }
+
+ if (ln_ptr == NULL) {
+ CKLMAGIC(l);
+ return -1;
+ }
+
+ CKLMAGIC(l);
+
+ /*--------------------------------
+ | insert the data into the list
+ --------------------------------*/
+ return insert_ln ( l, ln, data_ptr );
+}
+
+
+
+/*----------------------------------------------------------------------
+| remove_ln
+|
+| Remove the item in the list pointed to by ln. This routine is not
+| intended to be called directly by the user because the validity
+| of ln is not checked. This routine is called by list manipulation
+| routines within this module, in which ln is known to point to a
+| valid list node.
+ ----------------------------------------------------------------------*/
+static
+void *
+remove_ln ( LIST * l, LISTNODE * ln )
+{
+ void * r;
+
+ CKLMAGIC(l);
+
+ CKMAGIC(ln);
+
+ if (ln==l->top) {
+ /*------------------------------
+ | remove the head of the list
+ ------------------------------*/
+ l->top = ln->next;
+ if (l->top != NULL) {
+ l->top->prev = NULL;
+ }
+ else {
+ /*----------------------------------------
+ | this was the only item in the list
+ ----------------------------------------*/
+ l->bottom = NULL;
+ }
+ }
+ else if (ln==l->bottom) {
+ /*------------------------------
+ | remove the tail of the list
+ ------------------------------*/
+ l->bottom = ln->prev;
+ if (l->bottom != NULL) {
+ l->bottom->next = NULL;
+ }
+ }
+ else {
+ /*-------------------------------------
+ | remove from the middle of the list
+ -------------------------------------*/
+ ln->prev->next = ln->next;
+ ln->next->prev = ln->prev;
+ }
+
+ /*-----------------------------
+ | prepare to return the data
+ -----------------------------*/
+ r = ln->data;
+
+ /*-----------------------------------------------
+ | free the listnode for re-use
+ -----------------------------------------------*/
+ free_listnode(l,ln);
+
+ /*------------------------------------
+ | adjust the item count of the list
+ ------------------------------------*/
+ l->num--;
+
+ CKLMAGIC(l);
+
+ return r;
+}
+
+
+
+/*-------------------------------------------------------------------------
+| lrmv_d
+|
+| remove from list, data - removes the data element from the list,
+| destructive
+ -------------------------------------------------------------------------*/
+void *
+lrmv_d ( LISTID lid, void * data_ptr )
+{
+ LIST * l;
+ LISTNODE * ln;
+ int i;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ i = 0;
+ ln = l->top;
+ while (ln && (ln->data != data_ptr)) {
+ i++;
+ CKMAGIC(ln);
+ ln = ln->next;
+ }
+
+ if (ln == NULL) {
+ CKLMAGIC(l);
+ return NULL;
+ }
+ else {
+ CKLMAGIC(l);
+ return remove_ln ( l, ln );
+ }
+}
+
+
+
+/*-------------------------------------------------------------------------
+| lrmv_ln
+|
+| remove from list, by list node - remove the data element pointed to
+| by 'ln' from the list, destructive
+ -------------------------------------------------------------------------*/
+void *
+lrmv_ln ( LISTID lid, LNODEID lnid )
+{
+ LIST * l;
+ LISTNODE * ln;
+ LISTNODE * p;
+
+ l = (LIST *)lid;
+ ln = (LISTNODE *)lnid;
+
+ CKLMAGIC(l);
+
+ CKMAGIC(ln);
+
+ p = l->top;
+ while ((p!=NULL)&&(p!=ln)) {
+ CKMAGIC(p);
+ p = p->next;
+ }
+
+ if (p==NULL) {
+ CKLMAGIC(l);
+ return NULL;
+ }
+ else {
+ CKLMAGIC(l);
+ return remove_ln ( l, p );
+ }
+}
+
+
+
+/*----------------------------------------------------------------------
+| lrmv_n
+|
+| remove from list, by item number - remove the nth element from
+| the list.
+ ----------------------------------------------------------------------*/
+void *
+lrmv_n ( LISTID lid, unsigned int n )
+{
+ int i;
+ LIST * l;
+ LISTNODE * ln;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ if ((n<1)||(n>l->num)) {
+ return NULL;
+ }
+
+ ln = l->top;
+ i = 1;
+ while (ln && (i!=n)) {
+ CKMAGIC(ln);
+ ln = ln->next;
+ i++;
+ }
+
+ if (ln) {
+ CKLMAGIC(l);
+ return remove_ln ( l, ln );
+ }
+ else {
+ CKLMAGIC(l);
+ return NULL;
+ }
+}
+
+
+/*----------------------------------------------------------------------
+| lrmv
+|
+| remove from list, last item - remove the last item from the list,
+| destructive
+ ----------------------------------------------------------------------*/
+void *
+lrmv ( LISTID lid )
+{
+ LIST * l;
+ LISTNODE * p;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ p = l->bottom;
+
+ if (p == NULL) {
+ CKLMAGIC(l);
+ return NULL;
+ }
+ else {
+ CKLMAGIC(l);
+ return remove_ln ( l, p );
+ }
+}
+
+
+
+/*----------------------------------------------------------------------
+| lsrch
+|
+| search list - return data element pointed to by 'p', NULL if not
+| found
+ ----------------------------------------------------------------------*/
+void *
+lsrch ( LISTID lid, void * p, int (* compare)(void * p1, void * p2) )
+{
+ LIST * l;
+ LISTNODE * ln;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ ln = l->top;
+
+ while (ln!=NULL) {
+ CKMAGIC(ln);
+ if (compare(p,ln->data) == 0) {
+ CKLMAGIC(l);
+ return ln->data;
+ }
+ else {
+ ln = ln->next;
+ }
+ }
+
+ CKLMAGIC(l);
+ return NULL;
+}
+
+/*----------------------------------------------------------------------
+| lsort
+|
+| sort list - sorts list inplace (using bubble sort)
+|
+ ----------------------------------------------------------------------*/
+void
+lsort ( LISTID lid, int (* compare)(void * p1, void * p2) )
+{
+ LIST * l;
+ LISTNODE * lt; /* this */
+ LISTNODE * ln; /* next */
+ int unsorted = 1;
+
+ l = (LIST *)lid;
+
+ CKLMAGIC(l);
+
+ while(unsorted){
+ lt = l->top;
+ unsorted = 0;
+ while (lt!=NULL) {
+ CKMAGIC(lt);
+ ln = lt->next;
+ if (ln!= NULL && compare(lt->data,ln->data) > 0) {
+ void * p = ln->data;
+ ln->data = lt->data;
+ lt->data = p;
+ unsorted = 1;
+ }
+ lt = ln;
+ }
+ }
+
+ CKLMAGIC(l);
+}
+
+
+int lprint ( FILE * f, LISTID lid )
+{
+ LIST * l;
+ LISTNODE * ln;
+ NODEPOOL * np;
+ int count;
+
+ l = (LIST *)lid;
+
+ fprintf ( f, "list id %p internal data structures:\n",
+ lid );
+#if CHECK_MAGIC
+ if ((l->magic1 != MAGIC) || (l->magic2 != MAGIC)) {
+ fprintf ( f, " *** WARNING: LIST MAGIC IS CORRUPT ***\n" );
+ }
+ fprintf ( f,
+ " magic1=0x%08x\n"
+ " magic2=0x%08x\n",
+ l->magic1, l->magic2 );
+#endif
+ fprintf ( f, " num f pool n_ln top bottom next_ln np_top np_bottom\n" );
+ fprintf ( f, " ---- - ---- ---- ---------- ---------- ---------- ---------- ----------\n" );
+ fprintf ( f, " %4d %1d %4d %4d %10p %10p %10p %10p %10p\n",
+ l->num, l->free_on_close, l->poolsize, l->n_ln_pool,
+ l->top, l->bottom,
+ l->next_ln, l->np_top, l->np_bottom );
+
+
+ fprintf ( f,
+ " node pools:\n"
+ " idx np magic1 next prev magic2\n"
+ " ---- ---------- ---------- ---------- ---------- ----------\n" );
+ count = 0;
+ np = l->np_top;
+ while (np != NULL) {
+ count++;
+ fprintf ( f, " %4d %10p 0x%08x %10p %10p 0x%08x\n",
+ count, np,
+#if CHECK_MAGIC
+ np->magic1,
+#else
+ 0,
+#endif
+ np->chain_next, np->chain_prev,
+#if CHECK_MAGIC
+ np->magic2
+#else
+ 0
+#endif
+ );
+ np = np->chain_next;
+ }
+
+ if (f) {
+ fprintf ( f,
+ " list elements:\n"
+ " n ln magic1 next prev data magic2\n"
+ " ---- ---------- ---------- ---------- ---------- ---------- ----------\n" );
+ count = 0;
+ ln = l->top;
+ while (ln != NULL) {
+ count++;
+ fprintf ( f, " %4d %10p %10x %10p %10p %10p %10x\n",
+ count, ln,
+#if CHECK_MAGIC
+ ln->magic1,
+#else
+ 0,
+#endif
+ ln->next, ln->prev, ln->data,
+#if CHECK_MAGIC
+ ln->magic2
+#else
+ 0
+#endif
+ );
+ ln = lnext(ln);
+ }
+ if (count != l->num) {
+ fprintf ( f,
+ " *** list count is not correct\n"
+ " *** list id indicates %d, counted items = %d\n",
+ l->num, count );
+ }
+ }
+
+ return 0;
+}
diff --git a/xs/src/avrdude/main-standalone.c b/xs/src/avrdude/main-standalone.c
new file mode 100644
index 000000000..359a055ca
--- /dev/null
+++ b/xs/src/avrdude/main-standalone.c
@@ -0,0 +1,9 @@
+#include "avrdude.h"
+
+
+static const char* SYS_CONFIG = "/etc/avrdude-slic3r.conf";
+
+int main(int argc, char *argv[])
+{
+ return avrdude_main(argc, argv, SYS_CONFIG);
+}
diff --git a/xs/src/avrdude/main.c b/xs/src/avrdude/main.c
new file mode 100644
index 000000000..ebda0ba19
--- /dev/null
+++ b/xs/src/avrdude/main.c
@@ -0,0 +1,1537 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2005 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright 2007-2014 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+
+/*
+ * Code to program an Atmel AVR device through one of the supported
+ * programmers.
+ *
+ * For parallel port connected programmers, the pin definitions can be
+ * changed via a config file. See the config file for instructions on
+ * how to add a programmer definition.
+ *
+ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/types.h>
+
+#if !defined(WIN32NATIVE)
+# include <sys/time.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "term.h"
+
+
+/* Get VERSION from ac_cfg.h */
+char * version = VERSION "-prusa3d";
+
+char * progname;
+char progbuf[PATH_MAX]; /* temporary buffer of spaces the same
+ length as progname; used for lining up
+ multiline messages */
+
+#define MSGBUFFER_SIZE 4096
+char msgbuffer[MSGBUFFER_SIZE];
+
+bool cancel_flag = false;
+
+static void avrdude_message_handler_null(const char *msg, unsigned size, void *user_p)
+{
+ // Output to stderr by default
+ (void)size;
+ (void)user_p;
+ fputs(msg, stderr);
+}
+
+static void *avrdude_message_handler_user_p = NULL;
+static avrdude_message_handler_t avrdude_message_handler = avrdude_message_handler_null;
+
+void avrdude_message_handler_set(avrdude_message_handler_t newhandler, void *user_p)
+{
+ if (newhandler != NULL) {
+ avrdude_message_handler = newhandler;
+ avrdude_message_handler_user_p = user_p;
+ } else {
+ avrdude_message_handler = avrdude_message_handler_null;
+ avrdude_message_handler_user_p = NULL;
+ }
+}
+
+int avrdude_message(const int msglvl, const char *format, ...)
+{
+ static const char *format_error = "avrdude_message: Could not format message";
+
+ int rc = 0;
+ va_list ap;
+ if (verbose >= msglvl) {
+ va_start(ap, format);
+ rc = vsnprintf(msgbuffer, MSGBUFFER_SIZE, format, ap);
+
+ if (rc > 0 && rc < MSGBUFFER_SIZE) {
+ avrdude_message_handler(msgbuffer, rc, avrdude_message_handler_user_p);
+ } else {
+ rc = snprintf(msgbuffer, MSGBUFFER_SIZE, "%s: %s", format_error, format);
+ if (rc > 0 && rc < MSGBUFFER_SIZE) {
+ avrdude_message_handler(msgbuffer, rc, avrdude_message_handler_user_p);
+ } else {
+ avrdude_message_handler(format_error, strlen(format_error), avrdude_message_handler_user_p);
+ }
+ }
+
+ va_end(ap);
+ }
+ return rc;
+}
+
+
+static void avrdude_progress_handler_null(const char *task, unsigned progress, void *user_p)
+{
+ // By default do nothing
+ (void)task;
+ (void)progress;
+ (void)user_p;
+}
+
+static void *avrdude_progress_handler_user_p = NULL;
+static avrdude_progress_handler_t avrdude_progress_handler = avrdude_progress_handler_null;
+
+void avrdude_progress_handler_set(avrdude_progress_handler_t newhandler, void *user_p)
+{
+ if (newhandler != NULL) {
+ avrdude_progress_handler = newhandler;
+ avrdude_progress_handler_user_p = user_p;
+ } else {
+ avrdude_progress_handler = avrdude_progress_handler_null;
+ avrdude_progress_handler_user_p = NULL;
+ }
+}
+
+void avrdude_progress_external(const char *task, unsigned progress)
+{
+ avrdude_progress_handler(task, progress, avrdude_progress_handler_user_p);
+}
+
+static void avrdude_oom_handler_null(const char *context, void *user_p)
+{
+ // Output a message and just exit
+ fputs("avrdude: Out of memory: ", stderr);
+ fputs(context, stderr);
+ exit(99);
+}
+
+static void *avrdude_oom_handler_user_p = NULL;
+static avrdude_oom_handler_t avrdude_oom_handler = avrdude_oom_handler_null;
+
+void avrdude_oom_handler_set(avrdude_oom_handler_t newhandler, void *user_p)
+{
+ if (newhandler != NULL) {
+ avrdude_oom_handler = newhandler;
+ avrdude_oom_handler_user_p = user_p;
+ } else {
+ avrdude_oom_handler = avrdude_oom_handler_null;
+ avrdude_oom_handler_user_p = NULL;
+ }
+}
+
+void avrdude_oom(const char *context)
+{
+ avrdude_oom_handler(context, avrdude_oom_handler_user_p);
+}
+
+void avrdude_cancel()
+{
+ cancel_flag = true;
+}
+
+
+struct list_walk_cookie
+{
+ FILE *f;
+ const char *prefix;
+};
+
+static LISTID updates = NULL;
+
+static LISTID extended_params = NULL;
+
+static LISTID additional_config_files = NULL;
+
+static PROGRAMMER * pgm;
+static bool pgm_setup = false;
+
+/*
+ * global options
+ */
+int verbose; /* verbose output */
+int quell_progress; /* un-verebose output */
+int ovsigck; /* 1=override sig check, 0=don't */
+
+
+
+
+/*
+ * usage message
+ */
+static void usage(void)
+{
+ avrdude_message(MSG_INFO,
+ "Usage: %s [options]\n"
+ "Options:\n"
+ " -p <partno> Required. Specify AVR device.\n"
+ " -b <baudrate> Override RS-232 baud rate.\n"
+ " -B <bitclock> Specify JTAG/STK500v2 bit clock period (us).\n"
+ " -C <config-file> Specify location of configuration file.\n"
+ " -c <programmer> Specify programmer type.\n"
+ " -D Disable auto erase for flash memory\n"
+ " -i <delay> ISP Clock Delay [in microseconds]\n"
+ " -P <port> Specify connection port.\n"
+ " -F Override invalid signature check.\n"
+ " -e Perform a chip erase.\n"
+ " -O Perform RC oscillator calibration (see AVR053). \n"
+ " -U <memtype>:r|w|v:<section>:<filename>[:format]\n"
+ " Memory operation specification.\n"
+ " Multiple -U options are allowed, each request\n"
+ " is performed in the order specified.\n"
+ " -n Do not write anything to the device.\n"
+ " -V Do not verify.\n"
+ " -u Disable safemode, default when running from a script.\n"
+ " -s Silent safemode operation, will not ask you if\n"
+ " fuses should be changed back.\n"
+ " -t Enter terminal mode.\n"
+ " -E <exitspec>[,<exitspec>] List programmer exit specifications.\n"
+ " -x <extended_param> Pass <extended_param> to programmer.\n"
+ " -y Count # erase cycles in EEPROM.\n"
+ " -Y <number> Initialize erase cycle # in EEPROM.\n"
+ " -v Verbose output. -v -v for more.\n"
+ " -q Quell progress output. -q -q for less.\n"
+// " -l logfile Use logfile rather than stderr for diagnostics.\n"
+ " -? Display this usage.\n"
+ "\navrdude version %s, URL: <http://savannah.nongnu.org/projects/avrdude/>\n"
+ ,progname, version);
+}
+
+
+// static void update_progress_tty (int percent, double etime, char *hdr)
+// {
+// static char hashes[51];
+// static char *header;
+// static int last = 0;
+// int i;
+
+// setvbuf(stderr, (char*)NULL, _IONBF, 0);
+
+// hashes[50] = 0;
+
+// memset (hashes, ' ', 50);
+// for (i=0; i<percent; i+=2) {
+// hashes[i/2] = '#';
+// }
+
+// if (hdr) {
+// avrdude_message(MSG_INFO, "\n");
+// last = 0;
+// header = hdr;
+// }
+
+// if (last == 0) {
+// avrdude_message(MSG_INFO, "\r%s | %s | %d%% %0.2fs",
+// header, hashes, percent, etime);
+// }
+
+// if (percent == 100) {
+// if (!last) avrdude_message(MSG_INFO, "\n\n");
+// last = 1;
+// }
+
+// setvbuf(stderr, (char*)NULL, _IOLBF, 0);
+// }
+
+static void update_progress_no_tty (int percent, double etime, char *hdr)
+{
+ static int done = 0;
+ static int last = 0;
+ static char *header = NULL;
+ int cnt = (percent>>1)*2;
+
+ // setvbuf(stderr, (char*)NULL, _IONBF, 0);
+
+ if (hdr) {
+ avrdude_message(MSG_INFO, "\n%s | ", hdr);
+ last = 0;
+ done = 0;
+ header = hdr;
+ avrdude_progress_external(header, 0);
+ }
+ else {
+ while ((cnt > last) && (done == 0)) {
+ avrdude_message(MSG_INFO, "#");
+ cnt -= 2;
+ }
+
+ if (done == 0) {
+ avrdude_progress_external(header, percent > 99 ? 99 : percent);
+ }
+ }
+
+ if ((percent == 100) && (done == 0)) {
+ avrdude_message(MSG_INFO, " | 100%% %0.2fs\n\n", etime);
+ avrdude_progress_external(header, 100);
+ last = 0;
+ done = 1;
+ }
+ else
+ last = (percent>>1)*2; /* Make last a multiple of 2. */
+
+ // setvbuf(stderr, (char*)NULL, _IOLBF, 0);
+}
+
+static void list_programmers_callback(const char *name, const char *desc,
+ const char *cfgname, int cfglineno,
+ void *cookie)
+{
+ struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
+ if (verbose){
+ fprintf(c->f, "%s%-16s = %-30s [%s:%d]\n",
+ c->prefix, name, desc, cfgname, cfglineno);
+ } else {
+ fprintf(c->f, "%s%-16s = %-s\n",
+ c->prefix, name, desc);
+ }
+}
+
+static void list_programmers(FILE * f, const char *prefix, LISTID programmers)
+{
+ struct list_walk_cookie c;
+
+ c.f = f;
+ c.prefix = prefix;
+
+ sort_programmers(programmers);
+
+ walk_programmers(programmers, list_programmers_callback, &c);
+}
+
+static void list_programmer_types_callback(const char *name, const char *desc,
+ void *cookie)
+{
+ struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
+ fprintf(c->f, "%s%-16s = %-s\n",
+ c->prefix, name, desc);
+}
+
+static void list_programmer_types(FILE * f, const char *prefix)
+{
+ struct list_walk_cookie c;
+
+ c.f = f;
+ c.prefix = prefix;
+
+ walk_programmer_types(list_programmer_types_callback, &c);
+}
+
+static void list_avrparts_callback(const char *name, const char *desc,
+ const char *cfgname, int cfglineno,
+ void *cookie)
+{
+ struct list_walk_cookie *c = (struct list_walk_cookie *)cookie;
+
+ /* hide ids starting with '.' */
+ if ((verbose < 2) && (name[0] == '.'))
+ return;
+
+ if (verbose) {
+ fprintf(c->f, "%s%-8s = %-18s [%s:%d]\n",
+ c->prefix, name, desc, cfgname, cfglineno);
+ } else {
+ fprintf(c->f, "%s%-8s = %s\n",
+ c->prefix, name, desc);
+ }
+}
+
+static void list_parts(FILE * f, const char *prefix, LISTID avrparts)
+{
+ struct list_walk_cookie c;
+
+ c.f = f;
+ c.prefix = prefix;
+
+ sort_avrparts(avrparts);
+
+ walk_avrparts(avrparts, list_avrparts_callback, &c);
+}
+
+// static void exithook(void)
+// {
+// if (pgm->teardown)
+// pgm->teardown(pgm);
+// }
+
+static int cleanup_main(int status)
+{
+ if (pgm_setup && pgm != NULL && pgm->teardown) {
+ pgm->teardown(pgm);
+ }
+
+ if (updates) {
+ ldestroy_cb(updates, (void(*)(void*))free_update);
+ updates = NULL;
+ }
+ if (extended_params) {
+ ldestroy(extended_params);
+ extended_params = NULL;
+ }
+ if (additional_config_files) {
+ ldestroy(additional_config_files);
+ additional_config_files = NULL;
+ }
+
+ cleanup_config();
+
+ return status;
+}
+
+/*
+ * main routine
+ */
+int avrdude_main(int argc, char * argv [], const char *sys_config)
+{
+ int rc; /* general return code checking */
+ int exitrc; /* exit code for main() */
+ int i; /* general loop counter */
+ int ch; /* options flag */
+ int len; /* length for various strings */
+ struct avrpart * p; /* which avr part we are programming */
+ AVRMEM * sig; /* signature data */
+ struct stat sb;
+ UPDATE * upd;
+ LNODEID * ln;
+
+
+ /* options / operating mode variables */
+ int erase; /* 1=erase chip, 0=don't */
+ int calibrate; /* 1=calibrate RC oscillator, 0=don't */
+ char * port; /* device port (/dev/xxx) */
+ int terminal; /* 1=enter terminal mode, 0=don't */
+ int verify; /* perform a verify operation */
+ char * exitspecs; /* exit specs string from command line */
+ char * programmer; /* programmer id */
+ char * partdesc; /* part id */
+ // char sys_config[PATH_MAX]; /* system wide config file */
+ char usr_config[PATH_MAX]; /* per-user config file */
+ char * e; /* for strtol() error checking */
+ int baudrate; /* override default programmer baud rate */
+ double bitclock; /* Specify programmer bit clock (JTAG ICE) */
+ int ispdelay; /* Specify the delay for ISP clock */
+ int safemode; /* Enable safemode, 1=safemode on, 0=normal */
+ int silentsafe; /* Don't ask about fuses, 1=silent, 0=normal */
+ int init_ok; /* Device initialization worked well */
+ int is_open; /* Device open succeeded */
+ // char * logfile; /* Use logfile rather than stderr for diagnostics */
+ enum updateflags uflags = UF_AUTO_ERASE; /* Flags for do_op() */
+ unsigned char safemode_lfuse = 0xff;
+ unsigned char safemode_hfuse = 0xff;
+ unsigned char safemode_efuse = 0xff;
+ unsigned char safemode_fuse = 0xff;
+
+ char * safemode_response;
+ int fuses_specified = 0;
+ int fuses_updated = 0;
+// #if !defined(WIN32NATIVE)
+// char * homedir;
+// #endif
+
+ /*
+ * Set line buffering for file descriptors so we see stdout and stderr
+ * properly interleaved.
+ */
+ // setvbuf(stdout, (char*)NULL, _IOLBF, 0);
+ // setvbuf(stderr, (char*)NULL, _IOLBF, 0);
+
+ progname = strrchr(argv[0],'/');
+
+ cancel_flag = false;
+
+#if defined (WIN32NATIVE)
+ /* take care of backslash as dir sep in W32 */
+ if (!progname) progname = strrchr(argv[0],'\\');
+#endif /* WIN32NATIVE */
+
+ if (progname)
+ progname++;
+ else
+ progname = argv[0];
+
+ default_parallel[0] = 0;
+ default_serial[0] = 0;
+ default_bitclock = 0.0;
+ default_safemode = -1;
+
+ init_config();
+
+ // atexit(cleanup_main);
+
+ updates = lcreat(NULL, 0);
+ if (updates == NULL) {
+ avrdude_message(MSG_INFO, "%s: cannot initialize updater list\n", progname);
+ return cleanup_main(1);
+ }
+
+ extended_params = lcreat(NULL, 0);
+ if (extended_params == NULL) {
+ avrdude_message(MSG_INFO, "%s: cannot initialize extended parameter list\n", progname);
+ return cleanup_main(1);
+ }
+
+ additional_config_files = lcreat(NULL, 0);
+ if (additional_config_files == NULL) {
+ avrdude_message(MSG_INFO, "%s: cannot initialize additional config files list\n", progname);
+ return cleanup_main(1);
+ }
+
+ partdesc = NULL;
+ port = NULL;
+ erase = 0;
+ calibrate = 0;
+ p = NULL;
+ ovsigck = 0;
+ terminal = 0;
+ verify = 1; /* on by default */
+ quell_progress = 0;
+ exitspecs = NULL;
+ pgm = NULL;
+ programmer = default_programmer;
+ verbose = 0;
+ baudrate = 0;
+ bitclock = 0.0;
+ ispdelay = 0;
+ safemode = 1; /* Safemode on by default */
+ silentsafe = 0; /* Ask by default */
+ is_open = 0;
+ // logfile = NULL;
+
+// #if defined(WIN32NATIVE)
+
+// win_sys_config_set(sys_config);
+// win_usr_config_set(usr_config);
+
+// #else
+
+// strcpy(sys_config, CONFIG_DIR);
+// i = strlen(sys_config);
+// if (i && (sys_config[i-1] != '/'))
+// strcat(sys_config, "/");
+// strcat(sys_config, "avrdude.conf");
+
+ usr_config[0] = 0;
+// homedir = getenv("HOME");
+// if (homedir != NULL) {
+// strcpy(usr_config, homedir);
+// i = strlen(usr_config);
+// if (i && (usr_config[i-1] != '/'))
+// strcat(usr_config, "/");
+// strcat(usr_config, ".avrduderc");
+// }
+
+// #endif
+
+ len = strlen(progname) + 2;
+ for (i=0; i<len; i++)
+ progbuf[i] = ' ';
+ progbuf[i] = 0;
+
+ /*
+ * check for no arguments
+ */
+ if (argc == 1) {
+ usage();
+ return 0;
+ }
+
+
+ /*
+ * process command line arguments
+ */
+ optind = 1; // Reset getopt, makes it possible to use it multiple times
+ while ((ch = getopt(argc,argv,"?b:B:c:C:DeE:Fi:l:np:OP:qstU:uvVx:yY:")) != -1) {
+
+ switch (ch) {
+ case 'b': /* override default programmer baud rate */
+ baudrate = strtol(optarg, &e, 0);
+ if ((e == optarg) || (*e != 0)) {
+ avrdude_message(MSG_INFO, "%s: invalid baud rate specified '%s'\n",
+ progname, optarg);
+ return cleanup_main(1);
+ }
+ break;
+
+ case 'B': /* specify JTAG ICE bit clock period */
+ bitclock = strtod(optarg, &e);
+ if (*e != 0) {
+ /* trailing unit of measure present */
+ int suffixlen = strlen(e);
+ switch (suffixlen) {
+ case 2:
+ if ((e[0] != 'h' && e[0] != 'H') || e[1] != 'z')
+ bitclock = 0.0;
+ else
+ /* convert from Hz to microseconds */
+ bitclock = 1E6 / bitclock;
+ break;
+
+ case 3:
+ if ((e[1] != 'h' && e[1] != 'H') || e[2] != 'z')
+ bitclock = 0.0;
+ else {
+ switch (e[0]) {
+ case 'M':
+ case 'm': /* no Millihertz here :) */
+ bitclock = 1.0 / bitclock;
+ break;
+
+ case 'k':
+ bitclock = 1E3 / bitclock;
+ break;
+
+ default:
+ bitclock = 0.0;
+ break;
+ }
+ }
+ break;
+
+ default:
+ bitclock = 0.0;
+ break;
+ }
+ if (bitclock == 0.0)
+ avrdude_message(MSG_INFO, "%s: invalid bit clock unit of measure '%s'\n",
+ progname, e);
+ }
+ if ((e == optarg) || bitclock == 0.0) {
+ avrdude_message(MSG_INFO, "%s: invalid bit clock period specified '%s'\n",
+ progname, optarg);
+ return cleanup_main(1);
+ }
+ break;
+
+ case 'i': /* specify isp clock delay */
+ ispdelay = strtol(optarg, &e,10);
+ if ((e == optarg) || (*e != 0) || ispdelay == 0) {
+ avrdude_message(MSG_INFO, "%s: invalid isp clock delay specified '%s'\n",
+ progname, optarg);
+ return cleanup_main(1);
+ }
+ break;
+
+ case 'c': /* programmer id */
+ programmer = optarg;
+ break;
+
+ // case 'C': /* system wide configuration file */
+ // if (optarg[0] == '+') {
+ // ladd(additional_config_files, optarg+1);
+ // } else {
+ // strncpy(sys_config, optarg, PATH_MAX);
+ // sys_config[PATH_MAX-1] = 0;
+ // }
+ // break;
+
+ case 'D': /* disable auto erase */
+ uflags &= ~UF_AUTO_ERASE;
+ break;
+
+ case 'e': /* perform a chip erase */
+ erase = 1;
+ uflags &= ~UF_AUTO_ERASE;
+ break;
+
+ case 'E':
+ exitspecs = optarg;
+ break;
+
+ case 'F': /* override invalid signature check */
+ ovsigck = 1;
+ break;
+
+ // case 'l':
+ // logfile = optarg;
+ // break;
+
+ case 'n':
+ uflags |= UF_NOWRITE;
+ break;
+
+ case 'O': /* perform RC oscillator calibration */
+ calibrate = 1;
+ break;
+
+ case 'p' : /* specify AVR part */
+ partdesc = optarg;
+ break;
+
+ case 'P':
+ port = optarg;
+ break;
+
+ case 'q' : /* Quell progress output */
+ quell_progress++ ;
+ break;
+
+ case 's' : /* Silent safemode */
+ silentsafe = 1;
+ safemode = 1;
+ break;
+
+ case 't': /* enter terminal mode */
+ terminal = 1;
+ break;
+
+ case 'u' : /* Disable safemode */
+ safemode = 0;
+ break;
+
+ case 'U':
+ upd = parse_op(optarg);
+ if (upd == NULL) {
+ avrdude_message(MSG_INFO, "%s: error parsing update operation '%s'\n",
+ progname, optarg);
+ return cleanup_main(1);
+ }
+ ladd(updates, upd);
+
+ if (verify && upd->op == DEVICE_WRITE) {
+ upd = dup_update(upd);
+ upd->op = DEVICE_VERIFY;
+ ladd(updates, upd);
+ }
+ break;
+
+ case 'v':
+ verbose++;
+ break;
+
+ case 'V':
+ verify = 0;
+ break;
+
+ case 'x':
+ ladd(extended_params, optarg);
+ break;
+
+ case 'y':
+ avrdude_message(MSG_INFO, "%s: erase cycle counter no longer supported\n",
+ progname);
+ break;
+
+ case 'Y':
+ avrdude_message(MSG_INFO, "%s: erase cycle counter no longer supported\n",
+ progname);
+ break;
+
+ case '?': /* help */
+ usage();
+ return cleanup_main(0);
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "%s: invalid option -%c\n\n", progname, ch);
+ usage();
+ return cleanup_main(1);
+ break;
+ }
+
+ }
+
+ // if (logfile != NULL) {
+ // FILE *newstderr = freopen(logfile, "w", stderr);
+ // if (newstderr == NULL) {
+ // /* Help! There's no stderr to complain to anymore now. */
+ // printf("Cannot create logfile \"%s\": %s\n",
+ // logfile, strerror(errno));
+ // return 1;
+ // }
+ // }
+
+ if (quell_progress == 0) {
+ // if (isatty (STDERR_FILENO))
+ // update_progress = update_progress_tty;
+ // else {
+ // update_progress = update_progress_no_tty;
+ // /* disable all buffering of stderr for compatibility with
+ // software that captures and redirects output to a GUI
+ // i.e. Programmers Notepad */
+ // setvbuf( stderr, NULL, _IONBF, 0 );
+ // setvbuf( stdout, NULL, _IONBF, 0 );
+ // }
+ update_progress = update_progress_no_tty;
+ }
+
+ /*
+ * Print out an identifying string so folks can tell what version
+ * they are running
+ */
+ avrdude_message(MSG_NOTICE, "\n%s: Version %s, compiled on %s at %s\n"
+ "%sCopyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/\n"
+ "%sCopyright (c) 2007-2014 Joerg Wunsch\n\n",
+ progname, version, __DATE__, __TIME__, progbuf, progbuf);
+ avrdude_message(MSG_NOTICE, "%sSystem wide configuration file is \"%s\"\n",
+ progbuf, sys_config);
+
+ rc = read_config(sys_config);
+ if (rc) {
+ avrdude_message(MSG_INFO, "%s: error reading system wide configuration file \"%s\"\n",
+ progname, sys_config);
+ return cleanup_main(1);
+ }
+
+ if (usr_config[0] != 0) {
+ avrdude_message(MSG_NOTICE, "%sUser configuration file is \"%s\"\n",
+ progbuf, usr_config);
+
+ rc = stat(usr_config, &sb);
+ if ((rc < 0) || ((sb.st_mode & S_IFREG) == 0)) {
+ avrdude_message(MSG_NOTICE, "%sUser configuration file does not exist or is not a "
+ "regular file, skipping\n",
+ progbuf);
+ }
+ else {
+ rc = read_config(usr_config);
+ if (rc) {
+ avrdude_message(MSG_INFO, "%s: error reading user configuration file \"%s\"\n",
+ progname, usr_config);
+ return cleanup_main(1);
+ }
+ }
+ }
+
+ if (lsize(additional_config_files) > 0) {
+ LNODEID ln1;
+ const char * p = NULL;
+
+ for (ln1=lfirst(additional_config_files); ln1; ln1=lnext(ln1)) {
+ p = ldata(ln1);
+ avrdude_message(MSG_NOTICE, "%sAdditional configuration file is \"%s\"\n",
+ progbuf, p);
+
+ rc = read_config(p);
+ if (rc) {
+ avrdude_message(MSG_INFO, "%s: error reading additional configuration file \"%s\"\n",
+ progname, p);
+ return cleanup_main(1);
+ }
+ }
+ }
+
+ // set bitclock from configuration files unless changed by command line
+ if (default_bitclock > 0 && bitclock == 0.0) {
+ bitclock = default_bitclock;
+ }
+
+ avrdude_message(MSG_NOTICE, "\n");
+
+ if (partdesc) {
+ if (strcmp(partdesc, "?") == 0) {
+ avrdude_message(MSG_INFO, "\n");
+ avrdude_message(MSG_INFO, "Valid parts are:\n");
+ list_parts(stderr, " ", part_list);
+ avrdude_message(MSG_INFO, "\n");
+ return cleanup_main(1);
+ }
+ }
+
+ if (programmer) {
+ if (strcmp(programmer, "?") == 0) {
+ avrdude_message(MSG_INFO, "\n");
+ avrdude_message(MSG_INFO, "Valid programmers are:\n");
+ list_programmers(stderr, " ", programmers);
+ avrdude_message(MSG_INFO, "\n");
+ return cleanup_main(1);
+ }
+ if (strcmp(programmer, "?type") == 0) {
+ avrdude_message(MSG_INFO, "\n");
+ avrdude_message(MSG_INFO, "Valid programmer types are:\n");
+ list_programmer_types(stderr, " ");
+ avrdude_message(MSG_INFO, "\n");
+ return cleanup_main(1);
+ }
+ }
+
+
+ if (programmer[0] == 0) {
+ avrdude_message(MSG_INFO, "\n%s: no programmer has been specified on the command line "
+ "or the config file\n",
+ progname);
+ avrdude_message(MSG_INFO, "%sSpecify a programmer using the -c option and try again\n\n",
+ progbuf);
+ return cleanup_main(1);
+ }
+
+ pgm = locate_programmer(programmers, programmer);
+ if (pgm == NULL) {
+ avrdude_message(MSG_INFO, "\n");
+ avrdude_message(MSG_INFO, "%s: Can't find programmer id \"%s\"\n",
+ progname, programmer);
+ avrdude_message(MSG_INFO, "\nValid programmers are:\n");
+ list_programmers(stderr, " ", programmers);
+ avrdude_message(MSG_INFO, "\n");
+ return cleanup_main(1);
+ }
+
+ if (pgm->initpgm) {
+ pgm->initpgm(pgm);
+ } else {
+ avrdude_message(MSG_INFO, "\n%s: Can't initialize the programmer.\n\n",
+ progname);
+ return cleanup_main(1);
+ }
+
+ if (pgm->setup) {
+ pgm->setup(pgm);
+ }
+ pgm_setup = true; // Replaces the atexit hook
+ // if (pgm->teardown) {
+ // atexit(exithook);
+ // }
+
+ if (lsize(extended_params) > 0) {
+ if (pgm->parseextparams == NULL) {
+ avrdude_message(MSG_INFO, "%s: WARNING: Programmer doesn't support extended parameters,"
+ " -x option(s) ignored\n",
+ progname);
+ } else {
+ if (pgm->parseextparams(pgm, extended_params) < 0) {
+ avrdude_message(MSG_INFO, "%s: Error parsing extended parameter list\n",
+ progname);
+ return cleanup_main(1);
+ }
+ }
+ }
+
+ if (port == NULL) {
+ switch (pgm->conntype)
+ {
+ case CONNTYPE_PARALLEL:
+ port = default_parallel;
+ break;
+
+ case CONNTYPE_SERIAL:
+ port = default_serial;
+ break;
+
+ case CONNTYPE_USB:
+ port = DEFAULT_USB;
+ break;
+ }
+ }
+
+ if (partdesc == NULL) {
+ avrdude_message(MSG_INFO, "%s: No AVR part has been specified, use \"-p Part\"\n\n",
+ progname);
+ avrdude_message(MSG_INFO, "Valid parts are:\n");
+ list_parts(stderr, " ", part_list);
+ avrdude_message(MSG_INFO, "\n");
+ return cleanup_main(1);
+ }
+
+
+ p = locate_part(part_list, partdesc);
+ if (p == NULL) {
+ avrdude_message(MSG_INFO, "%s: AVR Part \"%s\" not found.\n\n",
+ progname, partdesc);
+ avrdude_message(MSG_INFO, "Valid parts are:\n");
+ list_parts(stderr, " ", part_list);
+ avrdude_message(MSG_INFO, "\n");
+ return cleanup_main(1);
+ }
+
+
+ if (exitspecs != NULL) {
+ if (pgm->parseexitspecs == NULL) {
+ avrdude_message(MSG_INFO, "%s: WARNING: -E option not supported by this programmer type\n",
+ progname);
+ exitspecs = NULL;
+ }
+ else if (pgm->parseexitspecs(pgm, exitspecs) < 0) {
+ usage();
+ return cleanup_main(1);
+ }
+ }
+
+ if (default_safemode == 0) {
+ /* configuration disables safemode: revert meaning of -u */
+ if (safemode == 0)
+ /* -u was given: enable safemode */
+ safemode = 1;
+ else
+ /* -u not given: turn off */
+ safemode = 0;
+ }
+
+ if (isatty(STDIN_FILENO) == 0 && silentsafe == 0)
+ safemode = 0; /* Turn off safemode if this isn't a terminal */
+
+
+ if(p->flags & AVRPART_AVR32) {
+ safemode = 0;
+ }
+
+ if(p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) {
+ safemode = 0;
+ }
+
+
+ if (avr_initmem(p) != 0)
+ {
+ avrdude_message(MSG_INFO, "\n%s: failed to initialize memories\n",
+ progname);
+ return cleanup_main(1);
+ }
+
+ /*
+ * Now that we know which part we are going to program, locate any
+ * -U options using the default memory region, and fill in the
+ * device-dependent default region name, either "application" (for
+ * Xmega devices), or "flash" (everything else).
+ */
+ for (ln=lfirst(updates); ln; ln=lnext(ln)) {
+ upd = ldata(ln);
+ if (upd->memtype == NULL) {
+ const char *mtype = (p->flags & AVRPART_HAS_PDI)? "application": "flash";
+ avrdude_message(MSG_NOTICE2, "%s: defaulting memtype in -U %c:%s option to \"%s\"\n",
+ progname,
+ (upd->op == DEVICE_READ)? 'r': (upd->op == DEVICE_WRITE)? 'w': 'v',
+ upd->filename, mtype);
+ if ((upd->memtype = strdup(mtype)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
+ return cleanup_main(1);
+ }
+ }
+ }
+
+ /*
+ * open the programmer
+ */
+ if (port[0] == 0) {
+ avrdude_message(MSG_INFO, "\n%s: no port has been specified on the command line "
+ "or the config file\n",
+ progname);
+ avrdude_message(MSG_INFO, "%sSpecify a port using the -P option and try again\n\n",
+ progbuf);
+ return cleanup_main(1);
+ }
+
+ if (verbose) {
+ avrdude_message(MSG_NOTICE, "%sUsing Port : %s\n", progbuf, port);
+ avrdude_message(MSG_NOTICE, "%sUsing Programmer : %s\n", progbuf, programmer);
+ if ((strcmp(pgm->type, "avr910") == 0)) {
+ avrdude_message(MSG_NOTICE, "%savr910_devcode (avrdude.conf) : ", progbuf);
+ if(p->avr910_devcode)avrdude_message(MSG_INFO, "0x%x\n", p->avr910_devcode);
+ else avrdude_message(MSG_NOTICE, "none\n");
+ }
+ }
+
+ if (baudrate != 0) {
+ avrdude_message(MSG_NOTICE, "%sOverriding Baud Rate : %d\n", progbuf, baudrate);
+ pgm->baudrate = baudrate;
+ }
+
+ if (bitclock != 0.0) {
+ avrdude_message(MSG_NOTICE, "%sSetting bit clk period : %.1f\n", progbuf, bitclock);
+ pgm->bitclock = bitclock * 1e-6;
+ }
+
+ if (ispdelay != 0) {
+ avrdude_message(MSG_NOTICE, "%sSetting isp clock delay : %3i\n", progbuf, ispdelay);
+ pgm->ispdelay = ispdelay;
+ }
+
+ rc = pgm->open(pgm, port);
+ if (rc < 0) {
+ exitrc = 1;
+ pgm->ppidata = 0; /* clear all bits at exit */
+ goto main_exit;
+ }
+ is_open = 1;
+
+ if (calibrate) {
+ /*
+ * perform an RC oscillator calibration
+ * as outlined in appnote AVR053
+ */
+ if (pgm->perform_osccal == 0) {
+ avrdude_message(MSG_INFO, "%s: programmer does not support RC oscillator calibration\n",
+ progname);
+ exitrc = 1;
+ } else {
+ avrdude_message(MSG_INFO, "%s: performing RC oscillator calibration\n", progname);
+ exitrc = pgm->perform_osccal(pgm);
+ }
+ if (exitrc == 0 && quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: calibration value is now stored in EEPROM at address 0\n",
+ progname);
+ }
+ goto main_exit;
+ }
+
+ if (verbose) {
+ avr_display(stderr, p, progbuf, verbose);
+ avrdude_message(MSG_NOTICE, "\n");
+ programmer_display(pgm, progbuf);
+ }
+
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "\n");
+ }
+
+ exitrc = 0;
+
+ /*
+ * enable the programmer
+ */
+ pgm->enable(pgm);
+
+ /*
+ * turn off all the status leds
+ */
+ pgm->rdy_led(pgm, OFF);
+ pgm->err_led(pgm, OFF);
+ pgm->pgm_led(pgm, OFF);
+ pgm->vfy_led(pgm, OFF);
+
+ /*
+ * initialize the chip in preperation for accepting commands
+ */
+ init_ok = (rc = pgm->initialize(pgm, p)) >= 0;
+ if (!init_ok) {
+ avrdude_message(MSG_INFO, "%s: initialization failed, rc=%d\n", progname, rc);
+ if (!ovsigck) {
+ avrdude_message(MSG_INFO, "%sDouble check connections and try again, "
+ "or use -F to override\n"
+ "%sthis check.\n\n",
+ progbuf, progbuf);
+ exitrc = 1;
+ goto main_exit;
+ }
+ }
+
+ /* indicate ready */
+ pgm->rdy_led(pgm, ON);
+
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: AVR device initialized and ready to accept instructions\n",
+ progname);
+ }
+
+ /*
+ * Let's read the signature bytes to make sure there is at least a
+ * chip on the other end that is responding correctly. A check
+ * against 0xffffff / 0x000000 should ensure that the signature bytes
+ * are valid.
+ */
+ if(!(p->flags & AVRPART_AVR32)) {
+ int attempt = 0;
+ int waittime = 10000; /* 10 ms */
+
+ sig_again:
+ usleep(waittime);
+ if (init_ok) {
+ rc = avr_signature(pgm, p);
+ if (rc != 0) {
+ avrdude_message(MSG_INFO, "%s: error reading signature data, rc=%d\n",
+ progname, rc);
+ exitrc = 1;
+ goto main_exit;
+ }
+ }
+
+ sig = avr_locate_mem(p, "signature");
+ if (sig == NULL) {
+ avrdude_message(MSG_INFO, "%s: WARNING: signature data not defined for device \"%s\"\n",
+ progname, p->desc);
+ }
+
+ if (sig != NULL) {
+ int ff, zz;
+
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: Device signature = 0x", progname);
+ }
+ ff = zz = 1;
+ for (i=0; i<sig->size; i++) {
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%02x", sig->buf[i]);
+ }
+ if (sig->buf[i] != 0xff)
+ ff = 0;
+ if (sig->buf[i] != 0x00)
+ zz = 0;
+ }
+ if (quell_progress < 2) {
+ AVRPART * part;
+
+ part = locate_part_by_signature(part_list, sig->buf, sig->size);
+ if (part) {
+ avrdude_message(MSG_INFO, " (probably %s)", part->id);
+ }
+ }
+ if (ff || zz) {
+ if (++attempt < 3) {
+ waittime *= 5;
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, " (retrying)\n");
+ }
+ goto sig_again;
+ }
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "\n");
+ }
+ avrdude_message(MSG_INFO, "%s: Yikes! Invalid device signature.\n", progname);
+ if (!ovsigck) {
+ avrdude_message(MSG_INFO, "%sDouble check connections and try again, "
+ "or use -F to override\n"
+ "%sthis check.\n\n",
+ progbuf, progbuf);
+ exitrc = 1;
+ goto main_exit;
+ }
+ } else {
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "\n");
+ }
+ }
+
+ if (sig->size != 3 ||
+ sig->buf[0] != p->signature[0] ||
+ sig->buf[1] != p->signature[1] ||
+ sig->buf[2] != p->signature[2]) {
+ avrdude_message(MSG_INFO, "%s: Expected signature for %s is %02X %02X %02X\n",
+ progname, p->desc,
+ p->signature[0], p->signature[1], p->signature[2]);
+ if (!ovsigck) {
+ avrdude_message(MSG_INFO, "%sDouble check chip, "
+ "or use -F to override this check.\n",
+ progbuf);
+ exitrc = 1;
+ goto main_exit;
+ }
+ }
+ }
+ }
+
+ if (init_ok && safemode == 1) {
+ /* If safemode is enabled, go ahead and read the current low, high,
+ and extended fuse bytes as needed */
+
+ rc = safemode_readfuses(&safemode_lfuse, &safemode_hfuse,
+ &safemode_efuse, &safemode_fuse, pgm, p);
+
+ if (rc != 0) {
+
+ //Check if the programmer just doesn't support reading
+ if (rc == -5)
+ {
+ avrdude_message(MSG_NOTICE, "%s: safemode: Fuse reading not support by programmer.\n"
+ " Safemode disabled.\n", progname);
+ }
+ else
+ {
+
+ avrdude_message(MSG_INFO, "%s: safemode: To protect your AVR the programming "
+ "will be aborted\n",
+ progname);
+ exitrc = 1;
+ goto main_exit;
+ }
+ } else {
+ //Save the fuses as default
+ safemode_memfuses(1, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
+ }
+ }
+
+ if (uflags & UF_AUTO_ERASE) {
+ if ((p->flags & AVRPART_HAS_PDI) && pgm->page_erase != NULL &&
+ lsize(updates) > 0) {
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: NOTE: Programmer supports page erase for Xmega devices.\n"
+ "%sEach page will be erased before programming it, but no chip erase is performed.\n"
+ "%sTo disable page erases, specify the -D option; for a chip-erase, use the -e option.\n",
+ progname, progbuf, progbuf);
+ }
+ } else {
+ AVRMEM * m;
+ const char *memname = (p->flags & AVRPART_HAS_PDI)? "application": "flash";
+
+ uflags &= ~UF_AUTO_ERASE;
+ for (ln=lfirst(updates); ln; ln=lnext(ln)) {
+ upd = ldata(ln);
+ m = avr_locate_mem(p, upd->memtype);
+ if (m == NULL)
+ continue;
+ if ((strcasecmp(m->desc, memname) == 0) && (upd->op == DEVICE_WRITE)) {
+ erase = 1;
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: NOTE: \"%s\" memory has been specified, an erase cycle "
+ "will be performed\n"
+ "%sTo disable this feature, specify the -D option.\n",
+ progname, memname, progbuf);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if (init_ok && erase) {
+ /*
+ * erase the chip's flash and eeprom memories, this is required
+ * before the chip can accept new programming
+ */
+ if (uflags & UF_NOWRITE) {
+ avrdude_message(MSG_INFO, "%s: conflicting -e and -n options specified, NOT erasing chip\n",
+ progname);
+ } else {
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: erasing chip\n", progname);
+ }
+ exitrc = avr_chip_erase(pgm, p);
+ if(exitrc) goto main_exit;
+ }
+ }
+
+ if (terminal) {
+ /*
+ * terminal mode
+ */
+ exitrc = terminal_mode(pgm, p);
+ }
+
+ if (!init_ok) {
+ /*
+ * If we came here by the -tF options, bail out now.
+ */
+ exitrc = 1;
+ goto main_exit;
+ }
+
+
+ for (ln=lfirst(updates); ln; ln=lnext(ln)) {
+ upd = ldata(ln);
+ rc = do_op(pgm, p, upd, uflags);
+ if (rc) {
+ exitrc = 1;
+ break;
+ }
+ }
+
+ /* Right before we exit programming mode, which will make the fuse
+ bits active, check to make sure they are still correct */
+ if (safemode == 1) {
+ /* If safemode is enabled, go ahead and read the current low,
+ * high, and extended fuse bytes as needed */
+ unsigned char safemodeafter_lfuse = 0xff;
+ unsigned char safemodeafter_hfuse = 0xff;
+ unsigned char safemodeafter_efuse = 0xff;
+ unsigned char safemodeafter_fuse = 0xff;
+ unsigned char failures = 0;
+ char yes[1] = {'y'};
+
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "\n");
+ }
+
+ //Restore the default fuse values
+ safemode_memfuses(0, &safemode_lfuse, &safemode_hfuse, &safemode_efuse, &safemode_fuse);
+
+ /* Try reading back fuses, make sure they are reliable to read back */
+ if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
+ &safemodeafter_efuse, &safemodeafter_fuse, pgm, p) != 0) {
+ /* Uh-oh.. try once more to read back fuses */
+ if (safemode_readfuses(&safemodeafter_lfuse, &safemodeafter_hfuse,
+ &safemodeafter_efuse, &safemodeafter_fuse, pgm, p) != 0) {
+ avrdude_message(MSG_INFO, "%s: safemode: Sorry, reading back fuses was unreliable. "
+ "I have given up and exited programming mode\n",
+ progname);
+ exitrc = 1;
+ goto main_exit;
+ }
+ }
+
+ /* Now check what fuses are against what they should be */
+ if (safemodeafter_fuse != safemode_fuse) {
+ fuses_updated = 1;
+ avrdude_message(MSG_INFO, "%s: safemode: fuse changed! Was %x, and is now %x\n",
+ progname, safemode_fuse, safemodeafter_fuse);
+
+
+ /* Ask user - should we change them */
+
+ if (silentsafe == 0)
+ safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
+ else
+ safemode_response = yes;
+
+ if (tolower((int)(safemode_response[0])) == 'y') {
+
+ /* Enough chit-chat, time to program some fuses and check them */
+ if (safemode_writefuse (safemode_fuse, "fuse", pgm, p,
+ 10) == 0) {
+ avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
+ }
+ else {
+ avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
+ failures++;
+ }
+ }
+ }
+
+ /* Now check what fuses are against what they should be */
+ if (safemodeafter_lfuse != safemode_lfuse) {
+ fuses_updated = 1;
+ avrdude_message(MSG_INFO, "%s: safemode: lfuse changed! Was %x, and is now %x\n",
+ progname, safemode_lfuse, safemodeafter_lfuse);
+
+
+ /* Ask user - should we change them */
+
+ if (silentsafe == 0)
+ safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
+ else
+ safemode_response = yes;
+
+ if (tolower((int)(safemode_response[0])) == 'y') {
+
+ /* Enough chit-chat, time to program some fuses and check them */
+ if (safemode_writefuse (safemode_lfuse, "lfuse", pgm, p,
+ 10) == 0) {
+ avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
+ }
+ else {
+ avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
+ failures++;
+ }
+ }
+ }
+
+ /* Now check what fuses are against what they should be */
+ if (safemodeafter_hfuse != safemode_hfuse) {
+ fuses_updated = 1;
+ avrdude_message(MSG_INFO, "%s: safemode: hfuse changed! Was %x, and is now %x\n",
+ progname, safemode_hfuse, safemodeafter_hfuse);
+
+ /* Ask user - should we change them */
+ if (silentsafe == 0)
+ safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
+ else
+ safemode_response = yes;
+ if (tolower((int)(safemode_response[0])) == 'y') {
+
+ /* Enough chit-chat, time to program some fuses and check them */
+ if (safemode_writefuse(safemode_hfuse, "hfuse", pgm, p,
+ 10) == 0) {
+ avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
+ }
+ else {
+ avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
+ failures++;
+ }
+ }
+ }
+
+ /* Now check what fuses are against what they should be */
+ if (safemodeafter_efuse != safemode_efuse) {
+ fuses_updated = 1;
+ avrdude_message(MSG_INFO, "%s: safemode: efuse changed! Was %x, and is now %x\n",
+ progname, safemode_efuse, safemodeafter_efuse);
+
+ /* Ask user - should we change them */
+ if (silentsafe == 0)
+ safemode_response = terminal_get_input("Would you like this fuse to be changed back? [y/n] ");
+ else
+ safemode_response = yes;
+ if (tolower((int)(safemode_response[0])) == 'y') {
+
+ /* Enough chit-chat, time to program some fuses and check them */
+ if (safemode_writefuse (safemode_efuse, "efuse", pgm, p,
+ 10) == 0) {
+ avrdude_message(MSG_INFO, "%s: safemode: and is now rescued\n", progname);
+ }
+ else {
+ avrdude_message(MSG_INFO, "%s: and COULD NOT be changed\n", progname);
+ failures++;
+ }
+ }
+ }
+
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: safemode: ", progname);
+ if (failures == 0) {
+ avrdude_message(MSG_INFO, "Fuses OK (E:%02X, H:%02X, L:%02X)\n",
+ safemode_efuse, safemode_hfuse, safemode_lfuse);
+ }
+ else {
+ avrdude_message(MSG_INFO, "Fuses not recovered, sorry\n");
+ }
+ }
+
+ if (fuses_updated && fuses_specified) {
+ exitrc = 1;
+ }
+
+ }
+
+
+main_exit:
+
+ /*
+ * program complete
+ */
+
+ if (is_open) {
+ pgm->powerdown(pgm);
+
+ pgm->disable(pgm);
+
+ pgm->rdy_led(pgm, OFF);
+
+ pgm->close(pgm);
+ }
+
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "\n%s done. Thank you.\n\n", progname);
+ }
+
+ return cleanup_main(exitrc);
+}
diff --git a/xs/src/avrdude/my_ddk_hidsdi.h b/xs/src/avrdude/my_ddk_hidsdi.h
new file mode 100644
index 000000000..46c17d675
--- /dev/null
+++ b/xs/src/avrdude/my_ddk_hidsdi.h
@@ -0,0 +1,48 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2006 Christian Starkjohann
+ *
+ * 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$ */
+
+/*
+The following is a replacement for hidsdi.h from the Windows DDK. It defines some
+of the types and function prototypes of this header for our project. If you
+have the Windows DDK version of this file or a version shipped with MinGW, use
+that instead.
+*/
+#ifndef MY_DDK_HIDSDI_H
+#define MY_DDK_HIDSDI_H
+#include <pshpack4.h>
+#include <ddk/hidusage.h>
+#include <ddk/hidpi.h>
+typedef struct{
+ ULONG Size;
+ USHORT VendorID;
+ USHORT ProductID;
+ USHORT VersionNumber;
+}HIDD_ATTRIBUTES;
+void __stdcall HidD_GetHidGuid(OUT LPGUID hidGuid);
+BOOLEAN __stdcall HidD_GetAttributes(IN HANDLE device, OUT HIDD_ATTRIBUTES *attributes);
+BOOLEAN __stdcall HidD_GetManufacturerString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
+BOOLEAN __stdcall HidD_GetProductString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
+BOOLEAN __stdcall HidD_GetSerialNumberString(IN HANDLE device, OUT void *buffer, IN ULONG bufferLen);
+BOOLEAN __stdcall HidD_GetFeature(IN HANDLE device, OUT void *reportBuffer, IN ULONG bufferLen);
+BOOLEAN __stdcall HidD_SetFeature(IN HANDLE device, IN void *reportBuffer, IN ULONG bufferLen);
+BOOLEAN __stdcall HidD_GetNumInputBuffers(IN HANDLE device, OUT ULONG *numBuffers);
+BOOLEAN __stdcall HidD_SetNumInputBuffers(IN HANDLE device, OUT ULONG numBuffers);
+#include <poppack.h>
+#endif /* MY_DDK_HIDSDI_H */
diff --git a/xs/src/avrdude/par.c b/xs/src/avrdude/par.c
new file mode 100644
index 000000000..9dcb8db84
--- /dev/null
+++ b/xs/src/avrdude/par.c
@@ -0,0 +1,411 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2006 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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$ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+# include "freebsd_ppi.h"
+#elif defined(__linux__)
+# include "linux_ppdev.h"
+#elif defined(__sun__) || defined(__sun) /* Solaris */
+# include "solaris_ecpp.h"
+#endif
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "ppi.h"
+#include "bitbang.h"
+#include "par.h"
+
+#if HAVE_PARPORT
+
+struct ppipins_t {
+ int pin;
+ int reg;
+ int bit;
+ int inverted;
+};
+
+static struct ppipins_t ppipins[] = {
+ { 1, PPICTRL, 0x01, 1 },
+ { 2, PPIDATA, 0x01, 0 },
+ { 3, PPIDATA, 0x02, 0 },
+ { 4, PPIDATA, 0x04, 0 },
+ { 5, PPIDATA, 0x08, 0 },
+ { 6, PPIDATA, 0x10, 0 },
+ { 7, PPIDATA, 0x20, 0 },
+ { 8, PPIDATA, 0x40, 0 },
+ { 9, PPIDATA, 0x80, 0 },
+ { 10, PPISTATUS, 0x40, 0 },
+ { 11, PPISTATUS, 0x80, 1 },
+ { 12, PPISTATUS, 0x20, 0 },
+ { 13, PPISTATUS, 0x10, 0 },
+ { 14, PPICTRL, 0x02, 1 },
+ { 15, PPISTATUS, 0x08, 0 },
+ { 16, PPICTRL, 0x04, 0 },
+ { 17, PPICTRL, 0x08, 1 }
+};
+
+#define NPINS (sizeof(ppipins)/sizeof(struct ppipins_t))
+
+static int par_setpin_internal(PROGRAMMER * pgm, int pin, int value)
+{
+ int inverted;
+
+ inverted = pin & PIN_INVERSE;
+ pin &= PIN_MASK;
+
+ if (pin < 1 || pin > 17)
+ return -1;
+
+ pin--;
+
+ if (ppipins[pin].inverted)
+ inverted = !inverted;
+
+ if (inverted)
+ value = !value;
+
+ if (value)
+ ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+ else
+ ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+
+ if (pgm->ispdelay > 1)
+ bitbang_delay(pgm->ispdelay);
+
+ return 0;
+}
+
+static int par_setpin(PROGRAMMER * pgm, int pinfunc, int value)
+{
+ return par_setpin_internal(pgm, pgm->pinno[pinfunc], value);
+}
+
+static void par_setmany(PROGRAMMER * pgm, int pinfunc, int value)
+{
+ int pin, mask;
+ int pinset = pgm->pinno[pinfunc];
+
+ /* mask is anything non-pin - needs to be applied to each par_setpin to preserve inversion */
+ mask = pinset & (~PIN_MASK);
+
+ for (pin = 1; pin <= 17; pin++) {
+ if (pinset & (1 << pin))
+ par_setpin_internal(pgm, pin | mask, value);
+ }
+}
+
+static int par_getpin(PROGRAMMER * pgm, int pinfunc)
+{
+ int value;
+ int inverted;
+ int pin = pgm->pinno[pinfunc];
+
+ inverted = pin & PIN_INVERSE;
+ pin &= PIN_MASK;
+
+ if (pin < 1 || pin > 17)
+ return -1;
+
+ pin--;
+
+ value = ppi_get(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+
+ if (value)
+ value = 1;
+
+ if (ppipins[pin].inverted)
+ inverted = !inverted;
+
+ if (inverted)
+ value = !value;
+
+ return value;
+}
+
+
+static int par_highpulsepin(PROGRAMMER * pgm, int pinfunc)
+{
+ int inverted;
+ int pin = pgm->pinno[pinfunc];
+
+ inverted = pin & PIN_INVERSE;
+ pin &= PIN_MASK;
+
+ if (pin < 1 || pin > 17)
+ return -1;
+
+ pin--;
+
+ if (ppipins[pin].inverted)
+ inverted = !inverted;
+
+ if (inverted) {
+ ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+ if (pgm->ispdelay > 1)
+ bitbang_delay(pgm->ispdelay);
+
+ ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+ if (pgm->ispdelay > 1)
+ bitbang_delay(pgm->ispdelay);
+ } else {
+ ppi_set(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+ if (pgm->ispdelay > 1)
+ bitbang_delay(pgm->ispdelay);
+
+ ppi_clr(&pgm->fd, ppipins[pin].reg, ppipins[pin].bit);
+ if (pgm->ispdelay > 1)
+ bitbang_delay(pgm->ispdelay);
+ }
+
+ return 0;
+}
+
+/*
+ * apply power to the AVR processor
+ */
+static void par_powerup(PROGRAMMER * pgm)
+{
+ par_setmany(pgm, PPI_AVR_VCC, 1); /* power up */
+ usleep(100000);
+}
+
+
+/*
+ * remove power from the AVR processor
+ */
+static void par_powerdown(PROGRAMMER * pgm)
+{
+ par_setmany(pgm, PPI_AVR_VCC, 0); /* power down */
+}
+
+static void par_disable(PROGRAMMER * pgm)
+{
+ par_setmany(pgm, PPI_AVR_BUFF, 1); /* turn off */
+}
+
+static void par_enable(PROGRAMMER * pgm)
+{
+ /*
+ * Prepare to start talking to the connected device - pull reset low
+ * first, delay a few milliseconds, then enable the buffer. 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.
+ */
+
+ par_setpin(pgm, PIN_AVR_RESET, 0);
+ usleep(1);
+
+ /*
+ * enable the 74367 buffer, if connected; this signal is active low
+ */
+ par_setmany(pgm, PPI_AVR_BUFF, 0);
+}
+
+static int par_open(PROGRAMMER * pgm, char * port)
+{
+ int rc;
+
+ if (bitbang_check_prerequisites(pgm) < 0)
+ return -1;
+
+ ppi_open(port, &pgm->fd);
+ if (pgm->fd.ifd < 0) {
+ avrdude_message(MSG_INFO, "%s: failed to open parallel port \"%s\"\n\n",
+ progname, port);
+ return -1;
+ }
+
+ /*
+ * save pin values, so they can be restored when device is closed
+ */
+ rc = ppi_getall(&pgm->fd, PPIDATA);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: error reading status of ppi data port\n", progname);
+ return -1;
+ }
+ pgm->ppidata = rc;
+
+ rc = ppi_getall(&pgm->fd, PPICTRL);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: error reading status of ppi ctrl port\n", progname);
+ return -1;
+ }
+ pgm->ppictrl = rc;
+
+ return 0;
+}
+
+
+static void par_close(PROGRAMMER * pgm)
+{
+
+ /*
+ * Restore pin values before closing,
+ * but ensure that buffers are turned off.
+ */
+ ppi_setall(&pgm->fd, PPIDATA, pgm->ppidata);
+ ppi_setall(&pgm->fd, PPICTRL, pgm->ppictrl);
+
+ par_setmany(pgm, PPI_AVR_BUFF, 1);
+
+ /*
+ * Handle exit specs.
+ */
+ switch (pgm->exit_reset) {
+ case EXIT_RESET_ENABLED:
+ par_setpin(pgm, PIN_AVR_RESET, 0);
+ break;
+
+ case EXIT_RESET_DISABLED:
+ par_setpin(pgm, PIN_AVR_RESET, 1);
+ break;
+
+ case EXIT_RESET_UNSPEC:
+ /* Leave it alone. */
+ break;
+ }
+
+ switch (pgm->exit_datahigh) {
+ case EXIT_DATAHIGH_ENABLED:
+ ppi_setall(&pgm->fd, PPIDATA, 0xff);
+ break;
+
+ case EXIT_DATAHIGH_DISABLED:
+ ppi_setall(&pgm->fd, PPIDATA, 0x00);
+ break;
+
+ case EXIT_DATAHIGH_UNSPEC:
+ /* Leave it alone. */
+ break;
+ }
+
+ switch (pgm->exit_vcc) {
+ case EXIT_VCC_ENABLED:
+ par_setmany(pgm, PPI_AVR_VCC, 1);
+ break;
+
+ case EXIT_VCC_DISABLED:
+ par_setmany(pgm, PPI_AVR_VCC, 0);
+ break;
+
+ case EXIT_VCC_UNSPEC:
+ /* Leave it alone. */
+ break;
+ }
+
+ ppi_close(&pgm->fd);
+ pgm->fd.ifd = -1;
+}
+
+/*
+ * parse the -E string
+ */
+static int par_parseexitspecs(PROGRAMMER * pgm, char *s)
+{
+ char *cp;
+
+ while ((cp = strtok(s, ","))) {
+ if (strcmp(cp, "reset") == 0) {
+ pgm->exit_reset = EXIT_RESET_ENABLED;
+ }
+ else if (strcmp(cp, "noreset") == 0) {
+ pgm->exit_reset = EXIT_RESET_DISABLED;
+ }
+ else if (strcmp(cp, "vcc") == 0) {
+ pgm->exit_vcc = EXIT_VCC_ENABLED;
+ }
+ else if (strcmp(cp, "novcc") == 0) {
+ pgm->exit_vcc = EXIT_VCC_DISABLED;
+ }
+ else if (strcmp(cp, "d_high") == 0) {
+ pgm->exit_datahigh = EXIT_DATAHIGH_ENABLED;
+ }
+ else if (strcmp(cp, "d_low") == 0) {
+ pgm->exit_datahigh = EXIT_DATAHIGH_DISABLED;
+ }
+ else {
+ return -1;
+ }
+ s = 0; /* strtok() should be called with the actual string only once */
+ }
+
+ return 0;
+}
+
+void par_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "PPI");
+
+ pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
+
+ pgm->exit_vcc = EXIT_VCC_UNSPEC;
+ pgm->exit_reset = EXIT_RESET_UNSPEC;
+ pgm->exit_datahigh = EXIT_DATAHIGH_UNSPEC;
+
+ pgm->rdy_led = bitbang_rdy_led;
+ pgm->err_led = bitbang_err_led;
+ pgm->pgm_led = bitbang_pgm_led;
+ pgm->vfy_led = bitbang_vfy_led;
+ pgm->initialize = bitbang_initialize;
+ pgm->display = pgm_display_generic;
+ pgm->enable = par_enable;
+ pgm->disable = par_disable;
+ pgm->powerup = par_powerup;
+ pgm->powerdown = par_powerdown;
+ pgm->program_enable = bitbang_program_enable;
+ pgm->chip_erase = bitbang_chip_erase;
+ pgm->cmd = bitbang_cmd;
+ pgm->cmd_tpi = bitbang_cmd_tpi;
+ pgm->spi = bitbang_spi;
+ pgm->open = par_open;
+ pgm->close = par_close;
+ pgm->setpin = par_setpin;
+ pgm->getpin = par_getpin;
+ pgm->highpulsepin = par_highpulsepin;
+ pgm->parseexitspecs = par_parseexitspecs;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+}
+
+#else /* !HAVE_PARPORT */
+
+void par_initpgm(PROGRAMMER * pgm)
+{
+ avrdude_message(MSG_INFO, "%s: parallel port access not available in this configuration\n",
+ progname);
+}
+
+#endif /* HAVE_PARPORT */
+
+const char par_desc[] = "Parallel port bitbanging";
diff --git a/xs/src/avrdude/par.h b/xs/src/avrdude/par.h
new file mode 100644
index 000000000..708997037
--- /dev/null
+++ b/xs/src/avrdude/par.h
@@ -0,0 +1,35 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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 par_h
+#define par_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char par_desc[];
+void par_initpgm (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/xs/src/avrdude/pgm.c b/xs/src/avrdude/pgm.c
new file mode 100644
index 000000000..b8a93f104
--- /dev/null
+++ b/xs/src/avrdude/pgm.c
@@ -0,0 +1,333 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+static int pgm_default_2 (struct programmer_t *, AVRPART *);
+static int pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value);
+static void pgm_default_4 (struct programmer_t *);
+static int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data);
+static void pgm_default_6 (struct programmer_t *, const char *);
+
+
+static int pgm_default_open (struct programmer_t *pgm, char * name)
+{
+ avrdude_message(MSG_INFO, "\n%s: Fatal error: Programmer does not support open()",
+ progname);
+ return -1;
+}
+
+static int pgm_default_led (struct programmer_t * pgm, int value)
+{
+ /*
+ * If programmer has no LEDs, just do nothing.
+ */
+ return 0;
+}
+
+
+static void pgm_default_powerup_powerdown (struct programmer_t * pgm)
+{
+ /*
+ * If programmer does not support powerup/down, just do nothing.
+ */
+}
+
+
+PROGRAMMER * pgm_new(void)
+{
+ int i;
+ PROGRAMMER * pgm;
+
+ pgm = (PROGRAMMER *)malloc(sizeof(*pgm));
+ if (pgm == NULL) {
+ avrdude_message(MSG_INFO, "%s: out of memory allocating programmer structure\n",
+ progname);
+ return NULL;
+ }
+
+ memset(pgm, 0, sizeof(*pgm));
+
+ pgm->id = lcreat(NULL, 0);
+ pgm->usbpid = lcreat(NULL, 0);
+ pgm->desc[0] = 0;
+ pgm->type[0] = 0;
+ pgm->config_file[0] = 0;
+ pgm->lineno = 0;
+ pgm->baudrate = 0;
+ pgm->initpgm = NULL;
+
+ for (i=0; i<N_PINS; i++) {
+ pgm->pinno[i] = 0;
+ pin_clear_all(&(pgm->pin[i]));
+ }
+
+ /*
+ * mandatory functions - these are called without checking to see
+ * whether they are assigned or not
+ */
+ pgm->initialize = pgm_default_2;
+ pgm->display = pgm_default_6;
+ pgm->enable = pgm_default_4;
+ pgm->disable = pgm_default_4;
+ pgm->powerup = pgm_default_powerup_powerdown;
+ pgm->powerdown = pgm_default_powerup_powerdown;
+ pgm->program_enable = pgm_default_2;
+ pgm->chip_erase = pgm_default_2;
+ pgm->open = pgm_default_open;
+ pgm->close = pgm_default_4;
+ pgm->read_byte = pgm_default_3;
+ pgm->write_byte = pgm_default_5;
+
+ /*
+ * predefined functions - these functions have a valid default
+ * implementation. Hence, they don't need to be defined in
+ * the programmer.
+ */
+ pgm->rdy_led = pgm_default_led;
+ pgm->err_led = pgm_default_led;
+ pgm->pgm_led = pgm_default_led;
+ pgm->vfy_led = pgm_default_led;
+
+ /*
+ * optional functions - these are checked to make sure they are
+ * assigned before they are called
+ */
+ pgm->cmd = NULL;
+ pgm->cmd_tpi = NULL;
+ pgm->spi = NULL;
+ pgm->paged_write = NULL;
+ pgm->paged_load = NULL;
+ pgm->write_setup = NULL;
+ pgm->read_sig_bytes = NULL;
+ pgm->set_vtarget = NULL;
+ pgm->set_varef = NULL;
+ pgm->set_fosc = NULL;
+ pgm->perform_osccal = NULL;
+ pgm->parseextparams = NULL;
+ pgm->setup = NULL;
+ pgm->teardown = NULL;
+
+ return pgm;
+}
+
+void pgm_free(PROGRAMMER * const p)
+{
+ ldestroy_cb(p->id, free);
+ ldestroy_cb(p->usbpid, free);
+ p->id = NULL;
+ p->usbpid = NULL;
+ /* this is done by pgm_teardown, but usually cookie is not set to NULL */
+ /* if (p->cookie !=NULL) {
+ free(p->cookie);
+ p->cookie = NULL;
+ }*/
+ free(p);
+}
+
+PROGRAMMER * pgm_dup(const PROGRAMMER * const src)
+{
+ PROGRAMMER * pgm;
+ LNODEID ln;
+
+ pgm = (PROGRAMMER *)malloc(sizeof(*pgm));
+ if (pgm == NULL) {
+ avrdude_message(MSG_INFO, "%s: out of memory allocating programmer structure\n",
+ progname);
+ return NULL;
+ }
+
+ memcpy(pgm, src, sizeof(*pgm));
+
+ pgm->id = lcreat(NULL, 0);
+ pgm->usbpid = lcreat(NULL, 0);
+
+ for (ln = lfirst(src->usbpid); ln; ln = lnext(ln)) {
+ int *ip = malloc(sizeof(int));
+ if (ip == NULL) {
+ // avrdude_message(MSG_INFO, "%s: out of memory allocating programmer structure\n",
+ // progname);
+ // exit(1);
+ avrdude_oom("out of memory allocating programmer structure\n");
+ }
+ *ip = *(int *) ldata(ln);
+ ladd(pgm->usbpid, ip);
+ }
+
+ return pgm;
+}
+
+
+static void pgm_default(void)
+{
+ avrdude_message(MSG_INFO, "%s: programmer operation not supported\n", progname);
+}
+
+
+static int pgm_default_2 (struct programmer_t * pgm, AVRPART * p)
+{
+ pgm_default();
+ return -1;
+}
+
+static int pgm_default_3 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value)
+{
+ pgm_default();
+ return -1;
+}
+
+static void pgm_default_4 (struct programmer_t * pgm)
+{
+ pgm_default();
+}
+
+static int pgm_default_5 (struct programmer_t * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data)
+{
+ pgm_default();
+ return -1;
+}
+
+static void pgm_default_6 (struct programmer_t * pgm, const char * p)
+{
+ pgm_default();
+}
+
+
+void programmer_display(PROGRAMMER * pgm, const char * p)
+{
+ avrdude_message(MSG_INFO, "%sProgrammer Type : %s\n", p, pgm->type);
+ avrdude_message(MSG_INFO, "%sDescription : %s\n", p, pgm->desc);
+
+ pgm->display(pgm, p);
+}
+
+
+void pgm_display_generic_mask(PROGRAMMER * pgm, const char * p, unsigned int show)
+{
+ if(show & (1<<PPI_AVR_VCC))
+ avrdude_message(MSG_INFO, "%s VCC = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_VCC]));
+ if(show & (1<<PPI_AVR_BUFF))
+ avrdude_message(MSG_INFO, "%s BUFF = %s\n", p, pins_to_str(&pgm->pin[PPI_AVR_BUFF]));
+ if(show & (1<<PIN_AVR_RESET))
+ avrdude_message(MSG_INFO, "%s RESET = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_RESET]));
+ if(show & (1<<PIN_AVR_SCK))
+ avrdude_message(MSG_INFO, "%s SCK = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_SCK]));
+ if(show & (1<<PIN_AVR_MOSI))
+ avrdude_message(MSG_INFO, "%s MOSI = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_MOSI]));
+ if(show & (1<<PIN_AVR_MISO))
+ avrdude_message(MSG_INFO, "%s MISO = %s\n", p, pins_to_str(&pgm->pin[PIN_AVR_MISO]));
+ if(show & (1<<PIN_LED_ERR))
+ avrdude_message(MSG_INFO, "%s ERR LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_ERR]));
+ if(show & (1<<PIN_LED_RDY))
+ avrdude_message(MSG_INFO, "%s RDY LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_RDY]));
+ if(show & (1<<PIN_LED_PGM))
+ avrdude_message(MSG_INFO, "%s PGM LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_PGM]));
+ if(show & (1<<PIN_LED_VFY))
+ avrdude_message(MSG_INFO, "%s VFY LED = %s\n", p, pins_to_str(&pgm->pin[PIN_LED_VFY]));
+}
+
+void pgm_display_generic(PROGRAMMER * pgm, const char * p)
+{
+ pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS);
+}
+
+PROGRAMMER * locate_programmer(LISTID programmers, const char * configid)
+{
+ LNODEID ln1, ln2;
+ PROGRAMMER * p = NULL;
+ const char * id;
+ int found;
+
+ found = 0;
+
+ for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) {
+ p = ldata(ln1);
+ for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) {
+ id = ldata(ln2);
+ if (strcasecmp(configid, id) == 0)
+ found = 1;
+ }
+ }
+
+ if (found)
+ return p;
+
+ return NULL;
+}
+
+/*
+ * Iterate over the list of programmers given as "programmers", and
+ * call the callback function cb for each entry found. cb is being
+ * passed the following arguments:
+ * . the name of the programmer (for -c)
+ * . the descriptive text given in the config file
+ * . the name of the config file this programmer has been defined in
+ * . the line number of the config file this programmer has been defined at
+ * . the "cookie" passed into walk_programmers() (opaque client data)
+ */
+void walk_programmers(LISTID programmers, walk_programmers_cb cb, void *cookie)
+{
+ LNODEID ln1;
+ LNODEID ln2;
+ PROGRAMMER * p;
+
+ for (ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
+ p = ldata(ln1);
+ for (ln2=lfirst(p->id); ln2; ln2=lnext(ln2)) {
+ cb(ldata(ln2), p->desc, p->config_file, p->lineno, cookie);
+ }
+ }
+}
+
+/*
+ * Compare function to sort the list of programmers
+ */
+static int sort_programmer_compare(PROGRAMMER * p1,PROGRAMMER * p2)
+{
+ char* id1;
+ char* id2;
+ if(p1 == NULL || p2 == NULL) {
+ return 0;
+ }
+ id1 = ldata(lfirst(p1->id));
+ id2 = ldata(lfirst(p2->id));
+ return strncasecmp(id1,id2,AVR_IDLEN);
+}
+
+/*
+ * Sort the list of programmers given as "programmers"
+ */
+void sort_programmers(LISTID programmers)
+{
+ lsort(programmers,(int (*)(void*, void*)) sort_programmer_compare);
+}
+
diff --git a/xs/src/avrdude/pgm_type.c b/xs/src/avrdude/pgm_type.c
new file mode 100644
index 000000000..ef27cf900
--- /dev/null
+++ b/xs/src/avrdude/pgm_type.c
@@ -0,0 +1,153 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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: pgm.c 976 2011-08-23 21:03:36Z joerg_wunsch $ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "arduino.h"
+#include "avr910.h"
+// #include "avrftdi.h"
+#include "buspirate.h"
+#include "butterfly.h"
+// #include "flip1.h"
+// #include "flip2.h"
+// #include "ft245r.h"
+// #include "jtagmkI.h"
+// #include "jtagmkII.h"
+// #include "jtag3.h"
+#include "linuxgpio.h"
+// #include "par.h"
+#include "pickit2.h"
+#include "ppi.h"
+#include "serbb.h"
+#include "stk500.h"
+#include "stk500generic.h"
+#include "stk500v2.h"
+// #include "usbasp.h"
+// #include "usbtiny.h"
+#include "wiring.h"
+
+
+const PROGRAMMER_TYPE programmers_types[] = {
+ {"arduino", arduino_initpgm, arduino_desc},
+ {"avr910", avr910_initpgm, avr910_desc},
+ // {"avrftdi", avrftdi_initpgm, avrftdi_desc},
+ {"buspirate", buspirate_initpgm, buspirate_desc},
+ {"buspirate_bb", buspirate_bb_initpgm, buspirate_bb_desc},
+ {"butterfly", butterfly_initpgm, butterfly_desc},
+ {"butterfly_mk", butterfly_mk_initpgm, butterfly_mk_desc},
+ // {"dragon_dw", jtagmkII_dragon_dw_initpgm, jtagmkII_dragon_dw_desc},
+ {"dragon_hvsp", stk500v2_dragon_hvsp_initpgm, stk500v2_dragon_hvsp_desc},
+ {"dragon_isp", stk500v2_dragon_isp_initpgm, stk500v2_dragon_isp_desc},
+ // {"dragon_jtag", jtagmkII_dragon_initpgm, jtagmkII_dragon_desc},
+ // {"dragon_pdi", jtagmkII_dragon_pdi_initpgm, jtagmkII_dragon_pdi_desc},
+ {"dragon_pp", stk500v2_dragon_pp_initpgm, stk500v2_dragon_pp_desc},
+ // {"flip1", flip1_initpgm, flip1_desc},
+ // {"flip2", flip2_initpgm, flip2_desc},
+ // {"ftdi_syncbb", ft245r_initpgm, ft245r_desc},
+ // {"jtagmki", jtagmkI_initpgm, jtagmkI_desc},
+ // {"jtagmkii", jtagmkII_initpgm, jtagmkII_desc},
+ // {"jtagmkii_avr32", jtagmkII_avr32_initpgm, jtagmkII_avr32_desc},
+ // {"jtagmkii_dw", jtagmkII_dw_initpgm, jtagmkII_dw_desc},
+ // {"jtagmkii_isp", stk500v2_jtagmkII_initpgm, stk500v2_jtagmkII_desc},
+ // {"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc},
+ // {"jtagice3", jtag3_initpgm, jtag3_desc},
+ // {"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc},
+ // {"jtagice3_dw", jtag3_dw_initpgm, jtag3_dw_desc},
+ // {"jtagice3_isp", stk500v2_jtag3_initpgm, stk500v2_jtag3_desc},
+ {"linuxgpio", linuxgpio_initpgm, linuxgpio_desc},
+ // {"par", par_initpgm, par_desc},
+ {"pickit2", pickit2_initpgm, pickit2_desc},
+ {"serbb", serbb_initpgm, serbb_desc},
+ {"stk500", stk500_initpgm, stk500_desc},
+ {"stk500generic", stk500generic_initpgm, stk500generic_desc},
+ {"stk500v2", stk500v2_initpgm, stk500v2_desc},
+ {"stk500hvsp", stk500hvsp_initpgm, stk500hvsp_desc},
+ {"stk500pp", stk500pp_initpgm, stk500pp_desc},
+ {"stk600", stk600_initpgm, stk600_desc},
+ {"stk600hvsp", stk600hvsp_initpgm, stk600hvsp_desc},
+ {"stk600pp", stk600pp_initpgm, stk600pp_desc},
+ // {"usbasp", usbasp_initpgm, usbasp_desc},
+ // {"usbtiny", usbtiny_initpgm, usbtiny_desc},
+ {"wiring", wiring_initpgm, wiring_desc},
+};
+
+const PROGRAMMER_TYPE * locate_programmer_type(const char * id)
+{
+ const PROGRAMMER_TYPE * p = NULL;
+ int i;
+ int found;
+
+ found = 0;
+
+ for (i = 0; i < sizeof(programmers_types)/sizeof(programmers_types[0]) && !found; i++) {
+ p = &(programmers_types[i]);
+ if (strcasecmp(id, p->id) == 0)
+ found = 1;
+ }
+
+ if (found)
+ return p;
+
+ return NULL;
+}
+
+/*
+ * Iterate over the list of programmers given as "programmers", and
+ * call the callback function cb for each entry found. cb is being
+ * passed the following arguments:
+ * . the name of the programmer (for -c)
+ * . the descriptive text given in the config file
+ * . the name of the config file this programmer has been defined in
+ * . the line number of the config file this programmer has been defined at
+ * . the "cookie" passed into walk_programmers() (opaque client data)
+ */
+ /*
+void walk_programmer_types(LISTID programmer_types, walk_programmer_types_cb cb, void *cookie)
+{
+ LNODEID ln1;
+ PROGRAMMER * p;
+
+ for (ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) {
+ p = ldata(ln1);
+ cb(p->id, p->desc, cookie);
+ }
+ }
+}*/
+
+void walk_programmer_types(walk_programmer_types_cb cb, void *cookie)
+{
+ const PROGRAMMER_TYPE * p;
+ int i;
+
+ for (i = 0; i < sizeof(programmers_types)/sizeof(programmers_types[0]); i++) {
+ p = &(programmers_types[i]);
+ cb(p->id, p->desc, cookie);
+ }
+}
+
+
diff --git a/xs/src/avrdude/pickit2.c b/xs/src/avrdude/pickit2.c
new file mode 100644
index 000000000..bbf8b9ad7
--- /dev/null
+++ b/xs/src/avrdude/pickit2.c
@@ -0,0 +1,1340 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2005 Erik Walthinsen
+ * Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2006 David Moore
+ * Copyright (C) 2006,2007 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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: pickit2.c 2010-05-03 dbrown$ */
+/* Based on Id: stk500v2.c 836 2009-07-10 22:39:37Z joerg_wunsch */
+
+/*
+ * avrdude interface for PicKit2 programmer
+ *
+ * The PicKit2 programmer is a cheap device capable
+ * of 2 (bidirectional data line), 3, 4 wire SPI comms
+ *
+ * The PICkit2 software license doesn't allow the source to be
+ * modified to program other devices - nor can we distribute
+ * their source code. This program is not derived from nor does it
+ * contain any of the pickit2 source and should be exempt from any
+ * licensing issues.
+ *
+ * ISP Pinout (AVR - PICKit2 (pin)):
+ * RST - VPP/MCLR (1)
+ * VDD - VDD Target (2) -- possibly optional if AVR self powered
+ * GND - GND (3)
+ * MISO - PGD (4)
+ * SCLK - PDC (5)
+ * MOSI - AUX (6)
+ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#if defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
+
+#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
+#include <windows.h>
+#if defined(HAVE_DDK_HIDSDI_H)
+# include <ddk/hidsdi.h>
+#else
+# include "my_ddk_hidsdi.h"
+#endif
+#include <setupapi.h>
+#else
+#if defined(HAVE_USB_H)
+# include <usb.h>
+#elif defined(HAVE_LUSB0_USB_H)
+# include <lusb0_usb.h>
+#else
+# error "libusb needs either <usb.h> or <lusb0_usb.h>"
+#endif
+#endif
+
+#if 0
+#define DEBUG(...) do { avrdude_message(MSG_DEBUG, __VA_ARGS__); } while(0)
+#else
+#define DEBUG(...) ((void)0)
+#endif
+
+#if 0
+#define DEBUGRECV(...) do { avrdude_message(MSG_DEBUG, __VA_ARGS__); } while(0)
+#else
+#define DEBUGRECV(...) ((void)0)
+#endif
+
+#define PICKIT2_VID 0x04d8
+#define PICKIT2_PID 0x0033
+
+#define SPI_MAX_CHUNK (64 - 10) // max packet size less the command overhead
+
+// win32native only:
+#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
+static HANDLE open_hid(unsigned short vid, unsigned short pid);
+const char *usb_strerror()
+{
+ return "";
+}
+#else
+static int usb_open_device(struct usb_dev_handle **dev, int vid, int pid);
+//#define INVALID_HANDLE_VALUE NULL
+#define USB_ERROR_NONE 0
+#define USB_ERROR_ACCESS 1
+#define USB_ERROR_NOTFOUND 2
+#define USB_ERROR_BUSY 16
+#define USB_ERROR_IO 5
+#endif // WIN32NATIVE
+
+static int pickit2_write_report(PROGRAMMER *pgm, const unsigned char report[65]);
+static int pickit2_read_report(PROGRAMMER *pgm, unsigned char report[65]);
+
+#ifndef MIN
+#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
+#endif
+
+/*
+ * Private data for this programmer.
+ */
+struct pdata
+{
+#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
+ HANDLE usb_handle, write_event, read_event;
+#else
+ struct usb_dev_handle *usb_handle; // LIBUSB STUFF
+#endif
+ uint8_t clock_period; // SPI clock period in us
+ int transaction_timeout; // usb trans timeout in ms
+};
+
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
+#define CMD_NOP 0x5A
+#define CMD_GET_VERSION 0x76
+#define CMD_SET_VDD_4(v) 0xA0, (uint8_t)((v)*2048+672), (uint8_t)(((v)*2048+672)/256), (uint8_t)((v)*36)
+#define CMD_SET_VPP_4(v) 0xA1, 0x40, (uint8_t)((v)*18.61), (uint8_t)((v)*13)
+#define CMD_READ_VDD_VPP 0xA3
+#define CMD_EXEC_SCRIPT_2(len) 0xA6, (len)
+#define CMD_CLR_DLOAD_BUFF 0xA7
+#define CMD_DOWNLOAD_DATA_2(len) 0xA8, (len)
+#define CMD_CLR_ULOAD_BUFF 0xA9
+#define CMD_UPLOAD_DATA 0xAA
+#define CMD_UPLOAD_DATA_NO_LEN 0xAC
+#define CMD_END_OF_BUFFER 0xAD
+
+#define SCR_VDD_ON 0xFF
+#define SCR_VDD_OFF 0xFE
+#define SCR_VPP_ON 0xFB
+#define SCR_VPP_OFF 0xFA
+#define SCR_VPP_PWM_ON 0xF9
+#define SCR_VPP_PWM_OFF 0xF8
+#define SCR_MCLR_GND_ON 0xF7
+#define SCR_MCLR_GND_OFF 0xF6
+#define SCR_BUSY_LED_ON 0xF5
+#define SCR_BUSY_LED_OFF 0xF4
+#define SCR_SET_ICSP_DELAY_2(us) 0xEA,(us)
+#define SCR_SET_PINS_2(dd, cd, dv, cv) 0xF3, (((cd)!=0) | (((dd)!=0)<<1) | (((cv)!=0)<<2) | (((dv)!=0)<<3))
+#define SCR_GET_PINS 0xDC
+#define SCR_LOOP_3(rel, cnt) 0xE9, rel, cnt
+#define SCR_DELAY_2(sec) ((sec)>0.0054528?0xE8:0xE7), (uint8_t)((sec)>0.0054528?(.999+(sec)/.00546):(.999+(sec)/.0000213))
+#define SCR_SET_AUX_2(ad, av) 0xCF, (((ad)!=0) | (((av)!=0)<<1))
+#define SCR_SPI_SETUP_PINS_4 SCR_SET_PINS_2(1,0,0,0), SCR_SET_AUX_2(0,0)
+#define SCR_SPI 0xC3
+#define SCR_SPI_LIT_2(v) 0xC7,(v)
+
+static void pickit2_setup(PROGRAMMER * pgm)
+{
+ if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0)
+ {
+ avrdude_message(MSG_INFO, "%s: pickit2_setup(): Out of memory allocating private data\n",
+ progname);
+ exit(1);
+ }
+ memset(pgm->cookie, 0, sizeof(struct pdata));
+
+ PDATA(pgm)->transaction_timeout = 1500; // default value, may be overridden with -x timeout=ms
+ PDATA(pgm)->clock_period = 10; // default value, may be overridden with -x clockrate=us or -B or -i
+}
+
+static void pickit2_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+}
+
+static int pickit2_open(PROGRAMMER * pgm, char * port)
+{
+#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
+ PDATA(pgm)->usb_handle = open_hid(PICKIT2_VID, PICKIT2_PID);
+
+ if (PDATA(pgm)->usb_handle == INVALID_HANDLE_VALUE)
+ {
+ /* no PICkit2 found */
+ avrdude_message(MSG_INFO, "%s: error: could not find PICkit2 with vid=0x%x pid=0x%x\n",
+ progname, PICKIT2_VID, PICKIT2_PID);
+ return -1;
+ }
+ else
+ {
+ // get the device description while we're at it
+ short buff[PGM_DESCLEN-1], i;
+ HidD_GetProductString(PDATA(pgm)->usb_handle, buff, PGM_DESCLEN-1);
+
+ // convert from wide chars, but do not overwrite trailing '\0'
+ memset(&(pgm->type), 0, PGM_DESCLEN);
+ for (i = 0; i < (PGM_DESCLEN-1) && buff[i]; i++)
+ {
+ pgm->type[i] = (char)buff[i]; // TODO what about little/big endian???
+ }
+ }
+#else
+ if (usb_open_device(&(PDATA(pgm)->usb_handle), PICKIT2_VID, PICKIT2_PID) < 0)
+ {
+ /* no PICkit2 found */
+ avrdude_message(MSG_INFO, "%s: error: could not find PICkit2 with vid=0x%x pid=0x%x\n",
+ progname, PICKIT2_VID, PICKIT2_PID);
+ return -1;
+ }
+#endif
+
+ if (pgm->ispdelay > 0)
+ {
+ PDATA(pgm)->clock_period = MIN(pgm->ispdelay, 255);
+ }
+ else if (pgm->bitclock > 0.0)
+ {
+ PDATA(pgm)->clock_period = MIN(pgm->bitclock * 1e6, 255);
+ }
+
+ return 0;
+}
+
+
+static void pickit2_close(PROGRAMMER * pgm)
+{
+#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
+ CloseHandle(PDATA(pgm)->usb_handle);
+ CloseHandle(PDATA(pgm)->read_event);
+ CloseHandle(PDATA(pgm)->write_event);
+#else
+ usb_close(PDATA(pgm)->usb_handle);
+#endif // WIN32NATIVE
+}
+
+
+static int pickit2_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char temp[4];
+ memset(temp, 0, sizeof(temp));
+
+ int errorCode = 0;
+
+ /* set sck period */
+ if (pgm->set_sck_period)
+ pgm->set_sck_period(pgm, pgm->bitclock);
+
+ /* connect to target device -- we'll just ask for the firmware version */
+ static const unsigned char report[65] = {0, CMD_GET_VERSION, CMD_END_OF_BUFFER};
+ if ((errorCode = pickit2_write_report(pgm, report)) > 0)
+ {
+ unsigned char report[65] = {0};
+ //memset(report, 0, sizeof(report));
+ if ((errorCode = pickit2_read_report(pgm, report)) >= 4)
+ {
+ avrdude_message(MSG_NOTICE, "%s: %s firmware version %d.%d.%d\n", progname, pgm->desc, (int)report[1], (int)report[2], (int)report[3]);
+
+ // set the pins, apply reset,
+ // TO DO: apply vtarget (if requested though -x option)
+ unsigned char report[65] =
+ {
+ 0, CMD_SET_VDD_4(5),
+ CMD_SET_VPP_4(5),
+ CMD_EXEC_SCRIPT_2(24),
+ SCR_SPI_SETUP_PINS_4, // SDO, SDI, SCK
+ SCR_SET_ICSP_DELAY_2(PDATA(pgm)->clock_period), // slow down the SPI
+ SCR_VDD_ON,
+ SCR_MCLR_GND_OFF, // let reset float high
+ SCR_VPP_PWM_ON,
+ SCR_DELAY_2(.1),
+ SCR_VPP_ON,
+ SCR_DELAY_2(.1),
+ SCR_VPP_OFF,
+ SCR_DELAY_2(.01),
+
+ SCR_MCLR_GND_ON, // reset low - programming mode
+ SCR_DELAY_2(.1),
+
+ SCR_BUSY_LED_ON,
+ SCR_DELAY_2(.3),
+ SCR_BUSY_LED_OFF,
+
+ CMD_CLR_DLOAD_BUFF,
+ CMD_CLR_ULOAD_BUFF,
+
+ CMD_END_OF_BUFFER
+ };
+
+ if (pickit2_write_report(pgm, report) < 0)
+ {
+ avrdude_message(MSG_INFO, "pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror());
+ return -1;
+ }
+ }
+ else
+ {
+ avrdude_message(MSG_INFO, "pickit2_read_report failed (ec %d). %s\n", errorCode, usb_strerror());
+ return -1;
+ }
+ }
+ else
+ {
+ avrdude_message(MSG_INFO, "pickit2_write_report failed (ec %d). %s\n", errorCode, usb_strerror());
+ return -1;
+ }
+
+ if (pgm->program_enable)
+ return pgm->program_enable(pgm, p);
+ else
+ return -1;
+}
+
+static void pickit2_disable(PROGRAMMER * pgm)
+{
+ /* make sure all pins are floating & all voltages are off */
+ static const unsigned char report[65] =
+ {
+ 0, CMD_EXEC_SCRIPT_2(8),
+ SCR_SET_PINS_2(1,1,0,0),
+ SCR_SET_AUX_2(1,0),
+ SCR_MCLR_GND_OFF,
+ SCR_VPP_OFF,
+ SCR_VDD_OFF,
+ SCR_BUSY_LED_OFF,
+ CMD_END_OF_BUFFER
+ };
+
+ pickit2_write_report(pgm, report);
+
+ return;
+}
+
+static void pickit2_enable(PROGRAMMER * pgm)
+{
+ /* Do nothing. */
+
+ return;
+}
+
+static void pickit2_display(PROGRAMMER * pgm, const char * p)
+{
+ DEBUG( "%s: Found \"%s\" version %d.%d.%d\n", progname, p, 1, 1, 1);
+ return;
+}
+
+#define sendReport(x)
+#define readReport(x) 0
+
+#if 0
+static int pickit2_rdy_led (struct programmer_t * pgm, int value)
+{
+ // no rdy led
+ return 0;
+}
+
+static int pickit2_err_led(struct programmer_t * pgm, int value)
+{
+ // there is no error led, so just flash the busy led a few times
+ uint8_t report[65] =
+ {
+ 0, CMD_EXEC_SCRIPT_2(9),
+ SCR_BUSY_LED_ON,
+ SCR_DELAY_2(.2),
+ SCR_BUSY_LED_OFF,
+ SCR_DELAY_2(.2),
+ SCR_LOOP_3(6, 9),
+ CMD_END_OF_BUFFER
+ };
+
+ // busy stops flashing by itself, so just return
+ if (!value)
+ {
+ return 0;
+ }
+
+ return pickit2_write_report(pgm, report) != -1;
+}
+#endif
+
+static int pickit2_pgm_led (struct programmer_t * pgm, int value)
+{
+ // script to set busy led appropriately
+ uint8_t report[65] = {0, CMD_EXEC_SCRIPT_2(1),
+ value ? SCR_BUSY_LED_ON : SCR_BUSY_LED_OFF,
+ CMD_END_OF_BUFFER
+ };
+
+ return pickit2_write_report(pgm, report) != -1;
+}
+
+static int pickit2_vfy_led (struct programmer_t * pgm, int value)
+{
+ // no such thing - maybe just call pgm_led
+
+ return pgm->pgm_led(pgm, value);
+}
+
+static void pickit2_powerup(struct programmer_t * pgm)
+{
+ // turn vdd on?
+}
+
+static void pickit2_powerdown(struct programmer_t * pgm)
+{
+ // do what?
+ pgm->disable(pgm);
+}
+
+static int pickit2_program_enable(struct programmer_t * pgm, AVRPART * p)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+
+ if (p->op[AVR_OP_PGM_ENABLE] == NULL)
+ {
+ avrdude_message(MSG_INFO, "program enable instruction not defined for part \"%s\"\n",
+ p->desc);
+ return -1;
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+ avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd);
+ pgm->cmd(pgm, cmd, res);
+
+ {
+ int i;
+ avrdude_message(MSG_DEBUG, "program_enable(): sending command. Resp = ");
+
+ for (i = 0; i < 4; i++)
+ {
+ avrdude_message(MSG_DEBUG, "%x ", (int)res[i]);
+ }
+ avrdude_message(MSG_DEBUG, "\n");
+ }
+
+ // check for sync character
+ if (res[2] != cmd[1])
+ return -2;
+
+ return 0;
+}
+
+static int pickit2_chip_erase(struct programmer_t * pgm, AVRPART * p)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+
+ if (p->op[AVR_OP_CHIP_ERASE] == NULL)
+ {
+ avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
+ p->desc);
+ return -1;
+ }
+
+ pgm->pgm_led(pgm, ON);
+
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
+ pgm->cmd(pgm, cmd, res);
+ usleep(p->chip_erase_delay);
+ pgm->initialize(pgm, p);
+
+ pgm->pgm_led(pgm, OFF);
+
+ return 0;
+}
+
+static int pickit2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ // only supporting flash & eeprom page reads
+ if ((!mem->paged || page_size <= 1) || (strcmp(mem->desc, "flash") != 0 && strcmp(mem->desc, "eeprom") != 0))
+ {
+ return -1;
+ }
+
+ DEBUG( "paged read ps %d, mem %s\n", page_size, mem->desc);
+
+ OPCODE *readop = 0, *lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
+ uint8_t data = 0, cmd[SPI_MAX_CHUNK], res[SPI_MAX_CHUNK];
+ unsigned int addr_base;
+ unsigned int max_addr = addr + n_bytes;
+
+ pgm->pgm_led(pgm, ON);
+
+ for (addr_base = addr; addr_base < max_addr; )
+ {
+ if ((addr_base == 0 || (addr_base % /*ext_address_boundary*/ 65536) == 0)
+ && lext != NULL)
+ {
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(lext, cmd);
+ avr_set_addr(lext, cmd, addr_base);
+ pgm->cmd(pgm, cmd, res);
+ }
+
+ // bytes to send in the next packet -- not necessary as pickit2_spi() handles breaking up
+ // the data into packets -- but we need to keep transfers frequent so that we can update the
+ // status indicator bar
+ uint32_t blockSize = MIN(65536 - (addr_base % 65536), MIN(max_addr - addr_base, SPI_MAX_CHUNK / 4));
+
+ memset(cmd, 0, sizeof(cmd));
+ memset(res, 0, sizeof(res));
+
+ uint8_t addr_off;
+ for (addr_off = 0; addr_off < blockSize; addr_off++)
+ {
+ int addr = addr_base + addr_off, caddr = addr;
+
+ if (mem->op[AVR_OP_READ_LO] != NULL && mem->op[AVR_OP_READ_HI] != NULL)
+ {
+ if (addr & 0x00000001)
+ readop = mem->op[AVR_OP_READ_HI];
+ else
+ readop = mem->op[AVR_OP_READ_LO];
+
+ caddr /= 2;
+ }
+ else if (mem->op[AVR_OP_READ] != NULL)
+ {
+ readop = mem->op[AVR_OP_READ];
+ }
+ else
+ {
+ avrdude_message(MSG_INFO, "no read command specified\n");
+ return -1;
+ }
+
+ avr_set_bits(readop, &cmd[addr_off*4]);
+ avr_set_addr(readop, &cmd[addr_off*4], caddr);
+ }
+
+ int bytes_read = pgm->spi(pgm, cmd, res, blockSize*4);
+
+ if (bytes_read < 0)
+ {
+ avrdude_message(MSG_INFO, "Failed @ pgm->spi()\n");
+ pgm->err_led(pgm, ON);
+ return -1;
+ }
+
+ DEBUG( "\npaged_load @ %X, wrote: %d, read: %d bytes\n", addr_base, blockSize*4, bytes_read);
+
+ for (addr_off = 0; addr_off < bytes_read / 4; addr_off++)
+ {
+ data = 0;
+ avr_get_output(readop, &res[addr_off*4], &data);
+ mem->buf[addr_base + addr_off] = data;
+
+ DEBUG( "%2X(%c)", (int)data, data<0x20?'.':data);
+ }
+ DEBUG( "\n");
+
+ addr_base += blockSize;
+ }
+
+ pgm->pgm_led(pgm, OFF);
+
+ return n_bytes;
+}
+
+
+static int pickit2_commit_page(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr)
+{
+ OPCODE * wp, * lext;
+
+ wp = mem->op[AVR_OP_WRITEPAGE];
+ if (wp == NULL)
+ {
+ avrdude_message(MSG_INFO, "pickit2_commit_page(): memory \"%s\" not configured for page writes\n",
+ mem->desc);
+ return -1;
+ }
+
+ // adjust the address if this memory is word-addressable
+ if ((mem->op[AVR_OP_LOADPAGE_LO]) || (mem->op[AVR_OP_READ_LO]))
+ addr /= 2;
+
+ unsigned char cmd[8];
+ memset(cmd, 0, sizeof(cmd));
+
+ // use the "load extended address" command, if available
+ lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
+ if (lext != NULL)
+ {
+ avr_set_bits(lext, cmd);
+ avr_set_addr(lext, cmd, addr);
+ }
+
+ // make up the write page command in the 2nd cmd position
+ avr_set_bits(wp, &cmd[4]);
+ avr_set_addr(wp, &cmd[4], addr);
+
+ if (lext != NULL)
+ {
+ // write the load extended address cmd && the write_page cmd
+ pgm->spi(pgm, cmd, NULL, 8);
+ }
+ else
+ {
+ // write just the write_page cmd
+ pgm->spi(pgm, &cmd[4], NULL, 4);
+ }
+
+ // just delay the max (we could do the delay in the PICkit2 if we wanted)
+ usleep(mem->max_write_delay);
+
+ return 0;
+}
+
+// not actually a paged write, but a bulk/batch write
+static int pickit2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned int page_size, unsigned int addr, unsigned int n_bytes)
+{
+ // only paged write for flash implemented
+ if (strcmp(mem->desc, "flash") != 0 && strcmp(mem->desc, "eeprom") != 0)
+ {
+ avrdude_message(MSG_INFO, "Part does not support %d paged write of %s\n", page_size, mem->desc);
+ return -1;
+ }
+
+ DEBUG( "page size %d mem %s supported: %d\n", page_size, mem->desc, mem->paged);
+ DEBUG( "loadpagehi %x, loadpagelow %x, writepage %x\n", (int)mem->op[AVR_OP_LOADPAGE_HI], (int)mem->op[AVR_OP_LOADPAGE_LO], (int)mem->op[AVR_OP_WRITEPAGE]);
+
+ OPCODE *writeop;
+ uint8_t cmd[SPI_MAX_CHUNK], res[SPI_MAX_CHUNK];
+ unsigned int addr_base;
+ unsigned int max_addr = addr + n_bytes;
+
+ pgm->pgm_led(pgm, ON);
+
+ for (addr_base = addr; addr_base < max_addr; )
+ {
+ uint32_t blockSize;
+
+ if (mem->paged)
+ {
+ blockSize = MIN(page_size - (addr_base % page_size), MIN(max_addr - addr_base, SPI_MAX_CHUNK/4) ); // bytes remaining in page
+ }
+ else
+ {
+ blockSize = 1;
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+ memset(res, 0, sizeof(res));
+
+ uint8_t addr_off;
+ for (addr_off = 0; addr_off < blockSize; addr_off++)
+ {
+ int addr = addr_base + addr_off;
+ int caddr = 0;
+
+ /*
+ * determine which memory opcode to use
+ */
+ if (mem->paged && mem->op[AVR_OP_LOADPAGE_HI] && mem->op[AVR_OP_LOADPAGE_LO])
+ {
+ if (addr & 0x01)
+ writeop = mem->op[AVR_OP_LOADPAGE_HI];
+ else
+ writeop = mem->op[AVR_OP_LOADPAGE_LO];
+ caddr = addr / 2;
+ }
+ else if (mem->paged && mem->op[AVR_OP_LOADPAGE_LO])
+ {
+ writeop = mem->op[AVR_OP_LOADPAGE_LO];
+ caddr = addr;
+ }
+ else if (mem->op[AVR_OP_WRITE_LO])
+ {
+ writeop = mem->op[AVR_OP_WRITE_LO];
+ caddr = addr; // maybe this should divide by 2 & use the write_high opcode also
+
+ avrdude_message(MSG_INFO, "Error AVR_OP_WRITE_LO defined only (where's the HIGH command?)\n");
+ return -1;
+ }
+ else
+ {
+ writeop = mem->op[AVR_OP_WRITE];
+ caddr = addr;
+ }
+
+ if (writeop == NULL)
+ {
+ pgm->err_led(pgm, ON);
+ // not supported!
+ return -1;
+ }
+
+ avr_set_bits(writeop, &cmd[addr_off*4]);
+ avr_set_addr(writeop, &cmd[addr_off*4], caddr);
+ avr_set_input(writeop, &cmd[addr_off*4], mem->buf[addr]);
+ }
+
+ int bytes_read = pgm->spi(pgm, cmd, res, blockSize*4);
+
+ if (bytes_read < 0)
+ {
+ avrdude_message(MSG_INFO, "Failed @ pgm->spi()\n");
+ pgm->err_led(pgm, ON);
+ return -1;
+ }
+
+ addr_base += blockSize;
+
+ // write the page - this function looks after extended address also
+ if (mem->paged && (((addr_base % page_size) == 0) || (addr_base == max_addr)))
+ {
+ DEBUG( "Calling pickit2_commit_page()\n");
+ pickit2_commit_page(pgm, p, mem, addr_base-1);
+ }
+ else if (!mem->paged)
+ {
+ usleep(mem->max_write_delay);
+ }
+ }
+
+ pgm->pgm_led(pgm, OFF);
+
+ return n_bytes;
+}
+
+
+static int pickit2_cmd(struct programmer_t * pgm, const unsigned char *cmd,
+ unsigned char *res)
+{
+ return pgm->spi(pgm, cmd, res, 4);
+}
+
+// breaks up the cmd[] data into packets & sends to the pickit2. Data shifted in is stored in res[].
+static int pickit2_spi(struct programmer_t * pgm, const unsigned char *cmd,
+ unsigned char *res, int n_bytes)
+{
+ int retval = 0, temp1 = 0, temp2 = 0, count = n_bytes;
+
+ while (count > 0)
+ {
+ uint8_t i, blockSize = MIN(count, SPI_MAX_CHUNK);
+ uint8_t report[65] = {0, CMD_DOWNLOAD_DATA_2(blockSize)};
+ uint8_t *repptr = report + 3;
+
+ memset(report + 3, CMD_END_OF_BUFFER, sizeof(report) - 3);
+
+ // append some data to write to SPI
+ for (i = 0; i < blockSize; i++)
+ {
+ *repptr++ = *cmd++;
+ count--; // 1 less byte to pack
+ }
+
+ if (blockSize == 1)
+ {
+ *repptr++ = 0xa6; //CMD_EXECUTE_SCRIPT;
+ *repptr++ = 1;
+ *repptr++ = SCR_SPI;
+ }
+ else
+ {
+ *repptr++ = 0xa6; //CMD_EXECUTE_SCRIPT_2;
+ *repptr++ = 4;
+ *repptr++ = SCR_SPI;
+ *repptr++ = 0xe9; //SCR_LOOP_3;
+ *repptr++ = 1;
+ *repptr++ = blockSize - 1;
+ }
+
+ // request the data read to be sent to us
+ *repptr++ = CMD_UPLOAD_DATA;
+
+ // check return values
+ if ((temp1=pickit2_write_report(pgm, report)) < 0 ||
+ (temp2=pickit2_read_report(pgm, report)) < 0)
+ {
+ return -1;
+ }/*
+ else
+ {
+ int i;
+ DEBUG( "in spi. wrote %d, read %d\n", temp1, temp2);
+
+ for (i = 0; i < temp2; i++)
+ {
+ DEBUG( "%2.2x ", report[i]);
+ }
+
+ DEBUG( "\n");
+ }*/
+
+ retval = report[1]; // upload-length field
+ repptr = &report[2]; // actual data starts here
+
+ if (res) // copy data if user has specified a storage location
+ {
+ memcpy(res, repptr, retval);
+ res += retval;
+ }
+ }
+
+ return n_bytes;
+}
+
+#if (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
+/*
+ Func: open_hid()
+ Desc: finds & opens device having specified VID & PID.
+ Retn: Handle of open device or INVALID_HANDLE_VALUE on fail
+
+ Note this routine is a modified function from:
+ usbhidiocDlg.cpp : implementation file
+ Project: usbhidioc.cpp
+ Version: 3.0
+ Date: 7/18/05
+ by Jan Axelson (jan@Lvr.com)
+*/
+static HANDLE open_hid(unsigned short vid, unsigned short pid)
+{
+ //Use a series of API calls to find a HID with a specified Vendor IF and Product ID.
+ HANDLE returnHandle = INVALID_HANDLE_VALUE;
+ HIDD_ATTRIBUTES Attributes;
+// DWORD DeviceUsage;
+ SP_DEVICE_INTERFACE_DATA devInfoData;
+ BOOL LastDevice = FALSE;
+ int MemberIndex = 0;
+ LONG Result;
+
+ // were global, now just local scrap
+ DWORD Length = 0;
+ PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
+ HANDLE DeviceHandle=NULL;
+ GUID HidGuid;
+ HANDLE hDevInfo;
+ ULONG Required;
+ BOOL MyDeviceDetected = 0;
+
+ /*
+ API function: HidD_GetHidGuid
+ Get the GUID for all system HIDs.
+ Returns: the GUID in HidGuid.
+ */
+
+ HidD_GetHidGuid(&HidGuid);
+ DEBUG("\nHidD_GetHidGuid returned.\n");
+
+ /*
+ API function: SetupDiGetClassDevs
+ Returns: a handle to a device information set for all installed devices.
+ Requires: the GUID returned by GetHidGuid.
+ */
+
+ hDevInfo=SetupDiGetClassDevs
+ (&HidGuid,
+ NULL,
+ NULL,
+ DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);
+
+ DEBUG("\nSetupDiGetClassDevs returned 0x%x\n", hDevInfo);
+ devInfoData.cbSize = sizeof(devInfoData);
+
+ //Step through the available devices looking for the one we want.
+ //Quit on detecting the desired device or checking all available devices without success.
+
+ MemberIndex = 0;
+ LastDevice = FALSE;
+
+ do
+ {
+ /*
+ API function: SetupDiEnumDeviceInterfaces
+ On return, MyDeviceInterfaceData contains the handle to a
+ SP_DEVICE_INTERFACE_DATA structure for a detected device.
+ Requires:
+ The DeviceInfoSet returned in SetupDiGetClassDevs.
+ The HidGuid returned in GetHidGuid.
+ An index to specify a device.
+ */
+
+
+ Result=SetupDiEnumDeviceInterfaces
+ (hDevInfo,
+ 0,
+ &HidGuid,
+ MemberIndex,
+ &devInfoData);
+
+ DEBUG("\nSetupDiEnumDeviceInterfaces returned 0x%x\n", Result);
+
+ if (Result != 0)
+ {
+ //A device has been detected, so get more information about it.
+
+ /*
+ API function: SetupDiGetDeviceInterfaceDetail
+ Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure
+ containing information about a device.
+ To retrieve the information, call this function twice.
+ The first time returns the size of the structure in Length.
+ The second time returns a pointer to the data in DeviceInfoSet.
+ Requires:
+ A DeviceInfoSet returned by SetupDiGetClassDevs
+ The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces.
+
+ The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure.
+ This application doesn't retrieve or use the structure.
+ If retrieving the structure, set
+ MyDeviceInfoData.cbSize = length of MyDeviceInfoData.
+ and pass the structure's address.
+ */
+
+ //Get the Length value.
+ //The call will return with a "buffer too small" error which can be ignored.
+ Result = SetupDiGetDeviceInterfaceDetail
+ (hDevInfo,
+ &devInfoData,
+ NULL,
+ 0,
+ &Length,
+ NULL);
+
+ DEBUG("\nSetupDiGetDeviceInterfaceDetail returned 0x%x\n", Result);
+
+ //Allocate memory for the hDevInfo structure, using the returned Length.
+
+ detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
+
+ //Set cbSize in the detailData structure.
+
+ detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+
+ //Call the function again, this time passing it the returned buffer size.
+
+ Result = SetupDiGetDeviceInterfaceDetail
+ (hDevInfo,
+ &devInfoData,
+ detailData,
+ Length,
+ &Required,
+ NULL);
+
+ // Open a handle to the device.
+ // To enable retrieving information about a system mouse or keyboard,
+ // don't request Read or Write access for this handle.
+
+ /*
+ API function: CreateFile
+ Returns: a handle that enables reading and writing to the device.
+ Requires:
+ The DevicePath in the detailData structure
+ returned by SetupDiGetDeviceInterfaceDetail.
+ */
+
+ DeviceHandle=CreateFile
+ (detailData->DevicePath,
+ 0,
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ (LPSECURITY_ATTRIBUTES)NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+
+ DEBUG("CreateFile(): %s\n", detailData->DevicePath);
+ /*
+ API function: HidD_GetAttributes
+ Requests information from the device.
+ Requires: the handle returned by CreateFile.
+ Returns: a HIDD_ATTRIBUTES structure containing
+ the Vendor ID, Product ID, and Product Version Number.
+ Use this information to decide if the detected device is
+ the one we're looking for.
+ */
+
+ //Set the Size to the number of bytes in the structure.
+
+ Attributes.Size = sizeof(Attributes);
+
+ Result = HidD_GetAttributes
+ (DeviceHandle,
+ &Attributes);
+
+ DEBUG("HidD_GetAttributes returned 0x%x\n", Result);
+ DEBUG("VID: %.4X PID: %.4X\n", Attributes.VendorID, Attributes.ProductID);
+
+ //Is it the desired device?
+ MyDeviceDetected = FALSE;
+ if (Attributes.VendorID == vid)
+ {
+ if (Attributes.ProductID == pid)
+ {
+ //Both the Vendor ID and Product ID match.
+
+ MyDeviceDetected = TRUE;
+
+ // Get a handle for us to use.
+
+ returnHandle = CreateFile
+ (detailData->DevicePath,
+ GENERIC_WRITE | GENERIC_READ,
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ (LPSECURITY_ATTRIBUTES)NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ } //if (Attributes.ProductID == ProductID)
+
+ else
+ //The Product ID doesn't match.
+
+ CloseHandle(DeviceHandle);
+
+ } //if (Attributes.VendorID == VendorID)
+
+ else
+ //The Vendor ID doesn't match.
+
+ CloseHandle(DeviceHandle);
+
+ //Free the memory used by the detailData structure (no longer needed).
+
+ free(detailData);
+
+ } //if (Result != 0)
+
+ else
+ //SetupDiEnumDeviceInterfaces returned 0, so there are no more devices to check.
+
+ LastDevice=TRUE;
+
+ //If we haven't found the device yet, and haven't tried every available device,
+ //try the next one.
+
+ MemberIndex = MemberIndex + 1;
+
+ } //do
+
+ while ((LastDevice == FALSE) && (MyDeviceDetected == FALSE));
+
+ if (MyDeviceDetected == FALSE)
+ DEBUG("Device not detected\n");
+ else
+ DEBUG("Device detected\n");
+
+ //Free the memory reserved for hDevInfo by SetupDiClassDevs.
+
+ DEBUG("Calling SetupDiDestroyDeviceInfoList\n");
+ SetupDiDestroyDeviceInfoList(hDevInfo);
+
+ return returnHandle;
+}
+
+// simple read with timeout
+static int usb_read_interrupt(PROGRAMMER *pgm, void *buff, int size, int timeout)
+{
+ OVERLAPPED ovr;
+ DWORD bytesRead = 0;
+
+ if (PDATA(pgm)->read_event == NULL)
+ {
+ PDATA(pgm)->read_event = CreateEvent(0, 0, 0, 0);
+ }
+
+ memset(&ovr, 0, sizeof(ovr));
+ ovr.hEvent = PDATA(pgm)->read_event;
+
+ ReadFile(PDATA(pgm)->usb_handle, buff, size, &bytesRead, &ovr);
+ if (WaitForSingleObject(PDATA(pgm)->read_event, timeout) == WAIT_TIMEOUT)
+ {
+ CancelIo(PDATA(pgm)->usb_handle);
+ return -1;
+ }
+
+ GetOverlappedResult(PDATA(pgm)->usb_handle, &ovr, &bytesRead, 0);
+
+ return bytesRead > 0 ? bytesRead : -1;
+}
+
+// simple write with timeout
+static int usb_write_interrupt(PROGRAMMER *pgm, const void *buff, int size, int timeout)
+{
+ OVERLAPPED ovr;
+ DWORD bytesWritten = 0;
+
+ if (PDATA(pgm)->write_event == NULL)
+ {
+ PDATA(pgm)->write_event = CreateEvent(0, 0, 0, 0);
+ }
+
+ memset(&ovr, 0, sizeof(ovr));
+ ovr.hEvent = PDATA(pgm)->write_event;
+
+ WriteFile(PDATA(pgm)->usb_handle, buff, size, &bytesWritten, &ovr);
+ if (WaitForSingleObject(PDATA(pgm)->write_event, timeout) == WAIT_TIMEOUT)
+ {
+ CancelIo(PDATA(pgm)->usb_handle);
+ return -1;
+ }
+
+ GetOverlappedResult(PDATA(pgm)->usb_handle, &ovr, &bytesWritten, 0);
+
+ return bytesWritten > 0 ? bytesWritten : -1;
+}
+
+static int pickit2_write_report(PROGRAMMER * pgm, const unsigned char report[65])
+{
+ return usb_write_interrupt(pgm, report, 65, PDATA(pgm)->transaction_timeout); // XXX
+}
+
+static int pickit2_read_report(PROGRAMMER * pgm, unsigned char report[65])
+{
+ return usb_read_interrupt(pgm, report, 65, PDATA(pgm)->transaction_timeout);
+}
+
+#else // WIN32NATIVE
+/* taken (modified) from avrdude usbasp.c */
+static int usb_open_device(struct usb_dev_handle **device, int vendor, int product)
+{
+ struct usb_bus *bus;
+ struct usb_device *dev;
+ usb_dev_handle *handle = NULL;
+ int errorCode = USB_ERROR_NOTFOUND;
+ static int didUsbInit = 0;
+
+ if (!didUsbInit)
+ {
+ didUsbInit = 1;
+ usb_init();
+ }
+ usb_find_busses();
+ usb_find_devices();
+ for (bus=usb_get_busses(); bus; bus=bus->next)
+ {
+ for (dev=bus->devices; dev; dev=dev->next)
+ {
+ DEBUG( "Enumerating device list.. VID: 0x%4.4x, PID: 0x%4.4x\n", dev->descriptor.idVendor, dev->descriptor.idProduct);
+ if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product)
+ {
+ /* we need to open the device in order to query strings */
+ handle = usb_open(dev);
+ if (handle == NULL)
+ {
+ errorCode = USB_ERROR_ACCESS;
+ avrdude_message(MSG_INFO, "%s: Warning: cannot open USB device: %s\n", progname, usb_strerror());
+ continue;
+ }
+
+ // return with opened device handle
+ else
+ {
+ avrdude_message(MSG_NOTICE, "Device %p seemed to open OK.\n", handle);
+
+ if ((errorCode = usb_set_configuration(handle, 1)) < 0)
+ {
+ avrdude_message(MSG_INFO, "Could not set configuration. Error code %d, %s.\n"
+ "You may need to run avrdude as root or set up correct usb port permissions.", errorCode, usb_strerror());
+ }
+
+ if ((errorCode = usb_claim_interface(handle, 0)) < 0)
+ {
+ avrdude_message(MSG_INFO, "Could not claim interface. Error code %d, %s\n"
+ "You may need to run avrdude as root or set up correct usb port permissions.", errorCode, usb_strerror());
+ }
+
+ errorCode = 0;
+ *device = handle;
+ return 0;
+ }
+ }
+ }
+ }
+
+ return -1;
+}
+
+static int pickit2_write_report(PROGRAMMER * pgm, const unsigned char report[65])
+{
+ // endpoint 1 OUT??
+ return usb_interrupt_write(PDATA(pgm)->usb_handle, USB_ENDPOINT_OUT | 1, (const char*)(report+1), 64, PDATA(pgm)->transaction_timeout);
+}
+
+static int pickit2_read_report(PROGRAMMER * pgm, unsigned char report[65])
+{
+ // endpoint 1 IN??
+ return usb_interrupt_read(PDATA(pgm)->usb_handle, USB_ENDPOINT_IN | 1, (char*)(report+1), 64, PDATA(pgm)->transaction_timeout);
+}
+#endif // WIN323NATIVE
+
+static int pickit2_parseextparams(struct programmer_t * pgm, LISTID extparms)
+{
+ LNODEID ln;
+ const char *extended_param;
+ int rv = 0;
+
+ for (ln = lfirst(extparms); ln; ln = lnext(ln))
+ {
+ extended_param = ldata(ln);
+
+ if (strncmp(extended_param, "clockrate=", strlen("clockrate=")) == 0)
+ {
+ int clock_rate;
+ if (sscanf(extended_param, "clockrate=%i", &clock_rate) != 1 || clock_rate <= 0)
+ {
+ avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid clockrate '%s'\n",
+ progname, extended_param);
+ rv = -1;
+ continue;
+ }
+
+ int clock_period = MIN(1000000 / clock_rate, 255); // max period is 255
+ clock_rate = (int)(1000000 / (clock_period + 5e-7)); // assume highest speed is 2MHz - should probably check this
+
+ avrdude_message(MSG_NOTICE2, "%s: pickit2_parseextparms(): clockrate set to 0x%02x\n",
+ progname, clock_rate);
+ PDATA(pgm)->clock_period = clock_period;
+
+ continue;
+ }
+
+ if (strncmp(extended_param, "timeout=", strlen("timeout=")) == 0)
+ {
+ int timeout;
+ if (sscanf(extended_param, "timeout=%i", &timeout) != 1 || timeout <= 0)
+ {
+ avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid timeout '%s'\n",
+ progname, extended_param);
+ rv = -1;
+ continue;
+ }
+
+ avrdude_message(MSG_NOTICE2, "%s: pickit2_parseextparms(): usb timeout set to 0x%02x\n",
+ progname, timeout);
+ PDATA(pgm)->transaction_timeout = timeout;
+
+ continue;
+ }
+
+ avrdude_message(MSG_INFO, "%s: pickit2_parseextparms(): invalid extended parameter '%s'\n",
+ progname, extended_param);
+ rv = -1;
+ }
+
+ return rv;
+}
+
+
+void pickit2_initpgm (PROGRAMMER * pgm)
+{
+ /*
+ * mandatory functions - these are called without checking to see
+ * whether they are assigned or not
+ */
+
+ pgm->initialize = pickit2_initialize;
+ pgm->display = pickit2_display;
+ pgm->enable = pickit2_enable;
+ pgm->disable = pickit2_disable;
+ pgm->powerup = pickit2_powerup;
+ pgm->powerdown = pickit2_powerdown;
+ pgm->program_enable = pickit2_program_enable;
+ pgm->chip_erase = pickit2_chip_erase;
+ pgm->open = pickit2_open;
+ pgm->close = pickit2_close;
+
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+
+ /*
+ * predefined functions - these functions have a valid default
+ * implementation. Hence, they don't need to be defined in
+ * the programmer.
+ */
+ //pgm->rdy_led = pickit2_rdy_led;
+ //pgm->err_led = pickit2_err_led;
+ pgm->pgm_led = pickit2_pgm_led;
+ pgm->vfy_led = pickit2_vfy_led;
+
+ /*
+ * optional functions - these are checked to make sure they are
+ * assigned before they are called
+ */
+
+ pgm->cmd = pickit2_cmd;
+ pgm->spi = pickit2_spi;
+ pgm->paged_write = pickit2_paged_write;
+ pgm->paged_load = pickit2_paged_load;
+ //pgm->write_setup = NULL;
+ //pgm->read_sig_bytes = NULL;
+ //pgm->set_vtarget = NULL;//pickit2_vtarget;
+ //pgm->set_varef = NULL;
+ //pgm->set_fosc = NULL;
+ //pgm->perform_osccal = NULL;
+
+ pgm->parseextparams = pickit2_parseextparams;
+
+ pgm->setup = pickit2_setup;
+ pgm->teardown = pickit2_teardown;
+ // pgm->page_size = 256; // not sure what this does... maybe the max page size that the page read/write function can handle
+
+ strncpy(pgm->type, "pickit2", sizeof(pgm->type));
+}
+#else
+static int pickit2_nousb_open (struct programmer_t *pgm, char * name) {
+ avrdude_message(MSG_INFO,
+#ifdef WIN32NATIVE
+ "%s: error: no usb or hid support. Please compile again with libusb or HID support from Win32 DDK installed.\n",
+#else
+ "%s: error: no usb support. Please compile again with libusb installed.\n",
+#endif
+ progname);
+
+ return -1;
+}
+
+void pickit2_initpgm (PROGRAMMER * pgm)
+{
+ /*
+ * mandatory functions - these are called without checking to see
+ * whether they are assigned or not
+ */
+
+ pgm->open = pickit2_nousb_open;
+
+ strncpy(pgm->type, "pickit2", sizeof(pgm->type));
+}
+
+#endif /* defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) */
+
+const char pickit2_desc[] = "Microchip's PICkit2 Programmer";
+
diff --git a/xs/src/avrdude/pickit2.h b/xs/src/avrdude/pickit2.h
new file mode 100644
index 000000000..cdd58d96d
--- /dev/null
+++ b/xs/src/avrdude/pickit2.h
@@ -0,0 +1,35 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2006 Thomas Fischl
+ *
+ * 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: pickit2.h 2010-05-03 dbrown $ */
+
+#ifndef pickit2_h
+#define pickit2_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char pickit2_desc[];
+void pickit2_initpgm (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // pickit2_h
diff --git a/xs/src/avrdude/pindefs.c b/xs/src/avrdude/pindefs.c
new file mode 100644
index 000000000..5753fc67b
--- /dev/null
+++ b/xs/src/avrdude/pindefs.c
@@ -0,0 +1,370 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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: pindefs.h 1132 2013-01-09 19:23:30Z rliebscher $ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+/**
+ * Adds a pin in the pin definition as normal or inverse pin.
+ *
+ * @param[out] pindef pin definition to update
+ * @param[in] pin number of pin [0..PIN_MAX]
+ * @param[in] inverse inverse (true) or normal (false) pin
+ */
+void pin_set_value(struct pindef_t * const pindef, const int pin, const bool inverse) {
+
+ pindef->mask[pin / PIN_FIELD_ELEMENT_SIZE] |= 1 << (pin % PIN_FIELD_ELEMENT_SIZE);
+ if(inverse) {
+ pindef->inverse[pin / PIN_FIELD_ELEMENT_SIZE] |= (1 << (pin % PIN_FIELD_ELEMENT_SIZE));
+ } else {
+ pindef->inverse[pin / PIN_FIELD_ELEMENT_SIZE] &= ~(1 << (pin % PIN_FIELD_ELEMENT_SIZE));
+ }
+}
+
+/**
+ * Clear all defined pins in pindef.
+ *
+ * @param[out] pindef pin definition to clear
+ */
+void pin_clear_all(struct pindef_t * const pindef) {
+ memset(pindef, 0, sizeof(struct pindef_t));
+}
+
+/**
+ * Convert new pin definition to old pin number
+ *
+ * @param[in] pindef new pin definition structure
+ * @param[out] pinno old pin definition integer
+ */
+static int pin_fill_old_pinno(const struct pindef_t * const pindef, unsigned int * const pinno) {
+ bool found = false;
+ int i;
+ for(i = 0; i < PIN_MAX; i++) {
+ if(pindef->mask[i / PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))) {
+ if(found) {
+ avrdude_message(MSG_INFO, "Multiple pins found\n"); //TODO
+ return -1;
+ }
+ found = true;
+ *pinno = i;
+ if(pindef->inverse[i / PIN_FIELD_ELEMENT_SIZE] & (1 << (i % PIN_FIELD_ELEMENT_SIZE))) {
+ *pinno |= PIN_INVERSE;
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * Convert new pin definition to old pinlist, does not support mixed inverted/non-inverted pin
+ *
+ * @param[in] pindef new pin definition structure
+ * @param[out] pinno old pin definition integer
+ */
+static int pin_fill_old_pinlist(const struct pindef_t * const pindef, unsigned int * const pinno) {
+ int i;
+
+ for(i = 0; i < PIN_FIELD_SIZE; i++) {
+ if(i == 0) {
+ if((pindef->mask[i] & ~PIN_MASK) != 0) {
+ avrdude_message(MSG_INFO, "Pins of higher index than max field size for old pinno found\n");
+ return -1;
+ }
+ if (pindef->mask[i] == 0) {
+ /* this pin function is not using any pins */
+ *pinno = 0;
+ } else if(pindef->mask[i] == pindef->inverse[i]) { /* all set bits in mask are set in inverse */
+ *pinno = pindef->mask[i];
+ *pinno |= PIN_INVERSE;
+ } else if(pindef->mask[i] == ((~pindef->inverse[i]) & pindef->mask[i])) { /* all set bits in mask are cleared in inverse */
+ *pinno = pindef->mask[i];
+ } else {
+ avrdude_message(MSG_INFO, "pins have different polarity set\n");
+ return -1;
+ }
+ } else if(pindef->mask[i] != 0) {
+ avrdude_message(MSG_INFO, "Pins have higher number than fit in old format\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+/**
+ * Convert for given programmer new pin definitions to old pin definitions.
+ *
+ * @param[inout] pgm programmer whose pins shall be converted.
+ */
+int pgm_fill_old_pins(struct programmer_t * const pgm) {
+
+ if (pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_VCC]), &(pgm->pinno[PPI_AVR_VCC])) < 0)
+ return -1;
+ if (pin_fill_old_pinlist(&(pgm->pin[PPI_AVR_BUFF]), &(pgm->pinno[PPI_AVR_BUFF])) < 0)
+ return -1;
+ if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_RESET]), &(pgm->pinno[PIN_AVR_RESET])) < 0)
+ return -1;
+ if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_SCK]), &(pgm->pinno[PIN_AVR_SCK])) < 0)
+ return -1;
+ if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_MOSI]), &(pgm->pinno[PIN_AVR_MOSI])) < 0)
+ return -1;
+ if (pin_fill_old_pinno(&(pgm->pin[PIN_AVR_MISO]), &(pgm->pinno[PIN_AVR_MISO])) < 0)
+ return -1;
+ if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_ERR]), &(pgm->pinno[PIN_LED_ERR])) < 0)
+ return -1;
+ if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_RDY]), &(pgm->pinno[PIN_LED_RDY])) < 0)
+ return -1;
+ if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_PGM]), &(pgm->pinno[PIN_LED_PGM])) < 0)
+ return -1;
+ if (pin_fill_old_pinno(&(pgm->pin[PIN_LED_VFY]), &(pgm->pinno[PIN_LED_VFY])) < 0)
+ return -1;
+
+ return 0;
+}
+
+/**
+ * This function returns a string representation of pins in the mask eg. 1,3,5-7,9,12
+ * Another execution of this function will overwrite the previous result in the static buffer.
+ * Consecutive pin number are representated as start-end.
+ *
+ * @param[in] pinmask the pin mask for which we want the string representation
+ * @returns pointer to a static string.
+ */
+const char * pinmask_to_str(const pinmask_t * const pinmask) {
+ static char buf[(PIN_MAX + 1) * 5]; // should be enough for PIN_MAX=255
+ char *p = buf;
+ int n;
+ int pin;
+ const char * fmt;
+ int start = -1;
+ int end = -1;
+
+ buf[0] = 0;
+ for(pin = PIN_MIN; pin <= PIN_MAX; pin++) {
+ int index = pin / PIN_FIELD_ELEMENT_SIZE;
+ int bit = pin % PIN_FIELD_ELEMENT_SIZE;
+ if(pinmask[index] & (1 << bit)) {
+ bool output = false;
+ if(start == -1) {
+ output = true;
+ start = pin;
+ end = start;
+ } else if(pin == end + 1) {
+ end = pin;
+ } else {
+ if(start != end) {
+ n = sprintf(p, "-%d", end);
+ p += n;
+ }
+ output = true;
+ start = pin;
+ end = start;
+ }
+ if(output) {
+ fmt = (buf[0] == 0) ? "%d" : ",%d";
+ n = sprintf(p, fmt, pin);
+ p += n;
+ }
+ }
+ }
+ if(start != end) {
+ n = sprintf(p, "-%d", end);
+ p += n;
+ }
+
+ if(buf[0] == 0)
+ return "(no pins)";
+
+ return buf;
+}
+
+
+/**
+ * This function checks all pin of pgm against the constraints given in the checklist.
+ * It checks if
+ * @li any invalid pins are used
+ * @li valid pins are used inverted when not allowed
+ * @li any pins are used by more than one function
+ * @li any mandatory pin is not set all.
+ *
+ * In case of any error it report the wrong function and the pin numbers.
+ * For verbose >= 2 it also reports the possible correct values.
+ * For verbose >=3 it shows also which pins were ok.
+ *
+ * @param[in] pgm the programmer to check
+ * @param[in] checklist the constraint for the pins
+ * @param[in] size the number of entries in checklist
+ * @returns 0 if all pin definitions are valid, -1 otherwise
+ */
+int pins_check(const struct programmer_t * const pgm, const struct pin_checklist_t * const checklist, const int size, bool output) {
+ static const struct pindef_t no_valid_pins = {{0}, {0}}; // default value if check list does not contain anything else
+ int rv = 0; // return value
+ int pinname; // loop counter through pinnames
+ pinmask_t already_used_all[PIN_FIELD_SIZE] = {0}; // collect pin definitions of all pin names for check of double use
+ // loop over all possible pinnames
+ for(pinname = 0; pinname < N_PINS; pinname++) {
+ bool used = false;
+ bool invalid = false;
+ bool inverse = false;
+ int index;
+ int segment;
+ bool mandatory_used = false;
+ pinmask_t invalid_used[PIN_FIELD_SIZE] = {0};
+ pinmask_t inverse_used[PIN_FIELD_SIZE] = {0};
+ pinmask_t already_used[PIN_FIELD_SIZE] = {0};
+ const struct pindef_t * valid_pins = &no_valid_pins;
+ bool is_mandatory = false;
+ bool is_ok = true;
+ //find corresponding check pattern
+ for(index = 0; index < size; index++) {
+ if(checklist[index].pinname == pinname) {
+ valid_pins = checklist[index].valid_pins;
+ is_mandatory = checklist[index].mandatory;
+ break;
+ }
+ }
+
+ for(segment = 0; segment < PIN_FIELD_SIZE; segment++) {
+ // check if for mandatory any pin is defined
+ invalid_used[segment] = pgm->pin[pinname].mask[segment] & ~valid_pins->mask[segment];
+ if(is_mandatory && (0 != (pgm->pin[pinname].mask[segment] & valid_pins->mask[segment]))) {
+ mandatory_used = true;
+ }
+ // check if it does not use any non valid pins
+ invalid_used[segment] = pgm->pin[pinname].mask[segment] & ~valid_pins->mask[segment];
+ if(invalid_used[segment]) {
+ invalid = true;
+ }
+ // check if it does not use any valid pins as inverse if not allowed
+ inverse_used[segment] = pgm->pin[pinname].inverse[segment] & valid_pins->mask[segment] & ~valid_pins->inverse[segment];
+ if(inverse_used[segment]) {
+ inverse = true;
+ }
+ // check if it does not use same pins as other function
+ already_used[segment] = pgm->pin[pinname].mask[segment] & already_used_all[segment];
+ if(already_used[segment]) {
+ used = true;
+ }
+ already_used_all[segment] |= pgm->pin[pinname].mask[segment];
+ }
+ if(invalid) {
+ if(output) {
+ avrdude_message(MSG_INFO, "%s: %s: Following pins are not valid pins for this function: %s\n",
+ progname, avr_pin_name(pinname), pinmask_to_str(invalid_used));
+ avrdude_message(MSG_NOTICE2, "%s: %s: Valid pins for this function are: %s\n",
+ progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->mask));
+ }
+ is_ok = false;
+ }
+ if(inverse) {
+ if(output) {
+ avrdude_message(MSG_INFO, "%s: %s: Following pins are not usable as inverse pins for this function: %s\n",
+ progname, avr_pin_name(pinname), pinmask_to_str(inverse_used));
+ avrdude_message(MSG_NOTICE2, "%s: %s: Valid inverse pins for this function are: %s\n",
+ progname, avr_pin_name(pinname), pinmask_to_str(valid_pins->inverse));
+ }
+ is_ok = false;
+ }
+ if(used) {
+ if(output) {
+ avrdude_message(MSG_INFO, "%s: %s: Following pins are set for other functions too: %s\n",
+ progname, avr_pin_name(pinname), pinmask_to_str(already_used));
+ is_ok = false;
+ }
+ }
+ if(!mandatory_used && is_mandatory && !invalid) {
+ if(output) {
+ avrdude_message(MSG_INFO, "%s: %s: Mandatory pin is not defined.\n",
+ progname, avr_pin_name(pinname));
+ }
+ is_ok = false;
+ }
+ if(!is_ok) {
+ rv = -1;
+ } else if(output) {
+ avrdude_message(MSG_DEBUG, "%s: %s: Pin is ok.\n",
+ progname, avr_pin_name(pinname));
+ }
+ }
+ return rv;
+}
+
+/**
+ * This function returns a string representation of defined pins eg. ~1,2,~4,~5,7
+ * Another execution of this function will overwrite the previous result in the static buffer.
+ *
+ * @param[in] pindef the pin definition for which we want the string representation
+ * @returns pointer to a static string.
+ */
+const char * pins_to_str(const struct pindef_t * const pindef) {
+ static char buf[(PIN_MAX + 1) * 5]; // should be enough for PIN_MAX=255
+ char *p = buf;
+ int n;
+ int pin;
+ const char * fmt;
+
+ buf[0] = 0;
+ for(pin = PIN_MIN; pin <= PIN_MAX; pin++) {
+ int index = pin / PIN_FIELD_ELEMENT_SIZE;
+ int bit = pin % PIN_FIELD_ELEMENT_SIZE;
+ if(pindef->mask[index] & (1 << bit)) {
+ if(pindef->inverse[index] & (1 << bit)) {
+ fmt = (buf[0] == 0) ? "~%d" : ",~%d";
+ } else {
+ fmt = (buf[0] == 0) ? " %d" : ",%d";
+ }
+ n = sprintf(p, fmt, pin);
+ p += n;
+ }
+ }
+
+ if(buf[0] == 0)
+ return " (not used)";
+
+ return buf;
+}
+
+/**
+ * Returns the name of the pin as string.
+ *
+ * @param pinname the pinname which we want as string.
+ * @returns a string with the pinname, or <unknown> if pinname is invalid.
+ */
+const char * avr_pin_name(int pinname) {
+ switch(pinname) {
+ case PPI_AVR_VCC : return "VCC";
+ case PPI_AVR_BUFF : return "BUFF";
+ case PIN_AVR_RESET : return "RESET";
+ case PIN_AVR_SCK : return "SCK";
+ case PIN_AVR_MOSI : return "MOSI";
+ case PIN_AVR_MISO : return "MISO";
+ case PIN_LED_ERR : return "ERRLED";
+ case PIN_LED_RDY : return "RDYLED";
+ case PIN_LED_PGM : return "PGMLED";
+ case PIN_LED_VFY : return "VFYLED";
+ default : return "<unknown>";
+ }
+}
+
+
diff --git a/xs/src/avrdude/ppi.c b/xs/src/avrdude/ppi.c
new file mode 100644
index 000000000..2706b850e
--- /dev/null
+++ b/xs/src/avrdude/ppi.c
@@ -0,0 +1,236 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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$ */
+
+
+#if !defined(WIN32NATIVE)
+
+#include "ac_cfg.h"
+
+#if HAVE_PARPORT
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+# include "freebsd_ppi.h"
+#elif defined(__linux__)
+# include "linux_ppdev.h"
+#elif defined(__sun__) || defined(__sun) /* Solaris */
+# include "solaris_ecpp.h"
+#endif
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "ppi.h"
+
+enum {
+ PPI_READ,
+ PPI_WRITE,
+ PPI_SHADOWREAD
+};
+
+static int ppi_shadow_access(union filedescriptor *fdp, int reg,
+ unsigned char *v, unsigned char action)
+{
+ static unsigned char shadow[3];
+ int shadow_num;
+
+ switch (reg) {
+ case PPIDATA:
+ shadow_num = 0;
+ break;
+ case PPICTRL:
+ shadow_num = 1;
+ break;
+ case PPISTATUS:
+ shadow_num = 2;
+ break;
+ default:
+ avrdude_message(MSG_INFO, "%s: avr_set(): invalid register=%d\n",
+ progname, reg);
+ return -1;
+ break;
+ }
+
+ switch (action) {
+ case PPI_SHADOWREAD:
+ *v = shadow[shadow_num];
+ break;
+ case PPI_READ:
+ DO_PPI_READ(fdp->ifd, reg, v);
+ shadow[shadow_num]=*v;
+ break;
+ case PPI_WRITE:
+ shadow[shadow_num]=*v;
+ DO_PPI_WRITE(fdp->ifd, reg, v);
+ break;
+ }
+ return 0;
+}
+
+/*
+ * set the indicated bit of the specified register.
+ */
+int ppi_set(union filedescriptor *fdp, int reg, int bit)
+{
+ unsigned char v;
+ int rc;
+
+ rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
+ v |= bit;
+ rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
+
+ if (rc)
+ return -1;
+
+ return 0;
+}
+
+
+/*
+ * clear the indicated bit of the specified register.
+ */
+int ppi_clr(union filedescriptor *fdp, int reg, int bit)
+{
+ unsigned char v;
+ int rc;
+
+ rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
+ v &= ~bit;
+ rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
+
+ if (rc)
+ return -1;
+
+ return 0;
+}
+
+
+/*
+ * get the indicated bit of the specified register.
+ */
+int ppi_get(union filedescriptor *fdp, int reg, int bit)
+{
+ unsigned char v;
+ int rc;
+
+ rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
+ v &= bit;
+
+ if (rc)
+ return -1;
+
+ return v; /* v == bit */
+}
+
+/*
+ * toggle the indicated bit of the specified register.
+ */
+int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
+{
+ unsigned char v;
+ int rc;
+
+ rc = ppi_shadow_access(fdp, reg, &v, PPI_SHADOWREAD);
+ v ^= bit;
+ rc |= ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
+
+ if (rc)
+ return -1;
+
+ return 0;
+}
+
+
+/*
+ * get all bits of the specified register.
+ */
+int ppi_getall(union filedescriptor *fdp, int reg)
+{
+ unsigned char v;
+ int rc;
+
+ rc = ppi_shadow_access(fdp, reg, &v, PPI_READ);
+
+ if (rc)
+ return -1;
+
+ return v; /* v == bit */
+}
+
+/*
+ * set all bits of the specified register to val.
+ */
+int ppi_setall(union filedescriptor *fdp, int reg, int val)
+{
+ unsigned char v;
+ int rc;
+
+ v = val;
+ rc = ppi_shadow_access(fdp, reg, &v, PPI_WRITE);
+
+ if (rc)
+ return -1;
+
+ return 0;
+}
+
+
+void ppi_open(char * port, union filedescriptor *fdp)
+{
+ int fd;
+ unsigned char v;
+
+ fd = open(port, O_RDWR);
+ if (fd < 0) {
+ avrdude_message(MSG_INFO, "%s: can't open device \"%s\": %s\n",
+ progname, port, strerror(errno));
+ fdp->ifd = -1;
+ return;
+ }
+
+ ppi_claim (fd);
+
+ /*
+ * Initialize shadow registers
+ */
+
+ ppi_shadow_access (fdp, PPIDATA, &v, PPI_READ);
+ ppi_shadow_access (fdp, PPICTRL, &v, PPI_READ);
+ ppi_shadow_access (fdp, PPISTATUS, &v, PPI_READ);
+
+ fdp->ifd = fd;
+}
+
+
+void ppi_close(union filedescriptor *fdp)
+{
+ ppi_release (fdp->ifd);
+ close(fdp->ifd);
+}
+
+#endif /* HAVE_PARPORT */
+
+#endif /* !WIN32NATIVE */
diff --git a/xs/src/avrdude/ppi.h b/xs/src/avrdude/ppi.h
new file mode 100644
index 000000000..38fc1e8b5
--- /dev/null
+++ b/xs/src/avrdude/ppi.h
@@ -0,0 +1,59 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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 ppi_h
+#define ppi_h
+
+/*
+ * PPI registers
+ */
+enum {
+ PPIDATA,
+ PPICTRL,
+ PPISTATUS
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ppi_get (union filedescriptor *fdp, int reg, int bit);
+
+int ppi_set (union filedescriptor *fdp, int reg, int bit);
+
+int ppi_clr (union filedescriptor *fdp, int reg, int bit);
+
+int ppi_getall (union filedescriptor *fdp, int reg);
+
+int ppi_setall (union filedescriptor *fdp, int reg, int val);
+
+int ppi_toggle (union filedescriptor *fdp, int reg, int bit);
+
+void ppi_open (char * port, union filedescriptor *fdp);
+
+void ppi_close (union filedescriptor *fdp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/xs/src/avrdude/ppiwin.c b/xs/src/avrdude/ppiwin.c
new file mode 100644
index 000000000..7811288c0
--- /dev/null
+++ b/xs/src/avrdude/ppiwin.c
@@ -0,0 +1,417 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003, 2004, 2006
+ * Eric B. Weddington <eweddington@cso.atmel.com>
+ * Copyright 2008, Joerg Wunsch
+ *
+ * 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$ */
+
+/*
+This is the parallel port interface for Windows built using Cygwin.
+
+In the ppi_* functions that access the parallel port registers,
+fd = parallel port address
+reg = register as defined in an enum in ppi.h. This must be converted
+ to a proper offset of the base address.
+*/
+
+
+#include "ac_cfg.h"
+
+#if defined (WIN32NATIVE)
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <windows.h>
+#include <sys/time.h>
+#include <windows.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "ppi.h"
+
+#define DEVICE_LPT1 "lpt1"
+#define DEVICE_LPT2 "lpt2"
+#define DEVICE_LPT3 "lpt3"
+
+#define DEVICE_MAX 3
+
+typedef struct
+{
+ const char *name;
+ int base_address;
+} winpp;
+
+static const winpp winports[DEVICE_MAX] =
+{
+ {DEVICE_LPT1, 0x378},
+ {DEVICE_LPT2, 0x278},
+ {DEVICE_LPT3, 0x3BC},
+};
+
+
+
+
+
+/* FUNCTION PROTOTYPES */
+static int winnt_pp_open(void);
+static unsigned short port_get(union filedescriptor *fdp, int reg);
+static unsigned char reg2offset(int reg);
+static unsigned char inb(unsigned short port);
+static void outb(unsigned char value, unsigned short port);
+
+
+
+/* FUNCTION DEFINITIONS */
+
+void ppi_open(char *port, union filedescriptor *fdp)
+{
+ unsigned char i;
+ int fd;
+
+ fd = winnt_pp_open();
+
+ if(fd < 0)
+ {
+ avrdude_message(MSG_INFO, "%s: can't open device \"giveio\"\n\n", progname);
+ fdp->ifd = -1;
+ return;
+ }
+
+ /* Search the windows port names for a match */
+ fd = -1;
+ for(i = 0; i < DEVICE_MAX; i++)
+ {
+ if(strcmp(winports[i].name, port) == 0)
+ {
+ /* Set the file descriptor with the Windows parallel port base address. */
+ fd = winports[i].base_address;
+ break;
+ }
+ }
+ if(fd == -1)
+ {
+ /*
+ * Supplied port name did not match any of the pre-defined
+ * names. Try interpreting it as a numeric
+ * (hexadecimal/decimal/octal) address.
+ */
+ char *cp;
+
+ fd = strtol(port, &cp, 0);
+ if(*port == '\0' || *cp != '\0')
+ {
+ avrdude_message(MSG_INFO, "%s: port name \"%s\" is neither lpt1/2/3 nor valid number\n",
+ progname, port);
+ fd = -1;
+ }
+ }
+ if(fd < 0)
+ {
+ avrdude_message(MSG_INFO, "%s: can't open device \"%s\"\n\n", progname, port);
+ fdp->ifd = -1;
+ return;
+ }
+
+ fdp->ifd = fd;
+}
+
+
+#define DRIVERNAME "\\\\.\\giveio"
+static int winnt_pp_open(void)
+{
+ // Only try to use giveio under Windows NT/2000/XP.
+ OSVERSIONINFO ver_info;
+
+ memset(&ver_info, 0, sizeof(ver_info));
+
+ ver_info.dwOSVersionInfoSize = sizeof(ver_info);
+
+ if(!GetVersionEx(&ver_info))
+ {
+ return(-1);
+ }
+ else if(ver_info.dwPlatformId == VER_PLATFORM_WIN32_NT)
+ {
+ HANDLE h = CreateFileA(DRIVERNAME,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if(h == INVALID_HANDLE_VALUE)
+ {
+ return(-1);
+ }
+
+ /* Close immediately. The process now has the rights it needs. */
+ if(h != NULL)
+ {
+ CloseHandle(h);
+ }
+ }
+ return(0);
+}
+
+
+
+
+void ppi_close(union filedescriptor *fdp)
+{
+ return;
+}
+
+
+
+/*
+ * set the indicated bit of the specified register.
+ */
+int ppi_set(union filedescriptor *fdp, int reg, int bit)
+{
+ unsigned char v;
+ unsigned short port;
+
+ port = port_get(fdp, reg);
+ v = inb(port);
+ v |= bit;
+ outb(v, port);
+ return 0;
+}
+
+
+/*
+ * clear the indicated bit of the specified register.
+ */
+int ppi_clr(union filedescriptor *fdp, int reg, int bit)
+{
+ unsigned char v;
+ unsigned short port;
+
+ port = port_get(fdp, reg);
+ v = inb(port);
+ v &= ~bit;
+ outb(v, port);
+
+ return 0;
+}
+
+
+/*
+ * get the indicated bit of the specified register.
+ */
+int ppi_get(union filedescriptor *fdp, int reg, int bit)
+{
+ unsigned char v;
+
+ v = inb(port_get(fdp, reg));
+ v &= bit;
+
+ return(v);
+}
+
+
+
+
+/*
+ * toggle the indicated bit of the specified register.
+ */
+int ppi_toggle(union filedescriptor *fdp, int reg, int bit)
+{
+ unsigned char v;
+ unsigned short port;
+
+ port = port_get(fdp, reg);
+
+ v = inb(port);
+ v ^= bit;
+ outb(v, port);
+
+ return 0;
+}
+
+
+/*
+ * get all bits of the specified register.
+ */
+int ppi_getall(union filedescriptor *fdp, int reg)
+{
+ unsigned char v;
+
+ v = inb(port_get(fdp, reg));
+
+ return((int)v);
+}
+
+
+
+
+/*
+ * set all bits of the specified register to val.
+ */
+int ppi_setall(union filedescriptor *fdp, int reg, int val)
+{
+ outb((unsigned char)val, port_get(fdp, reg));
+ return 0;
+}
+
+
+
+
+/* Calculate port address to access. */
+static unsigned short port_get(union filedescriptor *fdp, int reg)
+{
+ return((unsigned short)(fdp->ifd + reg2offset(reg)));
+}
+
+
+/* Convert register enum to offset of base address. */
+static unsigned char reg2offset(int reg)
+{
+ unsigned char offset = 0;
+
+ switch(reg)
+ {
+ case PPIDATA:
+ {
+ offset = 0;
+ break;
+ }
+ case PPISTATUS:
+ {
+ offset = 1;
+ break;
+ }
+ case PPICTRL:
+ {
+ offset = 2;
+ break;
+ }
+ }
+
+ return(offset);
+}
+
+
+/* Read in value from port. */
+static unsigned char inb(unsigned short port)
+{
+ unsigned char t;
+
+ asm volatile ("in %1, %0"
+ : "=a" (t)
+ : "d" (port));
+
+ return t;
+}
+
+
+/* Write value to port. */
+static void outb(unsigned char value, unsigned short port)
+{
+ asm volatile ("out %1, %0"
+ :
+ : "d" (port), "a" (value) );
+
+ return;
+}
+
+#if !defined(HAVE_GETTIMEOFDAY)
+struct timezone;
+int gettimeofday(struct timeval *tv, struct timezone *unused){
+// i've found only ms resolution, avrdude expects us
+
+ SYSTEMTIME st;
+ GetSystemTime(&st);
+
+ tv->tv_sec=(long)(st.wSecond+st.wMinute*60+st.wHour*3600);
+ tv->tv_usec=(long)(st.wMilliseconds*1000);
+
+ return 0;
+}
+#endif /* HAVE_GETTIMEOFDAY */
+
+// #define W32USLEEPDBG
+
+#ifdef W32USLEEPDBG
+
+# define DEBUG_QueryPerformanceCounter(arg) QueryPerformanceCounter(arg)
+# define DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf) \
+ do { \
+ unsigned long dt; \
+ dt = (unsigned long)((stop.QuadPart - start.QuadPart) * 1000 * 1000 \
+ / freq.QuadPart); \
+ avrdude_message(MSG_INFO, \
+ "hpt:%i usleep usec:%lu sleep msec:%lu timed usec:%lu\n", \
+ has_highperf, us, ((us + 999) / 1000), dt); \
+ } while (0)
+
+#else
+
+# define DEBUG_QueryPerformanceCounter(arg)
+# define DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf)
+
+#endif
+
+#if !defined(HAVE_USLEEP)
+int usleep(unsigned int us)
+{
+ int has_highperf;
+ LARGE_INTEGER freq,start,stop,loopend;
+
+ // workaround: although usleep is very precise if using
+ // high-performance-timers there are sometimes problems with
+ // verify - increasing the delay helps sometimes but not
+ // realiably. There must be some other problem. Maybe just
+ // with my test-hardware maybe in the code-base.
+ //// us=(unsigned long) (us*1.5);
+
+ has_highperf=QueryPerformanceFrequency(&freq);
+
+ //has_highperf=0; // debug
+
+ if (has_highperf) {
+ QueryPerformanceCounter(&start);
+ loopend.QuadPart=start.QuadPart+freq.QuadPart*us/(1000*1000);
+ do {
+ QueryPerformanceCounter(&stop);
+ } while (stop.QuadPart<=loopend.QuadPart);
+ }
+ else {
+ DEBUG_QueryPerformanceCounter(&start);
+
+ Sleep(1);
+ Sleep( (DWORD)((us+999)/1000) );
+
+ DEBUG_QueryPerformanceCounter(&stop);
+ }
+
+ DEBUG_DisplayTimingInfo(start, stop, freq, us, has_highperf);
+
+ return 0;
+}
+#endif /* !HAVE_USLEEP */
+
+#endif
+
+
diff --git a/xs/src/avrdude/safemode.c b/xs/src/avrdude/safemode.c
new file mode 100644
index 000000000..b530a5fcb
--- /dev/null
+++ b/xs/src/avrdude/safemode.c
@@ -0,0 +1,318 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * avrdude is Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * This file: Copyright (C) 2005-2007 Colin O'Flynn <coflynn@newae.com>
+ *
+ * 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/>.
+ */
+
+
+#include <stdio.h>
+
+#include "ac_cfg.h"
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+/* This value from ac_cfg.h */
+/*
+ * Writes the specified fuse in fusename (can be "lfuse", "hfuse", or
+ * "efuse") and verifies it. Will try up to tries amount of times
+ * before giving up
+ */
+int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm,
+ AVRPART * p, int tries)
+{
+ AVRMEM * m;
+ unsigned char fuseread;
+ int returnvalue = -1;
+
+ m = avr_locate_mem(p, fusename);
+ if (m == NULL) {
+ return -1;
+ }
+
+ /* Keep trying to write then read back the fuse values */
+ while (tries > 0) {
+ if (avr_write_byte(pgm, p, m, 0, fuse) != 0)
+ {
+ continue;
+ }
+ if (pgm->read_byte(pgm, p, m, 0, &fuseread) != 0)
+ {
+ continue;
+ }
+
+ /* Report information to user if needed */
+ avrdude_message(MSG_NOTICE, "%s: safemode: Wrote %s to %x, read as %x. %d attempts left\n",
+ progname, fusename, fuse, fuseread, tries-1);
+
+ /* If fuse wrote OK, no need to keep going */
+ if (fuse == fuseread) {
+ tries = 0;
+ returnvalue = 0;
+ }
+ tries--;
+ }
+
+ return returnvalue;
+}
+
+/*
+ * Reads the fuses three times, checking that all readings are the
+ * same. This will ensure that the before values aren't in error!
+ */
+int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
+ unsigned char * efuse, unsigned char * fuse,
+ PROGRAMMER * pgm, AVRPART * p)
+{
+
+ unsigned char value;
+ unsigned char fusegood = 0;
+ unsigned char allowfuseread = 1;
+ unsigned char safemode_lfuse;
+ unsigned char safemode_hfuse;
+ unsigned char safemode_efuse;
+ unsigned char safemode_fuse;
+ AVRMEM * m;
+
+ safemode_lfuse = *lfuse;
+ safemode_hfuse = *hfuse;
+ safemode_efuse = *efuse;
+ safemode_fuse = *fuse;
+
+
+ /* Read fuse three times */
+ fusegood = 2; /* If AVR device doesn't support this fuse, don't want
+ to generate a verify error */
+ m = avr_locate_mem(p, "fuse");
+ if (m != NULL) {
+ fusegood = 0; /* By default fuse is a failure */
+ if(pgm->read_byte(pgm, p, m, 0, &safemode_fuse) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 1, fuse value: %x\n",progname, safemode_fuse);
+ if(pgm->read_byte(pgm, p, m, 0, &value) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 2, fuse value: %x\n",progname, value);
+ if (value == safemode_fuse) {
+ if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 3, fuse value: %x\n",progname, value);
+ if (value == safemode_fuse)
+ {
+ fusegood = 1; /* Fuse read OK three times */
+ }
+ }
+ }
+
+ //Programmer does not allow fuse reading.... no point trying anymore
+ if (allowfuseread == 0)
+ {
+ return -5;
+ }
+
+ if (fusegood == 0) {
+ avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read fuse properly. "
+ "Programmer may not be reliable.\n", progname);
+ return -1;
+ }
+ else if (fusegood == 1) {
+ avrdude_message(MSG_NOTICE, "%s: safemode: fuse reads as %X\n", progname, safemode_fuse);
+ }
+
+
+ /* Read lfuse three times */
+ fusegood = 2; /* If AVR device doesn't support this fuse, don't want
+ to generate a verify error */
+ m = avr_locate_mem(p, "lfuse");
+ if (m != NULL) {
+ fusegood = 0; /* By default fuse is a failure */
+ if (pgm->read_byte(pgm, p, m, 0, &safemode_lfuse) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 1, lfuse value: %x\n",progname, safemode_lfuse);
+ if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 2, lfuse value: %x\n",progname, value);
+ if (value == safemode_lfuse) {
+ if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 3, lfuse value: %x\n",progname, value);
+ if (value == safemode_lfuse){
+ fusegood = 1; /* Fuse read OK three times */
+ }
+ }
+ }
+
+ //Programmer does not allow fuse reading.... no point trying anymore
+ if (allowfuseread == 0)
+ {
+ return -5;
+ }
+
+
+ if (fusegood == 0) {
+ avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read lfuse properly. "
+ "Programmer may not be reliable.\n", progname);
+ return -1;
+ }
+ else if (fusegood == 1) {
+ avrdude_message(MSG_DEBUG, "%s: safemode: lfuse reads as %X\n", progname, safemode_lfuse);
+ }
+
+ /* Read hfuse three times */
+ fusegood = 2; /* If AVR device doesn't support this fuse, don't want
+ to generate a verify error */
+ m = avr_locate_mem(p, "hfuse");
+ if (m != NULL) {
+ fusegood = 0; /* By default fuse is a failure */
+ if (pgm->read_byte(pgm, p, m, 0, &safemode_hfuse) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 1, hfuse value: %x\n",progname, safemode_hfuse);
+ if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 2, hfuse value: %x\n",progname, value);
+ if (value == safemode_hfuse) {
+ if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 3, hfuse value: %x\n",progname, value);
+ if (value == safemode_hfuse){
+ fusegood = 1; /* Fuse read OK three times */
+ }
+ }
+ }
+
+ //Programmer does not allow fuse reading.... no point trying anymore
+ if (allowfuseread == 0)
+ {
+ return -5;
+ }
+
+ if (fusegood == 0) {
+ avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read hfuse properly. "
+ "Programmer may not be reliable.\n", progname);
+ return -2;
+ }
+ else if (fusegood == 1){
+ avrdude_message(MSG_NOTICE, "%s: safemode: hfuse reads as %X\n", progname, safemode_hfuse);
+ }
+
+ /* Read efuse three times */
+ fusegood = 2; /* If AVR device doesn't support this fuse, don't want
+ to generate a verify error */
+ m = avr_locate_mem(p, "efuse");
+ if (m != NULL) {
+ fusegood = 0; /* By default fuse is a failure */
+ if (pgm->read_byte(pgm, p, m, 0, &safemode_efuse) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 1, efuse value: %x\n",progname, safemode_efuse);
+ if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 2, efuse value: %x\n",progname, value);
+ if (value == safemode_efuse) {
+ if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
+ {
+ allowfuseread = 0;
+ }
+ avrdude_message(MSG_DEBUG, "%s: safemode read 3, efuse value: %x\n",progname, value);
+ if (value == safemode_efuse){
+ fusegood = 1; /* Fuse read OK three times */
+ }
+ }
+ }
+
+ //Programmer does not allow fuse reading.... no point trying anymore
+ if (allowfuseread == 0)
+ {
+ return -5;
+ }
+
+ if (fusegood == 0) {
+ avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read efuse properly. "
+ "Programmer may not be reliable.\n", progname);
+ return -3;
+ }
+ else if (fusegood == 1) {
+ avrdude_message(MSG_NOTICE, "%s: safemode: efuse reads as %X\n", progname, safemode_efuse);
+ }
+
+ *lfuse = safemode_lfuse;
+ *hfuse = safemode_hfuse;
+ *efuse = safemode_efuse;
+ *fuse = safemode_fuse;
+
+ return 0;
+}
+
+
+/*
+ * This routine will store the current values pointed to by lfuse,
+ * hfuse, and efuse into an internal buffer in this routine when save
+ * is set to 1. When save is 0 (or not 1 really) it will copy the
+ * values from the internal buffer into the locations pointed to be
+ * lfuse, hfuse, and efuse. This allows you to change the fuse bits if
+ * needed from another routine (ie: have it so if user requests fuse
+ * bits are changed, the requested value is now verified
+ */
+int safemode_memfuses (int save, unsigned char * lfuse, unsigned char * hfuse,
+ unsigned char * efuse, unsigned char * fuse)
+{
+ static unsigned char safemode_lfuse = 0xff;
+ static unsigned char safemode_hfuse = 0xff;
+ static unsigned char safemode_efuse = 0xff;
+ static unsigned char safemode_fuse = 0xff;
+
+ switch (save) {
+
+ /* Save the fuses as safemode setting */
+ case 1:
+ safemode_lfuse = *lfuse;
+ safemode_hfuse = *hfuse;
+ safemode_efuse = *efuse;
+ safemode_fuse = *fuse;
+
+ break;
+ /* Read back the fuses */
+ default:
+ *lfuse = safemode_lfuse;
+ *hfuse = safemode_hfuse;
+ *efuse = safemode_efuse;
+ *fuse = safemode_fuse;
+ break;
+ }
+
+ return 0;
+}
diff --git a/xs/src/avrdude/ser_avrdoper.c b/xs/src/avrdude/ser_avrdoper.c
new file mode 100644
index 000000000..71080b7c7
--- /dev/null
+++ b/xs/src/avrdude/ser_avrdoper.c
@@ -0,0 +1,661 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ * Copyright (C) 2006 Christian Starkjohann
+ *
+ * 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$ */
+
+/*
+ * Serial Interface emulation for USB programmer "AVR-Doper" in HID mode.
+ */
+
+#include "ac_cfg.h"
+
+#if defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+/* ------------------------------------------------------------------------ */
+
+/* Numeric constants for 'reportType' parameters */
+#define USB_HID_REPORT_TYPE_INPUT 1
+#define USB_HID_REPORT_TYPE_OUTPUT 2
+#define USB_HID_REPORT_TYPE_FEATURE 3
+
+/* These are the error codes which can be returned by functions of this
+ * module.
+ */
+#define USB_ERROR_NONE 0
+#define USB_ERROR_ACCESS 1
+#define USB_ERROR_NOTFOUND 2
+#define USB_ERROR_BUSY 16
+#define USB_ERROR_IO 5
+
+#define USB_VENDOR_ID 0x16c0
+#define USB_PRODUCT_ID 0x05df
+
+static int reportDataSizes[4] = {13, 29, 61, 125};
+
+static unsigned char avrdoperRxBuffer[280]; /* buffer for receive data */
+static int avrdoperRxLength = 0; /* amount of valid bytes in rx buffer */
+static int avrdoperRxPosition = 0; /* amount of bytes already consumed in rx buffer */
+
+/* ------------------------------------------------------------------------ */
+/* ------------------------------------------------------------------------ */
+/* ------------------------------------------------------------------------ */
+
+#if defined(WIN32NATIVE) && defined(HAVE_LIBHID)
+
+#include <windows.h>
+#include <setupapi.h>
+
+#if defined(HAVE_DDK_HIDSDI_H)
+# include <ddk/hidsdi.h>
+#else
+# include "my_ddk_hidsdi.h"
+#endif
+#include <ddk/hidpi.h>
+
+#ifdef USB_DEBUG
+#define DEBUG_PRINT(arg) printf arg
+#else
+#define DEBUG_PRINT(arg)
+#endif
+
+/* ------------------------------------------------------------------------ */
+
+static void convertUniToAscii(char *buffer)
+{
+ unsigned short *uni = (void *)buffer;
+ char *ascii = buffer;
+
+ while(*uni != 0){
+ if(*uni >= 256){
+ *ascii++ = '?';
+ uni++;
+ }else{
+ *ascii++ = *uni++;
+ }
+ }
+ *ascii++ = 0;
+}
+
+static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
+ int product, char *productName, int usesReportIDs)
+{
+ GUID hidGuid; /* GUID for HID driver */
+ HDEVINFO deviceInfoList;
+ SP_DEVICE_INTERFACE_DATA deviceInfo;
+ SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL;
+ DWORD size;
+ int i, openFlag = 0; /* may be FILE_FLAG_OVERLAPPED */
+ int errorCode = USB_ERROR_NOTFOUND;
+ HANDLE handle = INVALID_HANDLE_VALUE;
+ HIDD_ATTRIBUTES deviceAttributes;
+
+ HidD_GetHidGuid(&hidGuid);
+ deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL,
+ DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
+ deviceInfo.cbSize = sizeof(deviceInfo);
+ for(i=0;;i++){
+ if(handle != INVALID_HANDLE_VALUE){
+ CloseHandle(handle);
+ handle = INVALID_HANDLE_VALUE;
+ }
+ if(!SetupDiEnumDeviceInterfaces(deviceInfoList, 0, &hidGuid, i, &deviceInfo))
+ break; /* no more entries */
+ /* first do a dummy call just to determine the actual size required */
+ SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL);
+ if(deviceDetails != NULL)
+ free(deviceDetails);
+ deviceDetails = malloc(size);
+ deviceDetails->cbSize = sizeof(*deviceDetails);
+ /* this call is for real: */
+ SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails,
+ size, &size, NULL);
+ DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath));
+ /* attempt opening for R/W -- we don't care about devices which can't be accessed */
+ handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ openFlag, NULL);
+ if(handle == INVALID_HANDLE_VALUE){
+ DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError()));
+ /* errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore */
+ continue;
+ }
+ deviceAttributes.Size = sizeof(deviceAttributes);
+ HidD_GetAttributes(handle, &deviceAttributes);
+ DEBUG_PRINT(("device attributes: vid=%d pid=%d\n",
+ deviceAttributes.VendorID, deviceAttributes.ProductID));
+ if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product)
+ continue; /* ignore this device */
+ errorCode = USB_ERROR_NOTFOUND;
+ if(vendorName != NULL && productName != NULL){
+ char buffer[512];
+ if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){
+ DEBUG_PRINT(("error obtaining vendor name\n"));
+ errorCode = USB_ERROR_IO;
+ continue;
+ }
+ convertUniToAscii(buffer);
+ DEBUG_PRINT(("vendorName = \"%s\"\n", buffer));
+ if(strcmp(vendorName, buffer) != 0)
+ continue;
+ if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){
+ DEBUG_PRINT(("error obtaining product name\n"));
+ errorCode = USB_ERROR_IO;
+ continue;
+ }
+ convertUniToAscii(buffer);
+ DEBUG_PRINT(("productName = \"%s\"\n", buffer));
+ if(strcmp(productName, buffer) != 0)
+ continue;
+ }
+ break; /* we have found the device we are looking for! */
+ }
+ SetupDiDestroyDeviceInfoList(deviceInfoList);
+ if(deviceDetails != NULL)
+ free(deviceDetails);
+ if(handle != INVALID_HANDLE_VALUE){
+ fdp->pfd = (void *)handle;
+ errorCode = 0;
+ }
+ return errorCode;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static void usbCloseDevice(union filedescriptor *fdp)
+{
+ CloseHandle((HANDLE)fdp->pfd);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
+{
+ HANDLE handle = (HANDLE)fdp->pfd;
+ BOOLEAN rval = 0;
+ DWORD bytesWritten;
+
+ switch(reportType){
+ case USB_HID_REPORT_TYPE_INPUT:
+ break;
+ case USB_HID_REPORT_TYPE_OUTPUT:
+ rval = WriteFile(handle, buffer, len, &bytesWritten, NULL);
+ break;
+ case USB_HID_REPORT_TYPE_FEATURE:
+ rval = HidD_SetFeature(handle, buffer, len);
+ break;
+ }
+ return rval == 0 ? USB_ERROR_IO : 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
+ char *buffer, int *len)
+{
+ HANDLE handle = (HANDLE)fdp->pfd;
+ BOOLEAN rval = 0;
+ DWORD bytesRead;
+
+ switch(reportType){
+ case USB_HID_REPORT_TYPE_INPUT:
+ buffer[0] = reportNumber;
+ rval = ReadFile(handle, buffer, *len, &bytesRead, NULL);
+ if(rval)
+ *len = bytesRead;
+ break;
+ case USB_HID_REPORT_TYPE_OUTPUT:
+ break;
+ case USB_HID_REPORT_TYPE_FEATURE:
+ buffer[0] = reportNumber;
+ rval = HidD_GetFeature(handle, buffer, *len);
+ break;
+ }
+ return rval == 0 ? USB_ERROR_IO : 0;
+}
+
+/* ------------------------------------------------------------------------ */
+/* ------------------------------------------------------------------------ */
+/* ------------------------------------------------------------------------ */
+
+#else /* !(WIN32NATIVE && HAVE_LIBHID) */
+
+/* ------------------------------------------------------------------------ */
+/* ------------------------------------------------------------------------ */
+/* ------------------------------------------------------------------------ */
+
+#if defined(HAVE_USB_H)
+# include <usb.h>
+#elif defined(HAVE_LUSB0_USB_H)
+# include <lusb0_usb.h>
+#else
+# error "libusb needs either <usb.h> or <lusb0_usb.h>"
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#define USBRQ_HID_GET_REPORT 0x01
+#define USBRQ_HID_SET_REPORT 0x09
+
+static int usesReportIDs;
+
+/* ------------------------------------------------------------------------- */
+
+static int usbGetStringAscii(usb_dev_handle *dev, int index, int langid, char *buf, int buflen)
+{
+ char buffer[256];
+ int rval, i;
+
+ if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
+ (USB_DT_STRING << 8) + index, langid, buffer,
+ sizeof(buffer), 1000)) < 0)
+ return rval;
+ if(buffer[1] != USB_DT_STRING)
+ return 0;
+ if((unsigned char)buffer[0] < rval)
+ rval = (unsigned char)buffer[0];
+ rval /= 2;
+ /* lossy conversion to ISO Latin1 */
+ for(i=1;i<rval;i++){
+ if(i > buflen) /* destination buffer overflow */
+ break;
+ buf[i-1] = buffer[2 * i];
+ if(buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
+ buf[i-1] = '?';
+ }
+ buf[i-1] = 0;
+ return i-1;
+}
+
+static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName,
+ int product, char *productName, int doReportIDs)
+{
+ struct usb_bus *bus;
+ struct usb_device *dev;
+ usb_dev_handle *handle = NULL;
+ int errorCode = USB_ERROR_NOTFOUND;
+ static int didUsbInit = 0;
+
+ if(!didUsbInit){
+ usb_init();
+ didUsbInit = 1;
+ }
+ usb_find_busses();
+ usb_find_devices();
+ for(bus=usb_get_busses(); bus; bus=bus->next){
+ for(dev=bus->devices; dev; dev=dev->next){
+ if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){
+ char string[256];
+ int len;
+ handle = usb_open(dev); /* we need to open the device in order to query strings */
+ if(!handle){
+ errorCode = USB_ERROR_ACCESS;
+ avrdude_message(MSG_INFO, "Warning: cannot open USB device: %s\n",
+ usb_strerror());
+ continue;
+ }
+ if(vendorName == NULL && productName == NULL){ /* name does not matter */
+ break;
+ }
+ /* now check whether the names match: */
+ len = usbGetStringAscii(handle, dev->descriptor.iManufacturer,
+ 0x0409, string, sizeof(string));
+ if(len < 0){
+ errorCode = USB_ERROR_IO;
+ avrdude_message(MSG_INFO, "Warning: cannot query manufacturer for device: %s\n",
+ usb_strerror());
+ }else{
+ errorCode = USB_ERROR_NOTFOUND;
+ /* avrdude_message(MSG_INFO, "seen device from vendor ->%s<-\n", string); */
+ if(strcmp(string, vendorName) == 0){
+ len = usbGetStringAscii(handle, dev->descriptor.iProduct,
+ 0x0409, string, sizeof(string));
+ if(len < 0){
+ errorCode = USB_ERROR_IO;
+ avrdude_message(MSG_INFO, "Warning: cannot query product for device: %s\n",
+ usb_strerror());
+ }else{
+ errorCode = USB_ERROR_NOTFOUND;
+ /* avrdude_message(MSG_INFO, "seen product ->%s<-\n", string); */
+ if(strcmp(string, productName) == 0)
+ break;
+ }
+ }
+ }
+ usb_close(handle);
+ handle = NULL;
+ }
+ }
+ if(handle)
+ break;
+ }
+ if(handle != NULL){
+ int rval, retries = 3;
+ if(usb_set_configuration(handle, 1)){
+ avrdude_message(MSG_INFO, "Warning: could not set configuration: %s\n",
+ usb_strerror());
+ }
+ /* now try to claim the interface and detach the kernel HID driver on
+ * linux and other operating systems which support the call.
+ */
+ while((rval = usb_claim_interface(handle, 0)) != 0 && retries-- > 0){
+#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
+ if(usb_detach_kernel_driver_np(handle, 0) < 0){
+ avrdude_message(MSG_INFO, "Warning: could not detach kernel HID driver: %s\n",
+ usb_strerror());
+ }
+#endif
+ }
+ if(rval != 0)
+ avrdude_message(MSG_INFO, "Warning: could not claim interface\n");
+/* Continue anyway, even if we could not claim the interface. Control transfers
+ * should still work.
+ */
+ errorCode = 0;
+ fdp->pfd = (void *)handle;
+ usesReportIDs = doReportIDs;
+ }
+ return errorCode;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void usbCloseDevice(union filedescriptor *fdp)
+{
+ usb_close((usb_dev_handle *)fdp->pfd);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int usbSetReport(union filedescriptor *fdp, int reportType, char *buffer, int len)
+{
+ int bytesSent;
+
+ if(!usesReportIDs){
+ buffer++; /* skip dummy report ID */
+ len--;
+ }
+ bytesSent = usb_control_msg((usb_dev_handle *)fdp->pfd, USB_TYPE_CLASS |
+ USB_RECIP_INTERFACE | USB_ENDPOINT_OUT, USBRQ_HID_SET_REPORT,
+ reportType << 8 | buffer[0], 0, buffer, len, 5000);
+ if(bytesSent != len){
+ if(bytesSent < 0)
+ avrdude_message(MSG_INFO, "Error sending message: %s\n", usb_strerror());
+ return USB_ERROR_IO;
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int usbGetReport(union filedescriptor *fdp, int reportType, int reportNumber,
+ char *buffer, int *len)
+{
+ int bytesReceived, maxLen = *len;
+
+ if(!usesReportIDs){
+ buffer++; /* make room for dummy report ID */
+ maxLen--;
+ }
+ bytesReceived = usb_control_msg((usb_dev_handle *)fdp->pfd, USB_TYPE_CLASS |
+ USB_RECIP_INTERFACE | USB_ENDPOINT_IN, USBRQ_HID_GET_REPORT,
+ reportType << 8 | reportNumber, 0, buffer, maxLen, 5000);
+ if(bytesReceived < 0){
+ avrdude_message(MSG_INFO, "Error sending message: %s\n", usb_strerror());
+ return USB_ERROR_IO;
+ }
+ *len = bytesReceived;
+ if(!usesReportIDs){
+ buffer[-1] = reportNumber; /* add dummy report ID */
+ len++;
+ }
+ return 0;
+}
+
+#endif /* WIN32NATIVE */
+
+/* ------------------------------------------------------------------------ */
+/* ------------------------------------------------------------------------ */
+/* ------------------------------------------------------------------------ */
+
+/* ------------------------------------------------------------------------- */
+
+static void dumpBlock(const char *prefix, const unsigned char *buf, int len)
+{
+ int i;
+
+ if(len <= 8){ /* more compact format for short blocks */
+ avrdude_message(MSG_INFO, "%s: %d bytes: ", prefix, len);
+ for(i = 0; i < len; i++){
+ avrdude_message(MSG_INFO, "%02x ", buf[i]);
+ }
+ avrdude_message(MSG_INFO, " \"");
+ for(i = 0; i < len; i++){
+ if(buf[i] >= 0x20 && buf[i] < 0x7f){
+ fputc(buf[i], stderr);
+ }else{
+ fputc('.', stderr);
+ }
+ }
+ avrdude_message(MSG_INFO, "\"\n");
+ }else{
+ avrdude_message(MSG_INFO, "%s: %d bytes:\n", prefix, len);
+ while(len > 0){
+ for(i = 0; i < 16; i++){
+ if(i < len){
+ avrdude_message(MSG_INFO, "%02x ", buf[i]);
+ }else{
+ avrdude_message(MSG_INFO, " ");
+ }
+ if(i == 7)
+ fputc(' ', stderr);
+ }
+ avrdude_message(MSG_INFO, " \"");
+ for(i = 0; i < 16; i++){
+ if(i < len){
+ if(buf[i] >= 0x20 && buf[i] < 0x7f){
+ fputc(buf[i], stderr);
+ }else{
+ fputc('.', stderr);
+ }
+ }
+ }
+ avrdude_message(MSG_INFO, "\"\n");
+ buf += 16;
+ len -= 16;
+ }
+ }
+}
+
+static char *usbErrorText(int usbErrno)
+{
+ static char buffer[32];
+
+ switch(usbErrno){
+ case USB_ERROR_NONE: return "Success.";
+ case USB_ERROR_ACCESS: return "Access denied.";
+ case USB_ERROR_NOTFOUND:return "Device not found.";
+ case USB_ERROR_BUSY: return "Device is busy.";
+ case USB_ERROR_IO: return "I/O Error.";
+ default:
+ sprintf(buffer, "Unknown error %d.", usbErrno);
+ return buffer;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int avrdoper_open(char *port, union pinfo pinfo, union filedescriptor *fdp)
+{
+ int rval;
+ char *vname = "obdev.at";
+ char *devname = "AVR-Doper";
+
+ rval = usbOpenDevice(fdp, USB_VENDOR_ID, vname, USB_PRODUCT_ID, devname, 1);
+ if(rval != 0){
+ avrdude_message(MSG_INFO, "%s: avrdoper_open(): %s\n", progname, usbErrorText(rval));
+ return -1;
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void avrdoper_close(union filedescriptor *fdp)
+{
+ usbCloseDevice(fdp);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int chooseDataSize(int len)
+{
+ int i;
+
+ for(i = 0; i < sizeof(reportDataSizes)/sizeof(reportDataSizes[0]); i++){
+ if(reportDataSizes[i] >= len)
+ return i;
+ }
+ return i - 1;
+}
+
+static int avrdoper_send(union filedescriptor *fdp, const unsigned char *buf, size_t buflen)
+{
+ if(verbose > 3)
+ dumpBlock("Send", buf, buflen);
+ while(buflen > 0){
+ unsigned char buffer[256];
+ int rval, lenIndex = chooseDataSize(buflen);
+ int thisLen = buflen > reportDataSizes[lenIndex] ?
+ reportDataSizes[lenIndex] : buflen;
+ buffer[0] = lenIndex + 1; /* report ID */
+ buffer[1] = thisLen;
+ memcpy(buffer + 2, buf, thisLen);
+ avrdude_message(MSG_TRACE, "Sending %d bytes data chunk\n", thisLen);
+ rval = usbSetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, (char *)buffer,
+ reportDataSizes[lenIndex] + 2);
+ if(rval != 0){
+ avrdude_message(MSG_INFO, "%s: avrdoper_send(): %s\n", progname, usbErrorText(rval));
+ return -1;
+ }
+ buflen -= thisLen;
+ buf += thisLen;
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int avrdoperFillBuffer(union filedescriptor *fdp)
+{
+ int bytesPending = reportDataSizes[1]; /* guess how much data is buffered in device */
+
+ avrdoperRxPosition = avrdoperRxLength = 0;
+ while(bytesPending > 0){
+ int len, usbErr, lenIndex = chooseDataSize(bytesPending);
+ unsigned char buffer[128];
+ len = sizeof(avrdoperRxBuffer) - avrdoperRxLength; /* bytes remaining */
+ if(reportDataSizes[lenIndex] + 2 > len) /* requested data would not fit into buffer */
+ break;
+ len = reportDataSizes[lenIndex] + 2;
+ usbErr = usbGetReport(fdp, USB_HID_REPORT_TYPE_FEATURE, lenIndex + 1,
+ (char *)buffer, &len);
+ if(usbErr != 0){
+ avrdude_message(MSG_INFO, "%s: avrdoperFillBuffer(): %s\n", progname, usbErrorText(usbErr));
+ return -1;
+ }
+ avrdude_message(MSG_TRACE, "Received %d bytes data chunk of total %d\n", len - 2, buffer[1]);
+ len -= 2; /* compensate for report ID and length byte */
+ bytesPending = buffer[1] - len; /* amount still buffered */
+ if(len > buffer[1]) /* cut away padding */
+ len = buffer[1];
+ if(avrdoperRxLength + len > sizeof(avrdoperRxBuffer)){
+ avrdude_message(MSG_INFO, "%s: avrdoperFillBuffer(): internal error: buffer overflow\n",
+ progname);
+ return -1;
+ }
+ memcpy(avrdoperRxBuffer + avrdoperRxLength, buffer + 2, len);
+ avrdoperRxLength += len;
+ }
+ return 0;
+}
+
+static int avrdoper_recv(union filedescriptor *fdp, unsigned char *buf, size_t buflen)
+{
+ unsigned char *p = buf;
+ int remaining = buflen;
+
+ while(remaining > 0){
+ int len, available = avrdoperRxLength - avrdoperRxPosition;
+ if(available <= 0){ /* buffer is empty */
+ if (avrdoperFillBuffer(fdp) < 0)
+ return -1;
+ continue;
+ }
+ len = remaining < available ? remaining : available;
+ memcpy(p, avrdoperRxBuffer + avrdoperRxPosition, len);
+ p += len;
+ remaining -= len;
+ avrdoperRxPosition += len;
+ }
+ if(verbose > 3)
+ dumpBlock("Receive", buf, buflen);
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int avrdoper_drain(union filedescriptor *fdp, int display)
+{
+ do{
+ if (avrdoperFillBuffer(fdp) < 0)
+ return -1;
+ }while(avrdoperRxLength > 0);
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int avrdoper_set_dtr_rts(union filedescriptor *fdp, int is_on)
+{
+ avrdude_message(MSG_INFO, "%s: AVR-Doper doesn't support DTR/RTS setting\n", progname);
+ return -1;
+}
+
+/* ------------------------------------------------------------------------- */
+
+struct serial_device avrdoper_serdev =
+{
+ .open = avrdoper_open,
+ .close = avrdoper_close,
+ .send = avrdoper_send,
+ .recv = avrdoper_recv,
+ .drain = avrdoper_drain,
+ .set_dtr_rts = avrdoper_set_dtr_rts,
+ .flags = SERDEV_FL_NONE,
+};
+
+#endif /* defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID)) */
diff --git a/xs/src/avrdude/ser_posix.c b/xs/src/avrdude/ser_posix.c
new file mode 100644
index 000000000..cb0fc0385
--- /dev/null
+++ b/xs/src/avrdude/ser_posix.c
@@ -0,0 +1,524 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003-2004 Theodore A. Roth <troth@openavr.org>
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+
+/*
+ * Posix serial interface for avrdude.
+ */
+
+#if !defined(WIN32NATIVE)
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+#include <fcntl.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+long serial_recv_timeout = 5000; /* ms */
+#define MAX_ZERO_READS 512
+
+struct baud_mapping {
+ long baud;
+ speed_t speed;
+};
+
+/* There are a lot more baud rates we could handle, but what's the point? */
+
+static struct baud_mapping baud_lookup_table [] = {
+ { 1200, B1200 },
+ { 2400, B2400 },
+ { 4800, B4800 },
+ { 9600, B9600 },
+ { 19200, B19200 },
+ { 38400, B38400 },
+#ifdef B57600
+ { 57600, B57600 },
+#endif
+#ifdef B115200
+ { 115200, B115200 },
+#endif
+#ifdef B230400
+ { 230400, B230400 },
+#endif
+ { 0, 0 } /* Terminator. */
+};
+
+static struct termios original_termios;
+static int saved_original_termios;
+
+static speed_t serial_baud_lookup(long baud)
+{
+ struct baud_mapping *map = baud_lookup_table;
+
+ while (map->baud) {
+ if (map->baud == baud)
+ return map->speed;
+ map++;
+ }
+
+ /*
+ * If a non-standard BAUD rate is used, issue
+ * a warning (if we are verbose) and return the raw rate
+ */
+ avrdude_message(MSG_NOTICE, "%s: serial_baud_lookup(): Using non-standard baud rate: %ld",
+ progname, baud);
+
+ return baud;
+}
+
+static int ser_setspeed(union filedescriptor *fd, long baud)
+{
+ int rc;
+ struct termios termios;
+ speed_t speed = serial_baud_lookup (baud);
+
+ if (!isatty(fd->ifd))
+ return -ENOTTY;
+
+ /*
+ * initialize terminal modes
+ */
+ rc = tcgetattr(fd->ifd, &termios);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcgetattr() failed",
+ progname);
+ return -errno;
+ }
+
+ /*
+ * copy termios for ser_close if we haven't already
+ */
+ if (! saved_original_termios++) {
+ original_termios = termios;
+ }
+
+ termios.c_iflag = IGNBRK;
+ termios.c_oflag = 0;
+ termios.c_lflag = 0;
+ termios.c_cflag = (CS8 | CREAD | CLOCAL);
+ termios.c_cc[VMIN] = 1;
+ termios.c_cc[VTIME] = 0;
+
+ cfsetospeed(&termios, speed);
+ cfsetispeed(&termios, speed);
+
+ rc = tcsetattr(fd->ifd, TCSANOW, &termios);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: ser_setspeed(): tcsetattr() failed\n",
+ progname);
+ return -errno;
+ }
+
+ /*
+ * Everything is now set up for a local line without modem control
+ * or flow control, so clear O_NONBLOCK again.
+ */
+ rc = fcntl(fd->ifd, F_GETFL, 0);
+ if (rc != -1)
+ fcntl(fd->ifd, F_SETFL, rc & ~O_NONBLOCK);
+
+ return 0;
+}
+
+/*
+ * Given a port description of the form <host>:<port>, open a TCP
+ * connection to the specified destination, which is assumed to be a
+ * terminal/console server with serial parameters configured
+ * appropriately (e. g. 115200-8-N-1 for a STK500.)
+ */
+static int
+net_open(const char *port, union filedescriptor *fdp)
+{
+ char *hstr, *pstr, *end;
+ unsigned int pnum;
+ int fd;
+ struct sockaddr_in sockaddr;
+ struct hostent *hp;
+
+ if ((hstr = strdup(port)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: net_open(): Out of memory!\n",
+ progname);
+ return -1;
+ }
+
+ if (((pstr = strchr(hstr, ':')) == NULL) || (pstr == hstr)) {
+ avrdude_message(MSG_INFO, "%s: net_open(): Mangled host:port string \"%s\"\n",
+ progname, hstr);
+ free(hstr);
+ return -1;
+ }
+
+ /*
+ * Terminate the host section of the description.
+ */
+ *pstr++ = '\0';
+
+ pnum = strtoul(pstr, &end, 10);
+
+ if ((*pstr == '\0') || (*end != '\0') || (pnum == 0) || (pnum > 65535)) {
+ avrdude_message(MSG_INFO, "%s: net_open(): Bad port number \"%s\"\n",
+ progname, pstr);
+ free(hstr);
+ return -1;
+ }
+
+ if ((hp = gethostbyname(hstr)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: net_open(): unknown host \"%s\"\n",
+ progname, hstr);
+ free(hstr);
+ return -1;
+ }
+
+ free(hstr);
+
+ if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+ avrdude_message(MSG_INFO, "%s: net_open(): Cannot open socket: %s\n",
+ progname, strerror(errno));
+ return -1;
+ }
+
+ memset(&sockaddr, 0, sizeof(struct sockaddr_in));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(pnum);
+ memcpy(&(sockaddr.sin_addr.s_addr), hp->h_addr, sizeof(struct in_addr));
+
+ if (connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
+ avrdude_message(MSG_INFO, "%s: net_open(): Connect failed: %s\n",
+ progname, strerror(errno));
+ return -1;
+ }
+
+ fdp->ifd = fd;
+ return 0;
+}
+
+
+static int ser_set_dtr_rts(union filedescriptor *fdp, int is_on)
+{
+ unsigned int ctl;
+ int r;
+
+ r = ioctl(fdp->ifd, TIOCMGET, &ctl);
+ if (r < 0) {
+ perror("ioctl(\"TIOCMGET\")");
+ return -1;
+ }
+
+ if (is_on) {
+ /* Set DTR and RTS */
+ ctl |= (TIOCM_DTR | TIOCM_RTS);
+ }
+ else {
+ /* Clear DTR and RTS */
+ ctl &= ~(TIOCM_DTR | TIOCM_RTS);
+ }
+
+ r = ioctl(fdp->ifd, TIOCMSET, &ctl);
+ if (r < 0) {
+ perror("ioctl(\"TIOCMSET\")");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
+{
+ int rc;
+ int fd;
+
+ /*
+ * If the port is of the form "net:<host>:<port>", then
+ * handle it as a TCP connection to a terminal server.
+ */
+ if (strncmp(port, "net:", strlen("net:")) == 0) {
+ return net_open(port + strlen("net:"), fdp);
+ }
+
+ /*
+ * open the serial port
+ */
+ fd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
+ if (fd < 0) {
+ avrdude_message(MSG_INFO, "%s: ser_open(): can't open device \"%s\": %s\n",
+ progname, port, strerror(errno));
+ return -1;
+ }
+
+ fdp->ifd = fd;
+
+ /*
+ * set serial line attributes
+ */
+ rc = ser_setspeed(fdp, pinfo.baud);
+ if (rc) {
+ avrdude_message(MSG_INFO, "%s: ser_open(): can't set attributes for device \"%s\": %s\n",
+ progname, port, strerror(-rc));
+ close(fd);
+ return -1;
+ }
+ return 0;
+}
+
+
+static void ser_close(union filedescriptor *fd)
+{
+ /*
+ * restore original termios settings from ser_open
+ */
+ if (saved_original_termios) {
+ int rc = tcsetattr(fd->ifd, TCSANOW | TCSADRAIN, &original_termios);
+ if (rc) {
+ avrdude_message(MSG_INFO, "%s: ser_close(): can't reset attributes for device: %s\n",
+ progname, strerror(errno));
+ }
+ saved_original_termios = 0;
+ }
+
+ close(fd->ifd);
+}
+
+
+static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t buflen)
+{
+ int rc;
+ const unsigned char * p = buf;
+ size_t len = buflen;
+
+ if (!len)
+ return 0;
+
+ if (verbose > 3)
+ {
+ avrdude_message(MSG_TRACE, "%s: Send: ", progname);
+
+ while (buflen) {
+ unsigned char c = *buf;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE, "%c ", c);
+ }
+ else {
+ avrdude_message(MSG_TRACE, ". ");
+ }
+ avrdude_message(MSG_TRACE, "[%02x] ", c);
+
+ buf++;
+ buflen--;
+ }
+
+ avrdude_message(MSG_TRACE, "\n");
+ }
+
+ while (len) {
+ RETURN_IF_CANCEL();
+ rc = write(fd->ifd, p, (len > 1024) ? 1024 : len);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: ser_send(): write error: %s\n",
+ progname, strerror(errno));
+ return -1;
+ }
+ p += rc;
+ len -= rc;
+ }
+
+ return 0;
+}
+
+
+static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
+{
+ struct timeval timeout, to2;
+ fd_set rfds;
+ int nfds;
+ int rc;
+ unsigned char * p = buf;
+ size_t len = 0;
+ unsigned zero_reads = 0;
+
+ timeout.tv_sec = serial_recv_timeout / 1000L;
+ timeout.tv_usec = (serial_recv_timeout % 1000L) * 1000;
+ to2 = timeout;
+
+ while (len < buflen) {
+ reselect:
+ RETURN_IF_CANCEL();
+ FD_ZERO(&rfds);
+ FD_SET(fd->ifd, &rfds);
+
+ nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &to2);
+ // FIXME: The timeout has different behaviour on Linux vs other Unices
+ // On Linux, the timeout is modified by subtracting the time spent,
+ // on OS X (for example), it is not modified.
+ // POSIX recommends re-initializing it before selecting.
+ if (nfds == 0) {
+ avrdude_message(MSG_NOTICE2, "%s: ser_recv(): programmer is not responding\n",
+ progname);
+ return -1;
+ }
+ else if (nfds == -1) {
+ if (errno == EINTR || errno == EAGAIN) {
+ avrdude_message(MSG_INFO, "%s: ser_recv(): programmer is not responding,reselecting\n",
+ progname);
+ goto reselect;
+ }
+ else {
+ avrdude_message(MSG_INFO, "%s: ser_recv(): select(): %s\n",
+ progname, strerror(errno));
+ return -1;
+ }
+ }
+
+ rc = read(fd->ifd, p, (buflen - len > 1024) ? 1024 : buflen - len);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: ser_recv(): read error: %s\n",
+ progname, strerror(errno));
+ return -1;
+ } else if (rc == 0) {
+ zero_reads++;
+ if (zero_reads > MAX_ZERO_READS) {
+ avrdude_message(MSG_NOTICE2, "%s: ser_recv(): programmer is not responding (too many zero reads)\n",
+ progname);
+ return -1;
+ }
+ } else {
+ zero_reads = 0;
+ p += rc;
+ len += rc;
+ }
+ }
+
+ p = buf;
+
+ if (verbose > 3)
+ {
+ avrdude_message(MSG_TRACE, "%s: Recv: ", progname);
+
+ while (len) {
+ unsigned char c = *p;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE, "%c ", c);
+ }
+ else {
+ avrdude_message(MSG_TRACE, ". ");
+ }
+ avrdude_message(MSG_TRACE, "[%02x] ", c);
+
+ p++;
+ len--;
+ }
+ avrdude_message(MSG_TRACE, "\n");
+ }
+
+ return 0;
+}
+
+
+static int ser_drain(union filedescriptor *fd, int display)
+{
+ struct timeval timeout;
+ fd_set rfds;
+ int nfds;
+ int rc;
+ unsigned char buf;
+ unsigned zero_reads = 0;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 250000;
+
+ if (display) {
+ avrdude_message(MSG_INFO, "drain>");
+ }
+
+ while (1) {
+ FD_ZERO(&rfds);
+ FD_SET(fd->ifd, &rfds);
+
+ reselect:
+ RETURN_IF_CANCEL();
+ nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &timeout);
+ if (nfds == 0) {
+ if (display) {
+ avrdude_message(MSG_INFO, "<drain\n");
+ }
+
+ break;
+ }
+ else if (nfds == -1) {
+ if (errno == EINTR) {
+ goto reselect;
+ }
+ else {
+ avrdude_message(MSG_INFO, "%s: ser_drain(): select(): %s\n",
+ progname, strerror(errno));
+ return -1;
+ }
+ }
+
+ rc = read(fd->ifd, &buf, 1);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: ser_drain(): read error: %s\n",
+ progname, strerror(errno));
+ return -1;
+ } else if (rc == 0) {
+ zero_reads++;
+ if (zero_reads > MAX_ZERO_READS) {
+ avrdude_message(MSG_NOTICE2, "%s: ser_drain(): programmer is not responding (too many zero reads)\n",
+ progname);
+ return -1;
+ }
+ } else {
+ zero_reads = 0;
+ }
+ if (display) {
+ avrdude_message(MSG_INFO, "%02x ", buf);
+ }
+ }
+
+ return 0;
+}
+
+struct serial_device serial_serdev =
+{
+ .open = ser_open,
+ .setspeed = ser_setspeed,
+ .close = ser_close,
+ .send = ser_send,
+ .recv = ser_recv,
+ .drain = ser_drain,
+ .set_dtr_rts = ser_set_dtr_rts,
+ .flags = SERDEV_FL_CANSETSPEED,
+};
+
+struct serial_device *serdev = &serial_serdev;
+
+#endif /* WIN32NATIVE */
diff --git a/xs/src/avrdude/ser_win32.c b/xs/src/avrdude/ser_win32.c
new file mode 100644
index 000000000..4e1713128
--- /dev/null
+++ b/xs/src/avrdude/ser_win32.c
@@ -0,0 +1,709 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003, 2004 Martin J. Thomas <mthomas@rhrk.uni-kl.de>
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+
+/*
+ * Native Win32 serial interface for avrdude.
+ */
+
+#include "ac_cfg.h"
+
+#if defined(WIN32NATIVE)
+
+#ifdef HAVE_LIBWS2_32
+/* winsock2.h must be included before windows.h from avrdude.h... */
+# include <winsock2.h>
+#endif
+
+#include <windows.h>
+#include <stdio.h>
+#include <ctype.h> /* for isprint */
+#include <errno.h> /* ENOTTY */
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+long serial_recv_timeout = 5000; /* ms */
+
+#define W32SERBUFSIZE 1024
+
+struct baud_mapping {
+ long baud;
+ DWORD speed;
+};
+
+static unsigned char serial_over_ethernet = 0;
+
+/* HANDLE hComPort=INVALID_HANDLE_VALUE; */
+
+static struct baud_mapping baud_lookup_table [] = {
+ { 1200, CBR_1200 },
+ { 2400, CBR_2400 },
+ { 4800, CBR_4800 },
+ { 9600, CBR_9600 },
+ { 19200, CBR_19200 },
+ { 38400, CBR_38400 },
+ { 57600, CBR_57600 },
+ { 115200, CBR_115200 },
+ { 0, 0 } /* Terminator. */
+};
+
+static DWORD serial_baud_lookup(long baud)
+{
+ struct baud_mapping *map = baud_lookup_table;
+
+ while (map->baud) {
+ if (map->baud == baud)
+ return map->speed;
+ map++;
+ }
+
+ /*
+ * If a non-standard BAUD rate is used, issue
+ * a warning (if we are verbose) and return the raw rate
+ */
+ avrdude_message(MSG_NOTICE, "%s: serial_baud_lookup(): Using non-standard baud rate: %ld",
+ progname, baud);
+
+ return baud;
+}
+
+
+static BOOL serial_w32SetTimeOut(HANDLE hComPort, DWORD timeout) // in ms
+{
+ COMMTIMEOUTS ctmo;
+ ZeroMemory (&ctmo, sizeof(COMMTIMEOUTS));
+ // Don't use the two other two values, set them to zero. This way a constant timeout is used
+ // for the following reads.
+ // ctmo.ReadIntervalTimeout = timeout;
+ // ctmo.ReadTotalTimeoutMultiplier = timeout;
+ ctmo.ReadTotalTimeoutConstant = timeout;
+
+ return SetCommTimeouts(hComPort, &ctmo);
+}
+
+static int ser_setspeed(union filedescriptor *fd, long baud)
+{
+ if (serial_over_ethernet) {
+ return -ENOTTY;
+ } else {
+ DCB dcb;
+ HANDLE hComPort = (HANDLE)fd->pfd;
+
+ ZeroMemory (&dcb, sizeof(DCB));
+ dcb.DCBlength = sizeof(DCB);
+ dcb.BaudRate = serial_baud_lookup (baud);
+ dcb.fBinary = 1;
+ dcb.fDtrControl = DTR_CONTROL_DISABLE;
+ dcb.fRtsControl = RTS_CONTROL_DISABLE;
+ dcb.ByteSize = 8;
+ dcb.Parity = NOPARITY;
+ dcb.StopBits = ONESTOPBIT;
+
+ if (!SetCommState(hComPort, &dcb))
+ return -1;
+
+ return 0;
+ }
+}
+
+#ifdef HAVE_LIBWS2_32
+static int
+net_open(const char *port, union filedescriptor *fdp)
+{
+ WSADATA wsaData;
+ LPVOID lpMsgBuf;
+
+ char *hstr, *pstr, *end;
+ unsigned int pnum;
+ int fd;
+ struct sockaddr_in sockaddr;
+ struct hostent *hp;
+
+ if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
+ avrdude_message(MSG_INFO, "%s: net_open(): WSAStartup() failed\n", progname);
+ return -1;
+ }
+
+ if ((hstr = strdup(port)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: net_open(): Out of memory!\n", progname);
+ return -1;
+ }
+
+ if (((pstr = strchr(hstr, ':')) == NULL) || (pstr == hstr)) {
+ avrdude_message(MSG_INFO, "%s: net_open(): Mangled host:port string \"%s\"\n", progname, hstr);
+ free(hstr);
+ return -1;
+ }
+
+ /*
+ * Terminate the host section of the description.
+ */
+ *pstr++ = '\0';
+
+ pnum = strtoul(pstr, &end, 10);
+
+ if ((*pstr == '\0') || (*end != '\0') || (pnum == 0) || (pnum > 65535)) {
+ avrdude_message(MSG_INFO, "%s: net_open(): Bad port number \"%s\"\n", progname, pstr);
+ free(hstr);
+ return -1;
+ }
+
+ if ((hp = gethostbyname(hstr)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: net_open(): unknown host \"%s\"\n", progname, hstr);
+ free(hstr);
+ return -1;
+ }
+
+ free(hstr);
+
+ if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ WSAGetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&lpMsgBuf,
+ 0,
+ NULL);
+ avrdude_message(MSG_INFO, "%s: net_open(): Cannot open socket: %s\n", progname, (char *)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ return -1;
+ }
+
+ memset(&sockaddr, 0, sizeof(struct sockaddr_in));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(pnum);
+ memcpy(&(sockaddr.sin_addr.s_addr), hp->h_addr, sizeof(struct in_addr));
+
+ if (connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))) {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ WSAGetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&lpMsgBuf,
+ 0,
+ NULL);
+ avrdude_message(MSG_INFO, "%s: net_open(): Connect failed: %s\n", progname, (char *)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ return -1;
+ }
+
+ fdp->ifd = fd;
+
+ serial_over_ethernet = 1;
+ return 0;
+}
+#endif
+
+
+static int ser_open(char * port, union pinfo pinfo, union filedescriptor *fdp)
+{
+ LPVOID lpMsgBuf;
+ HANDLE hComPort=INVALID_HANDLE_VALUE;
+ char *newname = 0;
+
+ /*
+ * If the port is of the form "net:<host>:<port>", then
+ * handle it as a TCP connection to a terminal server.
+ */
+ if (strncmp(port, "net:", strlen("net:")) == 0) {
+#ifdef HAVE_LIBWS2_32
+ return net_open(port + strlen("net:"), fdp);
+#else
+ avrdude_message(MSG_INFO, "%s: ser_open(): "
+ "not configured for TCP connections\n",
+ progname);
+ return -1;
+#endif
+ }
+
+ if (strncasecmp(port, "com", strlen("com")) == 0) {
+
+ // prepend "\\\\.\\" to name, required for port # >= 10
+ newname = malloc(strlen("\\\\.\\") + strlen(port) + 1);
+
+ if (newname == 0) {
+ // avrdude_message(MSG_INFO, "%s: ser_open(): out of memory\n",
+ // progname);
+ // exit(1);
+ avrdude_oom("ser_open(): out of memory\n");
+ }
+ strcpy(newname, "\\\\.\\");
+ strcat(newname, port);
+
+ port = newname;
+ }
+
+ hComPort = CreateFileA(port, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hComPort == INVALID_HANDLE_VALUE) {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL);
+ avrdude_message(MSG_INFO, "%s: ser_open(): can't open device \"%s\": %s\n",
+ progname, port, (char*)lpMsgBuf);
+ LocalFree( lpMsgBuf );
+ return -1;
+ }
+
+ if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE))
+ {
+ CloseHandle(hComPort);
+ avrdude_message(MSG_INFO, "%s: ser_open(): can't set buffers for \"%s\"\n",
+ progname, port);
+ return -1;
+ }
+
+ fdp->pfd = (void *)hComPort;
+ if (ser_setspeed(fdp, pinfo.baud) != 0)
+ {
+ CloseHandle(hComPort);
+ avrdude_message(MSG_INFO, "%s: ser_open(): can't set com-state for \"%s\"\n",
+ progname, port);
+ return -1;
+ }
+
+ if (!serial_w32SetTimeOut(hComPort,0))
+ {
+ CloseHandle(hComPort);
+ avrdude_message(MSG_INFO, "%s: ser_open(): can't set initial timeout for \"%s\"\n",
+ progname, port);
+ return -1;
+ }
+
+ if (newname != 0) {
+ free(newname);
+ }
+ return 0;
+}
+
+
+static void ser_close(union filedescriptor *fd)
+{
+ if (serial_over_ethernet) {
+#ifdef HAVE_LIBWS2_32
+ closesocket(fd->ifd);
+ WSACleanup();
+#endif
+ } else {
+ HANDLE hComPort=(HANDLE)fd->pfd;
+ if (hComPort != INVALID_HANDLE_VALUE)
+ CloseHandle (hComPort);
+
+ hComPort = INVALID_HANDLE_VALUE;
+ }
+}
+
+static int ser_set_dtr_rts(union filedescriptor *fd, int is_on)
+{
+ if (serial_over_ethernet) {
+ return 0;
+ } else {
+ HANDLE hComPort=(HANDLE)fd->pfd;
+
+ if (is_on) {
+ EscapeCommFunction(hComPort, SETDTR);
+ EscapeCommFunction(hComPort, SETRTS);
+ } else {
+ EscapeCommFunction(hComPort, CLRDTR);
+ EscapeCommFunction(hComPort, CLRRTS);
+ }
+ return 0;
+ }
+}
+
+#ifdef HAVE_LIBWS2_32
+static int net_send(union filedescriptor *fd, const unsigned char * buf, size_t buflen)
+{
+ LPVOID lpMsgBuf;
+ int rc;
+ const unsigned char *p = buf;
+ size_t len = buflen;
+
+ if (fd->ifd < 0) {
+ avrdude_message(MSG_NOTICE, "%s: net_send(): connection not open\n", progname);
+ exit(1);
+ }
+
+ if (!len) {
+ return 0;
+ }
+
+ if (verbose > 3) {
+ avrdude_message(MSG_TRACE, "%s: Send: ", progname);
+
+ while (buflen) {
+ unsigned char c = *buf;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE, "%c ", c);
+ } else {
+ avrdude_message(MSG_TRACE, ". ");
+ }
+ avrdude_message(MSG_TRACE, "[%02x] ", c);
+
+ buf++;
+ buflen--;
+ }
+
+ avrdude_message(MSG_TRACE, "\n");
+ }
+
+ while (len) {
+ rc = send(fd->ifd, p, (len > 1024) ? 1024 : len, 0);
+ if (rc < 0) {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ WSAGetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&lpMsgBuf,
+ 0,
+ NULL);
+ avrdude_message(MSG_INFO, "%s: net_send(): send error: %s\n", progname, (char *)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ exit(1);
+ }
+ p += rc;
+ len -= rc;
+ }
+
+ return 0;
+}
+#endif
+
+
+static int ser_send(union filedescriptor *fd, const unsigned char * buf, size_t buflen)
+{
+#ifdef HAVE_LIBWS2_32
+ if (serial_over_ethernet) {
+ return net_send(fd, buf, buflen);
+ }
+#endif
+
+ size_t len = buflen;
+ unsigned char c='\0';
+ DWORD written;
+ const unsigned char * b = buf;
+
+ RETURN_IF_CANCEL();
+
+ HANDLE hComPort=(HANDLE)fd->pfd;
+
+ if (hComPort == INVALID_HANDLE_VALUE) {
+ avrdude_message(MSG_INFO, "%s: ser_send(): port not open\n",
+ progname);
+ return -1;
+ }
+
+ if (!len)
+ return 0;
+
+ if (verbose > 3)
+ {
+ avrdude_message(MSG_TRACE, "%s: Send: ", progname);
+
+ while (len) {
+ c = *b;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE, "%c ", c);
+ }
+ else {
+ avrdude_message(MSG_TRACE, ". ");
+ }
+ avrdude_message(MSG_TRACE, "[%02x] ", c);
+ b++;
+ len--;
+ }
+ avrdude_message(MSG_INFO, "\n");
+ }
+
+ serial_w32SetTimeOut(hComPort,500);
+
+ if (!WriteFile (hComPort, buf, buflen, &written, NULL)) {
+ avrdude_message(MSG_INFO, "%s: ser_send(): write error: %s\n",
+ progname, "sorry no info avail"); // TODO
+ return -1;
+ }
+
+ if (written != buflen) {
+ avrdude_message(MSG_INFO, "%s: ser_send(): size/send mismatch\n",
+ progname);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+#ifdef HAVE_LIBWS2_32
+static int net_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
+{
+ LPVOID lpMsgBuf;
+ struct timeval timeout, to2;
+ fd_set rfds;
+ int nfds;
+ int rc;
+ unsigned char *p = buf;
+ size_t len = 0;
+
+ if (fd->ifd < 0) {
+ avrdude_message(MSG_INFO, "%s: net_recv(): connection not open\n", progname);
+ exit(1);
+ }
+
+ timeout.tv_sec = serial_recv_timeout / 1000L;
+ timeout.tv_usec = (serial_recv_timeout % 1000L) * 1000;
+ to2 = timeout;
+
+ while (len < buflen) {
+reselect:
+ FD_ZERO(&rfds);
+ FD_SET(fd->ifd, &rfds);
+
+ nfds = select(fd->ifd + 1, &rfds, NULL, NULL, &to2);
+ if (nfds == 0) {
+ if (verbose > 1) {
+ avrdude_message(MSG_NOTICE, "%s: ser_recv(): programmer is not responding\n", progname);
+ }
+ return -1;
+ } else if (nfds == -1) {
+ if (WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEINPROGRESS) {
+ avrdude_message(MSG_NOTICE, "%s: ser_recv(): programmer is not responding, reselecting\n", progname);
+ goto reselect;
+ } else {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ WSAGetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&lpMsgBuf,
+ 0,
+ NULL);
+ avrdude_message(MSG_INFO, "%s: ser_recv(): select(): %s\n", progname, (char *)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ exit(1);
+ }
+ }
+
+ rc = recv(fd->ifd, p, (buflen - len > 1024) ? 1024 : buflen - len, 0);
+ if (rc < 0) {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ WSAGetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&lpMsgBuf,
+ 0,
+ NULL);
+ avrdude_message(MSG_INFO, "%s: ser_recv(): read error: %s\n", progname, (char *)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ exit(1);
+ }
+ p += rc;
+ len += rc;
+ }
+
+ p = buf;
+
+ if (verbose > 3) {
+ avrdude_message(MSG_TRACE, "%s: Recv: ", progname);
+
+ while (len) {
+ unsigned char c = *p;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE, "%c ", c);
+ } else {
+ avrdude_message(MSG_TRACE, ". ");
+ }
+ avrdude_message(MSG_TRACE, "[%02x] ", c);
+
+ p++;
+ len--;
+ }
+ avrdude_message(MSG_TRACE, "\n");
+ }
+
+ return 0;
+}
+#endif
+
+static int ser_recv(union filedescriptor *fd, unsigned char * buf, size_t buflen)
+{
+#ifdef HAVE_LIBWS2_32
+ if (serial_over_ethernet) {
+ return net_recv(fd, buf, buflen);
+ }
+#endif
+
+ unsigned char c;
+ unsigned char * p = buf;
+ DWORD read;
+
+ RETURN_IF_CANCEL();
+
+ HANDLE hComPort=(HANDLE)fd->pfd;
+
+ if (hComPort == INVALID_HANDLE_VALUE) {
+ avrdude_message(MSG_INFO, "%s: ser_read(): port not open\n",
+ progname);
+ return -1;
+ }
+
+ serial_w32SetTimeOut(hComPort, serial_recv_timeout);
+
+ if (!ReadFile(hComPort, buf, buflen, &read, NULL)) {
+ LPVOID lpMsgBuf;
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL );
+ avrdude_message(MSG_INFO, "%s: ser_recv(): read error: %s\n",
+ progname, (char*)lpMsgBuf);
+ LocalFree( lpMsgBuf );
+ return -1;
+ }
+
+ /* time out detected */
+ if (read == 0) {
+ avrdude_message(MSG_NOTICE2, "%s: ser_recv(): programmer is not responding\n",
+ progname);
+ return -1;
+ }
+
+ p = buf;
+
+ if (verbose > 3)
+ {
+ avrdude_message(MSG_TRACE, "%s: Recv: ", progname);
+
+ while (read) {
+ c = *p;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE, "%c ", c);
+ }
+ else {
+ avrdude_message(MSG_TRACE, ". ");
+ }
+ avrdude_message(MSG_TRACE, "[%02x] ", c);
+
+ p++;
+ read--;
+ }
+ avrdude_message(MSG_INFO, "\n");
+ }
+ return 0;
+}
+
+
+static int ser_drain(union filedescriptor *fd, int display)
+{
+ // int rc;
+ unsigned char buf[10];
+ BOOL readres;
+ DWORD read;
+
+ HANDLE hComPort=(HANDLE)fd->pfd;
+
+ if (hComPort == INVALID_HANDLE_VALUE) {
+ avrdude_message(MSG_INFO, "%s: ser_drain(): port not open\n",
+ progname);
+ return -1;
+ }
+
+ serial_w32SetTimeOut(hComPort,250);
+
+ if (display) {
+ avrdude_message(MSG_INFO, "drain>");
+ }
+
+ while (1) {
+ RETURN_IF_CANCEL();
+
+ readres=ReadFile(hComPort, buf, 1, &read, NULL);
+ if (!readres) {
+ LPVOID lpMsgBuf;
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL );
+ avrdude_message(MSG_INFO, "%s: ser_drain(): read error: %s\n",
+ progname, (char*)lpMsgBuf);
+ LocalFree( lpMsgBuf );
+ return -1;
+ }
+
+ if (read) { // data avail
+ if (display) avrdude_message(MSG_INFO, "%02x ", buf[0]);
+ }
+ else { // no more data
+ if (display) avrdude_message(MSG_INFO, "<drain\n");
+ break;
+ }
+ } // while
+ return 0;
+}
+
+struct serial_device serial_serdev =
+{
+ .open = ser_open,
+ .setspeed = ser_setspeed,
+ .close = ser_close,
+ .send = ser_send,
+ .recv = ser_recv,
+ .drain = ser_drain,
+ .set_dtr_rts = ser_set_dtr_rts,
+ .flags = SERDEV_FL_CANSETSPEED,
+};
+
+struct serial_device *serdev = &serial_serdev;
+
+#endif /* WIN32NATIVE */
diff --git a/xs/src/avrdude/serbb.h b/xs/src/avrdude/serbb.h
new file mode 100644
index 000000000..cdb89a366
--- /dev/null
+++ b/xs/src/avrdude/serbb.h
@@ -0,0 +1,37 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.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$ */
+
+#ifndef serbb_h
+#define serbb_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char serbb_desc[];
+void serbb_initpgm (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/xs/src/avrdude/serbb_posix.c b/xs/src/avrdude/serbb_posix.c
new file mode 100644
index 000000000..319cfc9e4
--- /dev/null
+++ b/xs/src/avrdude/serbb_posix.c
@@ -0,0 +1,321 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+
+/*
+ * Posix serial bitbanging interface for avrdude.
+ */
+
+#if !defined(WIN32NATIVE)
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "bitbang.h"
+#include "serbb.h"
+
+#undef DEBUG
+
+static struct termios oldmode;
+
+/*
+ serial port/pin mapping
+
+ 1 cd <-
+ 2 (rxd) <-
+ 3 txd ->
+ 4 dtr ->
+ 5 GND
+ 6 dsr <-
+ 7 rts ->
+ 8 cts <-
+ 9 ri <-
+*/
+
+#define DB9PINS 9
+
+static int serregbits[DB9PINS + 1] =
+{ 0, TIOCM_CD, 0, 0, TIOCM_DTR, 0, TIOCM_DSR, TIOCM_RTS, TIOCM_CTS, TIOCM_RI };
+
+#ifdef DEBUG
+static char *serpins[DB9PINS + 1] =
+ { "NONE", "CD", "RXD", "TXD", "DTR", "GND", "DSR", "RTS", "CTS", "RI" };
+#endif
+
+static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
+{
+ unsigned int ctl;
+ int r;
+ int pin = pgm->pinno[pinfunc]; // get its value
+
+ if (pin & PIN_INVERSE)
+ {
+ value = !value;
+ pin &= PIN_MASK;
+ }
+
+ if ( pin < 1 || pin > DB9PINS )
+ return -1;
+
+#ifdef DEBUG
+ printf("%s to %d\n",serpins[pin],value);
+#endif
+
+ switch ( pin )
+ {
+ case 3: /* txd */
+ r = ioctl(pgm->fd.ifd, value ? TIOCSBRK : TIOCCBRK, 0);
+ if (r < 0) {
+ perror("ioctl(\"TIOCxBRK\")");
+ return -1;
+ }
+ break;
+
+ case 4: /* dtr */
+ case 7: /* rts */
+ r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
+ if (r < 0) {
+ perror("ioctl(\"TIOCMGET\")");
+ return -1;
+ }
+ if ( value )
+ ctl |= serregbits[pin];
+ else
+ ctl &= ~(serregbits[pin]);
+ r = ioctl(pgm->fd.ifd, TIOCMSET, &ctl);
+ if (r < 0) {
+ perror("ioctl(\"TIOCMSET\")");
+ return -1;
+ }
+ break;
+
+ default: /* impossible */
+ return -1;
+ }
+
+ if (pgm->ispdelay > 1)
+ bitbang_delay(pgm->ispdelay);
+
+ return 0;
+}
+
+static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
+{
+ unsigned int ctl;
+ unsigned char invert;
+ int r;
+ int pin = pgm->pinno[pinfunc]; // get its value
+
+ if (pin & PIN_INVERSE)
+ {
+ invert = 1;
+ pin &= PIN_MASK;
+ } else
+ invert = 0;
+
+ if ( pin < 1 || pin > DB9PINS )
+ return(-1);
+
+ switch ( pin )
+ {
+ case 2: /* rxd, currently not implemented, FIXME */
+ return(-1);
+
+ case 1: /* cd */
+ case 6: /* dsr */
+ case 8: /* cts */
+ case 9: /* ri */
+ r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
+ if (r < 0) {
+ perror("ioctl(\"TIOCMGET\")");
+ return -1;
+ }
+ if ( !invert )
+ {
+#ifdef DEBUG
+ printf("%s is %d\n",serpins[pin],(ctl & serregbits[pin]) ? 1 : 0 );
+#endif
+ return ( (ctl & serregbits[pin]) ? 1 : 0 );
+ }
+ else
+ {
+#ifdef DEBUG
+ printf("%s is %d (~)\n",serpins[pin],(ctl & serregbits[pin]) ? 0 : 1 );
+#endif
+ return (( ctl & serregbits[pin]) ? 0 : 1 );
+ }
+
+ default: /* impossible */
+ return(-1);
+ }
+}
+
+static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc)
+{
+ int pin = pgm->pinno[pinfunc]; // replace pin name by its value
+
+ if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS )
+ return -1;
+
+ serbb_setpin(pgm, pinfunc, 1);
+ serbb_setpin(pgm, pinfunc, 0);
+
+ return 0;
+}
+
+
+
+static void serbb_display(PROGRAMMER *pgm, const char *p)
+{
+ /* MAYBE */
+}
+
+static void serbb_enable(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void serbb_disable(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void serbb_powerup(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void serbb_powerdown(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static int serbb_open(PROGRAMMER *pgm, char *port)
+{
+ struct termios mode;
+ int flags;
+ int r;
+
+ if (bitbang_check_prerequisites(pgm) < 0)
+ return -1;
+
+ /* adapted from uisp code */
+
+ pgm->fd.ifd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
+
+ if (pgm->fd.ifd < 0) {
+ perror(port);
+ return(-1);
+ }
+
+ r = tcgetattr(pgm->fd.ifd, &mode);
+ if (r < 0) {
+ avrdude_message(MSG_INFO, "%s: ", port);
+ perror("tcgetattr");
+ return(-1);
+ }
+ oldmode = mode;
+
+ mode.c_iflag = IGNBRK | IGNPAR;
+ mode.c_oflag = 0;
+ mode.c_cflag = CLOCAL | CREAD | CS8 | B9600;
+ mode.c_cc [VMIN] = 1;
+ mode.c_cc [VTIME] = 0;
+
+ r = tcsetattr(pgm->fd.ifd, TCSANOW, &mode);
+ if (r < 0) {
+ avrdude_message(MSG_INFO, "%s: ", port);
+ perror("tcsetattr");
+ return(-1);
+ }
+
+ /* Clear O_NONBLOCK flag. */
+ flags = fcntl(pgm->fd.ifd, F_GETFL, 0);
+ if (flags == -1)
+ {
+ avrdude_message(MSG_INFO, "%s: Can not get flags: %s\n",
+ progname, strerror(errno));
+ return(-1);
+ }
+ flags &= ~O_NONBLOCK;
+ if (fcntl(pgm->fd.ifd, F_SETFL, flags) == -1)
+ {
+ avrdude_message(MSG_INFO, "%s: Can not clear nonblock flag: %s\n",
+ progname, strerror(errno));
+ return(-1);
+ }
+
+ return(0);
+}
+
+static void serbb_close(PROGRAMMER *pgm)
+{
+ if (pgm->fd.ifd != -1)
+ {
+ (void)tcsetattr(pgm->fd.ifd, TCSANOW, &oldmode);
+ pgm->setpin(pgm, PIN_AVR_RESET, 1);
+ close(pgm->fd.ifd);
+ }
+ return;
+}
+
+const char serbb_desc[] = "Serial port bitbanging";
+
+void serbb_initpgm(PROGRAMMER *pgm)
+{
+ strcpy(pgm->type, "SERBB");
+
+ pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
+
+ pgm->rdy_led = bitbang_rdy_led;
+ pgm->err_led = bitbang_err_led;
+ pgm->pgm_led = bitbang_pgm_led;
+ pgm->vfy_led = bitbang_vfy_led;
+ pgm->initialize = bitbang_initialize;
+ pgm->display = serbb_display;
+ pgm->enable = serbb_enable;
+ pgm->disable = serbb_disable;
+ pgm->powerup = serbb_powerup;
+ pgm->powerdown = serbb_powerdown;
+ pgm->program_enable = bitbang_program_enable;
+ pgm->chip_erase = bitbang_chip_erase;
+ pgm->cmd = bitbang_cmd;
+ pgm->cmd_tpi = bitbang_cmd_tpi;
+ pgm->open = serbb_open;
+ pgm->close = serbb_close;
+ pgm->setpin = serbb_setpin;
+ pgm->getpin = serbb_getpin;
+ pgm->highpulsepin = serbb_highpulsepin;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+}
+
+#endif /* WIN32NATIVE */
diff --git a/xs/src/avrdude/serbb_win32.c b/xs/src/avrdude/serbb_win32.c
new file mode 100644
index 000000000..4f1069c85
--- /dev/null
+++ b/xs/src/avrdude/serbb_win32.c
@@ -0,0 +1,366 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003, 2004 Martin J. Thomas <mthomas@rhrk.uni-kl.de>
+ * Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
+ * Copyright (C) 2005, 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+
+/*
+ * Win32 serial bitbanging interface for avrdude.
+ */
+
+#include "avrdude.h"
+
+#if defined(WIN32NATIVE)
+
+
+#include "ac_cfg.h"
+
+#include <windows.h>
+#include <stdio.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "bitbang.h"
+#include "serbb.h"
+
+/* cached status lines */
+static int dtr, rts, txd;
+
+#define W32SERBUFSIZE 1024
+
+/*
+ serial port/pin mapping
+
+ 1 cd <-
+ 2 (rxd) <-
+ 3 txd ->
+ 4 dtr ->
+ 5 GND
+ 6 dsr <-
+ 7 rts ->
+ 8 cts <-
+ 9 ri <-
+*/
+
+#define DB9PINS 9
+
+static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
+{
+ int pin = pgm->pinno[pinfunc];
+ HANDLE hComPort = (HANDLE)pgm->fd.pfd;
+ LPVOID lpMsgBuf;
+ DWORD dwFunc;
+ const char *name;
+
+ if (pin & PIN_INVERSE)
+ {
+ value = !value;
+ pin &= PIN_MASK;
+ }
+
+ if (pin < 1 || pin > DB9PINS)
+ return -1;
+
+ switch (pin)
+ {
+ case 3: /* txd */
+ dwFunc = value? SETBREAK: CLRBREAK;
+ name = value? "SETBREAK": "CLRBREAK";
+ txd = value;
+ break;
+
+ case 4: /* dtr */
+ dwFunc = value? SETDTR: CLRDTR;
+ name = value? "SETDTR": "CLRDTR";
+ dtr = value;
+ break;
+
+ case 7: /* rts */
+ dwFunc = value? SETRTS: CLRRTS;
+ name = value? "SETRTS": "CLRRTS";
+ break;
+
+ default:
+ avrdude_message(MSG_NOTICE, "%s: serbb_setpin(): unknown pin %d\n",
+ progname, pin + 1);
+ return -1;
+ }
+ avrdude_message(MSG_TRACE2, "%s: serbb_setpin(): EscapeCommFunction(%s)\n",
+ progname, name);
+ if (!EscapeCommFunction(hComPort, dwFunc))
+ {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL);
+ avrdude_message(MSG_INFO, "%s: serbb_setpin(): SetCommState() failed: %s\n",
+ progname, (char *)lpMsgBuf);
+ CloseHandle(hComPort);
+ LocalFree(lpMsgBuf);
+ return -1;
+ }
+
+ if (pgm->ispdelay > 1)
+ bitbang_delay(pgm->ispdelay);
+
+ return 0;
+}
+
+static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
+{
+ int pin = pgm->pinno[pinfunc];
+ HANDLE hComPort = (HANDLE)pgm->fd.pfd;
+ LPVOID lpMsgBuf;
+ int invert, rv;
+ const char *name;
+ DWORD modemstate;
+
+ if (pin & PIN_INVERSE)
+ {
+ invert = 1;
+ pin &= PIN_MASK;
+ } else
+ invert = 0;
+
+ if (pin < 1 || pin > DB9PINS)
+ return -1;
+
+ if (pin == 1 /* cd */ || pin == 6 /* dsr */ || pin == 8 /* cts */)
+ {
+ if (!GetCommModemStatus(hComPort, &modemstate))
+ {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL);
+ avrdude_message(MSG_INFO, "%s: serbb_setpin(): GetCommModemStatus() failed: %s\n",
+ progname, (char *)lpMsgBuf);
+ CloseHandle(hComPort);
+ LocalFree(lpMsgBuf);
+ return -1;
+ }
+ avrdude_message(MSG_TRACE2, "%s: serbb_getpin(): GetCommState() => 0x%lx\n",
+ progname, modemstate);
+ switch (pin)
+ {
+ case 1:
+ modemstate &= MS_RLSD_ON;
+ break;
+ case 6:
+ modemstate &= MS_DSR_ON;
+ break;
+ case 8:
+ modemstate &= MS_CTS_ON;
+ break;
+ }
+ rv = modemstate != 0;
+ if (invert)
+ rv = !rv;
+
+ return rv;
+ }
+
+ switch (pin)
+ {
+ case 3: /* txd */
+ rv = txd;
+ name = "TXD";
+ break;
+ case 4: /* dtr */
+ rv = dtr;
+ name = "DTR";
+ break;
+ case 7: /* rts */
+ rv = rts;
+ name = "RTS";
+ break;
+ default:
+ avrdude_message(MSG_NOTICE, "%s: serbb_getpin(): unknown pin %d\n",
+ progname, pin + 1);
+ return -1;
+ }
+ avrdude_message(MSG_TRACE2, "%s: serbb_getpin(): return cached state for %s\n",
+ progname, name);
+ if (invert)
+ rv = !rv;
+
+ return rv;
+}
+
+static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc)
+{
+ int pin = pgm->pinno[pinfunc];
+ if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS )
+ return -1;
+
+ serbb_setpin(pgm, pinfunc, 1);
+ serbb_setpin(pgm, pinfunc, 0);
+
+ return 0;
+}
+
+
+static void serbb_display(PROGRAMMER *pgm, const char *p)
+{
+ /* MAYBE */
+}
+
+static void serbb_enable(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void serbb_disable(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void serbb_powerup(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void serbb_powerdown(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static int serbb_open(PROGRAMMER *pgm, char *port)
+{
+ DCB dcb;
+ LPVOID lpMsgBuf;
+ HANDLE hComPort = INVALID_HANDLE_VALUE;
+
+ if (bitbang_check_prerequisites(pgm) < 0)
+ return -1;
+
+ hComPort = CreateFileA(port, GENERIC_READ | GENERIC_WRITE, 0, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (hComPort == INVALID_HANDLE_VALUE) {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL);
+ avrdude_message(MSG_INFO, "%s: ser_open(): can't open device \"%s\": %s\n",
+ progname, port, (char*)lpMsgBuf);
+ LocalFree(lpMsgBuf);
+ return -1;
+ }
+
+ if (!SetupComm(hComPort, W32SERBUFSIZE, W32SERBUFSIZE))
+ {
+ CloseHandle(hComPort);
+ avrdude_message(MSG_INFO, "%s: ser_open(): can't set buffers for \"%s\"\n",
+ progname, port);
+ return -1;
+ }
+
+
+ ZeroMemory(&dcb, sizeof(DCB));
+ dcb.DCBlength = sizeof(DCB);
+ dcb.BaudRate = CBR_9600;
+ dcb.fBinary = 1;
+ dcb.fDtrControl = DTR_CONTROL_DISABLE;
+ dcb.fRtsControl = RTS_CONTROL_DISABLE;
+ dcb.ByteSize = 8;
+ dcb.Parity = NOPARITY;
+ dcb.StopBits = ONESTOPBIT;
+
+ if (!SetCommState(hComPort, &dcb))
+ {
+ CloseHandle(hComPort);
+ avrdude_message(MSG_INFO, "%s: ser_open(): can't set com-state for \"%s\"\n",
+ progname, port);
+ return -1;
+ }
+ avrdude_message(MSG_DEBUG, "%s: ser_open(): opened comm port \"%s\", handle 0x%x\n",
+ progname, port, (int)hComPort);
+
+ pgm->fd.pfd = (void *)hComPort;
+
+ dtr = rts = txd = 0;
+
+ return 0;
+}
+
+static void serbb_close(PROGRAMMER *pgm)
+{
+ HANDLE hComPort=(HANDLE)pgm->fd.pfd;
+ if (hComPort != INVALID_HANDLE_VALUE)
+ {
+ pgm->setpin(pgm, PIN_AVR_RESET, 1);
+ CloseHandle (hComPort);
+ }
+ avrdude_message(MSG_DEBUG, "%s: ser_close(): closed comm port handle 0x%x\n",
+ progname, (int)hComPort);
+
+ hComPort = INVALID_HANDLE_VALUE;
+}
+
+const char serbb_desc[] = "Serial port bitbanging";
+
+void serbb_initpgm(PROGRAMMER *pgm)
+{
+ strcpy(pgm->type, "SERBB");
+
+ pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
+
+ pgm->rdy_led = bitbang_rdy_led;
+ pgm->err_led = bitbang_err_led;
+ pgm->pgm_led = bitbang_pgm_led;
+ pgm->vfy_led = bitbang_vfy_led;
+ pgm->initialize = bitbang_initialize;
+ pgm->display = serbb_display;
+ pgm->enable = serbb_enable;
+ pgm->disable = serbb_disable;
+ pgm->powerup = serbb_powerup;
+ pgm->powerdown = serbb_powerdown;
+ pgm->program_enable = bitbang_program_enable;
+ pgm->chip_erase = bitbang_chip_erase;
+ pgm->cmd = bitbang_cmd;
+ pgm->cmd_tpi = bitbang_cmd_tpi;
+ pgm->open = serbb_open;
+ pgm->close = serbb_close;
+ pgm->setpin = serbb_setpin;
+ pgm->getpin = serbb_getpin;
+ pgm->highpulsepin = serbb_highpulsepin;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+}
+
+#endif /* WIN32NATIVE */
diff --git a/xs/src/avrdude/solaris_ecpp.h b/xs/src/avrdude/solaris_ecpp.h
new file mode 100644
index 000000000..7db040d14
--- /dev/null
+++ b/xs/src/avrdude/solaris_ecpp.h
@@ -0,0 +1,50 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2005 Joerg Wunsch
+ *
+ * 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 solaris_ecpp_h
+#define solaris_ecpp_h
+
+#include <sys/ecppio.h>
+
+#define ppi_claim(fd) \
+ do { \
+ struct ecpp_transfer_parms p; \
+ (void)ioctl(fd, ECPPIOC_GETPARMS, &p); \
+ p.mode = ECPP_DIAG_MODE; \
+ (void)ioctl(fd, ECPPIOC_SETPARMS, &p); \
+ } while(0);
+
+#define ppi_release(fd)
+
+#define DO_PPI_READ(fd, reg, valp) \
+ do { struct ecpp_regs r; \
+ if ((reg) == PPIDATA) { (void)ioctl(fd, ECPPIOC_GETDATA, valp); } \
+ else { (void)ioctl(fd, ECPPIOC_GETREGS, &r); \
+ *(valp) = ((reg) == PPICTRL)? r.dcr: r.dsr; } \
+ } while(0)
+#define DO_PPI_WRITE(fd, reg, valp) \
+ do { struct ecpp_regs r; \
+ if ((reg) == PPIDATA) { (void)ioctl(fd, ECPPIOC_SETDATA, valp); } \
+ else { if ((reg) == PPICTRL) r.dcr = *(valp); else r.dsr = *(valp); \
+ (void)ioctl(fd, ECPPIOC_SETREGS, &r); } \
+ } while(0)
+
+
+#endif /* solaris_ecpp_h */
diff --git a/xs/src/avrdude/stk500.c b/xs/src/avrdude/stk500.c
new file mode 100644
index 000000000..63deb228f
--- /dev/null
+++ b/xs/src/avrdude/stk500.c
@@ -0,0 +1,1349 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2008,2014 Joerg Wunsch
+ *
+ * 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 Atmel STK500 programmer
+ *
+ * Note: most commands use the "universal command" feature of the
+ * programmer in a "pass through" mode, exceptions are "program
+ * enable", "paged read", and "paged write".
+ *
+ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "stk500.h"
+#include "stk500_private.h"
+
+#define STK500_XTAL 7372800U
+#define MAX_SYNC_ATTEMPTS 10
+
+struct pdata
+{
+ unsigned char ext_addr_byte; /* Record ext-addr byte set in the
+ * target device (if used) */
+};
+
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
+
+static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
+static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value);
+static void stk500_print_parms1(PROGRAMMER * pgm, const char * p);
+
+
+static int stk500_send(PROGRAMMER * pgm, unsigned char * buf, size_t len)
+{
+ return serial_send(&pgm->fd, buf, len);
+}
+
+
+static int stk500_recv(PROGRAMMER * pgm, unsigned char * buf, size_t len)
+{
+ int rv;
+
+ rv = serial_recv(&pgm->fd, buf, len);
+ if (rv < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500_recv(): programmer is not responding\n",
+ progname);
+ return -1;
+ }
+ return 0;
+}
+
+
+int stk500_drain(PROGRAMMER * pgm, int display)
+{
+ return serial_drain(&pgm->fd, display);
+}
+
+
+int stk500_getsync(PROGRAMMER * pgm)
+{
+ unsigned char buf[32], resp[32];
+ int attempt;
+
+ /*
+ * get in sync */
+ buf[0] = Cmnd_STK_GET_SYNC;
+ buf[1] = Sync_CRC_EOP;
+
+ /*
+ * First send and drain a few times to get rid of line noise
+ */
+
+ stk500_send(pgm, buf, 2);
+ stk500_drain(pgm, 0);
+ stk500_send(pgm, buf, 2);
+ stk500_drain(pgm, 0);
+
+ for (attempt = 0; attempt < MAX_SYNC_ATTEMPTS; attempt++) {
+ stk500_send(pgm, buf, 2);
+ stk500_recv(pgm, resp, 1);
+ if (resp[0] == Resp_STK_INSYNC){
+ break;
+ }
+ avrdude_message(MSG_INFO, "%s: stk500_getsync() attempt %d of %d: not in sync: resp=0x%02x\n",
+ progname, attempt + 1, MAX_SYNC_ATTEMPTS, resp[0]);
+ }
+ if (attempt == MAX_SYNC_ATTEMPTS) {
+ stk500_drain(pgm, 0);
+ return -1;
+ }
+
+ if (stk500_recv(pgm, resp, 1) < 0)
+ return -1;
+ if (resp[0] != Resp_STK_OK) {
+ avrdude_message(MSG_INFO, "%s: stk500_getsync(): can't communicate with device: "
+ "resp=0x%02x\n",
+ progname, resp[0]);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * transmit an AVR device command and return the results; 'cmd' and
+ * 'res' must point to at least a 4 byte data buffer
+ */
+static int stk500_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+ unsigned char *res)
+{
+ unsigned char buf[32];
+
+ buf[0] = Cmnd_STK_UNIVERSAL;
+ buf[1] = cmd[0];
+ buf[2] = cmd[1];
+ buf[3] = cmd[2];
+ buf[4] = cmd[3];
+ buf[5] = Sync_CRC_EOP;
+
+ stk500_send(pgm, buf, 6);
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "%s: stk500_cmd(): programmer is out of sync\n", progname);
+ return -1;
+ }
+
+ res[0] = cmd[1];
+ res[1] = cmd[2];
+ res[2] = cmd[3];
+ if (stk500_recv(pgm, &res[3], 1) < 0)
+ return -1;
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] != Resp_STK_OK) {
+ avrdude_message(MSG_INFO, "%s: stk500_cmd(): protocol error\n", progname);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * issue the 'chip erase' command to the AVR device
+ */
+static int stk500_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+
+ if (pgm->cmd == NULL) {
+ avrdude_message(MSG_INFO, "%s: Error: %s programmer uses stk500_chip_erase() but does not\n"
+ "provide a cmd() method.\n",
+ progname, pgm->type);
+ return -1;
+ }
+
+ if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
+ avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
+ p->desc);
+ return -1;
+ }
+
+ pgm->pgm_led(pgm, ON);
+
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
+ pgm->cmd(pgm, cmd, res);
+ usleep(p->chip_erase_delay);
+ pgm->initialize(pgm, p);
+
+ pgm->pgm_led(pgm, OFF);
+
+ return 0;
+}
+
+/*
+ * issue the 'program enable' command to the AVR device
+ */
+static int stk500_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char buf[16];
+ int tries=0;
+
+ retry:
+
+ tries++;
+
+ buf[0] = Cmnd_STK_ENTER_PROGMODE;
+ buf[1] = Sync_CRC_EOP;
+
+ stk500_send(pgm, buf, 2);
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_NOSYNC) {
+ if (tries > 33) {
+ avrdude_message(MSG_INFO, "%s: stk500_program_enable(): can't get into sync\n",
+ progname);
+ return -1;
+ }
+ if (stk500_getsync(pgm) < 0)
+ return -1;
+ goto retry;
+ }
+ else if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "%s: stk500_program_enable(): protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -1;
+ }
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_OK) {
+ return 0;
+ }
+ else if (buf[0] == Resp_STK_NODEVICE) {
+ avrdude_message(MSG_INFO, "%s: stk500_program_enable(): no device\n",
+ progname);
+ return -1;
+ }
+
+ if(buf[0] == Resp_STK_FAILED)
+ {
+ avrdude_message(MSG_INFO, "%s: stk500_program_enable(): failed to enter programming mode\n",
+ progname);
+ return -1;
+ }
+
+
+ avrdude_message(MSG_INFO, "%s: stk500_program_enable(): unknown response=0x%02x\n",
+ progname, buf[0]);
+
+ return -1;
+}
+
+
+
+static int stk500_set_extended_parms(PROGRAMMER * pgm, int n,
+ unsigned char * cmd)
+{
+ unsigned char buf[16];
+ int tries=0;
+ int i;
+
+ retry:
+
+ tries++;
+
+ buf[0] = Cmnd_STK_SET_DEVICE_EXT;
+ for (i=0; i<n; i++) {
+ buf[1+i] = cmd[i];
+ }
+ i++;
+ buf[i] = Sync_CRC_EOP;
+
+ stk500_send(pgm, buf, i+1);
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_NOSYNC) {
+ if (tries > 33) {
+ avrdude_message(MSG_INFO, "%s: stk500_set_extended_parms(): can't get into sync\n",
+ progname);
+ return -1;
+ }
+ if (stk500_getsync(pgm) < 0)
+ return -1;
+ goto retry;
+ }
+ else if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "%s: stk500_set_extended_parms(): protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -1;
+ }
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_OK) {
+ return 0;
+ }
+ else if (buf[0] == Resp_STK_NODEVICE) {
+ avrdude_message(MSG_INFO, "%s: stk500_set_extended_parms(): no device\n",
+ progname);
+ return -1;
+ }
+
+ if(buf[0] == Resp_STK_FAILED)
+ {
+ avrdude_message(MSG_INFO, "%s: stk500_set_extended_parms(): failed to set extended "
+ "device programming parameters\n",
+ progname);
+ return -1;
+ }
+
+
+ avrdude_message(MSG_INFO, "%s: stk500_set_extended_parms(): unknown response=0x%02x\n",
+ progname, buf[0]);
+
+ return -1;
+}
+
+/*
+ * Crossbow MIB510 initialization and shutdown. Use cmd = 1 to
+ * initialize, cmd = 0 to close.
+ */
+static int mib510_isp(PROGRAMMER * pgm, unsigned char cmd)
+{
+ unsigned char buf[9];
+ int tries = 0;
+
+ buf[0] = 0xaa;
+ buf[1] = 0x55;
+ buf[2] = 0x55;
+ buf[3] = 0xaa;
+ buf[4] = 0x17;
+ buf[5] = 0x51;
+ buf[6] = 0x31;
+ buf[7] = 0x13;
+ buf[8] = cmd;
+
+
+ retry:
+
+ tries++;
+
+ stk500_send(pgm, buf, 9);
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_NOSYNC) {
+ if (tries > 33) {
+ avrdude_message(MSG_INFO, "%s: mib510_isp(): can't get into sync\n",
+ progname);
+ return -1;
+ }
+ if (stk500_getsync(pgm) < 0)
+ return -1;
+ goto retry;
+ }
+ else if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "%s: mib510_isp(): protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -1;
+ }
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_OK) {
+ return 0;
+ }
+ else if (buf[0] == Resp_STK_NODEVICE) {
+ avrdude_message(MSG_INFO, "%s: mib510_isp(): no device\n",
+ progname);
+ return -1;
+ }
+
+ if (buf[0] == Resp_STK_FAILED)
+ {
+ avrdude_message(MSG_INFO, "%s: mib510_isp(): command %d failed\n",
+ progname, cmd);
+ return -1;
+ }
+
+
+ avrdude_message(MSG_INFO, "%s: mib510_isp(): unknown response=0x%02x\n",
+ progname, buf[0]);
+
+ return -1;
+}
+
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char buf[32];
+ AVRMEM * m;
+ int tries;
+ unsigned maj, min;
+ int rc;
+ int n_extparms;
+
+ stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);
+ stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);
+
+ // MIB510 does not need extparams
+ if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0)
+ n_extparms = 0;
+ else if ((maj > 1) || ((maj == 1) && (min > 10)))
+ n_extparms = 4;
+ else
+ n_extparms = 3;
+
+ tries = 0;
+
+ retry:
+ tries++;
+
+ memset(buf, 0, sizeof(buf));
+
+ /*
+ * set device programming parameters
+ */
+ buf[0] = Cmnd_STK_SET_DEVICE;
+
+ buf[1] = p->stk500_devcode;
+ buf[2] = 0; /* device revision */
+
+ if ((p->flags & AVRPART_SERIALOK) && (p->flags & AVRPART_PARALLELOK))
+ buf[3] = 0; /* device supports parallel and serial programming */
+ else
+ buf[3] = 1; /* device supports parallel only */
+
+ if (p->flags & AVRPART_PARALLELOK) {
+ if (p->flags & AVRPART_PSEUDOPARALLEL) {
+ buf[4] = 0; /* pseudo parallel interface */
+ n_extparms = 0;
+ }
+ else {
+ buf[4] = 1; /* full parallel interface */
+ }
+ }
+
+#if 0
+ avrdude_message(MSG_INFO, "%s: stk500_initialize(): n_extparms = %d\n",
+ progname, n_extparms);
+#endif
+
+ buf[5] = 1; /* polling supported - XXX need this in config file */
+ buf[6] = 1; /* programming is self-timed - XXX need in config file */
+
+ m = avr_locate_mem(p, "lock");
+ if (m)
+ buf[7] = m->size;
+ else
+ buf[7] = 0;
+
+ /*
+ * number of fuse bytes
+ */
+ buf[8] = 0;
+ m = avr_locate_mem(p, "fuse");
+ if (m)
+ buf[8] += m->size;
+ m = avr_locate_mem(p, "lfuse");
+ if (m)
+ buf[8] += m->size;
+ m = avr_locate_mem(p, "hfuse");
+ if (m)
+ buf[8] += m->size;
+ m = avr_locate_mem(p, "efuse");
+ if (m)
+ buf[8] += m->size;
+
+ m = avr_locate_mem(p, "flash");
+ if (m) {
+ buf[9] = m->readback[0];
+ buf[10] = m->readback[1];
+ if (m->paged) {
+ buf[13] = (m->page_size >> 8) & 0x00ff;
+ buf[14] = m->page_size & 0x00ff;
+ }
+ buf[17] = (m->size >> 24) & 0xff;
+ buf[18] = (m->size >> 16) & 0xff;
+ buf[19] = (m->size >> 8) & 0xff;
+ buf[20] = m->size & 0xff;
+ }
+ else {
+ buf[9] = 0xff;
+ buf[10] = 0xff;
+ buf[13] = 0;
+ buf[14] = 0;
+ buf[17] = 0;
+ buf[18] = 0;
+ buf[19] = 0;
+ buf[20] = 0;
+ }
+
+ m = avr_locate_mem(p, "eeprom");
+ if (m) {
+ buf[11] = m->readback[0];
+ buf[12] = m->readback[1];
+ buf[15] = (m->size >> 8) & 0x00ff;
+ buf[16] = m->size & 0x00ff;
+ }
+ else {
+ buf[11] = 0xff;
+ buf[12] = 0xff;
+ buf[15] = 0;
+ buf[16] = 0;
+ }
+
+ buf[21] = Sync_CRC_EOP;
+
+ stk500_send(pgm, buf, 22);
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_NOSYNC) {
+ avrdude_message(MSG_INFO, "%s: stk500_initialize(): programmer not in sync, resp=0x%02x\n",
+ progname, buf[0]);
+ if (tries > 33)
+ return -1;
+ if (stk500_getsync(pgm) < 0)
+ return -1;
+ goto retry;
+ }
+ else if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "%s: stk500_initialize(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -1;
+ }
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] != Resp_STK_OK) {
+ avrdude_message(MSG_INFO, "%s: stk500_initialize(): (b) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_OK, buf[0]);
+ return -1;
+ }
+
+ if (n_extparms) {
+ if ((p->pagel == 0) || (p->bs2 == 0)) {
+ avrdude_message(MSG_NOTICE2, "%s: PAGEL and BS2 signals not defined in the configuration "
+ "file for part %s, using dummy values\n",
+ progname, p->desc);
+ buf[2] = 0xD7; /* they look somehow possible, */
+ buf[3] = 0xA0; /* don't they? ;) */
+ }
+ else {
+ buf[2] = p->pagel;
+ buf[3] = p->bs2;
+ }
+ buf[0] = n_extparms+1;
+
+ /*
+ * m is currently pointing to eeprom memory if the part has it
+ */
+ if (m)
+ buf[1] = m->page_size;
+ else
+ buf[1] = 0;
+
+
+ if (n_extparms == 4) {
+ if (p->reset_disposition == RESET_DEDICATED)
+ buf[4] = 0;
+ else
+ buf[4] = 1;
+ }
+
+ rc = stk500_set_extended_parms(pgm, n_extparms+1, buf);
+ if (rc) {
+ avrdude_message(MSG_INFO, "%s: stk500_initialize(): failed\n", progname);
+ return -1;
+ }
+ }
+
+ return pgm->program_enable(pgm, p);
+}
+
+
+static void stk500_disable(PROGRAMMER * pgm)
+{
+ unsigned char buf[16];
+ int tries=0;
+
+ retry:
+
+ tries++;
+
+ buf[0] = Cmnd_STK_LEAVE_PROGMODE;
+ buf[1] = Sync_CRC_EOP;
+
+ stk500_send(pgm, buf, 2);
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return;
+ if (buf[0] == Resp_STK_NOSYNC) {
+ if (tries > 33) {
+ avrdude_message(MSG_INFO, "%s: stk500_disable(): can't get into sync\n",
+ progname);
+ return;
+ }
+ if (stk500_getsync(pgm) < 0)
+ return;
+ goto retry;
+ }
+ else if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "%s: stk500_disable(): protocol error, expect=0x%02x, "
+ "resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return;
+ }
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return;
+ if (buf[0] == Resp_STK_OK) {
+ return;
+ }
+ else if (buf[0] == Resp_STK_NODEVICE) {
+ avrdude_message(MSG_INFO, "%s: stk500_disable(): no device\n",
+ progname);
+ return;
+ }
+
+ avrdude_message(MSG_INFO, "%s: stk500_disable(): unknown response=0x%02x\n",
+ progname, buf[0]);
+
+ return;
+}
+
+static void stk500_enable(PROGRAMMER * pgm)
+{
+ return;
+}
+
+
+static int stk500_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;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ stk500_drain(pgm, 0);
+
+ // MIB510 init
+ if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0 &&
+ mib510_isp(pgm, 1) != 0)
+ return -1;
+
+ if (stk500_getsync(pgm) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static void stk500_close(PROGRAMMER * pgm)
+{
+ // MIB510 close
+ if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0)
+ (void)mib510_isp(pgm, 0);
+
+ serial_close(&pgm->fd);
+ pgm->fd.ifd = -1;
+}
+
+
+static int stk500_loadaddr(PROGRAMMER * pgm, AVRMEM * mem, unsigned int addr)
+{
+ unsigned char buf[16];
+ int tries;
+ unsigned char ext_byte;
+ OPCODE * lext;
+
+ tries = 0;
+ retry:
+ tries++;
+
+ /* To support flash > 64K words the correct Extended Address Byte is needed */
+ lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
+ if (lext != NULL) {
+ ext_byte = (addr >> 16) & 0xff;
+ if (ext_byte != PDATA(pgm)->ext_addr_byte) {
+ /* Either this is the first addr load, or a 64K word boundary is
+ * crossed, so set the ext addr byte */
+ avr_set_bits(lext, buf);
+ avr_set_addr(lext, buf, addr);
+ stk500_cmd(pgm, buf, buf);
+ PDATA(pgm)->ext_addr_byte = ext_byte;
+ }
+ }
+
+ buf[0] = Cmnd_STK_LOAD_ADDRESS;
+ // Workaround for the infamous ';' bug in the Prusa3D usb to serial converter.
+ // Send the binary data by nibbles to avoid transmitting the ';' character.
+ buf[1] = addr & 0x0f;
+ buf[2] = addr & 0xf0;
+ buf[3] = (addr >> 8) & 0x0f;
+ buf[4] = (addr >> 8) & 0xf0;
+ buf[5] = Sync_CRC_EOP;
+ stk500_send(pgm, buf, 6);
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_NOSYNC) {
+ if (tries > 33) {
+ avrdude_message(MSG_INFO, "%s: stk500_loadaddr(): can't get into sync\n",
+ progname);
+ return -1;
+ }
+ if (stk500_getsync(pgm) < 0)
+ return -1;
+ goto retry;
+ }
+ else if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "%s: stk500_loadaddr(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -1;
+ }
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_OK) {
+ return 0;
+ }
+
+ avrdude_message(MSG_INFO, "%s: loadaddr(): (b) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+
+ return -1;
+}
+
+
+static int stk500_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned char *buf = alloca(page_size + 16);
+ int memtype;
+ int a_div;
+ int block_size;
+ int tries;
+ unsigned int n;
+ unsigned int i, j;
+ unsigned int prusa3d_semicolon_workaround_round = 0;
+ bool has_semicolon = false;
+
+ if (strcmp(m->desc, "flash") == 0) {
+ memtype = 'F';
+ }
+ else if (strcmp(m->desc, "eeprom") == 0) {
+ memtype = 'E';
+ }
+ else {
+ return -2;
+ }
+
+ if ((m->op[AVR_OP_LOADPAGE_LO]) || (m->op[AVR_OP_READ_LO]))
+ a_div = 2;
+ else
+ a_div = 1;
+
+ n = addr + n_bytes;
+#if 0
+ avrdude_message(MSG_INFO, "n_bytes = %d\n"
+ "n = %u\n"
+ "a_div = %d\n"
+ "page_size = %d\n",
+ n_bytes, n, a_div, page_size);
+#endif
+
+ for (; addr < n; addr += block_size) {
+ // MIB510 uses fixed blocks size of 256 bytes
+ if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
+ block_size = 256;
+ } else {
+ if (n - addr < page_size)
+ block_size = n - addr;
+ else
+ block_size = page_size;
+ }
+ tries = 0;
+ retry:
+ tries++;
+ stk500_loadaddr(pgm, m, addr/a_div);
+
+ for (i = 0; i < n_bytes; ++ i)
+ if (m->buf[addr + i] == ';') {
+ has_semicolon = true;
+ break;
+ }
+
+ for (prusa3d_semicolon_workaround_round = 0; prusa3d_semicolon_workaround_round < (has_semicolon ? 2 : 1); ++ prusa3d_semicolon_workaround_round) {
+ /* build command block and avoid multiple send commands as it leads to a crash
+ of the silabs usb serial driver on mac os x */
+ i = 0;
+ buf[i++] = Cmnd_STK_PROG_PAGE;
+ // Workaround for the infamous ';' bug in the Prusa3D usb to serial converter.
+ // Send the binary data by nibbles to avoid transmitting the ';' character.
+ buf[i++] = (block_size >> 8) & 0xf0;
+ buf[i++] = (block_size >> 8) & 0x0f;
+ buf[i++] = block_size & 0xf0;
+ buf[i++] = block_size & 0x0f;
+ buf[i++] = memtype;
+ if (has_semicolon) {
+ for (j = 0; j < block_size; ++i, ++ j) {
+ buf[i] = m->buf[addr + j];
+ if (buf[i] == ';')
+ buf[i] |= (prusa3d_semicolon_workaround_round ? 0xf0 : 0x0f);
+ }
+ } else {
+ memcpy(&buf[i], &m->buf[addr], block_size);
+ i += block_size;
+ }
+ buf[i++] = Sync_CRC_EOP;
+ stk500_send( pgm, buf, i);
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_NOSYNC) {
+ if (tries > 33) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): can't get into sync\n",
+ progname);
+ return -3;
+ }
+ if (stk500_getsync(pgm) < 0)
+ return -1;
+ goto retry;
+ }
+ else if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -4;
+ }
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] != Resp_STK_OK) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_paged_write(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -5;
+ }
+ }
+ }
+
+ return n_bytes;
+}
+
+static int stk500_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned char buf[16];
+ int memtype;
+ int a_div;
+ int tries;
+ unsigned int n;
+ int block_size;
+
+ if (strcmp(m->desc, "flash") == 0) {
+ memtype = 'F';
+ }
+ else if (strcmp(m->desc, "eeprom") == 0) {
+ memtype = 'E';
+ }
+ else {
+ return -2;
+ }
+
+ if ((m->op[AVR_OP_LOADPAGE_LO]) || (m->op[AVR_OP_READ_LO]))
+ a_div = 2;
+ else
+ a_div = 1;
+
+ n = addr + n_bytes;
+ for (; addr < n; addr += block_size) {
+ // MIB510 uses fixed blocks size of 256 bytes
+ if (strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
+ block_size = 256;
+ } else {
+ if (n - addr < page_size)
+ block_size = n - addr;
+ else
+ block_size = page_size;
+ }
+
+ tries = 0;
+ retry:
+ tries++;
+ stk500_loadaddr(pgm, m, addr/a_div);
+ buf[0] = Cmnd_STK_READ_PAGE;
+ // Workaround for the infamous ';' bug in the Prusa3D usb to serial converter.
+ // Send the binary data by nibbles to avoid transmitting the ';' character.
+ buf[1] = (block_size >> 8) & 0xf0;
+ buf[2] = (block_size >> 8) & 0x0f;
+ buf[3] = block_size & 0xf0;
+ buf[4] = block_size & 0x0f;
+ buf[5] = memtype;
+ buf[6] = Sync_CRC_EOP;
+ stk500_send(pgm, buf, 7);
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_NOSYNC) {
+ if (tries > 33) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_paged_load(): can't get into sync\n",
+ progname);
+ return -3;
+ }
+ if (stk500_getsync(pgm) < 0)
+ return -1;
+ goto retry;
+ }
+ else if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_paged_load(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -4;
+ }
+
+ if (stk500_recv(pgm, &m->buf[addr], block_size) < 0)
+ return -1;
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+
+ if(strcmp(ldata(lfirst(pgm->id)), "mib510") == 0) {
+ if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_paged_load(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -5;
+ }
+ }
+ else {
+ if (buf[0] != Resp_STK_OK) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_paged_load(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_OK, buf[0]);
+ return -5;
+ }
+ }
+ }
+
+ return n_bytes;
+}
+
+
+static int stk500_set_vtarget(PROGRAMMER * pgm, double v)
+{
+ unsigned uaref, utarg;
+
+ utarg = (unsigned)((v + 0.049) * 10);
+
+ if (stk500_getparm(pgm, Parm_STK_VADJUST, &uaref) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500_set_vtarget(): cannot obtain V[aref]\n",
+ progname);
+ return -1;
+ }
+
+ if (uaref > utarg) {
+ avrdude_message(MSG_INFO, "%s: stk500_set_vtarget(): reducing V[aref] from %.1f to %.1f\n",
+ progname, uaref / 10.0, v);
+ if (stk500_setparm(pgm, Parm_STK_VADJUST, utarg)
+ != 0)
+ return -1;
+ }
+ return stk500_setparm(pgm, Parm_STK_VTARGET, utarg);
+}
+
+
+static int stk500_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
+ double v)
+{
+ unsigned uaref, utarg;
+
+ uaref = (unsigned)((v + 0.049) * 10);
+
+ if (stk500_getparm(pgm, Parm_STK_VTARGET, &utarg) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500_set_varef(): cannot obtain V[target]\n",
+ progname);
+ return -1;
+ }
+
+ if (uaref > utarg) {
+ avrdude_message(MSG_INFO, "%s: stk500_set_varef(): V[aref] must not be greater than "
+ "V[target] = %.1f\n",
+ progname, utarg / 10.0);
+ return -1;
+ }
+ return stk500_setparm(pgm, Parm_STK_VADJUST, uaref);
+}
+
+
+static int stk500_set_fosc(PROGRAMMER * pgm, double v)
+{
+ unsigned prescale, cmatch, fosc;
+ static unsigned ps[] = {
+ 1, 8, 32, 64, 128, 256, 1024
+ };
+ int idx, rc;
+
+ prescale = cmatch = 0;
+ if (v > 0.0) {
+ if (v > STK500_XTAL / 2) {
+ const char *unit;
+ if (v > 1e6) {
+ v /= 1e6;
+ unit = "MHz";
+ } else if (v > 1e3) {
+ v /= 1e3;
+ unit = "kHz";
+ } else
+ unit = "Hz";
+ avrdude_message(MSG_INFO, "%s: stk500_set_fosc(): f = %.3f %s too high, using %.3f MHz\n",
+ progname, v, unit, STK500_XTAL / 2e6);
+ fosc = STK500_XTAL / 2;
+ } else
+ fosc = (unsigned)v;
+
+ for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {
+ if (fosc >= STK500_XTAL / (256 * ps[idx] * 2)) {
+ /* this prescaler value can handle our frequency */
+ prescale = idx + 1;
+ cmatch = (unsigned)(STK500_XTAL / (2 * fosc * ps[idx])) - 1;
+ break;
+ }
+ }
+ if (idx == sizeof(ps) / sizeof(ps[0])) {
+ avrdude_message(MSG_INFO, "%s: stk500_set_fosc(): f = %u Hz too low, %u Hz min\n",
+ progname, fosc, STK500_XTAL / (256 * 1024 * 2));
+ return -1;
+ }
+ }
+
+ if ((rc = stk500_setparm(pgm, Parm_STK_OSC_PSCALE, prescale)) != 0
+ || (rc = stk500_setparm(pgm, Parm_STK_OSC_CMATCH, cmatch)) != 0)
+ return rc;
+
+ return 0;
+}
+
+
+/* This code assumes that each count of the SCK duration parameter
+ represents 8/f, where f is the clock frequency of the STK500 master
+ processors (not the target). This number comes from Atmel
+ application note AVR061. It appears that the STK500 bit bangs SCK.
+ For small duration values, the actual SCK width is larger than
+ expected. As the duration value increases, the SCK width error
+ diminishes. */
+static int stk500_set_sck_period(PROGRAMMER * pgm, double v)
+{
+ int dur;
+ double min, max;
+
+ min = 8.0 / STK500_XTAL;
+ max = 255 * min;
+ dur = v / min + 0.5;
+
+ if (v < min) {
+ dur = 1;
+ avrdude_message(MSG_INFO, "%s: stk500_set_sck_period(): p = %.1f us too small, using %.1f us\n",
+ progname, v / 1e-6, dur * min / 1e-6);
+ } else if (v > max) {
+ dur = 255;
+ avrdude_message(MSG_INFO, "%s: stk500_set_sck_period(): p = %.1f us too large, using %.1f us\n",
+ progname, v / 1e-6, dur * min / 1e-6);
+ }
+
+ return stk500_setparm(pgm, Parm_STK_SCK_DURATION, dur);
+}
+
+
+static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value)
+{
+ unsigned char buf[16];
+ unsigned v;
+ int tries = 0;
+
+ retry:
+ tries++;
+ buf[0] = Cmnd_STK_GET_PARAMETER;
+ buf[1] = parm;
+ buf[2] = Sync_CRC_EOP;
+
+ stk500_send(pgm, buf, 3);
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_NOSYNC) {
+ if (tries > 33) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_getparm(): can't get into sync\n",
+ progname);
+ return -1;
+ }
+ if (stk500_getsync(pgm) < 0)
+ return -1;
+ goto retry;
+ }
+ else if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_getparm(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -2;
+ }
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ v = buf[0];
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_FAILED) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_getparm(): parameter 0x%02x failed\n",
+ progname, v);
+ return -3;
+ }
+ else if (buf[0] != Resp_STK_OK) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_getparm(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -3;
+ }
+
+ *value = v;
+
+ return 0;
+}
+
+
+static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value)
+{
+ unsigned char buf[16];
+ int tries = 0;
+
+ retry:
+ tries++;
+ buf[0] = Cmnd_STK_SET_PARAMETER;
+ buf[1] = parm;
+ buf[2] = value;
+ buf[3] = Sync_CRC_EOP;
+
+ stk500_send(pgm, buf, 4);
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_NOSYNC) {
+ if (tries > 33) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_setparm(): can't get into sync\n",
+ progname);
+ return -1;
+ }
+ if (stk500_getsync(pgm) < 0)
+ return -1;
+ goto retry;
+ }
+ else if (buf[0] != Resp_STK_INSYNC) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_setparm(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -2;
+ }
+
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_OK)
+ return 0;
+
+ parm = buf[0]; /* if not STK_OK, we've been echoed parm here */
+ if (stk500_recv(pgm, buf, 1) < 0)
+ return -1;
+ if (buf[0] == Resp_STK_FAILED) {
+ avrdude_message(MSG_INFO, "\n%s: stk500_setparm(): parameter 0x%02x failed\n",
+ progname, parm);
+ return -3;
+ }
+ else {
+ avrdude_message(MSG_INFO, "\n%s: stk500_setparm(): (a) protocol error, "
+ "expect=0x%02x, resp=0x%02x\n",
+ progname, Resp_STK_INSYNC, buf[0]);
+ return -3;
+ }
+}
+
+
+static void stk500_display(PROGRAMMER * pgm, const char * p)
+{
+ unsigned maj, min, hdw, topcard;
+
+ stk500_getparm(pgm, Parm_STK_HW_VER, &hdw);
+ stk500_getparm(pgm, Parm_STK_SW_MAJOR, &maj);
+ stk500_getparm(pgm, Parm_STK_SW_MINOR, &min);
+ stk500_getparm(pgm, Param_STK500_TOPCARD_DETECT, &topcard);
+
+ avrdude_message(MSG_INFO, "%sHardware Version: %d\n", p, hdw);
+ avrdude_message(MSG_INFO, "%sFirmware Version: %d.%d\n", p, maj, min);
+ if (topcard < 3) {
+ const char *n = "Unknown";
+
+ switch (topcard) {
+ case 1:
+ n = "STK502";
+ break;
+
+ case 2:
+ n = "STK501";
+ break;
+ }
+ avrdude_message(MSG_INFO, "%sTopcard : %s\n", p, n);
+ }
+ stk500_print_parms1(pgm, p);
+
+ return;
+}
+
+
+static void stk500_print_parms1(PROGRAMMER * pgm, const char * p)
+{
+ unsigned vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
+
+ stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget);
+ stk500_getparm(pgm, Parm_STK_VADJUST, &vadjust);
+ stk500_getparm(pgm, Parm_STK_OSC_PSCALE, &osc_pscale);
+ stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch);
+ stk500_getparm(pgm, Parm_STK_SCK_DURATION, &sck_duration);
+
+ avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
+ avrdude_message(MSG_INFO, "%sVaref : %.1f V\n", p, vadjust / 10.0);
+ avrdude_message(MSG_INFO, "%sOscillator : ", p);
+ if (osc_pscale == 0)
+ avrdude_message(MSG_INFO, "Off\n");
+ else {
+ int prescale = 1;
+ double f = STK500_XTAL / 2;
+ const char *unit;
+
+ switch (osc_pscale) {
+ case 2: prescale = 8; break;
+ case 3: prescale = 32; break;
+ case 4: prescale = 64; break;
+ case 5: prescale = 128; break;
+ case 6: prescale = 256; break;
+ case 7: prescale = 1024; break;
+ }
+ f /= prescale;
+ f /= (osc_cmatch + 1);
+ if (f > 1e6) {
+ f /= 1e6;
+ unit = "MHz";
+ } else if (f > 1e3) {
+ f /= 1000;
+ unit = "kHz";
+ } else
+ unit = "Hz";
+ avrdude_message(MSG_INFO, "%.3f %s\n", f, unit);
+ }
+ avrdude_message(MSG_INFO, "%sSCK period : %.1f us\n", p,
+ sck_duration * 8.0e6 / STK500_XTAL + 0.05);
+
+ return;
+}
+
+
+static void stk500_print_parms(PROGRAMMER * pgm)
+{
+ stk500_print_parms1(pgm, "");
+}
+
+static void stk500_setup(PROGRAMMER * pgm)
+{
+ if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
+ avrdude_message(MSG_INFO, "%s: stk500_setup(): Out of memory allocating private data\n",
+ progname);
+ return;
+ }
+ memset(pgm->cookie, 0, sizeof(struct pdata));
+ PDATA(pgm)->ext_addr_byte = 0xff; /* Ensures it is programmed before
+ * first memory address */
+}
+
+static void stk500_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+}
+
+const char stk500_desc[] = "Atmel STK500 Version 1.x firmware";
+
+void stk500_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "STK500");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500_initialize;
+ pgm->display = stk500_display;
+ pgm->enable = stk500_enable;
+ pgm->disable = stk500_disable;
+ pgm->program_enable = stk500_program_enable;
+ pgm->chip_erase = stk500_chip_erase;
+ pgm->cmd = stk500_cmd;
+ pgm->open = stk500_open;
+ pgm->close = stk500_close;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500_paged_write;
+ pgm->paged_load = stk500_paged_load;
+ pgm->print_parms = stk500_print_parms;
+ pgm->set_vtarget = stk500_set_vtarget;
+ pgm->set_varef = stk500_set_varef;
+ pgm->set_fosc = stk500_set_fosc;
+ pgm->set_sck_period = stk500_set_sck_period;
+ pgm->setup = stk500_setup;
+ pgm->teardown = stk500_teardown;
+ pgm->page_size = 256;
+}
diff --git a/xs/src/avrdude/stk500.h b/xs/src/avrdude/stk500.h
new file mode 100644
index 000000000..d0bce452d
--- /dev/null
+++ b/xs/src/avrdude/stk500.h
@@ -0,0 +1,41 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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 stk500_h
+#define stk500_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char stk500_desc[];
+void stk500_initpgm (PROGRAMMER * pgm);
+
+/* used by arduino.c to avoid duplicate code */
+int stk500_getsync(PROGRAMMER * pgm);
+int stk500_drain(PROGRAMMER * pgm, int display);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/xs/src/avrdude/stk500_private.h b/xs/src/avrdude/stk500_private.h
new file mode 100644
index 000000000..7efe866c4
--- /dev/null
+++ b/xs/src/avrdude/stk500_private.h
@@ -0,0 +1,103 @@
+//**** ATMEL AVR - A P P L I C A T I O N N O T E ************************
+//*
+//* Title: AVR061 - STK500 Communication Protocol
+//* Filename: command.h
+//* Version: 1.0
+//* Last updated: 09.09.2002
+//*
+//* Support E-mail: avr@atmel.com
+//*
+//**************************************************************************
+
+// *****************[ STK Message constants ]***************************
+
+#define STK_SIGN_ON_MESSAGE "AVR STK" // Sign on string for Cmnd_STK_GET_SIGN_ON
+
+// *****************[ STK Response constants ]***************************
+
+#define Resp_STK_OK 0x10 // ' '
+#define Resp_STK_FAILED 0x11 // ' '
+#define Resp_STK_UNKNOWN 0x12 // ' '
+#define Resp_STK_NODEVICE 0x13 // ' '
+#define Resp_STK_INSYNC 0x14 // ' '
+#define Resp_STK_NOSYNC 0x15 // ' '
+
+#define Resp_ADC_CHANNEL_ERROR 0x16 // ' '
+#define Resp_ADC_MEASURE_OK 0x17 // ' '
+#define Resp_PWM_CHANNEL_ERROR 0x18 // ' '
+#define Resp_PWM_ADJUST_OK 0x19 // ' '
+
+// *****************[ STK Special constants ]***************************
+
+#define Sync_CRC_EOP 0x20 // 'SPACE'
+
+// *****************[ STK Command constants ]***************************
+
+#define Cmnd_STK_GET_SYNC 0x30 // ' '
+#define Cmnd_STK_GET_SIGN_ON 0x31 // ' '
+
+#define Cmnd_STK_SET_PARAMETER 0x40 // ' '
+#define Cmnd_STK_GET_PARAMETER 0x41 // ' '
+#define Cmnd_STK_SET_DEVICE 0x42 // ' '
+#define Cmnd_STK_SET_DEVICE_EXT 0x45 // ' '
+
+#define Cmnd_STK_ENTER_PROGMODE 0x50 // ' '
+#define Cmnd_STK_LEAVE_PROGMODE 0x51 // ' '
+#define Cmnd_STK_CHIP_ERASE 0x52 // ' '
+#define Cmnd_STK_CHECK_AUTOINC 0x53 // ' '
+#define Cmnd_STK_LOAD_ADDRESS 0x55 // ' '
+#define Cmnd_STK_UNIVERSAL 0x56 // ' '
+#define Cmnd_STK_UNIVERSAL_MULTI 0x57 // ' '
+
+#define Cmnd_STK_PROG_FLASH 0x60 // ' '
+#define Cmnd_STK_PROG_DATA 0x61 // ' '
+#define Cmnd_STK_PROG_FUSE 0x62 // ' '
+#define Cmnd_STK_PROG_LOCK 0x63 // ' '
+#define Cmnd_STK_PROG_PAGE 0x64 // ' '
+#define Cmnd_STK_PROG_FUSE_EXT 0x65 // ' '
+
+#define Cmnd_STK_READ_FLASH 0x70 // ' '
+#define Cmnd_STK_READ_DATA 0x71 // ' '
+#define Cmnd_STK_READ_FUSE 0x72 // ' '
+#define Cmnd_STK_READ_LOCK 0x73 // ' '
+#define Cmnd_STK_READ_PAGE 0x74 // ' '
+#define Cmnd_STK_READ_SIGN 0x75 // ' '
+#define Cmnd_STK_READ_OSCCAL 0x76 // ' '
+#define Cmnd_STK_READ_FUSE_EXT 0x77 // ' '
+#define Cmnd_STK_READ_OSCCAL_EXT 0x78 // ' '
+
+// *****************[ STK Parameter constants ]***************************
+
+#define Parm_STK_HW_VER 0x80 // ' ' - R
+#define Parm_STK_SW_MAJOR 0x81 // ' ' - R
+#define Parm_STK_SW_MINOR 0x82 // ' ' - R
+#define Parm_STK_LEDS 0x83 // ' ' - R/W
+#define Parm_STK_VTARGET 0x84 // ' ' - R/W
+#define Parm_STK_VADJUST 0x85 // ' ' - R/W
+#define Parm_STK_OSC_PSCALE 0x86 // ' ' - R/W
+#define Parm_STK_OSC_CMATCH 0x87 // ' ' - R/W
+#define Parm_STK_RESET_DURATION 0x88 // ' ' - R/W
+#define Parm_STK_SCK_DURATION 0x89 // ' ' - R/W
+
+#define Parm_STK_BUFSIZEL 0x90 // ' ' - R/W, Range {0..255}
+#define Parm_STK_BUFSIZEH 0x91 // ' ' - R/W, Range {0..255}
+#define Parm_STK_DEVICE 0x92 // ' ' - R/W, Range {0..255}
+#define Parm_STK_PROGMODE 0x93 // ' ' - 'P' or 'S'
+#define Parm_STK_PARAMODE 0x94 // ' ' - TRUE or FALSE
+#define Parm_STK_POLLING 0x95 // ' ' - TRUE or FALSE
+#define Parm_STK_SELFTIMED 0x96 // ' ' - TRUE or FALSE
+#define Param_STK500_TOPCARD_DETECT 0x98 // ' ' - Detect top-card attached
+
+// *****************[ STK status bit definitions ]***************************
+
+#define Stat_STK_INSYNC 0x01 // INSYNC status bit, '1' - INSYNC
+#define Stat_STK_PROGMODE 0x02 // Programming mode, '1' - PROGMODE
+#define Stat_STK_STANDALONE 0x04 // Standalone mode, '1' - SM mode
+#define Stat_STK_RESET 0x08 // RESET button, '1' - Pushed
+#define Stat_STK_PROGRAM 0x10 // Program button, ' 1' - Pushed
+#define Stat_STK_LEDG 0x20 // Green LED status, '1' - Lit
+#define Stat_STK_LEDR 0x40 // Red LED status, '1' - Lit
+#define Stat_STK_LEDBLINK 0x80 // LED blink ON/OFF, '1' - Blink
+
+
+// *****************************[ End Of COMMAND.H ]**************************
diff --git a/xs/src/avrdude/stk500generic.c b/xs/src/avrdude/stk500generic.c
new file mode 100644
index 000000000..9c1ea4036
--- /dev/null
+++ b/xs/src/avrdude/stk500generic.c
@@ -0,0 +1,90 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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 Atmel STK500 programmer
+ *
+ * This is a wrapper around the STK500[v1] and STK500v2 programmers.
+ * Try to select the programmer type that actually responds, and
+ * divert to the actual programmer implementation if successful.
+ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "stk500generic.h"
+#include "stk500.h"
+#include "stk500v2.h"
+
+static int stk500generic_open(PROGRAMMER * pgm, char * port)
+{
+ stk500_initpgm(pgm);
+ if (pgm->open(pgm, port) >= 0)
+ {
+ avrdude_message(MSG_INFO, "%s: successfully opened stk500v1 device -- please use -c stk500v1\n",
+ progname);
+ return 0;
+ }
+
+ pgm->close(pgm);
+
+ stk500v2_initpgm(pgm);
+ if (pgm->open(pgm, port) >= 0)
+ {
+ avrdude_message(MSG_INFO, "%s: successfully opened stk500v2 device -- please use -c stk500v2\n",
+ progname);
+ return 0;
+ }
+
+ avrdude_message(MSG_INFO, "%s: cannot open either stk500v1 or stk500v2 programmer\n",
+ progname);
+ return -1;
+}
+
+static void stk500generic_setup(PROGRAMMER * pgm)
+{
+ /*
+ * Only STK500v2 needs setup/teardown.
+ */
+ stk500v2_initpgm(pgm);
+ pgm->setup(pgm);
+}
+
+static void stk500generic_teardown(PROGRAMMER * pgm)
+{
+ stk500v2_initpgm(pgm);
+ pgm->teardown(pgm);
+}
+
+const char stk500generic_desc[] = "Atmel STK500, autodetect firmware version";
+
+void stk500generic_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "STK500GENERIC");
+
+ pgm->open = stk500generic_open;
+ pgm->setup = stk500generic_setup;
+ pgm->teardown = stk500generic_teardown;
+}
diff --git a/xs/src/avrdude/stk500generic.h b/xs/src/avrdude/stk500generic.h
new file mode 100644
index 000000000..0c0590129
--- /dev/null
+++ b/xs/src/avrdude/stk500generic.h
@@ -0,0 +1,29 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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 stk500generic_h__
+#define stk500generic_h__
+
+extern const char stk500generic_desc[];
+void stk500generic_initpgm (PROGRAMMER * pgm);
+
+#endif
+
+
diff --git a/xs/src/avrdude/stk500v2.c b/xs/src/avrdude/stk500v2.c
new file mode 100644
index 000000000..691152b46
--- /dev/null
+++ b/xs/src/avrdude/stk500v2.c
@@ -0,0 +1,4798 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2005 Erik Walthinsen
+ * Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2006 David Moore
+ * Copyright (C) 2006,2007,2010 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+/* Based on Id: stk500.c,v 1.46 2004/12/22 01:52:45 bdean Exp */
+
+/*
+ * avrdude interface for Atmel STK500V2 programmer
+ *
+ * As the AVRISP mkII device is basically an STK500v2 one that can
+ * only talk across USB, and that misses any kind of framing protocol,
+ * this is handled here as well.
+ *
+ * Note: most commands use the "universal command" feature of the
+ * programmer in a "pass through" mode, exceptions are "program
+ * enable", "paged read", and "paged write".
+ *
+ */
+
+#include "ac_cfg.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#include <time.h>
+
+#if !defined(WIN32NATIVE)
+# include <sys/time.h>
+#endif
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "stk500_private.h" // temp until all code converted
+#include "stk500v2.h"
+#include "stk500v2_private.h"
+#include "usbdevs.h"
+
+/*
+ * We need to import enough from the JTAG ICE mkII definitions to be
+ * able to talk to the ICE, query some parameters etc. The macro
+ * JTAGMKII_PRIVATE_EXPORTED limits the amount of definitions that
+ * jtagmkII_private.h will export, so to avoid conflicts with those
+ * names that are identical to the STK500v2 ones.
+ */
+#include "jtagmkII.h" // public interfaces from jtagmkII.c
+#define JTAGMKII_PRIVATE_EXPORTED
+#include "jtagmkII_private.h"
+
+#include "jtag3.h" // public interfaces from jtagmkII.c
+#define JTAG3_PRIVATE_EXPORTED
+#include "jtag3_private.h"
+
+#define STK500V2_XTAL 7372800U
+
+// Timeout (in seconds) for waiting for serial response
+#define SERIAL_TIMEOUT 2
+
+// Retry count
+#define RETRIES 0
+
+#if 0
+#define DEBUG(...) avrdude_message(MSG_INFO, __VA_ARGS__)
+#else
+#define DEBUG(...)
+#endif
+
+#if 0
+#define DEBUGRECV(...) avrdude_message(MSG_INFO, __VA_ARGS__)
+#else
+#define DEBUGRECV(...)
+#endif
+
+enum hvmode
+{
+ PPMODE, HVSPMODE
+};
+
+
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
+
+/*
+ * Data structure for displaying STK600 routing and socket cards.
+ */
+struct carddata
+{
+ int id;
+ const char *name;
+};
+
+static const char *pgmname[] =
+{
+ "unknown",
+ "STK500",
+ "AVRISP",
+ "AVRISP mkII",
+ "JTAG ICE mkII",
+ "STK600",
+ "JTAGICE3",
+};
+
+struct jtagispentry
+{
+ unsigned char cmd;
+ unsigned short size;
+#define SZ_READ_FLASH_EE USHRT_MAX
+#define SZ_SPI_MULTI (USHRT_MAX - 1)
+};
+
+static const struct jtagispentry jtagispcmds[] = {
+ /* generic */
+ { CMD_SET_PARAMETER, 2 },
+ { CMD_GET_PARAMETER, 3 },
+ { CMD_OSCCAL, 2 },
+ { CMD_LOAD_ADDRESS, 2 },
+ /* ISP mode */
+ { CMD_ENTER_PROGMODE_ISP, 2 },
+ { CMD_LEAVE_PROGMODE_ISP, 2 },
+ { CMD_CHIP_ERASE_ISP, 2 },
+ { CMD_PROGRAM_FLASH_ISP, 2 },
+ { CMD_READ_FLASH_ISP, SZ_READ_FLASH_EE },
+ { CMD_PROGRAM_EEPROM_ISP, 2 },
+ { CMD_READ_EEPROM_ISP, SZ_READ_FLASH_EE },
+ { CMD_PROGRAM_FUSE_ISP, 3 },
+ { CMD_READ_FUSE_ISP, 4 },
+ { CMD_PROGRAM_LOCK_ISP, 3 },
+ { CMD_READ_LOCK_ISP, 4 },
+ { CMD_READ_SIGNATURE_ISP, 4 },
+ { CMD_READ_OSCCAL_ISP, 4 },
+ { CMD_SPI_MULTI, SZ_SPI_MULTI },
+ /* all HV modes */
+ { CMD_SET_CONTROL_STACK, 2 },
+ /* HVSP mode */
+ { CMD_ENTER_PROGMODE_HVSP, 2 },
+ { CMD_LEAVE_PROGMODE_HVSP, 2 },
+ { CMD_CHIP_ERASE_HVSP, 2 },
+ { CMD_PROGRAM_FLASH_HVSP, 2 },
+ { CMD_READ_FLASH_HVSP, SZ_READ_FLASH_EE },
+ { CMD_PROGRAM_EEPROM_HVSP, 2 },
+ { CMD_READ_EEPROM_HVSP, SZ_READ_FLASH_EE },
+ { CMD_PROGRAM_FUSE_HVSP, 2 },
+ { CMD_READ_FUSE_HVSP, 3 },
+ { CMD_PROGRAM_LOCK_HVSP, 2 },
+ { CMD_READ_LOCK_HVSP, 3 },
+ { CMD_READ_SIGNATURE_HVSP, 3 },
+ { CMD_READ_OSCCAL_HVSP, 3 },
+ /* PP mode */
+ { CMD_ENTER_PROGMODE_PP, 2 },
+ { CMD_LEAVE_PROGMODE_PP, 2 },
+ { CMD_CHIP_ERASE_PP, 2 },
+ { CMD_PROGRAM_FLASH_PP, 2 },
+ { CMD_READ_FLASH_PP, SZ_READ_FLASH_EE },
+ { CMD_PROGRAM_EEPROM_PP, 2 },
+ { CMD_READ_EEPROM_PP, SZ_READ_FLASH_EE },
+ { CMD_PROGRAM_FUSE_PP, 2 },
+ { CMD_READ_FUSE_PP, 3 },
+ { CMD_PROGRAM_LOCK_PP, 2 },
+ { CMD_READ_LOCK_PP, 3 },
+ { CMD_READ_SIGNATURE_PP, 3 },
+ { CMD_READ_OSCCAL_PP, 3 },
+};
+
+/*
+ * From XML file:
+ <REVISION>
+ <RC_ID_MAJOR>0</RC_ID_MAJOR>
+ <RC_ID_MINOR>56</RC_ID_MINOR>
+ <EC_ID_MAJOR>0</EC_ID_MAJOR>
+ <EC_ID_MINOR>1</EC_ID_MINOR>
+ </REVISION>
+ */
+/*
+ * These two tables can be semi-automatically updated from
+ * targetboards.xml using tools/get-stk600-cards.xsl.
+ */
+static const struct carddata routing_cards[] =
+{
+ { 0x01, "STK600-RC020T-1" },
+ { 0x03, "STK600-RC028T-3" },
+ { 0x05, "STK600-RC040M-5" },
+ { 0x08, "STK600-RC020T-8" },
+ { 0x0A, "STK600-RC040M-4" },
+ { 0x0C, "STK600-RC008T-2" },
+ { 0x0D, "STK600-RC028M-6" },
+ { 0x10, "STK600-RC064M-10" },
+ { 0x11, "STK600-RC100M-11" },
+ { 0x13, "STK600-RC100X-13" },
+ { 0x15, "STK600-RC044X-15" },
+ { 0x18, "STK600-RC100M-18" },
+ { 0x19, "STK600-RCPWM-19" },
+ { 0x1A, "STK600-RC064X-14" },
+ { 0x1B, "STK600-RC032U-20" },
+ { 0x1C, "STK600-RC014T-12" },
+ { 0x1E, "STK600-RC064U-17" },
+ { 0x1F, "STK600-RCuC3B0-21" },
+ { 0x20, "STK600-RCPWM-22" },
+ { 0x21, "STK600-RC020T-23" },
+ { 0x22, "STK600-RC044M-24" },
+ { 0x23, "STK600-RC044U-25" },
+ { 0x24, "STK600-RCPWM-26" },
+ { 0x25, "STK600-RCuC3B48-27" },
+ { 0x27, "STK600-RC032M-29" },
+ { 0x28, "STK600-RC044M-30" },
+ { 0x29, "STK600-RC044M-31" },
+ { 0x2A, "STK600-RC014T-42" },
+ { 0x2B, "STK600-RC020T-43" },
+ { 0x30, "STK600-RCUC3A144-32" },
+ { 0x34, "STK600-RCUC3L0-34" },
+ { 0x38, "STK600-RCUC3C0-36" },
+ { 0x3B, "STK600-RCUC3C0-37" },
+ { 0x3E, "STK600-RCUC3A144-33" },
+ { 0x46, "STK600-RCuC3A100-28" },
+ { 0x55, "STK600-RC064M-9" },
+ { 0x88, "STK600-RCUC3C1-38" },
+ { 0x8B, "STK600-RCUC3C1-39" },
+ { 0xA0, "STK600-RC008T-7" },
+ { 0xB8, "STK600-RCUC3C2-40" },
+ { 0xBB, "STK600-RCUC3C2-41" },
+};
+
+static const struct carddata socket_cards[] =
+{
+ { 0x01, "STK600-TQFP48" },
+ { 0x02, "STK600-TQFP32" },
+ { 0x03, "STK600-TQFP100" },
+ { 0x04, "STK600-SOIC" },
+ { 0x06, "STK600-TQFP144" },
+ { 0x09, "STK600-TinyX3U" },
+ { 0x0C, "STK600-TSSOP44" },
+ { 0x0D, "STK600-TQFP44" },
+ { 0x0E, "STK600-TQFP64-2" },
+ { 0x0F, "STK600-ATMEGA2560" },
+ { 0x15, "STK600-MLF64" },
+ { 0x16, "STK600-ATXMEGAT0" },
+ { 0x18, "QT600-ATMEGA324-QM64" },
+ { 0x19, "STK600-ATMEGA128RFA1" },
+ { 0x1A, "QT600-ATTINY88-QT8" },
+ { 0x1B, "QT600-ATXMEGA128A1-QT16" },
+ { 0x1C, "QT600-AT32UC3L-QM64" },
+ { 0x1D, "STK600-HVE2" },
+ { 0x1E, "STK600-ATTINY10" },
+ { 0x55, "STK600-TQFP64" },
+ { 0x69, "STK600-uC3-144" },
+ { 0xF0, "STK600-ATXMEGA1281A1" },
+ { 0xF1, "STK600-DIP" },
+};
+
+static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value);
+static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char value);
+static int stk500v2_getparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int * value);
+static int stk500v2_setparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int value);
+static int stk500v2_setparm_real(PROGRAMMER * pgm, unsigned char parm, unsigned char value);
+static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p);
+static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes);
+static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes);
+
+static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize);
+
+static double stk500v2_sck_to_us(PROGRAMMER * pgm, unsigned char dur);
+static int stk500v2_set_sck_period_mk2(PROGRAMMER * pgm, double v);
+
+static int stk600_set_sck_period(PROGRAMMER * pgm, double v);
+
+static void stk600_setup_xprog(PROGRAMMER * pgm);
+static void stk600_setup_isp(PROGRAMMER * pgm);
+static int stk600_xprog_program_enable(PROGRAMMER * pgm, AVRPART * p);
+
+void stk500v2_setup(PROGRAMMER * pgm)
+{
+ if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
+ // avrdude_message(MSG_INFO, "%s: stk500v2_setup(): Out of memory allocating private data\n",
+ // progname);
+ // exit(1);
+ avrdude_oom("stk500v2_setup(): Out of memory allocating private data\n");
+ }
+ memset(pgm->cookie, 0, sizeof(struct pdata));
+ PDATA(pgm)->command_sequence = 1;
+ PDATA(pgm)->boot_start = ULONG_MAX;
+}
+
+static void stk500v2_jtagmkII_setup(PROGRAMMER * pgm)
+{
+ // void *mycookie, *theircookie;
+
+ // if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
+ // avrdude_message(MSG_INFO, "%s: stk500v2_setup(): Out of memory allocating private data\n",
+ // progname);
+ // exit(1);
+ // }
+ // memset(pgm->cookie, 0, sizeof(struct pdata));
+ // PDATA(pgm)->command_sequence = 1;
+
+ // /*
+ // * Now, have the JTAG ICE mkII backend allocate its own private
+ // * data. Store our own cookie in a safe place for the time being.
+ // */
+ // mycookie = pgm->cookie;
+ // jtagmkII_setup(pgm);
+ // theircookie = pgm->cookie;
+ // pgm->cookie = mycookie;
+ // PDATA(pgm)->chained_pdata = theircookie;
+}
+
+static void stk500v2_jtag3_setup(PROGRAMMER * pgm)
+{
+ // void *mycookie, *theircookie;
+
+ // if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
+ // avrdude_message(MSG_INFO, "%s: stk500v2_setup(): Out of memory allocating private data\n",
+ // progname);
+ // exit(1);
+ // }
+ // memset(pgm->cookie, 0, sizeof(struct pdata));
+ // PDATA(pgm)->command_sequence = 1;
+
+ // /*
+ // * Now, have the JTAGICE3 backend allocate its own private
+ // * data. Store our own cookie in a safe place for the time being.
+ // */
+ // mycookie = pgm->cookie;
+ // jtag3_setup(pgm);
+ // theircookie = pgm->cookie;
+ // pgm->cookie = mycookie;
+ // PDATA(pgm)->chained_pdata = theircookie;
+}
+
+void stk500v2_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+}
+
+static void stk500v2_jtagmkII_teardown(PROGRAMMER * pgm)
+{
+ // void *mycookie;
+
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+ // jtagmkII_teardown(pgm);
+
+ // free(mycookie);
+}
+
+static void stk500v2_jtag3_teardown(PROGRAMMER * pgm)
+{
+ // void *mycookie;
+
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+ // jtag3_teardown(pgm);
+
+ // free(mycookie);
+}
+
+
+static unsigned short
+b2_to_u16(unsigned char *b)
+{
+ unsigned short l;
+ l = b[0];
+ l += (unsigned)b[1] << 8;
+
+ return l;
+}
+
+static int stk500v2_send_mk2(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ if (serial_send(&pgm->fd, data, len) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500_send_mk2(): failed to send command to serial port\n",progname);
+ return -1;
+ }
+
+ return 0;
+}
+
+static unsigned short get_jtagisp_return_size(unsigned char cmd)
+{
+ int i;
+
+ for (i = 0; i < sizeof jtagispcmds / sizeof jtagispcmds[0]; i++)
+ if (jtagispcmds[i].cmd == cmd)
+ return jtagispcmds[i].size;
+
+ return 0;
+}
+
+/*
+ * Send the data as a JTAG ICE mkII encapsulated ISP packet.
+ * Unlike what AVR067 says, the packet gets a length of our
+ * response buffer prepended, and replies with RSP_SPI_DATA
+ * if successful.
+ */
+static int stk500v2_jtagmkII_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ return -1;
+ // unsigned char *cmdbuf;
+ // int rv;
+ // unsigned short sz;
+ // void *mycookie;
+
+ // sz = get_jtagisp_return_size(data[0]);
+ // if (sz == 0) {
+ // avrdude_message(MSG_INFO, "%s: unsupported encapsulated ISP command: %#x\n",
+ // progname, data[0]);
+ // return -1;
+ // }
+ // if (sz == SZ_READ_FLASH_EE) {
+ // /*
+ // * For CMND_READ_FLASH_ISP and CMND_READ_EEPROM_ISP, extract the
+ // * size of the return data from the request. Note that the
+ // * request itself has the size in big endian format, while we are
+ // * supposed to deliver it in little endian.
+ // */
+ // sz = 3 + (data[1] << 8) + data[2];
+ // } else if (sz == SZ_SPI_MULTI) {
+ // /*
+ // * CMND_SPI_MULTI has the Rx size encoded in its 3rd byte.
+ // */
+ // sz = 3 + data[2];
+ // }
+
+ // if ((cmdbuf = malloc(len + 3)) == NULL) {
+ // avrdude_message(MSG_INFO, "%s: out of memory for command packet\n",
+ // progname);
+ // exit(1);
+ // }
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+ // cmdbuf[0] = CMND_ISP_PACKET;
+ // cmdbuf[1] = sz & 0xff;
+ // cmdbuf[2] = (sz >> 8) & 0xff;
+ // memcpy(cmdbuf + 3, data, len);
+ // rv = jtagmkII_send(pgm, cmdbuf, len + 3);
+ // free(cmdbuf);
+ // pgm->cookie = mycookie;
+
+ // return rv;
+}
+
+/*
+ * Send the data as a JTAGICE3 encapsulated ISP packet.
+ */
+static int stk500v2_jtag3_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ return -1;
+ // unsigned char *cmdbuf;
+ // int rv;
+ // void *mycookie;
+
+ // if ((cmdbuf = malloc(len + 1)) == NULL) {
+ // avrdude_message(MSG_INFO, "%s: out of memory for command packet\n",
+ // progname);
+ // exit(1);
+ // }
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+ // cmdbuf[0] = SCOPE_AVR_ISP;
+ // memcpy(cmdbuf + 1, data, len);
+ // rv = jtag3_send(pgm, cmdbuf, len + 1);
+ // free(cmdbuf);
+ // pgm->cookie = mycookie;
+
+ // return rv;
+}
+
+static int stk500v2_send(PROGRAMMER * pgm, unsigned char * data, size_t len)
+{
+ unsigned char buf[275 + 6]; // max MESSAGE_BODY of 275 bytes, 6 bytes overhead
+ int i;
+
+ if (PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
+ PDATA(pgm)->pgmtype == PGMTYPE_STK600)
+ return stk500v2_send_mk2(pgm, data, len);
+ else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII)
+ return stk500v2_jtagmkII_send(pgm, data, len);
+ else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3)
+ return stk500v2_jtag3_send(pgm, data, len);
+
+ buf[0] = MESSAGE_START;
+ buf[1] = PDATA(pgm)->command_sequence;
+ buf[2] = len / 256;
+ buf[3] = len % 256;
+ buf[4] = TOKEN;
+ memcpy(buf+5, data, len);
+
+ // calculate the XOR checksum
+ buf[5+len] = 0;
+ for (i=0;i<5+len;i++)
+ buf[5+len] ^= buf[i];
+
+ DEBUG("STK500V2: stk500v2_send(");
+ for (i=0;i<len+6;i++) DEBUG("0x%02x ",buf[i]);
+ DEBUG(", %d)\n",len+6);
+
+ if (serial_send(&pgm->fd, buf, len+6) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_send(): failed to send command to serial port\n",progname);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int stk500v2_drain(PROGRAMMER * pgm, int display)
+{
+ return serial_drain(&pgm->fd, display);
+}
+
+static int stk500v2_recv_mk2(PROGRAMMER * pgm, unsigned char *msg,
+ size_t maxsize)
+{
+ int rv;
+
+ rv = serial_recv(&pgm->fd, msg, maxsize);
+ if (rv < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_recv_mk2: error in USB receive\n", progname);
+ return -1;
+ }
+
+ return rv;
+}
+
+static int stk500v2_jtagmkII_recv(PROGRAMMER * pgm, unsigned char *msg,
+ size_t maxsize)
+{
+ return -1;
+ // int rv;
+ // unsigned char *jtagmsg;
+ // void *mycookie;
+
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+ // rv = jtagmkII_recv(pgm, &jtagmsg);
+ // pgm->cookie = mycookie;
+ // if (rv <= 0) {
+ // avrdude_message(MSG_INFO, "%s: stk500v2_jtagmkII_recv(): error in jtagmkII_recv()\n",
+ // progname);
+ // return -1;
+ // }
+ // if (rv - 1 > maxsize) {
+ // avrdude_message(MSG_INFO, "%s: stk500v2_jtagmkII_recv(): got %u bytes, have only room for %u bytes\n",
+ // progname, (unsigned)rv - 1, (unsigned)maxsize);
+ // rv = maxsize;
+ // }
+ // switch (jtagmsg[0]) {
+ // case RSP_SPI_DATA:
+ // break;
+ // case RSP_FAILED:
+ // avrdude_message(MSG_INFO, "%s: stk500v2_jtagmkII_recv(): failed\n",
+ // progname);
+ // return -1;
+ // case RSP_ILLEGAL_MCU_STATE:
+ // avrdude_message(MSG_INFO, "%s: stk500v2_jtagmkII_recv(): illegal MCU state\n",
+ // progname);
+ // return -1;
+ // default:
+ // avrdude_message(MSG_INFO, "%s: stk500v2_jtagmkII_recv(): unknown status %d\n",
+ // progname, jtagmsg[0]);
+ // return -1;
+ // }
+ // memcpy(msg, jtagmsg + 1, rv - 1);
+ // return rv;
+}
+
+static int stk500v2_jtag3_recv(PROGRAMMER * pgm, unsigned char *msg,
+ size_t maxsize)
+{
+ return -1;
+ // int rv;
+ // unsigned char *jtagmsg;
+ // void *mycookie;
+
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+ // rv = jtag3_recv(pgm, &jtagmsg);
+ // pgm->cookie = mycookie;
+ // if (rv <= 0) {
+ // avrdude_message(MSG_INFO, "%s: stk500v2_jtag3_recv(): error in jtagmkII_recv()\n",
+ // progname);
+ // return -1;
+ // }
+ // /* Getting more data than expected is a normal case for the EDBG
+ // implementation of JTAGICE3, as they always request a full 512
+ // octets from the ICE. Thus, only complain at high verbose
+ // levels. */
+ // if (rv - 1 > maxsize) {
+ // avrdude_message(MSG_DEBUG, "%s: stk500v2_jtag3_recv(): got %u bytes, have only room for %u bytes\n",
+ // progname, (unsigned)rv - 1, (unsigned)maxsize);
+ // rv = maxsize;
+ // }
+ // if (jtagmsg[0] != SCOPE_AVR_ISP) {
+ // avrdude_message(MSG_INFO, "%s: stk500v2_jtag3_recv(): message is not AVR ISP: 0x%02x\n",
+ // progname, jtagmsg[0]);
+ // free(jtagmsg);
+ // return -1;
+ // }
+ // memcpy(msg, jtagmsg + 1, rv - 1);
+ // free(jtagmsg);
+ // return rv;
+}
+
+static int stk500v2_recv(PROGRAMMER * pgm, unsigned char *msg, size_t maxsize) {
+ enum states { sINIT, sSTART, sSEQNUM, sSIZE1, sSIZE2, sTOKEN, sDATA, sCSUM, sDONE } state = sSTART;
+ unsigned int msglen = 0;
+ unsigned int curlen = 0;
+ int timeout = 0;
+ unsigned char c, checksum = 0;
+
+ /*
+ * The entire timeout handling here is not very consistent, see
+ *
+ * https://savannah.nongnu.org/bugs/index.php?43626
+ */
+ long timeoutval = SERIAL_TIMEOUT; // seconds
+ struct timeval tv;
+ double tstart, tnow;
+
+ if (PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
+ PDATA(pgm)->pgmtype == PGMTYPE_STK600)
+ return stk500v2_recv_mk2(pgm, msg, maxsize);
+ else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII)
+ return stk500v2_jtagmkII_recv(pgm, msg, maxsize);
+ else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3)
+ return stk500v2_jtag3_recv(pgm, msg, maxsize);
+
+ DEBUG("STK500V2: stk500v2_recv(): ");
+
+ gettimeofday(&tv, NULL);
+ tstart = tv.tv_sec;
+
+ while ( (state != sDONE ) && (!timeout) ) {
+ RETURN_IF_CANCEL();
+ if (serial_recv(&pgm->fd, &c, 1) < 0)
+ goto timedout;
+ DEBUG("0x%02x ",c);
+ checksum ^= c;
+
+ switch (state) {
+ case sSTART:
+ DEBUGRECV("hoping for start token...");
+ if (c == MESSAGE_START) {
+ DEBUGRECV("got it\n");
+ checksum = MESSAGE_START;
+ state = sSEQNUM;
+ } else
+ DEBUGRECV("sorry\n");
+ break;
+ case sSEQNUM:
+ DEBUGRECV("hoping for sequence...\n");
+ if (c == PDATA(pgm)->command_sequence) {
+ DEBUGRECV("got it, incrementing\n");
+ state = sSIZE1;
+ PDATA(pgm)->command_sequence++;
+ } else {
+ DEBUGRECV("sorry\n");
+ state = sSTART;
+ }
+ break;
+ case sSIZE1:
+ DEBUGRECV("hoping for size LSB\n");
+ msglen = (unsigned)c * 256;
+ state = sSIZE2;
+ break;
+ case sSIZE2:
+ DEBUGRECV("hoping for size MSB...");
+ msglen += (unsigned)c;
+ DEBUG(" msg is %u bytes\n",msglen);
+ state = sTOKEN;
+ break;
+ case sTOKEN:
+ if (c == TOKEN) state = sDATA;
+ else state = sSTART;
+ break;
+ case sDATA:
+ if (curlen < maxsize) {
+ msg[curlen] = c;
+ } else {
+ avrdude_message(MSG_INFO, "%s: stk500v2_recv(): buffer too small, received %d byte into %u byte buffer\n",
+ progname,curlen,(unsigned int)maxsize);
+ return -2;
+ }
+ if ((curlen == 0) && (msg[0] == ANSWER_CKSUM_ERROR)) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_recv(): previous packet sent with wrong checksum\n",
+ progname);
+ return -3;
+ }
+ curlen++;
+ if (curlen == msglen) state = sCSUM;
+ break;
+ case sCSUM:
+ if (checksum == 0) {
+ state = sDONE;
+ } else {
+ state = sSTART;
+ avrdude_message(MSG_INFO, "%s: stk500v2_recv(): checksum error\n",
+ progname);
+ return -4;
+ }
+ break;
+ default:
+ avrdude_message(MSG_INFO, "%s: stk500v2_recv(): unknown state\n",
+ progname);
+ return -5;
+ } /* switch */
+
+ gettimeofday(&tv, NULL);
+ tnow = tv.tv_sec;
+ if (tnow-tstart > timeoutval) { // wuff - signed/unsigned/overflow
+ timedout:
+ avrdude_message(MSG_INFO, "%s: stk500v2_recv(): timeout\n",
+ progname);
+ return -1;
+ }
+
+ } /* while */
+ DEBUG("\n");
+
+ return (int)(msglen+6);
+}
+
+
+
+int stk500v2_getsync(PROGRAMMER * pgm) {
+ int tries = 0;
+ unsigned char buf[1], resp[32];
+ int status;
+
+ DEBUG("STK500V2: stk500v2_getsync()\n");
+
+ if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII ||
+ PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3)
+ return 0;
+
+retry:
+ tries++;
+
+ RETURN_IF_CANCEL();
+
+ // send the sync command and see if we can get there
+ buf[0] = CMD_SIGN_ON;
+ if (stk500v2_send(pgm, buf, 1) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_getsync(): can't communicate with device\n", progname);
+ return -1;
+ }
+
+ RETURN_IF_CANCEL();
+
+ // try to get the response back and see where we got
+ status = stk500v2_recv(pgm, resp, sizeof(resp));
+
+ RETURN_IF_CANCEL();
+
+ // if we got bytes returned, check to see what came back
+ if (status > 0) {
+ if ((resp[0] == CMD_SIGN_ON) && (resp[1] == STATUS_CMD_OK) &&
+ (status > 3)) {
+ // success!
+ unsigned int siglen = resp[2];
+ if (siglen >= strlen("STK500_2") &&
+ memcmp(resp + 3, "STK500_2", strlen("STK500_2")) == 0) {
+ PDATA(pgm)->pgmtype = PGMTYPE_STK500;
+ } else if (siglen >= strlen("AVRISP_2") &&
+ memcmp(resp + 3, "AVRISP_2", strlen("AVRISP_2")) == 0) {
+ PDATA(pgm)->pgmtype = PGMTYPE_AVRISP;
+ } else if (siglen >= strlen("AVRISP_MK2") &&
+ memcmp(resp + 3, "AVRISP_MK2", strlen("AVRISP_MK2")) == 0) {
+ PDATA(pgm)->pgmtype = PGMTYPE_AVRISP_MKII;
+ } else if (siglen >= strlen("STK600") &&
+ memcmp(resp + 3, "STK600", strlen("STK600")) == 0) {
+ PDATA(pgm)->pgmtype = PGMTYPE_STK600;
+ } else {
+ resp[siglen + 3] = 0;
+ avrdude_message(MSG_NOTICE, "%s: stk500v2_getsync(): got response from unknown "
+ "programmer %s, assuming STK500\n",
+ progname, resp + 3);
+ PDATA(pgm)->pgmtype = PGMTYPE_STK500;
+ }
+ avrdude_message(MSG_DEBUG, "%s: stk500v2_getsync(): found %s programmer\n",
+ progname, pgmname[PDATA(pgm)->pgmtype]);
+ return 0;
+ } else {
+ if (tries > RETRIES) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_getsync(): can't communicate with device: resp=0x%02x\n",
+ progname, resp[0]);
+ return -6;
+ } else
+ goto retry;
+ }
+
+ // or if we got a timeout
+ } else if (status == -1) {
+ if (tries > RETRIES) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_getsync(): timeout communicating with programmer\n",
+ progname);
+ return -1;
+ } else
+ goto retry;
+
+ // or any other error
+ } else {
+ if (tries > RETRIES) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_getsync(): error communicating with programmer: (%d)\n",
+ progname,status);
+ } else
+ goto retry;
+ }
+
+ return 0;
+}
+
+static int stk500v2_command(PROGRAMMER * pgm, unsigned char * buf,
+ size_t len, size_t maxlen) {
+ int i;
+ int tries = 0;
+ int status;
+
+ DEBUG("STK500V2: stk500v2_command(");
+ for (i=0;i<len;i++) DEBUG("0x%02x ",buf[i]);
+ DEBUG(", %d)\n",len);
+
+retry:
+ tries++;
+
+ RETURN_IF_CANCEL();
+
+ // send the command to the programmer
+ if (stk500v2_send(pgm, buf, len) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_command(): can't communicate with device\n", progname);
+ return -1;
+ }
+
+ RETURN_IF_CANCEL();
+
+ // attempt to read the status back
+ status = stk500v2_recv(pgm,buf,maxlen);
+
+ RETURN_IF_CANCEL();
+
+ // if we got a successful readback, return
+ if (status > 0) {
+ DEBUG(" = %d\n",status);
+ if (status < 2) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_command(): short reply\n", progname);
+ return -1;
+ }
+ if (buf[0] == CMD_XPROG_SETMODE || buf[0] == CMD_XPROG) {
+ /*
+ * Decode XPROG wrapper errors.
+ */
+ const char *msg;
+ int i;
+
+ /*
+ * For CMD_XPROG_SETMODE, the status is returned in buf[1].
+ * For CMD_XPROG, buf[1] contains the XPRG_CMD_* command, and
+ * buf[2] contains the status.
+ */
+ i = buf[0] == CMD_XPROG_SETMODE? 1: 2;
+
+ if (buf[i] != XPRG_ERR_OK) {
+ switch (buf[i]) {
+ case XPRG_ERR_FAILED: msg = "Failed"; break;
+ case XPRG_ERR_COLLISION: msg = "Collision"; break;
+ case XPRG_ERR_TIMEOUT: msg = "Timeout"; break;
+ default: msg = "Unknown"; break;
+ }
+ avrdude_message(MSG_INFO, "%s: stk500v2_command(): error in %s: %s\n",
+ progname,
+ (buf[0] == CMD_XPROG_SETMODE? "CMD_XPROG_SETMODE": "CMD_XPROG"),
+ msg);
+ return -1;
+ }
+ return 0;
+ } else {
+ /*
+ * Decode STK500v2 errors.
+ */
+ if (buf[1] >= STATUS_CMD_TOUT && buf[1] < 0xa0) {
+ const char *msg;
+ char msgbuf[30];
+ switch (buf[1]) {
+ case STATUS_CMD_TOUT:
+ msg = "Command timed out";
+ break;
+
+ case STATUS_RDY_BSY_TOUT:
+ msg = "Sampling of the RDY/nBSY pin timed out";
+ break;
+
+ case STATUS_SET_PARAM_MISSING:
+ msg = "The `Set Device Parameters' have not been "
+ "executed in advance of this command";
+
+ default:
+ sprintf(msgbuf, "unknown, code 0x%02x", buf[1]);
+ msg = msgbuf;
+ break;
+ }
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_command(): warning: %s\n",
+ progname, msg);
+ }
+ } else if (buf[1] == STATUS_CMD_OK) {
+ return status;
+ } else if (buf[1] == STATUS_CMD_FAILED) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_command(): command failed\n",
+ progname);
+ } else if (buf[1] == STATUS_CMD_UNKNOWN) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_command(): unknown command\n",
+ progname);
+ } else {
+ avrdude_message(MSG_INFO, "%s: stk500v2_command(): unknown status 0x%02x\n",
+ progname, buf[1]);
+ }
+ return -1;
+ }
+ }
+
+ // otherwise try to sync up again
+ status = stk500v2_getsync(pgm);
+ if (status != 0) {
+ if (tries > RETRIES) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_command(): failed miserably to execute command 0x%02x\n",
+ progname,buf[0]);
+ return -1;
+ } else
+ goto retry;
+ }
+
+ DEBUG(" = 0\n");
+ return 0;
+}
+
+static int stk500v2_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+ unsigned char *res)
+{
+ unsigned char buf[8];
+ int result;
+
+ DEBUG("STK500V2: stk500v2_cmd(%02x,%02x,%02x,%02x)\n",cmd[0],cmd[1],cmd[2],cmd[3]);
+
+ buf[0] = CMD_SPI_MULTI;
+ buf[1] = 4;
+ buf[2] = 4;
+ buf[3] = 0;
+ buf[4] = cmd[0];
+ buf[5] = cmd[1];
+ buf[6] = cmd[2];
+ buf[7] = cmd[3];
+
+ result = stk500v2_command(pgm, buf, 8, sizeof(buf));
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_cmd(): failed to send command\n",
+ progname);
+ return -1;
+ } else if (result < 6) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_cmd(): short reply, len = %d\n",
+ progname, result);
+ return -1;
+ }
+
+ res[0] = buf[2];
+ res[1] = buf[3];
+ res[2] = buf[4];
+ res[3] = buf[5];
+
+ return 0;
+}
+
+
+static int stk500v2_jtag3_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+ unsigned char *res)
+{
+ avrdude_message(MSG_INFO, "%s: stk500v2_jtag3_cmd(): Not available in JTAGICE3\n",
+ progname);
+
+ return -1;
+}
+
+
+/*
+ * issue the 'chip erase' command to the AVR device
+ */
+static int stk500v2_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ int result;
+ unsigned char buf[16];
+
+ if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_chip_erase: chip erase instruction not defined for part \"%s\"\n",
+ progname, p->desc);
+ return -1;
+ }
+
+ pgm->pgm_led(pgm, ON);
+
+ buf[0] = CMD_CHIP_ERASE_ISP;
+ buf[1] = p->chip_erase_delay / 1000;
+ buf[2] = 0; // use delay (?)
+ avr_set_bits(p->op[AVR_OP_CHIP_ERASE], buf+3);
+ result = stk500v2_command(pgm, buf, 7, sizeof(buf));
+ usleep(p->chip_erase_delay);
+ pgm->initialize(pgm, p);
+
+ pgm->pgm_led(pgm, OFF);
+
+ return result >= 0? 0: -1;
+}
+
+/*
+ * issue the 'chip erase' command to the AVR device, generic HV mode
+ */
+static int stk500hv_chip_erase(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
+{
+ int result;
+ unsigned char buf[3];
+
+ pgm->pgm_led(pgm, ON);
+
+ if (mode == PPMODE) {
+ buf[0] = CMD_CHIP_ERASE_PP;
+ buf[1] = p->chiperasepulsewidth;
+ buf[2] = p->chiperasepolltimeout;
+ } else {
+ buf[0] = CMD_CHIP_ERASE_HVSP;
+ buf[1] = p->chiperasepolltimeout;
+ buf[2] = p->chiperasetime;
+ }
+ result = stk500v2_command(pgm, buf, 3, sizeof(buf));
+ usleep(p->chip_erase_delay);
+ pgm->initialize(pgm, p);
+
+ pgm->pgm_led(pgm, OFF);
+
+ return result >= 0? 0: -1;
+}
+
+/*
+ * issue the 'chip erase' command to the AVR device, parallel mode
+ */
+static int stk500pp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ return stk500hv_chip_erase(pgm, p, PPMODE);
+}
+
+/*
+ * issue the 'chip erase' command to the AVR device, HVSP mode
+ */
+static int stk500hvsp_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ return stk500hv_chip_erase(pgm, p, HVSPMODE);
+}
+
+static struct
+{
+ unsigned int state;
+ const char *description;
+} connection_status[] =
+{
+ { STATUS_CONN_FAIL_MOSI, "MOSI fail" },
+ { STATUS_CONN_FAIL_RST, "RST fail" },
+ { STATUS_CONN_FAIL_SCK, "SCK fail" },
+ { STATUS_TGT_NOT_DETECTED, "Target not detected" },
+ { STATUS_TGT_REVERSE_INSERTED, "Target reverse inserted" },
+};
+
+/*
+ * Max length of returned message is the sum of all the description
+ * strings in the table above, plus 2 characters for separation.
+ * Currently, this is 76 chars.
+ */
+static void
+stk500v2_translate_conn_status(unsigned char status, char *msg)
+{
+ size_t i;
+ int need_comma;
+
+ *msg = 0;
+ need_comma = 0;
+
+ for (i = 0;
+ i < sizeof connection_status / sizeof connection_status[0];
+ i++)
+ {
+ if ((status & connection_status[i].state) != 0)
+ {
+ if (need_comma)
+ strcat(msg, ", ");
+ strcat(msg, connection_status[i].description);
+ need_comma = 1;
+ }
+ }
+ if (*msg == 0)
+ sprintf(msg, "Unknown status 0x%02x", status);
+}
+
+
+/*
+ * issue the 'program enable' command to the AVR device
+ */
+static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char buf[16];
+ char msg[100]; /* see remarks above about size needed */
+ int rv, tries;
+
+ PDATA(pgm)->lastpart = p;
+
+ if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_program_enable(): program enable instruction not defined for part \"%s\"\n",
+ progname, p->desc);
+ return -1;
+ }
+
+ if (PDATA(pgm)->pgmtype == PGMTYPE_STK500 ||
+ PDATA(pgm)->pgmtype == PGMTYPE_STK600)
+ /* Activate AVR-style (low active) RESET */
+ stk500v2_setparm_real(pgm, PARAM_RESET_POLARITY, 0x01);
+
+ tries = 0;
+// retry:
+ buf[0] = CMD_ENTER_PROGMODE_ISP;
+ buf[1] = p->timeout;
+ buf[2] = p->stabdelay;
+ buf[3] = p->cmdexedelay;
+ buf[4] = p->synchloops;
+ buf[5] = p->bytedelay;
+ buf[6] = p->pollvalue;
+ buf[7] = p->pollindex;
+ avr_set_bits(p->op[AVR_OP_PGM_ENABLE], buf+8);
+ buf[10] = buf[11] = 0;
+
+ rv = stk500v2_command(pgm, buf, 12, sizeof(buf));
+
+ if (rv < 0) {
+ switch (PDATA(pgm)->pgmtype)
+ {
+ case PGMTYPE_STK600:
+ case PGMTYPE_AVRISP_MKII:
+ if (stk500v2_getparm(pgm, PARAM_STATUS_TGT_CONN, &buf[0]) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_program_enable(): cannot get connection status\n",
+ progname);
+ } else {
+ stk500v2_translate_conn_status(buf[0], msg);
+ avrdude_message(MSG_INFO, "%s: stk500v2_program_enable():"
+ " bad AVRISPmkII connection status: %s\n",
+ progname, msg);
+ }
+ break;
+
+ case PGMTYPE_JTAGICE3:
+ return -1;
+ // if (buf[1] == STATUS_CMD_FAILED &&
+ // (p->flags & AVRPART_HAS_DW) != 0) {
+ // void *mycookie;
+ // unsigned char cmd[4], *resp;
+
+ // /* Try debugWIRE, and MONCON_DISABLE */
+ // avrdude_message(MSG_NOTICE2, "%s: No response in ISP mode, trying debugWIRE\n",
+ // progname);
+
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+
+ // cmd[0] = PARM3_CONN_DW;
+ // if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, cmd, 1) < 0) {
+ // pgm->cookie = mycookie;
+ // break;
+ // }
+
+ // cmd[0] = SCOPE_AVR;
+
+ // cmd[1] = CMD3_SIGN_ON;
+ // cmd[2] = cmd[3] = 0;
+ // if (jtag3_command(pgm, cmd, 4, &resp, "AVR sign-on") >= 0) {
+ // free(resp);
+
+ // cmd[1] = CMD3_START_DW_DEBUG;
+ // if (jtag3_command(pgm, cmd, 4, &resp, "start DW debug") >= 0) {
+ // free(resp);
+
+ // cmd[1] = CMD3_MONCON_DISABLE;
+ // if (jtag3_command(pgm, cmd, 3, &resp, "MonCon disable") >= 0)
+ // free(resp);
+ // }
+ // }
+ // pgm->cookie = mycookie;
+ // if (tries++ > 3) {
+ // avrdude_message(MSG_INFO, "%s: Failed to return from debugWIRE to ISP.\n",
+ // progname);
+ // break;
+ // }
+ // avrdude_message(MSG_INFO, "%s: Target prepared for ISP, signed off.\n"
+ // "%s: Now retrying without power-cycling the target.\n",
+ // progname, progname);
+ // goto retry;
+ // }
+ break;
+
+ default:
+ /* cannot report anything for other pgmtypes */
+ break;
+ }
+ }
+
+ return rv;
+}
+
+/*
+ * issue the 'program enable' command to the AVR device, parallel mode
+ */
+static int stk500pp_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char buf[16];
+
+ PDATA(pgm)->lastpart = p;
+
+ buf[0] = CMD_ENTER_PROGMODE_PP;
+ buf[1] = p->hventerstabdelay;
+ buf[2] = p->progmodedelay;
+ buf[3] = p->latchcycles;
+ buf[4] = p->togglevtg;
+ buf[5] = p->poweroffdelay;
+ buf[6] = p->resetdelayms;
+ buf[7] = p->resetdelayus;
+
+ return stk500v2_command(pgm, buf, 8, sizeof(buf));
+}
+
+/*
+ * issue the 'program enable' command to the AVR device, HVSP mode
+ */
+static int stk500hvsp_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char buf[16];
+
+ PDATA(pgm)->lastpart = p;
+
+ buf[0] = PDATA(pgm)->pgmtype == PGMTYPE_STK600?
+ CMD_ENTER_PROGMODE_HVSP_STK600:
+ CMD_ENTER_PROGMODE_HVSP;
+ buf[1] = p->hventerstabdelay;
+ buf[2] = p->hvspcmdexedelay;
+ buf[3] = p->synchcycles;
+ buf[4] = p->latchcycles;
+ buf[5] = p->togglevtg;
+ buf[6] = p->poweroffdelay;
+ buf[7] = p->resetdelayms;
+ buf[8] = p->resetdelayus;
+
+ return stk500v2_command(pgm, buf, 9, sizeof(buf));
+}
+
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+static int stk500v2_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+
+ LNODEID ln;
+ AVRMEM * m;
+
+ if ((PDATA(pgm)->pgmtype == PGMTYPE_STK600 ||
+ PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII ||
+ PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) != 0
+ && (p->flags & (AVRPART_HAS_PDI | AVRPART_HAS_TPI)) != 0) {
+ /*
+ * This is an ATxmega device, must use XPROG protocol for the
+ * remaining actions.
+ */
+ if ((p->flags & AVRPART_HAS_PDI) != 0) {
+ /*
+ * Find out where the border between application and boot area
+ * is.
+ */
+ AVRMEM *bootmem = avr_locate_mem(p, "boot");
+ AVRMEM *flashmem = avr_locate_mem(p, "flash");
+ if (bootmem == NULL || flashmem == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_initialize(): Cannot locate \"flash\" and \"boot\" memories in description\n",
+ progname);
+ } else {
+ PDATA(pgm)->boot_start = bootmem->offset - flashmem->offset;
+ }
+ }
+ stk600_setup_xprog(pgm);
+ } else {
+ stk600_setup_isp(pgm);
+ }
+
+ /*
+ * Examine the avrpart's memory definitions, and initialize the page
+ * caches. For devices/memory that are not page oriented, treat
+ * them as page size 1 for EEPROM, and 2 for flash.
+ */
+ PDATA(pgm)->flash_pagesize = 2;
+ PDATA(pgm)->eeprom_pagesize = 1;
+ for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
+ m = ldata(ln);
+ if (strcmp(m->desc, "flash") == 0) {
+ if (m->page_size > 0) {
+ if (m->page_size > 256)
+ PDATA(pgm)->flash_pagesize = 256;
+ else
+ PDATA(pgm)->flash_pagesize = m->page_size;
+ }
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ if (m->page_size > 0)
+ PDATA(pgm)->eeprom_pagesize = m->page_size;
+ }
+ }
+ free(PDATA(pgm)->flash_pagecache);
+ free(PDATA(pgm)->eeprom_pagecache);
+ if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_initialize(): Out of memory\n",
+ progname);
+ return -1;
+ }
+ if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_initialize(): Out of memory\n",
+ progname);
+ free(PDATA(pgm)->flash_pagecache);
+ return -1;
+ }
+ PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+
+ if (p->flags & AVRPART_IS_AT90S1200) {
+ /*
+ * AT90S1200 needs a positive reset pulse after a chip erase.
+ */
+ pgm->disable(pgm);
+ usleep(10000);
+ }
+ return pgm->program_enable(pgm, p);
+}
+
+
+
+/*
+ * initialize the AVR device and prepare it to accept commands
+ */
+static int stk500v2_jtag3_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ return -1;
+ // unsigned char parm[4], *resp;
+ // LNODEID ln;
+ // AVRMEM * m;
+ // void *mycookie;
+
+ // if ((p->flags & AVRPART_HAS_PDI) ||
+ // (p->flags & AVRPART_HAS_TPI)) {
+ // avrdude_message(MSG_INFO, "%s: jtag3_initialize(): part %s has no ISP interface\n",
+ // progname, p->desc);
+ // return -1;
+ // }
+
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+
+ // if (p->flags & AVRPART_HAS_DW)
+ // parm[0] = PARM3_ARCH_TINY;
+ // else
+ // parm[0] = PARM3_ARCH_MEGA;
+ // if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_ARCH, parm, 1) < 0) {
+ // pgm->cookie = mycookie;
+ // return -1;
+ // }
+
+ // parm[0] = PARM3_SESS_PROGRAMMING;
+ // if (jtag3_setparm(pgm, SCOPE_AVR, 0, PARM3_SESS_PURPOSE, parm, 1) < 0) {
+ // pgm->cookie = mycookie;
+ // return -1;
+ // }
+
+ // parm[0] = PARM3_CONN_ISP;
+ // if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, parm, 1) < 0) {
+ // pgm->cookie = mycookie;
+ // return -1;
+ // }
+
+ // parm[0] = SCOPE_AVR_ISP;
+ // parm[1] = 0x1e;
+ // jtag3_send(pgm, parm, 2);
+
+ // if (jtag3_recv(pgm, &resp) > 0)
+ // free(resp);
+
+ // pgm->cookie = mycookie;
+
+ // /*
+ // * Examine the avrpart's memory definitions, and initialize the page
+ // * caches. For devices/memory that are not page oriented, treat
+ // * them as page size 1 for EEPROM, and 2 for flash.
+ // */
+ // PDATA(pgm)->flash_pagesize = 2;
+ // PDATA(pgm)->eeprom_pagesize = 1;
+ // for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
+ // m = ldata(ln);
+ // if (strcmp(m->desc, "flash") == 0) {
+ // if (m->page_size > 0) {
+ // if (m->page_size > 256)
+ // PDATA(pgm)->flash_pagesize = 256;
+ // else
+ // PDATA(pgm)->flash_pagesize = m->page_size;
+ // }
+ // } else if (strcmp(m->desc, "eeprom") == 0) {
+ // if (m->page_size > 0)
+ // PDATA(pgm)->eeprom_pagesize = m->page_size;
+ // }
+ // }
+ // free(PDATA(pgm)->flash_pagecache);
+ // free(PDATA(pgm)->eeprom_pagecache);
+ // if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
+ // avrdude_message(MSG_INFO, "%s: stk500hv_initialize(): Out of memory\n",
+ // progname);
+ // return -1;
+ // }
+ // if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
+ // avrdude_message(MSG_INFO, "%s: stk500hv_initialize(): Out of memory\n",
+ // progname);
+ // free(PDATA(pgm)->flash_pagecache);
+ // return -1;
+ // }
+ // PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+
+ // return pgm->program_enable(pgm, p);
+}
+
+
+/*
+ * initialize the AVR device and prepare it to accept commands, generic HV mode
+ */
+static int stk500hv_initialize(PROGRAMMER * pgm, AVRPART * p, enum hvmode mode)
+{
+ unsigned char buf[CTL_STACK_SIZE + 1];
+ int result;
+ LNODEID ln;
+ AVRMEM * m;
+
+ if (p->ctl_stack_type != (mode == PPMODE? CTL_STACK_PP: CTL_STACK_HVSP)) {
+ avrdude_message(MSG_INFO, "%s: stk500hv_initialize(): "
+ "%s programming control stack not defined for part \"%s\"\n",
+ progname,
+ (mode == PPMODE? "parallel": "high-voltage serial"),
+ p->desc);
+ return -1;
+ }
+
+ buf[0] = CMD_SET_CONTROL_STACK;
+ memcpy(buf + 1, p->controlstack, CTL_STACK_SIZE);
+
+ result = stk500v2_command(pgm, buf, CTL_STACK_SIZE + 1, sizeof(buf));
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500hv_initalize(): "
+ "failed to set control stack\n",
+ progname);
+ return -1;
+ }
+
+ /*
+ * Examine the avrpart's memory definitions, and initialize the page
+ * caches. For devices/memory that are not page oriented, treat
+ * them as page size 1 for EEPROM, and 2 for flash.
+ */
+ PDATA(pgm)->flash_pagesize = 2;
+ PDATA(pgm)->eeprom_pagesize = 1;
+ for (ln = lfirst(p->mem); ln; ln = lnext(ln)) {
+ m = ldata(ln);
+ if (strcmp(m->desc, "flash") == 0) {
+ if (m->page_size > 0) {
+ if (m->page_size > 256)
+ PDATA(pgm)->flash_pagesize = 256;
+ else
+ PDATA(pgm)->flash_pagesize = m->page_size;
+ }
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ if (m->page_size > 0)
+ PDATA(pgm)->eeprom_pagesize = m->page_size;
+ }
+ }
+ free(PDATA(pgm)->flash_pagecache);
+ free(PDATA(pgm)->eeprom_pagecache);
+ if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500hv_initialize(): Out of memory\n",
+ progname);
+ return -1;
+ }
+ if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500hv_initialize(): Out of memory\n",
+ progname);
+ free(PDATA(pgm)->flash_pagecache);
+ return -1;
+ }
+ PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+
+ return pgm->program_enable(pgm, p);
+}
+
+/*
+ * initialize the AVR device and prepare it to accept commands, PP mode
+ */
+static int stk500pp_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ return stk500hv_initialize(pgm, p, PPMODE);
+}
+
+/*
+ * initialize the AVR device and prepare it to accept commands, HVSP mode
+ */
+static int stk500hvsp_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ return stk500hv_initialize(pgm, p, HVSPMODE);
+}
+
+static void stk500v2_jtag3_disable(PROGRAMMER * pgm)
+{
+ unsigned char buf[16];
+ int result;
+
+ free(PDATA(pgm)->flash_pagecache);
+ PDATA(pgm)->flash_pagecache = NULL;
+ free(PDATA(pgm)->eeprom_pagecache);
+ PDATA(pgm)->eeprom_pagecache = NULL;
+
+ buf[0] = CMD_LEAVE_PROGMODE_ISP;
+ buf[1] = 1; // preDelay;
+ buf[2] = 1; // postDelay;
+
+ result = stk500v2_command(pgm, buf, 3, sizeof(buf));
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_disable(): failed to leave programming mode\n",
+ progname);
+ }
+
+ return;
+}
+
+static void stk500v2_disable(PROGRAMMER * pgm)
+{
+ unsigned char buf[16];
+ int result;
+
+ buf[0] = CMD_LEAVE_PROGMODE_ISP;
+ buf[1] = 1; // preDelay;
+ buf[2] = 1; // postDelay;
+
+ result = stk500v2_command(pgm, buf, 3, sizeof(buf));
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_disable(): failed to leave programming mode\n",
+ progname);
+ }
+
+ return;
+}
+
+/*
+ * Leave programming mode, generic HV mode
+ */
+static void stk500hv_disable(PROGRAMMER * pgm, enum hvmode mode)
+{
+ unsigned char buf[16];
+ int result;
+
+ free(PDATA(pgm)->flash_pagecache);
+ PDATA(pgm)->flash_pagecache = NULL;
+ free(PDATA(pgm)->eeprom_pagecache);
+ PDATA(pgm)->eeprom_pagecache = NULL;
+
+ buf[0] = mode == PPMODE? CMD_LEAVE_PROGMODE_PP:
+ (PDATA(pgm)->pgmtype == PGMTYPE_STK600?
+ CMD_LEAVE_PROGMODE_HVSP_STK600:
+ CMD_LEAVE_PROGMODE_HVSP);
+ buf[1] = 15; // p->hvleavestabdelay;
+ buf[2] = 15; // p->resetdelay;
+
+ result = stk500v2_command(pgm, buf, 3, sizeof(buf));
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500hv_disable(): "
+ "failed to leave programming mode\n",
+ progname);
+ }
+
+ return;
+}
+
+/*
+ * Leave programming mode, PP mode
+ */
+static void stk500pp_disable(PROGRAMMER * pgm)
+{
+ stk500hv_disable(pgm, PPMODE);
+}
+
+/*
+ * Leave programming mode, HVSP mode
+ */
+static void stk500hvsp_disable(PROGRAMMER * pgm)
+{
+ stk500hv_disable(pgm, HVSPMODE);
+}
+
+static void stk500v2_enable(PROGRAMMER * pgm)
+{
+ return;
+}
+
+
+static int stk500v2_open(PROGRAMMER * pgm, char * port)
+{
+ union pinfo pinfo = { .baud = 115200 };
+
+ DEBUG("STK500V2: stk500v2_open()\n");
+
+ if (pgm->baudrate)
+ pinfo.baud = pgm->baudrate;
+
+ PDATA(pgm)->pgmtype = PGMTYPE_UNKNOWN;
+
+ if(strcasecmp(port, "avrdoper") == 0){
+#if defined(HAVE_LIBUSB) || (defined(WIN32NATIVE) && defined(HAVE_LIBHID))
+ serdev = &avrdoper_serdev;
+ PDATA(pgm)->pgmtype = PGMTYPE_STK500;
+#else
+ avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+ return -1;
+#endif
+ }
+
+ /*
+ * If the port name starts with "usb", divert the serial routines
+ * to the USB ones. The serial_open() function for USB overrides
+ * the meaning of the "baud" parameter to be the USB device ID to
+ * search for.
+ */
+ if (strncmp(port, "usb", 3) == 0) {
+#if defined(HAVE_LIBUSB)
+ serdev = &usb_serdev_frame;
+ pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+ pinfo.usbinfo.flags = 0;
+ pinfo.usbinfo.pid = USB_DEVICE_AVRISPMKII;
+ PDATA(pgm)->pgmtype = PGMTYPE_AVRISP_MKII;
+ pgm->set_sck_period = stk500v2_set_sck_period_mk2;
+ pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+ pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
+ pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
+ pgm->fd.usb.eep = 0; /* no seperate EP for events */
+#else
+ avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+ return -1;
+#endif
+ }
+
+ strcpy(pgm->port, port);
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ stk500v2_drain(pgm, 0);
+
+ stk500v2_getsync(pgm);
+
+ stk500v2_drain(pgm, 0);
+
+ if (pgm->bitclock != 0.0) {
+ if (pgm->set_sck_period(pgm, pgm->bitclock) != 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int stk600_open(PROGRAMMER * pgm, char * port)
+{
+ union pinfo pinfo = { .baud = 115200 };
+
+ DEBUG("STK500V2: stk600_open()\n");
+
+ if (pgm->baudrate)
+ pinfo.baud = pgm->baudrate;
+
+ PDATA(pgm)->pgmtype = PGMTYPE_UNKNOWN;
+
+ /*
+ * If the port name starts with "usb", divert the serial routines
+ * to the USB ones. The serial_open() function for USB overrides
+ * the meaning of the "baud" parameter to be the USB device ID to
+ * search for.
+ */
+ if (strncmp(port, "usb", 3) == 0) {
+#if defined(HAVE_LIBUSB)
+ serdev = &usb_serdev_frame;
+ pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+ pinfo.usbinfo.flags = 0;
+ pinfo.usbinfo.pid = USB_DEVICE_STK600;
+ PDATA(pgm)->pgmtype = PGMTYPE_STK600;
+ pgm->set_sck_period = stk600_set_sck_period;
+ pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+ pgm->fd.usb.rep = USBDEV_BULK_EP_READ_STK600;
+ pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_STK600;
+ pgm->fd.usb.eep = 0; /* no seperate EP for events */
+#else
+ avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+ return -1;
+#endif
+ }
+
+ strcpy(pgm->port, port);
+ if (serial_open(port, pinfo, &pgm->fd)==-1) {
+ return -1;
+ }
+
+ /*
+ * drain any extraneous input
+ */
+ stk500v2_drain(pgm, 0);
+
+ stk500v2_getsync(pgm);
+
+ stk500v2_drain(pgm, 0);
+
+ if (pgm->bitclock != 0.0) {
+ if (pgm->set_sck_period(pgm, pgm->bitclock) != 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static void stk500v2_close(PROGRAMMER * pgm)
+{
+ DEBUG("STK500V2: stk500v2_close()\n");
+
+ serial_close(&pgm->fd);
+ pgm->fd.ifd = -1;
+}
+
+
+static int stk500v2_loadaddr(PROGRAMMER * pgm, unsigned int addr)
+{
+ unsigned char buf[16];
+ int result;
+
+ DEBUG("STK500V2: stk500v2_loadaddr(%d)\n",addr);
+
+ buf[0] = CMD_LOAD_ADDRESS;
+ buf[1] = (addr >> 24) & 0xff;
+ buf[2] = (addr >> 16) & 0xff;
+ buf[3] = (addr >> 8) & 0xff;
+ buf[4] = addr & 0xff;
+
+ result = stk500v2_command(pgm, buf, 5, sizeof(buf));
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_loadaddr(): failed to set load address\n",
+ progname);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Read a single byte, generic HV mode
+ */
+static int stk500hv_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value,
+ enum hvmode mode)
+{
+ int result, cmdlen = 2;
+ unsigned char buf[266];
+ unsigned long paddr = 0UL, *paddr_ptr = NULL;
+ unsigned int pagesize = 0, use_ext_addr = 0, addrshift = 0;
+ unsigned char *cache_ptr = NULL;
+
+ avrdude_message(MSG_NOTICE2, "%s: stk500hv_read_byte(.., %s, 0x%lx, ...)\n",
+ progname, mem->desc, addr);
+
+ if (strcmp(mem->desc, "flash") == 0) {
+ buf[0] = mode == PPMODE? CMD_READ_FLASH_PP: CMD_READ_FLASH_HVSP;
+ cmdlen = 3;
+ pagesize = PDATA(pgm)->flash_pagesize;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->flash_pageaddr;
+ cache_ptr = PDATA(pgm)->flash_pagecache;
+ addrshift = 1;
+ /*
+ * If bit 31 is set, this indicates that the following read/write
+ * operation will be performed on a memory that is larger than
+ * 64KBytes. This is an indication to STK500 that a load extended
+ * address must be executed.
+ */
+ if (mem->op[AVR_OP_LOAD_EXT_ADDR] != NULL) {
+ use_ext_addr = (1U << 31);
+ }
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ buf[0] = mode == PPMODE? CMD_READ_EEPROM_PP: CMD_READ_EEPROM_HVSP;
+ cmdlen = 3;
+ pagesize = mem->page_size;
+ if (pagesize == 0)
+ pagesize = 1;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
+ cache_ptr = PDATA(pgm)->eeprom_pagecache;
+ } else if (strcmp(mem->desc, "lfuse") == 0 ||
+ strcmp(mem->desc, "fuse") == 0) {
+ buf[0] = mode == PPMODE? CMD_READ_FUSE_PP: CMD_READ_FUSE_HVSP;
+ addr = 0;
+ } else if (strcmp(mem->desc, "hfuse") == 0) {
+ buf[0] = mode == PPMODE? CMD_READ_FUSE_PP: CMD_READ_FUSE_HVSP;
+ addr = 1;
+ } else if (strcmp(mem->desc, "efuse") == 0) {
+ buf[0] = mode == PPMODE? CMD_READ_FUSE_PP: CMD_READ_FUSE_HVSP;
+ addr = 2;
+ } else if (strcmp(mem->desc, "lock") == 0) {
+ buf[0] = mode == PPMODE? CMD_READ_LOCK_PP: CMD_READ_LOCK_HVSP;
+ } else if (strcmp(mem->desc, "calibration") == 0) {
+ buf[0] = mode == PPMODE? CMD_READ_OSCCAL_PP: CMD_READ_OSCCAL_HVSP;
+ } else if (strcmp(mem->desc, "signature") == 0) {
+ buf[0] = mode == PPMODE? CMD_READ_SIGNATURE_PP: CMD_READ_SIGNATURE_HVSP;
+ }
+
+ /*
+ * In HV mode, we have to use paged reads for flash and
+ * EEPROM, and cache the results in a page cache.
+ *
+ * Page cache validation is based on "{flash,eeprom}_pageaddr"
+ * (holding the base address of the most recent cache fill
+ * operation). This variable is set to (unsigned long)-1L when the
+ * cache needs to be invalidated.
+ */
+ if (pagesize && paddr == *paddr_ptr) {
+ *value = cache_ptr[addr & (pagesize - 1)];
+ return 0;
+ }
+
+ if (cmdlen == 3) {
+ /* long command, fill in # of bytes */
+ buf[1] = (pagesize >> 8) & 0xff;
+ buf[2] = pagesize & 0xff;
+
+ /* flash and EEPROM reads require the load address command */
+ if (stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0)
+ return -1;
+ } else {
+ buf[1] = addr;
+ }
+
+ avrdude_message(MSG_NOTICE2, "%s: stk500hv_read_byte(): Sending read memory command: ",
+ progname);
+
+ result = stk500v2_command(pgm, buf, cmdlen, sizeof(buf));
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500hv_read_byte(): "
+ "timeout/error communicating with programmer\n",
+ progname);
+ return -1;
+ }
+
+ if (pagesize) {
+ *paddr_ptr = paddr;
+ memcpy(cache_ptr, buf + 2, pagesize);
+ *value = cache_ptr[addr & (pagesize - 1)];
+ } else {
+ *value = buf[2];
+ }
+
+ return 0;
+}
+
+/*
+ * Read a single byte, PP mode
+ */
+static int stk500pp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value)
+{
+ return stk500hv_read_byte(pgm, p, mem, addr, value, PPMODE);
+}
+
+/*
+ * Read a single byte, HVSP mode
+ */
+static int stk500hvsp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value)
+{
+ return stk500hv_read_byte(pgm, p, mem, addr, value, HVSPMODE);
+}
+
+/*
+ * Read a single byte, ISP mode
+ *
+ * By now, only used on the JTAGICE3 which does not implement the
+ * CMD_SPI_MULTI SPI passthrough command.
+ */
+static int stk500isp_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value)
+{
+ int result, pollidx;
+ unsigned char buf[6];
+ unsigned long paddr = 0UL, *paddr_ptr = NULL;
+ unsigned int pagesize = 0;
+ unsigned char *cache_ptr = NULL;
+ OPCODE *op;
+
+ avrdude_message(MSG_NOTICE2, "%s: stk500isp_read_byte(.., %s, 0x%lx, ...)\n",
+ progname, mem->desc, addr);
+
+ if (strcmp(mem->desc, "flash") == 0 ||
+ strcmp(mem->desc, "eeprom") == 0) {
+ // use paged access, and cache result
+ if (strcmp(mem->desc, "flash") == 0) {
+ pagesize = PDATA(pgm)->flash_pagesize;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->flash_pageaddr;
+ cache_ptr = PDATA(pgm)->flash_pagecache;
+ } else {
+ pagesize = mem->page_size;
+ if (pagesize == 0)
+ pagesize = 1;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
+ cache_ptr = PDATA(pgm)->eeprom_pagecache;
+ }
+
+ if (paddr == *paddr_ptr) {
+ *value = cache_ptr[addr & (pagesize - 1)];
+ return 0;
+ }
+
+ if (stk500v2_paged_load(pgm, p, mem, pagesize, paddr, pagesize) < 0)
+ return -1;
+
+ *paddr_ptr = paddr;
+ memcpy(cache_ptr, &mem->buf[paddr], pagesize);
+ *value = cache_ptr[addr & (pagesize - 1)];
+
+ return 0;
+ }
+
+ if (strcmp(mem->desc, "lfuse") == 0 ||
+ strcmp(mem->desc, "fuse") == 0) {
+ buf[0] = CMD_READ_FUSE_ISP;
+ addr = 0;
+ } else if (strcmp(mem->desc, "hfuse") == 0) {
+ buf[0] = CMD_READ_FUSE_ISP;
+ addr = 1;
+ } else if (strcmp(mem->desc, "efuse") == 0) {
+ buf[0] = CMD_READ_FUSE_ISP;
+ addr = 2;
+ } else if (strcmp(mem->desc, "lock") == 0) {
+ buf[0] = CMD_READ_LOCK_ISP;
+ } else if (strcmp(mem->desc, "calibration") == 0) {
+ buf[0] = CMD_READ_OSCCAL_ISP;
+ } else if (strcmp(mem->desc, "signature") == 0) {
+ buf[0] = CMD_READ_SIGNATURE_ISP;
+ }
+
+ memset(buf + 1, 0, 5);
+ if ((op = mem->op[AVR_OP_READ]) == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500isp_read_byte(): invalid operation AVR_OP_READ on %s memory\n",
+ progname, mem->desc);
+ return -1;
+ }
+ avr_set_bits(op, buf + 2);
+ if ((pollidx = avr_get_output_index(op)) == -1) {
+ avrdude_message(MSG_INFO, "%s: stk500isp_read_byte(): cannot determine pollidx to read %s memory\n",
+ progname, mem->desc);
+ pollidx = 3;
+ }
+ buf[1] = pollidx + 1;
+ avr_set_addr(op, buf + 2, addr);
+
+ avrdude_message(MSG_NOTICE2, "%s: stk500isp_read_byte(): Sending read memory command: ",
+ progname);
+
+ result = stk500v2_command(pgm, buf, 6, sizeof(buf));
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500isp_read_byte(): "
+ "timeout/error communicating with programmer\n",
+ progname);
+ return -1;
+ }
+
+ *value = buf[2];
+
+ return 0;
+}
+
+/*
+ * Write one byte, generic HV mode
+ */
+static int stk500hv_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data,
+ enum hvmode mode)
+{
+ int result, cmdlen, timeout = 0, pulsewidth = 0;
+ unsigned char buf[266];
+ unsigned long paddr = 0UL, *paddr_ptr = NULL;
+ unsigned int pagesize = 0, use_ext_addr = 0, addrshift = 0;
+ unsigned char *cache_ptr = NULL;
+
+ avrdude_message(MSG_NOTICE2, "%s: stk500hv_write_byte(.., %s, 0x%lx, ...)\n",
+ progname, mem->desc, addr);
+
+ if (strcmp(mem->desc, "flash") == 0) {
+ buf[0] = mode == PPMODE? CMD_PROGRAM_FLASH_PP: CMD_PROGRAM_FLASH_HVSP;
+ pagesize = PDATA(pgm)->flash_pagesize;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->flash_pageaddr;
+ cache_ptr = PDATA(pgm)->flash_pagecache;
+ addrshift = 1;
+ /*
+ * If bit 31 is set, this indicates that the following read/write
+ * operation will be performed on a memory that is larger than
+ * 64KBytes. This is an indication to STK500 that a load extended
+ * address must be executed.
+ */
+ if (mem->op[AVR_OP_LOAD_EXT_ADDR] != NULL) {
+ use_ext_addr = (1U << 31);
+ }
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ buf[0] = mode == PPMODE? CMD_PROGRAM_EEPROM_PP: CMD_PROGRAM_EEPROM_HVSP;
+ pagesize = mem->page_size;
+ if (pagesize == 0)
+ pagesize = 1;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
+ cache_ptr = PDATA(pgm)->eeprom_pagecache;
+ } else if (strcmp(mem->desc, "lfuse") == 0 ||
+ strcmp(mem->desc, "fuse") == 0) {
+ buf[0] = mode == PPMODE? CMD_PROGRAM_FUSE_PP: CMD_PROGRAM_FUSE_HVSP;
+ addr = 0;
+ pulsewidth = p->programfusepulsewidth;
+ timeout = p->programfusepolltimeout;
+ } else if (strcmp(mem->desc, "hfuse") == 0) {
+ buf[0] = mode == PPMODE? CMD_PROGRAM_FUSE_PP: CMD_PROGRAM_FUSE_HVSP;
+ addr = 1;
+ pulsewidth = p->programfusepulsewidth;
+ timeout = p->programfusepolltimeout;
+ } else if (strcmp(mem->desc, "efuse") == 0) {
+ buf[0] = mode == PPMODE? CMD_PROGRAM_FUSE_PP: CMD_PROGRAM_FUSE_HVSP;
+ addr = 2;
+ pulsewidth = p->programfusepulsewidth;
+ timeout = p->programfusepolltimeout;
+ } else if (strcmp(mem->desc, "lock") == 0) {
+ buf[0] = mode == PPMODE? CMD_PROGRAM_LOCK_PP: CMD_PROGRAM_LOCK_HVSP;
+ pulsewidth = p->programlockpulsewidth;
+ timeout = p->programlockpolltimeout;
+ } else {
+ avrdude_message(MSG_INFO, "%s: stk500hv_write_byte(): "
+ "unsupported memory type: %s\n",
+ progname, mem->desc);
+ return -1;
+ }
+
+ cmdlen = 5 + pagesize;
+
+ /*
+ * In HV mode, we have to use paged writes for flash and
+ * EEPROM. As both, flash and EEPROM cells can only be programmed
+ * from `1' to `0' bits (even EEPROM does not support auto-erase in
+ * parallel mode), we just pre-fill the page cache with 0xff, so all
+ * those cells that are outside our current address will remain
+ * unaffected.
+ */
+ if (pagesize) {
+ memset(cache_ptr, 0xff, pagesize);
+ cache_ptr[addr & (pagesize - 1)] = data;
+
+ /* long command, fill in # of bytes */
+ buf[1] = (pagesize >> 8) & 0xff;
+ buf[2] = pagesize & 0xff;
+
+ /*
+ * Synthesize the mode byte. This is simpler than adding yet
+ * another parameter to the avrdude.conf file. We calculate the
+ * bits corresponding to the page size, as explained in AVR068.
+ * We set bit 7, to indicate this is to actually write the page to
+ * the target device. We set bit 6 to indicate this is the very
+ * last page to be programmed, whatever this means -- we just
+ * pretend we don't know any better. ;-) Bit 0 is set if this is
+ * a paged memory, which means it has a page size of more than 2.
+ */
+ buf[3] = 0x80 | 0x40;
+ if (pagesize > 2) {
+ unsigned int rv = stk500v2_mode_for_pagesize(pagesize);
+ if (rv == 0)
+ return -1;
+ buf[3] |= rv;
+ buf[3] |= 0x01;
+ }
+ buf[4] = mem->delay;
+ memcpy(buf + 5, cache_ptr, pagesize);
+
+ /* flash and EEPROM reads require the load address command */
+ if (stk500v2_loadaddr(pgm, use_ext_addr | (paddr >> addrshift)) < 0)
+ return -1;
+ } else {
+ buf[1] = addr;
+ buf[2] = data;
+ if (mode == PPMODE) {
+ buf[3] = pulsewidth;
+ buf[4] = timeout;
+ } else {
+ buf[3] = timeout;
+ cmdlen--;
+ }
+ }
+
+ avrdude_message(MSG_NOTICE2, "%s: stk500hv_write_byte(): Sending write memory command: ",
+ progname);
+
+ result = stk500v2_command(pgm, buf, cmdlen, sizeof(buf));
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500hv_write_byte(): "
+ "timeout/error communicating with programmer\n",
+ progname);
+ return -1;
+ }
+
+ if (pagesize) {
+ /* Invalidate the page cache. */
+ *paddr_ptr = (unsigned long)-1L;
+ }
+
+ return 0;
+}
+
+/*
+ * Write one byte, PP mode
+ */
+static int stk500pp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data)
+{
+ return stk500hv_write_byte(pgm, p, mem, addr, data, PPMODE);
+}
+
+/*
+ * Write one byte, HVSP mode
+ */
+static int stk500hvsp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data)
+{
+ return stk500hv_write_byte(pgm, p, mem, addr, data, HVSPMODE);
+}
+
+
+/*
+ * Write one byte, ISP mode
+ */
+static int stk500isp_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data)
+{
+ int result;
+ unsigned char buf[5];
+ unsigned long paddr = 0UL, *paddr_ptr = NULL;
+ unsigned int pagesize = 0;
+ unsigned char *cache_ptr = NULL;
+ OPCODE *op;
+
+ avrdude_message(MSG_NOTICE2, "%s: stk500isp_write_byte(.., %s, 0x%lx, ...)\n",
+ progname, mem->desc, addr);
+
+ if (strcmp(mem->desc, "flash") == 0 ||
+ strcmp(mem->desc, "eeprom") == 0) {
+ if (strcmp(mem->desc, "flash") == 0) {
+ pagesize = PDATA(pgm)->flash_pagesize;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->flash_pageaddr;
+ cache_ptr = PDATA(pgm)->flash_pagecache;
+ } else {
+ pagesize = mem->page_size;
+ if (pagesize == 0)
+ pagesize = 1;
+ paddr = addr & ~(pagesize - 1);
+ paddr_ptr = &PDATA(pgm)->eeprom_pageaddr;
+ cache_ptr = PDATA(pgm)->eeprom_pagecache;
+ }
+
+ /*
+ * We use paged writes for flash and EEPROM, reading back the
+ * current page first, modify the byte to write, and write out the
+ * entire page.
+ */
+ if (stk500v2_paged_load(pgm, p, mem, pagesize, paddr, pagesize) < 0)
+ return -1;
+
+ memcpy(cache_ptr, mem->buf + paddr, pagesize);
+ *paddr_ptr = paddr;
+ cache_ptr[addr & (pagesize - 1)] = data;
+ memcpy(mem->buf + paddr, cache_ptr, pagesize);
+
+ stk500v2_paged_write(pgm, p, mem, pagesize, paddr, pagesize);
+
+ return 0;
+ }
+
+ memset(buf, 0, sizeof buf);
+ if (strcmp(mem->desc, "lfuse") == 0 ||
+ strcmp(mem->desc, "fuse") == 0) {
+ buf[0] = CMD_PROGRAM_FUSE_ISP;
+ addr = 0;
+ } else if (strcmp(mem->desc, "hfuse") == 0) {
+ buf[0] = CMD_PROGRAM_FUSE_ISP;
+ addr = 1;
+ } else if (strcmp(mem->desc, "efuse") == 0) {
+ buf[0] = CMD_PROGRAM_FUSE_ISP;
+ addr = 2;
+ } else if (strcmp(mem->desc, "lock") == 0) {
+ buf[0] = CMD_PROGRAM_LOCK_ISP;
+ } else {
+ avrdude_message(MSG_INFO, "%s: stk500isp_write_byte(): "
+ "unsupported memory type: %s\n",
+ progname, mem->desc);
+ return -1;
+ }
+
+ if ((op = mem->op[AVR_OP_WRITE]) == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500isp_write_byte(): "
+ "no AVR_OP_WRITE for %s memory\n",
+ progname, mem->desc);
+ return -1;
+ }
+
+ avr_set_bits(op, buf + 1);
+ avr_set_addr(op, buf + 1, addr);
+ avr_set_input(op, buf + 1, data);
+
+ avrdude_message(MSG_NOTICE2, "%s: stk500isp_write_byte(): Sending write memory command: ",
+ progname);
+
+ result = stk500v2_command(pgm, buf, 5, sizeof(buf));
+
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500isp_write_byte(): "
+ "timeout/error communicating with programmer\n",
+ progname);
+ return -1;
+ }
+
+ /*
+ * Prevent verification readback to be too fast, see
+ * https://savannah.nongnu.org/bugs/index.php?42267
+ *
+ * After all, this is just an ugly hack working around some
+ * brokeness in the Atmel firmware starting with the AVRISPmkII (the
+ * old JTAGICEmkII isn't affected). Let's hope 10 ms of additional
+ * delay are good enough for everyone.
+ */
+ usleep(10000);
+
+ return 0;
+}
+
+static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+static int page = 0;
+ unsigned int block_size, last_addr, addrshift, use_ext_addr;
+ unsigned int maxaddr = addr + n_bytes;
+ unsigned char commandbuf[10];
+ unsigned char buf[266];
+ unsigned char cmds[4];
+ int result;
+ OPCODE * rop, * wop;
+
+ // Prusa3D workaround for a bug in the USB communication controller. The semicolon character is used as an initial character
+ // for special command sequences for the USB communication chip. The early releases of the USB communication chip had
+ // a bug, which produced a 0x0ff character after the semicolon. The patch is to program the semicolons by flashing
+ // firmware blocks twice: First the low nibbles of semicolons, second the high nibbles of the semicolon characters.
+ //
+ // Inside the 2nd round of a firmware block flashing?
+ bool prusa3d_semicolon_workaround_round2 = false;
+ // Buffer containing the other nibbles of semicolons to be flashed in the 2nd round.
+ unsigned char prusa3d_semicolon_workaround_round2_data[256];
+
+ DEBUG("STK500V2: stk500v2_paged_write(..,%s,%u,%u,%u)\n",
+ m->desc, page_size, addr, n_bytes);
+
+ if (page_size == 0) page_size = 256;
+ addrshift = 0;
+ use_ext_addr = 0;
+
+ // determine which command is to be used
+ if (strcmp(m->desc, "flash") == 0) {
+ addrshift = 1;
+ commandbuf[0] = CMD_PROGRAM_FLASH_ISP;
+ /*
+ * If bit 31 is set, this indicates that the following read/write
+ * operation will be performed on a memory that is larger than
+ * 64KBytes. This is an indication to STK500 that a load extended
+ * address must be executed.
+ */
+ if (m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) {
+ use_ext_addr = (1U << 31);
+ }
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ commandbuf[0] = CMD_PROGRAM_EEPROM_ISP;
+ }
+ commandbuf[4] = m->delay;
+
+ if (addrshift == 0) {
+ wop = m->op[AVR_OP_WRITE];
+ rop = m->op[AVR_OP_READ];
+ }
+ else {
+ wop = m->op[AVR_OP_WRITE_LO];
+ rop = m->op[AVR_OP_READ_LO];
+ }
+
+ // if the memory is paged, load the appropriate commands into the buffer
+ if (m->mode & 0x01) {
+ commandbuf[3] = m->mode | 0x80; // yes, write the page to flash
+
+ if (m->op[AVR_OP_LOADPAGE_LO] == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_paged_write: loadpage instruction not defined for part \"%s\"\n",
+ progname, p->desc);
+ return -1;
+ }
+ avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], cmds);
+ commandbuf[5] = cmds[0];
+
+ if (m->op[AVR_OP_WRITEPAGE] == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_paged_write: write page instruction not defined for part \"%s\"\n",
+ progname, p->desc);
+ return -1;
+ }
+ avr_set_bits(m->op[AVR_OP_WRITEPAGE], cmds);
+ commandbuf[6] = cmds[0];
+
+ // otherwise, we need to load different commands in
+ }
+ else {
+ commandbuf[3] = m->mode | 0x80; // yes, write the words to flash
+
+ if (wop == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_paged_write: write instruction not defined for part \"%s\"\n",
+ progname, p->desc);
+ return -1;
+ }
+ avr_set_bits(wop, cmds);
+ commandbuf[5] = cmds[0];
+ commandbuf[6] = 0;
+ }
+
+ // the read command is common to both methods
+ if (rop == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_paged_write: read instruction not defined for part \"%s\"\n",
+ progname, p->desc);
+ return -1;
+ }
+ avr_set_bits(rop, cmds);
+ commandbuf[7] = cmds[0];
+
+ commandbuf[8] = m->readback[0];
+ commandbuf[9] = m->readback[1];
+
+ last_addr=UINT_MAX; /* impossible address */
+
+ for (; addr < maxaddr; addr += prusa3d_semicolon_workaround_round2 ? 0 : page_size) {
+ if ((maxaddr - addr) < page_size)
+ block_size = maxaddr - addr;
+ else
+ block_size = page_size;
+
+ DEBUG("block_size at addr %d is %d\n",addr,block_size);
+
+ memcpy(buf,commandbuf,sizeof(commandbuf));
+
+ buf[1] = block_size >> 8;
+ buf[2] = block_size & 0xff;
+
+ if((last_addr==UINT_MAX)||(last_addr+block_size != addr)||prusa3d_semicolon_workaround_round2){
+ if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0)
+ return -1;
+ }
+ last_addr=addr;
+
+ if (prusa3d_semicolon_workaround_round2) {
+ // printf("Round 2: address %d\r\n", addr);
+ memcpy(buf+10, prusa3d_semicolon_workaround_round2_data, block_size);
+ prusa3d_semicolon_workaround_round2 = false;
+ } else {
+ for (size_t i = 0; i < block_size; ++ i) {
+ unsigned char b = m->buf[addr+i];
+ if (b == ';') {
+ // printf("semicolon at %d %d\r\n", addr, i);
+ prusa3d_semicolon_workaround_round2_data[i] = b | 0x0f0;
+ b |= 0x0f;
+ prusa3d_semicolon_workaround_round2 = true;
+ } else
+ prusa3d_semicolon_workaround_round2_data[i] = 0x0ff;
+ buf[i+10] = b;
+ }
+ }
+
+ result = stk500v2_command(pgm,buf,block_size+10, sizeof(buf));
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_paged_write: write command failed\n",
+ progname);
+ return -1;
+ }
+ }
+
+ return n_bytes;
+}
+
+/*
+ * Write pages of flash/EEPROM, generic HV mode
+ */
+static int stk500hv_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes,
+ enum hvmode mode)
+{
+ unsigned int block_size, last_addr, addrshift, use_ext_addr;
+ unsigned int maxaddr = addr + n_bytes;
+ unsigned char commandbuf[5], buf[266];
+ int result;
+
+ DEBUG("STK500V2: stk500hv_paged_write(..,%s,%u,%u)\n",
+ m->desc, page_size, addr, n_bytes);
+
+ addrshift = 0;
+ use_ext_addr = 0;
+
+ // determine which command is to be used
+ if (strcmp(m->desc, "flash") == 0) {
+ addrshift = 1;
+ PDATA(pgm)->flash_pageaddr = (unsigned long)-1L;
+ commandbuf[0] = mode == PPMODE? CMD_PROGRAM_FLASH_PP: CMD_PROGRAM_FLASH_HVSP;
+ /*
+ * If bit 31 is set, this indicates that the following read/write
+ * operation will be performed on a memory that is larger than
+ * 64KBytes. This is an indication to STK500 that a load extended
+ * address must be executed.
+ */
+ if (m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) {
+ use_ext_addr = (1U << 31);
+ }
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
+ commandbuf[0] = mode == PPMODE? CMD_PROGRAM_EEPROM_PP: CMD_PROGRAM_EEPROM_HVSP;
+ }
+ /*
+ * Synthesize the mode byte. This is simpler than adding yet
+ * another parameter to the avrdude.conf file. We calculate the
+ * bits corresponding to the page size, as explained in AVR068. We
+ * set bit 7, to indicate this is to actually write the page to the
+ * target device. We set bit 6 to indicate this is the very last
+ * page to be programmed, whatever this means -- we just pretend we
+ * don't know any better. ;-) Finally, we set bit 0 to say this is
+ * a paged memory, after all, that's why we got here at all.
+ */
+ commandbuf[3] = 0x80 | 0x40;
+ if (page_size > 2) {
+ unsigned int rv = stk500v2_mode_for_pagesize(page_size);
+ if (rv == 0)
+ return -1;
+ commandbuf[3] |= rv;
+ commandbuf[3] |= 0x01;
+ }
+ commandbuf[4] = m->delay;
+
+ if (page_size == 0) page_size = 256;
+
+ last_addr = UINT_MAX; /* impossible address */
+
+ for (; addr < maxaddr; addr += page_size) {
+ if ((maxaddr - addr) < page_size)
+ block_size = maxaddr - addr;
+ else
+ block_size = page_size;
+
+ DEBUG("block_size at addr %d is %d\n",addr,block_size);
+
+ memcpy(buf, commandbuf, sizeof(commandbuf));
+
+ buf[1] = page_size >> 8;
+ buf[2] = page_size & 0xff;
+
+ if ((last_addr == UINT_MAX) || (last_addr + block_size != addr)) {
+ if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0)
+ return -1;
+ }
+ last_addr=addr;
+
+ memcpy(buf + 5, m->buf + addr, block_size);
+ if (block_size != page_size)
+ memset(buf + 5 + block_size, 0xff, page_size - block_size);
+
+ result = stk500v2_command(pgm, buf, page_size + 5, sizeof(buf));
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500hv_paged_write: write command failed\n",
+ progname);
+ return -1;
+ }
+ }
+
+ return n_bytes;
+}
+
+/*
+ * Write pages of flash/EEPROM, PP mode
+ */
+static int stk500pp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ return stk500hv_paged_write(pgm, p, m, page_size, addr, n_bytes, PPMODE);
+}
+
+/*
+ * Write pages of flash/EEPROM, HVSP mode
+ */
+static int stk500hvsp_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ return stk500hv_paged_write(pgm, p, m, page_size, addr, n_bytes, HVSPMODE);
+}
+
+static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned int block_size, hiaddr, addrshift, use_ext_addr;
+ unsigned int maxaddr = addr + n_bytes;
+ unsigned char commandbuf[4];
+ unsigned char buf[275]; // max buffer size for stk500v2 at this point
+ unsigned char cmds[4];
+ int result;
+ OPCODE * rop;
+
+ DEBUG("STK500V2: stk500v2_paged_load(..,%s,%u,%u,%u)\n",
+ m->desc, page_size, addr, n_bytes);
+
+ page_size = m->readsize;
+
+ rop = m->op[AVR_OP_READ];
+
+ hiaddr = UINT_MAX;
+ addrshift = 0;
+ use_ext_addr = 0;
+
+ // determine which command is to be used
+ if (strcmp(m->desc, "flash") == 0) {
+ commandbuf[0] = CMD_READ_FLASH_ISP;
+ rop = m->op[AVR_OP_READ_LO];
+ addrshift = 1;
+ /*
+ * If bit 31 is set, this indicates that the following read/write
+ * operation will be performed on a memory that is larger than
+ * 64KBytes. This is an indication to STK500 that a load extended
+ * address must be executed.
+ */
+ if (m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) {
+ use_ext_addr = (1U << 31);
+ }
+ }
+ else if (strcmp(m->desc, "eeprom") == 0) {
+ commandbuf[0] = CMD_READ_EEPROM_ISP;
+ }
+
+ // the read command is common to both methods
+ if (rop == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_paged_load: read instruction not defined for part \"%s\"\n",
+ progname, p->desc);
+ return -1;
+ }
+ avr_set_bits(rop, cmds);
+ commandbuf[3] = cmds[0];
+
+ for (; addr < maxaddr; addr += page_size) {
+ if ((maxaddr - addr) < page_size)
+ block_size = maxaddr - addr;
+ else
+ block_size = page_size;
+ DEBUG("block_size at addr %d is %d\n",addr,block_size);
+
+ memcpy(buf,commandbuf,sizeof(commandbuf));
+
+ buf[1] = block_size >> 8;
+ buf[2] = block_size & 0xff;
+
+ // Ensure a new "load extended address" will be issued
+ // when crossing a 64 KB boundary in flash.
+ if (hiaddr != (addr & ~0xFFFF)) {
+ hiaddr = addr & ~0xFFFF;
+ if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0)
+ return -1;
+ }
+
+ result = stk500v2_command(pgm,buf,4,sizeof(buf));
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_paged_load: read command failed\n",
+ progname);
+ return -1;
+ }
+#if 0
+ for (i=0;i<page_size;i++) {
+ avrdude_message(MSG_INFO, "%02X",buf[2+i]);
+ if (i%16 == 15) avrdude_message(MSG_INFO, "\n");
+ }
+#endif
+
+ memcpy(&m->buf[addr], &buf[2], block_size);
+ }
+
+ return n_bytes;
+}
+
+
+/*
+ * Read pages of flash/EEPROM, generic HV mode
+ */
+static int stk500hv_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes,
+ enum hvmode mode)
+{
+ unsigned int block_size, hiaddr, addrshift, use_ext_addr;
+ unsigned int maxaddr = addr + n_bytes;
+ unsigned char commandbuf[3], buf[266];
+ int result;
+
+ DEBUG("STK500V2: stk500hv_paged_load(..,%s,%u,%u,%u)\n",
+ m->desc, page_size, addr, n_bytes);
+
+ page_size = m->readsize;
+
+ hiaddr = UINT_MAX;
+ addrshift = 0;
+ use_ext_addr = 0;
+
+ // determine which command is to be used
+ if (strcmp(m->desc, "flash") == 0) {
+ commandbuf[0] = mode == PPMODE? CMD_READ_FLASH_PP: CMD_READ_FLASH_HVSP;
+ addrshift = 1;
+ /*
+ * If bit 31 is set, this indicates that the following read/write
+ * operation will be performed on a memory that is larger than
+ * 64KBytes. This is an indication to STK500 that a load extended
+ * address must be executed.
+ */
+ if (m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) {
+ use_ext_addr = (1U << 31);
+ }
+ }
+ else if (strcmp(m->desc, "eeprom") == 0) {
+ commandbuf[0] = mode == PPMODE? CMD_READ_EEPROM_PP: CMD_READ_EEPROM_HVSP;
+ }
+
+ for (; addr < maxaddr; addr += page_size) {
+ if ((maxaddr - addr) < page_size)
+ block_size = maxaddr - addr;
+ else
+ block_size = page_size;
+ DEBUG("block_size at addr %d is %d\n",addr,block_size);
+
+ memcpy(buf, commandbuf, sizeof(commandbuf));
+
+ buf[1] = block_size >> 8;
+ buf[2] = block_size & 0xff;
+
+ // Ensure a new "load extended address" will be issued
+ // when crossing a 64 KB boundary in flash.
+ if (hiaddr != (addr & ~0xFFFF)) {
+ hiaddr = addr & ~0xFFFF;
+ if (stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift)) < 0)
+ return -1;
+ }
+
+ result = stk500v2_command(pgm, buf, 3, sizeof(buf));
+ if (result < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500hv_paged_load: read command failed\n",
+ progname);
+ return -1;
+ }
+#if 0
+ for (i = 0; i < page_size; i++) {
+ avrdude_message(MSG_INFO, "%02X", buf[2 + i]);
+ if (i % 16 == 15) avrdude_message(MSG_INFO, "\n");
+ }
+#endif
+
+ memcpy(&m->buf[addr], &buf[2], block_size);
+ }
+
+ return n_bytes;
+}
+
+/*
+ * Read pages of flash/EEPROM, PP mode
+ */
+static int stk500pp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ return stk500hv_paged_load(pgm, p, m, page_size, addr, n_bytes, PPMODE);
+}
+
+/*
+ * Read pages of flash/EEPROM, HVSP mode
+ */
+static int stk500hvsp_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ return stk500hv_paged_load(pgm, p, m, page_size, addr, n_bytes, HVSPMODE);
+}
+
+
+static int stk500v2_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int addr)
+{
+ avrdude_message(MSG_INFO, "%s: stk500v2_page_erase(): this function must never be called\n",
+ progname);
+ return -1;
+}
+
+static int stk500v2_set_vtarget(PROGRAMMER * pgm, double v)
+{
+ unsigned char uaref, utarg;
+
+ utarg = (unsigned)((v + 0.049) * 10);
+
+ if (stk500v2_getparm(pgm, PARAM_VADJUST, &uaref) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_vtarget(): cannot obtain V[aref]\n",
+ progname);
+ return -1;
+ }
+
+ if (uaref > utarg) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_vtarget(): reducing V[aref] from %.1f to %.1f\n",
+ progname, uaref / 10.0, v);
+ if (stk500v2_setparm(pgm, PARAM_VADJUST, utarg)
+ != 0)
+ return -1;
+ }
+ return stk500v2_setparm(pgm, PARAM_VTARGET, utarg);
+}
+
+
+static int stk500v2_set_varef(PROGRAMMER * pgm, unsigned int chan /* unused */,
+ double v)
+{
+ unsigned char uaref, utarg;
+
+ uaref = (unsigned)((v + 0.049) * 10);
+
+ if (stk500v2_getparm(pgm, PARAM_VTARGET, &utarg) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_varef(): cannot obtain V[target]\n",
+ progname);
+ return -1;
+ }
+
+ if (uaref > utarg) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_varef(): V[aref] must not be greater than "
+ "V[target] = %.1f\n",
+ progname, utarg / 10.0);
+ return -1;
+ }
+ return stk500v2_setparm(pgm, PARAM_VADJUST, uaref);
+}
+
+
+static int stk500v2_set_fosc(PROGRAMMER * pgm, double v)
+{
+ int fosc;
+ unsigned char prescale, cmatch;
+ static unsigned ps[] = {
+ 1, 8, 32, 64, 128, 256, 1024
+ };
+ int idx, rc;
+
+ prescale = cmatch = 0;
+ if (v > 0.0) {
+ if (v > STK500V2_XTAL / 2) {
+ const char *unit;
+ if (v > 1e6) {
+ v /= 1e6;
+ unit = "MHz";
+ } else if (v > 1e3) {
+ v /= 1e3;
+ unit = "kHz";
+ } else
+ unit = "Hz";
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_fosc(): f = %.3f %s too high, using %.3f MHz\n",
+ progname, v, unit, STK500V2_XTAL / 2e6);
+ fosc = STK500V2_XTAL / 2;
+ } else
+ fosc = (unsigned)v;
+
+ for (idx = 0; idx < sizeof(ps) / sizeof(ps[0]); idx++) {
+ if (fosc >= STK500V2_XTAL / (256 * ps[idx] * 2)) {
+ /* this prescaler value can handle our frequency */
+ prescale = idx + 1;
+ cmatch = (unsigned)(STK500V2_XTAL / (2 * fosc * ps[idx])) - 1;
+ break;
+ }
+ }
+ if (idx == sizeof(ps) / sizeof(ps[0])) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_fosc(): f = %u Hz too low, %u Hz min\n",
+ progname, fosc, STK500V2_XTAL / (256 * 1024 * 2));
+ return -1;
+ }
+ }
+
+ if ((rc = stk500v2_setparm(pgm, PARAM_OSC_PSCALE, prescale)) != 0
+ || (rc = stk500v2_setparm(pgm, PARAM_OSC_CMATCH, cmatch)) != 0)
+ return rc;
+
+ return 0;
+}
+
+/* The list of SCK frequencies supported by the AVRISP mkII, as listed
+ * in AVR069 */
+static double avrispmkIIfreqs[] = {
+ 8000000, 4000000, 2000000, 1000000, 500000, 250000, 125000,
+ 96386, 89888, 84211, 79208, 74767, 70797, 67227, 64000,
+ 61069, 58395, 55945, 51613, 49690, 47905, 46243, 43244,
+ 41885, 39409, 38278, 36200, 34335, 32654, 31129, 29740,
+ 28470, 27304, 25724, 24768, 23461, 22285, 21221, 20254,
+ 19371, 18562, 17583, 16914, 16097, 15356, 14520, 13914,
+ 13224, 12599, 12031, 11511, 10944, 10431, 9963, 9468,
+ 9081, 8612, 8239, 7851, 7498, 7137, 6809, 6478, 6178,
+ 5879, 5607, 5359, 5093, 4870, 4633, 4418, 4209, 4019,
+ 3823, 3645, 3474, 3310, 3161, 3011, 2869, 2734, 2611,
+ 2484, 2369, 2257, 2152, 2052, 1956, 1866, 1779, 1695,
+ 1615, 1539, 1468, 1398, 1333, 1271, 1212, 1155, 1101,
+ 1049, 1000, 953, 909, 866, 826, 787, 750, 715, 682,
+ 650, 619, 590, 563, 536, 511, 487, 465, 443, 422,
+ 402, 384, 366, 349, 332, 317, 302, 288, 274, 261,
+ 249, 238, 226, 216, 206, 196, 187, 178, 170, 162,
+ 154, 147, 140, 134, 128, 122, 116, 111, 105, 100,
+ 95.4, 90.9, 86.6, 82.6, 78.7, 75.0, 71.5, 68.2,
+ 65.0, 61.9, 59.0, 56.3, 53.6, 51.1
+};
+
+static int stk500v2_set_sck_period_mk2(PROGRAMMER * pgm, double v)
+{
+ int i;
+
+ for (i = 0; i < sizeof(avrispmkIIfreqs); i++) {
+ if (1 / avrispmkIIfreqs[i] >= v)
+ break;
+ }
+
+ avrdude_message(MSG_NOTICE2, "Using p = %.2f us for SCK (param = %d)\n",
+ 1000000 / avrispmkIIfreqs[i], i);
+
+ return stk500v2_setparm(pgm, PARAM_SCK_DURATION, i);
+}
+
+/*
+ * Return the "mode" value for the parallel and HVSP modes that
+ * corresponds to the pagesize.
+ */
+static unsigned int stk500v2_mode_for_pagesize(unsigned int pagesize)
+{
+ switch (pagesize)
+ {
+ case 256: return 0u << 1;
+ case 2: return 1u << 1;
+ case 4: return 2u << 1;
+ case 8: return 3u << 1;
+ case 16: return 4u << 1;
+ case 32: return 5u << 1;
+ case 64: return 6u << 1;
+ case 128: return 7u << 1;
+ }
+ avrdude_message(MSG_INFO, "%s: stk500v2_mode_for_pagesize(): invalid pagesize: %u\n",
+ progname, pagesize);
+ return 0;
+}
+
+/*
+ * See pseudo-code in AVR068
+ *
+ * This algorithm only fits for the STK500 itself. For the (old)
+ * AVRISP, the resulting ISP clock is only half. While this would be
+ * easy to fix in the algorithm, we'd need to add another
+ * configuration flag for this to the config file. Given the old
+ * AVRISP devices are virtually no longer around (and the AVRISPmkII
+ * uses a different algorithm below), it's probably not worth the
+ * hassle.
+ */
+static int stk500v2_set_sck_period(PROGRAMMER * pgm, double v)
+{
+ unsigned int d;
+ unsigned char dur;
+ double f = 1 / v;
+
+ if (f >= 1.8432E6)
+ d = 0;
+ else if (f > 460.8E3)
+ d = 1;
+ else if (f > 115.2E3)
+ d = 2;
+ else if (f > 57.6E3)
+ d = 3;
+ else
+ d = (unsigned int)ceil(1 / (24 * f / (double)STK500V2_XTAL) - 10.0 / 12.0);
+ if (d >= 255)
+ d = 254;
+ dur = d;
+
+ return stk500v2_setparm(pgm, PARAM_SCK_DURATION, dur);
+}
+
+static double stk500v2_sck_to_us(PROGRAMMER * pgm, unsigned char dur)
+{
+ double x;
+
+ if (dur == 0)
+ return 0.5425;
+ if (dur == 1)
+ return 2.17;
+ if (dur == 2)
+ return 8.68;
+ if (dur == 3)
+ return 17.36;
+
+ x = (double)dur + 10.0 / 12.0;
+ x = 1.0 / x;
+ x /= 24.0;
+ x *= (double)STK500V2_XTAL;
+ return 1E6 / x;
+}
+
+
+static int stk600_set_vtarget(PROGRAMMER * pgm, double v)
+{
+ unsigned char utarg;
+ unsigned int uaref;
+ int rv;
+
+ utarg = (unsigned)((v + 0.049) * 10);
+
+ if (stk500v2_getparm2(pgm, PARAM2_AREF0, &uaref) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_vtarget(): cannot obtain V[aref][0]\n",
+ progname);
+ return -1;
+ }
+
+ if (uaref > (unsigned)utarg * 10) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_vtarget(): reducing V[aref][0] from %.2f to %.1f\n",
+ progname, uaref / 100.0, v);
+ uaref = 10 * (unsigned)utarg;
+ if (stk500v2_setparm2(pgm, PARAM2_AREF0, uaref)
+ != 0)
+ return -1;
+ }
+
+ if (stk500v2_getparm2(pgm, PARAM2_AREF1, &uaref) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_vtarget(): cannot obtain V[aref][1]\n",
+ progname);
+ return -1;
+ }
+
+ if (uaref > (unsigned)utarg * 10) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_vtarget(): reducing V[aref][1] from %.2f to %.1f\n",
+ progname, uaref / 100.0, v);
+ uaref = 10 * (unsigned)utarg;
+ if (stk500v2_setparm2(pgm, PARAM2_AREF1, uaref)
+ != 0)
+ return -1;
+ }
+
+ /*
+ * Vtarget on the STK600 can only be adjusted while not being in
+ * programming mode.
+ */
+ if (PDATA(pgm)->lastpart)
+ pgm->disable(pgm);
+ rv = stk500v2_setparm(pgm, PARAM_VTARGET, utarg);
+ if (PDATA(pgm)->lastpart)
+ pgm->program_enable(pgm, PDATA(pgm)->lastpart);
+
+ return rv;
+}
+
+
+static int stk600_set_varef(PROGRAMMER * pgm, unsigned int chan, double v)
+{
+ unsigned char utarg;
+ unsigned int uaref;
+
+ uaref = (unsigned)((v + 0.0049) * 100);
+
+ if (stk500v2_getparm(pgm, PARAM_VTARGET, &utarg) != 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_varef(): cannot obtain V[target]\n",
+ progname);
+ return -1;
+ }
+
+ if (uaref > (unsigned)utarg * 10) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_varef(): V[aref] must not be greater than "
+ "V[target] = %.1f\n",
+ progname, utarg / 10.0);
+ return -1;
+ }
+
+ switch (chan)
+ {
+ case 0:
+ return stk500v2_setparm2(pgm, PARAM2_AREF0, uaref);
+
+ case 1:
+ return stk500v2_setparm2(pgm, PARAM2_AREF1, uaref);
+
+ default:
+ avrdude_message(MSG_INFO, "%s: stk500v2_set_varef(): invalid channel %d\n",
+ progname, chan);
+ return -1;
+ }
+}
+
+
+static int stk600_set_fosc(PROGRAMMER * pgm, double v)
+{
+ unsigned int oct, dac;
+
+ oct = 1.443 * log(v / 1039.0);
+ dac = 2048 - (2078.0 * pow(2, (double)(10 + oct))) / v;
+
+ return stk500v2_setparm2(pgm, PARAM2_CLOCK_CONF, (oct << 12) | (dac << 2));
+}
+
+static int stk600_set_sck_period(PROGRAMMER * pgm, double v)
+{
+ unsigned int sck;
+
+ sck = ceil((16e6 / (2 * 1.0 / v)) - 1);
+
+ if (sck >= 4096)
+ sck = 4095;
+
+ return stk500v2_setparm2(pgm, PARAM2_SCK_DURATION, sck);
+}
+
+static int stk500v2_jtag3_set_sck_period(PROGRAMMER * pgm, double v)
+{
+ unsigned char value[3];
+ unsigned int sck;
+
+ if (v < 1E-6)
+ sck = 0x400;
+ else if (v > 1E-3)
+ sck = 1;
+ else
+ sck = 1.0 / (1000.0 * v);
+
+ value[0] = CMD_SET_SCK;
+ value[1] = sck & 0xff;
+ value[2] = (sck >> 8) & 0xff;
+
+ if (stk500v2_jtag3_send(pgm, value, 3) < 0)
+ return -1;
+ if (stk500v2_jtag3_recv(pgm, value, 3) < 0)
+ return -1;
+ return 0;
+}
+
+static int stk500v2_getparm(PROGRAMMER * pgm, unsigned char parm, unsigned char * value)
+{
+ unsigned char buf[32];
+
+ buf[0] = CMD_GET_PARAMETER;
+ buf[1] = parm;
+
+ if (stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_getparm(): failed to get parameter 0x%02x\n",
+ progname, parm);
+ return -1;
+ }
+
+ *value = buf[2];
+
+ return 0;
+}
+
+static int stk500v2_setparm_real(PROGRAMMER * pgm, unsigned char parm, unsigned char value)
+{
+ unsigned char buf[32];
+
+ buf[0] = CMD_SET_PARAMETER;
+ buf[1] = parm;
+ buf[2] = value;
+
+ if (stk500v2_command(pgm, buf, 3, sizeof(buf)) < 0) {
+ avrdude_message(MSG_INFO, "\n%s: stk500v2_setparm(): failed to set parameter 0x%02x\n",
+ progname, parm);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int stk500v2_setparm(PROGRAMMER * pgm, unsigned char parm, unsigned char value)
+{
+ unsigned char current_value;
+ int res;
+
+ res = stk500v2_getparm(pgm, parm, &current_value);
+ if (res < 0)
+ avrdude_message(MSG_INFO, "%s: Unable to get parameter 0x%02x\n", progname, parm);
+
+ // don't issue a write if the correct value is already set.
+ if (value == current_value) {
+ avrdude_message(MSG_NOTICE2, "%s: Skipping parameter write; parameter value already set.\n", progname);
+ return 0;
+ }
+
+ return stk500v2_setparm_real(pgm, parm, value);
+}
+
+static int stk500v2_getparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int * value)
+{
+ unsigned char buf[32];
+
+ buf[0] = CMD_GET_PARAMETER;
+ buf[1] = parm;
+
+ if (stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_getparm2(): failed to get parameter 0x%02x\n",
+ progname, parm);
+ return -1;
+ }
+
+ *value = ((unsigned)buf[2] << 8) | buf[3];
+
+ return 0;
+}
+
+static int stk500v2_setparm2(PROGRAMMER * pgm, unsigned char parm, unsigned int value)
+{
+ unsigned char buf[32];
+
+ buf[0] = CMD_SET_PARAMETER;
+ buf[1] = parm;
+ buf[2] = value >> 8;
+ buf[3] = value;
+
+ if (stk500v2_command(pgm, buf, 4, sizeof(buf)) < 0) {
+ avrdude_message(MSG_INFO, "\n%s: stk500v2_setparm2(): failed to set parameter 0x%02x\n",
+ progname, parm);
+ return -1;
+ }
+
+ return 0;
+}
+
+static const char *stk600_get_cardname(const struct carddata *table,
+ size_t nele, int id)
+{
+ const struct carddata *cdp;
+
+ if (id == 0xFF)
+ /* 0xFF means this card is not present at all. */
+ return "Not present";
+
+ for (cdp = table; nele > 0; cdp++, nele--)
+ if (cdp->id == id)
+ return cdp->name;
+
+ return "Unknown";
+}
+
+
+static void stk500v2_display(PROGRAMMER * pgm, const char * p)
+{
+ unsigned char maj, min, hdw, topcard, maj_s1, min_s1, maj_s2, min_s2;
+ unsigned int rev;
+ const char *topcard_name, *pgmname;
+
+ switch (PDATA(pgm)->pgmtype) {
+ case PGMTYPE_UNKNOWN: pgmname = "Unknown"; break;
+ case PGMTYPE_STK500: pgmname = "STK500"; break;
+ case PGMTYPE_AVRISP: pgmname = "AVRISP"; break;
+ case PGMTYPE_AVRISP_MKII: pgmname = "AVRISP mkII"; break;
+ case PGMTYPE_STK600: pgmname = "STK600"; break;
+ default: pgmname = "None";
+ }
+ if (PDATA(pgm)->pgmtype != PGMTYPE_JTAGICE_MKII &&
+ PDATA(pgm)->pgmtype != PGMTYPE_JTAGICE3) {
+ avrdude_message(MSG_INFO, "%sProgrammer Model: %s\n", p, pgmname);
+ stk500v2_getparm(pgm, PARAM_HW_VER, &hdw);
+ stk500v2_getparm(pgm, PARAM_SW_MAJOR, &maj);
+ stk500v2_getparm(pgm, PARAM_SW_MINOR, &min);
+ avrdude_message(MSG_INFO, "%sHardware Version: %d\n", p, hdw);
+ avrdude_message(MSG_INFO, "%sFirmware Version Master : %d.%02d\n", p, maj, min);
+ if (PDATA(pgm)->pgmtype == PGMTYPE_STK600) {
+ stk500v2_getparm(pgm, PARAM_SW_MAJOR_SLAVE1, &maj_s1);
+ stk500v2_getparm(pgm, PARAM_SW_MINOR_SLAVE1, &min_s1);
+ stk500v2_getparm(pgm, PARAM_SW_MAJOR_SLAVE2, &maj_s2);
+ stk500v2_getparm(pgm, PARAM_SW_MINOR_SLAVE2, &min_s2);
+ avrdude_message(MSG_INFO, "%sFirmware Version Slave 1: %d.%02d\n", p, maj_s1, min_s1);
+ avrdude_message(MSG_INFO, "%sFirmware Version Slave 2: %d.%02d\n", p, maj_s2, min_s2);
+ }
+ }
+
+ if (PDATA(pgm)->pgmtype == PGMTYPE_STK500) {
+ stk500v2_getparm(pgm, PARAM_TOPCARD_DETECT, &topcard);
+ switch (topcard) {
+ case 0xAA: topcard_name = "STK501"; break;
+ case 0x55: topcard_name = "STK502"; break;
+ case 0xFA: topcard_name = "STK503"; break;
+ case 0xEE: topcard_name = "STK504"; break;
+ case 0xE4: topcard_name = "STK505"; break;
+ case 0xDD: topcard_name = "STK520"; break;
+ default: topcard_name = "Unknown"; break;
+ }
+ avrdude_message(MSG_INFO, "%sTopcard : %s\n", p, topcard_name);
+ } else if (PDATA(pgm)->pgmtype == PGMTYPE_STK600) {
+ stk500v2_getparm(pgm, PARAM_ROUTINGCARD_ID, &topcard);
+ avrdude_message(MSG_INFO, "%sRouting card : %s\n", p,
+ stk600_get_cardname(routing_cards,
+ sizeof routing_cards / sizeof routing_cards[0],
+ topcard));
+ stk500v2_getparm(pgm, PARAM_SOCKETCARD_ID, &topcard);
+ avrdude_message(MSG_INFO, "%sSocket card : %s\n", p,
+ stk600_get_cardname(socket_cards,
+ sizeof socket_cards / sizeof socket_cards[0],
+ topcard));
+ stk500v2_getparm2(pgm, PARAM2_RC_ID_TABLE_REV, &rev);
+ avrdude_message(MSG_INFO, "%sRC_ID table rev : %d\n", p, rev);
+ stk500v2_getparm2(pgm, PARAM2_EC_ID_TABLE_REV, &rev);
+ avrdude_message(MSG_INFO, "%sEC_ID table rev : %d\n", p, rev);
+ }
+ stk500v2_print_parms1(pgm, p);
+
+ return;
+}
+
+static double
+f_to_kHz_MHz(double f, const char **unit)
+{
+ if (f > 1e6) {
+ f /= 1e6;
+ *unit = "MHz";
+ } else if (f > 1e3) {
+ f /= 1000;
+ *unit = "kHz";
+ } else
+ *unit = "Hz";
+
+ return f;
+}
+
+static void stk500v2_print_parms1(PROGRAMMER * pgm, const char * p)
+{
+ unsigned char vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration =0; //XXX 0 is not correct, check caller
+ unsigned int sck_stk600, clock_conf, dac, oct, varef;
+ unsigned char vtarget_jtag[4];
+ int prescale;
+ double f;
+ const char *unit;
+ void *mycookie;
+
+ if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE_MKII) {
+ return;
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+ // jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget_jtag);
+ // pgm->cookie = mycookie;
+ // avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p,
+ // b2_to_u16(vtarget_jtag) / 1000.0);
+ } else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3) {
+ return;
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+ // jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, vtarget_jtag, 2);
+ // pgm->cookie = mycookie;
+ // avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p,
+ // b2_to_u16(vtarget_jtag) / 1000.0);
+
+ } else {
+ stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget);
+ avrdude_message(MSG_INFO, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
+ }
+
+ switch (PDATA(pgm)->pgmtype) {
+ case PGMTYPE_STK500:
+ stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration);
+ stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust);
+ stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale);
+ stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch);
+ avrdude_message(MSG_INFO, "%sSCK period : %.1f us\n", p,
+ stk500v2_sck_to_us(pgm, sck_duration));
+ avrdude_message(MSG_INFO, "%sVaref : %.1f V\n", p, vadjust / 10.0);
+ avrdude_message(MSG_INFO, "%sOscillator : ", p);
+ if (osc_pscale == 0)
+ avrdude_message(MSG_INFO, "Off\n");
+ else {
+ prescale = 1;
+ f = STK500V2_XTAL / 2;
+
+ switch (osc_pscale) {
+ case 2: prescale = 8; break;
+ case 3: prescale = 32; break;
+ case 4: prescale = 64; break;
+ case 5: prescale = 128; break;
+ case 6: prescale = 256; break;
+ case 7: prescale = 1024; break;
+ }
+ f /= prescale;
+ f /= (osc_cmatch + 1);
+ f = f_to_kHz_MHz(f, &unit);
+ avrdude_message(MSG_INFO, "%.3f %s\n", f, unit);
+ }
+ break;
+
+ case PGMTYPE_AVRISP_MKII:
+ case PGMTYPE_JTAGICE_MKII:
+ stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration);
+ avrdude_message(MSG_INFO, "%sSCK period : %.2f us\n", p,
+ (float) 1000000 / avrispmkIIfreqs[sck_duration]);
+ break;
+
+ case PGMTYPE_JTAGICE3:
+ {
+ unsigned char cmd[4];
+
+ cmd[0] = CMD_GET_SCK;
+ if (stk500v2_jtag3_send(pgm, cmd, 1) >= 0 &&
+ stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) {
+ unsigned int sck = cmd[1] | (cmd[2] << 8);
+ avrdude_message(MSG_INFO, "%sSCK period : %.2f us\n", p,
+ (float)(1E6 / (1000.0 * sck)));
+ }
+ }
+ break;
+
+ case PGMTYPE_STK600:
+ stk500v2_getparm2(pgm, PARAM2_AREF0, &varef);
+ avrdude_message(MSG_INFO, "%sVaref 0 : %.2f V\n", p, varef / 100.0);
+ stk500v2_getparm2(pgm, PARAM2_AREF1, &varef);
+ avrdude_message(MSG_INFO, "%sVaref 1 : %.2f V\n", p, varef / 100.0);
+ stk500v2_getparm2(pgm, PARAM2_SCK_DURATION, &sck_stk600);
+ avrdude_message(MSG_INFO, "%sSCK period : %.2f us\n", p,
+ (float) (sck_stk600 + 1) / 8.0);
+ stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf);
+ oct = (clock_conf & 0xf000) >> 12u;
+ dac = (clock_conf & 0x0ffc) >> 2u;
+ f = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0);
+ f = f_to_kHz_MHz(f, &unit);
+ avrdude_message(MSG_INFO, "%sOscillator : %.3f %s\n",
+ p, f, unit);
+ break;
+
+ default:
+ avrdude_message(MSG_INFO, "%sSCK period : %.1f us\n", p,
+ sck_duration * 8.0e6 / STK500V2_XTAL + 0.05);
+ break;
+ }
+
+ return;
+}
+
+
+static void stk500v2_print_parms(PROGRAMMER * pgm)
+{
+ stk500v2_print_parms1(pgm, "");
+}
+
+static int stk500v2_perform_osccal(PROGRAMMER * pgm)
+{
+ unsigned char buf[32];
+ int rv;
+
+ buf[0] = CMD_OSCCAL;
+
+ rv = stk500v2_command(pgm, buf, 1, sizeof(buf));
+ if (rv < 0) {
+ avrdude_message(MSG_INFO, "%s: stk500v2_perform_osccal(): failed\n",
+ progname);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Wrapper functions for the JTAG ICE mkII in ISP mode. This mode
+ * uses the normal JTAG ICE mkII packet stream to communicate with the
+ * ICE, but then encapsulates AVRISP mkII commands using
+ * CMND_ISP_PACKET.
+ */
+
+/*
+ * Open a JTAG ICE mkII in ISP mode.
+ */
+static int stk500v2_jtagmkII_open(PROGRAMMER * pgm, char * port)
+{
+ return -1;
+// union pinfo pinfo;
+// void *mycookie;
+// int rv;
+
+// avrdude_message(MSG_NOTICE2, "%s: stk500v2_jtagmkII_open()\n", progname);
+
+// /*
+// * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+// * attaching. If the config file or command-line parameters specify
+// * a higher baud rate, we switch to it later on, after establishing
+// * the connection with the ICE.
+// */
+// pinfo.baud = 19200;
+
+// /*
+// * If the port name starts with "usb", divert the serial routines
+// * to the USB ones. The serial_open() function for USB overrides
+// * the meaning of the "baud" parameter to be the USB device ID to
+// * search for.
+// */
+// if (strncmp(port, "usb", 3) == 0) {
+// #if defined(HAVE_LIBUSB)
+// serdev = &usb_serdev;
+// pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+// pinfo.usbinfo.flags = 0;
+// pinfo.usbinfo.pid = USB_DEVICE_JTAGICEMKII;
+// pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+// pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
+// pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
+// pgm->fd.usb.eep = 0; /* no seperate EP for events */
+// #else
+// avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+// return -1;
+// #endif
+// }
+
+// strcpy(pgm->port, port);
+// if (serial_open(port, pinfo, &pgm->fd)==-1) {
+// return -1;
+// }
+
+// /*
+// * drain any extraneous input
+// */
+// stk500v2_drain(pgm, 0);
+
+// mycookie = pgm->cookie;
+// pgm->cookie = PDATA(pgm)->chained_pdata;
+// if ((rv = jtagmkII_getsync(pgm, EMULATOR_MODE_SPI)) != 0) {
+// if (rv != JTAGII_GETSYNC_FAIL_GRACEFUL)
+// avrdude_message(MSG_INFO, "%s: failed to sync with the JTAG ICE mkII in ISP mode\n",
+// progname);
+// pgm->cookie = mycookie;
+// return -1;
+// }
+// pgm->cookie = mycookie;
+
+// PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII;
+
+// if (pgm->bitclock != 0.0) {
+// if (pgm->set_sck_period(pgm, pgm->bitclock) != 0)
+// return -1;
+// }
+
+// return 0;
+}
+
+
+/*
+ * Close an AVR Dragon or JTAG ICE mkII in ISP/HVSP/PP mode.
+ */
+static void stk500v2_jtagmkII_close(PROGRAMMER * pgm)
+{
+ // void *mycookie;
+
+ // avrdude_message(MSG_NOTICE2, "%s: stk500v2_jtagmkII_close()\n", progname);
+
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+ // jtagmkII_close(pgm);
+ // pgm->cookie = mycookie;
+}
+
+
+/*
+ * Close JTAGICE3.
+ */
+static void stk500v2_jtag3_close(PROGRAMMER * pgm)
+{
+ // void *mycookie;
+
+ // avrdude_message(MSG_NOTICE2, "%s: stk500v2_jtag3_close()\n", progname);
+
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+ // jtag3_close(pgm);
+ // pgm->cookie = mycookie;
+}
+
+
+/*
+ * Wrapper functions for the AVR Dragon in ISP mode. This mode
+ * uses the normal JTAG ICE mkII packet stream to communicate with the
+ * ICE, but then encapsulates AVRISP mkII commands using
+ * CMND_ISP_PACKET.
+ */
+
+/*
+ * Open an AVR Dragon in ISP mode.
+ */
+static int stk500v2_dragon_isp_open(PROGRAMMER * pgm, char * port)
+{
+ return -1;
+// union pinfo pinfo;
+// void *mycookie;
+
+// avrdude_message(MSG_NOTICE2, "%s: stk500v2_dragon_isp_open()\n", progname);
+
+// /*
+// * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+// * attaching. If the config file or command-line parameters specify
+// * a higher baud rate, we switch to it later on, after establishing
+// * the connection with the ICE.
+// */
+// pinfo.baud = 19200;
+
+// /*
+// * If the port name starts with "usb", divert the serial routines
+// * to the USB ones. The serial_open() function for USB overrides
+// * the meaning of the "baud" parameter to be the USB device ID to
+// * search for.
+// */
+// if (strncmp(port, "usb", 3) == 0) {
+// #if defined(HAVE_LIBUSB)
+// serdev = &usb_serdev;
+// pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+// pinfo.usbinfo.flags = 0;
+// pinfo.usbinfo.pid = USB_DEVICE_AVRDRAGON;
+// pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+// pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
+// pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
+// pgm->fd.usb.eep = 0; /* no seperate EP for events */
+// #else
+// avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+// return -1;
+// #endif
+// }
+
+// strcpy(pgm->port, port);
+// if (serial_open(port, pinfo, &pgm->fd)==-1) {
+// return -1;
+// }
+
+// /*
+// * drain any extraneous input
+// */
+// stk500v2_drain(pgm, 0);
+
+// mycookie = pgm->cookie;
+// pgm->cookie = PDATA(pgm)->chained_pdata;
+// if (jtagmkII_getsync(pgm, EMULATOR_MODE_SPI) != 0) {
+// avrdude_message(MSG_INFO, "%s: failed to sync with the AVR Dragon in ISP mode\n",
+// progname);
+// pgm->cookie = mycookie;
+// return -1;
+// }
+// pgm->cookie = mycookie;
+
+// PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII;
+
+// if (pgm->bitclock != 0.0) {
+// if (pgm->set_sck_period(pgm, pgm->bitclock) != 0)
+// return -1;
+// }
+
+// return 0;
+}
+
+
+/*
+ * Wrapper functions for the AVR Dragon in HV mode. This mode
+ * uses the normal JTAG ICE mkII packet stream to communicate with the
+ * ICE, but then encapsulates AVRISP mkII commands using
+ * CMND_ISP_PACKET.
+ */
+
+/*
+ * Open an AVR Dragon in HV mode (HVSP or parallel).
+ */
+static int stk500v2_dragon_hv_open(PROGRAMMER * pgm, char * port)
+{
+ return -1;
+// union pinfo pinfo;
+// void *mycookie;
+
+// avrdude_message(MSG_NOTICE2, "%s: stk500v2_dragon_hv_open()\n", progname);
+
+// /*
+// * The JTAG ICE mkII always starts with a baud rate of 19200 Bd upon
+// * attaching. If the config file or command-line parameters specify
+// * a higher baud rate, we switch to it later on, after establishing
+// * the connection with the ICE.
+// */
+// pinfo.baud = 19200;
+
+// /*
+// * If the port name starts with "usb", divert the serial routines
+// * to the USB ones. The serial_open() function for USB overrides
+// * the meaning of the "baud" parameter to be the USB device ID to
+// * search for.
+// */
+// if (strncmp(port, "usb", 3) == 0) {
+// #if defined(HAVE_LIBUSB)
+// serdev = &usb_serdev;
+// pinfo.usbinfo.vid = USB_VENDOR_ATMEL;
+// pinfo.usbinfo.flags = 0;
+// pinfo.usbinfo.pid = USB_DEVICE_AVRDRAGON;
+// pgm->fd.usb.max_xfer = USBDEV_MAX_XFER_MKII;
+// pgm->fd.usb.rep = USBDEV_BULK_EP_READ_MKII;
+// pgm->fd.usb.wep = USBDEV_BULK_EP_WRITE_MKII;
+// pgm->fd.usb.eep = 0; /* no seperate EP for events */
+// #else
+// avrdude_message(MSG_INFO, "avrdude was compiled without usb support.\n");
+// return -1;
+// #endif
+// }
+
+// strcpy(pgm->port, port);
+// if (serial_open(port, pinfo, &pgm->fd)==-1) {
+// return -1;
+// }
+
+// /*
+// * drain any extraneous input
+// */
+// stk500v2_drain(pgm, 0);
+
+// mycookie = pgm->cookie;
+// pgm->cookie = PDATA(pgm)->chained_pdata;
+// if (jtagmkII_getsync(pgm, EMULATOR_MODE_HV) != 0) {
+// avrdude_message(MSG_INFO, "%s: failed to sync with the AVR Dragon in HV mode\n",
+// progname);
+// pgm->cookie = mycookie;
+// return -1;
+// }
+// pgm->cookie = mycookie;
+
+// PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE_MKII;
+
+// if (pgm->bitclock != 0.0) {
+// if (pgm->set_sck_period(pgm, pgm->bitclock) != 0)
+// return -1;
+// }
+
+// return 0;
+}
+
+/*
+ * Wrapper functions for the JTAGICE3 in ISP mode. This mode
+ * uses the normal JTAGICE3 packet stream to communicate with the
+ * ICE, but then encapsulates AVRISP mkII commands using
+ * scope AVRISP.
+ */
+
+/*
+ * Open a JTAGICE3 in ISP mode.
+ */
+static int stk500v2_jtag3_open(PROGRAMMER * pgm, char * port)
+{
+ return -1;
+ // void *mycookie;
+ // int rv;
+
+ // avrdude_message(MSG_NOTICE2, "%s: stk500v2_jtag3_open()\n", progname);
+
+ // if (jtag3_open_common(pgm, port) < 0)
+ // return -1;
+
+ // mycookie = pgm->cookie;
+ // pgm->cookie = PDATA(pgm)->chained_pdata;
+ // if ((rv = jtag3_getsync(pgm, 42)) != 0) {
+ // if (rv != JTAGII_GETSYNC_FAIL_GRACEFUL)
+ // avrdude_message(MSG_INFO, "%s: failed to sync with the JTAGICE3 in ISP mode\n",
+ // progname);
+ // pgm->cookie = mycookie;
+ // return -1;
+ // }
+ // pgm->cookie = mycookie;
+
+ // PDATA(pgm)->pgmtype = PGMTYPE_JTAGICE3;
+
+ // if (pgm->bitclock != 0.0) {
+ // if (pgm->set_sck_period(pgm, pgm->bitclock) != 0)
+ // return -1;
+ // }
+
+ // return 0;
+}
+
+
+/*
+ * XPROG wrapper
+ */
+static int stk600_xprog_command(PROGRAMMER * pgm, unsigned char *b,
+ unsigned int cmdsize, unsigned int responsesize)
+{
+ unsigned char *newb;
+ unsigned int s;
+ int rv;
+
+ if (cmdsize < responsesize)
+ s = responsesize;
+ else
+ s = cmdsize;
+
+ if ((newb = malloc(s + 1)) == 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_cmd(): out of memory\n",
+ progname);
+ return -1;
+ }
+
+ newb[0] = CMD_XPROG;
+ memcpy(newb + 1, b, cmdsize);
+ rv = stk500v2_command(pgm, newb, cmdsize + 1, responsesize + 1);
+ if (rv == 0) {
+ memcpy(b, newb + 1, responsesize);
+ }
+
+ free(newb);
+
+ return rv;
+}
+
+
+/*
+ * issue the 'program enable' command to the AVR device, XPROG version
+ */
+static int stk600_xprog_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char buf[16];
+ unsigned int eepagesize = 42;
+ unsigned int nvm_base;
+ AVRMEM *mem = NULL;
+ int use_tpi;
+
+ use_tpi = (p->flags & AVRPART_HAS_TPI) != 0;
+
+ if (!use_tpi) {
+ if (p->nvm_base == 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_program_enable(): no nvm_base parameter for PDI device\n",
+ progname);
+ return -1;
+ }
+ if ((mem = avr_locate_mem(p, "eeprom")) != NULL) {
+ if (mem->page_size == 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_program_enable(): no EEPROM page_size parameter for PDI device\n",
+ progname);
+ return -1;
+ }
+ eepagesize = mem->page_size;
+ }
+ }
+
+ buf[0] = CMD_XPROG_SETMODE;
+ buf[1] = use_tpi? XPRG_MODE_TPI: XPRG_MODE_PDI;
+ if (stk500v2_command(pgm, buf, 2, sizeof(buf)) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_program_enable(): CMD_XPROG_SETMODE(XPRG_MODE_%s) failed\n",
+ progname, use_tpi? "TPI": "PDI");
+ return -1;
+ }
+
+ buf[0] = XPRG_CMD_ENTER_PROGMODE;
+ if (stk600_xprog_command(pgm, buf, 1, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_program_enable(): XPRG_CMD_ENTER_PROGMODE failed\n",
+ progname);
+ return -1;
+ }
+
+ if (use_tpi) {
+ /*
+ * Whatever all that might mean, it matches what AVR Studio
+ * does.
+ */
+ if (stk500v2_setparm_real(pgm, PARAM_DISCHARGEDELAY, 232) < 0)
+ return -1;
+
+ buf[0] = XPRG_CMD_SET_PARAM;
+ buf[1] = XPRG_PARAM_TPI_3;
+ buf[2] = 51;
+ if (stk600_xprog_command(pgm, buf, 3, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_program_enable(): XPRG_CMD_SET_PARAM(XPRG_PARAM_TPI_3) failed\n",
+ progname);
+ return -1;
+ }
+
+ buf[0] = XPRG_CMD_SET_PARAM;
+ buf[1] = XPRG_PARAM_TPI_4;
+ buf[2] = 50;
+ if (stk600_xprog_command(pgm, buf, 3, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_program_enable(): XPRG_CMD_SET_PARAM(XPRG_PARAM_TPI_4) failed\n",
+ progname);
+ return -1;
+ }
+ } else {
+ buf[0] = XPRG_CMD_SET_PARAM;
+ buf[1] = XPRG_PARAM_NVMBASE;
+ nvm_base = p->nvm_base;
+ /*
+ * The 0x01000000 appears to be an indication to the programmer
+ * that the respective address is located in IO (i.e., SRAM)
+ * memory address space rather than flash. This is not documented
+ * anywhere in AVR079 but matches what AVR Studio does.
+ */
+ nvm_base |= 0x01000000;
+ buf[2] = nvm_base >> 24;
+ buf[3] = nvm_base >> 16;
+ buf[4] = nvm_base >> 8;
+ buf[5] = nvm_base;
+ if (stk600_xprog_command(pgm, buf, 6, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_program_enable(): XPRG_CMD_SET_PARAM(XPRG_PARAM_NVMBASE) failed\n",
+ progname);
+ return -1;
+ }
+
+ if (mem != NULL) {
+ buf[0] = XPRG_CMD_SET_PARAM;
+ buf[1] = XPRG_PARAM_EEPPAGESIZE;
+ buf[2] = eepagesize >> 8;
+ buf[3] = eepagesize;
+ if (stk600_xprog_command(pgm, buf, 4, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_program_enable(): XPRG_CMD_SET_PARAM(XPRG_PARAM_EEPPAGESIZE) failed\n",
+ progname);
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static unsigned char stk600_xprog_memtype(PROGRAMMER * pgm, unsigned long addr)
+{
+ if (addr >= PDATA(pgm)->boot_start)
+ return XPRG_MEM_TYPE_BOOT;
+ else
+ return XPRG_MEM_TYPE_APPL;
+}
+
+
+static void stk600_xprog_disable(PROGRAMMER * pgm)
+{
+ unsigned char buf[2];
+
+ buf[0] = XPRG_CMD_LEAVE_PROGMODE;
+ if (stk600_xprog_command(pgm, buf, 1, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_program_disable(): XPRG_CMD_LEAVE_PROGMODE failed\n",
+ progname);
+ }
+}
+
+static int stk600_xprog_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char data)
+{
+ unsigned char b[9 + 256];
+ int need_erase = 0;
+ unsigned char write_size = 1;
+ unsigned char memcode;
+
+ memset(b, 0, sizeof(b));
+
+ if (strcmp(mem->desc, "flash") == 0) {
+ memcode = stk600_xprog_memtype(pgm, addr);
+ } else if (strcmp(mem->desc, "application") == 0 ||
+ strcmp(mem->desc, "apptable") == 0) {
+ memcode = XPRG_MEM_TYPE_APPL;
+ } else if (strcmp(mem->desc, "boot") == 0) {
+ memcode = XPRG_MEM_TYPE_BOOT;
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ memcode = XPRG_MEM_TYPE_EEPROM;
+ } else if (strncmp(mem->desc, "lock", strlen("lock")) == 0) {
+ memcode = XPRG_MEM_TYPE_LOCKBITS;
+ } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
+ memcode = XPRG_MEM_TYPE_FUSE;
+ if (p->flags & AVRPART_HAS_TPI)
+ /*
+ * TPI devices need a mystic erase prior to writing their
+ * fuses.
+ */
+ need_erase = 1;
+ } else if (strcmp(mem->desc, "usersig") == 0) {
+ memcode = XPRG_MEM_TYPE_USERSIG;
+ } else {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_write_byte(): unknown memory \"%s\"\n",
+ progname, mem->desc);
+ return -1;
+ }
+ addr += mem->offset;
+
+ if (need_erase) {
+ b[0] = XPRG_CMD_ERASE;
+ b[1] = XPRG_ERASE_CONFIG;
+ b[2] = mem->offset >> 24;
+ b[3] = mem->offset >> 16;
+ b[4] = mem->offset >> 8;
+ b[5] = mem->offset + 1;
+ if (stk600_xprog_command(pgm, b, 6, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_chip_erase(): XPRG_CMD_ERASE(XPRG_ERASE_CONFIG) failed\n",
+ progname);
+ return -1;
+ }
+ }
+
+ if (p->flags & AVRPART_HAS_TPI) {
+ /*
+ * Some TPI memories (configuration aka. fuse) require a
+ * larger write block size. We record that as a blocksize in
+ * avrdude.conf.
+ */
+ if (mem->blocksize != 0)
+ write_size = mem->blocksize;
+ }
+
+ b[0] = XPRG_CMD_WRITE_MEM;
+ b[1] = memcode;
+ b[2] = 0; /* pagemode: non-paged write */
+ b[3] = addr >> 24;
+ b[4] = addr >> 16;
+ b[5] = addr >> 8;
+ b[6] = addr;
+ b[7] = 0;
+ b[8] = write_size;
+ b[9] = data;
+ if (stk600_xprog_command(pgm, b, 9 + write_size, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_write_byte(): XPRG_CMD_WRITE_MEM failed\n",
+ progname);
+ return -1;
+ }
+ return 0;
+}
+
+
+static int stk600_xprog_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned long addr, unsigned char * value)
+{
+ unsigned char b[8];
+
+ if (strcmp(mem->desc, "flash") == 0) {
+ b[1] = stk600_xprog_memtype(pgm, addr);
+ } else if (strcmp(mem->desc, "application") == 0 ||
+ strcmp(mem->desc, "apptable") == 0) {
+ b[1] = XPRG_MEM_TYPE_APPL;
+ } else if (strcmp(mem->desc, "boot") == 0) {
+ b[1] = XPRG_MEM_TYPE_BOOT;
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ b[1] = XPRG_MEM_TYPE_EEPROM;
+ } else if (strcmp(mem->desc, "signature") == 0) {
+ b[1] = XPRG_MEM_TYPE_APPL;
+ } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
+ b[1] = XPRG_MEM_TYPE_FUSE;
+ } else if (strncmp(mem->desc, "lock", strlen("lock")) == 0) {
+ b[1] = XPRG_MEM_TYPE_LOCKBITS;
+ } else if (strcmp(mem->desc, "calibration") == 0) {
+ b[1] = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
+ } else if (strcmp(mem->desc, "usersig") == 0) {
+ b[1] = XPRG_MEM_TYPE_USERSIG;
+ } else {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_read_byte(): unknown memory \"%s\"\n",
+ progname, mem->desc);
+ return -1;
+ }
+ addr += mem->offset;
+
+ b[0] = XPRG_CMD_READ_MEM;
+ b[2] = addr >> 24;
+ b[3] = addr >> 16;
+ b[4] = addr >> 8;
+ b[5] = addr;
+ b[6] = 0;
+ b[7] = 1;
+ if (stk600_xprog_command(pgm, b, 8, 3) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_read_byte(): XPRG_CMD_READ_MEM failed\n",
+ progname);
+ return -1;
+ }
+ *value = b[2];
+ return 0;
+}
+
+
+static int stk600_xprog_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned char *b;
+ unsigned int offset;
+ unsigned char memtype;
+ int n_bytes_orig = n_bytes, dynamic_memtype = 0;
+ unsigned long use_ext_addr = 0;
+
+ /*
+ * The XPROG read command supports at most 256 bytes in one
+ * transfer.
+ */
+ if (page_size > 256)
+ page_size = 256; /* not really a page size anymore */
+
+ /*
+ * Fancy offsets everywhere.
+ * This is probably what AVR079 means when writing about the
+ * "TIF address space".
+ */
+ if (strcmp(mem->desc, "flash") == 0) {
+ memtype = 0;
+ dynamic_memtype = 1;
+ if (mem->size > 64 * 1024)
+ use_ext_addr = (1UL << 31);
+ } else if (strcmp(mem->desc, "application") == 0 ||
+ strcmp(mem->desc, "apptable") == 0) {
+ memtype = XPRG_MEM_TYPE_APPL;
+ if (mem->size > 64 * 1024)
+ use_ext_addr = (1UL << 31);
+ } else if (strcmp(mem->desc, "boot") == 0) {
+ memtype = XPRG_MEM_TYPE_BOOT;
+ // Do we have to consider the total amount of flash
+ // instead to decide whether to use extended addressing?
+ if (mem->size > 64 * 1024)
+ use_ext_addr = (1UL << 31);
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ memtype = XPRG_MEM_TYPE_EEPROM;
+ } else if (strcmp(mem->desc, "signature") == 0) {
+ memtype = XPRG_MEM_TYPE_APPL;
+ } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
+ memtype = XPRG_MEM_TYPE_FUSE;
+ } else if (strncmp(mem->desc, "lock", strlen("lock")) == 0) {
+ memtype = XPRG_MEM_TYPE_LOCKBITS;
+ } else if (strcmp(mem->desc, "calibration") == 0) {
+ memtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
+ } else if (strcmp(mem->desc, "usersig") == 0) {
+ memtype = XPRG_MEM_TYPE_USERSIG;
+ } else {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_paged_load(): unknown paged memory \"%s\"\n",
+ progname, mem->desc);
+ return -1;
+ }
+ offset = addr;
+ addr += mem->offset;
+
+ if ((b = malloc(page_size + 2)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_paged_load(): out of memory\n",
+ progname);
+ return -1;
+ }
+
+ if (stk500v2_loadaddr(pgm, use_ext_addr) < 0) {
+ free(b);
+ return -1;
+ }
+
+ while (n_bytes != 0) {
+ if (dynamic_memtype)
+ memtype = stk600_xprog_memtype(pgm, addr - mem->offset);
+
+ b[0] = XPRG_CMD_READ_MEM;
+ b[1] = memtype;
+ b[2] = addr >> 24;
+ b[3] = addr >> 16;
+ b[4] = addr >> 8;
+ b[5] = addr;
+ b[6] = page_size >> 8;
+ b[7] = page_size;
+ if (stk600_xprog_command(pgm, b, 8, page_size + 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_paged_load(): XPRG_CMD_READ_MEM failed\n",
+ progname);
+ free(b);
+ return -1;
+ }
+ memcpy(mem->buf + offset, b + 2, page_size);
+ if (n_bytes < page_size) {
+ n_bytes = page_size;
+ }
+ offset += page_size;
+ addr += page_size;
+ n_bytes -= page_size;
+ }
+ free(b);
+
+ return n_bytes_orig;
+}
+
+static int stk600_xprog_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned char *b;
+ unsigned int offset;
+ unsigned char memtype;
+ int n_bytes_orig = n_bytes, dynamic_memtype = 0;
+ size_t writesize;
+ unsigned long use_ext_addr = 0;
+ unsigned char writemode;
+
+ /*
+ * The XPROG read command supports at most 256 bytes in one
+ * transfer.
+ */
+ if (page_size > 512) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_paged_write(): cannot handle page size > 512\n",
+ progname);
+ return -1;
+ }
+
+ /*
+ * Fancy offsets everywhere.
+ * This is probably what AVR079 means when writing about the
+ * "TIF address space".
+ */
+ if (strcmp(mem->desc, "flash") == 0) {
+ memtype = 0;
+ dynamic_memtype = 1;
+ writemode = (1 << XPRG_MEM_WRITE_WRITE);
+ if (mem->size > 64 * 1024)
+ use_ext_addr = (1UL << 31);
+ } else if (strcmp(mem->desc, "application") == 0 ||
+ strcmp(mem->desc, "apptable") == 0) {
+ memtype = XPRG_MEM_TYPE_APPL;
+ writemode = (1 << XPRG_MEM_WRITE_WRITE);
+ if (mem->size > 64 * 1024)
+ use_ext_addr = (1UL << 31);
+ } else if (strcmp(mem->desc, "boot") == 0) {
+ memtype = XPRG_MEM_TYPE_BOOT;
+ writemode = (1 << XPRG_MEM_WRITE_WRITE);
+ // Do we have to consider the total amount of flash
+ // instead to decide whether to use extended addressing?
+ if (mem->size > 64 * 1024)
+ use_ext_addr = (1UL << 31);
+ } else if (strcmp(mem->desc, "eeprom") == 0) {
+ memtype = XPRG_MEM_TYPE_EEPROM;
+ writemode = (1 << XPRG_MEM_WRITE_WRITE) | (1 << XPRG_MEM_WRITE_ERASE);
+ } else if (strcmp(mem->desc, "signature") == 0) {
+ memtype = XPRG_MEM_TYPE_APPL;
+ writemode = (1 << XPRG_MEM_WRITE_WRITE);
+ } else if (strncmp(mem->desc, "fuse", strlen("fuse")) == 0) {
+ memtype = XPRG_MEM_TYPE_FUSE;
+ writemode = (1 << XPRG_MEM_WRITE_WRITE);
+ } else if (strncmp(mem->desc, "lock", strlen("lock")) == 0) {
+ memtype = XPRG_MEM_TYPE_LOCKBITS;
+ writemode = (1 << XPRG_MEM_WRITE_WRITE);
+ } else if (strcmp(mem->desc, "calibration") == 0) {
+ memtype = XPRG_MEM_TYPE_FACTORY_CALIBRATION;
+ writemode = (1 << XPRG_MEM_WRITE_WRITE);
+ } else if (strcmp(mem->desc, "usersig") == 0) {
+ memtype = XPRG_MEM_TYPE_USERSIG;
+ writemode = (1 << XPRG_MEM_WRITE_WRITE);
+ } else {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_paged_write(): unknown paged memory \"%s\"\n",
+ progname, mem->desc);
+ return -1;
+ }
+ offset = addr;
+ addr += mem->offset;
+
+ if ((b = malloc(page_size + 9)) == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_paged_write(): out of memory\n",
+ progname);
+ return -1;
+ }
+
+ if (stk500v2_loadaddr(pgm, use_ext_addr) < 0) {
+ free(b);
+ return -1;
+ }
+
+ while (n_bytes != 0) {
+
+ if (dynamic_memtype)
+ memtype = stk600_xprog_memtype(pgm, addr - mem->offset);
+
+ if (page_size > 256) {
+ /*
+ * AVR079 is not quite clear. While it suggests that
+ * downloading up to 512 bytes (256 words) were OK, it
+ * obviously isn't -- 512-byte pages on the ATxmega128A1
+ * are getting corrupted when written as a single piece.
+ * It writes random junk somewhere beyond byte 256.
+ * Splitting it into 256 byte chunks, and only setting the
+ * erase page / write page bits in the final chunk helps.
+ */
+ if (page_size % 256 != 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_paged_write(): page size not multiple of 256\n",
+ progname);
+ free(b);
+ return -1;
+ }
+ unsigned int chunk;
+ for (chunk = 0; chunk < page_size; chunk += 256) {
+ if (n_bytes < 256) {
+ memset(b + 9 + n_bytes, 0xff, 256 - n_bytes);
+ writesize = n_bytes;
+ } else {
+ writesize = 256;
+ }
+ b[0] = XPRG_CMD_WRITE_MEM;
+ b[1] = memtype;
+ b[2] = writemode;
+ b[3] = addr >> 24;
+ b[4] = addr >> 16;
+ b[5] = addr >> 8;
+ b[6] = addr;
+ b[7] = 1;
+ b[8] = 0;
+ memcpy(b + 9, mem->buf + offset, writesize);
+ if (stk600_xprog_command(pgm, b, 256 + 9, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_paged_write(): XPRG_CMD_WRITE_MEM failed\n",
+ progname);
+ free(b);
+ return -1;
+ }
+ if (n_bytes < 256)
+ n_bytes = 256;
+
+ offset += 256;
+ addr += 256;
+ n_bytes -= 256;
+ }
+ } else {
+ if (n_bytes < page_size) {
+ /*
+ * This can easily happen if the input file was not a
+ * multiple of the page size.
+ */
+ memset(b + 9 + n_bytes, 0xff, page_size - n_bytes);
+ writesize = n_bytes;
+ } else {
+ writesize = page_size;
+ }
+ b[0] = XPRG_CMD_WRITE_MEM;
+ b[1] = memtype;
+ b[2] = writemode;
+ b[3] = addr >> 24;
+ b[4] = addr >> 16;
+ b[5] = addr >> 8;
+ b[6] = addr;
+ b[7] = page_size >> 8;
+ b[8] = page_size;
+ memcpy(b + 9, mem->buf + offset, writesize);
+ if (stk600_xprog_command(pgm, b, page_size + 9, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_paged_write(): XPRG_CMD_WRITE_MEM failed\n",
+ progname);
+ free(b);
+ return -1;
+ }
+ if (n_bytes < page_size)
+ n_bytes = page_size;
+
+ offset += page_size;
+ addr += page_size;
+ n_bytes -= page_size;
+ }
+ }
+ free(b);
+
+ return n_bytes_orig;
+}
+
+static int stk600_xprog_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char b[6];
+ AVRMEM *mem;
+ unsigned int addr = 0;
+
+ if (p->flags & AVRPART_HAS_TPI) {
+ if ((mem = avr_locate_mem(p, "flash")) == NULL) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_chip_erase(): no FLASH definition found for TPI device\n",
+ progname);
+ return -1;
+ }
+ addr = mem->offset + 1;
+ }
+
+ b[0] = XPRG_CMD_ERASE;
+ b[1] = XPRG_ERASE_CHIP;
+ b[2] = addr >> 24;
+ b[3] = addr >> 16;
+ b[4] = addr >> 8;
+ b[5] = addr;
+ if (stk600_xprog_command(pgm, b, 6, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_chip_erase(): XPRG_CMD_ERASE(XPRG_ERASE_CHIP) failed\n",
+ progname);
+ return -1;
+ }
+ return 0;
+}
+
+static int stk600_xprog_page_erase(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int addr)
+{
+ unsigned char b[6];
+
+ if (strcmp(m->desc, "flash") == 0) {
+ b[1] = stk600_xprog_memtype(pgm, addr) == XPRG_MEM_TYPE_APPL?
+ XPRG_ERASE_APP_PAGE: XPRG_ERASE_BOOT_PAGE;
+ } else if (strcmp(m->desc, "application") == 0 ||
+ strcmp(m->desc, "apptable") == 0) {
+ b[1] = XPRG_ERASE_APP_PAGE;
+ } else if (strcmp(m->desc, "boot") == 0) {
+ b[1] = XPRG_ERASE_BOOT_PAGE;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ b[1] = XPRG_ERASE_EEPROM_PAGE;
+ } else if (strcmp(m->desc, "usersig") == 0) {
+ b[1] = XPRG_ERASE_USERSIG;
+ } else {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_page_erase(): unknown paged memory \"%s\"\n",
+ progname, m->desc);
+ return -1;
+ }
+ addr += m->offset;
+ b[0] = XPRG_CMD_ERASE;
+ b[2] = addr >> 24;
+ b[3] = addr >> 16;
+ b[4] = addr >> 8;
+ b[5] = addr;
+ if (stk600_xprog_command(pgm, b, 6, 2) < 0) {
+ avrdude_message(MSG_INFO, "%s: stk600_xprog_page_erase(): XPRG_CMD_ERASE(%d) failed\n",
+ progname, b[1]);
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Modify pgm's methods for XPROG operation.
+ */
+static void stk600_setup_xprog(PROGRAMMER * pgm)
+{
+ pgm->program_enable = stk600_xprog_program_enable;
+ pgm->disable = stk600_xprog_disable;
+ pgm->read_byte = stk600_xprog_read_byte;
+ pgm->write_byte = stk600_xprog_write_byte;
+ pgm->paged_load = stk600_xprog_paged_load;
+ pgm->paged_write = stk600_xprog_paged_write;
+ pgm->page_erase = stk600_xprog_page_erase;
+ pgm->chip_erase = stk600_xprog_chip_erase;
+}
+
+
+/*
+ * Modify pgm's methods for ISP operation.
+ */
+static void stk600_setup_isp(PROGRAMMER * pgm)
+{
+ pgm->program_enable = stk500v2_program_enable;
+ pgm->disable = stk500v2_disable;
+ pgm->read_byte = stk500isp_read_byte;
+ pgm->write_byte = stk500isp_write_byte;
+ pgm->paged_load = stk500v2_paged_load;
+ pgm->paged_write = stk500v2_paged_write;
+ pgm->page_erase = stk500v2_page_erase;
+ pgm->chip_erase = stk500v2_chip_erase;
+}
+
+const char stk500v2_desc[] = "Atmel STK500 Version 2.x firmware";
+
+void stk500v2_initpgm(PROGRAMMER * pgm)
+{
+
+ strcpy(pgm->type, "STK500V2");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500v2_initialize;
+ pgm->display = stk500v2_display;
+ pgm->enable = stk500v2_enable;
+ pgm->disable = stk500v2_disable;
+ pgm->program_enable = stk500v2_program_enable;
+ pgm->chip_erase = stk500v2_chip_erase;
+ pgm->cmd = stk500v2_cmd;
+ pgm->open = stk500v2_open;
+ pgm->close = stk500v2_close;
+ pgm->read_byte = stk500isp_read_byte;
+ pgm->write_byte = stk500isp_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500v2_paged_write;
+ pgm->paged_load = stk500v2_paged_load;
+ pgm->page_erase = stk500v2_page_erase;
+ pgm->print_parms = stk500v2_print_parms;
+ pgm->set_vtarget = stk500v2_set_vtarget;
+ pgm->set_varef = stk500v2_set_varef;
+ pgm->set_fosc = stk500v2_set_fosc;
+ pgm->set_sck_period = stk500v2_set_sck_period;
+ pgm->perform_osccal = stk500v2_perform_osccal;
+ pgm->setup = stk500v2_setup;
+ pgm->teardown = stk500v2_teardown;
+ pgm->page_size = 256;
+ pgm->set_upload_size= stk500v2_set_upload_size;
+}
+
+const char stk500pp_desc[] = "Atmel STK500 V2 in parallel programming mode";
+
+void stk500pp_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "STK500PP");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500pp_initialize;
+ pgm->display = stk500v2_display;
+ pgm->enable = stk500v2_enable;
+ pgm->disable = stk500pp_disable;
+ pgm->program_enable = stk500pp_program_enable;
+ pgm->chip_erase = stk500pp_chip_erase;
+ pgm->open = stk500v2_open;
+ pgm->close = stk500v2_close;
+ pgm->read_byte = stk500pp_read_byte;
+ pgm->write_byte = stk500pp_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500pp_paged_write;
+ pgm->paged_load = stk500pp_paged_load;
+ pgm->print_parms = stk500v2_print_parms;
+ pgm->set_vtarget = stk500v2_set_vtarget;
+ pgm->set_varef = stk500v2_set_varef;
+ pgm->set_fosc = stk500v2_set_fosc;
+ pgm->set_sck_period = stk500v2_set_sck_period;
+ pgm->setup = stk500v2_setup;
+ pgm->teardown = stk500v2_teardown;
+ pgm->page_size = 256;
+}
+
+const char stk500hvsp_desc[] = "Atmel STK500 V2 in high-voltage serial programming mode";
+
+void stk500hvsp_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "STK500HVSP");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500hvsp_initialize;
+ pgm->display = stk500v2_display;
+ pgm->enable = stk500v2_enable;
+ pgm->disable = stk500hvsp_disable;
+ pgm->program_enable = stk500hvsp_program_enable;
+ pgm->chip_erase = stk500hvsp_chip_erase;
+ pgm->open = stk500v2_open;
+ pgm->close = stk500v2_close;
+ pgm->read_byte = stk500hvsp_read_byte;
+ pgm->write_byte = stk500hvsp_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500hvsp_paged_write;
+ pgm->paged_load = stk500hvsp_paged_load;
+ pgm->print_parms = stk500v2_print_parms;
+ pgm->set_vtarget = stk500v2_set_vtarget;
+ pgm->set_varef = stk500v2_set_varef;
+ pgm->set_fosc = stk500v2_set_fosc;
+ pgm->set_sck_period = stk500v2_set_sck_period;
+ pgm->setup = stk500v2_setup;
+ pgm->teardown = stk500v2_teardown;
+ pgm->page_size = 256;
+}
+
+const char stk500v2_jtagmkII_desc[] = "Atmel JTAG ICE mkII in ISP mode";
+
+void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "JTAGMKII_ISP");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500v2_initialize;
+ pgm->display = stk500v2_display;
+ pgm->enable = stk500v2_enable;
+ pgm->disable = stk500v2_disable;
+ pgm->program_enable = stk500v2_program_enable;
+ pgm->chip_erase = stk500v2_chip_erase;
+ pgm->cmd = stk500v2_cmd;
+ pgm->open = stk500v2_jtagmkII_open;
+ pgm->close = stk500v2_jtagmkII_close;
+ pgm->read_byte = stk500isp_read_byte;
+ pgm->write_byte = stk500isp_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500v2_paged_write;
+ pgm->paged_load = stk500v2_paged_load;
+ pgm->page_erase = stk500v2_page_erase;
+ pgm->print_parms = stk500v2_print_parms;
+ pgm->set_sck_period = stk500v2_set_sck_period_mk2;
+ pgm->perform_osccal = stk500v2_perform_osccal;
+ pgm->setup = stk500v2_jtagmkII_setup;
+ pgm->teardown = stk500v2_jtagmkII_teardown;
+ pgm->page_size = 256;
+}
+
+const char stk500v2_dragon_isp_desc[] = "Atmel AVR Dragon in ISP mode";
+
+void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "DRAGON_ISP");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500v2_initialize;
+ pgm->display = stk500v2_display;
+ pgm->enable = stk500v2_enable;
+ pgm->disable = stk500v2_disable;
+ pgm->program_enable = stk500v2_program_enable;
+ pgm->chip_erase = stk500v2_chip_erase;
+ pgm->cmd = stk500v2_cmd;
+ pgm->open = stk500v2_dragon_isp_open;
+ pgm->close = stk500v2_jtagmkII_close;
+ pgm->read_byte = stk500isp_read_byte;
+ pgm->write_byte = stk500isp_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500v2_paged_write;
+ pgm->paged_load = stk500v2_paged_load;
+ pgm->page_erase = stk500v2_page_erase;
+ pgm->print_parms = stk500v2_print_parms;
+ pgm->set_sck_period = stk500v2_set_sck_period_mk2;
+ pgm->setup = stk500v2_jtagmkII_setup;
+ pgm->teardown = stk500v2_jtagmkII_teardown;
+ pgm->page_size = 256;
+}
+
+const char stk500v2_dragon_pp_desc[] = "Atmel AVR Dragon in PP mode";
+
+void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "DRAGON_PP");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500pp_initialize;
+ pgm->display = stk500v2_display;
+ pgm->enable = stk500v2_enable;
+ pgm->disable = stk500pp_disable;
+ pgm->program_enable = stk500pp_program_enable;
+ pgm->chip_erase = stk500pp_chip_erase;
+ pgm->open = stk500v2_dragon_hv_open;
+ pgm->close = stk500v2_jtagmkII_close;
+ pgm->read_byte = stk500pp_read_byte;
+ pgm->write_byte = stk500pp_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500pp_paged_write;
+ pgm->paged_load = stk500pp_paged_load;
+ pgm->print_parms = stk500v2_print_parms;
+ pgm->set_vtarget = stk500v2_set_vtarget;
+ pgm->set_varef = stk500v2_set_varef;
+ pgm->set_fosc = stk500v2_set_fosc;
+ pgm->set_sck_period = stk500v2_set_sck_period_mk2;
+ pgm->setup = stk500v2_jtagmkII_setup;
+ pgm->teardown = stk500v2_jtagmkII_teardown;
+ pgm->page_size = 256;
+}
+
+const char stk500v2_dragon_hvsp_desc[] = "Atmel AVR Dragon in HVSP mode";
+
+void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "DRAGON_HVSP");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500hvsp_initialize;
+ pgm->display = stk500v2_display;
+ pgm->enable = stk500v2_enable;
+ pgm->disable = stk500hvsp_disable;
+ pgm->program_enable = stk500hvsp_program_enable;
+ pgm->chip_erase = stk500hvsp_chip_erase;
+ pgm->open = stk500v2_dragon_hv_open;
+ pgm->close = stk500v2_jtagmkII_close;
+ pgm->read_byte = stk500hvsp_read_byte;
+ pgm->write_byte = stk500hvsp_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500hvsp_paged_write;
+ pgm->paged_load = stk500hvsp_paged_load;
+ pgm->print_parms = stk500v2_print_parms;
+ pgm->set_vtarget = stk500v2_set_vtarget;
+ pgm->set_varef = stk500v2_set_varef;
+ pgm->set_fosc = stk500v2_set_fosc;
+ pgm->set_sck_period = stk500v2_set_sck_period_mk2;
+ pgm->setup = stk500v2_jtagmkII_setup;
+ pgm->teardown = stk500v2_jtagmkII_teardown;
+ pgm->page_size = 256;
+}
+
+const char stk600_desc[] = "Atmel STK600";
+
+void stk600_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "STK600");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500v2_initialize;
+ pgm->display = stk500v2_display;
+ pgm->enable = stk500v2_enable;
+ pgm->disable = stk500v2_disable;
+ pgm->program_enable = stk500v2_program_enable;
+ pgm->chip_erase = stk500v2_chip_erase;
+ pgm->cmd = stk500v2_cmd;
+ pgm->open = stk600_open;
+ pgm->close = stk500v2_close;
+ pgm->read_byte = stk500isp_read_byte;
+ pgm->write_byte = stk500isp_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500v2_paged_write;
+ pgm->paged_load = stk500v2_paged_load;
+ pgm->page_erase = stk500v2_page_erase;
+ pgm->print_parms = stk500v2_print_parms;
+ pgm->set_vtarget = stk600_set_vtarget;
+ pgm->set_varef = stk600_set_varef;
+ pgm->set_fosc = stk600_set_fosc;
+ pgm->set_sck_period = stk600_set_sck_period;
+ pgm->perform_osccal = stk500v2_perform_osccal;
+ pgm->setup = stk500v2_setup;
+ pgm->teardown = stk500v2_teardown;
+ pgm->page_size = 256;
+}
+
+const char stk600pp_desc[] = "Atmel STK600 in parallel programming mode";
+
+void stk600pp_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "STK600PP");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500pp_initialize;
+ pgm->display = stk500v2_display;
+ pgm->enable = stk500v2_enable;
+ pgm->disable = stk500pp_disable;
+ pgm->program_enable = stk500pp_program_enable;
+ pgm->chip_erase = stk500pp_chip_erase;
+ pgm->open = stk600_open;
+ pgm->close = stk500v2_close;
+ pgm->read_byte = stk500pp_read_byte;
+ pgm->write_byte = stk500pp_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500pp_paged_write;
+ pgm->paged_load = stk500pp_paged_load;
+ pgm->print_parms = stk500v2_print_parms;
+ pgm->set_vtarget = stk600_set_vtarget;
+ pgm->set_varef = stk600_set_varef;
+ pgm->set_fosc = stk600_set_fosc;
+ pgm->set_sck_period = stk600_set_sck_period;
+ pgm->setup = stk500v2_setup;
+ pgm->teardown = stk500v2_teardown;
+ pgm->page_size = 256;
+}
+
+const char stk600hvsp_desc[] = "Atmel STK600 in high-voltage serial programming mode";
+
+void stk600hvsp_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "STK600HVSP");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500hvsp_initialize;
+ pgm->display = stk500v2_display;
+ pgm->enable = stk500v2_enable;
+ pgm->disable = stk500hvsp_disable;
+ pgm->program_enable = stk500hvsp_program_enable;
+ pgm->chip_erase = stk500hvsp_chip_erase;
+ pgm->open = stk600_open;
+ pgm->close = stk500v2_close;
+ pgm->read_byte = stk500hvsp_read_byte;
+ pgm->write_byte = stk500hvsp_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500hvsp_paged_write;
+ pgm->paged_load = stk500hvsp_paged_load;
+ pgm->print_parms = stk500v2_print_parms;
+ pgm->set_vtarget = stk600_set_vtarget;
+ pgm->set_varef = stk600_set_varef;
+ pgm->set_fosc = stk600_set_fosc;
+ pgm->set_sck_period = stk600_set_sck_period;
+ pgm->setup = stk500v2_setup;
+ pgm->teardown = stk500v2_teardown;
+ pgm->page_size = 256;
+}
+
+const char stk500v2_jtag3_desc[] = "Atmel JTAGICE3 in ISP mode";
+
+void stk500v2_jtag3_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "JTAG3_ISP");
+
+ /*
+ * mandatory functions
+ */
+ pgm->initialize = stk500v2_jtag3_initialize;
+ pgm->display = stk500v2_display;
+ pgm->enable = stk500v2_enable;
+ pgm->disable = stk500v2_jtag3_disable;
+ pgm->program_enable = stk500v2_program_enable;
+ pgm->chip_erase = stk500v2_chip_erase;
+ pgm->cmd = stk500v2_jtag3_cmd;
+ pgm->open = stk500v2_jtag3_open;
+ pgm->close = stk500v2_jtag3_close;
+ pgm->read_byte = stk500isp_read_byte;
+ pgm->write_byte = stk500isp_write_byte;
+
+ /*
+ * optional functions
+ */
+ pgm->paged_write = stk500v2_paged_write;
+ pgm->paged_load = stk500v2_paged_load;
+ pgm->page_erase = stk500v2_page_erase;
+ pgm->print_parms = stk500v2_print_parms;
+ pgm->set_sck_period = stk500v2_jtag3_set_sck_period;
+ pgm->perform_osccal = stk500v2_perform_osccal;
+ pgm->setup = stk500v2_jtag3_setup;
+ pgm->teardown = stk500v2_jtag3_teardown;
+ pgm->page_size = 256;
+}
+
+void stk500v2_set_upload_size(PROGRAMMER * pgm, int size)
+{
+ unsigned char buf[16];
+ buf[0] = CMD_SET_UPLOAD_SIZE_PRUSA3D;
+ buf[1] = size & 0xff;
+ buf[2] = size >> 8;
+ buf[3] = size >> 16;
+ stk500v2_command(pgm, buf, 4, sizeof(buf));
+}
+
diff --git a/xs/src/avrdude/stk500v2.h b/xs/src/avrdude/stk500v2.h
new file mode 100644
index 000000000..5c182c59c
--- /dev/null
+++ b/xs/src/avrdude/stk500v2.h
@@ -0,0 +1,65 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2002-2005 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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 stk500v2_h
+#define stk500v2_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char stk500v2_desc[];
+extern const char stk500hvsp_desc[];
+extern const char stk500pp_desc[];
+extern const char stk500v2_jtagmkII_desc[];
+extern const char stk500v2_dragon_hvsp_desc[];
+extern const char stk500v2_dragon_isp_desc[];
+extern const char stk500v2_dragon_pp_desc[];
+extern const char stk500v2_jtag3_desc[];
+extern const char stk600_desc[];
+extern const char stk600hvsp_desc[];
+extern const char stk600pp_desc[];
+void stk500v2_initpgm (PROGRAMMER * pgm);
+void stk500hvsp_initpgm (PROGRAMMER * pgm);
+void stk500pp_initpgm (PROGRAMMER * pgm);
+void stk500v2_jtagmkII_initpgm(PROGRAMMER * pgm);
+void stk500v2_jtag3_initpgm(PROGRAMMER * pgm);
+void stk500v2_dragon_hvsp_initpgm(PROGRAMMER * pgm);
+void stk500v2_dragon_isp_initpgm(PROGRAMMER * pgm);
+void stk500v2_dragon_pp_initpgm(PROGRAMMER * pgm);
+void stk600_initpgm (PROGRAMMER * pgm);
+void stk600hvsp_initpgm (PROGRAMMER * pgm);
+void stk600pp_initpgm (PROGRAMMER * pgm);
+
+void stk500v2_setup(PROGRAMMER * pgm);
+void stk500v2_teardown(PROGRAMMER * pgm);
+int stk500v2_drain(PROGRAMMER * pgm, int display);
+int stk500v2_getsync(PROGRAMMER * pgm);
+
+void stk500v2_set_upload_size(PROGRAMMER * pgm, int size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/xs/src/avrdude/stk500v2_private.h b/xs/src/avrdude/stk500v2_private.h
new file mode 100644
index 000000000..31c1bb23d
--- /dev/null
+++ b/xs/src/avrdude/stk500v2_private.h
@@ -0,0 +1,331 @@
+//**** ATMEL AVR - A P P L I C A T I O N N O T E ************************
+//*
+//* Title: AVR068 - STK500 Communication Protocol
+//* Filename: command.h
+//* Version: 1.0
+//* Last updated: 10.01.2005
+//*
+//* Support E-mail: avr@atmel.com
+//*
+//**************************************************************************
+
+// *****************[ STK message constants ]***************************
+
+#define MESSAGE_START 0x1B //= ESC = 27 decimal
+#define TOKEN 0x0E
+
+// *****************[ STK general command constants ]**************************
+
+#define CMD_SIGN_ON 0x01
+#define CMD_SET_PARAMETER 0x02
+#define CMD_GET_PARAMETER 0x03
+#define CMD_SET_DEVICE_PARAMETERS 0x04
+#define CMD_OSCCAL 0x05
+#define CMD_LOAD_ADDRESS 0x06
+#define CMD_FIRMWARE_UPGRADE 0x07
+#define CMD_CHECK_TARGET_CONNECTION 0x0D
+#define CMD_LOAD_RC_ID_TABLE 0x0E
+#define CMD_LOAD_EC_ID_TABLE 0x0F
+
+// *****************[ STK ISP command constants ]******************************
+
+#define CMD_ENTER_PROGMODE_ISP 0x10
+#define CMD_LEAVE_PROGMODE_ISP 0x11
+#define CMD_CHIP_ERASE_ISP 0x12
+#define CMD_PROGRAM_FLASH_ISP 0x13
+#define CMD_READ_FLASH_ISP 0x14
+#define CMD_PROGRAM_EEPROM_ISP 0x15
+#define CMD_READ_EEPROM_ISP 0x16
+#define CMD_PROGRAM_FUSE_ISP 0x17
+#define CMD_READ_FUSE_ISP 0x18
+#define CMD_PROGRAM_LOCK_ISP 0x19
+#define CMD_READ_LOCK_ISP 0x1A
+#define CMD_READ_SIGNATURE_ISP 0x1B
+#define CMD_READ_OSCCAL_ISP 0x1C
+#define CMD_SPI_MULTI 0x1D /* STK500v2, AVRISPmkII,
+ * JTAGICEmkII */
+#define CMD_SET_SCK 0x1D /* JTAGICE3 */
+#define CMD_GET_SCK 0x1E /* JTAGICE3 */
+
+// *****************[ STK PP command constants ]*******************************
+
+#define CMD_ENTER_PROGMODE_PP 0x20
+#define CMD_LEAVE_PROGMODE_PP 0x21
+#define CMD_CHIP_ERASE_PP 0x22
+#define CMD_PROGRAM_FLASH_PP 0x23
+#define CMD_READ_FLASH_PP 0x24
+#define CMD_PROGRAM_EEPROM_PP 0x25
+#define CMD_READ_EEPROM_PP 0x26
+#define CMD_PROGRAM_FUSE_PP 0x27
+#define CMD_READ_FUSE_PP 0x28
+#define CMD_PROGRAM_LOCK_PP 0x29
+#define CMD_READ_LOCK_PP 0x2A
+#define CMD_READ_SIGNATURE_PP 0x2B
+#define CMD_READ_OSCCAL_PP 0x2C
+
+#define CMD_SET_CONTROL_STACK 0x2D
+
+// *****************[ STK HVSP command constants ]*****************************
+
+#define CMD_ENTER_PROGMODE_HVSP 0x30
+#define CMD_LEAVE_PROGMODE_HVSP 0x31
+#define CMD_CHIP_ERASE_HVSP 0x32
+#define CMD_PROGRAM_FLASH_HVSP 0x33
+#define CMD_READ_FLASH_HVSP 0x34
+#define CMD_PROGRAM_EEPROM_HVSP 0x35
+#define CMD_READ_EEPROM_HVSP 0x36
+#define CMD_PROGRAM_FUSE_HVSP 0x37
+#define CMD_READ_FUSE_HVSP 0x38
+#define CMD_PROGRAM_LOCK_HVSP 0x39
+#define CMD_READ_LOCK_HVSP 0x3A
+#define CMD_READ_SIGNATURE_HVSP 0x3B
+#define CMD_READ_OSCCAL_HVSP 0x3C
+// These two are redefined since 0x30/0x31 collide
+// with the STK600 bootloader.
+#define CMD_ENTER_PROGMODE_HVSP_STK600 0x3D
+#define CMD_LEAVE_PROGMODE_HVSP_STK600 0x3E
+
+// *** XPROG command constants ***
+
+#define CMD_XPROG 0x50
+#define CMD_XPROG_SETMODE 0x51
+
+
+// *****************[ STK Prusa3D specific command constants ]*****************
+
+#define CMD_SET_UPLOAD_SIZE_PRUSA3D 0x71
+
+
+// *** AVR32 JTAG Programming command ***
+
+#define CMD_JTAG_AVR32 0x80
+#define CMD_ENTER_PROGMODE_JTAG_AVR32 0x81
+#define CMD_LEAVE_PROGMODE_JTAG_AVR32 0x82
+
+
+// *** AVR JTAG Programming command ***
+
+#define CMD_JTAG_AVR 0x90
+
+// *****************[ STK test command constants ]***************************
+
+#define CMD_ENTER_TESTMODE 0x60
+#define CMD_LEAVE_TESTMODE 0x61
+#define CMD_CHIP_WRITE 0x62
+#define CMD_PROGRAM_FLASH_PARTIAL 0x63
+#define CMD_PROGRAM_EEPROM_PARTIAL 0x64
+#define CMD_PROGRAM_SIGNATURE_ROW 0x65
+#define CMD_READ_FLASH_MARGIN 0x66
+#define CMD_READ_EEPROM_MARGIN 0x67
+#define CMD_READ_SIGNATURE_ROW_MARGIN 0x68
+#define CMD_PROGRAM_TEST_FUSE 0x69
+#define CMD_READ_TEST_FUSE 0x6A
+#define CMD_PROGRAM_HIDDEN_FUSE_LOW 0x6B
+#define CMD_READ_HIDDEN_FUSE_LOW 0x6C
+#define CMD_PROGRAM_HIDDEN_FUSE_HIGH 0x6D
+#define CMD_READ_HIDDEN_FUSE_HIGH 0x6E
+#define CMD_PROGRAM_HIDDEN_FUSE_EXT 0x6F
+#define CMD_READ_HIDDEN_FUSE_EXT 0x70
+
+// *****************[ STK status constants ]***************************
+
+// Success
+#define STATUS_CMD_OK 0x00
+
+// Warnings
+#define STATUS_CMD_TOUT 0x80
+#define STATUS_RDY_BSY_TOUT 0x81
+#define STATUS_SET_PARAM_MISSING 0x82
+
+// Errors
+#define STATUS_CMD_FAILED 0xC0
+#define STATUS_CKSUM_ERROR 0xC1
+#define STATUS_CMD_UNKNOWN 0xC9
+#define STATUS_CMD_ILLEGAL_PARAMETER 0xCA
+
+// Status
+#define STATUS_ISP_READY 0x00
+#define STATUS_CONN_FAIL_MOSI 0x01
+#define STATUS_CONN_FAIL_RST 0x02
+#define STATUS_CONN_FAIL_SCK 0x04
+#define STATUS_TGT_NOT_DETECTED 0x10
+#define STATUS_TGT_REVERSE_INSERTED 0x20
+
+// hw_status
+// Bits in status variable
+// Bit 0-3: Slave MCU
+// Bit 4-7: Master MCU
+
+#define STATUS_AREF_ERROR 0
+// Set to '1' if AREF is short circuited
+
+#define STATUS_VTG_ERROR 4
+// Set to '1' if VTG is short circuited
+
+#define STATUS_RC_CARD_ERROR 5
+// Set to '1' if board id changes when board is powered
+
+#define STATUS_PROGMODE 6
+// Set to '1' if board is in programming mode
+
+#define STATUS_POWER_SURGE 7
+// Set to '1' if board draws excessive current
+
+// *****************[ STK parameter constants ]***************************
+#define PARAM_BUILD_NUMBER_LOW 0x80 /* ??? */
+#define PARAM_BUILD_NUMBER_HIGH 0x81 /* ??? */
+#define PARAM_HW_VER 0x90
+#define PARAM_SW_MAJOR 0x91
+#define PARAM_SW_MINOR 0x92
+#define PARAM_VTARGET 0x94
+#define PARAM_VADJUST 0x95 /* STK500 only */
+#define PARAM_OSC_PSCALE 0x96 /* STK500 only */
+#define PARAM_OSC_CMATCH 0x97 /* STK500 only */
+#define PARAM_SCK_DURATION 0x98 /* STK500 only */
+#define PARAM_TOPCARD_DETECT 0x9A /* STK500 only */
+#define PARAM_STATUS 0x9C /* STK500 only */
+#define PARAM_DATA 0x9D /* STK500 only */
+#define PARAM_RESET_POLARITY 0x9E /* STK500 only, and STK600 FW
+ * version <= 2.0.3 */
+#define PARAM_CONTROLLER_INIT 0x9F
+
+/* STK600 parameters */
+#define PARAM_STATUS_TGT_CONN 0xA1
+#define PARAM_DISCHARGEDELAY 0xA4
+#define PARAM_SOCKETCARD_ID 0xA5
+#define PARAM_ROUTINGCARD_ID 0xA6
+#define PARAM_EXPCARD_ID 0xA7
+#define PARAM_SW_MAJOR_SLAVE1 0xA8
+#define PARAM_SW_MINOR_SLAVE1 0xA9
+#define PARAM_SW_MAJOR_SLAVE2 0xAA
+#define PARAM_SW_MINOR_SLAVE2 0xAB
+#define PARAM_BOARD_ID_STATUS 0xAD
+#define PARAM_RESET 0xB4
+
+#define PARAM_JTAG_ALLOW_FULL_PAGE_STREAM 0x50
+#define PARAM_JTAG_EEPROM_PAGE_SIZE 0x52
+#define PARAM_JTAG_DAISY_BITS_BEFORE 0x53
+#define PARAM_JTAG_DAISY_BITS_AFTER 0x54
+#define PARAM_JTAG_DAISY_UNITS_BEFORE 0x55
+#define PARAM_JTAG_DAISY_UNITS_AFTER 0x56
+
+// *** Parameter constants for 2 byte values ***
+#define PARAM2_SCK_DURATION 0xC0
+#define PARAM2_CLOCK_CONF 0xC1
+#define PARAM2_AREF0 0xC2
+#define PARAM2_AREF1 0xC3
+
+#define PARAM2_JTAG_FLASH_SIZE_H 0xC5
+#define PARAM2_JTAG_FLASH_SIZE_L 0xC6
+#define PARAM2_JTAG_FLASH_PAGE_SIZE 0xC7
+#define PARAM2_RC_ID_TABLE_REV 0xC8
+#define PARAM2_EC_ID_TABLE_REV 0xC9
+
+/* STK600 XPROG section */
+// XPROG modes
+#define XPRG_MODE_PDI 0
+#define XPRG_MODE_JTAG 1
+#define XPRG_MODE_TPI 2
+
+// XPROG commands
+#define XPRG_CMD_ENTER_PROGMODE 0x01
+#define XPRG_CMD_LEAVE_PROGMODE 0x02
+#define XPRG_CMD_ERASE 0x03
+#define XPRG_CMD_WRITE_MEM 0x04
+#define XPRG_CMD_READ_MEM 0x05
+#define XPRG_CMD_CRC 0x06
+#define XPRG_CMD_SET_PARAM 0x07
+
+// Memory types
+#define XPRG_MEM_TYPE_APPL 1
+#define XPRG_MEM_TYPE_BOOT 2
+#define XPRG_MEM_TYPE_EEPROM 3
+#define XPRG_MEM_TYPE_FUSE 4
+#define XPRG_MEM_TYPE_LOCKBITS 5
+#define XPRG_MEM_TYPE_USERSIG 6
+#define XPRG_MEM_TYPE_FACTORY_CALIBRATION 7
+
+// Erase types
+#define XPRG_ERASE_CHIP 1
+#define XPRG_ERASE_APP 2
+#define XPRG_ERASE_BOOT 3
+#define XPRG_ERASE_EEPROM 4
+#define XPRG_ERASE_APP_PAGE 5
+#define XPRG_ERASE_BOOT_PAGE 6
+#define XPRG_ERASE_EEPROM_PAGE 7
+#define XPRG_ERASE_USERSIG 8
+#define XPRG_ERASE_CONFIG 9 // TPI only, prepare fuse write
+
+// Write mode flags
+#define XPRG_MEM_WRITE_ERASE 0
+#define XPRG_MEM_WRITE_WRITE 1
+
+// CRC types
+#define XPRG_CRC_APP 1
+#define XPRG_CRC_BOOT 2
+#define XPRG_CRC_FLASH 3
+
+// Error codes
+#define XPRG_ERR_OK 0
+#define XPRG_ERR_FAILED 1
+#define XPRG_ERR_COLLISION 2
+#define XPRG_ERR_TIMEOUT 3
+
+// XPROG parameters of different sizes
+// 4-byte address
+#define XPRG_PARAM_NVMBASE 0x01
+// 2-byte page size
+#define XPRG_PARAM_EEPPAGESIZE 0x02
+// 1-byte, undocumented TPI param
+#define XPRG_PARAM_TPI_3 0x03
+// 1-byte, undocumented TPI param
+#define XPRG_PARAM_TPI_4 0x04
+
+// *****************[ STK answer constants ]***************************
+
+#define ANSWER_CKSUM_ERROR 0xB0
+
+/*
+ * Private data for this programmer.
+ */
+struct pdata
+{
+ /*
+ * See stk500pp_read_byte() for an explanation of the flash and
+ * EEPROM page caches.
+ */
+ unsigned char *flash_pagecache;
+ unsigned long flash_pageaddr;
+ unsigned int flash_pagesize;
+
+ unsigned char *eeprom_pagecache;
+ unsigned long eeprom_pageaddr;
+ unsigned int eeprom_pagesize;
+
+ unsigned char command_sequence;
+
+ enum
+ {
+ PGMTYPE_UNKNOWN,
+ PGMTYPE_STK500,
+ PGMTYPE_AVRISP,
+ PGMTYPE_AVRISP_MKII,
+ PGMTYPE_JTAGICE_MKII,
+ PGMTYPE_STK600,
+ PGMTYPE_JTAGICE3
+ }
+ pgmtype;
+
+ AVRPART *lastpart;
+
+ /* Start address of Xmega boot area */
+ unsigned long boot_start;
+
+ /*
+ * Chained pdata for the JTAG ICE mkII backend. This is used when
+ * calling the backend functions for ISP/HVSP/PP programming
+ * functionality of the JTAG ICE mkII and AVR Dragon.
+ */
+ void *chained_pdata;
+};
+
diff --git a/xs/src/avrdude/term.c b/xs/src/avrdude/term.c
new file mode 100644
index 000000000..012f6f1a5
--- /dev/null
+++ b/xs/src/avrdude/term.c
@@ -0,0 +1,957 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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$ */
+
+#include "ac_cfg.h"
+
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#if defined(HAVE_LIBREADLINE)
+#if !defined(WIN32NATIVE)
+# include <readline/readline.h>
+# include <readline/history.h>
+#endif
+#endif
+
+#include "avrdude.h"
+#include "term.h"
+
+struct command {
+ char * name;
+ int (*func)(PROGRAMMER * pgm, struct avrpart * p, int argc, char *argv[]);
+ char * desc;
+};
+
+
+static int cmd_dump (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_write (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_erase (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_sig (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_part (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_help (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_quit (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_send (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_parms (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_vtarg (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_varef (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_fosc (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_sck (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_spi (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_pgm (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+static int cmd_verbose (PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char *argv[]);
+
+struct command cmd[] = {
+ { "dump", cmd_dump, "dump memory : %s <memtype> <addr> <N-Bytes>" },
+ { "read", cmd_dump, "alias for dump" },
+ { "write", cmd_write, "write memory : %s <memtype> <addr> <b1> <b2> ... <bN>" },
+ { "erase", cmd_erase, "perform a chip erase" },
+ { "sig", cmd_sig, "display device signature bytes" },
+ { "part", cmd_part, "display the current part information" },
+ { "send", cmd_send, "send a raw command : %s <b1> <b2> <b3> <b4>" },
+ { "parms", cmd_parms, "display adjustable parameters (STK500 only)" },
+ { "vtarg", cmd_vtarg, "set <V[target]> (STK500 only)" },
+ { "varef", cmd_varef, "set <V[aref]> (STK500 only)" },
+ { "fosc", cmd_fosc, "set <oscillator frequency> (STK500 only)" },
+ { "sck", cmd_sck, "set <SCK period> (STK500 only)" },
+ { "spi", cmd_spi, "enter direct SPI mode" },
+ { "pgm", cmd_pgm, "return to programming mode" },
+ { "verbose", cmd_verbose, "change verbosity" },
+ { "help", cmd_help, "help" },
+ { "?", cmd_help, "help" },
+ { "quit", cmd_quit, "quit" }
+};
+
+#define NCMDS (sizeof(cmd)/sizeof(struct command))
+
+
+
+static int spi_mode = 0;
+
+static int nexttok(char * buf, char ** tok, char ** next)
+{
+ char * q, * n;
+
+ q = buf;
+ while (isspace((int)*q))
+ q++;
+
+ /* isolate first token */
+ n = q+1;
+ while (*n && !isspace((int)*n))
+ n++;
+
+ if (*n) {
+ *n = 0;
+ n++;
+ }
+
+ /* find start of next token */
+ while (isspace((int)*n))
+ n++;
+
+ *tok = q;
+ *next = n;
+
+ return 0;
+}
+
+
+static int hexdump_line(char * buffer, unsigned char * p, int n, int pad)
+{
+ char * hexdata = "0123456789abcdef";
+ char * b;
+ int i, j;
+
+ b = buffer;
+
+ j = 0;
+ for (i=0; i<n; i++) {
+ if (i && ((i % 8) == 0))
+ b[j++] = ' ';
+ b[j++] = hexdata[(p[i] & 0xf0) >> 4];
+ b[j++] = hexdata[(p[i] & 0x0f)];
+ if (i < 15)
+ b[j++] = ' ';
+ }
+
+ for (i=j; i<pad; i++)
+ b[i] = ' ';
+
+ b[i] = 0;
+
+ for (i=0; i<pad; i++) {
+ if (!((b[i] == '0') || (b[i] == ' ')))
+ return 0;
+ }
+
+ return 1;
+}
+
+
+static int chardump_line(char * buffer, unsigned char * p, int n, int pad)
+{
+ int i;
+ char b [ 128 ];
+
+ for (i=0; i<n; i++) {
+ memcpy(b, p, n);
+ buffer[i] = '.';
+ if (isalpha((int)(b[i])) || isdigit((int)(b[i])) || ispunct((int)(b[i])))
+ buffer[i] = b[i];
+ else if (isspace((int)(b[i])))
+ buffer[i] = ' ';
+ }
+
+ for (i=n; i<pad; i++)
+ buffer[i] = ' ';
+
+ buffer[i] = 0;
+
+ return 0;
+}
+
+
+static int hexdump_buf(FILE * f, int startaddr, unsigned char * buf, int len)
+{
+ int addr;
+ int n;
+ unsigned char * p;
+ char dst1[80];
+ char dst2[80];
+
+ addr = startaddr;
+ p = (unsigned char *)buf;
+ while (len) {
+ n = 16;
+ if (n > len)
+ n = len;
+ hexdump_line(dst1, p, n, 48);
+ chardump_line(dst2, p, n, 16);
+ fprintf(stdout, "%04x %s |%s|\n", addr, dst1, dst2);
+ len -= n;
+ addr += n;
+ p += n;
+ }
+
+ return 0;
+}
+
+
+static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ static char prevmem[128] = {0};
+ char * e;
+ unsigned char * buf;
+ int maxsize;
+ unsigned long i;
+ static unsigned long addr=0;
+ static int len=64;
+ AVRMEM * mem;
+ char * memtype = NULL;
+ int rc;
+
+ if (!((argc == 2) || (argc == 4))) {
+ avrdude_message(MSG_INFO, "Usage: dump <memtype> [<addr> <len>]\n");
+ return -1;
+ }
+
+ memtype = argv[1];
+
+ if (strncmp(prevmem, memtype, strlen(memtype)) != 0) {
+ addr = 0;
+ len = 64;
+ strncpy(prevmem, memtype, sizeof(prevmem)-1);
+ prevmem[sizeof(prevmem)-1] = 0;
+ }
+
+ mem = avr_locate_mem(p, memtype);
+ if (mem == NULL) {
+ avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n",
+ memtype, p->desc);
+ return -1;
+ }
+
+ if (argc == 4) {
+ addr = strtoul(argv[2], &e, 0);
+ if (*e || (e == argv[2])) {
+ avrdude_message(MSG_INFO, "%s (dump): can't parse address \"%s\"\n",
+ progname, argv[2]);
+ return -1;
+ }
+
+ len = strtol(argv[3], &e, 0);
+ if (*e || (e == argv[3])) {
+ avrdude_message(MSG_INFO, "%s (dump): can't parse length \"%s\"\n",
+ progname, argv[3]);
+ return -1;
+ }
+ }
+
+ maxsize = mem->size;
+
+ if (addr >= maxsize) {
+ if (argc == 2) {
+ /* wrap around */
+ addr = 0;
+ }
+ else {
+ avrdude_message(MSG_INFO, "%s (dump): address 0x%05lx is out of range for %s memory\n",
+ progname, addr, mem->desc);
+ return -1;
+ }
+ }
+
+ /* trim len if nessary to not read past the end of memory */
+ if ((addr + len) > maxsize)
+ len = maxsize - addr;
+
+ buf = malloc(len);
+ if (buf == NULL) {
+ avrdude_message(MSG_INFO, "%s (dump): out of memory\n", progname);
+ return -1;
+ }
+
+ for (i=0; i<len; i++) {
+ rc = pgm->read_byte(pgm, p, mem, addr+i, &buf[i]);
+ if (rc != 0) {
+ avrdude_message(MSG_INFO, "error reading %s address 0x%05lx of part %s\n",
+ mem->desc, addr+i, p->desc);
+ if (rc == -1)
+ avrdude_message(MSG_INFO, "read operation not supported on memory type \"%s\"\n",
+ mem->desc);
+ return -1;
+ }
+ }
+
+ hexdump_buf(stdout, addr, buf, len);
+
+ fprintf(stdout, "\n");
+
+ free(buf);
+
+ addr = addr + len;
+
+ return 0;
+}
+
+
+static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ char * e;
+ int len, maxsize;
+ char * memtype;
+ unsigned long addr, i;
+ unsigned char * buf;
+ unsigned char b;
+ int rc;
+ int werror;
+ AVRMEM * mem;
+
+ if (argc < 4) {
+ avrdude_message(MSG_INFO, "Usage: write <memtype> <addr> <byte1> "
+ "<byte2> ... byteN>\n");
+ return -1;
+ }
+
+ memtype = argv[1];
+
+ mem = avr_locate_mem(p, memtype);
+ if (mem == NULL) {
+ avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n",
+ memtype, p->desc);
+ return -1;
+ }
+
+ maxsize = mem->size;
+
+ addr = strtoul(argv[2], &e, 0);
+ if (*e || (e == argv[2])) {
+ avrdude_message(MSG_INFO, "%s (write): can't parse address \"%s\"\n",
+ progname, argv[2]);
+ return -1;
+ }
+
+ if (addr > maxsize) {
+ avrdude_message(MSG_INFO, "%s (write): address 0x%05lx is out of range for %s memory\n",
+ progname, addr, memtype);
+ return -1;
+ }
+
+ /* number of bytes to write at the specified address */
+ len = argc - 3;
+
+ if ((addr + len) > maxsize) {
+ avrdude_message(MSG_INFO, "%s (write): selected address and # bytes exceed "
+ "range for %s memory\n",
+ progname, memtype);
+ return -1;
+ }
+
+ buf = malloc(len);
+ if (buf == NULL) {
+ avrdude_message(MSG_INFO, "%s (write): out of memory\n", progname);
+ return -1;
+ }
+
+ for (i=3; i<argc; i++) {
+ buf[i-3] = strtoul(argv[i], &e, 0);
+ if (*e || (e == argv[i])) {
+ avrdude_message(MSG_INFO, "%s (write): can't parse byte \"%s\"\n",
+ progname, argv[i]);
+ free(buf);
+ return -1;
+ }
+ }
+
+ pgm->err_led(pgm, OFF);
+ for (werror=0, i=0; i<len; i++) {
+
+ rc = avr_write_byte(pgm, p, mem, addr+i, buf[i]);
+ if (rc) {
+ avrdude_message(MSG_INFO, "%s (write): error writing 0x%02x at 0x%05lx, rc=%d\n",
+ progname, buf[i], addr+i, rc);
+ if (rc == -1)
+ avrdude_message(MSG_INFO, "write operation not supported on memory type \"%s\"\n",
+ mem->desc);
+ werror = 1;
+ }
+
+ rc = pgm->read_byte(pgm, p, mem, addr+i, &b);
+ if (b != buf[i]) {
+ avrdude_message(MSG_INFO, "%s (write): error writing 0x%02x at 0x%05lx cell=0x%02x\n",
+ progname, buf[i], addr+i, b);
+ werror = 1;
+ }
+
+ if (werror) {
+ pgm->err_led(pgm, ON);
+ }
+ }
+
+ free(buf);
+
+ fprintf(stdout, "\n");
+
+ return 0;
+}
+
+
+static int cmd_send(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ unsigned char cmd[4], res[4];
+ char * e;
+ int i;
+ int len;
+
+ if (pgm->cmd == NULL) {
+ avrdude_message(MSG_INFO, "The %s programmer does not support direct ISP commands.\n",
+ pgm->type);
+ return -1;
+ }
+
+ if (spi_mode && (pgm->spi == NULL)) {
+ avrdude_message(MSG_INFO, "The %s programmer does not support direct SPI transfers.\n",
+ pgm->type);
+ return -1;
+ }
+
+
+ if ((argc > 5) || ((argc < 5) && (!spi_mode))) {
+ avrdude_message(MSG_INFO, spi_mode?
+ "Usage: send <byte1> [<byte2> [<byte3> [<byte4>]]]\n":
+ "Usage: send <byte1> <byte2> <byte3> <byte4>\n");
+ return -1;
+ }
+
+ /* number of bytes to write at the specified address */
+ len = argc - 1;
+
+ /* load command bytes */
+ for (i=1; i<argc; i++) {
+ cmd[i-1] = strtoul(argv[i], &e, 0);
+ if (*e || (e == argv[i])) {
+ avrdude_message(MSG_INFO, "%s (send): can't parse byte \"%s\"\n",
+ progname, argv[i]);
+ return -1;
+ }
+ }
+
+ pgm->err_led(pgm, OFF);
+
+ if (spi_mode)
+ pgm->spi(pgm, cmd, res, argc-1);
+ else
+ pgm->cmd(pgm, cmd, res);
+
+ /*
+ * display results
+ */
+ avrdude_message(MSG_INFO, "results:");
+ for (i=0; i<len; i++)
+ avrdude_message(MSG_INFO, " %02x", res[i]);
+ avrdude_message(MSG_INFO, "\n");
+
+ fprintf(stdout, "\n");
+
+ return 0;
+}
+
+
+static int cmd_erase(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ avrdude_message(MSG_INFO, "%s: erasing chip\n", progname);
+ pgm->chip_erase(pgm, p);
+ return 0;
+}
+
+
+static int cmd_part(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ fprintf(stdout, "\n");
+ avr_display(stdout, p, "", 0);
+ fprintf(stdout, "\n");
+
+ return 0;
+}
+
+
+static int cmd_sig(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ int i;
+ int rc;
+ AVRMEM * m;
+
+ rc = avr_signature(pgm, p);
+ if (rc != 0) {
+ avrdude_message(MSG_INFO, "error reading signature data, rc=%d\n",
+ rc);
+ }
+
+ m = avr_locate_mem(p, "signature");
+ if (m == NULL) {
+ avrdude_message(MSG_INFO, "signature data not defined for device \"%s\"\n",
+ p->desc);
+ }
+ else {
+ fprintf(stdout, "Device signature = 0x");
+ for (i=0; i<m->size; i++)
+ fprintf(stdout, "%02x", m->buf[i]);
+ fprintf(stdout, "\n\n");
+ }
+
+ return 0;
+}
+
+
+static int cmd_quit(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ return 1;
+}
+
+
+static int cmd_parms(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ if (pgm->print_parms == NULL) {
+ avrdude_message(MSG_INFO, "%s (parms): the %s programmer does not support "
+ "adjustable parameters\n",
+ progname, pgm->type);
+ return -1;
+ }
+ pgm->print_parms(pgm);
+
+ return 0;
+}
+
+
+static int cmd_vtarg(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ int rc;
+ double v;
+ char *endp;
+
+ if (argc != 2) {
+ avrdude_message(MSG_INFO, "Usage: vtarg <value>\n");
+ return -1;
+ }
+ v = strtod(argv[1], &endp);
+ if (endp == argv[1]) {
+ avrdude_message(MSG_INFO, "%s (vtarg): can't parse voltage \"%s\"\n",
+ progname, argv[1]);
+ return -1;
+ }
+ if (pgm->set_vtarget == NULL) {
+ avrdude_message(MSG_INFO, "%s (vtarg): the %s programmer cannot set V[target]\n",
+ progname, pgm->type);
+ return -2;
+ }
+ if ((rc = pgm->set_vtarget(pgm, v)) != 0) {
+ avrdude_message(MSG_INFO, "%s (vtarg): failed to set V[target] (rc = %d)\n",
+ progname, rc);
+ return -3;
+ }
+ return 0;
+}
+
+
+static int cmd_fosc(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ int rc;
+ double v;
+ char *endp;
+
+ if (argc != 2) {
+ avrdude_message(MSG_INFO, "Usage: fosc <value>[M|k] | off\n");
+ return -1;
+ }
+ v = strtod(argv[1], &endp);
+ if (endp == argv[1]) {
+ if (strcmp(argv[1], "off") == 0)
+ v = 0.0;
+ else {
+ avrdude_message(MSG_INFO, "%s (fosc): can't parse frequency \"%s\"\n",
+ progname, argv[1]);
+ return -1;
+ }
+ }
+ if (*endp == 'm' || *endp == 'M')
+ v *= 1e6;
+ else if (*endp == 'k' || *endp == 'K')
+ v *= 1e3;
+ if (pgm->set_fosc == NULL) {
+ avrdude_message(MSG_INFO, "%s (fosc): the %s programmer cannot set oscillator frequency\n",
+ progname, pgm->type);
+ return -2;
+ }
+ if ((rc = pgm->set_fosc(pgm, v)) != 0) {
+ avrdude_message(MSG_INFO, "%s (fosc): failed to set oscillator_frequency (rc = %d)\n",
+ progname, rc);
+ return -3;
+ }
+ return 0;
+}
+
+
+static int cmd_sck(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ int rc;
+ double v;
+ char *endp;
+
+ if (argc != 2) {
+ avrdude_message(MSG_INFO, "Usage: sck <value>\n");
+ return -1;
+ }
+ v = strtod(argv[1], &endp);
+ if (endp == argv[1]) {
+ avrdude_message(MSG_INFO, "%s (sck): can't parse period \"%s\"\n",
+ progname, argv[1]);
+ return -1;
+ }
+ v *= 1e-6; /* Convert from microseconds to seconds. */
+ if (pgm->set_sck_period == NULL) {
+ avrdude_message(MSG_INFO, "%s (sck): the %s programmer cannot set SCK period\n",
+ progname, pgm->type);
+ return -2;
+ }
+ if ((rc = pgm->set_sck_period(pgm, v)) != 0) {
+ avrdude_message(MSG_INFO, "%s (sck): failed to set SCK period (rc = %d)\n",
+ progname, rc);
+ return -3;
+ }
+ return 0;
+}
+
+
+static int cmd_varef(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ int rc;
+ unsigned int chan;
+ double v;
+ char *endp;
+
+ if (argc != 2 && argc != 3) {
+ avrdude_message(MSG_INFO, "Usage: varef [channel] <value>\n");
+ return -1;
+ }
+ if (argc == 2) {
+ chan = 0;
+ v = strtod(argv[1], &endp);
+ if (endp == argv[1]) {
+ avrdude_message(MSG_INFO, "%s (varef): can't parse voltage \"%s\"\n",
+ progname, argv[1]);
+ return -1;
+ }
+ } else {
+ chan = strtoul(argv[1], &endp, 10);
+ if (endp == argv[1]) {
+ avrdude_message(MSG_INFO, "%s (varef): can't parse channel \"%s\"\n",
+ progname, argv[1]);
+ return -1;
+ }
+ v = strtod(argv[2], &endp);
+ if (endp == argv[2]) {
+ avrdude_message(MSG_INFO, "%s (varef): can't parse voltage \"%s\"\n",
+ progname, argv[2]);
+ return -1;
+ }
+ }
+ if (pgm->set_varef == NULL) {
+ avrdude_message(MSG_INFO, "%s (varef): the %s programmer cannot set V[aref]\n",
+ progname, pgm->type);
+ return -2;
+ }
+ if ((rc = pgm->set_varef(pgm, chan, v)) != 0) {
+ avrdude_message(MSG_INFO, "%s (varef): failed to set V[aref] (rc = %d)\n",
+ progname, rc);
+ return -3;
+ }
+ return 0;
+}
+
+
+static int cmd_help(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ int i;
+
+ fprintf(stdout, "Valid commands:\n\n");
+ for (i=0; i<NCMDS; i++) {
+ fprintf(stdout, " %-6s : ", cmd[i].name);
+ fprintf(stdout, cmd[i].desc, cmd[i].name);
+ fprintf(stdout, "\n");
+ }
+ fprintf(stdout,
+ "\nUse the 'part' command to display valid memory types for use with the\n"
+ "'dump' and 'write' commands.\n\n");
+
+ return 0;
+}
+
+static int cmd_spi(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ pgm->setpin(pgm, PIN_AVR_RESET, 1);
+ spi_mode = 1;
+ return 0;
+}
+
+static int cmd_pgm(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ pgm->setpin(pgm, PIN_AVR_RESET, 0);
+ spi_mode = 0;
+ pgm->initialize(pgm, p);
+ return 0;
+}
+
+static int cmd_verbose(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ int nverb;
+ char *endp;
+
+ if (argc != 1 && argc != 2) {
+ avrdude_message(MSG_INFO, "Usage: verbose [<value>]\n");
+ return -1;
+ }
+ if (argc == 1) {
+ avrdude_message(MSG_INFO, "Verbosity level: %d\n", verbose);
+ return 0;
+ }
+ nverb = strtol(argv[1], &endp, 0);
+ if (endp == argv[2]) {
+ avrdude_message(MSG_INFO, "%s: can't parse verbosity level \"%s\"\n",
+ progname, argv[2]);
+ return -1;
+ }
+ if (nverb < 0) {
+ avrdude_message(MSG_INFO, "%s: verbosity level must be positive: %d\n",
+ progname, nverb);
+ return -1;
+ }
+ verbose = nverb;
+ avrdude_message(MSG_INFO, "New verbosity level: %d\n", verbose);
+
+ return 0;
+}
+
+static int tokenize(char * s, char *** argv)
+{
+ int i, n, l, nargs, offset;
+ int len, slen;
+ char * buf;
+ int bufsize;
+ char ** bufv;
+ char * q, * r;
+ char * nbuf;
+ char ** av;
+
+ slen = strlen(s);
+
+ /*
+ * initialize allow for 20 arguments, use realloc to grow this if
+ * necessary
+ */
+ nargs = 20;
+ bufsize = slen + 20;
+ buf = malloc(bufsize);
+ bufv = (char **) malloc(nargs*sizeof(char *));
+ for (i=0; i<nargs; i++) {
+ bufv[i] = NULL;
+ }
+ buf[0] = 0;
+
+ n = 0;
+ l = 0;
+ nbuf = buf;
+ r = s;
+ while (*r) {
+ nexttok(r, &q, &r);
+ strcpy(nbuf, q);
+ bufv[n] = nbuf;
+ len = strlen(q);
+ l += len + 1;
+ nbuf += len + 1;
+ nbuf[0] = 0;
+ n++;
+ if ((n % 20) == 0) {
+ /* realloc space for another 20 args */
+ bufsize += 20;
+ nargs += 20;
+ buf = realloc(buf, bufsize);
+ bufv = realloc(bufv, nargs*sizeof(char *));
+ nbuf = &buf[l];
+ for (i=n; i<nargs; i++)
+ bufv[i] = NULL;
+ }
+ }
+
+ /*
+ * We have parsed all the args, n == argc, bufv contains an array of
+ * pointers to each arg, and buf points to one memory block that
+ * contains all the args, back to back, seperated by a nul
+ * terminator. Consilidate bufv and buf into one big memory block
+ * so that the code that calls us, will have an easy job of freeing
+ * this memory.
+ */
+ av = (char **) malloc(slen + n + (n+1)*sizeof(char *));
+ q = (char *)&av[n+1];
+ memcpy(q, buf, l);
+ for (i=0; i<n; i++) {
+ offset = bufv[i] - buf;
+ av[i] = q + offset;
+ }
+ av[i] = NULL;
+
+ free(buf);
+ free(bufv);
+
+ *argv = av;
+
+ return n;
+}
+
+
+static int do_cmd(PROGRAMMER * pgm, struct avrpart * p,
+ int argc, char * argv[])
+{
+ int i;
+ int hold;
+ int len;
+
+ len = strlen(argv[0]);
+ hold = -1;
+ for (i=0; i<NCMDS; i++) {
+ if (strcasecmp(argv[0], cmd[i].name) == 0) {
+ return cmd[i].func(pgm, p, argc, argv);
+ }
+ else if (strncasecmp(argv[0], cmd[i].name, len)==0) {
+ if (hold != -1) {
+ avrdude_message(MSG_INFO, "%s: command \"%s\" is ambiguous\n",
+ progname, argv[0]);
+ return -1;
+ }
+ hold = i;
+ }
+ }
+
+ if (hold != -1)
+ return cmd[hold].func(pgm, p, argc, argv);
+
+ avrdude_message(MSG_INFO, "%s: invalid command \"%s\"\n",
+ progname, argv[0]);
+
+ return -1;
+}
+
+
+char * terminal_get_input(const char *prompt)
+{
+#if defined(HAVE_LIBREADLINE) && !defined(WIN32NATIVE)
+ char *input;
+ input = readline(prompt);
+ if ((input != NULL) && (strlen(input) >= 1))
+ add_history(input);
+
+ return input;
+#else
+ char input[256];
+ printf("%s", prompt);
+ if (fgets(input, sizeof(input), stdin))
+ {
+ /* FIXME: readline strips the '\n', should this too? */
+ return strdup(input);
+ }
+ else
+ return NULL;
+#endif
+}
+
+
+int terminal_mode(PROGRAMMER * pgm, struct avrpart * p)
+{
+ char * cmdbuf;
+ int i;
+ char * q;
+ int rc;
+ int argc;
+ char ** argv;
+
+ rc = 0;
+ while ((cmdbuf = terminal_get_input("avrdude> ")) != NULL) {
+ /*
+ * find the start of the command, skipping any white space
+ */
+ q = cmdbuf;
+ while (*q && isspace((int)*q))
+ q++;
+
+ /* skip blank lines and comments */
+ if (!*q || (*q == '#'))
+ continue;
+
+ /* tokenize command line */
+ argc = tokenize(q, &argv);
+
+ fprintf(stdout, ">>> ");
+ for (i=0; i<argc; i++)
+ fprintf(stdout, "%s ", argv[i]);
+ fprintf(stdout, "\n");
+
+ /* run the command */
+ rc = do_cmd(pgm, p, argc, argv);
+ free(argv);
+ if (rc > 0) {
+ rc = 0;
+ break;
+ }
+ free(cmdbuf);
+ }
+
+ return rc;
+}
+
+
diff --git a/xs/src/avrdude/term.h b/xs/src/avrdude/term.h
new file mode 100644
index 000000000..fca3aac84
--- /dev/null
+++ b/xs/src/avrdude/term.h
@@ -0,0 +1,37 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2004 Brian S. Dean <bsd@bsdhome.com>
+ *
+ * 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 term_h
+#define term_h
+
+#include "libavrdude.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int terminal_mode(PROGRAMMER * pgm, struct avrpart * p);
+char * terminal_get_input(const char *prompt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/xs/src/avrdude/tools/build-mingw32.sh b/xs/src/avrdude/tools/build-mingw32.sh
new file mode 100755
index 000000000..2d9e11261
--- /dev/null
+++ b/xs/src/avrdude/tools/build-mingw32.sh
@@ -0,0 +1,54 @@
+#! /bin/sh
+
+# ----------------------------------------------------------------------------
+# "THE BEER-WARE LICENSE" (Revision 42):
+# Joerg Wunsch wrote this file. As long as you retain this notice you
+# can do whatever you want with this stuff. If we meet some day, and you think
+# this stuff is worth it, you can buy me a beer in return.
+# ----------------------------------------------------------------------------
+
+# Script to cross-compile a MinGW32 executable under unixish host.
+# Run this script from within the tools/ subdirectory.
+# Override MINGW32_PREFIX and LIBUSB_PREFIX from the commandline
+# when invoking the script, like
+#
+# env LIBUSB_PREFIX="$HOME/dos/ProgramFiles/LibUSB-Win32" ./build-mingw32.sh
+#
+# The LibUSB-Win32 package is shipped as a self-installing
+# executable; it can be unpacked using Wine, and typically
+# extracts into the Wine environment.
+#
+# libelf can be cross-compiled, and installed into the MinGW32
+# target environment if desired.
+
+MINGW32_PREFIX=${MINGW32_PREFIX:-/usr/local/mingw32}
+LIBUSB_PREFIX=${LIBUSB_PREFIX:-/WINDOWS/ProgramFiles/LibUSB-Win32}
+
+for CC in mingw32-gcc i686-w64-mingw32-gcc i586-mingw32msvc-gcc
+do
+ touch foo.c
+ if ${CC} -c foo.c 2> /dev/null
+ then
+ rm -f foo.*
+ break
+ fi
+done
+tgt=$(expr "$CC" : "\(.*\)-gcc")
+
+BUILDDIR=build-mingw32
+mkdir -p ${BUILDDIR} || { echo "Cannot create build dir $BUILDDIR"; exit 1; }
+
+cd ${BUILDDIR} || { echo "Cannot chdir to $BUILDDIR"; exit 1; }
+
+LDFLAGS="-L${MINGW32_PREFIX}/lib -L${LIBUSB_PREFIX}/lib/gcc"
+CPPFLAGS="-I${MINGW32_PREFIX}/include -I${LIBUSB_PREFIX}/include"
+
+env \
+ CC="${CC}" \
+ CPPFLAGS="${CPPFLAGS}" \
+ LDFLAGS="${LDFLAGS}" \
+ ../../configure \
+ --host=$(../../config.guess) \
+ --target=${tgt}
+
+make all
diff --git a/xs/src/avrdude/tools/get-dw-params.xsl b/xs/src/avrdude/tools/get-dw-params.xsl
new file mode 100644
index 000000000..a3f083e96
--- /dev/null
+++ b/xs/src/avrdude/tools/get-dw-params.xsl
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding='ISO-8859-1' ?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<!--
+ * Copyright (c) 2006 Joerg Wunsch
+ *
+ * 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$
+-->
+<!--
+ * Extract the debugWire parameters
+ * from the XML, and format it the way src/devdescr.cc needs it.
+ *
+ * Run this file together with the respective AVR's XML file through
+ * an XSLT processor (xsltproc, saxon), and capture the output for
+ * inclusion into avrdude.conf.in.
+-->
+ <xsl:output method="text"/>
+ <xsl:template match="/">
+ <!-- Extract everything we need out of the XML. -->
+ <xsl:variable name="devname_orig"
+ select="/AVRPART/ADMIN/PART_NAME" />
+ <xsl:variable name="devname"
+ select="translate(/AVRPART/ADMIN/PART_NAME,
+ 'abcdefghijklmnopqrstuvwxyz',
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
+ <xsl:variable name="devname_lower"
+ select="translate(/AVRPART/ADMIN/PART_NAME,
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ 'abcdefghijklmnopqrstuvwxyz')" />
+ <xsl:variable name="ucEepromInst"
+ select="//AVRPART/ICE_SETTINGS/JTAGICEmkII/ucEepromInst" />
+ <xsl:variable name="ucFlashInst"
+ select="//AVRPART/ICE_SETTINGS/JTAGICEmkII/ucFlashInst" />
+
+ <!-- If there's a JTAGICEmkII node indicating debugWire, emit the entry. -->
+ <xsl:if test='//AVRPART/ICE_SETTINGS/JTAGICEmkII/Interface="DebugWire"'>
+
+ <!-- start of new entry -->
+ <xsl:text>#------------------------------------------------------------&#010;</xsl:text>
+ <xsl:text># </xsl:text>
+ <xsl:value-of select="$devname_orig" />
+ <xsl:text>&#010;</xsl:text>
+ <xsl:text>#------------------------------------------------------------&#010;</xsl:text>
+ <xsl:text>part&#010; desc = &quot;</xsl:text>
+ <xsl:value-of select="$devname_orig" />
+ <xsl:text>&quot;;&#010; has_debugwire = yes;&#010;</xsl:text>
+
+ <xsl:text> flash_instr = </xsl:text>
+ <xsl:call-template name="format-hex">
+ <xsl:with-param name="arg" select="$ucFlashInst" />
+ <xsl:with-param name="count" select="0" />
+ </xsl:call-template>
+ <xsl:text>;&#010;</xsl:text>
+
+ <xsl:text> eeprom_instr = </xsl:text>
+ <xsl:call-template name="format-hex">
+ <xsl:with-param name="arg" select="$ucEepromInst" />
+ <xsl:with-param name="count" select="0" />
+ </xsl:call-template>
+ <xsl:text>;&#010;</xsl:text>
+
+ </xsl:if> <!-- JTAGICEmkII uses debugWire -->
+
+ </xsl:template>
+
+ <xsl:template name="toupper">
+ </xsl:template>
+
+ <!-- return argument $arg if non-empty, 0 otherwise -->
+ <xsl:template name="maybezero">
+ <xsl:param name="arg" />
+ <xsl:choose>
+ <xsl:when test="string-length($arg) = 0"><xsl:text>0</xsl:text></xsl:when>
+ <xsl:otherwise><xsl:value-of select="$arg" /></xsl:otherwise>
+ </xsl:choose>
+ </xsl:template> <!-- maybezero -->
+
+ <!-- convert $XX hex number in $arg (if any) into 0xXX; -->
+ <!-- return 0 if $arg is empty -->
+ <xsl:template name="dollar-to-0x">
+ <xsl:param name="arg" />
+ <xsl:choose>
+ <xsl:when test="string-length($arg) = 0">
+ <xsl:text>0</xsl:text>
+ </xsl:when>
+ <xsl:when test="substring($arg, 1, 1) = '&#036;'">
+ <xsl:text>0x</xsl:text>
+ <xsl:value-of select="substring($arg, 2)" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$arg" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template> <!-- dollar-to-0x -->
+
+ <!-- Format a string of 0xXX numbers: start a new line -->
+ <!-- after each 8 hex numbers -->
+ <!-- call with parameter $count = 0, calls itself -->
+ <!-- recursively then until everything has been done -->
+ <xsl:template name="format-hex">
+ <xsl:param name="arg" />
+ <xsl:param name="count" />
+ <xsl:choose>
+ <xsl:when test="string-length($arg) &lt;= 4">
+ <!-- Last element, print it, and leave template. -->
+ <xsl:value-of select="$arg" />
+ </xsl:when>
+ <xsl:otherwise>
+ <!--
+ * More arguments follow, print first value,
+ * followed by a comma, decide whether a space
+ * or a newline needs to be emitted, and recurse
+ * with the remaining part of $arg.
+ -->
+ <xsl:value-of select="substring($arg, 1, 4)" />
+ <xsl:choose>
+ <xsl:when test="$count mod 8 = 7">
+ <xsl:text>,&#010;&#009; </xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>, </xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:variable name="newarg">
+ <!-- see whether there is a space after comma -->
+ <xsl:choose>
+ <xsl:when test="substring($arg, 6, 1) = ' '">
+ <xsl:value-of select="substring($arg, 7)" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring($arg, 6)" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:call-template name="format-hex">
+ <xsl:with-param name="arg" select="$newarg" />
+ <xsl:with-param name="count" select="$count + 1" />
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/xs/src/avrdude/tools/get-hv-params.xsl b/xs/src/avrdude/tools/get-hv-params.xsl
new file mode 100644
index 000000000..b4a595f13
--- /dev/null
+++ b/xs/src/avrdude/tools/get-hv-params.xsl
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding='ISO-8859-1' ?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<!--
+ * Copyright (c) 2006 Joerg Wunsch
+ *
+ * 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$
+-->
+<!--
+ * Extract high-voltage (parallel and serial) programming parameters
+ * out of the Atmel XML files, and convert them into avrdude.conf
+ * snippets.
+ *
+ * Run this file together with the respective AVR's XML file through
+ * an XSLT processor (xsltproc, saxon), and capture the output for
+ * inclusion into avrdude.conf.in.
+-->
+ <xsl:output method="text"/>
+ <xsl:template match="/">
+ <xsl:for-each select="//*">
+ <xsl:if test='name() = "STK500_2"'>
+
+ <!--
+ * High-voltage parallel programming parameters.
+ -->
+ <xsl:for-each
+ select="*[starts-with(translate(name(),
+ 'abcdefghijklmnopqrstuvwxyz',
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
+ 'PP')]">
+ <xsl:if test="self::node()[name() = 'PPControlStack']"
+ > pp_controlstack =
+ <xsl:call-template name="format_cstack">
+ <xsl:with-param name="stack" select="." />
+ <xsl:with-param name="count" select="0" />
+ </xsl:call-template>;
+</xsl:if> <!-- PPControlStack -->
+
+ <xsl:if test="self::node()[name() = 'PpEnterProgMode']">
+ <xsl:for-each select="*">
+ <xsl:if test="self::node()[name() = 'stabDelay']"
+ > hventerstabdelay = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'progModeDelay']"
+ > progmodedelay = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'latchCycles']"
+ > latchcycles = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'toggleVtg']"
+ > togglevtg = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'powerOffDelay']"
+ > poweroffdelay = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'resetDelayMs']"
+ > resetdelayms = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'resetDelayUs']"
+ > resetdelayus = <xsl:value-of select="." />;
+</xsl:if>
+ </xsl:for-each>
+ </xsl:if> <!-- PpEnterProgMode -->
+
+ <xsl:if test="self::node()[name() = 'PpLeaveProgMode']">
+ <xsl:for-each select="*">
+ <xsl:if test="self::node()[name() = 'stabDelay']"
+ > hvleavestabdelay = <xsl:value-of select="." />;
+</xsl:if>
+ </xsl:for-each>
+ </xsl:if> <!-- PpLeaveProgMode -->
+
+ <xsl:if test="self::node()[name() = 'PpChipErase']">
+ <xsl:for-each select="*">
+ <xsl:if test="self::node()[name() = 'pulseWidth']"
+ > chiperasepulsewidth = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'pollTimeout']"
+ > chiperasepolltimeout = <xsl:value-of select="." />;
+</xsl:if>
+ </xsl:for-each>
+ </xsl:if> <!-- PpChipErase -->
+
+ <xsl:if test="self::node()[name() = 'PpProgramFuse']">
+ <xsl:for-each select="*">
+ <xsl:if test="self::node()[name() = 'pulseWidth']"
+ > programfusepulsewidth = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'pollTimeout']"
+ > programfusepolltimeout = <xsl:value-of select="." />;
+</xsl:if>
+ </xsl:for-each>
+ </xsl:if> <!-- PpProgramFuse -->
+
+ <xsl:if test="self::node()[name() = 'PpProgramLock']">
+ <xsl:for-each select="*">
+ <xsl:if test="self::node()[name() = 'pulseWidth']"
+ > programlockpulsewidth = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'pollTimeout']"
+ > programlockpolltimeout = <xsl:value-of select="." />;
+</xsl:if>
+ </xsl:for-each>
+ </xsl:if> <!-- PpProgramLock -->
+
+ </xsl:for-each> <!-- PP parameters -->
+
+ <!--
+ * High-voltage serial programming parameters.
+ -->
+ <xsl:for-each
+ select="*[starts-with(translate(name(),
+ 'abcdefghijklmnopqrstuvwxyz',
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
+ 'HVSP')]">
+
+ <xsl:if test="self::node()[name() = 'HvspControlStack']"
+ > hvsp_controlstack =
+ <xsl:call-template name="format_cstack">
+ <xsl:with-param name="stack" select="." />
+ <xsl:with-param name="count" select="0" />
+ </xsl:call-template>;
+</xsl:if> <!-- HvspControlStack -->
+
+ <xsl:if test="self::node()[name() = 'HvspEnterProgMode']">
+ <xsl:for-each select="*">
+ <xsl:if test="self::node()[name() = 'stabDelay']"
+ > hventerstabdelay = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'cmdexeDelay']"
+ > hvspcmdexedelay = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'synchCycles']"
+ > synchcycles = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'latchCycles']"
+ > latchcycles = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'toggleVtg']"
+ > togglevtg = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'powoffDelay']"
+ > poweroffdelay = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'resetDelay1']"
+ > resetdelayms = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'resetDelay2']"
+ > resetdelayus = <xsl:value-of select="." />;
+</xsl:if>
+ </xsl:for-each>
+ </xsl:if> <!-- HvspEnterProgMode -->
+
+ <xsl:if test="self::node()[name() = 'HvspLeaveProgMode']">
+ <xsl:for-each select="*">
+ <xsl:if test="self::node()[name() = 'stabDelay']"
+ > hvleavestabdelay = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'resetDelay']"
+ > resetdelay = <xsl:value-of select="." />;
+</xsl:if>
+ </xsl:for-each>
+ </xsl:if> <!-- HvspLeaveProgMode -->
+
+ <xsl:if test="self::node()[name() = 'HvspChipErase']">
+ <xsl:for-each select="*">
+ <xsl:if test="self::node()[name() = 'pollTimeout']"
+ > chiperasepolltimeout = <xsl:value-of select="." />;
+</xsl:if>
+ <xsl:if test="self::node()[name() = 'eraseTime']"
+ > chiperasetime = <xsl:value-of select="." />;
+</xsl:if>
+ </xsl:for-each>
+ </xsl:if> <!-- HvspChipErase -->
+
+ <xsl:if test="self::node()[name() = 'HvspProgramFuse']">
+ <xsl:for-each select="*">
+ <xsl:if test="self::node()[name() = 'pollTimeout']"
+ > programfusepolltimeout = <xsl:value-of select="." />;
+</xsl:if>
+ </xsl:for-each>
+ </xsl:if> <!-- HvspProgramFuse -->
+
+ <xsl:if test="self::node()[name() = 'HvspProgramLock']">
+ <xsl:for-each select="*">
+ <xsl:if test="self::node()[name() = 'pollTimeout']"
+ > programlockpolltimeout = <xsl:value-of select="." />;
+</xsl:if>
+ </xsl:for-each>
+ </xsl:if> <!-- HvspProgramLock -->
+
+ </xsl:for-each> <!-- HVSP parameters -->
+
+ </xsl:if> <!-- STK500_2 parameters -->
+ </xsl:for-each> <!-- All nodes -->
+
+ </xsl:template>
+
+ <!--
+ * Format the control stack argument: replace space-separated
+ * list by a list separated with commas, followed by either
+ * a space or a newline, dependend on the current argument
+ * count.
+ * This template calls itself recursively, until the entire
+ * argument $stack has been processed.
+ -->
+ <xsl:template name="format_cstack">
+ <xsl:param name="stack" />
+ <xsl:param name="count" />
+ <xsl:choose>
+ <xsl:when test="string-length($stack) &lt;= 4">
+ <!-- Last element, print it, and leave template. -->
+ <xsl:value-of select="$stack" />
+ </xsl:when>
+ <xsl:otherwise>
+ <!--
+ * More arguments follow, print first value,
+ * followed by a comma, decide whether a space
+ * or a newline needs to be emitted, and recurse
+ * with the remaining part of $stack.
+ -->
+ <xsl:value-of select="substring($stack, 1, 4)" />
+ <xsl:choose>
+ <xsl:when test="$count mod 8 = 7">
+ <!-- comma, newline, 8 spaces indentation -->
+ <xsl:text>,
+ </xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- comma, space -->
+ <xsl:text>, </xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:call-template name="format_cstack">
+ <xsl:with-param name="stack" select="substring($stack, 6)"
+ />
+ <xsl:with-param name="count" select="$count + 1" />
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/xs/src/avrdude/tools/get-stk600-cards.xsl b/xs/src/avrdude/tools/get-stk600-cards.xsl
new file mode 100644
index 000000000..6165b526e
--- /dev/null
+++ b/xs/src/avrdude/tools/get-stk600-cards.xsl
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding='ISO-8859-1' ?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<!--
+ * Copyright (c) 2008 Joerg Wunsch
+ *
+ * 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$
+-->
+<!--
+ * Extract STK600 routing and socket card information out of
+ * targetboards.xml.
+ *
+ * Run this like:
+ *
+ * xsltproc -param what "'RC'" \
+ * tools/get-stk600-cards.xsl targetboard.xml | sort -u
+ *
+ * xsltproc -param what "'SC'" \
+ * tools/get-stk600-cards.xsl targetboard.xml | sort -u
+ *
+ * and copy&paste the results into the respective tables.
+-->
+<xsl:output method="text"/>
+<xsl:template match="/">
+ <xsl:if test="$what = 'RC'">
+ <xsl:for-each select="/STK600/ROUTING/CARD">
+ <xsl:if test="RC_NAME != ''">
+ <xsl:text> { </xsl:text>
+ <xsl:value-of select="RC_ID" />
+ <xsl:text>, &#034;</xsl:text>
+ <xsl:value-of select="RC_NAME" />
+ <xsl:text>&#034; },&#010;</xsl:text>
+ </xsl:if>
+ </xsl:for-each> <!-- All cards -->
+ </xsl:if> <!-- Routing cards -->
+
+ <xsl:if test="$what = 'SC'">
+ <xsl:for-each select="/STK600/ROUTING/CARD">
+ <xsl:if test="SC_NAME != ''">
+ <xsl:text> { </xsl:text>
+ <xsl:value-of select="SC_ID" />
+ <xsl:text>, &#034;</xsl:text>
+ <xsl:value-of select="SC_NAME" />
+ <xsl:text>&#034; },&#010;</xsl:text>
+ </xsl:if>
+ </xsl:for-each> <!-- All cards -->
+ </xsl:if> <!-- Socket cards -->
+
+</xsl:template>
+</xsl:stylesheet>
diff --git a/xs/src/avrdude/tools/get-stk600-devices.xsl b/xs/src/avrdude/tools/get-stk600-devices.xsl
new file mode 100644
index 000000000..efba1628a
--- /dev/null
+++ b/xs/src/avrdude/tools/get-stk600-devices.xsl
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding='ISO-8859-1' ?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<!--
+ * Copyright (c) 2008 Joerg Wunsch
+ *
+ * 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$
+-->
+<!--
+ * Extract STK600 device support out of
+ * targetboards.xml.
+ *
+ * Run this like:
+ *
+ * xsltproc \
+ * tools/get-stk600-devices.xsl targetboard.xml
+ *
+ * and copy&paste the results into the respective table.
+-->
+<xsl:output method="text"/>
+<xsl:template match="/">
+ <xsl:text>@multitable @columnfractions .15 .15 .6&#010;</xsl:text>
+ <xsl:text>Routing card @tab Socket card @tab Devices&#010;</xsl:text>
+ <xsl:for-each select="/STK600/ROUTING/CARD">
+ <xsl:text>@item @code{</xsl:text>
+ <xsl:value-of select="RC_NAME" />
+ <xsl:text>} @tab @code{</xsl:text>
+ <xsl:value-of select="SC_NAME" />
+ <xsl:text>} @tab</xsl:text>
+ <xsl:for-each select="TARGET">
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="NAME" />
+ </xsl:for-each>
+ <xsl:text>&#010;</xsl:text>
+ </xsl:for-each> <!-- All cards -->
+ <xsl:text>@end multitable&#010;</xsl:text>
+
+</xsl:template>
+</xsl:stylesheet>
diff --git a/xs/src/avrdude/tpi.h b/xs/src/avrdude/tpi.h
new file mode 100644
index 000000000..89d438d8b
--- /dev/null
+++ b/xs/src/avrdude/tpi.h
@@ -0,0 +1,76 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2011 Darell Tan <darell.tan@gmail.com>
+ *
+ * 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 tpi_h
+#define tpi_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static const unsigned char tpi_skey[] = { 0x12, 0x89, 0xAB, 0x45, 0xCD, 0xD8, 0x88, 0xFF };
+
+/* registers */
+#define TPI_REG_TPIIR 0x0F
+
+#define TPI_IDENT_CODE 0x80
+
+#define TPI_REG_TPIPCR 0x02
+#define TPI_REG_TPISR 0x00
+
+#define TPI_REG_TPISR_NVMEN (1 << 1)
+
+/* TPI commands */
+#define TPI_CMD_SLD 0x20
+#define TPI_CMD_SLD_PI 0x24
+#define TPI_CMD_SIN 0x10
+#define TPI_CMD_SOUT 0x90
+#define TPI_CMD_SSTCS 0xC0
+#define TPI_CMD_SST 0x60
+#define TPI_CMD_SST_PI 0x64
+
+#define TPI_CMD_SLDCS 0x80
+#define TPI_CMD_SSTPR 0x68
+#define TPI_CMD_SKEY 0xE0
+
+/* for TPI_CMD_SIN & TPI_CMD_SOUT */
+#define TPI_SIO_ADDR(x) ((x & 0x30) << 1 | (x & 0x0F))
+
+/* ATtiny4/5/9/10 I/O registers */
+#define TPI_IOREG_NVMCSR 0x32
+#define TPI_IOREG_NVMCMD 0x33
+
+/* bit for NVMCSR */
+#define TPI_IOREG_NVMCSR_NVMBSY (1 << 7)
+
+/* NVM commands */
+#define TPI_NVMCMD_NO_OPERATION 0x00
+#define TPI_NVMCMD_CHIP_ERASE 0x10
+#define TPI_NVMCMD_SECTION_ERASE 0x14
+#define TPI_NVMCMD_WORD_WRITE 0x1D
+
+static const unsigned char tpi_skey_cmd[] = { TPI_CMD_SKEY, 0xff, 0x88, 0xd8, 0xcd, 0x45, 0xab, 0x89, 0x12 };
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/xs/src/avrdude/update.c b/xs/src/avrdude/update.c
new file mode 100644
index 000000000..a255ab4f9
--- /dev/null
+++ b/xs/src/avrdude/update.c
@@ -0,0 +1,412 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000-2005 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2007 Joerg Wunsch
+ *
+ * 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$ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+UPDATE * parse_op(char * s)
+{
+ char buf[1024];
+ char * p, * cp, c;
+ UPDATE * upd;
+ int i;
+ size_t fnlen;
+
+ upd = (UPDATE *)malloc(sizeof(UPDATE));
+ if (upd == NULL) {
+ // avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
+ // exit(1);
+ avrdude_oom("parse_op: out of memory\n");
+ }
+
+ i = 0;
+ p = s;
+ while ((i < (sizeof(buf)-1) && *p && (*p != ':')))
+ buf[i++] = *p++;
+ buf[i] = 0;
+
+ if (*p != ':') {
+ upd->memtype = NULL; /* default memtype, "flash", or "application" */
+ upd->op = DEVICE_WRITE;
+ upd->filename = (char *)malloc(strlen(buf) + 1);
+ if (upd->filename == NULL) {
+ // avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
+ // exit(1);
+ avrdude_oom("parse_op: out of memory\n");
+ }
+ strcpy(upd->filename, buf);
+ upd->format = FMT_AUTO;
+ return upd;
+ }
+
+ upd->memtype = (char *)malloc(strlen(buf)+1);
+ if (upd->memtype == NULL) {
+ // avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
+ // exit(1);
+ avrdude_oom("parse_op: out of memory\n");
+ }
+ strcpy(upd->memtype, buf);
+
+ p++;
+ if (*p == 'r') {
+ upd->op = DEVICE_READ;
+ }
+ else if (*p == 'w') {
+ upd->op = DEVICE_WRITE;
+ }
+ else if (*p == 'v') {
+ upd->op = DEVICE_VERIFY;
+ }
+ else {
+ avrdude_message(MSG_INFO, "%s: invalid I/O mode '%c' in update specification\n",
+ progname, *p);
+ avrdude_message(MSG_INFO, " allowed values are:\n"
+ " r = read device\n"
+ " w = write device\n"
+ " v = verify device\n");
+ free(upd->memtype);
+ free(upd);
+ return NULL;
+ }
+
+ p++;
+
+ if (*p != ':') {
+ avrdude_message(MSG_INFO, "%s: invalid update specification\n", progname);
+ free(upd->memtype);
+ free(upd);
+ return NULL;
+ }
+
+ p++;
+
+ // Extension: Parse file section number
+ unsigned section = 0;
+
+ for (; *p != ':'; p++) {
+ if (*p >= '0' && *p <= '9') {
+ section *= 10;
+ section += *p - 0x30;
+ } else {
+ avrdude_message(MSG_INFO, "%s: invalid update specification: <section> is not a number\n", progname);
+ free(upd->memtype);
+ free(upd);
+ return NULL;
+ }
+ }
+
+ upd->section = section;
+ p++;
+
+ /*
+ * Now, parse the filename component. Instead of looking for the
+ * leftmost possible colon delimiter, we look for the rightmost one.
+ * If we found one, we do have a trailing :format specifier, and
+ * process it. Otherwise, the remainder of the string is our file
+ * name component. That way, the file name itself is allowed to
+ * contain a colon itself (e. g. C:/some/file.hex), except the
+ * optional format specifier becomes mandatory then.
+ */
+ cp = p;
+ p = strrchr(cp, ':');
+ if (p == NULL) {
+ upd->format = FMT_AUTO;
+ fnlen = strlen(cp);
+ upd->filename = (char *)malloc(fnlen + 1);
+ } else {
+ fnlen = p - cp;
+ upd->filename = (char *)malloc(fnlen +1);
+ c = *++p;
+ if (c && p[1])
+ /* More than one char - force failure below. */
+ c = '?';
+ switch (c) {
+ case 'a': upd->format = FMT_AUTO; break;
+ case 's': upd->format = FMT_SREC; break;
+ case 'i': upd->format = FMT_IHEX; break;
+ case 'r': upd->format = FMT_RBIN; break;
+ case 'e': upd->format = FMT_ELF; break;
+ case 'm': upd->format = FMT_IMM; break;
+ case 'b': upd->format = FMT_BIN; break;
+ case 'd': upd->format = FMT_DEC; break;
+ case 'h': upd->format = FMT_HEX; break;
+ case 'o': upd->format = FMT_OCT; break;
+ default:
+ avrdude_message(MSG_INFO, "%s: invalid file format '%s' in update specifier\n",
+ progname, p);
+ free(upd->memtype);
+ free(upd);
+ return NULL;
+ }
+ }
+
+ if (upd->filename == NULL) {
+ avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
+ free(upd->memtype);
+ free(upd);
+ return NULL;
+ }
+ memcpy(upd->filename, cp, fnlen);
+ upd->filename[fnlen] = 0;
+
+ return upd;
+}
+
+UPDATE * dup_update(UPDATE * upd)
+{
+ UPDATE * u;
+
+ u = (UPDATE *)malloc(sizeof(UPDATE));
+ if (u == NULL) {
+ // avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
+ // exit(1);
+ avrdude_oom("dup_update: out of memory\n");
+ }
+
+ memcpy(u, upd, sizeof(UPDATE));
+
+ if (upd->memtype != NULL)
+ u->memtype = strdup(upd->memtype);
+ else
+ u->memtype = NULL;
+ u->filename = strdup(upd->filename);
+
+ return u;
+}
+
+UPDATE * new_update(int op, char * memtype, int filefmt, char * filename, unsigned section)
+{
+ UPDATE * u;
+
+ u = (UPDATE *)malloc(sizeof(UPDATE));
+ if (u == NULL) {
+ // avrdude_message(MSG_INFO, "%s: out of memory\n", progname);
+ // exit(1);
+ avrdude_oom("new_update: out of memory\n");
+ }
+
+ u->memtype = strdup(memtype);
+ u->filename = strdup(filename);
+ u->op = op;
+ u->format = filefmt;
+ u->section = section;
+
+ return u;
+}
+
+void free_update(UPDATE * u)
+{
+ if (u != NULL) {
+ if(u->memtype != NULL) {
+ free(u->memtype);
+ u->memtype = NULL;
+ }
+ if(u->filename != NULL) {
+ free(u->filename);
+ u->filename = NULL;
+ }
+ free(u);
+ }
+}
+
+
+int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags flags)
+{
+ struct avrpart * v;
+ AVRMEM * mem;
+ int size, vsize;
+ int rc;
+
+ mem = avr_locate_mem(p, upd->memtype);
+ if (mem == NULL) {
+ avrdude_message(MSG_INFO, "\"%s\" memory type not defined for part \"%s\"\n",
+ upd->memtype, p->desc);
+ return -1;
+ }
+
+ if (upd->op == DEVICE_READ) {
+ /*
+ * read out the specified device memory and write it to a file
+ */
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: reading %s memory:\n",
+ progname, mem->desc);
+ }
+ report_progress(0,1,"Reading");
+ rc = avr_read(pgm, p, upd->memtype, 0);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: failed to read all of %s memory, rc=%d\n",
+ progname, mem->desc, rc);
+ return -1;
+ }
+ report_progress(1,1,NULL);
+ size = rc;
+
+ if (quell_progress < 2) {
+ if (rc == 0)
+ avrdude_message(MSG_INFO, "%s: Flash is empty, resulting file has no contents.\n",
+ progname);
+ avrdude_message(MSG_INFO, "%s: writing output file \"%s\"\n",
+ progname,
+ strcmp(upd->filename, "-")==0 ? "<stdout>" : upd->filename);
+ }
+ rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size, 0);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: write to file '%s' failed\n",
+ progname, upd->filename);
+ return -1;
+ }
+ }
+ else if (upd->op == DEVICE_WRITE) {
+ /*
+ * write the selected device memory using data from a file; first
+ * read the data from the specified file
+ */
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: reading input file \"%s\"\n",
+ progname,
+ strcmp(upd->filename, "-")==0 ? "<stdin>" : upd->filename);
+ }
+ rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->section);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n",
+ progname, upd->filename);
+ return -1;
+ }
+ size = rc;
+
+ /*
+ * write the buffer contents to the selected memory type
+ */
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: writing %s (%d bytes):\n",
+ progname, mem->desc, size);
+ }
+
+ //Prusa3D bootloader progress on lcd
+ if (strcmp(pgm->type, "Wiring") == 0)
+ {
+ if (pgm->set_upload_size != 0)
+ pgm->set_upload_size(pgm, size);
+ }
+
+ if (!(flags & UF_NOWRITE)) {
+ report_progress(0,1,"Writing");
+ rc = avr_write(pgm, p, upd->memtype, size, (flags & UF_AUTO_ERASE) != 0);
+ report_progress(1,1,NULL);
+ }
+ else {
+ // /*
+ // * test mode, don't actually write to the chip, output the buffer
+ // * to stdout in intel hex instead
+ // */
+ // rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size, 0);
+ }
+
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: failed to write %s memory, rc=%d\n",
+ progname, mem->desc, rc);
+ return -1;
+ }
+
+ vsize = rc;
+
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: %d bytes of %s written\n", progname,
+ vsize, mem->desc);
+ }
+
+ }
+ else if (upd->op == DEVICE_VERIFY) {
+ /*
+ * verify that the in memory file (p->mem[AVR_M_FLASH|AVR_M_EEPROM])
+ * is the same as what is on the chip
+ */
+ pgm->vfy_led(pgm, ON);
+
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: verifying %s memory against %s:\n",
+ progname, mem->desc, upd->filename);
+
+ avrdude_message(MSG_INFO, "%s: load data %s data from input file %s:\n",
+ progname, mem->desc, upd->filename);
+ }
+
+ rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1, upd->section);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: read from file '%s' failed\n",
+ progname, upd->filename);
+ return -1;
+ }
+ v = avr_dup_part(p);
+ size = rc;
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: input file %s contains %d bytes\n",
+ progname, upd->filename, size);
+ avrdude_message(MSG_INFO, "%s: reading on-chip %s data:\n",
+ progname, mem->desc);
+ }
+
+ report_progress (0,1,"Reading");
+ rc = avr_read(pgm, p, upd->memtype, v);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: failed to read all of %s memory, rc=%d\n",
+ progname, mem->desc, rc);
+ pgm->err_led(pgm, ON);
+ return -1;
+ }
+ report_progress (1,1,NULL);
+
+
+
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: verifying ...\n", progname);
+ }
+ rc = avr_verify(p, v, upd->memtype, size);
+ if (rc < 0) {
+ avrdude_message(MSG_INFO, "%s: verification error; content mismatch\n",
+ progname);
+ pgm->err_led(pgm, ON);
+ return -1;
+ }
+
+ if (quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: %d bytes of %s verified\n",
+ progname, rc, mem->desc);
+ }
+
+ pgm->vfy_led(pgm, OFF);
+ }
+ else {
+ avrdude_message(MSG_INFO, "%s: invalid update operation (%d) requested\n",
+ progname, upd->op);
+ return -1;
+ }
+
+ return 0;
+}
+
diff --git a/xs/src/avrdude/usb_hidapi.c b/xs/src/avrdude/usb_hidapi.c
new file mode 100644
index 000000000..81e9c4abe
--- /dev/null
+++ b/xs/src/avrdude/usb_hidapi.c
@@ -0,0 +1,357 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2016 Joerg Wunsch
+ *
+ * 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$ */
+
+/*
+ * USB interface via libhidapi for avrdude.
+ */
+
+#include "ac_cfg.h"
+#if defined(HAVE_LIBHIDAPI)
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <wchar.h>
+
+#include <hidapi/hidapi.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "usbdevs.h"
+
+#if defined(WIN32NATIVE)
+/* someone has defined "interface" to "struct" in Cygwin */
+# undef interface
+#endif
+
+/*
+ * The "baud" parameter is meaningless for USB devices, so we reuse it
+ * to pass the desired USB device ID.
+ */
+static int usbhid_open(char * port, union pinfo pinfo, union filedescriptor *fd)
+{
+ hid_device *dev;
+ char *serno, *cp2;
+ size_t x;
+ unsigned char usbbuf[USBDEV_MAX_XFER_3 + 1];
+
+ if (fd->usb.max_xfer == 0)
+ fd->usb.max_xfer = USBDEV_MAX_XFER_3;
+
+ /*
+ * The syntax for usb devices is defined as:
+ *
+ * -P usb[:serialnumber]
+ *
+ * See if we've got a serial number passed here. The serial number
+ * might contain colons which we remove below, and we compare it
+ * right-to-left, so only the least significant nibbles need to be
+ * specified.
+ */
+ if ((serno = strchr(port, ':')) != NULL)
+ {
+ /* first, drop all colons there if any */
+ cp2 = ++serno;
+
+ while ((cp2 = strchr(cp2, ':')) != NULL)
+ {
+ x = strlen(cp2) - 1;
+ memmove(cp2, cp2 + 1, x);
+ cp2[x] = '\0';
+ }
+
+ if (strlen(serno) > 12)
+ {
+ avrdude_message(MSG_INFO, "%s: usbhid_open(): invalid serial number \"%s\"\n",
+ progname, serno);
+ return -1;
+ }
+
+ wchar_t wserno[15];
+ mbstowcs(wserno, serno, 15);
+ size_t serlen = strlen(serno);
+
+ /*
+ * Now, try finding all devices matching VID:PID, and compare
+ * their serial numbers against the requested one.
+ */
+ struct hid_device_info *list, *walk;
+ list = hid_enumerate(pinfo.usbinfo.vid, pinfo.usbinfo.pid);
+ if (list == NULL)
+ return -1;
+
+ walk = list;
+ while (walk)
+ {
+ avrdude_message(MSG_NOTICE, "%s: usbhid_open(): Found %ls, serno: %ls\n",
+ progname, walk->product_string, walk->serial_number);
+ size_t slen = wcslen(walk->serial_number);
+ if (slen >= serlen &&
+ wcscmp(walk->serial_number + slen - serlen, wserno) == 0)
+ {
+ /* found matching serial number */
+ break;
+ }
+ avrdude_message(MSG_DEBUG, "%s: usbhid_open(): serial number doesn't match\n",
+ progname);
+ walk = walk->next;
+ }
+ if (walk == NULL)
+ {
+ avrdude_message(MSG_INFO, "%s: usbhid_open(): No matching device found\n",
+ progname);
+ hid_free_enumeration(list);
+ return -1;
+ }
+ avrdude_message(MSG_DEBUG, "%s: usbhid_open(): Opening path %s\n",
+ progname, walk->path);
+ dev = hid_open_path(walk->path);
+ hid_free_enumeration(list);
+ if (dev == NULL)
+ {
+ avrdude_message(MSG_INFO,
+ "%s: usbhid_open(): Found device, but hid_open_path() failed\n",
+ progname);
+ return -1;
+ }
+ }
+ else
+ {
+ /*
+ * No serial number requested, pass straight to hid_open()
+ */
+ dev = hid_open(pinfo.usbinfo.vid, pinfo.usbinfo.pid, NULL);
+ if (dev == NULL)
+ {
+ avrdude_message(MSG_INFO, "%s: usbhid_open(): No device found\n",
+ progname);
+ return -1;
+ }
+ }
+
+ fd->usb.handle = dev;
+
+ /*
+ * Try finding out the endpoint size. Alas, libhidapi doesn't
+ * provide us with an API function for that, nor for the report
+ * descriptor (which also contains that information).
+ *
+ * Since the Atmel tools a very picky to only respond to incoming
+ * packets that have full size, we need to know whether our device
+ * handles 512-byte data (JTAGICE3 in CMSIS-DAP mode, or AtmelICE,
+ * both on USB 2.0 connections), or 64-byte data only (both these on
+ * USB 1.1 connections, or mEDBG devices).
+ *
+ * In order to find out, we send a CMSIS-DAP DAP_Info command
+ * (0x00), with an ID of 0xFF (get maximum packet size). In theory,
+ * this gets us the desired information, but this suffers from a
+ * chicken-and-egg problem: the request must be sent with a
+ * full-sized packet lest the ICE won't answer. Thus, we send a
+ * 64-byte packet first, and if we don't get a timely reply,
+ * complete that request by sending another 448 bytes, and hope it
+ * will eventually reply.
+ *
+ * Note that libhidapi always requires a report ID as the first
+ * byte. If the target doesn't use report IDs (Atmel targets
+ * don't), this first byte must be 0x00. However, the length must
+ * be incremented by one, as the report ID will be omitted by the
+ * hidapi library.
+ */
+ if (pinfo.usbinfo.vid == USB_VENDOR_ATMEL)
+ {
+ avrdude_message(MSG_DEBUG, "%s: usbhid_open(): Probing for max. packet size\n",
+ progname);
+ memset(usbbuf, 0, sizeof usbbuf);
+ usbbuf[0] = 0; /* no HID reports used */
+ usbbuf[1] = 0; /* DAP_Info */
+ usbbuf[2] = 0xFF; /* get max. packet size */
+
+ hid_write(dev, usbbuf, 65);
+ fd->usb.max_xfer = 64; /* first guess */
+
+ memset(usbbuf, 0, sizeof usbbuf);
+ int res = hid_read_timeout(dev, usbbuf, 10 /* bytes */, 50 /* milliseconds */);
+ if (res == 0) {
+ /* no timely response, assume 512 byte size */
+ hid_write(dev, usbbuf, (512 - 64) + 1);
+ fd->usb.max_xfer = 512;
+ res = hid_read_timeout(dev, usbbuf, 10, 50);
+ }
+ if (res <= 0) {
+ avrdude_message(MSG_INFO, "%s: usbhid_open(): No response from device\n",
+ progname);
+ hid_close(dev);
+ return -1;
+ }
+ if (usbbuf[0] != 0 || usbbuf[1] != 2) {
+ avrdude_message(MSG_INFO,
+ "%s: usbhid_open(): Unexpected reply to DAP_Info: 0x%02x 0x%02x\n",
+ progname, usbbuf[0], usbbuf[1]);
+ } else {
+ fd->usb.max_xfer = usbbuf[2] + (usbbuf[3] << 8);
+ avrdude_message(MSG_DEBUG,
+ "%s: usbhid_open(): Setting max_xfer from DAP_Info response to %d\n",
+ progname, fd->usb.max_xfer);
+ }
+ }
+ if (fd->usb.max_xfer > USBDEV_MAX_XFER_3) {
+ avrdude_message(MSG_INFO,
+ "%s: usbhid_open(): Unexpected max size %d, reducing to %d\n",
+ progname, fd->usb.max_xfer, USBDEV_MAX_XFER_3);
+ fd->usb.max_xfer = USBDEV_MAX_XFER_3;
+ }
+
+ return 0;
+}
+
+static void usbhid_close(union filedescriptor *fd)
+{
+ hid_device *udev = (hid_device *)fd->usb.handle;
+
+ if (udev == NULL)
+ return;
+
+ hid_close(udev);
+}
+
+
+static int usbhid_send(union filedescriptor *fd, const unsigned char *bp, size_t mlen)
+{
+ hid_device *udev = (hid_device *)fd->usb.handle;
+ int rv;
+ int i = mlen;
+ const unsigned char * p = bp;
+ unsigned char usbbuf[USBDEV_MAX_XFER_3 + 1];
+
+
+ int tx_size;
+
+ if (udev == NULL)
+ return -1;
+
+ tx_size = (mlen < USBDEV_MAX_XFER_3)? mlen: USBDEV_MAX_XFER_3;
+ usbbuf[0] = 0; /* no report ID used */
+ memcpy(usbbuf + 1, bp, tx_size);
+ rv = hid_write(udev, usbbuf, tx_size + 1);
+ if (rv < 0) {
+ avrdude_message(MSG_INFO, "%s: Failed to write %d bytes to USB\n",
+ progname, tx_size);
+ return -1;
+ }
+ if (rv != tx_size + 1)
+ avrdude_message(MSG_INFO, "%s: Short write to USB: %d bytes out of %d written\n",
+ progname, rv, tx_size + 1);
+
+ if (verbose > 4)
+ {
+ avrdude_message(MSG_TRACE2, "%s: Sent: ", progname);
+
+ while (i) {
+ unsigned char c = *p;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE2, "%c ", c);
+ }
+ else {
+ avrdude_message(MSG_TRACE2, ". ");
+ }
+ avrdude_message(MSG_TRACE2, "[%02x] ", c);
+
+ p++;
+ i--;
+ }
+ avrdude_message(MSG_TRACE2, "\n");
+ }
+ return 0;
+}
+
+static int usbhid_recv(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
+{
+ hid_device *udev = (hid_device *)fd->usb.handle;
+ int i, rv;
+ unsigned char * p = buf;
+
+ if (udev == NULL)
+ return -1;
+
+ rv = i = hid_read_timeout(udev, buf, nbytes, 300);
+ if (i != nbytes)
+ avrdude_message(MSG_INFO,
+ "%s: Short read, read only %d out of %u bytes\n",
+ progname, i, nbytes);
+
+ if (verbose > 4)
+ {
+ avrdude_message(MSG_TRACE2, "%s: Recv: ", progname);
+
+ while (i) {
+ unsigned char c = *p;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE2, "%c ", c);
+ }
+ else {
+ avrdude_message(MSG_TRACE2, ". ");
+ }
+ avrdude_message(MSG_TRACE2, "[%02x] ", c);
+
+ p++;
+ i--;
+ }
+ avrdude_message(MSG_TRACE2, "\n");
+ }
+
+ return rv;
+}
+
+static int usbhid_drain(union filedescriptor *fd, int display)
+{
+ /*
+ * There is not much point in trying to flush any data
+ * on an USB endpoint, as the endpoint is supposed to
+ * start afresh after being configured from the host.
+ *
+ * As trying to flush the data here caused strange effects
+ * in some situations (see
+ * https://savannah.nongnu.org/bugs/index.php?43268 )
+ * better avoid it.
+ */
+
+ return 0;
+}
+
+/*
+ * Device descriptor.
+ */
+struct serial_device usbhid_serdev =
+{
+ .open = usbhid_open,
+ .close = usbhid_close,
+ .send = usbhid_send,
+ .recv = usbhid_recv,
+ .drain = usbhid_drain,
+ .flags = SERDEV_FL_NONE,
+};
+
+#endif /* HAVE_LIBHIDAPI */
diff --git a/xs/src/avrdude/usb_libusb.c b/xs/src/avrdude/usb_libusb.c
new file mode 100644
index 000000000..235e330a8
--- /dev/null
+++ b/xs/src/avrdude/usb_libusb.c
@@ -0,0 +1,615 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2005,2006 Joerg Wunsch
+ * Copyright (C) 2006 David Moore
+ *
+ * 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$ */
+
+/*
+ * USB interface via libusb for avrdude.
+ */
+
+#include "ac_cfg.h"
+#if defined(HAVE_LIBUSB)
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#if defined(HAVE_USB_H)
+# include <usb.h>
+#elif defined(HAVE_LUSB0_USB_H)
+# include <lusb0_usb.h>
+#else
+# error "libusb needs either <usb.h> or <lusb0_usb.h>"
+#endif
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "usbdevs.h"
+
+#if defined(WIN32NATIVE)
+/* someone has defined "interface" to "struct" in Cygwin */
+# undef interface
+#endif
+
+static char usbbuf[USBDEV_MAX_XFER_3];
+static int buflen = -1, bufptr;
+
+static int usb_interface;
+
+/*
+ * The "baud" parameter is meaningless for USB devices, so we reuse it
+ * to pass the desired USB device ID.
+ */
+static int usbdev_open(char * port, union pinfo pinfo, union filedescriptor *fd)
+{
+ char string[256];
+ char product[256];
+ struct usb_bus *bus;
+ struct usb_device *dev;
+ usb_dev_handle *udev;
+ char *serno, *cp2;
+ int i;
+ int iface;
+ size_t x;
+
+ /*
+ * The syntax for usb devices is defined as:
+ *
+ * -P usb[:serialnumber]
+ *
+ * See if we've got a serial number passed here. The serial number
+ * might contain colons which we remove below, and we compare it
+ * right-to-left, so only the least significant nibbles need to be
+ * specified.
+ */
+ if ((serno = strchr(port, ':')) != NULL)
+ {
+ /* first, drop all colons there if any */
+ cp2 = ++serno;
+
+ while ((cp2 = strchr(cp2, ':')) != NULL)
+ {
+ x = strlen(cp2) - 1;
+ memmove(cp2, cp2 + 1, x);
+ cp2[x] = '\0';
+ }
+
+ if (strlen(serno) > 12)
+ {
+ avrdude_message(MSG_INFO, "%s: usbdev_open(): invalid serial number \"%s\"\n",
+ progname, serno);
+ return -1;
+ }
+ }
+
+ if (fd->usb.max_xfer == 0)
+ fd->usb.max_xfer = USBDEV_MAX_XFER_MKII;
+
+ usb_init();
+
+ usb_find_busses();
+ usb_find_devices();
+
+ for (bus = usb_get_busses(); bus; bus = bus->next)
+ {
+ for (dev = bus->devices; dev; dev = dev->next)
+ {
+ if (dev->descriptor.idVendor == pinfo.usbinfo.vid &&
+ dev->descriptor.idProduct == pinfo.usbinfo.pid)
+ {
+ udev = usb_open(dev);
+ if (udev)
+ {
+ /* yeah, we found something */
+ if (usb_get_string_simple(udev,
+ dev->descriptor.iSerialNumber,
+ string, sizeof(string)) < 0)
+ {
+ avrdude_message(MSG_INFO, "%s: usb_open(): cannot read serial number \"%s\"\n",
+ progname, usb_strerror());
+ /*
+ * On some systems, libusb appears to have
+ * problems sending control messages. Catch the
+ * benign case where the user did not request a
+ * particular serial number, so we could
+ * continue anyway.
+ */
+ if (serno != NULL)
+ return -1; /* no chance */
+ else
+ strcpy(string, "[unknown]");
+ }
+
+ if (usb_get_string_simple(udev,
+ dev->descriptor.iProduct,
+ product, sizeof(product)) < 0)
+ {
+ avrdude_message(MSG_INFO, "%s: usb_open(): cannot read product name \"%s\"\n",
+ progname, usb_strerror());
+ strcpy(product, "[unnamed product]");
+ }
+ /*
+ * The CMSIS-DAP specification mandates the string
+ * "CMSIS-DAP" must be present somewhere in the
+ * product name string for a device compliant to
+ * that protocol. Use this for the decisision
+ * whether we have to search for a HID interface
+ * below.
+ */
+ if(strstr(product, "CMSIS-DAP") != NULL)
+ {
+ pinfo.usbinfo.flags |= PINFO_FL_USEHID;
+ /* The JTAGICE3 running the CMSIS-DAP firmware doesn't
+ * use a separate endpoint for event reception. */
+ fd->usb.eep = 0;
+ }
+
+ if(strstr(product, "mEDBG") != NULL)
+ {
+ /* The AVR Xplained Mini uses different endpoints. */
+ fd->usb.rep = 0x81;
+ fd->usb.wep = 0x02;
+ }
+
+ avrdude_message(MSG_NOTICE, "%s: usbdev_open(): Found %s, serno: %s\n",
+ progname, product, string);
+ if (serno != NULL)
+ {
+ /*
+ * See if the serial number requested by the
+ * user matches what we found, matching
+ * right-to-left.
+ */
+ x = strlen(string) - strlen(serno);
+ if (strcasecmp(string + x, serno) != 0)
+ {
+ avrdude_message(MSG_DEBUG, "%s: usbdev_open(): serial number doesn't match\n",
+ progname);
+ usb_close(udev);
+ continue;
+ }
+ }
+
+ if (dev->config == NULL)
+ {
+ avrdude_message(MSG_INFO, "%s: usbdev_open(): USB device has no configuration\n",
+ progname);
+ goto trynext;
+ }
+
+ if (usb_set_configuration(udev, dev->config[0].bConfigurationValue))
+ {
+ avrdude_message(MSG_INFO, "%s: usbdev_open(): WARNING: failed to set configuration %d: %s\n",
+ progname, dev->config[0].bConfigurationValue,
+ usb_strerror());
+ /* let's hope it has already been configured */
+ // goto trynext;
+ }
+
+ for (iface = 0; iface < dev->config[0].bNumInterfaces; iface++)
+ {
+ usb_interface = dev->config[0].interface[iface].altsetting[0].bInterfaceNumber;
+#ifdef LIBUSB_HAS_GET_DRIVER_NP
+ /*
+ * Many Linux systems attach the usbhid driver
+ * by default to any HID-class device. On
+ * those, the driver needs to be detached before
+ * we can claim the interface.
+ */
+ (void)usb_detach_kernel_driver_np(udev, usb_interface);
+#endif
+ if (usb_claim_interface(udev, usb_interface))
+ {
+ avrdude_message(MSG_INFO, "%s: usbdev_open(): error claiming interface %d: %s\n",
+ progname, usb_interface, usb_strerror());
+ }
+ else
+ {
+ if (pinfo.usbinfo.flags & PINFO_FL_USEHID)
+ {
+ /* only consider an interface that is of class HID */
+ if (dev->config[0].interface[iface].altsetting[0].bInterfaceClass !=
+ USB_CLASS_HID)
+ continue;
+ fd->usb.use_interrupt_xfer = 1;
+ }
+ break;
+ }
+ }
+ if (iface == dev->config[0].bNumInterfaces)
+ {
+ avrdude_message(MSG_INFO, "%s: usbdev_open(): no usable interface found\n",
+ progname);
+ goto trynext;
+ }
+
+ fd->usb.handle = udev;
+ if (fd->usb.rep == 0)
+ {
+ /* Try finding out what our read endpoint is. */
+ for (i = 0; i < dev->config[0].interface[iface].altsetting[0].bNumEndpoints; i++)
+ {
+ int possible_ep = dev->config[0].interface[iface].altsetting[0].
+ endpoint[i].bEndpointAddress;
+
+ if ((possible_ep & USB_ENDPOINT_DIR_MASK) != 0)
+ {
+ avrdude_message(MSG_NOTICE2, "%s: usbdev_open(): using read endpoint 0x%02x\n",
+ progname, possible_ep);
+ fd->usb.rep = possible_ep;
+ break;
+ }
+ }
+ if (fd->usb.rep == 0)
+ {
+ avrdude_message(MSG_INFO, "%s: usbdev_open(): cannot find a read endpoint, using 0x%02x\n",
+ progname, USBDEV_BULK_EP_READ_MKII);
+ fd->usb.rep = USBDEV_BULK_EP_READ_MKII;
+ }
+ }
+ for (i = 0; i < dev->config[0].interface[iface].altsetting[0].bNumEndpoints; i++)
+ {
+ if ((dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.rep ||
+ dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress == fd->usb.wep) &&
+ dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize < fd->usb.max_xfer)
+ {
+ avrdude_message(MSG_NOTICE, "%s: max packet size expected %d, but found %d due to EP 0x%02x's wMaxPacketSize\n",
+ progname,
+ fd->usb.max_xfer,
+ dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize,
+ dev->config[0].interface[iface].altsetting[0].endpoint[i].bEndpointAddress);
+ fd->usb.max_xfer = dev->config[0].interface[iface].altsetting[0].endpoint[i].wMaxPacketSize;
+ }
+ }
+ if (pinfo.usbinfo.flags & PINFO_FL_USEHID)
+ {
+ if (usb_control_msg(udev, 0x21, 0x0a /* SET_IDLE */, 0, 0, NULL, 0, 100) < 0)
+ avrdude_message(MSG_INFO, "%s: usbdev_open(): SET_IDLE failed\n", progname);
+ }
+ return 0;
+ trynext:
+ usb_close(udev);
+ }
+ else
+ avrdude_message(MSG_INFO, "%s: usbdev_open(): cannot open device: %s\n",
+ progname, usb_strerror());
+ }
+ }
+ }
+
+ if ((pinfo.usbinfo.flags & PINFO_FL_SILENT) == 0)
+ avrdude_message(MSG_NOTICE, "%s: usbdev_open(): did not find any%s USB device \"%s\" (0x%04x:0x%04x)\n",
+ progname, serno? " (matching)": "", port,
+ (unsigned)pinfo.usbinfo.vid, (unsigned)pinfo.usbinfo.pid);
+ return -1;
+}
+
+static void usbdev_close(union filedescriptor *fd)
+{
+ usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
+
+ if (udev == NULL)
+ return;
+
+ (void)usb_release_interface(udev, usb_interface);
+
+#if defined(__linux__)
+ /*
+ * Without this reset, the AVRISP mkII seems to stall the second
+ * time we try to connect to it. This is not necessary on
+ * FreeBSD.
+ */
+ usb_reset(udev);
+#endif
+
+ usb_close(udev);
+}
+
+
+static int usbdev_send(union filedescriptor *fd, const unsigned char *bp, size_t mlen)
+{
+ usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
+ int rv;
+ int i = mlen;
+ const unsigned char * p = bp;
+ int tx_size;
+
+ if (udev == NULL)
+ return -1;
+
+ /*
+ * Split the frame into multiple packets. It's important to make
+ * sure we finish with a short packet, or else the device won't know
+ * the frame is finished. For example, if we need to send 64 bytes,
+ * we must send a packet of length 64 followed by a packet of length
+ * 0.
+ */
+ do {
+ tx_size = (mlen < fd->usb.max_xfer)? mlen: fd->usb.max_xfer;
+ if (fd->usb.use_interrupt_xfer)
+ rv = usb_interrupt_write(udev, fd->usb.wep, (char *)bp, tx_size, 10000);
+ else
+ rv = usb_bulk_write(udev, fd->usb.wep, (char *)bp, tx_size, 10000);
+ if (rv != tx_size)
+ {
+ avrdude_message(MSG_INFO, "%s: usbdev_send(): wrote %d out of %d bytes, err = %s\n",
+ progname, rv, tx_size, usb_strerror());
+ return -1;
+ }
+ bp += tx_size;
+ mlen -= tx_size;
+ } while (mlen > 0);
+
+ if (verbose > 3)
+ {
+ avrdude_message(MSG_TRACE, "%s: Sent: ", progname);
+
+ while (i) {
+ unsigned char c = *p;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE, "%c ", c);
+ }
+ else {
+ avrdude_message(MSG_TRACE, ". ");
+ }
+ avrdude_message(MSG_TRACE, "[%02x] ", c);
+
+ p++;
+ i--;
+ }
+ avrdude_message(MSG_TRACE, "\n");
+ }
+ return 0;
+}
+
+/*
+ * As calls to usb_bulk_read() result in exactly one USB request, we
+ * have to buffer the read results ourselves, so the single-char read
+ * requests performed by the upper layers will be handled. In order
+ * to do this, we maintain a private buffer of what we've got so far,
+ * and transparently issue another USB read request if the buffer is
+ * empty and more data are requested.
+ */
+static int
+usb_fill_buf(usb_dev_handle *udev, int maxsize, int ep, int use_interrupt_xfer)
+{
+ int rv;
+
+ if (use_interrupt_xfer)
+ rv = usb_interrupt_read(udev, ep, usbbuf, maxsize, 10000);
+ else
+ rv = usb_bulk_read(udev, ep, usbbuf, maxsize, 10000);
+ if (rv < 0)
+ {
+ avrdude_message(MSG_NOTICE2, "%s: usb_fill_buf(): usb_%s_read() error %s\n",
+ progname, (use_interrupt_xfer? "interrupt": "bulk"),
+ usb_strerror());
+ return -1;
+ }
+
+ buflen = rv;
+ bufptr = 0;
+
+ return 0;
+}
+
+static int usbdev_recv(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
+{
+ usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
+ int i, amnt;
+ unsigned char * p = buf;
+
+ if (udev == NULL)
+ return -1;
+
+ for (i = 0; nbytes > 0;)
+ {
+ if (buflen <= bufptr)
+ {
+ if (usb_fill_buf(udev, fd->usb.max_xfer, fd->usb.rep, fd->usb.use_interrupt_xfer) < 0)
+ return -1;
+ }
+ amnt = buflen - bufptr > nbytes? nbytes: buflen - bufptr;
+ memcpy(buf + i, usbbuf + bufptr, amnt);
+ bufptr += amnt;
+ nbytes -= amnt;
+ i += amnt;
+ }
+
+ if (verbose > 4)
+ {
+ avrdude_message(MSG_TRACE2, "%s: Recv: ", progname);
+
+ while (i) {
+ unsigned char c = *p;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE2, "%c ", c);
+ }
+ else {
+ avrdude_message(MSG_TRACE2, ". ");
+ }
+ avrdude_message(MSG_TRACE2, "[%02x] ", c);
+
+ p++;
+ i--;
+ }
+ avrdude_message(MSG_TRACE2, "\n");
+ }
+
+ return 0;
+}
+
+/*
+ * This version of recv keeps reading packets until we receive a short
+ * packet. Then, the entire frame is assembled and returned to the
+ * user. The length will be unknown in advance, so we return the
+ * length as the return value of this function, or -1 in case of an
+ * error.
+ *
+ * This is used for the AVRISP mkII device.
+ */
+static int usbdev_recv_frame(union filedescriptor *fd, unsigned char *buf, size_t nbytes)
+{
+ usb_dev_handle *udev = (usb_dev_handle *)fd->usb.handle;
+ int rv, n;
+ int i;
+ unsigned char * p = buf;
+
+ if (udev == NULL)
+ return -1;
+
+ /* If there's an event EP, and it has data pending, return it first. */
+ if (fd->usb.eep != 0)
+ {
+ rv = usb_bulk_read(udev, fd->usb.eep, usbbuf,
+ fd->usb.max_xfer, 1);
+ if (rv > 4)
+ {
+ memcpy(buf, usbbuf, rv);
+ n = rv;
+ n |= USB_RECV_FLAG_EVENT;
+ goto printout;
+ }
+ else if (rv > 0)
+ {
+ avrdude_message(MSG_INFO, "Short event len = %d, ignored.\n", rv);
+ /* fallthrough */
+ }
+ }
+
+ n = 0;
+ do
+ {
+ if (fd->usb.use_interrupt_xfer)
+ rv = usb_interrupt_read(udev, fd->usb.rep, usbbuf,
+ fd->usb.max_xfer, 10000);
+ else
+ rv = usb_bulk_read(udev, fd->usb.rep, usbbuf,
+ fd->usb.max_xfer, 10000);
+ if (rv < 0)
+ {
+ avrdude_message(MSG_NOTICE2, "%s: usbdev_recv_frame(): usb_%s_read(): %s\n",
+ progname, (fd->usb.use_interrupt_xfer? "interrupt": "bulk"),
+ usb_strerror());
+ return -1;
+ }
+
+ if (rv <= nbytes)
+ {
+ memcpy (buf, usbbuf, rv);
+ buf += rv;
+ }
+ else
+ {
+ return -1; // buffer overflow
+ }
+
+ n += rv;
+ nbytes -= rv;
+ }
+ while (nbytes > 0 && rv == fd->usb.max_xfer);
+
+/*
+ this ends when the buffer is completly filled (nbytes=0) or was too small (nbytes< 0)
+ or a short packet is found.
+ however we cannot say for nbytes=0 that there was really a packet completed,
+ we had to check the last rv value than for a short packet,
+ but what happens if the packet does not end with a short packet?
+ and what if the buffer is filled without the packet was completed?
+
+ preconditions:
+ expected packet is not a multiple of usb.max_xfer. (prevents further waiting)
+
+ expected packet is shorter than the provided buffer (so it cannot filled completely)
+ or buffer size is not a multiple of usb.max_xfer. (so it can clearly detected if the buffer was overflown.)
+*/
+
+ printout:
+ if (verbose > 3)
+ {
+ i = n & USB_RECV_LENGTH_MASK;
+ avrdude_message(MSG_TRACE, "%s: Recv: ", progname);
+
+ while (i) {
+ unsigned char c = *p;
+ if (isprint(c)) {
+ avrdude_message(MSG_TRACE, "%c ", c);
+ }
+ else {
+ avrdude_message(MSG_TRACE, ". ");
+ }
+ avrdude_message(MSG_TRACE, "[%02x] ", c);
+
+ p++;
+ i--;
+ }
+ avrdude_message(MSG_TRACE, "\n");
+ }
+ return n;
+}
+
+static int usbdev_drain(union filedescriptor *fd, int display)
+{
+ /*
+ * There is not much point in trying to flush any data
+ * on an USB endpoint, as the endpoint is supposed to
+ * start afresh after being configured from the host.
+ *
+ * As trying to flush the data here caused strange effects
+ * in some situations (see
+ * https://savannah.nongnu.org/bugs/index.php?43268 )
+ * better avoid it.
+ */
+
+ return 0;
+}
+
+/*
+ * Device descriptor for the JTAG ICE mkII.
+ */
+struct serial_device usb_serdev =
+{
+ .open = usbdev_open,
+ .close = usbdev_close,
+ .send = usbdev_send,
+ .recv = usbdev_recv,
+ .drain = usbdev_drain,
+ .flags = SERDEV_FL_NONE,
+};
+
+/*
+ * Device descriptor for the AVRISP mkII.
+ */
+struct serial_device usb_serdev_frame =
+{
+ .open = usbdev_open,
+ .close = usbdev_close,
+ .send = usbdev_send,
+ .recv = usbdev_recv_frame,
+ .drain = usbdev_drain,
+ .flags = SERDEV_FL_NONE,
+};
+
+#endif /* HAVE_LIBUSB */
diff --git a/xs/src/avrdude/usbasp.c b/xs/src/avrdude/usbasp.c
new file mode 100644
index 000000000..e75eed1d7
--- /dev/null
+++ b/xs/src/avrdude/usbasp.c
@@ -0,0 +1,1221 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2006 Thomas Fischl
+ * Copyright 2007 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * 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$ */
+
+/*
+ * Interface to the USBasp programmer.
+ *
+ * See http://www.fischl.de/usbasp/
+ */
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "usbasp.h"
+#include "usbdevs.h"
+
+#if defined(HAVE_LIBUSB) || defined(HAVE_LIBUSB_1_0)
+
+#ifdef HAVE_LIBUSB_1_0
+# define USE_LIBUSB_1_0
+#endif
+
+#if defined(USE_LIBUSB_1_0)
+# if defined(HAVE_LIBUSB_1_0_LIBUSB_H)
+# include <libusb-1.0/libusb.h>
+# else
+# include <libusb.h>
+# endif
+#else
+# if defined(HAVE_USB_H)
+# include <usb.h>
+# elif defined(HAVE_LUSB0_USB_H)
+# include <lusb0_usb.h>
+# else
+# error "libusb needs either <usb.h> or <lusb0_usb.h>"
+# endif
+#endif
+
+#ifdef USE_LIBUSB_1_0
+
+static libusb_context *ctx = NULL;
+
+static int libusb_to_errno(int result)
+{
+ switch (result) {
+ case LIBUSB_SUCCESS:
+ return 0;
+ case LIBUSB_ERROR_IO:
+ return EIO;
+ case LIBUSB_ERROR_INVALID_PARAM:
+ return EINVAL;
+ case LIBUSB_ERROR_ACCESS:
+ return EACCES;
+ case LIBUSB_ERROR_NO_DEVICE:
+ return ENXIO;
+ case LIBUSB_ERROR_NOT_FOUND:
+ return ENOENT;
+ case LIBUSB_ERROR_BUSY:
+ return EBUSY;
+#ifdef ETIMEDOUT
+ case LIBUSB_ERROR_TIMEOUT:
+ return ETIMEDOUT;
+#endif
+#ifdef EOVERFLOW
+ case LIBUSB_ERROR_OVERFLOW:
+ return EOVERFLOW;
+#endif
+ case LIBUSB_ERROR_PIPE:
+ return EPIPE;
+ case LIBUSB_ERROR_INTERRUPTED:
+ return EINTR;
+ case LIBUSB_ERROR_NO_MEM:
+ return ENOMEM;
+ case LIBUSB_ERROR_NOT_SUPPORTED:
+ return ENOSYS;
+ default:
+ return ERANGE;
+ }
+}
+
+#endif
+
+
+/*
+ * Private data for this programmer.
+ */
+struct pdata
+{
+#ifdef USE_LIBUSB_1_0
+ libusb_device_handle *usbhandle;
+#else
+ usb_dev_handle *usbhandle;
+#endif
+ int sckfreq_hz;
+ unsigned int capabilities;
+ int use_tpi;
+};
+
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+#define IMPORT_PDATA(pgm) struct pdata *pdata = PDATA(pgm)
+
+
+
+/* Prototypes */
+// interface - management
+static void usbasp_setup(PROGRAMMER * pgm);
+static void usbasp_teardown(PROGRAMMER * pgm);
+// internal functions
+static int usbasp_transmit(PROGRAMMER * pgm, unsigned char receive,
+ unsigned char functionid, const unsigned char *send,
+ unsigned char *buffer, int buffersize);
+#ifdef USE_LIBUSB_1_0
+static int usbOpenDevice(libusb_device_handle **device, int vendor, char *vendorName, int product, char *productName);
+#else
+static int usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName);
+#endif
+// interface - prog.
+static int usbasp_open(PROGRAMMER * pgm, char * port);
+static void usbasp_close(PROGRAMMER * pgm);
+// dummy functions
+static void usbasp_disable(PROGRAMMER * pgm);
+static void usbasp_enable(PROGRAMMER * pgm);
+static void usbasp_display(PROGRAMMER * pgm, const char * p);
+// universal functions
+static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p);
+// SPI specific functions
+static int usbasp_spi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res);
+static int usbasp_spi_program_enable(PROGRAMMER * pgm, AVRPART * p);
+static int usbasp_spi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
+static int usbasp_spi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes);
+static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes);
+static int usbasp_spi_set_sck_period(PROGRAMMER *pgm, double sckperiod);
+// TPI specific functions
+static void usbasp_tpi_send_byte(PROGRAMMER * pgm, uint8_t b);
+static int usbasp_tpi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res);
+static int usbasp_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p);
+static int usbasp_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p);
+static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes);
+static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes);
+static int usbasp_tpi_set_sck_period(PROGRAMMER *pgm, double sckperiod);
+static int usbasp_tpi_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char * value);
+static int usbasp_tpi_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char data);
+
+
+/* Interface - management */
+static void usbasp_setup(PROGRAMMER * pgm)
+{
+ if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
+ avrdude_message(MSG_INFO, "%s: usbasp_setup(): Out of memory allocating private data\n",
+ progname);
+ exit(1);
+ }
+ memset(pgm->cookie, 0, sizeof(struct pdata));
+}
+
+static void usbasp_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+}
+
+/* Internal functions */
+
+static const char *usbasp_get_funcname(unsigned char functionid)
+{
+ switch (functionid) {
+ case USBASP_FUNC_CONNECT: return "USBASP_FUNC_CONNECT"; break;
+ case USBASP_FUNC_DISCONNECT: return "USBASP_FUNC_DISCONNECT"; break;
+ case USBASP_FUNC_TRANSMIT: return "USBASP_FUNC_TRANSMIT"; break;
+ case USBASP_FUNC_READFLASH: return "USBASP_FUNC_READFLASH"; break;
+ case USBASP_FUNC_ENABLEPROG: return "USBASP_FUNC_ENABLEPROG"; break;
+ case USBASP_FUNC_WRITEFLASH: return "USBASP_FUNC_WRITEFLASH"; break;
+ case USBASP_FUNC_READEEPROM: return "USBASP_FUNC_READEEPROM"; break;
+ case USBASP_FUNC_WRITEEEPROM: return "USBASP_FUNC_WRITEEEPROM"; break;
+ case USBASP_FUNC_SETLONGADDRESS: return "USBASP_FUNC_SETLONGADDRESS"; break;
+ case USBASP_FUNC_SETISPSCK: return "USBASP_FUNC_SETISPSCK"; break;
+ case USBASP_FUNC_TPI_CONNECT: return "USBASP_FUNC_TPI_CONNECT"; break;
+ case USBASP_FUNC_TPI_DISCONNECT: return "USBASP_FUNC_TPI_DISCONNECT"; break;
+ case USBASP_FUNC_TPI_RAWREAD: return "USBASP_FUNC_TPI_RAWREAD"; break;
+ case USBASP_FUNC_TPI_RAWWRITE: return "USBASP_FUNC_TPI_RAWWRITE"; break;
+ case USBASP_FUNC_TPI_READBLOCK: return "USBASP_FUNC_TPI_READBLOCK"; break;
+ case USBASP_FUNC_TPI_WRITEBLOCK: return "USBASP_FUNC_TPI_WRITEBLOCK"; break;
+ case USBASP_FUNC_GETCAPABILITIES: return "USBASP_FUNC_GETCAPABILITIES"; break;
+ default: return "Unknown USBASP function"; break;
+ }
+}
+
+/*
+ * wrapper for usb_control_msg call
+ */
+static int usbasp_transmit(PROGRAMMER * pgm,
+ unsigned char receive, unsigned char functionid,
+ const unsigned char *send,
+ unsigned char *buffer, int buffersize)
+{
+ int nbytes;
+
+ if (verbose > 3) {
+ avrdude_message(MSG_TRACE, "%s: usbasp_transmit(\"%s\", 0x%02x, 0x%02x, 0x%02x, 0x%02x)\n",
+ progname,
+ usbasp_get_funcname(functionid), send[0], send[1], send[2], send[3]);
+ if (!receive && buffersize > 0) {
+ int i;
+ avrdude_message(MSG_TRACE, "%s => ", progbuf);
+ for (i = 0; i < buffersize; i++)
+ avrdude_message(MSG_TRACE, "[%02x] ", buffer[i]);
+ avrdude_message(MSG_TRACE, "\n");
+ }
+ }
+
+#ifdef USE_LIBUSB_1_0
+ nbytes = libusb_control_transfer(PDATA(pgm)->usbhandle,
+ (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | (receive << 7)) & 0xff,
+ functionid & 0xff,
+ ((send[1] << 8) | send[0]) & 0xffff,
+ ((send[3] << 8) | send[2]) & 0xffff,
+ buffer,
+ buffersize & 0xffff,
+ 5000);
+ if(nbytes < 0){
+ avrdude_message(MSG_INFO, "%s: error: usbasp_transmit: %s\n", progname, strerror(libusb_to_errno(nbytes)));
+ return -1;
+ }
+#else
+ nbytes = usb_control_msg(PDATA(pgm)->usbhandle,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | (receive << 7),
+ functionid,
+ (send[1] << 8) | send[0],
+ (send[3] << 8) | send[2],
+ (char *)buffer, buffersize,
+ 5000);
+ if(nbytes < 0){
+ avrdude_message(MSG_INFO, "%s: error: usbasp_transmit: %s\n", progname, usb_strerror());
+ return -1;
+ }
+#endif
+
+ if (verbose > 3 && receive && nbytes > 0) {
+ int i;
+ avrdude_message(MSG_TRACE, "%s<= ", progbuf);
+ for (i = 0; i < nbytes; i++)
+ avrdude_message(MSG_TRACE, "[%02x] ", buffer[i]);
+ avrdude_message(MSG_TRACE, "\n");
+ }
+
+ return nbytes;
+}
+
+
+/*
+ * Try to open USB device with given VID, PID, vendor and product name
+ * Parts of this function were taken from an example code by OBJECTIVE
+ * DEVELOPMENT Software GmbH (www.obdev.at) to meet conditions for
+ * shared VID/PID
+ */
+#ifdef USE_LIBUSB_1_0
+static int usbOpenDevice(libusb_device_handle **device, int vendor,
+ char *vendorName, int product, char *productName)
+{
+ libusb_device_handle *handle = NULL;
+ int errorCode = USB_ERROR_NOTFOUND;
+ static int didUsbInit = 0;
+ int j;
+ int r;
+
+ if(!didUsbInit){
+ didUsbInit = 1;
+ libusb_init(&ctx);
+ }
+
+ libusb_device **dev_list;
+ int dev_list_len = libusb_get_device_list(ctx, &dev_list);
+
+ for (j=0; j<dev_list_len; ++j) {
+ libusb_device *dev = dev_list[j];
+ struct libusb_device_descriptor descriptor;
+ libusb_get_device_descriptor(dev, &descriptor);
+ if (descriptor.idVendor == vendor && descriptor.idProduct == product) {
+ char string[256];
+ /* we need to open the device in order to query strings */
+ r = libusb_open(dev, &handle);
+ if (!handle) {
+ errorCode = USB_ERROR_ACCESS;
+ avrdude_message(MSG_INFO, "%s: Warning: cannot open USB device: %s\n",
+ progname, strerror(libusb_to_errno(r)));
+ continue;
+ }
+ errorCode = 0;
+ /* now check whether the names match: */
+ /* if vendorName not given ignore it (any vendor matches) */
+ r = libusb_get_string_descriptor_ascii(handle, descriptor.iManufacturer & 0xff, (unsigned char*)string, sizeof(string));
+ if (r < 0) {
+ if ((vendorName != NULL) && (vendorName[0] != 0)) {
+ errorCode = USB_ERROR_IO;
+ avrdude_message(MSG_INFO, "%s: Warning: cannot query manufacturer for device: %s\n",
+ progname, strerror(libusb_to_errno(r)));
+ }
+ } else {
+ avrdude_message(MSG_NOTICE2, "%s: seen device from vendor ->%s<-\n",
+ progname, string);
+ if ((vendorName != NULL) && (vendorName[0] != 0) && (strcmp(string, vendorName) != 0))
+ errorCode = USB_ERROR_NOTFOUND;
+ }
+ /* if productName not given ignore it (any product matches) */
+ r = libusb_get_string_descriptor_ascii(handle, descriptor.iProduct & 0xff, (unsigned char*)string, sizeof(string));
+ if (r < 0) {
+ if ((productName != NULL) && (productName[0] != 0)) {
+ errorCode = USB_ERROR_IO;
+ avrdude_message(MSG_INFO, "%s: Warning: cannot query product for device: %s\n",
+ progname, strerror(libusb_to_errno(r)));
+ }
+ } else {
+ avrdude_message(MSG_NOTICE2, "%s: seen product ->%s<-\n",
+ progname, string);
+ if((productName != NULL) && (productName[0] != 0) && (strcmp(string, productName) != 0))
+ errorCode = USB_ERROR_NOTFOUND;
+ }
+ if (errorCode == 0)
+ break;
+ libusb_close(handle);
+ handle = NULL;
+ }
+ }
+ libusb_free_device_list(dev_list,1);
+ if (handle != NULL){
+ errorCode = 0;
+ *device = handle;
+ }
+ return errorCode;
+}
+#else
+static int usbOpenDevice(usb_dev_handle **device, int vendor,
+ char *vendorName, int product, char *productName)
+{
+struct usb_bus *bus;
+struct usb_device *dev;
+usb_dev_handle *handle = NULL;
+int errorCode = USB_ERROR_NOTFOUND;
+static int didUsbInit = 0;
+
+ if(!didUsbInit){
+ didUsbInit = 1;
+ usb_init();
+ }
+ usb_find_busses();
+ usb_find_devices();
+ for(bus=usb_get_busses(); bus; bus=bus->next){
+ for(dev=bus->devices; dev; dev=dev->next){
+ if(dev->descriptor.idVendor == vendor &&
+ dev->descriptor.idProduct == product){
+ char string[256];
+ int len;
+ /* we need to open the device in order to query strings */
+ handle = usb_open(dev);
+ if(!handle){
+ errorCode = USB_ERROR_ACCESS;
+ avrdude_message(MSG_INFO, "%s: Warning: cannot open USB device: %s\n",
+ progname, usb_strerror());
+ continue;
+ }
+ errorCode = 0;
+ /* now check whether the names match: */
+ /* if vendorName not given ignore it (any vendor matches) */
+ len = usb_get_string_simple(handle, dev->descriptor.iManufacturer,
+ string, sizeof(string));
+ if(len < 0){
+ if ((vendorName != NULL) && (vendorName[0] != 0)) {
+ errorCode = USB_ERROR_IO;
+ avrdude_message(MSG_INFO, "%s: Warning: cannot query manufacturer for device: %s\n",
+ progname, usb_strerror());
+ }
+ } else {
+ avrdude_message(MSG_NOTICE2, "%s: seen device from vendor ->%s<-\n",
+ progname, string);
+ if((vendorName != NULL) && (vendorName[0] != 0) && (strcmp(string, vendorName) != 0))
+ errorCode = USB_ERROR_NOTFOUND;
+ }
+ /* if productName not given ignore it (any product matches) */
+ len = usb_get_string_simple(handle, dev->descriptor.iProduct,
+ string, sizeof(string));
+ if(len < 0){
+ if ((productName != NULL) && (productName[0] != 0)) {
+ errorCode = USB_ERROR_IO;
+ avrdude_message(MSG_INFO, "%s: Warning: cannot query product for device: %s\n",
+ progname, usb_strerror());
+ }
+ } else {
+ avrdude_message(MSG_NOTICE2, "%s: seen product ->%s<-\n",
+ progname, string);
+ if((productName != NULL) && (productName[0] != 0) && (strcmp(string, productName) != 0))
+ errorCode = USB_ERROR_NOTFOUND;
+ }
+ if (errorCode == 0)
+ break;
+ usb_close(handle);
+ handle = NULL;
+ }
+ }
+ if(handle)
+ break;
+ }
+ if(handle != NULL){
+ errorCode = 0;
+ *device = handle;
+ }
+ return errorCode;
+}
+#endif
+
+
+/* Interface - prog. */
+static int usbasp_open(PROGRAMMER * pgm, char * port)
+{
+ avrdude_message(MSG_DEBUG, "%s: usbasp_open(\"%s\")\n",
+ progname, port);
+
+ /* usb_init will be done in usbOpenDevice */
+ LNODEID usbpid = lfirst(pgm->usbpid);
+ int pid, vid;
+ if (usbpid) {
+ pid = *(int *)(ldata(usbpid));
+ if (lnext(usbpid))
+ avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
+ progname, pid);
+ } else {
+ pid = USBASP_SHARED_PID;
+ }
+ vid = pgm->usbvid? pgm->usbvid: USBASP_SHARED_VID;
+ if (usbOpenDevice(&PDATA(pgm)->usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct) != 0) {
+ /* try alternatives */
+ if(strcasecmp(ldata(lfirst(pgm->id)), "usbasp") == 0) {
+ /* for id usbasp autodetect some variants */
+ if(strcasecmp(port, "nibobee") == 0) {
+ avrdude_message(MSG_INFO, "%s: warning: Using \"-C usbasp -P nibobee\" is deprecated,"
+ "use \"-C nibobee\" instead.\n",
+ progname);
+ if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_NIBOBEE_VID, "www.nicai-systems.com",
+ USBASP_NIBOBEE_PID, "NIBObee") != 0) {
+ avrdude_message(MSG_INFO, "%s: error: could not find USB device "
+ "\"NIBObee\" with vid=0x%x pid=0x%x\n",
+ progname, USBASP_NIBOBEE_VID, USBASP_NIBOBEE_PID);
+ return -1;
+ }
+ return 0;
+ }
+ /* check if device with old VID/PID is available */
+ if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_OLD_VID, "www.fischl.de",
+ USBASP_OLD_PID, "USBasp") == 0) {
+ /* found USBasp with old IDs */
+ avrdude_message(MSG_INFO, "%s: Warning: Found USB device \"USBasp\" with "
+ "old VID/PID! Please update firmware of USBasp!\n",
+ progname);
+ return 0;
+ }
+ /* original USBasp is specified in config file, so no need to check it again here */
+ /* no alternative found => fall through to generic error message */
+ }
+
+ avrdude_message(MSG_INFO, "%s: error: could not find USB device with vid=0x%x pid=0x%x",
+ progname, vid, pid);
+ if (pgm->usbvendor[0] != 0) {
+ avrdude_message(MSG_INFO, " vendor='%s'", pgm->usbvendor);
+ }
+ if (pgm->usbproduct[0] != 0) {
+ avrdude_message(MSG_INFO, " product='%s'", pgm->usbproduct);
+ }
+ avrdude_message(MSG_INFO, "\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void usbasp_close(PROGRAMMER * pgm)
+{
+ avrdude_message(MSG_DEBUG, "%s: usbasp_close()\n", progname);
+
+ if (PDATA(pgm)->usbhandle!=NULL) {
+ unsigned char temp[4];
+ memset(temp, 0, sizeof(temp));
+
+ if (PDATA(pgm)->use_tpi) {
+ usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_DISCONNECT, temp, temp, sizeof(temp));
+ } else {
+ usbasp_transmit(pgm, 1, USBASP_FUNC_DISCONNECT, temp, temp, sizeof(temp));
+ }
+
+#ifdef USE_LIBUSB_1_0
+ libusb_close(PDATA(pgm)->usbhandle);
+#else
+ usb_close(PDATA(pgm)->usbhandle);
+#endif
+ }
+#ifdef USE_LIBUSB_1_0
+ libusb_exit(ctx);
+#else
+ /* nothing for usb 0.1 ? */
+#endif
+}
+
+
+/* Dummy functions */
+static void usbasp_disable(PROGRAMMER * pgm)
+{
+ /* Do nothing. */
+
+ return;
+}
+
+static void usbasp_enable(PROGRAMMER * pgm)
+{
+ /* Do nothing. */
+
+ return;
+}
+
+static void usbasp_display(PROGRAMMER * pgm, const char * p)
+{
+ return;
+}
+
+
+/* Universal functions: for both SPI and TPI */
+static int usbasp_initialize(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char temp[4];
+ unsigned char res[4];
+ IMPORT_PDATA(pgm);
+
+ avrdude_message(MSG_DEBUG, "%s: usbasp_initialize()\n", progname);
+
+ /* get capabilities */
+ memset(temp, 0, sizeof(temp));
+ if(usbasp_transmit(pgm, 1, USBASP_FUNC_GETCAPABILITIES, temp, res, sizeof(res)) == 4)
+ pdata->capabilities = res[0] | ((unsigned int)res[1] << 8) | ((unsigned int)res[2] << 16) | ((unsigned int)res[3] << 24);
+ else
+ pdata->capabilities = 0;
+
+ pdata->use_tpi = ((pdata->capabilities & USBASP_CAP_TPI) != 0 && (p->flags & AVRPART_HAS_TPI) != 0) ? 1 : 0;
+
+ if(pdata->use_tpi)
+ {
+ /* calc tpiclk delay */
+ int dly = 1500000.0 * pgm->bitclock;
+ if(dly < 1)
+ dly = 1;
+ else if(dly > 2047)
+ dly = 2047;
+ temp[0] = dly;
+ temp[1] = dly >> 8;
+
+ /* connect */
+ usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_CONNECT, temp, res, sizeof(res));
+
+ /* change interface */
+ pgm->program_enable = usbasp_tpi_program_enable;
+ pgm->chip_erase = usbasp_tpi_chip_erase;
+ pgm->cmd = usbasp_tpi_cmd;
+ pgm->read_byte = usbasp_tpi_read_byte;
+ pgm->write_byte = usbasp_tpi_write_byte;
+ pgm->paged_write = usbasp_tpi_paged_write;
+ pgm->paged_load = usbasp_tpi_paged_load;
+ pgm->set_sck_period = usbasp_tpi_set_sck_period;
+ }
+ else
+ {
+ /* set sck period */
+ pgm->set_sck_period(pgm, pgm->bitclock);
+
+ /* connect to target device */
+ usbasp_transmit(pgm, 1, USBASP_FUNC_CONNECT, temp, res, sizeof(res));
+
+ /* change interface */
+ pgm->program_enable = usbasp_spi_program_enable;
+ pgm->chip_erase = usbasp_spi_chip_erase;
+ pgm->cmd = usbasp_spi_cmd;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+ pgm->paged_write = usbasp_spi_paged_write;
+ pgm->paged_load = usbasp_spi_paged_load;
+ pgm->set_sck_period = usbasp_spi_set_sck_period;
+ }
+
+ /* wait, so device is ready to receive commands */
+ usleep(100000);
+
+ return pgm->program_enable(pgm, p);
+}
+
+/* SPI specific functions */
+static int usbasp_spi_cmd(PROGRAMMER * pgm, const unsigned char *cmd,
+ unsigned char *res)
+{
+ avrdude_message(MSG_DEBUG, "%s: usbasp_spi_cmd(0x%02x, 0x%02x, 0x%02x, 0x%02x)%s",
+ progname, cmd[0], cmd[1], cmd[2], cmd[3],
+ verbose > 3? "...\n": "");
+
+ int nbytes =
+ usbasp_transmit(pgm, 1, USBASP_FUNC_TRANSMIT, cmd, res, 4);
+
+ if(nbytes != 4){
+ if (verbose == 3)
+ putc('\n', stderr);
+
+ avrdude_message(MSG_INFO, "%s: error: wrong responds size\n",
+ progname);
+ return -1;
+ }
+ avrdude_message(MSG_TRACE, "%s: usbasp_spi_cmd()", progname);
+ avrdude_message(MSG_DEBUG, " => 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
+ res[0], res[1], res[2], res[3]);
+
+ return 0;
+}
+
+static int usbasp_spi_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char res[4];
+ unsigned char cmd[4];
+ memset(cmd, 0, sizeof(cmd));
+ memset(res, 0, sizeof(res));
+
+ cmd[0] = 0;
+
+ avrdude_message(MSG_DEBUG, "%s: usbasp_program_enable()\n",
+ progname);
+
+ int nbytes =
+ usbasp_transmit(pgm, 1, USBASP_FUNC_ENABLEPROG, cmd, res, sizeof(res));
+
+ if ((nbytes != 1) | (res[0] != 0)) {
+ avrdude_message(MSG_INFO, "%s: error: program enable: target doesn't answer. %x \n",
+ progname, res[0]);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int usbasp_spi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char cmd[4];
+ unsigned char res[4];
+
+ avrdude_message(MSG_DEBUG, "%s: usbasp_chip_erase()\n",
+ progname);
+
+ if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
+ avrdude_message(MSG_INFO, "chip erase instruction not defined for part \"%s\"\n",
+ p->desc);
+ return -1;
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+
+ avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
+ pgm->cmd(pgm, cmd, res);
+ usleep(p->chip_erase_delay);
+ pgm->initialize(pgm, p);
+
+ return 0;
+}
+
+static int usbasp_spi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int address, unsigned int n_bytes)
+{
+ int n;
+ unsigned char cmd[4];
+ int wbytes = n_bytes;
+ int blocksize;
+ unsigned char *buffer = m->buf + address;
+ int function;
+
+ avrdude_message(MSG_DEBUG, "%s: usbasp_program_paged_load(\"%s\", 0x%x, %d)\n",
+ progname, m->desc, address, n_bytes);
+
+ if (strcmp(m->desc, "flash") == 0) {
+ function = USBASP_FUNC_READFLASH;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ function = USBASP_FUNC_READEEPROM;
+ } else {
+ return -2;
+ }
+
+ /* set blocksize depending on sck frequency */
+ if ((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) {
+ blocksize = USBASP_READBLOCKSIZE / 10;
+ } else {
+ blocksize = USBASP_READBLOCKSIZE;
+ }
+
+ while (wbytes) {
+ if (wbytes <= blocksize) {
+ blocksize = wbytes;
+ }
+ wbytes -= blocksize;
+
+ /* set address (new mode) - if firmware on usbasp support newmode, then they use address from this command */
+ unsigned char temp[4];
+ memset(temp, 0, sizeof(temp));
+ cmd[0] = address & 0xFF;
+ cmd[1] = address >> 8;
+ cmd[2] = address >> 16;
+ cmd[3] = address >> 24;
+ usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp));
+
+ /* send command with address (compatibility mode) - if firmware on
+ usbasp doesn't support newmode, then they use address from this */
+ cmd[0] = address & 0xFF;
+ cmd[1] = address >> 8;
+ // for compatibility - previous version of usbasp.c doesn't initialize this fields (firmware ignore it)
+ cmd[2] = 0;
+ cmd[3] = 0;
+
+ n = usbasp_transmit(pgm, 1, function, cmd, buffer, blocksize);
+
+ if (n != blocksize) {
+ avrdude_message(MSG_INFO, "%s: error: wrong reading bytes %x\n",
+ progname, n);
+ return -3;
+ }
+
+ buffer += blocksize;
+ address += blocksize;
+ }
+
+ return n_bytes;
+}
+
+static int usbasp_spi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int address, unsigned int n_bytes)
+{
+ int n;
+ unsigned char cmd[4];
+ int wbytes = n_bytes;
+ int blocksize;
+ unsigned char *buffer = m->buf + address;
+ unsigned char blockflags = USBASP_BLOCKFLAG_FIRST;
+ int function;
+
+ avrdude_message(MSG_DEBUG, "%s: usbasp_program_paged_write(\"%s\", 0x%x, %d)\n",
+ progname, m->desc, address, n_bytes);
+
+ if (strcmp(m->desc, "flash") == 0) {
+ function = USBASP_FUNC_WRITEFLASH;
+ } else if (strcmp(m->desc, "eeprom") == 0) {
+ function = USBASP_FUNC_WRITEEEPROM;
+ } else {
+ return -2;
+ }
+
+ /* set blocksize depending on sck frequency */
+ if ((PDATA(pgm)->sckfreq_hz > 0) && (PDATA(pgm)->sckfreq_hz < 10000)) {
+ blocksize = USBASP_WRITEBLOCKSIZE / 10;
+ } else {
+ blocksize = USBASP_WRITEBLOCKSIZE;
+ }
+
+ while (wbytes) {
+
+ if (wbytes <= blocksize) {
+ blocksize = wbytes;
+ }
+ wbytes -= blocksize;
+
+
+ /* set address (new mode) - if firmware on usbasp support newmode, then
+ they use address from this command */
+ unsigned char temp[4];
+ memset(temp, 0, sizeof(temp));
+ cmd[0] = address & 0xFF;
+ cmd[1] = address >> 8;
+ cmd[2] = address >> 16;
+ cmd[3] = address >> 24;
+ usbasp_transmit(pgm, 1, USBASP_FUNC_SETLONGADDRESS, cmd, temp, sizeof(temp));
+
+ /* normal command - firmware what support newmode - use address from previous command,
+ firmware what doesn't support newmode - ignore previous command and use address from this command */
+
+ cmd[0] = address & 0xFF;
+ cmd[1] = address >> 8;
+ cmd[2] = page_size & 0xFF;
+ cmd[3] = (blockflags & 0x0F) + ((page_size & 0xF00) >> 4); //TP: Mega128 fix
+ blockflags = 0;
+
+ n = usbasp_transmit(pgm, 0, function, cmd, buffer, blocksize);
+
+ if (n != blocksize) {
+ avrdude_message(MSG_INFO, "%s: error: wrong count at writing %x\n",
+ progname, n);
+ return -3;
+ }
+
+
+ buffer += blocksize;
+ address += blocksize;
+ }
+
+ return n_bytes;
+}
+
+/* The list of SCK frequencies in Hz supported by USBasp */
+static struct sckoptions_t usbaspSCKoptions[] = {
+ { USBASP_ISP_SCK_1500, 1500000 },
+ { USBASP_ISP_SCK_750, 750000 },
+ { USBASP_ISP_SCK_375, 375000 },
+ { USBASP_ISP_SCK_187_5, 187500 },
+ { USBASP_ISP_SCK_93_75, 93750 },
+ { USBASP_ISP_SCK_32, 32000 },
+ { USBASP_ISP_SCK_16, 16000 },
+ { USBASP_ISP_SCK_8, 8000 },
+ { USBASP_ISP_SCK_4, 4000 },
+ { USBASP_ISP_SCK_2, 2000 },
+ { USBASP_ISP_SCK_1, 1000 },
+ { USBASP_ISP_SCK_0_5, 500 }
+};
+
+/*
+ * Set sck period (in seconds)
+ * Find next possible sck period and write it to the programmer.
+ */
+static int usbasp_spi_set_sck_period(PROGRAMMER *pgm, double sckperiod)
+{
+ char clockoption = USBASP_ISP_SCK_AUTO;
+ unsigned char res[4];
+ unsigned char cmd[4];
+
+ avrdude_message(MSG_DEBUG, "%s: usbasp_spi_set_sck_period(%g)\n",
+ progname, sckperiod);
+
+ memset(cmd, 0, sizeof(cmd));
+ memset(res, 0, sizeof(res));
+
+ /* reset global sck frequency to auto */
+ PDATA(pgm)->sckfreq_hz = 0;
+
+ if (sckperiod == 0) {
+ /* auto sck set */
+
+ avrdude_message(MSG_NOTICE, "%s: auto set sck period (because given equals null)\n", progname);
+
+ } else {
+
+ int sckfreq = 1 / sckperiod; /* sck in Hz */
+ int usefreq = 0;
+
+ avrdude_message(MSG_NOTICE2, "%s: try to set SCK period to %g s (= %i Hz)\n", progname, sckperiod, sckfreq);
+
+ if (sckfreq >= usbaspSCKoptions[0].frequency) {
+ clockoption = usbaspSCKoptions[0].id;
+ usefreq = usbaspSCKoptions[0].frequency;
+ } else {
+
+ /* find clock option next to given clock */
+ int i;
+ for (i = 0; i < sizeof(usbaspSCKoptions) / sizeof(usbaspSCKoptions[0]); i++) {
+ if (sckfreq >= usbaspSCKoptions[i].frequency - 1) { /* subtract 1 to compensate round errors */
+ clockoption = usbaspSCKoptions[i].id;
+ usefreq = usbaspSCKoptions[i].frequency;
+ break;
+ }
+ }
+ }
+
+ /* save used sck frequency */
+ PDATA(pgm)->sckfreq_hz = usefreq;
+
+ avrdude_message(MSG_INFO, "%s: set SCK frequency to %i Hz\n", progname, usefreq);
+ }
+
+ cmd[0] = clockoption;
+
+ int nbytes =
+ usbasp_transmit(pgm, 1, USBASP_FUNC_SETISPSCK, cmd, res, sizeof(res));
+
+ if ((nbytes != 1) | (res[0] != 0)) {
+ avrdude_message(MSG_INFO, "%s: warning: cannot set sck period. please check for usbasp firmware update.\n",
+ progname);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* TPI specific functions */
+static void usbasp_tpi_send_byte(PROGRAMMER * pgm, uint8_t b)
+{
+ unsigned char temp[4];
+ memset(temp, 0, sizeof(temp));
+
+ temp[0] = b;
+
+ usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_RAWWRITE, temp, temp, sizeof(temp));
+}
+
+
+static int usbasp_tpi_recv_byte(PROGRAMMER * pgm)
+{
+ unsigned char temp[4];
+ memset(temp, 0, sizeof(temp));
+
+ if(usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_RAWREAD, temp, temp, sizeof(temp)) != 1)
+ {
+ avrdude_message(MSG_INFO, "%s: error: wrong responds size\n", progname);
+ return -1;
+ }
+
+ return temp[0];
+}
+
+
+static int usbasp_tpi_nvm_waitbusy(PROGRAMMER * pgm)
+{
+ int retry;
+
+ avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_nvm_waitbusy() ...", progname);
+
+ for(retry=50; retry>0; retry--)
+ {
+ usbasp_tpi_send_byte(pgm, TPI_OP_SIN(NVMCSR));
+ if(usbasp_tpi_recv_byte(pgm) & NVMCSR_BSY)
+ continue;
+
+ avrdude_message(MSG_DEBUG, " ready\n");
+
+ return 0;
+ }
+
+ avrdude_message(MSG_DEBUG, " failure\n");
+
+ return -1;
+}
+
+static int usbasp_tpi_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res)
+{
+ avrdude_message(MSG_INFO, "%s: error: spi_cmd used in TPI mode: not allowed\n", progname);
+ return -1;
+}
+
+static int usbasp_tpi_program_enable(PROGRAMMER * pgm, AVRPART * p)
+{
+ int retry;
+
+ avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_program_enable()\n", progname);
+
+ /* change guard time */
+ usbasp_tpi_send_byte(pgm, TPI_OP_SSTCS(TPIPCR));
+ usbasp_tpi_send_byte(pgm, TPIPCR_GT_2b);
+
+ /* send SKEY */
+ usbasp_tpi_send_byte(pgm, 0xE0);
+ usbasp_tpi_send_byte(pgm, 0xFF);
+ usbasp_tpi_send_byte(pgm, 0x88);
+ usbasp_tpi_send_byte(pgm, 0xD8);
+ usbasp_tpi_send_byte(pgm, 0xCD);
+ usbasp_tpi_send_byte(pgm, 0x45);
+ usbasp_tpi_send_byte(pgm, 0xAB);
+ usbasp_tpi_send_byte(pgm, 0x89);
+ usbasp_tpi_send_byte(pgm, 0x12);
+
+ /* check if device is ready */
+ for(retry=0; retry<10; retry++)
+ {
+ usbasp_tpi_send_byte(pgm, TPI_OP_SLDCS(TPIIR));
+ if(usbasp_tpi_recv_byte(pgm) != 0x80)
+ continue;
+ usbasp_tpi_send_byte(pgm, TPI_OP_SLDCS(TPISR));
+ if((usbasp_tpi_recv_byte(pgm) & TPISR_NVMEN) == 0)
+ continue;
+ break;
+ }
+ if(retry >= 10)
+ {
+ avrdude_message(MSG_INFO, "%s: error: program enable: target doesn't answer.\n", progname);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int usbasp_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_chip_erase()\n", progname);
+
+ /* Set PR to flash */
+ usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0));
+ usbasp_tpi_send_byte(pgm, 0x01);
+ usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1));
+ usbasp_tpi_send_byte(pgm, 0x40);
+ /* select ERASE */
+ usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD));
+ usbasp_tpi_send_byte(pgm, NVMCMD_CHIP_ERASE);
+ /* dummy write */
+ usbasp_tpi_send_byte(pgm, TPI_OP_SST_INC);
+ usbasp_tpi_send_byte(pgm, 0x00);
+ usbasp_tpi_nvm_waitbusy(pgm);
+
+ usleep(p->chip_erase_delay);
+ pgm->initialize(pgm, p);
+
+ return 0;
+}
+
+static int usbasp_tpi_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned char cmd[4];
+ unsigned char* dptr;
+ int readed, clen, n;
+ uint16_t pr;
+
+
+ avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_paged_load(\"%s\", 0x%0x, %d)\n",
+ progname, m->desc, addr, n_bytes);
+
+ dptr = addr + m->buf;
+ pr = addr + m->offset;
+ readed = 0;
+
+ while(readed < n_bytes)
+ {
+ clen = n_bytes - readed;
+ if(clen > 32)
+ clen = 32;
+
+ /* prepare READBLOCK cmd */
+ cmd[0] = pr & 0xFF;
+ cmd[1] = pr >> 8;
+ cmd[2] = 0;
+ cmd[3] = 0;
+ n = usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_READBLOCK, cmd, dptr, clen);
+ if(n != clen)
+ {
+ avrdude_message(MSG_INFO, "%s: error: wrong reading bytes %x\n", progname, n);
+ return -3;
+ }
+
+ readed += clen;
+ pr += clen;
+ dptr += clen;
+ }
+
+ return n_bytes;
+}
+
+static int usbasp_tpi_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned char cmd[4];
+ unsigned char* sptr;
+ int writed, clen, n;
+ uint16_t pr;
+
+
+ avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_paged_write(\"%s\", 0x%0x, %d)\n",
+ progname, m->desc, addr, n_bytes);
+
+ sptr = addr + m->buf;
+ pr = addr + m->offset;
+ writed = 0;
+
+ /* Set PR to flash */
+ usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0));
+ usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 );
+ usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1));
+ usbasp_tpi_send_byte(pgm, (pr >> 8) );
+
+ while(writed < n_bytes)
+ {
+ clen = n_bytes - writed;
+ if(clen > 32)
+ clen = 32;
+
+ /* prepare WRITEBLOCK cmd */
+ cmd[0] = pr & 0xFF;
+ cmd[1] = pr >> 8;
+ cmd[2] = 0;
+ cmd[3] = 0;
+ n = usbasp_transmit(pgm, 0, USBASP_FUNC_TPI_WRITEBLOCK, cmd, sptr, clen);
+ if(n != clen)
+ {
+ avrdude_message(MSG_INFO, "%s: error: wrong count at writing %x\n", progname, n);
+ return -3;
+ }
+
+ writed += clen;
+ pr += clen;
+ sptr += clen;
+ }
+
+ return n_bytes;
+}
+
+static int usbasp_tpi_set_sck_period(PROGRAMMER *pgm, double sckperiod)
+{
+ return 0;
+}
+static int usbasp_tpi_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char * value)
+{
+ unsigned char cmd[4];
+ int n;
+ uint16_t pr;
+
+
+ avrdude_message(MSG_DEBUG, "%s: usbasp_tpi_read_byte(\"%s\", 0x%0lx)\n",
+ progname, m->desc, addr);
+
+ pr = m->offset + addr;
+
+ /* READBLOCK */
+ cmd[0] = pr & 0xFF;
+ cmd[1] = pr >> 8;
+ cmd[2] = 0;
+ cmd[3] = 0;
+ n = usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_READBLOCK, cmd, value, 1);
+ if(n != 1)
+ {
+ avrdude_message(MSG_INFO, "%s: error: wrong reading bytes %x\n", progname, n);
+ return -3;
+ }
+ return 0;
+}
+
+static int usbasp_tpi_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned long addr, unsigned char data)
+{
+ avrdude_message(MSG_INFO, "%s: error: usbasp_write_byte in TPI mode: all writes have to be done at page level\n", progname);
+ return -1;
+}
+
+
+void usbasp_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "usbasp");
+
+ /*
+ * mandatory functions
+ */
+
+ pgm->initialize = usbasp_initialize;
+ pgm->display = usbasp_display;
+ pgm->enable = usbasp_enable;
+ pgm->disable = usbasp_disable;
+ pgm->program_enable = usbasp_spi_program_enable;
+ pgm->chip_erase = usbasp_spi_chip_erase;
+ pgm->cmd = usbasp_spi_cmd;
+ pgm->open = usbasp_open;
+ pgm->close = usbasp_close;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+
+ /*
+ * optional functions
+ */
+
+ pgm->paged_write = usbasp_spi_paged_write;
+ pgm->paged_load = usbasp_spi_paged_load;
+ pgm->setup = usbasp_setup;
+ pgm->teardown = usbasp_teardown;
+ pgm->set_sck_period = usbasp_spi_set_sck_period;
+
+}
+
+
+#else /* HAVE_LIBUSB */
+
+static int usbasp_nousb_open (struct programmer_t *pgm, char * name)
+{
+ avrdude_message(MSG_INFO, "%s: error: no usb support. please compile again with libusb installed.\n",
+ progname);
+
+ return -1;
+}
+
+void usbasp_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "usbasp");
+
+ pgm->open = usbasp_nousb_open;
+}
+
+#endif /* HAVE_LIBUSB */
+
+const char usbasp_desc[] = "USBasp programmer, see http://www.fischl.de/usbasp/";
+
diff --git a/xs/src/avrdude/usbasp.h b/xs/src/avrdude/usbasp.h
new file mode 100644
index 000000000..573d2b853
--- /dev/null
+++ b/xs/src/avrdude/usbasp.h
@@ -0,0 +1,137 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2006 Thomas Fischl
+ *
+ * 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 usbasp_h
+#define usbasp_h
+
+/* USB function call identifiers */
+#define USBASP_FUNC_CONNECT 1
+#define USBASP_FUNC_DISCONNECT 2
+#define USBASP_FUNC_TRANSMIT 3
+#define USBASP_FUNC_READFLASH 4
+#define USBASP_FUNC_ENABLEPROG 5
+#define USBASP_FUNC_WRITEFLASH 6
+#define USBASP_FUNC_READEEPROM 7
+#define USBASP_FUNC_WRITEEEPROM 8
+#define USBASP_FUNC_SETLONGADDRESS 9
+#define USBASP_FUNC_SETISPSCK 10
+#define USBASP_FUNC_TPI_CONNECT 11
+#define USBASP_FUNC_TPI_DISCONNECT 12
+#define USBASP_FUNC_TPI_RAWREAD 13
+#define USBASP_FUNC_TPI_RAWWRITE 14
+#define USBASP_FUNC_TPI_READBLOCK 15
+#define USBASP_FUNC_TPI_WRITEBLOCK 16
+#define USBASP_FUNC_GETCAPABILITIES 127
+
+/* USBASP capabilities */
+#define USBASP_CAP_TPI 0x01
+
+/* Block mode flags */
+#define USBASP_BLOCKFLAG_FIRST 1
+#define USBASP_BLOCKFLAG_LAST 2
+
+/* Block mode data size */
+#define USBASP_READBLOCKSIZE 200
+#define USBASP_WRITEBLOCKSIZE 200
+
+/* ISP SCK speed identifiers */
+#define USBASP_ISP_SCK_AUTO 0
+#define USBASP_ISP_SCK_0_5 1 /* 500 Hz */
+#define USBASP_ISP_SCK_1 2 /* 1 kHz */
+#define USBASP_ISP_SCK_2 3 /* 2 kHz */
+#define USBASP_ISP_SCK_4 4 /* 4 kHz */
+#define USBASP_ISP_SCK_8 5 /* 8 kHz */
+#define USBASP_ISP_SCK_16 6 /* 16 kHz */
+#define USBASP_ISP_SCK_32 7 /* 32 kHz */
+#define USBASP_ISP_SCK_93_75 8 /* 93.75 kHz */
+#define USBASP_ISP_SCK_187_5 9 /* 187.5 kHz */
+#define USBASP_ISP_SCK_375 10 /* 375 kHz */
+#define USBASP_ISP_SCK_750 11 /* 750 kHz */
+#define USBASP_ISP_SCK_1500 12 /* 1.5 MHz */
+
+/* TPI instructions */
+#define TPI_OP_SLD 0x20
+#define TPI_OP_SLD_INC 0x24
+#define TPI_OP_SST 0x60
+#define TPI_OP_SST_INC 0x64
+#define TPI_OP_SSTPR(a) (0x68 | (a))
+#define TPI_OP_SIN(a) (0x10 | (((a)<<1)&0x60) | ((a)&0x0F) )
+#define TPI_OP_SOUT(a) (0x90 | (((a)<<1)&0x60) | ((a)&0x0F) )
+#define TPI_OP_SLDCS(a) (0x80 | ((a)&0x0F) )
+#define TPI_OP_SSTCS(a) (0xC0 | ((a)&0x0F) )
+#define TPI_OP_SKEY 0xE0
+
+/* TPI control/status registers */
+#define TPIIR 0xF
+#define TPIPCR 0x2
+#define TPISR 0x0
+
+// TPIPCR bits
+#define TPIPCR_GT_2 0x04
+#define TPIPCR_GT_1 0x02
+#define TPIPCR_GT_0 0x01
+#define TPIPCR_GT_128b 0x00
+#define TPIPCR_GT_64b 0x01
+#define TPIPCR_GT_32b 0x02
+#define TPIPCR_GT_16b 0x03
+#define TPIPCR_GT_8b 0x04
+#define TPIPCR_GT_4b 0x05
+#define TPIPCR_GT_2b 0x06
+#define TPIPCR_GT_0b 0x07
+
+// TPISR bits
+#define TPISR_NVMEN 0x02
+
+/* NVM registers */
+#define NVMCSR 0x32
+#define NVMCMD 0x33
+
+// NVMCSR bits
+#define NVMCSR_BSY 0x80
+
+// NVMCMD values
+#define NVMCMD_NOP 0x00
+#define NVMCMD_CHIP_ERASE 0x10
+#define NVMCMD_SECTION_ERASE 0x14
+#define NVMCMD_WORD_WRITE 0x1D
+
+
+typedef struct sckoptions_t {
+ int id;
+ double frequency;
+} CLOCKOPTIONS;
+
+/* USB error identifiers */
+#define USB_ERROR_NOTFOUND 1
+#define USB_ERROR_ACCESS 2
+#define USB_ERROR_IO 3
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char usbasp_desc[];
+void usbasp_initpgm (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* usbasp_h */
diff --git a/xs/src/avrdude/usbdevs.h b/xs/src/avrdude/usbdevs.h
new file mode 100644
index 000000000..a3bc413ca
--- /dev/null
+++ b/xs/src/avrdude/usbdevs.h
@@ -0,0 +1,83 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2006 Joerg Wunsch
+ *
+ * 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$ */
+
+/*
+ * defines for the USB interface
+ */
+
+#ifndef usbdevs_h
+#define usbdevs_h
+
+#define USB_VENDOR_ATMEL 1003
+#define USB_DEVICE_JTAGICEMKII 0x2103
+#define USB_DEVICE_AVRISPMKII 0x2104
+#define USB_DEVICE_STK600 0x2106
+#define USB_DEVICE_AVRDRAGON 0x2107
+#define USB_DEVICE_JTAGICE3 0x2110
+#define USB_DEVICE_XPLAINEDPRO 0x2111
+#define USB_DEVICE_JTAG3_EDBG 0x2140
+#define USB_DEVICE_ATMEL_ICE 0x2141
+
+#define USB_VENDOR_FTDI 0x0403
+#define USB_DEVICE_FT2232 0x6010
+#define USB_DEVICE_FT245 0x6001
+
+#define USBASP_SHARED_VID 0x16C0 /* VOTI */
+#define USBASP_SHARED_PID 0x05DC /* Obdev's free shared PID */
+
+#define USBASP_OLD_VID 0x03EB /* ATMEL */
+#define USBASP_OLD_PID 0xC7B4 /* (unoffical) USBasp */
+
+#define USBASP_NIBOBEE_VID 0x16C0 /* VOTI */
+#define USBASP_NIBOBEE_PID 0x092F /* NIBObee PID */
+
+// these are specifically assigned to USBtiny,
+// if you need your own VID and PIDs you can get them for cheap from
+// www.mecanique.co.uk so please don't reuse these. Thanks!
+#define USBTINY_VENDOR_DEFAULT 0x1781
+#define USBTINY_PRODUCT_DEFAULT 0x0C9F
+
+
+
+/* JTAGICEmkII, AVRISPmkII */
+#define USBDEV_BULK_EP_WRITE_MKII 0x02
+#define USBDEV_BULK_EP_READ_MKII 0x82
+#define USBDEV_MAX_XFER_MKII 64
+
+/* STK600 */
+#define USBDEV_BULK_EP_WRITE_STK600 0x02
+#define USBDEV_BULK_EP_READ_STK600 0x83
+
+/* JTAGICE3 */
+#define USBDEV_BULK_EP_WRITE_3 0x01
+#define USBDEV_BULK_EP_READ_3 0x82
+#define USBDEV_EVT_EP_READ_3 0x83
+#define USBDEV_MAX_XFER_3 512
+
+/*
+ * When operating on the JTAGICE3, usbdev_recv_frame() returns an
+ * indication in the upper bits of the return value whether the
+ * message has been received from the event endpoint rather than the
+ * normal conversation endpoint.
+ */
+#define USB_RECV_LENGTH_MASK 0x0fff /* up to 4 KiB */
+#define USB_RECV_FLAG_EVENT 0x1000
+
+#endif /* usbdevs_h */
diff --git a/xs/src/avrdude/usbtiny.c b/xs/src/avrdude/usbtiny.c
new file mode 100644
index 000000000..b6bc7cc07
--- /dev/null
+++ b/xs/src/avrdude/usbtiny.c
@@ -0,0 +1,589 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2007 Dick Streefland, adapted for 5.4 by Limor Fried
+ *
+ * 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/>.
+ */
+
+/*
+ * Driver for "usbtiny"-type programmers
+ * Please see http://www.xs4all.nl/~dicks/avr/usbtiny/
+ * and http://www.ladyada.net/make/usbtinyisp/
+ * For example schematics and detailed documentation
+ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "usbtiny.h"
+#include "usbdevs.h"
+
+#if defined(HAVE_LIBUSB) // we use LIBUSB to talk to the board
+#if defined(HAVE_USB_H)
+# include <usb.h>
+#elif defined(HAVE_LUSB0_USB_H)
+# include <lusb0_usb.h>
+#else
+# error "libusb needs either <usb.h> or <lusb0_usb.h>"
+#endif
+
+#ifndef HAVE_UINT_T
+typedef unsigned int uint_t;
+#endif
+#ifndef HAVE_ULONG_T
+typedef unsigned long ulong_t;
+#endif
+
+extern int avr_write_byte_default ( PROGRAMMER* pgm, AVRPART* p,
+ AVRMEM* mem, ulong_t addr,
+ unsigned char data );
+/*
+ * Private data for this programmer.
+ */
+struct pdata
+{
+ usb_dev_handle *usb_handle;
+ int sck_period;
+ int chunk_size;
+ int retries;
+};
+
+#define PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
+// ----------------------------------------------------------------------
+
+static void usbtiny_setup(PROGRAMMER * pgm)
+{
+ if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) {
+ avrdude_message(MSG_INFO, "%s: usbtiny_setup(): Out of memory allocating private data\n",
+ progname);
+ exit(1);
+ }
+ memset(pgm->cookie, 0, sizeof(struct pdata));
+}
+
+static void usbtiny_teardown(PROGRAMMER * pgm)
+{
+ free(pgm->cookie);
+}
+
+// Wrapper for simple usb_control_msg messages
+static int usb_control (PROGRAMMER * pgm,
+ unsigned int requestid, unsigned int val, unsigned int index )
+{
+ int nbytes;
+ nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
+ USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ requestid,
+ val, index, // 2 bytes each of data
+ NULL, 0, // no data buffer in control messge
+ USB_TIMEOUT ); // default timeout
+ if(nbytes < 0){
+ avrdude_message(MSG_INFO, "\n%s: error: usbtiny_transmit: %s\n", progname, usb_strerror());
+ return -1;
+ }
+
+ return nbytes;
+}
+
+// Wrapper for simple usb_control_msg messages to receive data from programmer
+static int usb_in (PROGRAMMER * pgm,
+ unsigned int requestid, unsigned int val, unsigned int index,
+ unsigned char* buffer, int buflen, int bitclk )
+{
+ int nbytes;
+ int timeout;
+ int i;
+
+ // calculate the amout of time we expect the process to take by
+ // figuring the bit-clock time and buffer size and adding to the standard USB timeout.
+ timeout = USB_TIMEOUT + (buflen * bitclk) / 1000;
+
+ for (i = 0; i < 10; i++) {
+ nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
+ USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ requestid,
+ val, index,
+ (char *)buffer, buflen,
+ timeout);
+ if (nbytes == buflen) {
+ return nbytes;
+ }
+ PDATA(pgm)->retries++;
+ }
+ avrdude_message(MSG_INFO, "\n%s: error: usbtiny_receive: %s (expected %d, got %d)\n",
+ progname, usb_strerror(), buflen, nbytes);
+ return -1;
+}
+
+// Report the number of retries, and reset the counter.
+static void check_retries (PROGRAMMER * pgm, const char* operation)
+{
+ if (PDATA(pgm)->retries > 0 && quell_progress < 2) {
+ avrdude_message(MSG_INFO, "%s: %d retries during %s\n", progname,
+ PDATA(pgm)->retries, operation);
+ }
+ PDATA(pgm)->retries = 0;
+}
+
+// Wrapper for simple usb_control_msg messages to send data to programmer
+static int usb_out (PROGRAMMER * pgm,
+ unsigned int requestid, unsigned int val, unsigned int index,
+ unsigned char* buffer, int buflen, int bitclk )
+{
+ int nbytes;
+ int timeout;
+
+ // calculate the amout of time we expect the process to take by
+ // figuring the bit-clock time and buffer size and adding to the standard USB timeout.
+ timeout = USB_TIMEOUT + (buflen * bitclk) / 1000;
+
+ nbytes = usb_control_msg( PDATA(pgm)->usb_handle,
+ USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ requestid,
+ val, index,
+ (char *)buffer, buflen,
+ timeout);
+ if (nbytes != buflen) {
+ avrdude_message(MSG_INFO, "\n%s: error: usbtiny_send: %s (expected %d, got %d)\n",
+ progname, usb_strerror(), buflen, nbytes);
+ return -1;
+ }
+
+ return nbytes;
+}
+
+// Sometimes we just need to know the SPI command for the part to perform
+// a function. Here we wrap this request for an operation so that we
+// can just specify the part and operation and it'll do the right stuff
+// to get the information from AvrDude and send to the USBtiny
+static int usbtiny_avr_op (PROGRAMMER * pgm, AVRPART * p,
+ int op,
+ unsigned char *res)
+{
+ unsigned char cmd[4];
+
+ if (p->op[op] == NULL) {
+ avrdude_message(MSG_INFO, "Operation %d not defined for this chip!\n", op );
+ return -1;
+ }
+ memset(cmd, 0, sizeof(cmd));
+ avr_set_bits(p->op[op], cmd);
+
+ return pgm->cmd(pgm, cmd, res);
+}
+
+// ----------------------------------------------------------------------
+
+/* Find a device with the correct VID/PID match for USBtiny */
+
+static int usbtiny_open(PROGRAMMER* pgm, char* name)
+{
+ struct usb_bus *bus;
+ struct usb_device *dev = 0;
+ char *bus_name = NULL;
+ char *dev_name = NULL;
+ int vid, pid;
+
+ // if no -P was given or '-P usb' was given
+ if(strcmp(name, "usb") == 0)
+ name = NULL;
+ else {
+ // calculate bus and device names from -P option
+ const size_t usb_len = strlen("usb");
+ if(strncmp(name, "usb", usb_len) == 0 && ':' == name[usb_len]) {
+ bus_name = name + usb_len + 1;
+ dev_name = strchr(bus_name, ':');
+ if(NULL != dev_name)
+ *dev_name++ = '\0';
+ }
+ }
+
+ usb_init(); // initialize the libusb system
+ usb_find_busses(); // have libusb scan all the usb busses available
+ usb_find_devices(); // have libusb scan all the usb devices available
+
+ PDATA(pgm)->usb_handle = NULL;
+
+ if (pgm->usbvid)
+ vid = pgm->usbvid;
+ else
+ vid = USBTINY_VENDOR_DEFAULT;
+
+ LNODEID usbpid = lfirst(pgm->usbpid);
+ if (usbpid) {
+ pid = *(int *)(ldata(usbpid));
+ if (lnext(usbpid))
+ avrdude_message(MSG_INFO, "%s: Warning: using PID 0x%04x, ignoring remaining PIDs in list\n",
+ progname, pid);
+ } else {
+ pid = USBTINY_PRODUCT_DEFAULT;
+ }
+
+
+ // now we iterate through all the busses and devices
+ for ( bus = usb_busses; bus; bus = bus->next ) {
+ for ( dev = bus->devices; dev; dev = dev->next ) {
+ if (dev->descriptor.idVendor == vid
+ && dev->descriptor.idProduct == pid ) { // found match?
+ avrdude_message(MSG_NOTICE, "%s: usbdev_open(): Found USBtinyISP, bus:device: %s:%s\n",
+ progname, bus->dirname, dev->filename);
+ // if -P was given, match device by device name and bus name
+ if(name != NULL &&
+ (NULL == dev_name ||
+ strcmp(bus->dirname, bus_name) ||
+ strcmp(dev->filename, dev_name)))
+ continue;
+ PDATA(pgm)->usb_handle = usb_open(dev); // attempt to connect to device
+
+ // wrong permissions or something?
+ if (!PDATA(pgm)->usb_handle) {
+ avrdude_message(MSG_INFO, "%s: Warning: cannot open USB device: %s\n",
+ progname, usb_strerror());
+ continue;
+ }
+ }
+ }
+ }
+
+ if(NULL != name && NULL == dev_name) {
+ avrdude_message(MSG_INFO, "%s: Error: Invalid -P value: '%s'\n", progname, name);
+ avrdude_message(MSG_INFO, "%sUse -P usb:bus:device\n", progbuf);
+ return -1;
+ }
+ if (!PDATA(pgm)->usb_handle) {
+ avrdude_message(MSG_INFO, "%s: Error: Could not find USBtiny device (0x%x/0x%x)\n",
+ progname, vid, pid );
+ return -1;
+ }
+
+ return 0; // If we got here, we must have found a good USB device
+}
+
+/* Clean up the handle for the usbtiny */
+static void usbtiny_close ( PROGRAMMER* pgm )
+{
+ if (! PDATA(pgm)->usb_handle) {
+ return; // not a valid handle, bail!
+ }
+ usb_close(PDATA(pgm)->usb_handle); // ask libusb to clean up
+ PDATA(pgm)->usb_handle = NULL;
+}
+
+/* A simple calculator function determines the maximum size of data we can
+ shove through a USB connection without getting errors */
+static void usbtiny_set_chunk_size (PROGRAMMER * pgm, int period)
+{
+ PDATA(pgm)->chunk_size = CHUNK_SIZE; // start with the maximum (default)
+ while (PDATA(pgm)->chunk_size > 8 && period > 16) {
+ // Reduce the chunk size for a slow SCK to reduce
+ // the maximum time of a single USB transfer.
+ PDATA(pgm)->chunk_size >>= 1;
+ period >>= 1;
+ }
+}
+
+/* Given a SCK bit-clock speed (in useconds) we verify its an OK speed and tell the
+ USBtiny to update itself to the new frequency */
+static int usbtiny_set_sck_period (PROGRAMMER *pgm, double v)
+{
+ PDATA(pgm)->sck_period = (int)(v * 1e6 + 0.5); // convert from us to 'int', the 0.5 is for rounding up
+
+ // Make sure its not 0, as that will confuse the usbtiny
+ if (PDATA(pgm)->sck_period < SCK_MIN)
+ PDATA(pgm)->sck_period = SCK_MIN;
+
+ // We can't go slower, due to the byte-size of the clock variable
+ if (PDATA(pgm)->sck_period > SCK_MAX)
+ PDATA(pgm)->sck_period = SCK_MAX;
+
+ avrdude_message(MSG_NOTICE, "%s: Setting SCK period to %d usec\n", progname,
+ PDATA(pgm)->sck_period );
+
+ // send the command to the usbtiny device.
+ // MEME: for at90's fix resetstate?
+ if (usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_LOW) < 0)
+ return -1;
+
+ // with the new speed, we'll have to update how much data we send per usb transfer
+ usbtiny_set_chunk_size(pgm, PDATA(pgm)->sck_period);
+ return 0;
+}
+
+
+static int usbtiny_initialize (PROGRAMMER *pgm, AVRPART *p )
+{
+ unsigned char res[4]; // store the response from usbtinyisp
+
+ // Check for bit-clock and tell the usbtiny to adjust itself
+ if (pgm->bitclock > 0.0) {
+ // -B option specified: convert to valid range for sck_period
+ usbtiny_set_sck_period(pgm, pgm->bitclock);
+ } else {
+ // -B option not specified: use default
+ PDATA(pgm)->sck_period = SCK_DEFAULT;
+ avrdude_message(MSG_NOTICE, "%s: Using SCK period of %d usec\n",
+ progname, PDATA(pgm)->sck_period );
+ if (usb_control(pgm, USBTINY_POWERUP,
+ PDATA(pgm)->sck_period, RESET_LOW ) < 0)
+ return -1;
+ usbtiny_set_chunk_size(pgm, PDATA(pgm)->sck_period);
+ }
+
+ // Let the device wake up.
+ usleep(50000);
+
+ // Attempt to use the underlying avrdude methods to connect (MEME: is this kosher?)
+ if (! usbtiny_avr_op(pgm, p, AVR_OP_PGM_ENABLE, res)) {
+ // no response, RESET and try again
+ if (usb_control(pgm, USBTINY_POWERUP,
+ PDATA(pgm)->sck_period, RESET_HIGH) < 0 ||
+ usb_control(pgm, USBTINY_POWERUP,
+ PDATA(pgm)->sck_period, RESET_LOW) < 0)
+ return -1;
+ usleep(50000);
+ if ( ! usbtiny_avr_op( pgm, p, AVR_OP_PGM_ENABLE, res)) {
+ // give up
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/* Tell the USBtiny to release the output pins, etc */
+static void usbtiny_powerdown(PROGRAMMER * pgm)
+{
+ if (!PDATA(pgm)->usb_handle) {
+ return; // wasn't connected in the first place
+ }
+ usb_control(pgm, USBTINY_POWERDOWN, 0, 0); // Send USB control command to device
+}
+
+/* Send a 4-byte SPI command to the USBtinyISP for execution
+ This procedure is used by higher-level Avrdude procedures */
+static int usbtiny_cmd(PROGRAMMER * pgm, const unsigned char *cmd, unsigned char *res)
+{
+ int nbytes;
+
+ // Make sure its empty so we don't read previous calls if it fails
+ memset(res, '\0', 4 );
+
+ nbytes = usb_in( pgm, USBTINY_SPI,
+ (cmd[1] << 8) | cmd[0], // convert to 16-bit words
+ (cmd[3] << 8) | cmd[2], // "
+ res, 4, 8 * PDATA(pgm)->sck_period );
+ if (nbytes < 0)
+ return -1;
+ check_retries(pgm, "SPI command");
+ // print out the data we sent and received
+ avrdude_message(MSG_NOTICE2, "CMD: [%02x %02x %02x %02x] [%02x %02x %02x %02x]\n",
+ cmd[0], cmd[1], cmd[2], cmd[3],
+ res[0], res[1], res[2], res[3] );
+ return ((nbytes == 4) && // should have read 4 bytes
+ res[2] == cmd[1]); // AVR's do a delayed-echo thing
+}
+
+/* Send the chip-erase command */
+static int usbtiny_chip_erase(PROGRAMMER * pgm, AVRPART * p)
+{
+ unsigned char res[4];
+
+ if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
+ avrdude_message(MSG_INFO, "Chip erase instruction not defined for part \"%s\"\n",
+ p->desc);
+ return -1;
+ }
+
+ // get the command for erasing this chip and transmit to avrdude
+ if (! usbtiny_avr_op( pgm, p, AVR_OP_CHIP_ERASE, res )) {
+ return -1;
+ }
+ usleep( p->chip_erase_delay );
+
+ // prepare for further instruction
+ pgm->initialize(pgm, p);
+
+ return 0;
+}
+
+// These are required functions but don't actually do anything
+static void usbtiny_enable ( PROGRAMMER* pgm ) {}
+
+static void usbtiny_disable ( PROGRAMMER* pgm ) {}
+
+
+/* To speed up programming and reading, we do a 'chunked' read.
+ * We request just the data itself and the USBtiny uses the SPI function
+ * given to read in the data. Much faster than sending a 4-byte SPI request
+ * per byte
+*/
+static int usbtiny_paged_load (PROGRAMMER * pgm, AVRPART * p, AVRMEM* m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned int maxaddr = addr + n_bytes;
+ int chunk;
+ int function;
+
+
+ // First determine what we're doing
+ if (strcmp( m->desc, "flash" ) == 0) {
+ function = USBTINY_FLASH_READ;
+ } else {
+ function = USBTINY_EEPROM_READ;
+ }
+
+ for (; addr < maxaddr; addr += chunk) {
+ chunk = PDATA(pgm)->chunk_size; // start with the maximum chunk size possible
+
+ // Send the chunk of data to the USBtiny with the function we want
+ // to perform
+ if (usb_in(pgm,
+ function, // EEPROM or flash
+ 0, // delay between SPI commands
+ addr, // address in memory
+ m->buf + addr, // pointer to where we store data
+ chunk, // number of bytes
+ 32 * PDATA(pgm)->sck_period) // each byte gets turned into a 4-byte SPI cmd
+ < 0) {
+ // usb_in() multiplies this per byte.
+ return -1;
+ }
+ }
+
+ check_retries(pgm, "read");
+ return n_bytes;
+}
+
+/* To speed up programming and reading, we do a 'chunked' write.
+ * We send just the data itself and the USBtiny uses the SPI function
+ * given to write the data. Much faster than sending a 4-byte SPI request
+ * per byte.
+*/
+static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
+ unsigned int page_size,
+ unsigned int addr, unsigned int n_bytes)
+{
+ unsigned int maxaddr = addr + n_bytes;
+ int chunk; // Size of data to write at once
+ int next;
+ int function; // which SPI command to use
+ int delay; // delay required between SPI commands
+
+ // First determine what we're doing
+ if (strcmp( m->desc, "flash" ) == 0) {
+ function = USBTINY_FLASH_WRITE;
+ } else {
+ function = USBTINY_EEPROM_WRITE;
+ }
+
+ delay = 0;
+ if (! m->paged) {
+ unsigned int poll_value;
+ // Does this chip not support paged writes?
+ poll_value = (m->readback[1] << 8) | m->readback[0];
+ if (usb_control(pgm, USBTINY_POLL_BYTES, poll_value, 0 ) < 0)
+ return -1;
+ delay = m->max_write_delay;
+ }
+
+ for (; addr < maxaddr; addr += chunk) {
+ // start with the max chunk size
+ chunk = PDATA(pgm)->chunk_size;
+
+ // we can only write a page at a time anyways
+ if (m->paged && chunk > page_size)
+ chunk = page_size;
+
+ if (usb_out(pgm,
+ function, // Flash or EEPROM
+ delay, // How much to wait between each byte
+ addr, // Address in memory
+ m->buf + addr, // Pointer to data
+ chunk, // Number of bytes to write
+ 32 * PDATA(pgm)->sck_period + delay // each byte gets turned into a
+ // 4-byte SPI cmd usb_out() multiplies
+ // this per byte. Then add the cmd-delay
+ ) < 0) {
+ return -1;
+ }
+
+ next = addr + chunk; // Calculate what address we're at now
+ if (m->paged
+ && ((next % page_size) == 0 || next == maxaddr) ) {
+ // If we're at a page boundary, send the SPI command to flush it.
+ avr_write_page(pgm, p, m, (unsigned long) addr);
+ }
+ }
+ return n_bytes;
+}
+
+void usbtiny_initpgm ( PROGRAMMER* pgm )
+{
+ strcpy(pgm->type, "USBtiny");
+
+ /* Mandatory Functions */
+ pgm->initialize = usbtiny_initialize;
+ pgm->enable = usbtiny_enable;
+ pgm->disable = usbtiny_disable;
+ pgm->program_enable = NULL;
+ pgm->chip_erase = usbtiny_chip_erase;
+ pgm->cmd = usbtiny_cmd;
+ pgm->open = usbtiny_open;
+ pgm->close = usbtiny_close;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+
+ /* Optional Functions */
+ pgm->powerup = NULL;
+ pgm->powerdown = usbtiny_powerdown;
+ pgm->paged_load = usbtiny_paged_load;
+ pgm->paged_write = usbtiny_paged_write;
+ pgm->set_sck_period = usbtiny_set_sck_period;
+ pgm->setup = usbtiny_setup;
+ pgm->teardown = usbtiny_teardown;
+}
+
+#else /* !HAVE_LIBUSB */
+
+// Give a proper error if we were not compiled with libusb
+
+static int usbtiny_nousb_open(struct programmer_t *pgm, char * name)
+{
+ avrdude_message(MSG_INFO, "%s: error: no usb support. Please compile again with libusb installed.\n",
+ progname);
+
+ return -1;
+}
+
+void usbtiny_initpgm(PROGRAMMER * pgm)
+{
+ strcpy(pgm->type, "usbtiny");
+
+ pgm->open = usbtiny_nousb_open;
+}
+
+#endif /* HAVE_LIBUSB */
+
+const char usbtiny_desc[] = "Driver for \"usbtiny\"-type programmers";
+
diff --git a/xs/src/avrdude/usbtiny.h b/xs/src/avrdude/usbtiny.h
new file mode 100644
index 000000000..3a258b9f1
--- /dev/null
+++ b/xs/src/avrdude/usbtiny.h
@@ -0,0 +1,68 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2007 Limor Fried
+ *
+ * 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/>.
+ */
+
+
+#ifndef usbtiny_h
+#define usbtiny_h
+
+// Generic requests to the USBtiny
+#define USBTINY_ECHO 0 // echo test
+#define USBTINY_READ 1 // read byte (wIndex:address)
+#define USBTINY_WRITE 2 // write byte (wIndex:address, wValue:value)
+#define USBTINY_CLR 3 // clear bit (wIndex:address, wValue:bitno)
+#define USBTINY_SET 4 // set bit (wIndex:address, wValue:bitno)
+
+// Programming requests
+#define USBTINY_POWERUP 5 // apply power (wValue:SCK-period, wIndex:RESET)
+#define USBTINY_POWERDOWN 6 // remove power from chip
+#define USBTINY_SPI 7 // issue SPI command (wValue:c1c0, wIndex:c3c2)
+#define USBTINY_POLL_BYTES 8 // set poll bytes for write (wValue:p1p2)
+#define USBTINY_FLASH_READ 9 // read flash (wIndex:address)
+#define USBTINY_FLASH_WRITE 10 // write flash (wIndex:address, wValue:timeout)
+#define USBTINY_EEPROM_READ 11 // read eeprom (wIndex:address)
+#define USBTINY_EEPROM_WRITE 12 // write eeprom (wIndex:address, wValue:timeout)
+
+
+
+// Flags to indicate how to set RESET on power up
+#define RESET_LOW 0
+#define RESET_HIGH 1
+
+// The SCK speed can be set by avrdude, to allow programming of slow-clocked parts
+#define SCK_MIN 1 // usec delay (target clock >= 4 MHz)
+#define SCK_MAX 250 // usec (target clock >= 16 KHz)
+#define SCK_DEFAULT 10 // usec (target clock >= 0.4 MHz)
+
+// How much data, max, do we want to send in one USB packet?
+#define CHUNK_SIZE 128 // must be power of 2 less than 256
+
+// The default USB Timeout
+#define USB_TIMEOUT 500 // msec
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char usbtiny_desc[];
+void usbtiny_initpgm (PROGRAMMER * pgm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* usbtiny_h */
diff --git a/xs/src/avrdude/windows/.cvsignore b/xs/src/avrdude/windows/.cvsignore
new file mode 100644
index 000000000..601c4fbff
--- /dev/null
+++ b/xs/src/avrdude/windows/.cvsignore
@@ -0,0 +1,4 @@
+.cvsignore
+.deps
+Makefile
+Makefile.in
diff --git a/xs/src/avrdude/windows/Makefile.am b/xs/src/avrdude/windows/Makefile.am
new file mode 100644
index 000000000..9890fd05f
--- /dev/null
+++ b/xs/src/avrdude/windows/Makefile.am
@@ -0,0 +1,57 @@
+#
+# avrdude - A Downloader/Uploader for AVR device programmers
+# Copyright (C) 2003 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$
+#
+
+#
+# This Makefile will only be used on windows based systems.
+#
+
+local_install_list = \
+ giveio.sys \
+ install_giveio.bat \
+ remove_giveio.bat \
+ status_giveio.bat
+
+EXTRA_DIST = \
+ giveio.c \
+ $(local_install_list)
+
+bin_PROGRAMS = loaddrv
+
+loaddrv_SOURCES = \
+ loaddrv.c \
+ loaddrv.h
+
+install-exec-local:
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(local_install_list)'; for file in $$list; do \
+ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) \
+ $(srcdir)/$$file $(DESTDIR)$(bindir)/$$file"; \
+ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $(srcdir)/$$file \
+ $(DESTDIR)$(bindir)/$$file; \
+ done
+
+uninstall-local:
+ @for file in $(local_install_list); do \
+ echo " rm -f $(DESTDIR)$(bindir)/$$file"; \
+ rm -f $(DESTDIR)$(bindir)/$$file; \
+ done
+
diff --git a/xs/src/avrdude/windows/getopt.c b/xs/src/avrdude/windows/getopt.c
new file mode 100644
index 000000000..cfa302335
--- /dev/null
+++ b/xs/src/avrdude/windows/getopt.c
@@ -0,0 +1,1258 @@
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+ Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+# ifndef const
+# define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library. */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+# include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages. */
+# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
+# include <libintl.h>
+# ifndef _
+# define _(msgid) gettext (msgid)
+# endif
+# else
+# define _(msgid) (msgid)
+# endif
+# if defined _LIBC && defined USE_IN_LIBIO
+# include <wchar.h>
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+int __getopt_initialized;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+# include <string.h>
+# define my_index strchr
+#else
+
+# if HAVE_STRING_H || WIN32 /* Pete Wilson mod 7/28/02 */
+# include <string.h>
+# else
+# include <strings.h>
+# endif
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Stored original parameters.
+ XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+extern int __libc_argc;
+extern char **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+# define SWAP_FLAGS(ch1, ch2) \
+ if (nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+# else
+# define SWAP_FLAGS(ch1, ch2)
+# endif
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = malloc (top + 1);
+ if (new_str == NULL)
+ nonoption_flags_len = nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ nonoption_flags_max_len),
+ '\0', top + 1 - nonoption_flags_max_len);
+ nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ if (posixly_correct == NULL
+ && argc == __libc_argc && argv == __libc_argv)
+ {
+ if (nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = nonoption_flags_max_len = strlen (orig_str);
+ if (nonoption_flags_max_len < argc)
+ nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', nonoption_flags_max_len - len);
+ }
+ }
+ nonoption_flags_len = nonoption_flags_max_len;
+ }
+ else
+ nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ int print_errors = opterr;
+ if (optstring[0] == ':')
+ print_errors = 0;
+
+ if (argc < 1)
+ return -1;
+
+ optarg = NULL;
+
+ if (optind == 0 || !__getopt_initialized)
+ {
+ if (optind == 0)
+ optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
+ || (optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT and LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > optind)
+ last_nonopt = optind;
+ if (first_nonopt > optind)
+ first_nonopt = optind;
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc && NONOPTION_P)
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else if (long_only
+ || pfound->has_arg != p->has_arg
+ || pfound->flag != p->flag
+ || pfound->val != p->val)
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+#endif
+ }
+ nextchar += strlen (nextchar);
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+#endif
+
+ if (argv[optind - 1][1] == '-')
+ {
+ /* --option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("\
+%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#else
+ fprintf (stderr, _("\
+%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#endif
+ }
+ else
+ {
+ /* +option or -option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("\
+%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0],
+ pfound->name);
+#else
+ fprintf (stderr, _("\
+%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0], pfound->name);
+#endif
+ }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#endif
+ }
+
+ nextchar += strlen (nextchar);
+
+ optopt = pfound->val;
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+#endif
+ }
+ nextchar += strlen (nextchar);
+ optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+#endif
+
+ if (argv[optind][1] == '-')
+ {
+ /* --option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+#else
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+#endif
+ }
+ else
+ {
+ /* +option or -option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+#else
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+#endif
+ }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#endif
+ }
+ nextchar = (char *) "";
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+#endif
+
+ if (posixly_correct)
+ {
+ /* 1003.2 specifies the format of this message. */
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+#else
+ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
+#endif
+ }
+ else
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+#else
+ fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
+#endif
+ }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#endif
+ }
+ optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+#endif
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+#endif
+ }
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#endif
+ }
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf, _("\
+%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+#endif
+ }
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+#endif
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* Not ELIDE_CODE. */
+
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+/* #define TEST */ /* Pete Wilson mod 7/28/02 */
+#ifdef TEST
+
+#ifndef exit /* Pete Wilson mod 7/28/02 */
+ int exit(int); /* Pete Wilson mod 7/28/02 */
+#endif /* Pete Wilson mod 7/28/02 */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/xs/src/avrdude/windows/getopt.h b/xs/src/avrdude/windows/getopt.h
new file mode 100644
index 000000000..8a45c8b13
--- /dev/null
+++ b/xs/src/avrdude/windows/getopt.h
@@ -0,0 +1,188 @@
+
+/* getopt.h */
+/* Declarations for getopt.
+ Copyright (C) 1989-1994, 1996-1999, 2001 Free Software
+ Foundation, Inc. This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute
+ it and/or modify it under the terms of the GNU Lesser
+ General Public License as published by the Free Software
+ Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ The GNU C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with the GNU C Library; if not, write
+ to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA. */
+
+
+
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+ standalone, or this is the first header included in the source file.
+ If we are being used with glibc, we need to include <features.h>, but
+ that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
+ not defined, include <ctype.h>, which will pull in <features.h> for us
+ if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
+ doesn't flood the namespace with stuff the way some other headers do.) */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+# if (defined __STDC__ && __STDC__) || defined __cplusplus
+ const char *name;
+# else
+ char *name;
+# endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+ arguments in ARGV (ARGC of them, minus the program name) for
+ options given in OPTS.
+
+ Return the option character from OPTS just read. Return -1 when
+ there are no more options. For unrecognized options, or options
+ missing arguments, `optopt' is set to the option letter, and '?' is
+ returned.
+
+ The OPTS string is a list of characters which are recognized option
+ letters, optionally followed by colons, specifying that that letter
+ takes an argument, to be placed in `optarg'.
+
+ If a letter in OPTS is followed by two colons, its argument is
+ optional. This behavior is specific to the GNU `getopt'.
+
+ The argument `--' causes premature termination of argument
+ scanning, explicitly telling `getopt' that there are no more
+ options.
+
+ If OPTS begins with `--', then non-option arguments are treated as
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `getopt'. */
+
+#if (defined __STDC__ && __STDC__) || defined __cplusplus
+# ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
+# else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+# endif /* __GNU_LIBRARY__ */
+
+# ifndef __need_getopt
+extern int getopt_long (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+extern int getopt_long_only (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only);
+# endif
+#else /* not __STDC__ */
+extern int getopt ();
+# ifndef __need_getopt
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+# endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations. */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/xs/src/avrdude/windows/giveio.c b/xs/src/avrdude/windows/giveio.c
new file mode 100644
index 000000000..f752a2937
--- /dev/null
+++ b/xs/src/avrdude/windows/giveio.c
@@ -0,0 +1,168 @@
+/*********************************************************************
+
+Author: Dale Roberts
+Date: 8/30/95
+Program: GIVEIO.SYS
+Compile: Use DDK BUILD facility
+
+Purpose: Give direct port I/O access to a user mode process.
+
+*********************************************************************/
+#include <ntddk.h>
+
+/*
+ * The name of our device driver.
+ */
+#define DEVICE_NAME_STRING L"giveio"
+
+/*
+ * This is the "structure" of the IOPM. It is just a simple
+ * character array of length 0x2000.
+ *
+ * This holds 8K * 8 bits -> 64K bits of the IOPM, which maps the
+ * entire 64K I/O space of the x86 processor. Any 0 bits will give
+ * access to the corresponding port for user mode processes. Any 1
+ * bits will disallow I/O access to the corresponding port.
+ */
+#define IOPM_SIZE 0x2000
+typedef UCHAR IOPM[IOPM_SIZE];
+
+/*
+ * This will hold simply an array of 0's which will be copied
+ * into our actual IOPM in the TSS by Ke386SetIoAccessMap().
+ * The memory is allocated at driver load time.
+ */
+IOPM *IOPM_local = 0;
+
+/*
+ * These are the two undocumented calls that we will use to give
+ * the calling process I/O access.
+ *
+ * Ke386IoSetAccessMap() copies the passed map to the TSS.
+ *
+ * Ke386IoSetAccessProcess() adjusts the IOPM offset pointer so that
+ * the newly copied map is actually used. Otherwise, the IOPM offset
+ * points beyond the end of the TSS segment limit, causing any I/O
+ * access by the user mode process to generate an exception.
+ */
+void Ke386SetIoAccessMap(int, IOPM *);
+void Ke386QueryIoAccessMap(int, IOPM *);
+void Ke386IoSetAccessProcess(PEPROCESS, int);
+
+/*********************************************************************
+ Release any allocated objects.
+*********************************************************************/
+VOID GiveioUnload(IN PDRIVER_OBJECT DriverObject)
+{
+ WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING;
+ UNICODE_STRING uniDOSString;
+
+ if(IOPM_local)
+ MmFreeNonCachedMemory(IOPM_local, sizeof(IOPM));
+
+ RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);
+ IoDeleteSymbolicLink (&uniDOSString);
+ IoDeleteDevice(DriverObject->DeviceObject);
+}
+
+/*********************************************************************
+ Set the IOPM (I/O permission map) of the calling process so that it
+is given full I/O access. Our IOPM_local[] array is all zeros, so
+the IOPM will be all zeros. If OnFlag is 1, the process is given I/O
+access. If it is 0, access is removed.
+*********************************************************************/
+VOID SetIOPermissionMap(int OnFlag)
+{
+ Ke386IoSetAccessProcess(PsGetCurrentProcess(), OnFlag);
+ Ke386SetIoAccessMap(1, IOPM_local);
+}
+
+void GiveIO(void)
+{
+ SetIOPermissionMap(1);
+}
+
+/*********************************************************************
+ Service handler for a CreateFile() user mode call.
+
+ This routine is entered in the driver object function call table by
+the DriverEntry() routine. When the user mode application calls
+CreateFile(), this routine gets called while still in the context of
+the user mode application, but with the CPL (the processor's Current
+Privelege Level) set to 0. This allows us to do kernel mode
+operations. GiveIO() is called to give the calling process I/O
+access. All the user mode application needs do to obtain I/O access
+is open this device with CreateFile(). No other operations are
+required.
+*********************************************************************/
+NTSTATUS GiveioCreateDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ GiveIO(); // give the calling process I/O access
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+/*********************************************************************
+ Driver Entry routine.
+
+ This routine is called only once after the driver is initially
+loaded into memory. It allocates everything necessary for the
+driver's operation. In our case, it allocates memory for our IOPM
+array, and creates a device which user mode applications can open.
+It also creates a symbolic link to the device driver. This allows
+a user mode application to access our driver using the \\.\giveio
+notation.
+*********************************************************************/
+NTSTATUS DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+{
+ PDEVICE_OBJECT deviceObject;
+ NTSTATUS status;
+ WCHAR NameBuffer[] = L"\\Device\\" DEVICE_NAME_STRING;
+ WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING;
+ UNICODE_STRING uniNameString, uniDOSString;
+
+ //
+ // Allocate a buffer for the local IOPM and zero it.
+ //
+ IOPM_local = MmAllocateNonCachedMemory(sizeof(IOPM));
+ if(IOPM_local == 0)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ RtlZeroMemory(IOPM_local, sizeof(IOPM));
+
+ //
+ // Set up device driver name and device object.
+ //
+ RtlInitUnicodeString(&uniNameString, NameBuffer);
+ RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);
+
+ status = IoCreateDevice(DriverObject, 0,
+ &uniNameString,
+ FILE_DEVICE_UNKNOWN,
+ 0, FALSE, &deviceObject);
+
+ if(!NT_SUCCESS(status))
+ return status;
+
+ status = IoCreateSymbolicLink (&uniDOSString, &uniNameString);
+
+ if (!NT_SUCCESS(status))
+ return status;
+
+ //
+ // Initialize the Driver Object with driver's entry points.
+ // All we require are the Create and Unload operations.
+ //
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = GiveioCreateDispatch;
+ DriverObject->DriverUnload = GiveioUnload;
+ return STATUS_SUCCESS;
+}
+
diff --git a/xs/src/avrdude/windows/giveio.sys b/xs/src/avrdude/windows/giveio.sys
new file mode 100644
index 000000000..62a0cb66f
--- /dev/null
+++ b/xs/src/avrdude/windows/giveio.sys
Binary files differ
diff --git a/xs/src/avrdude/windows/install_giveio.bat b/xs/src/avrdude/windows/install_giveio.bat
new file mode 100755
index 000000000..4a02b093b
--- /dev/null
+++ b/xs/src/avrdude/windows/install_giveio.bat
@@ -0,0 +1,34 @@
+@set DIRVERNAME=giveio
+@set DIRVERFILE=%DIRVERNAME%.sys
+
+@echo Copying the driver to the windows directory
+@echo target file: %WINDIR%\%DIRVERFILE%
+@copy %DIRVERFILE% %WINDIR%\%DIRVERFILE%
+
+@echo Remove a running service if needed...
+@loaddrv stop %DIRVERNAME% >NUL
+@if errorlevel 2 goto install
+
+@loaddrv remove %DIRVERNAME% >NUL
+@if errorlevel 1 goto install
+
+:install
+@echo Installing Windows NT/2k/XP driver: %DIRVERNAME%
+
+@loaddrv install %DIRVERNAME% %WINDIR%\%DIRVERFILE%
+@if errorlevel 3 goto error
+
+@loaddrv start %DIRVERNAME%
+@if errorlevel 1 goto error
+
+@loaddrv starttype %DIRVERNAME% auto
+@if errorlevel 1 goto error
+
+@echo Success
+@goto exit
+
+:error
+@echo ERROR: Installation of %DIRVERNAME% failed
+
+:exit
+
diff --git a/xs/src/avrdude/windows/loaddrv.c b/xs/src/avrdude/windows/loaddrv.c
new file mode 100644
index 000000000..ca92a2a1a
--- /dev/null
+++ b/xs/src/avrdude/windows/loaddrv.c
@@ -0,0 +1,460 @@
+// loaddrv.c - Dynamic driver install/start/stop/remove
+// based on Paula Tomlinson's LOADDRV program.
+// She describes it in her May 1995 article in Windows/DOS Developer's
+// Journal (now Windows Developer's Journal).
+// Modified by Chris Liechti <cliechti@gmx.net>
+// I removed the old/ugly dialog, it now accepts command line options and
+// prints error messages with textual description from the OS.
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "loaddrv.h"
+
+// globals
+SC_HANDLE hSCMan = NULL;
+
+//get ext messages for windows error codes:
+void DisplayErrorText(DWORD dwLastError) {
+ LPSTR MessageBuffer;
+ DWORD dwBufferLength;
+
+ DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_IGNORE_INSERTS |
+ FORMAT_MESSAGE_FROM_SYSTEM;
+
+ dwBufferLength = FormatMessageA(
+ dwFormatFlags,
+ NULL, // module to get message from (NULL == system)
+ dwLastError,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
+ (LPSTR) &MessageBuffer,
+ 0,
+ NULL
+ );
+ if (dwBufferLength) {
+ // Output message
+ puts(MessageBuffer);
+ // Free the buffer allocated by the system.
+ LocalFree(MessageBuffer);
+ }
+}
+
+int exists(char *filename) {
+ FILE * pFile;
+ pFile = fopen(filename, "r");
+ return pFile != NULL;
+}
+
+void usage(void) {
+ printf("USGAE: loaddrv command drivername [args...]\n\n"
+ "NT/2k/XP Driver and Service modification tool.\n"
+ "(C)2002 Chris Liechti <cliechti@gmx.net>\n\n"
+ "Suported commands:\n\n"
+ " install [fullpathforinstall]\n"
+ " Install new service. Loaded from given path. If path is not present,\n"
+ " the local directory is searched for a .sys file. If the service\n"
+ " already exists, it must be removed first.\n"
+ " start\n"
+ " Start service. It must be installed in advance.\n"
+ " stop\n"
+ " Stop service.\n"
+ " remove\n"
+ " Remove service. It must be stopped in advance.\n"
+ " status\n"
+ " Show status information about service.\n"
+ " starttype auto|manual|system|disable\n"
+ " Change startup type to the given type.\n"
+ );
+}
+
+int main(int argc, char *argv[]) {
+ DWORD status = 0;
+ int level = 0;
+ if (argc < 3) {
+ usage();
+ exit(1);
+ }
+ LoadDriverInit();
+ if (strcmp(argv[1], "start") == 0) {
+ printf("starting %s... ", argv[2]);
+ status = DriverStart(argv[2]);
+ if ( status != OKAY) {
+ printf("start failed (status %ld):\n", status);
+ level = 1;
+ } else {
+ printf("ok.\n");
+ }
+ } else if (strcmp(argv[1], "stop") == 0) {
+ printf("stoping %s... ", argv[2]);
+ status = DriverStop(argv[2]);
+ if ( status != OKAY) {
+ printf("stop failed (status %ld):\n", status);
+ level = 1;
+ } else {
+ printf("ok.\n");
+ }
+ } else if (strcmp(argv[1], "install") == 0) {
+ char path[MAX_PATH*2];
+ if (argc<4) {
+ char cwd[MAX_PATH];
+ getcwd(cwd, sizeof cwd);
+ sprintf(path, "%s\\%s.sys", cwd, argv[2]);
+ } else {
+ strncpy(path, argv[3], MAX_PATH);
+ }
+ if (exists(path)) {
+ printf("installing %s from %s... ", argv[2], path);
+ status = DriverInstall(path, argv[2]);
+ if ( status != OKAY) {
+ printf("install failed (status %ld):\n", status);
+ level = 2;
+ } else {
+ printf("ok.\n");
+ }
+ } else {
+ printf("install failed, file not found: %s\n", path);
+ level = 1;
+ }
+ } else if (strcmp(argv[1], "remove") == 0) {
+ printf("removing %s... ", argv[2]);
+ status = DriverRemove(argv[2]);
+ if ( status != OKAY) {
+ printf("remove failed (status %ld):\n", status);
+ level = 1;
+ } else {
+ printf("ok.\n");
+ }
+ } else if (strcmp(argv[1], "status") == 0) {
+ printf("status of %s:\n", argv[2]);
+ status = DriverStatus(argv[2]);
+ if ( status != OKAY) {
+ printf("stat failed (status %ld):\n", status);
+ level = 1;
+ } else {
+ printf("ok.\n");
+ }
+ } else if (strcmp(argv[1], "starttype") == 0) {
+ if (argc < 4) {
+ printf("Error: need start type (string) as argument.\n");
+ level = 2;
+ } else {
+ DWORD type = 0;
+ printf("set start type of %s to %s... ", argv[2], argv[3]);
+ if (strcmp(argv[1], "boot") == 0) {
+ type = SERVICE_BOOT_START;
+ } else if (strcmp(argv[3], "system") == 0) {
+ type = SERVICE_SYSTEM_START;
+ } else if (strcmp(argv[3], "auto") == 0) {
+ type = SERVICE_AUTO_START;
+ } else if (strcmp(argv[3], "manual") == 0) {
+ type = SERVICE_DEMAND_START;
+ } else if (strcmp(argv[3], "disabled") == 0) {
+ type = SERVICE_DISABLED;
+ } else {
+ printf("unknown type\n");
+ level = 1;
+ }
+ if (level == 0) {
+ status = DriverStartType(argv[2], type);
+ if ( status != OKAY) {
+ printf("set start type failed (status %ld):\n", status);
+ level = 1;
+ } else {
+ printf("ok.\n");
+ }
+ }
+ }
+ } else {
+ usage();
+ level = 1;
+ }
+ if (status) DisplayErrorText(status);
+ LoadDriverCleanup();
+ exit(level);
+ return 0;
+}
+
+
+DWORD LoadDriverInit(void) {
+ // connect to local service control manager
+ if ((hSCMan = OpenSCManager(NULL, NULL,
+ SC_MANAGER_ALL_ACCESS)) == NULL) {
+ return -1;
+ }
+ return OKAY;
+}
+
+void LoadDriverCleanup(void) {
+ if (hSCMan != NULL) CloseServiceHandle(hSCMan);
+}
+
+/**-----------------------------------------------------**/
+DWORD DriverInstall(LPSTR lpPath, LPSTR lpDriver) {
+ BOOL dwStatus = OKAY;
+ SC_HANDLE hService = NULL;
+
+ // add to service control manager's database
+ if ((hService = CreateService(hSCMan, lpDriver,
+ lpDriver, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
+ SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, lpPath,
+ NULL, NULL, NULL, NULL, NULL)) == NULL)
+ dwStatus = GetLastError();
+ else CloseServiceHandle(hService);
+
+ return dwStatus;
+} // DriverInstall
+
+/**-----------------------------------------------------**/
+DWORD DriverStart(LPSTR lpDriver) {
+ BOOL dwStatus = OKAY;
+ SC_HANDLE hService = NULL;
+
+ // get a handle to the service
+ if ((hService = OpenService(hSCMan, lpDriver,
+ SERVICE_ALL_ACCESS)) != NULL)
+ {
+ // start the driver
+ if (!StartService(hService, 0, NULL))
+ dwStatus = GetLastError();
+ } else dwStatus = GetLastError();
+
+ if (hService != NULL) CloseServiceHandle(hService);
+ return dwStatus;
+} // DriverStart
+
+/**-----------------------------------------------------**/
+DWORD DriverStop(LPSTR lpDriver)
+{
+ BOOL dwStatus = OKAY;
+ SC_HANDLE hService = NULL;
+ SERVICE_STATUS serviceStatus;
+
+ // get a handle to the service
+ if ((hService = OpenService(hSCMan, lpDriver,
+ SERVICE_ALL_ACCESS)) != NULL)
+ {
+ // stop the driver
+ if (!ControlService(hService, SERVICE_CONTROL_STOP,
+ &serviceStatus))
+ dwStatus = GetLastError();
+ } else dwStatus = GetLastError();
+
+ if (hService != NULL) CloseServiceHandle(hService);
+ return dwStatus;
+} // DriverStop
+
+/**-----------------------------------------------------**/
+DWORD DriverRemove(LPSTR lpDriver)
+{
+ BOOL dwStatus = OKAY;
+ SC_HANDLE hService = NULL;
+
+ // get a handle to the service
+ if ((hService = OpenService(hSCMan, lpDriver,
+ SERVICE_ALL_ACCESS)) != NULL)
+ { // remove the driver
+ if (!DeleteService(hService))
+ dwStatus = GetLastError();
+ } else dwStatus = GetLastError();
+
+ if (hService != NULL) CloseServiceHandle(hService);
+ return dwStatus;
+} // DriverRemove
+
+/**-----------------------------------------------------**/
+////extensions by Lch
+/**-----------------------------------------------------**/
+DWORD DriverStatus(LPSTR lpDriver) {
+ BOOL dwStatus = OKAY;
+ SC_HANDLE hService = NULL;
+ DWORD dwBytesNeeded;
+
+ // get a handle to the service
+ if ((hService = OpenService(hSCMan, lpDriver,
+ SERVICE_ALL_ACCESS)) != NULL)
+ {
+ LPQUERY_SERVICE_CONFIG lpqscBuf;
+ //~ LPSERVICE_DESCRIPTION lpqscBuf2;
+ // Allocate a buffer for the configuration information.
+ if ((lpqscBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc(
+ LPTR, 4096)) != NULL)
+ {
+ //~ if ((lpqscBuf2 = (LPSERVICE_DESCRIPTION) LocalAlloc(
+ //~ LPTR, 4096)) != NULL)
+ {
+ // Get the configuration information.
+ if (QueryServiceConfig(
+ hService,
+ lpqscBuf,
+ 4096,
+ &dwBytesNeeded) //&&
+ //~ QueryServiceConfig2(
+ //~ hService,
+ //~ SERVICE_CONFIG_DESCRIPTION,
+ //~ lpqscBuf2,
+ //~ 4096,
+ //~ &dwBytesNeeded
+ )
+ {
+ // Print the configuration information.
+ printf("Type: [0x%02lx] ", lpqscBuf->dwServiceType);
+ switch (lpqscBuf->dwServiceType) {
+ case SERVICE_WIN32_OWN_PROCESS:
+ printf("The service runs in its own process.");
+ break;
+ case SERVICE_WIN32_SHARE_PROCESS:
+ printf("The service shares a process with other services.");
+ break;
+ case SERVICE_KERNEL_DRIVER:
+ printf("Kernel driver.");
+ break;
+ case SERVICE_FILE_SYSTEM_DRIVER:
+ printf("File system driver.");
+ break;
+ case SERVICE_INTERACTIVE_PROCESS:
+ printf("The service can interact with the desktop.");
+ break;
+ default:
+ printf("Unknown type.");
+ }
+ printf("\nStart Type: [0x%02lx] ", lpqscBuf->dwStartType);
+ switch (lpqscBuf->dwStartType) {
+ case SERVICE_BOOT_START:
+ printf("Boot");
+ break;
+ case SERVICE_SYSTEM_START:
+ printf("System");
+ break;
+ case SERVICE_AUTO_START:
+ printf("Automatic");
+ break;
+ case SERVICE_DEMAND_START:
+ printf("Manual");
+ break;
+ case SERVICE_DISABLED:
+ printf("Disabled");
+ break;
+ default:
+ printf("Unknown.");
+ }
+ printf("\nError Control: [0x%02lx] ", lpqscBuf->dwErrorControl);
+ switch (lpqscBuf->dwErrorControl) {
+ case SERVICE_ERROR_IGNORE:
+ printf("IGNORE: Ignore.");
+ break;
+ case SERVICE_ERROR_NORMAL:
+ printf("NORMAL: Display a message box.");
+ break;
+ case SERVICE_ERROR_SEVERE:
+ printf("SEVERE: Restart with last-known-good config.");
+ break;
+ case SERVICE_ERROR_CRITICAL:
+ printf("CRITICAL: Restart w/ last-known-good config.");
+ break;
+ default:
+ printf("Unknown.");
+ }
+ printf("\nBinary path: %s\n", lpqscBuf->lpBinaryPathName);
+
+ if (lpqscBuf->lpLoadOrderGroup != NULL)
+ printf("Load order grp: %s\n", lpqscBuf->lpLoadOrderGroup);
+ if (lpqscBuf->dwTagId != 0)
+ printf("Tag ID: %ld\n", lpqscBuf->dwTagId);
+ if (lpqscBuf->lpDependencies != NULL)
+ printf("Dependencies: %s\n", lpqscBuf->lpDependencies);
+ if (lpqscBuf->lpServiceStartName != NULL)
+ printf("Start Name: %s\n", lpqscBuf->lpServiceStartName);
+ //~ if (lpqscBuf2->lpDescription != NULL)
+ //~ printf("Description: %s\n", lpqscBuf2->lpDescription);
+ }
+ //~ LocalFree(lpqscBuf2);
+ }
+ LocalFree(lpqscBuf);
+ } else {
+ dwStatus = GetLastError();
+ }
+ } else {
+ dwStatus = GetLastError();
+ }
+
+ if (hService != NULL) CloseServiceHandle(hService);
+ return dwStatus;
+} // DriverStatus
+
+/**-----------------------------------------------------**/
+DWORD DriverStartType(LPSTR lpDriver, DWORD dwStartType) {
+ BOOL dwStatus = OKAY;
+ SC_HANDLE hService = NULL;
+
+ SC_LOCK sclLock;
+ LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf;
+ DWORD dwBytesNeeded;
+
+ // Need to acquire database lock before reconfiguring.
+ sclLock = LockServiceDatabase(hSCMan);
+
+ // If the database cannot be locked, report the details.
+ if (sclLock == NULL) {
+ // Exit if the database is not locked by another process.
+ if (GetLastError() == ERROR_SERVICE_DATABASE_LOCKED) {
+
+ // Allocate a buffer to get details about the lock.
+ lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc(
+ LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256);
+ if (lpqslsBuf != NULL) {
+ // Get and print the lock status information.
+ if (QueryServiceLockStatus(
+ hSCMan,
+ lpqslsBuf,
+ sizeof(QUERY_SERVICE_LOCK_STATUS)+256,
+ &dwBytesNeeded) )
+ {
+ if (lpqslsBuf->fIsLocked) {
+ printf("Locked by: %s, duration: %ld seconds\n",
+ lpqslsBuf->lpLockOwner,
+ lpqslsBuf->dwLockDuration
+ );
+ } else {
+ printf("No longer locked\n");
+ }
+ }
+ LocalFree(lpqslsBuf);
+ }
+ }
+ dwStatus = GetLastError();
+ } else {
+ // The database is locked, so it is safe to make changes.
+ // Open a handle to the service.
+ hService = OpenService(
+ hSCMan, // SCManager database
+ lpDriver, // name of service
+ SERVICE_CHANGE_CONFIG
+ ); // need CHANGE access
+ if (hService != NULL) {
+ // Make the changes.
+ if (!ChangeServiceConfig(
+ hService, // handle of service
+ SERVICE_NO_CHANGE, // service type: no change
+ dwStartType, // change service start type
+ SERVICE_NO_CHANGE, // error control: no change
+ NULL, // binary path: no change
+ NULL, // load order group: no change
+ NULL, // tag ID: no change
+ NULL, // dependencies: no change
+ NULL, // account name: no change
+ NULL, // password: no change
+ NULL) ) // display name: no change
+ {
+ dwStatus = GetLastError();
+ }
+ }
+ // Release the database lock.
+ UnlockServiceDatabase(sclLock);
+ }
+
+ if (hService != NULL) CloseServiceHandle(hService);
+ return dwStatus;
+} // DriverStartType
diff --git a/xs/src/avrdude/windows/loaddrv.h b/xs/src/avrdude/windows/loaddrv.h
new file mode 100644
index 000000000..d7d102b97
--- /dev/null
+++ b/xs/src/avrdude/windows/loaddrv.h
@@ -0,0 +1,20 @@
+#ifndef LOADDRV_H
+#define LOADDRV_H
+
+#include <windows.h>
+
+#define OKAY 0
+#define UNEXPECTED_ERROR 9999
+
+//prototypes
+DWORD LoadDriverInit(void);
+void LoadDriverCleanup(void);
+DWORD DriverInstall(LPSTR, LPSTR);
+DWORD DriverStart(LPSTR);
+DWORD DriverStop(LPSTR);
+DWORD DriverRemove(LPSTR);
+DWORD DriverStatus(LPSTR);
+DWORD DriverStartType(LPSTR, DWORD);
+#endif //LOADDRV_H
+
+
diff --git a/xs/src/avrdude/windows/remove_giveio.bat b/xs/src/avrdude/windows/remove_giveio.bat
new file mode 100755
index 000000000..024427db8
--- /dev/null
+++ b/xs/src/avrdude/windows/remove_giveio.bat
@@ -0,0 +1,14 @@
+@set DIRVERNAME=giveio
+
+@loaddrv stop %DIRVERNAME%
+@if errorlevel 2 goto error
+
+@loaddrv remove %DIRVERNAME%
+@if errorlevel 1 goto error
+
+@goto exit
+
+:error
+@echo ERROR: Deinstallation of %DIRVERNAME% failed
+
+:exit
diff --git a/xs/src/avrdude/windows/status_giveio.bat b/xs/src/avrdude/windows/status_giveio.bat
new file mode 100755
index 000000000..bc8214749
--- /dev/null
+++ b/xs/src/avrdude/windows/status_giveio.bat
@@ -0,0 +1,12 @@
+@set DIRVERNAME=giveio
+
+@loaddrv status %DIRVERNAME%
+@if errorlevel 1 goto error
+
+@goto exit
+
+:error
+@echo ERROR: Status querry for %DIRVERNAME% failed
+
+:exit
+
diff --git a/xs/src/avrdude/windows/unistd.cpp b/xs/src/avrdude/windows/unistd.cpp
new file mode 100644
index 000000000..e47c0b659
--- /dev/null
+++ b/xs/src/avrdude/windows/unistd.cpp
@@ -0,0 +1,44 @@
+#include "unistd.h"
+
+#include <cstdint>
+#include <chrono>
+#include <thread>
+
+#include <windows.h>
+
+
+extern "C" {
+
+
+int usleep(unsigned usec)
+{
+ std::this_thread::sleep_for(std::chrono::microseconds(usec));
+ return 0;
+}
+
+
+// SO: https://stackoverflow.com/questions/10905892/equivalent-of-gettimeday-for-windows
+int gettimeofday(struct timeval *tp, struct timezone *tzp)
+{
+ // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
+ // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
+ // until 00:00:00 January 1, 1970
+ static const std::uint64_t EPOCH = ((std::uint64_t) 116444736000000000ULL);
+
+ SYSTEMTIME system_time;
+ FILETIME file_time;
+ std::uint64_t time;
+
+ GetSystemTime(&system_time);
+ SystemTimeToFileTime(&system_time, &file_time);
+ time = ((std::uint64_t)file_time.dwLowDateTime);
+ time += ((std::uint64_t)file_time.dwHighDateTime) << 32;
+
+ tp->tv_sec = (long)((time - EPOCH) / 10000000L);
+ tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
+ return 0;
+}
+
+
+
+}
diff --git a/xs/src/avrdude/windows/unistd.h b/xs/src/avrdude/windows/unistd.h
new file mode 100644
index 000000000..b1bc6bf7f
--- /dev/null
+++ b/xs/src/avrdude/windows/unistd.h
@@ -0,0 +1,85 @@
+#ifndef SLIC3R_AVRDUDE_UNISTD_H
+#define SLIC3R_AVRDUDE_UNISTD_H 1
+
+/* This is intended as a drop-in replacement for unistd.h on Windows.
+ * Please add functionality as neeeded.
+ * https://stackoverflow.com/a/826027/1202830
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include <stdlib.h>
+#include <io.h>
+#include <getopt.h> /* getopt at: https://gist.github.com/ashelly/7776712 */
+#include <process.h> /* for getpid() and the exec..() family */
+#include <direct.h> /* for _getcwd() and _chdir() */
+#include <sys/types.h>
+#include <sys/stat.h> /* both for stat() */
+
+#ifndef __cplusplus
+#define inline __inline
+#endif
+
+#define __func__ __FUNCTION__
+
+#define srandom srand
+#define random rand
+
+/* Values for the second argument to access.
+ These may be OR'd together. */
+#define R_OK 4 /* Test for read permission. */
+#define W_OK 2 /* Test for write permission. */
+//#define X_OK 1 /* execute permission - unsupported in windows*/
+#define F_OK 0 /* Test for existence. */
+
+#define access _access
+#define dup2 _dup2
+#define execve _execve
+#define ftruncate _chsize
+#define unlink _unlink
+#define fileno _fileno
+#define getcwd _getcwd
+#define chdir _chdir
+#define isatty _isatty
+#define lseek _lseek
+#define snprintf _snprintf
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+#define stat _stat
+/* read, write, and close are NOT being #defined here, because while there are file handle specific versions for Windows, they probably don't work for sockets. You need to look at your app and consider whether to call e.g. closesocket(). */
+
+#ifdef _WIN64
+#define ssize_t __int64
+#else
+#define ssize_t long
+#endif
+
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#ifndef __cplusplus
+/* should be in some equivalent to <sys/types.h> */
+typedef __int8 int8_t;
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+#endif
+
+
+int usleep(unsigned usec);
+int gettimeofday(struct timeval *tp, struct timezone *tzp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* unistd.h */
diff --git a/xs/src/avrdude/wiring.c b/xs/src/avrdude/wiring.c
new file mode 100644
index 000000000..562a3f17c
--- /dev/null
+++ b/xs/src/avrdude/wiring.c
@@ -0,0 +1,224 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2011 Brett Hagman
+ *
+ * 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 Wiring bootloaders
+ *
+ * http://wiring.org.co/
+ *
+ * The Wiring bootloader uses a near-complete STK500v2 protocol.
+ * (Only ISP specific programming commands are not implemented
+ * e.g. chip erase).
+ * DTR and RTS signals are diddled to set the board into programming mode.
+ *
+ * Also includes an extended parameter to introduce a delay after opening
+ * to accommodate multi-layered programmers/bootloaders. If the extended
+ * parameter 'snooze' > 0, then no DTR/RTS toggle takes place, and
+ * AVRDUDE will wait that amount of time in milliseconds before syncing.
+ *
+ * Unfortunately, there is no way to easily chain private programmer data
+ * when we "inherit" programmer types as we have (stk500v2). Sooooo, a
+ * *cringe* global variable is used to store the snooze time.
+ */
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "stk500v2_private.h"
+#include "stk500v2.h"
+#include "wiring.h"
+
+/*
+ * Private data for this programmer.
+ */
+struct wiringpdata
+{
+ /*
+ * We just have the single snooze integer to carry around for now.
+ */
+ int snoozetime;
+};
+
+
+/* wiringpdata is our private data */
+/* pdata is stk500v2's private data (inherited) */
+
+#define WIRINGPDATA(x) ((struct wiringpdata *)(x))
+
+#define STK500V2PDATA(pgm) ((struct pdata *)(pgm->cookie))
+
+
+static void wiring_setup(PROGRAMMER * pgm)
+{
+ void *mycookie;
+
+ /*
+ * First, have STK500v2 backend allocate its own private data.
+ */
+ stk500v2_setup(pgm);
+
+ /*
+ * Now prepare our data
+ */
+ if ((mycookie = malloc(sizeof(struct wiringpdata))) == 0) {
+ // avrdude_message(MSG_INFO, "%s: wiring_setup(): Out of memory allocating private data\n",
+ // progname);
+ // exit(1);
+ avrdude_oom("wiring_setup(): Out of memory allocating private data\n");
+ }
+ memset(mycookie, 0, sizeof(struct wiringpdata));
+ WIRINGPDATA(mycookie)->snoozetime = 0;
+
+ /*
+ * Store our own cookie in a safe place for the time being.
+ */
+ STK500V2PDATA(pgm)->chained_pdata = mycookie;
+}
+
+static void wiring_teardown(PROGRAMMER * pgm)
+{
+ void *mycookie;
+
+ mycookie = STK500V2PDATA(pgm)->chained_pdata;
+
+ free(mycookie);
+
+ stk500v2_teardown(pgm);
+}
+
+static int wiring_parseextparms(PROGRAMMER * pgm, LISTID extparms)
+{
+ LNODEID ln;
+ const char *extended_param;
+ int rv = 0;
+ void *mycookie = STK500V2PDATA(pgm)->chained_pdata;
+
+ for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
+ extended_param = ldata(ln);
+
+ if (strncmp(extended_param, "snooze=", strlen("snooze=")) == 0) {
+ int newsnooze;
+ if (sscanf(extended_param, "snooze=%i", &newsnooze) != 1 ||
+ newsnooze < 0) {
+ avrdude_message(MSG_INFO, "%s: wiring_parseextparms(): invalid snooze time '%s'\n",
+ progname, extended_param);
+ rv = -1;
+ continue;
+ }
+ avrdude_message(MSG_NOTICE2, "%s: wiring_parseextparms(): snooze time set to %d ms\n",
+ progname, newsnooze);
+ WIRINGPDATA(mycookie)->snoozetime = newsnooze;
+
+ continue;
+ }
+
+ avrdude_message(MSG_INFO, "%s: wiring_parseextparms(): invalid extended parameter '%s'\n",
+ progname, extended_param);
+ rv = -1;
+ }
+
+ return rv;
+}
+
+static int wiring_open(PROGRAMMER * pgm, char * port)
+{
+ int timetosnooze;
+ void *mycookie = STK500V2PDATA(pgm)->chained_pdata;
+ union pinfo pinfo;
+
+ strcpy(pgm->port, port);
+ pinfo.baud = pgm->baudrate ? pgm->baudrate: 115200;
+ if (serial_open(port, pinfo, &pgm->fd) < 0) {
+ return -1;
+ }
+
+ /* If we have a snoozetime, then we wait and do NOT toggle DTR/RTS */
+
+ if (WIRINGPDATA(mycookie)->snoozetime > 0) {
+ timetosnooze = WIRINGPDATA(mycookie)->snoozetime;
+
+ avrdude_message(MSG_NOTICE2, "%s: wiring_open(): snoozing for %d ms\n",
+ progname, timetosnooze);
+ while (timetosnooze--)
+ usleep(1000);
+ avrdude_message(MSG_NOTICE2, "%s: wiring_open(): done snoozing\n",
+ progname);
+ } else {
+ /* Perform Wiring programming mode RESET. */
+ /* This effectively *releases* both DTR and RTS. */
+ /* i.e. both DTR and RTS rise to a HIGH logic level */
+ /* since they are active LOW signals. */
+
+ avrdude_message(MSG_NOTICE2, "%s: wiring_open(): releasing DTR/RTS\n",
+ progname);
+
+ serial_set_dtr_rts(&pgm->fd, 0);
+ usleep(50*1000);
+
+ /* After releasing for 50 milliseconds, DTR and RTS */
+ /* are asserted (i.e. logic LOW) again. */
+
+ avrdude_message(MSG_NOTICE2, "%s: wiring_open(): asserting DTR/RTS\n",
+ progname);
+
+ serial_set_dtr_rts(&pgm->fd, 1);
+ usleep(50*1000);
+ }
+
+ /* drain any extraneous input */
+ stk500v2_drain(pgm, 0);
+
+ if (stk500v2_getsync(pgm) < 0)
+ return -1;
+
+ return 0;
+}
+
+static void wiring_close(PROGRAMMER * pgm)
+{
+ serial_set_dtr_rts(&pgm->fd, 0);
+ serial_close(&pgm->fd);
+ pgm->fd.ifd = -1;
+}
+
+const char wiring_desc[] = "http://wiring.org.co/, Basically STK500v2 protocol, with some glue to trigger the bootloader.";
+
+void wiring_initpgm(PROGRAMMER * pgm)
+{
+ /* The Wiring bootloader uses a near-complete STK500v2 protocol. */
+
+ stk500v2_initpgm(pgm);
+
+ strcpy(pgm->type, "Wiring");
+ pgm->open = wiring_open;
+ pgm->close = wiring_close;
+
+ pgm->setup = wiring_setup;
+ pgm->teardown = wiring_teardown;
+ pgm->parseextparams = wiring_parseextparms;
+}
+
diff --git a/xs/src/avrdude/wiring.h b/xs/src/avrdude/wiring.h
new file mode 100644
index 000000000..ed1362de7
--- /dev/null
+++ b/xs/src/avrdude/wiring.h
@@ -0,0 +1,29 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2011 Brett Hagman
+ *
+ * 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 wiring_h__
+#define wiring_h__
+
+extern const char wiring_desc[];
+void wiring_initpgm(PROGRAMMER * pgm);
+
+#endif
+
+
diff --git a/xs/src/benchmark.h b/xs/src/benchmark.h
new file mode 100644
index 000000000..19870b37b
--- /dev/null
+++ b/xs/src/benchmark.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) Tamás Mészáros
+ * 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.
+ */
+#ifndef INCLUDE_BENCHMARK_H_
+#define INCLUDE_BENCHMARK_H_
+
+#include <chrono>
+#include <ratio>
+
+/**
+ * A class for doing benchmarks.
+ */
+class Benchmark {
+ typedef std::chrono::high_resolution_clock Clock;
+ typedef Clock::duration Duration;
+ typedef Clock::time_point TimePoint;
+
+ TimePoint t1, t2;
+ Duration d;
+
+ inline double to_sec(Duration d) {
+ return d.count() * double(Duration::period::num) / Duration::period::den;
+ }
+
+public:
+
+ /**
+ * Measure time from the moment of this call.
+ */
+ void start() { t1 = Clock::now(); }
+
+ /**
+ * Measure time to the moment of this call.
+ */
+ void stop() { t2 = Clock::now(); }
+
+ /**
+ * Get the time elapsed between a start() end a stop() call.
+ * @return Returns the elapsed time in seconds.
+ */
+ double getElapsedSec() { d = t2 - t1; return to_sec(d); }
+};
+
+
+#endif /* INCLUDE_BENCHMARK_H_ */
diff --git a/xs/src/eigen/Eigen/Cholesky b/xs/src/eigen/Eigen/Cholesky
index 369d1f5ec..1332b540d 100644
--- a/xs/src/eigen/Eigen/Cholesky
+++ b/xs/src/eigen/Eigen/Cholesky
@@ -9,6 +9,7 @@
#define EIGEN_CHOLESKY_MODULE_H
#include "Core"
+#include "Jacobi"
#include "src/Core/util/DisableStupidWarnings.h"
@@ -31,7 +32,11 @@
#include "src/Cholesky/LLT.h"
#include "src/Cholesky/LDLT.h"
#ifdef EIGEN_USE_LAPACKE
+#ifdef EIGEN_USE_MKL
+#include "mkl_lapacke.h"
+#else
#include "src/misc/lapacke.h"
+#endif
#include "src/Cholesky/LLT_LAPACKE.h"
#endif
diff --git a/xs/src/eigen/Eigen/Core b/xs/src/eigen/Eigen/Core
index 0f7fa630d..4d4901e03 100644
--- a/xs/src/eigen/Eigen/Core
+++ b/xs/src/eigen/Eigen/Core
@@ -14,6 +14,22 @@
// first thing Eigen does: stop the compiler from committing suicide
#include "src/Core/util/DisableStupidWarnings.h"
+#if defined(__CUDACC__) && !defined(EIGEN_NO_CUDA)
+ #define EIGEN_CUDACC __CUDACC__
+#endif
+
+#if defined(__CUDA_ARCH__) && !defined(EIGEN_NO_CUDA)
+ #define EIGEN_CUDA_ARCH __CUDA_ARCH__
+#endif
+
+#if defined(__CUDACC_VER_MAJOR__) && (__CUDACC_VER_MAJOR__ >= 9)
+#define EIGEN_CUDACC_VER ((__CUDACC_VER_MAJOR__ * 10000) + (__CUDACC_VER_MINOR__ * 100))
+#elif defined(__CUDACC_VER__)
+#define EIGEN_CUDACC_VER __CUDACC_VER__
+#else
+#define EIGEN_CUDACC_VER 0
+#endif
+
// Handle NVCC/CUDA/SYCL
#if defined(__CUDACC__) || defined(__SYCL_DEVICE_ONLY__)
// Do not try asserts on CUDA and SYCL!
@@ -155,6 +171,9 @@
#ifdef __AVX512DQ__
#define EIGEN_VECTORIZE_AVX512DQ
#endif
+ #ifdef __AVX512ER__
+ #define EIGEN_VECTORIZE_AVX512ER
+ #endif
#endif
// include files
@@ -229,7 +248,7 @@
#if defined __CUDACC__
#define EIGEN_VECTORIZE_CUDA
#include <vector_types.h>
- #if defined __CUDACC_VER__ && __CUDACC_VER__ >= 70500
+ #if EIGEN_CUDACC_VER >= 70500
#define EIGEN_HAS_CUDA_FP16
#endif
#endif
@@ -352,6 +371,7 @@ using std::ptrdiff_t;
#include "src/Core/MathFunctions.h"
#include "src/Core/GenericPacketMath.h"
#include "src/Core/MathFunctionsImpl.h"
+#include "src/Core/arch/Default/ConjHelper.h"
#if defined EIGEN_VECTORIZE_AVX512
#include "src/Core/arch/SSE/PacketMath.h"
@@ -367,6 +387,7 @@ using std::ptrdiff_t;
#include "src/Core/arch/AVX/MathFunctions.h"
#include "src/Core/arch/AVX/Complex.h"
#include "src/Core/arch/AVX/TypeCasting.h"
+ #include "src/Core/arch/SSE/TypeCasting.h"
#elif defined EIGEN_VECTORIZE_SSE
#include "src/Core/arch/SSE/PacketMath.h"
#include "src/Core/arch/SSE/MathFunctions.h"
diff --git a/xs/src/eigen/Eigen/Eigenvalues b/xs/src/eigen/Eigen/Eigenvalues
index 009e529e1..f3f661b07 100644
--- a/xs/src/eigen/Eigen/Eigenvalues
+++ b/xs/src/eigen/Eigen/Eigenvalues
@@ -45,7 +45,11 @@
#include "src/Eigenvalues/GeneralizedEigenSolver.h"
#include "src/Eigenvalues/MatrixBaseEigenvalues.h"
#ifdef EIGEN_USE_LAPACKE
+#ifdef EIGEN_USE_MKL
+#include "mkl_lapacke.h"
+#else
#include "src/misc/lapacke.h"
+#endif
#include "src/Eigenvalues/RealSchur_LAPACKE.h"
#include "src/Eigenvalues/ComplexSchur_LAPACKE.h"
#include "src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h"
diff --git a/xs/src/eigen/Eigen/LU b/xs/src/eigen/Eigen/LU
index 6f6c55629..6418a86e1 100644
--- a/xs/src/eigen/Eigen/LU
+++ b/xs/src/eigen/Eigen/LU
@@ -28,7 +28,11 @@
#include "src/LU/FullPivLU.h"
#include "src/LU/PartialPivLU.h"
#ifdef EIGEN_USE_LAPACKE
+#ifdef EIGEN_USE_MKL
+#include "mkl_lapacke.h"
+#else
#include "src/misc/lapacke.h"
+#endif
#include "src/LU/PartialPivLU_LAPACKE.h"
#endif
#include "src/LU/Determinant.h"
diff --git a/xs/src/eigen/Eigen/QR b/xs/src/eigen/Eigen/QR
index 80838e3bd..c7e914469 100644
--- a/xs/src/eigen/Eigen/QR
+++ b/xs/src/eigen/Eigen/QR
@@ -36,7 +36,11 @@
#include "src/QR/ColPivHouseholderQR.h"
#include "src/QR/CompleteOrthogonalDecomposition.h"
#ifdef EIGEN_USE_LAPACKE
+#ifdef EIGEN_USE_MKL
+#include "mkl_lapacke.h"
+#else
#include "src/misc/lapacke.h"
+#endif
#include "src/QR/HouseholderQR_LAPACKE.h"
#include "src/QR/ColPivHouseholderQR_LAPACKE.h"
#endif
diff --git a/xs/src/eigen/Eigen/QtAlignedMalloc b/xs/src/eigen/Eigen/QtAlignedMalloc
index c6571f129..4f07df02a 100644
--- a/xs/src/eigen/Eigen/QtAlignedMalloc
+++ b/xs/src/eigen/Eigen/QtAlignedMalloc
@@ -27,7 +27,7 @@ void qFree(void *ptr)
void *qRealloc(void *ptr, std::size_t size)
{
void* newPtr = Eigen::internal::aligned_malloc(size);
- memcpy(newPtr, ptr, size);
+ std::memcpy(newPtr, ptr, size);
Eigen::internal::aligned_free(ptr);
return newPtr;
}
diff --git a/xs/src/eigen/Eigen/SVD b/xs/src/eigen/Eigen/SVD
index 86143c23d..5d0e75f7f 100644
--- a/xs/src/eigen/Eigen/SVD
+++ b/xs/src/eigen/Eigen/SVD
@@ -37,7 +37,11 @@
#include "src/SVD/JacobiSVD.h"
#include "src/SVD/BDCSVD.h"
#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT)
+#ifdef EIGEN_USE_MKL
+#include "mkl_lapacke.h"
+#else
#include "src/misc/lapacke.h"
+#endif
#include "src/SVD/JacobiSVD_LAPACKE.h"
#endif
diff --git a/xs/src/eigen/Eigen/src/Cholesky/LDLT.h b/xs/src/eigen/Eigen/src/Cholesky/LDLT.h
index fcee7b2e3..0313a54bf 100644
--- a/xs/src/eigen/Eigen/src/Cholesky/LDLT.h
+++ b/xs/src/eigen/Eigen/src/Cholesky/LDLT.h
@@ -248,7 +248,7 @@ template<typename _MatrixType, int _UpLo> class LDLT
/** \brief Reports whether previous computation was successful.
*
* \returns \c Success if computation was succesful,
- * \c NumericalIssue if the matrix.appears to be negative.
+ * \c NumericalIssue if the factorization failed because of a zero pivot.
*/
ComputationInfo info() const
{
@@ -376,6 +376,8 @@ template<> struct ldlt_inplace<Lower>
if((rs>0) && pivot_is_valid)
A21 /= realAkk;
+ else if(rs>0)
+ ret = ret && (A21.array()==Scalar(0)).all();
if(found_zero_pivot && pivot_is_valid) ret = false; // factorization failed
else if(!pivot_is_valid) found_zero_pivot = true;
@@ -568,13 +570,14 @@ void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) cons
// more precisely, use pseudo-inverse of D (see bug 241)
using std::abs;
const typename Diagonal<const MatrixType>::RealReturnType vecD(vectorD());
- // In some previous versions, tolerance was set to the max of 1/highest and the maximal diagonal entry * epsilon
- // as motivated by LAPACK's xGELSS:
+ // In some previous versions, tolerance was set to the max of 1/highest (or rather numeric_limits::min())
+ // and the maximal diagonal entry * epsilon as motivated by LAPACK's xGELSS:
// RealScalar tolerance = numext::maxi(vecD.array().abs().maxCoeff() * NumTraits<RealScalar>::epsilon(),RealScalar(1) / NumTraits<RealScalar>::highest());
// However, LDLT is not rank revealing, and so adjusting the tolerance wrt to the highest
// diagonal element is not well justified and leads to numerical issues in some cases.
// Moreover, Lapack's xSYTRS routines use 0 for the tolerance.
- RealScalar tolerance = RealScalar(1) / NumTraits<RealScalar>::highest();
+ // Using numeric_limits::min() gives us more robustness to denormals.
+ RealScalar tolerance = (std::numeric_limits<RealScalar>::min)();
for (Index i = 0; i < vecD.size(); ++i)
{
diff --git a/xs/src/eigen/Eigen/src/Cholesky/LLT.h b/xs/src/eigen/Eigen/src/Cholesky/LLT.h
index 87ca8d423..e1624d21b 100644
--- a/xs/src/eigen/Eigen/src/Cholesky/LLT.h
+++ b/xs/src/eigen/Eigen/src/Cholesky/LLT.h
@@ -24,7 +24,7 @@ template<typename MatrixType, int UpLo> struct LLT_Traits;
*
* \tparam _MatrixType the type of the matrix of which we are computing the LL^T Cholesky decomposition
* \tparam _UpLo the triangular part that will be used for the decompositon: Lower (default) or Upper.
- * The other triangular part won't be read.
+ * The other triangular part won't be read.
*
* This class performs a LL^T Cholesky decomposition of a symmetric, positive definite
* matrix A such that A = LL^* = U^*U, where L is lower triangular.
@@ -41,14 +41,18 @@ template<typename MatrixType, int UpLo> struct LLT_Traits;
* Example: \include LLT_example.cpp
* Output: \verbinclude LLT_example.out
*
+ * \b Performance: for best performance, it is recommended to use a column-major storage format
+ * with the Lower triangular part (the default), or, equivalently, a row-major storage format
+ * with the Upper triangular part. Otherwise, you might get a 20% slowdown for the full factorization
+ * step, and rank-updates can be up to 3 times slower.
+ *
* This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
*
+ * Note that during the decomposition, only the lower (or upper, as defined by _UpLo) triangular part of A is considered.
+ * Therefore, the strict lower part does not have to store correct values.
+ *
* \sa MatrixBase::llt(), SelfAdjointView::llt(), class LDLT
*/
- /* HEY THIS DOX IS DISABLED BECAUSE THERE's A BUG EITHER HERE OR IN LDLT ABOUT THAT (OR BOTH)
- * Note that during the decomposition, only the upper triangular part of A is considered. Therefore,
- * the strict lower part does not have to store correct values.
- */
template<typename _MatrixType, int _UpLo> class LLT
{
public:
@@ -146,7 +150,7 @@ template<typename _MatrixType, int _UpLo> class LLT
}
template<typename Derived>
- void solveInPlace(MatrixBase<Derived> &bAndX) const;
+ void solveInPlace(const MatrixBase<Derived> &bAndX) const;
template<typename InputType>
LLT& compute(const EigenBase<InputType>& matrix);
@@ -177,7 +181,7 @@ template<typename _MatrixType, int _UpLo> class LLT
/** \brief Reports whether previous computation was successful.
*
* \returns \c Success if computation was succesful,
- * \c NumericalIssue if the matrix.appears to be negative.
+ * \c NumericalIssue if the matrix.appears not to be positive definite.
*/
ComputationInfo info() const
{
@@ -425,7 +429,8 @@ LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const EigenBase<InputType>
eigen_assert(a.rows()==a.cols());
const Index size = a.rows();
m_matrix.resize(size, size);
- m_matrix = a.derived();
+ if (!internal::is_same_dense(m_matrix, a.derived()))
+ m_matrix = a.derived();
// Compute matrix L1 norm = max abs column sum.
m_l1_norm = RealScalar(0);
@@ -485,11 +490,14 @@ void LLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) const
*
* This version avoids a copy when the right hand side matrix b is not needed anymore.
*
+ * \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
+ * This function will const_cast it, so constness isn't honored here.
+ *
* \sa LLT::solve(), MatrixBase::llt()
*/
template<typename MatrixType, int _UpLo>
template<typename Derived>
-void LLT<MatrixType,_UpLo>::solveInPlace(MatrixBase<Derived> &bAndX) const
+void LLT<MatrixType,_UpLo>::solveInPlace(const MatrixBase<Derived> &bAndX) const
{
eigen_assert(m_isInitialized && "LLT is not initialized.");
eigen_assert(m_matrix.rows()==bAndX.rows());
diff --git a/xs/src/eigen/Eigen/src/Core/Array.h b/xs/src/eigen/Eigen/src/Core/Array.h
index 0d34269fd..e10020d4f 100644
--- a/xs/src/eigen/Eigen/src/Core/Array.h
+++ b/xs/src/eigen/Eigen/src/Core/Array.h
@@ -231,10 +231,16 @@ class Array
: Base(other)
{ }
+ private:
+ struct PrivateType {};
+ public:
+
/** \sa MatrixBase::operator=(const EigenBase<OtherDerived>&) */
template<typename OtherDerived>
EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other)
+ EIGEN_STRONG_INLINE Array(const EigenBase<OtherDerived> &other,
+ typename internal::enable_if<internal::is_convertible<typename OtherDerived::Scalar,Scalar>::value,
+ PrivateType>::type = PrivateType())
: Base(other.derived())
{ }
diff --git a/xs/src/eigen/Eigen/src/Core/ArrayBase.h b/xs/src/eigen/Eigen/src/Core/ArrayBase.h
index f0232f65e..3dbc7084c 100644
--- a/xs/src/eigen/Eigen/src/Core/ArrayBase.h
+++ b/xs/src/eigen/Eigen/src/Core/ArrayBase.h
@@ -175,7 +175,7 @@ template<typename Derived> class ArrayBase
*/
template<typename Derived>
template<typename OtherDerived>
-EIGEN_STRONG_INLINE Derived &
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other)
{
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
@@ -188,7 +188,7 @@ ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other)
*/
template<typename Derived>
template<typename OtherDerived>
-EIGEN_STRONG_INLINE Derived &
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other)
{
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
@@ -201,7 +201,7 @@ ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other)
*/
template<typename Derived>
template<typename OtherDerived>
-EIGEN_STRONG_INLINE Derived &
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
ArrayBase<Derived>::operator*=(const ArrayBase<OtherDerived>& other)
{
call_assignment(derived(), other.derived(), internal::mul_assign_op<Scalar,typename OtherDerived::Scalar>());
@@ -214,7 +214,7 @@ ArrayBase<Derived>::operator*=(const ArrayBase<OtherDerived>& other)
*/
template<typename Derived>
template<typename OtherDerived>
-EIGEN_STRONG_INLINE Derived &
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived &
ArrayBase<Derived>::operator/=(const ArrayBase<OtherDerived>& other)
{
call_assignment(derived(), other.derived(), internal::div_assign_op<Scalar,typename OtherDerived::Scalar>());
diff --git a/xs/src/eigen/Eigen/src/Core/ArrayWrapper.h b/xs/src/eigen/Eigen/src/Core/ArrayWrapper.h
index a04521a16..688aadd62 100644
--- a/xs/src/eigen/Eigen/src/Core/ArrayWrapper.h
+++ b/xs/src/eigen/Eigen/src/Core/ArrayWrapper.h
@@ -32,7 +32,8 @@ struct traits<ArrayWrapper<ExpressionType> >
// Let's remove NestByRefBit
enum {
Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
- Flags = Flags0 & ~NestByRefBit
+ LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
+ Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
};
};
}
@@ -129,7 +130,8 @@ struct traits<MatrixWrapper<ExpressionType> >
// Let's remove NestByRefBit
enum {
Flags0 = traits<typename remove_all<typename ExpressionType::Nested>::type >::Flags,
- Flags = Flags0 & ~NestByRefBit
+ LvalueBitFlag = is_lvalue<ExpressionType>::value ? LvalueBit : 0,
+ Flags = (Flags0 & ~(NestByRefBit | LvalueBit)) | LvalueBitFlag
};
};
}
diff --git a/xs/src/eigen/Eigen/src/Core/AssignEvaluator.h b/xs/src/eigen/Eigen/src/Core/AssignEvaluator.h
index b0ec7b7ca..dbe435d86 100644
--- a/xs/src/eigen/Eigen/src/Core/AssignEvaluator.h
+++ b/xs/src/eigen/Eigen/src/Core/AssignEvaluator.h
@@ -39,7 +39,7 @@ public:
enum {
DstAlignment = DstEvaluator::Alignment,
SrcAlignment = SrcEvaluator::Alignment,
- DstHasDirectAccess = DstFlags & DirectAccessBit,
+ DstHasDirectAccess = (DstFlags & DirectAccessBit) == DirectAccessBit,
JointAlignment = EIGEN_PLAIN_ENUM_MIN(DstAlignment,SrcAlignment)
};
@@ -83,7 +83,7 @@ private:
&& int(OuterStride)!=Dynamic && int(OuterStride)%int(InnerPacketSize)==0
&& (EIGEN_UNALIGNED_VECTORIZE || int(JointAlignment)>=int(InnerRequiredAlignment)),
MayLinearize = bool(StorageOrdersAgree) && (int(DstFlags) & int(SrcFlags) & LinearAccessBit),
- MayLinearVectorize = bool(MightVectorize) && MayLinearize && DstHasDirectAccess
+ MayLinearVectorize = bool(MightVectorize) && bool(MayLinearize) && bool(DstHasDirectAccess)
&& (EIGEN_UNALIGNED_VECTORIZE || (int(DstAlignment)>=int(LinearRequiredAlignment)) || MaxSizeAtCompileTime == Dynamic),
/* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
so it's only good for large enough sizes. */
diff --git a/xs/src/eigen/Eigen/src/Core/Assign_MKL.h b/xs/src/eigen/Eigen/src/Core/Assign_MKL.h
index 6c2ab9264..6866095bf 100644
--- a/xs/src/eigen/Eigen/src/Core/Assign_MKL.h
+++ b/xs/src/eigen/Eigen/src/Core/Assign_MKL.h
@@ -84,7 +84,8 @@ class vml_assign_traits
struct Assignment<DstXprType, CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested>, assign_op<EIGENTYPE,EIGENTYPE>, \
Dense2Dense, typename enable_if<vml_assign_traits<DstXprType,SrcXprNested>::EnableVml>::type> { \
typedef CwiseUnaryOp<scalar_##EIGENOP##_op<EIGENTYPE>, SrcXprNested> SrcXprType; \
- static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE,EIGENTYPE> &/*func*/) { \
+ static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE,EIGENTYPE> &func) { \
+ resize_if_allowed(dst, src, func); \
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) { \
VMLOP(dst.size(), (const VMLTYPE*)src.nestedExpression().data(), \
@@ -144,7 +145,8 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(ceil, Ceil, _)
Dense2Dense, typename enable_if<vml_assign_traits<DstXprType,SrcXprNested>::EnableVml>::type> { \
typedef CwiseBinaryOp<scalar_##EIGENOP##_op<EIGENTYPE,EIGENTYPE>, SrcXprNested, \
const CwiseNullaryOp<internal::scalar_constant_op<EIGENTYPE>,Plain> > SrcXprType; \
- static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE,EIGENTYPE> &/*func*/) { \
+ static void run(DstXprType &dst, const SrcXprType &src, const assign_op<EIGENTYPE,EIGENTYPE> &func) { \
+ resize_if_allowed(dst, src, func); \
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); \
VMLTYPE exponent = reinterpret_cast<const VMLTYPE&>(src.rhs().functor().m_other); \
if(vml_assign_traits<DstXprType,SrcXprNested>::Traversal==LinearTraversal) \
diff --git a/xs/src/eigen/Eigen/src/Core/CoreEvaluators.h b/xs/src/eigen/Eigen/src/Core/CoreEvaluators.h
index f7c1effca..910889efa 100644
--- a/xs/src/eigen/Eigen/src/Core/CoreEvaluators.h
+++ b/xs/src/eigen/Eigen/src/Core/CoreEvaluators.h
@@ -977,7 +977,7 @@ struct evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
OuterStrideAtCompileTime = HasSameStorageOrderAsArgType
? int(outer_stride_at_compile_time<ArgType>::ret)
: int(inner_stride_at_compile_time<ArgType>::ret),
- MaskPacketAccessBit = (InnerStrideAtCompileTime == 1) ? PacketAccessBit : 0,
+ MaskPacketAccessBit = (InnerStrideAtCompileTime == 1 || HasSameStorageOrderAsArgType) ? PacketAccessBit : 0,
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1 || (InnerPanel && (evaluator<ArgType>::Flags&LinearAccessBit))) ? LinearAccessBit : 0,
FlagsRowMajorBit = XprType::Flags&RowMajorBit,
@@ -987,7 +987,9 @@ struct evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit,
PacketAlignment = unpacket_traits<PacketScalar>::alignment,
- Alignment0 = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % int(PacketAlignment)) == 0)) ? int(PacketAlignment) : 0,
+ Alignment0 = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic)
+ && (OuterStrideAtCompileTime!=0)
+ && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % int(PacketAlignment)) == 0)) ? int(PacketAlignment) : 0,
Alignment = EIGEN_PLAIN_ENUM_MIN(evaluator<ArgType>::Alignment, Alignment0)
};
typedef block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel> block_evaluator_type;
@@ -1018,14 +1020,16 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& block)
: m_argImpl(block.nestedExpression()),
m_startRow(block.startRow()),
- m_startCol(block.startCol())
+ m_startCol(block.startCol()),
+ m_linear_offset(InnerPanel?(XprType::IsRowMajor ? block.startRow()*block.cols() : block.startCol()*block.rows()):0)
{ }
typedef typename XprType::Scalar Scalar;
typedef typename XprType::CoeffReturnType CoeffReturnType;
enum {
- RowsAtCompileTime = XprType::RowsAtCompileTime
+ RowsAtCompileTime = XprType::RowsAtCompileTime,
+ ForwardLinearAccess = InnerPanel && bool(evaluator<ArgType>::Flags&LinearAccessBit)
};
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
@@ -1037,7 +1041,10 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
CoeffReturnType coeff(Index index) const
{
- return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
+ if (ForwardLinearAccess)
+ return m_argImpl.coeff(m_linear_offset.value() + index);
+ else
+ return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
@@ -1049,7 +1056,10 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Scalar& coeffRef(Index index)
{
- return coeffRef(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
+ if (ForwardLinearAccess)
+ return m_argImpl.coeffRef(m_linear_offset.value() + index);
+ else
+ return coeffRef(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
}
template<int LoadMode, typename PacketType>
@@ -1063,8 +1073,11 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
EIGEN_STRONG_INLINE
PacketType packet(Index index) const
{
- return packet<LoadMode,PacketType>(RowsAtCompileTime == 1 ? 0 : index,
- RowsAtCompileTime == 1 ? index : 0);
+ if (ForwardLinearAccess)
+ return m_argImpl.template packet<LoadMode,PacketType>(m_linear_offset.value() + index);
+ else
+ return packet<LoadMode,PacketType>(RowsAtCompileTime == 1 ? 0 : index,
+ RowsAtCompileTime == 1 ? index : 0);
}
template<int StoreMode, typename PacketType>
@@ -1078,15 +1091,19 @@ struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBa
EIGEN_STRONG_INLINE
void writePacket(Index index, const PacketType& x)
{
- return writePacket<StoreMode,PacketType>(RowsAtCompileTime == 1 ? 0 : index,
- RowsAtCompileTime == 1 ? index : 0,
- x);
+ if (ForwardLinearAccess)
+ return m_argImpl.template writePacket<StoreMode,PacketType>(m_linear_offset.value() + index, x);
+ else
+ return writePacket<StoreMode,PacketType>(RowsAtCompileTime == 1 ? 0 : index,
+ RowsAtCompileTime == 1 ? index : 0,
+ x);
}
protected:
evaluator<ArgType> m_argImpl;
const variable_if_dynamic<Index, (ArgType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
const variable_if_dynamic<Index, (ArgType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
+ const variable_if_dynamic<Index, InnerPanel ? Dynamic : 0> m_linear_offset;
};
// TODO: This evaluator does not actually use the child evaluator;
diff --git a/xs/src/eigen/Eigen/src/Core/CwiseNullaryOp.h b/xs/src/eigen/Eigen/src/Core/CwiseNullaryOp.h
index dd498f758..ddd607e38 100644
--- a/xs/src/eigen/Eigen/src/Core/CwiseNullaryOp.h
+++ b/xs/src/eigen/Eigen/src/Core/CwiseNullaryOp.h
@@ -105,7 +105,7 @@ class CwiseNullaryOp : public internal::dense_xpr_base< CwiseNullaryOp<NullaryOp
*/
template<typename Derived>
template<typename CustomNullaryOp>
-EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
DenseBase<Derived>::NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func)
{
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(rows, cols, func);
@@ -150,7 +150,7 @@ DenseBase<Derived>::NullaryExpr(Index size, const CustomNullaryOp& func)
*/
template<typename Derived>
template<typename CustomNullaryOp>
-EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, typename DenseBase<Derived>::PlainObject>
DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func)
{
return CwiseNullaryOp<CustomNullaryOp, PlainObject>(RowsAtCompileTime, ColsAtCompileTime, func);
@@ -192,7 +192,7 @@ DenseBase<Derived>::Constant(Index rows, Index cols, const Scalar& value)
* \sa class CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Constant(Index size, const Scalar& value)
{
return DenseBase<Derived>::NullaryExpr(size, internal::scalar_constant_op<Scalar>(value));
@@ -208,7 +208,7 @@ DenseBase<Derived>::Constant(Index size, const Scalar& value)
* \sa class CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Constant(const Scalar& value)
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
@@ -220,7 +220,7 @@ DenseBase<Derived>::Constant(const Scalar& value)
* \sa LinSpaced(Index,Scalar,Scalar), setLinSpaced(Index,const Scalar&,const Scalar&)
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
@@ -232,7 +232,7 @@ DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const
* \sa LinSpaced(Scalar,Scalar)
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
@@ -264,7 +264,7 @@ DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& hig
* \sa setLinSpaced(Index,const Scalar&,const Scalar&), CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
@@ -276,7 +276,7 @@ DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
* Special version for fixed size types which does not require the size parameter.
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
@@ -286,7 +286,7 @@ DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */
template<typename Derived>
-bool DenseBase<Derived>::isApproxToConstant
+EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isApproxToConstant
(const Scalar& val, const RealScalar& prec) const
{
typename internal::nested_eval<Derived,1>::type self(derived());
@@ -301,7 +301,7 @@ bool DenseBase<Derived>::isApproxToConstant
*
* \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */
template<typename Derived>
-bool DenseBase<Derived>::isConstant
+EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isConstant
(const Scalar& val, const RealScalar& prec) const
{
return isApproxToConstant(val, prec);
@@ -312,7 +312,7 @@ bool DenseBase<Derived>::isConstant
* \sa setConstant(), Constant(), class CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& val)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& val)
{
setConstant(val);
}
@@ -322,7 +322,7 @@ EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& val)
* \sa fill(), setConstant(Index,const Scalar&), setConstant(Index,Index,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& val)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& val)
{
return derived() = Constant(rows(), cols(), val);
}
@@ -337,7 +337,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& val)
* \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived&
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
PlainObjectBase<Derived>::setConstant(Index size, const Scalar& val)
{
resize(size);
@@ -356,7 +356,7 @@ PlainObjectBase<Derived>::setConstant(Index size, const Scalar& val)
* \sa MatrixBase::setConstant(const Scalar&), setConstant(Index,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&)
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived&
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& val)
{
resize(rows, cols);
@@ -380,7 +380,7 @@ PlainObjectBase<Derived>::setConstant(Index rows, Index cols, const Scalar& val)
* \sa LinSpaced(Index,const Scalar&,const Scalar&), CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar,PacketScalar>(low,high,newSize));
@@ -400,7 +400,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, con
* \sa LinSpaced(Index,const Scalar&,const Scalar&), setLinSpaced(Index, const Scalar&, const Scalar&), CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low, const Scalar& high)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low, const Scalar& high)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return setLinSpaced(size(), low, high);
@@ -423,7 +423,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low,
* \sa Zero(), Zero(Index)
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Zero(Index rows, Index cols)
{
return Constant(rows, cols, Scalar(0));
@@ -446,7 +446,7 @@ DenseBase<Derived>::Zero(Index rows, Index cols)
* \sa Zero(), Zero(Index,Index)
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Zero(Index size)
{
return Constant(size, Scalar(0));
@@ -463,7 +463,7 @@ DenseBase<Derived>::Zero(Index size)
* \sa Zero(Index), Zero(Index,Index)
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Zero()
{
return Constant(Scalar(0));
@@ -478,7 +478,7 @@ DenseBase<Derived>::Zero()
* \sa class CwiseNullaryOp, Zero()
*/
template<typename Derived>
-bool DenseBase<Derived>::isZero(const RealScalar& prec) const
+EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isZero(const RealScalar& prec) const
{
typename internal::nested_eval<Derived,1>::type self(derived());
for(Index j = 0; j < cols(); ++j)
@@ -496,7 +496,7 @@ bool DenseBase<Derived>::isZero(const RealScalar& prec) const
* \sa class CwiseNullaryOp, Zero()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero()
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero()
{
return setConstant(Scalar(0));
}
@@ -511,7 +511,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero()
* \sa DenseBase::setZero(), setZero(Index,Index), class CwiseNullaryOp, DenseBase::Zero()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived&
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
PlainObjectBase<Derived>::setZero(Index newSize)
{
resize(newSize);
@@ -529,7 +529,7 @@ PlainObjectBase<Derived>::setZero(Index newSize)
* \sa DenseBase::setZero(), setZero(Index), class CwiseNullaryOp, DenseBase::Zero()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived&
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
PlainObjectBase<Derived>::setZero(Index rows, Index cols)
{
resize(rows, cols);
@@ -553,7 +553,7 @@ PlainObjectBase<Derived>::setZero(Index rows, Index cols)
* \sa Ones(), Ones(Index), isOnes(), class Ones
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Ones(Index rows, Index cols)
{
return Constant(rows, cols, Scalar(1));
@@ -576,7 +576,7 @@ DenseBase<Derived>::Ones(Index rows, Index cols)
* \sa Ones(), Ones(Index,Index), isOnes(), class Ones
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Ones(Index newSize)
{
return Constant(newSize, Scalar(1));
@@ -593,7 +593,7 @@ DenseBase<Derived>::Ones(Index newSize)
* \sa Ones(Index), Ones(Index,Index), isOnes(), class Ones
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType
DenseBase<Derived>::Ones()
{
return Constant(Scalar(1));
@@ -608,7 +608,7 @@ DenseBase<Derived>::Ones()
* \sa class CwiseNullaryOp, Ones()
*/
template<typename Derived>
-bool DenseBase<Derived>::isOnes
+EIGEN_DEVICE_FUNC bool DenseBase<Derived>::isOnes
(const RealScalar& prec) const
{
return isApproxToConstant(Scalar(1), prec);
@@ -622,7 +622,7 @@ bool DenseBase<Derived>::isOnes
* \sa class CwiseNullaryOp, Ones()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes()
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes()
{
return setConstant(Scalar(1));
}
@@ -637,7 +637,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes()
* \sa MatrixBase::setOnes(), setOnes(Index,Index), class CwiseNullaryOp, MatrixBase::Ones()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived&
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
PlainObjectBase<Derived>::setOnes(Index newSize)
{
resize(newSize);
@@ -655,7 +655,7 @@ PlainObjectBase<Derived>::setOnes(Index newSize)
* \sa MatrixBase::setOnes(), setOnes(Index), class CwiseNullaryOp, MatrixBase::Ones()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived&
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived&
PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
{
resize(rows, cols);
@@ -679,7 +679,7 @@ PlainObjectBase<Derived>::setOnes(Index rows, Index cols)
* \sa Identity(), setIdentity(), isIdentity()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
MatrixBase<Derived>::Identity(Index rows, Index cols)
{
return DenseBase<Derived>::NullaryExpr(rows, cols, internal::scalar_identity_op<Scalar>());
@@ -696,7 +696,7 @@ MatrixBase<Derived>::Identity(Index rows, Index cols)
* \sa Identity(Index,Index), setIdentity(), isIdentity()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::IdentityReturnType
MatrixBase<Derived>::Identity()
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
@@ -771,7 +771,7 @@ struct setIdentity_impl<Derived, true>
* \sa class CwiseNullaryOp, Identity(), Identity(Index,Index), isIdentity()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
{
return internal::setIdentity_impl<Derived>::run(derived());
}
@@ -787,7 +787,7 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity()
* \sa MatrixBase::setIdentity(), class CwiseNullaryOp, MatrixBase::Identity()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index cols)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index cols)
{
derived().resize(rows, cols);
return setIdentity();
@@ -800,7 +800,7 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setIdentity(Index rows, Index
* \sa MatrixBase::Unit(Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index newSize, Index i)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index newSize, Index i)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return BasisReturnType(SquareMatrixType::Identity(newSize,newSize), i);
@@ -815,7 +815,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
* \sa MatrixBase::Unit(Index,Index), MatrixBase::UnitX(), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index i)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::Unit(Index i)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return BasisReturnType(SquareMatrixType::Identity(),i);
@@ -828,7 +828,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitX()
{ return Derived::Unit(0); }
/** \returns an expression of the Y axis unit vector (0,1{,0}^*)
@@ -838,7 +838,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitY()
{ return Derived::Unit(1); }
/** \returns an expression of the Z axis unit vector (0,0,1{,0}^*)
@@ -848,7 +848,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitZ()
{ return Derived::Unit(2); }
/** \returns an expression of the W axis unit vector (0,0,0,1)
@@ -858,7 +858,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBa
* \sa MatrixBase::Unit(Index,Index), MatrixBase::Unit(Index), MatrixBase::UnitY(), MatrixBase::UnitZ(), MatrixBase::UnitW()
*/
template<typename Derived>
-EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::BasisReturnType MatrixBase<Derived>::UnitW()
{ return Derived::Unit(3); }
} // end namespace Eigen
diff --git a/xs/src/eigen/Eigen/src/Core/DenseBase.h b/xs/src/eigen/Eigen/src/Core/DenseBase.h
index 46fe5193c..90066ae73 100644
--- a/xs/src/eigen/Eigen/src/Core/DenseBase.h
+++ b/xs/src/eigen/Eigen/src/Core/DenseBase.h
@@ -296,7 +296,7 @@ template<typename Derived> class DenseBase
EIGEN_DEVICE_FUNC
Derived& operator=(const ReturnByValue<OtherDerived>& func);
- /** \ínternal
+ /** \internal
* Copies \a other into *this without evaluating other. \returns a reference to *this.
* \deprecated */
template<typename OtherDerived>
@@ -484,9 +484,9 @@ template<typename Derived> class DenseBase
return derived().coeff(0,0);
}
- bool all() const;
- bool any() const;
- Index count() const;
+ EIGEN_DEVICE_FUNC bool all() const;
+ EIGEN_DEVICE_FUNC bool any() const;
+ EIGEN_DEVICE_FUNC Index count() const;
typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType;
typedef const VectorwiseOp<const Derived, Horizontal> ConstRowwiseReturnType;
diff --git a/xs/src/eigen/Eigen/src/Core/Diagonal.h b/xs/src/eigen/Eigen/src/Core/Diagonal.h
index 49e711257..afcaf3575 100644
--- a/xs/src/eigen/Eigen/src/Core/Diagonal.h
+++ b/xs/src/eigen/Eigen/src/Core/Diagonal.h
@@ -70,7 +70,10 @@ template<typename MatrixType, int _DiagIndex> class Diagonal
EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal)
EIGEN_DEVICE_FUNC
- explicit inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index) {}
+ explicit inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex) : m_matrix(matrix), m_index(a_index)
+ {
+ eigen_assert( a_index <= m_matrix.cols() && -a_index <= m_matrix.rows() );
+ }
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
diff --git a/xs/src/eigen/Eigen/src/Core/Dot.h b/xs/src/eigen/Eigen/src/Core/Dot.h
index 06ef18b8b..1fe7a84a4 100644
--- a/xs/src/eigen/Eigen/src/Core/Dot.h
+++ b/xs/src/eigen/Eigen/src/Core/Dot.h
@@ -31,7 +31,8 @@ struct dot_nocheck
typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
typedef typename conj_prod::result_type ResScalar;
EIGEN_DEVICE_FUNC
- static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
+ EIGEN_STRONG_INLINE
+ static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
{
return a.template binaryExpr<conj_prod>(b).sum();
}
@@ -43,7 +44,8 @@ struct dot_nocheck<T, U, true>
typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
typedef typename conj_prod::result_type ResScalar;
EIGEN_DEVICE_FUNC
- static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
+ EIGEN_STRONG_INLINE
+ static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
{
return a.transpose().template binaryExpr<conj_prod>(b).sum();
}
@@ -65,6 +67,7 @@ struct dot_nocheck<T, U, true>
template<typename Derived>
template<typename OtherDerived>
EIGEN_DEVICE_FUNC
+EIGEN_STRONG_INLINE
typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
{
@@ -102,7 +105,7 @@ EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scala
* \sa lpNorm(), dot(), squaredNorm()
*/
template<typename Derived>
-inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
+EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
{
return numext::sqrt(squaredNorm());
}
@@ -117,7 +120,7 @@ inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real Matr
* \sa norm(), normalize()
*/
template<typename Derived>
-inline const typename MatrixBase<Derived>::PlainObject
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
MatrixBase<Derived>::normalized() const
{
typedef typename internal::nested_eval<Derived,2>::type _Nested;
@@ -139,7 +142,7 @@ MatrixBase<Derived>::normalized() const
* \sa norm(), normalized()
*/
template<typename Derived>
-inline void MatrixBase<Derived>::normalize()
+EIGEN_STRONG_INLINE void MatrixBase<Derived>::normalize()
{
RealScalar z = squaredNorm();
// NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
@@ -160,7 +163,7 @@ inline void MatrixBase<Derived>::normalize()
* \sa stableNorm(), stableNormalize(), normalized()
*/
template<typename Derived>
-inline const typename MatrixBase<Derived>::PlainObject
+EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
MatrixBase<Derived>::stableNormalized() const
{
typedef typename internal::nested_eval<Derived,3>::type _Nested;
@@ -185,7 +188,7 @@ MatrixBase<Derived>::stableNormalized() const
* \sa stableNorm(), stableNormalized(), normalize()
*/
template<typename Derived>
-inline void MatrixBase<Derived>::stableNormalize()
+EIGEN_STRONG_INLINE void MatrixBase<Derived>::stableNormalize()
{
RealScalar w = cwiseAbs().maxCoeff();
RealScalar z = (derived()/w).squaredNorm();
diff --git a/xs/src/eigen/Eigen/src/Core/EigenBase.h b/xs/src/eigen/Eigen/src/Core/EigenBase.h
index f76995af9..b195506a9 100644
--- a/xs/src/eigen/Eigen/src/Core/EigenBase.h
+++ b/xs/src/eigen/Eigen/src/Core/EigenBase.h
@@ -14,6 +14,7 @@
namespace Eigen {
/** \class EigenBase
+ * \ingroup Core_Module
*
* Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
*
@@ -128,6 +129,7 @@ template<typename Derived> struct EigenBase
*/
template<typename Derived>
template<typename OtherDerived>
+EIGEN_DEVICE_FUNC
Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
{
call_assignment(derived(), other.derived());
@@ -136,6 +138,7 @@ Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
template<typename Derived>
template<typename OtherDerived>
+EIGEN_DEVICE_FUNC
Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
{
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar,typename OtherDerived::Scalar>());
@@ -144,6 +147,7 @@ Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
template<typename Derived>
template<typename OtherDerived>
+EIGEN_DEVICE_FUNC
Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
{
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar,typename OtherDerived::Scalar>());
diff --git a/xs/src/eigen/Eigen/src/Core/GeneralProduct.h b/xs/src/eigen/Eigen/src/Core/GeneralProduct.h
index 0f16cd8e3..6f0cc80e9 100644
--- a/xs/src/eigen/Eigen/src/Core/GeneralProduct.h
+++ b/xs/src/eigen/Eigen/src/Core/GeneralProduct.h
@@ -24,12 +24,17 @@ template<int Rows, int Cols, int Depth> struct product_type_selector;
template<int Size, int MaxSize> struct product_size_category
{
- enum { is_large = MaxSize == Dynamic ||
- Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD ||
- (Size==Dynamic && MaxSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD),
- value = is_large ? Large
- : Size == 1 ? 1
- : Small
+ enum {
+ #ifndef EIGEN_CUDA_ARCH
+ is_large = MaxSize == Dynamic ||
+ Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD ||
+ (Size==Dynamic && MaxSize>=EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD),
+ #else
+ is_large = 0,
+ #endif
+ value = is_large ? Large
+ : Size == 1 ? 1
+ : Small
};
};
@@ -379,8 +384,6 @@ template<> struct gemv_dense_selector<OnTheRight,RowMajor,false>
*
* \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*()
*/
-#ifndef __CUDACC__
-
template<typename Derived>
template<typename OtherDerived>
inline const Product<Derived, OtherDerived>
@@ -412,8 +415,6 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
return Product<Derived, OtherDerived>(derived(), other.derived());
}
-#endif // __CUDACC__
-
/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation.
*
* The returned product will behave like any other expressions: the coefficients of the product will be
diff --git a/xs/src/eigen/Eigen/src/Core/GenericPacketMath.h b/xs/src/eigen/Eigen/src/Core/GenericPacketMath.h
index 27033a2dd..029f8ac36 100644
--- a/xs/src/eigen/Eigen/src/Core/GenericPacketMath.h
+++ b/xs/src/eigen/Eigen/src/Core/GenericPacketMath.h
@@ -230,7 +230,7 @@ pload1(const typename unpacket_traits<Packet>::type *a) { return pset1<Packet>(
* duplicated to form: {from[0],from[0],from[1],from[1],from[2],from[2],from[3],from[3]}
* Currently, this function is only used for scalar * complex products.
*/
-template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
+template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
ploaddup(const typename unpacket_traits<Packet>::type* from) { return *from; }
/** \internal \returns a packet with elements of \a *from quadrupled.
@@ -278,7 +278,7 @@ inline void pbroadcast2(const typename unpacket_traits<Packet>::type *a,
}
/** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */
-template<typename Packet> inline Packet
+template<typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet
plset(const typename unpacket_traits<Packet>::type& a) { return a; }
/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
@@ -482,7 +482,7 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE void pstoret(Scalar* to, const Packet& fro
* by the current computation.
*/
template<typename Packet, int LoadMode>
-inline Packet ploadt_ro(const typename unpacket_traits<Packet>::type* from)
+EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE Packet ploadt_ro(const typename unpacket_traits<Packet>::type* from)
{
return ploadt<Packet, LoadMode>(from);
}
diff --git a/xs/src/eigen/Eigen/src/Core/Map.h b/xs/src/eigen/Eigen/src/Core/Map.h
index 06d196702..548bf9a2d 100644
--- a/xs/src/eigen/Eigen/src/Core/Map.h
+++ b/xs/src/eigen/Eigen/src/Core/Map.h
@@ -20,11 +20,17 @@ struct traits<Map<PlainObjectType, MapOptions, StrideType> >
{
typedef traits<PlainObjectType> TraitsBase;
enum {
+ PlainObjectTypeInnerSize = ((traits<PlainObjectType>::Flags&RowMajorBit)==RowMajorBit)
+ ? PlainObjectType::ColsAtCompileTime
+ : PlainObjectType::RowsAtCompileTime,
+
InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0
? int(PlainObjectType::InnerStrideAtCompileTime)
: int(StrideType::InnerStrideAtCompileTime),
OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0
- ? int(PlainObjectType::OuterStrideAtCompileTime)
+ ? (InnerStrideAtCompileTime==Dynamic || PlainObjectTypeInnerSize==Dynamic
+ ? Dynamic
+ : int(InnerStrideAtCompileTime) * int(PlainObjectTypeInnerSize))
: int(StrideType::OuterStrideAtCompileTime),
Alignment = int(MapOptions)&int(AlignedMask),
Flags0 = TraitsBase::Flags & (~NestByRefBit),
@@ -107,10 +113,11 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
EIGEN_DEVICE_FUNC
inline Index outerStride() const
{
- return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
- : IsVectorAtCompileTime ? this->size()
- : int(Flags)&RowMajorBit ? this->cols()
- : this->rows();
+ return int(StrideType::OuterStrideAtCompileTime) != 0 ? m_stride.outer()
+ : int(internal::traits<Map>::OuterStrideAtCompileTime) != Dynamic ? Index(internal::traits<Map>::OuterStrideAtCompileTime)
+ : IsVectorAtCompileTime ? (this->size() * innerStride())
+ : (int(Flags)&RowMajorBit) ? (this->cols() * innerStride())
+ : (this->rows() * innerStride());
}
/** Constructor in the fixed-size case.
diff --git a/xs/src/eigen/Eigen/src/Core/MathFunctions.h b/xs/src/eigen/Eigen/src/Core/MathFunctions.h
index 8d47fb8a4..6eb974d41 100644
--- a/xs/src/eigen/Eigen/src/Core/MathFunctions.h
+++ b/xs/src/eigen/Eigen/src/Core/MathFunctions.h
@@ -348,31 +348,7 @@ struct norm1_retval
* Implementation of hypot *
****************************************************************************/
-template<typename Scalar>
-struct hypot_impl
-{
- typedef typename NumTraits<Scalar>::Real RealScalar;
- static inline RealScalar run(const Scalar& x, const Scalar& y)
- {
- EIGEN_USING_STD_MATH(abs);
- EIGEN_USING_STD_MATH(sqrt);
- RealScalar _x = abs(x);
- RealScalar _y = abs(y);
- Scalar p, qp;
- if(_x>_y)
- {
- p = _x;
- qp = _y / p;
- }
- else
- {
- p = _y;
- qp = _x / p;
- }
- if(p==RealScalar(0)) return RealScalar(0);
- return p * sqrt(RealScalar(1) + qp*qp);
- }
-};
+template<typename Scalar> struct hypot_impl;
template<typename Scalar>
struct hypot_retval
@@ -495,7 +471,7 @@ namespace std_fallback {
typedef typename NumTraits<Scalar>::Real RealScalar;
EIGEN_USING_STD_MATH(log);
Scalar x1p = RealScalar(1) + x;
- return ( x1p == Scalar(1) ) ? x : x * ( log(x1p) / (x1p - RealScalar(1)) );
+ return numext::equal_strict(x1p, Scalar(1)) ? x : x * ( log(x1p) / (x1p - RealScalar(1)) );
}
}
@@ -1061,11 +1037,24 @@ double log(const double &x) { return ::log(x); }
template<typename T>
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
-typename NumTraits<T>::Real abs(const T &x) {
+typename internal::enable_if<NumTraits<T>::IsSigned || NumTraits<T>::IsComplex,typename NumTraits<T>::Real>::type
+abs(const T &x) {
EIGEN_USING_STD_MATH(abs);
return abs(x);
}
+template<typename T>
+EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
+typename internal::enable_if<!(NumTraits<T>::IsSigned || NumTraits<T>::IsComplex),typename NumTraits<T>::Real>::type
+abs(const T &x) {
+ return x;
+}
+
+#if defined(__SYCL_DEVICE_ONLY__)
+EIGEN_ALWAYS_INLINE float abs(float x) { return cl::sycl::fabs(x); }
+EIGEN_ALWAYS_INLINE double abs(double x) { return cl::sycl::fabs(x); }
+#endif // defined(__SYCL_DEVICE_ONLY__)
+
#ifdef __CUDACC__
template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
float abs(const float &x) { return ::fabsf(x); }
diff --git a/xs/src/eigen/Eigen/src/Core/MathFunctionsImpl.h b/xs/src/eigen/Eigen/src/Core/MathFunctionsImpl.h
index 3c9ef22fa..9c1ceb0eb 100644
--- a/xs/src/eigen/Eigen/src/Core/MathFunctionsImpl.h
+++ b/xs/src/eigen/Eigen/src/Core/MathFunctionsImpl.h
@@ -71,6 +71,29 @@ T generic_fast_tanh_float(const T& a_x)
return pdiv(p, q);
}
+template<typename RealScalar>
+EIGEN_STRONG_INLINE
+RealScalar positive_real_hypot(const RealScalar& x, const RealScalar& y)
+{
+ EIGEN_USING_STD_MATH(sqrt);
+ RealScalar p, qp;
+ p = numext::maxi(x,y);
+ if(p==RealScalar(0)) return RealScalar(0);
+ qp = numext::mini(y,x) / p;
+ return p * sqrt(RealScalar(1) + qp*qp);
+}
+
+template<typename Scalar>
+struct hypot_impl
+{
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+ static inline RealScalar run(const Scalar& x, const Scalar& y)
+ {
+ EIGEN_USING_STD_MATH(abs);
+ return positive_real_hypot<RealScalar>(abs(x), abs(y));
+ }
+};
+
} // end namespace internal
} // end namespace Eigen
diff --git a/xs/src/eigen/Eigen/src/Core/MatrixBase.h b/xs/src/eigen/Eigen/src/Core/MatrixBase.h
index f7cf04cde..05db48813 100644
--- a/xs/src/eigen/Eigen/src/Core/MatrixBase.h
+++ b/xs/src/eigen/Eigen/src/Core/MatrixBase.h
@@ -160,20 +160,11 @@ template<typename Derived> class MatrixBase
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
Derived& operator-=(const MatrixBase<OtherDerived>& other);
-#ifdef __CUDACC__
template<typename OtherDerived>
EIGEN_DEVICE_FUNC
- const Product<Derived,OtherDerived,LazyProduct>
- operator*(const MatrixBase<OtherDerived> &other) const
- { return this->lazyProduct(other); }
-#else
-
- template<typename OtherDerived>
const Product<Derived,OtherDerived>
operator*(const MatrixBase<OtherDerived> &other) const;
-#endif
-
template<typename OtherDerived>
EIGEN_DEVICE_FUNC
const Product<Derived,OtherDerived,LazyProduct>
@@ -294,7 +285,7 @@ template<typename Derived> class MatrixBase
* fuzzy comparison such as isApprox()
* \sa isApprox(), operator!= */
template<typename OtherDerived>
- inline bool operator==(const MatrixBase<OtherDerived>& other) const
+ EIGEN_DEVICE_FUNC inline bool operator==(const MatrixBase<OtherDerived>& other) const
{ return cwiseEqual(other).all(); }
/** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other.
@@ -302,7 +293,7 @@ template<typename Derived> class MatrixBase
* fuzzy comparison such as isApprox()
* \sa isApprox(), operator== */
template<typename OtherDerived>
- inline bool operator!=(const MatrixBase<OtherDerived>& other) const
+ EIGEN_DEVICE_FUNC inline bool operator!=(const MatrixBase<OtherDerived>& other) const
{ return cwiseNotEqual(other).any(); }
NoAlias<Derived,Eigen::MatrixBase > noalias();
diff --git a/xs/src/eigen/Eigen/src/Core/NumTraits.h b/xs/src/eigen/Eigen/src/Core/NumTraits.h
index dd61195bc..daf489878 100644
--- a/xs/src/eigen/Eigen/src/Core/NumTraits.h
+++ b/xs/src/eigen/Eigen/src/Core/NumTraits.h
@@ -215,6 +215,8 @@ struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
static inline RealScalar epsilon() { return NumTraits<RealScalar>::epsilon(); }
EIGEN_DEVICE_FUNC
static inline RealScalar dummy_precision() { return NumTraits<RealScalar>::dummy_precision(); }
+
+ static inline int digits10() { return NumTraits<Scalar>::digits10(); }
};
template<> struct NumTraits<std::string>
diff --git a/xs/src/eigen/Eigen/src/Core/PlainObjectBase.h b/xs/src/eigen/Eigen/src/Core/PlainObjectBase.h
index 77f4f6066..1dc7e223a 100644
--- a/xs/src/eigen/Eigen/src/Core/PlainObjectBase.h
+++ b/xs/src/eigen/Eigen/src/Core/PlainObjectBase.h
@@ -577,6 +577,10 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
* while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned
* \a data pointers.
*
+ * Here is an example using strides:
+ * \include Matrix_Map_stride.cpp
+ * Output: \verbinclude Matrix_Map_stride.out
+ *
* \see class Map
*/
//@{
diff --git a/xs/src/eigen/Eigen/src/Core/Product.h b/xs/src/eigen/Eigen/src/Core/Product.h
index ae0c94b38..676c48027 100644
--- a/xs/src/eigen/Eigen/src/Core/Product.h
+++ b/xs/src/eigen/Eigen/src/Core/Product.h
@@ -97,8 +97,8 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option,
&& "if you wanted a coeff-wise or a dot product use the respective explicit functions");
}
- EIGEN_DEVICE_FUNC inline Index rows() const { return m_lhs.rows(); }
- EIGEN_DEVICE_FUNC inline Index cols() const { return m_rhs.cols(); }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
EIGEN_DEVICE_FUNC const LhsNestedCleaned& lhs() const { return m_lhs; }
EIGEN_DEVICE_FUNC const RhsNestedCleaned& rhs() const { return m_rhs; }
@@ -127,7 +127,7 @@ public:
using Base::derived;
typedef typename Base::Scalar Scalar;
- operator const Scalar() const
+ EIGEN_STRONG_INLINE operator const Scalar() const
{
return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
}
@@ -162,7 +162,7 @@ class ProductImpl<Lhs,Rhs,Option,Dense>
public:
- EIGEN_DEVICE_FUNC Scalar coeff(Index row, Index col) const
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index row, Index col) const
{
EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
@@ -170,7 +170,7 @@ class ProductImpl<Lhs,Rhs,Option,Dense>
return internal::evaluator<Derived>(derived()).coeff(row,col);
}
- EIGEN_DEVICE_FUNC Scalar coeff(Index i) const
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index i) const
{
EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
diff --git a/xs/src/eigen/Eigen/src/Core/ProductEvaluators.h b/xs/src/eigen/Eigen/src/Core/ProductEvaluators.h
index 583b7f59e..9b99bd769 100644
--- a/xs/src/eigen/Eigen/src/Core/ProductEvaluators.h
+++ b/xs/src/eigen/Eigen/src/Core/ProductEvaluators.h
@@ -32,7 +32,7 @@ struct evaluator<Product<Lhs, Rhs, Options> >
typedef Product<Lhs, Rhs, Options> XprType;
typedef product_evaluator<XprType> Base;
- EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr) : Base(xpr) {}
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr) : Base(xpr) {}
};
// Catch "scalar * ( A * B )" and transform it to "(A*scalar) * B"
@@ -55,7 +55,7 @@ struct evaluator<CwiseBinaryOp<internal::scalar_product_op<Scalar1,Scalar2>,
const Product<Lhs, Rhs, DefaultProduct> > XprType;
typedef evaluator<Product<EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar1,Lhs,product), Rhs, DefaultProduct> > Base;
- EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr)
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr)
: Base(xpr.lhs().functor().m_other * xpr.rhs().lhs() * xpr.rhs().rhs())
{}
};
@@ -68,7 +68,7 @@ struct evaluator<Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex> >
typedef Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex> XprType;
typedef evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex> > Base;
- EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr)
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr)
: Base(Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex>(
Product<Lhs, Rhs, LazyProduct>(xpr.nestedExpression().lhs(), xpr.nestedExpression().rhs()),
xpr.index() ))
@@ -207,6 +207,12 @@ struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_sum_op<typename
static const bool value = true;
};
+template<typename OtherXpr, typename Lhs, typename Rhs>
+struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_difference_op<typename OtherXpr::Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, const OtherXpr,
+ const Product<Lhs,Rhs,DefaultProduct> >, DenseShape > {
+ static const bool value = true;
+};
+
template<typename DstXprType, typename OtherXpr, typename ProductType, typename Func1, typename Func2>
struct assignment_from_xpr_op_product
{
@@ -240,19 +246,19 @@ template<typename Lhs, typename Rhs>
struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct>
{
template<typename Dst>
- static inline void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
+ static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
{
dst.coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum();
}
template<typename Dst>
- static inline void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
+ static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
{
dst.coeffRef(0,0) += (lhs.transpose().cwiseProduct(rhs)).sum();
}
template<typename Dst>
- static void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
+ static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
{ dst.coeffRef(0,0) -= (lhs.transpose().cwiseProduct(rhs)).sum(); }
};
@@ -306,25 +312,25 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,OuterProduct>
};
template<typename Dst>
- static inline void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
+ static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
{
internal::outer_product_selector_run(dst, lhs, rhs, set(), is_row_major<Dst>());
}
template<typename Dst>
- static inline void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
+ static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
{
internal::outer_product_selector_run(dst, lhs, rhs, add(), is_row_major<Dst>());
}
template<typename Dst>
- static inline void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
+ static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
{
internal::outer_product_selector_run(dst, lhs, rhs, sub(), is_row_major<Dst>());
}
template<typename Dst>
- static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
+ static EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
{
internal::outer_product_selector_run(dst, lhs, rhs, adds(alpha), is_row_major<Dst>());
}
@@ -779,7 +785,11 @@ public:
_Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagFlags)&PacketAccessBit))),
_LinearAccessMask = (MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1) ? LinearAccessBit : 0,
Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixFlags)) | (_Vectorizable ? PacketAccessBit : 0),
- Alignment = evaluator<MatrixType>::Alignment
+ Alignment = evaluator<MatrixType>::Alignment,
+
+ AsScalarProduct = (DiagonalType::SizeAtCompileTime==1)
+ || (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::RowsAtCompileTime==1 && ProductOrder==OnTheLeft)
+ || (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==1 && ProductOrder==OnTheRight)
};
diagonal_product_evaluator_base(const MatrixType &mat, const DiagonalType &diag)
@@ -791,7 +801,10 @@ public:
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const
{
- return m_diagImpl.coeff(idx) * m_matImpl.coeff(idx);
+ if(AsScalarProduct)
+ return m_diagImpl.coeff(0) * m_matImpl.coeff(idx);
+ else
+ return m_diagImpl.coeff(idx) * m_matImpl.coeff(idx);
}
protected:
diff --git a/xs/src/eigen/Eigen/src/Core/Redux.h b/xs/src/eigen/Eigen/src/Core/Redux.h
index b6e8f8887..760e9f861 100644
--- a/xs/src/eigen/Eigen/src/Core/Redux.h
+++ b/xs/src/eigen/Eigen/src/Core/Redux.h
@@ -407,7 +407,7 @@ protected:
*/
template<typename Derived>
template<typename Func>
-typename internal::traits<Derived>::Scalar
+EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
DenseBase<Derived>::redux(const Func& func) const
{
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
diff --git a/xs/src/eigen/Eigen/src/Core/Ref.h b/xs/src/eigen/Eigen/src/Core/Ref.h
index bdf24f52a..9c6e3c5d9 100644
--- a/xs/src/eigen/Eigen/src/Core/Ref.h
+++ b/xs/src/eigen/Eigen/src/Core/Ref.h
@@ -95,6 +95,8 @@ protected:
template<typename Expression>
EIGEN_DEVICE_FUNC void construct(Expression& expr)
{
+ EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(PlainObjectType,Expression);
+
if(PlainObjectType::RowsAtCompileTime==1)
{
eigen_assert(expr.rows()==1 || expr.cols()==1);
diff --git a/xs/src/eigen/Eigen/src/Core/SelfAdjointView.h b/xs/src/eigen/Eigen/src/Core/SelfAdjointView.h
index 504c98f0e..b2e51f37a 100644
--- a/xs/src/eigen/Eigen/src/Core/SelfAdjointView.h
+++ b/xs/src/eigen/Eigen/src/Core/SelfAdjointView.h
@@ -71,7 +71,9 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
EIGEN_DEVICE_FUNC
explicit inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix)
- {}
+ {
+ EIGEN_STATIC_ASSERT(UpLo==Lower || UpLo==Upper,SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY);
+ }
EIGEN_DEVICE_FUNC
inline Index rows() const { return m_matrix.rows(); }
@@ -189,7 +191,7 @@ template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView
TriangularView<typename MatrixType::AdjointReturnType,TriMode> >::type(tmp2);
}
- typedef SelfAdjointView<const MatrixConjugateReturnType,Mode> ConjugateReturnType;
+ typedef SelfAdjointView<const MatrixConjugateReturnType,UpLo> ConjugateReturnType;
/** \sa MatrixBase::conjugate() const */
EIGEN_DEVICE_FUNC
inline const ConjugateReturnType conjugate() const
diff --git a/xs/src/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h b/xs/src/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h
index 719ed72a5..7c89c2e23 100644
--- a/xs/src/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h
+++ b/xs/src/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h
@@ -15,33 +15,29 @@ namespace Eigen {
// TODO generalize the scalar type of 'other'
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator*=(const Scalar& other)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator*=(const Scalar& other)
{
- typedef typename Derived::PlainObject PlainObject;
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::mul_assign_op<Scalar,Scalar>());
return derived();
}
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator+=(const Scalar& other)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator+=(const Scalar& other)
{
- typedef typename Derived::PlainObject PlainObject;
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::add_assign_op<Scalar,Scalar>());
return derived();
}
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator-=(const Scalar& other)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& ArrayBase<Derived>::operator-=(const Scalar& other)
{
- typedef typename Derived::PlainObject PlainObject;
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::sub_assign_op<Scalar,Scalar>());
return derived();
}
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator/=(const Scalar& other)
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator/=(const Scalar& other)
{
- typedef typename Derived::PlainObject PlainObject;
internal::call_assignment(this->derived(), PlainObject::Constant(rows(),cols(),other), internal::div_assign_op<Scalar,Scalar>());
return derived();
}
diff --git a/xs/src/eigen/Eigen/src/Core/Solve.h b/xs/src/eigen/Eigen/src/Core/Solve.h
index 960a58597..a8daea511 100644
--- a/xs/src/eigen/Eigen/src/Core/Solve.h
+++ b/xs/src/eigen/Eigen/src/Core/Solve.h
@@ -34,12 +34,12 @@ template<typename Decomposition, typename RhsType,typename StorageKind> struct s
template<typename Decomposition, typename RhsType>
struct solve_traits<Decomposition,RhsType,Dense>
{
- typedef Matrix<typename RhsType::Scalar,
+ typedef typename make_proper_matrix_type<typename RhsType::Scalar,
Decomposition::ColsAtCompileTime,
RhsType::ColsAtCompileTime,
RhsType::PlainObject::Options,
Decomposition::MaxColsAtCompileTime,
- RhsType::MaxColsAtCompileTime> PlainObject;
+ RhsType::MaxColsAtCompileTime>::type PlainObject;
};
template<typename Decomposition, typename RhsType>
diff --git a/xs/src/eigen/Eigen/src/Core/StableNorm.h b/xs/src/eigen/Eigen/src/Core/StableNorm.h
index d2fe1e199..88c8d9890 100644
--- a/xs/src/eigen/Eigen/src/Core/StableNorm.h
+++ b/xs/src/eigen/Eigen/src/Core/StableNorm.h
@@ -165,12 +165,13 @@ MatrixBase<Derived>::stableNorm() const
typedef typename internal::nested_eval<Derived,2>::type DerivedCopy;
typedef typename internal::remove_all<DerivedCopy>::type DerivedCopyClean;
- DerivedCopy copy(derived());
+ const DerivedCopy copy(derived());
enum {
CanAlign = ( (int(DerivedCopyClean::Flags)&DirectAccessBit)
|| (int(internal::evaluator<DerivedCopyClean>::Alignment)>0) // FIXME Alignment)>0 might not be enough
- ) && (blockSize*sizeof(Scalar)*2<EIGEN_STACK_ALLOCATION_LIMIT) // ifwe cannot allocate on the stack, then let's not bother about this optimization
+ ) && (blockSize*sizeof(Scalar)*2<EIGEN_STACK_ALLOCATION_LIMIT)
+ && (EIGEN_MAX_STATIC_ALIGN_BYTES>0) // if we cannot allocate on the stack, then let's not bother about this optimization
};
typedef typename internal::conditional<CanAlign, Ref<const Matrix<Scalar,Dynamic,1,0,blockSize,1>, internal::evaluator<DerivedCopyClean>::Alignment>,
typename DerivedCopyClean::ConstSegmentReturnType>::type SegmentWrapper;
diff --git a/xs/src/eigen/Eigen/src/Core/Transpositions.h b/xs/src/eigen/Eigen/src/Core/Transpositions.h
index 19c17bb4a..86da5af59 100644
--- a/xs/src/eigen/Eigen/src/Core/Transpositions.h
+++ b/xs/src/eigen/Eigen/src/Core/Transpositions.h
@@ -384,7 +384,7 @@ class Transpose<TranspositionsBase<TranspositionsDerived> >
const Product<OtherDerived, Transpose, AliasFreeProduct>
operator*(const MatrixBase<OtherDerived>& matrix, const Transpose& trt)
{
- return Product<OtherDerived, Transpose, AliasFreeProduct>(matrix.derived(), trt.derived());
+ return Product<OtherDerived, Transpose, AliasFreeProduct>(matrix.derived(), trt);
}
/** \returns the \a matrix with the inverse transpositions applied to the rows.
diff --git a/xs/src/eigen/Eigen/src/Core/arch/AVX/Complex.h b/xs/src/eigen/Eigen/src/Core/arch/AVX/Complex.h
index 99439c8aa..7fa61969d 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/AVX/Complex.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/AVX/Complex.h
@@ -204,23 +204,7 @@ template<> struct conj_helper<Packet4cf, Packet4cf, true,true>
}
};
-template<> struct conj_helper<Packet8f, Packet4cf, false,false>
-{
- EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet8f& x, const Packet4cf& y, const Packet4cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet4cf pmul(const Packet8f& x, const Packet4cf& y) const
- { return Packet4cf(Eigen::internal::pmul(x, y.v)); }
-};
-
-template<> struct conj_helper<Packet4cf, Packet8f, false,false>
-{
- EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet4cf& x, const Packet8f& y, const Packet4cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet4cf pmul(const Packet4cf& x, const Packet8f& y) const
- { return Packet4cf(Eigen::internal::pmul(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet4cf,Packet8f)
template<> EIGEN_STRONG_INLINE Packet4cf pdiv<Packet4cf>(const Packet4cf& a, const Packet4cf& b)
{
@@ -400,23 +384,7 @@ template<> struct conj_helper<Packet2cd, Packet2cd, true,true>
}
};
-template<> struct conj_helper<Packet4d, Packet2cd, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet4d& x, const Packet2cd& y, const Packet2cd& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cd pmul(const Packet4d& x, const Packet2cd& y) const
- { return Packet2cd(Eigen::internal::pmul(x, y.v)); }
-};
-
-template<> struct conj_helper<Packet2cd, Packet4d, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet2cd& x, const Packet4d& y, const Packet2cd& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cd pmul(const Packet2cd& x, const Packet4d& y) const
- { return Packet2cd(Eigen::internal::pmul(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cd,Packet4d)
template<> EIGEN_STRONG_INLINE Packet2cd pdiv<Packet2cd>(const Packet2cd& a, const Packet2cd& b)
{
diff --git a/xs/src/eigen/Eigen/src/Core/arch/AVX/PacketMath.h b/xs/src/eigen/Eigen/src/Core/arch/AVX/PacketMath.h
index 195d40fb4..61c3dfcab 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/AVX/PacketMath.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/AVX/PacketMath.h
@@ -308,9 +308,9 @@ template<> EIGEN_STRONG_INLINE void pstore1<Packet8i>(int* to, const int& a)
}
#ifndef EIGEN_VECTORIZE_AVX512
-template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
-template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
-template<> EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
+template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
+template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
+template<> EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
#endif
template<> EIGEN_STRONG_INLINE float pfirst<Packet8f>(const Packet8f& a) {
@@ -333,9 +333,12 @@ template<> EIGEN_STRONG_INLINE Packet4d preverse(const Packet4d& a)
{
__m256d tmp = _mm256_shuffle_pd(a,a,5);
return _mm256_permute2f128_pd(tmp, tmp, 1);
-
+ #if 0
+ // This version is unlikely to be faster as _mm256_shuffle_ps and _mm256_permute_pd
+ // exhibit the same latency/throughput, but it is here for future reference/benchmarking...
__m256d swap_halves = _mm256_permute2f128_pd(a,a,1);
return _mm256_permute_pd(swap_halves,5);
+ #endif
}
// pabs should be ok
diff --git a/xs/src/eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h b/xs/src/eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h
index 399be0ee4..9c1717f76 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h
@@ -88,9 +88,9 @@ plog<Packet16f>(const Packet16f& _x) {
// x = x + x - 1.0;
// } else { x = x - 1.0; }
__mmask16 mask = _mm512_cmp_ps_mask(x, p16f_cephes_SQRTHF, _CMP_LT_OQ);
- Packet16f tmp = _mm512_mask_blend_ps(mask, x, _mm512_setzero_ps());
+ Packet16f tmp = _mm512_mask_blend_ps(mask, _mm512_setzero_ps(), x);
x = psub(x, p16f_1);
- e = psub(e, _mm512_mask_blend_ps(mask, p16f_1, _mm512_setzero_ps()));
+ e = psub(e, _mm512_mask_blend_ps(mask, _mm512_setzero_ps(), p16f_1));
x = padd(x, tmp);
Packet16f x2 = pmul(x, x);
@@ -119,8 +119,9 @@ plog<Packet16f>(const Packet16f& _x) {
x = padd(x, y2);
// Filter out invalid inputs, i.e. negative arg will be NAN, 0 will be -INF.
- return _mm512_mask_blend_ps(iszero_mask, p16f_minus_inf,
- _mm512_mask_blend_ps(invalid_mask, p16f_nan, x));
+ return _mm512_mask_blend_ps(iszero_mask,
+ _mm512_mask_blend_ps(invalid_mask, x, p16f_nan),
+ p16f_minus_inf);
}
#endif
@@ -266,8 +267,7 @@ psqrt<Packet16f>(const Packet16f& _x) {
// select only the inverse sqrt of positive normal inputs (denormals are
// flushed to zero and cause infs as well).
__mmask16 non_zero_mask = _mm512_cmp_ps_mask(_x, p16f_flt_min, _CMP_GE_OQ);
- Packet16f x = _mm512_mask_blend_ps(non_zero_mask, _mm512_rsqrt14_ps(_x),
- _mm512_setzero_ps());
+ Packet16f x = _mm512_mask_blend_ps(non_zero_mask, _mm512_setzero_ps(), _mm512_rsqrt14_ps(_x));
// Do a single step of Newton's iteration.
x = pmul(x, pmadd(neg_half, pmul(x, x), p16f_one_point_five));
@@ -289,8 +289,7 @@ psqrt<Packet8d>(const Packet8d& _x) {
// select only the inverse sqrt of positive normal inputs (denormals are
// flushed to zero and cause infs as well).
__mmask8 non_zero_mask = _mm512_cmp_pd_mask(_x, p8d_dbl_min, _CMP_GE_OQ);
- Packet8d x = _mm512_mask_blend_pd(non_zero_mask, _mm512_rsqrt14_pd(_x),
- _mm512_setzero_pd());
+ Packet8d x = _mm512_mask_blend_pd(non_zero_mask, _mm512_setzero_pd(), _mm512_rsqrt14_pd(_x));
// Do a first step of Newton's iteration.
x = pmul(x, pmadd(neg_half, pmul(x, x), p8d_one_point_five));
@@ -333,20 +332,18 @@ prsqrt<Packet16f>(const Packet16f& _x) {
// select only the inverse sqrt of positive normal inputs (denormals are
// flushed to zero and cause infs as well).
__mmask16 le_zero_mask = _mm512_cmp_ps_mask(_x, p16f_flt_min, _CMP_LT_OQ);
- Packet16f x = _mm512_mask_blend_ps(le_zero_mask, _mm512_setzero_ps(),
- _mm512_rsqrt14_ps(_x));
+ Packet16f x = _mm512_mask_blend_ps(le_zero_mask, _mm512_rsqrt14_ps(_x), _mm512_setzero_ps());
// Fill in NaNs and Infs for the negative/zero entries.
__mmask16 neg_mask = _mm512_cmp_ps_mask(_x, _mm512_setzero_ps(), _CMP_LT_OQ);
Packet16f infs_and_nans = _mm512_mask_blend_ps(
- neg_mask, p16f_nan,
- _mm512_mask_blend_ps(le_zero_mask, p16f_inf, _mm512_setzero_ps()));
+ neg_mask, _mm512_mask_blend_ps(le_zero_mask, _mm512_setzero_ps(), p16f_inf), p16f_nan);
// Do a single step of Newton's iteration.
x = pmul(x, pmadd(neg_half, pmul(x, x), p16f_one_point_five));
// Insert NaNs and Infs in all the right places.
- return _mm512_mask_blend_ps(le_zero_mask, infs_and_nans, x);
+ return _mm512_mask_blend_ps(le_zero_mask, x, infs_and_nans);
}
template <>
@@ -363,14 +360,12 @@ prsqrt<Packet8d>(const Packet8d& _x) {
// select only the inverse sqrt of positive normal inputs (denormals are
// flushed to zero and cause infs as well).
__mmask8 le_zero_mask = _mm512_cmp_pd_mask(_x, p8d_dbl_min, _CMP_LT_OQ);
- Packet8d x = _mm512_mask_blend_pd(le_zero_mask, _mm512_setzero_pd(),
- _mm512_rsqrt14_pd(_x));
+ Packet8d x = _mm512_mask_blend_pd(le_zero_mask, _mm512_rsqrt14_pd(_x), _mm512_setzero_pd());
// Fill in NaNs and Infs for the negative/zero entries.
__mmask8 neg_mask = _mm512_cmp_pd_mask(_x, _mm512_setzero_pd(), _CMP_LT_OQ);
Packet8d infs_and_nans = _mm512_mask_blend_pd(
- neg_mask, p8d_nan,
- _mm512_mask_blend_pd(le_zero_mask, p8d_inf, _mm512_setzero_pd()));
+ neg_mask, _mm512_mask_blend_pd(le_zero_mask, _mm512_setzero_pd(), p8d_inf), p8d_nan);
// Do a first step of Newton's iteration.
x = pmul(x, pmadd(neg_half, pmul(x, x), p8d_one_point_five));
@@ -379,9 +374,9 @@ prsqrt<Packet8d>(const Packet8d& _x) {
x = pmul(x, pmadd(neg_half, pmul(x, x), p8d_one_point_five));
// Insert NaNs and Infs in all the right places.
- return _mm512_mask_blend_pd(le_zero_mask, infs_and_nans, x);
+ return _mm512_mask_blend_pd(le_zero_mask, x, infs_and_nans);
}
-#else
+#elif defined(EIGEN_VECTORIZE_AVX512ER)
template <>
EIGEN_STRONG_INLINE Packet16f prsqrt<Packet16f>(const Packet16f& x) {
return _mm512_rsqrt28_ps(x);
diff --git a/xs/src/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h b/xs/src/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h
index f6500a16e..89705248a 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h
@@ -618,9 +618,9 @@ EIGEN_STRONG_INLINE void pstore1<Packet16i>(int* to, const int& a) {
pstore(to, pa);
}
-template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
-template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
-template<> EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
+template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
+template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
+template<> EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
template <>
EIGEN_STRONG_INLINE float pfirst<Packet16f>(const Packet16f& a) {
diff --git a/xs/src/eigen/Eigen/src/Core/arch/AltiVec/Complex.h b/xs/src/eigen/Eigen/src/Core/arch/AltiVec/Complex.h
index 67db2f8ee..3e665730c 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/AltiVec/Complex.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/AltiVec/Complex.h
@@ -224,23 +224,7 @@ template<> struct conj_helper<Packet2cf, Packet2cf, true,true>
}
};
-template<> struct conj_helper<Packet4f, Packet2cf, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet4f& x, const Packet2cf& y, const Packet2cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cf pmul(const Packet4f& x, const Packet2cf& y) const
- { return Packet2cf(internal::pmul<Packet4f>(x, y.v)); }
-};
-
-template<> struct conj_helper<Packet2cf, Packet4f, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet4f& y, const Packet2cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& x, const Packet4f& y) const
- { return Packet2cf(internal::pmul<Packet4f>(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f)
template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
{
@@ -416,23 +400,8 @@ template<> struct conj_helper<Packet1cd, Packet1cd, true,true>
return pconj(internal::pmul(a, b));
}
};
-template<> struct conj_helper<Packet2d, Packet1cd, false,false>
-{
- EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet2d& x, const Packet1cd& y, const Packet1cd& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet1cd pmul(const Packet2d& x, const Packet1cd& y) const
- { return Packet1cd(internal::pmul<Packet2d>(x, y.v)); }
-};
-template<> struct conj_helper<Packet1cd, Packet2d, false,false>
-{
- EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet2d& y, const Packet1cd& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& x, const Packet2d& y) const
- { return Packet1cd(internal::pmul<Packet2d>(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d)
template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
{
diff --git a/xs/src/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h b/xs/src/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h
index b3f1ea199..08a27d153 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h
@@ -103,7 +103,7 @@ static Packet16uc p16uc_PSET32_WODD = vec_sld((Packet16uc) vec_splat((Packet4u
static Packet16uc p16uc_PSET32_WEVEN = vec_sld(p16uc_DUPLICATE32_HI, (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 3), 8);//{ 4,5,6,7, 4,5,6,7, 12,13,14,15, 12,13,14,15 };
static Packet16uc p16uc_HALF64_0_16 = vec_sld((Packet16uc)p4i_ZERO, vec_splat((Packet16uc) vec_abs(p4i_MINUS16), 3), 8); //{ 0,0,0,0, 0,0,0,0, 16,16,16,16, 16,16,16,16};
#else
-static Packet16uc p16uc_FORWARD = p16uc_REVERSE32;
+static Packet16uc p16uc_FORWARD = p16uc_REVERSE32;
static Packet16uc p16uc_REVERSE64 = { 8,9,10,11, 12,13,14,15, 0,1,2,3, 4,5,6,7 };
static Packet16uc p16uc_PSET32_WODD = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 1), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 3), 8);//{ 0,1,2,3, 0,1,2,3, 8,9,10,11, 8,9,10,11 };
static Packet16uc p16uc_PSET32_WEVEN = vec_sld((Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 0), (Packet16uc) vec_splat((Packet4ui)p16uc_FORWARD, 2), 8);//{ 4,5,6,7, 4,5,6,7, 12,13,14,15, 12,13,14,15 };
@@ -388,10 +388,28 @@ template<> EIGEN_STRONG_INLINE Packet4i pdiv<Packet4i>(const Packet4i& /*a*/, co
template<> EIGEN_STRONG_INLINE Packet4f pmadd(const Packet4f& a, const Packet4f& b, const Packet4f& c) { return vec_madd(a,b,c); }
template<> EIGEN_STRONG_INLINE Packet4i pmadd(const Packet4i& a, const Packet4i& b, const Packet4i& c) { return a*b + c; }
-template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_min(a, b); }
+template<> EIGEN_STRONG_INLINE Packet4f pmin<Packet4f>(const Packet4f& a, const Packet4f& b)
+{
+ #ifdef __VSX__
+ Packet4f ret;
+ __asm__ ("xvcmpgesp %x0,%x1,%x2\n\txxsel %x0,%x1,%x2,%x0" : "=&wa" (ret) : "wa" (a), "wa" (b));
+ return ret;
+ #else
+ return vec_min(a, b);
+ #endif
+}
template<> EIGEN_STRONG_INLINE Packet4i pmin<Packet4i>(const Packet4i& a, const Packet4i& b) { return vec_min(a, b); }
-template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_max(a, b); }
+template<> EIGEN_STRONG_INLINE Packet4f pmax<Packet4f>(const Packet4f& a, const Packet4f& b)
+{
+ #ifdef __VSX__
+ Packet4f ret;
+ __asm__ ("xvcmpgtsp %x0,%x2,%x1\n\txxsel %x0,%x1,%x2,%x0" : "=&wa" (ret) : "wa" (a), "wa" (b));
+ return ret;
+ #else
+ return vec_max(a, b);
+ #endif
+}
template<> EIGEN_STRONG_INLINE Packet4i pmax<Packet4i>(const Packet4i& a, const Packet4i& b) { return vec_max(a, b); }
template<> EIGEN_STRONG_INLINE Packet4f pand<Packet4f>(const Packet4f& a, const Packet4f& b) { return vec_and(a, b); }
@@ -764,7 +782,7 @@ typedef __vector __bool long Packet2bl;
static Packet2l p2l_ONE = { 1, 1 };
static Packet2l p2l_ZERO = reinterpret_cast<Packet2l>(p4i_ZERO);
-static Packet2d p2d_ONE = { 1.0, 1.0 };
+static Packet2d p2d_ONE = { 1.0, 1.0 };
static Packet2d p2d_ZERO = reinterpret_cast<Packet2d>(p4f_ZERO);
static Packet2d p2d_MZERO = { -0.0, -0.0 };
@@ -910,9 +928,19 @@ template<> EIGEN_STRONG_INLINE Packet2d pdiv<Packet2d>(const Packet2d& a, const
// for some weird raisons, it has to be overloaded for packet of integers
template<> EIGEN_STRONG_INLINE Packet2d pmadd(const Packet2d& a, const Packet2d& b, const Packet2d& c) { return vec_madd(a, b, c); }
-template<> EIGEN_STRONG_INLINE Packet2d pmin<Packet2d>(const Packet2d& a, const Packet2d& b) { return vec_min(a, b); }
+template<> EIGEN_STRONG_INLINE Packet2d pmin<Packet2d>(const Packet2d& a, const Packet2d& b)
+{
+ Packet2d ret;
+ __asm__ ("xvcmpgedp %x0,%x1,%x2\n\txxsel %x0,%x1,%x2,%x0" : "=&wa" (ret) : "wa" (a), "wa" (b));
+ return ret;
+ }
-template<> EIGEN_STRONG_INLINE Packet2d pmax<Packet2d>(const Packet2d& a, const Packet2d& b) { return vec_max(a, b); }
+template<> EIGEN_STRONG_INLINE Packet2d pmax<Packet2d>(const Packet2d& a, const Packet2d& b)
+{
+ Packet2d ret;
+ __asm__ ("xvcmpgtdp %x0,%x2,%x1\n\txxsel %x0,%x1,%x2,%x0" : "=&wa" (ret) : "wa" (a), "wa" (b));
+ return ret;
+}
template<> EIGEN_STRONG_INLINE Packet2d pand<Packet2d>(const Packet2d& a, const Packet2d& b) { return vec_and(a, b); }
@@ -969,7 +997,7 @@ template<> EIGEN_STRONG_INLINE Packet2d preduxp<Packet2d>(const Packet2d* vecs)
Packet2d v[2], sum;
v[0] = vecs[0] + reinterpret_cast<Packet2d>(vec_sld(reinterpret_cast<Packet4f>(vecs[0]), reinterpret_cast<Packet4f>(vecs[0]), 8));
v[1] = vecs[1] + reinterpret_cast<Packet2d>(vec_sld(reinterpret_cast<Packet4f>(vecs[1]), reinterpret_cast<Packet4f>(vecs[1]), 8));
-
+
#ifdef _BIG_ENDIAN
sum = reinterpret_cast<Packet2d>(vec_sld(reinterpret_cast<Packet4f>(v[0]), reinterpret_cast<Packet4f>(v[1]), 8));
#else
@@ -1022,7 +1050,7 @@ ptranspose(PacketBlock<Packet2d,2>& kernel) {
template<> EIGEN_STRONG_INLINE Packet2d pblend(const Selector<2>& ifPacket, const Packet2d& thenPacket, const Packet2d& elsePacket) {
Packet2l select = { ifPacket.select[0], ifPacket.select[1] };
- Packet2bl mask = vec_cmpeq(reinterpret_cast<Packet2d>(select), reinterpret_cast<Packet2d>(p2l_ONE));
+ Packet2bl mask = reinterpret_cast<Packet2bl>( vec_cmpeq(reinterpret_cast<Packet2d>(select), reinterpret_cast<Packet2d>(p2l_ONE)) );
return vec_sel(elsePacket, thenPacket, mask);
}
#endif // __VSX__
diff --git a/xs/src/eigen/Eigen/src/Core/arch/CUDA/Half.h b/xs/src/eigen/Eigen/src/Core/arch/CUDA/Half.h
index 52892db38..02ac0c23a 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/CUDA/Half.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/CUDA/Half.h
@@ -13,7 +13,7 @@
// Redistribution and use in source and binary forms, with or without
// modification, are permitted.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// “AS IS†AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// "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 COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
@@ -147,55 +147,55 @@ namespace half_impl {
// versions to get the ALU speed increased), but you do save the
// conversion steps back and forth.
-__device__ half operator + (const half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ half operator + (const half& a, const half& b) {
return __hadd(a, b);
}
-__device__ half operator * (const half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ half operator * (const half& a, const half& b) {
return __hmul(a, b);
}
-__device__ half operator - (const half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ half operator - (const half& a, const half& b) {
return __hsub(a, b);
}
-__device__ half operator / (const half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ half operator / (const half& a, const half& b) {
float num = __half2float(a);
float denom = __half2float(b);
return __float2half(num / denom);
}
-__device__ half operator - (const half& a) {
+EIGEN_STRONG_INLINE __device__ half operator - (const half& a) {
return __hneg(a);
}
-__device__ half& operator += (half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ half& operator += (half& a, const half& b) {
a = a + b;
return a;
}
-__device__ half& operator *= (half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ half& operator *= (half& a, const half& b) {
a = a * b;
return a;
}
-__device__ half& operator -= (half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ half& operator -= (half& a, const half& b) {
a = a - b;
return a;
}
-__device__ half& operator /= (half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ half& operator /= (half& a, const half& b) {
a = a / b;
return a;
}
-__device__ bool operator == (const half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ bool operator == (const half& a, const half& b) {
return __heq(a, b);
}
-__device__ bool operator != (const half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ bool operator != (const half& a, const half& b) {
return __hne(a, b);
}
-__device__ bool operator < (const half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ bool operator < (const half& a, const half& b) {
return __hlt(a, b);
}
-__device__ bool operator <= (const half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ bool operator <= (const half& a, const half& b) {
return __hle(a, b);
}
-__device__ bool operator > (const half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ bool operator > (const half& a, const half& b) {
return __hgt(a, b);
}
-__device__ bool operator >= (const half& a, const half& b) {
+EIGEN_STRONG_INLINE __device__ bool operator >= (const half& a, const half& b) {
return __hge(a, b);
}
@@ -238,10 +238,10 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half& operator /= (half& a, const half& b)
return a;
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator == (const half& a, const half& b) {
- return float(a) == float(b);
+ return numext::equal_strict(float(a),float(b));
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator != (const half& a, const half& b) {
- return float(a) != float(b);
+ return numext::not_equal_strict(float(a), float(b));
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool operator < (const half& a, const half& b) {
return float(a) < float(b);
@@ -386,11 +386,15 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half abs(const half& a) {
return result;
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp(const half& a) {
- return half(::expf(float(a)));
+#if EIGEN_CUDACC_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530
+ return half(hexp(a));
+#else
+ return half(::expf(float(a)));
+#endif
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log(const half& a) {
-#if defined(EIGEN_HAS_CUDA_FP16) && defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 530
- return Eigen::half(::hlog(a));
+#if defined(EIGEN_HAS_CUDA_FP16) && EIGEN_CUDACC_VER >= 80000 && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530
+ return half(::hlog(a));
#else
return half(::logf(float(a)));
#endif
@@ -402,7 +406,11 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log10(const half& a) {
return half(::log10f(float(a)));
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half sqrt(const half& a) {
- return half(::sqrtf(float(a)));
+#if EIGEN_CUDACC_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530
+ return half(hsqrt(a));
+#else
+ return half(::sqrtf(float(a)));
+#endif
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half pow(const half& a, const half& b) {
return half(::powf(float(a), float(b)));
@@ -420,10 +428,18 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half tanh(const half& a) {
return half(::tanhf(float(a)));
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half floor(const half& a) {
+#if EIGEN_CUDACC_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 300
+ return half(hfloor(a));
+#else
return half(::floorf(float(a)));
+#endif
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half ceil(const half& a) {
+#if EIGEN_CUDACC_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 300
+ return half(hceil(a));
+#else
return half(::ceilf(float(a)));
+#endif
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half (min)(const half& a, const half& b) {
@@ -474,9 +490,59 @@ template<> struct is_arithmetic<half> { enum { value = true }; };
} // end namespace internal
+} // end namespace Eigen
+
+namespace std {
+template<>
+struct numeric_limits<Eigen::half> {
+ static const bool is_specialized = true;
+ static const bool is_signed = true;
+ static const bool is_integer = false;
+ static const bool is_exact = false;
+ static const bool has_infinity = true;
+ static const bool has_quiet_NaN = true;
+ static const bool has_signaling_NaN = true;
+ static const float_denorm_style has_denorm = denorm_present;
+ static const bool has_denorm_loss = false;
+ static const std::float_round_style round_style = std::round_to_nearest;
+ static const bool is_iec559 = false;
+ static const bool is_bounded = false;
+ static const bool is_modulo = false;
+ static const int digits = 11;
+ static const int digits10 = 3; // according to http://half.sourceforge.net/structstd_1_1numeric__limits_3_01half__float_1_1half_01_4.html
+ static const int max_digits10 = 5; // according to http://half.sourceforge.net/structstd_1_1numeric__limits_3_01half__float_1_1half_01_4.html
+ static const int radix = 2;
+ static const int min_exponent = -13;
+ static const int min_exponent10 = -4;
+ static const int max_exponent = 16;
+ static const int max_exponent10 = 4;
+ static const bool traps = true;
+ static const bool tinyness_before = false;
+
+ static Eigen::half (min)() { return Eigen::half_impl::raw_uint16_to_half(0x400); }
+ static Eigen::half lowest() { return Eigen::half_impl::raw_uint16_to_half(0xfbff); }
+ static Eigen::half (max)() { return Eigen::half_impl::raw_uint16_to_half(0x7bff); }
+ static Eigen::half epsilon() { return Eigen::half_impl::raw_uint16_to_half(0x0800); }
+ static Eigen::half round_error() { return Eigen::half(0.5); }
+ static Eigen::half infinity() { return Eigen::half_impl::raw_uint16_to_half(0x7c00); }
+ static Eigen::half quiet_NaN() { return Eigen::half_impl::raw_uint16_to_half(0x7e00); }
+ static Eigen::half signaling_NaN() { return Eigen::half_impl::raw_uint16_to_half(0x7e00); }
+ static Eigen::half denorm_min() { return Eigen::half_impl::raw_uint16_to_half(0x1); }
+};
+}
+
+namespace Eigen {
+
template<> struct NumTraits<Eigen::half>
: GenericNumTraits<Eigen::half>
{
+ enum {
+ IsSigned = true,
+ IsInteger = false,
+ IsComplex = false,
+ RequireInitialization = false
+ };
+
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Eigen::half epsilon() {
return half_impl::raw_uint16_to_half(0x0800);
}
@@ -507,7 +573,7 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half exph(const Eigen::half& a) {
return Eigen::half(::expf(float(a)));
}
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Eigen::half logh(const Eigen::half& a) {
-#if defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 530
+#if EIGEN_CUDACC_VER >= 80000 && defined(EIGEN_CUDA_ARCH) && EIGEN_CUDA_ARCH >= 530
return Eigen::half(::hlog(a));
#else
return Eigen::half(::logf(float(a)));
diff --git a/xs/src/eigen/Eigen/src/Core/arch/CUDA/PacketMath.h b/xs/src/eigen/Eigen/src/Core/arch/CUDA/PacketMath.h
index ad66399e0..4dda63188 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/CUDA/PacketMath.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/CUDA/PacketMath.h
@@ -291,7 +291,7 @@ template<> EIGEN_DEVICE_FUNC inline double2 pabs<double2>(const double2& a) {
EIGEN_DEVICE_FUNC inline void
ptranspose(PacketBlock<float4,4>& kernel) {
- double tmp = kernel.packet[0].y;
+ float tmp = kernel.packet[0].y;
kernel.packet[0].y = kernel.packet[1].x;
kernel.packet[1].x = tmp;
diff --git a/xs/src/eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h b/xs/src/eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h
index ae54225f8..943e0b06d 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h
@@ -275,7 +275,7 @@ template<> __device__ EIGEN_STRONG_INLINE half2 plog1p<half2>(const half2& a) {
return __floats2half2_rn(r1, r2);
}
-#if defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000 && defined __CUDA_ARCH__ && __CUDA_ARCH__ >= 530
+#if EIGEN_CUDACC_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530
template<> __device__ EIGEN_STRONG_INLINE
half2 plog<half2>(const half2& a) {
diff --git a/xs/src/eigen/Eigen/src/Core/arch/Default/ConjHelper.h b/xs/src/eigen/Eigen/src/Core/arch/Default/ConjHelper.h
new file mode 100644
index 000000000..4cfe34e05
--- /dev/null
+++ b/xs/src/eigen/Eigen/src/Core/arch/Default/ConjHelper.h
@@ -0,0 +1,29 @@
+
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_ARCH_CONJ_HELPER_H
+#define EIGEN_ARCH_CONJ_HELPER_H
+
+#define EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(PACKET_CPLX, PACKET_REAL) \
+ template<> struct conj_helper<PACKET_REAL, PACKET_CPLX, false,false> { \
+ EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_REAL& x, const PACKET_CPLX& y, const PACKET_CPLX& c) const \
+ { return padd(c, pmul(x,y)); } \
+ EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_REAL& x, const PACKET_CPLX& y) const \
+ { return PACKET_CPLX(Eigen::internal::pmul<PACKET_REAL>(x, y.v)); } \
+ }; \
+ \
+ template<> struct conj_helper<PACKET_CPLX, PACKET_REAL, false,false> { \
+ EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_CPLX& x, const PACKET_REAL& y, const PACKET_CPLX& c) const \
+ { return padd(c, pmul(x,y)); } \
+ EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_CPLX& x, const PACKET_REAL& y) const \
+ { return PACKET_CPLX(Eigen::internal::pmul<PACKET_REAL>(x.v, y)); } \
+ };
+
+#endif // EIGEN_ARCH_CONJ_HELPER_H
diff --git a/xs/src/eigen/Eigen/src/Core/arch/NEON/Complex.h b/xs/src/eigen/Eigen/src/Core/arch/NEON/Complex.h
index 57e9b431f..306a309be 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/NEON/Complex.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/NEON/Complex.h
@@ -67,7 +67,7 @@ template<> struct unpacket_traits<Packet2cf> { typedef std::complex<float> type;
template<> EIGEN_STRONG_INLINE Packet2cf pset1<Packet2cf>(const std::complex<float>& from)
{
float32x2_t r64;
- r64 = vld1_f32((float *)&from);
+ r64 = vld1_f32((const float *)&from);
return Packet2cf(vcombine_f32(r64, r64));
}
@@ -142,7 +142,7 @@ template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<float>, Packet2cf
to[stride*1] = std::complex<float>(vgetq_lane_f32(from.v, 2), vgetq_lane_f32(from.v, 3));
}
-template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> * addr) { EIGEN_ARM_PREFETCH((float *)addr); }
+template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> * addr) { EIGEN_ARM_PREFETCH((const float *)addr); }
template<> EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet2cf>(const Packet2cf& a)
{
@@ -265,6 +265,8 @@ template<> struct conj_helper<Packet2cf, Packet2cf, true,true>
}
};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f)
+
template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
{
// TODO optimize it for NEON
@@ -275,7 +277,7 @@ template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, con
s = vmulq_f32(b.v, b.v);
rev_s = vrev64q_f32(s);
- return Packet2cf(pdiv(res.v, vaddq_f32(s,rev_s)));
+ return Packet2cf(pdiv<Packet4f>(res.v, vaddq_f32(s,rev_s)));
}
EIGEN_DEVICE_FUNC inline void
@@ -381,7 +383,7 @@ template<> EIGEN_STRONG_INLINE Packet1cd ploaddup<Packet1cd>(const std::complex<
template<> EIGEN_STRONG_INLINE void pstore <std::complex<double> >(std::complex<double> * to, const Packet1cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, from.v); }
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double> * to, const Packet1cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, from.v); }
-template<> EIGEN_STRONG_INLINE void prefetch<std::complex<double> >(const std::complex<double> * addr) { EIGEN_ARM_PREFETCH((double *)addr); }
+template<> EIGEN_STRONG_INLINE void prefetch<std::complex<double> >(const std::complex<double> * addr) { EIGEN_ARM_PREFETCH((const double *)addr); }
template<> EIGEN_DEVICE_FUNC inline Packet1cd pgather<std::complex<double>, Packet1cd>(const std::complex<double>* from, Index stride)
{
@@ -456,6 +458,8 @@ template<> struct conj_helper<Packet1cd, Packet1cd, true,true>
}
};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d)
+
template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
{
// TODO optimize it for NEON
diff --git a/xs/src/eigen/Eigen/src/Core/arch/NEON/PacketMath.h b/xs/src/eigen/Eigen/src/Core/arch/NEON/PacketMath.h
index 84a56bdcc..3d5ed0d24 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/NEON/PacketMath.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/NEON/PacketMath.h
@@ -36,12 +36,43 @@ namespace internal {
#endif
#endif
+#if EIGEN_COMP_MSVC
+
+// In MSVC's arm_neon.h header file, all NEON vector types
+// are aliases to the same underlying type __n128.
+// We thus have to wrap them to make them different C++ types.
+// (See also bug 1428)
+
+template<typename T,int unique_id>
+struct eigen_packet_wrapper
+{
+ operator T&() { return m_val; }
+ operator const T&() const { return m_val; }
+ eigen_packet_wrapper() {}
+ eigen_packet_wrapper(const T &v) : m_val(v) {}
+ eigen_packet_wrapper& operator=(const T &v) {
+ m_val = v;
+ return *this;
+ }
+
+ T m_val;
+};
+typedef eigen_packet_wrapper<float32x2_t,0> Packet2f;
+typedef eigen_packet_wrapper<float32x4_t,1> Packet4f;
+typedef eigen_packet_wrapper<int32x4_t ,2> Packet4i;
+typedef eigen_packet_wrapper<int32x2_t ,3> Packet2i;
+typedef eigen_packet_wrapper<uint32x4_t ,4> Packet4ui;
+
+#else
+
typedef float32x2_t Packet2f;
typedef float32x4_t Packet4f;
typedef int32x4_t Packet4i;
typedef int32x2_t Packet2i;
typedef uint32x4_t Packet4ui;
+#endif // EIGEN_COMP_MSVC
+
#define _EIGEN_DECLARE_CONST_Packet4f(NAME,X) \
const Packet4f p4f_##NAME = pset1<Packet4f>(X)
@@ -51,14 +82,17 @@ typedef uint32x4_t Packet4ui;
#define _EIGEN_DECLARE_CONST_Packet4i(NAME,X) \
const Packet4i p4i_##NAME = pset1<Packet4i>(X)
-// arm64 does have the pld instruction. If available, let's trust the __builtin_prefetch built-in function
-// which available on LLVM and GCC (at least)
-#if EIGEN_HAS_BUILTIN(__builtin_prefetch) || EIGEN_COMP_GNUC
+#if EIGEN_ARCH_ARM64
+ // __builtin_prefetch tends to do nothing on ARM64 compilers because the
+ // prefetch instructions there are too detailed for __builtin_prefetch to map
+ // meaningfully to them.
+ #define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__("prfm pldl1keep, [%[addr]]\n" ::[addr] "r"(ADDR) : );
+#elif EIGEN_HAS_BUILTIN(__builtin_prefetch) || EIGEN_COMP_GNUC
#define EIGEN_ARM_PREFETCH(ADDR) __builtin_prefetch(ADDR);
#elif defined __pld
#define EIGEN_ARM_PREFETCH(ADDR) __pld(ADDR)
-#elif !EIGEN_ARCH_ARM64
- #define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__ ( " pld [%[addr]]\n" :: [addr] "r" (ADDR) : "cc" );
+#elif EIGEN_ARCH_ARM32
+ #define EIGEN_ARM_PREFETCH(ADDR) __asm__ __volatile__ ("pld [%[addr]]\n" :: [addr] "r" (ADDR) : );
#else
// by default no explicit prefetching
#define EIGEN_ARM_PREFETCH(ADDR)
@@ -113,7 +147,7 @@ template<> EIGEN_STRONG_INLINE Packet4i pset1<Packet4i>(const int32_t& from)
template<> EIGEN_STRONG_INLINE Packet4f plset<Packet4f>(const float& a)
{
- const float32_t f[] = {0, 1, 2, 3};
+ const float f[] = {0, 1, 2, 3};
Packet4f countdown = vld1q_f32(f);
return vaddq_f32(pset1<Packet4f>(a), countdown);
}
diff --git a/xs/src/eigen/Eigen/src/Core/arch/SSE/Complex.h b/xs/src/eigen/Eigen/src/Core/arch/SSE/Complex.h
index 5607fe0ab..d075043ce 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/SSE/Complex.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/SSE/Complex.h
@@ -128,7 +128,7 @@ template<> EIGEN_DEVICE_FUNC inline void pscatter<std::complex<float>, Packet2cf
_mm_cvtss_f32(_mm_shuffle_ps(from.v, from.v, 3)));
}
-template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> * addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
+template<> EIGEN_STRONG_INLINE void prefetch<std::complex<float> >(const std::complex<float> * addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
template<> EIGEN_STRONG_INLINE std::complex<float> pfirst<Packet2cf>(const Packet2cf& a)
{
@@ -229,23 +229,7 @@ template<> struct conj_helper<Packet2cf, Packet2cf, true,true>
}
};
-template<> struct conj_helper<Packet4f, Packet2cf, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet4f& x, const Packet2cf& y, const Packet2cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cf pmul(const Packet4f& x, const Packet2cf& y) const
- { return Packet2cf(Eigen::internal::pmul<Packet4f>(x, y.v)); }
-};
-
-template<> struct conj_helper<Packet2cf, Packet4f, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet4f& y, const Packet2cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& x, const Packet4f& y) const
- { return Packet2cf(Eigen::internal::pmul<Packet4f>(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f)
template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
{
@@ -340,7 +324,7 @@ template<> EIGEN_STRONG_INLINE Packet1cd ploaddup<Packet1cd>(const std::complex<
template<> EIGEN_STRONG_INLINE void pstore <std::complex<double> >(std::complex<double> * to, const Packet1cd& from) { EIGEN_DEBUG_ALIGNED_STORE pstore((double*)to, Packet2d(from.v)); }
template<> EIGEN_STRONG_INLINE void pstoreu<std::complex<double> >(std::complex<double> * to, const Packet1cd& from) { EIGEN_DEBUG_UNALIGNED_STORE pstoreu((double*)to, Packet2d(from.v)); }
-template<> EIGEN_STRONG_INLINE void prefetch<std::complex<double> >(const std::complex<double> * addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
+template<> EIGEN_STRONG_INLINE void prefetch<std::complex<double> >(const std::complex<double> * addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
template<> EIGEN_STRONG_INLINE std::complex<double> pfirst<Packet1cd>(const Packet1cd& a)
{
@@ -430,23 +414,7 @@ template<> struct conj_helper<Packet1cd, Packet1cd, true,true>
}
};
-template<> struct conj_helper<Packet2d, Packet1cd, false,false>
-{
- EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet2d& x, const Packet1cd& y, const Packet1cd& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet1cd pmul(const Packet2d& x, const Packet1cd& y) const
- { return Packet1cd(Eigen::internal::pmul<Packet2d>(x, y.v)); }
-};
-
-template<> struct conj_helper<Packet1cd, Packet2d, false,false>
-{
- EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet2d& y, const Packet1cd& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& x, const Packet2d& y) const
- { return Packet1cd(Eigen::internal::pmul<Packet2d>(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d)
template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
{
diff --git a/xs/src/eigen/Eigen/src/Core/arch/SSE/PacketMath.h b/xs/src/eigen/Eigen/src/Core/arch/SSE/PacketMath.h
index 3832de147..5e652cc79 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/SSE/PacketMath.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -409,10 +409,16 @@ template<> EIGEN_STRONG_INLINE void pstore1<Packet2d>(double* to, const double&
pstore(to, Packet2d(vec2d_swizzle1(pa,0,0)));
}
+#if EIGEN_COMP_PGI
+typedef const void * SsePrefetchPtrType;
+#else
+typedef const char * SsePrefetchPtrType;
+#endif
+
#ifndef EIGEN_VECTORIZE_AVX
-template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
-template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
-template<> EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) { _mm_prefetch((const char*)(addr), _MM_HINT_T0); }
+template<> EIGEN_STRONG_INLINE void prefetch<float>(const float* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
+template<> EIGEN_STRONG_INLINE void prefetch<double>(const double* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
+template<> EIGEN_STRONG_INLINE void prefetch<int>(const int* addr) { _mm_prefetch((SsePrefetchPtrType)(addr), _MM_HINT_T0); }
#endif
#if EIGEN_COMP_MSVC_STRICT && EIGEN_OS_WIN64
@@ -876,4 +882,14 @@ template<> EIGEN_STRONG_INLINE double pmadd(const double& a, const double& b, co
} // end namespace Eigen
+#if EIGEN_COMP_PGI
+// PGI++ does not define the following intrinsics in C++ mode.
+static inline __m128 _mm_castpd_ps (__m128d x) { return reinterpret_cast<__m128&>(x); }
+static inline __m128i _mm_castpd_si128(__m128d x) { return reinterpret_cast<__m128i&>(x); }
+static inline __m128d _mm_castps_pd (__m128 x) { return reinterpret_cast<__m128d&>(x); }
+static inline __m128i _mm_castps_si128(__m128 x) { return reinterpret_cast<__m128i&>(x); }
+static inline __m128 _mm_castsi128_ps(__m128i x) { return reinterpret_cast<__m128&>(x); }
+static inline __m128d _mm_castsi128_pd(__m128i x) { return reinterpret_cast<__m128d&>(x); }
+#endif
+
#endif // EIGEN_PACKET_MATH_SSE_H
diff --git a/xs/src/eigen/Eigen/src/Core/arch/SSE/TypeCasting.h b/xs/src/eigen/Eigen/src/Core/arch/SSE/TypeCasting.h
index c84893230..c6ca8c716 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/SSE/TypeCasting.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/SSE/TypeCasting.h
@@ -14,6 +14,7 @@ namespace Eigen {
namespace internal {
+#ifndef EIGEN_VECTORIZE_AVX
template <>
struct type_casting_traits<float, int> {
enum {
@@ -23,11 +24,6 @@ struct type_casting_traits<float, int> {
};
};
-template<> EIGEN_STRONG_INLINE Packet4i pcast<Packet4f, Packet4i>(const Packet4f& a) {
- return _mm_cvttps_epi32(a);
-}
-
-
template <>
struct type_casting_traits<int, float> {
enum {
@@ -37,11 +33,6 @@ struct type_casting_traits<int, float> {
};
};
-template<> EIGEN_STRONG_INLINE Packet4f pcast<Packet4i, Packet4f>(const Packet4i& a) {
- return _mm_cvtepi32_ps(a);
-}
-
-
template <>
struct type_casting_traits<double, float> {
enum {
@@ -51,10 +42,6 @@ struct type_casting_traits<double, float> {
};
};
-template<> EIGEN_STRONG_INLINE Packet4f pcast<Packet2d, Packet4f>(const Packet2d& a, const Packet2d& b) {
- return _mm_shuffle_ps(_mm_cvtpd_ps(a), _mm_cvtpd_ps(b), (1 << 2) | (1 << 6));
-}
-
template <>
struct type_casting_traits<float, double> {
enum {
@@ -63,6 +50,19 @@ struct type_casting_traits<float, double> {
TgtCoeffRatio = 2
};
};
+#endif
+
+template<> EIGEN_STRONG_INLINE Packet4i pcast<Packet4f, Packet4i>(const Packet4f& a) {
+ return _mm_cvttps_epi32(a);
+}
+
+template<> EIGEN_STRONG_INLINE Packet4f pcast<Packet4i, Packet4f>(const Packet4i& a) {
+ return _mm_cvtepi32_ps(a);
+}
+
+template<> EIGEN_STRONG_INLINE Packet4f pcast<Packet2d, Packet4f>(const Packet2d& a, const Packet2d& b) {
+ return _mm_shuffle_ps(_mm_cvtpd_ps(a), _mm_cvtpd_ps(b), (1 << 2) | (1 << 6));
+}
template<> EIGEN_STRONG_INLINE Packet2d pcast<Packet4f, Packet2d>(const Packet4f& a) {
// Simply discard the second half of the input
diff --git a/xs/src/eigen/Eigen/src/Core/arch/ZVector/Complex.h b/xs/src/eigen/Eigen/src/Core/arch/ZVector/Complex.h
index d39d2d105..1bfb73397 100644
--- a/xs/src/eigen/Eigen/src/Core/arch/ZVector/Complex.h
+++ b/xs/src/eigen/Eigen/src/Core/arch/ZVector/Complex.h
@@ -336,6 +336,9 @@ template<> struct conj_helper<Packet2cf, Packet2cf, true,true>
}
};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f)
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d)
+
template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
{
// TODO optimize it for AltiVec
diff --git a/xs/src/eigen/Eigen/src/Core/functors/BinaryFunctors.h b/xs/src/eigen/Eigen/src/Core/functors/BinaryFunctors.h
index 96747bac7..3eae6b8ca 100644
--- a/xs/src/eigen/Eigen/src/Core/functors/BinaryFunctors.h
+++ b/xs/src/eigen/Eigen/src/Core/functors/BinaryFunctors.h
@@ -255,7 +255,7 @@ struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_NEQ> : binary_op_base<LhsScalar,Rh
/** \internal
- * \brief Template functor to compute the hypot of two scalars
+ * \brief Template functor to compute the hypot of two \b positive \b and \b real scalars
*
* \sa MatrixBase::stableNorm(), class Redux
*/
@@ -263,22 +263,15 @@ template<typename Scalar>
struct scalar_hypot_op<Scalar,Scalar> : binary_op_base<Scalar,Scalar>
{
EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
-// typedef typename NumTraits<Scalar>::Real result_type;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
+
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar &x, const Scalar &y) const
{
- EIGEN_USING_STD_MATH(sqrt)
- Scalar p, qp;
- if(_x>_y)
- {
- p = _x;
- qp = _y / p;
- }
- else
- {
- p = _y;
- qp = _x / p;
- }
- return p * sqrt(Scalar(1) + qp*qp);
+ // This functor is used by hypotNorm only for which it is faster to first apply abs
+ // on all coefficients prior to reduction through hypot.
+ // This way we avoid calling abs on positive and real entries, and this also permits
+ // to seamlessly handle complexes. Otherwise we would have to handle both real and complexes
+ // through the same functor...
+ return internal::positive_real_hypot(x,y);
}
};
template<typename Scalar>
diff --git a/xs/src/eigen/Eigen/src/Core/functors/NullaryFunctors.h b/xs/src/eigen/Eigen/src/Core/functors/NullaryFunctors.h
index 6a30466fb..b03be0269 100644
--- a/xs/src/eigen/Eigen/src/Core/functors/NullaryFunctors.h
+++ b/xs/src/eigen/Eigen/src/Core/functors/NullaryFunctors.h
@@ -44,16 +44,16 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
{
linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
m_low(low), m_high(high), m_size1(num_steps==1 ? 1 : num_steps-1), m_step(num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1)),
- m_interPacket(plset<Packet>(0)),
m_flip(numext::abs(high)<numext::abs(low))
{}
template<typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const {
+ typedef typename NumTraits<Scalar>::Real RealScalar;
if(m_flip)
- return (i==0)? m_low : (m_high - (m_size1-i)*m_step);
+ return (i==0)? m_low : (m_high - RealScalar(m_size1-i)*m_step);
else
- return (i==m_size1)? m_high : (m_low + i*m_step);
+ return (i==m_size1)? m_high : (m_low + RealScalar(i)*m_step);
}
template<typename IndexType>
@@ -63,7 +63,7 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
// [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) )
if(m_flip)
{
- Packet pi = padd(pset1<Packet>(Scalar(i-m_size1)),m_interPacket);
+ Packet pi = plset<Packet>(Scalar(i-m_size1));
Packet res = padd(pset1<Packet>(m_high), pmul(pset1<Packet>(m_step), pi));
if(i==0)
res = pinsertfirst(res, m_low);
@@ -71,7 +71,7 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
}
else
{
- Packet pi = padd(pset1<Packet>(Scalar(i)),m_interPacket);
+ Packet pi = plset<Packet>(Scalar(i));
Packet res = padd(pset1<Packet>(m_low), pmul(pset1<Packet>(m_step), pi));
if(i==m_size1-unpacket_traits<Packet>::size+1)
res = pinsertlast(res, m_high);
@@ -83,7 +83,6 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
const Scalar m_high;
const Index m_size1;
const Scalar m_step;
- const Packet m_interPacket;
const bool m_flip;
};
diff --git a/xs/src/eigen/Eigen/src/Core/functors/StlFunctors.h b/xs/src/eigen/Eigen/src/Core/functors/StlFunctors.h
index 6df3fa501..9c1d75850 100644
--- a/xs/src/eigen/Eigen/src/Core/functors/StlFunctors.h
+++ b/xs/src/eigen/Eigen/src/Core/functors/StlFunctors.h
@@ -83,13 +83,17 @@ struct functor_traits<std::binder1st<T> >
{ enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
#endif
+#if (__cplusplus < 201703L) && (EIGEN_COMP_MSVC < 1910)
+// std::unary_negate is deprecated since c++17 and will be removed in c++20
template<typename T>
struct functor_traits<std::unary_negate<T> >
{ enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
+// std::binary_negate is deprecated since c++17 and will be removed in c++20
template<typename T>
struct functor_traits<std::binary_negate<T> >
{ enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
+#endif
#ifdef EIGEN_STDEXT_SUPPORT
diff --git a/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
index 7122efa60..e844e37d1 100644
--- a/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
+++ b/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
@@ -269,10 +269,13 @@ struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,false>
enum {
IsRowMajor = (internal::traits<MatrixType>::Flags&RowMajorBit) ? 1 : 0,
LhsIsRowMajor = _ActualLhs::Flags&RowMajorBit ? 1 : 0,
- RhsIsRowMajor = _ActualRhs::Flags&RowMajorBit ? 1 : 0
+ RhsIsRowMajor = _ActualRhs::Flags&RowMajorBit ? 1 : 0,
+ SkipDiag = (UpLo&(UnitDiag|ZeroDiag))!=0
};
Index size = mat.cols();
+ if(SkipDiag)
+ size--;
Index depth = actualLhs.cols();
typedef internal::gemm_blocking_space<IsRowMajor ? RowMajor : ColMajor,typename Lhs::Scalar,typename Rhs::Scalar,
@@ -283,10 +286,11 @@ struct general_product_to_triangular_selector<MatrixType,ProductType,UpLo,false>
internal::general_matrix_matrix_triangular_product<Index,
typename Lhs::Scalar, LhsIsRowMajor ? RowMajor : ColMajor, LhsBlasTraits::NeedToConjugate,
typename Rhs::Scalar, RhsIsRowMajor ? RowMajor : ColMajor, RhsBlasTraits::NeedToConjugate,
- IsRowMajor ? RowMajor : ColMajor, UpLo>
+ IsRowMajor ? RowMajor : ColMajor, UpLo&(Lower|Upper)>
::run(size, depth,
- &actualLhs.coeffRef(0,0), actualLhs.outerStride(), &actualRhs.coeffRef(0,0), actualRhs.outerStride(),
- mat.data(), mat.outerStride(), actualAlpha, blocking);
+ &actualLhs.coeffRef(SkipDiag&&(UpLo&Lower)==Lower ? 1 : 0,0), actualLhs.outerStride(),
+ &actualRhs.coeffRef(0,SkipDiag&&(UpLo&Upper)==Upper ? 1 : 0), actualRhs.outerStride(),
+ mat.data() + (SkipDiag ? (bool(IsRowMajor) != ((UpLo&Lower)==Lower) ? 1 : mat.outerStride() ) : 0), mat.outerStride(), actualAlpha, blocking);
}
};
@@ -294,6 +298,7 @@ template<typename MatrixType, unsigned int UpLo>
template<typename ProductType>
TriangularView<MatrixType,UpLo>& TriangularViewImpl<MatrixType,UpLo,Dense>::_assignProduct(const ProductType& prod, const Scalar& alpha, bool beta)
{
+ EIGEN_STATIC_ASSERT((UpLo&UnitDiag)==0, WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED);
eigen_assert(derived().nestedExpression().rows() == prod.rows() && derived().cols() == prod.cols());
general_product_to_triangular_selector<MatrixType, ProductType, UpLo, internal::traits<ProductType>::InnerSize==1>::run(derived().nestedExpression().const_cast_derived(), prod, alpha, beta);
diff --git a/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h b/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h
index 5b7c15cca..9176a1382 100644
--- a/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h
+++ b/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h
@@ -52,7 +52,7 @@ struct general_matrix_matrix_triangular_product<Index,Scalar,LhsStorageOrder,Con
static EIGEN_STRONG_INLINE void run(Index size, Index depth,const Scalar* lhs, Index lhsStride, \
const Scalar* rhs, Index rhsStride, Scalar* res, Index resStride, Scalar alpha, level3_blocking<Scalar, Scalar>& blocking) \
{ \
- if (lhs==rhs) { \
+ if ( lhs==rhs && ((UpLo&(Lower|Upper)==UpLo)) ) { \
general_matrix_matrix_rankupdate<Index,Scalar,LhsStorageOrder,ConjugateLhs,ColMajor,UpLo> \
::run(size,depth,lhs,lhsStride,rhs,rhsStride,res,resStride,alpha,blocking); \
} else { \
@@ -88,7 +88,7 @@ struct general_matrix_matrix_rankupdate<Index,EIGTYPE,AStorageOrder,ConjugateA,C
BlasIndex lda=convert_index<BlasIndex>(lhsStride), ldc=convert_index<BlasIndex>(resStride), n=convert_index<BlasIndex>(size), k=convert_index<BlasIndex>(depth); \
char uplo=((IsLower) ? 'L' : 'U'), trans=((AStorageOrder==RowMajor) ? 'T':'N'); \
EIGTYPE beta(1); \
- BLASFUNC(&uplo, &trans, &n, &k, &numext::real_ref(alpha), lhs, &lda, &numext::real_ref(beta), res, &ldc); \
+ BLASFUNC(&uplo, &trans, &n, &k, (const BLASTYPE*)&numext::real_ref(alpha), lhs, &lda, (const BLASTYPE*)&numext::real_ref(beta), res, &ldc); \
} \
};
@@ -125,9 +125,13 @@ struct general_matrix_matrix_rankupdate<Index,EIGTYPE,AStorageOrder,ConjugateA,C
} \
};
-
+#ifdef EIGEN_USE_MKL
+EIGEN_BLAS_RANKUPDATE_R(double, double, dsyrk)
+EIGEN_BLAS_RANKUPDATE_R(float, float, ssyrk)
+#else
EIGEN_BLAS_RANKUPDATE_R(double, double, dsyrk_)
EIGEN_BLAS_RANKUPDATE_R(float, float, ssyrk_)
+#endif
// TODO hanlde complex cases
// EIGEN_BLAS_RANKUPDATE_C(dcomplex, double, double, zherk_)
diff --git a/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h b/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h
index 7a3bdbf20..b0f6b0d5b 100644
--- a/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h
+++ b/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h
@@ -46,7 +46,7 @@ namespace internal {
// gemm specialization
-#define GEMM_SPECIALIZATION(EIGTYPE, EIGPREFIX, BLASTYPE, BLASPREFIX) \
+#define GEMM_SPECIALIZATION(EIGTYPE, EIGPREFIX, BLASTYPE, BLASFUNC) \
template< \
typename Index, \
int LhsStorageOrder, bool ConjugateLhs, \
@@ -100,13 +100,20 @@ static void run(Index rows, Index cols, Index depth, \
ldb = convert_index<BlasIndex>(b_tmp.outerStride()); \
} else b = _rhs; \
\
- BLASPREFIX##gemm_(&transa, &transb, &m, &n, &k, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, &numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
+ BLASFUNC(&transa, &transb, &m, &n, &k, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
}};
-GEMM_SPECIALIZATION(double, d, double, d)
-GEMM_SPECIALIZATION(float, f, float, s)
-GEMM_SPECIALIZATION(dcomplex, cd, double, z)
-GEMM_SPECIALIZATION(scomplex, cf, float, c)
+#ifdef EIGEN_USE_MKL
+GEMM_SPECIALIZATION(double, d, double, dgemm)
+GEMM_SPECIALIZATION(float, f, float, sgemm)
+GEMM_SPECIALIZATION(dcomplex, cd, MKL_Complex16, zgemm)
+GEMM_SPECIALIZATION(scomplex, cf, MKL_Complex8, cgemm)
+#else
+GEMM_SPECIALIZATION(double, d, double, dgemm_)
+GEMM_SPECIALIZATION(float, f, float, sgemm_)
+GEMM_SPECIALIZATION(dcomplex, cd, double, zgemm_)
+GEMM_SPECIALIZATION(scomplex, cf, float, cgemm_)
+#endif
} // end namespase internal
diff --git a/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixVector.h b/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixVector.h
index 3c1a7fc40..a597c1f4e 100644
--- a/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixVector.h
+++ b/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixVector.h
@@ -183,8 +183,8 @@ EIGEN_DONT_INLINE void general_matrix_vector_product<Index,LhsScalar,LhsMapper,C
alignmentPattern = AllAligned;
}
- const Index offset1 = (FirstAligned && alignmentStep==1)?3:1;
- const Index offset3 = (FirstAligned && alignmentStep==1)?1:3;
+ const Index offset1 = (alignmentPattern==FirstAligned && alignmentStep==1)?3:1;
+ const Index offset3 = (alignmentPattern==FirstAligned && alignmentStep==1)?1:3;
Index columnBound = ((cols-skipColumns)/columnsAtOnce)*columnsAtOnce + skipColumns;
for (Index i=skipColumns; i<columnBound; i+=columnsAtOnce)
@@ -457,8 +457,8 @@ EIGEN_DONT_INLINE void general_matrix_vector_product<Index,LhsScalar,LhsMapper,R
alignmentPattern = AllAligned;
}
- const Index offset1 = (FirstAligned && alignmentStep==1)?3:1;
- const Index offset3 = (FirstAligned && alignmentStep==1)?1:3;
+ const Index offset1 = (alignmentPattern==FirstAligned && alignmentStep==1)?3:1;
+ const Index offset3 = (alignmentPattern==FirstAligned && alignmentStep==1)?1:3;
Index rowBound = ((rows-skipRows)/rowsAtOnce)*rowsAtOnce + skipRows;
for (Index i=skipRows; i<rowBound; i+=rowsAtOnce)
diff --git a/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h b/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h
index e3a5d5892..6e36c2b3c 100644
--- a/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h
+++ b/xs/src/eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h
@@ -85,7 +85,7 @@ EIGEN_BLAS_GEMV_SPECIALIZE(float)
EIGEN_BLAS_GEMV_SPECIALIZE(dcomplex)
EIGEN_BLAS_GEMV_SPECIALIZE(scomplex)
-#define EIGEN_BLAS_GEMV_SPECIALIZATION(EIGTYPE,BLASTYPE,BLASPREFIX) \
+#define EIGEN_BLAS_GEMV_SPECIALIZATION(EIGTYPE,BLASTYPE,BLASFUNC) \
template<typename Index, int LhsStorageOrder, bool ConjugateLhs, bool ConjugateRhs> \
struct general_matrix_vector_product_gemv<Index,EIGTYPE,LhsStorageOrder,ConjugateLhs,EIGTYPE,ConjugateRhs> \
{ \
@@ -113,14 +113,21 @@ static void run( \
x_ptr=x_tmp.data(); \
incx=1; \
} else x_ptr=rhs; \
- BLASPREFIX##gemv_(&trans, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)lhs, &lda, (const BLASTYPE*)x_ptr, &incx, &numext::real_ref(beta), (BLASTYPE*)res, &incy); \
+ BLASFUNC(&trans, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)lhs, &lda, (const BLASTYPE*)x_ptr, &incx, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &incy); \
}\
};
-EIGEN_BLAS_GEMV_SPECIALIZATION(double, double, d)
-EIGEN_BLAS_GEMV_SPECIALIZATION(float, float, s)
-EIGEN_BLAS_GEMV_SPECIALIZATION(dcomplex, double, z)
-EIGEN_BLAS_GEMV_SPECIALIZATION(scomplex, float, c)
+#ifdef EIGEN_USE_MKL
+EIGEN_BLAS_GEMV_SPECIALIZATION(double, double, dgemv)
+EIGEN_BLAS_GEMV_SPECIALIZATION(float, float, sgemv)
+EIGEN_BLAS_GEMV_SPECIALIZATION(dcomplex, MKL_Complex16, zgemv)
+EIGEN_BLAS_GEMV_SPECIALIZATION(scomplex, MKL_Complex8 , cgemv)
+#else
+EIGEN_BLAS_GEMV_SPECIALIZATION(double, double, dgemv_)
+EIGEN_BLAS_GEMV_SPECIALIZATION(float, float, sgemv_)
+EIGEN_BLAS_GEMV_SPECIALIZATION(dcomplex, double, zgemv_)
+EIGEN_BLAS_GEMV_SPECIALIZATION(scomplex, float, cgemv_)
+#endif
} // end namespase internal
diff --git a/xs/src/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h b/xs/src/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h
index a45238d69..9a5318507 100644
--- a/xs/src/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h
+++ b/xs/src/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h
@@ -40,7 +40,7 @@ namespace internal {
/* Optimized selfadjoint matrix * matrix (?SYMM/?HEMM) product */
-#define EIGEN_BLAS_SYMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \
+#define EIGEN_BLAS_SYMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \
template <typename Index, \
int LhsStorageOrder, bool ConjugateLhs, \
int RhsStorageOrder, bool ConjugateRhs> \
@@ -81,13 +81,13 @@ struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,true,ConjugateLh
ldb = convert_index<BlasIndex>(b_tmp.outerStride()); \
} else b = _rhs; \
\
- BLASPREFIX##symm_(&side, &uplo, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, &numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
+ BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
\
} \
};
-#define EIGEN_BLAS_HEMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \
+#define EIGEN_BLAS_HEMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \
template <typename Index, \
int LhsStorageOrder, bool ConjugateLhs, \
int RhsStorageOrder, bool ConjugateRhs> \
@@ -144,20 +144,26 @@ struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,true,ConjugateLh
ldb = convert_index<BlasIndex>(b_tmp.outerStride()); \
} \
\
- BLASPREFIX##hemm_(&side, &uplo, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, &numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
+ BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
\
} \
};
-EIGEN_BLAS_SYMM_L(double, double, d, d)
-EIGEN_BLAS_SYMM_L(float, float, f, s)
-EIGEN_BLAS_HEMM_L(dcomplex, double, cd, z)
-EIGEN_BLAS_HEMM_L(scomplex, float, cf, c)
-
+#ifdef EIGEN_USE_MKL
+EIGEN_BLAS_SYMM_L(double, double, d, dsymm)
+EIGEN_BLAS_SYMM_L(float, float, f, ssymm)
+EIGEN_BLAS_HEMM_L(dcomplex, MKL_Complex16, cd, zhemm)
+EIGEN_BLAS_HEMM_L(scomplex, MKL_Complex8, cf, chemm)
+#else
+EIGEN_BLAS_SYMM_L(double, double, d, dsymm_)
+EIGEN_BLAS_SYMM_L(float, float, f, ssymm_)
+EIGEN_BLAS_HEMM_L(dcomplex, double, cd, zhemm_)
+EIGEN_BLAS_HEMM_L(scomplex, float, cf, chemm_)
+#endif
/* Optimized matrix * selfadjoint matrix (?SYMM/?HEMM) product */
-#define EIGEN_BLAS_SYMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \
+#define EIGEN_BLAS_SYMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \
template <typename Index, \
int LhsStorageOrder, bool ConjugateLhs, \
int RhsStorageOrder, bool ConjugateRhs> \
@@ -197,13 +203,13 @@ struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,false,ConjugateL
ldb = convert_index<BlasIndex>(b_tmp.outerStride()); \
} else b = _lhs; \
\
- BLASPREFIX##symm_(&side, &uplo, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, &numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
+ BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
\
} \
};
-#define EIGEN_BLAS_HEMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \
+#define EIGEN_BLAS_HEMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \
template <typename Index, \
int LhsStorageOrder, bool ConjugateLhs, \
int RhsStorageOrder, bool ConjugateRhs> \
@@ -259,15 +265,21 @@ struct product_selfadjoint_matrix<EIGTYPE,Index,LhsStorageOrder,false,ConjugateL
ldb = convert_index<BlasIndex>(b_tmp.outerStride()); \
} \
\
- BLASPREFIX##hemm_(&side, &uplo, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, &numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
+ BLASFUNC(&side, &uplo, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)b, &ldb, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &ldc); \
} \
};
-EIGEN_BLAS_SYMM_R(double, double, d, d)
-EIGEN_BLAS_SYMM_R(float, float, f, s)
-EIGEN_BLAS_HEMM_R(dcomplex, double, cd, z)
-EIGEN_BLAS_HEMM_R(scomplex, float, cf, c)
-
+#ifdef EIGEN_USE_MKL
+EIGEN_BLAS_SYMM_R(double, double, d, dsymm)
+EIGEN_BLAS_SYMM_R(float, float, f, ssymm)
+EIGEN_BLAS_HEMM_R(dcomplex, MKL_Complex16, cd, zhemm)
+EIGEN_BLAS_HEMM_R(scomplex, MKL_Complex8, cf, chemm)
+#else
+EIGEN_BLAS_SYMM_R(double, double, d, dsymm_)
+EIGEN_BLAS_SYMM_R(float, float, f, ssymm_)
+EIGEN_BLAS_HEMM_R(dcomplex, double, cd, zhemm_)
+EIGEN_BLAS_HEMM_R(scomplex, float, cf, chemm_)
+#endif
} // end namespace internal
} // end namespace Eigen
diff --git a/xs/src/eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h b/xs/src/eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h
index 38f23accf..1238345e3 100644
--- a/xs/src/eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h
+++ b/xs/src/eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h
@@ -95,14 +95,21 @@ const EIGTYPE* _rhs, EIGTYPE* res, EIGTYPE alpha) \
x_tmp=map_x.conjugate(); \
x_ptr=x_tmp.data(); \
} else x_ptr=_rhs; \
- BLASFUNC(&uplo, &n, &numext::real_ref(alpha), (const BLASTYPE*)lhs, &lda, (const BLASTYPE*)x_ptr, &incx, &numext::real_ref(beta), (BLASTYPE*)res, &incy); \
+ BLASFUNC(&uplo, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)lhs, &lda, (const BLASTYPE*)x_ptr, &incx, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)res, &incy); \
}\
};
+#ifdef EIGEN_USE_MKL
+EIGEN_BLAS_SYMV_SPECIALIZATION(double, double, dsymv)
+EIGEN_BLAS_SYMV_SPECIALIZATION(float, float, ssymv)
+EIGEN_BLAS_SYMV_SPECIALIZATION(dcomplex, MKL_Complex16, zhemv)
+EIGEN_BLAS_SYMV_SPECIALIZATION(scomplex, MKL_Complex8, chemv)
+#else
EIGEN_BLAS_SYMV_SPECIALIZATION(double, double, dsymv_)
EIGEN_BLAS_SYMV_SPECIALIZATION(float, float, ssymv_)
EIGEN_BLAS_SYMV_SPECIALIZATION(dcomplex, double, zhemv_)
EIGEN_BLAS_SYMV_SPECIALIZATION(scomplex, float, chemv_)
+#endif
} // end namespace internal
diff --git a/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h b/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h
index 6ec5a8a0b..f784507e7 100644
--- a/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h
+++ b/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h
@@ -137,7 +137,13 @@ EIGEN_DONT_INLINE void product_triangular_matrix_matrix<Scalar,Index,Mode,true,
ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
- Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,LhsStorageOrder> triangularBuffer((internal::constructor_without_unaligned_array_assert()));
+ // To work around an "error: member reference base type 'Matrix<...>
+ // (Eigen::internal::constructor_without_unaligned_array_assert (*)())' is
+ // not a structure or union" compilation error in nvcc (tested V8.0.61),
+ // create a dummy internal::constructor_without_unaligned_array_assert
+ // object to pass to the Matrix constructor.
+ internal::constructor_without_unaligned_array_assert a;
+ Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,LhsStorageOrder> triangularBuffer(a);
triangularBuffer.setZero();
if((Mode&ZeroDiag)==ZeroDiag)
triangularBuffer.diagonal().setZero();
@@ -284,7 +290,8 @@ EIGEN_DONT_INLINE void product_triangular_matrix_matrix<Scalar,Index,Mode,false,
ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
- Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,RhsStorageOrder> triangularBuffer((internal::constructor_without_unaligned_array_assert()));
+ internal::constructor_without_unaligned_array_assert a;
+ Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,RhsStorageOrder> triangularBuffer(a);
triangularBuffer.setZero();
if((Mode&ZeroDiag)==ZeroDiag)
triangularBuffer.diagonal().setZero();
@@ -393,7 +400,9 @@ struct triangular_product_impl<Mode,LhsIsTriangular,Lhs,false,Rhs,false>
{
template<typename Dest> static void run(Dest& dst, const Lhs &a_lhs, const Rhs &a_rhs, const typename Dest::Scalar& alpha)
{
- typedef typename Dest::Scalar Scalar;
+ typedef typename Lhs::Scalar LhsScalar;
+ typedef typename Rhs::Scalar RhsScalar;
+ typedef typename Dest::Scalar Scalar;
typedef internal::blas_traits<Lhs> LhsBlasTraits;
typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
@@ -405,8 +414,9 @@ struct triangular_product_impl<Mode,LhsIsTriangular,Lhs,false,Rhs,false>
typename internal::add_const_on_value_type<ActualLhsType>::type lhs = LhsBlasTraits::extract(a_lhs);
typename internal::add_const_on_value_type<ActualRhsType>::type rhs = RhsBlasTraits::extract(a_rhs);
- Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(a_lhs)
- * RhsBlasTraits::extractScalarFactor(a_rhs);
+ LhsScalar lhs_alpha = LhsBlasTraits::extractScalarFactor(a_lhs);
+ RhsScalar rhs_alpha = RhsBlasTraits::extractScalarFactor(a_rhs);
+ Scalar actualAlpha = alpha * lhs_alpha * rhs_alpha;
typedef internal::gemm_blocking_space<(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor,Scalar,Scalar,
Lhs::MaxRowsAtCompileTime, Rhs::MaxColsAtCompileTime, Lhs::MaxColsAtCompileTime,4> BlockingType;
@@ -431,6 +441,21 @@ struct triangular_product_impl<Mode,LhsIsTriangular,Lhs,false,Rhs,false>
&dst.coeffRef(0,0), dst.outerStride(), // result info
actualAlpha, blocking
);
+
+ // Apply correction if the diagonal is unit and a scalar factor was nested:
+ if ((Mode&UnitDiag)==UnitDiag)
+ {
+ if (LhsIsTriangular && lhs_alpha!=LhsScalar(1))
+ {
+ Index diagSize = (std::min)(lhs.rows(),lhs.cols());
+ dst.topRows(diagSize) -= ((lhs_alpha-LhsScalar(1))*a_rhs).topRows(diagSize);
+ }
+ else if ((!LhsIsTriangular) && rhs_alpha!=RhsScalar(1))
+ {
+ Index diagSize = (std::min)(rhs.rows(),rhs.cols());
+ dst.leftCols(diagSize) -= (rhs_alpha-RhsScalar(1))*a_lhs.leftCols(diagSize);
+ }
+ }
}
};
diff --git a/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h b/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h
index aecded6bb..a25197ab0 100644
--- a/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h
+++ b/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h
@@ -75,7 +75,7 @@ EIGEN_BLAS_TRMM_SPECIALIZE(scomplex, true)
EIGEN_BLAS_TRMM_SPECIALIZE(scomplex, false)
// implements col-major += alpha * op(triangular) * op(general)
-#define EIGEN_BLAS_TRMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \
+#define EIGEN_BLAS_TRMM_L(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \
template <typename Index, int Mode, \
int LhsStorageOrder, bool ConjugateLhs, \
int RhsStorageOrder, bool ConjugateRhs> \
@@ -172,7 +172,7 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,true, \
} \
/*std::cout << "TRMM_L: A is square! Go to BLAS TRMM implementation! \n";*/ \
/* call ?trmm*/ \
- BLASPREFIX##trmm_(&side, &uplo, &transa, &diag, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (BLASTYPE*)b, &ldb); \
+ BLASFUNC(&side, &uplo, &transa, &diag, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (BLASTYPE*)b, &ldb); \
\
/* Add op(a_triangular)*b into res*/ \
Map<MatrixX##EIGPREFIX, 0, OuterStride<> > res_tmp(res,rows,cols,OuterStride<>(resStride)); \
@@ -180,13 +180,20 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,true, \
} \
};
-EIGEN_BLAS_TRMM_L(double, double, d, d)
-EIGEN_BLAS_TRMM_L(dcomplex, double, cd, z)
-EIGEN_BLAS_TRMM_L(float, float, f, s)
-EIGEN_BLAS_TRMM_L(scomplex, float, cf, c)
+#ifdef EIGEN_USE_MKL
+EIGEN_BLAS_TRMM_L(double, double, d, dtrmm)
+EIGEN_BLAS_TRMM_L(dcomplex, MKL_Complex16, cd, ztrmm)
+EIGEN_BLAS_TRMM_L(float, float, f, strmm)
+EIGEN_BLAS_TRMM_L(scomplex, MKL_Complex8, cf, ctrmm)
+#else
+EIGEN_BLAS_TRMM_L(double, double, d, dtrmm_)
+EIGEN_BLAS_TRMM_L(dcomplex, double, cd, ztrmm_)
+EIGEN_BLAS_TRMM_L(float, float, f, strmm_)
+EIGEN_BLAS_TRMM_L(scomplex, float, cf, ctrmm_)
+#endif
// implements col-major += alpha * op(general) * op(triangular)
-#define EIGEN_BLAS_TRMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \
+#define EIGEN_BLAS_TRMM_R(EIGTYPE, BLASTYPE, EIGPREFIX, BLASFUNC) \
template <typename Index, int Mode, \
int LhsStorageOrder, bool ConjugateLhs, \
int RhsStorageOrder, bool ConjugateRhs> \
@@ -282,7 +289,7 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,false, \
} \
/*std::cout << "TRMM_R: A is square! Go to BLAS TRMM implementation! \n";*/ \
/* call ?trmm*/ \
- BLASPREFIX##trmm_(&side, &uplo, &transa, &diag, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (BLASTYPE*)b, &ldb); \
+ BLASFUNC(&side, &uplo, &transa, &diag, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (BLASTYPE*)b, &ldb); \
\
/* Add op(a_triangular)*b into res*/ \
Map<MatrixX##EIGPREFIX, 0, OuterStride<> > res_tmp(res,rows,cols,OuterStride<>(resStride)); \
@@ -290,11 +297,17 @@ struct product_triangular_matrix_matrix_trmm<EIGTYPE,Index,Mode,false, \
} \
};
-EIGEN_BLAS_TRMM_R(double, double, d, d)
-EIGEN_BLAS_TRMM_R(dcomplex, double, cd, z)
-EIGEN_BLAS_TRMM_R(float, float, f, s)
-EIGEN_BLAS_TRMM_R(scomplex, float, cf, c)
-
+#ifdef EIGEN_USE_MKL
+EIGEN_BLAS_TRMM_R(double, double, d, dtrmm)
+EIGEN_BLAS_TRMM_R(dcomplex, MKL_Complex16, cd, ztrmm)
+EIGEN_BLAS_TRMM_R(float, float, f, strmm)
+EIGEN_BLAS_TRMM_R(scomplex, MKL_Complex8, cf, ctrmm)
+#else
+EIGEN_BLAS_TRMM_R(double, double, d, dtrmm_)
+EIGEN_BLAS_TRMM_R(dcomplex, double, cd, ztrmm_)
+EIGEN_BLAS_TRMM_R(float, float, f, strmm_)
+EIGEN_BLAS_TRMM_R(scomplex, float, cf, ctrmm_)
+#endif
} // end namespace internal
} // end namespace Eigen
diff --git a/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixVector.h b/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixVector.h
index 4b292e74d..76bfa159c 100644
--- a/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixVector.h
+++ b/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixVector.h
@@ -221,8 +221,9 @@ template<int Mode> struct trmv_selector<Mode,ColMajor>
typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
typename internal::add_const_on_value_type<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
- ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs)
- * RhsBlasTraits::extractScalarFactor(rhs);
+ LhsScalar lhs_alpha = LhsBlasTraits::extractScalarFactor(lhs);
+ RhsScalar rhs_alpha = RhsBlasTraits::extractScalarFactor(rhs);
+ ResScalar actualAlpha = alpha * lhs_alpha * rhs_alpha;
enum {
// FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1
@@ -274,6 +275,12 @@ template<int Mode> struct trmv_selector<Mode,ColMajor>
else
dest = MappedDest(actualDestPtr, dest.size());
}
+
+ if ( ((Mode&UnitDiag)==UnitDiag) && (lhs_alpha!=LhsScalar(1)) )
+ {
+ Index diagSize = (std::min)(lhs.rows(),lhs.cols());
+ dest.head(diagSize) -= (lhs_alpha-LhsScalar(1))*rhs.head(diagSize);
+ }
}
};
@@ -295,8 +302,9 @@ template<int Mode> struct trmv_selector<Mode,RowMajor>
typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
- ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs)
- * RhsBlasTraits::extractScalarFactor(rhs);
+ LhsScalar lhs_alpha = LhsBlasTraits::extractScalarFactor(lhs);
+ RhsScalar rhs_alpha = RhsBlasTraits::extractScalarFactor(rhs);
+ ResScalar actualAlpha = alpha * lhs_alpha * rhs_alpha;
enum {
DirectlyUseRhs = ActualRhsTypeCleaned::InnerStrideAtCompileTime==1
@@ -326,6 +334,12 @@ template<int Mode> struct trmv_selector<Mode,RowMajor>
actualRhsPtr,1,
dest.data(),dest.innerStride(),
actualAlpha);
+
+ if ( ((Mode&UnitDiag)==UnitDiag) && (lhs_alpha!=LhsScalar(1)) )
+ {
+ Index diagSize = (std::min)(lhs.rows(),lhs.cols());
+ dest.head(diagSize) -= (lhs_alpha-LhsScalar(1))*rhs.head(diagSize);
+ }
}
};
diff --git a/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h b/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h
index 07bf26ce5..3d47a2b94 100644
--- a/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h
+++ b/xs/src/eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h
@@ -71,7 +71,7 @@ EIGEN_BLAS_TRMV_SPECIALIZE(dcomplex)
EIGEN_BLAS_TRMV_SPECIALIZE(scomplex)
// implements col-major: res += alpha * op(triangular) * vector
-#define EIGEN_BLAS_TRMV_CM(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \
+#define EIGEN_BLAS_TRMV_CM(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX, BLASPOSTFIX) \
template<typename Index, int Mode, bool ConjLhs, bool ConjRhs> \
struct triangular_matrix_vector_product_trmv<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,ConjRhs,ColMajor> { \
enum { \
@@ -121,10 +121,10 @@ struct triangular_matrix_vector_product_trmv<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,
diag = IsUnitDiag ? 'U' : 'N'; \
\
/* call ?TRMV*/ \
- BLASPREFIX##trmv_(&uplo, &trans, &diag, &n, (const BLASTYPE*)_lhs, &lda, (BLASTYPE*)x, &incx); \
+ BLASPREFIX##trmv##BLASPOSTFIX(&uplo, &trans, &diag, &n, (const BLASTYPE*)_lhs, &lda, (BLASTYPE*)x, &incx); \
\
/* Add op(a_tr)rhs into res*/ \
- BLASPREFIX##axpy_(&n, &numext::real_ref(alpha),(const BLASTYPE*)x, &incx, (BLASTYPE*)_res, &incy); \
+ BLASPREFIX##axpy##BLASPOSTFIX(&n, (const BLASTYPE*)&numext::real_ref(alpha),(const BLASTYPE*)x, &incx, (BLASTYPE*)_res, &incy); \
/* Non-square case - doesn't fit to BLAS ?TRMV. Fall to default triangular product*/ \
if (size<(std::max)(rows,cols)) { \
if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \
@@ -142,18 +142,25 @@ struct triangular_matrix_vector_product_trmv<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,
m = convert_index<BlasIndex>(size); \
n = convert_index<BlasIndex>(cols-size); \
} \
- BLASPREFIX##gemv_(&trans, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)x, &incx, &numext::real_ref(beta), (BLASTYPE*)y, &incy); \
+ BLASPREFIX##gemv##BLASPOSTFIX(&trans, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)x, &incx, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)y, &incy); \
} \
} \
};
-EIGEN_BLAS_TRMV_CM(double, double, d, d)
-EIGEN_BLAS_TRMV_CM(dcomplex, double, cd, z)
-EIGEN_BLAS_TRMV_CM(float, float, f, s)
-EIGEN_BLAS_TRMV_CM(scomplex, float, cf, c)
+#ifdef EIGEN_USE_MKL
+EIGEN_BLAS_TRMV_CM(double, double, d, d,)
+EIGEN_BLAS_TRMV_CM(dcomplex, MKL_Complex16, cd, z,)
+EIGEN_BLAS_TRMV_CM(float, float, f, s,)
+EIGEN_BLAS_TRMV_CM(scomplex, MKL_Complex8, cf, c,)
+#else
+EIGEN_BLAS_TRMV_CM(double, double, d, d, _)
+EIGEN_BLAS_TRMV_CM(dcomplex, double, cd, z, _)
+EIGEN_BLAS_TRMV_CM(float, float, f, s, _)
+EIGEN_BLAS_TRMV_CM(scomplex, float, cf, c, _)
+#endif
// implements row-major: res += alpha * op(triangular) * vector
-#define EIGEN_BLAS_TRMV_RM(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX) \
+#define EIGEN_BLAS_TRMV_RM(EIGTYPE, BLASTYPE, EIGPREFIX, BLASPREFIX, BLASPOSTFIX) \
template<typename Index, int Mode, bool ConjLhs, bool ConjRhs> \
struct triangular_matrix_vector_product_trmv<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,ConjRhs,RowMajor> { \
enum { \
@@ -203,10 +210,10 @@ struct triangular_matrix_vector_product_trmv<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,
diag = IsUnitDiag ? 'U' : 'N'; \
\
/* call ?TRMV*/ \
- BLASPREFIX##trmv_(&uplo, &trans, &diag, &n, (const BLASTYPE*)_lhs, &lda, (BLASTYPE*)x, &incx); \
+ BLASPREFIX##trmv##BLASPOSTFIX(&uplo, &trans, &diag, &n, (const BLASTYPE*)_lhs, &lda, (BLASTYPE*)x, &incx); \
\
/* Add op(a_tr)rhs into res*/ \
- BLASPREFIX##axpy_(&n, &numext::real_ref(alpha),(const BLASTYPE*)x, &incx, (BLASTYPE*)_res, &incy); \
+ BLASPREFIX##axpy##BLASPOSTFIX(&n, (const BLASTYPE*)&numext::real_ref(alpha),(const BLASTYPE*)x, &incx, (BLASTYPE*)_res, &incy); \
/* Non-square case - doesn't fit to BLAS ?TRMV. Fall to default triangular product*/ \
if (size<(std::max)(rows,cols)) { \
if (ConjRhs) x_tmp = rhs.conjugate(); else x_tmp = rhs; \
@@ -224,15 +231,22 @@ struct triangular_matrix_vector_product_trmv<Index,Mode,EIGTYPE,ConjLhs,EIGTYPE,
m = convert_index<BlasIndex>(size); \
n = convert_index<BlasIndex>(cols-size); \
} \
- BLASPREFIX##gemv_(&trans, &n, &m, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)x, &incx, &numext::real_ref(beta), (BLASTYPE*)y, &incy); \
+ BLASPREFIX##gemv##BLASPOSTFIX(&trans, &n, &m, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (const BLASTYPE*)x, &incx, (const BLASTYPE*)&numext::real_ref(beta), (BLASTYPE*)y, &incy); \
} \
} \
};
-EIGEN_BLAS_TRMV_RM(double, double, d, d)
-EIGEN_BLAS_TRMV_RM(dcomplex, double, cd, z)
-EIGEN_BLAS_TRMV_RM(float, float, f, s)
-EIGEN_BLAS_TRMV_RM(scomplex, float, cf, c)
+#ifdef EIGEN_USE_MKL
+EIGEN_BLAS_TRMV_RM(double, double, d, d,)
+EIGEN_BLAS_TRMV_RM(dcomplex, MKL_Complex16, cd, z,)
+EIGEN_BLAS_TRMV_RM(float, float, f, s,)
+EIGEN_BLAS_TRMV_RM(scomplex, MKL_Complex8, cf, c,)
+#else
+EIGEN_BLAS_TRMV_RM(double, double, d, d,_)
+EIGEN_BLAS_TRMV_RM(dcomplex, double, cd, z,_)
+EIGEN_BLAS_TRMV_RM(float, float, f, s,_)
+EIGEN_BLAS_TRMV_RM(scomplex, float, cf, c,_)
+#endif
} // end namespase internal
diff --git a/xs/src/eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h b/xs/src/eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h
index 88c0fb794..f0775116a 100644
--- a/xs/src/eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h
+++ b/xs/src/eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h
@@ -38,7 +38,7 @@ namespace Eigen {
namespace internal {
// implements LeftSide op(triangular)^-1 * general
-#define EIGEN_BLAS_TRSM_L(EIGTYPE, BLASTYPE, BLASPREFIX) \
+#define EIGEN_BLAS_TRSM_L(EIGTYPE, BLASTYPE, BLASFUNC) \
template <typename Index, int Mode, bool Conjugate, int TriStorageOrder> \
struct triangular_solve_matrix<EIGTYPE,Index,OnTheLeft,Mode,Conjugate,TriStorageOrder,ColMajor> \
{ \
@@ -80,18 +80,24 @@ struct triangular_solve_matrix<EIGTYPE,Index,OnTheLeft,Mode,Conjugate,TriStorage
} \
if (IsUnitDiag) diag='U'; \
/* call ?trsm*/ \
- BLASPREFIX##trsm_(&side, &uplo, &transa, &diag, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (BLASTYPE*)_other, &ldb); \
+ BLASFUNC(&side, &uplo, &transa, &diag, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (BLASTYPE*)_other, &ldb); \
} \
};
-EIGEN_BLAS_TRSM_L(double, double, d)
-EIGEN_BLAS_TRSM_L(dcomplex, double, z)
-EIGEN_BLAS_TRSM_L(float, float, s)
-EIGEN_BLAS_TRSM_L(scomplex, float, c)
-
+#ifdef EIGEN_USE_MKL
+EIGEN_BLAS_TRSM_L(double, double, dtrsm)
+EIGEN_BLAS_TRSM_L(dcomplex, MKL_Complex16, ztrsm)
+EIGEN_BLAS_TRSM_L(float, float, strsm)
+EIGEN_BLAS_TRSM_L(scomplex, MKL_Complex8, ctrsm)
+#else
+EIGEN_BLAS_TRSM_L(double, double, dtrsm_)
+EIGEN_BLAS_TRSM_L(dcomplex, double, ztrsm_)
+EIGEN_BLAS_TRSM_L(float, float, strsm_)
+EIGEN_BLAS_TRSM_L(scomplex, float, ctrsm_)
+#endif
// implements RightSide general * op(triangular)^-1
-#define EIGEN_BLAS_TRSM_R(EIGTYPE, BLASTYPE, BLASPREFIX) \
+#define EIGEN_BLAS_TRSM_R(EIGTYPE, BLASTYPE, BLASFUNC) \
template <typename Index, int Mode, bool Conjugate, int TriStorageOrder> \
struct triangular_solve_matrix<EIGTYPE,Index,OnTheRight,Mode,Conjugate,TriStorageOrder,ColMajor> \
{ \
@@ -133,16 +139,22 @@ struct triangular_solve_matrix<EIGTYPE,Index,OnTheRight,Mode,Conjugate,TriStorag
} \
if (IsUnitDiag) diag='U'; \
/* call ?trsm*/ \
- BLASPREFIX##trsm_(&side, &uplo, &transa, &diag, &m, &n, &numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (BLASTYPE*)_other, &ldb); \
+ BLASFUNC(&side, &uplo, &transa, &diag, &m, &n, (const BLASTYPE*)&numext::real_ref(alpha), (const BLASTYPE*)a, &lda, (BLASTYPE*)_other, &ldb); \
/*std::cout << "TRMS_L specialization!\n";*/ \
} \
};
-EIGEN_BLAS_TRSM_R(double, double, d)
-EIGEN_BLAS_TRSM_R(dcomplex, double, z)
-EIGEN_BLAS_TRSM_R(float, float, s)
-EIGEN_BLAS_TRSM_R(scomplex, float, c)
-
+#ifdef EIGEN_USE_MKL
+EIGEN_BLAS_TRSM_R(double, double, dtrsm)
+EIGEN_BLAS_TRSM_R(dcomplex, MKL_Complex16, ztrsm)
+EIGEN_BLAS_TRSM_R(float, float, strsm)
+EIGEN_BLAS_TRSM_R(scomplex, MKL_Complex8, ctrsm)
+#else
+EIGEN_BLAS_TRSM_R(double, double, dtrsm_)
+EIGEN_BLAS_TRSM_R(dcomplex, double, ztrsm_)
+EIGEN_BLAS_TRSM_R(float, float, strsm_)
+EIGEN_BLAS_TRSM_R(scomplex, float, ctrsm_)
+#endif
} // end namespace internal
diff --git a/xs/src/eigen/Eigen/src/Core/util/MKL_support.h b/xs/src/eigen/Eigen/src/Core/util/MKL_support.h
index 26b59669e..b7d6ecc76 100644
--- a/xs/src/eigen/Eigen/src/Core/util/MKL_support.h
+++ b/xs/src/eigen/Eigen/src/Core/util/MKL_support.h
@@ -49,10 +49,11 @@
#define EIGEN_USE_LAPACKE
#endif
-#if defined(EIGEN_USE_MKL_VML)
+#if defined(EIGEN_USE_MKL_VML) && !defined(EIGEN_USE_MKL)
#define EIGEN_USE_MKL
#endif
+
#if defined EIGEN_USE_MKL
# include <mkl.h>
/*Check IMKL version for compatibility: < 10.3 is not usable with Eigen*/
@@ -108,6 +109,10 @@
#endif
#endif
+#if defined(EIGEN_USE_BLAS) && !defined(EIGEN_USE_MKL)
+#include "../../misc/blas.h"
+#endif
+
namespace Eigen {
typedef std::complex<double> dcomplex;
@@ -121,8 +126,5 @@ typedef int BlasIndex;
} // end namespace Eigen
-#if defined(EIGEN_USE_BLAS)
-#include "../../misc/blas.h"
-#endif
#endif // EIGEN_MKL_SUPPORT_H
diff --git a/xs/src/eigen/Eigen/src/Core/util/Macros.h b/xs/src/eigen/Eigen/src/Core/util/Macros.h
index 427d3cd6b..02d21d2cd 100644
--- a/xs/src/eigen/Eigen/src/Core/util/Macros.h
+++ b/xs/src/eigen/Eigen/src/Core/util/Macros.h
@@ -13,7 +13,7 @@
#define EIGEN_WORLD_VERSION 3
#define EIGEN_MAJOR_VERSION 3
-#define EIGEN_MINOR_VERSION 3
+#define EIGEN_MINOR_VERSION 5
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
@@ -399,7 +399,7 @@
// Does the compiler support variadic templates?
#ifndef EIGEN_HAS_VARIADIC_TEMPLATES
#if EIGEN_MAX_CPP_VER>=11 && (__cplusplus > 199711L || EIGEN_COMP_MSVC >= 1900) \
- && ( !defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64 || (defined __CUDACC_VER__ && __CUDACC_VER__ >= 80000) )
+ && (!defined(__NVCC__) || !EIGEN_ARCH_ARM_OR_ARM64 || (EIGEN_CUDACC_VER >= 80000) )
// ^^ Disable the use of variadic templates when compiling with versions of nvcc older than 8.0 on ARM devices:
// this prevents nvcc from crashing when compiling Eigen on Tegra X1
#define EIGEN_HAS_VARIADIC_TEMPLATES 1
@@ -413,7 +413,7 @@
#ifdef __CUDACC__
// Const expressions are supported provided that c++11 is enabled and we're using either clang or nvcc 7.5 or above
-#if EIGEN_MAX_CPP_VER>=14 && (__cplusplus > 199711L && defined(__CUDACC_VER__) && (EIGEN_COMP_CLANG || __CUDACC_VER__ >= 70500))
+#if EIGEN_MAX_CPP_VER>=14 && (__cplusplus > 199711L && (EIGEN_COMP_CLANG || EIGEN_CUDACC_VER >= 70500))
#define EIGEN_HAS_CONSTEXPR 1
#endif
#elif EIGEN_MAX_CPP_VER>=14 && (__has_feature(cxx_relaxed_constexpr) || (defined(__cplusplus) && __cplusplus >= 201402L) || \
@@ -487,11 +487,13 @@
// EIGEN_STRONG_INLINE is a stronger version of the inline, using __forceinline on MSVC,
// but it still doesn't use GCC's always_inline. This is useful in (common) situations where MSVC needs forceinline
// but GCC is still doing fine with just inline.
+#ifndef EIGEN_STRONG_INLINE
#if EIGEN_COMP_MSVC || EIGEN_COMP_ICC
#define EIGEN_STRONG_INLINE __forceinline
#else
#define EIGEN_STRONG_INLINE inline
#endif
+#endif
// EIGEN_ALWAYS_INLINE is the stronget, it has the effect of making the function inline and adding every possible
// attribute to maximize inlining. This should only be used when really necessary: in particular,
@@ -812,7 +814,8 @@ namespace Eigen {
// just an empty macro !
#define EIGEN_EMPTY
-#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || defined(__CUDACC_VER__)) // for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324)
+#if EIGEN_COMP_MSVC_STRICT && (EIGEN_COMP_MSVC < 1900 || EIGEN_CUDACC_VER>0)
+ // for older MSVC versions, as well as 1900 && CUDA 8, using the base operator is sufficient (cf Bugs 1000, 1324)
#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \
using Base::operator =;
#elif EIGEN_COMP_CLANG // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
@@ -986,7 +989,13 @@ namespace Eigen {
# define EIGEN_NOEXCEPT
# define EIGEN_NOEXCEPT_IF(x)
# define EIGEN_NO_THROW throw()
-# define EIGEN_EXCEPTION_SPEC(X) throw(X)
+# if EIGEN_COMP_MSVC
+ // MSVC does not support exception specifications (warning C4290),
+ // and they are deprecated in c++11 anyway.
+# define EIGEN_EXCEPTION_SPEC(X) throw()
+# else
+# define EIGEN_EXCEPTION_SPEC(X) throw(X)
+# endif
#endif
#endif // EIGEN_MACROS_H
diff --git a/xs/src/eigen/Eigen/src/Core/util/Memory.h b/xs/src/eigen/Eigen/src/Core/util/Memory.h
index c634d7ea0..66cdbd8dd 100644
--- a/xs/src/eigen/Eigen/src/Core/util/Memory.h
+++ b/xs/src/eigen/Eigen/src/Core/util/Memory.h
@@ -70,7 +70,7 @@ inline void throw_std_bad_alloc()
throw std::bad_alloc();
#else
std::size_t huge = static_cast<std::size_t>(-1);
- new int[huge];
+ ::operator new(huge);
#endif
}
@@ -493,7 +493,7 @@ template<typename T> struct smart_copy_helper<T,true> {
IntPtr size = IntPtr(end)-IntPtr(start);
if(size==0) return;
eigen_internal_assert(start!=0 && end!=0 && target!=0);
- memcpy(target, start, size);
+ std::memcpy(target, start, size);
}
};
@@ -696,7 +696,15 @@ template<typename T> void swap(scoped_array<T> &a,scoped_array<T> &b)
/** \class aligned_allocator
* \ingroup Core_Module
*
-* \brief STL compatible allocator to use with with 16 byte aligned types
+* \brief STL compatible allocator to use with types requiring a non standrad alignment.
+*
+* The memory is aligned as for dynamically aligned matrix/array types such as MatrixXd.
+* By default, it will thus provide at least 16 bytes alignment and more in following cases:
+* - 32 bytes alignment if AVX is enabled.
+* - 64 bytes alignment if AVX512 is enabled.
+*
+* This can be controled using the \c EIGEN_MAX_ALIGN_BYTES macro as documented
+* \link TopicPreprocessorDirectivesPerformance there \endlink.
*
* Example:
* \code
diff --git a/xs/src/eigen/Eigen/src/Core/util/Meta.h b/xs/src/eigen/Eigen/src/Core/util/Meta.h
index 7f6370755..1d73f05d6 100644
--- a/xs/src/eigen/Eigen/src/Core/util/Meta.h
+++ b/xs/src/eigen/Eigen/src/Core/util/Meta.h
@@ -485,6 +485,26 @@ T div_ceil(const T &a, const T &b)
return (a+b-1) / b;
}
+// The aim of the following functions is to bypass -Wfloat-equal warnings
+// when we really want a strict equality comparison on floating points.
+template<typename X, typename Y> EIGEN_STRONG_INLINE
+bool equal_strict(const X& x,const Y& y) { return x == y; }
+
+template<> EIGEN_STRONG_INLINE
+bool equal_strict(const float& x,const float& y) { return std::equal_to<float>()(x,y); }
+
+template<> EIGEN_STRONG_INLINE
+bool equal_strict(const double& x,const double& y) { return std::equal_to<double>()(x,y); }
+
+template<typename X, typename Y> EIGEN_STRONG_INLINE
+bool not_equal_strict(const X& x,const Y& y) { return x != y; }
+
+template<> EIGEN_STRONG_INLINE
+bool not_equal_strict(const float& x,const float& y) { return std::not_equal_to<float>()(x,y); }
+
+template<> EIGEN_STRONG_INLINE
+bool not_equal_strict(const double& x,const double& y) { return std::not_equal_to<double>()(x,y); }
+
} // end namespace numext
} // end namespace Eigen
diff --git a/xs/src/eigen/Eigen/src/Core/util/StaticAssert.h b/xs/src/eigen/Eigen/src/Core/util/StaticAssert.h
index 983361a45..500e47792 100644
--- a/xs/src/eigen/Eigen/src/Core/util/StaticAssert.h
+++ b/xs/src/eigen/Eigen/src/Core/util/StaticAssert.h
@@ -24,6 +24,7 @@
*
*/
+#ifndef EIGEN_STATIC_ASSERT
#ifndef EIGEN_NO_STATIC_ASSERT
#if EIGEN_MAX_CPP_VER>=11 && (__has_feature(cxx_static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L) || (EIGEN_COMP_MSVC >= 1600))
@@ -44,64 +45,65 @@
struct static_assertion<true>
{
enum {
- YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX,
- YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES,
- YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES,
- THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE,
- THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE,
- THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE,
- OUT_OF_RANGE_ACCESS,
- YOU_MADE_A_PROGRAMMING_MISTAKE,
- EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT,
- EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE,
- YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR,
- YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR,
- UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC,
- THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES,
- FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED,
- NUMERIC_TYPE_MUST_BE_REAL,
- COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED,
- WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED,
- THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE,
- INVALID_MATRIX_PRODUCT,
- INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS,
- INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION,
- YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY,
- THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES,
- THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES,
- INVALID_MATRIX_TEMPLATE_PARAMETERS,
- INVALID_MATRIXBASE_TEMPLATE_PARAMETERS,
- BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER,
- THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX,
- THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE,
- THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES,
- YOU_ALREADY_SPECIFIED_THIS_STRIDE,
- INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION,
- THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD,
- PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1,
- THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS,
- YOU_CANNOT_MIX_ARRAYS_AND_MATRICES,
- YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION,
- THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY,
- YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT,
- THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS,
- THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS,
- THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL,
- THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES,
- YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED,
- YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED,
- THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE,
- THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH,
- OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG,
- IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY,
- STORAGE_LAYOUT_DOES_NOT_MATCH,
- EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE,
- THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS,
- MATRIX_FREE_CONJUGATE_GRADIENT_IS_COMPATIBLE_WITH_UPPER_UNION_LOWER_MODE_ONLY,
- THIS_TYPE_IS_NOT_SUPPORTED,
- STORAGE_KIND_MUST_MATCH,
- STORAGE_INDEX_MUST_MATCH,
- CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY
+ YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX=1,
+ YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES=1,
+ YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES=1,
+ THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE=1,
+ THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE=1,
+ THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE=1,
+ OUT_OF_RANGE_ACCESS=1,
+ YOU_MADE_A_PROGRAMMING_MISTAKE=1,
+ EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT=1,
+ EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE=1,
+ YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR=1,
+ YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR=1,
+ UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC=1,
+ THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES=1,
+ FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED=1,
+ NUMERIC_TYPE_MUST_BE_REAL=1,
+ COEFFICIENT_WRITE_ACCESS_TO_SELFADJOINT_NOT_SUPPORTED=1,
+ WRITING_TO_TRIANGULAR_PART_WITH_UNIT_DIAGONAL_IS_NOT_SUPPORTED=1,
+ THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE=1,
+ INVALID_MATRIX_PRODUCT=1,
+ INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS=1,
+ INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION=1,
+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY=1,
+ THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES=1,
+ THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES=1,
+ INVALID_MATRIX_TEMPLATE_PARAMETERS=1,
+ INVALID_MATRIXBASE_TEMPLATE_PARAMETERS=1,
+ BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER=1,
+ THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX=1,
+ THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE=1,
+ THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES=1,
+ YOU_ALREADY_SPECIFIED_THIS_STRIDE=1,
+ INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION=1,
+ THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD=1,
+ PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1=1,
+ THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS=1,
+ YOU_CANNOT_MIX_ARRAYS_AND_MATRICES=1,
+ YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION=1,
+ THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY=1,
+ YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT=1,
+ THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS=1,
+ THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS=1,
+ THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL=1,
+ THIS_METHOD_IS_ONLY_FOR_ARRAYS_NOT_MATRICES=1,
+ YOU_PASSED_A_ROW_VECTOR_BUT_A_COLUMN_VECTOR_WAS_EXPECTED=1,
+ YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED=1,
+ THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE=1,
+ THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH=1,
+ OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG=1,
+ IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY=1,
+ STORAGE_LAYOUT_DOES_NOT_MATCH=1,
+ EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT__INVALID_COST_VALUE=1,
+ THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS=1,
+ MATRIX_FREE_CONJUGATE_GRADIENT_IS_COMPATIBLE_WITH_UPPER_UNION_LOWER_MODE_ONLY=1,
+ THIS_TYPE_IS_NOT_SUPPORTED=1,
+ STORAGE_KIND_MUST_MATCH=1,
+ STORAGE_INDEX_MUST_MATCH=1,
+ CHOLMOD_SUPPORTS_DOUBLE_PRECISION_ONLY=1,
+ SELFADJOINTVIEW_ACCEPTS_UPPER_AND_LOWER_MODE_ONLY=1
};
};
@@ -131,7 +133,7 @@
#define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG);
#endif // EIGEN_NO_STATIC_ASSERT
-
+#endif // EIGEN_STATIC_ASSERT
// static assertion failing if the type \a TYPE is not a vector type
#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) \
diff --git a/xs/src/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h b/xs/src/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
index 36a91dffc..87d789b3f 100644
--- a/xs/src/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
+++ b/xs/src/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h
@@ -311,7 +311,6 @@ GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixTyp
// Aliases:
Map<VectorType> v(reinterpret_cast<Scalar*>(m_tmp.data()), size);
ComplexVectorType &cv = m_tmp;
- const MatrixType &mZ = m_realQZ.matrixZ();
const MatrixType &mS = m_realQZ.matrixS();
const MatrixType &mT = m_realQZ.matrixT();
@@ -351,7 +350,7 @@ GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixTyp
}
}
}
- m_eivec.col(i).real().noalias() = mZ.transpose() * v;
+ m_eivec.col(i).real().noalias() = m_realQZ.matrixZ().transpose() * v;
m_eivec.col(i).real().normalize();
m_eivec.col(i).imag().setConstant(0);
}
@@ -400,7 +399,7 @@ GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixTyp
/ (alpha*mT.coeffRef(j,j) - static_cast<Scalar>(beta*mS.coeffRef(j,j)));
}
}
- m_eivec.col(i+1).noalias() = (mZ.transpose() * cv);
+ m_eivec.col(i+1).noalias() = (m_realQZ.matrixZ().transpose() * cv);
m_eivec.col(i+1).normalize();
m_eivec.col(i) = m_eivec.col(i+1).conjugate();
}
diff --git a/xs/src/eigen/Eigen/src/Eigenvalues/RealSchur.h b/xs/src/eigen/Eigen/src/Eigenvalues/RealSchur.h
index f5c86041d..17ea903f5 100644
--- a/xs/src/eigen/Eigen/src/Eigenvalues/RealSchur.h
+++ b/xs/src/eigen/Eigen/src/Eigenvalues/RealSchur.h
@@ -303,7 +303,7 @@ RealSchur<MatrixType>& RealSchur<MatrixType>::computeFromHessenberg(const HessMa
Scalar exshift(0); // sum of exceptional shifts
Scalar norm = computeNormOfT();
- if(norm!=0)
+ if(norm!=Scalar(0))
{
while (iu >= 0)
{
@@ -327,7 +327,7 @@ RealSchur<MatrixType>& RealSchur<MatrixType>::computeFromHessenberg(const HessMa
else // No convergence yet
{
// The firstHouseholderVector vector has to be initialized to something to get rid of a silly GCC warning (-O1 -Wall -DNDEBUG )
- Vector3s firstHouseholderVector(0,0,0), shiftInfo;
+ Vector3s firstHouseholderVector = Vector3s::Zero(), shiftInfo;
computeShift(iu, iter, exshift, shiftInfo);
iter = iter + 1;
totalIter = totalIter + 1;
diff --git a/xs/src/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h b/xs/src/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h
index 3891cf883..b0c947dc0 100644
--- a/xs/src/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h
+++ b/xs/src/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h
@@ -37,7 +37,7 @@ namespace Eigen {
/** \internal Specialization for the data types supported by LAPACKe */
-#define EIGEN_LAPACKE_EIG_SELFADJ(EIGTYPE, LAPACKE_TYPE, LAPACKE_RTYPE, LAPACKE_NAME, EIGCOLROW, LAPACKE_COLROW ) \
+#define EIGEN_LAPACKE_EIG_SELFADJ_2(EIGTYPE, LAPACKE_TYPE, LAPACKE_RTYPE, LAPACKE_NAME, EIGCOLROW ) \
template<> template<typename InputType> inline \
SelfAdjointEigenSolver<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >& \
SelfAdjointEigenSolver<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(const EigenBase<InputType>& matrix, int options) \
@@ -47,7 +47,7 @@ SelfAdjointEigenSolver<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(c
&& (options&EigVecMask)!=EigVecMask \
&& "invalid option parameter"); \
bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors; \
- lapack_int n = internal::convert_index<lapack_int>(matrix.cols()), lda, matrix_order, info; \
+ lapack_int n = internal::convert_index<lapack_int>(matrix.cols()), lda, info; \
m_eivalues.resize(n,1); \
m_subdiag.resize(n-1); \
m_eivec = matrix; \
@@ -63,27 +63,24 @@ SelfAdjointEigenSolver<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW> >::compute(c
} \
\
lda = internal::convert_index<lapack_int>(m_eivec.outerStride()); \
- matrix_order=LAPACKE_COLROW; \
char jobz, uplo='L'/*, range='A'*/; \
jobz = computeEigenvectors ? 'V' : 'N'; \
\
- info = LAPACKE_##LAPACKE_NAME( matrix_order, jobz, uplo, n, (LAPACKE_TYPE*)m_eivec.data(), lda, (LAPACKE_RTYPE*)m_eivalues.data() ); \
+ info = LAPACKE_##LAPACKE_NAME( LAPACK_COL_MAJOR, jobz, uplo, n, (LAPACKE_TYPE*)m_eivec.data(), lda, (LAPACKE_RTYPE*)m_eivalues.data() ); \
m_info = (info==0) ? Success : NoConvergence; \
m_isInitialized = true; \
m_eigenvectorsOk = computeEigenvectors; \
return *this; \
}
+#define EIGEN_LAPACKE_EIG_SELFADJ(EIGTYPE, LAPACKE_TYPE, LAPACKE_RTYPE, LAPACKE_NAME ) \
+ EIGEN_LAPACKE_EIG_SELFADJ_2(EIGTYPE, LAPACKE_TYPE, LAPACKE_RTYPE, LAPACKE_NAME, ColMajor ) \
+ EIGEN_LAPACKE_EIG_SELFADJ_2(EIGTYPE, LAPACKE_TYPE, LAPACKE_RTYPE, LAPACKE_NAME, RowMajor )
-EIGEN_LAPACKE_EIG_SELFADJ(double, double, double, dsyev, ColMajor, LAPACK_COL_MAJOR)
-EIGEN_LAPACKE_EIG_SELFADJ(float, float, float, ssyev, ColMajor, LAPACK_COL_MAJOR)
-EIGEN_LAPACKE_EIG_SELFADJ(dcomplex, lapack_complex_double, double, zheev, ColMajor, LAPACK_COL_MAJOR)
-EIGEN_LAPACKE_EIG_SELFADJ(scomplex, lapack_complex_float, float, cheev, ColMajor, LAPACK_COL_MAJOR)
-
-EIGEN_LAPACKE_EIG_SELFADJ(double, double, double, dsyev, RowMajor, LAPACK_ROW_MAJOR)
-EIGEN_LAPACKE_EIG_SELFADJ(float, float, float, ssyev, RowMajor, LAPACK_ROW_MAJOR)
-EIGEN_LAPACKE_EIG_SELFADJ(dcomplex, lapack_complex_double, double, zheev, RowMajor, LAPACK_ROW_MAJOR)
-EIGEN_LAPACKE_EIG_SELFADJ(scomplex, lapack_complex_float, float, cheev, RowMajor, LAPACK_ROW_MAJOR)
+EIGEN_LAPACKE_EIG_SELFADJ(double, double, double, dsyev)
+EIGEN_LAPACKE_EIG_SELFADJ(float, float, float, ssyev)
+EIGEN_LAPACKE_EIG_SELFADJ(dcomplex, lapack_complex_double, double, zheev)
+EIGEN_LAPACKE_EIG_SELFADJ(scomplex, lapack_complex_float, float, cheev)
} // end namespace Eigen
diff --git a/xs/src/eigen/Eigen/src/Geometry/AngleAxis.h b/xs/src/eigen/Eigen/src/Geometry/AngleAxis.h
index 0af3c1b08..83ee1be46 100644
--- a/xs/src/eigen/Eigen/src/Geometry/AngleAxis.h
+++ b/xs/src/eigen/Eigen/src/Geometry/AngleAxis.h
@@ -178,7 +178,7 @@ EIGEN_DEVICE_FUNC AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const Quaterni
if (n != Scalar(0))
{
m_angle = Scalar(2)*atan2(n, abs(q.w()));
- if(q.w() < 0)
+ if(q.w() < Scalar(0))
n = -n;
m_axis = q.vec() / n;
}
diff --git a/xs/src/eigen/Eigen/src/Geometry/Quaternion.h b/xs/src/eigen/Eigen/src/Geometry/Quaternion.h
index f6ef1bcf6..c3fd8c3e0 100644
--- a/xs/src/eigen/Eigen/src/Geometry/Quaternion.h
+++ b/xs/src/eigen/Eigen/src/Geometry/Quaternion.h
@@ -43,6 +43,11 @@ class QuaternionBase : public RotationBase<Derived, 3>
typedef typename internal::traits<Derived>::Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef typename internal::traits<Derived>::Coefficients Coefficients;
+ typedef typename Coefficients::CoeffReturnType CoeffReturnType;
+ typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit),
+ Scalar&, CoeffReturnType>::type NonConstCoeffReturnType;
+
+
enum {
Flags = Eigen::internal::traits<Derived>::Flags
};
@@ -58,22 +63,22 @@ class QuaternionBase : public RotationBase<Derived, 3>
/** \returns the \c x coefficient */
- EIGEN_DEVICE_FUNC inline Scalar x() const { return this->derived().coeffs().coeff(0); }
+ EIGEN_DEVICE_FUNC inline CoeffReturnType x() const { return this->derived().coeffs().coeff(0); }
/** \returns the \c y coefficient */
- EIGEN_DEVICE_FUNC inline Scalar y() const { return this->derived().coeffs().coeff(1); }
+ EIGEN_DEVICE_FUNC inline CoeffReturnType y() const { return this->derived().coeffs().coeff(1); }
/** \returns the \c z coefficient */
- EIGEN_DEVICE_FUNC inline Scalar z() const { return this->derived().coeffs().coeff(2); }
+ EIGEN_DEVICE_FUNC inline CoeffReturnType z() const { return this->derived().coeffs().coeff(2); }
/** \returns the \c w coefficient */
- EIGEN_DEVICE_FUNC inline Scalar w() const { return this->derived().coeffs().coeff(3); }
+ EIGEN_DEVICE_FUNC inline CoeffReturnType w() const { return this->derived().coeffs().coeff(3); }
- /** \returns a reference to the \c x coefficient */
- EIGEN_DEVICE_FUNC inline Scalar& x() { return this->derived().coeffs().coeffRef(0); }
- /** \returns a reference to the \c y coefficient */
- EIGEN_DEVICE_FUNC inline Scalar& y() { return this->derived().coeffs().coeffRef(1); }
- /** \returns a reference to the \c z coefficient */
- EIGEN_DEVICE_FUNC inline Scalar& z() { return this->derived().coeffs().coeffRef(2); }
- /** \returns a reference to the \c w coefficient */
- EIGEN_DEVICE_FUNC inline Scalar& w() { return this->derived().coeffs().coeffRef(3); }
+ /** \returns a reference to the \c x coefficient (if Derived is a non-const lvalue) */
+ EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType x() { return this->derived().coeffs().x(); }
+ /** \returns a reference to the \c y coefficient (if Derived is a non-const lvalue) */
+ EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType y() { return this->derived().coeffs().y(); }
+ /** \returns a reference to the \c z coefficient (if Derived is a non-const lvalue) */
+ EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType z() { return this->derived().coeffs().z(); }
+ /** \returns a reference to the \c w coefficient (if Derived is a non-const lvalue) */
+ EIGEN_DEVICE_FUNC inline NonConstCoeffReturnType w() { return this->derived().coeffs().w(); }
/** \returns a read-only vector expression of the imaginary part (x,y,z) */
EIGEN_DEVICE_FUNC inline const VectorBlock<const Coefficients,3> vec() const { return coeffs().template head<3>(); }
@@ -423,7 +428,7 @@ typedef Map<Quaternion<double>, Aligned> QuaternionMapAlignedd;
// Generic Quaternion * Quaternion product
// This product can be specialized for a given architecture via the Arch template argument.
namespace internal {
-template<int Arch, class Derived1, class Derived2, typename Scalar, int _Options> struct quat_product
+template<int Arch, class Derived1, class Derived2, typename Scalar> struct quat_product
{
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){
return Quaternion<Scalar>
@@ -446,8 +451,7 @@ QuaternionBase<Derived>::operator* (const QuaternionBase<OtherDerived>& other) c
EIGEN_STATIC_ASSERT((internal::is_same<typename Derived::Scalar, typename OtherDerived::Scalar>::value),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
return internal::quat_product<Architecture::Target, Derived, OtherDerived,
- typename internal::traits<Derived>::Scalar,
- EIGEN_PLAIN_ENUM_MIN(internal::traits<Derived>::Alignment, internal::traits<OtherDerived>::Alignment)>::run(*this, other);
+ typename internal::traits<Derived>::Scalar>::run(*this, other);
}
/** \sa operator*(Quaternion) */
@@ -672,7 +676,7 @@ EIGEN_DEVICE_FUNC inline Quaternion<typename internal::traits<Derived>::Scalar>
// Generic conjugate of a Quaternion
namespace internal {
-template<int Arch, class Derived, typename Scalar, int _Options> struct quat_conj
+template<int Arch, class Derived, typename Scalar> struct quat_conj
{
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Quaternion<Scalar> run(const QuaternionBase<Derived>& q){
return Quaternion<Scalar>(q.w(),-q.x(),-q.y(),-q.z());
@@ -691,8 +695,7 @@ EIGEN_DEVICE_FUNC inline Quaternion<typename internal::traits<Derived>::Scalar>
QuaternionBase<Derived>::conjugate() const
{
return internal::quat_conj<Architecture::Target, Derived,
- typename internal::traits<Derived>::Scalar,
- internal::traits<Derived>::Alignment>::run(*this);
+ typename internal::traits<Derived>::Scalar>::run(*this);
}
diff --git a/xs/src/eigen/Eigen/src/Geometry/arch/Geometry_SSE.h b/xs/src/eigen/Eigen/src/Geometry/arch/Geometry_SSE.h
index 1a86ff837..f68cab583 100644
--- a/xs/src/eigen/Eigen/src/Geometry/arch/Geometry_SSE.h
+++ b/xs/src/eigen/Eigen/src/Geometry/arch/Geometry_SSE.h
@@ -16,17 +16,23 @@ namespace Eigen {
namespace internal {
template<class Derived, class OtherDerived>
-struct quat_product<Architecture::SSE, Derived, OtherDerived, float, Aligned16>
+struct quat_product<Architecture::SSE, Derived, OtherDerived, float>
{
+ enum {
+ AAlignment = traits<Derived>::Alignment,
+ BAlignment = traits<OtherDerived>::Alignment,
+ ResAlignment = traits<Quaternion<float> >::Alignment
+ };
static inline Quaternion<float> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b)
{
Quaternion<float> res;
const __m128 mask = _mm_setr_ps(0.f,0.f,0.f,-0.f);
- __m128 a = _a.coeffs().template packet<Aligned16>(0);
- __m128 b = _b.coeffs().template packet<Aligned16>(0);
+ __m128 a = _a.coeffs().template packet<AAlignment>(0);
+ __m128 b = _b.coeffs().template packet<BAlignment>(0);
__m128 s1 = _mm_mul_ps(vec4f_swizzle1(a,1,2,0,2),vec4f_swizzle1(b,2,0,1,2));
__m128 s2 = _mm_mul_ps(vec4f_swizzle1(a,3,3,3,1),vec4f_swizzle1(b,0,1,2,1));
- pstore(&res.x(),
+ pstoret<float,Packet4f,ResAlignment>(
+ &res.x(),
_mm_add_ps(_mm_sub_ps(_mm_mul_ps(a,vec4f_swizzle1(b,3,3,3,3)),
_mm_mul_ps(vec4f_swizzle1(a,2,0,1,0),
vec4f_swizzle1(b,1,2,0,0))),
@@ -36,14 +42,17 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, float, Aligned16>
}
};
-template<class Derived, int Alignment>
-struct quat_conj<Architecture::SSE, Derived, float, Alignment>
+template<class Derived>
+struct quat_conj<Architecture::SSE, Derived, float>
{
+ enum {
+ ResAlignment = traits<Quaternion<float> >::Alignment
+ };
static inline Quaternion<float> run(const QuaternionBase<Derived>& q)
{
Quaternion<float> res;
const __m128 mask = _mm_setr_ps(-0.f,-0.f,-0.f,0.f);
- pstore(&res.x(), _mm_xor_ps(mask, q.coeffs().template packet<Alignment>(0)));
+ pstoret<float,Packet4f,ResAlignment>(&res.x(), _mm_xor_ps(mask, q.coeffs().template packet<traits<Derived>::Alignment>(0)));
return res;
}
};
@@ -52,6 +61,9 @@ struct quat_conj<Architecture::SSE, Derived, float, Alignment>
template<typename VectorLhs,typename VectorRhs>
struct cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
{
+ enum {
+ ResAlignment = traits<typename plain_matrix_type<VectorLhs>::type>::Alignment
+ };
static inline typename plain_matrix_type<VectorLhs>::type
run(const VectorLhs& lhs, const VectorRhs& rhs)
{
@@ -60,7 +72,7 @@ struct cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
__m128 mul1=_mm_mul_ps(vec4f_swizzle1(a,1,2,0,3),vec4f_swizzle1(b,2,0,1,3));
__m128 mul2=_mm_mul_ps(vec4f_swizzle1(a,2,0,1,3),vec4f_swizzle1(b,1,2,0,3));
typename plain_matrix_type<VectorLhs>::type res;
- pstore(&res.x(),_mm_sub_ps(mul1,mul2));
+ pstoret<float,Packet4f,ResAlignment>(&res.x(),_mm_sub_ps(mul1,mul2));
return res;
}
};
@@ -68,9 +80,14 @@ struct cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
-template<class Derived, class OtherDerived, int Alignment>
-struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
+template<class Derived, class OtherDerived>
+struct quat_product<Architecture::SSE, Derived, OtherDerived, double>
{
+ enum {
+ BAlignment = traits<OtherDerived>::Alignment,
+ ResAlignment = traits<Quaternion<double> >::Alignment
+ };
+
static inline Quaternion<double> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b)
{
const Packet2d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0));
@@ -78,8 +95,8 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
Quaternion<double> res;
const double* a = _a.coeffs().data();
- Packet2d b_xy = _b.coeffs().template packet<Alignment>(0);
- Packet2d b_zw = _b.coeffs().template packet<Alignment>(2);
+ Packet2d b_xy = _b.coeffs().template packet<BAlignment>(0);
+ Packet2d b_zw = _b.coeffs().template packet<BAlignment>(2);
Packet2d a_xx = pset1<Packet2d>(a[0]);
Packet2d a_yy = pset1<Packet2d>(a[1]);
Packet2d a_zz = pset1<Packet2d>(a[2]);
@@ -97,9 +114,9 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
t2 = psub(pmul(a_zz, b_xy), pmul(a_xx, b_zw));
#ifdef EIGEN_VECTORIZE_SSE3
EIGEN_UNUSED_VARIABLE(mask)
- pstore(&res.x(), _mm_addsub_pd(t1, preverse(t2)));
+ pstoret<double,Packet2d,ResAlignment>(&res.x(), _mm_addsub_pd(t1, preverse(t2)));
#else
- pstore(&res.x(), padd(t1, pxor(mask,preverse(t2))));
+ pstoret<double,Packet2d,ResAlignment>(&res.x(), padd(t1, pxor(mask,preverse(t2))));
#endif
/*
@@ -111,25 +128,28 @@ struct quat_product<Architecture::SSE, Derived, OtherDerived, double, Alignment>
t2 = padd(pmul(a_zz, b_zw), pmul(a_xx, b_xy));
#ifdef EIGEN_VECTORIZE_SSE3
EIGEN_UNUSED_VARIABLE(mask)
- pstore(&res.z(), preverse(_mm_addsub_pd(preverse(t1), t2)));
+ pstoret<double,Packet2d,ResAlignment>(&res.z(), preverse(_mm_addsub_pd(preverse(t1), t2)));
#else
- pstore(&res.z(), psub(t1, pxor(mask,preverse(t2))));
+ pstoret<double,Packet2d,ResAlignment>(&res.z(), psub(t1, pxor(mask,preverse(t2))));
#endif
return res;
}
};
-template<class Derived, int Alignment>
-struct quat_conj<Architecture::SSE, Derived, double, Alignment>
+template<class Derived>
+struct quat_conj<Architecture::SSE, Derived, double>
{
+ enum {
+ ResAlignment = traits<Quaternion<double> >::Alignment
+ };
static inline Quaternion<double> run(const QuaternionBase<Derived>& q)
{
Quaternion<double> res;
const __m128d mask0 = _mm_setr_pd(-0.,-0.);
const __m128d mask2 = _mm_setr_pd(-0.,0.);
- pstore(&res.x(), _mm_xor_pd(mask0, q.coeffs().template packet<Alignment>(0)));
- pstore(&res.z(), _mm_xor_pd(mask2, q.coeffs().template packet<Alignment>(2)));
+ pstoret<double,Packet2d,ResAlignment>(&res.x(), _mm_xor_pd(mask0, q.coeffs().template packet<traits<Derived>::Alignment>(0)));
+ pstoret<double,Packet2d,ResAlignment>(&res.z(), _mm_xor_pd(mask2, q.coeffs().template packet<traits<Derived>::Alignment>(2)));
return res;
}
};
diff --git a/xs/src/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h b/xs/src/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
index 358444aff..f66c846ef 100644
--- a/xs/src/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
+++ b/xs/src/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
@@ -152,13 +152,28 @@ class LeastSquareDiagonalPreconditioner : public DiagonalPreconditioner<_Scalar>
{
// Compute the inverse squared-norm of each column of mat
m_invdiag.resize(mat.cols());
- for(Index j=0; j<mat.outerSize(); ++j)
+ if(MatType::IsRowMajor)
{
- RealScalar sum = mat.innerVector(j).squaredNorm();
- if(sum>0)
- m_invdiag(j) = RealScalar(1)/sum;
- else
- m_invdiag(j) = RealScalar(1);
+ m_invdiag.setZero();
+ for(Index j=0; j<mat.outerSize(); ++j)
+ {
+ for(typename MatType::InnerIterator it(mat,j); it; ++it)
+ m_invdiag(it.index()) += numext::abs2(it.value());
+ }
+ for(Index j=0; j<mat.cols(); ++j)
+ if(numext::real(m_invdiag(j))>RealScalar(0))
+ m_invdiag(j) = RealScalar(1)/numext::real(m_invdiag(j));
+ }
+ else
+ {
+ for(Index j=0; j<mat.outerSize(); ++j)
+ {
+ RealScalar sum = mat.col(j).squaredNorm();
+ if(sum>RealScalar(0))
+ m_invdiag(j) = RealScalar(1)/sum;
+ else
+ m_invdiag(j) = RealScalar(1);
+ }
}
Base::m_isInitialized = true;
return *this;
diff --git a/xs/src/eigen/Eigen/src/Jacobi/Jacobi.h b/xs/src/eigen/Eigen/src/Jacobi/Jacobi.h
index d25af8e90..437e666a3 100644
--- a/xs/src/eigen/Eigen/src/Jacobi/Jacobi.h
+++ b/xs/src/eigen/Eigen/src/Jacobi/Jacobi.h
@@ -298,132 +298,162 @@ inline void MatrixBase<Derived>::applyOnTheRight(Index p, Index q, const JacobiR
}
namespace internal {
-template<typename VectorX, typename VectorY, typename OtherScalar>
-void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x, DenseBase<VectorY>& xpr_y, const JacobiRotation<OtherScalar>& j)
-{
- typedef typename VectorX::Scalar Scalar;
- enum { PacketSize = packet_traits<Scalar>::size };
- typedef typename packet_traits<Scalar>::type Packet;
- eigen_assert(xpr_x.size() == xpr_y.size());
- Index size = xpr_x.size();
- Index incrx = xpr_x.derived().innerStride();
- Index incry = xpr_y.derived().innerStride();
- Scalar* EIGEN_RESTRICT x = &xpr_x.derived().coeffRef(0);
- Scalar* EIGEN_RESTRICT y = &xpr_y.derived().coeffRef(0);
-
- OtherScalar c = j.c();
- OtherScalar s = j.s();
- if (c==OtherScalar(1) && s==OtherScalar(0))
- return;
-
- /*** dynamic-size vectorized paths ***/
+template<typename Scalar, typename OtherScalar,
+ int SizeAtCompileTime, int MinAlignment, bool Vectorizable>
+struct apply_rotation_in_the_plane_selector
+{
+ static inline void run(Scalar *x, Index incrx, Scalar *y, Index incry, Index size, OtherScalar c, OtherScalar s)
+ {
+ for(Index i=0; i<size; ++i)
+ {
+ Scalar xi = *x;
+ Scalar yi = *y;
+ *x = c * xi + numext::conj(s) * yi;
+ *y = -s * xi + numext::conj(c) * yi;
+ x += incrx;
+ y += incry;
+ }
+ }
+};
- if(VectorX::SizeAtCompileTime == Dynamic &&
- (VectorX::Flags & VectorY::Flags & PacketAccessBit) &&
- ((incrx==1 && incry==1) || PacketSize == 1))
+template<typename Scalar, typename OtherScalar,
+ int SizeAtCompileTime, int MinAlignment>
+struct apply_rotation_in_the_plane_selector<Scalar,OtherScalar,SizeAtCompileTime,MinAlignment,true /* vectorizable */>
+{
+ static inline void run(Scalar *x, Index incrx, Scalar *y, Index incry, Index size, OtherScalar c, OtherScalar s)
{
- // both vectors are sequentially stored in memory => vectorization
- enum { Peeling = 2 };
+ enum {
+ PacketSize = packet_traits<Scalar>::size,
+ OtherPacketSize = packet_traits<OtherScalar>::size
+ };
+ typedef typename packet_traits<Scalar>::type Packet;
+ typedef typename packet_traits<OtherScalar>::type OtherPacket;
+
+ /*** dynamic-size vectorized paths ***/
+ if(SizeAtCompileTime == Dynamic && ((incrx==1 && incry==1) || PacketSize == 1))
+ {
+ // both vectors are sequentially stored in memory => vectorization
+ enum { Peeling = 2 };
- Index alignedStart = internal::first_default_aligned(y, size);
- Index alignedEnd = alignedStart + ((size-alignedStart)/PacketSize)*PacketSize;
+ Index alignedStart = internal::first_default_aligned(y, size);
+ Index alignedEnd = alignedStart + ((size-alignedStart)/PacketSize)*PacketSize;
- const Packet pc = pset1<Packet>(c);
- const Packet ps = pset1<Packet>(s);
- conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex,false> pcj;
+ const OtherPacket pc = pset1<OtherPacket>(c);
+ const OtherPacket ps = pset1<OtherPacket>(s);
+ conj_helper<OtherPacket,Packet,NumTraits<OtherScalar>::IsComplex,false> pcj;
+ conj_helper<OtherPacket,Packet,false,false> pm;
- for(Index i=0; i<alignedStart; ++i)
- {
- Scalar xi = x[i];
- Scalar yi = y[i];
- x[i] = c * xi + numext::conj(s) * yi;
- y[i] = -s * xi + numext::conj(c) * yi;
- }
+ for(Index i=0; i<alignedStart; ++i)
+ {
+ Scalar xi = x[i];
+ Scalar yi = y[i];
+ x[i] = c * xi + numext::conj(s) * yi;
+ y[i] = -s * xi + numext::conj(c) * yi;
+ }
- Scalar* EIGEN_RESTRICT px = x + alignedStart;
- Scalar* EIGEN_RESTRICT py = y + alignedStart;
+ Scalar* EIGEN_RESTRICT px = x + alignedStart;
+ Scalar* EIGEN_RESTRICT py = y + alignedStart;
- if(internal::first_default_aligned(x, size)==alignedStart)
- {
- for(Index i=alignedStart; i<alignedEnd; i+=PacketSize)
+ if(internal::first_default_aligned(x, size)==alignedStart)
{
- Packet xi = pload<Packet>(px);
- Packet yi = pload<Packet>(py);
- pstore(px, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
- pstore(py, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
- px += PacketSize;
- py += PacketSize;
+ for(Index i=alignedStart; i<alignedEnd; i+=PacketSize)
+ {
+ Packet xi = pload<Packet>(px);
+ Packet yi = pload<Packet>(py);
+ pstore(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
+ pstore(py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
+ px += PacketSize;
+ py += PacketSize;
+ }
}
- }
- else
- {
- Index peelingEnd = alignedStart + ((size-alignedStart)/(Peeling*PacketSize))*(Peeling*PacketSize);
- for(Index i=alignedStart; i<peelingEnd; i+=Peeling*PacketSize)
+ else
{
- Packet xi = ploadu<Packet>(px);
- Packet xi1 = ploadu<Packet>(px+PacketSize);
- Packet yi = pload <Packet>(py);
- Packet yi1 = pload <Packet>(py+PacketSize);
- pstoreu(px, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
- pstoreu(px+PacketSize, padd(pmul(pc,xi1),pcj.pmul(ps,yi1)));
- pstore (py, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
- pstore (py+PacketSize, psub(pcj.pmul(pc,yi1),pmul(ps,xi1)));
- px += Peeling*PacketSize;
- py += Peeling*PacketSize;
+ Index peelingEnd = alignedStart + ((size-alignedStart)/(Peeling*PacketSize))*(Peeling*PacketSize);
+ for(Index i=alignedStart; i<peelingEnd; i+=Peeling*PacketSize)
+ {
+ Packet xi = ploadu<Packet>(px);
+ Packet xi1 = ploadu<Packet>(px+PacketSize);
+ Packet yi = pload <Packet>(py);
+ Packet yi1 = pload <Packet>(py+PacketSize);
+ pstoreu(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
+ pstoreu(px+PacketSize, padd(pm.pmul(pc,xi1),pcj.pmul(ps,yi1)));
+ pstore (py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
+ pstore (py+PacketSize, psub(pcj.pmul(pc,yi1),pm.pmul(ps,xi1)));
+ px += Peeling*PacketSize;
+ py += Peeling*PacketSize;
+ }
+ if(alignedEnd!=peelingEnd)
+ {
+ Packet xi = ploadu<Packet>(x+peelingEnd);
+ Packet yi = pload <Packet>(y+peelingEnd);
+ pstoreu(x+peelingEnd, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
+ pstore (y+peelingEnd, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
+ }
}
- if(alignedEnd!=peelingEnd)
+
+ for(Index i=alignedEnd; i<size; ++i)
{
- Packet xi = ploadu<Packet>(x+peelingEnd);
- Packet yi = pload <Packet>(y+peelingEnd);
- pstoreu(x+peelingEnd, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
- pstore (y+peelingEnd, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
+ Scalar xi = x[i];
+ Scalar yi = y[i];
+ x[i] = c * xi + numext::conj(s) * yi;
+ y[i] = -s * xi + numext::conj(c) * yi;
}
}
- for(Index i=alignedEnd; i<size; ++i)
+ /*** fixed-size vectorized path ***/
+ else if(SizeAtCompileTime != Dynamic && MinAlignment>0) // FIXME should be compared to the required alignment
{
- Scalar xi = x[i];
- Scalar yi = y[i];
- x[i] = c * xi + numext::conj(s) * yi;
- y[i] = -s * xi + numext::conj(c) * yi;
+ const OtherPacket pc = pset1<OtherPacket>(c);
+ const OtherPacket ps = pset1<OtherPacket>(s);
+ conj_helper<OtherPacket,Packet,NumTraits<OtherPacket>::IsComplex,false> pcj;
+ conj_helper<OtherPacket,Packet,false,false> pm;
+ Scalar* EIGEN_RESTRICT px = x;
+ Scalar* EIGEN_RESTRICT py = y;
+ for(Index i=0; i<size; i+=PacketSize)
+ {
+ Packet xi = pload<Packet>(px);
+ Packet yi = pload<Packet>(py);
+ pstore(px, padd(pm.pmul(pc,xi),pcj.pmul(ps,yi)));
+ pstore(py, psub(pcj.pmul(pc,yi),pm.pmul(ps,xi)));
+ px += PacketSize;
+ py += PacketSize;
+ }
}
- }
- /*** fixed-size vectorized path ***/
- else if(VectorX::SizeAtCompileTime != Dynamic &&
- (VectorX::Flags & VectorY::Flags & PacketAccessBit) &&
- (EIGEN_PLAIN_ENUM_MIN(evaluator<VectorX>::Alignment, evaluator<VectorY>::Alignment)>0)) // FIXME should be compared to the required alignment
- {
- const Packet pc = pset1<Packet>(c);
- const Packet ps = pset1<Packet>(s);
- conj_helper<Packet,Packet,NumTraits<Scalar>::IsComplex,false> pcj;
- Scalar* EIGEN_RESTRICT px = x;
- Scalar* EIGEN_RESTRICT py = y;
- for(Index i=0; i<size; i+=PacketSize)
+ /*** non-vectorized path ***/
+ else
{
- Packet xi = pload<Packet>(px);
- Packet yi = pload<Packet>(py);
- pstore(px, padd(pmul(pc,xi),pcj.pmul(ps,yi)));
- pstore(py, psub(pcj.pmul(pc,yi),pmul(ps,xi)));
- px += PacketSize;
- py += PacketSize;
+ apply_rotation_in_the_plane_selector<Scalar,OtherScalar,SizeAtCompileTime,MinAlignment,false>::run(x,incrx,y,incry,size,c,s);
}
}
+};
- /*** non-vectorized path ***/
- else
- {
- for(Index i=0; i<size; ++i)
- {
- Scalar xi = *x;
- Scalar yi = *y;
- *x = c * xi + numext::conj(s) * yi;
- *y = -s * xi + numext::conj(c) * yi;
- x += incrx;
- y += incry;
- }
- }
+template<typename VectorX, typename VectorY, typename OtherScalar>
+void /*EIGEN_DONT_INLINE*/ apply_rotation_in_the_plane(DenseBase<VectorX>& xpr_x, DenseBase<VectorY>& xpr_y, const JacobiRotation<OtherScalar>& j)
+{
+ typedef typename VectorX::Scalar Scalar;
+ const bool Vectorizable = (VectorX::Flags & VectorY::Flags & PacketAccessBit)
+ && (int(packet_traits<Scalar>::size) == int(packet_traits<OtherScalar>::size));
+
+ eigen_assert(xpr_x.size() == xpr_y.size());
+ Index size = xpr_x.size();
+ Index incrx = xpr_x.derived().innerStride();
+ Index incry = xpr_y.derived().innerStride();
+
+ Scalar* EIGEN_RESTRICT x = &xpr_x.derived().coeffRef(0);
+ Scalar* EIGEN_RESTRICT y = &xpr_y.derived().coeffRef(0);
+
+ OtherScalar c = j.c();
+ OtherScalar s = j.s();
+ if (c==OtherScalar(1) && s==OtherScalar(0))
+ return;
+
+ apply_rotation_in_the_plane_selector<
+ Scalar,OtherScalar,
+ VectorX::SizeAtCompileTime,
+ EIGEN_PLAIN_ENUM_MIN(evaluator<VectorX>::Alignment, evaluator<VectorY>::Alignment),
+ Vectorizable>::run(x,incrx,y,incry,size,c,s);
}
} // end namespace internal
diff --git a/xs/src/eigen/Eigen/src/LU/InverseImpl.h b/xs/src/eigen/Eigen/src/LU/InverseImpl.h
index 018f99b58..f49f23360 100644
--- a/xs/src/eigen/Eigen/src/LU/InverseImpl.h
+++ b/xs/src/eigen/Eigen/src/LU/InverseImpl.h
@@ -404,7 +404,7 @@ inline void MatrixBase<Derived>::computeInverseWithCheck(
const RealScalar& absDeterminantThreshold
) const
{
- RealScalar determinant;
+ Scalar determinant;
// i'd love to put some static assertions there, but SFINAE means that they have no effect...
eigen_assert(rows() == cols());
computeInverseAndDetWithCheck(inverse,determinant,invertible,absDeterminantThreshold);
diff --git a/xs/src/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h b/xs/src/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h
index 933cd564b..da85b4d6e 100644
--- a/xs/src/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h
+++ b/xs/src/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h
@@ -1004,7 +1004,7 @@ static IndexType find_ordering /* return the number of garbage collections */
COLAMD_ASSERT (head [min_score] >= COLAMD_EMPTY) ;
/* get pivot column from head of minimum degree list */
- while (head [min_score] == COLAMD_EMPTY && min_score < n_col)
+ while (min_score < n_col && head [min_score] == COLAMD_EMPTY)
{
min_score++ ;
}
diff --git a/xs/src/eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h b/xs/src/eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h
index d2ebfd7bb..160d8a523 100644
--- a/xs/src/eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h
+++ b/xs/src/eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h
@@ -64,28 +64,28 @@ namespace internal
typedef typename _MatrixType::StorageIndex StorageIndex;
};
- void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, float *vals, int *perm, int * invp, float *x, int nbrhs, int *iparm, double *dparm)
+ inline void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, float *vals, int *perm, int * invp, float *x, int nbrhs, int *iparm, double *dparm)
{
if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; }
if (nbrhs == 0) {x = NULL; nbrhs=1;}
s_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm);
}
- void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, double *vals, int *perm, int * invp, double *x, int nbrhs, int *iparm, double *dparm)
+ inline void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, double *vals, int *perm, int * invp, double *x, int nbrhs, int *iparm, double *dparm)
{
if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; }
if (nbrhs == 0) {x = NULL; nbrhs=1;}
d_pastix(pastix_data, pastix_comm, n, ptr, idx, vals, perm, invp, x, nbrhs, iparm, dparm);
}
- void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex<float> *vals, int *perm, int * invp, std::complex<float> *x, int nbrhs, int *iparm, double *dparm)
+ inline void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex<float> *vals, int *perm, int * invp, std::complex<float> *x, int nbrhs, int *iparm, double *dparm)
{
if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; }
if (nbrhs == 0) {x = NULL; nbrhs=1;}
c_pastix(pastix_data, pastix_comm, n, ptr, idx, reinterpret_cast<PASTIX_COMPLEX*>(vals), perm, invp, reinterpret_cast<PASTIX_COMPLEX*>(x), nbrhs, iparm, dparm);
}
- void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex<double> *vals, int *perm, int * invp, std::complex<double> *x, int nbrhs, int *iparm, double *dparm)
+ inline void eigen_pastix(pastix_data_t **pastix_data, int pastix_comm, int n, int *ptr, int *idx, std::complex<double> *vals, int *perm, int * invp, std::complex<double> *x, int nbrhs, int *iparm, double *dparm)
{
if (n == 0) { ptr = NULL; idx = NULL; vals = NULL; }
if (nbrhs == 0) {x = NULL; nbrhs=1;}
diff --git a/xs/src/eigen/Eigen/src/QR/ColPivHouseholderQR.h b/xs/src/eigen/Eigen/src/QR/ColPivHouseholderQR.h
index 0e47c8332..a7b47d55d 100644
--- a/xs/src/eigen/Eigen/src/QR/ColPivHouseholderQR.h
+++ b/xs/src/eigen/Eigen/src/QR/ColPivHouseholderQR.h
@@ -506,8 +506,8 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
m_colNormsUpdated.coeffRef(k) = m_colNormsDirect.coeffRef(k);
}
- RealScalar threshold_helper = numext::abs2<Scalar>(m_colNormsUpdated.maxCoeff() * NumTraits<Scalar>::epsilon()) / RealScalar(rows);
- RealScalar norm_downdate_threshold = numext::sqrt(NumTraits<Scalar>::epsilon());
+ RealScalar threshold_helper = numext::abs2<RealScalar>(m_colNormsUpdated.maxCoeff() * NumTraits<RealScalar>::epsilon()) / RealScalar(rows);
+ RealScalar norm_downdate_threshold = numext::sqrt(NumTraits<RealScalar>::epsilon());
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
m_maxpivot = RealScalar(0);
@@ -553,12 +553,12 @@ void ColPivHouseholderQR<MatrixType>::computeInPlace()
// http://www.netlib.org/lapack/lawnspdf/lawn176.pdf
// and used in LAPACK routines xGEQPF and xGEQP3.
// See lines 278-297 in http://www.netlib.org/lapack/explore-html/dc/df4/sgeqpf_8f_source.html
- if (m_colNormsUpdated.coeffRef(j) != 0) {
+ if (m_colNormsUpdated.coeffRef(j) != RealScalar(0)) {
RealScalar temp = abs(m_qr.coeffRef(k, j)) / m_colNormsUpdated.coeffRef(j);
temp = (RealScalar(1) + temp) * (RealScalar(1) - temp);
- temp = temp < 0 ? 0 : temp;
- RealScalar temp2 = temp * numext::abs2<Scalar>(m_colNormsUpdated.coeffRef(j) /
- m_colNormsDirect.coeffRef(j));
+ temp = temp < RealScalar(0) ? RealScalar(0) : temp;
+ RealScalar temp2 = temp * numext::abs2<RealScalar>(m_colNormsUpdated.coeffRef(j) /
+ m_colNormsDirect.coeffRef(j));
if (temp2 <= norm_downdate_threshold) {
// The updated norm has become too inaccurate so re-compute the column
// norm directly.
diff --git a/xs/src/eigen/Eigen/src/SVD/BDCSVD.h b/xs/src/eigen/Eigen/src/SVD/BDCSVD.h
index 25fca6f4d..1134d66e7 100644
--- a/xs/src/eigen/Eigen/src/SVD/BDCSVD.h
+++ b/xs/src/eigen/Eigen/src/SVD/BDCSVD.h
@@ -11,7 +11,7 @@
// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>
// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>
// Copyright (C) 2013 Jitse Niesen <jitse@maths.leeds.ac.uk>
-// Copyright (C) 2014-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2014-2017 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -77,6 +77,7 @@ public:
typedef _MatrixType MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
+ typedef typename NumTraits<RealScalar>::Literal Literal;
enum {
RowsAtCompileTime = MatrixType::RowsAtCompileTime,
ColsAtCompileTime = MatrixType::ColsAtCompileTime,
@@ -259,7 +260,7 @@ BDCSVD<MatrixType>& BDCSVD<MatrixType>::compute(const MatrixType& matrix, unsign
//**** step 0 - Copy the input matrix and apply scaling to reduce over/under-flows
RealScalar scale = matrix.cwiseAbs().maxCoeff();
- if(scale==RealScalar(0)) scale = RealScalar(1);
+ if(scale==Literal(0)) scale = Literal(1);
MatrixX copy;
if (m_isTranspose) copy = matrix.adjoint()/scale;
else copy = matrix/scale;
@@ -351,13 +352,13 @@ void BDCSVD<MatrixType>::structured_update(Block<MatrixXr,Dynamic,Dynamic> A, co
Index k1=0, k2=0;
for(Index j=0; j<n; ++j)
{
- if( (A.col(j).head(n1).array()!=0).any() )
+ if( (A.col(j).head(n1).array()!=Literal(0)).any() )
{
A1.col(k1) = A.col(j).head(n1);
B1.row(k1) = B.row(j);
++k1;
}
- if( (A.col(j).tail(n2).array()!=0).any() )
+ if( (A.col(j).tail(n2).array()!=Literal(0)).any() )
{
A2.col(k2) = A.col(j).tail(n2);
B2.row(k2) = B.row(j);
@@ -449,11 +450,11 @@ void BDCSVD<MatrixType>::divide (Index firstCol, Index lastCol, Index firstRowW,
l = m_naiveU.row(1).segment(firstCol, k);
f = m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1);
}
- if (m_compV) m_naiveV(firstRowW+k, firstColW) = 1;
+ if (m_compV) m_naiveV(firstRowW+k, firstColW) = Literal(1);
if (r0<considerZero)
{
- c0 = 1;
- s0 = 0;
+ c0 = Literal(1);
+ s0 = Literal(0);
}
else
{
@@ -574,7 +575,7 @@ void BDCSVD<MatrixType>::computeSVDofM(Index firstCol, Index n, MatrixXr& U, Vec
ArrayRef col0 = m_computed.col(firstCol).segment(firstCol, n);
m_workspace.head(n) = m_computed.block(firstCol, firstCol, n, n).diagonal();
ArrayRef diag = m_workspace.head(n);
- diag(0) = 0;
+ diag(0) = Literal(0);
// Allocate space for singular values and vectors
singVals.resize(n);
@@ -590,7 +591,7 @@ void BDCSVD<MatrixType>::computeSVDofM(Index firstCol, Index n, MatrixXr& U, Vec
// but others are interleaved and we must ignore them at this stage.
// To this end, let's compute a permutation skipping them:
Index actual_n = n;
- while(actual_n>1 && diag(actual_n-1)==0) --actual_n;
+ while(actual_n>1 && diag(actual_n-1)==Literal(0)) --actual_n;
Index m = 0; // size of the deflated problem
for(Index k=0;k<actual_n;++k)
if(abs(col0(k))>considerZero)
@@ -691,11 +692,13 @@ template <typename MatrixType>
typename BDCSVD<MatrixType>::RealScalar BDCSVD<MatrixType>::secularEq(RealScalar mu, const ArrayRef& col0, const ArrayRef& diag, const IndicesRef &perm, const ArrayRef& diagShifted, RealScalar shift)
{
Index m = perm.size();
- RealScalar res = 1;
+ RealScalar res = Literal(1);
for(Index i=0; i<m; ++i)
{
Index j = perm(i);
- res += numext::abs2(col0(j)) / ((diagShifted(j) - mu) * (diag(j) + shift + mu));
+ // The following expression could be rewritten to involve only a single division,
+ // but this would make the expression more sensitive to overflow.
+ res += (col0(j) / (diagShifted(j) - mu)) * (col0(j) / (diag(j) + shift + mu));
}
return res;
@@ -707,19 +710,22 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
{
using std::abs;
using std::swap;
+ using std::sqrt;
Index n = col0.size();
Index actual_n = n;
- while(actual_n>1 && col0(actual_n-1)==0) --actual_n;
+ // Note that here actual_n is computed based on col0(i)==0 instead of diag(i)==0 as above
+ // because 1) we have diag(i)==0 => col0(i)==0 and 2) if col0(i)==0, then diag(i) is already a singular value.
+ while(actual_n>1 && col0(actual_n-1)==Literal(0)) --actual_n;
for (Index k = 0; k < n; ++k)
{
- if (col0(k) == 0 || actual_n==1)
+ if (col0(k) == Literal(0) || actual_n==1)
{
// if col0(k) == 0, then entry is deflated, so singular value is on diagonal
// if actual_n==1, then the deflated problem is already diagonalized
singVals(k) = k==0 ? col0(0) : diag(k);
- mus(k) = 0;
+ mus(k) = Literal(0);
shifts(k) = k==0 ? col0(0) : diag(k);
continue;
}
@@ -731,15 +737,17 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
right = (diag(actual_n-1) + col0.matrix().norm());
else
{
- // Skip deflated singular values
+ // Skip deflated singular values,
+ // recall that at this stage we assume that z[j]!=0 and all entries for which z[j]==0 have been put aside.
+ // This should be equivalent to using perm[]
Index l = k+1;
- while(col0(l)==0) { ++l; eigen_internal_assert(l<actual_n); }
+ while(col0(l)==Literal(0)) { ++l; eigen_internal_assert(l<actual_n); }
right = diag(l);
}
// first decide whether it's closer to the left end or the right end
- RealScalar mid = left + (right-left) / 2;
- RealScalar fMid = secularEq(mid, col0, diag, perm, diag, 0);
+ RealScalar mid = left + (right-left) / Literal(2);
+ RealScalar fMid = secularEq(mid, col0, diag, perm, diag, Literal(0));
#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
std::cout << right-left << "\n";
std::cout << "fMid = " << fMid << " " << secularEq(mid-left, col0, diag, perm, diag-left, left) << " " << secularEq(mid-right, col0, diag, perm, diag-right, right) << "\n";
@@ -755,7 +763,7 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
<< " " << secularEq(0.8*(left+right), col0, diag, perm, diag, 0)
<< " " << secularEq(0.9*(left+right), col0, diag, perm, diag, 0) << "\n";
#endif
- RealScalar shift = (k == actual_n-1 || fMid > 0) ? left : right;
+ RealScalar shift = (k == actual_n-1 || fMid > Literal(0)) ? left : right;
// measure everything relative to shift
Map<ArrayXr> diagShifted(m_workspace.data()+4*n, n);
@@ -785,13 +793,13 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
// rational interpolation: fit a function of the form a / mu + b through the two previous
// iterates and use its zero to compute the next iterate
- bool useBisection = fPrev*fCur>0;
- while (fCur!=0 && abs(muCur - muPrev) > 8 * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(muCur), abs(muPrev)) && abs(fCur - fPrev)>NumTraits<RealScalar>::epsilon() && !useBisection)
+ bool useBisection = fPrev*fCur>Literal(0);
+ while (fCur!=Literal(0) && abs(muCur - muPrev) > Literal(8) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(muCur), abs(muPrev)) && abs(fCur - fPrev)>NumTraits<RealScalar>::epsilon() && !useBisection)
{
++m_numIters;
// Find a and b such that the function f(mu) = a / mu + b matches the current and previous samples.
- RealScalar a = (fCur - fPrev) / (1/muCur - 1/muPrev);
+ RealScalar a = (fCur - fPrev) / (Literal(1)/muCur - Literal(1)/muPrev);
RealScalar b = fCur - a / muCur;
// And find mu such that f(mu)==0:
RealScalar muZero = -a/b;
@@ -803,8 +811,8 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
fCur = fZero;
- if (shift == left && (muCur < 0 || muCur > right - left)) useBisection = true;
- if (shift == right && (muCur < -(right - left) || muCur > 0)) useBisection = true;
+ if (shift == left && (muCur < Literal(0) || muCur > right - left)) useBisection = true;
+ if (shift == right && (muCur < -(right - left) || muCur > Literal(0))) useBisection = true;
if (abs(fCur)>abs(fPrev)) useBisection = true;
}
@@ -817,15 +825,23 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
RealScalar leftShifted, rightShifted;
if (shift == left)
{
- leftShifted = (std::numeric_limits<RealScalar>::min)();
+ // to avoid overflow, we must have mu > max(real_min, |z(k)|/sqrt(real_max)),
+ // the factor 2 is to be more conservative
+ leftShifted = numext::maxi<RealScalar>( (std::numeric_limits<RealScalar>::min)(), Literal(2) * abs(col0(k)) / sqrt((std::numeric_limits<RealScalar>::max)()) );
+
+ // check that we did it right:
+ eigen_internal_assert( (numext::isfinite)( (col0(k)/leftShifted)*(col0(k)/(diag(k)+shift+leftShifted)) ) );
// I don't understand why the case k==0 would be special there:
- // if (k == 0) rightShifted = right - left; else
- rightShifted = (k==actual_n-1) ? right : ((right - left) * RealScalar(0.6)); // theoretically we can take 0.5, but let's be safe
+ // if (k == 0) rightShifted = right - left; else
+ rightShifted = (k==actual_n-1) ? right : ((right - left) * RealScalar(0.51)); // theoretically we can take 0.5, but let's be safe
}
else
{
- leftShifted = -(right - left) * RealScalar(0.6);
- rightShifted = -(std::numeric_limits<RealScalar>::min)();
+ leftShifted = -(right - left) * RealScalar(0.51);
+ if(k+1<n)
+ rightShifted = -numext::maxi<RealScalar>( (std::numeric_limits<RealScalar>::min)(), abs(col0(k+1)) / sqrt((std::numeric_limits<RealScalar>::max)()) );
+ else
+ rightShifted = -(std::numeric_limits<RealScalar>::min)();
}
RealScalar fLeft = secularEq(leftShifted, col0, diag, perm, diagShifted, shift);
@@ -841,13 +857,13 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
std::cout << k << " : " << fLeft << " * " << fRight << " == " << fLeft * fRight << " ; " << left << " - " << right << " -> " << leftShifted << " " << rightShifted << " shift=" << shift << "\n";
}
#endif
- eigen_internal_assert(fLeft * fRight < 0);
+ eigen_internal_assert(fLeft * fRight < Literal(0));
- while (rightShifted - leftShifted > 2 * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(leftShifted), abs(rightShifted)))
+ while (rightShifted - leftShifted > Literal(2) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(abs(leftShifted), abs(rightShifted)))
{
- RealScalar midShifted = (leftShifted + rightShifted) / 2;
+ RealScalar midShifted = (leftShifted + rightShifted) / Literal(2);
fMid = secularEq(midShifted, col0, diag, perm, diagShifted, shift);
- if (fLeft * fMid < 0)
+ if (fLeft * fMid < Literal(0))
{
rightShifted = midShifted;
}
@@ -858,7 +874,7 @@ void BDCSVD<MatrixType>::computeSingVals(const ArrayRef& col0, const ArrayRef& d
}
}
- muCur = (leftShifted + rightShifted) / 2;
+ muCur = (leftShifted + rightShifted) / Literal(2);
}
singVals[k] = shift + muCur;
@@ -892,8 +908,8 @@ void BDCSVD<MatrixType>::perturbCol0
// The offset permits to skip deflated entries while computing zhat
for (Index k = 0; k < n; ++k)
{
- if (col0(k) == 0) // deflated
- zhat(k) = 0;
+ if (col0(k) == Literal(0)) // deflated
+ zhat(k) = Literal(0);
else
{
// see equation (3.6)
@@ -918,7 +934,7 @@ void BDCSVD<MatrixType>::perturbCol0
std::cout << "zhat(" << k << ") = sqrt( " << prod << ") ; " << (singVals(last) + dk) << " * " << mus(last) + shifts(last) << " - " << dk << "\n";
#endif
RealScalar tmp = sqrt(prod);
- zhat(k) = col0(k) > 0 ? tmp : -tmp;
+ zhat(k) = col0(k) > Literal(0) ? tmp : -tmp;
}
}
}
@@ -934,7 +950,7 @@ void BDCSVD<MatrixType>::computeSingVecs
for (Index k = 0; k < n; ++k)
{
- if (zhat(k) == 0)
+ if (zhat(k) == Literal(0))
{
U.col(k) = VectorType::Unit(n+1, k);
if (m_compV) V.col(k) = VectorType::Unit(n, k);
@@ -947,7 +963,7 @@ void BDCSVD<MatrixType>::computeSingVecs
Index i = perm(l);
U(i,k) = zhat(i)/(((diag(i) - shifts(k)) - mus(k)) )/( (diag(i) + singVals[k]));
}
- U(n,k) = 0;
+ U(n,k) = Literal(0);
U.col(k).normalize();
if (m_compV)
@@ -958,7 +974,7 @@ void BDCSVD<MatrixType>::computeSingVecs
Index i = perm(l);
V(i,k) = diag(i) * zhat(i) / (((diag(i) - shifts(k)) - mus(k)) )/( (diag(i) + singVals[k]));
}
- V(0,k) = -1;
+ V(0,k) = Literal(-1);
V.col(k).normalize();
}
}
@@ -979,15 +995,15 @@ void BDCSVD<MatrixType>::deflation43(Index firstCol, Index shift, Index i, Index
Index start = firstCol + shift;
RealScalar c = m_computed(start, start);
RealScalar s = m_computed(start+i, start);
- RealScalar r = sqrt(numext::abs2(c) + numext::abs2(s));
- if (r == 0)
+ RealScalar r = numext::hypot(c,s);
+ if (r == Literal(0))
{
- m_computed(start+i, start+i) = 0;
+ m_computed(start+i, start+i) = Literal(0);
return;
}
m_computed(start,start) = r;
- m_computed(start+i, start) = 0;
- m_computed(start+i, start+i) = 0;
+ m_computed(start+i, start) = Literal(0);
+ m_computed(start+i, start+i) = Literal(0);
JacobiRotation<RealScalar> J(c/r,-s/r);
if (m_compU) m_naiveU.middleRows(firstCol, size+1).applyOnTheRight(firstCol, firstCol+i, J);
@@ -1020,7 +1036,7 @@ void BDCSVD<MatrixType>::deflation44(Index firstColu , Index firstColm, Index fi
<< m_computed(firstColm + i+1, firstColm+i+1) << " "
<< m_computed(firstColm + i+2, firstColm+i+2) << "\n";
#endif
- if (r==0)
+ if (r==Literal(0))
{
m_computed(firstColm + i, firstColm + i) = m_computed(firstColm + j, firstColm + j);
return;
@@ -1029,7 +1045,7 @@ void BDCSVD<MatrixType>::deflation44(Index firstColu , Index firstColm, Index fi
s/=r;
m_computed(firstColm + i, firstColm) = r;
m_computed(firstColm + j, firstColm + j) = m_computed(firstColm + i, firstColm + i);
- m_computed(firstColm + j, firstColm) = 0;
+ m_computed(firstColm + j, firstColm) = Literal(0);
JacobiRotation<RealScalar> J(c,-s);
if (m_compU) m_naiveU.middleRows(firstColu, size+1).applyOnTheRight(firstColu + i, firstColu + j, J);
@@ -1053,7 +1069,7 @@ void BDCSVD<MatrixType>::deflation(Index firstCol, Index lastCol, Index k, Index
const RealScalar considerZero = (std::numeric_limits<RealScalar>::min)();
RealScalar maxDiag = diag.tail((std::max)(Index(1),length-1)).cwiseAbs().maxCoeff();
RealScalar epsilon_strict = numext::maxi<RealScalar>(considerZero,NumTraits<RealScalar>::epsilon() * maxDiag);
- RealScalar epsilon_coarse = 8 * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(col0.cwiseAbs().maxCoeff(), maxDiag);
+ RealScalar epsilon_coarse = Literal(8) * NumTraits<RealScalar>::epsilon() * numext::maxi<RealScalar>(col0.cwiseAbs().maxCoeff(), maxDiag);
#ifdef EIGEN_BDCSVD_SANITY_CHECKS
assert(m_naiveU.allFinite());
@@ -1081,7 +1097,7 @@ void BDCSVD<MatrixType>::deflation(Index firstCol, Index lastCol, Index k, Index
#ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
std::cout << "deflation 4.2, set z(" << i << ") to zero because " << abs(col0(i)) << " < " << epsilon_strict << " (diag(" << i << ")=" << diag(i) << ")\n";
#endif
- col0(i) = 0;
+ col0(i) = Literal(0);
}
//condition 4.3
diff --git a/xs/src/eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h b/xs/src/eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h
index 50272154f..ff0516f61 100644
--- a/xs/src/eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h
+++ b/xs/src/eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h
@@ -61,9 +61,10 @@ JacobiSVD<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>, ColPiv
u = (LAPACKE_TYPE*)m_matrixU.data(); \
} else { ldu=1; u=&dummy; }\
MatrixType localV; \
- ldvt = (m_computeFullV) ? internal::convert_index<lapack_int>(m_cols) : (m_computeThinV) ? internal::convert_index<lapack_int>(m_diagSize) : 1; \
+ lapack_int vt_rows = (m_computeFullV) ? internal::convert_index<lapack_int>(m_cols) : (m_computeThinV) ? internal::convert_index<lapack_int>(m_diagSize) : 1; \
if (computeV()) { \
- localV.resize(ldvt, m_cols); \
+ localV.resize(vt_rows, m_cols); \
+ ldvt = internal::convert_index<lapack_int>(localV.outerStride()); \
vt = (LAPACKE_TYPE*)localV.data(); \
} else { ldvt=1; vt=&dummy; }\
Matrix<LAPACKE_RTYPE, Dynamic, Dynamic> superb; superb.resize(m_diagSize, 1); \
diff --git a/xs/src/eigen/Eigen/src/SVD/UpperBidiagonalization.h b/xs/src/eigen/Eigen/src/SVD/UpperBidiagonalization.h
index 0b1460894..11ac847e1 100644
--- a/xs/src/eigen/Eigen/src/SVD/UpperBidiagonalization.h
+++ b/xs/src/eigen/Eigen/src/SVD/UpperBidiagonalization.h
@@ -159,6 +159,8 @@ void upperbidiagonalization_blocked_helper(MatrixType& A,
traits<MatrixType>::Flags & RowMajorBit> > Y)
{
typedef typename MatrixType::Scalar Scalar;
+ typedef typename MatrixType::RealScalar RealScalar;
+ typedef typename NumTraits<RealScalar>::Literal Literal;
enum { StorageOrder = traits<MatrixType>::Flags & RowMajorBit };
typedef InnerStride<int(StorageOrder) == int(ColMajor) ? 1 : Dynamic> ColInnerStride;
typedef InnerStride<int(StorageOrder) == int(ColMajor) ? Dynamic : 1> RowInnerStride;
@@ -263,7 +265,7 @@ void upperbidiagonalization_blocked_helper(MatrixType& A,
SubMatType A10( A.block(bs,0, brows-bs,bs) );
SubMatType A01( A.block(0,bs, bs,bcols-bs) );
Scalar tmp = A01(bs-1,0);
- A01(bs-1,0) = 1;
+ A01(bs-1,0) = Literal(1);
A11.noalias() -= A10 * Y.topLeftCorner(bcols,bs).bottomRows(bcols-bs).adjoint();
A11.noalias() -= X.topLeftCorner(brows,bs).bottomRows(brows-bs) * A01;
A01(bs-1,0) = tmp;
diff --git a/xs/src/eigen/Eigen/src/SparseCore/AmbiVector.h b/xs/src/eigen/Eigen/src/SparseCore/AmbiVector.h
index 8a5cc91f2..e0295f2af 100644
--- a/xs/src/eigen/Eigen/src/SparseCore/AmbiVector.h
+++ b/xs/src/eigen/Eigen/src/SparseCore/AmbiVector.h
@@ -94,7 +94,7 @@ class AmbiVector
Index allocSize = m_allocatedElements * sizeof(ListEl);
allocSize = (allocSize + sizeof(Scalar) - 1)/sizeof(Scalar);
Scalar* newBuffer = new Scalar[allocSize];
- memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl));
+ std::memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl));
delete[] m_buffer;
m_buffer = newBuffer;
}
diff --git a/xs/src/eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h b/xs/src/eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
index 492eb0a29..9db119b67 100644
--- a/xs/src/eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
+++ b/xs/src/eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
@@ -17,7 +17,9 @@ namespace internal {
template<typename Lhs, typename Rhs, typename ResultType>
static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res, bool sortedInsertion = false)
{
- typedef typename remove_all<Lhs>::type::Scalar Scalar;
+ typedef typename remove_all<Lhs>::type::Scalar LhsScalar;
+ typedef typename remove_all<Rhs>::type::Scalar RhsScalar;
+ typedef typename remove_all<ResultType>::type::Scalar ResScalar;
// make sure to call innerSize/outerSize since we fake the storage order.
Index rows = lhs.innerSize();
@@ -25,7 +27,7 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r
eigen_assert(lhs.outerSize() == rhs.innerSize());
ei_declare_aligned_stack_constructed_variable(bool, mask, rows, 0);
- ei_declare_aligned_stack_constructed_variable(Scalar, values, rows, 0);
+ ei_declare_aligned_stack_constructed_variable(ResScalar, values, rows, 0);
ei_declare_aligned_stack_constructed_variable(Index, indices, rows, 0);
std::memset(mask,0,sizeof(bool)*rows);
@@ -51,12 +53,12 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r
Index nnz = 0;
for (typename evaluator<Rhs>::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt)
{
- Scalar y = rhsIt.value();
+ RhsScalar y = rhsIt.value();
Index k = rhsIt.index();
for (typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt)
{
Index i = lhsIt.index();
- Scalar x = lhsIt.value();
+ LhsScalar x = lhsIt.value();
if(!mask[i])
{
mask[i] = true;
@@ -166,11 +168,12 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,C
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorMatrix;
- RowMajorMatrix rhsRow = rhs;
- RowMajorMatrix resRow(lhs.rows(), rhs.cols());
- internal::conservative_sparse_sparse_product_impl<RowMajorMatrix,Lhs,RowMajorMatrix>(rhsRow, lhs, resRow);
- res = resRow;
+ typedef SparseMatrix<typename Rhs::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorRhs;
+ typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorRes;
+ RowMajorRhs rhsRow = rhs;
+ RowMajorRes resRow(lhs.rows(), rhs.cols());
+ internal::conservative_sparse_sparse_product_impl<RowMajorRhs,Lhs,RowMajorRes>(rhsRow, lhs, resRow);
+ res = resRow;
}
};
@@ -179,10 +182,11 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,R
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorMatrix;
- RowMajorMatrix lhsRow = lhs;
- RowMajorMatrix resRow(lhs.rows(), rhs.cols());
- internal::conservative_sparse_sparse_product_impl<Rhs,RowMajorMatrix,RowMajorMatrix>(rhs, lhsRow, resRow);
+ typedef SparseMatrix<typename Lhs::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorLhs;
+ typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename ResultType::StorageIndex> RowMajorRes;
+ RowMajorLhs lhsRow = lhs;
+ RowMajorRes resRow(lhs.rows(), rhs.cols());
+ internal::conservative_sparse_sparse_product_impl<Rhs,RowMajorLhs,RowMajorRes>(rhs, lhsRow, resRow);
res = resRow;
}
};
@@ -219,10 +223,11 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,C
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorMatrix;
- ColMajorMatrix lhsCol = lhs;
- ColMajorMatrix resCol(lhs.rows(), rhs.cols());
- internal::conservative_sparse_sparse_product_impl<ColMajorMatrix,Rhs,ColMajorMatrix>(lhsCol, rhs, resCol);
+ typedef SparseMatrix<typename Lhs::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorLhs;
+ typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorRes;
+ ColMajorLhs lhsCol = lhs;
+ ColMajorRes resCol(lhs.rows(), rhs.cols());
+ internal::conservative_sparse_sparse_product_impl<ColMajorLhs,Rhs,ColMajorRes>(lhsCol, rhs, resCol);
res = resCol;
}
};
@@ -232,10 +237,11 @@ struct conservative_sparse_sparse_product_selector<Lhs,Rhs,ResultType,ColMajor,R
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorMatrix;
- ColMajorMatrix rhsCol = rhs;
- ColMajorMatrix resCol(lhs.rows(), rhs.cols());
- internal::conservative_sparse_sparse_product_impl<Lhs,ColMajorMatrix,ColMajorMatrix>(lhs, rhsCol, resCol);
+ typedef SparseMatrix<typename Rhs::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorRhs;
+ typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorRes;
+ ColMajorRhs rhsCol = rhs;
+ ColMajorRes resCol(lhs.rows(), rhs.cols());
+ internal::conservative_sparse_sparse_product_impl<Lhs,ColMajorRhs,ColMajorRes>(lhs, rhsCol, resCol);
res = resCol;
}
};
@@ -263,7 +269,8 @@ namespace internal {
template<typename Lhs, typename Rhs, typename ResultType>
static void sparse_sparse_to_dense_product_impl(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef typename remove_all<Lhs>::type::Scalar Scalar;
+ typedef typename remove_all<Lhs>::type::Scalar LhsScalar;
+ typedef typename remove_all<Rhs>::type::Scalar RhsScalar;
Index cols = rhs.outerSize();
eigen_assert(lhs.outerSize() == rhs.innerSize());
@@ -274,12 +281,12 @@ static void sparse_sparse_to_dense_product_impl(const Lhs& lhs, const Rhs& rhs,
{
for (typename evaluator<Rhs>::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt)
{
- Scalar y = rhsIt.value();
+ RhsScalar y = rhsIt.value();
Index k = rhsIt.index();
for (typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt)
{
Index i = lhsIt.index();
- Scalar x = lhsIt.value();
+ LhsScalar x = lhsIt.value();
res.coeffRef(i,j) += x * y;
}
}
@@ -310,9 +317,9 @@ struct sparse_sparse_to_dense_product_selector<Lhs,Rhs,ResultType,RowMajor,ColMa
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorMatrix;
- ColMajorMatrix lhsCol(lhs);
- internal::sparse_sparse_to_dense_product_impl<ColMajorMatrix,Rhs,ResultType>(lhsCol, rhs, res);
+ typedef SparseMatrix<typename Lhs::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorLhs;
+ ColMajorLhs lhsCol(lhs);
+ internal::sparse_sparse_to_dense_product_impl<ColMajorLhs,Rhs,ResultType>(lhsCol, rhs, res);
}
};
@@ -321,9 +328,9 @@ struct sparse_sparse_to_dense_product_selector<Lhs,Rhs,ResultType,ColMajor,RowMa
{
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res)
{
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorMatrix;
- ColMajorMatrix rhsCol(rhs);
- internal::sparse_sparse_to_dense_product_impl<Lhs,ColMajorMatrix,ResultType>(lhs, rhsCol, res);
+ typedef SparseMatrix<typename Rhs::Scalar,ColMajor,typename ResultType::StorageIndex> ColMajorRhs;
+ ColMajorRhs rhsCol(rhs);
+ internal::sparse_sparse_to_dense_product_impl<Lhs,ColMajorRhs,ResultType>(lhs, rhsCol, res);
}
};
diff --git a/xs/src/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h b/xs/src/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h
index 9e39be738..65611b3d4 100644
--- a/xs/src/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h
+++ b/xs/src/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h
@@ -47,6 +47,7 @@ template<typename MatrixType, unsigned int _Mode> class SparseSelfAdjointView
enum {
Mode = _Mode,
+ TransposeMode = ((Mode & Upper) ? Lower : 0) | ((Mode & Lower) ? Upper : 0),
RowsAtCompileTime = internal::traits<SparseSelfAdjointView>::RowsAtCompileTime,
ColsAtCompileTime = internal::traits<SparseSelfAdjointView>::ColsAtCompileTime
};
@@ -310,7 +311,7 @@ inline void sparse_selfadjoint_time_dense_product(const SparseLhsType& lhs, cons
while (i && i.index()<j) ++i;
if(i && i.index()==j)
{
- res(j,k) += alpha * i.value() * rhs(j,k);
+ res.coeffRef(j,k) += alpha * i.value() * rhs.coeff(j,k);
++i;
}
}
@@ -323,14 +324,14 @@ inline void sparse_selfadjoint_time_dense_product(const SparseLhsType& lhs, cons
{
LhsScalar lhs_ij = i.value();
if(!LhsIsRowMajor) lhs_ij = numext::conj(lhs_ij);
- res_j += lhs_ij * rhs(i.index(),k);
+ res_j += lhs_ij * rhs.coeff(i.index(),k);
res(i.index(),k) += numext::conj(lhs_ij) * rhs_j;
}
- res(j,k) += alpha * res_j;
+ res.coeffRef(j,k) += alpha * res_j;
// handle diagonal coeff
if (ProcessFirstHalf && i && (i.index()==j))
- res(j,k) += alpha * i.value() * rhs(j,k);
+ res.coeffRef(j,k) += alpha * i.value() * rhs.coeff(j,k);
}
}
}
@@ -368,7 +369,7 @@ struct generic_product_impl<Lhs, RhsView, DenseShape, SparseSelfAdjointShape, Pr
// transpose everything
Transpose<Dest> dstT(dst);
- internal::sparse_selfadjoint_time_dense_product<RhsView::Mode>(rhsNested.transpose(), lhsNested.transpose(), dstT, alpha);
+ internal::sparse_selfadjoint_time_dense_product<RhsView::TransposeMode>(rhsNested.transpose(), lhsNested.transpose(), dstT, alpha);
}
};
diff --git a/xs/src/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h b/xs/src/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h
index 21c419002..88820a48f 100644
--- a/xs/src/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h
+++ b/xs/src/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h
@@ -21,7 +21,8 @@ static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& r
{
// return sparse_sparse_product_with_pruning_impl2(lhs,rhs,res);
- typedef typename remove_all<Lhs>::type::Scalar Scalar;
+ typedef typename remove_all<Rhs>::type::Scalar RhsScalar;
+ typedef typename remove_all<ResultType>::type::Scalar ResScalar;
typedef typename remove_all<Lhs>::type::StorageIndex StorageIndex;
// make sure to call innerSize/outerSize since we fake the storage order.
@@ -31,7 +32,7 @@ static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& r
eigen_assert(lhs.outerSize() == rhs.innerSize());
// allocate a temporary buffer
- AmbiVector<Scalar,StorageIndex> tempVector(rows);
+ AmbiVector<ResScalar,StorageIndex> tempVector(rows);
// mimics a resizeByInnerOuter:
if(ResultType::IsRowMajor)
@@ -63,14 +64,14 @@ static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& r
{
// FIXME should be written like this: tmp += rhsIt.value() * lhs.col(rhsIt.index())
tempVector.restart();
- Scalar x = rhsIt.value();
+ RhsScalar x = rhsIt.value();
for (typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, rhsIt.index()); lhsIt; ++lhsIt)
{
tempVector.coeffRef(lhsIt.index()) += lhsIt.value() * x;
}
}
res.startVec(j);
- for (typename AmbiVector<Scalar,StorageIndex>::Iterator it(tempVector,tolerance); it; ++it)
+ for (typename AmbiVector<ResScalar,StorageIndex>::Iterator it(tempVector,tolerance); it; ++it)
res.insertBackByOuterInner(j,it.index()) = it.value();
}
res.finalize();
@@ -85,7 +86,6 @@ struct sparse_sparse_product_with_pruning_selector;
template<typename Lhs, typename Rhs, typename ResultType>
struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,ColMajor,ColMajor,ColMajor>
{
- typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar;
typedef typename ResultType::RealScalar RealScalar;
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance)
@@ -129,8 +129,8 @@ struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,RowMajor,R
typedef typename ResultType::RealScalar RealScalar;
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance)
{
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename Lhs::StorageIndex> ColMajorMatrixLhs;
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename Lhs::StorageIndex> ColMajorMatrixRhs;
+ typedef SparseMatrix<typename Lhs::Scalar,ColMajor,typename Lhs::StorageIndex> ColMajorMatrixLhs;
+ typedef SparseMatrix<typename Rhs::Scalar,ColMajor,typename Lhs::StorageIndex> ColMajorMatrixRhs;
ColMajorMatrixLhs colLhs(lhs);
ColMajorMatrixRhs colRhs(rhs);
internal::sparse_sparse_product_with_pruning_impl<ColMajorMatrixLhs,ColMajorMatrixRhs,ResultType>(colLhs, colRhs, res, tolerance);
@@ -149,7 +149,7 @@ struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,ColMajor,R
typedef typename ResultType::RealScalar RealScalar;
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance)
{
- typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename Lhs::StorageIndex> RowMajorMatrixLhs;
+ typedef SparseMatrix<typename Lhs::Scalar,RowMajor,typename Lhs::StorageIndex> RowMajorMatrixLhs;
RowMajorMatrixLhs rowLhs(lhs);
sparse_sparse_product_with_pruning_selector<RowMajorMatrixLhs,Rhs,ResultType,RowMajor,RowMajor>(rowLhs,rhs,res,tolerance);
}
@@ -161,7 +161,7 @@ struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,RowMajor,C
typedef typename ResultType::RealScalar RealScalar;
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance)
{
- typedef SparseMatrix<typename ResultType::Scalar,RowMajor,typename Lhs::StorageIndex> RowMajorMatrixRhs;
+ typedef SparseMatrix<typename Rhs::Scalar,RowMajor,typename Lhs::StorageIndex> RowMajorMatrixRhs;
RowMajorMatrixRhs rowRhs(rhs);
sparse_sparse_product_with_pruning_selector<Lhs,RowMajorMatrixRhs,ResultType,RowMajor,RowMajor,RowMajor>(lhs,rowRhs,res,tolerance);
}
@@ -173,7 +173,7 @@ struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,ColMajor,R
typedef typename ResultType::RealScalar RealScalar;
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance)
{
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename Lhs::StorageIndex> ColMajorMatrixRhs;
+ typedef SparseMatrix<typename Rhs::Scalar,ColMajor,typename Lhs::StorageIndex> ColMajorMatrixRhs;
ColMajorMatrixRhs colRhs(rhs);
internal::sparse_sparse_product_with_pruning_impl<Lhs,ColMajorMatrixRhs,ResultType>(lhs, colRhs, res, tolerance);
}
@@ -185,7 +185,7 @@ struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,RowMajor,C
typedef typename ResultType::RealScalar RealScalar;
static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res, const RealScalar& tolerance)
{
- typedef SparseMatrix<typename ResultType::Scalar,ColMajor,typename Lhs::StorageIndex> ColMajorMatrixLhs;
+ typedef SparseMatrix<typename Lhs::Scalar,ColMajor,typename Lhs::StorageIndex> ColMajorMatrixLhs;
ColMajorMatrixLhs colLhs(lhs);
internal::sparse_sparse_product_with_pruning_impl<ColMajorMatrixLhs,Rhs,ResultType>(colLhs, rhs, res, tolerance);
}
diff --git a/xs/src/eigen/Eigen/src/SparseQR/SparseQR.h b/xs/src/eigen/Eigen/src/SparseQR/SparseQR.h
index 2d4498b03..7409fcae9 100644
--- a/xs/src/eigen/Eigen/src/SparseQR/SparseQR.h
+++ b/xs/src/eigen/Eigen/src/SparseQR/SparseQR.h
@@ -52,7 +52,7 @@ namespace internal {
* rank-revealing permutations. Use colsPermutation() to get it.
*
* Q is the orthogonal matrix represented as products of Householder reflectors.
- * Use matrixQ() to get an expression and matrixQ().transpose() to get the transpose.
+ * Use matrixQ() to get an expression and matrixQ().adjoint() to get the adjoint.
* You can then apply it to a vector.
*
* R is the sparse triangular or trapezoidal matrix. The later occurs when A is rank-deficient.
@@ -65,6 +65,7 @@ namespace internal {
* \implsparsesolverconcept
*
* \warning The input sparse matrix A must be in compressed mode (see SparseMatrix::makeCompressed()).
+ * \warning For complex matrices matrixQ().transpose() will actually return the adjoint matrix.
*
*/
template<typename _MatrixType, typename _OrderingType>
@@ -196,9 +197,9 @@ class SparseQR : public SparseSolverBase<SparseQR<_MatrixType,_OrderingType> >
Index rank = this->rank();
- // Compute Q^T * b;
+ // Compute Q^* * b;
typename Dest::PlainObject y, b;
- y = this->matrixQ().transpose() * B;
+ y = this->matrixQ().adjoint() * B;
b = y;
// Solve with the triangular matrix R
@@ -604,7 +605,7 @@ struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived
// Get the references
SparseQR_QProduct(const SparseQRType& qr, const Derived& other, bool transpose) :
m_qr(qr),m_other(other),m_transpose(transpose) {}
- inline Index rows() const { return m_transpose ? m_qr.rows() : m_qr.cols(); }
+ inline Index rows() const { return m_qr.matrixQ().rows(); }
inline Index cols() const { return m_other.cols(); }
// Assign to a vector
@@ -632,7 +633,10 @@ struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived
}
else
{
- eigen_assert(m_qr.m_Q.rows() == m_other.rows() && "Non conforming object sizes");
+ eigen_assert(m_qr.matrixQ().cols() == m_other.rows() && "Non conforming object sizes");
+
+ res.conservativeResize(rows(), cols());
+
// Compute res = Q * other column by column
for(Index j = 0; j < res.cols(); j++)
{
@@ -641,7 +645,7 @@ struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived
Scalar tau = Scalar(0);
tau = m_qr.m_Q.col(k).dot(res.col(j));
if(tau==Scalar(0)) continue;
- tau = tau * m_qr.m_hcoeffs(k);
+ tau = tau * numext::conj(m_qr.m_hcoeffs(k));
res.col(j) -= tau * m_qr.m_Q.col(k);
}
}
@@ -650,7 +654,7 @@ struct SparseQR_QProduct : ReturnByValue<SparseQR_QProduct<SparseQRType, Derived
const SparseQRType& m_qr;
const Derived& m_other;
- bool m_transpose;
+ bool m_transpose; // TODO this actually means adjoint
};
template<typename SparseQRType>
@@ -668,13 +672,14 @@ struct SparseQRMatrixQReturnType : public EigenBase<SparseQRMatrixQReturnType<Sp
{
return SparseQR_QProduct<SparseQRType,Derived>(m_qr,other.derived(),false);
}
+ // To use for operations with the adjoint of Q
SparseQRMatrixQTransposeReturnType<SparseQRType> adjoint() const
{
return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
}
inline Index rows() const { return m_qr.rows(); }
- inline Index cols() const { return (std::min)(m_qr.rows(),m_qr.cols()); }
- // To use for operations with the transpose of Q
+ inline Index cols() const { return m_qr.rows(); }
+ // To use for operations with the transpose of Q FIXME this is the same as adjoint at the moment
SparseQRMatrixQTransposeReturnType<SparseQRType> transpose() const
{
return SparseQRMatrixQTransposeReturnType<SparseQRType>(m_qr);
@@ -682,6 +687,7 @@ struct SparseQRMatrixQReturnType : public EigenBase<SparseQRMatrixQReturnType<Sp
const SparseQRType& m_qr;
};
+// TODO this actually represents the adjoint of Q
template<typename SparseQRType>
struct SparseQRMatrixQTransposeReturnType
{
@@ -712,7 +718,7 @@ struct Assignment<DstXprType, SparseQRMatrixQReturnType<SparseQRType>, internal:
typedef typename DstXprType::StorageIndex StorageIndex;
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &/*func*/)
{
- typename DstXprType::PlainObject idMat(src.m_qr.rows(), src.m_qr.rows());
+ typename DstXprType::PlainObject idMat(src.rows(), src.cols());
idMat.setIdentity();
// Sort the sparse householder reflectors if needed
const_cast<SparseQRType *>(&src.m_qr)->_sort_matrix_Q();
diff --git a/xs/src/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h b/xs/src/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h
index dc74de935..91c09ab13 100644
--- a/xs/src/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h
+++ b/xs/src/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h
@@ -10,19 +10,37 @@
#ifndef EIGEN_UMFPACKSUPPORT_H
#define EIGEN_UMFPACKSUPPORT_H
-namespace Eigen {
+namespace Eigen {
/* TODO extract L, extract U, compute det, etc... */
// generic double/complex<double> wrapper functions:
-inline void umfpack_defaults(double control[UMFPACK_CONTROL], double)
+inline void umfpack_defaults(double control[UMFPACK_CONTROL], double)
{ umfpack_di_defaults(control); }
-inline void umfpack_defaults(double control[UMFPACK_CONTROL], std::complex<double>)
+inline void umfpack_defaults(double control[UMFPACK_CONTROL], std::complex<double>)
{ umfpack_zi_defaults(control); }
+inline void umfpack_report_info(double control[UMFPACK_CONTROL], double info[UMFPACK_INFO], double)
+{ umfpack_di_report_info(control, info);}
+
+inline void umfpack_report_info(double control[UMFPACK_CONTROL], double info[UMFPACK_INFO], std::complex<double>)
+{ umfpack_zi_report_info(control, info);}
+
+inline void umfpack_report_status(double control[UMFPACK_CONTROL], int status, double)
+{ umfpack_di_report_status(control, status);}
+
+inline void umfpack_report_status(double control[UMFPACK_CONTROL], int status, std::complex<double>)
+{ umfpack_zi_report_status(control, status);}
+
+inline void umfpack_report_control(double control[UMFPACK_CONTROL], double)
+{ umfpack_di_report_control(control);}
+
+inline void umfpack_report_control(double control[UMFPACK_CONTROL], std::complex<double>)
+{ umfpack_zi_report_control(control);}
+
inline void umfpack_free_numeric(void **Numeric, double)
{ umfpack_di_free_numeric(Numeric); *Numeric = 0; }
@@ -156,6 +174,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
public:
typedef Array<double, UMFPACK_CONTROL, 1> UmfpackControl;
+ typedef Array<double, UMFPACK_INFO, 1> UmfpackInfo;
UmfPackLU()
: m_dummy(0,0), mp_matrix(m_dummy)
@@ -215,7 +234,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
return m_q;
}
- /** Computes the sparse Cholesky decomposition of \a matrix
+ /** Computes the sparse Cholesky decomposition of \a matrix
* Note that the matrix should be column-major, and in compressed format for best performance.
* \sa SparseMatrix::makeCompressed().
*/
@@ -240,7 +259,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
{
if(m_symbolic) umfpack_free_symbolic(&m_symbolic,Scalar());
if(m_numeric) umfpack_free_numeric(&m_numeric,Scalar());
-
+
grab(matrix.derived());
analyzePattern_impl();
@@ -267,7 +286,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
{
return m_control;
}
-
+
/** Provides access to the control settings array used by UmfPack.
*
* If this array contains NaN's, the default values are used.
@@ -278,7 +297,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
{
return m_control;
}
-
+
/** Performs a numeric decomposition of \a matrix
*
* The given matrix must has the same sparcity than the matrix on which the pattern anylysis has been performed.
@@ -293,10 +312,38 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
umfpack_free_numeric(&m_numeric,Scalar());
grab(matrix.derived());
-
+
factorize_impl();
}
+ /** Prints the current UmfPack control settings.
+ *
+ * \sa umfpackControl()
+ */
+ void umfpackReportControl()
+ {
+ umfpack_report_control(m_control.data(), Scalar());
+ }
+
+ /** Prints statistics collected by UmfPack.
+ *
+ * \sa analyzePattern(), compute()
+ */
+ void umfpackReportInfo()
+ {
+ eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()");
+ umfpack_report_info(m_control.data(), m_umfpackInfo.data(), Scalar());
+ }
+
+ /** Prints the status of the previous factorization operation performed by UmfPack (symbolic or numerical factorization).
+ *
+ * \sa analyzePattern(), compute()
+ */
+ void umfpackReportStatus() {
+ eigen_assert(m_analysisIsOk && "UmfPackLU: you must first call analyzePattern()");
+ umfpack_report_status(m_control.data(), m_fact_errorCode, Scalar());
+ }
+
/** \internal */
template<typename BDerived,typename XDerived>
bool _solve_impl(const MatrixBase<BDerived> &b, MatrixBase<XDerived> &x) const;
@@ -314,41 +361,42 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
m_numeric = 0;
m_symbolic = 0;
m_extractedDataAreDirty = true;
+
+ umfpack_defaults(m_control.data(), Scalar());
}
-
+
void analyzePattern_impl()
{
- umfpack_defaults(m_control.data(), Scalar());
- int errorCode = 0;
- errorCode = umfpack_symbolic(internal::convert_index<int>(mp_matrix.rows()),
- internal::convert_index<int>(mp_matrix.cols()),
- mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(),
- &m_symbolic, m_control.data(), 0);
+ m_fact_errorCode = umfpack_symbolic(internal::convert_index<int>(mp_matrix.rows()),
+ internal::convert_index<int>(mp_matrix.cols()),
+ mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(),
+ &m_symbolic, m_control.data(), m_umfpackInfo.data());
m_isInitialized = true;
- m_info = errorCode ? InvalidInput : Success;
+ m_info = m_fact_errorCode ? InvalidInput : Success;
m_analysisIsOk = true;
m_factorizationIsOk = false;
m_extractedDataAreDirty = true;
}
-
+
void factorize_impl()
{
+
m_fact_errorCode = umfpack_numeric(mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(),
- m_symbolic, &m_numeric, m_control.data(), 0);
+ m_symbolic, &m_numeric, m_control.data(), m_umfpackInfo.data());
m_info = m_fact_errorCode == UMFPACK_OK ? Success : NumericalIssue;
m_factorizationIsOk = true;
m_extractedDataAreDirty = true;
}
-
+
template<typename MatrixDerived>
void grab(const EigenBase<MatrixDerived> &A)
{
mp_matrix.~UmfpackMatrixRef();
::new (&mp_matrix) UmfpackMatrixRef(A.derived());
}
-
+
void grab(const UmfpackMatrixRef &A)
{
if(&(A.derived()) != &mp_matrix)
@@ -357,19 +405,20 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
::new (&mp_matrix) UmfpackMatrixRef(A);
}
}
-
+
// cached data to reduce reallocation, etc.
mutable LUMatrixType m_l;
int m_fact_errorCode;
UmfpackControl m_control;
-
+ mutable UmfpackInfo m_umfpackInfo;
+
mutable LUMatrixType m_u;
mutable IntColVectorType m_p;
mutable IntRowVectorType m_q;
UmfpackMatrixType m_dummy;
UmfpackMatrixRef mp_matrix;
-
+
void* m_numeric;
void* m_symbolic;
@@ -377,7 +426,7 @@ class UmfPackLU : public SparseSolverBase<UmfPackLU<_MatrixType> >
int m_factorizationIsOk;
int m_analysisIsOk;
mutable bool m_extractedDataAreDirty;
-
+
private:
UmfPackLU(const UmfPackLU& ) { }
};
@@ -427,7 +476,7 @@ bool UmfPackLU<MatrixType>::_solve_impl(const MatrixBase<BDerived> &b, MatrixBas
eigen_assert((BDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major rhs yet");
eigen_assert((XDerived::Flags&RowMajorBit)==0 && "UmfPackLU backend does not support non col-major result yet");
eigen_assert(b.derived().data() != x.derived().data() && " Umfpack does not support inplace solve");
-
+
int errorCode;
Scalar* x_ptr = 0;
Matrix<Scalar,Dynamic,1> x_tmp;
@@ -442,7 +491,7 @@ bool UmfPackLU<MatrixType>::_solve_impl(const MatrixBase<BDerived> &b, MatrixBas
x_ptr = &x.col(j).coeffRef(0);
errorCode = umfpack_solve(UMFPACK_A,
mp_matrix.outerIndexPtr(), mp_matrix.innerIndexPtr(), mp_matrix.valuePtr(),
- x_ptr, &b.const_cast_derived().col(j).coeffRef(0), m_numeric, m_control.data(), 0);
+ x_ptr, &b.const_cast_derived().col(j).coeffRef(0), m_numeric, m_control.data(), m_umfpackInfo.data());
if(x.innerStride()!=1)
x.col(j) = x_tmp;
if (errorCode!=0)
diff --git a/xs/src/eigen/README.md b/xs/src/eigen/README.md
index f56262cca..39892c00b 100644
--- a/xs/src/eigen/README.md
+++ b/xs/src/eigen/README.md
@@ -1,5 +1,5 @@
THIS IS NOT THE COMPLETE EIGEN DISTRIBUTION. ONLY FILES NEEDED FOR COMPILING EIGEN INTO SLIC3R WERE PUT INTO THE SLIC3R SOURCE DISTRIBUTION.
-THIS DIRECTORY CONTAINS PIECES OF THE EIGEN 3.3.3 SOURCE DISTRIBUTION.
+THIS DIRECTORY CONTAINS PIECES OF THE EIGEN 3.3.5 b3f3d4950030 SOURCE DISTRIBUTION.
**Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.**
diff --git a/xs/src/libnest2d/CMakeLists.txt b/xs/src/libnest2d/CMakeLists.txt
new file mode 100644
index 000000000..f81355012
--- /dev/null
+++ b/xs/src/libnest2d/CMakeLists.txt
@@ -0,0 +1,135 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(Libnest2D)
+
+if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
+ # Update if necessary
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long ")
+endif()
+
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED)
+
+# Add our own cmake module path.
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/)
+
+option(LIBNEST2D_UNITTESTS "If enabled, googletest framework will be downloaded
+ and the provided unit tests will be included in the build." OFF)
+
+option(LIBNEST2D_BUILD_EXAMPLES "If enabled, examples will be built." OFF)
+
+set(LIBNEST2D_GEOMETRIES_BACKEND "clipper" CACHE STRING
+ "Build libnest2d with geometry classes implemented by the chosen backend.")
+
+set(LIBNEST2D_OPTIMIZER_BACKEND "nlopt" CACHE STRING
+ "Build libnest2d with optimization features implemented by the chosen backend.")
+
+set(LIBNEST2D_SRCFILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/libnest2d.hpp # Templates only
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d.h # Exports ready made types using template arguments
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/geometry_traits.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/common.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/optimizer.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/metaloop.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/rotfinder.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/placers/placer_boilerplate.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/placers/bottomleftplacer.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/placers/nfpplacer.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/geometry_traits_nfp.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/selections/selection_boilerplate.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/selections/filler.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/selections/firstfit.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/selections/djd_heuristic.hpp
+ )
+
+set(LIBNEST2D_LIBRARIES "")
+
+set(LIBNEST2D_HEADERS ${CMAKE_CURRENT_SOURCE_DIR})
+
+if(LIBNEST2D_GEOMETRIES_BACKEND STREQUAL "clipper")
+
+ # Clipper backend is not enough on its own, it still needs some functions
+ # from Boost geometry
+ if(NOT Boost_INCLUDE_DIRS_FOUND)
+ find_package(Boost 1.58 REQUIRED)
+ # TODO automatic download of boost geometry headers
+ endif()
+
+ add_subdirectory(libnest2d/clipper_backend)
+
+ include_directories(BEFORE ${CLIPPER_INCLUDE_DIRS})
+ include_directories(${Boost_INCLUDE_DIRS})
+
+ list(APPEND LIBNEST2D_SRCFILES ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/clipper_backend/clipper_backend.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/boost_alg.hpp)
+ list(APPEND LIBNEST2D_LIBRARIES ${CLIPPER_LIBRARIES})
+ list(APPEND LIBNEST2D_HEADERS ${CLIPPER_INCLUDE_DIRS}
+ ${Boost_INCLUDE_DIRS_FOUND})
+endif()
+
+if(LIBNEST2D_OPTIMIZER_BACKEND STREQUAL "nlopt")
+ find_package(NLopt 1.4)
+ if(NOT NLopt_FOUND)
+ message(STATUS "NLopt not found so downloading "
+ "and automatic build is performed...")
+ include(DownloadNLopt)
+ endif()
+ find_package(Threads REQUIRED)
+
+ list(APPEND LIBNEST2D_SRCFILES ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/optimizers/simplex.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/optimizers/subplex.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/optimizers/genetic.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/libnest2d/optimizers/nlopt_boilerplate.hpp)
+ list(APPEND LIBNEST2D_LIBRARIES ${NLopt_LIBS})
+ list(APPEND LIBNEST2D_HEADERS ${NLopt_INCLUDE_DIR})
+endif()
+
+if(LIBNEST2D_UNITTESTS)
+ enable_testing()
+ add_subdirectory(tests)
+endif()
+
+if(LIBNEST2D_BUILD_EXAMPLES)
+
+ add_executable(example examples/main.cpp
+# tools/libnfpglue.hpp
+# tools/libnfpglue.cpp
+ tools/nfp_svgnest.hpp
+ tools/nfp_svgnest_glue.hpp
+ tools/svgtools.hpp
+ tests/printer_parts.cpp
+ tests/printer_parts.h
+ ${LIBNEST2D_SRCFILES}
+ )
+ set(TBB_STATIC ON)
+ find_package(TBB QUIET)
+ if(TBB_FOUND)
+ message(STATUS "Parallelization with Intel TBB")
+ target_include_directories(example PUBLIC ${TBB_INCLUDE_DIRS})
+ target_compile_definitions(example PUBLIC ${TBB_DEFINITIONS} -DUSE_TBB)
+ if(MSVC)
+ # Suppress implicit linking of the TBB libraries by the Visual Studio compiler.
+ target_compile_definitions(example PUBLIC -D__TBB_NO_IMPLICIT_LINKAGE)
+ endif()
+ # The Intel TBB library will use the std::exception_ptr feature of C++11.
+ target_compile_definitions(example PUBLIC -DTBB_USE_CAPTURED_EXCEPTION=1)
+
+ target_link_libraries(example ${TBB_LIBRARIES})
+ else()
+ find_package(OpenMP QUIET)
+ if(OpenMP_CXX_FOUND)
+ message(STATUS "Parallelization with OpenMP")
+ target_include_directories(example PUBLIC OpenMP::OpenMP_CXX)
+ target_link_libraries(example OpenMP::OpenMP_CXX)
+ endif()
+ endif()
+
+ target_link_libraries(example ${LIBNEST2D_LIBRARIES})
+ target_include_directories(example PUBLIC ${LIBNEST2D_HEADERS})
+endif()
+
+get_directory_property(hasParent PARENT_DIRECTORY)
+if(hasParent)
+ set(LIBNEST2D_INCLUDES ${LIBNEST2D_HEADERS} PARENT_SCOPE)
+ set(LIBNEST2D_LIBRARIES ${LIBNEST2D_LIBRARIES} PARENT_SCOPE)
+endif()
diff --git a/xs/src/libnest2d/LICENSE.txt b/xs/src/libnest2d/LICENSE.txt
new file mode 100644
index 000000000..dba13ed2d
--- /dev/null
+++ b/xs/src/libnest2d/LICENSE.txt
@@ -0,0 +1,661 @@
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+ 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
+them 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.
+
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU Affero General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero 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 that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ 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
+state 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 Affero General Public License as published by
+ the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero 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 your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
diff --git a/xs/src/libnest2d/README.md b/xs/src/libnest2d/README.md
new file mode 100644
index 000000000..61a7ac7d0
--- /dev/null
+++ b/xs/src/libnest2d/README.md
@@ -0,0 +1,43 @@
+# Introduction
+
+Libnest2D is a library and framework for the 2D bin packaging problem.
+Inspired from the [SVGNest](svgnest.com) Javascript library the project is
+built from scratch in C++11. The library is written with a policy that it should
+be usable out of the box with a very simple interface but has to be customizable
+to the very core as well. The algorithms are defined in a header only fashion
+with templated geometry types. These geometries can have custom or already
+existing implementation to avoid copying or having unnecessary dependencies.
+
+A default backend is provided if the user of the library just wants to use it
+out of the box without additional integration. This backend is reasonably
+fast and robust, being built on top of boost geometry and the
+[polyclipping](http://www.angusj.com/delphi/clipper.php) library. Usage of
+this default backend implies the dependency on these packages but its header
+only as well.
+
+This software is currently under construction and lacks a throughout
+documentation and some essential algorithms as well. At this stage it works well
+for rectangles and convex closed polygons without considering holes and
+concavities.
+
+Holes and non-convex polygons will be usable in the near future as well. The
+no fit polygon based placer module combined with the first fit selection
+strategy is now used in the [Slic3r](https://github.com/prusa3d/Slic3r)
+application's arrangement feature. It uses local optimization techniques to find
+the best placement of each new item based on some features of the arrangement.
+
+In the near future I would like to use machine learning to evaluate the
+placements and (or) the order if items in which they are placed and see what
+results can be obtained. This is a different approach than that of SVGnest which
+uses genetic algorithms to find better and better selection orders. Maybe the
+two approaches can be combined as well.
+
+# References
+- [SVGNest](https://github.com/Jack000/SVGnest)
+- [An effective heuristic for the two-dimensional irregular
+bin packing problem](http://www.cs.stir.ac.uk/~goc/papers/EffectiveHueristic2DAOR2013.pdf)
+- [Complete and robust no-fit polygon generation for the irregular stock cutting problem](https://www.sciencedirect.com/science/article/abs/pii/S0377221706001639)
+- [Applying Meta-Heuristic Algorithms to the Nesting
+Problem Utilising the No Fit Polygon](http://www.graham-kendall.com/papers/k2001.pdf)
+- [A comprehensive and robust procedure for obtaining the nofit polygon
+using Minkowski sums](https://www.sciencedirect.com/science/article/pii/S0305054806000669) \ No newline at end of file
diff --git a/xs/src/libnest2d/cmake_modules/DownloadNLopt.cmake b/xs/src/libnest2d/cmake_modules/DownloadNLopt.cmake
new file mode 100644
index 000000000..0f5392596
--- /dev/null
+++ b/xs/src/libnest2d/cmake_modules/DownloadNLopt.cmake
@@ -0,0 +1,32 @@
+include(DownloadProject)
+
+if (CMAKE_VERSION VERSION_LESS 3.2)
+ set(UPDATE_DISCONNECTED_IF_AVAILABLE "")
+else()
+ set(UPDATE_DISCONNECTED_IF_AVAILABLE "UPDATE_DISCONNECTED 1")
+endif()
+
+# set(NLopt_DIR ${CMAKE_BINARY_DIR}/nlopt)
+include(DownloadProject)
+download_project( PROJ nlopt
+ GIT_REPOSITORY https://github.com/stevengj/nlopt.git
+ GIT_TAG 1fcbcbf2fe8e34234e016cc43a6c41d3e8453e1f #master #nlopt-2.4.2
+ # CMAKE_CACHE_ARGS -DBUILD_SHARED_LIBS:BOOL=OFF -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${NLopt_DIR}
+ ${UPDATE_DISCONNECTED_IF_AVAILABLE}
+)
+
+set(SHARED_LIBS_STATE BUILD_SHARED_LIBS)
+set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
+set(NLOPT_PYTHON OFF CACHE BOOL "" FORCE)
+set(NLOPT_OCTAVE OFF CACHE BOOL "" FORCE)
+set(NLOPT_MATLAB OFF CACHE BOOL "" FORCE)
+set(NLOPT_GUILE OFF CACHE BOOL "" FORCE)
+set(NLOPT_SWIG OFF CACHE BOOL "" FORCE)
+set(NLOPT_LINK_PYTHON OFF CACHE BOOL "" FORCE)
+
+add_subdirectory(${nlopt_SOURCE_DIR} ${nlopt_BINARY_DIR})
+
+set(NLopt_LIBS nlopt)
+set(NLopt_INCLUDE_DIR ${nlopt_BINARY_DIR}
+ ${nlopt_BINARY_DIR}/src/api)
+set(SHARED_LIBS_STATE ${SHARED_STATE}) \ No newline at end of file
diff --git a/xs/src/libnest2d/cmake_modules/DownloadProject.CMakeLists.cmake.in b/xs/src/libnest2d/cmake_modules/DownloadProject.CMakeLists.cmake.in
new file mode 100644
index 000000000..d5cf3c1d9
--- /dev/null
+++ b/xs/src/libnest2d/cmake_modules/DownloadProject.CMakeLists.cmake.in
@@ -0,0 +1,17 @@
+# Distributed under the OSI-approved MIT License. See accompanying
+# file LICENSE or https://github.com/Crascit/DownloadProject for details.
+
+cmake_minimum_required(VERSION 2.8.2)
+
+project(${DL_ARGS_PROJ}-download NONE)
+
+include(ExternalProject)
+ExternalProject_Add(${DL_ARGS_PROJ}-download
+ ${DL_ARGS_UNPARSED_ARGUMENTS}
+ SOURCE_DIR "${DL_ARGS_SOURCE_DIR}"
+ BINARY_DIR "${DL_ARGS_BINARY_DIR}"
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ TEST_COMMAND ""
+) \ No newline at end of file
diff --git a/xs/src/libnest2d/cmake_modules/DownloadProject.cmake b/xs/src/libnest2d/cmake_modules/DownloadProject.cmake
new file mode 100644
index 000000000..1709e09ad
--- /dev/null
+++ b/xs/src/libnest2d/cmake_modules/DownloadProject.cmake
@@ -0,0 +1,182 @@
+# Distributed under the OSI-approved MIT License. See accompanying
+# file LICENSE or https://github.com/Crascit/DownloadProject for details.
+#
+# MODULE: DownloadProject
+#
+# PROVIDES:
+# download_project( PROJ projectName
+# [PREFIX prefixDir]
+# [DOWNLOAD_DIR downloadDir]
+# [SOURCE_DIR srcDir]
+# [BINARY_DIR binDir]
+# [QUIET]
+# ...
+# )
+#
+# Provides the ability to download and unpack a tarball, zip file, git repository,
+# etc. at configure time (i.e. when the cmake command is run). How the downloaded
+# and unpacked contents are used is up to the caller, but the motivating case is
+# to download source code which can then be included directly in the build with
+# add_subdirectory() after the call to download_project(). Source and build
+# directories are set up with this in mind.
+#
+# The PROJ argument is required. The projectName value will be used to construct
+# the following variables upon exit (obviously replace projectName with its actual
+# value):
+#
+# projectName_SOURCE_DIR
+# projectName_BINARY_DIR
+#
+# The SOURCE_DIR and BINARY_DIR arguments are optional and would not typically
+# need to be provided. They can be specified if you want the downloaded source
+# and build directories to be located in a specific place. The contents of
+# projectName_SOURCE_DIR and projectName_BINARY_DIR will be populated with the
+# locations used whether you provide SOURCE_DIR/BINARY_DIR or not.
+#
+# The DOWNLOAD_DIR argument does not normally need to be set. It controls the
+# location of the temporary CMake build used to perform the download.
+#
+# The PREFIX argument can be provided to change the base location of the default
+# values of DOWNLOAD_DIR, SOURCE_DIR and BINARY_DIR. If all of those three arguments
+# are provided, then PREFIX will have no effect. The default value for PREFIX is
+# CMAKE_BINARY_DIR.
+#
+# The QUIET option can be given if you do not want to show the output associated
+# with downloading the specified project.
+#
+# In addition to the above, any other options are passed through unmodified to
+# ExternalProject_Add() to perform the actual download, patch and update steps.
+# The following ExternalProject_Add() options are explicitly prohibited (they
+# are reserved for use by the download_project() command):
+#
+# CONFIGURE_COMMAND
+# BUILD_COMMAND
+# INSTALL_COMMAND
+# TEST_COMMAND
+#
+# Only those ExternalProject_Add() arguments which relate to downloading, patching
+# and updating of the project sources are intended to be used. Also note that at
+# least one set of download-related arguments are required.
+#
+# If using CMake 3.2 or later, the UPDATE_DISCONNECTED option can be used to
+# prevent a check at the remote end for changes every time CMake is run
+# after the first successful download. See the documentation of the ExternalProject
+# module for more information. It is likely you will want to use this option if it
+# is available to you. Note, however, that the ExternalProject implementation contains
+# bugs which result in incorrect handling of the UPDATE_DISCONNECTED option when
+# using the URL download method or when specifying a SOURCE_DIR with no download
+# method. Fixes for these have been created, the last of which is scheduled for
+# inclusion in CMake 3.8.0. Details can be found here:
+#
+# https://gitlab.kitware.com/cmake/cmake/commit/bdca68388bd57f8302d3c1d83d691034b7ffa70c
+# https://gitlab.kitware.com/cmake/cmake/issues/16428
+#
+# If you experience build errors related to the update step, consider avoiding
+# the use of UPDATE_DISCONNECTED.
+#
+# EXAMPLE USAGE:
+#
+# include(DownloadProject)
+# download_project(PROJ googletest
+# GIT_REPOSITORY https://github.com/google/googletest.git
+# GIT_TAG master
+# UPDATE_DISCONNECTED 1
+# QUIET
+# )
+#
+# add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
+#
+#========================================================================================
+
+
+set(_DownloadProjectDir "${CMAKE_CURRENT_LIST_DIR}")
+
+include(CMakeParseArguments)
+
+function(download_project)
+
+ set(options QUIET)
+ set(oneValueArgs
+ PROJ
+ PREFIX
+ DOWNLOAD_DIR
+ SOURCE_DIR
+ BINARY_DIR
+ # Prevent the following from being passed through
+ CONFIGURE_COMMAND
+ BUILD_COMMAND
+ INSTALL_COMMAND
+ TEST_COMMAND
+ )
+ set(multiValueArgs "")
+
+ cmake_parse_arguments(DL_ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ # Hide output if requested
+ if (DL_ARGS_QUIET)
+ set(OUTPUT_QUIET "OUTPUT_QUIET")
+ else()
+ unset(OUTPUT_QUIET)
+ message(STATUS "Downloading/updating ${DL_ARGS_PROJ}")
+ endif()
+
+ # Set up where we will put our temporary CMakeLists.txt file and also
+ # the base point below which the default source and binary dirs will be.
+ # The prefix must always be an absolute path.
+ if (NOT DL_ARGS_PREFIX)
+ set(DL_ARGS_PREFIX "${CMAKE_BINARY_DIR}")
+ else()
+ get_filename_component(DL_ARGS_PREFIX "${DL_ARGS_PREFIX}" ABSOLUTE
+ BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
+ if (NOT DL_ARGS_DOWNLOAD_DIR)
+ set(DL_ARGS_DOWNLOAD_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-download")
+ endif()
+
+ # Ensure the caller can know where to find the source and build directories
+ if (NOT DL_ARGS_SOURCE_DIR)
+ set(DL_ARGS_SOURCE_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-src")
+ endif()
+ if (NOT DL_ARGS_BINARY_DIR)
+ set(DL_ARGS_BINARY_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-build")
+ endif()
+ set(${DL_ARGS_PROJ}_SOURCE_DIR "${DL_ARGS_SOURCE_DIR}" PARENT_SCOPE)
+ set(${DL_ARGS_PROJ}_BINARY_DIR "${DL_ARGS_BINARY_DIR}" PARENT_SCOPE)
+
+ # The way that CLion manages multiple configurations, it causes a copy of
+ # the CMakeCache.txt to be copied across due to it not expecting there to
+ # be a project within a project. This causes the hard-coded paths in the
+ # cache to be copied and builds to fail. To mitigate this, we simply
+ # remove the cache if it exists before we configure the new project. It
+ # is safe to do so because it will be re-generated. Since this is only
+ # executed at the configure step, it should not cause additional builds or
+ # downloads.
+ file(REMOVE "${DL_ARGS_DOWNLOAD_DIR}/CMakeCache.txt")
+
+ # Create and build a separate CMake project to carry out the download.
+ # If we've already previously done these steps, they will not cause
+ # anything to be updated, so extra rebuilds of the project won't occur.
+ # Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project
+ # has this set to something not findable on the PATH.
+ configure_file("${_DownloadProjectDir}/DownloadProject.CMakeLists.cmake.in"
+ "${DL_ARGS_DOWNLOAD_DIR}/CMakeLists.txt")
+ execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
+ -D "CMAKE_MAKE_PROGRAM:FILE=${CMAKE_MAKE_PROGRAM}"
+ .
+ RESULT_VARIABLE result
+ ${OUTPUT_QUIET}
+ WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}"
+ )
+ if(result)
+ message(FATAL_ERROR "CMake step for ${DL_ARGS_PROJ} failed: ${result}")
+ endif()
+ execute_process(COMMAND ${CMAKE_COMMAND} --build .
+ RESULT_VARIABLE result
+ ${OUTPUT_QUIET}
+ WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}"
+ )
+ if(result)
+ message(FATAL_ERROR "Build step for ${DL_ARGS_PROJ} failed: ${result}")
+ endif()
+
+endfunction() \ No newline at end of file
diff --git a/xs/src/libnest2d/cmake_modules/FindClipper.cmake b/xs/src/libnest2d/cmake_modules/FindClipper.cmake
new file mode 100644
index 000000000..f6b973440
--- /dev/null
+++ b/xs/src/libnest2d/cmake_modules/FindClipper.cmake
@@ -0,0 +1,50 @@
+# Find Clipper library (http://www.angusj.com/delphi/clipper.php).
+# The following variables are set
+#
+# CLIPPER_FOUND
+# CLIPPER_INCLUDE_DIRS
+# CLIPPER_LIBRARIES
+#
+# It searches the environment variable $CLIPPER_PATH automatically.
+
+FIND_PATH(CLIPPER_INCLUDE_DIRS clipper.hpp
+ $ENV{CLIPPER_PATH}
+ $ENV{CLIPPER_PATH}/cpp/
+ $ENV{CLIPPER_PATH}/include/
+ $ENV{CLIPPER_PATH}/include/polyclipping/
+ ${PROJECT_SOURCE_DIR}/python/pymesh/third_party/include/
+ ${PROJECT_SOURCE_DIR}/python/pymesh/third_party/include/polyclipping/
+ ${CMAKE_PREFIX_PATH}/include/polyclipping
+ ${CMAKE_PREFIX_PATH}/include/
+ /opt/local/include/
+ /opt/local/include/polyclipping/
+ /usr/local/include/
+ /usr/local/include/polyclipping/
+ /usr/include
+ /usr/include/polyclipping/)
+
+FIND_LIBRARY(CLIPPER_LIBRARIES polyclipping
+ $ENV{CLIPPER_PATH}
+ $ENV{CLIPPER_PATH}/cpp/
+ $ENV{CLIPPER_PATH}/cpp/build/
+ $ENV{CLIPPER_PATH}/lib/
+ $ENV{CLIPPER_PATH}/lib/polyclipping/
+ ${PROJECT_SOURCE_DIR}/python/pymesh/third_party/lib/
+ ${PROJECT_SOURCE_DIR}/python/pymesh/third_party/lib/polyclipping/
+ ${CMAKE_PREFIX_PATH}/lib/
+ ${CMAKE_PREFIX_PATH}/lib/polyclipping/
+ /opt/local/lib/
+ /opt/local/lib/polyclipping/
+ /usr/local/lib/
+ /usr/local/lib/polyclipping/
+ /usr/lib/polyclipping)
+
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Clipper
+ "Clipper library cannot be found. Consider set CLIPPER_PATH environment variable"
+ CLIPPER_INCLUDE_DIRS
+ CLIPPER_LIBRARIES)
+
+MARK_AS_ADVANCED(
+ CLIPPER_INCLUDE_DIRS
+ CLIPPER_LIBRARIES) \ No newline at end of file
diff --git a/xs/src/libnest2d/cmake_modules/FindNLopt.cmake b/xs/src/libnest2d/cmake_modules/FindNLopt.cmake
new file mode 100644
index 000000000..4b93be7b6
--- /dev/null
+++ b/xs/src/libnest2d/cmake_modules/FindNLopt.cmake
@@ -0,0 +1,125 @@
+#///////////////////////////////////////////////////////////////////////////
+#//-------------------------------------------------------------------------
+#//
+#// Description:
+#// cmake module for finding NLopt installation
+#// NLopt installation location is defined by environment variable $NLOPT
+#//
+#// following variables are defined:
+#// NLopt_DIR - NLopt installation directory
+#// NLopt_INCLUDE_DIR - NLopt header directory
+#// NLopt_LIBRARY_DIR - NLopt library directory
+#// NLopt_LIBS - NLopt library files
+#//
+#// Example usage:
+#// find_package(NLopt 1.4 REQUIRED)
+#//
+#//
+#//-------------------------------------------------------------------------
+
+
+set(NLopt_FOUND FALSE)
+set(NLopt_ERROR_REASON "")
+set(NLopt_DEFINITIONS "")
+set(NLopt_LIBS)
+
+
+set(NLopt_DIR $ENV{NLOPT})
+if(NOT NLopt_DIR)
+
+ set(NLopt_FOUND TRUE)
+
+ set(_NLopt_LIB_NAMES "nlopt")
+ find_library(NLopt_LIBS
+ NAMES ${_NLopt_LIB_NAMES})
+ if(NOT NLopt_LIBS)
+ set(NLopt_FOUND FALSE)
+ set(NLopt_ERROR_REASON "${NLopt_ERROR_REASON} Cannot find NLopt library '${_NLopt_LIB_NAMES}'.")
+ else()
+ get_filename_component(NLopt_DIR ${NLopt_LIBS} PATH)
+ endif()
+ unset(_NLopt_LIB_NAMES)
+
+ set(_NLopt_HEADER_FILE_NAME "nlopt.hpp")
+ find_file(_NLopt_HEADER_FILE
+ NAMES ${_NLopt_HEADER_FILE_NAME})
+ if(NOT _NLopt_HEADER_FILE)
+ set(NLopt_FOUND FALSE)
+ set(NLopt_ERROR_REASON "${NLopt_ERROR_REASON} Cannot find NLopt header file '${_NLopt_HEADER_FILE_NAME}'.")
+ endif()
+ unset(_NLopt_HEADER_FILE_NAME)
+ unset(_NLopt_HEADER_FILE)
+
+ if(NOT NLopt_FOUND)
+ set(NLopt_ERROR_REASON "${NLopt_ERROR_REASON} NLopt not found in system directories (and environment variable NLOPT is not set).")
+ else()
+ get_filename_component(NLopt_INCLUDE_DIR ${_NLopt_HEADER_FILE} DIRECTORY )
+ endif()
+
+
+
+else()
+
+ set(NLopt_FOUND TRUE)
+
+ set(NLopt_INCLUDE_DIR "${NLopt_DIR}/include")
+ if(NOT EXISTS "${NLopt_INCLUDE_DIR}")
+ set(NLopt_FOUND FALSE)
+ set(NLopt_ERROR_REASON "${NLopt_ERROR_REASON} Directory '${NLopt_INCLUDE_DIR}' does not exist.")
+ endif()
+
+ set(NLopt_LIBRARY_DIR "${NLopt_DIR}/lib")
+ if(NOT EXISTS "${NLopt_LIBRARY_DIR}")
+ set(NLopt_FOUND FALSE)
+ set(NLopt_ERROR_REASON "${NLopt_ERROR_REASON} Directory '${NLopt_LIBRARY_DIR}' does not exist.")
+ endif()
+
+ set(_NLopt_LIB_NAMES "nlopt_cxx")
+ find_library(NLopt_LIBS
+ NAMES ${_NLopt_LIB_NAMES}
+ PATHS ${NLopt_LIBRARY_DIR}
+ NO_DEFAULT_PATH)
+ if(NOT NLopt_LIBS)
+ set(NLopt_FOUND FALSE)
+ set(NLopt_ERROR_REASON "${NLopt_ERROR_REASON} Cannot find NLopt library '${_NLopt_LIB_NAMES}' in '${NLopt_LIBRARY_DIR}'.")
+ endif()
+ unset(_NLopt_LIB_NAMES)
+
+ set(_NLopt_HEADER_FILE_NAME "nlopt.hpp")
+ find_file(_NLopt_HEADER_FILE
+ NAMES ${_NLopt_HEADER_FILE_NAME}
+ PATHS ${NLopt_INCLUDE_DIR}
+ NO_DEFAULT_PATH)
+ if(NOT _NLopt_HEADER_FILE)
+ set(NLopt_FOUND FALSE)
+ set(NLopt_ERROR_REASON "${NLopt_ERROR_REASON} Cannot find NLopt header file '${_NLopt_HEADER_FILE_NAME}' in '${NLopt_INCLUDE_DIR}'.")
+ endif()
+ unset(_NLopt_HEADER_FILE_NAME)
+ unset(_NLopt_HEADER_FILE)
+
+endif()
+
+
+# make variables changeable
+mark_as_advanced(
+ NLopt_INCLUDE_DIR
+ NLopt_LIBRARY_DIR
+ NLopt_LIBS
+ NLopt_DEFINITIONS
+ )
+
+
+# report result
+if(NLopt_FOUND)
+ message(STATUS "Found NLopt in '${NLopt_DIR}'.")
+ message(STATUS "Using NLopt include directory '${NLopt_INCLUDE_DIR}'.")
+ message(STATUS "Using NLopt library '${NLopt_LIBS}'.")
+else()
+ if(NLopt_FIND_REQUIRED)
+ message(FATAL_ERROR "Unable to find requested NLopt installation:${NLopt_ERROR_REASON}")
+ else()
+ if(NOT NLopt_FIND_QUIETLY)
+ message(STATUS "NLopt was not found:${NLopt_ERROR_REASON}")
+ endif()
+ endif()
+endif() \ No newline at end of file
diff --git a/xs/src/libnest2d/cmake_modules/FindTBB.cmake b/xs/src/libnest2d/cmake_modules/FindTBB.cmake
new file mode 100644
index 000000000..8b498d3ab
--- /dev/null
+++ b/xs/src/libnest2d/cmake_modules/FindTBB.cmake
@@ -0,0 +1,322 @@
+# The MIT License (MIT)
+#
+# Copyright (c) 2015 Justus Calvin
+#
+# 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.
+
+#
+# FindTBB
+# -------
+#
+# Find TBB include directories and libraries.
+#
+# Usage:
+#
+# find_package(TBB [major[.minor]] [EXACT]
+# [QUIET] [REQUIRED]
+# [[COMPONENTS] [components...]]
+# [OPTIONAL_COMPONENTS components...])
+#
+# where the allowed components are tbbmalloc and tbb_preview. Users may modify
+# the behavior of this module with the following variables:
+#
+# * TBB_ROOT_DIR - The base directory the of TBB installation.
+# * TBB_INCLUDE_DIR - The directory that contains the TBB headers files.
+# * TBB_LIBRARY - The directory that contains the TBB library files.
+# * TBB_<library>_LIBRARY - The path of the TBB the corresponding TBB library.
+# These libraries, if specified, override the
+# corresponding library search results, where <library>
+# may be tbb, tbb_debug, tbbmalloc, tbbmalloc_debug,
+# tbb_preview, or tbb_preview_debug.
+# * TBB_USE_DEBUG_BUILD - The debug version of tbb libraries, if present, will
+# be used instead of the release version.
+# * TBB_STATIC - Static linking of libraries with a _static suffix.
+# For example, on Windows a tbb_static.lib will be searched for
+# instead of tbb.lib.
+#
+# Users may modify the behavior of this module with the following environment
+# variables:
+#
+# * TBB_INSTALL_DIR
+# * TBBROOT
+# * LIBRARY_PATH
+#
+# This module will set the following variables:
+#
+# * TBB_FOUND - Set to false, or undefined, if we haven’t found, or
+# don’t want to use TBB.
+# * TBB_<component>_FOUND - If False, optional <component> part of TBB sytem is
+# not available.
+# * TBB_VERSION - The full version string
+# * TBB_VERSION_MAJOR - The major version
+# * TBB_VERSION_MINOR - The minor version
+# * TBB_INTERFACE_VERSION - The interface version number defined in
+# tbb/tbb_stddef.h.
+# * TBB_<library>_LIBRARY_RELEASE - The path of the TBB release version of
+# <library>, where <library> may be tbb, tbb_debug,
+# tbbmalloc, tbbmalloc_debug, tbb_preview, or
+# tbb_preview_debug.
+# * TBB_<library>_LIBRARY_DEGUG - The path of the TBB release version of
+# <library>, where <library> may be tbb, tbb_debug,
+# tbbmalloc, tbbmalloc_debug, tbb_preview, or
+# tbb_preview_debug.
+#
+# The following varibles should be used to build and link with TBB:
+#
+# * TBB_INCLUDE_DIRS - The include directory for TBB.
+# * TBB_LIBRARIES - The libraries to link against to use TBB.
+# * TBB_LIBRARIES_RELEASE - The release libraries to link against to use TBB.
+# * TBB_LIBRARIES_DEBUG - The debug libraries to link against to use TBB.
+# * TBB_DEFINITIONS - Definitions to use when compiling code that uses
+# TBB.
+# * TBB_DEFINITIONS_RELEASE - Definitions to use when compiling release code that
+# uses TBB.
+# * TBB_DEFINITIONS_DEBUG - Definitions to use when compiling debug code that
+# uses TBB.
+#
+# This module will also create the "tbb" target that may be used when building
+# executables and libraries.
+
+include(FindPackageHandleStandardArgs)
+
+if(NOT TBB_FOUND)
+
+ ##################################
+ # Check the build type
+ ##################################
+
+ if(NOT DEFINED TBB_USE_DEBUG_BUILD)
+ if(CMAKE_BUILD_TYPE MATCHES "(Debug|DEBUG|debug)")
+ set(TBB_BUILD_TYPE DEBUG)
+ else()
+ set(TBB_BUILD_TYPE RELEASE)
+ endif()
+ elseif(TBB_USE_DEBUG_BUILD)
+ set(TBB_BUILD_TYPE DEBUG)
+ else()
+ set(TBB_BUILD_TYPE RELEASE)
+ endif()
+
+ ##################################
+ # Set the TBB search directories
+ ##################################
+
+ # Define search paths based on user input and environment variables
+ set(TBB_SEARCH_DIR ${TBB_ROOT_DIR} $ENV{TBB_INSTALL_DIR} $ENV{TBBROOT})
+
+ # Define the search directories based on the current platform
+ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ set(TBB_DEFAULT_SEARCH_DIR "C:/Program Files/Intel/TBB"
+ "C:/Program Files (x86)/Intel/TBB")
+
+ # Set the target architecture
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(TBB_ARCHITECTURE "intel64")
+ else()
+ set(TBB_ARCHITECTURE "ia32")
+ endif()
+
+ # Set the TBB search library path search suffix based on the version of VC
+ if(WINDOWS_STORE)
+ set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11_ui")
+ elseif(MSVC14)
+ set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc14")
+ elseif(MSVC12)
+ set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc12")
+ elseif(MSVC11)
+ set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11")
+ elseif(MSVC10)
+ set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc10")
+ endif()
+
+ # Add the library path search suffix for the VC independent version of TBB
+ list(APPEND TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc_mt")
+
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ # OS X
+ set(TBB_DEFAULT_SEARCH_DIR "/opt/intel/tbb")
+
+ # TODO: Check to see which C++ library is being used by the compiler.
+ if(NOT ${CMAKE_SYSTEM_VERSION} VERSION_LESS 13.0)
+ # The default C++ library on OS X 10.9 and later is libc++
+ set(TBB_LIB_PATH_SUFFIX "lib/libc++" "lib")
+ else()
+ set(TBB_LIB_PATH_SUFFIX "lib")
+ endif()
+ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ # Linux
+ set(TBB_DEFAULT_SEARCH_DIR "/opt/intel/tbb")
+
+ # TODO: Check compiler version to see the suffix should be <arch>/gcc4.1 or
+ # <arch>/gcc4.1. For now, assume that the compiler is more recent than
+ # gcc 4.4.x or later.
+ if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ set(TBB_LIB_PATH_SUFFIX "lib/intel64/gcc4.4")
+ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
+ set(TBB_LIB_PATH_SUFFIX "lib/ia32/gcc4.4")
+ endif()
+ endif()
+
+ ##################################
+ # Find the TBB include dir
+ ##################################
+
+ find_path(TBB_INCLUDE_DIRS tbb/tbb.h
+ HINTS ${TBB_INCLUDE_DIR} ${TBB_SEARCH_DIR}
+ PATHS ${TBB_DEFAULT_SEARCH_DIR}
+ PATH_SUFFIXES include)
+
+ ##################################
+ # Set version strings
+ ##################################
+
+ if(TBB_INCLUDE_DIRS)
+ file(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _tbb_version_file)
+ string(REGEX REPLACE ".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1"
+ TBB_VERSION_MAJOR "${_tbb_version_file}")
+ string(REGEX REPLACE ".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1"
+ TBB_VERSION_MINOR "${_tbb_version_file}")
+ string(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1"
+ TBB_INTERFACE_VERSION "${_tbb_version_file}")
+ set(TBB_VERSION "${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR}")
+ endif()
+
+ ##################################
+ # Find TBB components
+ ##################################
+
+ if(TBB_VERSION VERSION_LESS 4.3)
+ set(TBB_SEARCH_COMPOMPONENTS tbb_preview tbbmalloc tbb)
+ else()
+ set(TBB_SEARCH_COMPOMPONENTS tbb_preview tbbmalloc_proxy tbbmalloc tbb)
+ endif()
+
+ if(TBB_STATIC)
+ set(TBB_STATIC_SUFFIX "_static")
+ endif()
+
+ # Find each component
+ foreach(_comp ${TBB_SEARCH_COMPOMPONENTS})
+ if(";${TBB_FIND_COMPONENTS};tbb;" MATCHES ";${_comp};")
+
+ # Search for the libraries
+ find_library(TBB_${_comp}_LIBRARY_RELEASE ${_comp}${TBB_STATIC_SUFFIX}
+ HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR}
+ PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH
+ PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX})
+
+ find_library(TBB_${_comp}_LIBRARY_DEBUG ${_comp}${TBB_STATIC_SUFFIX}_debug
+ HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR}
+ PATHS ${TBB_DEFAULT_SEARCH_DIR} ENV LIBRARY_PATH
+ PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX})
+
+ if(TBB_${_comp}_LIBRARY_DEBUG)
+ list(APPEND TBB_LIBRARIES_DEBUG "${TBB_${_comp}_LIBRARY_DEBUG}")
+ endif()
+ if(TBB_${_comp}_LIBRARY_RELEASE)
+ list(APPEND TBB_LIBRARIES_RELEASE "${TBB_${_comp}_LIBRARY_RELEASE}")
+ endif()
+ if(TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE} AND NOT TBB_${_comp}_LIBRARY)
+ set(TBB_${_comp}_LIBRARY "${TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE}}")
+ endif()
+
+ if(TBB_${_comp}_LIBRARY AND EXISTS "${TBB_${_comp}_LIBRARY}")
+ set(TBB_${_comp}_FOUND TRUE)
+ else()
+ set(TBB_${_comp}_FOUND FALSE)
+ endif()
+
+ # Mark internal variables as advanced
+ mark_as_advanced(TBB_${_comp}_LIBRARY_RELEASE)
+ mark_as_advanced(TBB_${_comp}_LIBRARY_DEBUG)
+ mark_as_advanced(TBB_${_comp}_LIBRARY)
+
+ endif()
+ endforeach()
+
+ unset(TBB_STATIC_SUFFIX)
+
+ ##################################
+ # Set compile flags and libraries
+ ##################################
+
+ set(TBB_DEFINITIONS_RELEASE "")
+ set(TBB_DEFINITIONS_DEBUG "-DTBB_USE_DEBUG=1")
+
+ if(TBB_LIBRARIES_${TBB_BUILD_TYPE})
+ set(TBB_DEFINITIONS "${TBB_DEFINITIONS_${TBB_BUILD_TYPE}}")
+ set(TBB_LIBRARIES "${TBB_LIBRARIES_${TBB_BUILD_TYPE}}")
+ elseif(TBB_LIBRARIES_RELEASE)
+ set(TBB_DEFINITIONS "${TBB_DEFINITIONS_RELEASE}")
+ set(TBB_LIBRARIES "${TBB_LIBRARIES_RELEASE}")
+ elseif(TBB_LIBRARIES_DEBUG)
+ set(TBB_DEFINITIONS "${TBB_DEFINITIONS_DEBUG}")
+ set(TBB_LIBRARIES "${TBB_LIBRARIES_DEBUG}")
+ endif()
+
+ find_package_handle_standard_args(TBB
+ REQUIRED_VARS TBB_INCLUDE_DIRS TBB_LIBRARIES
+ HANDLE_COMPONENTS
+ VERSION_VAR TBB_VERSION)
+
+ ##################################
+ # Create targets
+ ##################################
+
+ if(NOT CMAKE_VERSION VERSION_LESS 3.0 AND TBB_FOUND)
+ add_library(tbb SHARED IMPORTED)
+ set_target_properties(tbb PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES ${TBB_INCLUDE_DIRS}
+ IMPORTED_LOCATION ${TBB_LIBRARIES})
+ if(TBB_LIBRARIES_RELEASE AND TBB_LIBRARIES_DEBUG)
+ set_target_properties(tbb PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:TBB_USE_DEBUG=1>"
+ IMPORTED_LOCATION_DEBUG ${TBB_LIBRARIES_DEBUG}
+ IMPORTED_LOCATION_RELWITHDEBINFO ${TBB_LIBRARIES_DEBUG}
+ IMPORTED_LOCATION_RELEASE ${TBB_LIBRARIES_RELEASE}
+ IMPORTED_LOCATION_MINSIZEREL ${TBB_LIBRARIES_RELEASE}
+ )
+ elseif(TBB_LIBRARIES_RELEASE)
+ set_target_properties(tbb PROPERTIES IMPORTED_LOCATION ${TBB_LIBRARIES_RELEASE})
+ else()
+ set_target_properties(tbb PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "${TBB_DEFINITIONS_DEBUG}"
+ IMPORTED_LOCATION ${TBB_LIBRARIES_DEBUG}
+ )
+ endif()
+ endif()
+
+ mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARIES)
+
+ unset(TBB_ARCHITECTURE)
+ unset(TBB_BUILD_TYPE)
+ unset(TBB_LIB_PATH_SUFFIX)
+ unset(TBB_DEFAULT_SEARCH_DIR)
+
+ if(TBB_DEBUG)
+ message(STATUS " TBB_INCLUDE_DIRS = ${TBB_INCLUDE_DIRS}")
+ message(STATUS " TBB_DEFINITIONS = ${TBB_DEFINITIONS}")
+ message(STATUS " TBB_LIBRARIES = ${TBB_LIBRARIES}")
+ message(STATUS " TBB_DEFINITIONS_DEBUG = ${TBB_DEFINITIONS_DEBUG}")
+ message(STATUS " TBB_LIBRARIES_DEBUG = ${TBB_LIBRARIES_DEBUG}")
+ message(STATUS " TBB_DEFINITIONS_RELEASE = ${TBB_DEFINITIONS_RELEASE}")
+ message(STATUS " TBB_LIBRARIES_RELEASE = ${TBB_LIBRARIES_RELEASE}")
+ endif()
+
+endif()
diff --git a/xs/src/libnest2d/examples/main.cpp b/xs/src/libnest2d/examples/main.cpp
new file mode 100644
index 000000000..ebc3fb15c
--- /dev/null
+++ b/xs/src/libnest2d/examples/main.cpp
@@ -0,0 +1,218 @@
+#include <iostream>
+#include <string>
+#include <fstream>
+//#define DEBUG_EXPORT_NFP
+
+#include <libnest2d.h>
+
+#include "tests/printer_parts.h"
+#include "tools/benchmark.h"
+#include "tools/svgtools.hpp"
+#include "libnest2d/rotfinder.hpp"
+
+//#include "tools/libnfpglue.hpp"
+//#include "tools/nfp_svgnest_glue.hpp"
+
+
+using namespace libnest2d;
+using ItemGroup = std::vector<std::reference_wrapper<Item>>;
+
+std::vector<Item>& _parts(std::vector<Item>& ret, const TestData& data)
+{
+ if(ret.empty()) {
+ ret.reserve(data.size());
+ for(auto& inp : data)
+ ret.emplace_back(inp);
+ }
+
+ return ret;
+}
+
+std::vector<Item>& prusaParts() {
+ static std::vector<Item> ret;
+ return _parts(ret, PRINTER_PART_POLYGONS);
+}
+
+std::vector<Item>& stegoParts() {
+ static std::vector<Item> ret;
+ return _parts(ret, STEGOSAUR_POLYGONS);
+}
+
+std::vector<Item>& prusaExParts() {
+ static std::vector<Item> ret;
+ if(ret.empty()) {
+ ret.reserve(PRINTER_PART_POLYGONS_EX.size());
+ for(auto& p : PRINTER_PART_POLYGONS_EX) {
+ ret.emplace_back(p.Contour, p.Holes);
+ }
+ }
+ return ret;
+}
+
+void arrangeRectangles() {
+ using namespace libnest2d;
+
+ const int SCALE = 1000000;
+
+ std::vector<Item> rects(202, {
+ {-9945219, -3065619},
+ {-9781479, -2031780},
+ {-9510560, -1020730},
+ {-9135450, -43529},
+ {-2099999, 14110899},
+ {2099999, 14110899},
+ {9135450, -43529},
+ {9510560, -1020730},
+ {9781479, -2031780},
+ {9945219, -3065619},
+ {10000000, -4110899},
+ {9945219, -5156179},
+ {9781479, -6190019},
+ {9510560, -7201069},
+ {9135450, -8178270},
+ {8660249, -9110899},
+ {8090169, -9988750},
+ {7431449, -10802209},
+ {6691309, -11542349},
+ {5877850, -12201069},
+ {5000000, -12771149},
+ {4067369, -13246350},
+ {3090169, -13621459},
+ {2079119, -13892379},
+ {1045279, -14056119},
+ {0, -14110899},
+ {-1045279, -14056119},
+ {-2079119, -13892379},
+ {-3090169, -13621459},
+ {-4067369, -13246350},
+ {-5000000, -12771149},
+ {-5877850, -12201069},
+ {-6691309, -11542349},
+ {-7431449, -10802209},
+ {-8090169, -9988750},
+ {-8660249, -9110899},
+ {-9135450, -8178270},
+ {-9510560, -7201069},
+ {-9781479, -6190019},
+ {-9945219, -5156179},
+ {-10000000, -4110899},
+ {-9945219, -3065619},
+ });
+
+ std::vector<Item> input;
+ input.insert(input.end(), prusaParts().begin(), prusaParts().end());
+// input.insert(input.end(), prusaExParts().begin(), prusaExParts().end());
+// input.insert(input.end(), stegoParts().begin(), stegoParts().end());
+// input.insert(input.end(), rects.begin(), rects.end());
+
+ Box bin(250*SCALE, 210*SCALE);
+// PolygonImpl bin = {
+// {
+// {25*SCALE, 0},
+// {0, 25*SCALE},
+// {0, 225*SCALE},
+// {25*SCALE, 250*SCALE},
+// {225*SCALE, 250*SCALE},
+// {250*SCALE, 225*SCALE},
+// {250*SCALE, 25*SCALE},
+// {225*SCALE, 0},
+// {25*SCALE, 0}
+// },
+// {}
+// };
+
+// Circle bin({0, 0}, 125*SCALE);
+
+ auto min_obj_distance = static_cast<Coord>(6*SCALE);
+
+ using Placer = placers::_NofitPolyPlacer<PolygonImpl, decltype(bin)>;
+ using Packer = Nester<Placer, FirstFitSelection>;
+
+ Packer arrange(bin, min_obj_distance);
+
+ Packer::PlacementConfig pconf;
+ pconf.alignment = Placer::Config::Alignment::CENTER;
+ pconf.starting_point = Placer::Config::Alignment::CENTER;
+ pconf.rotations = {0.0/*, Pi/2.0, Pi, 3*Pi/2*/};
+ pconf.accuracy = 0.65f;
+ pconf.parallel = true;
+
+ Packer::SelectionConfig sconf;
+// sconf.allow_parallel = false;
+// sconf.force_parallel = false;
+// sconf.try_triplets = true;
+// sconf.try_reverse_order = true;
+// sconf.waste_increment = 0.01;
+
+ arrange.configure(pconf, sconf);
+
+ arrange.progressIndicator([&](unsigned r){
+ std::cout << "Remaining items: " << r << std::endl;
+ });
+
+// findMinimumBoundingBoxRotations(input.begin(), input.end());
+
+ Benchmark bench;
+
+ bench.start();
+ Packer::ResultType result;
+
+ try {
+ result = arrange.execute(input.begin(), input.end());
+ } catch(GeometryException& ge) {
+ std::cerr << "Geometry error: " << ge.what() << std::endl;
+ return ;
+ } catch(std::exception& e) {
+ std::cerr << "Exception: " << e.what() << std::endl;
+ return ;
+ }
+
+ bench.stop();
+
+ std::vector<double> eff;
+ eff.reserve(result.size());
+
+ auto bin_area = sl::area(bin);
+ for(auto& r : result) {
+ double a = 0;
+ std::for_each(r.begin(), r.end(), [&a] (Item& e ){ a += e.area(); });
+ eff.emplace_back(a/bin_area);
+ };
+
+ std::cout << bench.getElapsedSec() << " bin count: " << result.size()
+ << std::endl;
+
+ std::cout << "Bin efficiency: (";
+ for(double e : eff) std::cout << e*100.0 << "% ";
+ std::cout << ") Average: "
+ << std::accumulate(eff.begin(), eff.end(), 0.0)*100.0/result.size()
+ << " %" << std::endl;
+
+ std::cout << "Bin usage: (";
+ size_t total = 0;
+ for(auto& r : result) { std::cout << r.size() << " "; total += r.size(); }
+ std::cout << ") Total: " << total << std::endl;
+
+// for(auto& it : input) {
+// auto ret = sl::isValid(it.transformedShape());
+// std::cout << ret.second << std::endl;
+// }
+
+ if(total != input.size()) std::cout << "ERROR " << "could not pack "
+ << input.size() - total << " elements!"
+ << std::endl;
+
+ using SVGWriter = svg::SVGWriter<PolygonImpl>;
+
+ SVGWriter::Config conf;
+ conf.mm_in_coord_units = SCALE;
+ SVGWriter svgw(conf);
+ svgw.setSize(Box(250*SCALE, 210*SCALE));
+ svgw.writePackGroup(result);
+ svgw.save("out");
+}
+
+int main(void /*int argc, char **argv*/) {
+ arrangeRectangles();
+ return EXIT_SUCCESS;
+}
diff --git a/xs/src/libnest2d/libnest2d.h b/xs/src/libnest2d/libnest2d.h
new file mode 100644
index 000000000..bfd88f4f5
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d.h
@@ -0,0 +1,42 @@
+#ifndef LIBNEST2D_H
+#define LIBNEST2D_H
+
+// The type of backend should be set conditionally by the cmake configuriation
+// for now we set it statically to clipper backend
+#include <libnest2d/clipper_backend/clipper_backend.hpp>
+
+// We include the stock optimizers for local and global optimization
+#include <libnest2d/optimizers/subplex.hpp> // Local subplex for NfpPlacer
+#include <libnest2d/optimizers/genetic.hpp> // Genetic for min. bounding box
+
+#include <libnest2d/libnest2d.hpp>
+#include <libnest2d/placers/bottomleftplacer.hpp>
+#include <libnest2d/placers/nfpplacer.hpp>
+#include <libnest2d/selections/firstfit.hpp>
+#include <libnest2d/selections/filler.hpp>
+#include <libnest2d/selections/djd_heuristic.hpp>
+
+namespace libnest2d {
+
+using Point = PointImpl;
+using Coord = TCoord<PointImpl>;
+using Box = _Box<PointImpl>;
+using Segment = _Segment<PointImpl>;
+using Circle = _Circle<PointImpl>;
+
+using Item = _Item<PolygonImpl>;
+using Rectangle = _Rectangle<PolygonImpl>;
+
+using PackGroup = _PackGroup<PolygonImpl>;
+using IndexedPackGroup = _IndexedPackGroup<PolygonImpl>;
+
+using FillerSelection = selections::_FillerSelection<PolygonImpl>;
+using FirstFitSelection = selections::_FirstFitSelection<PolygonImpl>;
+using DJDHeuristic = selections::_DJDHeuristic<PolygonImpl>;
+
+using NfpPlacer = placers::_NofitPolyPlacer<PolygonImpl>;
+using BottomLeftPlacer = placers::_BottomLeftPlacer<PolygonImpl>;
+
+}
+
+#endif // LIBNEST2D_H
diff --git a/xs/src/libnest2d/libnest2d/boost_alg.hpp b/xs/src/libnest2d/libnest2d/boost_alg.hpp
new file mode 100644
index 000000000..bb0403b06
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/boost_alg.hpp
@@ -0,0 +1,518 @@
+#ifndef BOOST_ALG_HPP
+#define BOOST_ALG_HPP
+
+#ifndef DISABLE_BOOST_SERIALIZE
+ #include <sstream>
+#endif
+
+#ifdef __clang__
+#undef _MSC_EXTENSIONS
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4244)
+#pragma warning(disable: 4267)
+#endif
+#include <boost/geometry.hpp>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+// this should be removed to not confuse the compiler
+// #include <libnest2d.h>
+
+namespace bp2d {
+
+using libnest2d::TCoord;
+using libnest2d::PointImpl;
+using Coord = TCoord<PointImpl>;
+using libnest2d::PolygonImpl;
+using libnest2d::PathImpl;
+using libnest2d::Orientation;
+using libnest2d::OrientationType;
+using libnest2d::getX;
+using libnest2d::getY;
+using libnest2d::setX;
+using libnest2d::setY;
+using Box = libnest2d::_Box<PointImpl>;
+using Segment = libnest2d::_Segment<PointImpl>;
+using Shapes = libnest2d::nfp::Shapes<PolygonImpl>;
+
+}
+
+/**
+ * We have to make all the libnest2d geometry types available to boost. The real
+ * models of the geometries remain the same if a conforming model for libnest2d
+ * was defined by the library client. Boost is used only as an optional
+ * implementer of some algorithms that can be implemented by the model itself
+ * if a faster alternative exists.
+ *
+ * However, boost has its own type traits and we have to define the needed
+ * specializations to be able to use boost::geometry. This can be done with the
+ * already provided model.
+ */
+namespace boost {
+namespace geometry {
+namespace traits {
+
+/* ************************************************************************** */
+/* Point concept adaptaion ************************************************** */
+/* ************************************************************************** */
+
+template<> struct tag<bp2d::PointImpl> {
+ using type = point_tag;
+};
+
+template<> struct coordinate_type<bp2d::PointImpl> {
+ using type = bp2d::Coord;
+};
+
+template<> struct coordinate_system<bp2d::PointImpl> {
+ using type = cs::cartesian;
+};
+
+template<> struct dimension<bp2d::PointImpl>: boost::mpl::int_<2> {};
+
+template<>
+struct access<bp2d::PointImpl, 0 > {
+ static inline bp2d::Coord get(bp2d::PointImpl const& a) {
+ return libnest2d::getX(a);
+ }
+
+ static inline void set(bp2d::PointImpl& a,
+ bp2d::Coord const& value) {
+ libnest2d::setX(a, value);
+ }
+};
+
+template<>
+struct access<bp2d::PointImpl, 1 > {
+ static inline bp2d::Coord get(bp2d::PointImpl const& a) {
+ return libnest2d::getY(a);
+ }
+
+ static inline void set(bp2d::PointImpl& a,
+ bp2d::Coord const& value) {
+ libnest2d::setY(a, value);
+ }
+};
+
+
+/* ************************************************************************** */
+/* Box concept adaptaion **************************************************** */
+/* ************************************************************************** */
+
+template<> struct tag<bp2d::Box> {
+ using type = box_tag;
+};
+
+template<> struct point_type<bp2d::Box> {
+ using type = bp2d::PointImpl;
+};
+
+template<> struct indexed_access<bp2d::Box, min_corner, 0> {
+ static inline bp2d::Coord get(bp2d::Box const& box) {
+ return bp2d::getX(box.minCorner());
+ }
+ static inline void set(bp2d::Box &box, bp2d::Coord const& coord) {
+ bp2d::setX(box.minCorner(), coord);
+ }
+};
+
+template<> struct indexed_access<bp2d::Box, min_corner, 1> {
+ static inline bp2d::Coord get(bp2d::Box const& box) {
+ return bp2d::getY(box.minCorner());
+ }
+ static inline void set(bp2d::Box &box, bp2d::Coord const& coord) {
+ bp2d::setY(box.minCorner(), coord);
+ }
+};
+
+template<> struct indexed_access<bp2d::Box, max_corner, 0> {
+ static inline bp2d::Coord get(bp2d::Box const& box) {
+ return bp2d::getX(box.maxCorner());
+ }
+ static inline void set(bp2d::Box &box, bp2d::Coord const& coord) {
+ bp2d::setX(box.maxCorner(), coord);
+ }
+};
+
+template<> struct indexed_access<bp2d::Box, max_corner, 1> {
+ static inline bp2d::Coord get(bp2d::Box const& box) {
+ return bp2d::getY(box.maxCorner());
+ }
+ static inline void set(bp2d::Box &box, bp2d::Coord const& coord) {
+ bp2d::setY(box.maxCorner(), coord);
+ }
+};
+
+/* ************************************************************************** */
+/* Segment concept adaptaion ************************************************ */
+/* ************************************************************************** */
+
+template<> struct tag<bp2d::Segment> {
+ using type = segment_tag;
+};
+
+template<> struct point_type<bp2d::Segment> {
+ using type = bp2d::PointImpl;
+};
+
+template<> struct indexed_access<bp2d::Segment, 0, 0> {
+ static inline bp2d::Coord get(bp2d::Segment const& seg) {
+ return bp2d::getX(seg.first());
+ }
+ static inline void set(bp2d::Segment &seg, bp2d::Coord const& coord) {
+ auto p = seg.first(); bp2d::setX(p, coord); seg.first(p);
+ }
+};
+
+template<> struct indexed_access<bp2d::Segment, 0, 1> {
+ static inline bp2d::Coord get(bp2d::Segment const& seg) {
+ return bp2d::getY(seg.first());
+ }
+ static inline void set(bp2d::Segment &seg, bp2d::Coord const& coord) {
+ auto p = seg.first(); bp2d::setY(p, coord); seg.first(p);
+ }
+};
+
+template<> struct indexed_access<bp2d::Segment, 1, 0> {
+ static inline bp2d::Coord get(bp2d::Segment const& seg) {
+ return bp2d::getX(seg.second());
+ }
+ static inline void set(bp2d::Segment &seg, bp2d::Coord const& coord) {
+ auto p = seg.second(); bp2d::setX(p, coord); seg.second(p);
+ }
+};
+
+template<> struct indexed_access<bp2d::Segment, 1, 1> {
+ static inline bp2d::Coord get(bp2d::Segment const& seg) {
+ return bp2d::getY(seg.second());
+ }
+ static inline void set(bp2d::Segment &seg, bp2d::Coord const& coord) {
+ auto p = seg.second(); bp2d::setY(p, coord); seg.second(p);
+ }
+};
+
+
+/* ************************************************************************** */
+/* Polygon concept adaptation *********************************************** */
+/* ************************************************************************** */
+
+// Connversion between libnest2d::Orientation and order_selector ///////////////
+
+template<bp2d::Orientation> struct ToBoostOrienation {};
+
+template<>
+struct ToBoostOrienation<bp2d::Orientation::CLOCKWISE> {
+ static const order_selector Value = clockwise;
+};
+
+template<>
+struct ToBoostOrienation<bp2d::Orientation::COUNTER_CLOCKWISE> {
+ static const order_selector Value = counterclockwise;
+};
+
+static const bp2d::Orientation RealOrientation =
+ bp2d::OrientationType<bp2d::PolygonImpl>::Value;
+
+// Ring implementation /////////////////////////////////////////////////////////
+
+// Boost would refer to ClipperLib::Path (alias bp2d::PolygonImpl) as a ring
+template<> struct tag<bp2d::PathImpl> {
+ using type = ring_tag;
+};
+
+template<> struct point_order<bp2d::PathImpl> {
+ static const order_selector value =
+ ToBoostOrienation<RealOrientation>::Value;
+};
+
+// All our Paths should be closed for the bin packing application
+template<> struct closure<bp2d::PathImpl> {
+ static const closure_selector value = closed;
+};
+
+// Polygon implementation //////////////////////////////////////////////////////
+
+template<> struct tag<bp2d::PolygonImpl> {
+ using type = polygon_tag;
+};
+
+template<> struct exterior_ring<bp2d::PolygonImpl> {
+ static inline bp2d::PathImpl& get(bp2d::PolygonImpl& p) {
+ return libnest2d::shapelike::getContour(p);
+ }
+
+ static inline bp2d::PathImpl const& get(bp2d::PolygonImpl const& p) {
+ return libnest2d::shapelike::getContour(p);
+ }
+};
+
+template<> struct ring_const_type<bp2d::PolygonImpl> {
+ using type = const bp2d::PathImpl&;
+};
+
+template<> struct ring_mutable_type<bp2d::PolygonImpl> {
+ using type = bp2d::PathImpl&;
+};
+
+template<> struct interior_const_type<bp2d::PolygonImpl> {
+ using type = const libnest2d::THolesContainer<bp2d::PolygonImpl>&;
+};
+
+template<> struct interior_mutable_type<bp2d::PolygonImpl> {
+ using type = libnest2d::THolesContainer<bp2d::PolygonImpl>&;
+};
+
+template<>
+struct interior_rings<bp2d::PolygonImpl> {
+
+ static inline libnest2d::THolesContainer<bp2d::PolygonImpl>& get(
+ bp2d::PolygonImpl& p)
+ {
+ return libnest2d::shapelike::holes(p);
+ }
+
+ static inline const libnest2d::THolesContainer<bp2d::PolygonImpl>& get(
+ bp2d::PolygonImpl const& p)
+ {
+ return libnest2d::shapelike::holes(p);
+ }
+};
+
+/* ************************************************************************** */
+/* MultiPolygon concept adaptation ****************************************** */
+/* ************************************************************************** */
+
+template<> struct tag<bp2d::Shapes> {
+ using type = multi_polygon_tag;
+};
+
+} // traits
+} // geometry
+
+// This is an addition to the ring implementation of Polygon concept
+template<>
+struct range_value<bp2d::PathImpl> {
+ using type = bp2d::PointImpl;
+};
+
+template<>
+struct range_value<bp2d::Shapes> {
+ using type = bp2d::PolygonImpl;
+};
+
+} // boost
+
+/* ************************************************************************** */
+/* Algorithms *************************************************************** */
+/* ************************************************************************** */
+
+namespace libnest2d { // Now the algorithms that boost can provide...
+
+namespace pointlike {
+template<>
+inline double distance(const PointImpl& p1, const PointImpl& p2 )
+{
+ return boost::geometry::distance(p1, p2);
+}
+
+template<>
+inline double distance(const PointImpl& p, const bp2d::Segment& seg )
+{
+ return boost::geometry::distance(p, seg);
+}
+}
+
+namespace shapelike {
+// Tell libnest2d how to make string out of a ClipperPolygon object
+template<>
+inline bool intersects(const PathImpl& sh1, const PathImpl& sh2)
+{
+ return boost::geometry::intersects(sh1, sh2);
+}
+
+// Tell libnest2d how to make string out of a ClipperPolygon object
+template<>
+inline bool intersects(const PolygonImpl& sh1, const PolygonImpl& sh2)
+{
+ return boost::geometry::intersects(sh1, sh2);
+}
+
+// Tell libnest2d how to make string out of a ClipperPolygon object
+template<>
+inline bool intersects(const bp2d::Segment& s1, const bp2d::Segment& s2)
+{
+ return boost::geometry::intersects(s1, s2);
+}
+
+#ifndef DISABLE_BOOST_AREA
+template<>
+inline double area(const PolygonImpl& shape, const PolygonTag&)
+{
+ return boost::geometry::area(shape);
+}
+#endif
+
+template<>
+inline bool isInside(const PointImpl& point, const PolygonImpl& shape)
+{
+ return boost::geometry::within(point, shape);
+}
+
+template<>
+inline bool isInside(const PolygonImpl& sh1, const PolygonImpl& sh2)
+{
+ return boost::geometry::within(sh1, sh2);
+}
+
+template<>
+inline bool touches(const PolygonImpl& sh1, const PolygonImpl& sh2)
+{
+ return boost::geometry::touches(sh1, sh2);
+}
+
+template<>
+inline bool touches( const PointImpl& point, const PolygonImpl& shape)
+{
+ return boost::geometry::touches(point, shape);
+}
+
+#ifndef DISABLE_BOOST_BOUNDING_BOX
+template<>
+inline bp2d::Box boundingBox(const PolygonImpl& sh, const PolygonTag&)
+{
+ bp2d::Box b;
+ boost::geometry::envelope(sh, b);
+ return b;
+}
+
+template<>
+inline bp2d::Box boundingBox<bp2d::Shapes>(const bp2d::Shapes& shapes,
+ const MultiPolygonTag&)
+{
+ bp2d::Box b;
+ boost::geometry::envelope(shapes, b);
+ return b;
+}
+#endif
+
+#ifndef DISABLE_BOOST_CONVEX_HULL
+template<>
+inline PolygonImpl convexHull(const PolygonImpl& sh, const PolygonTag&)
+{
+ PolygonImpl ret;
+ boost::geometry::convex_hull(sh, ret);
+ return ret;
+}
+
+template<>
+inline PolygonImpl convexHull(const TMultiShape<PolygonImpl>& shapes,
+ const MultiPolygonTag&)
+{
+ PolygonImpl ret;
+ boost::geometry::convex_hull(shapes, ret);
+ return ret;
+}
+#endif
+
+#ifndef DISABLE_BOOST_OFFSET
+template<>
+inline void offset(PolygonImpl& sh, bp2d::Coord distance)
+{
+ PolygonImpl cpy = sh;
+ boost::geometry::buffer(cpy, sh, distance);
+}
+#endif
+
+#ifndef DISABLE_BOOST_SERIALIZE
+template<> inline std::string serialize<libnest2d::Formats::SVG>(
+ const PolygonImpl& sh, double scale)
+{
+ std::stringstream ss;
+ std::string style = "fill: none; stroke: black; stroke-width: 1px;";
+
+ using namespace boost::geometry;
+ using Pointf = model::point<double, 2, cs::cartesian>;
+ using Polygonf = model::polygon<Pointf>;
+
+ Polygonf::ring_type ring;
+ Polygonf::inner_container_type holes;
+ ring.reserve(shapelike::contourVertexCount(sh));
+
+ for(auto it = shapelike::cbegin(sh); it != shapelike::cend(sh); it++) {
+ auto& v = *it;
+ ring.emplace_back(getX(v)*scale, getY(v)*scale);
+ };
+
+ auto H = shapelike::holes(sh);
+ for(PathImpl& h : H ) {
+ Polygonf::ring_type hf;
+ for(auto it = h.begin(); it != h.end(); it++) {
+ auto& v = *it;
+ hf.emplace_back(getX(v)*scale, getY(v)*scale);
+ };
+ holes.push_back(hf);
+ }
+
+ Polygonf poly;
+ poly.outer() = ring;
+ poly.inners() = holes;
+ auto svg_data = boost::geometry::svg(poly, style);
+
+ ss << svg_data << std::endl;
+
+ return ss.str();
+}
+#endif
+
+#ifndef DISABLE_BOOST_UNSERIALIZE
+template<>
+inline void unserialize<libnest2d::Formats::SVG>(
+ PolygonImpl& sh,
+ const std::string& str)
+{
+}
+#endif
+
+template<> inline std::pair<bool, std::string> isValid(const PolygonImpl& sh)
+{
+ std::string message;
+ bool ret = boost::geometry::is_valid(sh, message);
+
+ return {ret, message};
+}
+}
+
+namespace nfp {
+
+#ifndef DISABLE_BOOST_NFP_MERGE
+
+// Warning: I could not get boost union_ to work. Geometries will overlap.
+template<>
+inline bp2d::Shapes nfp::merge(const bp2d::Shapes& shapes,
+ const PolygonImpl& sh)
+{
+ bp2d::Shapes retv;
+ boost::geometry::union_(shapes, sh, retv);
+ return retv;
+}
+
+template<>
+inline bp2d::Shapes nfp::merge(const bp2d::Shapes& shapes)
+{
+ bp2d::Shapes retv;
+ boost::geometry::union_(shapes, shapes.back(), retv);
+ return retv;
+}
+#endif
+
+}
+
+
+}
+
+
+
+#endif // BOOST_ALG_HPP
diff --git a/xs/src/libnest2d/libnest2d/clipper_backend/CMakeLists.txt b/xs/src/libnest2d/libnest2d/clipper_backend/CMakeLists.txt
new file mode 100644
index 000000000..b6f2de439
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/clipper_backend/CMakeLists.txt
@@ -0,0 +1,48 @@
+if(NOT TARGET clipper) # If there is a clipper target in the parent project we are good to go.
+
+ find_package(Clipper 6.1)
+
+ if(NOT CLIPPER_FOUND)
+ find_package(Subversion QUIET)
+ if(Subversion_FOUND)
+ message(STATUS "Clipper not found so it will be downloaded.")
+ # Silently download and build the library in the build dir
+
+ if (CMAKE_VERSION VERSION_LESS 3.2)
+ set(UPDATE_DISCONNECTED_IF_AVAILABLE "")
+ else()
+ set(UPDATE_DISCONNECTED_IF_AVAILABLE "UPDATE_DISCONNECTED 1")
+ endif()
+
+ include(DownloadProject)
+ download_project( PROJ clipper_library
+ SVN_REPOSITORY https://svn.code.sf.net/p/polyclipping/code/trunk/cpp
+ SVN_REVISION -r540
+ #SOURCE_SUBDIR cpp
+ INSTALL_COMMAND ""
+ CONFIGURE_COMMAND "" # Not working, I will just add the source files
+ ${UPDATE_DISCONNECTED_IF_AVAILABLE}
+ )
+
+ # This is not working and I dont have time to fix it
+ # add_subdirectory(${clipper_library_SOURCE_DIR}/cpp
+ # ${clipper_library_BINARY_DIR}
+ # )
+
+ add_library(clipper_lib STATIC
+ ${clipper_library_SOURCE_DIR}/clipper.cpp
+ ${clipper_library_SOURCE_DIR}/clipper.hpp)
+
+ set(CLIPPER_INCLUDE_DIRS ${clipper_library_SOURCE_DIR}
+ PARENT_SCOPE)
+
+ set(CLIPPER_LIBRARIES clipper_lib PARENT_SCOPE)
+
+ else()
+ message(FATAL_ERROR "Can't find clipper library and no SVN client found to download.
+ You can download the clipper sources and define a clipper target in your project, that will work for libnest2d.")
+ endif()
+ endif()
+else()
+ set(CLIPPER_LIBRARIES clipper PARENT_SCOPE)
+endif()
diff --git a/xs/src/libnest2d/libnest2d/clipper_backend/clipper_backend.hpp b/xs/src/libnest2d/libnest2d/clipper_backend/clipper_backend.hpp
new file mode 100644
index 000000000..745fd2108
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/clipper_backend/clipper_backend.hpp
@@ -0,0 +1,460 @@
+#ifndef CLIPPER_BACKEND_HPP
+#define CLIPPER_BACKEND_HPP
+
+#include <sstream>
+#include <unordered_map>
+#include <cassert>
+#include <vector>
+#include <iostream>
+
+#include "../geometry_traits.hpp"
+#include "../geometry_traits_nfp.hpp"
+
+#include <clipper.hpp>
+
+namespace ClipperLib {
+using PointImpl = IntPoint;
+using PathImpl = Path;
+using HoleStore = std::vector<PathImpl>;
+
+struct PolygonImpl {
+ PathImpl Contour;
+ HoleStore Holes;
+
+ inline PolygonImpl() = default;
+
+ inline explicit PolygonImpl(const PathImpl& cont): Contour(cont) {}
+ inline explicit PolygonImpl(const HoleStore& holes):
+ Holes(holes) {}
+ inline PolygonImpl(const Path& cont, const HoleStore& holes):
+ Contour(cont), Holes(holes) {}
+
+ inline explicit PolygonImpl(PathImpl&& cont): Contour(std::move(cont)) {}
+ inline explicit PolygonImpl(HoleStore&& holes): Holes(std::move(holes)) {}
+ inline PolygonImpl(Path&& cont, HoleStore&& holes):
+ Contour(std::move(cont)), Holes(std::move(holes)) {}
+};
+
+inline PointImpl& operator +=(PointImpl& p, const PointImpl& pa ) {
+ // This could be done with SIMD
+ p.X += pa.X;
+ p.Y += pa.Y;
+ return p;
+}
+
+inline PointImpl operator+(const PointImpl& p1, const PointImpl& p2) {
+ PointImpl ret = p1;
+ ret += p2;
+ return ret;
+}
+
+inline PointImpl& operator -=(PointImpl& p, const PointImpl& pa ) {
+ p.X -= pa.X;
+ p.Y -= pa.Y;
+ return p;
+}
+
+inline PointImpl operator -(PointImpl& p ) {
+ PointImpl ret = p;
+ ret.X = -ret.X;
+ ret.Y = -ret.Y;
+ return ret;
+}
+
+inline PointImpl operator-(const PointImpl& p1, const PointImpl& p2) {
+ PointImpl ret = p1;
+ ret -= p2;
+ return ret;
+}
+
+inline PointImpl& operator *=(PointImpl& p, const PointImpl& pa ) {
+ p.X *= pa.X;
+ p.Y *= pa.Y;
+ return p;
+}
+
+inline PointImpl operator*(const PointImpl& p1, const PointImpl& p2) {
+ PointImpl ret = p1;
+ ret *= p2;
+ return ret;
+}
+
+}
+
+namespace libnest2d {
+
+// Aliases for convinience
+using ClipperLib::PointImpl;
+using ClipperLib::PathImpl;
+using ClipperLib::PolygonImpl;
+using ClipperLib::HoleStore;
+
+// Type of coordinate units used by Clipper
+template<> struct CoordType<PointImpl> {
+ using Type = ClipperLib::cInt;
+};
+
+// Type of point used by Clipper
+template<> struct PointType<PolygonImpl> {
+ using Type = PointImpl;
+};
+
+template<> struct PointType<PointImpl> {
+ using Type = PointImpl;
+};
+
+template<> struct CountourType<PolygonImpl> {
+ using Type = PathImpl;
+};
+
+template<> struct ShapeTag<PolygonImpl> { using Type = PolygonTag; };
+
+template<> struct ShapeTag<TMultiShape<PolygonImpl>> {
+ using Type = MultiPolygonTag;
+};
+
+template<> struct PointType<TMultiShape<PolygonImpl>> {
+ using Type = PointImpl;
+};
+
+template<> struct HolesContainer<PolygonImpl> {
+ using Type = ClipperLib::Paths;
+};
+
+namespace pointlike {
+
+// Tell libnest2d how to extract the X coord from a ClipperPoint object
+template<> inline TCoord<PointImpl> x(const PointImpl& p)
+{
+ return p.X;
+}
+
+// Tell libnest2d how to extract the Y coord from a ClipperPoint object
+template<> inline TCoord<PointImpl> y(const PointImpl& p)
+{
+ return p.Y;
+}
+
+// Tell libnest2d how to extract the X coord from a ClipperPoint object
+template<> inline TCoord<PointImpl>& x(PointImpl& p)
+{
+ return p.X;
+}
+
+// Tell libnest2d how to extract the Y coord from a ClipperPoint object
+template<> inline TCoord<PointImpl>& y(PointImpl& p)
+{
+ return p.Y;
+}
+
+}
+
+#define DISABLE_BOOST_AREA
+
+namespace _smartarea {
+template<Orientation o>
+inline double area(const PolygonImpl& /*sh*/) {
+ return std::nan("");
+}
+
+template<>
+inline double area<Orientation::CLOCKWISE>(const PolygonImpl& sh) {
+ double a = 0;
+
+ std::for_each(sh.Holes.begin(), sh.Holes.end(), [&a](const PathImpl& h)
+ {
+ a -= ClipperLib::Area(h);
+ });
+
+ return -ClipperLib::Area(sh.Contour) + a;
+}
+
+template<>
+inline double area<Orientation::COUNTER_CLOCKWISE>(const PolygonImpl& sh) {
+ double a = 0;
+
+ std::for_each(sh.Holes.begin(), sh.Holes.end(), [&a](const PathImpl& h)
+ {
+ a += ClipperLib::Area(h);
+ });
+
+ return ClipperLib::Area(sh.Contour) + a;
+}
+
+}
+
+namespace shapelike {
+
+template<> inline void reserve(PolygonImpl& sh, size_t vertex_capacity)
+{
+ return sh.Contour.reserve(vertex_capacity);
+}
+
+// Tell libnest2d how to make string out of a ClipperPolygon object
+template<> inline double area(const PolygonImpl& sh, const PolygonTag&)
+{
+ return _smartarea::area<OrientationType<PolygonImpl>::Value>(sh);
+}
+
+template<> inline void offset(PolygonImpl& sh, TCoord<PointImpl> distance)
+{
+ #define DISABLE_BOOST_OFFSET
+
+ using ClipperLib::ClipperOffset;
+ using ClipperLib::jtMiter;
+ using ClipperLib::etClosedPolygon;
+ using ClipperLib::Paths;
+
+ // If the input is not at least a triangle, we can not do this algorithm
+ if(sh.Contour.size() <= 3 ||
+ std::any_of(sh.Holes.begin(), sh.Holes.end(),
+ [](const PathImpl& p) { return p.size() <= 3; })
+ ) throw GeometryException(GeomErr::OFFSET);
+
+ ClipperOffset offs;
+ Paths result;
+ offs.AddPath(sh.Contour, jtMiter, etClosedPolygon);
+ offs.AddPaths(sh.Holes, jtMiter, etClosedPolygon);
+ offs.Execute(result, static_cast<double>(distance));
+
+ // Offsetting reverts the orientation and also removes the last vertex
+ // so boost will not have a closed polygon.
+
+ bool found_the_contour = false;
+ for(auto& r : result) {
+ if(ClipperLib::Orientation(r)) {
+ // We don't like if the offsetting generates more than one contour
+ // but throwing would be an overkill. Instead, we should warn the
+ // caller about the inability to create correct geometries
+ if(!found_the_contour) {
+ sh.Contour = r;
+ ClipperLib::ReversePath(sh.Contour);
+ sh.Contour.push_back(sh.Contour.front());
+ found_the_contour = true;
+ } else {
+ dout() << "Warning: offsetting result is invalid!";
+ /* TODO warning */
+ }
+ } else {
+ // TODO If there are multiple contours we can't be sure which hole
+ // belongs to the first contour. (But in this case the situation is
+ // bad enough to let it go...)
+ sh.Holes.push_back(r);
+ ClipperLib::ReversePath(sh.Holes.back());
+ sh.Holes.back().push_back(sh.Holes.back().front());
+ }
+ }
+}
+
+// Tell libnest2d how to make string out of a ClipperPolygon object
+template<> inline std::string toString(const PolygonImpl& sh)
+{
+ std::stringstream ss;
+
+ ss << "Contour {\n";
+ for(auto p : sh.Contour) {
+ ss << "\t" << p.X << " " << p.Y << "\n";
+ }
+ ss << "}\n";
+
+ for(auto& h : sh.Holes) {
+ ss << "Holes {\n";
+ for(auto p : h) {
+ ss << "\t{\n";
+ ss << "\t\t" << p.X << " " << p.Y << "\n";
+ ss << "\t}\n";
+ }
+ ss << "}\n";
+ }
+
+ return ss.str();
+}
+
+template<>
+inline PolygonImpl create(const PathImpl& path, const HoleStore& holes)
+{
+ PolygonImpl p;
+ p.Contour = path;
+
+ // Expecting that the coordinate system Y axis is positive in upwards
+ // direction
+ if(ClipperLib::Orientation(p.Contour)) {
+ // Not clockwise then reverse the b*tch
+ ClipperLib::ReversePath(p.Contour);
+ }
+
+ p.Holes = holes;
+ for(auto& h : p.Holes) {
+ if(!ClipperLib::Orientation(h)) {
+ ClipperLib::ReversePath(h);
+ }
+ }
+
+ return p;
+}
+
+template<> inline PolygonImpl create( PathImpl&& path, HoleStore&& holes) {
+ PolygonImpl p;
+ p.Contour.swap(path);
+
+ // Expecting that the coordinate system Y axis is positive in upwards
+ // direction
+ if(ClipperLib::Orientation(p.Contour)) {
+ // Not clockwise then reverse the b*tch
+ ClipperLib::ReversePath(p.Contour);
+ }
+
+ p.Holes.swap(holes);
+
+ for(auto& h : p.Holes) {
+ if(!ClipperLib::Orientation(h)) {
+ ClipperLib::ReversePath(h);
+ }
+ }
+
+ return p;
+}
+
+template<>
+inline const THolesContainer<PolygonImpl>& holes(const PolygonImpl& sh)
+{
+ return sh.Holes;
+}
+
+template<> inline THolesContainer<PolygonImpl>& holes(PolygonImpl& sh)
+{
+ return sh.Holes;
+}
+
+template<>
+inline TContour<PolygonImpl>& getHole(PolygonImpl& sh, unsigned long idx)
+{
+ return sh.Holes[idx];
+}
+
+template<>
+inline const TContour<PolygonImpl>& getHole(const PolygonImpl& sh,
+ unsigned long idx)
+{
+ return sh.Holes[idx];
+}
+
+template<> inline size_t holeCount(const PolygonImpl& sh)
+{
+ return sh.Holes.size();
+}
+
+template<> inline PathImpl& getContour(PolygonImpl& sh)
+{
+ return sh.Contour;
+}
+
+template<>
+inline const PathImpl& getContour(const PolygonImpl& sh)
+{
+ return sh.Contour;
+}
+
+#define DISABLE_BOOST_TRANSLATE
+template<>
+inline void translate(PolygonImpl& sh, const PointImpl& offs)
+{
+ for(auto& p : sh.Contour) { p += offs; }
+ for(auto& hole : sh.Holes) for(auto& p : hole) { p += offs; }
+}
+
+#define DISABLE_BOOST_ROTATE
+template<>
+inline void rotate(PolygonImpl& sh, const Radians& rads)
+{
+ using Coord = TCoord<PointImpl>;
+
+ auto cosa = rads.cos();
+ auto sina = rads.sin();
+
+ for(auto& p : sh.Contour) {
+ p = {
+ static_cast<Coord>(p.X * cosa - p.Y * sina),
+ static_cast<Coord>(p.X * sina + p.Y * cosa)
+ };
+ }
+ for(auto& hole : sh.Holes) for(auto& p : hole) {
+ p = {
+ static_cast<Coord>(p.X * cosa - p.Y * sina),
+ static_cast<Coord>(p.X * sina + p.Y * cosa)
+ };
+ }
+}
+
+} // namespace shapelike
+
+#define DISABLE_BOOST_NFP_MERGE
+inline std::vector<PolygonImpl> _merge(ClipperLib::Clipper& clipper) {
+ shapelike::Shapes<PolygonImpl> retv;
+
+ ClipperLib::PolyTree result;
+ clipper.Execute(ClipperLib::ctUnion, result, ClipperLib::pftNegative);
+ retv.reserve(static_cast<size_t>(result.Total()));
+
+ std::function<void(ClipperLib::PolyNode*, PolygonImpl&)> processHole;
+
+ auto processPoly = [&retv, &processHole](ClipperLib::PolyNode *pptr) {
+ PolygonImpl poly(pptr->Contour);
+ poly.Contour.push_back(poly.Contour.front());
+ for(auto h : pptr->Childs) { processHole(h, poly); }
+ retv.push_back(poly);
+ };
+
+ processHole = [&processPoly](ClipperLib::PolyNode *pptr, PolygonImpl& poly)
+ {
+ poly.Holes.push_back(pptr->Contour);
+ poly.Holes.back().push_back(poly.Holes.back().front());
+ for(auto c : pptr->Childs) processPoly(c);
+ };
+
+ auto traverse = [&processPoly] (ClipperLib::PolyNode *node)
+ {
+ for(auto ch : node->Childs) {
+ processPoly(ch);
+ }
+ };
+
+ traverse(&result);
+
+ return retv;
+}
+
+namespace nfp {
+
+template<> inline std::vector<PolygonImpl>
+merge(const std::vector<PolygonImpl>& shapes)
+{
+ ClipperLib::Clipper clipper(ClipperLib::ioReverseSolution);
+
+ bool closed = true;
+ bool valid = true;
+
+ for(auto& path : shapes) {
+ valid &= clipper.AddPath(path.Contour, ClipperLib::ptSubject, closed);
+
+ for(auto& hole : path.Holes) {
+ valid &= clipper.AddPath(hole, ClipperLib::ptSubject, closed);
+ }
+ }
+
+ if(!valid) throw GeometryException(GeomErr::MERGE);
+
+ return _merge(clipper);
+}
+
+}
+
+}
+
+//#define DISABLE_BOOST_SERIALIZE
+//#define DISABLE_BOOST_UNSERIALIZE
+
+// All other operators and algorithms are implemented with boost
+#include "../boost_alg.hpp"
+
+#endif // CLIPPER_BACKEND_HPP
diff --git a/xs/src/libnest2d/libnest2d/common.hpp b/xs/src/libnest2d/libnest2d/common.hpp
new file mode 100644
index 000000000..6867f76f3
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/common.hpp
@@ -0,0 +1,202 @@
+#ifndef LIBNEST2D_CONFIG_HPP
+#define LIBNEST2D_CONFIG_HPP
+
+#ifndef NDEBUG
+#include <iostream>
+#endif
+
+#include <stdexcept>
+#include <string>
+#include <cmath>
+#include <type_traits>
+
+#if defined(_MSC_VER) && _MSC_VER <= 1800 || __cplusplus < 201103L
+ #define BP2D_NOEXCEPT
+ #define BP2D_CONSTEXPR
+ #define BP2D_COMPILER_MSVC12
+#elif __cplusplus >= 201103L
+ #define BP2D_NOEXCEPT noexcept
+ #define BP2D_CONSTEXPR constexpr
+#endif
+
+/*
+ * Debugging output dout and derr definition
+ */
+//#ifndef NDEBUG
+//# define dout std::cout
+//# define derr std::cerr
+//#else
+//# define dout 0 && std::cout
+//# define derr 0 && std::cerr
+//#endif
+
+namespace libnest2d {
+
+struct DOut {
+#ifndef NDEBUG
+ std::ostream& out = std::cout;
+#endif
+};
+
+struct DErr {
+#ifndef NDEBUG
+ std::ostream& out = std::cerr;
+#endif
+};
+
+template<class T>
+inline DOut&& operator<<( DOut&& out, T&& d) {
+#ifndef NDEBUG
+ out.out << d;
+#endif
+ return std::move(out);
+}
+
+template<class T>
+inline DErr&& operator<<( DErr&& out, T&& d) {
+#ifndef NDEBUG
+ out.out << d;
+#endif
+ return std::move(out);
+}
+inline DOut dout() { return DOut(); }
+inline DErr derr() { return DErr(); }
+
+template< class T >
+struct remove_cvref {
+ using type = typename std::remove_cv<
+ typename std::remove_reference<T>::type>::type;
+};
+
+template< class T >
+using remove_cvref_t = typename remove_cvref<T>::type;
+
+template< class T >
+using remove_ref_t = typename std::remove_reference<T>::type;
+
+template<bool B, class T>
+using enable_if_t = typename std::enable_if<B, T>::type;
+
+template<class F, class...Args>
+struct invoke_result {
+ using type = typename std::result_of<F(Args...)>::type;
+};
+
+template<class F, class...Args>
+using invoke_result_t = typename invoke_result<F, Args...>::type;
+
+/**
+ * A useful little tool for triggering static_assert error messages e.g. when
+ * a mandatory template specialization (implementation) is missing.
+ *
+ * \tparam T A template argument that may come from and outer template method.
+ */
+template<class T> struct always_false { enum { value = false }; };
+
+const double BP2D_CONSTEXPR Pi = 3.141592653589793238463; // 2*std::acos(0);
+const double BP2D_CONSTEXPR Pi_2 = 2*Pi;
+
+/**
+ * @brief Only for the Radian and Degrees classes to behave as doubles.
+ */
+class Double {
+protected:
+ double val_;
+public:
+ Double(): val_(double{}) { }
+ Double(double d) : val_(d) { }
+
+ operator double() const BP2D_NOEXCEPT { return val_; }
+ operator double&() BP2D_NOEXCEPT { return val_; }
+};
+
+class Degrees;
+
+/**
+ * @brief Data type representing radians. It supports conversion to degrees.
+ */
+class Radians: public Double {
+ mutable double sin_ = std::nan(""), cos_ = std::nan("");
+public:
+ Radians(double rads = Double() ): Double(rads) {}
+ inline Radians(const Degrees& degs);
+
+ inline operator Degrees();
+ inline double toDegrees();
+
+ inline double sin() const {
+ if(std::isnan(sin_)) {
+ cos_ = std::cos(val_);
+ sin_ = std::sin(val_);
+ }
+ return sin_;
+ }
+
+ inline double cos() const {
+ if(std::isnan(cos_)) {
+ cos_ = std::cos(val_);
+ sin_ = std::sin(val_);
+ }
+ return cos_;
+ }
+};
+
+/**
+ * @brief Data type representing degrees. It supports conversion to radians.
+ */
+class Degrees: public Double {
+public:
+ Degrees(double deg = Double()): Double(deg) {}
+ Degrees(const Radians& rads): Double( rads * 180/Pi ) {}
+ inline double toRadians() { return Radians(*this);}
+};
+
+inline bool operator==(const Degrees& deg, const Radians& rads) {
+ Degrees deg2 = rads;
+ auto diff = std::abs(deg - deg2);
+ return diff < 0.0001;
+}
+
+inline bool operator==(const Radians& rads, const Degrees& deg) {
+ return deg == rads;
+}
+
+inline Radians::operator Degrees() { return *this * 180/Pi; }
+
+inline Radians::Radians(const Degrees &degs): Double( degs * Pi/180) {}
+
+inline double Radians::toDegrees() { return operator Degrees(); }
+
+enum class GeomErr : std::size_t {
+ OFFSET,
+ MERGE,
+ NFP
+};
+
+const std::string ERROR_STR[] = {
+ "Offsetting could not be done! An invalid geometry may have been added.",
+ "Error while merging geometries!",
+ "No fit polygon cannot be calculated."
+};
+
+class GeometryException: public std::exception {
+
+ virtual const std::string& errorstr(GeomErr errcode) const BP2D_NOEXCEPT {
+ return ERROR_STR[static_cast<std::size_t>(errcode)];
+ }
+
+ GeomErr errcode_;
+public:
+
+ GeometryException(GeomErr code): errcode_(code) {}
+
+ GeomErr errcode() const { return errcode_; }
+
+ const char * what() const BP2D_NOEXCEPT override {
+ return errorstr(errcode_).c_str();
+ }
+};
+
+
+}
+#endif // LIBNEST2D_CONFIG_HPP
diff --git a/xs/src/libnest2d/libnest2d/geometry_traits.hpp b/xs/src/libnest2d/libnest2d/geometry_traits.hpp
new file mode 100644
index 000000000..a78a03b3a
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/geometry_traits.hpp
@@ -0,0 +1,825 @@
+#ifndef GEOMETRY_TRAITS_HPP
+#define GEOMETRY_TRAITS_HPP
+
+#include <string>
+#include <type_traits>
+#include <algorithm>
+#include <array>
+#include <vector>
+#include <numeric>
+#include <limits>
+#include <cmath>
+
+#include "common.hpp"
+
+namespace libnest2d {
+
+/// Getting the coordinate data type for a geometry class.
+template<class GeomClass> struct CoordType { using Type = long; };
+
+/// TCoord<GeomType> as shorthand for typename `CoordType<GeomType>::Type`.
+template<class GeomType>
+using TCoord = typename CoordType<remove_cvref_t<GeomType>>::Type;
+
+/// Getting the type of point structure used by a shape.
+template<class Sh> struct PointType { using Type = typename Sh::PointType; };
+
+/// TPoint<ShapeClass> as shorthand for `typename PointType<ShapeClass>::Type`.
+template<class Shape>
+using TPoint = typename PointType<remove_cvref_t<Shape>>::Type;
+
+/**
+ * \brief A point pair base class for other point pairs (segment, box, ...).
+ * \tparam RawPoint The actual point type to use.
+ */
+template<class RawPoint>
+struct PointPair {
+ RawPoint p1;
+ RawPoint p2;
+};
+
+struct PolygonTag {};
+struct MultiPolygonTag {};
+struct BoxTag {};
+struct CircleTag {};
+
+template<class Shape> struct ShapeTag { using Type = typename Shape::Tag; };
+template<class S> using Tag = typename ShapeTag<S>::Type;
+
+template<class S> struct MultiShape { using Type = std::vector<S>; };
+template<class S> using TMultiShape = typename MultiShape<S>::Type;
+
+/**
+ * \brief An abstraction of a box;
+ */
+template<class RawPoint>
+class _Box: PointPair<RawPoint> {
+ using PointPair<RawPoint>::p1;
+ using PointPair<RawPoint>::p2;
+public:
+
+ using Tag = BoxTag;
+ using PointType = RawPoint;
+
+ inline _Box() = default;
+ inline _Box(const RawPoint& p, const RawPoint& pp):
+ PointPair<RawPoint>({p, pp}) {}
+
+ inline _Box(TCoord<RawPoint> width, TCoord<RawPoint> height):
+ _Box(RawPoint{0, 0}, RawPoint{width, height}) {}
+
+ inline const RawPoint& minCorner() const BP2D_NOEXCEPT { return p1; }
+ inline const RawPoint& maxCorner() const BP2D_NOEXCEPT { return p2; }
+
+ inline RawPoint& minCorner() BP2D_NOEXCEPT { return p1; }
+ inline RawPoint& maxCorner() BP2D_NOEXCEPT { return p2; }
+
+ inline TCoord<RawPoint> width() const BP2D_NOEXCEPT;
+ inline TCoord<RawPoint> height() const BP2D_NOEXCEPT;
+
+ inline RawPoint center() const BP2D_NOEXCEPT;
+
+ inline double area() const BP2D_NOEXCEPT {
+ return double(width()*height());
+ }
+};
+
+template<class RawPoint>
+class _Circle {
+ RawPoint center_;
+ double radius_ = 0;
+public:
+
+ using Tag = CircleTag;
+ using PointType = RawPoint;
+
+ _Circle() = default;
+
+ _Circle(const RawPoint& center, double r): center_(center), radius_(r) {}
+
+ inline const RawPoint& center() const BP2D_NOEXCEPT { return center_; }
+ inline const void center(const RawPoint& c) { center_ = c; }
+
+ inline double radius() const BP2D_NOEXCEPT { return radius_; }
+ inline void radius(double r) { radius_ = r; }
+
+ inline double area() const BP2D_NOEXCEPT {
+ return 2.0*Pi*radius_*radius_;
+ }
+};
+
+/**
+ * \brief An abstraction of a directed line segment with two points.
+ */
+template<class RawPoint>
+class _Segment: PointPair<RawPoint> {
+ using PointPair<RawPoint>::p1;
+ using PointPair<RawPoint>::p2;
+ mutable Radians angletox_ = std::nan("");
+public:
+
+ using PointType = RawPoint;
+
+ inline _Segment() = default;
+
+ inline _Segment(const RawPoint& p, const RawPoint& pp):
+ PointPair<RawPoint>({p, pp}) {}
+
+ /**
+ * @brief Get the first point.
+ * @return Returns the starting point.
+ */
+ inline const RawPoint& first() const BP2D_NOEXCEPT { return p1; }
+
+ /**
+ * @brief The end point.
+ * @return Returns the end point of the segment.
+ */
+ inline const RawPoint& second() const BP2D_NOEXCEPT { return p2; }
+
+ inline void first(const RawPoint& p) BP2D_NOEXCEPT
+ {
+ angletox_ = std::nan(""); p1 = p;
+ }
+
+ inline void second(const RawPoint& p) BP2D_NOEXCEPT {
+ angletox_ = std::nan(""); p2 = p;
+ }
+
+ /// Returns the angle measured to the X (horizontal) axis.
+ inline Radians angleToXaxis() const;
+
+ /// The length of the segment in the measure of the coordinate system.
+ inline double length();
+};
+
+// This struct serves almost as a namespace. The only difference is that is can
+// used in friend declarations.
+namespace pointlike {
+
+ template<class RawPoint>
+ inline TCoord<RawPoint> x(const RawPoint& p)
+ {
+ return p(0);
+ }
+
+ template<class RawPoint>
+ inline TCoord<RawPoint> y(const RawPoint& p)
+ {
+ return p(1);
+ }
+
+ template<class RawPoint>
+ inline TCoord<RawPoint>& x(RawPoint& p)
+ {
+ return p(0);
+ }
+
+ template<class RawPoint>
+ inline TCoord<RawPoint>& y(RawPoint& p)
+ {
+ return p(1);
+ }
+
+ template<class RawPoint>
+ inline double distance(const RawPoint& /*p1*/, const RawPoint& /*p2*/)
+ {
+ static_assert(always_false<RawPoint>::value,
+ "PointLike::distance(point, point) unimplemented!");
+ return 0;
+ }
+
+ template<class RawPoint>
+ inline double distance(const RawPoint& /*p1*/,
+ const _Segment<RawPoint>& /*s*/)
+ {
+ static_assert(always_false<RawPoint>::value,
+ "PointLike::distance(point, segment) unimplemented!");
+ return 0;
+ }
+
+ template<class RawPoint>
+ inline std::pair<TCoord<RawPoint>, bool> horizontalDistance(
+ const RawPoint& p, const _Segment<RawPoint>& s)
+ {
+ using Unit = TCoord<RawPoint>;
+ auto x = pointlike::x(p), y = pointlike::y(p);
+ auto x1 = pointlike::x(s.first()), y1 = pointlike::y(s.first());
+ auto x2 = pointlike::x(s.second()), y2 = pointlike::y(s.second());
+
+ TCoord<RawPoint> ret;
+
+ if( (y < y1 && y < y2) || (y > y1 && y > y2) )
+ return {0, false};
+ if ((y == y1 && y == y2) && (x > x1 && x > x2))
+ ret = std::min( x-x1, x -x2);
+ else if( (y == y1 && y == y2) && (x < x1 && x < x2))
+ ret = -std::min(x1 - x, x2 - x);
+ else if(std::abs(y - y1) <= std::numeric_limits<Unit>::epsilon() &&
+ std::abs(y - y2) <= std::numeric_limits<Unit>::epsilon())
+ ret = 0;
+ else
+ ret = x - x1 + (x1 - x2)*(y1 - y)/(y1 - y2);
+
+ return {ret, true};
+ }
+
+ template<class RawPoint>
+ inline std::pair<TCoord<RawPoint>, bool> verticalDistance(
+ const RawPoint& p, const _Segment<RawPoint>& s)
+ {
+ using Unit = TCoord<RawPoint>;
+ auto x = pointlike::x(p), y = pointlike::y(p);
+ auto x1 = pointlike::x(s.first()), y1 = pointlike::y(s.first());
+ auto x2 = pointlike::x(s.second()), y2 = pointlike::y(s.second());
+
+ TCoord<RawPoint> ret;
+
+ if( (x < x1 && x < x2) || (x > x1 && x > x2) )
+ return {0, false};
+ if ((x == x1 && x == x2) && (y > y1 && y > y2))
+ ret = std::min( y-y1, y -y2);
+ else if( (x == x1 && x == x2) && (y < y1 && y < y2))
+ ret = -std::min(y1 - y, y2 - y);
+ else if(std::abs(x - x1) <= std::numeric_limits<Unit>::epsilon() &&
+ std::abs(x - x2) <= std::numeric_limits<Unit>::epsilon())
+ ret = 0;
+ else
+ ret = y - y1 + (y1 - y2)*(x1 - x)/(x1 - x2);
+
+ return {ret, true};
+ }
+}
+
+template<class RawPoint>
+TCoord<RawPoint> _Box<RawPoint>::width() const BP2D_NOEXCEPT
+{
+ return pointlike::x(maxCorner()) - pointlike::x(minCorner());
+}
+
+template<class RawPoint>
+TCoord<RawPoint> _Box<RawPoint>::height() const BP2D_NOEXCEPT
+{
+ return pointlike::y(maxCorner()) - pointlike::y(minCorner());
+}
+
+template<class RawPoint>
+TCoord<RawPoint> getX(const RawPoint& p) { return pointlike::x<RawPoint>(p); }
+
+template<class RawPoint>
+TCoord<RawPoint> getY(const RawPoint& p) { return pointlike::y<RawPoint>(p); }
+
+template<class RawPoint>
+void setX(RawPoint& p, const TCoord<RawPoint>& val)
+{
+ pointlike::x<RawPoint>(p) = val;
+}
+
+template<class RawPoint>
+void setY(RawPoint& p, const TCoord<RawPoint>& val)
+{
+ pointlike::y<RawPoint>(p) = val;
+}
+
+template<class RawPoint>
+inline Radians _Segment<RawPoint>::angleToXaxis() const
+{
+ if(std::isnan(static_cast<double>(angletox_))) {
+ TCoord<RawPoint> dx = getX(second()) - getX(first());
+ TCoord<RawPoint> dy = getY(second()) - getY(first());
+
+ double a = std::atan2(dy, dx);
+ auto s = std::signbit(a);
+
+ if(s) a += Pi_2;
+ angletox_ = a;
+ }
+ return angletox_;
+}
+
+template<class RawPoint>
+inline double _Segment<RawPoint>::length()
+{
+ return pointlike::distance(first(), second());
+}
+
+template<class RawPoint>
+inline RawPoint _Box<RawPoint>::center() const BP2D_NOEXCEPT {
+ auto& minc = minCorner();
+ auto& maxc = maxCorner();
+
+ using Coord = TCoord<RawPoint>;
+
+ RawPoint ret = { // No rounding here, we dont know if these are int coords
+ static_cast<Coord>( (getX(minc) + getX(maxc))/2.0 ),
+ static_cast<Coord>( (getY(minc) + getY(maxc))/2.0 )
+ };
+
+ return ret;
+}
+
+template<class RawShape>
+struct HolesContainer {
+ using Type = std::vector<RawShape>;
+};
+
+template<class RawShape>
+using THolesContainer = typename HolesContainer<remove_cvref_t<RawShape>>::Type;
+
+template<class RawShape>
+struct CountourType {
+ using Type = RawShape;
+};
+
+template<class RawShape>
+using TContour = typename CountourType<remove_cvref_t<RawShape>>::Type;
+
+enum class Orientation {
+ CLOCKWISE,
+ COUNTER_CLOCKWISE
+};
+
+template<class RawShape>
+struct OrientationType {
+
+ // Default Polygon orientation that the library expects
+ static const Orientation Value = Orientation::CLOCKWISE;
+};
+
+enum class Formats {
+ WKT,
+ SVG
+};
+
+// This struct serves as a namespace. The only difference is that it can be
+// used in friend declarations and can be aliased at class scope.
+namespace shapelike {
+
+ template<class RawShape>
+ using Shapes = TMultiShape<RawShape>;
+
+ template<class RawShape>
+ inline RawShape create(const TContour<RawShape>& contour,
+ const THolesContainer<RawShape>& holes)
+ {
+ return RawShape(contour, holes);
+ }
+
+ template<class RawShape>
+ inline RawShape create(TContour<RawShape>&& contour,
+ THolesContainer<RawShape>&& holes)
+ {
+ return RawShape(contour, holes);
+ }
+
+ template<class RawShape>
+ inline RawShape create(const TContour<RawShape>& contour)
+ {
+ return create<RawShape>(contour, {});
+ }
+
+ template<class RawShape>
+ inline RawShape create(TContour<RawShape>&& contour)
+ {
+ return create<RawShape>(contour, {});
+ }
+
+ template<class RawShape>
+ inline THolesContainer<RawShape>& holes(RawShape& /*sh*/)
+ {
+ static THolesContainer<RawShape> empty;
+ return empty;
+ }
+
+ template<class RawShape>
+ inline const THolesContainer<RawShape>& holes(const RawShape& /*sh*/)
+ {
+ static THolesContainer<RawShape> empty;
+ return empty;
+ }
+
+ template<class RawShape>
+ inline TContour<RawShape>& getHole(RawShape& sh, unsigned long idx)
+ {
+ return holes(sh)[idx];
+ }
+
+ template<class RawShape>
+ inline const TContour<RawShape>& getHole(const RawShape& sh,
+ unsigned long idx)
+ {
+ return holes(sh)[idx];
+ }
+
+ template<class RawShape>
+ inline size_t holeCount(const RawShape& sh)
+ {
+ return holes(sh).size();
+ }
+
+ template<class RawShape>
+ inline TContour<RawShape>& getContour(RawShape& sh)
+ {
+ return sh;
+ }
+
+ template<class RawShape>
+ inline const TContour<RawShape>& getContour(const RawShape& sh)
+ {
+ return sh;
+ }
+
+ // Optional, does nothing by default
+ template<class RawShape>
+ inline void reserve(RawShape& /*sh*/, size_t /*vertex_capacity*/) {}
+
+ template<class RawShape, class...Args>
+ inline void addVertex(RawShape& sh, Args...args)
+ {
+ return getContour(sh).emplace_back(std::forward<Args>(args)...);
+ }
+
+ template<class RawShape>
+ inline typename TContour<RawShape>::iterator begin(RawShape& sh)
+ {
+ return getContour(sh).begin();
+ }
+
+ template<class RawShape>
+ inline typename TContour<RawShape>::iterator end(RawShape& sh)
+ {
+ return getContour(sh).end();
+ }
+
+ template<class RawShape>
+ inline typename TContour<RawShape>::const_iterator
+ cbegin(const RawShape& sh)
+ {
+ return getContour(sh).cbegin();
+ }
+
+ template<class RawShape>
+ inline typename TContour<RawShape>::const_iterator cend(const RawShape& sh)
+ {
+ return getContour(sh).cend();
+ }
+
+ template<class RawShape>
+ inline std::string toString(const RawShape& /*sh*/)
+ {
+ return "";
+ }
+
+ template<Formats, class RawShape>
+ inline std::string serialize(const RawShape& /*sh*/, double /*scale*/=1)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::serialize() unimplemented!");
+ return "";
+ }
+
+ template<Formats, class RawShape>
+ inline void unserialize(RawShape& /*sh*/, const std::string& /*str*/)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::unserialize() unimplemented!");
+ }
+
+ template<class RawShape>
+ inline double area(const RawShape& /*sh*/, const PolygonTag&)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::area() unimplemented!");
+ return 0;
+ }
+
+ template<class RawShape>
+ inline bool intersects(const RawShape& /*sh*/, const RawShape& /*sh*/)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::intersects() unimplemented!");
+ return false;
+ }
+
+ template<class RawShape>
+ inline bool isInside(const TPoint<RawShape>& /*point*/,
+ const RawShape& /*shape*/)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::isInside(point, shape) unimplemented!");
+ return false;
+ }
+
+ template<class RawShape>
+ inline bool isInside(const RawShape& /*shape*/,
+ const RawShape& /*shape*/)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::isInside(shape, shape) unimplemented!");
+ return false;
+ }
+
+ template<class RawShape>
+ inline bool touches( const RawShape& /*shape*/,
+ const RawShape& /*shape*/)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::touches(shape, shape) unimplemented!");
+ return false;
+ }
+
+ template<class RawShape>
+ inline bool touches( const TPoint<RawShape>& /*point*/,
+ const RawShape& /*shape*/)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::touches(point, shape) unimplemented!");
+ return false;
+ }
+
+ template<class RawShape>
+ inline _Box<TPoint<RawShape>> boundingBox(const RawShape& /*sh*/,
+ const PolygonTag&)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::boundingBox(shape) unimplemented!");
+ }
+
+ template<class RawShapes>
+ inline _Box<TPoint<typename RawShapes::value_type>>
+ boundingBox(const RawShapes& /*sh*/, const MultiPolygonTag&)
+ {
+ static_assert(always_false<RawShapes>::value,
+ "ShapeLike::boundingBox(shapes) unimplemented!");
+ }
+
+ template<class RawShape>
+ inline RawShape convexHull(const RawShape& /*sh*/, const PolygonTag&)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::convexHull(shape) unimplemented!");
+ return RawShape();
+ }
+
+ template<class RawShapes>
+ inline typename RawShapes::value_type
+ convexHull(const RawShapes& /*sh*/, const MultiPolygonTag&)
+ {
+ static_assert(always_false<RawShapes>::value,
+ "ShapeLike::convexHull(shapes) unimplemented!");
+ return typename RawShapes::value_type();
+ }
+
+ template<class RawShape>
+ inline void rotate(RawShape& /*sh*/, const Radians& /*rads*/)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::rotate() unimplemented!");
+ }
+
+ template<class RawShape, class RawPoint>
+ inline void translate(RawShape& /*sh*/, const RawPoint& /*offs*/)
+ {
+ static_assert(always_false<RawShape>::value,
+ "ShapeLike::translate() unimplemented!");
+ }
+
+ template<class RawShape>
+ inline void offset(RawShape& /*sh*/, TCoord<TPoint<RawShape>> /*distance*/)
+ {
+ dout() << "The current geometry backend does not support offsetting!\n";
+ }
+
+ template<class RawShape>
+ inline std::pair<bool, std::string> isValid(const RawShape& /*sh*/)
+ {
+ return {false, "ShapeLike::isValid() unimplemented!"};
+ }
+
+ template<class RawShape>
+ inline bool isConvex(const TContour<RawShape>& sh)
+ {
+ using Vertex = TPoint<RawShape>;
+ auto first = sh.begin();
+ auto middle = std::next(first);
+ auto last = std::next(middle);
+ using CVrRef = const Vertex&;
+
+ auto zcrossproduct = [](CVrRef k, CVrRef k1, CVrRef k2) {
+ auto dx1 = getX(k1) - getX(k);
+ auto dy1 = getY(k1) - getY(k);
+ auto dx2 = getX(k2) - getX(k1);
+ auto dy2 = getY(k2) - getY(k1);
+ return dx1*dy2 - dy1*dx2;
+ };
+
+ auto firstprod = zcrossproduct( *(std::prev(std::prev(sh.end()))),
+ *first,
+ *middle );
+
+ bool ret = true;
+ bool frsign = firstprod > 0;
+ while(last != sh.end()) {
+ auto &k = *first, &k1 = *middle, &k2 = *last;
+ auto zc = zcrossproduct(k, k1, k2);
+ ret &= frsign == (zc > 0);
+ ++first; ++middle; ++last;
+ }
+
+ return ret;
+ }
+
+ // *************************************************************************
+ // No need to implement these
+ // *************************************************************************
+
+ template<class Box>
+ inline Box boundingBox(const Box& box, const BoxTag& )
+ {
+ return box;
+ }
+
+ template<class Circle>
+ inline _Box<typename Circle::PointType> boundingBox(
+ const Circle& circ, const CircleTag&)
+ {
+ using Point = typename Circle::PointType;
+ using Coord = TCoord<Point>;
+ Point pmin = {
+ static_cast<Coord>(getX(circ.center()) - circ.radius()),
+ static_cast<Coord>(getY(circ.center()) - circ.radius()) };
+
+ Point pmax = {
+ static_cast<Coord>(getX(circ.center()) + circ.radius()),
+ static_cast<Coord>(getY(circ.center()) + circ.radius()) };
+
+ return {pmin, pmax};
+ }
+
+ template<class S> // Dispatch function
+ inline _Box<TPoint<S>> boundingBox(const S& sh)
+ {
+ return boundingBox(sh, Tag<S>() );
+ }
+
+ template<class Box>
+ inline double area(const Box& box, const BoxTag& )
+ {
+ return box.area();
+ }
+
+ template<class Circle>
+ inline double area(const Circle& circ, const CircleTag& )
+ {
+ return circ.area();
+ }
+
+ template<class RawShape> // Dispatching function
+ inline double area(const RawShape& sh)
+ {
+ return area(sh, Tag<RawShape>());
+ }
+
+ template<class RawShape>
+ inline double area(const Shapes<RawShape>& shapes)
+ {
+ return std::accumulate(shapes.begin(), shapes.end(), 0.0,
+ [](double a, const RawShape& b) {
+ return a += area(b);
+ });
+ }
+
+ template<class RawShape>
+ inline auto convexHull(const RawShape& sh)
+ -> decltype(convexHull(sh, Tag<RawShape>())) // TODO: C++14 could deduce
+ {
+ return convexHull(sh, Tag<RawShape>());
+ }
+
+ template<class RawShape>
+ inline bool isInside(const TPoint<RawShape>& point,
+ const _Circle<TPoint<RawShape>>& circ)
+ {
+ return pointlike::distance(point, circ.center()) < circ.radius();
+ }
+
+ template<class RawShape>
+ inline bool isInside(const TPoint<RawShape>& point,
+ const _Box<TPoint<RawShape>>& box)
+ {
+ auto px = getX(point);
+ auto py = getY(point);
+ auto minx = getX(box.minCorner());
+ auto miny = getY(box.minCorner());
+ auto maxx = getX(box.maxCorner());
+ auto maxy = getY(box.maxCorner());
+
+ return px > minx && px < maxx && py > miny && py < maxy;
+ }
+
+ template<class RawShape>
+ inline bool isInside(const RawShape& sh,
+ const _Circle<TPoint<RawShape>>& circ)
+ {
+ return std::all_of(cbegin(sh), cend(sh),
+ [&circ](const TPoint<RawShape>& p){
+ return isInside<RawShape>(p, circ);
+ });
+ }
+
+ template<class RawShape>
+ inline bool isInside(const _Box<TPoint<RawShape>>& box,
+ const _Circle<TPoint<RawShape>>& circ)
+ {
+ return isInside<RawShape>(box.minCorner(), circ) &&
+ isInside<RawShape>(box.maxCorner(), circ);
+ }
+
+ template<class RawShape>
+ inline bool isInside(const _Box<TPoint<RawShape>>& ibb,
+ const _Box<TPoint<RawShape>>& box)
+ {
+ auto iminX = getX(ibb.minCorner());
+ auto imaxX = getX(ibb.maxCorner());
+ auto iminY = getY(ibb.minCorner());
+ auto imaxY = getY(ibb.maxCorner());
+
+ auto minX = getX(box.minCorner());
+ auto maxX = getX(box.maxCorner());
+ auto minY = getY(box.minCorner());
+ auto maxY = getY(box.maxCorner());
+
+ return iminX > minX && imaxX < maxX && iminY > minY && imaxY < maxY;
+ }
+
+ template<class RawShape> // Potential O(1) implementation may exist
+ inline TPoint<RawShape>& vertex(RawShape& sh, unsigned long idx)
+ {
+ return *(begin(sh) + idx);
+ }
+
+ template<class RawShape> // Potential O(1) implementation may exist
+ inline const TPoint<RawShape>& vertex(const RawShape& sh,
+ unsigned long idx)
+ {
+ return *(cbegin(sh) + idx);
+ }
+
+ template<class RawShape>
+ inline size_t contourVertexCount(const RawShape& sh)
+ {
+ return cend(sh) - cbegin(sh);
+ }
+
+ template<class RawShape, class Fn>
+ inline void foreachContourVertex(RawShape& sh, Fn fn) {
+ for(auto it = begin(sh); it != end(sh); ++it) fn(*it);
+ }
+
+ template<class RawShape, class Fn>
+ inline void foreachHoleVertex(RawShape& sh, Fn fn) {
+ for(int i = 0; i < holeCount(sh); ++i) {
+ auto& h = getHole(sh, i);
+ for(auto it = begin(h); it != end(h); ++it) fn(*it);
+ }
+ }
+
+ template<class RawShape, class Fn>
+ inline void foreachContourVertex(const RawShape& sh, Fn fn) {
+ for(auto it = cbegin(sh); it != cend(sh); ++it) fn(*it);
+ }
+
+ template<class RawShape, class Fn>
+ inline void foreachHoleVertex(const RawShape& sh, Fn fn) {
+ for(int i = 0; i < holeCount(sh); ++i) {
+ auto& h = getHole(sh, i);
+ for(auto it = cbegin(h); it != cend(h); ++it) fn(*it);
+ }
+ }
+
+ template<class RawShape, class Fn>
+ inline void foreachVertex(RawShape& sh, Fn fn) {
+ foreachContourVertex(sh, fn);
+ foreachHoleVertex(sh, fn);
+ }
+
+ template<class RawShape, class Fn>
+ inline void foreachVertex(const RawShape& sh, Fn fn) {
+ foreachContourVertex(sh, fn);
+ foreachHoleVertex(sh, fn);
+ }
+}
+
+#define DECLARE_MAIN_TYPES(T) \
+ using Polygon = T; \
+ using Point = TPoint<T>; \
+ using Coord = TCoord<Point>; \
+ using Contour = TContour<T>; \
+ using Box = _Box<Point>; \
+ using Circle = _Circle<Point>; \
+ using Segment = _Segment<Point>; \
+ using Polygons = TMultiShape<T>
+
+}
+
+#endif // GEOMETRY_TRAITS_HPP
diff --git a/xs/src/libnest2d/libnest2d/geometry_traits_nfp.hpp b/xs/src/libnest2d/libnest2d/geometry_traits_nfp.hpp
new file mode 100644
index 000000000..2982454cd
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/geometry_traits_nfp.hpp
@@ -0,0 +1,558 @@
+#ifndef GEOMETRIES_NOFITPOLYGON_HPP
+#define GEOMETRIES_NOFITPOLYGON_HPP
+
+#include "geometry_traits.hpp"
+#include <algorithm>
+#include <functional>
+#include <vector>
+#include <iterator>
+
+namespace libnest2d {
+
+namespace __nfp {
+// Do not specialize this...
+template<class RawShape>
+inline bool _vsort(const TPoint<RawShape>& v1, const TPoint<RawShape>& v2)
+{
+ using Coord = TCoord<TPoint<RawShape>>;
+ Coord &&x1 = getX(v1), &&x2 = getX(v2), &&y1 = getY(v1), &&y2 = getY(v2);
+ auto diff = y1 - y2;
+ if(std::abs(diff) <= std::numeric_limits<Coord>::epsilon())
+ return x1 < x2;
+
+ return diff < 0;
+}
+}
+
+/// A collection of static methods for handling the no fit polygon creation.
+namespace nfp {
+
+//namespace sl = shapelike;
+//namespace pl = pointlike;
+
+/// The complexity level of a polygon that an NFP implementation can handle.
+enum class NfpLevel: unsigned {
+ CONVEX_ONLY,
+ ONE_CONVEX,
+ BOTH_CONCAVE,
+ ONE_CONVEX_WITH_HOLES,
+ BOTH_CONCAVE_WITH_HOLES
+};
+
+template<class RawShape>
+using NfpResult = std::pair<RawShape, TPoint<RawShape>>;
+
+template<class RawShape> struct MaxNfpLevel {
+ static const BP2D_CONSTEXPR NfpLevel value = NfpLevel::CONVEX_ONLY;
+};
+
+
+// Shorthand for a pile of polygons
+template<class RawShape>
+using Shapes = TMultiShape<RawShape>;
+
+/**
+ * Merge a bunch of polygons with the specified additional polygon.
+ *
+ * \tparam RawShape the Polygon data type.
+ * \param shc The pile of polygons that will be unified with sh.
+ * \param sh A single polygon to unify with shc.
+ *
+ * \return A set of polygons that is the union of the input polygons. Note that
+ * mostly it will be a set containing only one big polygon but if the input
+ * polygons are disjuct than the resulting set will contain more polygons.
+ */
+template<class RawShapes>
+inline RawShapes merge(const RawShapes& /*shc*/)
+{
+ static_assert(always_false<RawShapes>::value,
+ "Nfp::merge(shapes, shape) unimplemented!");
+}
+
+/**
+ * Merge a bunch of polygons with the specified additional polygon.
+ *
+ * \tparam RawShape the Polygon data type.
+ * \param shc The pile of polygons that will be unified with sh.
+ * \param sh A single polygon to unify with shc.
+ *
+ * \return A set of polygons that is the union of the input polygons. Note that
+ * mostly it will be a set containing only one big polygon but if the input
+ * polygons are disjuct than the resulting set will contain more polygons.
+ */
+template<class RawShape>
+inline TMultiShape<RawShape> merge(const TMultiShape<RawShape>& shc,
+ const RawShape& sh)
+{
+ auto m = nfp::merge(shc);
+ m.push_back(sh);
+ return nfp::merge(m);
+}
+
+/**
+ * Get the vertex of the polygon that is at the lowest values (bottom) in the Y
+ * axis and if there are more than one vertices on the same Y coordinate than
+ * the result will be the leftmost (with the highest X coordinate).
+ */
+template<class RawShape>
+inline TPoint<RawShape> leftmostDownVertex(const RawShape& sh)
+{
+
+ // find min x and min y vertex
+ auto it = std::min_element(shapelike::cbegin(sh), shapelike::cend(sh),
+ __nfp::_vsort<RawShape>);
+
+ return it == shapelike::cend(sh) ? TPoint<RawShape>() : *it;;
+}
+
+/**
+ * Get the vertex of the polygon that is at the highest values (top) in the Y
+ * axis and if there are more than one vertices on the same Y coordinate than
+ * the result will be the rightmost (with the lowest X coordinate).
+ */
+template<class RawShape>
+TPoint<RawShape> rightmostUpVertex(const RawShape& sh)
+{
+
+ // find max x and max y vertex
+ auto it = std::max_element(shapelike::cbegin(sh), shapelike::cend(sh),
+ __nfp::_vsort<RawShape>);
+
+ return it == shapelike::cend(sh) ? TPoint<RawShape>() : *it;
+}
+
+/**
+ * A method to get a vertex from a polygon that always maintains a relative
+ * position to the coordinate system: It is always the rightmost top vertex.
+ *
+ * This way it does not matter in what order the vertices are stored, the
+ * reference will be always the same for the same polygon.
+ */
+template<class RawShape>
+inline TPoint<RawShape> referenceVertex(const RawShape& sh)
+{
+ return rightmostUpVertex(sh);
+}
+
+/**
+ * The "trivial" Cuninghame-Green implementation of NFP for convex polygons.
+ *
+ * You can use this even if you provide implementations for the more complex
+ * cases (Through specializing the the NfpImpl struct). Currently, no other
+ * cases are covered in the library.
+ *
+ * Complexity should be no more than linear in the number of edges of the input
+ * polygons.
+ *
+ * \tparam RawShape the Polygon data type.
+ * \param sh The stationary polygon
+ * \param cother The orbiting polygon
+ * \return Returns a pair of the NFP and its reference vertex of the two input
+ * polygons which have to be strictly convex. The resulting NFP is proven to be
+ * convex as well in this case.
+ *
+ */
+template<class RawShape>
+inline NfpResult<RawShape> nfpConvexOnly(const RawShape& sh,
+ const RawShape& other)
+{
+ using Vertex = TPoint<RawShape>; using Edge = _Segment<Vertex>;
+ namespace sl = shapelike;
+
+ RawShape rsh; // Final nfp placeholder
+ Vertex top_nfp;
+ std::vector<Edge> edgelist;
+
+ auto cap = sl::contourVertexCount(sh) + sl::contourVertexCount(other);
+
+ // Reserve the needed memory
+ edgelist.reserve(cap);
+ sl::reserve(rsh, static_cast<unsigned long>(cap));
+
+ { // place all edges from sh into edgelist
+ auto first = sl::cbegin(sh);
+ auto next = std::next(first);
+
+ while(next != sl::cend(sh)) {
+ edgelist.emplace_back(*(first), *(next));
+ ++first; ++next;
+ }
+ }
+
+ { // place all edges from other into edgelist
+ auto first = sl::cbegin(other);
+ auto next = std::next(first);
+
+ while(next != sl::cend(other)) {
+ edgelist.emplace_back(*(next), *(first));
+ ++first; ++next;
+ }
+ }
+
+ // Sort the edges by angle to X axis.
+ std::sort(edgelist.begin(), edgelist.end(),
+ [](const Edge& e1, const Edge& e2)
+ {
+ return e1.angleToXaxis() > e2.angleToXaxis();
+ });
+
+ // Add the two vertices from the first edge into the final polygon.
+ sl::addVertex(rsh, edgelist.front().first());
+ sl::addVertex(rsh, edgelist.front().second());
+
+ // Sorting function for the nfp reference vertex search
+ auto& cmp = __nfp::_vsort<RawShape>;
+
+ // the reference (rightmost top) vertex so far
+ top_nfp = *std::max_element(sl::cbegin(rsh), sl::cend(rsh), cmp );
+
+ auto tmp = std::next(sl::begin(rsh));
+
+ // Construct final nfp by placing each edge to the end of the previous
+ for(auto eit = std::next(edgelist.begin());
+ eit != edgelist.end();
+ ++eit)
+ {
+ auto d = *tmp - eit->first();
+ Vertex p = eit->second() + d;
+
+ sl::addVertex(rsh, p);
+
+ // Set the new reference vertex
+ if(cmp(top_nfp, p)) top_nfp = p;
+
+ tmp = std::next(tmp);
+ }
+
+ return {rsh, top_nfp};
+}
+
+template<class RawShape>
+NfpResult<RawShape> nfpSimpleSimple(const RawShape& cstationary,
+ const RawShape& cother)
+{
+
+ // Algorithms are from the original algorithm proposed in paper:
+ // https://eprints.soton.ac.uk/36850/1/CORMSIS-05-05.pdf
+
+ // /////////////////////////////////////////////////////////////////////////
+ // Algorithm 1: Obtaining the minkowski sum
+ // /////////////////////////////////////////////////////////////////////////
+
+ // I guess this is not a full minkowski sum of the two input polygons by
+ // definition. This yields a subset that is compatible with the next 2
+ // algorithms.
+
+ using Result = NfpResult<RawShape>;
+ using Vertex = TPoint<RawShape>;
+ using Coord = TCoord<Vertex>;
+ using Edge = _Segment<Vertex>;
+ namespace sl = shapelike;
+ using std::signbit;
+ using std::sort;
+ using std::vector;
+ using std::ref;
+ using std::reference_wrapper;
+
+ // TODO The original algorithms expects the stationary polygon in
+ // counter clockwise and the orbiter in clockwise order.
+ // So for preventing any further complication, I will make the input
+ // the way it should be, than make my way around the orientations.
+
+ // Reverse the stationary contour to counter clockwise
+ auto stcont = sl::getContour(cstationary);
+ std::reverse(stcont.begin(), stcont.end());
+ RawShape stationary;
+ sl::getContour(stationary) = stcont;
+
+ // Reverse the orbiter contour to counter clockwise
+ auto orbcont = sl::getContour(cother);
+
+ std::reverse(orbcont.begin(), orbcont.end());
+
+ // Copy the orbiter (contour only), we will have to work on it
+ RawShape orbiter;
+ sl::getContour(orbiter) = orbcont;
+
+ // Step 1: Make the orbiter reverse oriented
+ for(auto &v : sl::getContour(orbiter)) v = -v;
+
+ // An egde with additional data for marking it
+ struct MarkedEdge {
+ Edge e; Radians turn_angle = 0; bool is_turning_point = false;
+ MarkedEdge() = default;
+ MarkedEdge(const Edge& ed, Radians ta, bool tp):
+ e(ed), turn_angle(ta), is_turning_point(tp) {}
+ };
+
+ // Container for marked edges
+ using EdgeList = vector<MarkedEdge>;
+
+ EdgeList A, B;
+
+ // This is how an edge list is created from the polygons
+ auto fillEdgeList = [](EdgeList& L, const RawShape& poly, int dir) {
+ L.reserve(sl::contourVertexCount(poly));
+
+ auto it = sl::cbegin(poly);
+ auto nextit = std::next(it);
+
+ double turn_angle = 0;
+ bool is_turn_point = false;
+
+ while(nextit != sl::cend(poly)) {
+ L.emplace_back(Edge(*it, *nextit), turn_angle, is_turn_point);
+ it++; nextit++;
+ }
+
+ auto getTurnAngle = [](const Edge& e1, const Edge& e2) {
+ auto phi = e1.angleToXaxis();
+ auto phi_prev = e2.angleToXaxis();
+ auto TwoPi = 2.0*Pi;
+ if(phi > Pi) phi -= TwoPi;
+ if(phi_prev > Pi) phi_prev -= TwoPi;
+ auto turn_angle = phi-phi_prev;
+ if(turn_angle > Pi) turn_angle -= TwoPi;
+ return phi-phi_prev;
+ };
+
+ if(dir > 0) {
+ auto eit = L.begin();
+ auto enext = std::next(eit);
+
+ eit->turn_angle = getTurnAngle(L.front().e, L.back().e);
+
+ while(enext != L.end()) {
+ enext->turn_angle = getTurnAngle( enext->e, eit->e);
+ enext->is_turning_point =
+ signbit(enext->turn_angle) != signbit(eit->turn_angle);
+ ++eit; ++enext;
+ }
+
+ L.front().is_turning_point = signbit(L.front().turn_angle) !=
+ signbit(L.back().turn_angle);
+ } else {
+ std::cout << L.size() << std::endl;
+
+ auto eit = L.rbegin();
+ auto enext = std::next(eit);
+
+ eit->turn_angle = getTurnAngle(L.back().e, L.front().e);
+
+ while(enext != L.rend()) {
+ enext->turn_angle = getTurnAngle(enext->e, eit->e);
+ enext->is_turning_point =
+ signbit(enext->turn_angle) != signbit(eit->turn_angle);
+ std::cout << enext->is_turning_point << " " << enext->turn_angle << std::endl;
+
+ ++eit; ++enext;
+ }
+
+ L.back().is_turning_point = signbit(L.back().turn_angle) !=
+ signbit(L.front().turn_angle);
+ }
+ };
+
+ // Step 2: Fill the edgelists
+ fillEdgeList(A, stationary, 1);
+ fillEdgeList(B, orbiter, -1);
+
+ // A reference to a marked edge that also knows its container
+ struct MarkedEdgeRef {
+ reference_wrapper<MarkedEdge> eref;
+ reference_wrapper<vector<MarkedEdgeRef>> container;
+ Coord dir = 1; // Direction modifier
+
+ inline Radians angleX() const { return eref.get().e.angleToXaxis(); }
+ inline const Edge& edge() const { return eref.get().e; }
+ inline Edge& edge() { return eref.get().e; }
+ inline bool isTurningPoint() const {
+ return eref.get().is_turning_point;
+ }
+ inline bool isFrom(const vector<MarkedEdgeRef>& cont ) {
+ return &(container.get()) == &cont;
+ }
+ inline bool eq(const MarkedEdgeRef& mr) {
+ return &(eref.get()) == &(mr.eref.get());
+ }
+
+ MarkedEdgeRef(reference_wrapper<MarkedEdge> er,
+ reference_wrapper<vector<MarkedEdgeRef>> ec):
+ eref(er), container(ec), dir(1) {}
+
+ MarkedEdgeRef(reference_wrapper<MarkedEdge> er,
+ reference_wrapper<vector<MarkedEdgeRef>> ec,
+ Coord d):
+ eref(er), container(ec), dir(d) {}
+ };
+
+ using EdgeRefList = vector<MarkedEdgeRef>;
+
+ // Comparing two marked edges
+ auto sortfn = [](const MarkedEdgeRef& e1, const MarkedEdgeRef& e2) {
+ return e1.angleX() < e2.angleX();
+ };
+
+ EdgeRefList Aref, Bref; // We create containers for the references
+ Aref.reserve(A.size()); Bref.reserve(B.size());
+
+ // Fill reference container for the stationary polygon
+ std::for_each(A.begin(), A.end(), [&Aref](MarkedEdge& me) {
+ Aref.emplace_back( ref(me), ref(Aref) );
+ });
+
+ // Fill reference container for the orbiting polygon
+ std::for_each(B.begin(), B.end(), [&Bref](MarkedEdge& me) {
+ Bref.emplace_back( ref(me), ref(Bref) );
+ });
+
+ struct EdgeGroup { typename EdgeRefList::const_iterator first, last; };
+
+ auto mink = [sortfn] // the Mink(Q, R, direction) sub-procedure
+ (const EdgeGroup& Q, const EdgeGroup& R, bool positive)
+ {
+
+ // Step 1 "merge sort_list(Q) and sort_list(R) to form merge_list(Q,R)"
+ // Sort the containers of edge references and merge them.
+ // Q could be sorted only once and be reused here but we would still
+ // need to merge it with sorted(R).
+
+ EdgeRefList merged;
+ EdgeRefList S, seq;
+ merged.reserve((Q.last - Q.first) + (R.last - R.first));
+
+ merged.insert(merged.end(), Q.first, Q.last);
+ merged.insert(merged.end(), R.first, R.last);
+ sort(merged.begin(), merged.end(), sortfn);
+
+ // Step 2 "set i = 1, k = 1, direction = 1, s1 = q1"
+ // we dont use i, instead, q is an iterator into Q. k would be an index
+ // into the merged sequence but we use "it" as an iterator for that
+
+ // here we obtain references for the containers for later comparisons
+ const auto& Rcont = R.first->container.get();
+ const auto& Qcont = Q.first->container.get();
+
+ // Set the intial direction
+ Coord dir = positive? 1 : -1;
+
+ // roughly i = 1 (so q = Q.first) and s1 = q1 so S[0] = q;
+ auto q = Q.first;
+ S.push_back(*q++);
+
+ // Roughly step 3
+ while(q != Q.last) {
+ auto it = merged.begin();
+ while(it != merged.end() && !(it->eq(*(Q.first))) ) {
+ if(it->isFrom(Rcont)) {
+ auto s = *it;
+ s.dir = dir;
+ S.push_back(s);
+ }
+ if(it->eq(*q)) {
+ S.push_back(*q);
+ if(it->isTurningPoint()) dir = -dir;
+ if(q != Q.first) it += dir;
+ }
+ else it += dir;
+ }
+ ++q; // "Set i = i + 1"
+ }
+
+ // Step 4:
+
+ // "Let starting edge r1 be in position si in sequence"
+ // whaaat? I guess this means the following:
+ S[0] = *R.first;
+ auto it = S.begin();
+
+ // "Set j = 1, next = 2, direction = 1, seq1 = si"
+ // we dont use j, seq is expanded dynamically.
+ dir = 1; auto next = std::next(R.first);
+
+ // Step 5:
+ // "If all si edges have been allocated to seqj" should mean that
+ // we loop until seq has equal size with S
+ while(seq.size() < S.size()) {
+ ++it; if(it == S.end()) it = S.begin();
+
+ if(it->isFrom(Qcont)) {
+ seq.push_back(*it); // "If si is from Q, j = j + 1, seqj = si"
+
+ // "If si is a turning point in Q,
+ // direction = - direction, next = next + direction"
+ if(it->isTurningPoint()) { dir = -dir; next += dir; }
+ }
+
+ if(it->eq(*next) && dir == next->dir) { // "If si = direction.rnext"
+ // "j = j + 1, seqj = si, next = next + direction"
+ seq.push_back(*it); next += dir;
+ }
+ }
+
+ return seq;
+ };
+
+ EdgeGroup R{ Bref.begin(), Bref.begin() }, Q{ Aref.begin(), Aref.end() };
+ auto it = Bref.begin();
+ bool orientation = true;
+ EdgeRefList seqlist;
+ seqlist.reserve(3*(Aref.size() + Bref.size()));
+
+ while(it != Bref.end()) // This is step 3 and step 4 in one loop
+ if(it->isTurningPoint()) {
+ R = {R.last, it++};
+ auto seq = mink(Q, R, orientation);
+
+ // TODO step 6 (should be 5 shouldn't it?): linking edges from A
+ // I don't get this step
+
+ seqlist.insert(seqlist.end(), seq.begin(), seq.end());
+ orientation = !orientation;
+ } else ++it;
+
+ if(seqlist.empty()) seqlist = mink(Q, {Bref.begin(), Bref.end()}, true);
+
+ // /////////////////////////////////////////////////////////////////////////
+ // Algorithm 2: breaking Minkowski sums into track line trips
+ // /////////////////////////////////////////////////////////////////////////
+
+
+ // /////////////////////////////////////////////////////////////////////////
+ // Algorithm 3: finding the boundary of the NFP from track line trips
+ // /////////////////////////////////////////////////////////////////////////
+
+
+
+ return Result(stationary, Vertex());
+}
+
+// Specializable NFP implementation class. Specialize it if you have a faster
+// or better NFP implementation
+template<class RawShape, NfpLevel nfptype>
+struct NfpImpl {
+ NfpResult<RawShape> operator()(const RawShape& sh, const RawShape& other)
+ {
+ static_assert(nfptype == NfpLevel::CONVEX_ONLY,
+ "Nfp::noFitPolygon() unimplemented!");
+
+ // Libnest2D has a default implementation for convex polygons and will
+ // use it if feasible.
+ return nfpConvexOnly(sh, other);
+ }
+};
+
+/// Helper function to get the NFP
+template<NfpLevel nfptype, class RawShape>
+inline NfpResult<RawShape> noFitPolygon(const RawShape& sh,
+ const RawShape& other)
+{
+ NfpImpl<RawShape, nfptype> nfps;
+ return nfps(sh, other);
+}
+
+}
+
+}
+
+#endif // GEOMETRIES_NOFITPOLYGON_HPP
diff --git a/xs/src/libnest2d/libnest2d/libnest2d.hpp b/xs/src/libnest2d/libnest2d/libnest2d.hpp
new file mode 100644
index 000000000..4d1e62f99
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/libnest2d.hpp
@@ -0,0 +1,980 @@
+#ifndef LIBNEST2D_HPP
+#define LIBNEST2D_HPP
+
+#include <memory>
+#include <vector>
+#include <map>
+#include <array>
+#include <algorithm>
+#include <functional>
+
+#include "geometry_traits.hpp"
+
+namespace libnest2d {
+
+namespace sl = shapelike;
+namespace pl = pointlike;
+
+/**
+ * \brief An item to be placed on a bin.
+ *
+ * It holds a copy of the original shape object but supports move construction
+ * from the shape objects if its an rvalue reference. This way we can construct
+ * the items without the cost of copying a potentially large amount of input.
+ *
+ * The results of some calculations are cached for maintaining fast run times.
+ * For this reason, memory demands are much higher but this should pay off.
+ */
+template<class RawShape>
+class _Item {
+ using Coord = TCoord<TPoint<RawShape>>;
+ using Vertex = TPoint<RawShape>;
+ using Box = _Box<Vertex>;
+
+ using VertexConstIterator = typename TContour<RawShape>::const_iterator;
+
+ // The original shape that gets encapsulated.
+ RawShape sh_;
+
+ // Transformation data
+ Vertex translation_;
+ Radians rotation_;
+ Coord offset_distance_;
+
+ // Info about whether the transformations will have to take place
+ // This is needed because if floating point is used, it is hard to say
+ // that a zero angle is not a rotation because of testing for equality.
+ bool has_rotation_ = false, has_translation_ = false, has_offset_ = false;
+
+ // For caching the calculations as they can get pretty expensive.
+ mutable RawShape tr_cache_;
+ mutable bool tr_cache_valid_ = false;
+ mutable double area_cache_ = 0;
+ mutable bool area_cache_valid_ = false;
+ mutable RawShape offset_cache_;
+ mutable bool offset_cache_valid_ = false;
+
+ enum class Convexity: char {
+ UNCHECKED,
+ C_TRUE,
+ C_FALSE
+ };
+
+ mutable Convexity convexity_ = Convexity::UNCHECKED;
+ mutable VertexConstIterator rmt_; // rightmost top vertex
+ mutable VertexConstIterator lmb_; // leftmost bottom vertex
+ mutable bool rmt_valid_ = false, lmb_valid_ = false;
+ mutable struct BBCache {
+ Box bb; bool valid;
+ BBCache(): valid(false) {}
+ } bb_cache_;
+
+public:
+
+ /// The type of the shape which was handed over as the template argument.
+ using ShapeType = RawShape;
+
+ /**
+ * \brief Iterator type for the outer vertices.
+ *
+ * Only const iterators can be used. The _Item type is not intended to
+ * modify the carried shapes from the outside. The main purpose of this type
+ * is to cache the calculation results from the various operators it
+ * supports. Giving out a non const iterator would make it impossible to
+ * perform correct cache invalidation.
+ */
+ using Iterator = VertexConstIterator;
+
+ /**
+ * @brief Get the orientation of the polygon.
+ *
+ * The orientation have to be specified as a specialization of the
+ * OrientationType struct which has a Value constant.
+ *
+ * @return The orientation type identifier for the _Item type.
+ */
+ static BP2D_CONSTEXPR Orientation orientation() {
+ return OrientationType<RawShape>::Value;
+ }
+
+ /**
+ * @brief Constructing an _Item form an existing raw shape. The shape will
+ * be copied into the _Item object.
+ * @param sh The original shape object.
+ */
+ explicit inline _Item(const RawShape& sh): sh_(sh) {}
+
+ /**
+ * @brief Construction of an item by moving the content of the raw shape,
+ * assuming that it supports move semantics.
+ * @param sh The original shape object.
+ */
+ explicit inline _Item(RawShape&& sh): sh_(std::move(sh)) {}
+
+ /**
+ * @brief Create an item from an initializer list.
+ * @param il The initializer list of vertices.
+ */
+ inline _Item(const std::initializer_list< Vertex >& il):
+ sh_(sl::create<RawShape>(il)) {}
+
+ inline _Item(const TContour<RawShape>& contour,
+ const THolesContainer<RawShape>& holes = {}):
+ sh_(sl::create<RawShape>(contour, holes)) {}
+
+ inline _Item(TContour<RawShape>&& contour,
+ THolesContainer<RawShape>&& holes):
+ sh_(sl::create<RawShape>(std::move(contour),
+ std::move(holes))) {}
+
+ /**
+ * @brief Convert the polygon to string representation. The format depends
+ * on the implementation of the polygon.
+ * @return
+ */
+ inline std::string toString() const
+ {
+ return sl::toString(sh_);
+ }
+
+ /// Iterator tho the first contour vertex in the polygon.
+ inline Iterator begin() const
+ {
+ return sl::cbegin(sh_);
+ }
+
+ /// Alias to begin()
+ inline Iterator cbegin() const
+ {
+ return sl::cbegin(sh_);
+ }
+
+ /// Iterator to the last contour vertex.
+ inline Iterator end() const
+ {
+ return sl::cend(sh_);
+ }
+
+ /// Alias to end()
+ inline Iterator cend() const
+ {
+ return sl::cend(sh_);
+ }
+
+ /**
+ * @brief Get a copy of an outer vertex within the carried shape.
+ *
+ * Note that the vertex considered here is taken from the original shape
+ * that this item is constructed from. This means that no transformation is
+ * applied to the shape in this call.
+ *
+ * @param idx The index of the requested vertex.
+ * @return A copy of the requested vertex.
+ */
+ inline Vertex vertex(unsigned long idx) const
+ {
+ return sl::vertex(sh_, idx);
+ }
+
+ /**
+ * @brief Modify a vertex.
+ *
+ * Note that this method will invalidate every cached calculation result
+ * including polygon offset and transformations.
+ *
+ * @param idx The index of the requested vertex.
+ * @param v The new vertex data.
+ */
+ inline void setVertex(unsigned long idx, const Vertex& v )
+ {
+ invalidateCache();
+ sl::vertex(sh_, idx) = v;
+ }
+
+ /**
+ * @brief Calculate the shape area.
+ *
+ * The method returns absolute value and does not reflect polygon
+ * orientation. The result is cached, subsequent calls will have very little
+ * cost.
+ * @return The shape area in floating point double precision.
+ */
+ inline double area() const {
+ double ret ;
+ if(area_cache_valid_) ret = area_cache_;
+ else {
+ ret = sl::area(offsettedShape());
+ area_cache_ = ret;
+ area_cache_valid_ = true;
+ }
+ return ret;
+ }
+
+ inline bool isContourConvex() const {
+ bool ret = false;
+
+ switch(convexity_) {
+ case Convexity::UNCHECKED:
+ ret = sl::isConvex<RawShape>(sl::getContour(transformedShape()));
+ convexity_ = ret? Convexity::C_TRUE : Convexity::C_FALSE;
+ break;
+ case Convexity::C_TRUE: ret = true; break;
+ case Convexity::C_FALSE:;
+ }
+
+ return ret;
+ }
+
+ inline bool isHoleConvex(unsigned /*holeidx*/) const {
+ return false;
+ }
+
+ inline bool areHolesConvex() const {
+ return false;
+ }
+
+ /// The number of the outer ring vertices.
+ inline size_t vertexCount() const {
+ return sl::contourVertexCount(sh_);
+ }
+
+ inline size_t holeCount() const {
+ return sl::holeCount(sh_);
+ }
+
+ /**
+ * @brief isPointInside
+ * @param p
+ * @return
+ */
+ inline bool isInside(const Vertex& p) const
+ {
+ return sl::isInside(p, transformedShape());
+ }
+
+ inline bool isInside(const _Item& sh) const
+ {
+ return sl::isInside(transformedShape(), sh.transformedShape());
+ }
+
+ inline bool isInside(const RawShape& sh) const
+ {
+ return sl::isInside(transformedShape(), sh);
+ }
+
+ inline bool isInside(const _Box<TPoint<RawShape>>& box) const;
+ inline bool isInside(const _Circle<TPoint<RawShape>>& box) const;
+
+ inline void translate(const Vertex& d) BP2D_NOEXCEPT
+ {
+ translation(translation() + d);
+ }
+
+ inline void rotate(const Radians& rads) BP2D_NOEXCEPT
+ {
+ rotation(rotation() + rads);
+ }
+
+ inline void addOffset(Coord distance) BP2D_NOEXCEPT
+ {
+ offset_distance_ = distance;
+ has_offset_ = true;
+ invalidateCache();
+ }
+
+ inline void removeOffset() BP2D_NOEXCEPT {
+ has_offset_ = false;
+ invalidateCache();
+ }
+
+ inline Radians rotation() const BP2D_NOEXCEPT
+ {
+ return rotation_;
+ }
+
+ inline TPoint<RawShape> translation() const BP2D_NOEXCEPT
+ {
+ return translation_;
+ }
+
+ inline void rotation(Radians rot) BP2D_NOEXCEPT
+ {
+ if(rotation_ != rot) {
+ rotation_ = rot; has_rotation_ = true; tr_cache_valid_ = false;
+ rmt_valid_ = false; lmb_valid_ = false;
+ bb_cache_.valid = false;
+ }
+ }
+
+ inline void translation(const TPoint<RawShape>& tr) BP2D_NOEXCEPT
+ {
+ if(translation_ != tr) {
+ translation_ = tr; has_translation_ = true; tr_cache_valid_ = false;
+ //bb_cache_.valid = false;
+ }
+ }
+
+ inline const RawShape& transformedShape() const
+ {
+ if(tr_cache_valid_) return tr_cache_;
+
+ RawShape cpy = offsettedShape();
+ if(has_rotation_) sl::rotate(cpy, rotation_);
+ if(has_translation_) sl::translate(cpy, translation_);
+ tr_cache_ = cpy; tr_cache_valid_ = true;
+ rmt_valid_ = false; lmb_valid_ = false;
+
+ return tr_cache_;
+ }
+
+ inline operator RawShape() const
+ {
+ return transformedShape();
+ }
+
+ inline const RawShape& rawShape() const BP2D_NOEXCEPT
+ {
+ return sh_;
+ }
+
+ inline void resetTransformation() BP2D_NOEXCEPT
+ {
+ has_translation_ = false; has_rotation_ = false; has_offset_ = false;
+ invalidateCache();
+ }
+
+ inline Box boundingBox() const {
+ if(!bb_cache_.valid) {
+ if(!has_rotation_)
+ bb_cache_.bb = sl::boundingBox(offsettedShape());
+ else {
+ // TODO make sure this works
+ auto rotsh = offsettedShape();
+ sl::rotate(rotsh, rotation_);
+ bb_cache_.bb = sl::boundingBox(rotsh);
+ }
+ bb_cache_.valid = true;
+ }
+
+ auto &bb = bb_cache_.bb; auto &tr = translation_;
+ return {bb.minCorner() + tr, bb.maxCorner() + tr };
+ }
+
+ inline Vertex referenceVertex() const {
+ return rightmostTopVertex();
+ }
+
+ inline Vertex rightmostTopVertex() const {
+ if(!rmt_valid_ || !tr_cache_valid_) { // find max x and max y vertex
+ auto& tsh = transformedShape();
+ rmt_ = std::max_element(sl::cbegin(tsh), sl::cend(tsh), vsort);
+ rmt_valid_ = true;
+ }
+ return *rmt_;
+ }
+
+ inline Vertex leftmostBottomVertex() const {
+ if(!lmb_valid_ || !tr_cache_valid_) { // find min x and min y vertex
+ auto& tsh = transformedShape();
+ lmb_ = std::min_element(sl::cbegin(tsh), sl::cend(tsh), vsort);
+ lmb_valid_ = true;
+ }
+ return *lmb_;
+ }
+
+ //Static methods:
+
+ inline static bool intersects(const _Item& sh1, const _Item& sh2)
+ {
+ return sl::intersects(sh1.transformedShape(),
+ sh2.transformedShape());
+ }
+
+ inline static bool touches(const _Item& sh1, const _Item& sh2)
+ {
+ return sl::touches(sh1.transformedShape(),
+ sh2.transformedShape());
+ }
+
+private:
+
+ inline const RawShape& offsettedShape() const {
+ if(has_offset_ ) {
+ if(offset_cache_valid_) return offset_cache_;
+
+ offset_cache_ = sh_;
+ sl::offset(offset_cache_, offset_distance_);
+ offset_cache_valid_ = true;
+ return offset_cache_;
+ }
+ return sh_;
+ }
+
+ inline void invalidateCache() const BP2D_NOEXCEPT
+ {
+ tr_cache_valid_ = false;
+ lmb_valid_ = false; rmt_valid_ = false;
+ area_cache_valid_ = false;
+ offset_cache_valid_ = false;
+ bb_cache_.valid = false;
+ convexity_ = Convexity::UNCHECKED;
+ }
+
+ static inline bool vsort(const Vertex& v1, const Vertex& v2)
+ {
+ Coord &&x1 = getX(v1), &&x2 = getX(v2);
+ Coord &&y1 = getY(v1), &&y2 = getY(v2);
+ auto diff = y1 - y2;
+ if(std::abs(diff) <= std::numeric_limits<Coord>::epsilon())
+ return x1 < x2;
+
+ return diff < 0;
+ }
+};
+
+/**
+ * \brief Subclass of _Item for regular rectangle items.
+ */
+template<class RawShape>
+class _Rectangle: public _Item<RawShape> {
+ using _Item<RawShape>::vertex;
+ using TO = Orientation;
+public:
+
+ using Unit = TCoord<TPoint<RawShape>>;
+
+ template<TO o = OrientationType<RawShape>::Value>
+ inline _Rectangle(Unit width, Unit height,
+ // disable this ctor if o != CLOCKWISE
+ enable_if_t< o == TO::CLOCKWISE, int> = 0 ):
+ _Item<RawShape>( sl::create<RawShape>( {
+ {0, 0},
+ {0, height},
+ {width, height},
+ {width, 0},
+ {0, 0}
+ } ))
+ {
+ }
+
+ template<TO o = OrientationType<RawShape>::Value>
+ inline _Rectangle(Unit width, Unit height,
+ // disable this ctor if o != COUNTER_CLOCKWISE
+ enable_if_t< o == TO::COUNTER_CLOCKWISE, int> = 0 ):
+ _Item<RawShape>( sl::create<RawShape>( {
+ {0, 0},
+ {width, 0},
+ {width, height},
+ {0, height},
+ {0, 0}
+ } ))
+ {
+ }
+
+ inline Unit width() const BP2D_NOEXCEPT {
+ return getX(vertex(2));
+ }
+
+ inline Unit height() const BP2D_NOEXCEPT {
+ return getY(vertex(2));
+ }
+};
+
+template<class RawShape>
+inline bool _Item<RawShape>::isInside(const _Box<TPoint<RawShape>>& box) const {
+ return sl::isInside<RawShape>(boundingBox(), box);
+}
+
+template<class RawShape> inline bool
+_Item<RawShape>::isInside(const _Circle<TPoint<RawShape>>& circ) const {
+ return sl::isInside<RawShape>(transformedShape(), circ);
+}
+
+
+template<class I> using _ItemRef = std::reference_wrapper<I>;
+template<class I> using _ItemGroup = std::vector<_ItemRef<I>>;
+
+template<class Iterator>
+struct ConstItemRange {
+ Iterator from;
+ Iterator to;
+ bool valid = false;
+
+ ConstItemRange() = default;
+ ConstItemRange(Iterator f, Iterator t): from(f), to(t), valid(true) {}
+};
+
+template<class Container>
+inline ConstItemRange<typename Container::const_iterator>
+rem(typename Container::const_iterator it, const Container& cont) {
+ return {std::next(it), cont.end()};
+}
+
+/**
+ * \brief A wrapper interface (trait) class for any placement strategy provider.
+ *
+ * If a client wants to use its own placement algorithm, all it has to do is to
+ * specialize this class template and define all the ten methods it has. It can
+ * use the strategies::PlacerBoilerplace class for creating a new placement
+ * strategy where only the constructor and the trypack method has to be provided
+ * and it will work out of the box.
+ */
+template<class PlacementStrategy>
+class PlacementStrategyLike {
+ PlacementStrategy impl_;
+public:
+
+ /// The item type that the placer works with.
+ using Item = typename PlacementStrategy::Item;
+
+ /// The placer's config type. Should be a simple struct but can be anything.
+ using Config = typename PlacementStrategy::Config;
+
+ /**
+ * \brief The type of the bin that the placer works with.
+ *
+ * Can be a box or an arbitrary shape or just a width or height without a
+ * second dimension if an infinite bin is considered.
+ */
+ using BinType = typename PlacementStrategy::BinType;
+
+ /**
+ * \brief Pack result that can be used to accept or discard it. See trypack
+ * method.
+ */
+ using PackResult = typename PlacementStrategy::PackResult;
+
+ using ItemRef = _ItemRef<Item>;
+ using ItemGroup = _ItemGroup<Item>;
+ using DefaultIterator = typename ItemGroup::const_iterator;
+
+ /**
+ * @brief Constructor taking the bin and an optional configuration.
+ * @param bin The bin object whose type is defined by the placement strategy.
+ * @param config The configuration for the particular placer.
+ */
+ explicit PlacementStrategyLike(const BinType& bin,
+ const Config& config = Config()):
+ impl_(bin)
+ {
+ configure(config);
+ }
+
+ /**
+ * @brief Provide a different configuration for the placer.
+ *
+ * Note that it depends on the particular placer implementation how it
+ * reacts to config changes in the middle of a calculation.
+ *
+ * @param config The configuration object defined by the placement strategy.
+ */
+ inline void configure(const Config& config) { impl_.configure(config); }
+
+ /**
+ * Try to pack an item with a result object that contains the packing
+ * information for later accepting it.
+ *
+ * \param item_store A container of items that are intended to be packed
+ * later. Can be used by the placer to switch tactics. When it's knows that
+ * many items will come a greedy strategy may not be the best.
+ * \param from The iterator to the item from which the packing should start,
+ * including the pointed item
+ * \param count How many items should be packed. If the value is 1, than
+ * just the item pointed to by "from" argument should be packed.
+ */
+ template<class Iter = DefaultIterator>
+ inline PackResult trypack(
+ Item& item,
+ const ConstItemRange<Iter>& remaining = ConstItemRange<Iter>())
+ {
+ return impl_.trypack(item, remaining);
+ }
+
+ /**
+ * @brief A method to accept a previously tried item (or items).
+ *
+ * If the pack result is a failure the method should ignore it.
+ * @param r The result of a previous trypack call.
+ */
+ inline void accept(PackResult& r) { impl_.accept(r); }
+
+ /**
+ * @brief pack Try to pack and immediately accept it on success.
+ *
+ * A default implementation would be to call
+ * { auto&& r = trypack(...); accept(r); return r; } but we should let the
+ * implementor of the placement strategy to harvest any optimizations from
+ * the absence of an intermediate step. The above version can still be used
+ * in the implementation.
+ *
+ * @param item The item to pack.
+ * @return Returns true if the item was packed or false if it could not be
+ * packed.
+ */
+ template<class Range = ConstItemRange<DefaultIterator>>
+ inline bool pack(
+ Item& item,
+ const Range& remaining = Range())
+ {
+ return impl_.pack(item, remaining);
+ }
+
+ /// Unpack the last element (remove it from the list of packed items).
+ inline void unpackLast() { impl_.unpackLast(); }
+
+ /// Get the bin object.
+ inline const BinType& bin() const { return impl_.bin(); }
+
+ /// Set a new bin object.
+ inline void bin(const BinType& bin) { impl_.bin(bin); }
+
+ /// Get the packed items.
+ inline ItemGroup getItems() { return impl_.getItems(); }
+
+ /// Clear the packed items so a new session can be started.
+ inline void clearItems() { impl_.clearItems(); }
+
+ inline double filledArea() const { return impl_.filledArea(); }
+
+};
+
+// The progress function will be called with the number of placed items
+using ProgressFunction = std::function<void(unsigned)>;
+
+/**
+ * A wrapper interface (trait) class for any selections strategy provider.
+ */
+template<class SelectionStrategy>
+class SelectionStrategyLike {
+ SelectionStrategy impl_;
+public:
+ using Item = typename SelectionStrategy::Item;
+ using Config = typename SelectionStrategy::Config;
+
+ using ItemRef = std::reference_wrapper<Item>;
+ using ItemGroup = std::vector<ItemRef>;
+
+ /**
+ * @brief Provide a different configuration for the selection strategy.
+ *
+ * Note that it depends on the particular placer implementation how it
+ * reacts to config changes in the middle of a calculation.
+ *
+ * @param config The configuration object defined by the selection strategy.
+ */
+ inline void configure(const Config& config) {
+ impl_.configure(config);
+ }
+
+ /**
+ * @brief A function callback which should be called whenever an item or
+ * a group of items where successfully packed.
+ * @param fn A function callback object taking one unsigned integer as the
+ * number of the remaining items to pack.
+ */
+ void progressIndicator(ProgressFunction fn) { impl_.progressIndicator(fn); }
+
+ /**
+ * \brief A method to start the calculation on the input sequence.
+ *
+ * \tparam TPlacer The only mandatory template parameter is the type of
+ * placer compatible with the PlacementStrategyLike interface.
+ *
+ * \param first, last The first and last iterator if the input sequence. It
+ * can be only an iterator of a type convertible to Item.
+ * \param bin. The shape of the bin. It has to be supported by the placement
+ * strategy.
+ * \param An optional config object for the placer.
+ */
+ template<class TPlacer, class TIterator,
+ class TBin = typename PlacementStrategyLike<TPlacer>::BinType,
+ class PConfig = typename PlacementStrategyLike<TPlacer>::Config>
+ inline void packItems(
+ TIterator first,
+ TIterator last,
+ TBin&& bin,
+ PConfig&& config = PConfig() )
+ {
+ impl_.template packItems<TPlacer>(first, last,
+ std::forward<TBin>(bin),
+ std::forward<PConfig>(config));
+ }
+
+ /**
+ * \brief Get the number of bins opened by the selection algorithm.
+ *
+ * Initially it is zero and after the call to packItems it will return
+ * the number of bins opened by the packing procedure.
+ *
+ * \return The number of bins opened.
+ */
+ inline size_t binCount() const { return impl_.binCount(); }
+
+ /**
+ * @brief Get the items for a particular bin.
+ * @param binIndex The index of the requested bin.
+ * @return Returns a list of all items packed into the requested bin.
+ */
+ inline ItemGroup itemsForBin(size_t binIndex) {
+ return impl_.itemsForBin(binIndex);
+ }
+
+ /// Same as itemsForBin but for a const context.
+ inline const ItemGroup itemsForBin(size_t binIndex) const {
+ return impl_.itemsForBin(binIndex);
+ }
+};
+
+
+/**
+ * \brief A list of packed item vectors. Each vector represents a bin.
+ */
+template<class RawShape>
+using _PackGroup = std::vector<
+ std::vector<
+ std::reference_wrapper<_Item<RawShape>>
+ >
+ >;
+
+/**
+ * \brief A list of packed (index, item) pair vectors. Each vector represents a
+ * bin.
+ *
+ * The index is points to the position of the item in the original input
+ * sequence. This way the caller can use the items as a transformation data
+ * carrier and transform the original objects manually.
+ */
+template<class RawShape>
+using _IndexedPackGroup = std::vector<
+ std::vector<
+ std::pair<
+ unsigned,
+ std::reference_wrapper<_Item<RawShape>>
+ >
+ >
+ >;
+
+/**
+ * The Arranger is the front-end class for the libnest2d library. It takes the
+ * input items and outputs the items with the proper transformations to be
+ * inside the provided bin.
+ */
+template<class PlacementStrategy, class SelectionStrategy >
+class Nester {
+ using TSel = SelectionStrategyLike<SelectionStrategy>;
+ TSel selector_;
+public:
+ using Item = typename PlacementStrategy::Item;
+ using ItemRef = std::reference_wrapper<Item>;
+ using TPlacer = PlacementStrategyLike<PlacementStrategy>;
+ using BinType = typename TPlacer::BinType;
+ using PlacementConfig = typename TPlacer::Config;
+ using SelectionConfig = typename TSel::Config;
+
+ using Unit = TCoord<TPoint<typename Item::ShapeType>>;
+
+ using IndexedPackGroup = _IndexedPackGroup<typename Item::ShapeType>;
+ using PackGroup = _PackGroup<typename Item::ShapeType>;
+ using ResultType = PackGroup;
+ using ResultTypeIndexed = IndexedPackGroup;
+
+private:
+ BinType bin_;
+ PlacementConfig pconfig_;
+ Unit min_obj_distance_;
+
+ using SItem = typename SelectionStrategy::Item;
+ using TPItem = remove_cvref_t<Item>;
+ using TSItem = remove_cvref_t<SItem>;
+
+ std::vector<TPItem> item_cache_;
+
+public:
+
+ /**
+ * \brief Constructor taking the bin as the only mandatory parameter.
+ *
+ * \param bin The bin shape that will be used by the placers. The type
+ * of the bin should be one that is supported by the placer type.
+ */
+ template<class TBinType = BinType,
+ class PConf = PlacementConfig,
+ class SConf = SelectionConfig>
+ Nester( TBinType&& bin,
+ Unit min_obj_distance = 0,
+ PConf&& pconfig = PConf(),
+ SConf&& sconfig = SConf()):
+ bin_(std::forward<TBinType>(bin)),
+ pconfig_(std::forward<PlacementConfig>(pconfig)),
+ min_obj_distance_(min_obj_distance)
+ {
+ static_assert( std::is_same<TPItem, TSItem>::value,
+ "Incompatible placement and selection strategy!");
+
+ selector_.configure(std::forward<SelectionConfig>(sconfig));
+ }
+
+ void configure(const PlacementConfig& pconf) { pconfig_ = pconf; }
+ void configure(const SelectionConfig& sconf) { selector_.configure(sconf); }
+ void configure(const PlacementConfig& pconf, const SelectionConfig& sconf) {
+ pconfig_ = pconf;
+ selector_.configure(sconf);
+ }
+ void configure(const SelectionConfig& sconf, const PlacementConfig& pconf) {
+ pconfig_ = pconf;
+ selector_.configure(sconf);
+ }
+
+ /**
+ * \brief Arrange an input sequence and return a PackGroup object with
+ * the packed groups corresponding to the bins.
+ *
+ * The number of groups in the pack group is the number of bins opened by
+ * the selection algorithm.
+ */
+ template<class TIterator>
+ inline PackGroup execute(TIterator from, TIterator to)
+ {
+ return _execute(from, to);
+ }
+
+ /**
+ * A version of the arrange method returning an IndexedPackGroup with
+ * the item indexes into the original input sequence.
+ *
+ * Takes a little longer to collect the indices. Scales linearly with the
+ * input sequence size.
+ */
+ template<class TIterator>
+ inline IndexedPackGroup executeIndexed(TIterator from, TIterator to)
+ {
+ return _executeIndexed(from, to);
+ }
+
+ /// Shorthand to normal arrange method.
+ template<class TIterator>
+ inline PackGroup operator() (TIterator from, TIterator to)
+ {
+ return _execute(from, to);
+ }
+
+ /// Set a progress indicator function object for the selector.
+ inline Nester& progressIndicator(ProgressFunction func)
+ {
+ selector_.progressIndicator(func); return *this;
+ }
+
+ inline PackGroup lastResult() {
+ PackGroup ret;
+ for(size_t i = 0; i < selector_.binCount(); i++) {
+ auto items = selector_.itemsForBin(i);
+ ret.push_back(items);
+ }
+ return ret;
+ }
+
+private:
+
+ template<class TIterator,
+ class IT = remove_cvref_t<typename TIterator::value_type>,
+
+ // This function will be used only if the iterators are pointing to
+ // a type compatible with the libnets2d::_Item template.
+ // This way we can use references to input elements as they will
+ // have to exist for the lifetime of this call.
+ class T = enable_if_t< std::is_convertible<IT, TPItem>::value, IT>
+ >
+ inline PackGroup _execute(TIterator from, TIterator to, bool = false)
+ {
+ __execute(from, to);
+ return lastResult();
+ }
+
+ template<class TIterator,
+ class IT = remove_cvref_t<typename TIterator::value_type>,
+ class T = enable_if_t<!std::is_convertible<IT, TPItem>::value, IT>
+ >
+ inline PackGroup _execute(TIterator from, TIterator to, int = false)
+ {
+ item_cache_ = {from, to};
+
+ __execute(item_cache_.begin(), item_cache_.end());
+ return lastResult();
+ }
+
+ template<class TIterator,
+ class IT = remove_cvref_t<typename TIterator::value_type>,
+
+ // This function will be used only if the iterators are pointing to
+ // a type compatible with the libnest2d::_Item template.
+ // This way we can use references to input elements as they will
+ // have to exist for the lifetime of this call.
+ class T = enable_if_t< std::is_convertible<IT, TPItem>::value, IT>
+ >
+ inline IndexedPackGroup _executeIndexed(TIterator from,
+ TIterator to,
+ bool = false)
+ {
+ __execute(from, to);
+ return createIndexedPackGroup(from, to, selector_);
+ }
+
+ template<class TIterator,
+ class IT = remove_cvref_t<typename TIterator::value_type>,
+ class T = enable_if_t<!std::is_convertible<IT, TPItem>::value, IT>
+ >
+ inline IndexedPackGroup _executeIndexed(TIterator from,
+ TIterator to,
+ int = false)
+ {
+ item_cache_ = {from, to};
+ __execute(item_cache_.begin(), item_cache_.end());
+ return createIndexedPackGroup(from, to, selector_);
+ }
+
+ template<class TIterator>
+ static IndexedPackGroup createIndexedPackGroup(TIterator from,
+ TIterator to,
+ TSel& selector)
+ {
+ IndexedPackGroup pg;
+ pg.reserve(selector.binCount());
+
+ for(size_t i = 0; i < selector.binCount(); i++) {
+ auto items = selector.itemsForBin(i);
+ pg.push_back({});
+ pg[i].reserve(items.size());
+
+ for(Item& itemA : items) {
+ auto it = from;
+ unsigned idx = 0;
+ while(it != to) {
+ Item& itemB = *it;
+ if(&itemB == &itemA) break;
+ it++; idx++;
+ }
+ pg[i].emplace_back(idx, itemA);
+ }
+ }
+
+ return pg;
+ }
+
+ template<class TIter> inline void __execute(TIter from, TIter to)
+ {
+ if(min_obj_distance_ > 0) std::for_each(from, to, [this](Item& item) {
+ item.addOffset(static_cast<Unit>(std::ceil(min_obj_distance_/2.0)));
+ });
+
+ selector_.template packItems<PlacementStrategy>(
+ from, to, bin_, pconfig_);
+
+ if(min_obj_distance_ > 0) std::for_each(from, to, [](Item& item) {
+ item.removeOffset();
+ });
+ }
+};
+
+}
+
+#endif // LIBNEST2D_HPP
diff --git a/xs/src/libnest2d/libnest2d/metaloop.hpp b/xs/src/libnest2d/libnest2d/metaloop.hpp
new file mode 100644
index 000000000..d88988ba1
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/metaloop.hpp
@@ -0,0 +1,227 @@
+#ifndef METALOOP_HPP
+#define METALOOP_HPP
+
+#include "common.hpp"
+#include <tuple>
+#include <functional>
+
+namespace libnest2d {
+
+/* ************************************************************************** */
+/* C++14 std::index_sequence implementation: */
+/* ************************************************************************** */
+
+/**
+ * \brief C++11 conformant implementation of the index_sequence type from C++14
+ */
+template<size_t...Ints> struct index_sequence {
+ using value_type = size_t;
+ BP2D_CONSTEXPR value_type size() const { return sizeof...(Ints); }
+};
+
+// A Help structure to generate the integer list
+template<size_t...Nseq> struct genSeq;
+
+// Recursive template to generate the list
+template<size_t I, size_t...Nseq> struct genSeq<I, Nseq...> {
+ // Type will contain a genSeq with Nseq appended by one element
+ using Type = typename genSeq< I - 1, I - 1, Nseq...>::Type;
+};
+
+// Terminating recursion
+template <size_t ... Nseq> struct genSeq<0, Nseq...> {
+ // If I is zero, Type will contain index_sequence with the fuly generated
+ // integer list.
+ using Type = index_sequence<Nseq...>;
+};
+
+/// Helper alias to make an index sequence from 0 to N
+template<size_t N> using make_index_sequence = typename genSeq<N>::Type;
+
+/// Helper alias to make an index sequence for a parameter pack
+template<class...Args>
+using index_sequence_for = make_index_sequence<sizeof...(Args)>;
+
+
+/* ************************************************************************** */
+
+namespace opt {
+
+using std::forward;
+using std::tuple;
+using std::get;
+using std::tuple_element;
+
+/**
+ * @brief Helper class to be able to loop over a parameter pack's elements.
+ */
+class metaloop {
+
+// The implementation is based on partial struct template specializations.
+// Basically we need a template type that is callable and takes an integer
+// non-type template parameter which can be used to implement recursive calls.
+//
+// C++11 will not allow the usage of a plain template function that is why we
+// use struct with overloaded call operator. At the same time C++11 prohibits
+// partial template specialization with a non type parameter such as int. We
+// need to wrap that in a type (see metaloop::Int).
+
+/*
+ * A helper alias to create integer values wrapped as a type. It is necessary
+ * because a non type template parameter (such as int) would be prohibited in
+ * a partial specialization. Also for the same reason we have to use a class
+ * _Metaloop instead of a simple function as a functor. A function cannot be
+ * partially specialized in a way that is necessary for this trick.
+ */
+template<int N> using Int = std::integral_constant<int, N>;
+
+/*
+ * Helper class to implement in-place functors.
+ *
+ * We want to be able to use inline functors like a lambda to keep the code
+ * as clear as possible.
+ */
+template<int N, class Fn> class MapFn {
+ Fn&& fn_;
+public:
+
+ // It takes the real functor that can be specified in-place but only
+ // with C++14 because the second parameter's type will depend on the
+ // type of the parameter pack element that is processed. In C++14 we can
+ // specify this second parameter type as auto in the lambda parameter list.
+ inline MapFn(Fn&& fn): fn_(forward<Fn>(fn)) {}
+
+ template<class T> void operator ()(T&& pack_element) {
+ // We provide the index as the first parameter and the pack (or tuple)
+ // element as the second parameter to the functor.
+ fn_(N, forward<T>(pack_element));
+ }
+};
+
+/*
+ * Implementation of the template loop trick.
+ * We create a mechanism for looping over a parameter pack in compile time.
+ * \tparam Idx is the loop index which will be decremented at each recursion.
+ * \tparam Args The parameter pack that will be processed.
+ *
+ */
+template <typename Idx, class...Args>
+class _MetaLoop {};
+
+// Implementation for the first element of Args...
+template <class...Args>
+class _MetaLoop<Int<0>, Args...> {
+public:
+
+ const static BP2D_CONSTEXPR int N = 0;
+ const static BP2D_CONSTEXPR int ARGNUM = sizeof...(Args)-1;
+
+ template<class Tup, class Fn>
+ void run( Tup&& valtup, Fn&& fn) {
+ MapFn<ARGNUM-N, Fn> {forward<Fn>(fn)} (get<ARGNUM-N>(valtup));
+ }
+};
+
+// Implementation for the N-th element of Args...
+template <int N, class...Args>
+class _MetaLoop<Int<N>, Args...> {
+public:
+
+ const static BP2D_CONSTEXPR int ARGNUM = sizeof...(Args)-1;
+
+ template<class Tup, class Fn>
+ void run(Tup&& valtup, Fn&& fn) {
+ MapFn<ARGNUM-N, Fn> {forward<Fn>(fn)} (std::get<ARGNUM-N>(valtup));
+
+ // Recursive call to process the next element of Args
+ _MetaLoop<Int<N-1>, Args...> ().run(forward<Tup>(valtup),
+ forward<Fn>(fn));
+ }
+};
+
+/*
+ * Instantiation: We must instantiate the template with the last index because
+ * the generalized version calls the decremented instantiations recursively.
+ * Once the instantiation with the first index is called, the terminating
+ * version of run is called which does not call itself anymore.
+ *
+ * If you are utterly annoyed, at least you have learned a super crazy
+ * functional meta-programming pattern.
+ */
+template<class...Args>
+using MetaLoop = _MetaLoop<Int<sizeof...(Args)-1>, Args...>;
+
+public:
+
+/**
+ * \brief The final usable function template.
+ *
+ * This is similar to what varags was on C but in compile time C++11.
+ * You can call:
+ * apply(<the mapping function>, <arbitrary number of arguments of any type>);
+ * For example:
+ *
+ * struct mapfunc {
+ * template<class T> void operator()(int N, T&& element) {
+ * std::cout << "The value of the parameter "<< N <<": "
+ * << element << std::endl;
+ * }
+ * };
+ *
+ * apply(mapfunc(), 'a', 10, 151.545);
+ *
+ * C++14:
+ * apply([](int N, auto&& element){
+ * std::cout << "The value of the parameter "<< N <<": "
+ * << element << std::endl;
+ * }, 'a', 10, 151.545);
+ *
+ * This yields the output:
+ * The value of the parameter 0: a
+ * The value of the parameter 1: 10
+ * The value of the parameter 2: 151.545
+ *
+ * As an addition, the function can be called with a tuple as the second
+ * parameter holding the arguments instead of a parameter pack.
+ *
+ */
+template<class...Args, class Fn>
+inline static void apply(Fn&& fn, Args&&...args) {
+ MetaLoop<Args...>().run(tuple<Args&&...>(forward<Args>(args)...),
+ forward<Fn>(fn));
+}
+
+/// The version of apply with a tuple rvalue reference.
+template<class...Args, class Fn>
+inline static void apply(Fn&& fn, tuple<Args...>&& tup) {
+ MetaLoop<Args...>().run(std::move(tup), forward<Fn>(fn));
+}
+
+/// The version of apply with a tuple lvalue reference.
+template<class...Args, class Fn>
+inline static void apply(Fn&& fn, tuple<Args...>& tup) {
+ MetaLoop<Args...>().run(tup, forward<Fn>(fn));
+}
+
+/// The version of apply with a tuple const reference.
+template<class...Args, class Fn>
+inline static void apply(Fn&& fn, const tuple<Args...>& tup) {
+ MetaLoop<Args...>().run(tup, forward<Fn>(fn));
+}
+
+/**
+ * Call a function with its arguments encapsualted in a tuple.
+ */
+template<class Fn, class Tup, std::size_t...Is>
+inline static auto
+callFunWithTuple(Fn&& fn, Tup&& tup, index_sequence<Is...>) ->
+ decltype(fn(std::get<Is>(tup)...))
+{
+ return fn(std::get<Is>(tup)...);
+}
+
+};
+}
+}
+
+#endif // METALOOP_HPP
diff --git a/xs/src/libnest2d/libnest2d/optimizer.hpp b/xs/src/libnest2d/libnest2d/optimizer.hpp
new file mode 100644
index 000000000..90d2f2ff9
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/optimizer.hpp
@@ -0,0 +1,247 @@
+#ifndef OPTIMIZER_HPP
+#define OPTIMIZER_HPP
+
+#include <tuple>
+#include <functional>
+#include <limits>
+#include "common.hpp"
+
+namespace libnest2d { namespace opt {
+
+using std::forward;
+using std::tuple;
+using std::make_tuple;
+
+/// A Type trait for upper and lower limit of a numeric type.
+template<class T, class B = void >
+struct limits {
+ inline static T min() { return std::numeric_limits<T>::min(); }
+ inline static T max() { return std::numeric_limits<T>::max(); }
+};
+
+template<class T>
+struct limits<T, enable_if_t<std::numeric_limits<T>::has_infinity, void>> {
+ inline static T min() { return -std::numeric_limits<T>::infinity(); }
+ inline static T max() { return std::numeric_limits<T>::infinity(); }
+};
+
+/// An interval of possible input values for optimization
+template<class T>
+class Bound {
+ T min_;
+ T max_;
+public:
+ Bound(const T& min = limits<T>::min(),
+ const T& max = limits<T>::max()): min_(min), max_(max) {}
+ inline const T min() const BP2D_NOEXCEPT { return min_; }
+ inline const T max() const BP2D_NOEXCEPT { return max_; }
+};
+
+/**
+ * Helper function to make a Bound object with its type deduced automatically.
+ */
+template<class T>
+inline Bound<T> bound(const T& min, const T& max) { return Bound<T>(min, max); }
+
+/**
+ * This is the type of an input tuple for the object function. It holds the
+ * values and their type in each dimension.
+ */
+template<class...Args> using Input = tuple<Args...>;
+
+template<class...Args>
+inline tuple<Args...> initvals(Args...args) { return make_tuple(args...); }
+
+/**
+ * @brief Specific optimization methods for which a default optimizer
+ * implementation can be instantiated.
+ */
+enum class Method {
+ L_SIMPLEX,
+ L_SUBPLEX,
+ G_GENETIC,
+ //...
+};
+
+/**
+ * @brief Info about result of an optimization. These codes are exactly the same
+ * as the nlopt codes for convinience.
+ */
+enum ResultCodes {
+ FAILURE = -1, /* generic failure code */
+ INVALID_ARGS = -2,
+ OUT_OF_MEMORY = -3,
+ ROUNDOFF_LIMITED = -4,
+ FORCED_STOP = -5,
+ SUCCESS = 1, /* generic success code */
+ STOPVAL_REACHED = 2,
+ FTOL_REACHED = 3,
+ XTOL_REACHED = 4,
+ MAXEVAL_REACHED = 5,
+ MAXTIME_REACHED = 6
+};
+
+/**
+ * \brief A type to hold the complete result of the optimization.
+ */
+template<class...Args>
+struct Result {
+ ResultCodes resultcode;
+ tuple<Args...> optimum;
+ double score;
+};
+
+/**
+ * @brief A type for specifying the stop criteria.
+ */
+struct StopCriteria {
+
+ /// If the absolute value difference between two scores.
+ double absolute_score_difference = std::nan("");
+
+ /// If the relative value difference between two scores.
+ double relative_score_difference = std::nan("");
+
+ /// Stop if this value or better is found.
+ double stop_score = std::nan("");
+
+ unsigned max_iterations = 0;
+};
+
+/**
+ * \brief The Optimizer base class with CRTP pattern.
+ */
+template<class Subclass>
+class Optimizer {
+protected:
+ enum class OptDir{
+ MIN,
+ MAX
+ } dir_;
+
+ StopCriteria stopcr_;
+
+public:
+
+ inline explicit Optimizer(const StopCriteria& scr = {}): stopcr_(scr) {}
+
+ /**
+ * \brief Optimize for minimum value of the provided objectfunction.
+ * \param objectfunction The function that will be searched for the minimum
+ * return value.
+ * \param initvals A tuple with the initial values for the search
+ * \param bounds A parameter pack with the bounds for each dimension.
+ * \return Returns a Result<Args...> structure.
+ * An example call would be:
+ * auto result = opt.optimize_min(
+ * [](tuple<double> x) // object function
+ * {
+ * return std::pow(std::get<0>(x), 2);
+ * },
+ * make_tuple(-0.5), // initial value
+ * {-1.0, 1.0} // search space bounds
+ * );
+ */
+ template<class Func, class...Args>
+ inline Result<Args...> optimize_min(Func&& objectfunction,
+ Input<Args...> initvals,
+ Bound<Args>... bounds)
+ {
+ dir_ = OptDir::MIN;
+ return static_cast<Subclass*>(this)->template optimize<Func, Args...>(
+ forward<Func>(objectfunction), initvals, bounds... );
+ }
+
+ template<class Func, class...Args>
+ inline Result<Args...> optimize_min(Func&& objectfunction,
+ Input<Args...> initvals)
+ {
+ dir_ = OptDir::MIN;
+ return static_cast<Subclass*>(this)->template optimize<Func, Args...>(
+ objectfunction, initvals, Bound<Args>()... );
+ }
+
+ template<class...Args, class Func>
+ inline Result<Args...> optimize_min(Func&& objectfunction)
+ {
+ dir_ = OptDir::MIN;
+ return static_cast<Subclass*>(this)->template optimize<Func, Args...>(
+ objectfunction,
+ Input<Args...>(),
+ Bound<Args>()... );
+ }
+
+ /// Same as optimize_min but optimizes for maximum function value.
+ template<class Func, class...Args>
+ inline Result<Args...> optimize_max(Func&& objectfunction,
+ Input<Args...> initvals,
+ Bound<Args>... bounds)
+ {
+ dir_ = OptDir::MAX;
+ return static_cast<Subclass*>(this)->template optimize<Func, Args...>(
+ objectfunction, initvals, bounds... );
+ }
+
+ template<class Func, class...Args>
+ inline Result<Args...> optimize_max(Func&& objectfunction,
+ Input<Args...> initvals)
+ {
+ dir_ = OptDir::MAX;
+ return static_cast<Subclass*>(this)->template optimize<Func, Args...>(
+ objectfunction, initvals, Bound<Args>()... );
+ }
+
+ template<class...Args, class Func>
+ inline Result<Args...> optimize_max(Func&& objectfunction)
+ {
+ dir_ = OptDir::MAX;
+ return static_cast<Subclass*>(this)->template optimize<Func, Args...>(
+ objectfunction,
+ Input<Args...>(),
+ Bound<Args>()... );
+ }
+
+};
+
+// Just to be able to instantiate an unimplemented method and generate compile
+// error.
+template<class T = void>
+class DummyOptimizer : public Optimizer<DummyOptimizer<T>> {
+ friend class Optimizer<DummyOptimizer<T>>;
+
+public:
+ DummyOptimizer() {
+ static_assert(always_false<T>::value, "Optimizer unimplemented!");
+ }
+
+ DummyOptimizer(const StopCriteria&) {
+ static_assert(always_false<T>::value, "Optimizer unimplemented!");
+ }
+
+ template<class Func, class...Args>
+ Result<Args...> optimize(Func&& /*func*/,
+ tuple<Args...> /*initvals*/,
+ Bound<Args>... /*args*/)
+ {
+ return Result<Args...>();
+ }
+};
+
+// Specializing this struct will tell what kind of optimizer to generate for
+// a given method
+template<Method m> struct OptimizerSubclass { using Type = DummyOptimizer<>; };
+
+/// Optimizer type based on the method provided in parameter m.
+template<Method m> using TOptimizer = typename OptimizerSubclass<m>::Type;
+
+/// Global optimizer with an explicitly specified local method.
+template<Method m>
+inline TOptimizer<m> GlobalOptimizer(Method, const StopCriteria& scr = {})
+{ // Need to be specialized in order to do anything useful.
+ return TOptimizer<m>(scr);
+}
+
+}
+}
+
+#endif // OPTIMIZER_HPP
diff --git a/xs/src/libnest2d/libnest2d/optimizers/genetic.hpp b/xs/src/libnest2d/libnest2d/optimizers/genetic.hpp
new file mode 100644
index 000000000..276854a12
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/optimizers/genetic.hpp
@@ -0,0 +1,31 @@
+#ifndef GENETIC_HPP
+#define GENETIC_HPP
+
+#include "nlopt_boilerplate.hpp"
+
+namespace libnest2d { namespace opt {
+
+class GeneticOptimizer: public NloptOptimizer {
+public:
+ inline explicit GeneticOptimizer(const StopCriteria& scr = {}):
+ NloptOptimizer(method2nloptAlg(Method::G_GENETIC), scr) {}
+
+ inline GeneticOptimizer& localMethod(Method m) {
+ localmethod_ = m;
+ return *this;
+ }
+};
+
+template<>
+struct OptimizerSubclass<Method::G_GENETIC> { using Type = GeneticOptimizer; };
+
+template<> TOptimizer<Method::G_GENETIC> GlobalOptimizer<Method::G_GENETIC>(
+ Method localm, const StopCriteria& scr )
+{
+ return GeneticOptimizer (scr).localMethod(localm);
+}
+
+}
+}
+
+#endif // GENETIC_HPP
diff --git a/xs/src/libnest2d/libnest2d/optimizers/nlopt_boilerplate.hpp b/xs/src/libnest2d/libnest2d/optimizers/nlopt_boilerplate.hpp
new file mode 100644
index 000000000..1a0f06e02
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/optimizers/nlopt_boilerplate.hpp
@@ -0,0 +1,186 @@
+#ifndef NLOPT_BOILERPLATE_HPP
+#define NLOPT_BOILERPLATE_HPP
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4244)
+#pragma warning(disable: 4267)
+#endif
+#include <nlopt.hpp>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#include <libnest2d/optimizer.hpp>
+#include <cassert>
+#include "libnest2d/metaloop.hpp"
+
+#include <utility>
+
+namespace libnest2d { namespace opt {
+
+inline nlopt::algorithm method2nloptAlg(Method m) {
+
+ switch(m) {
+ case Method::L_SIMPLEX: return nlopt::LN_NELDERMEAD;
+ case Method::L_SUBPLEX: return nlopt::LN_SBPLX;
+ case Method::G_GENETIC: return nlopt::GN_ESCH;
+ default: assert(false); throw(m);
+ }
+}
+
+/**
+ * Optimizer based on NLopt.
+ *
+ * All the optimized types have to be convertible to double.
+ */
+class NloptOptimizer: public Optimizer<NloptOptimizer> {
+protected:
+ nlopt::opt opt_;
+ std::vector<double> lower_bounds_;
+ std::vector<double> upper_bounds_;
+ std::vector<double> initvals_;
+ nlopt::algorithm alg_;
+ Method localmethod_;
+
+ using Base = Optimizer<NloptOptimizer>;
+
+ friend Base;
+
+ // ********************************************************************** */
+
+ // TODO: CHANGE FOR LAMBDAS WHEN WE WILL MOVE TO C++14
+
+ struct BoundsFunc {
+ NloptOptimizer& self;
+ inline explicit BoundsFunc(NloptOptimizer& o): self(o) {}
+
+ template<class T> void operator()(int N, T& bounds)
+ {
+ self.lower_bounds_[N] = bounds.min();
+ self.upper_bounds_[N] = bounds.max();
+ }
+ };
+
+ struct InitValFunc {
+ NloptOptimizer& self;
+ inline explicit InitValFunc(NloptOptimizer& o): self(o) {}
+
+ template<class T> void operator()(int N, T& initval)
+ {
+ self.initvals_[N] = initval;
+ }
+ };
+
+ struct ResultCopyFunc {
+ NloptOptimizer& self;
+ inline explicit ResultCopyFunc(NloptOptimizer& o): self(o) {}
+
+ template<class T> void operator()(int N, T& resultval)
+ {
+ resultval = self.initvals_[N];
+ }
+ };
+
+ struct FunvalCopyFunc {
+ using D = const std::vector<double>;
+ D& params;
+ inline explicit FunvalCopyFunc(D& p): params(p) {}
+
+ template<class T> void operator()(int N, T& resultval)
+ {
+ resultval = params[N];
+ }
+ };
+
+ /* ********************************************************************** */
+
+ template<class Fn, class...Args>
+ static double optfunc(const std::vector<double>& params,
+ std::vector<double>& /*grad*/,
+ void *data)
+ {
+ auto fnptr = static_cast<remove_ref_t<Fn>*>(data);
+ auto funval = std::tuple<Args...>();
+
+ // copy the obtained objectfunction arguments to the funval tuple.
+ metaloop::apply(FunvalCopyFunc(params), funval);
+
+ auto ret = metaloop::callFunWithTuple(*fnptr, funval,
+ index_sequence_for<Args...>());
+
+ return ret;
+ }
+
+ template<class Func, class...Args>
+ Result<Args...> optimize(Func&& func,
+ std::tuple<Args...> initvals,
+ Bound<Args>... args)
+ {
+ lower_bounds_.resize(sizeof...(Args));
+ upper_bounds_.resize(sizeof...(Args));
+ initvals_.resize(sizeof...(Args));
+
+ opt_ = nlopt::opt(alg_, sizeof...(Args) );
+
+ // Copy the bounds which is obtained as a parameter pack in args into
+ // lower_bounds_ and upper_bounds_
+ metaloop::apply(BoundsFunc(*this), args...);
+
+ opt_.set_lower_bounds(lower_bounds_);
+ opt_.set_upper_bounds(upper_bounds_);
+
+ nlopt::opt localopt;
+ switch(opt_.get_algorithm()) {
+ case nlopt::GN_MLSL:
+ case nlopt::GN_MLSL_LDS:
+ localopt = nlopt::opt(method2nloptAlg(localmethod_),
+ sizeof...(Args));
+ localopt.set_lower_bounds(lower_bounds_);
+ localopt.set_upper_bounds(upper_bounds_);
+ opt_.set_local_optimizer(localopt);
+ default: ;
+ }
+
+ double abs_diff = stopcr_.absolute_score_difference;
+ double rel_diff = stopcr_.relative_score_difference;
+ double stopval = stopcr_.stop_score;
+ if(!std::isnan(abs_diff)) opt_.set_ftol_abs(abs_diff);
+ if(!std::isnan(rel_diff)) opt_.set_ftol_rel(rel_diff);
+ if(!std::isnan(stopval)) opt_.set_stopval(stopval);
+
+ if(this->stopcr_.max_iterations > 0)
+ opt_.set_maxeval(this->stopcr_.max_iterations );
+
+ // Take care of the initial values, copy them to initvals_
+ metaloop::apply(InitValFunc(*this), initvals);
+
+ switch(dir_) {
+ case OptDir::MIN:
+ opt_.set_min_objective(optfunc<Func, Args...>, &func); break;
+ case OptDir::MAX:
+ opt_.set_max_objective(optfunc<Func, Args...>, &func); break;
+ }
+
+ Result<Args...> result;
+
+ auto rescode = opt_.optimize(initvals_, result.score);
+ result.resultcode = static_cast<ResultCodes>(rescode);
+
+ metaloop::apply(ResultCopyFunc(*this), result.optimum);
+
+ return result;
+ }
+
+public:
+ inline explicit NloptOptimizer(nlopt::algorithm alg,
+ StopCriteria stopcr = {}):
+ Base(stopcr), alg_(alg), localmethod_(Method::L_SIMPLEX) {}
+
+};
+
+}
+}
+
+
+#endif // NLOPT_BOILERPLATE_HPP
diff --git a/xs/src/libnest2d/libnest2d/optimizers/simplex.hpp b/xs/src/libnest2d/libnest2d/optimizers/simplex.hpp
new file mode 100644
index 000000000..78b09b89a
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/optimizers/simplex.hpp
@@ -0,0 +1,20 @@
+#ifndef SIMPLEX_HPP
+#define SIMPLEX_HPP
+
+#include "nlopt_boilerplate.hpp"
+
+namespace libnest2d { namespace opt {
+
+class SimplexOptimizer: public NloptOptimizer {
+public:
+ inline explicit SimplexOptimizer(const StopCriteria& scr = {}):
+ NloptOptimizer(method2nloptAlg(Method::L_SIMPLEX), scr) {}
+};
+
+template<>
+struct OptimizerSubclass<Method::L_SIMPLEX> { using Type = SimplexOptimizer; };
+
+}
+}
+
+#endif // SIMPLEX_HPP
diff --git a/xs/src/libnest2d/libnest2d/optimizers/subplex.hpp b/xs/src/libnest2d/libnest2d/optimizers/subplex.hpp
new file mode 100644
index 000000000..841b04057
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/optimizers/subplex.hpp
@@ -0,0 +1,20 @@
+#ifndef SUBPLEX_HPP
+#define SUBPLEX_HPP
+
+#include "nlopt_boilerplate.hpp"
+
+namespace libnest2d { namespace opt {
+
+class SubplexOptimizer: public NloptOptimizer {
+public:
+ inline explicit SubplexOptimizer(const StopCriteria& scr = {}):
+ NloptOptimizer(method2nloptAlg(Method::L_SUBPLEX), scr) {}
+};
+
+template<>
+struct OptimizerSubclass<Method::L_SUBPLEX> { using Type = SubplexOptimizer; };
+
+}
+}
+
+#endif // SUBPLEX_HPP
diff --git a/xs/src/libnest2d/libnest2d/placers/bottomleftplacer.hpp b/xs/src/libnest2d/libnest2d/placers/bottomleftplacer.hpp
new file mode 100644
index 000000000..18c27c40c
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/placers/bottomleftplacer.hpp
@@ -0,0 +1,412 @@
+#ifndef BOTTOMLEFT_HPP
+#define BOTTOMLEFT_HPP
+
+#include <limits>
+
+#include "placer_boilerplate.hpp"
+
+namespace libnest2d { namespace placers {
+
+template<class T, class = T> struct Epsilon {};
+
+template<class T>
+struct Epsilon<T, enable_if_t<std::is_integral<T>::value, T> > {
+ static const T Value = 1;
+};
+
+template<class T>
+struct Epsilon<T, enable_if_t<std::is_floating_point<T>::value, T> > {
+ static const T Value = 1e-3;
+};
+
+template<class RawShape>
+struct BLConfig {
+ DECLARE_MAIN_TYPES(RawShape);
+
+ Coord min_obj_distance = 0;
+ Coord epsilon = Epsilon<Coord>::Value;
+ bool allow_rotations = false;
+};
+
+template<class RawShape>
+class _BottomLeftPlacer: public PlacerBoilerplate<
+ _BottomLeftPlacer<RawShape>,
+ RawShape, _Box<TPoint<RawShape>>,
+ BLConfig<RawShape> >
+{
+ using Base = PlacerBoilerplate<_BottomLeftPlacer<RawShape>, RawShape,
+ _Box<TPoint<RawShape>>, BLConfig<RawShape>>;
+ DECLARE_PLACER(Base)
+
+public:
+
+ explicit _BottomLeftPlacer(const BinType& bin): Base(bin) {}
+
+ template<class Range = ConstItemRange<typename Base::DefaultIter>>
+ PackResult trypack(Item& item,
+ const Range& = Range())
+ {
+ auto r = _trypack(item);
+ if(!r && Base::config_.allow_rotations) {
+
+ item.rotate(Degrees(90));
+ r =_trypack(item);
+ }
+ return r;
+ }
+
+ enum class Dir {
+ LEFT,
+ DOWN
+ };
+
+ inline RawShape leftPoly(const Item& item) const {
+ return toWallPoly(item, Dir::LEFT);
+ }
+
+ inline RawShape downPoly(const Item& item) const {
+ return toWallPoly(item, Dir::DOWN);
+ }
+
+ inline Unit availableSpaceLeft(const Item& item) {
+ return availableSpace(item, Dir::LEFT);
+ }
+
+ inline Unit availableSpaceDown(const Item& item) {
+ return availableSpace(item, Dir::DOWN);
+ }
+
+protected:
+
+ PackResult _trypack(Item& item) {
+
+ // Get initial position for item in the top right corner
+ setInitialPosition(item);
+
+ Unit d = availableSpaceDown(item);
+ auto eps = config_.epsilon;
+ bool can_move = d > eps;
+ bool can_be_packed = can_move;
+ bool left = true;
+
+ while(can_move) {
+ if(left) { // write previous down move and go down
+ item.translate({0, -d+eps});
+ d = availableSpaceLeft(item);
+ can_move = d > eps;
+ left = false;
+ } else { // write previous left move and go down
+ item.translate({-d+eps, 0});
+ d = availableSpaceDown(item);
+ can_move = d > eps;
+ left = true;
+ }
+ }
+
+ if(can_be_packed) {
+ Item trsh(item.transformedShape());
+ for(auto& v : trsh) can_be_packed = can_be_packed &&
+ getX(v) < bin_.width() &&
+ getY(v) < bin_.height();
+ }
+
+ return can_be_packed? PackResult(item) : PackResult();
+ }
+
+ void setInitialPosition(Item& item) {
+ auto bb = item.boundingBox();
+
+ Vertex v = { getX(bb.maxCorner()), getY(bb.minCorner()) };
+
+
+ Coord dx = getX(bin_.maxCorner()) - getX(v);
+ Coord dy = getY(bin_.maxCorner()) - getY(v);
+
+ item.translate({dx, dy});
+ }
+
+ template<class C = Coord>
+ static enable_if_t<std::is_floating_point<C>::value, bool>
+ isInTheWayOf( const Item& item,
+ const Item& other,
+ const RawShape& scanpoly)
+ {
+ auto tsh = other.transformedShape();
+ return ( sl::intersects(tsh, scanpoly) ||
+ sl::isInside(tsh, scanpoly) ) &&
+ ( !sl::intersects(tsh, item.rawShape()) &&
+ !sl::isInside(tsh, item.rawShape()) );
+ }
+
+ template<class C = Coord>
+ static enable_if_t<std::is_integral<C>::value, bool>
+ isInTheWayOf( const Item& item,
+ const Item& other,
+ const RawShape& scanpoly)
+ {
+ auto tsh = other.transformedShape();
+
+ bool inters_scanpoly = sl::intersects(tsh, scanpoly) &&
+ !sl::touches(tsh, scanpoly);
+ bool inters_item = sl::intersects(tsh, item.rawShape()) &&
+ !sl::touches(tsh, item.rawShape());
+
+ return ( inters_scanpoly ||
+ sl::isInside(tsh, scanpoly)) &&
+ ( !inters_item &&
+ !sl::isInside(tsh, item.rawShape())
+ );
+ }
+
+ ItemGroup itemsInTheWayOf(const Item& item, const Dir dir) {
+ // Get the left or down polygon, that has the same area as the shadow
+ // of input item reflected to the left or downwards
+ auto&& scanpoly = dir == Dir::LEFT? leftPoly(item) :
+ downPoly(item);
+
+ ItemGroup ret; // packed items 'in the way' of item
+ ret.reserve(items_.size());
+
+ // Predicate to find items that are 'in the way' for left (down) move
+ auto predicate = [&scanpoly, &item](const Item& it) {
+ return isInTheWayOf(item, it, scanpoly);
+ };
+
+ // Get the items that are in the way for the left (or down) movement
+ std::copy_if(items_.begin(), items_.end(),
+ std::back_inserter(ret), predicate);
+
+ return ret;
+ }
+
+ Unit availableSpace(const Item& _item, const Dir dir) {
+
+ Item item (_item.transformedShape());
+
+
+ std::function<Coord(const Vertex&)> getCoord;
+ std::function< std::pair<Coord, bool>(const Segment&, const Vertex&) >
+ availableDistanceSV;
+
+ std::function< std::pair<Coord, bool>(const Vertex&, const Segment&) >
+ availableDistance;
+
+ if(dir == Dir::LEFT) {
+ getCoord = [](const Vertex& v) { return getX(v); };
+ availableDistance = pointlike::horizontalDistance<Vertex>;
+ availableDistanceSV = [](const Segment& s, const Vertex& v) {
+ auto ret = pointlike::horizontalDistance<Vertex>(v, s);
+ if(ret.second) ret.first = -ret.first;
+ return ret;
+ };
+ }
+ else {
+ getCoord = [](const Vertex& v) { return getY(v); };
+ availableDistance = pointlike::verticalDistance<Vertex>;
+ availableDistanceSV = [](const Segment& s, const Vertex& v) {
+ auto ret = pointlike::verticalDistance<Vertex>(v, s);
+ if(ret.second) ret.first = -ret.first;
+ return ret;
+ };
+ }
+
+ auto&& items_in_the_way = itemsInTheWayOf(item, dir);
+
+ // Comparison function for finding min vertex
+ auto cmp = [&getCoord](const Vertex& v1, const Vertex& v2) {
+ return getCoord(v1) < getCoord(v2);
+ };
+
+ // find minimum left or down coordinate of item
+ auto minvertex_it = std::min_element(item.begin(),
+ item.end(),
+ cmp);
+
+ // Get the initial distance in floating point
+ Unit m = getCoord(*minvertex_it);
+
+ // Check available distance for every vertex of item to the objects
+ // in the way for the nearest intersection
+ if(!items_in_the_way.empty()) { // This is crazy, should be optimized...
+ for(Item& pleft : items_in_the_way) {
+ // For all segments in items_to_left
+
+ assert(pleft.vertexCount() > 0);
+
+ auto trpleft = pleft.transformedShape();
+ auto first = sl::begin(trpleft);
+ auto next = first + 1;
+ auto endit = sl::end(trpleft);
+
+ while(next != endit) {
+ Segment seg(*(first++), *(next++));
+ for(auto& v : item) { // For all vertices in item
+
+ auto d = availableDistance(v, seg);
+
+ if(d.second && d.first < m) m = d.first;
+ }
+ }
+ }
+
+ auto first = item.begin();
+ auto next = first + 1;
+ auto endit = item.end();
+
+ // For all edges in item:
+ while(next != endit) {
+ Segment seg(*(first++), *(next++));
+
+ // for all shapes in items_to_left
+ for(Item& sh : items_in_the_way) {
+ assert(sh.vertexCount() > 0);
+
+ Item tsh(sh.transformedShape());
+ for(auto& v : tsh) { // For all vertices in item
+
+ auto d = availableDistanceSV(seg, v);
+
+ if(d.second && d.first < m) m = d.first;
+ }
+ }
+ }
+ }
+
+ return m;
+ }
+
+ /**
+ * Implementation of the left (and down) polygon as described by
+ * [López-Camacho et al. 2013]\
+ * (http://www.cs.stir.ac.uk/~goc/papers/EffectiveHueristic2DAOR2013.pdf)
+ * see algorithm 8 for details...
+ */
+ RawShape toWallPoly(const Item& _item, const Dir dir) const {
+ // The variable names reflect the case of left polygon calculation.
+ //
+ // We will iterate through the item's vertices and search for the top
+ // and bottom vertices (or right and left if dir==Dir::DOWN).
+ // Save the relevant vertices and their indices into `bottom` and
+ // `top` vectors. In case of left polygon construction these will
+ // contain the top and bottom polygons which have the same vertical
+ // coordinates (in case there is more of them).
+ //
+ // We get the leftmost (or downmost) vertex from the `bottom` and `top`
+ // vectors and construct the final polygon.
+
+ Item item (_item.transformedShape());
+
+ auto getCoord = [dir](const Vertex& v) {
+ return dir == Dir::LEFT? getY(v) : getX(v);
+ };
+
+ Coord max_y = std::numeric_limits<Coord>::min();
+ Coord min_y = std::numeric_limits<Coord>::max();
+
+ using El = std::pair<size_t, std::reference_wrapper<const Vertex>>;
+
+ std::function<bool(const El&, const El&)> cmp;
+
+ if(dir == Dir::LEFT)
+ cmp = [](const El& e1, const El& e2) {
+ return getX(e1.second.get()) < getX(e2.second.get());
+ };
+ else
+ cmp = [](const El& e1, const El& e2) {
+ return getY(e1.second.get()) < getY(e2.second.get());
+ };
+
+ std::vector< El > top;
+ std::vector< El > bottom;
+
+ size_t idx = 0;
+ for(auto& v : item) { // Find the bottom and top vertices and save them
+ auto vref = std::cref(v);
+ auto vy = getCoord(v);
+
+ if( vy > max_y ) {
+ max_y = vy;
+ top.clear();
+ top.emplace_back(idx, vref);
+ }
+ else if(vy == max_y) { top.emplace_back(idx, vref); }
+
+ if(vy < min_y) {
+ min_y = vy;
+ bottom.clear();
+ bottom.emplace_back(idx, vref);
+ }
+ else if(vy == min_y) { bottom.emplace_back(idx, vref); }
+
+ idx++;
+ }
+
+ // Get the top and bottom leftmost vertices, or the right and left
+ // downmost vertices (if dir == Dir::DOWN)
+ auto topleft_it = std::min_element(top.begin(), top.end(), cmp);
+ auto bottomleft_it =
+ std::min_element(bottom.begin(), bottom.end(), cmp);
+
+ auto& topleft_vertex = topleft_it->second.get();
+ auto& bottomleft_vertex = bottomleft_it->second.get();
+
+ // Start and finish positions for the vertices that will be part of the
+ // new polygon
+ auto start = std::min(topleft_it->first, bottomleft_it->first);
+ auto finish = std::max(topleft_it->first, bottomleft_it->first);
+
+ // the return shape
+ RawShape rsh;
+
+ // reserve for all vertices plus 2 for the left horizontal wall, 2 for
+ // the additional vertices for maintaning min object distance
+ sl::reserve(rsh, finish-start+4);
+
+ /*auto addOthers = [&rsh, finish, start, &item](){
+ for(size_t i = start+1; i < finish; i++)
+ sl::addVertex(rsh, item.vertex(i));
+ };*/
+
+ auto reverseAddOthers = [&rsh, finish, start, &item](){
+ for(auto i = finish-1; i > start; i--)
+ sl::addVertex(rsh, item.vertex(
+ static_cast<unsigned long>(i)));
+ };
+
+ // Final polygon construction...
+
+ static_assert(OrientationType<RawShape>::Value ==
+ Orientation::CLOCKWISE,
+ "Counter clockwise toWallPoly() Unimplemented!");
+
+ // Clockwise polygon construction
+
+ sl::addVertex(rsh, topleft_vertex);
+
+ if(dir == Dir::LEFT) reverseAddOthers();
+ else {
+ sl::addVertex(rsh, getX(topleft_vertex), 0);
+ sl::addVertex(rsh, getX(bottomleft_vertex), 0);
+ }
+
+ sl::addVertex(rsh, bottomleft_vertex);
+
+ if(dir == Dir::LEFT) {
+ sl::addVertex(rsh, 0, getY(bottomleft_vertex));
+ sl::addVertex(rsh, 0, getY(topleft_vertex));
+ }
+ else reverseAddOthers();
+
+
+ // Close the polygon
+ sl::addVertex(rsh, topleft_vertex);
+
+ return rsh;
+ }
+
+};
+
+}
+}
+
+#endif //BOTTOMLEFT_HPP
diff --git a/xs/src/libnest2d/libnest2d/placers/nfpplacer.hpp b/xs/src/libnest2d/libnest2d/placers/nfpplacer.hpp
new file mode 100644
index 000000000..c86fb507e
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/placers/nfpplacer.hpp
@@ -0,0 +1,1205 @@
+#ifndef NOFITPOLY_HPP
+#define NOFITPOLY_HPP
+
+#include <cassert>
+
+// For caching nfps
+#include <unordered_map>
+
+// For parallel for
+#include <functional>
+#include <iterator>
+#include <future>
+#include <atomic>
+
+#ifndef NDEBUG
+#include <iostream>
+#endif
+#include "placer_boilerplate.hpp"
+#include "../geometry_traits_nfp.hpp"
+#include "libnest2d/optimizer.hpp"
+
+#include "tools/svgtools.hpp"
+
+#ifdef USE_TBB
+#include <tbb/parallel_for.h>
+#elif defined(_OPENMP)
+#include <omp.h>
+#endif
+
+namespace libnest2d {
+
+namespace __parallel {
+
+using std::function;
+using std::iterator_traits;
+template<class It>
+using TIteratorValue = typename iterator_traits<It>::value_type;
+
+template<class Iterator>
+inline void enumerate(
+ Iterator from, Iterator to,
+ function<void(TIteratorValue<Iterator>, size_t)> fn,
+ std::launch policy = std::launch::deferred | std::launch::async)
+{
+ using TN = size_t;
+ auto iN = to-from;
+ TN N = iN < 0? 0 : TN(iN);
+
+#ifdef USE_TBB
+ if((policy & std::launch::async) == std::launch::async) {
+ tbb::parallel_for<TN>(0, N, [from, fn] (TN n) { fn(*(from + n), n); } );
+ } else {
+ for(TN n = 0; n < N; n++) fn(*(from + n), n);
+ }
+#elif defined(_OPENMP)
+ if((policy & std::launch::async) == std::launch::async) {
+ #pragma omp parallel for
+ for(TN n = 0; n < N; n++) fn(*(from + n), n);
+ }
+ else {
+ for(TN n = 0; n < N; n++) fn(*(from + n), n);
+ }
+#else
+ std::vector<std::future<void>> rets(N);
+
+ auto it = from;
+ for(TN b = 0; b < N; b++) {
+ rets[b] = std::async(policy, fn, *it++, unsigned(b));
+ }
+
+ for(TN fi = 0; fi < N; ++fi) rets[fi].wait();
+#endif
+}
+
+class SpinLock {
+ static std::atomic_flag locked;
+public:
+ void lock() {
+ while (locked.test_and_set(std::memory_order_acquire)) { ; }
+ }
+ void unlock() {
+ locked.clear(std::memory_order_release);
+ }
+};
+
+std::atomic_flag SpinLock::locked = ATOMIC_FLAG_INIT ;
+
+}
+
+namespace __itemhash {
+
+using Key = size_t;
+
+template<class S>
+Key hash(const _Item<S>& item) {
+ using Point = TPoint<S>;
+ using Segment = _Segment<Point>;
+
+ static const int N = 26;
+ static const int M = N*N - 1;
+
+ std::string ret;
+ auto& rhs = item.rawShape();
+ auto& ctr = sl::getContour(rhs);
+ auto it = ctr.begin();
+ auto nx = std::next(it);
+
+ double circ = 0;
+ while(nx != ctr.end()) {
+ Segment seg(*it++, *nx++);
+ Radians a = seg.angleToXaxis();
+ double deg = Degrees(a);
+ int ms = 'A', ls = 'A';
+ while(deg > N) { ms++; deg -= N; }
+ ls += int(deg);
+ ret.push_back(char(ms)); ret.push_back(char(ls));
+ circ += seg.length();
+ }
+
+ it = ctr.begin(); nx = std::next(it);
+
+ while(nx != ctr.end()) {
+ Segment seg(*it++, *nx++);
+ auto l = int(M * seg.length() / circ);
+ int ms = 'A', ls = 'A';
+ while(l > N) { ms++; l -= N; }
+ ls += l;
+ ret.push_back(char(ms)); ret.push_back(char(ls));
+ }
+
+ return std::hash<std::string>()(ret);
+}
+
+template<class S>
+using Hash = std::unordered_map<Key, nfp::NfpResult<S>>;
+
+}
+
+namespace placers {
+
+template<class RawShape>
+struct NfpPConfig {
+
+ using ItemGroup = _ItemGroup<_Item<RawShape>>;
+
+ enum class Alignment {
+ CENTER,
+ BOTTOM_LEFT,
+ BOTTOM_RIGHT,
+ TOP_LEFT,
+ TOP_RIGHT,
+ };
+
+ /// Which angles to try out for better results.
+ std::vector<Radians> rotations;
+
+ /// Where to align the resulting packed pile.
+ Alignment alignment;
+
+ /// Where to start putting objects in the bin.
+ Alignment starting_point;
+
+ /**
+ * @brief A function object representing the fitting function in the
+ * placement optimization process. (Optional)
+ *
+ * This is the most versatile tool to configure the placer. The fitting
+ * function is evaluated many times when a new item is being placed into the
+ * bin. The output should be a rated score of the new item's position.
+ *
+ * This is not a mandatory option as there is a default fitting function
+ * that will optimize for the best pack efficiency. With a custom fitting
+ * function you can e.g. influence the shape of the arranged pile.
+ *
+ * \param item The only parameter is the candidate item which has info
+ * about its current position. Your job is to rate this position compared to
+ * the already packed items.
+ *
+ */
+ std::function<double(const _Item<RawShape>&)> object_function;
+
+ /**
+ * @brief The quality of search for an optimal placement.
+ * This is a compromise slider between quality and speed. Zero is the
+ * fast and poor solution while 1.0 is the slowest but most accurate.
+ */
+ float accuracy = 0.65f;
+
+ /**
+ * @brief If you want to see items inside other item's holes, you have to
+ * turn this switch on.
+ *
+ * This will only work if a suitable nfp implementation is provided.
+ * The library has no such implementation right now.
+ */
+ bool explore_holes = false;
+
+ /**
+ * @brief If true, use all CPUs available. Run on a single core otherwise.
+ */
+ bool parallel = true;
+
+ /**
+ * @brief before_packing Callback that is called just before a search for
+ * a new item's position is started. You can use this to create various
+ * cache structures and update them between subsequent packings.
+ *
+ * \param merged pile A polygon that is the union of all items in the bin.
+ *
+ * \param pile The items parameter is a container with all the placed
+ * polygons excluding the current candidate. You can for instance check the
+ * alignment with the candidate item or do anything else.
+ *
+ * \param remaining A container with the remaining items waiting to be
+ * placed. You can use some features about the remaining items to alter to
+ * score of the current placement. If you know that you have to leave place
+ * for other items as well, that might influence your decision about where
+ * the current candidate should be placed. E.g. imagine three big circles
+ * which you want to place into a box: you might place them in a triangle
+ * shape which has the maximum pack density. But if there is a 4th big
+ * circle than you won't be able to pack it. If you knew apriori that
+ * there four circles are to be placed, you would have placed the first 3
+ * into an L shape. This parameter can be used to make these kind of
+ * decisions (for you or a more intelligent AI).
+ */
+ std::function<void(const nfp::Shapes<RawShape>&, // merged pile
+ const ItemGroup&, // packed items
+ const ItemGroup& // remaining items
+ )> before_packing;
+
+ NfpPConfig(): rotations({0.0, Pi/2.0, Pi, 3*Pi/2}),
+ alignment(Alignment::CENTER), starting_point(Alignment::CENTER) {}
+};
+
+/**
+ * A class for getting a point on the circumference of the polygon (in log time)
+ *
+ * This is a transformation of the provided polygon to be able to pinpoint
+ * locations on the circumference. The optimizer will pass a floating point
+ * value e.g. within <0,1> and we have to transform this value quickly into a
+ * coordinate on the circumference. By definition 0 should yield the first
+ * vertex and 1.0 would be the last (which should coincide with first).
+ *
+ * We also have to make this work for the holes of the captured polygon.
+ */
+template<class RawShape> class EdgeCache {
+ using Vertex = TPoint<RawShape>;
+ using Coord = TCoord<Vertex>;
+ using Edge = _Segment<Vertex>;
+
+ struct ContourCache {
+ mutable std::vector<double> corners;
+ std::vector<Edge> emap;
+ std::vector<double> distances;
+ double full_distance = 0;
+ } contour_;
+
+ std::vector<ContourCache> holes_;
+
+ double accuracy_ = 1.0;
+
+ void createCache(const RawShape& sh) {
+ { // For the contour
+ auto first = shapelike::cbegin(sh);
+ auto next = std::next(first);
+ auto endit = shapelike::cend(sh);
+
+ contour_.distances.reserve(shapelike::contourVertexCount(sh));
+
+ while(next != endit) {
+ contour_.emap.emplace_back(*(first++), *(next++));
+ contour_.full_distance += contour_.emap.back().length();
+ contour_.distances.push_back(contour_.full_distance);
+ }
+ }
+
+ for(auto& h : shapelike::holes(sh)) { // For the holes
+ auto first = h.begin();
+ auto next = std::next(first);
+ auto endit = h.end();
+
+ ContourCache hc;
+ hc.distances.reserve(endit - first);
+
+ while(next != endit) {
+ hc.emap.emplace_back(*(first++), *(next++));
+ hc.full_distance += hc.emap.back().length();
+ hc.distances.push_back(hc.full_distance);
+ }
+
+ holes_.push_back(hc);
+ }
+ }
+
+ size_t stride(const size_t N) const {
+ using std::round;
+ using std::pow;
+
+ return static_cast<Coord>(
+ round(N/pow(N, pow(accuracy_, 1.0/3.0)))
+ );
+ }
+
+ void fetchCorners() const {
+ if(!contour_.corners.empty()) return;
+
+ const auto N = contour_.distances.size();
+ const auto S = stride(N);
+
+ contour_.corners.reserve(N / S + 1);
+ contour_.corners.emplace_back(0.0);
+ auto N_1 = N-1;
+ contour_.corners.emplace_back(0.0);
+ for(size_t i = 0; i < N_1; i += S) {
+ contour_.corners.emplace_back(
+ contour_.distances.at(i) / contour_.full_distance);
+ }
+ }
+
+ void fetchHoleCorners(unsigned hidx) const {
+ auto& hc = holes_[hidx];
+ if(!hc.corners.empty()) return;
+
+ const auto N = hc.distances.size();
+ auto N_1 = N-1;
+ const auto S = stride(N);
+ hc.corners.reserve(N / S + 1);
+ hc.corners.emplace_back(0.0);
+ for(size_t i = 0; i < N_1; i += S) {
+ hc.corners.emplace_back(
+ hc.distances.at(i) / hc.full_distance);
+ }
+ }
+
+ inline Vertex coords(const ContourCache& cache, double distance) const {
+ assert(distance >= .0 && distance <= 1.0);
+
+ // distance is from 0.0 to 1.0, we scale it up to the full length of
+ // the circumference
+ double d = distance*cache.full_distance;
+
+ auto& distances = cache.distances;
+
+ // Magic: we find the right edge in log time
+ auto it = std::lower_bound(distances.begin(), distances.end(), d);
+ auto idx = it - distances.begin(); // get the index of the edge
+ auto edge = cache.emap[idx]; // extrac the edge
+
+ // Get the remaining distance on the target edge
+ auto ed = d - (idx > 0 ? *std::prev(it) : 0 );
+ auto angle = edge.angleToXaxis();
+ Vertex ret = edge.first();
+
+ // Get the point on the edge which lies in ed distance from the start
+ ret += { static_cast<Coord>(std::round(ed*std::cos(angle))),
+ static_cast<Coord>(std::round(ed*std::sin(angle))) };
+
+ return ret;
+ }
+
+public:
+
+ using iterator = std::vector<double>::iterator;
+ using const_iterator = std::vector<double>::const_iterator;
+
+ inline EdgeCache() = default;
+
+ inline EdgeCache(const _Item<RawShape>& item)
+ {
+ createCache(item.transformedShape());
+ }
+
+ inline EdgeCache(const RawShape& sh)
+ {
+ createCache(sh);
+ }
+
+ /// Resolution of returned corners. The stride is derived from this value.
+ void accuracy(double a /* within <0.0, 1.0>*/) { accuracy_ = a; }
+
+ /**
+ * @brief Get a point on the circumference of a polygon.
+ * @param distance A relative distance from the starting point to the end.
+ * Can be from 0.0 to 1.0 where 0.0 is the starting point and 1.0 is the
+ * closing point (which should be eqvivalent with the starting point with
+ * closed polygons).
+ * @return Returns the coordinates of the point lying on the polygon
+ * circumference.
+ */
+ inline Vertex coords(double distance) const {
+ return coords(contour_, distance);
+ }
+
+ inline Vertex coords(unsigned hidx, double distance) const {
+ assert(hidx < holes_.size());
+ return coords(holes_[hidx], distance);
+ }
+
+ inline double circumference() const BP2D_NOEXCEPT {
+ return contour_.full_distance;
+ }
+
+ inline double circumference(unsigned hidx) const BP2D_NOEXCEPT {
+ return holes_[hidx].full_distance;
+ }
+
+ /// Get the normalized distance values for each vertex
+ inline const std::vector<double>& corners() const BP2D_NOEXCEPT {
+ fetchCorners();
+ return contour_.corners;
+ }
+
+ /// corners for a specific hole
+ inline const std::vector<double>&
+ corners(unsigned holeidx) const BP2D_NOEXCEPT {
+ fetchHoleCorners(holeidx);
+ return holes_[holeidx].corners;
+ }
+
+ /// The number of holes in the abstracted polygon
+ inline size_t holeCount() const BP2D_NOEXCEPT { return holes_.size(); }
+
+};
+
+template<nfp::NfpLevel lvl>
+struct Lvl { static const nfp::NfpLevel value = lvl; };
+
+template<class RawShape>
+inline void correctNfpPosition(nfp::NfpResult<RawShape>& nfp,
+ const _Item<RawShape>& stationary,
+ const _Item<RawShape>& orbiter)
+{
+ // The provided nfp is somewhere in the dark. We need to get it
+ // to the right position around the stationary shape.
+ // This is done by choosing the leftmost lowest vertex of the
+ // orbiting polygon to be touched with the rightmost upper
+ // vertex of the stationary polygon. In this configuration, the
+ // reference vertex of the orbiting polygon (which can be dragged around
+ // the nfp) will be its rightmost upper vertex that coincides with the
+ // rightmost upper vertex of the nfp. No proof provided other than Jonas
+ // Lindmark's reasoning about the reference vertex of nfp in his thesis
+ // ("No fit polygon problem" - section 2.1.9)
+
+ auto touch_sh = stationary.rightmostTopVertex();
+ auto touch_other = orbiter.leftmostBottomVertex();
+ auto dtouch = touch_sh - touch_other;
+ auto top_other = orbiter.rightmostTopVertex() + dtouch;
+ auto dnfp = top_other - nfp.second; // nfp.second is the nfp reference point
+ shapelike::translate(nfp.first, dnfp);
+}
+
+template<class RawShape>
+inline void correctNfpPosition(nfp::NfpResult<RawShape>& nfp,
+ const RawShape& stationary,
+ const _Item<RawShape>& orbiter)
+{
+ auto touch_sh = nfp::rightmostUpVertex(stationary);
+ auto touch_other = orbiter.leftmostBottomVertex();
+ auto dtouch = touch_sh - touch_other;
+ auto top_other = orbiter.rightmostTopVertex() + dtouch;
+ auto dnfp = top_other - nfp.second;
+ shapelike::translate(nfp.first, dnfp);
+}
+
+template<class RawShape, class Circle = _Circle<TPoint<RawShape>> >
+Circle minimizeCircle(const RawShape& sh) {
+ using Point = TPoint<RawShape>;
+ using Coord = TCoord<Point>;
+
+ auto& ctr = sl::getContour(sh);
+ if(ctr.empty()) return {{0, 0}, 0};
+
+ auto bb = sl::boundingBox(sh);
+ auto capprx = bb.center();
+ auto rapprx = pl::distance(bb.minCorner(), bb.maxCorner());
+
+
+ opt::StopCriteria stopcr;
+ stopcr.max_iterations = 30;
+ stopcr.relative_score_difference = 1e-3;
+ opt::TOptimizer<opt::Method::L_SUBPLEX> solver(stopcr);
+
+ std::vector<double> dists(ctr.size(), 0);
+
+ auto result = solver.optimize_min(
+ [capprx, rapprx, &ctr, &dists](double xf, double yf) {
+ auto xt = Coord( std::round(getX(capprx) + rapprx*xf) );
+ auto yt = Coord( std::round(getY(capprx) + rapprx*yf) );
+
+ Point centr(xt, yt);
+
+ unsigned i = 0;
+ for(auto v : ctr) {
+ dists[i++] = pl::distance(v, centr);
+ }
+
+ auto mit = std::max_element(dists.begin(), dists.end());
+
+ assert(mit != dists.end());
+
+ return *mit;
+ },
+ opt::initvals(0.0, 0.0),
+ opt::bound(-1.0, 1.0), opt::bound(-1.0, 1.0)
+ );
+
+ double oxf = std::get<0>(result.optimum);
+ double oyf = std::get<1>(result.optimum);
+ auto xt = Coord( std::round(getX(capprx) + rapprx*oxf) );
+ auto yt = Coord( std::round(getY(capprx) + rapprx*oyf) );
+
+ Point cc(xt, yt);
+ auto r = result.score;
+
+ return {cc, r};
+}
+
+template<class RawShape>
+_Circle<TPoint<RawShape>> boundingCircle(const RawShape& sh) {
+ return minimizeCircle(sh);
+}
+
+template<class RawShape, class TBin = _Box<TPoint<RawShape>>>
+class _NofitPolyPlacer: public PlacerBoilerplate<_NofitPolyPlacer<RawShape, TBin>,
+ RawShape, TBin, NfpPConfig<RawShape>> {
+
+ using Base = PlacerBoilerplate<_NofitPolyPlacer<RawShape, TBin>,
+ RawShape, TBin, NfpPConfig<RawShape>>;
+
+ DECLARE_PLACER(Base)
+
+ using Box = _Box<TPoint<RawShape>>;
+
+ using MaxNfpLevel = nfp::MaxNfpLevel<RawShape>;
+
+ using ItemKeys = std::vector<__itemhash::Key>;
+
+ // Norming factor for the optimization function
+ const double norm_;
+
+ // Caching calculated nfps
+ __itemhash::Hash<RawShape> nfpcache_;
+
+ // Storing item hash keys
+ ItemKeys item_keys_;
+
+public:
+
+ using Pile = nfp::Shapes<RawShape>;
+
+ inline explicit _NofitPolyPlacer(const BinType& bin):
+ Base(bin),
+ norm_(std::sqrt(sl::area(bin))) {}
+
+ _NofitPolyPlacer(const _NofitPolyPlacer&) = default;
+ _NofitPolyPlacer& operator=(const _NofitPolyPlacer&) = default;
+
+#ifndef BP2D_COMPILER_MSVC12 // MSVC2013 does not support default move ctors
+ _NofitPolyPlacer(_NofitPolyPlacer&&) BP2D_NOEXCEPT = default;
+ _NofitPolyPlacer& operator=(_NofitPolyPlacer&&) BP2D_NOEXCEPT = default;
+#endif
+
+ static inline double overfit(const Box& bb, const RawShape& bin) {
+ auto bbin = sl::boundingBox(bin);
+ auto d = bbin.center() - bb.center();
+ _Rectangle<RawShape> rect(bb.width(), bb.height());
+ rect.translate(bb.minCorner() + d);
+ return sl::isInside(rect.transformedShape(), bin) ? -1.0 : 1;
+ }
+
+ static inline double overfit(const RawShape& chull, const RawShape& bin) {
+ auto bbch = sl::boundingBox(chull);
+ auto bbin = sl::boundingBox(bin);
+ auto d = bbch.center() - bbin.center();
+ auto chullcpy = chull;
+ sl::translate(chullcpy, d);
+ return sl::isInside(chullcpy, bin) ? -1.0 : 1.0;
+ }
+
+ static inline double overfit(const RawShape& chull, const Box& bin)
+ {
+ auto bbch = sl::boundingBox(chull);
+ return overfit(bbch, bin);
+ }
+
+ static inline double overfit(const Box& bb, const Box& bin)
+ {
+ auto wdiff = double(bb.width() - bin.width());
+ auto hdiff = double(bb.height() - bin.height());
+ double diff = 0;
+ if(wdiff > 0) diff += wdiff;
+ if(hdiff > 0) diff += hdiff;
+ return diff;
+ }
+
+ static inline double overfit(const Box& bb, const _Circle<Vertex>& bin)
+ {
+ double boxr = 0.5*pl::distance(bb.minCorner(), bb.maxCorner());
+ double diff = boxr - bin.radius();
+ return diff;
+ }
+
+ static inline double overfit(const RawShape& chull,
+ const _Circle<Vertex>& bin)
+ {
+ double r = boundingCircle(chull).radius();
+ double diff = r - bin.radius();
+ return diff;
+ }
+
+ template<class Range = ConstItemRange<typename Base::DefaultIter>>
+ PackResult trypack(Item& item,
+ const Range& remaining = Range()) {
+ auto result = _trypack(item, remaining);
+
+ // Experimental
+ // if(!result) repack(item, result);
+
+ return result;
+ }
+
+ ~_NofitPolyPlacer() {
+ clearItems();
+ }
+
+ inline void clearItems() {
+ finalAlign(bin_);
+ Base::clearItems();
+ }
+
+private:
+
+ using Shapes = TMultiShape<RawShape>;
+ using ItemRef = std::reference_wrapper<Item>;
+ using ItemWithHash = const std::pair<ItemRef, __itemhash::Key>;
+
+ Shapes calcnfp(const ItemWithHash itsh, Lvl<nfp::NfpLevel::CONVEX_ONLY>)
+ {
+ using namespace nfp;
+
+ Shapes nfps(items_.size());
+ const Item& trsh = itsh.first;
+
+ __parallel::enumerate(items_.begin(), items_.end(),
+ [&nfps, &trsh](const Item& sh, size_t n)
+ {
+ auto& fixedp = sh.transformedShape();
+ auto& orbp = trsh.transformedShape();
+ auto subnfp_r = noFitPolygon<NfpLevel::CONVEX_ONLY>(fixedp, orbp);
+ correctNfpPosition(subnfp_r, sh, trsh);
+ nfps[n] = subnfp_r.first;
+ });
+
+// for(auto& n : nfps) {
+// auto valid = sl::isValid(n);
+// if(!valid.first) std::cout << "Warning: " << valid.second << std::endl;
+// }
+
+ return nfp::merge(nfps);
+ }
+
+ template<class Level>
+ Shapes calcnfp( const ItemWithHash itsh, Level)
+ { // Function for arbitrary level of nfp implementation
+ using namespace nfp;
+
+ Shapes nfps;
+ const Item& trsh = itsh.first;
+
+ auto& orb = trsh.transformedShape();
+ bool orbconvex = trsh.isContourConvex();
+
+ for(Item& sh : items_) {
+ nfp::NfpResult<RawShape> subnfp;
+ auto& stat = sh.transformedShape();
+
+ if(sh.isContourConvex() && orbconvex)
+ subnfp = nfp::noFitPolygon<NfpLevel::CONVEX_ONLY>(stat, orb);
+ else if(orbconvex)
+ subnfp = nfp::noFitPolygon<NfpLevel::ONE_CONVEX>(stat, orb);
+ else
+ subnfp = nfp::noFitPolygon<Level::value>(stat, orb);
+
+ correctNfpPosition(subnfp, sh, trsh);
+
+ nfps = nfp::merge(nfps, subnfp.first);
+ }
+
+ return nfps;
+ }
+
+ // Very much experimental
+ void repack(Item& item, PackResult& result) {
+
+ if((sl::area(bin_) - this->filledArea()) >= item.area()) {
+ auto prev_func = config_.object_function;
+
+ unsigned iter = 0;
+ ItemGroup backup_rf = items_;
+ std::vector<Item> backup_cpy;
+ for(Item& itm : items_) backup_cpy.emplace_back(itm);
+
+ auto ofn = [this, &item, &result, &iter, &backup_cpy, &backup_rf]
+ (double ratio)
+ {
+ auto& bin = bin_;
+ iter++;
+ config_.object_function = [bin, ratio](
+ nfp::Shapes<RawShape>& pile,
+ const Item& item,
+ const ItemGroup& /*remaining*/)
+ {
+ pile.emplace_back(item.transformedShape());
+ auto ch = sl::convexHull(pile);
+ auto pbb = sl::boundingBox(pile);
+ pile.pop_back();
+
+ double parea = 0.5*(sl::area(ch) + sl::area(pbb));
+
+ double pile_area = std::accumulate(
+ pile.begin(), pile.end(), item.area(),
+ [](double sum, const RawShape& sh){
+ return sum + sl::area(sh);
+ });
+
+ // The pack ratio -- how much is the convex hull occupied
+ double pack_rate = (pile_area)/parea;
+
+ // ratio of waste
+ double waste = 1.0 - pack_rate;
+
+ // Score is the square root of waste. This will extend the
+ // range of good (lower) values and shrink the range of bad
+ // (larger) values.
+ auto wscore = std::sqrt(waste);
+
+
+ auto ibb = item.boundingBox();
+ auto bbb = sl::boundingBox(bin);
+ auto c = ibb.center();
+ double norm = 0.5*pl::distance(bbb.minCorner(),
+ bbb.maxCorner());
+
+ double dscore = pl::distance(c, pbb.center()) / norm;
+
+ return ratio*wscore + (1.0 - ratio) * dscore;
+ };
+
+ auto bb = sl::boundingBox(bin);
+ double norm = bb.width() + bb.height();
+
+ auto items = items_;
+ clearItems();
+ auto it = items.begin();
+ while(auto pr = _trypack(*it++)) {
+ this->accept(pr); if(it == items.end()) break;
+ }
+
+ auto count_diff = items.size() - items_.size();
+ double score = count_diff;
+
+ if(count_diff == 0) {
+ result = _trypack(item);
+
+ if(result) {
+ std::cout << "Success" << std::endl;
+ score = 0.0;
+ } else {
+ score += result.overfit() / norm;
+ }
+ } else {
+ result = PackResult();
+ items_ = backup_rf;
+ for(unsigned i = 0; i < items_.size(); i++) {
+ items_[i].get() = backup_cpy[i];
+ }
+ }
+
+ std::cout << iter << " repack result: " << score << " "
+ << ratio << " " << count_diff << std::endl;
+
+ return score;
+ };
+
+ opt::StopCriteria stopcr;
+ stopcr.max_iterations = 30;
+ stopcr.stop_score = 1e-20;
+ opt::TOptimizer<opt::Method::L_SUBPLEX> solver(stopcr);
+ solver.optimize_min(ofn, opt::initvals(0.5),
+ opt::bound(0.0, 1.0));
+
+ // optimize
+ config_.object_function = prev_func;
+ }
+
+ }
+
+ struct Optimum {
+ double relpos;
+ unsigned nfpidx;
+ int hidx;
+ Optimum(double pos, unsigned nidx):
+ relpos(pos), nfpidx(nidx), hidx(-1) {}
+ Optimum(double pos, unsigned nidx, int holeidx):
+ relpos(pos), nfpidx(nidx), hidx(holeidx) {}
+ };
+
+ class Optimizer: public opt::TOptimizer<opt::Method::L_SUBPLEX> {
+ public:
+ Optimizer() {
+ opt::StopCriteria stopcr;
+ stopcr.max_iterations = 200;
+ stopcr.relative_score_difference = 1e-20;
+ this->stopcr_ = stopcr;
+ }
+ };
+
+ static Box boundingBox(const Box& pilebb, const Box& ibb ) {
+ auto& pminc = pilebb.minCorner();
+ auto& pmaxc = pilebb.maxCorner();
+ auto& iminc = ibb.minCorner();
+ auto& imaxc = ibb.maxCorner();
+ Vertex minc, maxc;
+
+ setX(minc, std::min(getX(pminc), getX(iminc)));
+ setY(minc, std::min(getY(pminc), getY(iminc)));
+
+ setX(maxc, std::max(getX(pmaxc), getX(imaxc)));
+ setY(maxc, std::max(getY(pmaxc), getY(imaxc)));
+ return Box(minc, maxc);
+ }
+
+ using Edges = EdgeCache<RawShape>;
+
+ template<class Range = ConstItemRange<typename Base::DefaultIter>>
+ PackResult _trypack(
+ Item& item,
+ const Range& remaining = Range()) {
+
+ PackResult ret;
+
+ bool can_pack = false;
+ double best_overfit = std::numeric_limits<double>::max();
+
+ auto remlist = ItemGroup(remaining.from, remaining.to);
+ size_t itemhash = __itemhash::hash(item);
+
+ if(items_.empty()) {
+ setInitialPosition(item);
+ best_overfit = overfit(item.transformedShape(), bin_);
+ can_pack = best_overfit <= 0;
+ } else {
+
+ double global_score = std::numeric_limits<double>::max();
+
+ auto initial_tr = item.translation();
+ auto initial_rot = item.rotation();
+ Vertex final_tr = {0, 0};
+ Radians final_rot = initial_rot;
+ Shapes nfps;
+
+ for(auto rot : config_.rotations) {
+
+ item.translation(initial_tr);
+ item.rotation(initial_rot + rot);
+ item.boundingBox(); // fill the bb cache
+
+ // place the new item outside of the print bed to make sure
+ // it is disjunct from the current merged pile
+ placeOutsideOfBin(item);
+
+ nfps = calcnfp({item, itemhash}, Lvl<MaxNfpLevel::value>());
+
+ auto iv = item.referenceVertex();
+
+ auto startpos = item.translation();
+
+ std::vector<Edges> ecache;
+ ecache.reserve(nfps.size());
+
+ for(auto& nfp : nfps ) {
+ ecache.emplace_back(nfp);
+ ecache.back().accuracy(config_.accuracy);
+ }
+
+ Shapes pile;
+ pile.reserve(items_.size()+1);
+ // double pile_area = 0;
+ for(Item& mitem : items_) {
+ pile.emplace_back(mitem.transformedShape());
+ // pile_area += mitem.area();
+ }
+
+ auto merged_pile = nfp::merge(pile);
+ auto& bin = bin_;
+ double norm = norm_;
+ auto pbb = sl::boundingBox(merged_pile);
+ auto binbb = sl::boundingBox(bin);
+
+ // This is the kernel part of the object function that is
+ // customizable by the library client
+ auto _objfunc = config_.object_function?
+ config_.object_function :
+ [norm, bin, binbb, pbb](const Item& item)
+ {
+ auto ibb = item.boundingBox();
+ auto fullbb = boundingBox(pbb, ibb);
+
+ double score = pl::distance(ibb.center(), binbb.center());
+ score /= norm;
+
+ double miss = overfit(fullbb, bin);
+ miss = miss > 0? miss : 0;
+ score += std::pow(miss, 2);
+
+ return score;
+ };
+
+ // Our object function for placement
+ auto rawobjfunc =
+ [_objfunc, iv, startpos] (Vertex v, Item& itm)
+ {
+ auto d = v - iv;
+ d += startpos;
+ itm.translation(d);
+ return _objfunc(itm);
+ };
+
+ auto getNfpPoint = [&ecache](const Optimum& opt)
+ {
+ return opt.hidx < 0? ecache[opt.nfpidx].coords(opt.relpos) :
+ ecache[opt.nfpidx].coords(opt.hidx, opt.relpos);
+ };
+
+ auto boundaryCheck =
+ [&merged_pile, &getNfpPoint, &item, &bin, &iv, &startpos]
+ (const Optimum& o)
+ {
+ auto v = getNfpPoint(o);
+ auto d = v - iv;
+ d += startpos;
+ item.translation(d);
+
+ merged_pile.emplace_back(item.transformedShape());
+ auto chull = sl::convexHull(merged_pile);
+ merged_pile.pop_back();
+
+ return overfit(chull, bin);
+ };
+
+ Optimum optimum(0, 0);
+ double best_score = std::numeric_limits<double>::max();
+ std::launch policy = std::launch::deferred;
+ if(config_.parallel) policy |= std::launch::async;
+
+ if(config_.before_packing)
+ config_.before_packing(merged_pile, items_, remlist);
+
+ using OptResult = opt::Result<double>;
+ using OptResults = std::vector<OptResult>;
+
+ // Local optimization with the four polygon corners as
+ // starting points
+ for(unsigned ch = 0; ch < ecache.size(); ch++) {
+ auto& cache = ecache[ch];
+
+ OptResults results(cache.corners().size());
+
+ auto& rofn = rawobjfunc;
+ auto& nfpoint = getNfpPoint;
+
+ __parallel::enumerate(
+ cache.corners().begin(),
+ cache.corners().end(),
+ [&results, &item, &rofn, &nfpoint, ch]
+ (double pos, size_t n)
+ {
+ Optimizer solver;
+
+ Item itemcpy = item;
+ auto contour_ofn = [&rofn, &nfpoint, ch, &itemcpy]
+ (double relpos)
+ {
+ Optimum op(relpos, ch);
+ return rofn(nfpoint(op), itemcpy);
+ };
+
+ try {
+ results[n] = solver.optimize_min(contour_ofn,
+ opt::initvals<double>(pos),
+ opt::bound<double>(0, 1.0)
+ );
+ } catch(std::exception& e) {
+ derr() << "ERROR: " << e.what() << "\n";
+ }
+ }, policy);
+
+ auto resultcomp =
+ []( const OptResult& r1, const OptResult& r2 ) {
+ return r1.score < r2.score;
+ };
+
+ auto mr = *std::min_element(results.begin(), results.end(),
+ resultcomp);
+
+ if(mr.score < best_score) {
+ Optimum o(std::get<0>(mr.optimum), ch, -1);
+ double miss = boundaryCheck(o);
+ if(miss <= 0) {
+ best_score = mr.score;
+ optimum = o;
+ } else {
+ best_overfit = std::min(miss, best_overfit);
+ }
+ }
+
+ for(unsigned hidx = 0; hidx < cache.holeCount(); ++hidx) {
+ results.clear();
+ results.resize(cache.corners(hidx).size());
+
+ // TODO : use parallel for
+ __parallel::enumerate(cache.corners(hidx).begin(),
+ cache.corners(hidx).end(),
+ [&results, &item, &nfpoint,
+ &rofn, ch, hidx]
+ (double pos, size_t n)
+ {
+ Optimizer solver;
+
+ Item itmcpy = item;
+ auto hole_ofn =
+ [&rofn, &nfpoint, ch, hidx, &itmcpy]
+ (double pos)
+ {
+ Optimum opt(pos, ch, hidx);
+ return rofn(nfpoint(opt), itmcpy);
+ };
+
+ try {
+ results[n] = solver.optimize_min(hole_ofn,
+ opt::initvals<double>(pos),
+ opt::bound<double>(0, 1.0)
+ );
+
+ } catch(std::exception& e) {
+ derr() << "ERROR: " << e.what() << "\n";
+ }
+ }, policy);
+
+ auto hmr = *std::min_element(results.begin(),
+ results.end(),
+ resultcomp);
+
+ if(hmr.score < best_score) {
+ Optimum o(std::get<0>(hmr.optimum),
+ ch, hidx);
+ double miss = boundaryCheck(o);
+ if(miss <= 0.0) {
+ best_score = hmr.score;
+ optimum = o;
+ } else {
+ best_overfit = std::min(miss, best_overfit);
+ }
+ }
+ }
+ }
+
+ if( best_score < global_score ) {
+ auto d = getNfpPoint(optimum) - iv;
+ d += startpos;
+ final_tr = d;
+ final_rot = initial_rot + rot;
+ can_pack = true;
+ global_score = best_score;
+ }
+ }
+
+ item.translation(final_tr);
+ item.rotation(final_rot);
+ }
+
+ if(can_pack) {
+ ret = PackResult(item);
+ item_keys_.emplace_back(itemhash);
+ } else {
+ ret = PackResult(best_overfit);
+ }
+
+ return ret;
+ }
+
+ inline void finalAlign(const RawShape& pbin) {
+ auto bbin = sl::boundingBox(pbin);
+ finalAlign(bbin);
+ }
+
+ inline void finalAlign(_Circle<TPoint<RawShape>> cbin) {
+ if(items_.empty()) return;
+ nfp::Shapes<RawShape> m;
+ m.reserve(items_.size());
+ for(Item& item : items_) m.emplace_back(item.transformedShape());
+
+ auto c = boundingCircle(sl::convexHull(m));
+
+ auto d = cbin.center() - c.center();
+ for(Item& item : items_) item.translate(d);
+ }
+
+ inline void finalAlign(Box bbin) {
+ if(items_.empty()) return;
+ nfp::Shapes<RawShape> m;
+ m.reserve(items_.size());
+ for(Item& item : items_) m.emplace_back(item.transformedShape());
+ auto&& bb = sl::boundingBox(m);
+
+ Vertex ci, cb;
+
+ switch(config_.alignment) {
+ case Config::Alignment::CENTER: {
+ ci = bb.center();
+ cb = bbin.center();
+ break;
+ }
+ case Config::Alignment::BOTTOM_LEFT: {
+ ci = bb.minCorner();
+ cb = bbin.minCorner();
+ break;
+ }
+ case Config::Alignment::BOTTOM_RIGHT: {
+ ci = {getX(bb.maxCorner()), getY(bb.minCorner())};
+ cb = {getX(bbin.maxCorner()), getY(bbin.minCorner())};
+ break;
+ }
+ case Config::Alignment::TOP_LEFT: {
+ ci = {getX(bb.minCorner()), getY(bb.maxCorner())};
+ cb = {getX(bbin.minCorner()), getY(bbin.maxCorner())};
+ break;
+ }
+ case Config::Alignment::TOP_RIGHT: {
+ ci = bb.maxCorner();
+ cb = bbin.maxCorner();
+ break;
+ }
+ }
+
+ auto d = cb - ci;
+ for(Item& item : items_) item.translate(d);
+ }
+
+ void setInitialPosition(Item& item) {
+ Box&& bb = item.boundingBox();
+ Vertex ci, cb;
+ auto bbin = sl::boundingBox(bin_);
+
+ switch(config_.starting_point) {
+ case Config::Alignment::CENTER: {
+ ci = bb.center();
+ cb = bbin.center();
+ break;
+ }
+ case Config::Alignment::BOTTOM_LEFT: {
+ ci = bb.minCorner();
+ cb = bbin.minCorner();
+ break;
+ }
+ case Config::Alignment::BOTTOM_RIGHT: {
+ ci = {getX(bb.maxCorner()), getY(bb.minCorner())};
+ cb = {getX(bbin.maxCorner()), getY(bbin.minCorner())};
+ break;
+ }
+ case Config::Alignment::TOP_LEFT: {
+ ci = {getX(bb.minCorner()), getY(bb.maxCorner())};
+ cb = {getX(bbin.minCorner()), getY(bbin.maxCorner())};
+ break;
+ }
+ case Config::Alignment::TOP_RIGHT: {
+ ci = bb.maxCorner();
+ cb = bbin.maxCorner();
+ break;
+ }
+ }
+
+ auto d = cb - ci;
+ item.translate(d);
+ }
+
+ void placeOutsideOfBin(Item& item) {
+ auto&& bb = item.boundingBox();
+ Box binbb = sl::boundingBox(bin_);
+
+ Vertex v = { getX(bb.maxCorner()), getY(bb.minCorner()) };
+
+ Coord dx = getX(binbb.maxCorner()) - getX(v);
+ Coord dy = getY(binbb.maxCorner()) - getY(v);
+
+ item.translate({dx, dy});
+ }
+
+};
+
+
+}
+}
+
+#endif // NOFITPOLY_H
diff --git a/xs/src/libnest2d/libnest2d/placers/placer_boilerplate.hpp b/xs/src/libnest2d/libnest2d/placers/placer_boilerplate.hpp
new file mode 100644
index 000000000..0df1b8c91
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/placers/placer_boilerplate.hpp
@@ -0,0 +1,134 @@
+#ifndef PLACER_BOILERPLATE_HPP
+#define PLACER_BOILERPLATE_HPP
+
+#include "../libnest2d.hpp"
+
+namespace libnest2d { namespace placers {
+
+struct EmptyConfig {};
+
+template<class Subclass, class RawShape, class TBin, class Cfg = EmptyConfig>
+class PlacerBoilerplate {
+ mutable bool farea_valid_ = false;
+ mutable double farea_ = 0.0;
+public:
+ using Item = _Item<RawShape>;
+ using Vertex = TPoint<RawShape>;
+ using Segment = _Segment<Vertex>;
+ using BinType = TBin;
+ using Coord = TCoord<Vertex>;
+ using Unit = Coord;
+ using Config = Cfg;
+ using ItemGroup = _ItemGroup<Item>;
+ using DefaultIter = typename ItemGroup::const_iterator;
+
+ class PackResult {
+ Item *item_ptr_;
+ Vertex move_;
+ Radians rot_;
+ double overfit_;
+ friend class PlacerBoilerplate;
+ friend Subclass;
+
+ PackResult(Item& item):
+ item_ptr_(&item),
+ move_(item.translation()),
+ rot_(item.rotation()) {}
+
+ PackResult(double overfit = 1.0):
+ item_ptr_(nullptr), overfit_(overfit) {}
+
+ public:
+ operator bool() { return item_ptr_ != nullptr; }
+ double overfit() const { return overfit_; }
+ };
+
+ inline PlacerBoilerplate(const BinType& bin, unsigned cap = 50): bin_(bin)
+ {
+ items_.reserve(cap);
+ }
+
+ inline const BinType& bin() const BP2D_NOEXCEPT { return bin_; }
+
+ template<class TB> inline void bin(TB&& b) {
+ bin_ = std::forward<BinType>(b);
+ }
+
+ inline void configure(const Config& config) BP2D_NOEXCEPT {
+ config_ = config;
+ }
+
+ template<class Range = ConstItemRange<DefaultIter>>
+ bool pack(Item& item,
+ const Range& rem = Range()) {
+ auto&& r = static_cast<Subclass*>(this)->trypack(item, rem);
+ if(r) {
+ items_.push_back(*(r.item_ptr_));
+ farea_valid_ = false;
+ }
+ return r;
+ }
+
+ void accept(PackResult& r) {
+ if(r) {
+ r.item_ptr_->translation(r.move_);
+ r.item_ptr_->rotation(r.rot_);
+ items_.push_back(*(r.item_ptr_));
+ farea_valid_ = false;
+ }
+ }
+
+ void unpackLast() {
+ items_.pop_back();
+ farea_valid_ = false;
+ }
+
+ inline const ItemGroup& getItems() const { return items_; }
+
+ inline void clearItems() {
+ items_.clear();
+ farea_valid_ = false;
+ }
+
+ inline double filledArea() const {
+ if(farea_valid_) return farea_;
+ else {
+ farea_ = .0;
+ std::for_each(items_.begin(), items_.end(),
+ [this] (Item& item) {
+ farea_ += item.area();
+ });
+ farea_valid_ = true;
+ }
+
+ return farea_;
+ }
+
+protected:
+
+ BinType bin_;
+ ItemGroup items_;
+ Cfg config_;
+};
+
+
+#define DECLARE_PLACER(Base) \
+using Base::bin_; \
+using Base::items_; \
+using Base::config_; \
+public: \
+using typename Base::Item; \
+using typename Base::ItemGroup; \
+using typename Base::BinType; \
+using typename Base::Config; \
+using typename Base::Vertex; \
+using typename Base::Segment; \
+using typename Base::PackResult; \
+using typename Base::Coord; \
+using typename Base::Unit; \
+private:
+
+}
+}
+
+#endif // PLACER_BOILERPLATE_HPP
diff --git a/xs/src/libnest2d/libnest2d/rotfinder.hpp b/xs/src/libnest2d/libnest2d/rotfinder.hpp
new file mode 100644
index 000000000..525fd8759
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/rotfinder.hpp
@@ -0,0 +1,41 @@
+#ifndef ROTFINDER_HPP
+#define ROTFINDER_HPP
+
+#include <libnest2d/libnest2d.hpp>
+#include <libnest2d/optimizer.hpp>
+#include <iterator>
+
+namespace libnest2d {
+
+template<class RawShape>
+Radians findBestRotation(_Item<RawShape>& item) {
+ opt::StopCriteria stopcr;
+ stopcr.absolute_score_difference = 0.01;
+ stopcr.max_iterations = 10000;
+ opt::TOptimizer<opt::Method::G_GENETIC> solver(stopcr);
+
+ auto orig_rot = item.rotation();
+
+ auto result = solver.optimize_min([&item, &orig_rot](Radians rot){
+ item.rotation(orig_rot + rot);
+ auto bb = item.boundingBox();
+ return std::sqrt(bb.height()*bb.width());
+ }, opt::initvals(Radians(0)), opt::bound<Radians>(-Pi/2, Pi/2));
+
+ item.rotation(orig_rot);
+
+ return std::get<0>(result.optimum);
+}
+
+template<class Iterator>
+void findMinimumBoundingBoxRotations(Iterator from, Iterator to) {
+ using V = typename std::iterator_traits<Iterator>::value_type;
+ std::for_each(from, to, [](V& item){
+ Radians rot = findBestRotation(item);
+ item.rotate(rot);
+ });
+}
+
+}
+
+#endif // ROTFINDER_HPP
diff --git a/xs/src/libnest2d/libnest2d/selections/djd_heuristic.hpp b/xs/src/libnest2d/libnest2d/selections/djd_heuristic.hpp
new file mode 100644
index 000000000..ee93d0592
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/selections/djd_heuristic.hpp
@@ -0,0 +1,717 @@
+#ifndef DJD_HEURISTIC_HPP
+#define DJD_HEURISTIC_HPP
+
+#include <list>
+#include <future>
+#include <atomic>
+#include <functional>
+
+#include "selection_boilerplate.hpp"
+
+namespace libnest2d { namespace selections {
+
+/**
+ * Selection heuristic based on [López-Camacho]\
+ * (http://www.cs.stir.ac.uk/~goc/papers/EffectiveHueristic2DAOR2013.pdf)
+ */
+template<class RawShape>
+class _DJDHeuristic: public SelectionBoilerplate<RawShape> {
+ using Base = SelectionBoilerplate<RawShape>;
+
+ class SpinLock {
+ std::atomic_flag& lck_;
+ public:
+
+ inline SpinLock(std::atomic_flag& flg): lck_(flg) {}
+
+ inline void lock() {
+ while(lck_.test_and_set(std::memory_order_acquire)) {}
+ }
+
+ inline void unlock() { lck_.clear(std::memory_order_release); }
+ };
+
+public:
+ using typename Base::Item;
+ using typename Base::ItemRef;
+
+ /**
+ * @brief The Config for DJD heuristic.
+ */
+ struct Config {
+
+ /**
+ * If true, the algorithm will try to place pair and triplets in all
+ * possible order. It will have a hugely negative impact on performance.
+ */
+ bool try_reverse_order = true;
+
+ /**
+ * @brief try_pairs Whether to try pairs of items to pack. It will add
+ * a quadratic component to the complexity.
+ */
+ bool try_pairs = true;
+
+ /**
+ * @brief Whether to try groups of 3 items to pack. This could be very
+ * slow for large number of items (>100) as it adds a cubic component
+ * to the complexity.
+ */
+ bool try_triplets = false;
+
+ /**
+ * The initial fill proportion of the bin area that will be filled before
+ * trying items one by one, or pairs or triplets.
+ *
+ * The initial fill proportion suggested by
+ * [López-Camacho]\
+ * (http://www.cs.stir.ac.uk/~goc/papers/EffectiveHueristic2DAOR2013.pdf)
+ * is one third of the area of bin.
+ */
+ double initial_fill_proportion = 1.0/3.0;
+
+ /**
+ * @brief How much is the acceptable waste incremented at each iteration
+ */
+ double waste_increment = 0.1;
+
+ /**
+ * @brief Allow parallel jobs for filling multiple bins.
+ *
+ * This will decrease the soution quality but can greatly boost up
+ * performance for large number of items.
+ */
+ bool allow_parallel = true;
+
+ /**
+ * @brief Always use parallel processing if the items don't fit into
+ * one bin.
+ */
+ bool force_parallel = false;
+ };
+
+private:
+ using Base::packed_bins_;
+ using ItemGroup = typename Base::ItemGroup;
+
+ using Container = ItemGroup;
+ Container store_;
+ Config config_;
+
+ static const unsigned MAX_ITEMS_SEQUENTIALLY = 30;
+ static const unsigned MAX_VERTICES_SEQUENTIALLY = MAX_ITEMS_SEQUENTIALLY*20;
+
+public:
+
+ inline void configure(const Config& config) {
+ config_ = config;
+ }
+
+ template<class TPlacer, class TIterator,
+ class TBin = typename PlacementStrategyLike<TPlacer>::BinType,
+ class PConfig = typename PlacementStrategyLike<TPlacer>::Config>
+ void packItems( TIterator first,
+ TIterator last,
+ const TBin& bin,
+ PConfig&& pconfig = PConfig() )
+ {
+ using Placer = PlacementStrategyLike<TPlacer>;
+ using ItemList = std::list<ItemRef>;
+
+ const double bin_area = sl::area(bin);
+ const double w = bin_area * config_.waste_increment;
+
+ const double INITIAL_FILL_PROPORTION = config_.initial_fill_proportion;
+ const double INITIAL_FILL_AREA = bin_area*INITIAL_FILL_PROPORTION;
+
+ store_.clear();
+ store_.reserve(last-first);
+ packed_bins_.clear();
+
+ std::copy(first, last, std::back_inserter(store_));
+
+ std::sort(store_.begin(), store_.end(), [](Item& i1, Item& i2) {
+ return i1.area() > i2.area();
+ });
+
+ size_t glob_vertex_count = 0;
+ std::for_each(store_.begin(), store_.end(),
+ [&glob_vertex_count](const Item& item) {
+ glob_vertex_count += item.vertexCount();
+ });
+
+ std::vector<Placer> placers;
+
+ bool try_reverse = config_.try_reverse_order;
+
+ // Will use a subroutine to add a new bin
+ auto addBin = [this, &placers, &bin, &pconfig]()
+ {
+ placers.emplace_back(bin);
+ packed_bins_.emplace_back();
+ placers.back().configure(pconfig);
+ };
+
+ // Types for pairs and triplets
+ using TPair = std::tuple<ItemRef, ItemRef>;
+ using TTriplet = std::tuple<ItemRef, ItemRef, ItemRef>;
+
+
+ // Method for checking a pair whether it was a pack failure.
+ auto check_pair = [](const std::vector<TPair>& wrong_pairs,
+ ItemRef i1, ItemRef i2)
+ {
+ return std::any_of(wrong_pairs.begin(), wrong_pairs.end(),
+ [&i1, &i2](const TPair& pair)
+ {
+ Item& pi1 = std::get<0>(pair), &pi2 = std::get<1>(pair);
+ Item& ri1 = i1, &ri2 = i2;
+ return (&pi1 == &ri1 && &pi2 == &ri2) ||
+ (&pi1 == &ri2 && &pi2 == &ri1);
+ });
+ };
+
+ // Method for checking if a triplet was a pack failure
+ auto check_triplet = [](
+ const std::vector<TTriplet>& wrong_triplets,
+ ItemRef i1,
+ ItemRef i2,
+ ItemRef i3)
+ {
+ return std::any_of(wrong_triplets.begin(),
+ wrong_triplets.end(),
+ [&i1, &i2, &i3](const TTriplet& tripl)
+ {
+ Item& pi1 = std::get<0>(tripl);
+ Item& pi2 = std::get<1>(tripl);
+ Item& pi3 = std::get<2>(tripl);
+ Item& ri1 = i1, &ri2 = i2, &ri3 = i3;
+ return (&pi1 == &ri1 && &pi2 == &ri2 && &pi3 == &ri3) ||
+ (&pi1 == &ri1 && &pi2 == &ri3 && &pi3 == &ri2) ||
+ (&pi1 == &ri2 && &pi2 == &ri1 && &pi3 == &ri3) ||
+ (&pi1 == &ri3 && &pi2 == &ri2 && &pi3 == &ri1);
+ });
+ };
+
+ using ItemListIt = typename ItemList::iterator;
+
+ auto largestPiece = [](ItemListIt it, ItemList& not_packed) {
+ return it == not_packed.begin()? std::next(it) : not_packed.begin();
+ };
+
+ auto secondLargestPiece = [&largestPiece](ItemListIt it,
+ ItemList& not_packed) {
+ auto ret = std::next(largestPiece(it, not_packed));
+ return ret == it? std::next(ret) : ret;
+ };
+
+ auto smallestPiece = [](ItemListIt it, ItemList& not_packed) {
+ auto last = std::prev(not_packed.end());
+ return it == last? std::prev(it) : last;
+ };
+
+ auto secondSmallestPiece = [&smallestPiece](ItemListIt it,
+ ItemList& not_packed) {
+ auto ret = std::prev(smallestPiece(it, not_packed));
+ return ret == it? std::prev(ret) : ret;
+ };
+
+ auto tryOneByOne = // Subroutine to try adding items one by one.
+ [&bin_area]
+ (Placer& placer, ItemList& not_packed,
+ double waste,
+ double& free_area,
+ double& filled_area)
+ {
+ double item_area = 0;
+ bool ret = false;
+ auto it = not_packed.begin();
+
+ auto pack = [&placer, &not_packed](ItemListIt it) {
+ return placer.pack(*it, rem(it, not_packed));
+ };
+
+ while(it != not_packed.end() && !ret &&
+ free_area - (item_area = it->get().area()) <= waste)
+ {
+ if(item_area <= free_area && pack(it) ) {
+ free_area -= item_area;
+ filled_area = bin_area - free_area;
+ ret = true;
+ } else
+ it++;
+ }
+
+ if(ret) not_packed.erase(it);
+
+ return ret;
+ };
+
+ auto tryGroupsOfTwo = // Try adding groups of two items into the bin.
+ [&bin_area, &check_pair, &largestPiece, &smallestPiece,
+ try_reverse]
+ (Placer& placer, ItemList& not_packed,
+ double waste,
+ double& free_area,
+ double& filled_area)
+ {
+ double item_area = 0;
+ const auto endit = not_packed.end();
+
+ if(not_packed.size() < 2)
+ return false; // No group of two items
+
+ double largest_area = not_packed.front().get().area();
+ auto itmp = not_packed.begin(); itmp++;
+ double second_largest = itmp->get().area();
+ if( free_area - second_largest - largest_area > waste)
+ return false; // If even the largest two items do not fill
+ // the bin to the desired waste than we can end here.
+
+
+ bool ret = false;
+ auto it = not_packed.begin();
+ auto it2 = it;
+
+ std::vector<TPair> wrong_pairs;
+ using std::placeholders::_1;
+
+ auto trypack = [&placer, &not_packed](ItemListIt it) {
+ return placer.trypack(*it, rem(it, not_packed));
+ };
+
+ while(it != endit && !ret &&
+ free_area - (item_area = it->get().area()) -
+ largestPiece(it, not_packed)->get().area() <= waste)
+ {
+ if(item_area + smallestPiece(it, not_packed)->get().area() >
+ free_area ) { it++; continue; }
+
+ auto pr = trypack(it);
+
+ // First would fit
+ it2 = not_packed.begin();
+ double item2_area = 0;
+ while(it2 != endit && pr && !ret && free_area -
+ (item2_area = it2->get().area()) - item_area <= waste)
+ {
+ double area_sum = item_area + item2_area;
+
+ if(it == it2 || area_sum > free_area ||
+ check_pair(wrong_pairs, *it, *it2)) {
+ it2++; continue;
+ }
+
+ placer.accept(pr);
+ auto pr2 = trypack(it2);
+ if(!pr2) {
+ placer.unpackLast(); // remove first
+ if(try_reverse) {
+ pr2 = trypack(it2);
+ if(pr2) {
+ placer.accept(pr2);
+ auto pr12 = trypack(it);
+ if(pr12) {
+ placer.accept(pr12);
+ ret = true;
+ } else {
+ placer.unpackLast();
+ }
+ }
+ }
+ } else {
+ placer.accept(pr2); ret = true;
+ }
+
+ if(ret)
+ { // Second fits as well
+ free_area -= area_sum;
+ filled_area = bin_area - free_area;
+ } else {
+ wrong_pairs.emplace_back(*it, *it2);
+ it2++;
+ }
+ }
+
+ if(!ret) it++;
+ }
+
+ if(ret) { not_packed.erase(it); not_packed.erase(it2); }
+
+ return ret;
+ };
+
+ auto tryGroupsOfThree = // Try adding groups of three items.
+ [&bin_area,
+ &smallestPiece, &largestPiece,
+ &secondSmallestPiece, &secondLargestPiece,
+ &check_pair, &check_triplet, try_reverse]
+ (Placer& placer, ItemList& not_packed,
+ double waste,
+ double& free_area,
+ double& filled_area)
+ {
+ auto np_size = not_packed.size();
+ if(np_size < 3) return false;
+
+ auto it = not_packed.begin(); // from
+ const auto endit = not_packed.end(); // to
+ auto it2 = it, it3 = it;
+
+ // Containers for pairs and triplets that were tried before and
+ // do not work.
+ std::vector<TPair> wrong_pairs;
+ std::vector<TTriplet> wrong_triplets;
+
+ auto cap = np_size*np_size / 2 ;
+ wrong_pairs.reserve(cap);
+ wrong_triplets.reserve(cap);
+
+ // Will be true if a succesfull pack can be made.
+ bool ret = false;
+
+ auto area = [](const ItemListIt& it) {
+ return it->get().area();
+ };
+
+ auto trypack = [&placer, &not_packed](ItemListIt it) {
+ return placer.trypack(*it, rem(it, not_packed));
+ };
+
+ auto pack = [&placer, &not_packed](ItemListIt it) {
+ return placer.pack(*it, rem(it, not_packed));
+ };
+
+ while (it != endit && !ret) { // drill down 1st level
+
+ // We need to determine in each iteration the largest, second
+ // largest, smallest and second smallest item in terms of area.
+
+ Item& largest = *largestPiece(it, not_packed);
+ Item& second_largest = *secondLargestPiece(it, not_packed);
+
+ double area_of_two_largest =
+ largest.area() + second_largest.area();
+
+ // Check if there is enough free area for the item and the two
+ // largest item
+ if(free_area - area(it) - area_of_two_largest > waste)
+ break;
+
+ // Determine the area of the two smallest item.
+ Item& smallest = *smallestPiece(it, not_packed);
+ Item& second_smallest = *secondSmallestPiece(it, not_packed);
+
+ // Check if there is enough free area for the item and the two
+ // smallest item.
+ double area_of_two_smallest =
+ smallest.area() + second_smallest.area();
+
+ if(area(it) + area_of_two_smallest > free_area) {
+ it++; continue;
+ }
+
+ auto pr = trypack(it);
+
+ // Check for free area and try to pack the 1st item...
+ if(!pr) { it++; continue; }
+
+ it2 = not_packed.begin();
+ double rem2_area = free_area - largest.area();
+ double a2_sum = 0;
+
+ while(it2 != endit && !ret &&
+ rem2_area - (a2_sum = area(it) + area(it2)) <= waste) {
+ // Drill down level 2
+
+ if(a2_sum != area(it) + area(it2)) throw -1;
+
+ if(it == it2 || check_pair(wrong_pairs, *it, *it2)) {
+ it2++; continue;
+ }
+
+ if(a2_sum + smallest.area() > free_area) {
+ it2++; continue;
+ }
+
+ bool can_pack2 = false;
+
+ placer.accept(pr);
+ auto pr2 = trypack(it2);
+ auto pr12 = pr;
+ if(!pr2) {
+ placer.unpackLast(); // remove first
+ if(try_reverse) {
+ pr2 = trypack(it2);
+ if(pr2) {
+ placer.accept(pr2);
+ pr12 = trypack(it);
+ if(pr12) can_pack2 = true;
+ placer.unpackLast();
+ }
+ }
+ } else {
+ placer.unpackLast();
+ can_pack2 = true;
+ }
+
+ if(!can_pack2) {
+ wrong_pairs.emplace_back(*it, *it2);
+ it2++;
+ continue;
+ }
+
+ // Now we have packed a group of 2 items.
+ // The 'smallest' variable now could be identical with
+ // it2 but we don't bother with that
+
+ it3 = not_packed.begin();
+
+ double a3_sum = 0;
+
+ while(it3 != endit && !ret &&
+ free_area - (a3_sum = a2_sum + area(it3)) <= waste) {
+ // 3rd level
+
+ if(it3 == it || it3 == it2 ||
+ check_triplet(wrong_triplets, *it, *it2, *it3))
+ { it3++; continue; }
+
+ if(a3_sum > free_area) { it3++; continue; }
+
+ placer.accept(pr12); placer.accept(pr2);
+ bool can_pack3 = pack(it3);
+
+ if(!can_pack3) {
+ placer.unpackLast();
+ placer.unpackLast();
+ }
+
+ if(!can_pack3 && try_reverse) {
+
+ std::array<size_t, 3> indices = {0, 1, 2};
+ std::array<typename ItemList::iterator, 3>
+ candidates = {it, it2, it3};
+
+ auto tryPack = [&placer, &candidates, &pack](
+ const decltype(indices)& idx)
+ {
+ std::array<bool, 3> packed = {false};
+
+ for(auto id : idx) packed.at(id) =
+ pack(candidates[id]);
+
+ bool check =
+ std::all_of(packed.begin(),
+ packed.end(),
+ [](bool b) { return b; });
+
+ if(!check) for(bool b : packed) if(b)
+ placer.unpackLast();
+
+ return check;
+ };
+
+ while (!can_pack3 && std::next_permutation(
+ indices.begin(),
+ indices.end())){
+ can_pack3 = tryPack(indices);
+ };
+ }
+
+ if(can_pack3) {
+ // finishit
+ free_area -= a3_sum;
+ filled_area = bin_area - free_area;
+ ret = true;
+ } else {
+ wrong_triplets.emplace_back(*it, *it2, *it3);
+ it3++;
+ }
+
+ } // 3rd while
+
+ if(!ret) it2++;
+
+ } // Second while
+
+ if(!ret) it++;
+
+ } // First while
+
+ if(ret) { // If we eventually succeeded, remove all the packed ones.
+ not_packed.erase(it);
+ not_packed.erase(it2);
+ not_packed.erase(it3);
+ }
+
+ return ret;
+ };
+
+ // Safety test: try to pack each item into an empty bin. If it fails
+ // then it should be removed from the not_packed list
+ { auto it = store_.begin();
+ while (it != store_.end()) {
+ Placer p(bin); p.configure(pconfig);
+ if(!p.pack(*it, rem(it, store_))) {
+ it = store_.erase(it);
+ } else it++;
+ }
+ }
+
+ int acounter = int(store_.size());
+ std::atomic_flag flg = ATOMIC_FLAG_INIT;
+ SpinLock slock(flg);
+
+ auto makeProgress = [this, &acounter, &slock]
+ (Placer& placer, size_t idx, int packednum)
+ {
+
+ packed_bins_[idx] = placer.getItems();
+
+ // TODO here should be a spinlock
+ slock.lock();
+ acounter -= packednum;
+ this->progress_(acounter);
+ slock.unlock();
+ };
+
+ double items_area = 0;
+ for(Item& item : store_) items_area += item.area();
+
+ // Number of bins that will definitely be needed
+ auto bincount_guess = unsigned(std::ceil(items_area / bin_area));
+
+ // Do parallel if feasible
+ bool do_parallel = config_.allow_parallel && bincount_guess > 1 &&
+ ((glob_vertex_count > MAX_VERTICES_SEQUENTIALLY ||
+ store_.size() > MAX_ITEMS_SEQUENTIALLY) ||
+ config_.force_parallel);
+
+ if(do_parallel) dout() << "Parallel execution..." << "\n";
+
+ bool do_pairs = config_.try_pairs;
+ bool do_triplets = config_.try_triplets;
+
+ // The DJD heuristic algorithm itself:
+ auto packjob = [INITIAL_FILL_AREA, bin_area, w, do_triplets, do_pairs,
+ &tryOneByOne,
+ &tryGroupsOfTwo,
+ &tryGroupsOfThree,
+ &makeProgress]
+ (Placer& placer, ItemList& not_packed, size_t idx)
+ {
+ double filled_area = placer.filledArea();
+ double free_area = bin_area - filled_area;
+ double waste = .0;
+ bool lasttry = false;
+
+ while(!not_packed.empty()) {
+
+ {// Fill the bin up to INITIAL_FILL_PROPORTION of its capacity
+ auto it = not_packed.begin();
+
+ while(it != not_packed.end() &&
+ filled_area < INITIAL_FILL_AREA)
+ {
+ if(placer.pack(*it, rem(it, not_packed))) {
+ filled_area += it->get().area();
+ free_area = bin_area - filled_area;
+ it = not_packed.erase(it);
+ makeProgress(placer, idx, 1);
+ } else it++;
+ }
+ }
+
+ // try pieses one by one
+ while(tryOneByOne(placer, not_packed, waste, free_area,
+ filled_area)) {
+ waste = 0; lasttry = false;
+ makeProgress(placer, idx, 1);
+ }
+
+ // try groups of 2 pieses
+ while(do_pairs &&
+ tryGroupsOfTwo(placer, not_packed, waste, free_area,
+ filled_area)) {
+ waste = 0; lasttry = false;
+ makeProgress(placer, idx, 2);
+ }
+
+ // try groups of 3 pieses
+ while(do_triplets &&
+ tryGroupsOfThree(placer, not_packed, waste, free_area,
+ filled_area)) {
+ waste = 0; lasttry = false;
+ makeProgress(placer, idx, 3);
+ }
+
+ waste += w;
+ if(!lasttry && waste > free_area) lasttry = true;
+ else if(lasttry) break;
+ }
+ };
+
+ size_t idx = 0;
+ ItemList remaining;
+
+ if(do_parallel) {
+ std::vector<ItemList> not_packeds(bincount_guess);
+
+ // Preallocating the bins
+ for(unsigned b = 0; b < bincount_guess; b++) {
+ addBin();
+ ItemList& not_packed = not_packeds[b];
+ for(unsigned idx = b; idx < store_.size(); idx+=bincount_guess) {
+ not_packed.push_back(store_[idx]);
+ }
+ }
+
+ // The parallel job
+ auto job = [&placers, &not_packeds, &packjob](unsigned idx) {
+ Placer& placer = placers[idx];
+ ItemList& not_packed = not_packeds[idx];
+ return packjob(placer, not_packed, idx);
+ };
+
+ // We will create jobs for each bin
+ std::vector<std::future<void>> rets(bincount_guess);
+
+ for(unsigned b = 0; b < bincount_guess; b++) { // launch the jobs
+ rets[b] = std::async(std::launch::async, job, b);
+ }
+
+ for(unsigned fi = 0; fi < rets.size(); ++fi) {
+ rets[fi].wait();
+
+ // Collect remaining items while waiting for the running jobs
+ remaining.merge( not_packeds[fi], [](Item& i1, Item& i2) {
+ return i1.area() > i2.area();
+ });
+
+ }
+
+ idx = placers.size();
+
+ // Try to put the remaining items into one of the packed bins
+ if(remaining.size() <= placers.size())
+ for(size_t j = 0; j < idx && !remaining.empty(); j++) {
+ packjob(placers[j], remaining, j);
+ }
+
+ } else {
+ remaining = ItemList(store_.begin(), store_.end());
+ }
+
+ while(!remaining.empty()) {
+ addBin();
+ packjob(placers[idx], remaining, idx); idx++;
+ }
+
+ }
+};
+
+}
+}
+
+#endif // DJD_HEURISTIC_HPP
diff --git a/xs/src/libnest2d/libnest2d/selections/filler.hpp b/xs/src/libnest2d/libnest2d/selections/filler.hpp
new file mode 100644
index 000000000..0da7220a1
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/selections/filler.hpp
@@ -0,0 +1,80 @@
+#ifndef FILLER_HPP
+#define FILLER_HPP
+
+#include "selection_boilerplate.hpp"
+
+namespace libnest2d { namespace selections {
+
+template<class RawShape>
+class _FillerSelection: public SelectionBoilerplate<RawShape> {
+ using Base = SelectionBoilerplate<RawShape>;
+public:
+ using typename Base::Item;
+ using Config = int; //dummy
+
+private:
+ using Base::packed_bins_;
+ using typename Base::ItemGroup;
+ using Container = ItemGroup;
+ Container store_;
+
+public:
+
+ void configure(const Config& /*config*/) { }
+
+ template<class TPlacer, class TIterator,
+ class TBin = typename PlacementStrategyLike<TPlacer>::BinType,
+ class PConfig = typename PlacementStrategyLike<TPlacer>::Config>
+ void packItems(TIterator first,
+ TIterator last,
+ TBin&& bin,
+ PConfig&& pconfig = PConfig())
+ {
+
+ store_.clear();
+ auto total = last-first;
+ store_.reserve(total);
+ packed_bins_.emplace_back();
+
+ auto makeProgress = [this, &total](
+ PlacementStrategyLike<TPlacer>& placer)
+ {
+ packed_bins_.back() = placer.getItems();
+#ifndef NDEBUG
+ packed_bins_.back().insert(packed_bins_.back().end(),
+ placer.getDebugItems().begin(),
+ placer.getDebugItems().end());
+#endif
+ this->progress_(--total);
+ };
+
+ std::copy(first, last, std::back_inserter(store_));
+
+ auto sortfunc = [](Item& i1, Item& i2) {
+ return i1.area() > i2.area();
+ };
+
+ std::sort(store_.begin(), store_.end(), sortfunc);
+
+ PlacementStrategyLike<TPlacer> placer(bin);
+ placer.configure(pconfig);
+
+ auto it = store_.begin();
+ while(it != store_.end()) {
+ if(!placer.pack(*it, {std::next(it), store_.end()})) {
+ if(packed_bins_.back().empty()) ++it;
+ placer.clearItems();
+ packed_bins_.emplace_back();
+ } else {
+ makeProgress(placer);
+ ++it;
+ }
+ }
+
+ }
+};
+
+}
+}
+
+#endif //BOTTOMLEFT_HPP
diff --git a/xs/src/libnest2d/libnest2d/selections/firstfit.hpp b/xs/src/libnest2d/libnest2d/selections/firstfit.hpp
new file mode 100644
index 000000000..bca7497db
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/selections/firstfit.hpp
@@ -0,0 +1,97 @@
+#ifndef FIRSTFIT_HPP
+#define FIRSTFIT_HPP
+
+#include "../libnest2d.hpp"
+#include "selection_boilerplate.hpp"
+
+namespace libnest2d { namespace selections {
+
+template<class RawShape>
+class _FirstFitSelection: public SelectionBoilerplate<RawShape> {
+ using Base = SelectionBoilerplate<RawShape>;
+public:
+ using typename Base::Item;
+ using Config = int; //dummy
+
+private:
+ using Base::packed_bins_;
+ using typename Base::ItemGroup;
+ using Container = ItemGroup;//typename std::vector<_Item<RawShape>>;
+
+ Container store_;
+
+public:
+
+ void configure(const Config& /*config*/) { }
+
+ template<class TPlacer, class TIterator,
+ class TBin = typename PlacementStrategyLike<TPlacer>::BinType,
+ class PConfig = typename PlacementStrategyLike<TPlacer>::Config>
+ void packItems(TIterator first,
+ TIterator last,
+ TBin&& bin,
+ PConfig&& pconfig = PConfig())
+ {
+
+ using Placer = PlacementStrategyLike<TPlacer>;
+
+ store_.clear();
+ store_.reserve(last-first);
+ packed_bins_.clear();
+
+ std::vector<Placer> placers;
+ placers.reserve(last-first);
+
+ std::copy(first, last, std::back_inserter(store_));
+
+ auto sortfunc = [](Item& i1, Item& i2) {
+ return i1.area() > i2.area();
+ };
+
+ std::sort(store_.begin(), store_.end(), sortfunc);
+
+ auto total = last-first;
+ auto makeProgress = [this, &total](Placer& placer, size_t idx) {
+ packed_bins_[idx] = placer.getItems();
+ this->progress_(static_cast<unsigned>(--total));
+ };
+
+ // Safety test: try to pack each item into an empty bin. If it fails
+ // then it should be removed from the list
+ { auto it = store_.begin();
+ while (it != store_.end()) {
+ Placer p(bin); p.configure(pconfig);
+ if(!p.pack(*it)) {
+ it = store_.erase(it);
+ } else it++;
+ }
+ }
+
+ auto it = store_.begin();
+
+ while(it != store_.end()) {
+ bool was_packed = false;
+ size_t j = 0;
+ while(!was_packed) {
+ for(; j < placers.size() && !was_packed; j++) {
+ if((was_packed = placers[j].pack(*it, rem(it, store_) )))
+ makeProgress(placers[j], j);
+ }
+
+ if(!was_packed) {
+ placers.emplace_back(bin);
+ placers.back().configure(pconfig);
+ packed_bins_.emplace_back();
+ j = placers.size() - 1;
+ }
+ }
+ ++it;
+ }
+ }
+
+};
+
+}
+}
+
+#endif // FIRSTFIT_HPP
diff --git a/xs/src/libnest2d/libnest2d/selections/selection_boilerplate.hpp b/xs/src/libnest2d/libnest2d/selections/selection_boilerplate.hpp
new file mode 100644
index 000000000..05bbae658
--- /dev/null
+++ b/xs/src/libnest2d/libnest2d/selections/selection_boilerplate.hpp
@@ -0,0 +1,41 @@
+#ifndef SELECTION_BOILERPLATE_HPP
+#define SELECTION_BOILERPLATE_HPP
+
+#include "../libnest2d.hpp"
+
+namespace libnest2d { namespace selections {
+
+template<class RawShape>
+class SelectionBoilerplate {
+public:
+ using Item = _Item<RawShape>;
+ using ItemRef = std::reference_wrapper<Item>;
+ using ItemGroup = std::vector<ItemRef>;
+ using PackGroup = std::vector<ItemGroup>;
+
+ size_t binCount() const { return packed_bins_.size(); }
+
+ ItemGroup itemsForBin(size_t binIndex) {
+ assert(binIndex < packed_bins_.size());
+ return packed_bins_[binIndex];
+ }
+
+ inline const ItemGroup itemsForBin(size_t binIndex) const {
+ assert(binIndex < packed_bins_.size());
+ return packed_bins_[binIndex];
+ }
+
+ inline void progressIndicator(ProgressFunction fn) {
+ progress_ = fn;
+ }
+
+protected:
+
+ PackGroup packed_bins_;
+ ProgressFunction progress_ = [](unsigned){};
+};
+
+}
+}
+
+#endif // SELECTION_BOILERPLATE_HPP
diff --git a/xs/src/libnest2d/tests/CMakeLists.txt b/xs/src/libnest2d/tests/CMakeLists.txt
new file mode 100644
index 000000000..3777f3c56
--- /dev/null
+++ b/xs/src/libnest2d/tests/CMakeLists.txt
@@ -0,0 +1,51 @@
+
+# Try to find existing GTest installation
+find_package(GTest 1.7)
+
+if(NOT GTEST_FOUND)
+ message(STATUS "GTest not found so downloading...")
+ # Go and download google test framework, integrate it with the build
+ set(GTEST_LIBS_TO_LINK gtest gtest_main)
+
+ if (CMAKE_VERSION VERSION_LESS 3.2)
+ set(UPDATE_DISCONNECTED_IF_AVAILABLE "")
+ else()
+ set(UPDATE_DISCONNECTED_IF_AVAILABLE "UPDATE_DISCONNECTED 1")
+ endif()
+
+ include(DownloadProject)
+ download_project(PROJ googletest
+ GIT_REPOSITORY https://github.com/google/googletest.git
+ GIT_TAG release-1.7.0
+ ${UPDATE_DISCONNECTED_IF_AVAILABLE}
+ )
+
+ # Prevent GoogleTest from overriding our compiler/linker options
+ # when building with Visual Studio
+ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+
+ add_subdirectory(${googletest_SOURCE_DIR}
+ ${googletest_BINARY_DIR}
+ )
+
+ set(GTEST_INCLUDE_DIRS ${googletest_SOURCE_DIR}/include)
+
+else()
+ find_package(Threads REQUIRED)
+ set(GTEST_LIBS_TO_LINK ${GTEST_BOTH_LIBRARIES} Threads::Threads)
+endif()
+
+add_executable(bp2d_tests test.cpp
+ ../tools/svgtools.hpp
+# ../tools/libnfpglue.hpp
+# ../tools/libnfpglue.cpp
+ printer_parts.h
+ printer_parts.cpp
+ ${LIBNEST2D_SRCFILES}
+ )
+target_link_libraries(bp2d_tests ${LIBNEST2D_LIBRARIES} ${GTEST_LIBS_TO_LINK} )
+
+target_include_directories(bp2d_tests PRIVATE BEFORE ${LIBNEST2D_HEADERS}
+ ${GTEST_INCLUDE_DIRS})
+
+add_test(libnest2d_tests bp2d_tests)
diff --git a/xs/src/libnest2d/tests/printer_parts.cpp b/xs/src/libnest2d/tests/printer_parts.cpp
new file mode 100644
index 000000000..bdc2a3d43
--- /dev/null
+++ b/xs/src/libnest2d/tests/printer_parts.cpp
@@ -0,0 +1,3175 @@
+#include "printer_parts.h"
+
+const TestData PRINTER_PART_POLYGONS =
+{
+ {
+ {-5000000, 8954050},
+ {5000000, 8954050},
+ {5000000, -45949},
+ {4972609, -568550},
+ {3500000, -8954050},
+ {-3500000, -8954050},
+ {-4972609, -568550},
+ {-5000000, -45949},
+ {-5000000, 8954050},
+ },
+ {
+ {-63750000, -8000000},
+ {-54750000, 46000000},
+ {50750000, 46000000},
+ {63750000, 33000000},
+ {63750000, -46000000},
+ {-54750000, -46000000},
+ {-63750000, -28000000},
+ {-63750000, -8000000},
+ },
+ {
+ {-52750000, 41512348},
+ {-31250000, 45987651},
+ {52750000, 45987651},
+ {52750000, -45987651},
+ {-52750000, -45987651},
+ {-52750000, 41512348},
+ },
+ {
+ {-3900000, 14000000},
+ {-2167950, 14000000},
+ {1721454, 7263400},
+ {3828529, 3613790},
+ {3838809, 3582149},
+ {3871560, 3270569},
+ {3900000, 3000000},
+ {3500000, -3000000},
+ {3471560, -3270565},
+ {3447549, -3498986},
+ {3292510, -3976167},
+ {3099999, -4512949},
+ {2530129, -5500000},
+ {807565, -8483570},
+ {-2377349, -14000000},
+ {-3900000, -14000000},
+ {-3900000, 14000000},
+ },
+ {
+ {-31750000, -1000000},
+ {-25250000, 40500000},
+ {-18250000, 47500000},
+ {10750000, 47500000},
+ {16750000, 41500000},
+ {31750000, -37000000},
+ {31750000, -43857898},
+ {28107900, -47500000},
+ {18392099, -47500000},
+ {-20750000, -46500000},
+ {-31750000, -4000000},
+ {-31750000, -1000000},
+ },
+ {
+ {-34625000, -14265399},
+ {-10924999, 24875000},
+ {33325000, 24875000},
+ {37575000, 20625000},
+ {37575000, 17625000},
+ {26575000, -24875000},
+ {-8924999, -24875000},
+ {-34625000, -24484600},
+ {-37575000, -19375000},
+ {-34625000, -14265399},
+ },
+ {
+ {-14000000, 9000000},
+ {-11000000, 17000000},
+ {14000000, 17000000},
+ {14000000, -17000000},
+ {-11000000, -17000000},
+ {-14000000, -8000000},
+ {-14000000, 9000000},
+ },
+ {
+ {-5300000, 2227401},
+ {-237800, 5150001},
+ {5299999, 5150001},
+ {5299999, 650001},
+ {4699999, -5149997},
+ {-5300000, -5149997},
+ {-5300000, 2227401},
+ },
+ {
+ {-12000000, 18000000},
+ {12000000, 18000000},
+ {12000000, -18000000},
+ {-12000000, -18000000},
+ {-12000000, 18000000},
+ },
+ {
+ {-18000000, -1000000},
+ {-15000000, 22000000},
+ {-11000000, 26000000},
+ {11000000, 26000000},
+ {15000000, 22000000},
+ {18000000, -1000000},
+ {18000000, -26000000},
+ {-18000000, -26000000},
+ {-18000000, -1000000},
+ },
+ {
+ {-77500000, 30000000},
+ {-72500000, 35000000},
+ {72500000, 35000000},
+ {77500000, 30000000},
+ {77500000, -32928901},
+ {75428901, -35000000},
+ {-75428901, -35000000},
+ {-77500000, -32928901},
+ {-77500000, 30000000},
+ },
+ {
+ {-9945219, -3065619},
+ {-9781479, -2031780},
+ {-9510560, -1020730},
+ {-9135450, -43529},
+ {-2099999, 14110899},
+ {2099999, 14110899},
+ {9135450, -43529},
+ {9510560, -1020730},
+ {9781479, -2031780},
+ {9945219, -3065619},
+ {10000000, -4110899},
+ {9945219, -5156179},
+ {9781479, -6190019},
+ {9510560, -7201069},
+ {9135450, -8178270},
+ {8660249, -9110899},
+ {8090169, -9988750},
+ {7431449, -10802209},
+ {6691309, -11542349},
+ {5877850, -12201069},
+ {5000000, -12771149},
+ {4067369, -13246350},
+ {3090169, -13621459},
+ {2079119, -13892379},
+ {1045279, -14056119},
+ {0, -14110899},
+ {-1045279, -14056119},
+ {-2079119, -13892379},
+ {-3090169, -13621459},
+ {-4067369, -13246350},
+ {-5000000, -12771149},
+ {-5877850, -12201069},
+ {-6691309, -11542349},
+ {-7431449, -10802209},
+ {-8090169, -9988750},
+ {-8660249, -9110899},
+ {-9135450, -8178270},
+ {-9510560, -7201069},
+ {-9781479, -6190019},
+ {-9945219, -5156179},
+ {-10000000, -4110899},
+ {-9945219, -3065619},
+ },
+ {
+ {-34192394, -5192389},
+ {-31499996, 39000000},
+ {-8183795, 47668998},
+ {-6769596, 47668998},
+ {-4648197, 45547698},
+ {34192394, 6707109},
+ {34192394, 5192389},
+ {31500003, -39000000},
+ {8183803, -47668998},
+ {6769603, -47668998},
+ {4648202, -45547698},
+ {-32474895, -8424619},
+ {-34192394, -6707109},
+ {-34192394, -5192389},
+ },
+ {
+ {-23475500, -11910099},
+ {-18000000, 8217699},
+ {-11139699, 20100000},
+ {-10271400, 20899999},
+ {9532010, 20899999},
+ {11199999, 20100000},
+ {18500000, 8600000},
+ {23475500, -11910099},
+ {23799999, -14899999},
+ {23706600, -15788900},
+ {23668899, -16147499},
+ {23281299, -17340400},
+ {22654100, -18426700},
+ {21814800, -19358900},
+ {20799999, -20096199},
+ {19654100, -20606300},
+ {18427200, -20867099},
+ {17799999, -20899999},
+ {-17799999, -20899999},
+ {-18427200, -20867099},
+ {-19654100, -20606300},
+ {-20799999, -20096199},
+ {-21814800, -19358900},
+ {-22654100, -18426700},
+ {-23281299, -17340400},
+ {-23668899, -16147499},
+ {-23799999, -14899999},
+ {-23475500, -11910099},
+ },
+ {
+ {-32000000, 10000000},
+ {-31934440, 10623733},
+ {-31740640, 11220210},
+ {-31427049, 11763360},
+ {-31007389, 12229430},
+ {-30500000, 12598079},
+ {-29927051, 12853170},
+ {-29313585, 12983570},
+ {16000000, 16000000},
+ {26000000, 16000000},
+ {31007400, 12229430},
+ {31427101, 11763360},
+ {31740600, 11220210},
+ {31934398, 10623733},
+ {32000000, 10000000},
+ {32000000, -13000000},
+ {31934398, -13623699},
+ {31740600, -14220199},
+ {31427101, -14763399},
+ {31007400, -15229400},
+ {30500000, -15598100},
+ {29927101, -15853200},
+ {29313598, -15983600},
+ {29000000, -16000000},
+ {-28000000, -16000000},
+ {-29313585, -15983600},
+ {-29927051, -15853200},
+ {-30500000, -15598100},
+ {-31007389, -15229400},
+ {-31427049, -14763399},
+ {-31740640, -14220199},
+ {-31934440, -13623699},
+ {-32000000, -13000000},
+ {-32000000, 10000000},
+ },
+ {
+ {-36133789, -46431022},
+ {-36040100, -46171817},
+ {-35852722, -45653411},
+ {2200073, 59616485},
+ {12112792, 87039184},
+ {14274505, 93019332},
+ {14382049, 93291641},
+ {14508483, 93563430},
+ {14573425, 93688369},
+ {14654052, 93832443},
+ {14818634, 94096328},
+ {14982757, 94327621},
+ {15001708, 94352630},
+ {15202392, 94598999},
+ {15419342, 94833160},
+ {15497497, 94910552},
+ {15650848, 95053039},
+ {15894866, 95256866},
+ {16104309, 95412185},
+ {16149047, 95443206},
+ {16410888, 95611038},
+ {16677795, 95759750},
+ {16782348, 95812332},
+ {16947143, 95889144},
+ {17216400, 95999465},
+ {17483123, 96091293},
+ {17505554, 96098251},
+ {17745178, 96165542},
+ {18000671, 96223373},
+ {18245880, 96265884},
+ {18484039, 96295257},
+ {18976715, 96319580},
+ {31135131, 96319580},
+ {31697082, 96287902},
+ {31746368, 96282104},
+ {32263000, 96190719},
+ {32338623, 96172576},
+ {32821411, 96026641},
+ {32906188, 95995391},
+ {33360565, 95797012},
+ {33443420, 95754882},
+ {33869171, 95505874},
+ {33900756, 95485122},
+ {34136413, 95318618},
+ {34337127, 95159790},
+ {34377288, 95125930},
+ {34619628, 94905410},
+ {34756286, 94767364},
+ {34859008, 94656143},
+ {35090606, 94378067},
+ {35120849, 94338546},
+ {35309295, 94072113},
+ {35434875, 93871475},
+ {35510070, 93740310},
+ {35688232, 93385772},
+ {35699096, 93361679},
+ {35839782, 93012557},
+ {35905487, 92817459},
+ {35961578, 92625488},
+ {36048004, 92249023},
+ {36051574, 92229934},
+ {36108856, 91831405},
+ {36122985, 91667816},
+ {36133789, 91435317},
+ {36129669, 91085830},
+ {36127685, 91046661},
+ {36092742, 90669830},
+ {36069946, 90514739},
+ {36031829, 90308425},
+ {35948211, 89965225},
+ {34482635, 84756820},
+ {27911407, 61403976},
+ {-5872558, -58657440},
+ {-14243621, -88406509},
+ {-14576812, -89590599},
+ {-15421997, -92594200},
+ {-15657684, -93431732},
+ {-16038940, -93720520},
+ {-16420196, -94009307},
+ {-17182708, -94586875},
+ {-18834838, -95838272},
+ {-19470275, -96319580},
+ {-21368133, -96319580},
+ {-22763854, -96319534},
+ {-29742462, -96319274},
+ {-32533935, -96319168},
+ {-36133789, -54619018},
+ {-36133789, -46431022},
+ },
+ {
+ {-26000000, 25500000},
+ {-6500000, 45000000},
+ {17499998, 45000000},
+ {23966310, 38533699},
+ {26000000, 36500000},
+ {26000000, -19000000},
+ {25950000, -24500000},
+ {17000000, -42214698},
+ {14300000, -45000000},
+ {-14299999, -45000000},
+ {-17500000, -41714698},
+ {-23400001, -24500000},
+ {-26000000, -10464000},
+ {-26000000, 25500000},
+ },
+ {
+ {-26000000, 16636100},
+ {-25072200, 18777799},
+ {-16500000, 35299999},
+ {-15050000, 36750000},
+ {13550000, 36750000},
+ {15000000, 35299999},
+ {26000000, 16045200},
+ {26000000, -2750000},
+ {16500000, -34507900},
+ {14840600, -36167301},
+ {14257900, -36750000},
+ {-14257900, -36750000},
+ {-16500000, -34507900},
+ {-26000000, -2750000},
+ {-26000000, 16636100},
+ },
+ {
+ {-18062349, 18950099},
+ {4644938, 20049900},
+ {6230361, 20049900},
+ {7803279, 19851200},
+ {9338899, 19456899},
+ {10812990, 18873300},
+ {12202310, 18109500},
+ {13484951, 17177600},
+ {14640670, 16092300},
+ {15651250, 14870700},
+ {16500749, 13532100},
+ {17175849, 12097599},
+ {17665750, 10589700},
+ {17962850, 9032400},
+ {18062349, 7450099},
+ {17962850, 5867799},
+ {15810750, -11007740},
+ {15683750, -11727769},
+ {15506849, -12437200},
+ {15280929, -13132559},
+ {15007040, -13810470},
+ {14686531, -14467609},
+ {14320949, -15100799},
+ {13912099, -15706950},
+ {13461959, -16283100},
+ {12972730, -16826450},
+ {12446790, -17334339},
+ {11886699, -17804309},
+ {11295190, -18234069},
+ {10675149, -18621520},
+ {10029590, -18964771},
+ {9361650, -19262149},
+ {8674600, -19512220},
+ {7971780, -19713699},
+ {7256609, -19865798},
+ {6532589, -19967498},
+ {5803222, -20018501},
+ {5437650, -20024900},
+ {-1062349, -20049900},
+ {-16562349, -20049900},
+ {-18062349, -18549900},
+ {-18062349, 18950099},
+ },
+ {
+ {-18062349, 41299900},
+ {-1062349, 41299900},
+ {15280929, -8117440},
+ {15506849, -8812799},
+ {15683750, -9522230},
+ {15810750, -10242259},
+ {17962850, -27117799},
+ {18062349, -28700099},
+ {17962850, -30282400},
+ {17665750, -31839700},
+ {17175849, -33347599},
+ {16500749, -34782100},
+ {15651250, -36120700},
+ {14640670, -37342300},
+ {13484951, -38427600},
+ {12202310, -39359500},
+ {10812990, -40123298},
+ {9338899, -40706901},
+ {7803279, -41101200},
+ {6230361, -41299900},
+ {4644938, -41299900},
+ {-18062349, -40200099},
+ {-18062349, 41299900},
+ },
+ {
+ {-11750000, 13057900},
+ {-9807860, 15000000},
+ {4392139, 24000000},
+ {11750000, 24000000},
+ {11750000, -24000000},
+ {4392139, -24000000},
+ {-9807860, -15000000},
+ {-11750000, -13057900},
+ {-11750000, 13057900},
+ },
+ {
+ {-12500000, 17500000},
+ {12500000, 17500000},
+ {12500000, -17500000},
+ {-12500000, -17500000},
+ {-12500000, 17500000},
+ },
+ {
+ {-23500000, 11500000},
+ {-13857859, 21000000},
+ {-11000000, 21000000},
+ {18500000, 500000},
+ {23500000, -4500000},
+ {23500000, -19500000},
+ {22000000, -21000000},
+ {-23500000, -21000000},
+ {-23500000, 11500000},
+ },
+ {
+ {-13000000, 5250000},
+ {-4000000, 6750000},
+ {4000000, 6750000},
+ {13000000, 5250000},
+ {13000000, 838459},
+ {11376299, -1973939},
+ {10350899, -3750000},
+ {8618800, -6750000},
+ {-8498290, -6750000},
+ {-13000000, 1047180},
+ {-13000000, 5250000},
+ },
+ {
+ {-25000000, 50500000},
+ {-21500000, 54000000},
+ {18286800, 54000000},
+ {25000000, 47286800},
+ {25000000, -47286800},
+ {18286800, -54000000},
+ {-21500000, -54000000},
+ {-25000000, -50500000},
+ {-25000000, 50500000},
+ },
+ {
+ {-19000000, 46000000},
+ {-16799999, 46000000},
+ {14000000, 34000000},
+ {19000000, 29000000},
+ {19000000, -29000000},
+ {14000000, -34000000},
+ {-16799999, -46000000},
+ {-19000000, -46000000},
+ {-19000000, 46000000},
+ },
+ {
+ {-7956170, 836226},
+ {-7825180, 1663290},
+ {-7767529, 1914530},
+ {-7608449, 2472140},
+ {-7308360, 3253890},
+ {-7083650, 3717780},
+ {-6928199, 4000000},
+ {-6472139, 4702280},
+ {-5988090, 5304979},
+ {-5945159, 5353040},
+ {-5353040, 5945159},
+ {-4702280, 6472139},
+ {-4544519, 6583869},
+ {-4000000, 6928199},
+ {-3253890, 7308360},
+ {-2836839, 7480130},
+ {-2472140, 7608449},
+ {-1663290, 7825180},
+ {-964293, 7941669},
+ {-836226, 7956170},
+ {0, 8000000},
+ {836226, 7956170},
+ {964293, 7941669},
+ {1663290, 7825180},
+ {2472140, 7608449},
+ {2836839, 7480130},
+ {3253890, 7308360},
+ {4000000, 6928199},
+ {4544519, 6583869},
+ {4702280, 6472139},
+ {5353040, 5945159},
+ {5945159, 5353040},
+ {5988090, 5304979},
+ {6472139, 4702280},
+ {6928199, 4000000},
+ {7083650, 3717780},
+ {7308360, 3253890},
+ {7608449, 2472140},
+ {7767529, 1914530},
+ {7825180, 1663290},
+ {7956170, 836226},
+ {8000000, 0},
+ {7956170, -836226},
+ {7825180, -1663290},
+ {7767529, -1914530},
+ {7608449, -2472140},
+ {7308360, -3253890},
+ {7083650, -3717780},
+ {6928199, -4000000},
+ {6472139, -4702280},
+ {5988090, -5304979},
+ {5945159, -5353040},
+ {5353040, -5945159},
+ {4702280, -6472139},
+ {4544519, -6583869},
+ {4000000, -6928199},
+ {3253890, -7308360},
+ {2836839, -7480130},
+ {2472140, -7608449},
+ {1663290, -7825180},
+ {964293, -7941669},
+ {836226, -7956170},
+ {0, -8000000},
+ {-836226, -7956170},
+ {-964293, -7941669},
+ {-1663290, -7825180},
+ {-2472140, -7608449},
+ {-2836839, -7480130},
+ {-3253890, -7308360},
+ {-4000000, -6928199},
+ {-4544519, -6583869},
+ {-4702280, -6472139},
+ {-5353040, -5945159},
+ {-5945159, -5353040},
+ {-5988090, -5304979},
+ {-6472139, -4702280},
+ {-6928199, -4000000},
+ {-7083650, -3717780},
+ {-7308360, -3253890},
+ {-7608449, -2472140},
+ {-7767529, -1914530},
+ {-7825180, -1663290},
+ {-7956170, -836226},
+ {-8000000, 0},
+ {-7956170, 836226},
+ },
+};
+
+const TestData STEGOSAUR_POLYGONS =
+{
+ {
+ {113210205, 107034095},
+ {113561798, 109153793},
+ {113750099, 109914001},
+ {114396499, 111040199},
+ {114599197, 111321998},
+ {115570404, 112657096},
+ {116920097, 114166595},
+ {117630599, 114609390},
+ {119703704, 115583900},
+ {120559494, 115811996},
+ {121045410, 115754493},
+ {122698097, 115526496},
+ {123373001, 115370193},
+ {123482406, 115315689},
+ {125664199, 114129798},
+ {125920303, 113968193},
+ {128551208, 111866195},
+ {129075592, 111443199},
+ {135044692, 106572608},
+ {135254898, 106347694},
+ {135415100, 106102897},
+ {136121704, 103779891},
+ {136325103, 103086303},
+ {136690093, 101284896},
+ {136798309, 97568496},
+ {136798309, 97470397},
+ {136787399, 97375297},
+ {136753295, 97272102},
+ {136687988, 97158699},
+ {136539794, 96946899},
+ {135526702, 95550994},
+ {135388488, 95382293},
+ {135272491, 95279098},
+ {135214904, 95250595},
+ {135122894, 95218002},
+ {134966705, 95165191},
+ {131753997, 94380798},
+ {131226806, 94331001},
+ {129603393, 94193893},
+ {129224197, 94188003},
+ {127874107, 94215103},
+ {126812797, 94690200},
+ {126558197, 94813896},
+ {118361801, 99824195},
+ {116550796, 101078796},
+ {116189704, 101380493},
+ {114634002, 103027999},
+ {114118103, 103820297},
+ {113399200, 105568000},
+ {113201705, 106093597},
+ {113210205, 107034095},
+ },
+ {
+ {77917999, 130563003},
+ {77926300, 131300903},
+ {77990196, 132392700},
+ {78144195, 133328002},
+ {78170593, 133427093},
+ {78235900, 133657592},
+ {78799598, 135466705},
+ {78933296, 135832397},
+ {79112899, 136247604},
+ {79336303, 136670898},
+ {79585197, 137080596},
+ {79726303, 137309005},
+ {79820297, 137431900},
+ {79942199, 137549407},
+ {90329193, 145990203},
+ {90460197, 146094390},
+ {90606399, 146184509},
+ {90715194, 146230010},
+ {90919601, 146267211},
+ {142335296, 153077697},
+ {143460296, 153153594},
+ {143976593, 153182189},
+ {145403991, 153148605},
+ {145562301, 153131195},
+ {145705993, 153102905},
+ {145938796, 153053192},
+ {146134094, 153010101},
+ {146483184, 152920196},
+ {146904693, 152806396},
+ {147180099, 152670196},
+ {147357788, 152581695},
+ {147615295, 152423095},
+ {147782287, 152294708},
+ {149281799, 150908386},
+ {149405303, 150784912},
+ {166569305, 126952499},
+ {166784301, 126638099},
+ {166938491, 126393699},
+ {167030899, 126245101},
+ {167173004, 126015899},
+ {167415298, 125607200},
+ {167468292, 125504699},
+ {167553100, 125320899},
+ {167584594, 125250694},
+ {167684997, 125004394},
+ {167807098, 124672401},
+ {167938995, 124255203},
+ {168052307, 123694000},
+ {170094100, 112846900},
+ {170118408, 112684204},
+ {172079101, 88437797},
+ {172082000, 88294403},
+ {171916290, 82827606},
+ {171911590, 82705703},
+ {171874893, 82641906},
+ {169867004, 79529907},
+ {155996795, 58147998},
+ {155904998, 58066299},
+ {155864791, 58054199},
+ {134315704, 56830902},
+ {134086486, 56817901},
+ {98200096, 56817798},
+ {97838195, 56818599},
+ {79401695, 56865097},
+ {79291297, 56865501},
+ {79180694, 56869499},
+ {79058799, 56885097},
+ {78937301, 56965301},
+ {78324691, 57374599},
+ {77932998, 57638401},
+ {77917999, 57764297},
+ {77917999, 130563003},
+ },
+ {
+ {75566848, 109289947},
+ {75592651, 109421951},
+ {75644248, 109534446},
+ {95210548, 141223846},
+ {95262649, 141307449},
+ {95487854, 141401443},
+ {95910850, 141511642},
+ {96105651, 141550338},
+ {106015045, 142803451},
+ {106142852, 142815155},
+ {166897460, 139500244},
+ {167019348, 139484741},
+ {168008239, 138823043},
+ {168137542, 138735153},
+ {168156250, 138616851},
+ {173160751, 98882049},
+ {174381546, 87916046},
+ {174412246, 87579048},
+ {174429443, 86988746},
+ {174436141, 86297348},
+ {174438949, 84912048},
+ {174262939, 80999145},
+ {174172546, 80477546},
+ {173847549, 79140846},
+ {173623840, 78294349},
+ {173120239, 76485046},
+ {173067138, 76300544},
+ {173017852, 76137542},
+ {172941543, 75903045},
+ {172892547, 75753143},
+ {172813537, 75533348},
+ {172758453, 75387046},
+ {172307556, 74196746},
+ {171926544, 73192848},
+ {171891448, 73100448},
+ {171672546, 72524147},
+ {171502441, 72085144},
+ {171414459, 71859146},
+ {171294250, 71552352},
+ {171080139, 71019744},
+ {171039245, 70928146},
+ {170970550, 70813346},
+ {170904235, 70704040},
+ {170786254, 70524353},
+ {168063247, 67259048},
+ {167989547, 67184844},
+ {83427947, 67184844},
+ {78360847, 67201248},
+ {78238845, 67220550},
+ {78151550, 67350547},
+ {77574554, 68220550},
+ {77494949, 68342651},
+ {77479949, 68464546},
+ {75648345, 106513351},
+ {75561050, 109165740},
+ {75566848, 109289947},
+ },
+ {
+ {75619415, 108041595},
+ {83609863, 134885772},
+ {83806945, 135450820},
+ {83943908, 135727371},
+ {84799934, 137289794},
+ {86547897, 140033782},
+ {86674118, 140192962},
+ {86810661, 140364715},
+ {87045211, 140619918},
+ {88187042, 141853240},
+ {93924575, 147393783},
+ {94058013, 147454803},
+ {111640083, 153754562},
+ {111762550, 153787933},
+ {111975250, 153835311},
+ {112127426, 153842803},
+ {116797996, 154005157},
+ {116969688, 154010681},
+ {117141731, 154005935},
+ {117333145, 153988037},
+ {118007507, 153919952},
+ {118159675, 153902130},
+ {118931480, 153771942},
+ {120878150, 153379089},
+ {121172164, 153319259},
+ {122074508, 153034362},
+ {122260681, 152970367},
+ {122313438, 152949584},
+ {130755096, 149423736},
+ {130996063, 149316818},
+ {138893524, 144469665},
+ {138896423, 144466918},
+ {169883666, 97686134},
+ {170115036, 96518981},
+ {170144317, 96365257},
+ {174395645, 67672065},
+ {174396560, 67664222},
+ {174288452, 66839241},
+ {174170364, 66096923},
+ {174112731, 65952033},
+ {174021377, 65823486},
+ {173948608, 65743225},
+ {173863830, 65654769},
+ {170408340, 63627494},
+ {170004867, 63394714},
+ {169585632, 63194389},
+ {169441162, 63137046},
+ {168944274, 62952133},
+ {160605072, 60214218},
+ {160331573, 60126396},
+ {159674743, 59916877},
+ {150337249, 56943778},
+ {150267730, 56922073},
+ {150080139, 56864868},
+ {149435333, 56676422},
+ {149310241, 56640579},
+ {148055419, 56285041},
+ {147828796, 56230949},
+ {147598205, 56181800},
+ {147149963, 56093917},
+ {146834457, 56044700},
+ {146727966, 56028717},
+ {146519729, 56004882},
+ {146328521, 55989326},
+ {146170684, 55990036},
+ {146151321, 55990745},
+ {145800170, 56003616},
+ {145639526, 56017753},
+ {145599426, 56022491},
+ {145481338, 56039184},
+ {145389556, 56052757},
+ {145325134, 56062591},
+ {145176574, 56086135},
+ {145017272, 56113922},
+ {107163085, 63504539},
+ {101013870, 65454101},
+ {100921798, 65535285},
+ {95362182, 74174079},
+ {75652366, 107803443},
+ {75635391, 107834983},
+ {75628814, 107853294},
+ {75603431, 107933692},
+ {75619415, 108041595},
+ },
+ {
+ {83617141, 120264900},
+ {84617370, 126416427},
+ {84648635, 126601341},
+ {84693695, 126816085},
+ {84762496, 127082641},
+ {84772140, 127117034},
+ {84860748, 127391693},
+ {84927398, 127550239},
+ {85072967, 127789642},
+ {85155151, 127908851},
+ {86745422, 130042907},
+ {86982666, 130317489},
+ {89975143, 133230743},
+ {90091384, 133338500},
+ {96260833, 138719818},
+ {96713928, 139103668},
+ {98139297, 140307388},
+ {102104766, 143511505},
+ {102142089, 143536468},
+ {102457626, 143735107},
+ {103386764, 144312988},
+ {103845001, 144579177},
+ {104139175, 144737136},
+ {104551254, 144932250},
+ {104690155, 144985778},
+ {104844238, 145010009},
+ {105020034, 145010375},
+ {128999633, 144082305},
+ {129096542, 144076141},
+ {133932327, 143370178},
+ {134130615, 143326751},
+ {134281250, 143289520},
+ {135247116, 142993438},
+ {150774948, 137828704},
+ {150893478, 137786178},
+ {151350921, 137608901},
+ {159797760, 134318115},
+ {159979827, 134244384},
+ {159988128, 134240997},
+ {160035186, 134221633},
+ {160054962, 134211486},
+ {160168762, 134132736},
+ {160181228, 134121047},
+ {160336425, 133961502},
+ {160689147, 133564331},
+ {161446258, 132710739},
+ {163306427, 130611648},
+ {164845474, 128873855},
+ {165270233, 128393600},
+ {165281478, 128380706},
+ {165300598, 128358673},
+ {165303497, 128355194},
+ {166411590, 122772674},
+ {166423767, 122708648},
+ {164745605, 66237312},
+ {164740341, 66193061},
+ {164721755, 66082092},
+ {164721160, 66078750},
+ {164688476, 65914146},
+ {164668426, 65859436},
+ {164563110, 65765937},
+ {164431152, 65715034},
+ {163997619, 65550788},
+ {163946426, 65531440},
+ {162998107, 65173629},
+ {162664978, 65049140},
+ {162482696, 64991668},
+ {162464660, 64989639},
+ {148029083, 66896141},
+ {147862396, 66932853},
+ {130087829, 73341102},
+ {129791564, 73469726},
+ {100590927, 90307685},
+ {100483535, 90373847},
+ {100364990, 90458930},
+ {96447448, 93276664},
+ {95179656, 94189010},
+ {93692718, 95260208},
+ {87904327, 99430885},
+ {87663711, 99606147},
+ {87576202, 99683990},
+ {87498199, 99801719},
+ {85740264, 104173728},
+ {85538925, 104710494},
+ {84786132, 107265830},
+ {84635955, 107801383},
+ {84619506, 107868064},
+ {84518463, 108287200},
+ {84456848, 108613471},
+ {84419158, 108826194},
+ {84375244, 109093818},
+ {84329818, 109435180},
+ {84249862, 110179664},
+ {84218429, 110572166},
+ {83630020, 117995208},
+ {83595535, 118787673},
+ {83576217, 119290679},
+ {83617141, 120264900},
+ },
+ {
+ {91735549, 117640846},
+ {91748252, 117958145},
+ {91823547, 118515449},
+ {92088752, 119477249},
+ {97995346, 140538452},
+ {98031051, 140660446},
+ {98154449, 141060241},
+ {98179855, 141133758},
+ {98217056, 141232849},
+ {98217147, 141233047},
+ {98269256, 141337051},
+ {98298950, 141387954},
+ {98337753, 141445755},
+ {99455047, 142984451},
+ {99656250, 143247344},
+ {102567855, 146783752},
+ {102685150, 146906845},
+ {102828948, 147031250},
+ {102972457, 147120452},
+ {103676147, 147539642},
+ {103758956, 147586151},
+ {103956756, 147682144},
+ {104479949, 147931457},
+ {104744453, 148044143},
+ {104994750, 148123443},
+ {105375648, 148158645},
+ {109266250, 148178253},
+ {109447753, 148169052},
+ {109693649, 148129150},
+ {113729949, 147337448},
+ {113884552, 147303054},
+ {115155349, 146956146},
+ {117637145, 146174346},
+ {154694046, 134048049},
+ {156979949, 133128555},
+ {157076843, 133059356},
+ {157125045, 133001449},
+ {157561340, 132300750},
+ {157865753, 131795959},
+ {157923156, 131667358},
+ {158007049, 131297653},
+ {158112747, 130777053},
+ {158116653, 130640853},
+ {158268951, 119981643},
+ {158260040, 119824752},
+ {158229949, 119563751},
+ {149914047, 73458648},
+ {149877548, 73331748},
+ {144460754, 66413558},
+ {144230545, 66153152},
+ {144128051, 66075057},
+ {143974853, 65973152},
+ {142812744, 65353149},
+ {141810943, 64837249},
+ {141683349, 64805152},
+ {141505157, 64784652},
+ {108214355, 61896251},
+ {107826354, 61866352},
+ {107072151, 61821750},
+ {106938850, 61873550},
+ {106584251, 62055152},
+ {106419952, 62147548},
+ {100459152, 65546951},
+ {100343849, 65615150},
+ {100198852, 65716949},
+ {99825149, 65979751},
+ {94619247, 70330352},
+ {94492355, 70480850},
+ {94445846, 70547355},
+ {94425354, 70588752},
+ {94379753, 70687652},
+ {94110252, 71443450},
+ {94095252, 71569053},
+ {91737251, 117308746},
+ {91731048, 117430946},
+ {91735549, 117640846},
+ },
+ {
+ {108231399, 111763748},
+ {108335403, 111927955},
+ {108865203, 112754745},
+ {109206703, 113283851},
+ {127117500, 125545951},
+ {127212097, 125560951},
+ {127358497, 125563652},
+ {131348007, 125551147},
+ {131412002, 125550849},
+ {131509506, 125535446},
+ {131579391, 125431343},
+ {132041000, 124735656},
+ {132104690, 124637847},
+ {144108505, 100950546},
+ {144120605, 100853042},
+ {144123291, 100764648},
+ {144122695, 100475143},
+ {144086898, 85637748},
+ {144083602, 85549346},
+ {144071105, 85451843},
+ {144007003, 85354545},
+ {143679595, 84864547},
+ {143468597, 84551048},
+ {143367889, 84539146},
+ {109847702, 84436347},
+ {109684700, 84458953},
+ {105946502, 89406143},
+ {105915901, 91160446},
+ {105880905, 93187744},
+ {105876701, 93441345},
+ {108231399, 111763748},
+ },
+ {
+ {102614700, 117684249},
+ {102675102, 118074157},
+ {102888999, 118743148},
+ {103199707, 119517555},
+ {103446800, 120099655},
+ {103488204, 120193450},
+ {104063903, 121373947},
+ {104535499, 122192245},
+ {104595802, 122295249},
+ {104663002, 122402854},
+ {104945701, 122854858},
+ {105740501, 124038848},
+ {106809700, 125479354},
+ {107564399, 126380050},
+ {108116203, 126975646},
+ {123724700, 142516540},
+ {124938400, 143705444},
+ {127919601, 146599243},
+ {128150894, 146821456},
+ {128251602, 146917251},
+ {128383605, 147041839},
+ {128527709, 147176147},
+ {128685699, 147321456},
+ {128861007, 147481246},
+ {132825103, 151046661},
+ {133005493, 151205657},
+ {133389007, 151488143},
+ {133896499, 151858062},
+ {134172302, 151991546},
+ {134375000, 152063140},
+ {135316101, 152300949},
+ {136056304, 152220947},
+ {136242706, 152186843},
+ {136622207, 152016448},
+ {136805404, 151908355},
+ {147099594, 145766845},
+ {147246704, 144900756},
+ {147387603, 144048461},
+ {144353698, 99345855},
+ {144333801, 99232254},
+ {144244598, 98812850},
+ {144228698, 98757858},
+ {144174606, 98616455},
+ {133010101, 72396743},
+ {132018905, 70280853},
+ {130667404, 67536949},
+ {129167297, 64854446},
+ {128569198, 64098350},
+ {124458503, 59135948},
+ {124260597, 58946949},
+ {123908706, 58658851},
+ {123460098, 58327850},
+ {122674499, 57840648},
+ {122041801, 57712150},
+ {121613403, 57699047},
+ {121359901, 57749351},
+ {121123199, 57826450},
+ {120953498, 57882247},
+ {120431701, 58198547},
+ {120099205, 58599349},
+ {119892303, 58903049},
+ {102835296, 115179351},
+ {102686599, 115817245},
+ {102612396, 116540557},
+ {102614700, 117684249},
+ },
+ {
+ {98163757, 71203430},
+ {98212463, 73314544},
+ {98326538, 74432693},
+ {98402908, 75169799},
+ {98524154, 76328353},
+ {99088806, 79911361},
+ {99304885, 80947769},
+ {100106689, 84244186},
+ {100358123, 85080337},
+ {101715545, 89252807},
+ {101969528, 89987213},
+ {107989440, 106391418},
+ {126299575, 140277343},
+ {127061813, 141486663},
+ {127405746, 141872253},
+ {127846908, 142318450},
+ {130818496, 145301574},
+ {134366424, 148100921},
+ {135308380, 148798828},
+ {135745666, 149117523},
+ {136033020, 149251800},
+ {136500579, 149387725},
+ {136662719, 149418395},
+ {136973922, 149474822},
+ {137184890, 149484375},
+ {137623748, 149434356},
+ {137830810, 149355072},
+ {138681732, 148971343},
+ {139374465, 148463409},
+ {139589187, 148264312},
+ {139809707, 148010711},
+ {139985610, 147685028},
+ {140196029, 147284973},
+ {140355834, 146978668},
+ {142079666, 142575622},
+ {146702194, 129469726},
+ {151285888, 113275238},
+ {151543731, 112046264},
+ {151701629, 110884704},
+ {151837020, 108986206},
+ {151837097, 107724029},
+ {151760101, 106529205},
+ {151581970, 105441925},
+ {151577301, 105413757},
+ {151495269, 105014709},
+ {151393142, 104551513},
+ {151058502, 103296112},
+ {150705520, 102477264},
+ {150137725, 101686370},
+ {149427032, 100938537},
+ {102979965, 60772064},
+ {101930953, 60515609},
+ {101276748, 60634414},
+ {100717803, 60918136},
+ {100125732, 61584625},
+ {99618148, 62413436},
+ {99457214, 62709442},
+ {99368347, 62914794},
+ {99166992, 63728332},
+ {98313827, 69634780},
+ {98176910, 70615707},
+ {98162902, 70798233},
+ {98163757, 71203430},
+ },
+ {
+ {79090698, 116426399},
+ {80959800, 137087692},
+ {81030303, 137762298},
+ {81190704, 138903503},
+ {81253700, 139084197},
+ {81479301, 139544998},
+ {81952003, 140118896},
+ {82319900, 140523895},
+ {82967803, 140993896},
+ {83022903, 141032104},
+ {83777900, 141493606},
+ {84722099, 141849899},
+ {84944396, 141887207},
+ {86144699, 141915893},
+ {87643997, 141938095},
+ {88277503, 141887695},
+ {88582099, 141840606},
+ {89395401, 141712203},
+ {90531204, 141528396},
+ {91014801, 141438400},
+ {92097595, 141190093},
+ {123348297, 132876998},
+ {123399505, 132860000},
+ {123452804, 132841506},
+ {123515502, 132818908},
+ {123543800, 132806198},
+ {124299598, 132437393},
+ {124975502, 132042098},
+ {125047500, 131992202},
+ {125119506, 131930603},
+ {166848800, 86317703},
+ {168976409, 83524902},
+ {169359603, 82932701},
+ {169852600, 81917800},
+ {170686904, 79771202},
+ {170829406, 79245597},
+ {170885498, 78796295},
+ {170909301, 78531898},
+ {170899703, 78238700},
+ {170842803, 77553199},
+ {170701293, 76723495},
+ {170302307, 75753898},
+ {169924301, 75067398},
+ {169359802, 74578796},
+ {168148605, 73757499},
+ {163261596, 71124702},
+ {162986007, 70977798},
+ {162248703, 70599098},
+ {158193405, 68923995},
+ {157514297, 68667495},
+ {156892700, 68495201},
+ {156607299, 68432998},
+ {154301895, 68061904},
+ {93440299, 68061904},
+ {88732002, 68255996},
+ {88627304, 68298500},
+ {88111396, 68541900},
+ {86393898, 69555404},
+ {86138298, 69706695},
+ {85871704, 69913200},
+ {85387199, 70393402},
+ {79854499, 76783203},
+ {79209701, 77649398},
+ {79108505, 78072502},
+ {79090698, 78472198},
+ {79090698, 116426399},
+ },
+ {
+ {90956314, 84639938},
+ {91073814, 85141891},
+ {91185752, 85505371},
+ {109815368, 137196487},
+ {110342590, 138349899},
+ {110388549, 138447540},
+ {110652862, 138971343},
+ {110918045, 139341140},
+ {114380859, 143159042},
+ {114446723, 143220352},
+ {114652198, 143392166},
+ {114712196, 143437301},
+ {114782165, 143476028},
+ {114873054, 143514923},
+ {115217086, 143660934},
+ {115306060, 143695526},
+ {115344009, 143707580},
+ {115444541, 143737747},
+ {115589378, 143779937},
+ {115751358, 143823989},
+ {115802780, 143825820},
+ {116872810, 143753616},
+ {116927055, 143744644},
+ {154690734, 133504180},
+ {155009704, 133371856},
+ {155029907, 133360061},
+ {155089141, 133323181},
+ {155342315, 133163360},
+ {155602294, 132941406},
+ {155669158, 132880294},
+ {155821624, 132737884},
+ {155898986, 132656890},
+ {155934936, 132608932},
+ {155968627, 132562713},
+ {156062896, 132431808},
+ {156111694, 132363174},
+ {156148147, 132297180},
+ {158738342, 127281066},
+ {159026672, 126378631},
+ {159073699, 125806335},
+ {159048522, 125299743},
+ {159040313, 125192901},
+ {158898300, 123934677},
+ {149829376, 70241508},
+ {149763031, 69910629},
+ {149684692, 69628723},
+ {149557800, 69206214},
+ {149366485, 68864326},
+ {149137390, 68578514},
+ {148637466, 68048767},
+ {147027725, 66632934},
+ {146228607, 66257507},
+ {146061309, 66184646},
+ {146017929, 66174186},
+ {145236465, 66269500},
+ {144802490, 66345039},
+ {144673995, 66376220},
+ {93732284, 79649864},
+ {93345336, 79785865},
+ {93208084, 79840286},
+ {92814521, 79997779},
+ {92591087, 80098968},
+ {92567016, 80110511},
+ {92032684, 80860725},
+ {91988853, 80930152},
+ {91471725, 82210029},
+ {91142349, 83076683},
+ {90969284, 83653182},
+ {90929664, 84043212},
+ {90926315, 84325256},
+ {90956314, 84639938},
+ },
+ {
+ {114758499, 88719909},
+ {114771591, 88860549},
+ {115515533, 94195907},
+ {115559539, 94383651},
+ {119882980, 109502059},
+ {120660522, 111909683},
+ {126147735, 124949630},
+ {127127212, 127107215},
+ {129976379, 132117279},
+ {130754470, 133257080},
+ {130820968, 133340835},
+ {130889312, 133423858},
+ {131094787, 133652832},
+ {131257629, 133828247},
+ {131678619, 134164276},
+ {131791107, 134248901},
+ {131969482, 134335189},
+ {132054107, 134373718},
+ {132927368, 134701141},
+ {133077072, 134749313},
+ {133196075, 134785705},
+ {133345230, 134804351},
+ {133498809, 134809051},
+ {133611541, 134797607},
+ {134621170, 134565322},
+ {134741165, 134527511},
+ {134892089, 134465240},
+ {135071212, 134353820},
+ {135252029, 134185821},
+ {135384979, 134003631},
+ {135615585, 133576675},
+ {135793029, 132859008},
+ {135890228, 131382904},
+ {135880828, 131261657},
+ {135837570, 130787963},
+ {135380661, 127428909},
+ {132830596, 109495368},
+ {132815826, 109411666},
+ {132765869, 109199302},
+ {132724380, 109068161},
+ {127490066, 93353515},
+ {125330810, 87852828},
+ {125248336, 87647026},
+ {125002182, 87088424},
+ {124894592, 86872482},
+ {121007278, 80019584},
+ {120962829, 79941261},
+ {120886489, 79833923},
+ {120154983, 78949615},
+ {119366561, 78111709},
+ {119014755, 77776794},
+ {116728790, 75636238},
+ {116660522, 75593933},
+ {116428192, 75458541},
+ {116355255, 75416870},
+ {116264663, 75372528},
+ {115952728, 75233367},
+ {115865554, 75205482},
+ {115756835, 75190956},
+ {115564163, 75197830},
+ {115481170, 75202087},
+ {115417144, 75230400},
+ {115226959, 75337806},
+ {115203842, 75351448},
+ {114722015, 75746932},
+ {114672103, 75795661},
+ {114594619, 75891891},
+ {114565811, 75973831},
+ {114478256, 76240814},
+ {114178039, 77252197},
+ {114137664, 77769668},
+ {114109771, 78154464},
+ {114758499, 88719909},
+ },
+ {
+ {108135070, 109828002},
+ {108200347, 110091529},
+ {108319419, 110298500},
+ {108439025, 110488388},
+ {108663574, 110766731},
+ {108812957, 110935768},
+ {109321914, 111398925},
+ {109368087, 111430320},
+ {109421295, 111466331},
+ {110058998, 111849746},
+ {127160308, 120588981},
+ {127350692, 120683456},
+ {128052749, 120997207},
+ {128326919, 121113449},
+ {131669586, 122213058},
+ {131754745, 122240592},
+ {131854583, 122264770},
+ {132662048, 122449813},
+ {132782669, 122449897},
+ {132909118, 122443687},
+ {133013442, 122436058},
+ {140561035, 121609939},
+ {140786346, 121583320},
+ {140876144, 121570228},
+ {140962356, 121547996},
+ {141052612, 121517837},
+ {141231292, 121442184},
+ {141309371, 121390007},
+ {141370132, 121327003},
+ {141456008, 121219932},
+ {141591598, 121045005},
+ {141905761, 120634796},
+ {141894607, 120305725},
+ {141881881, 120110855},
+ {141840881, 119885009},
+ {141685043, 119238922},
+ {141617416, 118962882},
+ {141570434, 118858856},
+ {131617462, 100598548},
+ {131542846, 100487213},
+ {131229385, 100089019},
+ {131091476, 99928108},
+ {119824127, 90297180},
+ {119636337, 90142387},
+ {119507492, 90037765},
+ {119436744, 89983657},
+ {119423942, 89974159},
+ {119207366, 89822471},
+ {119117149, 89767097},
+ {119039489, 89726867},
+ {116322929, 88522857},
+ {114817031, 87882110},
+ {114683975, 87826751},
+ {114306411, 87728507},
+ {113876434, 87646003},
+ {113792106, 87629974},
+ {113658988, 87615974},
+ {113574333, 87609275},
+ {112813575, 87550102},
+ {112578567, 87560157},
+ {112439880, 87571647},
+ {112306922, 87599395},
+ {112225082, 87622535},
+ {112132568, 87667175},
+ {112103477, 87682830},
+ {110795242, 88511634},
+ {110373565, 88847793},
+ {110286537, 88934989},
+ {109730873, 89531501},
+ {109648735, 89628883},
+ {109552581, 89768859},
+ {109514228, 89838470},
+ {109501640, 89877586},
+ {109480964, 89941864},
+ {109461761, 90032417},
+ {109457778, 90055458},
+ {108105194, 109452575},
+ {108094238, 109620979},
+ {108135070, 109828002},
+ },
+ {
+ {108764694, 108910400},
+ {108965499, 112306495},
+ {109598602, 120388298},
+ {110573898, 128289596},
+ {110597801, 128427795},
+ {113786201, 137983795},
+ {113840301, 138134704},
+ {113937202, 138326904},
+ {114046005, 138520401},
+ {114150802, 138696792},
+ {114164703, 138717895},
+ {114381896, 139021194},
+ {114701004, 139425292},
+ {114997398, 139747497},
+ {115065597, 139805191},
+ {115134498, 139850891},
+ {115167098, 139871704},
+ {115473396, 139992797},
+ {115537498, 139995101},
+ {116762596, 139832000},
+ {116897499, 139808593},
+ {118401802, 139225585},
+ {118437500, 139209594},
+ {118488204, 139182189},
+ {118740097, 139033996},
+ {118815795, 138967285},
+ {134401000, 116395492},
+ {134451507, 116309997},
+ {135488098, 113593597},
+ {137738006, 106775695},
+ {140936492, 97033889},
+ {140960006, 96948997},
+ {141026504, 96660995},
+ {141067291, 96467094},
+ {141124893, 95771896},
+ {141511795, 90171600},
+ {141499801, 90026000},
+ {141479598, 89907798},
+ {141276794, 88844596},
+ {141243804, 88707397},
+ {140778305, 87031593},
+ {140733306, 86871696},
+ {140697204, 86789993},
+ {140619796, 86708190},
+ {140398391, 86487396},
+ {125798797, 72806198},
+ {125415802, 72454498},
+ {123150398, 70566093},
+ {123038803, 70503997},
+ {122681198, 70305397},
+ {121919204, 70104797},
+ {121533699, 70008094},
+ {121273696, 70004898},
+ {121130599, 70020797},
+ {121045097, 70033294},
+ {120847099, 70082298},
+ {120481895, 70278999},
+ {120367004, 70379692},
+ {120272796, 70475097},
+ {119862098, 71004791},
+ {119745101, 71167297},
+ {119447799, 71726997},
+ {119396499, 71825798},
+ {119348701, 71944496},
+ {109508796, 98298797},
+ {109368598, 98700897},
+ {109298400, 98926391},
+ {108506301, 102750991},
+ {108488197, 102879898},
+ {108764694, 108910400},
+ },
+ {
+ {106666252, 87231246},
+ {106673248, 87358055},
+ {107734146, 101975646},
+ {107762649, 102357955},
+ {108702445, 111208351},
+ {108749450, 111345153},
+ {108848350, 111542648},
+ {110270645, 114264358},
+ {110389648, 114445144},
+ {138794845, 143461151},
+ {139048355, 143648956},
+ {139376144, 143885345},
+ {139594451, 144022644},
+ {139754043, 144110046},
+ {139923950, 144185852},
+ {140058242, 144234451},
+ {140185653, 144259552},
+ {140427551, 144292648},
+ {141130950, 144281448},
+ {141157653, 144278152},
+ {141214355, 144266555},
+ {141347457, 144223449},
+ {141625350, 144098953},
+ {141755142, 144040145},
+ {141878143, 143971557},
+ {142011444, 143858154},
+ {142076843, 143796356},
+ {142160644, 143691055},
+ {142224456, 143560852},
+ {142925842, 142090850},
+ {142935653, 142065353},
+ {142995956, 141899154},
+ {143042556, 141719757},
+ {143102951, 141436157},
+ {143129257, 141230453},
+ {143316055, 139447250},
+ {143342544, 133704650},
+ {143307556, 130890960},
+ {142461257, 124025558},
+ {141916046, 120671051},
+ {141890457, 120526153},
+ {140002349, 113455749},
+ {139909149, 113144149},
+ {139853454, 112974456},
+ {137303756, 105228057},
+ {134700546, 98161254},
+ {134617950, 97961547},
+ {133823547, 96118057},
+ {133688751, 95837356},
+ {133481353, 95448059},
+ {133205444, 94948150},
+ {131178955, 91529853},
+ {131144744, 91482055},
+ {113942047, 67481246},
+ {113837051, 67360549},
+ {113048950, 66601745},
+ {112305549, 66002746},
+ {112030853, 65790351},
+ {111970649, 65767547},
+ {111912445, 65755249},
+ {111854248, 65743453},
+ {111657447, 65716354},
+ {111576950, 65707351},
+ {111509750, 65708549},
+ {111443550, 65718551},
+ {111397247, 65737449},
+ {111338546, 65764648},
+ {111129547, 65863349},
+ {111112449, 65871551},
+ {110995254, 65927856},
+ {110968849, 65946151},
+ {110941444, 65966751},
+ {110836448, 66057853},
+ {110490447, 66445449},
+ {110404144, 66576751},
+ {106802055, 73202148},
+ {106741950, 73384948},
+ {106715454, 73469650},
+ {106678054, 73627151},
+ {106657455, 75433448},
+ {106666252, 87231246},
+ },
+ {
+ {101852752, 106261352},
+ {101868949, 106406051},
+ {102347549, 108974250},
+ {112286750, 152027954},
+ {112305648, 152106536},
+ {112325752, 152175857},
+ {112391448, 152290863},
+ {113558250, 154187454},
+ {113592048, 154226745},
+ {113694351, 154313156},
+ {113736549, 154335647},
+ {113818145, 154367462},
+ {114284454, 154490951},
+ {114415847, 154504547},
+ {114520751, 154489151},
+ {114571350, 154478057},
+ {114594551, 154472854},
+ {114630546, 154463958},
+ {114715148, 154429443},
+ {146873657, 136143051},
+ {146941741, 136074249},
+ {147190155, 135763549},
+ {147262649, 135654937},
+ {147309951, 135557159},
+ {147702255, 133903945},
+ {147934143, 131616348},
+ {147967041, 131273864},
+ {148185852, 127892250},
+ {148195648, 127669754},
+ {148179656, 126409851},
+ {148119552, 126182151},
+ {147874053, 125334152},
+ {147818954, 125150352},
+ {146958557, 122656646},
+ {139070251, 101025955},
+ {139002655, 100879051},
+ {119028450, 63067649},
+ {118846649, 62740753},
+ {115676048, 57814651},
+ {115550453, 57629852},
+ {115330352, 57319751},
+ {115094749, 56998352},
+ {114978347, 56847454},
+ {114853050, 56740550},
+ {114695053, 56609550},
+ {114582252, 56528148},
+ {114210449, 56375953},
+ {113636245, 56214950},
+ {113470352, 56171649},
+ {109580749, 55503551},
+ {109491645, 55495452},
+ {109238754, 55511550},
+ {109080352, 55534049},
+ {108027748, 55687351},
+ {107839950, 55732349},
+ {107614456, 55834953},
+ {107488143, 55925952},
+ {107302551, 56062553},
+ {107218353, 56145751},
+ {107199447, 56167251},
+ {107052749, 56354850},
+ {106978652, 56476348},
+ {106869644, 56710754},
+ {104541351, 62448753},
+ {104454551, 62672554},
+ {104441253, 62707351},
+ {104231750, 63366348},
+ {104222648, 63419952},
+ {104155746, 63922649},
+ {104127349, 64147552},
+ {104110847, 64299957},
+ {102235450, 92366752},
+ {101804351, 102877655},
+ {101852752, 106261352},
+ },
+ {
+ {106808700, 120885696},
+ {106818695, 120923103},
+ {106873901, 121057098},
+ {115123603, 133614700},
+ {115128799, 133619598},
+ {115182197, 133661804},
+ {115330101, 133740707},
+ {115455398, 133799407},
+ {115595001, 133836807},
+ {115651000, 133851806},
+ {116413604, 134055206},
+ {116654495, 134097900},
+ {116887603, 134075210},
+ {117071098, 134040405},
+ {117458801, 133904891},
+ {118057998, 133572601},
+ {118546997, 133261001},
+ {118578498, 133239395},
+ {118818603, 133011596},
+ {121109695, 130501495},
+ {122661598, 128760101},
+ {142458190, 102765197},
+ {142789001, 102099601},
+ {143105010, 101386505},
+ {143154800, 101239700},
+ {143193908, 100825500},
+ {143160507, 100282501},
+ {143133499, 100083602},
+ {143092697, 99880500},
+ {143050689, 99766700},
+ {142657501, 98974502},
+ {142580307, 98855201},
+ {122267196, 76269897},
+ {122036399, 76105003},
+ {121832000, 76028305},
+ {121688796, 75983108},
+ {121591598, 75955001},
+ {121119697, 75902099},
+ {120789596, 75953498},
+ {120487495, 76041900},
+ {120042701, 76365798},
+ {119886695, 76507301},
+ {119774200, 76635299},
+ {119739097, 76686904},
+ {119685195, 76798202},
+ {119456199, 77320098},
+ {106877601, 119561401},
+ {106854797, 119645103},
+ {106849098, 119668807},
+ {106847099, 119699005},
+ {106840400, 119801406},
+ {106807800, 120719299},
+ {106806098, 120862808},
+ {106808700, 120885696},
+ },
+ {
+ {99663352, 105328948},
+ {99690048, 105797050},
+ {99714050, 105921447},
+ {99867248, 106439949},
+ {100111557, 107256546},
+ {104924850, 120873649},
+ {105106155, 121284049},
+ {105519149, 122184753},
+ {105586051, 122292655},
+ {105665054, 122400154},
+ {106064147, 122838455},
+ {106755355, 123453453},
+ {106929054, 123577651},
+ {107230346, 123771949},
+ {107760650, 123930648},
+ {108875854, 124205154},
+ {108978752, 124228050},
+ {131962051, 123738754},
+ {135636047, 123513954},
+ {135837249, 123500747},
+ {136357345, 123442749},
+ {136577346, 123394454},
+ {136686645, 123367752},
+ {137399353, 123185050},
+ {137733947, 123063156},
+ {137895355, 122997154},
+ {138275650, 122829154},
+ {138394256, 122767753},
+ {138516845, 122670150},
+ {139987045, 121111251},
+ {149171646, 108517349},
+ {149274353, 108372848},
+ {149314758, 108314247},
+ {149428848, 108140846},
+ {149648651, 107650550},
+ {149779541, 107290252},
+ {149833343, 107115249},
+ {149891357, 106920051},
+ {150246353, 105630249},
+ {150285842, 105423454},
+ {150320953, 105233749},
+ {150336639, 104981552},
+ {150298049, 104374053},
+ {150287948, 104271850},
+ {150026153, 103481147},
+ {149945449, 103301651},
+ {149888946, 103213455},
+ {149800949, 103103851},
+ {149781143, 103079650},
+ {149714141, 103005447},
+ {149589950, 102914146},
+ {149206054, 102698951},
+ {128843856, 91378150},
+ {128641754, 91283050},
+ {119699851, 87248046},
+ {117503555, 86311950},
+ {117145851, 86178054},
+ {116323654, 85925048},
+ {115982551, 85834045},
+ {115853050, 85819252},
+ {115222549, 85771949},
+ {107169357, 85771949},
+ {107122650, 85776451},
+ {106637145, 85831550},
+ {105095046, 86423950},
+ {104507850, 86703750},
+ {104384155, 86763153},
+ {104332351, 86790145},
+ {104198257, 86882644},
+ {103913757, 87109451},
+ {103592346, 87388450},
+ {103272651, 87666748},
+ {103198051, 87779052},
+ {101698654, 90600952},
+ {101523551, 90958450},
+ {101360054, 91347450},
+ {101295349, 91542144},
+ {99774551, 98278152},
+ {99746749, 98417755},
+ {99704055, 98675453},
+ {99663352, 99022949},
+ {99663352, 105328948},
+ },
+ {
+ {95036499, 101778106},
+ {95479103, 102521301},
+ {95587295, 102700103},
+ {98306503, 106984901},
+ {98573303, 107377700},
+ {100622406, 110221702},
+ {101252304, 111089599},
+ {104669502, 115750198},
+ {121838500, 131804107},
+ {122000503, 131943695},
+ {122176803, 132023406},
+ {122474105, 132025390},
+ {122703804, 132023101},
+ {123278808, 131878112},
+ {124072998, 131509109},
+ {124466506, 131102508},
+ {152779296, 101350906},
+ {153016510, 101090606},
+ {153269699, 100809097},
+ {153731994, 100214096},
+ {153927902, 99939796},
+ {154641098, 98858100},
+ {154864303, 98517601},
+ {155056594, 97816604},
+ {155083511, 97645599},
+ {155084899, 97462097},
+ {154682601, 94386100},
+ {154376007, 92992599},
+ {154198593, 92432403},
+ {153830505, 91861701},
+ {153686904, 91678695},
+ {151907104, 90314605},
+ {151368896, 89957603},
+ {146983306, 87632202},
+ {139082397, 84273605},
+ {128947692, 80411399},
+ {121179000, 78631301},
+ {120264701, 78458198},
+ {119279510, 78304603},
+ {116913101, 77994102},
+ {116151504, 77974601},
+ {115435104, 78171401},
+ {113544105, 78709106},
+ {113231002, 78879898},
+ {112726303, 79163604},
+ {112310501, 79411102},
+ {96169998, 97040802},
+ {95196304, 98364402},
+ {95167800, 98409599},
+ {95083503, 98570701},
+ {94986999, 99022201},
+ {94915100, 100413299},
+ {95036499, 101778106},
+ },
+ {
+ {82601348, 96004745},
+ {83443847, 128861953},
+ {84173248, 136147354},
+ {104268249, 141388839},
+ {104373649, 141395355},
+ {105686950, 141389541},
+ {149002243, 140435653},
+ {159095748, 133388244},
+ {159488143, 133112655},
+ {159661849, 132894653},
+ {163034149, 128290847},
+ {164801849, 124684249},
+ {167405746, 72553245},
+ {167330444, 71960746},
+ {167255050, 71791847},
+ {167147155, 71572044},
+ {166999557, 71341545},
+ {166723937, 70961448},
+ {166238250, 70611541},
+ {165782348, 70359649},
+ {165649444, 70286849},
+ {165332946, 70122344},
+ {165164154, 70062248},
+ {164879150, 69967544},
+ {164744949, 69928947},
+ {164691452, 69915245},
+ {164669448, 69910247},
+ {159249938, 68738952},
+ {158528259, 68704742},
+ {147564254, 68604644},
+ {116196655, 68982742},
+ {115364944, 69005050},
+ {115193145, 69013549},
+ {101701248, 70984146},
+ {93918449, 72233047},
+ {93789749, 72285247},
+ {93777046, 72292648},
+ {93586044, 72444046},
+ {93366348, 72662345},
+ {93301147, 72745452},
+ {93260345, 72816345},
+ {83523948, 92593849},
+ {83430145, 92810241},
+ {82815048, 94665542},
+ {82755554, 94858551},
+ {82722953, 95014350},
+ {82594253, 95682350},
+ {82601348, 96004745},
+ },
+ {
+ {110371345, 125796493},
+ {110411544, 126159599},
+ {110445251, 126362899},
+ {111201950, 127863800},
+ {112030052, 129270492},
+ {112367050, 129799301},
+ {113088348, 130525604},
+ {113418144, 130853698},
+ {117363449, 134705505},
+ {118131149, 135444793},
+ {118307449, 135607299},
+ {119102546, 136297195},
+ {119385047, 136531906},
+ {120080848, 137094390},
+ {120794845, 137645401},
+ {121150344, 137896392},
+ {121528945, 138162506},
+ {121644546, 138242095},
+ {122142349, 138506408},
+ {127540847, 141363006},
+ {127933448, 141516204},
+ {128728256, 141766799},
+ {129877151, 141989898},
+ {130626052, 142113891},
+ {130912246, 142135192},
+ {131246841, 142109100},
+ {131496047, 142027404},
+ {131596252, 141957794},
+ {131696350, 141873504},
+ {131741043, 141803405},
+ {138788452, 128037704},
+ {139628646, 125946197},
+ {138319351, 112395401},
+ {130035354, 78066703},
+ {124174049, 69908798},
+ {123970649, 69676895},
+ {123874252, 69571899},
+ {123246643, 68961303},
+ {123193954, 68924400},
+ {121952049, 68110000},
+ {121787345, 68021896},
+ {121661544, 67970306},
+ {121313446, 67877502},
+ {121010650, 67864799},
+ {120995346, 67869705},
+ {120583747, 68122207},
+ {120509750, 68170600},
+ {120485847, 68189102},
+ {112160148, 77252403},
+ {111128646, 78690704},
+ {110969650, 78939407},
+ {110512550, 79663406},
+ {110397247, 79958206},
+ {110371345, 80038299},
+ {110371345, 125796493},
+ },
+ {
+ {112163948, 137752700},
+ {112171150, 137837997},
+ {112203048, 137955993},
+ {112240150, 138008209},
+ {112343246, 138111099},
+ {112556243, 138223205},
+ {112937149, 138307998},
+ {113318748, 138331909},
+ {126076446, 138428298},
+ {126165245, 138428695},
+ {126312446, 138417907},
+ {134075546, 136054504},
+ {134322753, 135949401},
+ {134649948, 135791198},
+ {135234954, 135493408},
+ {135290145, 135464691},
+ {135326248, 135443695},
+ {135920043, 135032592},
+ {135993850, 134975799},
+ {136244247, 134761199},
+ {136649444, 134378692},
+ {137067153, 133964294},
+ {137188156, 133839096},
+ {137298049, 133704498},
+ {137318954, 133677795},
+ {137413543, 133522201},
+ {137687347, 133043792},
+ {137816055, 132660705},
+ {137836044, 131747695},
+ {137807144, 131318603},
+ {136279342, 119078704},
+ {136249053, 118945800},
+ {127306152, 81348602},
+ {127114852, 81065505},
+ {127034248, 80951400},
+ {126971649, 80893707},
+ {125093551, 79178001},
+ {124935745, 79036003},
+ {115573745, 71767601},
+ {115411148, 71701805},
+ {115191947, 71621002},
+ {115017051, 71571304},
+ {114870147, 71572898},
+ {113869552, 71653900},
+ {112863349, 72976104},
+ {112756347, 73223899},
+ {112498947, 73832206},
+ {112429351, 73998504},
+ {112366050, 74168098},
+ {112273246, 74487098},
+ {112239250, 74605400},
+ {112195549, 74899902},
+ {112163948, 75280700},
+ {112163948, 137752700},
+ },
+ {
+ {78562347, 141451843},
+ {79335624, 142828186},
+ {79610343, 143188140},
+ {79845077, 143445724},
+ {81379173, 145126678},
+ {81826751, 145577178},
+ {82519126, 146209472},
+ {83964973, 147280502},
+ {85471343, 148377868},
+ {86115539, 148760803},
+ {88839988, 150281188},
+ {89021247, 150382217},
+ {90775917, 151320526},
+ {91711380, 151767288},
+ {92757591, 152134277},
+ {93241058, 152201766},
+ {113402145, 153091995},
+ {122065994, 146802825},
+ {164111053, 91685104},
+ {164812759, 90470565},
+ {165640182, 89037384},
+ {171027435, 66211853},
+ {171450805, 64406951},
+ {171463150, 64349624},
+ {171469787, 64317184},
+ {171475585, 64282028},
+ {171479812, 64253036},
+ {171483596, 64210433},
+ {171484405, 64153488},
+ {171483001, 64140785},
+ {171481719, 64132751},
+ {171478668, 64115478},
+ {171472702, 64092437},
+ {171462768, 64075408},
+ {171448089, 64061347},
+ {171060333, 63854789},
+ {169640502, 63197738},
+ {169342147, 63086711},
+ {166413101, 62215766},
+ {151881774, 58826736},
+ {146010574, 57613151},
+ {141776962, 56908004},
+ {140982940, 57030628},
+ {139246154, 57540817},
+ {139209609, 57566974},
+ {127545310, 66015594},
+ {127476654, 66104812},
+ {105799087, 98784980},
+ {85531921, 129338897},
+ {79319717, 138704513},
+ {78548156, 140188079},
+ {78530448, 140530456},
+ {78515594, 141299987},
+ {78562347, 141451843},
+ },
+ {
+ {77755004, 128712387},
+ {78073547, 130552612},
+ {78433593, 132017822},
+ {79752693, 136839645},
+ {80479461, 138929260},
+ {80903221, 140119674},
+ {81789848, 141978454},
+ {82447387, 143105575},
+ {83288436, 144264328},
+ {84593582, 145846542},
+ {84971939, 146242813},
+ {86905578, 147321304},
+ {87874191, 147594131},
+ {89249092, 147245132},
+ {89541542, 147169052},
+ {98759140, 144071609},
+ {98894233, 144024261},
+ {113607818, 137992843},
+ {128324356, 131649307},
+ {139610076, 126210189},
+ {146999572, 122112884},
+ {147119415, 122036041},
+ {148717330, 120934616},
+ {149114776, 120652725},
+ {171640289, 92086624},
+ {171677917, 92036224},
+ {171721191, 91973869},
+ {171851608, 91721557},
+ {171927795, 91507644},
+ {172398696, 89846351},
+ {172436752, 89559959},
+ {169361663, 64753852},
+ {169349029, 64687164},
+ {169115127, 63616458},
+ {168965728, 63218254},
+ {168911788, 63121219},
+ {168901611, 63106807},
+ {168896896, 63100486},
+ {168890686, 63092460},
+ {168876586, 63081058},
+ {168855529, 63067909},
+ {168808746, 63046024},
+ {167251068, 62405864},
+ {164291717, 63716899},
+ {152661651, 69910156},
+ {142312393, 75421356},
+ {78778053, 111143295},
+ {77887222, 113905914},
+ {77591979, 124378433},
+ {77563247, 126586669},
+ {77755004, 128712387},
+ },
+ {
+ {105954101, 131182754},
+ {105959197, 131275848},
+ {105972801, 131473556},
+ {105981498, 131571044},
+ {106077903, 132298553},
+ {106134094, 132715255},
+ {106155700, 132832351},
+ {106180099, 132942657},
+ {106326797, 133590347},
+ {106375099, 133719345},
+ {106417602, 133829345},
+ {106471000, 133930343},
+ {106707901, 134308654},
+ {106728401, 134340545},
+ {106778198, 134417556},
+ {106832397, 134491851},
+ {106891296, 134562957},
+ {106981300, 134667358},
+ {107044204, 134736557},
+ {107111000, 134802658},
+ {107180999, 134865661},
+ {107291099, 134961349},
+ {107362998, 135020355},
+ {107485397, 135112854},
+ {107558998, 135166946},
+ {107690399, 135256256},
+ {107765098, 135305252},
+ {107903594, 135390548},
+ {108183898, 135561843},
+ {108459503, 135727951},
+ {108532501, 135771850},
+ {108796096, 135920059},
+ {108944099, 135972549},
+ {109102401, 136010757},
+ {109660598, 136071044},
+ {109971595, 136100250},
+ {110209594, 136116851},
+ {110752799, 136122344},
+ {111059906, 136105758},
+ {111152900, 136100357},
+ {111237197, 136091354},
+ {111316101, 136075057},
+ {111402000, 136050949},
+ {111475296, 136026657},
+ {143546600, 123535949},
+ {143899002, 122454353},
+ {143917404, 122394348},
+ {143929199, 122354652},
+ {143944793, 122295753},
+ {143956207, 122250953},
+ {143969497, 122192253},
+ {143980102, 122143249},
+ {143991302, 122083053},
+ {144000396, 122031753},
+ {144009796, 121970954},
+ {144017303, 121917655},
+ {144025405, 121850250},
+ {144030609, 121801452},
+ {144036804, 121727455},
+ {144040008, 121683456},
+ {144043502, 121600952},
+ {144044708, 121565048},
+ {144045700, 121470352},
+ {144045898, 121446952},
+ {144041503, 121108657},
+ {144037506, 121023452},
+ {143733795, 118731750},
+ {140461395, 95238647},
+ {140461105, 95236755},
+ {140433807, 95115249},
+ {140392608, 95011650},
+ {134840805, 84668952},
+ {134824996, 84642456},
+ {134781494, 84572952},
+ {134716796, 84480850},
+ {127473899, 74425453},
+ {127467002, 74417152},
+ {127431701, 74381652},
+ {127402603, 74357147},
+ {127375503, 74334457},
+ {127294906, 74276649},
+ {127181900, 74207649},
+ {127177597, 74205451},
+ {127123901, 74178451},
+ {127078903, 74155853},
+ {127028999, 74133148},
+ {126870803, 74070953},
+ {126442901, 73917648},
+ {126432403, 73914955},
+ {126326004, 73889846},
+ {126262405, 73880645},
+ {126128097, 73878456},
+ {125998199, 73877655},
+ {108701095, 74516647},
+ {108644599, 74519348},
+ {108495201, 74528953},
+ {108311302, 74556457},
+ {108252799, 74569458},
+ {108079002, 74612152},
+ {107981399, 74638954},
+ {107921295, 74657951},
+ {107862197, 74685951},
+ {107601303, 74828948},
+ {107546997, 74863449},
+ {107192794, 75098846},
+ {107131202, 75151153},
+ {106260002, 76066146},
+ {106195098, 76221145},
+ {106168502, 76328453},
+ {106144699, 76437454},
+ {106124496, 76538452},
+ {106103698, 76649650},
+ {106084197, 76761650},
+ {106066299, 76874450},
+ {106049903, 76987457},
+ {106034797, 77101150},
+ {106020904, 77214950},
+ {106008201, 77328948},
+ {105996902, 77443145},
+ {105986099, 77565849},
+ {105977005, 77679649},
+ {105969299, 77793151},
+ {105963096, 77906349},
+ {105958297, 78019149},
+ {105955299, 78131454},
+ {105954101, 78242950},
+ {105954101, 131182754},
+ },
+ {
+ {91355499, 77889205},
+ {114834197, 120804504},
+ {114840301, 120815200},
+ {124701507, 132324798},
+ {124798805, 132436706},
+ {124901504, 132548309},
+ {125126602, 132788909},
+ {125235000, 132901901},
+ {125337707, 133005401},
+ {125546302, 133184707},
+ {125751602, 133358703},
+ {126133300, 133673004},
+ {126263900, 133775604},
+ {126367401, 133855499},
+ {126471908, 133935104},
+ {126596008, 134027496},
+ {127119308, 134397094},
+ {127135101, 134408203},
+ {127433609, 134614303},
+ {127554107, 134695709},
+ {128155395, 135070907},
+ {128274505, 135141799},
+ {129132003, 135573211},
+ {129438003, 135713195},
+ {129556106, 135767196},
+ {131512695, 136648498},
+ {132294509, 136966598},
+ {132798400, 137158798},
+ {133203796, 137294494},
+ {133377410, 137350799},
+ {133522399, 137396606},
+ {133804397, 137480697},
+ {134017807, 137542205},
+ {134288696, 137618408},
+ {134564208, 137680099},
+ {134844696, 137740097},
+ {135202606, 137807098},
+ {135489105, 137849807},
+ {135626800, 137864898},
+ {135766906, 137878692},
+ {135972808, 137895797},
+ {136110107, 137905502},
+ {136235000, 137913101},
+ {136485809, 137907196},
+ {139194305, 136979202},
+ {140318298, 136536209},
+ {140380004, 136505004},
+ {140668197, 136340499},
+ {140724304, 136298904},
+ {140808197, 136228210},
+ {140861801, 136180603},
+ {140917404, 136129104},
+ {140979202, 136045104},
+ {141022903, 135984207},
+ {147591094, 126486999},
+ {147661315, 126356101},
+ {147706100, 126261901},
+ {147749099, 126166000},
+ {147817108, 126007507},
+ {147859100, 125908599},
+ {153693206, 111901100},
+ {153731109, 111807800},
+ {153760894, 111698806},
+ {158641998, 92419303},
+ {158644500, 92263702},
+ {158539703, 92013504},
+ {158499603, 91918899},
+ {158335510, 91626800},
+ {158264007, 91516304},
+ {158216308, 91449203},
+ {158178314, 91397506},
+ {158094299, 91283203},
+ {157396408, 90368202},
+ {157285491, 90224700},
+ {157169906, 90079200},
+ {157050003, 89931304},
+ {156290603, 89006805},
+ {156221099, 88922897},
+ {156087707, 88771003},
+ {155947906, 88620498},
+ {155348602, 88004203},
+ {155113204, 87772796},
+ {154947296, 87609703},
+ {154776306, 87448204},
+ {154588806, 87284301},
+ {153886306, 86716400},
+ {153682403, 86560501},
+ {152966705, 86032402},
+ {152687805, 85828704},
+ {152484313, 85683204},
+ {152278808, 85539001},
+ {150878204, 84561401},
+ {150683013, 84426498},
+ {150599395, 84372703},
+ {150395599, 84243202},
+ {149988906, 83989395},
+ {149782897, 83864501},
+ {149568908, 83739799},
+ {148872100, 83365303},
+ {148625396, 83242202},
+ {128079010, 73079605},
+ {127980506, 73031005},
+ {126701103, 72407104},
+ {126501701, 72312202},
+ {126431503, 72280601},
+ {126311706, 72230606},
+ {126260101, 72210899},
+ {126191902, 72187599},
+ {126140106, 72170303},
+ {126088203, 72155303},
+ {126036102, 72142700},
+ {125965904, 72126899},
+ {125913009, 72116600},
+ {125859603, 72108505},
+ {125788101, 72100296},
+ {125733505, 72094398},
+ {125678100, 72090400},
+ {125621398, 72088302},
+ {125548805, 72087303},
+ {125490707, 72086898},
+ {125430908, 72088203},
+ {125369804, 72091094},
+ {125306900, 72095306},
+ {125233505, 72100997},
+ {125168609, 72106506},
+ {125102203, 72113601},
+ {125034103, 72122207},
+ {124964309, 72132095},
+ {124890701, 72143707},
+ {124819305, 72155105},
+ {91355499, 77889099},
+ {91355499, 77889205},
+ },
+ {
+ {84531845, 127391708},
+ {84916946, 130417510},
+ {86133247, 131166900},
+ {86338447, 131292892},
+ {86748847, 131544799},
+ {102193946, 136599502},
+ {103090942, 136796798},
+ {103247146, 136822509},
+ {104083549, 136911499},
+ {106119346, 137109802},
+ {106265853, 137122207},
+ {106480247, 137139205},
+ {110257850, 137133605},
+ {116917747, 136131408},
+ {117054946, 136106704},
+ {119043945, 135244293},
+ {119249046, 135154708},
+ {136220947, 126833007},
+ {165896347, 91517105},
+ {166032546, 91314697},
+ {166055435, 91204902},
+ {166056152, 91176803},
+ {166047256, 91100006},
+ {166039733, 91063705},
+ {165814849, 90080802},
+ {165736450, 89837707},
+ {165677246, 89732101},
+ {165676956, 89731803},
+ {165560241, 89629302},
+ {154419952, 82608505},
+ {153822143, 82239700},
+ {137942749, 74046104},
+ {137095245, 73845504},
+ {135751342, 73537704},
+ {134225952, 73208602},
+ {132484344, 72860801},
+ {124730346, 73902000},
+ {120736549, 74464401},
+ {100401245, 78685401},
+ {90574645, 90625701},
+ {90475944, 90748809},
+ {90430747, 90808700},
+ {90321548, 90958305},
+ {90254852, 91077903},
+ {90165641, 91244003},
+ {90134941, 91302398},
+ {84474647, 103745697},
+ {84328048, 104137901},
+ {84288543, 104327606},
+ {84038047, 106164604},
+ {84013351, 106368698},
+ {83943847, 110643203},
+ {84531845, 127391708},
+ },
+};
+
+const TestDataEx PRINTER_PART_POLYGONS_EX =
+{
+ {
+ {
+ {533726562, 142141690},
+ {532359712, 143386134},
+ {530141290, 142155145},
+ {528649729, 160091460},
+ {533659500, 157607547},
+ {538669739, 160091454},
+ {537178168, 142155145},
+ {534959534, 143386102},
+ {533726562, 142141690},
+ },
+ {
+ },
+ },
+ {
+ {
+ {118305840, 11603332},
+ {118311095, 26616786},
+ {113311095, 26611146},
+ {109311095, 29604752},
+ {109300760, 44608489},
+ {109311095, 49631801},
+ {113300790, 52636806},
+ {118311095, 52636806},
+ {118308782, 103636810},
+ {223830940, 103636981},
+ {236845321, 90642174},
+ {236832882, 11630488},
+ {232825251, 11616786},
+ {210149075, 11616786},
+ {211308596, 13625149},
+ {209315325, 17080886},
+ {205326885, 17080886},
+ {203334352, 13629720},
+ {204493136, 11616786},
+ {118305840, 11603332},
+ },
+ {
+ },
+ },
+ {
+ {
+ {365619370, 111280336},
+ {365609100, 198818091},
+ {387109100, 198804367},
+ {387109100, 203279701},
+ {471129120, 203279688},
+ {471128689, 111283937},
+ {365619370, 111280336},
+ },
+ {
+ },
+ },
+ {
+ {
+ {479997525, 19177632},
+ {477473010, 21975778},
+ {475272613, 21969219},
+ {475267479, 32995796},
+ {477026388, 32995796},
+ {483041428, 22582411},
+ {482560272, 20318630},
+ {479997525, 19177632},
+ },
+ {
+ },
+ },
+ {
+ {
+ {476809080, 4972372},
+ {475267479, 4975778},
+ {475272613, 16002357},
+ {481018177, 18281994},
+ {482638044, 15466085},
+ {476809080, 4972372},
+ },
+ {
+ },
+ },
+ {
+ {
+ {424866064, 10276075},
+ {415113411, 10277960},
+ {411723180, 13685293},
+ {410473354, 18784347},
+ {382490868, 18784008},
+ {380996185, 17286945},
+ {380996185, 11278161},
+ {375976165, 11284347},
+ {375976165, 56389754},
+ {375169018, 57784347},
+ {371996185, 57784347},
+ {371996185, 53779177},
+ {364976165, 53784347},
+ {364969637, 56791976},
+ {369214608, 61054367},
+ {371474507, 61054367},
+ {371473155, 98298160},
+ {378476349, 105317193},
+ {407491306, 105307497},
+ {413509785, 99284903},
+ {413496185, 48304367},
+ {419496173, 48315719},
+ {422501887, 45292801},
+ {422500504, 39363184},
+ {420425079, 37284347},
+ {419476165, 43284347},
+ {413496185, 43284347},
+ {413497261, 30797428},
+ {418986175, 25308513},
+ {424005230, 25315076},
+ {428496185, 20815924},
+ {428512720, 13948847},
+ {424866064, 10276075},
+ },
+ {
+ },
+ },
+ {
+ {
+ {723893066, 37354349},
+ {717673034, 37370791},
+ {717673034, 44872138},
+ {715673034, 44867768},
+ {715673034, 46055353},
+ {699219526, 40066777},
+ {697880758, 37748547},
+ {691985477, 37748293},
+ {689014018, 42869257},
+ {691985477, 48016003},
+ {697575093, 48003007},
+ {715671494, 54589493},
+ {715656800, 87142158},
+ {759954611, 87142158},
+ {764193054, 82897328},
+ {764193054, 79872138},
+ {757173034, 79866968},
+ {757173034, 83872138},
+ {754419422, 83869509},
+ {753193054, 81739327},
+ {753193054, 37360571},
+ {723893066, 37354349},
+ },
+ {
+ },
+ },
+ {
+ {
+ {85607478, 4227596},
+ {61739211, 4230337},
+ {61739211, 13231393},
+ {58725066, 13231405},
+ {58721589, 27731406},
+ {58738375, 30262521},
+ {61739211, 30251413},
+ {61736212, 38251411},
+ {70759231, 38254724},
+ {70905600, 33317391},
+ {73749222, 31251468},
+ {76592843, 33317393},
+ {76739211, 38254516},
+ {86765007, 38251411},
+ {86759599, 4231393},
+ {85607478, 4227596},
+ },
+ {
+ },
+ },
+ {
+ {
+ {534839721, 53437770},
+ {534839721, 60849059},
+ {539898273, 63773857},
+ {545461140, 63757881},
+ {544859741, 53447836},
+ {541839721, 53437862},
+ {541710836, 56353878},
+ {540193984, 57229659},
+ {538859741, 53437862},
+ {534839721, 53437770},
+ },
+ {
+ },
+ },
+ {
+ {
+ {756086230, 136598477},
+ {732054387, 136605752},
+ {732052489, 172629505},
+ {756091994, 172627853},
+ {756086230, 136598477},
+ },
+ {
+ },
+ },
+ {
+ {
+ {100337034, 79731391},
+ {70296833, 79731391},
+ {70311095, 92263567},
+ {74329808, 96264260},
+ {96344976, 96257215},
+ {100344419, 92232243},
+ {100337034, 79731391},
+ },
+ {
+ },
+ },
+ {
+ {
+ {102331115, 44216643},
+ {67311095, 44217252},
+ {67311095, 69250964},
+ {74329808, 76264260},
+ {96334594, 76251411},
+ {103335261, 69241401},
+ {103345839, 44231404},
+ {102331115, 44216643},
+ },
+ {
+ },
+ },
+ {
+ {
+ {93849749, 109613798},
+ {91771666, 111698636},
+ {91772404, 174626800},
+ {96782902, 179645338},
+ {241790509, 179645349},
+ {246800716, 174626800},
+ {246802574, 111699755},
+ {243934250, 109616385},
+ {93849749, 109613798},
+ },
+ {
+ },
+ },
+ {
+ {
+ {15856630, 87966835},
+ {8414359, 91273170},
+ {5891847, 99010553},
+ {8403012, 104668172},
+ {13739106, 107763252},
+ {13739106, 116209175},
+ {17959116, 116219127},
+ {17959127, 107763252},
+ {23952579, 103855773},
+ {25806388, 96944174},
+ {22553953, 90543787},
+ {15856630, 87966835},
+ },
+ {
+ },
+ },
+ {
+ {
+ {503922805, 110421794},
+ {491110107, 123244292},
+ {479598157, 123244304},
+ {479601067, 149264312},
+ {494260327, 149265241},
+ {502929782, 157948320},
+ {506490250, 155806171},
+ {502950518, 155094962},
+ {507193172, 150852294},
+ {504364680, 148023895},
+ {535816833, 116571757},
+ {538656617, 119411542},
+ {542887886, 115157558},
+ {543594970, 118693080},
+ {545330008, 116966050},
+ {540309189, 110425901},
+ {503922805, 110421794},
+ },
+ {
+ },
+ },
+ {
+ {
+ {519310433, 62560296},
+ {515749982, 64702434},
+ {519289696, 65413661},
+ {515047062, 69656303},
+ {517875553, 72484703},
+ {486423431, 103936848},
+ {483595031, 101108448},
+ {479352325, 105351055},
+ {478645233, 101815525},
+ {476917724, 103520870},
+ {481923478, 110077233},
+ {518337308, 110084297},
+ {531130127, 97264312},
+ {542630127, 97281049},
+ {542639167, 71244292},
+ {527979906, 71243363},
+ {519310433, 62560296},
+ },
+ {
+ },
+ },
+ {
+ {
+ {528658425, 14775300},
+ {525975568, 24475413},
+ {522556814, 29181341},
+ {517517474, 32090757},
+ {511736147, 32698600},
+ {506200465, 30901018},
+ {501879743, 27011092},
+ {497782491, 14775300},
+ {492372374, 15588397},
+ {489384268, 20795320},
+ {491253082, 28537271},
+ {495185363, 34469052},
+ {495178475, 43927542},
+ {502032399, 55796416},
+ {524402581, 55807400},
+ {531706434, 44295318},
+ {531205383, 34469052},
+ {536679415, 23789946},
+ {535868173, 17264403},
+ {532873348, 15073849},
+ {528658425, 14775300},
+ },
+ {
+ },
+ },
+ {
+ {
+ {481122222, 166062916},
+ {478115710, 166824472},
+ {477103577, 169063247},
+ {477106058, 192070670},
+ {478623652, 194687013},
+ {525109130, 195083267},
+ {525117792, 198086965},
+ {535129140, 198091624},
+ {535129150, 195083267},
+ {539038502, 194940807},
+ {540865280, 193308821},
+ {541132038, 169100183},
+ {539614599, 166459484},
+ {481122222, 166062916},
+ },
+ {
+ },
+ },
+ {
+ {
+ {23771404, 13005453},
+ {24774973, 19182457},
+ {31971050, 18727127},
+ {32556286, 58337520},
+ {25390683, 58337566},
+ {25063762, 54707065},
+ {20168811, 54707252},
+ {20171550, 62917175},
+ {70810377, 202895528},
+ {74314421, 205588631},
+ {88674817, 205515176},
+ {91837376, 203083756},
+ {92280287, 199307207},
+ {40674807, 15904975},
+ {36849630, 13006690},
+ {23771404, 13005453},
+ },
+ {
+ },
+ },
+ {
+ {
+ {336421201, 2986256},
+ {331176570, 6498191},
+ {327552287, 5825511},
+ {324913825, 2988891},
+ {316226154, 2989990},
+ {313040282, 6275291},
+ {313040282, 23489990},
+ {307126391, 23490002},
+ {307140289, 25510010},
+ {313040282, 25510010},
+ {313040282, 28989990},
+ {307126391, 28990002},
+ {307140289, 31015515},
+ {313040282, 31010010},
+ {313040282, 35989990},
+ {304534809, 37529785},
+ {304524991, 73488855},
+ {308554680, 77518546},
+ {324040282, 77510010},
+ {324040295, 93025333},
+ {334574441, 93010010},
+ {334574441, 90989990},
+ {332560302, 90989990},
+ {332560302, 85010010},
+ {334560302, 85010010},
+ {334561237, 82010010},
+ {338540282, 82010010},
+ {339540282, 83760010},
+ {338540293, 93020012},
+ {348060655, 93014679},
+ {356564448, 84500000},
+ {356560555, 28989990},
+ {347334198, 29039989},
+ {347334198, 25510010},
+ {356510304, 25521084},
+ {356510315, 23478922},
+ {347560302, 23489990},
+ {347560302, 5775291},
+ {344874443, 2989990},
+ {336421201, 2986256},
+ },
+ {
+ },
+ },
+ {
+ {
+ {465152221, 31684687},
+ {457606880, 31688302},
+ {452659362, 35508617},
+ {449044605, 34734089},
+ {446478972, 31692751},
+ {437784814, 31692957},
+ {435521210, 33956565},
+ {435532195, 65697616},
+ {426028494, 65691361},
+ {426025938, 85049712},
+ {435532195, 95717636},
+ {435524445, 103754026},
+ {436995898, 105225463},
+ {447552204, 105226323},
+ {447552215, 103197497},
+ {444552215, 103197616},
+ {444552215, 99217636},
+ {452032195, 99217636},
+ {452032195, 105221758},
+ {465588513, 105225463},
+ {467059965, 103754026},
+ {467052215, 95717636},
+ {478053039, 84511285},
+ {478056214, 65697616},
+ {468552215, 65697616},
+ {468563959, 33957323},
+ {465152221, 31684687},
+ },
+ {
+ },
+ },
+ {
+ {
+ {764927063, 92658416},
+ {762115426, 94171595},
+ {762122741, 131696443},
+ {786415417, 132779578},
+ {793690904, 129904572},
+ {797383202, 124822853},
+ {798269157, 120142660},
+ {796710161, 114090278},
+ {793387498, 110215980},
+ {796094093, 103892242},
+ {794107594, 96994001},
+ {787445494, 92840355},
+ {764927063, 92658416},
+ },
+ {
+ },
+ },
+ {
+ {
+ {27496331, 123147467},
+ {3202195, 124246400},
+ {3203433, 205768600},
+ {20223453, 205775606},
+ {20223644, 163243606},
+ {31297341, 162189074},
+ {36789517, 155659691},
+ {36967183, 150566416},
+ {34468182, 145711036},
+ {38465496, 140400171},
+ {38952460, 132613091},
+ {34771593, 126022444},
+ {27496331, 123147467},
+ },
+ {
+ },
+ },
+ {
+ {
+ {797556553, 39197820},
+ {791313598, 39199767},
+ {789506233, 39864015},
+ {789522521, 48199767},
+ {775974570, 48195721},
+ {774022521, 50129235},
+ {774008720, 76258022},
+ {775974570, 78223833},
+ {789522521, 78219787},
+ {789522521, 86576919},
+ {797556547, 87221747},
+ {797556553, 39197820},
+ },
+ {
+ },
+ },
+ {
+ {
+ {676593113, 129820144},
+ {676565322, 164844636},
+ {701599609, 164858650},
+ {701599609, 129823260},
+ {676593113, 129820144},
+ },
+ {
+ },
+ },
+ {
+ {
+ {727646871, 93121321},
+ {709122741, 93122138},
+ {709122741, 125656310},
+ {718769809, 135145243},
+ {721622937, 135156111},
+ {724152429, 132626619},
+ {723734126, 112688301},
+ {725837154, 107378546},
+ {728976138, 104430846},
+ {735847924, 102664848},
+ {741289364, 104430846},
+ {745202882, 108599767},
+ {746590596, 114642158},
+ {751137173, 114644887},
+ {756151199, 109641674},
+ {756149037, 94634278},
+ {754642761, 93122138},
+ {727646871, 93121321},
+ },
+ {
+ },
+ },
+ {
+ {
+ {135915724, 185598906},
+ {131396265, 193419009},
+ {131399444, 197643260},
+ {140399444, 197636810},
+ {140399444, 199138818},
+ {157419464, 197643916},
+ {157422805, 193210743},
+ {153046747, 185604789},
+ {149044579, 185614655},
+ {147324399, 189850396},
+ {144168954, 191108901},
+ {141187892, 189479768},
+ {139917659, 185615382},
+ {135915724, 185598906},
+ },
+ {
+ },
+ },
+ {
+ {
+ {312619110, 154485844},
+ {309601817, 157488332},
+ {309599764, 203494810},
+ {313109244, 207010010},
+ {352900849, 207019221},
+ {359629120, 200302405},
+ {359638705, 159501827},
+ {354621096, 154487830},
+ {312619110, 154485844},
+ },
+ {
+ },
+ },
+ {
+ {
+ {313120315, 98984639},
+ {309609100, 102486971},
+ {309596977, 148492024},
+ {312591195, 151510010},
+ {354608772, 151524494},
+ {359629120, 146515788},
+ {359638123, 105715491},
+ {352907860, 98987790},
+ {313120315, 98984639},
+ },
+ {
+ },
+ },
+ {
+ {
+ {657746643, 86246732},
+ {651722477, 92270881},
+ {651720052, 131280884},
+ {653947196, 131280884},
+ {659746643, 125487816},
+ {659746643, 119273826},
+ {663742413, 112352691},
+ {671726623, 112352691},
+ {675733721, 119283349},
+ {684745297, 119298573},
+ {689758503, 114263168},
+ {689752066, 91272158},
+ {684746643, 86260871},
+ {657746643, 86246732},
+ },
+ {
+ },
+ },
+ {
+ {
+ {653940791, 39260871},
+ {651720052, 39260871},
+ {651726623, 78280611},
+ {657746631, 84295035},
+ {684746643, 84280891},
+ {689752066, 79269604},
+ {689746643, 56247942},
+ {684745283, 51243184},
+ {675733721, 51258413},
+ {671726623, 58189071},
+ {663742413, 58189071},
+ {659746643, 51267936},
+ {659746643, 45053950},
+ {653940791, 39260871},
+ },
+ {
+ },
+ },
+ {
+ {
+ {442365208, 3053303},
+ {436408500, 5694021},
+ {434342552, 11072741},
+ {436986326, 17009033},
+ {442365367, 19073360},
+ {448299202, 16431441},
+ {450365150, 11052721},
+ {448299202, 5694021},
+ {442365208, 3053303},
+ },
+ {
+ },
+ },
+};
diff --git a/xs/src/libnest2d/tests/printer_parts.h b/xs/src/libnest2d/tests/printer_parts.h
new file mode 100644
index 000000000..b9a4eb8fa
--- /dev/null
+++ b/xs/src/libnest2d/tests/printer_parts.h
@@ -0,0 +1,40 @@
+#ifndef PRINTER_PARTS_H
+#define PRINTER_PARTS_H
+
+#include <vector>
+#include <clipper.hpp>
+
+#ifndef CLIPPER_BACKEND_HPP
+namespace ClipperLib {
+using PointImpl = IntPoint;
+using PathImpl = Path;
+using HoleStore = std::vector<PathImpl>;
+
+struct PolygonImpl {
+ PathImpl Contour;
+ HoleStore Holes;
+
+ inline PolygonImpl() {}
+
+ inline explicit PolygonImpl(const PathImpl& cont): Contour(cont) {}
+ inline explicit PolygonImpl(const HoleStore& holes):
+ Holes(holes) {}
+ inline PolygonImpl(const Path& cont, const HoleStore& holes):
+ Contour(cont), Holes(holes) {}
+
+ inline explicit PolygonImpl(PathImpl&& cont): Contour(std::move(cont)) {}
+ inline explicit PolygonImpl(HoleStore&& holes): Holes(std::move(holes)) {}
+ inline PolygonImpl(Path&& cont, HoleStore&& holes):
+ Contour(std::move(cont)), Holes(std::move(holes)) {}
+};
+}
+#endif
+
+using TestData = std::vector<ClipperLib::Path>;
+using TestDataEx = std::vector<ClipperLib::PolygonImpl>;
+
+extern const TestData PRINTER_PART_POLYGONS;
+extern const TestData STEGOSAUR_POLYGONS;
+extern const TestDataEx PRINTER_PART_POLYGONS_EX;
+
+#endif // PRINTER_PARTS_H
diff --git a/xs/src/libnest2d/tests/test.cpp b/xs/src/libnest2d/tests/test.cpp
new file mode 100644
index 000000000..323fb8d31
--- /dev/null
+++ b/xs/src/libnest2d/tests/test.cpp
@@ -0,0 +1,847 @@
+#include <gtest/gtest.h>
+#include <fstream>
+
+#include <libnest2d.h>
+#include "printer_parts.h"
+#include <libnest2d/geometry_traits_nfp.hpp>
+//#include "../tools/libnfpglue.hpp"
+//#include "../tools/nfp_svgnest_glue.hpp"
+
+std::vector<libnest2d::Item>& prusaParts() {
+ static std::vector<libnest2d::Item> ret;
+
+ if(ret.empty()) {
+ ret.reserve(PRINTER_PART_POLYGONS.size());
+ for(auto& inp : PRINTER_PART_POLYGONS) ret.emplace_back(inp);
+ }
+
+ return ret;
+}
+
+TEST(BasicFunctionality, Angles)
+{
+
+ using namespace libnest2d;
+
+ Degrees deg(180);
+ Radians rad(deg);
+ Degrees deg2(rad);
+
+ ASSERT_DOUBLE_EQ(rad, Pi);
+ ASSERT_DOUBLE_EQ(deg, 180);
+ ASSERT_DOUBLE_EQ(deg2, 180);
+ ASSERT_DOUBLE_EQ(rad, (Radians) deg);
+ ASSERT_DOUBLE_EQ( (Degrees) rad, deg);
+
+ ASSERT_TRUE(rad == deg);
+
+ Segment seg = {{0, 0}, {12, -10}};
+
+ ASSERT_TRUE(Degrees(seg.angleToXaxis()) > 270 &&
+ Degrees(seg.angleToXaxis()) < 360);
+
+ seg = {{0, 0}, {12, 10}};
+
+ ASSERT_TRUE(Degrees(seg.angleToXaxis()) > 0 &&
+ Degrees(seg.angleToXaxis()) < 90);
+
+ seg = {{0, 0}, {-12, 10}};
+
+ ASSERT_TRUE(Degrees(seg.angleToXaxis()) > 90 &&
+ Degrees(seg.angleToXaxis()) < 180);
+
+ seg = {{0, 0}, {-12, -10}};
+
+ ASSERT_TRUE(Degrees(seg.angleToXaxis()) > 180 &&
+ Degrees(seg.angleToXaxis()) < 270);
+
+ seg = {{0, 0}, {1, 0}};
+
+ ASSERT_DOUBLE_EQ(Degrees(seg.angleToXaxis()), 0);
+
+ seg = {{0, 0}, {0, 1}};
+
+ ASSERT_DOUBLE_EQ(Degrees(seg.angleToXaxis()), 90);
+
+
+ seg = {{0, 0}, {-1, 0}};
+
+ ASSERT_DOUBLE_EQ(Degrees(seg.angleToXaxis()), 180);
+
+
+ seg = {{0, 0}, {0, -1}};
+
+ ASSERT_DOUBLE_EQ(Degrees(seg.angleToXaxis()), 270);
+
+}
+
+// Simple test, does not use gmock
+TEST(BasicFunctionality, creationAndDestruction)
+{
+ using namespace libnest2d;
+
+ Item sh = { {0, 0}, {1, 0}, {1, 1}, {0, 1} };
+
+ ASSERT_EQ(sh.vertexCount(), 4u);
+
+ Item sh2 ({ {0, 0}, {1, 0}, {1, 1}, {0, 1} });
+
+ ASSERT_EQ(sh2.vertexCount(), 4u);
+
+ // copy
+ Item sh3 = sh2;
+
+ ASSERT_EQ(sh3.vertexCount(), 4u);
+
+ sh2 = {};
+
+ ASSERT_EQ(sh2.vertexCount(), 0u);
+ ASSERT_EQ(sh3.vertexCount(), 4u);
+
+}
+
+TEST(GeometryAlgorithms, boundingCircle) {
+ using namespace libnest2d;
+ using placers::boundingCircle;
+
+ PolygonImpl p = {{{0, 10}, {10, 0}, {0, -10}, {0, 10}}, {}};
+ Circle c = boundingCircle(p);
+
+ ASSERT_EQ(c.center().X, 0);
+ ASSERT_EQ(c.center().Y, 0);
+ ASSERT_DOUBLE_EQ(c.radius(), 10);
+
+ shapelike::translate(p, PointImpl{10, 10});
+ c = boundingCircle(p);
+
+ ASSERT_EQ(c.center().X, 10);
+ ASSERT_EQ(c.center().Y, 10);
+ ASSERT_DOUBLE_EQ(c.radius(), 10);
+
+ auto parts = prusaParts();
+
+ int i = 0;
+ for(auto& part : parts) {
+ c = boundingCircle(part.transformedShape());
+ if(std::isnan(c.radius())) std::cout << "fail: radius is nan" << std::endl;
+
+ else for(auto v : shapelike::getContour(part.transformedShape()) ) {
+ auto d = pointlike::distance(v, c.center());
+ if(d > c.radius() ) {
+ auto e = std::abs( 1.0 - d/c.radius());
+ ASSERT_LE(e, 1e-3);
+ }
+ }
+ i++;
+ }
+
+}
+
+TEST(GeometryAlgorithms, Distance) {
+ using namespace libnest2d;
+
+ Point p1 = {0, 0};
+
+ Point p2 = {10, 0};
+ Point p3 = {10, 10};
+
+ ASSERT_DOUBLE_EQ(pointlike::distance(p1, p2), 10);
+ ASSERT_DOUBLE_EQ(pointlike::distance(p1, p3), sqrt(200));
+
+ Segment seg(p1, p3);
+
+ ASSERT_DOUBLE_EQ(pointlike::distance(p2, seg), 7.0710678118654755);
+
+ auto result = pointlike::horizontalDistance(p2, seg);
+
+ auto check = [](Coord val, Coord expected) {
+ if(std::is_floating_point<Coord>::value)
+ ASSERT_DOUBLE_EQ(static_cast<double>(val),
+ static_cast<double>(expected));
+ else
+ ASSERT_EQ(val, expected);
+ };
+
+ ASSERT_TRUE(result.second);
+ check(result.first, 10);
+
+ result = pointlike::verticalDistance(p2, seg);
+ ASSERT_TRUE(result.second);
+ check(result.first, -10);
+
+ result = pointlike::verticalDistance(Point{10, 20}, seg);
+ ASSERT_TRUE(result.second);
+ check(result.first, 10);
+
+
+ Point p4 = {80, 0};
+ Segment seg2 = { {0, 0}, {0, 40} };
+
+ result = pointlike::horizontalDistance(p4, seg2);
+
+ ASSERT_TRUE(result.second);
+ check(result.first, 80);
+
+ result = pointlike::verticalDistance(p4, seg2);
+ // Point should not be related to the segment
+ ASSERT_FALSE(result.second);
+
+}
+
+TEST(GeometryAlgorithms, Area) {
+ using namespace libnest2d;
+
+ Rectangle rect(10, 10);
+
+ ASSERT_EQ(rect.area(), 100);
+
+ Rectangle rect2 = {100, 100};
+
+ ASSERT_EQ(rect2.area(), 10000);
+
+ Item item = {
+ {61, 97},
+ {70, 151},
+ {176, 151},
+ {189, 138},
+ {189, 59},
+ {70, 59},
+ {61, 77},
+ {61, 97}
+ };
+
+ ASSERT_TRUE(shapelike::area(item.transformedShape()) > 0 );
+}
+
+TEST(GeometryAlgorithms, IsPointInsidePolygon) {
+ using namespace libnest2d;
+
+ Rectangle rect(10, 10);
+
+ Point p = {1, 1};
+
+ ASSERT_TRUE(rect.isInside(p));
+
+ p = {11, 11};
+
+ ASSERT_FALSE(rect.isInside(p));
+
+
+ p = {11, 12};
+
+ ASSERT_FALSE(rect.isInside(p));
+
+
+ p = {3, 3};
+
+ ASSERT_TRUE(rect.isInside(p));
+
+}
+
+//TEST(GeometryAlgorithms, Intersections) {
+// using namespace binpack2d;
+
+// Rectangle rect(70, 30);
+
+// rect.translate({80, 60});
+
+// Rectangle rect2(80, 60);
+// rect2.translate({80, 0});
+
+//// ASSERT_FALSE(Item::intersects(rect, rect2));
+
+// Segment s1({0, 0}, {10, 10});
+// Segment s2({1, 1}, {11, 11});
+// ASSERT_FALSE(ShapeLike::intersects(s1, s1));
+// ASSERT_FALSE(ShapeLike::intersects(s1, s2));
+//}
+
+// Simple test, does not use gmock
+TEST(GeometryAlgorithms, LeftAndDownPolygon)
+{
+ using namespace libnest2d;
+ using namespace libnest2d;
+
+ Box bin(100, 100);
+ BottomLeftPlacer placer(bin);
+
+ Item item = {{70, 75}, {88, 60}, {65, 50}, {60, 30}, {80, 20}, {42, 20},
+ {35, 35}, {35, 55}, {40, 75}, {70, 75}};
+
+ Item leftControl = { {40, 75},
+ {35, 55},
+ {35, 35},
+ {42, 20},
+ {0, 20},
+ {0, 75},
+ {40, 75}};
+
+ Item downControl = {{88, 60},
+ {88, 0},
+ {35, 0},
+ {35, 35},
+ {42, 20},
+ {80, 20},
+ {60, 30},
+ {65, 50},
+ {88, 60}};
+
+ Item leftp(placer.leftPoly(item));
+
+ ASSERT_TRUE(shapelike::isValid(leftp.rawShape()).first);
+ ASSERT_EQ(leftp.vertexCount(), leftControl.vertexCount());
+
+ for(unsigned long i = 0; i < leftControl.vertexCount(); i++) {
+ ASSERT_EQ(getX(leftp.vertex(i)), getX(leftControl.vertex(i)));
+ ASSERT_EQ(getY(leftp.vertex(i)), getY(leftControl.vertex(i)));
+ }
+
+ Item downp(placer.downPoly(item));
+
+ ASSERT_TRUE(shapelike::isValid(downp.rawShape()).first);
+ ASSERT_EQ(downp.vertexCount(), downControl.vertexCount());
+
+ for(unsigned long i = 0; i < downControl.vertexCount(); i++) {
+ ASSERT_EQ(getX(downp.vertex(i)), getX(downControl.vertex(i)));
+ ASSERT_EQ(getY(downp.vertex(i)), getY(downControl.vertex(i)));
+ }
+}
+
+// Simple test, does not use gmock
+TEST(GeometryAlgorithms, ArrangeRectanglesTight)
+{
+ using namespace libnest2d;
+
+ std::vector<Rectangle> rects = {
+ {80, 80},
+ {60, 90},
+ {70, 30},
+ {80, 60},
+ {60, 60},
+ {60, 40},
+ {40, 40},
+ {10, 10},
+ {10, 10},
+ {10, 10},
+ {10, 10},
+ {10, 10},
+ {5, 5},
+ {5, 5},
+ {5, 5},
+ {5, 5},
+ {5, 5},
+ {5, 5},
+ {5, 5},
+ {20, 20} };
+
+
+ Nester<BottomLeftPlacer, DJDHeuristic> arrange(Box(210, 250));
+
+ auto groups = arrange(rects.begin(), rects.end());
+
+ ASSERT_EQ(groups.size(), 1u);
+ ASSERT_EQ(groups[0].size(), rects.size());
+
+ // check for no intersections, no containment:
+
+ for(auto result : groups) {
+ bool valid = true;
+ for(Item& r1 : result) {
+ for(Item& r2 : result) {
+ if(&r1 != &r2 ) {
+ valid = !Item::intersects(r1, r2) || Item::touches(r1, r2);
+ valid = (valid && !r1.isInside(r2) && !r2.isInside(r1));
+ ASSERT_TRUE(valid);
+ }
+ }
+ }
+ }
+
+}
+
+TEST(GeometryAlgorithms, ArrangeRectanglesLoose)
+{
+ using namespace libnest2d;
+
+// std::vector<Rectangle> rects = { {40, 40}, {10, 10}, {20, 20} };
+ std::vector<Rectangle> rects = {
+ {80, 80},
+ {60, 90},
+ {70, 30},
+ {80, 60},
+ {60, 60},
+ {60, 40},
+ {40, 40},
+ {10, 10},
+ {10, 10},
+ {10, 10},
+ {10, 10},
+ {10, 10},
+ {5, 5},
+ {5, 5},
+ {5, 5},
+ {5, 5},
+ {5, 5},
+ {5, 5},
+ {5, 5},
+ {20, 20} };
+
+ Coord min_obj_distance = 5;
+
+ Nester<BottomLeftPlacer, DJDHeuristic> arrange(Box(210, 250),
+ min_obj_distance);
+
+ auto groups = arrange(rects.begin(), rects.end());
+
+ ASSERT_EQ(groups.size(), 1u);
+ ASSERT_EQ(groups[0].size(), rects.size());
+
+ // check for no intersections, no containment:
+ auto result = groups[0];
+ bool valid = true;
+ for(Item& r1 : result) {
+ for(Item& r2 : result) {
+ if(&r1 != &r2 ) {
+ valid = !Item::intersects(r1, r2);
+ valid = (valid && !r1.isInside(r2) && !r2.isInside(r1));
+ ASSERT_TRUE(valid);
+ }
+ }
+ }
+
+}
+
+namespace {
+using namespace libnest2d;
+
+template<unsigned long SCALE = 1, class Bin>
+void exportSVG(std::vector<std::reference_wrapper<Item>>& result, const Bin& bin, int idx = 0) {
+
+
+ std::string loc = "out";
+
+ static std::string svg_header =
+R"raw(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg height="500" width="500" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+)raw";
+
+ int i = idx;
+ auto r = result;
+// for(auto r : result) {
+ std::fstream out(loc + std::to_string(i) + ".svg", std::fstream::out);
+ if(out.is_open()) {
+ out << svg_header;
+ Item rbin( Rectangle(bin.width(), bin.height()) );
+ for(unsigned i = 0; i < rbin.vertexCount(); i++) {
+ auto v = rbin.vertex(i);
+ setY(v, -getY(v)/SCALE + 500 );
+ setX(v, getX(v)/SCALE);
+ rbin.setVertex(i, v);
+ }
+ out << shapelike::serialize<Formats::SVG>(rbin.rawShape()) << std::endl;
+ for(Item& sh : r) {
+ Item tsh(sh.transformedShape());
+ for(unsigned i = 0; i < tsh.vertexCount(); i++) {
+ auto v = tsh.vertex(i);
+ setY(v, -getY(v)/SCALE + 500);
+ setX(v, getX(v)/SCALE);
+ tsh.setVertex(i, v);
+ }
+ out << shapelike::serialize<Formats::SVG>(tsh.rawShape()) << std::endl;
+ }
+ out << "\n</svg>" << std::endl;
+ }
+ out.close();
+
+// i++;
+// }
+}
+}
+
+TEST(GeometryAlgorithms, BottomLeftStressTest) {
+ using namespace libnest2d;
+
+ const Coord SCALE = 1000000;
+ auto& input = prusaParts();
+
+ Box bin(210*SCALE, 250*SCALE);
+ BottomLeftPlacer placer(bin);
+
+ auto it = input.begin();
+ auto next = it;
+ int i = 0;
+ while(it != input.end() && ++next != input.end()) {
+ placer.pack(*it);
+ placer.pack(*next);
+
+ auto result = placer.getItems();
+ bool valid = true;
+
+ if(result.size() == 2) {
+ Item& r1 = result[0];
+ Item& r2 = result[1];
+ valid = !Item::intersects(r1, r2) || Item::touches(r1, r2);
+ valid = (valid && !r1.isInside(r2) && !r2.isInside(r1));
+ if(!valid) {
+ std::cout << "error index: " << i << std::endl;
+ exportSVG(result, bin, i);
+ }
+ ASSERT_TRUE(valid);
+ } else {
+ std::cout << "something went terribly wrong!" << std::endl;
+ FAIL();
+ }
+
+ placer.clearItems();
+ it++;
+ i++;
+ }
+}
+
+namespace {
+
+struct ItemPair {
+ Item orbiter;
+ Item stationary;
+};
+
+std::vector<ItemPair> nfp_testdata = {
+ {
+ {
+ {80, 50},
+ {100, 70},
+ {120, 50},
+ {80, 50}
+ },
+ {
+ {10, 10},
+ {10, 40},
+ {40, 40},
+ {40, 10},
+ {10, 10}
+ }
+ },
+ {
+ {
+ {80, 50},
+ {60, 70},
+ {80, 90},
+ {120, 90},
+ {140, 70},
+ {120, 50},
+ {80, 50}
+ },
+ {
+ {10, 10},
+ {10, 40},
+ {40, 40},
+ {40, 10},
+ {10, 10}
+ }
+ },
+ {
+ {
+ {40, 10},
+ {30, 10},
+ {20, 20},
+ {20, 30},
+ {30, 40},
+ {40, 40},
+ {50, 30},
+ {50, 20},
+ {40, 10}
+ },
+ {
+ {80, 0},
+ {80, 30},
+ {110, 30},
+ {110, 0},
+ {80, 0}
+ }
+ },
+ {
+ {
+ {117, 107},
+ {118, 109},
+ {120, 112},
+ {122, 113},
+ {128, 113},
+ {130, 112},
+ {132, 109},
+ {133, 107},
+ {133, 103},
+ {132, 101},
+ {130, 98},
+ {128, 97},
+ {122, 97},
+ {120, 98},
+ {118, 101},
+ {117, 103},
+ {117, 107}
+ },
+ {
+ {102, 116},
+ {111, 126},
+ {114, 126},
+ {144, 106},
+ {148, 100},
+ {148, 85},
+ {147, 84},
+ {102, 84},
+ {102, 116},
+ }
+ },
+ {
+ {
+ {99, 122},
+ {108, 140},
+ {110, 142},
+ {139, 142},
+ {151, 122},
+ {151, 102},
+ {142, 70},
+ {139, 68},
+ {111, 68},
+ {108, 70},
+ {99, 102},
+ {99, 122},
+ },
+ {
+ {107, 124},
+ {128, 125},
+ {133, 125},
+ {136, 124},
+ {140, 121},
+ {142, 119},
+ {143, 116},
+ {143, 109},
+ {141, 93},
+ {139, 89},
+ {136, 86},
+ {134, 85},
+ {108, 85},
+ {107, 86},
+ {107, 124},
+ }
+ },
+ {
+ {
+ {91, 100},
+ {94, 144},
+ {117, 153},
+ {118, 153},
+ {159, 112},
+ {159, 110},
+ {156, 66},
+ {133, 57},
+ {132, 57},
+ {91, 98},
+ {91, 100},
+ },
+ {
+ {101, 90},
+ {103, 98},
+ {107, 113},
+ {114, 125},
+ {115, 126},
+ {135, 126},
+ {136, 125},
+ {144, 114},
+ {149, 90},
+ {149, 89},
+ {148, 87},
+ {145, 84},
+ {105, 84},
+ {102, 87},
+ {101, 89},
+ {101, 90},
+ }
+ }
+};
+
+std::vector<ItemPair> nfp_concave_testdata = {
+ { // ItemPair
+ {
+ {
+ {533726, 142141},
+ {532359, 143386},
+ {530141, 142155},
+ {528649, 160091},
+ {533659, 157607},
+ {538669, 160091},
+ {537178, 142155},
+ {534959, 143386},
+ {533726, 142141},
+ }
+ },
+ {
+ {
+ {118305, 11603},
+ {118311, 26616},
+ {113311, 26611},
+ {109311, 29604},
+ {109300, 44608},
+ {109311, 49631},
+ {113300, 52636},
+ {118311, 52636},
+ {118308, 103636},
+ {223830, 103636},
+ {236845, 90642},
+ {236832, 11630},
+ {232825, 11616},
+ {210149, 11616},
+ {211308, 13625},
+ {209315, 17080},
+ {205326, 17080},
+ {203334, 13629},
+ {204493, 11616},
+ {118305, 11603},
+ }
+ },
+ }
+};
+
+template<nfp::NfpLevel lvl, Coord SCALE>
+void testNfp(const std::vector<ItemPair>& testdata) {
+ using namespace libnest2d;
+
+ Box bin(210*SCALE, 250*SCALE);
+
+ int testcase = 0;
+
+ auto& exportfun = exportSVG<SCALE, Box>;
+
+ auto onetest = [&](Item& orbiter, Item& stationary, unsigned testidx){
+ testcase++;
+
+ orbiter.translate({210*SCALE, 0});
+
+ auto&& nfp = nfp::noFitPolygon<lvl>(stationary.rawShape(),
+ orbiter.transformedShape());
+
+ placers::correctNfpPosition(nfp, stationary, orbiter);
+
+ auto valid = shapelike::isValid(nfp.first);
+
+ /*Item infp(nfp.first);
+ if(!valid.first) {
+ std::cout << "test instance: " << testidx << " "
+ << valid.second << std::endl;
+ std::vector<std::reference_wrapper<Item>> inp = {std::ref(infp)};
+ exportfun(inp, bin, testidx);
+ }*/
+
+ ASSERT_TRUE(valid.first);
+
+ Item infp(nfp.first);
+
+ int i = 0;
+ auto rorbiter = orbiter.transformedShape();
+ auto vo = nfp::referenceVertex(rorbiter);
+
+ ASSERT_TRUE(stationary.isInside(infp));
+
+ for(auto v : infp) {
+ auto dx = getX(v) - getX(vo);
+ auto dy = getY(v) - getY(vo);
+
+ Item tmp = orbiter;
+
+ tmp.translate({dx, dy});
+
+ bool touching = Item::touches(tmp, stationary);
+
+ if(!touching || !valid.first) {
+ std::vector<std::reference_wrapper<Item>> inp = {
+ std::ref(stationary), std::ref(tmp), std::ref(infp)
+ };
+
+ exportfun(inp, bin, testcase*i++);
+ }
+
+ ASSERT_TRUE(touching);
+ }
+ };
+
+ unsigned tidx = 0;
+ for(auto& td : testdata) {
+ auto orbiter = td.orbiter;
+ auto stationary = td.stationary;
+ onetest(orbiter, stationary, tidx++);
+ }
+
+ tidx = 0;
+ for(auto& td : testdata) {
+ auto orbiter = td.stationary;
+ auto stationary = td.orbiter;
+ onetest(orbiter, stationary, tidx++);
+ }
+}
+}
+
+TEST(GeometryAlgorithms, nfpConvexConvex) {
+ testNfp<nfp::NfpLevel::CONVEX_ONLY, 1>(nfp_testdata);
+}
+
+//TEST(GeometryAlgorithms, nfpConcaveConcave) {
+// testNfp<NfpLevel::BOTH_CONCAVE, 1000>(nfp_concave_testdata);
+//}
+
+TEST(GeometryAlgorithms, nfpConcaveConcave) {
+ using namespace libnest2d;
+
+// Rectangle r1(10, 10);
+// Rectangle r2(20, 20);
+// auto result = Nfp::nfpSimpleSimple(r1.transformedShape(),
+// r2.transformedShape());
+}
+
+TEST(GeometryAlgorithms, pointOnPolygonContour) {
+ using namespace libnest2d;
+
+ Rectangle input(10, 10);
+
+ placers::EdgeCache<PolygonImpl> ecache(input);
+
+ auto first = *input.begin();
+ ASSERT_TRUE(getX(first) == getX(ecache.coords(0)));
+ ASSERT_TRUE(getY(first) == getY(ecache.coords(0)));
+
+ auto last = *std::prev(input.end());
+ ASSERT_TRUE(getX(last) == getX(ecache.coords(1.0)));
+ ASSERT_TRUE(getY(last) == getY(ecache.coords(1.0)));
+
+ for(int i = 0; i <= 100; i++) {
+ auto v = ecache.coords(i*(0.01));
+ ASSERT_TRUE(shapelike::touches(v, input.transformedShape()));
+ }
+}
+
+TEST(GeometryAlgorithms, mergePileWithPolygon) {
+ using namespace libnest2d;
+
+ Rectangle rect1(10, 15);
+ Rectangle rect2(15, 15);
+ Rectangle rect3(20, 15);
+
+ rect2.translate({10, 0});
+ rect3.translate({25, 0});
+
+ shapelike::Shapes<PolygonImpl> pile;
+ pile.push_back(rect1.transformedShape());
+ pile.push_back(rect2.transformedShape());
+
+ auto result = nfp::merge(pile, rect3.transformedShape());
+
+ ASSERT_EQ(result.size(), 1);
+
+ Rectangle ref(45, 15);
+
+ ASSERT_EQ(shapelike::area(result.front()), ref.area());
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/xs/src/libnest2d/tools/benchmark.h b/xs/src/libnest2d/tools/benchmark.h
new file mode 100644
index 000000000..19870b37b
--- /dev/null
+++ b/xs/src/libnest2d/tools/benchmark.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) Tamás Mészáros
+ * 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.
+ */
+#ifndef INCLUDE_BENCHMARK_H_
+#define INCLUDE_BENCHMARK_H_
+
+#include <chrono>
+#include <ratio>
+
+/**
+ * A class for doing benchmarks.
+ */
+class Benchmark {
+ typedef std::chrono::high_resolution_clock Clock;
+ typedef Clock::duration Duration;
+ typedef Clock::time_point TimePoint;
+
+ TimePoint t1, t2;
+ Duration d;
+
+ inline double to_sec(Duration d) {
+ return d.count() * double(Duration::period::num) / Duration::period::den;
+ }
+
+public:
+
+ /**
+ * Measure time from the moment of this call.
+ */
+ void start() { t1 = Clock::now(); }
+
+ /**
+ * Measure time to the moment of this call.
+ */
+ void stop() { t2 = Clock::now(); }
+
+ /**
+ * Get the time elapsed between a start() end a stop() call.
+ * @return Returns the elapsed time in seconds.
+ */
+ double getElapsedSec() { d = t2 - t1; return to_sec(d); }
+};
+
+
+#endif /* INCLUDE_BENCHMARK_H_ */
diff --git a/xs/src/libnest2d/tools/libnfpglue.cpp b/xs/src/libnest2d/tools/libnfpglue.cpp
new file mode 100644
index 000000000..31733acf9
--- /dev/null
+++ b/xs/src/libnest2d/tools/libnfpglue.cpp
@@ -0,0 +1,157 @@
+//#ifndef NDEBUG
+//#define NFP_DEBUG
+//#endif
+
+#include "libnfpglue.hpp"
+#include "tools/libnfporb/libnfporb.hpp"
+
+namespace libnest2d {
+
+namespace {
+inline bool vsort(const libnfporb::point_t& v1, const libnfporb::point_t& v2)
+{
+ using Coord = libnfporb::coord_t;
+ Coord x1 = v1.x_, x2 = v2.x_, y1 = v1.y_, y2 = v2.y_;
+ auto diff = y1 - y2;
+#ifdef LIBNFP_USE_RATIONAL
+ long double diffv = diff.convert_to<long double>();
+#else
+ long double diffv = diff.val();
+#endif
+ if(std::abs(diffv) <=
+ std::numeric_limits<Coord>::epsilon())
+ return x1 < x2;
+
+ return diff < 0;
+}
+
+TCoord<PointImpl> getX(const libnfporb::point_t& p) {
+#ifdef LIBNFP_USE_RATIONAL
+ return p.x_.convert_to<TCoord<PointImpl>>();
+#else
+ return static_cast<TCoord<PointImpl>>(std::round(p.x_.val()));
+#endif
+}
+
+TCoord<PointImpl> getY(const libnfporb::point_t& p) {
+#ifdef LIBNFP_USE_RATIONAL
+ return p.y_.convert_to<TCoord<PointImpl>>();
+#else
+ return static_cast<TCoord<PointImpl>>(std::round(p.y_.val()));
+#endif
+}
+
+libnfporb::point_t scale(const libnfporb::point_t& p, long double factor) {
+#ifdef LIBNFP_USE_RATIONAL
+ auto px = p.x_.convert_to<long double>();
+ auto py = p.y_.convert_to<long double>();
+#else
+ long double px = p.x_.val();
+ long double py = p.y_.val();
+#endif
+ return {px*factor, py*factor};
+}
+
+}
+
+NfpR _nfp(const PolygonImpl &sh, const PolygonImpl &cother)
+{
+ namespace sl = shapelike;
+
+ NfpR ret;
+
+ try {
+ libnfporb::polygon_t pstat, porb;
+
+ boost::geometry::convert(sh, pstat);
+ boost::geometry::convert(cother, porb);
+
+ long double factor = 0.0000001;//libnfporb::NFP_EPSILON;
+ long double refactor = 1.0/factor;
+
+ for(auto& v : pstat.outer()) v = scale(v, factor);
+// std::string message;
+// boost::geometry::is_valid(pstat, message);
+// std::cout << message << std::endl;
+ for(auto& h : pstat.inners()) for(auto& v : h) v = scale(v, factor);
+
+ for(auto& v : porb.outer()) v = scale(v, factor);
+// message;
+// boost::geometry::is_valid(porb, message);
+// std::cout << message << std::endl;
+ for(auto& h : porb.inners()) for(auto& v : h) v = scale(v, factor);
+
+
+ // this can throw
+ auto nfp = libnfporb::generateNFP(pstat, porb, true);
+
+ auto &ct = sl::getContour(ret.first);
+ ct.reserve(nfp.front().size()+1);
+ for(auto v : nfp.front()) {
+ v = scale(v, refactor);
+ ct.emplace_back(getX(v), getY(v));
+ }
+ ct.push_back(ct.front());
+ std::reverse(ct.begin(), ct.end());
+
+ auto &rholes = sl::holes(ret.first);
+ for(size_t hidx = 1; hidx < nfp.size(); ++hidx) {
+ if(nfp[hidx].size() >= 3) {
+ rholes.emplace_back();
+ auto& h = rholes.back();
+ h.reserve(nfp[hidx].size()+1);
+
+ for(auto& v : nfp[hidx]) {
+ v = scale(v, refactor);
+ h.emplace_back(getX(v), getY(v));
+ }
+ h.push_back(h.front());
+ std::reverse(h.begin(), h.end());
+ }
+ }
+
+ ret.second = nfp::referenceVertex(ret.first);
+
+ } catch(std::exception& e) {
+ std::cout << "Error: " << e.what() << "\nTrying with convex hull..." << std::endl;
+// auto ch_stat = ShapeLike::convexHull(sh);
+// auto ch_orb = ShapeLike::convexHull(cother);
+ ret = nfp::nfpConvexOnly(sh, cother);
+ }
+
+ return ret;
+}
+
+NfpR nfp::NfpImpl<PolygonImpl, nfp::NfpLevel::CONVEX_ONLY>::operator()(
+ const PolygonImpl &sh, const ClipperLib::PolygonImpl &cother)
+{
+ return _nfp(sh, cother);//nfpConvexOnly(sh, cother);
+}
+
+NfpR nfp::NfpImpl<PolygonImpl, nfp::NfpLevel::ONE_CONVEX>::operator()(
+ const PolygonImpl &sh, const ClipperLib::PolygonImpl &cother)
+{
+ return _nfp(sh, cother);
+}
+
+NfpR nfp::NfpImpl<PolygonImpl, nfp::NfpLevel::BOTH_CONCAVE>::operator()(
+ const PolygonImpl &sh, const ClipperLib::PolygonImpl &cother)
+{
+ return _nfp(sh, cother);
+}
+
+//PolygonImpl
+//Nfp::NfpImpl<PolygonImpl, NfpLevel::ONE_CONVEX_WITH_HOLES>::operator()(
+// const PolygonImpl &sh, const ClipperLib::PolygonImpl &cother)
+//{
+// return _nfp(sh, cother);
+//}
+
+//PolygonImpl
+//Nfp::NfpImpl<PolygonImpl, NfpLevel::BOTH_CONCAVE_WITH_HOLES>::operator()(
+// const PolygonImpl &sh, const ClipperLib::PolygonImpl &cother)
+//{
+// return _nfp(sh, cother);
+//}
+
+}
diff --git a/xs/src/libnest2d/tools/libnfpglue.hpp b/xs/src/libnest2d/tools/libnfpglue.hpp
new file mode 100644
index 000000000..1ff033cb9
--- /dev/null
+++ b/xs/src/libnest2d/tools/libnfpglue.hpp
@@ -0,0 +1,46 @@
+#ifndef LIBNFPGLUE_HPP
+#define LIBNFPGLUE_HPP
+
+#include <libnest2d/clipper_backend/clipper_backend.hpp>
+
+namespace libnest2d {
+
+using NfpR = nfp::NfpResult<PolygonImpl>;
+
+NfpR _nfp(const PolygonImpl& sh, const PolygonImpl& cother);
+
+template<>
+struct nfp::NfpImpl<PolygonImpl, nfp::NfpLevel::CONVEX_ONLY> {
+ NfpR operator()(const PolygonImpl& sh, const PolygonImpl& cother);
+};
+
+template<>
+struct nfp::NfpImpl<PolygonImpl, nfp::NfpLevel::ONE_CONVEX> {
+ NfpR operator()(const PolygonImpl& sh, const PolygonImpl& cother);
+};
+
+template<>
+struct nfp::NfpImpl<PolygonImpl, nfp::NfpLevel::BOTH_CONCAVE> {
+ NfpR operator()(const PolygonImpl& sh, const PolygonImpl& cother);
+};
+
+//template<>
+//struct Nfp::NfpImpl<PolygonImpl, NfpLevel::ONE_CONVEX_WITH_HOLES> {
+// NfpResult operator()(const PolygonImpl& sh, const PolygonImpl& cother);
+//};
+
+//template<>
+//struct Nfp::NfpImpl<PolygonImpl, NfpLevel::BOTH_CONCAVE_WITH_HOLES> {
+// NfpResult operator()(const PolygonImpl& sh, const PolygonImpl& cother);
+//};
+
+template<> struct nfp::MaxNfpLevel<PolygonImpl> {
+ static const BP2D_CONSTEXPR NfpLevel value =
+// NfpLevel::CONVEX_ONLY;
+ NfpLevel::BOTH_CONCAVE;
+};
+
+}
+
+
+#endif // LIBNFPGLUE_HPP
diff --git a/xs/src/libnest2d/tools/libnfporb/LICENSE b/xs/src/libnest2d/tools/libnfporb/LICENSE
new file mode 100644
index 000000000..94a9ed024
--- /dev/null
+++ b/xs/src/libnest2d/tools/libnfporb/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. 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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. 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.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ 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
+state 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 3 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 does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program 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, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU 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 Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/xs/src/libnest2d/tools/libnfporb/ORIGIN b/xs/src/libnest2d/tools/libnfporb/ORIGIN
new file mode 100644
index 000000000..788bfd9af
--- /dev/null
+++ b/xs/src/libnest2d/tools/libnfporb/ORIGIN
@@ -0,0 +1,2 @@
+https://github.com/kallaballa/libnfp.git
+commit hash a5cf9f6a76ddab95567fccf629d4d099b60237d7 \ No newline at end of file
diff --git a/xs/src/libnest2d/tools/libnfporb/README.md b/xs/src/libnest2d/tools/libnfporb/README.md
new file mode 100644
index 000000000..9698972be
--- /dev/null
+++ b/xs/src/libnest2d/tools/libnfporb/README.md
@@ -0,0 +1,89 @@
+[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.en.html)
+##### If you give me a real good reason i might be willing to give you permission to use it under a different license for a specific application. Real good reasons include the following (non-exhausive): the greater good, educational purpose and money :)
+
+# libnfporb
+Implementation of a robust no-fit polygon generation in a C++ library using an orbiting approach.
+
+__Please note:__ The paper this implementation is based it on has several bad assumptions that required me to "improvise". That means the code doesn't reflect the paper anymore and is running way slower than expected. At the moment I'm working on implementing a new approach based on this paper (using minkowski sums): https://eprints.soton.ac.uk/36850/1/CORMSIS-05-05.pdf
+
+## Description
+
+The no-fit polygon optimization makes it possible to check for overlap (or non-overlapping touch) of two polygons with only 1 point in polygon check (by providing the set of non-overlapping placements).
+This library implements the orbiting approach to generate the no-fit polygon: Given two polygons A and B, A is the stationary one and B the orbiting one, B is slid as tightly as possibly around the edges of polygon A. During the orbiting a chosen reference point is tracked. By tracking the movement of the reference point a third polygon can be generated: the no-fit polygon.
+
+Once the no-fit polygon has been generated it can be used to test for overlap by only checking if the reference point is inside the NFP (overlap) outside the NFP (no overlap) or exactly on the edge of the NFP (touch).
+
+### Examples:
+
+The polygons:
+
+![Start of NFP](/images/start.png?raw=true)
+
+Orbiting:
+
+![State 1](/images/next0.png?raw=true)
+![State 2](/images/next1.png?raw=true)
+![State 3](/images/next2.png?raw=true)
+![State 4](/images/next3.png?raw=true)
+
+![State 5](/images/next4.png?raw=true)
+![State 6](/images/next5.png?raw=true)
+![State 7](/images/next6.png?raw=true)
+![State 8](/images/next7.png?raw=true)
+
+![State 9](/images/next8.png?raw=true)
+
+The resulting NFP is red:
+
+![nfp](/images/nfp.png?raw=true)
+
+Polygons can have concavities, holes, interlocks or might fit perfectly:
+
+![concavities](/images/concavities.png?raw=true)
+![hole](/images/hole.png?raw=true)
+![interlock](/images/interlock.png?raw=true)
+![jigsaw](/images/jigsaw.png?raw=true)
+
+## The Approach
+The approch of this library is highly inspired by the scientific paper [Complete and robust no-fit polygon generation
+for the irregular stock cutting problem](https://pdfs.semanticscholar.org/e698/0dd78306ba7d5bb349d20c6d8f2e0aa61062.pdf) and by [Svgnest](http://svgnest.com)
+
+Note that is wasn't completely possible to implement it as suggested in the paper because it had several shortcomings that prevent complete NFP generation on some of my test cases. Especially the termination criteria (reference point returns to first point of NFP) proved to be wrong (see: test-case rect). Also tracking of used edges can't be performed as suggested in the paper since there might be situations where no edge of A is traversed (see: test-case doublecon).
+
+By default the library is using floating point as coordinate type but by defining the flag "LIBNFP_USE_RATIONAL" the library can be instructed to use infinite precision.
+
+## Build
+The library has two dependencies: [Boost Geometry](http://www.boost.org/doc/libs/1_65_1/libs/geometry/doc/html/index.html) and [libgmp](https://gmplib.org). You need to install those first before building. Note that building is only required for the examples. The library itself is header-only.
+
+ git clone https://github.com/kallaballa/libnfp.git
+ cd libnfp
+ make
+ sudo make install
+
+## Code Example
+
+```c++
+//uncomment next line to use infinite precision (slow)
+//#define LIBNFP_USE_RATIONAL
+#include "../src/libnfp.hpp"
+
+int main(int argc, char** argv) {
+ using namespace libnfp;
+ polygon_t pA;
+ polygon_t pB;
+ //read polygons from wkt files
+ read_wkt_polygon(argv[1], pA);
+ read_wkt_polygon(argv[2], pB);
+
+ //generate NFP of polygon A and polygon B and check the polygons for validity.
+ //When the third parameters is false validity check is skipped for a little performance increase
+ nfp_t nfp = generateNFP(pA, pB, true);
+
+ //write a svg containing pA, pB and NFP
+ write_svg("nfp.svg",{pA,pB},nfp);
+ return 0;
+}
+```
+Run the example program:
+
+ examples/nfp data/crossing/A.wkt data/crossing/B.wkt
diff --git a/xs/src/libnest2d/tools/libnfporb/libnfporb.hpp b/xs/src/libnest2d/tools/libnfporb/libnfporb.hpp
new file mode 100644
index 000000000..8cb34567e
--- /dev/null
+++ b/xs/src/libnest2d/tools/libnfporb/libnfporb.hpp
@@ -0,0 +1,1547 @@
+#ifndef NFP_HPP_
+#define NFP_HPP_
+
+#include <iostream>
+#include <list>
+#include <string>
+#include <fstream>
+#include <streambuf>
+#include <vector>
+#include <set>
+#include <exception>
+#include <random>
+#include <limits>
+
+#if defined(_MSC_VER) && _MSC_VER <= 1800 || __cplusplus < 201103L
+ #define LIBNFP_NOEXCEPT
+ #define LIBNFP_CONSTEXPR
+#elif __cplusplus >= 201103L
+ #define LIBNFP_NOEXCEPT noexcept
+ #define LIBNFP_CONSTEXPR constexpr
+#endif
+
+#ifdef LIBNFP_USE_RATIONAL
+#include <boost/multiprecision/gmp.hpp>
+#include <boost/multiprecision/number.hpp>
+#endif
+#include <boost/geometry.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/geometries/point_xy.hpp>
+#include <boost/geometry/geometries/polygon.hpp>
+#include <boost/geometry/geometries/linestring.hpp>
+#include <boost/geometry/io/svg/svg_mapper.hpp>
+#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/geometries/register/point.hpp>
+
+#ifdef LIBNFP_USE_RATIONAL
+namespace bm = boost::multiprecision;
+#endif
+namespace bg = boost::geometry;
+namespace trans = boost::geometry::strategy::transform;
+
+
+namespace libnfporb {
+#ifdef NFP_DEBUG
+#define DEBUG_VAL(x) std::cerr << x << std::endl;
+#define DEBUG_MSG(title, value) std::cerr << title << ":" << value << std::endl;
+#else
+#define DEBUG_VAL(x)
+#define DEBUG_MSG(title, value)
+#endif
+
+using std::string;
+
+static LIBNFP_CONSTEXPR long double NFP_EPSILON=0.00000001;
+
+class LongDouble {
+private:
+ long double val_;
+public:
+ LongDouble() : val_(0) {
+ }
+
+ LongDouble(const long double& val) : val_(val) {
+ }
+
+ void setVal(const long double& v) {
+ val_ = v;
+ }
+
+ long double val() const {
+ return val_;
+ }
+
+ LongDouble operator/(const LongDouble& other) const {
+ return this->val_ / other.val_;
+ }
+
+ LongDouble operator*(const LongDouble& other) const {
+ return this->val_ * other.val_;
+ }
+
+ LongDouble operator-(const LongDouble& other) const {
+ return this->val_ - other.val_;
+ }
+
+ LongDouble operator-() const {
+ return this->val_ * -1;
+ }
+
+ LongDouble operator+(const LongDouble& other) const {
+ return this->val_ + other.val_;
+ }
+
+ void operator/=(const LongDouble& other) {
+ this->val_ = this->val_ / other.val_;
+ }
+
+ void operator*=(const LongDouble& other) {
+ this->val_ = this->val_ * other.val_;
+ }
+
+ void operator-=(const LongDouble& other) {
+ this->val_ = this->val_ - other.val_;
+ }
+
+ void operator+=(const LongDouble& other) {
+ this->val_ = this->val_ + other.val_;
+ }
+
+ bool operator==(const int& other) const {
+ return this->operator ==(static_cast<long double>(other));
+ }
+
+ bool operator==(const LongDouble& other) const {
+ return this->operator ==(other.val());
+ }
+
+ bool operator==(const long double& other) const {
+ return this->val() == other;
+ }
+
+ bool operator!=(const int& other) const {
+ return !this->operator ==(other);
+ }
+
+ bool operator!=(const LongDouble& other) const {
+ return !this->operator ==(other);
+ }
+
+ bool operator!=(const long double& other) const {
+ return !this->operator ==(other);
+ }
+
+ bool operator<(const int& other) const {
+ return this->operator <(static_cast<long double>(other));
+ }
+
+ bool operator<(const LongDouble& other) const {
+ return this->operator <(other.val());
+ }
+
+ bool operator<(const long double& other) const {
+ return this->val() < other;
+ }
+
+ bool operator>(const int& other) const {
+ return this->operator >(static_cast<long double>(other));
+ }
+
+ bool operator>(const LongDouble& other) const {
+ return this->operator >(other.val());
+ }
+
+ bool operator>(const long double& other) const {
+ return this->val() > other;
+ }
+
+ bool operator>=(const int& other) const {
+ return this->operator >=(static_cast<long double>(other));
+ }
+
+ bool operator>=(const LongDouble& other) const {
+ return this->operator >=(other.val());
+ }
+
+ bool operator>=(const long double& other) const {
+ return this->val() >= other;
+ }
+
+ bool operator<=(const int& other) const {
+ return this->operator <=(static_cast<long double>(other));
+ }
+
+ bool operator<=(const LongDouble& other) const {
+ return this->operator <=(other.val());
+ }
+
+ bool operator<=(const long double& other) const {
+ return this->val() <= other;
+ }
+};
+}
+
+
+namespace std {
+template<>
+ struct numeric_limits<libnfporb::LongDouble>
+ {
+ static const LIBNFP_CONSTEXPR bool is_specialized = true;
+
+ static const LIBNFP_CONSTEXPR long double
+ min() LIBNFP_NOEXCEPT { return std::numeric_limits<long double>::min(); }
+
+ static LIBNFP_CONSTEXPR long double
+ max() LIBNFP_NOEXCEPT { return std::numeric_limits<long double>::max(); }
+
+#if __cplusplus >= 201103L
+ static LIBNFP_CONSTEXPR long double
+ lowest() LIBNFP_NOEXCEPT { return -std::numeric_limits<long double>::lowest(); }
+#endif
+
+ static const LIBNFP_CONSTEXPR int digits = std::numeric_limits<long double>::digits;
+ static const LIBNFP_CONSTEXPR int digits10 = std::numeric_limits<long double>::digits10;
+#if __cplusplus >= 201103L
+ static const LIBNFP_CONSTEXPR int max_digits10
+ = std::numeric_limits<long double>::max_digits10;
+#endif
+ static const LIBNFP_CONSTEXPR bool is_signed = true;
+ static const LIBNFP_CONSTEXPR bool is_integer = false;
+ static const LIBNFP_CONSTEXPR bool is_exact = false;
+ static const LIBNFP_CONSTEXPR int radix = std::numeric_limits<long double>::radix;
+
+ static const LIBNFP_CONSTEXPR long double
+ epsilon() LIBNFP_NOEXCEPT { return libnfporb::NFP_EPSILON; }
+
+ static const LIBNFP_CONSTEXPR long double
+ round_error() LIBNFP_NOEXCEPT { return 0.5L; }
+
+ static const LIBNFP_CONSTEXPR int min_exponent = std::numeric_limits<long double>::min_exponent;
+ static const LIBNFP_CONSTEXPR int min_exponent10 = std::numeric_limits<long double>::min_exponent10;
+ static const LIBNFP_CONSTEXPR int max_exponent = std::numeric_limits<long double>::max_exponent;
+ static const LIBNFP_CONSTEXPR int max_exponent10 = std::numeric_limits<long double>::max_exponent10;
+
+
+ static const LIBNFP_CONSTEXPR bool has_infinity = std::numeric_limits<long double>::has_infinity;
+ static const LIBNFP_CONSTEXPR bool has_quiet_NaN = std::numeric_limits<long double>::has_quiet_NaN;
+ static const LIBNFP_CONSTEXPR bool has_signaling_NaN = has_quiet_NaN;
+ static const LIBNFP_CONSTEXPR float_denorm_style has_denorm
+ = std::numeric_limits<long double>::has_denorm;
+ static const LIBNFP_CONSTEXPR bool has_denorm_loss
+ = std::numeric_limits<long double>::has_denorm_loss;
+
+
+ static const LIBNFP_CONSTEXPR long double
+ infinity() LIBNFP_NOEXCEPT { return std::numeric_limits<long double>::infinity(); }
+
+ static const LIBNFP_CONSTEXPR long double
+ quiet_NaN() LIBNFP_NOEXCEPT { return std::numeric_limits<long double>::quiet_NaN(); }
+
+ static const LIBNFP_CONSTEXPR long double
+ signaling_NaN() LIBNFP_NOEXCEPT { return std::numeric_limits<long double>::signaling_NaN(); }
+
+
+ static const LIBNFP_CONSTEXPR long double
+ denorm_min() LIBNFP_NOEXCEPT { return std::numeric_limits<long double>::denorm_min(); }
+
+ static const LIBNFP_CONSTEXPR bool is_iec559
+ = has_infinity && has_quiet_NaN && has_denorm == denorm_present;
+
+ static const LIBNFP_CONSTEXPR bool is_bounded = true;
+ static const LIBNFP_CONSTEXPR bool is_modulo = false;
+
+ static const LIBNFP_CONSTEXPR bool traps = std::numeric_limits<long double>::traps;
+ static const LIBNFP_CONSTEXPR bool tinyness_before =
+ std::numeric_limits<long double>::tinyness_before;
+ static const LIBNFP_CONSTEXPR float_round_style round_style =
+ round_to_nearest;
+ };
+}
+
+namespace boost {
+namespace numeric {
+ template<>
+ struct raw_converter<boost::numeric::conversion_traits<double, libnfporb::LongDouble>>
+ {
+ typedef boost::numeric::conversion_traits<double, libnfporb::LongDouble>::result_type result_type ;
+ typedef boost::numeric::conversion_traits<double, libnfporb::LongDouble>::argument_type argument_type ;
+
+ static result_type low_level_convert ( argument_type s ) { return s.val() ; }
+ } ;
+}
+}
+
+namespace libnfporb {
+
+#ifndef LIBNFP_USE_RATIONAL
+typedef LongDouble coord_t;
+#else
+typedef bm::number<bm::gmp_rational, bm::et_off> rational_t;
+typedef rational_t coord_t;
+#endif
+
+bool equals(const LongDouble& lhs, const LongDouble& rhs);
+#ifdef LIBNFP_USE_RATIONAL
+bool equals(const rational_t& lhs, const rational_t& rhs);
+#endif
+bool equals(const long double& lhs, const long double& rhs);
+
+const coord_t MAX_COORD = 999999999999999999.0;
+const coord_t MIN_COORD = std::numeric_limits<coord_t>::min();
+
+class point_t {
+public:
+ point_t() : x_(0), y_(0) {
+ }
+ point_t(coord_t x, coord_t y) : x_(x), y_(y) {
+ }
+ bool marked_ = false;
+ coord_t x_;
+ coord_t y_;
+
+ point_t operator-(const point_t& other) const {
+ point_t result = *this;
+ bg::subtract_point(result, other);
+ return result;
+ }
+
+ point_t operator+(const point_t& other) const {
+ point_t result = *this;
+ bg::add_point(result, other);
+ return result;
+ }
+
+ bool operator==(const point_t& other) const {
+ return bg::equals(this, other);
+ }
+
+ bool operator!=(const point_t& other) const {
+ return !this->operator ==(other);
+ }
+
+ bool operator<(const point_t& other) const {
+ return boost::geometry::math::smaller(this->x_, other.x_) || (equals(this->x_, other.x_) && boost::geometry::math::smaller(this->y_, other.y_));
+ }
+};
+
+
+
+
+inline long double toLongDouble(const LongDouble& c) {
+ return c.val();
+}
+
+#ifdef LIBNFP_USE_RATIONAL
+inline long double toLongDouble(const rational_t& c) {
+ return bm::numerator(c).convert_to<long double>() / bm::denominator(c).convert_to<long double>();
+}
+#endif
+
+std::ostream& operator<<(std::ostream& os, const coord_t& p) {
+ os << toLongDouble(p);
+ return os;
+}
+
+std::istream& operator>>(std::istream& is, LongDouble& c) {
+ long double val;
+ is >> val;
+ c.setVal(val);
+ return is;
+}
+
+std::ostream& operator<<(std::ostream& os, const point_t& p) {
+ os << "{" << toLongDouble(p.x_) << "," << toLongDouble(p.y_) << "}";
+ return os;
+}
+const point_t INVALID_POINT = {MAX_COORD, MAX_COORD};
+
+typedef bg::model::segment<point_t> segment_t;
+}
+
+#ifdef LIBNFP_USE_RATIONAL
+inline long double acos(const libnfporb::rational_t& r) {
+ return acos(libnfporb::toLongDouble(r));
+}
+#endif
+
+inline long double acos(const libnfporb::LongDouble& ld) {
+ return acos(libnfporb::toLongDouble(ld));
+}
+
+#ifdef LIBNFP_USE_RATIONAL
+inline long double sqrt(const libnfporb::rational_t& r) {
+ return sqrt(libnfporb::toLongDouble(r));
+}
+#endif
+
+inline long double sqrt(const libnfporb::LongDouble& ld) {
+ return sqrt(libnfporb::toLongDouble(ld));
+}
+
+BOOST_GEOMETRY_REGISTER_POINT_2D(libnfporb::point_t, libnfporb::coord_t, cs::cartesian, x_, y_)
+
+
+namespace boost {
+namespace geometry {
+namespace math {
+namespace detail {
+
+template <>
+struct square_root<libnfporb::LongDouble>
+{
+ typedef libnfporb::LongDouble return_type;
+
+ static inline libnfporb::LongDouble apply(libnfporb::LongDouble const& a)
+ {
+ return std::sqrt(a.val());
+ }
+};
+
+#ifdef LIBNFP_USE_RATIONAL
+template <>
+struct square_root<libnfporb::rational_t>
+{
+ typedef libnfporb::rational_t return_type;
+
+ static inline libnfporb::rational_t apply(libnfporb::rational_t const& a)
+ {
+ return std::sqrt(libnfporb::toLongDouble(a));
+ }
+};
+#endif
+
+template<>
+struct abs<libnfporb::LongDouble>
+ {
+ static libnfporb::LongDouble apply(libnfporb::LongDouble const& value)
+ {
+ libnfporb::LongDouble const zero = libnfporb::LongDouble();
+ return value.val() < zero.val() ? -value.val() : value.val();
+ }
+ };
+
+template <>
+struct equals<libnfporb::LongDouble, false>
+{
+ template<typename Policy>
+ static inline bool apply(libnfporb::LongDouble const& lhs, libnfporb::LongDouble const& rhs, Policy const& policy)
+ {
+ if(lhs.val() == rhs.val())
+ return true;
+
+ return bg::math::detail::abs<libnfporb::LongDouble>::apply(lhs.val() - rhs.val()) <= policy.apply(lhs.val(), rhs.val()) * libnfporb::NFP_EPSILON;
+ }
+};
+
+template <>
+struct smaller<libnfporb::LongDouble>
+{
+ static inline bool apply(libnfporb::LongDouble const& lhs, libnfporb::LongDouble const& rhs)
+ {
+ if(lhs.val() == rhs.val() || bg::math::detail::abs<libnfporb::LongDouble>::apply(lhs.val() - rhs.val()) <= libnfporb::NFP_EPSILON * std::max(lhs.val(), rhs.val()))
+ return false;
+
+ return lhs < rhs;
+ }
+};
+}
+}
+}
+}
+
+namespace libnfporb {
+inline bool smaller(const LongDouble& lhs, const LongDouble& rhs) {
+ return boost::geometry::math::detail::smaller<LongDouble>::apply(lhs, rhs);
+}
+
+inline bool larger(const LongDouble& lhs, const LongDouble& rhs) {
+ return smaller(rhs, lhs);
+}
+
+bool equals(const LongDouble& lhs, const LongDouble& rhs) {
+ if(lhs.val() == rhs.val())
+ return true;
+
+ return bg::math::detail::abs<libnfporb::LongDouble>::apply(lhs.val() - rhs.val()) <= libnfporb::NFP_EPSILON * std::max(lhs.val(), rhs.val());
+}
+
+#ifdef LIBNFP_USE_RATIONAL
+inline bool smaller(const rational_t& lhs, const rational_t& rhs) {
+ return lhs < rhs;
+}
+
+inline bool larger(const rational_t& lhs, const rational_t& rhs) {
+ return smaller(rhs, lhs);
+}
+
+bool equals(const rational_t& lhs, const rational_t& rhs) {
+ return lhs == rhs;
+}
+#endif
+
+inline bool smaller(const long double& lhs, const long double& rhs) {
+ return lhs < rhs;
+}
+
+inline bool larger(const long double& lhs, const long double& rhs) {
+ return smaller(rhs, lhs);
+}
+
+
+bool equals(const long double& lhs, const long double& rhs) {
+ return lhs == rhs;
+}
+
+typedef bg::model::polygon<point_t, false, true> polygon_t;
+typedef std::vector<polygon_t::ring_type> nfp_t;
+typedef bg::model::linestring<point_t> linestring_t;
+
+typedef polygon_t::ring_type::size_type psize_t;
+
+typedef bg::model::d2::point_xy<long double> pointf_t;
+typedef bg::model::segment<pointf_t> segmentf_t;
+typedef bg::model::polygon<pointf_t, false, true> polygonf_t;
+
+polygonf_t::ring_type convert(const polygon_t::ring_type& r) {
+ polygonf_t::ring_type rf;
+ for(const auto& pt : r) {
+ rf.push_back(pointf_t(toLongDouble(pt.x_), toLongDouble(pt.y_)));
+ }
+ return rf;
+}
+
+polygonf_t convert(polygon_t p) {
+ polygonf_t pf;
+ pf.outer() = convert(p.outer());
+
+ for(const auto& r : p.inners()) {
+ pf.inners().push_back(convert(r));
+ }
+
+ return pf;
+}
+
+polygon_t nfpRingsToNfpPoly(const nfp_t& nfp) {
+ polygon_t nfppoly;
+ for (const auto& pt : nfp.front()) {
+ nfppoly.outer().push_back(pt);
+ }
+
+ for (size_t i = 1; i < nfp.size(); ++i) {
+ nfppoly.inners().push_back({});
+ for (const auto& pt : nfp[i]) {
+ nfppoly.inners().back().push_back(pt);
+ }
+ }
+
+ return nfppoly;
+}
+
+void write_svg(std::string const& filename,const std::vector<segment_t>& segments) {
+ std::ofstream svg(filename.c_str());
+
+ boost::geometry::svg_mapper<pointf_t> mapper(svg, 100, 100, "width=\"200mm\" height=\"200mm\" viewBox=\"-250 -250 500 500\"");
+ for(const auto& seg : segments) {
+ segmentf_t segf({toLongDouble(seg.first.x_), toLongDouble(seg.first.y_)}, {toLongDouble(seg.second.x_), toLongDouble(seg.second.y_)});
+ mapper.add(segf);
+ mapper.map(segf, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
+ }
+}
+
+void write_svg(std::string const& filename, const polygon_t& p, const polygon_t::ring_type& ring) {
+ std::ofstream svg(filename.c_str());
+
+ boost::geometry::svg_mapper<pointf_t> mapper(svg, 100, 100, "width=\"200mm\" height=\"200mm\" viewBox=\"-250 -250 500 500\"");
+ auto pf = convert(p);
+ auto rf = convert(ring);
+
+ mapper.add(pf);
+ mapper.map(pf, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
+ mapper.add(rf);
+ mapper.map(rf, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
+}
+
+void write_svg(std::string const& filename, std::vector<polygon_t> const& polygons) {
+ std::ofstream svg(filename.c_str());
+
+ boost::geometry::svg_mapper<pointf_t> mapper(svg, 100, 100, "width=\"200mm\" height=\"200mm\" viewBox=\"-250 -250 500 500\"");
+ for (auto p : polygons) {
+ auto pf = convert(p);
+ mapper.add(pf);
+ mapper.map(pf, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
+ }
+}
+
+void write_svg(std::string const& filename, std::vector<polygon_t> const& polygons, const nfp_t& nfp) {
+ polygon_t nfppoly;
+ for (const auto& pt : nfp.front()) {
+ nfppoly.outer().push_back(pt);
+ }
+
+ for (size_t i = 1; i < nfp.size(); ++i) {
+ nfppoly.inners().push_back({});
+ for (const auto& pt : nfp[i]) {
+ nfppoly.inners().back().push_back(pt);
+ }
+ }
+ std::ofstream svg(filename.c_str());
+
+ boost::geometry::svg_mapper<pointf_t> mapper(svg, 100, 100, "width=\"200mm\" height=\"200mm\" viewBox=\"-250 -250 500 500\"");
+ for (auto p : polygons) {
+ auto pf = convert(p);
+ mapper.add(pf);
+ mapper.map(pf, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
+ }
+ bg::correct(nfppoly);
+ auto nfpf = convert(nfppoly);
+ mapper.add(nfpf);
+ mapper.map(nfpf, "fill-opacity:0.5;fill:rgb(204,153,0);stroke:rgb(204,153,0);stroke-width:2");
+
+ for(auto& r: nfpf.inners()) {
+ if(r.size() == 1) {
+ mapper.add(r.front());
+ mapper.map(r.front(), "fill-opacity:0.5;fill:rgb(204,153,0);stroke:rgb(204,153,0);stroke-width:2");
+ } else if(r.size() == 2) {
+ segmentf_t seg(r.front(), *(r.begin()+1));
+ mapper.add(seg);
+ mapper.map(seg, "fill-opacity:0.5;fill:rgb(204,153,0);stroke:rgb(204,153,0);stroke-width:2");
+ }
+ }
+}
+
+std::ostream& operator<<(std::ostream& os, const segment_t& seg) {
+ os << "{" << seg.first << "," << seg.second << "}";
+ return os;
+}
+
+bool operator<(const segment_t& lhs, const segment_t& rhs) {
+ return lhs.first < rhs.first || ((lhs.first == rhs.first) && (lhs.second < rhs.second));
+}
+
+bool operator==(const segment_t& lhs, const segment_t& rhs) {
+ return (lhs.first == rhs.first && lhs.second == rhs.second) || (lhs.first == rhs.second && lhs.second == rhs.first);
+}
+
+bool operator!=(const segment_t& lhs, const segment_t& rhs) {
+ return !operator==(lhs,rhs);
+}
+
+enum Alignment {
+ LEFT,
+ RIGHT,
+ ON
+};
+
+point_t normalize(const point_t& pt) {
+ point_t norm = pt;
+ coord_t len = bg::length(segment_t{{0,0},pt});
+
+ if(len == 0.0L)
+ return {0,0};
+
+ norm.x_ /= len;
+ norm.y_ /= len;
+
+ return norm;
+}
+
+Alignment get_alignment(const segment_t& seg, const point_t& pt){
+ coord_t res = ((seg.second.x_ - seg.first.x_)*(pt.y_ - seg.first.y_)
+ - (seg.second.y_ - seg.first.y_)*(pt.x_ - seg.first.x_));
+
+ if(equals(res, 0)) {
+ return ON;
+ } else if(larger(res,0)) {
+ return LEFT;
+ } else {
+ return RIGHT;
+ }
+}
+
+long double get_inner_angle(const point_t& joint, const point_t& end1, const point_t& end2) {
+ coord_t dx21 = end1.x_-joint.x_;
+ coord_t dx31 = end2.x_-joint.x_;
+ coord_t dy21 = end1.y_-joint.y_;
+ coord_t dy31 = end2.y_-joint.y_;
+ coord_t m12 = sqrt((dx21*dx21 + dy21*dy21));
+ coord_t m13 = sqrt((dx31*dx31 + dy31*dy31));
+ if(m12 == 0.0L || m13 == 0.0L)
+ return 0;
+ return acos( (dx21*dx31 + dy21*dy31) / (m12 * m13) );
+}
+
+struct TouchingPoint {
+ enum Type {
+ VERTEX,
+ A_ON_B,
+ B_ON_A
+ };
+ Type type_;
+ psize_t A_;
+ psize_t B_;
+};
+
+struct TranslationVector {
+ point_t vector_;
+ segment_t edge_;
+ bool fromA_;
+ string name_;
+
+ bool operator<(const TranslationVector& other) const {
+ return this->vector_ < other.vector_ || ((this->vector_ == other.vector_) && (this->edge_ < other.edge_));
+ }
+};
+
+std::ostream& operator<<(std::ostream& os, const TranslationVector& tv) {
+ os << "{" << tv.edge_ << " -> " << tv.vector_ << "} = " << tv.name_;
+ return os;
+}
+
+
+void read_wkt_polygon(const string& filename, polygon_t& p) {
+ std::ifstream t(filename);
+
+ std::string str;
+ t.seekg(0, std::ios::end);
+ str.reserve(t.tellg());
+ t.seekg(0, std::ios::beg);
+
+ str.assign((std::istreambuf_iterator<char>(t)),
+ std::istreambuf_iterator<char>());
+
+ str.pop_back();
+ bg::read_wkt(str, p);
+ bg::correct(p);
+}
+
+std::vector<psize_t> find_minimum_y(const polygon_t& p) {
+ std::vector<psize_t> result;
+ coord_t min = MAX_COORD;
+ auto& po = p.outer();
+ for(psize_t i = 0; i < p.outer().size() - 1; ++i) {
+ if(smaller(po[i].y_, min)) {
+ result.clear();
+ min = po[i].y_;
+ result.push_back(i);
+ } else if (equals(po[i].y_, min)) {
+ result.push_back(i);
+ }
+ }
+ return result;
+}
+
+std::vector<psize_t> find_maximum_y(const polygon_t& p) {
+ std::vector<psize_t> result;
+ coord_t max = MIN_COORD;
+ auto& po = p.outer();
+ for(psize_t i = 0; i < p.outer().size() - 1; ++i) {
+ if(larger(po[i].y_, max)) {
+ result.clear();
+ max = po[i].y_;
+ result.push_back(i);
+ } else if (equals(po[i].y_, max)) {
+ result.push_back(i);
+ }
+ }
+ return result;
+}
+
+psize_t find_point(const polygon_t::ring_type& ring, const point_t& pt) {
+ for(psize_t i = 0; i < ring.size(); ++i) {
+ if(ring[i] == pt)
+ return i;
+ }
+ return std::numeric_limits<psize_t>::max();
+}
+
+std::vector<TouchingPoint> findTouchingPoints(const polygon_t::ring_type& ringA, const polygon_t::ring_type& ringB) {
+ std::vector<TouchingPoint> touchers;
+ for(psize_t i = 0; i < ringA.size() - 1; i++) {
+ psize_t nextI = i+1;
+ for(psize_t j = 0; j < ringB.size() - 1; j++) {
+ psize_t nextJ = j+1;
+ if(ringA[i] == ringB[j]) {
+ touchers.push_back({TouchingPoint::VERTEX, i, j});
+ } else if (ringA[nextI] != ringB[j] && bg::intersects(segment_t(ringA[i],ringA[nextI]), ringB[j])) {
+ touchers.push_back({TouchingPoint::B_ON_A, nextI, j});
+ } else if (ringB[nextJ] != ringA[i] && bg::intersects(segment_t(ringB[j],ringB[nextJ]), ringA[i])) {
+ touchers.push_back({TouchingPoint::A_ON_B, i, nextJ});
+ }
+ }
+ }
+ return touchers;
+}
+
+//TODO deduplicate code
+TranslationVector trimVector(const polygon_t::ring_type& rA, const polygon_t::ring_type& rB, const TranslationVector& tv) {
+ coord_t shortest = bg::length(tv.edge_);
+ TranslationVector trimmed = tv;
+ for(const auto& ptA : rA) {
+ point_t translated;
+ //for polygon A we invert the translation
+ trans::translate_transformer<coord_t, 2, 2> translate(-tv.vector_.x_, -tv.vector_.y_);
+ boost::geometry::transform(ptA, translated, translate);
+ linestring_t projection;
+ segment_t segproj(ptA, translated);
+ projection.push_back(ptA);
+ projection.push_back(translated);
+ std::vector<point_t> intersections;
+ bg::intersection(rB, projection, intersections);
+ if(bg::touches(projection, rB) && intersections.size() < 2) {
+ continue;
+ }
+
+ //find shortest intersection
+ coord_t len;
+ segment_t segi;
+ for(const auto& pti : intersections) {
+ segi = segment_t(ptA,pti);
+ len = bg::length(segi);
+ if(smaller(len, shortest)) {
+ trimmed.vector_ = ptA - pti;
+ trimmed.edge_ = segi;
+ shortest = len;
+ }
+ }
+ }
+
+ for(const auto& ptB : rB) {
+ point_t translated;
+
+ trans::translate_transformer<coord_t, 2, 2> translate(tv.vector_.x_, tv.vector_.y_);
+ boost::geometry::transform(ptB, translated, translate);
+ linestring_t projection;
+ segment_t segproj(ptB, translated);
+ projection.push_back(ptB);
+ projection.push_back(translated);
+ std::vector<point_t> intersections;
+ bg::intersection(rA, projection, intersections);
+ if(bg::touches(projection, rA) && intersections.size() < 2) {
+ continue;
+ }
+
+ //find shortest intersection
+ coord_t len;
+ segment_t segi;
+ for(const auto& pti : intersections) {
+
+ segi = segment_t(ptB,pti);
+ len = bg::length(segi);
+ if(smaller(len, shortest)) {
+ trimmed.vector_ = pti - ptB;
+ trimmed.edge_ = segi;
+ shortest = len;
+ }
+ }
+ }
+ return trimmed;
+}
+
+std::vector<TranslationVector> findFeasibleTranslationVectors(polygon_t::ring_type& ringA, polygon_t::ring_type& ringB, const std::vector<TouchingPoint>& touchers) {
+ //use a set to automatically filter duplicate vectors
+ std::vector<TranslationVector> potentialVectors;
+ std::vector<std::pair<segment_t,segment_t>> touchEdges;
+
+ for (psize_t i = 0; i < touchers.size(); i++) {
+ point_t& vertexA = ringA[touchers[i].A_];
+ vertexA.marked_ = true;
+
+ // adjacent A vertices
+ auto prevAindex = static_cast<signed long>(touchers[i].A_ - 1);
+ auto nextAindex = static_cast<signed long>(touchers[i].A_ + 1);
+
+ prevAindex = (prevAindex < 0) ? static_cast<signed long>(ringA.size() - 2) : prevAindex; // loop
+ nextAindex = (static_cast<psize_t>(nextAindex) >= ringA.size()) ? 1 : nextAindex; // loop
+
+ point_t& prevA = ringA[prevAindex];
+ point_t& nextA = ringA[nextAindex];
+
+ // adjacent B vertices
+ point_t& vertexB = ringB[touchers[i].B_];
+
+ auto prevBindex = static_cast<signed long>(touchers[i].B_ - 1);
+ auto nextBindex = static_cast<signed long>(touchers[i].B_ + 1);
+
+ prevBindex = (prevBindex < 0) ? static_cast<signed long>(ringB.size() - 2) : prevBindex; // loop
+ nextBindex = (static_cast<psize_t>(nextBindex) >= ringB.size()) ? 1 : nextBindex; // loop
+
+ point_t& prevB = ringB[prevBindex];
+ point_t& nextB = ringB[nextBindex];
+
+ if (touchers[i].type_ == TouchingPoint::VERTEX) {
+ segment_t a1 = { vertexA, nextA };
+ segment_t a2 = { vertexA, prevA };
+ segment_t b1 = { vertexB, nextB };
+ segment_t b2 = { vertexB, prevB };
+
+ //swap the segment elements so that always the first point is the touching point
+ //also make the second segment always a segment of ringB
+ touchEdges.push_back({a1, b1});
+ touchEdges.push_back({a1, b2});
+ touchEdges.push_back({a2, b1});
+ touchEdges.push_back({a2, b2});
+#ifdef NFP_DEBUG
+ write_svg("touchersV" + std::to_string(i) + ".svg", {a1,a2,b1,b2});
+#endif
+
+ //TODO test parallel edges for floating point stability
+ Alignment al;
+ //a1 and b1 meet at start vertex
+ al = get_alignment(a1, b1.second);
+ if(al == LEFT) {
+ potentialVectors.push_back({b1.first - b1.second, b1, false, "vertex1"});
+ } else if(al == RIGHT) {
+ potentialVectors.push_back({a1.second - a1.first, a1, true, "vertex2"});
+ } else {
+ potentialVectors.push_back({a1.second - a1.first, a1, true, "vertex3"});
+ }
+
+ //a1 and b2 meet at start and end
+ al = get_alignment(a1, b2.second);
+ if(al == LEFT) {
+ //no feasible translation
+ } else if(al == RIGHT) {
+ potentialVectors.push_back({a1.second - a1.first, a1, true, "vertex4"});
+ } else {
+ potentialVectors.push_back({a1.second - a1.first, a1, true, "vertex5"});
+ }
+
+ //a2 and b1 meet at end and start
+ al = get_alignment(a2, b1.second);
+ if(al == LEFT) {
+ //no feasible translation
+ } else if(al == RIGHT) {
+ potentialVectors.push_back({b1.first - b1.second, b1, false, "vertex6"});
+ } else {
+ potentialVectors.push_back({b1.first - b1.second, b1, false, "vertex7"});
+ }
+ } else if (touchers[i].type_ == TouchingPoint::B_ON_A) {
+ segment_t a1 = {vertexB, vertexA};
+ segment_t a2 = {vertexB, prevA};
+ segment_t b1 = {vertexB, prevB};
+ segment_t b2 = {vertexB, nextB};
+
+ touchEdges.push_back({a1, b1});
+ touchEdges.push_back({a1, b2});
+ touchEdges.push_back({a2, b1});
+ touchEdges.push_back({a2, b2});
+#ifdef NFP_DEBUG
+ write_svg("touchersB" + std::to_string(i) + ".svg", {a1,a2,b1,b2});
+#endif
+ potentialVectors.push_back({vertexA - vertexB, {vertexB, vertexA}, true, "bona"});
+ } else if (touchers[i].type_ == TouchingPoint::A_ON_B) {
+ //TODO testme
+ segment_t a1 = {vertexA, prevA};
+ segment_t a2 = {vertexA, nextA};
+ segment_t b1 = {vertexA, vertexB};
+ segment_t b2 = {vertexA, prevB};
+#ifdef NFP_DEBUG
+ write_svg("touchersA" + std::to_string(i) + ".svg", {a1,a2,b1,b2});
+#endif
+ touchEdges.push_back({a1, b1});
+ touchEdges.push_back({a2, b1});
+ touchEdges.push_back({a1, b2});
+ touchEdges.push_back({a2, b2});
+ potentialVectors.push_back({vertexA - vertexB, {vertexA, vertexB}, false, "aonb"});
+ }
+ }
+
+ //discard immediately intersecting translations
+ std::vector<TranslationVector> vectors;
+ for(const auto& v : potentialVectors) {
+ bool discarded = false;
+ for(const auto& sp : touchEdges) {
+ point_t normEdge = normalize(v.edge_.second - v.edge_.first);
+ point_t normFirst = normalize(sp.first.second - sp.first.first);
+ point_t normSecond = normalize(sp.second.second - sp.second.first);
+
+ Alignment a1 = get_alignment({{0,0},normEdge}, normFirst);
+ Alignment a2 = get_alignment({{0,0},normEdge}, normSecond);
+
+ if(a1 == a2 && a1 != ON) {
+ long double df = get_inner_angle({0,0},normEdge, normFirst);
+ long double ds = get_inner_angle({0,0},normEdge, normSecond);
+
+ point_t normIn = normalize(v.edge_.second - v.edge_.first);
+ if (equals(df, ds)) {
+ TranslationVector trimmed = trimVector(ringA,ringB, v);
+ polygon_t::ring_type translated;
+ trans::translate_transformer<coord_t, 2, 2> translate(trimmed.vector_.x_, trimmed.vector_.y_);
+ boost::geometry::transform(ringB, translated, translate);
+ if (!(bg::intersects(translated, ringA) && !bg::overlaps(translated, ringA) && !bg::covered_by(translated, ringA) && !bg::covered_by(ringA, translated))) {
+ discarded = true;
+ break;
+ }
+ } else {
+
+ if (normIn == normalize(v.vector_)) {
+ if (larger(ds, df)) {
+ discarded = true;
+ break;
+ }
+ } else {
+ if (smaller(ds, df)) {
+ discarded = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(!discarded)
+ vectors.push_back(v);
+ }
+ return vectors;
+}
+
+bool find(const std::vector<TranslationVector>& h, const TranslationVector& tv) {
+ for(const auto& htv : h) {
+ if(htv.vector_ == tv.vector_)
+ return true;
+ }
+ return false;
+}
+
+TranslationVector getLongest(const std::vector<TranslationVector>& tvs) {
+ coord_t len;
+ coord_t maxLen = MIN_COORD;
+ TranslationVector longest;
+ longest.vector_ = INVALID_POINT;
+
+ for(auto& tv : tvs) {
+ len = bg::length(segment_t{{0,0},tv.vector_});
+ if(larger(len, maxLen)) {
+ maxLen = len;
+ longest = tv;
+ }
+ }
+ return longest;
+}
+
+TranslationVector selectNextTranslationVector(const polygon_t& pA, const polygon_t::ring_type& rA, const polygon_t::ring_type& rB, const std::vector<TranslationVector>& tvs, const std::vector<TranslationVector>& history) {
+ if(!history.empty()) {
+ TranslationVector last = history.back();
+ std::vector<TranslationVector> historyCopy = history;
+ if(historyCopy.size() >= 2) {
+ historyCopy.erase(historyCopy.end() - 1);
+ historyCopy.erase(historyCopy.end() - 1);
+ if(historyCopy.size() > 4) {
+ historyCopy.erase(historyCopy.begin(), historyCopy.end() - 4);
+ }
+
+ } else {
+ historyCopy.clear();
+ }
+ DEBUG_MSG("last", last);
+
+ psize_t laterI = std::numeric_limits<psize_t>::max();
+ point_t previous = rA[0];
+ point_t next;
+
+ if(last.fromA_) {
+ for (psize_t i = 1; i < rA.size() + 1; ++i) {
+ if (i >= rA.size())
+ next = rA[i % rA.size()];
+ else
+ next = rA[i];
+
+ segment_t candidate( previous, next );
+ if(candidate == last.edge_) {
+ laterI = i;
+ break;
+ }
+ previous = next;
+ }
+
+ if (laterI == std::numeric_limits<psize_t>::max()) {
+ point_t later;
+ if (last.vector_ == (last.edge_.second - last.edge_.first)) {
+ later = last.edge_.second;
+ } else {
+ later = last.edge_.first;
+ }
+
+ laterI = find_point(rA, later);
+ }
+ } else {
+ point_t later;
+ if (last.vector_ == (last.edge_.second - last.edge_.first)) {
+ later = last.edge_.second;
+ } else {
+ later = last.edge_.first;
+ }
+
+ laterI = find_point(rA, later);
+ }
+
+ if (laterI == std::numeric_limits<psize_t>::max()) {
+ throw std::runtime_error(
+ "Internal error: Can't find later point of last edge");
+ }
+
+ std::vector<segment_t> viableEdges;
+ previous = rA[laterI];
+ for(psize_t i = laterI + 1; i < rA.size() + laterI + 1; ++i) {
+ if(i >= rA.size())
+ next = rA[i % rA.size()];
+ else
+ next = rA[i];
+
+ viableEdges.push_back({previous, next});
+ previous = next;
+ }
+
+// auto rng = std::default_random_engine {};
+// std::shuffle(std::begin(viableEdges), std::end(viableEdges), rng);
+
+ //search with consulting the history to prevent oscillation
+ std::vector<TranslationVector> viableTrans;
+ for(const auto& ve: viableEdges) {
+ for(const auto& tv : tvs) {
+ if((tv.fromA_ && (normalize(tv.vector_) == normalize(ve.second - ve.first))) && (tv.edge_ != last.edge_ || tv.vector_.x_ != -last.vector_.x_ || tv.vector_.y_ != -last.vector_.y_) && !find(historyCopy, tv)) {
+ viableTrans.push_back(tv);
+ }
+ }
+ for (const auto& tv : tvs) {
+ if (!tv.fromA_) {
+ point_t later;
+ if (tv.vector_ == (tv.edge_.second - tv.edge_.first) && (tv.edge_ != last.edge_ || tv.vector_.x_ != -last.vector_.x_ || tv.vector_.y_ != -last.vector_.y_) && !find(historyCopy, tv)) {
+ later = tv.edge_.second;
+ } else if (tv.vector_ == (tv.edge_.first - tv.edge_.second)) {
+ later = tv.edge_.first;
+ } else
+ continue;
+
+ if (later == ve.first || later == ve.second) {
+ viableTrans.push_back(tv);
+ }
+ }
+ }
+ }
+
+ if(!viableTrans.empty())
+ return getLongest(viableTrans);
+
+ //search again without the history
+ for(const auto& ve: viableEdges) {
+ for(const auto& tv : tvs) {
+ if((tv.fromA_ && (normalize(tv.vector_) == normalize(ve.second - ve.first))) && (tv.edge_ != last.edge_ || tv.vector_.x_ != -last.vector_.x_ || tv.vector_.y_ != -last.vector_.y_)) {
+ viableTrans.push_back(tv);
+ }
+ }
+ for (const auto& tv : tvs) {
+ if (!tv.fromA_) {
+ point_t later;
+ if (tv.vector_ == (tv.edge_.second - tv.edge_.first) && (tv.edge_ != last.edge_ || tv.vector_.x_ != -last.vector_.x_ || tv.vector_.y_ != -last.vector_.y_)) {
+ later = tv.edge_.second;
+ } else if (tv.vector_ == (tv.edge_.first - tv.edge_.second)) {
+ later = tv.edge_.first;
+ } else
+ continue;
+
+ if (later == ve.first || later == ve.second) {
+ viableTrans.push_back(tv);
+ }
+ }
+ }
+ }
+ if(!viableTrans.empty())
+ return getLongest(viableTrans);
+
+ /*
+ //search again without the history and without checking last edge
+ for(const auto& ve: viableEdges) {
+ for(const auto& tv : tvs) {
+ if((tv.fromA_ && (normalize(tv.vector_) == normalize(ve.second - ve.first)))) {
+ return tv;
+ }
+ }
+ for (const auto& tv : tvs) {
+ if (!tv.fromA_) {
+ point_t later;
+ if (tv.vector_ == (tv.edge_.second - tv.edge_.first)) {
+ later = tv.edge_.second;
+ } else if (tv.vector_ == (tv.edge_.first - tv.edge_.second)) {
+ later = tv.edge_.first;
+ } else
+ continue;
+
+ if (later == ve.first || later == ve.second) {
+ return tv;
+ }
+ }
+ }
+ }*/
+
+ if(tvs.size() == 1)
+ return *tvs.begin();
+
+ TranslationVector tv;
+ tv.vector_ = INVALID_POINT;
+ return tv;
+ } else {
+ return getLongest(tvs);
+ }
+}
+
+bool inNfp(const point_t& pt, const nfp_t& nfp) {
+ for(const auto& r : nfp) {
+ if(bg::touches(pt, r))
+ return true;
+ }
+
+ return false;
+}
+
+enum SearchStartResult {
+ FIT,
+ FOUND,
+ NOT_FOUND
+};
+
+SearchStartResult searchStartTranslation(polygon_t::ring_type& rA, const polygon_t::ring_type& rB, const nfp_t& nfp,const bool& inside, point_t& result) {
+ for(psize_t i = 0; i < rA.size() - 1; i++) {
+ psize_t index;
+ if (i >= rA.size())
+ index = i % rA.size() + 1;
+ else
+ index = i;
+
+ auto& ptA = rA[index];
+
+ if(ptA.marked_)
+ continue;
+
+ ptA.marked_ = true;
+
+ for(const auto& ptB: rB) {
+ point_t testTranslation = ptA - ptB;
+ polygon_t::ring_type translated;
+ boost::geometry::transform(rB, translated, trans::translate_transformer<coord_t, 2, 2>(testTranslation.x_, testTranslation.y_));
+
+ //check if the translated rB is identical to rA
+ bool identical = false;
+ for(const auto& ptT: translated) {
+ identical = false;
+ for(const auto& ptA: rA) {
+ if(ptT == ptA) {
+ identical = true;
+ break;
+ }
+ }
+ if(!identical)
+ break;
+ }
+
+ if(identical) {
+ result = testTranslation;
+ return FIT;
+ }
+
+ bool bInside = false;
+ for(const auto& ptT: translated) {
+ if(bg::within(ptT, rA)) {
+ bInside = true;
+ break;
+ } else if(!bg::touches(ptT, rA)) {
+ bInside = false;
+ break;
+ }
+ }
+
+ if(((bInside && inside) || (!bInside && !inside)) && (!bg::overlaps(translated, rA) && !bg::covered_by(translated, rA) && !bg::covered_by(rA, translated)) && !inNfp(translated.front(), nfp)){
+ result = testTranslation;
+ return FOUND;
+ }
+
+ point_t nextPtA = rA[index + 1];
+ TranslationVector slideVector;
+ slideVector.vector_ = nextPtA - ptA;
+ slideVector.edge_ = {ptA, nextPtA};
+ slideVector.fromA_ = true;
+ TranslationVector trimmed = trimVector(rA, translated, slideVector);
+ polygon_t::ring_type translated2;
+ trans::translate_transformer<coord_t, 2, 2> trans(trimmed.vector_.x_, trimmed.vector_.y_);
+ boost::geometry::transform(translated, translated2, trans);
+
+ //check if the translated rB is identical to rA
+ identical = false;
+ for(const auto& ptT: translated) {
+ identical = false;
+ for(const auto& ptA: rA) {
+ if(ptT == ptA) {
+ identical = true;
+ break;
+ }
+ }
+ if(!identical)
+ break;
+ }
+
+ if(identical) {
+ result = trimmed.vector_ + testTranslation;
+ return FIT;
+ }
+
+ bInside = false;
+ for(const auto& ptT: translated2) {
+ if(bg::within(ptT, rA)) {
+ bInside = true;
+ break;
+ } else if(!bg::touches(ptT, rA)) {
+ bInside = false;
+ break;
+ }
+ }
+
+ if(((bInside && inside) || (!bInside && !inside)) && (!bg::overlaps(translated2, rA) && !bg::covered_by(translated2, rA) && !bg::covered_by(rA, translated2)) && !inNfp(translated2.front(), nfp)){
+ result = trimmed.vector_ + testTranslation;
+ return FOUND;
+ }
+ }
+ }
+ return NOT_FOUND;
+}
+
+enum SlideResult {
+ LOOP,
+ NO_LOOP,
+ NO_TRANSLATION
+};
+
+SlideResult slide(polygon_t& pA, polygon_t::ring_type& rA, polygon_t::ring_type& rB, nfp_t& nfp, const point_t& transB, bool inside) {
+ polygon_t::ring_type rifsB;
+ boost::geometry::transform(rB, rifsB, trans::translate_transformer<coord_t, 2, 2>(transB.x_, transB.y_));
+ rB = std::move(rifsB);
+
+#ifdef NFP_DEBUG
+ write_svg("ifs.svg", pA, rB);
+#endif
+
+ bool startAvailable = true;
+ psize_t cnt = 0;
+ point_t referenceStart = rB.front();
+ std::vector<TranslationVector> history;
+
+ //generate the nfp for the ring
+ while(startAvailable) {
+ DEBUG_VAL(cnt);
+ //use first point of rB as reference
+ nfp.back().push_back(rB.front());
+ if(cnt == 15)
+ std::cerr << "";
+
+ std::vector<TouchingPoint> touchers = findTouchingPoints(rA, rB);
+
+#ifdef NFP_DEBUG
+ DEBUG_MSG("touchers", touchers.size());
+ for(auto t : touchers) {
+ DEBUG_VAL(t.type_);
+ }
+#endif
+ if(touchers.empty()) {
+ throw std::runtime_error("Internal error: No touching points found");
+ }
+ std::vector<TranslationVector> transVectors = findFeasibleTranslationVectors(rA, rB, touchers);
+
+#ifdef NFP_DEBUG
+ DEBUG_MSG("collected vectors", transVectors.size());
+ for(auto pt : transVectors) {
+ DEBUG_VAL(pt);
+ }
+#endif
+
+ if(transVectors.empty()) {
+ return NO_LOOP;
+ }
+
+ TranslationVector next = selectNextTranslationVector(pA, rA, rB, transVectors, history);
+
+ if(next.vector_ == INVALID_POINT)
+ return NO_TRANSLATION;
+
+ DEBUG_MSG("next", next);
+
+ TranslationVector trimmed = trimVector(rA, rB, next);
+ DEBUG_MSG("trimmed", trimmed);
+
+ history.push_back(next);
+
+ polygon_t::ring_type nextRB;
+ boost::geometry::transform(rB, nextRB, trans::translate_transformer<coord_t, 2, 2>(trimmed.vector_.x_, trimmed.vector_.y_));
+ rB = std::move(nextRB);
+
+#ifdef NFP_DEBUG
+ write_svg("next" + std::to_string(cnt) + ".svg", pA,rB);
+#endif
+
+ ++cnt;
+ if(referenceStart == rB.front() || (inside && bg::touches(rB.front(), nfp.front()))) {
+ startAvailable = false;
+ }
+ }
+ return LOOP;
+}
+
+void removeCoLinear(polygon_t::ring_type& r) {
+ assert(r.size() > 2);
+ psize_t nextI;
+ psize_t prevI = 0;
+ segment_t segment(r[r.size() - 2], r[0]);
+ polygon_t::ring_type newR;
+
+ for (psize_t i = 1; i < r.size() + 1; ++i) {
+ if (i >= r.size())
+ nextI = i % r.size() + 1;
+ else
+ nextI = i;
+
+ if (get_alignment(segment, r[nextI]) != ON) {
+ newR.push_back(r[prevI]);
+ }
+ segment = {segment.second, r[nextI]};
+ prevI = nextI;
+ }
+
+ r = newR;
+}
+
+void removeCoLinear(polygon_t& p) {
+ removeCoLinear(p.outer());
+ for (auto& r : p.inners())
+ removeCoLinear(r);
+}
+
+nfp_t generateNFP(polygon_t& pA, polygon_t& pB, const bool checkValidity = true) {
+ removeCoLinear(pA);
+ removeCoLinear(pB);
+
+ if(checkValidity) {
+ std::string reason;
+ if(!bg::is_valid(pA, reason))
+ throw std::runtime_error("Polygon A is invalid: " + reason);
+
+ if(!bg::is_valid(pB, reason))
+ throw std::runtime_error("Polygon B is invalid: " + reason);
+ }
+
+ nfp_t nfp;
+
+#ifdef NFP_DEBUG
+ write_svg("start.svg", {pA, pB});
+#endif
+
+ DEBUG_VAL(bg::wkt(pA))
+ DEBUG_VAL(bg::wkt(pB));
+
+ //prevent double vertex connections at start because we might come back the same way we go which would end the nfp prematurely
+ std::vector<psize_t> ptyaminI = find_minimum_y(pA);
+ std::vector<psize_t> ptybmaxI = find_maximum_y(pB);
+
+ point_t pAstart;
+ point_t pBstart;
+
+ if(ptyaminI.size() > 1 || ptybmaxI.size() > 1) {
+ //find right-most of A and left-most of B to prevent double connection at start
+ coord_t maxX = MIN_COORD;
+ psize_t iRightMost = 0;
+ for(psize_t& ia : ptyaminI) {
+ const point_t& candidateA = pA.outer()[ia];
+ if(larger(candidateA.x_, maxX)) {
+ maxX = candidateA.x_;
+ iRightMost = ia;
+ }
+ }
+
+ coord_t minX = MAX_COORD;
+ psize_t iLeftMost = 0;
+ for(psize_t& ib : ptybmaxI) {
+ const point_t& candidateB = pB.outer()[ib];
+ if(smaller(candidateB.x_, minX)) {
+ minX = candidateB.x_;
+ iLeftMost = ib;
+ }
+ }
+ pAstart = pA.outer()[iRightMost];
+ pBstart = pB.outer()[iLeftMost];
+ } else {
+ pAstart = pA.outer()[ptyaminI.front()];
+ pBstart = pB.outer()[ptybmaxI.front()];
+ }
+
+ nfp.push_back({});
+ point_t transB = {pAstart - pBstart};
+
+ if(slide(pA, pA.outer(), pB.outer(), nfp, transB, false) != LOOP) {
+ throw std::runtime_error("Unable to complete outer nfp loop");
+ }
+
+ DEBUG_VAL("##### outer #####");
+ point_t startTrans;
+ while(true) {
+ SearchStartResult res = searchStartTranslation(pA.outer(), pB.outer(), nfp, false, startTrans);
+ if(res == FOUND) {
+ nfp.push_back({});
+ DEBUG_VAL("##### interlock start #####")
+ polygon_t::ring_type rifsB;
+ boost::geometry::transform(pB.outer(), rifsB, trans::translate_transformer<coord_t, 2, 2>(startTrans.x_, startTrans.y_));
+ if(inNfp(rifsB.front(), nfp)) {
+ continue;
+ }
+ SlideResult sres = slide(pA, pA.outer(), pB.outer(), nfp, startTrans, true);
+ if(sres != LOOP) {
+ if(sres == NO_TRANSLATION) {
+ //no initial slide found -> jiggsaw
+ if(!inNfp(pB.outer().front(),nfp)) {
+ nfp.push_back({});
+ nfp.back().push_back(pB.outer().front());
+ }
+ }
+ }
+ DEBUG_VAL("##### interlock end #####");
+ } else if(res == FIT) {
+ point_t reference = pB.outer().front();
+ point_t translated;
+ trans::translate_transformer<coord_t, 2, 2> translate(startTrans.x_, startTrans.y_);
+ boost::geometry::transform(reference, translated, translate);
+ if(!inNfp(translated,nfp)) {
+ nfp.push_back({});
+ nfp.back().push_back(translated);
+ }
+ break;
+ } else
+ break;
+ }
+
+
+ for(auto& rA : pA.inners()) {
+ while(true) {
+ SearchStartResult res = searchStartTranslation(rA, pB.outer(), nfp, true, startTrans);
+ if(res == FOUND) {
+ nfp.push_back({});
+ DEBUG_VAL("##### hole start #####");
+ slide(pA, rA, pB.outer(), nfp, startTrans, true);
+ DEBUG_VAL("##### hole end #####");
+ } else if(res == FIT) {
+ point_t reference = pB.outer().front();
+ point_t translated;
+ trans::translate_transformer<coord_t, 2, 2> translate(startTrans.x_, startTrans.y_);
+ boost::geometry::transform(reference, translated, translate);
+ if(!inNfp(translated,nfp)) {
+ nfp.push_back({});
+ nfp.back().push_back(translated);
+ }
+ break;
+ } else
+ break;
+ }
+ }
+
+#ifdef NFP_DEBUG
+ write_svg("nfp.svg", {pA,pB}, nfp);
+#endif
+
+ return nfp;
+}
+}
+#endif
diff --git a/xs/src/libnest2d/tools/nfp_svgnest.hpp b/xs/src/libnest2d/tools/nfp_svgnest.hpp
new file mode 100644
index 000000000..ac5700c10
--- /dev/null
+++ b/xs/src/libnest2d/tools/nfp_svgnest.hpp
@@ -0,0 +1,1018 @@
+#ifndef NFP_SVGNEST_HPP
+#define NFP_SVGNEST_HPP
+
+#include <limits>
+#include <unordered_map>
+
+#include <libnest2d/geometry_traits_nfp.hpp>
+
+namespace libnest2d {
+
+namespace __svgnest {
+
+using std::sqrt;
+using std::min;
+using std::max;
+using std::abs;
+using std::isnan;
+
+//template<class Coord> struct _Scale {
+// static const BP2D_CONSTEXPR long long Value = 1000000;
+//};
+
+template<class S> struct _alg {
+ using Contour = TContour<S>;
+ using Point = TPoint<S>;
+ using iCoord = TCoord<Point>;
+ using Coord = double;
+ using Shapes = nfp::Shapes<S>;
+
+ static const Coord TOL;
+
+#define dNAN std::nan("")
+
+ struct Vector {
+ Coord x = 0.0, y = 0.0;
+ bool marked = false;
+ Vector() = default;
+ Vector(Coord X, Coord Y): x(X), y(Y) {}
+ Vector(const Point& p): x(Coord(getX(p))), y(Coord(getY(p))) {}
+ operator Point() const { return {iCoord(x), iCoord(y)}; }
+ Vector& operator=(const Point& p) {
+ x = getX(p), y = getY(p); return *this;
+ }
+ bool operator!=(const Vector& v) const {
+ return v.x != x || v.y != y;
+ }
+ Vector(std::initializer_list<Coord> il):
+ x(*il.begin()), y(*std::next(il.begin())) {}
+ };
+
+ static inline Coord x(const Point& p) { return Coord(getX(p)); }
+ static inline Coord y(const Point& p) { return Coord(getY(p)); }
+
+ static inline Coord x(const Vector& p) { return p.x; }
+ static inline Coord y(const Vector& p) { return p.y; }
+
+ class Cntr {
+ std::vector<Vector> v_;
+ public:
+ Cntr(const Contour& c) {
+ v_.reserve(c.size());
+ std::transform(c.begin(), c.end(), std::back_inserter(v_),
+ [](const Point& p) {
+ return Vector(double(x(p)) / 1e6, double(y(p)) / 1e6);
+ });
+ std::reverse(v_.begin(), v_.end());
+ v_.pop_back();
+ }
+ Cntr() = default;
+
+ Coord offsetx = 0;
+ Coord offsety = 0;
+ size_t size() const { return v_.size(); }
+ bool empty() const { return v_.empty(); }
+ typename std::vector<Vector>::const_iterator cbegin() const { return v_.cbegin(); }
+ typename std::vector<Vector>::const_iterator cend() const { return v_.cend(); }
+ typename std::vector<Vector>::iterator begin() { return v_.begin(); }
+ typename std::vector<Vector>::iterator end() { return v_.end(); }
+ Vector& operator[](size_t idx) { return v_[idx]; }
+ const Vector& operator[](size_t idx) const { return v_[idx]; }
+ template<class...Args>
+ void emplace_back(Args&&...args) {
+ v_.emplace_back(std::forward<Args>(args)...);
+ }
+ template<class...Args>
+ void push(Args&&...args) {
+ v_.emplace_back(std::forward<Args>(args)...);
+ }
+ void clear() { v_.clear(); }
+
+ operator Contour() const {
+ Contour cnt;
+ cnt.reserve(v_.size() + 1);
+ std::transform(v_.begin(), v_.end(), std::back_inserter(cnt),
+ [](const Vector& vertex) {
+ return Point(iCoord(vertex.x) * 1000000, iCoord(vertex.y) * 1000000);
+ });
+ if(!cnt.empty()) cnt.emplace_back(cnt.front());
+ S sh = shapelike::create<S>(cnt);
+
+// std::reverse(cnt.begin(), cnt.end());
+ return shapelike::getContour(sh);
+ }
+ };
+
+ inline static bool _almostEqual(Coord a, Coord b,
+ Coord tolerance = TOL)
+ {
+ return std::abs(a - b) < tolerance;
+ }
+
+ // returns true if p lies on the line segment defined by AB,
+ // but not at any endpoints may need work!
+ static bool _onSegment(const Vector& A, const Vector& B, const Vector& p) {
+
+ // vertical line
+ if(_almostEqual(A.x, B.x) && _almostEqual(p.x, A.x)) {
+ if(!_almostEqual(p.y, B.y) && !_almostEqual(p.y, A.y) &&
+ p.y < max(B.y, A.y) && p.y > min(B.y, A.y)){
+ return true;
+ }
+ else{
+ return false;
+ }
+ }
+
+ // horizontal line
+ if(_almostEqual(A.y, B.y) && _almostEqual(p.y, A.y)){
+ if(!_almostEqual(p.x, B.x) && !_almostEqual(p.x, A.x) &&
+ p.x < max(B.x, A.x) && p.x > min(B.x, A.x)){
+ return true;
+ }
+ else{
+ return false;
+ }
+ }
+
+ //range check
+ if((p.x < A.x && p.x < B.x) || (p.x > A.x && p.x > B.x) ||
+ (p.y < A.y && p.y < B.y) || (p.y > A.y && p.y > B.y))
+ return false;
+
+ // exclude end points
+ if((_almostEqual(p.x, A.x) && _almostEqual(p.y, A.y)) ||
+ (_almostEqual(p.x, B.x) && _almostEqual(p.y, B.y)))
+ return false;
+
+
+ double cross = (p.y - A.y) * (B.x - A.x) - (p.x - A.x) * (B.y - A.y);
+
+ if(abs(cross) > TOL) return false;
+
+ double dot = (p.x - A.x) * (B.x - A.x) + (p.y - A.y)*(B.y - A.y);
+
+ if(dot < 0 || _almostEqual(dot, 0)) return false;
+
+ double len2 = (B.x - A.x)*(B.x - A.x) + (B.y - A.y)*(B.y - A.y);
+
+ if(dot > len2 || _almostEqual(dot, len2)) return false;
+
+ return true;
+ }
+
+ // return true if point is in the polygon, false if outside, and null if exactly on a point or edge
+ static int pointInPolygon(const Vector& point, const Cntr& polygon) {
+ if(polygon.size() < 3){
+ return 0;
+ }
+
+ bool inside = false;
+ Coord offsetx = polygon.offsetx;
+ Coord offsety = polygon.offsety;
+
+ for (size_t i = 0, j = polygon.size() - 1; i < polygon.size(); j=i++) {
+ auto xi = polygon[i].x + offsetx;
+ auto yi = polygon[i].y + offsety;
+ auto xj = polygon[j].x + offsetx;
+ auto yj = polygon[j].y + offsety;
+
+ if(_almostEqual(xi, point.x) && _almostEqual(yi, point.y)){
+ return 0; // no result
+ }
+
+ if(_onSegment({xi, yi}, {xj, yj}, point)){
+ return 0; // exactly on the segment
+ }
+
+ if(_almostEqual(xi, xj) && _almostEqual(yi, yj)){ // ignore very small lines
+ continue;
+ }
+
+ bool intersect = ((yi > point.y) != (yj > point.y)) &&
+ (point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi);
+ if (intersect) inside = !inside;
+ }
+
+ return inside? 1 : -1;
+ }
+
+ static bool intersect(const Cntr& A, const Cntr& B){
+ Contour a = A, b = B;
+ return shapelike::intersects(shapelike::create<S>(a), shapelike::create<S>(b));
+ }
+
+ static Vector _normalizeVector(const Vector& v) {
+ if(_almostEqual(v.x*v.x + v.y*v.y, Coord(1))){
+ return Point(v); // given vector was already a unit vector
+ }
+ auto len = sqrt(v.x*v.x + v.y*v.y);
+ auto inverse = 1/len;
+
+ return { Coord(v.x*inverse), Coord(v.y*inverse) };
+ }
+
+ static double pointDistance( const Vector& p,
+ const Vector& s1,
+ const Vector& s2,
+ Vector normal,
+ bool infinite = false)
+ {
+ normal = _normalizeVector(normal);
+
+ Vector dir = {
+ normal.y,
+ -normal.x
+ };
+
+ auto pdot = p.x*dir.x + p.y*dir.y;
+ auto s1dot = s1.x*dir.x + s1.y*dir.y;
+ auto s2dot = s2.x*dir.x + s2.y*dir.y;
+
+ auto pdotnorm = p.x*normal.x + p.y*normal.y;
+ auto s1dotnorm = s1.x*normal.x + s1.y*normal.y;
+ auto s2dotnorm = s2.x*normal.x + s2.y*normal.y;
+
+ if(!infinite){
+ if (((pdot<s1dot || _almostEqual(pdot, s1dot)) &&
+ (pdot<s2dot || _almostEqual(pdot, s2dot))) ||
+ ((pdot>s1dot || _almostEqual(pdot, s1dot)) &&
+ (pdot>s2dot || _almostEqual(pdot, s2dot))))
+ {
+ // dot doesn't collide with segment,
+ // or lies directly on the vertex
+ return dNAN;
+ }
+ if ((_almostEqual(pdot, s1dot) && _almostEqual(pdot, s2dot)) &&
+ (pdotnorm>s1dotnorm && pdotnorm>s2dotnorm))
+ {
+ return min(pdotnorm - s1dotnorm, pdotnorm - s2dotnorm);
+ }
+ if ((_almostEqual(pdot, s1dot) && _almostEqual(pdot, s2dot)) &&
+ (pdotnorm<s1dotnorm && pdotnorm<s2dotnorm)){
+ return -min(s1dotnorm-pdotnorm, s2dotnorm-pdotnorm);
+ }
+ }
+
+ return -(pdotnorm - s1dotnorm + (s1dotnorm - s2dotnorm)*(s1dot - pdot)
+ / double(s1dot - s2dot));
+ }
+
+ static double segmentDistance( const Vector& A,
+ const Vector& B,
+ const Vector& E,
+ const Vector& F,
+ Vector direction)
+ {
+ Vector normal = {
+ direction.y,
+ -direction.x
+ };
+
+ Vector reverse = {
+ -direction.x,
+ -direction.y
+ };
+
+ auto dotA = A.x*normal.x + A.y*normal.y;
+ auto dotB = B.x*normal.x + B.y*normal.y;
+ auto dotE = E.x*normal.x + E.y*normal.y;
+ auto dotF = F.x*normal.x + F.y*normal.y;
+
+ auto crossA = A.x*direction.x + A.y*direction.y;
+ auto crossB = B.x*direction.x + B.y*direction.y;
+ auto crossE = E.x*direction.x + E.y*direction.y;
+ auto crossF = F.x*direction.x + F.y*direction.y;
+
+// auto crossABmin = min(crossA, crossB);
+// auto crossABmax = max(crossA, crossB);
+
+// auto crossEFmax = max(crossE, crossF);
+// auto crossEFmin = min(crossE, crossF);
+
+ auto ABmin = min(dotA, dotB);
+ auto ABmax = max(dotA, dotB);
+
+ auto EFmax = max(dotE, dotF);
+ auto EFmin = min(dotE, dotF);
+
+ // segments that will merely touch at one point
+ if(_almostEqual(ABmax, EFmin, TOL) || _almostEqual(ABmin, EFmax,TOL)) {
+ return dNAN;
+ }
+ // segments miss eachother completely
+ if(ABmax < EFmin || ABmin > EFmax){
+ return dNAN;
+ }
+
+ double overlap = 0;
+
+ if((ABmax > EFmax && ABmin < EFmin) || (EFmax > ABmax && EFmin < ABmin))
+ {
+ overlap = 1;
+ }
+ else{
+ auto minMax = min(ABmax, EFmax);
+ auto maxMin = max(ABmin, EFmin);
+
+ auto maxMax = max(ABmax, EFmax);
+ auto minMin = min(ABmin, EFmin);
+
+ overlap = (minMax-maxMin)/(maxMax-minMin);
+ }
+
+ auto crossABE = (E.y - A.y) * (B.x - A.x) - (E.x - A.x) * (B.y - A.y);
+ auto crossABF = (F.y - A.y) * (B.x - A.x) - (F.x - A.x) * (B.y - A.y);
+
+ // lines are colinear
+ if(_almostEqual(crossABE,0) && _almostEqual(crossABF,0)){
+
+ Vector ABnorm = {B.y-A.y, A.x-B.x};
+ Vector EFnorm = {F.y-E.y, E.x-F.x};
+
+ auto ABnormlength = sqrt(ABnorm.x*ABnorm.x + ABnorm.y*ABnorm.y);
+ ABnorm.x /= ABnormlength;
+ ABnorm.y /= ABnormlength;
+
+ auto EFnormlength = sqrt(EFnorm.x*EFnorm.x + EFnorm.y*EFnorm.y);
+ EFnorm.x /= EFnormlength;
+ EFnorm.y /= EFnormlength;
+
+ // segment normals must point in opposite directions
+ if(abs(ABnorm.y * EFnorm.x - ABnorm.x * EFnorm.y) < TOL &&
+ ABnorm.y * EFnorm.y + ABnorm.x * EFnorm.x < 0){
+ // normal of AB segment must point in same direction as
+ // given direction vector
+ auto normdot = ABnorm.y * direction.y + ABnorm.x * direction.x;
+ // the segments merely slide along eachother
+ if(_almostEqual(normdot,0, TOL)){
+ return dNAN;
+ }
+ if(normdot < 0){
+ return 0.0;
+ }
+ }
+ return dNAN;
+ }
+
+ std::vector<double> distances; distances.reserve(10);
+
+ // coincident points
+ if(_almostEqual(dotA, dotE)){
+ distances.emplace_back(crossA-crossE);
+ }
+ else if(_almostEqual(dotA, dotF)){
+ distances.emplace_back(crossA-crossF);
+ }
+ else if(dotA > EFmin && dotA < EFmax){
+ auto d = pointDistance(A,E,F,reverse);
+ if(!isnan(d) && _almostEqual(d, 0))
+ { // A currently touches EF, but AB is moving away from EF
+ auto dB = pointDistance(B,E,F,reverse,true);
+ if(dB < 0 || _almostEqual(dB*overlap,0)){
+ d = dNAN;
+ }
+ }
+ if(!isnan(d)){
+ distances.emplace_back(d);
+ }
+ }
+
+ if(_almostEqual(dotB, dotE)){
+ distances.emplace_back(crossB-crossE);
+ }
+ else if(_almostEqual(dotB, dotF)){
+ distances.emplace_back(crossB-crossF);
+ }
+ else if(dotB > EFmin && dotB < EFmax){
+ auto d = pointDistance(B,E,F,reverse);
+
+ if(!isnan(d) && _almostEqual(d, 0))
+ { // crossA>crossB A currently touches EF, but AB is moving away from EF
+ double dA = pointDistance(A,E,F,reverse,true);
+ if(dA < 0 || _almostEqual(dA*overlap,0)){
+ d = dNAN;
+ }
+ }
+ if(!isnan(d)){
+ distances.emplace_back(d);
+ }
+ }
+
+ if(dotE > ABmin && dotE < ABmax){
+ auto d = pointDistance(E,A,B,direction);
+ if(!isnan(d) && _almostEqual(d, 0))
+ { // crossF<crossE A currently touches EF, but AB is moving away from EF
+ double dF = pointDistance(F,A,B,direction, true);
+ if(dF < 0 || _almostEqual(dF*overlap,0)){
+ d = dNAN;
+ }
+ }
+ if(!isnan(d)){
+ distances.emplace_back(d);
+ }
+ }
+
+ if(dotF > ABmin && dotF < ABmax){
+ auto d = pointDistance(F,A,B,direction);
+ if(!isnan(d) && _almostEqual(d, 0))
+ { // && crossE<crossF A currently touches EF,
+ // but AB is moving away from EF
+ double dE = pointDistance(E,A,B,direction, true);
+ if(dE < 0 || _almostEqual(dE*overlap,0)){
+ d = dNAN;
+ }
+ }
+ if(!isnan(d)){
+ distances.emplace_back(d);
+ }
+ }
+
+ if(distances.empty()){
+ return dNAN;
+ }
+
+ return *std::min_element(distances.begin(), distances.end());
+ }
+
+ static double polygonSlideDistance( const Cntr& AA,
+ const Cntr& BB,
+ Vector direction,
+ bool ignoreNegative)
+ {
+// Vector A1, A2, B1, B2;
+ Cntr A = AA;
+ Cntr B = BB;
+
+ Coord Aoffsetx = A.offsetx;
+ Coord Boffsetx = B.offsetx;
+ Coord Aoffsety = A.offsety;
+ Coord Boffsety = B.offsety;
+
+ // close the loop for polygons
+ if(A[0] != A[A.size()-1]){
+ A.emplace_back(AA[0]);
+ }
+
+ if(B[0] != B[B.size()-1]){
+ B.emplace_back(BB[0]);
+ }
+
+ auto& edgeA = A;
+ auto& edgeB = B;
+
+ double distance = dNAN, d = dNAN;
+
+ Vector dir = _normalizeVector(direction);
+
+// Vector normal = {
+// dir.y,
+// -dir.x
+// };
+
+// Vector reverse = {
+// -dir.x,
+// -dir.y,
+// };
+
+ for(size_t i = 0; i < edgeB.size() - 1; i++){
+ for(size_t j = 0; j < edgeA.size() - 1; j++){
+ Vector A1 = {x(edgeA[j]) + Aoffsetx, y(edgeA[j]) + Aoffsety };
+ Vector A2 = {x(edgeA[j+1]) + Aoffsetx, y(edgeA[j+1]) + Aoffsety};
+ Vector B1 = {x(edgeB[i]) + Boffsetx, y(edgeB[i]) + Boffsety };
+ Vector B2 = {x(edgeB[i+1]) + Boffsetx, y(edgeB[i+1]) + Boffsety};
+
+ if((_almostEqual(A1.x, A2.x) && _almostEqual(A1.y, A2.y)) ||
+ (_almostEqual(B1.x, B2.x) && _almostEqual(B1.y, B2.y))){
+ continue; // ignore extremely small lines
+ }
+
+ d = segmentDistance(A1, A2, B1, B2, dir);
+
+ if(!isnan(d) && (isnan(distance) || d < distance)){
+ if(!ignoreNegative || d > 0 || _almostEqual(d, 0)){
+ distance = d;
+ }
+ }
+ }
+ }
+ return distance;
+ }
+
+ static double polygonProjectionDistance(const Cntr& AA,
+ const Cntr& BB,
+ Vector direction)
+ {
+ Cntr A = AA;
+ Cntr B = BB;
+
+ auto Boffsetx = B.offsetx;
+ auto Boffsety = B.offsety;
+ auto Aoffsetx = A.offsetx;
+ auto Aoffsety = A.offsety;
+
+ // close the loop for polygons
+ if(A[0] != A[A.size()-1]){
+ A.push(A[0]);
+ }
+
+ if(B[0] != B[B.size()-1]){
+ B.push(B[0]);
+ }
+
+ auto& edgeA = A;
+ auto& edgeB = B;
+
+ double distance = dNAN, d;
+// Vector p, s1, s2;
+
+ for(size_t i = 0; i < edgeB.size(); i++) {
+ // the shortest/most negative projection of B onto A
+ double minprojection = dNAN;
+ Vector minp;
+ for(size_t j = 0; j < edgeA.size() - 1; j++){
+ Vector p = {x(edgeB[i]) + Boffsetx, y(edgeB[i]) + Boffsety };
+ Vector s1 = {x(edgeA[j]) + Aoffsetx, y(edgeA[j]) + Aoffsety };
+ Vector s2 = {x(edgeA[j+1]) + Aoffsetx, y(edgeA[j+1]) + Aoffsety };
+
+ if(abs((s2.y-s1.y) * direction.x -
+ (s2.x-s1.x) * direction.y) < TOL) continue;
+
+ // project point, ignore edge boundaries
+ d = pointDistance(p, s1, s2, direction);
+
+ if(!isnan(d) && (isnan(minprojection) || d < minprojection)) {
+ minprojection = d;
+ minp = p;
+ }
+ }
+
+ if(!isnan(minprojection) && (isnan(distance) ||
+ minprojection > distance)){
+ distance = minprojection;
+ }
+ }
+
+ return distance;
+ }
+
+ static std::pair<bool, Vector> searchStartPoint(
+ const Cntr& AA, const Cntr& BB, bool inside, const std::vector<Cntr>& NFP = {})
+ {
+ // clone arrays
+ auto A = AA;
+ auto B = BB;
+
+// // close the loop for polygons
+// if(A[0] != A[A.size()-1]){
+// A.push(A[0]);
+// }
+
+// if(B[0] != B[B.size()-1]){
+// B.push(B[0]);
+// }
+
+ // returns true if point already exists in the given nfp
+ auto inNfp = [](const Vector& p, const std::vector<Cntr>& nfp){
+ if(nfp.empty()){
+ return false;
+ }
+
+ for(size_t i=0; i < nfp.size(); i++){
+ for(size_t j = 0; j< nfp[i].size(); j++){
+ if(_almostEqual(p.x, nfp[i][j].x) &&
+ _almostEqual(p.y, nfp[i][j].y)){
+ return true;
+ }
+ }
+ }
+
+ return false;
+ };
+
+ for(size_t i = 0; i < A.size() - 1; i++){
+ if(!A[i].marked) {
+ A[i].marked = true;
+ for(size_t j = 0; j < B.size(); j++){
+ B.offsetx = A[i].x - B[j].x;
+ B.offsety = A[i].y - B[j].y;
+
+ int Binside = 0;
+ for(size_t k = 0; k < B.size(); k++){
+ int inpoly = pointInPolygon({B[k].x + B.offsetx, B[k].y + B.offsety}, A);
+ if(inpoly != 0){
+ Binside = inpoly;
+ break;
+ }
+ }
+
+ if(Binside == 0){ // A and B are the same
+ return {false, {}};
+ }
+
+ auto startPoint = std::make_pair(true, Vector(B.offsetx, B.offsety));
+ if(((Binside && inside) || (!Binside && !inside)) &&
+ !intersect(A,B) && !inNfp(startPoint.second, NFP)){
+ return startPoint;
+ }
+
+ // slide B along vector
+ auto vx = A[i+1].x - A[i].x;
+ auto vy = A[i+1].y - A[i].y;
+
+ double d1 = polygonProjectionDistance(A,B,{vx, vy});
+ double d2 = polygonProjectionDistance(B,A,{-vx, -vy});
+
+ double d = dNAN;
+
+ // todo: clean this up
+ if(isnan(d1) && isnan(d2)){
+ // nothin
+ }
+ else if(isnan(d1)){
+ d = d2;
+ }
+ else if(isnan(d2)){
+ d = d1;
+ }
+ else{
+ d = min(d1,d2);
+ }
+
+ // only slide until no longer negative
+ // todo: clean this up
+ if(!isnan(d) && !_almostEqual(d,0) && d > 0){
+
+ }
+ else{
+ continue;
+ }
+
+ auto vd2 = vx*vx + vy*vy;
+
+ if(d*d < vd2 && !_almostEqual(d*d, vd2)){
+ auto vd = sqrt(vx*vx + vy*vy);
+ vx *= d/vd;
+ vy *= d/vd;
+ }
+
+ B.offsetx += vx;
+ B.offsety += vy;
+
+ for(size_t k = 0; k < B.size(); k++){
+ int inpoly = pointInPolygon({B[k].x + B.offsetx, B[k].y + B.offsety}, A);
+ if(inpoly != 0){
+ Binside = inpoly;
+ break;
+ }
+ }
+ startPoint = std::make_pair(true, Vector{B.offsetx, B.offsety});
+ if(((Binside && inside) || (!Binside && !inside)) &&
+ !intersect(A,B) && !inNfp(startPoint.second, NFP)){
+ return startPoint;
+ }
+ }
+ }
+ }
+
+ return {false, Vector(0, 0)};
+ }
+
+ static std::vector<Cntr> noFitPolygon(Cntr A,
+ Cntr B,
+ bool inside,
+ bool searchEdges)
+ {
+ if(A.size() < 3 || B.size() < 3) {
+ throw GeometryException(GeomErr::NFP);
+ return {};
+ }
+
+ A.offsetx = 0;
+ A.offsety = 0;
+
+ long i = 0, j = 0;
+
+ auto minA = y(A[0]);
+ long minAindex = 0;
+
+ auto maxB = y(B[0]);
+ long maxBindex = 0;
+
+ for(i = 1; i < A.size(); i++){
+ A[i].marked = false;
+ if(y(A[i]) < minA){
+ minA = y(A[i]);
+ minAindex = i;
+ }
+ }
+
+ for(i = 1; i < B.size(); i++){
+ B[i].marked = false;
+ if(y(B[i]) > maxB){
+ maxB = y(B[i]);
+ maxBindex = i;
+ }
+ }
+
+ std::pair<bool, Vector> startpoint;
+
+ if(!inside){
+ // shift B such that the bottom-most point of B is at the top-most
+ // point of A. This guarantees an initial placement with no
+ // intersections
+ startpoint = { true,
+ { x(A[minAindex]) - x(B[maxBindex]),
+ y(A[minAindex]) - y(B[maxBindex]) }
+ };
+ }
+ else {
+ // no reliable heuristic for inside
+ startpoint = searchStartPoint(A, B, true);
+ }
+
+ std::vector<Cntr> NFPlist;
+
+ struct Touch {
+ int type;
+ long A;
+ long B;
+ Touch(int t, long a, long b): type(t), A(a), B(b) {}
+ };
+
+ while(startpoint.first) {
+
+ B.offsetx = startpoint.second.x;
+ B.offsety = startpoint.second.y;
+
+ // maintain a list of touching points/edges
+ std::vector<Touch> touching;
+
+ struct V {
+ Coord x, y;
+ Vector *start, *end;
+ operator bool() {
+ return start != nullptr && end != nullptr;
+ }
+ operator Vector() const { return {x, y}; }
+ } prevvector = {0, 0, nullptr, nullptr};
+
+ Cntr NFP;
+ NFP.emplace_back(x(B[0]) + B.offsetx, y(B[0]) + B.offsety);
+
+ auto referencex = x(B[0]) + B.offsetx;
+ auto referencey = y(B[0]) + B.offsety;
+ auto startx = referencex;
+ auto starty = referencey;
+ unsigned counter = 0;
+
+ // sanity check, prevent infinite loop
+ while(counter < 10*(A.size() + B.size())){
+ touching.clear();
+
+ // find touching vertices/edges
+ for(i = 0; i < A.size(); i++){
+ long nexti = (i == A.size() - 1) ? 0 : i + 1;
+ for(j = 0; j < B.size(); j++){
+
+ long nextj = (j == B.size() - 1) ? 0 : j + 1;
+
+ if( _almostEqual(A[i].x, B[j].x+B.offsetx) &&
+ _almostEqual(A[i].y, B[j].y+B.offsety))
+ {
+ touching.emplace_back(0, i, j);
+ }
+ else if( _onSegment(
+ A[i], A[nexti],
+ { B[j].x+B.offsetx, B[j].y + B.offsety}) )
+ {
+ touching.emplace_back(1, nexti, j);
+ }
+ else if( _onSegment(
+ {B[j].x+B.offsetx, B[j].y + B.offsety},
+ {B[nextj].x+B.offsetx, B[nextj].y + B.offsety},
+ A[i]) )
+ {
+ touching.emplace_back(2, i, nextj);
+ }
+ }
+ }
+
+ // generate translation vectors from touching vertices/edges
+ std::vector<V> vectors;
+ for(i=0; i < touching.size(); i++){
+ auto& vertexA = A[touching[i].A];
+ vertexA.marked = true;
+
+ // adjacent A vertices
+ auto prevAindex = touching[i].A - 1;
+ auto nextAindex = touching[i].A + 1;
+
+ prevAindex = (prevAindex < 0) ? A.size() - 1 : prevAindex; // loop
+ nextAindex = (nextAindex >= A.size()) ? 0 : nextAindex; // loop
+
+ auto& prevA = A[prevAindex];
+ auto& nextA = A[nextAindex];
+
+ // adjacent B vertices
+ auto& vertexB = B[touching[i].B];
+
+ auto prevBindex = touching[i].B-1;
+ auto nextBindex = touching[i].B+1;
+
+ prevBindex = (prevBindex < 0) ? B.size() - 1 : prevBindex; // loop
+ nextBindex = (nextBindex >= B.size()) ? 0 : nextBindex; // loop
+
+ auto& prevB = B[prevBindex];
+ auto& nextB = B[nextBindex];
+
+ if(touching[i].type == 0){
+
+ V vA1 = {
+ prevA.x - vertexA.x,
+ prevA.y - vertexA.y,
+ &vertexA,
+ &prevA
+ };
+
+ V vA2 = {
+ nextA.x - vertexA.x,
+ nextA.y - vertexA.y,
+ &vertexA,
+ &nextA
+ };
+
+ // B vectors need to be inverted
+ V vB1 = {
+ vertexB.x - prevB.x,
+ vertexB.y - prevB.y,
+ &prevB,
+ &vertexB
+ };
+
+ V vB2 = {
+ vertexB.x - nextB.x,
+ vertexB.y - nextB.y,
+ &nextB,
+ &vertexB
+ };
+
+ vectors.emplace_back(vA1);
+ vectors.emplace_back(vA2);
+ vectors.emplace_back(vB1);
+ vectors.emplace_back(vB2);
+ }
+ else if(touching[i].type == 1){
+ vectors.emplace_back(V{
+ vertexA.x-(vertexB.x+B.offsetx),
+ vertexA.y-(vertexB.y+B.offsety),
+ &prevA,
+ &vertexA
+ });
+
+ vectors.emplace_back(V{
+ prevA.x-(vertexB.x+B.offsetx),
+ prevA.y-(vertexB.y+B.offsety),
+ &vertexA,
+ &prevA
+ });
+ }
+ else if(touching[i].type == 2){
+ vectors.emplace_back(V{
+ vertexA.x-(vertexB.x+B.offsetx),
+ vertexA.y-(vertexB.y+B.offsety),
+ &prevB,
+ &vertexB
+ });
+
+ vectors.emplace_back(V{
+ vertexA.x-(prevB.x+B.offsetx),
+ vertexA.y-(prevB.y+B.offsety),
+ &vertexB,
+ &prevB
+ });
+ }
+ }
+
+ // TODO: there should be a faster way to reject vectors that
+ // will cause immediate intersection. For now just check them all
+
+ V translate = {0, 0, nullptr, nullptr};
+ double maxd = 0;
+
+ for(i = 0; i < vectors.size(); i++) {
+ if(vectors[i].x == 0 && vectors[i].y == 0){
+ continue;
+ }
+
+ // if this vector points us back to where we came from, ignore it.
+ // ie cross product = 0, dot product < 0
+ if(prevvector && vectors[i].y * prevvector.y + vectors[i].x * prevvector.x < 0){
+
+ // compare magnitude with unit vectors
+ double vectorlength = sqrt(vectors[i].x*vectors[i].x+vectors[i].y*vectors[i].y);
+ Vector unitv = {Coord(vectors[i].x/vectorlength),
+ Coord(vectors[i].y/vectorlength)};
+
+ double prevlength = sqrt(prevvector.x*prevvector.x+prevvector.y*prevvector.y);
+ Vector prevunit = { prevvector.x/prevlength, prevvector.y/prevlength};
+
+ // we need to scale down to unit vectors to normalize vector length. Could also just do a tan here
+ if(abs(unitv.y * prevunit.x - unitv.x * prevunit.y) < 0.0001){
+ continue;
+ }
+ }
+
+ V vi = vectors[i];
+ double d = polygonSlideDistance(A, B, vi, true);
+ double vecd2 = vectors[i].x*vectors[i].x + vectors[i].y*vectors[i].y;
+
+ if(isnan(d) || d*d > vecd2){
+ double vecd = sqrt(vectors[i].x*vectors[i].x + vectors[i].y*vectors[i].y);
+ d = vecd;
+ }
+
+ if(!isnan(d) && d > maxd){
+ maxd = d;
+ translate = vectors[i];
+ }
+ }
+
+ if(!translate || _almostEqual(maxd, 0))
+ {
+ // didn't close the loop, something went wrong here
+ NFP.clear();
+ break;
+ }
+
+ translate.start->marked = true;
+ translate.end->marked = true;
+
+ prevvector = translate;
+
+ // trim
+ double vlength2 = translate.x*translate.x + translate.y*translate.y;
+ if(maxd*maxd < vlength2 && !_almostEqual(maxd*maxd, vlength2)){
+ double scale = sqrt((maxd*maxd)/vlength2);
+ translate.x *= scale;
+ translate.y *= scale;
+ }
+
+ referencex += translate.x;
+ referencey += translate.y;
+
+ if(_almostEqual(referencex, startx) &&
+ _almostEqual(referencey, starty)) {
+ // we've made a full loop
+ break;
+ }
+
+ // if A and B start on a touching horizontal line,
+ // the end point may not be the start point
+ bool looped = false;
+ if(NFP.size() > 0) {
+ for(i = 0; i < NFP.size() - 1; i++) {
+ if(_almostEqual(referencex, NFP[i].x) &&
+ _almostEqual(referencey, NFP[i].y)){
+ looped = true;
+ }
+ }
+ }
+
+ if(looped){
+ // we've made a full loop
+ break;
+ }
+
+ NFP.emplace_back(referencex, referencey);
+
+ B.offsetx += translate.x;
+ B.offsety += translate.y;
+
+ counter++;
+ }
+
+ if(NFP.size() > 0){
+ NFPlist.emplace_back(NFP);
+ }
+
+ if(!searchEdges){
+ // only get outer NFP or first inner NFP
+ break;
+ }
+
+ startpoint =
+ searchStartPoint(A, B, inside, NFPlist);
+
+ }
+
+ return NFPlist;
+ }
+};
+
+template<class S> const double _alg<S>::TOL = std::pow(10, -9);
+
+}
+}
+
+#endif // NFP_SVGNEST_HPP
diff --git a/xs/src/libnest2d/tools/nfp_svgnest_glue.hpp b/xs/src/libnest2d/tools/nfp_svgnest_glue.hpp
new file mode 100644
index 000000000..ea1fb4d07
--- /dev/null
+++ b/xs/src/libnest2d/tools/nfp_svgnest_glue.hpp
@@ -0,0 +1,75 @@
+#ifndef NFP_SVGNEST_GLUE_HPP
+#define NFP_SVGNEST_GLUE_HPP
+
+#include "nfp_svgnest.hpp"
+
+#include <libnest2d/clipper_backend/clipper_backend.hpp>
+
+namespace libnest2d {
+
+namespace __svgnest {
+
+//template<> struct _Tol<double> {
+// static const BP2D_CONSTEXPR TCoord<PointImpl> Value = 1000000;
+//};
+
+}
+
+namespace nfp {
+
+using NfpR = NfpResult<PolygonImpl>;
+
+template<> struct NfpImpl<PolygonImpl, NfpLevel::CONVEX_ONLY> {
+ NfpR operator()(const PolygonImpl& sh, const PolygonImpl& cother) {
+// return nfpConvexOnly(sh, cother);
+ namespace sl = shapelike;
+ using alg = __svgnest::_alg<PolygonImpl>;
+
+ auto nfp_p = alg::noFitPolygon(sl::getContour(sh),
+ sl::getContour(cother), false, false);
+
+ PolygonImpl nfp_cntr;
+ if(!nfp_p.empty()) nfp_cntr.Contour = nfp_p.front();
+ return {nfp_cntr, referenceVertex(nfp_cntr)};
+ }
+};
+
+template<> struct NfpImpl<PolygonImpl, NfpLevel::ONE_CONVEX> {
+ NfpR operator()(const PolygonImpl& sh, const PolygonImpl& cother) {
+// return nfpConvexOnly(sh, cother);
+ namespace sl = shapelike;
+ using alg = __svgnest::_alg<PolygonImpl>;
+
+ std::cout << "Itt vagyok" << std::endl;
+ auto nfp_p = alg::noFitPolygon(sl::getContour(sh),
+ sl::getContour(cother), false, false);
+
+ PolygonImpl nfp_cntr;
+ nfp_cntr.Contour = nfp_p.front();
+ return {nfp_cntr, referenceVertex(nfp_cntr)};
+ }
+};
+
+template<>
+struct NfpImpl<PolygonImpl, NfpLevel::BOTH_CONCAVE> {
+ NfpR operator()(const PolygonImpl& sh, const PolygonImpl& cother) {
+ namespace sl = shapelike;
+ using alg = __svgnest::_alg<PolygonImpl>;
+
+ auto nfp_p = alg::noFitPolygon(sl::getContour(sh),
+ sl::getContour(cother), true, false);
+
+ PolygonImpl nfp_cntr;
+ nfp_cntr.Contour = nfp_p.front();
+ return {nfp_cntr, referenceVertex(nfp_cntr)};
+ }
+};
+
+template<> struct MaxNfpLevel<PolygonImpl> {
+// static const BP2D_CONSTEXPR NfpLevel value = NfpLevel::BOTH_CONCAVE;
+ static const BP2D_CONSTEXPR NfpLevel value = NfpLevel::CONVEX_ONLY;
+};
+
+}}
+
+#endif // NFP_SVGNEST_GLUE_HPP
diff --git a/xs/src/libnest2d/tools/svgtools.hpp b/xs/src/libnest2d/tools/svgtools.hpp
new file mode 100644
index 000000000..776dd5a1a
--- /dev/null
+++ b/xs/src/libnest2d/tools/svgtools.hpp
@@ -0,0 +1,122 @@
+#ifndef SVGTOOLS_HPP
+#define SVGTOOLS_HPP
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include <libnest2d/libnest2d.hpp>
+
+namespace libnest2d { namespace svg {
+
+template<class RawShape>
+class SVGWriter {
+ using Item = _Item<RawShape>;
+ using Coord = TCoord<TPoint<RawShape>>;
+ using Box = _Box<TPoint<RawShape>>;
+ using PackGroup = _PackGroup<RawShape>;
+
+public:
+
+ enum OrigoLocation {
+ TOPLEFT,
+ BOTTOMLEFT
+ };
+
+ struct Config {
+ OrigoLocation origo_location;
+ Coord mm_in_coord_units;
+ double width, height;
+ Config():
+ origo_location(BOTTOMLEFT), mm_in_coord_units(1000000),
+ width(500), height(500) {}
+
+ };
+
+private:
+ Config conf_;
+ std::vector<std::string> svg_layers_;
+ bool finished_ = false;
+public:
+
+ SVGWriter(const Config& conf = Config()):
+ conf_(conf) {}
+
+ void setSize(const Box& box) {
+ conf_.height = static_cast<double>(box.height()) /
+ conf_.mm_in_coord_units;
+ conf_.width = static_cast<double>(box.width()) /
+ conf_.mm_in_coord_units;
+ }
+
+ void writeItem(const Item& item) {
+ if(svg_layers_.empty()) addLayer();
+ auto tsh = item.transformedShape();
+ if(conf_.origo_location == BOTTOMLEFT) {
+ auto d = static_cast<Coord>(
+ std::round(conf_.height*conf_.mm_in_coord_units) );
+
+ auto& contour = shapelike::getContour(tsh);
+ for(auto& v : contour) setY(v, -getY(v) + d);
+
+ auto& holes = shapelike::holes(tsh);
+ for(auto& h : holes) for(auto& v : h) setY(v, -getY(v) + d);
+
+ }
+ currentLayer() += shapelike::serialize<Formats::SVG>(tsh,
+ 1.0/conf_.mm_in_coord_units) + "\n";
+ }
+
+ void writePackGroup(const PackGroup& result) {
+ for(auto r : result) {
+ addLayer();
+ for(Item& sh : r) {
+ writeItem(sh);
+ }
+ finishLayer();
+ }
+ }
+
+ void addLayer() {
+ svg_layers_.emplace_back(header());
+ finished_ = false;
+ }
+
+ void finishLayer() {
+ currentLayer() += "\n</svg>\n";
+ finished_ = true;
+ }
+
+ void save(const std::string& filepath) {
+ size_t lyrc = svg_layers_.size() > 1? 1 : 0;
+ size_t last = svg_layers_.size() > 1? svg_layers_.size() : 0;
+
+ for(auto& lyr : svg_layers_) {
+ std::fstream out(filepath + (lyrc > 0? std::to_string(lyrc) : "") +
+ ".svg", std::fstream::out);
+ if(out.is_open()) out << lyr;
+ if(lyrc == last && !finished_) out << "\n</svg>\n";
+ out.flush(); out.close(); lyrc++;
+ };
+ }
+
+private:
+
+ std::string& currentLayer() { return svg_layers_.back(); }
+
+ const std::string header() const {
+ std::string svg_header =
+R"raw(<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg height=")raw";
+ svg_header += std::to_string(conf_.height) + "\" width=\"" + std::to_string(conf_.width) + "\" ";
+ svg_header += R"raw(xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">)raw";
+ return svg_header;
+ }
+
+};
+
+}
+}
+
+#endif // SVGTOOLS_HPP
diff --git a/xs/src/libslic3r/BoundingBox.cpp b/xs/src/libslic3r/BoundingBox.cpp
index 91ba88d84..d3cca7ff2 100644
--- a/xs/src/libslic3r/BoundingBox.cpp
+++ b/xs/src/libslic3r/BoundingBox.cpp
@@ -2,12 +2,14 @@
#include <algorithm>
#include <assert.h>
+#include <Eigen/Dense>
+
namespace Slic3r {
template BoundingBoxBase<Point>::BoundingBoxBase(const std::vector<Point> &points);
-template BoundingBoxBase<Pointf>::BoundingBoxBase(const std::vector<Pointf> &points);
+template BoundingBoxBase<Vec2d>::BoundingBoxBase(const std::vector<Vec2d> &points);
-template BoundingBox3Base<Pointf3>::BoundingBox3Base(const std::vector<Pointf3> &points);
+template BoundingBox3Base<Vec3d>::BoundingBox3Base(const std::vector<Vec3d> &points);
BoundingBox::BoundingBox(const Lines &lines)
{
@@ -20,23 +22,21 @@ BoundingBox::BoundingBox(const Lines &lines)
*this = BoundingBox(points);
}
-void
-BoundingBox::polygon(Polygon* polygon) const
+void BoundingBox::polygon(Polygon* polygon) const
{
polygon->points.clear();
polygon->points.resize(4);
- polygon->points[0].x = this->min.x;
- polygon->points[0].y = this->min.y;
- polygon->points[1].x = this->max.x;
- polygon->points[1].y = this->min.y;
- polygon->points[2].x = this->max.x;
- polygon->points[2].y = this->max.y;
- polygon->points[3].x = this->min.x;
- polygon->points[3].y = this->max.y;
+ polygon->points[0](0) = this->min(0);
+ polygon->points[0](1) = this->min(1);
+ polygon->points[1](0) = this->max(0);
+ polygon->points[1](1) = this->min(1);
+ polygon->points[2](0) = this->max(0);
+ polygon->points[2](1) = this->max(1);
+ polygon->points[3](0) = this->min(0);
+ polygon->points[3](1) = this->max(1);
}
-Polygon
-BoundingBox::polygon() const
+Polygon BoundingBox::polygon() const
{
Polygon p;
this->polygon(&p);
@@ -48,8 +48,8 @@ BoundingBox BoundingBox::rotated(double angle) const
BoundingBox out;
out.merge(this->min.rotated(angle));
out.merge(this->max.rotated(angle));
- out.merge(Point(this->min.x, this->max.y).rotated(angle));
- out.merge(Point(this->max.x, this->min.y).rotated(angle));
+ out.merge(Point(this->min(0), this->max(1)).rotated(angle));
+ out.merge(Point(this->max(0), this->min(1)).rotated(angle));
return out;
}
@@ -58,36 +58,35 @@ BoundingBox BoundingBox::rotated(double angle, const Point &center) const
BoundingBox out;
out.merge(this->min.rotated(angle, center));
out.merge(this->max.rotated(angle, center));
- out.merge(Point(this->min.x, this->max.y).rotated(angle, center));
- out.merge(Point(this->max.x, this->min.y).rotated(angle, center));
+ out.merge(Point(this->min(0), this->max(1)).rotated(angle, center));
+ out.merge(Point(this->max(0), this->min(1)).rotated(angle, center));
return out;
}
template <class PointClass> void
BoundingBoxBase<PointClass>::scale(double factor)
{
- this->min.scale(factor);
- this->max.scale(factor);
+ this->min *= factor;
+ this->max *= factor;
}
template void BoundingBoxBase<Point>::scale(double factor);
-template void BoundingBoxBase<Pointf>::scale(double factor);
-template void BoundingBoxBase<Pointf3>::scale(double factor);
+template void BoundingBoxBase<Vec2d>::scale(double factor);
+template void BoundingBoxBase<Vec3d>::scale(double factor);
template <class PointClass> void
BoundingBoxBase<PointClass>::merge(const PointClass &point)
{
if (this->defined) {
- this->min.x = std::min(point.x, this->min.x);
- this->min.y = std::min(point.y, this->min.y);
- this->max.x = std::max(point.x, this->max.x);
- this->max.y = std::max(point.y, this->max.y);
+ this->min = this->min.cwiseMin(point);
+ this->max = this->max.cwiseMax(point);
} else {
- this->min = this->max = point;
+ this->min = point;
+ this->max = point;
this->defined = true;
}
}
template void BoundingBoxBase<Point>::merge(const Point &point);
-template void BoundingBoxBase<Pointf>::merge(const Pointf &point);
+template void BoundingBoxBase<Vec2d>::merge(const Vec2d &point);
template <class PointClass> void
BoundingBoxBase<PointClass>::merge(const std::vector<PointClass> &points)
@@ -95,18 +94,16 @@ BoundingBoxBase<PointClass>::merge(const std::vector<PointClass> &points)
this->merge(BoundingBoxBase(points));
}
template void BoundingBoxBase<Point>::merge(const Points &points);
-template void BoundingBoxBase<Pointf>::merge(const Pointfs &points);
+template void BoundingBoxBase<Vec2d>::merge(const Pointfs &points);
template <class PointClass> void
BoundingBoxBase<PointClass>::merge(const BoundingBoxBase<PointClass> &bb)
{
- assert(bb.defined || bb.min.x >= bb.max.x || bb.min.y >= bb.max.y);
+ assert(bb.defined || bb.min(0) >= bb.max(0) || bb.min(1) >= bb.max(1));
if (bb.defined) {
if (this->defined) {
- this->min.x = std::min(bb.min.x, this->min.x);
- this->min.y = std::min(bb.min.y, this->min.y);
- this->max.x = std::max(bb.max.x, this->max.x);
- this->max.y = std::max(bb.max.y, this->max.y);
+ this->min = this->min.cwiseMin(bb.min);
+ this->max = this->max.cwiseMax(bb.max);
} else {
this->min = bb.min;
this->max = bb.max;
@@ -115,112 +112,121 @@ BoundingBoxBase<PointClass>::merge(const BoundingBoxBase<PointClass> &bb)
}
}
template void BoundingBoxBase<Point>::merge(const BoundingBoxBase<Point> &bb);
-template void BoundingBoxBase<Pointf>::merge(const BoundingBoxBase<Pointf> &bb);
+template void BoundingBoxBase<Vec2d>::merge(const BoundingBoxBase<Vec2d> &bb);
template <class PointClass> void
BoundingBox3Base<PointClass>::merge(const PointClass &point)
{
if (this->defined) {
- this->min.z = std::min(point.z, this->min.z);
- this->max.z = std::max(point.z, this->max.z);
+ this->min = this->min.cwiseMin(point);
+ this->max = this->max.cwiseMax(point);
+ } else {
+ this->min = point;
+ this->max = point;
+ this->defined = true;
}
- BoundingBoxBase<PointClass>::merge(point);
}
-template void BoundingBox3Base<Pointf3>::merge(const Pointf3 &point);
+template void BoundingBox3Base<Vec3d>::merge(const Vec3d &point);
template <class PointClass> void
BoundingBox3Base<PointClass>::merge(const std::vector<PointClass> &points)
{
this->merge(BoundingBox3Base(points));
}
-template void BoundingBox3Base<Pointf3>::merge(const Pointf3s &points);
+template void BoundingBox3Base<Vec3d>::merge(const Pointf3s &points);
template <class PointClass> void
BoundingBox3Base<PointClass>::merge(const BoundingBox3Base<PointClass> &bb)
{
- assert(bb.defined || bb.min.x >= bb.max.x || bb.min.y >= bb.max.y || bb.min.z >= bb.max.z);
+ assert(bb.defined || bb.min(0) >= bb.max(0) || bb.min(1) >= bb.max(1) || bb.min(2) >= bb.max(2));
if (bb.defined) {
if (this->defined) {
- this->min.z = std::min(bb.min.z, this->min.z);
- this->max.z = std::max(bb.max.z, this->max.z);
+ this->min = this->min.cwiseMin(bb.min);
+ this->max = this->max.cwiseMax(bb.max);
+ } else {
+ this->min = bb.min;
+ this->max = bb.max;
+ this->defined = true;
}
- BoundingBoxBase<PointClass>::merge(bb);
}
}
-template void BoundingBox3Base<Pointf3>::merge(const BoundingBox3Base<Pointf3> &bb);
+template void BoundingBox3Base<Vec3d>::merge(const BoundingBox3Base<Vec3d> &bb);
template <class PointClass> PointClass
BoundingBoxBase<PointClass>::size() const
{
- return PointClass(this->max.x - this->min.x, this->max.y - this->min.y);
+ return PointClass(this->max(0) - this->min(0), this->max(1) - this->min(1));
}
template Point BoundingBoxBase<Point>::size() const;
-template Pointf BoundingBoxBase<Pointf>::size() const;
+template Vec2d BoundingBoxBase<Vec2d>::size() const;
template <class PointClass> PointClass
BoundingBox3Base<PointClass>::size() const
{
- return PointClass(this->max.x - this->min.x, this->max.y - this->min.y, this->max.z - this->min.z);
+ return PointClass(this->max(0) - this->min(0), this->max(1) - this->min(1), this->max(2) - this->min(2));
}
-template Pointf3 BoundingBox3Base<Pointf3>::size() const;
+template Vec3d BoundingBox3Base<Vec3d>::size() const;
template <class PointClass> double BoundingBoxBase<PointClass>::radius() const
{
assert(this->defined);
- double x = this->max.x - this->min.x;
- double y = this->max.y - this->min.y;
+ double x = this->max(0) - this->min(0);
+ double y = this->max(1) - this->min(1);
return 0.5 * sqrt(x*x+y*y);
}
template double BoundingBoxBase<Point>::radius() const;
-template double BoundingBoxBase<Pointf>::radius() const;
+template double BoundingBoxBase<Vec2d>::radius() const;
template <class PointClass> double BoundingBox3Base<PointClass>::radius() const
{
- double x = this->max.x - this->min.x;
- double y = this->max.y - this->min.y;
- double z = this->max.z - this->min.z;
+ double x = this->max(0) - this->min(0);
+ double y = this->max(1) - this->min(1);
+ double z = this->max(2) - this->min(2);
return 0.5 * sqrt(x*x+y*y+z*z);
}
-template double BoundingBox3Base<Pointf3>::radius() const;
+template double BoundingBox3Base<Vec3d>::radius() const;
template <class PointClass> void
BoundingBoxBase<PointClass>::offset(coordf_t delta)
{
- this->min.translate(-delta, -delta);
- this->max.translate(delta, delta);
+ PointClass v(delta, delta);
+ this->min -= v;
+ this->max += v;
}
template void BoundingBoxBase<Point>::offset(coordf_t delta);
-template void BoundingBoxBase<Pointf>::offset(coordf_t delta);
+template void BoundingBoxBase<Vec2d>::offset(coordf_t delta);
template <class PointClass> void
BoundingBox3Base<PointClass>::offset(coordf_t delta)
{
- this->min.translate(-delta, -delta, -delta);
- this->max.translate(delta, delta, delta);
+ PointClass v(delta, delta, delta);
+ this->min -= v;
+ this->max += v;
}
-template void BoundingBox3Base<Pointf3>::offset(coordf_t delta);
+template void BoundingBox3Base<Vec3d>::offset(coordf_t delta);
template <class PointClass> PointClass
BoundingBoxBase<PointClass>::center() const
{
- return PointClass(
- (this->max.x + this->min.x)/2,
- (this->max.y + this->min.y)/2
- );
+ return (this->min + this->max) / 2;
}
template Point BoundingBoxBase<Point>::center() const;
-template Pointf BoundingBoxBase<Pointf>::center() const;
+template Vec2d BoundingBoxBase<Vec2d>::center() const;
template <class PointClass> PointClass
BoundingBox3Base<PointClass>::center() const
{
- return PointClass(
- (this->max.x + this->min.x)/2,
- (this->max.y + this->min.y)/2,
- (this->max.z + this->min.z)/2
- );
+ return (this->min + this->max) / 2;
+}
+template Vec3d BoundingBox3Base<Vec3d>::center() const;
+
+template <class PointClass> coordf_t
+BoundingBox3Base<PointClass>::max_size() const
+{
+ PointClass s = size();
+ return std::max(s(0), std::max(s(1), s(2)));
}
-template Pointf3 BoundingBox3Base<Pointf3>::center() const;
+template coordf_t BoundingBox3Base<Vec3d>::max_size() const;
// Align a coordinate to a grid. The coordinate may be negative,
// the aligned value will never be bigger than the original one.
@@ -238,9 +244,40 @@ static inline coord_t _align_to_grid(const coord_t coord, const coord_t spacing)
void BoundingBox::align_to_grid(const coord_t cell_size)
{
if (this->defined) {
- min.x = _align_to_grid(min.x, cell_size);
- min.y = _align_to_grid(min.y, cell_size);
+ min(0) = _align_to_grid(min(0), cell_size);
+ min(1) = _align_to_grid(min(1), cell_size);
}
}
+BoundingBoxf3 BoundingBoxf3::transformed(const Transform3d& matrix) const
+{
+ typedef Eigen::Matrix<double, 3, 8, Eigen::DontAlign> Vertices;
+
+ Vertices src_vertices;
+ src_vertices(0, 0) = min(0); src_vertices(1, 0) = min(1); src_vertices(2, 0) = min(2);
+ src_vertices(0, 1) = max(0); src_vertices(1, 1) = min(1); src_vertices(2, 1) = min(2);
+ src_vertices(0, 2) = max(0); src_vertices(1, 2) = max(1); src_vertices(2, 2) = min(2);
+ src_vertices(0, 3) = min(0); src_vertices(1, 3) = max(1); src_vertices(2, 3) = min(2);
+ src_vertices(0, 4) = min(0); src_vertices(1, 4) = min(1); src_vertices(2, 4) = max(2);
+ src_vertices(0, 5) = max(0); src_vertices(1, 5) = min(1); src_vertices(2, 5) = max(2);
+ src_vertices(0, 6) = max(0); src_vertices(1, 6) = max(1); src_vertices(2, 6) = max(2);
+ src_vertices(0, 7) = min(0); src_vertices(1, 7) = max(1); src_vertices(2, 7) = max(2);
+
+ Vertices dst_vertices = matrix * src_vertices.colwise().homogeneous();
+
+ Vec3d v_min(dst_vertices(0, 0), dst_vertices(1, 0), dst_vertices(2, 0));
+ Vec3d v_max = v_min;
+
+ for (int i = 1; i < 8; ++i)
+ {
+ for (int j = 0; j < 3; ++j)
+ {
+ v_min(j) = std::min(v_min(j), dst_vertices(j, i));
+ v_max(j) = std::max(v_max(j), dst_vertices(j, i));
+ }
+ }
+
+ return BoundingBoxf3(v_min, v_max);
+}
+
}
diff --git a/xs/src/libslic3r/BoundingBox.hpp b/xs/src/libslic3r/BoundingBox.hpp
index 92a2bd451..db56c765c 100644
--- a/xs/src/libslic3r/BoundingBox.hpp
+++ b/xs/src/libslic3r/BoundingBox.hpp
@@ -7,11 +7,6 @@
namespace Slic3r {
-typedef Point Size;
-typedef Point3 Size3;
-typedef Pointf Sizef;
-typedef Pointf3 Sizef3;
-
template <class PointClass>
class BoundingBoxBase
{
@@ -20,25 +15,22 @@ public:
PointClass max;
bool defined;
- BoundingBoxBase() : defined(false) {};
+ BoundingBoxBase() : defined(false), min(PointClass::Zero()), max(PointClass::Zero()) {}
BoundingBoxBase(const PointClass &pmin, const PointClass &pmax) :
- min(pmin), max(pmax), defined(pmin.x < pmax.x && pmin.y < pmax.y) {}
- BoundingBoxBase(const std::vector<PointClass>& points)
+ min(pmin), max(pmax), defined(pmin(0) < pmax(0) && pmin(1) < pmax(1)) {}
+ BoundingBoxBase(const std::vector<PointClass>& points) : min(PointClass::Zero()), max(PointClass::Zero())
{
if (points.empty())
CONFESS("Empty point set supplied to BoundingBoxBase constructor");
typename std::vector<PointClass>::const_iterator it = points.begin();
- this->min.x = this->max.x = it->x;
- this->min.y = this->max.y = it->y;
- for (++it; it != points.end(); ++it)
- {
- this->min.x = std::min(it->x, this->min.x);
- this->min.y = std::min(it->y, this->min.y);
- this->max.x = std::max(it->x, this->max.x);
- this->max.y = std::max(it->y, this->max.y);
+ this->min = *it;
+ this->max = *it;
+ for (++ it; it != points.end(); ++ it) {
+ this->min = this->min.cwiseMin(*it);
+ this->max = this->max.cwiseMax(*it);
}
- this->defined = (this->min.x < this->max.x) && (this->min.y < this->max.y);
+ this->defined = (this->min(0) < this->max(0)) && (this->min(1) < this->max(1));
}
void merge(const PointClass &point);
void merge(const std::vector<PointClass> &points);
@@ -46,17 +38,17 @@ public:
void scale(double factor);
PointClass size() const;
double radius() const;
- void translate(coordf_t x, coordf_t y) { assert(this->defined); this->min.translate(x, y); this->max.translate(x, y); }
- void translate(const Pointf &pos) { this->translate(pos.x, pos.y); }
+ void translate(coordf_t x, coordf_t y) { assert(this->defined); PointClass v(x, y); this->min += v; this->max += v; }
+ void translate(const Vec2d &v) { this->min += v; this->max += v; }
void offset(coordf_t delta);
PointClass center() const;
bool contains(const PointClass &point) const {
- return point.x >= this->min.x && point.x <= this->max.x
- && point.y >= this->min.y && point.y <= this->max.y;
+ return point(0) >= this->min(0) && point(0) <= this->max(0)
+ && point(1) >= this->min(1) && point(1) <= this->max(1);
}
bool overlap(const BoundingBoxBase<PointClass> &other) const {
- return ! (this->max.x < other.min.x || this->min.x > other.max.x ||
- this->max.y < other.min.y || this->min.y > other.max.y);
+ return ! (this->max(0) < other.min(0) || this->min(0) > other.max(0) ||
+ this->max(1) < other.min(1) || this->min(1) > other.max(1));
}
bool operator==(const BoundingBoxBase<PointClass> &rhs) { return this->min == rhs.min && this->max == rhs.max; }
bool operator!=(const BoundingBoxBase<PointClass> &rhs) { return ! (*this == rhs); }
@@ -69,39 +61,42 @@ public:
BoundingBox3Base() : BoundingBoxBase<PointClass>() {};
BoundingBox3Base(const PointClass &pmin, const PointClass &pmax) :
BoundingBoxBase<PointClass>(pmin, pmax)
- { if (pmin.z >= pmax.z) BoundingBoxBase<PointClass>::defined = false; }
+ { if (pmin(2) >= pmax(2)) BoundingBoxBase<PointClass>::defined = false; }
BoundingBox3Base(const std::vector<PointClass>& points)
- : BoundingBoxBase<PointClass>(points)
{
if (points.empty())
CONFESS("Empty point set supplied to BoundingBox3Base constructor");
-
typename std::vector<PointClass>::const_iterator it = points.begin();
- this->min.z = this->max.z = it->z;
- for (++it; it != points.end(); ++it)
- {
- this->min.z = std::min(it->z, this->min.z);
- this->max.z = std::max(it->z, this->max.z);
+ this->min = *it;
+ this->max = *it;
+ for (++ it; it != points.end(); ++ it) {
+ this->min = this->min.cwiseMin(*it);
+ this->max = this->max.cwiseMax(*it);
}
- this->defined &= (this->min.z < this->max.z);
+ this->defined = (this->min(0) < this->max(0)) && (this->min(1) < this->max(1)) && (this->min(2) < this->max(2));
}
void merge(const PointClass &point);
void merge(const std::vector<PointClass> &points);
void merge(const BoundingBox3Base<PointClass> &bb);
PointClass size() const;
double radius() const;
- void translate(coordf_t x, coordf_t y, coordf_t z) { this->min.translate(x, y, z); this->max.translate(x, y, z); }
- void translate(const Pointf3 &pos) { this->translate(pos.x, pos.y, pos.z); }
+ void translate(coordf_t x, coordf_t y, coordf_t z) { assert(this->defined); PointClass v(x, y, z); this->min += v; this->max += v; }
+ void translate(const Vec3d &v) { this->min += v; this->max += v; }
void offset(coordf_t delta);
PointClass center() const;
+ coordf_t max_size() const;
bool contains(const PointClass &point) const {
- return BoundingBoxBase<PointClass>::contains(point) && point.z >= this->min.z && point.z <= this->max.z;
+ return BoundingBoxBase<PointClass>::contains(point) && point(2) >= this->min(2) && point(2) <= this->max(2);
}
bool contains(const BoundingBox3Base<PointClass>& other) const {
return contains(other.min) && contains(other.max);
}
+
+ bool intersects(const BoundingBox3Base<PointClass>& other) const {
+ return (this->min(0) < other.max(0)) && (this->max(0) > other.min(0)) && (this->min(1) < other.max(1)) && (this->max(1) > other.min(1)) && (this->min(2) < other.max(2)) && (this->max(2) > other.min(2));
+ }
};
class BoundingBox : public BoundingBoxBase<Point>
@@ -125,40 +120,42 @@ public:
friend BoundingBox get_extents_rotated(const Points &points, double angle);
};
-class BoundingBox3 : public BoundingBox3Base<Point3>
+class BoundingBox3 : public BoundingBox3Base<Vec3crd>
{
public:
- BoundingBox3() : BoundingBox3Base<Point3>() {};
- BoundingBox3(const Point3 &pmin, const Point3 &pmax) : BoundingBox3Base<Point3>(pmin, pmax) {};
- BoundingBox3(const Points3& points) : BoundingBox3Base<Point3>(points) {};
+ BoundingBox3() : BoundingBox3Base<Vec3crd>() {};
+ BoundingBox3(const Vec3crd &pmin, const Vec3crd &pmax) : BoundingBox3Base<Vec3crd>(pmin, pmax) {};
+ BoundingBox3(const Points3& points) : BoundingBox3Base<Vec3crd>(points) {};
};
-class BoundingBoxf : public BoundingBoxBase<Pointf>
+class BoundingBoxf : public BoundingBoxBase<Vec2d>
{
public:
- BoundingBoxf() : BoundingBoxBase<Pointf>() {};
- BoundingBoxf(const Pointf &pmin, const Pointf &pmax) : BoundingBoxBase<Pointf>(pmin, pmax) {};
- BoundingBoxf(const std::vector<Pointf> &points) : BoundingBoxBase<Pointf>(points) {};
+ BoundingBoxf() : BoundingBoxBase<Vec2d>() {};
+ BoundingBoxf(const Vec2d &pmin, const Vec2d &pmax) : BoundingBoxBase<Vec2d>(pmin, pmax) {};
+ BoundingBoxf(const std::vector<Vec2d> &points) : BoundingBoxBase<Vec2d>(points) {};
};
-class BoundingBoxf3 : public BoundingBox3Base<Pointf3>
+class BoundingBoxf3 : public BoundingBox3Base<Vec3d>
{
public:
- BoundingBoxf3() : BoundingBox3Base<Pointf3>() {};
- BoundingBoxf3(const Pointf3 &pmin, const Pointf3 &pmax) : BoundingBox3Base<Pointf3>(pmin, pmax) {};
- BoundingBoxf3(const std::vector<Pointf3> &points) : BoundingBox3Base<Pointf3>(points) {};
+ BoundingBoxf3() : BoundingBox3Base<Vec3d>() {};
+ BoundingBoxf3(const Vec3d &pmin, const Vec3d &pmax) : BoundingBox3Base<Vec3d>(pmin, pmax) {};
+ BoundingBoxf3(const std::vector<Vec3d> &points) : BoundingBox3Base<Vec3d>(points) {};
+
+ BoundingBoxf3 transformed(const Transform3d& matrix) const;
};
template<typename VT>
inline bool empty(const BoundingBoxBase<VT> &bb)
{
- return ! bb.defined || bb.min.x >= bb.max.x || bb.min.y >= bb.max.y;
+ return ! bb.defined || bb.min(0) >= bb.max(0) || bb.min(1) >= bb.max(1);
}
template<typename VT>
inline bool empty(const BoundingBox3Base<VT> &bb)
{
- return ! bb.defined || bb.min.x >= bb.max.x || bb.min.y >= bb.max.y || bb.min.z >= bb.max.z;
+ return ! bb.defined || bb.min(0) >= bb.max(0) || bb.min(1) >= bb.max(1) || bb.min(2) >= bb.max(2);
}
} // namespace Slic3r
diff --git a/xs/src/libslic3r/BridgeDetector.cpp b/xs/src/libslic3r/BridgeDetector.cpp
index a5272683f..ccc3505ce 100644
--- a/xs/src/libslic3r/BridgeDetector.cpp
+++ b/xs/src/libslic3r/BridgeDetector.cpp
@@ -102,16 +102,16 @@ bool BridgeDetector::detect_angle(double bridge_direction_override)
// Get an oriented bounding box around _anchor_regions.
BoundingBox bbox = get_extents_rotated(this->_anchor_regions, - angle);
// Cover the region with line segments.
- lines.reserve((bbox.max.y - bbox.min.y + this->spacing) / this->spacing);
+ lines.reserve((bbox.max(1) - bbox.min(1) + this->spacing) / this->spacing);
double s = sin(angle);
double c = cos(angle);
//FIXME Vojtech: The lines shall be spaced half the line width from the edge, but then
// some of the test cases fail. Need to adjust the test cases then?
-// for (coord_t y = bbox.min.y + this->spacing / 2; y <= bbox.max.y; y += this->spacing)
- for (coord_t y = bbox.min.y; y <= bbox.max.y; y += this->spacing)
+// for (coord_t y = bbox.min(1) + this->spacing / 2; y <= bbox.max(1); y += this->spacing)
+ for (coord_t y = bbox.min(1); y <= bbox.max(1); y += this->spacing)
lines.push_back(Line(
- Point((coord_t)round(c * bbox.min.x - s * y), (coord_t)round(c * y + s * bbox.min.x)),
- Point((coord_t)round(c * bbox.max.x - s * y), (coord_t)round(c * y + s * bbox.max.x))));
+ Point((coord_t)round(c * bbox.min(0) - s * y), (coord_t)round(c * y + s * bbox.min(0))),
+ Point((coord_t)round(c * bbox.max(0) - s * y), (coord_t)round(c * y + s * bbox.max(0)))));
}
double total_length = 0;
@@ -182,9 +182,9 @@ std::vector<double> BridgeDetector::bridge_direction_candidates() const
/* we also test angles of each open supporting edge
(this finds the optimal angle for C-shaped supports) */
- for (Polylines::const_iterator edge = this->_edges.begin(); edge != this->_edges.end(); ++edge)
- if (! edge->first_point().coincides_with(edge->last_point()))
- angles.push_back(Line(edge->first_point(), edge->last_point()).direction());
+ for (const Polyline &edge : this->_edges)
+ if (edge.first_point() != edge.last_point())
+ angles.push_back(Line(edge.first_point(), edge.last_point()).direction());
// remove duplicates
double min_resolution = PI/180.0; // 1 degree
@@ -282,10 +282,12 @@ BridgeDetector::unsupported_edges(double angle, Polylines* unsupported) const
extrusions would be anchored within such length (i.e. a slightly non-parallel bridging
direction might still benefit from anchors if long enough)
double angle_tolerance = PI / 180.0 * 5.0; */
- for (Lines::const_iterator line = unsupported_lines.begin(); line != unsupported_lines.end(); ++line) {
- if (!Slic3r::Geometry::directions_parallel(line->direction(), angle))
- unsupported->push_back(*line);
- }
+ for (const Line &line : unsupported_lines)
+ if (! Slic3r::Geometry::directions_parallel(line.direction(), angle)) {
+ unsupported->emplace_back(Polyline());
+ unsupported->back().points.emplace_back(line.a);
+ unsupported->back().points.emplace_back(line.b);
+ }
}
/*
diff --git a/xs/src/libslic3r/ClipperUtils.cpp b/xs/src/libslic3r/ClipperUtils.cpp
index 86123b23c..f00e908ce 100644
--- a/xs/src/libslic3r/ClipperUtils.cpp
+++ b/xs/src/libslic3r/ClipperUtils.cpp
@@ -171,7 +171,7 @@ Slic3rMultiPoint_to_ClipperPath(const MultiPoint &input)
{
ClipperLib::Path retval;
for (Points::const_iterator pit = input.points.begin(); pit != input.points.end(); ++pit)
- retval.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y ));
+ retval.push_back(ClipperLib::IntPoint( (*pit)(0), (*pit)(1) ));
return retval;
}
@@ -181,7 +181,7 @@ Slic3rMultiPoint_to_ClipperPath_reversed(const Slic3r::MultiPoint &input)
ClipperLib::Path output;
output.reserve(input.points.size());
for (Slic3r::Points::const_reverse_iterator pit = input.points.rbegin(); pit != input.points.rend(); ++pit)
- output.push_back(ClipperLib::IntPoint( (*pit).x, (*pit).y ));
+ output.push_back(ClipperLib::IntPoint( (*pit)(0), (*pit)(1) ));
return output;
}
@@ -458,6 +458,19 @@ offset2_ex(const Polygons &polygons, const float delta1, const float delta2,
return ClipperPaths_to_Slic3rExPolygons(output);
}
+//FIXME Vojtech: This functon may likely be optimized to avoid some of the Slic3r to Clipper
+// conversions and unnecessary Clipper calls.
+ExPolygons offset2_ex(const ExPolygons &expolygons, const float delta1,
+ const float delta2, ClipperLib::JoinType joinType, double miterLimit)
+{
+ Polygons polys;
+ for (const ExPolygon &expoly : expolygons)
+ append(polys,
+ offset(offset_ex(expoly, delta1, joinType, miterLimit),
+ delta2, joinType, miterLimit));
+ return union_ex(polys);
+}
+
template <class T>
T
_clipper_do(const ClipperLib::ClipType clipType, const Polygons &subject,
@@ -582,26 +595,26 @@ Polylines _clipper_pl(ClipperLib::ClipType clipType, const Polygons &subject, co
to recombine continuous polylines. */
for (size_t i = 0; i < retval.size(); ++i) {
for (size_t j = i+1; j < retval.size(); ++j) {
- if (retval[i].points.back().coincides_with(retval[j].points.front())) {
+ if (retval[i].points.back() == retval[j].points.front()) {
/* If last point of i coincides with first point of j,
append points of j to i and delete j */
retval[i].points.insert(retval[i].points.end(), retval[j].points.begin()+1, retval[j].points.end());
retval.erase(retval.begin() + j);
--j;
- } else if (retval[i].points.front().coincides_with(retval[j].points.back())) {
+ } else if (retval[i].points.front() == retval[j].points.back()) {
/* If first point of i coincides with last point of j,
prepend points of j to i and delete j */
retval[i].points.insert(retval[i].points.begin(), retval[j].points.begin(), retval[j].points.end()-1);
retval.erase(retval.begin() + j);
--j;
- } else if (retval[i].points.front().coincides_with(retval[j].points.front())) {
+ } else if (retval[i].points.front() == retval[j].points.front()) {
/* Since Clipper does not preserve orientation of polylines,
also check the case when first point of i coincides with first point of j. */
retval[j].reverse();
retval[i].points.insert(retval[i].points.begin(), retval[j].points.begin(), retval[j].points.end()-1);
retval.erase(retval.begin() + j);
--j;
- } else if (retval[i].points.back().coincides_with(retval[j].points.back())) {
+ } else if (retval[i].points.back() == retval[j].points.back()) {
/* Since Clipper does not preserve orientation of polylines,
also check the case when last point of i coincides with last point of j. */
retval[j].reverse();
@@ -621,8 +634,8 @@ _clipper_ln(ClipperLib::ClipType clipType, const Lines &subject, const Polygons
// convert Lines to Polylines
Polylines polylines;
polylines.reserve(subject.size());
- for (Lines::const_iterator line = subject.begin(); line != subject.end(); ++line)
- polylines.push_back(*line);
+ for (const Line &line : subject)
+ polylines.emplace_back(Polyline(line.a, line.b));
// perform operation
polylines = _clipper_pl(clipType, polylines, clip, safety_offset_);
@@ -650,8 +663,7 @@ union_pt_chained(const Polygons &subject, bool safety_offset_)
return retval;
}
-void
-traverse_pt(ClipperLib::PolyNodes &nodes, Polygons* retval)
+void traverse_pt(ClipperLib::PolyNodes &nodes, Polygons* retval)
{
/* use a nearest neighbor search to order these children
TODO: supply start_near to chained_path() too? */
@@ -677,8 +689,7 @@ traverse_pt(ClipperLib::PolyNodes &nodes, Polygons* retval)
}
}
-Polygons
-simplify_polygons(const Polygons &subject, bool preserve_collinear)
+Polygons simplify_polygons(const Polygons &subject, bool preserve_collinear)
{
// convert into Clipper polygons
ClipperLib::Paths input_subject = Slic3rMultiPoints_to_ClipperPaths(subject);
@@ -698,13 +709,11 @@ simplify_polygons(const Polygons &subject, bool preserve_collinear)
return ClipperPaths_to_Slic3rPolygons(output);
}
-ExPolygons
-simplify_polygons_ex(const Polygons &subject, bool preserve_collinear)
+ExPolygons simplify_polygons_ex(const Polygons &subject, bool preserve_collinear)
{
- if (!preserve_collinear) {
- return union_ex(simplify_polygons(subject, preserve_collinear));
- }
-
+ if (! preserve_collinear)
+ return union_ex(simplify_polygons(subject, false));
+
// convert into Clipper polygons
ClipperLib::Paths input_subject = Slic3rMultiPoints_to_ClipperPaths(subject);
diff --git a/xs/src/libslic3r/ClipperUtils.hpp b/xs/src/libslic3r/ClipperUtils.hpp
index eb83c31a3..b065cfe07 100644
--- a/xs/src/libslic3r/ClipperUtils.hpp
+++ b/xs/src/libslic3r/ClipperUtils.hpp
@@ -80,6 +80,9 @@ Slic3r::Polygons offset2(const Slic3r::Polygons &polygons, const float delta1,
Slic3r::ExPolygons offset2_ex(const Slic3r::Polygons &polygons, const float delta1,
const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
double miterLimit = 3);
+Slic3r::ExPolygons offset2_ex(const Slic3r::ExPolygons &expolygons, const float delta1,
+ const float delta2, ClipperLib::JoinType joinType = ClipperLib::jtMiter,
+ double miterLimit = 3);
Slic3r::Polygons _clipper(ClipperLib::ClipType clipType,
const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp
index 1a0b8fb4a..e7442d773 100644
--- a/xs/src/libslic3r/Config.cpp
+++ b/xs/src/libslic3r/Config.cpp
@@ -20,6 +20,7 @@
namespace Slic3r {
+// Escape \n, \r and backslash
std::string escape_string_cstyle(const std::string &str)
{
// Allocate a buffer twice the input string length,
@@ -28,9 +29,15 @@ std::string escape_string_cstyle(const std::string &str)
char *outptr = out.data();
for (size_t i = 0; i < str.size(); ++ i) {
char c = str[i];
- if (c == '\n' || c == '\r') {
+ if (c == '\r') {
+ (*outptr ++) = '\\';
+ (*outptr ++) = 'r';
+ } else if (c == '\n') {
(*outptr ++) = '\\';
(*outptr ++) = 'n';
+ } else if (c == '\\') {
+ (*outptr ++) = '\\';
+ (*outptr ++) = '\\';
} else
(*outptr ++) = c;
}
@@ -69,7 +76,10 @@ std::string escape_strings_cstyle(const std::vector<std::string> &strs)
if (c == '\\' || c == '"') {
(*outptr ++) = '\\';
(*outptr ++) = c;
- } else if (c == '\n' || c == '\r') {
+ } else if (c == '\r') {
+ (*outptr ++) = '\\';
+ (*outptr ++) = 'r';
+ } else if (c == '\n') {
(*outptr ++) = '\\';
(*outptr ++) = 'n';
} else
@@ -84,6 +94,7 @@ std::string escape_strings_cstyle(const std::vector<std::string> &strs)
return std::string(out.data(), outptr - out.data());
}
+// Unescape \n, \r and backslash
bool unescape_string_cstyle(const std::string &str, std::string &str_out)
{
std::vector<char> out(str.size(), 0);
@@ -94,8 +105,12 @@ bool unescape_string_cstyle(const std::string &str, std::string &str_out)
if (++ i == str.size())
return false;
c = str[i];
- if (c == 'n')
+ if (c == 'r')
+ (*outptr ++) = '\r';
+ else if (c == 'n')
(*outptr ++) = '\n';
+ else
+ (*outptr ++) = c;
} else
(*outptr ++) = c;
}
@@ -134,7 +149,9 @@ bool unescape_strings_cstyle(const std::string &str, std::vector<std::string> &o
if (++ i == str.size())
return false;
c = str[i];
- if (c == 'n')
+ if (c == 'r')
+ c = '\r';
+ else if (c == 'n')
c = '\n';
}
buf.push_back(c);
@@ -185,10 +202,13 @@ void ConfigBase::apply_only(const ConfigBase &other, const t_config_option_keys
// This is only possible if other is of DynamicConfig type.
if (ignore_nonexistent)
continue;
- throw UnknownOptionException();
+ throw UnknownOptionException(opt_key);
}
const ConfigOption *other_opt = other.option(opt_key);
- if (other_opt != nullptr)
+ if (other_opt == nullptr) {
+ // The key was not found in the source config, therefore it will not be initialized!
+// printf("Not found, therefore not initialized: %s\n", opt_key.c_str());
+ } else
my_opt->set(other_opt);
}
}
@@ -206,6 +226,56 @@ t_config_option_keys ConfigBase::diff(const ConfigBase &other) const
return diff;
}
+template<class T>
+void add_correct_opts_to_diff(const std::string &opt_key, t_config_option_keys& vec, const ConfigBase &other, const ConfigBase *this_c)
+{
+ const T* opt_init = static_cast<const T*>(other.option(opt_key));
+ const T* opt_cur = static_cast<const T*>(this_c->option(opt_key));
+ int opt_init_max_id = opt_init->values.size() - 1;
+ for (int i = 0; i < opt_cur->values.size(); i++)
+ {
+ int init_id = i <= opt_init_max_id ? i : 0;
+ if (opt_cur->values[i] != opt_init->values[init_id])
+ vec.emplace_back(opt_key + "#" + std::to_string(i));
+ }
+}
+
+t_config_option_keys ConfigBase::deep_diff(const ConfigBase &other) const
+{
+ t_config_option_keys diff;
+ for (const t_config_option_key &opt_key : this->keys()) {
+ const ConfigOption *this_opt = this->option(opt_key);
+ const ConfigOption *other_opt = other.option(opt_key);
+ if (this_opt != nullptr && other_opt != nullptr && *this_opt != *other_opt)
+ {
+ if (opt_key == "bed_shape"){ diff.emplace_back(opt_key); continue; }
+ switch (other_opt->type())
+ {
+ case coInts: add_correct_opts_to_diff<ConfigOptionInts >(opt_key, diff, other, this); break;
+ case coBools: add_correct_opts_to_diff<ConfigOptionBools >(opt_key, diff, other, this); break;
+ case coFloats: add_correct_opts_to_diff<ConfigOptionFloats >(opt_key, diff, other, this); break;
+ case coStrings: add_correct_opts_to_diff<ConfigOptionStrings >(opt_key, diff, other, this); break;
+ case coPercents:add_correct_opts_to_diff<ConfigOptionPercents >(opt_key, diff, other, this); break;
+ case coPoints: add_correct_opts_to_diff<ConfigOptionPoints >(opt_key, diff, other, this); break;
+ default: diff.emplace_back(opt_key); break;
+ }
+ }
+ }
+ return diff;
+}
+
+t_config_option_keys ConfigBase::equal(const ConfigBase &other) const
+{
+ t_config_option_keys equal;
+ for (const t_config_option_key &opt_key : this->keys()) {
+ const ConfigOption *this_opt = this->option(opt_key);
+ const ConfigOption *other_opt = other.option(opt_key);
+ if (this_opt != nullptr && other_opt != nullptr && *this_opt == *other_opt)
+ equal.emplace_back(opt_key);
+ }
+ return equal;
+}
+
std::string ConfigBase::serialize(const t_config_option_key &opt_key) const
{
const ConfigOption* opt = this->option(opt_key);
@@ -232,7 +302,7 @@ bool ConfigBase::set_deserialize_raw(const t_config_option_key &opt_key_src, con
// Try to deserialize the option by its name.
const ConfigDef *def = this->def();
if (def == nullptr)
- throw NoDefinitionException();
+ throw NoDefinitionException(opt_key);
const ConfigOptionDef *optdef = def->get(opt_key);
if (optdef == nullptr) {
// If we didn't find an option, look for any other option having this as an alias.
@@ -248,7 +318,7 @@ bool ConfigBase::set_deserialize_raw(const t_config_option_key &opt_key_src, con
break;
}
if (optdef == nullptr)
- throw UnknownOptionException();
+ throw UnknownOptionException(opt_key);
}
if (! optdef->shortcut.empty()) {
@@ -278,7 +348,7 @@ double ConfigBase::get_abs_value(const t_config_option_key &opt_key) const
// Get option definition.
const ConfigDef *def = this->def();
if (def == nullptr)
- throw NoDefinitionException();
+ throw NoDefinitionException(opt_key);
const ConfigOptionDef *opt_def = def->get(opt_key);
assert(opt_def != nullptr);
// Compute absolute value over the absolute value of the base option.
@@ -468,7 +538,7 @@ ConfigOption* DynamicConfig::optptr(const t_config_option_key &opt_key, bool cre
// Try to create a new ConfigOption.
const ConfigDef *def = this->def();
if (def == nullptr)
- throw NoDefinitionException();
+ throw NoDefinitionException(opt_key);
const ConfigOptionDef *optdef = def->get(opt_key);
if (optdef == nullptr)
// throw std::runtime_error(std::string("Invalid option name: ") + opt_key);
@@ -522,7 +592,7 @@ void StaticConfig::set_defaults()
t_config_option_keys StaticConfig::keys() const
{
t_config_option_keys keys;
- assert(this->def != nullptr);
+ assert(this->def() != nullptr);
for (const auto &opt_def : this->def()->options)
if (this->option(opt_def.first) != nullptr)
keys.push_back(opt_def.first);
diff --git a/xs/src/libslic3r/Config.hpp b/xs/src/libslic3r/Config.hpp
index 3dccedbf0..e3cd14335 100644
--- a/xs/src/libslic3r/Config.hpp
+++ b/xs/src/libslic3r/Config.hpp
@@ -49,9 +49,9 @@ enum ConfigOptionType {
coPercents = coPercent + coVectorType,
// a fraction or an absolute value
coFloatOrPercent = 5,
- // single 2d point. Currently not used.
+ // single 2d point (Point2f). Currently not used.
coPoint = 6,
- // vector of 2d points. Currently used for the definition of the print bed and for the extruder offsets.
+ // vector of 2d points (Point2f). Currently used for the definition of the print bed and for the extruder offsets.
coPoints = coPoint + coVectorType,
// single boolean value
coBool = 7,
@@ -291,6 +291,8 @@ public:
ConfigOptionFloats() : ConfigOptionVector<double>() {}
explicit ConfigOptionFloats(size_t n, double value) : ConfigOptionVector<double>(n, value) {}
explicit ConfigOptionFloats(std::initializer_list<double> il) : ConfigOptionVector<double>(std::move(il)) {}
+ explicit ConfigOptionFloats(const std::vector<double> &vec) : ConfigOptionVector<double>(vec) {}
+ explicit ConfigOptionFloats(std::vector<double> &&vec) : ConfigOptionVector<double>(std::move(vec)) {}
static ConfigOptionType static_type() { return coFloats; }
ConfigOptionType type() const override { return static_type(); }
@@ -620,11 +622,11 @@ public:
}
};
-class ConfigOptionPoint : public ConfigOptionSingle<Pointf>
+class ConfigOptionPoint : public ConfigOptionSingle<Vec2d>
{
public:
- ConfigOptionPoint() : ConfigOptionSingle<Pointf>(Pointf(0,0)) {}
- explicit ConfigOptionPoint(const Pointf &value) : ConfigOptionSingle<Pointf>(value) {}
+ ConfigOptionPoint() : ConfigOptionSingle<Vec2d>(Vec2d(0,0)) {}
+ explicit ConfigOptionPoint(const Vec2d &value) : ConfigOptionSingle<Vec2d>(value) {}
static ConfigOptionType static_type() { return coPoint; }
ConfigOptionType type() const override { return static_type(); }
@@ -635,30 +637,28 @@ public:
std::string serialize() const override
{
std::ostringstream ss;
- ss << this->value.x;
+ ss << this->value(0);
ss << ",";
- ss << this->value.y;
+ ss << this->value(1);
return ss.str();
}
bool deserialize(const std::string &str, bool append = false) override
{
UNUSED(append);
- std::istringstream iss(str);
- iss >> this->value.x;
- iss.ignore(std::numeric_limits<std::streamsize>::max(), ',');
- iss.ignore(std::numeric_limits<std::streamsize>::max(), 'x');
- iss >> this->value.y;
- return true;
+ char dummy;
+ return sscanf(str.data(), " %lf , %lf %c", &this->value(0), &this->value(1), &dummy) == 2 ||
+ sscanf(str.data(), " %lf x %lf %c", &this->value(0), &this->value(1), &dummy) == 2;
}
};
-class ConfigOptionPoints : public ConfigOptionVector<Pointf>
+class ConfigOptionPoints : public ConfigOptionVector<Vec2d>
{
public:
- ConfigOptionPoints() : ConfigOptionVector<Pointf>() {}
- explicit ConfigOptionPoints(size_t n, const Pointf &value) : ConfigOptionVector<Pointf>(n, value) {}
- explicit ConfigOptionPoints(std::initializer_list<Pointf> il) : ConfigOptionVector<Pointf>(std::move(il)) {}
+ ConfigOptionPoints() : ConfigOptionVector<Vec2d>() {}
+ explicit ConfigOptionPoints(size_t n, const Vec2d &value) : ConfigOptionVector<Vec2d>(n, value) {}
+ explicit ConfigOptionPoints(std::initializer_list<Vec2d> il) : ConfigOptionVector<Vec2d>(std::move(il)) {}
+ explicit ConfigOptionPoints(const std::vector<Vec2d> &values) : ConfigOptionVector<Vec2d>(values) {}
static ConfigOptionType static_type() { return coPoints; }
ConfigOptionType type() const override { return static_type(); }
@@ -671,9 +671,9 @@ public:
std::ostringstream ss;
for (Pointfs::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
if (it - this->values.begin() != 0) ss << ",";
- ss << it->x;
+ ss << (*it)(0);
ss << "x";
- ss << it->y;
+ ss << (*it)(1);
}
return ss.str();
}
@@ -696,13 +696,13 @@ public:
std::istringstream is(str);
std::string point_str;
while (std::getline(is, point_str, ',')) {
- Pointf point;
+ Vec2d point(Vec2d::Zero());
std::istringstream iss(point_str);
std::string coord_str;
if (std::getline(iss, coord_str, 'x')) {
- std::istringstream(coord_str) >> point.x;
+ std::istringstream(coord_str) >> point(0);
if (std::getline(iss, coord_str, 'x')) {
- std::istringstream(coord_str) >> point.y;
+ std::istringstream(coord_str) >> point(1);
}
}
this->values.push_back(point);
@@ -821,12 +821,7 @@ public:
bool deserialize(const std::string &str, bool append = false) override
{
UNUSED(append);
- const t_config_enum_values &enum_keys_map = ConfigOptionEnum<T>::get_enum_values();
- auto it = enum_keys_map.find(str);
- if (it == enum_keys_map.end())
- return false;
- this->value = static_cast<T>(it->second);
- return true;
+ return from_string(str, this->value);
}
static bool has(T value)
@@ -838,7 +833,7 @@ public:
}
// Map from an enum name to an enum integer value.
- static t_config_enum_names& get_enum_names()
+ static const t_config_enum_names& get_enum_names()
{
static t_config_enum_names names;
if (names.empty()) {
@@ -855,7 +850,17 @@ public:
return names;
}
// Map from an enum name to an enum integer value.
- static t_config_enum_values& get_enum_values();
+ static const t_config_enum_values& get_enum_values();
+
+ static bool from_string(const std::string &str, T &value)
+ {
+ const t_config_enum_values &enum_keys_map = ConfigOptionEnum<T>::get_enum_values();
+ auto it = enum_keys_map.find(str);
+ if (it == enum_keys_map.end())
+ return false;
+ value = static_cast<T>(it->second);
+ return true;
+ }
};
// Generic enum configuration value.
@@ -900,7 +905,7 @@ public:
// What type? bool, int, string etc.
ConfigOptionType type = coNone;
// Default value of this option. The default value object is owned by ConfigDef, it is released in its destructor.
- ConfigOption *default_value = nullptr;
+ const ConfigOption *default_value = nullptr;
// Usually empty.
// Special values - "i_enum_open", "f_enum_open" to provide combo box for int or float selection,
@@ -958,7 +963,7 @@ public:
std::vector<std::string> enum_labels;
// For enums (when type == coEnum). Maps enum_values to enums.
// Initialized by ConfigOptionEnum<xxx>::get_enum_values()
- t_config_enum_values *enum_keys_map = nullptr;
+ const t_config_enum_values *enum_keys_map = nullptr;
bool has_enum_value(const std::string &value) const {
for (const std::string &v : enum_values)
@@ -1030,7 +1035,7 @@ public:
TYPE* option(const t_config_option_key &opt_key, bool create = false)
{
ConfigOption *opt = this->optptr(opt_key, create);
- assert(opt == nullptr || opt->type() == TYPE::static_type());
+// assert(opt == nullptr || opt->type() == TYPE::static_type());
return (opt == nullptr || opt->type() != TYPE::static_type()) ? nullptr : static_cast<TYPE*>(opt);
}
template<typename TYPE>
@@ -1046,6 +1051,10 @@ public:
void apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false);
bool equals(const ConfigBase &other) const { return this->diff(other).empty(); }
t_config_option_keys diff(const ConfigBase &other) const;
+ // Use deep_diff to correct return of changed options,
+ // considering individual options for each extruder
+ t_config_option_keys deep_diff(const ConfigBase &other) const;
+ t_config_option_keys equal(const ConfigBase &other) const;
std::string serialize(const t_config_option_key &opt_key) const;
// Set a configuration value from a string, it will call an overridable handle_legacy()
// to resolve renamed and removed configuration keys.
@@ -1232,17 +1241,22 @@ protected:
};
/// Specialization of std::exception to indicate that an unknown config option has been encountered.
-class UnknownOptionException : public std::exception
-{
+class UnknownOptionException : public std::runtime_error {
public:
- const char* what() const noexcept override { return "Unknown config option"; }
+ UnknownOptionException() :
+ std::runtime_error("Unknown option exception") {}
+ UnknownOptionException(const std::string &opt_key) :
+ std::runtime_error(std::string("Unknown option exception: ") + opt_key) {}
};
/// Indicate that the ConfigBase derived class does not provide config definition (the method def() returns null).
-class NoDefinitionException : public std::exception
+class NoDefinitionException : public std::runtime_error
{
public:
- const char* what() const noexcept override { return "No config definition"; }
+ NoDefinitionException() :
+ std::runtime_error("No definition exception") {}
+ NoDefinitionException(const std::string &opt_key) :
+ std::runtime_error(std::string("No definition exception: ") + opt_key) {}
};
}
diff --git a/xs/src/libslic3r/EdgeGrid.cpp b/xs/src/libslic3r/EdgeGrid.cpp
index 752243407..50f424e6d 100644
--- a/xs/src/libslic3r/EdgeGrid.cpp
+++ b/xs/src/libslic3r/EdgeGrid.cpp
@@ -117,15 +117,15 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
m_bbox.merge(pts[j]);
}
coord_t eps = 16;
- m_bbox.min.x -= eps;
- m_bbox.min.y -= eps;
- m_bbox.max.x += eps;
- m_bbox.max.y += eps;
+ m_bbox.min(0) -= eps;
+ m_bbox.min(1) -= eps;
+ m_bbox.max(0) += eps;
+ m_bbox.max(1) += eps;
// 2) Initialize the edge grid.
m_resolution = resolution;
- m_cols = (m_bbox.max.x - m_bbox.min.x + m_resolution - 1) / m_resolution;
- m_rows = (m_bbox.max.y - m_bbox.min.y + m_resolution - 1) / m_resolution;
+ m_cols = (m_bbox.max(0) - m_bbox.min(0) + m_resolution - 1) / m_resolution;
+ m_rows = (m_bbox.max(1) - m_bbox.min(1) + m_resolution - 1) / m_resolution;
m_cells.assign(m_rows * m_cols, Cell());
// 3) First round of contour rasterization, count the edges per grid cell.
@@ -135,15 +135,15 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
// End points of the line segment.
Slic3r::Point p1(pts[j]);
Slic3r::Point p2 = pts[(j + 1 == pts.size()) ? 0 : j + 1];
- p1.x -= m_bbox.min.x;
- p1.y -= m_bbox.min.y;
- p2.x -= m_bbox.min.x;
- p2.y -= m_bbox.min.y;
+ p1(0) -= m_bbox.min(0);
+ p1(1) -= m_bbox.min(1);
+ p2(0) -= m_bbox.min(0);
+ p2(1) -= m_bbox.min(1);
// Get the cells of the end points.
- coord_t ix = p1.x / m_resolution;
- coord_t iy = p1.y / m_resolution;
- coord_t ixb = p2.x / m_resolution;
- coord_t iyb = p2.y / m_resolution;
+ coord_t ix = p1(0) / m_resolution;
+ coord_t iy = p1(1) / m_resolution;
+ coord_t ixb = p2(0) / m_resolution;
+ coord_t iyb = p2(1) / m_resolution;
assert(ix >= 0 && ix < m_cols);
assert(iy >= 0 && iy < m_rows);
assert(ixb >= 0 && ixb < m_cols);
@@ -154,13 +154,13 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
// Both ends fall into the same cell.
continue;
// Raster the centeral part of the line.
- coord_t dx = std::abs(p2.x - p1.x);
- coord_t dy = std::abs(p2.y - p1.y);
- if (p1.x < p2.x) {
- int64_t ex = int64_t((ix + 1)*m_resolution - p1.x) * int64_t(dy);
- if (p1.y < p2.y) {
+ coord_t dx = std::abs(p2(0) - p1(0));
+ coord_t dy = std::abs(p2(1) - p1(1));
+ if (p1(0) < p2(0)) {
+ int64_t ex = int64_t((ix + 1)*m_resolution - p1(0)) * int64_t(dy);
+ if (p1(1) < p2(1)) {
// x positive, y positive
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix <= ixb && iy <= iyb);
if (ex < ey) {
@@ -185,7 +185,7 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
else {
// x positive, y non positive
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix <= ixb && iy >= iyb);
if (ex <= ey) {
@@ -203,10 +203,10 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
}
else {
- int64_t ex = int64_t(p1.x - ix*m_resolution) * int64_t(dy);
- if (p1.y < p2.y) {
+ int64_t ex = int64_t(p1(0) - ix*m_resolution) * int64_t(dy);
+ if (p1(1) < p2(1)) {
// x non positive, y positive
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix >= ixb && iy <= iyb);
if (ex < ey) {
@@ -225,7 +225,7 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
else {
// x non positive, y non positive
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix >= ixb && iy >= iyb);
if (ex < ey) {
@@ -279,15 +279,15 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
// End points of the line segment.
Slic3r::Point p1(pts[j]);
Slic3r::Point p2 = pts[(j + 1 == pts.size()) ? 0 : j + 1];
- p1.x -= m_bbox.min.x;
- p1.y -= m_bbox.min.y;
- p2.x -= m_bbox.min.x;
- p2.y -= m_bbox.min.y;
+ p1(0) -= m_bbox.min(0);
+ p1(1) -= m_bbox.min(1);
+ p2(0) -= m_bbox.min(0);
+ p2(1) -= m_bbox.min(1);
// Get the cells of the end points.
- coord_t ix = p1.x / m_resolution;
- coord_t iy = p1.y / m_resolution;
- coord_t ixb = p2.x / m_resolution;
- coord_t iyb = p2.y / m_resolution;
+ coord_t ix = p1(0) / m_resolution;
+ coord_t iy = p1(1) / m_resolution;
+ coord_t ixb = p2(0) / m_resolution;
+ coord_t iyb = p2(1) / m_resolution;
assert(ix >= 0 && ix < m_cols);
assert(iy >= 0 && iy < m_rows);
assert(ixb >= 0 && ixb < m_cols);
@@ -298,13 +298,13 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
// Both ends fall into the same cell.
continue;
// Raster the centeral part of the line.
- coord_t dx = std::abs(p2.x - p1.x);
- coord_t dy = std::abs(p2.y - p1.y);
- if (p1.x < p2.x) {
- int64_t ex = int64_t((ix + 1)*m_resolution - p1.x) * int64_t(dy);
- if (p1.y < p2.y) {
+ coord_t dx = std::abs(p2(0) - p1(0));
+ coord_t dy = std::abs(p2(1) - p1(1));
+ if (p1(0) < p2(0)) {
+ int64_t ex = int64_t((ix + 1)*m_resolution - p1(0)) * int64_t(dy);
+ if (p1(1) < p2(1)) {
// x positive, y positive
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix <= ixb && iy <= iyb);
if (ex < ey) {
@@ -329,7 +329,7 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
else {
// x positive, y non positive
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix <= ixb && iy >= iyb);
if (ex <= ey) {
@@ -347,10 +347,10 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
}
else {
- int64_t ex = int64_t(p1.x - ix*m_resolution) * int64_t(dy);
- if (p1.y < p2.y) {
+ int64_t ex = int64_t(p1(0) - ix*m_resolution) * int64_t(dy);
+ if (p1(1) < p2(1)) {
// x non positive, y positive
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix >= ixb && iy <= iyb);
if (ex < ey) {
@@ -369,7 +369,7 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
}
else {
// x non positive, y non positive
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix >= ixb && iy >= iyb);
if (ex < ey) {
@@ -429,15 +429,15 @@ bool EdgeGrid::Grid::intersect(const MultiPoint &polyline, bool closed)
Point p1 = p1src;
Point p2 = p2src;
// Discretize the line segment p1, p2.
- p1.x -= m_bbox.min.x;
- p1.y -= m_bbox.min.y;
- p2.x -= m_bbox.min.x;
- p2.y -= m_bbox.min.y;
+ p1(0) -= m_bbox.min(0);
+ p1(1) -= m_bbox.min(1);
+ p2(0) -= m_bbox.min(0);
+ p2(1) -= m_bbox.min(1);
// Get the cells of the end points.
- coord_t ix = div_floor(p1.x, m_resolution);
- coord_t iy = div_floor(p1.y, m_resolution);
- coord_t ixb = div_floor(p2.x, m_resolution);
- coord_t iyb = div_floor(p2.y, m_resolution);
+ coord_t ix = div_floor(p1(0), m_resolution);
+ coord_t iy = div_floor(p1(1), m_resolution);
+ coord_t ixb = div_floor(p2(0), m_resolution);
+ coord_t iyb = div_floor(p2(1), m_resolution);
// assert(ix >= 0 && ix < m_cols);
// assert(iy >= 0 && iy < m_rows);
// assert(ixb >= 0 && ixb < m_cols);
@@ -449,12 +449,12 @@ bool EdgeGrid::Grid::intersect(const MultiPoint &polyline, bool closed)
// Both ends fall into the same cell.
continue;
// Raster the centeral part of the line.
- coord_t dx = std::abs(p2.x - p1.x);
- coord_t dy = std::abs(p2.y - p1.y);
- if (p1.x < p2.x) {
- int64_t ex = int64_t((ix + 1)*m_resolution - p1.x) * int64_t(dy);
- if (p1.y < p2.y) {
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ coord_t dx = std::abs(p2(0) - p1(0));
+ coord_t dy = std::abs(p2(1) - p1(1));
+ if (p1(0) < p2(0)) {
+ int64_t ex = int64_t((ix + 1)*m_resolution - p1(0)) * int64_t(dy);
+ if (p1(1) < p2(1)) {
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix <= ixb && iy <= iyb);
if (ex < ey) {
@@ -479,7 +479,7 @@ bool EdgeGrid::Grid::intersect(const MultiPoint &polyline, bool closed)
} while (ix != ixb || iy != iyb);
}
else {
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix <= ixb && iy >= iyb);
if (ex <= ey) {
@@ -498,9 +498,9 @@ bool EdgeGrid::Grid::intersect(const MultiPoint &polyline, bool closed)
}
}
else {
- int64_t ex = int64_t(p1.x - ix*m_resolution) * int64_t(dy);
- if (p1.y < p2.y) {
- int64_t ey = int64_t((iy + 1)*m_resolution - p1.y) * int64_t(dx);
+ int64_t ex = int64_t(p1(0) - ix*m_resolution) * int64_t(dy);
+ if (p1(1) < p2(1)) {
+ int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
do {
assert(ix >= ixb && iy <= iyb);
if (ex < ey) {
@@ -519,7 +519,7 @@ bool EdgeGrid::Grid::intersect(const MultiPoint &polyline, bool closed)
} while (ix != ixb || iy != iyb);
}
else {
- int64_t ey = int64_t(p1.y - iy*m_resolution) * int64_t(dx);
+ int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
do {
assert(ix >= ixb && iy >= iyb);
if (ex < ey) {
@@ -556,8 +556,8 @@ bool EdgeGrid::Grid::line_cell_intersect(const Point &p1a, const Point &p2a, con
{
BoundingBox bbox(p1a, p1a);
bbox.merge(p2a);
- int64_t va_x = p2a.x - p1a.x;
- int64_t va_y = p2a.y - p1a.y;
+ int64_t va_x = p2a(0) - p1a(0);
+ int64_t va_y = p2a(1) - p1a(1);
for (size_t i = cell.begin; i != cell.end; ++ i) {
const std::pair<size_t, size_t> &cell_data = m_cell_data[i];
// Contour indexed by the ith line of this cell.
@@ -576,21 +576,21 @@ bool EdgeGrid::Grid::line_cell_intersect(const Point &p1a, const Point &p2a, con
if (! bbox.overlap(bbox2))
continue;
// Now intersect the two line segments using exact arithmetics.
- int64_t w1_x = p1b.x - p1a.x;
- int64_t w1_y = p1b.y - p1a.y;
- int64_t w2_x = p2b.x - p1a.x;
- int64_t w2_y = p2b.y - p1a.y;
+ int64_t w1_x = p1b(0) - p1a(0);
+ int64_t w1_y = p1b(1) - p1a(1);
+ int64_t w2_x = p2b(0) - p1a(0);
+ int64_t w2_y = p2b(1) - p1a(1);
int64_t side1 = va_x * w1_y - va_y * w1_x;
int64_t side2 = va_x * w2_y - va_y * w2_x;
if (side1 == side2 && side1 != 0)
// The line segments don't intersect.
continue;
- w1_x = p1a.x - p1b.x;
- w1_y = p1a.y - p1b.y;
- w2_x = p2a.x - p1b.x;
- w2_y = p2a.y - p1b.y;
- int64_t vb_x = p2b.x - p1b.x;
- int64_t vb_y = p2b.y - p1b.y;
+ w1_x = p1a(0) - p1b(0);
+ w1_y = p1a(1) - p1b(1);
+ w2_x = p2a(0) - p1b(0);
+ w2_y = p2a(1) - p1b(1);
+ int64_t vb_x = p2b(0) - p1b(0);
+ int64_t vb_y = p2b(1) - p1b(1);
side1 = vb_x * w1_y - vb_y * w1_x;
side2 = vb_x * w2_y - vb_y * w2_x;
if (side1 == side2 && side1 != 0)
@@ -607,14 +607,14 @@ bool EdgeGrid::Grid::line_cell_intersect(const Point &p1a, const Point &p2a, con
bool EdgeGrid::Grid::inside(const Point &pt_src)
{
Point p = pt_src;
- p.x -= m_bbox.min.x;
- p.y -= m_bbox.min.y;
+ p(0) -= m_bbox.min(0);
+ p(1) -= m_bbox.min(1);
// Get the cell of the point.
- if (p.x < 0 || p.y < 0)
+ if (p(0) < 0 || p(1) < 0)
return false;
- coord_t ix = p.x / m_resolution;
- coord_t iy = p.y / m_resolution;
- if (ix >= m_cols || iy >= m_rows)
+ coord_t ix = p(0) / m_resolution;
+ coord_t iy = p(1) / m_resolution;
+ if (ix >= this->m_cols || iy >= this->m_rows)
return false;
size_t i_closest = (size_t)-1;
@@ -634,21 +634,21 @@ bool EdgeGrid::Grid::inside(const Point &pt_src)
idx2 = 0;
const Point &p1 = contour[idx1];
const Point &p2 = contour[idx2];
- if (p1.y < p2.y) {
- if (p.y < p1.y || p.y > p2.y)
+ if (p1(1) < p2(1)) {
+ if (p(1) < p1(1) || p(1) > p2(1))
continue;
//FIXME finish this!
int64_t vx = 0;// pt_src
//FIXME finish this!
int64_t det = 0;
- } else if (p1.y != p2.y) {
- assert(p1.y > p2.y);
- if (p.y < p2.y || p.y > p1.y)
+ } else if (p1(1) != p2(1)) {
+ assert(p1(1) > p2(1));
+ if (p(1) < p2(1) || p(1) > p1(1))
continue;
} else {
- assert(p1.y == p2.y);
- if (p1.y == p.y) {
- if (p.x >= p1.x && p.x <= p2.x)
+ assert(p1(1) == p2(1));
+ if (p1(1) == p(1)) {
+ if (p(0) >= p1(0) && p(0) <= p2(0))
// On the segment.
return true;
// Before or after the segment.
@@ -767,9 +767,9 @@ void EdgeGrid::Grid::calculate_sdf()
const Slic3r::Point &p1 = pts[ipt];
const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1];
// Segment vector
- const Slic3r::Point v_seg = p1.vector_to(p2);
+ const Slic3r::Point v_seg = p2 - p1;
// l2 of v_seg
- const int64_t l2_seg = int64_t(v_seg.x) * int64_t(v_seg.x) + int64_t(v_seg.y) * int64_t(v_seg.y);
+ const int64_t l2_seg = int64_t(v_seg(0)) * int64_t(v_seg(0)) + int64_t(v_seg(1)) * int64_t(v_seg(1));
// For each corner of this cell and its 1 ring neighbours:
for (int corner_y = -1; corner_y < 3; ++ corner_y) {
coord_t corner_r = r + corner_y;
@@ -780,28 +780,28 @@ void EdgeGrid::Grid::calculate_sdf()
if (corner_c < 0 || corner_c >= ncols)
continue;
float &d_min = m_signed_distance_field[corner_r * ncols + corner_c];
- Slic3r::Point pt(m_bbox.min.x + corner_c * m_resolution, m_bbox.min.y + corner_r * m_resolution);
- Slic3r::Point v_pt = p1.vector_to(pt);
+ Slic3r::Point pt(m_bbox.min(0) + corner_c * m_resolution, m_bbox.min(1) + corner_r * m_resolution);
+ Slic3r::Point v_pt = pt - p1;
// dot(p2-p1, pt-p1)
- int64_t t_pt = int64_t(v_seg.x) * int64_t(v_pt.x) + int64_t(v_seg.y) * int64_t(v_pt.y);
+ int64_t t_pt = int64_t(v_seg(0)) * int64_t(v_pt(0)) + int64_t(v_seg(1)) * int64_t(v_pt(1));
if (t_pt < 0) {
// Closest to p1.
- double dabs = sqrt(int64_t(v_pt.x) * int64_t(v_pt.x) + int64_t(v_pt.y) * int64_t(v_pt.y));
+ double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1)));
if (dabs < d_min) {
// Previous point.
const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1];
- Slic3r::Point v_seg_prev = p0.vector_to(p1);
- int64_t t2_pt = int64_t(v_seg_prev.x) * int64_t(v_pt.x) + int64_t(v_seg_prev.y) * int64_t(v_pt.y);
+ Slic3r::Point v_seg_prev = p1 - p0;
+ int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1));
if (t2_pt > 0) {
// Inside the wedge between the previous and the next segment.
// Set the signum depending on whether the vertex is convex or reflex.
- int64_t det = int64_t(v_seg_prev.x) * int64_t(v_seg.y) - int64_t(v_seg_prev.y) * int64_t(v_seg.x);
+ int64_t det = int64_t(v_seg_prev(0)) * int64_t(v_seg(1)) - int64_t(v_seg_prev(1)) * int64_t(v_seg(0));
assert(det != 0);
d_min = dabs;
// Fill in an unsigned vector towards the zero iso surface.
float *l = &L[(corner_r * ncols + corner_c) << 1];
- l[0] = std::abs(v_pt.x);
- l[1] = std::abs(v_pt.y);
+ l[0] = std::abs(v_pt(0));
+ l[1] = std::abs(v_pt(1));
#ifdef _DEBUG
double dabs2 = sqrt(l[0]*l[0]+l[1]*l[1]);
assert(std::abs(dabs-dabs2) < 1e-4 * std::max(dabs, dabs2));
@@ -816,7 +816,7 @@ void EdgeGrid::Grid::calculate_sdf()
} else {
// Closest to the segment.
assert(t_pt >= 0 && t_pt <= l2_seg);
- int64_t d_seg = int64_t(v_seg.y) * int64_t(v_pt.x) - int64_t(v_seg.x) * int64_t(v_pt.y);
+ int64_t d_seg = int64_t(v_seg(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1));
double d = double(d_seg) / sqrt(double(l2_seg));
double dabs = std::abs(d);
if (dabs < d_min) {
@@ -824,8 +824,8 @@ void EdgeGrid::Grid::calculate_sdf()
// Fill in an unsigned vector towards the zero iso surface.
float *l = &L[(corner_r * ncols + corner_c) << 1];
float linv = float(d_seg) / float(l2_seg);
- l[0] = std::abs(float(v_seg.y) * linv);
- l[1] = std::abs(float(v_seg.x) * linv);
+ l[0] = std::abs(float(v_seg(1)) * linv);
+ l[1] = std::abs(float(v_seg(0)) * linv);
#ifdef _DEBUG
double dabs2 = sqrt(l[0]*l[0]+l[1]*l[1]);
assert(std::abs(dabs-dabs2) <= 1e-4 * std::max(dabs, dabs2));
@@ -1059,8 +1059,8 @@ void EdgeGrid::Grid::calculate_sdf()
float EdgeGrid::Grid::signed_distance_bilinear(const Point &pt) const
{
- coord_t x = pt.x - m_bbox.min.x;
- coord_t y = pt.y - m_bbox.min.y;
+ coord_t x = pt(0) - m_bbox.min(0);
+ coord_t y = pt(1) - m_bbox.min(1);
coord_t w = m_resolution * m_cols;
coord_t h = m_resolution * m_rows;
bool clamped = false;
@@ -1124,39 +1124,39 @@ float EdgeGrid::Grid::signed_distance_bilinear(const Point &pt) const
bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment) const {
BoundingBox bbox;
- bbox.min = bbox.max = Point(pt.x - m_bbox.min.x, pt.y - m_bbox.min.y);
+ bbox.min = bbox.max = Point(pt(0) - m_bbox.min(0), pt(1) - m_bbox.min(1));
bbox.defined = true;
// Upper boundary, round to grid and test validity.
- bbox.max.x += search_radius;
- bbox.max.y += search_radius;
- if (bbox.max.x < 0 || bbox.max.y < 0)
+ bbox.max(0) += search_radius;
+ bbox.max(1) += search_radius;
+ if (bbox.max(0) < 0 || bbox.max(1) < 0)
return false;
- bbox.max.x /= m_resolution;
- bbox.max.y /= m_resolution;
- if (bbox.max.x >= m_cols)
- bbox.max.x = m_cols - 1;
- if (bbox.max.y >= m_rows)
- bbox.max.y = m_rows - 1;
+ bbox.max(0) /= m_resolution;
+ bbox.max(1) /= m_resolution;
+ if (bbox.max(0) >= m_cols)
+ bbox.max(0) = m_cols - 1;
+ if (bbox.max(1) >= m_rows)
+ bbox.max(1) = m_rows - 1;
// Lower boundary, round to grid and test validity.
- bbox.min.x -= search_radius;
- bbox.min.y -= search_radius;
- if (bbox.min.x < 0)
- bbox.min.x = 0;
- if (bbox.min.y < 0)
- bbox.min.y = 0;
- bbox.min.x /= m_resolution;
- bbox.min.y /= m_resolution;
+ bbox.min(0) -= search_radius;
+ bbox.min(1) -= search_radius;
+ if (bbox.min(0) < 0)
+ bbox.min(0) = 0;
+ if (bbox.min(1) < 0)
+ bbox.min(1) = 0;
+ bbox.min(0) /= m_resolution;
+ bbox.min(1) /= m_resolution;
// Is the interval empty?
- if (bbox.min.x > bbox.max.x ||
- bbox.min.y > bbox.max.y)
+ if (bbox.min(0) > bbox.max(0) ||
+ bbox.min(1) > bbox.max(1))
return false;
// Traverse all cells in the bounding box.
float d_min = search_radius;
// Signum of the distance field at pt.
int sign_min = 0;
bool on_segment = false;
- for (int r = bbox.min.y; r <= bbox.max.y; ++ r) {
- for (int c = bbox.min.x; c <= bbox.max.x; ++ c) {
+ for (int r = bbox.min(1); r <= bbox.max(1); ++ r) {
+ for (int c = bbox.min(0); c <= bbox.max(0); ++ c) {
const Cell &cell = m_cells[r * m_cols + c];
for (size_t i = cell.begin; i < cell.end; ++ i) {
const Slic3r::Points &pts = *m_contours[m_cell_data[i].first];
@@ -1164,25 +1164,25 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu
// End points of the line segment.
const Slic3r::Point &p1 = pts[ipt];
const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1];
- Slic3r::Point v_seg = p1.vector_to(p2);
- Slic3r::Point v_pt = p1.vector_to(pt);
+ Slic3r::Point v_seg = p2 - p1;
+ Slic3r::Point v_pt = pt - p1;
// dot(p2-p1, pt-p1)
- int64_t t_pt = int64_t(v_seg.x) * int64_t(v_pt.x) + int64_t(v_seg.y) * int64_t(v_pt.y);
+ int64_t t_pt = int64_t(v_seg(0)) * int64_t(v_pt(0)) + int64_t(v_seg(1)) * int64_t(v_pt(1));
// l2 of seg
- int64_t l2_seg = int64_t(v_seg.x) * int64_t(v_seg.x) + int64_t(v_seg.y) * int64_t(v_seg.y);
+ int64_t l2_seg = int64_t(v_seg(0)) * int64_t(v_seg(0)) + int64_t(v_seg(1)) * int64_t(v_seg(1));
if (t_pt < 0) {
// Closest to p1.
- double dabs = sqrt(int64_t(v_pt.x) * int64_t(v_pt.x) + int64_t(v_pt.y) * int64_t(v_pt.y));
+ double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1)));
if (dabs < d_min) {
// Previous point.
const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1];
- Slic3r::Point v_seg_prev = p0.vector_to(p1);
- int64_t t2_pt = int64_t(v_seg_prev.x) * int64_t(v_pt.x) + int64_t(v_seg_prev.y) * int64_t(v_pt.y);
+ Slic3r::Point v_seg_prev = p1 - p0;
+ int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1));
if (t2_pt > 0) {
// Inside the wedge between the previous and the next segment.
d_min = dabs;
// Set the signum depending on whether the vertex is convex or reflex.
- int64_t det = int64_t(v_seg_prev.x) * int64_t(v_seg.y) - int64_t(v_seg_prev.y) * int64_t(v_seg.x);
+ int64_t det = int64_t(v_seg_prev(0)) * int64_t(v_seg(1)) - int64_t(v_seg_prev(1)) * int64_t(v_seg(0));
assert(det != 0);
sign_min = (det > 0) ? 1 : -1;
on_segment = false;
@@ -1195,7 +1195,7 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu
} else {
// Closest to the segment.
assert(t_pt >= 0 && t_pt <= l2_seg);
- int64_t d_seg = int64_t(v_seg.y) * int64_t(v_pt.x) - int64_t(v_seg.x) * int64_t(v_pt.y);
+ int64_t d_seg = int64_t(v_seg(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1));
double d = double(d_seg) / sqrt(double(l2_seg));
double dabs = std::abs(d);
if (dabs < d_min) {
@@ -1307,7 +1307,7 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset) const
const Line &line_next = lines[it->second];
const Vector v1 = line_current.vector();
const Vector v2 = line_next.vector();
- int64_t cross = int64_t(v1.x) * int64_t(v2.y) - int64_t(v2.x) * int64_t(v1.y);
+ int64_t cross = int64_t(v1(0)) * int64_t(v2(1)) - int64_t(v2(0)) * int64_t(v1(1));
if (cross > 0) {
// This has to be a convex right angle. There is no better next line.
i_next = it->second;
@@ -1328,10 +1328,10 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset) const
Polygon &poly = out[i];
for (size_t j = 0; j < poly.points.size(); ++ j) {
Point &p = poly.points[j];
- p.x *= m_resolution;
- p.y *= m_resolution;
- p.x += m_bbox.min.x;
- p.y += m_bbox.min.y;
+ p(0) *= m_resolution;
+ p(1) *= m_resolution;
+ p(0) += m_bbox.min(0);
+ p(1) += m_bbox.min(1);
}
// Shrink the contour slightly, so if the same contour gets discretized and simplified again, one will get the same result.
// Remove collineaer points.
@@ -1341,11 +1341,11 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset) const
size_t j0 = (j == 0) ? poly.points.size() - 1 : j - 1;
size_t j2 = (j + 1 == poly.points.size()) ? 0 : j + 1;
Point v = poly.points[j2] - poly.points[j0];
- if (v.x != 0 && v.y != 0) {
+ if (v(0) != 0 && v(1) != 0) {
// This is a corner point. Copy it to the output contour.
Point p = poly.points[j];
- p.y += (v.x < 0) ? - offset : offset;
- p.x += (v.y > 0) ? - offset : offset;
+ p(1) += (v(0) < 0) ? - offset : offset;
+ p(0) += (v(1) > 0) ? - offset : offset;
pts.push_back(p);
}
}
@@ -1357,8 +1357,8 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset) const
#if 0
void EdgeGrid::save_png(const EdgeGrid::Grid &grid, const BoundingBox &bbox, coord_t resolution, const char *path)
{
- unsigned int w = (bbox.max.x - bbox.min.x + resolution - 1) / resolution;
- unsigned int h = (bbox.max.y - bbox.min.y + resolution - 1) / resolution;
+ unsigned int w = (bbox.max(0) - bbox.min(0) + resolution - 1) / resolution;
+ unsigned int h = (bbox.max(1) - bbox.min(1) + resolution - 1) / resolution;
wxImage img(w, h);
unsigned char *data = img.GetData();
memset(data, 0, w * h * 3);
@@ -1371,7 +1371,7 @@ void EdgeGrid::save_png(const EdgeGrid::Grid &grid, const BoundingBox &bbox, coo
for (coord_t r = 0; r < h; ++r) {
for (coord_t c = 0; c < w; ++ c) {
unsigned char *pxl = data + (((h - r - 1) * w) + c) * 3;
- Point pt(c * resolution + bbox.min.x, r * resolution + bbox.min.y);
+ Point pt(c * resolution + bbox.min(0), r * resolution + bbox.min(1));
coordf_t min_dist;
bool on_segment = true;
#if 0
@@ -1409,8 +1409,8 @@ void EdgeGrid::save_png(const EdgeGrid::Grid &grid, const BoundingBox &bbox, coo
pxl[2] = 0;
}
- float gridx = float(pt.x - grid.bbox().min.x) / float(grid.resolution());
- float gridy = float(pt.y - grid.bbox().min.y) / float(grid.resolution());
+ float gridx = float(pt(0) - grid.bbox().min(0)) / float(grid.resolution());
+ float gridy = float(pt(1) - grid.bbox().min(1)) / float(grid.resolution());
if (gridx >= -0.4f && gridy >= -0.4f && gridx <= grid.cols() + 0.4f && gridy <= grid.rows() + 0.4f) {
int ix = int(floor(gridx + 0.5f));
int iy = int(floor(gridy + 0.5f));
diff --git a/xs/src/libslic3r/ExPolygon.cpp b/xs/src/libslic3r/ExPolygon.cpp
index 1d4bac50b..4294fe543 100644
--- a/xs/src/libslic3r/ExPolygon.cpp
+++ b/xs/src/libslic3r/ExPolygon.cpp
@@ -34,54 +34,43 @@ ExPolygon::operator Polylines() const
return to_polylines(*this);
}
-void
-ExPolygon::scale(double factor)
+void ExPolygon::scale(double factor)
{
contour.scale(factor);
- for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
- (*it).scale(factor);
- }
+ for (Polygon &hole : holes)
+ hole.scale(factor);
}
-void
-ExPolygon::translate(double x, double y)
+void ExPolygon::translate(double x, double y)
{
contour.translate(x, y);
- for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
- (*it).translate(x, y);
- }
+ for (Polygon &hole : holes)
+ hole.translate(x, y);
}
-void
-ExPolygon::rotate(double angle)
+void ExPolygon::rotate(double angle)
{
contour.rotate(angle);
- for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
- (*it).rotate(angle);
- }
+ for (Polygon &hole : holes)
+ hole.rotate(angle);
}
-void
-ExPolygon::rotate(double angle, const Point &center)
+void ExPolygon::rotate(double angle, const Point &center)
{
contour.rotate(angle, center);
- for (Polygons::iterator it = holes.begin(); it != holes.end(); ++it) {
- (*it).rotate(angle, center);
- }
+ for (Polygon &hole : holes)
+ hole.rotate(angle, center);
}
-double
-ExPolygon::area() const
+double ExPolygon::area() const
{
double a = this->contour.area();
- for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
- a -= -(*it).area(); // holes have negative area
- }
+ for (const Polygon &hole : holes)
+ a -= - hole.area(); // holes have negative area
return a;
}
-bool
-ExPolygon::is_valid() const
+bool ExPolygon::is_valid() const
{
if (!this->contour.is_valid() || !this->contour.is_counter_clockwise()) return false;
for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
@@ -90,20 +79,17 @@ ExPolygon::is_valid() const
return true;
}
-bool
-ExPolygon::contains(const Line &line) const
+bool ExPolygon::contains(const Line &line) const
{
- return this->contains((Polyline)line);
+ return this->contains(Polyline(line.a, line.b));
}
-bool
-ExPolygon::contains(const Polyline &polyline) const
+bool ExPolygon::contains(const Polyline &polyline) const
{
return diff_pl((Polylines)polyline, *this).empty();
}
-bool
-ExPolygon::contains(const Polylines &polylines) const
+bool ExPolygon::contains(const Polylines &polylines) const
{
#if 0
BoundingBox bbox = get_extents(polylines);
@@ -120,8 +106,7 @@ ExPolygon::contains(const Polylines &polylines) const
return pl_out.empty();
}
-bool
-ExPolygon::contains(const Point &point) const
+bool ExPolygon::contains(const Point &point) const
{
if (!this->contour.contains(point)) return false;
for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
@@ -131,8 +116,7 @@ ExPolygon::contains(const Point &point) const
}
// inclusive version of contains() that also checks whether point is on boundaries
-bool
-ExPolygon::contains_b(const Point &point) const
+bool ExPolygon::contains_b(const Point &point) const
{
return this->contains(point) || this->has_boundary_point(point);
}
@@ -168,52 +152,42 @@ ExPolygon::overlaps(const ExPolygon &other) const
return ! other.contour.points.empty() && this->contains_b(other.contour.points.front());
}
-void
-ExPolygon::simplify_p(double tolerance, Polygons* polygons) const
+void ExPolygon::simplify_p(double tolerance, Polygons* polygons) const
{
Polygons pp = this->simplify_p(tolerance);
polygons->insert(polygons->end(), pp.begin(), pp.end());
}
-Polygons
-ExPolygon::simplify_p(double tolerance) const
+Polygons ExPolygon::simplify_p(double tolerance) const
{
Polygons pp;
pp.reserve(this->holes.size() + 1);
-
// contour
{
Polygon p = this->contour;
p.points.push_back(p.points.front());
p.points = MultiPoint::_douglas_peucker(p.points, tolerance);
p.points.pop_back();
- pp.push_back(p);
+ pp.emplace_back(std::move(p));
}
-
// holes
- for (Polygons::const_iterator it = this->holes.begin(); it != this->holes.end(); ++it) {
- Polygon p = *it;
+ for (Polygon p : this->holes) {
p.points.push_back(p.points.front());
p.points = MultiPoint::_douglas_peucker(p.points, tolerance);
p.points.pop_back();
- pp.push_back(p);
+ pp.emplace_back(std::move(p));
}
- pp = simplify_polygons(pp);
- return pp;
+ return simplify_polygons(pp);
}
-ExPolygons
-ExPolygon::simplify(double tolerance) const
+ExPolygons ExPolygon::simplify(double tolerance) const
{
- Polygons pp = this->simplify_p(tolerance);
- return union_ex(pp);
+ return union_ex(this->simplify_p(tolerance));
}
-void
-ExPolygon::simplify(double tolerance, ExPolygons* expolygons) const
+void ExPolygon::simplify(double tolerance, ExPolygons* expolygons) const
{
- ExPolygons ep = this->simplify(tolerance);
- expolygons->insert(expolygons->end(), ep.begin(), ep.end());
+ append(*expolygons, this->simplify(tolerance));
}
void
@@ -253,25 +227,24 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl
Point new_front = polyline.points.front();
Point new_back = polyline.points.back();
if (polyline.endpoints.first && !this->has_boundary_point(new_front)) {
- Line line(polyline.points.front(), polyline.points[1]);
-
+ Vec2d p1 = polyline.points.front().cast<double>();
+ Vec2d p2 = polyline.points[1].cast<double>();
// prevent the line from touching on the other side, otherwise intersection() might return that solution
- if (polyline.points.size() == 2) line.b = line.midpoint();
-
- line.extend_start(max_width);
- (void)this->contour.intersection(line, &new_front);
+ if (polyline.points.size() == 2)
+ p2 = (p1 + p2) * 0.5;
+ // Extend the start of the segment.
+ p1 -= (p2 - p1).normalized() * max_width;
+ this->contour.intersection(Line(p1.cast<coord_t>(), p2.cast<coord_t>()), &new_front);
}
if (polyline.endpoints.second && !this->has_boundary_point(new_back)) {
- Line line(
- *(polyline.points.end() - 2),
- polyline.points.back()
- );
-
+ Vec2d p1 = (polyline.points.end() - 2)->cast<double>();
+ Vec2d p2 = polyline.points.back().cast<double>();
// prevent the line from touching on the other side, otherwise intersection() might return that solution
- if (polyline.points.size() == 2) line.a = line.midpoint();
- line.extend_end(max_width);
-
- (void)this->contour.intersection(line, &new_back);
+ if (polyline.points.size() == 2)
+ p1 = (p1 + p2) * 0.5;
+ // Extend the start of the segment.
+ p2 += (p2 - p1).normalized() * max_width;
+ this->contour.intersection(Line(p1.cast<coord_t>(), p2.cast<coord_t>()), &new_back);
}
polyline.points.front() = new_front;
polyline.points.back() = new_back;
@@ -304,14 +277,14 @@ ExPolygon::medial_axis(double max_width, double min_width, ThickPolylines* polyl
// find another polyline starting here
for (size_t j = i+1; j < pp.size(); ++j) {
ThickPolyline& other = pp[j];
- if (polyline.last_point().coincides_with(other.last_point())) {
+ if (polyline.last_point() == other.last_point()) {
other.reverse();
- } else if (polyline.first_point().coincides_with(other.last_point())) {
+ } else if (polyline.first_point() == other.last_point()) {
polyline.reverse();
other.reverse();
- } else if (polyline.first_point().coincides_with(other.first_point())) {
+ } else if (polyline.first_point() == other.first_point()) {
polyline.reverse();
- } else if (!polyline.last_point().coincides_with(other.first_point())) {
+ } else if (polyline.last_point() != other.first_point()) {
continue;
}
@@ -371,7 +344,7 @@ ExPolygon::get_trapezoids2(Polygons* polygons) const
std::vector<coord_t> xx;
xx.reserve(pp.size());
for (Points::const_iterator p = pp.begin(); p != pp.end(); ++p)
- xx.push_back(p->x);
+ xx.push_back(p->x());
std::sort(xx.begin(), xx.end());
// find trapezoids by looping from first to next-to-last coordinate
@@ -382,14 +355,14 @@ ExPolygon::get_trapezoids2(Polygons* polygons) const
// build rectangle
Polygon poly;
poly.points.resize(4);
- poly[0].x = *x;
- poly[0].y = bb.min.y;
- poly[1].x = next_x;
- poly[1].y = bb.min.y;
- poly[2].x = next_x;
- poly[2].y = bb.max.y;
- poly[3].x = *x;
- poly[3].y = bb.max.y;
+ poly[0](0) = *x;
+ poly[0](1) = bb.min(1);
+ poly[1](0) = next_x;
+ poly[1](1) = bb.min(1);
+ poly[2](0) = next_x;
+ poly[2](1) = bb.max(1);
+ poly[3](0) = *x;
+ poly[3](1) = bb.max(1);
// intersect with this expolygon
// append results to return value
@@ -435,10 +408,11 @@ ExPolygon::triangulate_pp(Polygons* polygons) const
TPPLPoly p;
p.Init(int(ex->contour.points.size()));
//printf(PRINTF_ZU "\n0\n", ex->contour.points.size());
- for (Points::const_iterator point = ex->contour.points.begin(); point != ex->contour.points.end(); ++point) {
- p[ point-ex->contour.points.begin() ].x = point->x;
- p[ point-ex->contour.points.begin() ].y = point->y;
- //printf("%ld %ld\n", point->x, point->y);
+ for (const Point &point : ex->contour.points) {
+ size_t i = &point - &ex->contour.points.front();
+ p[i].x = point(0);
+ p[i].y = point(1);
+ //printf("%ld %ld\n", point->x(), point->y());
}
p.SetHole(false);
input.push_back(p);
@@ -449,10 +423,11 @@ ExPolygon::triangulate_pp(Polygons* polygons) const
TPPLPoly p;
p.Init(hole->points.size());
//printf(PRINTF_ZU "\n1\n", hole->points.size());
- for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) {
- p[ point-hole->points.begin() ].x = point->x;
- p[ point-hole->points.begin() ].y = point->y;
- //printf("%ld %ld\n", point->x, point->y);
+ for (const Point &point : hole->points) {
+ size_t i = &point - &hole->points.front();
+ p[i].x = point(0);
+ p[i].y = point(1);
+ //printf("%ld %ld\n", point->x(), point->y());
}
p.SetHole(true);
input.push_back(p);
@@ -470,8 +445,8 @@ ExPolygon::triangulate_pp(Polygons* polygons) const
Polygon p;
p.points.resize(num_points);
for (long i = 0; i < num_points; ++i) {
- p.points[i].x = coord_t((*poly)[i].x);
- p.points[i].y = coord_t((*poly)[i].y);
+ p.points[i](0) = coord_t((*poly)[i].x);
+ p.points[i](1) = coord_t((*poly)[i].y);
}
polygons->push_back(p);
}
@@ -487,19 +462,17 @@ ExPolygon::triangulate_p2t(Polygons* polygons) const
// contour
std::vector<p2t::Point*> ContourPoints;
- for (Points::const_iterator point = ex->contour.points.begin(); point != ex->contour.points.end(); ++point) {
+ for (const Point &pt : ex->contour.points)
// We should delete each p2t::Point object
- ContourPoints.push_back(new p2t::Point(point->x, point->y));
- }
+ ContourPoints.push_back(new p2t::Point(pt(0), pt(1)));
p2t::CDT cdt(ContourPoints);
// holes
for (Polygons::const_iterator hole = ex->holes.begin(); hole != ex->holes.end(); ++hole) {
std::vector<p2t::Point*> points;
- for (Points::const_iterator point = hole->points.begin(); point != hole->points.end(); ++point) {
+ for (const Point &pt : hole->points)
// will be destructed in SweepContext::~SweepContext
- points.push_back(new p2t::Point(point->x, point->y));
- }
+ points.push_back(new p2t::Point(pt(0), pt(1)));
cdt.AddHole(points);
}
@@ -516,9 +489,8 @@ ExPolygon::triangulate_p2t(Polygons* polygons) const
polygons->push_back(p);
}
- for(std::vector<p2t::Point*>::iterator it = ContourPoints.begin(); it != ContourPoints.end(); ++it) {
- delete *it;
- }
+ for (p2t::Point *ptr : ContourPoints)
+ delete ptr;
}
}
@@ -533,17 +505,6 @@ ExPolygon::lines() const
return lines;
}
-std::string
-ExPolygon::dump_perl() const
-{
- std::ostringstream ret;
- ret << "[" << this->contour.dump_perl();
- for (Polygons::const_iterator h = this->holes.begin(); h != this->holes.end(); ++h)
- ret << "," << h->dump_perl();
- ret << "]";
- return ret.str();
-}
-
BoundingBox get_extents(const ExPolygon &expolygon)
{
return get_extents(expolygon.contour);
diff --git a/xs/src/libslic3r/ExPolygon.hpp b/xs/src/libslic3r/ExPolygon.hpp
index f4782ba55..4833ee49e 100644
--- a/xs/src/libslic3r/ExPolygon.hpp
+++ b/xs/src/libslic3r/ExPolygon.hpp
@@ -63,7 +63,6 @@ public:
void triangulate_pp(Polygons* polygons) const;
void triangulate_p2t(Polygons* polygons) const;
Lines lines() const;
- std::string dump_perl() const;
};
// Count a nuber of polygons stored inside the vector of expolygons.
diff --git a/xs/src/libslic3r/ExtrusionEntity.cpp b/xs/src/libslic3r/ExtrusionEntity.cpp
index c6f67b169..92f0d3669 100644
--- a/xs/src/libslic3r/ExtrusionEntity.cpp
+++ b/xs/src/libslic3r/ExtrusionEntity.cpp
@@ -220,7 +220,7 @@ void ExtrusionLoop::split_at(const Point &point, bool prefer_non_overhang)
double min_non_overhang = std::numeric_limits<double>::max();
for (ExtrusionPaths::const_iterator path = this->paths.begin(); path != this->paths.end(); ++path) {
Point p_tmp = point.projection_onto(path->polyline);
- double dist = point.distance_to(p_tmp);
+ double dist = (p_tmp - point).cast<double>().norm();
if (dist < min) {
p = p_tmp;
min = dist;
diff --git a/xs/src/libslic3r/ExtrusionEntity.hpp b/xs/src/libslic3r/ExtrusionEntity.hpp
index 9d34aced8..2bd03600c 100644
--- a/xs/src/libslic3r/ExtrusionEntity.hpp
+++ b/xs/src/libslic3r/ExtrusionEntity.hpp
@@ -92,6 +92,7 @@ public:
virtual double min_mm3_per_mm() const = 0;
virtual Polyline as_polyline() const = 0;
virtual double length() const = 0;
+ virtual double total_volume() const = 0;
};
typedef std::vector<ExtrusionEntity*> ExtrusionEntitiesPtr;
@@ -148,6 +149,7 @@ public:
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
double min_mm3_per_mm() const { return this->mm3_per_mm; }
Polyline as_polyline() const { return this->polyline; }
+ virtual double total_volume() const { return mm3_per_mm * unscale<double>(length()); }
private:
void _inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const;
@@ -194,6 +196,7 @@ public:
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
double min_mm3_per_mm() const;
Polyline as_polyline() const;
+ virtual double total_volume() const { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
};
// Single continuous extrusion loop, possibly with varying extrusion thickness, extrusion height or bridging / non bridging.
@@ -241,6 +244,7 @@ public:
// Minimum volumetric velocity of this extrusion entity. Used by the constant nozzle pressure algorithm.
double min_mm3_per_mm() const;
Polyline as_polyline() const { return this->polygon().split_at_first_point(); }
+ virtual double total_volume() const { double volume =0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
private:
ExtrusionLoopRole m_loop_role;
diff --git a/xs/src/libslic3r/ExtrusionEntityCollection.cpp b/xs/src/libslic3r/ExtrusionEntityCollection.cpp
index 4513139e2..7a086bcbf 100644
--- a/xs/src/libslic3r/ExtrusionEntityCollection.cpp
+++ b/xs/src/libslic3r/ExtrusionEntityCollection.cpp
@@ -125,6 +125,7 @@ void ExtrusionEntityCollection::chained_path_from(Point start_near, ExtrusionEnt
continue;
}
}
+
ExtrusionEntity* entity = (*it)->clone();
my_paths.push_back(entity);
if (orig_indices != NULL) indices_map[entity] = it - this->entities.begin();
diff --git a/xs/src/libslic3r/ExtrusionEntityCollection.hpp b/xs/src/libslic3r/ExtrusionEntityCollection.hpp
index 03bd2ba97..3b34145f8 100644
--- a/xs/src/libslic3r/ExtrusionEntityCollection.hpp
+++ b/xs/src/libslic3r/ExtrusionEntityCollection.hpp
@@ -50,10 +50,15 @@ public:
src.clear();
}
}
- void append(const ExtrusionPaths &paths) {
+ void append(const ExtrusionPaths &paths) {
this->entities.reserve(this->entities.size() + paths.size());
- for (ExtrusionPaths::const_iterator path = paths.begin(); path != paths.end(); ++path)
- this->entities.push_back(path->clone());
+ for (const ExtrusionPath &path : paths)
+ this->entities.emplace_back(path.clone());
+ }
+ void append(ExtrusionPaths &&paths) {
+ this->entities.reserve(this->entities.size() + paths.size());
+ for (ExtrusionPath &path : paths)
+ this->entities.emplace_back(new ExtrusionPath(std::move(path)));
}
void replace(size_t i, const ExtrusionEntity &entity);
void remove(size_t i);
@@ -79,6 +84,7 @@ public:
void flatten(ExtrusionEntityCollection* retval) const;
ExtrusionEntityCollection flatten() const;
double min_mm3_per_mm() const;
+ virtual double total_volume() const {double volume=0.; for (const auto& ent : entities) volume+=ent->total_volume(); return volume; }
// Following methods shall never be called on an ExtrusionEntityCollection.
Polyline as_polyline() const {
diff --git a/xs/src/libslic3r/ExtrusionSimulator.cpp b/xs/src/libslic3r/ExtrusionSimulator.cpp
index daecbc0d1..fcb2fe825 100644
--- a/xs/src/libslic3r/ExtrusionSimulator.cpp
+++ b/xs/src/libslic3r/ExtrusionSimulator.cpp
@@ -893,24 +893,24 @@ ExtrusionSimulator::~ExtrusionSimulator()
void ExtrusionSimulator::set_image_size(const Point &image_size)
{
// printf("ExtrusionSimulator::set_image_size()\n");
- if (this->image_size.x == image_size.x &&
- this->image_size.y == image_size.y)
+ if (this->image_size.x() == image_size.x() &&
+ this->image_size.y() == image_size.y())
return;
// printf("Setting image size: %d, %d\n", image_size.x, image_size.y);
this->image_size = image_size;
// Allocate the image data in an RGBA format.
// printf("Allocating image data, size %d\n", image_size.x * image_size.y * 4);
- pimpl->image_data.assign(image_size.x * image_size.y * 4, 0);
+ pimpl->image_data.assign(image_size.x() * image_size.y() * 4, 0);
// printf("Allocating image data, allocated\n");
//FIXME fill the image with red vertical lines.
- for (size_t r = 0; r < image_size.y; ++ r) {
- for (size_t c = 0; c < image_size.x; c += 2) {
+ for (size_t r = 0; r < image_size.y(); ++ r) {
+ for (size_t c = 0; c < image_size.x(); c += 2) {
// Color red
- pimpl->image_data[r * image_size.x * 4 + c * 4] = 255;
+ pimpl->image_data[r * image_size.x() * 4 + c * 4] = 255;
// Opacity full
- pimpl->image_data[r * image_size.x * 4 + c * 4 + 3] = 255;
+ pimpl->image_data[r * image_size.x() * 4 + c * 4 + 3] = 255;
}
}
// printf("Allocating image data, set\n");
@@ -922,8 +922,8 @@ void ExtrusionSimulator::set_viewport(const BoundingBox &viewport)
if (this->viewport != viewport) {
this->viewport = viewport;
Point sz = viewport.size();
- pimpl->accumulator.resize(boost::extents[sz.y][sz.x]);
- pimpl->bitmap.resize(boost::extents[sz.y*pimpl->bitmap_oversampled][sz.x*pimpl->bitmap_oversampled]);
+ pimpl->accumulator.resize(boost::extents[sz.y()][sz.x()]);
+ pimpl->bitmap.resize(boost::extents[sz.y()*pimpl->bitmap_oversampled][sz.x()*pimpl->bitmap_oversampled]);
// printf("Accumulator size: %d, %d\n", sz.y, sz.x);
}
}
@@ -943,8 +943,8 @@ void ExtrusionSimulator::reset_accumulator()
// printf("ExtrusionSimulator::reset_accumulator()\n");
Point sz = viewport.size();
// printf("Reset accumulator, Accumulator size: %d, %d\n", sz.y, sz.x);
- memset(&pimpl->accumulator[0][0], 0, sizeof(float) * sz.x * sz.y);
- memset(&pimpl->bitmap[0][0], 0, sz.x * sz.y * pimpl->bitmap_oversampled * pimpl->bitmap_oversampled);
+ memset(&pimpl->accumulator[0][0], 0, sizeof(float) * sz.x() * sz.y());
+ memset(&pimpl->bitmap[0][0], 0, sz.x() * sz.y() * pimpl->bitmap_oversampled * pimpl->bitmap_oversampled);
pimpl->extrusion_points.clear();
// printf("Reset accumulator, done.\n");
}
@@ -955,17 +955,17 @@ void ExtrusionSimulator::extrude_to_accumulator(const ExtrusionPath &path, const
// Convert the path to V2f points, shift and scale them to the viewport.
std::vector<V2f> polyline;
polyline.reserve(path.polyline.points.size());
- float scalex = float(viewport.size().x) / float(bbox.size().x);
- float scaley = float(viewport.size().y) / float(bbox.size().y);
+ float scalex = float(viewport.size().x()) / float(bbox.size().x());
+ float scaley = float(viewport.size().y()) / float(bbox.size().y());
float w = scale_(path.width) * scalex;
float h = scale_(path.height) * scalex;
w = scale_(path.mm3_per_mm / path.height) * scalex;
// printf("scalex: %f, scaley: %f\n", scalex, scaley);
- // printf("bbox: %d,%d %d,%d\n", bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y);
+ // printf("bbox: %d,%d %d,%d\n", bbox.min.x(), bbox.min.y, bbox.max.x(), bbox.max.y);
for (Points::const_iterator it = path.polyline.points.begin(); it != path.polyline.points.end(); ++ it) {
- // printf("point %d,%d\n", it->x+shift.x, it->y+shift.y);
+ // printf("point %d,%d\n", it->x+shift.x(), it->y+shift.y);
ExtrusionPoint ept;
- ept.center = V2f(float(it->x+shift.x-bbox.min.x) * scalex, float(it->y+shift.y-bbox.min.y) * scaley);
+ ept.center = V2f(float((*it)(0)+shift.x()-bbox.min.x()) * scalex, float((*it)(1)+shift.y()-bbox.min.y()) * scaley);
ept.radius = w/2.f;
ept.height = 0.5f;
polyline.push_back(ept.center);
@@ -989,9 +989,9 @@ void ExtrusionSimulator::evaluate_accumulator(ExtrusionSimulationType simulation
if (simulationType > ExtrusionSimulationDontSpread) {
// Average the cells of a bitmap into a lower resolution floating point mask.
- A2f mask(boost::extents[sz.y][sz.x]);
- for (int r = 0; r < sz.y; ++r) {
- for (int c = 0; c < sz.x; ++c) {
+ A2f mask(boost::extents[sz.y()][sz.x()]);
+ for (int r = 0; r < sz.y(); ++r) {
+ for (int c = 0; c < sz.x(); ++c) {
float p = 0;
for (int j = 0; j < pimpl->bitmap_oversampled; ++ j) {
for (int i = 0; i < pimpl->bitmap_oversampled; ++ i) {
@@ -1009,9 +1009,9 @@ void ExtrusionSimulator::evaluate_accumulator(ExtrusionSimulationType simulation
}
// Color map the accumulator.
- for (int r = 0; r < sz.y; ++r) {
- unsigned char *ptr = &pimpl->image_data[(image_size.x * (viewport.min.y + r) + viewport.min.x) * 4];
- for (int c = 0; c < sz.x; ++c) {
+ for (int r = 0; r < sz.y(); ++r) {
+ unsigned char *ptr = &pimpl->image_data[(image_size.x() * (viewport.min.y() + r) + viewport.min.x()) * 4];
+ for (int c = 0; c < sz.x(); ++c) {
#if 1
float p = pimpl->accumulator[r][c];
#else
diff --git a/xs/src/libslic3r/FileParserError.hpp b/xs/src/libslic3r/FileParserError.hpp
new file mode 100644
index 000000000..3f560fa4f
--- /dev/null
+++ b/xs/src/libslic3r/FileParserError.hpp
@@ -0,0 +1,52 @@
+#ifndef slic3r_FileParserError_hpp_
+#define slic3r_FileParserError_hpp_
+
+#include "libslic3r.h"
+
+#include <string>
+#include <boost/filesystem/path.hpp>
+#include <stdexcept>
+
+namespace Slic3r {
+
+// Generic file parser error, mostly copied from boost::property_tree::file_parser_error
+class file_parser_error: public std::runtime_error
+{
+public:
+ file_parser_error(const std::string &msg, const std::string &file, unsigned long line = 0) :
+ std::runtime_error(format_what(msg, file, line)),
+ m_message(msg), m_filename(file), m_line(line) {}
+ file_parser_error(const std::string &msg, const boost::filesystem::path &file, unsigned long line = 0) :
+ std::runtime_error(format_what(msg, file.string(), line)),
+ m_message(msg), m_filename(file.string()), m_line(line) {}
+ // gcc 3.4.2 complains about lack of throw specifier on compiler
+ // generated dtor
+ ~file_parser_error() throw() {}
+
+ // Get error message (without line and file - use what() to get full message)
+ std::string message() const { return m_message; }
+ // Get error filename
+ std::string filename() const { return m_filename; }
+ // Get error line number
+ unsigned long line() const { return m_line; }
+
+private:
+ std::string m_message;
+ std::string m_filename;
+ unsigned long m_line;
+
+ // Format error message to be returned by std::runtime_error::what()
+ static std::string format_what(const std::string &msg, const std::string &file, unsigned long l)
+ {
+ std::stringstream stream;
+ stream << (file.empty() ? "<unspecified file>" : file.c_str());
+ if (l > 0)
+ stream << '(' << l << ')';
+ stream << ": " << msg;
+ return stream.str();
+ }
+};
+
+}; // Slic3r
+
+#endif // slic3r_FileParserError_hpp_
diff --git a/xs/src/libslic3r/Fill/Fill3DHoneycomb.cpp b/xs/src/libslic3r/Fill/Fill3DHoneycomb.cpp
index aa9774784..6a37e4369 100644
--- a/xs/src/libslic3r/Fill/Fill3DHoneycomb.cpp
+++ b/xs/src/libslic3r/Fill/Fill3DHoneycomb.cpp
@@ -54,9 +54,9 @@ static std::vector<coordf_t> perpendPoints(const coordf_t offset, const size_t b
// components that are outside these limits are set to the limits.
static inline void trim(Pointfs &pts, coordf_t minX, coordf_t minY, coordf_t maxX, coordf_t maxY)
{
- for (Pointfs::iterator it = pts.begin(); it != pts.end(); ++ it) {
- it->x = clamp(minX, maxX, it->x);
- it->y = clamp(minY, maxY, it->y);
+ for (Vec2d &pt : pts) {
+ pt(0) = clamp(minX, maxX, pt(0));
+ pt(1) = clamp(minY, maxY, pt(1));
}
}
@@ -66,7 +66,7 @@ static inline Pointfs zip(const std::vector<coordf_t> &x, const std::vector<coor
Pointfs out;
out.reserve(x.size());
for (size_t i = 0; i < x.size(); ++ i)
- out.push_back(Pointf(x[i], y[i]));
+ out.push_back(Vec2d(x[i], y[i]));
return out;
}
@@ -128,7 +128,7 @@ static Polylines makeGrid(coord_t z, coord_t gridSize, size_t gridWidth, size_t
result.push_back(Polyline());
Polyline &polyline = result.back();
for (Pointfs::const_iterator it = it_polylines->begin(); it != it_polylines->end(); ++ it)
- polyline.points.push_back(Point(coord_t(it->x * scaleFactor), coord_t(it->y * scaleFactor)));
+ polyline.points.push_back(Point(coord_t((*it)(0) * scaleFactor), coord_t((*it)(1) * scaleFactor)));
}
return result;
}
@@ -153,13 +153,13 @@ void Fill3DHoneycomb::_fill_surface_single(
Polylines polylines = makeGrid(
scale_(this->z),
distance,
- ceil(bb.size().x / distance) + 1,
- ceil(bb.size().y / distance) + 1,
+ ceil(bb.size()(0) / distance) + 1,
+ ceil(bb.size()(1) / distance) + 1,
((this->layer_id/thickness_layers) % 2) + 1);
// move pattern in place
for (Polylines::iterator it = polylines.begin(); it != polylines.end(); ++ it)
- it->translate(bb.min.x, bb.min.y);
+ it->translate(bb.min(0), bb.min(1));
// clip pattern to boundaries
polylines = intersection_pl(polylines, (Polygons)expolygon);
@@ -187,7 +187,7 @@ void Fill3DHoneycomb::_fill_surface_single(
const Point &last_point = pts_end.back();
// TODO: we should also check that both points are on a fill_boundary to avoid
// connecting paths on the boundaries of internal regions
- if (first_point.distance_to(last_point) <= 1.5 * distance &&
+ if ((last_point - first_point).cast<double>().norm() <= 1.5 * distance &&
expolygon_off.contains(Line(last_point, first_point))) {
// Append the polyline.
pts_end.insert(pts_end.end(), it_polyline->points.begin(), it_polyline->points.end());
diff --git a/xs/src/libslic3r/Fill/FillBase.hpp b/xs/src/libslic3r/Fill/FillBase.hpp
index 62d18e518..b67d14339 100644
--- a/xs/src/libslic3r/Fill/FillBase.hpp
+++ b/xs/src/libslic3r/Fill/FillBase.hpp
@@ -121,11 +121,11 @@ public:
return aligned;
}
static Point _align_to_grid(Point coord, Point spacing)
- { return Point(_align_to_grid(coord.x, spacing.x), _align_to_grid(coord.y, spacing.y)); }
+ { return Point(_align_to_grid(coord(0), spacing(0)), _align_to_grid(coord(1), spacing(1))); }
static coord_t _align_to_grid(coord_t coord, coord_t spacing, coord_t base)
{ return base + _align_to_grid(coord - base, spacing); }
static Point _align_to_grid(Point coord, Point spacing, Point base)
- { return Point(_align_to_grid(coord.x, spacing.x, base.x), _align_to_grid(coord.y, spacing.y, base.y)); }
+ { return Point(_align_to_grid(coord(0), spacing(0), base(0)), _align_to_grid(coord(1), spacing(1), base(1))); }
};
} // namespace Slic3r
diff --git a/xs/src/libslic3r/Fill/FillConcentric.cpp b/xs/src/libslic3r/Fill/FillConcentric.cpp
index b21ad2799..8a3a7ea89 100644
--- a/xs/src/libslic3r/Fill/FillConcentric.cpp
+++ b/xs/src/libslic3r/Fill/FillConcentric.cpp
@@ -20,8 +20,8 @@ void FillConcentric::_fill_surface_single(
coord_t distance = coord_t(min_spacing / params.density);
if (params.density > 0.9999f && !params.dont_adjust) {
- distance = this->_adjust_solid_spacing(bounding_box.size().x, distance);
- this->spacing = unscale(distance);
+ distance = this->_adjust_solid_spacing(bounding_box.size()(0), distance);
+ this->spacing = unscale<double>(distance);
}
Polygons loops = (Polygons)expolygon;
diff --git a/xs/src/libslic3r/Fill/FillGyroid.cpp b/xs/src/libslic3r/Fill/FillGyroid.cpp
index e63ce0bfd..d6bf03ce6 100644
--- a/xs/src/libslic3r/Fill/FillGyroid.cpp
+++ b/xs/src/libslic3r/Fill/FillGyroid.cpp
@@ -9,74 +9,117 @@
namespace Slic3r {
-static inline Polyline make_wave_vertical(
- double width, double height, double x0,
- double segmentSize, double scaleFactor,
- double z_cos, double z_sin, bool flip)
+static inline double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
{
- Polyline polyline;
- polyline.points.emplace_back(Point(coord_t(clamp(0., width, x0) * scaleFactor), 0));
- double phase_offset_sin = (z_cos < 0 ? M_PI : 0) + M_PI;
- double phase_offset_cos = (z_cos < 0 ? M_PI : 0) + M_PI + (flip ? M_PI : 0.);
- for (double y = 0.; y < height + segmentSize; y += segmentSize) {
- y = std::min(y, height);
- double a = sin(y + phase_offset_sin);
+ if (vertical) {
+ double phase_offset = (z_cos < 0 ? M_PI : 0) + M_PI;
+ double a = sin(x + phase_offset);
double b = - z_cos;
- double res = z_sin * cos(y + phase_offset_cos);
+ double res = z_sin * cos(x + phase_offset + (flip ? M_PI : 0.));
double r = sqrt(sqr(a) + sqr(b));
- double x = clamp(0., width, asin(a/r) + asin(res/r) + M_PI + x0);
- polyline.points.emplace_back(convert_to<Point>(Pointf(x, y) * scaleFactor));
+ return asin(a/r) + asin(res/r) + M_PI;
+ }
+ else {
+ double phase_offset = z_sin < 0 ? M_PI : 0.;
+ double a = cos(x + phase_offset);
+ double b = - z_sin;
+ double res = z_cos * sin(x + phase_offset + (flip ? 0 : M_PI));
+ double r = sqrt(sqr(a) + sqr(b));
+ return (asin(a/r) + asin(res/r) + 0.5 * M_PI);
}
- if (flip)
- std::reverse(polyline.points.begin(), polyline.points.end());
- return polyline;
}
-static inline Polyline make_wave_horizontal(
- double width, double height, double y0,
- double segmentSize, double scaleFactor,
- double z_cos, double z_sin, bool flip)
+static inline Polyline make_wave(
+ const std::vector<Vec2d>& one_period, double width, double height, double offset, double scaleFactor,
+ double z_cos, double z_sin, bool vertical)
{
+ std::vector<Vec2d> points = one_period;
+ double period = points.back()(0);
+ points.pop_back();
+ int n = points.size();
+ do {
+ points.emplace_back(Vec2d(points[points.size()-n](0) + period, points[points.size()-n](1)));
+ } while (points.back()(0) < width);
+ points.back()(0) = width;
+
+ // and construct the final polyline to return:
Polyline polyline;
- polyline.points.emplace_back(Point(0, coord_t(clamp(0., height, y0) * scaleFactor)));
- double phase_offset_sin = (z_sin < 0 ? M_PI : 0) + (flip ? 0 : M_PI);
- double phase_offset_cos = z_sin < 0 ? M_PI : 0.;
- for (double x=0.; x < width + segmentSize; x += segmentSize) {
- x = std::min(x, width);
- double a = cos(x + phase_offset_cos);
- double b = - z_sin;
- double res = z_cos * sin(x + phase_offset_sin);
- double r = sqrt(sqr(a) + sqr(b));
- double y = clamp(0., height, asin(a/r) + asin(res/r) + 0.5 * M_PI + y0);
- polyline.points.emplace_back(convert_to<Point>(Pointf(x, y) * scaleFactor));
+ for (auto& point : points) {
+ point(1) += offset;
+ point(1) = clamp(0., height, double(point(1)));
+ if (vertical)
+ std::swap(point(0), point(1));
+ polyline.points.emplace_back((point * scaleFactor).cast<coord_t>());
}
- if (flip)
- std::reverse(polyline.points.begin(), polyline.points.end());
+
return polyline;
}
-static Polylines make_gyroid_waves(double gridZ, double density, double layer_width, double width, double height)
+static std::vector<Vec2d> make_one_period(double width, double scaleFactor, double z_cos, double z_sin, bool vertical, bool flip)
{
- double scaleFactor = scale_(layer_width) / density;
- double segmentSize = 0.5 * density;
+ std::vector<Vec2d> points;
+ double dx = M_PI_4; // very coarse spacing to begin with
+ double limit = std::min(2*M_PI, width);
+ for (double x = 0.; x < limit + EPSILON; x += dx) { // so the last point is there too
+ x = std::min(x, limit);
+ points.emplace_back(Vec2d(x,f(x, z_sin,z_cos, vertical, flip)));
+ }
+
+ // now we will check all internal points and in case some are too far from the line connecting its neighbours,
+ // we will add one more point on each side:
+ const double tolerance = .1;
+ for (unsigned int i=1;i<points.size()-1;++i) {
+ auto& lp = points[i-1]; // left point
+ auto& tp = points[i]; // this point
+ Vec2d lrv = tp - lp;
+ auto& rp = points[i+1]; // right point
+ // calculate distance of the point to the line:
+ double dist_mm = unscale<double>(scaleFactor) * std::abs(cross2(rp, lp) - cross2(rp - lp, tp)) / lrv.norm();
+ if (dist_mm > tolerance) { // if the difference from straight line is more than this
+ double x = 0.5f * (points[i-1](0) + points[i](0));
+ points.emplace_back(Vec2d(x, f(x, z_sin, z_cos, vertical, flip)));
+ x = 0.5f * (points[i+1](0) + points[i](0));
+ points.emplace_back(Vec2d(x, f(x, z_sin, z_cos, vertical, flip)));
+ // we added the points to the end, but need them all in order
+ std::sort(points.begin(), points.end(), [](const Vec2d &lhs, const Vec2d &rhs){ return lhs < rhs; });
+ // decrement i so we also check the first newly added point
+ --i;
+ }
+ }
+ return points;
+}
+
+static Polylines make_gyroid_waves(double gridZ, double density_adjusted, double line_spacing, double width, double height)
+{
+ const double scaleFactor = scale_(line_spacing) / density_adjusted;
//scale factor for 5% : 8 712 388
// 1z = 10^-6 mm ?
- double z = gridZ / scaleFactor;
- double z_sin = sin(z);
- double z_cos = cos(z);
- Polylines result;
- if (abs(z_sin) <= abs(z_cos)) {
- // Vertical wave
- double x0 = M_PI * (int)((- 0.5 * M_PI) / M_PI - 1.);
- bool flip = ((int)(x0 / M_PI + 1.) & 1) != 0;
- for (; x0 < width - 0.5 * M_PI; x0 += M_PI, flip = ! flip)
- result.emplace_back(make_wave_vertical(width, height, x0, segmentSize, scaleFactor, z_cos, z_sin, flip));
- } else {
- // Horizontal wave
- bool flip = true;
- for (double y0 = 0.; y0 < width; y0 += M_PI, flip = !flip)
- result.emplace_back(make_wave_horizontal(width, height, y0, segmentSize, scaleFactor, z_cos, z_sin, flip));
+ const double z = gridZ / scaleFactor;
+ const double z_sin = sin(z);
+ const double z_cos = cos(z);
+
+ bool vertical = (std::abs(z_sin) <= std::abs(z_cos));
+ double lower_bound = 0.;
+ double upper_bound = height;
+ bool flip = true;
+ if (vertical) {
+ flip = false;
+ lower_bound = -M_PI;
+ upper_bound = width - M_PI_2;
+ std::swap(width,height);
}
+
+ std::vector<Vec2d> one_period = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip); // creates one period of the waves, so it doesn't have to be recalculated all the time
+ Polylines result;
+
+ for (double y0 = lower_bound; y0 < upper_bound+EPSILON; y0 += 2*M_PI) // creates odd polylines
+ result.emplace_back(make_wave(one_period, width, height, y0, scaleFactor, z_cos, z_sin, vertical));
+
+ flip = !flip; // even polylines are a bit shifted
+ one_period = make_one_period(width, scaleFactor, z_cos, z_sin, vertical, flip); // updates the one period sample
+ for (double y0 = lower_bound + M_PI; y0 < upper_bound+EPSILON; y0 += 2*M_PI) // creates even polylines
+ result.emplace_back(make_wave(one_period, width, height, y0, scaleFactor, z_cos, z_sin, vertical));
+
return result;
}
@@ -87,24 +130,27 @@ void FillGyroid::_fill_surface_single(
ExPolygon &expolygon,
Polylines &polylines_out)
{
- // no rotation is supported for this infill pattern
+ // no rotation is supported for this infill pattern (yet)
BoundingBox bb = expolygon.contour.bounding_box();
- coord_t distance = coord_t(scale_(this->spacing) / (params.density*this->scaling));
+ // Density adjusted to have a good %of weight.
+ double density_adjusted = std::max(0., params.density * 2.);
+ // Distance between the gyroid waves in scaled coordinates.
+ coord_t distance = coord_t(scale_(this->spacing) / density_adjusted);
// align bounding box to a multiple of our grid module
- bb.merge(_align_to_grid(bb.min, Point(2*M_PI*distance, 2*M_PI*distance)));
-
+ bb.merge(_align_to_grid(bb.min, Point(2.*M_PI*distance, 2.*M_PI*distance)));
+
// generate pattern
Polylines polylines = make_gyroid_waves(
scale_(this->z),
- params.density*this->scaling,
+ density_adjusted,
this->spacing,
- ceil(bb.size().x / distance) + 1.,
- ceil(bb.size().y / distance) + 1.);
+ ceil(bb.size()(0) / distance) + 1.,
+ ceil(bb.size()(1) / distance) + 1.);
// move pattern in place
for (Polyline &polyline : polylines)
- polyline.translate(bb.min.x, bb.min.y);
+ polyline.translate(bb.min(0), bb.min(1));
// clip pattern to boundaries
polylines = intersection_pl(polylines, (Polygons)expolygon);
@@ -133,7 +179,7 @@ void FillGyroid::_fill_surface_single(
// TODO: we should also check that both points are on a fill_boundary to avoid
// connecting paths on the boundaries of internal regions
// TODO: avoid crossing current infill path
- if (first_point.distance_to(last_point) <= 5 * distance &&
+ if ((last_point - first_point).cast<double>().norm() <= 5 * distance &&
expolygon_off.contains(Line(last_point, first_point))) {
// Append the polyline.
pts_end.insert(pts_end.end(), polyline.points.begin(), polyline.points.end());
diff --git a/xs/src/libslic3r/Fill/FillGyroid.hpp b/xs/src/libslic3r/Fill/FillGyroid.hpp
index 758652a5c..17924b5ab 100644
--- a/xs/src/libslic3r/Fill/FillGyroid.hpp
+++ b/xs/src/libslic3r/Fill/FillGyroid.hpp
@@ -17,10 +17,6 @@ public:
virtual bool use_bridge_flow() const { return true; }
protected:
-
- // mult of density, to have a good %of weight for each density parameter
- float scaling = 1.75;
-
virtual void _fill_surface_single(
const FillParams &params,
unsigned int thickness_layers,
diff --git a/xs/src/libslic3r/Fill/FillHoneycomb.cpp b/xs/src/libslic3r/Fill/FillHoneycomb.cpp
index aa0e0f6b0..6f26167a2 100644
--- a/xs/src/libslic3r/Fill/FillHoneycomb.cpp
+++ b/xs/src/libslic3r/Fill/FillHoneycomb.cpp
@@ -50,13 +50,13 @@ void FillHoneycomb::_fill_surface_single(
bounding_box.merge(_align_to_grid(bounding_box.min, Point(m.hex_width, m.pattern_height)));
}
- coord_t x = bounding_box.min.x;
- while (x <= bounding_box.max.x) {
+ coord_t x = bounding_box.min(0);
+ while (x <= bounding_box.max(0)) {
Polygon p;
coord_t ax[2] = { x + m.x_offset, x + m.distance - m.x_offset };
for (size_t i = 0; i < 2; ++ i) {
std::reverse(p.points.begin(), p.points.end()); // turn first half upside down
- for (coord_t y = bounding_box.min.y; y <= bounding_box.max.y; y += m.y_short + m.hex_side + m.y_short + m.hex_side) {
+ for (coord_t y = bounding_box.min(1); y <= bounding_box.max(1); y += m.y_short + m.hex_side + m.y_short + m.hex_side) {
p.points.push_back(Point(ax[1], y + m.y_offset));
p.points.push_back(Point(ax[0], y + m.y_short - m.y_offset));
p.points.push_back(Point(ax[0], y + m.y_short + m.hex_side + m.y_offset));
@@ -101,7 +101,7 @@ void FillHoneycomb::_fill_surface_single(
for (Polylines::iterator it_path = chained.begin(); it_path != chained.end(); ++ it_path) {
if (! paths.empty()) {
// distance between first point of this path and last point of last path
- double distance = paths.back().last_point().distance_to(it_path->first_point());
+ double distance = (it_path->first_point() - paths.back().last_point()).cast<double>().norm();
if (distance <= m.hex_width) {
paths.back().points.insert(paths.back().points.end(), it_path->points.begin(), it_path->points.end());
continue;
diff --git a/xs/src/libslic3r/Fill/FillPlanePath.cpp b/xs/src/libslic3r/Fill/FillPlanePath.cpp
index f71ef95a1..615cc6efe 100644
--- a/xs/src/libslic3r/Fill/FillPlanePath.cpp
+++ b/xs/src/libslic3r/Fill/FillPlanePath.cpp
@@ -24,14 +24,14 @@ void FillPlanePath::_fill_surface_single(
Point shift = this->_centered() ?
bounding_box.center() :
bounding_box.min;
- expolygon.translate(-shift.x, -shift.y);
- bounding_box.translate(-shift.x, -shift.y);
+ expolygon.translate(-shift(0), -shift(1));
+ bounding_box.translate(-shift(0), -shift(1));
Pointfs pts = _generate(
- coord_t(ceil(coordf_t(bounding_box.min.x) / distance_between_lines)),
- coord_t(ceil(coordf_t(bounding_box.min.y) / distance_between_lines)),
- coord_t(ceil(coordf_t(bounding_box.max.x) / distance_between_lines)),
- coord_t(ceil(coordf_t(bounding_box.max.y) / distance_between_lines)));
+ coord_t(ceil(coordf_t(bounding_box.min(0)) / distance_between_lines)),
+ coord_t(ceil(coordf_t(bounding_box.min(1)) / distance_between_lines)),
+ coord_t(ceil(coordf_t(bounding_box.max(0)) / distance_between_lines)),
+ coord_t(ceil(coordf_t(bounding_box.max(1)) / distance_between_lines)));
Polylines polylines;
if (pts.size() >= 2) {
@@ -41,8 +41,8 @@ void FillPlanePath::_fill_surface_single(
polyline.points.reserve(pts.size());
for (Pointfs::iterator it = pts.begin(); it != pts.end(); ++ it)
polyline.points.push_back(Point(
- coord_t(floor(it->x * distance_between_lines + 0.5)),
- coord_t(floor(it->y * distance_between_lines + 0.5))));
+ coord_t(floor((*it)(0) * distance_between_lines + 0.5)),
+ coord_t(floor((*it)(1) * distance_between_lines + 0.5))));
// intersection(polylines_src, offset((Polygons)expolygon, scale_(0.02)), &polylines);
polylines = intersection_pl(polylines, to_polygons(expolygon));
@@ -62,7 +62,7 @@ void FillPlanePath::_fill_surface_single(
// paths must be repositioned and rotated back
for (Polylines::iterator it = polylines.begin(); it != polylines.end(); ++ it) {
- it->translate(shift.x, shift.y);
+ it->translate(shift(0), shift(1));
it->rotate(direction.first);
}
}
@@ -86,12 +86,12 @@ Pointfs FillArchimedeanChords::_generate(coord_t min_x, coord_t min_y, coord_t m
coordf_t r = 1;
Pointfs out;
//FIXME Vojtech: If used as a solid infill, there is a gap left at the center.
- out.push_back(Pointf(0, 0));
- out.push_back(Pointf(1, 0));
+ out.push_back(Vec2d(0, 0));
+ out.push_back(Vec2d(1, 0));
while (r < rmax) {
theta += 1. / r;
r = a + b * theta;
- out.push_back(Pointf(r * cos(theta), r * sin(theta)));
+ out.push_back(Vec2d(r * cos(theta), r * sin(theta)));
}
return out;
}
@@ -162,7 +162,7 @@ Pointfs FillHilbertCurve::_generate(coord_t min_x, coord_t min_y, coord_t max_x,
line.reserve(sz2);
for (size_t i = 0; i < sz2; ++ i) {
Point p = hilbert_n_to_xy(i);
- line.push_back(Pointf(p.x + min_x, p.y + min_y));
+ line.push_back(Vec2d(p(0) + min_x, p(1) + min_y));
}
return line;
}
@@ -175,27 +175,27 @@ Pointfs FillOctagramSpiral::_generate(coord_t min_x, coord_t min_y, coord_t max_
coordf_t r = 0;
coordf_t r_inc = sqrt(2.);
Pointfs out;
- out.push_back(Pointf(0, 0));
+ out.push_back(Vec2d(0, 0));
while (r < rmax) {
r += r_inc;
coordf_t rx = r / sqrt(2.);
coordf_t r2 = r + rx;
- out.push_back(Pointf( r, 0.));
- out.push_back(Pointf( r2, rx));
- out.push_back(Pointf( rx, rx));
- out.push_back(Pointf( rx, r2));
- out.push_back(Pointf(0., r));
- out.push_back(Pointf(-rx, r2));
- out.push_back(Pointf(-rx, rx));
- out.push_back(Pointf(-r2, rx));
- out.push_back(Pointf(-r, 0.));
- out.push_back(Pointf(-r2, -rx));
- out.push_back(Pointf(-rx, -rx));
- out.push_back(Pointf(-rx, -r2));
- out.push_back(Pointf(0., -r));
- out.push_back(Pointf( rx, -r2));
- out.push_back(Pointf( rx, -rx));
- out.push_back(Pointf( r2+r_inc, -rx));
+ out.push_back(Vec2d( r, 0.));
+ out.push_back(Vec2d( r2, rx));
+ out.push_back(Vec2d( rx, rx));
+ out.push_back(Vec2d( rx, r2));
+ out.push_back(Vec2d(0., r));
+ out.push_back(Vec2d(-rx, r2));
+ out.push_back(Vec2d(-rx, rx));
+ out.push_back(Vec2d(-r2, rx));
+ out.push_back(Vec2d(-r, 0.));
+ out.push_back(Vec2d(-r2, -rx));
+ out.push_back(Vec2d(-rx, -rx));
+ out.push_back(Vec2d(-rx, -r2));
+ out.push_back(Vec2d(0., -r));
+ out.push_back(Vec2d( rx, -r2));
+ out.push_back(Vec2d( rx, -rx));
+ out.push_back(Vec2d( r2+r_inc, -rx));
}
return out;
}
diff --git a/xs/src/libslic3r/Fill/FillRectilinear.cpp b/xs/src/libslic3r/Fill/FillRectilinear.cpp
index 5ba30ba51..205eb1b66 100644
--- a/xs/src/libslic3r/Fill/FillRectilinear.cpp
+++ b/xs/src/libslic3r/Fill/FillRectilinear.cpp
@@ -26,8 +26,8 @@ void FillRectilinear::_fill_surface_single(
// define flow spacing according to requested density
if (params.density > 0.9999f && !params.dont_adjust) {
- this->_line_spacing = this->_adjust_solid_spacing(bounding_box.size().x, this->_line_spacing);
- this->spacing = unscale(this->_line_spacing);
+ this->_line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), this->_line_spacing);
+ this->spacing = unscale<double>(this->_line_spacing);
} else {
// extend bounding box so that our pattern will be aligned with other layers
// Transform the reference point to the rotated coordinate system.
@@ -38,14 +38,14 @@ void FillRectilinear::_fill_surface_single(
}
// generate the basic pattern
- coord_t x_max = bounding_box.max.x + SCALED_EPSILON;
+ coord_t x_max = bounding_box.max(0) + SCALED_EPSILON;
Lines lines;
- for (coord_t x = bounding_box.min.x; x <= x_max; x += this->_line_spacing)
- lines.push_back(this->_line(lines.size(), x, bounding_box.min.y, bounding_box.max.y));
+ for (coord_t x = bounding_box.min(0); x <= x_max; x += this->_line_spacing)
+ lines.push_back(this->_line(lines.size(), x, bounding_box.min(1), bounding_box.max(1)));
if (this->_horizontal_lines()) {
- coord_t y_max = bounding_box.max.y + SCALED_EPSILON;
- for (coord_t y = bounding_box.min.y; y <= y_max; y += this->_line_spacing)
- lines.push_back(Line(Point(bounding_box.min.x, y), Point(bounding_box.max.x, y)));
+ coord_t y_max = bounding_box.max(1) + SCALED_EPSILON;
+ for (coord_t y = bounding_box.min(1); y <= y_max; y += this->_line_spacing)
+ lines.push_back(Line(Point(bounding_box.min(0), y), Point(bounding_box.max(0), y)));
}
// clip paths against a slightly larger expolygon, so that the first and last paths
@@ -72,10 +72,10 @@ void FillRectilinear::_fill_surface_single(
for (Polylines::iterator it_polyline = polylines.begin(); it_polyline != polylines.end(); ++ it_polyline) {
Point *first_point = &it_polyline->points.front();
Point *last_point = &it_polyline->points.back();
- if (first_point->y > last_point->y)
+ if (first_point->y() > last_point->y())
std::swap(first_point, last_point);
- first_point->y -= extra;
- last_point->y += extra;
+ first_point->y() -= extra;
+ last_point->y() += extra;
}
size_t n_polylines_out_old = polylines_out.size();
@@ -103,10 +103,10 @@ void FillRectilinear::_fill_surface_single(
const Point &first_point = it_polyline->points.front();
const Point &last_point = pts_end.back();
// Distance in X, Y.
- const Vector distance = first_point.vector_to(last_point);
+ const Vector distance = last_point - first_point;
// TODO: we should also check that both points are on a fill_boundary to avoid
// connecting paths on the boundaries of internal regions
- if (this->_can_connect(std::abs(distance.x), std::abs(distance.y)) &&
+ if (this->_can_connect(std::abs(distance(0)), std::abs(distance(1))) &&
expolygon_off.contains(Line(last_point, first_point))) {
// Append the polyline.
pts_end.insert(pts_end.end(), it_polyline->points.begin(), it_polyline->points.end());
@@ -122,7 +122,7 @@ void FillRectilinear::_fill_surface_single(
// paths must be rotated back
for (Polylines::iterator it = polylines_out.begin() + n_polylines_out_old; it != polylines_out.end(); ++ it) {
// No need to translate, the absolute position is irrelevant.
- // it->translate(- direction.second.x, - direction.second.y);
+ // it->translate(- direction.second(0), - direction.second(1));
it->rotate(direction.first);
}
}
diff --git a/xs/src/libslic3r/Fill/FillRectilinear2.cpp b/xs/src/libslic3r/Fill/FillRectilinear2.cpp
index ddd785101..65440d0ef 100644
--- a/xs/src/libslic3r/Fill/FillRectilinear2.cpp
+++ b/xs/src/libslic3r/Fill/FillRectilinear2.cpp
@@ -42,12 +42,12 @@ static inline coordf_t segment_length(const Polygon &poly, size_t seg1, const Po
Point px = (i == 0) ? p1 : p2;
Point pa = poly.points[((seg == 0) ? poly.points.size() : seg) - 1];
Point pb = poly.points[seg];
- if (pa.x > pb.x)
- std::swap(pa.x, pb.x);
- if (pa.y > pb.y)
- std::swap(pa.y, pb.y);
- assert(px.x >= pa.x && px.x <= pb.x);
- assert(px.y >= pa.y && px.y <= pb.y);
+ if (pa(0) > pb(0))
+ std::swap(pa(0), pb(0));
+ if (pa(1) > pb(1))
+ std::swap(pa(1), pb(1));
+ assert(px(0) >= pa(0) && px(0) <= pb(0));
+ assert(px(1) >= pa(1) && px(1) <= pb(1));
}
#endif /* SLIC3R_DEBUG */
const Point *pPrev = &p1;
@@ -55,14 +55,14 @@ static inline coordf_t segment_length(const Polygon &poly, size_t seg1, const Po
coordf_t len = 0;
if (seg1 <= seg2) {
for (size_t i = seg1; i < seg2; ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
} else {
for (size_t i = seg1; i < poly.points.size(); ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
for (size_t i = 0; i < seg2; ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
}
- len += pPrev->distance_to(p2);
+ len += (*pPrev - p2).cast<double>().norm();
return len;
}
@@ -791,15 +791,15 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
// define flow spacing according to requested density
if (params.full_infill() && !params.dont_adjust) {
- line_spacing = this->_adjust_solid_spacing(bounding_box.size().x, line_spacing);
- this->spacing = unscale(line_spacing);
+ line_spacing = this->_adjust_solid_spacing(bounding_box.size()(0), line_spacing);
+ this->spacing = unscale<double>(line_spacing);
} else {
// extend bounding box so that our pattern will be aligned with other layers
// Transform the reference point to the rotated coordinate system.
Point refpt = rotate_vector.second.rotated(- rotate_vector.first);
// _align_to_grid will not work correctly with positive pattern_shift.
coord_t pattern_shift_scaled = coord_t(scale_(pattern_shift)) % line_spacing;
- refpt.x -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
+ refpt(0) -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
bounding_box.merge(_align_to_grid(
bounding_box.min,
Point(line_spacing, line_spacing),
@@ -808,8 +808,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
// Intersect a set of euqally spaced vertical lines wiht expolygon.
// n_vlines = ceil(bbox_width / line_spacing)
- size_t n_vlines = (bounding_box.max.x - bounding_box.min.x + line_spacing - 1) / line_spacing;
- coord_t x0 = bounding_box.min.x;
+ size_t n_vlines = (bounding_box.max(0) - bounding_box.min(0) + line_spacing - 1) / line_spacing;
+ coord_t x0 = bounding_box.min(0);
if (params.full_infill())
x0 += (line_spacing + SCALED_EPSILON) / 2;
@@ -842,8 +842,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
const Point &p1 = contour[iPrev];
const Point &p2 = contour[iSegment];
// Which of the equally spaced vertical lines is intersected by this segment?
- coord_t l = p1.x;
- coord_t r = p2.x;
+ coord_t l = p1(0);
+ coord_t r = p2(0);
if (l > r)
std::swap(l, r);
// il, ir are the left / right indices of vertical lines intersecting a segment
@@ -869,33 +869,33 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
assert(l <= this_x);
assert(r >= this_x);
// Calculate the intersection position in y axis. x is known.
- if (p1.x == this_x) {
- if (p2.x == this_x) {
+ if (p1(0) == this_x) {
+ if (p2(0) == this_x) {
// Ignore strictly vertical segments.
continue;
}
- is.pos_p = p1.y;
+ is.pos_p = p1(1);
is.pos_q = 1;
- } else if (p2.x == this_x) {
- is.pos_p = p2.y;
+ } else if (p2(0) == this_x) {
+ is.pos_p = p2(1);
is.pos_q = 1;
} else {
// First calculate the intersection parameter 't' as a rational number with non negative denominator.
- if (p2.x > p1.x) {
- is.pos_p = this_x - p1.x;
- is.pos_q = p2.x - p1.x;
+ if (p2(0) > p1(0)) {
+ is.pos_p = this_x - p1(0);
+ is.pos_q = p2(0) - p1(0);
} else {
- is.pos_p = p1.x - this_x;
- is.pos_q = p1.x - p2.x;
+ is.pos_p = p1(0) - this_x;
+ is.pos_q = p1(0) - p2(0);
}
assert(is.pos_p >= 0 && is.pos_p <= is.pos_q);
// Make an intersection point from the 't'.
- is.pos_p *= int64_t(p2.y - p1.y);
- is.pos_p += p1.y * int64_t(is.pos_q);
+ is.pos_p *= int64_t(p2(1) - p1(1));
+ is.pos_p += p1(1) * int64_t(is.pos_q);
}
// +-1 to take rounding into account.
- assert(is.pos() + 1 >= std::min(p1.y, p2.y));
- assert(is.pos() <= std::max(p1.y, p2.y) + 1);
+ assert(is.pos() + 1 >= std::min(p1(1), p2(1)));
+ assert(is.pos() <= std::max(p1(1), p2(1)) + 1);
segs[i].intersections.push_back(is);
}
}
@@ -919,7 +919,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
const Points &contour = poly_with_offset.contour(iContour).points;
size_t iSegment = sil.intersections[i].iSegment;
size_t iPrev = ((iSegment == 0) ? contour.size() : iSegment) - 1;
- coord_t dir = contour[iSegment].x - contour[iPrev].x;
+ coord_t dir = contour[iSegment](0) - contour[iPrev](0);
bool low = dir > 0;
sil.intersections[i].type = poly_with_offset.is_contour_outer(iContour) ?
(low ? SegmentIntersection::OUTER_LOW : SegmentIntersection::OUTER_HIGH) :
@@ -1066,7 +1066,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
intrsctn.consumed_vertical_up :
seg.intersections[i-1].consumed_vertical_up;
if (! consumed) {
- coordf_t dist2 = sqr(coordf_t(pointLast.x - seg.pos)) + sqr(coordf_t(pointLast.y - intrsctn.pos()));
+ coordf_t dist2 = sqr(coordf_t(pointLast(0) - seg.pos)) + sqr(coordf_t(pointLast(1) - intrsctn.pos()));
if (dist2 < dist2min) {
dist2min = dist2;
i_vline = i_vline2;
@@ -1356,8 +1356,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
// Handle nearly zero length edges.
if (polyline_current->points.size() <= 1 ||
(polyline_current->points.size() == 2 &&
- std::abs(polyline_current->points.front().x - polyline_current->points.back().x) < SCALED_EPSILON &&
- std::abs(polyline_current->points.front().y - polyline_current->points.back().y) < SCALED_EPSILON))
+ std::abs(polyline_current->points.front()(0) - polyline_current->points.back()(0)) < SCALED_EPSILON &&
+ std::abs(polyline_current->points.front()(1) - polyline_current->points.back()(1)) < SCALED_EPSILON))
polylines_out.pop_back();
intrsctn = NULL;
i_intersection = -1;
@@ -1383,7 +1383,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
// paths must be rotated back
for (Polylines::iterator it = polylines_out.begin() + n_polylines_out_initial; it != polylines_out.end(); ++ it) {
// No need to translate, the absolute position is irrelevant.
- // it->translate(- rotate_vector.second.x, - rotate_vector.second.y);
+ // it->translate(- rotate_vector.second(0), - rotate_vector.second(1));
assert(! it->has_duplicate_points());
it->rotate(rotate_vector.first);
//FIXME rather simplify the paths to avoid very short edges?
diff --git a/xs/src/libslic3r/Fill/FillRectilinear3.cpp b/xs/src/libslic3r/Fill/FillRectilinear3.cpp
index 1e7e3a1cd..8fc129eac 100644
--- a/xs/src/libslic3r/Fill/FillRectilinear3.cpp
+++ b/xs/src/libslic3r/Fill/FillRectilinear3.cpp
@@ -217,30 +217,30 @@ Point SegmentIntersection::pos() const
const Point &seg_start = poly.points[(this->iSegment == 0) ? poly.points.size() - 1 : this->iSegment - 1];
const Point &seg_end = poly.points[this->iSegment];
// Point, vector of the segment.
- const Pointf p1 = convert_to<Pointf>(seg_start);
- const Pointf v1 = convert_to<Pointf>(seg_end - seg_start);
+ const Vec2d p1(seg_start.cast<coordf_t>());
+ const Vec2d v1((seg_end - seg_start).cast<coordf_t>());
// Point, vector of this hatching line.
- const Pointf p2 = convert_to<Pointf>(line->pos);
- const Pointf v2 = convert_to<Pointf>(line->dir);
+ const Vec2d p2(line->pos.cast<coordf_t>());
+ const Vec2d v2(line->dir.cast<coordf_t>());
// Intersect the two rays.
- double denom = v1.x * v2.y - v2.x * v1.y;
+ double denom = v1(0) * v2(1) - v2(0) * v1(1);
Point out;
if (denom == 0.) {
// Lines are collinear. As the pos() method is not supposed to be called on collinear vectors,
// the source vectors are not quite collinear. Return the center of the contour segment.
out = seg_start + seg_end;
- out.x >>= 1;
- out.y >>= 1;
+ out(0) >>= 1;
+ out(1) >>= 1;
} else {
// Find the intersection point.
- double t = (v2.x * (p1.y - p2.y) - v2.y * (p1.x - p2.x)) / denom;
+ double t = (v2(0) * (p1(1) - p2(1)) - v2(1) * (p1(0) - p2(0))) / denom;
if (t < 0.)
out = seg_start;
else if (t > 1.)
out = seg_end;
else {
- out.x = coord_t(floor(p1.x + t * v1.x + 0.5));
- out.y = coord_t(floor(p1.y + t * v1.y + 0.5));
+ out(0) = coord_t(floor(p1(0) + t * v1(0) + 0.5));
+ out(1) = coord_t(floor(p1(1) + t * v1(1) + 0.5));
}
}
return out;
@@ -276,13 +276,13 @@ int SegmentIntersection::ordering_along_line(const SegmentIntersection &other) c
// other.iSegment succeeds this->iSegment
assert(seg_end_a == seg_start_b);
// Avoid calling the 128bit x 128bit multiplication below if this->line intersects the common point.
- if (cross(this->line->dir, seg_end_b - this->line->pos) == 0)
+ if (cross2(Vec2i64(this->line->dir.cast<int64_t>()), (seg_end_b - this->line->pos).cast<int64_t>()) == 0)
return 0;
} else if ((other.iSegment + 1) % poly_a.points.size() == this->iSegment) {
// this->iSegment succeeds other.iSegment
assert(seg_start_a == seg_end_b);
// Avoid calling the 128bit x 128bit multiplication below if this->line intersects the common point.
- if (cross(this->line->dir, seg_start_a - this->line->pos) == 0)
+ if (cross2(Vec2i64(this->line->dir.cast<int64_t>()), (seg_start_a - this->line->pos).cast<int64_t>()) == 0)
return 0;
} else {
// General case.
@@ -290,35 +290,35 @@ int SegmentIntersection::ordering_along_line(const SegmentIntersection &other) c
}
// First test, whether both points of one segment are completely in one half-plane of the other line.
- const Point vec_b = seg_end_b - seg_start_b;
- int side_start = signum(cross(vec_b, seg_start_a - seg_start_b));
- int side_end = signum(cross(vec_b, seg_end_a - seg_start_b));
+ const Vec2i64 vec_b = (seg_end_b - seg_start_b).cast<int64_t>();
+ int side_start = signum(cross2(vec_b, (seg_start_a - seg_start_b).cast<int64_t>()));
+ int side_end = signum(cross2(vec_b, (seg_end_a - seg_start_b).cast<int64_t>()));
int side = side_start * side_end;
if (side > 0)
// This segment is completely inside one half-plane of the other line, therefore the ordering is trivial.
- return signum(cross(vec_b, this->line->dir)) * side_start;
+ return signum(cross2(vec_b, this->line->dir.cast<int64_t>())) * side_start;
- const Point vec_a = seg_end_a - seg_start_a;
- int side_start2 = signum(cross(vec_a, seg_start_b - seg_start_a));
- int side_end2 = signum(cross(vec_a, seg_end_b - seg_start_a));
+ const Vec2i64 vec_a = (seg_end_a - seg_start_a).cast<int64_t>();
+ int side_start2 = signum(cross2(vec_a, (seg_start_b - seg_start_a).cast<int64_t>()));
+ int side_end2 = signum(cross2(vec_a, (seg_end_b - seg_start_a).cast<int64_t>()));
int side2 = side_start2 * side_end2;
//if (side == 0 && side2 == 0)
// The segments share one of their end points.
if (side2 > 0)
// This segment is completely inside one half-plane of the other line, therefore the ordering is trivial.
- return signum(cross(this->line->dir, vec_a)) * side_start2;
+ return signum(cross2(this->line->dir.cast<int64_t>(), vec_a)) * side_start2;
// The two segments intersect and they are not sucessive segments of the same contour.
// Ordering of the points depends on the position of the segment intersection (left / right from this->line),
// therefore a simple test over the input segment end points is not sufficient.
// Find the parameters of intersection of the two segmetns with this->line.
- int64_t denom1 = cross(this->line->dir, vec_a);
- int64_t denom2 = cross(this->line->dir, vec_b);
- Point vx_a = seg_start_a - this->line->pos;
- Point vx_b = seg_start_b - this->line->pos;
- int64_t t1_times_denom1 = int64_t(vx_a.x) * int64_t(vec_a.y) - int64_t(vx_a.y) * int64_t(vec_a.x);
- int64_t t2_times_denom2 = int64_t(vx_b.x) * int64_t(vec_b.y) - int64_t(vx_b.y) * int64_t(vec_b.x);
+ int64_t denom1 = cross2(this->line->dir.cast<int64_t>(), vec_a);
+ int64_t denom2 = cross2(this->line->dir.cast<int64_t>(), vec_b);
+ Vec2i64 vx_a = (seg_start_a - this->line->pos).cast<int64_t>();
+ Vec2i64 vx_b = (seg_start_b - this->line->pos).cast<int64_t>();
+ int64_t t1_times_denom1 = vx_a(0) * vec_a(1) - vx_a(1) * vec_a(0);
+ int64_t t2_times_denom2 = vx_b(0) * vec_b(1) - vx_b(1) * vec_b(0);
assert(denom1 != 0);
assert(denom2 != 0);
return Int128::compare_rationals_filtered(t1_times_denom1, denom1, t2_times_denom2, denom2);
@@ -330,7 +330,7 @@ bool SegmentIntersection::operator<(const SegmentIntersection &other) const
#ifdef _DEBUG
Point p1 = this->pos();
Point p2 = other.pos();
- int64_t d = dot(this->line->dir, p2 - p1);
+ int64_t d = this->line->dir.cast<int64_t>().dot((p2 - p1).cast<int64_t>());
#endif /* _DEBUG */
int ordering = this->ordering_along_line(other);
#ifdef _DEBUG
@@ -389,16 +389,16 @@ static bool prepare_infill_hatching_segments(
// Define the flow spacing according to requested density.
if (params.full_infill() && ! params.dont_adjust) {
// Full infill, adjust the line spacing to fit an integer number of lines.
- out.line_spacing = Fill::_adjust_solid_spacing(bounding_box.size().x, line_spacing);
+ out.line_spacing = Fill::_adjust_solid_spacing(bounding_box.size()(0), line_spacing);
// Report back the adjusted line spacing.
- fill_dir_params.spacing = float(unscale(line_spacing));
+ fill_dir_params.spacing = unscale<double>(line_spacing);
} else {
// Extend bounding box so that our pattern will be aligned with the other layers.
// Transform the reference point to the rotated coordinate system.
Point refpt = rotate_vector.second.rotated(- out.angle);
// _align_to_grid will not work correctly with positive pattern_shift.
coord_t pattern_shift_scaled = coord_t(scale_(fill_dir_params.pattern_shift)) % line_spacing;
- refpt.x -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
+ refpt(0) -= (pattern_shift_scaled >= 0) ? pattern_shift_scaled : (line_spacing + pattern_shift_scaled);
bounding_box.merge(Fill::_align_to_grid(
bounding_box.min,
Point(line_spacing, line_spacing),
@@ -407,13 +407,13 @@ static bool prepare_infill_hatching_segments(
// Intersect a set of euqally spaced vertical lines wiht expolygon.
// n_vlines = ceil(bbox_width / line_spacing)
- size_t n_vlines = (bounding_box.max.x - bounding_box.min.x + line_spacing - 1) / line_spacing;
- coord_t x0 = bounding_box.min.x;
+ size_t n_vlines = (bounding_box.max(0) - bounding_box.min(0) + line_spacing - 1) / line_spacing;
+ coord_t x0 = bounding_box.min(0);
if (params.full_infill())
x0 += coord_t((line_spacing + SCALED_EPSILON) / 2);
out.line_spacing = line_spacing;
- out.start_point = Point(x0, bounding_box.min.y);
+ out.start_point = Point(x0, bounding_box.min(1));
out.start_point.rotate(out.angle);
#ifdef SLIC3R_DEBUG
@@ -436,10 +436,10 @@ static bool prepare_infill_hatching_segments(
for (size_t i = 0; i < n_vlines; ++ i) {
auto &seg = out.segs[i];
seg.idx = i;
- // seg.x = x0 + coord_t(i) * line_spacing;
+ // seg(0) = x0 + coord_t(i) * line_spacing;
coord_t x = x0 + coord_t(i) * line_spacing;
- seg.pos.x = coord_t(floor(cos_a * x - sin_a * bounding_box.min.y + 0.5));
- seg.pos.y = coord_t(floor(cos_a * bounding_box.min.y + sin_a * x + 0.5));
+ seg.pos(0) = coord_t(floor(cos_a * x - sin_a * bounding_box.min(1) + 0.5));
+ seg.pos(1) = coord_t(floor(cos_a * bounding_box.min(1) + sin_a * x + 0.5));
seg.dir = out.direction;
}
@@ -454,7 +454,7 @@ static bool prepare_infill_hatching_segments(
const Point *pr = &contour[iSegment];
// Orient the segment to the direction vector.
const Point v = *pr - *pl;
- int orientation = Int128::sign_determinant_2x2_filtered(v.x, v.y, out.direction.x, out.direction.y);
+ int orientation = Int128::sign_determinant_2x2_filtered(v(0), v(1), out.direction(0), out.direction(1));
if (orientation == 0)
// Ignore strictly vertical segments.
continue;
@@ -462,26 +462,26 @@ static bool prepare_infill_hatching_segments(
// Always orient the input segment consistently towards the hatching direction.
std::swap(pl, pr);
// Which of the equally spaced vertical lines is intersected by this segment?
- coord_t l = (coord_t)floor(cos_a * pl->x + sin_a * pl->y - SCALED_EPSILON);
- coord_t r = (coord_t)ceil (cos_a * pr->x + sin_a * pr->y + SCALED_EPSILON);
+ coord_t l = (coord_t)floor(cos_a * (*pl)(0) + sin_a * (*pl)(1) - SCALED_EPSILON);
+ coord_t r = (coord_t)ceil (cos_a * (*pr)(0) + sin_a * (*pr)(1) + SCALED_EPSILON);
assert(l < r - SCALED_EPSILON);
// il, ir are the left / right indices of vertical lines intersecting a segment
int il = std::max<int>(0, (l - x0 + line_spacing) / line_spacing);
int ir = std::min<int>(int(out.segs.size()) - 1, (r - x0) / line_spacing);
// The previous tests were done with floating point arithmetics over an epsilon-extended interval.
// Now do the same tests with exact arithmetics over the exact interval.
- while (il <= ir && Int128::orient(out.segs[il].pos, out.segs[il].pos + out.direction, *pl) < 0)
+ while (il <= ir && int128::orient(out.segs[il].pos, out.segs[il].pos + out.direction, *pl) < 0)
++ il;
- while (il <= ir && Int128::orient(out.segs[ir].pos, out.segs[ir].pos + out.direction, *pr) > 0)
+ while (il <= ir && int128::orient(out.segs[ir].pos, out.segs[ir].pos + out.direction, *pr) > 0)
-- ir;
// Here it is ensured, that
// 1) out.seg is not parallel to (pl, pr)
// 2) all lines from il to ir intersect <pl, pr>.
assert(il >= 0 && ir < int(out.segs.size()));
for (int i = il; i <= ir; ++ i) {
- // assert(out.segs[i].x == i * line_spacing + x0);
- // assert(l <= out.segs[i].x);
- // assert(r >= out.segs[i].x);
+ // assert(out.segs[i](0) == i * line_spacing + x0);
+ // assert(l <= out.segs[i](0));
+ // assert(r >= out.segs[i](0));
SegmentIntersection is;
is.line = &out.segs[i];
is.expoly_with_offset = &poly_with_offset;
@@ -489,12 +489,12 @@ static bool prepare_infill_hatching_segments(
is.iSegment = iSegment;
// Test whether the calculated intersection point falls into the bounding box of the input segment.
// +-1 to take rounding into account.
- assert(Int128::orient(out.segs[i].pos, out.segs[i].pos + out.direction, *pl) >= 0);
- assert(Int128::orient(out.segs[i].pos, out.segs[i].pos + out.direction, *pr) <= 0);
- assert(is.pos().x + 1 >= std::min(pl->x, pr->x));
- assert(is.pos().y + 1 >= std::min(pl->y, pr->y));
- assert(is.pos().x <= std::max(pl->x, pr->x) + 1);
- assert(is.pos().y <= std::max(pl->y, pr->y) + 1);
+ assert(int128::orient(out.segs[i].pos, out.segs[i].pos + out.direction, *pl) >= 0);
+ assert(int128::orient(out.segs[i].pos, out.segs[i].pos + out.direction, *pr) <= 0);
+ assert(is.pos()(0) + 1 >= std::min((*pl)(0), (*pr)(0)));
+ assert(is.pos()(1) + 1 >= std::min((*pl)(1), (*pr)(1)));
+ assert(is.pos()(0) <= std::max((*pl)(0), (*pr)(0)) + 1);
+ assert(is.pos()(1) <= std::max((*pl)(1), (*pr)(1)) + 1);
out.segs[i].intersections.push_back(is);
}
}
@@ -510,7 +510,7 @@ static bool prepare_infill_hatching_segments(
for (size_t i = 1; i < sil.intersections.size(); ++ i) {
Point p1 = sil.intersections[i - 1].pos();
Point p2 = sil.intersections[i].pos();
- int64_t d = dot(sil.dir, p2 - p1);
+ int64_t d = sil.dir.cast<int64_t>().dot((p2 - p1).cast<int64_t>());
assert(d >= - int64_t(SCALED_EPSILON));
}
#endif /* _DEBUG */
@@ -527,7 +527,7 @@ static bool prepare_infill_hatching_segments(
const Points &contour = poly_with_offset.contour(iContour).points;
size_t iSegment = sil.intersections[i].iSegment;
size_t iPrev = ((iSegment == 0) ? contour.size() : iSegment) - 1;
- int dir = Int128::cross(contour[iSegment] - contour[iPrev], sil.dir);
+ int dir = int128::cross(contour[iSegment] - contour[iPrev], sil.dir);
bool low = dir > 0;
sil.intersections[i].type = poly_with_offset.is_contour_outer(iContour) ?
(low ? SegmentIntersection::OUTER_LOW : SegmentIntersection::OUTER_HIGH) :
@@ -659,12 +659,12 @@ static inline coordf_t segment_length(const Polygon &poly, size_t seg1, const Po
Point px = (i == 0) ? p1 : p2;
Point pa = poly.points[((seg == 0) ? poly.points.size() : seg) - 1];
Point pb = poly.points[seg];
- if (pa.x > pb.x)
- std::swap(pa.x, pb.x);
- if (pa.y > pb.y)
- std::swap(pa.y, pb.y);
- assert(px.x >= pa.x && px.x <= pb.x);
- assert(px.y >= pa.y && px.y <= pb.y);
+ if (pa(0) > pb(0))
+ std::swap(pa(0), pb(0));
+ if (pa(1) > pb(1))
+ std::swap(pa(1), pb(1));
+ assert(px(0) >= pa(0) && px(0) <= pb(0));
+ assert(px(1) >= pa(1) && px(1) <= pb(1));
}
#endif /* SLIC3R_DEBUG */
const Point *pPrev = &p1;
@@ -672,14 +672,14 @@ static inline coordf_t segment_length(const Polygon &poly, size_t seg1, const Po
coordf_t len = 0;
if (seg1 <= seg2) {
for (size_t i = seg1; i < seg2; ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
} else {
for (size_t i = seg1; i < poly.points.size(); ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
for (size_t i = 0; i < seg2; ++ i, pPrev = pThis)
- len += pPrev->distance_to(*(pThis = &poly.points[i]));
+ len += (*pPrev - *(pThis = &poly.points[i])).cast<double>().norm();
}
- len += pPrev->distance_to(p2);
+ len += (*pPrev - p2).cast<double>().norm();
return len;
}
@@ -1191,7 +1191,7 @@ static bool fill_hatching_segments_legacy(
intrsctn.consumed_vertical_up :
seg.intersections[i-1].consumed_vertical_up;
if (! consumed) {
- coordf_t dist2 = pointLast.distance_to(intrsctn.pos());
+ coordf_t dist2 = (intrsctn.pos() - pointLast).cast<double>().norm();
if (dist2 < dist2min) {
dist2min = dist2;
i_vline = i_vline2;
@@ -1481,8 +1481,8 @@ static bool fill_hatching_segments_legacy(
// Handle nearly zero length edges.
if (polyline_current->points.size() <= 1 ||
(polyline_current->points.size() == 2 &&
- std::abs(polyline_current->points.front().x - polyline_current->points.back().x) < SCALED_EPSILON &&
- std::abs(polyline_current->points.front().y - polyline_current->points.back().y) < SCALED_EPSILON))
+ std::abs(polyline_current->points.front()(0) - polyline_current->points.back()(0)) < SCALED_EPSILON &&
+ std::abs(polyline_current->points.front()(1) - polyline_current->points.back()(1)) < SCALED_EPSILON))
polylines_out.pop_back();
intrsctn = NULL;
i_intersection = -1;
@@ -1510,7 +1510,7 @@ static bool fill_hatching_segments_legacy(
// paths must be rotated back
for (Polylines::iterator it = polylines_out.begin() + n_polylines_out_initial; it != polylines_out.end(); ++ it) {
// No need to translate, the absolute position is irrelevant.
- // it->translate(- rotate_vector.second.x, - rotate_vector.second.y);
+ // it->translate(- rotate_vector.second(0), - rotate_vector.second(1));
assert(! it->has_duplicate_points());
//it->rotate(rotate_vector.first);
//FIXME rather simplify the paths to avoid very short edges?
diff --git a/xs/src/libslic3r/Format/3mf.cpp b/xs/src/libslic3r/Format/3mf.cpp
index b34b8989e..464cbb8e6 100644
--- a/xs/src/libslic3r/Format/3mf.cpp
+++ b/xs/src/libslic3r/Format/3mf.cpp
@@ -16,6 +16,12 @@
#include <Eigen/Dense>
#include <miniz/miniz_zip.h>
+// VERSION NUMBERS
+// 0 : .3mf, files saved by older slic3r or other applications. No version definition in them.
+// 1 : Introduction of 3mf versioning. No other change in data saved into 3mf files.
+const unsigned int VERSION_3MF = 1;
+const char* SLIC3RPE_3MF_VERSION = "slic3rpe:Version3mf"; // definition of the metadata name saved into .model file
+
const std::string MODEL_FOLDER = "3D/";
const std::string MODEL_EXTENSION = ".model";
const std::string MODEL_FILE = "3D/3dmodel.model"; // << this is the only format of the string which works with CURA
@@ -23,6 +29,7 @@ const std::string CONTENT_TYPES_FILE = "[Content_Types].xml";
const std::string RELATIONSHIPS_FILE = "_rels/.rels";
const std::string PRINT_CONFIG_FILE = "Metadata/Slic3r_PE.config";
const std::string MODEL_CONFIG_FILE = "Metadata/Slic3r_PE_model.config";
+const std::string LAYER_HEIGHTS_PROFILE_FILE = "Metadata/Slic3r_PE_layer_heights_profile.txt";
const char* MODEL_TAG = "model";
const char* RESOURCES_TAG = "resources";
@@ -36,9 +43,9 @@ const char* COMPONENTS_TAG = "components";
const char* COMPONENT_TAG = "component";
const char* BUILD_TAG = "build";
const char* ITEM_TAG = "item";
+const char* METADATA_TAG = "metadata";
const char* CONFIG_TAG = "config";
-const char* METADATA_TAG = "metadata";
const char* VOLUME_TAG = "volume";
const char* UNIT_ATTR = "unit";
@@ -80,8 +87,6 @@ const char* INVALID_OBJECT_TYPES[] =
"other"
};
-typedef Eigen::Matrix<float, 4, 4, Eigen::RowMajor> Matrix4x4;
-
const char* get_attribute_value_charptr(const char** attributes, unsigned int attributes_size, const char* attribute_key)
{
if ((attributes == nullptr) || (attributes_size == 0) || (attributes_size % 2 != 0) || (attribute_key == nullptr))
@@ -114,11 +119,11 @@ int get_attribute_value_int(const char** attributes, unsigned int attributes_siz
return (text != nullptr) ? ::atoi(text) : 0;
}
-Matrix4x4 get_matrix_from_string(const std::string& mat_str)
+Slic3r::Transform3d get_transform_from_string(const std::string& mat_str)
{
if (mat_str.empty())
// empty string means default identity matrix
- return Matrix4x4::Identity();
+ return Slic3r::Transform3d::Identity();
std::vector<std::string> mat_elements_str;
boost::split(mat_elements_str, mat_str, boost::is_any_of(" "), boost::token_compress_on);
@@ -126,9 +131,9 @@ Matrix4x4 get_matrix_from_string(const std::string& mat_str)
unsigned int size = (unsigned int)mat_elements_str.size();
if (size != 12)
// invalid data, return identity matrix
- return Matrix4x4::Identity();
+ return Slic3r::Transform3d::Identity();
- Matrix4x4 ret = Matrix4x4::Identity();
+ Slic3r::Transform3d ret = Slic3r::Transform3d::Identity();
unsigned int i = 0;
// matrices are stored into 3mf files as 4x3
// we need to transpose them
@@ -136,7 +141,7 @@ Matrix4x4 get_matrix_from_string(const std::string& mat_str)
{
for (unsigned int r = 0; r < 3; ++r)
{
- ret(r, c) = (float)::atof(mat_elements_str[i++].c_str());
+ ret(r, c) = ::atof(mat_elements_str[i++].c_str());
}
}
return ret;
@@ -202,17 +207,17 @@ namespace Slic3r {
struct Component
{
int object_id;
- Matrix4x4 matrix;
+ Transform3d transform;
explicit Component(int object_id)
: object_id(object_id)
- , matrix(Matrix4x4::Identity())
+ , transform(Transform3d::Identity())
{
}
- Component(int object_id, const Matrix4x4& matrix)
+ Component(int object_id, const Transform3d& transform)
: object_id(object_id)
- , matrix(matrix)
+ , transform(transform)
{
}
};
@@ -266,11 +271,11 @@ namespace Slic3r {
struct Instance
{
ModelInstance* instance;
- Matrix4x4 matrix;
+ Transform3d transform;
- Instance(ModelInstance* instance, const Matrix4x4& matrix)
+ Instance(ModelInstance* instance, const Transform3d& transform)
: instance(instance)
- , matrix(matrix)
+ , transform(transform)
{
}
};
@@ -315,6 +320,10 @@ namespace Slic3r {
typedef std::vector<Instance> InstancesList;
typedef std::map<int, ObjectMetadata> IdToMetadataMap;
typedef std::map<int, Geometry> IdToGeometryMap;
+ typedef std::map<int, std::vector<coordf_t>> IdToLayerHeightsProfileMap;
+
+ // Version of the 3mf file
+ unsigned int m_version;
XML_Parser m_xml_parser;
Model* m_model;
@@ -326,6 +335,9 @@ namespace Slic3r {
IdToGeometryMap m_geometries;
CurrentConfig m_curr_config;
IdToMetadataMap m_objects_metadata;
+ IdToLayerHeightsProfileMap m_layer_heights_profiles;
+ std::string m_curr_metadata_name;
+ std::string m_curr_characters;
public:
_3MF_Importer();
@@ -339,12 +351,14 @@ namespace Slic3r {
bool _load_model_from_file(const std::string& filename, Model& model, PresetBundle& bundle);
bool _extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat);
- bool _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, PresetBundle& bundle, const std::string& archive_filename);
+ void _extract_layer_heights_profile_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat);
+ void _extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, PresetBundle& bundle, const std::string& archive_filename);
bool _extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model);
// handlers to parse the .model file
void _handle_start_model_xml_element(const char* name, const char** attributes);
void _handle_end_model_xml_element(const char* name);
+ void _handle_model_xml_characters(const XML_Char* s, int len);
// handlers to parse the MODEL_CONFIG_FILE file
void _handle_start_config_xml_element(const char* name, const char** attributes);
@@ -386,10 +400,12 @@ namespace Slic3r {
bool _handle_start_item(const char** attributes, unsigned int num_attributes);
bool _handle_end_item();
- bool _create_object_instance(int object_id, const Matrix4x4& matrix, unsigned int recur_counter);
+ bool _handle_start_metadata(const char** attributes, unsigned int num_attributes);
+ bool _handle_end_metadata();
- void _apply_transform(ModelObject& object, const Matrix4x4& matrix);
- void _apply_transform(ModelInstance& instance, const Matrix4x4& matrix);
+ bool _create_object_instance(int object_id, const Transform3d& transform, unsigned int recur_counter);
+
+ void _apply_transform(ModelInstance& instance, const Transform3d& transform);
bool _handle_start_config(const char** attributes, unsigned int num_attributes);
bool _handle_end_config();
@@ -408,6 +424,7 @@ namespace Slic3r {
// callbacks to parse the .model file
static void XMLCALL _handle_start_model_xml_element(void* userData, const char* name, const char** attributes);
static void XMLCALL _handle_end_model_xml_element(void* userData, const char* name);
+ static void XMLCALL _handle_model_xml_characters(void* userData, const XML_Char* s, int len);
// callbacks to parse the MODEL_CONFIG_FILE file
static void XMLCALL _handle_start_config_xml_element(void* userData, const char* name, const char** attributes);
@@ -415,9 +432,12 @@ namespace Slic3r {
};
_3MF_Importer::_3MF_Importer()
- : m_xml_parser(nullptr)
+ : m_version(0)
+ , m_xml_parser(nullptr)
, m_model(nullptr)
, m_unit_factor(1.0f)
+ , m_curr_metadata_name("")
+ , m_curr_characters("")
{
}
@@ -428,6 +448,7 @@ namespace Slic3r {
bool _3MF_Importer::load_model_from_file(const std::string& filename, Model& model, PresetBundle& bundle)
{
+ m_version = 0;
m_model = &model;
m_unit_factor = 1.0f;
m_curr_object.reset();
@@ -438,6 +459,9 @@ namespace Slic3r {
m_curr_config.object_id = -1;
m_curr_config.volume_id = -1;
m_objects_metadata.clear();
+ m_layer_heights_profiles.clear();
+ m_curr_metadata_name.clear();
+ m_curr_characters.clear();
clear_errors();
return _load_model_from_file(filename, model, bundle);
@@ -473,6 +497,8 @@ namespace Slic3r {
mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
mz_zip_archive_file_stat stat;
+
+ // we first loop the entries to read from the archive the .model file only, in order to extract the version from it
for (mz_uint i = 0; i < num_entries; ++i)
{
if (mz_zip_reader_file_stat(&archive, i, &stat))
@@ -490,15 +516,26 @@ namespace Slic3r {
return false;
}
}
+ }
+ }
+
+ // we then loop again the entries to read other files stored in the archive
+ for (mz_uint i = 0; i < num_entries; ++i)
+ {
+ if (mz_zip_reader_file_stat(&archive, i, &stat))
+ {
+ std::string name(stat.m_filename);
+ std::replace(name.begin(), name.end(), '\\', '/');
+
+ if (boost::algorithm::iequals(name, LAYER_HEIGHTS_PROFILE_FILE))
+ {
+ // extract slic3r lazer heights profile file
+ _extract_layer_heights_profile_config_from_archive(archive, stat);
+ }
else if (boost::algorithm::iequals(name, PRINT_CONFIG_FILE))
{
// extract slic3r print config file
- if (!_extract_print_config_from_archive(archive, stat, bundle, filename))
- {
- mz_zip_reader_end(&archive);
- add_error("Archive does not contain a valid print config");
- return false;
- }
+ _extract_print_config_from_archive(archive, stat, bundle, filename);
}
else if (boost::algorithm::iequals(name, MODEL_CONFIG_FILE))
{
@@ -527,6 +564,13 @@ namespace Slic3r {
return false;
}
+ IdToLayerHeightsProfileMap::iterator obj_layer_heights_profile = m_layer_heights_profiles.find(object.first);
+ if (obj_layer_heights_profile != m_layer_heights_profiles.end())
+ {
+ object.second->layer_height_profile = obj_layer_heights_profile->second;
+ object.second->layer_height_profile_valid = true;
+ }
+
IdToMetadataMap::iterator obj_metadata = m_objects_metadata.find(object.first);
if (obj_metadata != m_objects_metadata.end())
{
@@ -557,19 +601,6 @@ namespace Slic3r {
if (!_generate_volumes(*object.second, obj_geometry->second, *volumes_ptr))
return false;
-
- // apply transformation if the object contains a single instance
- if (object.second->instances.size() == 1)
- {
- for (const Instance& instance : m_instances)
- {
- if (object.second->instances[0] == instance.instance)
- {
- _apply_transform(*object.second, instance.matrix);
- break;
- }
- }
- }
}
// fixes the min z of the model if negative
@@ -597,6 +628,7 @@ namespace Slic3r {
XML_SetUserData(m_xml_parser, (void*)this);
XML_SetElementHandler(m_xml_parser, _3MF_Importer::_handle_start_model_xml_element, _3MF_Importer::_handle_end_model_xml_element);
+ XML_SetCharacterDataHandler(m_xml_parser, _3MF_Importer::_handle_model_xml_characters);
void* parser_buffer = XML_GetBuffer(m_xml_parser, (int)stat.m_uncomp_size);
if (parser_buffer == nullptr)
@@ -623,23 +655,90 @@ namespace Slic3r {
return true;
}
- bool _3MF_Importer::_extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, PresetBundle& bundle, const std::string& archive_filename)
+ void _3MF_Importer::_extract_print_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, PresetBundle& bundle, const std::string& archive_filename)
{
if (stat.m_uncomp_size > 0)
{
- std::vector<char> buffer((size_t)stat.m_uncomp_size + 1, 0);
+ std::string buffer((size_t)stat.m_uncomp_size, 0);
mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
if (res == 0)
{
add_error("Error while reading config data to buffer");
- return false;
+ return;
}
-
- buffer.back() = '\0';
bundle.load_config_string(buffer.data(), archive_filename.c_str());
}
+ }
- return true;
+ void _3MF_Importer::_extract_layer_heights_profile_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat)
+ {
+ if (stat.m_uncomp_size > 0)
+ {
+ std::string buffer((size_t)stat.m_uncomp_size, 0);
+ mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, (void*)buffer.data(), (size_t)stat.m_uncomp_size, 0);
+ if (res == 0)
+ {
+ add_error("Error while reading layer heights profile data to buffer");
+ return;
+ }
+
+ if (buffer.back() == '\n')
+ buffer.pop_back();
+
+ std::vector<std::string> objects;
+ boost::split(objects, buffer, boost::is_any_of("\n"), boost::token_compress_off);
+
+ for (const std::string& object : objects)
+ {
+ std::vector<std::string> object_data;
+ boost::split(object_data, object, boost::is_any_of("|"), boost::token_compress_off);
+ if (object_data.size() != 2)
+ {
+ add_error("Error while reading object data");
+ continue;
+ }
+
+ std::vector<std::string> object_data_id;
+ boost::split(object_data_id, object_data[0], boost::is_any_of("="), boost::token_compress_off);
+ if (object_data_id.size() != 2)
+ {
+ add_error("Error while reading object id");
+ continue;
+ }
+
+ int object_id = std::atoi(object_data_id[1].c_str());
+ if (object_id == 0)
+ {
+ add_error("Found invalid object id");
+ continue;
+ }
+
+ IdToLayerHeightsProfileMap::iterator object_item = m_layer_heights_profiles.find(object_id);
+ if (object_item != m_layer_heights_profiles.end())
+ {
+ add_error("Found duplicated layer heights profile");
+ continue;
+ }
+
+ std::vector<std::string> object_data_profile;
+ boost::split(object_data_profile, object_data[1], boost::is_any_of(";"), boost::token_compress_off);
+ if ((object_data_profile.size() <= 4) || (object_data_profile.size() % 2 != 0))
+ {
+ add_error("Found invalid layer heights profile");
+ continue;
+ }
+
+ std::vector<coordf_t> profile;
+ profile.reserve(object_data_profile.size());
+
+ for (const std::string& value : object_data_profile)
+ {
+ profile.push_back((coordf_t)std::atof(value.c_str()));
+ }
+
+ m_layer_heights_profiles.insert(IdToLayerHeightsProfileMap::value_type(object_id, profile));
+ }
+ }
}
bool _3MF_Importer::_extract_model_config_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, Model& model)
@@ -719,6 +818,8 @@ namespace Slic3r {
res = _handle_start_build(attributes, num_attributes);
else if (::strcmp(ITEM_TAG, name) == 0)
res = _handle_start_item(attributes, num_attributes);
+ else if (::strcmp(METADATA_TAG, name) == 0)
+ res = _handle_start_metadata(attributes, num_attributes);
if (!res)
_stop_xml_parser();
@@ -755,11 +856,18 @@ namespace Slic3r {
res = _handle_end_build();
else if (::strcmp(ITEM_TAG, name) == 0)
res = _handle_end_item();
+ else if (::strcmp(METADATA_TAG, name) == 0)
+ res = _handle_end_metadata();
if (!res)
_stop_xml_parser();
}
+ void _3MF_Importer::_handle_model_xml_characters(const XML_Char* s, int len)
+ {
+ m_curr_characters.append(s, len);
+ }
+
void _3MF_Importer::_handle_start_config_xml_element(const char* name, const char** attributes)
{
if (m_xml_parser == nullptr)
@@ -822,11 +930,10 @@ namespace Slic3r {
if (instance.instance != nullptr)
{
ModelObject* object = instance.instance->get_object();
- if ((object != nullptr) && (object->instances.size() > 1))
+ if (object != nullptr)
{
- // multiple instances -> apply the matrix to the instance
- // (for single instance the transformation can be applied only after the volumes have been generated)
- _apply_transform(*instance.instance, instance.matrix);
+ // apply the transform to the instance
+ _apply_transform(*instance.instance, instance.transform);
}
}
}
@@ -1010,7 +1117,7 @@ namespace Slic3r {
bool _3MF_Importer::_handle_start_component(const char** attributes, unsigned int num_attributes)
{
int object_id = get_attribute_value_int(attributes, num_attributes, OBJECTID_ATTR);
- Matrix4x4 matrix = get_matrix_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR));
+ Transform3d transform = get_transform_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR));
IdToModelObjectMap::iterator object_item = m_objects.find(object_id);
if (object_item == m_objects.end())
@@ -1023,7 +1130,7 @@ namespace Slic3r {
}
}
- m_curr_object.components.emplace_back(object_id, matrix);
+ m_curr_object.components.emplace_back(object_id, transform);
return true;
}
@@ -1056,9 +1163,9 @@ namespace Slic3r {
// see specifications
int object_id = get_attribute_value_int(attributes, num_attributes, OBJECTID_ATTR);
- Matrix4x4 matrix = get_matrix_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR));
+ Transform3d transform = get_transform_from_string(get_attribute_value_string(attributes, num_attributes, TRANSFORM_ATTR));
- return _create_object_instance(object_id, matrix, 1);
+ return _create_object_instance(object_id, transform, 1);
}
bool _3MF_Importer::_handle_end_item()
@@ -1067,7 +1174,26 @@ namespace Slic3r {
return true;
}
- bool _3MF_Importer::_create_object_instance(int object_id, const Matrix4x4& matrix, unsigned int recur_counter)
+ bool _3MF_Importer::_handle_start_metadata(const char** attributes, unsigned int num_attributes)
+ {
+ m_curr_characters.clear();
+
+ std::string name = get_attribute_value_string(attributes, num_attributes, NAME_ATTR);
+ if (!name.empty())
+ m_curr_metadata_name = name;
+
+ return true;
+ }
+
+ bool _3MF_Importer::_handle_end_metadata()
+ {
+ if (m_curr_metadata_name == SLIC3RPE_3MF_VERSION)
+ m_version = (unsigned int)atoi(m_curr_characters.c_str());
+
+ return true;
+ }
+
+ bool _3MF_Importer::_create_object_instance(int object_id, const Transform3d& transform, unsigned int recur_counter)
{
static const unsigned int MAX_RECURSIONS = 10;
@@ -1104,7 +1230,7 @@ namespace Slic3r {
return false;
}
- m_instances.emplace_back(instance, matrix);
+ m_instances.emplace_back(instance, transform);
}
}
else
@@ -1112,7 +1238,7 @@ namespace Slic3r {
// recursively process nested components
for (const Component& component : it->second)
{
- if (!_create_object_instance(component.object_id, matrix * component.matrix, recur_counter + 1))
+ if (!_create_object_instance(component.object_id, transform * component.transform, recur_counter + 1))
return false;
}
}
@@ -1120,29 +1246,20 @@ namespace Slic3r {
return true;
}
- void _3MF_Importer::_apply_transform(ModelObject& object, const Matrix4x4& matrix)
- {
- float matrix3x4[12] = { matrix(0, 0), matrix(0, 1), matrix(0, 2), matrix(0, 3),
- matrix(1, 0), matrix(1, 1), matrix(1, 2), matrix(1, 3),
- matrix(2, 0), matrix(2, 1), matrix(2, 2), matrix(2, 3) };
-
- object.transform(matrix3x4);
- }
-
- void _3MF_Importer::_apply_transform(ModelInstance& instance, const Matrix4x4& matrix)
+ void _3MF_Importer::_apply_transform(ModelInstance& instance, const Transform3d& transform)
{
// slic3r ModelInstance cannot be transformed using a matrix
// we extract from the given matrix only the values currently used
// translation
- double offset_x = (double)matrix(0, 3);
- double offset_y = (double)matrix(1, 3);
- double offset_z = (double)matrix(2, 3);
+ double offset_x = transform(0, 3);
+ double offset_y = transform(1, 3);
+ double offset_z = transform(2, 3);
// scale
- double sx = ::sqrt(sqr((double)matrix(0, 0)) + sqr((double)matrix(1, 0)) + sqr((double)matrix(2, 0)));
- double sy = ::sqrt(sqr((double)matrix(0, 1)) + sqr((double)matrix(1, 1)) + sqr((double)matrix(2, 1)));
- double sz = ::sqrt(sqr((double)matrix(0, 2)) + sqr((double)matrix(1, 2)) + sqr((double)matrix(2, 2)));
+ double sx = ::sqrt(sqr(transform(0, 0)) + sqr(transform(1, 0)) + sqr(transform(2, 0)));
+ double sy = ::sqrt(sqr(transform(0, 1)) + sqr(transform(1, 1)) + sqr(transform(2, 1)));
+ double sz = ::sqrt(sqr(transform(0, 2)) + sqr(transform(1, 2)) + sqr(transform(2, 2)));
// invalid scale value, return
if ((sx == 0.0) || (sy == 0.0) || (sz == 0.0))
@@ -1152,69 +1269,26 @@ namespace Slic3r {
if ((std::abs(sx - sy) > 0.00001) || (std::abs(sx - sz) > 0.00001))
return;
- // rotations (extracted using quaternion)
double inv_sx = 1.0 / sx;
double inv_sy = 1.0 / sy;
double inv_sz = 1.0 / sz;
-
- Eigen::Matrix<double, 3, 3, Eigen::RowMajor> m3x3;
- m3x3 << (double)matrix(0, 0) * inv_sx, (double)matrix(0, 1) * inv_sy, (double)matrix(0, 2) * inv_sz,
- (double)matrix(1, 0) * inv_sx, (double)matrix(1, 1) * inv_sy, (double)matrix(1, 2) * inv_sz,
- (double)matrix(2, 0) * inv_sx, (double)matrix(2, 1) * inv_sy, (double)matrix(2, 2) * inv_sz;
- double qw = 0.5 * ::sqrt(std::max(0.0, 1.0 + m3x3(0, 0) + m3x3(1, 1) + m3x3(2, 2)));
- double qx = 0.5 * ::sqrt(std::max(0.0, 1.0 + m3x3(0, 0) - m3x3(1, 1) - m3x3(2, 2)));
- double qy = 0.5 * ::sqrt(std::max(0.0, 1.0 - m3x3(0, 0) + m3x3(1, 1) - m3x3(2, 2)));
- double qz = 0.5 * ::sqrt(std::max(0.0, 1.0 - m3x3(0, 0) - m3x3(1, 1) + m3x3(2, 2)));
+ Eigen::Matrix3d m3x3;
+ m3x3 << transform(0, 0) * inv_sx, transform(0, 1) * inv_sy, transform(0, 2) * inv_sz,
+ transform(1, 0) * inv_sx, transform(1, 1) * inv_sy, transform(1, 2) * inv_sz,
+ transform(2, 0) * inv_sx, transform(2, 1) * inv_sy, transform(2, 2) * inv_sz;
- double q_magnitude = ::sqrt(sqr(qw) + sqr(qx) + sqr(qy) + sqr(qz));
+ Eigen::AngleAxisd rotation;
+ rotation.fromRotationMatrix(m3x3);
- // invalid length, return
- if (q_magnitude == 0.0)
+ // invalid rotation axis, we currently handle only rotations around Z axis
+ if ((rotation.angle() != 0.0) && (rotation.axis() != Vec3d::UnitZ()) && (rotation.axis() != -Vec3d::UnitZ()))
return;
- double inv_q_magnitude = 1.0 / q_magnitude;
+ double angle_z = (rotation.axis() == Vec3d::UnitZ()) ? rotation.angle() : -rotation.angle();
- qw *= inv_q_magnitude;
- qx *= inv_q_magnitude;
- qy *= inv_q_magnitude;
- qz *= inv_q_magnitude;
-
- double test = qx * qy + qz * qw;
- double angle_x, angle_y, angle_z;
-
- if (test > 0.499)
- {
- // singularity at north pole
- angle_x = 0.0;
- angle_y = 2.0 * ::atan2(qx, qw);
- angle_z = 0.5 * PI;
- }
- else if (test < -0.499)
- {
- // singularity at south pole
- angle_x = 0.0;
- angle_y = -2.0 * ::atan2(qx, qw);
- angle_z = -0.5 * PI;
- }
- else
- {
- angle_x = ::atan2(2.0 * qx * qw - 2.0 * qy * qz, 1.0 - 2.0 * sqr(qx) - 2.0 * sqr(qz));
- angle_y = ::atan2(2.0 * qy * qw - 2.0 * qx * qz, 1.0 - 2.0 * sqr(qy) - 2.0 * sqr(qz));
- angle_z = ::asin(2.0 * qx * qy + 2.0 * qz * qw);
-
- if (angle_x < 0.0)
- angle_x += 2.0 * PI;
-
- if (angle_y < 0.0)
- angle_y += 2.0 * PI;
-
- if (angle_z < 0.0)
- angle_z += 2.0 * PI;
- }
-
- instance.offset.x = offset_x;
- instance.offset.y = offset_y;
+ instance.offset(0) = offset_x;
+ instance.offset(1) = offset_y;
instance.scaling_factor = sx;
instance.rotation = angle_z;
}
@@ -1346,12 +1420,13 @@ namespace Slic3r {
stl_facet& facet = stl.facet_start[i];
for (unsigned int v = 0; v < 3; ++v)
{
- ::memcpy((void*)&facet.vertex[v].x, (const void*)&geometry.vertices[geometry.triangles[src_start_id + ii + v] * 3], 3 * sizeof(float));
+ ::memcpy(facet.vertex[v].data(), (const void*)&geometry.vertices[geometry.triangles[src_start_id + ii + v] * 3], 3 * sizeof(float));
}
}
stl_get_size(&stl);
volume->mesh.repair();
+ volume->calculate_convex_hull();
// apply volume's name and config data
for (const Metadata& metadata : volume_data.metadata)
@@ -1382,6 +1457,13 @@ namespace Slic3r {
importer->_handle_end_model_xml_element(name);
}
+ void XMLCALL _3MF_Importer::_handle_model_xml_characters(void* userData, const XML_Char* s, int len)
+ {
+ _3MF_Importer* importer = (_3MF_Importer*)userData;
+ if (importer != nullptr)
+ importer->_handle_model_xml_characters(s, len);
+ }
+
void XMLCALL _3MF_Importer::_handle_start_config_xml_element(void* userData, const char* name, const char** attributes)
{
_3MF_Importer* importer = (_3MF_Importer*)userData;
@@ -1401,11 +1483,11 @@ namespace Slic3r {
struct BuildItem
{
unsigned int id;
- Matrix4x4 matrix;
+ Transform3d transform;
- BuildItem(unsigned int id, const Matrix4x4& matrix)
+ BuildItem(unsigned int id, const Transform3d& transform)
: id(id)
- , matrix(matrix)
+ , transform(transform)
{
}
};
@@ -1443,27 +1525,28 @@ namespace Slic3r {
IdToObjectDataMap m_objects_data;
public:
- bool save_model_to_file(const std::string& filename, Model& model, const Print& print);
+ bool save_model_to_file(const std::string& filename, Model& model, const Print& print, bool export_print_config);
private:
- bool _save_model_to_file(const std::string& filename, Model& model, const Print& print);
+ bool _save_model_to_file(const std::string& filename, Model& model, const Print& print, bool export_print_config);
bool _add_content_types_file_to_archive(mz_zip_archive& archive);
bool _add_relationships_file_to_archive(mz_zip_archive& archive);
bool _add_model_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_object_to_model_stream(std::stringstream& stream, unsigned int& object_id, ModelObject& object, BuildItemsList& build_items, VolumeToOffsetsMap& volumes_offsets);
bool _add_mesh_to_object_stream(std::stringstream& stream, ModelObject& object, VolumeToOffsetsMap& volumes_offsets);
bool _add_build_to_model_stream(std::stringstream& stream, const BuildItemsList& build_items);
+ bool _add_layer_height_profile_file_to_archive(mz_zip_archive& archive, Model& model);
bool _add_print_config_file_to_archive(mz_zip_archive& archive, const Print& print);
bool _add_model_config_file_to_archive(mz_zip_archive& archive, const Model& model);
};
- bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const Print& print)
+ bool _3MF_Exporter::save_model_to_file(const std::string& filename, Model& model, const Print& print, bool export_print_config)
{
clear_errors();
- return _save_model_to_file(filename, model, print);
+ return _save_model_to_file(filename, model, print, export_print_config);
}
- bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const Print& print)
+ bool _3MF_Exporter::_save_model_to_file(const std::string& filename, Model& model, const Print& print, bool export_print_config)
{
mz_zip_archive archive;
mz_zip_zero_struct(&archive);
@@ -1501,14 +1584,25 @@ namespace Slic3r {
return false;
}
- // adds slic3r print config file
- if (!_add_print_config_file_to_archive(archive, print))
+ // adds layer height profile file
+ if (!_add_layer_height_profile_file_to_archive(archive, model))
{
mz_zip_writer_end(&archive);
boost::filesystem::remove(filename);
return false;
}
+ // adds slic3r print config file
+ if (export_print_config)
+ {
+ if (!_add_print_config_file_to_archive(archive, print))
+ {
+ mz_zip_writer_end(&archive);
+ boost::filesystem::remove(filename);
+ return false;
+ }
+ }
+
// adds slic3r model config file
if (!_add_model_config_file_to_archive(archive, model))
{
@@ -1573,7 +1667,8 @@ namespace Slic3r {
{
std::stringstream stream;
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- stream << "<" << MODEL_TAG << " unit=\"millimeter\" xml:lang=\"en-US\" xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\">\n";
+ stream << "<" << MODEL_TAG << " unit=\"millimeter\" xml:lang=\"en-US\" xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\" xmlns:slic3rpe=\"http://schemas.slic3r.org/3mf/2017/06\">\n";
+ stream << " <" << METADATA_TAG << " name=\"" << SLIC3RPE_3MF_VERSION << "\">" << VERSION_3MF << "</" << METADATA_TAG << ">\n";
stream << " <" << RESOURCES_TAG << ">\n";
BuildItemsList build_items;
@@ -1641,11 +1736,8 @@ namespace Slic3r {
stream << " </" << COMPONENTS_TAG << ">\n";
}
- Eigen::Affine3f transform;
- transform = Eigen::Translation3f((float)(instance->offset.x + object.origin_translation.x), (float)(instance->offset.y + object.origin_translation.y), (float)object.origin_translation.z)
- * Eigen::AngleAxisf((float)instance->rotation, Eigen::Vector3f::UnitZ())
- * Eigen::Scaling((float)instance->scaling_factor);
- build_items.emplace_back(instance_id, transform.matrix());
+ Transform3d t = instance->world_matrix();
+ build_items.emplace_back(instance_id, t);
stream << " </" << OBJECT_TAG << ">\n";
@@ -1687,10 +1779,9 @@ namespace Slic3r {
for (int i = 0; i < stl.stats.shared_vertices; ++i)
{
stream << " <" << VERTEX_TAG << " ";
- // Subtract origin_translation in order to restore the original local coordinates
- stream << "x=\"" << (stl.v_shared[i].x - object.origin_translation.x) << "\" ";
- stream << "y=\"" << (stl.v_shared[i].y - object.origin_translation.y) << "\" ";
- stream << "z=\"" << (stl.v_shared[i].z - object.origin_translation.z) << "\" />\n";
+ stream << "x=\"" << stl.v_shared[i](0) << "\" ";
+ stream << "y=\"" << stl.v_shared[i](1) << "\" ";
+ stream << "z=\"" << stl.v_shared[i](2) << "\" />\n";
}
}
@@ -1747,7 +1838,7 @@ namespace Slic3r {
{
for (unsigned r = 0; r < 3; ++r)
{
- stream << item.matrix(r, c);
+ stream << item.transform(r, c);
if ((r != 2) || (c != 3))
stream << " ";
}
@@ -1760,6 +1851,44 @@ namespace Slic3r {
return true;
}
+ bool _3MF_Exporter::_add_layer_height_profile_file_to_archive(mz_zip_archive& archive, Model& model)
+ {
+ std::string out = "";
+ char buffer[1024];
+
+ unsigned int count = 0;
+ for (const ModelObject* object : model.objects)
+ {
+ ++count;
+ std::vector<double> layer_height_profile = object->layer_height_profile_valid ? object->layer_height_profile : std::vector<double>();
+ if ((layer_height_profile.size() >= 4) && ((layer_height_profile.size() % 2) == 0))
+ {
+ sprintf(buffer, "object_id=%d|", count);
+ out += buffer;
+
+ // Store the layer height profile as a single semicolon separated list.
+ for (size_t i = 0; i < layer_height_profile.size(); ++i)
+ {
+ sprintf(buffer, (i == 0) ? "%f" : ";%f", layer_height_profile[i]);
+ out += buffer;
+ }
+
+ out += "\n";
+ }
+ }
+
+ if (!out.empty())
+ {
+ if (!mz_zip_writer_add_mem(&archive, LAYER_HEIGHTS_PROFILE_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION))
+ {
+ add_error("Unable to add layer heights profile file to archive");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
bool _3MF_Exporter::_add_print_config_file_to_archive(mz_zip_archive& archive, const Print& print)
{
char buffer[1024];
@@ -1768,10 +1897,13 @@ namespace Slic3r {
GCode::append_full_config(print, out);
- if (!mz_zip_writer_add_mem(&archive, PRINT_CONFIG_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION))
+ if (!out.empty())
{
- add_error("Unable to add print config file to archive");
- return false;
+ if (!mz_zip_writer_add_mem(&archive, PRINT_CONFIG_FILE.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION))
+ {
+ add_error("Unable to add print config file to archive");
+ return false;
+ }
}
return true;
@@ -1792,7 +1924,7 @@ namespace Slic3r {
// stores object's name
if (!obj->name.empty())
- stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"name\" " << VALUE_ATTR << "=\"" << obj->name << "\"/>\n";
+ stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << OBJECT_TYPE << "\" " << KEY_ATTR << "=\"name\" " << VALUE_ATTR << "=\"" << xml_escape(obj->name) << "\"/>\n";
// stores object's config data
for (const std::string& key : obj->config.keys())
@@ -1815,7 +1947,7 @@ namespace Slic3r {
// stores volume's name
if (!volume->name.empty())
- stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << NAME_KEY << "\" " << VALUE_ATTR << "=\"" << volume->name << "\"/>\n";
+ stream << " <" << METADATA_TAG << " " << TYPE_ATTR << "=\"" << VOLUME_TYPE << "\" " << KEY_ATTR << "=\"" << NAME_KEY << "\" " << VALUE_ATTR << "=\"" << xml_escape(volume->name) << "\"/>\n";
// stores volume's modifier field
if (volume->modifier)
@@ -1856,20 +1988,17 @@ namespace Slic3r {
_3MF_Importer importer;
bool res = importer.load_model_from_file(path, *model, *bundle);
-
- if (!res)
- importer.log_errors();
-
+ importer.log_errors();
return res;
}
- bool store_3mf(const char* path, Model* model, Print* print)
+ bool store_3mf(const char* path, Model* model, Print* print, bool export_print_config)
{
if ((path == nullptr) || (model == nullptr) || (print == nullptr))
return false;
_3MF_Exporter exporter;
- bool res = exporter.save_model_to_file(path, *model, *print);
+ bool res = exporter.save_model_to_file(path, *model, *print, export_print_config);
if (!res)
exporter.log_errors();
diff --git a/xs/src/libslic3r/Format/3mf.hpp b/xs/src/libslic3r/Format/3mf.hpp
index 9b48c860b..85bc812e3 100644
--- a/xs/src/libslic3r/Format/3mf.hpp
+++ b/xs/src/libslic3r/Format/3mf.hpp
@@ -12,7 +12,7 @@ namespace Slic3r {
// Save the given model and the config data contained in the given Print into a 3mf file.
// The model could be modified during the export process if meshes are not repaired or have no shared vertices
- extern bool store_3mf(const char* path, Model* model, Print* print);
+ extern bool store_3mf(const char* path, Model* model, Print* print, bool export_print_config);
}; // namespace Slic3r
diff --git a/xs/src/libslic3r/Format/AMF.cpp b/xs/src/libslic3r/Format/AMF.cpp
index a52dd532a..81617ad72 100644
--- a/xs/src/libslic3r/Format/AMF.cpp
+++ b/xs/src/libslic3r/Format/AMF.cpp
@@ -8,11 +8,13 @@
#include "../libslic3r.h"
#include "../Model.hpp"
#include "../GCode.hpp"
+#include "../Utils.hpp"
#include "../slic3r/GUI/PresetBundle.hpp"
#include "AMF.hpp"
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/nowide/fstream.hpp>
#include <miniz/miniz_zip.h>
#if 0
@@ -24,6 +26,12 @@
#include <assert.h>
+// VERSION NUMBERS
+// 0 : .amf, .amf.xml and .zip.amf files saved by older slic3r. No version definition in them.
+// 1 : Introduction of amf versioning. No other change in data saved into amf files.
+const unsigned int VERSION_AMF = 1;
+const char* SLIC3RPE_AMF_VERSION = "slic3rpe_amf_version";
+
const char* SLIC3R_CONFIG_TYPE = "slic3rpe_config";
namespace Slic3r
@@ -32,6 +40,7 @@ namespace Slic3r
struct AMFParserContext
{
AMFParserContext(XML_Parser parser, const std::string& archive_filename, PresetBundle* preset_bundle, Model *model) :
+ m_version(0),
m_parser(parser),
m_model(*model),
m_object(nullptr),
@@ -137,6 +146,8 @@ struct AMFParserContext
std::vector<Instance> instances;
};
+ // Version of the amf file
+ unsigned int m_version;
// Current Expat XML parser instance.
XML_Parser m_parser;
// Model to receive objects extracted from an AMF file.
@@ -360,9 +371,9 @@ void AMFParserContext::endElement(const char * /* name */)
case NODE_TYPE_VERTEX:
assert(m_object);
// Parse the vertex data
- m_object_vertices.emplace_back(atof(m_value[0].c_str()));
- m_object_vertices.emplace_back(atof(m_value[1].c_str()));
- m_object_vertices.emplace_back(atof(m_value[2].c_str()));
+ m_object_vertices.emplace_back((float)atof(m_value[0].c_str()));
+ m_object_vertices.emplace_back((float)atof(m_value[1].c_str()));
+ m_object_vertices.emplace_back((float)atof(m_value[2].c_str()));
m_value[0].clear();
m_value[1].clear();
m_value[2].clear();
@@ -391,10 +402,11 @@ void AMFParserContext::endElement(const char * /* name */)
for (size_t i = 0; i < m_volume_facets.size();) {
stl_facet &facet = stl.facet_start[i/3];
for (unsigned int v = 0; v < 3; ++ v)
- memcpy(&facet.vertex[v].x, &m_object_vertices[m_volume_facets[i ++] * 3], 3 * sizeof(float));
+ memcpy(facet.vertex[v].data(), &m_object_vertices[m_volume_facets[i ++] * 3], 3 * sizeof(float));
}
stl_get_size(&stl);
m_volume->mesh.repair();
+ m_volume->calculate_convex_hull();
m_volume_facets.clear();
m_volume = nullptr;
break;
@@ -462,6 +474,10 @@ void AMFParserContext::endElement(const char * /* name */)
if (m_volume && m_value[0] == "name")
m_volume->name = std::move(m_value[1]);
}
+ else if (strncmp(m_value[0].c_str(), SLIC3RPE_AMF_VERSION, strlen(SLIC3RPE_AMF_VERSION)) == 0) {
+ m_version = (unsigned int)atoi(m_value[1].c_str());
+ }
+
m_value[0].clear();
m_value[1].clear();
break;
@@ -482,8 +498,8 @@ void AMFParserContext::endDocument()
for (const Instance &instance : object.second.instances)
if (instance.deltax_set && instance.deltay_set) {
ModelInstance *mi = m_model.objects[object.second.idx]->add_instance();
- mi->offset.x = instance.deltax;
- mi->offset.y = instance.deltay;
+ mi->offset(0) = instance.deltax;
+ mi->offset(1) = instance.deltay;
mi->rotation = instance.rz_set ? instance.rz : 0.f;
mi->scaling_factor = instance.scale_set ? instance.scale : 1.f;
}
@@ -543,47 +559,8 @@ bool load_amf_file(const char *path, PresetBundle* bundle, Model *model)
return result;
}
-// Load an AMF archive into a provided model.
-bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model)
+bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, const char* path, PresetBundle* bundle, Model* model, unsigned int& version)
{
- if ((path == nullptr) || (model == nullptr))
- return false;
-
- mz_zip_archive archive;
- mz_zip_zero_struct(&archive);
-
- mz_bool res = mz_zip_reader_init_file(&archive, path, 0);
- if (res == 0)
- {
- printf("Unable to init zip reader\n");
- return false;
- }
-
- mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
- if (num_entries != 1)
- {
- printf("Found invalid number of entries\n");
- mz_zip_reader_end(&archive);
- return false;
- }
-
- mz_zip_archive_file_stat stat;
- res = mz_zip_reader_file_stat(&archive, 0, &stat);
- if (res == 0)
- {
- printf("Unable to extract entry statistics\n");
- mz_zip_reader_end(&archive);
- return false;
- }
-
- std::string internal_amf_filename = boost::ireplace_last_copy(boost::filesystem::path(path).filename().string(), ".zip.amf", ".amf");
- if (internal_amf_filename != stat.m_filename)
- {
- printf("Found invalid internal filename\n");
- mz_zip_reader_end(&archive);
- return false;
- }
-
if (stat.m_uncomp_size == 0)
{
printf("Found invalid size\n");
@@ -611,7 +588,7 @@ bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model)
return false;
}
- res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, (size_t)stat.m_uncomp_size, 0);
+ mz_bool res = mz_zip_reader_extract_file_to_mem(&archive, stat.m_filename, parser_buffer, (size_t)stat.m_uncomp_size, 0);
if (res == 0)
{
printf("Error while reading model data to buffer\n");
@@ -628,6 +605,62 @@ bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model)
ctx.endDocument();
+ version = ctx.m_version;
+
+ return true;
+}
+
+// Load an AMF archive into a provided model.
+bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model)
+{
+ if ((path == nullptr) || (model == nullptr))
+ return false;
+
+ unsigned int version = 0;
+
+ mz_zip_archive archive;
+ mz_zip_zero_struct(&archive);
+
+ mz_bool res = mz_zip_reader_init_file(&archive, path, 0);
+ if (res == 0)
+ {
+ printf("Unable to init zip reader\n");
+ return false;
+ }
+
+ mz_uint num_entries = mz_zip_reader_get_num_files(&archive);
+
+ mz_zip_archive_file_stat stat;
+ // we first loop the entries to read from the archive the .amf file only, in order to extract the version from it
+ for (mz_uint i = 0; i < num_entries; ++i)
+ {
+ if (mz_zip_reader_file_stat(&archive, i, &stat))
+ {
+ if (boost::iends_with(stat.m_filename, ".amf"))
+ {
+ if (!extract_model_from_archive(archive, stat, path, bundle, model, version))
+ {
+ mz_zip_reader_end(&archive);
+ printf("Archive does not contain a valid model");
+ return false;
+ }
+
+ break;
+ }
+ }
+ }
+
+#if 0 // forward compatibility
+ // we then loop again the entries to read other files stored in the archive
+ for (mz_uint i = 0; i < num_entries; ++i)
+ {
+ if (mz_zip_reader_file_stat(&archive, i, &stat))
+ {
+ // add code to extract the file
+ }
+ }
+#endif // forward compatibility
+
mz_zip_reader_end(&archive);
return true;
}
@@ -636,23 +669,39 @@ bool load_amf_archive(const char *path, PresetBundle* bundle, Model *model)
// If bundle is not a null pointer, updates it if the amf file/archive contains config data
bool load_amf(const char *path, PresetBundle* bundle, Model *model)
{
- if (boost::iends_with(path, ".zip.amf"))
- return load_amf_archive(path, bundle, model);
- else if (boost::iends_with(path, ".amf") || boost::iends_with(path, ".amf.xml"))
+ if (boost::iends_with(path, ".amf.xml"))
+ // backward compatibility with older slic3r output
return load_amf_file(path, bundle, model);
+ else if (boost::iends_with(path, ".amf"))
+ {
+ boost::nowide::ifstream file(path, boost::nowide::ifstream::binary);
+ if (!file.good())
+ return false;
+
+ std::string zip_mask(2, '\0');
+ file.read(const_cast<char*>(zip_mask.data()), 2);
+ file.close();
+
+ return (zip_mask == "PK") ? load_amf_archive(path, bundle, model) : load_amf_file(path, bundle, model);
+ }
else
return false;
}
-bool store_amf(const char *path, Model *model, Print* print)
+bool store_amf(const char *path, Model *model, Print* print, bool export_print_config)
{
if ((path == nullptr) || (model == nullptr) || (print == nullptr))
return false;
+ // forces ".zip.amf" extension
+ std::string export_path = path;
+ if (!boost::iends_with(export_path, ".zip.amf"))
+ export_path = boost::filesystem::path(export_path).replace_extension(".zip.amf").string();
+
mz_zip_archive archive;
mz_zip_zero_struct(&archive);
- mz_bool res = mz_zip_writer_init_file(&archive, path, 0);
+ mz_bool res = mz_zip_writer_init_file(&archive, export_path.c_str(), 0);
if (res == 0)
return false;
@@ -660,10 +709,14 @@ bool store_amf(const char *path, Model *model, Print* print)
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
stream << "<amf unit=\"millimeter\">\n";
stream << "<metadata type=\"cad\">Slic3r " << SLIC3R_VERSION << "</metadata>\n";
+ stream << "<metadata type=\"" << SLIC3RPE_AMF_VERSION << "\">" << VERSION_AMF << "</metadata>\n";
- std::string config = "\n";
- GCode::append_full_config(*print, config);
- stream << "<metadata type=\"" << SLIC3R_CONFIG_TYPE << "\">" << config << "</metadata>\n";
+ if (export_print_config)
+ {
+ std::string config = "\n";
+ GCode::append_full_config(*print, config);
+ stream << "<metadata type=\"" << SLIC3R_CONFIG_TYPE << "\">" << xml_escape(config) << "</metadata>\n";
+ }
for (const auto &material : model->materials) {
if (material.first.empty())
@@ -683,7 +736,7 @@ bool store_amf(const char *path, Model *model, Print* print)
for (const std::string &key : object->config.keys())
stream << " <metadata type=\"slic3r." << key << "\">" << object->config.serialize(key) << "</metadata>\n";
if (!object->name.empty())
- stream << " <metadata type=\"name\">" << object->name << "</metadata>\n";
+ stream << " <metadata type=\"name\">" << xml_escape(object->name) << "</metadata>\n";
std::vector<double> layer_height_profile = object->layer_height_profile_valid ? object->layer_height_profile : std::vector<double>();
if (layer_height_profile.size() >= 4 && (layer_height_profile.size() % 2) == 0) {
// Store the layer height profile as a single semicolon separated list.
@@ -708,9 +761,9 @@ bool store_amf(const char *path, Model *model, Print* print)
for (size_t i = 0; i < stl.stats.shared_vertices; ++ i) {
stream << " <vertex>\n";
stream << " <coordinates>\n";
- stream << " <x>" << stl.v_shared[i].x << "</x>\n";
- stream << " <y>" << stl.v_shared[i].y << "</y>\n";
- stream << " <z>" << stl.v_shared[i].z << "</z>\n";
+ stream << " <x>" << stl.v_shared[i](0) << "</x>\n";
+ stream << " <y>" << stl.v_shared[i](1) << "</y>\n";
+ stream << " <z>" << stl.v_shared[i](2) << "</z>\n";
stream << " </coordinates>\n";
stream << " </vertex>\n";
}
@@ -727,7 +780,7 @@ bool store_amf(const char *path, Model *model, Print* print)
for (const std::string &key : volume->config.keys())
stream << " <metadata type=\"slic3r." << key << "\">" << volume->config.serialize(key) << "</metadata>\n";
if (!volume->name.empty())
- stream << " <metadata type=\"name\">" << volume->name << "</metadata>\n";
+ stream << " <metadata type=\"name\">" << xml_escape(volume->name) << "</metadata>\n";
if (volume->modifier)
stream << " <metadata type=\"slic3r.modifier\">1</metadata>\n";
for (int i = 0; i < volume->mesh.stl.stats.number_of_facets; ++i) {
@@ -751,8 +804,8 @@ bool store_amf(const char *path, Model *model, Print* print)
" <scale>%lf</scale>\n"
" </instance>\n",
object_id,
- instance->offset.x,
- instance->offset.y,
+ instance->offset(0),
+ instance->offset(1),
instance->rotation,
instance->scaling_factor);
//FIXME missing instance->scaling_factor
@@ -767,20 +820,20 @@ bool store_amf(const char *path, Model *model, Print* print)
}
stream << "</amf>\n";
- std::string internal_amf_filename = boost::ireplace_last_copy(boost::filesystem::path(path).filename().string(), ".zip.amf", ".amf");
+ std::string internal_amf_filename = boost::ireplace_last_copy(boost::filesystem::path(export_path).filename().string(), ".zip.amf", ".amf");
std::string out = stream.str();
if (!mz_zip_writer_add_mem(&archive, internal_amf_filename.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION))
{
mz_zip_writer_end(&archive);
- boost::filesystem::remove(path);
+ boost::filesystem::remove(export_path);
return false;
}
if (!mz_zip_writer_finalize_archive(&archive))
{
mz_zip_writer_end(&archive);
- boost::filesystem::remove(path);
+ boost::filesystem::remove(export_path);
return false;
}
diff --git a/xs/src/libslic3r/Format/AMF.hpp b/xs/src/libslic3r/Format/AMF.hpp
index 027ebdab3..4779e9a51 100644
--- a/xs/src/libslic3r/Format/AMF.hpp
+++ b/xs/src/libslic3r/Format/AMF.hpp
@@ -12,7 +12,7 @@ extern bool load_amf(const char *path, PresetBundle* bundle, Model *model);
// Save the given model and the config data contained in the given Print into an amf file.
// The model could be modified during the export process if meshes are not repaired or have no shared vertices
-extern bool store_amf(const char *path, Model *model, Print* print);
+extern bool store_amf(const char *path, Model *model, Print* print, bool export_print_config);
}; // namespace Slic3r
diff --git a/xs/src/libslic3r/Format/OBJ.cpp b/xs/src/libslic3r/Format/OBJ.cpp
index ea6b5604c..ee5756083 100644
--- a/xs/src/libslic3r/Format/OBJ.cpp
+++ b/xs/src/libslic3r/Format/OBJ.cpp
@@ -57,14 +57,14 @@ bool load_obj(const char *path, Model *model, const char *object_name_in)
continue;
stl_facet &facet = stl.facet_start[i_face ++];
size_t num_normals = 0;
- stl_normal normal = { 0.f };
+ stl_normal normal(stl_normal::Zero());
for (unsigned int v = 0; v < 3; ++ v) {
const ObjParser::ObjVertex &vertex = data.vertices[i++];
- memcpy(&facet.vertex[v].x, &data.coordinates[vertex.coordIdx*4], 3 * sizeof(float));
+ memcpy(facet.vertex[v].data(), &data.coordinates[vertex.coordIdx*4], 3 * sizeof(float));
if (vertex.normalIdx != -1) {
- normal.x += data.normals[vertex.normalIdx*3];
- normal.y += data.normals[vertex.normalIdx*3+1];
- normal.z += data.normals[vertex.normalIdx*3+2];
+ normal(0) += data.normals[vertex.normalIdx*3];
+ normal(1) += data.normals[vertex.normalIdx*3+1];
+ normal(2) += data.normals[vertex.normalIdx*3+2];
++ num_normals;
}
}
@@ -74,33 +74,27 @@ bool load_obj(const char *path, Model *model, const char *object_name_in)
facet2.vertex[0] = facet.vertex[0];
facet2.vertex[1] = facet.vertex[2];
const ObjParser::ObjVertex &vertex = data.vertices[i++];
- memcpy(&facet2.vertex[2].x, &data.coordinates[vertex.coordIdx * 4], 3 * sizeof(float));
+ memcpy(facet2.vertex[2].data(), &data.coordinates[vertex.coordIdx * 4], 3 * sizeof(float));
if (vertex.normalIdx != -1) {
- normal.x += data.normals[vertex.normalIdx*3];
- normal.y += data.normals[vertex.normalIdx*3+1];
- normal.z += data.normals[vertex.normalIdx*3+2];
+ normal(0) += data.normals[vertex.normalIdx*3];
+ normal(1) += data.normals[vertex.normalIdx*3+1];
+ normal(2) += data.normals[vertex.normalIdx*3+2];
++ num_normals;
}
if (num_normals == 4) {
// Normalize an average normal of a quad.
- float len = sqrt(facet.normal.x*facet.normal.x + facet.normal.y*facet.normal.y + facet.normal.z*facet.normal.z);
+ float len = facet.normal.norm();
if (len > EPSILON) {
- normal.x /= len;
- normal.y /= len;
- normal.z /= len;
+ normal /= len;
facet.normal = normal;
facet2.normal = normal;
}
}
} else if (num_normals == 3) {
// Normalize an average normal of a triangle.
- float len = sqrt(facet.normal.x*facet.normal.x + facet.normal.y*facet.normal.y + facet.normal.z*facet.normal.z);
- if (len > EPSILON) {
- normal.x /= len;
- normal.y /= len;
- normal.z /= len;
- facet.normal = normal;
- }
+ float len = facet.normal.norm();
+ if (len > EPSILON)
+ facet.normal = normal / len;
}
}
stl_get_size(&stl);
diff --git a/xs/src/libslic3r/Format/PRUS.cpp b/xs/src/libslic3r/Format/PRUS.cpp
index 1809eaead..3cf3fc075 100644
--- a/xs/src/libslic3r/Format/PRUS.cpp
+++ b/xs/src/libslic3r/Format/PRUS.cpp
@@ -166,7 +166,7 @@ bool load_prus(const char *path, Model *model)
float trafo[3][4] = { 0 };
double instance_rotation = 0.;
double instance_scaling_factor = 1.f;
- Pointf instance_offset(0., 0.);
+ Vec2d instance_offset(0., 0.);
bool trafo_set = false;
unsigned int group_id = (unsigned int)-1;
unsigned int extruder_id = (unsigned int)-1;
@@ -207,8 +207,8 @@ bool load_prus(const char *path, Model *model)
for (size_t c = 0; c < 3; ++ c)
trafo[r][c] += mat_trafo(r, c);
}
- instance_offset.x = position[0] - zero[0];
- instance_offset.y = position[1] - zero[1];
+ instance_offset(0) = position[0] - zero[0];
+ instance_offset(1) = position[1] - zero[1];
trafo[2][3] = position[2] / instance_scaling_factor;
trafo_set = true;
}
@@ -260,8 +260,8 @@ bool load_prus(const char *path, Model *model)
mesh.repair();
// Transform the model.
stl_transform(&stl, &trafo[0][0]);
- if (std::abs(stl.stats.min.z) < EPSILON)
- stl.stats.min.z = 0.;
+ if (std::abs(stl.stats.min(2)) < EPSILON)
+ stl.stats.min(2) = 0.;
// Add a mesh to a model.
if (mesh.facets_count() > 0)
mesh_valid = true;
@@ -309,11 +309,11 @@ bool load_prus(const char *path, Model *model)
assert(res_normal == 3);
int res_outer_loop = line_reader.next_line_scanf(" outer loop");
assert(res_outer_loop == 0);
- int res_vertex1 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[0].x, &facet.vertex[0].y, &facet.vertex[0].z);
+ int res_vertex1 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[0](0), &facet.vertex[0](1), &facet.vertex[0](2));
assert(res_vertex1 == 3);
- int res_vertex2 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[1].x, &facet.vertex[1].y, &facet.vertex[1].z);
+ int res_vertex2 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[1](0), &facet.vertex[1](1), &facet.vertex[1](2));
assert(res_vertex2 == 3);
- int res_vertex3 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[2].x, &facet.vertex[2].y, &facet.vertex[2].z);
+ int res_vertex3 = line_reader.next_line_scanf(" vertex %f %f %f", &facet.vertex[2](0), &facet.vertex[2](1), &facet.vertex[2](2));
assert(res_vertex3 == 3);
int res_endloop = line_reader.next_line_scanf(" endloop");
assert(res_endloop == 0);
@@ -324,9 +324,9 @@ bool load_prus(const char *path, Model *model)
break;
}
// 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.x) != 1 ||
- sscanf(normal_buf[1], "%f", &facet.normal.y) != 1 ||
- sscanf(normal_buf[2], "%f", &facet.normal.z) != 1) {
+ 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));
diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp
index e55404845..0ade0de61 100644
--- a/xs/src/libslic3r/GCode.cpp
+++ b/xs/src/libslic3r/GCode.cpp
@@ -49,11 +49,11 @@ Polyline AvoidCrossingPerimeters::travel_to(const GCode &gcodegen, const Point &
// If use_external, then perform the path planning in the world coordinate system (correcting for the gcodegen offset).
// Otherwise perform the path planning in the coordinate system of the active object.
bool use_external = this->use_external_mp || this->use_external_mp_once;
- Point scaled_origin = use_external ? Point::new_scale(gcodegen.origin().x, gcodegen.origin().y) : Point(0, 0);
+ Point scaled_origin = use_external ? Point::new_scale(gcodegen.origin()(0), gcodegen.origin()(1)) : Point(0, 0);
Polyline result = (use_external ? m_external_mp.get() : m_layer_mp.get())->
shortest_path(gcodegen.last_pos() + scaled_origin, point + scaled_origin);
if (use_external)
- result.translate(scaled_origin.negative());
+ result.translate(- scaled_origin);
return result;
}
@@ -64,8 +64,8 @@ std::string OozePrevention::pre_toolchange(GCode &gcodegen)
// move to the nearest standby point
if (!this->standby_points.empty()) {
// get current position in print coordinates
- Pointf3 writer_pos = gcodegen.writer().get_position();
- Point pos = Point::new_scale(writer_pos.x, writer_pos.y);
+ Vec3d writer_pos = gcodegen.writer().get_position();
+ Point pos = Point::new_scale(writer_pos(0), writer_pos(1));
// find standby point
Point standby_point;
@@ -74,7 +74,7 @@ std::string OozePrevention::pre_toolchange(GCode &gcodegen)
/* We don't call gcodegen.travel_to() because we don't need retraction (it was already
triggered by the caller) nor avoid_crossing_perimeters and also because the coordinates
of the destination point must not be transformed by origin nor current extruder offset. */
- gcode += gcodegen.writer().travel_to_xy(Pointf::new_unscale(standby_point),
+ gcode += gcodegen.writer().travel_to_xy(unscale(standby_point),
"move to standby position");
}
@@ -160,13 +160,25 @@ Wipe::wipe(GCode &gcodegen, bool toolchange)
static inline Point wipe_tower_point_to_object_point(GCode &gcodegen, const WipeTower::xy &wipe_tower_pt)
{
- return Point(scale_(wipe_tower_pt.x - gcodegen.origin().x), scale_(wipe_tower_pt.y - gcodegen.origin().y));
+ return Point(scale_(wipe_tower_pt.x - gcodegen.origin()(0)), scale_(wipe_tower_pt.y - gcodegen.origin()(1)));
}
std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const
{
std::string gcode;
+ // Toolchangeresult.gcode assumes the wipe tower corner is at the origin
+ // We want to rotate and shift all extrusions (gcode postprocessing) and starting and ending position
+ float alpha = m_wipe_tower_rotation/180.f * M_PI;
+ WipeTower::xy start_pos = tcr.start_pos;
+ WipeTower::xy end_pos = tcr.end_pos;
+ start_pos.rotate(alpha);
+ start_pos.translate(m_wipe_tower_pos);
+ end_pos.rotate(alpha);
+ end_pos.translate(m_wipe_tower_pos);
+ std::string tcr_rotated_gcode = rotate_wipe_tower_moves(tcr.gcode, tcr.start_pos, m_wipe_tower_pos, alpha);
+
+
// Disable linear advance for the wipe tower operations.
gcode += "M900 K0\n";
// Move over the wipe tower.
@@ -174,14 +186,14 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
gcode += gcodegen.retract(true);
gcodegen.m_avoid_crossing_perimeters.use_external_mp_once = true;
gcode += gcodegen.travel_to(
- wipe_tower_point_to_object_point(gcodegen, tcr.start_pos),
+ wipe_tower_point_to_object_point(gcodegen, start_pos),
erMixed,
"Travel to a Wipe Tower");
gcode += gcodegen.unretract();
// Let the tool change be executed by the wipe tower class.
// Inform the G-code writer about the changes done behind its back.
- gcode += tcr.gcode;
+ gcode += tcr_rotated_gcode;
// Let the m_writer know the current extruder_id, but ignore the generated G-code.
if (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id))
gcodegen.writer().toolchange(new_extruder_id);
@@ -195,18 +207,18 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
check_add_eol(gcode);
}
// A phony move to the end position at the wipe tower.
- gcodegen.writer().travel_to_xy(Pointf(tcr.end_pos.x, tcr.end_pos.y));
- gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, tcr.end_pos));
+ gcodegen.writer().travel_to_xy(Vec2d(end_pos.x, end_pos.y));
+ gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, end_pos));
// Prepare a future wipe.
gcodegen.m_wipe.path.points.clear();
if (new_extruder_id >= 0) {
// Start the wipe at the current position.
- gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, tcr.end_pos));
+ gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen, end_pos));
// Wipe end point: Wipe direction away from the closer tower edge to the further tower edge.
gcodegen.m_wipe.path.points.emplace_back(wipe_tower_point_to_object_point(gcodegen,
- WipeTower::xy((std::abs(m_left - tcr.end_pos.x) < std::abs(m_right - tcr.end_pos.x)) ? m_right : m_left,
- tcr.end_pos.y)));
+ WipeTower::xy((std::abs(m_left - end_pos.x) < std::abs(m_right - end_pos.x)) ? m_right : m_left,
+ end_pos.y)));
}
// Let the planner know we are traveling between objects.
@@ -214,6 +226,57 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
return gcode;
}
+// This function postprocesses gcode_original, rotates and moves all G1 extrusions and returns resulting gcode
+// Starting position has to be supplied explicitely (otherwise it would fail in case first G1 command only contained one coordinate)
+std::string WipeTowerIntegration::rotate_wipe_tower_moves(const std::string& gcode_original, const WipeTower::xy& start_pos, const WipeTower::xy& translation, float angle) const
+{
+ std::istringstream gcode_str(gcode_original);
+ std::string gcode_out;
+ std::string line;
+ WipeTower::xy pos = start_pos;
+ WipeTower::xy transformed_pos;
+ WipeTower::xy old_pos(-1000.1f, -1000.1f);
+
+ while (gcode_str) {
+ std::getline(gcode_str, line); // we read the gcode line by line
+ if (line.find("G1 ") == 0) {
+ std::ostringstream line_out;
+ std::istringstream line_str(line);
+ line_str >> std::noskipws; // don't skip whitespace
+ char ch = 0;
+ while (line_str >> ch) {
+ if (ch == 'X')
+ line_str >> pos.x;
+ else
+ if (ch == 'Y')
+ line_str >> pos.y;
+ else
+ line_out << ch;
+ }
+
+ transformed_pos = pos;
+ transformed_pos.rotate(angle);
+ transformed_pos.translate(translation);
+
+ if (transformed_pos != old_pos) {
+ line = line_out.str();
+ char buf[2048] = "G1";
+ if (transformed_pos.x != old_pos.x)
+ sprintf(buf + strlen(buf), " X%.3f", transformed_pos.x);
+ if (transformed_pos.y != old_pos.y)
+ sprintf(buf + strlen(buf), " Y%.3f", transformed_pos.y);
+
+ line.replace(line.find("G1 "), 3, buf);
+ old_pos = transformed_pos;
+ }
+ }
+ gcode_out += line + "\n";
+ }
+ return gcode_out;
+}
+
+
+
std::string WipeTowerIntegration::prime(GCode &gcodegen)
{
assert(m_layer_idx == 0);
@@ -230,7 +293,7 @@ std::string WipeTowerIntegration::prime(GCode &gcodegen)
gcodegen.writer().toolchange(current_extruder_id);
gcodegen.placeholder_parser().set("current_extruder", current_extruder_id);
// A phony move to the end position at the wipe tower.
- gcodegen.writer().travel_to_xy(Pointf(m_priming.end_pos.x, m_priming.end_pos.y));
+ gcodegen.writer().travel_to_xy(Vec2d(m_priming.end_pos.x, m_priming.end_pos.y));
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, m_priming.end_pos));
// Prepare a future wipe.
gcodegen.m_wipe.path.points.clear();
@@ -262,7 +325,7 @@ std::string WipeTowerIntegration::tool_change(GCode &gcodegen, int extruder_id,
std::string WipeTowerIntegration::finalize(GCode &gcodegen)
{
std::string gcode;
- if (std::abs(gcodegen.writer().get_position().z - m_final_purge.print_z) > EPSILON)
+ if (std::abs(gcodegen.writer().get_position()(2) - m_final_purge.print_z) > EPSILON)
gcode += gcodegen.change_layer(m_final_purge.print_z);
gcode += append_tcr(gcodegen, m_final_purge, -1);
return gcode;
@@ -309,10 +372,12 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec
size_t object_idx;
size_t layer_idx;
};
- std::vector<std::vector<LayerToPrint>> per_object(print.objects().size(), std::vector<LayerToPrint>());
+
+ PrintObjectPtrs printable_objects = print.get_printable_objects();
+ std::vector<std::vector<LayerToPrint>> per_object(printable_objects.size(), std::vector<LayerToPrint>());
std::vector<OrderingItem> ordering;
- for (size_t i = 0; i < print.objects().size(); ++ i) {
- per_object[i] = collect_layers_to_print(*print.objects()[i]);
+ for (size_t i = 0; i < printable_objects.size(); ++i) {
+ per_object[i] = collect_layers_to_print(*printable_objects[i]);
OrderingItem ordering_item;
ordering_item.object_idx = i;
ordering.reserve(ordering.size() + per_object[i].size());
@@ -337,8 +402,8 @@ std::vector<std::pair<coordf_t, std::vector<GCode::LayerToPrint>>> GCode::collec
std::pair<coordf_t, std::vector<LayerToPrint>> merged;
// Assign an average print_z to the set of layers with nearly equal print_z.
merged.first = 0.5 * (ordering[i].print_z + ordering[j-1].print_z);
- merged.second.assign(print.objects().size(), LayerToPrint());
- for (; i < j; ++ i) {
+ merged.second.assign(printable_objects.size(), LayerToPrint());
+ for (; i < j; ++i) {
const OrderingItem &oi = ordering[i];
assert(merged.second[oi.object_idx].layer() == nullptr);
merged.second[oi.object_idx] = std::move(per_object[oi.object_idx][oi.layer_idx]);
@@ -382,6 +447,13 @@ void GCode::do_export(Print *print, const char *path, GCodePreviewData *preview_
throw;
}
fclose(file);
+
+ if (print->config().remaining_times.value) {
+ m_normal_time_estimator.post_process_remaining_times(path_tmp, 60.0f);
+ if (m_silent_time_estimator_enabled)
+ m_silent_time_estimator.post_process_remaining_times(path_tmp, 60.0f);
+ }
+
if (! m_placeholder_parser_failed_templates.empty()) {
// G-code export proceeded, but some of the PlaceholderParser substitutions failed.
std::string msg = std::string("G-code export to ") + path + " failed due to invalid custom G-code sections:\n\n";
@@ -413,9 +485,69 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
print.set_started(psGCodeExport);
- // resets time estimator
- m_time_estimator.reset();
- m_time_estimator.set_dialect(print.config().gcode_flavor);
+ // resets time estimators
+ m_normal_time_estimator.reset();
+ m_normal_time_estimator.set_dialect(print.config().gcode_flavor);
+ m_silent_time_estimator_enabled = (print.config().gcode_flavor == gcfMarlin) && print.config().silent_mode;
+
+ // Until we have a UI support for the other firmwares than the Marlin, use the hardcoded default values
+ // and let the user to enter the G-code limits into the start G-code.
+ // If the following block is enabled for other firmwares than the Marlin, then the function
+ // this->print_machine_envelope(file, print);
+ // shall be adjusted as well to produce a G-code block compatible with the particular firmware flavor.
+ if (print.config().gcode_flavor.value == gcfMarlin) {
+ m_normal_time_estimator.set_max_acceleration(print.config().machine_max_acceleration_extruding.values[0]);
+ m_normal_time_estimator.set_retract_acceleration(print.config().machine_max_acceleration_retracting.values[0]);
+ m_normal_time_estimator.set_minimum_feedrate(print.config().machine_min_extruding_rate.values[0]);
+ m_normal_time_estimator.set_minimum_travel_feedrate(print.config().machine_min_travel_rate.values[0]);
+ m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, print.config().machine_max_acceleration_x.values[0]);
+ m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, print.config().machine_max_acceleration_y.values[0]);
+ m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, print.config().machine_max_acceleration_z.values[0]);
+ m_normal_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, print.config().machine_max_acceleration_e.values[0]);
+ m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, print.config().machine_max_feedrate_x.values[0]);
+ m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, print.config().machine_max_feedrate_y.values[0]);
+ m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, print.config().machine_max_feedrate_z.values[0]);
+ m_normal_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, print.config().machine_max_feedrate_e.values[0]);
+ m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, print.config().machine_max_jerk_x.values[0]);
+ m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, print.config().machine_max_jerk_y.values[0]);
+ m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config().machine_max_jerk_z.values[0]);
+ m_normal_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config().machine_max_jerk_e.values[0]);
+
+ if (m_silent_time_estimator_enabled)
+ {
+ m_silent_time_estimator.reset();
+ m_silent_time_estimator.set_dialect(print.config().gcode_flavor);
+ m_silent_time_estimator.set_max_acceleration(print.config().machine_max_acceleration_extruding.values[1]);
+ m_silent_time_estimator.set_retract_acceleration(print.config().machine_max_acceleration_retracting.values[1]);
+ m_silent_time_estimator.set_minimum_feedrate(print.config().machine_min_extruding_rate.values[1]);
+ m_silent_time_estimator.set_minimum_travel_feedrate(print.config().machine_min_travel_rate.values[1]);
+ m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::X, print.config().machine_max_acceleration_x.values[1]);
+ m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Y, print.config().machine_max_acceleration_y.values[1]);
+ m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::Z, print.config().machine_max_acceleration_z.values[1]);
+ m_silent_time_estimator.set_axis_max_acceleration(GCodeTimeEstimator::E, print.config().machine_max_acceleration_e.values[1]);
+ m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::X, print.config().machine_max_feedrate_x.values[1]);
+ m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Y, print.config().machine_max_feedrate_y.values[1]);
+ m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::Z, print.config().machine_max_feedrate_z.values[1]);
+ m_silent_time_estimator.set_axis_max_feedrate(GCodeTimeEstimator::E, print.config().machine_max_feedrate_e.values[1]);
+ m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::X, print.config().machine_max_jerk_x.values[1]);
+ m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Y, print.config().machine_max_jerk_y.values[1]);
+ m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::Z, print.config().machine_max_jerk_z.values[1]);
+ m_silent_time_estimator.set_axis_max_jerk(GCodeTimeEstimator::E, print.config().machine_max_jerk_e.values[1]);
+ if (print.config().single_extruder_multi_material) {
+ // As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they
+ // are considered to be active for the single extruder multi-material printers only.
+ m_silent_time_estimator.set_filament_load_times(print.config().filament_load_time.values);
+ m_silent_time_estimator.set_filament_unload_times(print.config().filament_unload_time.values);
+ }
+ }
+ }
+ // Filament load / unload times are not specific to a firmware flavor. Let anybody use it if they find it useful.
+ if (print.config().single_extruder_multi_material) {
+ // As of now the fields are shown at the UI dialog in the same combo box as the ramming values, so they
+ // are considered to be active for the single extruder multi-material printers only.
+ m_normal_time_estimator.set_filament_load_times(print.config().filament_load_time.values);
+ m_normal_time_estimator.set_filament_unload_times(print.config().filament_unload_time.values);
+ }
// resets analyzer
m_analyzer.reset();
@@ -429,9 +561,10 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
// How many times will be change_layer() called?
// change_layer() in turn increments the progress bar status.
m_layer_count = 0;
+ PrintObjectPtrs printable_objects = print.get_printable_objects();
if (print.config().complete_objects.value) {
// Add each of the object's layers separately.
- for (auto object : print.objects()) {
+ for (auto object : printable_objects) {
std::vector<coordf_t> zs;
zs.reserve(object->layers().size() + object->support_layers().size());
for (auto layer : object->layers())
@@ -444,7 +577,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
} else {
// Print all objects with the same print_z together.
std::vector<coordf_t> zs;
- for (auto object : print.objects()) {
+ for (auto object : printable_objects) {
zs.reserve(zs.size() + object->layers().size() + object->support_layers().size());
for (auto layer : object->layers())
zs.push_back(layer->print_z);
@@ -464,8 +597,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
{
// get the minimum cross-section used in the print
std::vector<double> mm3_per_mm;
- for (auto object : print.objects()) {
- for (size_t region_id = 0; region_id < print.regions().size(); ++ region_id) {
+ for (auto object : printable_objects) {
+ for (size_t region_id = 0; region_id < print.regions().size(); ++region_id) {
auto region = print.regions()[region_id];
for (auto layer : object->layers()) {
auto layerm = layer->regions()[region_id];
@@ -529,7 +662,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
print.throw_if_canceled();
// Write some terse information on the slicing parameters.
- const PrintObject *first_object = print.objects().front();
+ const PrintObject *first_object = printable_objects.front();
const double layer_height = first_object->config().layer_height.value;
const double first_layer_height = first_object->config().first_layer_height.get_abs_value(layer_height);
for (size_t region_id = 0; region_id < print.regions().size(); ++ region_id) {
@@ -547,6 +680,14 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
}
print.throw_if_canceled();
+ // adds tags for time estimators
+ if (print.config().remaining_times.value)
+ {
+ _writeln(file, GCodeTimeEstimator::Normal_First_M73_Output_Placeholder_Tag);
+ if (m_silent_time_estimator_enabled)
+ _writeln(file, GCodeTimeEstimator::Silent_First_M73_Output_Placeholder_Tag);
+ }
+
// Prepare the helper object for replacing placeholders in custom G-code and output filename.
m_placeholder_parser = print.placeholder_parser();
m_placeholder_parser.update_timestamp();
@@ -559,20 +700,24 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
size_t initial_print_object_id = 0;
bool has_wipe_tower = false;
if (print.config().complete_objects.value) {
- // Find the 1st printing object, find its tool ordering and the initial extruder ID.
- for (; initial_print_object_id < print.objects().size(); ++initial_print_object_id) {
- tool_ordering = ToolOrdering(*print.objects()[initial_print_object_id], initial_extruder_id);
- if ((initial_extruder_id = tool_ordering.first_extruder()) != (unsigned int)-1)
- break;
- }
- } else {
+ // Find the 1st printing object, find its tool ordering and the initial extruder ID.
+ for (; initial_print_object_id < printable_objects.size(); ++initial_print_object_id) {
+ tool_ordering = ToolOrdering(*printable_objects[initial_print_object_id], initial_extruder_id);
+ if ((initial_extruder_id = tool_ordering.first_extruder()) != (unsigned int)-1)
+ break;
+ }
+ } else {
// Find tool ordering for all the objects at once, and the initial extruder ID.
// If the tool ordering has been pre-calculated by Print class for wipe tower already, reuse it.
tool_ordering = print.wipe_tower_data().tool_ordering.empty() ?
ToolOrdering(print, initial_extruder_id) :
print.wipe_tower_data().tool_ordering;
- initial_extruder_id = tool_ordering.first_extruder();
has_wipe_tower = print.has_wipe_tower() && tool_ordering.has_wipe_tower();
+ initial_extruder_id = (has_wipe_tower && ! print.config().single_extruder_multi_material_priming) ?
+ // The priming towers will be skipped.
+ tool_ordering.all_extruders().back() :
+ // Don't skip the priming towers.
+ tool_ordering.first_extruder();
}
if (initial_extruder_id == (unsigned int)-1) {
// Nothing to print!
@@ -586,6 +731,9 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
m_cooling_buffer->set_current_extruder(initial_extruder_id);
+ // Emit machine envelope limits for the Marlin firmware.
+ this->print_machine_envelope(file, print);
+
// Disable fan.
if (! print.config().cooling.get_at(initial_extruder_id) || print.config().disable_fan_first_layers.get_at(initial_extruder_id))
_write(file, m_writer.set_fan(0, true));
@@ -598,8 +746,8 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
m_placeholder_parser.set("current_object_idx", 0);
// For the start / end G-code to do the priming and final filament pull in case there is no wipe tower provided.
m_placeholder_parser.set("has_wipe_tower", has_wipe_tower);
+ m_placeholder_parser.set("has_single_extruder_multi_material_priming", has_wipe_tower && print.config().single_extruder_multi_material_priming);
std::string start_gcode = this->placeholder_parser_process("start_gcode", print.config().start_gcode.value, initial_extruder_id);
-
// Set bed temperature if the start G-code does not contain any bed temp control G-codes.
this->_print_first_layer_bed_temperature(file, print, start_gcode, initial_extruder_id, true);
// Set extruder(s) temperature before and after start G-code.
@@ -638,12 +786,12 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
// Collect outer contours of all objects over all layers.
// Discard objects only containing thin walls (offset would fail on an empty polygon).
Polygons islands;
- for (const PrintObject *object : print.objects())
+ for (const PrintObject *object : printable_objects)
for (const Layer *layer : object->layers())
for (const ExPolygon &expoly : layer->slices.expolygons)
- for (const Point &copy : object->_shifted_copies) {
+ for (const Point &copy : object->copies()) {
islands.emplace_back(expoly.contour);
- islands.back().translate(copy);
+ islands.back().translate(- copy);
}
//FIXME Mege the islands in parallel.
m_avoid_crossing_perimeters.init_external_mp(union_ex(islands));
@@ -660,9 +808,9 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
Polygon outer_skirt = Slic3r::Geometry::convex_hull(skirt_points);
Polygons skirts;
for (unsigned int extruder_id : print.extruders()) {
- const Pointf &extruder_offset = print.config().extruder_offset.get_at(extruder_id);
+ const Vec2d &extruder_offset = print.config().extruder_offset.get_at(extruder_id);
Polygon s(outer_skirt);
- s.translate(-scale_(extruder_offset.x), -scale_(extruder_offset.y));
+ s.translate(Point::new_scale(- extruder_offset(0), - extruder_offset(1)));
skirts.emplace_back(std::move(s));
}
m_ooze_prevention.enable = true;
@@ -681,21 +829,24 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
print.throw_if_canceled();
}
- // Set initial extruder only after custom start G-code.
- _write(file, this->set_extruder(initial_extruder_id));
+ if (! (has_wipe_tower && print.config().single_extruder_multi_material_priming)) {
+ // Set initial extruder only after custom start G-code.
+ // Ugly hack: Do not set the initial extruder if the extruder is primed using the MMU priming towers at the edge of the print bed.
+ _write(file, this->set_extruder(initial_extruder_id));
+ }
// Do all objects for each layer.
if (print.config().complete_objects.value) {
// Print objects from the smallest to the tallest to avoid collisions
// when moving onto next object starting point.
- std::vector<PrintObject*> objects(print.objects());
- std::sort(objects.begin(), objects.end(), [](const PrintObject* po1, const PrintObject* po2) { return po1->size.z < po2->size.z; });
+ std::vector<PrintObject*> objects(printable_objects);
+ std::sort(objects.begin(), objects.end(), [](const PrintObject* po1, const PrintObject* po2) { return po1->size(2) < po2->size(2); });
size_t finished_objects = 0;
for (size_t object_id = initial_print_object_id; object_id < objects.size(); ++ object_id) {
const PrintObject &object = *objects[object_id];
- for (const Point &copy : object._shifted_copies) {
+ for (const Point &copy : object.copies()) {
// Get optimal tool ordering to minimize tool switches of a multi-exruder print.
- if (object_id != initial_print_object_id || &copy != object._shifted_copies.data()) {
+ if (object_id != initial_print_object_id || &copy != object.copies().data()) {
// Don't initialize for the first object and first copy.
tool_ordering = ToolOrdering(object, final_extruder_id);
unsigned int new_extruder_id = tool_ordering.first_extruder();
@@ -707,7 +858,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
assert(final_extruder_id != (unsigned int)-1);
}
print.throw_if_canceled();
- this->set_origin(unscale(copy.x), unscale(copy.y));
+ this->set_origin(unscale(copy));
if (finished_objects > 0) {
// Move to the origin position for the copy we're going to print.
// This happens before Z goes down to layer 0 again, so that no collision happens hopefully.
@@ -736,7 +887,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
for (const LayerToPrint &ltp : layers_to_print) {
std::vector<LayerToPrint> lrs;
lrs.emplace_back(std::move(ltp));
- this->process_layer(file, print, lrs, tool_ordering.tools_for_layer(ltp.print_z()), &copy - object._shifted_copies.data());
+ this->process_layer(file, print, lrs, tool_ordering.tools_for_layer(ltp.print_z()), &copy - object.copies().data());
print.throw_if_canceled();
}
if (m_pressure_equalizer)
@@ -751,8 +902,9 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
// Order objects using a nearest neighbor search.
std::vector<size_t> object_indices;
Points object_reference_points;
- for (PrintObject *object : print.objects())
- object_reference_points.push_back(object->_shifted_copies.front());
+ PrintObjectPtrs printable_objects = print.get_printable_objects();
+ for (PrintObject *object : printable_objects)
+ object_reference_points.push_back(object->copies().front());
Slic3r::Geometry::chained_path(object_reference_points, object_indices);
// Sort layers by Z.
// All extrusion moves with the same top layer height are extruded uninterrupted.
@@ -761,33 +913,35 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
if (has_wipe_tower && ! layers_to_print.empty()) {
m_wipe_tower.reset(new WipeTowerIntegration(print.config(), *print.wipe_tower_data().priming.get(), print.wipe_tower_data().tool_changes, *print.wipe_tower_data().final_purge.get()));
_write(file, m_writer.travel_to_z(first_layer_height + m_config.z_offset.value, "Move to the first layer height"));
- _write(file, m_wipe_tower->prime(*this));
- // Verify, whether the print overaps the priming extrusions.
- BoundingBoxf bbox_print(get_print_extrusions_extents(print));
- coordf_t twolayers_printz = ((layers_to_print.size() == 1) ? layers_to_print.front() : layers_to_print[1]).first + EPSILON;
- for (const PrintObject *print_object : print.objects())
- bbox_print.merge(get_print_object_extrusions_extents(*print_object, twolayers_printz));
- bbox_print.merge(get_wipe_tower_extrusions_extents(print, twolayers_printz));
- BoundingBoxf bbox_prime(get_wipe_tower_priming_extrusions_extents(print));
- bbox_prime.offset(0.5f);
- // Beep for 500ms, tone 800Hz. Yet better, play some Morse.
- _write(file, this->retract());
- _write(file, "M300 S800 P500\n");
- if (bbox_prime.overlap(bbox_print)) {
- // Wait for the user to remove the priming extrusions, otherwise they would
- // get covered by the print.
- _write(file, "M1 Remove priming towers and click button.\n");
- }
- else {
- // Just wait for a bit to let the user check, that the priming succeeded.
- //TODO Add a message explaining what the printer is waiting for. This needs a firmware fix.
- _write(file, "M1 S10\n");
+ if (print.config().single_extruder_multi_material_priming) {
+ _write(file, m_wipe_tower->prime(*this));
+ // Verify, whether the print overaps the priming extrusions.
+ BoundingBoxf bbox_print(get_print_extrusions_extents(print));
+ coordf_t twolayers_printz = ((layers_to_print.size() == 1) ? layers_to_print.front() : layers_to_print[1]).first + EPSILON;
+ for (const PrintObject *print_object : printable_objects)
+ bbox_print.merge(get_print_object_extrusions_extents(*print_object, twolayers_printz));
+ bbox_print.merge(get_wipe_tower_extrusions_extents(print, twolayers_printz));
+ BoundingBoxf bbox_prime(get_wipe_tower_priming_extrusions_extents(print));
+ bbox_prime.offset(0.5f);
+ // Beep for 500ms, tone 800Hz. Yet better, play some Morse.
+ _write(file, this->retract());
+ _write(file, "M300 S800 P500\n");
+ if (bbox_prime.overlap(bbox_print)) {
+ // Wait for the user to remove the priming extrusions, otherwise they would
+ // get covered by the print.
+ _write(file, "M1 Remove priming towers and click button.\n");
+ }
+ else {
+ // Just wait for a bit to let the user check, that the priming succeeded.
+ //TODO Add a message explaining what the printer is waiting for. This needs a firmware fix.
+ _write(file, "M1 S10\n");
+ }
}
print.throw_if_canceled();
}
// Extrude the layers.
for (auto &layer : layers_to_print) {
- const ToolOrdering::LayerTools &layer_tools = tool_ordering.tools_for_layer(layer.first);
+ const LayerTools &layer_tools = tool_ordering.tools_for_layer(layer.first);
if (m_wipe_tower && layer_tools.has_wipe_tower)
m_wipe_tower->next_layer();
this->process_layer(file, print, layer.second, layer_tools, size_t(-1));
@@ -813,30 +967,38 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
}
// Process filament-specific gcode in extruder order.
- if (print.config().single_extruder_multi_material) {
- // Process the end_filament_gcode for the active filament only.
- _writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config().end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id()));
- } else {
- for (const std::string &end_gcode : print.config().end_filament_gcode.values)
- _writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config().end_filament_gcode.values.front())));
+ {
+ DynamicConfig config;
+ config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index));
+ config.set_key_value("layer_z", new ConfigOptionFloat(m_writer.get_position()(2) - m_config.z_offset.value));
+ if (print.config().single_extruder_multi_material) {
+ // Process the end_filament_gcode for the active filament only.
+ _writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config().end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id(), &config));
+ } else {
+ for (const std::string &end_gcode : print.config().end_filament_gcode.values)
+ _writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config().end_filament_gcode.values.front()), &config));
+ }
+ _writeln(file, this->placeholder_parser_process("end_gcode", print.config().end_gcode, m_writer.extruder()->id(), &config));
}
- _writeln(file, this->placeholder_parser_process("end_gcode", print.config().end_gcode, m_writer.extruder()->id()));
_write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
_write(file, m_writer.postamble());
print.throw_if_canceled();
// calculates estimated printing time
- m_time_estimator.calculate_time();
+ m_normal_time_estimator.calculate_time(false);
+ if (m_silent_time_estimator_enabled)
+ m_silent_time_estimator.calculate_time(false);
// Get filament stats.
print.m_print_statistics.clear();
- print.m_print_statistics.estimated_print_time = m_time_estimator.get_time_hms();
+ print.m_print_statistics.estimated_normal_print_time = m_normal_time_estimator.get_time_dhms();
+ print.m_print_statistics.estimated_silent_print_time = m_silent_time_estimator_enabled ? m_silent_time_estimator.get_time_dhms() : "N/A";
for (const Extruder &extruder : m_writer.extruders()) {
double used_filament = extruder.used_filament();
double extruded_volume = extruder.extruded_volume();
double filament_weight = extruded_volume * extruder.filament_density() * 0.001;
double filament_cost = filament_weight * extruder.filament_cost() * 0.001;
- print.m_print_statistics.filament_stats.insert(std::pair<size_t,float>(extruder.id(), used_filament));
+ print.m_print_statistics.filament_stats.insert(std::pair<size_t, float>(extruder.id(), (float)used_filament));
_write_format(file, "; filament used = %.1lfmm (%.1lfcm3)\n", used_filament, extruded_volume * 0.001);
if (filament_weight > 0.) {
print.m_print_statistics.total_weight = print.m_print_statistics.total_weight + filament_weight;
@@ -850,7 +1012,9 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data)
print.m_print_statistics.total_extruded_volume = print.m_print_statistics.total_extruded_volume + extruded_volume;
}
_write_format(file, "; total filament cost = %.1lf\n", print.m_print_statistics.total_cost);
- _write_format(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms().c_str());
+ _write_format(file, "; estimated printing time (normal mode) = %s\n", m_normal_time_estimator.get_time_dhms().c_str());
+ if (m_silent_time_estimator_enabled)
+ _write_format(file, "; estimated printing time (silent mode) = %s\n", m_silent_time_estimator.get_time_dhms().c_str());
// Append full config.
_write(file, "\n");
@@ -938,6 +1102,36 @@ static bool custom_gcode_sets_temperature(const std::string &gcode, const int mc
return temp_set_by_gcode;
}
+// Print the machine envelope G-code for the Marlin firmware based on the "machine_max_xxx" parameters.
+// Do not process this piece of G-code by the time estimator, it already knows the values through another sources.
+void GCode::print_machine_envelope(FILE *file, Print &print)
+{
+ if (print.config().gcode_flavor.value == gcfMarlin) {
+ fprintf(file, "M201 X%d Y%d Z%d E%d ; sets maximum accelerations, mm/sec^2\n",
+ int(print.config().machine_max_acceleration_x.values.front() + 0.5),
+ int(print.config().machine_max_acceleration_y.values.front() + 0.5),
+ int(print.config().machine_max_acceleration_z.values.front() + 0.5),
+ int(print.config().machine_max_acceleration_e.values.front() + 0.5));
+ fprintf(file, "M203 X%d Y%d Z%d E%d ; sets maximum feedrates, mm/sec\n",
+ int(print.config().machine_max_feedrate_x.values.front() + 0.5),
+ int(print.config().machine_max_feedrate_y.values.front() + 0.5),
+ int(print.config().machine_max_feedrate_z.values.front() + 0.5),
+ int(print.config().machine_max_feedrate_e.values.front() + 0.5));
+ fprintf(file, "M204 P%d R%d T%d ; sets acceleration (P, T) and retract acceleration (R), mm/sec^2\n",
+ int(print.config().machine_max_acceleration_extruding.values.front() + 0.5),
+ int(print.config().machine_max_acceleration_retracting.values.front() + 0.5),
+ int(print.config().machine_max_acceleration_extruding.values.front() + 0.5));
+ fprintf(file, "M205 X%.2lf Y%.2lf Z%.2lf E%.2lf ; sets the jerk limits, mm/sec\n",
+ print.config().machine_max_jerk_x.values.front(),
+ print.config().machine_max_jerk_y.values.front(),
+ print.config().machine_max_jerk_z.values.front(),
+ print.config().machine_max_jerk_e.values.front());
+ fprintf(file, "M205 S%d T%d ; sets the minimum extruding and travel feed rate, mm/sec\n",
+ int(print.config().machine_min_extruding_rate.values.front() + 0.5),
+ int(print.config().machine_min_travel_rate.values.front() + 0.5));
+ }
+}
+
// Write 1st layer bed temperatures into the G-code.
// Only do that if the start G-code does not already contain any M-code controlling an extruder temperature.
// M140 - Set Extruder Temperature
@@ -1028,7 +1222,7 @@ void GCode::process_layer(
const Print &print,
// Set of object & print layers of the same PrintObject and with the same print_z.
const std::vector<LayerToPrint> &layers,
- const ToolOrdering::LayerTools &layer_tools,
+ const LayerTools &layer_tools,
// If set to size_t(-1), then print all copies of all objects.
// Otherwise print a single copy of a single object.
const size_t single_object_idx)
@@ -1166,7 +1360,6 @@ void GCode::process_layer(
// Group extrusions by an extruder, then by an object, an island and a region.
std::map<unsigned int, std::vector<ObjectByExtruder>> by_extruder;
-
for (const LayerToPrint &layer_to_print : layers) {
if (layer_to_print.support_layer != nullptr) {
const SupportLayer &support_layer = *layer_to_print.support_layer;
@@ -1233,8 +1426,8 @@ void GCode::process_layer(
layer_surface_bboxes.push_back(get_extents(expoly.contour));
auto point_inside_surface = [&layer, &layer_surface_bboxes](const size_t i, const Point &point) {
const BoundingBox &bbox = layer_surface_bboxes[i];
- return point.x >= bbox.min.x && point.x < bbox.max.x &&
- point.y >= bbox.min.y && point.y < bbox.max.y &&
+ return point(0) >= bbox.min(0) && point(0) < bbox.max(0) &&
+ point(1) >= bbox.min(1) && point(1) < bbox.max(1) &&
layer.slices.expolygons[i].contour.contains(point);
};
@@ -1243,74 +1436,77 @@ void GCode::process_layer(
if (layerm == nullptr)
continue;
const PrintRegion &region = *print.regions()[region_id];
-
- // process perimeters
- for (const ExtrusionEntity *ee : layerm->perimeters.entities) {
- // perimeter_coll represents perimeter extrusions of a single island.
- const auto *perimeter_coll = dynamic_cast<const ExtrusionEntityCollection*>(ee);
- if (perimeter_coll->entities.empty())
- // This shouldn't happen but first_point() would fail.
- continue;
- // Init by_extruder item only if we actually use the extruder.
- std::vector<ObjectByExtruder::Island> &islands = object_islands_by_extruder(
- by_extruder,
- std::max<int>(region.config().perimeter_extruder.value - 1, 0),
- &layer_to_print - layers.data(),
- layers.size(), n_slices+1);
- for (size_t i = 0; i <= n_slices; ++ i)
- if (// perimeter_coll->first_point does not fit inside any slice
- i == n_slices ||
- // perimeter_coll->first_point fits inside ith slice
- point_inside_surface(i, perimeter_coll->first_point())) {
- if (islands[i].by_region.empty())
- islands[i].by_region.assign(print.regions().size(), ObjectByExtruder::Island::Region());
- islands[i].by_region[region_id].perimeters.append(perimeter_coll->entities);
- break;
- }
- }
-
- // process infill
- // layerm->fills is a collection of Slic3r::ExtrusionPath::Collection objects (C++ class ExtrusionEntityCollection),
- // each one containing the ExtrusionPath objects of a certain infill "group" (also called "surface"
- // throughout the code). We can redefine the order of such Collections but we have to
- // do each one completely at once.
- for (const ExtrusionEntity *ee : layerm->fills.entities) {
- // fill represents infill extrusions of a single island.
- const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
- if (fill->entities.empty())
- // This shouldn't happen but first_point() would fail.
- continue;
- // init by_extruder item only if we actually use the extruder
- int extruder_id = std::max<int>(0, (is_solid_infill(fill->entities.front()->role()) ? region.config().solid_infill_extruder : region.config().infill_extruder) - 1);
- // Init by_extruder item only if we actually use the extruder.
- std::vector<ObjectByExtruder::Island> &islands = object_islands_by_extruder(
- by_extruder,
- extruder_id,
- &layer_to_print - layers.data(),
- layers.size(), n_slices+1);
- for (size_t i = 0; i <= n_slices; ++i)
- if (// fill->first_point does not fit inside any slice
- i == n_slices ||
- // fill->first_point fits inside ith slice
- point_inside_surface(i, fill->first_point())) {
- if (islands[i].by_region.empty())
- islands[i].by_region.assign(print.regions().size(), ObjectByExtruder::Island::Region());
- islands[i].by_region[region_id].infills.append(fill->entities);
- break;
+
+
+ // Now we must process perimeters and infills and create islands of extrusions in by_region std::map.
+ // It is also necessary to save which extrusions are part of MM wiping and which are not.
+ // The process is almost the same for perimeters and infills - we will do it in a cycle that repeats twice:
+ for (std::string entity_type("infills") ; entity_type != "done" ; entity_type = entity_type=="infills" ? "perimeters" : "done") {
+
+ const ExtrusionEntitiesPtr& source_entities = entity_type=="infills" ? layerm->fills.entities : layerm->perimeters.entities;
+
+ for (const ExtrusionEntity *ee : source_entities) {
+ // fill represents infill extrusions of a single island.
+ const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
+ if (fill->entities.empty()) // This shouldn't happen but first_point() would fail.
+ continue;
+
+ // This extrusion is part of certain Region, which tells us which extruder should be used for it:
+ int correct_extruder_id = Print::get_extruder(*fill, region);
+ //FIXME what is this?
+ entity_type=="infills" ?
+ std::max<int>(0, (is_solid_infill(fill->entities.front()->role()) ? region.config().solid_infill_extruder : region.config().infill_extruder) - 1) :
+ std::max<int>(region.config().perimeter_extruder.value - 1, 0);
+
+ // Let's recover vector of extruder overrides:
+ const ExtruderPerCopy* entity_overrides = const_cast<LayerTools&>(layer_tools).wiping_extrusions().get_extruder_overrides(fill, correct_extruder_id, layer_to_print.object()->copies().size());
+
+ // Now we must add this extrusion into the by_extruder map, once for each extruder that will print it:
+ for (unsigned int extruder : layer_tools.extruders)
+ {
+ // Init by_extruder item only if we actually use the extruder:
+ if (std::find(entity_overrides->begin(), entity_overrides->end(), extruder) != entity_overrides->end() || // at least one copy is overridden to use this extruder
+ std::find(entity_overrides->begin(), entity_overrides->end(), -extruder-1) != entity_overrides->end() || // at least one copy would normally be printed with this extruder (see get_extruder_overrides function for explanation)
+ (std::find(layer_tools.extruders.begin(), layer_tools.extruders.end(), correct_extruder_id) == layer_tools.extruders.end() && extruder == layer_tools.extruders.back())) // this entity is not overridden, but its extruder is not in layer_tools - we'll print it
+ //by last extruder on this layer (could happen e.g. when a wiping object is taller than others - dontcare extruders are eradicated from layer_tools)
+ {
+ std::vector<ObjectByExtruder::Island> &islands = object_islands_by_extruder(
+ by_extruder,
+ extruder,
+ &layer_to_print - layers.data(),
+ layers.size(), n_slices+1);
+ for (size_t i = 0; i <= n_slices; ++i)
+ if (// fill->first_point does not fit inside any slice
+ i == n_slices ||
+ // fill->first_point fits inside ith slice
+ point_inside_surface(i, fill->first_point())) {
+ if (islands[i].by_region.empty())
+ islands[i].by_region.assign(print.regions().size(), ObjectByExtruder::Island::Region());
+ islands[i].by_region[region_id].append(entity_type, fill, entity_overrides, layer_to_print.object()->copies().size());
+ break;
+ }
+ }
}
+ }
}
} // for regions
}
} // for objects
+
+
// Extrude the skirt, brim, support, perimeters, infill ordered by the extruders.
std::vector<std::unique_ptr<EdgeGrid::Grid>> lower_layer_edge_grids(layers.size());
for (unsigned int extruder_id : layer_tools.extruders)
- {
+ {
gcode += (layer_tools.has_wipe_tower && m_wipe_tower) ?
m_wipe_tower->tool_change(*this, extruder_id, extruder_id == layer_tools.extruders.back()) :
this->set_extruder(extruder_id);
+ // let analyzer tag generator aware of a role type change
+ if (m_enable_analyzer && layer_tools.has_wipe_tower && m_wipe_tower)
+ m_last_analyzer_extrusion_role = erWipeTower;
+
if (extrude_skirt) {
auto loops_it = skirt_loops_per_extruder.find(extruder_id);
if (loops_it != skirt_loops_per_extruder.end()) {
@@ -1327,7 +1523,7 @@ void GCode::process_layer(
for (ExtrusionPath &path : loop.paths) {
path.height = (float)layer.height;
path.mm3_per_mm = mm3_per_mm;
- }
+ }
gcode += this->extrude_loop(loop, "skirt", m_config.support_material_speed.value);
}
m_avoid_crossing_perimeters.use_external_mp = false;
@@ -1336,7 +1532,7 @@ void GCode::process_layer(
m_avoid_crossing_perimeters.disable_once = true;
}
}
-
+
// Extrude brim with the extruder of the 1st region.
if (! m_brim_done) {
this->set_origin(0., 0.);
@@ -1349,49 +1545,60 @@ void GCode::process_layer(
m_avoid_crossing_perimeters.disable_once = true;
}
+
auto objects_by_extruder_it = by_extruder.find(extruder_id);
if (objects_by_extruder_it == by_extruder.end())
continue;
- for (const ObjectByExtruder &object_by_extruder : objects_by_extruder_it->second) {
- const size_t layer_id = &object_by_extruder - objects_by_extruder_it->second.data();
- const PrintObject *print_object = layers[layer_id].object();
- if (print_object == nullptr)
- // This layer is empty for this particular object, it has neither object extrusions nor support extrusions at this print_z.
- continue;
-
- m_config.apply(print_object->config(), true);
- m_layer = layers[layer_id].layer();
- if (m_config.avoid_crossing_perimeters)
- m_avoid_crossing_perimeters.init_layer_mp(union_ex(m_layer->slices, true));
- Points copies;
- if (single_object_idx == size_t(-1))
- copies = print_object->_shifted_copies;
- else
- copies.push_back(print_object->_shifted_copies[single_object_idx]);
- // Sort the copies by the closest point starting with the current print position.
-
- for (const Point &copy : copies) {
- // When starting a new object, use the external motion planner for the first travel move.
- std::pair<const PrintObject*, Point> this_object_copy(print_object, copy);
- if (m_last_obj_copy != this_object_copy)
- m_avoid_crossing_perimeters.use_external_mp_once = true;
- m_last_obj_copy = this_object_copy;
- this->set_origin(unscale(copy.x), unscale(copy.y));
- if (object_by_extruder.support != nullptr) {
- m_layer = layers[layer_id].support_layer;
- gcode += this->extrude_support(
- // support_extrusion_role is erSupportMaterial, erSupportMaterialInterface or erMixed for all extrusion paths.
- object_by_extruder.support->chained_path_from(m_last_pos, false, object_by_extruder.support_extrusion_role));
- m_layer = layers[layer_id].layer();
- }
- for (const ObjectByExtruder::Island &island : object_by_extruder.islands) {
- if (print.config().infill_first) {
- gcode += this->extrude_infill(print, island.by_region);
- gcode += this->extrude_perimeters(print, island.by_region, lower_layer_edge_grids[layer_id]);
- } else {
- gcode += this->extrude_perimeters(print, island.by_region, lower_layer_edge_grids[layer_id]);
- gcode += this->extrude_infill(print, island.by_region);
+ // We are almost ready to print. However, we must go through all the objects twice to print the the overridden extrusions first (infill/perimeter wiping feature):
+ for (int print_wipe_extrusions=const_cast<LayerTools&>(layer_tools).wiping_extrusions().is_anything_overridden(); print_wipe_extrusions>=0; --print_wipe_extrusions) {
+ if (print_wipe_extrusions == 0)
+ gcode+="; PURGING FINISHED\n";
+
+ for (ObjectByExtruder &object_by_extruder : objects_by_extruder_it->second) {
+ const size_t layer_id = &object_by_extruder - objects_by_extruder_it->second.data();
+ const PrintObject *print_object = layers[layer_id].object();
+ if (print_object == nullptr)
+ // This layer is empty for this particular object, it has neither object extrusions nor support extrusions at this print_z.
+ continue;
+
+ m_config.apply(print_object->config(), true);
+ m_layer = layers[layer_id].layer();
+ if (m_config.avoid_crossing_perimeters)
+ m_avoid_crossing_perimeters.init_layer_mp(union_ex(m_layer->slices, true));
+ Points copies;
+ if (single_object_idx == size_t(-1))
+ copies = print_object->copies();
+ else
+ copies.push_back(print_object->copies()[single_object_idx]);
+ // Sort the copies by the closest point starting with the current print position.
+
+ unsigned int copy_id = 0;
+ for (const Point &copy : copies) {
+ // When starting a new object, use the external motion planner for the first travel move.
+ std::pair<const PrintObject*, Point> this_object_copy(print_object, copy);
+ if (m_last_obj_copy != this_object_copy)
+ m_avoid_crossing_perimeters.use_external_mp_once = true;
+ m_last_obj_copy = this_object_copy;
+ this->set_origin(unscale(copy));
+ if (object_by_extruder.support != nullptr && !print_wipe_extrusions) {
+ m_layer = layers[layer_id].support_layer;
+ gcode += this->extrude_support(
+ // support_extrusion_role is erSupportMaterial, erSupportMaterialInterface or erMixed for all extrusion paths.
+ object_by_extruder.support->chained_path_from(m_last_pos, false, object_by_extruder.support_extrusion_role));
+ m_layer = layers[layer_id].layer();
+ }
+ for (ObjectByExtruder::Island &island : object_by_extruder.islands) {
+ const auto& by_region_specific = const_cast<LayerTools&>(layer_tools).wiping_extrusions().is_anything_overridden() ? island.by_region_per_copy(copy_id, extruder_id, print_wipe_extrusions) : island.by_region;
+
+ if (print.config().infill_first) {
+ gcode += this->extrude_infill(print, by_region_specific);
+ gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[layer_id]);
+ } else {
+ gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[layer_id]);
+ gcode += this->extrude_infill(print,by_region_specific);
+ }
}
+ ++copy_id;
}
}
}
@@ -1414,7 +1621,7 @@ void GCode::process_layer(
if (m_pressure_equalizer)
gcode = m_pressure_equalizer->process(gcode.c_str(), false);
// printf("G-code after filter:\n%s\n", out.c_str());
-
+
_write(file, gcode);
}
@@ -1426,15 +1633,22 @@ void GCode::apply_print_config(const PrintConfig &print_config)
void GCode::append_full_config(const Print& print, std::string& str)
{
- const StaticPrintConfig *configs[] = { &print.config(), &print.default_object_config(), &print.default_region_config() };
+ const StaticPrintConfig *configs[] = { static_cast<const GCodeConfig*>(&print.config()), &print.default_object_config(), &print.default_region_config() };
for (size_t i = 0; i < sizeof(configs) / sizeof(configs[0]); ++i) {
const StaticPrintConfig *cfg = configs[i];
for (const std::string &key : cfg->keys())
- {
if (key != "compatible_printers")
str += "; " + key + " = " + cfg->serialize(key) + "\n";
- }
}
+ const DynamicConfig &full_config = print.placeholder_parser().config();
+ for (const char *key : {
+ "print_settings_id", "filament_settings_id", "printer_settings_id",
+ "printer_model", "printer_variant", "default_print_profile", "default_filament_profile",
+ "compatible_printers_condition_cummulative", "inherits_cummulative" }) {
+ const ConfigOption *opt = full_config.option(key);
+ if (opt != nullptr)
+ str += std::string("; ") + key + " = " + opt->serialize() + "\n";
+ }
}
void GCode::set_extruders(const std::vector<unsigned int> &extruder_ids)
@@ -1450,14 +1664,14 @@ void GCode::set_extruders(const std::vector<unsigned int> &extruder_ids)
}
}
-void GCode::set_origin(const Pointf &pointf)
+void GCode::set_origin(const Vec2d &pointf)
{
// if origin increases (goes towards right), last_pos decreases because it goes towards left
const Point translate(
- scale_(m_origin.x - pointf.x),
- scale_(m_origin.y - pointf.y)
+ scale_(m_origin(0) - pointf(0)),
+ scale_(m_origin(1) - pointf(1))
);
- m_last_pos.translate(translate);
+ m_last_pos += translate;
m_wipe.path.translate(translate);
m_origin = pointf;
}
@@ -1588,13 +1802,13 @@ static Points::iterator project_point_to_polygon_and_insert(Polygon &polygon, co
j = 0;
const Point &p1 = polygon.points[i];
const Point &p2 = polygon.points[j];
- const Slic3r::Point v_seg = p1.vector_to(p2);
- const Slic3r::Point v_pt = p1.vector_to(pt);
- const int64_t l2_seg = int64_t(v_seg.x) * int64_t(v_seg.x) + int64_t(v_seg.y) * int64_t(v_seg.y);
- int64_t t_pt = int64_t(v_seg.x) * int64_t(v_pt.x) + int64_t(v_seg.y) * int64_t(v_pt.y);
+ const Slic3r::Point v_seg = p2 - p1;
+ const Slic3r::Point v_pt = pt - p1;
+ const int64_t l2_seg = int64_t(v_seg(0)) * int64_t(v_seg(0)) + int64_t(v_seg(1)) * int64_t(v_seg(1));
+ int64_t t_pt = int64_t(v_seg(0)) * int64_t(v_pt(0)) + int64_t(v_seg(1)) * int64_t(v_pt(1));
if (t_pt < 0) {
// Closest to p1.
- double dabs = sqrt(int64_t(v_pt.x) * int64_t(v_pt.x) + int64_t(v_pt.y) * int64_t(v_pt.y));
+ double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1)));
if (dabs < d_min) {
d_min = dabs;
i_min = i;
@@ -1607,7 +1821,7 @@ static Points::iterator project_point_to_polygon_and_insert(Polygon &polygon, co
} else {
// Closest to the segment.
assert(t_pt >= 0 && t_pt <= l2_seg);
- int64_t d_seg = int64_t(v_seg.y) * int64_t(v_pt.x) - int64_t(v_seg.x) * int64_t(v_pt.y);
+ int64_t d_seg = int64_t(v_seg(1)) * int64_t(v_pt(0)) - int64_t(v_seg(0)) * int64_t(v_pt(1));
double d = double(d_seg) / sqrt(double(l2_seg));
double dabs = std::abs(d);
if (dabs < d_min) {
@@ -1616,15 +1830,15 @@ static Points::iterator project_point_to_polygon_and_insert(Polygon &polygon, co
// Evaluate the foot point.
pt_min = p1;
double linv = double(d_seg) / double(l2_seg);
- pt_min.x = pt.x - coord_t(floor(double(v_seg.y) * linv + 0.5));
- pt_min.y = pt.y + coord_t(floor(double(v_seg.x) * linv + 0.5));
+ pt_min(0) = pt(0) - coord_t(floor(double(v_seg(1)) * linv + 0.5));
+ pt_min(1) = pt(1) + coord_t(floor(double(v_seg(0)) * linv + 0.5));
assert(Line(p1, p2).distance_to(pt_min) < scale_(1e-5));
}
}
}
assert(i_min != size_t(-1));
- if (pt_min.distance_to(polygon.points[i_min]) > eps) {
+ if ((pt_min - polygon.points[i_min]).cast<double>().norm() > eps) {
// Insert a new point on the segment i_min, i_min+1.
return polygon.points.insert(polygon.points.begin() + (i_min + 1), pt_min);
}
@@ -1636,8 +1850,8 @@ std::vector<float> polygon_parameter_by_length(const Polygon &polygon)
// Parametrize the polygon by its length.
std::vector<float> lengths(polygon.points.size()+1, 0.);
for (size_t i = 1; i < polygon.points.size(); ++ i)
- lengths[i] = lengths[i-1] + float(polygon.points[i].distance_to(polygon.points[i-1]));
- lengths.back() = lengths[lengths.size()-2] + float(polygon.points.front().distance_to(polygon.points.back()));
+ lengths[i] = lengths[i-1] + (polygon.points[i] - polygon.points[i-1]).cast<float>().norm();
+ lengths.back() = lengths[lengths.size()-2] + (polygon.points.front() - polygon.points.back()).cast<float>().norm();
return lengths;
}
@@ -1685,10 +1899,10 @@ std::vector<float> polygon_angles_at_vertices(const Polygon &polygon, const std:
const Point &p0 = polygon.points[idx_prev];
const Point &p1 = polygon.points[idx_curr];
const Point &p2 = polygon.points[idx_next];
- const Point v1 = p0.vector_to(p1);
- const Point v2 = p1.vector_to(p2);
- int64_t dot = int64_t(v1.x)*int64_t(v2.x) + int64_t(v1.y)*int64_t(v2.y);
- int64_t cross = int64_t(v1.x)*int64_t(v2.y) - int64_t(v1.y)*int64_t(v2.x);
+ const Point v1 = p1 - p0;
+ const Point v2 = p2 - p1;
+ int64_t dot = int64_t(v1(0))*int64_t(v2(0)) + int64_t(v1(1))*int64_t(v2(1));
+ int64_t cross = int64_t(v1(0))*int64_t(v2(1)) - int64_t(v1(1))*int64_t(v2(0));
float angle = float(atan2(double(cross), double(dot)));
angles[idx_curr] = angle;
}
@@ -1712,10 +1926,10 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
{
static int iRun = 0;
BoundingBox bbox = (*lower_layer_edge_grid)->bbox();
- bbox.min.x -= scale_(5.f);
- bbox.min.y -= scale_(5.f);
- bbox.max.x += scale_(5.f);
- bbox.max.y += scale_(5.f);
+ bbox.min(0) -= scale_(5.f);
+ bbox.min(1) -= scale_(5.f);
+ bbox.max(0) += scale_(5.f);
+ bbox.max(1) += scale_(5.f);
EdgeGrid::save_png(*(*lower_layer_edge_grid), bbox, scale_(0.1f), debug_out_path("GCode_extrude_loop_edge_grid-%d.png", iRun++));
}
#endif
@@ -1751,7 +1965,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
break;
case spRear:
last_pos = m_layer->object()->bounding_box().center();
- last_pos.y += coord_t(3. * m_layer->object()->bounding_box().radius());
+ last_pos(1) += coord_t(3. * m_layer->object()->bounding_box().radius());
last_pos_weight = 5.f;
break;
}
@@ -1884,7 +2098,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
//FIXME Better parametrize the loop by its length.
Polygon polygon = loop.polygon();
Point centroid = polygon.centroid();
- last_pos = Point(polygon.bounding_box().max.x, centroid.y);
+ last_pos = Point(polygon.bounding_box().max(0), centroid(1));
last_pos.rotate(fmod((float)rand()/16.0, 2.0*PI), centroid);
}
// Find the closest point, avoid overhangs.
@@ -1941,19 +2155,17 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
// create the destination point along the first segment and rotate it
// we make sure we don't exceed the segment length because we don't know
// the rotation of the second segment so we might cross the object boundary
- Line first_segment(
- paths.front().polyline.points[0],
- paths.front().polyline.points[1]
- );
- double distance = std::min<double>(
- scale_(EXTRUDER_CONFIG(nozzle_diameter)),
- first_segment.length()
- );
- Point point = first_segment.point_at(distance);
- point.rotate(angle, first_segment.a);
-
+ Vec2d p1 = paths.front().polyline.points.front().cast<double>();
+ Vec2d p2 = paths.front().polyline.points[1].cast<double>();
+ Vec2d v = p2 - p1;
+ double nd = scale_(EXTRUDER_CONFIG(nozzle_diameter));
+ double l2 = v.squaredNorm();
+ // Shift by no more than a nozzle diameter.
+ //FIXME Hiding the seams will not work nicely for very densely discretized contours!
+ Point pt = ((nd * nd >= l2) ? p2 : (p1 + v * (nd / sqrt(l2)))).cast<coord_t>();
+ pt.rotate(angle, paths.front().polyline.points.front());
// generate the travel move
- gcode += m_writer.travel_to_xy(this->point_to_gcode(point), "move inwards before travel");
+ gcode += m_writer.travel_to_xy(this->point_to_gcode(pt), "move inwards before travel");
}
return gcode;
@@ -2074,7 +2286,9 @@ void GCode::_write(FILE* file, const char *what)
// writes string to file
fwrite(gcode, 1, ::strlen(gcode), file);
// updates time estimator and gcode lines vector
- m_time_estimator.add_gcode_block(gcode);
+ m_normal_time_estimator.add_gcode_block(gcode);
+ if (m_silent_time_estimator_enabled)
+ m_silent_time_estimator.add_gcode_block(gcode);
}
}
@@ -2121,7 +2335,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
std::string gcode;
// go to first point of extrusion path
- if (!m_last_pos_defined || !m_last_pos.coincides_with(path.first_point())) {
+ if (!m_last_pos_defined || m_last_pos != path.first_point()) {
gcode += this->travel_to(
path.first_point(),
path.role(),
@@ -2194,7 +2408,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
double F = speed * 60; // convert mm/sec to mm/min
// extrude arc or line
- if (m_enable_extrusion_role_markers || m_enable_analyzer)
+ if (m_enable_extrusion_role_markers)
{
if (path.role() != m_last_extrusion_role)
{
@@ -2205,18 +2419,20 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
sprintf(buf, ";_EXTRUSION_ROLE:%d\n", int(m_last_extrusion_role));
gcode += buf;
}
- if (m_enable_analyzer)
- {
- char buf[32];
- sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), int(m_last_extrusion_role));
- gcode += buf;
- }
}
}
// adds analyzer tags and updates analyzer's tracking data
if (m_enable_analyzer)
{
+ if (path.role() != m_last_analyzer_extrusion_role)
+ {
+ m_last_analyzer_extrusion_role = path.role();
+ char buf[32];
+ sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), int(m_last_analyzer_extrusion_role));
+ gcode += buf;
+ }
+
if (m_last_mm3_per_mm != path.mm3_per_mm)
{
m_last_mm3_per_mm = path.mm3_per_mm;
@@ -2254,6 +2470,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
if (path.role() == erExternalPerimeter)
comment += ";_EXTERNAL_PERIMETER";
}
+
// F is mm per minute.
gcode += m_writer.set_speed(F, "", comment);
double path_length = 0.;
@@ -2433,21 +2650,76 @@ std::string GCode::set_extruder(unsigned int extruder_id)
}
// convert a model-space scaled point into G-code coordinates
-Pointf GCode::point_to_gcode(const Point &point) const
+Vec2d GCode::point_to_gcode(const Point &point) const
{
- Pointf extruder_offset = EXTRUDER_CONFIG(extruder_offset);
- return Pointf(
- unscale(point.x) + m_origin.x - extruder_offset.x,
- unscale(point.y) + m_origin.y - extruder_offset.y);
+ Vec2d extruder_offset = EXTRUDER_CONFIG(extruder_offset);
+ return unscale(point) + m_origin - extruder_offset;
}
// convert a model-space scaled point into G-code coordinates
-Point GCode::gcode_to_point(const Pointf &point) const
+Point GCode::gcode_to_point(const Vec2d &point) const
{
- Pointf extruder_offset = EXTRUDER_CONFIG(extruder_offset);
+ Vec2d extruder_offset = EXTRUDER_CONFIG(extruder_offset);
return Point(
- scale_(point.x - m_origin.x + extruder_offset.x),
- scale_(point.y - m_origin.y + extruder_offset.y));
+ scale_(point(0) - m_origin(0) + extruder_offset(0)),
+ scale_(point(1) - m_origin(1) + extruder_offset(1)));
}
+// Goes through by_region std::vector and returns reference to a subvector of entities, that are to be printed
+// during infill/perimeter wiping, or normally (depends on wiping_entities parameter)
+// Returns a reference to member to avoid copying.
+const std::vector<GCode::ObjectByExtruder::Island::Region>& GCode::ObjectByExtruder::Island::by_region_per_copy(unsigned int copy, int extruder, bool wiping_entities)
+{
+ by_region_per_copy_cache.clear();
+
+ for (const auto& reg : by_region) {
+ by_region_per_copy_cache.push_back(ObjectByExtruder::Island::Region()); // creates a region in the newly created Island
+
+ // Now we are going to iterate through perimeters and infills and pick ones that are supposed to be printed
+ // References are used so that we don't have to repeat the same code
+ for (int iter = 0; iter < 2; ++iter) {
+ const ExtrusionEntitiesPtr& entities = (iter ? reg.infills.entities : reg.perimeters.entities);
+ ExtrusionEntityCollection& target_eec = (iter ? by_region_per_copy_cache.back().infills : by_region_per_copy_cache.back().perimeters);
+ const std::vector<const ExtruderPerCopy*>& overrides = (iter ? reg.infills_overrides : reg.perimeters_overrides);
+
+ // Now the most important thing - which extrusion should we print.
+ // See function ToolOrdering::get_extruder_overrides for details about the negative numbers hack.
+ int this_extruder_mark = wiping_entities ? extruder : -extruder-1;
+
+ for (unsigned int i=0;i<entities.size();++i)
+ if (overrides[i]->at(copy) == this_extruder_mark) // this copy should be printed with this extruder
+ target_eec.append((*entities[i]));
+ }
+ }
+ return by_region_per_copy_cache;
}
+
+
+
+// This function takes the eec and appends its entities to either perimeters or infills of this Region (depending on the first parameter)
+// It also saves pointer to ExtruderPerCopy struct (for each entity), that holds information about which extruders should be used for which copy.
+void GCode::ObjectByExtruder::Island::Region::append(const std::string& type, const ExtrusionEntityCollection* eec, const ExtruderPerCopy* copies_extruder, unsigned int object_copies_num)
+{
+ // We are going to manipulate either perimeters or infills, exactly in the same way. Let's create pointers to the proper structure to not repeat ourselves:
+ ExtrusionEntityCollection* perimeters_or_infills = &infills;
+ std::vector<const ExtruderPerCopy*>* perimeters_or_infills_overrides = &infills_overrides;
+
+ if (type == "perimeters") {
+ perimeters_or_infills = &perimeters;
+ perimeters_or_infills_overrides = &perimeters_overrides;
+ }
+ else
+ if (type != "infills") {
+ CONFESS("Unknown parameter!");
+ return;
+ }
+
+
+ // First we append the entities, there are eec->entities.size() of them:
+ perimeters_or_infills->append(eec->entities);
+
+ for (unsigned int i=0;i<eec->entities.size();++i)
+ perimeters_or_infills_overrides->push_back(copies_extruder);
+}
+
+} // namespace Slic3r
diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp
index 0e5305cb5..34183012a 100644
--- a/xs/src/libslic3r/GCode.hpp
+++ b/xs/src/libslic3r/GCode.hpp
@@ -83,8 +83,10 @@ public:
const WipeTower::ToolChangeResult &priming,
const std::vector<std::vector<WipeTower::ToolChangeResult>> &tool_changes,
const WipeTower::ToolChangeResult &final_purge) :
- m_left(float(print_config.wipe_tower_x.value)),
- m_right(float(print_config.wipe_tower_x.value + print_config.wipe_tower_width.value)),
+ m_left(/*float(print_config.wipe_tower_x.value)*/ 0.f),
+ m_right(float(/*print_config.wipe_tower_x.value +*/ print_config.wipe_tower_width.value)),
+ m_wipe_tower_pos(float(print_config.wipe_tower_x.value), float(print_config.wipe_tower_y.value)),
+ m_wipe_tower_rotation(float(print_config.wipe_tower_rotation_angle)),
m_priming(priming),
m_tool_changes(tool_changes),
m_final_purge(final_purge),
@@ -101,9 +103,14 @@ private:
WipeTowerIntegration& operator=(const WipeTowerIntegration&);
std::string append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id) const;
+ // Postprocesses gcode: rotates and moves all G1 extrusions and returns result
+ std::string rotate_wipe_tower_moves(const std::string& gcode_original, const WipeTower::xy& start_pos, const WipeTower::xy& translation, float angle) const;
+
// Left / right edges of the wipe tower, for the planning of wipe moves.
const float m_left;
const float m_right;
+ const WipeTower::xy m_wipe_tower_pos;
+ const float m_wipe_tower_rotation;
// Reference to cached values at the Printer class.
const WipeTower::ToolChangeResult &m_priming;
const std::vector<std::vector<WipeTower::ToolChangeResult>> &m_tool_changes;
@@ -112,15 +119,18 @@ private:
int m_layer_idx;
int m_tool_change_idx;
bool m_brim_done;
+ bool i_have_brim = false;
};
class GCode {
public:
GCode() :
+ m_origin(Vec2d::Zero()),
m_enable_loop_clipping(true),
m_enable_cooling_markers(false),
m_enable_extrusion_role_markers(false),
m_enable_analyzer(false),
+ m_last_analyzer_extrusion_role(erNone),
m_layer_count(0),
m_layer_index(-1),
m_layer(nullptr),
@@ -132,6 +142,9 @@ public:
m_last_height(GCodeAnalyzer::Default_Height),
m_brim_done(false),
m_second_layer_things_done(false),
+ m_normal_time_estimator(GCodeTimeEstimator::Normal),
+ m_silent_time_estimator(GCodeTimeEstimator::Silent),
+ m_silent_time_estimator_enabled(false),
m_last_obj_copy(nullptr, Point(std::numeric_limits<coord_t>::max(), std::numeric_limits<coord_t>::max()))
{}
~GCode() {}
@@ -141,12 +154,12 @@ public:
void do_export(Print *print, const char *path, GCodePreviewData *preview_data = nullptr);
// Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests.
- const Pointf& origin() const { return m_origin; }
- void set_origin(const Pointf &pointf);
- void set_origin(const coordf_t x, const coordf_t y) { this->set_origin(Pointf(x, y)); }
+ const Vec2d& origin() const { return m_origin; }
+ void set_origin(const Vec2d &pointf);
+ void set_origin(const coordf_t x, const coordf_t y) { this->set_origin(Vec2d(x, y)); }
const Point& last_pos() const { return m_last_pos; }
- Pointf point_to_gcode(const Point &point) const;
- Point gcode_to_point(const Pointf &point) const;
+ Vec2d point_to_gcode(const Point &point) const;
+ Point gcode_to_point(const Vec2d &point) const;
const FullPrintConfig &config() const { return m_config; }
const Layer* layer() const { return m_layer; }
GCodeWriter& writer() { return m_writer; }
@@ -186,7 +199,7 @@ protected:
const Print &print,
// Set of object & print layers of the same PrintObject and with the same print_z.
const std::vector<LayerToPrint> &layers,
- const ToolOrdering::LayerTools &layer_tools,
+ const LayerTools &layer_tools,
// If set to size_t(-1), then print all copies of all objects.
// Otherwise print a single copy of a single object.
const size_t single_object_idx = size_t(-1));
@@ -201,6 +214,7 @@ protected:
std::string extrude_multi_path(ExtrusionMultiPath multipath, std::string description = "", double speed = -1.);
std::string extrude_path(ExtrusionPath path, std::string description = "", double speed = -1.);
+ typedef std::vector<int> ExtruderPerCopy;
// Extruding multiple objects with soluble / non-soluble / combined supports
// on a multi-material printer, trying to minimize tool switches.
// Following structures sort extrusions by the extruder ID, by an order of objects and object islands.
@@ -216,11 +230,24 @@ protected:
struct Region {
ExtrusionEntityCollection perimeters;
ExtrusionEntityCollection infills;
+
+ std::vector<const ExtruderPerCopy*> infills_overrides;
+ std::vector<const ExtruderPerCopy*> perimeters_overrides;
+
+ // Appends perimeter/infill entities and writes don't indices of those that are not to be extruder as part of perimeter/infill wiping
+ void append(const std::string& type, const ExtrusionEntityCollection* eec, const ExtruderPerCopy* copy_extruders, unsigned int object_copies_num);
};
- std::vector<Region> by_region;
+
+ std::vector<Region> by_region; // all extrusions for this island, grouped by regions
+ const std::vector<Region>& by_region_per_copy(unsigned int copy, int extruder, bool wiping_entities = false); // returns reference to subvector of by_region
+
+ private:
+ std::vector<Region> by_region_per_copy_cache; // caches vector generated by function above to avoid copying and recalculating
};
std::vector<Island> islands;
};
+
+
std::string extrude_perimeters(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region, std::unique_ptr<EdgeGrid::Grid> &lower_layer_edge_grid);
std::string extrude_infill(const Print &print, const std::vector<ObjectByExtruder::Island::Region> &by_region);
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
@@ -234,7 +261,7 @@ protected:
/* Origin of print coordinates expressed in unscaled G-code coordinates.
This affects the input arguments supplied to the extrude*() and travel_to()
methods. */
- Pointf m_origin;
+ Vec2d m_origin;
FullPrintConfig m_config;
GCodeWriter m_writer;
PlaceholderParser m_placeholder_parser;
@@ -255,6 +282,7 @@ protected:
// Extended markers will be added during G-code generation.
// The G-code Analyzer will remove these comments from the final G-code.
bool m_enable_analyzer;
+ ExtrusionRole m_last_analyzer_extrusion_role;
// How many times will change_layer() be called?
// change_layer() will update the progress bar.
unsigned int m_layer_count;
@@ -289,8 +317,10 @@ protected:
// Index of a last object copy extruded.
std::pair<const PrintObject*, Point> m_last_obj_copy;
- // Time estimator
- GCodeTimeEstimator m_time_estimator;
+ // Time estimators
+ GCodeTimeEstimator m_normal_time_estimator;
+ GCodeTimeEstimator m_silent_time_estimator;
+ bool m_silent_time_estimator_enabled;
// Analyzer
GCodeAnalyzer m_analyzer;
@@ -308,6 +338,7 @@ protected:
void _write_format(FILE* file, const char* format, ...);
std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1);
+ void print_machine_envelope(FILE *file, Print &print);
void _print_first_layer_bed_temperature(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
void _print_first_layer_extruder_temperatures(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
// this flag triggers first layer speeds
diff --git a/xs/src/libslic3r/GCode/Analyzer.cpp b/xs/src/libslic3r/GCode/Analyzer.cpp
index 6530806c4..51d5b1a06 100644
--- a/xs/src/libslic3r/GCode/Analyzer.cpp
+++ b/xs/src/libslic3r/GCode/Analyzer.cpp
@@ -14,7 +14,7 @@ static const float MMMIN_TO_MMSEC = 1.0f / 60.0f;
static const float INCHES_TO_MM = 25.4f;
static const float DEFAULT_FEEDRATE = 0.0f;
static const unsigned int DEFAULT_EXTRUDER_ID = 0;
-static const Slic3r::Pointf3 DEFAULT_START_POSITION = Slic3r::Pointf3(0.0f, 0.0f, 0.0f);
+static const Slic3r::Vec3d DEFAULT_START_POSITION = Slic3r::Vec3d(0.0f, 0.0f, 0.0f);
static const float DEFAULT_START_EXTRUSION = 0.0f;
namespace Slic3r {
@@ -71,7 +71,7 @@ bool GCodeAnalyzer::Metadata::operator != (const GCodeAnalyzer::Metadata& other)
return false;
}
-GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Pointf3& start_position, const Pointf3& end_position, float delta_extruder)
+GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder)
: type(type)
, data(extrusion_role, extruder_id, mm3_per_mm, width, height, feedrate)
, start_position(start_position)
@@ -80,7 +80,7 @@ GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, ExtrusionRole extrusi
{
}
-GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, const GCodeAnalyzer::Metadata& data, const Pointf3& start_position, const Pointf3& end_position, float delta_extruder)
+GCodeAnalyzer::GCodeMove::GCodeMove(GCodeMove::EType type, const GCodeAnalyzer::Metadata& data, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder)
: type(type)
, data(data)
, start_position(start_position)
@@ -97,8 +97,8 @@ GCodeAnalyzer::GCodeAnalyzer()
void GCodeAnalyzer::reset()
{
_set_units(Millimeters);
- _set_positioning_xyz_type(Absolute);
- _set_positioning_e_type(Relative);
+ _set_global_positioning_type(Absolute);
+ _set_e_local_positioning_type(Absolute);
_set_extrusion_role(erNone);
_set_extruder_id(DEFAULT_EXTRUDER_ID);
_set_mm3_per_mm(Default_mm3_per_mm);
@@ -177,6 +177,16 @@ void GCodeAnalyzer::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLi
_processG1(line);
break;
}
+ case 10: // Retract
+ {
+ _processG10(line);
+ break;
+ }
+ case 11: // Unretract
+ {
+ _processG11(line);
+ break;
+ }
case 22: // Firmware controlled Retract
{
_processG22(line);
@@ -237,13 +247,13 @@ void GCodeAnalyzer::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLi
}
// Returns the new absolute position on the given axis in dependence of the given parameters
-float axis_absolute_position_from_G1_line(GCodeAnalyzer::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeAnalyzer::EUnits units, GCodeAnalyzer::EPositioningType type, float current_absolute_position)
+float axis_absolute_position_from_G1_line(GCodeAnalyzer::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeAnalyzer::EUnits units, bool is_relative, float current_absolute_position)
{
float lengthsScaleFactor = (units == GCodeAnalyzer::Inches) ? INCHES_TO_MM : 1.0f;
if (lineG1.has(Slic3r::Axis(axis)))
{
float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor;
- return (type == GCodeAnalyzer::Absolute) ? ret : current_absolute_position + ret;
+ return is_relative ? current_absolute_position + ret : ret;
}
else
return current_absolute_position;
@@ -256,7 +266,11 @@ void GCodeAnalyzer::_processG1(const GCodeReader::GCodeLine& line)
float new_pos[Num_Axis];
for (unsigned char a = X; a < Num_Axis; ++a)
{
- new_pos[a] = axis_absolute_position_from_G1_line((EAxis)a, line, units, (a == E) ? _get_positioning_e_type() : _get_positioning_xyz_type(), _get_axis_position((EAxis)a));
+ bool is_relative = (_get_global_positioning_type() == Relative);
+ if (a == E)
+ is_relative |= (_get_e_local_positioning_type() == Relative);
+
+ new_pos[a] = axis_absolute_position_from_G1_line((EAxis)a, line, units, is_relative, _get_axis_position((EAxis)a));
}
// updates feedrate from line, if present
@@ -305,6 +319,18 @@ void GCodeAnalyzer::_processG1(const GCodeReader::GCodeLine& line)
_store_move(type);
}
+void GCodeAnalyzer::_processG10(const GCodeReader::GCodeLine& line)
+{
+ // stores retract move
+ _store_move(GCodeMove::Retract);
+}
+
+void GCodeAnalyzer::_processG11(const GCodeReader::GCodeLine& line)
+{
+ // stores unretract move
+ _store_move(GCodeMove::Unretract);
+}
+
void GCodeAnalyzer::_processG22(const GCodeReader::GCodeLine& line)
{
// stores retract move
@@ -319,12 +345,12 @@ void GCodeAnalyzer::_processG23(const GCodeReader::GCodeLine& line)
void GCodeAnalyzer::_processG90(const GCodeReader::GCodeLine& line)
{
- _set_positioning_xyz_type(Absolute);
+ _set_global_positioning_type(Absolute);
}
void GCodeAnalyzer::_processG91(const GCodeReader::GCodeLine& line)
{
- _set_positioning_xyz_type(Relative);
+ _set_global_positioning_type(Relative);
}
void GCodeAnalyzer::_processG92(const GCodeReader::GCodeLine& line)
@@ -367,12 +393,12 @@ void GCodeAnalyzer::_processG92(const GCodeReader::GCodeLine& line)
void GCodeAnalyzer::_processM82(const GCodeReader::GCodeLine& line)
{
- _set_positioning_e_type(Absolute);
+ _set_e_local_positioning_type(Absolute);
}
void GCodeAnalyzer::_processM83(const GCodeReader::GCodeLine& line)
{
- _set_positioning_e_type(Relative);
+ _set_e_local_positioning_type(Relative);
}
void GCodeAnalyzer::_processT(const GCodeReader::GCodeLine& line)
@@ -466,24 +492,24 @@ GCodeAnalyzer::EUnits GCodeAnalyzer::_get_units() const
return m_state.units;
}
-void GCodeAnalyzer::_set_positioning_xyz_type(GCodeAnalyzer::EPositioningType type)
+void GCodeAnalyzer::_set_global_positioning_type(GCodeAnalyzer::EPositioningType type)
{
- m_state.positioning_xyz_type = type;
+ m_state.global_positioning_type = type;
}
-GCodeAnalyzer::EPositioningType GCodeAnalyzer::_get_positioning_xyz_type() const
+GCodeAnalyzer::EPositioningType GCodeAnalyzer::_get_global_positioning_type() const
{
- return m_state.positioning_xyz_type;
+ return m_state.global_positioning_type;
}
-void GCodeAnalyzer::_set_positioning_e_type(GCodeAnalyzer::EPositioningType type)
+void GCodeAnalyzer::_set_e_local_positioning_type(GCodeAnalyzer::EPositioningType type)
{
- m_state.positioning_e_type = type;
+ m_state.e_local_positioning_type = type;
}
-GCodeAnalyzer::EPositioningType GCodeAnalyzer::_get_positioning_e_type() const
+GCodeAnalyzer::EPositioningType GCodeAnalyzer::_get_e_local_positioning_type() const
{
- return m_state.positioning_e_type;
+ return m_state.e_local_positioning_type;
}
void GCodeAnalyzer::_set_extrusion_role(ExtrusionRole extrusion_role)
@@ -561,12 +587,12 @@ void GCodeAnalyzer::_reset_axes_position()
::memset((void*)m_state.position, 0, Num_Axis * sizeof(float));
}
-void GCodeAnalyzer::_set_start_position(const Pointf3& position)
+void GCodeAnalyzer::_set_start_position(const Vec3d& position)
{
m_state.start_position = position;
}
-const Pointf3& GCodeAnalyzer::_get_start_position() const
+const Vec3d& GCodeAnalyzer::_get_start_position() const
{
return m_state.start_position;
}
@@ -586,9 +612,9 @@ float GCodeAnalyzer::_get_delta_extrusion() const
return _get_axis_position(E) - m_state.start_extrusion;
}
-Pointf3 GCodeAnalyzer::_get_end_position() const
+Vec3d GCodeAnalyzer::_get_end_position() const
{
- return Pointf3(m_state.position[X], m_state.position[Y], m_state.position[Z]);
+ return Vec3d(m_state.position[X], m_state.position[Y], m_state.position[Z]);
}
void GCodeAnalyzer::_store_move(GCodeAnalyzer::GCodeMove::EType type)
@@ -647,15 +673,17 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
Metadata data;
float z = FLT_MAX;
Polyline polyline;
- Pointf3 position(FLT_MAX, FLT_MAX, FLT_MAX);
+ Vec3d position(FLT_MAX, FLT_MAX, FLT_MAX);
+ float volumetric_rate = FLT_MAX;
GCodePreviewData::Range height_range;
GCodePreviewData::Range width_range;
GCodePreviewData::Range feedrate_range;
+ GCodePreviewData::Range volumetric_rate_range;
// constructs the polylines while traversing the moves
for (const GCodeMove& move : extrude_moves->second)
{
- if ((data != move.data) || (data.feedrate != move.data.feedrate) || (z != move.start_position.z) || (position != move.start_position))
+ if ((data != move.data) || (z != move.start_position.z()) || (position != move.start_position) || (volumetric_rate != move.data.feedrate * (float)move.data.mm3_per_mm))
{
// store current polyline
polyline.remove_duplicate_points();
@@ -665,19 +693,21 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
polyline = Polyline();
// add both vertices of the move
- polyline.append(Point(scale_(move.start_position.x), scale_(move.start_position.y)));
- polyline.append(Point(scale_(move.end_position.x), scale_(move.end_position.y)));
+ polyline.append(Point(scale_(move.start_position.x()), scale_(move.start_position.y())));
+ polyline.append(Point(scale_(move.end_position.x()), scale_(move.end_position.y())));
// update current values
data = move.data;
- z = move.start_position.z;
+ z = move.start_position.z();
+ volumetric_rate = move.data.feedrate * (float)move.data.mm3_per_mm;
height_range.update_from(move.data.height);
width_range.update_from(move.data.width);
feedrate_range.update_from(move.data.feedrate);
+ volumetric_rate_range.update_from(volumetric_rate);
}
else
// append end vertex of the move to current polyline
- polyline.append(Point(scale_(move.end_position.x), scale_(move.end_position.y)));
+ polyline.append(Point(scale_(move.end_position.x()), scale_(move.end_position.y())));
// update current values
position = move.end_position;
@@ -688,9 +718,10 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ
Helper::store_polyline(polyline, data, z, preview_data);
// updates preview ranges data
- preview_data.extrusion.ranges.height.set_from(height_range);
- preview_data.extrusion.ranges.width.set_from(width_range);
- preview_data.extrusion.ranges.feedrate.set_from(feedrate_range);
+ preview_data.ranges.height.update_from(height_range);
+ preview_data.ranges.width.update_from(width_range);
+ preview_data.ranges.feedrate.update_from(feedrate_range);
+ preview_data.ranges.volumetric_rate.update_from(volumetric_rate_range);
}
void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data)
@@ -711,17 +742,21 @@ void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data)
return;
Polyline3 polyline;
- Pointf3 position(FLT_MAX, FLT_MAX, FLT_MAX);
+ Vec3d position(FLT_MAX, FLT_MAX, FLT_MAX);
GCodePreviewData::Travel::EType type = GCodePreviewData::Travel::Num_Types;
GCodePreviewData::Travel::Polyline::EDirection direction = GCodePreviewData::Travel::Polyline::Num_Directions;
float feedrate = FLT_MAX;
unsigned int extruder_id = -1;
+ GCodePreviewData::Range height_range;
+ GCodePreviewData::Range width_range;
+ GCodePreviewData::Range feedrate_range;
+
// constructs the polylines while traversing the moves
for (const GCodeMove& move : travel_moves->second)
{
GCodePreviewData::Travel::EType move_type = (move.delta_extruder < 0.0f) ? GCodePreviewData::Travel::Retract : ((move.delta_extruder > 0.0f) ? GCodePreviewData::Travel::Extrude : GCodePreviewData::Travel::Move);
- GCodePreviewData::Travel::Polyline::EDirection move_direction = ((move.start_position.x != move.end_position.x) || (move.start_position.y != move.end_position.y)) ? GCodePreviewData::Travel::Polyline::Generic : GCodePreviewData::Travel::Polyline::Vertical;
+ GCodePreviewData::Travel::Polyline::EDirection move_direction = ((move.start_position.x() != move.end_position.x()) || (move.start_position.y() != move.end_position.y())) ? GCodePreviewData::Travel::Polyline::Generic : GCodePreviewData::Travel::Polyline::Vertical;
if ((type != move_type) || (direction != move_direction) || (feedrate != move.data.feedrate) || (position != move.start_position) || (extruder_id != move.data.extruder_id))
{
@@ -733,23 +768,31 @@ void GCodeAnalyzer::_calc_gcode_preview_travel(GCodePreviewData& preview_data)
polyline = Polyline3();
// add both vertices of the move
- polyline.append(Point3(scale_(move.start_position.x), scale_(move.start_position.y), scale_(move.start_position.z)));
- polyline.append(Point3(scale_(move.end_position.x), scale_(move.end_position.y), scale_(move.end_position.z)));
+ polyline.append(Vec3crd(scale_(move.start_position.x()), scale_(move.start_position.y()), scale_(move.start_position.z())));
+ polyline.append(Vec3crd(scale_(move.end_position.x()), scale_(move.end_position.y()), scale_(move.end_position.z())));
}
else
// append end vertex of the move to current polyline
- polyline.append(Point3(scale_(move.end_position.x), scale_(move.end_position.y), scale_(move.end_position.z)));
+ polyline.append(Vec3crd(scale_(move.end_position.x()), scale_(move.end_position.y()), scale_(move.end_position.z())));
// update current values
position = move.end_position;
type = move_type;
feedrate = move.data.feedrate;
extruder_id = move.data.extruder_id;
+ height_range.update_from(move.data.height);
+ width_range.update_from(move.data.width);
+ feedrate_range.update_from(move.data.feedrate);
}
// store last polyline
polyline.remove_duplicate_points();
Helper::store_polyline(polyline, type, direction, feedrate, extruder_id, preview_data);
+
+ // updates preview ranges data
+ preview_data.ranges.height.update_from(height_range);
+ preview_data.ranges.width.update_from(width_range);
+ preview_data.ranges.feedrate.update_from(feedrate_range);
}
void GCodeAnalyzer::_calc_gcode_preview_retractions(GCodePreviewData& preview_data)
@@ -761,7 +804,7 @@ void GCodeAnalyzer::_calc_gcode_preview_retractions(GCodePreviewData& preview_da
for (const GCodeMove& move : retraction_moves->second)
{
// store position
- Point3 position(scale_(move.start_position.x), scale_(move.start_position.y), scale_(move.start_position.z));
+ Vec3crd position(scale_(move.start_position.x()), scale_(move.start_position.y()), scale_(move.start_position.z()));
preview_data.retraction.positions.emplace_back(position, move.data.width, move.data.height);
}
}
@@ -775,7 +818,7 @@ void GCodeAnalyzer::_calc_gcode_preview_unretractions(GCodePreviewData& preview_
for (const GCodeMove& move : unretraction_moves->second)
{
// store position
- Point3 position(scale_(move.start_position.x), scale_(move.start_position.y), scale_(move.start_position.z));
+ Vec3crd position(scale_(move.start_position.x()), scale_(move.start_position.y()), scale_(move.start_position.z()));
preview_data.unretraction.positions.emplace_back(position, move.data.width, move.data.height);
}
}
diff --git a/xs/src/libslic3r/GCode/Analyzer.hpp b/xs/src/libslic3r/GCode/Analyzer.hpp
index 7939d432d..27a49b869 100644
--- a/xs/src/libslic3r/GCode/Analyzer.hpp
+++ b/xs/src/libslic3r/GCode/Analyzer.hpp
@@ -75,12 +75,12 @@ public:
EType type;
Metadata data;
- Pointf3 start_position;
- Pointf3 end_position;
+ Vec3d start_position;
+ Vec3d end_position;
float delta_extruder;
- GCodeMove(EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Pointf3& start_position, const Pointf3& end_position, float delta_extruder);
- GCodeMove(EType type, const Metadata& data, const Pointf3& start_position, const Pointf3& end_position, float delta_extruder);
+ GCodeMove(EType type, ExtrusionRole extrusion_role, unsigned int extruder_id, double mm3_per_mm, float width, float height, float feedrate, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder);
+ GCodeMove(EType type, const Metadata& data, const Vec3d& start_position, const Vec3d& end_position, float delta_extruder);
};
typedef std::vector<GCodeMove> GCodeMovesList;
@@ -90,10 +90,10 @@ private:
struct State
{
EUnits units;
- EPositioningType positioning_xyz_type;
- EPositioningType positioning_e_type;
+ EPositioningType global_positioning_type;
+ EPositioningType e_local_positioning_type;
Metadata data;
- Pointf3 start_position;
+ Vec3d start_position = Vec3d::Zero();
float start_extrusion;
float position[Num_Axis];
};
@@ -127,6 +127,12 @@ private:
// Move
void _processG1(const GCodeReader::GCodeLine& line);
+ // Retract
+ void _processG10(const GCodeReader::GCodeLine& line);
+
+ // Unretract
+ void _processG11(const GCodeReader::GCodeLine& line);
+
// Firmware controlled Retract
void _processG22(const GCodeReader::GCodeLine& line);
@@ -170,11 +176,11 @@ private:
void _set_units(EUnits units);
EUnits _get_units() const;
- void _set_positioning_xyz_type(EPositioningType type);
- EPositioningType _get_positioning_xyz_type() const;
+ void _set_global_positioning_type(EPositioningType type);
+ EPositioningType _get_global_positioning_type() const;
- void _set_positioning_e_type(EPositioningType type);
- EPositioningType _get_positioning_e_type() const;
+ void _set_e_local_positioning_type(EPositioningType type);
+ EPositioningType _get_e_local_positioning_type() const;
void _set_extrusion_role(ExtrusionRole extrusion_role);
ExtrusionRole _get_extrusion_role() const;
@@ -200,15 +206,15 @@ private:
// Sets axes position to zero
void _reset_axes_position();
- void _set_start_position(const Pointf3& position);
- const Pointf3& _get_start_position() const;
+ void _set_start_position(const Vec3d& position);
+ const Vec3d& _get_start_position() const;
void _set_start_extrusion(float extrusion);
float _get_start_extrusion() const;
float _get_delta_extrusion() const;
// Returns current xyz position (from m_state.position[])
- Pointf3 _get_end_position() const;
+ Vec3d _get_end_position() const;
// Adds a new move with the given data
void _store_move(GCodeMove::EType type);
diff --git a/xs/src/libslic3r/GCode/CoolingBuffer.cpp b/xs/src/libslic3r/GCode/CoolingBuffer.cpp
index cd2baeffb..40ccc7b09 100644
--- a/xs/src/libslic3r/GCode/CoolingBuffer.cpp
+++ b/xs/src/libslic3r/GCode/CoolingBuffer.cpp
@@ -23,366 +23,586 @@ CoolingBuffer::CoolingBuffer(GCode &gcodegen) : m_gcodegen(gcodegen), m_current_
void CoolingBuffer::reset()
{
m_current_pos.assign(5, 0.f);
- Pointf3 pos = m_gcodegen.writer().get_position();
- m_current_pos[0] = float(pos.x);
- m_current_pos[1] = float(pos.y);
- m_current_pos[2] = float(pos.z);
+ Vec3d pos = m_gcodegen.writer().get_position();
+ m_current_pos[0] = float(pos(0));
+ m_current_pos[1] = float(pos(1));
+ m_current_pos[2] = float(pos(2));
m_current_pos[4] = float(m_gcodegen.config().travel_speed.value);
}
-#define EXTRUDER_CONFIG(OPT) config.OPT.get_at(m_current_extruder)
-
-std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_id)
+struct CoolingLine
{
- const FullPrintConfig &config = m_gcodegen.config();
- const std::vector<Extruder> &extruders = m_gcodegen.writer().extruders();
- const size_t num_extruders = extruders.size();
+ enum Type {
+ TYPE_SET_TOOL = 1 << 0,
+ TYPE_EXTRUDE_END = 1 << 1,
+ TYPE_BRIDGE_FAN_START = 1 << 2,
+ TYPE_BRIDGE_FAN_END = 1 << 3,
+ TYPE_G0 = 1 << 4,
+ TYPE_G1 = 1 << 5,
+ TYPE_ADJUSTABLE = 1 << 6,
+ TYPE_EXTERNAL_PERIMETER = 1 << 7,
+ // The line sets a feedrate.
+ TYPE_HAS_F = 1 << 8,
+ TYPE_WIPE = 1 << 9,
+ TYPE_G4 = 1 << 10,
+ TYPE_G92 = 1 << 11,
+ };
+
+ CoolingLine(unsigned int type, size_t line_start, size_t line_end) :
+ type(type), line_start(line_start), line_end(line_end),
+ length(0.f), feedrate(0.f), time(0.f), time_max(0.f), slowdown(false) {}
+
+ bool adjustable(bool slowdown_external_perimeters) const {
+ return (this->type & TYPE_ADJUSTABLE) &&
+ (! (this->type & TYPE_EXTERNAL_PERIMETER) || slowdown_external_perimeters) &&
+ this->time < this->time_max;
+ }
+
+ bool adjustable() const {
+ return (this->type & TYPE_ADJUSTABLE) && this->time < this->time_max;
+ }
- // Calculate the required per extruder time stretches.
- struct Adjustment {
- Adjustment(unsigned int extruder_id = 0) : extruder_id(extruder_id) {}
- // Calculate the total elapsed time per this extruder, adjusted for the slowdown.
- float elapsed_time_total() {
- float time_total = 0.f;
- for (const Line &line : lines)
+ size_t type;
+ // Start of this line at the G-code snippet.
+ size_t line_start;
+ // End of this line at the G-code snippet.
+ size_t line_end;
+ // XY Euclidian length of this segment.
+ float length;
+ // Current feedrate, possibly adjusted.
+ float feedrate;
+ // Current duration of this segment.
+ float time;
+ // Maximum duration of this segment.
+ float time_max;
+ // If marked with the "slowdown" flag, the line has been slowed down.
+ bool slowdown;
+};
+
+// Calculate the required per extruder time stretches.
+struct PerExtruderAdjustments
+{
+ // Calculate the total elapsed time per this extruder, adjusted for the slowdown.
+ float elapsed_time_total() {
+ float time_total = 0.f;
+ for (const CoolingLine &line : lines)
+ time_total += line.time;
+ return time_total;
+ }
+ // Calculate the total elapsed time when slowing down
+ // to the minimum extrusion feed rate defined for the current material.
+ float maximum_time_after_slowdown(bool slowdown_external_perimeters) {
+ float time_total = 0.f;
+ for (const CoolingLine &line : lines)
+ if (line.adjustable(slowdown_external_perimeters)) {
+ if (line.time_max == FLT_MAX)
+ return FLT_MAX;
+ else
+ time_total += line.time_max;
+ } else
time_total += line.time;
- return time_total;
- }
- // Calculate the maximum time when slowing down.
- float maximum_time(bool slowdown_external_perimeters) {
- float time_total = 0.f;
- for (const Line &line : lines)
- if (line.adjustable(slowdown_external_perimeters)) {
- if (line.time_max == FLT_MAX)
- return FLT_MAX;
- else
- time_total += line.time_max;
- } else
- time_total += line.time;
- return time_total;
- }
- // Calculate the non-adjustable part of the total time.
- float non_adjustable_time(bool slowdown_external_perimeters) {
- float time_total = 0.f;
- for (const Line &line : lines)
- if (! line.adjustable(slowdown_external_perimeters))
- time_total += line.time;
- return time_total;
- }
- float slow_down_maximum(bool slowdown_external_perimeters) {
- float time_total = 0.f;
- for (Line &line : lines) {
- if (line.adjustable(slowdown_external_perimeters)) {
- assert(line.time_max >= 0.f && line.time_max < FLT_MAX);
- line.slowdown = true;
- line.time = line.time_max;
- }
+ return time_total;
+ }
+ // Calculate the adjustable part of the total time.
+ float adjustable_time(bool slowdown_external_perimeters) {
+ float time_total = 0.f;
+ for (const CoolingLine &line : lines)
+ if (line.adjustable(slowdown_external_perimeters))
+ time_total += line.time;
+ return time_total;
+ }
+ // Calculate the non-adjustable part of the total time.
+ float non_adjustable_time(bool slowdown_external_perimeters) {
+ float time_total = 0.f;
+ for (const CoolingLine &line : lines)
+ if (! line.adjustable(slowdown_external_perimeters))
time_total += line.time;
+ return time_total;
+ }
+ // Slow down the adjustable extrusions to the minimum feedrate allowed for the current extruder material.
+ // Used by both proportional and non-proportional slow down.
+ float slowdown_to_minimum_feedrate(bool slowdown_external_perimeters) {
+ float time_total = 0.f;
+ for (CoolingLine &line : lines) {
+ if (line.adjustable(slowdown_external_perimeters)) {
+ assert(line.time_max >= 0.f && line.time_max < FLT_MAX);
+ line.slowdown = true;
+ line.time = line.time_max;
+ line.feedrate = line.length / line.time;
}
- return time_total;
+ time_total += line.time;
}
- float slow_down_proportional(float factor, bool slowdown_external_perimeters) {
- assert(factor >= 1.f);
- float time_total = 0.f;
- for (Line &line : lines) {
- if (line.adjustable(slowdown_external_perimeters)) {
- line.slowdown = true;
- line.time = std::min(line.time_max, line.time * factor);
- }
- time_total += line.time;
+ return time_total;
+ }
+ // Slow down each adjustable G-code line proportionally by a factor.
+ // Used by the proportional slow down.
+ float slow_down_proportional(float factor, bool slowdown_external_perimeters) {
+ assert(factor >= 1.f);
+ float time_total = 0.f;
+ for (CoolingLine &line : lines) {
+ if (line.adjustable(slowdown_external_perimeters)) {
+ line.slowdown = true;
+ line.time = std::min(line.time_max, line.time * factor);
+ line.feedrate = line.length / line.time;
}
- return time_total;
+ time_total += line.time;
}
+ return time_total;
+ }
- bool operator<(const Adjustment &rhs) const { return this->extruder_id < rhs.extruder_id; }
-
- struct Line
- {
- enum Type {
- TYPE_SET_TOOL = 1 << 0,
- TYPE_EXTRUDE_END = 1 << 1,
- TYPE_BRIDGE_FAN_START = 1 << 2,
- TYPE_BRIDGE_FAN_END = 1 << 3,
- TYPE_G0 = 1 << 4,
- TYPE_G1 = 1 << 5,
- TYPE_ADJUSTABLE = 1 << 6,
- TYPE_EXTERNAL_PERIMETER = 1 << 7,
- // The line sets a feedrate.
- TYPE_HAS_F = 1 << 8,
- TYPE_WIPE = 1 << 9,
- TYPE_G4 = 1 << 10,
- TYPE_G92 = 1 << 11,
- };
+ // Sort the lines, adjustable first, higher feedrate first.
+ // Used by non-proportional slow down.
+ void sort_lines_by_decreasing_feedrate() {
+ std::sort(lines.begin(), lines.end(), [](const CoolingLine &l1, const CoolingLine &l2) {
+ bool adj1 = l1.adjustable();
+ bool adj2 = l2.adjustable();
+ return (adj1 == adj2) ? l1.feedrate > l2.feedrate : adj1;
+ });
+ for (n_lines_adjustable = 0;
+ n_lines_adjustable < lines.size() && this->lines[n_lines_adjustable].adjustable();
+ ++ n_lines_adjustable);
+ time_non_adjustable = 0.f;
+ for (size_t i = n_lines_adjustable; i < lines.size(); ++ i)
+ time_non_adjustable += lines[i].time;
+ }
- Line(unsigned int type, size_t line_start, size_t line_end) :
- type(type), line_start(line_start), line_end(line_end),
- length(0.f), time(0.f), time_max(0.f), slowdown(false) {}
+ // Calculate the maximum time stretch when slowing down to min_feedrate.
+ // Slowdown to min_feedrate shall be allowed for this extruder's material.
+ // Used by non-proportional slow down.
+ float time_stretch_when_slowing_down_to_feedrate(float min_feedrate) {
+ float time_stretch = 0.f;
+ assert(this->min_print_speed < min_feedrate + EPSILON);
+ for (size_t i = 0; i < n_lines_adjustable; ++ i) {
+ const CoolingLine &line = lines[i];
+ if (line.feedrate > min_feedrate)
+ time_stretch += line.time * (line.feedrate / min_feedrate - 1.f);
+ }
+ return time_stretch;
+ }
- bool adjustable(bool slowdown_external_perimeters) const {
- return (this->type & TYPE_ADJUSTABLE) &&
- (! (this->type & TYPE_EXTERNAL_PERIMETER) || slowdown_external_perimeters) &&
- this->time < this->time_max;
+ // Slow down all adjustable lines down to min_feedrate.
+ // Slowdown to min_feedrate shall be allowed for this extruder's material.
+ // Used by non-proportional slow down.
+ void slow_down_to_feedrate(float min_feedrate) {
+ assert(this->min_print_speed < min_feedrate + EPSILON);
+ for (size_t i = 0; i < n_lines_adjustable; ++ i) {
+ CoolingLine &line = lines[i];
+ if (line.feedrate > min_feedrate) {
+ line.time *= std::max(1.f, line.feedrate / min_feedrate);
+ line.feedrate = min_feedrate;
+ line.slowdown = true;
}
+ }
+ }
- size_t type;
- // Start of this line at the G-code snippet.
- size_t line_start;
- // End of this line at the G-code snippet.
- size_t line_end;
- // XY Euclidian length of this segment.
- float length;
- // Current duration of this segment.
- float time;
- // Maximum duration of this segment.
- float time_max;
- // If marked with the "slowdown" flag, the line has been slowed down.
- bool slowdown;
- };
+ // Extruder, for which the G-code will be adjusted.
+ unsigned int extruder_id = 0;
+ // Is the cooling slow down logic enabled for this extruder's material?
+ bool cooling_slow_down_enabled = false;
+ // Slow down the print down to min_print_speed if the total layer time is below slowdown_below_layer_time.
+ float slowdown_below_layer_time = 0.f;
+ // Minimum print speed allowed for this extruder.
+ float min_print_speed = 0.f;
- // Extruder, for which the G-code will be adjusted.
- unsigned int extruder_id;
- // Parsed lines.
- std::vector<Line> lines;
- };
- std::vector<Adjustment> adjustments(num_extruders, Adjustment());
- for (size_t i = 0; i < num_extruders; ++ i)
- adjustments[i].extruder_id = extruders[i].id();
- const std::string toolchange_prefix = m_gcodegen.writer().toolchange_prefix();
- // Parse the layer G-code for the moves, which could be adjusted.
+ // Parsed lines.
+ std::vector<CoolingLine> lines;
+ // The following two values are set by sort_lines_by_decreasing_feedrate():
+ // Number of adjustable lines, at the start of lines.
+ size_t n_lines_adjustable = 0;
+ // Non-adjustable time of lines starting with n_lines_adjustable.
+ float time_non_adjustable = 0;
+ // Current total time for this extruder.
+ float time_total = 0;
+ // Maximum time for this extruder, when the maximum slow down is applied.
+ float time_maximum = 0;
+
+ // Temporaries for processing the slow down. Both thresholds go from 0 to n_lines_adjustable.
+ size_t idx_line_begin = 0;
+ size_t idx_line_end = 0;
+};
+
+std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_id)
+{
+ std::vector<PerExtruderAdjustments> per_extruder_adjustments = this->parse_layer_gcode(gcode, m_current_pos);
+ float layer_time_stretched = this->calculate_layer_slowdown(per_extruder_adjustments);
+ return this->apply_layer_cooldown(gcode, layer_id, layer_time_stretched, per_extruder_adjustments);
+}
+
+// Parse the layer G-code for the moves, which could be adjusted.
+// Return the list of parsed lines, bucketed by an extruder.
+std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::string &gcode, std::vector<float> &current_pos) const
+{
+ const FullPrintConfig &config = m_gcodegen.config();
+ const std::vector<Extruder> &extruders = m_gcodegen.writer().extruders();
+ unsigned int num_extruders = 0;
+ for (const Extruder &ex : extruders)
+ num_extruders = std::max(ex.id() + 1, num_extruders);
+
+ std::vector<PerExtruderAdjustments> per_extruder_adjustments(extruders.size());
+ std::vector<size_t> map_extruder_to_per_extruder_adjustment(num_extruders, 0);
+ for (size_t i = 0; i < extruders.size(); ++ i) {
+ PerExtruderAdjustments &adj = per_extruder_adjustments[i];
+ unsigned int extruder_id = extruders[i].id();
+ adj.extruder_id = extruder_id;
+ adj.cooling_slow_down_enabled = config.cooling.get_at(extruder_id);
+ adj.slowdown_below_layer_time = config.slowdown_below_layer_time.get_at(extruder_id);
+ adj.min_print_speed = config.min_print_speed.get_at(extruder_id);
+ map_extruder_to_per_extruder_adjustment[extruder_id] = i;
+ }
+
+ const std::string toolchange_prefix = m_gcodegen.writer().toolchange_prefix();
+ unsigned int current_extruder = m_current_extruder;
+ PerExtruderAdjustments *adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
+ const char *line_start = gcode.c_str();
+ const char *line_end = line_start;
+ const char extrusion_axis = config.get_extrusion_axis()[0];
+ // Index of an existing CoolingLine of the current adjustment, which holds the feedrate setting command
+ // for a sequence of extrusion moves.
+ size_t active_speed_modifier = size_t(-1);
+
+ for (; *line_start != 0; line_start = line_end)
{
- float min_print_speed = float(EXTRUDER_CONFIG(min_print_speed));
- auto adjustment = std::lower_bound(adjustments.begin(), adjustments.end(), Adjustment(m_current_extruder));
- unsigned int initial_extruder = m_current_extruder;
- const char *line_start = gcode.c_str();
- const char *line_end = line_start;
- const char extrusion_axis = config.get_extrusion_axis()[0];
- // Index of an existing Adjustment::Line of the current adjustment, which holds the feedrate setting command
- // for a sequence of extrusion moves.
- size_t active_speed_modifier = size_t(-1);
- for (; *line_start != 0; line_start = line_end) {
- while (*line_end != '\n' && *line_end != 0)
- ++ line_end;
- // sline will not contain the trailing '\n'.
- std::string sline(line_start, line_end);
- // Adjustment::Line will contain the trailing '\n'.
- if (*line_end == '\n')
- ++ line_end;
- Adjustment::Line line(0, line_start - gcode.c_str(), line_end - gcode.c_str());
- if (boost::starts_with(sline, "G0 "))
- line.type = Adjustment::Line::TYPE_G0;
- else if (boost::starts_with(sline, "G1 "))
- line.type = Adjustment::Line::TYPE_G1;
- else if (boost::starts_with(sline, "G92 "))
- line.type = Adjustment::Line::TYPE_G92;
- if (line.type) {
- // G0, G1 or G92
- // Parse the G-code line.
- std::vector<float> new_pos(m_current_pos);
- const char *c = sline.data() + 3;
- for (;;) {
- // Skip whitespaces.
- for (; *c == ' ' || *c == '\t'; ++ c);
- if (*c == 0 || *c == ';')
- break;
- // Parse the axis.
- size_t axis = (*c >= 'X' && *c <= 'Z') ? (*c - 'X') :
- (*c == extrusion_axis) ? 3 : (*c == 'F') ? 4 : size_t(-1);
- if (axis != size_t(-1)) {
- new_pos[axis] = float(atof(++c));
- if (axis == 4) {
- // Convert mm/min to mm/sec.
- new_pos[4] /= 60.f;
- if ((line.type & Adjustment::Line::TYPE_G92) == 0)
- // This is G0 or G1 line and it sets the feedrate. This mark is used for reducing the duplicate F calls.
- line.type |= Adjustment::Line::TYPE_HAS_F;
- }
- }
- // Skip this word.
- for (; *c != ' ' && *c != '\t' && *c != 0; ++ c);
+ while (*line_end != '\n' && *line_end != 0)
+ ++ line_end;
+ // sline will not contain the trailing '\n'.
+ std::string sline(line_start, line_end);
+ // CoolingLine will contain the trailing '\n'.
+ if (*line_end == '\n')
+ ++ line_end;
+ CoolingLine line(0, line_start - gcode.c_str(), line_end - gcode.c_str());
+ if (boost::starts_with(sline, "G0 "))
+ line.type = CoolingLine::TYPE_G0;
+ else if (boost::starts_with(sline, "G1 "))
+ line.type = CoolingLine::TYPE_G1;
+ else if (boost::starts_with(sline, "G92 "))
+ line.type = CoolingLine::TYPE_G92;
+ if (line.type) {
+ // G0, G1 or G92
+ // Parse the G-code line.
+ std::vector<float> new_pos(current_pos);
+ const char *c = sline.data() + 3;
+ for (;;) {
+ // Skip whitespaces.
+ for (; *c == ' ' || *c == '\t'; ++ c);
+ if (*c == 0 || *c == ';')
+ break;
+ // Parse the axis.
+ size_t axis = (*c >= 'X' && *c <= 'Z') ? (*c - 'X') :
+ (*c == extrusion_axis) ? 3 : (*c == 'F') ? 4 : size_t(-1);
+ if (axis != size_t(-1)) {
+ new_pos[axis] = float(atof(++c));
+ if (axis == 4) {
+ // Convert mm/min to mm/sec.
+ new_pos[4] /= 60.f;
+ if ((line.type & CoolingLine::TYPE_G92) == 0)
+ // This is G0 or G1 line and it sets the feedrate. This mark is used for reducing the duplicate F calls.
+ line.type |= CoolingLine::TYPE_HAS_F;
+ }
}
- bool external_perimeter = boost::contains(sline, ";_EXTERNAL_PERIMETER");
- bool wipe = boost::contains(sline, ";_WIPE");
- if (external_perimeter)
- line.type |= Adjustment::Line::TYPE_EXTERNAL_PERIMETER;
- if (wipe)
- line.type |= Adjustment::Line::TYPE_WIPE;
- if (boost::contains(sline, ";_EXTRUDE_SET_SPEED") && ! wipe) {
- line.type |= Adjustment::Line::TYPE_ADJUSTABLE;
- active_speed_modifier = adjustment->lines.size();
+ // Skip this word.
+ for (; *c != ' ' && *c != '\t' && *c != 0; ++ c);
+ }
+ bool external_perimeter = boost::contains(sline, ";_EXTERNAL_PERIMETER");
+ bool wipe = boost::contains(sline, ";_WIPE");
+ if (external_perimeter)
+ line.type |= CoolingLine::TYPE_EXTERNAL_PERIMETER;
+ if (wipe)
+ line.type |= CoolingLine::TYPE_WIPE;
+ if (boost::contains(sline, ";_EXTRUDE_SET_SPEED") && ! wipe) {
+ line.type |= CoolingLine::TYPE_ADJUSTABLE;
+ active_speed_modifier = adjustment->lines.size();
+ }
+ if ((line.type & CoolingLine::TYPE_G92) == 0) {
+ // G0 or G1. Calculate the duration.
+ if (config.use_relative_e_distances.value)
+ // Reset extruder accumulator.
+ current_pos[3] = 0.f;
+ float dif[4];
+ for (size_t i = 0; i < 4; ++ i)
+ dif[i] = new_pos[i] - current_pos[i];
+ float dxy2 = dif[0] * dif[0] + dif[1] * dif[1];
+ float dxyz2 = dxy2 + dif[2] * dif[2];
+ if (dxyz2 > 0.f) {
+ // Movement in xyz, calculate time from the xyz Euclidian distance.
+ line.length = sqrt(dxyz2);
+ } else if (std::abs(dif[3]) > 0.f) {
+ // Movement in the extruder axis.
+ line.length = std::abs(dif[3]);
}
- if ((line.type & Adjustment::Line::TYPE_G92) == 0) {
- // G0 or G1. Calculate the duration.
- if (config.use_relative_e_distances.value)
- // Reset extruder accumulator.
- m_current_pos[3] = 0.f;
- float dif[4];
- for (size_t i = 0; i < 4; ++ i)
- dif[i] = new_pos[i] - m_current_pos[i];
- float dxy2 = dif[0] * dif[0] + dif[1] * dif[1];
- float dxyz2 = dxy2 + dif[2] * dif[2];
- if (dxyz2 > 0.f) {
- // Movement in xyz, calculate time from the xyz Euclidian distance.
- line.length = sqrt(dxyz2);
- } else if (std::abs(dif[3]) > 0.f) {
- // Movement in the extruder axis.
- line.length = std::abs(dif[3]);
+ line.feedrate = new_pos[4];
+ assert((line.type & CoolingLine::TYPE_ADJUSTABLE) == 0 || line.feedrate > 0.f);
+ if (line.length > 0)
+ line.time = line.length / line.feedrate;
+ line.time_max = line.time;
+ if ((line.type & CoolingLine::TYPE_ADJUSTABLE) || active_speed_modifier != size_t(-1))
+ line.time_max = (adjustment->min_print_speed == 0.f) ? FLT_MAX : std::max(line.time, line.length / adjustment->min_print_speed);
+ if (active_speed_modifier < adjustment->lines.size() && (line.type & CoolingLine::TYPE_G1)) {
+ // Inside the ";_EXTRUDE_SET_SPEED" blocks, there must not be a G1 Fxx entry.
+ assert((line.type & CoolingLine::TYPE_HAS_F) == 0);
+ CoolingLine &sm = adjustment->lines[active_speed_modifier];
+ assert(sm.feedrate > 0.f);
+ sm.length += line.length;
+ sm.time += line.time;
+ if (sm.time_max != FLT_MAX) {
+ if (line.time_max == FLT_MAX)
+ sm.time_max = FLT_MAX;
+ else
+ sm.time_max += line.time_max;
}
- if (line.length > 0)
- line.time = line.length / new_pos[4]; // current F
- line.time_max = line.time;
- if ((line.type & Adjustment::Line::TYPE_ADJUSTABLE) || active_speed_modifier != size_t(-1))
- line.time_max = (min_print_speed == 0.f) ? FLT_MAX : std::max(line.time, line.length / min_print_speed);
- if (active_speed_modifier < adjustment->lines.size() && (line.type & Adjustment::Line::TYPE_G1)) {
- // Inside the ";_EXTRUDE_SET_SPEED" blocks, there must not be a G1 Fxx entry.
- assert((line.type & Adjustment::Line::TYPE_HAS_F) == 0);
- Adjustment::Line &sm = adjustment->lines[active_speed_modifier];
- sm.length += line.length;
- sm.time += line.time;
- if (sm.time_max != FLT_MAX) {
- if (line.time_max == FLT_MAX)
- sm.time_max = FLT_MAX;
- else
- sm.time_max += line.time_max;
- }
- // Don't store this line.
- line.type = 0;
- }
- }
- m_current_pos = std::move(new_pos);
- } else if (boost::starts_with(sline, ";_EXTRUDE_END")) {
- line.type = Adjustment::Line::TYPE_EXTRUDE_END;
- active_speed_modifier = size_t(-1);
- } else if (boost::starts_with(sline, toolchange_prefix)) {
- // Switch the tool.
- line.type = Adjustment::Line::TYPE_SET_TOOL;
- unsigned int new_extruder = (unsigned int)atoi(sline.c_str() + toolchange_prefix.size());
- if (new_extruder != m_current_extruder) {
- m_current_extruder = new_extruder;
- min_print_speed = float(EXTRUDER_CONFIG(min_print_speed));
- adjustment = std::lower_bound(adjustments.begin(), adjustments.end(), Adjustment(m_current_extruder));
+ // Don't store this line.
+ line.type = 0;
}
- } else if (boost::starts_with(sline, ";_BRIDGE_FAN_START")) {
- line.type = Adjustment::Line::TYPE_BRIDGE_FAN_START;
- } else if (boost::starts_with(sline, ";_BRIDGE_FAN_END")) {
- line.type = Adjustment::Line::TYPE_BRIDGE_FAN_END;
- } else if (boost::starts_with(sline, "G4 ")) {
- // Parse the wait time.
- line.type = Adjustment::Line::TYPE_G4;
- size_t pos_S = sline.find('S', 3);
- size_t pos_P = sline.find('P', 3);
- line.time = line.time_max = float(
- (pos_S > 0) ? atof(sline.c_str() + pos_S + 1) :
- (pos_P > 0) ? atof(sline.c_str() + pos_P + 1) * 0.001 : 0.);
}
- if (line.type != 0)
- adjustment->lines.emplace_back(std::move(line));
- }
- m_current_extruder = initial_extruder;
+ current_pos = std::move(new_pos);
+ } else if (boost::starts_with(sline, ";_EXTRUDE_END")) {
+ line.type = CoolingLine::TYPE_EXTRUDE_END;
+ active_speed_modifier = size_t(-1);
+ } else if (boost::starts_with(sline, toolchange_prefix)) {
+ // Switch the tool.
+ line.type = CoolingLine::TYPE_SET_TOOL;
+ unsigned int new_extruder = (unsigned int)atoi(sline.c_str() + toolchange_prefix.size());
+ if (new_extruder != current_extruder) {
+ current_extruder = new_extruder;
+ adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
+ }
+ } else if (boost::starts_with(sline, ";_BRIDGE_FAN_START")) {
+ line.type = CoolingLine::TYPE_BRIDGE_FAN_START;
+ } else if (boost::starts_with(sline, ";_BRIDGE_FAN_END")) {
+ line.type = CoolingLine::TYPE_BRIDGE_FAN_END;
+ } else if (boost::starts_with(sline, "G4 ")) {
+ // Parse the wait time.
+ line.type = CoolingLine::TYPE_G4;
+ size_t pos_S = sline.find('S', 3);
+ size_t pos_P = sline.find('P', 3);
+ line.time = line.time_max = float(
+ (pos_S > 0) ? atof(sline.c_str() + pos_S + 1) :
+ (pos_P > 0) ? atof(sline.c_str() + pos_P + 1) * 0.001 : 0.);
+ }
+ if (line.type != 0)
+ adjustment->lines.emplace_back(std::move(line));
}
- // Sort the extruders by the increasing slowdown_below_layer_time.
- std::vector<size_t> by_slowdown_layer_time;
- by_slowdown_layer_time.reserve(num_extruders);
+ return per_extruder_adjustments;
+}
+
+// Slow down an extruder range proportionally down to slowdown_below_layer_time.
+// Return the total time for the complete layer.
+static inline float extruder_range_slow_down_proportional(
+ std::vector<PerExtruderAdjustments*>::iterator it_begin,
+ std::vector<PerExtruderAdjustments*>::iterator it_end,
+ // Elapsed time for the extruders already processed.
+ float elapsed_time_total0,
+ // Initial total elapsed time before slow down.
+ float elapsed_time_before_slowdown,
+ // Target time for the complete layer (all extruders applied).
+ float slowdown_below_layer_time)
+{
+ // Total layer time after the slow down has been applied.
+ float total_after_slowdown = elapsed_time_before_slowdown;
+ // Now decide, whether the external perimeters shall be slowed down as well.
+ float max_time_nep = elapsed_time_total0;
+ for (auto it = it_begin; it != it_end; ++ it)
+ max_time_nep += (*it)->maximum_time_after_slowdown(false);
+ if (max_time_nep > slowdown_below_layer_time) {
+ // It is sufficient to slow down the non-external perimeter moves to reach the target layer time.
+ // Slow down the non-external perimeters proportionally.
+ float non_adjustable_time = elapsed_time_total0;
+ for (auto it = it_begin; it != it_end; ++ it)
+ non_adjustable_time += (*it)->non_adjustable_time(false);
+ // The following step is a linear programming task due to the minimum movement speeds of the print moves.
+ // Run maximum 5 iterations until a good enough approximation is reached.
+ for (size_t iter = 0; iter < 5; ++ iter) {
+ float factor = (slowdown_below_layer_time - non_adjustable_time) / (total_after_slowdown - non_adjustable_time);
+ assert(factor > 1.f);
+ total_after_slowdown = elapsed_time_total0;
+ for (auto it = it_begin; it != it_end; ++ it)
+ total_after_slowdown += (*it)->slow_down_proportional(factor, false);
+ if (total_after_slowdown > 0.95f * slowdown_below_layer_time)
+ break;
+ }
+ } else {
+ // Slow down everything. First slow down the non-external perimeters to maximum.
+ for (auto it = it_begin; it != it_end; ++ it)
+ (*it)->slowdown_to_minimum_feedrate(false);
+ // Slow down the external perimeters proportionally.
+ float non_adjustable_time = elapsed_time_total0;
+ for (auto it = it_begin; it != it_end; ++ it)
+ non_adjustable_time += (*it)->non_adjustable_time(true);
+ for (size_t iter = 0; iter < 5; ++ iter) {
+ float factor = (slowdown_below_layer_time - non_adjustable_time) / (total_after_slowdown - non_adjustable_time);
+ assert(factor > 1.f);
+ total_after_slowdown = elapsed_time_total0;
+ for (auto it = it_begin; it != it_end; ++ it)
+ total_after_slowdown += (*it)->slow_down_proportional(factor, true);
+ if (total_after_slowdown > 0.95f * slowdown_below_layer_time)
+ break;
+ }
+ }
+ return total_after_slowdown;
+}
+
+// Slow down an extruder range to slowdown_below_layer_time.
+// Return the total time for the complete layer.
+static inline void extruder_range_slow_down_non_proportional(
+ std::vector<PerExtruderAdjustments*>::iterator it_begin,
+ std::vector<PerExtruderAdjustments*>::iterator it_end,
+ float time_stretch)
+{
+ // Slow down. Try to equalize the feedrates.
+ std::vector<PerExtruderAdjustments*> by_min_print_speed(it_begin, it_end);
+ // Find the next highest adjustable feedrate among the extruders.
+ float feedrate = 0;
+ for (PerExtruderAdjustments *adj : by_min_print_speed) {
+ adj->idx_line_begin = 0;
+ adj->idx_line_end = 0;
+ assert(adj->idx_line_begin < adj->n_lines_adjustable);
+ if (adj->lines[adj->idx_line_begin].feedrate > feedrate)
+ feedrate = adj->lines[adj->idx_line_begin].feedrate;
+ }
+ assert(feedrate > 0.f);
+ // Sort by min_print_speed, maximum speed first.
+ std::sort(by_min_print_speed.begin(), by_min_print_speed.end(),
+ [](const PerExtruderAdjustments *p1, const PerExtruderAdjustments *p2){ return p1->min_print_speed > p2->min_print_speed; });
+ // Slow down, fast moves first.
+ for (;;) {
+ // For each extruder, find the span of lines with a feedrate close to feedrate.
+ for (PerExtruderAdjustments *adj : by_min_print_speed) {
+ for (adj->idx_line_end = adj->idx_line_begin;
+ adj->idx_line_end < adj->n_lines_adjustable && adj->lines[adj->idx_line_end].feedrate > feedrate - EPSILON;
+ ++ adj->idx_line_end) ;
+ }
+ // Find the next highest adjustable feedrate among the extruders.
+ float feedrate_next = 0.f;
+ for (PerExtruderAdjustments *adj : by_min_print_speed)
+ if (adj->idx_line_end < adj->n_lines_adjustable && adj->lines[adj->idx_line_end].feedrate > feedrate_next)
+ feedrate_next = adj->lines[adj->idx_line_end].feedrate;
+ // Slow down, limited by max(feedrate_next, min_print_speed).
+ for (auto adj = by_min_print_speed.begin(); adj != by_min_print_speed.end();) {
+ // Slow down at most by time_stretch.
+ if ((*adj)->min_print_speed == 0.f) {
+ // All the adjustable speeds are now lowered to the same speed,
+ // and the minimum speed is set to zero.
+ float time_adjustable = 0.f;
+ for (auto it = adj; it != by_min_print_speed.end(); ++ it)
+ time_adjustable += (*it)->adjustable_time(true);
+ float rate = (time_adjustable + time_stretch) / time_adjustable;
+ for (auto it = adj; it != by_min_print_speed.end(); ++ it)
+ (*it)->slow_down_proportional(rate, true);
+ return;
+ } else {
+ float feedrate_limit = std::max(feedrate_next, (*adj)->min_print_speed);
+ bool done = false;
+ float time_stretch_max = 0.f;
+ for (auto it = adj; it != by_min_print_speed.end(); ++ it)
+ time_stretch_max += (*it)->time_stretch_when_slowing_down_to_feedrate(feedrate_limit);
+ if (time_stretch_max >= time_stretch) {
+ feedrate_limit = feedrate - (feedrate - feedrate_limit) * time_stretch / time_stretch_max;
+ done = true;
+ } else
+ time_stretch -= time_stretch_max;
+ for (auto it = adj; it != by_min_print_speed.end(); ++ it)
+ (*it)->slow_down_to_feedrate(feedrate_limit);
+ if (done)
+ return;
+ }
+ // Skip the other extruders with nearly the same min_print_speed, as they have been processed already.
+ auto next = adj;
+ for (++ next; next != by_min_print_speed.end() && (*next)->min_print_speed > (*adj)->min_print_speed - EPSILON; ++ next);
+ adj = next;
+ }
+ if (feedrate_next == 0.f)
+ // There are no other extrusions available for slow down.
+ break;
+ for (PerExtruderAdjustments *adj : by_min_print_speed) {
+ adj->idx_line_begin = adj->idx_line_end;
+ feedrate = feedrate_next;
+ }
+ }
+}
+
+// Calculate slow down for all the extruders.
+float CoolingBuffer::calculate_layer_slowdown(std::vector<PerExtruderAdjustments> &per_extruder_adjustments)
+{
+ // Sort the extruders by an increasing slowdown_below_layer_time.
+ // The layers with a lower slowdown_below_layer_time are slowed down
+ // together with all the other layers with slowdown_below_layer_time above.
+ std::vector<PerExtruderAdjustments*> by_slowdown_time;
+ by_slowdown_time.reserve(per_extruder_adjustments.size());
// Only insert entries, which are adjustable (have cooling enabled and non-zero stretchable time).
// Collect total print time of non-adjustable extruders.
- float elapsed_time_total_non_adjustable = 0.f;
- for (size_t i = 0; i < num_extruders; ++ i) {
- if (config.cooling.get_at(extruders[i].id()))
- by_slowdown_layer_time.emplace_back(i);
- else
- elapsed_time_total_non_adjustable += adjustments[i].elapsed_time_total();
+ float elapsed_time_total0 = 0.f;
+ for (PerExtruderAdjustments &adj : per_extruder_adjustments) {
+ // Curren total time for this extruder.
+ adj.time_total = adj.elapsed_time_total();
+ // Maximum time for this extruder, when all extrusion moves are slowed down to min_extrusion_speed.
+ adj.time_maximum = adj.maximum_time_after_slowdown(true);
+ if (adj.cooling_slow_down_enabled && adj.lines.size() > 0) {
+ by_slowdown_time.emplace_back(&adj);
+ if (! m_cooling_logic_proportional)
+ // sorts the lines, also sets adj.time_non_adjustable
+ adj.sort_lines_by_decreasing_feedrate();
+ } else
+ elapsed_time_total0 += adj.elapsed_time_total();
}
- std::sort(by_slowdown_layer_time.begin(), by_slowdown_layer_time.end(),
- [&config, &extruders](const size_t idx1, const size_t idx2){
- return config.slowdown_below_layer_time.get_at(extruders[idx1].id()) <
- config.slowdown_below_layer_time.get_at(extruders[idx2].id());
- });
+ std::sort(by_slowdown_time.begin(), by_slowdown_time.end(),
+ [](const PerExtruderAdjustments *adj1, const PerExtruderAdjustments *adj2)
+ { return adj1->slowdown_below_layer_time < adj2->slowdown_below_layer_time; });
- // Elapsed time after adjustment.
- float elapsed_time_total = 0.f;
- {
- // Elapsed time for the already adjusted extruders.
- float elapsed_time_total0 = elapsed_time_total_non_adjustable;
- for (size_t i_by_slowdown_layer_time = 0; i_by_slowdown_layer_time < by_slowdown_layer_time.size(); ++ i_by_slowdown_layer_time) {
- // Idx in adjustments.
- size_t idx = by_slowdown_layer_time[i_by_slowdown_layer_time];
- // Macro to sum or adjust all sections starting with i_by_slowdown_layer_time.
- #define FORALL_UNPROCESSED(ACCUMULATOR, ACTION) \
- ACCUMULATOR = elapsed_time_total0;\
- for (size_t j = i_by_slowdown_layer_time; j < by_slowdown_layer_time.size(); ++ j) \
- ACCUMULATOR += adjustments[by_slowdown_layer_time[j]].ACTION
- // Calculate the current adjusted elapsed_time_total over the non-finalized extruders.
- float total;
- FORALL_UNPROCESSED(total, elapsed_time_total());
- float slowdown_below_layer_time = float(config.slowdown_below_layer_time.get_at(adjustments[idx].extruder_id)) * 1.001f;
- if (total > slowdown_below_layer_time) {
- // The current total time is above the minimum threshold of the rest of the extruders, don't adjust anything.
+ for (auto cur_begin = by_slowdown_time.begin(); cur_begin != by_slowdown_time.end(); ++ cur_begin) {
+ PerExtruderAdjustments &adj = *(*cur_begin);
+ // Calculate the current adjusted elapsed_time_total over the non-finalized extruders.
+ float total = elapsed_time_total0;
+ for (auto it = cur_begin; it != by_slowdown_time.end(); ++ it)
+ total += (*it)->time_total;
+ float slowdown_below_layer_time = adj.slowdown_below_layer_time * 1.001f;
+ if (total > slowdown_below_layer_time) {
+ // The current total time is above the minimum threshold of the rest of the extruders, don't adjust anything.
+ } else {
+ // Adjust this and all the following (higher config.slowdown_below_layer_time) extruders.
+ // Sum maximum slow down time as if everything was slowed down including the external perimeters.
+ float max_time = elapsed_time_total0;
+ for (auto it = cur_begin; it != by_slowdown_time.end(); ++ it)
+ max_time += (*it)->time_maximum;
+ if (max_time > slowdown_below_layer_time) {
+ if (m_cooling_logic_proportional)
+ extruder_range_slow_down_proportional(cur_begin, by_slowdown_time.end(), elapsed_time_total0, total, slowdown_below_layer_time);
+ else
+ extruder_range_slow_down_non_proportional(cur_begin, by_slowdown_time.end(), slowdown_below_layer_time - total);
} else {
- // Adjust this and all the following (higher config.slowdown_below_layer_time) extruders.
- // Sum maximum slow down time as if everything was slowed down including the external perimeters.
- float max_time;
- FORALL_UNPROCESSED(max_time, maximum_time(true));
- if (max_time > slowdown_below_layer_time) {
- // By slowing every possible movement, the layer time could be reached. Now decide
- // whether the external perimeters shall be slowed down as well.
- float max_time_nep;
- FORALL_UNPROCESSED(max_time_nep, maximum_time(false));
- if (max_time_nep > slowdown_below_layer_time) {
- // It is sufficient to slow down the non-external perimeter moves to reach the target layer time.
- // Slow down the non-external perimeters proportionally.
- float non_adjustable_time;
- FORALL_UNPROCESSED(non_adjustable_time, non_adjustable_time(false));
- // The following step is a linear programming task due to the minimum movement speeds of the print moves.
- // Run maximum 5 iterations until a good enough approximation is reached.
- for (size_t iter = 0; iter < 5; ++ iter) {
- float factor = (slowdown_below_layer_time - non_adjustable_time) / (total - non_adjustable_time);
- assert(factor > 1.f);
- FORALL_UNPROCESSED(total, slow_down_proportional(factor, false));
- if (total > 0.95f * slowdown_below_layer_time)
- break;
- }
- } else {
- // Slow down everything. First slow down the non-external perimeters to maximum.
- FORALL_UNPROCESSED(total, slow_down_maximum(false));
- // Slow down the external perimeters proportionally.
- float non_adjustable_time;
- FORALL_UNPROCESSED(non_adjustable_time, non_adjustable_time(true));
- for (size_t iter = 0; iter < 5; ++ iter) {
- float factor = (slowdown_below_layer_time - non_adjustable_time) / (total - non_adjustable_time);
- assert(factor > 1.f);
- FORALL_UNPROCESSED(total, slow_down_proportional(factor, true));
- if (total > 0.95f * slowdown_below_layer_time)
- break;
- }
- }
- } else {
- // Slow down to maximum possible.
- FORALL_UNPROCESSED(total, slow_down_maximum(true));
- }
+ // Slow down to maximum possible.
+ for (auto it = cur_begin; it != by_slowdown_time.end(); ++ it)
+ (*it)->slowdown_to_minimum_feedrate(true);
}
- #undef FORALL_UNPROCESSED
- // Sum the final elapsed time for all extruders up to i_by_slowdown_layer_time.
- if (i_by_slowdown_layer_time + 1 == by_slowdown_layer_time.size())
- // Optimization for single extruder prints.
- elapsed_time_total0 = total;
- else
- elapsed_time_total0 += adjustments[idx].elapsed_time_total();
}
- elapsed_time_total = elapsed_time_total0;
+ elapsed_time_total0 += adj.elapsed_time_total();
}
- // Transform the G-code.
- // First sort the adjustment lines by their position in the source G-code.
- std::vector<const Adjustment::Line*> lines;
+ return elapsed_time_total0;
+}
+
+// Apply slow down over G-code lines stored in per_extruder_adjustments, enable fan if needed.
+// Returns the adjusted G-code.
+std::string CoolingBuffer::apply_layer_cooldown(
+ // Source G-code for the current layer.
+ const std::string &gcode,
+ // ID of the current layer, used to disable fan for the first n layers.
+ size_t layer_id,
+ // Total time of this layer after slow down, used to control the fan.
+ float layer_time,
+ // Per extruder list of G-code lines and their cool down attributes.
+ std::vector<PerExtruderAdjustments> &per_extruder_adjustments)
+{
+ // First sort the adjustment lines by of multiple extruders by their position in the source G-code.
+ std::vector<const CoolingLine*> lines;
{
size_t n_lines = 0;
- for (const Adjustment &adj : adjustments)
+ for (const PerExtruderAdjustments &adj : per_extruder_adjustments)
n_lines += adj.lines.size();
lines.reserve(n_lines);
- for (const Adjustment &adj : adjustments)
- for (const Adjustment::Line &line : adj.lines)
+ for (const PerExtruderAdjustments &adj : per_extruder_adjustments)
+ for (const CoolingLine &line : adj.lines)
lines.emplace_back(&line);
- std::sort(lines.begin(), lines.end(), [](const Adjustment::Line *ln1, const Adjustment::Line *ln2) { return ln1->line_start < ln2->line_start; } );
+ std::sort(lines.begin(), lines.end(), [](const CoolingLine *ln1, const CoolingLine *ln2) { return ln1->line_start < ln2->line_start; } );
}
// Second generate the adjusted G-code.
std::string new_gcode;
@@ -390,8 +610,9 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
int fan_speed = -1;
bool bridge_fan_control = false;
int bridge_fan_speed = 0;
- auto change_extruder_set_fan = [ this, layer_id, elapsed_time_total, &new_gcode, &fan_speed, &bridge_fan_control, &bridge_fan_speed ]() {
+ auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &fan_speed, &bridge_fan_control, &bridge_fan_speed ]() {
const FullPrintConfig &config = m_gcodegen.config();
+#define EXTRUDER_CONFIG(OPT) config.OPT.get_at(m_current_extruder)
int min_fan_speed = EXTRUDER_CONFIG(min_fan_speed);
int fan_speed_new = EXTRUDER_CONFIG(fan_always_on) ? min_fan_speed : 0;
if (layer_id >= EXTRUDER_CONFIG(disable_fan_first_layers)) {
@@ -399,17 +620,18 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
float slowdown_below_layer_time = float(EXTRUDER_CONFIG(slowdown_below_layer_time));
float fan_below_layer_time = float(EXTRUDER_CONFIG(fan_below_layer_time));
if (EXTRUDER_CONFIG(cooling)) {
- if (elapsed_time_total < slowdown_below_layer_time) {
+ if (layer_time < slowdown_below_layer_time) {
// Layer time very short. Enable the fan to a full throttle.
fan_speed_new = max_fan_speed;
- } else if (elapsed_time_total < fan_below_layer_time) {
+ } else if (layer_time < fan_below_layer_time) {
// Layer time quite short. Enable the fan proportionally according to the current layer time.
- assert(elapsed_time_total >= slowdown_below_layer_time);
- double t = (elapsed_time_total - slowdown_below_layer_time) / (fan_below_layer_time - slowdown_below_layer_time);
+ assert(layer_time >= slowdown_below_layer_time);
+ double t = (layer_time - slowdown_below_layer_time) / (fan_below_layer_time - slowdown_below_layer_time);
fan_speed_new = int(floor(t * min_fan_speed + (1. - t) * max_fan_speed) + 0.5);
}
}
bridge_fan_speed = EXTRUDER_CONFIG(bridge_fan_speed);
+#undef EXTRUDER_CONFIG
bridge_fan_control = bridge_fan_speed > fan_speed_new;
} else {
bridge_fan_control = false;
@@ -421,49 +643,50 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
new_gcode += m_gcodegen.writer().set_fan(fan_speed);
}
};
- change_extruder_set_fan();
- const char *pos = gcode.c_str();
- int current_feedrate = 0;
- for (const Adjustment::Line *line : lines) {
+ const char *pos = gcode.c_str();
+ int current_feedrate = 0;
+ const std::string toolchange_prefix = m_gcodegen.writer().toolchange_prefix();
+ change_extruder_set_fan();
+ for (const CoolingLine *line : lines) {
const char *line_start = gcode.c_str() + line->line_start;
const char *line_end = gcode.c_str() + line->line_end;
if (line_start > pos)
new_gcode.append(pos, line_start - pos);
- if (line->type & Adjustment::Line::TYPE_SET_TOOL) {
+ if (line->type & CoolingLine::TYPE_SET_TOOL) {
unsigned int new_extruder = (unsigned int)atoi(line_start + toolchange_prefix.size());
if (new_extruder != m_current_extruder) {
m_current_extruder = new_extruder;
change_extruder_set_fan();
}
new_gcode.append(line_start, line_end - line_start);
- } else if (line->type & Adjustment::Line::TYPE_BRIDGE_FAN_START) {
+ } else if (line->type & CoolingLine::TYPE_BRIDGE_FAN_START) {
if (bridge_fan_control)
new_gcode += m_gcodegen.writer().set_fan(bridge_fan_speed, true);
- } else if (line->type & Adjustment::Line::TYPE_BRIDGE_FAN_END) {
+ } else if (line->type & CoolingLine::TYPE_BRIDGE_FAN_END) {
if (bridge_fan_control)
new_gcode += m_gcodegen.writer().set_fan(fan_speed, true);
- } else if (line->type & Adjustment::Line::TYPE_EXTRUDE_END) {
+ } else if (line->type & CoolingLine::TYPE_EXTRUDE_END) {
// Just remove this comment.
- } else if (line->type & (Adjustment::Line::TYPE_ADJUSTABLE | Adjustment::Line::TYPE_EXTERNAL_PERIMETER | Adjustment::Line::TYPE_WIPE | Adjustment::Line::TYPE_HAS_F)) {
+ } else if (line->type & (CoolingLine::TYPE_ADJUSTABLE | CoolingLine::TYPE_EXTERNAL_PERIMETER | CoolingLine::TYPE_WIPE | CoolingLine::TYPE_HAS_F)) {
// Find the start of a comment, or roll to the end of line.
- const char *end = line_start;
- for (; end < line_end && *end != ';'; ++ end);
- // Find the 'F' word.
+ const char *end = line_start;
+ for (; end < line_end && *end != ';'; ++ end);
+ // Find the 'F' word.
const char *fpos = strstr(line_start + 2, " F") + 2;
int new_feedrate = current_feedrate;
bool modify = false;
assert(fpos != nullptr);
if (line->slowdown) {
modify = true;
- new_feedrate = int(floor(60. * (line->length / line->time) + 0.5));
+ new_feedrate = int(floor(60. * line->feedrate + 0.5));
} else {
new_feedrate = atoi(fpos);
if (new_feedrate != current_feedrate) {
// Append the line without the comment.
new_gcode.append(line_start, end - line_start);
current_feedrate = new_feedrate;
- } else if ((line->type & (Adjustment::Line::TYPE_ADJUSTABLE | Adjustment::Line::TYPE_EXTERNAL_PERIMETER | Adjustment::Line::TYPE_WIPE)) || line->length == 0.) {
+ } else if ((line->type & (CoolingLine::TYPE_ADJUSTABLE | CoolingLine::TYPE_EXTERNAL_PERIMETER | CoolingLine::TYPE_WIPE)) || line->length == 0.) {
// Feedrate does not change and this line does not move the print head. Skip the complete G-code line including the G-code comment.
end = line_end;
} else {
@@ -488,7 +711,7 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
new_gcode.append(line_start, f - line_start + 1);
}
// Skip the non-whitespaces of the F parameter up the comment or end of line.
- for (; fpos != end && *fpos != ' ' && *fpos != ';' && *fpos != '\n'; ++fpos);
+ for (; fpos != end && *fpos != ' ' && *fpos != ';' && *fpos != '\n'; ++fpos);
// Append the rest of the line without the comment.
if (fpos < end)
new_gcode.append(fpos, end - fpos);
@@ -497,22 +720,22 @@ std::string CoolingBuffer::process_layer(const std::string &gcode, size_t layer_
}
// Process the rest of the line.
if (end < line_end) {
- if (line->type & (Adjustment::Line::TYPE_ADJUSTABLE | Adjustment::Line::TYPE_EXTERNAL_PERIMETER | Adjustment::Line::TYPE_WIPE)) {
- // Process comments, remove ";_EXTRUDE_SET_SPEED", ";_EXTERNAL_PERIMETER", ";_WIPE"
- std::string comment(end, line_end);
- boost::replace_all(comment, ";_EXTRUDE_SET_SPEED", "");
- if (line->type & Adjustment::Line::TYPE_EXTERNAL_PERIMETER)
+ if (line->type & (CoolingLine::TYPE_ADJUSTABLE | CoolingLine::TYPE_EXTERNAL_PERIMETER | CoolingLine::TYPE_WIPE)) {
+ // Process comments, remove ";_EXTRUDE_SET_SPEED", ";_EXTERNAL_PERIMETER", ";_WIPE"
+ std::string comment(end, line_end);
+ boost::replace_all(comment, ";_EXTRUDE_SET_SPEED", "");
+ if (line->type & CoolingLine::TYPE_EXTERNAL_PERIMETER)
boost::replace_all(comment, ";_EXTERNAL_PERIMETER", "");
- if (line->type & Adjustment::Line::TYPE_WIPE)
+ if (line->type & CoolingLine::TYPE_WIPE)
boost::replace_all(comment, ";_WIPE", "");
- new_gcode += comment;
- } else {
- // Just attach the rest of the source line.
- new_gcode.append(end, line_end - end);
- }
+ new_gcode += comment;
+ } else {
+ // Just attach the rest of the source line.
+ new_gcode.append(end, line_end - end);
+ }
}
} else {
- new_gcode.append(line_start, line_end - line_start);
+ new_gcode.append(line_start, line_end - line_start);
}
pos = line_end;
}
diff --git a/xs/src/libslic3r/GCode/CoolingBuffer.hpp b/xs/src/libslic3r/GCode/CoolingBuffer.hpp
index f85c470b3..bf4b082e2 100644
--- a/xs/src/libslic3r/GCode/CoolingBuffer.hpp
+++ b/xs/src/libslic3r/GCode/CoolingBuffer.hpp
@@ -9,13 +9,17 @@ namespace Slic3r {
class GCode;
class Layer;
-
-/*
-A standalone G-code filter, to control cooling of the print.
-The G-code is processed per layer. Once a layer is collected, fan start / stop commands are edited
-and the print is modified to stretch over a minimum layer time.
-*/
-
+class PerExtruderAdjustments;
+
+// A standalone G-code filter, to control cooling of the print.
+// The G-code is processed per layer. Once a layer is collected, fan start / stop commands are edited
+// and the print is modified to stretch over a minimum layer time.
+//
+// The simple it sounds, the actual implementation is significantly more complex.
+// Namely, for a multi-extruder print, each material may require a different cooling logic.
+// For example, some materials may not like to print too slowly, while with some materials
+// we may slow down significantly.
+//
class CoolingBuffer {
public:
CoolingBuffer(GCode &gcodegen);
@@ -25,7 +29,12 @@ public:
GCode* gcodegen() { return &m_gcodegen; }
private:
- CoolingBuffer& operator=(const CoolingBuffer&);
+ CoolingBuffer& operator=(const CoolingBuffer&) = delete;
+ std::vector<PerExtruderAdjustments> parse_layer_gcode(const std::string &gcode, std::vector<float> &current_pos) const;
+ float calculate_layer_slowdown(std::vector<PerExtruderAdjustments> &per_extruder_adjustments);
+ // Apply slow down over G-code lines stored in per_extruder_adjustments, enable fan if needed.
+ // Returns the adjusted G-code.
+ std::string apply_layer_cooldown(const std::string &gcode, size_t layer_id, float layer_time, std::vector<PerExtruderAdjustments> &per_extruder_adjustments);
GCode& m_gcodegen;
std::string m_gcode;
@@ -34,6 +43,9 @@ private:
std::vector<char> m_axis;
std::vector<float> m_current_pos;
unsigned int m_current_extruder;
+
+ // Old logic: proportional.
+ bool m_cooling_logic_proportional = false;
};
}
diff --git a/xs/src/libslic3r/GCode/PreviewData.cpp b/xs/src/libslic3r/GCode/PreviewData.cpp
index 1923505e4..9cf9716e0 100644
--- a/xs/src/libslic3r/GCode/PreviewData.cpp
+++ b/xs/src/libslic3r/GCode/PreviewData.cpp
@@ -2,7 +2,12 @@
#include "PreviewData.hpp"
#include <float.h>
#include <wx/intl.h>
-#include "slic3r/GUI/GUI.hpp"
+#include <I18N.hpp>
+
+#include <boost/format.hpp>
+
+//! macro used to mark string used at localization,
+#define L(s) (s)
namespace Slic3r {
@@ -85,6 +90,12 @@ void GCodePreviewData::Range::update_from(float value)
max = std::max(max, value);
}
+void GCodePreviewData::Range::update_from(const Range& other)
+{
+ min = std::min(min, other.min);
+ max = std::max(max, other.max);
+}
+
void GCodePreviewData::Range::set_from(const Range& other)
{
min = other.min;
@@ -93,17 +104,31 @@ void GCodePreviewData::Range::set_from(const Range& other)
float GCodePreviewData::Range::step_size() const
{
- return (max - min) / (float)Colors_Count;
+ return (max - min) / (float)(Colors_Count - 1);
}
-const GCodePreviewData::Color& GCodePreviewData::Range::get_color_at_max() const
+GCodePreviewData::Color GCodePreviewData::Range::get_color_at(float value) const
{
- return colors[Colors_Count - 1];
-}
+ if (empty())
+ return Color::Dummy;
-const GCodePreviewData::Color& GCodePreviewData::Range::get_color_at(float value) const
-{
- return empty() ? get_color_at_max() : colors[clamp((unsigned int)0, Colors_Count - 1, (unsigned int)((value - min) / step_size()))];
+ float global_t = (value - min) / step_size();
+
+ unsigned int low = (unsigned int)global_t;
+ unsigned int high = clamp((unsigned int)0, Colors_Count - 1, low + 1);
+
+ Color color_low = colors[low];
+ Color color_high = colors[high];
+
+ float local_t = global_t - (float)low;
+
+ // interpolate in RGB space
+ Color ret;
+ for (unsigned int i = 0; i < 4; ++i)
+ {
+ ret.rgba[i] = lerp(color_low.rgba[i], color_high.rgba[i], local_t);
+ }
+ return ret;
}
GCodePreviewData::LegendItem::LegendItem(const std::string& text, const GCodePreviewData::Color& color)
@@ -158,9 +183,6 @@ void GCodePreviewData::Extrusion::set_default()
view_type = Default_View_Type;
::memcpy((void*)role_colors, (const void*)Default_Extrusion_Role_Colors, Num_Extrusion_Roles * sizeof(Color));
- ::memcpy((void*)ranges.height.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
- ::memcpy((void*)ranges.width.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
- ::memcpy((void*)ranges.feedrate.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
for (unsigned int i = 0; i < Num_Extrusion_Roles; ++i)
{
@@ -198,12 +220,13 @@ void GCodePreviewData::Travel::set_default()
width = Default_Width;
height = Default_Height;
::memcpy((void*)type_colors, (const void*)Default_Type_Colors, Num_Types * sizeof(Color));
+
is_visible = false;
}
const GCodePreviewData::Color GCodePreviewData::Retraction::Default_Color = GCodePreviewData::Color(1.0f, 1.0f, 1.0f, 1.0f);
-GCodePreviewData::Retraction::Position::Position(const Point3& position, float width, float height)
+GCodePreviewData::Retraction::Position::Position(const Vec3crd& position, float width, float height)
: position(position)
, width(width)
, height(height)
@@ -228,6 +251,11 @@ GCodePreviewData::GCodePreviewData()
void GCodePreviewData::set_default()
{
+ ::memcpy((void*)ranges.height.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
+ ::memcpy((void*)ranges.width.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
+ ::memcpy((void*)ranges.feedrate.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
+ ::memcpy((void*)ranges.volumetric_rate.colors, (const void*)Range::Default_Colors, Range::Colors_Count * sizeof(Color));
+
extrusion.set_default();
travel.set_default();
retraction.set_default();
@@ -237,6 +265,10 @@ void GCodePreviewData::set_default()
void GCodePreviewData::reset()
{
+ ranges.width.reset();
+ ranges.height.reset();
+ ranges.feedrate.reset();
+ ranges.volumetric_rate.reset();
extrusion.layers.clear();
travel.polylines.clear();
retraction.positions.clear();
@@ -248,24 +280,29 @@ bool GCodePreviewData::empty() const
return extrusion.layers.empty() && travel.polylines.empty() && retraction.positions.empty() && unretraction.positions.empty();
}
-const GCodePreviewData::Color& GCodePreviewData::get_extrusion_role_color(ExtrusionRole role) const
+GCodePreviewData::Color GCodePreviewData::get_extrusion_role_color(ExtrusionRole role) const
{
return extrusion.role_colors[role];
}
-const GCodePreviewData::Color& GCodePreviewData::get_extrusion_height_color(float height) const
+GCodePreviewData::Color GCodePreviewData::get_height_color(float height) const
+{
+ return ranges.height.get_color_at(height);
+}
+
+GCodePreviewData::Color GCodePreviewData::get_width_color(float width) const
{
- return extrusion.ranges.height.get_color_at(height);
+ return ranges.width.get_color_at(width);
}
-const GCodePreviewData::Color& GCodePreviewData::get_extrusion_width_color(float width) const
+GCodePreviewData::Color GCodePreviewData::get_feedrate_color(float feedrate) const
{
- return extrusion.ranges.width.get_color_at(width);
+ return ranges.feedrate.get_color_at(feedrate);
}
-const GCodePreviewData::Color& GCodePreviewData::get_extrusion_feedrate_color(float feedrate) const
+GCodePreviewData::Color GCodePreviewData::get_volumetric_rate_color(float rate) const
{
- return extrusion.ranges.feedrate.get_color_at(feedrate);
+ return ranges.volumetric_rate.get_color_at(rate);
}
void GCodePreviewData::set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha)
@@ -334,6 +371,8 @@ std::string GCodePreviewData::get_legend_title() const
return L("Width (mm)");
case Extrusion::Feedrate:
return L("Speed (mm/s)");
+ case Extrusion::VolumetricRate:
+ return L("Volumetric flow rate (mm3/s)");
case Extrusion::Tool:
return L("Tool");
}
@@ -348,11 +387,12 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
static void FillListFromRange(LegendItemsList& list, const Range& range, unsigned int decimals, float scale_factor)
{
list.reserve(Range::Colors_Count);
+
float step = range.step_size();
- for (unsigned int i = 0; i < Range::Colors_Count; ++i)
+ for (int i = Range::Colors_Count - 1; i >= 0; --i)
{
- char buf[32];
- sprintf(buf, "%.*f/%.*f", decimals, scale_factor * (range.min + (float)i * step), decimals, scale_factor * (range.min + (float)(i + 1) * step));
+ char buf[1024];
+ sprintf(buf, "%.*f", decimals, scale_factor * (range.min + (float)i * step));
list.emplace_back(buf, range.colors[i]);
}
}
@@ -370,24 +410,29 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
items.reserve(last_valid - first_valid + 1);
for (unsigned int i = (unsigned int)first_valid; i <= (unsigned int)last_valid; ++i)
{
- items.emplace_back(_CHB(extrusion.role_names[i].c_str()).data(), extrusion.role_colors[i]);
+ items.emplace_back(Slic3r::I18N::translate(extrusion.role_names[i]), extrusion.role_colors[i]);
}
break;
}
case Extrusion::Height:
{
- Helper::FillListFromRange(items, extrusion.ranges.height, 3, 1.0f);
+ Helper::FillListFromRange(items, ranges.height, 3, 1.0f);
break;
}
case Extrusion::Width:
{
- Helper::FillListFromRange(items, extrusion.ranges.width, 3, 1.0f);
+ Helper::FillListFromRange(items, ranges.width, 3, 1.0f);
break;
}
case Extrusion::Feedrate:
{
- Helper::FillListFromRange(items, extrusion.ranges.feedrate, 0, 1.0f);
+ Helper::FillListFromRange(items, ranges.feedrate, 1, 1.0f);
+ break;
+ }
+ case Extrusion::VolumetricRate:
+ {
+ Helper::FillListFromRange(items, ranges.volumetric_rate, 3, 1.0f);
break;
}
case Extrusion::Tool:
@@ -396,13 +441,9 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
items.reserve(tools_colors_count);
for (unsigned int i = 0; i < tools_colors_count; ++i)
{
- char buf[MIN_BUF_LENGTH_FOR_L];
- sprintf(buf, _CHB(L("Extruder %d")), i + 1);
-
GCodePreviewData::Color color;
::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + i * 4), 4 * sizeof(float));
-
- items.emplace_back(buf, color);
+ items.emplace_back((boost::format(Slic3r::I18N::translate(L("Extruder %d"))) % (i + 1)).str(), color);
}
break;
diff --git a/xs/src/libslic3r/GCode/PreviewData.hpp b/xs/src/libslic3r/GCode/PreviewData.hpp
index 9fb2dc464..ab74993f5 100644
--- a/xs/src/libslic3r/GCode/PreviewData.hpp
+++ b/xs/src/libslic3r/GCode/PreviewData.hpp
@@ -37,11 +37,19 @@ public:
void reset();
bool empty() const;
void update_from(float value);
+ void update_from(const Range& other);
void set_from(const Range& other);
float step_size() const;
- const Color& get_color_at(float value) const;
- const Color& get_color_at_max() const;
+ Color get_color_at(float value) const;
+ };
+
+ struct Ranges
+ {
+ Range height;
+ Range width;
+ Range feedrate;
+ Range volumetric_rate;
};
struct LegendItem
@@ -62,6 +70,7 @@ public:
Height,
Width,
Feedrate,
+ VolumetricRate,
Tool,
Num_View_Types
};
@@ -71,13 +80,6 @@ public:
static const std::string Default_Extrusion_Role_Names[Num_Extrusion_Roles];
static const EViewType Default_View_Type;
- struct Ranges
- {
- Range height;
- Range width;
- Range feedrate;
- };
-
struct Layer
{
float z;
@@ -91,7 +93,6 @@ public:
EViewType view_type;
Color role_colors[Num_Extrusion_Roles];
std::string role_names[Num_Extrusion_Roles];
- Ranges ranges;
LayersList layers;
unsigned int role_flags;
@@ -150,11 +151,11 @@ public:
struct Position
{
- Point3 position;
+ Vec3crd position;
float width;
float height;
- Position(const Point3& position, float width, float height);
+ Position(const Vec3crd& position, float width, float height);
};
typedef std::vector<Position> PositionsList;
@@ -178,6 +179,7 @@ public:
Retraction retraction;
Retraction unretraction;
Shell shell;
+ Ranges ranges;
GCodePreviewData();
@@ -185,10 +187,11 @@ public:
void reset();
bool empty() const;
- const Color& get_extrusion_role_color(ExtrusionRole role) const;
- const Color& get_extrusion_height_color(float height) const;
- const Color& get_extrusion_width_color(float width) const;
- const Color& get_extrusion_feedrate_color(float feedrate) const;
+ Color get_extrusion_role_color(ExtrusionRole role) const;
+ Color get_height_color(float height) const;
+ Color get_width_color(float width) const;
+ Color get_feedrate_color(float feedrate) const;
+ Color get_volumetric_rate_color(float rate) const;
void set_extrusion_role_color(const std::string& role_name, float red, float green, float blue, float alpha);
void set_extrusion_paths_colors(const std::vector<std::string>& colors);
diff --git a/xs/src/libslic3r/GCode/PrintExtents.cpp b/xs/src/libslic3r/GCode/PrintExtents.cpp
index 43352ee82..00b8838b6 100644
--- a/xs/src/libslic3r/GCode/PrintExtents.cpp
+++ b/xs/src/libslic3r/GCode/PrintExtents.cpp
@@ -19,10 +19,10 @@ static inline BoundingBox extrusion_polyline_extents(const Polyline &polyline, c
if (! polyline.points.empty())
bbox.merge(polyline.points.front());
for (const Point &pt : polyline.points) {
- bbox.min.x = std::min(bbox.min.x, pt.x - radius);
- bbox.min.y = std::min(bbox.min.y, pt.y - radius);
- bbox.max.x = std::max(bbox.max.x, pt.x + radius);
- bbox.max.y = std::max(bbox.max.y, pt.y + radius);
+ bbox.min(0) = std::min(bbox.min(0), pt(0) - radius);
+ bbox.min(1) = std::min(bbox.min(1), pt(1) - radius);
+ bbox.max(0) = std::max(bbox.max(0), pt(0) + radius);
+ bbox.max(1) = std::max(bbox.max(1), pt(1) + radius);
}
return bbox;
}
@@ -32,8 +32,8 @@ static inline BoundingBoxf extrusionentity_extents(const ExtrusionPath &extrusio
BoundingBox bbox = extrusion_polyline_extents(extrusion_path.polyline, scale_(0.5 * extrusion_path.width));
BoundingBoxf bboxf;
if (! empty(bbox)) {
- bboxf.min = Pointf::new_unscale(bbox.min);
- bboxf.max = Pointf::new_unscale(bbox.max);
+ bboxf.min = unscale(bbox.min);
+ bboxf.max = unscale(bbox.max);
bboxf.defined = true;
}
return bboxf;
@@ -46,8 +46,8 @@ static inline BoundingBoxf extrusionentity_extents(const ExtrusionLoop &extrusio
bbox.merge(extrusion_polyline_extents(extrusion_path.polyline, scale_(0.5 * extrusion_path.width)));
BoundingBoxf bboxf;
if (! empty(bbox)) {
- bboxf.min = Pointf::new_unscale(bbox.min);
- bboxf.max = Pointf::new_unscale(bbox.max);
+ bboxf.min = unscale(bbox.min);
+ bboxf.max = unscale(bbox.max);
bboxf.defined = true;
}
return bboxf;
@@ -60,8 +60,8 @@ static inline BoundingBoxf extrusionentity_extents(const ExtrusionMultiPath &ext
bbox.merge(extrusion_polyline_extents(extrusion_path.polyline, scale_(0.5 * extrusion_path.width)));
BoundingBoxf bboxf;
if (! empty(bbox)) {
- bboxf.min = Pointf::new_unscale(bbox.min);
- bboxf.max = Pointf::new_unscale(bbox.max);
+ bboxf.min = unscale(bbox.min);
+ bboxf.max = unscale(bbox.max);
bboxf.defined = true;
}
return bboxf;
@@ -121,9 +121,9 @@ BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object
if (support_layer)
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
bbox_this.merge(extrusionentity_extents(extrusion_entity));
- for (const Point &offset : print_object._shifted_copies) {
+ for (const Point &offset : print_object.copies()) {
BoundingBoxf bbox_translated(bbox_this);
- bbox_translated.translate(Pointf::new_unscale(offset));
+ bbox_translated.translate(unscale(offset));
bbox.merge(bbox_translated);
}
}
@@ -134,6 +134,12 @@ BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object
// The projection does not contain the priming regions.
BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_t max_print_z)
{
+ // Wipe tower extrusions are saved as if the tower was at the origin with no rotation
+ // We need to get position and angle of the wipe tower to transform them to actual position.
+ Transform2d trafo =
+ Eigen::Translation2d(print.config().wipe_tower_x.value, print.config().wipe_tower_y.value) *
+ Eigen::Rotation2Dd(print.config().wipe_tower_rotation_angle.value);
+
BoundingBoxf bbox;
for (const std::vector<WipeTower::ToolChangeResult> &tool_changes : print.wipe_tower_data().tool_changes) {
if (! tool_changes.empty() && tool_changes.front().print_z > max_print_z)
@@ -142,14 +148,11 @@ BoundingBoxf get_wipe_tower_extrusions_extents(const Print &print, const coordf_
for (size_t i = 1; i < tcr.extrusions.size(); ++ i) {
const WipeTower::Extrusion &e = tcr.extrusions[i];
if (e.width > 0) {
- Pointf p1((&e - 1)->pos.x, (&e - 1)->pos.y);
- Pointf p2(e.pos.x, e.pos.y);
- bbox.merge(p1);
- coordf_t radius = 0.5 * e.width;
- bbox.min.x = std::min(bbox.min.x, std::min(p1.x, p2.x) - radius);
- bbox.min.y = std::min(bbox.min.y, std::min(p1.y, p2.y) - radius);
- bbox.max.x = std::max(bbox.max.x, std::max(p1.x, p2.x) + radius);
- bbox.max.y = std::max(bbox.max.y, std::max(p1.y, p2.y) + radius);
+ Vec2d delta = 0.5 * Vec2d(e.width, e.width);
+ Vec2d p1 = trafo * Vec2d((&e - 1)->pos.x, (&e - 1)->pos.y);
+ Vec2d p2 = trafo * Vec2d(e.pos.x, e.pos.y);
+ bbox.merge(p1.cwiseMin(p2) - delta);
+ bbox.merge(p1.cwiseMax(p2) + delta);
}
}
}
@@ -166,14 +169,14 @@ BoundingBoxf get_wipe_tower_priming_extrusions_extents(const Print &print)
for (size_t i = 1; i < tcr.extrusions.size(); ++ i) {
const WipeTower::Extrusion &e = tcr.extrusions[i];
if (e.width > 0) {
- Pointf p1((&e - 1)->pos.x, (&e - 1)->pos.y);
- Pointf p2(e.pos.x, e.pos.y);
+ Vec2d p1((&e - 1)->pos.x, (&e - 1)->pos.y);
+ Vec2d p2(e.pos.x, e.pos.y);
bbox.merge(p1);
coordf_t radius = 0.5 * e.width;
- bbox.min.x = std::min(bbox.min.x, std::min(p1.x, p2.x) - radius);
- bbox.min.y = std::min(bbox.min.y, std::min(p1.y, p2.y) - radius);
- bbox.max.x = std::max(bbox.max.x, std::max(p1.x, p2.x) + radius);
- bbox.max.y = std::max(bbox.max.y, std::max(p1.y, p2.y) + radius);
+ bbox.min(0) = std::min(bbox.min(0), std::min(p1(0), p2(0)) - radius);
+ bbox.min(1) = std::min(bbox.min(1), std::min(p1(1), p2(1)) - radius);
+ bbox.max(0) = std::max(bbox.max(0), std::max(p1(0), p2(0)) + radius);
+ bbox.max(1) = std::max(bbox.max(1), std::max(p1(1), p2(1)) + radius);
}
}
}
diff --git a/xs/src/libslic3r/GCode/ToolOrdering.cpp b/xs/src/libslic3r/GCode/ToolOrdering.cpp
index 6e03d89c9..175b69447 100644
--- a/xs/src/libslic3r/GCode/ToolOrdering.cpp
+++ b/xs/src/libslic3r/GCode/ToolOrdering.cpp
@@ -15,6 +15,24 @@
namespace Slic3r {
+
+// Returns true in case that extruder a comes before b (b does not have to be present). False otherwise.
+bool LayerTools::is_extruder_order(unsigned int a, unsigned int b) const
+{
+ if (a==b)
+ return false;
+
+ for (auto extruder : extruders) {
+ if (extruder == a)
+ return true;
+ if (extruder == b)
+ return false;
+ }
+
+ return false;
+}
+
+
// For the use case when each object is printed separately
// (print.config().complete_objects is true).
ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extruder, bool prime_multi_material)
@@ -48,11 +66,14 @@ ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extrude
// (print.config().complete_objects is false).
ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool prime_multi_material)
{
+ m_print_config_ptr = &print.config();
+
+ PrintObjectPtrs objects = print.get_printable_objects();
// Initialize the print layers for all objects and all layers.
coordf_t object_bottom_z = 0.;
{
std::vector<coordf_t> zs;
- for (auto object : print.objects()) {
+ for (auto object : objects) {
zs.reserve(zs.size() + object->layers().size() + object->support_layers().size());
for (auto layer : object->layers())
zs.emplace_back(layer->print_z);
@@ -65,7 +86,7 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool
}
// Collect extruders reuqired to print the layers.
- for (auto object : print.objects())
+ for (auto object : objects)
this->collect_extruders(*object);
// Reorder the extruders to minimize tool switches.
@@ -76,9 +97,10 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool
this->collect_extruder_statistics(prime_multi_material);
}
-ToolOrdering::LayerTools& ToolOrdering::tools_for_layer(coordf_t print_z)
+
+LayerTools& ToolOrdering::tools_for_layer(coordf_t print_z)
{
- auto it_layer_tools = std::lower_bound(m_layer_tools.begin(), m_layer_tools.end(), ToolOrdering::LayerTools(print_z - EPSILON));
+ auto it_layer_tools = std::lower_bound(m_layer_tools.begin(), m_layer_tools.end(), LayerTools(print_z - EPSILON));
assert(it_layer_tools != m_layer_tools.end());
coordf_t dist_min = std::abs(it_layer_tools->print_z - print_z);
for (++ it_layer_tools; it_layer_tools != m_layer_tools.end(); ++it_layer_tools) {
@@ -102,7 +124,7 @@ void ToolOrdering::initialize_layers(std::vector<coordf_t> &zs)
coordf_t zmax = zs[i] + EPSILON;
for (; j < zs.size() && zs[j] <= zmax; ++ j) ;
// Assign an average print_z to the set of layers with nearly equal print_z.
- m_layer_tools.emplace_back(LayerTools(0.5 * (zs[i] + zs[j-1])));
+ m_layer_tools.emplace_back(LayerTools(0.5 * (zs[i] + zs[j-1]), m_print_config_ptr));
i = j;
}
}
@@ -134,12 +156,29 @@ void ToolOrdering::collect_extruders(const PrintObject &object)
if (layerm == nullptr)
continue;
const PrintRegion &region = *object.print()->regions()[region_id];
+
if (! layerm->perimeters.entities.empty()) {
- layer_tools.extruders.push_back(region.config().perimeter_extruder.value);
+ bool something_nonoverriddable = true;
+
+ if (m_print_config_ptr) { // in this case complete_objects is false (see ToolOrdering constructors)
+ something_nonoverriddable = false;
+ for (const auto& eec : layerm->perimeters.entities) // let's check if there are nonoverriddable entities
+ if (!layer_tools.wiping_extrusions().is_overriddable(dynamic_cast<const ExtrusionEntityCollection&>(*eec), *m_print_config_ptr, object, region)) {
+ something_nonoverriddable = true;
+ break;
+ }
+ }
+
+ if (something_nonoverriddable)
+ layer_tools.extruders.push_back(region.config().perimeter_extruder.value);
+
layer_tools.has_object = true;
}
+
+
bool has_infill = false;
bool has_solid_infill = false;
+ bool something_nonoverriddable = false;
for (const ExtrusionEntity *ee : layerm->fills.entities) {
// fill represents infill extrusions of a single island.
const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
@@ -148,19 +187,33 @@ void ToolOrdering::collect_extruders(const PrintObject &object)
has_solid_infill = true;
else if (role != erNone)
has_infill = true;
+
+ if (m_print_config_ptr) {
+ if (!something_nonoverriddable && !layer_tools.wiping_extrusions().is_overriddable(*fill, *m_print_config_ptr, object, region))
+ something_nonoverriddable = true;
+ }
+ }
+
+ if (something_nonoverriddable || !m_print_config_ptr)
+ {
+ if (has_solid_infill)
+ layer_tools.extruders.push_back(region.config().solid_infill_extruder);
+ if (has_infill)
+ layer_tools.extruders.push_back(region.config().infill_extruder);
}
- if (has_solid_infill)
- layer_tools.extruders.push_back(region.config().solid_infill_extruder);
- if (has_infill)
- layer_tools.extruders.push_back(region.config().infill_extruder);
if (has_solid_infill || has_infill)
layer_tools.has_object = true;
}
}
- // Sort and remove duplicates
- for (LayerTools &lt : m_layer_tools)
- sort_remove_duplicates(lt.extruders);
+ for (auto& layer : m_layer_tools) {
+ // Sort and remove duplicates
+ sort_remove_duplicates(layer.extruders);
+
+ // make sure that there are some tools for each object layer (e.g. tall wiping object will result in empty extruders vector)
+ if (layer.extruders.empty() && layer.has_object)
+ layer.extruders.push_back(0); // 0="dontcare" extruder - it will be taken care of in reorder_extruders
+ }
}
// Reorder extruders to minimize layer changes.
@@ -217,6 +270,8 @@ void ToolOrdering::reorder_extruders(unsigned int last_extruder_id)
}
}
+
+
void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z)
{
if (m_layer_tools.empty())
@@ -327,4 +382,250 @@ void ToolOrdering::collect_extruder_statistics(bool prime_multi_material)
}
}
+
+
+// This function is called from Print::mark_wiping_extrusions and sets extruder this entity should be printed with (-1 .. as usual)
+void WipingExtrusions::set_extruder_override(const ExtrusionEntity* entity, unsigned int copy_id, int extruder, unsigned int num_of_copies)
+{
+ something_overridden = true;
+
+ auto entity_map_it = (entity_map.insert(std::make_pair(entity, std::vector<int>()))).first; // (add and) return iterator
+ auto& copies_vector = entity_map_it->second;
+ if (copies_vector.size() < num_of_copies)
+ copies_vector.resize(num_of_copies, -1);
+
+ if (copies_vector[copy_id] != -1)
+ std::cout << "ERROR: Entity extruder overriden multiple times!!!\n"; // A debugging message - this must never happen.
+
+ copies_vector[copy_id] = extruder;
+}
+
+
+// Finds first non-soluble extruder on the layer
+int WipingExtrusions::first_nonsoluble_extruder_on_layer(const PrintConfig& print_config) const
+{
+ const LayerTools& lt = *m_layer_tools;
+ for (auto extruders_it = lt.extruders.begin(); extruders_it != lt.extruders.end(); ++extruders_it)
+ if (!print_config.filament_soluble.get_at(*extruders_it))
+ return (*extruders_it);
+
+ return (-1);
+}
+
+// Finds last non-soluble extruder on the layer
+int WipingExtrusions::last_nonsoluble_extruder_on_layer(const PrintConfig& print_config) const
+{
+ const LayerTools& lt = *m_layer_tools;
+ for (auto extruders_it = lt.extruders.rbegin(); extruders_it != lt.extruders.rend(); ++extruders_it)
+ if (!print_config.filament_soluble.get_at(*extruders_it))
+ return (*extruders_it);
+
+ return (-1);
+}
+
+
+// Decides whether this entity could be overridden
+bool WipingExtrusions::is_overriddable(const ExtrusionEntityCollection& eec, const PrintConfig& print_config, const PrintObject& object, const PrintRegion& region) const
+{
+ if (print_config.filament_soluble.get_at(Print::get_extruder(eec, region)))
+ return false;
+
+ if (object.config().wipe_into_objects)
+ return true;
+
+ if (!region.config().wipe_into_infill || eec.role() != erInternalInfill)
+ return false;
+
+ return true;
+}
+
+
+// Following function iterates through all extrusions on the layer, remembers those that could be used for wiping after toolchange
+// and returns volume that is left to be wiped on the wipe tower.
+float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int old_extruder, unsigned int new_extruder, float volume_to_wipe)
+{
+ const LayerTools& lt = *m_layer_tools;
+ const float min_infill_volume = 0.f; // ignore infill with smaller volume than this
+
+ if (print.config().filament_soluble.get_at(old_extruder) || print.config().filament_soluble.get_at(new_extruder))
+ return volume_to_wipe; // Soluble filament cannot be wiped in a random infill, neither the filament after it
+
+ // we will sort objects so that dedicated for wiping are at the beginning:
+ PrintObjectPtrs object_list = print.get_printable_objects();
+ std::sort(object_list.begin(), object_list.end(), [](const PrintObject* a, const PrintObject* b) { return a->config().wipe_into_objects; });
+
+ // We will now iterate through
+ // - first the dedicated objects to mark perimeters or infills (depending on infill_first)
+ // - second through the dedicated ones again to mark infills or perimeters (depending on infill_first)
+ // - then all the others to mark infills (in case that !infill_first, we must also check that the perimeter is finished already
+ // this is controlled by the following variable:
+ bool perimeters_done = false;
+
+ for (int i=0 ; i<(int)object_list.size() + (perimeters_done ? 0 : 1); ++i) {
+ if (!perimeters_done && (i==(int)object_list.size() || !object_list[i]->config().wipe_into_objects)) { // we passed the last dedicated object in list
+ perimeters_done = true;
+ i=-1; // let's go from the start again
+ continue;
+ }
+
+ const auto& object = object_list[i];
+
+ // Finds this layer:
+ auto this_layer_it = std::find_if(object->layers().begin(), object->layers().end(), [&lt](const Layer* lay) { return std::abs(lt.print_z - lay->print_z)<EPSILON; });
+ if (this_layer_it == object->layers().end())
+ continue;
+ const Layer* this_layer = *this_layer_it;
+ unsigned int num_of_copies = object->copies().size();
+
+ for (unsigned int copy = 0; copy < num_of_copies; ++copy) { // iterate through copies first, so that we mark neighbouring infills to minimize travel moves
+
+ for (size_t region_id = 0; region_id < object->print()->regions().size(); ++ region_id) {
+ const auto& region = *object->print()->regions()[region_id];
+
+ if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
+ continue;
+
+
+ if ((!print.config().infill_first ? perimeters_done : !perimeters_done) || (!object->config().wipe_into_objects && region.config().wipe_into_infill)) {
+ for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->fills.entities) { // iterate through all infill Collections
+ auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
+
+ if (!is_overriddable(*fill, print.config(), *object, region))
+ continue;
+
+ // What extruder would this normally be printed with?
+ unsigned int correct_extruder = Print::get_extruder(*fill, region);
+
+ if (volume_to_wipe<=0)
+ continue;
+
+ if (!object->config().wipe_into_objects && !print.config().infill_first && region.config().wipe_into_infill)
+ // In this case we must check that the original extruder is used on this layer before the one we are overridding
+ // (and the perimeters will be finished before the infill is printed):
+ if (!lt.is_extruder_order(region.config().perimeter_extruder - 1, new_extruder))
+ continue;
+
+ if ((!is_entity_overridden(fill, copy) && fill->total_volume() > min_infill_volume)) { // this infill will be used to wipe this extruder
+ set_extruder_override(fill, copy, new_extruder, num_of_copies);
+ volume_to_wipe -= fill->total_volume();
+ }
+ }
+ }
+
+ // Now the same for perimeters - see comments above for explanation:
+ if (object->config().wipe_into_objects && (print.config().infill_first ? perimeters_done : !perimeters_done))
+ {
+ for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->perimeters.entities) {
+ auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
+ if (!is_overriddable(*fill, print.config(), *object, region))
+ continue;
+
+ if (volume_to_wipe<=0)
+ continue;
+
+ if ((!is_entity_overridden(fill, copy) && fill->total_volume() > min_infill_volume)) {
+ set_extruder_override(fill, copy, new_extruder, num_of_copies);
+ volume_to_wipe -= fill->total_volume();
+ }
+ }
+ }
+ }
+ }
+ }
+ return std::max(0.f, volume_to_wipe);
+}
+
+
+
+// Called after all toolchanges on a layer were mark_infill_overridden. There might still be overridable entities,
+// that were not actually overridden. If they are part of a dedicated object, printing them with the extruder
+// they were initially assigned to might mean violating the perimeter-infill order. We will therefore go through
+// them again and make sure we override it.
+void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
+{
+ const LayerTools& lt = *m_layer_tools;
+ unsigned int first_nonsoluble_extruder = first_nonsoluble_extruder_on_layer(print.config());
+ unsigned int last_nonsoluble_extruder = last_nonsoluble_extruder_on_layer(print.config());
+
+ PrintObjectPtrs printable_objects = print.get_printable_objects();
+ for (const PrintObject* object : printable_objects) {
+ // Finds this layer:
+ auto this_layer_it = std::find_if(object->layers().begin(), object->layers().end(), [&lt](const Layer* lay) { return std::abs(lt.print_z - lay->print_z)<EPSILON; });
+ if (this_layer_it == object->layers().end())
+ continue;
+ const Layer* this_layer = *this_layer_it;
+ unsigned int num_of_copies = object->copies().size();
+
+ for (unsigned int copy = 0; copy < num_of_copies; ++copy) { // iterate through copies first, so that we mark neighbouring infills to minimize travel moves
+ for (size_t region_id = 0; region_id < object->print()->regions().size(); ++ region_id) {
+ const auto& region = *object->print()->regions()[region_id];
+
+ if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
+ continue;
+
+ for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->fills.entities) { // iterate through all infill Collections
+ auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
+
+ if (!is_overriddable(*fill, print.config(), *object, region)
+ || is_entity_overridden(fill, copy) )
+ continue;
+
+ // This infill could have been overridden but was not - unless we do something, it could be
+ // printed before its perimeter, or not be printed at all (in case its original extruder has
+ // not been added to LayerTools
+ // Either way, we will now force-override it with something suitable:
+ if (print.config().infill_first
+ || object->config().wipe_into_objects // in this case the perimeter is overridden, so we can override by the last one safely
+ || lt.is_extruder_order(region.config().perimeter_extruder - 1, last_nonsoluble_extruder // !infill_first, but perimeter is already printed when last extruder prints
+ || std::find(lt.extruders.begin(), lt.extruders.end(), region.config().infill_extruder - 1) == lt.extruders.end()) // we have to force override - this could violate infill_first (FIXME)
+ )
+ set_extruder_override(fill, copy, (print.config().infill_first ? first_nonsoluble_extruder : last_nonsoluble_extruder), num_of_copies);
+ else {
+ // In this case we can (and should) leave it to be printed normally.
+ // Force overriding would mean it gets printed before its perimeter.
+ }
+ }
+
+ // Now the same for perimeters - see comments above for explanation:
+ for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->perimeters.entities) { // iterate through all perimeter Collections
+ auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
+ if (!is_overriddable(*fill, print.config(), *object, region)
+ || is_entity_overridden(fill, copy) )
+ continue;
+
+ set_extruder_override(fill, copy, (print.config().infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies);
+ }
+ }
+ }
+ }
+}
+
+
+
+
+
+
+
+// Following function is called from process_layer and returns pointer to vector with information about which extruders should be used for given copy of this entity.
+// It first makes sure the pointer is valid (creates the vector if it does not exist) and contains a record for each copy
+// It also modifies the vector in place and changes all -1 to correct_extruder_id (at the time the overrides were created, correct extruders were not known,
+// so -1 was used as "print as usual".
+// The resulting vector has to keep track of which extrusions are the ones that were overridden and which were not. In the extruder is used as overridden,
+// its number is saved as it is (zero-based index). Usual extrusions are saved as -number-1 (unfortunately there is no negative zero).
+const std::vector<int>* WipingExtrusions::get_extruder_overrides(const ExtrusionEntity* entity, int correct_extruder_id, int num_of_copies)
+{
+ auto entity_map_it = entity_map.find(entity);
+ if (entity_map_it == entity_map.end())
+ entity_map_it = (entity_map.insert(std::make_pair(entity, std::vector<int>()))).first;
+
+ // Now the entity_map_it should be valid, let's make sure the vector is long enough:
+ entity_map_it->second.resize(num_of_copies, -1);
+
+ // Each -1 now means "print as usual" - we will replace it with actual extruder id (shifted it so we don't lose that information):
+ std::replace(entity_map_it->second.begin(), entity_map_it->second.end(), -1, -correct_extruder_id-1);
+
+ return &(entity_map_it->second);
+}
+
+
} // namespace Slic3r
diff --git a/xs/src/libslic3r/GCode/ToolOrdering.hpp b/xs/src/libslic3r/GCode/ToolOrdering.hpp
index c92806b19..4dcf6516a 100644
--- a/xs/src/libslic3r/GCode/ToolOrdering.hpp
+++ b/xs/src/libslic3r/GCode/ToolOrdering.hpp
@@ -9,38 +9,99 @@ namespace Slic3r {
class Print;
class PrintObject;
+class LayerTools;
-class ToolOrdering
+
+
+// Object of this class holds information about whether an extrusion is printed immediately
+// after a toolchange (as part of infill/perimeter wiping) or not. One extrusion can be a part
+// of several copies - this has to be taken into account.
+class WipingExtrusions
+{
+public:
+ bool is_anything_overridden() const { // if there are no overrides, all the agenda can be skipped - this function can tell us if that's the case
+ return something_overridden;
+ }
+
+ // This is called from GCode::process_layer - see implementation for further comments:
+ const std::vector<int>* get_extruder_overrides(const ExtrusionEntity* entity, int correct_extruder_id, int num_of_copies);
+
+ // This function goes through all infill entities, decides which ones will be used for wiping and
+ // marks them by the extruder id. Returns volume that remains to be wiped on the wipe tower:
+ float mark_wiping_extrusions(const Print& print, unsigned int old_extruder, unsigned int new_extruder, float volume_to_wipe);
+
+ void ensure_perimeters_infills_order(const Print& print);
+
+ bool is_overriddable(const ExtrusionEntityCollection& ee, const PrintConfig& print_config, const PrintObject& object, const PrintRegion& region) const;
+
+ void set_layer_tools_ptr(const LayerTools* lt) { m_layer_tools = lt; }
+
+private:
+ int first_nonsoluble_extruder_on_layer(const PrintConfig& print_config) const;
+ int last_nonsoluble_extruder_on_layer(const PrintConfig& print_config) const;
+
+ // This function is called from mark_wiping_extrusions and sets extruder that it should be printed with (-1 .. as usual)
+ void set_extruder_override(const ExtrusionEntity* entity, unsigned int copy_id, int extruder, unsigned int num_of_copies);
+
+ // Returns true in case that entity is not printed with its usual extruder for a given copy:
+ bool is_entity_overridden(const ExtrusionEntity* entity, int copy_id) const {
+ return (entity_map.find(entity) == entity_map.end() ? false : entity_map.at(entity).at(copy_id) != -1);
+ }
+
+ std::map<const ExtrusionEntity*, std::vector<int>> entity_map; // to keep track of who prints what
+ bool something_overridden = false;
+ const LayerTools* m_layer_tools; // so we know which LayerTools object this belongs to
+};
+
+
+
+class LayerTools
{
public:
- struct LayerTools
- {
- LayerTools(const coordf_t z) :
- print_z(z),
- has_object(false),
- has_support(false),
- has_wipe_tower(false),
- wipe_tower_partitions(0),
- wipe_tower_layer_height(0.) {}
-
- bool operator< (const LayerTools &rhs) const { return print_z < rhs.print_z; }
- bool operator==(const LayerTools &rhs) const { return print_z == rhs.print_z; }
-
- coordf_t print_z;
- bool has_object;
- bool has_support;
- // Zero based extruder IDs, ordered to minimize tool switches.
- std::vector<unsigned int> extruders;
- // Will there be anything extruded on this layer for the wipe tower?
- // Due to the support layers possibly interleaving the object layers,
- // wipe tower will be disabled for some support only layers.
- bool has_wipe_tower;
- // Number of wipe tower partitions to support the required number of tool switches
- // and to support the wipe tower partitions above this one.
- size_t wipe_tower_partitions;
- coordf_t wipe_tower_layer_height;
- };
+ LayerTools(const coordf_t z, const PrintConfig* print_config_ptr = nullptr) :
+ print_z(z),
+ has_object(false),
+ has_support(false),
+ has_wipe_tower(false),
+ wipe_tower_partitions(0),
+ wipe_tower_layer_height(0.) {}
+
+ // Changing these operators to epsilon version can make a problem in cases where support and object layers get close to each other.
+ // In case someone tries to do it, make sure you know what you're doing and test it properly (slice multiple objects at once with supports).
+ bool operator< (const LayerTools &rhs) const { return print_z < rhs.print_z; }
+ bool operator==(const LayerTools &rhs) const { return print_z == rhs.print_z; }
+
+ bool is_extruder_order(unsigned int a, unsigned int b) const;
+
+ coordf_t print_z;
+ bool has_object;
+ bool has_support;
+ // Zero based extruder IDs, ordered to minimize tool switches.
+ std::vector<unsigned int> extruders;
+ // Will there be anything extruded on this layer for the wipe tower?
+ // Due to the support layers possibly interleaving the object layers,
+ // wipe tower will be disabled for some support only layers.
+ bool has_wipe_tower;
+ // Number of wipe tower partitions to support the required number of tool switches
+ // and to support the wipe tower partitions above this one.
+ size_t wipe_tower_partitions;
+ coordf_t wipe_tower_layer_height;
+
+ WipingExtrusions& wiping_extrusions() {
+ m_wiping_extrusions.set_layer_tools_ptr(this);
+ return m_wiping_extrusions;
+ }
+
+private:
+ // This object holds list of extrusion that will be used for extruder wiping
+ WipingExtrusions m_wiping_extrusions;
+};
+
+
+class ToolOrdering
+{
+public:
ToolOrdering() {}
// For the use case when each object is printed separately
@@ -72,7 +133,7 @@ public:
std::vector<LayerTools>::const_iterator begin() const { return m_layer_tools.begin(); }
std::vector<LayerTools>::const_iterator end() const { return m_layer_tools.end(); }
bool empty() const { return m_layer_tools.empty(); }
- const std::vector<LayerTools>& layer_tools() const { return m_layer_tools; }
+ std::vector<LayerTools>& layer_tools() { return m_layer_tools; }
bool has_wipe_tower() const { return ! m_layer_tools.empty() && m_first_printing_extruder != (unsigned int)-1 && m_layer_tools.front().wipe_tower_partitions > 0; }
private:
@@ -80,17 +141,22 @@ private:
void collect_extruders(const PrintObject &object);
void reorder_extruders(unsigned int last_extruder_id);
void fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z);
- void collect_extruder_statistics(bool prime_multi_material);
-
- std::vector<LayerTools> m_layer_tools;
- // First printing extruder, including the multi-material priming sequence.
- unsigned int m_first_printing_extruder = (unsigned int)-1;
- // Final printing extruder.
- unsigned int m_last_printing_extruder = (unsigned int)-1;
- // All extruders, which extrude some material over m_layer_tools.
- std::vector<unsigned int> m_all_printing_extruders;
+ void collect_extruder_statistics(bool prime_multi_material);
+
+ std::vector<LayerTools> m_layer_tools;
+ // First printing extruder, including the multi-material priming sequence.
+ unsigned int m_first_printing_extruder = (unsigned int)-1;
+ // Final printing extruder.
+ unsigned int m_last_printing_extruder = (unsigned int)-1;
+ // All extruders, which extrude some material over m_layer_tools.
+ std::vector<unsigned int> m_all_printing_extruders;
+
+
+ const PrintConfig* m_print_config_ptr = nullptr;
};
+
+
} // namespace SLic3r
#endif /* slic3r_ToolOrdering_hpp_ */
diff --git a/xs/src/libslic3r/GCode/WipeTower.hpp b/xs/src/libslic3r/GCode/WipeTower.hpp
index 2c92e16e6..c35a0feb3 100644
--- a/xs/src/libslic3r/GCode/WipeTower.hpp
+++ b/xs/src/libslic3r/GCode/WipeTower.hpp
@@ -17,12 +17,37 @@ public:
struct xy
{
xy(float x = 0.f, float y = 0.f) : x(x), y(y) {}
+ xy(const xy& pos,float xp,float yp) : x(pos.x+xp), y(pos.y+yp) {}
xy operator+(const xy &rhs) const { xy out(*this); out.x += rhs.x; out.y += rhs.y; return out; }
xy operator-(const xy &rhs) const { xy out(*this); out.x -= rhs.x; out.y -= rhs.y; return out; }
xy& operator+=(const xy &rhs) { x += rhs.x; y += rhs.y; return *this; }
xy& operator-=(const xy &rhs) { x -= rhs.x; y -= rhs.y; return *this; }
bool operator==(const xy &rhs) const { return x == rhs.x && y == rhs.y; }
bool operator!=(const xy &rhs) const { return x != rhs.x || y != rhs.y; }
+
+ // Rotate the point around center of the wipe tower about given angle (in degrees)
+ xy rotate(float width, float depth, float angle) const {
+ xy out(0,0);
+ float temp_x = x - width / 2.f;
+ float temp_y = y - depth / 2.f;
+ angle *= float(M_PI/180.);
+ out.x += temp_x * cos(angle) - temp_y * sin(angle) + width / 2.f;
+ out.y += temp_x * sin(angle) + temp_y * cos(angle) + depth / 2.f;
+ return out;
+ }
+
+ // Rotate the point around origin about given angle in degrees
+ void rotate(float angle) {
+ float temp_x = x * cos(angle) - y * sin(angle);
+ y = x * sin(angle) + y * cos(angle);
+ x = temp_x;
+ }
+
+ void translate(const xy& vect) {
+ x += vect.x;
+ y += vect.y;
+ }
+
float x;
float y;
};
@@ -90,6 +115,9 @@ public:
// This is useful not only for the print time estimation, but also for the control of layer cooling.
float elapsed_time;
+ // Is this a priming extrusion? (If so, the wipe tower rotation & translation will not be applied later)
+ bool priming;
+
// Sum the total length of the extrusion.
float total_extrusion_length_in_plane() {
float e_length = 0.f;
@@ -112,17 +140,15 @@ public:
const std::vector<unsigned int> &tools,
// If true, the last priming are will be the same as the other priming areas, and the rest of the wipe will be performed inside the wipe tower.
// If false, the last priming are will be large enough to wipe the last extruder sufficiently.
- bool last_wipe_inside_wipe_tower,
- // May be used by a stand alone post processor.
- Purpose purpose = PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) = 0;
+ bool last_wipe_inside_wipe_tower) = 0;
// Returns gcode for toolchange and the end position.
// if new_tool == -1, just unload the current filament over the wipe tower.
- virtual ToolChangeResult tool_change(unsigned int new_tool, bool last_in_layer, Purpose purpose = PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) = 0;
+ virtual ToolChangeResult tool_change(unsigned int new_tool, bool last_in_layer) = 0;
// Close the current wipe tower layer with a perimeter and possibly fill the unfilled space with a zig-zag.
// Call this method only if layer_finished() is false.
- virtual ToolChangeResult finish_layer(Purpose purpose = PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) = 0;
+ virtual ToolChangeResult finish_layer() = 0;
// Is the current layer finished? A layer is finished if either the wipe tower is finished, or
// the wipe tower has been completely covered by the tool change extrusions,
diff --git a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
index 069f975dd..2c96cce7b 100644
--- a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
+++ b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.cpp
@@ -1,10 +1,25 @@
+/*
+
+TODO LIST
+---------
+
+1. cooling moves - DONE
+2. account for perimeter and finish_layer extrusions and subtract it from last wipe - DONE
+3. priming extrusions (last wipe must clear the color) - DONE
+4. Peter's wipe tower - layer's are not exactly square
+5. Peter's wipe tower - variable width for higher levels
+6. Peter's wipe tower - make sure it is not too sparse (apply max_bridge_distance and make last wipe longer)
+7. Peter's wipe tower - enable enhanced first layer adhesion
+
+*/
+
#include "WipeTowerPrusaMM.hpp"
#include <assert.h>
#include <math.h>
-#include <fstream>
#include <iostream>
#include <vector>
+#include <numeric>
#include "Analyzer.hpp"
@@ -16,6 +31,7 @@
#define strcasecmp _stricmp
#endif
+
namespace Slic3r
{
@@ -24,17 +40,38 @@ namespace PrusaMultiMaterial {
class Writer
{
public:
- Writer() :
+ Writer(float layer_height, float line_width) :
m_current_pos(std::numeric_limits<float>::max(), std::numeric_limits<float>::max()),
m_current_z(0.f),
m_current_feedrate(0.f),
+ m_layer_height(layer_height),
m_extrusion_flow(0.f),
- m_layer_height(0.f),
m_preview_suppressed(false),
- m_elapsed_time(0.f) {}
-
- Writer& set_initial_position(const WipeTower::xy &pos) {
- m_start_pos = pos;
+ m_elapsed_time(0.f),
+ m_default_analyzer_line_width(line_width)
+ {
+ // adds tag for analyzer:
+ char buf[64];
+ sprintf(buf, ";%s%f\n", GCodeAnalyzer::Height_Tag.c_str(), m_layer_height); // don't rely on GCodeAnalyzer knowing the layer height - it knows nothing at priming
+ m_gcode += buf;
+ sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower);
+ m_gcode += buf;
+ change_analyzer_line_width(line_width);
+ }
+
+ Writer& change_analyzer_line_width(float line_width) {
+ // adds tag for analyzer:
+ char buf[64];
+ sprintf(buf, ";%s%f\n", GCodeAnalyzer::Width_Tag.c_str(), line_width);
+ m_gcode += buf;
+ return *this;
+ }
+
+ Writer& set_initial_position(const WipeTower::xy &pos, float width = 0.f, float depth = 0.f, float internal_angle = 0.f) {
+ m_wipe_tower_width = width;
+ m_wipe_tower_depth = depth;
+ m_internal_angle = internal_angle;
+ m_start_pos = WipeTower::xy(pos,0.f,m_y_shift).rotate(m_wipe_tower_width, m_wipe_tower_depth, m_internal_angle);
m_current_pos = pos;
return *this;
}
@@ -44,17 +81,20 @@ public:
Writer& set_z(float z)
{ m_current_z = z; return *this; }
- Writer& set_layer_height(float layer_height)
- { m_layer_height = layer_height; return *this; }
-
Writer& set_extrusion_flow(float flow)
{ m_extrusion_flow = flow; return *this; }
+ Writer& set_y_shift(float shift) {
+ m_current_pos.y -= shift-m_y_shift;
+ m_y_shift = shift;
+ return (*this);
+ }
+
// Suppress / resume G-code preview in Slic3r. Slic3r will have difficulty to differentiate the various
// filament loading and cooling moves from normal extrusion moves. Therefore the writer
// is asked to suppres output of some lines, which look like extrusions.
- Writer& suppress_preview() { m_preview_suppressed = true; return *this; }
- Writer& resume_preview() { m_preview_suppressed = false; return *this; }
+ Writer& suppress_preview() { change_analyzer_line_width(0.f); m_preview_suppressed = true; return *this; }
+ Writer& resume_preview() { change_analyzer_line_width(m_default_analyzer_line_width); m_preview_suppressed = false; return *this; }
Writer& feedrate(float f)
{
@@ -67,8 +107,9 @@ public:
const std::vector<WipeTower::Extrusion>& extrusions() const { return m_extrusions; }
float x() const { return m_current_pos.x; }
float y() const { return m_current_pos.y; }
- const WipeTower::xy& start_pos() const { return m_start_pos; }
const WipeTower::xy& pos() const { return m_current_pos; }
+ const WipeTower::xy start_pos_rotated() const { return m_start_pos; }
+ const WipeTower::xy pos_rotated() const { return WipeTower::xy(m_current_pos, 0.f, m_y_shift).rotate(m_wipe_tower_width, m_wipe_tower_depth, m_internal_angle); }
float elapsed_time() const { return m_elapsed_time; }
// Extrude with an explicitely provided amount of extrusion.
@@ -81,22 +122,30 @@ public:
float dx = x - m_current_pos.x;
float dy = y - m_current_pos.y;
double len = sqrt(dx*dx+dy*dy);
+
+
+ // Now do the "internal rotation" with respect to the wipe tower center
+ WipeTower::xy rotated_current_pos(WipeTower::xy(m_current_pos,0.f,m_y_shift).rotate(m_wipe_tower_width, m_wipe_tower_depth, m_internal_angle)); // this is where we are
+ WipeTower::xy rot(WipeTower::xy(x,y+m_y_shift).rotate(m_wipe_tower_width, m_wipe_tower_depth, m_internal_angle)); // this is where we want to go
+
if (! m_preview_suppressed && e > 0.f && len > 0.) {
// Width of a squished extrusion, corrected for the roundings of the squished extrusions.
// This is left zero if it is a travel move.
- float width = float(double(e) * m_filament_area / (len * m_layer_height));
+ float width = float(double(e) * /*Filament_Area*/2.40528 / (len * m_layer_height));
// Correct for the roundings of a squished extrusion.
- width += float(m_layer_height * (1. - M_PI / 4.));
- if (m_extrusions.empty() || m_extrusions.back().pos != m_current_pos)
- m_extrusions.emplace_back(WipeTower::Extrusion(m_current_pos, 0, m_current_tool));
- m_extrusions.emplace_back(WipeTower::Extrusion(WipeTower::xy(x, y), width, m_current_tool));
+ width += m_layer_height * float(1. - M_PI / 4.);
+ if (m_extrusions.empty() || m_extrusions.back().pos != rotated_current_pos)
+ m_extrusions.emplace_back(WipeTower::Extrusion(rotated_current_pos, 0, m_current_tool));
+ m_extrusions.emplace_back(WipeTower::Extrusion(WipeTower::xy(rot.x, rot.y), width, m_current_tool));
}
m_gcode += "G1";
- if (x != m_current_pos.x)
- m_gcode += set_format_X(x);
- if (y != m_current_pos.y)
- m_gcode += set_format_Y(y);
+ if (std::abs(rot.x - rotated_current_pos.x) > EPSILON)
+ m_gcode += set_format_X(rot.x);
+
+ if (std::abs(rot.y - rotated_current_pos.y) > EPSILON)
+ m_gcode += set_format_Y(rot.y);
+
if (e != 0.f)
m_gcode += set_format_E(e);
@@ -104,6 +153,9 @@ public:
if (f != 0.f && f != m_current_feedrate)
m_gcode += set_format_F(f);
+ m_current_pos.x = x;
+ m_current_pos.y = y;
+
// Update the elapsed time with a rough estimate.
m_elapsed_time += ((len == 0) ? std::abs(e) : len) / m_current_feedrate * 60.f;
m_gcode += "\n";
@@ -130,6 +182,31 @@ public:
Writer& extrude(const WipeTower::xy &dest, const float f = 0.f)
{ return extrude(dest.x, dest.y, f); }
+
+ Writer& rectangle(const WipeTower::xy& ld,float width,float height,const float f = 0.f)
+ {
+ WipeTower::xy corners[4];
+ corners[0] = ld;
+ corners[1] = WipeTower::xy(ld,width,0.f);
+ corners[2] = WipeTower::xy(ld,width,height);
+ corners[3] = WipeTower::xy(ld,0.f,height);
+ int index_of_closest = 0;
+ if (x()-ld.x > ld.x+width-x()) // closer to the right
+ index_of_closest = 1;
+ if (y()-ld.y > ld.y+height-y()) // closer to the top
+ index_of_closest = (index_of_closest==0 ? 3 : 2);
+
+ travel(corners[index_of_closest].x, y()); // travel to the closest corner
+ travel(x(),corners[index_of_closest].y);
+
+ int i = index_of_closest;
+ do {
+ ++i;
+ if (i==4) i=0;
+ extrude(corners[i], f);
+ } while (i != index_of_closest);
+ return (*this);
+ }
Writer& load(float e, float f = 0.f)
{
@@ -143,7 +220,7 @@ public:
m_gcode += "\n";
return *this;
}
-
+
// Derectract while moving in the X direction.
// If |x| > 0, the feed rate relates to the x distance,
// otherwise the feed rate relates to the e distance.
@@ -153,6 +230,17 @@ public:
Writer& retract(float e, float f = 0.f)
{ return load(-e, f); }
+// Loads filament while also moving towards given points in x-axis (x feedrate is limited by cutting the distance short if necessary)
+ Writer& load_move_x_advanced(float farthest_x, float loading_dist, float loading_speed, float max_x_speed = 50.f)
+ {
+ float time = std::abs(loading_dist / loading_speed);
+ float x_speed = std::min(max_x_speed, std::abs(farthest_x - x()) / time);
+ float feedrate = 60.f * std::hypot(x_speed, loading_speed);
+
+ float end_point = x() + (farthest_x > x() ? 1.f : -1.f) * x_speed * time;
+ return extrude_explicit(end_point, y(), loading_dist, feedrate);
+ }
+
// Elevate the extruder head above the current print_z position.
Writer& z_hop(float hop, float f = 0.f)
{
@@ -198,8 +286,19 @@ public:
// Set extruder temperature, don't wait by default.
Writer& set_extruder_temp(int temperature, bool wait = false)
{
+ char buf[128];
+ sprintf(buf, "M%d S%d\n", wait ? 109 : 104, temperature);
+ m_gcode += buf;
+ return *this;
+ };
+
+ // Wait for a period of time (seconds).
+ Writer& wait(float time)
+ {
+ if (time==0)
+ return *this;
char buf[128];
- sprintf(buf, "M%d S%d\n", wait ? 109 : 104, temperature);
+ sprintf(buf, "G4 S%.3f\n", time);
m_gcode += buf;
return *this;
};
@@ -243,6 +342,25 @@ public:
return *this;
};
+
+ Writer& set_fan(unsigned int speed)
+ {
+ if (speed == m_last_fan_speed)
+ return *this;
+
+ if (speed == 0)
+ m_gcode += "M107\n";
+ else
+ {
+ m_gcode += "M106 S";
+ char buf[128];
+ sprintf(buf,"%u\n",(unsigned int)(255.0 * speed / 100.0));
+ m_gcode += buf;
+ }
+ m_last_fan_speed = speed;
+ return *this;
+ }
+
Writer& comment_material(WipeTowerPrusaMM::material_type material)
{
m_gcode += "; material : ";
@@ -279,9 +397,16 @@ private:
std::string m_gcode;
std::vector<WipeTower::Extrusion> m_extrusions;
float m_elapsed_time;
- const double m_filament_area = 0.25*M_PI*1.75*1.75;
-
- std::string set_format_X(float x) {
+ float m_internal_angle = 0.f;
+ float m_y_shift = 0.f;
+ float m_wipe_tower_width = 0.f;
+ float m_wipe_tower_depth = 0.f;
+ float m_last_fan_speed = 0.f;
+ int current_temp = -1;
+ const float m_default_analyzer_line_width;
+
+ std::string set_format_X(float x)
+ {
char buf[64];
sprintf(buf, " X%.3f", x);
m_current_pos.x = x;
@@ -315,32 +440,11 @@ private:
}
Writer& operator=(const Writer &rhs);
-};
-
-/*
-class Material
-{
-public:
- std::string name;
- std::string type;
-
- struct RammingStep {
-// float length;
- float extrusion_multiplier; // sirka linky
- float extrusion;
- float speed;
- };
- std::vector<RammingStep> ramming_sequence;
+}; // class Writer
- // Number and speed of the cooling moves.
- std::vector<float> cooling_moves;
+}; // namespace PrusaMultiMaterial
- // Percentage of the speed overide, in pairs of <z, percentage>
- std::vector<std::pair<float, int>> speed_override;
-};
-*/
-} // namespace PrusaMultiMaterial
WipeTowerPrusaMM::material_type WipeTowerPrusaMM::parse_material(const char *name)
{
@@ -365,6 +469,7 @@ WipeTowerPrusaMM::material_type WipeTowerPrusaMM::parse_material(const char *nam
return INVALID;
}
+
// Returns gcode to prime the nozzles at the front edge of the print bed.
WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
// print_z of the first layer.
@@ -373,90 +478,52 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
const std::vector<unsigned int> &tools,
// If true, the last priming are will be the same as the other priming areas, and the rest of the wipe will be performed inside the wipe tower.
// If false, the last priming are will be large enough to wipe the last extruder sufficiently.
- bool last_wipe_inside_wipe_tower,
- // May be used by a stand alone post processor.
- Purpose purpose)
+ bool last_wipe_inside_wipe_tower)
{
this->set_layer(first_layer_height, first_layer_height, tools.size(), true, false);
-
- float wipe_area = m_wipe_area;
- // Calculate the amount of wipe over the wipe tower brim following the prime, decrease wipe_area
- // with the amount of material extruded over the brim.
- {
- // Simulate the brim extrusions, summ the length of the extrusion.
- float e_length = this->tool_change(0, false, PURPOSE_EXTRUDE).total_extrusion_length_in_plane();
- // Shrink wipe_area by the amount of extrusion extruded by the finish_layer().
- // Y stepping of the wipe extrusions.
- float dy = m_perimeter_width * 0.8f;
- // Number of whole wipe lines, that would be extruded to wipe as much material as the finish_layer().
- // Minimum wipe area is 5mm wide.
- //FIXME calculate the purge_lines_width precisely.
- float purge_lines_width = 1.3f;
- wipe_area = std::max(5.f, m_wipe_area - float(floor(e_length / m_wipe_tower_width)) * dy - purge_lines_width);
- }
-
- this->set_layer(first_layer_height, first_layer_height, tools.size(), true, false);
- m_num_layer_changes = 0;
- m_current_tool = tools.front();
-
+ this->m_current_tool = tools.front();
+
// The Prusa i3 MK2 has a working space of [0, -2.2] to [250, 210].
// Due to the XYZ calibration, this working space may shrink slightly from all directions,
// therefore the homing position is shifted inside the bed by 0.2 in the firmware to [0.2, -2.0].
// box_coordinates cleaning_box(xy(0.5f, - 1.5f), m_wipe_tower_width, wipe_area);
- box_coordinates cleaning_box(xy(5.f, 0.f), m_wipe_tower_width, wipe_area);
- PrusaMultiMaterial::Writer writer;
+ const float prime_section_width = std::min(240.f / tools.size(), 60.f);
+ box_coordinates cleaning_box(xy(5.f, 0.01f + m_perimeter_width/2.f), prime_section_width, 100.f);
+
+ PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width);
writer.set_extrusion_flow(m_extrusion_flow)
.set_z(m_z_pos)
- .set_layer_height(m_layer_height)
.set_initial_tool(m_current_tool)
.append(";--------------------\n"
"; CP PRIMING START\n")
.append(";--------------------\n")
.speed_override(100);
- // Always move to the starting position.
- writer.set_initial_position(xy(0.f, 0.f))
- .travel(cleaning_box.ld, 7200)
- // Increase the extruder driver current to allow fast ramming.
- .set_extruder_trimpot(750);
-
- // adds tag for analyzer
- char buf[32];
- sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower);
- writer.append(buf);
-
- if (purpose == PURPOSE_EXTRUDE || purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) {
- float y_end = 0.f;
- for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
- unsigned int tool = tools[idx_tool];
- // Select the tool, set a speed override for soluble and flex materials.
- toolchange_Change(writer, tool, m_material[tool]);
- // Prime the tool.
- toolchange_Load(writer, cleaning_box);
- if (idx_tool + 1 == tools.size()) {
- // Last tool should not be unloaded, but it should be wiped enough to become of a pure color.
- if (last_wipe_inside_wipe_tower) {
- // Shrink the last wipe area to the area of the other purge areas,
- // remember the last initial wipe width to be purged into the 1st layer of the wipe tower.
- m_initial_extra_wipe = std::max(0.f, wipe_area - (y_end + 0.5f * 0.85f * m_perimeter_width - cleaning_box.ld.y));
- cleaning_box.lu.y -= m_initial_extra_wipe;
- cleaning_box.ru.y -= m_initial_extra_wipe;
- }
- toolchange_Wipe(writer, cleaning_box, false);
- } else {
- // Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
- writer.travel(writer.x(), writer.y() + m_perimeter_width, 7200);
- // Change the extruder temperature to the temperature of the next filament before starting the cooling moves.
- toolchange_Unload(writer, cleaning_box, m_material[m_current_tool], m_first_layer_temperature[tools[idx_tool+1]]);
- // Save the y end of the non-last priming area.
- y_end = writer.y();
- cleaning_box.translate(m_wipe_tower_width, 0.f);
- writer.travel(cleaning_box.ld, 7200);
- }
- ++ m_num_tool_changes;
- }
- }
+ writer.set_initial_position(xy(0.f, 0.f)) // Always move to the starting position
+ .travel(cleaning_box.ld, 7200)
+ .set_extruder_trimpot(750); // Increase the extruder driver current to allow fast ramming.
+
+ for (size_t idx_tool = 0; idx_tool < tools.size(); ++ idx_tool) {
+ unsigned int tool = tools[idx_tool];
+ m_left_to_right = true;
+ toolchange_Change(writer, tool, m_filpar[tool].material); // Select the tool, set a speed override for soluble and flex materials.
+ toolchange_Load(writer, cleaning_box); // Prime the tool.
+ if (idx_tool + 1 == tools.size()) {
+ // Last tool should not be unloaded, but it should be wiped enough to become of a pure color.
+ toolchange_Wipe(writer, cleaning_box, wipe_volumes[tools[idx_tool-1]][tool]);
+ } else {
+ // Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
+ //writer.travel(writer.x(), writer.y() + m_perimeter_width, 7200);
+ toolchange_Wipe(writer, cleaning_box , 20.f);
+ box_coordinates box = cleaning_box;
+ box.translate(0.f, writer.y() - cleaning_box.ld.y + m_perimeter_width);
+ toolchange_Unload(writer, box , m_filpar[m_current_tool].material, m_filpar[tools[idx_tool + 1]].first_layer_temperature);
+ cleaning_box.translate(prime_section_width, 0.f);
+ writer.travel(cleaning_box.ld, 7200);
+ }
+ ++ m_num_tool_changes;
+ }
// Reset the extruder current to a normal value.
writer.set_extruder_trimpot(550)
@@ -467,267 +534,169 @@ WipeTower::ToolChangeResult WipeTowerPrusaMM::prime(
";------------------\n"
"\n\n");
- // Force m_idx_tool_change_in_layer to -1, so that tool_change() will know to extrude the wipe tower brim.
- m_idx_tool_change_in_layer = (unsigned int)(-1);
+ // so that tool_change() will know to extrude the wipe tower brim:
+ m_print_brim = true;
ToolChangeResult result;
- result.print_z = m_z_pos;
- result.layer_height = m_layer_height;
+ result.priming = true;
+ result.print_z = this->m_z_pos;
+ result.layer_height = this->m_layer_height;
result.gcode = writer.gcode();
result.elapsed_time = writer.elapsed_time();
result.extrusions = writer.extrusions();
- result.start_pos = writer.start_pos();
- result.end_pos = writer.pos();
+ result.start_pos = writer.start_pos_rotated();
+ result.end_pos = writer.pos_rotated();
return result;
}
-WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, bool last_in_layer, Purpose purpose)
+WipeTower::ToolChangeResult WipeTowerPrusaMM::tool_change(unsigned int tool, bool last_in_layer)
{
- // Either it is the last tool unload,
- // or there must be a nonzero wipe tower partitions available.
-// assert(tool < 0 || it_layer_tools->wipe_tower_partitions > 0);
-
- if (m_idx_tool_change_in_layer == (unsigned int)(-1)) {
- // First layer, prime the extruder.
- return toolchange_Brim(purpose);
- }
-
- float wipe_area = m_wipe_area;
- if (++ m_idx_tool_change_in_layer < (unsigned int)m_max_color_changes && last_in_layer) {
- // This tool_change() call will be followed by a finish_layer() call.
- // Try to shrink the wipe_area to save material, as less than usual wipe is required
- // if this step is foolowed by finish_layer() extrusions wiping the same extruder.
- for (size_t iter = 0; iter < 3; ++ iter) {
- // Simulate the finish_layer() extrusions, summ the length of the extrusion.
- float e_length = 0.f;
- {
- unsigned int old_idx_tool_change = m_idx_tool_change_in_layer;
- float old_wipe_start_y = m_current_wipe_start_y;
- m_current_wipe_start_y += wipe_area;
- e_length = this->finish_layer(PURPOSE_EXTRUDE).total_extrusion_length_in_plane();
- m_idx_tool_change_in_layer = old_idx_tool_change;
- m_current_wipe_start_y = old_wipe_start_y;
- }
- // Shrink wipe_area by the amount of extrusion extruded by the finish_layer().
- // Y stepping of the wipe extrusions.
- float dy = m_perimeter_width * 0.8f;
- // Number of whole wipe lines, that would be extruded to wipe as much material as the finish_layer().
- float num_lines_extruded = floor(e_length / m_wipe_tower_width);
- // Minimum wipe area is 5mm wide.
- wipe_area = m_wipe_area - num_lines_extruded * dy;
- if (wipe_area < 5.) {
- wipe_area = 5.;
+ if ( m_print_brim )
+ return toolchange_Brim();
+
+ float wipe_area = 0.f;
+ bool last_change_in_layer = false;
+ float wipe_volume = 0.f;
+
+ // Finds this toolchange info
+ if (tool != (unsigned int)(-1))
+ {
+ for (const auto &b : m_layer_info->tool_changes)
+ if ( b.new_tool == tool ) {
+ wipe_volume = b.wipe_volume;
+ if (tool == m_layer_info->tool_changes.back().new_tool)
+ last_change_in_layer = true;
+ wipe_area = b.required_depth * m_layer_info->extra_spacing;
break;
}
- }
+ }
+ else {
+ // Otherwise we are going to Unload only. And m_layer_info would be invalid.
}
box_coordinates cleaning_box(
- m_wipe_tower_pos + xy(0.f, m_current_wipe_start_y + 0.5f * m_perimeter_width),
- m_wipe_tower_width,
- wipe_area - m_perimeter_width);
+ xy(m_perimeter_width / 2.f, m_perimeter_width / 2.f),
+ m_wipe_tower_width - m_perimeter_width,
+ (tool != (unsigned int)(-1) ? /*m_layer_info->depth*/wipe_area+m_depth_traversed-0.5*m_perimeter_width
+ : m_wipe_tower_depth-m_perimeter_width));
- PrusaMultiMaterial::Writer writer;
+ PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width);
writer.set_extrusion_flow(m_extrusion_flow)
- .set_z(m_z_pos)
- .set_layer_height(m_layer_height)
- .set_initial_tool(m_current_tool)
- .append(";--------------------\n"
- "; CP TOOLCHANGE START\n")
- .comment_with_value(" toolchange #", m_num_tool_changes)
- .comment_material(m_material[m_current_tool])
- .append(";--------------------\n")
- .speed_override(100);
-
- xy initial_position = ((m_current_shape == SHAPE_NORMAL) ? cleaning_box.ld : cleaning_box.lu) +
- xy(m_perimeter_width, ((m_current_shape == SHAPE_NORMAL) ? 1.f : -1.f) * m_perimeter_width);
-
- if (purpose == PURPOSE_MOVE_TO_TOWER || purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) {
- // Scaffold leaks terribly, reduce leaking by a full retract when going to the wipe tower.
- float initial_retract = ((m_material[m_current_tool] == SCAFF) ? 1.f : 0.5f) * m_retract;
- writer // Lift for a Z hop.
- .z_hop(m_zhop, 7200)
- // Additional retract on move to tower.
- .retract(initial_retract, 3600)
- // Move to a starting position, one perimeter width inside the cleaning box.
- .travel(initial_position, 7200)
- // Unlift for a Z hop.
- .z_hop_reset(7200)
- // Additional retract on move to tower.
- .load(initial_retract, 3600)
- .load(m_retract, 1500);
- } else {
- // Already at the initial position.
- writer.set_initial_position(initial_position);
- }
-
- // adds tag for analyzer
- char buf[32];
- sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower);
- writer.append(buf);
-
- if (purpose == PURPOSE_EXTRUDE || purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) {
- // Increase the extruder driver current to allow fast ramming.
- writer.set_extruder_trimpot(750);
- // Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
-
- if (tool != (unsigned int)-1) {
- toolchange_Unload(writer, cleaning_box, m_material[m_current_tool],
- m_is_first_layer ? m_first_layer_temperature[tool] : m_temperature[tool]);
- // This is not the last change.
- // Change the tool, set a speed override for soluble and flex materials.
- toolchange_Change(writer, tool, m_material[tool]);
- toolchange_Load(writer, cleaning_box);
- // Wipe the newly loaded filament until the end of the assigned wipe area.
- toolchange_Wipe(writer, cleaning_box, false);
- // Draw a perimeter around cleaning_box and wipe.
- box_coordinates box = cleaning_box;
- if (m_current_shape == SHAPE_REVERSED) {
- std::swap(box.lu, box.ld);
- std::swap(box.ru, box.rd);
- }
- // Draw a perimeter around cleaning_box.
- writer.travel(box.lu, 7000)
- .extrude(box.ld, 3200).extrude(box.rd)
- .extrude(box.ru).extrude(box.lu);
- // Wipe the nozzle.
- //if (purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE)
- // Always wipe the nozzle with a long wipe to reduce stringing when moving away from the wipe tower.
- writer.travel(box.ru, 7200)
- .travel(box.lu);
- } else
- toolchange_Unload(writer, cleaning_box, m_material[m_current_tool], m_temperature[m_current_tool]);
-
- // Reset the extruder current to a normal value.
- writer.set_extruder_trimpot(550)
- .feedrate(6000)
- .flush_planner_queue()
- .reset_extruder()
- .append("; CP TOOLCHANGE END\n"
- ";------------------\n"
- "\n\n");
-
- ++ m_num_tool_changes;
- m_current_wipe_start_y += wipe_area;
- }
+ .set_z(m_z_pos)
+ .set_initial_tool(m_current_tool)
+ .set_y_shift(m_y_shift + (tool!=(unsigned int)(-1) && (m_current_shape == SHAPE_REVERSED && !m_peters_wipe_tower) ? m_layer_info->depth - m_layer_info->toolchanges_depth(): 0.f))
+ .append(";--------------------\n"
+ "; CP TOOLCHANGE START\n")
+ .comment_with_value(" toolchange #", m_num_tool_changes + 1) // the number is zero-based
+ .comment_material(m_filpar[m_current_tool].material)
+ .append(";--------------------\n")
+ .speed_override(100);
+
+ xy initial_position = cleaning_box.ld + WipeTower::xy(0.f,m_depth_traversed);
+ writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
+
+ // Increase the extruder driver current to allow fast ramming.
+ writer.set_extruder_trimpot(750);
+
+ // Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
+ if (tool != (unsigned int)-1){ // This is not the last change.
+ toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].material,
+ m_is_first_layer ? m_filpar[tool].first_layer_temperature : m_filpar[tool].temperature);
+ toolchange_Change(writer, tool, m_filpar[tool].material); // Change the tool, set a speed override for soluble and flex materials.
+ toolchange_Load(writer, cleaning_box);
+ writer.travel(writer.x(),writer.y()-m_perimeter_width); // cooling and loading were done a bit down the road
+ toolchange_Wipe(writer, cleaning_box, wipe_volume); // Wipe the newly loaded filament until the end of the assigned wipe area.
+ } else
+ toolchange_Unload(writer, cleaning_box, m_filpar[m_current_tool].material, m_filpar[m_current_tool].temperature);
+
+ ++ m_num_tool_changes;
+ m_depth_traversed += wipe_area;
+
+ if (last_change_in_layer) {// draw perimeter line
+ writer.set_y_shift(m_y_shift);
+ if (m_peters_wipe_tower)
+ writer.rectangle(WipeTower::xy(0.f, 0.f),m_layer_info->depth + 3*m_perimeter_width,m_wipe_tower_depth);
+ else {
+ writer.rectangle(WipeTower::xy(0.f, 0.f),m_wipe_tower_width, m_layer_info->depth + m_perimeter_width);
+ if (layer_finished()) { // no finish_layer will be called, we must wipe the nozzle
+ writer.travel(writer.x()> m_wipe_tower_width / 2.f ? 0.f : m_wipe_tower_width, writer.y());
+ }
+ }
+ }
+
+ writer.set_extruder_trimpot(550) // Reset the extruder current to a normal value.
+ .feedrate(6000)
+ .flush_planner_queue()
+ .reset_extruder()
+ .append("; CP TOOLCHANGE END\n"
+ ";------------------\n"
+ "\n\n");
ToolChangeResult result;
- result.print_z = m_z_pos;
- result.layer_height = m_layer_height;
+ result.priming = false;
+ result.print_z = this->m_z_pos;
+ result.layer_height = this->m_layer_height;
result.gcode = writer.gcode();
result.elapsed_time = writer.elapsed_time();
result.extrusions = writer.extrusions();
- result.start_pos = writer.start_pos();
- result.end_pos = writer.pos();
+ result.start_pos = writer.start_pos_rotated();
+ result.end_pos = writer.pos_rotated();
return result;
}
-WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(Purpose purpose, bool sideOnly, float y_offset)
+WipeTower::ToolChangeResult WipeTowerPrusaMM::toolchange_Brim(bool sideOnly, float y_offset)
{
const box_coordinates wipeTower_box(
- m_wipe_tower_pos,
+ WipeTower::xy(0.f, 0.f),
m_wipe_tower_width,
- m_wipe_area * float(m_max_color_changes) - m_perimeter_width / 2);
+ m_wipe_tower_depth);
- PrusaMultiMaterial::Writer writer;
+ PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width);
writer.set_extrusion_flow(m_extrusion_flow * 1.1f)
- // Let the writer know the current Z position as a base for Z-hop.
- .set_z(m_z_pos)
- .set_layer_height(m_layer_height)
+ .set_z(m_z_pos) // Let the writer know the current Z position as a base for Z-hop.
.set_initial_tool(m_current_tool)
- .append(
- ";-------------------------------------\n"
- "; CP WIPE TOWER FIRST LAYER BRIM START\n");
+ .append(";-------------------------------------\n"
+ "; CP WIPE TOWER FIRST LAYER BRIM START\n");
xy initial_position = wipeTower_box.lu - xy(m_perimeter_width * 6.f, 0);
-
- if (purpose == PURPOSE_MOVE_TO_TOWER || purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE)
- // Move with Z hop.
- writer.z_hop(m_zhop, 7200)
- .travel(initial_position, 6000)
- .z_hop_reset(7200);
- else
- writer.set_initial_position(initial_position);
-
- // adds tag for analyzer
- char buf[32];
- sprintf(buf, ";%s%d\n", GCodeAnalyzer::Extrusion_Role_Tag.c_str(), erWipeTower);
- writer.append(buf);
-
- if (purpose == PURPOSE_EXTRUDE || purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) {
- // Prime the extruder 10*m_perimeter_width left along the vertical edge of the wipe tower.
- writer.extrude_explicit(wipeTower_box.ld - xy(m_perimeter_width * 6.f, 0),
- 1.5f * m_extrusion_flow * (wipeTower_box.lu.y - wipeTower_box.ld.y), 2400);
-
- // The tool is supposed to be active and primed at the time when the wipe tower brim is extruded.
- // toolchange_Change(writer, int(tool), m_material[tool]);
-
- if (sideOnly) {
- float x_offset = m_perimeter_width;
- for (size_t i = 0; i < 4; ++ i, x_offset += m_perimeter_width)
- writer.travel (wipeTower_box.ld + xy(- x_offset, y_offset), 7000)
- .extrude(wipeTower_box.lu + xy(- x_offset, - y_offset), 2100);
- writer.travel(wipeTower_box.rd + xy(x_offset, y_offset), 7000);
- x_offset = m_perimeter_width;
- for (size_t i = 0; i < 4; ++ i, x_offset += m_perimeter_width)
- writer.travel (wipeTower_box.rd + xy(x_offset, y_offset), 7000)
- .extrude(wipeTower_box.ru + xy(x_offset, - y_offset), 2100);
- } else {
- // Extrude 4 rounds of a brim around the future wipe tower.
- box_coordinates box(wipeTower_box);
- //FIXME why is the box shifted in +Y by 0.5f * m_perimeter_width?
- box.translate(0.f, 0.5f * m_perimeter_width);
- box.expand(0.5f * m_perimeter_width);
- for (size_t i = 0; i < 4; ++ i) {
- writer.travel (box.ld, 7000)
- .extrude(box.lu, 2100).extrude(box.ru)
- .extrude(box.rd ).extrude(box.ld);
- box.expand(m_perimeter_width);
- }
- }
-
- if (m_initial_extra_wipe > m_perimeter_width * 1.9f) {
- box_coordinates cleaning_box(
- m_wipe_tower_pos + xy(0.f, 0.5f * m_perimeter_width),
- m_wipe_tower_width,
- m_initial_extra_wipe - m_perimeter_width);
- writer.travel(cleaning_box.ld + xy(m_perimeter_width, 0.5f * m_perimeter_width), 6000);
- // Wipe the newly loaded filament until the end of the assigned wipe area.
- toolchange_Wipe(writer, cleaning_box, true);
- // Draw a perimeter around cleaning_box.
- writer.travel(cleaning_box.lu, 7000)
- .extrude(cleaning_box.ld, 3200).extrude(cleaning_box.rd)
- .extrude(cleaning_box.ru).extrude(cleaning_box.lu);
- m_current_wipe_start_y = m_initial_extra_wipe;
- }
-
- // Move to the front left corner.
- writer.travel(wipeTower_box.ld, 7000);
-
- //if (purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE)
- // Wipe along the front edge.
- // Always wipe the nozzle with a long wipe to reduce stringing when moving away from the wipe tower.
- writer.travel(wipeTower_box.rd)
- .travel(wipeTower_box.ld);
-
- writer.append("; CP WIPE TOWER FIRST LAYER BRIM END\n"
- ";-----------------------------------\n");
-
- // Mark the brim as extruded.
- m_idx_tool_change_in_layer = 0;
- }
+ writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
+
+ writer.extrude_explicit(wipeTower_box.ld - xy(m_perimeter_width * 6.f, 0), // Prime the extruder left of the wipe tower.
+ 1.5f * m_extrusion_flow * (wipeTower_box.lu.y - wipeTower_box.ld.y), 2400);
+
+ // The tool is supposed to be active and primed at the time when the wipe tower brim is extruded.
+ // Extrude 4 rounds of a brim around the future wipe tower.
+ box_coordinates box(wipeTower_box);
+ box.expand(m_perimeter_width);
+ for (size_t i = 0; i < 4; ++ i) {
+ writer.travel (box.ld, 7000)
+ .extrude(box.lu, 2100).extrude(box.ru)
+ .extrude(box.rd ).extrude(box.ld);
+ box.expand(m_perimeter_width);
+ }
+
+ writer.travel(wipeTower_box.ld, 7000); // Move to the front left corner.
+ writer.travel(wipeTower_box.rd) // Always wipe the nozzle with a long wipe to reduce stringing when moving away from the wipe tower.
+ .travel(wipeTower_box.ld);
+ writer.append("; CP WIPE TOWER FIRST LAYER BRIM END\n"
+ ";-----------------------------------\n");
+
+ m_print_brim = false; // Mark the brim as extruded
ToolChangeResult result;
- result.print_z = m_z_pos;
- result.layer_height = m_layer_height;
+ result.priming = false;
+ result.print_z = this->m_z_pos;
+ result.layer_height = this->m_layer_height;
result.gcode = writer.gcode();
result.elapsed_time = writer.elapsed_time();
result.extrusions = writer.extrusions();
- result.start_pos = writer.start_pos();
- result.end_pos = writer.pos();
+ result.start_pos = writer.start_pos_rotated();
+ result.end_pos = writer.pos_rotated();
return result;
}
+
+
// Ram the hot material out of the melt zone, retract the filament into the cooling tubes and let it cool.
void WipeTowerPrusaMM::toolchange_Unload(
PrusaMultiMaterial::Writer &writer,
@@ -735,87 +704,146 @@ void WipeTowerPrusaMM::toolchange_Unload(
const material_type current_material,
const int new_temperature)
{
- float xl = cleaning_box.ld.x + 0.5f * m_perimeter_width;
- float xr = cleaning_box.rd.x - 0.5f * m_perimeter_width;
- float y_step = ((m_current_shape == SHAPE_NORMAL) ? 1.f : -1.f) * m_perimeter_width;
-
- writer.append("; CP TOOLCHANGE UNLOAD\n");
-
- // Ram the hot material out of the extruder melt zone.
- // Current extruder position is on the left, one perimeter inside the cleaning box in both X and Y.
- float e0 = m_perimeter_width * m_extrusion_flow;
- float e = (xr - xl) * m_extrusion_flow;
- switch (current_material)
- {
- case ABS:
- // ramming start end y increment amount feedrate
- writer.ram(xl + m_perimeter_width * 2, xr - m_perimeter_width, y_step * 0.2f, 0, 1.2f * e, 4000)
- .ram(xr - m_perimeter_width, xl + m_perimeter_width, y_step * 1.2f, e0, 1.6f * e, 4600)
- .ram(xl + m_perimeter_width * 2, xr - m_perimeter_width * 2, y_step * 1.2f, e0, 1.8f * e, 5000)
- .ram(xr - m_perimeter_width * 2, xl + m_perimeter_width * 2, y_step * 1.2f, e0, 1.8f * e, 5000);
- break;
- case PVA:
- // Used for the PrimaSelect PVA
- writer.ram(xl + m_perimeter_width * 2, xr - m_perimeter_width, y_step * 0.2f, 0, 1.75f * e, 4000)
- .ram(xr - m_perimeter_width, xl + m_perimeter_width, y_step * 1.5f, 0, 1.75f * e, 4500)
- .ram(xl + m_perimeter_width * 2, xr - m_perimeter_width * 2, y_step * 1.5f, 0, 1.75f * e, 4800)
- .ram(xr - m_perimeter_width, xl + m_perimeter_width, y_step * 1.5f, 0, 1.75f * e, 5000);
- break;
- case SCAFF:
- writer.ram(xl + m_perimeter_width * 2, xr - m_perimeter_width, y_step * 2.f, 0, 1.75f * e, 4000)
- .ram(xr - m_perimeter_width, xl + m_perimeter_width, y_step * 3.f, 0, 2.34f * e, 4600)
- .ram(xl + m_perimeter_width * 2, xr - m_perimeter_width * 2, y_step * 3.f, 0, 2.63f * e, 5200);
- break;
- default:
- // PLA, PLA/PHA and others
- // Used for the Verbatim BVOH, PET, NGEN, co-polyesters
- writer.ram(xl + m_perimeter_width * 2, xr - m_perimeter_width, y_step * 0.2f, 0, 1.60f * e, 4000)
- .ram(xr - m_perimeter_width, xl + m_perimeter_width, y_step * 1.2f, e0, 1.65f * e, 4600)
- .ram(xl + m_perimeter_width * 2, xr - m_perimeter_width * 2, y_step * 1.2f, e0, 1.74f * e, 5200);
+ float xl = cleaning_box.ld.x + 1.f * m_perimeter_width;
+ float xr = cleaning_box.rd.x - 1.f * m_perimeter_width;
+
+ const float line_width = m_perimeter_width * m_filpar[m_current_tool].ramming_line_width_multiplicator; // desired ramming line thickness
+ const float y_step = line_width * m_filpar[m_current_tool].ramming_step_multiplicator * m_extra_spacing; // spacing between lines in mm
+
+ writer.append("; CP TOOLCHANGE UNLOAD\n")
+ .change_analyzer_line_width(line_width);
+
+ unsigned i = 0; // iterates through ramming_speed
+ m_left_to_right = true; // current direction of ramming
+ float remaining = xr - xl ; // keeps track of distance to the next turnaround
+ float e_done = 0; // measures E move done from each segment
+
+ writer.travel(xl, cleaning_box.ld.y + m_depth_traversed + y_step/2.f ); // move to starting position
+
+ // if the ending point of the ram would end up in mid air, align it with the end of the wipe tower:
+ if (m_layer_info > m_plan.begin() && m_layer_info < m_plan.end() && (m_layer_info-1!=m_plan.begin() || !m_adhesion )) {
+
+ // this is y of the center of previous sparse infill border
+ float sparse_beginning_y = 0.f;
+ if (m_current_shape == SHAPE_REVERSED)
+ sparse_beginning_y += ((m_layer_info-1)->depth - (m_layer_info-1)->toolchanges_depth())
+ - ((m_layer_info)->depth-(m_layer_info)->toolchanges_depth()) ;
+ else
+ sparse_beginning_y += (m_layer_info-1)->toolchanges_depth() + m_perimeter_width;
+
+ //debugging:
+ /* float oldx = writer.x();
+ float oldy = writer.y();
+ writer.travel(xr,sparse_beginning_y);
+ writer.extrude(xr+5,writer.y());
+ writer.travel(oldx,oldy);*/
+
+ float sum_of_depths = 0.f;
+ for (const auto& tch : m_layer_info->tool_changes) { // let's find this toolchange
+ if (tch.old_tool == m_current_tool) {
+ sum_of_depths += tch.ramming_depth;
+ float ramming_end_y = sum_of_depths;
+ ramming_end_y -= (y_step/m_extra_spacing-m_perimeter_width) / 2.f; // center of final ramming line
+
+ // debugging:
+ /*float oldx = writer.x();
+ float oldy = writer.y();
+ writer.travel(xl,ramming_end_y);
+ writer.extrude(xl-15,writer.y());
+ writer.travel(oldx,oldy);*/
+
+ if ( (m_current_shape == SHAPE_REVERSED && ramming_end_y < sparse_beginning_y - 0.5f*m_perimeter_width ) ||
+ (m_current_shape == SHAPE_NORMAL && ramming_end_y > sparse_beginning_y + 0.5f*m_perimeter_width ) )
+ {
+ writer.extrude(xl + tch.first_wipe_line-1.f*m_perimeter_width,writer.y());
+ remaining -= tch.first_wipe_line-1.f*m_perimeter_width;
+ }
+ break;
+ }
+ sum_of_depths += tch.required_depth;
+ }
+ }
+
+ // now the ramming itself:
+ while (i < m_filpar[m_current_tool].ramming_speed.size())
+ {
+ const float x = volume_to_length(m_filpar[m_current_tool].ramming_speed[i] * 0.25f, line_width, m_layer_height);
+ const float e = m_filpar[m_current_tool].ramming_speed[i] * 0.25f / Filament_Area; // transform volume per sec to E move;
+ const float dist = std::min(x - e_done, remaining); // distance to travel for either the next 0.25s, or to the next turnaround
+ const float actual_time = dist/x * 0.25;
+ writer.ram(writer.x(), writer.x() + (m_left_to_right ? 1.f : -1.f) * dist, 0, 0, e * (dist / x), std::hypot(dist, e * (dist / x)) / (actual_time / 60.));
+ remaining -= dist;
+
+ if (remaining < WT_EPSILON) { // we reached a turning point
+ writer.travel(writer.x(), writer.y() + y_step, 7200);
+ m_left_to_right = !m_left_to_right;
+ remaining = xr - xl;
+ }
+ e_done += dist; // subtract what was actually done
+ if (e_done > x - WT_EPSILON) { // current segment finished
+ ++i;
+ e_done = 0;
+ }
}
-
- // Pull the filament end into a cooling tube.
- writer.retract(15, 5000).retract(50, 5400).retract(15, 3000).retract(12, 2000);
-
- if (new_temperature != 0)
- // Set the extruder temperature, but don't wait.
+ WipeTower::xy end_of_ramming(writer.x(),writer.y());
+ writer.change_analyzer_line_width(m_perimeter_width); // so the next lines are not affected by ramming_line_width_multiplier
+
+ // Retraction:
+ float old_x = writer.x();
+ float turning_point = (!m_left_to_right ? xl : xr );
+ float total_retraction_distance = m_cooling_tube_retraction + m_cooling_tube_length/2.f - 15.f; // the 15mm is reserved for the first part after ramming
+ writer.suppress_preview()
+ .retract(15.f, m_filpar[m_current_tool].unloading_speed_start * 60.f) // feedrate 5000mm/min = 83mm/s
+ .retract(0.70f * total_retraction_distance, 1.0f * m_filpar[m_current_tool].unloading_speed * 60.f)
+ .retract(0.20f * total_retraction_distance, 0.5f * m_filpar[m_current_tool].unloading_speed * 60.f)
+ .retract(0.10f * total_retraction_distance, 0.3f * m_filpar[m_current_tool].unloading_speed * 60.f)
+
+ /*.load_move_x_advanced(turning_point, -15.f, 83.f, 50.f) // this is done at fixed speed
+ .load_move_x_advanced(old_x, -0.70f * total_retraction_distance, 1.0f * m_filpar[m_current_tool].unloading_speed)
+ .load_move_x_advanced(turning_point, -0.20f * total_retraction_distance, 0.5f * m_filpar[m_current_tool].unloading_speed)
+ .load_move_x_advanced(old_x, -0.10f * total_retraction_distance, 0.3f * m_filpar[m_current_tool].unloading_speed)
+ .travel(old_x, writer.y()) // in case previous move was shortened to limit feedrate*/
+ .resume_preview();
+
+ if (new_temperature != 0 && new_temperature != m_old_temperature ) { // Set the extruder temperature, but don't wait.
writer.set_extruder_temp(new_temperature, false);
-
- // In case the current print head position is closer to the left edge, reverse the direction.
- if (std::abs(writer.x() - xl) < std::abs(writer.x() - xr))
- std::swap(xl, xr);
- // Horizontal cooling moves will be performed at the following Y coordinate:
- writer.travel(xr, writer.y() + y_step * 0.8f, 7200)
- .suppress_preview();
- switch (current_material)
- {
- case PVA:
- writer.cool(xl, xr, 3, -5, 1600)
- .cool(xl, xr, 5, -5, 2000)
- .cool(xl, xr, 5, -5, 2200)
- .cool(xl, xr, 5, -5, 2400)
- .cool(xl, xr, 5, -5, 2400)
- .cool(xl, xr, 5, -3, 2400);
- break;
- case SCAFF:
- writer.cool(xl, xr, 3, -5, 1600)
- .cool(xl, xr, 5, -5, 2000)
- .cool(xl, xr, 5, -5, 2200)
- .cool(xl, xr, 5, -5, 2200)
- .cool(xl, xr, 5, -3, 2400);
- break;
- default:
- writer.cool(xl, xr, 3, -5, 1600)
- .cool(xl, xr, 5, -5, 2000)
- .cool(xl, xr, 5, -5, 2400)
- .cool(xl, xr, 5, -3, 2400);
- }
+ m_old_temperature = new_temperature;
+ }
+
+ // Cooling:
+ const int& number_of_moves = m_filpar[m_current_tool].cooling_moves;
+ if (number_of_moves > 0) {
+ const float& initial_speed = m_filpar[m_current_tool].cooling_initial_speed;
+ const float& final_speed = m_filpar[m_current_tool].cooling_final_speed;
+
+ float speed_inc = (final_speed - initial_speed) / (2.f * number_of_moves - 1.f);
+
+ writer.suppress_preview()
+ .travel(writer.x(), writer.y() + y_step);
+ old_x = writer.x();
+ turning_point = xr-old_x > old_x-xl ? xr : xl;
+ for (int i=0; i<number_of_moves; ++i) {
+ float speed = initial_speed + speed_inc * 2*i;
+ writer.load_move_x_advanced(turning_point, m_cooling_tube_length, speed);
+ speed += speed_inc;
+ writer.load_move_x_advanced(old_x, -m_cooling_tube_length, speed);
+ }
+ }
+
+ // let's wait is necessary:
+ writer.wait(m_filpar[m_current_tool].delay);
+ // we should be at the beginning of the cooling tube again - let's move to parking position:
+ writer.retract(-m_cooling_tube_length/2.f+m_parking_pos_retraction-m_cooling_tube_retraction, 2000);
+
+ // this is to align ramming and future wiping extrusions, so the future y-steps can be uniform from the start:
+ // the perimeter_width will later be subtracted, it is there to not load while moving over just extruded material
+ writer.travel(end_of_ramming.x, end_of_ramming.y + (y_step/m_extra_spacing-m_perimeter_width) / 2.f + m_perimeter_width, 2400.f);
writer.resume_preview()
.flush_planner_queue();
}
-// Change the tool, set a speed override for solube and flex materials.
+// Change the tool, set a speed override for soluble and flex materials.
void WipeTowerPrusaMM::toolchange_Change(
PrusaMultiMaterial::Writer &writer,
const unsigned int new_tool,
@@ -835,219 +863,373 @@ void WipeTowerPrusaMM::toolchange_Change(
m_current_tool = new_tool;
}
+
+
void WipeTowerPrusaMM::toolchange_Load(
PrusaMultiMaterial::Writer &writer,
const box_coordinates &cleaning_box)
-{
- float xl = cleaning_box.ld.x + m_perimeter_width;
- float xr = cleaning_box.rd.x - m_perimeter_width;
- //FIXME flipping left / right side, so that the following toolchange_Wipe will start
- // where toolchange_Load ends.
- std::swap(xl, xr);
-
- writer.append("; CP TOOLCHANGE LOAD\n")
- // Load the filament while moving left / right,
- // so the excess material will not create a blob at a single position.
+{
+ float xl = cleaning_box.ld.x + m_perimeter_width * 0.75f;
+ float xr = cleaning_box.rd.x - m_perimeter_width * 0.75f;
+ float oldx = writer.x(); // the nozzle is in place to do the first wiping moves, we will remember the position
+
+ // Load the filament while moving left / right, so the excess material will not create a blob at a single position.
+ float turning_point = ( oldx-xl < xr-oldx ? xr : xl );
+ float edist = m_parking_pos_retraction+m_extra_loading_move;
+
+ writer.append("; CP TOOLCHANGE LOAD\n")
.suppress_preview()
- // Accelerate the filament loading
- .load_move_x(xr, 20, 1400)
- // Fast loading phase
- .load_move_x(xl, 40, 3000)
- // Slowing down
- .load_move_x(xr, 20, 1600)
- .load_move_x(xl, 10, 1000)
- .resume_preview();
+ /*.load_move_x_advanced(turning_point, 0.2f * edist, 0.3f * m_filpar[m_current_tool].loading_speed) // Acceleration
+ .load_move_x_advanced(oldx, 0.5f * edist, m_filpar[m_current_tool].loading_speed) // Fast phase
+ .load_move_x_advanced(turning_point, 0.2f * edist, 0.3f * m_filpar[m_current_tool].loading_speed) // Slowing down
+ .load_move_x_advanced(oldx, 0.1f * edist, 0.1f * m_filpar[m_current_tool].loading_speed) // Super slow*/
- // Extrude first five lines (just three lines if colorInit is set).
- writer.extrude(xr, writer.y(), 1600);
- bool colorInit = false;
- size_t pass = colorInit ? 1 : 2;
- float dy = ((m_current_shape == SHAPE_NORMAL) ? 1.f : -1.f) * m_perimeter_width * 0.85f;
- for (int i = 0; i < pass; ++ i) {
- writer.travel (xr, writer.y() + dy, 7200);
- writer.extrude(xl, writer.y(), 2200);
- writer.travel (xl, writer.y() + dy, 7200);
- writer.extrude(xr, writer.y(), 2200);
- }
+ .load(0.2f * edist, 60.f * m_filpar[m_current_tool].loading_speed_start)
+ .load_move_x_advanced(turning_point, 0.7f * edist, m_filpar[m_current_tool].loading_speed) // Fast phase
+ .load_move_x_advanced(oldx, 0.1f * edist, 0.1f * m_filpar[m_current_tool].loading_speed) // Super slow*/
+
+ .travel(oldx, writer.y()) // in case last move was shortened to limit x feedrate
+ .resume_preview();
// Reset the extruder current to the normal value.
writer.set_extruder_trimpot(550);
}
+
+
+
// Wipe the newly loaded filament until the end of the assigned wipe area.
void WipeTowerPrusaMM::toolchange_Wipe(
PrusaMultiMaterial::Writer &writer,
const box_coordinates &cleaning_box,
- bool skip_initial_y_move)
+ float wipe_volume)
{
// Increase flow on first layer, slow down print.
writer.set_extrusion_flow(m_extrusion_flow * (m_is_first_layer ? 1.18f : 1.f))
.append("; CP TOOLCHANGE WIPE\n");
float wipe_coeff = m_is_first_layer ? 0.5f : 1.f;
- float xl = cleaning_box.ld.x + 2.f * m_perimeter_width;
- float xr = cleaning_box.rd.x - 2.f * m_perimeter_width;
- // Wipe speed will increase up to 4800.
- float wipe_speed = 4200.f;
- float wipe_speed_inc = 50.f;
- float wipe_speed_max = 4800.f;
- // Y increment per wipe line.
- float dy = ((m_current_shape == SHAPE_NORMAL) ? 1.f : -1.f) * m_perimeter_width * 0.8f;
- for (bool p = true;
- // Next wipe line fits the cleaning box.
- ((m_current_shape == SHAPE_NORMAL) ?
- (writer.y() <= cleaning_box.lu.y - m_perimeter_width) :
- (writer.y() >= cleaning_box.ld.y + m_perimeter_width));
- p = ! p)
- {
- wipe_speed = std::min(wipe_speed_max, wipe_speed + wipe_speed_inc);
- if (skip_initial_y_move)
- skip_initial_y_move = false;
+ const float& xl = cleaning_box.ld.x;
+ const float& xr = cleaning_box.rd.x;
+
+
+ // Variables x_to_wipe and traversed_x are here to be able to make sure it always wipes at least
+ // the ordered volume, even if it means violating the box. This can later be removed and simply
+ // wipe until the end of the assigned area.
+
+ float x_to_wipe = volume_to_length(wipe_volume, m_perimeter_width, m_layer_height);
+ float dy = m_extra_spacing*m_perimeter_width;
+ float wipe_speed = 1600.f;
+
+ // if there is less than 2.5*m_perimeter_width to the edge, advance straightaway (there is likely a blob anyway)
+ if ((m_left_to_right ? xr-writer.x() : writer.x()-xl) < 2.5f*m_perimeter_width) {
+ writer.travel((m_left_to_right ? xr-m_perimeter_width : xl+m_perimeter_width),writer.y()+dy);
+ m_left_to_right = !m_left_to_right;
+ }
+
+
+ // now the wiping itself:
+ for (int i = 0; true; ++i) {
+ if (i!=0) {
+ if (wipe_speed < 1610.f) wipe_speed = 1800.f;
+ else if (wipe_speed < 1810.f) wipe_speed = 2200.f;
+ else if (wipe_speed < 2210.f) wipe_speed = 4200.f;
+ else wipe_speed = std::min(4800.f, wipe_speed + 50.f);
+ }
+
+ float traversed_x = writer.x();
+ if (m_left_to_right)
+ writer.extrude(xr - (i % 4 == 0 ? 0 : 1.5*m_perimeter_width), writer.y(), wipe_speed * wipe_coeff);
else
- writer.extrude(xl - (p ? m_perimeter_width / 2 : m_perimeter_width), writer.y() + dy, wipe_speed * wipe_coeff);
- writer.extrude(xr + (p ? m_perimeter_width : m_perimeter_width * 2), writer.y(), wipe_speed * wipe_coeff);
- // Next wipe line fits the cleaning box.
- if ((m_current_shape == SHAPE_NORMAL) ?
- (writer.y() > cleaning_box.lu.y - m_perimeter_width) :
- (writer.y() < cleaning_box.ld.y + m_perimeter_width))
+ writer.extrude(xl + (i % 4 == 1 ? 0 : 1.5*m_perimeter_width), writer.y(), wipe_speed * wipe_coeff);
+
+ if (writer.y()+EPSILON > cleaning_box.lu.y-0.5f*m_perimeter_width)
+ break; // in case next line would not fit
+
+ traversed_x -= writer.x();
+ x_to_wipe -= fabs(traversed_x);
+ if (x_to_wipe < WT_EPSILON) {
+ writer.travel(m_left_to_right ? xl + 1.5*m_perimeter_width : xr - 1.5*m_perimeter_width, writer.y(), 7200);
break;
- wipe_speed = std::min(wipe_speed_max, wipe_speed + wipe_speed_inc);
- writer.extrude(xr + m_perimeter_width, writer.y() + dy, wipe_speed * wipe_coeff);
- writer.extrude(xl - m_perimeter_width, writer.y());
+ }
+ // stepping to the next line:
+ writer.extrude(writer.x() + (i % 4 == 0 ? -1.f : (i % 4 == 1 ? 1.f : 0.f)) * 1.5*m_perimeter_width, writer.y() + dy);
+ m_left_to_right = !m_left_to_right;
}
- // Reset the extrusion flow.
- writer.set_extrusion_flow(m_extrusion_flow);
+
+ // this is neither priming nor not the last toolchange on this layer - we are going back to the model - wipe the nozzle
+ if (m_layer_info != m_plan.end() && m_current_tool != m_layer_info->tool_changes.back().new_tool) {
+ m_left_to_right = !m_left_to_right;
+ writer.travel(writer.x(), writer.y() - dy)
+ .travel(m_left_to_right ? m_wipe_tower_width : 0.f, writer.y());
+ }
+
+ writer.set_extrusion_flow(m_extrusion_flow); // Reset the extrusion flow.
}
-WipeTower::ToolChangeResult WipeTowerPrusaMM::finish_layer(Purpose purpose)
+
+
+
+WipeTower::ToolChangeResult WipeTowerPrusaMM::finish_layer()
{
// This should only be called if the layer is not finished yet.
// Otherwise the caller would likely travel to the wipe tower in vain.
assert(! this->layer_finished());
- PrusaMultiMaterial::Writer writer;
+ PrusaMultiMaterial::Writer writer(m_layer_height, m_perimeter_width);
writer.set_extrusion_flow(m_extrusion_flow)
- .set_z(m_z_pos)
- .set_layer_height(m_layer_height)
- .set_initial_tool(m_current_tool)
- .append(";--------------------\n"
- "; CP EMPTY GRID START\n")
- // m_num_layer_changes is incremented by set_z, so it is 1 based.
- .comment_with_value(" layer #", m_num_layer_changes - 1);
+ .set_z(m_z_pos)
+ .set_initial_tool(m_current_tool)
+ .set_y_shift(m_y_shift - (m_current_shape == SHAPE_REVERSED && !m_peters_wipe_tower ? m_layer_info->toolchanges_depth() : 0.f))
+ .append(";--------------------\n"
+ "; CP EMPTY GRID START\n")
+ .comment_with_value(" layer #", m_num_layer_changes + 1);
// Slow down on the 1st layer.
float speed_factor = m_is_first_layer ? 0.5f : 1.f;
+ float current_depth = m_layer_info->depth - m_layer_info->toolchanges_depth();
+ box_coordinates fill_box(xy(m_perimeter_width, m_depth_traversed + m_perimeter_width),
+ m_wipe_tower_width - 2 * m_perimeter_width, current_depth-m_perimeter_width);
+
+
+ writer.set_initial_position((m_left_to_right ? fill_box.ru : fill_box.lu), // so there is never a diagonal travel
+ m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation);
+
+ box_coordinates box = fill_box;
+ for (int i=0;i<2;++i) {
+ if (m_layer_info->toolchanges_depth() < WT_EPSILON) { // there were no toolchanges on this layer
+ if (i==0) box.expand(m_perimeter_width);
+ else box.expand(-m_perimeter_width);
+ }
+ else i=2; // only draw the inner perimeter, outer has been already drawn by tool_change(...)
+ writer.rectangle(box.ld,box.rd.x-box.ld.x,box.ru.y-box.rd.y,2900*speed_factor);
+ }
+
+ // we are in one of the corners, travel to ld along the perimeter:
+ if (writer.x() > fill_box.ld.x+EPSILON) writer.travel(fill_box.ld.x,writer.y());
+ if (writer.y() > fill_box.ld.y+EPSILON) writer.travel(writer.x(),fill_box.ld.y);
+
+ if (m_is_first_layer && m_adhesion) {
+ // Extrude a dense infill at the 1st layer to improve 1st layer adhesion of the wipe tower.
+ box.expand(-m_perimeter_width/2.f);
+ int nsteps = int(floor((box.lu.y - box.ld.y) / (2*m_perimeter_width)));
+ float step = (box.lu.y - box.ld.y) / nsteps;
+ writer.travel(box.ld-xy(m_perimeter_width/2.f,m_perimeter_width/2.f));
+ if (nsteps >= 0)
+ for (int i = 0; i < nsteps; ++i) {
+ writer.extrude(box.ld.x+m_perimeter_width/2.f, writer.y() + 0.5f * step);
+ writer.extrude(box.rd.x - m_perimeter_width / 2.f, writer.y());
+ writer.extrude(box.rd.x - m_perimeter_width / 2.f, writer.y() + 0.5f * step);
+ writer.extrude(box.ld.x + m_perimeter_width / 2.f, writer.y());
+ }
+ writer.travel(box.rd.x-m_perimeter_width/2.f,writer.y()); // wipe the nozzle
+ }
+ else { // Extrude a sparse infill to support the material to be printed above.
+ const float dy = (fill_box.lu.y - fill_box.ld.y - m_perimeter_width);
+ const float left = fill_box.lu.x+2*m_perimeter_width;
+ const float right = fill_box.ru.x - 2 * m_perimeter_width;
+ if (dy > m_perimeter_width)
+ {
+ // Extrude an inverse U at the left of the region.
+ writer.travel(fill_box.ld + xy(m_perimeter_width * 2, 0.f))
+ .extrude(fill_box.lu + xy(m_perimeter_width * 2, 0.f), 2900 * speed_factor);
+
+ const int n = 1+(right-left)/(m_bridging);
+ const float dx = (right-left)/n;
+ for (int i=1;i<=n;++i) {
+ float x=left+dx*i;
+ writer.travel(x,writer.y());
+ writer.extrude(x,i%2 ? fill_box.rd.y : fill_box.ru.y);
+ }
+ writer.travel(left,writer.y(),7200); // wipes the nozzle before moving away from the wipe tower
+ }
+ else
+ writer.travel(right,writer.y(),7200); // wipes the nozzle before moving away from the wipe tower
+ }
+ writer.append("; CP EMPTY GRID END\n"
+ ";------------------\n\n\n\n\n\n\n");
+
+ m_depth_traversed = m_wipe_tower_depth-m_perimeter_width;
- box_coordinates fill_box(m_wipe_tower_pos + xy(0.f, m_current_wipe_start_y),
- m_wipe_tower_width, float(m_max_color_changes) * m_wipe_area - m_current_wipe_start_y);
- fill_box.expand(0.f, - 0.5f * m_perimeter_width);
- {
- float firstLayerOffset = 0.f;
- fill_box.ld.y += firstLayerOffset;
- fill_box.rd.y += firstLayerOffset;
+ ToolChangeResult result;
+ result.priming = false;
+ result.print_z = this->m_z_pos;
+ result.layer_height = this->m_layer_height;
+ result.gcode = writer.gcode();
+ result.elapsed_time = writer.elapsed_time();
+ result.extrusions = writer.extrusions();
+ result.start_pos = writer.start_pos_rotated();
+ result.end_pos = writer.pos_rotated();
+ return result;
+}
+
+// Appends a toolchange into m_plan and calculates neccessary depth of the corresponding box
+void WipeTowerPrusaMM::plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool, unsigned int new_tool, bool brim, float wipe_volume)
+{
+ assert(m_plan.back().z <= z_par + WT_EPSILON ); // refuses to add a layer below the last one
+
+ if (m_plan.empty() || m_plan.back().z + WT_EPSILON < z_par) // if we moved to a new layer, we'll add it to m_plan first
+ m_plan.push_back(WipeTowerInfo(z_par, layer_height_par));
+
+ if (brim) { // this toolchange prints brim - we must add it to m_plan, but not to count its depth
+ m_plan.back().tool_changes.push_back(WipeTowerInfo::ToolChange(old_tool, new_tool));
+ return;
}
- if (purpose == PURPOSE_MOVE_TO_TOWER || purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) {
- if (m_idx_tool_change_in_layer == 0) {
- // There were no tool changes at all in this layer.
- writer.retract(m_retract * 1.5f, 3600)
- // Jump with retract to fill_box.ld + a random shift in +x.
- .z_hop(m_zhop, 7200)
- .travel(fill_box.ld + xy(5.f + 15.f * float(rand()) / RAND_MAX, 0.f), 7000)
- .z_hop_reset(7200)
- // Prime the extruder.
- .load_move_x(fill_box.ld.x, m_retract * 1.5f, 3600);
- } else {
- // Otherwise the extruder is already over the wipe tower.
+ if (old_tool==new_tool) // new layer without toolchanges - we are done
+ return;
+
+ // this is an actual toolchange - let's calculate depth to reserve on the wipe tower
+ float depth = 0.f;
+ float width = m_wipe_tower_width - 3*m_perimeter_width;
+ float length_to_extrude = volume_to_length(0.25f * std::accumulate(m_filpar[old_tool].ramming_speed.begin(), m_filpar[old_tool].ramming_speed.end(), 0.f),
+ m_perimeter_width * m_filpar[old_tool].ramming_line_width_multiplicator,
+ layer_height_par);
+ depth = (int(length_to_extrude / width) + 1) * (m_perimeter_width * m_filpar[old_tool].ramming_line_width_multiplicator * m_filpar[old_tool].ramming_step_multiplicator);
+ float ramming_depth = depth;
+ length_to_extrude = width*((length_to_extrude / width)-int(length_to_extrude / width)) - width;
+ float first_wipe_line = -length_to_extrude;
+ length_to_extrude += volume_to_length(wipe_volume, m_perimeter_width, layer_height_par);
+ length_to_extrude = std::max(length_to_extrude,0.f);
+
+ depth += (int(length_to_extrude / width) + 1) * m_perimeter_width;
+ depth *= m_extra_spacing;
+
+ m_plan.back().tool_changes.push_back(WipeTowerInfo::ToolChange(old_tool, new_tool, depth, ramming_depth, first_wipe_line, wipe_volume));
+}
+
+
+
+void WipeTowerPrusaMM::plan_tower()
+{
+ // Calculate m_wipe_tower_depth (maximum depth for all the layers) and propagate depths downwards
+ m_wipe_tower_depth = 0.f;
+ for (auto& layer : m_plan)
+ layer.depth = 0.f;
+
+ for (int layer_index = m_plan.size() - 1; layer_index >= 0; --layer_index)
+ {
+ float this_layer_depth = std::max(m_plan[layer_index].depth, m_plan[layer_index].toolchanges_depth());
+ m_plan[layer_index].depth = this_layer_depth;
+
+ if (this_layer_depth > m_wipe_tower_depth - m_perimeter_width)
+ m_wipe_tower_depth = this_layer_depth + m_perimeter_width;
+
+ for (int i = layer_index - 1; i >= 0 ; i--)
+ {
+ if (m_plan[i].depth - this_layer_depth < 2*m_perimeter_width )
+ m_plan[i].depth = this_layer_depth;
}
- } else {
- // The print head is inside the wipe tower. Rather move to the start of the following extrusion.
- // writer.set_initial_position(fill_box.ld);
- writer.set_initial_position(fill_box.ld);
}
+}
- if (purpose == PURPOSE_EXTRUDE || purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE) {
- // Extrude the first perimeter.
- box_coordinates box = fill_box;
- writer.extrude(box.lu, 2400 * speed_factor)
- .extrude(box.ru)
- .extrude(box.rd)
- .extrude(box.ld + xy(m_perimeter_width / 2, 0));
-
- // Extrude second perimeter.
- box.expand(- m_perimeter_width / 2);
- writer.extrude(box.lu, 3200 * speed_factor)
- .extrude(box.ru)
- .extrude(box.rd)
- .extrude(box.ld + xy(m_perimeter_width / 2, 0));
-
- if (m_is_first_layer) {
- // Extrude a dense infill at the 1st layer to improve 1st layer adhesion of the wipe tower.
- box.expand(- m_perimeter_width / 2);
- box.ld.y -= 0.5f * m_perimeter_width;
- box.rd.y = box.ld.y;
- int nsteps = int(floor((box.lu.y - box.ld.y) / (2. * (1.0 * m_perimeter_width))));
- float step = (box.lu.y - box.ld.y) / nsteps;
- for (size_t i = 0; i < nsteps; ++ i) {
- writer.extrude(box.ld.x, writer.y() + 0.5f * step);
- writer.extrude(box.rd.x, writer.y());
- writer.extrude(box.rd.x, writer.y() + 0.5f * step);
- writer.extrude(box.ld.x, writer.y());
- }
- } else {
- // Extrude a sparse infill to support the material to be printed above.
-
- // Extrude an inverse U at the left of the region.
- writer.extrude(box.ld + xy(m_perimeter_width / 2, m_perimeter_width / 2))
- .extrude(fill_box.ld + xy(m_perimeter_width * 3, m_perimeter_width), 2900 * speed_factor)
- .extrude(fill_box.lu + xy(m_perimeter_width * 3, - m_perimeter_width))
- .extrude(fill_box.lu + xy(m_perimeter_width * 6, - m_perimeter_width))
- .extrude(fill_box.ld + xy(m_perimeter_width * 6, m_perimeter_width));
-
- if (fill_box.lu.y - fill_box.ld.y > 4.f) {
- // Extrude three zig-zags.
- float step = (m_wipe_tower_width - m_perimeter_width * 12.f) / 12.f;
- for (size_t i = 0; i < 3; ++ i) {
- writer.extrude(writer.x() + step, fill_box.ld.y + m_perimeter_width * 8, 3200 * speed_factor);
- writer.extrude(writer.x() , fill_box.lu.y - m_perimeter_width * 8);
- writer.extrude(writer.x() + step, fill_box.lu.y - m_perimeter_width );
- writer.extrude(writer.x() + step, fill_box.lu.y - m_perimeter_width * 8);
- writer.extrude(writer.x() , fill_box.ld.y + m_perimeter_width * 8);
- writer.extrude(writer.x() + step, fill_box.ld.y + m_perimeter_width );
- }
- }
+void WipeTowerPrusaMM::save_on_last_wipe()
+{
+ for (m_layer_info=m_plan.begin();m_layer_info<m_plan.end();++m_layer_info) {
+ set_layer(m_layer_info->z, m_layer_info->height, 0, m_layer_info->z == m_plan.front().z, m_layer_info->z == m_plan.back().z);
+ if (m_layer_info->tool_changes.size()==0) // we have no way to save anything on an empty layer
+ continue;
- // Extrude an inverse U at the left of the region.
- writer.extrude(fill_box.ru + xy(- m_perimeter_width * 6, - m_perimeter_width), 2900 * speed_factor)
- .extrude(fill_box.ru + xy(- m_perimeter_width * 3, - m_perimeter_width))
- .extrude(fill_box.rd + xy(- m_perimeter_width * 3, m_perimeter_width))
- .extrude(fill_box.rd + xy(- m_perimeter_width, m_perimeter_width));
- }
+ for (const auto &toolchange : m_layer_info->tool_changes)
+ tool_change(toolchange.new_tool, false);
+
+ float width = m_wipe_tower_width - 3*m_perimeter_width; // width we draw into
+ float length_to_save = 2*(m_wipe_tower_width+m_wipe_tower_depth) + (!layer_finished() ? finish_layer().total_extrusion_length_in_plane() : 0.f);
+ float length_to_wipe = volume_to_length(m_layer_info->tool_changes.back().wipe_volume,
+ m_perimeter_width,m_layer_info->height) - m_layer_info->tool_changes.back().first_wipe_line - length_to_save;
+
+ length_to_wipe = std::max(length_to_wipe,0.f);
+ float depth_to_wipe = m_perimeter_width * (std::floor(length_to_wipe/width) + ( length_to_wipe > 0.f ? 1.f : 0.f ) ) * m_extra_spacing;
- // if (purpose == PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE)
- if (true)
- // Wipe along the front side of the current wiping box.
- // Always wipe the nozzle with a long wipe to reduce stringing when moving away from the wipe tower.
- writer.travel(fill_box.ld + xy( m_perimeter_width, m_perimeter_width / 2), 7200)
- .travel(fill_box.rd + xy(- m_perimeter_width, m_perimeter_width / 2));
+ //depth += (int(length_to_extrude / width) + 1) * m_perimeter_width;
+ m_layer_info->tool_changes.back().required_depth = m_layer_info->tool_changes.back().ramming_depth + depth_to_wipe;
+ }
+}
+
+// Processes vector m_plan and calls respective functions to generate G-code for the wipe tower
+// Resulting ToolChangeResults are appended into vector "result"
+void WipeTowerPrusaMM::generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &result)
+{
+ if (m_plan.empty())
+
+ return;
+
+ m_extra_spacing = 1.f;
+
+ plan_tower();
+ for (int i=0;i<5;++i) {
+ save_on_last_wipe();
+ plan_tower();
+ }
+
+ if (m_peters_wipe_tower)
+ make_wipe_tower_square();
+
+ m_layer_info = m_plan.begin();
+ m_current_tool = (unsigned int)(-2); // we don't know which extruder to start with - we'll set it according to the first toolchange
+
+ std::vector<WipeTower::ToolChangeResult> layer_result;
+ for (auto layer : m_plan)
+ {
+ set_layer(layer.z,layer.height,0,layer.z == m_plan.front().z,layer.z == m_plan.back().z);
+ if (m_peters_wipe_tower)
+ m_internal_rotation += 90.f;
else
- writer.feedrate(7200);
+ m_internal_rotation += 180.f;
+
+ if (!m_peters_wipe_tower && m_layer_info->depth < m_wipe_tower_depth - m_perimeter_width)
+ m_y_shift = (m_wipe_tower_depth-m_layer_info->depth-m_perimeter_width)/2.f;
+
+ for (const auto &toolchange : layer.tool_changes) {
+ if (m_current_tool == (unsigned int)(-2))
+ m_current_tool = toolchange.old_tool;
+ layer_result.emplace_back(tool_change(toolchange.new_tool, false));
+ }
+
+ if (! layer_finished()) {
+ auto finish_layer_toolchange = finish_layer();
+ if ( ! layer.tool_changes.empty() ) { // we will merge it to the last toolchange
+ auto& last_toolchange = layer_result.back();
+ if (last_toolchange.end_pos != finish_layer_toolchange.start_pos) {
+ char buf[2048]; // Add a travel move from tc1.end_pos to tc2.start_pos.
+ sprintf(buf, "G1 X%.3f Y%.3f F7200\n", finish_layer_toolchange.start_pos.x, finish_layer_toolchange.start_pos.y);
+ last_toolchange.gcode += buf;
+ }
+ last_toolchange.gcode += finish_layer_toolchange.gcode;
+ last_toolchange.extrusions.insert(last_toolchange.extrusions.end(), finish_layer_toolchange.extrusions.begin(), finish_layer_toolchange.extrusions.end());
+ last_toolchange.end_pos = finish_layer_toolchange.end_pos;
+ }
+ else
+ layer_result.emplace_back(std::move(finish_layer_toolchange));
+ }
+
+ result.emplace_back(std::move(layer_result));
+ m_is_first_layer = false;
+ }
+}
- writer.append("; CP EMPTY GRID END\n"
- ";------------------\n\n\n\n\n\n\n");
+void WipeTowerPrusaMM::make_wipe_tower_square()
+{
+ const float width = m_wipe_tower_width - 3 * m_perimeter_width;
+ const float depth = m_wipe_tower_depth - m_perimeter_width;
+ // area that we actually print into is width*depth
+ float side = sqrt(depth * width);
+
+ m_wipe_tower_width = side + 3 * m_perimeter_width;
+ m_wipe_tower_depth = side + 2 * m_perimeter_width;
+ // For all layers, find how depth changed and update all toolchange depths
+ for (auto &lay : m_plan)
+ {
+ side = sqrt(lay.depth * width);
+ float width_ratio = width / side;
- // Indicate that this wipe tower layer is fully covered.
- m_idx_tool_change_in_layer = (unsigned int)m_max_color_changes;
+ //lay.extra_spacing = width_ratio;
+ for (auto &tch : lay.tool_changes)
+ tch.required_depth *= width_ratio;
}
- ToolChangeResult result;
- result.print_z = m_z_pos;
- result.layer_height = m_layer_height;
- result.gcode = writer.gcode();
- result.elapsed_time = writer.elapsed_time();
- result.extrusions = writer.extrusions();
- result.start_pos = writer.start_pos();
- result.end_pos = writer.pos();
- return result;
+ plan_tower(); // propagates depth downwards again (width has changed)
+ for (auto& lay : m_plan) // depths set, now the spacing
+ lay.extra_spacing = lay.depth / lay.toolchanges_depth();
}
}; // namespace Slic3r
diff --git a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
index b8c7ab31f..305dbc40a 100644
--- a/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
+++ b/xs/src/libslic3r/GCode/WipeTowerPrusaMM.hpp
@@ -1,13 +1,15 @@
#ifndef WipeTowerPrusaMM_hpp_
#define WipeTowerPrusaMM_hpp_
-#include <algorithm>
#include <cmath>
#include <string>
+#include <sstream>
#include <utility>
+#include <algorithm>
#include "WipeTower.hpp"
+
namespace Slic3r
{
@@ -15,6 +17,8 @@ namespace PrusaMultiMaterial {
class Writer;
};
+
+
class WipeTowerPrusaMM : public WipeTower
{
public:
@@ -39,65 +43,103 @@ public:
// y -- y coordinates of wipe tower in mm ( left bottom corner )
// width -- width of wipe tower in mm ( default 60 mm - leave as it is )
// wipe_area -- space available for one toolchange in mm
- WipeTowerPrusaMM(float x, float y, float width, float wipe_area, unsigned int initial_tool) :
+ WipeTowerPrusaMM(float x, float y, float width, float rotation_angle, float cooling_tube_retraction,
+ float cooling_tube_length, float parking_pos_retraction, float extra_loading_move, float bridging,
+ const std::vector<std::vector<float>>& wiping_matrix, unsigned int initial_tool) :
m_wipe_tower_pos(x, y),
m_wipe_tower_width(width),
- m_wipe_area(wipe_area),
+ m_wipe_tower_rotation_angle(rotation_angle),
+ m_y_shift(0.f),
m_z_pos(0.f),
- m_current_tool(initial_tool)
- {
- for (size_t i = 0; i < 4; ++ i) {
- // Extruder specific parameters.
- m_material[i] = PLA;
- m_temperature[i] = 0;
- m_first_layer_temperature[i] = 0;
- }
- }
+ m_is_first_layer(false),
+ m_cooling_tube_retraction(cooling_tube_retraction),
+ m_cooling_tube_length(cooling_tube_length),
+ m_parking_pos_retraction(parking_pos_retraction),
+ m_extra_loading_move(extra_loading_move),
+ m_bridging(bridging),
+ m_current_tool(initial_tool),
+ wipe_volumes(wiping_matrix)
+ {}
virtual ~WipeTowerPrusaMM() {}
- // _retract - retract value in mm
- void set_retract(float retract) { m_retract = retract; }
-
- // _zHop - z hop value in mm
- void set_zhop(float zhop) { m_zhop = zhop; }
// Set the extruder properties.
- void set_extruder(size_t idx, material_type material, int temp, int first_layer_temp)
+ void set_extruder(size_t idx, material_type material, int temp, int first_layer_temp, float loading_speed, float loading_speed_start,
+ float unloading_speed, float unloading_speed_start, float delay, int cooling_moves,
+ float cooling_initial_speed, float cooling_final_speed, std::string ramming_parameters, float nozzle_diameter)
{
- m_material[idx] = material;
- m_temperature[idx] = temp;
- m_first_layer_temperature[idx] = first_layer_temp;
+ //while (m_filpar.size() < idx+1) // makes sure the required element is in the vector
+ m_filpar.push_back(FilamentParameters());
+
+ m_filpar[idx].material = material;
+ m_filpar[idx].temperature = temp;
+ m_filpar[idx].first_layer_temperature = first_layer_temp;
+ m_filpar[idx].loading_speed = loading_speed;
+ m_filpar[idx].loading_speed_start = loading_speed_start;
+ m_filpar[idx].unloading_speed = unloading_speed;
+ m_filpar[idx].unloading_speed_start = unloading_speed_start;
+ m_filpar[idx].delay = delay;
+ m_filpar[idx].cooling_moves = cooling_moves;
+ m_filpar[idx].cooling_initial_speed = cooling_initial_speed;
+ m_filpar[idx].cooling_final_speed = cooling_final_speed;
+ m_filpar[idx].nozzle_diameter = nozzle_diameter; // to be used in future with (non-single) multiextruder MM
+
+ m_perimeter_width = nozzle_diameter * Width_To_Nozzle_Ratio; // all extruders are now assumed to have the same diameter
+
+ std::stringstream stream{ramming_parameters};
+ float speed = 0.f;
+ stream >> m_filpar[idx].ramming_line_width_multiplicator >> m_filpar[idx].ramming_step_multiplicator;
+ m_filpar[idx].ramming_line_width_multiplicator /= 100;
+ m_filpar[idx].ramming_step_multiplicator /= 100;
+ while (stream >> speed)
+ m_filpar[idx].ramming_speed.push_back(speed);
}
+
+ // Appends into internal structure m_plan containing info about the future wipe tower
+ // to be used before building begins. The entries must be added ordered in z.
+ void plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool, unsigned int new_tool, bool brim, float wipe_volume = 0.f);
+
+ // Iterates through prepared m_plan, generates ToolChangeResults and appends them to "result"
+ void generate(std::vector<std::vector<WipeTower::ToolChangeResult>> &result);
+
+ float get_depth() const { return m_wipe_tower_depth; }
+
+
+
// Switch to a next layer.
virtual void set_layer(
// Print height of this layer.
- float print_z,
- // Layer height, used to calculate extrusion the rate.
- float layer_height,
+ float print_z,
+ // Layer height, used to calculate extrusion the rate.
+ float layer_height,
// Maximum number of tool changes on this layer or the layers below.
- size_t max_tool_changes,
+ size_t max_tool_changes,
// Is this the first layer of the print? In that case print the brim first.
- bool is_first_layer,
+ bool is_first_layer,
// Is this the last layer of the waste tower?
- bool is_last_layer)
+ bool is_last_layer)
{
m_z_pos = print_z;
m_layer_height = layer_height;
- m_max_color_changes = max_tool_changes;
m_is_first_layer = is_first_layer;
- m_is_last_layer = is_last_layer;
- // Start counting the color changes from zero. Special case: -1 - extrude a brim first.
- m_idx_tool_change_in_layer = is_first_layer ? (unsigned int)(-1) : 0;
- m_current_wipe_start_y = 0.f;
+ m_print_brim = is_first_layer;
+ m_depth_traversed = 0.f;
m_current_shape = (! is_first_layer && m_current_shape == SHAPE_NORMAL) ? SHAPE_REVERSED : SHAPE_NORMAL;
- ++ m_num_layer_changes;
- // Extrusion rate for an extrusion aka perimeter width 0.35mm.
- // Clamp the extrusion height to a 0.2mm layer height, independent of the nozzle diameter.
-// m_extrusion_flow = std::min(0.2f, layer_height) * 0.145f;
- // Use a strictly
- m_extrusion_flow = layer_height * 0.145f;
+ if (is_first_layer) {
+ this->m_num_layer_changes = 0;
+ this->m_num_tool_changes = 0;
+ }
+ else
+ ++ m_num_layer_changes;
+
+ // Calculate extrusion flow from desired line width, nozzle diameter, filament diameter and layer_height:
+ m_extrusion_flow = extrusion_flow(layer_height);
+
+ // Advance m_layer_info iterator, making sure we got it right
+ while (!m_plan.empty() && m_layer_info->z < print_z - WT_EPSILON && m_layer_info+1 != m_plan.end())
+ ++m_layer_info;
}
// Return the wipe tower position.
@@ -115,79 +157,120 @@ public:
const std::vector<unsigned int> &tools,
// If true, the last priming are will be the same as the other priming areas, and the rest of the wipe will be performed inside the wipe tower.
// If false, the last priming are will be large enough to wipe the last extruder sufficiently.
- bool last_wipe_inside_wipe_tower,
- // May be used by a stand alone post processor.
- Purpose purpose = PURPOSE_MOVE_TO_TOWER_AND_EXTRUDE);
+ bool last_wipe_inside_wipe_tower);
// Returns gcode for a toolchange and a final print head position.
// On the first layer, extrude a brim around the future wipe tower first.
- virtual ToolChangeResult tool_change(unsigned int new_tool, bool last_in_layer, Purpose purpose);
+ virtual ToolChangeResult tool_change(unsigned int new_tool, bool last_in_layer);
- // Close the current wipe tower layer with a perimeter and possibly fill the unfilled space with a zig-zag.
+ // Fill the unfilled space with a sparse infill.
// Call this method only if layer_finished() is false.
- virtual ToolChangeResult finish_layer(Purpose purpose);
+ virtual ToolChangeResult finish_layer();
+
+ // Is the current layer finished?
+ virtual bool layer_finished() const {
+ return ( (m_is_first_layer ? m_wipe_tower_depth - m_perimeter_width : m_layer_info->depth) - WT_EPSILON < m_depth_traversed);
+ }
- // Is the current layer finished? A layer is finished if either the wipe tower is finished, or
- // the wipe tower has been completely covered by the tool change extrusions,
- // or the rest of the tower has been filled by a sparse infill with the finish_layer() method.
- virtual bool layer_finished() const
- { return m_idx_tool_change_in_layer == m_max_color_changes; }
private:
WipeTowerPrusaMM();
- // A fill-in direction (positive Y, negative Y) alternates with each layer.
- enum wipe_shape
+ enum wipe_shape // A fill-in direction
{
- SHAPE_NORMAL = 1,
+ SHAPE_NORMAL = 1,
SHAPE_REVERSED = -1
};
- // Left front corner of the wipe tower in mm.
- xy m_wipe_tower_pos;
- // Width of the wipe tower.
- float m_wipe_tower_width;
- // Per color Y span.
- float m_wipe_area;
- // Current Z position.
- float m_z_pos = 0.f;
- // Current layer height.
- float m_layer_height = 0.f;
- // Maximum number of color changes per layer.
- size_t m_max_color_changes = 0;
- // Is this the 1st layer of the print? If so, print the brim around the waste tower.
- bool m_is_first_layer = false;
- // Is this the last layer of this waste tower?
- bool m_is_last_layer = false;
+
+ const bool m_peters_wipe_tower = false; // sparse wipe tower inspired by Peter's post processor - not finished yet
+ const float Filament_Area = M_PI * 1.75f * 1.75f / 4.f; // filament area in mm^2
+ const float Width_To_Nozzle_Ratio = 1.25f; // desired line width (oval) in multiples of nozzle diameter - may not be actually neccessary to adjust
+ const float WT_EPSILON = 1e-3f;
+
+
+ xy m_wipe_tower_pos; // Left front corner of the wipe tower in mm.
+ float m_wipe_tower_width; // Width of the wipe tower.
+ float m_wipe_tower_depth = 0.f; // Depth of the wipe tower
+ float m_wipe_tower_rotation_angle = 0.f; // Wipe tower rotation angle in degrees (with respect to x axis)
+ float m_internal_rotation = 0.f;
+ float m_y_shift = 0.f; // y shift passed to writer
+ float m_z_pos = 0.f; // Current Z position.
+ float m_layer_height = 0.f; // Current layer height.
+ size_t m_max_color_changes = 0; // Maximum number of color changes per layer.
+ bool m_is_first_layer = false;// Is this the 1st layer of the print? If so, print the brim around the waste tower.
+ int m_old_temperature = -1; // To keep track of what was the last temp that we set (so we don't issue the command when not neccessary)
// G-code generator parameters.
- float m_zhop = 0.5f;
- float m_retract = 4.f;
- // Width of an extrusion line, also a perimeter spacing for 100% infill.
- float m_perimeter_width = 0.5f;
- // Extrusion flow is derived from m_perimeter_width, layer height and filament diameter.
- float m_extrusion_flow = 0.029f;
+ float m_cooling_tube_retraction = 0.f;
+ float m_cooling_tube_length = 0.f;
+ float m_parking_pos_retraction = 0.f;
+ float m_extra_loading_move = 0.f;
+ float m_bridging = 0.f;
+ bool m_adhesion = true;
+
+ float m_perimeter_width = 0.4 * Width_To_Nozzle_Ratio; // Width of an extrusion line, also a perimeter spacing for 100% infill.
+ float m_extrusion_flow = 0.038; //0.029f;// Extrusion flow is derived from m_perimeter_width, layer height and filament diameter.
+
+
+ struct FilamentParameters {
+ material_type material = PLA;
+ int temperature = 0;
+ int first_layer_temperature = 0;
+ float loading_speed = 0.f;
+ float loading_speed_start = 0.f;
+ float unloading_speed = 0.f;
+ float unloading_speed_start = 0.f;
+ float delay = 0.f ;
+ int cooling_moves = 0;
+ float cooling_initial_speed = 0.f;
+ float cooling_final_speed = 0.f;
+ float ramming_line_width_multiplicator = 0.f;
+ float ramming_step_multiplicator = 0.f;
+ std::vector<float> ramming_speed;
+ float nozzle_diameter;
+ };
// Extruder specific parameters.
- material_type m_material[4];
- int m_temperature[4];
- int m_first_layer_temperature[4];
-
- // State of the wiper tower generator.
- // Layer change counter for the output statistics.
- unsigned int m_num_layer_changes = 0;
- // Tool change change counter for the output statistics.
- unsigned int m_num_tool_changes = 0;
- // Layer change counter in this layer. Counting up to m_max_color_changes.
- unsigned int m_idx_tool_change_in_layer = 0;
+ std::vector<FilamentParameters> m_filpar;
+
+
+ // State of the wipe tower generator.
+ unsigned int m_num_layer_changes = 0; // Layer change counter for the output statistics.
+ unsigned int m_num_tool_changes = 0; // Tool change change counter for the output statistics.
+ ///unsigned int m_idx_tool_change_in_layer = 0; // Layer change counter in this layer. Counting up to m_max_color_changes.
+ bool m_print_brim = true;
// A fill-in direction (positive Y, negative Y) alternates with each layer.
wipe_shape m_current_shape = SHAPE_NORMAL;
unsigned int m_current_tool = 0;
- // Current y position at the wipe tower.
- float m_current_wipe_start_y = 0.f;
- // How much to wipe the 1st extruder over the wipe tower at the 1st layer
- // after the wipe tower brim has been extruded?
- float m_initial_extra_wipe = 0.f;
+ const std::vector<std::vector<float>> wipe_volumes;
+
+ float m_depth_traversed = 0.f; // Current y position at the wipe tower.
+ bool m_left_to_right = true;
+ float m_extra_spacing = 1.f;
+
+ // Calculates extrusion flow needed to produce required line width for given layer height
+ float extrusion_flow(float layer_height = -1.f) const // negative layer_height - return current m_extrusion_flow
+ {
+ if ( layer_height < 0 )
+ return m_extrusion_flow;
+ return layer_height * ( m_perimeter_width - layer_height * (1-M_PI/4.f)) / Filament_Area;
+ }
+
+ // Calculates length of extrusion line to extrude given volume
+ float volume_to_length(float volume, float line_width, float layer_height) const {
+ return std::max(0., volume / (layer_height * (line_width - layer_height * (1. - M_PI / 4.))));
+ }
+
+ // Calculates depth for all layers and propagates them downwards
+ void plan_tower();
+
+ // Goes through m_plan and recalculates depths and width of the WT to make it exactly square - experimental
+ void make_wipe_tower_square();
+
+ // Goes through m_plan, calculates border and finish_layer extrusions and subtracts them from last wipe
+ void save_on_last_wipe();
+
struct box_coordinates
{
@@ -216,14 +299,43 @@ private:
}
xy ld; // left down
xy lu; // left upper
- xy ru; // right upper
xy rd; // right lower
+ xy ru; // right upper
+ };
+
+
+ // to store information about tool changes for a given layer
+ struct WipeTowerInfo{
+ struct ToolChange {
+ unsigned int old_tool;
+ unsigned int new_tool;
+ float required_depth;
+ float ramming_depth;
+ float first_wipe_line;
+ float wipe_volume;
+ ToolChange(unsigned int old, unsigned int newtool, float depth=0.f, float ramming_depth=0.f, float fwl=0.f, float wv=0.f)
+ : old_tool{old}, new_tool{newtool}, required_depth{depth}, ramming_depth{ramming_depth}, first_wipe_line{fwl}, wipe_volume{wv} {}
+ };
+ float z; // z position of the layer
+ float height; // layer height
+ float depth; // depth of the layer based on all layers above
+ float extra_spacing;
+ float toolchanges_depth() const { float sum = 0.f; for (const auto &a : tool_changes) sum += a.required_depth; return sum; }
+
+ std::vector<ToolChange> tool_changes;
+
+ WipeTowerInfo(float z_par, float layer_height_par)
+ : z{z_par}, height{layer_height_par}, depth{0}, extra_spacing{1.f} {}
};
+ std::vector<WipeTowerInfo> m_plan; // Stores information about all layers and toolchanges for the future wipe tower (filled by plan_toolchange(...))
+ std::vector<WipeTowerInfo>::iterator m_layer_info = m_plan.end();
+
+
// Returns gcode for wipe tower brim
- // sideOnly -- set to false -- experimental, draw brim on sides of wipe tower
+ // sideOnly -- set to false -- experimental, draw brim on sides of wipe tower
// offset -- set to 0 -- experimental, offset to replace brim in front / rear of wipe tower
- ToolChangeResult toolchange_Brim(Purpose purpose, bool sideOnly = false, float y_offset = 0.f);
+ ToolChangeResult toolchange_Brim(bool sideOnly = false, float y_offset = 0.f);
void toolchange_Unload(
PrusaMultiMaterial::Writer &writer,
@@ -243,11 +355,12 @@ private:
void toolchange_Wipe(
PrusaMultiMaterial::Writer &writer,
const box_coordinates &cleaning_box,
- bool skip_initial_y_move);
-
- void toolchange_Perimeter();
+ float wipe_volume);
};
+
+
+
}; // namespace Slic3r
#endif /* WipeTowerPrusaMM_hpp_ */
diff --git a/xs/src/libslic3r/GCodeReader.cpp b/xs/src/libslic3r/GCodeReader.cpp
index c1e1e98be..51853e9fa 100644
--- a/xs/src/libslic3r/GCodeReader.cpp
+++ b/xs/src/libslic3r/GCodeReader.cpp
@@ -114,6 +114,28 @@ void GCodeReader::parse_file(const std::string &file, callback_t callback)
this->parse_line(line, callback);
}
+bool GCodeReader::GCodeLine::has(char axis) const
+{
+ const char *c = m_raw.c_str();
+ // Skip the whitespaces.
+ c = skip_whitespaces(c);
+ // Skip the command.
+ c = skip_word(c);
+ // Up to the end of line or comment.
+ while (! is_end_of_gcode_line(*c)) {
+ // Skip whitespaces.
+ c = skip_whitespaces(c);
+ if (is_end_of_gcode_line(*c))
+ break;
+ // Check the name of the axis.
+ if (*c == axis)
+ return true;
+ // Skip the rest of the word.
+ c = skip_word(c);
+ }
+ return false;
+}
+
bool GCodeReader::GCodeLine::has_value(char axis, float &value) const
{
const char *c = m_raw.c_str();
diff --git a/xs/src/libslic3r/GCodeReader.hpp b/xs/src/libslic3r/GCodeReader.hpp
index 102cbd27a..84ed89a7c 100644
--- a/xs/src/libslic3r/GCodeReader.hpp
+++ b/xs/src/libslic3r/GCodeReader.hpp
@@ -27,6 +27,7 @@ public:
bool has(Axis axis) const { return (m_mask & (1 << int(axis))) != 0; }
float value(Axis axis) const { return m_axis[axis]; }
+ bool has(char axis) const;
bool has_value(char axis, float &value) const;
float new_Z(const GCodeReader &reader) const { return this->has(Z) ? this->z() : reader.z(); }
float new_E(const GCodeReader &reader) const { return this->has(E) ? this->e() : reader.e(); }
diff --git a/xs/src/libslic3r/GCodeSender.cpp b/xs/src/libslic3r/GCodeSender.cpp
index bbeaf836d..0988091ce 100644
--- a/xs/src/libslic3r/GCodeSender.cpp
+++ b/xs/src/libslic3r/GCodeSender.cpp
@@ -2,6 +2,7 @@
#include <iostream>
#include <istream>
#include <string>
+#include <thread>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
@@ -41,6 +42,7 @@ struct termios2 {
//#define DEBUG_SERIAL
#ifdef DEBUG_SERIAL
+#include <cstdlib>
#include <fstream>
std::fstream fs;
#endif
@@ -52,7 +54,11 @@ namespace Slic3r {
GCodeSender::GCodeSender()
: io(), serial(io), can_send(false), sent(0), open(false), error(false),
connected(false), queue_paused(false)
-{}
+{
+#ifdef DEBUG_SERIAL
+ std::srand(std::time(nullptr));
+#endif
+}
GCodeSender::~GCodeSender()
{
@@ -358,15 +364,23 @@ GCodeSender::on_read(const boost::system::error_code& error,
// extract the first number from line
boost::algorithm::trim_left_if(line, !boost::algorithm::is_digit());
size_t toresend = boost::lexical_cast<size_t>(line.substr(0, line.find_first_not_of("0123456789")));
- ++ toresend; // N is 0-based
- if (toresend >= this->sent - this->last_sent.size() && toresend < this->last_sent.size()) {
+
+#ifdef DEBUG_SERIAL
+ fs << "!! line num out of sync: toresend = " << toresend << ", sent = " << sent << ", last_sent.size = " << last_sent.size() << std::endl;
+#endif
+
+ if (toresend > this->sent - this->last_sent.size() && toresend <= this->sent) {
{
boost::lock_guard<boost::mutex> l(this->queue_mutex);
+ const auto lines_to_resend = this->sent - toresend + 1;
+#ifdef DEBUG_SERIAL
+ fs << "!! resending " << lines_to_resend << " lines" << std::endl;
+#endif
// move the unsent lines to priqueue
this->priqueue.insert(
this->priqueue.begin(), // insert at the beginning
- this->last_sent.begin() + toresend - (this->sent - this->last_sent.size()) - 1,
+ this->last_sent.begin() + this->last_sent.size() - lines_to_resend,
this->last_sent.end()
);
@@ -477,8 +491,14 @@ GCodeSender::do_send()
if (line.empty()) return;
// compute full line
- std::string full_line = "N" + boost::lexical_cast<std::string>(this->sent) + " " + line;
++ this->sent;
+#ifndef DEBUG_SERIAL
+ const auto line_num = this->sent;
+#else
+ // In DEBUG_SERIAL mode, test line re-synchronization by sending bad line number 1/4 of the time
+ const auto line_num = std::rand() < RAND_MAX/4 ? 0 : this->sent;
+#endif
+ std::string full_line = "N" + boost::lexical_cast<std::string>(line_num) + " " + line;
// calculate checksum
int cs = 0;
@@ -497,8 +517,9 @@ GCodeSender::do_send()
this->last_sent.push_back(line);
this->can_send = false;
- if (this->last_sent.size() > KEEP_SENT)
- this->last_sent.erase(this->last_sent.begin(), this->last_sent.end() - KEEP_SENT);
+ while (this->last_sent.size() > KEEP_SENT) {
+ this->last_sent.pop_front();
+ }
// we can't supply boost::asio::buffer(full_line) to async_write() because full_line is on the
// stack and the buffer would lose its underlying storage causing memory corruption
@@ -548,16 +569,12 @@ GCodeSender::set_DTR(bool on)
void
GCodeSender::reset()
{
- this->set_DTR(false);
- boost::this_thread::sleep(boost::posix_time::milliseconds(200));
- this->set_DTR(true);
- boost::this_thread::sleep(boost::posix_time::milliseconds(200));
- this->set_DTR(false);
- boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
- {
- boost::lock_guard<boost::mutex> l(this->queue_mutex);
- this->can_send = true;
- }
+ set_DTR(false);
+ std::this_thread::sleep_for(std::chrono::milliseconds(200));
+ set_DTR(true);
+ std::this_thread::sleep_for(std::chrono::milliseconds(200));
+ set_DTR(false);
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
} // namespace Slic3r
diff --git a/xs/src/libslic3r/GCodeSender.hpp b/xs/src/libslic3r/GCodeSender.hpp
index 3022993cb..d7663ca55 100644
--- a/xs/src/libslic3r/GCodeSender.hpp
+++ b/xs/src/libslic3r/GCodeSender.hpp
@@ -51,7 +51,7 @@ class GCodeSender : private boost::noncopyable {
bool can_send;
bool queue_paused;
size_t sent;
- std::vector<std::string> last_sent;
+ std::deque<std::string> last_sent;
// this mutex guards log, T, B
mutable boost::mutex log_mutex;
diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp
index 912799ca9..7471367fe 100644
--- a/xs/src/libslic3r/GCodeTimeEstimator.cpp
+++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp
@@ -4,15 +4,20 @@
#include <Shiny/Shiny.h>
+#include <boost/nowide/fstream.hpp>
+#include <boost/nowide/cstdio.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+
static const float MMMIN_TO_MMSEC = 1.0f / 60.0f;
static const float MILLISEC_TO_SEC = 0.001f;
static const float INCHES_TO_MM = 25.4f;
+
static const float DEFAULT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp)
static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2
static const float DEFAULT_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2
static const float DEFAULT_AXIS_MAX_FEEDRATE[] = { 500.0f, 500.0f, 12.0f, 120.0f }; // Prusa Firmware 1_75mm_MK2
static const float DEFAULT_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 500.0f, 10000.0f }; // Prusa Firmware 1_75mm_MK2
-static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // from Prusa Firmware (Configuration.h)
+static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.4f, 2.5f }; // from Prusa Firmware (Configuration.h)
static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h)
static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h)
static const float DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent
@@ -73,6 +78,10 @@ namespace Slic3r {
return ::sqrt(value);
}
+ GCodeTimeEstimator::Block::Block()
+ {
+ }
+
float GCodeTimeEstimator::Block::move_length() const
{
float length = ::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z]));
@@ -159,12 +168,51 @@ namespace Slic3r {
}
#endif // ENABLE_MOVE_STATS
- GCodeTimeEstimator::GCodeTimeEstimator()
+ const std::string GCodeTimeEstimator::Normal_First_M73_Output_Placeholder_Tag = "; NORMAL_FIRST_M73_OUTPUT_PLACEHOLDER";
+ const std::string GCodeTimeEstimator::Silent_First_M73_Output_Placeholder_Tag = "; SILENT_FIRST_M73_OUTPUT_PLACEHOLDER";
+
+ GCodeTimeEstimator::GCodeTimeEstimator(EMode mode)
+ : _mode(mode)
{
reset();
set_default();
}
+ void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line)
+ {
+ PROFILE_FUNC();
+ _parser.parse_line(gcode_line,
+ [this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
+ { this->_process_gcode_line(reader, line); });
+ }
+
+ void GCodeTimeEstimator::add_gcode_block(const char *ptr)
+ {
+ PROFILE_FUNC();
+ GCodeReader::GCodeLine gline;
+ auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
+ { this->_process_gcode_line(reader, line); };
+ for (; *ptr != 0;) {
+ gline.reset();
+ ptr = _parser.parse_line(ptr, gline, action);
+ }
+ }
+
+ void GCodeTimeEstimator::calculate_time(bool start_from_beginning)
+ {
+ PROFILE_FUNC();
+ if (start_from_beginning)
+ {
+ _reset_time();
+ _last_st_synchronized_block_id = -1;
+ }
+ _calculate_time();
+
+#if ENABLE_MOVE_STATS
+ _log_moves_stats();
+#endif // ENABLE_MOVE_STATS
+ }
+
void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode)
{
reset();
@@ -178,9 +226,6 @@ namespace Slic3r {
#if ENABLE_MOVE_STATS
_log_moves_stats();
#endif // ENABLE_MOVE_STATS
-
- _reset_blocks();
- _reset();
}
void GCodeTimeEstimator::calculate_time_from_file(const std::string& file)
@@ -193,9 +238,6 @@ namespace Slic3r {
#if ENABLE_MOVE_STATS
_log_moves_stats();
#endif // ENABLE_MOVE_STATS
-
- _reset_blocks();
- _reset();
}
void GCodeTimeEstimator::calculate_time_from_lines(const std::vector<std::string>& gcode_lines)
@@ -211,42 +253,126 @@ namespace Slic3r {
#if ENABLE_MOVE_STATS
_log_moves_stats();
#endif // ENABLE_MOVE_STATS
-
- _reset_blocks();
- _reset();
}
- void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line)
+ bool GCodeTimeEstimator::post_process_remaining_times(const std::string& filename, float interval)
{
- PROFILE_FUNC();
- _parser.parse_line(gcode_line,
- [this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
- { this->_process_gcode_line(reader, line); });
- }
+ boost::nowide::ifstream in(filename);
+ if (!in.good())
+ throw std::runtime_error(std::string("Remaining times export failed.\nCannot open file for reading.\n"));
- void GCodeTimeEstimator::add_gcode_block(const char *ptr)
- {
- PROFILE_FUNC();
- GCodeReader::GCodeLine gline;
- auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line)
- { this->_process_gcode_line(reader, line); };
- for (; *ptr != 0;) {
- gline.reset();
- ptr = _parser.parse_line(ptr, gline, action);
+ std::string path_tmp = filename + ".times";
+
+ FILE* out = boost::nowide::fopen(path_tmp.c_str(), "wb");
+ if (out == nullptr)
+ throw std::runtime_error(std::string("Remaining times export failed.\nCannot open file for writing.\n"));
+
+ std::string time_mask;
+ switch (_mode)
+ {
+ default:
+ case Normal:
+ {
+ time_mask = "M73 P%s R%s\n";
+ break;
+ }
+ case Silent:
+ {
+ time_mask = "M73 Q%s S%s\n";
+ break;
+ }
}
- }
- void GCodeTimeEstimator::calculate_time()
- {
- PROFILE_FUNC();
- _calculate_time();
+ unsigned int g1_lines_count = 0;
+ float last_recorded_time = 0.0f;
+ std::string gcode_line;
+ // buffer line to export only when greater than 64K to reduce writing calls
+ std::string export_line;
+ char time_line[64];
+ while (std::getline(in, gcode_line))
+ {
+ if (!in.good())
+ {
+ fclose(out);
+ throw std::runtime_error(std::string("Remaining times export failed.\nError while reading from file.\n"));
+ }
-#if ENABLE_MOVE_STATS
- _log_moves_stats();
-#endif // ENABLE_MOVE_STATS
+ // replaces placeholders for initial line M73 with the real lines
+ if (((_mode == Normal) && (gcode_line == Normal_First_M73_Output_Placeholder_Tag)) ||
+ ((_mode == Silent) && (gcode_line == Silent_First_M73_Output_Placeholder_Tag)))
+ {
+ sprintf(time_line, time_mask.c_str(), "0", _get_time_minutes(_time).c_str());
+ gcode_line = time_line;
+ }
+ else
+ gcode_line += "\n";
- _reset_blocks();
- _reset();
+ // add remaining time lines where needed
+ _parser.parse_line(gcode_line,
+ [this, &g1_lines_count, &last_recorded_time, &time_line, &gcode_line, time_mask, interval](GCodeReader& reader, const GCodeReader::GCodeLine& line)
+ {
+ if (line.cmd_is("G1"))
+ {
+ ++g1_lines_count;
+
+ if (!line.has_e())
+ return;
+
+ G1LineIdToBlockIdMap::const_iterator it = _g1_line_ids.find(g1_lines_count);
+ if ((it != _g1_line_ids.end()) && (it->second < (unsigned int)_blocks.size()))
+ {
+ const Block& block = _blocks[it->second];
+ if (block.elapsed_time != -1.0f)
+ {
+ float block_remaining_time = _time - block.elapsed_time;
+ if (std::abs(last_recorded_time - block_remaining_time) > interval)
+ {
+ sprintf(time_line, time_mask.c_str(), std::to_string((int)(100.0f * block.elapsed_time / _time)).c_str(), _get_time_minutes(block_remaining_time).c_str());
+ gcode_line += time_line;
+
+ last_recorded_time = block_remaining_time;
+ }
+ }
+ }
+ }
+ });
+
+ export_line += gcode_line;
+ if (export_line.length() > 65535)
+ {
+ fwrite((const void*)export_line.c_str(), 1, export_line.length(), out);
+ if (ferror(out))
+ {
+ in.close();
+ fclose(out);
+ boost::nowide::remove(path_tmp.c_str());
+ throw std::runtime_error(std::string("Remaining times export failed.\nIs the disk full?\n"));
+ }
+ export_line.clear();
+ }
+ }
+
+ if (export_line.length() > 0)
+ {
+ fwrite((const void*)export_line.c_str(), 1, export_line.length(), out);
+ if (ferror(out))
+ {
+ in.close();
+ fclose(out);
+ boost::nowide::remove(path_tmp.c_str());
+ throw std::runtime_error(std::string("Remaining times export failed.\nIs the disk full?\n"));
+ }
+ }
+
+ fclose(out);
+ in.close();
+
+ boost::nowide::remove(filename.c_str());
+ if (boost::nowide::rename(path_tmp.c_str(), filename.c_str()) != 0)
+ throw std::runtime_error(std::string("Failed to rename the output G-code file from ") + path_tmp + " to " + filename + '\n' +
+ "Is " + path_tmp + " locked?" + '\n');
+
+ return true;
}
void GCodeTimeEstimator::set_axis_position(EAxis axis, float position)
@@ -301,7 +427,10 @@ namespace Slic3r {
void GCodeTimeEstimator::set_acceleration(float acceleration_mm_sec2)
{
- _state.acceleration = acceleration_mm_sec2;
+ _state.acceleration = (_state.max_acceleration == 0) ?
+ acceleration_mm_sec2 :
+ // Clamp the acceleration with the maximum.
+ std::min(_state.max_acceleration, acceleration_mm_sec2);
}
float GCodeTimeEstimator::get_acceleration() const
@@ -309,6 +438,18 @@ namespace Slic3r {
return _state.acceleration;
}
+ void GCodeTimeEstimator::set_max_acceleration(float acceleration_mm_sec2)
+ {
+ _state.max_acceleration = acceleration_mm_sec2;
+ if (acceleration_mm_sec2 > 0)
+ _state.acceleration = acceleration_mm_sec2;
+ }
+
+ float GCodeTimeEstimator::get_max_acceleration() const
+ {
+ return _state.max_acceleration;
+ }
+
void GCodeTimeEstimator::set_retract_acceleration(float acceleration_mm_sec2)
{
_state.retract_acceleration = acceleration_mm_sec2;
@@ -339,6 +480,40 @@ namespace Slic3r {
return _state.minimum_travel_feedrate;
}
+ void GCodeTimeEstimator::set_filament_load_times(const std::vector<double> &filament_load_times)
+ {
+ _state.filament_load_times.clear();
+ for (double t : filament_load_times)
+ _state.filament_load_times.push_back(t);
+ }
+
+ void GCodeTimeEstimator::set_filament_unload_times(const std::vector<double> &filament_unload_times)
+ {
+ _state.filament_unload_times.clear();
+ for (double t : filament_unload_times)
+ _state.filament_unload_times.push_back(t);
+ }
+
+ float GCodeTimeEstimator::get_filament_load_time(unsigned int id_extruder)
+ {
+ return
+ (_state.filament_load_times.empty() || id_extruder == _state.extruder_id_unloaded) ?
+ 0 :
+ (_state.filament_load_times.size() <= id_extruder) ?
+ _state.filament_load_times.front() :
+ _state.filament_load_times[id_extruder];
+ }
+
+ float GCodeTimeEstimator::get_filament_unload_time(unsigned int id_extruder)
+ {
+ return
+ (_state.filament_unload_times.empty() || id_extruder == _state.extruder_id_unloaded) ?
+ 0 :
+ (_state.filament_unload_times.size() <= id_extruder) ?
+ _state.filament_unload_times.front() :
+ _state.filament_unload_times[id_extruder];
+ }
+
void GCodeTimeEstimator::set_extrude_factor_override_percentage(float percentage)
{
_state.extrude_factor_override_percentage = percentage;
@@ -356,6 +531,7 @@ namespace Slic3r {
GCodeFlavor GCodeTimeEstimator::get_dialect() const
{
+ PROFILE_FUNC();
return _state.dialect;
}
@@ -369,28 +545,61 @@ namespace Slic3r {
return _state.units;
}
- void GCodeTimeEstimator::set_positioning_xyz_type(GCodeTimeEstimator::EPositioningType type)
+ void GCodeTimeEstimator::set_global_positioning_type(GCodeTimeEstimator::EPositioningType type)
+ {
+ _state.global_positioning_type = type;
+ }
+
+ GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_global_positioning_type() const
+ {
+ return _state.global_positioning_type;
+ }
+
+ void GCodeTimeEstimator::set_e_local_positioning_type(GCodeTimeEstimator::EPositioningType type)
+ {
+ _state.e_local_positioning_type = type;
+ }
+
+ GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_e_local_positioning_type() const
+ {
+ return _state.e_local_positioning_type;
+ }
+
+ int GCodeTimeEstimator::get_g1_line_id() const
{
- _state.positioning_xyz_type = type;
+ return _state.g1_line_id;
}
- GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_positioning_xyz_type() const
+ void GCodeTimeEstimator::increment_g1_line_id()
{
- return _state.positioning_xyz_type;
+ ++_state.g1_line_id;
}
- void GCodeTimeEstimator::set_positioning_e_type(GCodeTimeEstimator::EPositioningType type)
+ void GCodeTimeEstimator::reset_g1_line_id()
{
- _state.positioning_e_type = type;
+ _state.g1_line_id = 0;
}
- GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_positioning_e_type() const
+ void GCodeTimeEstimator::set_extruder_id(unsigned int id)
{
- return _state.positioning_e_type;
+ _state.extruder_id = id;
+ }
+
+ unsigned int GCodeTimeEstimator::get_extruder_id() const
+ {
+ return _state.extruder_id;
+ }
+
+ void GCodeTimeEstimator::reset_extruder_id()
+ {
+ // Set the initial extruder ID to unknown. For the multi-material setup it means
+ // that all the filaments are parked in the MMU and no filament is loaded yet.
+ _state.extruder_id = _state.extruder_id_unloaded;
}
void GCodeTimeEstimator::add_additional_time(float timeSec)
{
+ PROFILE_FUNC();
_state.additional_time += timeSec;
}
@@ -408,16 +617,19 @@ namespace Slic3r {
{
set_units(Millimeters);
set_dialect(gcfRepRap);
- set_positioning_xyz_type(Absolute);
- set_positioning_e_type(Relative);
+ set_global_positioning_type(Absolute);
+ set_e_local_positioning_type(Absolute);
set_feedrate(DEFAULT_FEEDRATE);
+ // Setting the maximum acceleration to zero means that the there is no limit and the G-code
+ // is allowed to set excessive values.
+ set_max_acceleration(0);
set_acceleration(DEFAULT_ACCELERATION);
set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION);
set_minimum_feedrate(DEFAULT_MINIMUM_FEEDRATE);
set_minimum_travel_feedrate(DEFAULT_MINIMUM_TRAVEL_FEEDRATE);
set_extrude_factor_override_percentage(DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE);
-
+
for (unsigned char a = X; a < Num_Axis; ++a)
{
EAxis axis = (EAxis)a;
@@ -425,11 +637,14 @@ namespace Slic3r {
set_axis_max_acceleration(axis, DEFAULT_AXIS_MAX_ACCELERATION[a]);
set_axis_max_jerk(axis, DEFAULT_AXIS_MAX_JERK[a]);
}
+
+ _state.filament_load_times.clear();
+ _state.filament_unload_times.clear();
}
void GCodeTimeEstimator::reset()
{
- _time = 0.0f;
+ _reset_time();
#if ENABLE_MOVE_STATS
_moves_stats.clear();
#endif // ENABLE_MOVE_STATS
@@ -442,23 +657,14 @@ namespace Slic3r {
return _time;
}
- std::string GCodeTimeEstimator::get_time_hms() const
+ std::string GCodeTimeEstimator::get_time_dhms() const
{
- float timeinsecs = get_time();
- int hours = (int)(timeinsecs / 3600.0f);
- timeinsecs -= (float)hours * 3600.0f;
- int minutes = (int)(timeinsecs / 60.0f);
- timeinsecs -= (float)minutes * 60.0f;
-
- char buffer[64];
- if (hours > 0)
- ::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)timeinsecs);
- else if (minutes > 0)
- ::sprintf(buffer, "%dm %ds", minutes, (int)timeinsecs);
- else
- ::sprintf(buffer, "%ds", (int)timeinsecs);
+ return _get_time_dhms(get_time());
+ }
- return buffer;
+ std::string GCodeTimeEstimator::get_time_minutes() const
+ {
+ return _get_time_minutes(get_time());
}
void GCodeTimeEstimator::_reset()
@@ -471,6 +677,17 @@ namespace Slic3r {
set_axis_position(Z, 0.0f);
set_additional_time(0.0f);
+
+ reset_extruder_id();
+ reset_g1_line_id();
+ _g1_line_ids.clear();
+
+ _last_st_synchronized_block_id = -1;
+ }
+
+ void GCodeTimeEstimator::_reset_time()
+ {
+ _time = 0.0f;
}
void GCodeTimeEstimator::_reset_blocks()
@@ -478,22 +695,27 @@ namespace Slic3r {
_blocks.clear();
}
+
void GCodeTimeEstimator::_calculate_time()
{
+ PROFILE_FUNC();
_forward_pass();
_reverse_pass();
_recalculate_trapezoids();
_time += get_additional_time();
- for (const Block& block : _blocks)
+ for (int i = _last_st_synchronized_block_id + 1; i < (int)_blocks.size(); ++i)
{
+ Block& block = _blocks[i];
+
#if ENABLE_MOVE_STATS
float block_time = 0.0f;
block_time += block.acceleration_time();
block_time += block.cruise_time();
block_time += block.deceleration_time();
_time += block_time;
+ block.elapsed_time = _time;
MovesStatsMap::iterator it = _moves_stats.find(block.move_type);
if (it == _moves_stats.end())
@@ -505,8 +727,13 @@ namespace Slic3r {
_time += block.acceleration_time();
_time += block.cruise_time();
_time += block.deceleration_time();
+ block.elapsed_time = _time;
#endif // ENABLE_MOVE_STATS
}
+
+ _last_st_synchronized_block_id = _blocks.size() - 1;
+ // The additional time has been consumed (added to the total time), reset it to zero.
+ set_additional_time(0.);
}
void GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line)
@@ -619,22 +846,32 @@ namespace Slic3r {
_processM566(line);
break;
}
+ case 702: // MK3 MMU2: Process the final filament unload.
+ {
+ _processM702(line);
+ break;
+ }
}
break;
}
+ case 'T': // Select Tools
+ {
+ _processT(line);
+ break;
+ }
}
}
}
// Returns the new absolute position on the given axis in dependence of the given parameters
- float axis_absolute_position_from_G1_line(GCodeTimeEstimator::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeTimeEstimator::EUnits units, GCodeTimeEstimator::EPositioningType type, float current_absolute_position)
+ float axis_absolute_position_from_G1_line(GCodeTimeEstimator::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeTimeEstimator::EUnits units, bool is_relative, float current_absolute_position)
{
float lengthsScaleFactor = (units == GCodeTimeEstimator::Inches) ? INCHES_TO_MM : 1.0f;
if (lineG1.has(Slic3r::Axis(axis)))
{
float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor;
- return (type == GCodeTimeEstimator::Absolute) ? ret : current_absolute_position + ret;
+ return is_relative ? current_absolute_position + ret : ret;
}
else
return current_absolute_position;
@@ -642,12 +879,19 @@ namespace Slic3r {
void GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
+ increment_g1_line_id();
+
// updates axes positions from line
EUnits units = get_units();
float new_pos[Num_Axis];
for (unsigned char a = X; a < Num_Axis; ++a)
{
- new_pos[a] = axis_absolute_position_from_G1_line((EAxis)a, line, units, (a == E) ? get_positioning_e_type() : get_positioning_xyz_type(), get_axis_position((EAxis)a));
+ bool is_relative = (get_global_positioning_type() == Relative);
+ if (a == E)
+ is_relative |= (get_e_local_positioning_type() == Relative);
+
+ new_pos[a] = axis_absolute_position_from_G1_line((EAxis)a, line, units, is_relative, get_axis_position((EAxis)a));
}
// updates feedrate from line, if present
@@ -686,13 +930,16 @@ namespace Slic3r {
if (_curr.abs_axis_feedrate[a] > 0.0f)
min_feedrate_factor = std::min(min_feedrate_factor, get_axis_max_feedrate((EAxis)a) / _curr.abs_axis_feedrate[a]);
}
-
+
block.feedrate.cruise = min_feedrate_factor * _curr.feedrate;
- for (unsigned char a = X; a < Num_Axis; ++a)
+ if (min_feedrate_factor < 1.0f)
{
- _curr.axis_feedrate[a] *= min_feedrate_factor;
- _curr.abs_axis_feedrate[a] *= min_feedrate_factor;
+ for (unsigned char a = X; a < Num_Axis; ++a)
+ {
+ _curr.axis_feedrate[a] *= min_feedrate_factor;
+ _curr.abs_axis_feedrate[a] *= min_feedrate_factor;
+ }
}
// calculates block acceleration
@@ -825,10 +1072,12 @@ namespace Slic3r {
// adds block to blocks list
_blocks.emplace_back(block);
+ _g1_line_ids.insert(G1LineIdToBlockIdMap::value_type(get_g1_line_id(), (unsigned int)_blocks.size() - 1));
}
void GCodeTimeEstimator::_processG4(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
GCodeFlavor dialect = get_dialect();
float value;
@@ -850,33 +1099,37 @@ namespace Slic3r {
void GCodeTimeEstimator::_processG20(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
set_units(Inches);
}
void GCodeTimeEstimator::_processG21(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
set_units(Millimeters);
}
void GCodeTimeEstimator::_processG28(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
// TODO
}
void GCodeTimeEstimator::_processG90(const GCodeReader::GCodeLine& line)
{
- set_positioning_xyz_type(Absolute);
+ PROFILE_FUNC();
+ set_global_positioning_type(Absolute);
}
void GCodeTimeEstimator::_processG91(const GCodeReader::GCodeLine& line)
{
- // TODO: THERE ARE DIALECT VARIANTS
-
- set_positioning_xyz_type(Relative);
+ PROFILE_FUNC();
+ set_global_positioning_type(Relative);
}
void GCodeTimeEstimator::_processG92(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
float lengthsScaleFactor = (get_units() == Inches) ? INCHES_TO_MM : 1.0f;
bool anyFound = false;
@@ -917,26 +1170,31 @@ namespace Slic3r {
void GCodeTimeEstimator::_processM1(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
_simulate_st_synchronize();
}
void GCodeTimeEstimator::_processM82(const GCodeReader::GCodeLine& line)
{
- set_positioning_e_type(Absolute);
+ PROFILE_FUNC();
+ set_e_local_positioning_type(Absolute);
}
void GCodeTimeEstimator::_processM83(const GCodeReader::GCodeLine& line)
{
- set_positioning_e_type(Relative);
+ PROFILE_FUNC();
+ set_e_local_positioning_type(Relative);
}
void GCodeTimeEstimator::_processM109(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
// TODO
}
void GCodeTimeEstimator::_processM201(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
GCodeFlavor dialect = get_dialect();
// see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration
@@ -957,6 +1215,7 @@ namespace Slic3r {
void GCodeTimeEstimator::_processM203(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
GCodeFlavor dialect = get_dialect();
// see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate
@@ -981,16 +1240,32 @@ namespace Slic3r {
void GCodeTimeEstimator::_processM204(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
float value;
- if (line.has_value('S', value))
+ if (line.has_value('S', value)) {
+ // Legacy acceleration format. This format is used by the legacy Marlin, MK2 or MK3 firmware,
+ // and it is also generated by Slic3r to control acceleration per extrusion type
+ // (there is a separate acceleration settings in Slicer for perimeter, first layer etc).
set_acceleration(value);
-
- if (line.has_value('T', value))
- set_retract_acceleration(value);
+ if (line.has_value('T', value))
+ set_retract_acceleration(value);
+ } else {
+ // New acceleration format, compatible with the upstream Marlin.
+ if (line.has_value('P', value))
+ set_acceleration(value);
+ if (line.has_value('R', value))
+ set_retract_acceleration(value);
+ if (line.has_value('T', value)) {
+ // Interpret the T value as the travel acceleration in the new Marlin format.
+ //FIXME Prusa3D firmware currently does not support travel acceleration value independent from the extruding acceleration value.
+ // set_travel_acceleration(value);
+ }
+ }
}
void GCodeTimeEstimator::_processM205(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
if (line.has_x())
{
float max_jerk = line.x();
@@ -1017,6 +1292,7 @@ namespace Slic3r {
void GCodeTimeEstimator::_processM221(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
float value_s;
float value_t;
if (line.has_value('S', value_s) && !line.has_value('T', value_t))
@@ -1025,6 +1301,7 @@ namespace Slic3r {
void GCodeTimeEstimator::_processM566(const GCodeReader::GCodeLine& line)
{
+ PROFILE_FUNC();
if (line.has_x())
set_axis_max_jerk(X, line.x() * MMMIN_TO_MMSEC);
@@ -1038,17 +1315,49 @@ namespace Slic3r {
set_axis_max_jerk(E, line.e() * MMMIN_TO_MMSEC);
}
+ void GCodeTimeEstimator::_processM702(const GCodeReader::GCodeLine& line)
+ {
+ PROFILE_FUNC();
+ if (line.has('C')) {
+ // MK3 MMU2 specific M code:
+ // M702 C is expected to be sent by the custom end G-code when finalizing a print.
+ // The MK3 unit shall unload and park the active filament into the MMU2 unit.
+ add_additional_time(get_filament_unload_time(get_extruder_id()));
+ reset_extruder_id();
+ _simulate_st_synchronize();
+ }
+ }
+
+ void GCodeTimeEstimator::_processT(const GCodeReader::GCodeLine& line)
+ {
+ std::string cmd = line.cmd();
+ if (cmd.length() > 1)
+ {
+ unsigned int id = (unsigned int)::strtol(cmd.substr(1).c_str(), nullptr, 10);
+ if (get_extruder_id() != id)
+ {
+ // Specific to the MK3 MMU2: The initial extruder ID is set to -1 indicating
+ // that the filament is parked in the MMU2 unit and there is nothing to be unloaded yet.
+ add_additional_time(get_filament_unload_time(get_extruder_id()));
+ set_extruder_id(id);
+ add_additional_time(get_filament_load_time(get_extruder_id()));
+ _simulate_st_synchronize();
+ }
+ }
+ }
+
void GCodeTimeEstimator::_simulate_st_synchronize()
{
+ PROFILE_FUNC();
_calculate_time();
- _reset_blocks();
}
void GCodeTimeEstimator::_forward_pass()
{
+ PROFILE_FUNC();
if (_blocks.size() > 1)
{
- for (unsigned int i = 0; i < (unsigned int)_blocks.size() - 1; ++i)
+ for (int i = _last_st_synchronized_block_id + 1; i < (int)_blocks.size() - 1; ++i)
{
_planner_forward_pass_kernel(_blocks[i], _blocks[i + 1]);
}
@@ -1057,9 +1366,10 @@ namespace Slic3r {
void GCodeTimeEstimator::_reverse_pass()
{
+ PROFILE_FUNC();
if (_blocks.size() > 1)
{
- for (int i = (int)_blocks.size() - 1; i >= 1; --i)
+ for (int i = (int)_blocks.size() - 1; i >= _last_st_synchronized_block_id + 2; --i)
{
_planner_reverse_pass_kernel(_blocks[i - 1], _blocks[i]);
}
@@ -1068,6 +1378,7 @@ namespace Slic3r {
void GCodeTimeEstimator::_planner_forward_pass_kernel(Block& prev, Block& curr)
{
+ PROFILE_FUNC();
// If the previous block is an acceleration block, but it is not long enough to complete the
// full speed change within the block, we need to adjust the entry speed accordingly. Entry
// speeds have already been reset, maximized, and reverse planned by reverse planner.
@@ -1108,11 +1419,14 @@ namespace Slic3r {
void GCodeTimeEstimator::_recalculate_trapezoids()
{
+ PROFILE_FUNC();
Block* curr = nullptr;
Block* next = nullptr;
- for (Block& b : _blocks)
+ for (int i = _last_st_synchronized_block_id + 1; i < (int)_blocks.size(); ++i)
{
+ Block& b = _blocks[i];
+
curr = next;
next = &b;
@@ -1142,6 +1456,33 @@ namespace Slic3r {
}
}
+ std::string GCodeTimeEstimator::_get_time_dhms(float time_in_secs)
+ {
+ int days = (int)(time_in_secs / 86400.0f);
+ time_in_secs -= (float)days * 86400.0f;
+ int hours = (int)(time_in_secs / 3600.0f);
+ time_in_secs -= (float)hours * 3600.0f;
+ int minutes = (int)(time_in_secs / 60.0f);
+ time_in_secs -= (float)minutes * 60.0f;
+
+ char buffer[64];
+ if (days > 0)
+ ::sprintf(buffer, "%dd %dh %dm %ds", days, hours, minutes, (int)time_in_secs);
+ else if (hours > 0)
+ ::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)time_in_secs);
+ else if (minutes > 0)
+ ::sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs);
+ else
+ ::sprintf(buffer, "%ds", (int)time_in_secs);
+
+ return buffer;
+ }
+
+ std::string GCodeTimeEstimator::_get_time_minutes(float time_in_secs)
+ {
+ return std::to_string((int)(::roundf(time_in_secs / 60.0f)));
+ }
+
#if ENABLE_MOVE_STATS
void GCodeTimeEstimator::_log_moves_stats() const
{
diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp
index 5ad5b8d0c..e9da584c3 100644
--- a/xs/src/libslic3r/GCodeTimeEstimator.hpp
+++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp
@@ -17,6 +17,15 @@ namespace Slic3r {
class GCodeTimeEstimator
{
public:
+ static const std::string Normal_First_M73_Output_Placeholder_Tag;
+ static const std::string Silent_First_M73_Output_Placeholder_Tag;
+
+ enum EMode : unsigned char
+ {
+ Normal,
+ Silent
+ };
+
enum EUnits : unsigned char
{
Millimeters,
@@ -61,16 +70,27 @@ namespace Slic3r {
{
GCodeFlavor dialect;
EUnits units;
- EPositioningType positioning_xyz_type;
- EPositioningType positioning_e_type;
+ EPositioningType global_positioning_type;
+ EPositioningType e_local_positioning_type;
Axis axis[Num_Axis];
float feedrate; // mm/s
float acceleration; // mm/s^2
+ // hard limit for the acceleration, to which the firmware will clamp.
+ float max_acceleration; // mm/s^2
float retract_acceleration; // mm/s^2
float additional_time; // s
float minimum_feedrate; // mm/s
float minimum_travel_feedrate; // mm/s
- float extrude_factor_override_percentage;
+ float extrude_factor_override_percentage;
+ // Additional load / unload times for a filament exchange sequence.
+ std::vector<float> filament_load_times;
+ std::vector<float> filament_unload_times;
+ unsigned int g1_line_id;
+ // extruder_id is currently used to correctly calculate filament load / unload times
+ // into the total print time. This is currently only really used by the MK3 MMU2:
+ // Extruder id (-1) means no filament is loaded yet, all the filaments are parked in the MK3 MMU2 unit.
+ static const unsigned int extruder_id_unloaded = (unsigned int)-1;
+ unsigned int extruder_id;
};
public:
@@ -121,7 +141,6 @@ namespace Slic3r {
bool nominal_length;
};
-
#if ENABLE_MOVE_STATS
EMoveType move_type;
#endif // ENABLE_MOVE_STATS
@@ -134,6 +153,9 @@ namespace Slic3r {
FeedrateProfile feedrate;
Trapezoid trapezoid;
+ float elapsed_time;
+
+ Block();
// Returns the length of the move covered by this block, in mm
float move_length() const;
@@ -187,19 +209,39 @@ namespace Slic3r {
typedef std::map<Block::EMoveType, MoveStats> MovesStatsMap;
#endif // ENABLE_MOVE_STATS
+ typedef std::map<unsigned int, unsigned int> G1LineIdToBlockIdMap;
+
private:
+ EMode _mode;
GCodeReader _parser;
State _state;
Feedrates _curr;
Feedrates _prev;
BlocksList _blocks;
+ // Map between g1 line id and blocks id, used to speed up export of remaining times
+ G1LineIdToBlockIdMap _g1_line_ids;
+ // Index of the last block already st_synchronized
+ int _last_st_synchronized_block_id;
float _time; // s
+
#if ENABLE_MOVE_STATS
MovesStatsMap _moves_stats;
#endif // ENABLE_MOVE_STATS
public:
- GCodeTimeEstimator();
+ explicit GCodeTimeEstimator(EMode mode);
+
+ // Adds the given gcode line
+ void add_gcode_line(const std::string& gcode_line);
+
+ void add_gcode_block(const char *ptr);
+ void add_gcode_block(const std::string &str) { this->add_gcode_block(str.c_str()); }
+
+ // Calculates the time estimate from the gcode lines added using add_gcode_line() or add_gcode_block()
+ // start_from_beginning:
+ // if set to true all blocks will be used to calculate the time estimate,
+ // if set to false only the blocks not yet processed will be used and the calculated time will be added to the current calculated time
+ void calculate_time(bool start_from_beginning);
// Calculates the time estimate from the given gcode in string format
void calculate_time_from_text(const std::string& gcode);
@@ -210,14 +252,12 @@ namespace Slic3r {
// Calculates the time estimate from the gcode contained in given list of gcode lines
void calculate_time_from_lines(const std::vector<std::string>& gcode_lines);
- // Adds the given gcode line
- void add_gcode_line(const std::string& gcode_line);
-
- void add_gcode_block(const char *ptr);
- void add_gcode_block(const std::string &str) { this->add_gcode_block(str.c_str()); }
-
- // Calculates the time estimate from the gcode lines added using add_gcode_line()
- void calculate_time();
+ // Process the gcode contained in the file with the given filename,
+ // placing in it new lines (M73) containing the remaining time, at the given interval in seconds
+ // and saving the result back in the same file
+ // This time estimator should have been already used to calculate the time estimate for the gcode
+ // contained in the given file before to call this method
+ bool post_process_remaining_times(const std::string& filename, float interval_sec);
// Set current position on the given axis with the given value
void set_axis_position(EAxis axis, float position);
@@ -239,6 +279,10 @@ namespace Slic3r {
void set_acceleration(float acceleration_mm_sec2);
float get_acceleration() const;
+ // Maximum acceleration for the machine. The firmware simulator will clamp the M204 Sxxx to this maximum.
+ void set_max_acceleration(float acceleration_mm_sec2);
+ float get_max_acceleration() const;
+
void set_retract_acceleration(float acceleration_mm_sec2);
float get_retract_acceleration() const;
@@ -248,6 +292,11 @@ namespace Slic3r {
void set_minimum_travel_feedrate(float feedrate_mm_sec);
float get_minimum_travel_feedrate() const;
+ void set_filament_load_times(const std::vector<double> &filament_load_times);
+ void set_filament_unload_times(const std::vector<double> &filament_unload_times);
+ float get_filament_load_time(unsigned int id_extruder);
+ float get_filament_unload_time(unsigned int id_extruder);
+
void set_extrude_factor_override_percentage(float percentage);
float get_extrude_factor_override_percentage() const;
@@ -257,11 +306,19 @@ namespace Slic3r {
void set_units(EUnits units);
EUnits get_units() const;
- void set_positioning_xyz_type(EPositioningType type);
- EPositioningType get_positioning_xyz_type() const;
+ void set_global_positioning_type(EPositioningType type);
+ EPositioningType get_global_positioning_type() const;
- void set_positioning_e_type(EPositioningType type);
- EPositioningType get_positioning_e_type() const;
+ void set_e_local_positioning_type(EPositioningType type);
+ EPositioningType get_e_local_positioning_type() const;
+
+ int get_g1_line_id() const;
+ void increment_g1_line_id();
+ void reset_g1_line_id();
+
+ void set_extruder_id(unsigned int id);
+ unsigned int get_extruder_id() const;
+ void reset_extruder_id();
void add_additional_time(float timeSec);
void set_additional_time(float timeSec);
@@ -275,11 +332,15 @@ namespace Slic3r {
// Returns the estimated time, in seconds
float get_time() const;
- // Returns the estimated time, in format HHh MMm SSs
- std::string get_time_hms() const;
+ // Returns the estimated time, in format DDd HHh MMm SSs
+ std::string get_time_dhms() const;
+
+ // Returns the estimated time, in minutes (integer)
+ std::string get_time_minutes() const;
private:
void _reset();
+ void _reset_time();
void _reset_blocks();
// Calculates the time estimate
@@ -342,6 +403,12 @@ namespace Slic3r {
// Set allowable instantaneous speed change
void _processM566(const GCodeReader::GCodeLine& line);
+ // Unload the current filament into the MK3 MMU2 unit at the end of print.
+ void _processM702(const GCodeReader::GCodeLine& line);
+
+ // Processes T line (Select Tool)
+ void _processT(const GCodeReader::GCodeLine& line);
+
// Simulates firmware st_synchronize() call
void _simulate_st_synchronize();
@@ -353,6 +420,12 @@ namespace Slic3r {
void _recalculate_trapezoids();
+ // Returns the given time is seconds in format DDd HHh MMm SSs
+ static std::string _get_time_dhms(float time_in_secs);
+
+ // Returns the given, in minutes (integer)
+ static std::string _get_time_minutes(float time_in_secs);
+
#if ENABLE_MOVE_STATS
void _log_moves_stats() const;
#endif // ENABLE_MOVE_STATS
diff --git a/xs/src/libslic3r/GCodeWriter.cpp b/xs/src/libslic3r/GCodeWriter.cpp
index 9876a3fac..6ef17f4f4 100644
--- a/xs/src/libslic3r/GCodeWriter.cpp
+++ b/xs/src/libslic3r/GCodeWriter.cpp
@@ -19,6 +19,8 @@ void GCodeWriter::apply_print_config(const PrintConfig &print_config)
this->config.apply(print_config, true);
m_extrusion_axis = this->config.get_extrusion_axis();
m_single_extruder_multi_material = print_config.single_extruder_multi_material.value;
+ m_max_acceleration = (print_config.gcode_flavor.value == gcfMarlin) ?
+ print_config.machine_max_acceleration_extruding.values.front() : 0;
}
void GCodeWriter::set_extruders(const std::vector<unsigned int> &extruder_ids)
@@ -170,6 +172,10 @@ std::string GCodeWriter::set_fan(unsigned int speed, bool dont_save)
std::string GCodeWriter::set_acceleration(unsigned int acceleration)
{
+ // Clamp the acceleration to the allowed maximum.
+ if (m_max_acceleration > 0 && acceleration > m_max_acceleration)
+ acceleration = m_max_acceleration;
+
if (acceleration == 0 || acceleration == m_last_acceleration)
return std::string();
@@ -270,30 +276,30 @@ std::string GCodeWriter::set_speed(double F, const std::string &comment, const s
return gcode.str();
}
-std::string GCodeWriter::travel_to_xy(const Pointf &point, const std::string &comment)
+std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &comment)
{
- m_pos.x = point.x;
- m_pos.y = point.y;
+ m_pos(0) = point(0);
+ m_pos(1) = point(1);
std::ostringstream gcode;
- gcode << "G1 X" << XYZF_NUM(point.x)
- << " Y" << XYZF_NUM(point.y)
+ gcode << "G1 X" << XYZF_NUM(point(0))
+ << " Y" << XYZF_NUM(point(1))
<< " F" << XYZF_NUM(this->config.travel_speed.value * 60.0);
COMMENT(comment);
gcode << "\n";
return gcode.str();
}
-std::string GCodeWriter::travel_to_xyz(const Pointf3 &point, const std::string &comment)
+std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &comment)
{
/* If target Z is lower than current Z but higher than nominal Z we
don't perform the Z move but we only move in the XY plane and
adjust the nominal Z by reducing the lift amount that will be
used for unlift. */
- if (!this->will_move_z(point.z)) {
- double nominal_z = m_pos.z - m_lifted;
- m_lifted = m_lifted - (point.z - nominal_z);
- return this->travel_to_xy(point);
+ if (!this->will_move_z(point(2))) {
+ double nominal_z = m_pos(2) - m_lifted;
+ m_lifted = m_lifted - (point(2) - nominal_z);
+ return this->travel_to_xy(to_2d(point));
}
/* In all the other cases, we perform an actual XYZ move and cancel
@@ -302,9 +308,9 @@ std::string GCodeWriter::travel_to_xyz(const Pointf3 &point, const std::string &
m_pos = point;
std::ostringstream gcode;
- gcode << "G1 X" << XYZF_NUM(point.x)
- << " Y" << XYZF_NUM(point.y)
- << " Z" << XYZF_NUM(point.z)
+ gcode << "G1 X" << XYZF_NUM(point(0))
+ << " Y" << XYZF_NUM(point(1))
+ << " Z" << XYZF_NUM(point(2))
<< " F" << XYZF_NUM(this->config.travel_speed.value * 60.0);
COMMENT(comment);
gcode << "\n";
@@ -317,7 +323,7 @@ std::string GCodeWriter::travel_to_z(double z, const std::string &comment)
we don't perform the move but we only adjust the nominal Z by
reducing the lift amount that will be used for unlift. */
if (!this->will_move_z(z)) {
- double nominal_z = m_pos.z - m_lifted;
+ double nominal_z = m_pos(2) - m_lifted;
m_lifted = m_lifted - (z - nominal_z);
return "";
}
@@ -330,7 +336,7 @@ std::string GCodeWriter::travel_to_z(double z, const std::string &comment)
std::string GCodeWriter::_travel_to_z(double z, const std::string &comment)
{
- m_pos.z = z;
+ m_pos(2) = z;
std::ostringstream gcode;
gcode << "G1 Z" << XYZF_NUM(z)
@@ -345,38 +351,38 @@ bool GCodeWriter::will_move_z(double z) const
/* If target Z is lower than current Z but higher than nominal Z
we don't perform an actual Z move. */
if (m_lifted > 0) {
- double nominal_z = m_pos.z - m_lifted;
- if (z >= nominal_z && z <= m_pos.z)
+ double nominal_z = m_pos(2) - m_lifted;
+ if (z >= nominal_z && z <= m_pos(2))
return false;
}
return true;
}
-std::string GCodeWriter::extrude_to_xy(const Pointf &point, double dE, const std::string &comment)
+std::string GCodeWriter::extrude_to_xy(const Vec2d &point, double dE, const std::string &comment)
{
- m_pos.x = point.x;
- m_pos.y = point.y;
+ m_pos(0) = point(0);
+ m_pos(1) = point(1);
m_extruder->extrude(dE);
std::ostringstream gcode;
- gcode << "G1 X" << XYZF_NUM(point.x)
- << " Y" << XYZF_NUM(point.y)
+ gcode << "G1 X" << XYZF_NUM(point(0))
+ << " Y" << XYZF_NUM(point(1))
<< " " << m_extrusion_axis << E_NUM(m_extruder->E());
COMMENT(comment);
gcode << "\n";
return gcode.str();
}
-std::string GCodeWriter::extrude_to_xyz(const Pointf3 &point, double dE, const std::string &comment)
+std::string GCodeWriter::extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment)
{
m_pos = point;
m_lifted = 0;
m_extruder->extrude(dE);
std::ostringstream gcode;
- gcode << "G1 X" << XYZF_NUM(point.x)
- << " Y" << XYZF_NUM(point.y)
- << " Z" << XYZF_NUM(point.z)
+ gcode << "G1 X" << XYZF_NUM(point(0))
+ << " Y" << XYZF_NUM(point(1))
+ << " Z" << XYZF_NUM(point(2))
<< " " << m_extrusion_axis << E_NUM(m_extruder->E());
COMMENT(comment);
gcode << "\n";
@@ -480,12 +486,12 @@ std::string GCodeWriter::lift()
{
double above = this->config.retract_lift_above.get_at(m_extruder->id());
double below = this->config.retract_lift_below.get_at(m_extruder->id());
- if (m_pos.z >= above && (below == 0 || m_pos.z <= below))
+ if (m_pos(2) >= above && (below == 0 || m_pos(2) <= below))
target_lift = this->config.retract_lift.get_at(m_extruder->id());
}
if (m_lifted == 0 && target_lift > 0) {
m_lifted = target_lift;
- return this->_travel_to_z(m_pos.z + target_lift, "lift Z");
+ return this->_travel_to_z(m_pos(2) + target_lift, "lift Z");
}
return "";
}
@@ -494,7 +500,7 @@ std::string GCodeWriter::unlift()
{
std::string gcode;
if (m_lifted > 0) {
- gcode += this->_travel_to_z(m_pos.z - m_lifted, "restore layer Z");
+ gcode += this->_travel_to_z(m_pos(2) - m_lifted, "restore layer Z");
m_lifted = 0;
}
return gcode;
diff --git a/xs/src/libslic3r/GCodeWriter.hpp b/xs/src/libslic3r/GCodeWriter.hpp
index 78e9c9323..664b0e3a1 100644
--- a/xs/src/libslic3r/GCodeWriter.hpp
+++ b/xs/src/libslic3r/GCodeWriter.hpp
@@ -18,7 +18,7 @@ public:
GCodeWriter() :
multiple_extruders(false), m_extrusion_axis("E"), m_extruder(nullptr),
m_single_extruder_multi_material(false),
- m_last_acceleration(0), m_last_fan_speed(0),
+ m_last_acceleration(0), m_max_acceleration(0), m_last_fan_speed(0),
m_last_bed_temperature(0), m_last_bed_temperature_reached(true),
m_lifted(0)
{}
@@ -55,18 +55,18 @@ public:
std::string toolchange_prefix() const;
std::string toolchange(unsigned int extruder_id);
std::string set_speed(double F, const std::string &comment = std::string(), const std::string &cooling_marker = std::string()) const;
- std::string travel_to_xy(const Pointf &point, const std::string &comment = std::string());
- std::string travel_to_xyz(const Pointf3 &point, const std::string &comment = std::string());
+ std::string travel_to_xy(const Vec2d &point, const std::string &comment = std::string());
+ std::string travel_to_xyz(const Vec3d &point, const std::string &comment = std::string());
std::string travel_to_z(double z, const std::string &comment = std::string());
bool will_move_z(double z) const;
- std::string extrude_to_xy(const Pointf &point, double dE, const std::string &comment = std::string());
- std::string extrude_to_xyz(const Pointf3 &point, double dE, const std::string &comment = std::string());
+ std::string extrude_to_xy(const Vec2d &point, double dE, const std::string &comment = std::string());
+ std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment = std::string());
std::string retract(bool before_wipe = false);
std::string retract_for_toolchange(bool before_wipe = false);
std::string unretract();
std::string lift();
std::string unlift();
- Pointf3 get_position() const { return m_pos; }
+ Vec3d get_position() const { return m_pos; }
private:
std::vector<Extruder> m_extruders;
@@ -74,11 +74,14 @@ private:
bool m_single_extruder_multi_material;
Extruder* m_extruder;
unsigned int m_last_acceleration;
+ // Limit for setting the acceleration, to respect the machine limits set for the Marlin firmware.
+ // If set to zero, the limit is not in action.
+ unsigned int m_max_acceleration;
unsigned int m_last_fan_speed;
unsigned int m_last_bed_temperature;
bool m_last_bed_temperature_reached;
double m_lifted;
- Pointf3 m_pos;
+ Vec3d m_pos = Vec3d::Zero();
std::string _travel_to_z(double z, const std::string &comment);
std::string _retract(double length, double restart_extra, const std::string &comment);
diff --git a/xs/src/libslic3r/Geometry.cpp b/xs/src/libslic3r/Geometry.cpp
index 39b626ee3..b0ded2d04 100644
--- a/xs/src/libslic3r/Geometry.cpp
+++ b/xs/src/libslic3r/Geometry.cpp
@@ -195,47 +195,110 @@ using namespace boost::polygon; // provides also high() and low()
namespace Slic3r { namespace Geometry {
-static bool
-sort_points (Point a, Point b)
+static bool sort_points(const Point& a, const Point& b)
{
- return (a.x < b.x) || (a.x == b.x && a.y < b.y);
+ return (a(0) < b(0)) || (a(0) == b(0) && a(1) < b(1));
}
-/* This implementation is based on Andrew's monotone chain 2D convex hull algorithm */
+static bool sort_pointfs(const Vec3d& a, const Vec3d& b)
+{
+ return (a(0) < b(0)) || (a(0) == b(0) && a(1) < b(1));
+}
+
+// This implementation is based on Andrew's monotone chain 2D convex hull algorithm
Polygon
convex_hull(Points points)
{
assert(points.size() >= 3);
// sort input points
std::sort(points.begin(), points.end(), sort_points);
-
+
int n = points.size(), k = 0;
Polygon hull;
if (n >= 3) {
- hull.points.resize(2*n);
+ hull.points.resize(2 * n);
// Build lower hull
for (int i = 0; i < n; i++) {
- while (k >= 2 && points[i].ccw(hull.points[k-2], hull.points[k-1]) <= 0) k--;
- hull.points[k++] = points[i];
+ while (k >= 2 && points[i].ccw(hull[k-2], hull[k-1]) <= 0) k--;
+ hull[k++] = points[i];
}
// Build upper hull
for (int i = n-2, t = k+1; i >= 0; i--) {
- while (k >= t && points[i].ccw(hull.points[k-2], hull.points[k-1]) <= 0) k--;
- hull.points[k++] = points[i];
+ while (k >= t && points[i].ccw(hull[k-2], hull[k-1]) <= 0) k--;
+ hull[k++] = points[i];
}
hull.points.resize(k);
-
- assert( hull.points.front().coincides_with(hull.points.back()) );
+
+ assert(hull.points.front() == hull.points.back());
hull.points.pop_back();
}
return hull;
}
+Pointf3s
+convex_hull(Pointf3s points)
+{
+ assert(points.size() >= 3);
+ // sort input points
+ std::sort(points.begin(), points.end(), sort_pointfs);
+
+ int n = points.size(), k = 0;
+ Pointf3s hull;
+
+ if (n >= 3)
+ {
+ hull.resize(2 * n);
+
+ // Build lower hull
+ for (int i = 0; i < n; ++i)
+ {
+ Point p = Point::new_scale(points[i](0), points[i](1));
+ while (k >= 2)
+ {
+ Point k1 = Point::new_scale(hull[k - 1](0), hull[k - 1](1));
+ Point k2 = Point::new_scale(hull[k - 2](0), hull[k - 2](1));
+
+ if (p.ccw(k2, k1) <= 0)
+ --k;
+ else
+ break;
+ }
+
+ hull[k++] = points[i];
+ }
+
+ // Build upper hull
+ for (int i = n - 2, t = k + 1; i >= 0; --i)
+ {
+ Point p = Point::new_scale(points[i](0), points[i](1));
+ while (k >= t)
+ {
+ Point k1 = Point::new_scale(hull[k - 1](0), hull[k - 1](1));
+ Point k2 = Point::new_scale(hull[k - 2](0), hull[k - 2](1));
+
+ if (p.ccw(k2, k1) <= 0)
+ --k;
+ else
+ break;
+ }
+
+ hull[k++] = points[i];
+ }
+
+ hull.resize(k);
+
+ assert(hull.front() == hull.back());
+ hull.pop_back();
+ }
+
+ return hull;
+}
+
Polygon
convex_hull(const Polygons &polygons)
{
@@ -243,7 +306,7 @@ convex_hull(const Polygons &polygons)
for (Polygons::const_iterator p = polygons.begin(); p != polygons.end(); ++p) {
pp.insert(pp.end(), p->points.begin(), p->points.end());
}
- return convex_hull(pp);
+ return convex_hull(std::move(pp));
}
/* accepts an arrayref of points and returns a list of indices
@@ -345,54 +408,54 @@ linint(double value, double oldmin, double oldmax, double newmin, double newmax)
// If the points have the same weight, sort them lexicographically by their positions.
struct ArrangeItem {
ArrangeItem() {}
- Pointf pos;
+ Vec2d pos;
coordf_t weight;
bool operator<(const ArrangeItem &other) const {
return weight < other.weight ||
- ((weight == other.weight) && (pos.y < other.pos.y || (pos.y == other.pos.y && pos.x < other.pos.x)));
+ ((weight == other.weight) && (pos(1) < other.pos(1) || (pos(1) == other.pos(1) && pos(0) < other.pos(0))));
}
};
-Pointfs arrange(size_t num_parts, const Pointf &part_size, coordf_t gap, const BoundingBoxf* bed_bounding_box)
+Pointfs arrange(size_t num_parts, const Vec2d &part_size, coordf_t gap, const BoundingBoxf* bed_bounding_box)
{
// Use actual part size (the largest) plus separation distance (half on each side) in spacing algorithm.
- const Pointf cell_size(part_size.x + gap, part_size.y + gap);
+ const Vec2d cell_size(part_size(0) + gap, part_size(1) + gap);
const BoundingBoxf bed_bbox = (bed_bounding_box != NULL && bed_bounding_box->defined) ?
*bed_bounding_box :
// Bogus bed size, large enough not to trigger the unsufficient bed size error.
BoundingBoxf(
- Pointf(0, 0),
- Pointf(cell_size.x * num_parts, cell_size.y * num_parts));
+ Vec2d(0, 0),
+ Vec2d(cell_size(0) * num_parts, cell_size(1) * num_parts));
// This is how many cells we have available into which to put parts.
- size_t cellw = size_t(floor((bed_bbox.size().x + gap) / cell_size.x));
- size_t cellh = size_t(floor((bed_bbox.size().y + gap) / cell_size.y));
+ size_t cellw = size_t(floor((bed_bbox.size()(0) + gap) / cell_size(0)));
+ size_t cellh = size_t(floor((bed_bbox.size()(1) + gap) / cell_size(1)));
if (num_parts > cellw * cellh)
CONFESS(PRINTF_ZU " parts won't fit in your print area!\n", num_parts);
// Get a bounding box of cellw x cellh cells, centered at the center of the bed.
- Pointf cells_size(cellw * cell_size.x - gap, cellh * cell_size.y - gap);
- Pointf cells_offset(bed_bbox.center() - 0.5 * cells_size);
+ Vec2d cells_size(cellw * cell_size(0) - gap, cellh * cell_size(1) - gap);
+ Vec2d cells_offset(bed_bbox.center() - 0.5 * cells_size);
BoundingBoxf cells_bb(cells_offset, cells_size + cells_offset);
// List of cells, sorted by distance from center.
std::vector<ArrangeItem> cellsorder(cellw * cellh, ArrangeItem());
for (size_t j = 0; j < cellh; ++ j) {
// Center of the jth row on the bed.
- coordf_t cy = linint(j + 0.5, 0., double(cellh), cells_bb.min.y, cells_bb.max.y);
+ coordf_t cy = linint(j + 0.5, 0., double(cellh), cells_bb.min(1), cells_bb.max(1));
// Offset from the bed center.
- coordf_t yd = cells_bb.center().y - cy;
+ coordf_t yd = cells_bb.center()(1) - cy;
for (size_t i = 0; i < cellw; ++ i) {
// Center of the ith column on the bed.
- coordf_t cx = linint(i + 0.5, 0., double(cellw), cells_bb.min.x, cells_bb.max.x);
+ coordf_t cx = linint(i + 0.5, 0., double(cellw), cells_bb.min(0), cells_bb.max(0));
// Offset from the bed center.
- coordf_t xd = cells_bb.center().x - cx;
+ coordf_t xd = cells_bb.center()(0) - cx;
// Cell with a distance from the bed center.
ArrangeItem &ci = cellsorder[j * cellw + i];
// Cell center
- ci.pos.x = cx;
- ci.pos.y = cy;
+ ci.pos(0) = cx;
+ ci.pos(1) = cy;
// Square distance of the cell center to the bed center.
ci.weight = xd * xd + yd * yd;
}
@@ -405,61 +468,61 @@ Pointfs arrange(size_t num_parts, const Pointf &part_size, coordf_t gap, const B
Pointfs positions;
positions.reserve(num_parts);
for (std::vector<ArrangeItem>::const_iterator it = cellsorder.begin(); it != cellsorder.end(); ++ it)
- positions.push_back(Pointf(it->pos.x - 0.5 * part_size.x, it->pos.y - 0.5 * part_size.y));
+ positions.push_back(Vec2d(it->pos(0) - 0.5 * part_size(0), it->pos(1) - 0.5 * part_size(1)));
return positions;
}
#else
class ArrangeItem {
- public:
- Pointf pos;
+public:
+ Vec2d pos = Vec2d::Zero();
size_t index_x, index_y;
coordf_t dist;
};
class ArrangeItemIndex {
- public:
+public:
coordf_t index;
ArrangeItem item;
ArrangeItemIndex(coordf_t _index, ArrangeItem _item) : index(_index), item(_item) {};
};
bool
-arrange(size_t total_parts, const Pointf &part_size, coordf_t dist, const BoundingBoxf* bb, Pointfs &positions)
+arrange(size_t total_parts, const Vec2d &part_size, coordf_t dist, const BoundingBoxf* bb, Pointfs &positions)
{
positions.clear();
- Pointf part = part_size;
+ Vec2d part = part_size;
// use actual part size (the largest) plus separation distance (half on each side) in spacing algorithm
- part.x += dist;
- part.y += dist;
+ part(0) += dist;
+ part(1) += dist;
- Pointf area;
+ Vec2d area(Vec2d::Zero());
if (bb != NULL && bb->defined) {
area = bb->size();
} else {
// bogus area size, large enough not to trigger the error below
- area.x = part.x * total_parts;
- area.y = part.y * total_parts;
+ area(0) = part(0) * total_parts;
+ area(1) = part(1) * total_parts;
}
// this is how many cells we have available into which to put parts
- size_t cellw = floor((area.x + dist) / part.x);
- size_t cellh = floor((area.y + dist) / part.y);
+ size_t cellw = floor((area(0) + dist) / part(0));
+ size_t cellh = floor((area(1) + dist) / part(1));
if (total_parts > (cellw * cellh))
return false;
// total space used by cells
- Pointf cells(cellw * part.x, cellh * part.y);
+ Vec2d cells(cellw * part(0), cellh * part(1));
// bounding box of total space used by cells
BoundingBoxf cells_bb;
- cells_bb.merge(Pointf(0,0)); // min
+ cells_bb.merge(Vec2d(0,0)); // min
cells_bb.merge(cells); // max
// center bounding box to area
cells_bb.translate(
- (area.x - cells.x) / 2,
- (area.y - cells.y) / 2
+ (area(0) - cells(0)) / 2,
+ (area(1) - cells(1)) / 2
);
// list of cells, sorted by distance from center
@@ -468,15 +531,15 @@ arrange(size_t total_parts, const Pointf &part_size, coordf_t dist, const Boundi
// work out distance for all cells, sort into list
for (size_t i = 0; i <= cellw-1; ++i) {
for (size_t j = 0; j <= cellh-1; ++j) {
- coordf_t cx = linint(i + 0.5, 0, cellw, cells_bb.min.x, cells_bb.max.x);
- coordf_t cy = linint(j + 0.5, 0, cellh, cells_bb.min.y, cells_bb.max.y);
+ coordf_t cx = linint(i + 0.5, 0, cellw, cells_bb.min(0), cells_bb.max(0));
+ coordf_t cy = linint(j + 0.5, 0, cellh, cells_bb.min(1), cells_bb.max(1));
- coordf_t xd = fabs((area.x / 2) - cx);
- coordf_t yd = fabs((area.y / 2) - cy);
+ coordf_t xd = fabs((area(0) / 2) - cx);
+ coordf_t yd = fabs((area(1) / 2) - cy);
ArrangeItem c;
- c.pos.x = cx;
- c.pos.y = cy;
+ c.pos(0) = cx;
+ c.pos(1) = cy;
c.index_x = i;
c.index_y = j;
c.dist = xd * xd + yd * yd - fabs((cellw / 2) - (i + 0.5));
@@ -533,13 +596,13 @@ arrange(size_t total_parts, const Pointf &part_size, coordf_t dist, const Boundi
coordf_t cx = c.item.index_x - lx;
coordf_t cy = c.item.index_y - ty;
- positions.push_back(Pointf(cx * part.x, cy * part.y));
+ positions.push_back(Vec2d(cx * part(0), cy * part(1)));
}
if (bb != NULL && bb->defined) {
for (Pointfs::iterator p = positions.begin(); p != positions.end(); ++p) {
- p->x += bb->min.x;
- p->y += bb->min.y;
+ p->x() += bb->min(0);
+ p->y() += bb->min(1);
}
}
@@ -608,15 +671,15 @@ namespace Voronoi { namespace Internal {
if (cell1.contains_point() && cell2.contains_point()) {
point_type p1 = retrieve_point(segments, cell1);
point_type p2 = retrieve_point(segments, cell2);
- origin.x((p1.x() + p2.x()) * 0.5);
- origin.y((p1.y() + p2.y()) * 0.5);
- direction.x(p1.y() - p2.y());
- direction.y(p2.x() - p1.x());
+ origin.x((p1(0) + p2(0)) * 0.5);
+ origin.y((p1(1) + p2(1)) * 0.5);
+ direction.x(p1(1) - p2(1));
+ direction.y(p2(0) - p1(0));
} else {
origin = cell1.contains_segment() ? retrieve_point(segments, cell2) : retrieve_point(segments, cell1);
segment_type segment = cell1.contains_segment() ? segments[cell1.source_index()] : segments[cell2.source_index()];
- coordinate_type dx = high(segment).x() - low(segment).x();
- coordinate_type dy = high(segment).y() - low(segment).y();
+ coordinate_type dx = high(segment)(0) - low(segment)(0);
+ coordinate_type dy = high(segment)(1) - low(segment)(1);
if ((low(segment) == origin) ^ cell1.contains_point()) {
direction.x(dy);
direction.y(-dx);
@@ -625,19 +688,19 @@ namespace Voronoi { namespace Internal {
direction.y(dx);
}
}
- coordinate_type koef = bbox_max_size / (std::max)(fabs(direction.x()), fabs(direction.y()));
+ coordinate_type koef = bbox_max_size / (std::max)(fabs(direction(0)), fabs(direction(1)));
if (edge.vertex0() == NULL) {
clipped_edge->push_back(point_type(
- origin.x() - direction.x() * koef,
- origin.y() - direction.y() * koef));
+ origin(0) - direction(0) * koef,
+ origin(1) - direction(1) * koef));
} else {
clipped_edge->push_back(
point_type(edge.vertex0()->x(), edge.vertex0()->y()));
}
if (edge.vertex1() == NULL) {
clipped_edge->push_back(point_type(
- origin.x() + direction.x() * koef,
- origin.y() + direction.y() * koef));
+ origin(0) + direction(0) * koef,
+ origin(1) + direction(1) * koef));
} else {
clipped_edge->push_back(
point_type(edge.vertex1()->x(), edge.vertex1()->y()));
@@ -676,10 +739,10 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
const bool primaryEdgesOnly = false;
BoundingBox bbox = BoundingBox(lines);
- bbox.min.x -= coord_t(1. / SCALING_FACTOR);
- bbox.min.y -= coord_t(1. / SCALING_FACTOR);
- bbox.max.x += coord_t(1. / SCALING_FACTOR);
- bbox.max.y += coord_t(1. / SCALING_FACTOR);
+ bbox.min(0) -= coord_t(1. / SCALING_FACTOR);
+ bbox.min(1) -= coord_t(1. / SCALING_FACTOR);
+ bbox.max(0) += coord_t(1. / SCALING_FACTOR);
+ bbox.max(1) += coord_t(1. / SCALING_FACTOR);
::Slic3r::SVG svg(path, bbox);
@@ -689,7 +752,7 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
// bbox.scale(1.2);
// For clipping of half-lines to some reasonable value.
// The line will then be clipped by the SVG viewer anyway.
- const double bbox_dim_max = double(bbox.max.x - bbox.min.x) + double(bbox.max.y - bbox.min.y);
+ const double bbox_dim_max = double(bbox.max(0) - bbox.min(0)) + double(bbox.max(1) - bbox.min(1));
// For the discretization of the Voronoi parabolic segments.
const double discretization_step = 0.0005 * bbox_dim_max;
@@ -697,8 +760,8 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
std::vector<Voronoi::Internal::segment_type> segments;
for (Lines::const_iterator it = lines.begin(); it != lines.end(); ++ it)
segments.push_back(Voronoi::Internal::segment_type(
- Voronoi::Internal::point_type(double(it->a.x), double(it->a.y)),
- Voronoi::Internal::point_type(double(it->b.x), double(it->b.y))));
+ Voronoi::Internal::point_type(double(it->a(0)), double(it->a(1))),
+ Voronoi::Internal::point_type(double(it->b(0)), double(it->b(1)))));
// Color exterior edges.
for (voronoi_diagram<double>::const_edge_iterator it = vd.edges().begin(); it != vd.edges().end(); ++it)
@@ -712,13 +775,13 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
}
// Draw the input polygon.
for (Lines::const_iterator it = lines.begin(); it != lines.end(); ++it)
- svg.draw(Line(Point(coord_t(it->a.x), coord_t(it->a.y)), Point(coord_t(it->b.x), coord_t(it->b.y))), inputSegmentColor, inputSegmentLineWidth);
+ svg.draw(Line(Point(coord_t(it->a(0)), coord_t(it->a(1))), Point(coord_t(it->b(0)), coord_t(it->b(1)))), inputSegmentColor, inputSegmentLineWidth);
#if 1
// Draw voronoi vertices.
for (voronoi_diagram<double>::const_vertex_iterator it = vd.vertices().begin(); it != vd.vertices().end(); ++it)
if (! internalEdgesOnly || it->color() != Voronoi::Internal::EXTERNAL_COLOR)
- svg.draw(Point(coord_t(it->x()), coord_t(it->y())), voronoiPointColor, voronoiPointRadius);
+ svg.draw(Point(coord_t((*it)(0)), coord_t((*it)(1))), voronoiPointColor, voronoiPointRadius);
for (voronoi_diagram<double>::const_edge_iterator it = vd.edges().begin(); it != vd.edges().end(); ++it) {
if (primaryEdgesOnly && !it->is_primary())
@@ -743,7 +806,7 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
color = voronoiLineColorSecondary;
}
for (std::size_t i = 0; i + 1 < samples.size(); ++i)
- svg.draw(Line(Point(coord_t(samples[i].x()), coord_t(samples[i].y())), Point(coord_t(samples[i+1].x()), coord_t(samples[i+1].y()))), color, voronoiLineWidth);
+ svg.draw(Line(Point(coord_t(samples[i](0)), coord_t(samples[i](1))), Point(coord_t(samples[i+1](0)), coord_t(samples[i+1](1)))), color, voronoiLineWidth);
}
#endif
@@ -758,8 +821,8 @@ static inline void dump_voronoi_to_svg(const Lines &lines, /* const */ voronoi_d
template<typename T>
T dist(const boost::polygon::point_data<T> &p1,const boost::polygon::point_data<T> &p2)
{
- T dx = p2.x() - p1.x();
- T dy = p2.y() - p1.y();
+ T dx = p2(0) - p1(0);
+ T dy = p2(1) - p1(1);
return sqrt(dx*dx+dy*dy);
}
@@ -770,11 +833,11 @@ inline point_type project_point_to_segment(segment_type &seg, point_type &px)
typedef typename point_type::coordinate_type T;
const point_type &p0 = low(seg);
const point_type &p1 = high(seg);
- const point_type dir(p1.x()-p0.x(), p1.y()-p0.y());
- const point_type dproj(px.x()-p0.x(), px.y()-p0.y());
- const T t = (dir.x()*dproj.x() + dir.y()*dproj.y()) / (dir.x()*dir.x() + dir.y()*dir.y());
+ const point_type dir(p1(0)-p0(0), p1(1)-p0(1));
+ const point_type dproj(px(0)-p0(0), px(1)-p0(1));
+ const T t = (dir(0)*dproj(0) + dir(1)*dproj(1)) / (dir(0)*dir(0) + dir(1)*dir(1));
assert(t >= T(-1e-6) && t <= T(1. + 1e-6));
- return point_type(p0.x() + t*dir.x(), p0.y() + t*dir.y());
+ return point_type(p0(0) + t*dir(0), p0(1) + t*dir(1));
}
template<typename VD, typename SEGMENTS>
@@ -828,8 +891,8 @@ public:
Lines2VDSegments(const Lines &alines) : lines(alines) {}
typename VD::segment_type operator[](size_t idx) const {
return typename VD::segment_type(
- typename VD::point_type(typename VD::coord_type(lines[idx].a.x), typename VD::coord_type(lines[idx].a.y)),
- typename VD::point_type(typename VD::coord_type(lines[idx].b.x), typename VD::coord_type(lines[idx].b.y)));
+ typename VD::point_type(typename VD::coord_type(lines[idx].a(0)), typename VD::coord_type(lines[idx].a(1))),
+ typename VD::point_type(typename VD::coord_type(lines[idx].b(0)), typename VD::coord_type(lines[idx].b(1))));
}
private:
const Lines &lines;
@@ -910,7 +973,7 @@ MedialAxis::build(ThickPolylines* polylines)
assert(polyline.width.size() == polyline.points.size()*2 - 2);
// prevent loop endpoints from being extended
- if (polyline.first_point().coincides_with(polyline.last_point())) {
+ if (polyline.first_point() == polyline.last_point()) {
polyline.endpoints.first = false;
polyline.endpoints.second = false;
}
@@ -1003,7 +1066,7 @@ MedialAxis::validate_edge(const VD::edge_type* edge)
// this could maybe be optimized (checking inclusion of the endpoints
// might give false positives as they might belong to the contour itself)
if (this->expolygon != NULL) {
- if (line.a.coincides_with(line.b)) {
+ if (line.a == line.b) {
// in this case, contains(line) returns a false positive
if (!this->expolygon->contains(line.a)) return false;
} else {
@@ -1042,12 +1105,12 @@ MedialAxis::validate_edge(const VD::edge_type* edge)
calculate the distance to that endpoint instead. */
coordf_t w0 = cell_r->contains_segment()
- ? line.a.distance_to(segment_r)*2
- : line.a.distance_to(this->retrieve_endpoint(cell_r))*2;
+ ? segment_r.distance_to(line.a)*2
+ : (this->retrieve_endpoint(cell_r) - line.a).cast<double>().norm()*2;
coordf_t w1 = cell_l->contains_segment()
- ? line.b.distance_to(segment_l)*2
- : line.b.distance_to(this->retrieve_endpoint(cell_l))*2;
+ ? segment_l.distance_to(line.b)*2
+ : (this->retrieve_endpoint(cell_l) - line.b).cast<double>().norm()*2;
if (cell_l->contains_segment() && cell_r->contains_segment()) {
// calculate the relative angle between the two boundary segments
diff --git a/xs/src/libslic3r/Geometry.hpp b/xs/src/libslic3r/Geometry.hpp
index c2c3dc8b7..3698b996f 100644
--- a/xs/src/libslic3r/Geometry.hpp
+++ b/xs/src/libslic3r/Geometry.hpp
@@ -30,9 +30,9 @@ enum Orientation
static inline Orientation orient(const Point &a, const Point &b, const Point &c)
{
// BOOST_STATIC_ASSERT(sizeof(coord_t) * 2 == sizeof(int64_t));
- int64_t u = int64_t(b.x) * int64_t(c.y) - int64_t(b.y) * int64_t(c.x);
- int64_t v = int64_t(a.x) * int64_t(c.y) - int64_t(a.y) * int64_t(c.x);
- int64_t w = int64_t(a.x) * int64_t(b.y) - int64_t(a.y) * int64_t(b.x);
+ int64_t u = int64_t(b(0)) * int64_t(c(1)) - int64_t(b(1)) * int64_t(c(0));
+ int64_t v = int64_t(a(0)) * int64_t(c(1)) - int64_t(a(1)) * int64_t(c(0));
+ int64_t w = int64_t(a(0)) * int64_t(b(1)) - int64_t(a(1)) * int64_t(b(0));
int64_t d = u - v + w;
return (d > 0) ? ORIENTATION_CCW : ((d == 0) ? ORIENTATION_COLINEAR : ORIENTATION_CW);
}
@@ -52,7 +52,7 @@ static inline bool is_ccw(const Polygon &poly)
for (unsigned int i = 1; i < poly.points.size(); ++ i) {
const Point &pmin = poly.points[imin];
const Point &p = poly.points[i];
- if (p.x < pmin.x || (p.x == pmin.x && p.y < pmin.y))
+ if (p(0) < pmin(0) || (p(0) == pmin(0) && p(1) < pmin(1)))
imin = i;
}
@@ -66,26 +66,26 @@ static inline bool is_ccw(const Polygon &poly)
return o == ORIENTATION_CCW;
}
-inline bool ray_ray_intersection(const Pointf &p1, const Vectorf &v1, const Pointf &p2, const Vectorf &v2, Pointf &res)
+inline bool ray_ray_intersection(const Vec2d &p1, const Vec2d &v1, const Vec2d &p2, const Vec2d &v2, Vec2d &res)
{
- double denom = v1.x * v2.y - v2.x * v1.y;
+ double denom = v1(0) * v2(1) - v2(0) * v1(1);
if (std::abs(denom) < EPSILON)
return false;
- double t = (v2.x * (p1.y - p2.y) - v2.y * (p1.x - p2.x)) / denom;
- res.x = p1.x + t * v1.x;
- res.y = p1.y + t * v1.y;
+ double t = (v2(0) * (p1(1) - p2(1)) - v2(1) * (p1(0) - p2(0))) / denom;
+ res(0) = p1(0) + t * v1(0);
+ res(1) = p1(1) + t * v1(1);
return true;
}
-inline bool segment_segment_intersection(const Pointf &p1, const Vectorf &v1, const Pointf &p2, const Vectorf &v2, Pointf &res)
+inline bool segment_segment_intersection(const Vec2d &p1, const Vec2d &v1, const Vec2d &p2, const Vec2d &v2, Vec2d &res)
{
- double denom = v1.x * v2.y - v2.x * v1.y;
+ double denom = v1(0) * v2(1) - v2(0) * v1(1);
if (std::abs(denom) < EPSILON)
// Lines are collinear.
return false;
- double s12_x = p1.x - p2.x;
- double s12_y = p1.y - p2.y;
- double s_numer = v1.x * s12_y - v1.y * s12_x;
+ double s12_x = p1(0) - p2(0);
+ double s12_y = p1(1) - p2(1);
+ double s_numer = v1(0) * s12_y - v1(1) * s12_x;
bool denom_is_positive = false;
if (denom < 0.) {
denom_is_positive = true;
@@ -95,7 +95,7 @@ inline bool segment_segment_intersection(const Pointf &p1, const Vectorf &v1, co
if (s_numer < 0.)
// Intersection outside of the 1st segment.
return false;
- double t_numer = v2.x * s12_y - v2.y * s12_x;
+ double t_numer = v2(0) * s12_y - v2(1) * s12_x;
if (! denom_is_positive)
t_numer = - t_numer;
if (t_numer < 0. || s_numer > denom || t_numer > denom)
@@ -103,13 +103,15 @@ inline bool segment_segment_intersection(const Pointf &p1, const Vectorf &v1, co
return false;
// Intersection inside both of the segments.
double t = t_numer / denom;
- res.x = p1.x + t * v1.x;
- res.y = p1.y + t * v1.y;
+ res(0) = p1(0) + t * v1(0);
+ res(1) = p1(1) + t * v1(1);
return true;
}
+Pointf3s convex_hull(Pointf3s points);
Polygon convex_hull(Points points);
Polygon convex_hull(const Polygons &polygons);
+
void chained_path(const Points &points, std::vector<Points::size_type> &retval, Point start_near);
void chained_path(const Points &points, std::vector<Points::size_type> &retval);
template<class T> void chained_path_items(Points &points, T &items, T &retval);
@@ -123,7 +125,7 @@ void simplify_polygons(const Polygons &polygons, double tolerance, Polygons* ret
double linint(double value, double oldmin, double oldmax, double newmin, double newmax);
bool arrange(
// input
- size_t num_parts, const Pointf &part_size, coordf_t gap, const BoundingBoxf* bed_bounding_box,
+ size_t num_parts, const Vec2d &part_size, coordf_t gap, const BoundingBoxf* bed_bounding_box,
// output
Pointfs &positions);
diff --git a/xs/src/libslic3r/I18N.hpp b/xs/src/libslic3r/I18N.hpp
new file mode 100644
index 000000000..db4fd22df
--- /dev/null
+++ b/xs/src/libslic3r/I18N.hpp
@@ -0,0 +1,18 @@
+#ifndef slic3r_I18N_hpp_
+#define slic3r_I18N_hpp_
+
+#include <string>
+
+namespace Slic3r {
+
+namespace I18N {
+ typedef std::string (*translate_fn_type)(const char*);
+ extern translate_fn_type translate_fn;
+ inline void set_translate_callback(translate_fn_type fn) { translate_fn = fn; }
+ inline std::string translate(const std::string &s) { return (translate_fn == nullptr) ? s : (*translate_fn)(s.c_str()); }
+ inline std::string translate(const char *ptr) { return (translate_fn == nullptr) ? std::string(ptr) : (*translate_fn)(ptr); }
+} // namespace I18N
+
+} // namespace Slic3r
+
+#endif /* slic3r_I18N_hpp_ */
diff --git a/xs/src/libslic3r/Int128.hpp b/xs/src/libslic3r/Int128.hpp
index 7bf0c87b4..d54b75342 100644
--- a/xs/src/libslic3r/Int128.hpp
+++ b/xs/src/libslic3r/Int128.hpp
@@ -48,7 +48,6 @@
#endif
#include <cassert>
-#include "Point.hpp"
#if ! defined(_MSC_VER) && defined(__SIZEOF_INT128__)
#define HAS_INTRINSIC_128_TYPE
@@ -288,20 +287,4 @@ public:
}
return sign_determinant_2x2(p1, q1, p2, q2) * invert;
}
-
- // Exact orientation predicate,
- // returns +1: CCW, 0: collinear, -1: CW.
- static int orient(const Slic3r::Point &p1, const Slic3r::Point &p2, const Slic3r::Point &p3)
- {
- Slic3r::Vector v1(p2 - p1);
- Slic3r::Vector v2(p3 - p1);
- return sign_determinant_2x2_filtered(v1.x, v1.y, v2.x, v2.y);
- }
-
- // Exact orientation predicate,
- // returns +1: CCW, 0: collinear, -1: CW.
- static int cross(const Slic3r::Point &v1, const Slic3r::Point &v2)
- {
- return sign_determinant_2x2_filtered(v1.x, v1.y, v2.x, v2.y);
- }
};
diff --git a/xs/src/libslic3r/Layer.cpp b/xs/src/libslic3r/Layer.cpp
index 72ac371a2..6c2bd0da9 100644
--- a/xs/src/libslic3r/Layer.cpp
+++ b/xs/src/libslic3r/Layer.cpp
@@ -167,8 +167,8 @@ void Layer::export_region_slices_to_svg(const char *path) const
for (const auto &surface : region->slices.surfaces)
bbox.merge(get_extents(surface.expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
@@ -193,8 +193,8 @@ void Layer::export_region_fill_surfaces_to_svg(const char *path) const
for (const auto &surface : region->slices.surfaces)
bbox.merge(get_extents(surface.expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
diff --git a/xs/src/libslic3r/LayerRegion.cpp b/xs/src/libslic3r/LayerRegion.cpp
index c576d7eec..65184c9d1 100644
--- a/xs/src/libslic3r/LayerRegion.cpp
+++ b/xs/src/libslic3r/LayerRegion.cpp
@@ -392,8 +392,8 @@ void LayerRegion::export_region_slices_to_svg(const char *path) const
for (Surfaces::const_iterator surface = this->slices.surfaces.begin(); surface != this->slices.surfaces.end(); ++surface)
bbox.merge(get_extents(surface->expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
@@ -419,8 +419,8 @@ void LayerRegion::export_region_fill_surfaces_to_svg(const char *path) const
for (Surfaces::const_iterator surface = this->fill_surfaces.surfaces.begin(); surface != this->fill_surfaces.surfaces.end(); ++surface)
bbox.merge(get_extents(surface->expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
diff --git a/xs/src/libslic3r/Line.cpp b/xs/src/libslic3r/Line.cpp
index e9d5d7742..35cfa2b76 100644
--- a/xs/src/libslic3r/Line.cpp
+++ b/xs/src/libslic3r/Line.cpp
@@ -7,133 +7,70 @@
namespace Slic3r {
-std::string
-Line::wkt() const
+Linef3 transform(const Linef3& line, const Transform3d& t)
{
- std::ostringstream ss;
- ss << "LINESTRING(" << this->a.x << " " << this->a.y << ","
- << this->b.x << " " << this->b.y << ")";
- return ss.str();
-}
-
-Line::operator Lines() const
-{
- Lines lines;
- lines.push_back(*this);
- return lines;
-}
-
-Line::operator Polyline() const
-{
- Polyline pl;
- pl.points.push_back(this->a);
- pl.points.push_back(this->b);
- return pl;
-}
-
-void
-Line::scale(double factor)
-{
- this->a.scale(factor);
- this->b.scale(factor);
-}
-
-void
-Line::translate(double x, double y)
-{
- this->a.translate(x, y);
- this->b.translate(x, y);
-}
-
-void
-Line::rotate(double angle, const Point &center)
-{
- this->a.rotate(angle, center);
- this->b.rotate(angle, center);
-}
-
-void
-Line::reverse()
-{
- std::swap(this->a, this->b);
-}
+ typedef Eigen::Matrix<double, 3, 2> LineInMatrixForm;
-double
-Line::length() const
-{
- return this->a.distance_to(this->b);
-}
+ LineInMatrixForm world_line;
+ ::memcpy((void*)world_line.col(0).data(), (const void*)line.a.data(), 3 * sizeof(double));
+ ::memcpy((void*)world_line.col(1).data(), (const void*)line.b.data(), 3 * sizeof(double));
-Point
-Line::midpoint() const
-{
- return Point((this->a.x + this->b.x) / 2.0, (this->a.y + this->b.y) / 2.0);
+ LineInMatrixForm local_line = t * world_line.colwise().homogeneous();
+ return Linef3(Vec3d(local_line(0, 0), local_line(1, 0), local_line(2, 0)), Vec3d(local_line(0, 1), local_line(1, 1), local_line(2, 1)));
}
-void
-Line::point_at(double distance, Point* point) const
+bool Line::intersection_infinite(const Line &other, Point* point) const
{
- double len = this->length();
- *point = this->a;
- if (this->a.x != this->b.x)
- point->x = this->a.x + (this->b.x - this->a.x) * distance / len;
- if (this->a.y != this->b.y)
- point->y = this->a.y + (this->b.y - this->a.y) * distance / len;
-}
-
-Point
-Line::point_at(double distance) const
-{
- Point p;
- this->point_at(distance, &p);
- return p;
-}
-
-bool
-Line::intersection_infinite(const Line &other, Point* point) const
-{
- Vector x = this->a.vector_to(other.a);
- Vector d1 = this->vector();
- Vector d2 = other.vector();
-
- double cross = d1.x * d2.y - d1.y * d2.x;
- if (std::fabs(cross) < EPSILON)
+ Vec2d a1 = this->a.cast<double>();
+ Vec2d a2 = other.a.cast<double>();
+ Vec2d v12 = (other.a - this->a).cast<double>();
+ Vec2d v1 = (this->b - this->a).cast<double>();
+ Vec2d v2 = (other.b - other.a).cast<double>();
+ double denom = cross2(v1, v2);
+ if (std::fabs(denom) < EPSILON)
return false;
-
- double t1 = (x.x * d2.y - x.y * d2.x)/cross;
- point->x = this->a.x + d1.x * t1;
- point->y = this->a.y + d1.y * t1;
+ double t1 = cross2(v12, v2) / denom;
+ *point = (a1 + t1 * v1).cast<coord_t>();
return true;
}
-bool
-Line::coincides_with(const Line &line) const
+/* distance to the closest point of line */
+double Line::distance_to(const Point &point) const
{
- return this->a.coincides_with(line.a) && this->b.coincides_with(line.b);
+ const Line &line = *this;
+ const Vec2d v = (line.b - line.a).cast<double>();
+ const Vec2d va = (point - line.a).cast<double>();
+ const double l2 = v.squaredNorm(); // avoid a sqrt
+ if (l2 == 0.0)
+ // line.a == line.b case
+ return va.norm();
+ // Consider the line extending the segment, parameterized as line.a + t (line.b - line.a).
+ // We find projection of this point onto the line.
+ // It falls where t = [(this-line.a) . (line.b-line.a)] / |line.b-line.a|^2
+ const double t = va.dot(v) / l2;
+ if (t < 0.0) return va.norm(); // beyond the 'a' end of the segment
+ else if (t > 1.0) return (point - line.b).cast<double>().norm(); // beyond the 'b' end of the segment
+ return (t * v - va).norm();
}
-double
-Line::distance_to(const Point &point) const
+double Line::perp_distance_to(const Point &point) const
{
- return point.distance_to(*this);
+ const Line &line = *this;
+ const Vec2d v = (line.b - line.a).cast<double>();
+ const Vec2d va = (point - line.a).cast<double>();
+ if (line.a == line.b)
+ return va.norm();
+ return std::abs(cross2(v, va)) / v.norm();
}
-double
-Line::atan2_() const
-{
- return atan2(this->b.y - this->a.y, this->b.x - this->a.x);
-}
-
-double
-Line::orientation() const
+double Line::orientation() const
{
double angle = this->atan2_();
if (angle < 0) angle = 2*PI + angle;
return angle;
}
-double
-Line::direction() const
+double Line::direction() const
{
double atan2 = this->atan2_();
return (fabs(atan2 - PI) < EPSILON) ? 0
@@ -141,108 +78,42 @@ Line::direction() const
: atan2;
}
-bool
-Line::parallel_to(double angle) const {
- return Slic3r::Geometry::directions_parallel(this->direction(), angle);
-}
-
-bool
-Line::parallel_to(const Line &line) const {
- return this->parallel_to(line.direction());
-}
-
-Vector
-Line::vector() const
+bool Line::parallel_to(double angle) const
{
- return Vector(this->b.x - this->a.x, this->b.y - this->a.y);
-}
-
-Vector
-Line::normal() const
-{
- return Vector((this->b.y - this->a.y), -(this->b.x - this->a.x));
-}
-
-void
-Line::extend_end(double distance)
-{
- // relocate last point by extending the segment by the specified length
- Line line = *this;
- line.reverse();
- this->b = line.point_at(-distance);
-}
-
-void
-Line::extend_start(double distance)
-{
- // relocate first point by extending the first segment by the specified length
- this->a = this->point_at(-distance);
+ return Slic3r::Geometry::directions_parallel(this->direction(), angle);
}
-bool
-Line::intersection(const Line& line, Point* intersection) const
-{
- double denom = ((double)(line.b.y - line.a.y)*(this->b.x - this->a.x)) -
- ((double)(line.b.x - line.a.x)*(this->b.y - this->a.y));
-
- double nume_a = ((double)(line.b.x - line.a.x)*(this->a.y - line.a.y)) -
- ((double)(line.b.y - line.a.y)*(this->a.x - line.a.x));
-
- double nume_b = ((double)(this->b.x - this->a.x)*(this->a.y - line.a.y)) -
- ((double)(this->b.y - this->a.y)*(this->a.x - line.a.x));
-
- if (fabs(denom) < EPSILON) {
- if (fabs(nume_a) < EPSILON && fabs(nume_b) < EPSILON) {
- return false; // coincident
- }
- return false; // parallel
- }
-
- double ua = nume_a / denom;
- double ub = nume_b / denom;
-
- if (ua >= 0 && ua <= 1.0f && ub >= 0 && ub <= 1.0f)
- {
+bool Line::intersection(const Line &l2, Point *intersection) const
+{
+ const Line &l1 = *this;
+ const Vec2d v1 = (l1.b - l1.a).cast<double>();
+ const Vec2d v2 = (l2.b - l2.a).cast<double>();
+ const Vec2d v12 = (l1.a - l2.a).cast<double>();
+ double denom = cross2(v1, v2);
+ double nume_a = cross2(v2, v12);
+ double nume_b = cross2(v1, v12);
+ if (fabs(denom) < EPSILON)
+#if 0
+ // Lines are collinear. Return true if they are coincident (overlappign).
+ return ! (fabs(nume_a) < EPSILON && fabs(nume_b) < EPSILON);
+#else
+ return false;
+#endif
+ double t1 = nume_a / denom;
+ double t2 = nume_b / denom;
+ if (t1 >= 0 && t1 <= 1.0f && t2 >= 0 && t2 <= 1.0f) {
// Get the intersection point.
- intersection->x = this->a.x + ua*(this->b.x - this->a.x);
- intersection->y = this->a.y + ua*(this->b.y - this->a.y);
+ (*intersection) = (l1.a.cast<double>() + t1 * v1).cast<coord_t>();
return true;
}
-
return false; // not intersecting
}
-double
-Line::ccw(const Point& point) const
-{
- return point.ccw(*this);
-}
-
-double Line3::length() const
-{
- return a.distance_to(b);
-}
-
-Vector3 Line3::vector() const
-{
- return Vector3(b.x - a.x, b.y - a.y, b.z - a.z);
-}
-
-Pointf3
-Linef3::intersect_plane(double z) const
-{
- return Pointf3(
- this->a.x + (this->b.x - this->a.x) * (z - this->a.z) / (this->b.z - this->a.z),
- this->a.y + (this->b.y - this->a.y) * (z - this->a.z) / (this->b.z - this->a.z),
- z
- );
-}
-
-void
-Linef3::scale(double factor)
+Vec3d Linef3::intersect_plane(double z) const
{
- this->a.scale(factor);
- this->b.scale(factor);
+ auto v = (this->b - this->a).cast<double>();
+ double t = (z - this->a(2)) / v(2);
+ return Vec3d(this->a(0) + v(0) * t, this->a(1) + v(1) * t, z);
}
}
diff --git a/xs/src/libslic3r/Line.hpp b/xs/src/libslic3r/Line.hpp
index 4826017ab..36e02247c 100644
--- a/xs/src/libslic3r/Line.hpp
+++ b/xs/src/libslic3r/Line.hpp
@@ -15,80 +15,85 @@ typedef std::vector<Line> Lines;
typedef std::vector<Line3> Lines3;
typedef std::vector<ThickLine> ThickLines;
+Linef3 transform(const Linef3& line, const Transform3d& t);
+
class Line
{
public:
- Point a;
- Point b;
- Line() {};
- explicit Line(Point _a, Point _b): a(_a), b(_b) {};
- std::string wkt() const;
- operator Lines() const;
- operator Polyline() const;
- void scale(double factor);
- void translate(double x, double y);
- void rotate(double angle, const Point &center);
- void reverse();
- double length() const;
- Point midpoint() const;
- void point_at(double distance, Point* point) const;
- Point point_at(double distance) const;
- bool intersection_infinite(const Line &other, Point* point) const;
- bool coincides_with(const Line &line) const;
+ Line() {}
+ Line(const Point& _a, const Point& _b) : a(_a), b(_b) {}
+ explicit operator Lines() const { Lines lines; lines.emplace_back(*this); return lines; }
+ void scale(double factor) { this->a *= factor; this->b *= factor; }
+ void translate(double x, double y) { Vector v(x, y); this->a += v; this->b += v; }
+ void rotate(double angle, const Point &center) { this->a.rotate(angle, center); this->b.rotate(angle, center); }
+ void reverse() { std::swap(this->a, this->b); }
+ double length() const { return (b - a).cast<double>().norm(); }
+ Point midpoint() const { return (this->a + this->b) / 2; }
+ bool intersection_infinite(const Line &other, Point* point) const;
+ bool operator==(const Line &rhs) const { return this->a == rhs.a && this->b == rhs.b; }
double distance_to(const Point &point) const;
- bool parallel_to(double angle) const;
- bool parallel_to(const Line &line) const;
- double atan2_() const;
+ double perp_distance_to(const Point &point) const;
+ bool parallel_to(double angle) const;
+ bool parallel_to(const Line &line) const { return this->parallel_to(line.direction()); }
+ double atan2_() const { return atan2(this->b(1) - this->a(1), this->b(0) - this->a(0)); }
double orientation() const;
double direction() const;
- Vector vector() const;
- Vector normal() const;
- void extend_end(double distance);
- void extend_start(double distance);
- bool intersection(const Line& line, Point* intersection) const;
- double ccw(const Point& point) const;
+ Vector vector() const { return this->b - this->a; }
+ Vector normal() const { return Vector((this->b(1) - this->a(1)), -(this->b(0) - this->a(0))); }
+ bool intersection(const Line& line, Point* intersection) const;
+ double ccw(const Point& point) const { return point.ccw(*this); }
+
+ Point a;
+ Point b;
};
class ThickLine : public Line
{
- public:
- coordf_t a_width, b_width;
-
- ThickLine() : a_width(0), b_width(0) {};
- ThickLine(Point _a, Point _b) : Line(_a, _b), a_width(0), b_width(0) {};
+public:
+ ThickLine() : a_width(0), b_width(0) {}
+ ThickLine(const Point& a, const Point& b) : Line(a, b), a_width(0), b_width(0) {}
+ ThickLine(const Point& a, const Point& b, double wa, double wb) : Line(a, b), a_width(wa), b_width(wb) {}
+
+ double a_width, b_width;
};
class Line3
{
public:
- Point3 a;
- Point3 b;
+ Line3() : a(Vec3crd::Zero()), b(Vec3crd::Zero()) {}
+ Line3(const Vec3crd& _a, const Vec3crd& _b) : a(_a), b(_b) {}
- Line3() {}
- Line3(const Point3& _a, const Point3& _b) : a(_a), b(_b) {}
+ double length() const { return (this->a - this->b).cast<double>().norm(); }
+ Vec3crd vector() const { return this->b - this->a; }
- double length() const;
- Vector3 vector() const;
+ Vec3crd a;
+ Vec3crd b;
};
class Linef
{
- public:
- Pointf a;
- Pointf b;
- Linef() {};
- explicit Linef(Pointf _a, Pointf _b): a(_a), b(_b) {};
+public:
+ Linef() : a(Vec2d::Zero()), b(Vec2d::Zero()) {}
+ Linef(const Vec2d& _a, const Vec2d& _b) : a(_a), b(_b) {}
+
+ Vec2d a;
+ Vec2d b;
};
class Linef3
{
- public:
- Pointf3 a;
- Pointf3 b;
- Linef3() {};
- explicit Linef3(Pointf3 _a, Pointf3 _b): a(_a), b(_b) {};
- Pointf3 intersect_plane(double z) const;
- void scale(double factor);
+public:
+ Linef3() : a(Vec3d::Zero()), b(Vec3d::Zero()) {}
+ Linef3(const Vec3d& _a, const Vec3d& _b) : a(_a), b(_b) {}
+
+ Vec3d intersect_plane(double z) const;
+ void scale(double factor) { this->a *= factor; this->b *= factor; }
+ Vec3d vector() const { return this->b - this->a; }
+ Vec3d unit_vector() const { return (length() == 0.0) ? Vec3d::Zero() : vector().normalized(); }
+ double length() const { return vector().norm(); }
+
+ Vec3d a;
+ Vec3d b;
};
} // namespace Slic3r
diff --git a/xs/src/libslic3r/Model.cpp b/xs/src/libslic3r/Model.cpp
index 6f1ce1ce5..19c474cad 100644
--- a/xs/src/libslic3r/Model.cpp
+++ b/xs/src/libslic3r/Model.cpp
@@ -14,8 +14,13 @@
#include <boost/nowide/iostream.hpp>
#include <boost/algorithm/string/replace.hpp>
+#include "SVG.hpp"
+#include <Eigen/Dense>
+
namespace Slic3r {
+ unsigned int Model::s_auto_extruder_id = 1;
+
Model::Model(const Model &other)
{
// copy materials
@@ -230,28 +235,17 @@ BoundingBoxf3 Model::bounding_box() const
return bb;
}
-BoundingBoxf3 Model::transformed_bounding_box() const
-{
- BoundingBoxf3 bb;
- for (const ModelObject* obj : this->objects)
- bb.merge(obj->tight_bounding_box(false));
- return bb;
-}
-
-void Model::center_instances_around_point(const Pointf &point)
+void Model::center_instances_around_point(const Vec2d &point)
{
-// BoundingBoxf3 bb = this->bounding_box();
BoundingBoxf3 bb;
for (ModelObject *o : this->objects)
for (size_t i = 0; i < o->instances.size(); ++ i)
bb.merge(o->instance_bounding_box(i, false));
- Sizef3 size = bb.size();
- coordf_t shift_x = -bb.min.x + point.x - size.x/2;
- coordf_t shift_y = -bb.min.y + point.y - size.y/2;
+ Vec2d shift = point - 0.5 * to_2d(bb.size()) - to_2d(bb.min);
for (ModelObject *o : this->objects) {
for (ModelInstance *i : o->instances)
- i->offset.translate(shift_x, shift_y);
+ i->offset += shift;
o->invalidate_bounding_box();
}
}
@@ -267,6 +261,10 @@ TriangleMesh Model::mesh() const
static bool _arrange(const Pointfs &sizes, coordf_t dist, const BoundingBoxf* bb, Pointfs &out)
{
+ if (sizes.empty())
+ // return if the list is empty or the following call to BoundingBoxf constructor will lead to a crash
+ return true;
+
// we supply unscaled data to arrange()
bool result = Slic3r::Geometry::arrange(
sizes.size(), // number of parts
@@ -302,29 +300,30 @@ bool Model::arrange_objects(coordf_t dist, const BoundingBoxf* bb)
for (size_t i = 0; i < o->instances.size(); ++ i) {
// an accurate snug bounding box around the transformed mesh.
BoundingBoxf3 bbox(o->instance_bounding_box(i, true));
- instance_sizes.push_back(bbox.size());
- instance_centers.push_back(bbox.center());
+ instance_sizes.emplace_back(to_2d(bbox.size()));
+ instance_centers.emplace_back(to_2d(bbox.center()));
}
Pointfs positions;
if (! _arrange(instance_sizes, dist, bb, positions))
return false;
-
- size_t idx = 0;
- for (ModelObject *o : this->objects) {
+
+ size_t idx = 0;
+ for (ModelObject *o : this->objects) {
for (ModelInstance *i : o->instances) {
i->offset = positions[idx] - instance_centers[idx];
++ idx;
}
o->invalidate_bounding_box();
}
+
return true;
}
// Duplicate the entire model preserving instance relative positions.
void Model::duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb)
{
- Pointfs model_sizes(copies_num-1, this->bounding_box().size());
+ Pointfs model_sizes(copies_num-1, to_2d(this->bounding_box().size()));
Pointfs positions;
if (! _arrange(model_sizes, dist, bb, positions))
CONFESS("Cannot duplicate part as the resulting objects would not fit on the print bed.\n");
@@ -335,9 +334,9 @@ void Model::duplicate(size_t copies_num, coordf_t dist, const BoundingBoxf* bb)
// make a copy of the pointers in order to avoid recursion when appending their copies
ModelInstancePtrs instances = o->instances;
for (const ModelInstance *i : instances) {
- for (const Pointf &pos : positions) {
+ for (const Vec2d &pos : positions) {
ModelInstance *instance = o->add_instance(*i);
- instance->offset.translate(pos);
+ instance->offset += pos;
}
}
o->invalidate_bounding_box();
@@ -367,13 +366,13 @@ void Model::duplicate_objects_grid(size_t x, size_t y, coordf_t dist)
ModelObject* object = this->objects.front();
object->clear_instances();
- Sizef3 size = object->bounding_box().size();
+ Vec3d size = object->bounding_box().size();
for (size_t x_copy = 1; x_copy <= x; ++x_copy) {
for (size_t y_copy = 1; y_copy <= y; ++y_copy) {
ModelInstance* instance = object->add_instance();
- instance->offset.x = (size.x + dist) * (x_copy-1);
- instance->offset.y = (size.y + dist) * (y_copy-1);
+ instance->offset(0) = (size(0) + dist) * (x_copy-1);
+ instance->offset(1) = (size(1) + dist) * (y_copy-1);
}
}
}
@@ -387,7 +386,7 @@ bool Model::looks_like_multipart_object() const
if (obj->volumes.size() > 1 || obj->config.keys().size() > 1)
return false;
for (const ModelVolume *vol : obj->volumes) {
- double zmin_this = vol->mesh.bounding_box().min.z;
+ double zmin_this = vol->mesh.bounding_box().min(2);
if (zmin == std::numeric_limits<double>::max())
zmin = zmin_this;
else if (std::abs(zmin - zmin_this) > EPSILON)
@@ -398,17 +397,26 @@ bool Model::looks_like_multipart_object() const
return false;
}
-void Model::convert_multipart_object()
+void Model::convert_multipart_object(unsigned int max_extruders)
{
if (this->objects.empty())
return;
ModelObject* object = new ModelObject(this);
object->input_file = this->objects.front()->input_file;
-
+
+ reset_auto_extruder_id();
+
for (const ModelObject* o : this->objects)
for (const ModelVolume* v : o->volumes)
- object->add_volume(*v)->name = o->name;
+ {
+ ModelVolume* new_v = object->add_volume(*v);
+ if (new_v != nullptr)
+ {
+ new_v->name = o->name;
+ new_v->config.set_deserialize("extruder", get_auto_extruder_id_as_string(max_extruders));
+ }
+ }
for (const ModelInstance* i : this->objects.front()->instances)
object->add_instance(*i);
@@ -422,13 +430,13 @@ void Model::adjust_min_z()
if (objects.empty())
return;
- if (bounding_box().min.z < 0.0)
+ if (bounding_box().min(2) < 0.0)
{
for (ModelObject* obj : objects)
{
if (obj != nullptr)
{
- coordf_t obj_min_z = obj->bounding_box().min.z;
+ coordf_t obj_min_z = obj->bounding_box().min(2);
if (obj_min_z < 0.0)
obj->translate(0.0, 0.0, -obj_min_z);
}
@@ -436,30 +444,26 @@ void Model::adjust_min_z()
}
}
-bool Model::fits_print_volume(const DynamicPrintConfig* config) const
+unsigned int Model::get_auto_extruder_id(unsigned int max_extruders)
{
- if (config == nullptr)
- return false;
+ unsigned int id = s_auto_extruder_id;
- if (objects.empty())
- return true;
+ if (++s_auto_extruder_id > max_extruders)
+ reset_auto_extruder_id();
- const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config->option("bed_shape"));
- if (opt == nullptr)
- return false;
+ return id;
+}
- BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
- BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config->opt_float("max_print_height")));
- return print_volume.contains(transformed_bounding_box());
+std::string Model::get_auto_extruder_id_as_string(unsigned int max_extruders)
+{
+ char str_extruder[64];
+ sprintf(str_extruder, "%ud", get_auto_extruder_id(max_extruders));
+ return str_extruder;
}
-bool Model::fits_print_volume(const FullPrintConfig &config) const
+void Model::reset_auto_extruder_id()
{
- if (objects.empty())
- return true;
- BoundingBox bed_box_2D = get_extents(Polygon::new_scale(config.bed_shape.values));
- BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config.max_print_height));
- return print_volume.contains(transformed_bounding_box());
+ s_auto_extruder_id = 1;
}
ModelObject::ModelObject(Model *model, const ModelObject &other, bool copy_volumes) :
@@ -592,7 +596,7 @@ void ModelObject::clear_instances()
// Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug.
-const BoundingBoxf3& ModelObject::bounding_box()
+const BoundingBoxf3& ModelObject::bounding_box() const
{
if (! m_bounding_box_valid) {
BoundingBoxf3 raw_bbox;
@@ -608,54 +612,6 @@ const BoundingBoxf3& ModelObject::bounding_box()
return m_bounding_box;
}
-BoundingBoxf3 ModelObject::tight_bounding_box(bool include_modifiers) const
-{
- BoundingBoxf3 bb;
-
- for (const ModelVolume* vol : this->volumes)
- {
- if (include_modifiers || !vol->modifier)
- {
- for (const ModelInstance* inst : this->instances)
- {
- double c = cos(inst->rotation);
- double s = sin(inst->rotation);
-
- for (int f = 0; f < vol->mesh.stl.stats.number_of_facets; ++f)
- {
- const stl_facet& facet = vol->mesh.stl.facet_start[f];
-
- for (int i = 0; i < 3; ++i)
- {
- // original point
- const stl_vertex& v = facet.vertex[i];
- Pointf3 p((double)v.x, (double)v.y, (double)v.z);
-
- // scale
- p.x *= inst->scaling_factor;
- p.y *= inst->scaling_factor;
- p.z *= inst->scaling_factor;
-
- // rotate Z
- double x = p.x;
- double y = p.y;
- p.x = c * x - s * y;
- p.y = s * x + c * y;
-
- // translate
- p.x += inst->offset.x;
- p.y += inst->offset.y;
-
- bb.merge(p);
- }
- }
- }
- }
- }
-
- return bb;
-}
-
// A mesh containing all transformed instances of this object.
TriangleMesh ModelObject::mesh() const
{
@@ -713,25 +669,19 @@ void ModelObject::center_around_origin()
if (! v->modifier)
bb.merge(v->mesh.bounding_box());
- // first align to origin on XYZ
- Vectorf3 vector(-bb.min.x, -bb.min.y, -bb.min.z);
-
- // then center it on XY
- Sizef3 size = bb.size();
- vector.x -= size.x/2;
- vector.y -= size.y/2;
-
- this->translate(vector);
- this->origin_translation.translate(vector);
-
+ // Shift is the vector from the center of the bottom face of the bounding box to the origin
+ Vec3d shift = -bb.center();
+ shift(2) = -bb.min(2);
+
+ this->translate(shift);
+ this->origin_translation += shift;
+
if (!this->instances.empty()) {
for (ModelInstance *i : this->instances) {
// apply rotation and scaling to vector as well before translating instance,
// in order to leave final position unaltered
- Vectorf3 v = vector.negative();
- v.rotate(i->rotation);
- v.scale(i->scaling_factor);
- i->offset.translate(v.x, v.y);
+ Vec3d i_shift = i->world_matrix(true) * shift;
+ i->offset -= to_2d(i_shift);
}
this->invalidate_bounding_box();
}
@@ -740,47 +690,64 @@ void ModelObject::center_around_origin()
void ModelObject::translate(coordf_t x, coordf_t y, coordf_t z)
{
for (ModelVolume *v : this->volumes)
+ {
v->mesh.translate(float(x), float(y), float(z));
- if (m_bounding_box_valid)
+ v->m_convex_hull.translate(float(x), float(y), float(z));
+ }
+
+ if (m_bounding_box_valid)
m_bounding_box.translate(x, y, z);
}
-void ModelObject::scale(const Pointf3 &versor)
+void ModelObject::scale(const Vec3d &versor)
{
for (ModelVolume *v : this->volumes)
+ {
v->mesh.scale(versor);
+ v->m_convex_hull.scale(versor);
+ }
// reset origin translation since it doesn't make sense anymore
- this->origin_translation = Pointf3(0,0,0);
+ this->origin_translation = Vec3d::Zero();
this->invalidate_bounding_box();
}
-void ModelObject::rotate(float angle, const Axis &axis)
+void ModelObject::rotate(float angle, const Axis& axis)
{
for (ModelVolume *v : this->volumes)
+ {
v->mesh.rotate(angle, axis);
- this->origin_translation = Pointf3(0,0,0);
+ v->m_convex_hull.rotate(angle, axis);
+ }
+
+ center_around_origin();
+
+ this->origin_translation = Vec3d::Zero();
this->invalidate_bounding_box();
}
-void ModelObject::transform(const float* matrix3x4)
+void ModelObject::rotate(float angle, const Vec3d& axis)
{
- if (matrix3x4 == nullptr)
- return;
-
- for (ModelVolume* v : volumes)
+ for (ModelVolume *v : this->volumes)
{
- v->mesh.transform(matrix3x4);
+ v->mesh.rotate(angle, axis);
+ v->m_convex_hull.rotate(angle, axis);
}
- origin_translation = Pointf3(0.0, 0.0, 0.0);
- invalidate_bounding_box();
+ center_around_origin();
+
+ this->origin_translation = Vec3d::Zero();
+ this->invalidate_bounding_box();
}
void ModelObject::mirror(const Axis &axis)
{
for (ModelVolume *v : this->volumes)
+ {
v->mesh.mirror(axis);
- this->origin_translation = Pointf3(0,0,0);
+ v->m_convex_hull.mirror(axis);
+ }
+
+ this->origin_translation = Vec3d::Zero();
this->invalidate_bounding_box();
}
@@ -826,33 +793,8 @@ void ModelObject::cut(coordf_t z, Model* model) const
lower->add_volume(*volume);
} else {
TriangleMesh upper_mesh, lower_mesh;
- // TODO: shouldn't we use object bounding box instead of per-volume bb?
- coordf_t cut_z = z + volume->mesh.bounding_box().min.z;
- if (false) {
-// if (volume->mesh.has_multiple_patches()) {
- // Cutting algorithm does not work on intersecting meshes.
- // As we are not sure whether the meshes don't intersect,
- // we rather split the mesh into multiple non-intersecting pieces.
- TriangleMeshPtrs meshptrs = volume->mesh.split();
- for (TriangleMeshPtrs::iterator mesh = meshptrs.begin(); mesh != meshptrs.end(); ++mesh) {
- printf("Cutting mesh patch %d of %d\n", int(mesh - meshptrs.begin()), int(meshptrs.size()));
- (*mesh)->repair();
- TriangleMeshSlicer tms(*mesh);
- if (mesh == meshptrs.begin()) {
- tms.cut(cut_z, &upper_mesh, &lower_mesh);
- } else {
- TriangleMesh upper_mesh_this, lower_mesh_this;
- tms.cut(cut_z, &upper_mesh_this, &lower_mesh_this);
- upper_mesh.merge(upper_mesh_this);
- lower_mesh.merge(lower_mesh_this);
- }
- delete *mesh;
- }
- } else {
- printf("Cutting mesh patch\n");
- TriangleMeshSlicer tms(&volume->mesh);
- tms.cut(cut_z, &upper_mesh, &lower_mesh);
- }
+ TriangleMeshSlicer tms(&volume->mesh);
+ tms.cut(z, &upper_mesh, &lower_mesh);
upper_mesh.repair();
lower_mesh.repair();
@@ -907,6 +849,27 @@ void ModelObject::split(ModelObjectPtrs* new_objects)
return;
}
+void ModelObject::check_instances_print_volume_state(const BoundingBoxf3& print_volume)
+{
+ for (const ModelVolume* vol : this->volumes)
+ {
+ if (!vol->modifier)
+ {
+ for (ModelInstance* inst : this->instances)
+ {
+ BoundingBoxf3 bb = vol->get_convex_hull().transformed_bounding_box(inst->world_matrix());
+
+ if (print_volume.contains(bb))
+ inst->print_volume_state = ModelInstance::PVS_Inside;
+ else if (print_volume.intersects(bb))
+ inst->print_volume_state = ModelInstance::PVS_Partly_Outside;
+ else
+ inst->print_volume_state = ModelInstance::PVS_Fully_Outside;
+ }
+ }
+ }
+}
+
void ModelObject::print_info() const
{
using namespace std;
@@ -916,16 +879,16 @@ void ModelObject::print_info() const
TriangleMesh mesh = this->raw_mesh();
mesh.check_topology();
BoundingBoxf3 bb = mesh.bounding_box();
- Sizef3 size = bb.size();
- cout << "size_x = " << size.x << endl;
- cout << "size_y = " << size.y << endl;
- cout << "size_z = " << size.z << endl;
- cout << "min_x = " << bb.min.x << endl;
- cout << "min_y = " << bb.min.y << endl;
- cout << "min_z = " << bb.min.z << endl;
- cout << "max_x = " << bb.max.x << endl;
- cout << "max_y = " << bb.max.y << endl;
- cout << "max_z = " << bb.max.z << endl;
+ Vec3d size = bb.size();
+ cout << "size_x = " << size(0) << endl;
+ cout << "size_y = " << size(1) << endl;
+ cout << "size_z = " << size(2) << endl;
+ cout << "min_x = " << bb.min(0) << endl;
+ cout << "min_y = " << bb.min(1) << endl;
+ cout << "min_z = " << bb.min(2) << endl;
+ cout << "max_x = " << bb.max(0) << endl;
+ cout << "max_y = " << bb.max(1) << endl;
+ cout << "max_z = " << bb.max(2) << endl;
cout << "number_of_facets = " << mesh.stl.stats.number_of_facets << endl;
cout << "manifold = " << (mesh.is_manifold() ? "yes" : "no") << endl;
@@ -977,10 +940,20 @@ ModelMaterial* ModelVolume::assign_unique_material()
return model->add_material(this->_material_id);
}
+void ModelVolume::calculate_convex_hull()
+{
+ m_convex_hull = mesh.convex_hull_3d();
+}
+
+const TriangleMesh& ModelVolume::get_convex_hull() const
+{
+ return m_convex_hull;
+}
+
// Split this volume, append the result to the object owning this volume.
// Return the number of volumes created from this one.
// This is useful to assign different materials to different volumes of an object.
-size_t ModelVolume::split()
+size_t ModelVolume::split(unsigned int max_extruders)
{
TriangleMeshPtrs meshptrs = this->mesh.split();
if (meshptrs.size() <= 1) {
@@ -991,6 +964,9 @@ size_t ModelVolume::split()
size_t idx = 0;
size_t ivolume = std::find(this->object->volumes.begin(), this->object->volumes.end(), this) - this->object->volumes.begin();
std::string name = this->name;
+
+ Model::reset_auto_extruder_id();
+
for (TriangleMesh *mesh : meshptrs) {
mesh->repair();
if (idx == 0)
@@ -1000,6 +976,7 @@ size_t ModelVolume::split()
char str_idx[64];
sprintf(str_idx, "_%d", idx + 1);
this->object->volumes[ivolume]->name = name + str_idx;
+ this->object->volumes[ivolume]->config.set_deserialize("extruder", Model::get_auto_extruder_id_as_string(max_extruders));
delete mesh;
++ idx;
}
@@ -1009,45 +986,26 @@ size_t ModelVolume::split()
void ModelInstance::transform_mesh(TriangleMesh* mesh, bool dont_translate) const
{
- mesh->rotate_z(this->rotation); // rotate around mesh origin
- mesh->scale(this->scaling_factor); // scale around mesh origin
- if (!dont_translate)
- mesh->translate(this->offset.x, this->offset.y, 0);
+ mesh->transform(world_matrix(dont_translate).cast<float>());
}
BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mesh, bool dont_translate) const
{
// Rotate around mesh origin.
- double c = cos(this->rotation);
- double s = sin(this->rotation);
- BoundingBoxf3 bbox;
- for (int i = 0; i < mesh->stl.stats.number_of_facets; ++ i) {
- const stl_facet &facet = mesh->stl.facet_start[i];
- for (int j = 0; j < 3; ++ j) {
- stl_vertex v = facet.vertex[j];
- double xold = v.x;
- double yold = v.y;
- v.x = float(c * xold - s * yold);
- v.y = float(s * xold + c * yold);
- bbox.merge(Pointf3(v.x, v.y, v.z));
- }
- }
- if (! empty(bbox)) {
+ TriangleMesh copy(*mesh);
+ copy.transform(world_matrix(true, false, true).cast<float>());
+ BoundingBoxf3 bbox = copy.bounding_box();
+
+ if (!empty(bbox)) {
// Scale the bounding box uniformly.
if (std::abs(this->scaling_factor - 1.) > EPSILON) {
- bbox.min.x *= float(this->scaling_factor);
- bbox.min.y *= float(this->scaling_factor);
- bbox.min.z *= float(this->scaling_factor);
- bbox.max.x *= float(this->scaling_factor);
- bbox.max.y *= float(this->scaling_factor);
- bbox.max.z *= float(this->scaling_factor);
+ bbox.min *= this->scaling_factor;
+ bbox.max *= this->scaling_factor;
}
// Translate the bounding box.
if (! dont_translate) {
- bbox.min.x += float(this->offset.x);
- bbox.min.y += float(this->offset.y);
- bbox.max.x += float(this->offset.x);
- bbox.max.y += float(this->offset.y);
+ Eigen::Map<Vec2d>(bbox.min.data()) += this->offset;
+ Eigen::Map<Vec2d>(bbox.max.data()) += this->offset;
}
}
return bbox;
@@ -1055,32 +1013,12 @@ BoundingBoxf3 ModelInstance::transform_mesh_bounding_box(const TriangleMesh* mes
BoundingBoxf3 ModelInstance::transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate) const
{
- // rotate around mesh origin
- double c = cos(this->rotation);
- double s = sin(this->rotation);
- Pointf3 pts[4] = {
- bbox.min,
- bbox.max,
- Pointf3(bbox.min.x, bbox.max.y, bbox.min.z),
- Pointf3(bbox.max.x, bbox.min.y, bbox.max.z)
- };
- BoundingBoxf3 out;
- for (int i = 0; i < 4; ++ i) {
- Pointf3 &v = pts[i];
- double xold = v.x;
- double yold = v.y;
- v.x = float(c * xold - s * yold);
- v.y = float(s * xold + c * yold);
- v.x *= this->scaling_factor;
- v.y *= this->scaling_factor;
- v.z *= this->scaling_factor;
- if (! dont_translate) {
- v.x += this->offset.x;
- v.y += this->offset.y;
- }
- out.merge(v);
- }
- return out;
+ return bbox.transformed(world_matrix(dont_translate));
+}
+
+Vec3d ModelInstance::transform_vector(const Vec3d& v, bool dont_translate) const
+{
+ return world_matrix(dont_translate) * v;
}
void ModelInstance::transform_polygon(Polygon* polygon) const
@@ -1089,4 +1027,20 @@ void ModelInstance::transform_polygon(Polygon* polygon) const
polygon->scale(this->scaling_factor); // scale around polygon origin
}
+Transform3d ModelInstance::world_matrix(bool dont_translate, bool dont_rotate, bool dont_scale) const
+{
+ Transform3d m = Transform3d::Identity();
+
+ if (!dont_translate)
+ m.translate(Vec3d(offset(0), offset(1), 0.0));
+
+ if (!dont_rotate)
+ m.rotate(Eigen::AngleAxisd(rotation, Vec3d::UnitZ()));
+
+ if (!dont_scale)
+ m.scale(scaling_factor);
+
+ return m;
+}
+
}
diff --git a/xs/src/libslic3r/Model.hpp b/xs/src/libslic3r/Model.hpp
index bf7f60e36..8a8af481c 100644
--- a/xs/src/libslic3r/Model.hpp
+++ b/xs/src/libslic3r/Model.hpp
@@ -84,7 +84,7 @@ public:
center_around_origin() method. Callers might want to apply the same translation
to new volumes before adding them to this object in order to preserve alignment
when user expects that. */
- Pointf3 origin_translation;
+ Vec3d origin_translation;
Model* get_model() const { return m_model; };
@@ -103,11 +103,8 @@ public:
// Returns the bounding box of the transformed instances.
// This bounding box is approximate and not snug.
// This bounding box is being cached.
- const BoundingBoxf3& bounding_box();
+ const BoundingBoxf3& bounding_box() const;
void invalidate_bounding_box() { m_bounding_box_valid = false; }
- // Returns a snug bounding box of the transformed instances.
- // This bounding box is not being cached.
- BoundingBoxf3 tight_bounding_box(bool include_modifiers) const;
// A mesh containing all transformed instances of this object.
TriangleMesh mesh() const;
@@ -120,11 +117,11 @@ public:
// A snug bounding box around the transformed non-modifier object volumes.
BoundingBoxf3 instance_bounding_box(size_t instance_idx, bool dont_translate = false) const;
void center_around_origin();
- void translate(const Vectorf3 &vector) { this->translate(vector.x, vector.y, vector.z); }
+ void translate(const Vec3d &vector) { this->translate(vector(0), vector(1), vector(2)); }
void translate(coordf_t x, coordf_t y, coordf_t z);
- void scale(const Pointf3 &versor);
+ void scale(const Vec3d &versor);
void rotate(float angle, const Axis &axis);
- void transform(const float* matrix3x4);
+ void rotate(float angle, const Vec3d& axis);
void mirror(const Axis &axis);
size_t materials_count() const;
size_t facets_count() const;
@@ -132,11 +129,13 @@ public:
void cut(coordf_t z, Model* model) const;
void split(ModelObjectPtrs* new_objects);
+ void check_instances_print_volume_state(const BoundingBoxf3& print_volume);
+
// Print object statistics to console.
void print_info() const;
private:
- ModelObject(Model *model) : layer_height_profile_valid(false), m_model(model), m_bounding_box_valid(false) {}
+ ModelObject(Model *model) : layer_height_profile_valid(false), m_model(model), origin_translation(Vec3d::Zero()), m_bounding_box_valid(false) {}
ModelObject(Model *model, const ModelObject &other, bool copy_volumes = true);
ModelObject& operator= (ModelObject other);
void swap(ModelObject &other);
@@ -145,8 +144,9 @@ private:
// Parent object, owning this ModelObject.
Model *m_model;
// Bounding box, cached.
- BoundingBoxf3 m_bounding_box;
- bool m_bounding_box_valid;
+
+ mutable BoundingBoxf3 m_bounding_box;
+ mutable bool m_bounding_box_valid;
};
// An object STL, or a modifier volume, over which a different set of parameters shall be applied.
@@ -154,6 +154,10 @@ private:
class ModelVolume
{
friend class ModelObject;
+
+ // The convex hull of this model's mesh.
+ TriangleMesh m_convex_hull;
+
public:
std::string name;
// The triangular model.
@@ -173,36 +177,61 @@ public:
// Split this volume, append the result to the object owning this volume.
// Return the number of volumes created from this one.
// This is useful to assign different materials to different volumes of an object.
- size_t split();
-
+ size_t split(unsigned int max_extruders);
+
ModelMaterial* assign_unique_material();
+ void calculate_convex_hull();
+ const TriangleMesh& get_convex_hull() const;
+
private:
// Parent object owning this ModelVolume.
ModelObject* object;
t_model_material_id _material_id;
- ModelVolume(ModelObject *object, const TriangleMesh &mesh) : mesh(mesh), modifier(false), object(object) {}
- ModelVolume(ModelObject *object, TriangleMesh &&mesh) : mesh(std::move(mesh)), modifier(false), object(object) {}
- ModelVolume(ModelObject *object, const ModelVolume &other) :
- name(other.name), mesh(other.mesh), config(other.config), modifier(other.modifier), object(object)
- { this->material_id(other.material_id()); }
- ModelVolume(ModelObject *object, const ModelVolume &other, const TriangleMesh &&mesh) :
+ ModelVolume(ModelObject *object, const TriangleMesh &mesh) : mesh(mesh), modifier(false), object(object)
+ {
+ if (mesh.stl.stats.number_of_facets > 1)
+ calculate_convex_hull();
+ }
+ ModelVolume(ModelObject *object, TriangleMesh &&mesh, TriangleMesh &&convex_hull) : mesh(std::move(mesh)), m_convex_hull(std::move(convex_hull)), modifier(false), object(object) {}
+ ModelVolume(ModelObject *object, const ModelVolume &other) :
+ name(other.name), mesh(other.mesh), m_convex_hull(other.m_convex_hull), config(other.config), modifier(other.modifier), object(object)
+ {
+ this->material_id(other.material_id());
+ }
+ ModelVolume(ModelObject *object, const ModelVolume &other, const TriangleMesh &&mesh) :
name(other.name), mesh(std::move(mesh)), config(other.config), modifier(other.modifier), object(object)
- { this->material_id(other.material_id()); }
+ {
+ this->material_id(other.material_id());
+ if (mesh.stl.stats.number_of_facets > 1)
+ calculate_convex_hull();
+ }
};
// A single instance of a ModelObject.
// Knows the affine transformation of an object.
class ModelInstance
{
- friend class ModelObject;
public:
+ enum EPrintVolumeState : unsigned char
+ {
+ PVS_Inside,
+ PVS_Partly_Outside,
+ PVS_Fully_Outside,
+ Num_BedStates
+ };
+
+ friend class ModelObject;
+
double rotation; // Rotation around the Z axis, in radians around mesh center point
double scaling_factor;
- Pointf offset; // in unscaled coordinates
+ Vec2d offset; // in unscaled coordinates
- ModelObject* get_object() const { return this->object; };
+ // flag showing the position of this instance with respect to the print volume (set by Print::validate() using ModelObject::check_instances_print_volume_state())
+ EPrintVolumeState print_volume_state;
+
+ ModelObject* get_object() const { return this->object; }
// To be called on an external mesh
void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const;
@@ -210,16 +239,22 @@ public:
BoundingBoxf3 transform_mesh_bounding_box(const TriangleMesh* mesh, bool dont_translate = false) const;
// Transform an external bounding box.
BoundingBoxf3 transform_bounding_box(const BoundingBoxf3 &bbox, bool dont_translate = false) const;
+ // Transform an external vector.
+ Vec3d transform_vector(const Vec3d& v, bool dont_translate = false) const;
// To be called on an external polygon. It does not translate the polygon, only rotates and scales.
void transform_polygon(Polygon* polygon) const;
-
+
+ Transform3d world_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false) const;
+
+ bool is_printable() const { return print_volume_state == PVS_Inside; }
+
private:
// Parent object, owning this instance.
ModelObject* object;
- ModelInstance(ModelObject *object) : rotation(0), scaling_factor(1), object(object) {}
+ ModelInstance(ModelObject *object) : rotation(0), scaling_factor(1), offset(Vec2d::Zero()), object(object), print_volume_state(PVS_Inside) {}
ModelInstance(ModelObject *object, const ModelInstance &other) :
- rotation(other.rotation), scaling_factor(other.scaling_factor), offset(other.offset), object(object) {}
+ rotation(other.rotation), scaling_factor(other.scaling_factor), offset(other.offset), object(object), print_volume_state(PVS_Inside) {}
};
@@ -230,6 +265,8 @@ private:
// all objects may share mutliple materials.
class Model
{
+ static unsigned int s_auto_extruder_id;
+
public:
// Materials are owned by a model and referenced by objects through t_model_material_id.
// Single material may be shared by multiple models.
@@ -266,9 +303,7 @@ public:
bool add_default_instances();
// Returns approximate axis aligned bounding box of this model
BoundingBoxf3 bounding_box() const;
- // Returns tight axis aligned bounding box of this model
- BoundingBoxf3 transformed_bounding_box() const;
- void center_instances_around_point(const Pointf &point);
+ void center_instances_around_point(const Vec2d &point);
void translate(coordf_t x, coordf_t y, coordf_t z) { for (ModelObject *o : this->objects) o->translate(x, y, z); }
TriangleMesh mesh() const;
bool arrange_objects(coordf_t dist, const BoundingBoxf* bb = NULL);
@@ -278,16 +313,16 @@ public:
void duplicate_objects_grid(size_t x, size_t y, coordf_t dist);
bool looks_like_multipart_object() const;
- void convert_multipart_object();
+ void convert_multipart_object(unsigned int max_extruders);
// Ensures that the min z of the model is not negative
void adjust_min_z();
- // Returs true if this model is contained into the print volume defined inside the given config
- bool fits_print_volume(const DynamicPrintConfig* config) const;
- bool fits_print_volume(const FullPrintConfig &config) const;
-
void print_info() const { for (const ModelObject *o : this->objects) o->print_info(); }
+
+ static unsigned int get_auto_extruder_id(unsigned int max_extruders);
+ static std::string get_auto_extruder_id_as_string(unsigned int max_extruders);
+ static void reset_auto_extruder_id();
};
}
diff --git a/xs/src/libslic3r/ModelArrange.hpp b/xs/src/libslic3r/ModelArrange.hpp
new file mode 100644
index 000000000..36bd8ed97
--- /dev/null
+++ b/xs/src/libslic3r/ModelArrange.hpp
@@ -0,0 +1,788 @@
+#ifndef MODELARRANGE_HPP
+#define MODELARRANGE_HPP
+
+#include "Model.hpp"
+#include "SVG.hpp"
+#include <libnest2d.h>
+
+#include <numeric>
+#include <ClipperUtils.hpp>
+
+#include <boost/geometry/index/rtree.hpp>
+
+namespace Slic3r {
+namespace arr {
+
+using namespace libnest2d;
+
+std::string toString(const Model& model, bool holes = true) {
+ std::stringstream ss;
+
+ ss << "{\n";
+
+ for(auto objptr : model.objects) {
+ if(!objptr) continue;
+
+ auto rmesh = objptr->raw_mesh();
+
+ for(auto objinst : objptr->instances) {
+ if(!objinst) continue;
+
+ Slic3r::TriangleMesh tmpmesh = rmesh;
+ tmpmesh.scale(objinst->scaling_factor);
+ objinst->transform_mesh(&tmpmesh);
+ ExPolygons expolys = tmpmesh.horizontal_projection();
+ for(auto& expoly_complex : expolys) {
+
+ auto tmp = expoly_complex.simplify(1.0/SCALING_FACTOR);
+ if(tmp.empty()) continue;
+ auto expoly = tmp.front();
+ expoly.contour.make_clockwise();
+ for(auto& h : expoly.holes) h.make_counter_clockwise();
+
+ ss << "\t{\n";
+ ss << "\t\t{\n";
+
+ for(auto v : expoly.contour.points) ss << "\t\t\t{"
+ << v(0) << ", "
+ << v(1) << "},\n";
+ {
+ auto v = expoly.contour.points.front();
+ ss << "\t\t\t{" << v(0) << ", " << v(1) << "},\n";
+ }
+ ss << "\t\t},\n";
+
+ // Holes:
+ ss << "\t\t{\n";
+ if(holes) for(auto h : expoly.holes) {
+ ss << "\t\t\t{\n";
+ for(auto v : h.points) ss << "\t\t\t\t{"
+ << v(0) << ", "
+ << v(1) << "},\n";
+ {
+ auto v = h.points.front();
+ ss << "\t\t\t\t{" << v(0) << ", " << v(1) << "},\n";
+ }
+ ss << "\t\t\t},\n";
+ }
+ ss << "\t\t},\n";
+
+ ss << "\t},\n";
+ }
+ }
+ }
+
+ ss << "}\n";
+
+ return ss.str();
+}
+
+void toSVG(SVG& svg, const Model& model) {
+ for(auto objptr : model.objects) {
+ if(!objptr) continue;
+
+ auto rmesh = objptr->raw_mesh();
+
+ for(auto objinst : objptr->instances) {
+ if(!objinst) continue;
+
+ Slic3r::TriangleMesh tmpmesh = rmesh;
+ tmpmesh.scale(objinst->scaling_factor);
+ objinst->transform_mesh(&tmpmesh);
+ ExPolygons expolys = tmpmesh.horizontal_projection();
+ svg.draw(expolys);
+ }
+ }
+}
+
+namespace bgi = boost::geometry::index;
+
+using SpatElement = std::pair<Box, unsigned>;
+using SpatIndex = bgi::rtree< SpatElement, bgi::rstar<16, 4> >;
+using ItemGroup = std::vector<std::reference_wrapper<Item>>;
+template<class TBin>
+using TPacker = typename placers::_NofitPolyPlacer<PolygonImpl, TBin>;
+
+const double BIG_ITEM_TRESHOLD = 0.02;
+
+Box boundingBox(const Box& pilebb, const Box& ibb ) {
+ auto& pminc = pilebb.minCorner();
+ auto& pmaxc = pilebb.maxCorner();
+ auto& iminc = ibb.minCorner();
+ auto& imaxc = ibb.maxCorner();
+ PointImpl minc, maxc;
+
+ setX(minc, std::min(getX(pminc), getX(iminc)));
+ setY(minc, std::min(getY(pminc), getY(iminc)));
+
+ setX(maxc, std::max(getX(pmaxc), getX(imaxc)));
+ setY(maxc, std::max(getY(pmaxc), getY(imaxc)));
+ return Box(minc, maxc);
+}
+
+std::tuple<double /*score*/, Box /*farthest point from bin center*/>
+objfunc(const PointImpl& bincenter,
+ const shapelike::Shapes<PolygonImpl>& merged_pile,
+ const Box& pilebb,
+ const ItemGroup& items,
+ const Item &item,
+ double bin_area,
+ double norm, // A norming factor for physical dimensions
+ // a spatial index to quickly get neighbors of the candidate item
+ const SpatIndex& spatindex,
+ const ItemGroup& remaining
+ )
+{
+ using Coord = TCoord<PointImpl>;
+
+ static const double ROUNDNESS_RATIO = 0.5;
+ static const double DENSITY_RATIO = 1.0 - ROUNDNESS_RATIO;
+
+ // We will treat big items (compared to the print bed) differently
+ auto isBig = [bin_area](double a) {
+ return a/bin_area > BIG_ITEM_TRESHOLD ;
+ };
+
+ // Candidate item bounding box
+ auto ibb = sl::boundingBox(item.transformedShape());
+
+ // Calculate the full bounding box of the pile with the candidate item
+ auto fullbb = boundingBox(pilebb, ibb);
+
+ // The bounding box of the big items (they will accumulate in the center
+ // of the pile
+ Box bigbb;
+ if(spatindex.empty()) bigbb = fullbb;
+ else {
+ auto boostbb = spatindex.bounds();
+ boost::geometry::convert(boostbb, bigbb);
+ }
+
+ // Will hold the resulting score
+ double score = 0;
+
+ if(isBig(item.area())) {
+ // This branch is for the bigger items..
+
+ auto minc = ibb.minCorner(); // bottom left corner
+ auto maxc = ibb.maxCorner(); // top right corner
+
+ // top left and bottom right corners
+ auto top_left = PointImpl{getX(minc), getY(maxc)};
+ auto bottom_right = PointImpl{getX(maxc), getY(minc)};
+
+ // Now the distance of the gravity center will be calculated to the
+ // five anchor points and the smallest will be chosen.
+ std::array<double, 5> dists;
+ auto cc = fullbb.center(); // The gravity center
+ dists[0] = pl::distance(minc, cc);
+ dists[1] = pl::distance(maxc, cc);
+ dists[2] = pl::distance(ibb.center(), cc);
+ dists[3] = pl::distance(top_left, cc);
+ dists[4] = pl::distance(bottom_right, cc);
+
+ // The smalles distance from the arranged pile center:
+ auto dist = *(std::min_element(dists.begin(), dists.end())) / norm;
+
+ // Density is the pack density: how big is the arranged pile
+ double density = 0;
+
+ if(remaining.empty()) {
+
+ auto mp = merged_pile;
+ mp.emplace_back(item.transformedShape());
+ auto chull = sl::convexHull(mp);
+
+ placers::EdgeCache<PolygonImpl> ec(chull);
+
+ double circ = ec.circumference() / norm;
+ double bcirc = 2.0*(fullbb.width() + fullbb.height()) / norm;
+ score = 0.5*circ + 0.5*bcirc;
+
+ } else {
+ // Prepare a variable for the alignment score.
+ // This will indicate: how well is the candidate item aligned with
+ // its neighbors. We will check the alignment with all neighbors and
+ // return the score for the best alignment. So it is enough for the
+ // candidate to be aligned with only one item.
+ auto alignment_score = 1.0;
+
+ density = (fullbb.width()*fullbb.height()) / (norm*norm);
+ auto querybb = item.boundingBox();
+
+ // Query the spatial index for the neighbors
+ std::vector<SpatElement> result;
+ result.reserve(spatindex.size());
+ spatindex.query(bgi::intersects(querybb),
+ std::back_inserter(result));
+
+ for(auto& e : result) { // now get the score for the best alignment
+ auto idx = e.second;
+ Item& p = items[idx];
+ auto parea = p.area();
+ if(std::abs(1.0 - parea/item.area()) < 1e-6) {
+ auto bb = boundingBox(p.boundingBox(), ibb);
+ auto bbarea = bb.area();
+ auto ascore = 1.0 - (item.area() + parea)/bbarea;
+
+ if(ascore < alignment_score) alignment_score = ascore;
+ }
+ }
+
+ // The final mix of the score is the balance between the distance
+ // from the full pile center, the pack density and the
+ // alignment with the neighbors
+ if(result.empty())
+ score = 0.5 * dist + 0.5 * density;
+ else
+ score = 0.45 * dist + 0.45 * density + 0.1 * alignment_score;
+ }
+ } else if( !isBig(item.area()) && spatindex.empty()) {
+ auto bindist = pl::distance(ibb.center(), bincenter) / norm;
+ // Bindist is surprisingly enough...
+ score = bindist;
+ } else {
+ // Here there are the small items that should be placed around the
+ // already processed bigger items.
+ // No need to play around with the anchor points, the center will be
+ // just fine for small items
+ score = pl::distance(ibb.center(), bigbb.center()) / norm;
+ }
+
+ return std::make_tuple(score, fullbb);
+}
+
+template<class PConf>
+void fillConfig(PConf& pcfg) {
+
+ // Align the arranged pile into the center of the bin
+ pcfg.alignment = PConf::Alignment::CENTER;
+
+ // Start placing the items from the center of the print bed
+ pcfg.starting_point = PConf::Alignment::CENTER;
+
+ // TODO cannot use rotations until multiple objects of same geometry can
+ // handle different rotations
+ // arranger.useMinimumBoundigBoxRotation();
+ pcfg.rotations = { 0.0 };
+
+ // The accuracy of optimization.
+ // Goes from 0.0 to 1.0 and scales performance as well
+ pcfg.accuracy = 0.65f;
+
+ pcfg.parallel = true;
+}
+
+template<class TBin>
+class AutoArranger {};
+
+template<class TBin>
+class _ArrBase {
+protected:
+
+ using Placer = TPacker<TBin>;
+ using Selector = FirstFitSelection;
+ using Packer = Nester<Placer, Selector>;
+ using PConfig = typename Packer::PlacementConfig;
+ using Distance = TCoord<PointImpl>;
+ using Pile = sl::Shapes<PolygonImpl>;
+
+ Packer pck_;
+ PConfig pconf_; // Placement configuration
+ double bin_area_;
+ SpatIndex rtree_;
+ double norm_;
+ Pile merged_pile_;
+ Box pilebb_;
+ ItemGroup remaining_;
+ ItemGroup items_;
+public:
+
+ _ArrBase(const TBin& bin, Distance dist,
+ std::function<void(unsigned)> progressind):
+ pck_(bin, dist), bin_area_(sl::area(bin)),
+ norm_(std::sqrt(sl::area(bin)))
+ {
+ fillConfig(pconf_);
+
+ pconf_.before_packing =
+ [this](const Pile& merged_pile, // merged pile
+ const ItemGroup& items, // packed items
+ const ItemGroup& remaining) // future items to be packed
+ {
+ items_ = items;
+ merged_pile_ = merged_pile;
+ remaining_ = remaining;
+
+ pilebb_ = sl::boundingBox(merged_pile);
+
+ rtree_.clear();
+
+ // We will treat big items (compared to the print bed) differently
+ auto isBig = [this](double a) {
+ return a/bin_area_ > BIG_ITEM_TRESHOLD ;
+ };
+
+ for(unsigned idx = 0; idx < items.size(); ++idx) {
+ Item& itm = items[idx];
+ if(isBig(itm.area())) rtree_.insert({itm.boundingBox(), idx});
+ }
+ };
+
+ pck_.progressIndicator(progressind);
+ }
+
+ template<class...Args> inline IndexedPackGroup operator()(Args&&...args) {
+ rtree_.clear();
+ return pck_.executeIndexed(std::forward<Args>(args)...);
+ }
+};
+
+template<>
+class AutoArranger<Box>: public _ArrBase<Box> {
+public:
+
+ AutoArranger(const Box& bin, Distance dist,
+ std::function<void(unsigned)> progressind):
+ _ArrBase<Box>(bin, dist, progressind)
+ {
+
+ pconf_.object_function = [this, bin] (const Item &item) {
+
+ auto result = objfunc(bin.center(),
+ merged_pile_,
+ pilebb_,
+ items_,
+ item,
+ bin_area_,
+ norm_,
+ rtree_,
+ remaining_);
+
+ double score = std::get<0>(result);
+ auto& fullbb = std::get<1>(result);
+
+ double miss = Placer::overfit(fullbb, bin);
+ miss = miss > 0? miss : 0;
+ score += miss*miss;
+
+ return score;
+ };
+
+ pck_.configure(pconf_);
+ }
+};
+
+using lnCircle = libnest2d::_Circle<libnest2d::PointImpl>;
+
+template<>
+class AutoArranger<lnCircle>: public _ArrBase<lnCircle> {
+public:
+
+ AutoArranger(const lnCircle& bin, Distance dist,
+ std::function<void(unsigned)> progressind):
+ _ArrBase<lnCircle>(bin, dist, progressind) {
+
+ pconf_.object_function = [this, &bin] (const Item &item) {
+
+ auto result = objfunc(bin.center(),
+ merged_pile_,
+ pilebb_,
+ items_,
+ item,
+ bin_area_,
+ norm_,
+ rtree_,
+ remaining_);
+
+ double score = std::get<0>(result);
+
+ auto isBig = [this](const Item& itm) {
+ return itm.area()/bin_area_ > BIG_ITEM_TRESHOLD ;
+ };
+
+ if(isBig(item)) {
+ auto mp = merged_pile_;
+ mp.push_back(item.transformedShape());
+ auto chull = sl::convexHull(mp);
+ double miss = Placer::overfit(chull, bin);
+ if(miss < 0) miss = 0;
+ score += miss*miss;
+ }
+
+ return score;
+ };
+
+ pck_.configure(pconf_);
+ }
+};
+
+template<>
+class AutoArranger<PolygonImpl>: public _ArrBase<PolygonImpl> {
+public:
+ AutoArranger(const PolygonImpl& bin, Distance dist,
+ std::function<void(unsigned)> progressind):
+ _ArrBase<PolygonImpl>(bin, dist, progressind)
+ {
+ pconf_.object_function = [this, &bin] (const Item &item) {
+
+ auto binbb = sl::boundingBox(bin);
+ auto result = objfunc(binbb.center(),
+ merged_pile_,
+ pilebb_,
+ items_,
+ item,
+ bin_area_,
+ norm_,
+ rtree_,
+ remaining_);
+ double score = std::get<0>(result);
+
+ return score;
+ };
+
+ pck_.configure(pconf_);
+ }
+};
+
+template<> // Specialization with no bin
+class AutoArranger<bool>: public _ArrBase<Box> {
+public:
+
+ AutoArranger(Distance dist, std::function<void(unsigned)> progressind):
+ _ArrBase<Box>(Box(0, 0), dist, progressind)
+ {
+ this->pconf_.object_function = [this] (const Item &item) {
+
+ auto result = objfunc({0, 0},
+ merged_pile_,
+ pilebb_,
+ items_,
+ item,
+ 0,
+ norm_,
+ rtree_,
+ remaining_);
+ return std::get<0>(result);
+ };
+
+ this->pck_.configure(pconf_);
+ }
+};
+
+// A container which stores a pointer to the 3D object and its projected
+// 2D shape from top view.
+using ShapeData2D =
+ std::vector<std::pair<Slic3r::ModelInstance*, Item>>;
+
+ShapeData2D projectModelFromTop(const Slic3r::Model &model) {
+ ShapeData2D ret;
+
+ auto s = std::accumulate(model.objects.begin(), model.objects.end(), 0,
+ [](size_t s, ModelObject* o){
+ return s + o->instances.size();
+ });
+
+ ret.reserve(s);
+
+ for(auto objptr : model.objects) {
+ if(objptr) {
+
+ auto rmesh = objptr->raw_mesh();
+
+ for(auto objinst : objptr->instances) {
+ if(objinst) {
+ Slic3r::TriangleMesh tmpmesh = rmesh;
+ ClipperLib::PolygonImpl pn;
+
+ tmpmesh.scale(objinst->scaling_factor);
+
+ // TODO export the exact 2D projection
+ auto p = tmpmesh.convex_hull();
+
+ p.make_clockwise();
+ p.append(p.first_point());
+ pn.Contour = Slic3rMultiPoint_to_ClipperPath( p );
+
+ // Efficient conversion to item.
+ Item item(std::move(pn));
+
+ // Invalid geometries would throw exceptions when arranging
+ if(item.vertexCount() > 3) {
+ item.rotation(objinst->rotation);
+ item.translation( {
+ ClipperLib::cInt(objinst->offset(0)/SCALING_FACTOR),
+ ClipperLib::cInt(objinst->offset(1)/SCALING_FACTOR)
+ });
+ ret.emplace_back(objinst, item);
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+class Circle {
+ Point center_;
+ double radius_;
+public:
+
+ inline Circle(): center_(0, 0), radius_(std::nan("")) {}
+ inline Circle(const Point& c, double r): center_(c), radius_(r) {}
+
+ inline double radius() const { return radius_; }
+ inline const Point& center() const { return center_; }
+ inline operator bool() { return !std::isnan(radius_); }
+ inline operator lnCircle() {
+ return lnCircle({center_(0), center_(1)}, radius_);
+ }
+};
+
+enum class BedShapeType {
+ BOX,
+ CIRCLE,
+ IRREGULAR,
+ WHO_KNOWS
+};
+
+struct BedShapeHint {
+ BedShapeType type;
+ /*union*/ struct { // I know but who cares...
+ Circle circ;
+ BoundingBox box;
+ Polyline polygon;
+ } shape;
+};
+
+BedShapeHint bedShape(const Polyline& bed) {
+ BedShapeHint ret;
+
+ auto x = [](const Point& p) { return p(0); };
+ auto y = [](const Point& p) { return p(1); };
+
+ auto width = [x](const BoundingBox& box) {
+ return x(box.max) - x(box.min);
+ };
+
+ auto height = [y](const BoundingBox& box) {
+ return y(box.max) - y(box.min);
+ };
+
+ auto area = [&width, &height](const BoundingBox& box) {
+ double w = width(box);
+ double h = height(box);
+ return w*h;
+ };
+
+ auto poly_area = [](Polyline p) {
+ Polygon pp; pp.points.reserve(p.points.size() + 1);
+ pp.points = std::move(p.points);
+ pp.points.emplace_back(pp.points.front());
+ return std::abs(pp.area());
+ };
+
+ auto distance_to = [x, y](const Point& p1, const Point& p2) {
+ double dx = x(p2) - x(p1);
+ double dy = y(p2) - y(p1);
+ return std::sqrt(dx*dx + dy*dy);
+ };
+
+ auto bb = bed.bounding_box();
+
+ auto isCircle = [bb, distance_to](const Polyline& polygon) {
+ auto center = bb.center();
+ std::vector<double> vertex_distances;
+ double avg_dist = 0;
+ for (auto pt: polygon.points)
+ {
+ double distance = distance_to(center, pt);
+ vertex_distances.push_back(distance);
+ avg_dist += distance;
+ }
+
+ avg_dist /= vertex_distances.size();
+
+ Circle ret(center, avg_dist);
+ for (auto el: vertex_distances)
+ {
+ if (abs(el - avg_dist) > 10 * SCALED_EPSILON)
+ ret = Circle();
+ break;
+ }
+
+ return ret;
+ };
+
+ auto parea = poly_area(bed);
+
+ if( (1.0 - parea/area(bb)) < 1e-3 ) {
+ ret.type = BedShapeType::BOX;
+ ret.shape.box = bb;
+ }
+ else if(auto c = isCircle(bed)) {
+ ret.type = BedShapeType::CIRCLE;
+ ret.shape.circ = c;
+ } else {
+ ret.type = BedShapeType::IRREGULAR;
+ ret.shape.polygon = bed;
+ }
+
+ // Determine the bed shape by hand
+ return ret;
+}
+
+void applyResult(
+ IndexedPackGroup::value_type& group,
+ Coord batch_offset,
+ ShapeData2D& shapemap)
+{
+ for(auto& r : group) {
+ auto idx = r.first; // get the original item index
+ Item& item = r.second; // get the item itself
+
+ // Get the model instance from the shapemap using the index
+ ModelInstance *inst_ptr = shapemap[idx].first;
+
+ // Get the tranformation data from the item object and scale it
+ // appropriately
+ auto off = item.translation();
+ Radians rot = item.rotation();
+ Vec2d foff(off.X*SCALING_FACTOR + batch_offset, off.Y*SCALING_FACTOR);
+
+ // write the tranformation data into the model instance
+ inst_ptr->rotation = rot;
+ inst_ptr->offset = foff;
+ }
+}
+
+
+/**
+ * \brief Arranges the model objects on the screen.
+ *
+ * The arrangement considers multiple bins (aka. print beds) for placing all
+ * the items provided in the model argument. If the items don't fit on one
+ * print bed, the remaining will be placed onto newly created print beds.
+ * The first_bin_only parameter, if set to true, disables this behaviour and
+ * makes sure that only one print bed is filled and the remaining items will be
+ * untouched. When set to false, the items which could not fit onto the
+ * print bed will be placed next to the print bed so the user should see a
+ * pile of items on the print bed and some other piles outside the print
+ * area that can be dragged later onto the print bed as a group.
+ *
+ * \param model The model object with the 3D content.
+ * \param dist The minimum distance which is allowed for any pair of items
+ * on the print bed in any direction.
+ * \param bb The bounding box of the print bed. It corresponds to the 'bin'
+ * for bin packing.
+ * \param first_bin_only This parameter controls whether to place the
+ * remaining items which do not fit onto the print area next to the print
+ * bed or leave them untouched (let the user arrange them by hand or remove
+ * them).
+ */
+bool arrange(Model &model, coordf_t min_obj_distance,
+ const Slic3r::Polyline& bed,
+ BedShapeHint bedhint,
+ bool first_bin_only,
+ std::function<void(unsigned)> progressind)
+{
+ using ArrangeResult = _IndexedPackGroup<PolygonImpl>;
+
+ bool ret = true;
+
+ // Get the 2D projected shapes with their 3D model instance pointers
+ auto shapemap = arr::projectModelFromTop(model);
+
+ // Copy the references for the shapes only as the arranger expects a
+ // sequence of objects convertible to Item or ClipperPolygon
+ std::vector<std::reference_wrapper<Item>> shapes;
+ shapes.reserve(shapemap.size());
+ std::for_each(shapemap.begin(), shapemap.end(),
+ [&shapes] (ShapeData2D::value_type& it)
+ {
+ shapes.push_back(std::ref(it.second));
+ });
+
+ IndexedPackGroup result;
+
+ if(bedhint.type == BedShapeType::WHO_KNOWS) bedhint = bedShape(bed);
+
+ BoundingBox bbb(bed);
+
+ auto binbb = Box({
+ static_cast<libnest2d::Coord>(bbb.min(0)),
+ static_cast<libnest2d::Coord>(bbb.min(1))
+ },
+ {
+ static_cast<libnest2d::Coord>(bbb.max(0)),
+ static_cast<libnest2d::Coord>(bbb.max(1))
+ });
+
+ switch(bedhint.type) {
+ case BedShapeType::BOX: {
+
+ // Create the arranger for the box shaped bed
+ AutoArranger<Box> arrange(binbb, min_obj_distance, progressind);
+
+ // Arrange and return the items with their respective indices within the
+ // input sequence.
+ result = arrange(shapes.begin(), shapes.end());
+ break;
+ }
+ case BedShapeType::CIRCLE: {
+
+ auto c = bedhint.shape.circ;
+ auto cc = lnCircle(c);
+
+ AutoArranger<lnCircle> arrange(cc, min_obj_distance, progressind);
+ result = arrange(shapes.begin(), shapes.end());
+ break;
+ }
+ case BedShapeType::IRREGULAR:
+ case BedShapeType::WHO_KNOWS: {
+
+ using P = libnest2d::PolygonImpl;
+
+ auto ctour = Slic3rMultiPoint_to_ClipperPath(bed);
+ P irrbed = sl::create<PolygonImpl>(std::move(ctour));
+
+ AutoArranger<P> arrange(irrbed, min_obj_distance, progressind);
+
+ // Arrange and return the items with their respective indices within the
+ // input sequence.
+ result = arrange(shapes.begin(), shapes.end());
+ break;
+ }
+ };
+
+ if(result.empty()) return false;
+
+ if(first_bin_only) {
+ applyResult(result.front(), 0, shapemap);
+ } else {
+
+ const auto STRIDE_PADDING = 1.2;
+
+ Coord stride = static_cast<Coord>(STRIDE_PADDING*
+ binbb.width()*SCALING_FACTOR);
+ Coord batch_offset = 0;
+
+ for(auto& group : result) {
+ applyResult(group, batch_offset, shapemap);
+
+ // Only the first pack group can be placed onto the print bed. The
+ // other objects which could not fit will be placed next to the
+ // print bed
+ batch_offset += stride;
+ }
+ }
+
+ for(auto objptr : model.objects) objptr->invalidate_bounding_box();
+
+ return ret && result.size() == 1;
+}
+
+}
+}
+#endif // MODELARRANGE_HPP
diff --git a/xs/src/libslic3r/MotionPlanner.cpp b/xs/src/libslic3r/MotionPlanner.cpp
index e8605d68c..ff3475ed8 100644
--- a/xs/src/libslic3r/MotionPlanner.cpp
+++ b/xs/src/libslic3r/MotionPlanner.cpp
@@ -58,7 +58,7 @@ Polyline MotionPlanner::shortest_path(const Point &from, const Point &to)
{
// If we have an empty configuration space, return a straight move.
if (m_islands.empty())
- return Line(from, to);
+ return Polyline(from, to);
// Are both points in the same island?
int island_idx_from = -1;
@@ -74,7 +74,7 @@ Polyline MotionPlanner::shortest_path(const Point &from, const Point &to)
// Since both points are in the same island, is a direct move possible?
// If so, we avoid generating the visibility environment.
if (island.m_island.contains(Line(from, to)))
- return Line(from, to);
+ return Polyline(from, to);
// Both points are inside a single island, but the straight line crosses the island boundary.
island_idx = idx;
break;
@@ -90,7 +90,7 @@ Polyline MotionPlanner::shortest_path(const Point &from, const Point &to)
if (env.m_env.expolygons.empty()) {
// if this environment is empty (probably because it's too small), perform straight move
// and avoid running the algorithms on empty dataset
- return Line(from, to);
+ return Polyline(from, to);
}
// Now check whether points are inside the environment.
@@ -224,7 +224,7 @@ const MotionPlannerGraph& MotionPlanner::init_graph(int island_idx)
else
v1_idx = i_v1->second;
// Euclidean distance is used as weight for the graph edge
- graph->add_edge(v0_idx, v1_idx, p0.distance_to(p1));
+ graph->add_edge(v0_idx, v1_idx, (p1 - p0).cast<double>().norm());
}
}
}
@@ -238,7 +238,7 @@ static inline size_t nearest_waypoint_index(const Point &start_point, const Poin
size_t idx = size_t(-1);
double dmin = std::numeric_limits<double>::infinity();
for (const Point &p : middle_points) {
- double d = start_point.distance_to(p) + p.distance_to(end_point);
+ double d = (p - start_point).cast<double>().norm() + (end_point - p).cast<double>().norm();
if (d < dmin) {
idx = &p - middle_points.data();
dmin = d;
diff --git a/xs/src/libslic3r/MultiPoint.cpp b/xs/src/libslic3r/MultiPoint.cpp
index 2e65492cd..f44897a04 100644
--- a/xs/src/libslic3r/MultiPoint.cpp
+++ b/xs/src/libslic3r/MultiPoint.cpp
@@ -8,59 +8,52 @@ MultiPoint::operator Points() const
return this->points;
}
-void
-MultiPoint::scale(double factor)
+void MultiPoint::scale(double factor)
{
- for (Points::iterator it = points.begin(); it != points.end(); ++it) {
- (*it).scale(factor);
- }
+ for (Point &pt : points)
+ pt *= factor;
}
-void
-MultiPoint::translate(double x, double y)
+void MultiPoint::translate(double x, double y)
{
- for (Points::iterator it = points.begin(); it != points.end(); ++it) {
- (*it).translate(x, y);
- }
+ Vector v(x, y);
+ for (Point &pt : points)
+ pt += v;
}
-void
-MultiPoint::translate(const Point &vector)
+void MultiPoint::translate(const Point &v)
{
- this->translate(vector.x, vector.y);
+ for (Point &pt : points)
+ pt += v;
}
void MultiPoint::rotate(double cos_angle, double sin_angle)
{
for (Point &pt : this->points) {
- double cur_x = double(pt.x);
- double cur_y = double(pt.y);
- pt.x = coord_t(round(cos_angle * cur_x - sin_angle * cur_y));
- pt.y = coord_t(round(cos_angle * cur_y + sin_angle * cur_x));
+ double cur_x = double(pt(0));
+ double cur_y = double(pt(1));
+ pt(0) = coord_t(round(cos_angle * cur_x - sin_angle * cur_y));
+ pt(1) = coord_t(round(cos_angle * cur_y + sin_angle * cur_x));
}
}
-void
-MultiPoint::rotate(double angle, const Point &center)
+void MultiPoint::rotate(double angle, const Point &center)
{
double s = sin(angle);
double c = cos(angle);
- for (Points::iterator it = points.begin(); it != points.end(); ++it) {
- double dx = double(it->x - center.x);
- double dy = double(it->y - center.y);
- it->x = (coord_t)round(double(center.x) + c * dx - s * dy);
- it->y = (coord_t)round(double(center.y) + c * dy + s * dx);
+ for (Point &pt : points) {
+ Vec2crd v(pt - center);
+ pt(0) = (coord_t)round(double(center(0)) + c * v[0] - s * v[1]);
+ pt(1) = (coord_t)round(double(center(1)) + c * v[1] + s * v[0]);
}
}
-void
-MultiPoint::reverse()
+void MultiPoint::reverse()
{
std::reverse(this->points.begin(), this->points.end());
}
-Point
-MultiPoint::first_point() const
+Point MultiPoint::first_point() const
{
return this->points.front();
}
@@ -79,16 +72,16 @@ MultiPoint::length() const
int
MultiPoint::find_point(const Point &point) const
{
- for (Points::const_iterator it = this->points.begin(); it != this->points.end(); ++it) {
- if (it->coincides_with(point)) return it - this->points.begin();
- }
+ for (const Point &pt : this->points)
+ if (pt == point)
+ return &pt - &this->points.front();
return -1; // not found
}
bool
MultiPoint::has_boundary_point(const Point &point) const
{
- double dist = point.distance_to(point.projection_onto(*this));
+ double dist = (point.projection_onto(*this) - point).cast<double>().norm();
return dist < SCALED_EPSILON;
}
@@ -102,7 +95,7 @@ bool
MultiPoint::has_duplicate_points() const
{
for (size_t i = 1; i < points.size(); ++i)
- if (points[i-1].coincides_with(points[i]))
+ if (points[i-1] == points[i])
return true;
return false;
}
@@ -112,7 +105,7 @@ MultiPoint::remove_duplicate_points()
{
size_t j = 0;
for (size_t i = 1; i < points.size(); ++i) {
- if (points[j].coincides_with(points[i])) {
+ if (points[j] == points[i]) {
// Just increase index i.
} else {
++ j;
@@ -146,10 +139,10 @@ bool MultiPoint::first_intersection(const Line& line, Point* intersection) const
if (l.intersection(line, &ip)) {
if (! found) {
found = true;
- dmin = ip.distance_to(line.a);
+ dmin = (line.a - ip).cast<double>().norm();
*intersection = ip;
} else {
- double d = ip.distance_to(line.a);
+ double d = (line.a - ip).cast<double>().norm();
if (d < dmin) {
dmin = d;
*intersection = ip;
@@ -160,19 +153,6 @@ bool MultiPoint::first_intersection(const Line& line, Point* intersection) const
return found;
}
-std::string
-MultiPoint::dump_perl() const
-{
- std::ostringstream ret;
- ret << "[";
- for (Points::const_iterator p = this->points.begin(); p != this->points.end(); ++p) {
- ret << p->dump_perl();
- if (p != this->points.end()-1) ret << ",";
- }
- ret << "]";
- return ret.str();
-}
-
//FIXME This is very inefficient in term of memory use.
// The recursive algorithm shall run in place, not allocating temporary data in each recursion.
Points
@@ -185,7 +165,7 @@ MultiPoint::_douglas_peucker(const Points &points, const double tolerance)
Line full(points.front(), points.back());
for (Points::const_iterator it = points.begin() + 1; it != points.end(); ++it) {
// we use shortest distance, not perpendicular distance
- double d = it->distance_to(full);
+ double d = full.distance_to(*it);
if (d > dmax) {
index = it - points.begin();
dmax = d;
@@ -216,25 +196,22 @@ MultiPoint::_douglas_peucker(const Points &points, const double tolerance)
void MultiPoint3::translate(double x, double y)
{
- for (Point3& p : points)
- {
- p.translate(x, y);
+ for (Vec3crd &p : points) {
+ p(0) += x;
+ p(1) += y;
}
}
void MultiPoint3::translate(const Point& vector)
{
- translate(vector.x, vector.y);
+ this->translate(vector(0), vector(1));
}
double MultiPoint3::length() const
{
- Lines3 lines = this->lines();
double len = 0.0;
- for (const Line3& line : lines)
- {
+ for (const Line3& line : this->lines())
len += line.length();
- }
return len;
}
@@ -246,15 +223,11 @@ BoundingBox3 MultiPoint3::bounding_box() const
bool MultiPoint3::remove_duplicate_points()
{
size_t j = 0;
- for (size_t i = 1; i < points.size(); ++i)
- {
- if (points[j].coincides_with(points[i]))
- {
+ for (size_t i = 1; i < points.size(); ++i) {
+ if (points[j] == points[i]) {
// Just increase index i.
- }
- else
- {
- ++j;
+ } else {
+ ++ j;
if (j < i)
points[j] = points[i];
}
@@ -281,19 +254,19 @@ BoundingBox get_extents_rotated(const Points &points, double angle)
double s = sin(angle);
double c = cos(angle);
Points::const_iterator it = points.begin();
- double cur_x = (double)it->x;
- double cur_y = (double)it->y;
- bbox.min.x = bbox.max.x = (coord_t)round(c * cur_x - s * cur_y);
- bbox.min.y = bbox.max.y = (coord_t)round(c * cur_y + s * cur_x);
+ double cur_x = (double)(*it)(0);
+ double cur_y = (double)(*it)(1);
+ bbox.min(0) = bbox.max(0) = (coord_t)round(c * cur_x - s * cur_y);
+ bbox.min(1) = bbox.max(1) = (coord_t)round(c * cur_y + s * cur_x);
for (++it; it != points.end(); ++it) {
- double cur_x = (double)it->x;
- double cur_y = (double)it->y;
+ double cur_x = (double)(*it)(0);
+ double cur_y = (double)(*it)(1);
coord_t x = (coord_t)round(c * cur_x - s * cur_y);
coord_t y = (coord_t)round(c * cur_y + s * cur_x);
- bbox.min.x = std::min(x, bbox.min.x);
- bbox.min.y = std::min(y, bbox.min.y);
- bbox.max.x = std::max(x, bbox.max.x);
- bbox.max.y = std::max(y, bbox.max.y);
+ bbox.min(0) = std::min(x, bbox.min(0));
+ bbox.min(1) = std::min(y, bbox.min(1));
+ bbox.max(0) = std::max(x, bbox.max(0));
+ bbox.max(1) = std::max(y, bbox.max(1));
}
bbox.defined = true;
}
diff --git a/xs/src/libslic3r/MultiPoint.hpp b/xs/src/libslic3r/MultiPoint.hpp
index 0970e9a67..1fef4083b 100644
--- a/xs/src/libslic3r/MultiPoint.hpp
+++ b/xs/src/libslic3r/MultiPoint.hpp
@@ -18,10 +18,11 @@ public:
Points points;
operator Points() const;
- MultiPoint() {};
+ MultiPoint() {}
MultiPoint(const MultiPoint &other) : points(other.points) {}
MultiPoint(MultiPoint &&other) : points(std::move(other.points)) {}
- explicit MultiPoint(const Points &_points): points(_points) {}
+ MultiPoint(std::initializer_list<Point> list) : points(list) {}
+ explicit MultiPoint(const Points &_points) : points(_points) {}
MultiPoint& operator=(const MultiPoint &other) { points = other.points; return *this; }
MultiPoint& operator=(MultiPoint &&other) { points = std::move(other.points); return *this; }
void scale(double factor);
@@ -43,9 +44,9 @@ public:
int idx = -1;
if (! this->points.empty()) {
idx = 0;
- double dist_min = this->points.front().distance_to(point);
+ double dist_min = (point - this->points.front()).cast<double>().norm();
for (int i = 1; i < int(this->points.size()); ++ i) {
- double d = this->points[i].distance_to(point);
+ double d = (this->points[i] - point).cast<double>().norm();
if (d < dist_min) {
dist_min = d;
idx = i;
@@ -75,7 +76,6 @@ public:
bool intersection(const Line& line, Point* intersection) const;
bool first_intersection(const Line& line, Point* intersection) const;
- std::string dump_perl() const;
static Points _douglas_peucker(const Points &points, const double tolerance);
};
@@ -85,7 +85,7 @@ class MultiPoint3
public:
Points3 points;
- void append(const Point3& point) { this->points.push_back(point); }
+ void append(const Vec3crd& point) { this->points.push_back(point); }
void translate(double x, double y);
void translate(const Point& vector);
diff --git a/xs/src/libslic3r/PerimeterGenerator.cpp b/xs/src/libslic3r/PerimeterGenerator.cpp
index 176f28926..de8aeeb2a 100644
--- a/xs/src/libslic3r/PerimeterGenerator.cpp
+++ b/xs/src/libslic3r/PerimeterGenerator.cpp
@@ -44,7 +44,6 @@ void PerimeterGenerator::process()
// lower layer, so we take lower slices and offset them by half the nozzle diameter used
// in the current layer
double nozzle_diameter = this->print_config->nozzle_diameter.get_at(this->config->perimeter_extruder-1);
-
this->_lower_slices_p = offset(*this->lower_slices, float(scale_(+nozzle_diameter/2)));
}
@@ -52,149 +51,115 @@ void PerimeterGenerator::process()
// extra perimeters for each one
for (const Surface &surface : this->slices->surfaces) {
// detect how many perimeters must be generated for this island
- const int loop_number = this->config->perimeters + surface.extra_perimeters -1; // 0-indexed loops
-
- Polygons gaps;
-
- Polygons last = surface.expolygon.simplify_p(SCALED_RESOLUTION);
- if (loop_number >= 0) { // no loops = -1
-
+ int loop_number = this->config->perimeters + surface.extra_perimeters - 1; // 0-indexed loops
+ ExPolygons last = union_ex(surface.expolygon.simplify_p(SCALED_RESOLUTION));
+ ExPolygons gaps;
+ if (loop_number >= 0) {
+ // In case no perimeters are to be generated, loop_number will equal to -1.
std::vector<PerimeterGeneratorLoops> contours(loop_number+1); // depth => loops
std::vector<PerimeterGeneratorLoops> holes(loop_number+1); // depth => loops
ThickPolylines thin_walls;
-
// we loop one time more than needed in order to find gaps after the last perimeter was applied
- for (int i = 0; i <= loop_number+1; ++i) { // outer loop is 0
- Polygons offsets;
+ for (int i = 0;; ++ i) { // outer loop is 0
+ // Calculate next onion shell of perimeters.
+ ExPolygons offsets;
if (i == 0) {
// the minimum thickness of a single loop is:
// ext_width/2 + ext_spacing/2 + spacing/2 + width/2
- if (this->config->thin_walls) {
- offsets = offset2(
+ offsets = this->config->thin_walls ?
+ offset2_ex(
last,
-(ext_perimeter_width / 2 + ext_min_spacing / 2 - 1),
- +(ext_min_spacing/2 - 1)
- );
- } else {
- offsets = offset(last, - ext_perimeter_width / 2);
- }
-
+ +(ext_min_spacing / 2 - 1)) :
+ offset_ex(last, - ext_perimeter_width / 2);
// look for thin walls
if (this->config->thin_walls) {
- Polygons diffpp = diff(
- last,
- offset(offsets, ext_perimeter_width / 2),
- true // medial axis requires non-overlapping geometry
- );
-
// the following offset2 ensures almost nothing in @thin_walls is narrower than $min_width
// (actually, something larger than that still may exist due to mitering or other causes)
coord_t min_width = scale_(this->ext_perimeter_flow.nozzle_diameter / 3);
- ExPolygons expp = offset2_ex(diffpp, -min_width/2, +min_width/2);
-
+ ExPolygons expp = offset2_ex(
+ // medial axis requires non-overlapping geometry
+ diff_ex(to_polygons(last),
+ offset(offsets, ext_perimeter_width / 2),
+ true),
+ - min_width / 2, min_width / 2);
// the maximum thickness of our thin wall area is equal to the minimum thickness of a single loop
- for (ExPolygons::const_iterator ex = expp.begin(); ex != expp.end(); ++ex)
- ex->medial_axis(ext_perimeter_width + ext_perimeter_spacing2, min_width, &thin_walls);
-
- #ifdef DEBUG
- printf(" " PRINTF_ZU " thin walls detected\n", thin_walls.size());
- #endif
-
- /*
- if (false) {
- require "Slic3r/SVG.pm";
- Slic3r::SVG::output(
- "medial_axis.svg",
- no_arrows => 1,
- #expolygons => \@expp,
- polylines => \@thin_walls,
- );
- }
- */
+ for (ExPolygon &ex : expp)
+ ex.medial_axis(ext_perimeter_width + ext_perimeter_spacing2, min_width, &thin_walls);
}
} else {
//FIXME Is this offset correct if the line width of the inner perimeters differs
// from the line width of the infill?
coord_t distance = (i == 1) ? ext_perimeter_spacing2 : perimeter_spacing;
-
- if (this->config->thin_walls) {
+ offsets = this->config->thin_walls ?
// This path will ensure, that the perimeters do not overfill, as in
// prusa3d/Slic3r GH #32, but with the cost of rounding the perimeters
// excessively, creating gaps, which then need to be filled in by the not very
// reliable gap fill algorithm.
// Also the offset2(perimeter, -x, x) may sometimes lead to a perimeter, which is larger than
// the original.
- offsets = offset2(
- last,
- -(distance + min_spacing/2 - 1),
- +(min_spacing/2 - 1)
- );
- } else {
+ offset2_ex(last,
+ - (distance + min_spacing / 2 - 1),
+ min_spacing / 2 - 1) :
// If "detect thin walls" is not enabled, this paths will be entered, which
// leads to overflows, as in prusa3d/Slic3r GH #32
- offsets = offset(
- last,
- -distance
- );
- }
-
+ offset_ex(last, - distance);
// look for gaps
- if (this->config->gap_fill_speed.value > 0 && this->config->fill_density.value > 0) {
+ if (this->config->gap_fill_speed.value > 0 && this->config->fill_density.value > 0)
// not using safety offset here would "detect" very narrow gaps
// (but still long enough to escape the area threshold) that gap fill
// won't be able to fill but we'd still remove from infill area
- Polygons diff_pp = diff(
- offset(last, -0.5*distance),
- offset(offsets, +0.5*distance + 10) // safety offset
- );
- gaps.insert(gaps.end(), diff_pp.begin(), diff_pp.end());
- }
+ append(gaps, diff_ex(
+ offset(last, -0.5 * distance),
+ offset(offsets, 0.5 * distance + 10))); // safety offset
}
-
- if (offsets.empty()) break;
- if (i > loop_number) break; // we were only looking for gaps this time
-
- last = offsets;
- for (Polygons::const_iterator polygon = offsets.begin(); polygon != offsets.end(); ++polygon) {
- PerimeterGeneratorLoop loop(*polygon, i);
- loop.is_contour = polygon->is_counter_clockwise();
- if (loop.is_contour) {
- contours[i].push_back(loop);
- } else {
- holes[i].push_back(loop);
+ if (offsets.empty()) {
+ // Store the number of loops actually generated.
+ loop_number = i - 1;
+ // No region left to be filled in.
+ last.clear();
+ break;
+ } else if (i > loop_number) {
+ // If i > loop_number, we were looking just for gaps.
+ break;
+ }
+ for (const ExPolygon &expolygon : offsets) {
+ contours[i].emplace_back(PerimeterGeneratorLoop(expolygon.contour, i, true));
+ if (! expolygon.holes.empty()) {
+ holes[i].reserve(holes[i].size() + expolygon.holes.size());
+ for (const Polygon &hole : expolygon.holes)
+ holes[i].emplace_back(PerimeterGeneratorLoop(hole, i, false));
}
}
+ last = std::move(offsets);
}
-
+
// nest loops: holes first
- for (int d = 0; d <= loop_number; ++d) {
+ for (int d = 0; d <= loop_number; ++ d) {
PerimeterGeneratorLoops &holes_d = holes[d];
-
// loop through all holes having depth == d
- for (int i = 0; i < (int)holes_d.size(); ++i) {
+ for (int i = 0; i < (int)holes_d.size(); ++ i) {
const PerimeterGeneratorLoop &loop = holes_d[i];
-
// find the hole loop that contains this one, if any
- for (int t = d+1; t <= loop_number; ++t) {
- for (int j = 0; j < (int)holes[t].size(); ++j) {
+ for (int t = d + 1; t <= loop_number; ++ t) {
+ for (int j = 0; j < (int)holes[t].size(); ++ j) {
PerimeterGeneratorLoop &candidate_parent = holes[t][j];
if (candidate_parent.polygon.contains(loop.polygon.first_point())) {
candidate_parent.children.push_back(loop);
holes_d.erase(holes_d.begin() + i);
- --i;
+ -- i;
goto NEXT_LOOP;
}
}
}
-
// if no hole contains this hole, find the contour loop that contains it
- for (int t = loop_number; t >= 0; --t) {
- for (int j = 0; j < (int)contours[t].size(); ++j) {
+ for (int t = loop_number; t >= 0; -- t) {
+ for (int j = 0; j < (int)contours[t].size(); ++ j) {
PerimeterGeneratorLoop &candidate_parent = contours[t][j];
if (candidate_parent.polygon.contains(loop.polygon.first_point())) {
candidate_parent.children.push_back(loop);
holes_d.erase(holes_d.begin() + i);
- --i;
+ -- i;
goto NEXT_LOOP;
}
}
@@ -202,75 +167,57 @@ void PerimeterGenerator::process()
NEXT_LOOP: ;
}
}
-
// nest contour loops
- for (int d = loop_number; d >= 1; --d) {
+ for (int d = loop_number; d >= 1; -- d) {
PerimeterGeneratorLoops &contours_d = contours[d];
-
// loop through all contours having depth == d
- for (int i = 0; i < (int)contours_d.size(); ++i) {
+ for (int i = 0; i < (int)contours_d.size(); ++ i) {
const PerimeterGeneratorLoop &loop = contours_d[i];
-
// find the contour loop that contains it
- for (int t = d-1; t >= 0; --t) {
- for (int j = 0; j < contours[t].size(); ++j) {
+ for (int t = d - 1; t >= 0; -- t) {
+ for (int j = 0; j < contours[t].size(); ++ j) {
PerimeterGeneratorLoop &candidate_parent = contours[t][j];
if (candidate_parent.polygon.contains(loop.polygon.first_point())) {
candidate_parent.children.push_back(loop);
contours_d.erase(contours_d.begin() + i);
- --i;
+ -- i;
goto NEXT_CONTOUR;
}
}
}
-
NEXT_CONTOUR: ;
}
}
-
// at this point, all loops should be in contours[0]
-
ExtrusionEntityCollection entities = this->_traverse_loops(contours.front(), thin_walls);
-
// if brim will be printed, reverse the order of perimeters so that
// we continue inwards after having finished the brim
// TODO: add test for perimeter order
- if (this->config->external_perimeters_first
- || (this->layer_id == 0 && this->print_config->brim_width.value > 0))
- entities.reverse();
-
+ if (this->config->external_perimeters_first ||
+ (this->layer_id == 0 && this->print_config->brim_width.value > 0))
+ entities.reverse();
// append perimeters for this slice as a collection
- if (!entities.empty())
+ if (! entities.empty())
this->loops->append(entities);
} // for each loop of an island
// fill gaps
- if (!gaps.empty()) {
- /*
- SVG svg("gaps.svg");
- svg.draw(union_ex(gaps));
- svg.Close();
- */
-
+ if (! gaps.empty()) {
// collapse
double min = 0.2 * perimeter_width * (1 - INSET_OVERLAP_TOLERANCE);
double max = 2. * perimeter_spacing;
ExPolygons gaps_ex = diff_ex(
- offset2(gaps, -min/2, +min/2),
- offset2(gaps, -max/2, +max/2),
- true
- );
-
+ //FIXME offset2 would be enough and cheaper.
+ offset2_ex(gaps, -min/2, +min/2),
+ offset2_ex(gaps, -max/2, +max/2),
+ true);
ThickPolylines polylines;
- for (ExPolygons::const_iterator ex = gaps_ex.begin(); ex != gaps_ex.end(); ++ex)
- ex->medial_axis(max, min, &polylines);
-
- if (!polylines.empty()) {
+ for (const ExPolygon &ex : gaps_ex)
+ ex.medial_axis(max, min, &polylines);
+ if (! polylines.empty()) {
ExtrusionEntityCollection gap_fill = this->_variable_width(polylines,
erGapFill, this->solid_infill_flow);
-
this->gap_fill->append(gap_fill.entities);
-
/* Make sure we don't infill narrow parts that are already gap-filled
(we only consider this surface's gaps to reduce the diff() complexity).
Growing actual extrusions ensures that gaps not filled by medial axis
@@ -279,7 +226,7 @@ void PerimeterGenerator::process()
and use zigzag). */
//FIXME Vojtech: This grows by a rounded extrusion width, not by line spacing,
// therefore it may cover the area, but no the volume.
- last = diff(last, gap_fill.polygons_covered_by_width(10.f));
+ last = diff_ex(to_polygons(last), gap_fill.polygons_covered_by_width(10.f));
}
}
@@ -287,36 +234,34 @@ void PerimeterGenerator::process()
// we offset by half the perimeter spacing (to get to the actual infill boundary)
// and then we offset back and forth by half the infill spacing to only consider the
// non-collapsing regions
- coord_t inset = 0;
- if (loop_number == 0) {
- // one loop
- inset += ext_perimeter_spacing / 2;
- } else if (loop_number > 0) {
- // two or more loops
- inset += perimeter_spacing / 2;
- }
+ coord_t inset =
+ (loop_number < 0) ? 0 :
+ (loop_number == 0) ?
+ // one loop
+ ext_perimeter_spacing / 2 :
+ // two or more loops?
+ perimeter_spacing / 2;
// only apply infill overlap if we actually have one perimeter
if (inset > 0)
- inset -= this->config->get_abs_value("infill_overlap", inset + solid_infill_spacing / 2);
+ inset -= scale_(this->config->get_abs_value("infill_overlap", unscale<double>(inset + solid_infill_spacing / 2)));
// simplify infill contours according to resolution
Polygons pp;
- for (ExPolygon &ex : union_ex(last))
+ for (ExPolygon &ex : last)
ex.simplify_p(SCALED_RESOLUTION, &pp);
// collapse too narrow infill areas
- coord_t min_perimeter_infill_spacing = solid_infill_spacing * (1 - INSET_OVERLAP_TOLERANCE);
+ coord_t min_perimeter_infill_spacing = solid_infill_spacing * (1. - INSET_OVERLAP_TOLERANCE);
// append infill areas to fill_surfaces
this->fill_surfaces->append(
offset2_ex(
- pp,
- -inset -min_perimeter_infill_spacing/2,
- +min_perimeter_infill_spacing/2),
+ union_ex(pp),
+ - inset - min_perimeter_infill_spacing / 2,
+ min_perimeter_infill_spacing / 2),
stInternal);
} // for each island
}
-ExtrusionEntityCollection
-PerimeterGenerator::_traverse_loops(const PerimeterGeneratorLoops &loops,
- ThickPolylines &thin_walls) const
+ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
+ const PerimeterGeneratorLoops &loops, ThickPolylines &thin_walls) const
{
// loops is an arrayref of ::Loop objects
// turn each one into an ExtrusionLoop object
@@ -421,120 +366,115 @@ PerimeterGenerator::_traverse_loops(const PerimeterGeneratorLoops &loops,
return entities;
}
-ExtrusionEntityCollection
-PerimeterGenerator::_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const
+static inline ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, Flow &flow, const float tolerance)
{
- // this value determines granularity of adaptive width, as G-code does not allow
- // variable extrusion within a single move; this value shall only affect the amount
- // of segments, and any pruning shall be performed before we apply this tolerance
- const double tolerance = scale_(0.05);
+ ExtrusionPaths paths;
+ ExtrusionPath path(role);
+ ThickLines lines = thick_polyline.thicklines();
- ExtrusionEntityCollection coll;
- for (ThickPolylines::const_iterator p = polylines.begin(); p != polylines.end(); ++p) {
- ExtrusionPaths paths;
- ExtrusionPath path(role);
- ThickLines lines = p->thicklines();
+ for (int i = 0; i < (int)lines.size(); ++i) {
+ const ThickLine& line = lines[i];
- for (int i = 0; i < (int)lines.size(); ++i) {
- const ThickLine& line = lines[i];
-
- const coordf_t line_len = line.length();
- if (line_len < SCALED_EPSILON) continue;
-
- double thickness_delta = fabs(line.a_width - line.b_width);
- if (thickness_delta > tolerance) {
- const unsigned short segments = ceil(thickness_delta / tolerance);
- const coordf_t seg_len = line_len / segments;
- Points pp;
- std::vector<coordf_t> width;
- {
- pp.push_back(line.a);
- width.push_back(line.a_width);
- for (size_t j = 1; j < segments; ++j) {
- pp.push_back(line.point_at(j*seg_len));
-
- coordf_t w = line.a_width + (j*seg_len) * (line.b_width-line.a_width) / line_len;
- width.push_back(w);
- width.push_back(w);
- }
- pp.push_back(line.b);
- width.push_back(line.b_width);
+ const coordf_t line_len = line.length();
+ if (line_len < SCALED_EPSILON) continue;
+
+ double thickness_delta = fabs(line.a_width - line.b_width);
+ if (thickness_delta > tolerance) {
+ const unsigned short segments = ceil(thickness_delta / tolerance);
+ const coordf_t seg_len = line_len / segments;
+ Points pp;
+ std::vector<coordf_t> width;
+ {
+ pp.push_back(line.a);
+ width.push_back(line.a_width);
+ for (size_t j = 1; j < segments; ++j) {
+ pp.push_back((line.a.cast<double>() + (line.b - line.a).cast<double>().normalized() * (j * seg_len)).cast<coord_t>());
- assert(pp.size() == segments + 1);
- assert(width.size() == segments*2);
- }
-
- // delete this line and insert new ones
- lines.erase(lines.begin() + i);
- for (size_t j = 0; j < segments; ++j) {
- ThickLine new_line(pp[j], pp[j+1]);
- new_line.a_width = width[2*j];
- new_line.b_width = width[2*j+1];
- lines.insert(lines.begin() + i + j, new_line);
+ coordf_t w = line.a_width + (j*seg_len) * (line.b_width-line.a_width) / line_len;
+ width.push_back(w);
+ width.push_back(w);
}
+ pp.push_back(line.b);
+ width.push_back(line.b_width);
- --i;
- continue;
+ assert(pp.size() == segments + 1);
+ assert(width.size() == segments*2);
}
- const double w = fmax(line.a_width, line.b_width);
+ // delete this line and insert new ones
+ lines.erase(lines.begin() + i);
+ for (size_t j = 0; j < segments; ++j) {
+ ThickLine new_line(pp[j], pp[j+1]);
+ new_line.a_width = width[2*j];
+ new_line.b_width = width[2*j+1];
+ lines.insert(lines.begin() + i + j, new_line);
+ }
- if (path.polyline.points.empty()) {
- path.polyline.append(line.a);
+ -- i;
+ continue;
+ }
+
+ const double w = fmax(line.a_width, line.b_width);
+ if (path.polyline.points.empty()) {
+ path.polyline.append(line.a);
+ path.polyline.append(line.b);
+ // Convert from spacing to extrusion width based on the extrusion model
+ // of a square extrusion ended with semi circles.
+ flow.width = unscale<float>(w) + flow.height * (1. - 0.25 * PI);
+ #ifdef SLIC3R_DEBUG
+ printf(" filling %f gap\n", flow.width);
+ #endif
+ path.mm3_per_mm = flow.mm3_per_mm();
+ path.width = flow.width;
+ path.height = flow.height;
+ } else {
+ thickness_delta = fabs(scale_(flow.width) - w);
+ if (thickness_delta <= tolerance) {
+ // the width difference between this line and the current flow width is
+ // within the accepted tolerance
path.polyline.append(line.b);
- // Convert from spacing to extrusion width based on the extrusion model
- // of a square extrusion ended with semi circles.
- flow.width = unscale(w) + flow.height * (1. - 0.25 * PI);
- #ifdef SLIC3R_DEBUG
- printf(" filling %f gap\n", flow.width);
- #endif
- path.mm3_per_mm = flow.mm3_per_mm();
- path.width = flow.width;
- path.height = flow.height;
} else {
- thickness_delta = fabs(scale_(flow.width) - w);
- if (thickness_delta <= tolerance) {
- // the width difference between this line and the current flow width is
- // within the accepted tolerance
-
- path.polyline.append(line.b);
- } else {
- // we need to initialize a new line
- paths.push_back(path);
- path = ExtrusionPath(role);
- --i;
- }
+ // we need to initialize a new line
+ paths.emplace_back(std::move(path));
+ path = ExtrusionPath(role);
+ -- i;
}
}
- if (path.polyline.is_valid())
- paths.push_back(path);
-
- // append paths to collection
- if (!paths.empty()) {
- if (paths.front().first_point().coincides_with(paths.back().last_point()))
- coll.append(ExtrusionLoop(paths));
+ }
+ if (path.polyline.is_valid())
+ paths.emplace_back(std::move(path));
+ return paths;
+}
+
+ExtrusionEntityCollection PerimeterGenerator::_variable_width(const ThickPolylines &polylines, ExtrusionRole role, Flow flow) const
+{
+ // This value determines granularity of adaptive width, as G-code does not allow
+ // variable extrusion within a single move; this value shall only affect the amount
+ // of segments, and any pruning shall be performed before we apply this tolerance.
+ ExtrusionEntityCollection coll;
+ const double tolerance = scale_(0.05);
+ for (const ThickPolyline &p : polylines) {
+ ExtrusionPaths paths = thick_polyline_to_extrusion_paths(p, role, flow, tolerance);
+ // Append paths to collection.
+ if (! paths.empty()) {
+ if (paths.front().first_point() == paths.back().last_point())
+ coll.append(ExtrusionLoop(std::move(paths)));
else
- coll.append(paths);
+ coll.append(std::move(paths));
}
}
-
return coll;
}
-bool
-PerimeterGeneratorLoop::is_internal_contour() const
+bool PerimeterGeneratorLoop::is_internal_contour() const
{
- if (this->is_contour) {
- // an internal contour is a contour containing no other contours
- for (std::vector<PerimeterGeneratorLoop>::const_iterator loop = this->children.begin();
- loop != this->children.end(); ++loop) {
- if (loop->is_contour) {
- return false;
- }
- }
- return true;
- }
- return false;
+ // An internal contour is a contour containing no other contours
+ if (! this->is_contour)
+ return false;
+ for (const PerimeterGeneratorLoop &loop : this->children)
+ if (loop.is_contour)
+ return false;
+ return true;
}
}
diff --git a/xs/src/libslic3r/PerimeterGenerator.hpp b/xs/src/libslic3r/PerimeterGenerator.hpp
index dd1f9b0ec..44af8c8be 100644
--- a/xs/src/libslic3r/PerimeterGenerator.hpp
+++ b/xs/src/libslic3r/PerimeterGenerator.hpp
@@ -24,9 +24,8 @@ public:
// Children contour, may be both CCW and CW oriented (outer contours or holes).
std::vector<PerimeterGeneratorLoop> children;
- PerimeterGeneratorLoop(Polygon polygon, unsigned short depth)
- : polygon(polygon), is_contour(false), depth(depth)
- {};
+ PerimeterGeneratorLoop(Polygon polygon, unsigned short depth, bool is_contour) :
+ polygon(polygon), is_contour(is_contour), depth(depth) {}
// External perimeter. It may be CCW or CW oriented (outer contour or hole contour).
bool is_external() const { return this->depth == 0; }
// An island, which may have holes, but it does not have another internal island.
diff --git a/xs/src/libslic3r/PlaceholderParser.cpp b/xs/src/libslic3r/PlaceholderParser.cpp
index 848e7fd2a..cc6f1c75e 100644
--- a/xs/src/libslic3r/PlaceholderParser.cpp
+++ b/xs/src/libslic3r/PlaceholderParser.cpp
@@ -414,6 +414,7 @@ namespace client
lhs.type = TYPE_BOOL;
lhs.data.b = invert ? ! value : value;
}
+ // Compare operators, store the result into lhs.
static void equal (expr &lhs, expr &rhs) { compare_op(lhs, rhs, '=', false); }
static void not_equal(expr &lhs, expr &rhs) { compare_op(lhs, rhs, '=', true ); }
static void lower (expr &lhs, expr &rhs) { compare_op(lhs, rhs, '<', false); }
@@ -421,6 +422,40 @@ namespace client
static void leq (expr &lhs, expr &rhs) { compare_op(lhs, rhs, '>', true ); }
static void geq (expr &lhs, expr &rhs) { compare_op(lhs, rhs, '<', true ); }
+ enum Function2ParamsType {
+ FUNCTION_MIN,
+ FUNCTION_MAX,
+ };
+ // Store the result into param1.
+ static void function_2params(expr &param1, expr &param2, Function2ParamsType fun)
+ {
+ const char *err_msg = "Not a numeric type.";
+ param1.throw_if_not_numeric(err_msg);
+ param2.throw_if_not_numeric(err_msg);
+ if (param1.type == TYPE_DOUBLE || param2.type == TYPE_DOUBLE) {
+ double d = 0.;
+ switch (fun) {
+ case FUNCTION_MIN: d = std::min(param1.as_d(), param2.as_d()); break;
+ case FUNCTION_MAX: d = std::max(param1.as_d(), param2.as_d()); break;
+ default: param1.throw_exception("Internal error: invalid function");
+ }
+ param1.data.d = d;
+ param1.type = TYPE_DOUBLE;
+ } else {
+ int i = 0.;
+ switch (fun) {
+ case FUNCTION_MIN: i = std::min(param1.as_i(), param2.as_i()); break;
+ case FUNCTION_MAX: i = std::max(param1.as_i(), param2.as_i()); break;
+ default: param1.throw_exception("Internal error: invalid function");
+ }
+ param1.data.i = i;
+ param1.type = TYPE_INT;
+ }
+ }
+ // Store the result into param1.
+ static void min(expr &param1, expr &param2) { function_2params(param1, param2, FUNCTION_MIN); }
+ static void max(expr &param1, expr &param2) { function_2params(param1, param2, FUNCTION_MAX); }
+
static void regex_op(expr &lhs, boost::iterator_range<Iterator> &rhs, char op)
{
const std::string *subject = nullptr;
@@ -658,7 +693,7 @@ namespace client
case coInts: output.set_i(static_cast<const ConfigOptionInts *>(opt.opt)->values[idx]); break;
case coStrings: output.set_s(static_cast<const ConfigOptionStrings *>(opt.opt)->values[idx]); break;
case coPercents: output.set_d(static_cast<const ConfigOptionPercents*>(opt.opt)->values[idx]); break;
- case coPoints: output.set_s(static_cast<const ConfigOptionPoints *>(opt.opt)->values[idx].dump_perl()); break;
+ case coPoints: output.set_s(to_string(static_cast<const ConfigOptionPoints *>(opt.opt)->values[idx])); break;
case coBools: output.set_b(static_cast<const ConfigOptionBools *>(opt.opt)->values[idx] != 0); break;
default:
ctx->throw_exception("Unknown vector variable type", opt.it_range);
@@ -1019,6 +1054,10 @@ namespace client
| (lit('-') > unary_expression(_r1) ) [ px::bind(&FactorActions::minus_, _1, _val) ]
| (lit('+') > unary_expression(_r1) > iter_pos) [ px::bind(&FactorActions::expr_, _1, _2, _val) ]
| ((kw["not"] | '!') > unary_expression(_r1) > iter_pos) [ px::bind(&FactorActions::not_, _1, _val) ]
+ | (kw["min"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
+ [ px::bind(&expr<Iterator>::min, _val, _2) ]
+ | (kw["max"] > '(' > conditional_expression(_r1) [_val = _1] > ',' > conditional_expression(_r1) > ')')
+ [ px::bind(&expr<Iterator>::max, _val, _2) ]
| (strict_double > iter_pos) [ px::bind(&FactorActions::double_, _1, _2, _val) ]
| (int_ > iter_pos) [ px::bind(&FactorActions::int_, _1, _2, _val) ]
| (kw[bool_] > iter_pos) [ px::bind(&FactorActions::bool_, _1, _2, _val) ]
@@ -1051,6 +1090,8 @@ namespace client
("elsif")
("endif")
("false")
+ ("min")
+ ("max")
("not")
("or")
("true");
diff --git a/xs/src/libslic3r/Point.cpp b/xs/src/libslic3r/Point.cpp
index 7c1dc91f5..c2417d0dc 100644
--- a/xs/src/libslic3r/Point.cpp
+++ b/xs/src/libslic3r/Point.cpp
@@ -1,85 +1,72 @@
#include "Point.hpp"
#include "Line.hpp"
#include "MultiPoint.hpp"
+#include "Int128.hpp"
#include <algorithm>
-#include <cmath>
namespace Slic3r {
-Point::Point(double x, double y)
+std::vector<Vec3f> transform(const std::vector<Vec3f>& points, const Transform3f& t)
{
- this->x = lrint(x);
- this->y = lrint(y);
-}
+ unsigned int vertices_count = (unsigned int)points.size();
+ if (vertices_count == 0)
+ return std::vector<Vec3f>();
-std::string
-Point::wkt() const
-{
- std::ostringstream ss;
- ss << "POINT(" << this->x << " " << this->y << ")";
- return ss.str();
-}
+ unsigned int data_size = 3 * vertices_count * sizeof(float);
-std::string
-Point::dump_perl() const
-{
- std::ostringstream ss;
- ss << "[" << this->x << "," << this->y << "]";
- return ss.str();
-}
+ Eigen::MatrixXf src(3, vertices_count);
+ ::memcpy((void*)src.data(), (const void*)points.data(), data_size);
-void
-Point::scale(double factor)
-{
- this->x *= factor;
- this->y *= factor;
-}
+ Eigen::MatrixXf dst(3, vertices_count);
+ dst = t * src.colwise().homogeneous();
-void
-Point::translate(double x, double y)
-{
- this->x += x;
- this->y += y;
+ std::vector<Vec3f> ret_points(vertices_count, Vec3f::Zero());
+ ::memcpy((void*)ret_points.data(), (const void*)dst.data(), data_size);
+ return ret_points;
}
-void
-Point::translate(const Vector &vector)
+Pointf3s transform(const Pointf3s& points, const Transform3d& t)
{
- this->translate(vector.x, vector.y);
-}
+ unsigned int vertices_count = (unsigned int)points.size();
+ if (vertices_count == 0)
+ return Pointf3s();
-void
-Point::rotate(double angle)
-{
- double cur_x = (double)this->x;
- double cur_y = (double)this->y;
- double s = sin(angle);
- double c = cos(angle);
- this->x = (coord_t)round(c * cur_x - s * cur_y);
- this->y = (coord_t)round(c * cur_y + s * cur_x);
+ unsigned int data_size = 3 * vertices_count * sizeof(double);
+
+ Eigen::MatrixXd src(3, vertices_count);
+ ::memcpy((void*)src.data(), (const void*)points.data(), data_size);
+
+ Eigen::MatrixXd dst(3, vertices_count);
+ dst = t * src.colwise().homogeneous();
+
+ Pointf3s ret_points(vertices_count, Vec3d::Zero());
+ ::memcpy((void*)ret_points.data(), (const void*)dst.data(), data_size);
+ return ret_points;
}
-void
-Point::rotate(double angle, const Point &center)
+void Point::rotate(double angle)
{
- double cur_x = (double)this->x;
- double cur_y = (double)this->y;
- double s = sin(angle);
- double c = cos(angle);
- double dx = cur_x - (double)center.x;
- double dy = cur_y - (double)center.y;
- this->x = (coord_t)round( (double)center.x + c * dx - s * dy );
- this->y = (coord_t)round( (double)center.y + c * dy + s * dx );
+ double cur_x = (double)(*this)(0);
+ double cur_y = (double)(*this)(1);
+ double s = ::sin(angle);
+ double c = ::cos(angle);
+ (*this)(0) = (coord_t)round(c * cur_x - s * cur_y);
+ (*this)(1) = (coord_t)round(c * cur_y + s * cur_x);
}
-bool
-Point::coincides_with_epsilon(const Point &point) const
+void Point::rotate(double angle, const Point &center)
{
- return std::abs(this->x - point.x) < SCALED_EPSILON && std::abs(this->y - point.y) < SCALED_EPSILON;
+ double cur_x = (double)(*this)(0);
+ double cur_y = (double)(*this)(1);
+ double s = ::sin(angle);
+ double c = ::cos(angle);
+ double dx = cur_x - (double)center(0);
+ double dy = cur_y - (double)center(1);
+ (*this)(0) = (coord_t)round( (double)center(0) + c * dx - s * dy );
+ (*this)(1) = (coord_t)round( (double)center(1) + c * dy + s * dx );
}
-int
-Point::nearest_point_index(const Points &points) const
+int Point::nearest_point_index(const Points &points) const
{
PointConstPtrs p;
p.reserve(points.size());
@@ -96,12 +83,12 @@ int Point::nearest_point_index(const PointConstPtrs &points) const
for (PointConstPtrs::const_iterator it = points.begin(); it != points.end(); ++it) {
/* If the X distance of the candidate is > than the total distance of the
best previous candidate, we know we don't want it */
- double d = sqr<double>(this->x - (*it)->x);
+ double d = sqr<double>((*this)(0) - (*it)->x());
if (distance != -1 && d > distance) continue;
/* If the Y distance of the candidate is > than the total distance of the
best previous candidate, we know we don't want it */
- d += sqr<double>(this->y - (*it)->y);
+ d += sqr<double>((*this)(1) - (*it)->y());
if (distance != -1 && d > distance) continue;
idx = it - points.begin();
@@ -113,8 +100,7 @@ int Point::nearest_point_index(const PointConstPtrs &points) const
return idx;
}
-int
-Point::nearest_point_index(const PointPtrs &points) const
+int Point::nearest_point_index(const PointPtrs &points) const
{
PointConstPtrs p;
p.reserve(points.size());
@@ -123,8 +109,7 @@ Point::nearest_point_index(const PointPtrs &points) const
return this->nearest_point_index(p);
}
-bool
-Point::nearest_point(const Points &points, Point* point) const
+bool Point::nearest_point(const Points &points, Point* point) const
{
int idx = this->nearest_point_index(points);
if (idx == -1) return false;
@@ -132,40 +117,6 @@ Point::nearest_point(const Points &points, Point* point) const
return true;
}
-/* distance to the closest point of line */
-double
-Point::distance_to(const Line &line) const
-{
- const double dx = line.b.x - line.a.x;
- const double dy = line.b.y - line.a.y;
-
- const double l2 = dx*dx + dy*dy; // avoid a sqrt
- if (l2 == 0.0) return this->distance_to(line.a); // line.a == line.b case
-
- // Consider the line extending the segment, parameterized as line.a + t (line.b - line.a).
- // We find projection of this point onto the line.
- // It falls where t = [(this-line.a) . (line.b-line.a)] / |line.b-line.a|^2
- const double t = ((this->x - line.a.x) * dx + (this->y - line.a.y) * dy) / l2;
- if (t < 0.0) return this->distance_to(line.a); // beyond the 'a' end of the segment
- else if (t > 1.0) return this->distance_to(line.b); // beyond the 'b' end of the segment
- Point projection(
- line.a.x + t * dx,
- line.a.y + t * dy
- );
- return this->distance_to(projection);
-}
-
-double
-Point::perp_distance_to(const Line &line) const
-{
- if (line.a.coincides_with(line.b)) return this->distance_to(line.a);
-
- double n = (double)(line.b.x - line.a.x) * (double)(line.a.y - this->y)
- - (double)(line.a.x - this->x) * (double)(line.b.y - line.a.y);
-
- return std::abs(n) / line.length();
-}
-
/* Three points are a counter-clockwise turn if ccw > 0, clockwise if
* ccw < 0, and collinear if ccw = 0 because ccw is a determinant that
* gives the signed area of the triangle formed by p1, p2 and this point.
@@ -173,51 +124,46 @@ Point::perp_distance_to(const Line &line) const
* z-component of their 3D cross product.
* We return double because it must be big enough to hold 2*max(|coordinate|)^2
*/
-double
-Point::ccw(const Point &p1, const Point &p2) const
+double Point::ccw(const Point &p1, const Point &p2) const
{
- return (double)(p2.x - p1.x)*(double)(this->y - p1.y) - (double)(p2.y - p1.y)*(double)(this->x - p1.x);
+ return (double)(p2(0) - p1(0))*(double)((*this)(1) - p1(1)) - (double)(p2(1) - p1(1))*(double)((*this)(0) - p1(0));
}
-double
-Point::ccw(const Line &line) const
+double Point::ccw(const Line &line) const
{
return this->ccw(line.a, line.b);
}
// returns the CCW angle between this-p1 and this-p2
// i.e. this assumes a CCW rotation from p1 to p2 around this
-double
-Point::ccw_angle(const Point &p1, const Point &p2) const
+double Point::ccw_angle(const Point &p1, const Point &p2) const
{
- double angle = atan2(p1.x - this->x, p1.y - this->y)
- - atan2(p2.x - this->x, p2.y - this->y);
+ double angle = atan2(p1(0) - (*this)(0), p1(1) - (*this)(1))
+ - atan2(p2(0) - (*this)(0), p2(1) - (*this)(1));
// we only want to return only positive angles
return angle <= 0 ? angle + 2*PI : angle;
}
-Point
-Point::projection_onto(const MultiPoint &poly) const
+Point Point::projection_onto(const MultiPoint &poly) const
{
Point running_projection = poly.first_point();
- double running_min = this->distance_to(running_projection);
+ double running_min = (running_projection - *this).cast<double>().norm();
Lines lines = poly.lines();
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
Point point_temp = this->projection_onto(*line);
- if (this->distance_to(point_temp) < running_min) {
+ if ((point_temp - *this).cast<double>().norm() < running_min) {
running_projection = point_temp;
- running_min = this->distance_to(running_projection);
+ running_min = (running_projection - *this).cast<double>().norm();
}
}
return running_projection;
}
-Point
-Point::projection_onto(const Line &line) const
+Point Point::projection_onto(const Line &line) const
{
- if (line.a.coincides_with(line.b)) return line.a;
+ if (line.a == line.b) return line.a;
/*
(Ported from VisiLibity by Karl J. Obermeyer)
@@ -228,151 +174,37 @@ Point::projection_onto(const Line &line) const
If theta is outside the interval [0,1], then one of the Line_Segment's endpoints
must be closest to calling Point.
*/
- double lx = (double)(line.b.x - line.a.x);
- double ly = (double)(line.b.y - line.a.y);
- double theta = ( (double)(line.b.x - this->x)*lx + (double)(line.b.y- this->y)*ly )
+ double lx = (double)(line.b(0) - line.a(0));
+ double ly = (double)(line.b(1) - line.a(1));
+ double theta = ( (double)(line.b(0) - (*this)(0))*lx + (double)(line.b(1)- (*this)(1))*ly )
/ ( sqr<double>(lx) + sqr<double>(ly) );
if (0.0 <= theta && theta <= 1.0)
- return theta * line.a + (1.0-theta) * line.b;
+ return (theta * line.a.cast<coordf_t>() + (1.0-theta) * line.b.cast<coordf_t>()).cast<coord_t>();
// Else pick closest endpoint.
- if (this->distance_to(line.a) < this->distance_to(line.b)) {
- return line.a;
- } else {
- return line.b;
- }
-}
-
-Point
-Point::negative() const
-{
- return Point(-this->x, -this->y);
-}
-
-Vector
-Point::vector_to(const Point &point) const
-{
- return Vector(point.x - this->x, point.y - this->y);
-}
-
-std::ostream&
-operator<<(std::ostream &stm, const Pointf &pointf)
-{
- return stm << pointf.x << "," << pointf.y;
+ return ((line.a - *this).cast<double>().squaredNorm() < (line.b - *this).cast<double>().squaredNorm()) ? line.a : line.b;
}
-std::string
-Pointf::wkt() const
+std::ostream& operator<<(std::ostream &stm, const Vec2d &pointf)
{
- std::ostringstream ss;
- ss << "POINT(" << this->x << " " << this->y << ")";
- return ss.str();
+ return stm << pointf(0) << "," << pointf(1);
}
-std::string
-Pointf::dump_perl() const
-{
- std::ostringstream ss;
- ss << "[" << this->x << "," << this->y << "]";
- return ss.str();
-}
-
-void
-Pointf::scale(double factor)
-{
- this->x *= factor;
- this->y *= factor;
-}
-
-void
-Pointf::translate(double x, double y)
-{
- this->x += x;
- this->y += y;
-}
-
-void
-Pointf::translate(const Vectorf &vector)
-{
- this->translate(vector.x, vector.y);
-}
-
-void
-Pointf::rotate(double angle)
-{
- double cur_x = this->x;
- double cur_y = this->y;
- double s = sin(angle);
- double c = cos(angle);
- this->x = c * cur_x - s * cur_y;
- this->y = c * cur_y + s * cur_x;
-}
-
-void
-Pointf::rotate(double angle, const Pointf &center)
-{
- double cur_x = this->x;
- double cur_y = this->y;
- double s = sin(angle);
- double c = cos(angle);
- double dx = cur_x - center.x;
- double dy = cur_y - center.y;
- this->x = center.x + c * dx - s * dy;
- this->y = center.y + c * dy + s * dx;
-}
+namespace int128 {
-Pointf
-Pointf::negative() const
+int orient(const Vec2crd &p1, const Vec2crd &p2, const Vec2crd &p3)
{
- return Pointf(-this->x, -this->y);
+ Slic3r::Vector v1(p2 - p1);
+ Slic3r::Vector v2(p3 - p1);
+ return Int128::sign_determinant_2x2_filtered(v1(0), v1(1), v2(0), v2(1));
}
-Vectorf
-Pointf::vector_to(const Pointf &point) const
+int cross(const Vec2crd &v1, const Vec2crd &v2)
{
- return Vectorf(point.x - this->x, point.y - this->y);
+ return Int128::sign_determinant_2x2_filtered(v1(0), v1(1), v2(0), v2(1));
}
-void
-Pointf3::scale(double factor)
-{
- Pointf::scale(factor);
- this->z *= factor;
-}
-
-void
-Pointf3::translate(const Vectorf3 &vector)
-{
- this->translate(vector.x, vector.y, vector.z);
-}
-
-void
-Pointf3::translate(double x, double y, double z)
-{
- Pointf::translate(x, y);
- this->z += z;
-}
-
-double
-Pointf3::distance_to(const Pointf3 &point) const
-{
- double dx = ((double)point.x - this->x);
- double dy = ((double)point.y - this->y);
- double dz = ((double)point.z - this->z);
- return sqrt(dx*dx + dy*dy + dz*dz);
-}
-
-Pointf3
-Pointf3::negative() const
-{
- return Pointf3(-this->x, -this->y, -this->z);
-}
-
-Vectorf3
-Pointf3::vector_to(const Pointf3 &point) const
-{
- return Vectorf3(point.x - this->x, point.y - this->y, point.z - this->z);
}
}
diff --git a/xs/src/libslic3r/Point.hpp b/xs/src/libslic3r/Point.hpp
index 6c9096a3d..c1aff561f 100644
--- a/xs/src/libslic3r/Point.hpp
+++ b/xs/src/libslic3r/Point.hpp
@@ -2,89 +2,131 @@
#define slic3r_Point_hpp_
#include "libslic3r.h"
+#include <cstddef>
#include <vector>
-#include <math.h>
+#include <cmath>
#include <string>
#include <sstream>
#include <unordered_map>
+#include <Eigen/Geometry>
+
namespace Slic3r {
class Line;
-class Linef;
class MultiPoint;
class Point;
-class Point3;
-class Pointf;
-class Pointf3;
typedef Point Vector;
-typedef Point3 Vector3;
-typedef Pointf Vectorf;
-typedef Pointf3 Vectorf3;
-typedef std::vector<Point> Points;
-typedef std::vector<Point*> PointPtrs;
-typedef std::vector<const Point*> PointConstPtrs;
-typedef std::vector<Point3> Points3;
-typedef std::vector<Pointf> Pointfs;
-typedef std::vector<Pointf3> Pointf3s;
-class Point
+// Eigen types, to replace the Slic3r's own types in the future.
+// Vector types with a fixed point coordinate base type.
+typedef Eigen::Matrix<coord_t, 2, 1, Eigen::DontAlign> Vec2crd;
+typedef Eigen::Matrix<coord_t, 3, 1, Eigen::DontAlign> Vec3crd;
+typedef Eigen::Matrix<int64_t, 2, 1, Eigen::DontAlign> Vec2i64;
+typedef Eigen::Matrix<int64_t, 3, 1, Eigen::DontAlign> Vec3i64;
+
+// Vector types with a double coordinate base type.
+typedef Eigen::Matrix<float, 2, 1, Eigen::DontAlign> Vec2f;
+typedef Eigen::Matrix<float, 3, 1, Eigen::DontAlign> Vec3f;
+typedef Eigen::Matrix<double, 2, 1, Eigen::DontAlign> Vec2d;
+typedef Eigen::Matrix<double, 3, 1, Eigen::DontAlign> Vec3d;
+
+typedef std::vector<Point> Points;
+typedef std::vector<Point*> PointPtrs;
+typedef std::vector<const Point*> PointConstPtrs;
+typedef std::vector<Vec3crd> Points3;
+typedef std::vector<Vec2d> Pointfs;
+typedef std::vector<Vec3d> Pointf3s;
+
+typedef Eigen::Transform<float, 2, Eigen::Affine, Eigen::DontAlign> Transform2f;
+typedef Eigen::Transform<double, 2, Eigen::Affine, Eigen::DontAlign> Transform2d;
+typedef Eigen::Transform<float, 3, Eigen::Affine, Eigen::DontAlign> Transform3f;
+typedef Eigen::Transform<double, 3, Eigen::Affine, Eigen::DontAlign> Transform3d;
+
+inline bool operator<(const Vec2d &lhs, const Vec2d &rhs) { return lhs(0) < rhs(0) || (lhs(0) == rhs(0) && lhs(1) < rhs(1)); }
+
+inline int64_t cross2(const Vec2i64 &v1, const Vec2i64 &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
+inline coord_t cross2(const Vec2crd &v1, const Vec2crd &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
+inline float cross2(const Vec2f &v1, const Vec2f &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
+inline double cross2(const Vec2d &v1, const Vec2d &v2) { return v1(0) * v2(1) - v1(1) * v2(0); }
+
+inline Vec2crd to_2d(const Vec3crd &pt3) { return Vec2crd(pt3(0), pt3(1)); }
+inline Vec2i64 to_2d(const Vec3i64 &pt3) { return Vec2i64(pt3(0), pt3(1)); }
+inline Vec2f to_2d(const Vec3f &pt3) { return Vec2f (pt3(0), pt3(1)); }
+inline Vec2d to_2d(const Vec3d &pt3) { return Vec2d (pt3(0), pt3(1)); }
+
+inline Vec2d unscale(coord_t x, coord_t y) { return Vec2d(unscale<double>(x), unscale<double>(y)); }
+inline Vec2d unscale(const Vec2crd &pt) { return Vec2d(unscale<double>(pt(0)), unscale<double>(pt(1))); }
+inline Vec2d unscale(const Vec2d &pt) { return Vec2d(unscale<double>(pt(0)), unscale<double>(pt(1))); }
+inline Vec3d unscale(coord_t x, coord_t y, coord_t z) { return Vec3d(unscale<double>(x), unscale<double>(y), unscale<double>(z)); }
+inline Vec3d unscale(const Vec3crd &pt) { return Vec3d(unscale<double>(pt(0)), unscale<double>(pt(1)), unscale<double>(pt(2))); }
+inline Vec3d unscale(const Vec3d &pt) { return Vec3d(unscale<double>(pt(0)), unscale<double>(pt(1)), unscale<double>(pt(2))); }
+
+inline std::string to_string(const Vec2crd &pt) { return std::string("[") + std::to_string(pt(0)) + ", " + std::to_string(pt(1)) + "]"; }
+inline std::string to_string(const Vec2d &pt) { return std::string("[") + std::to_string(pt(0)) + ", " + std::to_string(pt(1)) + "]"; }
+inline std::string to_string(const Vec3crd &pt) { return std::string("[") + std::to_string(pt(0)) + ", " + std::to_string(pt(1)) + ", " + std::to_string(pt(2)) + "]"; }
+inline std::string to_string(const Vec3d &pt) { return std::string("[") + std::to_string(pt(0)) + ", " + std::to_string(pt(1)) + ", " + std::to_string(pt(2)) + "]"; }
+
+std::vector<Vec3f> transform(const std::vector<Vec3f>& points, const Transform3f& t);
+Pointf3s transform(const Pointf3s& points, const Transform3d& t);
+
+class Point : public Vec2crd
{
public:
typedef coord_t coord_type;
- coord_t x;
- coord_t y;
- Point(coord_t _x = 0, coord_t _y = 0): x(_x), y(_y) {};
- Point(int64_t _x, int64_t _y): x(coord_t(_x)), y(coord_t(_y)) {}; // for Clipper
- Point(double x, double y);
+
+ Point() : Vec2crd() { (*this)(0) = 0; (*this)(1) = 0; }
+ Point(coord_t x, coord_t y) { (*this)(0) = x; (*this)(1) = y; }
+ Point(int64_t x, int64_t y) { (*this)(0) = coord_t(x); (*this)(1) = coord_t(y); } // for Clipper
+ Point(double x, double y) { (*this)(0) = coord_t(lrint(x)); (*this)(1) = coord_t(lrint(y)); }
+ Point(const Point &rhs) { *this = rhs; }
+ // This constructor allows you to construct Point from Eigen expressions
+ template<typename OtherDerived>
+ Point(const Eigen::MatrixBase<OtherDerived> &other) : Vec2crd(other) {}
static Point new_scale(coordf_t x, coordf_t y) { return Point(coord_t(scale_(x)), coord_t(scale_(y))); }
- bool operator==(const Point& rhs) const { return this->x == rhs.x && this->y == rhs.y; }
- bool operator!=(const Point& rhs) const { return ! (*this == rhs); }
- bool operator<(const Point& rhs) const { return this->x < rhs.x || (this->x == rhs.x && this->y < rhs.y); }
+ // This method allows you to assign Eigen expressions to MyVectorType
+ template<typename OtherDerived>
+ Point& operator=(const Eigen::MatrixBase<OtherDerived> &other)
+ {
+ this->Vec2crd::operator=(other);
+ return *this;
+ }
- Point& operator+=(const Point& rhs) { this->x += rhs.x; this->y += rhs.y; return *this; }
- Point& operator-=(const Point& rhs) { this->x -= rhs.x; this->y -= rhs.y; return *this; }
- Point& operator*=(const coord_t& rhs) { this->x *= rhs; this->y *= rhs; return *this; }
+ bool operator< (const Point& rhs) const { return (*this)(0) < rhs(0) || ((*this)(0) == rhs(0) && (*this)(1) < rhs(1)); }
- std::string wkt() const;
- std::string dump_perl() const;
- void scale(double factor);
- void translate(double x, double y);
- void translate(const Vector &vector);
- void rotate(double angle);
- void rotate(double angle, const Point &center);
- Point rotated(double angle) const { Point res(*this); res.rotate(angle); return res; }
- Point rotated(double angle, const Point &center) const { Point res(*this); res.rotate(angle, center); return res; }
- bool coincides_with(const Point &point) const { return this->x == point.x && this->y == point.y; }
- bool coincides_with_epsilon(const Point &point) const;
- int nearest_point_index(const Points &points) const;
- int nearest_point_index(const PointConstPtrs &points) const;
- int nearest_point_index(const PointPtrs &points) const;
- bool nearest_point(const Points &points, Point* point) const;
- double distance_to(const Point &point) const { return sqrt(distance_to_sq(point)); }
- double distance_to_sq(const Point &point) const { double dx = double(point.x - this->x); double dy = double(point.y - this->y); return dx*dx + dy*dy; }
- double distance_to(const Line &line) const;
- double perp_distance_to(const Line &line) const;
+ Point& operator+=(const Point& rhs) { (*this)(0) += rhs(0); (*this)(1) += rhs(1); return *this; }
+ Point& operator-=(const Point& rhs) { (*this)(0) -= rhs(0); (*this)(1) -= rhs(1); return *this; }
+ Point& operator*=(const double &rhs) { (*this)(0) *= rhs; (*this)(1) *= rhs; return *this; }
+
+ void rotate(double angle);
+ void rotate(double angle, const Point &center);
+ Point rotated(double angle) const { Point res(*this); res.rotate(angle); return res; }
+ Point rotated(double angle, const Point &center) const { Point res(*this); res.rotate(angle, center); return res; }
+ int nearest_point_index(const Points &points) const;
+ int nearest_point_index(const PointConstPtrs &points) const;
+ int nearest_point_index(const PointPtrs &points) const;
+ bool nearest_point(const Points &points, Point* point) const;
double ccw(const Point &p1, const Point &p2) const;
double ccw(const Line &line) const;
double ccw_angle(const Point &p1, const Point &p2) const;
- Point projection_onto(const MultiPoint &poly) const;
- Point projection_onto(const Line &line) const;
- Point negative() const;
- Vector vector_to(const Point &point) const;
+ Point projection_onto(const MultiPoint &poly) const;
+ Point projection_onto(const Line &line) const;
};
-inline Point operator+(const Point& point1, const Point& point2) { return Point(point1.x + point2.x, point1.y + point2.y); }
-inline Point operator-(const Point& point1, const Point& point2) { return Point(point1.x - point2.x, point1.y - point2.y); }
-inline Point operator*(double scalar, const Point& point2) { return Point(scalar * point2.x, scalar * point2.y); }
-inline int64_t cross(const Point &v1, const Point &v2) { return int64_t(v1.x) * int64_t(v2.y) - int64_t(v1.y) * int64_t(v2.x); }
-inline int64_t dot(const Point &v1, const Point &v2) { return int64_t(v1.x) * int64_t(v2.x) + int64_t(v1.y) * int64_t(v2.y); }
+namespace int128 {
+ // Exact orientation predicate,
+ // returns +1: CCW, 0: collinear, -1: CW.
+ int orient(const Vec2crd &p1, const Vec2crd &p2, const Vec2crd &p3);
+ // Exact orientation predicate,
+ // returns +1: CCW, 0: collinear, -1: CW.
+ int cross(const Vec2crd &v1, const Vec2crd &v2);
+}
// To be used by std::unordered_map, std::unordered_multimap and friends.
struct PointHash {
- size_t operator()(const Point &pt) const {
- return std::hash<coord_t>()(pt.x) ^ std::hash<coord_t>()(pt.y);
+ size_t operator()(const Vec2crd &pt) const {
+ return std::hash<coord_t>()(pt(0)) ^ std::hash<coord_t>()(pt(1));
}
};
@@ -128,36 +170,36 @@ public:
}
void insert(const ValueType &value) {
- const Point *pt = m_point_accessor(value);
+ const Vec2crd *pt = m_point_accessor(value);
if (pt != nullptr)
- m_map.emplace(std::make_pair(Point(pt->x>>m_grid_log2, pt->y>>m_grid_log2), value));
+ m_map.emplace(std::make_pair(Vec2crd(pt->x()>>m_grid_log2, pt->y()>>m_grid_log2), value));
}
void insert(ValueType &&value) {
- const Point *pt = m_point_accessor(value);
+ const Vec2crd *pt = m_point_accessor(value);
if (pt != nullptr)
- m_map.emplace(std::make_pair(Point(pt->x>>m_grid_log2, pt->y>>m_grid_log2), std::move(value)));
+ m_map.emplace(std::make_pair(Vec2crd(pt->x()>>m_grid_log2, pt->y()>>m_grid_log2), std::move(value)));
}
// Return a pair of <ValueType*, distance_squared>
- std::pair<const ValueType*, double> find(const Point &pt) {
+ std::pair<const ValueType*, double> find(const Vec2crd &pt) {
// Iterate over 4 closest grid cells around pt,
// find the closest start point inside these cells to pt.
const ValueType *value_min = nullptr;
double dist_min = std::numeric_limits<double>::max();
// Round pt to a closest grid_cell corner.
- Point grid_corner((pt.x+(m_grid_resolution>>1))>>m_grid_log2, (pt.y+(m_grid_resolution>>1))>>m_grid_log2);
+ Vec2crd grid_corner((pt(0)+(m_grid_resolution>>1))>>m_grid_log2, (pt(1)+(m_grid_resolution>>1))>>m_grid_log2);
// For four neighbors of grid_corner:
for (coord_t neighbor_y = -1; neighbor_y < 1; ++ neighbor_y) {
for (coord_t neighbor_x = -1; neighbor_x < 1; ++ neighbor_x) {
// Range of fragment starts around grid_corner, close to pt.
- auto range = m_map.equal_range(Point(grid_corner.x + neighbor_x, grid_corner.y + neighbor_y));
+ auto range = m_map.equal_range(Vec2crd(grid_corner(0) + neighbor_x, grid_corner(1) + neighbor_y));
// Find the map entry closest to pt.
for (auto it = range.first; it != range.second; ++it) {
const ValueType &value = it->second;
- const Point *pt2 = m_point_accessor(value);
+ const Vec2crd *pt2 = m_point_accessor(value);
if (pt2 != nullptr) {
- const double d2 = pt.distance_to_sq(*pt2);
+ const double d2 = (pt - *pt2).squaredNorm();
if (d2 < dist_min) {
dist_min = d2;
value_min = &value;
@@ -172,7 +214,7 @@ public:
}
private:
- typedef typename std::unordered_multimap<Point, ValueType, PointHash> map_type;
+ typedef typename std::unordered_multimap<Vec2crd, ValueType, PointHash> map_type;
PointAccessor m_point_accessor;
map_type m_map;
coord_t m_search_radius;
@@ -180,107 +222,7 @@ private:
coord_t m_grid_log2;
};
-class Point3 : public Point
-{
-public:
- coord_t z;
- explicit Point3(coord_t _x = 0, coord_t _y = 0, coord_t _z = 0): Point(_x, _y), z(_z) {};
- static Point3 new_scale(coordf_t x, coordf_t y, coordf_t z) { return Point3(coord_t(scale_(x)), coord_t(scale_(y)), coord_t(scale_(z))); }
- bool operator==(const Point3 &rhs) const { return this->x == rhs.x && this->y == rhs.y && this->z == rhs.z; }
- bool operator!=(const Point3 &rhs) const { return ! (*this == rhs); }
- bool coincides_with(const Point3& rhs) const { return this->x == rhs.x && this->y == rhs.y && this->z == rhs.z; }
-private:
- // Hide the following inherited methods:
- bool operator==(const Point &rhs) const;
- bool operator!=(const Point &rhs) const;
-};
-
-std::ostream& operator<<(std::ostream &stm, const Pointf &pointf);
-
-class Pointf
-{
-public:
- typedef coordf_t coord_type;
- coordf_t x;
- coordf_t y;
- explicit Pointf(coordf_t _x = 0, coordf_t _y = 0): x(_x), y(_y) {};
- static Pointf new_unscale(coord_t x, coord_t y) {
- return Pointf(unscale(x), unscale(y));
- };
- static Pointf new_unscale(const Point &p) {
- return Pointf(unscale(p.x), unscale(p.y));
- };
- std::string wkt() const;
- std::string dump_perl() const;
- void scale(double factor);
- void translate(double x, double y);
- void translate(const Vectorf &vector);
- void rotate(double angle);
- void rotate(double angle, const Pointf &center);
- Pointf negative() const;
- Vectorf vector_to(const Pointf &point) const;
-
- Pointf& operator+=(const Pointf& rhs) { this->x += rhs.x; this->y += rhs.y; return *this; }
- Pointf& operator-=(const Pointf& rhs) { this->x -= rhs.x; this->y -= rhs.y; return *this; }
- Pointf& operator*=(const coordf_t& rhs) { this->x *= rhs; this->y *= rhs; return *this; }
-
- bool operator==(const Pointf &rhs) const { return this->x == rhs.x && this->y == rhs.y; }
- bool operator!=(const Pointf &rhs) const { return ! (*this == rhs); }
- bool operator< (const Pointf& rhs) const { return this->x < rhs.x || (this->x == rhs.x && this->y < rhs.y); }
-};
-
-inline Pointf operator+(const Pointf& point1, const Pointf& point2) { return Pointf(point1.x + point2.x, point1.y + point2.y); }
-inline Pointf operator-(const Pointf& point1, const Pointf& point2) { return Pointf(point1.x - point2.x, point1.y - point2.y); }
-inline Pointf operator*(double scalar, const Pointf& point2) { return Pointf(scalar * point2.x, scalar * point2.y); }
-inline Pointf operator*(const Pointf& point2, double scalar) { return Pointf(scalar * point2.x, scalar * point2.y); }
-inline coordf_t cross(const Pointf &v1, const Pointf &v2) { return v1.x * v2.y - v1.y * v2.x; }
-inline coordf_t dot(const Pointf &v1, const Pointf &v2) { return v1.x * v2.x + v1.y * v2.y; }
-inline coordf_t dot(const Pointf &v) { return v.x * v.x + v.y * v.y; }
-inline double length(const Vectorf &v) { return sqrt(dot(v)); }
-inline double l2(const Vectorf &v) { return dot(v); }
-
-class Pointf3 : public Pointf
-{
-public:
- coordf_t z;
- explicit Pointf3(coordf_t _x = 0, coordf_t _y = 0, coordf_t _z = 0): Pointf(_x, _y), z(_z) {};
- static Pointf3 new_unscale(coord_t x, coord_t y, coord_t z) {
- return Pointf3(unscale(x), unscale(y), unscale(z));
- };
- static Pointf3 new_unscale(const Point3& p) { return Pointf3(unscale(p.x), unscale(p.y), unscale(p.z)); }
- void scale(double factor);
- void translate(const Vectorf3 &vector);
- void translate(double x, double y, double z);
- double distance_to(const Pointf3 &point) const;
- Pointf3 negative() const;
- Vectorf3 vector_to(const Pointf3 &point) const;
-
- bool operator==(const Pointf3 &rhs) const { return this->x == rhs.x && this->y == rhs.y && this->z == rhs.z; }
- bool operator!=(const Pointf3 &rhs) const { return ! (*this == rhs); }
-
-private:
- // Hide the following inherited methods:
- bool operator==(const Pointf &rhs) const;
- bool operator!=(const Pointf &rhs) const;
-};
-
-inline Pointf3 operator+(const Pointf3& p1, const Pointf3& p2) { return Pointf3(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z); }
-inline Pointf3 operator-(const Pointf3& p1, const Pointf3& p2) { return Pointf3(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z); }
-inline Pointf3 operator-(const Pointf3& p) { return Pointf3(-p.x, -p.y, -p.z); }
-inline Pointf3 operator*(double scalar, const Pointf3& p) { return Pointf3(scalar * p.x, scalar * p.y, scalar * p.z); }
-inline Pointf3 operator*(const Pointf3& p, double scalar) { return Pointf3(scalar * p.x, scalar * p.y, scalar * p.z); }
-inline Pointf3 cross(const Pointf3& v1, const Pointf3& v2) { return Pointf3(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x); }
-inline coordf_t dot(const Pointf3& v1, const Pointf3& v2) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; }
-inline Pointf3 normalize(const Pointf3& v)
-{
- coordf_t len = ::sqrt(sqr(v.x) + sqr(v.y) + sqr(v.z));
- return (len != 0.0) ? 1.0 / len * v : Pointf3(0.0, 0.0, 0.0);
-}
-
-template<typename TO> inline TO convert_to(const Point &src) { return TO(typename TO::coord_type(src.x), typename TO::coord_type(src.y)); }
-template<typename TO> inline TO convert_to(const Pointf &src) { return TO(typename TO::coord_type(src.x), typename TO::coord_type(src.y)); }
-template<typename TO> inline TO convert_to(const Point3 &src) { return TO(typename TO::coord_type(src.x), typename TO::coord_type(src.y), typename TO::coord_type(src.z)); }
-template<typename TO> inline TO convert_to(const Pointf3 &src) { return TO(typename TO::coord_type(src.x), typename TO::coord_type(src.y), typename TO::coord_type(src.z)); }
+std::ostream& operator<<(std::ostream &stm, const Vec2d &pointf);
} // namespace Slic3r
@@ -296,7 +238,7 @@ namespace boost { namespace polygon {
typedef coord_t coordinate_type;
static inline coordinate_type get(const Slic3r::Point& point, orientation_2d orient) {
- return (orient == HORIZONTAL) ? point.x : point.y;
+ return (orient == HORIZONTAL) ? (coordinate_type)point(0) : (coordinate_type)point(1);
}
};
@@ -305,14 +247,14 @@ namespace boost { namespace polygon {
typedef coord_t coordinate_type;
static inline void set(Slic3r::Point& point, orientation_2d orient, coord_t value) {
if (orient == HORIZONTAL)
- point.x = value;
+ point(0) = value;
else
- point.y = value;
+ point(1) = value;
}
static inline Slic3r::Point construct(coord_t x_value, coord_t y_value) {
Slic3r::Point retval;
- retval.x = x_value;
- retval.y = y_value;
+ retval(0) = x_value;
+ retval(1) = y_value;
return retval;
}
};
diff --git a/xs/src/libslic3r/Polygon.cpp b/xs/src/libslic3r/Polygon.cpp
index 27f9a2ca1..14248d84f 100644
--- a/xs/src/libslic3r/Polygon.cpp
+++ b/xs/src/libslic3r/Polygon.cpp
@@ -44,11 +44,9 @@ Polyline
Polygon::split_at_vertex(const Point &point) const
{
// find index of point
- for (Points::const_iterator it = this->points.begin(); it != this->points.end(); ++it) {
- if (it->coincides_with(point)) {
- return this->split_at_index(it - this->points.begin());
- }
- }
+ for (const Point &pt : this->points)
+ if (pt == point)
+ return this->split_at_index(&pt - &this->points.front());
CONFESS("Point not found");
return Polyline();
}
@@ -88,7 +86,7 @@ int64_t Polygon::area2x() const
int64_t a = 0;
for (size_t i = 0, j = n - 1; i < n; ++i)
- a += int64_t(poly[j].x + poly[i].x) * int64_t(poly[j].y - poly[i].y);
+ a += int64_t(poly[j](0) + poly[i](0)) * int64_t(poly[j](1) - poly[i](1));
j = i;
}
return -a * 0.5;
@@ -103,7 +101,7 @@ double Polygon::area() const
double a = 0.;
for (size_t i = 0, j = n - 1; i < n; ++i) {
- a += double(points[j].x + points[i].x) * double(points[i].y - points[j].y);
+ a += ((double)points[j](0) + (double)points[i](0)) * ((double)points[i](1) - (double)points[j](1));
j = i;
}
return 0.5 * a;
@@ -157,17 +155,17 @@ Polygon::contains(const Point &point) const
Points::const_iterator i = this->points.begin();
Points::const_iterator j = this->points.end() - 1;
for (; i != this->points.end(); j = i++) {
- //FIXME this test is not numerically robust. Particularly, it does not handle horizontal segments at y == point.y well.
- // Does the ray with y == point.y intersect this line segment?
+ //FIXME this test is not numerically robust. Particularly, it does not handle horizontal segments at y == point(1) well.
+ // Does the ray with y == point(1) intersect this line segment?
#if 1
- if ( ((i->y > point.y) != (j->y > point.y))
- && ((double)point.x < (double)(j->x - i->x) * (double)(point.y - i->y) / (double)(j->y - i->y) + (double)i->x) )
+ if ( (((*i)(1) > point(1)) != ((*j)(1) > point(1)))
+ && ((double)point(0) < (double)((*j)(0) - (*i)(0)) * (double)(point(1) - (*i)(1)) / (double)((*j)(1) - (*i)(1)) + (double)(*i)(0)) )
result = !result;
#else
- if ((i->y > point.y) != (j->y > point.y)) {
+ if (((*i)(1) > point(1)) != ((*j)(1) > point(1))) {
// Orientation predicated relative to i-th point.
- double orient = (double)(point.x - i->x) * (double)(j->y - i->y) - (double)(point.y - i->y) * (double)(j->x - i->x);
- if ((i->y > j->y) ? (orient > 0.) : (orient < 0.))
+ double orient = (double)(point(0) - (*i)(0)) * (double)((*j)(1) - (*i)(1)) - (double)(point(1) - (*i)(1)) * (double)((*j)(0) - (*i)(0));
+ if (((*i)(1) > (*j)(1)) ? (orient > 0.) : (orient < 0.))
result = !result;
}
#endif
@@ -225,26 +223,13 @@ Polygon::centroid() const
Polyline polyline = this->split_at_first_point();
for (Points::const_iterator point = polyline.points.begin(); point != polyline.points.end() - 1; ++point) {
- x_temp += (double)( point->x + (point+1)->x ) * ( (double)point->x*(point+1)->y - (double)(point+1)->x*point->y );
- y_temp += (double)( point->y + (point+1)->y ) * ( (double)point->x*(point+1)->y - (double)(point+1)->x*point->y );
+ x_temp += (double)( point->x() + (point+1)->x() ) * ( (double)point->x()*(point+1)->y() - (double)(point+1)->x()*point->y() );
+ y_temp += (double)( point->y() + (point+1)->y() ) * ( (double)point->x()*(point+1)->y() - (double)(point+1)->x()*point->y() );
}
return Point(x_temp/(6*area_temp), y_temp/(6*area_temp));
}
-std::string
-Polygon::wkt() const
-{
- std::ostringstream wkt;
- wkt << "POLYGON((";
- for (Points::const_iterator p = this->points.begin(); p != this->points.end(); ++p) {
- wkt << p->x << " " << p->y;
- if (p != this->points.end()-1) wkt << ",";
- }
- wkt << "))";
- return wkt.str();
-}
-
// find all concave vertices (i.e. having an internal angle greater than the supplied angle)
// (external = right side, thus we consider ccw orientation)
Points
@@ -302,24 +287,24 @@ Point Polygon::point_projection(const Point &point) const
for (size_t i = 0; i < this->points.size(); ++ i) {
const Point &pt0 = this->points[i];
const Point &pt1 = this->points[(i + 1 == this->points.size()) ? 0 : i + 1];
- double d = pt0.distance_to(point);
+ double d = (point - pt0).cast<double>().norm();
if (d < dmin) {
dmin = d;
proj = pt0;
}
- d = pt1.distance_to(point);
+ d = (point - pt1).cast<double>().norm();
if (d < dmin) {
dmin = d;
proj = pt1;
}
- Pointf v1(coordf_t(pt1.x - pt0.x), coordf_t(pt1.y - pt0.y));
- coordf_t div = dot(v1);
+ Vec2d v1(coordf_t(pt1(0) - pt0(0)), coordf_t(pt1(1) - pt0(1)));
+ coordf_t div = v1.squaredNorm();
if (div > 0.) {
- Pointf v2(coordf_t(point.x - pt0.x), coordf_t(point.y - pt0.y));
- coordf_t t = dot(v1, v2) / div;
+ Vec2d v2(coordf_t(point(0) - pt0(0)), coordf_t(point(1) - pt0(1)));
+ coordf_t t = v1.dot(v2) / div;
if (t > 0. && t < 1.) {
- Point foot(coord_t(floor(coordf_t(pt0.x) + t * v1.x + 0.5)), coord_t(floor(coordf_t(pt0.y) + t * v1.y + 0.5)));
- d = foot.distance_to(point);
+ Point foot(coord_t(floor(coordf_t(pt0(0)) + t * v1(0) + 0.5)), coord_t(floor(coordf_t(pt0(1)) + t * v1(1) + 0.5)));
+ d = (point - foot).cast<double>().norm();
if (d < dmin) {
dmin = d;
proj = foot;
@@ -376,12 +361,12 @@ static inline bool is_stick(const Point &p1, const Point &p2, const Point &p3)
{
Point v1 = p2 - p1;
Point v2 = p3 - p2;
- int64_t dir = int64_t(v1.x) * int64_t(v2.x) + int64_t(v1.y) * int64_t(v2.y);
+ int64_t dir = int64_t(v1(0)) * int64_t(v2(0)) + int64_t(v1(1)) * int64_t(v2(1));
if (dir > 0)
// p3 does not turn back to p1. Do not remove p2.
return false;
- double l2_1 = double(v1.x) * double(v1.x) + double(v1.y) * double(v1.y);
- double l2_2 = double(v2.x) * double(v2.x) + double(v2.y) * double(v2.y);
+ double l2_1 = double(v1(0)) * double(v1(0)) + double(v1(1)) * double(v1(1));
+ double l2_2 = double(v2(0)) * double(v2(0)) + double(v2(1)) * double(v2(1));
if (dir == 0)
// p1, p2, p3 may make a perpendicular corner, or there is a zero edge length.
// Remove p2 if it is coincident with p1 or p2.
@@ -389,7 +374,7 @@ static inline bool is_stick(const Point &p1, const Point &p2, const Point &p3)
// p3 turns back to p1 after p2. Are p1, p2, p3 collinear?
// Calculate distance from p3 to a segment (p1, p2) or from p1 to a segment(p2, p3),
// whichever segment is longer
- double cross = double(v1.x) * double(v2.y) - double(v2.x) * double(v1.y);
+ double cross = double(v1(0)) * double(v2(1)) - double(v2(0)) * double(v1(1));
double dist2 = cross * cross / std::max(l2_1, l2_2);
return dist2 < EPSILON * EPSILON;
}
diff --git a/xs/src/libslic3r/Polygon.hpp b/xs/src/libslic3r/Polygon.hpp
index 1a02d78b7..54909352c 100644
--- a/xs/src/libslic3r/Polygon.hpp
+++ b/xs/src/libslic3r/Polygon.hpp
@@ -24,11 +24,12 @@ public:
explicit Polygon(const Points &points): MultiPoint(points) {}
Polygon(const Polygon &other) : MultiPoint(other.points) {}
Polygon(Polygon &&other) : MultiPoint(std::move(other.points)) {}
- static Polygon new_scale(std::vector<Pointf> points) {
- Points int_points;
- for (auto pt : points)
- int_points.push_back(Point::new_scale(pt.x, pt.y));
- return Polygon(int_points);
+ static Polygon new_scale(const std::vector<Vec2d> &points) {
+ Polygon pgn;
+ pgn.points.reserve(points.size());
+ for (const Vec2d &pt : points)
+ pgn.points.emplace_back(Point::new_scale(pt(0), pt(1)));
+ return pgn;
}
Polygon& operator=(const Polygon &other) { points = other.points; return *this; }
Polygon& operator=(Polygon &&other) { points = std::move(other.points); return *this; }
@@ -54,7 +55,6 @@ public:
void simplify(double tolerance, Polygons &polygons) const;
void triangulate_convex(Polygons* polygons) const;
Point centroid() const;
- std::string wkt() const;
Points concave_points(double angle = PI) const;
Points convex_points(double angle = PI) const;
// Projection of a point onto the polygon.
diff --git a/xs/src/libslic3r/Polyline.cpp b/xs/src/libslic3r/Polyline.cpp
index 3432506c6..b2e50bca3 100644
--- a/xs/src/libslic3r/Polyline.cpp
+++ b/xs/src/libslic3r/Polyline.cpp
@@ -33,7 +33,7 @@ Polyline::leftmost_point() const
{
Point p = this->points.front();
for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) {
- if (it->x < p.x) p = *it;
+ if ((*it)(0) < p(0)) p = *it;
}
return p;
}
@@ -52,92 +52,82 @@ Polyline::lines() const
}
// removes the given distance from the end of the polyline
-void
-Polyline::clip_end(double distance)
+void Polyline::clip_end(double distance)
{
while (distance > 0) {
- Point last_point = this->last_point();
+ Vec2d last_point = this->last_point().cast<double>();
this->points.pop_back();
- if (this->points.empty()) break;
-
- double last_segment_length = last_point.distance_to(this->last_point());
- if (last_segment_length <= distance) {
- distance -= last_segment_length;
- continue;
+ if (this->points.empty())
+ break;
+ Vec2d v = this->last_point().cast<double>() - last_point;
+ double lsqr = v.squaredNorm();
+ if (lsqr > distance * distance) {
+ this->points.emplace_back((last_point + v * (distance / sqrt(lsqr))).cast<coord_t>());
+ return;
}
-
- Line segment(last_point, this->last_point());
- this->points.push_back(segment.point_at(distance));
- distance = 0;
+ distance -= sqrt(lsqr);
}
}
// removes the given distance from the start of the polyline
-void
-Polyline::clip_start(double distance)
+void Polyline::clip_start(double distance)
{
this->reverse();
this->clip_end(distance);
- if (this->points.size() >= 2) this->reverse();
+ if (this->points.size() >= 2)
+ this->reverse();
}
-void
-Polyline::extend_end(double distance)
+void Polyline::extend_end(double distance)
{
// relocate last point by extending the last segment by the specified length
- Line line(
- this->points.back(),
- *(this->points.end() - 2)
- );
- this->points.back() = line.point_at(-distance);
+ Vec2d v = (this->points.back() - *(this->points.end() - 2)).cast<double>().normalized();
+ this->points.back() += (v * distance).cast<coord_t>();
}
-void
-Polyline::extend_start(double distance)
+void Polyline::extend_start(double distance)
{
// relocate first point by extending the first segment by the specified length
- this->points.front() = Line(this->points.front(), this->points[1]).point_at(-distance);
+ Vec2d v = (this->points.front() - this->points[1]).cast<double>().normalized();
+ this->points.front() += (v * distance).cast<coord_t>();
}
/* this method returns a collection of points picked on the polygon contour
so that they are evenly spaced according to the input distance */
-Points
-Polyline::equally_spaced_points(double distance) const
+Points Polyline::equally_spaced_points(double distance) const
{
Points points;
- points.push_back(this->first_point());
+ points.emplace_back(this->first_point());
double len = 0;
for (Points::const_iterator it = this->points.begin() + 1; it != this->points.end(); ++it) {
- double segment_length = it->distance_to(*(it-1));
+ Vec2d p1 = (it-1)->cast<double>();
+ Vec2d v = it->cast<double>() - p1;
+ double segment_length = v.norm();
len += segment_length;
- if (len < distance) continue;
-
+ if (len < distance)
+ continue;
if (len == distance) {
- points.push_back(*it);
+ points.emplace_back(*it);
len = 0;
continue;
}
-
double take = segment_length - (len - distance); // how much we take of this segment
- Line segment(*(it-1), *it);
- points.push_back(segment.point_at(take));
- --it;
- len = -take;
+ points.emplace_back((p1 + v * (take / v.norm())).cast<coord_t>());
+ -- it;
+ len = - take;
}
return points;
}
-void
-Polyline::simplify(double tolerance)
+void Polyline::simplify(double tolerance)
{
this->points = MultiPoint::_douglas_peucker(this->points, tolerance);
}
/* This method simplifies all *lines* contained in the supplied area */
template <class T>
-void
-Polyline::simplify_by_visibility(const T &area)
+void Polyline::simplify_by_visibility(const T &area)
{
Points &pp = this->points;
@@ -157,30 +147,29 @@ Polyline::simplify_by_visibility(const T &area)
template void Polyline::simplify_by_visibility<ExPolygon>(const ExPolygon &area);
template void Polyline::simplify_by_visibility<ExPolygonCollection>(const ExPolygonCollection &area);
-void
-Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
+void Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
{
if (this->points.empty()) return;
// find the line to split at
size_t line_idx = 0;
Point p = this->first_point();
- double min = point.distance_to(p);
+ double min = (p - point).cast<double>().norm();
Lines lines = this->lines();
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
Point p_tmp = point.projection_onto(*line);
- if (point.distance_to(p_tmp) < min) {
+ if ((p_tmp - point).cast<double>().norm() < min) {
p = p_tmp;
- min = point.distance_to(p);
+ min = (p - point).cast<double>().norm();
line_idx = line - lines.begin();
}
}
// create first half
p1->points.clear();
- for (Lines::const_iterator line = lines.begin(); line != lines.begin() + line_idx + 1; ++line) {
- if (!line->a.coincides_with(p)) p1->points.push_back(line->a);
- }
+ for (Lines::const_iterator line = lines.begin(); line != lines.begin() + line_idx + 1; ++line)
+ if (line->a != p)
+ p1->points.push_back(line->a);
// we add point instead of p because they might differ because of numerical issues
// and caller might want to rely on point belonging to result polylines
p1->points.push_back(point);
@@ -193,8 +182,7 @@ Polyline::split_at(const Point &point, Polyline* p1, Polyline* p2) const
}
}
-bool
-Polyline::is_straight() const
+bool Polyline::is_straight() const
{
/* Check that each segment's direction is equal to the line connecting
first point and last point. (Checking each line against the previous
@@ -208,19 +196,6 @@ Polyline::is_straight() const
return true;
}
-std::string
-Polyline::wkt() const
-{
- std::ostringstream wkt;
- wkt << "LINESTRING((";
- for (Points::const_iterator p = this->points.begin(); p != this->points.end(); ++p) {
- wkt << p->x << " " << p->y;
- if (p != this->points.end()-1) wkt << ",";
- }
- wkt << "))";
- return wkt.str();
-}
-
BoundingBox get_extents(const Polyline &polyline)
{
return polyline.bounding_box();
@@ -254,30 +229,17 @@ bool remove_degenerate(Polylines &polylines)
return modified;
}
-ThickLines
-ThickPolyline::thicklines() const
+ThickLines ThickPolyline::thicklines() const
{
ThickLines lines;
if (this->points.size() >= 2) {
lines.reserve(this->points.size() - 1);
- for (size_t i = 0; i < this->points.size()-1; ++i) {
- ThickLine line(this->points[i], this->points[i+1]);
- line.a_width = this->width[2*i];
- line.b_width = this->width[2*i+1];
- lines.push_back(line);
- }
+ for (size_t i = 0; i + 1 < this->points.size(); ++ i)
+ lines.emplace_back(this->points[i], this->points[i + 1], this->width[2 * i], this->width[2 * i + 1]);
}
return lines;
}
-void
-ThickPolyline::reverse()
-{
- Polyline::reverse();
- std::reverse(this->width.begin(), this->width.end());
- std::swap(this->endpoints.first, this->endpoints.second);
-}
-
Lines3 Polyline3::lines() const
{
Lines3 lines;
diff --git a/xs/src/libslic3r/Polyline.hpp b/xs/src/libslic3r/Polyline.hpp
index b64743d84..0c934e074 100644
--- a/xs/src/libslic3r/Polyline.hpp
+++ b/xs/src/libslic3r/Polyline.hpp
@@ -19,14 +19,15 @@ public:
Polyline() {};
Polyline(const Polyline &other) : MultiPoint(other.points) {}
Polyline(Polyline &&other) : MultiPoint(std::move(other.points)) {}
+ Polyline(std::initializer_list<Point> list) : MultiPoint(list) {}
+ explicit Polyline(const Point &p1, const Point &p2) { points.reserve(2); points.emplace_back(p1); points.emplace_back(p2); }
Polyline& operator=(const Polyline &other) { points = other.points; return *this; }
Polyline& operator=(Polyline &&other) { points = std::move(other.points); return *this; }
- static Polyline new_scale(std::vector<Pointf> points) {
+ static Polyline new_scale(const std::vector<Vec2d> &points) {
Polyline pl;
- Points int_points;
- for (auto pt : points)
- int_points.push_back(Point::new_scale(pt.x, pt.y));
- pl.append(int_points);
+ pl.points.reserve(points.size());
+ for (const Vec2d &pt : points)
+ pl.points.emplace_back(Point::new_scale(pt(0), pt(1)));
return pl;
}
@@ -71,7 +72,6 @@ public:
template <class T> void simplify_by_visibility(const T &area);
void split_at(const Point &point, Polyline* p1, Polyline* p2) const;
bool is_straight() const;
- std::string wkt() const;
};
extern BoundingBox get_extents(const Polyline &polyline);
@@ -129,12 +129,17 @@ inline void polylines_append(Polylines &dst, Polylines &&src)
bool remove_degenerate(Polylines &polylines);
class ThickPolyline : public Polyline {
- public:
- std::vector<coordf_t> width;
- std::pair<bool,bool> endpoints;
- ThickPolyline() : endpoints(std::make_pair(false, false)) {};
+public:
+ ThickPolyline() : endpoints(std::make_pair(false, false)) {}
ThickLines thicklines() const;
- void reverse();
+ void reverse() {
+ Polyline::reverse();
+ std::reverse(this->width.begin(), this->width.end());
+ std::swap(this->endpoints.first, this->endpoints.second);
+ }
+
+ std::vector<coordf_t> width;
+ std::pair<bool,bool> endpoints;
};
class Polyline3 : public MultiPoint3
diff --git a/xs/src/libslic3r/PolylineCollection.cpp b/xs/src/libslic3r/PolylineCollection.cpp
index ca9c64d23..3f65ea699 100644
--- a/xs/src/libslic3r/PolylineCollection.cpp
+++ b/xs/src/libslic3r/PolylineCollection.cpp
@@ -15,9 +15,9 @@ inline int nearest_point_index(const std::vector<Chaining> &pairs, const Point &
T dmin = std::numeric_limits<T>::max();
int idx = 0;
for (std::vector<Chaining>::const_iterator it = pairs.begin(); it != pairs.end(); ++it) {
- T d = sqr(T(start_near.x - it->first.x));
+ T d = sqr(T(start_near(0) - it->first(0)));
if (d <= dmin) {
- d += sqr(T(start_near.y - it->first.y));
+ d += sqr(T(start_near(1) - it->first(1)));
if (d < dmin) {
idx = (it - pairs.begin()) * 2;
dmin = d;
@@ -26,9 +26,9 @@ inline int nearest_point_index(const std::vector<Chaining> &pairs, const Point &
}
}
if (! no_reverse) {
- d = sqr(T(start_near.x - it->last.x));
+ d = sqr(T(start_near(0) - it->last(0)));
if (d <= dmin) {
- d += sqr(T(start_near.y - it->last.y));
+ d += sqr(T(start_near(1) - it->last(1)));
if (d < dmin) {
idx = (it - pairs.begin()) * 2 + 1;
dmin = d;
@@ -82,7 +82,7 @@ Point PolylineCollection::leftmost_point(const Polylines &polylines)
Point p = it->leftmost_point();
for (++ it; it != polylines.end(); ++it) {
Point p2 = it->leftmost_point();
- if (p2.x < p.x)
+ if (p2(0) < p(0))
p = p2;
}
return p;
diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp
index e8a010a79..ae02216df 100644
--- a/xs/src/libslic3r/Print.cpp
+++ b/xs/src/libslic3r/Print.cpp
@@ -4,6 +4,7 @@
#include "Extruder.hpp"
#include "Flow.hpp"
#include "Geometry.hpp"
+#include "I18N.hpp"
#include "SupportMaterial.hpp"
#include "GCode.hpp"
#include "GCode/WipeTowerPrusaMM.hpp"
@@ -13,6 +14,13 @@
#include <boost/lexical_cast.hpp>
#include <boost/log/trivial.hpp>
+//#include "slic3r/ProgressIndicator.hpp"
+#include "PrintExport.hpp"
+
+//! macro used to mark string used at localization,
+//! return same string
+#define L(s) Slic3r::I18N::translate(s)
+
namespace Slic3r {
template class PrintState<PrintStep, psCount>;
@@ -71,6 +79,13 @@ bool Print::reload_model_instances()
return invalidated;
}
+PrintObjectPtrs Print::get_printable_objects() const
+{
+ PrintObjectPtrs printable_objects(m_objects);
+ printable_objects.erase(std::remove_if(printable_objects.begin(), printable_objects.end(), [](PrintObject* o) { return !o->is_printable(); }), printable_objects.end());
+ return printable_objects;
+}
+
PrintRegion* Print::add_region()
{
m_regions.emplace_back(new PrintRegion(this));
@@ -127,7 +142,6 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"gcode_comments",
"gcode_flavor",
"infill_acceleration",
- "infill_first",
"layer_gcode",
"min_fan_speed",
"max_fan_speed",
@@ -154,6 +168,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"retract_restart_extra",
"retract_restart_extra_toolchange",
"retract_speed",
+ "single_extruder_multi_material_priming",
"slowdown_below_layer_time",
"standby_temperature_delta",
"start_gcode",
@@ -165,7 +180,10 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
"use_relative_e_distances",
"use_volumetric_e",
"variable_layer_height",
- "wipe"
+ "wipe",
+ "wipe_tower_x",
+ "wipe_tower_y",
+ "wipe_tower_rotation_angle"
};
static std::unordered_set<std::string> steps_ignore;
@@ -173,6 +191,7 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
std::vector<PrintStep> steps;
std::vector<PrintObjectStep> osteps;
bool invalidated = false;
+
for (const t_config_option_key &opt_key : opt_keys) {
if (steps_gcode.find(opt_key) != steps_gcode.end()) {
// These options only affect G-code export or they are just notes without influence on the generated G-code,
@@ -199,15 +218,29 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|| opt_key == "filament_type"
|| opt_key == "filament_soluble"
|| opt_key == "first_layer_temperature"
+ || opt_key == "filament_loading_speed"
+ || opt_key == "filament_loading_speed_start"
+ || opt_key == "filament_unloading_speed"
+ || opt_key == "filament_unloading_speed_start"
+ || opt_key == "filament_toolchange_delay"
+ || opt_key == "filament_cooling_moves"
+ || opt_key == "filament_minimal_purge_on_wipe_tower"
+ || opt_key == "filament_cooling_initial_speed"
+ || opt_key == "filament_cooling_final_speed"
+ || opt_key == "filament_ramming_parameters"
|| opt_key == "gcode_flavor"
+ || opt_key == "infill_first"
|| opt_key == "single_extruder_multi_material"
|| opt_key == "spiral_vase"
|| opt_key == "temperature"
|| opt_key == "wipe_tower"
- || opt_key == "wipe_tower_x"
- || opt_key == "wipe_tower_y"
|| opt_key == "wipe_tower_width"
- || opt_key == "wipe_tower_per_color_wipe"
+ || opt_key == "wipe_tower_bridging"
+ || opt_key == "wiping_volumes_matrix"
+ || opt_key == "parking_pos_retraction"
+ || opt_key == "cooling_tube_retraction"
+ || opt_key == "cooling_tube_length"
+ || opt_key == "extra_loading_move"
|| opt_key == "z_offset") {
steps.emplace_back(psWipeTower);
} else if (
@@ -219,7 +252,6 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
osteps.emplace_back(posSupportMaterial);
steps.emplace_back(psSkirt);
steps.emplace_back(psBrim);
- steps.emplace_back(psWipeTower);
} else {
// for legacy, if we can't handle this option let's invalidate all steps
//FIXME invalidate all steps of all objects as well?
@@ -361,7 +393,7 @@ void Print::add_model_object(ModelObject* model_object, int idx)
}
// If no region exists with the same config, create a new one.
if (region_id == size_t(-1)) {
- region_id = this->regions().size();
+ region_id = m_regions.size();
this->add_region(config);
}
// Assign volume to a region.
@@ -456,7 +488,7 @@ bool Print::apply_config(DynamicPrintConfig config)
const ModelVolume &volume = *object->model_object()->volumes[volume_id];
if (this_region_config_set) {
// If the new config for this volume differs from the other
- // volume configs currently associated to this region, it means
+ // volume configs currently associated to this region, it means
// the region subdivision does not make sense anymore.
if (! this_region_config.equals(this->_region_config_from_model_volume(volume))) {
rearrange_regions = true;
@@ -530,14 +562,20 @@ bool Print::has_skirt() const
std::string Print::validate() const
{
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(m_config.bed_shape.values));
- BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), m_config.max_print_height));
+ BoundingBoxf3 print_volume(unscale(bed_box_2D.min(0), bed_box_2D.min(1), 0.0), unscale(bed_box_2D.max(0), bed_box_2D.max(1), scale_(m_config.max_print_height)));
// Allow the objects to protrude below the print bed, only the part of the object above the print bed will be sliced.
- print_volume.min.z = -1e10;
+ print_volume.min(2) = -1e10;
+ unsigned int printable_count = 0;
for (PrintObject *po : m_objects) {
- if (! print_volume.contains(po->model_object()->tight_bounding_box(false)))
- return "Some objects are outside of the print volume.";
+ po->model_object()->check_instances_print_volume_state(print_volume);
+ po->reload_model_instances();
+ if (po->is_printable())
+ ++printable_count;
}
+ if (printable_count == 0)
+ return L("All objects are outside of the print volume.");
+
if (m_config.complete_objects) {
// Check horizontal clearance.
{
@@ -558,11 +596,11 @@ std::string Print::validate() const
// Grow convex hull with the clearance margin.
convex_hull = offset(convex_hull, scale_(m_config.extruder_clearance_radius.value)/2, jtRound, scale_(0.1)).front();
// Now we check that no instance of convex_hull intersects any of the previously checked object instances.
- for (const Point &copy : object->_shifted_copies) {
+ for (const Point &copy : object->m_copies) {
Polygon p = convex_hull;
p.translate(copy);
if (! intersection(convex_hulls_other, p).empty())
- return "Some objects are too close; your extruder will collide with them.";
+ return L("Some objects are too close; your extruder will collide with them.");
polygons_append(convex_hulls_other, p);
}
}
@@ -571,13 +609,13 @@ std::string Print::validate() const
{
std::vector<coord_t> object_height;
for (const PrintObject *object : m_objects)
- object_height.insert(object_height.end(), object->copies().size(), object->size.z);
+ object_height.insert(object_height.end(), object->copies().size(), object->size(2));
std::sort(object_height.begin(), object_height.end());
// Ignore the tallest *copy* (this is why we repeat height for all of them):
// it will be printed as last one so its height doesn't matter.
object_height.pop_back();
if (! object_height.empty() && object_height.back() > scale_(m_config.extruder_clearance_height.value))
- return "Some objects are too tall and cannot be printed without extruder collisions.";
+ return L("Some objects are too tall and cannot be printed without extruder collisions.");
}
} // end if (m_config.complete_objects)
@@ -587,40 +625,65 @@ std::string Print::validate() const
total_copies_count += object->copies().size();
// #4043
if (total_copies_count > 1 && ! m_config.complete_objects.value)
- return "The Spiral Vase option can only be used when printing a single object.";
+ return L("The Spiral Vase option can only be used when printing a single object.");
if (m_regions.size() > 1)
- return "The Spiral Vase option can only be used when printing single material objects.";
+ return L("The Spiral Vase option can only be used when printing single material objects.");
+ }
+
+ if (m_config.single_extruder_multi_material) {
+ for (size_t i=1; i<m_config.nozzle_diameter.values.size(); ++i)
+ if (m_config.nozzle_diameter.values[i] != m_config.nozzle_diameter.values[i-1])
+ return L("All extruders must have the same diameter for single extruder multimaterial printer.");
}
if (this->has_wipe_tower() && ! m_objects.empty()) {
- #if 0
- for (auto dmr : m_config.nozzle_diameter.values)
- if (std::abs(dmr - 0.4) > EPSILON)
- return "The Wipe Tower is currently only supported for the 0.4mm nozzle diameter.";
- #endif
if (m_config.gcode_flavor != gcfRepRap && m_config.gcode_flavor != gcfMarlin)
- return "The Wipe Tower is currently only supported for the Marlin and RepRap/Sprinter G-code flavors.";
+ return L("The Wipe Tower is currently only supported for the Marlin and RepRap/Sprinter G-code flavors.");
if (! m_config.use_relative_e_distances)
- return "The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1).";
+ return L("The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1).");
SlicingParameters slicing_params0 = m_objects.front()->slicing_parameters();
+
+ const PrintObject* tallest_object = m_objects.front(); // let's find the tallest object
+ for (const auto* object : m_objects)
+ if (*(object->layer_height_profile.end()-2) > *(tallest_object->layer_height_profile.end()-2) )
+ tallest_object = object;
+
for (PrintObject *object : m_objects) {
SlicingParameters slicing_params = object->slicing_parameters();
if (std::abs(slicing_params.first_print_layer_height - slicing_params0.first_print_layer_height) > EPSILON ||
std::abs(slicing_params.layer_height - slicing_params0.layer_height ) > EPSILON)
- return "The Wipe Tower is only supported for multiple objects if they have equal layer heigths";
+ return L("The Wipe Tower is only supported for multiple objects if they have equal layer heigths");
if (slicing_params.raft_layers() != slicing_params0.raft_layers())
- return "The Wipe Tower is only supported for multiple objects if they are printed over an equal number of raft layers";
+ return L("The Wipe Tower is only supported for multiple objects if they are printed over an equal number of raft layers");
if (object->config().support_material_contact_distance != m_objects.front()->config().support_material_contact_distance)
- return "The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance";
+ return L("The Wipe Tower is only supported for multiple objects if they are printed with the same support_material_contact_distance");
if (! equal_layering(slicing_params, slicing_params0))
- return "The Wipe Tower is only supported for multiple objects if they are sliced equally.";
+ return L("The Wipe Tower is only supported for multiple objects if they are sliced equally.");
bool was_layer_height_profile_valid = object->layer_height_profile_valid;
object->update_layer_height_profile();
object->layer_height_profile_valid = was_layer_height_profile_valid;
- for (size_t i = 5; i < object->layer_height_profile.size(); i += 2)
- if (object->layer_height_profile[i-1] > slicing_params.object_print_z_min + EPSILON &&
- std::abs(object->layer_height_profile[i] - object->config().layer_height) > EPSILON)
- return "The Wipe Tower is currently only supported with constant Z layer spacing. Layer editing is not allowed.";
+
+ if ( m_config.variable_layer_height ) { // comparing layer height profiles
+ bool failed = false;
+ if (tallest_object->layer_height_profile.size() >= object->layer_height_profile.size() ) {
+ int i = 0;
+ while ( i < object->layer_height_profile.size() && i < tallest_object->layer_height_profile.size()) {
+ if (std::abs(tallest_object->layer_height_profile[i] - object->layer_height_profile[i])) {
+ failed = true;
+ break;
+ }
+ ++i;
+ if (i == object->layer_height_profile.size()-2) // this element contains this objects max z
+ if (tallest_object->layer_height_profile[i] > object->layer_height_profile[i]) // the difference does not matter in this case
+ ++i;
+ }
+ }
+ else
+ failed = true;
+
+ if (failed)
+ return L("The Wipe tower is only supported if all objects have the same layer height profile");
+ }
}
}
@@ -628,13 +691,17 @@ std::string Print::validate() const
// find the smallest nozzle diameter
std::vector<unsigned int> extruders = this->extruders();
if (extruders.empty())
- return "The supplied settings will cause an empty print.";
+ return L("The supplied settings will cause an empty print.");
std::vector<double> nozzle_diameters;
for (unsigned int extruder_id : extruders)
nozzle_diameters.push_back(m_config.nozzle_diameter.get_at(extruder_id));
double min_nozzle_diameter = *std::min_element(nozzle_diameters.begin(), nozzle_diameters.end());
-
+ unsigned int total_extruders_count = m_config.nozzle_diameter.size();
+ for (const auto& extruder_idx : extruders)
+ if ( extruder_idx >= total_extruders_count )
+ return L("One or more object were assigned an extruder that the printer does not have.");
+
for (PrintObject *object : m_objects) {
if ((object->config().support_material_extruder == -1 || object->config().support_material_interface_extruder == -1) &&
(object->config().raft_layers > 0 || object->config().support_material.value)) {
@@ -642,13 +709,13 @@ std::string Print::validate() const
// will be printed with the current tool without a forced tool change. Play safe, assert that all object nozzles
// are of the same diameter.
if (nozzle_diameters.size() > 1)
- return "Printing with multiple extruders of differing nozzle diameters. "
+ return L("Printing with multiple extruders of differing nozzle diameters. "
"If support is to be printed with the current extruder (support_material_extruder == 0 or support_material_interface_extruder == 0), "
- "all nozzles have to be of the same diameter.";
+ "all nozzles have to be of the same diameter.");
}
// validate first_layer_height
- double first_layer_height = object->config().get_abs_value("first_layer_height");
+ double first_layer_height = object->config().get_abs_value(L("first_layer_height"));
double first_layer_min_nozzle_diameter;
if (object->config().raft_layers > 0) {
// if we have raft layers, only support material extruder is used on first layer
@@ -663,11 +730,11 @@ std::string Print::validate() const
first_layer_min_nozzle_diameter = min_nozzle_diameter;
}
if (first_layer_height > first_layer_min_nozzle_diameter)
- return "First layer height can't be greater than nozzle diameter";
+ return L("First layer height can't be greater than nozzle diameter");
// validate layer_height
if (object->config().layer_height.value > min_nozzle_diameter)
- return "Layer height can't be greater than nozzle diameter";
+ return L("Layer height can't be greater than nozzle diameter");
}
}
@@ -680,9 +747,9 @@ BoundingBox Print::bounding_box() const
{
BoundingBox bb;
for (const PrintObject *object : m_objects)
- for (Point copy : object->_shifted_copies) {
+ for (Point copy : object->m_copies) {
bb.merge(copy);
- copy.translate(object->size);
+ copy += to_2d(object->size);
bb.merge(copy);
}
return bb;
@@ -897,8 +964,9 @@ void Print::_make_skirt()
// prepended to the first 'n' layers (with 'n' = skirt_height).
// $skirt_height_z in this case is the highest possible skirt height for safety.
coordf_t skirt_height_z = 0.;
- for (const PrintObject *object : m_objects) {
- size_t skirt_layers = this->has_infinite_skirt() ?
+ PrintObjectPtrs printable_objects = get_printable_objects();
+ for (const PrintObject *object : printable_objects) {
+ size_t skirt_layers = this->has_infinite_skirt() ?
object->layer_count() :
std::min(size_t(m_config.skirt_height.value), object->layer_count());
skirt_height_z = std::max(skirt_height_z, object->m_layers[skirt_layers-1]->print_z);
@@ -906,8 +974,7 @@ void Print::_make_skirt()
// Collect points from all layers contained in skirt height.
Points points;
- for (const PrintObject *object : m_objects) {
- this->throw_if_canceled();
+ for (const PrintObject *object : printable_objects) {
Points object_points;
// Get object layers up to skirt_height_z.
for (const Layer *layer : object->m_layers) {
@@ -925,10 +992,10 @@ void Print::_make_skirt()
append(object_points, extrusion_entity->as_polyline().points);
}
// Repeat points for each object copy.
- for (const Point &shift : object->_shifted_copies) {
+ for (const Point &shift : object->m_copies) {
Points copy_points = object_points;
for (Point &pt : copy_points)
- pt.translate(shift);
+ pt += shift;
append(points, copy_points);
}
}
@@ -967,7 +1034,9 @@ void Print::_make_skirt()
// Initial offset of the brim inner edge from the object (possible with a support & raft).
// The skirt will touch the brim if the brim is extruded.
- coord_t distance = scale_(std::max(m_config.skirt_distance.value, m_config.brim_width.value));
+ Flow brim_flow = this->brim_flow();
+ double actual_brim_width = brim_flow.spacing() * floor(m_config.brim_width.value / brim_flow.spacing());
+ coord_t distance = scale_(std::max(m_config.skirt_distance.value, actual_brim_width) - spacing/2.);
// Draw outlines from outside to inside.
// Loop while we have less skirts than required or any extruder hasn't reached the min length if any.
std::vector<coordf_t> extruded_length(extruders.size(), 0.);
@@ -995,7 +1064,7 @@ void Print::_make_skirt()
m_skirt.append(eloop);
if (m_config.min_skirt_length.value > 0) {
// The skirt length is limited. Sum the total amount of filament length extruded, in mm.
- extruded_length[extruder_idx] += unscale(loop.length()) * extruders_e_per_mm[extruder_idx];
+ extruded_length[extruder_idx] += unscale<double>(loop.length()) * extruders_e_per_mm[extruder_idx];
if (extruded_length[extruder_idx] < m_config.min_skirt_length.value) {
// Not extruded enough yet with the current extruder. Add another loop.
if (i == 1)
@@ -1020,22 +1089,22 @@ void Print::_make_brim()
// Brim is only printed on first layer and uses perimeter extruder.
Flow flow = this->brim_flow();
Polygons islands;
- for (PrintObject *object : m_objects) {
- this->throw_if_canceled();
+ PrintObjectPtrs printable_objects = get_printable_objects();
+ for (PrintObject *object : printable_objects) {
Polygons object_islands;
for (ExPolygon &expoly : object->m_layers.front()->slices.expolygons)
object_islands.push_back(expoly.contour);
if (! object->support_layers().empty())
object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
- islands.reserve(islands.size() + object_islands.size() * object->_shifted_copies.size());
- for (const Point &pt : object->_shifted_copies)
+ islands.reserve(islands.size() + object_islands.size() * object->m_copies.size());
+ for (const Point &pt : object->m_copies)
for (Polygon &poly : object_islands) {
islands.push_back(poly);
islands.back().translate(pt);
}
}
Polygons loops;
- size_t num_loops = size_t(floor(m_config.brim_width.value / flow.width));
+ size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing()));
for (size_t i = 0; i < num_loops; ++ i) {
this->throw_if_canceled();
islands = offset(islands, float(flow.scaled_spacing()), jtSquare);
@@ -1066,6 +1135,18 @@ bool Print::has_wipe_tower() const
void Print::_make_wipe_tower()
{
+ m_wipe_tower_data.clear();
+ if (! this->has_wipe_tower())
+ return;
+
+ // Get wiping matrix to get number of extruders and convert vector<double> to vector<float>:
+ std::vector<float> wiping_matrix(cast<float>(m_config.wiping_volumes_matrix.values));
+ // Extract purging volumes for each extruder pair:
+ std::vector<std::vector<float>> wipe_volumes;
+ const unsigned int number_of_extruders = (unsigned int)(sqrt(wiping_matrix.size())+EPSILON);
+ for (unsigned int i = 0; i<number_of_extruders; ++i)
+ wipe_volumes.push_back(std::vector<float>(wiping_matrix.begin()+i*number_of_extruders, wiping_matrix.begin()+(i+1)*number_of_extruders));
+
// Let the ToolOrdering class know there will be initial priming extrusions at the start of the print.
m_wipe_tower_data.tool_ordering = ToolOrdering(*this, (unsigned int)-1, true);
if (! m_wipe_tower_data.tool_ordering.has_wipe_tower())
@@ -1081,7 +1162,7 @@ void Print::_make_wipe_tower()
size_t idx_end = m_wipe_tower_data.tool_ordering.layer_tools().size();
// Find the first wipe tower layer, which does not have a counterpart in an object or a support layer.
for (size_t i = 0; i < idx_end; ++ i) {
- const ToolOrdering::LayerTools &lt = m_wipe_tower_data.tool_ordering.layer_tools()[i];
+ const LayerTools &lt = m_wipe_tower_data.tool_ordering.layer_tools()[i];
if (lt.has_wipe_tower && ! lt.has_object && ! lt.has_support) {
idx_begin = i;
break;
@@ -1095,7 +1176,7 @@ void Print::_make_wipe_tower()
for (; it_layer != it_end && (*it_layer)->print_z - EPSILON < wipe_tower_new_layer_print_z_first; ++ it_layer);
// Find the stopper of the sequence of wipe tower layers, which do not have a counterpart in an object or a support layer.
for (size_t i = idx_begin; i < idx_end; ++ i) {
- ToolOrdering::LayerTools &lt = const_cast<ToolOrdering::LayerTools&>(m_wipe_tower_data.tool_ordering.layer_tools()[i]);
+ LayerTools &lt = const_cast<LayerTools&>(m_wipe_tower_data.tool_ordering.layer_tools()[i]);
if (! (lt.has_wipe_tower && ! lt.has_object && ! lt.has_support))
break;
lt.has_support = true;
@@ -1112,78 +1193,73 @@ void Print::_make_wipe_tower()
// Initialize the wipe tower.
WipeTowerPrusaMM wipe_tower(
float(m_config.wipe_tower_x.value), float(m_config.wipe_tower_y.value),
- float(m_config.wipe_tower_width.value), float(m_config.wipe_tower_per_color_wipe.value),
+ float(m_config.wipe_tower_width.value),
+ float(m_config.wipe_tower_rotation_angle.value), float(m_config.cooling_tube_retraction.value),
+ float(m_config.cooling_tube_length.value), float(m_config.parking_pos_retraction.value),
+ float(m_config.extra_loading_move.value), float(m_config.wipe_tower_bridging), wipe_volumes,
m_wipe_tower_data.tool_ordering.first_extruder());
-
+
//wipe_tower.set_retract();
//wipe_tower.set_zhop();
// Set the extruder & material properties at the wipe tower object.
- for (size_t i = 0; i < 4; ++ i)
+ for (size_t i = 0; i < number_of_extruders; ++ i)
wipe_tower.set_extruder(
i,
WipeTowerPrusaMM::parse_material(m_config.filament_type.get_at(i).c_str()),
m_config.temperature.get_at(i),
- m_config.first_layer_temperature.get_at(i));
-
- // When printing the first layer's wipe tower, the first extruder is expected to be active and primed.
- // Therefore the number of wipe sections at the wipe tower will be (m_wipe_tower_data.tool_ordering.front().extruders-1) at the 1st layer.
- // The following variable is true if the last priming section cannot be squeezed inside the wipe tower.
- bool last_priming_wipe_full = m_wipe_tower_data.tool_ordering.front().extruders.size() > m_wipe_tower_data.tool_ordering.front().wipe_tower_partitions;
+ m_config.first_layer_temperature.get_at(i),
+ m_config.filament_loading_speed.get_at(i),
+ m_config.filament_loading_speed_start.get_at(i),
+ m_config.filament_unloading_speed.get_at(i),
+ m_config.filament_unloading_speed_start.get_at(i),
+ m_config.filament_toolchange_delay.get_at(i),
+ m_config.filament_cooling_moves.get_at(i),
+ m_config.filament_cooling_initial_speed.get_at(i),
+ m_config.filament_cooling_final_speed.get_at(i),
+ m_config.filament_ramming_parameters.get_at(i),
+ m_config.nozzle_diameter.get_at(i));
m_wipe_tower_data.priming = Slic3r::make_unique<WipeTower::ToolChangeResult>(
- wipe_tower.prime(this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), ! last_priming_wipe_full, WipeTower::PURPOSE_EXTRUDE));
+ wipe_tower.prime(this->skirt_first_layer_height(), m_wipe_tower_data.tool_ordering.all_extruders(), false));
- // Generate the wipe tower layers.
- m_wipe_tower_data.tool_changes.reserve(m_wipe_tower_data.tool_ordering.layer_tools().size());
- // Set current_extruder_id to the last extruder primed.
- unsigned int current_extruder_id = m_wipe_tower_data.tool_ordering.all_extruders().back();
- for (const ToolOrdering::LayerTools &layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) {
- this->throw_if_canceled();
- if (! layer_tools.has_wipe_tower)
- // This is a support only layer, or the wipe tower does not reach to this height.
- continue;
- bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
- bool last_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0;
- wipe_tower.set_layer(
- float(layer_tools.print_z),
- float(layer_tools.wipe_tower_layer_height),
- layer_tools.wipe_tower_partitions,
- first_layer,
- last_layer);
- std::vector<WipeTower::ToolChangeResult> tool_changes;
- for (unsigned int extruder_id : layer_tools.extruders)
- // Call the wipe_tower.tool_change() at the first layer for the initial extruder
- // to extrude the wipe tower brim,
- if ((first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) ||
- // or when an extruder shall be switched.
- extruder_id != current_extruder_id) {
- tool_changes.emplace_back(wipe_tower.tool_change(extruder_id, extruder_id == layer_tools.extruders.back(), WipeTower::PURPOSE_EXTRUDE));
- current_extruder_id = extruder_id;
- }
- if (! wipe_tower.layer_finished()) {
- tool_changes.emplace_back(wipe_tower.finish_layer(WipeTower::PURPOSE_EXTRUDE));
- if (tool_changes.size() > 1) {
- // Merge the two last tool changes into one.
- WipeTower::ToolChangeResult &tc1 = tool_changes[tool_changes.size() - 2];
- WipeTower::ToolChangeResult &tc2 = tool_changes.back();
- if (tc1.end_pos != tc2.start_pos) {
- // Add a travel move from tc1.end_pos to tc2.start_pos.
- char buf[2048];
- sprintf(buf, "G1 X%.3f Y%.3f F7200\n", tc2.start_pos.x, tc2.start_pos.y);
- tc1.gcode += buf;
+ // Lets go through the wipe tower layers and determine pairs of extruder changes for each
+ // to pass to wipe_tower (so that it can use it for planning the layout of the tower)
+ {
+ unsigned int current_extruder_id = m_wipe_tower_data.tool_ordering.all_extruders().back();
+ for (auto &layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers
+ if (!layer_tools.has_wipe_tower) continue;
+ bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front();
+ wipe_tower.plan_toolchange(layer_tools.print_z, layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id,false);
+ for (const auto extruder_id : layer_tools.extruders) {
+ if ((first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) || extruder_id != current_extruder_id) {
+ float volume_to_wipe = wipe_volumes[current_extruder_id][extruder_id]; // total volume to wipe after this toolchange
+ // Not all of that can be used for infill purging:
+ volume_to_wipe -= m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
+
+ // try to assign some infills/objects for the wiping:
+ volume_to_wipe = layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_extruder_id, extruder_id, volume_to_wipe);
+
+ // add back the minimal amount toforce on the wipe tower:
+ volume_to_wipe += m_config.filament_minimal_purge_on_wipe_tower.get_at(extruder_id);
+
+ // request a toolchange at the wipe tower with at least volume_to_wipe purging amount
+ wipe_tower.plan_toolchange(layer_tools.print_z, layer_tools.wipe_tower_layer_height, current_extruder_id, extruder_id,
+ first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back(), volume_to_wipe);
+ current_extruder_id = extruder_id;
}
- tc1.gcode += tc2.gcode;
- append(tc1.extrusions, tc2.extrusions);
- tc1.end_pos = tc2.end_pos;
- tool_changes.pop_back();
}
+ layer_tools.wiping_extrusions().ensure_perimeters_infills_order(*this);
+ if (&layer_tools == &m_wipe_tower_data.tool_ordering.back() || (&layer_tools + 1)->wipe_tower_partitions == 0)
+ break;
}
- m_wipe_tower_data.tool_changes.emplace_back(std::move(tool_changes));
- if (last_layer)
- break;
}
-
+
+ // Generate the wipe tower layers.
+ m_wipe_tower_data.tool_changes.reserve(m_wipe_tower_data.tool_ordering.layer_tools().size());
+ wipe_tower.generate(m_wipe_tower_data.tool_changes);
+ m_wipe_tower_data.depth = wipe_tower.get_depth();
+
// Unload the current filament over the purge tower.
coordf_t layer_height = m_objects.front()->config().layer_height.value;
if (m_wipe_tower_data.tool_ordering.back().wipe_tower_partitions > 0) {
@@ -1201,7 +1277,7 @@ void Print::_make_wipe_tower()
wipe_tower.set_layer(float(m_wipe_tower_data.tool_ordering.back().print_z), float(layer_height), 0, false, true);
}
m_wipe_tower_data.final_purge = Slic3r::make_unique<WipeTower::ToolChangeResult>(
- wipe_tower.tool_change((unsigned int)-1, false, WipeTower::PURPOSE_EXTRUDE));
+ wipe_tower.tool_change((unsigned int)-1, false));
}
std::string Print::output_filename() const
@@ -1211,7 +1287,7 @@ std::string Print::output_filename() const
try {
return this->placeholder_parser().process(m_config.output_filename_format.value, 0, &cfg_timestamp);
} catch (std::runtime_error &err) {
- throw std::runtime_error(std::string("Failed processing of the output_filename_format template.\n") + err.what());
+ throw std::runtime_error(L("Failed processing of the output_filename_format template.") + "\n" + err.what());
}
}
@@ -1238,4 +1314,24 @@ std::string Print::output_filepath(const std::string &path) const
return path;
}
+void Print::print_to_png(const std::string &dirpath)
+{
+ print_to<FilePrinterFormat::PNG>(*this,
+ dirpath,
+ float(m_config.bed_size_x.value),
+ float(m_config.bed_size_y.value),
+ int(m_config.pixel_width.value),
+ int(m_config.pixel_height.value),
+ float(m_config.exp_time.value),
+ float(m_config.exp_time_first.value));
+}
+
+// Returns extruder this eec should be printed with, according to PrintRegion config
+int Print::get_extruder(const ExtrusionEntityCollection& fill, const PrintRegion &region)
+{
+ return is_infill(fill.role()) ? std::max<int>(0, (is_solid_infill(fill.entities.front()->role()) ? region.config().solid_infill_extruder : region.config().infill_extruder) - 1) :
+ std::max<int>(region.config().perimeter_extruder.value - 1, 0);
}
+
+} // namespace Slic3r
+
diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp
index 71711b31e..d72c1fef5 100644
--- a/xs/src/libslic3r/Print.hpp
+++ b/xs/src/libslic3r/Print.hpp
@@ -158,31 +158,23 @@ class PrintObject
public:
// vector of (vectors of volume ids), indexed by region_id
std::vector<std::vector<int>> region_volumes;
- t_layer_height_ranges layer_height_ranges;
+ t_layer_height_ranges layer_height_ranges;
// Profile of increasing z to a layer height, to be linearly interpolated when calculating the layers.
// The pairs of <z, layer_height> are packed into a 1D array to simplify handling by the Perl XS.
// layer_height_profile must not be set by the background thread.
- std::vector<coordf_t> layer_height_profile;
+ std::vector<coordf_t> layer_height_profile;
// There is a layer_height_profile at both PrintObject and ModelObject. The layer_height_profile at the ModelObject
// is used for interactive editing and for loading / storing into a project file (AMF file as of today).
// This flag indicates that the layer_height_profile at the UI has been updated, therefore the backend needs to get it.
// This flag is necessary as we cannot safely clear the layer_height_profile if the background calculation is running.
- bool layer_height_profile_valid;
+ bool layer_height_profile_valid;
// this is set to true when LayerRegion->slices is split in top/internal/bottom
// so that next call to make_perimeters() performs a union() before computing loops
- bool typed_slices;
+ bool typed_slices;
- Point3 size; // XYZ in scaled coordinates
-
- // scaled coordinates to add to copies (to compensate for the alignment
- // operated when creating the object but still preserving a coherent API
- // for external callers)
- Point _copies_shift;
-
- // Slic3r::Point objects in scaled G-code coordinates in our coordinates
- Points _shifted_copies;
+ Vec3crd size; // XYZ in scaled coordinates
Print* print() { return m_print; }
const Print* print() const { return m_print; }
@@ -195,13 +187,13 @@ public:
const SupportLayerPtrs& support_layers() const { return m_support_layers; }
const Points& copies() const { return m_copies; }
- bool add_copy(const Pointf &point);
+ bool add_copy(const Vec2d &point);
bool delete_last_copy();
bool delete_all_copies() { return this->set_copies(Points()); }
bool set_copies(const Points &points);
bool reload_model_instances();
// since the object is aligned to origin, bounding box coincides with size
- BoundingBox bounding_box() const { return BoundingBox(Point(0,0), this->size); }
+ BoundingBox bounding_box() const { return BoundingBox(Point(0,0), to_2d(this->size)); }
// adds region_id, too, if necessary
void add_region_volume(unsigned int region_id, int volume_id) {
@@ -244,6 +236,8 @@ public:
void reset_layer_height_profile();
+ void adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action);
+
// Collect the slicing parameters, to be used by variable layer thickness algorithm,
// by the interactive layer height editor and by the printing process itself.
// The slicing parameters are dependent on various configuration values
@@ -262,6 +256,7 @@ private:
void _slice();
std::string _fix_slicing_errors();
void _simplify_slices(double distance);
+ void _make_perimeters();
bool has_support_material() const;
void detect_surfaces_type();
void process_external_surfaces();
@@ -272,11 +267,17 @@ private:
void combine_infill();
void _generate_support_material();
+ bool is_printable() const { return ! m_copies.empty(); }
+
Print *m_print;
ModelObject *m_model_object;
PrintObjectConfig m_config;
// Slic3r::Point objects in scaled G-code coordinates
Points m_copies;
+ // scaled coordinates to add to copies (to compensate for the alignment
+ // operated when creating the object but still preserving a coherent API
+ // for external callers)
+ Point m_copies_shift;
LayerPtrs m_layers;
SupportLayerPtrs m_support_layers;
@@ -308,18 +309,23 @@ struct WipeTowerData
std::vector<std::vector<WipeTower::ToolChangeResult>> tool_changes;
std::unique_ptr<WipeTower::ToolChangeResult> final_purge;
+ // Depth of the wipe tower to pass to GLCanvas3D for exact bounding box:
+ float depth;
+
void clear() {
tool_ordering.clear();
priming.reset(nullptr);
tool_changes.clear();
final_purge.reset(nullptr);
+ depth = 0.f;
}
};
struct PrintStatistics
{
PrintStatistics() { clear(); }
- std::string estimated_print_time;
+ std::string estimated_normal_print_time;
+ std::string estimated_silent_print_time;
double total_used_filament;
double total_extruded_volume;
double total_cost;
@@ -327,11 +333,12 @@ struct PrintStatistics
std::map<size_t, float> filament_stats;
void clear() {
- estimated_print_time.clear();
+ estimated_normal_print_time.clear();
+ estimated_silent_print_time.clear();
total_used_filament = 0.;
total_extruded_volume = 0.;
- total_weight = 0.;
total_cost = 0.;
+ total_weight = 0.;
filament_stats.clear();
}
};
@@ -345,7 +352,7 @@ class Print
public:
Print() { restart(); }
~Print() { clear_objects(); }
-
+
// Methods, which change the state of Print / PrintObject / PrintRegion.
// The following methods are synchronized with process() and export_gcode(),
// so that process() and export_gcode() may be called from a background thread.
@@ -359,6 +366,8 @@ public:
bool apply_config(DynamicPrintConfig config);
void process();
void export_gcode(const std::string &path_template, GCodePreviewData *preview_data);
+ // SLA export, temporary.
+ void print_to_png(const std::string &dirpath);
// methods for handling state
bool is_step_done(PrintStep step) const { return m_state.is_done(step); }
@@ -366,6 +375,9 @@ public:
bool has_infinite_skirt() const;
bool has_skirt() const;
+ PrintObjectPtrs get_printable_objects() const;
+ float get_wipe_tower_depth() const { return m_wipe_tower_data.depth; }
+
// Returns an empty string if valid, otherwise returns an error message.
std::string validate() const;
BoundingBox bounding_box() const;
@@ -386,9 +398,13 @@ public:
const PrintObjectConfig& default_object_config() const { return m_default_object_config; }
const PrintRegionConfig& default_region_config() const { return m_default_region_config; }
const PrintObjectPtrs& objects() const { return m_objects; }
+ const PrintObject* get_object(int idx) const { return m_objects[idx]; }
const PrintRegionPtrs& regions() const { return m_regions; }
const PlaceholderParser& placeholder_parser() const { return m_placeholder_parser; }
+ // Returns extruder this eec should be printed with, according to PrintRegion config:
+ static int get_extruder(const ExtrusionEntityCollection& fill, const PrintRegion &region);
+
const ExtrusionEntityCollection& skirt() const { return m_skirt; }
const ExtrusionEntityCollection& brim() const { return m_brim; }
@@ -458,6 +474,7 @@ private:
// The mutex will be used to guard the worker thread against entering a stage
// while the data influencing the stage is modified.
tbb::mutex m_mutex;
+
// Has the calculation been canceled?
tbb::atomic<bool> m_canceled;
// Callback to be evoked regularly to update state of the UI thread.
@@ -489,6 +506,7 @@ private:
friend class PrintObject;
};
+
#define FOREACH_BASE(type, container, iterator) for (type::const_iterator iterator = (container).begin(); iterator != (container).end(); ++iterator)
#define FOREACH_OBJECT(print, object) FOREACH_BASE(PrintObjectPtrs, (print)->m_objects, object)
#define FOREACH_LAYER(object, layer) FOREACH_BASE(LayerPtrs, (object)->m_layers, layer)
diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp
index 298fe9207..a3e84a356 100644
--- a/xs/src/libslic3r/PrintConfig.cpp
+++ b/xs/src/libslic3r/PrintConfig.cpp
@@ -1,7 +1,10 @@
#include "PrintConfig.hpp"
+#include "I18N.hpp"
#include <set>
#include <boost/algorithm/string/replace.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
+#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
@@ -11,12 +14,54 @@ namespace Slic3r {
//! macro used to mark string used at localization,
//! return same string
-#define L(s) s
+#define L(s) Slic3r::I18N::translate(s)
PrintConfigDef::PrintConfigDef()
{
+ this->init_common_params();
+ this->init_fff_params();
+ this->init_sla_params();
+}
+
+void PrintConfigDef::init_common_params()
+{
t_optiondef_map &Options = this->options;
+ ConfigOptionDef* def;
+
+ def = this->add("printer_technology", coEnum);
+ def->label = L("Printer technology");
+ def->tooltip = L("Printer technology");
+ def->cli = "printer-technology=s";
+ def->enum_keys_map = &ConfigOptionEnum<PrinterTechnology>::get_enum_values();
+ def->enum_values.push_back("FFF");
+ def->enum_values.push_back("SLA");
+ def->default_value = new ConfigOptionEnum<PrinterTechnology>(ptFFF);
+
+ def = this->add("bed_shape", coPoints);
+ def->label = L("Bed shape");
+ def->default_value = new ConfigOptionPoints{ Vec2d(0, 0), Vec2d(200, 0), Vec2d(200, 200), Vec2d(0, 200) };
+ def = this->add("layer_height", coFloat);
+ def->label = L("Layer height");
+ def->category = L("Layers and Perimeters");
+ def->tooltip = L("This setting controls the height (and thus the total number) of the slices/layers. "
+ "Thinner layers give better accuracy but take more time to print.");
+ def->sidetext = L("mm");
+ def->cli = "layer-height=f";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloat(0.3);
+
+ def = this->add("max_print_height", coFloat);
+ def->label = L("Max print height");
+ def->tooltip = L("Set this to the maximum height that can be reached by your extruder while printing.");
+ def->sidetext = L("mm");
+ def->cli = "max-print-height=f";
+ def->default_value = new ConfigOptionFloat(200.0);
+}
+
+void PrintConfigDef::init_fff_params()
+{
+ t_optiondef_map &Options = this->options;
ConfigOptionDef* def;
// Maximum extruder temperature, bumped to 1500 to support printing of glass.
@@ -30,10 +75,6 @@ PrintConfigDef::PrintConfigDef()
def->cli = "avoid-crossing-perimeters!";
def->default_value = new ConfigOptionBool(false);
- def = this->add("bed_shape", coPoints);
- def->label = L("Bed shape");
- def->default_value = new ConfigOptionPoints { Pointf(0,0), Pointf(200,0), Pointf(200,200), Pointf(0,200) };
-
def = this->add("bed_temperature", coInts);
def->label = L("Other layers");
def->tooltip = L("Bed temperature for layers after the first one. "
@@ -111,8 +152,8 @@ PrintConfigDef::PrintConfigDef()
"with cooling (use a fan) before tweaking this.");
def->cli = "bridge-flow-ratio=f";
def->min = 0;
- def->max = 2;
- def->default_value = new ConfigOptionFloat(1);
+ def->max = 2;
+ def->default_value = new ConfigOptionFloat(1);
def = this->add("bridge_speed", coFloat);
def->label = L("Bridges");
@@ -151,6 +192,11 @@ PrintConfigDef::PrintConfigDef()
"with the active printer profile.");
def->default_value = new ConfigOptionString();
+ // The following value is to be stored into the project file (AMF, 3MF, Config ...)
+ // and it contains a sum of "compatible_printers_condition" values over the print and filament profiles.
+ def = this->add("compatible_printers_condition_cummulative", coStrings);
+ def->default_value = new ConfigOptionStrings();
+
def = this->add("complete_objects", coBool);
def->label = L("Complete individual objects");
def->tooltip = L("When printing multiple objects or copies, this feature will complete "
@@ -167,6 +213,22 @@ PrintConfigDef::PrintConfigDef()
def->cli = "cooling!";
def->default_value = new ConfigOptionBools { true };
+ def = this->add("cooling_tube_retraction", coFloat);
+ def->label = L("Cooling tube position");
+ def->tooltip = L("Distance of the center-point of the cooling tube from the extruder tip ");
+ def->sidetext = L("mm");
+ def->cli = "cooling_tube_retraction=f";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloat(91.5f);
+
+ def = this->add("cooling_tube_length", coFloat);
+ def->label = L("Cooling tube length");
+ def->tooltip = L("Length of the cooling tube to limit space for cooling moves inside it ");
+ def->sidetext = L("mm");
+ def->cli = "cooling_tube_length=f";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloat(5.f);
+
def = this->add("default_acceleration", coFloat);
def->label = L("Default");
def->tooltip = L("This is the acceleration your printer will be reset to after "
@@ -177,6 +239,18 @@ PrintConfigDef::PrintConfigDef()
def->min = 0;
def->default_value = new ConfigOptionFloat(0);
+ def = this->add("default_filament_profile", coStrings);
+ def->label = L("Default filament profile");
+ def->tooltip = L("Default filament profile associated with the current printer profile. "
+ "On selection of the current printer profile, this filament profile will be activated.");
+ def->default_value = new ConfigOptionStrings();
+
+ def = this->add("default_print_profile", coString);
+ def->label = L("Default print profile");
+ def->tooltip = L("Default print profile associated with the current printer profile. "
+ "On selection of the current printer profile, this print profile will be activated.");
+ def->default_value = new ConfigOptionString();
+
def = this->add("disable_fan_first_layers", coInts);
def->label = L("Disable fan for the first");
def->tooltip = L("You can set this to a positive value to disable fan at all "
@@ -255,11 +329,11 @@ PrintConfigDef::PrintConfigDef()
def->enum_values.push_back("hilbertcurve");
def->enum_values.push_back("archimedeanchords");
def->enum_values.push_back("octagramspiral");
- def->enum_labels.push_back("Rectilinear");
- def->enum_labels.push_back("Concentric");
- def->enum_labels.push_back("Hilbert Curve");
- def->enum_labels.push_back("Archimedean Chords");
- def->enum_labels.push_back("Octagram Spiral");
+ def->enum_labels.push_back(L("Rectilinear"));
+ def->enum_labels.push_back(L("Concentric"));
+ def->enum_labels.push_back(L("Hilbert Curve"));
+ def->enum_labels.push_back(L("Archimedean Chords"));
+ def->enum_labels.push_back(L("Octagram Spiral"));
// solid_fill_pattern is an obsolete equivalent to external_fill_pattern.
def->aliases.push_back("solid_fill_pattern");
def->default_value = new ConfigOptionEnum<InfillPattern>(ipRectilinear);
@@ -316,6 +390,7 @@ PrintConfigDef::PrintConfigDef()
def->enum_labels.push_back("2");
def->enum_labels.push_back("3");
def->enum_labels.push_back("4");
+ def->enum_labels.push_back("5");
def = this->add("extruder_clearance_height", coFloat);
def->label = L("Height");
@@ -355,7 +430,7 @@ PrintConfigDef::PrintConfigDef()
"from the XY coordinate).");
def->sidetext = L("mm");
def->cli = "extruder-offset=s@";
- def->default_value = new ConfigOptionPoints { Pointf(0,0) };
+ def->default_value = new ConfigOptionPoints { Vec2d(0,0) };
def = this->add("extrusion_axis", coString);
def->label = L("Extrusion axis");
@@ -407,7 +482,7 @@ PrintConfigDef::PrintConfigDef()
def->tooltip = L("This is only used in the Slic3r interface as a visual help.");
def->cli = "filament-color=s@";
def->gui_type = "color";
- def->default_value = new ConfigOptionStrings { "#29b2b2" };
+ def->default_value = new ConfigOptionStrings { "#29B2B2" };
def = this->add("filament_notes", coStrings);
def->label = L("Filament notes");
@@ -428,6 +503,108 @@ PrintConfigDef::PrintConfigDef()
def->min = 0;
def->default_value = new ConfigOptionFloats { 0. };
+ def = this->add("filament_loading_speed", coFloats);
+ def->label = L("Loading speed");
+ def->tooltip = L("Speed used for loading the filament on the wipe tower. ");
+ def->sidetext = L("mm/s");
+ def->cli = "filament-loading-speed=f@";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats { 28. };
+
+ def = this->add("filament_loading_speed_start", coFloats);
+ def->label = L("Loading speed at the start");
+ def->tooltip = L("Speed used at the very beginning of loading phase. ");
+ def->sidetext = L("mm/s");
+ def->cli = "filament-loading-speed-start=f@";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats { 3. };
+
+ def = this->add("filament_unloading_speed", coFloats);
+ def->label = L("Unloading speed");
+ def->tooltip = L("Speed used for unloading the filament on the wipe tower (does not affect "
+ " initial part of unloading just after ramming). ");
+ def->sidetext = L("mm/s");
+ def->cli = "filament-unloading-speed=f@";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats { 90. };
+
+ def = this->add("filament_unloading_speed_start", coFloats);
+ def->label = L("Unloading speed at the start");
+ def->tooltip = L("Speed used for unloading the tip of the filament immediately after ramming. ");
+ def->sidetext = L("mm/s");
+ def->cli = "filament-unloading-speed-start=f@";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats { 100. };
+
+ def = this->add("filament_toolchange_delay", coFloats);
+ def->label = L("Delay after unloading");
+ def->tooltip = L("Time to wait after the filament is unloaded. "
+ "May help to get reliable toolchanges with flexible materials "
+ "that may need more time to shrink to original dimensions. ");
+ def->sidetext = L("s");
+ def->cli = "filament-toolchange-delay=f@";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats { 0. };
+
+ def = this->add("filament_cooling_moves", coInts);
+ def->label = L("Number of cooling moves");
+ def->tooltip = L("Filament is cooled by being moved back and forth in the "
+ "cooling tubes. Specify desired number of these moves ");
+ def->cli = "filament-cooling-moves=i@";
+ def->max = 0;
+ def->max = 20;
+ def->default_value = new ConfigOptionInts { 4 };
+
+ def = this->add("filament_cooling_initial_speed", coFloats);
+ def->label = L("Speed of the first cooling move");
+ def->tooltip = L("Cooling moves are gradually accelerating beginning at this speed. ");
+ def->cli = "filament-cooling-initial-speed=f@";
+ def->sidetext = L("mm/s");
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats { 2.2f };
+
+ def = this->add("filament_minimal_purge_on_wipe_tower", coFloats);
+ def->label = L("Minimal purge on wipe tower");
+ def->tooltip = L("After a tool change, the exact position of the newly loaded filament inside "
+ "the nozzle may not be known, and the filament pressure is likely not yet stable. "
+ "Before purging the print head into an infill or a sacrificial object, Slic3r will always prime "
+ "this amount of material into the wipe tower to produce successive infill or sacrificial object extrusions reliably.");
+ def->cli = "filament-minimal-purge-on-wipe-tower=f@";
+ def->sidetext = L("mm³");
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats { 15.f };
+
+ def = this->add("filament_cooling_final_speed", coFloats);
+ def->label = L("Speed of the last cooling move");
+ def->tooltip = L("Cooling moves are gradually accelerating towards this speed. ");
+ def->cli = "filament-cooling-final-speed=f@";
+ def->sidetext = L("mm/s");
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats { 3.4f };
+
+ def = this->add("filament_load_time", coFloats);
+ def->label = L("Filament load time");
+ def->tooltip = L("Time for the printer firmware (or the Multi Material Unit 2.0) to load a new filament during a tool change (when executing the T code). This time is added to the total print time by the G-code time estimator.");
+ def->cli = "filament-load-time=i@";
+ def->sidetext = L("s");
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats { 0.0f };
+
+ def = this->add("filament_ramming_parameters", coStrings);
+ def->label = L("Ramming parameters");
+ def->tooltip = L("This string is edited by RammingDialog and contains ramming specific parameters ");
+ def->cli = "filament-ramming-parameters=s@";
+ def->default_value = new ConfigOptionStrings { "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0|"
+ " 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" };
+
+ def = this->add("filament_unload_time", coFloats);
+ def->label = L("Filament unload time");
+ def->tooltip = L("Time for the printer firmware (or the Multi Material Unit 2.0) to unload a filament during a tool change (when executing the T code). This time is added to the total print time by the G-code time estimator.");
+ def->cli = "filament-unload-time=i@";
+ def->sidetext = L("s");
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats { 0.0f };
+
def = this->add("filament_diameter", coFloats);
def->label = L("Diameter");
def->tooltip = L("Enter your filament diameter here. Good precision is required, so use a caliper "
@@ -449,10 +626,7 @@ PrintConfigDef::PrintConfigDef()
def = this->add("filament_type", coStrings);
def->label = L("Filament type");
- def->tooltip = L("If you want to process the output G-code through custom scripts, just list their "
- "absolute paths here. Separate multiple scripts with a semicolon. Scripts will be passed "
- "the absolute path to the G-code file as the first argument, and they can access "
- "the Slic3r config settings by reading environment variables.");
+ def->tooltip = L("The filament material type for use in custom G-codes.");
def->cli = "filament_type=s@";
def->gui_type = "f_enum_open";
def->gui_flags = "show_value";
@@ -555,19 +729,19 @@ PrintConfigDef::PrintConfigDef()
def->enum_values.push_back("hilbertcurve");
def->enum_values.push_back("archimedeanchords");
def->enum_values.push_back("octagramspiral");
- def->enum_labels.push_back("Rectilinear");
- def->enum_labels.push_back("Grid");
- def->enum_labels.push_back("Triangles");
- def->enum_labels.push_back("Stars");
- def->enum_labels.push_back("Cubic");
- def->enum_labels.push_back("Line");
- def->enum_labels.push_back("Concentric");
- def->enum_labels.push_back("Honeycomb");
- def->enum_labels.push_back("3D Honeycomb");
- def->enum_labels.push_back("Gyroid");
- def->enum_labels.push_back("Hilbert Curve");
- def->enum_labels.push_back("Archimedean Chords");
- def->enum_labels.push_back("Octagram Spiral");
+ def->enum_labels.push_back(L("Rectilinear"));
+ def->enum_labels.push_back(L("Grid"));
+ def->enum_labels.push_back(L("Triangles"));
+ def->enum_labels.push_back(L("Stars"));
+ def->enum_labels.push_back(L("Cubic"));
+ def->enum_labels.push_back(L("Line"));
+ def->enum_labels.push_back(L("Concentric"));
+ def->enum_labels.push_back(L("Honeycomb"));
+ def->enum_labels.push_back(L("3D Honeycomb"));
+ def->enum_labels.push_back(L("Gyroid"));
+ def->enum_labels.push_back(L("Hilbert Curve"));
+ def->enum_labels.push_back(L("Archimedean Chords"));
+ def->enum_labels.push_back(L("Octagram Spiral"));
def->default_value = new ConfigOptionEnum<InfillPattern>(ipStars);
def = this->add("first_layer_acceleration", coFloat);
@@ -675,8 +849,8 @@ PrintConfigDef::PrintConfigDef()
def->enum_labels.push_back("Mach3/LinuxCNC");
def->enum_labels.push_back("Machinekit");
def->enum_labels.push_back("Smoothie");
- def->enum_labels.push_back("No extrusion");
- def->default_value = new ConfigOptionEnum<GCodeFlavor>(gcfMarlin);
+ def->enum_labels.push_back(L("No extrusion"));
+ def->default_value = new ConfigOptionEnum<GCodeFlavor>(gcfRepRap);
def = this->add("infill_acceleration", coFloat);
def->label = L("Infill");
@@ -754,6 +928,18 @@ PrintConfigDef::PrintConfigDef()
def->min = 0;
def->default_value = new ConfigOptionFloat(80);
+ def = this->add("inherits", coString);
+ def->label = L("Inherits profile");
+ def->tooltip = L("Name of the profile, from which this profile inherits.");
+ def->full_width = true;
+ def->height = 50;
+ def->default_value = new ConfigOptionString();
+
+ // The following value is to be stored into the project file (AMF, 3MF, Config ...)
+ // and it contains a sum of "inherits" values over the print and filament profiles.
+ def = this->add("inherits_cummulative", coStrings);
+ def->default_value = new ConfigOptionStrings();
+
def = this->add("interface_shells", coBool);
def->label = L("Interface shells");
def->tooltip = L("Force the generation of solid shells between adjacent materials/volumes. "
@@ -774,15 +960,105 @@ PrintConfigDef::PrintConfigDef()
def->height = 50;
def->default_value = new ConfigOptionString("");
- def = this->add("layer_height", coFloat);
- def->label = L("Layer height");
- def->category = L("Layers and Perimeters");
- def->tooltip = L("This setting controls the height (and thus the total number) of the slices/layers. "
- "Thinner layers give better accuracy but take more time to print.");
- def->sidetext = L("mm");
- def->cli = "layer-height=f";
+ def = this->add("remaining_times", coBool);
+ def->label = L("Supports remaining times");
+ def->tooltip = L("Emit M73 P[percent printed] R[remaining time in minutes] at 1 minute"
+ " intervals into the G-code to let the firmware show accurate remaining time."
+ " As of now only the Prusa i3 MK3 firmware recognizes M73."
+ " Also the i3 MK3 firmware supports M73 Qxx Sxx for the silent mode.");
+ def->default_value = new ConfigOptionBool(false);
+
+ def = this->add("silent_mode", coBool);
+ def->label = L("Supports silent mode");
+ def->tooltip = L("Set silent mode for the G-code flavor");
+ def->default_value = new ConfigOptionBool(true);
+
+ const int machine_limits_opt_width = 70;
+ {
+ struct AxisDefault {
+ std::string name;
+ std::vector<double> max_feedrate;
+ std::vector<double> max_acceleration;
+ std::vector<double> max_jerk;
+ };
+ std::vector<AxisDefault> axes {
+ // name, max_feedrate, max_acceleration, max_jerk
+ { "x", { 500., 200. }, { 9000., 1000. }, { 10. , 10. } },
+ { "y", { 500., 200. }, { 9000., 1000. }, { 10. , 10. } },
+ { "z", { 12., 12. }, { 500., 200. }, { 0.2, 0.4 } },
+ { "e", { 120., 120. }, { 10000., 5000. }, { 2.5, 2.5 } }
+ };
+ for (const AxisDefault &axis : axes) {
+ std::string axis_upper = boost::to_upper_copy<std::string>(axis.name);
+ // Add the machine feedrate limits for XYZE axes. (M203)
+ def = this->add("machine_max_feedrate_" + axis.name, coFloats);
+ def->full_label = (boost::format(L("Maximum feedrate %1%")) % axis_upper).str();
+ def->category = L("Machine limits");
+ def->tooltip = (boost::format(L("Maximum feedrate of the %1% axis")) % axis_upper).str();
+ def->sidetext = L("mm/s");
+ def->min = 0;
+ def->width = machine_limits_opt_width;
+ def->default_value = new ConfigOptionFloats(axis.max_feedrate);
+ // Add the machine acceleration limits for XYZE axes (M201)
+ def = this->add("machine_max_acceleration_" + axis.name, coFloats);
+ def->full_label = (boost::format(L("Maximum acceleration %1%")) % axis_upper).str();
+ def->category = L("Machine limits");
+ def->tooltip = (boost::format(L("Maximum acceleration of the %1% axis")) % axis_upper).str();
+ def->sidetext = L("mm/s²");
+ def->min = 0;
+ def->width = machine_limits_opt_width;
+ def->default_value = new ConfigOptionFloats(axis.max_acceleration);
+ // Add the machine jerk limits for XYZE axes (M205)
+ def = this->add("machine_max_jerk_" + axis.name, coFloats);
+ def->full_label = (boost::format(L("Maximum jerk %1%")) % axis_upper).str();
+ def->category = L("Machine limits");
+ def->tooltip = (boost::format(L("Maximum jerk of the %1% axis")) % axis_upper).str();
+ def->sidetext = L("mm/s");
+ def->min = 0;
+ def->width = machine_limits_opt_width;
+ def->default_value = new ConfigOptionFloats(axis.max_jerk);
+ }
+ }
+
+ // M205 S... [mm/sec]
+ def = this->add("machine_min_extruding_rate", coFloats);
+ def->full_label = L("Minimum feedrate when extruding");
+ def->category = L("Machine limits");
+ def->tooltip = L("Minimum feedrate when extruding") + " (M205 S)";
+ def->sidetext = L("mm/s");
def->min = 0;
- def->default_value = new ConfigOptionFloat(0.3);
+ def->width = machine_limits_opt_width;
+ def->default_value = new ConfigOptionFloats{ 0., 0. };
+
+ // M205 T... [mm/sec]
+ def = this->add("machine_min_travel_rate", coFloats);
+ def->full_label = L("Minimum travel feedrate");
+ def->category = L("Machine limits");
+ def->tooltip = L("Minimum travel feedrate") + " (M205 T)";
+ def->sidetext = L("mm/s");
+ def->min = 0;
+ def->width = machine_limits_opt_width;
+ def->default_value = new ConfigOptionFloats{ 0., 0. };
+
+ // M204 S... [mm/sec^2]
+ def = this->add("machine_max_acceleration_extruding", coFloats);
+ def->full_label = L("Maximum acceleration when extruding");
+ def->category = L("Machine limits");
+ def->tooltip = L("Maximum acceleration when extruding") + " (M204 S)";
+ def->sidetext = L("mm/s²");
+ def->min = 0;
+ def->width = machine_limits_opt_width;
+ def->default_value = new ConfigOptionFloats{ 1500., 1250. };
+
+ // M204 T... [mm/sec^2]
+ def = this->add("machine_max_acceleration_retracting", coFloats);
+ def->full_label = L("Maximum acceleration when retracting");
+ def->category = L("Machine limits");
+ def->tooltip = L("Maximum acceleration when retracting") + " (M204 T)";
+ def->sidetext = L("mm/s²");
+ def->min = 0;
+ def->width = machine_limits_opt_width;
+ def->default_value = new ConfigOptionFloats{ 1500., 1250. };
def = this->add("max_fan_speed", coInts);
def->label = L("Max");
@@ -804,13 +1080,6 @@ PrintConfigDef::PrintConfigDef()
def->min = 0;
def->default_value = new ConfigOptionFloats { 0. };
- def = this->add("max_print_height", coFloat);
- def->label = L("Max print height");
- def->tooltip = L("Set this to the maximum height that can be reached by your extruder while printing.");
- def->sidetext = L("mm");
- def->cli = "max-print-height=f";
- def->default_value = new ConfigOptionFloat(200.0);
-
def = this->add("max_print_speed", coFloat);
def->label = L("Max print speed");
def->tooltip = L("When setting other speed settings to 0 Slic3r will autocalculate the optimal speed "
@@ -879,7 +1148,7 @@ PrintConfigDef::PrintConfigDef()
def->default_value = new ConfigOptionFloats { 10. };
def = this->add("min_skirt_length", coFloat);
- def->label = L("Minimum extrusion length");
+ def->label = L("Minimal filament extrusion length");
def->tooltip = L("Generate no less than the number of skirt loops required to consume "
"the specified amount of filament on the bottom layer. For multi-extruder machines, "
"this minimum applies to each extruder.");
@@ -905,25 +1174,37 @@ PrintConfigDef::PrintConfigDef()
def->cli = "nozzle-diameter=f@";
def->default_value = new ConfigOptionFloats { 0.5 };
- def = this->add("octoprint_apikey", coString);
- def->label = L("API Key");
- def->tooltip = L("Slic3r can upload G-code files to OctoPrint. This field should contain "
- "the API Key required for authentication.");
- def->cli = "octoprint-apikey=s";
+ def = this->add("host_type", coEnum);
+ def->label = L("Host Type");
+ def->tooltip = L("Slic3r can upload G-code files to a printer host. This field must contain "
+ "the kind of the host.");
+ def->cli = "host-type=s";
+ def->enum_keys_map = &ConfigOptionEnum<PrintHostType>::get_enum_values();
+ def->enum_values.push_back("octoprint");
+ def->enum_values.push_back("duet");
+ def->enum_labels.push_back("OctoPrint");
+ def->enum_labels.push_back("Duet");
+ def->default_value = new ConfigOptionEnum<PrintHostType>(htOctoPrint);
+
+ def = this->add("printhost_apikey", coString);
+ def->label = L("API Key / Password");
+ def->tooltip = L("Slic3r can upload G-code files to a printer host. This field should contain "
+ "the API Key or the password required for authentication.");
+ def->cli = "printhost-apikey=s";
def->default_value = new ConfigOptionString("");
- def = this->add("octoprint_cafile", coString);
+ def = this->add("printhost_cafile", coString);
def->label = "HTTPS CA file";
def->tooltip = "Custom CA certificate file can be specified for HTTPS OctoPrint connections, in crt/pem format. "
"If left blank, the default OS CA certificate repository is used.";
- def->cli = "octoprint-cafile=s";
+ def->cli = "printhost-cafile=s";
def->default_value = new ConfigOptionString("");
- def = this->add("octoprint_host", coString);
+ def = this->add("print_host", coString);
def->label = L("Hostname, IP or URL");
- def->tooltip = L("Slic3r can upload G-code files to OctoPrint. This field should contain "
- "the hostname, IP address or URL of the OctoPrint instance.");
- def->cli = "octoprint-host=s";
+ def->tooltip = L("Slic3r can upload G-code files to a printer host. This field should contain "
+ "the hostname, IP address or URL of the printer host instance.");
+ def->cli = "print-host=s";
def->default_value = new ConfigOptionString("");
def = this->add("only_retract_when_crossing_perimeters", coBool);
@@ -959,6 +1240,24 @@ PrintConfigDef::PrintConfigDef()
def->cli = "overhangs!";
def->default_value = new ConfigOptionBool(true);
+ def = this->add("parking_pos_retraction", coFloat);
+ def->label = L("Filament parking position");
+ def->tooltip = L("Distance of the extruder tip from the position where the filament is parked "
+ "when unloaded. This should match the value in printer firmware. ");
+ def->sidetext = L("mm");
+ def->cli = "parking_pos_retraction=f";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloat(92.f);
+
+ def = this->add("extra_loading_move", coFloat);
+ def->label = L("Extra loading distance");
+ def->tooltip = L("When set to zero, the distance the filament is moved from parking position during load "
+ "is exactly the same as it was moved back during unload. When positive, it is loaded further, "
+ " if negative, the loading move is shorter than unloading. ");
+ def->sidetext = L("mm");
+ def->cli = "extra_loading_move=f";
+ def->default_value = new ConfigOptionFloat(-2.f);
+
def = this->add("perimeter_acceleration", coFloat);
def->label = L("Perimeters");
def->tooltip = L("This is the acceleration your printer will use for perimeters. "
@@ -1023,7 +1322,12 @@ PrintConfigDef::PrintConfigDef()
def->multiline = true;
def->full_width = true;
def->height = 60;
- def->default_value = new ConfigOptionStrings{ "" };
+ def->default_value = new ConfigOptionStrings();
+
+ def = this->add("printer_model", coString);
+ def->label = L("Printer type");
+ def->tooltip = L("Type of the printer.");
+ def->default_value = new ConfigOptionString();
def = this->add("printer_notes", coString);
def->label = L("Printer notes");
@@ -1034,6 +1338,16 @@ PrintConfigDef::PrintConfigDef()
def->height = 130;
def->default_value = new ConfigOptionString("");
+ def = this->add("printer_vendor", coString);
+ def->label = L("Printer vendor");
+ def->tooltip = L("Name of the printer vendor.");
+ def->default_value = new ConfigOptionString();
+
+ def = this->add("printer_variant", coString);
+ def->label = L("Printer variant");
+ def->tooltip = L("Name of the printer variant. For example, the printer variants may be differentiated by a nozzle diameter.");
+ def->default_value = new ConfigOptionString();
+
def = this->add("print_settings_id", coString);
def->default_value = new ConfigOptionString("");
@@ -1172,10 +1486,10 @@ PrintConfigDef::PrintConfigDef()
def->enum_values.push_back("nearest");
def->enum_values.push_back("aligned");
def->enum_values.push_back("rear");
- def->enum_labels.push_back("Random");
- def->enum_labels.push_back("Nearest");
- def->enum_labels.push_back("Aligned");
- def->enum_labels.push_back("Rear");
+ def->enum_labels.push_back(L("Random"));
+ def->enum_labels.push_back(L("Nearest"));
+ def->enum_labels.push_back(L("Aligned"));
+ def->enum_labels.push_back(L("Rear"));
def->default_value = new ConfigOptionEnum<SeamPosition>(spAligned);
#if 0
@@ -1388,7 +1702,13 @@ PrintConfigDef::PrintConfigDef()
def->label = L("Single Extruder Multi Material");
def->tooltip = L("The printer multiplexes filaments into a single hot end.");
def->cli = "single-extruder-multi-material!";
- def->default_value = new ConfigOptionBool(false);
+ def->default_value = new ConfigOptionBool(false);
+
+ def = this->add("single_extruder_multi_material_priming", coBool);
+ def->label = L("Prime all printing extruders");
+ def->tooltip = L("If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print.");
+ def->cli = "single-extruder-multi-material-priming!";
+ def->default_value = new ConfigOptionBool(true);
def = this->add("support_material", coBool);
def->label = L("Generate support material");
@@ -1438,8 +1758,8 @@ PrintConfigDef::PrintConfigDef()
def->min = 0;
def->enum_values.push_back("0");
def->enum_values.push_back("0.2");
- def->enum_labels.push_back("0 (soluble)");
- def->enum_labels.push_back("0.2 (detachable)");
+ def->enum_labels.push_back((boost::format("0 (%1%)") % L("soluble")).str());
+ def->enum_labels.push_back((boost::format("0.2 (%1%)") % L("detachable")).str());
def->default_value = new ConfigOptionFloat(0.2);
def = this->add("support_material_enforce_layers", coInt);
@@ -1528,9 +1848,9 @@ PrintConfigDef::PrintConfigDef()
def->enum_values.push_back("rectilinear");
def->enum_values.push_back("rectilinear-grid");
def->enum_values.push_back("honeycomb");
- def->enum_labels.push_back("rectilinear");
- def->enum_labels.push_back("rectilinear grid");
- def->enum_labels.push_back("honeycomb");
+ def->enum_labels.push_back(L("Rectilinear"));
+ def->enum_labels.push_back(L("Rectilinear grid"));
+ def->enum_labels.push_back(L("Honeycomb"));
def->default_value = new ConfigOptionEnum<SupportMaterialPattern>(smpRectilinear);
def = this->add("support_material_spacing", coFloat);
@@ -1587,7 +1907,7 @@ PrintConfigDef::PrintConfigDef()
"temperature control commands in the output.");
def->cli = "temperature=i@";
def->full_label = L("Temperature");
- def->max = 0;
+ def->min = 0;
def->max = max_temp;
def->default_value = new ConfigOptionInts { 200 };
@@ -1711,6 +2031,25 @@ PrintConfigDef::PrintConfigDef()
def->cli = "wipe-tower!";
def->default_value = new ConfigOptionBool(false);
+ def = this->add("wiping_volumes_extruders", coFloats);
+ def->label = L("Purging volumes - load/unload volumes");
+ def->tooltip = L("This vector saves required volumes to change from/to each tool used on the "
+ "wipe tower. These values are used to simplify creation of the full purging "
+ "volumes below. ");
+ def->cli = "wiping-volumes-extruders=f@";
+ def->default_value = new ConfigOptionFloats { 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f, 70.f };
+
+ def = this->add("wiping_volumes_matrix", coFloats);
+ def->label = L("Purging volumes - matrix");
+ def->tooltip = L("This matrix describes volumes (in cubic milimetres) required to purge the"
+ " new filament on the wipe tower for any given pair of tools. ");
+ def->cli = "wiping-volumes-matrix=f@";
+ def->default_value = new ConfigOptionFloats { 0.f, 140.f, 140.f, 140.f, 140.f,
+ 140.f, 0.f, 140.f, 140.f, 140.f,
+ 140.f, 140.f, 0.f, 140.f, 140.f,
+ 140.f, 140.f, 140.f, 0.f, 140.f,
+ 140.f, 140.f, 140.f, 140.f, 0.f };
+
def = this->add("wipe_tower_x", coFloat);
def->label = L("Position X");
def->tooltip = L("X coordinate of the left front corner of a wipe tower");
@@ -1732,14 +2071,37 @@ PrintConfigDef::PrintConfigDef()
def->cli = "wipe-tower-width=f";
def->default_value = new ConfigOptionFloat(60.);
- def = this->add("wipe_tower_per_color_wipe", coFloat);
- def->label = L("Per color change depth");
- def->tooltip = L("Depth of a wipe color per color change. For N colors, there will be "
- "maximum (N-1) tool switches performed, therefore the total depth "
- "of the wipe tower will be (N-1) times this value.");
+ def = this->add("wipe_tower_rotation_angle", coFloat);
+ def->label = L("Wipe tower rotation angle");
+ def->tooltip = L("Wipe tower rotation angle with respect to x-axis ");
+ def->sidetext = L("degrees");
+ def->cli = "wipe-tower-rotation-angle=f";
+ def->default_value = new ConfigOptionFloat(0.);
+
+ def = this->add("wipe_into_infill", coBool);
+ def->category = L("Extruders");
+ def->label = L("Wipe into this object's infill");
+ def->tooltip = L("Purging after toolchange will done inside this object's infills. "
+ "This lowers the amount of waste but may result in longer print time "
+ " due to additional travel moves.");
+ def->cli = "wipe-into-infill!";
+ def->default_value = new ConfigOptionBool(false);
+
+ def = this->add("wipe_into_objects", coBool);
+ def->category = L("Extruders");
+ def->label = L("Wipe into this object");
+ def->tooltip = L("Object will be used to purge the nozzle after a toolchange to save material "
+ "that would otherwise end up in the wipe tower and decrease print time. "
+ "Colours of the objects will be mixed as a result.");
+ def->cli = "wipe-into-objects!";
+ def->default_value = new ConfigOptionBool(false);
+
+ def = this->add("wipe_tower_bridging", coFloat);
+ def->label = L("Maximal bridging distance");
+ def->tooltip = L("Maximal distance between supports on sparse infill sections. ");
def->sidetext = L("mm");
- def->cli = "wipe-tower-per-color-wipe=f";
- def->default_value = new ConfigOptionFloat(15.);
+ def->cli = "wipe-tower-bridging=f";
+ def->default_value = new ConfigOptionFloat(10.);
def = this->add("xy_size_compensation", coFloat);
def->label = L("XY Size Compensation");
@@ -1760,6 +2122,149 @@ PrintConfigDef::PrintConfigDef()
def->sidetext = L("mm");
def->cli = "z-offset=f";
def->default_value = new ConfigOptionFloat(0);
+
+ def = this->add("bed_size_x", coFloat);
+ def->label = L("Bed size X");
+ def->category = L("Dwarf");
+ def->sidetext = L("mm");
+ def->cli = "bed-size-x=f";
+ def->default_value = new ConfigOptionFloat(68.);
+
+ def = this->add("bed_size_y", coFloat);
+ def->label = L("Bed size Y");
+ def->category = L("Dwarf");
+ def->sidetext = L("mm");
+ def->cli = "bed-size-y=f";
+ def->default_value = new ConfigOptionFloat(120.);
+
+ def = this->add("pixel_width", coInt);
+ def->label = L("Picture resolution X");
+ def->category = L("Dwarf");
+ def->sidetext = L("px");
+ def->cli = "pixel-width=i";
+ def->min = 1;
+ def->default_value = new ConfigOptionInt(1440);
+
+ def = this->add("pixel_height", coInt);
+ def->label = L("Picture resolution Y");
+ def->category = L("Dwarf");
+ def->sidetext = L("px");
+ def->cli = "pixel-height=i";
+ def->min = 1;
+ def->default_value = new ConfigOptionInt(2560);
+
+ def = this->add("exp_time", coFloat);
+ def->label = L("Exposure time");
+ def->category = L("Dwarf");
+ def->sidetext = L("s");
+ def->cli = "exp-time=f";
+ def->min = 1;
+ def->default_value = new ConfigOptionFloat(8.);
+
+ def = this->add("exp_time_first", coFloat);
+ def->label = L("Exposure time first layers");
+ def->category = L("Dwarf");
+ def->sidetext = L("s");
+ def->cli = "exp-time-first=f";
+ def->min = 1;
+ def->default_value = new ConfigOptionFloat(35.);
+}
+
+void PrintConfigDef::init_sla_params()
+{
+ t_optiondef_map &Options = this->options;
+ ConfigOptionDef* def;
+
+ // SLA Printer settings
+ def = this->add("display_width", coFloat);
+ def->label = L("Display width");
+ def->tooltip = L("Width of the display");
+ def->cli = "display-width=f";
+ def->min = 1;
+ def->default_value = new ConfigOptionFloat(150.);
+
+ def = this->add("display_height", coFloat);
+ def->label = L("Display height");
+ def->tooltip = L("Height of the display");
+ def->cli = "display-height=f";
+ def->min = 1;
+ def->default_value = new ConfigOptionFloat(100.);
+
+ def = this->add("display_pixels_x", coInt);
+ def->full_label = L("Number of pixels in");
+ def->label = ("X");
+ def->tooltip = L("Number of pixels in X");
+ def->cli = "display-pixels-x=i";
+ def->min = 100;
+ def->default_value = new ConfigOptionInt(2000);
+
+ def = this->add("display_pixels_y", coInt);
+ def->label = ("Y");
+ def->tooltip = L("Number of pixels in Y");
+ def->cli = "display-pixels-y=i";
+ def->min = 100;
+ def->default_value = new ConfigOptionInt(1000);
+
+ def = this->add("printer_correction", coFloats);
+ def->full_label = L("Printer scaling correction");
+ def->tooltip = L("Printer scaling correction");
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats( { 1., 1., 1. } );
+
+ // SLA Material settings.
+ def = this->add("initial_layer_height", coFloat);
+ def->label = L("Initial layer height");
+ def->tooltip = L("Initial layer height");
+ def->sidetext = L("mm");
+ def->cli = "initial-layer-height=f";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloat(0.3);
+
+ def = this->add("exposure_time", coFloat);
+ def->label = L("Exposure time");
+ def->tooltip = L("Exposure time");
+ def->sidetext = L("s");
+ def->cli = "exposure-time=f";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloat(10);
+
+ def = this->add("initial_exposure_time", coFloat);
+ def->label = L("Initial exposure time");
+ def->tooltip = L("Initial exposure time");
+ def->sidetext = L("s");
+ def->cli = "initial-exposure-time=f";
+ def->min = 0;
+ def->default_value = new ConfigOptionFloat(15);
+
+ def = this->add("material_correction_printing", coFloats);
+ def->full_label = L("Correction for expansion when printing");
+ def->tooltip = L("Correction for expansion when printing");
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats( { 1. , 1., 1. } );
+
+ def = this->add("material_correction_curing", coFloats);
+ def->full_label = L("Correction for expansion after curing");
+ def->tooltip = L("Correction for expansion after curing");
+ def->min = 0;
+ def->default_value = new ConfigOptionFloats( { 1. , 1., 1. } );
+
+ def = this->add("material_notes", coString);
+ def->label = L("SLA print material notes");
+ def->tooltip = L("You can put your notes regarding the SLA print material here.");
+ def->cli = "material-notes=s";
+ def->multiline = true;
+ def->full_width = true;
+ def->height = 130;
+ def->default_value = new ConfigOptionString("");
+
+ def = this->add("default_sla_material_profile", coString);
+ def->label = L("Default SLA material profile");
+ def->tooltip = L("Default print profile associated with the current printer profile. "
+ "On selection of the current printer profile, this print profile will be activated.");
+ def->default_value = new ConfigOptionString();
+
+ def = this->add("sla_material_settings_id", coString);
+ def->default_value = new ConfigOptionString("");
}
void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value)
@@ -1792,10 +2297,8 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
ConfigOptionPoint p;
p.deserialize(value);
std::ostringstream oss;
- oss << "0x0," << p.value.x << "x0," << p.value.x << "x" << p.value.y << ",0x" << p.value.y;
+ oss << "0x0," << p.value(0) << "x0," << p.value(0) << "x" << p.value(1) << ",0x" << p.value(1);
value = oss.str();
- } else if (opt_key == "octoprint_host" && !value.empty()) {
- opt_key = "print_host";
} else if ((opt_key == "perimeter_acceleration" && value == "25")
|| (opt_key == "infill_acceleration" && value == "50")) {
/* For historical reasons, the world's full of configs having these very low values;
@@ -1806,10 +2309,12 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
} else if (opt_key == "support_material_pattern" && value == "pillars") {
// Slic3r PE does not support the pillars. They never worked well.
value = "rectilinear";
- } else if (opt_key == "support_material_threshold" && value == "0") {
- // 0 used to be automatic threshold, but we introduced percent values so let's
- // transform it into the default value
- value = "60%";
+ } else if (opt_key == "octoprint_host") {
+ opt_key = "print_host";
+ } else if (opt_key == "octoprint_cafile") {
+ opt_key = "printhost_cafile";
+ } else if (opt_key == "octoprint_apikey") {
+ opt_key = "printhost_apikey";
}
// Ignore the following obsolete configuration keys:
@@ -1818,16 +2323,16 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
"support_material_tool", "acceleration", "adjust_overhang_flow",
"standby_temperature", "scale", "rotate", "duplicate", "duplicate_grid",
"start_perimeters_at_concave_points", "start_perimeters_at_non_overhang", "randomize_start",
- "seal_position", "vibration_limit", "bed_size", "octoprint_host",
- "print_center", "g0", "threads", "pressure_advance"
+ "seal_position", "vibration_limit", "bed_size",
+ "print_center", "g0", "threads", "pressure_advance", "wipe_tower_per_color_wipe"
};
+
if (ignore.find(opt_key) != ignore.end()) {
opt_key = "";
return;
}
if (! print_config_def.has(opt_key)) {
- //printf("Unknown option %s\n", opt_key.c_str());
opt_key = "";
return;
}
@@ -2079,9 +2584,14 @@ std::string FullPrintConfig::validate()
// Declare the static caches for each StaticPrintConfig derived class.
StaticPrintConfig::StaticCache<class Slic3r::PrintObjectConfig> PrintObjectConfig::s_cache_PrintObjectConfig;
StaticPrintConfig::StaticCache<class Slic3r::PrintRegionConfig> PrintRegionConfig::s_cache_PrintRegionConfig;
+StaticPrintConfig::StaticCache<class Slic3r::MachineEnvelopeConfig> MachineEnvelopeConfig::s_cache_MachineEnvelopeConfig;
StaticPrintConfig::StaticCache<class Slic3r::GCodeConfig> GCodeConfig::s_cache_GCodeConfig;
StaticPrintConfig::StaticCache<class Slic3r::PrintConfig> PrintConfig::s_cache_PrintConfig;
StaticPrintConfig::StaticCache<class Slic3r::HostConfig> HostConfig::s_cache_HostConfig;
StaticPrintConfig::StaticCache<class Slic3r::FullPrintConfig> FullPrintConfig::s_cache_FullPrintConfig;
+StaticPrintConfig::StaticCache<class Slic3r::SLAMaterialConfig> SLAMaterialConfig::s_cache_SLAMaterialConfig;
+StaticPrintConfig::StaticCache<class Slic3r::SLAPrinterConfig> SLAPrinterConfig::s_cache_SLAPrinterConfig;
+StaticPrintConfig::StaticCache<class Slic3r::SLAFullPrintConfig> SLAFullPrintConfig::s_cache_SLAFullPrintConfig;
+
}
diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp
index cb94a7921..5bc99a51a 100644
--- a/xs/src/libslic3r/PrintConfig.hpp
+++ b/xs/src/libslic3r/PrintConfig.hpp
@@ -22,11 +22,23 @@
namespace Slic3r {
+enum PrinterTechnology
+{
+ // Fused Filament Fabrication
+ ptFFF,
+ // Stereolitography
+ ptSLA,
+};
+
enum GCodeFlavor {
gcfRepRap, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlin, gcfSailfish, gcfMach3, gcfMachinekit,
gcfSmoothie, gcfNoExtrusion,
};
+enum PrintHostType {
+ htOctoPrint, htDuet,
+};
+
enum InfillPattern {
ipRectilinear, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral,
@@ -44,7 +56,16 @@ enum FilamentType {
ftPLA, ftABS, ftPET, ftHIPS, ftFLEX, ftSCAFF, ftEDGE, ftNGEN, ftPVA
};
-template<> inline t_config_enum_values& ConfigOptionEnum<GCodeFlavor>::get_enum_values() {
+template<> inline const t_config_enum_values& ConfigOptionEnum<PrinterTechnology>::get_enum_values() {
+ static t_config_enum_values keys_map;
+ if (keys_map.empty()) {
+ keys_map["FFF"] = ptFFF;
+ keys_map["SLA"] = ptSLA;
+ }
+ return keys_map;
+}
+
+template<> inline const t_config_enum_values& ConfigOptionEnum<GCodeFlavor>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["reprap"] = gcfRepRap;
@@ -61,7 +82,16 @@ template<> inline t_config_enum_values& ConfigOptionEnum<GCodeFlavor>::get_enum_
return keys_map;
}
-template<> inline t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enum_values() {
+template<> inline const t_config_enum_values& ConfigOptionEnum<PrintHostType>::get_enum_values() {
+ static t_config_enum_values keys_map;
+ if (keys_map.empty()) {
+ keys_map["octoprint"] = htOctoPrint;
+ keys_map["duet"] = htDuet;
+ }
+ return keys_map;
+}
+
+template<> inline const t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["rectilinear"] = ipRectilinear;
@@ -81,7 +111,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum<InfillPattern>::get_enu
return keys_map;
}
-template<> inline t_config_enum_values& ConfigOptionEnum<SupportMaterialPattern>::get_enum_values() {
+template<> inline const t_config_enum_values& ConfigOptionEnum<SupportMaterialPattern>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["rectilinear"] = smpRectilinear;
@@ -91,7 +121,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum<SupportMaterialPattern>
return keys_map;
}
-template<> inline t_config_enum_values& ConfigOptionEnum<SeamPosition>::get_enum_values() {
+template<> inline const t_config_enum_values& ConfigOptionEnum<SeamPosition>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["random"] = spRandom;
@@ -102,7 +132,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum<SeamPosition>::get_enum
return keys_map;
}
-template<> inline t_config_enum_values& ConfigOptionEnum<FilamentType>::get_enum_values() {
+template<> inline const t_config_enum_values& ConfigOptionEnum<FilamentType>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["PLA"] = ftPLA;
@@ -126,6 +156,11 @@ public:
PrintConfigDef();
static void handle_legacy(t_config_option_key &opt_key, std::string &value);
+
+private:
+ void init_common_params();
+ void init_fff_params();
+ void init_sla_params();
};
// The one and only global definition of SLic3r configuration options.
@@ -154,6 +189,13 @@ public:
// Validate the PrintConfig. Returns an empty string on success, otherwise an error message is returned.
std::string validate();
+
+ // Verify whether the opt_key has not been obsoleted or renamed.
+ // Both opt_key and value may be modified by handle_legacy().
+ // If the opt_key is no more valid in this version of Slic3r, opt_key is cleared by handle_legacy().
+ // handle_legacy() is called internally by set_deserialize().
+ void handle_legacy(t_config_option_key &opt_key, std::string &value) const override
+ { PrintConfigDef::handle_legacy(opt_key, value); }
};
template<typename CONFIG>
@@ -329,7 +371,8 @@ public:
ConfigOptionBool support_material_with_sheath;
ConfigOptionFloatOrPercent support_material_xy_spacing;
ConfigOptionFloat xy_size_compensation;
-
+ ConfigOptionBool wipe_into_objects;
+
protected:
void initialize(StaticCacheBase &cache, const char *base_ptr)
{
@@ -365,6 +408,7 @@ protected:
OPT_PTR(support_material_threshold);
OPT_PTR(support_material_with_sheath);
OPT_PTR(xy_size_compensation);
+ OPT_PTR(wipe_into_objects);
}
};
@@ -407,7 +451,8 @@ public:
ConfigOptionFloatOrPercent top_infill_extrusion_width;
ConfigOptionInt top_solid_layers;
ConfigOptionFloatOrPercent top_solid_infill_speed;
-
+ ConfigOptionBool wipe_into_infill;
+
protected:
void initialize(StaticCacheBase &cache, const char *base_ptr)
{
@@ -445,6 +490,57 @@ protected:
OPT_PTR(top_infill_extrusion_width);
OPT_PTR(top_solid_infill_speed);
OPT_PTR(top_solid_layers);
+ OPT_PTR(wipe_into_infill);
+ }
+};
+
+class MachineEnvelopeConfig : public StaticPrintConfig
+{
+ STATIC_PRINT_CONFIG_CACHE(MachineEnvelopeConfig)
+public:
+ // M201 X... Y... Z... E... [mm/sec^2]
+ ConfigOptionFloats machine_max_acceleration_x;
+ ConfigOptionFloats machine_max_acceleration_y;
+ ConfigOptionFloats machine_max_acceleration_z;
+ ConfigOptionFloats machine_max_acceleration_e;
+ // M203 X... Y... Z... E... [mm/sec]
+ ConfigOptionFloats machine_max_feedrate_x;
+ ConfigOptionFloats machine_max_feedrate_y;
+ ConfigOptionFloats machine_max_feedrate_z;
+ ConfigOptionFloats machine_max_feedrate_e;
+ // M204 S... [mm/sec^2]
+ ConfigOptionFloats machine_max_acceleration_extruding;
+ // M204 T... [mm/sec^2]
+ ConfigOptionFloats machine_max_acceleration_retracting;
+ // M205 X... Y... Z... E... [mm/sec]
+ ConfigOptionFloats machine_max_jerk_x;
+ ConfigOptionFloats machine_max_jerk_y;
+ ConfigOptionFloats machine_max_jerk_z;
+ ConfigOptionFloats machine_max_jerk_e;
+ // M205 T... [mm/sec]
+ ConfigOptionFloats machine_min_travel_rate;
+ // M205 S... [mm/sec]
+ ConfigOptionFloats machine_min_extruding_rate;
+
+protected:
+ void initialize(StaticCacheBase &cache, const char *base_ptr)
+ {
+ OPT_PTR(machine_max_acceleration_x);
+ OPT_PTR(machine_max_acceleration_y);
+ OPT_PTR(machine_max_acceleration_z);
+ OPT_PTR(machine_max_acceleration_e);
+ OPT_PTR(machine_max_feedrate_x);
+ OPT_PTR(machine_max_feedrate_y);
+ OPT_PTR(machine_max_feedrate_z);
+ OPT_PTR(machine_max_feedrate_e);
+ OPT_PTR(machine_max_acceleration_extruding);
+ OPT_PTR(machine_max_acceleration_retracting);
+ OPT_PTR(machine_max_jerk_x);
+ OPT_PTR(machine_max_jerk_y);
+ OPT_PTR(machine_max_jerk_z);
+ OPT_PTR(machine_max_jerk_e);
+ OPT_PTR(machine_min_travel_rate);
+ OPT_PTR(machine_min_extruding_rate);
}
};
@@ -466,6 +562,18 @@ public:
ConfigOptionBools filament_soluble;
ConfigOptionFloats filament_cost;
ConfigOptionFloats filament_max_volumetric_speed;
+ ConfigOptionFloats filament_loading_speed;
+ ConfigOptionFloats filament_loading_speed_start;
+ ConfigOptionFloats filament_load_time;
+ ConfigOptionFloats filament_unloading_speed;
+ ConfigOptionFloats filament_unloading_speed_start;
+ ConfigOptionFloats filament_toolchange_delay;
+ ConfigOptionFloats filament_unload_time;
+ ConfigOptionInts filament_cooling_moves;
+ ConfigOptionFloats filament_cooling_initial_speed;
+ ConfigOptionFloats filament_minimal_purge_on_wipe_tower;
+ ConfigOptionFloats filament_cooling_final_speed;
+ ConfigOptionStrings filament_ramming_parameters;
ConfigOptionBool gcode_comments;
ConfigOptionEnum<GCodeFlavor> gcode_flavor;
ConfigOptionString layer_gcode;
@@ -485,13 +593,20 @@ public:
ConfigOptionString start_gcode;
ConfigOptionStrings start_filament_gcode;
ConfigOptionBool single_extruder_multi_material;
+ ConfigOptionBool single_extruder_multi_material_priming;
ConfigOptionString toolchange_gcode;
ConfigOptionFloat travel_speed;
ConfigOptionBool use_firmware_retraction;
ConfigOptionBool use_relative_e_distances;
ConfigOptionBool use_volumetric_e;
ConfigOptionBool variable_layer_height;
-
+ ConfigOptionFloat cooling_tube_retraction;
+ ConfigOptionFloat cooling_tube_length;
+ ConfigOptionFloat parking_pos_retraction;
+ ConfigOptionBool remaining_times;
+ ConfigOptionBool silent_mode;
+ ConfigOptionFloat extra_loading_move;
+
std::string get_extrusion_axis() const
{
return
@@ -515,6 +630,18 @@ protected:
OPT_PTR(filament_soluble);
OPT_PTR(filament_cost);
OPT_PTR(filament_max_volumetric_speed);
+ OPT_PTR(filament_loading_speed);
+ OPT_PTR(filament_loading_speed_start);
+ OPT_PTR(filament_load_time);
+ OPT_PTR(filament_unloading_speed);
+ OPT_PTR(filament_unloading_speed_start);
+ OPT_PTR(filament_unload_time);
+ OPT_PTR(filament_toolchange_delay);
+ OPT_PTR(filament_cooling_moves);
+ OPT_PTR(filament_cooling_initial_speed);
+ OPT_PTR(filament_minimal_purge_on_wipe_tower);
+ OPT_PTR(filament_cooling_final_speed);
+ OPT_PTR(filament_ramming_parameters);
OPT_PTR(gcode_comments);
OPT_PTR(gcode_flavor);
OPT_PTR(layer_gcode);
@@ -532,6 +659,7 @@ protected:
OPT_PTR(retract_restart_extra_toolchange);
OPT_PTR(retract_speed);
OPT_PTR(single_extruder_multi_material);
+ OPT_PTR(single_extruder_multi_material_priming);
OPT_PTR(start_gcode);
OPT_PTR(start_filament_gcode);
OPT_PTR(toolchange_gcode);
@@ -540,11 +668,17 @@ protected:
OPT_PTR(use_relative_e_distances);
OPT_PTR(use_volumetric_e);
OPT_PTR(variable_layer_height);
+ OPT_PTR(cooling_tube_retraction);
+ OPT_PTR(cooling_tube_length);
+ OPT_PTR(parking_pos_retraction);
+ OPT_PTR(remaining_times);
+ OPT_PTR(silent_mode);
+ OPT_PTR(extra_loading_move);
}
};
// This object is mapped to Perl as Slic3r::Config::Print.
-class PrintConfig : public GCodeConfig
+class PrintConfig : public MachineEnvelopeConfig, public GCodeConfig
{
STATIC_PRINT_CONFIG_CACHE_DERIVED(PrintConfig)
PrintConfig() : GCodeConfig(0) { initialize_cache(); *this = s_cache_PrintConfig.defaults(); }
@@ -592,6 +726,7 @@ public:
ConfigOptionString output_filename_format;
ConfigOptionFloat perimeter_acceleration;
ConfigOptionStrings post_process;
+ ConfigOptionString printer_model;
ConfigOptionString printer_notes;
ConfigOptionFloat resolution;
ConfigOptionFloats retract_before_travel;
@@ -610,12 +745,23 @@ public:
ConfigOptionFloat wipe_tower_y;
ConfigOptionFloat wipe_tower_width;
ConfigOptionFloat wipe_tower_per_color_wipe;
+ ConfigOptionFloat wipe_tower_rotation_angle;
+ ConfigOptionFloat wipe_tower_bridging;
+ ConfigOptionFloats wiping_volumes_matrix;
+ ConfigOptionFloats wiping_volumes_extruders;
ConfigOptionFloat z_offset;
+ ConfigOptionFloat bed_size_x;
+ ConfigOptionFloat bed_size_y;
+ ConfigOptionInt pixel_width;
+ ConfigOptionInt pixel_height;
+ ConfigOptionFloat exp_time;
+ ConfigOptionFloat exp_time_first;
protected:
PrintConfig(int) : GCodeConfig(1) {}
void initialize(StaticCacheBase &cache, const char *base_ptr)
{
+ this->MachineEnvelopeConfig::initialize(cache, base_ptr);
this->GCodeConfig::initialize(cache, base_ptr);
OPT_PTR(avoid_crossing_perimeters);
OPT_PTR(bed_shape);
@@ -657,6 +803,7 @@ protected:
OPT_PTR(output_filename_format);
OPT_PTR(perimeter_acceleration);
OPT_PTR(post_process);
+ OPT_PTR(printer_model);
OPT_PTR(printer_notes);
OPT_PTR(resolution);
OPT_PTR(retract_before_travel);
@@ -675,7 +822,17 @@ protected:
OPT_PTR(wipe_tower_y);
OPT_PTR(wipe_tower_width);
OPT_PTR(wipe_tower_per_color_wipe);
+ OPT_PTR(wipe_tower_rotation_angle);
+ OPT_PTR(wipe_tower_bridging);
+ OPT_PTR(wiping_volumes_matrix);
+ OPT_PTR(wiping_volumes_extruders);
OPT_PTR(z_offset);
+ OPT_PTR(bed_size_x);
+ OPT_PTR(bed_size_y);
+ OPT_PTR(pixel_width);
+ OPT_PTR(pixel_height);
+ OPT_PTR(exp_time);
+ OPT_PTR(exp_time_first);
}
};
@@ -683,18 +840,20 @@ class HostConfig : public StaticPrintConfig
{
STATIC_PRINT_CONFIG_CACHE(HostConfig)
public:
- ConfigOptionString octoprint_host;
- ConfigOptionString octoprint_apikey;
- ConfigOptionString octoprint_cafile;
+ ConfigOptionEnum<PrintHostType> host_type;
+ ConfigOptionString print_host;
+ ConfigOptionString printhost_apikey;
+ ConfigOptionString printhost_cafile;
ConfigOptionString serial_port;
ConfigOptionInt serial_speed;
protected:
void initialize(StaticCacheBase &cache, const char *base_ptr)
{
- OPT_PTR(octoprint_host);
- OPT_PTR(octoprint_apikey);
- OPT_PTR(octoprint_cafile);
+ OPT_PTR(host_type);
+ OPT_PTR(print_host);
+ OPT_PTR(printhost_apikey);
+ OPT_PTR(printhost_cafile);
OPT_PTR(serial_port);
OPT_PTR(serial_speed);
}
@@ -713,6 +872,7 @@ class FullPrintConfig :
public:
// Validate the FullPrintConfig. Returns an empty string on success, otherwise an error message is returned.
std::string validate();
+
protected:
// Protected constructor to be called to initialize ConfigCache::m_default.
FullPrintConfig(int) : PrintObjectConfig(0), PrintRegionConfig(0), PrintConfig(0), HostConfig(0) {}
@@ -725,6 +885,73 @@ protected:
}
};
+class SLAMaterialConfig : public StaticPrintConfig
+{
+ STATIC_PRINT_CONFIG_CACHE(SLAMaterialConfig)
+public:
+ ConfigOptionFloat layer_height;
+ ConfigOptionFloat initial_layer_height;
+ ConfigOptionFloat exposure_time;
+ ConfigOptionFloat initial_exposure_time;
+ ConfigOptionFloats material_correction_printing;
+ ConfigOptionFloats material_correction_curing;
+protected:
+ void initialize(StaticCacheBase &cache, const char *base_ptr)
+ {
+ OPT_PTR(layer_height);
+ OPT_PTR(initial_layer_height);
+ OPT_PTR(exposure_time);
+ OPT_PTR(initial_exposure_time);
+ OPT_PTR(material_correction_printing);
+ OPT_PTR(material_correction_curing);
+ }
+};
+
+class SLAPrinterConfig : public StaticPrintConfig
+{
+ STATIC_PRINT_CONFIG_CACHE(SLAPrinterConfig)
+public:
+ ConfigOptionEnum<PrinterTechnology> printer_technology;
+ ConfigOptionPoints bed_shape;
+ ConfigOptionFloat max_print_height;
+ ConfigOptionFloat display_width;
+ ConfigOptionFloat display_height;
+ ConfigOptionInt display_pixels_x;
+ ConfigOptionInt display_pixels_y;
+ ConfigOptionFloats printer_correction;
+protected:
+ void initialize(StaticCacheBase &cache, const char *base_ptr)
+ {
+ OPT_PTR(printer_technology);
+ OPT_PTR(bed_shape);
+ OPT_PTR(max_print_height);
+ OPT_PTR(display_width);
+ OPT_PTR(display_height);
+ OPT_PTR(display_pixels_x);
+ OPT_PTR(display_pixels_y);
+ OPT_PTR(printer_correction);
+ }
+};
+
+class SLAFullPrintConfig : public SLAPrinterConfig, public SLAMaterialConfig
+{
+ STATIC_PRINT_CONFIG_CACHE_DERIVED(SLAFullPrintConfig)
+ SLAFullPrintConfig() : SLAPrinterConfig(0), SLAMaterialConfig(0) { initialize_cache(); *this = s_cache_SLAFullPrintConfig.defaults(); }
+
+public:
+ // Validate the SLAFullPrintConfig. Returns an empty string on success, otherwise an error message is returned.
+// std::string validate();
+
+protected:
+ // Protected constructor to be called to initialize ConfigCache::m_default.
+ SLAFullPrintConfig(int) : SLAPrinterConfig(0), SLAMaterialConfig(0) {}
+ void initialize(StaticCacheBase &cache, const char *base_ptr)
+ {
+ this->SLAPrinterConfig ::initialize(cache, base_ptr);
+ this->SLAMaterialConfig::initialize(cache, base_ptr);
+ }
+};
+
#undef STATIC_PRINT_CONFIG_CACHE
#undef STATIC_PRINT_CONFIG_CACHE_BASE
#undef STATIC_PRINT_CONFIG_CACHE_DERIVED
diff --git a/xs/src/libslic3r/PrintExport.hpp b/xs/src/libslic3r/PrintExport.hpp
new file mode 100644
index 000000000..7c3871251
--- /dev/null
+++ b/xs/src/libslic3r/PrintExport.hpp
@@ -0,0 +1,383 @@
+#ifndef PRINTEXPORT_HPP
+#define PRINTEXPORT_HPP
+
+#include "Print.hpp"
+
+// For png export of the sliced model
+#include <fstream>
+#include <sstream>
+
+#include <wx/stdstream.h>
+#include <wx/wfstream.h>
+#include <wx/zipstrm.h>
+
+#include <boost/log/trivial.hpp>
+
+#include "Rasterizer/Rasterizer.hpp"
+#include <tbb/parallel_for.h>
+#include <tbb/spin_mutex.h>//#include "tbb/mutex.h"
+
+namespace Slic3r {
+
+enum class FilePrinterFormat {
+ PNG,
+ SVG
+};
+
+/*
+ * Interface for a file printer of the slices. Implementation can be an SVG
+ * or PNG printer or any other format.
+ *
+ * The format argument specifies the output format of the printer and it enables
+ * different implementations of this class template for each supported format.
+ *
+ */
+template<FilePrinterFormat format>
+class FilePrinter {
+public:
+
+ void printConfig(const Print&);
+
+ // Draw an ExPolygon which is a polygon inside a slice on the specified layer.
+ void drawPolygon(const ExPolygon& p, unsigned lyr);
+
+ // Tell the printer how many layers should it consider.
+ void layers(unsigned layernum);
+
+ // Get the number of layers in the print.
+ unsigned layers() const;
+
+ /* Switch to a particular layer. If there where less layers then the
+ * specified layer number than an appropriate number of layers will be
+ * allocated in the printer.
+ */
+ void beginLayer(unsigned layer);
+
+ // Allocate a new layer on top of the last and switch to it.
+ void beginLayer();
+
+ /*
+ * Finish the selected layer. It means that no drawing is allowed on that
+ * layer anymore. This fact can be used to prepare the file system output
+ * data like png comprimation and so on.
+ */
+ void finishLayer(unsigned layer);
+
+ // Finish the top layer.
+ void finishLayer();
+
+ // Save all the layers into the file (or dir) specified in the path argument
+ void save(const std::string& path);
+
+ // Save only the selected layer to the file specified in path argument.
+ void saveLayer(unsigned lyr, const std::string& path);
+};
+
+// Implementation for PNG raster output
+// Be aware that if a large number of layers are allocated, it can very well
+// exhaust the available memory especially on 32 bit platform.
+template<> class FilePrinter<FilePrinterFormat::PNG> {
+
+ struct Layer {
+ Raster first;
+ std::stringstream second;
+
+ Layer() {}
+
+ Layer(const Layer&) = delete;
+ Layer(Layer&& m):
+ first(std::move(m.first))/*, second(std::move(m.second))*/ {}
+ };
+
+ // We will save the compressed PNG data into stringstreams which can be done
+ // in parallel. Later we can write every layer to the disk sequentially.
+ std::vector<Layer> layers_rst_;
+ Raster::Resolution res_;
+ Raster::PixelDim pxdim_;
+ const Print *print_ = nullptr;
+ double exp_time_s_ = .0, exp_time_first_s_ = .0;
+
+ std::string createIniContent(const std::string& projectname) {
+ double layer_height = print_?
+ print_->default_object_config().layer_height.getFloat() :
+ 0.05;
+
+ using std::string;
+ using std::to_string;
+
+ auto expt_str = to_string(exp_time_s_);
+ auto expt_first_str = to_string(exp_time_first_s_);
+ auto stepnum_str = to_string(static_cast<unsigned>(800*layer_height));
+ auto layerh_str = to_string(layer_height);
+
+ return string(
+ "action = print\n"
+ "jobDir = ") + projectname + "\n" +
+ "expTime = " + expt_str + "\n"
+ "expTimeFirst = " + expt_first_str + "\n"
+ "stepNum = " + stepnum_str + "\n"
+ "wifiOn = 1\n"
+ "tiltSlow = 60\n"
+ "tiltFast = 15\n"
+ "numFade = 10\n"
+ "startdelay = 0\n"
+ "layerHeight = " + layerh_str + "\n"
+ "noteInfo = "
+ "expTime="+expt_str+"+resinType=generic+layerHeight="
+ +layerh_str+"+printer=DWARF3\n";
+ }
+
+ // Change this to TOP_LEFT if you want correct PNG orientation
+ static const Raster::Origin ORIGIN = Raster::Origin::BOTTOM_LEFT;
+
+public:
+ inline FilePrinter(double width_mm, double height_mm,
+ unsigned width_px, unsigned height_px,
+ double exp_time, double exp_time_first):
+ res_(width_px, height_px),
+ pxdim_(width_mm/width_px, height_mm/height_px),
+ exp_time_s_(exp_time),
+ exp_time_first_s_(exp_time_first)
+ {
+ }
+
+ FilePrinter(const FilePrinter& ) = delete;
+ FilePrinter(FilePrinter&& m):
+ layers_rst_(std::move(m.layers_rst_)),
+ res_(m.res_),
+ pxdim_(m.pxdim_) {}
+
+ inline void layers(unsigned cnt) { if(cnt > 0) layers_rst_.resize(cnt); }
+ inline unsigned layers() const { return layers_rst_.size(); }
+
+ void printConfig(const Print& printconf) { print_ = &printconf; }
+
+ inline void drawPolygon(const ExPolygon& p, unsigned lyr) {
+ assert(lyr < layers_rst_.size());
+ layers_rst_[lyr].first.draw(p);
+ }
+
+ inline void beginLayer(unsigned lyr) {
+ if(layers_rst_.size() <= lyr) layers_rst_.resize(lyr+1);
+ layers_rst_[lyr].first.reset(res_, pxdim_, ORIGIN);
+ }
+
+ inline void beginLayer() {
+ layers_rst_.emplace_back();
+ layers_rst_.front().first.reset(res_, pxdim_, ORIGIN);
+ }
+
+ inline void finishLayer(unsigned lyr_id) {
+ assert(lyr_id < layers_rst_.size());
+ layers_rst_[lyr_id].first.save(layers_rst_[lyr_id].second,
+ Raster::Compression::PNG);
+ layers_rst_[lyr_id].first.reset();
+ }
+
+ inline void finishLayer() {
+ if(!layers_rst_.empty()) {
+ layers_rst_.back().first.save(layers_rst_.back().second,
+ Raster::Compression::PNG);
+ layers_rst_.back().first.reset();
+ }
+ }
+
+ inline void save(const std::string& path) {
+
+ wxFileName filepath(path);
+
+ wxFFileOutputStream zipfile(path);
+
+ std::string project = filepath.GetName().ToStdString();
+
+ if(!zipfile.IsOk()) {
+ BOOST_LOG_TRIVIAL(error) << "Can't create zip file for layers! "
+ << path;
+ return;
+ }
+
+ wxZipOutputStream zipstream(zipfile);
+ wxStdOutputStream pngstream(zipstream);
+
+ zipstream.PutNextEntry("config.ini");
+ pngstream << createIniContent(project);
+
+ for(unsigned i = 0; i < layers_rst_.size(); i++) {
+ if(layers_rst_[i].second.rdbuf()->in_avail() > 0) {
+ char lyrnum[6];
+ std::sprintf(lyrnum, "%.5d", i);
+ auto zfilename = project + lyrnum + ".png";
+ zipstream.PutNextEntry(zfilename);
+ pngstream << layers_rst_[i].second.rdbuf();
+ layers_rst_[i].second.str("");
+ }
+ }
+
+ zipstream.Close();
+ zipfile.Close();
+ }
+
+ void saveLayer(unsigned lyr, const std::string& path) {
+ unsigned i = lyr;
+ assert(i < layers_rst_.size());
+
+ char lyrnum[6];
+ std::sprintf(lyrnum, "%.5d", lyr);
+ std::string loc = path + "layer" + lyrnum + ".png";
+
+ std::fstream out(loc, std::fstream::out | std::fstream::binary);
+ if(out.good()) {
+ layers_rst_[i].first.save(out, Raster::Compression::PNG);
+ } else {
+ BOOST_LOG_TRIVIAL(error) << "Can't create file for layer";
+ }
+
+ out.close();
+ layers_rst_[i].first.reset();
+ }
+};
+
+// Let's shadow this eigen interface
+inline coord_t px(const Point& p) { return p(0); }
+inline coord_t py(const Point& p) { return p(1); }
+inline coordf_t px(const Vec2d& p) { return p(0); }
+inline coordf_t py(const Vec2d& p) { return p(1); }
+
+template<FilePrinterFormat format, class...Args>
+void print_to(Print& print,
+ std::string dirpath,
+ double width_mm,
+ double height_mm,
+ Args&&...args)
+{
+
+ std::string& dir = dirpath;
+
+ // This map will hold the layers sorted by z coordinate. Layers on the
+ // same height (from different objects) will be mapped to the same key and
+ // rasterized to the same image.
+ std::map<long long, LayerPtrs> layers;
+
+ auto& objects = print.objects();
+
+ // Merge the sliced layers with the support layers
+ std::for_each(objects.cbegin(), objects.cend(), [&layers](const PrintObject *o) {
+ for(const auto l : o->layers()) {
+ auto& lyrs = layers[static_cast<long long>(scale_(l->print_z))];
+ lyrs.push_back(l);
+ }
+
+ for(const auto l : o->support_layers()) {
+ auto& lyrs = layers[static_cast<long long>(scale_(l->print_z))];
+ lyrs.push_back(l);
+ }
+ });
+
+ auto print_bb = print.bounding_box();
+ Vec2d punsc = unscale(print_bb.size());
+
+ // If the print does not fit into the print area we should cry about it.
+ if(px(punsc) > width_mm || py(punsc) > height_mm) {
+ BOOST_LOG_TRIVIAL(warning) << "Warning: Print will not fit!" << "\n"
+ << "Width needed: " << px(punsc) << "\n"
+ << "Height needed: " << py(punsc) << "\n";
+ }
+
+ // Offset for centering the print onto the print area
+ auto cx = scale_(width_mm)/2 - (px(print_bb.center()) - px(print_bb.min));
+ auto cy = scale_(height_mm)/2 - (py(print_bb.center()) - py(print_bb.min));
+
+ // Create the actual printer, forward any additional arguments to it.
+ FilePrinter<format> printer(width_mm, height_mm,
+ std::forward<Args>(args)...);
+
+ printer.printConfig(print);
+
+ printer.layers(layers.size()); // Allocate space for all the layers
+
+ int st_prev = 0;
+ const std::string jobdesc = "Rasterizing and compressing sliced layers";
+ tbb::spin_mutex m;
+
+ std::vector<long long> keys;
+ keys.reserve(layers.size());
+ for(auto& e : layers) keys.push_back(e.first);
+
+ //FIXME
+ int initstatus = //print.progressindicator? print.progressindicator->state() :
+ 0;
+ print.set_status(initstatus, jobdesc);
+
+ // Method that prints one layer
+ auto process_layer = [&layers, &keys, &printer, &st_prev, &m,
+ &jobdesc, print_bb, dir, cx, cy, &print, initstatus]
+ (unsigned layer_id)
+ {
+ LayerPtrs lrange = layers[keys[layer_id]];
+
+ printer.beginLayer(layer_id); // Switch to the appropriate layer
+
+ for(Layer *lp : lrange) {
+ Layer& l = *lp;
+
+ ExPolygonCollection slices = l.slices; // Copy the layer slices
+
+ // Sort the polygons in the layer
+ std::stable_sort(slices.expolygons.begin(), slices.expolygons.end(),
+ [](const ExPolygon& a, const ExPolygon& b) {
+ return a.contour.contains(b.contour.first_point()) ? false :
+ true;
+ });
+
+ // Draw all the polygons in the slice to the actual layer.
+ for (const Point &d : l.object()->copies())
+ for (ExPolygon slice : slices.expolygons) {
+ slice.translate(px(d), py(d));
+ slice.translate(-px(print_bb.min) + cx,
+ -py(print_bb.min) + cy);
+
+ printer.drawPolygon(slice, layer_id);
+ }
+
+ /*if(print.has_support_material() && layer_id > 0) {
+ BOOST_LOG_TRIVIAL(warning) << "support material for layer "
+ << layer_id
+ << " defined but export is "
+ "not yet implemented.";
+
+ }*/
+
+ }
+
+ printer.finishLayer(layer_id); // Finish the layer for later saving it.
+
+ auto st = static_cast<int>(layer_id*80.0/layers.size());
+ m.lock();
+ if( st - st_prev > 10) {
+ print.set_status(initstatus + st, jobdesc);
+ st_prev = st;
+ }
+ m.unlock();
+
+ // printer.saveLayer(layer_id, dir); We could save the layer immediately
+ };
+
+ // Print all the layers in parallel
+ tbb::parallel_for<size_t, decltype(process_layer)>(0,
+ layers.size(),
+ process_layer);
+
+ // Sequential version (for testing)
+ // for(unsigned l = 0; l < layers.size(); ++l) process_layer(l);
+
+// print.set_status(100, jobdesc);
+
+ // Save the print into the file system.
+ print.set_status(initstatus + 90, "Writing layers to disk");
+ printer.save(dir);
+ print.set_status(initstatus + 100, "Writing layers completed");
+}
+
+}
+
+#endif // PRINTEXPORT_HPP
diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp
index ba2521cd7..96c831157 100644
--- a/xs/src/libslic3r/PrintObject.cpp
+++ b/xs/src/libslic3r/PrintObject.cpp
@@ -4,6 +4,7 @@
#include "Geometry.hpp"
#include "SupportMaterial.hpp"
#include "Surface.hpp"
+#include "Slicing.hpp"
#include <utility>
#include <boost/log/trivial.hpp>
@@ -37,6 +38,7 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Bounding
typed_slices(false),
m_print(print),
m_model_object(model_object),
+ size(Vec3crd::Zero()),
layer_height_profile_valid(false)
{
// Compute the translation to be applied to our meshes so that we work with smaller coordinates
@@ -47,10 +49,9 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Bounding
// don't assume it's already aligned and we don't alter the original position in model.
// We store the XY translation so that we can place copies correctly in the output G-code
// (copies are expressed in G-code coordinates and this translation is not publicly exposed).
- this->_copies_shift = Point::new_scale(modobj_bbox.min.x, modobj_bbox.min.y);
+ m_copies_shift = Point::new_scale(modobj_bbox.min(0), modobj_bbox.min(1));
// Scale the object size and store it
- Pointf3 size = modobj_bbox.size();
- this->size = Point3::new_scale(size.x, size.y, size.z);
+ this->size = (modobj_bbox.size() * (1. / SCALING_FACTOR)).cast<coord_t>();
}
this->reload_model_instances();
@@ -58,10 +59,10 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Bounding
this->layer_height_profile = model_object->layer_height_profile;
}
-bool PrintObject::add_copy(const Pointf &point)
+bool PrintObject::add_copy(const Vec2d &point)
{
Points points = m_copies;
- points.push_back(Point::new_scale(point.x, point.y));
+ points.push_back(Point::new_scale(point(0), point(1)));
return this->set_copies(points);
}
@@ -74,24 +75,23 @@ bool PrintObject::delete_last_copy()
bool PrintObject::set_copies(const Points &points)
{
- m_copies = points;
+ bool copies_num_changed = m_copies.size() != points.size();
// order copies with a nearest neighbor search and translate them by _copies_shift
- this->_shifted_copies.clear();
- this->_shifted_copies.reserve(points.size());
+ m_copies.clear();
+ m_copies.reserve(points.size());
// order copies with a nearest-neighbor search
std::vector<Points::size_type> ordered_copies;
Slic3r::Geometry::chained_path(points, ordered_copies);
- for (size_t point_idx : ordered_copies) {
- Point copy = points[point_idx];
- copy.translate(this->_copies_shift);
- this->_shifted_copies.push_back(copy);
- }
+ for (size_t point_idx : ordered_copies)
+ m_copies.push_back(points[point_idx] + m_copies_shift);
bool invalidated = m_print->invalidate_step(psSkirt);
invalidated |= m_print->invalidate_step(psBrim);
+ if (copies_num_changed)
+ invalidated |= m_print->invalidate_step(psWipeTower);
return invalidated;
}
@@ -100,7 +100,8 @@ bool PrintObject::reload_model_instances()
Points copies;
copies.reserve(m_model_object->instances.size());
for (const ModelInstance *mi : m_model_object->instances)
- copies.emplace_back(Point::new_scale(mi->offset.x, mi->offset.y));
+ if (mi->is_printable())
+ copies.emplace_back(Point::new_scale(mi->offset(0), mi->offset(1)));
return this->set_copies(copies);
}
@@ -115,7 +116,7 @@ bool PrintObject::reload_model_instances()
// this should be idempotent
void PrintObject::slice()
{
- if (m_state.is_done(posSlice))
+ if (this->is_step_done(posSlice))
return;
this->set_started(posSlice);
m_print->set_status(10, "Processing triangulated mesh");
@@ -143,7 +144,7 @@ void PrintObject::make_perimeters()
// prerequisites
this->slice();
- if (m_state.is_done(posPerimeters))
+ if (this->is_step_done(posPerimeters))
return;
this->set_started(posPerimeters);
@@ -168,12 +169,8 @@ void PrintObject::make_perimeters()
// inside the object - infill_only_where_needed should be the method of choice for printing
// hollow objects
for (size_t region_id = 0; region_id < m_print->regions().size(); ++ region_id) {
- const PrintRegion &region = *m_print->regions()[region_id];
-
- if (!region.config().extra_perimeters
- || region.config().perimeters == 0
- || region.config().fill_density == 0
- || this->layer_count() < 2)
+ const PrintRegion &region = *m_print->regions()[region_id];
+ if (! region.config().extra_perimeters || region.config().perimeters == 0 || region.config().fill_density == 0 || this->layer_count() < 2)
continue;
BOOST_LOG_TRIVIAL(debug) << "Generating extra perimeters for region " << region_id << " in parallel - start";
@@ -259,7 +256,7 @@ void PrintObject::make_perimeters()
void PrintObject::prepare_infill()
{
- if (m_state.is_done(posPrepareInfill))
+ if (this->is_step_done(posPrepareInfill))
return;
this->set_started(posPrepareInfill);
@@ -375,10 +372,13 @@ void PrintObject::prepare_infill()
void PrintObject::infill()
{
+ if (! this->is_printable())
+ return;
+
// prerequisites
this->prepare_infill();
- if (! m_state.is_done(posInfill)) {
+ if (! this->is_step_done(posInfill)) {
this->set_started(posInfill);
BOOST_LOG_TRIVIAL(debug) << "Filling layers in parallel - start";
tbb::parallel_for(
@@ -401,7 +401,7 @@ void PrintObject::infill()
void PrintObject::generate_support_material()
{
- if (! m_state.is_done(posSupportMaterial)) {
+ if (! this->is_step_done(posSupportMaterial)) {
this->set_started(posSupportMaterial);
this->clear_support_layers();
if ((m_config.support_material || m_config.raft_layers > 0) && m_layers.size() > 1) {
@@ -545,7 +545,10 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|| opt_key == "perimeter_speed"
|| opt_key == "small_perimeter_speed"
|| opt_key == "solid_infill_speed"
- || opt_key == "top_solid_infill_speed") {
+ || opt_key == "top_solid_infill_speed"
+ || opt_key == "wipe_into_infill" // when these these two are changed, we only need to invalidate the wipe tower,
+ || opt_key == "wipe_into_objects" // which we already did at the very beginning - nothing more to be done
+ ) {
// these options only affect G-code export, so nothing to invalidate
} else {
// for legacy, if we can't handle this option let's invalidate all steps
@@ -585,6 +588,8 @@ bool PrintObject::invalidate_step(PrintObjectStep step)
}
// Wipe tower depends on the ordering of extruders, which in turn depends on everything.
+ // It also decides about what the wipe_into_infill / wipe_into_object features will do,
+ // and that too depends on many of the settings.
invalidated |= m_print->invalidate_step(psWipeTower);
return invalidated;
}
@@ -1341,7 +1346,7 @@ SlicingParameters PrintObject::slicing_parameters() const
{
return SlicingParameters::create_from_config(
this->print()->config(), m_config,
- unscale(this->size.z), this->print()->object_extruders());
+ unscale<double>(this->size(2)), this->print()->object_extruders());
}
bool PrintObject::update_layer_height_profile(std::vector<coordf_t> &layer_height_profile) const
@@ -1402,8 +1407,8 @@ void PrintObject::_slice()
this->typed_slices = false;
-#if 0
- // Disable parallelization for debugging purposes.
+#ifdef SLIC3R_PROFILE
+ // Disable parallelization so the Shiny profiler works
static tbb::task_scheduler_init *tbb_init = nullptr;
tbb_init = new tbb::task_scheduler_init(1);
#endif
@@ -1461,7 +1466,7 @@ void PrintObject::_slice()
if (region_id == other_region_id)
continue;
for (size_t layer_id = 0; layer_id < expolygons_by_layer.size(); ++ layer_id) {
- Layer *layer = this->layers()[layer_id];
+ Layer *layer = m_layers[layer_id];
LayerRegion *layerm = layer->m_regions[region_id];
LayerRegion *other_layerm = layer->m_regions[other_region_id];
if (layerm == nullptr || other_layerm == nullptr)
@@ -1563,7 +1568,7 @@ std::vector<ExPolygons> PrintObject::_slice_region(size_t region_id, const std::
// consider the first one
this->model_object()->instances.front()->transform_mesh(&mesh, true);
// align mesh to Z = 0 (it should be already aligned actually) and apply XY shift
- mesh.translate(- float(unscale(this->_copies_shift.x)), - float(unscale(this->_copies_shift.y)), -float(this->model_object()->bounding_box().min.z));
+ mesh.translate(- unscale<float>(m_copies_shift(0)), - unscale<float>(m_copies_shift(1)), - float(this->model_object()->bounding_box().min(2)));
// perform actual slicing
TriangleMeshSlicer mslicer;
Print *print = this->print();
@@ -1680,6 +1685,113 @@ void PrintObject::_simplify_slices(double distance)
BOOST_LOG_TRIVIAL(debug) << "Slicing objects - siplifying slices in parallel - end";
}
+void PrintObject::_make_perimeters()
+{
+ if (!this->is_printable())
+ return;
+
+ if (this->is_step_done(posPerimeters))
+ return;
+ this->set_started(posPerimeters);
+
+ BOOST_LOG_TRIVIAL(info) << "Generating perimeters...";
+
+ // merge slices if they were split into types
+ if (this->typed_slices) {
+ FOREACH_LAYER(this, layer_it)
+ (*layer_it)->merge_slices();
+ this->typed_slices = false;
+ this->invalidate_step(posPrepareInfill);
+ }
+
+ // compare each layer to the one below, and mark those slices needing
+ // one additional inner perimeter, like the top of domed objects-
+
+ // this algorithm makes sure that at least one perimeter is overlapping
+ // but we don't generate any extra perimeter if fill density is zero, as they would be floating
+ // inside the object - infill_only_where_needed should be the method of choice for printing
+ // hollow objects
+ for (size_t region_id = 0; region_id < m_print->regions().size(); ++ region_id) {
+ const PrintRegion &region = *m_print->regions()[region_id];
+ if (! region.config().extra_perimeters || region.config().perimeters == 0 || region.config().fill_density == 0 || this->layer_count() < 2)
+ continue;
+
+ BOOST_LOG_TRIVIAL(debug) << "Generating extra perimeters for region " << region_id << " in parallel - start";
+ tbb::parallel_for(
+ tbb::blocked_range<size_t>(0, m_layers.size() - 1),
+ [this, &region, region_id](const tbb::blocked_range<size_t>& range) {
+ for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
+ LayerRegion &layerm = *m_layers[layer_idx]->regions()[region_id];
+ const LayerRegion &upper_layerm = *m_layers[layer_idx+1]->regions()[region_id];
+ const Polygons upper_layerm_polygons = upper_layerm.slices;
+ // Filter upper layer polygons in intersection_ppl by their bounding boxes?
+ // my $upper_layerm_poly_bboxes= [ map $_->bounding_box, @{$upper_layerm_polygons} ];
+ const double total_loop_length = total_length(upper_layerm_polygons);
+ const coord_t perimeter_spacing = layerm.flow(frPerimeter).scaled_spacing();
+ const Flow ext_perimeter_flow = layerm.flow(frExternalPerimeter);
+ const coord_t ext_perimeter_width = ext_perimeter_flow.scaled_width();
+ const coord_t ext_perimeter_spacing = ext_perimeter_flow.scaled_spacing();
+
+ for (Surface &slice : layerm.slices.surfaces) {
+ for (;;) {
+ // compute the total thickness of perimeters
+ const coord_t perimeters_thickness = ext_perimeter_width/2 + ext_perimeter_spacing/2
+ + (region.config().perimeters-1 + slice.extra_perimeters) * perimeter_spacing;
+ // define a critical area where we don't want the upper slice to fall into
+ // (it should either lay over our perimeters or outside this area)
+ const coord_t critical_area_depth = coord_t(perimeter_spacing * 1.5);
+ const Polygons critical_area = diff(
+ offset(slice.expolygon, float(- perimeters_thickness)),
+ offset(slice.expolygon, float(- perimeters_thickness - critical_area_depth))
+ );
+ // check whether a portion of the upper slices falls inside the critical area
+ const Polylines intersection = intersection_pl(to_polylines(upper_layerm_polygons), critical_area);
+ // only add an additional loop if at least 30% of the slice loop would benefit from it
+ if (total_length(intersection) <= total_loop_length*0.3)
+ break;
+ /*
+ if (0) {
+ require "Slic3r/SVG.pm";
+ Slic3r::SVG::output(
+ "extra.svg",
+ no_arrows => 1,
+ expolygons => union_ex($critical_area),
+ polylines => [ map $_->split_at_first_point, map $_->p, @{$upper_layerm->slices} ],
+ );
+ }
+ */
+ ++ slice.extra_perimeters;
+ }
+ #ifdef DEBUG
+ if (slice.extra_perimeters > 0)
+ printf(" adding %d more perimeter(s) at layer %zu\n", slice.extra_perimeters, layer_idx);
+ #endif
+ }
+ }
+ });
+ BOOST_LOG_TRIVIAL(debug) << "Generating extra perimeters for region " << region_id << " in parallel - end";
+ }
+
+ BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - start";
+ tbb::parallel_for(
+ tbb::blocked_range<size_t>(0, m_layers.size()),
+ [this](const tbb::blocked_range<size_t>& range) {
+ for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx)
+ m_layers[layer_idx]->make_perimeters();
+ }
+ );
+ BOOST_LOG_TRIVIAL(debug) << "Generating perimeters in parallel - end";
+
+ /*
+ simplify slices (both layer and region slices),
+ we only need the max resolution for perimeters
+ ### This makes this method not-idempotent, so we keep it disabled for now.
+ ###$self->_simplify_slices(&Slic3r::SCALED_RESOLUTION);
+ */
+
+ this->set_done(posPerimeters);
+}
+
// Only active if config->infill_only_where_needed. This step trims the sparse infill,
// so it acts as an internal support. It maintains all other infill types intact.
// Here the internal surfaces and perimeters have to be supported by the sparse infill.
@@ -2069,6 +2181,9 @@ void PrintObject::combine_infill()
void PrintObject::_generate_support_material()
{
+ if (!this->is_printable())
+ return;
+
PrintObjectSupportMaterial support_material(this, PrintObject::slicing_parameters());
support_material.generate(*this);
}
@@ -2083,4 +2198,12 @@ void PrintObject::reset_layer_height_profile()
this->model_object()->layer_height_profile_valid = false;
}
+void PrintObject::adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action)
+{
+ update_layer_height_profile(m_model_object->layer_height_profile);
+ Slic3r::adjust_layer_height_profile(slicing_parameters(), m_model_object->layer_height_profile, z, layer_thickness_delta, band_width, LayerHeightEditActionType(action));
+ m_model_object->layer_height_profile_valid = true;
+ layer_height_profile_valid = false;
+}
+
} // namespace Slic3r
diff --git a/xs/src/libslic3r/Rasterizer/Rasterizer.cpp b/xs/src/libslic3r/Rasterizer/Rasterizer.cpp
new file mode 100644
index 000000000..b0bf04343
--- /dev/null
+++ b/xs/src/libslic3r/Rasterizer/Rasterizer.cpp
@@ -0,0 +1,214 @@
+#include "Rasterizer.hpp"
+#include <ExPolygon.hpp>
+
+#include <cstdint>
+
+// For rasterizing
+#include <agg/agg_basics.h>
+#include <agg/agg_rendering_buffer.h>
+#include <agg/agg_pixfmt_gray.h>
+#include <agg/agg_pixfmt_rgb.h>
+#include <agg/agg_renderer_base.h>
+#include <agg/agg_renderer_scanline.h>
+
+#include <agg/agg_scanline_p.h>
+#include <agg/agg_rasterizer_scanline_aa.h>
+#include <agg/agg_path_storage.h>
+
+// For png compression
+#include <png/writer.hpp>
+
+namespace Slic3r {
+
+class Raster::Impl {
+public:
+ using TPixelRenderer = agg::pixfmt_gray8; // agg::pixfmt_rgb24;
+ using TRawRenderer = agg::renderer_base<TPixelRenderer>;
+ using TPixel = TPixelRenderer::color_type;
+ using TRawBuffer = agg::rendering_buffer;
+
+ using TBuffer = std::vector<TPixelRenderer::pixel_type>;
+
+ using TRendererAA = agg::renderer_scanline_aa_solid<TRawRenderer>;
+
+ static const TPixel ColorWhite;
+ static const TPixel ColorBlack;
+
+ using Origin = Raster::Origin;
+
+private:
+ Raster::Resolution resolution_;
+ Raster::PixelDim pxdim_;
+ TBuffer buf_;
+ TRawBuffer rbuf_;
+ TPixelRenderer pixfmt_;
+ TRawRenderer raw_renderer_;
+ TRendererAA renderer_;
+ Origin o_;
+ std::function<void(agg::path_storage&)> flipy_ = [](agg::path_storage&) {};
+public:
+ inline Impl(const Raster::Resolution& res, const Raster::PixelDim &pd,
+ Origin o):
+ resolution_(res), pxdim_(pd),
+ buf_(res.pixels()),
+ rbuf_(reinterpret_cast<TPixelRenderer::value_type*>(buf_.data()),
+ res.width_px, res.height_px,
+ res.width_px*TPixelRenderer::num_components),
+ pixfmt_(rbuf_),
+ raw_renderer_(pixfmt_),
+ renderer_(raw_renderer_),
+ o_(o)
+ {
+ renderer_.color(ColorWhite);
+
+ // If we would like to play around with gamma
+ // ras.gamma(agg::gamma_power(1.0));
+
+ clear();
+
+ if(o_ == Origin::TOP_LEFT) flipy_ = [this](agg::path_storage& path) {
+ path.flip_y(0, resolution_.height_px);
+ };
+ }
+
+ void draw(const ExPolygon &poly) {
+ agg::rasterizer_scanline_aa<> ras;
+ agg::scanline_p8 scanlines;
+
+ auto&& path = to_path(poly.contour);
+ flipy_(path);
+ ras.add_path(path);
+
+ for(auto h : poly.holes) {
+ auto&& holepath = to_path(h);
+ flipy_(holepath);
+ ras.add_path(holepath);
+ }
+
+ agg::render_scanlines(ras, scanlines, renderer_);
+ }
+
+ inline void clear() {
+ raw_renderer_.clear(ColorBlack);
+ }
+
+ inline TBuffer& buffer() { return buf_; }
+
+ inline const Raster::Resolution resolution() { return resolution_; }
+
+ inline Origin origin() const /*noexcept*/ { return o_; }
+
+private:
+ double getPx(const Point& p) {
+ return p(0) * SCALING_FACTOR/pxdim_.w_mm;
+ }
+
+ double getPy(const Point& p) {
+ return p(1) * SCALING_FACTOR/pxdim_.h_mm;
+ }
+
+ agg::path_storage to_path(const Polygon& poly) {
+ agg::path_storage path;
+ auto it = poly.points.begin();
+ path.move_to(getPx(*it), getPy(*it));
+ while(++it != poly.points.end())
+ path.line_to(getPx(*it), getPy(*it));
+
+ path.line_to(getPx(poly.points.front()), getPy(poly.points.front()));
+ return path;
+ }
+
+};
+
+const Raster::Impl::TPixel Raster::Impl::ColorWhite = Raster::Impl::TPixel(255);
+const Raster::Impl::TPixel Raster::Impl::ColorBlack = Raster::Impl::TPixel(0);
+
+Raster::Raster(const Resolution &r, const PixelDim &pd, Origin o):
+ impl_(new Impl(r, pd, o)) {}
+
+Raster::Raster() {}
+
+Raster::~Raster() {}
+
+Raster::Raster(Raster &&m):
+ impl_(std::move(m.impl_)) {}
+
+void Raster::reset(const Raster::Resolution &r, const Raster::PixelDim &pd)
+{
+ // Free up the unnecessary memory and make sure it stays clear after
+ // an exception
+ auto o = impl_? impl_->origin() : Origin::TOP_LEFT;
+ reset(r, pd, o);
+}
+
+void Raster::reset(const Raster::Resolution &r, const Raster::PixelDim &pd,
+ Raster::Origin o)
+{
+ impl_.reset();
+ impl_.reset(new Impl(r, pd, o));
+}
+
+void Raster::reset()
+{
+ impl_.reset();
+}
+
+Raster::Resolution Raster::resolution() const
+{
+ if(impl_) return impl_->resolution();
+
+ return Resolution(0, 0);
+}
+
+void Raster::clear()
+{
+ assert(impl_);
+ impl_->clear();
+}
+
+void Raster::draw(const ExPolygon &poly)
+{
+ assert(impl_);
+ impl_->draw(poly);
+}
+
+void Raster::save(std::ostream& stream, Compression comp)
+{
+ assert(impl_);
+ switch(comp) {
+ case Compression::PNG: {
+
+ png::writer<std::ostream> wr(stream);
+
+ wr.set_bit_depth(8);
+ wr.set_color_type(png::color_type_gray);
+ wr.set_width(resolution().width_px);
+ wr.set_height(resolution().height_px);
+ wr.set_compression_type(png::compression_type_default);
+
+ wr.write_info();
+
+ auto& b = impl_->buffer();
+ auto ptr = reinterpret_cast<png::byte*>( b.data() );
+ unsigned stride =
+ sizeof(Impl::TBuffer::value_type) * resolution().width_px;
+
+ for(unsigned r = 0; r < resolution().height_px; r++, ptr+=stride) {
+ wr.write_row(ptr);
+ }
+
+ break;
+ }
+ case Compression::RAW: {
+ stream << "P5 "
+ << impl_->resolution().width_px << " "
+ << impl_->resolution().height_px << " "
+ << "255 ";
+
+ stream.write(reinterpret_cast<const char*>(impl_->buffer().data()),
+ impl_->buffer().size()*sizeof(Impl::TBuffer::value_type));
+ }
+ }
+}
+
+}
diff --git a/xs/src/libslic3r/Rasterizer/Rasterizer.hpp b/xs/src/libslic3r/Rasterizer/Rasterizer.hpp
new file mode 100644
index 000000000..cbb39bc6b
--- /dev/null
+++ b/xs/src/libslic3r/Rasterizer/Rasterizer.hpp
@@ -0,0 +1,86 @@
+#ifndef RASTERIZER_HPP
+#define RASTERIZER_HPP
+
+#include <ostream>
+#include <memory>
+
+namespace Slic3r {
+
+class ExPolygon;
+
+/**
+ * @brief Raster captures an anti-aliased monochrome canvas where vectorial
+ * polygons can be rasterized. Fill color is always white and the background is
+ * black. Contours are anti-aliased.
+ *
+ * It also supports saving the raster data into a standard output stream in raw
+ * or PNG format.
+ */
+class Raster {
+ class Impl;
+ std::unique_ptr<Impl> impl_;
+public:
+
+ /// Supported compression types
+ enum class Compression {
+ RAW, //!> Uncompressed pixel data
+ PNG //!> PNG compression
+ };
+
+ enum class Origin {
+ TOP_LEFT,
+ BOTTOM_LEFT
+ };
+
+ /// Type that represents a resolution in pixels.
+ struct Resolution {
+ unsigned width_px;
+ unsigned height_px;
+ inline Resolution(unsigned w, unsigned h): width_px(w), height_px(h) {}
+ inline unsigned pixels() const /*noexcept*/ {
+ return width_px * height_px;
+ }
+ };
+
+ /// Types that represents the dimension of a pixel in millimeters.
+ struct PixelDim {
+ double w_mm;
+ double h_mm;
+ inline PixelDim(double px_width_mm, double px_height_mm ):
+ w_mm(px_width_mm), h_mm(px_height_mm) {}
+ };
+
+ /// Constructor taking the resolution and the pixel dimension.
+ explicit Raster(const Resolution& r, const PixelDim& pd,
+ Origin o = Origin::BOTTOM_LEFT );
+ Raster();
+ Raster(const Raster& cpy) = delete;
+ Raster& operator=(const Raster& cpy) = delete;
+ Raster(Raster&& m);
+ ~Raster();
+
+ /// Reallocated everything for the given resolution and pixel dimension.
+ void reset(const Resolution& r, const PixelDim& pd);
+ void reset(const Resolution& r, const PixelDim& pd, Origin o);
+
+ /**
+ * Release the allocated resources. Drawing in this state ends in
+ * unspecified behaviour.
+ */
+ void reset();
+
+ /// Get the resolution of the raster.
+ Resolution resolution() const;
+
+ /// Clear the raster with black color.
+ void clear();
+
+ /// Draw a polygon with holes.
+ void draw(const ExPolygon& poly);
+
+ /// Save the raster on the specified stream.
+ void save(std::ostream& stream, Compression comp = Compression::RAW);
+};
+
+}
+#endif // RASTERIZER_HPP
diff --git a/xs/src/libslic3r/SLABasePool.cpp b/xs/src/libslic3r/SLABasePool.cpp
new file mode 100644
index 000000000..f3683865c
--- /dev/null
+++ b/xs/src/libslic3r/SLABasePool.cpp
@@ -0,0 +1,531 @@
+#include <functional>
+#include <numeric>
+
+#include "SLABasePool.hpp"
+#include "ExPolygon.hpp"
+#include "TriangleMesh.hpp"
+#include "ClipperUtils.hpp"
+#include "boost/log/trivial.hpp"
+
+//#include "SVG.hpp"
+
+namespace Slic3r { namespace sla {
+
+namespace {
+
+using coord_t = Point::coord_type;
+
+/// get the scaled clipper units for a millimeter value
+inline coord_t mm(double v) { return coord_t(v/SCALING_FACTOR); }
+
+/// Get x and y coordinates (because we are eigenizing...)
+inline coord_t x(const Point& p) { return p(0); }
+inline coord_t y(const Point& p) { return p(1); }
+inline coord_t& x(Point& p) { return p(0); }
+inline coord_t& y(Point& p) { return p(1); }
+
+inline coordf_t x(const Vec3d& p) { return p(0); }
+inline coordf_t y(const Vec3d& p) { return p(1); }
+inline coordf_t z(const Vec3d& p) { return p(2); }
+inline coordf_t& x(Vec3d& p) { return p(0); }
+inline coordf_t& y(Vec3d& p) { return p(1); }
+inline coordf_t& z(Vec3d& p) { return p(2); }
+
+inline coord_t& x(Vec3crd& p) { return p(0); }
+inline coord_t& y(Vec3crd& p) { return p(1); }
+inline coord_t& z(Vec3crd& p) { return p(2); }
+inline coord_t x(const Vec3crd& p) { return p(0); }
+inline coord_t y(const Vec3crd& p) { return p(1); }
+inline coord_t z(const Vec3crd& p) { return p(2); }
+
+inline void triangulate(const ExPolygon& expoly, Polygons& triangles) {
+ expoly.triangulate_p2t(&triangles);
+}
+
+inline Polygons triangulate(const ExPolygon& expoly) {
+ Polygons tri; triangulate(expoly, tri); return tri;
+}
+
+using Indices = std::vector<Vec3crd>;
+
+/// Intermediate struct for a 3D mesh
+struct Contour3D {
+ Pointf3s points;
+ Indices indices;
+
+ void merge(const Contour3D& ctr) {
+ auto s3 = coord_t(points.size());
+ auto s = coord_t(indices.size());
+
+ points.insert(points.end(), ctr.points.begin(), ctr.points.end());
+ indices.insert(indices.end(), ctr.indices.begin(), ctr.indices.end());
+
+ for(auto n = s; n < indices.size(); n++) {
+ auto& idx = indices[n]; x(idx) += s3; y(idx) += s3; z(idx) += s3;
+ }
+ }
+};
+
+/// Convert the triangulation output to an intermediate mesh.
+inline Contour3D convert(const Polygons& triangles, coord_t z, bool dir) {
+
+ Pointf3s points;
+ points.reserve(3*triangles.size());
+ Indices indices;
+ indices.reserve(points.size());
+
+ for(auto& tr : triangles) {
+ auto c = coord_t(points.size()), b = c++, a = c++;
+ if(dir) indices.emplace_back(a, b, c);
+ else indices.emplace_back(c, b, a);
+ for(auto& p : tr.points) {
+ points.emplace_back(unscale(x(p), y(p), z));
+ }
+ }
+
+ return {points, indices};
+}
+
+/// Only a debug function to generate top and bottom plates from a 2D shape.
+/// It is not used in the algorithm directly.
+inline Contour3D roofs(const ExPolygon& poly, coord_t z_distance) {
+ Polygons triangles = triangulate(poly);
+
+ auto lower = convert(triangles, 0, false);
+ auto upper = convert(triangles, z_distance, true);
+ lower.merge(upper);
+ return lower;
+}
+
+inline Contour3D walls(const ExPolygon& floor_plate, const ExPolygon& ceiling,
+ double floor_z_mm, double ceiling_z_mm) {
+ using std::transform; using std::back_inserter;
+
+ ExPolygon poly;
+ poly.contour.points = floor_plate.contour.points;
+ poly.holes.emplace_back(ceiling.contour);
+ auto& h = poly.holes.front();
+ std::reverse(h.points.begin(), h.points.end());
+ Polygons tri = triangulate(poly);
+
+ Contour3D ret;
+ ret.points.reserve(tri.size() * 3);
+
+ double fz = floor_z_mm;
+ double cz = ceiling_z_mm;
+ auto& rp = ret.points;
+ auto& rpi = ret.indices;
+ ret.indices.reserve(tri.size() * 3);
+
+ coord_t idx = 0;
+
+ auto hlines = h.lines();
+ auto is_upper = [&hlines](const Point& p) {
+ return std::any_of(hlines.begin(), hlines.end(),
+ [&p](const Line& l) {
+ return l.distance_to(p) < mm(0.01);
+ });
+ };
+
+ std::for_each(tri.begin(), tri.end(),
+ [&rp, &rpi, &poly, &idx, is_upper, fz, cz](const Polygon& pp)
+ {
+ for(auto& p : pp.points)
+ if(is_upper(p))
+ rp.emplace_back(unscale(x(p), y(p), mm(cz)));
+ else rp.emplace_back(unscale(x(p), y(p), mm(fz)));
+
+ coord_t a = idx++, b = idx++, c = idx++;
+ if(fz > cz) rpi.emplace_back(c, b, a);
+ else rpi.emplace_back(a, b, c);
+ });
+
+ return ret;
+}
+
+/// Mesh from an existing contour.
+inline TriangleMesh mesh(const Contour3D& ctour) {
+ return {ctour.points, ctour.indices};
+}
+
+/// Mesh from an evaporating 3D contour
+inline TriangleMesh mesh(Contour3D&& ctour) {
+ return {std::move(ctour.points), std::move(ctour.indices)};
+}
+
+/// Offsetting with clipper and smoothing the edges into a curvature.
+inline void offset(ExPolygon& sh, coord_t distance) {
+ using ClipperLib::ClipperOffset;
+ using ClipperLib::jtRound;
+ using ClipperLib::etClosedPolygon;
+ using ClipperLib::Paths;
+ using ClipperLib::Path;
+
+ auto&& ctour = Slic3rMultiPoint_to_ClipperPath(sh.contour);
+ auto&& holes = Slic3rMultiPoints_to_ClipperPaths(sh.holes);
+
+ // If the input is not at least a triangle, we can not do this algorithm
+ if(ctour.size() < 3 ||
+ std::any_of(holes.begin(), holes.end(),
+ [](const Path& p) { return p.size() < 3; })
+ ) {
+ BOOST_LOG_TRIVIAL(error) << "Invalid geometry for offsetting!";
+ return;
+ }
+
+ ClipperOffset offs;
+ offs.ArcTolerance = 0.01*mm(1);
+ Paths result;
+ offs.AddPath(ctour, jtRound, etClosedPolygon);
+ offs.AddPaths(holes, jtRound, etClosedPolygon);
+ offs.Execute(result, static_cast<double>(distance));
+
+ // Offsetting reverts the orientation and also removes the last vertex
+ // so boost will not have a closed polygon.
+
+ bool found_the_contour = false;
+ sh.holes.clear();
+ for(auto& r : result) {
+ if(ClipperLib::Orientation(r)) {
+ // We don't like if the offsetting generates more than one contour
+ // but throwing would be an overkill. Instead, we should warn the
+ // caller about the inability to create correct geometries
+ if(!found_the_contour) {
+ auto rr = ClipperPath_to_Slic3rPolygon(r);
+ sh.contour.points.swap(rr.points);
+ found_the_contour = true;
+ } else {
+ BOOST_LOG_TRIVIAL(warning)
+ << "Warning: offsetting result is invalid!";
+ }
+ } else {
+ // TODO If there are multiple contours we can't be sure which hole
+ // belongs to the first contour. (But in this case the situation is
+ // bad enough to let it go...)
+ sh.holes.emplace_back(ClipperPath_to_Slic3rPolygon(r));
+ }
+ }
+}
+
+template<class ExP, class D>
+inline Contour3D round_edges(const ExPolygon& base_plate,
+ double radius_mm,
+ double degrees,
+ double ceilheight_mm,
+ bool dir,
+ ExP&& last_offset = ExP(), D&& last_height = D())
+{
+ auto ob = base_plate;
+ auto ob_prev = ob;
+ double wh = ceilheight_mm, wh_prev = wh;
+ Contour3D curvedwalls;
+
+ const size_t steps = 6; // steps for 180 degrees
+ degrees = std::fmod(degrees, 180);
+ const int portion = int(steps*degrees / 90);
+ const double ystep_mm = radius_mm/steps;
+ coord_t s = dir? 1 : -1;
+ double xxprev = 0;
+ for(int i = 0; i < portion; i++) {
+ ob = base_plate;
+
+ // The offset is given by the equation: x = sqrt(r^2 - y^2)
+ // which can be derived from the circle equation. y is the current
+ // height for which the offset is calculated and x is the offset itself
+ // r is the radius of the circle that is used to smooth the edges
+
+ double r2 = radius_mm * radius_mm;
+ double y2 = steps*ystep_mm - i*ystep_mm;
+ y2 *= y2;
+
+ double xx = sqrt(r2 - y2);
+
+ offset(ob, s*mm(xx));
+ wh = ceilheight_mm - i*ystep_mm;
+
+ Contour3D pwalls;
+ if(xxprev < xx) pwalls = walls(ob, ob_prev, wh, wh_prev);
+ else pwalls = walls(ob_prev, ob, wh_prev, wh);
+
+ curvedwalls.merge(pwalls);
+ ob_prev = ob;
+ wh_prev = wh;
+ xxprev = xx;
+ }
+
+ last_offset = std::move(ob);
+ last_height = wh;
+
+ return curvedwalls;
+}
+
+/// Generating the concave part of the 3D pool with the bottom plate and the
+/// side walls.
+inline Contour3D inner_bed(const ExPolygon& poly, double depth_mm,
+ double begin_h_mm = 0) {
+
+ Polygons triangles = triangulate(poly);
+
+ coord_t depth = mm(depth_mm);
+ coord_t begin_h = mm(begin_h_mm);
+
+ auto bottom = convert(triangles, -depth + begin_h, false);
+ auto lines = poly.lines();
+
+ // Generate outer walls
+ auto fp = [](const Point& p, Point::coord_type z) {
+ return unscale(x(p), y(p), z);
+ };
+
+ for(auto& l : lines) {
+ auto s = coord_t(bottom.points.size());
+
+ bottom.points.emplace_back(fp(l.a, -depth + begin_h));
+ bottom.points.emplace_back(fp(l.b, -depth + begin_h));
+ bottom.points.emplace_back(fp(l.a, begin_h));
+ bottom.points.emplace_back(fp(l.b, begin_h));
+
+ bottom.indices.emplace_back(s + 3, s + 1, s);
+ bottom.indices.emplace_back(s + 2, s + 3, s);
+ }
+
+ return bottom;
+}
+
+/// Unification of polygons (with clipper) preserving holes as well.
+inline ExPolygons unify(const ExPolygons& shapes) {
+ using ClipperLib::ptSubject;
+
+ ExPolygons retv;
+
+ bool closed = true;
+ bool valid = true;
+
+ ClipperLib::Clipper clipper;
+
+ for(auto& path : shapes) {
+ auto clipperpath = Slic3rMultiPoint_to_ClipperPath(path.contour);
+
+ if(!clipperpath.empty())
+ valid &= clipper.AddPath(clipperpath, ptSubject, closed);
+
+ auto clipperholes = Slic3rMultiPoints_to_ClipperPaths(path.holes);
+
+ for(auto& hole : clipperholes) {
+ if(!hole.empty())
+ valid &= clipper.AddPath(hole, ptSubject, closed);
+ }
+ }
+
+ if(!valid) BOOST_LOG_TRIVIAL(warning) << "Unification of invalid shapes!";
+
+ ClipperLib::PolyTree result;
+ clipper.Execute(ClipperLib::ctUnion, result, ClipperLib::pftNonZero);
+
+ retv.reserve(static_cast<size_t>(result.Total()));
+
+ // Now we will recursively traverse the polygon tree and serialize it
+ // into an ExPolygon with holes. The polygon tree has the clipper-ish
+ // PolyTree structure which alternates its nodes as contours and holes
+
+ // A "declaration" of function for traversing leafs which are holes
+ std::function<void(ClipperLib::PolyNode*, ExPolygon&)> processHole;
+
+ // Process polygon which calls processHoles which than calls processPoly
+ // again until no leafs are left.
+ auto processPoly = [&retv, &processHole](ClipperLib::PolyNode *pptr) {
+ ExPolygon poly;
+ poly.contour.points = ClipperPath_to_Slic3rPolygon(pptr->Contour);
+ for(auto h : pptr->Childs) { processHole(h, poly); }
+ retv.push_back(poly);
+ };
+
+ // Body of the processHole function
+ processHole = [&processPoly](ClipperLib::PolyNode *pptr, ExPolygon& poly)
+ {
+ poly.holes.emplace_back();
+ poly.holes.back().points = ClipperPath_to_Slic3rPolygon(pptr->Contour);
+ for(auto c : pptr->Childs) processPoly(c);
+ };
+
+ // Wrapper for traversing.
+ auto traverse = [&processPoly] (ClipperLib::PolyNode *node)
+ {
+ for(auto ch : node->Childs) {
+ processPoly(ch);
+ }
+ };
+
+ // Here is the actual traverse
+ traverse(&result);
+
+ return retv;
+}
+
+inline Point centroid(Points& pp) {
+ Point c;
+ switch(pp.size()) {
+ case 0: break;
+ case 1: c = pp.front(); break;
+ case 2: c = (pp[0] + pp[1]) / 2; break;
+ default: {
+ Polygon p;
+ p.points.swap(pp);
+ c = p.centroid();
+ pp.swap(p.points);
+ break;
+ }
+ }
+
+ return c;
+}
+
+inline Point centroid(const ExPolygon& poly) {
+ return poly.contour.centroid();
+}
+
+/// A fake concave hull that is constructed by connecting separate shapes
+/// with explicit bridges. Bridges are generated from each shape's centroid
+/// to the center of the "scene" which is the centroid calculated from the shape
+/// centroids (a star is created...)
+inline ExPolygons concave_hull(const ExPolygons& polys, double max_dist_mm = 50)
+{
+ if(polys.empty()) return ExPolygons();
+
+ ExPolygons punion = unify(polys); // could be redundant
+
+ if(punion.size() == 1) return punion;
+
+ // We get the centroids of all the islands in the 2D slice
+ Points centroids; centroids.reserve(punion.size());
+ std::transform(punion.begin(), punion.end(), std::back_inserter(centroids),
+ [](const ExPolygon& poly) { return centroid(poly); });
+
+ // Centroid of the centroids of islands. This is where the additional
+ // connector sticks are routed.
+ Point cc = centroid(centroids);
+
+ punion.reserve(punion.size() + centroids.size());
+
+ std::transform(centroids.begin(), centroids.end(),
+ std::back_inserter(punion),
+ [cc, max_dist_mm](const Point& c) {
+
+ double dx = x(c) - x(cc), dy = y(c) - y(cc);
+ double l = std::sqrt(dx * dx + dy * dy);
+ double nx = dx / l, ny = dy / l;
+ double max_dist = mm(max_dist_mm);
+
+ if(l > max_dist) return ExPolygon();
+
+ ExPolygon r;
+ auto& ctour = r.contour.points;
+
+ ctour.reserve(3);
+ ctour.emplace_back(cc);
+
+ Point d(coord_t(mm(1)*nx), coord_t(mm(1)*ny));
+ ctour.emplace_back(c + Point( -y(d), x(d) ));
+ ctour.emplace_back(c + Point( y(d), -x(d) ));
+ offset(r, mm(1));
+
+ return r;
+ });
+
+ punion = unify(punion);
+
+ return punion;
+}
+
+}
+
+void ground_layer(const TriangleMesh &mesh, ExPolygons &output, float h)
+{
+ TriangleMesh m = mesh;
+ TriangleMeshSlicer slicer(&m);
+
+ std::vector<ExPolygons> tmp;
+
+ slicer.slice({h}, &tmp, [](){});
+
+ output = tmp.front();
+}
+
+void create_base_pool(const ExPolygons &ground_layer, TriangleMesh& out,
+ double min_wall_thickness_mm,
+ double min_wall_height_mm,
+ double max_merge_distance_mm)
+{
+ auto concavehs = concave_hull(ground_layer, max_merge_distance_mm);
+ for(ExPolygon& concaveh : concavehs) {
+ if(concaveh.contour.points.empty()) return;
+ concaveh.holes.clear();
+
+ BoundingBox bb(concaveh);
+ coord_t w = x(bb.max) - x(bb.min);
+ coord_t h = y(bb.max) - y(bb.min);
+
+ auto wall_thickness = coord_t((w+h)*0.01);
+
+ const coord_t WALL_THICKNESS = mm(min_wall_thickness_mm) +
+ wall_thickness;
+
+ const coord_t WALL_DISTANCE = coord_t(0.3*WALL_THICKNESS);
+ const coord_t HEIGHT = mm(min_wall_height_mm);
+
+ auto outer_base = concaveh;
+ offset(outer_base, WALL_THICKNESS+WALL_DISTANCE);
+ auto inner_base = outer_base;
+ offset(inner_base, -WALL_THICKNESS);
+ inner_base.holes.clear(); outer_base.holes.clear();
+
+ ExPolygon top_poly;
+ top_poly.contour = outer_base.contour;
+ top_poly.holes.emplace_back(inner_base.contour);
+ auto& tph = top_poly.holes.back().points;
+ std::reverse(tph.begin(), tph.end());
+
+ Contour3D pool;
+
+ ExPolygon ob = outer_base; double wh = 0;
+ auto curvedwalls = round_edges(ob,
+ 1, // radius 1 mm
+ 170, // 170 degrees
+ 0, // z position of the input plane
+ true,
+ ob, wh);
+ pool.merge(curvedwalls);
+
+ ExPolygon ob_contr = ob;
+ ob_contr.holes.clear();
+
+ auto pwalls = walls(ob_contr, inner_base, wh, -min_wall_height_mm);
+ pool.merge(pwalls);
+
+ Polygons top_triangles, bottom_triangles;
+ triangulate(top_poly, top_triangles);
+ triangulate(inner_base, bottom_triangles);
+ auto top_plate = convert(top_triangles, 0, false);
+ auto bottom_plate = convert(bottom_triangles, -HEIGHT, true);
+
+ ob = inner_base; wh = 0;
+ curvedwalls = round_edges(ob,
+ 1, // radius 1 mm
+ 90, // 170 degrees
+ 0, // z position of the input plane
+ false,
+ ob, wh);
+ pool.merge(curvedwalls);
+
+ auto innerbed = inner_bed(ob, min_wall_height_mm/2 + wh, wh);
+
+ pool.merge(top_plate);
+ pool.merge(bottom_plate);
+ pool.merge(innerbed);
+
+ out.merge(mesh(pool));
+ }
+}
+
+}
+}
diff --git a/xs/src/libslic3r/SLABasePool.hpp b/xs/src/libslic3r/SLABasePool.hpp
new file mode 100644
index 000000000..55c94df07
--- /dev/null
+++ b/xs/src/libslic3r/SLABasePool.hpp
@@ -0,0 +1,32 @@
+#ifndef SLASUPPORTPOOL_HPP
+#define SLASUPPORTPOOL_HPP
+
+#include <vector>
+
+namespace Slic3r {
+
+class ExPolygon;
+class TriangleMesh;
+
+namespace sla {
+
+using ExPolygons = std::vector<ExPolygon>;
+
+/// Calculate the polygon representing the slice of the lowest layer of mesh
+void ground_layer(const TriangleMesh& mesh,
+ ExPolygons& output,
+ float height = 0.1f);
+
+/// Calculate the pool for the mesh for SLA printing
+void create_base_pool(const ExPolygons& ground_layer,
+ TriangleMesh& output_mesh,
+ double min_wall_thickness_mm = 2,
+ double min_wall_height_mm = 5,
+ double max_merge_distance_mm = 50
+ );
+
+}
+
+}
+
+#endif // SLASUPPORTPOOL_HPP
diff --git a/xs/src/libslic3r/SVG.cpp b/xs/src/libslic3r/SVG.cpp
index c94db8e74..03f55802e 100644
--- a/xs/src/libslic3r/SVG.cpp
+++ b/xs/src/libslic3r/SVG.cpp
@@ -3,7 +3,7 @@
#include <boost/nowide/cstdio.hpp>
-#define COORD(x) ((float)unscale((x))*10)
+#define COORD(x) (unscale<float>((x))*10)
namespace Slic3r {
@@ -32,8 +32,8 @@ bool SVG::open(const char* afilename, const BoundingBox &bbox, const coord_t bbo
this->f = boost::nowide::fopen(afilename, "w");
if (f == NULL)
return false;
- float w = COORD(bbox.max.x - bbox.min.x + 2 * bbox_offset);
- float h = COORD(bbox.max.y - bbox.min.y + 2 * bbox_offset);
+ float w = COORD(bbox.max(0) - bbox.min(0) + 2 * bbox_offset);
+ float h = COORD(bbox.max(1) - bbox.min(1) + 2 * bbox_offset);
fprintf(this->f,
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n"
@@ -50,7 +50,7 @@ SVG::draw(const Line &line, std::string stroke, coordf_t stroke_width)
{
fprintf(this->f,
" <line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" style=\"stroke: %s; stroke-width: %f\"",
- COORD(line.a.x - origin.x), COORD(line.a.y - origin.y), COORD(line.b.x - origin.x), COORD(line.b.y - origin.y), stroke.c_str(), (stroke_width == 0) ? 1.f : COORD(stroke_width));
+ COORD(line.a(0) - origin(0)), COORD(line.a(1) - origin(1)), COORD(line.b(0) - origin(0)), COORD(line.b(1) - origin(1)), stroke.c_str(), (stroke_width == 0) ? 1.f : COORD(stroke_width));
if (this->arrows)
fprintf(this->f, " marker-end=\"url(#endArrow)\"");
fprintf(this->f, "/>\n");
@@ -58,21 +58,21 @@ SVG::draw(const Line &line, std::string stroke, coordf_t stroke_width)
void SVG::draw(const ThickLine &line, const std::string &fill, const std::string &stroke, coordf_t stroke_width)
{
- Pointf dir(line.b.x-line.a.x, line.b.y-line.a.y);
- Pointf perp(-dir.y, dir.x);
- coordf_t len = sqrt(perp.x*perp.x + perp.y*perp.y);
+ Vec2d dir(line.b(0)-line.a(0), line.b(1)-line.a(1));
+ Vec2d perp(-dir(1), dir(0));
+ coordf_t len = sqrt(perp(0)*perp(0) + perp(1)*perp(1));
coordf_t da = coordf_t(0.5)*line.a_width/len;
coordf_t db = coordf_t(0.5)*line.b_width/len;
fprintf(this->f,
" <polygon points=\"%f,%f %f,%f %f,%f %f,%f\" style=\"fill:%s; stroke: %s; stroke-width: %f\"/>\n",
- COORD(line.a.x-da*perp.x-origin.x),
- COORD(line.a.y-da*perp.y-origin.y),
- COORD(line.b.x-db*perp.x-origin.x),
- COORD(line.b.y-db*perp.y-origin.y),
- COORD(line.b.x+db*perp.x-origin.x),
- COORD(line.b.y+db*perp.y-origin.y),
- COORD(line.a.x+da*perp.x-origin.x),
- COORD(line.a.y+da*perp.y-origin.y),
+ COORD(line.a(0)-da*perp(0)-origin(0)),
+ COORD(line.a(1)-da*perp(1)-origin(1)),
+ COORD(line.b(0)-db*perp(0)-origin(0)),
+ COORD(line.b(1)-db*perp(1)-origin(1)),
+ COORD(line.b(0)+db*perp(0)-origin(0)),
+ COORD(line.b(1)+db*perp(1)-origin(1)),
+ COORD(line.a(0)+da*perp(0)-origin(0)),
+ COORD(line.a(1)+da*perp(1)-origin(1)),
fill.c_str(), stroke.c_str(),
(stroke_width == 0) ? 1.f : COORD(stroke_width));
}
@@ -220,7 +220,7 @@ SVG::draw(const Point &point, std::string fill, coord_t iradius)
{
float radius = (iradius == 0) ? 3.f : COORD(iradius);
std::ostringstream svg;
- svg << " <circle cx=\"" << COORD(point.x - origin.x) << "\" cy=\"" << COORD(point.y - origin.y)
+ svg << " <circle cx=\"" << COORD(point(0) - origin(0)) << "\" cy=\"" << COORD(point(1) - origin(1))
<< "\" r=\"" << radius << "\" "
<< "style=\"stroke: none; fill: " << fill << "\" />";
@@ -287,8 +287,8 @@ SVG::get_path_d(const MultiPoint &mp, bool closed) const
std::ostringstream d;
d << "M ";
for (Points::const_iterator p = mp.points.begin(); p != mp.points.end(); ++p) {
- d << COORD(p->x - origin.x) << " ";
- d << COORD(p->y - origin.y) << " ";
+ d << COORD((*p)(0) - origin(0)) << " ";
+ d << COORD((*p)(1) - origin(1)) << " ";
}
if (closed) d << "z";
return d.str();
@@ -300,8 +300,8 @@ SVG::get_path_d(const ClipperLib::Path &path, double scale, bool closed) const
std::ostringstream d;
d << "M ";
for (ClipperLib::Path::const_iterator p = path.begin(); p != path.end(); ++p) {
- d << COORD(scale * p->X - origin.x) << " ";
- d << COORD(scale * p->Y - origin.y) << " ";
+ d << COORD(scale * p->X - origin(0)) << " ";
+ d << COORD(scale * p->Y - origin(1)) << " ";
}
if (closed) d << "z";
return d.str();
@@ -311,8 +311,8 @@ void SVG::draw_text(const Point &pt, const char *text, const char *color)
{
fprintf(this->f,
"<text x=\"%f\" y=\"%f\" font-family=\"sans-serif\" font-size=\"20px\" fill=\"%s\">%s</text>",
- COORD(pt.x-origin.x),
- COORD(pt.y-origin.y),
+ COORD(pt(0)-origin(0)),
+ COORD(pt(1)-origin(1)),
color, text);
}
@@ -320,13 +320,13 @@ void SVG::draw_legend(const Point &pt, const char *text, const char *color)
{
fprintf(this->f,
"<circle cx=\"%f\" cy=\"%f\" r=\"10\" fill=\"%s\"/>",
- COORD(pt.x-origin.x),
- COORD(pt.y-origin.y),
+ COORD(pt(0)-origin(0)),
+ COORD(pt(1)-origin(1)),
color);
fprintf(this->f,
"<text x=\"%f\" y=\"%f\" font-family=\"sans-serif\" font-size=\"10px\" fill=\"%s\">%s</text>",
- COORD(pt.x-origin.x) + 20.f,
- COORD(pt.y-origin.y),
+ COORD(pt(0)-origin(0)) + 20.f,
+ COORD(pt(1)-origin(1)),
"black", text);
}
diff --git a/xs/src/libslic3r/Slicing.cpp b/xs/src/libslic3r/Slicing.cpp
index e9295d1e3..1bc38502b 100644
--- a/xs/src/libslic3r/Slicing.cpp
+++ b/xs/src/libslic3r/Slicing.cpp
@@ -561,15 +561,15 @@ int generate_layer_height_texture(
void *data, int rows, int cols, bool level_of_detail_2nd_level)
{
// https://github.com/aschn/gnuplot-colorbrewer
- std::vector<Point3> palette_raw;
- palette_raw.push_back(Point3(0x01A, 0x098, 0x050));
- palette_raw.push_back(Point3(0x066, 0x0BD, 0x063));
- palette_raw.push_back(Point3(0x0A6, 0x0D9, 0x06A));
- palette_raw.push_back(Point3(0x0D9, 0x0F1, 0x0EB));
- palette_raw.push_back(Point3(0x0FE, 0x0E6, 0x0EB));
- palette_raw.push_back(Point3(0x0FD, 0x0AE, 0x061));
- palette_raw.push_back(Point3(0x0F4, 0x06D, 0x043));
- palette_raw.push_back(Point3(0x0D7, 0x030, 0x027));
+ std::vector<Vec3crd> palette_raw;
+ palette_raw.push_back(Vec3crd(0x01A, 0x098, 0x050));
+ palette_raw.push_back(Vec3crd(0x066, 0x0BD, 0x063));
+ palette_raw.push_back(Vec3crd(0x0A6, 0x0D9, 0x06A));
+ palette_raw.push_back(Vec3crd(0x0D9, 0x0F1, 0x0EB));
+ palette_raw.push_back(Vec3crd(0x0FE, 0x0E6, 0x0EB));
+ palette_raw.push_back(Vec3crd(0x0FD, 0x0AE, 0x061));
+ palette_raw.push_back(Vec3crd(0x0F4, 0x06D, 0x043));
+ palette_raw.push_back(Vec3crd(0x0D7, 0x030, 0x027));
// Clear the main texture and the 2nd LOD level.
// memset(data, 0, rows * cols * (level_of_detail_2nd_level ? 5 : 4));
@@ -600,25 +600,25 @@ int generate_layer_height_texture(
int idx1 = clamp(0, int(palette_raw.size() - 1), int(floor(idxf)));
int idx2 = std::min(int(palette_raw.size() - 1), idx1 + 1);
coordf_t t = idxf - coordf_t(idx1);
- const Point3 &color1 = palette_raw[idx1];
- const Point3 &color2 = palette_raw[idx2];
+ const Vec3crd &color1 = palette_raw[idx1];
+ const Vec3crd &color2 = palette_raw[idx2];
coordf_t z = cell_to_z * coordf_t(cell);
assert(z >= lo && z <= hi);
// Intensity profile to visualize the layers.
coordf_t intensity = cos(M_PI * 0.7 * (mid - z) / h);
// Color mapping from layer height to RGB.
- Pointf3 color(
- intensity * lerp(coordf_t(color1.x), coordf_t(color2.x), t),
- intensity * lerp(coordf_t(color1.y), coordf_t(color2.y), t),
- intensity * lerp(coordf_t(color1.z), coordf_t(color2.z), t));
+ Vec3d color(
+ intensity * lerp(coordf_t(color1(0)), coordf_t(color2(0)), t),
+ intensity * lerp(coordf_t(color1(1)), coordf_t(color2(1)), t),
+ intensity * lerp(coordf_t(color1(2)), coordf_t(color2(2)), t));
int row = cell / (cols - 1);
int col = cell - row * (cols - 1);
assert(row >= 0 && row < rows);
assert(col >= 0 && col < cols);
unsigned char *ptr = (unsigned char*)data + (row * cols + col) * 4;
- ptr[0] = (unsigned char)clamp<int>(0, 255, int(floor(color.x + 0.5)));
- ptr[1] = (unsigned char)clamp<int>(0, 255, int(floor(color.y + 0.5)));
- ptr[2] = (unsigned char)clamp<int>(0, 255, int(floor(color.z + 0.5)));
+ ptr[0] = (unsigned char)clamp<int>(0, 255, int(floor(color(0) + 0.5)));
+ ptr[1] = (unsigned char)clamp<int>(0, 255, int(floor(color(1) + 0.5)));
+ ptr[2] = (unsigned char)clamp<int>(0, 255, int(floor(color(2) + 0.5)));
ptr[3] = 255;
if (col == 0 && row > 0) {
// Duplicate the first value in a row as a last value of the preceding row.
@@ -636,21 +636,21 @@ int generate_layer_height_texture(
int idx1 = clamp(0, int(palette_raw.size() - 1), int(floor(idxf)));
int idx2 = std::min(int(palette_raw.size() - 1), idx1 + 1);
coordf_t t = idxf - coordf_t(idx1);
- const Point3 &color1 = palette_raw[idx1];
- const Point3 &color2 = palette_raw[idx2];
+ const Vec3crd &color1 = palette_raw[idx1];
+ const Vec3crd &color2 = palette_raw[idx2];
// Color mapping from layer height to RGB.
- Pointf3 color(
- lerp(coordf_t(color1.x), coordf_t(color2.x), t),
- lerp(coordf_t(color1.y), coordf_t(color2.y), t),
- lerp(coordf_t(color1.z), coordf_t(color2.z), t));
+ Vec3d color(
+ lerp(coordf_t(color1(0)), coordf_t(color2(0)), t),
+ lerp(coordf_t(color1(1)), coordf_t(color2(1)), t),
+ lerp(coordf_t(color1(2)), coordf_t(color2(2)), t));
int row = cell / (cols1 - 1);
int col = cell - row * (cols1 - 1);
assert(row >= 0 && row < rows/2);
assert(col >= 0 && col < cols/2);
unsigned char *ptr = data1 + (row * cols1 + col) * 4;
- ptr[0] = (unsigned char)clamp<int>(0, 255, int(floor(color.x + 0.5)));
- ptr[1] = (unsigned char)clamp<int>(0, 255, int(floor(color.y + 0.5)));
- ptr[2] = (unsigned char)clamp<int>(0, 255, int(floor(color.z + 0.5)));
+ ptr[0] = (unsigned char)clamp<int>(0, 255, int(floor(color(0) + 0.5)));
+ ptr[1] = (unsigned char)clamp<int>(0, 255, int(floor(color(1) + 0.5)));
+ ptr[2] = (unsigned char)clamp<int>(0, 255, int(floor(color(2) + 0.5)));
ptr[3] = 255;
if (col == 0 && row > 0) {
// Duplicate the first value in a row as a last value of the preceding row.
diff --git a/xs/src/libslic3r/SlicingAdaptive.cpp b/xs/src/libslic3r/SlicingAdaptive.cpp
index ff0da7636..2ef4aec8c 100644
--- a/xs/src/libslic3r/SlicingAdaptive.cpp
+++ b/xs/src/libslic3r/SlicingAdaptive.cpp
@@ -15,8 +15,8 @@ void SlicingAdaptive::clear()
std::pair<float, float> face_z_span(const stl_facet *f)
{
return std::pair<float, float>(
- std::min(std::min(f->vertex[0].z, f->vertex[1].z), f->vertex[2].z),
- std::max(std::max(f->vertex[0].z, f->vertex[1].z), f->vertex[2].z));
+ std::min(std::min(f->vertex[0](2), f->vertex[1](2)), f->vertex[2](2)),
+ std::max(std::max(f->vertex[0](2), f->vertex[1](2)), f->vertex[2](2)));
}
void SlicingAdaptive::prepare()
@@ -40,7 +40,7 @@ void SlicingAdaptive::prepare()
// 3) Generate Z components of the facet normals.
m_face_normal_z.assign(m_faces.size(), 0.f);
for (size_t iface = 0; iface < m_faces.size(); ++ iface)
- m_face_normal_z[iface] = m_faces[iface]->normal.z;
+ m_face_normal_z[iface] = m_faces[iface]->normal(2);
}
float SlicingAdaptive::cusp_height(float z, float cusp_value, int &current_facet)
diff --git a/xs/src/libslic3r/SupportMaterial.cpp b/xs/src/libslic3r/SupportMaterial.cpp
index d18f9d710..a6b6c1bb8 100644
--- a/xs/src/libslic3r/SupportMaterial.cpp
+++ b/xs/src/libslic3r/SupportMaterial.cpp
@@ -67,9 +67,9 @@ Point export_support_surface_type_legend_to_svg_box_size()
void export_support_surface_type_legend_to_svg(SVG &svg, const Point &pos)
{
// 1st row
- coord_t pos_x0 = pos.x + scale_(1.);
+ coord_t pos_x0 = pos(0) + scale_(1.);
coord_t pos_x = pos_x0;
- coord_t pos_y = pos.y + scale_(1.5);
+ coord_t pos_y = pos(1) + scale_(1.5);
coord_t step_x = scale_(10.);
svg.draw_legend(Point(pos_x, pos_y), "top contact" , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltTopContact));
pos_x += step_x;
@@ -82,7 +82,7 @@ void export_support_surface_type_legend_to_svg(SVG &svg, const Point &pos)
svg.draw_legend(Point(pos_x, pos_y), "bottom contact" , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltBottomContact));
// 2nd row
pos_x = pos_x0;
- pos_y = pos.y+scale_(2.8);
+ pos_y = pos(1)+scale_(2.8);
svg.draw_legend(Point(pos_x, pos_y), "raft interface" , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltRaftInterface));
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "raft base" , support_surface_type_to_color_name(PrintObjectSupportMaterial::sltRaftBase));
@@ -98,8 +98,8 @@ void export_print_z_polygons_to_svg(const char *path, PrintObjectSupportMaterial
for (int i = 0; i < n_layers; ++ i)
bbox.merge(get_extents(layers[i]->polygons));
Point legend_size = export_support_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
for (int i = 0; i < n_layers; ++ i)
@@ -120,8 +120,8 @@ void export_print_z_polygons_and_extrusions_to_svg(
for (int i = 0; i < n_layers; ++ i)
bbox.merge(get_extents(layers[i]->polygons));
Point legend_size = export_support_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
for (int i = 0; i < n_layers; ++ i)
@@ -506,8 +506,8 @@ public:
for (ExPolygon &island : islands) {
BoundingBox bbox = get_extents(island.contour);
- auto it_lower = std::lower_bound(m_island_samples.begin(), m_island_samples.end(), bbox.min - Point(1, 1));
- auto it_upper = std::upper_bound(m_island_samples.begin(), m_island_samples.end(), bbox.max + Point(1, 1));
+ auto it_lower = std::lower_bound(m_island_samples.begin(), m_island_samples.end(), Point(bbox.min - Point(1, 1)));
+ auto it_upper = std::upper_bound(m_island_samples.begin(), m_island_samples.end(), Point(bbox.max + Point(1, 1)));
samples_inside.clear();
for (auto it = it_lower; it != it_upper; ++ it)
if (bbox.contains(*it))
@@ -519,12 +519,12 @@ public:
Points::const_iterator i = contour.points.begin();
Points::const_iterator j = contour.points.end() - 1;
for (; i != contour.points.end(); j = i ++) {
- //FIXME this test is not numerically robust. Particularly, it does not handle horizontal segments at y == point.y well.
- // Does the ray with y == point.y intersect this line segment?
+ //FIXME this test is not numerically robust. Particularly, it does not handle horizontal segments at y == point(1) well.
+ // Does the ray with y == point(1) intersect this line segment?
for (auto &sample_inside : samples_inside) {
- if ((i->y > sample_inside.first.y) != (j->y > sample_inside.first.y)) {
- double x1 = (double)sample_inside.first.x;
- double x2 = (double)i->x + (double)(j->x - i->x) * (double)(sample_inside.first.y - i->y) / (double)(j->y - i->y);
+ if (((*i)(1) > sample_inside.first(1)) != ((*j)(1) > sample_inside.first(1))) {
+ double x1 = (double)sample_inside.first(0);
+ double x2 = (double)(*i)(0) + (double)((*j)(0) - (*i)(0)) * (double)(sample_inside.first(1) - (*i)(1)) / (double)((*j)(1) - (*i)(1));
if (x1 < x2)
sample_inside.second = !sample_inside.second;
}
@@ -585,11 +585,11 @@ private:
const Point &p3 = (pt_min == &expoly.contour.points.back()) ? expoly.contour.points.front() : *(pt_min + 1);
Vector v = (p3 - p2) + (p1 - p2);
- double l2 = double(v.x)*double(v.x)+double(v.y)*double(v.y);
+ double l2 = double(v(0))*double(v(0))+double(v(1))*double(v(1));
if (l2 == 0.)
return p2;
double coef = 20. / sqrt(l2);
- return Point(p2.x + coef * v.x, p2.y + coef * v.y);
+ return Point(p2(0) + coef * v(0), p2(1) + coef * v(1));
}
static Points island_samples(const ExPolygons &expolygons)
@@ -789,7 +789,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
// workaround for Clipper bug, see Slic3r::Polygon::clip_as_polyline()
for (Polyline &polyline : overhang_perimeters)
- polyline.points[0].x += 1;
+ polyline.points[0](0) += 1;
// Trim the perimeters of this layer by the lower layer to get the unsupported pieces of perimeters.
overhang_perimeters = diff_pl(overhang_perimeters, lower_grown_slices);
@@ -2057,11 +2057,11 @@ void LoopInterfaceProcessor::generate(MyLayerExtruded &top_contact_layer, const
const Point &p1 = *(it-1);
const Point &p2 = *it;
// Intersection of a ray (p1, p2) with a circle placed at center_last, with radius of circle_distance.
- const Pointf v_seg(coordf_t(p2.x) - coordf_t(p1.x), coordf_t(p2.y) - coordf_t(p1.y));
- const Pointf v_cntr(coordf_t(p1.x - center_last.x), coordf_t(p1.y - center_last.y));
- coordf_t a = dot(v_seg);
- coordf_t b = 2. * dot(v_seg, v_cntr);
- coordf_t c = dot(v_cntr) - circle_distance * circle_distance;
+ const Vec2d v_seg(coordf_t(p2(0)) - coordf_t(p1(0)), coordf_t(p2(1)) - coordf_t(p1(1)));
+ const Vec2d v_cntr(coordf_t(p1(0) - center_last(0)), coordf_t(p1(1) - center_last(1)));
+ coordf_t a = v_seg.squaredNorm();
+ coordf_t b = 2. * v_seg.dot(v_cntr);
+ coordf_t c = v_cntr.squaredNorm() - circle_distance * circle_distance;
coordf_t disc = b * b - 4. * a * c;
if (disc > 0.) {
// The circle intersects a ray. Avoid the parts of the segment inside the circle.
@@ -2081,7 +2081,7 @@ void LoopInterfaceProcessor::generate(MyLayerExtruded &top_contact_layer, const
}
seg_current_pt = &p1;
seg_current_t = t;
- center_last = Point(p1.x + coord_t(v_seg.x * t), p1.y + coord_t(v_seg.y * t));
+ center_last = Point(p1(0) + coord_t(v_seg(0) * t), p1(1) + coord_t(v_seg(1) * t));
// It has been verified that the new point is far enough from center_last.
// Ensure, that it is far enough from all the centers.
std::pair<const Point*, coordf_t> circle_closest = circle_centers_lookup.find(center_last);
@@ -2100,9 +2100,9 @@ void LoopInterfaceProcessor::generate(MyLayerExtruded &top_contact_layer, const
circle_centers.push_back(center_last);
}
external_loops.push_back(std::move(contour));
- for (Points::const_iterator it_center = circle_centers.begin(); it_center != circle_centers.end(); ++ it_center) {
+ for (const Point &center : circle_centers) {
circles.push_back(circle);
- circles.back().translate(*it_center);
+ circles.back().translate(center);
}
}
}
@@ -2359,7 +2359,7 @@ void modulate_extrusion_by_overlapping_layers(
(fragment_end.is_start ? &polyline.points.front() : &polyline.points.back());
}
private:
- ExtrusionPathFragmentEndPointAccessor& operator=(const ExtrusionPathFragmentEndPointAccessor&);
+ ExtrusionPathFragmentEndPointAccessor& operator=(const ExtrusionPathFragmentEndPointAccessor&) = delete;
const std::vector<ExtrusionPathFragment> &m_path_fragments;
};
const coord_t search_radius = 7;
@@ -2392,7 +2392,7 @@ void modulate_extrusion_by_overlapping_layers(
if (end_and_dist2.first == nullptr) {
// New fragment connecting to pt_current was not found.
// Verify that the last point found is close to the original end point of the unfragmented path.
- //const double d2 = pt_end.distance_to_sq(pt_current);
+ //const double d2 = (pt_end - pt_current).squaredNorm();
//assert(d2 < coordf_t(search_radius * search_radius));
// End of the path.
break;
@@ -2887,9 +2887,9 @@ void PrintObjectSupportMaterial::clip_by_pillars(
BoundingBox bbox;
for (LayersPtr::const_iterator it = top_contacts.begin(); it != top_contacts.end(); ++ it)
bbox.merge(get_extents((*it)->polygons));
- grid.reserve(size_t(ceil(bb.size().x / pillar_spacing)) * size_t(ceil(bb.size().y / pillar_spacing)));
- for (coord_t x = bb.min.x; x <= bb.max.x - pillar_size; x += pillar_spacing) {
- for (coord_t y = bb.min.y; y <= bb.max.y - pillar_size; y += pillar_spacing) {
+ grid.reserve(size_t(ceil(bb.size()(0) / pillar_spacing)) * size_t(ceil(bb.size()(1) / pillar_spacing)));
+ for (coord_t x = bb.min(0); x <= bb.max(0) - pillar_size; x += pillar_spacing) {
+ for (coord_t y = bb.min(1); y <= bb.max(1) - pillar_size; y += pillar_spacing) {
grid.push_back(pillar);
for (size_t i = 0; i < pillar.points.size(); ++ i)
grid.back().points[i].translate(Point(x, y));
diff --git a/xs/src/libslic3r/Surface.cpp b/xs/src/libslic3r/Surface.cpp
index 384540d87..0e9eca7fd 100644
--- a/xs/src/libslic3r/Surface.cpp
+++ b/xs/src/libslic3r/Surface.cpp
@@ -106,9 +106,9 @@ Point export_surface_type_legend_to_svg_box_size()
void export_surface_type_legend_to_svg(SVG &svg, const Point &pos)
{
// 1st row
- coord_t pos_x0 = pos.x + scale_(1.);
+ coord_t pos_x0 = pos(0) + scale_(1.);
coord_t pos_x = pos_x0;
- coord_t pos_y = pos.y + scale_(1.5);
+ coord_t pos_y = pos(1) + scale_(1.5);
coord_t step_x = scale_(10.);
svg.draw_legend(Point(pos_x, pos_y), "perimeter" , surface_type_to_color_name(stPerimeter));
pos_x += step_x;
@@ -121,7 +121,7 @@ void export_surface_type_legend_to_svg(SVG &svg, const Point &pos)
svg.draw_legend(Point(pos_x, pos_y), "invalid" , surface_type_to_color_name(SurfaceType(-1)));
// 2nd row
pos_x = pos_x0;
- pos_y = pos.y+scale_(2.8);
+ pos_y = pos(1)+scale_(2.8);
svg.draw_legend(Point(pos_x, pos_y), "internal" , surface_type_to_color_name(stInternal));
pos_x += step_x;
svg.draw_legend(Point(pos_x, pos_y), "internal solid" , surface_type_to_color_name(stInternalSolid));
diff --git a/xs/src/libslic3r/SurfaceCollection.cpp b/xs/src/libslic3r/SurfaceCollection.cpp
index 42ddf9574..6db599306 100644
--- a/xs/src/libslic3r/SurfaceCollection.cpp
+++ b/xs/src/libslic3r/SurfaceCollection.cpp
@@ -170,8 +170,8 @@ void SurfaceCollection::export_to_svg(const char *path, bool show_labels)
for (Surfaces::const_iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface)
bbox.merge(get_extents(surface->expolygon));
Point legend_size = export_surface_type_legend_to_svg_box_size();
- Point legend_pos(bbox.min.x, bbox.max.y);
- bbox.merge(Point(std::max(bbox.min.x + legend_size.x, bbox.max.x), bbox.max.y + legend_size.y));
+ Point legend_pos(bbox.min(0), bbox.max(1));
+ bbox.merge(Point(std::max(bbox.min(0) + legend_size(0), bbox.max(0)), bbox.max(1) + legend_size(1)));
SVG svg(path, bbox);
const float transparency = 0.5f;
diff --git a/xs/src/libslic3r/TriangleMesh.cpp b/xs/src/libslic3r/TriangleMesh.cpp
index 17b3d98f9..7b8f85b6b 100644
--- a/xs/src/libslic3r/TriangleMesh.cpp
+++ b/xs/src/libslic3r/TriangleMesh.cpp
@@ -1,6 +1,9 @@
#include "TriangleMesh.hpp"
#include "ClipperUtils.hpp"
#include "Geometry.hpp"
+#include "qhull/src/libqhullcpp/Qhull.h"
+#include "qhull/src/libqhullcpp/QhullFacetList.h"
+#include "qhull/src/libqhullcpp/QhullVertexSet.h"
#include <cmath>
#include <deque>
#include <queue>
@@ -10,11 +13,14 @@
#include <utility>
#include <algorithm>
#include <math.h>
+#include <type_traits>
#include <boost/log/trivial.hpp>
#include <tbb/parallel_for.h>
+#include <Eigen/Dense>
+
#if 0
#define DEBUG
#define _DEBUG
@@ -30,13 +36,7 @@
namespace Slic3r {
-TriangleMesh::TriangleMesh()
- : repaired(false)
-{
- stl_initialize(&this->stl);
-}
-
-TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Point3>& facets )
+TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd>& facets )
: repaired(false)
{
stl_initialize(&this->stl);
@@ -51,47 +51,22 @@ TriangleMesh::TriangleMesh(const Pointf3s &points, const std::vector<Point3>& fa
for (int i = 0; i < stl.stats.number_of_facets; i++) {
stl_facet facet;
- facet.normal.x = 0;
- facet.normal.y = 0;
- facet.normal.z = 0;
-
- const Pointf3& ref_f1 = points[facets[i].x];
- facet.vertex[0].x = ref_f1.x;
- facet.vertex[0].y = ref_f1.y;
- facet.vertex[0].z = ref_f1.z;
-
- const Pointf3& ref_f2 = points[facets[i].y];
- facet.vertex[1].x = ref_f2.x;
- facet.vertex[1].y = ref_f2.y;
- facet.vertex[1].z = ref_f2.z;
-
- const Pointf3& ref_f3 = points[facets[i].z];
- facet.vertex[2].x = ref_f3.x;
- facet.vertex[2].y = ref_f3.y;
- facet.vertex[2].z = ref_f3.z;
-
+ facet.vertex[0] = points[facets[i](0)].cast<float>();
+ facet.vertex[1] = points[facets[i](1)].cast<float>();
+ facet.vertex[2] = points[facets[i](2)].cast<float>();
facet.extra[0] = 0;
facet.extra[1] = 0;
+ stl_normal normal;
+ stl_calculate_normal(normal, &facet);
+ stl_normalize_vector(normal);
+ facet.normal = normal;
+
stl.facet_start[i] = facet;
}
stl_get_size(&stl);
}
-TriangleMesh::TriangleMesh(const TriangleMesh &other) :
- repaired(false)
-{
- stl_initialize(&this->stl);
- *this = other;
-}
-
-TriangleMesh::TriangleMesh(TriangleMesh &&other) :
- repaired(false)
-{
- stl_initialize(&this->stl);
- this->swap(other);
-}
-
TriangleMesh& TriangleMesh::operator=(const TriangleMesh &other)
{
stl_close(&this->stl);
@@ -119,42 +94,8 @@ TriangleMesh& TriangleMesh::operator=(const TriangleMesh &other)
return *this;
}
-TriangleMesh& TriangleMesh::operator=(TriangleMesh &&other)
-{
- this->swap(other);
- return *this;
-}
-
-void
-TriangleMesh::swap(TriangleMesh &other)
-{
- std::swap(this->stl, other.stl);
- std::swap(this->repaired, other.repaired);
-}
-
-TriangleMesh::~TriangleMesh() {
- stl_close(&this->stl);
-}
-
-void
-TriangleMesh::ReadSTLFile(const char* input_file) {
- stl_open(&stl, input_file);
-}
-
-void
-TriangleMesh::write_ascii(const char* output_file)
+void TriangleMesh::repair()
{
- stl_write_ascii(&this->stl, output_file, "");
-}
-
-void
-TriangleMesh::write_binary(const char* output_file)
-{
- stl_write_binary(&this->stl, output_file, "");
-}
-
-void
-TriangleMesh::repair() {
if (this->repaired) return;
// admesh fails when repairing empty meshes
@@ -251,13 +192,7 @@ void TriangleMesh::check_topology()
}
}
-bool TriangleMesh::is_manifold() const
-{
- return this->stl.stats.connected_facets_3_edge == this->stl.stats.number_of_facets;
-}
-
-void
-TriangleMesh::reset_repair_stats() {
+void TriangleMesh::reset_repair_stats() {
this->stl.stats.degenerate_facets = 0;
this->stl.stats.edges_fixed = 0;
this->stl.stats.facets_removed = 0;
@@ -267,8 +202,7 @@ TriangleMesh::reset_repair_stats() {
this->stl.stats.normals_fixed = 0;
}
-bool
-TriangleMesh::needed_repair() const
+bool TriangleMesh::needed_repair() const
{
return this->stl.stats.degenerate_facets > 0
|| this->stl.stats.edges_fixed > 0
@@ -278,14 +212,8 @@ TriangleMesh::needed_repair() const
|| this->stl.stats.backwards_edges > 0;
}
-size_t
-TriangleMesh::facets_count() const
+void TriangleMesh::WriteOBJFile(char* output_file)
{
- return this->stl.stats.number_of_facets;
-}
-
-void
-TriangleMesh::WriteOBJFile(char* output_file) {
stl_generate_shared_vertices(&stl);
stl_write_obj(&stl, output_file);
}
@@ -296,13 +224,9 @@ void TriangleMesh::scale(float factor)
stl_invalidate_shared_vertices(&this->stl);
}
-void TriangleMesh::scale(const Pointf3 &versor)
+void TriangleMesh::scale(const Vec3d &versor)
{
- float fversor[3];
- fversor[0] = versor.x;
- fversor[1] = versor.y;
- fversor[2] = versor.z;
- stl_scale_versor(&this->stl, fversor);
+ stl_scale_versor(&this->stl, versor.cast<float>());
stl_invalidate_shared_vertices(&this->stl);
}
@@ -332,19 +256,15 @@ void TriangleMesh::rotate(float angle, const Axis &axis)
stl_invalidate_shared_vertices(&this->stl);
}
-void TriangleMesh::rotate_x(float angle)
+void TriangleMesh::rotate(float angle, const Vec3d& axis)
{
- this->rotate(angle, X);
-}
-
-void TriangleMesh::rotate_y(float angle)
-{
- this->rotate(angle, Y);
-}
+ if (angle == 0.f)
+ return;
-void TriangleMesh::rotate_z(float angle)
-{
- this->rotate(angle, Z);
+ Vec3f axis_norm = axis.cast<float>().normalized();
+ Transform3f m = Transform3f::Identity();
+ m.rotate(Eigen::AngleAxisf(angle, axis_norm));
+ stl_transform(&stl, m);
}
void TriangleMesh::mirror(const Axis &axis)
@@ -359,46 +279,27 @@ void TriangleMesh::mirror(const Axis &axis)
stl_invalidate_shared_vertices(&this->stl);
}
-void TriangleMesh::mirror_x()
-{
- this->mirror(X);
-}
-
-void TriangleMesh::mirror_y()
-{
- this->mirror(Y);
-}
-
-void TriangleMesh::mirror_z()
+void TriangleMesh::transform(const Transform3f& t)
{
- this->mirror(Z);
-}
-
-void TriangleMesh::transform(const float* matrix3x4)
-{
- if (matrix3x4 == nullptr)
- return;
-
- stl_transform(&stl, const_cast<float*>(matrix3x4));
- stl_invalidate_shared_vertices(&stl);
+ stl_transform(&stl, t);
}
void TriangleMesh::align_to_origin()
{
this->translate(
- -(this->stl.stats.min.x),
- -(this->stl.stats.min.y),
- -(this->stl.stats.min.z)
- );
+ - this->stl.stats.min(0),
+ - this->stl.stats.min(1),
+ - this->stl.stats.min(2));
}
void TriangleMesh::rotate(double angle, Point* center)
{
if (angle == 0.)
return;
- this->translate(float(-center->x), float(-center->y), 0);
+ Vec2f c = center->cast<float>();
+ this->translate(-c(0), -c(1), 0);
stl_rotate_z(&(this->stl), (float)angle);
- this->translate(float(+center->x), float(+center->y), 0);
+ this->translate(c(0), c(1), 0);
}
bool TriangleMesh::has_multiple_patches() const
@@ -471,14 +372,14 @@ size_t TriangleMesh::number_of_patches() const
return num_bodies;
}
-TriangleMeshPtrs
-TriangleMesh::split() const
+TriangleMeshPtrs TriangleMesh::split() const
{
- TriangleMeshPtrs meshes;
- std::set<int> seen_facets;
+ TriangleMeshPtrs meshes;
+ std::vector<unsigned char> facet_visited(this->stl.stats.number_of_facets, false);
// we need neighbors
- if (!this->repaired) CONFESS("split() requires repair()");
+ if (!this->repaired)
+ CONFESS("split() requires repair()");
// loop while we have remaining facets
for (;;) {
@@ -486,46 +387,45 @@ TriangleMesh::split() const
std::queue<int> facet_queue;
std::deque<int> facets;
for (int facet_idx = 0; facet_idx < this->stl.stats.number_of_facets; facet_idx++) {
- if (seen_facets.find(facet_idx) == seen_facets.end()) {
+ if (! facet_visited[facet_idx]) {
// if facet was not seen put it into queue and start searching
facet_queue.push(facet_idx);
break;
}
}
- if (facet_queue.empty()) break;
-
- while (!facet_queue.empty()) {
+ if (facet_queue.empty())
+ break;
+
+ while (! facet_queue.empty()) {
int facet_idx = facet_queue.front();
facet_queue.pop();
- if (seen_facets.find(facet_idx) != seen_facets.end()) continue;
- facets.push_back(facet_idx);
- for (int j = 0; j <= 2; j++) {
- facet_queue.push(this->stl.neighbors_start[facet_idx].neighbor[j]);
+ if (! facet_visited[facet_idx]) {
+ facets.emplace_back(facet_idx);
+ for (int j = 0; j < 3; ++ j)
+ facet_queue.push(this->stl.neighbors_start[facet_idx].neighbor[j]);
+ facet_visited[facet_idx] = true;
}
- seen_facets.insert(facet_idx);
}
-
+
TriangleMesh* mesh = new TriangleMesh;
- meshes.push_back(mesh);
+ meshes.emplace_back(mesh);
mesh->stl.stats.type = inmemory;
mesh->stl.stats.number_of_facets = facets.size();
mesh->stl.stats.original_num_facets = mesh->stl.stats.number_of_facets;
stl_clear_error(&mesh->stl);
stl_allocate(&mesh->stl);
- int first = 1;
- for (std::deque<int>::const_iterator facet = facets.begin(); facet != facets.end(); ++facet) {
+ bool first = true;
+ for (std::deque<int>::const_iterator facet = facets.begin(); facet != facets.end(); ++ facet) {
mesh->stl.facet_start[facet - facets.begin()] = this->stl.facet_start[*facet];
stl_facet_stats(&mesh->stl, this->stl.facet_start[*facet], first);
- first = 0;
}
}
return meshes;
}
-void
-TriangleMesh::merge(const TriangleMesh &mesh)
+void TriangleMesh::merge(const TriangleMesh &mesh)
{
// reset stats and metadata
int number_of_facets = this->stl.stats.number_of_facets;
@@ -556,45 +456,165 @@ ExPolygons TriangleMesh::horizontal_projection() const
stl_facet* facet = &this->stl.facet_start[i];
Polygon p;
p.points.resize(3);
- p.points[0] = Point::new_scale(facet->vertex[0].x, facet->vertex[0].y);
- p.points[1] = Point::new_scale(facet->vertex[1].x, facet->vertex[1].y);
- p.points[2] = Point::new_scale(facet->vertex[2].x, facet->vertex[2].y);
+ p.points[0] = Point::new_scale(facet->vertex[0](0), facet->vertex[0](1));
+ p.points[1] = Point::new_scale(facet->vertex[1](0), facet->vertex[1](1));
+ p.points[2] = Point::new_scale(facet->vertex[2](0), facet->vertex[2](1));
p.make_counter_clockwise(); // do this after scaling, as winding order might change while doing that
- pp.push_back(p);
+ pp.emplace_back(p);
}
// the offset factor was tuned using groovemount.stl
return union_ex(offset(pp, scale_(0.01)), true);
}
+const float* TriangleMesh::first_vertex() const
+{
+ return this->stl.facet_start ? &this->stl.facet_start->vertex[0](0) : nullptr;
+}
+
Polygon TriangleMesh::convex_hull()
{
this->require_shared_vertices();
Points pp;
pp.reserve(this->stl.stats.shared_vertices);
for (int i = 0; i < this->stl.stats.shared_vertices; ++ i) {
- stl_vertex* v = &this->stl.v_shared[i];
- pp.emplace_back(Point::new_scale(v->x, v->y));
+ const stl_vertex &v = this->stl.v_shared[i];
+ pp.emplace_back(Point::new_scale(v(0), v(1)));
}
return Slic3r::Geometry::convex_hull(pp);
}
-BoundingBoxf3
-TriangleMesh::bounding_box() const
+BoundingBoxf3 TriangleMesh::bounding_box() const
{
BoundingBoxf3 bb;
bb.defined = true;
- bb.min.x = this->stl.stats.min.x;
- bb.min.y = this->stl.stats.min.y;
- bb.min.z = this->stl.stats.min.z;
- bb.max.x = this->stl.stats.max.x;
- bb.max.y = this->stl.stats.max.y;
- bb.max.z = this->stl.stats.max.z;
+ bb.min = this->stl.stats.min.cast<double>();
+ bb.max = this->stl.stats.max.cast<double>();
return bb;
}
-void
-TriangleMesh::require_shared_vertices()
+BoundingBoxf3 TriangleMesh::transformed_bounding_box(const Transform3d& t) const
+{
+ bool has_shared = (stl.v_shared != nullptr);
+ if (!has_shared)
+ stl_generate_shared_vertices(&stl);
+
+ unsigned int vertices_count = (stl.stats.shared_vertices > 0) ? (unsigned int)stl.stats.shared_vertices : 3 * (unsigned int)stl.stats.number_of_facets;
+
+ if (vertices_count == 0)
+ return BoundingBoxf3();
+
+ Eigen::MatrixXd src_vertices(3, vertices_count);
+
+ if (stl.stats.shared_vertices > 0)
+ {
+ stl_vertex* vertex_ptr = stl.v_shared;
+ for (int i = 0; i < stl.stats.shared_vertices; ++i)
+ {
+ src_vertices(0, i) = (double)(*vertex_ptr)(0);
+ src_vertices(1, i) = (double)(*vertex_ptr)(1);
+ src_vertices(2, i) = (double)(*vertex_ptr)(2);
+ vertex_ptr += 1;
+ }
+ }
+ else
+ {
+ 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)
+ {
+ src_vertices(0, v_id) = (double)facet_ptr->vertex[i](0);
+ src_vertices(1, v_id) = (double)facet_ptr->vertex[i](1);
+ src_vertices(2, v_id) = (double)facet_ptr->vertex[i](2);
+ ++v_id;
+ }
+ facet_ptr += 1;
+ }
+ }
+
+ if (!has_shared && (stl.stats.shared_vertices > 0))
+ stl_invalidate_shared_vertices(&stl);
+
+ Eigen::MatrixXd dst_vertices(3, vertices_count);
+ dst_vertices = t * src_vertices.colwise().homogeneous();
+
+ Vec3d v_min(dst_vertices(0, 0), dst_vertices(1, 0), dst_vertices(2, 0));
+ Vec3d v_max = v_min;
+
+ for (int i = 1; i < vertices_count; ++i)
+ {
+ for (int j = 0; j < 3; ++j)
+ {
+ v_min(j) = std::min(v_min(j), dst_vertices(j, i));
+ v_max(j) = std::max(v_max(j), dst_vertices(j, i));
+ }
+ }
+
+ return BoundingBoxf3(v_min, v_max);
+}
+
+TriangleMesh TriangleMesh::convex_hull_3d() const
+{
+ // Helper struct for qhull:
+ struct PointForQHull{
+ PointForQHull(float x_p, float y_p, float z_p) : x((realT)x_p), y((realT)y_p), z((realT)z_p) {}
+ realT x, y, z;
+ };
+ std::vector<PointForQHull> src_vertices;
+
+ // We will now fill the vector with input points for computation:
+ stl_facet* facet_ptr = stl.facet_start;
+ while (facet_ptr < stl.facet_start + stl.stats.number_of_facets)
+ {
+ for (int i = 0; i < 3; ++i)
+ {
+ const stl_vertex& v = facet_ptr->vertex[i];
+ src_vertices.emplace_back(v(0), v(1), v(2));
+ }
+
+ facet_ptr += 1;
+ }
+
+ // The qhull call:
+ orgQhull::Qhull qhull;
+ qhull.disableOutputStream(); // we want qhull to be quiet
+ try
+ {
+ qhull.runQhull("", 3, (int)src_vertices.size(), (const realT*)(src_vertices.data()), "Qt");
+ }
+ catch (...)
+ {
+ std::cout << "Unable to create convex hull" << std::endl;
+ return TriangleMesh();
+ }
+
+ // Let's collect results:
+ Pointf3s dst_vertices;
+ std::vector<Vec3crd> facets;
+ auto facet_list = qhull.facetList().toStdVector();
+ for (const orgQhull::QhullFacet& facet : facet_list)
+ { // iterate through facets
+ orgQhull::QhullVertexSet vertices = facet.vertices();
+ for (int i = 0; i < 3; ++i)
+ { // iterate through facet's vertices
+
+ orgQhull::QhullPoint p = vertices[i].point();
+ const float* coords = p.coordinates();
+ dst_vertices.emplace_back(coords[0], coords[1], coords[2]);
+ }
+ unsigned int size = (unsigned int)dst_vertices.size();
+ facets.emplace_back(size - 3, size - 2, size - 1);
+ }
+
+ TriangleMesh output_mesh(dst_vertices, facets);
+ output_mesh.repair();
+ output_mesh.require_shared_vertices();
+ return output_mesh;
+}
+
+void TriangleMesh::require_shared_vertices()
{
BOOST_LOG_TRIVIAL(trace) << "TriangleMeshSlicer::require_shared_vertices - start";
if (!this->repaired)
@@ -614,11 +634,8 @@ void TriangleMeshSlicer::init(TriangleMesh *_mesh, throw_on_cancel_callback_type
facets_edges.assign(_mesh->stl.stats.number_of_facets * 3, -1);
v_scaled_shared.assign(_mesh->stl.v_shared, _mesh->stl.v_shared + _mesh->stl.stats.shared_vertices);
// Scale the copied vertices.
- for (int i = 0; i < this->mesh->stl.stats.shared_vertices; ++ i) {
- this->v_scaled_shared[i].x /= float(SCALING_FACTOR);
- this->v_scaled_shared[i].y /= float(SCALING_FACTOR);
- this->v_scaled_shared[i].z /= float(SCALING_FACTOR);
- }
+ for (int i = 0; i < this->mesh->stl.stats.shared_vertices; ++ i)
+ this->v_scaled_shared[i] *= float(1. / SCALING_FACTOR);
// Create a mapping from triangle edge into face.
struct EdgeToFace {
@@ -783,14 +800,14 @@ void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vector<IntersectionLin
const stl_facet &facet = this->mesh->stl.facet_start[facet_idx];
// find facet extents
- const float min_z = fminf(facet.vertex[0].z, fminf(facet.vertex[1].z, facet.vertex[2].z));
- const float max_z = fmaxf(facet.vertex[0].z, fmaxf(facet.vertex[1].z, facet.vertex[2].z));
+ const float min_z = fminf(facet.vertex[0](2), fminf(facet.vertex[1](2), facet.vertex[2](2)));
+ const float max_z = fmaxf(facet.vertex[0](2), fmaxf(facet.vertex[1](2), facet.vertex[2](2)));
#ifdef SLIC3R_DEBUG
printf("\n==> FACET %d (%f,%f,%f - %f,%f,%f - %f,%f,%f):\n", facet_idx,
- facet.vertex[0].x, facet.vertex[0].y, facet.vertex[0].z,
- facet.vertex[1].x, facet.vertex[1].y, facet.vertex[1].z,
- facet.vertex[2].x, facet.vertex[2].y, facet.vertex[2].z);
+ facet.vertex[0].x, facet.vertex[0].y, facet.vertex[0](2),
+ facet.vertex[1].x, facet.vertex[1].y, facet.vertex[1](2),
+ facet.vertex[2].x, facet.vertex[2].y, facet.vertex[2](2));
printf("z: min = %.2f, max = %.2f\n", min_z, max_z);
#endif
@@ -810,24 +827,24 @@ void TriangleMeshSlicer::_slice_do(size_t facet_idx, std::vector<IntersectionLin
if (il.edge_type == feHorizontal) {
// Insert all three edges of the face.
const int *vertices = this->mesh->stl.v_indices[facet_idx].vertex;
- const bool reverse = this->mesh->stl.facet_start[facet_idx].normal.z < 0;
+ const bool reverse = this->mesh->stl.facet_start[facet_idx].normal(2) < 0;
for (int j = 0; j < 3; ++ j) {
int a_id = vertices[j % 3];
int b_id = vertices[(j+1) % 3];
if (reverse)
std::swap(a_id, b_id);
- const stl_vertex *a = &this->v_scaled_shared[a_id];
- const stl_vertex *b = &this->v_scaled_shared[b_id];
- il.a.x = a->x;
- il.a.y = a->y;
- il.b.x = b->x;
- il.b.y = b->y;
+ const stl_vertex &a = this->v_scaled_shared[a_id];
+ const stl_vertex &b = this->v_scaled_shared[b_id];
+ il.a(0) = a(0);
+ il.a(1) = a(1);
+ il.b(0) = b(0);
+ il.b(1) = b(1);
il.a_id = a_id;
il.b_id = b_id;
- (*lines)[layer_idx].push_back(il);
+ (*lines)[layer_idx].emplace_back(il);
}
} else
- (*lines)[layer_idx].push_back(il);
+ (*lines)[layer_idx].emplace_back(il);
}
}
}
@@ -867,66 +884,63 @@ bool TriangleMeshSlicer::slice_facet(
// Reorder vertices so that the first one is the one with lowest Z.
// This is needed to get all intersection lines in a consistent order
// (external on the right of the line)
- int i = (facet.vertex[1].z == min_z) ? 1 : ((facet.vertex[2].z == min_z) ? 2 : 0);
+ int i = (facet.vertex[1](2) == min_z) ? 1 : ((facet.vertex[2](2) == min_z) ? 2 : 0);
for (int j = i; j - i < 3; ++ j) { // loop through facet edges
int edge_id = this->facets_edges[facet_idx * 3 + (j % 3)];
const int *vertices = this->mesh->stl.v_indices[facet_idx].vertex;
int a_id = vertices[j % 3];
int b_id = vertices[(j+1) % 3];
- const stl_vertex *a = &this->v_scaled_shared[a_id];
- const stl_vertex *b = &this->v_scaled_shared[b_id];
+ const stl_vertex &a = this->v_scaled_shared[a_id];
+ const stl_vertex &b = this->v_scaled_shared[b_id];
// Is edge or face aligned with the cutting plane?
- if (a->z == slice_z && b->z == slice_z) {
+ if (a(2) == slice_z && b(2) == slice_z) {
// Edge is horizontal and belongs to the current layer.
const stl_vertex &v0 = this->v_scaled_shared[vertices[0]];
const stl_vertex &v1 = this->v_scaled_shared[vertices[1]];
const stl_vertex &v2 = this->v_scaled_shared[vertices[2]];
+ bool swap = false;
if (min_z == max_z) {
// All three vertices are aligned with slice_z.
line_out->edge_type = feHorizontal;
- if (this->mesh->stl.facet_start[facet_idx].normal.z < 0) {
+ if (this->mesh->stl.facet_start[facet_idx].normal(2) < 0) {
// If normal points downwards this is a bottom horizontal facet so we reverse its point order.
- std::swap(a, b);
- std::swap(a_id, b_id);
+ swap = true;
}
- } else if (v0.z < slice_z || v1.z < slice_z || v2.z < slice_z) {
+ } else if (v0(2) < slice_z || v1(2) < slice_z || v2(2) < slice_z) {
// Two vertices are aligned with the cutting plane, the third vertex is below the cutting plane.
line_out->edge_type = feTop;
- std::swap(a, b);
- std::swap(a_id, b_id);
+ swap = true;
} else {
// Two vertices are aligned with the cutting plane, the third vertex is above the cutting plane.
line_out->edge_type = feBottom;
}
- line_out->a.x = a->x;
- line_out->a.y = a->y;
- line_out->b.x = b->x;
- line_out->b.y = b->y;
- line_out->a_id = a_id;
- line_out->b_id = b_id;
+ line_out->a = to_2d(swap ? b : a).cast<coord_t>();
+ line_out->b = to_2d(swap ? a : b).cast<coord_t>();
+ line_out->a_id = swap ? b_id : a_id;
+ line_out->b_id = swap ? a_id : b_id;
return true;
}
- if (a->z == slice_z) {
+ if (a(2) == slice_z) {
// Only point a alings with the cutting plane.
points_on_layer[num_points_on_layer ++] = num_points;
IntersectionPoint &point = points[num_points ++];
- point.x = a->x;
- point.y = a->y;
+ point(0) = a(0);
+ point(1) = a(1);
point.point_id = a_id;
- } else if (b->z == slice_z) {
+ } else if (b(2) == slice_z) {
// Only point b alings with the cutting plane.
points_on_layer[num_points_on_layer ++] = num_points;
IntersectionPoint &point = points[num_points ++];
- point.x = b->x;
- point.y = b->y;
+ point(0) = b(0);
+ point(1) = b(1);
point.point_id = b_id;
- } else if ((a->z < slice_z && b->z > slice_z) || (b->z < slice_z && a->z > slice_z)) {
+ } else if ((a(2) < slice_z && b(2) > slice_z) || (b(2) < slice_z && a(2) > slice_z)) {
// A general case. The face edge intersects the cutting plane. Calculate the intersection point.
IntersectionPoint &point = points[num_points ++];
- point.x = b->x + (a->x - b->x) * (slice_z - b->z) / (a->z - b->z);
- point.y = b->y + (a->y - b->y) * (slice_z - b->z) / (a->z - b->z);
+ point(0) = b(0) + (a(0) - b(0)) * (slice_z - b(2)) / (a(2) - b(2));
+ point(1) = b(1) + (a(1) - b(1)) * (slice_z - b(2)) / (a(2) - b(2));
point.edge_id = edge_id;
}
}
@@ -1197,8 +1211,8 @@ void TriangleMeshSlicer::make_loops(std::vector<IntersectionLine> &lines, Polygo
if ((ip1.edge_id != -1 && ip1.edge_id == ip2.edge_id) ||
(ip1.point_id != -1 && ip1.point_id == ip2.point_id)) {
// The current loop is complete. Add it to the output.
- assert(opl.points.front().point_id == opl.points.back().point_id);
- assert(opl.points.front().edge_id == opl.points.back().edge_id);
+ /*assert(opl.points.front().point_id == opl.points.back().point_id);
+ assert(opl.points.front().edge_id == opl.points.back().edge_id);*/
// Remove the duplicate last point.
opl.points.pop_back();
if (opl.points.size() >= 3) {
@@ -1207,7 +1221,7 @@ void TriangleMeshSlicer::make_loops(std::vector<IntersectionLine> &lines, Polygo
// Orient the patched up polygons CCW. This heuristic may close some holes and cavities.
double area = 0.;
for (size_t i = 0, j = opl.points.size() - 1; i < opl.points.size(); j = i ++)
- area += double(opl.points[j].x + opl.points[i].x) * double(opl.points[i].y - opl.points[j].y);
+ area += double(opl.points[j](0) + opl.points[i](0)) * double(opl.points[i](1) - opl.points[j](1));
if (area < 0)
std::reverse(opl.points.begin(), opl.points.end());
loops->emplace_back(std::move(opl.points));
@@ -1234,9 +1248,9 @@ void TriangleMeshSlicer::make_expolygons_simple(std::vector<IntersectionLine> &l
if (loop->area() >= 0.) {
ExPolygon ex;
ex.contour = *loop;
- slices->push_back(ex);
+ slices->emplace_back(ex);
} else {
- holes.push_back(*loop);
+ holes.emplace_back(*loop);
}
}
@@ -1327,8 +1341,8 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic
//std::vector<double> area;
//std::vector<size_t> sorted_area; // vector of indices
//for (Polygons::const_iterator loop = loops.begin(); loop != loops.end(); ++ loop) {
- // area.push_back(loop->area());
- // sorted_area.push_back(loop - loops.begin());
+ // area.emplace_back(loop->area());
+ // sorted_area.emplace_back(loop - loops.begin());
//}
//
//// outer first
@@ -1343,7 +1357,7 @@ void TriangleMeshSlicer::make_expolygons(const Polygons &loops, ExPolygons* slic
// would do the same, thus repeating the calculation */
// Polygons::const_iterator loop = loops.begin() + *loop_idx;
// if (area[*loop_idx] > +EPSILON)
- // p_slices.push_back(*loop);
+ // p_slices.emplace_back(*loop);
// else if (area[*loop_idx] < -EPSILON)
// //FIXME This is arbitrary and possibly very slow.
// // If the hole is inside a polygon, then there is no need to diff.
@@ -1393,20 +1407,20 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
stl_facet* facet = &this->mesh->stl.facet_start[facet_idx];
// find facet extents
- float min_z = std::min(facet->vertex[0].z, std::min(facet->vertex[1].z, facet->vertex[2].z));
- float max_z = std::max(facet->vertex[0].z, std::max(facet->vertex[1].z, facet->vertex[2].z));
+ float min_z = std::min(facet->vertex[0](2), std::min(facet->vertex[1](2), facet->vertex[2](2)));
+ float max_z = std::max(facet->vertex[0](2), std::max(facet->vertex[1](2), facet->vertex[2](2)));
// intersect facet with cutting plane
IntersectionLine line;
if (this->slice_facet(scaled_z, *facet, facet_idx, min_z, max_z, &line)) {
// Save intersection lines for generating correct triangulations.
if (line.edge_type == feTop) {
- lower_lines.push_back(line);
+ lower_lines.emplace_back(line);
} else if (line.edge_type == feBottom) {
- upper_lines.push_back(line);
+ upper_lines.emplace_back(line);
} else if (line.edge_type != feHorizontal) {
- lower_lines.push_back(line);
- upper_lines.push_back(line);
+ lower_lines.emplace_back(line);
+ upper_lines.emplace_back(line);
}
}
@@ -1421,47 +1435,47 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
// look for the vertex on whose side of the slicing plane there are no other vertices
int isolated_vertex;
- if ( (facet->vertex[0].z > z) == (facet->vertex[1].z > z) ) {
+ if ( (facet->vertex[0](2) > z) == (facet->vertex[1](2) > z) ) {
isolated_vertex = 2;
- } else if ( (facet->vertex[1].z > z) == (facet->vertex[2].z > z) ) {
+ } else if ( (facet->vertex[1](2) > z) == (facet->vertex[2](2) > z) ) {
isolated_vertex = 0;
} else {
isolated_vertex = 1;
}
// get vertices starting from the isolated one
- stl_vertex* v0 = &facet->vertex[isolated_vertex];
- stl_vertex* v1 = &facet->vertex[(isolated_vertex+1) % 3];
- stl_vertex* v2 = &facet->vertex[(isolated_vertex+2) % 3];
+ const stl_vertex &v0 = facet->vertex[isolated_vertex];
+ const stl_vertex &v1 = facet->vertex[(isolated_vertex+1) % 3];
+ const stl_vertex &v2 = facet->vertex[(isolated_vertex+2) % 3];
// intersect v0-v1 and v2-v0 with cutting plane and make new vertices
stl_vertex v0v1, v2v0;
- v0v1.x = v1->x + (v0->x - v1->x) * (z - v1->z) / (v0->z - v1->z);
- v0v1.y = v1->y + (v0->y - v1->y) * (z - v1->z) / (v0->z - v1->z);
- v0v1.z = z;
- v2v0.x = v2->x + (v0->x - v2->x) * (z - v2->z) / (v0->z - v2->z);
- v2v0.y = v2->y + (v0->y - v2->y) * (z - v2->z) / (v0->z - v2->z);
- v2v0.z = z;
+ v0v1(0) = v1(0) + (v0(0) - v1(0)) * (z - v1(2)) / (v0(2) - v1(2));
+ v0v1(1) = v1(1) + (v0(1) - v1(1)) * (z - v1(2)) / (v0(2) - v1(2));
+ v0v1(2) = z;
+ v2v0(0) = v2(0) + (v0(0) - v2(0)) * (z - v2(2)) / (v0(2) - v2(2));
+ v2v0(1) = v2(1) + (v0(1) - v2(1)) * (z - v2(2)) / (v0(2) - v2(2));
+ v2v0(2) = z;
// build the triangular facet
stl_facet triangle;
triangle.normal = facet->normal;
- triangle.vertex[0] = *v0;
+ triangle.vertex[0] = v0;
triangle.vertex[1] = v0v1;
triangle.vertex[2] = v2v0;
// build the facets forming a quadrilateral on the other side
stl_facet quadrilateral[2];
quadrilateral[0].normal = facet->normal;
- quadrilateral[0].vertex[0] = *v1;
- quadrilateral[0].vertex[1] = *v2;
+ quadrilateral[0].vertex[0] = v1;
+ quadrilateral[0].vertex[1] = v2;
quadrilateral[0].vertex[2] = v0v1;
quadrilateral[1].normal = facet->normal;
- quadrilateral[1].vertex[0] = *v2;
+ quadrilateral[1].vertex[0] = v2;
quadrilateral[1].vertex[1] = v2v0;
quadrilateral[1].vertex[2] = v0v1;
- if (v0->z > z) {
+ if (v0(2) > z) {
if (upper != NULL) stl_add_facet(&upper->stl, &triangle);
if (lower != NULL) {
stl_add_facet(&lower->stl, &quadrilateral[0]);
@@ -1493,13 +1507,11 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
Polygon p = *polygon;
p.reverse();
stl_facet facet;
- facet.normal.x = 0;
- facet.normal.y = 0;
- facet.normal.z = -1;
+ facet.normal = stl_normal(0, 0, -1.f);
for (size_t i = 0; i <= 2; ++i) {
- facet.vertex[i].x = unscale(p.points[i].x);
- facet.vertex[i].y = unscale(p.points[i].y);
- facet.vertex[i].z = z;
+ facet.vertex[i](0) = unscale<float>(p.points[i](0));
+ facet.vertex[i](1) = unscale<float>(p.points[i](1));
+ facet.vertex[i](2) = z;
}
stl_add_facet(&upper->stl, &facet);
}
@@ -1519,13 +1531,11 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
// convert triangles to facets and append them to mesh
for (Polygons::const_iterator polygon = triangles.begin(); polygon != triangles.end(); ++polygon) {
stl_facet facet;
- facet.normal.x = 0;
- facet.normal.y = 0;
- facet.normal.z = 1;
+ facet.normal = stl_normal(0, 0, 1.f);
for (size_t i = 0; i <= 2; ++i) {
- facet.vertex[i].x = unscale(polygon->points[i].x);
- facet.vertex[i].y = unscale(polygon->points[i].y);
- facet.vertex[i].z = z;
+ facet.vertex[i](0) = unscale<float>(polygon->points[i](0));
+ facet.vertex[i](1) = unscale<float>(polygon->points[i](1));
+ facet.vertex[i](2) = z;
}
stl_add_facet(&lower->stl, &facet);
}
@@ -1538,19 +1548,19 @@ void TriangleMeshSlicer::cut(float z, TriangleMesh* upper, TriangleMesh* lower)
// Generate the vertex list for a cube solid of arbitrary size in X/Y/Z.
TriangleMesh make_cube(double x, double y, double z) {
- Pointf3 pv[8] = {
- Pointf3(x, y, 0), Pointf3(x, 0, 0), Pointf3(0, 0, 0),
- Pointf3(0, y, 0), Pointf3(x, y, z), Pointf3(0, y, z),
- Pointf3(0, 0, z), Pointf3(x, 0, z)
+ Vec3d pv[8] = {
+ Vec3d(x, y, 0), Vec3d(x, 0, 0), Vec3d(0, 0, 0),
+ Vec3d(0, y, 0), Vec3d(x, y, z), Vec3d(0, y, z),
+ Vec3d(0, 0, z), Vec3d(x, 0, z)
};
- Point3 fv[12] = {
- Point3(0, 1, 2), Point3(0, 2, 3), Point3(4, 5, 6),
- Point3(4, 6, 7), Point3(0, 4, 7), Point3(0, 7, 1),
- Point3(1, 7, 6), Point3(1, 6, 2), Point3(2, 6, 5),
- Point3(2, 5, 3), Point3(4, 0, 3), Point3(4, 3, 5)
+ Vec3crd fv[12] = {
+ Vec3crd(0, 1, 2), Vec3crd(0, 2, 3), Vec3crd(4, 5, 6),
+ Vec3crd(4, 6, 7), Vec3crd(0, 4, 7), Vec3crd(0, 7, 1),
+ Vec3crd(1, 7, 6), Vec3crd(1, 6, 2), Vec3crd(2, 6, 5),
+ Vec3crd(2, 5, 3), Vec3crd(4, 0, 3), Vec3crd(4, 3, 5)
};
- std::vector<Point3> facets(&fv[0], &fv[0]+12);
+ std::vector<Vec3crd> facets(&fv[0], &fv[0]+12);
Pointf3s vertices(&pv[0], &pv[0]+8);
TriangleMesh mesh(vertices ,facets);
@@ -1562,11 +1572,11 @@ TriangleMesh make_cube(double x, double y, double z) {
// Default is 360 sides, angle fa is in radians.
TriangleMesh make_cylinder(double r, double h, double fa) {
Pointf3s vertices;
- std::vector<Point3> facets;
+ std::vector<Vec3crd> facets;
// 2 special vertices, top and bottom center, rest are relative to this
- vertices.push_back(Pointf3(0.0, 0.0, 0.0));
- vertices.push_back(Pointf3(0.0, 0.0, h));
+ vertices.emplace_back(Vec3d(0.0, 0.0, 0.0));
+ vertices.emplace_back(Vec3d(0.0, 0.0, h));
// adjust via rounding to get an even multiple for any provided angle.
double angle = (2*PI / floor(2*PI / fa));
@@ -1576,26 +1586,23 @@ TriangleMesh make_cylinder(double r, double h, double fa) {
// top and bottom.
// Special case: Last line shares 2 vertices with the first line.
unsigned id = vertices.size() - 1;
- vertices.push_back(Pointf3(sin(0) * r , cos(0) * r, 0));
- vertices.push_back(Pointf3(sin(0) * r , cos(0) * r, h));
+ vertices.emplace_back(Vec3d(sin(0) * r , cos(0) * r, 0));
+ vertices.emplace_back(Vec3d(sin(0) * r , cos(0) * r, h));
for (double i = 0; i < 2*PI; i+=angle) {
- Pointf3 b(0, r, 0);
- Pointf3 t(0, r, h);
- b.rotate(i, Pointf3(0,0,0));
- t.rotate(i, Pointf3(0,0,h));
- vertices.push_back(b);
- vertices.push_back(t);
+ Vec2d p = Eigen::Rotation2Dd(i) * Eigen::Vector2d(0, r);
+ vertices.emplace_back(Vec3d(p(0), p(1), 0.));
+ vertices.emplace_back(Vec3d(p(0), p(1), h));
id = vertices.size() - 1;
- facets.push_back(Point3( 0, id - 1, id - 3)); // top
- facets.push_back(Point3(id, 1, id - 2)); // bottom
- facets.push_back(Point3(id, id - 2, id - 3)); // upper-right of side
- facets.push_back(Point3(id, id - 3, id - 1)); // bottom-left of side
+ facets.emplace_back(Vec3crd( 0, id - 1, id - 3)); // top
+ facets.emplace_back(Vec3crd(id, 1, id - 2)); // bottom
+ facets.emplace_back(Vec3crd(id, id - 2, id - 3)); // upper-right of side
+ facets.emplace_back(Vec3crd(id, id - 3, id - 1)); // bottom-left of side
}
// Connect the last set of vertices with the first.
- facets.push_back(Point3( 2, 0, id - 1));
- facets.push_back(Point3( 1, 3, id));
- facets.push_back(Point3(id, 3, 2));
- facets.push_back(Point3(id, 2, id - 1));
+ facets.emplace_back(Vec3crd( 2, 0, id - 1));
+ facets.emplace_back(Vec3crd( 1, 3, id));
+ facets.emplace_back(Vec3crd(id, 3, 2));
+ facets.emplace_back(Vec3crd(id, 2, id - 1));
TriangleMesh mesh(vertices, facets);
return mesh;
@@ -1606,7 +1613,7 @@ TriangleMesh make_cylinder(double r, double h, double fa) {
// Default angle is 1 degree.
TriangleMesh make_sphere(double rho, double fa) {
Pointf3s vertices;
- std::vector<Point3> facets;
+ std::vector<Vec3crd> facets;
// Algorithm:
// Add points one-by-one to the sphere grid and form facets using relative coordinates.
@@ -1618,29 +1625,24 @@ TriangleMesh make_sphere(double rho, double fa) {
// Ring to be scaled to generate the steps of the sphere
std::vector<double> ring;
for (double i = 0; i < 2*PI; i+=angle) {
- ring.push_back(i);
+ ring.emplace_back(i);
}
const size_t steps = ring.size();
const double increment = (double)(1.0 / (double)steps);
// special case: first ring connects to 0,0,0
// insert and form facets.
- vertices.push_back(Pointf3(0.0, 0.0, -rho));
+ vertices.emplace_back(Vec3d(0.0, 0.0, -rho));
size_t id = vertices.size();
for (size_t i = 0; i < ring.size(); i++) {
// Fixed scaling
const double z = -rho + increment*rho*2.0;
// radius of the circle for this step.
const double r = sqrt(abs(rho*rho - z*z));
- Pointf3 b(0, r, z);
- b.rotate(ring[i], Pointf3(0,0,z));
- vertices.push_back(b);
- if (i == 0) {
- facets.push_back(Point3(1, 0, ring.size()));
- } else {
- facets.push_back(Point3(id, 0, id - 1));
- }
- id++;
+ Vec2d b = Eigen::Rotation2Dd(ring[i]) * Eigen::Vector2d(0, r);
+ vertices.emplace_back(Vec3d(b(0), b(1), z));
+ facets.emplace_back((i == 0) ? Vec3crd(1, 0, ring.size()) : Vec3crd(id, 0, id - 1));
+ ++ id;
}
// General case: insert and form facets for each step, joining it to the ring below it.
@@ -1649,16 +1651,15 @@ TriangleMesh make_sphere(double rho, double fa) {
const double r = sqrt(abs(rho*rho - z*z));
for (size_t i = 0; i < ring.size(); i++) {
- Pointf3 b(0, r, z);
- b.rotate(ring[i], Pointf3(0,0,z));
- vertices.push_back(b);
+ Vec2d b = Eigen::Rotation2Dd(ring[i]) * Eigen::Vector2d(0, r);
+ vertices.emplace_back(Vec3d(b(0), b(1), z));
if (i == 0) {
// wrap around
- facets.push_back(Point3(id + ring.size() - 1 , id, id - 1));
- facets.push_back(Point3(id, id - ring.size(), id - 1));
+ facets.emplace_back(Vec3crd(id + ring.size() - 1 , id, id - 1));
+ facets.emplace_back(Vec3crd(id, id - ring.size(), id - 1));
} else {
- facets.push_back(Point3(id , id - ring.size(), (id - 1) - ring.size()));
- facets.push_back(Point3(id, id - 1 - ring.size() , id - 1));
+ facets.emplace_back(Vec3crd(id , id - ring.size(), (id - 1) - ring.size()));
+ facets.emplace_back(Vec3crd(id, id - 1 - ring.size() , id - 1));
}
id++;
}
@@ -1667,13 +1668,13 @@ TriangleMesh make_sphere(double rho, double fa) {
// special case: last ring connects to 0,0,rho*2.0
// only form facets.
- vertices.push_back(Pointf3(0.0, 0.0, rho));
+ vertices.emplace_back(Vec3d(0.0, 0.0, rho));
for (size_t i = 0; i < ring.size(); i++) {
if (i == 0) {
// third vertex is on the other side of the ring.
- facets.push_back(Point3(id, id - ring.size(), id - 1));
+ facets.emplace_back(Vec3crd(id, id - ring.size(), id - 1));
} else {
- facets.push_back(Point3(id, id - ring.size() + i, id - ring.size() + (i - 1)));
+ facets.emplace_back(Vec3crd(id, id - ring.size() + i, id - ring.size() + (i - 1)));
}
}
id++;
diff --git a/xs/src/libslic3r/TriangleMesh.hpp b/xs/src/libslic3r/TriangleMesh.hpp
index 9a09975cd..ed3e6022d 100644
--- a/xs/src/libslic3r/TriangleMesh.hpp
+++ b/xs/src/libslic3r/TriangleMesh.hpp
@@ -21,44 +21,50 @@ typedef std::vector<TriangleMesh*> TriangleMeshPtrs;
class TriangleMesh
{
public:
- TriangleMesh();
- TriangleMesh(const Pointf3s &points, const std::vector<Point3> &facets);
- TriangleMesh(const TriangleMesh &other);
- TriangleMesh(TriangleMesh &&other);
+ TriangleMesh() : repaired(false) { stl_initialize(&this->stl); }
+ TriangleMesh(const Pointf3s &points, const std::vector<Vec3crd> &facets);
+ TriangleMesh(const TriangleMesh &other) : repaired(false) { stl_initialize(&this->stl); *this = other; }
+ TriangleMesh(TriangleMesh &&other) : repaired(false) { stl_initialize(&this->stl); this->swap(other); }
+ ~TriangleMesh() { stl_close(&this->stl); }
TriangleMesh& operator=(const TriangleMesh &other);
- TriangleMesh& operator=(TriangleMesh &&other);
- void swap(TriangleMesh &other);
- ~TriangleMesh();
- void ReadSTLFile(const char* input_file);
- void write_ascii(const char* output_file);
- void write_binary(const char* output_file);
+ TriangleMesh& operator=(TriangleMesh &&other) { this->swap(other); return *this; }
+ void swap(TriangleMesh &other) { std::swap(this->stl, other.stl); std::swap(this->repaired, other.repaired); }
+ void ReadSTLFile(const char* input_file) { stl_open(&stl, input_file); }
+ void write_ascii(const char* output_file) { stl_write_ascii(&this->stl, output_file, ""); }
+ void write_binary(const char* output_file) { stl_write_binary(&this->stl, output_file, ""); }
void repair();
float volume();
void check_topology();
- bool is_manifold() const;
+ bool is_manifold() const { return this->stl.stats.connected_facets_3_edge == this->stl.stats.number_of_facets; }
void WriteOBJFile(char* output_file);
void scale(float factor);
- void scale(const Pointf3 &versor);
+ void scale(const Vec3d &versor);
void translate(float x, float y, float z);
void rotate(float angle, const Axis &axis);
- void rotate_x(float angle);
- void rotate_y(float angle);
- void rotate_z(float angle);
+ void rotate(float angle, const Vec3d& axis);
+ void rotate_x(float angle) { this->rotate(angle, X); }
+ void rotate_y(float angle) { this->rotate(angle, Y); }
+ void rotate_z(float angle) { this->rotate(angle, Z); }
void mirror(const Axis &axis);
- void mirror_x();
- void mirror_y();
- void mirror_z();
- void transform(const float* matrix3x4);
+ void mirror_x() { this->mirror(X); }
+ void mirror_y() { this->mirror(Y); }
+ void mirror_z() { this->mirror(Z); }
+ void transform(const Transform3f& t);
void align_to_origin();
void rotate(double angle, Point* center);
TriangleMeshPtrs split() const;
void merge(const TriangleMesh &mesh);
ExPolygons horizontal_projection() const;
+ const float* first_vertex() const;
Polygon convex_hull();
BoundingBoxf3 bounding_box() const;
+ // Returns the bbox of this TriangleMesh transformed by the given transformation
+ BoundingBoxf3 transformed_bounding_box(const Transform3d& t) const;
+ // Returns the convex hull of this TriangleMesh
+ TriangleMesh convex_hull_3d() const;
void reset_repair_stats();
bool needed_repair() const;
- size_t facets_count() const;
+ size_t facets_count() const { return this->stl.stats.number_of_facets; }
// Returns true, if there are two and more connected patches in the mesh.
// Returns false, if one or zero connected patch is in the mesh.
@@ -67,7 +73,7 @@ public:
// Count disconnected triangle patches.
size_t number_of_patches() const;
- stl_file stl;
+ mutable stl_file stl;
bool repaired;
private:
diff --git a/xs/src/libslic3r/Utils.hpp b/xs/src/libslic3r/Utils.hpp
index 27e7fad6b..f1390b8a2 100644
--- a/xs/src/libslic3r/Utils.hpp
+++ b/xs/src/libslic3r/Utils.hpp
@@ -3,6 +3,8 @@
#include <locale>
+#include "libslic3r.h"
+
namespace Slic3r {
extern void set_logging_level(unsigned int level);
@@ -60,8 +62,8 @@ extern std::string timestamp_str();
// to be placed at the top of Slic3r generated files.
inline std::string header_slic3r_generated() { return std::string("generated by " SLIC3R_FORK_NAME " " SLIC3R_VERSION " " ) + timestamp_str(); }
-// Encode a file into a multi-part HTTP response with a given boundary.
-std::string octoprint_encode_file_send_request_content(const char *path, bool select, bool print, const char *boundary);
+// getpid platform wrapper
+extern unsigned get_current_pid();
// Compute the next highest power of 2 of 32-bit v
// http://graphics.stanford.edu/~seander/bithacks.html
@@ -82,6 +84,28 @@ inline T next_highest_power_of_2(T v)
return ++ v;
}
+extern std::string xml_escape(std::string text);
+
+class PerlCallback {
+public:
+ PerlCallback(void *sv) : m_callback(nullptr) { this->register_callback(sv); }
+ PerlCallback() : m_callback(nullptr) {}
+ ~PerlCallback() { this->deregister_callback(); }
+ void register_callback(void *sv);
+ void deregister_callback();
+ void call() const;
+ void call(int i) const;
+ void call(int i, int j) const;
+ void call(const std::vector<int>& ints) const;
+ void call(double a) const;
+ void call(double a, double b) const;
+ void call(double a, double b, double c) const;
+ void call(double a, double b, double c, double d) const;
+ void call(bool b) const;
+private:
+ void *m_callback;
+};
+
} // namespace Slic3r
#endif // slic3r_Utils_hpp_
diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h
index 0f192c37c..925e93031 100644
--- a/xs/src/libslic3r/libslic3r.h
+++ b/xs/src/libslic3r/libslic3r.h
@@ -14,7 +14,7 @@
#include <boost/thread.hpp>
#define SLIC3R_FORK_NAME "Slic3r Prusa Edition"
-#define SLIC3R_VERSION "1.39.0"
+#define SLIC3R_VERSION "1.41.0"
#define SLIC3R_BUILD "UNKNOWN"
typedef int32_t coord_t;
@@ -45,7 +45,6 @@ typedef double coordf_t;
//FIXME Better to use an inline function with an explicit return type.
//inline coord_t scale_(coordf_t v) { return coord_t(floor(v / SCALING_FACTOR + 0.5f)); }
#define scale_(val) ((val) / SCALING_FACTOR)
-#define unscale(val) ((val) * SCALING_FACTOR)
#define SCALED_EPSILON scale_(EPSILON)
/* Implementation of CONFESS("foo"): */
#ifdef _MSC_VER
@@ -102,6 +101,9 @@ inline std::string debug_out_path(const char *name, ...)
namespace Slic3r {
+template<typename T, typename Q>
+inline T unscale(Q v) { return T(v) * T(SCALING_FACTOR); }
+
enum Axis { X=0, Y, Z, E, F, NUM_AXES };
template <class T>
@@ -130,6 +132,17 @@ inline void append(std::vector<T>& dest, std::vector<T>&& src)
src.shrink_to_fit();
}
+// Casting an std::vector<> from one type to another type without warnings about a loss of accuracy.
+template<typename T_TO, typename T_FROM>
+std::vector<T_TO> cast(const std::vector<T_FROM> &src)
+{
+ std::vector<T_TO> dst;
+ dst.reserve(src.size());
+ for (const T_FROM &a : src)
+ dst.emplace_back((T_TO)a);
+ return dst;
+}
+
template <typename T>
inline void remove_nulls(std::vector<T*> &vec)
{
diff --git a/xs/src/libslic3r/utils.cpp b/xs/src/libslic3r/utils.cpp
index 34b9eaa9f..95aaf5453 100644
--- a/xs/src/libslic3r/utils.cpp
+++ b/xs/src/libslic3r/utils.cpp
@@ -1,6 +1,15 @@
+#include "Utils.hpp"
+#include "I18N.hpp"
+
#include <locale>
#include <ctime>
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
@@ -87,7 +96,7 @@ const std::string& var_dir()
std::string var(const std::string &file_name)
{
- auto file = boost::filesystem::canonical(boost::filesystem::path(g_var_dir) / file_name).make_preferred();
+ auto file = (boost::filesystem::path(g_var_dir) / file_name).make_preferred();
return file.string();
}
@@ -115,6 +124,9 @@ const std::string& localization_dir()
return g_local_dir;
}
+// Translate function callback, to call wxWidgets translate function to convert non-localized UTF8 string to a localized one.
+Slic3r::I18N::translate_fn_type Slic3r::I18N::translate_fn = nullptr;
+
static std::string g_data_dir;
void set_data_dir(const std::string &dir)
@@ -129,44 +141,6 @@ const std::string& data_dir()
} // namespace Slic3r
-#ifdef SLIC3R_HAS_BROKEN_CROAK
-
-// Some Strawberry Perl builds (mainly the latest 64bit builds) have a broken mechanism
-// for emiting Perl exception after handling a C++ exception. Perl interpreter
-// simply hangs. Better to show a message box in that case and stop the application.
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef WIN32
-#include <Windows.h>
-#endif
-
-void confess_at(const char *file, int line, const char *func, const char *format, ...)
-{
- char dest[1024*8];
- va_list argptr;
- va_start(argptr, format);
- vsprintf(dest, format, argptr);
- va_end(argptr);
-
- char filelinefunc[1024*8];
- sprintf(filelinefunc, "\r\nin function: %s\r\nfile: %s\r\nline: %d\r\n", func, file, line);
- strcat(dest, filelinefunc);
- strcat(dest, "\r\n Closing the application.\r\n");
- #ifdef WIN32
- ::MessageBoxA(NULL, dest, "Slic3r Prusa Edition", MB_OK | MB_ICONERROR);
- #endif
-
- // Give up.
- printf(dest);
- exit(-1);
-}
-
-#else
-
#include <xsinit.h>
void
@@ -196,7 +170,157 @@ confess_at(const char *file, int line, const char *func,
#endif
}
-#endif
+void PerlCallback::register_callback(void *sv)
+{
+ if (! SvROK((SV*)sv) || SvTYPE(SvRV((SV*)sv)) != SVt_PVCV)
+ croak("Not a Callback %_ for PerlFunction", (SV*)sv);
+ if (m_callback)
+ SvSetSV((SV*)m_callback, (SV*)sv);
+ else
+ m_callback = newSVsv((SV*)sv);
+}
+
+void PerlCallback::deregister_callback()
+{
+ if (m_callback) {
+ sv_2mortal((SV*)m_callback);
+ m_callback = nullptr;
+ }
+}
+
+void PerlCallback::call() const
+{
+ if (! m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+
+void PerlCallback::call(int i) const
+{
+ if (! m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(newSViv(i)));
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+
+void PerlCallback::call(int i, int j) const
+{
+ if (! m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(newSViv(i)));
+ XPUSHs(sv_2mortal(newSViv(j)));
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+
+void PerlCallback::call(const std::vector<int>& ints) const
+{
+ if (! m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ for (int i : ints)
+ {
+ XPUSHs(sv_2mortal(newSViv(i)));
+ }
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+
+void PerlCallback::call(double a) const
+{
+ if (!m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(newSVnv(a)));
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+
+void PerlCallback::call(double a, double b) const
+{
+ if (!m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(newSVnv(a)));
+ XPUSHs(sv_2mortal(newSVnv(b)));
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+
+void PerlCallback::call(double a, double b, double c) const
+{
+ if (!m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(newSVnv(a)));
+ XPUSHs(sv_2mortal(newSVnv(b)));
+ XPUSHs(sv_2mortal(newSVnv(c)));
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+
+void PerlCallback::call(double a, double b, double c, double d) const
+{
+ if (!m_callback)
+ return;
+ dSP;
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv_2mortal(newSVnv(a)));
+ XPUSHs(sv_2mortal(newSVnv(b)));
+ XPUSHs(sv_2mortal(newSVnv(c)));
+ XPUSHs(sv_2mortal(newSVnv(d)));
+ PUTBACK;
+ perl_call_sv(SvRV((SV*)m_callback), G_DISCARD);
+ FREETMPS;
+ LEAVE;
+}
+
+void PerlCallback::call(bool b) const
+{
+ call(b ? 1 : 0);
+}
#ifdef WIN32
#ifndef NOMINMAX
@@ -263,7 +387,6 @@ namespace PerlUtils {
std::string timestamp_str()
{
const auto now = boost::posix_time::second_clock::local_time();
- const auto date = now.date();
char buf[2048];
sprintf(buf, "on %04d-%02d-%02d at %02d:%02d:%02d",
// Local date in an ANSII format.
@@ -272,31 +395,40 @@ std::string timestamp_str()
return buf;
}
-std::string octoprint_encode_file_send_request_content(const char *cpath, bool select, bool print, const char *boundary)
+unsigned get_current_pid()
+{
+#ifdef WIN32
+ return GetCurrentProcessId();
+#else
+ return ::getpid();
+#endif
+}
+
+std::string xml_escape(std::string text)
{
- // Read the complete G-code string into a string buffer.
- // It will throw if the file cannot be open or read.
- std::stringstream str_stream;
+ std::string::size_type pos = 0;
+ for (;;)
{
- boost::nowide::ifstream ifs(cpath);
- str_stream << ifs.rdbuf();
+ pos = text.find_first_of("\"\'&<>", pos);
+ if (pos == std::string::npos)
+ break;
+
+ std::string replacement;
+ switch (text[pos])
+ {
+ case '\"': replacement = "&quot;"; break;
+ case '\'': replacement = "&apos;"; break;
+ case '&': replacement = "&amp;"; break;
+ case '<': replacement = "&lt;"; break;
+ case '>': replacement = "&gt;"; break;
+ default: break;
+ }
+
+ text.replace(pos, 1, replacement);
+ pos += replacement.size();
}
- boost::filesystem::path path(cpath);
- std::string request = boundary + '\n';
- request += "Content-Disposition: form-data; name=\"";
- request += path.stem().string() + "\"; filename=\"" + path.filename().string() + "\"\n";
- request += "Content-Type: application/octet-stream\n\n";
- request += str_stream.str();
- request += boundary + '\n';
- request += "Content-Disposition: form-data; name=\"select\"\n\n";
- request += select ? "true\n" : "false\n";
- request += boundary + '\n';
- request += "Content-Disposition: form-data; name=\"print\"\n\n";
- request += print ? "true\n" : "false\n";
- request += boundary + '\n';
-
- return request;
+ return text;
}
}; // namespace Slic3r
diff --git a/xs/src/perlglue.cpp b/xs/src/perlglue.cpp
index 58d553966..68fbcd612 100644
--- a/xs/src/perlglue.cpp
+++ b/xs/src/perlglue.cpp
@@ -41,9 +41,8 @@ REGISTER_CLASS(BoundingBoxf, "Geometry::BoundingBoxf");
REGISTER_CLASS(BoundingBoxf3, "Geometry::BoundingBoxf3");
REGISTER_CLASS(BridgeDetector, "BridgeDetector");
REGISTER_CLASS(Point, "Point");
-REGISTER_CLASS(Point3, "Point3");
-REGISTER_CLASS(Pointf, "Pointf");
-REGISTER_CLASS(Pointf3, "Pointf3");
+__REGISTER_CLASS(Vec2d, "Pointf");
+__REGISTER_CLASS(Vec3d, "Pointf3");
REGISTER_CLASS(DynamicPrintConfig, "Config");
REGISTER_CLASS(StaticPrintConfig, "Config::Static");
REGISTER_CLASS(PrintObjectConfig, "Config::PrintObject");
@@ -63,9 +62,12 @@ REGISTER_CLASS(GLVolumeCollection, "GUI::_3DScene::GLVolume::Collection");
REGISTER_CLASS(Preset, "GUI::Preset");
REGISTER_CLASS(PresetCollection, "GUI::PresetCollection");
REGISTER_CLASS(PresetBundle, "GUI::PresetBundle");
-REGISTER_CLASS(PresetHints, "GUI::PresetHints");
REGISTER_CLASS(TabIface, "GUI::Tab");
-REGISTER_CLASS(OctoPrint, "OctoPrint");
+REGISTER_CLASS(ProgressStatusBar, "GUI::ProgressStatusBar");
+REGISTER_CLASS(PresetUpdater, "PresetUpdater");
+REGISTER_CLASS(AppController, "AppController");
+REGISTER_CLASS(PrintController, "PrintController");
+REGISTER_CLASS(PrintHost, "PrintHost");
SV* ConfigBase__as_hash(ConfigBase* THIS)
{
@@ -132,7 +134,7 @@ SV* ConfigOption_to_SV(const ConfigOption &opt, const ConfigOptionDef &def)
auto optv = static_cast<const ConfigOptionPoints*>(&opt);
AV* av = newAV();
av_fill(av, optv->values.size()-1);
- for (const Pointf &v : optv->values)
+ for (const Vec2d &v : optv->values)
av_store(av, &v - optv->values.data(), perl_to_SV_clone_ref(v));
return newRV_noinc((SV*)av);
}
@@ -262,14 +264,14 @@ bool ConfigBase__set(ConfigBase* THIS, const t_config_option_key &opt_key, SV* v
return from_SV_check(value, &static_cast<ConfigOptionPoint*>(opt)->value);
case coPoints:
{
- std::vector<Pointf> &values = static_cast<ConfigOptionPoints*>(opt)->values;
+ std::vector<Vec2d> &values = static_cast<ConfigOptionPoints*>(opt)->values;
AV* av = (AV*)SvRV(value);
const size_t len = av_len(av)+1;
values.clear();
values.reserve(len);
for (size_t i = 0; i < len; i++) {
SV** elem = av_fetch(av, i, 0);
- Pointf point;
+ Vec2d point(Vec2d::Zero());
if (elem == NULL || !from_SV_check(*elem, &point)) return false;
values.emplace_back(point);
}
@@ -484,8 +486,8 @@ SV* to_SV_pureperl(const Point* THIS)
{
AV* av = newAV();
av_fill(av, 1);
- av_store(av, 0, newSViv(THIS->x));
- av_store(av, 1, newSViv(THIS->y));
+ av_store(av, 0, newSViv((*THIS)(0)));
+ av_store(av, 1, newSViv((*THIS)(1)));
return newRV_noinc((SV*)av);
}
@@ -494,8 +496,7 @@ void from_SV(SV* point_sv, Point* point)
AV* point_av = (AV*)SvRV(point_sv);
// get a double from Perl and round it, otherwise
// it would get truncated
- point->x = lrint(SvNV(*av_fetch(point_av, 0, 0)));
- point->y = lrint(SvNV(*av_fetch(point_av, 1, 0)));
+ (*point) = Point(SvNV(*av_fetch(point_av, 0, 0)), SvNV(*av_fetch(point_av, 1, 0)));
}
void from_SV_check(SV* point_sv, Point* point)
@@ -509,33 +510,32 @@ void from_SV_check(SV* point_sv, Point* point)
}
}
-SV* to_SV_pureperl(const Pointf* point)
+SV* to_SV_pureperl(const Vec2d* point)
{
AV* av = newAV();
av_fill(av, 1);
- av_store(av, 0, newSVnv(point->x));
- av_store(av, 1, newSVnv(point->y));
+ av_store(av, 0, newSVnv((*point)(0)));
+ av_store(av, 1, newSVnv((*point)(1)));
return newRV_noinc((SV*)av);
}
-bool from_SV(SV* point_sv, Pointf* point)
+bool from_SV(SV* point_sv, Vec2d* point)
{
AV* point_av = (AV*)SvRV(point_sv);
SV* sv_x = *av_fetch(point_av, 0, 0);
SV* sv_y = *av_fetch(point_av, 1, 0);
if (!looks_like_number(sv_x) || !looks_like_number(sv_y)) return false;
- point->x = SvNV(sv_x);
- point->y = SvNV(sv_y);
+ *point = Vec2d(SvNV(sv_x), SvNV(sv_y));
return true;
}
-bool from_SV_check(SV* point_sv, Pointf* point)
+bool from_SV_check(SV* point_sv, Vec2d* point)
{
if (sv_isobject(point_sv) && (SvTYPE(SvRV(point_sv)) == SVt_PVMG)) {
if (!sv_isa(point_sv, perl_class_name(point)) && !sv_isa(point_sv, perl_class_name_ref(point)))
CONFESS("Not a valid %s object (got %s)", perl_class_name(point), HvNAME(SvSTASH(SvRV(point_sv))));
- *point = *(Pointf*)SvIV((SV*)SvRV( point_sv ));
+ *point = *(Vec2d*)SvIV((SV*)SvRV( point_sv ));
return true;
} else {
return from_SV(point_sv, point);
diff --git a/xs/src/png/AUTHORS b/xs/src/png/AUTHORS
new file mode 100644
index 000000000..25aad54dc
--- /dev/null
+++ b/xs/src/png/AUTHORS
@@ -0,0 +1,4 @@
+png++ is written by Alexander Shulgin (alex dot shulgin at gmail dot com)
+Copyright (C) 2007,2008
+
+When writing to me be sure to put png++: in the subject :-)
diff --git a/xs/src/png/COPYING b/xs/src/png/COPYING
new file mode 100644
index 000000000..04889ba11
--- /dev/null
+++ b/xs/src/png/COPYING
@@ -0,0 +1,25 @@
+Copying png++ is subject to the following license:
+
+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.
diff --git a/xs/src/png/NEWS b/xs/src/png/NEWS
new file mode 100644
index 000000000..cc006fbf5
--- /dev/null
+++ b/xs/src/png/NEWS
@@ -0,0 +1,60 @@
+Version 0.2.7:
+
+ - Added solid_pixel_buffer (patch by Andrey Potapov).
+
+ - Fixed some compilation problems on Win32.
+
+Version 0.2.5:
+
+ - Fixed compatibility with newer libpng versions (>= 1.4)
+
+ - Fixed compilation on FreeBSD.
+
+ - Fixed tRNS handling with transformations.
+
+ - Added IO transformation debugging facility.
+
+ - Better organized test suite.
+
+Version 0.2.3:
+
+ - Fixed numerous `already defined' errors due to require_color_space
+ implementation.
+
+ - Added `config.hpp'.
+
+ - Fixed `strerror' usage.
+
+ - Minor docs fixes.
+
+
+Version 0.2.1:
+
+ - Added support for tRNS chunk.
+
+ - Added non-std IO streams support.
+
+ - Fixed 16-bit endianness problems.
+
+ - Improved test script.
+
+
+Version 0.2.0:
+
+ - Added support for 16-bit data (RGB, RGBA, Grayscale and Gray+Alpha
+ color types)
+
+ - Added support for packed 1-, 2- or 4-bit pixels (Grayscale and
+ Indexed colors)
+
+ - Fixed interlace handling code which was severely broken
+
+ - Added possibility to process images without reading the entire
+ image into memory
+
+ - Internals are refactored while the client interface is mostly
+ unchanged
+
+ - Added intensive test suite
+
+ - Added documentation
diff --git a/xs/src/png/color.hpp b/xs/src/png/color.hpp
new file mode 100644
index 000000000..b5ffde2c4
--- /dev/null
+++ b/xs/src/png/color.hpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_COLOR_HPP_INCLUDED
+#define PNGPP_COLOR_HPP_INCLUDED
+
+#include "types.hpp"
+
+namespace png
+{
+
+ /**
+ * \brief PNG color struct extension. Adds constructors.
+ */
+ struct color
+ : png_color
+ {
+ explicit color(byte r = 0, byte g = 0, byte b = 0)
+ {
+ this->red = r;
+ this->green = g;
+ this->blue = b;
+ }
+
+ /**
+ * \brief Initializes color with a copy of png_color object.
+ */
+ color(png_color const& other)
+ {
+ this->red = other.red;
+ this->green = other.green;
+ this->blue = other.blue;
+ }
+ };
+
+} // namespace png
+
+#endif // PNGPP_COLOR_HPP_INCLUDED
diff --git a/xs/src/png/end_info.hpp b/xs/src/png/end_info.hpp
new file mode 100644
index 000000000..09590596d
--- /dev/null
+++ b/xs/src/png/end_info.hpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_END_INFO_HPP_INCLUDED
+#define PNGPP_END_INFO_HPP_INCLUDED
+
+#include "info_base.hpp"
+
+namespace png
+{
+
+ /**
+ * \brief Internal class to hold PNG ending %info.
+ *
+ * \see info, info_base
+ */
+ class end_info
+ : public info_base
+ {
+ public:
+ end_info(io_base& io, png_struct* png)
+ : info_base(io, png)
+ {
+ }
+
+ void destroy()
+ {
+ assert(m_info);
+ png_destroy_info_struct(m_png, & m_info);
+ }
+
+ void read()
+ {
+ png_read_end(m_png, m_info);
+ }
+
+ void write() const
+ {
+ png_write_end(m_png, m_info);
+ }
+
+ // TODO: add methods to read/write text comments etc.
+ };
+
+} // namespace png
+
+#endif // PNGPP_END_INFO_HPP_INCLUDED
diff --git a/xs/src/png/error.hpp b/xs/src/png/error.hpp
new file mode 100644
index 000000000..c67f97630
--- /dev/null
+++ b/xs/src/png/error.hpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_ERROR_HPP_INCLUDED
+#define PNGPP_ERROR_HPP_INCLUDED
+
+/* check if we have strerror_s or strerror_r, prefer the former which is C11 std */
+#ifdef __STDC_LIB_EXT1__
+#define __STDC_WANT_LIB_EXT1__ 1
+#include <string.h>
+
+#define HAVE_STRERROR_S 1
+#else
+#undef HAVE_STRERROR_S
+#endif
+
+#include <string>
+#include <stdexcept>
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+
+namespace png
+{
+
+ /**
+ * \brief Exception class to represent runtime errors related to
+ * png++ operation.
+ */
+ class error
+ : public std::runtime_error
+ {
+ public:
+ /**
+ * \param message error description
+ */
+ explicit error(std::string const& message)
+ : std::runtime_error(message)
+ {
+ }
+ };
+
+ /**
+ * \brief Exception class to represent standard library errors
+ * (generally IO).
+ *
+ * \see reader, writer
+ */
+ class std_error
+ : public std::runtime_error
+ {
+ public:
+ /**
+ * Constructs an std_error object. The \a message string is
+ * appended with <tt>": "</tt> and the error description as
+ * returned by \c strerror(\a error).
+ *
+ * \param message error description
+ * \param error error number
+ */
+ explicit std_error(std::string const& message, int errnum = errno)
+ : std::runtime_error((message + ": ") + thread_safe_strerror(errnum))
+ {
+ }
+
+ protected:
+ static std::string thread_safe_strerror(int errnum)
+ {
+#define ERRBUF_SIZE 512
+
+#ifdef HAVE_STRERROR_S
+ char buf[ERRBUF_SIZE] = { 0 };
+ strerror_s(buf, ERRBUF_SIZE, errnum);
+ return std::string(buf);
+#else
+#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE
+ char buf[ERRBUF_SIZE] = { 0 };
+ strerror_r(errnum, buf, ERRBUF_SIZE);
+ return std::string(buf);
+#elif _GNU_SOURCE
+ /* GNU variant can return a pointer to static buffer instead of buf */
+ char buf[ERRBUF_SIZE] = { 0 };
+ return std::string(strerror_r(errnum, buf, ERRBUF_SIZE));
+#else
+ return std::string("An error occured with errnum ") +
+ std::to_string(errnum) +
+ ". Converting to the appropriate error message is disabled"
+ "in this instance of the png++ library.";
+#endif
+#endif
+
+#undef ERRBUF_SIZE
+ }
+ };
+
+} // namespace png
+
+#endif // PNGPP_ERROR_HPP_INCLUDED
diff --git a/xs/src/png/image_info.hpp b/xs/src/png/image_info.hpp
new file mode 100644
index 000000000..8407bc18b
--- /dev/null
+++ b/xs/src/png/image_info.hpp
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_IMAGE_INFO_HPP_INCLUDED
+#define PNGPP_IMAGE_INFO_HPP_INCLUDED
+
+#include "types.hpp"
+#include "palette.hpp"
+#include "tRNS.hpp"
+#include "pixel_traits.hpp"
+
+namespace png
+{
+
+ /**
+ * \brief Holds information about PNG image.
+ *
+ * \see image, generator, consumer
+ */
+ class image_info
+ {
+ public:
+ /**
+ * \brief Constructs the image_info object with default values
+ * for color_type, interlace_type, compression_method and
+ * filter_type.
+ */
+ image_info()
+ : m_width(0),
+ m_height(0),
+ m_bit_depth(0),
+ m_color_type(color_type_none),
+ m_interlace_type(interlace_none),
+ m_compression_type(compression_type_default),
+ m_filter_type(filter_type_default),
+ m_gamma(0.0)
+ {
+ }
+
+ uint_32 get_width() const
+ {
+ return m_width;
+ }
+
+ void set_width(uint_32 width)
+ {
+ m_width = width;
+ }
+
+ uint_32 get_height() const
+ {
+ return m_height;
+ }
+
+ void set_height(uint_32 height)
+ {
+ m_height = height;
+ }
+
+ color_type get_color_type() const
+ {
+ return m_color_type;
+ }
+
+ void set_color_type(color_type color_space)
+ {
+ m_color_type = color_space;
+ }
+
+ int get_bit_depth() const
+ {
+ return m_bit_depth;
+ }
+
+ void set_bit_depth(int bit_depth)
+ {
+ m_bit_depth = bit_depth;
+ }
+
+ interlace_type get_interlace_type() const
+ {
+ return m_interlace_type;
+ }
+
+ void set_interlace_type(interlace_type interlace)
+ {
+ m_interlace_type = interlace;
+ }
+
+ compression_type get_compression_type() const
+ {
+ return m_compression_type;
+ }
+
+ void set_compression_type(compression_type compression)
+ {
+ m_compression_type = compression;
+ }
+
+ filter_type get_filter_type() const
+ {
+ return m_filter_type;
+ }
+
+ void set_filter_type(filter_type filter)
+ {
+ m_filter_type = filter;
+ }
+
+ palette const& get_palette() const
+ {
+ return m_palette;
+ }
+
+ palette& get_palette()
+ {
+ return m_palette;
+ }
+
+ void set_palette(palette const& plte)
+ {
+ m_palette = plte;
+ }
+
+ /**
+ * \brief Removes all entries from the palette.
+ */
+ void drop_palette()
+ {
+ m_palette.clear();
+ }
+
+ tRNS const& get_tRNS() const
+ {
+ return m_tRNS;
+ }
+
+ tRNS& get_tRNS()
+ {
+ return m_tRNS;
+ }
+
+ void set_tRNS(tRNS const& trns)
+ {
+ m_tRNS = trns;
+ }
+
+ double get_gamma() const
+ {
+ return m_gamma;
+ }
+
+ void set_gamma(double gamma)
+ {
+ m_gamma = gamma;
+ }
+
+ protected:
+ uint_32 m_width;
+ uint_32 m_height;
+ int m_bit_depth;
+ color_type m_color_type;
+ interlace_type m_interlace_type;
+ compression_type m_compression_type;
+ filter_type m_filter_type;
+ palette m_palette;
+ tRNS m_tRNS;
+ double m_gamma;
+ };
+
+ /**
+ * \brief Returns an image_info object with color_type and
+ * bit_depth fields setup appropriate for the \c pixel type.
+ */
+ template< typename pixel >
+ image_info
+ make_image_info()
+ {
+ typedef pixel_traits< pixel > traits;
+ image_info info;
+ info.set_color_type(traits::get_color_type());
+ info.set_bit_depth(traits::get_bit_depth());
+ return info;
+ }
+
+} // namespace png
+
+#endif // PNGPP_IMAGE_INFO_HPP_INCLUDED
diff --git a/xs/src/png/info.hpp b/xs/src/png/info.hpp
new file mode 100644
index 000000000..3f3cf09c3
--- /dev/null
+++ b/xs/src/png/info.hpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_INFO_HPP_INCLUDED
+#define PNGPP_INFO_HPP_INCLUDED
+
+#include <cassert>
+#include "info_base.hpp"
+#include "image_info.hpp"
+
+namespace png
+{
+
+ /**
+ * \brief Holds information about PNG image. Adapter class for IO
+ * image operations.
+ */
+ class info
+ : public info_base,
+ public image_info
+ {
+ public:
+ info(io_base& io, png_struct* png)
+ : info_base(io, png)
+ {
+ }
+
+ void read()
+ {
+ assert(m_png);
+ assert(m_info);
+
+ png_read_info(m_png, m_info);
+ png_get_IHDR(m_png,
+ m_info,
+ & m_width,
+ & m_height,
+ reinterpret_cast< int* >(& m_bit_depth),
+ reinterpret_cast< int* >(& m_color_type),
+ reinterpret_cast< int* >(& m_interlace_type),
+ reinterpret_cast< int* >(& m_compression_type),
+ reinterpret_cast< int* >(& m_filter_type));
+
+ if (png_get_valid(m_png, m_info, chunk_PLTE) == chunk_PLTE)
+ {
+ png_color* colors = 0;
+ int count = 0;
+ png_get_PLTE(m_png, m_info, & colors, & count);
+ m_palette.assign(colors, colors + count);
+ }
+
+#ifdef PNG_tRNS_SUPPORTED
+ if (png_get_valid(m_png, m_info, chunk_tRNS) == chunk_tRNS)
+ {
+ if (m_color_type == color_type_palette)
+ {
+ int count;
+ byte* values;
+ if (png_get_tRNS(m_png, m_info, & values, & count, NULL)
+ != PNG_INFO_tRNS)
+ {
+ throw error("png_get_tRNS() failed");
+ }
+ m_tRNS.assign(values, values + count);
+ }
+ }
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+ if (png_get_valid(m_png, m_info, chunk_gAMA) == chunk_gAMA)
+ {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ if (png_get_gAMA(m_png, m_info, &m_gamma) != PNG_INFO_gAMA)
+ {
+ throw error("png_get_gAMA() failed");
+ }
+#else
+ png_fixed_point gamma = 0;
+ if (png_get_gAMA_fixed(m_png, m_info, &gamma) != PNG_INFO_gAMA)
+ {
+ throw error("png_get_gAMA_fixed() failed");
+ }
+ m_gamma = gamma / 100000.0;
+#endif
+ }
+#endif
+ }
+
+ void write() const
+ {
+ assert(m_png);
+ assert(m_info);
+
+ sync_ihdr();
+ if (m_color_type == color_type_palette)
+ {
+ if (! m_palette.empty())
+ {
+ png_set_PLTE(m_png, m_info,
+ const_cast< color* >(& m_palette[0]),
+ (int) m_palette.size());
+ }
+ if (! m_tRNS.empty())
+ {
+#ifdef PNG_tRNS_SUPPORTED
+ png_set_tRNS(m_png, m_info,
+ const_cast< byte* >(& m_tRNS[0]),
+ m_tRNS.size(),
+ NULL);
+#else
+ throw error("attempted to write tRNS chunk; recompile with PNG_tRNS_SUPPORTED");
+#endif
+ }
+ }
+
+ if (m_gamma > 0)
+ {
+#ifdef PNG_gAMA_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_set_gAMA(m_png, m_info, m_gamma);
+#else
+ png_set_gAMA_fixed(m_png, m_info,
+ (png_fixed_point)(m_gamma * 100000));
+#endif
+#else
+ throw error("attempted to write gAMA chunk; recompile with PNG_gAMA_SUPPORTED");
+#endif
+ }
+
+ png_write_info(m_png, m_info);
+ }
+
+ void update()
+ {
+ assert(m_png);
+ assert(m_info);
+
+ sync_ihdr();
+ png_read_update_info(m_png, m_info);
+ }
+
+ protected:
+ void sync_ihdr(void) const
+ {
+ png_set_IHDR(m_png,
+ m_info,
+ m_width,
+ m_height,
+ m_bit_depth,
+ m_color_type,
+ m_interlace_type,
+ m_compression_type,
+ m_filter_type);
+ }
+ };
+
+} // namespace png
+
+#endif // PNGPP_INFO_HPP_INCLUDED
diff --git a/xs/src/png/info_base.hpp b/xs/src/png/info_base.hpp
new file mode 100644
index 000000000..45e154296
--- /dev/null
+++ b/xs/src/png/info_base.hpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_INFO_BASE_HPP_INCLUDED
+#define PNGPP_INFO_BASE_HPP_INCLUDED
+
+#include <cassert>
+#include "error.hpp"
+#include "types.hpp"
+
+namespace png
+{
+
+ class io_base;
+
+ /**
+ * \brief Internal class to hold PNG info or end_info.
+ */
+ class info_base
+ {
+ info_base(info_base const&);
+ info_base& operator=(info_base const&);
+
+ public:
+ info_base(io_base& io, png_struct* png)
+ : m_io(io),
+ m_png(png),
+ m_info(png_create_info_struct(m_png))
+ {
+ }
+
+ png_info* get_png_info() const
+ {
+ return m_info;
+ }
+
+ png_info** get_png_info_ptr()
+ {
+ return & m_info;
+ }
+
+ protected:
+ io_base& m_io;
+ png_struct* m_png;
+ png_info* m_info;
+ };
+
+} // namespace png
+
+#endif // PNGPP_INFO_BASE_HPP_INCLUDED
diff --git a/xs/src/png/io_base.hpp b/xs/src/png/io_base.hpp
new file mode 100644
index 000000000..3c2d83043
--- /dev/null
+++ b/xs/src/png/io_base.hpp
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_IO_BASE_HPP_INCLUDED
+#define PNGPP_IO_BASE_HPP_INCLUDED
+
+#include <cassert>
+#include <cstdio>
+#include <cstdarg>
+#include "error.hpp"
+#include "info.hpp"
+#include "end_info.hpp"
+
+static void
+trace_io_transform(char const* fmt, ...)
+{
+#ifdef DEBUG_IO_TRANSFORM
+ va_list va;
+ va_start(va, fmt);
+ fprintf(stderr, "TRANSFORM_IO: ");
+ vfprintf(stderr, fmt, va);
+ va_end(va);
+#endif
+}
+#define TRACE_IO_TRANSFORM trace_io_transform
+
+namespace png
+{
+
+ /**
+ * \brief Base class for PNG reader/writer classes.
+ *
+ * \see reader, writer
+ */
+ class io_base
+ {
+ io_base(io_base const&);
+ io_base& operator=(io_base const&);
+
+ public:
+ explicit io_base(png_struct* png)
+ : m_png(png),
+ m_info(*this, m_png),
+ m_end_info(*this, m_png)
+ {
+ }
+
+ ~io_base()
+ {
+ assert(! m_png);
+ assert(! m_info.get_png_info());
+ assert(! m_end_info.get_png_info());
+ }
+
+ png_struct* get_png_struct() const
+ {
+ return m_png;
+ }
+
+ info& get_info()
+ {
+ return m_info;
+ }
+
+ info const& get_info() const
+ {
+ return m_info;
+ }
+
+ image_info const& get_image_info() const
+ {
+ return m_info;
+ }
+
+ void set_image_info(image_info const& info)
+ {
+ static_cast< image_info& >(m_info) = info; // slice it
+ }
+
+ end_info& get_end_info()
+ {
+ return m_end_info;
+ }
+
+ end_info const& get_end_info() const
+ {
+ return m_end_info;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // info accessors
+ //
+ uint_32 get_width() const
+ {
+ return m_info.get_width();
+ }
+
+ void set_width(uint_32 width)
+ {
+ m_info.set_width(width);
+ }
+
+ uint_32 get_height() const
+ {
+ return m_info.get_height();
+ }
+
+ void set_height(uint_32 height)
+ {
+ m_info.set_height(height);
+ }
+
+ color_type get_color_type() const
+ {
+ return m_info.get_color_type();
+ }
+
+ void set_color_type(color_type color_space)
+ {
+ m_info.set_color_type(color_space);
+ }
+
+ int get_bit_depth() const
+ {
+ return m_info.get_bit_depth();
+ }
+
+ void set_bit_depth(int bit_depth)
+ {
+ m_info.set_bit_depth(bit_depth);
+ }
+
+ interlace_type get_interlace_type() const
+ {
+ return m_info.get_interlace_type();
+ }
+
+ void set_interlace_type(interlace_type interlace)
+ {
+ m_info.set_interlace_type(interlace);
+ }
+
+ compression_type get_compression_type() const
+ {
+ return m_info.get_compression_type();
+ }
+
+ void set_compression_type(compression_type compression)
+ {
+ m_info.set_compression_type(compression);
+ }
+
+ filter_type get_filter_type() const
+ {
+ return m_info.get_filter_type();
+ }
+
+ void set_filter_type(filter_type filter)
+ {
+ m_info.set_filter_type(filter);
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ bool has_chunk(chunk id)
+ {
+ return png_get_valid(m_png,
+ m_info.get_png_info(),
+ uint_32(id)) == uint_32(id);
+ }
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ void set_gray_1_2_4_to_8() const
+ {
+ TRACE_IO_TRANSFORM("png_set_expand_gray_1_2_4_to_8\n");
+ png_set_expand_gray_1_2_4_to_8(m_png);
+ }
+
+ void set_palette_to_rgb() const
+ {
+ TRACE_IO_TRANSFORM("png_set_palette_to_rgb\n");
+ png_set_palette_to_rgb(m_png);
+ }
+
+ void set_tRNS_to_alpha() const
+ {
+ TRACE_IO_TRANSFORM("png_set_tRNS_to_alpha\n");
+ png_set_tRNS_to_alpha(m_png);
+ }
+#endif // defined(PNG_READ_EXPAND_SUPPORTED)
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+ void set_bgr() const
+ {
+ TRACE_IO_TRANSFORM("png_set_bgr\n");
+ png_set_bgr(m_png);
+ }
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+ void set_gray_to_rgb() const
+ {
+ TRACE_IO_TRANSFORM("png_set_gray_to_rgb\n");
+ png_set_gray_to_rgb(m_png);
+ }
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ void set_rgb_to_gray(rgb_to_gray_error_action error_action
+ = rgb_to_gray_silent,
+ double red_weight = -1.0,
+ double green_weight = -1.0) const
+ {
+ TRACE_IO_TRANSFORM("png_set_rgb_to_gray: error_action=%d,"
+ " red_weight=%lf, green_weight=%lf\n",
+ error_action, red_weight, green_weight);
+
+ png_set_rgb_to_gray(m_png, error_action, red_weight, green_weight);
+ }
+#else
+ void set_rgb_to_gray(rgb_to_gray_error_action error_action
+ = rgb_to_gray_silent,
+ fixed_point red_weight = -1,
+ fixed_point green_weight = -1) const
+ {
+ TRACE_IO_TRANSFORM("png_set_rgb_to_gray_fixed: error_action=%d,"
+ " red_weight=%d, green_weight=%d\n",
+ error_action, red_weight, green_weight);
+
+ png_set_rgb_to_gray_fixed(m_png, error_action,
+ red_weight, green_weight);
+ }
+#endif // PNG_FLOATING_POINT_SUPPORTED
+
+ //////////////////////////////////////////////////////////////////////
+ // alpha channel transformations
+ //
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+ void set_strip_alpha() const
+ {
+ TRACE_IO_TRANSFORM("png_set_strip_alpha\n");
+ png_set_strip_alpha(m_png);
+ }
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) \
+ || defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+ void set_swap_alpha() const
+ {
+ TRACE_IO_TRANSFORM("png_set_swap_alpha\n");
+ png_set_swap_alpha(m_png);
+ }
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) \
+ || defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+ void set_invert_alpha() const
+ {
+ TRACE_IO_TRANSFORM("png_set_invert_alpha\n");
+ png_set_invert_alpha(m_png);
+ }
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+ void set_filler(uint_32 filler, filler_type type) const
+ {
+ TRACE_IO_TRANSFORM("png_set_filler: filler=%08x, type=%d\n",
+ filler, type);
+
+ png_set_filler(m_png, filler, type);
+ }
+
+#if !defined(PNG_1_0_X)
+ void set_add_alpha(uint_32 filler, filler_type type) const
+ {
+ TRACE_IO_TRANSFORM("png_set_add_alpha: filler=%08x, type=%d\n",
+ filler, type);
+
+ png_set_add_alpha(m_png, filler, type);
+ }
+#endif
+#endif // PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+ void set_swap() const
+ {
+ TRACE_IO_TRANSFORM("png_set_swap\n");
+ png_set_swap(m_png);
+ }
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+ void set_packing() const
+ {
+ TRACE_IO_TRANSFORM("png_set_packing\n");
+ png_set_packing(m_png);
+ }
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) \
+ || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+ void set_packswap() const
+ {
+ TRACE_IO_TRANSFORM("png_set_packswap\n");
+ png_set_packswap(m_png);
+ }
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+ void set_shift(byte red_bits, byte green_bits, byte blue_bits,
+ byte alpha_bits = 0) const
+ {
+ TRACE_IO_TRANSFORM("png_set_shift: red_bits=%d, green_bits=%d,"
+ " blue_bits=%d, alpha_bits=%d\n",
+ red_bits, green_bits, blue_bits, alpha_bits);
+
+ if (get_color_type() != color_type_rgb
+ || get_color_type() != color_type_rgb_alpha)
+ {
+ throw error("set_shift: expected RGB or RGBA color type");
+ }
+ color_info bits;
+ bits.red = red_bits;
+ bits.green = green_bits;
+ bits.blue = blue_bits;
+ bits.alpha = alpha_bits;
+ png_set_shift(m_png, & bits);
+ }
+
+ void set_shift(byte gray_bits, byte alpha_bits = 0) const
+ {
+ TRACE_IO_TRANSFORM("png_set_shift: gray_bits=%d, alpha_bits=%d\n",
+ gray_bits, alpha_bits);
+
+ if (get_color_type() != color_type_gray
+ || get_color_type() != color_type_gray_alpha)
+ {
+ throw error("set_shift: expected Gray or Gray+Alpha color type");
+ }
+ color_info bits;
+ bits.gray = gray_bits;
+ bits.alpha = alpha_bits;
+ png_set_shift(m_png, & bits);
+ }
+#endif // PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) \
+ || defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ int set_interlace_handling() const
+ {
+ TRACE_IO_TRANSFORM("png_set_interlace_handling\n");
+ return png_set_interlace_handling(m_png);
+ }
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+ void set_invert_mono() const
+ {
+ TRACE_IO_TRANSFORM("png_set_invert_mono\n");
+ png_set_invert_mono(m_png);
+ }
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+ void set_strip_16() const
+ {
+ TRACE_IO_TRANSFORM("png_set_strip_16\n");
+ png_set_strip_16(m_png);
+ }
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ void set_read_user_transform(png_user_transform_ptr transform_fn)
+ {
+ TRACE_IO_TRANSFORM("png_set_read_user_transform_fn\n");
+ png_set_read_user_transform_fn(m_png, transform_fn);
+ }
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) \
+ || defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ void set_user_transform_info(void* info, int bit_depth, int channels)
+ {
+ TRACE_IO_TRANSFORM("png_set_user_transform_info: bit_depth=%d,"
+ " channels=%d\n", bit_depth, channels);
+
+ png_set_user_transform_info(m_png, info, bit_depth, channels);
+ }
+#endif
+
+ protected:
+ void* get_io_ptr() const
+ {
+ return png_get_io_ptr(m_png);
+ }
+
+ void set_error(char const* message)
+ {
+ assert(message);
+ m_error = message;
+ }
+
+ void reset_error()
+ {
+ m_error.clear();
+ }
+
+/*
+ std::string const& get_error() const
+ {
+ return m_error;
+ }
+*/
+
+ bool is_error() const
+ {
+ return !m_error.empty();
+ }
+
+ void raise_error()
+ {
+ longjmp(png_jmpbuf(m_png), -1);
+ }
+
+ static void raise_error(png_struct* png, char const* message)
+ {
+ io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
+ io->set_error(message);
+ io->raise_error();
+ }
+
+ png_struct* m_png;
+ info m_info;
+ end_info m_end_info;
+ std::string m_error;
+ };
+
+} // namespace png
+
+#endif // PNGPP_IO_BASE_HPP_INCLUDED
diff --git a/xs/src/png/libpng/ANNOUNCE b/xs/src/png/libpng/ANNOUNCE
new file mode 100644
index 000000000..0f66c0d1d
--- /dev/null
+++ b/xs/src/png/libpng/ANNOUNCE
@@ -0,0 +1,35 @@
+Libpng 1.6.34 - September 29, 2017
+
+This is a public release of libpng, intended for use in production codes.
+
+Files available for download:
+
+Source files with LF line endings (for Unix/Linux) and with a
+"configure" script
+
+ libpng-1.6.34.tar.xz (LZMA-compressed, recommended)
+ libpng-1.6.34.tar.gz
+
+Source files with CRLF line endings (for Windows), without the
+"configure" script
+
+ lpng1634.7z (LZMA-compressed, recommended)
+ lpng1634.zip
+
+Other information:
+
+ libpng-1.6.34-README.txt
+ libpng-1.6.34-LICENSE.txt
+ libpng-1.6.34-*.asc (armored detached GPG signatures)
+
+Changes since the last public release (1.6.33):
+ Removed contrib/pngsuite/i*.png; some of these were incorrect and caused
+ test failures.
+
+Send comments/corrections/commendations to png-mng-implement at lists.sf.net
+(subscription required; visit
+https://lists.sourceforge.net/lists/listinfo/png-mng-implement
+to subscribe)
+or to glennrp at users.sourceforge.net
+
+Glenn R-P
diff --git a/xs/src/png/libpng/CMakeLists.txt b/xs/src/png/libpng/CMakeLists.txt
new file mode 100644
index 000000000..266b67d0e
--- /dev/null
+++ b/xs/src/png/libpng/CMakeLists.txt
@@ -0,0 +1,937 @@
+# CMakeLists.txt
+
+# Copyright (C) 2007,2009-2017 Glenn Randers-Pehrson
+# Written by Christian Ehrlicher, 2007
+# Revised by Roger Lowman, 2009-2010
+# Revised by Clifford Yapp, 2011-2012
+# Revised by Roger Leigh, 2016
+# Revised by Andreas Franek, 2016
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+cmake_minimum_required(VERSION 3.0.2)
+cmake_policy(VERSION 3.0.2)
+
+# Set MacOSX @rpath usage globally.
+if (POLICY CMP0020)
+ cmake_policy(SET CMP0020 NEW)
+endif(POLICY CMP0020)
+if (POLICY CMP0042)
+ cmake_policy(SET CMP0042 NEW)
+endif(POLICY CMP0042)
+# Use new variable expansion policy.
+if (POLICY CMP0053)
+ cmake_policy(SET CMP0053 NEW)
+endif(POLICY CMP0053)
+if (POLICY CMP0054)
+ cmake_policy(SET CMP0054 NEW)
+endif(POLICY CMP0054)
+
+set(CMAKE_CONFIGURATION_TYPES "Release;Debug;MinSizeRel;RelWithDebInfo")
+
+project(libpng ASM C)
+
+set(PNGLIB_MAJOR 1)
+set(PNGLIB_MINOR 6)
+set(PNGLIB_RELEASE 34)
+set(PNGLIB_NAME libpng${PNGLIB_MAJOR}${PNGLIB_MINOR})
+set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_RELEASE})
+
+# needed packages
+
+#Allow users to specify location of Zlib,
+# Useful if zlib is being built alongside this as a sub-project
+
+set(PNG_BUILD_ZLIB ${CMAKE_CURRENT_SOURCE_DIR}/zlib)
+
+if(NOT WIN32)
+ find_library(M_LIBRARY
+ NAMES m
+ PATHS /usr/lib /usr/local/lib
+ )
+ if(NOT M_LIBRARY)
+ message(STATUS "math lib 'libm' not found; floating point support disabled")
+ endif()
+else()
+ # not needed on windows
+ set(M_LIBRARY "")
+endif()
+
+# COMMAND LINE OPTIONS
+option(PNG_SHARED "Build shared lib" OFF)
+option(PNG_STATIC "Build static lib" ON)
+option(PNG_TESTS "Build libpng tests" OFF)
+
+# Many more configuration options could be added here
+option(PNG_FRAMEWORK "Build OS X framework" OFF)
+option(PNG_DEBUG "Build with debug output" OFF)
+option(PNGARG "Disable ANSI-C prototypes" OFF)
+
+option(PNG_HARDWARE_OPTIMIZATIONS "Enable Hardware Optimizations" ON)
+
+set(PNG_PREFIX "" CACHE STRING "Prefix to add to the API function names")
+set(DFA_XTRA "" CACHE FILEPATH "File containing extra configuration settings")
+
+if(PNG_HARDWARE_OPTIMIZATIONS)
+# set definitions and sources for arm
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
+ CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
+ set(PNG_ARM_NEON_POSSIBLE_VALUES check on off)
+ set(PNG_ARM_NEON "check" CACHE STRING "Enable ARM NEON optimizations:
+ check: (default) use internal checking code;
+ off: disable the optimizations;
+ on: turn on unconditionally.")
+ set_property(CACHE PNG_ARM_NEON PROPERTY STRINGS
+ ${PNG_ARM_NEON_POSSIBLE_VALUES})
+ list(FIND PNG_ARM_NEON_POSSIBLE_VALUES ${PNG_ARM_NEON} index)
+ if(index EQUAL -1)
+ message(FATAL_ERROR
+ " PNG_ARM_NEON must be one of [${PNG_ARM_NEON_POSSIBLE_VALUES}]")
+ elseif(NOT ${PNG_ARM_NEON} STREQUAL "no")
+ set(libpng_arm_sources
+ arm/arm_init.c
+ arm/filter_neon.S
+ arm/filter_neon_intrinsics.c)
+
+ if(${PNG_ARM_NEON} STREQUAL "on")
+ add_definitions(-DPNG_ARM_NEON_OPT=2)
+ elseif(${PNG_ARM_NEON} STREQUAL "check")
+ add_definitions(-DPNG_ARM_NEON_CHECK_SUPPORTED)
+ endif()
+ else()
+ add_definitions(-DPNG_ARM_NEON_OPT=0)
+ endif()
+endif()
+
+# set definitions and sources for powerpc
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
+ CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*" )
+ set(PNG_POWERPC_VSX_POSSIBLE_VALUES on off)
+ set(PNG_POWERPC_VSX "on" CACHE STRING "Enable POWERPC VSX optimizations:
+ off: disable the optimizations.")
+ set_property(CACHE PNG_POWERPC_VSX PROPERTY STRINGS
+ ${PNG_POWERPC_VSX_POSSIBLE_VALUES})
+ list(FIND PNG_POWERPC_VSX_POSSIBLE_VALUES ${PNG_POWERPC_VSX} index)
+ if(index EQUAL -1)
+ message(FATAL_ERROR
+ " PNG_POWERPC_VSX must be one of [${PNG_POWERPC_VSX_POSSIBLE_VALUES}]")
+ elseif(NOT ${PNG_POWERPC_VSX} STREQUAL "no")
+ set(libpng_powerpc_sources
+ powerpc/powerpc_init.c
+ powerpc/filter_vsx_intrinsics.c)
+ if(${PNG_POWERPC_VSX} STREQUAL "on")
+ add_definitions(-DPNG_POWERPC_VSX_OPT=2)
+ endif()
+ else()
+ add_definitions(-DPNG_POWERPC_VSX_OPT=0)
+ endif()
+endif()
+
+# set definitions and sources for intel
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
+ CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*" )
+ set(PNG_INTEL_SSE_POSSIBLE_VALUES on off)
+ set(PNG_INTEL_SSE "on" CACHE STRING "Enable INTEL_SSE optimizations:
+ off: disable the optimizations")
+ set_property(CACHE PNG_INTEL_SSE PROPERTY STRINGS
+ ${PNG_INTEL_SSE_POSSIBLE_VALUES})
+ list(FIND PNG_INTEL_SSE_POSSIBLE_VALUES ${PNG_INTEL_SSE} index)
+ if(index EQUAL -1)
+ message(FATAL_ERROR
+ " PNG_INTEL_SSE must be one of [${PNG_INTEL_SSE_POSSIBLE_VALUES}]")
+ elseif(NOT ${PNG_INTEL_SSE} STREQUAL "no")
+ set(libpng_intel_sources
+ intel/intel_init.c
+ intel/filter_sse2_intrinsics.c)
+ if(${PNG_INTEL_SSE} STREQUAL "on")
+ add_definitions(-DPNG_INTEL_SSE_OPT=1)
+ endif()
+ else()
+ add_definitions(-DPNG_INTEL_SSE_OPT=0)
+ endif()
+endif()
+
+# set definitions and sources for MIPS
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR
+ CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*" )
+ set(PNG_MIPS_MSA_POSSIBLE_VALUES on off)
+ set(PNG_MIPS_MSA "on" CACHE STRING "Enable MIPS_MSA optimizations:
+ off: disable the optimizations")
+ set_property(CACHE PNG_MIPS_MSA PROPERTY STRINGS
+ ${PNG_MIPS_MSA_POSSIBLE_VALUES})
+ list(FIND PNG_MIPS_MSA_POSSIBLE_VALUES ${PNG_MIPS_MSA} index)
+ if(index EQUAL -1)
+ message(FATAL_ERROR
+ " PNG_MIPS_MSA must be one of [${PNG_MIPS_MSA_POSSIBLE_VALUES}]")
+ elseif(NOT ${PNG_MIPS_MSA} STREQUAL "no")
+ set(libpng_mips_sources
+ mips/mips_init.c
+ mips/filter_msa_intrinsics.c)
+ if(${PNG_MIPS_MSA} STREQUAL "on")
+ add_definitions(-DPNG_MIPS_MSA_OPT=2)
+ endif()
+ else()
+ add_definitions(-DPNG_MIPS_MSA_OPT=0)
+ endif()
+endif()
+endif(PNG_HARDWARE_OPTIMIZATIONS)
+
+# SET LIBNAME
+set(PNG_LIB_NAME png${PNGLIB_MAJOR}${PNGLIB_MINOR})
+
+# to distinguish between debug and release lib
+set(CMAKE_DEBUG_POSTFIX "d")
+
+include(CheckCSourceCompiles)
+option(ld-version-script "Enable linker version script" ON)
+if(ld-version-script AND NOT APPLE)
+ # Check if LD supports linker scripts.
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map" "VERS_1 {
+ global: sym;
+ local: *;
+};
+
+VERS_2 {
+ global: sym2;
+ main;
+} VERS_1;
+")
+ set(CMAKE_REQUIRED_FLAGS_SAVE ${CMAKE_REQUIRED_FLAGS})
+ set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/conftest.map'")
+ check_c_source_compiles("void sym(void) {}
+void sym2(void) {}
+int main(void) {return 0;}
+" HAVE_LD_VERSION_SCRIPT)
+ if(NOT HAVE_LD_VERSION_SCRIPT)
+ set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE} "-Wl,-M -Wl,${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
+ check_c_source_compiles("void sym(void) {}
+void sym2(void) {}
+int main(void) {return 0;}
+" HAVE_SOLARIS_LD_VERSION_SCRIPT)
+ endif()
+ set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE})
+ file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
+endif()
+
+# Find symbol prefix. Likely obsolete and unnecessary with recent
+# toolchains (it's not done in many other projects).
+function(symbol_prefix)
+ set(SYMBOL_PREFIX)
+
+ execute_process(COMMAND "${CMAKE_C_COMPILER}" "-E" "-"
+ INPUT_FILE /dev/null
+ OUTPUT_VARIABLE OUT
+ RESULT_VARIABLE STATUS)
+
+ if(CPP_FAIL)
+ message(WARNING "Failed to run the C preprocessor")
+ endif()
+
+ string(REPLACE "\n" ";" OUT "${OUT}")
+ foreach(line ${OUT})
+ string(REGEX MATCH "^PREFIX=" found_match "${line}")
+ if(found_match)
+ STRING(REGEX REPLACE "^PREFIX=(.*\)" "\\1" prefix "${line}")
+ string(REGEX MATCH "__USER_LABEL_PREFIX__" found_match "${prefix}")
+ if(found_match)
+ STRING(REGEX REPLACE "(.*)__USER_LABEL_PREFIX__(.*)" "\\1\\2" prefix "${prefix}")
+ endif()
+ set(SYMBOL_PREFIX "${prefix}")
+ endif()
+ endforeach()
+
+ message(STATUS "Symbol prefix: ${SYMBOL_PREFIX}")
+ set(SYMBOL_PREFIX "${SYMBOL_PREFIX}" PARENT_SCOPE)
+endfunction()
+
+if(UNIX)
+ symbol_prefix()
+endif()
+
+find_program(AWK NAMES gawk awk)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+if(NOT AWK OR ANDROID)
+ # No awk available to generate sources; use pre-built pnglibconf.h
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt
+ ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h)
+ add_custom_target(genfiles) # Dummy
+else()
+ include(CMakeParseArguments)
+ # Generate .chk from .out with awk
+ # generate_chk(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])
+ function(generate_chk)
+ set(options)
+ set(oneValueArgs INPUT OUTPUT)
+ set(multiValueArgs DEPENDS)
+ cmake_parse_arguments(_GC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+ if (NOT _GC_INPUT)
+ message(FATAL_ERROR "Invalid arguments. generate_out requires input.")
+ endif()
+ if (NOT _GC_OUTPUT)
+ message(FATAL_ERROR "Invalid arguments. generate_out requires output.")
+ endif()
+
+ add_custom_command(OUTPUT "${_GC_OUTPUT}"
+ COMMAND "${CMAKE_COMMAND}"
+ "-DINPUT=${_GC_INPUT}"
+ "-DOUTPUT=${_GC_OUTPUT}"
+ -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/genchk.cmake"
+ DEPENDS "${_GC_INPUT}" ${_GC_DEPENDS}
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ endfunction()
+
+ # Generate .out from .c with awk
+ # generate_out(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]])
+ function(generate_out)
+ set(options)
+ set(oneValueArgs INPUT OUTPUT)
+ set(multiValueArgs DEPENDS)
+ cmake_parse_arguments(_GO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+ if (NOT _GO_INPUT)
+ message(FATAL_ERROR "Invalid arguments. generate_out requires input.")
+ endif()
+ if (NOT _GO_OUTPUT)
+ message(FATAL_ERROR "Invalid arguments. generate_out requires output.")
+ endif()
+
+ add_custom_command(OUTPUT "${_GO_OUTPUT}"
+ COMMAND "${CMAKE_COMMAND}"
+ "-DINPUT=${_GO_INPUT}"
+ "-DOUTPUT=${_GO_OUTPUT}"
+ -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/genout.cmake"
+ DEPENDS "${_GO_INPUT}" ${_GO_DEPENDS}
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ endfunction()
+
+ # Generate specific source file with awk
+ # generate_source(OUTPUT outputfile [DEPENDS dep1 [dep2...]])
+ function(generate_source)
+ set(options)
+ set(oneValueArgs OUTPUT)
+ set(multiValueArgs DEPENDS)
+ cmake_parse_arguments(_GSO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+ if (NOT _GSO_OUTPUT)
+ message(FATAL_ERROR "Invalid arguments. generate_source requires output.")
+ endif()
+
+ add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_GSO_OUTPUT}"
+ COMMAND "${CMAKE_COMMAND}"
+ "-DOUTPUT=${_GSO_OUTPUT}"
+ -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake"
+ DEPENDS ${_GSO_DEPENDS}
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ endfunction()
+
+ # Copy file
+ function(generate_copy source destination)
+ add_custom_command(OUTPUT "${destination}"
+ COMMAND "${CMAKE_COMMAND}" -E remove "${destination}"
+ COMMAND "${CMAKE_COMMAND}" -E copy "${source}"
+ "${destination}"
+ DEPENDS "${source}")
+ endfunction()
+
+ # Generate scripts/pnglibconf.h
+ generate_source(OUTPUT "scripts/pnglibconf.c"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
+ "${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk"
+ "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
+
+ # Generate pnglibconf.c
+ generate_source(OUTPUT "pnglibconf.c"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa"
+ "${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk"
+ "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h")
+
+ if(PNG_PREFIX)
+ set(PNGLIBCONF_H_EXTRA_DEPENDS
+ "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
+ "${CMAKE_CURRENT_SOURCE_DIR}/scripts/macro.lst")
+ set(PNGPREFIX_H_EXTRA_DEPENDS
+ "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out")
+ endif()
+
+ generate_out(INPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
+
+ # Generate pnglibconf.h
+ generate_source(OUTPUT "pnglibconf.h"
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
+ ${PNGLIBCONF_H_EXTRA_DEPENDS})
+
+ generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/intprefix.c"
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out"
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
+
+ generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/prefix.c"
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
+ "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out")
+
+ # Generate pngprefix.h
+ generate_source(OUTPUT "pngprefix.h"
+ DEPENDS ${PNGPREFIX_H_EXTRA_DEPENDS})
+
+ generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/sym.c"
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
+
+ generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.c"
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt")
+
+ generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/vers.c"
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h"
+ "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h")
+
+ generate_chk(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk"
+ "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.def")
+
+ add_custom_target(symbol-check DEPENDS
+ "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk")
+
+ generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
+ "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
+ generate_copy("${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out"
+ "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
+
+ add_custom_target(genvers DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers")
+ add_custom_target(gensym DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym")
+
+ add_custom_target("genprebuilt"
+ COMMAND "${CMAKE_COMMAND}"
+ "-DOUTPUT=scripts/pnglibconf.h.prebuilt"
+ -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+
+ # A single target handles generation of all generated files. If
+ # they are dependend upon separately by multiple targets, this
+ # confuses parallel make (it would require a separate top-level
+ # target for each file to track the dependencies properly).
+ add_custom_target(genfiles DEPENDS
+ "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym"
+ "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers"
+ "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c"
+ "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
+ "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out"
+ "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h"
+ "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out"
+ "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c"
+ "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out"
+ "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out"
+ "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk"
+ "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out"
+ "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out")
+endif(NOT AWK OR ANDROID)
+
+# OUR SOURCES
+set(libpng_public_hdrs
+ png.h
+ pngconf.h
+ "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h"
+)
+set(libpng_private_hdrs
+ pngpriv.h
+ pngdebug.h
+ pnginfo.h
+ pngstruct.h
+)
+if(AWK AND NOT ANDROID)
+ list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h")
+endif()
+set(libpng_sources
+ ${libpng_public_hdrs}
+ ${libpng_private_hdrs}
+ png.c
+ pngerror.c
+ pngget.c
+ pngmem.c
+ pngpread.c
+ pngread.c
+ pngrio.c
+ pngrtran.c
+ pngrutil.c
+ pngset.c
+ pngtrans.c
+ pngwio.c
+ pngwrite.c
+ pngwtran.c
+ pngwutil.c
+ ${libpng_arm_sources}
+ ${libpng_intel_sources}
+ ${libpng_mips_sources}
+ ${libpng_powerpc_sources}
+)
+set(pngtest_sources
+ pngtest.c
+)
+set(pngvalid_sources
+ contrib/libtests/pngvalid.c
+)
+set(pngstest_sources
+ contrib/libtests/pngstest.c
+)
+set(pngunknown_sources
+ contrib/libtests/pngunknown.c
+)
+set(pngimage_sources
+ contrib/libtests/pngimage.c
+)
+set(pngfix_sources
+ contrib/tools/pngfix.c
+)
+set(png_fix_itxt_sources
+ contrib/tools/png-fix-itxt.c
+)
+
+if(MSVC)
+ add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
+endif(MSVC)
+
+if(PNG_DEBUG)
+ add_definitions(-DPNG_DEBUG)
+endif()
+
+# NOW BUILD OUR TARGET
+include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${ZLIB_INCLUDE_DIR})
+
+unset(PNG_LIB_TARGETS)
+
+if(PNG_SHARED)
+ add_library(png SHARED ${libpng_sources})
+ set(PNG_LIB_TARGETS png)
+ set_target_properties(png PROPERTIES OUTPUT_NAME ${PNG_LIB_NAME})
+ add_dependencies(png genfiles)
+ if(MSVC)
+ # msvc does not append 'lib' - do it here to have consistent name
+ set_target_properties(png PROPERTIES PREFIX "lib")
+ set_target_properties(png PROPERTIES IMPORT_PREFIX "lib")
+ endif()
+ target_link_libraries(png ${ZLIB_LIBRARY} ${M_LIBRARY})
+
+ if(UNIX AND AWK)
+ if(HAVE_LD_VERSION_SCRIPT)
+ set_target_properties(png PROPERTIES LINK_FLAGS
+ "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
+ elseif(HAVE_SOLARIS_LD_VERSION_SCRIPT)
+ set_target_properties(png PROPERTIES LINK_FLAGS
+ "-Wl,-M -Wl,'${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'")
+ endif()
+ endif()
+endif()
+
+if(PNG_STATIC)
+ # does not work without changing name
+ set(PNG_LIB_NAME_STATIC png_static)
+ add_library(png_static STATIC ${libpng_sources})
+ add_dependencies(png_static genfiles)
+ # MSVC doesn't use a different file extension for shared vs. static
+ # libs. We are able to change OUTPUT_NAME to remove the _static
+ # for all other platforms.
+ if(NOT MSVC)
+ set_target_properties(png_static PROPERTIES
+ OUTPUT_NAME "${PNG_LIB_NAME}"
+ CLEAN_DIRECT_OUTPUT 1)
+ else()
+ set_target_properties(png_static PROPERTIES
+ OUTPUT_NAME "${PNG_LIB_NAME}_static"
+ CLEAN_DIRECT_OUTPUT 1)
+ endif()
+ list(APPEND PNG_LIB_TARGETS png_static)
+ if(MSVC)
+ # msvc does not append 'lib' - do it here to have consistent name
+ set_target_properties(png_static PROPERTIES PREFIX "lib")
+ endif()
+ target_link_libraries(png_static ${ZLIB_LIBRARY} ${M_LIBRARY})
+endif()
+
+if(PNG_FRAMEWORK)
+ set(PNG_LIB_NAME_FRAMEWORK png_framework)
+ add_library(png_framework SHARED ${libpng_sources})
+ add_dependencies(png_framework genfiles)
+ list(APPEND PNG_LIB_TARGETS png_framework)
+ set_target_properties(png_framework PROPERTIES
+ FRAMEWORK TRUE
+ FRAMEWORK_VERSION ${PNGLIB_VERSION}
+ MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PNGLIB_MAJOR}.${PNGLIB_MINOR}
+ MACOSX_FRAMEWORK_BUNDLE_VERSION ${PNGLIB_VERSION}
+ MACOSX_FRAMEWORK_IDENTIFIER org.libpng.libpng
+ XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
+ PUBLIC_HEADER "${libpng_public_hdrs}"
+ OUTPUT_NAME png)
+ target_link_libraries(png_framework ${ZLIB_LIBRARY} ${M_LIBRARY})
+endif()
+
+if(NOT PNG_LIB_TARGETS)
+ message(SEND_ERROR
+ "No library variant selected to build. "
+ "Please enable at least one of the following options: "
+ " PNG_STATIC, PNG_SHARED, PNG_FRAMEWORK")
+endif()
+
+if(PNG_SHARED AND WIN32)
+ set_target_properties(png PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL)
+endif()
+
+function(png_add_test)
+ set(options)
+ set(oneValueArgs NAME COMMAND)
+ set(multiValueArgs OPTIONS FILES)
+ cmake_parse_arguments(_PAT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ if (NOT _PAT_NAME)
+ message(FATAL_ERROR "Invalid arguments. png_add_test requires name.")
+ endif()
+ if (NOT _PAT_COMMAND)
+ message(FATAL_ERROR "Invalid arguments. png_add_test requires command.")
+ endif()
+
+ set(TEST_OPTIONS "${_PAT_OPTIONS}")
+ set(TEST_FILES "${_PAT_FILES}")
+
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/test.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake" @ONLY)
+ if(CMAKE_MAJOR_VERSION GREATER 2) # have generator expressions
+ add_test(NAME "${_PAT_NAME}"
+ COMMAND "${CMAKE_COMMAND}"
+ "-DLIBPNG=$<TARGET_FILE:png>"
+ "-DTEST_COMMAND=$<TARGET_FILE:${_PAT_COMMAND}>"
+ -P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake")
+ else() # old 2.x add_test; limited and won't work well on Windows
+ # Note LIBPNG is a dummy value as there are no generator expressions
+ add_test("${_PAT_NAME}" "${CMAKE_COMMAND}"
+ "-DLIBPNG=${CMAKE_CURRENT_BINARY_DIR}/libpng.so"
+ "-DTEST_COMMAND=./${_PAT_COMMAND}"
+ -P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake")
+ endif()
+endfunction()
+
+if(PNG_TESTS AND PNG_SHARED)
+ # Find test PNG files by globbing, but sort lists to ensure
+ # consistency between different filesystems.
+ file(GLOB PNGSUITE_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/*.png")
+ list(SORT PNGSUITE_PNGS)
+ file(GLOB TEST_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/testpngs/*.png")
+ list(SORT TEST_PNGS)
+
+ set(PNGTEST_PNG "${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png")
+
+ add_executable(pngtest ${pngtest_sources})
+ target_link_libraries(pngtest png)
+
+ png_add_test(NAME pngtest COMMAND pngtest FILES "${PNGTEST_PNG}")
+
+ add_executable(pngvalid ${pngvalid_sources})
+ target_link_libraries(pngvalid png)
+
+ png_add_test(NAME pngvalid-gamma-16-to-8
+ COMMAND pngvalid OPTIONS --gamma-16-to-8)
+ png_add_test(NAME pngvalid-gamma-alpha-mode
+ COMMAND pngvalid OPTIONS --gamma-alpha-mode)
+ png_add_test(NAME pngvalid-gamma-background
+ COMMAND pngvalid OPTIONS --gamma-background)
+ png_add_test(NAME pngvalid-gamma-expand16-alpha-mode
+ COMMAND pngvalid OPTIONS --gamma-alpha-mode --expand16)
+ png_add_test(NAME pngvalid-gamma-expand16-background
+ COMMAND pngvalid OPTIONS --gamma-background --expand16)
+ png_add_test(NAME pngvalid-gamma-expand16-transform
+ COMMAND pngvalid OPTIONS --gamma-transform --expand16)
+ png_add_test(NAME pngvalid-gamma-sbit
+ COMMAND pngvalid OPTIONS --gamma-sbit)
+ png_add_test(NAME pngvalid-gamma-threshold
+ COMMAND pngvalid OPTIONS --gamma-threshold)
+ png_add_test(NAME pngvalid-gamma-transform
+ COMMAND pngvalid OPTIONS --gamma-transform)
+ png_add_test(NAME pngvalid-progressive-interlace-standard
+ COMMAND pngvalid OPTIONS --standard --progressive-read --interlace)
+ png_add_test(NAME pngvalid-progressive-size
+ COMMAND pngvalid OPTIONS --size --progressive-read)
+ png_add_test(NAME pngvalid-progressive-standard
+ COMMAND pngvalid OPTIONS --standard --progressive-read)
+ png_add_test(NAME pngvalid-standard
+ COMMAND pngvalid OPTIONS --standard)
+ png_add_test(NAME pngvalid-transform
+ COMMAND pngvalid OPTIONS --transform)
+
+ add_executable(pngstest ${pngstest_sources})
+ target_link_libraries(pngstest png)
+
+ foreach(gamma_type 1.8 linear none sRGB)
+ foreach(alpha_type none alpha)
+ set(PNGSTEST_FILES)
+ foreach(test_png ${TEST_PNGS})
+ string(REGEX MATCH ".*-linear[-.].*" TEST_PNG_LINEAR "${test_png}")
+ string(REGEX MATCH ".*-sRGB[-.].*" TEST_PNG_SRGB "${test_png}")
+ string(REGEX MATCH ".*-1.8[-.].*" TEST_PNG_G18 "${test_png}")
+ string(REGEX MATCH ".*-alpha-.*" TEST_PNG_ALPHA "${test_png}")
+
+ set(TEST_PNG_VALID TRUE)
+
+ if(TEST_PNG_ALPHA)
+ if (NOT "${alpha_type}" STREQUAL "alpha")
+ set(TEST_PNG_VALID FALSE)
+ endif()
+ else()
+ if ("${alpha_type}" STREQUAL "alpha")
+ set(TEST_PNG_VALID FALSE)
+ endif()
+ endif()
+
+ if(TEST_PNG_LINEAR)
+ if(NOT "${gamma_type}" STREQUAL "linear")
+ set(TEST_PNG_VALID FALSE)
+ endif()
+ elseif(TEST_PNG_SRGB)
+ if(NOT "${gamma_type}" STREQUAL "sRGB")
+ set(TEST_PNG_VALID FALSE)
+ endif()
+ elseif(TEST_PNG_G18)
+ if(NOT "${gamma_type}" STREQUAL "1.8")
+ set(TEST_PNG_VALID FALSE)
+ endif()
+ else()
+ if(NOT "${gamma_type}" STREQUAL "none")
+ set(TEST_PNG_VALID FALSE)
+ endif()
+ endif()
+
+ if(TEST_PNG_VALID)
+ list(APPEND PNGSTEST_FILES "${test_png}")
+ endif()
+ endforeach()
+ # Should already be sorted, but sort anyway to be certain.
+ list(SORT PNGSTEST_FILES)
+ png_add_test(NAME pngstest-${gamma_type}-${alpha_type}
+ COMMAND pngstest
+ OPTIONS --tmpfile "${gamma_type}-${alpha_type}-" --log
+ FILES ${PNGSTEST_FILES})
+ endforeach()
+ endforeach()
+
+ add_executable(pngunknown ${pngunknown_sources})
+ target_link_libraries(pngunknown png)
+
+ png_add_test(NAME pngunknown-discard COMMAND pngunknown OPTIONS --strict default=discard FILES "${PNGTEST_PNG}")
+ png_add_test(NAME pngunknown-IDAT COMMAND pngunknown OPTIONS --strict default=discard IDAT=save FILES "${PNGTEST_PNG}")
+ png_add_test(NAME pngunknown-if-safe COMMAND pngunknown OPTIONS --strict default=if-safe FILES "${PNGTEST_PNG}")
+ png_add_test(NAME pngunknown-sAPI COMMAND pngunknown OPTIONS --strict bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save FILES "${PNGTEST_PNG}")
+ png_add_test(NAME pngunknown-save COMMAND pngunknown OPTIONS --strict default=save FILES "${PNGTEST_PNG}")
+ png_add_test(NAME pngunknown-sTER COMMAND pngunknown OPTIONS --strict sTER=if-safe FILES "${PNGTEST_PNG}")
+ png_add_test(NAME pngunknown-vpAg COMMAND pngunknown OPTIONS --strict vpAg=if-safe FILES "${PNGTEST_PNG}")
+
+ add_executable(pngimage ${pngimage_sources})
+ target_link_libraries(pngimage png)
+
+ png_add_test(NAME pngimage-quick COMMAND pngimage OPTIONS --list-combos --log FILES ${PNGSUITE_PNGS})
+ png_add_test(NAME pngimage-full COMMAND pngimage OPTIONS --exhaustive --list-combos --log FILES ${PNGSUITE_PNGS})
+endif()
+
+if(PNG_SHARED)
+ add_executable(pngfix ${pngfix_sources})
+ target_link_libraries(pngfix png)
+ set(PNG_BIN_TARGETS pngfix)
+
+ add_executable(png-fix-itxt ${png_fix_itxt_sources})
+ target_link_libraries(png-fix-itxt ${ZLIB_LIBRARY} ${M_LIBRARY})
+ list(APPEND PNG_BIN_TARGETS png-fix-itxt)
+endif()
+
+# Set a variable with CMake code which:
+# Creates a symlink from src to dest (if possible) or alternatively
+# copies if different.
+include(CMakeParseArguments)
+
+function(CREATE_SYMLINK DEST_FILE)
+
+ cmake_parse_arguments(S "" "FILE;TARGET" "" ${ARGN})
+
+ if(NOT S_TARGET AND NOT S_FILE)
+ message(FATAL_ERROR "Specify either a TARGET or a FILE for CREATE_SYMLINK to link to.")
+ endif(NOT S_TARGET AND NOT S_FILE)
+
+ if(S_TARGET AND S_FILE)
+ message(FATAL_ERROR "CREATE_SYMLINK called with both source file ${S_FILE} and build target ${S_TARGET} arguments - can only handle 1 type per call.")
+ endif(S_TARGET AND S_FILE)
+
+ if(S_FILE)
+ # If we don't need to symlink something that's coming from a build target,
+ # we can go ahead and symlink/copy at configure time.
+
+ if(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS)
+ execute_process(
+ COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${S_FILE} ${DEST_FILE}
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ )
+ else(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS)
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E create_symlink ${S_FILE} ${DEST_FILE}
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ )
+ endif(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS)
+ endif(S_FILE)
+
+ if(S_TARGET)
+ # We need to use generator expressions, which can be a bit tricky, so for
+ # simplicity make the symlink a POST_BUILD step and use the TARGET
+ # signature of add_custom_command.
+
+ if(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS)
+ add_custom_command(TARGET ${S_TARGET} POST_BUILD
+ COMMAND "${CMAKE_COMMAND}" -E copy_if_different $<TARGET_LINKER_FILE_NAME:${S_TARGET}> $<TARGET_LINKER_FILE_DIR:${S_TARGET}>/${DEST_FILE}
+ )
+ else(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS)
+ add_custom_command(TARGET ${S_TARGET} POST_BUILD
+ COMMAND "${CMAKE_COMMAND}" -E create_symlink $<TARGET_LINKER_FILE_NAME:${S_TARGET}> $<TARGET_LINKER_FILE_DIR:${S_TARGET}>/${DEST_FILE}
+ )
+ endif(CMAKE_HOST_WIN32 AND NOT CYGWIN AND NOT MSYS)
+
+ endif(S_TARGET)
+
+endfunction()
+
+# Create source generation scripts.
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genchk.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/scripts/genchk.cmake @ONLY)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/genout.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/scripts/genout.cmake @ONLY)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/gensrc.cmake.in
+ ${CMAKE_CURRENT_BINARY_DIR}/scripts/gensrc.cmake @ONLY)
+
+
+# libpng is a library so default to 'lib'
+if(NOT DEFINED CMAKE_INSTALL_LIBDIR)
+ set(CMAKE_INSTALL_LIBDIR lib)
+endif(NOT DEFINED CMAKE_INSTALL_LIBDIR)
+
+# CREATE PKGCONFIG FILES
+# we use the same files like ./configure, so we have to set its vars
+# Only do this on Windows for Cygwin - the files don't make much sense outside
+# a UNIX look alike
+if(NOT WIN32 OR CYGWIN OR MINGW)
+ set(prefix ${CMAKE_INSTALL_PREFIX})
+ set(exec_prefix ${CMAKE_INSTALL_PREFIX})
+ set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
+ set(includedir ${CMAKE_INSTALL_PREFIX}/include)
+ set(LIBS "-lz -lm")
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc @ONLY)
+ CREATE_SYMLINK(libpng.pc FILE ${PNGLIB_NAME}.pc)
+
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config @ONLY)
+ CREATE_SYMLINK(libpng-config FILE ${PNGLIB_NAME}-config)
+endif(NOT WIN32 OR CYGWIN OR MINGW)
+
+# SET UP LINKS
+if(PNG_SHARED)
+ set_target_properties(png PROPERTIES
+# VERSION 16.${PNGLIB_RELEASE}.1.6.34
+ VERSION 16.${PNGLIB_RELEASE}.0
+ SOVERSION 16
+ CLEAN_DIRECT_OUTPUT 1)
+endif()
+
+# If CMake > 2.4.x, we set a variable used below to export
+# targets to an export file.
+# TODO: Use VERSION_GREATER after our cmake_minimum_required >= 2.6.2
+if(CMAKE_MAJOR_VERSION GREATER 1 AND CMAKE_MINOR_VERSION GREATER 4)
+ set(PNG_EXPORT_RULE EXPORT libpng)
+elseif(CMAKE_MAJOR_VERSION GREATER 2) # future proof
+ set(PNG_EXPORT_RULE EXPORT libpng)
+endif()
+
+# INSTALL
+if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
+ install(TARGETS ${PNG_LIB_TARGETS}
+ ${PNG_EXPORT_RULE}
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR})
+
+ if(PNG_SHARED)
+ # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin
+ if(CYGWIN OR MINGW)
+ CREATE_SYMLINK(libpng${CMAKE_IMPORT_LIBRARY_SUFFIX} TARGET png)
+ install(FILES $<TARGET_LINKER_FILE_DIR:png>/libpng${CMAKE_IMPORT_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR})
+ endif(CYGWIN OR MINGW)
+
+ if(NOT WIN32)
+ CREATE_SYMLINK(libpng${CMAKE_SHARED_LIBRARY_SUFFIX} TARGET png)
+ install(FILES $<TARGET_LINKER_FILE_DIR:png>/libpng${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR})
+ endif(NOT WIN32)
+ endif(PNG_SHARED)
+
+ if(PNG_STATIC)
+ if(NOT WIN32 OR CYGWIN OR MINGW)
+ CREATE_SYMLINK( libpng${CMAKE_STATIC_LIBRARY_SUFFIX} TARGET png_static)
+ install(FILES $<TARGET_LINKER_FILE_DIR:png_static>/libpng${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR})
+ endif(NOT WIN32 OR CYGWIN OR MINGW)
+ endif()
+endif()
+
+if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
+ install(FILES ${libpng_public_hdrs} DESTINATION include)
+ install(FILES ${libpng_public_hdrs} DESTINATION include/${PNGLIB_NAME})
+endif()
+if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL )
+ if(NOT WIN32 OR CYGWIN OR MINGW)
+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config DESTINATION bin)
+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
+ DESTINATION bin)
+ endif(NOT WIN32 OR CYGWIN OR MINGW)
+endif()
+
+if(NOT SKIP_INSTALL_PROGRAMS AND NOT SKIP_INSTALL_ALL )
+ install(TARGETS ${PNG_BIN_TARGETS}
+ RUNTIME DESTINATION bin)
+endif()
+
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+ # Install man pages
+ if(NOT PNG_MAN_DIR)
+ set(PNG_MAN_DIR "share/man")
+ endif()
+ install(FILES libpng.3 libpngpf.3 DESTINATION ${PNG_MAN_DIR}/man3)
+ install(FILES png.5 DESTINATION ${PNG_MAN_DIR}/man5)
+ # Install pkg-config files
+ if(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config
+ DESTINATION bin)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}.pc
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${PNGLIB_NAME}-config
+ DESTINATION bin)
+ endif(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW)
+endif()
+
+# On versions of CMake that support it, create an export file CMake
+# users can include() to import our targets
+if(PNG_EXPORT_RULE AND NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL )
+ install(EXPORT libpng DESTINATION lib/libpng FILE lib${PNG_LIB_NAME}.cmake)
+endif()
+
+# what's with libpng-manual.txt and all the extra files?
+
+# UNINSTALL
+# do we need this?
+
+# DIST
+# do we need this?
+
+# to create msvc import lib for mingw compiled shared lib
+# pexports libpng.dll > libpng.def
+# lib /def:libpng.def /machine:x86
diff --git a/xs/src/png/libpng/LICENSE b/xs/src/png/libpng/LICENSE
new file mode 100644
index 000000000..4cda4fa0a
--- /dev/null
+++ b/xs/src/png/libpng/LICENSE
@@ -0,0 +1,133 @@
+
+This copy of the libpng notices is provided for your convenience. In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+This code is released under the libpng license.
+
+libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are
+Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
+derived from libpng-1.0.6, and are distributed according to the same
+disclaimer and license as libpng-1.0.6 with the following individuals
+added to the list of Contributing Authors:
+
+ Simon-Pierre Cadieux
+ Eric S. Raymond
+ Mans Rullgard
+ Cosmin Truta
+ Gilles Vollant
+ James Yu
+ Mandar Sahastrabuddhe
+ Google Inc.
+ Vadim Barkov
+
+and with the following additions to the disclaimer:
+
+ There is no warranty against interference with your enjoyment of the
+ library or against infringement. There is no warranty that our
+ efforts or the library will fulfill any of your particular purposes
+ or needs. This library is provided with all faults, and the entire
+ risk of satisfactory quality, performance, accuracy, and effort is with
+ the user.
+
+Some files in the "contrib" directory and some configure-generated
+files that are distributed with libpng have other copyright owners and
+are released under other open source licenses.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
+libpng-0.96, and are distributed according to the same disclaimer and
+license as libpng-0.96, with the following individuals added to the list
+of Contributing Authors:
+
+ Tom Lane
+ Glenn Randers-Pehrson
+ Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
+and are distributed according to the same disclaimer and license as
+libpng-0.88, with the following individuals added to the list of
+Contributing Authors:
+
+ John Bowler
+ Kevin Bracey
+ Sam Bushell
+ Magnus Holmgren
+ Greg Roelofs
+ Tom Tanner
+
+Some files in the "scripts" directory have other copyright owners
+but are released under this license.
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+ Andreas Dilger
+ Dave Martindale
+ Guy Eric Schalnat
+ Paul Schmidt
+ Tim Wegner
+
+The PNG Reference Library is supplied "AS IS". The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose. The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+ 1. The origin of this source code must not be misrepresented.
+
+ 2. Altered versions must be plainly marked as such and must not
+ be misrepresented as being the original source.
+
+ 3. This Copyright notice may not be removed or altered from any
+ source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products. If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
+
+TRADEMARK:
+
+The name "libpng" has not been registered by the Copyright owner
+as a trademark in any jurisdiction. However, because libpng has
+been distributed and maintained world-wide, continually since 1995,
+the Copyright owner claims "common-law trademark protection" in any
+jurisdiction where common-law trademark is recognized.
+
+OSI CERTIFICATION:
+
+Libpng is OSI Certified Open Source Software. OSI Certified Open Source is
+a certification mark of the Open Source Initiative. OSI has not addressed
+the additional disclaimers inserted at version 1.0.7.
+
+EXPORT CONTROL:
+
+The Copyright owner believes that the Export Control Classification
+Number (ECCN) for libpng is EAR99, which means not subject to export
+controls or International Traffic in Arms Regulations (ITAR) because
+it is open source, publicly available software, that does not contain
+any encryption software. See the EAR, paragraphs 734.3(b)(3) and
+734.7(b).
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+September 29, 2017
diff --git a/xs/src/png/libpng/arm/arm_init.c b/xs/src/png/libpng/arm/arm_init.c
new file mode 100644
index 000000000..02df812e7
--- /dev/null
+++ b/xs/src/png/libpng/arm/arm_init.c
@@ -0,0 +1,135 @@
+
+/* arm_init.c - NEON optimised filter functions
+ *
+ * Copyright (c) 2014,2016 Glenn Randers-Pehrson
+ * Written by Mans Rullgard, 2011.
+ * Last changed in libpng 1.6.22 [May 26, 2016]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
+ * called.
+ */
+#define _POSIX_SOURCE 1
+
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+#if PNG_ARM_NEON_OPT > 0
+#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */
+/* WARNING: it is strongly recommended that you do not build libpng with
+ * run-time checks for CPU features if at all possible. In the case of the ARM
+ * NEON instructions there is no processor-specific way of detecting the
+ * presence of the required support, therefore run-time detection is extremely
+ * OS specific.
+ *
+ * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing
+ * a fragment of C source code which defines the png_have_neon function. There
+ * are a number of implementations in contrib/arm-neon, but the only one that
+ * has partial support is contrib/arm-neon/linux.c - a generic Linux
+ * implementation which reads /proc/cpufino.
+ */
+#ifndef PNG_ARM_NEON_FILE
+# ifdef __linux__
+# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c"
+# endif
+#endif
+
+#ifdef PNG_ARM_NEON_FILE
+
+#include <signal.h> /* for sig_atomic_t */
+static int png_have_neon(png_structp png_ptr);
+#include PNG_ARM_NEON_FILE
+
+#else /* PNG_ARM_NEON_FILE */
+# error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks"
+#endif /* PNG_ARM_NEON_FILE */
+#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */
+
+#ifndef PNG_ALIGNED_MEMORY_SUPPORTED
+# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
+#endif
+
+void
+png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
+{
+ /* The switch statement is compiled in for ARM_NEON_API, the call to
+ * png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined
+ * the check is only performed if the API has not set the NEON option on
+ * or off explicitly. In this case the check controls what happens.
+ *
+ * If the CHECK is not compiled in and the option is UNSET the behavior prior
+ * to 1.6.7 was to use the NEON code - this was a bug caused by having the
+ * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF,
+ * as documented in png.h
+ */
+ png_debug(1, "in png_init_filter_functions_neon");
+#ifdef PNG_ARM_NEON_API_SUPPORTED
+ switch ((pp->options >> PNG_ARM_NEON) & 3)
+ {
+ case PNG_OPTION_UNSET:
+ /* Allow the run-time check to execute if it has been enabled -
+ * thus both API and CHECK can be turned on. If it isn't supported
+ * this case will fall through to the 'default' below, which just
+ * returns.
+ */
+#endif /* PNG_ARM_NEON_API_SUPPORTED */
+#ifdef PNG_ARM_NEON_CHECK_SUPPORTED
+ {
+ static volatile sig_atomic_t no_neon = -1; /* not checked */
+
+ if (no_neon < 0)
+ no_neon = !png_have_neon(pp);
+
+ if (no_neon)
+ return;
+ }
+#ifdef PNG_ARM_NEON_API_SUPPORTED
+ break;
+#endif
+#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */
+
+#ifdef PNG_ARM_NEON_API_SUPPORTED
+ default: /* OFF or INVALID */
+ return;
+
+ case PNG_OPTION_ON:
+ /* Option turned on */
+ break;
+ }
+#endif
+
+ /* IMPORTANT: any new external functions used here must be declared using
+ * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the
+ * 'prefix' option to configure works:
+ *
+ * ./configure --with-libpng-prefix=foobar_
+ *
+ * Verify you have got this right by running the above command, doing a build
+ * and examining pngprefix.h; it must contain a #define for every external
+ * function you add. (Notice that this happens automatically for the
+ * initialization function.)
+ */
+ pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon;
+
+ if (bpp == 3)
+ {
+ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon;
+ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon;
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+ png_read_filter_row_paeth3_neon;
+ }
+
+ else if (bpp == 4)
+ {
+ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon;
+ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon;
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+ png_read_filter_row_paeth4_neon;
+ }
+}
+#endif /* PNG_ARM_NEON_OPT > 0 */
+#endif /* READ */
diff --git a/xs/src/png/libpng/arm/filter_neon.S b/xs/src/png/libpng/arm/filter_neon.S
new file mode 100644
index 000000000..000764cd2
--- /dev/null
+++ b/xs/src/png/libpng/arm/filter_neon.S
@@ -0,0 +1,253 @@
+
+/* filter_neon.S - NEON optimised filter functions
+ *
+ * Copyright (c) 2014,2017 Glenn Randers-Pehrson
+ * Written by Mans Rullgard, 2011.
+ * Last changed in libpng 1.6.31 [July 27, 2017]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* This is required to get the symbol renames, which are #defines, and the
+ * definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION.
+ */
+#define PNG_VERSION_INFO_ONLY
+#include "../pngpriv.h"
+
+#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
+#endif
+
+#ifdef PNG_READ_SUPPORTED
+
+/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for
+ * ARM64). The code in arm/filter_neon_intrinsics.c supports ARM64, however it
+ * only works if -mfpu=neon is specified on the GCC command line. See pngpriv.h
+ * for the logic which sets PNG_USE_ARM_NEON_ASM:
+ */
+#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */
+
+#if PNG_ARM_NEON_OPT > 0
+
+#ifdef __ELF__
+# define ELF
+#else
+# define ELF @
+#endif
+
+ .arch armv7-a
+ .fpu neon
+
+.macro func name, export=0
+ .macro endfunc
+ELF .size \name, . - \name
+ .endfunc
+ .purgem endfunc
+ .endm
+ .text
+
+ /* Explicitly specifying alignment here because some versions of
+ * GAS don't align code correctly. This is harmless in correctly
+ * written versions of GAS.
+ */
+ .align 2
+
+ .if \export
+ .global \name
+ .endif
+ELF .type \name, STT_FUNC
+ .func \name
+\name:
+.endm
+
+func png_read_filter_row_sub4_neon, export=1
+ ldr r3, [r0, #4] @ rowbytes
+ vmov.i8 d3, #0
+1:
+ vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
+ vadd.u8 d0, d3, d4
+ vadd.u8 d1, d0, d5
+ vadd.u8 d2, d1, d6
+ vadd.u8 d3, d2, d7
+ vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
+ subs r3, r3, #16
+ bgt 1b
+
+ bx lr
+endfunc
+
+func png_read_filter_row_sub3_neon, export=1
+ ldr r3, [r0, #4] @ rowbytes
+ vmov.i8 d3, #0
+ mov r0, r1
+ mov r2, #3
+ mov r12, #12
+ vld1.8 {q11}, [r0], r12
+1:
+ vext.8 d5, d22, d23, #3
+ vadd.u8 d0, d3, d22
+ vext.8 d6, d22, d23, #6
+ vadd.u8 d1, d0, d5
+ vext.8 d7, d23, d23, #1
+ vld1.8 {q11}, [r0], r12
+ vst1.32 {d0[0]}, [r1,:32], r2
+ vadd.u8 d2, d1, d6
+ vst1.32 {d1[0]}, [r1], r2
+ vadd.u8 d3, d2, d7
+ vst1.32 {d2[0]}, [r1], r2
+ vst1.32 {d3[0]}, [r1], r2
+ subs r3, r3, #12
+ bgt 1b
+
+ bx lr
+endfunc
+
+func png_read_filter_row_up_neon, export=1
+ ldr r3, [r0, #4] @ rowbytes
+1:
+ vld1.8 {q0}, [r1,:128]
+ vld1.8 {q1}, [r2,:128]!
+ vadd.u8 q0, q0, q1
+ vst1.8 {q0}, [r1,:128]!
+ subs r3, r3, #16
+ bgt 1b
+
+ bx lr
+endfunc
+
+func png_read_filter_row_avg4_neon, export=1
+ ldr r12, [r0, #4] @ rowbytes
+ vmov.i8 d3, #0
+1:
+ vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
+ vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]!
+ vhadd.u8 d0, d3, d16
+ vadd.u8 d0, d0, d4
+ vhadd.u8 d1, d0, d17
+ vadd.u8 d1, d1, d5
+ vhadd.u8 d2, d1, d18
+ vadd.u8 d2, d2, d6
+ vhadd.u8 d3, d2, d19
+ vadd.u8 d3, d3, d7
+ vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
+ subs r12, r12, #16
+ bgt 1b
+
+ bx lr
+endfunc
+
+func png_read_filter_row_avg3_neon, export=1
+ push {r4,lr}
+ ldr r12, [r0, #4] @ rowbytes
+ vmov.i8 d3, #0
+ mov r0, r1
+ mov r4, #3
+ mov lr, #12
+ vld1.8 {q11}, [r0], lr
+1:
+ vld1.8 {q10}, [r2], lr
+ vext.8 d5, d22, d23, #3
+ vhadd.u8 d0, d3, d20
+ vext.8 d17, d20, d21, #3
+ vadd.u8 d0, d0, d22
+ vext.8 d6, d22, d23, #6
+ vhadd.u8 d1, d0, d17
+ vext.8 d18, d20, d21, #6
+ vadd.u8 d1, d1, d5
+ vext.8 d7, d23, d23, #1
+ vld1.8 {q11}, [r0], lr
+ vst1.32 {d0[0]}, [r1,:32], r4
+ vhadd.u8 d2, d1, d18
+ vst1.32 {d1[0]}, [r1], r4
+ vext.8 d19, d21, d21, #1
+ vadd.u8 d2, d2, d6
+ vhadd.u8 d3, d2, d19
+ vst1.32 {d2[0]}, [r1], r4
+ vadd.u8 d3, d3, d7
+ vst1.32 {d3[0]}, [r1], r4
+ subs r12, r12, #12
+ bgt 1b
+
+ pop {r4,pc}
+endfunc
+
+.macro paeth rx, ra, rb, rc
+ vaddl.u8 q12, \ra, \rb @ a + b
+ vaddl.u8 q15, \rc, \rc @ 2*c
+ vabdl.u8 q13, \rb, \rc @ pa
+ vabdl.u8 q14, \ra, \rc @ pb
+ vabd.u16 q15, q12, q15 @ pc
+ vcle.u16 q12, q13, q14 @ pa <= pb
+ vcle.u16 q13, q13, q15 @ pa <= pc
+ vcle.u16 q14, q14, q15 @ pb <= pc
+ vand q12, q12, q13 @ pa <= pb && pa <= pc
+ vmovn.u16 d28, q14
+ vmovn.u16 \rx, q12
+ vbsl d28, \rb, \rc
+ vbsl \rx, \ra, d28
+.endm
+
+func png_read_filter_row_paeth4_neon, export=1
+ ldr r12, [r0, #4] @ rowbytes
+ vmov.i8 d3, #0
+ vmov.i8 d20, #0
+1:
+ vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
+ vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]!
+ paeth d0, d3, d16, d20
+ vadd.u8 d0, d0, d4
+ paeth d1, d0, d17, d16
+ vadd.u8 d1, d1, d5
+ paeth d2, d1, d18, d17
+ vadd.u8 d2, d2, d6
+ paeth d3, d2, d19, d18
+ vmov d20, d19
+ vadd.u8 d3, d3, d7
+ vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
+ subs r12, r12, #16
+ bgt 1b
+
+ bx lr
+endfunc
+
+func png_read_filter_row_paeth3_neon, export=1
+ push {r4,lr}
+ ldr r12, [r0, #4] @ rowbytes
+ vmov.i8 d3, #0
+ vmov.i8 d4, #0
+ mov r0, r1
+ mov r4, #3
+ mov lr, #12
+ vld1.8 {q11}, [r0], lr
+1:
+ vld1.8 {q10}, [r2], lr
+ paeth d0, d3, d20, d4
+ vext.8 d5, d22, d23, #3
+ vadd.u8 d0, d0, d22
+ vext.8 d17, d20, d21, #3
+ paeth d1, d0, d17, d20
+ vst1.32 {d0[0]}, [r1,:32], r4
+ vext.8 d6, d22, d23, #6
+ vadd.u8 d1, d1, d5
+ vext.8 d18, d20, d21, #6
+ paeth d2, d1, d18, d17
+ vext.8 d7, d23, d23, #1
+ vld1.8 {q11}, [r0], lr
+ vst1.32 {d1[0]}, [r1], r4
+ vadd.u8 d2, d2, d6
+ vext.8 d19, d21, d21, #1
+ paeth d3, d2, d19, d18
+ vst1.32 {d2[0]}, [r1], r4
+ vmov d4, d19
+ vadd.u8 d3, d3, d7
+ vst1.32 {d3[0]}, [r1], r4
+ subs r12, r12, #12
+ bgt 1b
+
+ pop {r4,pc}
+endfunc
+#endif /* PNG_ARM_NEON_OPT > 0 */
+#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */
+#endif /* READ */
diff --git a/xs/src/png/libpng/arm/filter_neon_intrinsics.c b/xs/src/png/libpng/arm/filter_neon_intrinsics.c
new file mode 100644
index 000000000..ea7e356bc
--- /dev/null
+++ b/xs/src/png/libpng/arm/filter_neon_intrinsics.c
@@ -0,0 +1,387 @@
+
+/* filter_neon_intrinsics.c - NEON optimised filter functions
+ *
+ * Copyright (c) 2014,2016 Glenn Randers-Pehrson
+ * Written by James Yu <james.yu at linaro.org>, October 2013.
+ * Based on filter_neon.S, written by Mans Rullgard, 2011.
+ *
+ * Last changed in libpng 1.6.22 [May 26, 2016]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* This code requires -mfpu=neon on the command line: */
+#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
+
+#include <arm_neon.h>
+
+/* libpng row pointers are not necessarily aligned to any particular boundary,
+ * however this code will only work with appropriate alignment. arm/arm_init.c
+ * checks for this (and will not compile unless it is done). This code uses
+ * variants of png_aligncast to avoid compiler warnings.
+ */
+#define png_ptr(type,pointer) png_aligncast(type *,pointer)
+#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)
+
+/* The following relies on a variable 'temp_pointer' being declared with type
+ * 'type'. This is written this way just to hide the GCC strict aliasing
+ * warning; note that the code is safe because there never is an alias between
+ * the input and output pointers.
+ */
+#define png_ldr(type,pointer)\
+ (temp_pointer = png_ptr(type,pointer), *temp_pointer)
+
+#if PNG_ARM_NEON_OPT > 0
+
+void
+png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_bytep rp = row;
+ png_bytep rp_stop = row + row_info->rowbytes;
+ png_const_bytep pp = prev_row;
+
+ png_debug(1, "in png_read_filter_row_up_neon");
+
+ for (; rp < rp_stop; rp += 16, pp += 16)
+ {
+ uint8x16_t qrp, qpp;
+
+ qrp = vld1q_u8(rp);
+ qpp = vld1q_u8(pp);
+ qrp = vaddq_u8(qrp, qpp);
+ vst1q_u8(rp, qrp);
+ }
+}
+
+void
+png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_bytep rp = row;
+ png_bytep rp_stop = row + row_info->rowbytes;
+
+ uint8x16_t vtmp = vld1q_u8(rp);
+ uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp);
+ uint8x8x2_t vrp = *vrpt;
+
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ png_debug(1, "in png_read_filter_row_sub3_neon");
+
+ for (; rp < rp_stop;)
+ {
+ uint8x8_t vtmp1, vtmp2;
+ uint32x2_t *temp_pointer;
+
+ vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+ vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
+ vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6);
+ vdest.val[1] = vadd_u8(vdest.val[0], vtmp1);
+
+ vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+ vdest.val[2] = vadd_u8(vdest.val[1], vtmp2);
+ vdest.val[3] = vadd_u8(vdest.val[2], vtmp1);
+
+ vtmp = vld1q_u8(rp + 12);
+ vrpt = png_ptr(uint8x8x2_t, &vtmp);
+ vrp = *vrpt;
+
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+ rp += 3;
+ }
+
+ PNG_UNUSED(prev_row)
+}
+
+void
+png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_bytep rp = row;
+ png_bytep rp_stop = row + row_info->rowbytes;
+
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ png_debug(1, "in png_read_filter_row_sub4_neon");
+
+ for (; rp < rp_stop; rp += 16)
+ {
+ uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp));
+ uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp);
+ uint8x8x4_t vrp = *vrpt;
+ uint32x2x4_t *temp_pointer;
+
+ vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
+ vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]);
+ vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]);
+ vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]);
+ vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+ }
+
+ PNG_UNUSED(prev_row)
+}
+
+void
+png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_bytep rp = row;
+ png_const_bytep pp = prev_row;
+ png_bytep rp_stop = row + row_info->rowbytes;
+
+ uint8x16_t vtmp;
+ uint8x8x2_t *vrpt;
+ uint8x8x2_t vrp;
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ vtmp = vld1q_u8(rp);
+ vrpt = png_ptr(uint8x8x2_t,&vtmp);
+ vrp = *vrpt;
+
+ png_debug(1, "in png_read_filter_row_avg3_neon");
+
+ for (; rp < rp_stop; pp += 12)
+ {
+ uint8x8_t vtmp1, vtmp2, vtmp3;
+
+ uint8x8x2_t *vppt;
+ uint8x8x2_t vpp;
+
+ uint32x2_t *temp_pointer;
+
+ vtmp = vld1q_u8(pp);
+ vppt = png_ptr(uint8x8x2_t,&vtmp);
+ vpp = *vppt;
+
+ vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+ vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
+ vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+
+ vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
+ vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6);
+ vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2);
+ vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
+
+ vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6);
+ vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+
+ vtmp = vld1q_u8(rp + 12);
+ vrpt = png_ptr(uint8x8x2_t,&vtmp);
+ vrp = *vrpt;
+
+ vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2);
+ vdest.val[2] = vadd_u8(vdest.val[2], vtmp3);
+
+ vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
+
+ vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2);
+ vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
+
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+ rp += 3;
+ }
+}
+
+void
+png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_bytep rp = row;
+ png_bytep rp_stop = row + row_info->rowbytes;
+ png_const_bytep pp = prev_row;
+
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ png_debug(1, "in png_read_filter_row_avg4_neon");
+
+ for (; rp < rp_stop; rp += 16, pp += 16)
+ {
+ uint32x2x4_t vtmp;
+ uint8x8x4_t *vrpt, *vppt;
+ uint8x8x4_t vrp, vpp;
+ uint32x2x4_t *temp_pointer;
+
+ vtmp = vld4_u32(png_ptr(uint32_t,rp));
+ vrpt = png_ptr(uint8x8x4_t,&vtmp);
+ vrp = *vrpt;
+ vtmp = vld4_u32(png_ptrc(uint32_t,pp));
+ vppt = png_ptr(uint8x8x4_t,&vtmp);
+ vpp = *vppt;
+
+ vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
+ vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+ vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]);
+ vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
+ vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]);
+ vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
+ vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]);
+ vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
+
+ vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+ }
+}
+
+static uint8x8_t
+paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c)
+{
+ uint8x8_t d, e;
+ uint16x8_t p1, pa, pb, pc;
+
+ p1 = vaddl_u8(a, b); /* a + b */
+ pc = vaddl_u8(c, c); /* c * 2 */
+ pa = vabdl_u8(b, c); /* pa */
+ pb = vabdl_u8(a, c); /* pb */
+ pc = vabdq_u16(p1, pc); /* pc */
+
+ p1 = vcleq_u16(pa, pb); /* pa <= pb */
+ pa = vcleq_u16(pa, pc); /* pa <= pc */
+ pb = vcleq_u16(pb, pc); /* pb <= pc */
+
+ p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */
+
+ d = vmovn_u16(pb);
+ e = vmovn_u16(p1);
+
+ d = vbsl_u8(d, b, c);
+ e = vbsl_u8(e, a, d);
+
+ return e;
+}
+
+void
+png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_bytep rp = row;
+ png_const_bytep pp = prev_row;
+ png_bytep rp_stop = row + row_info->rowbytes;
+
+ uint8x16_t vtmp;
+ uint8x8x2_t *vrpt;
+ uint8x8x2_t vrp;
+ uint8x8_t vlast = vdup_n_u8(0);
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ vtmp = vld1q_u8(rp);
+ vrpt = png_ptr(uint8x8x2_t,&vtmp);
+ vrp = *vrpt;
+
+ png_debug(1, "in png_read_filter_row_paeth3_neon");
+
+ for (; rp < rp_stop; pp += 12)
+ {
+ uint8x8x2_t *vppt;
+ uint8x8x2_t vpp;
+ uint8x8_t vtmp1, vtmp2, vtmp3;
+ uint32x2_t *temp_pointer;
+
+ vtmp = vld1q_u8(pp);
+ vppt = png_ptr(uint8x8x2_t,&vtmp);
+ vpp = *vppt;
+
+ vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
+ vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+
+ vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
+ vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
+ vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]);
+ vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
+
+ vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6);
+ vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6);
+ vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2);
+ vdest.val[2] = vadd_u8(vdest.val[2], vtmp1);
+
+ vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
+ vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
+
+ vtmp = vld1q_u8(rp + 12);
+ vrpt = png_ptr(uint8x8x2_t,&vtmp);
+ vrp = *vrpt;
+
+ vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3);
+ vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
+
+ vlast = vtmp2;
+
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
+ rp += 3;
+ vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
+ rp += 3;
+ }
+}
+
+void
+png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_bytep rp = row;
+ png_bytep rp_stop = row + row_info->rowbytes;
+ png_const_bytep pp = prev_row;
+
+ uint8x8_t vlast = vdup_n_u8(0);
+ uint8x8x4_t vdest;
+ vdest.val[3] = vdup_n_u8(0);
+
+ png_debug(1, "in png_read_filter_row_paeth4_neon");
+
+ for (; rp < rp_stop; rp += 16, pp += 16)
+ {
+ uint32x2x4_t vtmp;
+ uint8x8x4_t *vrpt, *vppt;
+ uint8x8x4_t vrp, vpp;
+ uint32x2x4_t *temp_pointer;
+
+ vtmp = vld4_u32(png_ptr(uint32_t,rp));
+ vrpt = png_ptr(uint8x8x4_t,&vtmp);
+ vrp = *vrpt;
+ vtmp = vld4_u32(png_ptrc(uint32_t,pp));
+ vppt = png_ptr(uint8x8x4_t,&vtmp);
+ vpp = *vppt;
+
+ vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
+ vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
+ vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]);
+ vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
+ vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]);
+ vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
+ vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]);
+ vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
+
+ vlast = vpp.val[3];
+
+ vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0);
+ }
+}
+
+#endif /* PNG_ARM_NEON_OPT > 0 */
+#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */
+#endif /* READ */
diff --git a/xs/src/png/libpng/intel/filter_sse2_intrinsics.c b/xs/src/png/libpng/intel/filter_sse2_intrinsics.c
new file mode 100644
index 000000000..5e8553fbb
--- /dev/null
+++ b/xs/src/png/libpng/intel/filter_sse2_intrinsics.c
@@ -0,0 +1,406 @@
+
+/* filter_sse2_intrinsics.c - SSE2 optimized filter functions
+ *
+ * Copyright (c) 2016-2017 Glenn Randers-Pehrson
+ * Written by Mike Klein and Matt Sarett
+ * Derived from arm/filter_neon_intrinsics.c
+ *
+ * Last changed in libpng 1.6.31 [July 27, 2017]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+#if PNG_INTEL_SSE_IMPLEMENTATION > 0
+
+#include <immintrin.h>
+
+/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d).
+ * They're positioned like this:
+ * prev: c b
+ * row: a d
+ * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be
+ * whichever of a, b, or c is closest to p=a+b-c.
+ */
+
+static __m128i load4(const void* p) {
+ return _mm_cvtsi32_si128(*(const int*)p);
+}
+
+static void store4(void* p, __m128i v) {
+ *(int*)p = _mm_cvtsi128_si32(v);
+}
+
+static __m128i load3(const void* p) {
+ /* We'll load 2 bytes, then 1 byte,
+ * then mask them together, and finally load into SSE.
+ */
+ const png_uint_16* p01 = (png_const_uint_16p)p;
+ const png_byte* p2 = (const png_byte*)(p01+1);
+
+ png_uint_32 v012 = (png_uint_32)(*p01)
+ | (png_uint_32)(*p2) << 16;
+ return load4(&v012);
+}
+
+static void store3(void* p, __m128i v) {
+ /* We'll pull from SSE as a 32-bit int, then write
+ * its bottom two bytes, then its third byte.
+ */
+ png_uint_32 v012;
+ png_uint_16* p01;
+ png_byte* p2;
+
+ store4(&v012, v);
+
+ p01 = (png_uint_16p)p;
+ p2 = (png_byte*)(p01+1);
+ *p01 = (png_uint_16)v012;
+ *p2 = (png_byte)(v012 >> 16);
+}
+
+void png_read_filter_row_sub3_sse2(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev)
+{
+ /* The Sub filter predicts each pixel as the previous pixel, a.
+ * There is no pixel to the left of the first pixel. It's encoded directly.
+ * That works with our main loop if we just say that left pixel was zero.
+ */
+ png_size_t rb;
+
+ __m128i a, d = _mm_setzero_si128();
+
+ png_debug(1, "in png_read_filter_row_sub3_sse2");
+
+ rb = row_info->rowbytes;
+ while (rb >= 4) {
+ a = d; d = load4(row);
+ d = _mm_add_epi8(d, a);
+ store3(row, d);
+
+ row += 3;
+ rb -= 3;
+ }
+ if (rb > 0) {
+ a = d; d = load3(row);
+ d = _mm_add_epi8(d, a);
+ store3(row, d);
+
+ row += 3;
+ rb -= 3;
+ }
+ PNG_UNUSED(prev)
+}
+
+void png_read_filter_row_sub4_sse2(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev)
+{
+ /* The Sub filter predicts each pixel as the previous pixel, a.
+ * There is no pixel to the left of the first pixel. It's encoded directly.
+ * That works with our main loop if we just say that left pixel was zero.
+ */
+ png_size_t rb;
+
+ __m128i a, d = _mm_setzero_si128();
+
+ png_debug(1, "in png_read_filter_row_sub4_sse2");
+
+ rb = row_info->rowbytes+4;
+ while (rb > 4) {
+ a = d; d = load4(row);
+ d = _mm_add_epi8(d, a);
+ store4(row, d);
+
+ row += 4;
+ rb -= 4;
+ }
+ PNG_UNUSED(prev)
+}
+
+void png_read_filter_row_avg3_sse2(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev)
+{
+ /* The Avg filter predicts each pixel as the (truncated) average of a and b.
+ * There's no pixel to the left of the first pixel. Luckily, it's
+ * predicted to be half of the pixel above it. So again, this works
+ * perfectly with our loop if we make sure a starts at zero.
+ */
+
+ png_size_t rb;
+
+ const __m128i zero = _mm_setzero_si128();
+
+ __m128i b;
+ __m128i a, d = zero;
+
+ png_debug(1, "in png_read_filter_row_avg3_sse2");
+ rb = row_info->rowbytes;
+ while (rb >= 4) {
+ __m128i avg;
+ b = load4(prev);
+ a = d; d = load4(row );
+
+ /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
+ avg = _mm_avg_epu8(a,b);
+ /* ...but we can fix it up by subtracting off 1 if it rounded up. */
+ avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
+ _mm_set1_epi8(1)));
+ d = _mm_add_epi8(d, avg);
+ store3(row, d);
+
+ prev += 3;
+ row += 3;
+ rb -= 3;
+ }
+ if (rb > 0) {
+ __m128i avg;
+ b = load3(prev);
+ a = d; d = load3(row );
+
+ /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
+ avg = _mm_avg_epu8(a,b);
+ /* ...but we can fix it up by subtracting off 1 if it rounded up. */
+ avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
+ _mm_set1_epi8(1)));
+
+ d = _mm_add_epi8(d, avg);
+ store3(row, d);
+
+ prev += 3;
+ row += 3;
+ rb -= 3;
+ }
+}
+
+void png_read_filter_row_avg4_sse2(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev)
+{
+ /* The Avg filter predicts each pixel as the (truncated) average of a and b.
+ * There's no pixel to the left of the first pixel. Luckily, it's
+ * predicted to be half of the pixel above it. So again, this works
+ * perfectly with our loop if we make sure a starts at zero.
+ */
+ png_size_t rb;
+ const __m128i zero = _mm_setzero_si128();
+ __m128i b;
+ __m128i a, d = zero;
+
+ png_debug(1, "in png_read_filter_row_avg4_sse2");
+
+ rb = row_info->rowbytes+4;
+ while (rb > 4) {
+ __m128i avg;
+ b = load4(prev);
+ a = d; d = load4(row );
+
+ /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
+ avg = _mm_avg_epu8(a,b);
+ /* ...but we can fix it up by subtracting off 1 if it rounded up. */
+ avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
+ _mm_set1_epi8(1)));
+
+ d = _mm_add_epi8(d, avg);
+ store4(row, d);
+
+ prev += 4;
+ row += 4;
+ rb -= 4;
+ }
+}
+
+/* Returns |x| for 16-bit lanes. */
+static __m128i abs_i16(__m128i x) {
+#if PNG_INTEL_SSE_IMPLEMENTATION >= 2
+ return _mm_abs_epi16(x);
+#else
+ /* Read this all as, return x<0 ? -x : x.
+ * To negate two's complement, you flip all the bits then add 1.
+ */
+ __m128i is_negative = _mm_cmplt_epi16(x, _mm_setzero_si128());
+
+ /* Flip negative lanes. */
+ x = _mm_xor_si128(x, is_negative);
+
+ /* +1 to negative lanes, else +0. */
+ x = _mm_sub_epi16(x, is_negative);
+ return x;
+#endif
+}
+
+/* Bytewise c ? t : e. */
+static __m128i if_then_else(__m128i c, __m128i t, __m128i e) {
+#if PNG_INTEL_SSE_IMPLEMENTATION >= 3
+ return _mm_blendv_epi8(e,t,c);
+#else
+ return _mm_or_si128(_mm_and_si128(c, t), _mm_andnot_si128(c, e));
+#endif
+}
+
+void png_read_filter_row_paeth3_sse2(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev)
+{
+ /* Paeth tries to predict pixel d using the pixel to the left of it, a,
+ * and two pixels from the previous row, b and c:
+ * prev: c b
+ * row: a d
+ * The Paeth function predicts d to be whichever of a, b, or c is nearest to
+ * p=a+b-c.
+ *
+ * The first pixel has no left context, and so uses an Up filter, p = b.
+ * This works naturally with our main loop's p = a+b-c if we force a and c
+ * to zero.
+ * Here we zero b and d, which become c and a respectively at the start of
+ * the loop.
+ */
+ png_size_t rb;
+ const __m128i zero = _mm_setzero_si128();
+ __m128i c, b = zero,
+ a, d = zero;
+
+ png_debug(1, "in png_read_filter_row_paeth3_sse2");
+
+ rb = row_info->rowbytes;
+ while (rb >= 4) {
+ /* It's easiest to do this math (particularly, deal with pc) with 16-bit
+ * intermediates.
+ */
+ __m128i pa,pb,pc,smallest,nearest;
+ c = b; b = _mm_unpacklo_epi8(load4(prev), zero);
+ a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
+
+ /* (p-a) == (a+b-c - a) == (b-c) */
+
+ pa = _mm_sub_epi16(b,c);
+
+ /* (p-b) == (a+b-c - b) == (a-c) */
+ pb = _mm_sub_epi16(a,c);
+
+ /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
+ pc = _mm_add_epi16(pa,pb);
+
+ pa = abs_i16(pa); /* |p-a| */
+ pb = abs_i16(pb); /* |p-b| */
+ pc = abs_i16(pc); /* |p-c| */
+
+ smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+
+ /* Paeth breaks ties favoring a over b over c. */
+ nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+ if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
+ c));
+
+ /* Note `_epi8`: we need addition to wrap modulo 255. */
+ d = _mm_add_epi8(d, nearest);
+ store3(row, _mm_packus_epi16(d,d));
+
+ prev += 3;
+ row += 3;
+ rb -= 3;
+ }
+ if (rb > 0) {
+ /* It's easiest to do this math (particularly, deal with pc) with 16-bit
+ * intermediates.
+ */
+ __m128i pa,pb,pc,smallest,nearest;
+ c = b; b = _mm_unpacklo_epi8(load3(prev), zero);
+ a = d; d = _mm_unpacklo_epi8(load3(row ), zero);
+
+ /* (p-a) == (a+b-c - a) == (b-c) */
+ pa = _mm_sub_epi16(b,c);
+
+ /* (p-b) == (a+b-c - b) == (a-c) */
+ pb = _mm_sub_epi16(a,c);
+
+ /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
+ pc = _mm_add_epi16(pa,pb);
+
+ pa = abs_i16(pa); /* |p-a| */
+ pb = abs_i16(pb); /* |p-b| */
+ pc = abs_i16(pc); /* |p-c| */
+
+ smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+
+ /* Paeth breaks ties favoring a over b over c. */
+ nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+ if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
+ c));
+
+ /* Note `_epi8`: we need addition to wrap modulo 255. */
+ d = _mm_add_epi8(d, nearest);
+ store3(row, _mm_packus_epi16(d,d));
+
+ prev += 3;
+ row += 3;
+ rb -= 3;
+ }
+}
+
+void png_read_filter_row_paeth4_sse2(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev)
+{
+ /* Paeth tries to predict pixel d using the pixel to the left of it, a,
+ * and two pixels from the previous row, b and c:
+ * prev: c b
+ * row: a d
+ * The Paeth function predicts d to be whichever of a, b, or c is nearest to
+ * p=a+b-c.
+ *
+ * The first pixel has no left context, and so uses an Up filter, p = b.
+ * This works naturally with our main loop's p = a+b-c if we force a and c
+ * to zero.
+ * Here we zero b and d, which become c and a respectively at the start of
+ * the loop.
+ */
+ png_size_t rb;
+ const __m128i zero = _mm_setzero_si128();
+ __m128i pa,pb,pc,smallest,nearest;
+ __m128i c, b = zero,
+ a, d = zero;
+
+ png_debug(1, "in png_read_filter_row_paeth4_sse2");
+
+ rb = row_info->rowbytes+4;
+ while (rb > 4) {
+ /* It's easiest to do this math (particularly, deal with pc) with 16-bit
+ * intermediates.
+ */
+ c = b; b = _mm_unpacklo_epi8(load4(prev), zero);
+ a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
+
+ /* (p-a) == (a+b-c - a) == (b-c) */
+ pa = _mm_sub_epi16(b,c);
+
+ /* (p-b) == (a+b-c - b) == (a-c) */
+ pb = _mm_sub_epi16(a,c);
+
+ /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
+ pc = _mm_add_epi16(pa,pb);
+
+ pa = abs_i16(pa); /* |p-a| */
+ pb = abs_i16(pb); /* |p-b| */
+ pc = abs_i16(pc); /* |p-c| */
+
+ smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
+
+ /* Paeth breaks ties favoring a over b over c. */
+ nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
+ if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
+ c));
+
+ /* Note `_epi8`: we need addition to wrap modulo 255. */
+ d = _mm_add_epi8(d, nearest);
+ store4(row, _mm_packus_epi16(d,d));
+
+ prev += 4;
+ row += 4;
+ rb -= 4;
+ }
+}
+
+#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */
+#endif /* READ */
diff --git a/xs/src/png/libpng/intel/intel_init.c b/xs/src/png/libpng/intel/intel_init.c
new file mode 100644
index 000000000..8f08baf8c
--- /dev/null
+++ b/xs/src/png/libpng/intel/intel_init.c
@@ -0,0 +1,53 @@
+
+/* intel_init.c - SSE2 optimized filter functions
+ *
+ * Copyright (c) 2016-2017 Glenn Randers-Pehrson
+ * Written by Mike Klein and Matt Sarett, Google, Inc.
+ * Derived from arm/arm_init.c
+ *
+ * Last changed in libpng 1.6.29 [March 16, 2017]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+#if PNG_INTEL_SSE_IMPLEMENTATION > 0
+
+void
+png_init_filter_functions_sse2(png_structp pp, unsigned int bpp)
+{
+ /* The techniques used to implement each of these filters in SSE operate on
+ * one pixel at a time.
+ * So they generally speed up 3bpp images about 3x, 4bpp images about 4x.
+ * They can scale up to 6 and 8 bpp images and down to 2 bpp images,
+ * but they'd not likely have any benefit for 1bpp images.
+ * Most of these can be implemented using only MMX and 64-bit registers,
+ * but they end up a bit slower than using the equally-ubiquitous SSE2.
+ */
+ png_debug(1, "in png_init_filter_functions_sse2");
+ if (bpp == 3)
+ {
+ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_sse2;
+ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_sse2;
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+ png_read_filter_row_paeth3_sse2;
+ }
+ else if (bpp == 4)
+ {
+ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_sse2;
+ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_sse2;
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+ png_read_filter_row_paeth4_sse2;
+ }
+
+ /* No need optimize PNG_FILTER_VALUE_UP. The compiler should
+ * autovectorize.
+ */
+}
+
+#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */
+#endif /* PNG_READ_SUPPORTED */
diff --git a/xs/src/png/libpng/libpng-config.in b/xs/src/png/libpng/libpng-config.in
new file mode 100644
index 000000000..69bf8e33f
--- /dev/null
+++ b/xs/src/png/libpng/libpng-config.in
@@ -0,0 +1,127 @@
+#! /bin/sh
+
+# libpng-config
+# provides configuration info for libpng.
+
+# Copyright (C) 2002, 2004, 2006, 2007 Glenn Randers-Pehrson
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+# Modeled after libxml-config.
+
+version="@PNGLIB_VERSION@"
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+libdir="@libdir@"
+includedir="@includedir@/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@"
+libs="-lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@"
+all_libs="-lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@ @LIBS@"
+I_opts="-I${includedir}"
+L_opts="-L${libdir}"
+R_opts=""
+cppflags=""
+ccopts=""
+ldopts=""
+
+usage()
+{
+ cat <<EOF
+Usage: $0 [OPTION] ...
+
+Known values for OPTION are:
+
+ --prefix print libpng prefix
+ --libdir print path to directory containing library
+ --libs print library linking information
+ --ccopts print compiler options
+ --cppflags print pre-processor flags
+ --cflags print preprocessor flags, I_opts, and compiler options
+ --I_opts print "-I" include options
+ --L_opts print linker "-L" flags for dynamic linking
+ --R_opts print dynamic linker "-R" or "-rpath" flags
+ --ldopts print linker options
+ --ldflags print linker flags (ldopts, L_opts, R_opts, and libs)
+ --static revise subsequent outputs for static linking
+ --help print this help and exit
+ --version print version information
+EOF
+
+ exit $1
+}
+
+if test $# -eq 0; then
+ usage 1
+fi
+
+while test $# -gt 0; do
+ case "$1" in
+
+ --prefix)
+ echo ${prefix}
+ ;;
+
+ --version)
+ echo ${version}
+ exit 0
+ ;;
+
+ --help)
+ usage 0
+ ;;
+
+ --ccopts)
+ echo ${ccopts}
+ ;;
+
+ --cppflags)
+ echo ${cppflags}
+ ;;
+
+ --cflags)
+ echo ${I_opts} ${cppflags} ${ccopts}
+ ;;
+
+ --libdir)
+ echo ${libdir}
+ ;;
+
+ --libs)
+ echo ${libs}
+ ;;
+
+ --I_opts)
+ echo ${I_opts}
+ ;;
+
+ --L_opts)
+ echo ${L_opts}
+ ;;
+
+ --R_opts)
+ echo ${R_opts}
+ ;;
+
+ --ldopts)
+ echo ${ldopts}
+ ;;
+
+ --ldflags)
+ echo ${ldopts} ${L_opts} ${R_opts} ${libs}
+ ;;
+
+ --static)
+ R_opts=""
+ libs=${all_libs}
+ ;;
+
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+exit 0
diff --git a/xs/src/png/libpng/libpng.pc.in b/xs/src/png/libpng/libpng.pc.in
new file mode 100644
index 000000000..9708e9af2
--- /dev/null
+++ b/xs/src/png/libpng/libpng.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@
+
+Name: libpng
+Description: Loads and saves PNG files
+Version: @PNGLIB_VERSION@
+Requires: zlib
+Libs: -L${libdir} -lpng@PNGLIB_MAJOR@@PNGLIB_MINOR@
+Libs.private: @LIBS@
+Cflags: -I${includedir}
diff --git a/xs/src/png/libpng/mips/filter_msa_intrinsics.c b/xs/src/png/libpng/mips/filter_msa_intrinsics.c
new file mode 100644
index 000000000..943bb3d05
--- /dev/null
+++ b/xs/src/png/libpng/mips/filter_msa_intrinsics.c
@@ -0,0 +1,807 @@
+
+/* filter_msa_intrinsics.c - MSA optimised filter functions
+ *
+ * Copyright (c) 2016 Glenn Randers-Pehrson
+ * Written by Mandar Sahastrabuddhe, August 2016.
+ * Last changed in libpng 1.6.25 [September 1, 2016]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* This code requires -mfpu=msa on the command line: */
+#if PNG_MIPS_MSA_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
+
+#include <msa.h>
+
+/* libpng row pointers are not necessarily aligned to any particular boundary,
+ * however this code will only work with appropriate alignment. mips/mips_init.c
+ * checks for this (and will not compile unless it is done). This code uses
+ * variants of png_aligncast to avoid compiler warnings.
+ */
+#define png_ptr(type,pointer) png_aligncast(type *,pointer)
+#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)
+
+/* The following relies on a variable 'temp_pointer' being declared with type
+ * 'type'. This is written this way just to hide the GCC strict aliasing
+ * warning; note that the code is safe because there never is an alias between
+ * the input and output pointers.
+ */
+#define png_ldr(type,pointer)\
+ (temp_pointer = png_ptr(type,pointer), *temp_pointer)
+
+#if PNG_MIPS_MSA_OPT > 0
+
+#ifdef CLANG_BUILD
+ #define MSA_SRLI_B(a, b) __msa_srli_b((v16i8) a, b)
+
+ #define LW(psrc) \
+ ( { \
+ uint8_t *psrc_lw_m = (uint8_t *) (psrc); \
+ uint32_t val_m; \
+ \
+ asm volatile ( \
+ "lw %[val_m], %[psrc_lw_m] \n\t" \
+ \
+ : [val_m] "=r" (val_m) \
+ : [psrc_lw_m] "m" (*psrc_lw_m) \
+ ); \
+ \
+ val_m; \
+ } )
+
+ #define SH(val, pdst) \
+ { \
+ uint8_t *pdst_sh_m = (uint8_t *) (pdst); \
+ uint16_t val_m = (val); \
+ \
+ asm volatile ( \
+ "sh %[val_m], %[pdst_sh_m] \n\t" \
+ \
+ : [pdst_sh_m] "=m" (*pdst_sh_m) \
+ : [val_m] "r" (val_m) \
+ ); \
+ }
+
+ #define SW(val, pdst) \
+ { \
+ uint8_t *pdst_sw_m = (uint8_t *) (pdst); \
+ uint32_t val_m = (val); \
+ \
+ asm volatile ( \
+ "sw %[val_m], %[pdst_sw_m] \n\t" \
+ \
+ : [pdst_sw_m] "=m" (*pdst_sw_m) \
+ : [val_m] "r" (val_m) \
+ ); \
+ }
+
+ #if (__mips == 64)
+ #define SD(val, pdst) \
+ { \
+ uint8_t *pdst_sd_m = (uint8_t *) (pdst); \
+ uint64_t val_m = (val); \
+ \
+ asm volatile ( \
+ "sd %[val_m], %[pdst_sd_m] \n\t" \
+ \
+ : [pdst_sd_m] "=m" (*pdst_sd_m) \
+ : [val_m] "r" (val_m) \
+ ); \
+ }
+ #else
+ #define SD(val, pdst) \
+ { \
+ uint8_t *pdst_sd_m = (uint8_t *) (pdst); \
+ uint32_t val0_m, val1_m; \
+ \
+ val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF); \
+ val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF); \
+ \
+ SW(val0_m, pdst_sd_m); \
+ SW(val1_m, pdst_sd_m + 4); \
+ }
+ #endif
+#else
+ #define MSA_SRLI_B(a, b) (a >> b)
+
+#if (__mips_isa_rev >= 6)
+ #define LW(psrc) \
+ ( { \
+ uint8_t *psrc_lw_m = (uint8_t *) (psrc); \
+ uint32_t val_m; \
+ \
+ asm volatile ( \
+ "lw %[val_m], %[psrc_lw_m] \n\t" \
+ \
+ : [val_m] "=r" (val_m) \
+ : [psrc_lw_m] "m" (*psrc_lw_m) \
+ ); \
+ \
+ val_m; \
+ } )
+
+ #define SH(val, pdst) \
+ { \
+ uint8_t *pdst_sh_m = (uint8_t *) (pdst); \
+ uint16_t val_m = (val); \
+ \
+ asm volatile ( \
+ "sh %[val_m], %[pdst_sh_m] \n\t" \
+ \
+ : [pdst_sh_m] "=m" (*pdst_sh_m) \
+ : [val_m] "r" (val_m) \
+ ); \
+ }
+
+ #define SW(val, pdst) \
+ { \
+ uint8_t *pdst_sw_m = (uint8_t *) (pdst); \
+ uint32_t val_m = (val); \
+ \
+ asm volatile ( \
+ "sw %[val_m], %[pdst_sw_m] \n\t" \
+ \
+ : [pdst_sw_m] "=m" (*pdst_sw_m) \
+ : [val_m] "r" (val_m) \
+ ); \
+ }
+
+ #if (__mips == 64)
+ #define SD(val, pdst) \
+ { \
+ uint8_t *pdst_sd_m = (uint8_t *) (pdst); \
+ uint64_t val_m = (val); \
+ \
+ asm volatile ( \
+ "sd %[val_m], %[pdst_sd_m] \n\t" \
+ \
+ : [pdst_sd_m] "=m" (*pdst_sd_m) \
+ : [val_m] "r" (val_m) \
+ ); \
+ }
+ #else
+ #define SD(val, pdst) \
+ { \
+ uint8_t *pdst_sd_m = (uint8_t *) (pdst); \
+ uint32_t val0_m, val1_m; \
+ \
+ val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF); \
+ val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF); \
+ \
+ SW(val0_m, pdst_sd_m); \
+ SW(val1_m, pdst_sd_m + 4); \
+ }
+ #endif
+#else // !(__mips_isa_rev >= 6)
+ #define LW(psrc) \
+ ( { \
+ uint8_t *psrc_lw_m = (uint8_t *) (psrc); \
+ uint32_t val_m; \
+ \
+ asm volatile ( \
+ "ulw %[val_m], %[psrc_lw_m] \n\t" \
+ \
+ : [val_m] "=r" (val_m) \
+ : [psrc_lw_m] "m" (*psrc_lw_m) \
+ ); \
+ \
+ val_m; \
+ } )
+
+ #define SH(val, pdst) \
+ { \
+ uint8_t *pdst_sh_m = (uint8_t *) (pdst); \
+ uint16_t val_m = (val); \
+ \
+ asm volatile ( \
+ "ush %[val_m], %[pdst_sh_m] \n\t" \
+ \
+ : [pdst_sh_m] "=m" (*pdst_sh_m) \
+ : [val_m] "r" (val_m) \
+ ); \
+ }
+
+ #define SW(val, pdst) \
+ { \
+ uint8_t *pdst_sw_m = (uint8_t *) (pdst); \
+ uint32_t val_m = (val); \
+ \
+ asm volatile ( \
+ "usw %[val_m], %[pdst_sw_m] \n\t" \
+ \
+ : [pdst_sw_m] "=m" (*pdst_sw_m) \
+ : [val_m] "r" (val_m) \
+ ); \
+ }
+
+ #define SD(val, pdst) \
+ { \
+ uint8_t *pdst_sd_m = (uint8_t *) (pdst); \
+ uint32_t val0_m, val1_m; \
+ \
+ val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF); \
+ val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF); \
+ \
+ SW(val0_m, pdst_sd_m); \
+ SW(val1_m, pdst_sd_m + 4); \
+ }
+
+ #define SW_ZERO(pdst) \
+ { \
+ uint8_t *pdst_m = (uint8_t *) (pdst); \
+ \
+ asm volatile ( \
+ "usw $0, %[pdst_m] \n\t" \
+ \
+ : [pdst_m] "=m" (*pdst_m) \
+ : \
+ ); \
+ }
+#endif // (__mips_isa_rev >= 6)
+#endif
+
+#define LD_B(RTYPE, psrc) *((RTYPE *) (psrc))
+#define LD_UB(...) LD_B(v16u8, __VA_ARGS__)
+#define LD_B2(RTYPE, psrc, stride, out0, out1) \
+{ \
+ out0 = LD_B(RTYPE, (psrc)); \
+ out1 = LD_B(RTYPE, (psrc) + stride); \
+}
+#define LD_UB2(...) LD_B2(v16u8, __VA_ARGS__)
+#define LD_B4(RTYPE, psrc, stride, out0, out1, out2, out3) \
+{ \
+ LD_B2(RTYPE, (psrc), stride, out0, out1); \
+ LD_B2(RTYPE, (psrc) + 2 * stride , stride, out2, out3); \
+}
+#define LD_UB4(...) LD_B4(v16u8, __VA_ARGS__)
+
+#define ST_B(RTYPE, in, pdst) *((RTYPE *) (pdst)) = (in)
+#define ST_UB(...) ST_B(v16u8, __VA_ARGS__)
+#define ST_B2(RTYPE, in0, in1, pdst, stride) \
+{ \
+ ST_B(RTYPE, in0, (pdst)); \
+ ST_B(RTYPE, in1, (pdst) + stride); \
+}
+#define ST_UB2(...) ST_B2(v16u8, __VA_ARGS__)
+#define ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride) \
+{ \
+ ST_B2(RTYPE, in0, in1, (pdst), stride); \
+ ST_B2(RTYPE, in2, in3, (pdst) + 2 * stride, stride); \
+}
+#define ST_UB4(...) ST_B4(v16u8, __VA_ARGS__)
+
+#define ADD2(in0, in1, in2, in3, out0, out1) \
+{ \
+ out0 = in0 + in1; \
+ out1 = in2 + in3; \
+}
+#define ADD3(in0, in1, in2, in3, in4, in5, \
+ out0, out1, out2) \
+{ \
+ ADD2(in0, in1, in2, in3, out0, out1); \
+ out2 = in4 + in5; \
+}
+#define ADD4(in0, in1, in2, in3, in4, in5, in6, in7, \
+ out0, out1, out2, out3) \
+{ \
+ ADD2(in0, in1, in2, in3, out0, out1); \
+ ADD2(in4, in5, in6, in7, out2, out3); \
+}
+
+#define ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1) \
+{ \
+ out0 = (RTYPE) __msa_ilvr_b((v16i8) in0, (v16i8) in1); \
+ out1 = (RTYPE) __msa_ilvr_b((v16i8) in2, (v16i8) in3); \
+}
+#define ILVR_B2_SH(...) ILVR_B2(v8i16, __VA_ARGS__)
+
+#define HSUB_UB2(RTYPE, in0, in1, out0, out1) \
+{ \
+ out0 = (RTYPE) __msa_hsub_u_h((v16u8) in0, (v16u8) in0); \
+ out1 = (RTYPE) __msa_hsub_u_h((v16u8) in1, (v16u8) in1); \
+}
+#define HSUB_UB2_SH(...) HSUB_UB2(v8i16, __VA_ARGS__)
+
+#define SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val) \
+{ \
+ v16i8 zero_m = { 0 }; \
+ out0 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in0, slide_val); \
+ out1 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in1, slide_val); \
+}
+#define SLDI_B2_0_UB(...) SLDI_B2_0(v16u8, __VA_ARGS__)
+
+#define SLDI_B3_0(RTYPE, in0, in1, in2, out0, out1, out2, slide_val) \
+{ \
+ v16i8 zero_m = { 0 }; \
+ SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val); \
+ out2 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in2, slide_val); \
+}
+#define SLDI_B3_0_UB(...) SLDI_B3_0(v16u8, __VA_ARGS__)
+
+#define ILVEV_W2(RTYPE, in0, in1, in2, in3, out0, out1) \
+{ \
+ out0 = (RTYPE) __msa_ilvev_w((v4i32) in1, (v4i32) in0); \
+ out1 = (RTYPE) __msa_ilvev_w((v4i32) in3, (v4i32) in2); \
+}
+#define ILVEV_W2_UB(...) ILVEV_W2(v16u8, __VA_ARGS__)
+
+#define ADD_ABS_H3(RTYPE, in0, in1, in2, out0, out1, out2) \
+{ \
+ RTYPE zero = {0}; \
+ \
+ out0 = __msa_add_a_h((v8i16) zero, in0); \
+ out1 = __msa_add_a_h((v8i16) zero, in1); \
+ out2 = __msa_add_a_h((v8i16) zero, in2); \
+}
+#define ADD_ABS_H3_SH(...) ADD_ABS_H3(v8i16, __VA_ARGS__)
+
+#define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) \
+{ \
+ out0 = (RTYPE) __msa_vshf_b((v16i8) mask0, (v16i8) in1, (v16i8) in0); \
+ out1 = (RTYPE) __msa_vshf_b((v16i8) mask1, (v16i8) in3, (v16i8) in2); \
+}
+#define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__)
+
+#define CMP_AND_SELECT(inp0, inp1, inp2, inp3, inp4, inp5, out0) \
+{ \
+ v8i16 _sel_h0, _sel_h1; \
+ v16u8 _sel_b0, _sel_b1; \
+ _sel_h0 = (v8i16) __msa_clt_u_h((v8u16) inp1, (v8u16) inp0); \
+ _sel_b0 = (v16u8) __msa_pckev_b((v16i8) _sel_h0, (v16i8) _sel_h0); \
+ inp0 = (v8i16) __msa_bmnz_v((v16u8) inp0, (v16u8) inp1, (v16u8) _sel_h0); \
+ inp4 = (v16u8) __msa_bmnz_v(inp3, inp4, _sel_b0); \
+ _sel_h1 = (v8i16) __msa_clt_u_h((v8u16) inp2, (v8u16) inp0); \
+ _sel_b1 = (v16u8) __msa_pckev_b((v16i8) _sel_h1, (v16i8) _sel_h1); \
+ inp4 = (v16u8) __msa_bmnz_v(inp4, inp5, _sel_b1); \
+ out0 += inp4; \
+}
+
+void png_read_filter_row_up_msa(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_size_t i, cnt, cnt16, cnt32;
+ png_size_t istop = row_info->rowbytes;
+ png_bytep rp = row;
+ png_const_bytep pp = prev_row;
+ v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
+
+ for (i = 0; i < (istop >> 6); i++)
+ {
+ LD_UB4(rp, 16, src0, src1, src2, src3);
+ LD_UB4(pp, 16, src4, src5, src6, src7);
+ pp += 64;
+
+ ADD4(src0, src4, src1, src5, src2, src6, src3, src7,
+ src0, src1, src2, src3);
+
+ ST_UB4(src0, src1, src2, src3, rp, 16);
+ rp += 64;
+ }
+
+ if (istop & 0x3F)
+ {
+ cnt32 = istop & 0x20;
+ cnt16 = istop & 0x10;
+ cnt = istop & 0xF;
+
+ if(cnt32)
+ {
+ if (cnt16 && cnt)
+ {
+ LD_UB4(rp, 16, src0, src1, src2, src3);
+ LD_UB4(pp, 16, src4, src5, src6, src7);
+
+ ADD4(src0, src4, src1, src5, src2, src6, src3, src7,
+ src0, src1, src2, src3);
+
+ ST_UB4(src0, src1, src2, src3, rp, 16);
+ rp += 64;
+ }
+ else if (cnt16 || cnt)
+ {
+ LD_UB2(rp, 16, src0, src1);
+ LD_UB2(pp, 16, src4, src5);
+ pp += 32;
+ src2 = LD_UB(rp + 32);
+ src6 = LD_UB(pp);
+
+ ADD3(src0, src4, src1, src5, src2, src6, src0, src1, src2);
+
+ ST_UB2(src0, src1, rp, 16);
+ rp += 32;
+ ST_UB(src2, rp);
+ rp += 16;
+ }
+ else
+ {
+ LD_UB2(rp, 16, src0, src1);
+ LD_UB2(pp, 16, src4, src5);
+
+ ADD2(src0, src4, src1, src5, src0, src1);
+
+ ST_UB2(src0, src1, rp, 16);
+ rp += 32;
+ }
+ }
+ else if (cnt16 && cnt)
+ {
+ LD_UB2(rp, 16, src0, src1);
+ LD_UB2(pp, 16, src4, src5);
+
+ ADD2(src0, src4, src1, src5, src0, src1);
+
+ ST_UB2(src0, src1, rp, 16);
+ rp += 32;
+ }
+ else if (cnt16 || cnt)
+ {
+ src0 = LD_UB(rp);
+ src4 = LD_UB(pp);
+ pp += 16;
+
+ src0 += src4;
+
+ ST_UB(src0, rp);
+ rp += 16;
+ }
+ }
+}
+
+void png_read_filter_row_sub4_msa(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_size_t count;
+ png_size_t istop = row_info->rowbytes;
+ png_bytep src = row;
+ png_bytep nxt = row + 4;
+ int32_t inp0;
+ v16u8 src0, src1, src2, src3, src4;
+ v16u8 dst0, dst1;
+ v16u8 zero = { 0 };
+
+ istop -= 4;
+
+ inp0 = LW(src);
+ src += 4;
+ src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+
+ for (count = 0; count < istop; count += 16)
+ {
+ src1 = LD_UB(src);
+ src += 16;
+
+ src2 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 4);
+ src3 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 8);
+ src4 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 12);
+ src1 += src0;
+ src2 += src1;
+ src3 += src2;
+ src4 += src3;
+ src0 = src4;
+ ILVEV_W2_UB(src1, src2, src3, src4, dst0, dst1);
+ dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0);
+
+ ST_UB(dst0, nxt);
+ nxt += 16;
+ }
+}
+
+void png_read_filter_row_sub3_msa(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_size_t count;
+ png_size_t istop = row_info->rowbytes;
+ png_bytep src = row;
+ png_bytep nxt = row + 3;
+ int64_t out0;
+ int32_t inp0, out1;
+ v16u8 src0, src1, src2, src3, src4, dst0, dst1;
+ v16u8 zero = { 0 };
+ v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 };
+
+ istop -= 3;
+
+ inp0 = LW(src);
+ src += 3;
+ src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+
+ for (count = 0; count < istop; count += 12)
+ {
+ src1 = LD_UB(src);
+ src += 12;
+
+ src2 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 3);
+ src3 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 6);
+ src4 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 9);
+ src1 += src0;
+ src2 += src1;
+ src3 += src2;
+ src4 += src3;
+ src0 = src4;
+ VSHF_B2_UB(src1, src2, src3, src4, mask0, mask0, dst0, dst1);
+ dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0);
+ out0 = __msa_copy_s_d((v2i64) dst0, 0);
+ out1 = __msa_copy_s_w((v4i32) dst0, 2);
+
+ SD(out0, nxt);
+ nxt += 8;
+ SW(out1, nxt);
+ nxt += 4;
+ }
+}
+
+void png_read_filter_row_avg4_msa(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_size_t i;
+ png_bytep src = row;
+ png_bytep nxt = row;
+ png_const_bytep pp = prev_row;
+ png_size_t istop = row_info->rowbytes - 4;
+ int32_t inp0, inp1, out0;
+ v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1;
+ v16u8 zero = { 0 };
+
+ inp0 = LW(pp);
+ pp += 4;
+ inp1 = LW(src);
+ src += 4;
+ src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+ src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
+ src0 = (v16u8) MSA_SRLI_B(src0, 1);
+ src1 += src0;
+ out0 = __msa_copy_s_w((v4i32) src1, 0);
+ SW(out0, nxt);
+ nxt += 4;
+
+ for (i = 0; i < istop; i += 16)
+ {
+ src2 = LD_UB(pp);
+ pp += 16;
+ src6 = LD_UB(src);
+ src += 16;
+
+ SLDI_B2_0_UB(src2, src6, src3, src7, 4);
+ SLDI_B2_0_UB(src2, src6, src4, src8, 8);
+ SLDI_B2_0_UB(src2, src6, src5, src9, 12);
+ src2 = __msa_ave_u_b(src2, src1);
+ src6 += src2;
+ src3 = __msa_ave_u_b(src3, src6);
+ src7 += src3;
+ src4 = __msa_ave_u_b(src4, src7);
+ src8 += src4;
+ src5 = __msa_ave_u_b(src5, src8);
+ src9 += src5;
+ src1 = src9;
+ ILVEV_W2_UB(src6, src7, src8, src9, dst0, dst1);
+ dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0);
+
+ ST_UB(dst0, nxt);
+ nxt += 16;
+ }
+}
+
+void png_read_filter_row_avg3_msa(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_size_t i;
+ png_bytep src = row;
+ png_bytep nxt = row;
+ png_const_bytep pp = prev_row;
+ png_size_t istop = row_info->rowbytes - 3;
+ int64_t out0;
+ int32_t inp0, inp1, out1;
+ int16_t out2;
+ v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1;
+ v16u8 zero = { 0 };
+ v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 };
+
+ inp0 = LW(pp);
+ pp += 3;
+ inp1 = LW(src);
+ src += 3;
+ src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+ src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
+ src0 = (v16u8) MSA_SRLI_B(src0, 1);
+ src1 += src0;
+ out2 = __msa_copy_s_h((v8i16) src1, 0);
+ SH(out2, nxt);
+ nxt += 2;
+ nxt[0] = src1[2];
+ nxt++;
+
+ for (i = 0; i < istop; i += 12)
+ {
+ src2 = LD_UB(pp);
+ pp += 12;
+ src6 = LD_UB(src);
+ src += 12;
+
+ SLDI_B2_0_UB(src2, src6, src3, src7, 3);
+ SLDI_B2_0_UB(src2, src6, src4, src8, 6);
+ SLDI_B2_0_UB(src2, src6, src5, src9, 9);
+ src2 = __msa_ave_u_b(src2, src1);
+ src6 += src2;
+ src3 = __msa_ave_u_b(src3, src6);
+ src7 += src3;
+ src4 = __msa_ave_u_b(src4, src7);
+ src8 += src4;
+ src5 = __msa_ave_u_b(src5, src8);
+ src9 += src5;
+ src1 = src9;
+ VSHF_B2_UB(src6, src7, src8, src9, mask0, mask0, dst0, dst1);
+ dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0);
+ out0 = __msa_copy_s_d((v2i64) dst0, 0);
+ out1 = __msa_copy_s_w((v4i32) dst0, 2);
+
+ SD(out0, nxt);
+ nxt += 8;
+ SW(out1, nxt);
+ nxt += 4;
+ }
+}
+
+void png_read_filter_row_paeth4_msa(png_row_infop row_info,
+ png_bytep row,
+ png_const_bytep prev_row)
+{
+ int32_t count, rp_end;
+ png_bytep nxt;
+ png_const_bytep prev_nxt;
+ int32_t inp0, inp1, res0;
+ v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9;
+ v16u8 src10, src11, src12, src13, dst0, dst1;
+ v8i16 vec0, vec1, vec2;
+ v16u8 zero = { 0 };
+
+ nxt = row;
+ prev_nxt = prev_row;
+
+ inp0 = LW(nxt);
+ inp1 = LW(prev_nxt);
+ prev_nxt += 4;
+ src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+ src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
+
+ src1 += src0;
+ res0 = __msa_copy_s_w((v4i32) src1, 0);
+
+ SW(res0, nxt);
+ nxt += 4;
+
+ /* Remainder */
+ rp_end = row_info->rowbytes - 4;
+
+ for (count = 0; count < rp_end; count += 16)
+ {
+ src2 = LD_UB(prev_nxt);
+ prev_nxt += 16;
+ src6 = LD_UB(prev_row);
+ prev_row += 16;
+ src10 = LD_UB(nxt);
+
+ SLDI_B3_0_UB(src2, src6, src10, src3, src7, src11, 4);
+ SLDI_B3_0_UB(src2, src6, src10, src4, src8, src12, 8);
+ SLDI_B3_0_UB(src2, src6, src10, src5, src9, src13, 12);
+ ILVR_B2_SH(src2, src6, src1, src6, vec0, vec1);
+ HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+ vec2 = vec0 + vec1;
+ ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+ CMP_AND_SELECT(vec0, vec1, vec2, src1, src2, src6, src10);
+ ILVR_B2_SH(src3, src7, src10, src7, vec0, vec1);
+ HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+ vec2 = vec0 + vec1;
+ ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+ CMP_AND_SELECT(vec0, vec1, vec2, src10, src3, src7, src11);
+ ILVR_B2_SH(src4, src8, src11, src8, vec0, vec1);
+ HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+ vec2 = vec0 + vec1;
+ ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+ CMP_AND_SELECT(vec0, vec1, vec2, src11, src4, src8, src12);
+ ILVR_B2_SH(src5, src9, src12, src9, vec0, vec1);
+ HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+ vec2 = vec0 + vec1;
+ ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+ CMP_AND_SELECT(vec0, vec1, vec2, src12, src5, src9, src13);
+ src1 = src13;
+ ILVEV_W2_UB(src10, src11, src12, src1, dst0, dst1);
+ dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0);
+
+ ST_UB(dst0, nxt);
+ nxt += 16;
+ }
+}
+
+void png_read_filter_row_paeth3_msa(png_row_infop row_info,
+ png_bytep row,
+ png_const_bytep prev_row)
+{
+ int32_t count, rp_end;
+ png_bytep nxt;
+ png_const_bytep prev_nxt;
+ int64_t out0;
+ int32_t inp0, inp1, out1;
+ int16_t out2;
+ v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1;
+ v16u8 src10, src11, src12, src13;
+ v8i16 vec0, vec1, vec2;
+ v16u8 zero = { 0 };
+ v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 };
+
+ nxt = row;
+ prev_nxt = prev_row;
+
+ inp0 = LW(nxt);
+ inp1 = LW(prev_nxt);
+ prev_nxt += 3;
+ src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
+ src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
+
+ src1 += src0;
+ out2 = __msa_copy_s_h((v8i16) src1, 0);
+
+ SH(out2, nxt);
+ nxt += 2;
+ nxt[0] = src1[2];
+ nxt++;
+
+ /* Remainder */
+ rp_end = row_info->rowbytes - 3;
+
+ for (count = 0; count < rp_end; count += 12)
+ {
+ src2 = LD_UB(prev_nxt);
+ prev_nxt += 12;
+ src6 = LD_UB(prev_row);
+ prev_row += 12;
+ src10 = LD_UB(nxt);
+
+ SLDI_B3_0_UB(src2, src6, src10, src3, src7, src11, 3);
+ SLDI_B3_0_UB(src2, src6, src10, src4, src8, src12, 6);
+ SLDI_B3_0_UB(src2, src6, src10, src5, src9, src13, 9);
+ ILVR_B2_SH(src2, src6, src1, src6, vec0, vec1);
+ HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+ vec2 = vec0 + vec1;
+ ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+ CMP_AND_SELECT(vec0, vec1, vec2, src1, src2, src6, src10);
+ ILVR_B2_SH(src3, src7, src10, src7, vec0, vec1);
+ HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+ vec2 = vec0 + vec1;
+ ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+ CMP_AND_SELECT(vec0, vec1, vec2, src10, src3, src7, src11);
+ ILVR_B2_SH(src4, src8, src11, src8, vec0, vec1);
+ HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+ vec2 = vec0 + vec1;
+ ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+ CMP_AND_SELECT(vec0, vec1, vec2, src11, src4, src8, src12);
+ ILVR_B2_SH(src5, src9, src12, src9, vec0, vec1);
+ HSUB_UB2_SH(vec0, vec1, vec0, vec1);
+ vec2 = vec0 + vec1;
+ ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
+ CMP_AND_SELECT(vec0, vec1, vec2, src12, src5, src9, src13);
+ src1 = src13;
+ VSHF_B2_UB(src10, src11, src12, src13, mask0, mask0, dst0, dst1);
+ dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0);
+ out0 = __msa_copy_s_d((v2i64) dst0, 0);
+ out1 = __msa_copy_s_w((v4i32) dst0, 2);
+
+ SD(out0, nxt);
+ nxt += 8;
+ SW(out1, nxt);
+ nxt += 4;
+ }
+}
+
+#endif /* PNG_MIPS_MSA_OPT > 0 */
+#endif /* PNG_MIPS_MSA_IMPLEMENTATION == 1 (intrinsics) */
+#endif /* READ */
diff --git a/xs/src/png/libpng/mips/mips_init.c b/xs/src/png/libpng/mips/mips_init.c
new file mode 100644
index 000000000..0bfb7a32e
--- /dev/null
+++ b/xs/src/png/libpng/mips/mips_init.c
@@ -0,0 +1,129 @@
+
+/* mips_init.c - MSA optimised filter functions
+ *
+ * Copyright (c) 2016 Glenn Randers-Pehrson
+ * Written by Mandar Sahastrabuddhe, 2016.
+ * Last changed in libpng 1.6.25 [September 1, 2016]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
+ * called.
+ */
+#define _POSIX_SOURCE 1
+
+#include <stdio.h>
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+#if PNG_MIPS_MSA_OPT > 0
+#ifdef PNG_MIPS_MSA_CHECK_SUPPORTED /* Do run-time checks */
+/* WARNING: it is strongly recommended that you do not build libpng with
+ * run-time checks for CPU features if at all possible. In the case of the MIPS
+ * MSA instructions there is no processor-specific way of detecting the
+ * presence of the required support, therefore run-time detection is extremely
+ * OS specific.
+ *
+ * You may set the macro PNG_MIPS_MSA_FILE to the file name of file containing
+ * a fragment of C source code which defines the png_have_msa function. There
+ * are a number of implementations in contrib/mips-msa, but the only one that
+ * has partial support is contrib/mips-msa/linux.c - a generic Linux
+ * implementation which reads /proc/cpufino.
+ */
+#ifndef PNG_MIPS_MSA_FILE
+# ifdef __linux__
+# define PNG_MIPS_MSA_FILE "contrib/mips-msa/linux.c"
+# endif
+#endif
+
+#ifdef PNG_MIPS_MSA_FILE
+
+#include <signal.h> /* for sig_atomic_t */
+static int png_have_msa(png_structp png_ptr);
+#include PNG_MIPS_MSA_FILE
+
+#else /* PNG_MIPS_MSA_FILE */
+# error "PNG_MIPS_MSA_FILE undefined: no support for run-time MIPS MSA checks"
+#endif /* PNG_MIPS_MSA_FILE */
+#endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
+
+#ifndef PNG_ALIGNED_MEMORY_SUPPORTED
+# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
+#endif
+
+void
+png_init_filter_functions_msa(png_structp pp, unsigned int bpp)
+{
+ /* The switch statement is compiled in for MIPS_MSA_API, the call to
+ * png_have_msa is compiled in for MIPS_MSA_CHECK. If both are defined
+ * the check is only performed if the API has not set the MSA option on
+ * or off explicitly. In this case the check controls what happens.
+ */
+
+#ifdef PNG_MIPS_MSA_API_SUPPORTED
+ switch ((pp->options >> PNG_MIPS_MSA) & 3)
+ {
+ case PNG_OPTION_UNSET:
+ /* Allow the run-time check to execute if it has been enabled -
+ * thus both API and CHECK can be turned on. If it isn't supported
+ * this case will fall through to the 'default' below, which just
+ * returns.
+ */
+#endif /* PNG_MIPS_MSA_API_SUPPORTED */
+#ifdef PNG_MIPS_MSA_CHECK_SUPPORTED
+ {
+ static volatile sig_atomic_t no_msa = -1; /* not checked */
+
+ if (no_msa < 0)
+ no_msa = !png_have_msa(pp);
+
+ if (no_msa)
+ return;
+ }
+#ifdef PNG_MIPS_MSA_API_SUPPORTED
+ break;
+#endif
+#endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
+
+#ifdef PNG_MIPS_MSA_API_SUPPORTED
+ default: /* OFF or INVALID */
+ return;
+
+ case PNG_OPTION_ON:
+ /* Option turned on */
+ break;
+ }
+#endif
+
+ /* IMPORTANT: any new external functions used here must be declared using
+ * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the
+ * 'prefix' option to configure works:
+ *
+ * ./configure --with-libpng-prefix=foobar_
+ *
+ * Verify you have got this right by running the above command, doing a build
+ * and examining pngprefix.h; it must contain a #define for every external
+ * function you add. (Notice that this happens automatically for the
+ * initialization function.)
+ */
+ pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_msa;
+
+ if (bpp == 3)
+ {
+ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_msa;
+ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_msa;
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_msa;
+ }
+
+ else if (bpp == 4)
+ {
+ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_msa;
+ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_msa;
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_msa;
+ }
+}
+#endif /* PNG_MIPS_MSA_OPT > 0 */
+#endif /* READ */
diff --git a/xs/src/png/libpng/png.c b/xs/src/png/libpng/png.c
new file mode 100644
index 000000000..ff02c5651
--- /dev/null
+++ b/xs/src/png/libpng/png.c
@@ -0,0 +1,4614 @@
+
+/* png.c - location for general purpose libpng functions
+ *
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef png_libpng_version_1_6_34 Your_png_h_is_not_version_1_6_34;
+
+#ifdef __GNUC__
+/* The version tests may need to be added to, but the problem warning has
+ * consistently been fixed in GCC versions which obtain wide-spread release.
+ * The problem is that many versions of GCC rearrange comparison expressions in
+ * the optimizer in such a way that the results of the comparison will change
+ * if signed integer overflow occurs. Such comparisons are not permitted in
+ * ANSI C90, however GCC isn't clever enough to work out that that do not occur
+ * below in png_ascii_from_fp and png_muldiv, so it produces a warning with
+ * -Wextra. Unfortunately this is highly dependent on the optimizer and the
+ * machine architecture so the warning comes and goes unpredictably and is
+ * impossible to "fix", even were that a good idea.
+ */
+#if __GNUC__ == 7 && __GNUC_MINOR__ == 1
+#define GCC_STRICT_OVERFLOW 1
+#endif /* GNU 7.1.x */
+#endif /* GNU */
+#ifndef GCC_STRICT_OVERFLOW
+#define GCC_STRICT_OVERFLOW 0
+#endif
+
+/* Tells libpng that we have already handled the first "num_bytes" bytes
+ * of the PNG file signature. If the PNG data is embedded into another
+ * stream we can set num_bytes = 8 so that libpng will not attempt to read
+ * or write any of the magic bytes before it starts on the IHDR.
+ */
+
+#ifdef PNG_READ_SUPPORTED
+void PNGAPI
+png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
+{
+ unsigned int nb = (unsigned int)num_bytes;
+
+ png_debug(1, "in png_set_sig_bytes");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (num_bytes < 0)
+ nb = 0;
+
+ if (nb > 8)
+ png_error(png_ptr, "Too many bytes for PNG signature");
+
+ png_ptr->sig_bytes = (png_byte)nb;
+}
+
+/* Checks whether the supplied bytes match the PNG signature. We allow
+ * checking less than the full 8-byte signature so that those apps that
+ * already read the first few bytes of a file to determine the file type
+ * can simply check the remaining bytes for extra assurance. Returns
+ * an integer less than, equal to, or greater than zero if sig is found,
+ * respectively, to be less than, to match, or be greater than the correct
+ * PNG signature (this is the same behavior as strcmp, memcmp, etc).
+ */
+int PNGAPI
+png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
+{
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+ if (num_to_check > 8)
+ num_to_check = 8;
+
+ else if (num_to_check < 1)
+ return (-1);
+
+ if (start > 7)
+ return (-1);
+
+ if (start + num_to_check > 8)
+ num_to_check = 8 - start;
+
+ return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
+}
+
+#endif /* READ */
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Function to allocate memory for zlib */
+PNG_FUNCTION(voidpf /* PRIVATE */,
+png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
+{
+ png_alloc_size_t num_bytes = size;
+
+ if (png_ptr == NULL)
+ return NULL;
+
+ if (items >= (~(png_alloc_size_t)0)/size)
+ {
+ png_warning (png_voidcast(png_structrp, png_ptr),
+ "Potential overflow in png_zalloc()");
+ return NULL;
+ }
+
+ num_bytes *= items;
+ return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes);
+}
+
+/* Function to free memory for zlib */
+void /* PRIVATE */
+png_zfree(voidpf png_ptr, voidpf ptr)
+{
+ png_free(png_voidcast(png_const_structrp,png_ptr), ptr);
+}
+
+/* Reset the CRC variable to 32 bits of 1's. Care must be taken
+ * in case CRC is > 32 bits to leave the top bits 0.
+ */
+void /* PRIVATE */
+png_reset_crc(png_structrp png_ptr)
+{
+ /* The cast is safe because the crc is a 32-bit value. */
+ png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
+}
+
+/* Calculate the CRC over a section of data. We can only pass as
+ * much data to this routine as the largest single buffer size. We
+ * also check that this data will actually be used before going to the
+ * trouble of calculating it.
+ */
+void /* PRIVATE */
+png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)
+{
+ int need_crc = 1;
+
+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+ (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ need_crc = 0;
+ }
+
+ else /* critical */
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
+ need_crc = 0;
+ }
+
+ /* 'uLong' is defined in zlib.h as unsigned long; this means that on some
+ * systems it is a 64-bit value. crc32, however, returns 32 bits so the
+ * following cast is safe. 'uInt' may be no more than 16 bits, so it is
+ * necessary to perform a loop here.
+ */
+ if (need_crc != 0 && length > 0)
+ {
+ uLong crc = png_ptr->crc; /* Should never issue a warning */
+
+ do
+ {
+ uInt safe_length = (uInt)length;
+#ifndef __COVERITY__
+ if (safe_length == 0)
+ safe_length = (uInt)-1; /* evil, but safe */
+#endif
+
+ crc = crc32(crc, ptr, safe_length);
+
+ /* The following should never issue compiler warnings; if they do the
+ * target system has characteristics that will probably violate other
+ * assumptions within the libpng code.
+ */
+ ptr += safe_length;
+ length -= safe_length;
+ }
+ while (length > 0);
+
+ /* And the following is always safe because the crc is only 32 bits. */
+ png_ptr->crc = (png_uint_32)crc;
+ }
+}
+
+/* Check a user supplied version number, called from both read and write
+ * functions that create a png_struct.
+ */
+int
+png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
+{
+ /* Libpng versions 1.0.0 and later are binary compatible if the version
+ * string matches through the second '.'; we must recompile any
+ * applications that use any older library version.
+ */
+
+ if (user_png_ver != NULL)
+ {
+ int i = -1;
+ int found_dots = 0;
+
+ do
+ {
+ i++;
+ if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i])
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+ if (user_png_ver[i] == '.')
+ found_dots++;
+ } while (found_dots < 2 && user_png_ver[i] != 0 &&
+ PNG_LIBPNG_VER_STRING[i] != 0);
+ }
+
+ else
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+
+ if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0)
+ {
+#ifdef PNG_WARNINGS_SUPPORTED
+ size_t pos = 0;
+ char m[128];
+
+ pos = png_safecat(m, (sizeof m), pos,
+ "Application built with libpng-");
+ pos = png_safecat(m, (sizeof m), pos, user_png_ver);
+ pos = png_safecat(m, (sizeof m), pos, " but running with ");
+ pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING);
+ PNG_UNUSED(pos)
+
+ png_warning(png_ptr, m);
+#endif
+
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags = 0;
+#endif
+
+ return 0;
+ }
+
+ /* Success return. */
+ return 1;
+}
+
+/* Generic function to create a png_struct for either read or write - this
+ * contains the common initialization.
+ */
+PNG_FUNCTION(png_structp /* PRIVATE */,
+png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
+{
+ png_struct create_struct;
+# ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf create_jmp_buf;
+# endif
+
+ /* This temporary stack-allocated structure is used to provide a place to
+ * build enough context to allow the user provided memory allocator (if any)
+ * to be called.
+ */
+ memset(&create_struct, 0, (sizeof create_struct));
+
+ /* Added at libpng-1.2.6 */
+# ifdef PNG_USER_LIMITS_SUPPORTED
+ create_struct.user_width_max = PNG_USER_WIDTH_MAX;
+ create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
+
+# ifdef PNG_USER_CHUNK_CACHE_MAX
+ /* Added at libpng-1.2.43 and 1.4.0 */
+ create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
+# endif
+
+# ifdef PNG_USER_CHUNK_MALLOC_MAX
+ /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists
+ * in png_struct regardless.
+ */
+ create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+# endif
+
+ /* The following two API calls simply set fields in png_struct, so it is safe
+ * to do them now even though error handling is not yet set up.
+ */
+# ifdef PNG_USER_MEM_SUPPORTED
+ png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
+# else
+ PNG_UNUSED(mem_ptr)
+ PNG_UNUSED(malloc_fn)
+ PNG_UNUSED(free_fn)
+# endif
+
+ /* (*error_fn) can return control to the caller after the error_ptr is set,
+ * this will result in a memory leak unless the error_fn does something
+ * extremely sophisticated. The design lacks merit but is implicit in the
+ * API.
+ */
+ png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
+
+# ifdef PNG_SETJMP_SUPPORTED
+ if (!setjmp(create_jmp_buf))
+# endif
+ {
+# ifdef PNG_SETJMP_SUPPORTED
+ /* Temporarily fake out the longjmp information until we have
+ * successfully completed this function. This only works if we have
+ * setjmp() support compiled in, but it is safe - this stuff should
+ * never happen.
+ */
+ create_struct.jmp_buf_ptr = &create_jmp_buf;
+ create_struct.jmp_buf_size = 0; /*stack allocation*/
+ create_struct.longjmp_fn = longjmp;
+# endif
+ /* Call the general version checker (shared with read and write code):
+ */
+ if (png_user_version_check(&create_struct, user_png_ver) != 0)
+ {
+ png_structrp png_ptr = png_voidcast(png_structrp,
+ png_malloc_warn(&create_struct, (sizeof *png_ptr)));
+
+ if (png_ptr != NULL)
+ {
+ /* png_ptr->zstream holds a back-pointer to the png_struct, so
+ * this can only be done now:
+ */
+ create_struct.zstream.zalloc = png_zalloc;
+ create_struct.zstream.zfree = png_zfree;
+ create_struct.zstream.opaque = png_ptr;
+
+# ifdef PNG_SETJMP_SUPPORTED
+ /* Eliminate the local error handling: */
+ create_struct.jmp_buf_ptr = NULL;
+ create_struct.jmp_buf_size = 0;
+ create_struct.longjmp_fn = 0;
+# endif
+
+ *png_ptr = create_struct;
+
+ /* This is the successful return point */
+ return png_ptr;
+ }
+ }
+ }
+
+ /* A longjmp because of a bug in the application storage allocator or a
+ * simple failure to allocate the png_struct.
+ */
+ return NULL;
+}
+
+/* Allocate the memory for an info_struct for the application. */
+PNG_FUNCTION(png_infop,PNGAPI
+png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
+{
+ png_inforp info_ptr;
+
+ png_debug(1, "in png_create_info_struct");
+
+ if (png_ptr == NULL)
+ return NULL;
+
+ /* Use the internal API that does not (or at least should not) error out, so
+ * that this call always returns ok. The application typically sets up the
+ * error handling *after* creating the info_struct because this is the way it
+ * has always been done in 'example.c'.
+ */
+ info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
+ (sizeof *info_ptr)));
+
+ if (info_ptr != NULL)
+ memset(info_ptr, 0, (sizeof *info_ptr));
+
+ return info_ptr;
+}
+
+/* This function frees the memory associated with a single info struct.
+ * Normally, one would use either png_destroy_read_struct() or
+ * png_destroy_write_struct() to free an info struct, but this may be
+ * useful for some applications. From libpng 1.6.0 this function is also used
+ * internally to implement the png_info release part of the 'struct' destroy
+ * APIs. This ensures that all possible approaches free the same data (all of
+ * it).
+ */
+void PNGAPI
+png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
+{
+ png_inforp info_ptr = NULL;
+
+ png_debug(1, "in png_destroy_info_struct");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (info_ptr_ptr != NULL)
+ info_ptr = *info_ptr_ptr;
+
+ if (info_ptr != NULL)
+ {
+ /* Do this first in case of an error below; if the app implements its own
+ * memory management this can lead to png_free calling png_error, which
+ * will abort this routine and return control to the app error handler.
+ * An infinite loop may result if it then tries to free the same info
+ * ptr.
+ */
+ *info_ptr_ptr = NULL;
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+ memset(info_ptr, 0, (sizeof *info_ptr));
+ png_free(png_ptr, info_ptr);
+ }
+}
+
+/* Initialize the info structure. This is now an internal function (0.89)
+ * and applications using it are urged to use png_create_info_struct()
+ * instead. Use deprecated in 1.6.0, internal use removed (used internally it
+ * is just a memset).
+ *
+ * NOTE: it is almost inconceivable that this API is used because it bypasses
+ * the user-memory mechanism and the user error handling/warning mechanisms in
+ * those cases where it does anything other than a memset.
+ */
+PNG_FUNCTION(void,PNGAPI
+png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
+ PNG_DEPRECATED)
+{
+ png_inforp info_ptr = *ptr_ptr;
+
+ png_debug(1, "in png_info_init_3");
+
+ if (info_ptr == NULL)
+ return;
+
+ if ((sizeof (png_info)) > png_info_struct_size)
+ {
+ *ptr_ptr = NULL;
+ /* The following line is why this API should not be used: */
+ free(info_ptr);
+ info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
+ (sizeof *info_ptr)));
+ if (info_ptr == NULL)
+ return;
+ *ptr_ptr = info_ptr;
+ }
+
+ /* Set everything to 0 */
+ memset(info_ptr, 0, (sizeof *info_ptr));
+}
+
+/* The following API is not called internally */
+void PNGAPI
+png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
+ int freer, png_uint_32 mask)
+{
+ png_debug(1, "in png_data_freer");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (freer == PNG_DESTROY_WILL_FREE_DATA)
+ info_ptr->free_me |= mask;
+
+ else if (freer == PNG_USER_WILL_FREE_DATA)
+ info_ptr->free_me &= ~mask;
+
+ else
+ png_error(png_ptr, "Unknown freer parameter in png_data_freer");
+}
+
+void PNGAPI
+png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
+ int num)
+{
+ png_debug(1, "in png_free_data");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+#ifdef PNG_TEXT_SUPPORTED
+ /* Free text item num or (if num == -1) all text items */
+ if (info_ptr->text != NULL &&
+ ((mask & PNG_FREE_TEXT) & info_ptr->free_me) != 0)
+ {
+ if (num != -1)
+ {
+ png_free(png_ptr, info_ptr->text[num].key);
+ info_ptr->text[num].key = NULL;
+ }
+
+ else
+ {
+ int i;
+
+ for (i = 0; i < info_ptr->num_text; i++)
+ png_free(png_ptr, info_ptr->text[i].key);
+
+ png_free(png_ptr, info_ptr->text);
+ info_ptr->text = NULL;
+ info_ptr->num_text = 0;
+ info_ptr->max_text = 0;
+ }
+ }
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+ /* Free any tRNS entry */
+ if (((mask & PNG_FREE_TRNS) & info_ptr->free_me) != 0)
+ {
+ info_ptr->valid &= ~PNG_INFO_tRNS;
+ png_free(png_ptr, info_ptr->trans_alpha);
+ info_ptr->trans_alpha = NULL;
+ info_ptr->num_trans = 0;
+ }
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+ /* Free any sCAL entry */
+ if (((mask & PNG_FREE_SCAL) & info_ptr->free_me) != 0)
+ {
+ png_free(png_ptr, info_ptr->scal_s_width);
+ png_free(png_ptr, info_ptr->scal_s_height);
+ info_ptr->scal_s_width = NULL;
+ info_ptr->scal_s_height = NULL;
+ info_ptr->valid &= ~PNG_INFO_sCAL;
+ }
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+ /* Free any pCAL entry */
+ if (((mask & PNG_FREE_PCAL) & info_ptr->free_me) != 0)
+ {
+ png_free(png_ptr, info_ptr->pcal_purpose);
+ png_free(png_ptr, info_ptr->pcal_units);
+ info_ptr->pcal_purpose = NULL;
+ info_ptr->pcal_units = NULL;
+
+ if (info_ptr->pcal_params != NULL)
+ {
+ int i;
+
+ for (i = 0; i < info_ptr->pcal_nparams; i++)
+ png_free(png_ptr, info_ptr->pcal_params[i]);
+
+ png_free(png_ptr, info_ptr->pcal_params);
+ info_ptr->pcal_params = NULL;
+ }
+ info_ptr->valid &= ~PNG_INFO_pCAL;
+ }
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+ /* Free any profile entry */
+ if (((mask & PNG_FREE_ICCP) & info_ptr->free_me) != 0)
+ {
+ png_free(png_ptr, info_ptr->iccp_name);
+ png_free(png_ptr, info_ptr->iccp_profile);
+ info_ptr->iccp_name = NULL;
+ info_ptr->iccp_profile = NULL;
+ info_ptr->valid &= ~PNG_INFO_iCCP;
+ }
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+ /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
+ if (info_ptr->splt_palettes != NULL &&
+ ((mask & PNG_FREE_SPLT) & info_ptr->free_me) != 0)
+ {
+ if (num != -1)
+ {
+ png_free(png_ptr, info_ptr->splt_palettes[num].name);
+ png_free(png_ptr, info_ptr->splt_palettes[num].entries);
+ info_ptr->splt_palettes[num].name = NULL;
+ info_ptr->splt_palettes[num].entries = NULL;
+ }
+
+ else
+ {
+ int i;
+
+ for (i = 0; i < info_ptr->splt_palettes_num; i++)
+ {
+ png_free(png_ptr, info_ptr->splt_palettes[i].name);
+ png_free(png_ptr, info_ptr->splt_palettes[i].entries);
+ }
+
+ png_free(png_ptr, info_ptr->splt_palettes);
+ info_ptr->splt_palettes = NULL;
+ info_ptr->splt_palettes_num = 0;
+ info_ptr->valid &= ~PNG_INFO_sPLT;
+ }
+ }
+#endif
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+ if (info_ptr->unknown_chunks != NULL &&
+ ((mask & PNG_FREE_UNKN) & info_ptr->free_me) != 0)
+ {
+ if (num != -1)
+ {
+ png_free(png_ptr, info_ptr->unknown_chunks[num].data);
+ info_ptr->unknown_chunks[num].data = NULL;
+ }
+
+ else
+ {
+ int i;
+
+ for (i = 0; i < info_ptr->unknown_chunks_num; i++)
+ png_free(png_ptr, info_ptr->unknown_chunks[i].data);
+
+ png_free(png_ptr, info_ptr->unknown_chunks);
+ info_ptr->unknown_chunks = NULL;
+ info_ptr->unknown_chunks_num = 0;
+ }
+ }
+#endif
+
+#ifdef PNG_eXIf_SUPPORTED
+ /* Free any eXIf entry */
+ if (((mask & PNG_FREE_EXIF) & info_ptr->free_me) != 0)
+ {
+# ifdef PNG_READ_eXIf_SUPPORTED
+ if (info_ptr->eXIf_buf)
+ {
+ png_free(png_ptr, info_ptr->eXIf_buf);
+ info_ptr->eXIf_buf = NULL;
+ }
+# endif
+ if (info_ptr->exif)
+ {
+ png_free(png_ptr, info_ptr->exif);
+ info_ptr->exif = NULL;
+ }
+ info_ptr->valid &= ~PNG_INFO_eXIf;
+ }
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+ /* Free any hIST entry */
+ if (((mask & PNG_FREE_HIST) & info_ptr->free_me) != 0)
+ {
+ png_free(png_ptr, info_ptr->hist);
+ info_ptr->hist = NULL;
+ info_ptr->valid &= ~PNG_INFO_hIST;
+ }
+#endif
+
+ /* Free any PLTE entry that was internally allocated */
+ if (((mask & PNG_FREE_PLTE) & info_ptr->free_me) != 0)
+ {
+ png_free(png_ptr, info_ptr->palette);
+ info_ptr->palette = NULL;
+ info_ptr->valid &= ~PNG_INFO_PLTE;
+ info_ptr->num_palette = 0;
+ }
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+ /* Free any image bits attached to the info structure */
+ if (((mask & PNG_FREE_ROWS) & info_ptr->free_me) != 0)
+ {
+ if (info_ptr->row_pointers != NULL)
+ {
+ png_uint_32 row;
+ for (row = 0; row < info_ptr->height; row++)
+ png_free(png_ptr, info_ptr->row_pointers[row]);
+
+ png_free(png_ptr, info_ptr->row_pointers);
+ info_ptr->row_pointers = NULL;
+ }
+ info_ptr->valid &= ~PNG_INFO_IDAT;
+ }
+#endif
+
+ if (num != -1)
+ mask &= ~PNG_FREE_MUL;
+
+ info_ptr->free_me &= ~mask;
+}
+#endif /* READ || WRITE */
+
+/* This function returns a pointer to the io_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy() or png_read_destroy() are called.
+ */
+png_voidp PNGAPI
+png_get_io_ptr(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return (NULL);
+
+ return (png_ptr->io_ptr);
+}
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+# ifdef PNG_STDIO_SUPPORTED
+/* Initialize the default input/output functions for the PNG file. If you
+ * use your own read or write routines, you can call either png_set_read_fn()
+ * or png_set_write_fn() instead of png_init_io(). If you have defined
+ * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
+ * function of your own because "FILE *" isn't necessarily available.
+ */
+void PNGAPI
+png_init_io(png_structrp png_ptr, png_FILE_p fp)
+{
+ png_debug(1, "in png_init_io");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->io_ptr = (png_voidp)fp;
+}
+# endif
+
+# ifdef PNG_SAVE_INT_32_SUPPORTED
+/* PNG signed integers are saved in 32-bit 2's complement format. ANSI C-90
+ * defines a cast of a signed integer to an unsigned integer either to preserve
+ * the value, if it is positive, or to calculate:
+ *
+ * (UNSIGNED_MAX+1) + integer
+ *
+ * Where UNSIGNED_MAX is the appropriate maximum unsigned value, so when the
+ * negative integral value is added the result will be an unsigned value
+ * correspnding to the 2's complement representation.
+ */
+void PNGAPI
+png_save_int_32(png_bytep buf, png_int_32 i)
+{
+ png_save_uint_32(buf, (png_uint_32)i);
+}
+# endif
+
+# ifdef PNG_TIME_RFC1123_SUPPORTED
+/* Convert the supplied time into an RFC 1123 string suitable for use in
+ * a "Creation Time" or other text-based time string.
+ */
+int PNGAPI
+png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
+{
+ static PNG_CONST char short_months[12][4] =
+ {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+ if (out == NULL)
+ return 0;
+
+ if (ptime->year > 9999 /* RFC1123 limitation */ ||
+ ptime->month == 0 || ptime->month > 12 ||
+ ptime->day == 0 || ptime->day > 31 ||
+ ptime->hour > 23 || ptime->minute > 59 ||
+ ptime->second > 60)
+ return 0;
+
+ {
+ size_t pos = 0;
+ char number_buf[5]; /* enough for a four-digit year */
+
+# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
+# define APPEND_NUMBER(format, value)\
+ APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
+# define APPEND(ch) if (pos < 28) out[pos++] = (ch)
+
+ APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);
+ APPEND(' ');
+ APPEND_STRING(short_months[(ptime->month - 1)]);
+ APPEND(' ');
+ APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
+ APPEND(' ');
+ APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
+ APPEND(':');
+ APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
+ APPEND(':');
+ APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
+ APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
+ PNG_UNUSED (pos)
+
+# undef APPEND
+# undef APPEND_NUMBER
+# undef APPEND_STRING
+ }
+
+ return 1;
+}
+
+# if PNG_LIBPNG_VER < 10700
+/* To do: remove the following from libpng-1.7 */
+/* Original API that uses a private buffer in png_struct.
+ * Deprecated because it causes png_struct to carry a spurious temporary
+ * buffer (png_struct::time_buffer), better to have the caller pass this in.
+ */
+png_const_charp PNGAPI
+png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)
+{
+ if (png_ptr != NULL)
+ {
+ /* The only failure above if png_ptr != NULL is from an invalid ptime */
+ if (png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime) == 0)
+ png_warning(png_ptr, "Ignoring invalid time value");
+
+ else
+ return png_ptr->time_buffer;
+ }
+
+ return NULL;
+}
+# endif /* LIBPNG_VER < 10700 */
+# endif /* TIME_RFC1123 */
+
+#endif /* READ || WRITE */
+
+png_const_charp PNGAPI
+png_get_copyright(png_const_structrp png_ptr)
+{
+ PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
+#ifdef PNG_STRING_COPYRIGHT
+ return PNG_STRING_COPYRIGHT
+#else
+# ifdef __STDC__
+ return PNG_STRING_NEWLINE \
+ "libpng version 1.6.34 - September 29, 2017" PNG_STRING_NEWLINE \
+ "Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson" \
+ PNG_STRING_NEWLINE \
+ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
+ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
+ PNG_STRING_NEWLINE;
+# else
+ return "libpng version 1.6.34 - September 29, 2017\
+ Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson\
+ Copyright (c) 1996-1997 Andreas Dilger\
+ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
+# endif
+#endif
+}
+
+/* The following return the library version as a short string in the
+ * format 1.0.0 through 99.99.99zz. To get the version of *.h files
+ * used with your application, print out PNG_LIBPNG_VER_STRING, which
+ * is defined in png.h.
+ * Note: now there is no difference between png_get_libpng_ver() and
+ * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
+ * it is guaranteed that png.c uses the correct version of png.h.
+ */
+png_const_charp PNGAPI
+png_get_libpng_ver(png_const_structrp png_ptr)
+{
+ /* Version of *.c files used when building libpng */
+ return png_get_header_ver(png_ptr);
+}
+
+png_const_charp PNGAPI
+png_get_header_ver(png_const_structrp png_ptr)
+{
+ /* Version of *.h files used when building libpng */
+ PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
+ return PNG_LIBPNG_VER_STRING;
+}
+
+png_const_charp PNGAPI
+png_get_header_version(png_const_structrp png_ptr)
+{
+ /* Returns longer string containing both version and date */
+ PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
+#ifdef __STDC__
+ return PNG_HEADER_VERSION_STRING
+# ifndef PNG_READ_SUPPORTED
+ " (NO READ SUPPORT)"
+# endif
+ PNG_STRING_NEWLINE;
+#else
+ return PNG_HEADER_VERSION_STRING;
+#endif
+}
+
+#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+/* NOTE: this routine is not used internally! */
+/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
+ * large of png_color. This lets grayscale images be treated as
+ * paletted. Most useful for gamma correction and simplification
+ * of code. This API is not used internally.
+ */
+void PNGAPI
+png_build_grayscale_palette(int bit_depth, png_colorp palette)
+{
+ int num_palette;
+ int color_inc;
+ int i;
+ int v;
+
+ png_debug(1, "in png_do_build_grayscale_palette");
+
+ if (palette == NULL)
+ return;
+
+ switch (bit_depth)
+ {
+ case 1:
+ num_palette = 2;
+ color_inc = 0xff;
+ break;
+
+ case 2:
+ num_palette = 4;
+ color_inc = 0x55;
+ break;
+
+ case 4:
+ num_palette = 16;
+ color_inc = 0x11;
+ break;
+
+ case 8:
+ num_palette = 256;
+ color_inc = 1;
+ break;
+
+ default:
+ num_palette = 0;
+ color_inc = 0;
+ break;
+ }
+
+ for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
+ {
+ palette[i].red = (png_byte)(v & 0xff);
+ palette[i].green = (png_byte)(v & 0xff);
+ palette[i].blue = (png_byte)(v & 0xff);
+ }
+}
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+int PNGAPI
+png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
+{
+ /* Check chunk_name and return "keep" value if it's on the list, else 0 */
+ png_const_bytep p, p_end;
+
+ if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)
+ return PNG_HANDLE_CHUNK_AS_DEFAULT;
+
+ p_end = png_ptr->chunk_list;
+ p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
+
+ /* The code is the fifth byte after each four byte string. Historically this
+ * code was always searched from the end of the list, this is no longer
+ * necessary because the 'set' routine handles duplicate entries correcty.
+ */
+ do /* num_chunk_list > 0, so at least one */
+ {
+ p -= 5;
+
+ if (memcmp(chunk_name, p, 4) == 0)
+ return p[4];
+ }
+ while (p > p_end);
+
+ /* This means that known chunks should be processed and unknown chunks should
+ * be handled according to the value of png_ptr->unknown_default; this can be
+ * confusing because, as a result, there are two levels of defaulting for
+ * unknown chunks.
+ */
+ return PNG_HANDLE_CHUNK_AS_DEFAULT;
+}
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
+ defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+int /* PRIVATE */
+png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
+{
+ png_byte chunk_string[5];
+
+ PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
+ return png_handle_as_unknown(png_ptr, chunk_string);
+}
+#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
+#endif /* SET_UNKNOWN_CHUNKS */
+
+#ifdef PNG_READ_SUPPORTED
+/* This function, added to libpng-1.0.6g, is untested. */
+int PNGAPI
+png_reset_zstream(png_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return Z_STREAM_ERROR;
+
+ /* WARNING: this resets the window bits to the maximum! */
+ return (inflateReset(&png_ptr->zstream));
+}
+#endif /* READ */
+
+/* This function was added to libpng-1.0.7 */
+png_uint_32 PNGAPI
+png_access_version_number(void)
+{
+ /* Version of *.c files used when building libpng */
+ return((png_uint_32)PNG_LIBPNG_VER);
+}
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
+ * If it doesn't 'ret' is used to set it to something appropriate, even in cases
+ * like Z_OK or Z_STREAM_END where the error code is apparently a success code.
+ */
+void /* PRIVATE */
+png_zstream_error(png_structrp png_ptr, int ret)
+{
+ /* Translate 'ret' into an appropriate error string, priority is given to the
+ * one in zstream if set. This always returns a string, even in cases like
+ * Z_OK or Z_STREAM_END where the error code is a success code.
+ */
+ if (png_ptr->zstream.msg == NULL) switch (ret)
+ {
+ default:
+ case Z_OK:
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code");
+ break;
+
+ case Z_STREAM_END:
+ /* Normal exit */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream");
+ break;
+
+ case Z_NEED_DICT:
+ /* This means the deflate stream did not have a dictionary; this
+ * indicates a bogus PNG.
+ */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary");
+ break;
+
+ case Z_ERRNO:
+ /* gz APIs only: should not happen */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error");
+ break;
+
+ case Z_STREAM_ERROR:
+ /* internal libpng error */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib");
+ break;
+
+ case Z_DATA_ERROR:
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream");
+ break;
+
+ case Z_MEM_ERROR:
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory");
+ break;
+
+ case Z_BUF_ERROR:
+ /* End of input or output; not a problem if the caller is doing
+ * incremental read or write.
+ */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated");
+ break;
+
+ case Z_VERSION_ERROR:
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version");
+ break;
+
+ case PNG_UNEXPECTED_ZLIB_RETURN:
+ /* Compile errors here mean that zlib now uses the value co-opted in
+ * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above
+ * and change pngpriv.h. Note that this message is "... return",
+ * whereas the default/Z_OK one is "... return code".
+ */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return");
+ break;
+ }
+}
+
+/* png_convert_size: a PNGAPI but no longer in png.h, so deleted
+ * at libpng 1.5.5!
+ */
+
+/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
+#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
+static int
+png_colorspace_check_gamma(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_fixed_point gAMA, int from)
+ /* This is called to check a new gamma value against an existing one. The
+ * routine returns false if the new gamma value should not be written.
+ *
+ * 'from' says where the new gamma value comes from:
+ *
+ * 0: the new gamma value is the libpng estimate for an ICC profile
+ * 1: the new gamma value comes from a gAMA chunk
+ * 2: the new gamma value comes from an sRGB chunk
+ */
+{
+ png_fixed_point gtest;
+
+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+ (png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) == 0 ||
+ png_gamma_significant(gtest) != 0))
+ {
+ /* Either this is an sRGB image, in which case the calculated gamma
+ * approximation should match, or this is an image with a profile and the
+ * value libpng calculates for the gamma of the profile does not match the
+ * value recorded in the file. The former, sRGB, case is an error, the
+ * latter is just a warning.
+ */
+ if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
+ {
+ png_chunk_report(png_ptr, "gamma value does not match sRGB",
+ PNG_CHUNK_ERROR);
+ /* Do not overwrite an sRGB value */
+ return from == 2;
+ }
+
+ else /* sRGB tag not involved */
+ {
+ png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
+ PNG_CHUNK_WARNING);
+ return from == 1;
+ }
+ }
+
+ return 1;
+}
+
+void /* PRIVATE */
+png_colorspace_set_gamma(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_fixed_point gAMA)
+{
+ /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
+ * occur. Since the fixed point representation is asymetrical it is
+ * possible for 1/gamma to overflow the limit of 21474 and this means the
+ * gamma value must be at least 5/100000 and hence at most 20000.0. For
+ * safety the limits here are a little narrower. The values are 0.00016 to
+ * 6250.0, which are truly ridiculous gamma values (and will produce
+ * displays that are all black or all white.)
+ *
+ * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
+ * handling code, which only required the value to be >0.
+ */
+ png_const_charp errmsg;
+
+ if (gAMA < 16 || gAMA > 625000000)
+ errmsg = "gamma value out of range";
+
+# ifdef PNG_READ_gAMA_SUPPORTED
+ /* Allow the application to set the gamma value more than once */
+ else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+ (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
+ errmsg = "duplicate";
+# endif
+
+ /* Do nothing if the colorspace is already invalid */
+ else if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
+ return;
+
+ else
+ {
+ if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA,
+ 1/*from gAMA*/) != 0)
+ {
+ /* Store this gamma value. */
+ colorspace->gamma = gAMA;
+ colorspace->flags |=
+ (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);
+ }
+
+ /* At present if the check_gamma test fails the gamma of the colorspace is
+ * not updated however the colorspace is not invalidated. This
+ * corresponds to the case where the existing gamma comes from an sRGB
+ * chunk or profile. An error message has already been output.
+ */
+ return;
+ }
+
+ /* Error exit - errmsg has been set. */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);
+}
+
+void /* PRIVATE */
+png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)
+{
+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
+ {
+ /* Everything is invalid */
+ info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|
+ PNG_INFO_iCCP);
+
+# ifdef PNG_COLORSPACE_SUPPORTED
+ /* Clean up the iCCP profile now if it won't be used. */
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);
+# else
+ PNG_UNUSED(png_ptr)
+# endif
+ }
+
+ else
+ {
+# ifdef PNG_COLORSPACE_SUPPORTED
+ /* Leave the INFO_iCCP flag set if the pngset.c code has already set
+ * it; this allows a PNG to contain a profile which matches sRGB and
+ * yet still have that profile retrievable by the application.
+ */
+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB) != 0)
+ info_ptr->valid |= PNG_INFO_sRGB;
+
+ else
+ info_ptr->valid &= ~PNG_INFO_sRGB;
+
+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+ info_ptr->valid |= PNG_INFO_cHRM;
+
+ else
+ info_ptr->valid &= ~PNG_INFO_cHRM;
+# endif
+
+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0)
+ info_ptr->valid |= PNG_INFO_gAMA;
+
+ else
+ info_ptr->valid &= ~PNG_INFO_gAMA;
+ }
+}
+
+#ifdef PNG_READ_SUPPORTED
+void /* PRIVATE */
+png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)
+{
+ if (info_ptr == NULL) /* reduce code size; check here not in the caller */
+ return;
+
+ info_ptr->colorspace = png_ptr->colorspace;
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+#endif
+#endif /* GAMMA */
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
+ * cHRM, as opposed to using chromaticities. These internal APIs return
+ * non-zero on a parameter error. The X, Y and Z values are required to be
+ * positive and less than 1.0.
+ */
+static int
+png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
+{
+ png_int_32 d, dwhite, whiteX, whiteY;
+
+ d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;
+ if (png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d) == 0)
+ return 1;
+ if (png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d) == 0)
+ return 1;
+ dwhite = d;
+ whiteX = XYZ->red_X;
+ whiteY = XYZ->red_Y;
+
+ d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;
+ if (png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d) == 0)
+ return 1;
+ if (png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d) == 0)
+ return 1;
+ dwhite += d;
+ whiteX += XYZ->green_X;
+ whiteY += XYZ->green_Y;
+
+ d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;
+ if (png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d) == 0)
+ return 1;
+ if (png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d) == 0)
+ return 1;
+ dwhite += d;
+ whiteX += XYZ->blue_X;
+ whiteY += XYZ->blue_Y;
+
+ /* The reference white is simply the sum of the end-point (X,Y,Z) vectors,
+ * thus:
+ */
+ if (png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite) == 0)
+ return 1;
+ if (png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite) == 0)
+ return 1;
+
+ return 0;
+}
+
+static int
+png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
+{
+ png_fixed_point red_inverse, green_inverse, blue_scale;
+ png_fixed_point left, right, denominator;
+
+ /* Check xy and, implicitly, z. Note that wide gamut color spaces typically
+ * have end points with 0 tristimulus values (these are impossible end
+ * points, but they are used to cover the possible colors). We check
+ * xy->whitey against 5, not 0, to avoid a possible integer overflow.
+ */
+ if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1;
+ if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
+ if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
+ if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
+ if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1;
+ if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
+ if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
+ if (xy->whitey < 5 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
+
+ /* The reverse calculation is more difficult because the original tristimulus
+ * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
+ * derived values were recorded in the cHRM chunk;
+ * (red,green,blue,white)x(x,y). This loses one degree of freedom and
+ * therefore an arbitrary ninth value has to be introduced to undo the
+ * original transformations.
+ *
+ * Think of the original end-points as points in (X,Y,Z) space. The
+ * chromaticity values (c) have the property:
+ *
+ * C
+ * c = ---------
+ * X + Y + Z
+ *
+ * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the
+ * three chromaticity values (x,y,z) for each end-point obey the
+ * relationship:
+ *
+ * x + y + z = 1
+ *
+ * This describes the plane in (X,Y,Z) space that intersects each axis at the
+ * value 1.0; call this the chromaticity plane. Thus the chromaticity
+ * calculation has scaled each end-point so that it is on the x+y+z=1 plane
+ * and chromaticity is the intersection of the vector from the origin to the
+ * (X,Y,Z) value with the chromaticity plane.
+ *
+ * To fully invert the chromaticity calculation we would need the three
+ * end-point scale factors, (red-scale, green-scale, blue-scale), but these
+ * were not recorded. Instead we calculated the reference white (X,Y,Z) and
+ * recorded the chromaticity of this. The reference white (X,Y,Z) would have
+ * given all three of the scale factors since:
+ *
+ * color-C = color-c * color-scale
+ * white-C = red-C + green-C + blue-C
+ * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
+ *
+ * But cHRM records only white-x and white-y, so we have lost the white scale
+ * factor:
+ *
+ * white-C = white-c*white-scale
+ *
+ * To handle this the inverse transformation makes an arbitrary assumption
+ * about white-scale:
+ *
+ * Assume: white-Y = 1.0
+ * Hence: white-scale = 1/white-y
+ * Or: red-Y + green-Y + blue-Y = 1.0
+ *
+ * Notice the last statement of the assumption gives an equation in three of
+ * the nine values we want to calculate. 8 more equations come from the
+ * above routine as summarised at the top above (the chromaticity
+ * calculation):
+ *
+ * Given: color-x = color-X / (color-X + color-Y + color-Z)
+ * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
+ *
+ * This is 9 simultaneous equations in the 9 variables "color-C" and can be
+ * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix
+ * determinants, however this is not as bad as it seems because only 28 of
+ * the total of 90 terms in the various matrices are non-zero. Nevertheless
+ * Cramer's rule is notoriously numerically unstable because the determinant
+ * calculation involves the difference of large, but similar, numbers. It is
+ * difficult to be sure that the calculation is stable for real world values
+ * and it is certain that it becomes unstable where the end points are close
+ * together.
+ *
+ * So this code uses the perhaps slightly less optimal but more
+ * understandable and totally obvious approach of calculating color-scale.
+ *
+ * This algorithm depends on the precision in white-scale and that is
+ * (1/white-y), so we can immediately see that as white-y approaches 0 the
+ * accuracy inherent in the cHRM chunk drops off substantially.
+ *
+ * libpng arithmetic: a simple inversion of the above equations
+ * ------------------------------------------------------------
+ *
+ * white_scale = 1/white-y
+ * white-X = white-x * white-scale
+ * white-Y = 1.0
+ * white-Z = (1 - white-x - white-y) * white_scale
+ *
+ * white-C = red-C + green-C + blue-C
+ * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
+ *
+ * This gives us three equations in (red-scale,green-scale,blue-scale) where
+ * all the coefficients are now known:
+ *
+ * red-x*red-scale + green-x*green-scale + blue-x*blue-scale
+ * = white-x/white-y
+ * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
+ * red-z*red-scale + green-z*green-scale + blue-z*blue-scale
+ * = (1 - white-x - white-y)/white-y
+ *
+ * In the last equation color-z is (1 - color-x - color-y) so we can add all
+ * three equations together to get an alternative third:
+ *
+ * red-scale + green-scale + blue-scale = 1/white-y = white-scale
+ *
+ * So now we have a Cramer's rule solution where the determinants are just
+ * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve
+ * multiplication of three coefficients so we can't guarantee to avoid
+ * overflow in the libpng fixed point representation. Using Cramer's rule in
+ * floating point is probably a good choice here, but it's not an option for
+ * fixed point. Instead proceed to simplify the first two equations by
+ * eliminating what is likely to be the largest value, blue-scale:
+ *
+ * blue-scale = white-scale - red-scale - green-scale
+ *
+ * Hence:
+ *
+ * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
+ * (white-x - blue-x)*white-scale
+ *
+ * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
+ * 1 - blue-y*white-scale
+ *
+ * And now we can trivially solve for (red-scale,green-scale):
+ *
+ * green-scale =
+ * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
+ * -----------------------------------------------------------
+ * green-x - blue-x
+ *
+ * red-scale =
+ * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale
+ * ---------------------------------------------------------
+ * red-y - blue-y
+ *
+ * Hence:
+ *
+ * red-scale =
+ * ( (green-x - blue-x) * (white-y - blue-y) -
+ * (green-y - blue-y) * (white-x - blue-x) ) / white-y
+ * -------------------------------------------------------------------------
+ * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
+ *
+ * green-scale =
+ * ( (red-y - blue-y) * (white-x - blue-x) -
+ * (red-x - blue-x) * (white-y - blue-y) ) / white-y
+ * -------------------------------------------------------------------------
+ * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
+ *
+ * Accuracy:
+ * The input values have 5 decimal digits of accuracy. The values are all in
+ * the range 0 < value < 1, so simple products are in the same range but may
+ * need up to 10 decimal digits to preserve the original precision and avoid
+ * underflow. Because we are using a 32-bit signed representation we cannot
+ * match this; the best is a little over 9 decimal digits, less than 10.
+ *
+ * The approach used here is to preserve the maximum precision within the
+ * signed representation. Because the red-scale calculation above uses the
+ * difference between two products of values that must be in the range -1..+1
+ * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The
+ * factor is irrelevant in the calculation because it is applied to both
+ * numerator and denominator.
+ *
+ * Note that the values of the differences of the products of the
+ * chromaticities in the above equations tend to be small, for example for
+ * the sRGB chromaticities they are:
+ *
+ * red numerator: -0.04751
+ * green numerator: -0.08788
+ * denominator: -0.2241 (without white-y multiplication)
+ *
+ * The resultant Y coefficients from the chromaticities of some widely used
+ * color space definitions are (to 15 decimal places):
+ *
+ * sRGB
+ * 0.212639005871510 0.715168678767756 0.072192315360734
+ * Kodak ProPhoto
+ * 0.288071128229293 0.711843217810102 0.000085653960605
+ * Adobe RGB
+ * 0.297344975250536 0.627363566255466 0.075291458493998
+ * Adobe Wide Gamut RGB
+ * 0.258728243040113 0.724682314948566 0.016589442011321
+ */
+ /* By the argument, above overflow should be impossible here. The return
+ * value of 2 indicates an internal error to the caller.
+ */
+ if (png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7) == 0)
+ return 2;
+ if (png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7) == 0)
+ return 2;
+ denominator = left - right;
+
+ /* Now find the red numerator. */
+ if (png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
+ return 2;
+ if (png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
+ return 2;
+
+ /* Overflow is possible here and it indicates an extreme set of PNG cHRM
+ * chunk values. This calculation actually returns the reciprocal of the
+ * scale value because this allows us to delay the multiplication of white-y
+ * into the denominator, which tends to produce a small number.
+ */
+ if (png_muldiv(&red_inverse, xy->whitey, denominator, left-right) == 0 ||
+ red_inverse <= xy->whitey /* r+g+b scales = white scale */)
+ return 1;
+
+ /* Similarly for green_inverse: */
+ if (png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7) == 0)
+ return 2;
+ if (png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7) == 0)
+ return 2;
+ if (png_muldiv(&green_inverse, xy->whitey, denominator, left-right) == 0 ||
+ green_inverse <= xy->whitey)
+ return 1;
+
+ /* And the blue scale, the checks above guarantee this can't overflow but it
+ * can still produce 0 for extreme cHRM values.
+ */
+ blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -
+ png_reciprocal(green_inverse);
+ if (blue_scale <= 0)
+ return 1;
+
+
+ /* And fill in the png_XYZ: */
+ if (png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
+ red_inverse) == 0)
+ return 1;
+
+ if (png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
+ green_inverse) == 0)
+ return 1;
+
+ if (png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
+ PNG_FP_1) == 0)
+ return 1;
+
+ return 0; /*success*/
+}
+
+static int
+png_XYZ_normalize(png_XYZ *XYZ)
+{
+ png_int_32 Y;
+
+ if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||
+ XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||
+ XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)
+ return 1;
+
+ /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.
+ * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
+ * relying on addition of two positive values producing a negative one is not
+ * safe.
+ */
+ Y = XYZ->red_Y;
+ if (0x7fffffff - Y < XYZ->green_X)
+ return 1;
+ Y += XYZ->green_Y;
+ if (0x7fffffff - Y < XYZ->blue_X)
+ return 1;
+ Y += XYZ->blue_Y;
+
+ if (Y != PNG_FP_1)
+ {
+ if (png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y) == 0)
+ return 1;
+
+ if (png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y) == 0)
+ return 1;
+
+ if (png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y) == 0)
+ return 1;
+ if (png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
+{
+ /* Allow an error of +/-0.01 (absolute value) on each chromaticity */
+ if (PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
+ PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
+ PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) ||
+ PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) ||
+ PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
+ PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
+ PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) ||
+ PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta))
+ return 0;
+ return 1;
+}
+
+/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
+ * chunk chromaticities. Earlier checks used to simply look for the overflow
+ * condition (where the determinant of the matrix to solve for XYZ ends up zero
+ * because the chromaticity values are not all distinct.) Despite this it is
+ * theoretically possible to produce chromaticities that are apparently valid
+ * but that rapidly degrade to invalid, potentially crashing, sets because of
+ * arithmetic inaccuracies when calculations are performed on them. The new
+ * check is to round-trip xy -> XYZ -> xy and then check that the result is
+ * within a small percentage of the original.
+ */
+static int
+png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
+{
+ int result;
+ png_xy xy_test;
+
+ /* As a side-effect this routine also returns the XYZ endpoints. */
+ result = png_XYZ_from_xy(XYZ, xy);
+ if (result != 0)
+ return result;
+
+ result = png_xy_from_XYZ(&xy_test, XYZ);
+ if (result != 0)
+ return result;
+
+ if (png_colorspace_endpoints_match(xy, &xy_test,
+ 5/*actually, the math is pretty accurate*/) != 0)
+ return 0;
+
+ /* Too much slip */
+ return 1;
+}
+
+/* This is the check going the other way. The XYZ is modified to normalize it
+ * (another side-effect) and the xy chromaticities are returned.
+ */
+static int
+png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
+{
+ int result;
+ png_XYZ XYZtemp;
+
+ result = png_XYZ_normalize(XYZ);
+ if (result != 0)
+ return result;
+
+ result = png_xy_from_XYZ(xy, XYZ);
+ if (result != 0)
+ return result;
+
+ XYZtemp = *XYZ;
+ return png_colorspace_check_xy(&XYZtemp, xy);
+}
+
+/* Used to check for an endpoint match against sRGB */
+static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
+{
+ /* color x y */
+ /* red */ 64000, 33000,
+ /* green */ 30000, 60000,
+ /* blue */ 15000, 6000,
+ /* white */ 31270, 32900
+};
+
+static int
+png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
+ int preferred)
+{
+ if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
+ return 0;
+
+ /* The consistency check is performed on the chromaticities; this factors out
+ * variations because of the normalization (or not) of the end point Y
+ * values.
+ */
+ if (preferred < 2 &&
+ (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+ {
+ /* The end points must be reasonably close to any we already have. The
+ * following allows an error of up to +/-.001
+ */
+ if (png_colorspace_endpoints_match(xy, &colorspace->end_points_xy,
+ 100) == 0)
+ {
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_benign_error(png_ptr, "inconsistent chromaticities");
+ return 0; /* failed */
+ }
+
+ /* Only overwrite with preferred values */
+ if (preferred == 0)
+ return 1; /* ok, but no change */
+ }
+
+ colorspace->end_points_xy = *xy;
+ colorspace->end_points_XYZ = *XYZ;
+ colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;
+
+ /* The end points are normally quoted to two decimal digits, so allow +/-0.01
+ * on this test.
+ */
+ if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000) != 0)
+ colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;
+
+ else
+ colorspace->flags &= PNG_COLORSPACE_CANCEL(
+ PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
+
+ return 2; /* ok and changed */
+}
+
+int /* PRIVATE */
+png_colorspace_set_chromaticities(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, const png_xy *xy, int preferred)
+{
+ /* We must check the end points to ensure they are reasonable - in the past
+ * color management systems have crashed as a result of getting bogus
+ * colorant values, while this isn't the fault of libpng it is the
+ * responsibility of libpng because PNG carries the bomb and libpng is in a
+ * position to protect against it.
+ */
+ png_XYZ XYZ;
+
+ switch (png_colorspace_check_xy(&XYZ, xy))
+ {
+ case 0: /* success */
+ return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
+ preferred);
+
+ case 1:
+ /* We can't invert the chromaticities so we can't produce value XYZ
+ * values. Likely as not a color management system will fail too.
+ */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_benign_error(png_ptr, "invalid chromaticities");
+ break;
+
+ default:
+ /* libpng is broken; this should be a warning but if it happens we
+ * want error reports so for the moment it is an error.
+ */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_error(png_ptr, "internal error checking chromaticities");
+ }
+
+ return 0; /* failed */
+}
+
+int /* PRIVATE */
+png_colorspace_set_endpoints(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
+{
+ png_XYZ XYZ = *XYZ_in;
+ png_xy xy;
+
+ switch (png_colorspace_check_XYZ(&xy, &XYZ))
+ {
+ case 0:
+ return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
+ preferred);
+
+ case 1:
+ /* End points are invalid. */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_benign_error(png_ptr, "invalid end points");
+ break;
+
+ default:
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_error(png_ptr, "internal error checking chromaticities");
+ }
+
+ return 0; /* failed */
+}
+
+#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)
+/* Error message generation */
+static char
+png_icc_tag_char(png_uint_32 byte)
+{
+ byte &= 0xff;
+ if (byte >= 32 && byte <= 126)
+ return (char)byte;
+ else
+ return '?';
+}
+
+static void
+png_icc_tag_name(char *name, png_uint_32 tag)
+{
+ name[0] = '\'';
+ name[1] = png_icc_tag_char(tag >> 24);
+ name[2] = png_icc_tag_char(tag >> 16);
+ name[3] = png_icc_tag_char(tag >> 8);
+ name[4] = png_icc_tag_char(tag );
+ name[5] = '\'';
+}
+
+static int
+is_ICC_signature_char(png_alloc_size_t it)
+{
+ return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) ||
+ (it >= 97 && it <= 122);
+}
+
+static int
+is_ICC_signature(png_alloc_size_t it)
+{
+ return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
+ is_ICC_signature_char((it >> 16) & 0xff) &&
+ is_ICC_signature_char((it >> 8) & 0xff) &&
+ is_ICC_signature_char(it & 0xff);
+}
+
+static int
+png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_alloc_size_t value, png_const_charp reason)
+{
+ size_t pos;
+ char message[196]; /* see below for calculation */
+
+ if (colorspace != NULL)
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+
+ pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
+ pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
+ pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
+ if (is_ICC_signature(value) != 0)
+ {
+ /* So 'value' is at most 4 bytes and the following cast is safe */
+ png_icc_tag_name(message+pos, (png_uint_32)value);
+ pos += 6; /* total +8; less than the else clause */
+ message[pos++] = ':';
+ message[pos++] = ' ';
+ }
+# ifdef PNG_WARNINGS_SUPPORTED
+ else
+ {
+ char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
+
+ pos = png_safecat(message, (sizeof message), pos,
+ png_format_number(number, number+(sizeof number),
+ PNG_NUMBER_FORMAT_x, value));
+ pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
+ }
+# endif
+ /* The 'reason' is an arbitrary message, allow +79 maximum 195 */
+ pos = png_safecat(message, (sizeof message), pos, reason);
+ PNG_UNUSED(pos)
+
+ /* This is recoverable, but make it unconditionally an app_error on write to
+ * avoid writing invalid ICC profiles into PNG files (i.e., we handle them
+ * on read, with a warning, but on write unless the app turns off
+ * application errors the PNG won't be written.)
+ */
+ png_chunk_report(png_ptr, message,
+ (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
+
+ return 0;
+}
+#endif /* sRGB || iCCP */
+
+#ifdef PNG_sRGB_SUPPORTED
+int /* PRIVATE */
+png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ int intent)
+{
+ /* sRGB sets known gamma, end points and (from the chunk) intent. */
+ /* IMPORTANT: these are not necessarily the values found in an ICC profile
+ * because ICC profiles store values adapted to a D50 environment; it is
+ * expected that the ICC profile mediaWhitePointTag will be D50; see the
+ * checks and code elsewhere to understand this better.
+ *
+ * These XYZ values, which are accurate to 5dp, produce rgb to gray
+ * coefficients of (6968,23435,2366), which are reduced (because they add up
+ * to 32769 not 32768) to (6968,23434,2366). These are the values that
+ * libpng has traditionally used (and are the best values given the 15bit
+ * algorithm used by the rgb to gray code.)
+ */
+ static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */
+ {
+ /* color X Y Z */
+ /* red */ 41239, 21264, 1933,
+ /* green */ 35758, 71517, 11919,
+ /* blue */ 18048, 7219, 95053
+ };
+
+ /* Do nothing if the colorspace is already invalidated. */
+ if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
+ return 0;
+
+ /* Check the intent, then check for existing settings. It is valid for the
+ * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must
+ * be consistent with the correct values. If, however, this function is
+ * called below because an iCCP chunk matches sRGB then it is quite
+ * conceivable that an older app recorded incorrect gAMA and cHRM because of
+ * an incorrect calculation based on the values in the profile - this does
+ * *not* invalidate the profile (though it still produces an error, which can
+ * be ignored.)
+ */
+ if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
+ return png_icc_profile_error(png_ptr, colorspace, "sRGB",
+ (png_alloc_size_t)intent, "invalid sRGB rendering intent");
+
+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
+ colorspace->rendering_intent != intent)
+ return png_icc_profile_error(png_ptr, colorspace, "sRGB",
+ (png_alloc_size_t)intent, "inconsistent rendering intents");
+
+ if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
+ {
+ png_benign_error(png_ptr, "duplicate sRGB information ignored");
+ return 0;
+ }
+
+ /* If the standard sRGB cHRM chunk does not match the one from the PNG file
+ * warn but overwrite the value with the correct one.
+ */
+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
+ !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
+ 100))
+ png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
+ PNG_CHUNK_ERROR);
+
+ /* This check is just done for the error reporting - the routine always
+ * returns true when the 'from' argument corresponds to sRGB (2).
+ */
+ (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
+ 2/*from sRGB*/);
+
+ /* intent: bugs in GCC force 'int' to be used as the parameter type. */
+ colorspace->rendering_intent = (png_uint_16)intent;
+ colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;
+
+ /* endpoints */
+ colorspace->end_points_xy = sRGB_xy;
+ colorspace->end_points_XYZ = sRGB_XYZ;
+ colorspace->flags |=
+ (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
+
+ /* gamma */
+ colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;
+ colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
+
+ /* Finally record that we have an sRGB profile */
+ colorspace->flags |=
+ (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
+
+ return 1; /* set */
+}
+#endif /* sRGB */
+
+#ifdef PNG_iCCP_SUPPORTED
+/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value
+ * is XYZ(0.9642,1.0,0.8249), which scales to:
+ *
+ * (63189.8112, 65536, 54060.6464)
+ */
+static const png_byte D50_nCIEXYZ[12] =
+ { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
+
+static int /* bool */
+icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length)
+{
+ if (profile_length < 132)
+ return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+ "too short");
+ return 1;
+}
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+int /* PRIVATE */
+png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length)
+{
+ if (!icc_check_length(png_ptr, colorspace, name, profile_length))
+ return 0;
+
+ /* This needs to be here because the 'normal' check is in
+ * png_decompress_chunk, yet this happens after the attempt to
+ * png_malloc_base the required data. We only need this on read; on write
+ * the caller supplies the profile buffer so libpng doesn't allocate it. See
+ * the call to icc_check_length below (the write case).
+ */
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ else if (png_ptr->user_chunk_malloc_max > 0 &&
+ png_ptr->user_chunk_malloc_max < profile_length)
+ return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+ "exceeds application limits");
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+ else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length)
+ return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+ "exceeds libpng limits");
+# else /* !SET_USER_LIMITS */
+ /* This will get compiled out on all 32-bit and better systems. */
+ else if (PNG_SIZE_MAX < profile_length)
+ return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+ "exceeds system limits");
+# endif /* !SET_USER_LIMITS */
+
+ return 1;
+}
+#endif /* READ_iCCP */
+
+int /* PRIVATE */
+png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length,
+ png_const_bytep profile/* first 132 bytes only */, int color_type)
+{
+ png_uint_32 temp;
+
+ /* Length check; this cannot be ignored in this code because profile_length
+ * is used later to check the tag table, so even if the profile seems over
+ * long profile_length from the caller must be correct. The caller can fix
+ * this up on read or write by just passing in the profile header length.
+ */
+ temp = png_get_uint_32(profile);
+ if (temp != profile_length)
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "length does not match profile");
+
+ temp = (png_uint_32) (*(profile+8));
+ if (temp > 3 && (profile_length & 3))
+ return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+ "invalid length");
+
+ temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
+ if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
+ profile_length < 132+12*temp) /* truncated tag table */
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "tag count too large");
+
+ /* The 'intent' must be valid or we can't store it, ICC limits the intent to
+ * 16 bits.
+ */
+ temp = png_get_uint_32(profile+64);
+ if (temp >= 0xffff) /* The ICC limit */
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid rendering intent");
+
+ /* This is just a warning because the profile may be valid in future
+ * versions.
+ */
+ if (temp >= PNG_sRGB_INTENT_LAST)
+ (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+ "intent outside defined range");
+
+ /* At this point the tag table can't be checked because it hasn't necessarily
+ * been loaded; however, various header fields can be checked. These checks
+ * are for values permitted by the PNG spec in an ICC profile; the PNG spec
+ * restricts the profiles that can be passed in an iCCP chunk (they must be
+ * appropriate to processing PNG data!)
+ */
+
+ /* Data checks (could be skipped). These checks must be independent of the
+ * version number; however, the version number doesn't accomodate changes in
+ * the header fields (just the known tags and the interpretation of the
+ * data.)
+ */
+ temp = png_get_uint_32(profile+36); /* signature 'ascp' */
+ if (temp != 0x61637370)
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid signature");
+
+ /* Currently the PCS illuminant/adopted white point (the computational
+ * white point) are required to be D50,
+ * however the profile contains a record of the illuminant so perhaps ICC
+ * expects to be able to change this in the future (despite the rationale in
+ * the introduction for using a fixed PCS adopted white.) Consequently the
+ * following is just a warning.
+ */
+ if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
+ (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
+ "PCS illuminant is not D50");
+
+ /* The PNG spec requires this:
+ * "If the iCCP chunk is present, the image samples conform to the colour
+ * space represented by the embedded ICC profile as defined by the
+ * International Color Consortium [ICC]. The colour space of the ICC profile
+ * shall be an RGB colour space for colour images (PNG colour types 2, 3, and
+ * 6), or a greyscale colour space for greyscale images (PNG colour types 0
+ * and 4)."
+ *
+ * This checking code ensures the embedded profile (on either read or write)
+ * conforms to the specification requirements. Notice that an ICC 'gray'
+ * color-space profile contains the information to transform the monochrome
+ * data to XYZ or L*a*b (according to which PCS the profile uses) and this
+ * should be used in preference to the standard libpng K channel replication
+ * into R, G and B channels.
+ *
+ * Previously it was suggested that an RGB profile on grayscale data could be
+ * handled. However it it is clear that using an RGB profile in this context
+ * must be an error - there is no specification of what it means. Thus it is
+ * almost certainly more correct to ignore the profile.
+ */
+ temp = png_get_uint_32(profile+16); /* data colour space field */
+ switch (temp)
+ {
+ case 0x52474220: /* 'RGB ' */
+ if ((color_type & PNG_COLOR_MASK_COLOR) == 0)
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "RGB color space not permitted on grayscale PNG");
+ break;
+
+ case 0x47524159: /* 'GRAY' */
+ if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "Gray color space not permitted on RGB PNG");
+ break;
+
+ default:
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid ICC profile color space");
+ }
+
+ /* It is up to the application to check that the profile class matches the
+ * application requirements; the spec provides no guidance, but it's pretty
+ * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer
+ * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these
+ * cases. Issue an error for device link or abstract profiles - these don't
+ * contain the records necessary to transform the color-space to anything
+ * other than the target device (and not even that for an abstract profile).
+ * Profiles of these classes may not be embedded in images.
+ */
+ temp = png_get_uint_32(profile+12); /* profile/device class */
+ switch (temp)
+ {
+ case 0x73636e72: /* 'scnr' */
+ case 0x6d6e7472: /* 'mntr' */
+ case 0x70727472: /* 'prtr' */
+ case 0x73706163: /* 'spac' */
+ /* All supported */
+ break;
+
+ case 0x61627374: /* 'abst' */
+ /* May not be embedded in an image */
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid embedded Abstract ICC profile");
+
+ case 0x6c696e6b: /* 'link' */
+ /* DeviceLink profiles cannot be interpreted in a non-device specific
+ * fashion, if an app uses the AToB0Tag in the profile the results are
+ * undefined unless the result is sent to the intended device,
+ * therefore a DeviceLink profile should not be found embedded in a
+ * PNG.
+ */
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "unexpected DeviceLink ICC profile class");
+
+ case 0x6e6d636c: /* 'nmcl' */
+ /* A NamedColor profile is also device specific, however it doesn't
+ * contain an AToB0 tag that is open to misinterpretation. Almost
+ * certainly it will fail the tests below.
+ */
+ (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+ "unexpected NamedColor ICC profile class");
+ break;
+
+ default:
+ /* To allow for future enhancements to the profile accept unrecognized
+ * profile classes with a warning, these then hit the test below on the
+ * tag content to ensure they are backward compatible with one of the
+ * understood profiles.
+ */
+ (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+ "unrecognized ICC profile class");
+ break;
+ }
+
+ /* For any profile other than a device link one the PCS must be encoded
+ * either in XYZ or Lab.
+ */
+ temp = png_get_uint_32(profile+20);
+ switch (temp)
+ {
+ case 0x58595a20: /* 'XYZ ' */
+ case 0x4c616220: /* 'Lab ' */
+ break;
+
+ default:
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "unexpected ICC PCS encoding");
+ }
+
+ return 1;
+}
+
+int /* PRIVATE */
+png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length,
+ png_const_bytep profile /* header plus whole tag table */)
+{
+ png_uint_32 tag_count = png_get_uint_32(profile+128);
+ png_uint_32 itag;
+ png_const_bytep tag = profile+132; /* The first tag */
+
+ /* First scan all the tags in the table and add bits to the icc_info value
+ * (temporarily in 'tags').
+ */
+ for (itag=0; itag < tag_count; ++itag, tag += 12)
+ {
+ png_uint_32 tag_id = png_get_uint_32(tag+0);
+ png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */
+ png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */
+
+ /* The ICC specification does not exclude zero length tags, therefore the
+ * start might actually be anywhere if there is no data, but this would be
+ * a clear abuse of the intent of the standard so the start is checked for
+ * being in range. All defined tag types have an 8 byte header - a 4 byte
+ * type signature then 0.
+ */
+
+ /* This is a hard error; potentially it can cause read outside the
+ * profile.
+ */
+ if (tag_start > profile_length || tag_length > profile_length - tag_start)
+ return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
+ "ICC profile tag outside profile");
+
+ if ((tag_start & 3) != 0)
+ {
+ /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is
+ * only a warning here because libpng does not care about the
+ * alignment.
+ */
+ (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
+ "ICC profile tag start not a multiple of 4");
+ }
+ }
+
+ return 1; /* success, maybe with warnings */
+}
+
+#ifdef PNG_sRGB_SUPPORTED
+#if PNG_sRGB_PROFILE_CHECKS >= 0
+/* Information about the known ICC sRGB profiles */
+static const struct
+{
+ png_uint_32 adler, crc, length;
+ png_uint_32 md5[4];
+ png_byte have_md5;
+ png_byte is_broken;
+ png_uint_16 intent;
+
+# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
+# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\
+ { adler, crc, length, md5, broke, intent },
+
+} png_sRGB_checks[] =
+{
+ /* This data comes from contrib/tools/checksum-icc run on downloads of
+ * all four ICC sRGB profiles from www.color.org.
+ */
+ /* adler32, crc32, MD5[4], intent, date, length, file-name */
+ PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
+ PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
+ "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
+
+ /* ICC sRGB v2 perceptual no black-compensation: */
+ PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
+ PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
+ "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
+
+ PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
+ PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
+ "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
+
+ /* ICC sRGB v4 perceptual */
+ PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
+ PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
+ "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
+
+ /* The following profiles have no known MD5 checksum. If there is a match
+ * on the (empty) MD5 the other fields are used to attempt a match and
+ * a warning is produced. The first two of these profiles have a 'cprt' tag
+ * which suggests that they were also made by Hewlett Packard.
+ */
+ PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
+ "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
+
+ /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
+ * match the D50 PCS illuminant in the header (it is in fact the D65 values,
+ * so the white point is recorded as the un-adapted value.) The profiles
+ * below only differ in one byte - the intent - and are basically the same as
+ * the previous profile except for the mediaWhitePointTag error and a missing
+ * chromaticAdaptationTag.
+ */
+ PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
+ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
+
+ PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
+ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
+};
+
+static int
+png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
+ png_const_bytep profile, uLong adler)
+{
+ /* The quick check is to verify just the MD5 signature and trust the
+ * rest of the data. Because the profile has already been verified for
+ * correctness this is safe. png_colorspace_set_sRGB will check the 'intent'
+ * field too, so if the profile has been edited with an intent not defined
+ * by sRGB (but maybe defined by a later ICC specification) the read of
+ * the profile will fail at that point.
+ */
+
+ png_uint_32 length = 0;
+ png_uint_32 intent = 0x10000; /* invalid */
+#if PNG_sRGB_PROFILE_CHECKS > 1
+ uLong crc = 0; /* the value for 0 length data */
+#endif
+ unsigned int i;
+
+#ifdef PNG_SET_OPTION_SUPPORTED
+ /* First see if PNG_SKIP_sRGB_CHECK_PROFILE has been set to "on" */
+ if (((png_ptr->options >> PNG_SKIP_sRGB_CHECK_PROFILE) & 3) ==
+ PNG_OPTION_ON)
+ return 0;
+#endif
+
+ for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
+ {
+ if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
+ png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
+ png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
+ png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
+ {
+ /* This may be one of the old HP profiles without an MD5, in that
+ * case we can only use the length and Adler32 (note that these
+ * are not used by default if there is an MD5!)
+ */
+# if PNG_sRGB_PROFILE_CHECKS == 0
+ if (png_sRGB_checks[i].have_md5 != 0)
+ return 1+png_sRGB_checks[i].is_broken;
+# endif
+
+ /* Profile is unsigned or more checks have been configured in. */
+ if (length == 0)
+ {
+ length = png_get_uint_32(profile);
+ intent = png_get_uint_32(profile+64);
+ }
+
+ /* Length *and* intent must match */
+ if (length == (png_uint_32) png_sRGB_checks[i].length &&
+ intent == (png_uint_32) png_sRGB_checks[i].intent)
+ {
+ /* Now calculate the adler32 if not done already. */
+ if (adler == 0)
+ {
+ adler = adler32(0, NULL, 0);
+ adler = adler32(adler, profile, length);
+ }
+
+ if (adler == png_sRGB_checks[i].adler)
+ {
+ /* These basic checks suggest that the data has not been
+ * modified, but if the check level is more than 1 perform
+ * our own crc32 checksum on the data.
+ */
+# if PNG_sRGB_PROFILE_CHECKS > 1
+ if (crc == 0)
+ {
+ crc = crc32(0, NULL, 0);
+ crc = crc32(crc, profile, length);
+ }
+
+ /* So this check must pass for the 'return' below to happen.
+ */
+ if (crc == png_sRGB_checks[i].crc)
+# endif
+ {
+ if (png_sRGB_checks[i].is_broken != 0)
+ {
+ /* These profiles are known to have bad data that may cause
+ * problems if they are used, therefore attempt to
+ * discourage their use, skip the 'have_md5' warning below,
+ * which is made irrelevant by this error.
+ */
+ png_chunk_report(png_ptr, "known incorrect sRGB profile",
+ PNG_CHUNK_ERROR);
+ }
+
+ /* Warn that this being done; this isn't even an error since
+ * the profile is perfectly valid, but it would be nice if
+ * people used the up-to-date ones.
+ */
+ else if (png_sRGB_checks[i].have_md5 == 0)
+ {
+ png_chunk_report(png_ptr,
+ "out-of-date sRGB profile with no signature",
+ PNG_CHUNK_WARNING);
+ }
+
+ return 1+png_sRGB_checks[i].is_broken;
+ }
+ }
+
+# if PNG_sRGB_PROFILE_CHECKS > 0
+ /* The signature matched, but the profile had been changed in some
+ * way. This probably indicates a data error or uninformed hacking.
+ * Fall through to "no match".
+ */
+ png_chunk_report(png_ptr,
+ "Not recognizing known sRGB profile that has been edited",
+ PNG_CHUNK_WARNING);
+ break;
+# endif
+ }
+ }
+ }
+
+ return 0; /* no match */
+}
+
+void /* PRIVATE */
+png_icc_set_sRGB(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
+{
+ /* Is this profile one of the known ICC sRGB profiles? If it is, just set
+ * the sRGB information.
+ */
+ if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler) != 0)
+ (void)png_colorspace_set_sRGB(png_ptr, colorspace,
+ (int)/*already checked*/png_get_uint_32(profile+64));
+}
+#endif /* PNG_sRGB_PROFILE_CHECKS >= 0 */
+#endif /* sRGB */
+
+int /* PRIVATE */
+png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
+ int color_type)
+{
+ if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
+ return 0;
+
+ if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
+ png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
+ color_type) != 0 &&
+ png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
+ profile) != 0)
+ {
+# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
+ /* If no sRGB support, don't try storing sRGB information */
+ png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
+# endif
+ return 1;
+ }
+
+ /* Failure case */
+ return 0;
+}
+#endif /* iCCP */
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+void /* PRIVATE */
+png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
+{
+ /* Set the rgb_to_gray coefficients from the colorspace. */
+ if (png_ptr->rgb_to_gray_coefficients_set == 0 &&
+ (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+ {
+ /* png_set_background has not been called, get the coefficients from the Y
+ * values of the colorspace colorants.
+ */
+ png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y;
+ png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y;
+ png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y;
+ png_fixed_point total = r+g+b;
+
+ if (total > 0 &&
+ r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
+ g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
+ b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
+ r+g+b <= 32769)
+ {
+ /* We allow 0 coefficients here. r+g+b may be 32769 if two or
+ * all of the coefficients were rounded up. Handle this by
+ * reducing the *largest* coefficient by 1; this matches the
+ * approach used for the default coefficients in pngrtran.c
+ */
+ int add = 0;
+
+ if (r+g+b > 32768)
+ add = -1;
+ else if (r+g+b < 32768)
+ add = 1;
+
+ if (add != 0)
+ {
+ if (g >= r && g >= b)
+ g += add;
+ else if (r >= g && r >= b)
+ r += add;
+ else
+ b += add;
+ }
+
+ /* Check for an internal error. */
+ if (r+g+b != 32768)
+ png_error(png_ptr,
+ "internal error handling cHRM coefficients");
+
+ else
+ {
+ png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r;
+ png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
+ }
+ }
+
+ /* This is a png_error at present even though it could be ignored -
+ * it should never happen, but it is important that if it does, the
+ * bug is fixed.
+ */
+ else
+ png_error(png_ptr, "internal error handling cHRM->XYZ");
+ }
+}
+#endif /* READ_RGB_TO_GRAY */
+
+#endif /* COLORSPACE */
+
+#ifdef __GNUC__
+/* This exists solely to work round a warning from GNU C. */
+static int /* PRIVATE */
+png_gt(size_t a, size_t b)
+{
+ return a > b;
+}
+#else
+# define png_gt(a,b) ((a) > (b))
+#endif
+
+void /* PRIVATE */
+png_check_IHDR(png_const_structrp png_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type)
+{
+ int error = 0;
+
+ /* Check for width and height valid values */
+ if (width == 0)
+ {
+ png_warning(png_ptr, "Image width is zero in IHDR");
+ error = 1;
+ }
+
+ if (width > PNG_UINT_31_MAX)
+ {
+ png_warning(png_ptr, "Invalid image width in IHDR");
+ error = 1;
+ }
+
+ if (png_gt(((width + 7) & (~7U)),
+ ((PNG_SIZE_MAX
+ - 48 /* big_row_buf hack */
+ - 1) /* filter byte */
+ / 8) /* 8-byte RGBA pixels */
+ - 1)) /* extra max_pixel_depth pad */
+ {
+ /* The size of the row must be within the limits of this architecture.
+ * Because the read code can perform arbitrary transformations the
+ * maximum size is checked here. Because the code in png_read_start_row
+ * adds extra space "for safety's sake" in several places a conservative
+ * limit is used here.
+ *
+ * NOTE: it would be far better to check the size that is actually used,
+ * but the effect in the real world is minor and the changes are more
+ * extensive, therefore much more dangerous and much more difficult to
+ * write in a way that avoids compiler warnings.
+ */
+ png_warning(png_ptr, "Image width is too large for this architecture");
+ error = 1;
+ }
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (width > png_ptr->user_width_max)
+#else
+ if (width > PNG_USER_WIDTH_MAX)
+#endif
+ {
+ png_warning(png_ptr, "Image width exceeds user limit in IHDR");
+ error = 1;
+ }
+
+ if (height == 0)
+ {
+ png_warning(png_ptr, "Image height is zero in IHDR");
+ error = 1;
+ }
+
+ if (height > PNG_UINT_31_MAX)
+ {
+ png_warning(png_ptr, "Invalid image height in IHDR");
+ error = 1;
+ }
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (height > png_ptr->user_height_max)
+#else
+ if (height > PNG_USER_HEIGHT_MAX)
+#endif
+ {
+ png_warning(png_ptr, "Image height exceeds user limit in IHDR");
+ error = 1;
+ }
+
+ /* Check other values */
+ if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
+ bit_depth != 8 && bit_depth != 16)
+ {
+ png_warning(png_ptr, "Invalid bit depth in IHDR");
+ error = 1;
+ }
+
+ if (color_type < 0 || color_type == 1 ||
+ color_type == 5 || color_type > 6)
+ {
+ png_warning(png_ptr, "Invalid color type in IHDR");
+ error = 1;
+ }
+
+ if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
+ ((color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
+ {
+ png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
+ error = 1;
+ }
+
+ if (interlace_type >= PNG_INTERLACE_LAST)
+ {
+ png_warning(png_ptr, "Unknown interlace method in IHDR");
+ error = 1;
+ }
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Unknown compression method in IHDR");
+ error = 1;
+ }
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ /* Accept filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not read a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 &&
+ png_ptr->mng_features_permitted != 0)
+ png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
+
+ if (filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+ (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
+ ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
+ (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
+ {
+ png_warning(png_ptr, "Unknown filter method in IHDR");
+ error = 1;
+ }
+
+ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0)
+ {
+ png_warning(png_ptr, "Invalid filter method in IHDR");
+ error = 1;
+ }
+ }
+
+#else
+ if (filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Unknown filter method in IHDR");
+ error = 1;
+ }
+#endif
+
+ if (error == 1)
+ png_error(png_ptr, "Invalid IHDR data");
+}
+
+#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
+/* ASCII to fp functions */
+/* Check an ASCII formated floating point value, see the more detailed
+ * comments in pngpriv.h
+ */
+/* The following is used internally to preserve the sticky flags */
+#define png_fp_add(state, flags) ((state) |= (flags))
+#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
+
+int /* PRIVATE */
+png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
+ png_size_tp whereami)
+{
+ int state = *statep;
+ png_size_t i = *whereami;
+
+ while (i < size)
+ {
+ int type;
+ /* First find the type of the next character */
+ switch (string[i])
+ {
+ case 43: type = PNG_FP_SAW_SIGN; break;
+ case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
+ case 46: type = PNG_FP_SAW_DOT; break;
+ case 48: type = PNG_FP_SAW_DIGIT; break;
+ case 49: case 50: case 51: case 52:
+ case 53: case 54: case 55: case 56:
+ case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
+ case 69:
+ case 101: type = PNG_FP_SAW_E; break;
+ default: goto PNG_FP_End;
+ }
+
+ /* Now deal with this type according to the current
+ * state, the type is arranged to not overlap the
+ * bits of the PNG_FP_STATE.
+ */
+ switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
+ {
+ case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
+ if ((state & PNG_FP_SAW_ANY) != 0)
+ goto PNG_FP_End; /* not a part of the number */
+
+ png_fp_add(state, type);
+ break;
+
+ case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
+ /* Ok as trailer, ok as lead of fraction. */
+ if ((state & PNG_FP_SAW_DOT) != 0) /* two dots */
+ goto PNG_FP_End;
+
+ else if ((state & PNG_FP_SAW_DIGIT) != 0) /* trailing dot? */
+ png_fp_add(state, type);
+
+ else
+ png_fp_set(state, PNG_FP_FRACTION | type);
+
+ break;
+
+ case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
+ if ((state & PNG_FP_SAW_DOT) != 0) /* delayed fraction */
+ png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
+
+ png_fp_add(state, type | PNG_FP_WAS_VALID);
+
+ break;
+
+ case PNG_FP_INTEGER + PNG_FP_SAW_E:
+ if ((state & PNG_FP_SAW_DIGIT) == 0)
+ goto PNG_FP_End;
+
+ png_fp_set(state, PNG_FP_EXPONENT);
+
+ break;
+
+ /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
+ goto PNG_FP_End; ** no sign in fraction */
+
+ /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
+ goto PNG_FP_End; ** Because SAW_DOT is always set */
+
+ case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
+ png_fp_add(state, type | PNG_FP_WAS_VALID);
+ break;
+
+ case PNG_FP_FRACTION + PNG_FP_SAW_E:
+ /* This is correct because the trailing '.' on an
+ * integer is handled above - so we can only get here
+ * with the sequence ".E" (with no preceding digits).
+ */
+ if ((state & PNG_FP_SAW_DIGIT) == 0)
+ goto PNG_FP_End;
+
+ png_fp_set(state, PNG_FP_EXPONENT);
+
+ break;
+
+ case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
+ if ((state & PNG_FP_SAW_ANY) != 0)
+ goto PNG_FP_End; /* not a part of the number */
+
+ png_fp_add(state, PNG_FP_SAW_SIGN);
+
+ break;
+
+ /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
+ goto PNG_FP_End; */
+
+ case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
+ png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
+
+ break;
+
+ /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
+ goto PNG_FP_End; */
+
+ default: goto PNG_FP_End; /* I.e. break 2 */
+ }
+
+ /* The character seems ok, continue. */
+ ++i;
+ }
+
+PNG_FP_End:
+ /* Here at the end, update the state and return the correct
+ * return code.
+ */
+ *statep = state;
+ *whereami = i;
+
+ return (state & PNG_FP_SAW_DIGIT) != 0;
+}
+
+
+/* The same but for a complete string. */
+int
+png_check_fp_string(png_const_charp string, png_size_t size)
+{
+ int state=0;
+ png_size_t char_index=0;
+
+ if (png_check_fp_number(string, size, &state, &char_index) != 0 &&
+ (char_index == size || string[char_index] == 0))
+ return state /* must be non-zero - see above */;
+
+ return 0; /* i.e. fail */
+}
+#endif /* pCAL || sCAL */
+
+#ifdef PNG_sCAL_SUPPORTED
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+/* Utility used below - a simple accurate power of ten from an integral
+ * exponent.
+ */
+static double
+png_pow10(int power)
+{
+ int recip = 0;
+ double d = 1;
+
+ /* Handle negative exponent with a reciprocal at the end because
+ * 10 is exact whereas .1 is inexact in base 2
+ */
+ if (power < 0)
+ {
+ if (power < DBL_MIN_10_EXP) return 0;
+ recip = 1; power = -power;
+ }
+
+ if (power > 0)
+ {
+ /* Decompose power bitwise. */
+ double mult = 10;
+ do
+ {
+ if (power & 1) d *= mult;
+ mult *= mult;
+ power >>= 1;
+ }
+ while (power > 0);
+
+ if (recip != 0) d = 1/d;
+ }
+ /* else power is 0 and d is 1 */
+
+ return d;
+}
+
+/* Function to format a floating point value in ASCII with a given
+ * precision.
+ */
+#if GCC_STRICT_OVERFLOW
+#pragma GCC diagnostic push
+/* The problem arises below with exp_b10, which can never overflow because it
+ * comes, originally, from frexp and is therefore limited to a range which is
+ * typically +/-710 (log2(DBL_MAX)/log2(DBL_MIN)).
+ */
+#pragma GCC diagnostic warning "-Wstrict-overflow=2"
+#endif /* GCC_STRICT_OVERFLOW */
+void /* PRIVATE */
+png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
+ double fp, unsigned int precision)
+{
+ /* We use standard functions from math.h, but not printf because
+ * that would require stdio. The caller must supply a buffer of
+ * sufficient size or we will png_error. The tests on size and
+ * the space in ascii[] consumed are indicated below.
+ */
+ if (precision < 1)
+ precision = DBL_DIG;
+
+ /* Enforce the limit of the implementation precision too. */
+ if (precision > DBL_DIG+1)
+ precision = DBL_DIG+1;
+
+ /* Basic sanity checks */
+ if (size >= precision+5) /* See the requirements below. */
+ {
+ if (fp < 0)
+ {
+ fp = -fp;
+ *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */
+ --size;
+ }
+
+ if (fp >= DBL_MIN && fp <= DBL_MAX)
+ {
+ int exp_b10; /* A base 10 exponent */
+ double base; /* 10^exp_b10 */
+
+ /* First extract a base 10 exponent of the number,
+ * the calculation below rounds down when converting
+ * from base 2 to base 10 (multiply by log10(2) -
+ * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
+ * be increased. Note that the arithmetic shift
+ * performs a floor() unlike C arithmetic - using a
+ * C multiply would break the following for negative
+ * exponents.
+ */
+ (void)frexp(fp, &exp_b10); /* exponent to base 2 */
+
+ exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
+
+ /* Avoid underflow here. */
+ base = png_pow10(exp_b10); /* May underflow */
+
+ while (base < DBL_MIN || base < fp)
+ {
+ /* And this may overflow. */
+ double test = png_pow10(exp_b10+1);
+
+ if (test <= DBL_MAX)
+ {
+ ++exp_b10; base = test;
+ }
+
+ else
+ break;
+ }
+
+ /* Normalize fp and correct exp_b10, after this fp is in the
+ * range [.1,1) and exp_b10 is both the exponent and the digit
+ * *before* which the decimal point should be inserted
+ * (starting with 0 for the first digit). Note that this
+ * works even if 10^exp_b10 is out of range because of the
+ * test on DBL_MAX above.
+ */
+ fp /= base;
+ while (fp >= 1)
+ {
+ fp /= 10; ++exp_b10;
+ }
+
+ /* Because of the code above fp may, at this point, be
+ * less than .1, this is ok because the code below can
+ * handle the leading zeros this generates, so no attempt
+ * is made to correct that here.
+ */
+
+ {
+ unsigned int czero, clead, cdigits;
+ char exponent[10];
+
+ /* Allow up to two leading zeros - this will not lengthen
+ * the number compared to using E-n.
+ */
+ if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
+ {
+ czero = 0U-exp_b10; /* PLUS 2 digits: TOTAL 3 */
+ exp_b10 = 0; /* Dot added below before first output. */
+ }
+ else
+ czero = 0; /* No zeros to add */
+
+ /* Generate the digit list, stripping trailing zeros and
+ * inserting a '.' before a digit if the exponent is 0.
+ */
+ clead = czero; /* Count of leading zeros */
+ cdigits = 0; /* Count of digits in list. */
+
+ do
+ {
+ double d;
+
+ fp *= 10;
+ /* Use modf here, not floor and subtract, so that
+ * the separation is done in one step. At the end
+ * of the loop don't break the number into parts so
+ * that the final digit is rounded.
+ */
+ if (cdigits+czero+1 < precision+clead)
+ fp = modf(fp, &d);
+
+ else
+ {
+ d = floor(fp + .5);
+
+ if (d > 9)
+ {
+ /* Rounding up to 10, handle that here. */
+ if (czero > 0)
+ {
+ --czero; d = 1;
+ if (cdigits == 0) --clead;
+ }
+ else
+ {
+ while (cdigits > 0 && d > 9)
+ {
+ int ch = *--ascii;
+
+ if (exp_b10 != (-1))
+ ++exp_b10;
+
+ else if (ch == 46)
+ {
+ ch = *--ascii; ++size;
+ /* Advance exp_b10 to '1', so that the
+ * decimal point happens after the
+ * previous digit.
+ */
+ exp_b10 = 1;
+ }
+
+ --cdigits;
+ d = ch - 47; /* I.e. 1+(ch-48) */
+ }
+
+ /* Did we reach the beginning? If so adjust the
+ * exponent but take into account the leading
+ * decimal point.
+ */
+ if (d > 9) /* cdigits == 0 */
+ {
+ if (exp_b10 == (-1))
+ {
+ /* Leading decimal point (plus zeros?), if
+ * we lose the decimal point here it must
+ * be reentered below.
+ */
+ int ch = *--ascii;
+
+ if (ch == 46)
+ {
+ ++size; exp_b10 = 1;
+ }
+
+ /* Else lost a leading zero, so 'exp_b10' is
+ * still ok at (-1)
+ */
+ }
+ else
+ ++exp_b10;
+
+ /* In all cases we output a '1' */
+ d = 1;
+ }
+ }
+ }
+ fp = 0; /* Guarantees termination below. */
+ }
+
+ if (d == 0)
+ {
+ ++czero;
+ if (cdigits == 0) ++clead;
+ }
+ else
+ {
+ /* Included embedded zeros in the digit count. */
+ cdigits += czero - clead;
+ clead = 0;
+
+ while (czero > 0)
+ {
+ /* exp_b10 == (-1) means we just output the decimal
+ * place - after the DP don't adjust 'exp_b10' any
+ * more!
+ */
+ if (exp_b10 != (-1))
+ {
+ if (exp_b10 == 0)
+ {
+ *ascii++ = 46; --size;
+ }
+ /* PLUS 1: TOTAL 4 */
+ --exp_b10;
+ }
+ *ascii++ = 48; --czero;
+ }
+
+ if (exp_b10 != (-1))
+ {
+ if (exp_b10 == 0)
+ {
+ *ascii++ = 46; --size; /* counted above */
+ }
+
+ --exp_b10;
+ }
+ *ascii++ = (char)(48 + (int)d); ++cdigits;
+ }
+ }
+ while (cdigits+czero < precision+clead && fp > DBL_MIN);
+
+ /* The total output count (max) is now 4+precision */
+
+ /* Check for an exponent, if we don't need one we are
+ * done and just need to terminate the string. At
+ * this point exp_b10==(-1) is effectively a flag - it got
+ * to '-1' because of the decrement after outputting
+ * the decimal point above (the exponent required is
+ * *not* -1!)
+ */
+ if (exp_b10 >= (-1) && exp_b10 <= 2)
+ {
+ /* The following only happens if we didn't output the
+ * leading zeros above for negative exponent, so this
+ * doesn't add to the digit requirement. Note that the
+ * two zeros here can only be output if the two leading
+ * zeros were *not* output, so this doesn't increase
+ * the output count.
+ */
+ while (exp_b10-- > 0) *ascii++ = 48;
+
+ *ascii = 0;
+
+ /* Total buffer requirement (including the '\0') is
+ * 5+precision - see check at the start.
+ */
+ return;
+ }
+
+ /* Here if an exponent is required, adjust size for
+ * the digits we output but did not count. The total
+ * digit output here so far is at most 1+precision - no
+ * decimal point and no leading or trailing zeros have
+ * been output.
+ */
+ size -= cdigits;
+
+ *ascii++ = 69; --size; /* 'E': PLUS 1 TOTAL 2+precision */
+
+ /* The following use of an unsigned temporary avoids ambiguities in
+ * the signed arithmetic on exp_b10 and permits GCC at least to do
+ * better optimization.
+ */
+ {
+ unsigned int uexp_b10;
+
+ if (exp_b10 < 0)
+ {
+ *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */
+ uexp_b10 = 0U-exp_b10;
+ }
+
+ else
+ uexp_b10 = 0U+exp_b10;
+
+ cdigits = 0;
+
+ while (uexp_b10 > 0)
+ {
+ exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
+ uexp_b10 /= 10;
+ }
+ }
+
+ /* Need another size check here for the exponent digits, so
+ * this need not be considered above.
+ */
+ if (size > cdigits)
+ {
+ while (cdigits > 0) *ascii++ = exponent[--cdigits];
+
+ *ascii = 0;
+
+ return;
+ }
+ }
+ }
+ else if (!(fp >= DBL_MIN))
+ {
+ *ascii++ = 48; /* '0' */
+ *ascii = 0;
+ return;
+ }
+ else
+ {
+ *ascii++ = 105; /* 'i' */
+ *ascii++ = 110; /* 'n' */
+ *ascii++ = 102; /* 'f' */
+ *ascii = 0;
+ return;
+ }
+ }
+
+ /* Here on buffer too small. */
+ png_error(png_ptr, "ASCII conversion buffer too small");
+}
+#if GCC_STRICT_OVERFLOW
+#pragma GCC diagnostic pop
+#endif /* GCC_STRICT_OVERFLOW */
+
+# endif /* FLOATING_POINT */
+
+# ifdef PNG_FIXED_POINT_SUPPORTED
+/* Function to format a fixed point value in ASCII.
+ */
+void /* PRIVATE */
+png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
+ png_size_t size, png_fixed_point fp)
+{
+ /* Require space for 10 decimal digits, a decimal point, a minus sign and a
+ * trailing \0, 13 characters:
+ */
+ if (size > 12)
+ {
+ png_uint_32 num;
+
+ /* Avoid overflow here on the minimum integer. */
+ if (fp < 0)
+ {
+ *ascii++ = 45; num = (png_uint_32)(-fp);
+ }
+ else
+ num = (png_uint_32)fp;
+
+ if (num <= 0x80000000) /* else overflowed */
+ {
+ unsigned int ndigits = 0, first = 16 /* flag value */;
+ char digits[10];
+
+ while (num)
+ {
+ /* Split the low digit off num: */
+ unsigned int tmp = num/10;
+ num -= tmp*10;
+ digits[ndigits++] = (char)(48 + num);
+ /* Record the first non-zero digit, note that this is a number
+ * starting at 1, it's not actually the array index.
+ */
+ if (first == 16 && num > 0)
+ first = ndigits;
+ num = tmp;
+ }
+
+ if (ndigits > 0)
+ {
+ while (ndigits > 5) *ascii++ = digits[--ndigits];
+ /* The remaining digits are fractional digits, ndigits is '5' or
+ * smaller at this point. It is certainly not zero. Check for a
+ * non-zero fractional digit:
+ */
+ if (first <= 5)
+ {
+ unsigned int i;
+ *ascii++ = 46; /* decimal point */
+ /* ndigits may be <5 for small numbers, output leading zeros
+ * then ndigits digits to first:
+ */
+ i = 5;
+ while (ndigits < i)
+ {
+ *ascii++ = 48; --i;
+ }
+ while (ndigits >= first) *ascii++ = digits[--ndigits];
+ /* Don't output the trailing zeros! */
+ }
+ }
+ else
+ *ascii++ = 48;
+
+ /* And null terminate the string: */
+ *ascii = 0;
+ return;
+ }
+ }
+
+ /* Here on buffer too small. */
+ png_error(png_ptr, "ASCII conversion buffer too small");
+}
+# endif /* FIXED_POINT */
+#endif /* SCAL */
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
+ !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
+ (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
+ defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
+ (defined(PNG_sCAL_SUPPORTED) && \
+ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
+png_fixed_point
+png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
+{
+ double r = floor(100000 * fp + .5);
+
+ if (r > 2147483647. || r < -2147483648.)
+ png_fixed_error(png_ptr, text);
+
+# ifndef PNG_ERROR_TEXT_SUPPORTED
+ PNG_UNUSED(text)
+# endif
+
+ return (png_fixed_point)r;
+}
+#endif
+
+#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_COLORSPACE_SUPPORTED) ||\
+ defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
+/* muldiv functions */
+/* This API takes signed arguments and rounds the result to the nearest
+ * integer (or, for a fixed point number - the standard argument - to
+ * the nearest .00001). Overflow and divide by zero are signalled in
+ * the result, a boolean - true on success, false on overflow.
+ */
+#if GCC_STRICT_OVERFLOW /* from above */
+/* It is not obvious which comparison below gets optimized in such a way that
+ * signed overflow would change the result; looking through the code does not
+ * reveal any tests which have the form GCC complains about, so presumably the
+ * optimizer is moving an add or subtract into the 'if' somewhere.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic warning "-Wstrict-overflow=2"
+#endif /* GCC_STRICT_OVERFLOW */
+int
+png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
+ png_int_32 divisor)
+{
+ /* Return a * times / divisor, rounded. */
+ if (divisor != 0)
+ {
+ if (a == 0 || times == 0)
+ {
+ *res = 0;
+ return 1;
+ }
+ else
+ {
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ double r = a;
+ r *= times;
+ r /= divisor;
+ r = floor(r+.5);
+
+ /* A png_fixed_point is a 32-bit integer. */
+ if (r <= 2147483647. && r >= -2147483648.)
+ {
+ *res = (png_fixed_point)r;
+ return 1;
+ }
+#else
+ int negative = 0;
+ png_uint_32 A, T, D;
+ png_uint_32 s16, s32, s00;
+
+ if (a < 0)
+ negative = 1, A = -a;
+ else
+ A = a;
+
+ if (times < 0)
+ negative = !negative, T = -times;
+ else
+ T = times;
+
+ if (divisor < 0)
+ negative = !negative, D = -divisor;
+ else
+ D = divisor;
+
+ /* Following can't overflow because the arguments only
+ * have 31 bits each, however the result may be 32 bits.
+ */
+ s16 = (A >> 16) * (T & 0xffff) +
+ (A & 0xffff) * (T >> 16);
+ /* Can't overflow because the a*times bit is only 30
+ * bits at most.
+ */
+ s32 = (A >> 16) * (T >> 16) + (s16 >> 16);
+ s00 = (A & 0xffff) * (T & 0xffff);
+
+ s16 = (s16 & 0xffff) << 16;
+ s00 += s16;
+
+ if (s00 < s16)
+ ++s32; /* carry */
+
+ if (s32 < D) /* else overflow */
+ {
+ /* s32.s00 is now the 64-bit product, do a standard
+ * division, we know that s32 < D, so the maximum
+ * required shift is 31.
+ */
+ int bitshift = 32;
+ png_fixed_point result = 0; /* NOTE: signed */
+
+ while (--bitshift >= 0)
+ {
+ png_uint_32 d32, d00;
+
+ if (bitshift > 0)
+ d32 = D >> (32-bitshift), d00 = D << bitshift;
+
+ else
+ d32 = 0, d00 = D;
+
+ if (s32 > d32)
+ {
+ if (s00 < d00) --s32; /* carry */
+ s32 -= d32, s00 -= d00, result += 1<<bitshift;
+ }
+
+ else
+ if (s32 == d32 && s00 >= d00)
+ s32 = 0, s00 -= d00, result += 1<<bitshift;
+ }
+
+ /* Handle the rounding. */
+ if (s00 >= (D >> 1))
+ ++result;
+
+ if (negative != 0)
+ result = -result;
+
+ /* Check for overflow. */
+ if ((negative != 0 && result <= 0) ||
+ (negative == 0 && result >= 0))
+ {
+ *res = result;
+ return 1;
+ }
+ }
+#endif
+ }
+ }
+
+ return 0;
+}
+#if GCC_STRICT_OVERFLOW
+#pragma GCC diagnostic pop
+#endif /* GCC_STRICT_OVERFLOW */
+#endif /* READ_GAMMA || INCH_CONVERSIONS */
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+/* The following is for when the caller doesn't much care about the
+ * result.
+ */
+png_fixed_point
+png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times,
+ png_int_32 divisor)
+{
+ png_fixed_point result;
+
+ if (png_muldiv(&result, a, times, divisor) != 0)
+ return result;
+
+ png_warning(png_ptr, "fixed point overflow ignored");
+ return 0;
+}
+#endif
+
+#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */
+/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
+png_fixed_point
+png_reciprocal(png_fixed_point a)
+{
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ double r = floor(1E10/a+.5);
+
+ if (r <= 2147483647. && r >= -2147483648.)
+ return (png_fixed_point)r;
+#else
+ png_fixed_point res;
+
+ if (png_muldiv(&res, 100000, 100000, a) != 0)
+ return res;
+#endif
+
+ return 0; /* error/overflow */
+}
+
+/* This is the shared test on whether a gamma value is 'significant' - whether
+ * it is worth doing gamma correction.
+ */
+int /* PRIVATE */
+png_gamma_significant(png_fixed_point gamma_val)
+{
+ return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||
+ gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
+}
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+#ifdef PNG_16BIT_SUPPORTED
+/* A local convenience routine. */
+static png_fixed_point
+png_product2(png_fixed_point a, png_fixed_point b)
+{
+ /* The required result is 1/a * 1/b; the following preserves accuracy. */
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ double r = a * 1E-5;
+ r *= b;
+ r = floor(r+.5);
+
+ if (r <= 2147483647. && r >= -2147483648.)
+ return (png_fixed_point)r;
+#else
+ png_fixed_point res;
+
+ if (png_muldiv(&res, a, b, 100000) != 0)
+ return res;
+#endif
+
+ return 0; /* overflow */
+}
+#endif /* 16BIT */
+
+/* The inverse of the above. */
+png_fixed_point
+png_reciprocal2(png_fixed_point a, png_fixed_point b)
+{
+ /* The required result is 1/a * 1/b; the following preserves accuracy. */
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ if (a != 0 && b != 0)
+ {
+ double r = 1E15/a;
+ r /= b;
+ r = floor(r+.5);
+
+ if (r <= 2147483647. && r >= -2147483648.)
+ return (png_fixed_point)r;
+ }
+#else
+ /* This may overflow because the range of png_fixed_point isn't symmetric,
+ * but this API is only used for the product of file and screen gamma so it
+ * doesn't matter that the smallest number it can produce is 1/21474, not
+ * 1/100000
+ */
+ png_fixed_point res = png_product2(a, b);
+
+ if (res != 0)
+ return png_reciprocal(res);
+#endif
+
+ return 0; /* overflow */
+}
+#endif /* READ_GAMMA */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */
+#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
+/* Fixed point gamma.
+ *
+ * The code to calculate the tables used below can be found in the shell script
+ * contrib/tools/intgamma.sh
+ *
+ * To calculate gamma this code implements fast log() and exp() calls using only
+ * fixed point arithmetic. This code has sufficient precision for either 8-bit
+ * or 16-bit sample values.
+ *
+ * The tables used here were calculated using simple 'bc' programs, but C double
+ * precision floating point arithmetic would work fine.
+ *
+ * 8-bit log table
+ * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to
+ * 255, so it's the base 2 logarithm of a normalized 8-bit floating point
+ * mantissa. The numbers are 32-bit fractions.
+ */
+static const png_uint_32
+png_8bit_l2[128] =
+{
+ 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,
+ 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,
+ 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,
+ 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,
+ 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,
+ 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,
+ 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,
+ 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,
+ 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,
+ 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,
+ 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,
+ 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,
+ 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,
+ 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,
+ 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,
+ 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,
+ 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,
+ 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,
+ 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,
+ 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U,
+ 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U,
+ 24347096U, 0U
+
+#if 0
+ /* The following are the values for 16-bit tables - these work fine for the
+ * 8-bit conversions but produce very slightly larger errors in the 16-bit
+ * log (about 1.2 as opposed to 0.7 absolute error in the final value). To
+ * use these all the shifts below must be adjusted appropriately.
+ */
+ 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,
+ 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,
+ 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,
+ 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,
+ 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,
+ 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,
+ 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,
+ 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,
+ 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,
+ 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,
+ 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,
+ 1119, 744, 372
+#endif
+};
+
+static png_int_32
+png_log8bit(unsigned int x)
+{
+ unsigned int lg2 = 0;
+ /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log,
+ * because the log is actually negate that means adding 1. The final
+ * returned value thus has the range 0 (for 255 input) to 7.994 (for 1
+ * input), return -1 for the overflow (log 0) case, - so the result is
+ * always at most 19 bits.
+ */
+ if ((x &= 0xff) == 0)
+ return -1;
+
+ if ((x & 0xf0) == 0)
+ lg2 = 4, x <<= 4;
+
+ if ((x & 0xc0) == 0)
+ lg2 += 2, x <<= 2;
+
+ if ((x & 0x80) == 0)
+ lg2 += 1, x <<= 1;
+
+ /* result is at most 19 bits, so this cast is safe: */
+ return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16));
+}
+
+/* The above gives exact (to 16 binary places) log2 values for 8-bit images,
+ * for 16-bit images we use the most significant 8 bits of the 16-bit value to
+ * get an approximation then multiply the approximation by a correction factor
+ * determined by the remaining up to 8 bits. This requires an additional step
+ * in the 16-bit case.
+ *
+ * We want log2(value/65535), we have log2(v'/255), where:
+ *
+ * value = v' * 256 + v''
+ * = v' * f
+ *
+ * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128
+ * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less
+ * than 258. The final factor also needs to correct for the fact that our 8-bit
+ * value is scaled by 255, whereas the 16-bit values must be scaled by 65535.
+ *
+ * This gives a final formula using a calculated value 'x' which is value/v' and
+ * scaling by 65536 to match the above table:
+ *
+ * log2(x/257) * 65536
+ *
+ * Since these numbers are so close to '1' we can use simple linear
+ * interpolation between the two end values 256/257 (result -368.61) and 258/257
+ * (result 367.179). The values used below are scaled by a further 64 to give
+ * 16-bit precision in the interpolation:
+ *
+ * Start (256): -23591
+ * Zero (257): 0
+ * End (258): 23499
+ */
+#ifdef PNG_16BIT_SUPPORTED
+static png_int_32
+png_log16bit(png_uint_32 x)
+{
+ unsigned int lg2 = 0;
+
+ /* As above, but now the input has 16 bits. */
+ if ((x &= 0xffff) == 0)
+ return -1;
+
+ if ((x & 0xff00) == 0)
+ lg2 = 8, x <<= 8;
+
+ if ((x & 0xf000) == 0)
+ lg2 += 4, x <<= 4;
+
+ if ((x & 0xc000) == 0)
+ lg2 += 2, x <<= 2;
+
+ if ((x & 0x8000) == 0)
+ lg2 += 1, x <<= 1;
+
+ /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional
+ * value.
+ */
+ lg2 <<= 28;
+ lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4;
+
+ /* Now we need to interpolate the factor, this requires a division by the top
+ * 8 bits. Do this with maximum precision.
+ */
+ x = ((x << 16) + (x >> 9)) / (x >> 8);
+
+ /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,
+ * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly
+ * 16 bits to interpolate to get the low bits of the result. Round the
+ * answer. Note that the end point values are scaled by 64 to retain overall
+ * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust
+ * the overall scaling by 6-12. Round at every step.
+ */
+ x -= 1U << 24;
+
+ if (x <= 65536U) /* <= '257' */
+ lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12);
+
+ else
+ lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);
+
+ /* Safe, because the result can't have more than 20 bits: */
+ return (png_int_32)((lg2 + 2048) >> 12);
+}
+#endif /* 16BIT */
+
+/* The 'exp()' case must invert the above, taking a 20-bit fixed point
+ * logarithmic value and returning a 16 or 8-bit number as appropriate. In
+ * each case only the low 16 bits are relevant - the fraction - since the
+ * integer bits (the top 4) simply determine a shift.
+ *
+ * The worst case is the 16-bit distinction between 65535 and 65534. This
+ * requires perhaps spurious accuracy in the decoding of the logarithm to
+ * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance
+ * of getting this accuracy in practice.
+ *
+ * To deal with this the following exp() function works out the exponent of the
+ * fractional part of the logarithm by using an accurate 32-bit value from the
+ * top four fractional bits then multiplying in the remaining bits.
+ */
+static const png_uint_32
+png_32bit_exp[16] =
+{
+ /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */
+ 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U,
+ 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U,
+ 2553802834U, 2445529972U, 2341847524U, 2242560872U
+};
+
+/* Adjustment table; provided to explain the numbers in the code below. */
+#if 0
+for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"}
+ 11 44937.64284865548751208448
+ 10 45180.98734845585101160448
+ 9 45303.31936980687359311872
+ 8 45364.65110595323018870784
+ 7 45395.35850361789624614912
+ 6 45410.72259715102037508096
+ 5 45418.40724413220722311168
+ 4 45422.25021786898173001728
+ 3 45424.17186732298419044352
+ 2 45425.13273269940811464704
+ 1 45425.61317555035558641664
+ 0 45425.85339951654943850496
+#endif
+
+static png_uint_32
+png_exp(png_fixed_point x)
+{
+ if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */
+ {
+ /* Obtain a 4-bit approximation */
+ png_uint_32 e = png_32bit_exp[(x >> 12) & 0x0f];
+
+ /* Incorporate the low 12 bits - these decrease the returned value by
+ * multiplying by a number less than 1 if the bit is set. The multiplier
+ * is determined by the above table and the shift. Notice that the values
+ * converge on 45426 and this is used to allow linear interpolation of the
+ * low bits.
+ */
+ if (x & 0x800)
+ e -= (((e >> 16) * 44938U) + 16U) >> 5;
+
+ if (x & 0x400)
+ e -= (((e >> 16) * 45181U) + 32U) >> 6;
+
+ if (x & 0x200)
+ e -= (((e >> 16) * 45303U) + 64U) >> 7;
+
+ if (x & 0x100)
+ e -= (((e >> 16) * 45365U) + 128U) >> 8;
+
+ if (x & 0x080)
+ e -= (((e >> 16) * 45395U) + 256U) >> 9;
+
+ if (x & 0x040)
+ e -= (((e >> 16) * 45410U) + 512U) >> 10;
+
+ /* And handle the low 6 bits in a single block. */
+ e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;
+
+ /* Handle the upper bits of x. */
+ e >>= x >> 16;
+ return e;
+ }
+
+ /* Check for overflow */
+ if (x <= 0)
+ return png_32bit_exp[0];
+
+ /* Else underflow */
+ return 0;
+}
+
+static png_byte
+png_exp8bit(png_fixed_point lg2)
+{
+ /* Get a 32-bit value: */
+ png_uint_32 x = png_exp(lg2);
+
+ /* Convert the 32-bit value to 0..255 by multiplying by 256-1. Note that the
+ * second, rounding, step can't overflow because of the first, subtraction,
+ * step.
+ */
+ x -= x >> 8;
+ return (png_byte)(((x + 0x7fffffU) >> 24) & 0xff);
+}
+
+#ifdef PNG_16BIT_SUPPORTED
+static png_uint_16
+png_exp16bit(png_fixed_point lg2)
+{
+ /* Get a 32-bit value: */
+ png_uint_32 x = png_exp(lg2);
+
+ /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
+ x -= x >> 16;
+ return (png_uint_16)((x + 32767U) >> 16);
+}
+#endif /* 16BIT */
+#endif /* FLOATING_ARITHMETIC */
+
+png_byte
+png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
+{
+ if (value > 0 && value < 255)
+ {
+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ /* 'value' is unsigned, ANSI-C90 requires the compiler to correctly
+ * convert this to a floating point value. This includes values that
+ * would overflow if 'value' were to be converted to 'int'.
+ *
+ * Apparently GCC, however, does an intermediate conversion to (int)
+ * on some (ARM) but not all (x86) platforms, possibly because of
+ * hardware FP limitations. (E.g. if the hardware conversion always
+ * assumes the integer register contains a signed value.) This results
+ * in ANSI-C undefined behavior for large values.
+ *
+ * Other implementations on the same machine might actually be ANSI-C90
+ * conformant and therefore compile spurious extra code for the large
+ * values.
+ *
+ * We can be reasonably sure that an unsigned to float conversion
+ * won't be faster than an int to float one. Therefore this code
+ * assumes responsibility for the undefined behavior, which it knows
+ * can't happen because of the check above.
+ *
+ * Note the argument to this routine is an (unsigned int) because, on
+ * 16-bit platforms, it is assigned a value which might be out of
+ * range for an (int); that would result in undefined behavior in the
+ * caller if the *argument* ('value') were to be declared (int).
+ */
+ double r = floor(255*pow((int)/*SAFE*/value/255.,gamma_val*.00001)+.5);
+ return (png_byte)r;
+# else
+ png_int_32 lg2 = png_log8bit(value);
+ png_fixed_point res;
+
+ if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
+ return png_exp8bit(res);
+
+ /* Overflow. */
+ value = 0;
+# endif
+ }
+
+ return (png_byte)(value & 0xff);
+}
+
+#ifdef PNG_16BIT_SUPPORTED
+png_uint_16
+png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
+{
+ if (value > 0 && value < 65535)
+ {
+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ /* The same (unsigned int)->(double) constraints apply here as above,
+ * however in this case the (unsigned int) to (int) conversion can
+ * overflow on an ANSI-C90 compliant system so the cast needs to ensure
+ * that this is not possible.
+ */
+ double r = floor(65535*pow((png_int_32)value/65535.,
+ gamma_val*.00001)+.5);
+ return (png_uint_16)r;
+# else
+ png_int_32 lg2 = png_log16bit(value);
+ png_fixed_point res;
+
+ if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1) != 0)
+ return png_exp16bit(res);
+
+ /* Overflow. */
+ value = 0;
+# endif
+ }
+
+ return (png_uint_16)value;
+}
+#endif /* 16BIT */
+
+/* This does the right thing based on the bit_depth field of the
+ * png_struct, interpreting values as 8-bit or 16-bit. While the result
+ * is nominally a 16-bit value if bit depth is 8 then the result is
+ * 8-bit (as are the arguments.)
+ */
+png_uint_16 /* PRIVATE */
+png_gamma_correct(png_structrp png_ptr, unsigned int value,
+ png_fixed_point gamma_val)
+{
+ if (png_ptr->bit_depth == 8)
+ return png_gamma_8bit_correct(value, gamma_val);
+
+#ifdef PNG_16BIT_SUPPORTED
+ else
+ return png_gamma_16bit_correct(value, gamma_val);
+#else
+ /* should not reach this */
+ return 0;
+#endif /* 16BIT */
+}
+
+#ifdef PNG_16BIT_SUPPORTED
+/* Internal function to build a single 16-bit table - the table consists of
+ * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount
+ * to shift the input values right (or 16-number_of_signifiant_bits).
+ *
+ * The caller is responsible for ensuring that the table gets cleaned up on
+ * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument
+ * should be somewhere that will be cleaned.
+ */
+static void
+png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
+ PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+{
+ /* Various values derived from 'shift': */
+ PNG_CONST unsigned int num = 1U << (8U - shift);
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ /* CSE the division and work round wacky GCC warnings (see the comments
+ * in png_gamma_8bit_correct for where these come from.)
+ */
+ PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1);
+#endif
+ PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
+ PNG_CONST unsigned int max_by_2 = 1U << (15U-shift);
+ unsigned int i;
+
+ png_uint_16pp table = *ptable =
+ (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
+
+ for (i = 0; i < num; i++)
+ {
+ png_uint_16p sub_table = table[i] =
+ (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16)));
+
+ /* The 'threshold' test is repeated here because it can arise for one of
+ * the 16-bit tables even if the others don't hit it.
+ */
+ if (png_gamma_significant(gamma_val) != 0)
+ {
+ /* The old code would overflow at the end and this would cause the
+ * 'pow' function to return a result >1, resulting in an
+ * arithmetic error. This code follows the spec exactly; ig is
+ * the recovered input sample, it always has 8-16 bits.
+ *
+ * We want input * 65535/max, rounded, the arithmetic fits in 32
+ * bits (unsigned) so long as max <= 32767.
+ */
+ unsigned int j;
+ for (j = 0; j < 256; j++)
+ {
+ png_uint_32 ig = (j << (8-shift)) + i;
+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ /* Inline the 'max' scaling operation: */
+ /* See png_gamma_8bit_correct for why the cast to (int) is
+ * required here.
+ */
+ double d = floor(65535.*pow(ig*fmax, gamma_val*.00001)+.5);
+ sub_table[j] = (png_uint_16)d;
+# else
+ if (shift != 0)
+ ig = (ig * 65535U + max_by_2)/max;
+
+ sub_table[j] = png_gamma_16bit_correct(ig, gamma_val);
+# endif
+ }
+ }
+ else
+ {
+ /* We must still build a table, but do it the fast way. */
+ unsigned int j;
+
+ for (j = 0; j < 256; j++)
+ {
+ png_uint_32 ig = (j << (8-shift)) + i;
+
+ if (shift != 0)
+ ig = (ig * 65535U + max_by_2)/max;
+
+ sub_table[j] = (png_uint_16)ig;
+ }
+ }
+ }
+}
+
+/* NOTE: this function expects the *inverse* of the overall gamma transformation
+ * required.
+ */
+static void
+png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
+ PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+{
+ PNG_CONST unsigned int num = 1U << (8U - shift);
+ PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
+ unsigned int i;
+ png_uint_32 last;
+
+ png_uint_16pp table = *ptable =
+ (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
+
+ /* 'num' is the number of tables and also the number of low bits of low
+ * bits of the input 16-bit value used to select a table. Each table is
+ * itself indexed by the high 8 bits of the value.
+ */
+ for (i = 0; i < num; i++)
+ table[i] = (png_uint_16p)png_malloc(png_ptr,
+ 256 * (sizeof (png_uint_16)));
+
+ /* 'gamma_val' is set to the reciprocal of the value calculated above, so
+ * pow(out,g) is an *input* value. 'last' is the last input value set.
+ *
+ * In the loop 'i' is used to find output values. Since the output is
+ * 8-bit there are only 256 possible values. The tables are set up to
+ * select the closest possible output value for each input by finding
+ * the input value at the boundary between each pair of output values
+ * and filling the table up to that boundary with the lower output
+ * value.
+ *
+ * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9-bit
+ * values the code below uses a 16-bit value in i; the values start at
+ * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last
+ * entries are filled with 255). Start i at 128 and fill all 'last'
+ * table entries <= 'max'
+ */
+ last = 0;
+ for (i = 0; i < 255; ++i) /* 8-bit output value */
+ {
+ /* Find the corresponding maximum input value */
+ png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */
+
+ /* Find the boundary value in 16 bits: */
+ png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val);
+
+ /* Adjust (round) to (16-shift) bits: */
+ bound = (bound * max + 32768U)/65535U + 1U;
+
+ while (last < bound)
+ {
+ table[last & (0xffU >> shift)][last >> (8U - shift)] = out;
+ last++;
+ }
+ }
+
+ /* And fill in the final entries. */
+ while (last < (num << 8))
+ {
+ table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U;
+ last++;
+ }
+}
+#endif /* 16BIT */
+
+/* Build a single 8-bit table: same as the 16-bit case but much simpler (and
+ * typically much faster). Note that libpng currently does no sBIT processing
+ * (apparently contrary to the spec) so a 256-entry table is always generated.
+ */
+static void
+png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
+ PNG_CONST png_fixed_point gamma_val)
+{
+ unsigned int i;
+ png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
+
+ if (png_gamma_significant(gamma_val) != 0)
+ for (i=0; i<256; i++)
+ table[i] = png_gamma_8bit_correct(i, gamma_val);
+
+ else
+ for (i=0; i<256; ++i)
+ table[i] = (png_byte)(i & 0xff);
+}
+
+/* Used from png_read_destroy and below to release the memory used by the gamma
+ * tables.
+ */
+void /* PRIVATE */
+png_destroy_gamma_table(png_structrp png_ptr)
+{
+ png_free(png_ptr, png_ptr->gamma_table);
+ png_ptr->gamma_table = NULL;
+
+#ifdef PNG_16BIT_SUPPORTED
+ if (png_ptr->gamma_16_table != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_table[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_table);
+ png_ptr->gamma_16_table = NULL;
+ }
+#endif /* 16BIT */
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ png_free(png_ptr, png_ptr->gamma_from_1);
+ png_ptr->gamma_from_1 = NULL;
+ png_free(png_ptr, png_ptr->gamma_to_1);
+ png_ptr->gamma_to_1 = NULL;
+
+#ifdef PNG_16BIT_SUPPORTED
+ if (png_ptr->gamma_16_from_1 != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_from_1);
+ png_ptr->gamma_16_from_1 = NULL;
+ }
+ if (png_ptr->gamma_16_to_1 != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_to_1);
+ png_ptr->gamma_16_to_1 = NULL;
+ }
+#endif /* 16BIT */
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+}
+
+/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
+ * tables, we don't make a full table if we are reducing to 8-bit in
+ * the future. Note also how the gamma_16 tables are segmented so that
+ * we don't need to allocate > 64K chunks for a full 16-bit table.
+ */
+void /* PRIVATE */
+png_build_gamma_table(png_structrp png_ptr, int bit_depth)
+{
+ png_debug(1, "in png_build_gamma_table");
+
+ /* Remove any existing table; this copes with multiple calls to
+ * png_read_update_info. The warning is because building the gamma tables
+ * multiple times is a performance hit - it's harmless but the ability to
+ * call png_read_update_info() multiple times is new in 1.5.6 so it seems
+ * sensible to warn if the app introduces such a hit.
+ */
+ if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
+ {
+ png_warning(png_ptr, "gamma table being rebuilt");
+ png_destroy_gamma_table(png_ptr);
+ }
+
+ if (bit_depth <= 8)
+ {
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
+ png_ptr->screen_gamma > 0 ?
+ png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+ {
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
+ png_reciprocal(png_ptr->colorspace.gamma));
+
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
+ png_ptr->screen_gamma > 0 ?
+ png_reciprocal(png_ptr->screen_gamma) :
+ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+ }
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+ }
+#ifdef PNG_16BIT_SUPPORTED
+ else
+ {
+ png_byte shift, sig_bit;
+
+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ {
+ sig_bit = png_ptr->sig_bit.red;
+
+ if (png_ptr->sig_bit.green > sig_bit)
+ sig_bit = png_ptr->sig_bit.green;
+
+ if (png_ptr->sig_bit.blue > sig_bit)
+ sig_bit = png_ptr->sig_bit.blue;
+ }
+ else
+ sig_bit = png_ptr->sig_bit.gray;
+
+ /* 16-bit gamma code uses this equation:
+ *
+ * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
+ *
+ * Where 'iv' is the input color value and 'ov' is the output value -
+ * pow(iv, gamma).
+ *
+ * Thus the gamma table consists of up to 256 256-entry tables. The table
+ * is selected by the (8-gamma_shift) most significant of the low 8 bits
+ * of the color value then indexed by the upper 8 bits:
+ *
+ * table[low bits][high 8 bits]
+ *
+ * So the table 'n' corresponds to all those 'iv' of:
+ *
+ * <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
+ *
+ */
+ if (sig_bit > 0 && sig_bit < 16U)
+ /* shift == insignificant bits */
+ shift = (png_byte)((16U - sig_bit) & 0xff);
+
+ else
+ shift = 0; /* keep all 16 bits */
+
+ if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+ {
+ /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
+ * the significant bits in the *input* when the output will
+ * eventually be 8 bits. By default it is 11.
+ */
+ if (shift < (16U - PNG_MAX_GAMMA_8))
+ shift = (16U - PNG_MAX_GAMMA_8);
+ }
+
+ if (shift > 8U)
+ shift = 8U; /* Guarantees at least one table! */
+
+ png_ptr->gamma_shift = shift;
+
+ /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
+ * PNG_COMPOSE). This effectively smashed the background calculation for
+ * 16-bit output because the 8-bit table assumes the result will be
+ * reduced to 8 bits.
+ */
+ if ((png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8)) != 0)
+ png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
+ png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
+
+ else
+ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
+ png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if ((png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY)) != 0)
+ {
+ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
+ png_reciprocal(png_ptr->colorspace.gamma));
+
+ /* Notice that the '16 from 1' table should be full precision, however
+ * the lookup on this table still uses gamma_shift, so it can't be.
+ * TODO: fix this.
+ */
+ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
+ png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
+ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+ }
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+ }
+#endif /* 16BIT */
+}
+#endif /* READ_GAMMA */
+
+/* HARDWARE OR SOFTWARE OPTION SUPPORT */
+#ifdef PNG_SET_OPTION_SUPPORTED
+int PNGAPI
+png_set_option(png_structrp png_ptr, int option, int onoff)
+{
+ if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
+ (option & 1) == 0)
+ {
+ png_uint_32 mask = 3U << option;
+ png_uint_32 setting = (2U + (onoff != 0)) << option;
+ png_uint_32 current = png_ptr->options;
+
+ png_ptr->options = (png_uint_32)(((current & ~mask) | setting) & 0xff);
+
+ return (int)(current & mask) >> option;
+ }
+
+ return PNG_OPTION_INVALID;
+}
+#endif
+
+/* sRGB support */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+/* sRGB conversion tables; these are machine generated with the code in
+ * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the
+ * specification (see the article at https://en.wikipedia.org/wiki/SRGB)
+ * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
+ * The sRGB to linear table is exact (to the nearest 16-bit linear fraction).
+ * The inverse (linear to sRGB) table has accuracies as follows:
+ *
+ * For all possible (255*65535+1) input values:
+ *
+ * error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact
+ *
+ * For the input values corresponding to the 65536 16-bit values:
+ *
+ * error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact
+ *
+ * In all cases the inexact readings are only off by one.
+ */
+
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+/* The convert-to-sRGB table is only currently required for read. */
+const png_uint_16 png_sRGB_table[256] =
+{
+ 0,20,40,60,80,99,119,139,
+ 159,179,199,219,241,264,288,313,
+ 340,367,396,427,458,491,526,562,
+ 599,637,677,718,761,805,851,898,
+ 947,997,1048,1101,1156,1212,1270,1330,
+ 1391,1453,1517,1583,1651,1720,1790,1863,
+ 1937,2013,2090,2170,2250,2333,2418,2504,
+ 2592,2681,2773,2866,2961,3058,3157,3258,
+ 3360,3464,3570,3678,3788,3900,4014,4129,
+ 4247,4366,4488,4611,4736,4864,4993,5124,
+ 5257,5392,5530,5669,5810,5953,6099,6246,
+ 6395,6547,6700,6856,7014,7174,7335,7500,
+ 7666,7834,8004,8177,8352,8528,8708,8889,
+ 9072,9258,9445,9635,9828,10022,10219,10417,
+ 10619,10822,11028,11235,11446,11658,11873,12090,
+ 12309,12530,12754,12980,13209,13440,13673,13909,
+ 14146,14387,14629,14874,15122,15371,15623,15878,
+ 16135,16394,16656,16920,17187,17456,17727,18001,
+ 18277,18556,18837,19121,19407,19696,19987,20281,
+ 20577,20876,21177,21481,21787,22096,22407,22721,
+ 23038,23357,23678,24002,24329,24658,24990,25325,
+ 25662,26001,26344,26688,27036,27386,27739,28094,
+ 28452,28813,29176,29542,29911,30282,30656,31033,
+ 31412,31794,32179,32567,32957,33350,33745,34143,
+ 34544,34948,35355,35764,36176,36591,37008,37429,
+ 37852,38278,38706,39138,39572,40009,40449,40891,
+ 41337,41785,42236,42690,43147,43606,44069,44534,
+ 45002,45473,45947,46423,46903,47385,47871,48359,
+ 48850,49344,49841,50341,50844,51349,51858,52369,
+ 52884,53401,53921,54445,54971,55500,56032,56567,
+ 57105,57646,58190,58737,59287,59840,60396,60955,
+ 61517,62082,62650,63221,63795,64372,64952,65535
+};
+#endif /* SIMPLIFIED_READ */
+
+/* The base/delta tables are required for both read and write (but currently
+ * only the simplified versions.)
+ */
+const png_uint_16 png_sRGB_base[512] =
+{
+ 128,1782,3383,4644,5675,6564,7357,8074,
+ 8732,9346,9921,10463,10977,11466,11935,12384,
+ 12816,13233,13634,14024,14402,14769,15125,15473,
+ 15812,16142,16466,16781,17090,17393,17690,17981,
+ 18266,18546,18822,19093,19359,19621,19879,20133,
+ 20383,20630,20873,21113,21349,21583,21813,22041,
+ 22265,22487,22707,22923,23138,23350,23559,23767,
+ 23972,24175,24376,24575,24772,24967,25160,25352,
+ 25542,25730,25916,26101,26284,26465,26645,26823,
+ 27000,27176,27350,27523,27695,27865,28034,28201,
+ 28368,28533,28697,28860,29021,29182,29341,29500,
+ 29657,29813,29969,30123,30276,30429,30580,30730,
+ 30880,31028,31176,31323,31469,31614,31758,31902,
+ 32045,32186,32327,32468,32607,32746,32884,33021,
+ 33158,33294,33429,33564,33697,33831,33963,34095,
+ 34226,34357,34486,34616,34744,34873,35000,35127,
+ 35253,35379,35504,35629,35753,35876,35999,36122,
+ 36244,36365,36486,36606,36726,36845,36964,37083,
+ 37201,37318,37435,37551,37668,37783,37898,38013,
+ 38127,38241,38354,38467,38580,38692,38803,38915,
+ 39026,39136,39246,39356,39465,39574,39682,39790,
+ 39898,40005,40112,40219,40325,40431,40537,40642,
+ 40747,40851,40955,41059,41163,41266,41369,41471,
+ 41573,41675,41777,41878,41979,42079,42179,42279,
+ 42379,42478,42577,42676,42775,42873,42971,43068,
+ 43165,43262,43359,43456,43552,43648,43743,43839,
+ 43934,44028,44123,44217,44311,44405,44499,44592,
+ 44685,44778,44870,44962,45054,45146,45238,45329,
+ 45420,45511,45601,45692,45782,45872,45961,46051,
+ 46140,46229,46318,46406,46494,46583,46670,46758,
+ 46846,46933,47020,47107,47193,47280,47366,47452,
+ 47538,47623,47709,47794,47879,47964,48048,48133,
+ 48217,48301,48385,48468,48552,48635,48718,48801,
+ 48884,48966,49048,49131,49213,49294,49376,49458,
+ 49539,49620,49701,49782,49862,49943,50023,50103,
+ 50183,50263,50342,50422,50501,50580,50659,50738,
+ 50816,50895,50973,51051,51129,51207,51285,51362,
+ 51439,51517,51594,51671,51747,51824,51900,51977,
+ 52053,52129,52205,52280,52356,52432,52507,52582,
+ 52657,52732,52807,52881,52956,53030,53104,53178,
+ 53252,53326,53400,53473,53546,53620,53693,53766,
+ 53839,53911,53984,54056,54129,54201,54273,54345,
+ 54417,54489,54560,54632,54703,54774,54845,54916,
+ 54987,55058,55129,55199,55269,55340,55410,55480,
+ 55550,55620,55689,55759,55828,55898,55967,56036,
+ 56105,56174,56243,56311,56380,56448,56517,56585,
+ 56653,56721,56789,56857,56924,56992,57059,57127,
+ 57194,57261,57328,57395,57462,57529,57595,57662,
+ 57728,57795,57861,57927,57993,58059,58125,58191,
+ 58256,58322,58387,58453,58518,58583,58648,58713,
+ 58778,58843,58908,58972,59037,59101,59165,59230,
+ 59294,59358,59422,59486,59549,59613,59677,59740,
+ 59804,59867,59930,59993,60056,60119,60182,60245,
+ 60308,60370,60433,60495,60558,60620,60682,60744,
+ 60806,60868,60930,60992,61054,61115,61177,61238,
+ 61300,61361,61422,61483,61544,61605,61666,61727,
+ 61788,61848,61909,61969,62030,62090,62150,62211,
+ 62271,62331,62391,62450,62510,62570,62630,62689,
+ 62749,62808,62867,62927,62986,63045,63104,63163,
+ 63222,63281,63340,63398,63457,63515,63574,63632,
+ 63691,63749,63807,63865,63923,63981,64039,64097,
+ 64155,64212,64270,64328,64385,64443,64500,64557,
+ 64614,64672,64729,64786,64843,64900,64956,65013,
+ 65070,65126,65183,65239,65296,65352,65409,65465
+};
+
+const png_byte png_sRGB_delta[512] =
+{
+ 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54,
+ 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36,
+ 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28,
+ 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24,
+ 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21,
+ 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19,
+ 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,
+ 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,
+ 16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14,
+ 14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13,
+ 13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,
+ 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
+ 12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11,
+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
+ 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
+ 10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
+};
+#endif /* SIMPLIFIED READ/WRITE sRGB support */
+
+/* SIMPLIFIED READ/WRITE SUPPORT */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+static int
+png_image_free_function(png_voidp argument)
+{
+ png_imagep image = png_voidcast(png_imagep, argument);
+ png_controlp cp = image->opaque;
+ png_control c;
+
+ /* Double check that we have a png_ptr - it should be impossible to get here
+ * without one.
+ */
+ if (cp->png_ptr == NULL)
+ return 0;
+
+ /* First free any data held in the control structure. */
+# ifdef PNG_STDIO_SUPPORTED
+ if (cp->owned_file != 0)
+ {
+ FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr);
+ cp->owned_file = 0;
+
+ /* Ignore errors here. */
+ if (fp != NULL)
+ {
+ cp->png_ptr->io_ptr = NULL;
+ (void)fclose(fp);
+ }
+ }
+# endif
+
+ /* Copy the control structure so that the original, allocated, version can be
+ * safely freed. Notice that a png_error here stops the remainder of the
+ * cleanup, but this is probably fine because that would indicate bad memory
+ * problems anyway.
+ */
+ c = *cp;
+ image->opaque = &c;
+ png_free(c.png_ptr, cp);
+
+ /* Then the structures, calling the correct API. */
+ if (c.for_write != 0)
+ {
+# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
+ png_destroy_write_struct(&c.png_ptr, &c.info_ptr);
+# else
+ png_error(c.png_ptr, "simplified write not supported");
+# endif
+ }
+ else
+ {
+# ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+ png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL);
+# else
+ png_error(c.png_ptr, "simplified read not supported");
+# endif
+ }
+
+ /* Success. */
+ return 1;
+}
+
+void PNGAPI
+png_image_free(png_imagep image)
+{
+ /* Safely call the real function, but only if doing so is safe at this point
+ * (if not inside an error handling context). Otherwise assume
+ * png_safe_execute will call this API after the return.
+ */
+ if (image != NULL && image->opaque != NULL &&
+ image->opaque->error_buf == NULL)
+ {
+ /* Ignore errors here: */
+ (void)png_safe_execute(image, png_image_free_function, image);
+ image->opaque = NULL;
+ }
+}
+
+int /* PRIVATE */
+png_image_error(png_imagep image, png_const_charp error_message)
+{
+ /* Utility to log an error. */
+ png_safecat(image->message, (sizeof image->message), 0, error_message);
+ image->warning_or_error |= PNG_IMAGE_ERROR;
+ png_image_free(image);
+ return 0;
+}
+
+#endif /* SIMPLIFIED READ/WRITE */
+#endif /* READ || WRITE */
diff --git a/xs/src/png/libpng/png.h b/xs/src/png/libpng/png.h
new file mode 100644
index 000000000..4c873f5c2
--- /dev/null
+++ b/xs/src/png/libpng/png.h
@@ -0,0 +1,3278 @@
+
+/* png.h - header file for PNG reference library
+ *
+ * libpng version 1.6.34, September 29, 2017
+ *
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license (See LICENSE, below)
+ *
+ * Authors and maintainers:
+ * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
+ * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
+ * libpng versions 0.97, January 1998, through 1.6.34, September 29, 2017:
+ * Glenn Randers-Pehrson.
+ * See also "Contributing Authors", below.
+ */
+
+/*
+ * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ *
+ * If you modify libpng you may insert additional notices immediately following
+ * this sentence.
+ *
+ * This code is released under the libpng license.
+ *
+ * libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are
+ * Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
+ * derived from libpng-1.0.6, and are distributed according to the same
+ * disclaimer and license as libpng-1.0.6 with the following individuals
+ * added to the list of Contributing Authors:
+ *
+ * Simon-Pierre Cadieux
+ * Eric S. Raymond
+ * Mans Rullgard
+ * Cosmin Truta
+ * Gilles Vollant
+ * James Yu
+ * Mandar Sahastrabuddhe
+ * Google Inc.
+ * Vadim Barkov
+ *
+ * and with the following additions to the disclaimer:
+ *
+ * There is no warranty against interference with your enjoyment of the
+ * library or against infringement. There is no warranty that our
+ * efforts or the library will fulfill any of your particular purposes
+ * or needs. This library is provided with all faults, and the entire
+ * risk of satisfactory quality, performance, accuracy, and effort is with
+ * the user.
+ *
+ * Some files in the "contrib" directory and some configure-generated
+ * files that are distributed with libpng have other copyright owners and
+ * are released under other open source licenses.
+ *
+ * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+ * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
+ * libpng-0.96, and are distributed according to the same disclaimer and
+ * license as libpng-0.96, with the following individuals added to the list
+ * of Contributing Authors:
+ *
+ * Tom Lane
+ * Glenn Randers-Pehrson
+ * Willem van Schaik
+ *
+ * libpng versions 0.89, June 1996, through 0.96, May 1997, are
+ * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
+ * and are distributed according to the same disclaimer and license as
+ * libpng-0.88, with the following individuals added to the list of
+ * Contributing Authors:
+ *
+ * John Bowler
+ * Kevin Bracey
+ * Sam Bushell
+ * Magnus Holmgren
+ * Greg Roelofs
+ * Tom Tanner
+ *
+ * Some files in the "scripts" directory have other copyright owners
+ * but are released under this license.
+ *
+ * libpng versions 0.5, May 1995, through 0.88, January 1996, are
+ * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+ *
+ * For the purposes of this copyright and license, "Contributing Authors"
+ * is defined as the following set of individuals:
+ *
+ * Andreas Dilger
+ * Dave Martindale
+ * Guy Eric Schalnat
+ * Paul Schmidt
+ * Tim Wegner
+ *
+ * The PNG Reference Library is supplied "AS IS". The Contributing Authors
+ * and Group 42, Inc. disclaim all warranties, expressed or implied,
+ * including, without limitation, the warranties of merchantability and of
+ * fitness for any purpose. The Contributing Authors and Group 42, Inc.
+ * assume no liability for direct, indirect, incidental, special, exemplary,
+ * or consequential damages, which may result from the use of the PNG
+ * Reference Library, even if advised of the possibility of such damage.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute this
+ * source code, or portions hereof, for any purpose, without fee, subject
+ * to the following restrictions:
+ *
+ * 1. The origin of this source code must not be misrepresented.
+ *
+ * 2. Altered versions must be plainly marked as such and must not
+ * be misrepresented as being the original source.
+ *
+ * 3. This Copyright notice may not be removed or altered from any
+ * source or altered source distribution.
+ *
+ * The Contributing Authors and Group 42, Inc. specifically permit, without
+ * fee, and encourage the use of this source code as a component to
+ * supporting the PNG file format in commercial products. If you use this
+ * source code in a product, acknowledgment is not required but would be
+ * appreciated.
+ *
+ * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
+ *
+ * TRADEMARK:
+ *
+ * The name "libpng" has not been registered by the Copyright owner
+ * as a trademark in any jurisdiction. However, because libpng has
+ * been distributed and maintained world-wide, continually since 1995,
+ * the Copyright owner claims "common-law trademark protection" in any
+ * jurisdiction where common-law trademark is recognized.
+ *
+ * OSI CERTIFICATION:
+ *
+ * Libpng is OSI Certified Open Source Software. OSI Certified Open Source is
+ * a certification mark of the Open Source Initiative. OSI has not addressed
+ * the additional disclaimers inserted at version 1.0.7.
+ *
+ * EXPORT CONTROL:
+ *
+ * The Copyright owner believes that the Export Control Classification
+ * Number (ECCN) for libpng is EAR99, which means not subject to export
+ * controls or International Traffic in Arms Regulations (ITAR) because
+ * it is open source, publicly available software, that does not contain
+ * any encryption software. See the EAR, paragraphs 734.3(b)(3) and
+ * 734.7(b).
+ */
+
+/*
+ * A "png_get_copyright" function is available, for convenient use in "about"
+ * boxes and the like:
+ *
+ * printf("%s", png_get_copyright(NULL));
+ *
+ * Also, the PNG logo (in PNG format, of course) is supplied in the
+ * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+ */
+
+/*
+ * The contributing authors would like to thank all those who helped
+ * with testing, bug fixes, and patience. This wouldn't have been
+ * possible without all of you.
+ *
+ * Thanks to Frank J. T. Wojcik for helping with the documentation.
+ */
+
+/* Note about libpng version numbers:
+ *
+ * Due to various miscommunications, unforeseen code incompatibilities
+ * and occasional factors outside the authors' control, version numbering
+ * on the library has not always been consistent and straightforward.
+ * The following table summarizes matters since version 0.89c, which was
+ * the first widely used release:
+ *
+ * source png.h png.h shared-lib
+ * version string int version
+ * ------- ------ ----- ----------
+ * 0.89c "1.0 beta 3" 0.89 89 1.0.89
+ * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90]
+ * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95]
+ * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96]
+ * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97]
+ * 0.97c 0.97 97 2.0.97
+ * 0.98 0.98 98 2.0.98
+ * 0.99 0.99 98 2.0.99
+ * 0.99a-m 0.99 99 2.0.99
+ * 1.00 1.00 100 2.1.0 [100 should be 10000]
+ * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000]
+ * 1.0.1 png.h string is 10001 2.1.0
+ * 1.0.1a-e identical to the 10002 from here on, the shared library
+ * 1.0.2 source version) 10002 is 2.V where V is the source code
+ * 1.0.2a-b 10003 version, except as noted.
+ * 1.0.3 10003
+ * 1.0.3a-d 10004
+ * 1.0.4 10004
+ * 1.0.4a-f 10005
+ * 1.0.5 (+ 2 patches) 10005
+ * 1.0.5a-d 10006
+ * 1.0.5e-r 10100 (not source compatible)
+ * 1.0.5s-v 10006 (not binary compatible)
+ * 1.0.6 (+ 3 patches) 10006 (still binary incompatible)
+ * 1.0.6d-f 10007 (still binary incompatible)
+ * 1.0.6g 10007
+ * 1.0.6h 10007 10.6h (testing xy.z so-numbering)
+ * 1.0.6i 10007 10.6i
+ * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0)
+ * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible)
+ * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible)
+ * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible)
+ * 1.0.7 1 10007 (still compatible)
+ * ...
+ * 1.0.19 10 10019 10.so.0.19[.0]
+ * ...
+ * 1.2.59 13 10257 12.so.0.59[.0]
+ * ...
+ * 1.5.30 15 10527 15.so.15.30[.0]
+ * ...
+ * 1.6.34 16 10633 16.so.16.34[.0]
+ *
+ * Henceforth the source version will match the shared-library major
+ * and minor numbers; the shared-library major version number will be
+ * used for changes in backward compatibility, as it is intended. The
+ * PNG_LIBPNG_VER macro, which is not used within libpng but is available
+ * for applications, is an unsigned integer of the form xyyzz corresponding
+ * to the source version x.y.z (leading zeros in y and z). Beta versions
+ * were given the previous public release number plus a letter, until
+ * version 1.0.6j; from then on they were given the upcoming public
+ * release number plus "betaNN" or "rcNN".
+ *
+ * Binary incompatibility exists only when applications make direct access
+ * to the info_ptr or png_ptr members through png.h, and the compiled
+ * application is loaded with a different version of the library.
+ *
+ * DLLNUM will change each time there are forward or backward changes
+ * in binary compatibility (e.g., when a new feature is added).
+ *
+ * See libpng.txt or libpng.3 for more information. The PNG specification
+ * is available as a W3C Recommendation and as an ISO Specification,
+ * <https://www.w3.org/TR/2003/REC-PNG-20031110/
+ */
+
+/*
+ * Y2K compliance in libpng:
+ * =========================
+ *
+ * September 29, 2017
+ *
+ * Since the PNG Development group is an ad-hoc body, we can't make
+ * an official declaration.
+ *
+ * This is your unofficial assurance that libpng from version 0.71 and
+ * upward through 1.6.34 are Y2K compliant. It is my belief that
+ * earlier versions were also Y2K compliant.
+ *
+ * Libpng only has two year fields. One is a 2-byte unsigned integer
+ * that will hold years up to 65535. The other, which is deprecated,
+ * holds the date in text format, and will hold years up to 9999.
+ *
+ * The integer is
+ * "png_uint_16 year" in png_time_struct.
+ *
+ * The string is
+ * "char time_buffer[29]" in png_struct. This is no longer used
+ * in libpng-1.6.x and will be removed from libpng-1.7.0.
+ *
+ * There are seven time-related functions:
+ * png.c: png_convert_to_rfc_1123_buffer() in png.c
+ * (formerly png_convert_to_rfc_1123() prior to libpng-1.5.x and
+ * png_convert_to_rfc_1152() in error prior to libpng-0.98)
+ * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+ * png_convert_from_time_t() in pngwrite.c
+ * png_get_tIME() in pngget.c
+ * png_handle_tIME() in pngrutil.c, called in pngread.c
+ * png_set_tIME() in pngset.c
+ * png_write_tIME() in pngwutil.c, called in pngwrite.c
+ *
+ * All handle dates properly in a Y2K environment. The
+ * png_convert_from_time_t() function calls gmtime() to convert from system
+ * clock time, which returns (year - 1900), which we properly convert to
+ * the full 4-digit year. There is a possibility that libpng applications
+ * are not passing 4-digit years into the png_convert_to_rfc_1123_buffer()
+ * function, or that they are incorrectly passing only a 2-digit year
+ * instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ * but this is not under our control. The libpng documentation has always
+ * stated that it works with 4-digit years, and the APIs have been
+ * documented as such.
+ *
+ * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
+ * integer to hold the year, and can hold years as large as 65535.
+ *
+ * zlib, upon which libpng depends, is also Y2K compliant. It contains
+ * no date-related code.
+ *
+ * Glenn Randers-Pehrson
+ * libpng maintainer
+ * PNG Development Group
+ */
+
+#ifndef PNG_H
+#define PNG_H
+
+/* This is not the place to learn how to use libpng. The file libpng-manual.txt
+ * describes how to use libpng, and the file example.c summarizes it
+ * with some code on which to build. This file is useful for looking
+ * at the actual function definitions and structure components. If that
+ * file has been stripped from your copy of libpng, you can find it at
+ * <http://www.libpng.org/pub/png/libpng-manual.txt>
+ *
+ * If you just need to read a PNG file and don't want to read the documentation
+ * skip to the end of this file and read the section entitled 'simplified API'.
+ */
+
+/* Version information for png.h - this should match the version in png.c */
+#define PNG_LIBPNG_VER_STRING "1.6.34"
+#define PNG_HEADER_VERSION_STRING " libpng version 1.6.34 - September 29, 2017\n"
+
+#define PNG_LIBPNG_VER_SONUM 16
+#define PNG_LIBPNG_VER_DLLNUM 16
+
+/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
+#define PNG_LIBPNG_VER_MAJOR 1
+#define PNG_LIBPNG_VER_MINOR 6
+#define PNG_LIBPNG_VER_RELEASE 34
+
+/* This should match the numeric part of the final component of
+ * PNG_LIBPNG_VER_STRING, omitting any leading zero:
+ */
+
+#define PNG_LIBPNG_VER_BUILD 0
+
+/* Release Status */
+#define PNG_LIBPNG_BUILD_ALPHA 1
+#define PNG_LIBPNG_BUILD_BETA 2
+#define PNG_LIBPNG_BUILD_RC 3
+#define PNG_LIBPNG_BUILD_STABLE 4
+#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
+
+/* Release-Specific Flags */
+#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with
+ PNG_LIBPNG_BUILD_STABLE only */
+#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
+ PNG_LIBPNG_BUILD_SPECIAL */
+#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
+ PNG_LIBPNG_BUILD_PRIVATE */
+
+#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
+
+/* Careful here. At one time, Guy wanted to use 082, but that would be octal.
+ * We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
+ * version 1.0.0 was mis-numbered 100 instead of 10000). From
+ * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release
+ */
+#define PNG_LIBPNG_VER 10634 /* 1.6.34 */
+
+/* Library configuration: these options cannot be changed after
+ * the library has been built.
+ */
+#ifndef PNGLCONF_H
+/* If pnglibconf.h is missing, you can
+ * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
+ */
+# include "pnglibconf.h"
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* Machine specific configuration. */
+# include "pngconf.h"
+#endif
+
+/*
+ * Added at libpng-1.2.8
+ *
+ * Ref MSDN: Private as priority over Special
+ * VS_FF_PRIVATEBUILD File *was not* built using standard release
+ * procedures. If this value is given, the StringFileInfo block must
+ * contain a PrivateBuild string.
+ *
+ * VS_FF_SPECIALBUILD File *was* built by the original company using
+ * standard release procedures but is a variation of the standard
+ * file of the same version number. If this value is given, the
+ * StringFileInfo block must contain a SpecialBuild string.
+ */
+
+#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */
+# define PNG_LIBPNG_BUILD_TYPE \
+ (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
+#else
+# ifdef PNG_LIBPNG_SPECIALBUILD
+# define PNG_LIBPNG_BUILD_TYPE \
+ (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
+# else
+# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
+# endif
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Version information for C files, stored in png.c. This had better match
+ * the version above.
+ */
+#define png_libpng_ver png_get_header_ver(NULL)
+
+/* This file is arranged in several sections:
+ *
+ * 1. [omitted]
+ * 2. Any configuration options that can be specified by for the application
+ * code when it is built. (Build time configuration is in pnglibconf.h)
+ * 3. Type definitions (base types are defined in pngconf.h), structure
+ * definitions.
+ * 4. Exported library functions.
+ * 5. Simplified API.
+ * 6. Implementation options.
+ *
+ * The library source code has additional files (principally pngpriv.h) that
+ * allow configuration of the library.
+ */
+
+/* Section 1: [omitted] */
+
+/* Section 2: run time configuration
+ * See pnglibconf.h for build time configuration
+ *
+ * Run time configuration allows the application to choose between
+ * implementations of certain arithmetic APIs. The default is set
+ * at build time and recorded in pnglibconf.h, but it is safe to
+ * override these (and only these) settings. Note that this won't
+ * change what the library does, only application code, and the
+ * settings can (and probably should) be made on a per-file basis
+ * by setting the #defines before including png.h
+ *
+ * Use macros to read integers from PNG data or use the exported
+ * functions?
+ * PNG_USE_READ_MACROS: use the macros (see below) Note that
+ * the macros evaluate their argument multiple times.
+ * PNG_NO_USE_READ_MACROS: call the relevant library function.
+ *
+ * Use the alternative algorithm for compositing alpha samples that
+ * does not use division?
+ * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division'
+ * algorithm.
+ * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm.
+ *
+ * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is
+ * false?
+ * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error
+ * APIs to png_warning.
+ * Otherwise the calls are mapped to png_error.
+ */
+
+/* Section 3: type definitions, including structures and compile time
+ * constants.
+ * See pngconf.h for base types that vary by machine/system
+ */
+
+/* This triggers a compiler error in png.c, if png.c and png.h
+ * do not agree upon the version number.
+ */
+typedef char* png_libpng_version_1_6_34;
+
+/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
+ *
+ * png_struct is the cache of information used while reading or writing a single
+ * PNG file. One of these is always required, although the simplified API
+ * (below) hides the creation and destruction of it.
+ */
+typedef struct png_struct_def png_struct;
+typedef const png_struct * png_const_structp;
+typedef png_struct * png_structp;
+typedef png_struct * * png_structpp;
+
+/* png_info contains information read from or to be written to a PNG file. One
+ * or more of these must exist while reading or creating a PNG file. The
+ * information is not used by libpng during read but is used to control what
+ * gets written when a PNG file is created. "png_get_" function calls read
+ * information during read and "png_set_" functions calls write information
+ * when creating a PNG.
+ * been moved into a separate header file that is not accessible to
+ * applications. Read libpng-manual.txt or libpng.3 for more info.
+ */
+typedef struct png_info_def png_info;
+typedef png_info * png_infop;
+typedef const png_info * png_const_infop;
+typedef png_info * * png_infopp;
+
+/* Types with names ending 'p' are pointer types. The corresponding types with
+ * names ending 'rp' are identical pointer types except that the pointer is
+ * marked 'restrict', which means that it is the only pointer to the object
+ * passed to the function. Applications should not use the 'restrict' types;
+ * it is always valid to pass 'p' to a pointer with a function argument of the
+ * corresponding 'rp' type. Different compilers have different rules with
+ * regard to type matching in the presence of 'restrict'. For backward
+ * compatibility libpng callbacks never have 'restrict' in their parameters and,
+ * consequentially, writing portable application code is extremely difficult if
+ * an attempt is made to use 'restrict'.
+ */
+typedef png_struct * PNG_RESTRICT png_structrp;
+typedef const png_struct * PNG_RESTRICT png_const_structrp;
+typedef png_info * PNG_RESTRICT png_inforp;
+typedef const png_info * PNG_RESTRICT png_const_inforp;
+
+/* Three color definitions. The order of the red, green, and blue, (and the
+ * exact size) is not important, although the size of the fields need to
+ * be png_byte or png_uint_16 (as defined below).
+ */
+typedef struct png_color_struct
+{
+ png_byte red;
+ png_byte green;
+ png_byte blue;
+} png_color;
+typedef png_color * png_colorp;
+typedef const png_color * png_const_colorp;
+typedef png_color * * png_colorpp;
+
+typedef struct png_color_16_struct
+{
+ png_byte index; /* used for palette files */
+ png_uint_16 red; /* for use in red green blue files */
+ png_uint_16 green;
+ png_uint_16 blue;
+ png_uint_16 gray; /* for use in grayscale files */
+} png_color_16;
+typedef png_color_16 * png_color_16p;
+typedef const png_color_16 * png_const_color_16p;
+typedef png_color_16 * * png_color_16pp;
+
+typedef struct png_color_8_struct
+{
+ png_byte red; /* for use in red green blue files */
+ png_byte green;
+ png_byte blue;
+ png_byte gray; /* for use in grayscale files */
+ png_byte alpha; /* for alpha channel files */
+} png_color_8;
+typedef png_color_8 * png_color_8p;
+typedef const png_color_8 * png_const_color_8p;
+typedef png_color_8 * * png_color_8pp;
+
+/*
+ * The following two structures are used for the in-core representation
+ * of sPLT chunks.
+ */
+typedef struct png_sPLT_entry_struct
+{
+ png_uint_16 red;
+ png_uint_16 green;
+ png_uint_16 blue;
+ png_uint_16 alpha;
+ png_uint_16 frequency;
+} png_sPLT_entry;
+typedef png_sPLT_entry * png_sPLT_entryp;
+typedef const png_sPLT_entry * png_const_sPLT_entryp;
+typedef png_sPLT_entry * * png_sPLT_entrypp;
+
+/* When the depth of the sPLT palette is 8 bits, the color and alpha samples
+ * occupy the LSB of their respective members, and the MSB of each member
+ * is zero-filled. The frequency member always occupies the full 16 bits.
+ */
+
+typedef struct png_sPLT_struct
+{
+ png_charp name; /* palette name */
+ png_byte depth; /* depth of palette samples */
+ png_sPLT_entryp entries; /* palette entries */
+ png_int_32 nentries; /* number of palette entries */
+} png_sPLT_t;
+typedef png_sPLT_t * png_sPLT_tp;
+typedef const png_sPLT_t * png_const_sPLT_tp;
+typedef png_sPLT_t * * png_sPLT_tpp;
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
+ * and whether that contents is compressed or not. The "key" field
+ * points to a regular zero-terminated C string. The "text" fields can be a
+ * regular C string, an empty string, or a NULL pointer.
+ * However, the structure returned by png_get_text() will always contain
+ * the "text" field as a regular zero-terminated C string (possibly
+ * empty), never a NULL pointer, so it can be safely used in printf() and
+ * other string-handling functions. Note that the "itxt_length", "lang", and
+ * "lang_key" members of the structure only exist when the library is built
+ * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by
+ * default without iTXt support. Also note that when iTXt *is* supported,
+ * the "lang" and "lang_key" fields contain NULL pointers when the
+ * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or
+ * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the
+ * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag"
+ * which is always 0 or 1, or its "compression method" which is always 0.
+ */
+typedef struct png_text_struct
+{
+ int compression; /* compression value:
+ -1: tEXt, none
+ 0: zTXt, deflate
+ 1: iTXt, none
+ 2: iTXt, deflate */
+ png_charp key; /* keyword, 1-79 character description of "text" */
+ png_charp text; /* comment, may be an empty string (ie "")
+ or a NULL pointer */
+ png_size_t text_length; /* length of the text string */
+ png_size_t itxt_length; /* length of the itxt string */
+ png_charp lang; /* language code, 0-79 characters
+ or a NULL pointer */
+ png_charp lang_key; /* keyword translated UTF-8 string, 0 or more
+ chars or a NULL pointer */
+} png_text;
+typedef png_text * png_textp;
+typedef const png_text * png_const_textp;
+typedef png_text * * png_textpp;
+#endif
+
+/* Supported compression types for text in PNG files (tEXt, and zTXt).
+ * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
+#define PNG_TEXT_COMPRESSION_NONE_WR -3
+#define PNG_TEXT_COMPRESSION_zTXt_WR -2
+#define PNG_TEXT_COMPRESSION_NONE -1
+#define PNG_TEXT_COMPRESSION_zTXt 0
+#define PNG_ITXT_COMPRESSION_NONE 1
+#define PNG_ITXT_COMPRESSION_zTXt 2
+#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */
+
+/* png_time is a way to hold the time in an machine independent way.
+ * Two conversions are provided, both from time_t and struct tm. There
+ * is no portable way to convert to either of these structures, as far
+ * as I know. If you know of a portable way, send it to me. As a side
+ * note - PNG has always been Year 2000 compliant!
+ */
+typedef struct png_time_struct
+{
+ png_uint_16 year; /* full year, as in, 1995 */
+ png_byte month; /* month of year, 1 - 12 */
+ png_byte day; /* day of month, 1 - 31 */
+ png_byte hour; /* hour of day, 0 - 23 */
+ png_byte minute; /* minute of hour, 0 - 59 */
+ png_byte second; /* second of minute, 0 - 60 (for leap seconds) */
+} png_time;
+typedef png_time * png_timep;
+typedef const png_time * png_const_timep;
+typedef png_time * * png_timepp;
+
+#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) ||\
+ defined(PNG_USER_CHUNKS_SUPPORTED)
+/* png_unknown_chunk is a structure to hold queued chunks for which there is
+ * no specific support. The idea is that we can use this to queue
+ * up private chunks for output even though the library doesn't actually
+ * know about their semantics.
+ *
+ * The data in the structure is set by libpng on read and used on write.
+ */
+typedef struct png_unknown_chunk_t
+{
+ png_byte name[5]; /* Textual chunk name with '\0' terminator */
+ png_byte *data; /* Data, should not be modified on read! */
+ png_size_t size;
+
+ /* On write 'location' must be set using the flag values listed below.
+ * Notice that on read it is set by libpng however the values stored have
+ * more bits set than are listed below. Always treat the value as a
+ * bitmask. On write set only one bit - setting multiple bits may cause the
+ * chunk to be written in multiple places.
+ */
+ png_byte location; /* mode of operation at read time */
+}
+png_unknown_chunk;
+
+typedef png_unknown_chunk * png_unknown_chunkp;
+typedef const png_unknown_chunk * png_const_unknown_chunkp;
+typedef png_unknown_chunk * * png_unknown_chunkpp;
+#endif
+
+/* Flag values for the unknown chunk location byte. */
+#define PNG_HAVE_IHDR 0x01
+#define PNG_HAVE_PLTE 0x02
+#define PNG_AFTER_IDAT 0x08
+
+/* Maximum positive integer used in PNG is (2^31)-1 */
+#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
+#define PNG_UINT_32_MAX ((png_uint_32)(-1))
+#define PNG_SIZE_MAX ((png_size_t)(-1))
+
+/* These are constants for fixed point values encoded in the
+ * PNG specification manner (x100000)
+ */
+#define PNG_FP_1 100000
+#define PNG_FP_HALF 50000
+#define PNG_FP_MAX ((png_fixed_point)0x7fffffffL)
+#define PNG_FP_MIN (-PNG_FP_MAX)
+
+/* These describe the color_type field in png_info. */
+/* color type masks */
+#define PNG_COLOR_MASK_PALETTE 1
+#define PNG_COLOR_MASK_COLOR 2
+#define PNG_COLOR_MASK_ALPHA 4
+
+/* color types. Note that not all combinations are legal */
+#define PNG_COLOR_TYPE_GRAY 0
+#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
+#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
+#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
+#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
+/* aliases */
+#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
+#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA
+
+/* This is for compression type. PNG 1.0-1.2 only define the single type. */
+#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
+#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
+
+/* This is for filter type. PNG 1.0-1.2 only define the single type. */
+#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */
+#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
+#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE
+
+/* These are for the interlacing type. These values should NOT be changed. */
+#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */
+#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */
+#define PNG_INTERLACE_LAST 2 /* Not a valid value */
+
+/* These are for the oFFs chunk. These values should NOT be changed. */
+#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */
+#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */
+#define PNG_OFFSET_LAST 2 /* Not a valid value */
+
+/* These are for the pCAL chunk. These values should NOT be changed. */
+#define PNG_EQUATION_LINEAR 0 /* Linear transformation */
+#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */
+#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */
+#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */
+#define PNG_EQUATION_LAST 4 /* Not a valid value */
+
+/* These are for the sCAL chunk. These values should NOT be changed. */
+#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */
+#define PNG_SCALE_METER 1 /* meters per pixel */
+#define PNG_SCALE_RADIAN 2 /* radians per pixel */
+#define PNG_SCALE_LAST 3 /* Not a valid value */
+
+/* These are for the pHYs chunk. These values should NOT be changed. */
+#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */
+#define PNG_RESOLUTION_METER 1 /* pixels/meter */
+#define PNG_RESOLUTION_LAST 2 /* Not a valid value */
+
+/* These are for the sRGB chunk. These values should NOT be changed. */
+#define PNG_sRGB_INTENT_PERCEPTUAL 0
+#define PNG_sRGB_INTENT_RELATIVE 1
+#define PNG_sRGB_INTENT_SATURATION 2
+#define PNG_sRGB_INTENT_ABSOLUTE 3
+#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */
+
+/* This is for text chunks */
+#define PNG_KEYWORD_MAX_LENGTH 79
+
+/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
+#define PNG_MAX_PALETTE_LENGTH 256
+
+/* These determine if an ancillary chunk's data has been successfully read
+ * from the PNG header, or if the application has filled in the corresponding
+ * data in the info_struct to be written into the output file. The values
+ * of the PNG_INFO_<chunk> defines should NOT be changed.
+ */
+#define PNG_INFO_gAMA 0x0001U
+#define PNG_INFO_sBIT 0x0002U
+#define PNG_INFO_cHRM 0x0004U
+#define PNG_INFO_PLTE 0x0008U
+#define PNG_INFO_tRNS 0x0010U
+#define PNG_INFO_bKGD 0x0020U
+#define PNG_INFO_hIST 0x0040U
+#define PNG_INFO_pHYs 0x0080U
+#define PNG_INFO_oFFs 0x0100U
+#define PNG_INFO_tIME 0x0200U
+#define PNG_INFO_pCAL 0x0400U
+#define PNG_INFO_sRGB 0x0800U /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000U /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000U /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000U /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000U /* ESR, 1.0.6 */
+#define PNG_INFO_eXIf 0x10000U /* GR-P, 1.6.31 */
+
+/* This is used for the transformation routines, as some of them
+ * change these values for the row. It also should enable using
+ * the routines for other purposes.
+ */
+typedef struct png_row_info_struct
+{
+ png_uint_32 width; /* width of row */
+ png_size_t rowbytes; /* number of bytes in row */
+ png_byte color_type; /* color type of row */
+ png_byte bit_depth; /* bit depth of row */
+ png_byte channels; /* number of channels (1, 2, 3, or 4) */
+ png_byte pixel_depth; /* bits per pixel (depth * channels) */
+} png_row_info;
+
+typedef png_row_info * png_row_infop;
+typedef png_row_info * * png_row_infopp;
+
+/* These are the function types for the I/O functions and for the functions
+ * that allow the user to override the default I/O functions with his or her
+ * own. The png_error_ptr type should match that of user-supplied warning
+ * and error functions, while the png_rw_ptr type should match that of the
+ * user read/write data functions. Note that the 'write' function must not
+ * modify the buffer it is passed. The 'read' function, on the other hand, is
+ * expected to return the read data in the buffer.
+ */
+typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp));
+typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t));
+typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp));
+typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,
+ int));
+typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32,
+ int));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
+typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
+
+/* The following callback receives png_uint_32 row_number, int pass for the
+ * png_bytep data of the row. When transforming an interlaced image the
+ * row number is the row number within the sub-image of the interlace pass, so
+ * the value will increase to the height of the sub-image (not the full image)
+ * then reset to 0 for the next pass.
+ *
+ * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
+ * find the output pixel (x,y) given an interlaced sub-image pixel
+ * (row,col,pass). (See below for these macros.)
+ */
+typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep,
+ png_uint_32, int));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop,
+ png_bytep));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp,
+ png_unknown_chunkp));
+#endif
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+/* not used anywhere */
+/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* This must match the function definition in <setjmp.h>, and the application
+ * must include this before png.h to obtain the definition of jmp_buf. The
+ * function is required to be PNG_NORETURN, but this is not checked. If the
+ * function does return the application will crash via an abort() or similar
+ * system level call.
+ *
+ * If you get a warning here while building the library you may need to make
+ * changes to ensure that pnglibconf.h records the calling convention used by
+ * your compiler. This may be very difficult - try using a different compiler
+ * to build the library!
+ */
+PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef);
+#endif
+
+/* Transform masks for the high-level interface */
+#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */
+#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */
+#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */
+#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */
+#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */
+#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */
+#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */
+#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */
+#define PNG_TRANSFORM_BGR 0x0080 /* read and write */
+#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */
+#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */
+#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */
+#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only */
+/* Added to libpng-1.2.34 */
+#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER
+#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */
+/* Added to libpng-1.4.0 */
+#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */
+/* Added to libpng-1.5.4 */
+#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */
+#if INT_MAX >= 0x8000 /* else this might break */
+#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */
+#endif
+
+/* Flags for MNG supported features */
+#define PNG_FLAG_MNG_EMPTY_PLTE 0x01
+#define PNG_FLAG_MNG_FILTER_64 0x04
+#define PNG_ALL_MNG_FEATURES 0x05
+
+/* NOTE: prior to 1.5 these functions had no 'API' style declaration,
+ * this allowed the zlib default functions to be used on Windows
+ * platforms. In 1.5 the zlib default malloc (which just calls malloc and
+ * ignores the first argument) should be completely compatible with the
+ * following.
+ */
+typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp,
+ png_alloc_size_t));
+typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp));
+
+/* Section 4: exported functions
+ * Here are the function definitions most commonly used. This is not
+ * the place to find out how to use libpng. See libpng-manual.txt for the
+ * full explanation, see example.c for the summary. This just provides
+ * a simple one line description of the use of each function.
+ *
+ * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in
+ * pngconf.h and in the *.dfn files in the scripts directory.
+ *
+ * PNG_EXPORT(ordinal, type, name, (args));
+ *
+ * ordinal: ordinal that is used while building
+ * *.def files. The ordinal value is only
+ * relevant when preprocessing png.h with
+ * the *.dfn files for building symbol table
+ * entries, and are removed by pngconf.h.
+ * type: return type of the function
+ * name: function name
+ * args: function arguments, with types
+ *
+ * When we wish to append attributes to a function prototype we use
+ * the PNG_EXPORTA() macro instead.
+ *
+ * PNG_EXPORTA(ordinal, type, name, (args), attributes);
+ *
+ * ordinal, type, name, and args: same as in PNG_EXPORT().
+ * attributes: function attributes
+ */
+
+/* Returns the version number of the library */
+PNG_EXPORT(1, png_uint_32, png_access_version_number, (void));
+
+/* Tell lib we have already handled the first <num_bytes> magic bytes.
+ * Handling more than 8 bytes from the beginning of the file is an error.
+ */
+PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes));
+
+/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
+ * PNG file. Returns zero if the supplied bytes match the 8-byte PNG
+ * signature, and non-zero otherwise. Having num_to_check == 0 or
+ * start > 7 will always fail (ie return non-zero).
+ */
+PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start,
+ png_size_t num_to_check));
+
+/* Simple signature checking function. This is the same as calling
+ * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
+ */
+#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n))
+
+/* Allocate and initialize png_ptr struct for reading, and any other memory. */
+PNG_EXPORTA(4, png_structp, png_create_read_struct,
+ (png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn),
+ PNG_ALLOCATED);
+
+/* Allocate and initialize png_ptr struct for writing, and any other memory */
+PNG_EXPORTA(5, png_structp, png_create_write_struct,
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn),
+ PNG_ALLOCATED);
+
+PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size,
+ (png_const_structrp png_ptr));
+
+PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr,
+ png_size_t size));
+
+/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
+ * match up.
+ */
+#ifdef PNG_SETJMP_SUPPORTED
+/* This function returns the jmp_buf built in to *png_ptr. It must be
+ * supplied with an appropriate 'longjmp' function to use on that jmp_buf
+ * unless the default error function is overridden in which case NULL is
+ * acceptable. The size of the jmp_buf is checked against the actual size
+ * allocated by the library - the call will return NULL on a mismatch
+ * indicating an ABI mismatch.
+ */
+PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr,
+ png_longjmp_ptr longjmp_fn, size_t jmp_buf_size));
+# define png_jmpbuf(png_ptr) \
+ (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf))))
+#else
+# define png_jmpbuf(png_ptr) \
+ (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP)
+#endif
+/* This function should be used by libpng applications in place of
+ * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it
+ * will use it; otherwise it will call PNG_ABORT(). This function was
+ * added in libpng-1.5.0.
+ */
+PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val),
+ PNG_NORETURN);
+
+#ifdef PNG_READ_SUPPORTED
+/* Reset the compression stream */
+PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED);
+#endif
+
+/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
+#ifdef PNG_USER_MEM_SUPPORTED
+PNG_EXPORTA(11, png_structp, png_create_read_struct_2,
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn,
+ png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
+ PNG_ALLOCATED);
+PNG_EXPORTA(12, png_structp, png_create_write_struct_2,
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn,
+ png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
+ PNG_ALLOCATED);
+#endif
+
+/* Write the PNG file signature. */
+PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr));
+
+/* Write a PNG chunk - size, type, (optional) data, CRC. */
+PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep
+ chunk_name, png_const_bytep data, png_size_t length));
+
+/* Write the start of a PNG chunk - length and chunk name. */
+PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr,
+ png_const_bytep chunk_name, png_uint_32 length));
+
+/* Write the data of a PNG chunk started with png_write_chunk_start(). */
+PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr,
+ png_const_bytep data, png_size_t length));
+
+/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
+PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr));
+
+/* Allocate and initialize the info structure */
+PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr),
+ PNG_ALLOCATED);
+
+/* DEPRECATED: this function allowed init structures to be created using the
+ * default allocation method (typically malloc). Use is deprecated in 1.6.0 and
+ * the API will be removed in the future.
+ */
+PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr,
+ png_size_t png_info_struct_size), PNG_DEPRECATED);
+
+/* Writes all the PNG information before the image. */
+PNG_EXPORT(20, void, png_write_info_before_PLTE,
+ (png_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(21, void, png_write_info,
+ (png_structrp png_ptr, png_const_inforp info_ptr));
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data. */
+PNG_EXPORT(22, void, png_read_info,
+ (png_structrp png_ptr, png_inforp info_ptr));
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+ /* Convert to a US string format: there is no localization support in this
+ * routine. The original implementation used a 29 character buffer in
+ * png_struct, this will be removed in future versions.
+ */
+#if PNG_LIBPNG_VER < 10700
+/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */
+PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr,
+ png_const_timep ptime),PNG_DEPRECATED);
+#endif
+PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29],
+ png_const_timep ptime));
+#endif
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+/* Convert from a struct tm to png_time */
+PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime,
+ const struct tm * ttime));
+
+/* Convert from time_t to png_time. Uses gmtime() */
+PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime));
+#endif /* CONVERT_tIME */
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
+PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr));
+PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr));
+PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr));
+PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion
+ * of a tRNS chunk if present.
+ */
+PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Use blue, green, red order for pixels. */
+PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+/* Expand the grayscale to 24-bit RGB if necessary. */
+PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+/* Reduce RGB to grayscale. */
+#define PNG_ERROR_ACTION_NONE 1
+#define PNG_ERROR_ACTION_WARN 2
+#define PNG_ERROR_ACTION_ERROR 3
+#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/
+
+PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr,
+ int error_action, double red, double green))
+PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr,
+ int error_action, png_fixed_point red, png_fixed_point green))
+
+PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp
+ png_ptr));
+#endif
+
+#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
+ png_colorp palette));
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+/* How the alpha channel is interpreted - this affects how the color channels
+ * of a PNG file are returned to the calling application when an alpha channel,
+ * or a tRNS chunk in a palette file, is present.
+ *
+ * This has no effect on the way pixels are written into a PNG output
+ * datastream. The color samples in a PNG datastream are never premultiplied
+ * with the alpha samples.
+ *
+ * The default is to return data according to the PNG specification: the alpha
+ * channel is a linear measure of the contribution of the pixel to the
+ * corresponding composited pixel, and the color channels are unassociated
+ * (not premultiplied). The gamma encoded color channels must be scaled
+ * according to the contribution and to do this it is necessary to undo
+ * the encoding, scale the color values, perform the composition and reencode
+ * the values. This is the 'PNG' mode.
+ *
+ * The alternative is to 'associate' the alpha with the color information by
+ * storing color channel values that have been scaled by the alpha.
+ * image. These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
+ * (the latter being the two common names for associated alpha color channels).
+ *
+ * For the 'OPTIMIZED' mode, a pixel is treated as opaque only if the alpha
+ * value is equal to the maximum value.
+ *
+ * The final choice is to gamma encode the alpha channel as well. This is
+ * broken because, in practice, no implementation that uses this choice
+ * correctly undoes the encoding before handling alpha composition. Use this
+ * choice only if other serious errors in the software or hardware you use
+ * mandate it; the typical serious error is for dark halos to appear around
+ * opaque areas of the composited PNG image because of arithmetic overflow.
+ *
+ * The API function png_set_alpha_mode specifies which of these choices to use
+ * with an enumerated 'mode' value and the gamma of the required output:
+ */
+#define PNG_ALPHA_PNG 0 /* according to the PNG standard */
+#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */
+#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */
+#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */
+#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */
+#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */
+
+PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode,
+ double output_gamma))
+PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
+ int mode, png_fixed_point output_gamma))
+#endif
+
+#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+/* The output_gamma value is a screen gamma in libpng terminology: it expresses
+ * how to decode the output values, not how they are encoded.
+ */
+#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */
+#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */
+#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */
+#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */
+#endif
+
+/* The following are examples of calls to png_set_alpha_mode to achieve the
+ * required overall gamma correction and, where necessary, alpha
+ * premultiplication.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+ * This is the default libpng handling of the alpha channel - it is not
+ * pre-multiplied into the color components. In addition the call states
+ * that the output is for a sRGB system and causes all PNG files without gAMA
+ * chunks to be assumed to be encoded using sRGB.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+ * In this case the output is assumed to be something like an sRGB conformant
+ * display preceeded by a power-law lookup table of power 1.45. This is how
+ * early Mac systems behaved.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
+ * This is the classic Jim Blinn approach and will work in academic
+ * environments where everything is done by the book. It has the shortcoming
+ * of assuming that input PNG data with no gamma information is linear - this
+ * is unlikely to be correct unless the PNG files where generated locally.
+ * Most of the time the output precision will be so low as to show
+ * significant banding in dark areas of the image.
+ *
+ * png_set_expand_16(pp);
+ * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);
+ * This is a somewhat more realistic Jim Blinn inspired approach. PNG files
+ * are assumed to have the sRGB encoding if not marked with a gamma value and
+ * the output is always 16 bits per component. This permits accurate scaling
+ * and processing of the data. If you know that your input PNG files were
+ * generated locally you might need to replace PNG_DEFAULT_sRGB with the
+ * correct value for your system.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
+ * If you just need to composite the PNG image onto an existing background
+ * and if you control the code that does this you can use the optimization
+ * setting. In this case you just copy completely opaque pixels to the
+ * output. For pixels that are not completely transparent (you just skip
+ * those) you do the composition math using png_composite or png_composite_16
+ * below then encode the resultant 8-bit or 16-bit values to match the output
+ * encoding.
+ *
+ * Other cases
+ * If neither the PNG nor the standard linear encoding work for you because
+ * of the software or hardware you use then you have a big problem. The PNG
+ * case will probably result in halos around the image. The linear encoding
+ * will probably result in a washed out, too bright, image (it's actually too
+ * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably
+ * substantially reduce the halos. Alternatively try:
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);
+ * This option will also reduce the halos, but there will be slight dark
+ * halos round the opaque parts of the image where the background is light.
+ * In the OPTIMIZED mode the halos will be light halos where the background
+ * is dark. Take your pick - the halos are unavoidable unless you can get
+ * your hardware/software fixed! (The OPTIMIZED approach is slightly
+ * faster.)
+ *
+ * When the default gamma of PNG files doesn't match the output gamma.
+ * If you have PNG files with no gamma information png_set_alpha_mode allows
+ * you to provide a default gamma, but it also sets the ouput gamma to the
+ * matching value. If you know your PNG files have a gamma that doesn't
+ * match the output you can take advantage of the fact that
+ * png_set_alpha_mode always sets the output gamma but only sets the PNG
+ * default if it is not already set:
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+ * The first call sets both the default and the output gamma values, the
+ * second call overrides the output gamma without changing the default. This
+ * is easier than achieving the same effect with png_set_gamma. You must use
+ * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
+ * fire if more than one call to png_set_alpha_mode and png_set_background is
+ * made in the same read operation, however multiple calls with PNG_ALPHA_PNG
+ * are ignored.
+ */
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */
+PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler,
+ int flags));
+/* The values of the PNG_FILLER_ defines should NOT be changed */
+# define PNG_FILLER_BEFORE 0
+# define PNG_FILLER_AFTER 1
+/* Add an alpha byte to 8-bit or 16-bit Gray or 24-bit or 48-bit RGB images. */
+PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr,
+ png_uint_32 filler, int flags));
+#endif /* READ_FILLER || WRITE_FILLER */
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swap bytes in 16-bit depth files. */
+PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
+PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
+ defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Swap packing order of pixels in bytes. */
+PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Converts files to legal bit depths. */
+PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p
+ true_bits));
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Have the code handle the interlacing. Returns the number of passes.
+ * MUST be called before png_read_update_info or png_start_read_image,
+ * otherwise it will not have the desired effect. Note that it is still
+ * necessary to call png_read_row or png_read_rows png_get_image_height
+ * times for each pass.
+*/
+PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+/* Invert monochrome files */
+PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+/* Handle alpha and tRNS by replacing with a background color. Prior to
+ * libpng-1.5.4 this API must not be called before the PNG file header has been
+ * read. Doing so will result in unexpected behavior and possible warnings or
+ * errors if the PNG file contains a bKGD chunk.
+ */
+PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr,
+ png_const_color_16p background_color, int background_gamma_code,
+ int need_expand, double background_gamma))
+PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr,
+ png_const_color_16p background_color, int background_gamma_code,
+ int need_expand, png_fixed_point background_gamma))
+#endif
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+# define PNG_BACKGROUND_GAMMA_UNKNOWN 0
+# define PNG_BACKGROUND_GAMMA_SCREEN 1
+# define PNG_BACKGROUND_GAMMA_FILE 2
+# define PNG_BACKGROUND_GAMMA_UNIQUE 3
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+/* Scale a 16-bit depth file down to 8-bit, accurately. */
+PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+#define PNG_READ_16_TO_8_SUPPORTED /* Name prior to 1.5.4 */
+/* Strip the second byte of information from a 16-bit depth file. */
+PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+/* Turn on quantizing, and reduce the palette to the number of colors
+ * available.
+ */
+PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr,
+ png_colorp palette, int num_palette, int maximum_colors,
+ png_const_uint_16p histogram, int full_quantize));
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* The threshold on gamma processing is configurable but hard-wired into the
+ * library. The following is the floating point variant.
+ */
+#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001)
+
+/* Handle gamma correction. Screen_gamma=(display_exponent).
+ * NOTE: this API simply sets the screen and file gamma values. It will
+ * therefore override the value for gamma in a PNG file if it is called after
+ * the file header has been read - use with care - call before reading the PNG
+ * file for best results!
+ *
+ * These routines accept the same gamma values as png_set_alpha_mode (described
+ * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either
+ * API (floating point or fixed.) Notice, however, that the 'file_gamma' value
+ * is the inverse of a 'screen gamma' value.
+ */
+PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr,
+ double screen_gamma, double override_file_gamma))
+PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr,
+ png_fixed_point screen_gamma, png_fixed_point override_file_gamma))
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+/* Set how many lines between output flushes - 0 for no flushing */
+PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows));
+/* Flush the current PNG output buffer */
+PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr));
+#endif
+
+/* Optional update palette with requested transformations */
+PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr));
+
+/* Optional call to update the users info structure */
+PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr,
+ png_inforp info_ptr));
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data. */
+PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row,
+ png_bytepp display_row, png_uint_32 num_rows));
+#endif
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read a row of data. */
+PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row,
+ png_bytep display_row));
+#endif
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the whole image into memory at once. */
+PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image));
+#endif
+
+/* Write a row of image data */
+PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr,
+ png_const_bytep row));
+
+/* Write a few rows of image data: (*row) is not written; however, the type
+ * is declared as writeable to maintain compatibility with previous versions
+ * of libpng and to allow the 'display_row' array from read_rows to be passed
+ * unchanged to write_rows.
+ */
+PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row,
+ png_uint_32 num_rows));
+
+/* Write the image data */
+PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image));
+
+/* Write the end of the PNG file. */
+PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr,
+ png_inforp info_ptr));
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file. */
+PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr));
+#endif
+
+/* Free any memory associated with the png_info_struct */
+PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr,
+ png_infopp info_ptr_ptr));
+
+/* Free any memory associated with the png_struct and the png_info_structs */
+PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr,
+ png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
+
+/* Free any memory associated with the png_struct and the png_info_structs */
+PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr,
+ png_infopp info_ptr_ptr));
+
+/* Set the libpng method of handling chunk CRC errors */
+PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action,
+ int ancil_action));
+
+/* Values for png_set_crc_action() say how to handle CRC errors in
+ * ancillary and critical chunks, and whether to use the data contained
+ * therein. Note that it is impossible to "discard" data in a critical
+ * chunk. For versions prior to 0.90, the action was always error/quit,
+ * whereas in version 0.90 and later, the action for CRC errors in ancillary
+ * chunks is warn/discard. These values should NOT be changed.
+ *
+ * value action:critical action:ancillary
+ */
+#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */
+#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */
+#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */
+#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */
+#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */
+#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */
+
+#ifdef PNG_WRITE_SUPPORTED
+/* These functions give the user control over the scan-line filtering in
+ * libpng and the compression methods used by zlib. These functions are
+ * mainly useful for testing, as the defaults should work with most users.
+ * Those users who are tight on memory or want faster performance at the
+ * expense of compression can modify them. See the compression library
+ * header file (zlib.h) for an explination of the compression functions.
+ */
+
+/* Set the filtering method(s) used by libpng. Currently, the only valid
+ * value for "method" is 0.
+ */
+PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,
+ int filters));
+#endif /* WRITE */
+
+/* Flags for png_set_filter() to say which filters to use. The flags
+ * are chosen so that they don't conflict with real filter types
+ * below, in case they are supplied instead of the #defined constants.
+ * These values should NOT be changed.
+ */
+#define PNG_NO_FILTERS 0x00
+#define PNG_FILTER_NONE 0x08
+#define PNG_FILTER_SUB 0x10
+#define PNG_FILTER_UP 0x20
+#define PNG_FILTER_AVG 0x40
+#define PNG_FILTER_PAETH 0x80
+#define PNG_FAST_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP)
+#define PNG_ALL_FILTERS (PNG_FAST_FILTERS | PNG_FILTER_AVG | PNG_FILTER_PAETH)
+
+/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
+ * These defines should NOT be changed.
+ */
+#define PNG_FILTER_VALUE_NONE 0
+#define PNG_FILTER_VALUE_SUB 1
+#define PNG_FILTER_VALUE_UP 2
+#define PNG_FILTER_VALUE_AVG 3
+#define PNG_FILTER_VALUE_PAETH 4
+#define PNG_FILTER_VALUE_LAST 5
+
+#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */
+PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr,
+ int heuristic_method, int num_weights, png_const_doublep filter_weights,
+ png_const_doublep filter_costs))
+PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed,
+ (png_structrp png_ptr, int heuristic_method, int num_weights,
+ png_const_fixed_point_p filter_weights,
+ png_const_fixed_point_p filter_costs))
+#endif /* WRITE_WEIGHTED_FILTER */
+
+/* The following are no longer used and will be removed from libpng-1.7: */
+#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */
+#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */
+#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */
+#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */
+
+/* Set the library compression level. Currently, valid values range from
+ * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
+ * (0 - no compression, 9 - "maximal" compression). Note that tests have
+ * shown that zlib compression levels 3-6 usually perform as well as level 9
+ * for PNG images, and do considerably fewer caclulations. In the future,
+ * these values may not correspond directly to the zlib compression levels.
+ */
+#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
+PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr,
+ int level));
+
+PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr,
+ int mem_level));
+
+PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr,
+ int strategy));
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr,
+ int window_bits));
+
+PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr,
+ int method));
+#endif /* WRITE_CUSTOMIZE_COMPRESSION */
+
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+/* Also set zlib parameters for compressing non-IDAT chunks */
+PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr,
+ int level));
+
+PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr,
+ int mem_level));
+
+PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr,
+ int strategy));
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+PNG_EXPORT(225, void, png_set_text_compression_window_bits,
+ (png_structrp png_ptr, int window_bits));
+
+PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,
+ int method));
+#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
+#endif /* WRITE */
+
+/* These next functions are called for input/output, memory, and error
+ * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c,
+ * and call standard C I/O routines such as fread(), fwrite(), and
+ * fprintf(). These functions can be made to use other I/O routines
+ * at run time for those applications that need to handle I/O in a
+ * different manner by calling png_set_???_fn(). See libpng-manual.txt for
+ * more information.
+ */
+
+#ifdef PNG_STDIO_SUPPORTED
+/* Initialize the input/output for the PNG file to the default functions. */
+PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp));
+#endif
+
+/* Replace the (error and abort), and warning functions with user
+ * supplied functions. If no messages are to be printed you must still
+ * write and use replacement functions. The replacement error_fn should
+ * still do a longjmp to the last setjmp location if you are using this
+ * method of error handling. If error_fn or warning_fn is NULL, the
+ * default function will be used.
+ */
+
+PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr,
+ png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
+
+/* Return the user pointer associated with the error functions */
+PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr));
+
+/* Replace the default data output functions with a user supplied one(s).
+ * If buffered output is not used, then output_flush_fn can be set to NULL.
+ * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
+ * output_flush_fn will be ignored (and thus can be NULL).
+ * It is probably a mistake to use NULL for output_flush_fn if
+ * write_data_fn is not also NULL unless you have built libpng with
+ * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's
+ * default flush function, which uses the standard *FILE structure, will
+ * be used.
+ */
+PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr,
+ png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
+
+/* Replace the default data input function with a user supplied one. */
+PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr,
+ png_rw_ptr read_data_fn));
+
+/* Return the user pointer associated with the I/O functions */
+PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr));
+
+PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr,
+ png_read_status_ptr read_row_fn));
+
+PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr,
+ png_write_status_ptr write_row_fn));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* Replace the default memory allocation functions with user supplied one(s). */
+PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+/* Return the user pointer associated with the memory functions */
+PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr,
+ png_user_transform_ptr read_user_transform_fn));
+#endif
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr,
+ png_user_transform_ptr write_user_transform_fn));
+#endif
+
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr,
+ png_voidp user_transform_ptr, int user_transform_depth,
+ int user_transform_channels));
+/* Return the user pointer associated with the user transform functions */
+PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr,
+ (png_const_structrp png_ptr));
+#endif
+
+#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
+/* Return information about the row currently being processed. Note that these
+ * APIs do not fail but will return unexpected results if called outside a user
+ * transform callback. Also note that when transforming an interlaced image the
+ * row number is the row number within the sub-image of the interlace pass, so
+ * the value will increase to the height of the sub-image (not the full image)
+ * then reset to 0 for the next pass.
+ *
+ * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
+ * find the output pixel (x,y) given an interlaced sub-image pixel
+ * (row,col,pass). (See below for these macros.)
+ */
+PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp));
+PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp));
+#endif
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+/* This callback is called only for *unknown* chunks. If
+ * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known
+ * chunks to be treated as unknown, however in this case the callback must do
+ * any processing required by the chunk (e.g. by calling the appropriate
+ * png_set_ APIs.)
+ *
+ * There is no write support - on write, by default, all the chunks in the
+ * 'unknown' list are written in the specified position.
+ *
+ * The integer return from the callback function is interpreted thus:
+ *
+ * negative: An error occurred; png_chunk_error will be called.
+ * zero: The chunk was not handled, the chunk will be saved. A critical
+ * chunk will cause an error at this point unless it is to be saved.
+ * positive: The chunk was handled, libpng will ignore/discard it.
+ *
+ * See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about
+ * how this behavior will change in libpng 1.7
+ */
+PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr,
+ png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr));
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+/* Sets the function callbacks for the push reader, and a pointer to a
+ * user-defined structure available to the callback functions.
+ */
+PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr,
+ png_voidp progressive_ptr, png_progressive_info_ptr info_fn,
+ png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn));
+
+/* Returns the user pointer associated with the push read functions */
+PNG_EXPORT(91, png_voidp, png_get_progressive_ptr,
+ (png_const_structrp png_ptr));
+
+/* Function to be called when data becomes available */
+PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
+ png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size));
+
+/* A function which may be called *only* within png_process_data to stop the
+ * processing of any more data. The function returns the number of bytes
+ * remaining, excluding any that libpng has cached internally. A subsequent
+ * call to png_process_data must supply these bytes again. If the argument
+ * 'save' is set to true the routine will first save all the pending data and
+ * will always return 0.
+ */
+PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save));
+
+/* A function which may be called *only* outside (after) a call to
+ * png_process_data. It returns the number of bytes of data to skip in the
+ * input. Normally it will return 0, but if it returns a non-zero value the
+ * application must skip than number of bytes of input data and pass the
+ * following data to the next call to png_process_data.
+ */
+PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp));
+
+/* Function that combines rows. 'new_row' is a flag that should come from
+ * the callback and be non-NULL if anything needs to be done; the library
+ * stores its own version of the new data internally and ignores the passed
+ * in value.
+ */
+PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr,
+ png_bytep old_row, png_const_bytep new_row));
+#endif /* PROGRESSIVE_READ */
+
+PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED);
+/* Added at libpng version 1.4.0 */
+PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED);
+
+/* Added at libpng version 1.2.4 */
+PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED);
+
+/* Frees a pointer allocated by png_malloc() */
+PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr));
+
+/* Free data that was allocated internally */
+PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 free_me, int num));
+
+/* Reassign responsibility for freeing existing data, whether allocated
+ * by libpng or by the application; this works on the png_info structure passed
+ * in, it does not change the state for other png_info structures.
+ *
+ * It is unlikely that this function works correctly as of 1.6.0 and using it
+ * may result either in memory leaks or double free of allocated data.
+ */
+PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int freer, png_uint_32 mask));
+
+/* Assignments for png_data_freer */
+#define PNG_DESTROY_WILL_FREE_DATA 1
+#define PNG_SET_WILL_FREE_DATA 1
+#define PNG_USER_WILL_FREE_DATA 2
+/* Flags for png_ptr->free_me and info_ptr->free_me */
+#define PNG_FREE_HIST 0x0008U
+#define PNG_FREE_ICCP 0x0010U
+#define PNG_FREE_SPLT 0x0020U
+#define PNG_FREE_ROWS 0x0040U
+#define PNG_FREE_PCAL 0x0080U
+#define PNG_FREE_SCAL 0x0100U
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+# define PNG_FREE_UNKN 0x0200U
+#endif
+/* PNG_FREE_LIST 0x0400U removed in 1.6.0 because it is ignored */
+#define PNG_FREE_PLTE 0x1000U
+#define PNG_FREE_TRNS 0x2000U
+#define PNG_FREE_TEXT 0x4000U
+#define PNG_FREE_EXIF 0x8000U /* Added at libpng-1.6.31 */
+#define PNG_FREE_ALL 0xffffU
+#define PNG_FREE_MUL 0x4220U /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+
+#ifdef PNG_USER_MEM_SUPPORTED
+PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED);
+PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr,
+ png_voidp ptr), PNG_DEPRECATED);
+#endif
+
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+/* Fatal error in PNG image of libpng - can't continue */
+PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr,
+ png_const_charp error_message), PNG_NORETURN);
+
+/* The same, but the chunk name is prepended to the error string. */
+PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr,
+ png_const_charp error_message), PNG_NORETURN);
+
+#else
+/* Fatal error in PNG image of libpng - can't continue */
+PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN);
+# define png_error(s1,s2) png_err(s1)
+# define png_chunk_error(s1,s2) png_err(s1)
+#endif
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* Non-fatal error in libpng. Can continue, but may have a problem. */
+PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
+
+/* Non-fatal error in libpng, chunk name is prepended to message. */
+PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
+#else
+# define png_warning(s1,s2) ((void)(s1))
+# define png_chunk_warning(s1,s2) ((void)(s1))
+#endif
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+/* Benign error in libpng. Can continue, but may have a problem.
+ * User can choose whether to handle as a fatal error or as a warning. */
+PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
+
+#ifdef PNG_READ_SUPPORTED
+/* Same, chunk name is prepended to message (only during read) */
+PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
+#endif
+
+PNG_EXPORT(109, void, png_set_benign_errors,
+ (png_structrp png_ptr, int allowed));
+#else
+# ifdef PNG_ALLOW_BENIGN_ERRORS
+# define png_benign_error png_warning
+# define png_chunk_benign_error png_chunk_warning
+# else
+# define png_benign_error png_error
+# define png_chunk_benign_error png_chunk_error
+# endif
+#endif
+
+/* The png_set_<chunk> functions are for storing values in the png_info_struct.
+ * Similarly, the png_get_<chunk> calls are used to read values from the
+ * png_info_struct, either storing the parameters in the passed variables, or
+ * setting pointers into the png_info_struct where the data is stored. The
+ * png_get_<chunk> functions return a non-zero value if the data was available
+ * in info_ptr, or return zero and do not change any of the parameters if the
+ * data was not available.
+ *
+ * These functions should be used instead of directly accessing png_info
+ * to avoid problems with future changes in the size and internal layout of
+ * png_info_struct.
+ */
+/* Returns "flag" if chunk data is valid in info_ptr. */
+PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 flag));
+
+/* Returns number of bytes needed to hold a transformed row. */
+PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+/* Returns row_pointers, which is an array of pointers to scanlines that was
+ * returned from png_read_png().
+ */
+PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Set row_pointers, which is an array of pointers to scanlines for use
+ * by png_write_png().
+ */
+PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_bytepp row_pointers));
+#endif
+
+/* Returns number of color channels in image. */
+PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Returns image width in pixels. */
+PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image height in pixels. */
+PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image bit_depth. */
+PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image color_type. */
+PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image filter_type. */
+PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image interlace_type. */
+PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image compression_type. */
+PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image resolution in pixels per meter, from pHYs chunk data. */
+PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+/* Returns pixel aspect ratio, computed from pHYs chunk data. */
+PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
+PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
+
+/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
+PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(128, png_int_32, png_get_x_offset_microns,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(129, png_int_32, png_get_y_offset_microns,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+#endif /* EASY_ACCESS */
+
+#ifdef PNG_READ_SUPPORTED
+/* Returns pointer to signature string read from PNG header */
+PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_color_16p *background));
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_color_16p background));
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x,
+ double *red_y, double *green_x, double *green_y, double *blue_x,
+ double *blue_y))
+PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z,
+ double *green_X, double *green_Y, double *green_Z, double *blue_X,
+ double *blue_Y, double *blue_Z))
+PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *int_white_x, png_fixed_point *int_white_y,
+ png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+ png_fixed_point *int_green_x, png_fixed_point *int_green_y,
+ png_fixed_point *int_blue_x, png_fixed_point *int_blue_y))
+PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
+ png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
+ png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
+ png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
+ png_fixed_point *int_blue_Z))
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr,
+ png_inforp info_ptr,
+ double white_x, double white_y, double red_x, double red_y, double green_x,
+ double green_y, double blue_x, double blue_y))
+PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr,
+ png_inforp info_ptr, double red_X, double red_Y, double red_Z,
+ double green_X, double green_Y, double green_Z, double blue_X,
+ double blue_Y, double blue_Z))
+PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_fixed_point int_white_x,
+ png_fixed_point int_white_y, png_fixed_point int_red_x,
+ png_fixed_point int_red_y, png_fixed_point int_green_x,
+ png_fixed_point int_green_y, png_fixed_point int_blue_x,
+ png_fixed_point int_blue_y))
+PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y,
+ png_fixed_point int_red_Z, png_fixed_point int_green_X,
+ png_fixed_point int_green_Y, png_fixed_point int_green_Z,
+ png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
+ png_fixed_point int_blue_Z))
+#endif
+
+#ifdef PNG_eXIf_SUPPORTED
+PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_bytep *exif));
+PNG_EXPORT(247, void, png_set_eXIf, (png_const_structrp png_ptr,
+ png_inforp info_ptr, const png_bytep exif));
+
+PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 *num_exif, png_bytep *exif));
+PNG_EXPORT(249, void, png_set_eXIf_1, (png_const_structrp png_ptr,
+ png_inforp info_ptr, const png_uint_32 num_exif, const png_bytep exif));
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, double *file_gamma))
+PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *int_file_gamma))
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr,
+ png_inforp info_ptr, double file_gamma))
+PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_fixed_point int_file_gamma))
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_16p *hist));
+PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_uint_16p hist));
+#endif
+
+PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height,
+ int *bit_depth, int *color_type, int *interlace_method,
+ int *compression_method, int *filter_method));
+
+PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_method, int compression_method,
+ int filter_method));
+
+#ifdef PNG_oFFs_SUPPORTED
+PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
+ int *unit_type));
+#endif
+
+#ifdef PNG_oFFs_SUPPORTED
+PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y,
+ int unit_type));
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_charp *purpose, png_int_32 *X0,
+ png_int_32 *X1, int *type, int *nparams, png_charp *units,
+ png_charpp *params));
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1,
+ int type, int nparams, png_const_charp units, png_charpp params));
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
+ int *unit_type));
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
+#endif
+
+PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_colorp *palette, int *num_palette));
+
+PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr,
+ png_inforp info_ptr, png_const_colorp palette, int num_palette));
+
+#ifdef PNG_sBIT_SUPPORTED
+PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_color_8p *sig_bit));
+#endif
+
+#ifdef PNG_sBIT_SUPPORTED
+PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_color_8p sig_bit));
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, int *file_srgb_intent));
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int srgb_intent));
+PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int srgb_intent));
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_charpp name, int *compression_type,
+ png_bytepp profile, png_uint_32 *proflen));
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_charp name, int compression_type,
+ png_const_bytep profile, png_uint_32 proflen));
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_sPLT_tpp entries));
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_sPLT_tp entries, int nentries));
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_get_text also returns the number of text chunks in *num_text */
+PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_textp *text_ptr, int *num_text));
+#endif
+
+/* Note while png_set_text() will accept a structure whose text,
+ * language, and translated keywords are NULL pointers, the structure
+ * returned by png_get_text will always contain regular
+ * zero-terminated C strings. They might be empty strings but
+ * they will never be NULL pointers.
+ */
+
+#ifdef PNG_TEXT_SUPPORTED
+PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_textp text_ptr, int num_text));
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_timep *mod_time));
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_timep mod_time));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans,
+ png_color_16p *trans_color));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr,
+ png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans,
+ png_const_color_16p trans_color));
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, int *unit, double *width, double *height))
+#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
+ defined(PNG_FLOATING_POINT_SUPPORTED)
+/* NOTE: this API is currently implemented using floating point arithmetic,
+ * consequently it can only be used on systems with floating point support.
+ * In any case the range of values supported by png_fixed_point is small and it
+ * is highly recommended that png_get_sCAL_s be used instead.
+ */
+PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
+ png_fixed_point *width, png_fixed_point *height))
+#endif
+PNG_EXPORT(169, png_uint_32, png_get_sCAL_s,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
+ png_charpp swidth, png_charpp sheight));
+
+PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int unit, double width, double height))
+PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int unit, png_fixed_point width,
+ png_fixed_point height))
+PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int unit,
+ png_const_charp swidth, png_const_charp sheight));
+#endif /* sCAL */
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+/* Provide the default handling for all unknown chunks or, optionally, for
+ * specific unknown chunks.
+ *
+ * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was
+ * ignored and the default was used, the per-chunk setting only had an effect on
+ * write. If you wish to have chunk-specific handling on read in code that must
+ * work on earlier versions you must use a user chunk callback to specify the
+ * desired handling (keep or discard.)
+ *
+ * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The
+ * parameter is interpreted as follows:
+ *
+ * READ:
+ * PNG_HANDLE_CHUNK_AS_DEFAULT:
+ * Known chunks: do normal libpng processing, do not keep the chunk (but
+ * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+ * Unknown chunks: for a specific chunk use the global default, when used
+ * as the default discard the chunk data.
+ * PNG_HANDLE_CHUNK_NEVER:
+ * Discard the chunk data.
+ * PNG_HANDLE_CHUNK_IF_SAFE:
+ * Keep the chunk data if the chunk is not critical else raise a chunk
+ * error.
+ * PNG_HANDLE_CHUNK_ALWAYS:
+ * Keep the chunk data.
+ *
+ * If the chunk data is saved it can be retrieved using png_get_unknown_chunks,
+ * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent
+ * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks
+ * it simply resets the behavior to the libpng default.
+ *
+ * INTERACTION WTIH USER CHUNK CALLBACKS:
+ * The per-chunk handling is always used when there is a png_user_chunk_ptr
+ * callback and the callback returns 0; the chunk is then always stored *unless*
+ * it is critical and the per-chunk setting is other than ALWAYS. Notice that
+ * the global default is *not* used in this case. (In effect the per-chunk
+ * value is incremented to at least IF_SAFE.)
+ *
+ * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and
+ * per-chunk defaults will be honored. If you want to preserve the current
+ * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE
+ * as the default - if you don't do this libpng 1.6 will issue a warning.
+ *
+ * If you want unhandled unknown chunks to be discarded in libpng 1.6 and
+ * earlier simply return '1' (handled).
+ *
+ * PNG_HANDLE_AS_UNKNOWN_SUPPORTED:
+ * If this is *not* set known chunks will always be handled by libpng and
+ * will never be stored in the unknown chunk list. Known chunks listed to
+ * png_set_keep_unknown_chunks will have no effect. If it is set then known
+ * chunks listed with a keep other than AS_DEFAULT will *never* be processed
+ * by libpng, in addition critical chunks must either be processed by the
+ * callback or saved.
+ *
+ * The IHDR and IEND chunks must not be listed. Because this turns off the
+ * default handling for chunks that would otherwise be recognized the
+ * behavior of libpng transformations may well become incorrect!
+ *
+ * WRITE:
+ * When writing chunks the options only apply to the chunks specified by
+ * png_set_unknown_chunks (below), libpng will *always* write known chunks
+ * required by png_set_ calls and will always write the core critical chunks
+ * (as required for PLTE).
+ *
+ * Each chunk in the png_set_unknown_chunks list is looked up in the
+ * png_set_keep_unknown_chunks list to find the keep setting, this is then
+ * interpreted as follows:
+ *
+ * PNG_HANDLE_CHUNK_AS_DEFAULT:
+ * Write safe-to-copy chunks and write other chunks if the global
+ * default is set to _ALWAYS, otherwise don't write this chunk.
+ * PNG_HANDLE_CHUNK_NEVER:
+ * Do not write the chunk.
+ * PNG_HANDLE_CHUNK_IF_SAFE:
+ * Write the chunk if it is safe-to-copy, otherwise do not write it.
+ * PNG_HANDLE_CHUNK_ALWAYS:
+ * Write the chunk.
+ *
+ * Note that the default behavior is effectively the opposite of the read case -
+ * in read unknown chunks are not stored by default, in write they are written
+ * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different
+ * - on write the safe-to-copy bit is checked, on read the critical bit is
+ * checked and on read if the chunk is critical an error will be raised.
+ *
+ * num_chunks:
+ * ===========
+ * If num_chunks is positive, then the "keep" parameter specifies the manner
+ * for handling only those chunks appearing in the chunk_list array,
+ * otherwise the chunk list array is ignored.
+ *
+ * If num_chunks is 0 the "keep" parameter specifies the default behavior for
+ * unknown chunks, as described above.
+ *
+ * If num_chunks is negative, then the "keep" parameter specifies the manner
+ * for handling all unknown chunks plus all chunks recognized by libpng
+ * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to
+ * be processed by libpng.
+ */
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
+ int keep, png_const_bytep chunk_list, int num_chunks));
+#endif /* HANDLE_AS_UNKNOWN */
+
+/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;
+ * the result is therefore true (non-zero) if special handling is required,
+ * false for the default handling.
+ */
+PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
+ png_const_bytep chunk_name));
+#endif /* SET_UNKNOWN_CHUNKS */
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_unknown_chunkp unknowns,
+ int num_unknowns));
+ /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added
+ * unknowns to the location currently stored in the png_struct. This is
+ * invariably the wrong value on write. To fix this call the following API
+ * for each chunk in the list with the correct location. If you know your
+ * code won't be compiled on earlier versions you can rely on
+ * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing
+ * the correct thing.
+ */
+
+PNG_EXPORT(175, void, png_set_unknown_chunk_location,
+ (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location));
+
+PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_unknown_chunkpp entries));
+#endif
+
+/* Png_free_data() will turn off the "valid" flag for anything it frees.
+ * If you need to turn it off for a chunk that your application has freed,
+ * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK);
+ */
+PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int mask));
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+/* The "params" pointer is currently not used and is for future expansion. */
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr,
+ int transforms, png_voidp params));
+#endif
+#ifdef PNG_WRITE_SUPPORTED
+PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr,
+ int transforms, png_voidp params));
+#endif
+#endif
+
+PNG_EXPORT(180, png_const_charp, png_get_copyright,
+ (png_const_structrp png_ptr));
+PNG_EXPORT(181, png_const_charp, png_get_header_ver,
+ (png_const_structrp png_ptr));
+PNG_EXPORT(182, png_const_charp, png_get_header_version,
+ (png_const_structrp png_ptr));
+PNG_EXPORT(183, png_const_charp, png_get_libpng_ver,
+ (png_const_structrp png_ptr));
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr,
+ png_uint_32 mng_features_permitted));
+#endif
+
+/* For use in png_set_keep_unknown, added to version 1.2.6 */
+#define PNG_HANDLE_CHUNK_AS_DEFAULT 0
+#define PNG_HANDLE_CHUNK_NEVER 1
+#define PNG_HANDLE_CHUNK_IF_SAFE 2
+#define PNG_HANDLE_CHUNK_ALWAYS 3
+#define PNG_HANDLE_CHUNK_LAST 4
+
+/* Strip the prepended error numbers ("#nnn ") from error and warning
+ * messages before passing them to the error or warning handler.
+ */
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr,
+ png_uint_32 strip_mode));
+#endif
+
+/* Added in libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr,
+ png_uint_32 user_width_max, png_uint_32 user_height_max));
+PNG_EXPORT(187, png_uint_32, png_get_user_width_max,
+ (png_const_structrp png_ptr));
+PNG_EXPORT(188, png_uint_32, png_get_user_height_max,
+ (png_const_structrp png_ptr));
+/* Added in libpng-1.4.0 */
+PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr,
+ png_uint_32 user_chunk_cache_max));
+PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max,
+ (png_const_structrp png_ptr));
+/* Added in libpng-1.4.1 */
+PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr,
+ png_alloc_size_t user_chunk_cache_max));
+PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max,
+ (png_const_structrp png_ptr));
+#endif
+
+#if defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+PNG_FP_EXPORT(196, float, png_get_x_offset_inches,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
+#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
+PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
+#endif
+
+PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr))
+#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
+PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
+#endif
+
+# ifdef PNG_pHYs_SUPPORTED
+PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
+ int *unit_type));
+# endif /* pHYs */
+#endif /* INCH_CONVERSIONS */
+
+/* Added in libpng-1.4.0 */
+#ifdef PNG_IO_STATE_SUPPORTED
+PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr));
+
+/* Removed from libpng 1.6; use png_get_io_chunk_type. */
+PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr),
+ PNG_DEPRECATED)
+
+PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
+ (png_const_structrp png_ptr));
+
+/* The flags returned by png_get_io_state() are the following: */
+# define PNG_IO_NONE 0x0000 /* no I/O at this moment */
+# define PNG_IO_READING 0x0001 /* currently reading */
+# define PNG_IO_WRITING 0x0002 /* currently writing */
+# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */
+# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */
+# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */
+# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */
+# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */
+# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */
+#endif /* IO_STATE */
+
+/* Interlace support. The following macros are always defined so that if
+ * libpng interlace handling is turned off the macros may be used to handle
+ * interlaced images within the application.
+ */
+#define PNG_INTERLACE_ADAM7_PASSES 7
+
+/* Two macros to return the first row and first column of the original,
+ * full, image which appears in a given pass. 'pass' is in the range 0
+ * to 6 and the result is in the range 0 to 7.
+ */
+#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7)
+#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7)
+
+/* A macro to return the offset between pixels in the output row for a pair of
+ * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that
+ * follows. Note that ROW_OFFSET is the offset from one row to the next whereas
+ * COL_OFFSET is from one column to the next, within a row.
+ */
+#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8)
+#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1))
+
+/* Two macros to help evaluate the number of rows or columns in each
+ * pass. This is expressed as a shift - effectively log2 of the number or
+ * rows or columns in each 8x8 tile of the original image.
+ */
+#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
+#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
+
+/* Hence two macros to determine the number of rows or columns in a given
+ * pass of an image given its height or width. In fact these macros may
+ * return non-zero even though the sub-image is empty, because the other
+ * dimension may be empty for a small image.
+ */
+#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
+ -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
+#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
+ -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
+
+/* For the reader row callbacks (both progressive and sequential) it is
+ * necessary to find the row in the output image given a row in an interlaced
+ * image, so two more macros:
+ */
+#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \
+ (((y_in)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
+#define PNG_COL_FROM_PASS_COL(x_in, pass) \
+ (((x_in)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
+
+/* Two macros which return a boolean (0 or 1) saying whether the given row
+ * or column is in a particular pass. These use a common utility macro that
+ * returns a mask for a given pass - the offset 'off' selects the row or
+ * column version. The mask has the appropriate bit set for each column in
+ * the tile.
+ */
+#define PNG_PASS_MASK(pass,off) ( \
+ ((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \
+ ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0))
+
+#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
+ ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
+#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
+ ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
+
+#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
+/* With these routines we avoid an integer divide, which will be slower on
+ * most machines. However, it does take more operations than the corresponding
+ * divide method, so it may be slower on a few RISC systems. There are two
+ * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
+ *
+ * Note that the rounding factors are NOT supposed to be the same! 128 and
+ * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
+ * standard method.
+ *
+ * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
+ */
+
+ /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
+
+# define png_composite(composite, fg, alpha, bg) \
+ { \
+ png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
+ * (png_uint_16)(alpha) \
+ + (png_uint_16)(bg)*(png_uint_16)(255 \
+ - (png_uint_16)(alpha)) + 128); \
+ (composite) = (png_byte)(((temp + (temp >> 8)) >> 8) & 0xff); \
+ }
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ { \
+ png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
+ * (png_uint_32)(alpha) \
+ + (png_uint_32)(bg)*(65535 \
+ - (png_uint_32)(alpha)) + 32768); \
+ (composite) = (png_uint_16)(0xffff & ((temp + (temp >> 16)) >> 16)); \
+ }
+
+#else /* Standard method using integer division */
+
+# define png_composite(composite, fg, alpha, bg) \
+ (composite) = \
+ (png_byte)(0xff & (((png_uint_16)(fg) * (png_uint_16)(alpha) + \
+ (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+ 127) / 255))
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ (composite) = \
+ (png_uint_16)(0xffff & (((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+ (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \
+ 32767) / 65535))
+#endif /* READ_COMPOSITE_NODIV */
+
+#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
+PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf));
+PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf));
+PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf));
+#endif
+
+PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr,
+ png_const_bytep buf));
+/* No png_get_int_16 -- may be added if there's a real need for it. */
+
+/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */
+#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i));
+#endif
+#ifdef PNG_SAVE_INT_32_SUPPORTED
+PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i));
+#endif
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
+/* No png_save_int_16 -- may be added if there's a real need for it. */
+#endif
+
+#ifdef PNG_USE_READ_MACROS
+/* Inline macros to do direct reads of bytes from the input buffer.
+ * The png_get_int_32() routine assumes we are using two's complement
+ * format for negative values, which is almost certainly true.
+ */
+# define PNG_get_uint_32(buf) \
+ (((png_uint_32)(*(buf)) << 24) + \
+ ((png_uint_32)(*((buf) + 1)) << 16) + \
+ ((png_uint_32)(*((buf) + 2)) << 8) + \
+ ((png_uint_32)(*((buf) + 3))))
+
+ /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
+ * function) incorrectly returned a value of type png_uint_32.
+ */
+# define PNG_get_uint_16(buf) \
+ ((png_uint_16) \
+ (((unsigned int)(*(buf)) << 8) + \
+ ((unsigned int)(*((buf) + 1)))))
+
+# define PNG_get_int_32(buf) \
+ ((png_int_32)((*(buf) & 0x80) \
+ ? -((png_int_32)(((png_get_uint_32(buf)^0xffffffffU)+1U)&0x7fffffffU)) \
+ : (png_int_32)png_get_uint_32(buf)))
+
+/* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
+ * but defining a macro name prefixed with PNG_PREFIX.
+ */
+# ifndef PNG_PREFIX
+# define png_get_uint_32(buf) PNG_get_uint_32(buf)
+# define png_get_uint_16(buf) PNG_get_uint_16(buf)
+# define png_get_int_32(buf) PNG_get_int_32(buf)
+# endif
+#else
+# ifdef PNG_PREFIX
+ /* No macros; revert to the (redefined) function */
+# define PNG_get_uint_32 (png_get_uint_32)
+# define PNG_get_uint_16 (png_get_uint_16)
+# define PNG_get_int_32 (png_get_int_32)
+# endif
+#endif
+
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+PNG_EXPORT(242, void, png_set_check_for_invalid_index,
+ (png_structrp png_ptr, int allowed));
+# ifdef PNG_GET_PALETTE_MAX_SUPPORTED
+PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr,
+ png_const_infop info_ptr));
+# endif
+#endif /* CHECK_FOR_INVALID_INDEX */
+
+/*******************************************************************************
+ * Section 5: SIMPLIFIED API
+ *******************************************************************************
+ *
+ * Please read the documentation in libpng-manual.txt (TODO: write said
+ * documentation) if you don't understand what follows.
+ *
+ * The simplified API hides the details of both libpng and the PNG file format
+ * itself. It allows PNG files to be read into a very limited number of
+ * in-memory bitmap formats or to be written from the same formats. If these
+ * formats do not accomodate your needs then you can, and should, use the more
+ * sophisticated APIs above - these support a wide variety of in-memory formats
+ * and a wide variety of sophisticated transformations to those formats as well
+ * as a wide variety of APIs to manipulate ancillary information.
+ *
+ * To read a PNG file using the simplified API:
+ *
+ * 1) Declare a 'png_image' structure (see below) on the stack, set the
+ * version field to PNG_IMAGE_VERSION and the 'opaque' pointer to NULL
+ * (this is REQUIRED, your program may crash if you don't do it.)
+ * 2) Call the appropriate png_image_begin_read... function.
+ * 3) Set the png_image 'format' member to the required sample format.
+ * 4) Allocate a buffer for the image and, if required, the color-map.
+ * 5) Call png_image_finish_read to read the image and, if required, the
+ * color-map into your buffers.
+ *
+ * There are no restrictions on the format of the PNG input itself; all valid
+ * color types, bit depths, and interlace methods are acceptable, and the
+ * input image is transformed as necessary to the requested in-memory format
+ * during the png_image_finish_read() step. The only caveat is that if you
+ * request a color-mapped image from a PNG that is full-color or makes
+ * complex use of an alpha channel the transformation is extremely lossy and the
+ * result may look terrible.
+ *
+ * To write a PNG file using the simplified API:
+ *
+ * 1) Declare a 'png_image' structure on the stack and memset() it to all zero.
+ * 2) Initialize the members of the structure that describe the image, setting
+ * the 'format' member to the format of the image samples.
+ * 3) Call the appropriate png_image_write... function with a pointer to the
+ * image and, if necessary, the color-map to write the PNG data.
+ *
+ * png_image is a structure that describes the in-memory format of an image
+ * when it is being read or defines the in-memory format of an image that you
+ * need to write:
+ */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) || \
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+
+#define PNG_IMAGE_VERSION 1
+
+typedef struct png_control *png_controlp;
+typedef struct
+{
+ png_controlp opaque; /* Initialize to NULL, free with png_image_free */
+ png_uint_32 version; /* Set to PNG_IMAGE_VERSION */
+ png_uint_32 width; /* Image width in pixels (columns) */
+ png_uint_32 height; /* Image height in pixels (rows) */
+ png_uint_32 format; /* Image format as defined below */
+ png_uint_32 flags; /* A bit mask containing informational flags */
+ png_uint_32 colormap_entries;
+ /* Number of entries in the color-map */
+
+ /* In the event of an error or warning the following field will be set to a
+ * non-zero value and the 'message' field will contain a '\0' terminated
+ * string with the libpng error or warning message. If both warnings and
+ * an error were encountered, only the error is recorded. If there
+ * are multiple warnings, only the first one is recorded.
+ *
+ * The upper 30 bits of this value are reserved, the low two bits contain
+ * a value as follows:
+ */
+# define PNG_IMAGE_WARNING 1
+# define PNG_IMAGE_ERROR 2
+ /*
+ * The result is a two-bit code such that a value more than 1 indicates
+ * a failure in the API just called:
+ *
+ * 0 - no warning or error
+ * 1 - warning
+ * 2 - error
+ * 3 - error preceded by warning
+ */
+# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1)
+
+ png_uint_32 warning_or_error;
+
+ char message[64];
+} png_image, *png_imagep;
+
+/* The samples of the image have one to four channels whose components have
+ * original values in the range 0 to 1.0:
+ *
+ * 1: A single gray or luminance channel (G).
+ * 2: A gray/luminance channel and an alpha channel (GA).
+ * 3: Three red, green, blue color channels (RGB).
+ * 4: Three color channels and an alpha channel (RGBA).
+ *
+ * The components are encoded in one of two ways:
+ *
+ * a) As a small integer, value 0..255, contained in a single byte. For the
+ * alpha channel the original value is simply value/255. For the color or
+ * luminance channels the value is encoded according to the sRGB specification
+ * and matches the 8-bit format expected by typical display devices.
+ *
+ * The color/gray channels are not scaled (pre-multiplied) by the alpha
+ * channel and are suitable for passing to color management software.
+ *
+ * b) As a value in the range 0..65535, contained in a 2-byte integer. All
+ * channels can be converted to the original value by dividing by 65535; all
+ * channels are linear. Color channels use the RGB encoding (RGB end-points) of
+ * the sRGB specification. This encoding is identified by the
+ * PNG_FORMAT_FLAG_LINEAR flag below.
+ *
+ * When the simplified API needs to convert between sRGB and linear colorspaces,
+ * the actual sRGB transfer curve defined in the sRGB specification (see the
+ * article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+ * approximation used elsewhere in libpng.
+ *
+ * When an alpha channel is present it is expected to denote pixel coverage
+ * of the color or luminance channels and is returned as an associated alpha
+ * channel: the color/gray channels are scaled (pre-multiplied) by the alpha
+ * value.
+ *
+ * The samples are either contained directly in the image data, between 1 and 8
+ * bytes per pixel according to the encoding, or are held in a color-map indexed
+ * by bytes in the image data. In the case of a color-map the color-map entries
+ * are individual samples, encoded as above, and the image data has one byte per
+ * pixel to select the relevant sample from the color-map.
+ */
+
+/* PNG_FORMAT_*
+ *
+ * #defines to be used in png_image::format. Each #define identifies a
+ * particular layout of sample data and, if present, alpha values. There are
+ * separate defines for each of the two component encodings.
+ *
+ * A format is built up using single bit flag values. All combinations are
+ * valid. Formats can be built up from the flag values or you can use one of
+ * the predefined values below. When testing formats always use the FORMAT_FLAG
+ * macros to test for individual features - future versions of the library may
+ * add new flags.
+ *
+ * When reading or writing color-mapped images the format should be set to the
+ * format of the entries in the color-map then png_image_{read,write}_colormap
+ * called to read or write the color-map and set the format correctly for the
+ * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly!
+ *
+ * NOTE: libpng can be built with particular features disabled. If you see
+ * compiler errors because the definition of one of the following flags has been
+ * compiled out it is because libpng does not have the required support. It is
+ * possible, however, for the libpng configuration to enable the format on just
+ * read or just write; in that case you may see an error at run time. You can
+ * guard against this by checking for the definition of the appropriate
+ * "_SUPPORTED" macro, one of:
+ *
+ * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED
+ */
+#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */
+#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */
+#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2-byte channels else 1-byte */
+#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */
+
+#ifdef PNG_FORMAT_BGR_SUPPORTED
+# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */
+#endif
+
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
+# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
+#endif
+
+#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */
+
+/* Commonly used formats have predefined macros.
+ *
+ * First the single byte (sRGB) formats:
+ */
+#define PNG_FORMAT_GRAY 0
+#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA
+#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST)
+#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR
+#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR)
+#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA)
+#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST)
+#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA)
+#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST)
+
+/* Then the linear 2-byte formats. When naming these "Y" is used to
+ * indicate a luminance (gray) channel.
+ */
+#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR
+#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA)
+#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR)
+#define PNG_FORMAT_LINEAR_RGB_ALPHA \
+ (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA)
+
+/* With color-mapped formats the image data is one byte for each pixel, the byte
+ * is an index into the color-map which is formatted as above. To obtain a
+ * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP
+ * to one of the above definitions, or you can use one of the definitions below.
+ */
+#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP)
+
+/* PNG_IMAGE macros
+ *
+ * These are convenience macros to derive information from a png_image
+ * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the
+ * actual image sample values - either the entries in the color-map or the
+ * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values
+ * for the pixels and will always return 1 for color-mapped formats. The
+ * remaining macros return information about the rows in the image and the
+ * complete image.
+ *
+ * NOTE: All the macros that take a png_image::format parameter are compile time
+ * constants if the format parameter is, itself, a constant. Therefore these
+ * macros can be used in array declarations and case labels where required.
+ * Similarly the macros are also pre-processor constants (sizeof is not used) so
+ * they can be used in #if tests.
+ *
+ * First the information about the samples.
+ */
+#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\
+ (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1)
+ /* Return the total number of channels in a given format: 1..4 */
+
+#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\
+ ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1)
+ /* Return the size in bytes of a single component of a pixel or color-map
+ * entry (as appropriate) in the image: 1 or 2.
+ */
+
+#define PNG_IMAGE_SAMPLE_SIZE(fmt)\
+ (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt))
+ /* This is the size of the sample data for one sample. If the image is
+ * color-mapped it is the size of one color-map entry (and image pixels are
+ * one byte in size), otherwise it is the size of one image pixel.
+ */
+
+#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\
+ (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256)
+ /* The maximum size of the color-map required by the format expressed in a
+ * count of components. This can be used to compile-time allocate a
+ * color-map:
+ *
+ * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)];
+ *
+ * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)];
+ *
+ * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the
+ * information from one of the png_image_begin_read_ APIs and dynamically
+ * allocate the required memory.
+ */
+
+/* Corresponding information about the pixels */
+#define PNG_IMAGE_PIXEL_(test,fmt)\
+ (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt))
+
+#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\
+ PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt)
+ /* The number of separate channels (components) in a pixel; 1 for a
+ * color-mapped image.
+ */
+
+#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\
+ PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt)
+ /* The size, in bytes, of each component in a pixel; 1 for a color-mapped
+ * image.
+ */
+
+#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt)
+ /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */
+
+/* Information about the whole row, or whole image */
+#define PNG_IMAGE_ROW_STRIDE(image)\
+ (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width)
+ /* Return the total number of components in a single row of the image; this
+ * is the minimum 'row stride', the minimum count of components between each
+ * row. For a color-mapped image this is the minimum number of bytes in a
+ * row.
+ *
+ * WARNING: this macro overflows for some images with more than one component
+ * and very large image widths. libpng will refuse to process an image where
+ * this macro would overflow.
+ */
+
+#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\
+ (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride))
+ /* Return the size, in bytes, of an image buffer given a png_image and a row
+ * stride - the number of components to leave space for in each row.
+ *
+ * WARNING: this macro overflows a 32-bit integer for some large PNG images,
+ * libpng will refuse to process an image where such an overflow would occur.
+ */
+
+#define PNG_IMAGE_SIZE(image)\
+ PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image))
+ /* Return the size, in bytes, of the image in memory given just a png_image;
+ * the row stride is the minimum stride required for the image.
+ */
+
+#define PNG_IMAGE_COLORMAP_SIZE(image)\
+ (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries)
+ /* Return the size, in bytes, of the color-map of this image. If the image
+ * format is not a color-map format this will return a size sufficient for
+ * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if
+ * you don't want to allocate a color-map in this case.
+ */
+
+/* PNG_IMAGE_FLAG_*
+ *
+ * Flags containing additional information about the image are held in the
+ * 'flags' field of png_image.
+ */
+#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01
+ /* This indicates the the RGB values of the in-memory bitmap do not
+ * correspond to the red, green and blue end-points defined by sRGB.
+ */
+
+#define PNG_IMAGE_FLAG_FAST 0x02
+ /* On write emphasise speed over compression; the resultant PNG file will be
+ * larger but will be produced significantly faster, particular for large
+ * images. Do not use this option for images which will be distributed, only
+ * used it when producing intermediate files that will be read back in
+ * repeatedly. For a typical 24-bit image the option will double the read
+ * speed at the cost of increasing the image size by 25%, however for many
+ * more compressible images the PNG file can be 10 times larger with only a
+ * slight speed gain.
+ */
+
+#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04
+ /* On read if the image is a 16-bit per component image and there is no gAMA
+ * or sRGB chunk assume that the components are sRGB encoded. Notice that
+ * images output by the simplified API always have gamma information; setting
+ * this flag only affects the interpretation of 16-bit images from an
+ * external source. It is recommended that the application expose this flag
+ * to the user; the user can normally easily recognize the difference between
+ * linear and sRGB encoding. This flag has no effect on write - the data
+ * passed to the write APIs must have the correct encoding (as defined
+ * above.)
+ *
+ * If the flag is not set (the default) input 16-bit per component data is
+ * assumed to be linear.
+ *
+ * NOTE: the flag can only be set after the png_image_begin_read_ call,
+ * because that call initializes the 'flags' field.
+ */
+
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+/* READ APIs
+ * ---------
+ *
+ * The png_image passed to the read APIs must have been initialized by setting
+ * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.)
+ */
+#ifdef PNG_STDIO_SUPPORTED
+PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image,
+ const char *file_name));
+ /* The named file is opened for read and the image header is filled in
+ * from the PNG header in the file.
+ */
+
+PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image,
+ FILE* file));
+ /* The PNG header is read from the stdio FILE object. */
+#endif /* STDIO */
+
+PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image,
+ png_const_voidp memory, png_size_t size));
+ /* The PNG header is read from the given memory buffer. */
+
+PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
+ png_const_colorp background, void *buffer, png_int_32 row_stride,
+ void *colormap));
+ /* Finish reading the image into the supplied buffer and clean up the
+ * png_image structure.
+ *
+ * row_stride is the step, in byte or 2-byte units as appropriate,
+ * between adjacent rows. A positive stride indicates that the top-most row
+ * is first in the buffer - the normal top-down arrangement. A negative
+ * stride indicates that the bottom-most row is first in the buffer.
+ *
+ * background need only be supplied if an alpha channel must be removed from
+ * a png_byte format and the removal is to be done by compositing on a solid
+ * color; otherwise it may be NULL and any composition will be done directly
+ * onto the buffer. The value is an sRGB color to use for the background,
+ * for grayscale output the green channel is used.
+ *
+ * background must be supplied when an alpha channel must be removed from a
+ * single byte color-mapped output format, in other words if:
+ *
+ * 1) The original format from png_image_begin_read_from_* had
+ * PNG_FORMAT_FLAG_ALPHA set.
+ * 2) The format set by the application does not.
+ * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and
+ * PNG_FORMAT_FLAG_LINEAR *not* set.
+ *
+ * For linear output removing the alpha channel is always done by compositing
+ * on black and background is ignored.
+ *
+ * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must
+ * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE.
+ * image->colormap_entries will be updated to the actual number of entries
+ * written to the colormap; this may be less than the original value.
+ */
+
+PNG_EXPORT(238, void, png_image_free, (png_imagep image));
+ /* Free any data allocated by libpng in image->opaque, setting the pointer to
+ * NULL. May be called at any time after the structure is initialized.
+ */
+#endif /* SIMPLIFIED_READ */
+
+#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
+/* WRITE APIS
+ * ----------
+ * For write you must initialize a png_image structure to describe the image to
+ * be written. To do this use memset to set the whole structure to 0 then
+ * initialize fields describing your image.
+ *
+ * version: must be set to PNG_IMAGE_VERSION
+ * opaque: must be initialized to NULL
+ * width: image width in pixels
+ * height: image height in rows
+ * format: the format of the data (image and color-map) you wish to write
+ * flags: set to 0 unless one of the defined flags applies; set
+ * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB
+ * values do not correspond to the colors in sRGB.
+ * colormap_entries: set to the number of entries in the color-map (0 to 256)
+ */
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
+PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
+ const char *file, int convert_to_8bit, const void *buffer,
+ png_int_32 row_stride, const void *colormap));
+ /* Write the image to the named file. */
+
+PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
+ int convert_to_8_bit, const void *buffer, png_int_32 row_stride,
+ const void *colormap));
+ /* Write the image to the given (FILE*). */
+#endif /* SIMPLIFIED_WRITE_STDIO */
+
+/* With all write APIs if image is in one of the linear formats with 16-bit
+ * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG
+ * gamma encoded according to the sRGB specification, otherwise a 16-bit linear
+ * encoded PNG file is written.
+ *
+ * With color-mapped data formats the colormap parameter point to a color-map
+ * with at least image->colormap_entries encoded in the specified format. If
+ * the format is linear the written PNG color-map will be converted to sRGB
+ * regardless of the convert_to_8_bit flag.
+ *
+ * With all APIs row_stride is handled as in the read APIs - it is the spacing
+ * from one row to the next in component sized units (1 or 2 bytes) and if
+ * negative indicates a bottom-up row layout in the buffer. If row_stride is
+ * zero, libpng will calculate it for you from the image width and number of
+ * channels.
+ *
+ * Note that the write API does not support interlacing, sub-8-bit pixels or
+ * most ancillary chunks. If you need to write text chunks (e.g. for copyright
+ * notices) you need to use one of the other APIs.
+ */
+
+PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
+ png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8_bit,
+ const void *buffer, png_int_32 row_stride, const void *colormap));
+ /* Write the image to the given memory buffer. The function both writes the
+ * whole PNG data stream to *memory and updates *memory_bytes with the count
+ * of bytes written.
+ *
+ * 'memory' may be NULL. In this case *memory_bytes is not read however on
+ * success the number of bytes which would have been written will still be
+ * stored in *memory_bytes. On failure *memory_bytes will contain 0.
+ *
+ * If 'memory' is not NULL it must point to memory[*memory_bytes] of
+ * writeable memory.
+ *
+ * If the function returns success memory[*memory_bytes] (if 'memory' is not
+ * NULL) contains the written PNG data. *memory_bytes will always be less
+ * than or equal to the original value.
+ *
+ * If the function returns false and *memory_bytes was not changed an error
+ * occured during write. If *memory_bytes was changed, or is not 0 if
+ * 'memory' was NULL, the write would have succeeded but for the memory
+ * buffer being too small. *memory_bytes contains the required number of
+ * bytes and will be bigger that the original value.
+ */
+
+#define png_image_write_get_memory_size(image, size, convert_to_8_bit, buffer,\
+ row_stride, colormap)\
+ png_image_write_to_memory(&(image), 0, &(size), convert_to_8_bit, buffer,\
+ row_stride, colormap)
+ /* Return the amount of memory in 'size' required to compress this image.
+ * The png_image structure 'image' must be filled in as in the above
+ * function and must not be changed before the actual write call, the buffer
+ * and all other parameters must also be identical to that in the final
+ * write call. The 'size' variable need not be initialized.
+ *
+ * NOTE: the macro returns true/false, if false is returned 'size' will be
+ * set to zero and the write failed and probably will fail if tried again.
+ */
+
+/* You can pre-allocate the buffer by making sure it is of sufficient size
+ * regardless of the amount of compression achieved. The buffer size will
+ * always be bigger than the original image and it will never be filled. The
+ * following macros are provided to assist in allocating the buffer.
+ */
+#define PNG_IMAGE_DATA_SIZE(image) (PNG_IMAGE_SIZE(image)+(image).height)
+ /* The number of uncompressed bytes in the PNG byte encoding of the image;
+ * uncompressing the PNG IDAT data will give this number of bytes.
+ *
+ * NOTE: while PNG_IMAGE_SIZE cannot overflow for an image in memory this
+ * macro can because of the extra bytes used in the PNG byte encoding. You
+ * need to avoid this macro if your image size approaches 2^30 in width or
+ * height. The same goes for the remainder of these macros; they all produce
+ * bigger numbers than the actual in-memory image size.
+ */
+#ifndef PNG_ZLIB_MAX_SIZE
+# define PNG_ZLIB_MAX_SIZE(b) ((b)+(((b)+7U)>>3)+(((b)+63U)>>6)+11U)
+ /* An upper bound on the number of compressed bytes given 'b' uncompressed
+ * bytes. This is based on deflateBounds() in zlib; different
+ * implementations of zlib compression may conceivably produce more data so
+ * if your zlib implementation is not zlib itself redefine this macro
+ * appropriately.
+ */
+#endif
+
+#define PNG_IMAGE_COMPRESSED_SIZE_MAX(image)\
+ PNG_ZLIB_MAX_SIZE((png_alloc_size_t)PNG_IMAGE_DATA_SIZE(image))
+ /* An upper bound on the size of the data in the PNG IDAT chunks. */
+
+#define PNG_IMAGE_PNG_SIZE_MAX_(image, image_size)\
+ ((8U/*sig*/+25U/*IHDR*/+16U/*gAMA*/+44U/*cHRM*/+12U/*IEND*/+\
+ (((image).format&PNG_FORMAT_FLAG_COLORMAP)?/*colormap: PLTE, tRNS*/\
+ 12U+3U*(image).colormap_entries/*PLTE data*/+\
+ (((image).format&PNG_FORMAT_FLAG_ALPHA)?\
+ 12U/*tRNS*/+(image).colormap_entries:0U):0U)+\
+ 12U)+(12U*((image_size)/PNG_ZBUF_SIZE))/*IDAT*/+(image_size))
+ /* A helper for the following macro; if your compiler cannot handle the
+ * following macro use this one with the result of
+ * PNG_IMAGE_COMPRESSED_SIZE_MAX(image) as the second argument (most
+ * compilers should handle this just fine.)
+ */
+
+#define PNG_IMAGE_PNG_SIZE_MAX(image)\
+ PNG_IMAGE_PNG_SIZE_MAX_(image, PNG_IMAGE_COMPRESSED_SIZE_MAX(image))
+ /* An upper bound on the total length of the PNG data stream for 'image'.
+ * The result is of type png_alloc_size_t, on 32-bit systems this may
+ * overflow even though PNG_IMAGE_DATA_SIZE does not overflow; the write will
+ * run out of buffer space but return a corrected size which should work.
+ */
+#endif /* SIMPLIFIED_WRITE */
+/*******************************************************************************
+ * END OF SIMPLIFIED API
+ ******************************************************************************/
+#endif /* SIMPLIFIED_{READ|WRITE} */
+
+/*******************************************************************************
+ * Section 6: IMPLEMENTATION OPTIONS
+ *******************************************************************************
+ *
+ * Support for arbitrary implementation-specific optimizations. The API allows
+ * particular options to be turned on or off. 'Option' is the number of the
+ * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given
+ * by the PNG_OPTION_ defines below.
+ *
+ * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions,
+ * are detected at run time, however sometimes it may be impossible
+ * to do this in user mode, in which case it is necessary to discover
+ * the capabilities in an OS specific way. Such capabilities are
+ * listed here when libpng has support for them and must be turned
+ * ON by the application if present.
+ *
+ * SOFTWARE: sometimes software optimizations actually result in performance
+ * decrease on some architectures or systems, or with some sets of
+ * PNG images. 'Software' options allow such optimizations to be
+ * selected at run time.
+ */
+#ifdef PNG_SET_OPTION_SUPPORTED
+#ifdef PNG_ARM_NEON_API_SUPPORTED
+# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */
+#endif
+#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */
+#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */
+#ifdef PNG_MIPS_MSA_API_SUPPORTED
+# define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */
+#endif
+#define PNG_IGNORE_ADLER32 8
+#ifdef PNG_POWERPC_VSX_API_SUPPORTED
+# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions supported */
+#endif
+#define PNG_OPTION_NEXT 12 /* Next option - numbers must be even */
+
+/* Return values: NOTE: there are four values and 'off' is *not* zero */
+#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */
+#define PNG_OPTION_INVALID 1 /* Option number out of range */
+#define PNG_OPTION_OFF 2
+#define PNG_OPTION_ON 3
+
+PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,
+ int onoff));
+#endif /* SET_OPTION */
+
+/*******************************************************************************
+ * END OF HARDWARE AND SOFTWARE OPTIONS
+ ******************************************************************************/
+
+/* Maintainer: Put new public prototypes here ^, in libpng.3, in project
+ * defs, and in scripts/symbols.def.
+ */
+
+/* The last ordinal number (this is the *last* one already used; the next
+ * one to use is one more than this.)
+ */
+#ifdef PNG_EXPORT_LAST_ORDINAL
+ PNG_EXPORT_LAST_ORDINAL(249);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNG_VERSION_INFO_ONLY */
+/* Do not put anything past this line */
+#endif /* PNG_H */
diff --git a/xs/src/png/libpng/pngconf.h b/xs/src/png/libpng/pngconf.h
new file mode 100644
index 000000000..d13b13e57
--- /dev/null
+++ b/xs/src/png/libpng/pngconf.h
@@ -0,0 +1,622 @@
+
+/* pngconf.h - machine configurable file for libpng
+ *
+ * libpng version 1.6.34, September 29, 2017
+ *
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * Any machine specific code is near the front of this file, so if you
+ * are configuring libpng for a machine, you may want to read the section
+ * starting here down to where it starts to typedef png_color, png_text,
+ * and png_info.
+ */
+
+#ifndef PNGCONF_H
+#define PNGCONF_H
+
+#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */
+
+/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C
+ * compiler for correct compilation. The following header files are required by
+ * the standard. If your compiler doesn't provide these header files, or they
+ * do not match the standard, you will need to provide/improve them.
+ */
+#include <limits.h>
+#include <stddef.h>
+
+/* Library header files. These header files are all defined by ISOC90; libpng
+ * expects conformant implementations, however, an ISOC90 conformant system need
+ * not provide these header files if the functionality cannot be implemented.
+ * In this case it will be necessary to disable the relevant parts of libpng in
+ * the build of pnglibconf.h.
+ *
+ * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not
+ * include this unnecessary header file.
+ */
+
+#ifdef PNG_STDIO_SUPPORTED
+ /* Required for the definition of FILE: */
+# include <stdio.h>
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* Required for the definition of jmp_buf and the declaration of longjmp: */
+# include <setjmp.h>
+#endif
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+ /* Required for struct tm: */
+# include <time.h>
+#endif
+
+#endif /* PNG_BUILDING_SYMBOL_TABLE */
+
+/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using
+ * PNG_NO_CONST; this is no longer supported except for data declarations which
+ * apparently still cause problems in 2011 on some compilers.
+ */
+#define PNG_CONST const /* backward compatibility only */
+
+/* This controls optimization of the reading of 16-bit and 32-bit values
+ * from PNG files. It can be set on a per-app-file basis - it
+ * just changes whether a macro is used when the function is called.
+ * The library builder sets the default; if read functions are not
+ * built into the library the macro implementation is forced on.
+ */
+#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
+# define PNG_USE_READ_MACROS
+#endif
+#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
+# if PNG_DEFAULT_READ_MACROS
+# define PNG_USE_READ_MACROS
+# endif
+#endif
+
+/* COMPILER SPECIFIC OPTIONS.
+ *
+ * These options are provided so that a variety of difficult compilers
+ * can be used. Some are fixed at build time (e.g. PNG_API_RULE
+ * below) but still have compiler specific implementations, others
+ * may be changed on a per-file basis when compiling against libpng.
+ */
+
+/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect
+ * against legacy (pre ISOC90) compilers that did not understand function
+ * prototypes. It is not required for modern C compilers.
+ */
+#ifndef PNGARG
+# define PNGARG(arglist) arglist
+#endif
+
+/* Function calling conventions.
+ * =============================
+ * Normally it is not necessary to specify to the compiler how to call
+ * a function - it just does it - however on x86 systems derived from
+ * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
+ * and some others) there are multiple ways to call a function and the
+ * default can be changed on the compiler command line. For this reason
+ * libpng specifies the calling convention of every exported function and
+ * every function called via a user supplied function pointer. This is
+ * done in this file by defining the following macros:
+ *
+ * PNGAPI Calling convention for exported functions.
+ * PNGCBAPI Calling convention for user provided (callback) functions.
+ * PNGCAPI Calling convention used by the ANSI-C library (required
+ * for longjmp callbacks and sometimes used internally to
+ * specify the calling convention for zlib).
+ *
+ * These macros should never be overridden. If it is necessary to
+ * change calling convention in a private build this can be done
+ * by setting PNG_API_RULE (which defaults to 0) to one of the values
+ * below to select the correct 'API' variants.
+ *
+ * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
+ * This is correct in every known environment.
+ * PNG_API_RULE=1 Use the operating system convention for PNGAPI and
+ * the 'C' calling convention (from PNGCAPI) for
+ * callbacks (PNGCBAPI). This is no longer required
+ * in any known environment - if it has to be used
+ * please post an explanation of the problem to the
+ * libpng mailing list.
+ *
+ * These cases only differ if the operating system does not use the C
+ * calling convention, at present this just means the above cases
+ * (x86 DOS/Windows sytems) and, even then, this does not apply to
+ * Cygwin running on those systems.
+ *
+ * Note that the value must be defined in pnglibconf.h so that what
+ * the application uses to call the library matches the conventions
+ * set when building the library.
+ */
+
+/* Symbol export
+ * =============
+ * When building a shared library it is almost always necessary to tell
+ * the compiler which symbols to export. The png.h macro 'PNG_EXPORT'
+ * is used to mark the symbols. On some systems these symbols can be
+ * extracted at link time and need no special processing by the compiler,
+ * on other systems the symbols are flagged by the compiler and just
+ * the declaration requires a special tag applied (unfortunately) in a
+ * compiler dependent way. Some systems can do either.
+ *
+ * A small number of older systems also require a symbol from a DLL to
+ * be flagged to the program that calls it. This is a problem because
+ * we do not know in the header file included by application code that
+ * the symbol will come from a shared library, as opposed to a statically
+ * linked one. For this reason the application must tell us by setting
+ * the magic flag PNG_USE_DLL to turn on the special processing before
+ * it includes png.h.
+ *
+ * Four additional macros are used to make this happen:
+ *
+ * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
+ * the build or imported if PNG_USE_DLL is set - compiler
+ * and system specific.
+ *
+ * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
+ * 'type', compiler specific.
+ *
+ * PNG_DLL_EXPORT Set to the magic to use during a libpng build to
+ * make a symbol exported from the DLL. Not used in the
+ * public header files; see pngpriv.h for how it is used
+ * in the libpng build.
+ *
+ * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
+ * from a DLL - used to define PNG_IMPEXP when
+ * PNG_USE_DLL is set.
+ */
+
+/* System specific discovery.
+ * ==========================
+ * This code is used at build time to find PNG_IMPEXP, the API settings
+ * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL
+ * import processing is possible. On Windows systems it also sets
+ * compiler-specific macros to the values required to change the calling
+ * conventions of the various functions.
+ */
+#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
+ defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+ /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or
+ * MinGW on any architecture currently supported by Windows. Also includes
+ * Watcom builds but these need special treatment because they are not
+ * compatible with GCC or Visual C because of different calling conventions.
+ */
+# if PNG_API_RULE == 2
+ /* If this line results in an error, either because __watcall is not
+ * understood or because of a redefine just below you cannot use *this*
+ * build of the library with the compiler you are using. *This* build was
+ * build using Watcom and applications must also be built using Watcom!
+ */
+# define PNGCAPI __watcall
+# endif
+
+# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
+# define PNGCAPI __cdecl
+# if PNG_API_RULE == 1
+ /* If this line results in an error __stdcall is not understood and
+ * PNG_API_RULE should not have been set to '1'.
+ */
+# define PNGAPI __stdcall
+# endif
+# else
+ /* An older compiler, or one not detected (erroneously) above,
+ * if necessary override on the command line to get the correct
+ * variants for the compiler.
+ */
+# ifndef PNGCAPI
+# define PNGCAPI _cdecl
+# endif
+# if PNG_API_RULE == 1 && !defined(PNGAPI)
+# define PNGAPI _stdcall
+# endif
+# endif /* compiler/api */
+
+ /* NOTE: PNGCBAPI always defaults to PNGCAPI. */
+
+# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
+# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed"
+# endif
+
+# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
+ (defined(__BORLANDC__) && __BORLANDC__ < 0x500)
+ /* older Borland and MSC
+ * compilers used '__export' and required this to be after
+ * the type.
+ */
+# ifndef PNG_EXPORT_TYPE
+# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
+# endif
+# define PNG_DLL_EXPORT __export
+# else /* newer compiler */
+# define PNG_DLL_EXPORT __declspec(dllexport)
+# ifndef PNG_DLL_IMPORT
+# define PNG_DLL_IMPORT __declspec(dllimport)
+# endif
+# endif /* compiler */
+
+#else /* !Windows */
+# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
+# define PNGAPI _System
+# else /* !Windows/x86 && !OS/2 */
+ /* Use the defaults, or define PNG*API on the command line (but
+ * this will have to be done for every compile!)
+ */
+# endif /* other system, !OS/2 */
+#endif /* !Windows/x86 */
+
+/* Now do all the defaulting . */
+#ifndef PNGCAPI
+# define PNGCAPI
+#endif
+#ifndef PNGCBAPI
+# define PNGCBAPI PNGCAPI
+#endif
+#ifndef PNGAPI
+# define PNGAPI PNGCAPI
+#endif
+
+/* PNG_IMPEXP may be set on the compilation system command line or (if not set)
+ * then in an internal header file when building the library, otherwise (when
+ * using the library) it is set here.
+ */
+#ifndef PNG_IMPEXP
+# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
+ /* This forces use of a DLL, disallowing static linking */
+# define PNG_IMPEXP PNG_DLL_IMPORT
+# endif
+
+# ifndef PNG_IMPEXP
+# define PNG_IMPEXP
+# endif
+#endif
+
+/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat
+ * 'attributes' as a storage class - the attributes go at the start of the
+ * function definition, and attributes are always appended regardless of the
+ * compiler. This considerably simplifies these macros but may cause problems
+ * if any compilers both need function attributes and fail to handle them as
+ * a storage class (this is unlikely.)
+ */
+#ifndef PNG_FUNCTION
+# define PNG_FUNCTION(type, name, args, attributes) attributes type name args
+#endif
+
+#ifndef PNG_EXPORT_TYPE
+# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
+#endif
+
+ /* The ordinal value is only relevant when preprocessing png.h for symbol
+ * table entries, so we discard it here. See the .dfn files in the
+ * scripts directory.
+ */
+
+#ifndef PNG_EXPORTA
+# define PNG_EXPORTA(ordinal, type, name, args, attributes) \
+ PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), PNGARG(args), \
+ PNG_LINKAGE_API attributes)
+#endif
+
+/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
+ * so make something non-empty to satisfy the requirement:
+ */
+#define PNG_EMPTY /*empty list*/
+
+#define PNG_EXPORT(ordinal, type, name, args) \
+ PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
+
+/* Use PNG_REMOVED to comment out a removed interface. */
+#ifndef PNG_REMOVED
+# define PNG_REMOVED(ordinal, type, name, args, attributes)
+#endif
+
+#ifndef PNG_CALLBACK
+# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
+#endif
+
+/* Support for compiler specific function attributes. These are used
+ * so that where compiler support is available incorrect use of API
+ * functions in png.h will generate compiler warnings.
+ *
+ * Added at libpng-1.2.41.
+ */
+
+#ifndef PNG_NO_PEDANTIC_WARNINGS
+# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
+# define PNG_PEDANTIC_WARNINGS_SUPPORTED
+# endif
+#endif
+
+#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
+ /* Support for compiler specific function attributes. These are used
+ * so that where compiler support is available, incorrect use of API
+ * functions in png.h will generate compiler warnings. Added at libpng
+ * version 1.2.41. Disabling these removes the warnings but may also produce
+ * less efficient code.
+ */
+# if defined(__clang__) && defined(__has_attribute)
+ /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
+# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
+# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
+# endif
+# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__)
+# define PNG_NORETURN __attribute__((__noreturn__))
+# endif
+# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__)
+# define PNG_ALLOCATED __attribute__((__malloc__))
+# endif
+# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__)
+# define PNG_DEPRECATED __attribute__((__deprecated__))
+# endif
+# if !defined(PNG_PRIVATE)
+# ifdef __has_extension
+# if __has_extension(attribute_unavailable_with_message)
+# define PNG_PRIVATE __attribute__((__unavailable__(\
+ "This function is not exported by libpng.")))
+# endif
+# endif
+# endif
+# ifndef PNG_RESTRICT
+# define PNG_RESTRICT __restrict
+# endif
+
+# elif defined(__GNUC__)
+# ifndef PNG_USE_RESULT
+# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
+# endif
+# ifndef PNG_NORETURN
+# define PNG_NORETURN __attribute__((__noreturn__))
+# endif
+# if __GNUC__ >= 3
+# ifndef PNG_ALLOCATED
+# define PNG_ALLOCATED __attribute__((__malloc__))
+# endif
+# ifndef PNG_DEPRECATED
+# define PNG_DEPRECATED __attribute__((__deprecated__))
+# endif
+# ifndef PNG_PRIVATE
+# if 0 /* Doesn't work so we use deprecated instead*/
+# define PNG_PRIVATE \
+ __attribute__((warning("This function is not exported by libpng.")))
+# else
+# define PNG_PRIVATE \
+ __attribute__((__deprecated__))
+# endif
+# endif
+# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
+# ifndef PNG_RESTRICT
+# define PNG_RESTRICT __restrict
+# endif
+# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */
+# endif /* __GNUC__ >= 3 */
+
+# elif defined(_MSC_VER) && (_MSC_VER >= 1300)
+# ifndef PNG_USE_RESULT
+# define PNG_USE_RESULT /* not supported */
+# endif
+# ifndef PNG_NORETURN
+# define PNG_NORETURN __declspec(noreturn)
+# endif
+# ifndef PNG_ALLOCATED
+# if (_MSC_VER >= 1400)
+# define PNG_ALLOCATED __declspec(restrict)
+# endif
+# endif
+# ifndef PNG_DEPRECATED
+# define PNG_DEPRECATED __declspec(deprecated)
+# endif
+# ifndef PNG_PRIVATE
+# define PNG_PRIVATE __declspec(deprecated)
+# endif
+# ifndef PNG_RESTRICT
+# if (_MSC_VER >= 1400)
+# define PNG_RESTRICT __restrict
+# endif
+# endif
+
+# elif defined(__WATCOMC__)
+# ifndef PNG_RESTRICT
+# define PNG_RESTRICT __restrict
+# endif
+# endif
+#endif /* PNG_PEDANTIC_WARNINGS */
+
+#ifndef PNG_DEPRECATED
+# define PNG_DEPRECATED /* Use of this function is deprecated */
+#endif
+#ifndef PNG_USE_RESULT
+# define PNG_USE_RESULT /* The result of this function must be checked */
+#endif
+#ifndef PNG_NORETURN
+# define PNG_NORETURN /* This function does not return */
+#endif
+#ifndef PNG_ALLOCATED
+# define PNG_ALLOCATED /* The result of the function is new memory */
+#endif
+#ifndef PNG_PRIVATE
+# define PNG_PRIVATE /* This is a private libpng function */
+#endif
+#ifndef PNG_RESTRICT
+# define PNG_RESTRICT /* The C99 "restrict" feature */
+#endif
+
+#ifndef PNG_FP_EXPORT /* A floating point API. */
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+# define PNG_FP_EXPORT(ordinal, type, name, args)\
+ PNG_EXPORT(ordinal, type, name, args);
+# else /* No floating point APIs */
+# define PNG_FP_EXPORT(ordinal, type, name, args)
+# endif
+#endif
+#ifndef PNG_FIXED_EXPORT /* A fixed point API. */
+# ifdef PNG_FIXED_POINT_SUPPORTED
+# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
+ PNG_EXPORT(ordinal, type, name, args);
+# else /* No fixed point APIs */
+# define PNG_FIXED_EXPORT(ordinal, type, name, args)
+# endif
+#endif
+
+#ifndef PNG_BUILDING_SYMBOL_TABLE
+/* Some typedefs to get us started. These should be safe on most of the common
+ * platforms.
+ *
+ * png_uint_32 and png_int_32 may, currently, be larger than required to hold a
+ * 32-bit value however this is not normally advisable.
+ *
+ * png_uint_16 and png_int_16 should always be two bytes in size - this is
+ * verified at library build time.
+ *
+ * png_byte must always be one byte in size.
+ *
+ * The checks below use constants from limits.h, as defined by the ISOC90
+ * standard.
+ */
+#if CHAR_BIT == 8 && UCHAR_MAX == 255
+ typedef unsigned char png_byte;
+#else
+# error "libpng requires 8-bit bytes"
+#endif
+
+#if INT_MIN == -32768 && INT_MAX == 32767
+ typedef int png_int_16;
+#elif SHRT_MIN == -32768 && SHRT_MAX == 32767
+ typedef short png_int_16;
+#else
+# error "libpng requires a signed 16-bit type"
+#endif
+
+#if UINT_MAX == 65535
+ typedef unsigned int png_uint_16;
+#elif USHRT_MAX == 65535
+ typedef unsigned short png_uint_16;
+#else
+# error "libpng requires an unsigned 16-bit type"
+#endif
+
+#if INT_MIN < -2147483646 && INT_MAX > 2147483646
+ typedef int png_int_32;
+#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646
+ typedef long int png_int_32;
+#else
+# error "libpng requires a signed 32-bit (or more) type"
+#endif
+
+#if UINT_MAX > 4294967294U
+ typedef unsigned int png_uint_32;
+#elif ULONG_MAX > 4294967294U
+ typedef unsigned long int png_uint_32;
+#else
+# error "libpng requires an unsigned 32-bit (or more) type"
+#endif
+
+/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however,
+ * requires an ISOC90 compiler and relies on consistent behavior of sizeof.
+ */
+typedef size_t png_size_t;
+typedef ptrdiff_t png_ptrdiff_t;
+
+/* libpng needs to know the maximum value of 'size_t' and this controls the
+ * definition of png_alloc_size_t, below. This maximum value of size_t limits
+ * but does not control the maximum allocations the library makes - there is
+ * direct application control of this through png_set_user_limits().
+ */
+#ifndef PNG_SMALL_SIZE_T
+ /* Compiler specific tests for systems where size_t is known to be less than
+ * 32 bits (some of these systems may no longer work because of the lack of
+ * 'far' support; see above.)
+ */
+# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\
+ (defined(_MSC_VER) && defined(MAXSEG_64K))
+# define PNG_SMALL_SIZE_T
+# endif
+#endif
+
+/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no
+ * smaller than png_uint_32. Casts from png_size_t or png_uint_32 to
+ * png_alloc_size_t are not necessary; in fact, it is recommended not to use
+ * them at all so that the compiler can complain when something turns out to be
+ * problematic.
+ *
+ * Casts in the other direction (from png_alloc_size_t to png_size_t or
+ * png_uint_32) should be explicitly applied; however, we do not expect to
+ * encounter practical situations that require such conversions.
+ *
+ * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than
+ * 4294967295 - i.e. less than the maximum value of png_uint_32.
+ */
+#ifdef PNG_SMALL_SIZE_T
+ typedef png_uint_32 png_alloc_size_t;
+#else
+ typedef png_size_t png_alloc_size_t;
+#endif
+
+/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler
+ * implementations of Intel CPU specific support of user-mode segmented address
+ * spaces, where 16-bit pointers address more than 65536 bytes of memory using
+ * separate 'segment' registers. The implementation requires two different
+ * types of pointer (only one of which includes the segment value.)
+ *
+ * If required this support is available in version 1.2 of libpng and may be
+ * available in versions through 1.5, although the correctness of the code has
+ * not been verified recently.
+ */
+
+/* Typedef for floating-point numbers that are converted to fixed-point with a
+ * multiple of 100,000, e.g., gamma
+ */
+typedef png_int_32 png_fixed_point;
+
+/* Add typedefs for pointers */
+typedef void * png_voidp;
+typedef const void * png_const_voidp;
+typedef png_byte * png_bytep;
+typedef const png_byte * png_const_bytep;
+typedef png_uint_32 * png_uint_32p;
+typedef const png_uint_32 * png_const_uint_32p;
+typedef png_int_32 * png_int_32p;
+typedef const png_int_32 * png_const_int_32p;
+typedef png_uint_16 * png_uint_16p;
+typedef const png_uint_16 * png_const_uint_16p;
+typedef png_int_16 * png_int_16p;
+typedef const png_int_16 * png_const_int_16p;
+typedef char * png_charp;
+typedef const char * png_const_charp;
+typedef png_fixed_point * png_fixed_point_p;
+typedef const png_fixed_point * png_const_fixed_point_p;
+typedef png_size_t * png_size_tp;
+typedef const png_size_t * png_const_size_tp;
+
+#ifdef PNG_STDIO_SUPPORTED
+typedef FILE * png_FILE_p;
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double * png_doublep;
+typedef const double * png_const_doublep;
+#endif
+
+/* Pointers to pointers; i.e. arrays */
+typedef png_byte * * png_bytepp;
+typedef png_uint_32 * * png_uint_32pp;
+typedef png_int_32 * * png_int_32pp;
+typedef png_uint_16 * * png_uint_16pp;
+typedef png_int_16 * * png_int_16pp;
+typedef const char * * png_const_charpp;
+typedef char * * png_charpp;
+typedef png_fixed_point * * png_fixed_point_pp;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double * * png_doublepp;
+#endif
+
+/* Pointers to pointers to pointers; i.e., pointer to array */
+typedef char * * * png_charppp;
+
+#endif /* PNG_BUILDING_SYMBOL_TABLE */
+
+#endif /* PNGCONF_H */
diff --git a/xs/src/png/libpng/pngdebug.h b/xs/src/png/libpng/pngdebug.h
new file mode 100644
index 000000000..15a7ed0c9
--- /dev/null
+++ b/xs/src/png/libpng/pngdebug.h
@@ -0,0 +1,153 @@
+
+/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
+ *
+ * Last changed in libpng 1.6.8 [December 19, 2013]
+ * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* Define PNG_DEBUG at compile time for debugging information. Higher
+ * numbers for PNG_DEBUG mean more debugging information. This has
+ * only been added since version 0.95 so it is not implemented throughout
+ * libpng yet, but more support will be added as needed.
+ *
+ * png_debug[1-2]?(level, message ,arg{0-2})
+ * Expands to a statement (either a simple expression or a compound
+ * do..while(0) statement) that outputs a message with parameter
+ * substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG
+ * is undefined, 0 or 1 every png_debug expands to a simple expression
+ * (actually ((void)0)).
+ *
+ * level: level of detail of message, starting at 0. A level 'n'
+ * message is preceded by 'n' 3-space indentations (not implemented
+ * on Microsoft compilers unless PNG_DEBUG_FILE is also
+ * defined, to allow debug DLL compilation with no standard IO).
+ * message: a printf(3) style text string. A trailing '\n' is added
+ * to the message.
+ * arg: 0 to 2 arguments for printf(3) style substitution in message.
+ */
+#ifndef PNGDEBUG_H
+#define PNGDEBUG_H
+/* These settings control the formatting of messages in png.c and pngerror.c */
+/* Moved to pngdebug.h at 1.5.0 */
+# ifndef PNG_LITERAL_SHARP
+# define PNG_LITERAL_SHARP 0x23
+# endif
+# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
+# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
+# endif
+# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
+# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
+# endif
+# ifndef PNG_STRING_NEWLINE
+# define PNG_STRING_NEWLINE "\n"
+# endif
+
+#ifdef PNG_DEBUG
+# if (PNG_DEBUG > 0)
+# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
+# include <crtdbg.h>
+# if (PNG_DEBUG > 1)
+# ifndef _DEBUG
+# define _DEBUG
+# endif
+# ifndef png_debug
+# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
+# endif
+# ifndef png_debug1
+# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
+# endif
+# ifndef png_debug2
+# define png_debug2(l,m,p1,p2) \
+ _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
+# endif
+# endif
+# else /* PNG_DEBUG_FILE || !_MSC_VER */
+# ifndef PNG_STDIO_SUPPORTED
+# include <stdio.h> /* not included yet */
+# endif
+# ifndef PNG_DEBUG_FILE
+# define PNG_DEBUG_FILE stderr
+# endif /* PNG_DEBUG_FILE */
+
+# if (PNG_DEBUG > 1)
+# ifdef __STDC__
+# ifndef png_debug
+# define png_debug(l,m) \
+ do { \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
+ (num_tabs==2 ? " " : (num_tabs>2 ? " " : "")))); \
+ } while (0)
+# endif
+# ifndef png_debug1
+# define png_debug1(l,m,p1) \
+ do { \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
+ (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1); \
+ } while (0)
+# endif
+# ifndef png_debug2
+# define png_debug2(l,m,p1,p2) \
+ do { \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
+ (num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1,p2);\
+ } while (0)
+# endif
+# else /* __STDC __ */
+# ifndef png_debug
+# define png_debug(l,m) \
+ do { \
+ int num_tabs=l; \
+ char format[256]; \
+ snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+ m,PNG_STRING_NEWLINE); \
+ fprintf(PNG_DEBUG_FILE,format); \
+ } while (0)
+# endif
+# ifndef png_debug1
+# define png_debug1(l,m,p1) \
+ do { \
+ int num_tabs=l; \
+ char format[256]; \
+ snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+ m,PNG_STRING_NEWLINE); \
+ fprintf(PNG_DEBUG_FILE,format,p1); \
+ } while (0)
+# endif
+# ifndef png_debug2
+# define png_debug2(l,m,p1,p2) \
+ do { \
+ int num_tabs=l; \
+ char format[256]; \
+ snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+ m,PNG_STRING_NEWLINE); \
+ fprintf(PNG_DEBUG_FILE,format,p1,p2); \
+ } while (0)
+# endif
+# endif /* __STDC __ */
+# endif /* (PNG_DEBUG > 1) */
+
+# endif /* _MSC_VER */
+# endif /* (PNG_DEBUG > 0) */
+#endif /* PNG_DEBUG */
+#ifndef png_debug
+# define png_debug(l, m) ((void)0)
+#endif
+#ifndef png_debug1
+# define png_debug1(l, m, p1) ((void)0)
+#endif
+#ifndef png_debug2
+# define png_debug2(l, m, p1, p2) ((void)0)
+#endif
+#endif /* PNGDEBUG_H */
diff --git a/xs/src/png/libpng/pngerror.c b/xs/src/png/libpng/pngerror.c
new file mode 100644
index 000000000..ad48bfb98
--- /dev/null
+++ b/xs/src/png/libpng/pngerror.c
@@ -0,0 +1,963 @@
+
+/* pngerror.c - stub functions for i/o and memory allocation
+ *
+ * Last changed in libpng 1.6.31 [July 27, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all error handling. Users who
+ * need special error handling are expected to write replacement functions
+ * and use png_set_error_fn() to use those functions. See the instructions
+ * at each function.
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
+ png_const_charp error_message)),PNG_NORETURN);
+
+#ifdef PNG_WARNINGS_SUPPORTED
+static void /* PRIVATE */
+png_default_warning PNGARG((png_const_structrp png_ptr,
+ png_const_charp warning_message));
+#endif /* WARNINGS */
+
+/* This function is called whenever there is a fatal error. This function
+ * should not be changed. If there is a need to handle errors differently,
+ * you should supply a replacement error function and use png_set_error_fn()
+ * to replace the error function at run-time.
+ */
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+PNG_FUNCTION(void,PNGAPI
+png_error,(png_const_structrp png_ptr, png_const_charp error_message),
+ PNG_NORETURN)
+{
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ char msg[16];
+ if (png_ptr != NULL)
+ {
+ if ((png_ptr->flags &
+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
+ {
+ if (*error_message == PNG_LITERAL_SHARP)
+ {
+ /* Strip "#nnnn " from beginning of error message. */
+ int offset;
+ for (offset = 1; offset<15; offset++)
+ if (error_message[offset] == ' ')
+ break;
+
+ if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
+ {
+ int i;
+ for (i = 0; i < offset - 1; i++)
+ msg[i] = error_message[i + 1];
+ msg[i - 1] = '\0';
+ error_message = msg;
+ }
+
+ else
+ error_message += offset;
+ }
+
+ else
+ {
+ if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
+ {
+ msg[0] = '0';
+ msg[1] = '\0';
+ error_message = msg;
+ }
+ }
+ }
+ }
+#endif
+ if (png_ptr != NULL && png_ptr->error_fn != NULL)
+ (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),
+ error_message);
+
+ /* If the custom handler doesn't exist, or if it returns,
+ use the default handler, which will not return. */
+ png_default_error(png_ptr, error_message);
+}
+#else
+PNG_FUNCTION(void,PNGAPI
+png_err,(png_const_structrp png_ptr),PNG_NORETURN)
+{
+ /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
+ * erroneously as '\0', instead of the empty string "". This was
+ * apparently an error, introduced in libpng-1.2.20, and png_default_error
+ * will crash in this case.
+ */
+ if (png_ptr != NULL && png_ptr->error_fn != NULL)
+ (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), "");
+
+ /* If the custom handler doesn't exist, or if it returns,
+ use the default handler, which will not return. */
+ png_default_error(png_ptr, "");
+}
+#endif /* ERROR_TEXT */
+
+/* Utility to safely appends strings to a buffer. This never errors out so
+ * error checking is not required in the caller.
+ */
+size_t
+png_safecat(png_charp buffer, size_t bufsize, size_t pos,
+ png_const_charp string)
+{
+ if (buffer != NULL && pos < bufsize)
+ {
+ if (string != NULL)
+ while (*string != '\0' && pos < bufsize-1)
+ buffer[pos++] = *string++;
+
+ buffer[pos] = '\0';
+ }
+
+ return pos;
+}
+
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
+/* Utility to dump an unsigned value into a buffer, given a start pointer and
+ * and end pointer (which should point just *beyond* the end of the buffer!)
+ * Returns the pointer to the start of the formatted string.
+ */
+png_charp
+png_format_number(png_const_charp start, png_charp end, int format,
+ png_alloc_size_t number)
+{
+ int count = 0; /* number of digits output */
+ int mincount = 1; /* minimum number required */
+ int output = 0; /* digit output (for the fixed point format) */
+
+ *--end = '\0';
+
+ /* This is written so that the loop always runs at least once, even with
+ * number zero.
+ */
+ while (end > start && (number != 0 || count < mincount))
+ {
+
+ static const char digits[] = "0123456789ABCDEF";
+
+ switch (format)
+ {
+ case PNG_NUMBER_FORMAT_fixed:
+ /* Needs five digits (the fraction) */
+ mincount = 5;
+ if (output != 0 || number % 10 != 0)
+ {
+ *--end = digits[number % 10];
+ output = 1;
+ }
+ number /= 10;
+ break;
+
+ case PNG_NUMBER_FORMAT_02u:
+ /* Expects at least 2 digits. */
+ mincount = 2;
+ /* FALLTHROUGH */
+
+ case PNG_NUMBER_FORMAT_u:
+ *--end = digits[number % 10];
+ number /= 10;
+ break;
+
+ case PNG_NUMBER_FORMAT_02x:
+ /* This format expects at least two digits */
+ mincount = 2;
+ /* FALLTHROUGH */
+
+ case PNG_NUMBER_FORMAT_x:
+ *--end = digits[number & 0xf];
+ number >>= 4;
+ break;
+
+ default: /* an error */
+ number = 0;
+ break;
+ }
+
+ /* Keep track of the number of digits added */
+ ++count;
+
+ /* Float a fixed number here: */
+ if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start))
+ {
+ /* End of the fraction, but maybe nothing was output? In that case
+ * drop the decimal point. If the number is a true zero handle that
+ * here.
+ */
+ if (output != 0)
+ *--end = '.';
+ else if (number == 0) /* and !output */
+ *--end = '0';
+ }
+ }
+
+ return end;
+}
+#endif
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* This function is called whenever there is a non-fatal error. This function
+ * should not be changed. If there is a need to handle warnings differently,
+ * you should supply a replacement warning function and use
+ * png_set_error_fn() to replace the warning function at run-time.
+ */
+void PNGAPI
+png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
+{
+ int offset = 0;
+ if (png_ptr != NULL)
+ {
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if ((png_ptr->flags &
+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
+#endif
+ {
+ if (*warning_message == PNG_LITERAL_SHARP)
+ {
+ for (offset = 1; offset < 15; offset++)
+ if (warning_message[offset] == ' ')
+ break;
+ }
+ }
+ }
+ if (png_ptr != NULL && png_ptr->warning_fn != NULL)
+ (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
+ warning_message + offset);
+ else
+ png_default_warning(png_ptr, warning_message + offset);
+}
+
+/* These functions support 'formatted' warning messages with up to
+ * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter
+ * is introduced by @<number>, where 'number' starts at 1. This follows the
+ * standard established by X/Open for internationalizable error messages.
+ */
+void
+png_warning_parameter(png_warning_parameters p, int number,
+ png_const_charp string)
+{
+ if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
+ (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
+}
+
+void
+png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
+ png_alloc_size_t value)
+{
+ char buffer[PNG_NUMBER_BUFFER_SIZE];
+ png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
+}
+
+void
+png_warning_parameter_signed(png_warning_parameters p, int number, int format,
+ png_int_32 value)
+{
+ png_alloc_size_t u;
+ png_charp str;
+ char buffer[PNG_NUMBER_BUFFER_SIZE];
+
+ /* Avoid overflow by doing the negate in a png_alloc_size_t: */
+ u = (png_alloc_size_t)value;
+ if (value < 0)
+ u = ~u + 1;
+
+ str = PNG_FORMAT_NUMBER(buffer, format, u);
+
+ if (value < 0 && str > buffer)
+ *--str = '-';
+
+ png_warning_parameter(p, number, str);
+}
+
+void
+png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
+ png_const_charp message)
+{
+ /* The internal buffer is just 192 bytes - enough for all our messages,
+ * overflow doesn't happen because this code checks! If someone figures
+ * out how to send us a message longer than 192 bytes, all that will
+ * happen is that the message will be truncated appropriately.
+ */
+ size_t i = 0; /* Index in the msg[] buffer: */
+ char msg[192];
+
+ /* Each iteration through the following loop writes at most one character
+ * to msg[i++] then returns here to validate that there is still space for
+ * the trailing '\0'. It may (in the case of a parameter) read more than
+ * one character from message[]; it must check for '\0' and continue to the
+ * test if it finds the end of string.
+ */
+ while (i<(sizeof msg)-1 && *message != '\0')
+ {
+ /* '@' at end of string is now just printed (previously it was skipped);
+ * it is an error in the calling code to terminate the string with @.
+ */
+ if (p != NULL && *message == '@' && message[1] != '\0')
+ {
+ int parameter_char = *++message; /* Consume the '@' */
+ static const char valid_parameters[] = "123456789";
+ int parameter = 0;
+
+ /* Search for the parameter digit, the index in the string is the
+ * parameter to use.
+ */
+ while (valid_parameters[parameter] != parameter_char &&
+ valid_parameters[parameter] != '\0')
+ ++parameter;
+
+ /* If the parameter digit is out of range it will just get printed. */
+ if (parameter < PNG_WARNING_PARAMETER_COUNT)
+ {
+ /* Append this parameter */
+ png_const_charp parm = p[parameter];
+ png_const_charp pend = p[parameter] + (sizeof p[parameter]);
+
+ /* No need to copy the trailing '\0' here, but there is no guarantee
+ * that parm[] has been initialized, so there is no guarantee of a
+ * trailing '\0':
+ */
+ while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)
+ msg[i++] = *parm++;
+
+ /* Consume the parameter digit too: */
+ ++message;
+ continue;
+ }
+
+ /* else not a parameter and there is a character after the @ sign; just
+ * copy that. This is known not to be '\0' because of the test above.
+ */
+ }
+
+ /* At this point *message can't be '\0', even in the bad parameter case
+ * above where there is a lone '@' at the end of the message string.
+ */
+ msg[i++] = *message++;
+ }
+
+ /* i is always less than (sizeof msg), so: */
+ msg[i] = '\0';
+
+ /* And this is the formatted message. It may be larger than
+ * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these
+ * are not (currently) formatted.
+ */
+ png_warning(png_ptr, msg);
+}
+#endif /* WARNINGS */
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
+{
+ if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
+ {
+# ifdef PNG_READ_SUPPORTED
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+ png_ptr->chunk_name != 0)
+ png_chunk_warning(png_ptr, error_message);
+ else
+# endif
+ png_warning(png_ptr, error_message);
+ }
+
+ else
+ {
+# ifdef PNG_READ_SUPPORTED
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+ png_ptr->chunk_name != 0)
+ png_chunk_error(png_ptr, error_message);
+ else
+# endif
+ png_error(png_ptr, error_message);
+ }
+
+# ifndef PNG_ERROR_TEXT_SUPPORTED
+ PNG_UNUSED(error_message)
+# endif
+}
+
+void /* PRIVATE */
+png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
+{
+ if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
+ png_warning(png_ptr, error_message);
+ else
+ png_error(png_ptr, error_message);
+
+# ifndef PNG_ERROR_TEXT_SUPPORTED
+ PNG_UNUSED(error_message)
+# endif
+}
+
+void /* PRIVATE */
+png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
+{
+ if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
+ png_warning(png_ptr, error_message);
+ else
+ png_error(png_ptr, error_message);
+
+# ifndef PNG_ERROR_TEXT_SUPPORTED
+ PNG_UNUSED(error_message)
+# endif
+}
+#endif /* BENIGN_ERRORS */
+
+#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */
+#if defined(PNG_WARNINGS_SUPPORTED) || \
+ (defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED))
+/* These utilities are used internally to build an error message that relates
+ * to the current chunk. The chunk name comes from png_ptr->chunk_name,
+ * which is used to prefix the message. The message is limited in length
+ * to 63 bytes. The name characters are output as hex digits wrapped in []
+ * if the character is invalid.
+ */
+#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+static PNG_CONST char png_digit[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+static void /* PRIVATE */
+png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
+ error_message)
+{
+ png_uint_32 chunk_name = png_ptr->chunk_name;
+ int iout = 0, ishift = 24;
+
+ while (ishift >= 0)
+ {
+ int c = (int)(chunk_name >> ishift) & 0xff;
+
+ ishift -= 8;
+ if (isnonalpha(c) != 0)
+ {
+ buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
+ buffer[iout++] = png_digit[(c & 0xf0) >> 4];
+ buffer[iout++] = png_digit[c & 0x0f];
+ buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
+ }
+
+ else
+ {
+ buffer[iout++] = (char)c;
+ }
+ }
+
+ if (error_message == NULL)
+ buffer[iout] = '\0';
+
+ else
+ {
+ int iin = 0;
+
+ buffer[iout++] = ':';
+ buffer[iout++] = ' ';
+
+ while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
+ buffer[iout++] = error_message[iin++];
+
+ /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */
+ buffer[iout] = '\0';
+ }
+}
+#endif /* WARNINGS || ERROR_TEXT */
+
+#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
+PNG_FUNCTION(void,PNGAPI
+png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
+ PNG_NORETURN)
+{
+ char msg[18+PNG_MAX_ERROR_TEXT];
+ if (png_ptr == NULL)
+ png_error(png_ptr, error_message);
+
+ else
+ {
+ png_format_buffer(png_ptr, msg, error_message);
+ png_error(png_ptr, msg);
+ }
+}
+#endif /* READ && ERROR_TEXT */
+
+#ifdef PNG_WARNINGS_SUPPORTED
+void PNGAPI
+png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
+{
+ char msg[18+PNG_MAX_ERROR_TEXT];
+ if (png_ptr == NULL)
+ png_warning(png_ptr, warning_message);
+
+ else
+ {
+ png_format_buffer(png_ptr, msg, warning_message);
+ png_warning(png_ptr, msg);
+ }
+}
+#endif /* WARNINGS */
+
+#ifdef PNG_READ_SUPPORTED
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
+ error_message)
+{
+ if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
+ png_chunk_warning(png_ptr, error_message);
+
+ else
+ png_chunk_error(png_ptr, error_message);
+
+# ifndef PNG_ERROR_TEXT_SUPPORTED
+ PNG_UNUSED(error_message)
+# endif
+}
+#endif
+#endif /* READ */
+
+void /* PRIVATE */
+png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
+{
+# ifndef PNG_WARNINGS_SUPPORTED
+ PNG_UNUSED(message)
+# endif
+
+ /* This is always supported, but for just read or just write it
+ * unconditionally does the right thing.
+ */
+# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+# endif
+
+# ifdef PNG_READ_SUPPORTED
+ {
+ if (error < PNG_CHUNK_ERROR)
+ png_chunk_warning(png_ptr, message);
+
+ else
+ png_chunk_benign_error(png_ptr, message);
+ }
+# endif
+
+# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
+ else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+# endif
+
+# ifdef PNG_WRITE_SUPPORTED
+ {
+ if (error < PNG_CHUNK_WRITE_ERROR)
+ png_app_warning(png_ptr, message);
+
+ else
+ png_app_error(png_ptr, message);
+ }
+# endif
+}
+
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_FUNCTION(void,
+png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
+{
+# define fixed_message "fixed point overflow in "
+# define fixed_message_ln ((sizeof fixed_message)-1)
+ unsigned int iin;
+ char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
+ memcpy(msg, fixed_message, fixed_message_ln);
+ iin = 0;
+ if (name != NULL)
+ while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
+ {
+ msg[fixed_message_ln + iin] = name[iin];
+ ++iin;
+ }
+ msg[fixed_message_ln + iin] = 0;
+ png_error(png_ptr, msg);
+}
+#endif
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* This API only exists if ANSI-C style error handling is used,
+ * otherwise it is necessary for png_default_error to be overridden.
+ */
+jmp_buf* PNGAPI
+png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
+ size_t jmp_buf_size)
+{
+ /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value
+ * and it must not change after that. Libpng doesn't care how big the
+ * buffer is, just that it doesn't change.
+ *
+ * If the buffer size is no *larger* than the size of jmp_buf when libpng is
+ * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0
+ * semantics that this call will not fail. If the size is larger, however,
+ * the buffer is allocated and this may fail, causing the function to return
+ * NULL.
+ */
+ if (png_ptr == NULL)
+ return NULL;
+
+ if (png_ptr->jmp_buf_ptr == NULL)
+ {
+ png_ptr->jmp_buf_size = 0; /* not allocated */
+
+ if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local))
+ png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;
+
+ else
+ {
+ png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
+ png_malloc_warn(png_ptr, jmp_buf_size));
+
+ if (png_ptr->jmp_buf_ptr == NULL)
+ return NULL; /* new NULL return on OOM */
+
+ png_ptr->jmp_buf_size = jmp_buf_size;
+ }
+ }
+
+ else /* Already allocated: check the size */
+ {
+ size_t size = png_ptr->jmp_buf_size;
+
+ if (size == 0)
+ {
+ size = (sizeof png_ptr->jmp_buf_local);
+ if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)
+ {
+ /* This is an internal error in libpng: somehow we have been left
+ * with a stack allocated jmp_buf when the application regained
+ * control. It's always possible to fix this up, but for the moment
+ * this is a png_error because that makes it easy to detect.
+ */
+ png_error(png_ptr, "Libpng jmp_buf still allocated");
+ /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */
+ }
+ }
+
+ if (size != jmp_buf_size)
+ {
+ png_warning(png_ptr, "Application jmp_buf size changed");
+ return NULL; /* caller will probably crash: no choice here */
+ }
+ }
+
+ /* Finally fill in the function, now we have a satisfactory buffer. It is
+ * valid to change the function on every call.
+ */
+ png_ptr->longjmp_fn = longjmp_fn;
+ return png_ptr->jmp_buf_ptr;
+}
+
+void /* PRIVATE */
+png_free_jmpbuf(png_structrp png_ptr)
+{
+ if (png_ptr != NULL)
+ {
+ jmp_buf *jb = png_ptr->jmp_buf_ptr;
+
+ /* A size of 0 is used to indicate a local, stack, allocation of the
+ * pointer; used here and in png.c
+ */
+ if (jb != NULL && png_ptr->jmp_buf_size > 0)
+ {
+
+ /* This stuff is so that a failure to free the error control structure
+ * does not leave libpng in a state with no valid error handling: the
+ * free always succeeds, if there is an error it gets ignored.
+ */
+ if (jb != &png_ptr->jmp_buf_local)
+ {
+ /* Make an internal, libpng, jmp_buf to return here */
+ jmp_buf free_jmp_buf;
+
+ if (!setjmp(free_jmp_buf))
+ {
+ png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */
+ png_ptr->jmp_buf_size = 0; /* stack allocation */
+ png_ptr->longjmp_fn = longjmp;
+ png_free(png_ptr, jb); /* Return to setjmp on error */
+ }
+ }
+ }
+
+ /* *Always* cancel everything out: */
+ png_ptr->jmp_buf_size = 0;
+ png_ptr->jmp_buf_ptr = NULL;
+ png_ptr->longjmp_fn = 0;
+ }
+}
+#endif
+
+/* This is the default error handling function. Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash. This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static PNG_FUNCTION(void /* PRIVATE */,
+png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
+ PNG_NORETURN)
+{
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ /* Check on NULL only added in 1.5.4 */
+ if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
+ {
+ /* Strip "#nnnn " from beginning of error message. */
+ int offset;
+ char error_number[16];
+ for (offset = 0; offset<15; offset++)
+ {
+ error_number[offset] = error_message[offset + 1];
+ if (error_message[offset] == ' ')
+ break;
+ }
+
+ if ((offset > 1) && (offset < 15))
+ {
+ error_number[offset - 1] = '\0';
+ fprintf(stderr, "libpng error no. %s: %s",
+ error_number, error_message + offset + 1);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+
+ else
+ {
+ fprintf(stderr, "libpng error: %s, offset=%d",
+ error_message, offset);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+ }
+ else
+#endif
+ {
+ fprintf(stderr, "libpng error: %s", error_message ? error_message :
+ "undefined");
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+#else
+ PNG_UNUSED(error_message) /* Make compiler happy */
+#endif
+ png_longjmp(png_ptr, 1);
+}
+
+PNG_FUNCTION(void,PNGAPI
+png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&
+ png_ptr->jmp_buf_ptr != NULL)
+ png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(val)
+#endif
+
+ /* If control reaches this point, png_longjmp() must not return. The only
+ * choice is to terminate the whole process (or maybe the thread); to do
+ * this the ANSI-C abort() function is used unless a different method is
+ * implemented by overriding the default configuration setting for
+ * PNG_ABORT().
+ */
+ PNG_ABORT();
+}
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway. Replacement functions don't have to do anything
+ * here if you don't want them to. In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void /* PRIVATE */
+png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)
+{
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+# ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (*warning_message == PNG_LITERAL_SHARP)
+ {
+ int offset;
+ char warning_number[16];
+ for (offset = 0; offset < 15; offset++)
+ {
+ warning_number[offset] = warning_message[offset + 1];
+ if (warning_message[offset] == ' ')
+ break;
+ }
+
+ if ((offset > 1) && (offset < 15))
+ {
+ warning_number[offset + 1] = '\0';
+ fprintf(stderr, "libpng warning no. %s: %s",
+ warning_number, warning_message + offset);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+
+ else
+ {
+ fprintf(stderr, "libpng warning: %s",
+ warning_message);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+ }
+ else
+# endif
+
+ {
+ fprintf(stderr, "libpng warning: %s", warning_message);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+#else
+ PNG_UNUSED(warning_message) /* Make compiler happy */
+#endif
+ PNG_UNUSED(png_ptr) /* Make compiler happy */
+}
+#endif /* WARNINGS */
+
+/* This function is called when the application wants to use another method
+ * of handling errors and warnings. Note that the error function MUST NOT
+ * return to the calling routine or serious problems will occur. The return
+ * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1)
+ */
+void PNGAPI
+png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warning_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->error_ptr = error_ptr;
+ png_ptr->error_fn = error_fn;
+#ifdef PNG_WARNINGS_SUPPORTED
+ png_ptr->warning_fn = warning_fn;
+#else
+ PNG_UNUSED(warning_fn)
+#endif
+}
+
+
+/* This function returns a pointer to the error_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_error_ptr(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return NULL;
+
+ return ((png_voidp)png_ptr->error_ptr);
+}
+
+
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+void PNGAPI
+png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
+{
+ if (png_ptr != NULL)
+ {
+ png_ptr->flags &=
+ ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
+ PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
+ }
+}
+#endif
+
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+ /* Currently the above both depend on SETJMP_SUPPORTED, however it would be
+ * possible to implement without setjmp support just so long as there is some
+ * way to handle the error return here:
+ */
+PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
+png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
+ PNG_NORETURN)
+{
+ const png_const_structrp png_ptr = png_nonconst_ptr;
+ png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
+
+ /* An error is always logged here, overwriting anything (typically a warning)
+ * that is already there:
+ */
+ if (image != NULL)
+ {
+ png_safecat(image->message, (sizeof image->message), 0, error_message);
+ image->warning_or_error |= PNG_IMAGE_ERROR;
+
+ /* Retrieve the jmp_buf from within the png_control, making this work for
+ * C++ compilation too is pretty tricky: C++ wants a pointer to the first
+ * element of a jmp_buf, but C doesn't tell us the type of that.
+ */
+ if (image->opaque != NULL && image->opaque->error_buf != NULL)
+ longjmp(png_control_jmp_buf(image->opaque), 1);
+
+ /* Missing longjmp buffer, the following is to help debugging: */
+ {
+ size_t pos = png_safecat(image->message, (sizeof image->message), 0,
+ "bad longjmp: ");
+ png_safecat(image->message, (sizeof image->message), pos,
+ error_message);
+ }
+ }
+
+ /* Here on an internal programming error. */
+ abort();
+}
+
+#ifdef PNG_WARNINGS_SUPPORTED
+void /* PRIVATE */ PNGCBAPI
+png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
+{
+ const png_const_structrp png_ptr = png_nonconst_ptr;
+ png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
+
+ /* A warning is only logged if there is no prior warning or error. */
+ if (image->warning_or_error == 0)
+ {
+ png_safecat(image->message, (sizeof image->message), 0, warning_message);
+ image->warning_or_error |= PNG_IMAGE_WARNING;
+ }
+}
+#endif
+
+int /* PRIVATE */
+png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
+{
+ volatile png_imagep image = image_in;
+ volatile int result;
+ volatile png_voidp saved_error_buf;
+ jmp_buf safe_jmpbuf;
+
+ /* Safely execute function(arg) with png_error returning to this function. */
+ saved_error_buf = image->opaque->error_buf;
+ result = setjmp(safe_jmpbuf) == 0;
+
+ if (result != 0)
+ {
+
+ image->opaque->error_buf = safe_jmpbuf;
+ result = function(arg);
+ }
+
+ image->opaque->error_buf = saved_error_buf;
+
+ /* And do the cleanup prior to any failure return. */
+ if (result == 0)
+ png_image_free(image);
+
+ return result;
+}
+#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */
+#endif /* READ || WRITE */
diff --git a/xs/src/png/libpng/pngget.c b/xs/src/png/libpng/pngget.c
new file mode 100644
index 000000000..26e9fb1c3
--- /dev/null
+++ b/xs/src/png/libpng/pngget.c
@@ -0,0 +1,1248 @@
+
+/* pngget.c - retrieval of values from info struct
+ *
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+png_uint_32 PNGAPI
+png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_uint_32 flag)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->valid & flag);
+
+ return(0);
+}
+
+png_size_t PNGAPI
+png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->rowbytes);
+
+ return(0);
+}
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+png_bytepp PNGAPI
+png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->row_pointers);
+
+ return(0);
+}
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Easy access to info, added in libpng-0.99 */
+png_uint_32 PNGAPI
+png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->width;
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->height;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->bit_depth;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->color_type;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->filter_type;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->interlace_type;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->compression_type;
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
+ info_ptr)
+{
+#ifdef PNG_pHYs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ {
+ png_debug1(1, "in %s retrieval function",
+ "png_get_x_pixels_per_meter");
+
+ if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
+ return (info_ptr->x_pixels_per_unit);
+ }
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(info_ptr)
+#endif
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
+ info_ptr)
+{
+#ifdef PNG_pHYs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ {
+ png_debug1(1, "in %s retrieval function",
+ "png_get_y_pixels_per_meter");
+
+ if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
+ return (info_ptr->y_pixels_per_unit);
+ }
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(info_ptr)
+#endif
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_pHYs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
+
+ if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
+ info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)
+ return (info_ptr->x_pixels_per_unit);
+ }
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(info_ptr)
+#endif
+
+ return (0);
+}
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp
+ info_ptr)
+{
+#ifdef PNG_READ_pHYs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
+
+ if (info_ptr->x_pixels_per_unit != 0)
+ return ((float)((float)info_ptr->y_pixels_per_unit
+ /(float)info_ptr->x_pixels_per_unit));
+ }
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(info_ptr)
+#endif
+
+ return ((float)0.0);
+}
+#endif
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_fixed_point PNGAPI
+png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
+ png_const_inforp info_ptr)
+{
+#ifdef PNG_READ_pHYs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pHYs) != 0 &&
+ info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 &&
+ info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX &&
+ info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX)
+ {
+ png_fixed_point res;
+
+ png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed");
+
+ /* The following casts work because a PNG 4 byte integer only has a valid
+ * range of 0..2^31-1; otherwise the cast might overflow.
+ */
+ if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1,
+ (png_int_32)info_ptr->x_pixels_per_unit) != 0)
+ return res;
+ }
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(info_ptr)
+#endif
+
+ return 0;
+}
+#endif
+
+png_int_32 PNGAPI
+png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_oFFs) != 0)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
+
+ if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
+ return (info_ptr->x_offset);
+ }
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(info_ptr)
+#endif
+
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_oFFs) != 0)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
+
+ if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
+ return (info_ptr->y_offset);
+ }
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(info_ptr)
+#endif
+
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_oFFs) != 0)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels");
+
+ if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
+ return (info_ptr->x_offset);
+ }
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(info_ptr)
+#endif
+
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_oFFs) != 0)
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels");
+
+ if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
+ return (info_ptr->y_offset);
+ }
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(info_ptr)
+#endif
+
+ return (0);
+}
+
+#ifdef PNG_INCH_CONVERSIONS_SUPPORTED
+static png_uint_32
+ppi_from_ppm(png_uint_32 ppm)
+{
+#if 0
+ /* The conversion is *(2.54/100), in binary (32 digits):
+ * .00000110100000001001110101001001
+ */
+ png_uint_32 t1001, t1101;
+ ppm >>= 1; /* .1 */
+ t1001 = ppm + (ppm >> 3); /* .1001 */
+ t1101 = t1001 + (ppm >> 1); /* .1101 */
+ ppm >>= 20; /* .000000000000000000001 */
+ t1101 += t1101 >> 15; /* .1101000000000001101 */
+ t1001 >>= 11; /* .000000000001001 */
+ t1001 += t1001 >> 12; /* .000000000001001000000001001 */
+ ppm += t1001; /* .000000000001001000001001001 */
+ ppm += t1101; /* .110100000001001110101001001 */
+ return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */
+#else
+ /* The argument is a PNG unsigned integer, so it is not permitted
+ * to be bigger than 2^31.
+ */
+ png_fixed_point result;
+ if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
+ 5000) != 0)
+ return (png_uint_32)result;
+
+ /* Overflow. */
+ return 0;
+#endif
+}
+
+png_uint_32 PNGAPI
+png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr));
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr));
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr));
+}
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+static png_fixed_point
+png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
+{
+ /* Convert from metres * 1,000,000 to inches * 100,000, meters to
+ * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.
+ * Notice that this can overflow - a warning is output and 0 is
+ * returned.
+ */
+ return png_muldiv_warn(png_ptr, microns, 500, 127);
+}
+
+png_fixed_point PNGAPI
+png_get_x_offset_inches_fixed(png_const_structrp png_ptr,
+ png_const_inforp info_ptr)
+{
+ return png_fixed_inches_from_microns(png_ptr,
+ png_get_x_offset_microns(png_ptr, info_ptr));
+}
+#endif
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_fixed_point PNGAPI
+png_get_y_offset_inches_fixed(png_const_structrp png_ptr,
+ png_const_inforp info_ptr)
+{
+ return png_fixed_inches_from_microns(png_ptr,
+ png_get_y_offset_microns(png_ptr, info_ptr));
+}
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ /* To avoid the overflow do the conversion directly in floating
+ * point.
+ */
+ return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937);
+}
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ /* To avoid the overflow do the conversion directly in floating
+ * point.
+ */
+ return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937);
+}
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+ png_uint_32 retval = 0;
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ {
+ png_debug1(1, "in %s retrieval function", "pHYs");
+
+ if (res_x != NULL)
+ {
+ *res_x = info_ptr->x_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+
+ if (res_y != NULL)
+ {
+ *res_y = info_ptr->y_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+
+ if (unit_type != NULL)
+ {
+ *unit_type = (int)info_ptr->phys_unit_type;
+ retval |= PNG_INFO_pHYs;
+
+ if (*unit_type == 1)
+ {
+ if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
+ if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
+ }
+ }
+ }
+
+ return (retval);
+}
+#endif /* pHYs */
+#endif /* INCH_CONVERSIONS */
+
+/* png_get_channels really belongs in here, too, but it's been around longer */
+
+#endif /* EASY_ACCESS */
+
+
+png_byte PNGAPI
+png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->channels);
+
+ return (0);
+}
+
+#ifdef PNG_READ_SUPPORTED
+png_const_bytep PNGAPI
+png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->signature);
+
+ return (NULL);
+}
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+png_uint_32 PNGAPI
+png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_color_16p *background)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_bKGD) != 0 &&
+ background != NULL)
+ {
+ png_debug1(1, "in %s retrieval function", "bKGD");
+
+ *background = &(info_ptr->background);
+ return (PNG_INFO_bKGD);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the
+ * same time to correct the rgb grayscale coefficient defaults obtained from the
+ * cHRM chunk in 1.5.4
+ */
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ double *white_x, double *white_y, double *red_x, double *red_y,
+ double *green_x, double *green_y, double *blue_x, double *blue_y)
+{
+ /* Quiet API change: this code used to only return the end points if a cHRM
+ * chunk was present, but the end points can also come from iCCP or sRGB
+ * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and
+ * the png_set_ APIs merely check that set end points are mutually
+ * consistent.
+ */
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+ {
+ png_debug1(1, "in %s retrieval function", "cHRM");
+
+ if (white_x != NULL)
+ *white_x = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
+ if (white_y != NULL)
+ *white_y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
+ if (red_x != NULL)
+ *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
+ "cHRM red X");
+ if (red_y != NULL)
+ *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
+ "cHRM red Y");
+ if (green_x != NULL)
+ *green_x = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
+ if (green_y != NULL)
+ *green_y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
+ if (blue_x != NULL)
+ *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
+ "cHRM blue X");
+ if (blue_y != NULL)
+ *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
+ "cHRM blue Y");
+ return (PNG_INFO_cHRM);
+ }
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ double *red_X, double *red_Y, double *red_Z, double *green_X,
+ double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
+ double *blue_Z)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+ {
+ png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
+
+ if (red_X != NULL)
+ *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
+ "cHRM red X");
+ if (red_Y != NULL)
+ *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
+ "cHRM red Y");
+ if (red_Z != NULL)
+ *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
+ "cHRM red Z");
+ if (green_X != NULL)
+ *green_X = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
+ if (green_Y != NULL)
+ *green_Y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
+ if (green_Z != NULL)
+ *green_Z = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
+ if (blue_X != NULL)
+ *blue_X = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
+ if (blue_Y != NULL)
+ *blue_Y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
+ if (blue_Z != NULL)
+ *blue_Z = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
+ return (PNG_INFO_cHRM);
+ }
+
+ return (0);
+}
+# endif
+
+# ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
+ png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
+ png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
+ png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
+ png_fixed_point *int_blue_Z)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+ {
+ png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
+
+ if (int_red_X != NULL)
+ *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X;
+ if (int_red_Y != NULL)
+ *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y;
+ if (int_red_Z != NULL)
+ *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z;
+ if (int_green_X != NULL)
+ *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X;
+ if (int_green_Y != NULL)
+ *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y;
+ if (int_green_Z != NULL)
+ *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z;
+ if (int_blue_X != NULL)
+ *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X;
+ if (int_blue_Y != NULL)
+ *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y;
+ if (int_blue_Z != NULL)
+ *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z;
+ return (PNG_INFO_cHRM);
+ }
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
+ png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
+ png_fixed_point *blue_x, png_fixed_point *blue_y)
+{
+ png_debug1(1, "in %s retrieval function", "cHRM");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+ {
+ if (white_x != NULL)
+ *white_x = info_ptr->colorspace.end_points_xy.whitex;
+ if (white_y != NULL)
+ *white_y = info_ptr->colorspace.end_points_xy.whitey;
+ if (red_x != NULL)
+ *red_x = info_ptr->colorspace.end_points_xy.redx;
+ if (red_y != NULL)
+ *red_y = info_ptr->colorspace.end_points_xy.redy;
+ if (green_x != NULL)
+ *green_x = info_ptr->colorspace.end_points_xy.greenx;
+ if (green_y != NULL)
+ *green_y = info_ptr->colorspace.end_points_xy.greeny;
+ if (blue_x != NULL)
+ *blue_x = info_ptr->colorspace.end_points_xy.bluex;
+ if (blue_y != NULL)
+ *blue_y = info_ptr->colorspace.end_points_xy.bluey;
+ return (PNG_INFO_cHRM);
+ }
+
+ return (0);
+}
+# endif
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+# ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *file_gamma)
+{
+ png_debug1(1, "in %s retrieval function", "gAMA");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+ file_gamma != NULL)
+ {
+ *file_gamma = info_ptr->colorspace.gamma;
+ return (PNG_INFO_gAMA);
+ }
+
+ return (0);
+}
+# endif
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ double *file_gamma)
+{
+ png_debug1(1, "in %s retrieval function", "gAMA(float)");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+ file_gamma != NULL)
+ {
+ *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
+ "png_get_gAMA");
+ return (PNG_INFO_gAMA);
+ }
+
+ return (0);
+}
+# endif
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ int *file_srgb_intent)
+{
+ png_debug1(1, "in %s retrieval function", "sRGB");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL)
+ {
+ *file_srgb_intent = info_ptr->colorspace.rendering_intent;
+ return (PNG_INFO_sRGB);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+png_uint_32 PNGAPI
+png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_charpp name, int *compression_type,
+ png_bytepp profile, png_uint_32 *proflen)
+{
+ png_debug1(1, "in %s retrieval function", "iCCP");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_iCCP) != 0 &&
+ name != NULL && compression_type != NULL && profile != NULL &&
+ proflen != NULL)
+ {
+ *name = info_ptr->iccp_name;
+ *profile = info_ptr->iccp_profile;
+ *proflen = png_get_uint_32(info_ptr->iccp_profile);
+ /* This is somewhat irrelevant since the profile data returned has
+ * actually been uncompressed.
+ */
+ *compression_type = PNG_COMPRESSION_TYPE_BASE;
+ return (PNG_INFO_iCCP);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+int PNGAPI
+png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_sPLT_tpp spalettes)
+{
+ if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
+ {
+ *spalettes = info_ptr->splt_palettes;
+ return info_ptr->splt_palettes_num;
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_eXIf_SUPPORTED
+png_uint_32 PNGAPI
+png_get_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_bytep *exif)
+{
+ png_warning(png_ptr, "png_get_eXIf does not work; use png_get_eXIf_1");
+ PNG_UNUSED(info_ptr)
+ PNG_UNUSED(exif)
+ return 0;
+}
+
+png_uint_32 PNGAPI
+png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_uint_32 *num_exif, png_bytep *exif)
+{
+ png_debug1(1, "in %s retrieval function", "eXIf");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_eXIf) != 0 && exif != NULL)
+ {
+ *num_exif = info_ptr->num_exif;
+ *exif = info_ptr->exif;
+ return (PNG_INFO_eXIf);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+png_uint_32 PNGAPI
+png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_uint_16p *hist)
+{
+ png_debug1(1, "in %s retrieval function", "hIST");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL)
+ {
+ *hist = info_ptr->hist;
+ return (PNG_INFO_hIST);
+ }
+
+ return (0);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_uint_32 *width, png_uint_32 *height, int *bit_depth,
+ int *color_type, int *interlace_type, int *compression_type,
+ int *filter_type)
+{
+ png_debug1(1, "in %s retrieval function", "IHDR");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return (0);
+
+ if (width != NULL)
+ *width = info_ptr->width;
+
+ if (height != NULL)
+ *height = info_ptr->height;
+
+ if (bit_depth != NULL)
+ *bit_depth = info_ptr->bit_depth;
+
+ if (color_type != NULL)
+ *color_type = info_ptr->color_type;
+
+ if (compression_type != NULL)
+ *compression_type = info_ptr->compression_type;
+
+ if (filter_type != NULL)
+ *filter_type = info_ptr->filter_type;
+
+ if (interlace_type != NULL)
+ *interlace_type = info_ptr->interlace_type;
+
+ /* This is redundant if we can be sure that the info_ptr values were all
+ * assigned in png_set_IHDR(). We do the check anyhow in case an
+ * application has ignored our advice not to mess with the members
+ * of info_ptr directly.
+ */
+ png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
+ info_ptr->compression_type, info_ptr->filter_type);
+
+ return (1);
+}
+
+#ifdef PNG_oFFs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
+{
+ png_debug1(1, "in %s retrieval function", "oFFs");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_oFFs) != 0 &&
+ offset_x != NULL && offset_y != NULL && unit_type != NULL)
+ {
+ *offset_x = info_ptr->x_offset;
+ *offset_y = info_ptr->y_offset;
+ *unit_type = (int)info_ptr->offset_unit_type;
+ return (PNG_INFO_oFFs);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
+ png_charp *units, png_charpp *params)
+{
+ png_debug1(1, "in %s retrieval function", "pCAL");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pCAL) != 0 &&
+ purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
+ nparams != NULL && units != NULL && params != NULL)
+ {
+ *purpose = info_ptr->pcal_purpose;
+ *X0 = info_ptr->pcal_X0;
+ *X1 = info_ptr->pcal_X1;
+ *type = (int)info_ptr->pcal_type;
+ *nparams = (int)info_ptr->pcal_nparams;
+ *units = info_ptr->pcal_units;
+ *params = info_ptr->pcal_params;
+ return (PNG_INFO_pCAL);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+# ifdef PNG_FIXED_POINT_SUPPORTED
+# if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
+ defined(PNG_FLOATING_POINT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ int *unit, png_fixed_point *width, png_fixed_point *height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL) != 0)
+ {
+ *unit = info_ptr->scal_unit;
+ /*TODO: make this work without FP support; the API is currently eliminated
+ * if neither floating point APIs nor internal floating point arithmetic
+ * are enabled.
+ */
+ *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
+ *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
+ "sCAL height");
+ return (PNG_INFO_sCAL);
+ }
+
+ return(0);
+}
+# endif /* FLOATING_ARITHMETIC */
+# endif /* FIXED_POINT */
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ int *unit, double *width, double *height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL) != 0)
+ {
+ *unit = info_ptr->scal_unit;
+ *width = atof(info_ptr->scal_s_width);
+ *height = atof(info_ptr->scal_s_height);
+ return (PNG_INFO_sCAL);
+ }
+
+ return(0);
+}
+# endif /* FLOATING POINT */
+png_uint_32 PNGAPI
+png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ int *unit, png_charpp width, png_charpp height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL) != 0)
+ {
+ *unit = info_ptr->scal_unit;
+ *width = info_ptr->scal_s_width;
+ *height = info_ptr->scal_s_height;
+ return (PNG_INFO_sCAL);
+ }
+
+ return(0);
+}
+#endif /* sCAL */
+
+#ifdef PNG_pHYs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+ png_uint_32 retval = 0;
+
+ png_debug1(1, "in %s retrieval function", "pHYs");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ {
+ if (res_x != NULL)
+ {
+ *res_x = info_ptr->x_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+
+ if (res_y != NULL)
+ {
+ *res_y = info_ptr->y_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+
+ if (unit_type != NULL)
+ {
+ *unit_type = (int)info_ptr->phys_unit_type;
+ retval |= PNG_INFO_pHYs;
+ }
+ }
+
+ return (retval);
+}
+#endif /* pHYs */
+
+png_uint_32 PNGAPI
+png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_colorp *palette, int *num_palette)
+{
+ png_debug1(1, "in %s retrieval function", "PLTE");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_PLTE) != 0 && palette != NULL)
+ {
+ *palette = info_ptr->palette;
+ *num_palette = info_ptr->num_palette;
+ png_debug1(3, "num_palette = %d", *num_palette);
+ return (PNG_INFO_PLTE);
+ }
+
+ return (0);
+}
+
+#ifdef PNG_sBIT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_color_8p *sig_bit)
+{
+ png_debug1(1, "in %s retrieval function", "sBIT");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL)
+ {
+ *sig_bit = &(info_ptr->sig_bit);
+ return (PNG_INFO_sBIT);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+int PNGAPI
+png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_textp *text_ptr, int *num_text)
+{
+ if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
+ {
+ png_debug1(1, "in 0x%lx retrieval function",
+ (unsigned long)png_ptr->chunk_name);
+
+ if (text_ptr != NULL)
+ *text_ptr = info_ptr->text;
+
+ if (num_text != NULL)
+ *num_text = info_ptr->num_text;
+
+ return info_ptr->num_text;
+ }
+
+ if (num_text != NULL)
+ *num_text = 0;
+
+ return(0);
+}
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+png_uint_32 PNGAPI
+png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_timep *mod_time)
+{
+ png_debug1(1, "in %s retrieval function", "tIME");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL)
+ {
+ *mod_time = &(info_ptr->mod_time);
+ return (PNG_INFO_tIME);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+png_uint_32 PNGAPI
+png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
+{
+ png_uint_32 retval = 0;
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_tRNS) != 0)
+ {
+ png_debug1(1, "in %s retrieval function", "tRNS");
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (trans_alpha != NULL)
+ {
+ *trans_alpha = info_ptr->trans_alpha;
+ retval |= PNG_INFO_tRNS;
+ }
+
+ if (trans_color != NULL)
+ *trans_color = &(info_ptr->trans_color);
+ }
+
+ else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
+ {
+ if (trans_color != NULL)
+ {
+ *trans_color = &(info_ptr->trans_color);
+ retval |= PNG_INFO_tRNS;
+ }
+
+ if (trans_alpha != NULL)
+ *trans_alpha = NULL;
+ }
+
+ if (num_trans != NULL)
+ {
+ *num_trans = info_ptr->num_trans;
+ retval |= PNG_INFO_tRNS;
+ }
+ }
+
+ return (retval);
+}
+#endif
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+int PNGAPI
+png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_unknown_chunkpp unknowns)
+{
+ if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
+ {
+ *unknowns = info_ptr->unknown_chunks;
+ return info_ptr->unknown_chunks_num;
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+png_byte PNGAPI
+png_get_rgb_to_gray_status (png_const_structrp png_ptr)
+{
+ return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
+}
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+png_voidp PNGAPI
+png_get_user_chunk_ptr(png_const_structrp png_ptr)
+{
+ return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
+}
+#endif
+
+png_size_t PNGAPI
+png_get_compression_buffer_size(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return 0;
+
+#ifdef PNG_WRITE_SUPPORTED
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+#endif
+ {
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ return png_ptr->IDAT_read_size;
+#else
+ return PNG_IDAT_READ_SIZE;
+#endif
+ }
+
+#ifdef PNG_WRITE_SUPPORTED
+ else
+ return png_ptr->zbuffer_size;
+#endif
+}
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* These functions were added to libpng 1.2.6 and were enabled
+ * by default in libpng-1.4.0 */
+png_uint_32 PNGAPI
+png_get_user_width_max (png_const_structrp png_ptr)
+{
+ return (png_ptr ? png_ptr->user_width_max : 0);
+}
+
+png_uint_32 PNGAPI
+png_get_user_height_max (png_const_structrp png_ptr)
+{
+ return (png_ptr ? png_ptr->user_height_max : 0);
+}
+
+/* This function was added to libpng 1.4.0 */
+png_uint_32 PNGAPI
+png_get_chunk_cache_max (png_const_structrp png_ptr)
+{
+ return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
+}
+
+/* This function was added to libpng 1.4.1 */
+png_alloc_size_t PNGAPI
+png_get_chunk_malloc_max (png_const_structrp png_ptr)
+{
+ return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
+}
+#endif /* SET_USER_LIMITS */
+
+/* These functions were added to libpng 1.4.0 */
+#ifdef PNG_IO_STATE_SUPPORTED
+png_uint_32 PNGAPI
+png_get_io_state (png_const_structrp png_ptr)
+{
+ return png_ptr->io_state;
+}
+
+png_uint_32 PNGAPI
+png_get_io_chunk_type (png_const_structrp png_ptr)
+{
+ return png_ptr->chunk_name;
+}
+#endif /* IO_STATE */
+
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+# ifdef PNG_GET_PALETTE_MAX_SUPPORTED
+int PNGAPI
+png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return png_ptr->num_palette_max;
+
+ return (-1);
+}
+# endif
+#endif
+
+#endif /* READ || WRITE */
diff --git a/xs/src/png/libpng/pnginfo.h b/xs/src/png/libpng/pnginfo.h
new file mode 100644
index 000000000..d5f6149db
--- /dev/null
+++ b/xs/src/png/libpng/pnginfo.h
@@ -0,0 +1,267 @@
+
+/* pnginfo.h - header file for PNG reference library
+ *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+ /* png_info is a structure that holds the information in a PNG file so
+ * that the application can find out the characteristics of the image.
+ * If you are reading the file, this structure will tell you what is
+ * in the PNG file. If you are writing the file, fill in the information
+ * you want to put into the PNG file, using png_set_*() functions, then
+ * call png_write_info().
+ *
+ * The names chosen should be very close to the PNG specification, so
+ * consult that document for information about the meaning of each field.
+ *
+ * With libpng < 0.95, it was only possible to directly set and read the
+ * the values in the png_info_struct, which meant that the contents and
+ * order of the values had to remain fixed. With libpng 0.95 and later,
+ * however, there are now functions that abstract the contents of
+ * png_info_struct from the application, so this makes it easier to use
+ * libpng with dynamic libraries, and even makes it possible to use
+ * libraries that don't have all of the libpng ancillary chunk-handing
+ * functionality. In libpng-1.5.0 this was moved into a separate private
+ * file that is not visible to applications.
+ *
+ * The following members may have allocated storage attached that should be
+ * cleaned up before the structure is discarded: palette, trans, text,
+ * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
+ * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
+ * are automatically freed when the info structure is deallocated, if they were
+ * allocated internally by libpng. This behavior can be changed by means
+ * of the png_data_freer() function.
+ *
+ * More allocation details: all the chunk-reading functions that
+ * change these members go through the corresponding png_set_*
+ * functions. A function to clear these members is available: see
+ * png_free_data(). The png_set_* functions do not depend on being
+ * able to point info structure members to any of the storage they are
+ * passed (they make their own copies), EXCEPT that the png_set_text
+ * functions use the same storage passed to them in the text_ptr or
+ * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
+ * functions do not make their own copies.
+ */
+#ifndef PNGINFO_H
+#define PNGINFO_H
+
+struct png_info_def
+{
+ /* The following are necessary for every PNG file */
+ png_uint_32 width; /* width of image in pixels (from IHDR) */
+ png_uint_32 height; /* height of image in pixels (from IHDR) */
+ png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
+ png_size_t rowbytes; /* bytes needed to hold an untransformed row */
+ png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
+ png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
+ png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
+ png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
+ png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
+ /* The following three should have been named *_method not *_type */
+ png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
+ png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
+ png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+
+ /* The following are set by png_set_IHDR, called from the application on
+ * write, but the are never actually used by the write code.
+ */
+ png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */
+ png_byte pixel_depth; /* number of bits per pixel */
+ png_byte spare_byte; /* to align the data, and for future use */
+
+#ifdef PNG_READ_SUPPORTED
+ /* This is never set during write */
+ png_byte signature[8]; /* magic bytes read by libpng from start of file */
+#endif
+
+ /* The rest of the data is optional. If you are reading, check the
+ * valid field to see if the information in these are valid. If you
+ * are writing, set the valid field to those chunks you want written,
+ * and initialize the appropriate fields below.
+ */
+
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+ /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are
+ * defined. When COLORSPACE is switched on all the colorspace-defining
+ * chunks should be enabled, when GAMMA is switched on all the gamma-defining
+ * chunks should be enabled. If this is not done it becomes possible to read
+ * inconsistent PNG files and assign a probably incorrect interpretation to
+ * the information. (In other words, by carefully choosing which chunks to
+ * recognize the system configuration can select an interpretation for PNG
+ * files containing ambiguous data and this will result in inconsistent
+ * behavior between different libpng builds!)
+ */
+ png_colorspace colorspace;
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+ /* iCCP chunk data. */
+ png_charp iccp_name; /* profile name */
+ png_bytep iccp_profile; /* International Color Consortium profile data */
+ png_uint_32 iccp_proflen; /* ICC profile data length */
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+ /* The tEXt, and zTXt chunks contain human-readable textual data in
+ * uncompressed, compressed, and optionally compressed forms, respectively.
+ * The data in "text" is an array of pointers to uncompressed,
+ * null-terminated C strings. Each chunk has a keyword that describes the
+ * textual data contained in that chunk. Keywords are not required to be
+ * unique, and the text string may be empty. Any number of text chunks may
+ * be in an image.
+ */
+ int num_text; /* number of comments read or comments to write */
+ int max_text; /* current size of text array */
+ png_textp text; /* array of comments read or comments to write */
+#endif /* TEXT */
+
+#ifdef PNG_tIME_SUPPORTED
+ /* The tIME chunk holds the last time the displayed image data was
+ * modified. See the png_time struct for the contents of this struct.
+ */
+ png_time mod_time;
+#endif
+
+#ifdef PNG_sBIT_SUPPORTED
+ /* The sBIT chunk specifies the number of significant high-order bits
+ * in the pixel data. Values are in the range [1, bit_depth], and are
+ * only specified for the channels in the pixel data. The contents of
+ * the low-order bits is not specified. Data is valid if
+ * (valid & PNG_INFO_sBIT) is non-zero.
+ */
+ png_color_8 sig_bit; /* significant bits in color channels */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
+defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* The tRNS chunk supplies transparency data for paletted images and
+ * other image types that don't need a full alpha channel. There are
+ * "num_trans" transparency values for a paletted image, stored in the
+ * same order as the palette colors, starting from index 0. Values
+ * for the data are in the range [0, 255], ranging from fully transparent
+ * to fully opaque, respectively. For non-paletted images, there is a
+ * single color specified that should be treated as fully transparent.
+ * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
+ */
+ png_bytep trans_alpha; /* alpha values for paletted image */
+ png_color_16 trans_color; /* transparent color for non-palette image */
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* The bKGD chunk gives the suggested image background color if the
+ * display program does not have its own background color and the image
+ * is needs to composited onto a background before display. The colors
+ * in "background" are normally in the same color space/depth as the
+ * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
+ */
+ png_color_16 background;
+#endif
+
+#ifdef PNG_oFFs_SUPPORTED
+ /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
+ * and downwards from the top-left corner of the display, page, or other
+ * application-specific co-ordinate space. See the PNG_OFFSET_ defines
+ * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
+ */
+ png_int_32 x_offset; /* x offset on page */
+ png_int_32 y_offset; /* y offset on page */
+ png_byte offset_unit_type; /* offset units type */
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+ /* The pHYs chunk gives the physical pixel density of the image for
+ * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
+ * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
+ */
+ png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
+ png_uint_32 y_pixels_per_unit; /* vertical pixel density */
+ png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
+#endif
+
+#ifdef PNG_eXIf_SUPPORTED
+ int num_exif; /* Added at libpng-1.6.31 */
+ png_bytep exif;
+# ifdef PNG_READ_eXIf_SUPPORTED
+ png_bytep eXIf_buf; /* Added at libpng-1.6.32 */
+# endif
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+ /* The hIST chunk contains the relative frequency or importance of the
+ * various palette entries, so that a viewer can intelligently select a
+ * reduced-color palette, if required. Data is an array of "num_palette"
+ * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
+ * is non-zero.
+ */
+ png_uint_16p hist;
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+ /* The pCAL chunk describes a transformation between the stored pixel
+ * values and original physical data values used to create the image.
+ * The integer range [0, 2^bit_depth - 1] maps to the floating-point
+ * range given by [pcal_X0, pcal_X1], and are further transformed by a
+ * (possibly non-linear) transformation function given by "pcal_type"
+ * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_
+ * defines below, and the PNG-Group's PNG extensions document for a
+ * complete description of the transformations and how they should be
+ * implemented, and for a description of the ASCII parameter strings.
+ * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
+ */
+ png_charp pcal_purpose; /* pCAL chunk description string */
+ png_int_32 pcal_X0; /* minimum value */
+ png_int_32 pcal_X1; /* maximum value */
+ png_charp pcal_units; /* Latin-1 string giving physical units */
+ png_charpp pcal_params; /* ASCII strings containing parameter values */
+ png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */
+ png_byte pcal_nparams; /* number of parameters given in pcal_params */
+#endif
+
+/* New members added in libpng-1.0.6 */
+ png_uint_32 free_me; /* flags items libpng is responsible for freeing */
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+ /* Storage for unknown chunks that the library doesn't recognize. */
+ png_unknown_chunkp unknown_chunks;
+
+ /* The type of this field is limited by the type of
+ * png_struct::user_chunk_cache_max, else overflow can occur.
+ */
+ int unknown_chunks_num;
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+ /* Data on sPLT chunks (there may be more than one). */
+ png_sPLT_tp splt_palettes;
+ int splt_palettes_num; /* Match type returned by png_get API */
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+ /* The sCAL chunk describes the actual physical dimensions of the
+ * subject matter of the graphic. The chunk contains a unit specification
+ * a byte value, and two ASCII strings representing floating-point
+ * values. The values are width and height corresponsing to one pixel
+ * in the image. Data values are valid if (valid & PNG_INFO_sCAL) is
+ * non-zero.
+ */
+ png_byte scal_unit; /* unit of physical scale */
+ png_charp scal_s_width; /* string containing height */
+ png_charp scal_s_height; /* string containing width */
+#endif
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+ /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)
+ non-zero */
+ /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
+ png_bytepp row_pointers; /* the image bits */
+#endif
+
+};
+#endif /* PNGINFO_H */
diff --git a/xs/src/png/libpng/pngmem.c b/xs/src/png/libpng/pngmem.c
new file mode 100644
index 000000000..ff3ef7e88
--- /dev/null
+++ b/xs/src/png/libpng/pngmem.c
@@ -0,0 +1,284 @@
+
+/* pngmem.c - stub functions for memory allocation
+ *
+ * Last changed in libpng 1.6.26 [October 20, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all memory allocation. Users who
+ * need special memory handling are expected to supply replacement
+ * functions for png_malloc() and png_free(), and to use
+ * png_create_read_struct_2() and png_create_write_struct_2() to
+ * identify the replacement functions.
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Free a png_struct */
+void /* PRIVATE */
+png_destroy_png_struct(png_structrp png_ptr)
+{
+ if (png_ptr != NULL)
+ {
+ /* png_free might call png_error and may certainly call
+ * png_get_mem_ptr, so fake a temporary png_struct to support this.
+ */
+ png_struct dummy_struct = *png_ptr;
+ memset(png_ptr, 0, (sizeof *png_ptr));
+ png_free(&dummy_struct, png_ptr);
+
+# ifdef PNG_SETJMP_SUPPORTED
+ /* We may have a jmp_buf left to deallocate. */
+ png_free_jmpbuf(&dummy_struct);
+# endif
+ }
+}
+
+/* Allocate memory. For reasonable files, size should never exceed
+ * 64K. However, zlib may allocate more than 64K if you don't tell
+ * it not to. See zconf.h and png.h for more information. zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ */
+PNG_FUNCTION(png_voidp,PNGAPI
+png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
+{
+ png_voidp ret;
+
+ ret = png_malloc(png_ptr, size);
+
+ if (ret != NULL)
+ memset(ret, 0, size);
+
+ return ret;
+}
+
+/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of
+ * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.
+ * Checking and error handling must happen outside this routine; it returns NULL
+ * if the allocation cannot be done (for any reason.)
+ */
+PNG_FUNCTION(png_voidp /* PRIVATE */,
+png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
+ PNG_ALLOCATED)
+{
+ /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
+ * allocators have also been removed in 1.6.0, so any 16-bit system now has
+ * to implement a user memory handler. This checks to be sure it isn't
+ * called with big numbers.
+ */
+#ifndef PNG_USER_MEM_SUPPORTED
+ PNG_UNUSED(png_ptr)
+#endif
+
+ /* Some compilers complain that this is always true. However, it
+ * can be false when integer overflow happens.
+ */
+ if (size > 0 && size <= PNG_SIZE_MAX
+# ifdef PNG_MAX_MALLOC_64K
+ && size <= 65536U
+# endif
+ )
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
+ return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
+
+ else
+#endif
+ return malloc((size_t)size); /* checked for truncation above */
+ }
+
+ else
+ return NULL;
+}
+
+#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
+ defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
+/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
+ * that arises because of the checks in png_realloc_array that are repeated in
+ * png_malloc_array.
+ */
+static png_voidp
+png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
+ size_t element_size)
+{
+ png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */
+
+ if (req <= PNG_SIZE_MAX/element_size)
+ return png_malloc_base(png_ptr, req * element_size);
+
+ /* The failure case when the request is too large */
+ return NULL;
+}
+
+PNG_FUNCTION(png_voidp /* PRIVATE */,
+png_malloc_array,(png_const_structrp png_ptr, int nelements,
+ size_t element_size),PNG_ALLOCATED)
+{
+ if (nelements <= 0 || element_size == 0)
+ png_error(png_ptr, "internal error: array alloc");
+
+ return png_malloc_array_checked(png_ptr, nelements, element_size);
+}
+
+PNG_FUNCTION(png_voidp /* PRIVATE */,
+png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
+ int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
+{
+ /* These are internal errors: */
+ if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
+ (old_array == NULL && old_elements > 0))
+ png_error(png_ptr, "internal error: array realloc");
+
+ /* Check for overflow on the elements count (so the caller does not have to
+ * check.)
+ */
+ if (add_elements <= INT_MAX - old_elements)
+ {
+ png_voidp new_array = png_malloc_array_checked(png_ptr,
+ old_elements+add_elements, element_size);
+
+ if (new_array != NULL)
+ {
+ /* Because png_malloc_array worked the size calculations below cannot
+ * overflow.
+ */
+ if (old_elements > 0)
+ memcpy(new_array, old_array, element_size*(unsigned)old_elements);
+
+ memset((char*)new_array + element_size*(unsigned)old_elements, 0,
+ element_size*(unsigned)add_elements);
+
+ return new_array;
+ }
+ }
+
+ return NULL; /* error */
+}
+#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */
+
+/* Various functions that have different error handling are derived from this.
+ * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
+ * function png_malloc_default is also provided.
+ */
+PNG_FUNCTION(png_voidp,PNGAPI
+png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
+{
+ png_voidp ret;
+
+ if (png_ptr == NULL)
+ return NULL;
+
+ ret = png_malloc_base(png_ptr, size);
+
+ if (ret == NULL)
+ png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */
+
+ return ret;
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+PNG_FUNCTION(png_voidp,PNGAPI
+png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
+ PNG_ALLOCATED PNG_DEPRECATED)
+{
+ png_voidp ret;
+
+ if (png_ptr == NULL)
+ return NULL;
+
+ /* Passing 'NULL' here bypasses the application provided memory handler. */
+ ret = png_malloc_base(NULL/*use malloc*/, size);
+
+ if (ret == NULL)
+ png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */
+
+ return ret;
+}
+#endif /* USER_MEM */
+
+/* This function was added at libpng version 1.2.3. The png_malloc_warn()
+ * function will issue a png_warning and return NULL instead of issuing a
+ * png_error, if it fails to allocate the requested memory.
+ */
+PNG_FUNCTION(png_voidp,PNGAPI
+png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
+ PNG_ALLOCATED)
+{
+ if (png_ptr != NULL)
+ {
+ png_voidp ret = png_malloc_base(png_ptr, size);
+
+ if (ret != NULL)
+ return ret;
+
+ png_warning(png_ptr, "Out of memory");
+ }
+
+ return NULL;
+}
+
+/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
+ * without taking any action.
+ */
+void PNGAPI
+png_free(png_const_structrp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr->free_fn != NULL)
+ png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr);
+
+ else
+ png_free_default(png_ptr, ptr);
+}
+
+PNG_FUNCTION(void,PNGAPI
+png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+#endif /* USER_MEM */
+
+ free(ptr);
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* This function is called when the application wants to use another method
+ * of allocating and freeing memory.
+ */
+void PNGAPI
+png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+ malloc_fn, png_free_ptr free_fn)
+{
+ if (png_ptr != NULL)
+ {
+ png_ptr->mem_ptr = mem_ptr;
+ png_ptr->malloc_fn = malloc_fn;
+ png_ptr->free_fn = free_fn;
+ }
+}
+
+/* This function returns a pointer to the mem_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_mem_ptr(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return NULL;
+
+ return png_ptr->mem_ptr;
+}
+#endif /* USER_MEM */
+#endif /* READ || WRITE */
diff --git a/xs/src/png/libpng/pngpread.c b/xs/src/png/libpng/pngpread.c
new file mode 100644
index 000000000..fbe361dc3
--- /dev/null
+++ b/xs/src/png/libpng/pngpread.c
@@ -0,0 +1,1096 @@
+
+/* pngpread.c - read a png file in push mode
+ *
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+
+/* Push model modes */
+#define PNG_READ_SIG_MODE 0
+#define PNG_READ_CHUNK_MODE 1
+#define PNG_READ_IDAT_MODE 2
+#define PNG_READ_tEXt_MODE 4
+#define PNG_READ_zTXt_MODE 5
+#define PNG_READ_DONE_MODE 6
+#define PNG_READ_iTXt_MODE 7
+#define PNG_ERROR_MODE 8
+
+#define PNG_PUSH_SAVE_BUFFER_IF_FULL \
+if (png_ptr->push_length + 4 > png_ptr->buffer_size) \
+ { png_push_save_buffer(png_ptr); return; }
+#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \
+if (png_ptr->buffer_size < N) \
+ { png_push_save_buffer(png_ptr); return; }
+
+void PNGAPI
+png_process_data(png_structrp png_ptr, png_inforp info_ptr,
+ png_bytep buffer, png_size_t buffer_size)
+{
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_push_restore_buffer(png_ptr, buffer, buffer_size);
+
+ while (png_ptr->buffer_size)
+ {
+ png_process_some_data(png_ptr, info_ptr);
+ }
+}
+
+png_size_t PNGAPI
+png_process_data_pause(png_structrp png_ptr, int save)
+{
+ if (png_ptr != NULL)
+ {
+ /* It's easiest for the caller if we do the save; then the caller doesn't
+ * have to supply the same data again:
+ */
+ if (save != 0)
+ png_push_save_buffer(png_ptr);
+ else
+ {
+ /* This includes any pending saved bytes: */
+ png_size_t remaining = png_ptr->buffer_size;
+ png_ptr->buffer_size = 0;
+
+ /* So subtract the saved buffer size, unless all the data
+ * is actually 'saved', in which case we just return 0
+ */
+ if (png_ptr->save_buffer_size < remaining)
+ return remaining - png_ptr->save_buffer_size;
+ }
+ }
+
+ return 0;
+}
+
+png_uint_32 PNGAPI
+png_process_data_skip(png_structrp png_ptr)
+{
+/* TODO: Deprecate and remove this API.
+ * Somewhere the implementation of this seems to have been lost,
+ * or abandoned. It was only to support some internal back-door access
+ * to png_struct) in libpng-1.4.x.
+ */
+ png_app_warning(png_ptr,
+"png_process_data_skip is not implemented in any current version of libpng");
+ return 0;
+}
+
+/* What we do with the incoming data depends on what we were previously
+ * doing before we ran out of data...
+ */
+void /* PRIVATE */
+png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
+{
+ if (png_ptr == NULL)
+ return;
+
+ switch (png_ptr->process_mode)
+ {
+ case PNG_READ_SIG_MODE:
+ {
+ png_push_read_sig(png_ptr, info_ptr);
+ break;
+ }
+
+ case PNG_READ_CHUNK_MODE:
+ {
+ png_push_read_chunk(png_ptr, info_ptr);
+ break;
+ }
+
+ case PNG_READ_IDAT_MODE:
+ {
+ png_push_read_IDAT(png_ptr);
+ break;
+ }
+
+ default:
+ {
+ png_ptr->buffer_size = 0;
+ break;
+ }
+ }
+}
+
+/* Read any remaining signature bytes from the stream and compare them with
+ * the correct PNG signature. It is possible that this routine is called
+ * with bytes already read from the signature, either because they have been
+ * checked by the calling application, or because of multiple calls to this
+ * routine.
+ */
+void /* PRIVATE */
+png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */
+ num_to_check = 8 - num_checked;
+
+ if (png_ptr->buffer_size < num_to_check)
+ {
+ num_to_check = png_ptr->buffer_size;
+ }
+
+ png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
+ num_to_check);
+ png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
+
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+ {
+ if (num_checked < 4 &&
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_error(png_ptr, "Not a PNG file");
+
+ else
+ png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+ }
+ else
+ {
+ if (png_ptr->sig_bytes >= 8)
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+ }
+}
+
+void /* PRIVATE */
+png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_uint_32 chunk_name;
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ int keep; /* unknown handling method */
+#endif
+
+ /* First we make sure we have enough data for the 4-byte chunk name
+ * and the 4-byte chunk length before proceeding with decoding the
+ * chunk data. To fully decode each of these chunks, we also make
+ * sure we have enough data in the buffer for the 4-byte CRC at the
+ * end of every chunk (except IDAT, which is handled separately).
+ */
+ if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
+ {
+ png_byte chunk_length[4];
+ png_byte chunk_tag[4];
+
+ PNG_PUSH_SAVE_BUFFER_IF_LT(8)
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, chunk_tag, 4);
+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+ png_check_chunk_length(png_ptr, png_ptr->push_length);
+ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+ }
+
+ chunk_name = png_ptr->chunk_name;
+
+ if (chunk_name == png_IDAT)
+ {
+ if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
+ /* If we reach an IDAT chunk, this means we have read all of the
+ * header chunks, and we can start reading the image (or if this
+ * is called after the image has been read - we have an error).
+ */
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_error(png_ptr, "Missing IHDR before IDAT");
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ (png_ptr->mode & PNG_HAVE_PLTE) == 0)
+ png_error(png_ptr, "Missing PLTE before IDAT");
+
+ png_ptr->process_mode = PNG_READ_IDAT_MODE;
+
+ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0)
+ if (png_ptr->push_length == 0)
+ return;
+
+ png_ptr->mode |= PNG_HAVE_IDAT;
+
+ if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
+ png_benign_error(png_ptr, "Too many IDATs found");
+ }
+
+ if (chunk_name == png_IHDR)
+ {
+ if (png_ptr->push_length != 13)
+ png_error(png_ptr, "Invalid IHDR length");
+
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+ else if (chunk_name == png_IEND)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
+
+ png_ptr->process_mode = PNG_READ_DONE_MODE;
+ png_push_have_end(png_ptr, info_ptr);
+ }
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);
+
+ if (chunk_name == png_PLTE)
+ png_ptr->mode |= PNG_HAVE_PLTE;
+ }
+#endif
+
+ else if (chunk_name == png_PLTE)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+ else if (chunk_name == png_IDAT)
+ {
+ png_ptr->idat_size = png_ptr->push_length;
+ png_ptr->process_mode = PNG_READ_IDAT_MODE;
+ png_push_have_info(png_ptr, info_ptr);
+ png_ptr->zstream.avail_out =
+ (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
+ png_ptr->iwidth) + 1;
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ return;
+ }
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (png_ptr->chunk_name == png_gAMA)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (png_ptr->chunk_name == png_sBIT)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (png_ptr->chunk_name == png_cHRM)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (chunk_name == png_sRGB)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (png_ptr->chunk_name == png_iCCP)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (chunk_name == png_sPLT)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (chunk_name == png_tRNS)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (chunk_name == png_bKGD)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (chunk_name == png_hIST)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (chunk_name == png_pHYs)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (chunk_name == png_oFFs)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (chunk_name == png_pCAL)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (chunk_name == png_sCAL)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (chunk_name == png_tIME)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (chunk_name == png_tEXt)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (chunk_name == png_zTXt)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (chunk_name == png_iTXt)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+
+ else
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_FULL
+ png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
+ }
+
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+}
+
+void PNGCBAPI
+png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
+{
+ png_bytep ptr;
+
+ if (png_ptr == NULL)
+ return;
+
+ ptr = buffer;
+ if (png_ptr->save_buffer_size != 0)
+ {
+ png_size_t save_size;
+
+ if (length < png_ptr->save_buffer_size)
+ save_size = length;
+
+ else
+ save_size = png_ptr->save_buffer_size;
+
+ memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
+ length -= save_size;
+ ptr += save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (length != 0 && png_ptr->current_buffer_size != 0)
+ {
+ png_size_t save_size;
+
+ if (length < png_ptr->current_buffer_size)
+ save_size = length;
+
+ else
+ save_size = png_ptr->current_buffer_size;
+
+ memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+}
+
+void /* PRIVATE */
+png_push_save_buffer(png_structrp png_ptr)
+{
+ if (png_ptr->save_buffer_size != 0)
+ {
+ if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
+ {
+ png_size_t i, istop;
+ png_bytep sp;
+ png_bytep dp;
+
+ istop = png_ptr->save_buffer_size;
+ for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
+ i < istop; i++, sp++, dp++)
+ {
+ *dp = *sp;
+ }
+ }
+ }
+ if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
+ png_ptr->save_buffer_max)
+ {
+ png_size_t new_max;
+ png_bytep old_buffer;
+
+ if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
+ (png_ptr->current_buffer_size + 256))
+ {
+ png_error(png_ptr, "Potential overflow of save_buffer");
+ }
+
+ new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
+ old_buffer = png_ptr->save_buffer;
+ png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
+ (png_size_t)new_max);
+
+ if (png_ptr->save_buffer == NULL)
+ {
+ png_free(png_ptr, old_buffer);
+ png_error(png_ptr, "Insufficient memory for save_buffer");
+ }
+
+ if (old_buffer)
+ memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+ else if (png_ptr->save_buffer_size)
+ png_error(png_ptr, "save_buffer error");
+ png_free(png_ptr, old_buffer);
+ png_ptr->save_buffer_max = new_max;
+ }
+ if (png_ptr->current_buffer_size)
+ {
+ memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
+ png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
+ png_ptr->save_buffer_size += png_ptr->current_buffer_size;
+ png_ptr->current_buffer_size = 0;
+ }
+ png_ptr->save_buffer_ptr = png_ptr->save_buffer;
+ png_ptr->buffer_size = 0;
+}
+
+void /* PRIVATE */
+png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
+ png_size_t buffer_length)
+{
+ png_ptr->current_buffer = buffer;
+ png_ptr->current_buffer_size = buffer_length;
+ png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
+ png_ptr->current_buffer_ptr = png_ptr->current_buffer;
+}
+
+void /* PRIVATE */
+png_push_read_IDAT(png_structrp png_ptr)
+{
+ if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0)
+ {
+ png_byte chunk_length[4];
+ png_byte chunk_tag[4];
+
+ /* TODO: this code can be commoned up with the same code in push_read */
+ PNG_PUSH_SAVE_BUFFER_IF_LT(8)
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, chunk_tag, 4);
+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
+ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+
+ if (png_ptr->chunk_name != png_IDAT)
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+
+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+ png_error(png_ptr, "Not enough compressed data");
+
+ return;
+ }
+
+ png_ptr->idat_size = png_ptr->push_length;
+ }
+
+ if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0)
+ {
+ png_size_t save_size = png_ptr->save_buffer_size;
+ png_uint_32 idat_size = png_ptr->idat_size;
+
+ /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
+ * are of different types and we don't know which variable has the fewest
+ * bits. Carefully select the smaller and cast it to the type of the
+ * larger - this cannot overflow. Do not cast in the following test - it
+ * will break on either 16-bit or 64-bit platforms.
+ */
+ if (idat_size < save_size)
+ save_size = (png_size_t)idat_size;
+
+ else
+ idat_size = (png_uint_32)save_size;
+
+ png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+ png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+ png_ptr->idat_size -= idat_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+
+ if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0)
+ {
+ png_size_t save_size = png_ptr->current_buffer_size;
+ png_uint_32 idat_size = png_ptr->idat_size;
+
+ /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
+ * are of different types and we don't know which variable has the fewest
+ * bits. Carefully select the smaller and cast it to the type of the
+ * larger - this cannot overflow.
+ */
+ if (idat_size < save_size)
+ save_size = (png_size_t)idat_size;
+
+ else
+ idat_size = (png_uint_32)save_size;
+
+ png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_ptr->idat_size -= idat_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+
+ if (png_ptr->idat_size == 0)
+ {
+ PNG_PUSH_SAVE_BUFFER_IF_LT(4)
+ png_crc_finish(png_ptr, 0);
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->zowner = 0;
+ }
+}
+
+void /* PRIVATE */
+png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
+ png_size_t buffer_length)
+{
+ /* The caller checks for a non-zero buffer length. */
+ if (!(buffer_length > 0) || buffer == NULL)
+ png_error(png_ptr, "No IDAT data (internal error)");
+
+ /* This routine must process all the data it has been given
+ * before returning, calling the row callback as required to
+ * handle the uncompressed results.
+ */
+ png_ptr->zstream.next_in = buffer;
+ /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
+ png_ptr->zstream.avail_in = (uInt)buffer_length;
+
+ /* Keep going until the decompressed data is all processed
+ * or the stream marked as finished.
+ */
+ while (png_ptr->zstream.avail_in > 0 &&
+ (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+ {
+ int ret;
+
+ /* We have data for zlib, but we must check that zlib
+ * has someplace to put the results. It doesn't matter
+ * if we don't expect any results -- it may be the input
+ * data is just the LZ end code.
+ */
+ if (!(png_ptr->zstream.avail_out > 0))
+ {
+ /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
+ png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
+ png_ptr->iwidth) + 1);
+
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ }
+
+ /* Using Z_SYNC_FLUSH here means that an unterminated
+ * LZ stream (a stream with a missing end code) can still
+ * be handled, otherwise (Z_NO_FLUSH) a future zlib
+ * implementation might defer output and therefore
+ * change the current behavior (see comments in inflate.c
+ * for why this doesn't happen at present with zlib 1.2.5).
+ */
+ ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH);
+
+ /* Check for any failure before proceeding. */
+ if (ret != Z_OK && ret != Z_STREAM_END)
+ {
+ /* Terminate the decompression. */
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+ png_ptr->zowner = 0;
+
+ /* This may be a truncated stream (missing or
+ * damaged end code). Treat that as a warning.
+ */
+ if (png_ptr->row_number >= png_ptr->num_rows ||
+ png_ptr->pass > 6)
+ png_warning(png_ptr, "Truncated compressed data in IDAT");
+
+ else
+ {
+ if (ret == Z_DATA_ERROR)
+ png_benign_error(png_ptr, "IDAT: ADLER32 checksum mismatch");
+ else
+ png_error(png_ptr, "Decompression error in IDAT");
+ }
+
+ /* Skip the check on unprocessed input */
+ return;
+ }
+
+ /* Did inflate output any data? */
+ if (png_ptr->zstream.next_out != png_ptr->row_buf)
+ {
+ /* Is this unexpected data after the last row?
+ * If it is, artificially terminate the LZ output
+ * here.
+ */
+ if (png_ptr->row_number >= png_ptr->num_rows ||
+ png_ptr->pass > 6)
+ {
+ /* Extra data. */
+ png_warning(png_ptr, "Extra compressed data in IDAT");
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+ png_ptr->zowner = 0;
+
+ /* Do no more processing; skip the unprocessed
+ * input check below.
+ */
+ return;
+ }
+
+ /* Do we have a complete row? */
+ if (png_ptr->zstream.avail_out == 0)
+ png_push_process_row(png_ptr);
+ }
+
+ /* And check for the end of the stream. */
+ if (ret == Z_STREAM_END)
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+ }
+
+ /* All the data should have been processed, if anything
+ * is left at this point we have bytes of IDAT data
+ * after the zlib end code.
+ */
+ if (png_ptr->zstream.avail_in > 0)
+ png_warning(png_ptr, "Extra compression data in IDAT");
+}
+
+void /* PRIVATE */
+png_push_process_row(png_structrp png_ptr)
+{
+ /* 1.5.6: row_info moved out of png_struct to a local here. */
+ png_row_info row_info;
+
+ row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
+ row_info.color_type = png_ptr->color_type;
+ row_info.bit_depth = png_ptr->bit_depth;
+ row_info.channels = png_ptr->channels;
+ row_info.pixel_depth = png_ptr->pixel_depth;
+ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
+
+ if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
+ {
+ if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
+ png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
+ png_ptr->prev_row + 1, png_ptr->row_buf[0]);
+ else
+ png_error(png_ptr, "bad adaptive filter value");
+ }
+
+ /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
+ * 1.5.6, while the buffer really is this big in current versions of libpng
+ * it may not be in the future, so this was changed just to copy the
+ * interlaced row count:
+ */
+ memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+ if (png_ptr->transformations != 0)
+ png_do_read_transformations(png_ptr, &row_info);
+#endif
+
+ /* The transformed pixel depth should match the depth now in row_info. */
+ if (png_ptr->transformed_pixel_depth == 0)
+ {
+ png_ptr->transformed_pixel_depth = row_info.pixel_depth;
+ if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
+ png_error(png_ptr, "progressive row overflow");
+ }
+
+ else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
+ png_error(png_ptr, "internal progressive row size calculation error");
+
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Expand interlaced rows to full size */
+ if (png_ptr->interlaced != 0 &&
+ (png_ptr->transformations & PNG_INTERLACE) != 0)
+ {
+ if (png_ptr->pass < 6)
+ png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
+ png_ptr->transformations);
+
+ switch (png_ptr->pass)
+ {
+ case 0:
+ {
+ int i;
+ for (i = 0; i < 8 && png_ptr->pass == 0; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
+ }
+
+ if (png_ptr->pass == 2) /* Pass 1 might be empty */
+ {
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ if (png_ptr->pass == 4 && png_ptr->height <= 4)
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ if (png_ptr->pass == 6 && png_ptr->height <= 4)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ break;
+ }
+
+ case 1:
+ {
+ int i;
+ for (i = 0; i < 8 && png_ptr->pass == 1; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 2) /* Skip top 4 generated rows */
+ {
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ break;
+ }
+
+ case 2:
+ {
+ int i;
+
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 4) /* Pass 3 might be empty */
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ break;
+ }
+
+ case 3:
+ {
+ int i;
+
+ for (i = 0; i < 4 && png_ptr->pass == 3; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 4) /* Skip top two generated rows */
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ break;
+ }
+
+ case 4:
+ {
+ int i;
+
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 6) /* Pass 5 might be empty */
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ break;
+ }
+
+ case 5:
+ {
+ int i;
+
+ for (i = 0; i < 2 && png_ptr->pass == 5; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 6) /* Skip top generated row */
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ break;
+ }
+
+ default:
+ case 6:
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+
+ if (png_ptr->pass != 6)
+ break;
+
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ }
+ else
+#endif
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+}
+
+void /* PRIVATE */
+png_read_push_finish_row(png_structrp png_ptr)
+{
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+ /* Height of interlace block. This is not currently used - if you need
+ * it, uncomment it here and in png.h
+ static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+ */
+#endif
+
+ png_ptr->row_number++;
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (png_ptr->interlaced != 0)
+ {
+ png_ptr->row_number = 0;
+ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+ do
+ {
+ png_ptr->pass++;
+ if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
+ (png_ptr->pass == 3 && png_ptr->width < 3) ||
+ (png_ptr->pass == 5 && png_ptr->width < 2))
+ png_ptr->pass++;
+
+ if (png_ptr->pass > 7)
+ png_ptr->pass--;
+
+ if (png_ptr->pass >= 7)
+ break;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ if ((png_ptr->transformations & PNG_INTERLACE) != 0)
+ break;
+
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+
+ } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
+ }
+#endif /* READ_INTERLACING */
+}
+
+void /* PRIVATE */
+png_push_have_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+ if (png_ptr->info_fn != NULL)
+ (*(png_ptr->info_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_end(png_structrp png_ptr, png_inforp info_ptr)
+{
+ if (png_ptr->end_fn != NULL)
+ (*(png_ptr->end_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_row(png_structrp png_ptr, png_bytep row)
+{
+ if (png_ptr->row_fn != NULL)
+ (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
+ (int)png_ptr->pass);
+}
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+void PNGAPI
+png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,
+ png_const_bytep new_row)
+{
+ if (png_ptr == NULL)
+ return;
+
+ /* new_row is a flag here - if it is NULL then the app callback was called
+ * from an empty row (see the calls to png_struct::row_fn below), otherwise
+ * it must be png_ptr->row_buf+1
+ */
+ if (new_row != NULL)
+ png_combine_row(png_ptr, old_row, 1/*blocky display*/);
+}
+#endif /* READ_INTERLACING */
+
+void PNGAPI
+png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,
+ png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+ png_progressive_end_ptr end_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->info_fn = info_fn;
+ png_ptr->row_fn = row_fn;
+ png_ptr->end_fn = end_fn;
+
+ png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
+}
+
+png_voidp PNGAPI
+png_get_progressive_ptr(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return (NULL);
+
+ return png_ptr->io_ptr;
+}
+#endif /* PROGRESSIVE_READ */
diff --git a/xs/src/png/libpng/pngpriv.h b/xs/src/png/libpng/pngpriv.h
new file mode 100644
index 000000000..1f2e90f2b
--- /dev/null
+++ b/xs/src/png/libpng/pngpriv.h
@@ -0,0 +1,2120 @@
+
+/* pngpriv.h - private declarations for use inside libpng
+ *
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* The symbols declared in this file (including the functions declared
+ * as extern) are PRIVATE. They are not part of the libpng public
+ * interface, and are not recommended for use by regular applications.
+ * Some of them may become public in the future; others may stay private,
+ * change in an incompatible way, or even disappear.
+ * Although the libpng users are not forbidden to include this header,
+ * they should be well aware of the issues that may arise from doing so.
+ */
+
+#ifndef PNGPRIV_H
+#define PNGPRIV_H
+
+/* Feature Test Macros. The following are defined here to ensure that correctly
+ * implemented libraries reveal the APIs libpng needs to build and hide those
+ * that are not needed and potentially damaging to the compilation.
+ *
+ * Feature Test Macros must be defined before any system header is included (see
+ * POSIX 1003.1 2.8.2 "POSIX Symbols."
+ *
+ * These macros only have an effect if the operating system supports either
+ * POSIX 1003.1 or C99, or both. On other operating systems (particularly
+ * Windows/Visual Studio) there is no effect; the OS specific tests below are
+ * still required (as of 2011-05-02.)
+ */
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* Standard library headers not required by png.h: */
+# include <stdlib.h>
+# include <string.h>
+#endif
+
+#define PNGLIB_BUILD /*libpng is being built, not used*/
+
+/* If HAVE_CONFIG_H is defined during the build then the build system must
+ * provide an appropriate "config.h" file on the include path. The header file
+ * must provide definitions as required below (search for "HAVE_CONFIG_H");
+ * see configure.ac for more details of the requirements. The macro
+ * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on
+ * 'configure'; define this macro to prevent the configure build including the
+ * configure generated config.h. Libpng is expected to compile without *any*
+ * special build system support on a reasonably ANSI-C compliant system.
+ */
+#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
+# include <config.h>
+
+ /* Pick up the definition of 'restrict' from config.h if it was read: */
+# define PNG_RESTRICT restrict
+#endif
+
+/* To support symbol prefixing it is necessary to know *before* including png.h
+ * whether the fixed point (and maybe other) APIs are exported, because if they
+ * are not internal definitions may be required. This is handled below just
+ * before png.h is included, but load the configuration now if it is available.
+ */
+#ifndef PNGLCONF_H
+# include "pnglibconf.h"
+#endif
+
+/* Local renames may change non-exported API functions from png.h */
+#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H)
+# include "pngprefix.h"
+#endif
+
+#ifdef PNG_USER_CONFIG
+# include "pngusr.h"
+ /* These should have been defined in pngusr.h */
+# ifndef PNG_USER_PRIVATEBUILD
+# define PNG_USER_PRIVATEBUILD "Custom libpng build"
+# endif
+# ifndef PNG_USER_DLLFNAME_POSTFIX
+# define PNG_USER_DLLFNAME_POSTFIX "Cb"
+# endif
+#endif
+
+/* Compile time options.
+ * =====================
+ * In a multi-arch build the compiler may compile the code several times for the
+ * same object module, producing different binaries for different architectures.
+ * When this happens configure-time setting of the target host options cannot be
+ * done and this interferes with the handling of the ARM NEON optimizations, and
+ * possibly other similar optimizations. Put additional tests here; in general
+ * this is needed when the same option can be changed at both compile time and
+ * run time depending on the target OS (i.e. iOS vs Android.)
+ *
+ * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because
+ * this is not possible with certain compilers (Oracle SUN OS CC), as a result
+ * it is necessary to ensure that all extern functions that *might* be used
+ * regardless of $(CFLAGS) get declared in this file. The test on __ARM_NEON__
+ * below is one example of this behavior because it is controlled by the
+ * presence or not of -mfpu=neon on the GCC command line, it is possible to do
+ * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely
+ * do this.
+ */
+#ifndef PNG_ARM_NEON_OPT
+ /* ARM NEON optimizations are being controlled by the compiler settings,
+ * typically the target FPU. If the FPU has been set to NEON (-mfpu=neon
+ * with GCC) then the compiler will define __ARM_NEON__ and we can rely
+ * unconditionally on NEON instructions not crashing, otherwise we must
+ * disable use of NEON instructions.
+ *
+ * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they
+ * can only be turned on automatically if that is supported too. If
+ * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail
+ * to compile with an appropriate #error if ALIGNED_MEMORY has been turned
+ * off.
+ *
+ * Note that gcc-4.9 defines __ARM_NEON instead of the deprecated
+ * __ARM_NEON__, so we check both variants.
+ *
+ * To disable ARM_NEON optimizations entirely, and skip compiling the
+ * associated assembler code, pass --enable-arm-neon=no to configure
+ * or put -DPNG_ARM_NEON_OPT=0 in CPPFLAGS.
+ */
+# if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \
+ defined(PNG_ALIGNED_MEMORY_SUPPORTED)
+# define PNG_ARM_NEON_OPT 2
+# else
+# define PNG_ARM_NEON_OPT 0
+# endif
+#endif
+
+#if PNG_ARM_NEON_OPT > 0
+ /* NEON optimizations are to be at least considered by libpng, so enable the
+ * callbacks to do this.
+ */
+# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon
+
+ /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used
+ * if possible - if __ARM_NEON__ is set and the compiler version is not known
+ * to be broken. This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can
+ * be:
+ *
+ * 1 The intrinsics code (the default with __ARM_NEON__)
+ * 2 The hand coded assembler (the default without __ARM_NEON__)
+ *
+ * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however
+ * this is *NOT* supported and may cease to work even after a minor revision
+ * to libpng. It *is* valid to do this for testing purposes, e.g. speed
+ * testing or a new compiler, but the results should be communicated to the
+ * libpng implementation list for incorporation in the next minor release.
+ */
+# ifndef PNG_ARM_NEON_IMPLEMENTATION
+# if defined(__ARM_NEON__) || defined(__ARM_NEON)
+# if defined(__clang__)
+ /* At present it is unknown by the libpng developers which versions
+ * of clang support the intrinsics, however some or perhaps all
+ * versions do not work with the assembler so this may be
+ * irrelevant, so just use the default (do nothing here.)
+ */
+# elif defined(__GNUC__)
+ /* GCC 4.5.4 NEON support is known to be broken. 4.6.3 is known to
+ * work, so if this *is* GCC, or G++, look for a version >4.5
+ */
+# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)
+# define PNG_ARM_NEON_IMPLEMENTATION 2
+# endif /* no GNUC support */
+# endif /* __GNUC__ */
+# else /* !defined __ARM_NEON__ */
+ /* The 'intrinsics' code simply won't compile without this -mfpu=neon:
+ */
+# define PNG_ARM_NEON_IMPLEMENTATION 2
+# endif /* __ARM_NEON__ */
+# endif /* !PNG_ARM_NEON_IMPLEMENTATION */
+
+# ifndef PNG_ARM_NEON_IMPLEMENTATION
+ /* Use the intrinsics code by default. */
+# define PNG_ARM_NEON_IMPLEMENTATION 1
+# endif
+#endif /* PNG_ARM_NEON_OPT > 0 */
+
+#ifndef PNG_MIPS_MSA_OPT
+# if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED)
+# define PNG_MIPS_MSA_OPT 2
+# else
+# define PNG_MIPS_MSA_OPT 0
+# endif
+#endif
+
+#ifndef PNG_POWERPC_VSX_OPT
+# if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__)
+# define PNG_POWERPC_VSX_OPT 2
+# else
+# define PNG_POWERPC_VSX_OPT 0
+# endif
+#endif
+
+#ifndef PNG_INTEL_SSE_OPT
+# ifdef PNG_INTEL_SSE
+ /* Only check for SSE if the build configuration has been modified to
+ * enable SSE optimizations. This means that these optimizations will
+ * be off by default. See contrib/intel for more details.
+ */
+# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
+ defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
+ (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
+# define PNG_INTEL_SSE_OPT 1
+# endif
+# endif
+#endif
+
+#if PNG_INTEL_SSE_OPT > 0
+# ifndef PNG_INTEL_SSE_IMPLEMENTATION
+# if defined(__SSE4_1__) || defined(__AVX__)
+ /* We are not actually using AVX, but checking for AVX is the best
+ way we can detect SSE4.1 and SSSE3 on MSVC.
+ */
+# define PNG_INTEL_SSE_IMPLEMENTATION 3
+# elif defined(__SSSE3__)
+# define PNG_INTEL_SSE_IMPLEMENTATION 2
+# elif defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
+ (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
+# define PNG_INTEL_SSE_IMPLEMENTATION 1
+# else
+# define PNG_INTEL_SSE_IMPLEMENTATION 0
+# endif
+# endif
+
+# if PNG_INTEL_SSE_IMPLEMENTATION > 0
+# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2
+# endif
+#endif
+
+#if PNG_MIPS_MSA_OPT > 0
+# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa
+# ifndef PNG_MIPS_MSA_IMPLEMENTATION
+# if defined(__mips_msa)
+# if defined(__clang__)
+# elif defined(__GNUC__)
+# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7)
+# define PNG_MIPS_MSA_IMPLEMENTATION 2
+# endif /* no GNUC support */
+# endif /* __GNUC__ */
+# else /* !defined __mips_msa */
+# define PNG_MIPS_MSA_IMPLEMENTATION 2
+# endif /* __mips_msa */
+# endif /* !PNG_MIPS_MSA_IMPLEMENTATION */
+
+# ifndef PNG_MIPS_MSA_IMPLEMENTATION
+# define PNG_MIPS_MSA_IMPLEMENTATION 1
+# endif
+#endif /* PNG_MIPS_MSA_OPT > 0 */
+
+#if PNG_POWERPC_VSX_OPT > 0
+# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx
+# define PNG_POWERPC_VSX_IMPLEMENTATION 1
+#endif
+
+
+/* Is this a build of a DLL where compilation of the object modules requires
+ * different preprocessor settings to those required for a simple library? If
+ * so PNG_BUILD_DLL must be set.
+ *
+ * If libpng is used inside a DLL but that DLL does not export the libpng APIs
+ * PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a
+ * static library of libpng then link the DLL against that.
+ */
+#ifndef PNG_BUILD_DLL
+# ifdef DLL_EXPORT
+ /* This is set by libtool when files are compiled for a DLL; libtool
+ * always compiles twice, even on systems where it isn't necessary. Set
+ * PNG_BUILD_DLL in case it is necessary:
+ */
+# define PNG_BUILD_DLL
+# else
+# ifdef _WINDLL
+ /* This is set by the Microsoft Visual Studio IDE in projects that
+ * build a DLL. It can't easily be removed from those projects (it
+ * isn't visible in the Visual Studio UI) so it is a fairly reliable
+ * indication that PNG_IMPEXP needs to be set to the DLL export
+ * attributes.
+ */
+# define PNG_BUILD_DLL
+# else
+# ifdef __DLL__
+ /* This is set by the Borland C system when compiling for a DLL
+ * (as above.)
+ */
+# define PNG_BUILD_DLL
+# else
+ /* Add additional compiler cases here. */
+# endif
+# endif
+# endif
+#endif /* Setting PNG_BUILD_DLL if required */
+
+/* See pngconf.h for more details: the builder of the library may set this on
+ * the command line to the right thing for the specific compilation system or it
+ * may be automagically set above (at present we know of no system where it does
+ * need to be set on the command line.)
+ *
+ * PNG_IMPEXP must be set here when building the library to prevent pngconf.h
+ * setting it to the "import" setting for a DLL build.
+ */
+#ifndef PNG_IMPEXP
+# ifdef PNG_BUILD_DLL
+# define PNG_IMPEXP PNG_DLL_EXPORT
+# else
+ /* Not building a DLL, or the DLL doesn't require specific export
+ * definitions.
+ */
+# define PNG_IMPEXP
+# endif
+#endif
+
+/* No warnings for private or deprecated functions in the build: */
+#ifndef PNG_DEPRECATED
+# define PNG_DEPRECATED
+#endif
+#ifndef PNG_PRIVATE
+# define PNG_PRIVATE
+#endif
+
+/* Symbol preprocessing support.
+ *
+ * To enable listing global, but internal, symbols the following macros should
+ * always be used to declare an extern data or function object in this file.
+ */
+#ifndef PNG_INTERNAL_DATA
+# define PNG_INTERNAL_DATA(type, name, array) PNG_LINKAGE_DATA type name array
+#endif
+
+#ifndef PNG_INTERNAL_FUNCTION
+# define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\
+ PNG_LINKAGE_FUNCTION PNG_FUNCTION(type, name, args, PNG_EMPTY attributes)
+#endif
+
+#ifndef PNG_INTERNAL_CALLBACK
+# define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\
+ PNG_LINKAGE_CALLBACK PNG_FUNCTION(type, (PNGCBAPI name), args,\
+ PNG_EMPTY attributes)
+#endif
+
+/* If floating or fixed point APIs are disabled they may still be compiled
+ * internally. To handle this make sure they are declared as the appropriate
+ * internal extern function (otherwise the symbol prefixing stuff won't work and
+ * the functions will be used without definitions.)
+ *
+ * NOTE: although all the API functions are declared here they are not all
+ * actually built! Because the declarations are still made it is necessary to
+ * fake out types that they depend on.
+ */
+#ifndef PNG_FP_EXPORT
+# ifndef PNG_FLOATING_POINT_SUPPORTED
+# define PNG_FP_EXPORT(ordinal, type, name, args)\
+ PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY);
+# ifndef PNG_VERSION_INFO_ONLY
+ typedef struct png_incomplete png_double;
+ typedef png_double* png_doublep;
+ typedef const png_double* png_const_doublep;
+ typedef png_double** png_doublepp;
+# endif
+# endif
+#endif
+#ifndef PNG_FIXED_EXPORT
+# ifndef PNG_FIXED_POINT_SUPPORTED
+# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
+ PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY);
+# endif
+#endif
+
+#include "png.h"
+
+/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */
+#ifndef PNG_DLL_EXPORT
+# define PNG_DLL_EXPORT
+#endif
+
+/* This is a global switch to set the compilation for an installed system
+ * (a release build). It can be set for testing debug builds to ensure that
+ * they will compile when the build type is switched to RC or STABLE, the
+ * default is just to use PNG_LIBPNG_BUILD_BASE_TYPE. Set this in CPPFLAGS
+ * with either:
+ *
+ * -DPNG_RELEASE_BUILD Turns on the release compile path
+ * -DPNG_RELEASE_BUILD=0 Turns it off
+ * or in your pngusr.h with
+ * #define PNG_RELEASE_BUILD=1 Turns on the release compile path
+ * #define PNG_RELEASE_BUILD=0 Turns it off
+ */
+#ifndef PNG_RELEASE_BUILD
+# define PNG_RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC)
+#endif
+
+/* SECURITY and SAFETY:
+ *
+ * libpng is built with support for internal limits on image dimensions and
+ * memory usage. These are documented in scripts/pnglibconf.dfa of the
+ * source and recorded in the machine generated header file pnglibconf.h.
+ */
+
+/* If you are running on a machine where you cannot allocate more
+ * than 64K of memory at once, uncomment this. While libpng will not
+ * normally need that much memory in a chunk (unless you load up a very
+ * large file), zlib needs to know how big of a chunk it can use, and
+ * libpng thus makes sure to check any memory allocation to verify it
+ * will fit into memory.
+ *
+ * zlib provides 'MAXSEG_64K' which, if defined, indicates the
+ * same limit and pngconf.h (already included) sets the limit
+ * if certain operating systems are detected.
+ */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+# define PNG_MAX_MALLOC_64K
+#endif
+
+#ifndef PNG_UNUSED
+/* Unused formal parameter warnings are silenced using the following macro
+ * which is expected to have no bad effects on performance (optimizing
+ * compilers will probably remove it entirely). Note that if you replace
+ * it with something other than whitespace, you must include the terminating
+ * semicolon.
+ */
+# define PNG_UNUSED(param) (void)param;
+#endif
+
+/* Just a little check that someone hasn't tried to define something
+ * contradictory.
+ */
+#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
+# undef PNG_ZBUF_SIZE
+# define PNG_ZBUF_SIZE 65536L
+#endif
+
+/* If warnings or errors are turned off the code is disabled or redirected here.
+ * From 1.5.4 functions have been added to allow very limited formatting of
+ * error and warning messages - this code will also be disabled here.
+ */
+#ifdef PNG_WARNINGS_SUPPORTED
+# define PNG_WARNING_PARAMETERS(p) png_warning_parameters p;
+#else
+# define png_warning_parameter(p,number,string) ((void)0)
+# define png_warning_parameter_unsigned(p,number,format,value) ((void)0)
+# define png_warning_parameter_signed(p,number,format,value) ((void)0)
+# define png_formatted_warning(pp,p,message) ((void)(pp))
+# define PNG_WARNING_PARAMETERS(p)
+#endif
+#ifndef PNG_ERROR_TEXT_SUPPORTED
+# define png_fixed_error(s1,s2) png_err(s1)
+#endif
+
+/* Some fixed point APIs are still required even if not exported because
+ * they get used by the corresponding floating point APIs. This magic
+ * deals with this:
+ */
+#ifdef PNG_FIXED_POINT_SUPPORTED
+# define PNGFAPI PNGAPI
+#else
+# define PNGFAPI /* PRIVATE */
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* Other defines specific to compilers can go here. Try to keep
+ * them inside an appropriate ifdef/endif pair for portability.
+ */
+
+/* C allows up-casts from (void*) to any pointer and (const void*) to any
+ * pointer to a const object. C++ regards this as a type error and requires an
+ * explicit, static, cast and provides the static_cast<> rune to ensure that
+ * const is not cast away.
+ */
+#ifdef __cplusplus
+# define png_voidcast(type, value) static_cast<type>(value)
+# define png_constcast(type, value) const_cast<type>(value)
+# define png_aligncast(type, value) \
+ static_cast<type>(static_cast<void*>(value))
+# define png_aligncastconst(type, value) \
+ static_cast<type>(static_cast<const void*>(value))
+#else
+# define png_voidcast(type, value) (value)
+# ifdef _WIN64
+# ifdef __GNUC__
+ typedef unsigned long long png_ptruint;
+# else
+ typedef unsigned __int64 png_ptruint;
+# endif
+# else
+ typedef unsigned long png_ptruint;
+# endif
+# define png_constcast(type, value) ((type)(png_ptruint)(const void*)(value))
+# define png_aligncast(type, value) ((void*)(value))
+# define png_aligncastconst(type, value) ((const void*)(value))
+#endif /* __cplusplus */
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
+ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
+ /* png.c requires the following ANSI-C constants if the conversion of
+ * floating point to ASCII is implemented therein:
+ *
+ * DBL_DIG Maximum number of decimal digits (can be set to any constant)
+ * DBL_MIN Smallest normalized fp number (can be set to an arbitrary value)
+ * DBL_MAX Maximum floating point number (can be set to an arbitrary value)
+ */
+# include <float.h>
+
+# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
+ defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
+ /* We need to check that <math.h> hasn't already been included earlier
+ * as it seems it doesn't agree with <fp.h>, yet we should really use
+ * <fp.h> if possible.
+ */
+# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
+# include <fp.h>
+# endif
+# else
+# include <math.h>
+# endif
+# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
+ /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+ * MATH=68881
+ */
+# include <m68881.h>
+# endif
+#endif
+
+/* This provides the non-ANSI (far) memory allocation routines. */
+#if defined(__TURBOC__) && defined(__MSDOS__)
+# include <mem.h>
+# include <alloc.h>
+#endif
+
+#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
+ defined(_WIN32) || defined(__WIN32__)
+# include <windows.h> /* defines _WINDOWS_ macro */
+#endif
+#endif /* PNG_VERSION_INFO_ONLY */
+
+/* Moved here around 1.5.0beta36 from pngconf.h */
+/* Users may want to use these so they are not private. Any library
+ * functions that are passed far data must be model-independent.
+ */
+
+/* Memory model/platform independent fns */
+#ifndef PNG_ABORT
+# ifdef _WINDOWS_
+# define PNG_ABORT() ExitProcess(0)
+# else
+# define PNG_ABORT() abort()
+# endif
+#endif
+
+/* These macros may need to be architecture dependent. */
+#define PNG_ALIGN_NONE 0 /* do not use data alignment */
+#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */
+#ifdef offsetof
+# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */
+#else
+# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */
+#endif
+#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */
+
+#ifndef PNG_ALIGN_TYPE
+ /* Default to using aligned access optimizations and requiring alignment to a
+ * multiple of the data type size. Override in a compiler specific fashion
+ * if necessary by inserting tests here:
+ */
+# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE
+#endif
+
+#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE
+ /* This is used because in some compiler implementations non-aligned
+ * structure members are supported, so the offsetof approach below fails.
+ * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access
+ * is good for performance. Do not do this unless you have tested the result
+ * and understand it.
+ */
+# define png_alignof(type) (sizeof (type))
+#else
+# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET
+# define png_alignof(type) offsetof(struct{char c; type t;}, t)
+# else
+# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS
+# define png_alignof(type) (1)
+# endif
+ /* Else leave png_alignof undefined to prevent use thereof */
+# endif
+#endif
+
+/* This implicitly assumes alignment is always to a power of 2. */
+#ifdef png_alignof
+# define png_isaligned(ptr, type)\
+ (((type)((const char*)ptr-(const char*)0) & \
+ (type)(png_alignof(type)-1)) == 0)
+#else
+# define png_isaligned(ptr, type) 0
+#endif
+
+/* End of memory model/platform independent support */
+/* End of 1.5.0beta36 move from pngconf.h */
+
+/* CONSTANTS and UTILITY MACROS
+ * These are used internally by libpng and not exposed in the API
+ */
+
+/* Various modes of operation. Note that after an init, mode is set to
+ * zero automatically when the structure is created. Three of these
+ * are defined in png.h because they need to be visible to applications
+ * that call png_set_unknown_chunk().
+ */
+/* #define PNG_HAVE_IHDR 0x01U (defined in png.h) */
+/* #define PNG_HAVE_PLTE 0x02U (defined in png.h) */
+#define PNG_HAVE_IDAT 0x04U
+/* #define PNG_AFTER_IDAT 0x08U (defined in png.h) */
+#define PNG_HAVE_IEND 0x10U
+ /* 0x20U (unused) */
+ /* 0x40U (unused) */
+ /* 0x80U (unused) */
+#define PNG_HAVE_CHUNK_HEADER 0x100U
+#define PNG_WROTE_tIME 0x200U
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400U
+#define PNG_BACKGROUND_IS_GRAY 0x800U
+#define PNG_HAVE_PNG_SIGNATURE 0x1000U
+#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
+ /* 0x4000U (unused) */
+#define PNG_IS_READ_STRUCT 0x8000U /* Else is a write struct */
+
+/* Flags for the transformations the PNG library does on the image data */
+#define PNG_BGR 0x0001U
+#define PNG_INTERLACE 0x0002U
+#define PNG_PACK 0x0004U
+#define PNG_SHIFT 0x0008U
+#define PNG_SWAP_BYTES 0x0010U
+#define PNG_INVERT_MONO 0x0020U
+#define PNG_QUANTIZE 0x0040U
+#define PNG_COMPOSE 0x0080U /* Was PNG_BACKGROUND */
+#define PNG_BACKGROUND_EXPAND 0x0100U
+#define PNG_EXPAND_16 0x0200U /* Added to libpng 1.5.2 */
+#define PNG_16_TO_8 0x0400U /* Becomes 'chop' in 1.5.4 */
+#define PNG_RGBA 0x0800U
+#define PNG_EXPAND 0x1000U
+#define PNG_GAMMA 0x2000U
+#define PNG_GRAY_TO_RGB 0x4000U
+#define PNG_FILLER 0x8000U
+#define PNG_PACKSWAP 0x10000U
+#define PNG_SWAP_ALPHA 0x20000U
+#define PNG_STRIP_ALPHA 0x40000U
+#define PNG_INVERT_ALPHA 0x80000U
+#define PNG_USER_TRANSFORM 0x100000U
+#define PNG_RGB_TO_GRAY_ERR 0x200000U
+#define PNG_RGB_TO_GRAY_WARN 0x400000U
+#define PNG_RGB_TO_GRAY 0x600000U /* two bits, RGB_TO_GRAY_ERR|WARN */
+#define PNG_ENCODE_ALPHA 0x800000U /* Added to libpng-1.5.4 */
+#define PNG_ADD_ALPHA 0x1000000U /* Added to libpng-1.2.7 */
+#define PNG_EXPAND_tRNS 0x2000000U /* Added to libpng-1.2.9 */
+#define PNG_SCALE_16_TO_8 0x4000000U /* Added to libpng-1.5.4 */
+ /* 0x8000000U unused */
+ /* 0x10000000U unused */
+ /* 0x20000000U unused */
+ /* 0x40000000U unused */
+/* Flags for png_create_struct */
+#define PNG_STRUCT_PNG 0x0001U
+#define PNG_STRUCT_INFO 0x0002U
+
+/* Flags for the png_ptr->flags rather than declaring a byte for each one */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001U
+#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002U /* Added to libpng-1.6.0 */
+ /* 0x0004U unused */
+#define PNG_FLAG_ZSTREAM_ENDED 0x0008U /* Added to libpng-1.6.0 */
+ /* 0x0010U unused */
+ /* 0x0020U unused */
+#define PNG_FLAG_ROW_INIT 0x0040U
+#define PNG_FLAG_FILLER_AFTER 0x0080U
+#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100U
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200U
+#define PNG_FLAG_CRC_CRITICAL_USE 0x0400U
+#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800U
+#define PNG_FLAG_ASSUME_sRGB 0x1000U /* Added to libpng-1.5.4 */
+#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000U /* Added to libpng-1.5.4 */
+#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000U /* Added to libpng-1.5.4 */
+/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000U */
+/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000U */
+#define PNG_FLAG_LIBRARY_MISMATCH 0x20000U
+#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000U
+#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000U
+#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000U /* Added to libpng-1.4.0 */
+#define PNG_FLAG_APP_WARNINGS_WARN 0x200000U /* Added to libpng-1.6.0 */
+#define PNG_FLAG_APP_ERRORS_WARN 0x400000U /* Added to libpng-1.6.0 */
+ /* 0x800000U unused */
+ /* 0x1000000U unused */
+ /* 0x2000000U unused */
+ /* 0x4000000U unused */
+ /* 0x8000000U unused */
+ /* 0x10000000U unused */
+ /* 0x20000000U unused */
+ /* 0x40000000U unused */
+
+#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
+ PNG_FLAG_CRC_ANCILLARY_NOWARN)
+
+#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \
+ PNG_FLAG_CRC_CRITICAL_IGNORE)
+
+#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \
+ PNG_FLAG_CRC_CRITICAL_MASK)
+
+/* Save typing and make code easier to understand */
+
+#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
+ abs((int)((c1).green) - (int)((c2).green)) + \
+ abs((int)((c1).blue) - (int)((c2).blue)))
+
+/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255
+ * by dividing by 257 *with rounding*. This macro is exact for the given range.
+ * See the discourse in pngrtran.c png_do_scale_16_to_8. The values in the
+ * macro were established by experiment (modifying the added value). The macro
+ * has a second variant that takes a value already scaled by 255 and divides by
+ * 65535 - this has a maximum error of .502. Over the range 0..65535*65535 it
+ * only gives off-by-one errors and only for 0.5% (1 in 200) of the values.
+ */
+#define PNG_DIV65535(v24) (((v24) + 32895) >> 16)
+#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255)
+
+/* Added to libpng-1.2.6 JB */
+#define PNG_ROWBYTES(pixel_bits, width) \
+ ((pixel_bits) >= 8 ? \
+ ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
+ (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
+
+/* This returns the number of trailing bits in the last byte of a row, 0 if the
+ * last byte is completely full of pixels. It is, in principle, (pixel_bits x
+ * width) % 8, but that would overflow for large 'width'. The second macro is
+ * the same except that it returns the number of unused bits in the last byte;
+ * (8-TRAILBITS), but 0 when TRAILBITS is 0.
+ *
+ * NOTE: these macros are intended to be self-evidently correct and never
+ * overflow on the assumption that pixel_bits is in the range 0..255. The
+ * arguments are evaluated only once and they can be signed (e.g. as a result of
+ * the integral promotions). The result of the expression always has type
+ * (png_uint_32), however the compiler always knows it is in the range 0..7.
+ */
+#define PNG_TRAILBITS(pixel_bits, width) \
+ (((pixel_bits) * ((width) % (png_uint_32)8)) % 8)
+
+#define PNG_PADBITS(pixel_bits, width) \
+ ((8 - PNG_TRAILBITS(pixel_bits, width)) % 8)
+
+/* PNG_OUT_OF_RANGE returns true if value is outside the range
+ * ideal-delta..ideal+delta. Each argument is evaluated twice.
+ * "ideal" and "delta" should be constants, normally simple
+ * integers, "value" a variable. Added to libpng-1.2.6 JB
+ */
+#define PNG_OUT_OF_RANGE(value, ideal, delta) \
+ ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
+
+/* Conversions between fixed and floating point, only defined if
+ * required (to make sure the code doesn't accidentally use float
+ * when it is supposedly disabled.)
+ */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+/* The floating point conversion can't overflow, though it can and
+ * does lose accuracy relative to the original fixed point value.
+ * In practice this doesn't matter because png_fixed_point only
+ * stores numbers with very low precision. The png_ptr and s
+ * arguments are unused by default but are there in case error
+ * checking becomes a requirement.
+ */
+#define png_float(png_ptr, fixed, s) (.00001 * (fixed))
+
+/* The fixed point conversion performs range checking and evaluates
+ * its argument multiple times, so must be used with care. The
+ * range checking uses the PNG specification values for a signed
+ * 32-bit fixed point value except that the values are deliberately
+ * rounded-to-zero to an integral value - 21474 (21474.83 is roughly
+ * (2^31-1) * 100000). 's' is a string that describes the value being
+ * converted.
+ *
+ * NOTE: this macro will raise a png_error if the range check fails,
+ * therefore it is normally only appropriate to use this on values
+ * that come from API calls or other sources where an out of range
+ * error indicates a programming error, not a data error!
+ *
+ * NOTE: by default this is off - the macro is not used - because the
+ * function call saves a lot of code.
+ */
+#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED
+#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\
+ ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0))
+#endif
+/* else the corresponding function is defined below, inside the scope of the
+ * cplusplus test.
+ */
+#endif
+
+/* Constants for known chunk types. If you need to add a chunk, define the name
+ * here. For historical reasons these constants have the form png_<name>; i.e.
+ * the prefix is lower case. Please use decimal values as the parameters to
+ * match the ISO PNG specification and to avoid relying on the C locale
+ * interpretation of character values.
+ *
+ * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values
+ * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string
+ * to be generated if required.
+ *
+ * PNG_32b correctly produces a value shifted by up to 24 bits, even on
+ * architectures where (int) is only 16 bits.
+ */
+#define PNG_32b(b,s) ((png_uint_32)(b) << (s))
+#define PNG_U32(b1,b2,b3,b4) \
+ (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))
+
+/* Constants for known chunk types.
+ *
+ * MAINTAINERS: If you need to add a chunk, define the name here.
+ * For historical reasons these constants have the form png_<name>; i.e.
+ * the prefix is lower case. Please use decimal values as the parameters to
+ * match the ISO PNG specification and to avoid relying on the C locale
+ * interpretation of character values. Please keep the list sorted.
+ *
+ * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk
+ * type. In fact the specification does not express chunk types this way,
+ * however using a 32-bit value means that the chunk type can be read from the
+ * stream using exactly the same code as used for a 32-bit unsigned value and
+ * can be examined far more efficiently (using one arithmetic compare).
+ *
+ * Prior to 1.5.6 the chunk type constants were expressed as C strings. The
+ * libpng API still uses strings for 'unknown' chunks and a macro,
+ * PNG_STRING_FROM_CHUNK, allows a string to be generated if required. Notice
+ * that for portable code numeric values must still be used; the string "IHDR"
+ * is not portable and neither is PNG_U32('I', 'H', 'D', 'R').
+ *
+ * In 1.7.0 the definitions will be made public in png.h to avoid having to
+ * duplicate the same definitions in application code.
+ */
+#define png_IDAT PNG_U32( 73, 68, 65, 84)
+#define png_IEND PNG_U32( 73, 69, 78, 68)
+#define png_IHDR PNG_U32( 73, 72, 68, 82)
+#define png_PLTE PNG_U32( 80, 76, 84, 69)
+#define png_bKGD PNG_U32( 98, 75, 71, 68)
+#define png_cHRM PNG_U32( 99, 72, 82, 77)
+#define png_eXIf PNG_U32(101, 88, 73, 102) /* registered July 2017 */
+#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */
+#define png_gAMA PNG_U32(103, 65, 77, 65)
+#define png_gIFg PNG_U32(103, 73, 70, 103)
+#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */
+#define png_gIFx PNG_U32(103, 73, 70, 120)
+#define png_hIST PNG_U32(104, 73, 83, 84)
+#define png_iCCP PNG_U32(105, 67, 67, 80)
+#define png_iTXt PNG_U32(105, 84, 88, 116)
+#define png_oFFs PNG_U32(111, 70, 70, 115)
+#define png_pCAL PNG_U32(112, 67, 65, 76)
+#define png_pHYs PNG_U32(112, 72, 89, 115)
+#define png_sBIT PNG_U32(115, 66, 73, 84)
+#define png_sCAL PNG_U32(115, 67, 65, 76)
+#define png_sPLT PNG_U32(115, 80, 76, 84)
+#define png_sRGB PNG_U32(115, 82, 71, 66)
+#define png_sTER PNG_U32(115, 84, 69, 82)
+#define png_tEXt PNG_U32(116, 69, 88, 116)
+#define png_tIME PNG_U32(116, 73, 77, 69)
+#define png_tRNS PNG_U32(116, 82, 78, 83)
+#define png_zTXt PNG_U32(122, 84, 88, 116)
+
+/* The following will work on (signed char*) strings, whereas the get_uint_32
+ * macro will fail on top-bit-set values because of the sign extension.
+ */
+#define PNG_CHUNK_FROM_STRING(s)\
+ PNG_U32(0xff & (s)[0], 0xff & (s)[1], 0xff & (s)[2], 0xff & (s)[3])
+
+/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is
+ * signed and the argument is a (char[]) This macro will fail miserably on
+ * systems where (char) is more than 8 bits.
+ */
+#define PNG_STRING_FROM_CHUNK(s,c)\
+ (void)(((char*)(s))[0]=(char)(((c)>>24) & 0xff), \
+ ((char*)(s))[1]=(char)(((c)>>16) & 0xff),\
+ ((char*)(s))[2]=(char)(((c)>>8) & 0xff), \
+ ((char*)(s))[3]=(char)((c & 0xff)))
+
+/* Do the same but terminate with a null character. */
+#define PNG_CSTRING_FROM_CHUNK(s,c)\
+ (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0)
+
+/* Test on flag values as defined in the spec (section 5.4): */
+#define PNG_CHUNK_ANCILLARY(c) (1 & ((c) >> 29))
+#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLARY(c))
+#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21))
+#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13))
+#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5))
+
+/* Gamma values (new at libpng-1.5.4): */
+#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */
+#define PNG_GAMMA_MAC_INVERSE 65909
+#define PNG_GAMMA_sRGB_INVERSE 45455
+
+/* Almost everything below is C specific; the #defines above can be used in
+ * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot.
+ */
+#ifndef PNG_VERSION_INFO_ONLY
+
+#include "pngstruct.h"
+#include "pnginfo.h"
+
+/* Validate the include paths - the include path used to generate pnglibconf.h
+ * must match that used in the build, or we must be using pnglibconf.h.prebuilt:
+ */
+#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM
+# error ZLIB_VERNUM != PNG_ZLIB_VERNUM \
+ "-I (include path) error: see the notes in pngpriv.h"
+ /* This means that when pnglibconf.h was built the copy of zlib.h that it
+ * used is not the same as the one being used here. Because the build of
+ * libpng makes decisions to use inflateInit2 and inflateReset2 based on the
+ * zlib version number and because this affects handling of certain broken
+ * PNG files the -I directives must match.
+ *
+ * The most likely explanation is that you passed a -I in CFLAGS. This will
+ * not work; all the preprocessor directories and in particular all the -I
+ * directives must be in CPPFLAGS.
+ */
+#endif
+
+/* This is used for 16-bit gamma tables -- only the top level pointers are
+ * const; this could be changed:
+ */
+typedef const png_uint_16p * png_const_uint_16pp;
+
+/* Added to libpng-1.5.7: sRGB conversion tables */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]);
+ /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value,
+ * 0..65535. This table gives the closest 16-bit answers (no errors).
+ */
+#endif
+
+PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]);
+PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]);
+
+#define PNG_sRGB_FROM_LINEAR(linear) \
+ ((png_byte)(0xff & ((png_sRGB_base[(linear)>>15] \
+ + ((((linear) & 0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8)))
+ /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB
+ * encoded value with maximum error 0.646365. Note that the input is not a
+ * 16-bit value; it has been multiplied by 255! */
+#endif /* SIMPLIFIED_READ/WRITE */
+
+
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Internal functions; these are not exported from a DLL however because they
+ * are used within several of the C source files they have to be C extern.
+ *
+ * All of these functions must be declared with PNG_INTERNAL_FUNCTION.
+ */
+
+/* Zlib support */
+#define PNG_UNEXPECTED_ZLIB_RETURN (-7)
+PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret),
+ PNG_EMPTY);
+ /* Used by the zlib handling functions to ensure that z_stream::msg is always
+ * set before they return.
+ */
+
+#ifdef PNG_WRITE_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr,
+ png_compression_bufferp *list),PNG_EMPTY);
+ /* Free the buffer list used by the compressed write code. */
+#endif
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
+ !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
+ (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
+ defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
+ (defined(PNG_sCAL_SUPPORTED) && \
+ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr,
+ double fp, png_const_charp text),PNG_EMPTY);
+#endif
+
+/* Check the user version string for compatibility, returns false if the version
+ * numbers aren't compatible.
+ */
+PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr,
+ png_const_charp user_png_ver),PNG_EMPTY);
+
+/* Internal base allocator - no messages, NULL on failure to allocate. This
+ * does, however, call the application provided allocator and that could call
+ * png_error (although that would be a bug in the application implementation.)
+ */
+PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr,
+ png_alloc_size_t size),PNG_ALLOCATED);
+
+#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
+ defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
+/* Internal array allocator, outputs no error or warning messages on failure,
+ * just returns NULL.
+ */
+PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr,
+ int nelements, size_t element_size),PNG_ALLOCATED);
+
+/* The same but an existing array is extended by add_elements. This function
+ * also memsets the new elements to 0 and copies the old elements. The old
+ * array is not freed or altered.
+ */
+PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr,
+ png_const_voidp array, int old_elements, int add_elements,
+ size_t element_size),PNG_ALLOCATED);
+#endif /* text, sPLT or unknown chunks */
+
+/* Magic to create a struct when there is no struct to call the user supplied
+ * memory allocators. Because error handling has not been set up the memory
+ * handlers can't safely call png_error, but this is an obscure and undocumented
+ * restriction so libpng has to assume that the 'free' handler, at least, might
+ * call png_error.
+ */
+PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct,
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn,
+ png_free_ptr free_fn),PNG_ALLOCATED);
+
+/* Free memory from internal libpng struct */
+PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr),
+ PNG_EMPTY);
+
+/* Free an allocated jmp_buf (always succeeds) */
+PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY);
+
+/* Function to allocate memory for zlib. PNGAPI is disallowed. */
+PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size),
+ PNG_ALLOCATED);
+
+/* Function to free memory for zlib. PNGAPI is disallowed. */
+PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY);
+
+/* Next four functions are used internally as callbacks. PNGCBAPI is required
+ * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to
+ * PNGCBAPI at 1.5.0
+ */
+
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr,
+ png_bytep data, png_size_t length),PNG_EMPTY);
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr,
+ png_bytep buffer, png_size_t length),PNG_EMPTY);
+#endif
+
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr,
+ png_bytep data, png_size_t length),PNG_EMPTY);
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+# ifdef PNG_STDIO_SUPPORTED
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr),
+ PNG_EMPTY);
+# endif
+#endif
+
+/* Reset the CRC variable */
+PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY);
+
+/* Write the "data" buffer to whatever output you are using */
+PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr,
+ png_const_bytep data, png_size_t length),PNG_EMPTY);
+
+/* Read and check the PNG file signature */
+PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+
+/* Read the chunk header (length + type name) */
+PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr),
+ PNG_EMPTY);
+
+/* Read data from whatever input you are using into the "data" buffer */
+PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data,
+ png_size_t length),PNG_EMPTY);
+
+/* Read bytes into buf, and update png_ptr->crc */
+PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf,
+ png_uint_32 length),PNG_EMPTY);
+
+/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr,
+ png_uint_32 skip),PNG_EMPTY);
+
+/* Read the CRC from the file and compare it to the libpng calculated CRC */
+PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY);
+
+/* Calculate the CRC over a section of data. Note that we are only
+ * passing a maximum of 64K on systems that have this as a memory limit,
+ * since this is the maximum buffer size we can specify.
+ */
+PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr,
+ png_const_bytep ptr, png_size_t length),PNG_EMPTY);
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY);
+#endif
+
+/* Write various chunks */
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.
+ */
+PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
+ int compression_method, int filter_method, int interlace_method),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr,
+ png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr,
+ png_const_bytep row_data, png_alloc_size_t row_data_length, int flush),
+ PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY);
+
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr,
+ png_fixed_point file_gamma),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr,
+ png_const_color_8p sbit, int color_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
+ const png_xy *xy), PNG_EMPTY);
+ /* The xy value must have been previously validated */
+#endif
+
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
+ int intent),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr,
+ png_bytep exif, int num_exif),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
+ png_const_charp name, png_const_bytep profile), PNG_EMPTY);
+ /* The profile must have been previously validated for correctness, the
+ * length comes from the first four bytes. Only the base, deflate,
+ * compression is supported.
+ */
+#endif
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr,
+ png_const_sPLT_tp palette),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr,
+ png_const_bytep trans, png_const_color_16p values, int number,
+ int color_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr,
+ png_const_color_16p values, int color_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr,
+ png_const_uint_16p hist, int num_hist),PNG_EMPTY);
+#endif
+
+/* Chunks that have keywords */
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr,
+ png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp
+ key, png_const_charp text, int compression),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr,
+ int compression, png_const_charp key, png_const_charp lang,
+ png_const_charp lang_key, png_const_charp text),PNG_EMPTY);
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */
+PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr,
+ png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr,
+ png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
+ png_const_charp units, png_charpp params),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr,
+ png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
+ int unit_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr,
+ png_const_timep mod_time),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr,
+ int unit, png_const_charp width, png_const_charp height),PNG_EMPTY);
+#endif
+
+/* Called when finished processing a row of data */
+PNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+
+/* Internal use only. Called before first row of data */
+PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+
+/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an
+ * array of png_ptr->width pixels. If the image is not interlaced or this
+ * is the final pass this just does a memcpy, otherwise the "display" flag
+ * is used to determine whether to copy pixels that are not in the current pass.
+ *
+ * Because 'png_do_read_interlace' (below) replicates pixels this allows this
+ * function to achieve the documented 'blocky' appearance during interlaced read
+ * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row'
+ * are not changed if they are not in the current pass, when display is 0.
+ *
+ * 'display' must be 0 or 1, otherwise the memcpy will be done regardless.
+ *
+ * The API always reads from the png_struct row buffer and always assumes that
+ * it is full width (png_do_read_interlace has already been called.)
+ *
+ * This function is only ever used to write to row buffers provided by the
+ * caller of the relevant libpng API and the row must have already been
+ * transformed by the read transformations.
+ *
+ * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed
+ * bitmasks for use within the code, otherwise runtime generated masks are used.
+ * The default is compile time masks.
+ */
+#ifndef PNG_USE_COMPILE_TIME_MASKS
+# define PNG_USE_COMPILE_TIME_MASKS 1
+#endif
+PNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr,
+ png_bytep row, int display),PNG_EMPTY);
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* Expand an interlaced row: the 'row_info' describes the pass data that has
+ * been read in and must correspond to the pixels in 'row', the pixels are
+ * expanded (moved apart) in 'row' to match the final layout, when doing this
+ * the pixels are *replicated* to the intervening space. This is essential for
+ * the correct operation of png_combine_row, above.
+ */
+PNG_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info,
+ png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY);
+#endif
+
+/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+/* Grab pixels out of a row for an interlaced pass */
+PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info,
+ png_bytep row, int pass),PNG_EMPTY);
+#endif
+
+/* Unfilter a row: check the filter value before calling this, there is no point
+ * calling it for PNG_FILTER_VALUE_NONE.
+ */
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);
+
+#if PNG_ARM_NEON_OPT > 0
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,
+ png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
+
+#if PNG_MIPS_MSA_OPT > 0
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info,
+ png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_msa,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_msa,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_msa,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_msa,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
+
+#if PNG_POWERPC_VSX_OPT > 0
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info,
+ png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_vsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_vsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_vsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_vsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_vsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_vsx,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
+
+#if PNG_INTEL_SSE_IMPLEMENTATION > 0
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+#endif
+
+/* Choose the best filter to use and filter the row data */
+PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
+ png_row_infop row_info),PNG_EMPTY);
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr,
+ png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY);
+ /* Read 'avail_out' bytes of data from the IDAT stream. If the output buffer
+ * is NULL the function checks, instead, for the end of the stream. In this
+ * case a benign error will be issued if the stream end is not found or if
+ * extra data has to be consumed.
+ */
+PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr),
+ PNG_EMPTY);
+ /* This cleans up when the IDAT LZ stream does not end when the last image
+ * byte is read; there is still some pending input.
+ */
+
+PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+ /* Finish a row while reading, dealing with interlacing passes, etc. */
+#endif /* SEQUENTIAL_READ */
+
+/* Initialize the row buffers, etc. */
+PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
+
+#if ZLIB_VERNUM >= 0x1240
+PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
+ PNG_EMPTY);
+# define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
+#else /* Zlib < 1.2.4 */
+# define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush)
+#endif /* Zlib < 1.2.4 */
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+/* Optional call to update the users info structure */
+PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+#endif
+
+/* Shared transform functions, defined in pngtran.c */
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+ defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info,
+ png_bytep row, int at_start),PNG_EMPTY);
+#endif
+
+#ifdef PNG_16BIT_SUPPORTED
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
+ defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+/* The following decodes the appropriate chunks, and does error correction,
+ * then calls the appropriate callback for the chunk if it is valid.
+ */
+
+/* Decode the IHDR chunk */
+PNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_eXIf_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_eXIf,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif /* READ_iCCP */
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif /* READ_sPLT */
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr,
+ const png_uint_32 chunk_name),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr,
+ const png_uint_32 chunk_length),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
+ /* This is the function that gets called for unknown chunks. The 'keep'
+ * argument is either non-zero for a known chunk that has been set to be
+ * handled as unknown or zero for an unknown chunk. By default the function
+ * just skips the chunk or errors out if it is critical.
+ */
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) ||\
+ defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling,
+ (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY);
+ /* Exactly as the API png_handle_as_unknown() except that the argument is a
+ * 32-bit chunk name, not a string.
+ */
+#endif /* READ_UNKNOWN_CHUNKS || HANDLE_AS_UNKNOWN */
+
+/* Handle the transformations for reading and writing */
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr,
+ png_row_infop row_info),PNG_EMPTY);
+#endif
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr,
+ png_row_infop row_info),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr),
+ PNG_EMPTY);
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr,
+ png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr,
+ png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
+ png_bytep row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+# ifdef PNG_READ_tEXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+# endif
+# ifdef PNG_READ_zTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+# endif
+# ifdef PNG_READ_iTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+# endif
+
+#endif /* PROGRESSIVE_READ */
+
+/* Added at libpng version 1.6.0 */
+#ifdef PNG_GAMMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY);
+ /* Set the colorspace gamma with a value provided by the application or by
+ * the gAMA chunk on read. The value will override anything set by an ICC
+ * profile.
+ */
+
+PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,
+ png_inforp info_ptr), PNG_EMPTY);
+ /* Synchronize the info 'valid' flags with the colorspace */
+
+PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,
+ png_inforp info_ptr), PNG_EMPTY);
+ /* Copy the png_struct colorspace to the info_struct and call the above to
+ * synchronize the flags. Checks for NULL info_ptr and does nothing.
+ */
+#endif
+
+/* Added at libpng version 1.4.0 */
+#ifdef PNG_COLORSPACE_SUPPORTED
+/* These internal functions are for maintaining the colorspace structure within
+ * a png_info or png_struct (or, indeed, both).
+ */
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities,
+ (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy,
+ int preferred), PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints,
+ (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ,
+ int preferred), PNG_EMPTY);
+
+#ifdef PNG_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, int intent), PNG_EMPTY);
+ /* This does set the colorspace gAMA and cHRM values too, but doesn't set the
+ * flags to write them, if it returns false there was a problem and an error
+ * message has already been output (but the colorspace may still need to be
+ * synced to record the invalid flag).
+ */
+#endif /* sRGB */
+
+#ifdef PNG_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length, png_const_bytep profile, int color_type),
+ PNG_EMPTY);
+ /* The 'name' is used for information only */
+
+/* Routines for checking parts of an ICC profile. */
+#ifdef PNG_READ_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length), PNG_EMPTY);
+#endif /* READ_iCCP */
+PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length,
+ png_const_bytep profile /* first 132 bytes only */, int color_type),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length,
+ png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY);
+#ifdef PNG_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,(
+ png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_bytep profile, uLong adler), PNG_EMPTY);
+ /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may
+ * be zero to indicate that it is not available. It is used, if provided,
+ * as a fast check on the profile when checking to see if it is sRGB.
+ */
+#endif
+#endif /* iCCP */
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients,
+ (png_structrp png_ptr), PNG_EMPTY);
+ /* Set the rgb_to_gray coefficients from the colorspace Y values */
+#endif /* READ_RGB_TO_GRAY */
+#endif /* COLORSPACE */
+
+/* Added at libpng version 1.4.0 */
+PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type),PNG_EMPTY);
+
+/* Added at libpng version 1.5.10 */
+#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
+ defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes,
+ (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY);
+#endif
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr,
+ png_const_charp name),PNG_NORETURN);
+#endif
+
+/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite
+ * the end. Always leaves the buffer nul terminated. Never errors out (and
+ * there is no error code.)
+ */
+PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize,
+ size_t pos, png_const_charp string),PNG_EMPTY);
+
+/* Various internal functions to handle formatted warning messages, currently
+ * only implemented for warnings.
+ */
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
+/* Utility to dump an unsigned value into a buffer, given a start pointer and
+ * and end pointer (which should point just *beyond* the end of the buffer!)
+ * Returns the pointer to the start of the formatted string. This utility only
+ * does unsigned values.
+ */
+PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start,
+ png_charp end, int format, png_alloc_size_t number),PNG_EMPTY);
+
+/* Convenience macro that takes an array: */
+#define PNG_FORMAT_NUMBER(buffer,format,number) \
+ png_format_number(buffer, buffer + (sizeof buffer), format, number)
+
+/* Suggested size for a number buffer (enough for 64 bits and a sign!) */
+#define PNG_NUMBER_BUFFER_SIZE 24
+
+/* These are the integer formats currently supported, the name is formed from
+ * the standard printf(3) format string.
+ */
+#define PNG_NUMBER_FORMAT_u 1 /* chose unsigned API! */
+#define PNG_NUMBER_FORMAT_02u 2
+#define PNG_NUMBER_FORMAT_d 1 /* chose signed API! */
+#define PNG_NUMBER_FORMAT_02d 2
+#define PNG_NUMBER_FORMAT_x 3
+#define PNG_NUMBER_FORMAT_02x 4
+#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */
+#endif
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* New defines and members adding in libpng-1.5.4 */
+# define PNG_WARNING_PARAMETER_SIZE 32
+# define PNG_WARNING_PARAMETER_COUNT 8 /* Maximum 9; see pngerror.c */
+
+/* An l-value of this type has to be passed to the APIs below to cache the
+ * values of the parameters to a formatted warning message.
+ */
+typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][
+ PNG_WARNING_PARAMETER_SIZE];
+
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p,
+ int number, png_const_charp string),PNG_EMPTY);
+ /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters,
+ * including the trailing '\0'.
+ */
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned,
+ (png_warning_parameters p, int number, int format, png_alloc_size_t value),
+ PNG_EMPTY);
+ /* Use png_alloc_size_t because it is an unsigned type as big as any we
+ * need to output. Use the following for a signed value.
+ */
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed,
+ (png_warning_parameters p, int number, int format, png_int_32 value),
+ PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr,
+ png_warning_parameters p, png_const_charp message),PNG_EMPTY);
+ /* 'message' follows the X/Open approach of using @1, @2 to insert
+ * parameters previously supplied using the above functions. Errors in
+ * specifying the parameters will simply result in garbage substitutions.
+ */
+#endif
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+/* Application errors (new in 1.6); use these functions (declared below) for
+ * errors in the parameters or order of API function calls on read. The
+ * 'warning' should be used for an error that can be handled completely; the
+ * 'error' for one which can be handled safely but which may lose application
+ * information or settings.
+ *
+ * By default these both result in a png_error call prior to release, while in a
+ * released version the 'warning' is just a warning. However if the application
+ * explicitly disables benign errors (explicitly permitting the code to lose
+ * information) they both turn into warnings.
+ *
+ * If benign errors aren't supported they end up as the corresponding base call
+ * (png_warning or png_error.)
+ */
+PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr,
+ png_const_charp message),PNG_EMPTY);
+ /* The application provided invalid parameters to an API function or called
+ * an API function at the wrong time, libpng can completely recover.
+ */
+
+PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr,
+ png_const_charp message),PNG_EMPTY);
+ /* As above but libpng will ignore the call, or attempt some other partial
+ * recovery from the error.
+ */
+#else
+# define png_app_warning(pp,s) png_warning(pp,s)
+# define png_app_error(pp,s) png_error(pp,s)
+#endif
+
+PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr,
+ png_const_charp message, int error),PNG_EMPTY);
+ /* Report a recoverable issue in chunk data. On read this is used to report
+ * a problem found while reading a particular chunk and the
+ * png_chunk_benign_error or png_chunk_warning function is used as
+ * appropriate. On write this is used to report an error that comes from
+ * data set via an application call to a png_set_ API and png_app_error or
+ * png_app_warning is used as appropriate.
+ *
+ * The 'error' parameter must have one of the following values:
+ */
+#define PNG_CHUNK_WARNING 0 /* never an error */
+#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */
+#define PNG_CHUNK_ERROR 2 /* always an error */
+
+/* ASCII to FP interfaces, currently only implemented if sCAL
+ * support is required.
+ */
+#if defined(PNG_sCAL_SUPPORTED)
+/* MAX_DIGITS is actually the maximum number of characters in an sCAL
+ * width or height, derived from the precision (number of significant
+ * digits - a build time settable option) and assumptions about the
+ * maximum ridiculous exponent.
+ */
+#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/)
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr,
+ png_charp ascii, png_size_t size, double fp, unsigned int precision),
+ PNG_EMPTY);
+#endif /* FLOATING_POINT */
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,
+ png_charp ascii, png_size_t size, png_fixed_point fp),PNG_EMPTY);
+#endif /* FIXED_POINT */
+#endif /* sCAL */
+
+#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
+/* An internal API to validate the format of a floating point number.
+ * The result is the index of the next character. If the number is
+ * not valid it will be the index of a character in the supposed number.
+ *
+ * The format of a number is defined in the PNG extensions specification
+ * and this API is strictly conformant to that spec, not anyone elses!
+ *
+ * The format as a regular expression is:
+ *
+ * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)?
+ *
+ * or:
+ *
+ * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)?
+ *
+ * The complexity is that either integer or fraction must be present and the
+ * fraction is permitted to have no digits only if the integer is present.
+ *
+ * NOTE: The dangling E problem.
+ * There is a PNG valid floating point number in the following:
+ *
+ * PNG floating point numbers are not greedy.
+ *
+ * Working this out requires *TWO* character lookahead (because of the
+ * sign), the parser does not do this - it will fail at the 'r' - this
+ * doesn't matter for PNG sCAL chunk values, but it requires more care
+ * if the value were ever to be embedded in something more complex. Use
+ * ANSI-C strtod if you need the lookahead.
+ */
+/* State table for the parser. */
+#define PNG_FP_INTEGER 0 /* before or in integer */
+#define PNG_FP_FRACTION 1 /* before or in fraction */
+#define PNG_FP_EXPONENT 2 /* before or in exponent */
+#define PNG_FP_STATE 3 /* mask for the above */
+#define PNG_FP_SAW_SIGN 4 /* Saw +/- in current state */
+#define PNG_FP_SAW_DIGIT 8 /* Saw a digit in current state */
+#define PNG_FP_SAW_DOT 16 /* Saw a dot in current state */
+#define PNG_FP_SAW_E 32 /* Saw an E (or e) in current state */
+#define PNG_FP_SAW_ANY 60 /* Saw any of the above 4 */
+
+/* These three values don't affect the parser. They are set but not used.
+ */
+#define PNG_FP_WAS_VALID 64 /* Preceding substring is a valid fp number */
+#define PNG_FP_NEGATIVE 128 /* A negative number, including "-0" */
+#define PNG_FP_NONZERO 256 /* A non-zero value */
+#define PNG_FP_STICKY 448 /* The above three flags */
+
+/* This is available for the caller to store in 'state' if required. Do not
+ * call the parser after setting it (the parser sometimes clears it.)
+ */
+#define PNG_FP_INVALID 512 /* Available for callers as a distinct value */
+
+/* Result codes for the parser (boolean - true meants ok, false means
+ * not ok yet.)
+ */
+#define PNG_FP_MAYBE 0 /* The number may be valid in the future */
+#define PNG_FP_OK 1 /* The number is valid */
+
+/* Tests on the sticky non-zero and negative flags. To pass these checks
+ * the state must also indicate that the whole number is valid - this is
+ * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this
+ * is equivalent to PNG_FP_OK above.)
+ */
+#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO)
+ /* NZ_MASK: the string is valid and a non-zero negative value */
+#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO)
+ /* Z MASK: the string is valid and a non-zero value. */
+ /* PNG_FP_SAW_DIGIT: the string is valid. */
+#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT)
+#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK)
+#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK)
+
+/* The actual parser. This can be called repeatedly. It updates
+ * the index into the string and the state variable (which must
+ * be initialized to 0). It returns a result code, as above. There
+ * is no point calling the parser any more if it fails to advance to
+ * the end of the string - it is stuck on an invalid character (or
+ * terminated by '\0').
+ *
+ * Note that the pointer will consume an E or even an E+ and then leave
+ * a 'maybe' state even though a preceding integer.fraction is valid.
+ * The PNG_FP_WAS_VALID flag indicates that a preceding substring was
+ * a valid number. It's possible to recover from this by calling
+ * the parser again (from the start, with state 0) but with a string
+ * that omits the last character (i.e. set the size to the index of
+ * the problem character.) This has not been tested within libpng.
+ */
+PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
+ png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY);
+
+/* This is the same but it checks a complete string and returns true
+ * only if it just contains a floating point number. As of 1.5.4 this
+ * function also returns the state at the end of parsing the number if
+ * it was valid (otherwise it returns 0.) This can be used for testing
+ * for negative or zero values using the sticky flag.
+ */
+PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
+ png_size_t size),PNG_EMPTY);
+#endif /* pCAL || sCAL */
+
+#if defined(PNG_GAMMA_SUPPORTED) ||\
+ defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
+/* Added at libpng version 1.5.0 */
+/* This is a utility to provide a*times/div (rounded) and indicate
+ * if there is an overflow. The result is a boolean - false (0)
+ * for overflow, true (1) if no overflow, in which case *res
+ * holds the result.
+ */
+PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a,
+ png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY);
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+/* Same deal, but issue a warning on overflow and return 0. */
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn,
+ (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by,
+ png_int_32 divided_by),PNG_EMPTY);
+#endif
+
+#ifdef PNG_GAMMA_SUPPORTED
+/* Calculate a reciprocal - used for gamma values. This returns
+ * 0 if the argument is 0 in order to maintain an undefined value;
+ * there are no warnings.
+ */
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a),
+ PNG_EMPTY);
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* The same but gives a reciprocal of the product of two fixed point
+ * values. Accuracy is suitable for gamma calculations but this is
+ * not exact - use png_muldiv for that. Only required at present on read.
+ */
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a,
+ png_fixed_point b),PNG_EMPTY);
+#endif
+
+/* Return true if the gamma value is significantly different from 1.0 */
+PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value),
+ PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* Internal fixed point gamma correction. These APIs are called as
+ * required to convert single values - they don't need to be fast,
+ * they are not used when processing image pixel values.
+ *
+ * While the input is an 'unsigned' value it must actually be the
+ * correct bit value - 0..255 or 0..65535 as required.
+ */
+PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr,
+ unsigned int value, png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value,
+ png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value,
+ png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr,
+ int bit_depth),PNG_EMPTY);
+#endif
+
+/* SIMPLIFIED READ/WRITE SUPPORT */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+/* The internal structure that png_image::opaque points to. */
+typedef struct png_control
+{
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_voidp error_buf; /* Always a jmp_buf at present. */
+
+ png_const_bytep memory; /* Memory buffer. */
+ png_size_t size; /* Size of the memory buffer. */
+
+ unsigned int for_write :1; /* Otherwise it is a read structure */
+ unsigned int owned_file :1; /* We own the file in io_ptr */
+} png_control;
+
+/* Return the pointer to the jmp_buf from a png_control: necessary because C
+ * does not reveal the type of the elements of jmp_buf.
+ */
+#ifdef __cplusplus
+# define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0])
+#else
+# define png_control_jmp_buf(pc) ((pc)->error_buf)
+#endif
+
+/* Utility to safely execute a piece of libpng code catching and logging any
+ * errors that might occur. Returns true on success, false on failure (either
+ * of the function or as a result of a png_error.)
+ */
+PNG_INTERNAL_CALLBACK(void,png_safe_error,(png_structp png_ptr,
+ png_const_charp error_message),PNG_NORETURN);
+
+#ifdef PNG_WARNINGS_SUPPORTED
+PNG_INTERNAL_CALLBACK(void,png_safe_warning,(png_structp png_ptr,
+ png_const_charp warning_message),PNG_EMPTY);
+#else
+# define png_safe_warning 0/*dummy argument*/
+#endif
+
+PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image,
+ int (*function)(png_voidp), png_voidp arg),PNG_EMPTY);
+
+/* Utility to log an error; this also cleans up the png_image; the function
+ * always returns 0 (false).
+ */
+PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image,
+ png_const_charp error_message),PNG_EMPTY);
+
+#ifndef PNG_SIMPLIFIED_READ_SUPPORTED
+/* png_image_free is used by the write code but not exported */
+PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY);
+#endif /* !SIMPLIFIED_READ */
+
+#endif /* SIMPLIFIED READ/WRITE */
+
+/* These are initialization functions for hardware specific PNG filter
+ * optimizations; list these here then select the appropriate one at compile
+ * time using the macro PNG_FILTER_OPTIMIZATIONS. If the macro is not defined
+ * the generic code is used.
+ */
+#ifdef PNG_FILTER_OPTIMIZATIONS
+PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr,
+ unsigned int bpp), PNG_EMPTY);
+ /* Just declare the optimization that will be used */
+#else
+ /* List *all* the possible optimizations here - this branch is required if
+ * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
+ * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
+ */
+# if PNG_ARM_NEON_OPT > 0
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
+ (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+#endif
+
+#if PNG_MIPS_MSA_OPT > 0
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa,
+ (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+#endif
+
+# if PNG_INTEL_SSE_IMPLEMENTATION > 0
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
+ (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+# endif
+#endif
+
+PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
+ png_const_charp key, png_bytep new_key), PNG_EMPTY);
+
+/* Maintainer: Put new private prototypes here ^ */
+
+#include "pngdebug.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNG_VERSION_INFO_ONLY */
+#endif /* PNGPRIV_H */
diff --git a/xs/src/png/libpng/pngread.c b/xs/src/png/libpng/pngread.c
new file mode 100644
index 000000000..da32e9ad9
--- /dev/null
+++ b/xs/src/png/libpng/pngread.c
@@ -0,0 +1,4219 @@
+
+/* pngread.c - read a PNG file
+ *
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains routines that an application calls directly to
+ * read a PNG file or stream.
+ */
+
+#include "pngpriv.h"
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
+# include <errno.h>
+#endif
+
+#ifdef PNG_READ_SUPPORTED
+
+/* Create a PNG structure for reading, and allocate any memory needed. */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
+{
+#ifndef PNG_USER_MEM_SUPPORTED
+ png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+ error_fn, warn_fn, NULL, NULL, NULL);
+#else
+ return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
+ warn_fn, NULL, NULL, NULL);
+}
+
+/* Alternate create PNG structure for reading, and allocate any memory
+ * needed.
+ */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
+{
+ png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+ error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+#endif /* USER_MEM */
+
+ if (png_ptr != NULL)
+ {
+ png_ptr->mode = PNG_IS_READ_STRUCT;
+
+ /* Added in libpng-1.6.0; this can be used to detect a read structure if
+ * required (it will be zero in a write structure.)
+ */
+# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE;
+# endif
+
+# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
+
+ /* In stable builds only warn if an application error can be completely
+ * handled.
+ */
+# if PNG_RELEASE_BUILD
+ png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
+# endif
+# endif
+
+ /* TODO: delay this, it can be done in png_init_io (if the app doesn't
+ * do it itself) avoiding setting the default function if it is not
+ * required.
+ */
+ png_set_read_fn(png_ptr, NULL, NULL);
+ }
+
+ return png_ptr;
+}
+
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data. This has been
+ * changed in v0.90 to allow reading a file that already has the magic
+ * bytes read from the stream. You can tell libpng how many bytes have
+ * been read from the beginning of the stream (up to the maximum of 8)
+ * via png_set_sig_bytes(), and we will only check the remaining bytes
+ * here. The application can then have access to the signature bytes we
+ * read if it is determined that this isn't a valid PNG file.
+ */
+void PNGAPI
+png_read_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ int keep;
+#endif
+
+ png_debug(1, "in png_read_info");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* Read and check the PNG file signature. */
+ png_read_sig(png_ptr, info_ptr);
+
+ for (;;)
+ {
+ png_uint_32 length = png_read_chunk_header(png_ptr);
+ png_uint_32 chunk_name = png_ptr->chunk_name;
+
+ /* IDAT logic needs to happen here to simplify getting the two flags
+ * right.
+ */
+ if (chunk_name == png_IDAT)
+ {
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "Missing IHDR before IDAT");
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ (png_ptr->mode & PNG_HAVE_PLTE) == 0)
+ png_chunk_error(png_ptr, "Missing PLTE before IDAT");
+
+ else if ((png_ptr->mode & PNG_AFTER_IDAT) != 0)
+ png_chunk_benign_error(png_ptr, "Too many IDATs found");
+
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ }
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ {
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ }
+
+ /* This should be a binary subdivision search or a hash for
+ * matching the chunk name rather than a linear search.
+ */
+ if (chunk_name == png_IHDR)
+ png_handle_IHDR(png_ptr, info_ptr, length);
+
+ else if (chunk_name == png_IEND)
+ png_handle_IEND(png_ptr, info_ptr, length);
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
+ {
+ png_handle_unknown(png_ptr, info_ptr, length, keep);
+
+ if (chunk_name == png_PLTE)
+ png_ptr->mode |= PNG_HAVE_PLTE;
+
+ else if (chunk_name == png_IDAT)
+ {
+ png_ptr->idat_size = 0; /* It has been consumed */
+ break;
+ }
+ }
+#endif
+ else if (chunk_name == png_PLTE)
+ png_handle_PLTE(png_ptr, info_ptr, length);
+
+ else if (chunk_name == png_IDAT)
+ {
+ png_ptr->idat_size = length;
+ break;
+ }
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (chunk_name == png_bKGD)
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (chunk_name == png_cHRM)
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_eXIf_SUPPORTED
+ else if (chunk_name == png_eXIf)
+ png_handle_eXIf(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (chunk_name == png_gAMA)
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (chunk_name == png_hIST)
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (chunk_name == png_oFFs)
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (chunk_name == png_pCAL)
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (chunk_name == png_sCAL)
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (chunk_name == png_pHYs)
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (chunk_name == png_sBIT)
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (chunk_name == png_sRGB)
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (chunk_name == png_iCCP)
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (chunk_name == png_sPLT)
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (chunk_name == png_tEXt)
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (chunk_name == png_tIME)
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (chunk_name == png_tRNS)
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (chunk_name == png_zTXt)
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (chunk_name == png_iTXt)
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+
+ else
+ png_handle_unknown(png_ptr, info_ptr, length,
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
+ }
+}
+#endif /* SEQUENTIAL_READ */
+
+/* Optional call to update the users info_ptr structure */
+void PNGAPI
+png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_debug(1, "in png_read_update_info");
+
+ if (png_ptr != NULL)
+ {
+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+ {
+ png_read_start_row(png_ptr);
+
+# ifdef PNG_READ_TRANSFORMS_SUPPORTED
+ png_read_transform_info(png_ptr, info_ptr);
+# else
+ PNG_UNUSED(info_ptr)
+# endif
+ }
+
+ /* New in 1.6.0 this avoids the bug of doing the initializations twice */
+ else
+ png_app_error(png_ptr,
+ "png_read_update_info/png_start_read_image: duplicate call");
+ }
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Initialize palette, background, etc, after transformations
+ * are set, but before any reading takes place. This allows
+ * the user to obtain a gamma-corrected palette, for example.
+ * If the user doesn't call this, we will do it ourselves.
+ */
+void PNGAPI
+png_start_read_image(png_structrp png_ptr)
+{
+ png_debug(1, "in png_start_read_image");
+
+ if (png_ptr != NULL)
+ {
+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+ png_read_start_row(png_ptr);
+
+ /* New in 1.6.0 this avoids the bug of doing the initializations twice */
+ else
+ png_app_error(png_ptr,
+ "png_start_read_image/png_read_update_info: duplicate call");
+ }
+}
+#endif /* SEQUENTIAL_READ */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Undoes intrapixel differencing,
+ * NOTE: this is apparently only supported in the 'sequential' reader.
+ */
+static void
+png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_intrapixel");
+
+ if (
+ (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ {
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
+
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
+
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
+ *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
+
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1);
+ png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
+ png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
+ png_uint_32 red = (s0 + s1 + 65536) & 0xffff;
+ png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
+ *(rp ) = (png_byte)((red >> 8) & 0xff);
+ *(rp + 1) = (png_byte)(red & 0xff);
+ *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
+ *(rp + 5) = (png_byte)(blue & 0xff);
+ }
+ }
+ }
+}
+#endif /* MNG_FEATURES */
+
+void PNGAPI
+png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
+{
+ png_row_info row_info;
+
+ if (png_ptr == NULL)
+ return;
+
+ png_debug2(1, "in png_read_row (row %lu, pass %d)",
+ (unsigned long)png_ptr->row_number, png_ptr->pass);
+
+ /* png_read_start_row sets the information (in particular iwidth) for this
+ * interlace pass.
+ */
+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+ png_read_start_row(png_ptr);
+
+ /* 1.5.6: row_info moved out of png_struct to a local here. */
+ row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
+ row_info.color_type = png_ptr->color_type;
+ row_info.bit_depth = png_ptr->bit_depth;
+ row_info.channels = png_ptr->channels;
+ row_info.pixel_depth = png_ptr->pixel_depth;
+ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
+
+#ifdef PNG_WARNINGS_SUPPORTED
+ if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+ {
+ /* Check for transforms that have been set but were defined out */
+#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
+ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
+ png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
+ if ((png_ptr->transformations & PNG_FILLER) != 0)
+ png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
+ !defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+ png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
+ if ((png_ptr->transformations & PNG_PACK) != 0)
+ png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
+ if ((png_ptr->transformations & PNG_SHIFT) != 0)
+ png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
+ if ((png_ptr->transformations & PNG_BGR) != 0)
+ png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
+ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
+ png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
+#endif
+ }
+#endif /* WARNINGS */
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* If interlaced and we do not need a new row, combine row and return.
+ * Notice that the pixels we have from previous rows have been transformed
+ * already; we can only combine like with like (transformed or
+ * untransformed) and, because of the libpng API for interlaced images, this
+ * means we must transform before de-interlacing.
+ */
+ if (png_ptr->interlaced != 0 &&
+ (png_ptr->transformations & PNG_INTERLACE) != 0)
+ {
+ switch (png_ptr->pass)
+ {
+ case 0:
+ if (png_ptr->row_number & 0x07)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 1:
+ if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 2:
+ if ((png_ptr->row_number & 0x07) != 4)
+ {
+ if (dsp_row != NULL && (png_ptr->row_number & 4))
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 3:
+ if ((png_ptr->row_number & 3) || png_ptr->width < 3)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 4:
+ if ((png_ptr->row_number & 3) != 2)
+ {
+ if (dsp_row != NULL && (png_ptr->row_number & 2))
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 5:
+ if ((png_ptr->row_number & 1) || png_ptr->width < 2)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ default:
+ case 6:
+ if ((png_ptr->row_number & 1) == 0)
+ {
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ }
+ }
+#endif
+
+ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)
+ png_error(png_ptr, "Invalid attempt to read row data");
+
+ /* Fill the row with IDAT data: */
+ png_ptr->row_buf[0]=255; /* to force error if no data was found */
+ png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);
+
+ if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
+ {
+ if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
+ png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
+ png_ptr->prev_row + 1, png_ptr->row_buf[0]);
+ else
+ png_error(png_ptr, "bad adaptive filter value");
+ }
+
+ /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
+ * 1.5.6, while the buffer really is this big in current versions of libpng
+ * it may not be in the future, so this was changed just to copy the
+ * interlaced count:
+ */
+ memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+ (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+ {
+ /* Intrapixel differencing */
+ png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1);
+ }
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+ if (png_ptr->transformations)
+ png_do_read_transformations(png_ptr, &row_info);
+#endif
+
+ /* The transformed pixel depth should match the depth now in row_info. */
+ if (png_ptr->transformed_pixel_depth == 0)
+ {
+ png_ptr->transformed_pixel_depth = row_info.pixel_depth;
+ if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
+ png_error(png_ptr, "sequential row overflow");
+ }
+
+ else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
+ png_error(png_ptr, "internal sequential row size calculation error");
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Expand interlaced rows to full size */
+ if (png_ptr->interlaced != 0 &&
+ (png_ptr->transformations & PNG_INTERLACE) != 0)
+ {
+ if (png_ptr->pass < 6)
+ png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
+ png_ptr->transformations);
+
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ if (row != NULL)
+ png_combine_row(png_ptr, row, 0/*row*/);
+ }
+
+ else
+#endif
+ {
+ if (row != NULL)
+ png_combine_row(png_ptr, row, -1/*ignored*/);
+
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, -1/*ignored*/);
+ }
+ png_read_finish_row(png_ptr);
+
+ if (png_ptr->read_row_fn != NULL)
+ (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+
+}
+#endif /* SEQUENTIAL_READ */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data. If the image is interlaced,
+ * and png_set_interlace_handling() has been called, the rows need to
+ * contain the contents of the rows from the previous pass. If the
+ * image has alpha or transparency, and png_handle_alpha()[*] has been
+ * called, the rows contents must be initialized to the contents of the
+ * screen.
+ *
+ * "row" holds the actual image, and pixels are placed in it
+ * as they arrive. If the image is displayed after each pass, it will
+ * appear to "sparkle" in. "display_row" can be used to display a
+ * "chunky" progressive image, with finer detail added as it becomes
+ * available. If you do not want this "chunky" display, you may pass
+ * NULL for display_row. If you do not want the sparkle display, and
+ * you have not called png_handle_alpha(), you may pass NULL for rows.
+ * If you have called png_handle_alpha(), and the image has either an
+ * alpha channel or a transparency chunk, you must provide a buffer for
+ * rows. In this case, you do not have to provide a display_row buffer
+ * also, but you may. If the image is not interlaced, or if you have
+ * not called png_set_interlace_handling(), the display_row buffer will
+ * be ignored, so pass NULL to it.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+
+void PNGAPI
+png_read_rows(png_structrp png_ptr, png_bytepp row,
+ png_bytepp display_row, png_uint_32 num_rows)
+{
+ png_uint_32 i;
+ png_bytepp rp;
+ png_bytepp dp;
+
+ png_debug(1, "in png_read_rows");
+
+ if (png_ptr == NULL)
+ return;
+
+ rp = row;
+ dp = display_row;
+ if (rp != NULL && dp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep rptr = *rp++;
+ png_bytep dptr = *dp++;
+
+ png_read_row(png_ptr, rptr, dptr);
+ }
+
+ else if (rp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep rptr = *rp;
+ png_read_row(png_ptr, rptr, NULL);
+ rp++;
+ }
+
+ else if (dp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep dptr = *dp;
+ png_read_row(png_ptr, NULL, dptr);
+ dp++;
+ }
+}
+#endif /* SEQUENTIAL_READ */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the entire image. If the image has an alpha channel or a tRNS
+ * chunk, and you have called png_handle_alpha()[*], you will need to
+ * initialize the image to the current image that PNG will be overlaying.
+ * We set the num_rows again here, in case it was incorrectly set in
+ * png_read_start_row() by a call to png_read_update_info() or
+ * png_start_read_image() if png_set_interlace_handling() wasn't called
+ * prior to either of these functions like it should have been. You can
+ * only call this function once. If you desire to have an image for
+ * each pass of a interlaced image, use png_read_rows() instead.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+void PNGAPI
+png_read_image(png_structrp png_ptr, png_bytepp image)
+{
+ png_uint_32 i, image_height;
+ int pass, j;
+ png_bytepp rp;
+
+ png_debug(1, "in png_read_image");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+ {
+ pass = png_set_interlace_handling(png_ptr);
+ /* And make sure transforms are initialized. */
+ png_start_read_image(png_ptr);
+ }
+ else
+ {
+ if (png_ptr->interlaced != 0 &&
+ (png_ptr->transformations & PNG_INTERLACE) == 0)
+ {
+ /* Caller called png_start_read_image or png_read_update_info without
+ * first turning on the PNG_INTERLACE transform. We can fix this here,
+ * but the caller should do it!
+ */
+ png_warning(png_ptr, "Interlace handling should be turned on when "
+ "using png_read_image");
+ /* Make sure this is set correctly */
+ png_ptr->num_rows = png_ptr->height;
+ }
+
+ /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
+ * the above error case.
+ */
+ pass = png_set_interlace_handling(png_ptr);
+ }
+#else
+ if (png_ptr->interlaced)
+ png_error(png_ptr,
+ "Cannot read interlaced image -- interlace handler disabled");
+
+ pass = 1;
+#endif
+
+ image_height=png_ptr->height;
+
+ for (j = 0; j < pass; j++)
+ {
+ rp = image;
+ for (i = 0; i < image_height; i++)
+ {
+ png_read_row(png_ptr, *rp, NULL);
+ rp++;
+ }
+ }
+}
+#endif /* SEQUENTIAL_READ */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file. Will not read past the end of the
+ * file, will verify the end is accurate, and will read any comments
+ * or time information at the end of the file, if info is not NULL.
+ */
+void PNGAPI
+png_read_end(png_structrp png_ptr, png_inforp info_ptr)
+{
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ int keep;
+#endif
+
+ png_debug(1, "in png_read_end");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* If png_read_end is called in the middle of reading the rows there may
+ * still be pending IDAT data and an owned zstream. Deal with this here.
+ */
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ if (png_chunk_unknown_handling(png_ptr, png_IDAT) == 0)
+#endif
+ png_read_finish_IDAT(png_ptr);
+
+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ /* Report invalid palette index; added at libng-1.5.10 */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ png_ptr->num_palette_max > png_ptr->num_palette)
+ png_benign_error(png_ptr, "Read palette index exceeding num_palette");
+#endif
+
+ do
+ {
+ png_uint_32 length = png_read_chunk_header(png_ptr);
+ png_uint_32 chunk_name = png_ptr->chunk_name;
+
+ if (chunk_name != png_IDAT)
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
+ if (chunk_name == png_IEND)
+ png_handle_IEND(png_ptr, info_ptr, length);
+
+ else if (chunk_name == png_IHDR)
+ png_handle_IHDR(png_ptr, info_ptr, length);
+
+ else if (info_ptr == NULL)
+ png_crc_finish(png_ptr, length);
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
+ {
+ if (chunk_name == png_IDAT)
+ {
+ if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+ || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+ png_benign_error(png_ptr, ".Too many IDATs found");
+ }
+ png_handle_unknown(png_ptr, info_ptr, length, keep);
+ if (chunk_name == png_PLTE)
+ png_ptr->mode |= PNG_HAVE_PLTE;
+ }
+#endif
+
+ else if (chunk_name == png_IDAT)
+ {
+ /* Zero length IDATs are legal after the last IDAT has been
+ * read, but not after other chunks have been read. 1.6 does not
+ * always read all the deflate data; specifically it cannot be relied
+ * upon to read the Adler32 at the end. If it doesn't ignore IDAT
+ * chunks which are longer than zero as well:
+ */
+ if ((length > 0 && !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+ || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) != 0)
+ png_benign_error(png_ptr, "..Too many IDATs found");
+
+ png_crc_finish(png_ptr, length);
+ }
+ else if (chunk_name == png_PLTE)
+ png_handle_PLTE(png_ptr, info_ptr, length);
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (chunk_name == png_bKGD)
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (chunk_name == png_cHRM)
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_eXIf_SUPPORTED
+ else if (chunk_name == png_eXIf)
+ png_handle_eXIf(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (chunk_name == png_gAMA)
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (chunk_name == png_hIST)
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (chunk_name == png_oFFs)
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (chunk_name == png_pCAL)
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (chunk_name == png_sCAL)
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (chunk_name == png_pHYs)
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (chunk_name == png_sBIT)
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (chunk_name == png_sRGB)
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (chunk_name == png_iCCP)
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (chunk_name == png_sPLT)
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (chunk_name == png_tEXt)
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (chunk_name == png_tIME)
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (chunk_name == png_tRNS)
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (chunk_name == png_zTXt)
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (chunk_name == png_iTXt)
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+
+ else
+ png_handle_unknown(png_ptr, info_ptr, length,
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
+ } while ((png_ptr->mode & PNG_HAVE_IEND) == 0);
+}
+#endif /* SEQUENTIAL_READ */
+
+/* Free all memory used in the read struct */
+static void
+png_read_destroy(png_structrp png_ptr)
+{
+ png_debug(1, "in png_read_destroy");
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ png_destroy_gamma_table(png_ptr);
+#endif
+
+ png_free(png_ptr, png_ptr->big_row_buf);
+ png_ptr->big_row_buf = NULL;
+ png_free(png_ptr, png_ptr->big_prev_row);
+ png_ptr->big_prev_row = NULL;
+ png_free(png_ptr, png_ptr->read_buffer);
+ png_ptr->read_buffer = NULL;
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+ png_free(png_ptr, png_ptr->palette_lookup);
+ png_ptr->palette_lookup = NULL;
+ png_free(png_ptr, png_ptr->quantize_index);
+ png_ptr->quantize_index = NULL;
+#endif
+
+ if ((png_ptr->free_me & PNG_FREE_PLTE) != 0)
+ {
+ png_zfree(png_ptr, png_ptr->palette);
+ png_ptr->palette = NULL;
+ }
+ png_ptr->free_me &= ~PNG_FREE_PLTE;
+
+#if defined(PNG_tRNS_SUPPORTED) || \
+ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if ((png_ptr->free_me & PNG_FREE_TRNS) != 0)
+ {
+ png_free(png_ptr, png_ptr->trans_alpha);
+ png_ptr->trans_alpha = NULL;
+ }
+ png_ptr->free_me &= ~PNG_FREE_TRNS;
+#endif
+
+ inflateEnd(&png_ptr->zstream);
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ png_free(png_ptr, png_ptr->save_buffer);
+ png_ptr->save_buffer = NULL;
+#endif
+
+#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) && \
+ defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ png_free(png_ptr, png_ptr->chunk_list);
+ png_ptr->chunk_list = NULL;
+#endif
+
+ /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error
+ * callbacks are still set at this point. They are required to complete the
+ * destruction of the png_struct itself.
+ */
+}
+
+/* Free all memory used by the read */
+void PNGAPI
+png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
+ png_infopp end_info_ptr_ptr)
+{
+ png_structrp png_ptr = NULL;
+
+ png_debug(1, "in png_destroy_read_struct");
+
+ if (png_ptr_ptr != NULL)
+ png_ptr = *png_ptr_ptr;
+
+ if (png_ptr == NULL)
+ return;
+
+ /* libpng 1.6.0: use the API to destroy info structs to ensure consistent
+ * behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API.
+ * The extra was, apparently, unnecessary yet this hides memory leak bugs.
+ */
+ png_destroy_info_struct(png_ptr, end_info_ptr_ptr);
+ png_destroy_info_struct(png_ptr, info_ptr_ptr);
+
+ *png_ptr_ptr = NULL;
+ png_read_destroy(png_ptr);
+ png_destroy_png_struct(png_ptr);
+}
+
+void PNGAPI
+png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->read_row_fn = read_row_fn;
+}
+
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_read_png(png_structrp png_ptr, png_inforp info_ptr,
+ int transforms, voidp params)
+{
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* png_read_info() gives us all of the information from the
+ * PNG file before the first IDAT (image data chunk).
+ */
+ png_read_info(png_ptr, info_ptr);
+ if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep)))
+ png_error(png_ptr, "Image is too high to process with png_read_png()");
+
+ /* -------------- image transformations start here ------------------- */
+ /* libpng 1.6.10: add code to cause a png_app_error if a selected TRANSFORM
+ * is not implemented. This will only happen in de-configured (non-default)
+ * libpng builds. The results can be unexpected - png_read_png may return
+ * short or mal-formed rows because the transform is skipped.
+ */
+
+ /* Tell libpng to strip 16-bit/color files down to 8 bits per color.
+ */
+ if ((transforms & PNG_TRANSFORM_SCALE_16) != 0)
+ /* Added at libpng-1.5.4. "strip_16" produces the same result that it
+ * did in earlier versions, while "scale_16" is now more accurate.
+ */
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ png_set_scale_16(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SCALE_16 not supported");
+#endif
+
+ /* If both SCALE and STRIP are required pngrtran will effectively cancel the
+ * latter by doing SCALE first. This is ok and allows apps not to check for
+ * which is supported to get the right answer.
+ */
+ if ((transforms & PNG_TRANSFORM_STRIP_16) != 0)
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ png_set_strip_16(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_16 not supported");
+#endif
+
+ /* Strip alpha bytes from the input data without combining with
+ * the background (not recommended).
+ */
+ if ((transforms & PNG_TRANSFORM_STRIP_ALPHA) != 0)
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ png_set_strip_alpha(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_ALPHA not supported");
+#endif
+
+ /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
+ * byte into separate bytes (useful for paletted and grayscale images).
+ */
+ if ((transforms & PNG_TRANSFORM_PACKING) != 0)
+#ifdef PNG_READ_PACK_SUPPORTED
+ png_set_packing(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
+#endif
+
+ /* Change the order of packed pixels to least significant bit first
+ * (not useful if you are using png_set_packing).
+ */
+ if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ png_set_packswap(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
+#endif
+
+ /* Expand paletted colors into true RGB triplets
+ * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
+ * Expand paletted or RGB images with transparency to full alpha
+ * channels so the data will be available as RGBA quartets.
+ */
+ if ((transforms & PNG_TRANSFORM_EXPAND) != 0)
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ png_set_expand(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND not supported");
+#endif
+
+ /* We don't handle background color or gamma transformation or quantizing.
+ */
+
+ /* Invert monochrome files to have 0 as white and 1 as black
+ */
+ if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)
+#ifdef PNG_READ_INVERT_SUPPORTED
+ png_set_invert_mono(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
+#endif
+
+ /* If you want to shift the pixel values from the range [0,255] or
+ * [0,65535] to the original [0,7] or [0,31], or whatever range the
+ * colors were originally in:
+ */
+ if ((transforms & PNG_TRANSFORM_SHIFT) != 0)
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
+ png_set_shift(png_ptr, &info_ptr->sig_bit);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
+#endif
+
+ /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
+ if ((transforms & PNG_TRANSFORM_BGR) != 0)
+#ifdef PNG_READ_BGR_SUPPORTED
+ png_set_bgr(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
+#endif
+
+ /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+ if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+ png_set_swap_alpha(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
+#endif
+
+ /* Swap bytes of 16-bit files to least significant byte first */
+ if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)
+#ifdef PNG_READ_SWAP_SUPPORTED
+ png_set_swap(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
+#endif
+
+/* Added at libpng-1.2.41 */
+ /* Invert the alpha channel from opacity to transparency */
+ if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ png_set_invert_alpha(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
+#endif
+
+/* Added at libpng-1.2.41 */
+ /* Expand grayscale image to RGB */
+ if ((transforms & PNG_TRANSFORM_GRAY_TO_RGB) != 0)
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ png_set_gray_to_rgb(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_GRAY_TO_RGB not supported");
+#endif
+
+/* Added at libpng-1.5.4 */
+ if ((transforms & PNG_TRANSFORM_EXPAND_16) != 0)
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ png_set_expand_16(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_EXPAND_16 not supported");
+#endif
+
+ /* We don't handle adding filler bytes */
+
+ /* We use png_read_image and rely on that for interlace handling, but we also
+ * call png_read_update_info therefore must turn on interlace handling now:
+ */
+ (void)png_set_interlace_handling(png_ptr);
+
+ /* Optional call to gamma correct and add the background to the palette
+ * and update info structure. REQUIRED if you are expecting libpng to
+ * update the palette for you (i.e., you selected such a transform above).
+ */
+ png_read_update_info(png_ptr, info_ptr);
+
+ /* -------------- image transformations end here ------------------- */
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+ if (info_ptr->row_pointers == NULL)
+ {
+ png_uint_32 iptr;
+
+ info_ptr->row_pointers = png_voidcast(png_bytepp, png_malloc(png_ptr,
+ info_ptr->height * (sizeof (png_bytep))));
+
+ for (iptr=0; iptr<info_ptr->height; iptr++)
+ info_ptr->row_pointers[iptr] = NULL;
+
+ info_ptr->free_me |= PNG_FREE_ROWS;
+
+ for (iptr = 0; iptr < info_ptr->height; iptr++)
+ info_ptr->row_pointers[iptr] = png_voidcast(png_bytep,
+ png_malloc(png_ptr, info_ptr->rowbytes));
+ }
+
+ png_read_image(png_ptr, info_ptr->row_pointers);
+ info_ptr->valid |= PNG_INFO_IDAT;
+
+ /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
+ png_read_end(png_ptr, info_ptr);
+
+ PNG_UNUSED(params)
+}
+#endif /* INFO_IMAGE */
+#endif /* SEQUENTIAL_READ */
+
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+/* SIMPLIFIED READ
+ *
+ * This code currently relies on the sequential reader, though it could easily
+ * be made to work with the progressive one.
+ */
+/* Arguments to png_image_finish_read: */
+
+/* Encoding of PNG data (used by the color-map code) */
+# define P_NOTSET 0 /* File encoding not yet known */
+# define P_sRGB 1 /* 8-bit encoded to sRGB gamma */
+# define P_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */
+# define P_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */
+# define P_LINEAR8 4 /* 8-bit linear: only from a file value */
+
+/* Color-map processing: after libpng has run on the PNG image further
+ * processing may be needed to convert the data to color-map indices.
+ */
+#define PNG_CMAP_NONE 0
+#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */
+#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */
+#define PNG_CMAP_RGB 3 /* Process RGB data */
+#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */
+
+/* The following document where the background is for each processing case. */
+#define PNG_CMAP_NONE_BACKGROUND 256
+#define PNG_CMAP_GA_BACKGROUND 231
+#define PNG_CMAP_TRANS_BACKGROUND 254
+#define PNG_CMAP_RGB_BACKGROUND 256
+#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216
+
+typedef struct
+{
+ /* Arguments: */
+ png_imagep image;
+ png_voidp buffer;
+ png_int_32 row_stride;
+ png_voidp colormap;
+ png_const_colorp background;
+ /* Local variables: */
+ png_voidp local_row;
+ png_voidp first_row;
+ ptrdiff_t row_bytes; /* step between rows */
+ int file_encoding; /* E_ values above */
+ png_fixed_point gamma_to_linear; /* For P_FILE, reciprocal of gamma */
+ int colormap_processing; /* PNG_CMAP_ values above */
+} png_image_read_control;
+
+/* Do all the *safe* initialization - 'safe' means that png_error won't be
+ * called, so setting up the jmp_buf is not required. This means that anything
+ * called from here must *not* call png_malloc - it has to call png_malloc_warn
+ * instead so that control is returned safely back to this routine.
+ */
+static int
+png_image_read_init(png_imagep image)
+{
+ if (image->opaque == NULL)
+ {
+ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image,
+ png_safe_error, png_safe_warning);
+
+ /* And set the rest of the structure to NULL to ensure that the various
+ * fields are consistent.
+ */
+ memset(image, 0, (sizeof *image));
+ image->version = PNG_IMAGE_VERSION;
+
+ if (png_ptr != NULL)
+ {
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+
+ if (info_ptr != NULL)
+ {
+ png_controlp control = png_voidcast(png_controlp,
+ png_malloc_warn(png_ptr, (sizeof *control)));
+
+ if (control != NULL)
+ {
+ memset(control, 0, (sizeof *control));
+
+ control->png_ptr = png_ptr;
+ control->info_ptr = info_ptr;
+ control->for_write = 0;
+
+ image->opaque = control;
+ return 1;
+ }
+
+ /* Error clean up */
+ png_destroy_info_struct(png_ptr, &info_ptr);
+ }
+
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+ }
+
+ return png_image_error(image, "png_image_read: out of memory");
+ }
+
+ return png_image_error(image, "png_image_read: opaque pointer not NULL");
+}
+
+/* Utility to find the base format of a PNG file from a png_struct. */
+static png_uint_32
+png_image_format(png_structrp png_ptr)
+{
+ png_uint_32 format = 0;
+
+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ format |= PNG_FORMAT_FLAG_COLOR;
+
+ if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ format |= PNG_FORMAT_FLAG_ALPHA;
+
+ /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS
+ * sets the png_struct fields; that's all we are interested in here. The
+ * precise interaction with an app call to png_set_tRNS and PNG file reading
+ * is unclear.
+ */
+ else if (png_ptr->num_trans > 0)
+ format |= PNG_FORMAT_FLAG_ALPHA;
+
+ if (png_ptr->bit_depth == 16)
+ format |= PNG_FORMAT_FLAG_LINEAR;
+
+ if ((png_ptr->color_type & PNG_COLOR_MASK_PALETTE) != 0)
+ format |= PNG_FORMAT_FLAG_COLORMAP;
+
+ return format;
+}
+
+/* Is the given gamma significantly different from sRGB? The test is the same
+ * one used in pngrtran.c when deciding whether to do gamma correction. The
+ * arithmetic optimizes the division by using the fact that the inverse of the
+ * file sRGB gamma is 2.2
+ */
+static int
+png_gamma_not_sRGB(png_fixed_point g)
+{
+ if (g < PNG_FP_1)
+ {
+ /* An uninitialized gamma is assumed to be sRGB for the simplified API. */
+ if (g == 0)
+ return 0;
+
+ return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */);
+ }
+
+ return 1;
+}
+
+/* Do the main body of a 'png_image_begin_read' function; read the PNG file
+ * header and fill in all the information. This is executed in a safe context,
+ * unlike the init routine above.
+ */
+static int
+png_image_read_header(png_voidp argument)
+{
+ png_imagep image = png_voidcast(png_imagep, argument);
+ png_structrp png_ptr = image->opaque->png_ptr;
+ png_inforp info_ptr = image->opaque->info_ptr;
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+ png_set_benign_errors(png_ptr, 1/*warn*/);
+#endif
+ png_read_info(png_ptr, info_ptr);
+
+ /* Do this the fast way; just read directly out of png_struct. */
+ image->width = png_ptr->width;
+ image->height = png_ptr->height;
+
+ {
+ png_uint_32 format = png_image_format(png_ptr);
+
+ image->format = format;
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+ /* Does the colorspace match sRGB? If there is no color endpoint
+ * (colorant) information assume yes, otherwise require the
+ * 'ENDPOINTS_MATCHP_sRGB' colorspace flag to have been set. If the
+ * colorspace has been determined to be invalid ignore it.
+ */
+ if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags
+ & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB|
+ PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS))
+ image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB;
+#endif
+ }
+
+ /* We need the maximum number of entries regardless of the format the
+ * application sets here.
+ */
+ {
+ png_uint_32 cmap_entries;
+
+ switch (png_ptr->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ cmap_entries = 1U << png_ptr->bit_depth;
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ cmap_entries = (png_uint_32)png_ptr->num_palette;
+ break;
+
+ default:
+ cmap_entries = 256;
+ break;
+ }
+
+ if (cmap_entries > 256)
+ cmap_entries = 256;
+
+ image->colormap_entries = cmap_entries;
+ }
+
+ return 1;
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+int PNGAPI
+png_image_begin_read_from_stdio(png_imagep image, FILE* file)
+{
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (file != NULL)
+ {
+ if (png_image_read_init(image) != 0)
+ {
+ /* This is slightly evil, but png_init_io doesn't do anything other
+ * than this and we haven't changed the standard IO functions so
+ * this saves a 'safe' function.
+ */
+ image->opaque->png_ptr->io_ptr = file;
+ return png_safe_execute(image, png_image_read_header, image);
+ }
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_begin_read_from_stdio: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
+
+ return 0;
+}
+
+int PNGAPI
+png_image_begin_read_from_file(png_imagep image, const char *file_name)
+{
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (file_name != NULL)
+ {
+ FILE *fp = fopen(file_name, "rb");
+
+ if (fp != NULL)
+ {
+ if (png_image_read_init(image) != 0)
+ {
+ image->opaque->png_ptr->io_ptr = fp;
+ image->opaque->owned_file = 1;
+ return png_safe_execute(image, png_image_read_header, image);
+ }
+
+ /* Clean up: just the opened file. */
+ (void)fclose(fp);
+ }
+
+ else
+ return png_image_error(image, strerror(errno));
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_begin_read_from_file: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
+
+ return 0;
+}
+#endif /* STDIO */
+
+static void PNGCBAPI
+png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)
+{
+ if (png_ptr != NULL)
+ {
+ png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr);
+ if (image != NULL)
+ {
+ png_controlp cp = image->opaque;
+ if (cp != NULL)
+ {
+ png_const_bytep memory = cp->memory;
+ png_size_t size = cp->size;
+
+ if (memory != NULL && size >= need)
+ {
+ memcpy(out, memory, need);
+ cp->memory = memory + need;
+ cp->size = size - need;
+ return;
+ }
+
+ png_error(png_ptr, "read beyond end of data");
+ }
+ }
+
+ png_error(png_ptr, "invalid memory read");
+ }
+}
+
+int PNGAPI png_image_begin_read_from_memory(png_imagep image,
+ png_const_voidp memory, png_size_t size)
+{
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (memory != NULL && size > 0)
+ {
+ if (png_image_read_init(image) != 0)
+ {
+ /* Now set the IO functions to read from the memory buffer and
+ * store it into io_ptr. Again do this in-place to avoid calling a
+ * libpng function that requires error handling.
+ */
+ image->opaque->memory = png_voidcast(png_const_bytep, memory);
+ image->opaque->size = size;
+ image->opaque->png_ptr->io_ptr = image;
+ image->opaque->png_ptr->read_data_fn = png_image_memory_read;
+
+ return png_safe_execute(image, png_image_read_header, image);
+ }
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_begin_read_from_memory: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
+
+ return 0;
+}
+
+/* Utility function to skip chunks that are not used by the simplified image
+ * read functions and an appropriate macro to call it.
+ */
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+static void
+png_image_skip_unused_chunks(png_structrp png_ptr)
+{
+ /* Prepare the reader to ignore all recognized chunks whose data will not
+ * be used, i.e., all chunks recognized by libpng except for those
+ * involved in basic image reading:
+ *
+ * IHDR, PLTE, IDAT, IEND
+ *
+ * Or image data handling:
+ *
+ * tRNS, bKGD, gAMA, cHRM, sRGB, [iCCP] and sBIT.
+ *
+ * This provides a small performance improvement and eliminates any
+ * potential vulnerability to security problems in the unused chunks.
+ *
+ * At present the iCCP chunk data isn't used, so iCCP chunk can be ignored
+ * too. This allows the simplified API to be compiled without iCCP support,
+ * however if the support is there the chunk is still checked to detect
+ * errors (which are unfortunately quite common.)
+ */
+ {
+ static PNG_CONST png_byte chunks_to_process[] = {
+ 98, 75, 71, 68, '\0', /* bKGD */
+ 99, 72, 82, 77, '\0', /* cHRM */
+ 103, 65, 77, 65, '\0', /* gAMA */
+# ifdef PNG_READ_iCCP_SUPPORTED
+ 105, 67, 67, 80, '\0', /* iCCP */
+# endif
+ 115, 66, 73, 84, '\0', /* sBIT */
+ 115, 82, 71, 66, '\0', /* sRGB */
+ };
+
+ /* Ignore unknown chunks and all other chunks except for the
+ * IHDR, PLTE, tRNS, IDAT, and IEND chunks.
+ */
+ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
+ NULL, -1);
+
+ /* But do not ignore image data handling chunks */
+ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,
+ chunks_to_process, (int)/*SAFE*/(sizeof chunks_to_process)/5);
+ }
+}
+
+# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)
+#else
+# define PNG_SKIP_CHUNKS(p) ((void)0)
+#endif /* HANDLE_AS_UNKNOWN */
+
+/* The following macro gives the exact rounded answer for all values in the
+ * range 0..255 (it actually divides by 51.2, but the rounding still generates
+ * the correct numbers 0..5
+ */
+#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8)
+
+/* Utility functions to make particular color-maps */
+static void
+set_file_encoding(png_image_read_control *display)
+{
+ png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma;
+ if (png_gamma_significant(g) != 0)
+ {
+ if (png_gamma_not_sRGB(g) != 0)
+ {
+ display->file_encoding = P_FILE;
+ display->gamma_to_linear = png_reciprocal(g);
+ }
+
+ else
+ display->file_encoding = P_sRGB;
+ }
+
+ else
+ display->file_encoding = P_LINEAR8;
+}
+
+static unsigned int
+decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
+{
+ if (encoding == P_FILE) /* double check */
+ encoding = display->file_encoding;
+
+ if (encoding == P_NOTSET) /* must be the file encoding */
+ {
+ set_file_encoding(display);
+ encoding = display->file_encoding;
+ }
+
+ switch (encoding)
+ {
+ case P_FILE:
+ value = png_gamma_16bit_correct(value*257, display->gamma_to_linear);
+ break;
+
+ case P_sRGB:
+ value = png_sRGB_table[value];
+ break;
+
+ case P_LINEAR:
+ break;
+
+ case P_LINEAR8:
+ value *= 257;
+ break;
+
+#ifdef __GNUC__
+ default:
+ png_error(display->image->opaque->png_ptr,
+ "unexpected encoding (internal error)");
+#endif
+ }
+
+ return value;
+}
+
+static png_uint_32
+png_colormap_compose(png_image_read_control *display,
+ png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
+ png_uint_32 background, int encoding)
+{
+ /* The file value is composed on the background, the background has the given
+ * encoding and so does the result, the file is encoded with P_FILE and the
+ * file and alpha are 8-bit values. The (output) encoding will always be
+ * P_LINEAR or P_sRGB.
+ */
+ png_uint_32 f = decode_gamma(display, foreground, foreground_encoding);
+ png_uint_32 b = decode_gamma(display, background, encoding);
+
+ /* The alpha is always an 8-bit value (it comes from the palette), the value
+ * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires.
+ */
+ f = f * alpha + b * (255-alpha);
+
+ if (encoding == P_LINEAR)
+ {
+ /* Scale to 65535; divide by 255, approximately (in fact this is extremely
+ * accurate, it divides by 255.00000005937181414556, with no overflow.)
+ */
+ f *= 257; /* Now scaled by 65535 */
+ f += f >> 16;
+ f = (f+32768) >> 16;
+ }
+
+ else /* P_sRGB */
+ f = PNG_sRGB_FROM_LINEAR(f);
+
+ return f;
+}
+
+/* NOTE: P_LINEAR values to this routine must be 16-bit, but P_FILE values must
+ * be 8-bit.
+ */
+static void
+png_create_colormap_entry(png_image_read_control *display,
+ png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
+ png_uint_32 alpha, int encoding)
+{
+ png_imagep image = display->image;
+ const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
+ P_LINEAR : P_sRGB;
+ const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
+ (red != green || green != blue);
+
+ if (ip > 255)
+ png_error(image->opaque->png_ptr, "color-map index out of range");
+
+ /* Update the cache with whether the file gamma is significantly different
+ * from sRGB.
+ */
+ if (encoding == P_FILE)
+ {
+ if (display->file_encoding == P_NOTSET)
+ set_file_encoding(display);
+
+ /* Note that the cached value may be P_FILE too, but if it is then the
+ * gamma_to_linear member has been set.
+ */
+ encoding = display->file_encoding;
+ }
+
+ if (encoding == P_FILE)
+ {
+ png_fixed_point g = display->gamma_to_linear;
+
+ red = png_gamma_16bit_correct(red*257, g);
+ green = png_gamma_16bit_correct(green*257, g);
+ blue = png_gamma_16bit_correct(blue*257, g);
+
+ if (convert_to_Y != 0 || output_encoding == P_LINEAR)
+ {
+ alpha *= 257;
+ encoding = P_LINEAR;
+ }
+
+ else
+ {
+ red = PNG_sRGB_FROM_LINEAR(red * 255);
+ green = PNG_sRGB_FROM_LINEAR(green * 255);
+ blue = PNG_sRGB_FROM_LINEAR(blue * 255);
+ encoding = P_sRGB;
+ }
+ }
+
+ else if (encoding == P_LINEAR8)
+ {
+ /* This encoding occurs quite frequently in test cases because PngSuite
+ * includes a gAMA 1.0 chunk with most images.
+ */
+ red *= 257;
+ green *= 257;
+ blue *= 257;
+ alpha *= 257;
+ encoding = P_LINEAR;
+ }
+
+ else if (encoding == P_sRGB &&
+ (convert_to_Y != 0 || output_encoding == P_LINEAR))
+ {
+ /* The values are 8-bit sRGB values, but must be converted to 16-bit
+ * linear.
+ */
+ red = png_sRGB_table[red];
+ green = png_sRGB_table[green];
+ blue = png_sRGB_table[blue];
+ alpha *= 257;
+ encoding = P_LINEAR;
+ }
+
+ /* This is set if the color isn't gray but the output is. */
+ if (encoding == P_LINEAR)
+ {
+ if (convert_to_Y != 0)
+ {
+ /* NOTE: these values are copied from png_do_rgb_to_gray */
+ png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green +
+ (png_uint_32)2366 * blue;
+
+ if (output_encoding == P_LINEAR)
+ y = (y + 16384) >> 15;
+
+ else
+ {
+ /* y is scaled by 32768, we need it scaled by 255: */
+ y = (y + 128) >> 8;
+ y *= 255;
+ y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7);
+ alpha = PNG_DIV257(alpha);
+ encoding = P_sRGB;
+ }
+
+ blue = red = green = y;
+ }
+
+ else if (output_encoding == P_sRGB)
+ {
+ red = PNG_sRGB_FROM_LINEAR(red * 255);
+ green = PNG_sRGB_FROM_LINEAR(green * 255);
+ blue = PNG_sRGB_FROM_LINEAR(blue * 255);
+ alpha = PNG_DIV257(alpha);
+ encoding = P_sRGB;
+ }
+ }
+
+ if (encoding != output_encoding)
+ png_error(image->opaque->png_ptr, "bad encoding (internal error)");
+
+ /* Store the value. */
+ {
+# ifdef PNG_FORMAT_AFIRST_SUPPORTED
+ const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
+ (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
+# else
+# define afirst 0
+# endif
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
+# else
+# define bgr 0
+# endif
+
+ if (output_encoding == P_LINEAR)
+ {
+ png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap);
+
+ entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
+
+ /* The linear 16-bit values must be pre-multiplied by the alpha channel
+ * value, if less than 65535 (this is, effectively, composite on black
+ * if the alpha channel is removed.)
+ */
+ switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
+ {
+ case 4:
+ entry[afirst ? 0 : 3] = (png_uint_16)alpha;
+ /* FALLTHROUGH */
+
+ case 3:
+ if (alpha < 65535)
+ {
+ if (alpha > 0)
+ {
+ blue = (blue * alpha + 32767U)/65535U;
+ green = (green * alpha + 32767U)/65535U;
+ red = (red * alpha + 32767U)/65535U;
+ }
+
+ else
+ red = green = blue = 0;
+ }
+ entry[afirst + (2 ^ bgr)] = (png_uint_16)blue;
+ entry[afirst + 1] = (png_uint_16)green;
+ entry[afirst + bgr] = (png_uint_16)red;
+ break;
+
+ case 2:
+ entry[1 ^ afirst] = (png_uint_16)alpha;
+ /* FALLTHROUGH */
+
+ case 1:
+ if (alpha < 65535)
+ {
+ if (alpha > 0)
+ green = (green * alpha + 32767U)/65535U;
+
+ else
+ green = 0;
+ }
+ entry[afirst] = (png_uint_16)green;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ else /* output encoding is P_sRGB */
+ {
+ png_bytep entry = png_voidcast(png_bytep, display->colormap);
+
+ entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
+
+ switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
+ {
+ case 4:
+ entry[afirst ? 0 : 3] = (png_byte)alpha;
+ /* FALLTHROUGH */
+ case 3:
+ entry[afirst + (2 ^ bgr)] = (png_byte)blue;
+ entry[afirst + 1] = (png_byte)green;
+ entry[afirst + bgr] = (png_byte)red;
+ break;
+
+ case 2:
+ entry[1 ^ afirst] = (png_byte)alpha;
+ /* FALLTHROUGH */
+ case 1:
+ entry[afirst] = (png_byte)green;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+# ifdef afirst
+# undef afirst
+# endif
+# ifdef bgr
+# undef bgr
+# endif
+ }
+}
+
+static int
+make_gray_file_colormap(png_image_read_control *display)
+{
+ unsigned int i;
+
+ for (i=0; i<256; ++i)
+ png_create_colormap_entry(display, i, i, i, i, 255, P_FILE);
+
+ return (int)i;
+}
+
+static int
+make_gray_colormap(png_image_read_control *display)
+{
+ unsigned int i;
+
+ for (i=0; i<256; ++i)
+ png_create_colormap_entry(display, i, i, i, i, 255, P_sRGB);
+
+ return (int)i;
+}
+#define PNG_GRAY_COLORMAP_ENTRIES 256
+
+static int
+make_ga_colormap(png_image_read_control *display)
+{
+ unsigned int i, a;
+
+ /* Alpha is retained, the output will be a color-map with entries
+ * selected by six levels of alpha. One transparent entry, 6 gray
+ * levels for all the intermediate alpha values, leaving 230 entries
+ * for the opaque grays. The color-map entries are the six values
+ * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the
+ * relevant entry.
+ *
+ * if (alpha > 229) // opaque
+ * {
+ * // The 231 entries are selected to make the math below work:
+ * base = 0;
+ * entry = (231 * gray + 128) >> 8;
+ * }
+ * else if (alpha < 26) // transparent
+ * {
+ * base = 231;
+ * entry = 0;
+ * }
+ * else // partially opaque
+ * {
+ * base = 226 + 6 * PNG_DIV51(alpha);
+ * entry = PNG_DIV51(gray);
+ * }
+ */
+ i = 0;
+ while (i < 231)
+ {
+ unsigned int gray = (i * 256 + 115) / 231;
+ png_create_colormap_entry(display, i++, gray, gray, gray, 255, P_sRGB);
+ }
+
+ /* 255 is used here for the component values for consistency with the code
+ * that undoes premultiplication in pngwrite.c.
+ */
+ png_create_colormap_entry(display, i++, 255, 255, 255, 0, P_sRGB);
+
+ for (a=1; a<5; ++a)
+ {
+ unsigned int g;
+
+ for (g=0; g<6; ++g)
+ png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
+ P_sRGB);
+ }
+
+ return (int)i;
+}
+
+#define PNG_GA_COLORMAP_ENTRIES 256
+
+static int
+make_rgb_colormap(png_image_read_control *display)
+{
+ unsigned int i, r;
+
+ /* Build a 6x6x6 opaque RGB cube */
+ for (i=r=0; r<6; ++r)
+ {
+ unsigned int g;
+
+ for (g=0; g<6; ++g)
+ {
+ unsigned int b;
+
+ for (b=0; b<6; ++b)
+ png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
+ P_sRGB);
+ }
+ }
+
+ return (int)i;
+}
+
+#define PNG_RGB_COLORMAP_ENTRIES 216
+
+/* Return a palette index to the above palette given three 8-bit sRGB values. */
+#define PNG_RGB_INDEX(r,g,b) \
+ ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b)))
+
+static int
+png_image_read_colormap(png_voidp argument)
+{
+ png_image_read_control *display =
+ png_voidcast(png_image_read_control*, argument);
+ const png_imagep image = display->image;
+
+ const png_structrp png_ptr = image->opaque->png_ptr;
+ const png_uint_32 output_format = image->format;
+ const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ?
+ P_LINEAR : P_sRGB;
+
+ unsigned int cmap_entries;
+ unsigned int output_processing; /* Output processing option */
+ unsigned int data_encoding = P_NOTSET; /* Encoding libpng must produce */
+
+ /* Background information; the background color and the index of this color
+ * in the color-map if it exists (else 256).
+ */
+ unsigned int background_index = 256;
+ png_uint_32 back_r, back_g, back_b;
+
+ /* Flags to accumulate things that need to be done to the input. */
+ int expand_tRNS = 0;
+
+ /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is
+ * very difficult to do, the results look awful, and it is difficult to see
+ * what possible use it is because the application can't control the
+ * color-map.
+ */
+ if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 ||
+ png_ptr->num_trans > 0) /* alpha in input */ &&
+ ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */)
+ {
+ if (output_encoding == P_LINEAR) /* compose on black */
+ back_b = back_g = back_r = 0;
+
+ else if (display->background == NULL /* no way to remove it */)
+ png_error(png_ptr,
+ "background color must be supplied to remove alpha/transparency");
+
+ /* Get a copy of the background color (this avoids repeating the checks
+ * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the
+ * output format.
+ */
+ else
+ {
+ back_g = display->background->green;
+ if ((output_format & PNG_FORMAT_FLAG_COLOR) != 0)
+ {
+ back_r = display->background->red;
+ back_b = display->background->blue;
+ }
+ else
+ back_b = back_r = back_g;
+ }
+ }
+
+ else if (output_encoding == P_LINEAR)
+ back_b = back_r = back_g = 65535;
+
+ else
+ back_b = back_r = back_g = 255;
+
+ /* Default the input file gamma if required - this is necessary because
+ * libpng assumes that if no gamma information is present the data is in the
+ * output format, but the simplified API deduces the gamma from the input
+ * format.
+ */
+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0)
+ {
+ /* Do this directly, not using the png_colorspace functions, to ensure
+ * that it happens even if the colorspace is invalid (though probably if
+ * it is the setting will be ignored) Note that the same thing can be
+ * achieved at the application interface with png_set_gAMA.
+ */
+ if (png_ptr->bit_depth == 16 &&
+ (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
+ png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR;
+
+ else
+ png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE;
+
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+ }
+
+ /* Decide what to do based on the PNG color type of the input data. The
+ * utility function png_create_colormap_entry deals with most aspects of the
+ * output transformations; this code works out how to produce bytes of
+ * color-map entries from the original format.
+ */
+ switch (png_ptr->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ if (png_ptr->bit_depth <= 8)
+ {
+ /* There at most 256 colors in the output, regardless of
+ * transparency.
+ */
+ unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0;
+
+ cmap_entries = 1U << png_ptr->bit_depth;
+ if (cmap_entries > image->colormap_entries)
+ png_error(png_ptr, "gray[8] color-map: too few entries");
+
+ step = 255 / (cmap_entries - 1);
+ output_processing = PNG_CMAP_NONE;
+
+ /* If there is a tRNS chunk then this either selects a transparent
+ * value or, if the output has no alpha, the background color.
+ */
+ if (png_ptr->num_trans > 0)
+ {
+ trans = png_ptr->trans_color.gray;
+
+ if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0)
+ back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
+ }
+
+ /* png_create_colormap_entry just takes an RGBA and writes the
+ * corresponding color-map entry using the format from 'image',
+ * including the required conversion to sRGB or linear as
+ * appropriate. The input values are always either sRGB (if the
+ * gamma correction flag is 0) or 0..255 scaled file encoded values
+ * (if the function must gamma correct them).
+ */
+ for (i=val=0; i<cmap_entries; ++i, val += step)
+ {
+ /* 'i' is a file value. While this will result in duplicated
+ * entries for 8-bit non-sRGB encoded files it is necessary to
+ * have non-gamma corrected values to do tRNS handling.
+ */
+ if (i != trans)
+ png_create_colormap_entry(display, i, val, val, val, 255,
+ P_FILE/*8-bit with file gamma*/);
+
+ /* Else this entry is transparent. The colors don't matter if
+ * there is an alpha channel (back_alpha == 0), but it does no
+ * harm to pass them in; the values are not set above so this
+ * passes in white.
+ *
+ * NOTE: this preserves the full precision of the application
+ * supplied background color when it is used.
+ */
+ else
+ png_create_colormap_entry(display, i, back_r, back_g, back_b,
+ back_alpha, output_encoding);
+ }
+
+ /* We need libpng to preserve the original encoding. */
+ data_encoding = P_FILE;
+
+ /* The rows from libpng, while technically gray values, are now also
+ * color-map indices; however, they may need to be expanded to 1
+ * byte per pixel. This is what png_set_packing does (i.e., it
+ * unpacks the bit values into bytes.)
+ */
+ if (png_ptr->bit_depth < 8)
+ png_set_packing(png_ptr);
+ }
+
+ else /* bit depth is 16 */
+ {
+ /* The 16-bit input values can be converted directly to 8-bit gamma
+ * encoded values; however, if a tRNS chunk is present 257 color-map
+ * entries are required. This means that the extra entry requires
+ * special processing; add an alpha channel, sacrifice gray level
+ * 254 and convert transparent (alpha==0) entries to that.
+ *
+ * Use libpng to chop the data to 8 bits. Convert it to sRGB at the
+ * same time to minimize quality loss. If a tRNS chunk is present
+ * this means libpng must handle it too; otherwise it is impossible
+ * to do the exact match on the 16-bit value.
+ *
+ * If the output has no alpha channel *and* the background color is
+ * gray then it is possible to let libpng handle the substitution by
+ * ensuring that the corresponding gray level matches the background
+ * color exactly.
+ */
+ data_encoding = P_sRGB;
+
+ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "gray[16] color-map: too few entries");
+
+ cmap_entries = (unsigned int)make_gray_colormap(display);
+
+ if (png_ptr->num_trans > 0)
+ {
+ unsigned int back_alpha;
+
+ if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ back_alpha = 0;
+
+ else
+ {
+ if (back_r == back_g && back_g == back_b)
+ {
+ /* Background is gray; no special processing will be
+ * required.
+ */
+ png_color_16 c;
+ png_uint_32 gray = back_g;
+
+ if (output_encoding == P_LINEAR)
+ {
+ gray = PNG_sRGB_FROM_LINEAR(gray * 255);
+
+ /* And make sure the corresponding palette entry
+ * matches.
+ */
+ png_create_colormap_entry(display, gray, back_g, back_g,
+ back_g, 65535, P_LINEAR);
+ }
+
+ /* The background passed to libpng, however, must be the
+ * sRGB value.
+ */
+ c.index = 0; /*unused*/
+ c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
+
+ /* NOTE: does this work without expanding tRNS to alpha?
+ * It should be the color->gray case below apparently
+ * doesn't.
+ */
+ png_set_background_fixed(png_ptr, &c,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
+
+ output_processing = PNG_CMAP_NONE;
+ break;
+ }
+#ifdef __COVERITY__
+ /* Coverity claims that output_encoding cannot be 2 (P_LINEAR)
+ * here.
+ */
+ back_alpha = 255;
+#else
+ back_alpha = output_encoding == P_LINEAR ? 65535 : 255;
+#endif
+ }
+
+ /* output_processing means that the libpng-processed row will be
+ * 8-bit GA and it has to be processing to single byte color-map
+ * values. Entry 254 is replaced by either a completely
+ * transparent entry or by the background color at full
+ * precision (and the background color is not a simple gray
+ * level in this case.)
+ */
+ expand_tRNS = 1;
+ output_processing = PNG_CMAP_TRANS;
+ background_index = 254;
+
+ /* And set (overwrite) color-map entry 254 to the actual
+ * background color at full precision.
+ */
+ png_create_colormap_entry(display, 254, back_r, back_g, back_b,
+ back_alpha, output_encoding);
+ }
+
+ else
+ output_processing = PNG_CMAP_NONE;
+ }
+ break;
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ /* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum
+ * of 65536 combinations. If, however, the alpha channel is to be
+ * removed there are only 256 possibilities if the background is gray.
+ * (Otherwise there is a subset of the 65536 possibilities defined by
+ * the triangle between black, white and the background color.)
+ *
+ * Reduce 16-bit files to 8-bit and sRGB encode the result. No need to
+ * worry about tRNS matching - tRNS is ignored if there is an alpha
+ * channel.
+ */
+ data_encoding = P_sRGB;
+
+ if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ {
+ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "gray+alpha color-map: too few entries");
+
+ cmap_entries = (unsigned int)make_ga_colormap(display);
+
+ background_index = PNG_CMAP_GA_BACKGROUND;
+ output_processing = PNG_CMAP_GA;
+ }
+
+ else /* alpha is removed */
+ {
+ /* Alpha must be removed as the PNG data is processed when the
+ * background is a color because the G and A channels are
+ * independent and the vector addition (non-parallel vectors) is a
+ * 2-D problem.
+ *
+ * This can be reduced to the same algorithm as above by making a
+ * colormap containing gray levels (for the opaque grays), a
+ * background entry (for a transparent pixel) and a set of four six
+ * level color values, one set for each intermediate alpha value.
+ * See the comments in make_ga_colormap for how this works in the
+ * per-pixel processing.
+ *
+ * If the background is gray, however, we only need a 256 entry gray
+ * level color map. It is sufficient to make the entry generated
+ * for the background color be exactly the color specified.
+ */
+ if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 ||
+ (back_r == back_g && back_g == back_b))
+ {
+ /* Background is gray; no special processing will be required. */
+ png_color_16 c;
+ png_uint_32 gray = back_g;
+
+ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "gray-alpha color-map: too few entries");
+
+ cmap_entries = (unsigned int)make_gray_colormap(display);
+
+ if (output_encoding == P_LINEAR)
+ {
+ gray = PNG_sRGB_FROM_LINEAR(gray * 255);
+
+ /* And make sure the corresponding palette entry matches. */
+ png_create_colormap_entry(display, gray, back_g, back_g,
+ back_g, 65535, P_LINEAR);
+ }
+
+ /* The background passed to libpng, however, must be the sRGB
+ * value.
+ */
+ c.index = 0; /*unused*/
+ c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
+
+ png_set_background_fixed(png_ptr, &c,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
+
+ output_processing = PNG_CMAP_NONE;
+ }
+
+ else
+ {
+ png_uint_32 i, a;
+
+ /* This is the same as png_make_ga_colormap, above, except that
+ * the entries are all opaque.
+ */
+ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "ga-alpha color-map: too few entries");
+
+ i = 0;
+ while (i < 231)
+ {
+ png_uint_32 gray = (i * 256 + 115) / 231;
+ png_create_colormap_entry(display, i++, gray, gray, gray,
+ 255, P_sRGB);
+ }
+
+ /* NOTE: this preserves the full precision of the application
+ * background color.
+ */
+ background_index = i;
+ png_create_colormap_entry(display, i++, back_r, back_g, back_b,
+#ifdef __COVERITY__
+ /* Coverity claims that output_encoding
+ * cannot be 2 (P_LINEAR) here.
+ */ 255U,
+#else
+ output_encoding == P_LINEAR ? 65535U : 255U,
+#endif
+ output_encoding);
+
+ /* For non-opaque input composite on the sRGB background - this
+ * requires inverting the encoding for each component. The input
+ * is still converted to the sRGB encoding because this is a
+ * reasonable approximate to the logarithmic curve of human
+ * visual sensitivity, at least over the narrow range which PNG
+ * represents. Consequently 'G' is always sRGB encoded, while
+ * 'A' is linear. We need the linear background colors.
+ */
+ if (output_encoding == P_sRGB) /* else already linear */
+ {
+ /* This may produce a value not exactly matching the
+ * background, but that's ok because these numbers are only
+ * used when alpha != 0
+ */
+ back_r = png_sRGB_table[back_r];
+ back_g = png_sRGB_table[back_g];
+ back_b = png_sRGB_table[back_b];
+ }
+
+ for (a=1; a<5; ++a)
+ {
+ unsigned int g;
+
+ /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled
+ * by an 8-bit alpha value (0..255).
+ */
+ png_uint_32 alpha = 51 * a;
+ png_uint_32 back_rx = (255-alpha) * back_r;
+ png_uint_32 back_gx = (255-alpha) * back_g;
+ png_uint_32 back_bx = (255-alpha) * back_b;
+
+ for (g=0; g<6; ++g)
+ {
+ png_uint_32 gray = png_sRGB_table[g*51] * alpha;
+
+ png_create_colormap_entry(display, i++,
+ PNG_sRGB_FROM_LINEAR(gray + back_rx),
+ PNG_sRGB_FROM_LINEAR(gray + back_gx),
+ PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, P_sRGB);
+ }
+ }
+
+ cmap_entries = i;
+ output_processing = PNG_CMAP_GA;
+ }
+ }
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ /* Exclude the case where the output is gray; we can always handle this
+ * with the cases above.
+ */
+ if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0)
+ {
+ /* The color-map will be grayscale, so we may as well convert the
+ * input RGB values to a simple grayscale and use the grayscale
+ * code above.
+ *
+ * NOTE: calling this apparently damages the recognition of the
+ * transparent color in background color handling; call
+ * png_set_tRNS_to_alpha before png_set_background_fixed.
+ */
+ png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
+ -1);
+ data_encoding = P_sRGB;
+
+ /* The output will now be one or two 8-bit gray or gray+alpha
+ * channels. The more complex case arises when the input has alpha.
+ */
+ if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ png_ptr->num_trans > 0) &&
+ (output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ {
+ /* Both input and output have an alpha channel, so no background
+ * processing is required; just map the GA bytes to the right
+ * color-map entry.
+ */
+ expand_tRNS = 1;
+
+ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "rgb[ga] color-map: too few entries");
+
+ cmap_entries = (unsigned int)make_ga_colormap(display);
+ background_index = PNG_CMAP_GA_BACKGROUND;
+ output_processing = PNG_CMAP_GA;
+ }
+
+ else
+ {
+ /* Either the input or the output has no alpha channel, so there
+ * will be no non-opaque pixels in the color-map; it will just be
+ * grayscale.
+ */
+ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "rgb[gray] color-map: too few entries");
+
+ /* Ideally this code would use libpng to do the gamma correction,
+ * but if an input alpha channel is to be removed we will hit the
+ * libpng bug in gamma+compose+rgb-to-gray (the double gamma
+ * correction bug). Fix this by dropping the gamma correction in
+ * this case and doing it in the palette; this will result in
+ * duplicate palette entries, but that's better than the
+ * alternative of double gamma correction.
+ */
+ if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ png_ptr->num_trans > 0) &&
+ png_gamma_not_sRGB(png_ptr->colorspace.gamma) != 0)
+ {
+ cmap_entries = (unsigned int)make_gray_file_colormap(display);
+ data_encoding = P_FILE;
+ }
+
+ else
+ cmap_entries = (unsigned int)make_gray_colormap(display);
+
+ /* But if the input has alpha or transparency it must be removed
+ */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ png_ptr->num_trans > 0)
+ {
+ png_color_16 c;
+ png_uint_32 gray = back_g;
+
+ /* We need to ensure that the application background exists in
+ * the colormap and that completely transparent pixels map to
+ * it. Achieve this simply by ensuring that the entry
+ * selected for the background really is the background color.
+ */
+ if (data_encoding == P_FILE) /* from the fixup above */
+ {
+ /* The app supplied a gray which is in output_encoding, we
+ * need to convert it to a value of the input (P_FILE)
+ * encoding then set this palette entry to the required
+ * output encoding.
+ */
+ if (output_encoding == P_sRGB)
+ gray = png_sRGB_table[gray]; /* now P_LINEAR */
+
+ gray = PNG_DIV257(png_gamma_16bit_correct(gray,
+ png_ptr->colorspace.gamma)); /* now P_FILE */
+
+ /* And make sure the corresponding palette entry contains
+ * exactly the required sRGB value.
+ */
+ png_create_colormap_entry(display, gray, back_g, back_g,
+ back_g, 0/*unused*/, output_encoding);
+ }
+
+ else if (output_encoding == P_LINEAR)
+ {
+ gray = PNG_sRGB_FROM_LINEAR(gray * 255);
+
+ /* And make sure the corresponding palette entry matches.
+ */
+ png_create_colormap_entry(display, gray, back_g, back_g,
+ back_g, 0/*unused*/, P_LINEAR);
+ }
+
+ /* The background passed to libpng, however, must be the
+ * output (normally sRGB) value.
+ */
+ c.index = 0; /*unused*/
+ c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
+
+ /* NOTE: the following is apparently a bug in libpng. Without
+ * it the transparent color recognition in
+ * png_set_background_fixed seems to go wrong.
+ */
+ expand_tRNS = 1;
+ png_set_background_fixed(png_ptr, &c,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
+ }
+
+ output_processing = PNG_CMAP_NONE;
+ }
+ }
+
+ else /* output is color */
+ {
+ /* We could use png_quantize here so long as there is no transparent
+ * color or alpha; png_quantize ignores alpha. Easier overall just
+ * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube.
+ * Consequently we always want libpng to produce sRGB data.
+ */
+ data_encoding = P_sRGB;
+
+ /* Is there any transparency or alpha? */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ png_ptr->num_trans > 0)
+ {
+ /* Is there alpha in the output too? If so all four channels are
+ * processed into a special RGB cube with alpha support.
+ */
+ if ((output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ {
+ png_uint_32 r;
+
+ if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
+ png_error(png_ptr, "rgb+alpha color-map: too few entries");
+
+ cmap_entries = (unsigned int)make_rgb_colormap(display);
+
+ /* Add a transparent entry. */
+ png_create_colormap_entry(display, cmap_entries, 255, 255,
+ 255, 0, P_sRGB);
+
+ /* This is stored as the background index for the processing
+ * algorithm.
+ */
+ background_index = cmap_entries++;
+
+ /* Add 27 r,g,b entries each with alpha 0.5. */
+ for (r=0; r<256; r = (r << 1) | 0x7f)
+ {
+ png_uint_32 g;
+
+ for (g=0; g<256; g = (g << 1) | 0x7f)
+ {
+ png_uint_32 b;
+
+ /* This generates components with the values 0, 127 and
+ * 255
+ */
+ for (b=0; b<256; b = (b << 1) | 0x7f)
+ png_create_colormap_entry(display, cmap_entries++,
+ r, g, b, 128, P_sRGB);
+ }
+ }
+
+ expand_tRNS = 1;
+ output_processing = PNG_CMAP_RGB_ALPHA;
+ }
+
+ else
+ {
+ /* Alpha/transparency must be removed. The background must
+ * exist in the color map (achieved by setting adding it after
+ * the 666 color-map). If the standard processing code will
+ * pick up this entry automatically that's all that is
+ * required; libpng can be called to do the background
+ * processing.
+ */
+ unsigned int sample_size =
+ PNG_IMAGE_SAMPLE_SIZE(output_format);
+ png_uint_32 r, g, b; /* sRGB background */
+
+ if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
+ png_error(png_ptr, "rgb-alpha color-map: too few entries");
+
+ cmap_entries = (unsigned int)make_rgb_colormap(display);
+
+ png_create_colormap_entry(display, cmap_entries, back_r,
+ back_g, back_b, 0/*unused*/, output_encoding);
+
+ if (output_encoding == P_LINEAR)
+ {
+ r = PNG_sRGB_FROM_LINEAR(back_r * 255);
+ g = PNG_sRGB_FROM_LINEAR(back_g * 255);
+ b = PNG_sRGB_FROM_LINEAR(back_b * 255);
+ }
+
+ else
+ {
+ r = back_r;
+ g = back_g;
+ b = back_g;
+ }
+
+ /* Compare the newly-created color-map entry with the one the
+ * PNG_CMAP_RGB algorithm will use. If the two entries don't
+ * match, add the new one and set this as the background
+ * index.
+ */
+ if (memcmp((png_const_bytep)display->colormap +
+ sample_size * cmap_entries,
+ (png_const_bytep)display->colormap +
+ sample_size * PNG_RGB_INDEX(r,g,b),
+ sample_size) != 0)
+ {
+ /* The background color must be added. */
+ background_index = cmap_entries++;
+
+ /* Add 27 r,g,b entries each with created by composing with
+ * the background at alpha 0.5.
+ */
+ for (r=0; r<256; r = (r << 1) | 0x7f)
+ {
+ for (g=0; g<256; g = (g << 1) | 0x7f)
+ {
+ /* This generates components with the values 0, 127
+ * and 255
+ */
+ for (b=0; b<256; b = (b << 1) | 0x7f)
+ png_create_colormap_entry(display, cmap_entries++,
+ png_colormap_compose(display, r, P_sRGB, 128,
+ back_r, output_encoding),
+ png_colormap_compose(display, g, P_sRGB, 128,
+ back_g, output_encoding),
+ png_colormap_compose(display, b, P_sRGB, 128,
+ back_b, output_encoding),
+ 0/*unused*/, output_encoding);
+ }
+ }
+
+ expand_tRNS = 1;
+ output_processing = PNG_CMAP_RGB_ALPHA;
+ }
+
+ else /* background color is in the standard color-map */
+ {
+ png_color_16 c;
+
+ c.index = 0; /*unused*/
+ c.red = (png_uint_16)back_r;
+ c.gray = c.green = (png_uint_16)back_g;
+ c.blue = (png_uint_16)back_b;
+
+ png_set_background_fixed(png_ptr, &c,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
+
+ output_processing = PNG_CMAP_RGB;
+ }
+ }
+ }
+
+ else /* no alpha or transparency in the input */
+ {
+ /* Alpha in the output is irrelevant, simply map the opaque input
+ * pixels to the 6x6x6 color-map.
+ */
+ if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "rgb color-map: too few entries");
+
+ cmap_entries = (unsigned int)make_rgb_colormap(display);
+ output_processing = PNG_CMAP_RGB;
+ }
+ }
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ /* It's already got a color-map. It may be necessary to eliminate the
+ * tRNS entries though.
+ */
+ {
+ unsigned int num_trans = png_ptr->num_trans;
+ png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL;
+ png_const_colorp colormap = png_ptr->palette;
+ const int do_background = trans != NULL &&
+ (output_format & PNG_FORMAT_FLAG_ALPHA) == 0;
+ unsigned int i;
+
+ /* Just in case: */
+ if (trans == NULL)
+ num_trans = 0;
+
+ output_processing = PNG_CMAP_NONE;
+ data_encoding = P_FILE; /* Don't change from color-map indices */
+ cmap_entries = (unsigned int)png_ptr->num_palette;
+ if (cmap_entries > 256)
+ cmap_entries = 256;
+
+ if (cmap_entries > (unsigned int)image->colormap_entries)
+ png_error(png_ptr, "palette color-map: too few entries");
+
+ for (i=0; i < cmap_entries; ++i)
+ {
+ if (do_background != 0 && i < num_trans && trans[i] < 255)
+ {
+ if (trans[i] == 0)
+ png_create_colormap_entry(display, i, back_r, back_g,
+ back_b, 0, output_encoding);
+
+ else
+ {
+ /* Must compose the PNG file color in the color-map entry
+ * on the sRGB color in 'back'.
+ */
+ png_create_colormap_entry(display, i,
+ png_colormap_compose(display, colormap[i].red,
+ P_FILE, trans[i], back_r, output_encoding),
+ png_colormap_compose(display, colormap[i].green,
+ P_FILE, trans[i], back_g, output_encoding),
+ png_colormap_compose(display, colormap[i].blue,
+ P_FILE, trans[i], back_b, output_encoding),
+ output_encoding == P_LINEAR ? trans[i] * 257U :
+ trans[i],
+ output_encoding);
+ }
+ }
+
+ else
+ png_create_colormap_entry(display, i, colormap[i].red,
+ colormap[i].green, colormap[i].blue,
+ i < num_trans ? trans[i] : 255U, P_FILE/*8-bit*/);
+ }
+
+ /* The PNG data may have indices packed in fewer than 8 bits, it
+ * must be expanded if so.
+ */
+ if (png_ptr->bit_depth < 8)
+ png_set_packing(png_ptr);
+ }
+ break;
+
+ default:
+ png_error(png_ptr, "invalid PNG color type");
+ /*NOT REACHED*/
+ }
+
+ /* Now deal with the output processing */
+ if (expand_tRNS != 0 && png_ptr->num_trans > 0 &&
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0)
+ png_set_tRNS_to_alpha(png_ptr);
+
+ switch (data_encoding)
+ {
+ case P_sRGB:
+ /* Change to 8-bit sRGB */
+ png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
+ /* FALLTHROUGH */
+
+ case P_FILE:
+ if (png_ptr->bit_depth > 8)
+ png_set_scale_16(png_ptr);
+ break;
+
+#ifdef __GNUC__
+ default:
+ png_error(png_ptr, "bad data option (internal error)");
+#endif
+ }
+
+ if (cmap_entries > 256 || cmap_entries > image->colormap_entries)
+ png_error(png_ptr, "color map overflow (BAD internal error)");
+
+ image->colormap_entries = cmap_entries;
+
+ /* Double check using the recorded background index */
+ switch (output_processing)
+ {
+ case PNG_CMAP_NONE:
+ if (background_index != PNG_CMAP_NONE_BACKGROUND)
+ goto bad_background;
+ break;
+
+ case PNG_CMAP_GA:
+ if (background_index != PNG_CMAP_GA_BACKGROUND)
+ goto bad_background;
+ break;
+
+ case PNG_CMAP_TRANS:
+ if (background_index >= cmap_entries ||
+ background_index != PNG_CMAP_TRANS_BACKGROUND)
+ goto bad_background;
+ break;
+
+ case PNG_CMAP_RGB:
+ if (background_index != PNG_CMAP_RGB_BACKGROUND)
+ goto bad_background;
+ break;
+
+ case PNG_CMAP_RGB_ALPHA:
+ if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND)
+ goto bad_background;
+ break;
+
+ default:
+ png_error(png_ptr, "bad processing option (internal error)");
+
+ bad_background:
+ png_error(png_ptr, "bad background index (internal error)");
+ }
+
+ display->colormap_processing = (int)output_processing;
+
+ return 1/*ok*/;
+}
+
+/* The final part of the color-map read called from png_image_finish_read. */
+static int
+png_image_read_and_map(png_voidp argument)
+{
+ png_image_read_control *display = png_voidcast(png_image_read_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+ int passes;
+
+ /* Called when the libpng data must be transformed into the color-mapped
+ * form. There is a local row buffer in display->local and this routine must
+ * do the interlace handling.
+ */
+ switch (png_ptr->interlaced)
+ {
+ case PNG_INTERLACE_NONE:
+ passes = 1;
+ break;
+
+ case PNG_INTERLACE_ADAM7:
+ passes = PNG_INTERLACE_ADAM7_PASSES;
+ break;
+
+ default:
+ png_error(png_ptr, "unknown interlace type");
+ }
+
+ {
+ png_uint_32 height = image->height;
+ png_uint_32 width = image->width;
+ int proc = display->colormap_processing;
+ png_bytep first_row = png_voidcast(png_bytep, display->first_row);
+ ptrdiff_t step_row = display->row_bytes;
+ int pass;
+
+ for (pass = 0; pass < passes; ++pass)
+ {
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
+
+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+ {
+ /* The row may be empty for a short image: */
+ if (PNG_PASS_COLS(width, pass) == 0)
+ continue;
+
+ startx = PNG_PASS_START_COL(pass);
+ stepx = PNG_PASS_COL_OFFSET(pass);
+ y = PNG_PASS_START_ROW(pass);
+ stepy = PNG_PASS_ROW_OFFSET(pass);
+ }
+
+ else
+ {
+ y = 0;
+ startx = 0;
+ stepx = stepy = 1;
+ }
+
+ for (; y<height; y += stepy)
+ {
+ png_bytep inrow = png_voidcast(png_bytep, display->local_row);
+ png_bytep outrow = first_row + y * step_row;
+ png_const_bytep end_row = outrow + width;
+
+ /* Read read the libpng data into the temporary buffer. */
+ png_read_row(png_ptr, inrow, NULL);
+
+ /* Now process the row according to the processing option, note
+ * that the caller verifies that the format of the libpng output
+ * data is as required.
+ */
+ outrow += startx;
+ switch (proc)
+ {
+ case PNG_CMAP_GA:
+ for (; outrow < end_row; outrow += stepx)
+ {
+ /* The data is always in the PNG order */
+ unsigned int gray = *inrow++;
+ unsigned int alpha = *inrow++;
+ unsigned int entry;
+
+ /* NOTE: this code is copied as a comment in
+ * make_ga_colormap above. Please update the
+ * comment if you change this code!
+ */
+ if (alpha > 229) /* opaque */
+ {
+ entry = (231 * gray + 128) >> 8;
+ }
+ else if (alpha < 26) /* transparent */
+ {
+ entry = 231;
+ }
+ else /* partially opaque */
+ {
+ entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray);
+ }
+
+ *outrow = (png_byte)entry;
+ }
+ break;
+
+ case PNG_CMAP_TRANS:
+ for (; outrow < end_row; outrow += stepx)
+ {
+ png_byte gray = *inrow++;
+ png_byte alpha = *inrow++;
+
+ if (alpha == 0)
+ *outrow = PNG_CMAP_TRANS_BACKGROUND;
+
+ else if (gray != PNG_CMAP_TRANS_BACKGROUND)
+ *outrow = gray;
+
+ else
+ *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1);
+ }
+ break;
+
+ case PNG_CMAP_RGB:
+ for (; outrow < end_row; outrow += stepx)
+ {
+ *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]);
+ inrow += 3;
+ }
+ break;
+
+ case PNG_CMAP_RGB_ALPHA:
+ for (; outrow < end_row; outrow += stepx)
+ {
+ unsigned int alpha = inrow[3];
+
+ /* Because the alpha entries only hold alpha==0.5 values
+ * split the processing at alpha==0.25 (64) and 0.75
+ * (196).
+ */
+
+ if (alpha >= 196)
+ *outrow = PNG_RGB_INDEX(inrow[0], inrow[1],
+ inrow[2]);
+
+ else if (alpha < 64)
+ *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;
+
+ else
+ {
+ /* Likewise there are three entries for each of r, g
+ * and b. We could select the entry by popcount on
+ * the top two bits on those architectures that
+ * support it, this is what the code below does,
+ * crudely.
+ */
+ unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1;
+
+ /* Here are how the values map:
+ *
+ * 0x00 .. 0x3f -> 0
+ * 0x40 .. 0xbf -> 1
+ * 0xc0 .. 0xff -> 2
+ *
+ * So, as above with the explicit alpha checks, the
+ * breakpoints are at 64 and 196.
+ */
+ if (inrow[0] & 0x80) back_i += 9; /* red */
+ if (inrow[0] & 0x40) back_i += 9;
+ if (inrow[0] & 0x80) back_i += 3; /* green */
+ if (inrow[0] & 0x40) back_i += 3;
+ if (inrow[0] & 0x80) back_i += 1; /* blue */
+ if (inrow[0] & 0x40) back_i += 1;
+
+ *outrow = (png_byte)back_i;
+ }
+
+ inrow += 4;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+static int
+png_image_read_colormapped(png_voidp argument)
+{
+ png_image_read_control *display = png_voidcast(png_image_read_control*,
+ argument);
+ png_imagep image = display->image;
+ png_controlp control = image->opaque;
+ png_structrp png_ptr = control->png_ptr;
+ png_inforp info_ptr = control->info_ptr;
+
+ int passes = 0; /* As a flag */
+
+ PNG_SKIP_CHUNKS(png_ptr);
+
+ /* Update the 'info' structure and make sure the result is as required; first
+ * make sure to turn on the interlace handling if it will be required
+ * (because it can't be turned on *after* the call to png_read_update_info!)
+ */
+ if (display->colormap_processing == PNG_CMAP_NONE)
+ passes = png_set_interlace_handling(png_ptr);
+
+ png_read_update_info(png_ptr, info_ptr);
+
+ /* The expected output can be deduced from the colormap_processing option. */
+ switch (display->colormap_processing)
+ {
+ case PNG_CMAP_NONE:
+ /* Output must be one channel and one byte per pixel, the output
+ * encoding can be anything.
+ */
+ if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+ info_ptr->color_type == PNG_COLOR_TYPE_GRAY) &&
+ info_ptr->bit_depth == 8)
+ break;
+
+ goto bad_output;
+
+ case PNG_CMAP_TRANS:
+ case PNG_CMAP_GA:
+ /* Output must be two channels and the 'G' one must be sRGB, the latter
+ * can be checked with an exact number because it should have been set
+ * to this number above!
+ */
+ if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ info_ptr->bit_depth == 8 &&
+ png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
+ image->colormap_entries == 256)
+ break;
+
+ goto bad_output;
+
+ case PNG_CMAP_RGB:
+ /* Output must be 8-bit sRGB encoded RGB */
+ if (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
+ info_ptr->bit_depth == 8 &&
+ png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
+ image->colormap_entries == 216)
+ break;
+
+ goto bad_output;
+
+ case PNG_CMAP_RGB_ALPHA:
+ /* Output must be 8-bit sRGB encoded RGBA */
+ if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+ info_ptr->bit_depth == 8 &&
+ png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
+ image->colormap_entries == 244 /* 216 + 1 + 27 */)
+ break;
+
+ goto bad_output;
+
+ default:
+ bad_output:
+ png_error(png_ptr, "bad color-map processing (internal error)");
+ }
+
+ /* Now read the rows. Do this here if it is possible to read directly into
+ * the output buffer, otherwise allocate a local row buffer of the maximum
+ * size libpng requires and call the relevant processing routine safely.
+ */
+ {
+ png_voidp first_row = display->buffer;
+ ptrdiff_t row_bytes = display->row_stride;
+
+ /* The following expression is designed to work correctly whether it gives
+ * a signed or an unsigned result.
+ */
+ if (row_bytes < 0)
+ {
+ char *ptr = png_voidcast(char*, first_row);
+ ptr += (image->height-1) * (-row_bytes);
+ first_row = png_voidcast(png_voidp, ptr);
+ }
+
+ display->first_row = first_row;
+ display->row_bytes = row_bytes;
+ }
+
+ if (passes == 0)
+ {
+ int result;
+ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
+
+ display->local_row = row;
+ result = png_safe_execute(image, png_image_read_and_map, display);
+ display->local_row = NULL;
+ png_free(png_ptr, row);
+
+ return result;
+ }
+
+ else
+ {
+ png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
+
+ while (--passes >= 0)
+ {
+ png_uint_32 y = image->height;
+ png_bytep row = png_voidcast(png_bytep, display->first_row);
+
+ for (; y > 0; --y)
+ {
+ png_read_row(png_ptr, row, NULL);
+ row += row_bytes;
+ }
+ }
+
+ return 1;
+ }
+}
+
+/* Just the row reading part of png_image_read. */
+static int
+png_image_read_composite(png_voidp argument)
+{
+ png_image_read_control *display = png_voidcast(png_image_read_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+ int passes;
+
+ switch (png_ptr->interlaced)
+ {
+ case PNG_INTERLACE_NONE:
+ passes = 1;
+ break;
+
+ case PNG_INTERLACE_ADAM7:
+ passes = PNG_INTERLACE_ADAM7_PASSES;
+ break;
+
+ default:
+ png_error(png_ptr, "unknown interlace type");
+ }
+
+ {
+ png_uint_32 height = image->height;
+ png_uint_32 width = image->width;
+ ptrdiff_t step_row = display->row_bytes;
+ unsigned int channels =
+ (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1;
+ int pass;
+
+ for (pass = 0; pass < passes; ++pass)
+ {
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
+
+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+ {
+ /* The row may be empty for a short image: */
+ if (PNG_PASS_COLS(width, pass) == 0)
+ continue;
+
+ startx = PNG_PASS_START_COL(pass) * channels;
+ stepx = PNG_PASS_COL_OFFSET(pass) * channels;
+ y = PNG_PASS_START_ROW(pass);
+ stepy = PNG_PASS_ROW_OFFSET(pass);
+ }
+
+ else
+ {
+ y = 0;
+ startx = 0;
+ stepx = channels;
+ stepy = 1;
+ }
+
+ for (; y<height; y += stepy)
+ {
+ png_bytep inrow = png_voidcast(png_bytep, display->local_row);
+ png_bytep outrow;
+ png_const_bytep end_row;
+
+ /* Read the row, which is packed: */
+ png_read_row(png_ptr, inrow, NULL);
+
+ outrow = png_voidcast(png_bytep, display->first_row);
+ outrow += y * step_row;
+ end_row = outrow + width * channels;
+
+ /* Now do the composition on each pixel in this row. */
+ outrow += startx;
+ for (; outrow < end_row; outrow += stepx)
+ {
+ png_byte alpha = inrow[channels];
+
+ if (alpha > 0) /* else no change to the output */
+ {
+ unsigned int c;
+
+ for (c=0; c<channels; ++c)
+ {
+ png_uint_32 component = inrow[c];
+
+ if (alpha < 255) /* else just use component */
+ {
+ /* This is PNG_OPTIMIZED_ALPHA, the component value
+ * is a linear 8-bit value. Combine this with the
+ * current outrow[c] value which is sRGB encoded.
+ * Arithmetic here is 16-bits to preserve the output
+ * values correctly.
+ */
+ component *= 257*255; /* =65535 */
+ component += (255-alpha)*png_sRGB_table[outrow[c]];
+
+ /* So 'component' is scaled by 255*65535 and is
+ * therefore appropriate for the sRGB to linear
+ * conversion table.
+ */
+ component = PNG_sRGB_FROM_LINEAR(component);
+ }
+
+ outrow[c] = (png_byte)component;
+ }
+ }
+
+ inrow += channels+1; /* components and alpha channel */
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+/* The do_local_background case; called when all the following transforms are to
+ * be done:
+ *
+ * PNG_RGB_TO_GRAY
+ * PNG_COMPOSITE
+ * PNG_GAMMA
+ *
+ * This is a work-around for the fact that both the PNG_RGB_TO_GRAY and
+ * PNG_COMPOSITE code performs gamma correction, so we get double gamma
+ * correction. The fix-up is to prevent the PNG_COMPOSITE operation from
+ * happening inside libpng, so this routine sees an 8 or 16-bit gray+alpha
+ * row and handles the removal or pre-multiplication of the alpha channel.
+ */
+static int
+png_image_read_background(png_voidp argument)
+{
+ png_image_read_control *display = png_voidcast(png_image_read_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+ png_inforp info_ptr = image->opaque->info_ptr;
+ png_uint_32 height = image->height;
+ png_uint_32 width = image->width;
+ int pass, passes;
+
+ /* Double check the convoluted logic below. We expect to get here with
+ * libpng doing rgb to gray and gamma correction but background processing
+ * left to the png_image_read_background function. The rows libpng produce
+ * might be 8 or 16-bit but should always have two channels; gray plus alpha.
+ */
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
+ png_error(png_ptr, "lost rgb to gray");
+
+ if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+ png_error(png_ptr, "unexpected compose");
+
+ if (png_get_channels(png_ptr, info_ptr) != 2)
+ png_error(png_ptr, "lost/gained channels");
+
+ /* Expect the 8-bit case to always remove the alpha channel */
+ if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 &&
+ (image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ png_error(png_ptr, "unexpected 8-bit transformation");
+
+ switch (png_ptr->interlaced)
+ {
+ case PNG_INTERLACE_NONE:
+ passes = 1;
+ break;
+
+ case PNG_INTERLACE_ADAM7:
+ passes = PNG_INTERLACE_ADAM7_PASSES;
+ break;
+
+ default:
+ png_error(png_ptr, "unknown interlace type");
+ }
+
+ /* Use direct access to info_ptr here because otherwise the simplified API
+ * would require PNG_EASY_ACCESS_SUPPORTED (just for this.) Note this is
+ * checking the value after libpng expansions, not the original value in the
+ * PNG.
+ */
+ switch (info_ptr->bit_depth)
+ {
+ case 8:
+ /* 8-bit sRGB gray values with an alpha channel; the alpha channel is
+ * to be removed by composing on a background: either the row if
+ * display->background is NULL or display->background->green if not.
+ * Unlike the code above ALPHA_OPTIMIZED has *not* been done.
+ */
+ {
+ png_bytep first_row = png_voidcast(png_bytep, display->first_row);
+ ptrdiff_t step_row = display->row_bytes;
+
+ for (pass = 0; pass < passes; ++pass)
+ {
+ png_bytep row = png_voidcast(png_bytep, display->first_row);
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
+
+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+ {
+ /* The row may be empty for a short image: */
+ if (PNG_PASS_COLS(width, pass) == 0)
+ continue;
+
+ startx = PNG_PASS_START_COL(pass);
+ stepx = PNG_PASS_COL_OFFSET(pass);
+ y = PNG_PASS_START_ROW(pass);
+ stepy = PNG_PASS_ROW_OFFSET(pass);
+ }
+
+ else
+ {
+ y = 0;
+ startx = 0;
+ stepx = stepy = 1;
+ }
+
+ if (display->background == NULL)
+ {
+ for (; y<height; y += stepy)
+ {
+ png_bytep inrow = png_voidcast(png_bytep,
+ display->local_row);
+ png_bytep outrow = first_row + y * step_row;
+ png_const_bytep end_row = outrow + width;
+
+ /* Read the row, which is packed: */
+ png_read_row(png_ptr, inrow, NULL);
+
+ /* Now do the composition on each pixel in this row. */
+ outrow += startx;
+ for (; outrow < end_row; outrow += stepx)
+ {
+ png_byte alpha = inrow[1];
+
+ if (alpha > 0) /* else no change to the output */
+ {
+ png_uint_32 component = inrow[0];
+
+ if (alpha < 255) /* else just use component */
+ {
+ /* Since PNG_OPTIMIZED_ALPHA was not set it is
+ * necessary to invert the sRGB transfer
+ * function and multiply the alpha out.
+ */
+ component = png_sRGB_table[component] * alpha;
+ component += png_sRGB_table[outrow[0]] *
+ (255-alpha);
+ component = PNG_sRGB_FROM_LINEAR(component);
+ }
+
+ outrow[0] = (png_byte)component;
+ }
+
+ inrow += 2; /* gray and alpha channel */
+ }
+ }
+ }
+
+ else /* constant background value */
+ {
+ png_byte background8 = display->background->green;
+ png_uint_16 background = png_sRGB_table[background8];
+
+ for (; y<height; y += stepy)
+ {
+ png_bytep inrow = png_voidcast(png_bytep,
+ display->local_row);
+ png_bytep outrow = first_row + y * step_row;
+ png_const_bytep end_row = outrow + width;
+
+ /* Read the row, which is packed: */
+ png_read_row(png_ptr, inrow, NULL);
+
+ /* Now do the composition on each pixel in this row. */
+ outrow += startx;
+ for (; outrow < end_row; outrow += stepx)
+ {
+ png_byte alpha = inrow[1];
+
+ if (alpha > 0) /* else use background */
+ {
+ png_uint_32 component = inrow[0];
+
+ if (alpha < 255) /* else just use component */
+ {
+ component = png_sRGB_table[component] * alpha;
+ component += background * (255-alpha);
+ component = PNG_sRGB_FROM_LINEAR(component);
+ }
+
+ outrow[0] = (png_byte)component;
+ }
+
+ else
+ outrow[0] = background8;
+
+ inrow += 2; /* gray and alpha channel */
+ }
+
+ row += display->row_bytes;
+ }
+ }
+ }
+ }
+ break;
+
+ case 16:
+ /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must
+ * still be done and, maybe, the alpha channel removed. This code also
+ * handles the alpha-first option.
+ */
+ {
+ png_uint_16p first_row = png_voidcast(png_uint_16p,
+ display->first_row);
+ /* The division by two is safe because the caller passed in a
+ * stride which was multiplied by 2 (below) to get row_bytes.
+ */
+ ptrdiff_t step_row = display->row_bytes / 2;
+ unsigned int preserve_alpha = (image->format &
+ PNG_FORMAT_FLAG_ALPHA) != 0;
+ unsigned int outchannels = 1U+preserve_alpha;
+ int swap_alpha = 0;
+
+# ifdef PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
+ if (preserve_alpha != 0 &&
+ (image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
+ swap_alpha = 1;
+# endif
+
+ for (pass = 0; pass < passes; ++pass)
+ {
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
+
+ /* The 'x' start and step are adjusted to output components here.
+ */
+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+ {
+ /* The row may be empty for a short image: */
+ if (PNG_PASS_COLS(width, pass) == 0)
+ continue;
+
+ startx = PNG_PASS_START_COL(pass) * outchannels;
+ stepx = PNG_PASS_COL_OFFSET(pass) * outchannels;
+ y = PNG_PASS_START_ROW(pass);
+ stepy = PNG_PASS_ROW_OFFSET(pass);
+ }
+
+ else
+ {
+ y = 0;
+ startx = 0;
+ stepx = outchannels;
+ stepy = 1;
+ }
+
+ for (; y<height; y += stepy)
+ {
+ png_const_uint_16p inrow;
+ png_uint_16p outrow = first_row + y*step_row;
+ png_uint_16p end_row = outrow + width * outchannels;
+
+ /* Read the row, which is packed: */
+ png_read_row(png_ptr, png_voidcast(png_bytep,
+ display->local_row), NULL);
+ inrow = png_voidcast(png_const_uint_16p, display->local_row);
+
+ /* Now do the pre-multiplication on each pixel in this row.
+ */
+ outrow += startx;
+ for (; outrow < end_row; outrow += stepx)
+ {
+ png_uint_32 component = inrow[0];
+ png_uint_16 alpha = inrow[1];
+
+ if (alpha > 0) /* else 0 */
+ {
+ if (alpha < 65535) /* else just use component */
+ {
+ component *= alpha;
+ component += 32767;
+ component /= 65535;
+ }
+ }
+
+ else
+ component = 0;
+
+ outrow[swap_alpha] = (png_uint_16)component;
+ if (preserve_alpha != 0)
+ outrow[1 ^ swap_alpha] = alpha;
+
+ inrow += 2; /* components and alpha channel */
+ }
+ }
+ }
+ }
+ break;
+
+#ifdef __GNUC__
+ default:
+ png_error(png_ptr, "unexpected bit depth");
+#endif
+ }
+
+ return 1;
+}
+
+/* The guts of png_image_finish_read as a png_safe_execute callback. */
+static int
+png_image_read_direct(png_voidp argument)
+{
+ png_image_read_control *display = png_voidcast(png_image_read_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+ png_inforp info_ptr = image->opaque->info_ptr;
+
+ png_uint_32 format = image->format;
+ int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0;
+ int do_local_compose = 0;
+ int do_local_background = 0; /* to avoid double gamma correction bug */
+ int passes = 0;
+
+ /* Add transforms to ensure the correct output format is produced then check
+ * that the required implementation support is there. Always expand; always
+ * need 8 bits minimum, no palette and expanded tRNS.
+ */
+ png_set_expand(png_ptr);
+
+ /* Now check the format to see if it was modified. */
+ {
+ png_uint_32 base_format = png_image_format(png_ptr) &
+ ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */;
+ png_uint_32 change = format ^ base_format;
+ png_fixed_point output_gamma;
+ int mode; /* alpha mode */
+
+ /* Do this first so that we have a record if rgb to gray is happening. */
+ if ((change & PNG_FORMAT_FLAG_COLOR) != 0)
+ {
+ /* gray<->color transformation required. */
+ if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
+ png_set_gray_to_rgb(png_ptr);
+
+ else
+ {
+ /* libpng can't do both rgb to gray and
+ * background/pre-multiplication if there is also significant gamma
+ * correction, because both operations require linear colors and
+ * the code only supports one transform doing the gamma correction.
+ * Handle this by doing the pre-multiplication or background
+ * operation in this code, if necessary.
+ *
+ * TODO: fix this by rewriting pngrtran.c (!)
+ *
+ * For the moment (given that fixing this in pngrtran.c is an
+ * enormous change) 'do_local_background' is used to indicate that
+ * the problem exists.
+ */
+ if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ do_local_background = 1/*maybe*/;
+
+ png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,
+ PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
+ }
+
+ change &= ~PNG_FORMAT_FLAG_COLOR;
+ }
+
+ /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise.
+ */
+ {
+ png_fixed_point input_gamma_default;
+
+ if ((base_format & PNG_FORMAT_FLAG_LINEAR) != 0 &&
+ (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
+ input_gamma_default = PNG_GAMMA_LINEAR;
+ else
+ input_gamma_default = PNG_DEFAULT_sRGB;
+
+ /* Call png_set_alpha_mode to set the default for the input gamma; the
+ * output gamma is set by a second call below.
+ */
+ png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default);
+ }
+
+ if (linear != 0)
+ {
+ /* If there *is* an alpha channel in the input it must be multiplied
+ * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG.
+ */
+ if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ mode = PNG_ALPHA_STANDARD; /* associated alpha */
+
+ else
+ mode = PNG_ALPHA_PNG;
+
+ output_gamma = PNG_GAMMA_LINEAR;
+ }
+
+ else
+ {
+ mode = PNG_ALPHA_PNG;
+ output_gamma = PNG_DEFAULT_sRGB;
+ }
+
+ if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0)
+ {
+ mode = PNG_ALPHA_OPTIMIZED;
+ change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
+ }
+
+ /* If 'do_local_background' is set check for the presence of gamma
+ * correction; this is part of the work-round for the libpng bug
+ * described above.
+ *
+ * TODO: fix libpng and remove this.
+ */
+ if (do_local_background != 0)
+ {
+ png_fixed_point gtest;
+
+ /* This is 'png_gamma_threshold' from pngrtran.c; the test used for
+ * gamma correction, the screen gamma hasn't been set on png_struct
+ * yet; it's set below. png_struct::gamma, however, is set to the
+ * final value.
+ */
+ if (png_muldiv(&gtest, output_gamma, png_ptr->colorspace.gamma,
+ PNG_FP_1) != 0 && png_gamma_significant(gtest) == 0)
+ do_local_background = 0;
+
+ else if (mode == PNG_ALPHA_STANDARD)
+ {
+ do_local_background = 2/*required*/;
+ mode = PNG_ALPHA_PNG; /* prevent libpng doing it */
+ }
+
+ /* else leave as 1 for the checks below */
+ }
+
+ /* If the bit-depth changes then handle that here. */
+ if ((change & PNG_FORMAT_FLAG_LINEAR) != 0)
+ {
+ if (linear != 0 /*16-bit output*/)
+ png_set_expand_16(png_ptr);
+
+ else /* 8-bit output */
+ png_set_scale_16(png_ptr);
+
+ change &= ~PNG_FORMAT_FLAG_LINEAR;
+ }
+
+ /* Now the background/alpha channel changes. */
+ if ((change & PNG_FORMAT_FLAG_ALPHA) != 0)
+ {
+ /* Removing an alpha channel requires composition for the 8-bit
+ * formats; for the 16-bit it is already done, above, by the
+ * pre-multiplication and the channel just needs to be stripped.
+ */
+ if ((base_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ {
+ /* If RGB->gray is happening the alpha channel must be left and the
+ * operation completed locally.
+ *
+ * TODO: fix libpng and remove this.
+ */
+ if (do_local_background != 0)
+ do_local_background = 2/*required*/;
+
+ /* 16-bit output: just remove the channel */
+ else if (linear != 0) /* compose on black (well, pre-multiply) */
+ png_set_strip_alpha(png_ptr);
+
+ /* 8-bit output: do an appropriate compose */
+ else if (display->background != NULL)
+ {
+ png_color_16 c;
+
+ c.index = 0; /*unused*/
+ c.red = display->background->red;
+ c.green = display->background->green;
+ c.blue = display->background->blue;
+ c.gray = display->background->green;
+
+ /* This is always an 8-bit sRGB value, using the 'green' channel
+ * for gray is much better than calculating the luminance here;
+ * we can get off-by-one errors in that calculation relative to
+ * the app expectations and that will show up in transparent
+ * pixels.
+ */
+ png_set_background_fixed(png_ptr, &c,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
+ }
+
+ else /* compose on row: implemented below. */
+ {
+ do_local_compose = 1;
+ /* This leaves the alpha channel in the output, so it has to be
+ * removed by the code below. Set the encoding to the 'OPTIMIZE'
+ * one so the code only has to hack on the pixels that require
+ * composition.
+ */
+ mode = PNG_ALPHA_OPTIMIZED;
+ }
+ }
+
+ else /* output needs an alpha channel */
+ {
+ /* This is tricky because it happens before the swap operation has
+ * been accomplished; however, the swap does *not* swap the added
+ * alpha channel (weird API), so it must be added in the correct
+ * place.
+ */
+ png_uint_32 filler; /* opaque filler */
+ int where;
+
+ if (linear != 0)
+ filler = 65535;
+
+ else
+ filler = 255;
+
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
+ if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
+ {
+ where = PNG_FILLER_BEFORE;
+ change &= ~PNG_FORMAT_FLAG_AFIRST;
+ }
+
+ else
+#endif
+ where = PNG_FILLER_AFTER;
+
+ png_set_add_alpha(png_ptr, filler, where);
+ }
+
+ /* This stops the (irrelevant) call to swap_alpha below. */
+ change &= ~PNG_FORMAT_FLAG_ALPHA;
+ }
+
+ /* Now set the alpha mode correctly; this is always done, even if there is
+ * no alpha channel in either the input or the output because it correctly
+ * sets the output gamma.
+ */
+ png_set_alpha_mode_fixed(png_ptr, mode, output_gamma);
+
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ if ((change & PNG_FORMAT_FLAG_BGR) != 0)
+ {
+ /* Check only the output format; PNG is never BGR; don't do this if
+ * the output is gray, but fix up the 'format' value in that case.
+ */
+ if ((format & PNG_FORMAT_FLAG_COLOR) != 0)
+ png_set_bgr(png_ptr);
+
+ else
+ format &= ~PNG_FORMAT_FLAG_BGR;
+
+ change &= ~PNG_FORMAT_FLAG_BGR;
+ }
+# endif
+
+# ifdef PNG_FORMAT_AFIRST_SUPPORTED
+ if ((change & PNG_FORMAT_FLAG_AFIRST) != 0)
+ {
+ /* Only relevant if there is an alpha channel - it's particularly
+ * important to handle this correctly because do_local_compose may
+ * be set above and then libpng will keep the alpha channel for this
+ * code to remove.
+ */
+ if ((format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ {
+ /* Disable this if doing a local background,
+ * TODO: remove this when local background is no longer required.
+ */
+ if (do_local_background != 2)
+ png_set_swap_alpha(png_ptr);
+ }
+
+ else
+ format &= ~PNG_FORMAT_FLAG_AFIRST;
+
+ change &= ~PNG_FORMAT_FLAG_AFIRST;
+ }
+# endif
+
+ /* If the *output* is 16-bit then we need to check for a byte-swap on this
+ * architecture.
+ */
+ if (linear != 0)
+ {
+ PNG_CONST png_uint_16 le = 0x0001;
+
+ if ((*(png_const_bytep) & le) != 0)
+ png_set_swap(png_ptr);
+ }
+
+ /* If change is not now 0 some transformation is missing - error out. */
+ if (change != 0)
+ png_error(png_ptr, "png_read_image: unsupported transformation");
+ }
+
+ PNG_SKIP_CHUNKS(png_ptr);
+
+ /* Update the 'info' structure and make sure the result is as required; first
+ * make sure to turn on the interlace handling if it will be required
+ * (because it can't be turned on *after* the call to png_read_update_info!)
+ *
+ * TODO: remove the do_local_background fixup below.
+ */
+ if (do_local_compose == 0 && do_local_background != 2)
+ passes = png_set_interlace_handling(png_ptr);
+
+ png_read_update_info(png_ptr, info_ptr);
+
+ {
+ png_uint_32 info_format = 0;
+
+ if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ info_format |= PNG_FORMAT_FLAG_COLOR;
+
+ if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ {
+ /* do_local_compose removes this channel below. */
+ if (do_local_compose == 0)
+ {
+ /* do_local_background does the same if required. */
+ if (do_local_background != 2 ||
+ (format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ info_format |= PNG_FORMAT_FLAG_ALPHA;
+ }
+ }
+
+ else if (do_local_compose != 0) /* internal error */
+ png_error(png_ptr, "png_image_read: alpha channel lost");
+
+ if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) {
+ info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
+ }
+
+ if (info_ptr->bit_depth == 16)
+ info_format |= PNG_FORMAT_FLAG_LINEAR;
+
+#ifdef PNG_FORMAT_BGR_SUPPORTED
+ if ((png_ptr->transformations & PNG_BGR) != 0)
+ info_format |= PNG_FORMAT_FLAG_BGR;
+#endif
+
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
+ if (do_local_background == 2)
+ {
+ if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
+ info_format |= PNG_FORMAT_FLAG_AFIRST;
+ }
+
+ if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 ||
+ ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 &&
+ (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0))
+ {
+ if (do_local_background == 2)
+ png_error(png_ptr, "unexpected alpha swap transformation");
+
+ info_format |= PNG_FORMAT_FLAG_AFIRST;
+ }
+# endif
+
+ /* This is actually an internal error. */
+ if (info_format != format)
+ png_error(png_ptr, "png_read_image: invalid transformations");
+ }
+
+ /* Now read the rows. If do_local_compose is set then it is necessary to use
+ * a local row buffer. The output will be GA, RGBA or BGRA and must be
+ * converted to G, RGB or BGR as appropriate. The 'local_row' member of the
+ * display acts as a flag.
+ */
+ {
+ png_voidp first_row = display->buffer;
+ ptrdiff_t row_bytes = display->row_stride;
+
+ if (linear != 0)
+ row_bytes *= 2;
+
+ /* The following expression is designed to work correctly whether it gives
+ * a signed or an unsigned result.
+ */
+ if (row_bytes < 0)
+ {
+ char *ptr = png_voidcast(char*, first_row);
+ ptr += (image->height-1) * (-row_bytes);
+ first_row = png_voidcast(png_voidp, ptr);
+ }
+
+ display->first_row = first_row;
+ display->row_bytes = row_bytes;
+ }
+
+ if (do_local_compose != 0)
+ {
+ int result;
+ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
+
+ display->local_row = row;
+ result = png_safe_execute(image, png_image_read_composite, display);
+ display->local_row = NULL;
+ png_free(png_ptr, row);
+
+ return result;
+ }
+
+ else if (do_local_background == 2)
+ {
+ int result;
+ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
+
+ display->local_row = row;
+ result = png_safe_execute(image, png_image_read_background, display);
+ display->local_row = NULL;
+ png_free(png_ptr, row);
+
+ return result;
+ }
+
+ else
+ {
+ png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
+
+ while (--passes >= 0)
+ {
+ png_uint_32 y = image->height;
+ png_bytep row = png_voidcast(png_bytep, display->first_row);
+
+ for (; y > 0; --y)
+ {
+ png_read_row(png_ptr, row, NULL);
+ row += row_bytes;
+ }
+ }
+
+ return 1;
+ }
+}
+
+int PNGAPI
+png_image_finish_read(png_imagep image, png_const_colorp background,
+ void *buffer, png_int_32 row_stride, void *colormap)
+{
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ /* Check for row_stride overflow. This check is not performed on the
+ * original PNG format because it may not occur in the output PNG format
+ * and libpng deals with the issues of reading the original.
+ */
+ const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
+
+ /* The following checks just the 'row_stride' calculation to ensure it
+ * fits in a signed 32-bit value. Because channels/components can be
+ * either 1 or 2 bytes in size the length of a row can still overflow 32
+ * bits; this is just to verify that the 'row_stride' argument can be
+ * represented.
+ */
+ if (image->width <= 0x7fffffffU/channels) /* no overflow */
+ {
+ png_uint_32 check;
+ const png_uint_32 png_row_stride = image->width * channels;
+
+ if (row_stride == 0)
+ row_stride = (png_int_32)/*SAFE*/png_row_stride;
+
+ if (row_stride < 0)
+ check = (png_uint_32)(-row_stride);
+
+ else
+ check = (png_uint_32)row_stride;
+
+ /* This verifies 'check', the absolute value of the actual stride
+ * passed in and detects overflow in the application calculation (i.e.
+ * if the app did actually pass in a non-zero 'row_stride'.
+ */
+ if (image->opaque != NULL && buffer != NULL && check >= png_row_stride)
+ {
+ /* Now check for overflow of the image buffer calculation; this
+ * limits the whole image size to 32 bits for API compatibility with
+ * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
+ *
+ * The PNG_IMAGE_BUFFER_SIZE macro is:
+ *
+ * (PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)*height*(row_stride))
+ *
+ * And the component size is always 1 or 2, so make sure that the
+ * number of *bytes* that the application is saying are available
+ * does actually fit into a 32-bit number.
+ *
+ * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE
+ * will be changed to use png_alloc_size_t; bigger images can be
+ * accomodated on 64-bit systems.
+ */
+ if (image->height <=
+ 0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check)
+ {
+ if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
+ (image->colormap_entries > 0 && colormap != NULL))
+ {
+ int result;
+ png_image_read_control display;
+
+ memset(&display, 0, (sizeof display));
+ display.image = image;
+ display.buffer = buffer;
+ display.row_stride = row_stride;
+ display.colormap = colormap;
+ display.background = background;
+ display.local_row = NULL;
+
+ /* Choose the correct 'end' routine; for the color-map case
+ * all the setup has already been done.
+ */
+ if ((image->format & PNG_FORMAT_FLAG_COLORMAP) != 0)
+ result =
+ png_safe_execute(image,
+ png_image_read_colormap, &display) &&
+ png_safe_execute(image,
+ png_image_read_colormapped, &display);
+
+ else
+ result =
+ png_safe_execute(image,
+ png_image_read_direct, &display);
+
+ png_image_free(image);
+ return result;
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_finish_read[color-map]: no color-map");
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_finish_read: image too large");
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_finish_read: invalid argument");
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_finish_read: row_stride too large");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_finish_read: damaged PNG_IMAGE_VERSION");
+
+ return 0;
+}
+
+#endif /* SIMPLIFIED_READ */
+#endif /* READ */
diff --git a/xs/src/png/libpng/pngrio.c b/xs/src/png/libpng/pngrio.c
new file mode 100644
index 000000000..7e26e855c
--- /dev/null
+++ b/xs/src/png/libpng/pngrio.c
@@ -0,0 +1,120 @@
+
+/* pngrio.c - functions for data input
+ *
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all input. Users who need
+ * special handling are expected to write a function that has the same
+ * arguments as this and performs a similar function, but that possibly
+ * has a different input method. Note that you shouldn't change this
+ * function, but rather write a replacement function and then make
+ * libpng use it at run time with png_set_read_fn(...).
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* Read the data from whatever input you are using. The default routine
+ * reads from a file pointer. Note that this routine sometimes gets called
+ * with very small lengths, so you should implement some kind of simple
+ * buffering if you are using unbuffered reads. This should never be asked
+ * to read more than 64K on a 16-bit machine.
+ */
+void /* PRIVATE */
+png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length)
+{
+ png_debug1(4, "reading %d bytes", (int)length);
+
+ if (png_ptr->read_data_fn != NULL)
+ (*(png_ptr->read_data_fn))(png_ptr, data, length);
+
+ else
+ png_error(png_ptr, "Call to NULL read function");
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+/* This is the function that does the actual reading of data. If you are
+ * not reading from a standard C stream, you should create a replacement
+ * read_data function and use it at run time with png_set_read_fn(), rather
+ * than changing the library.
+ */
+void PNGCBAPI
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_size_t check;
+
+ if (png_ptr == NULL)
+ return;
+
+ /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+ * instead of an int, which is what fread() actually returns.
+ */
+ check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr));
+
+ if (check != length)
+ png_error(png_ptr, "Read Error");
+}
+#endif
+
+/* This function allows the application to supply a new input function
+ * for libpng if standard C streams aren't being used.
+ *
+ * This function takes as its arguments:
+ *
+ * png_ptr - pointer to a png input data structure
+ *
+ * io_ptr - pointer to user supplied structure containing info about
+ * the input functions. May be NULL.
+ *
+ * read_data_fn - pointer to a new input function that takes as its
+ * arguments a pointer to a png_struct, a pointer to
+ * a location where input data can be stored, and a 32-bit
+ * unsigned int that is the number of bytes to be read.
+ * To exit and output any fatal error messages the new write
+ * function should call png_error(png_ptr, "Error msg").
+ * May be NULL, in which case libpng's default function will
+ * be used.
+ */
+void PNGAPI
+png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
+ png_rw_ptr read_data_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->io_ptr = io_ptr;
+
+#ifdef PNG_STDIO_SUPPORTED
+ if (read_data_fn != NULL)
+ png_ptr->read_data_fn = read_data_fn;
+
+ else
+ png_ptr->read_data_fn = png_default_read_data;
+#else
+ png_ptr->read_data_fn = read_data_fn;
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+ /* It is an error to write to a read device */
+ if (png_ptr->write_data_fn != NULL)
+ {
+ png_ptr->write_data_fn = NULL;
+ png_warning(png_ptr,
+ "Can't set both read_data_fn and write_data_fn in the"
+ " same structure");
+ }
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+ png_ptr->output_flush_fn = NULL;
+#endif
+}
+#endif /* READ */
diff --git a/xs/src/png/libpng/pngrtran.c b/xs/src/png/libpng/pngrtran.c
new file mode 100644
index 000000000..c18965031
--- /dev/null
+++ b/xs/src/png/libpng/pngrtran.c
@@ -0,0 +1,5010 @@
+
+/* pngrtran.c - transforms the data in a row for PNG readers
+ *
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains functions optionally called by an application
+ * in order to tell libpng how to handle data when reading a PNG.
+ * Transformations that are used in both reading and writing are
+ * in pngtrans.c.
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* Set the action on getting a CRC error for an ancillary or critical chunk. */
+void PNGAPI
+png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
+{
+ png_debug(1, "in png_set_crc_action");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* Tell libpng how we react to CRC errors in critical chunks */
+ switch (crit_action)
+ {
+ case PNG_CRC_NO_CHANGE: /* Leave setting as is */
+ break;
+
+ case PNG_CRC_WARN_USE: /* Warn/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
+ break;
+
+ case PNG_CRC_QUIET_USE: /* Quiet/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
+ PNG_FLAG_CRC_CRITICAL_IGNORE;
+ break;
+
+ case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */
+ png_warning(png_ptr,
+ "Can't discard critical data on CRC error");
+ /* FALLTHROUGH */
+ case PNG_CRC_ERROR_QUIT: /* Error/quit */
+
+ case PNG_CRC_DEFAULT:
+ default:
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ break;
+ }
+
+ /* Tell libpng how we react to CRC errors in ancillary chunks */
+ switch (ancil_action)
+ {
+ case PNG_CRC_NO_CHANGE: /* Leave setting as is */
+ break;
+
+ case PNG_CRC_WARN_USE: /* Warn/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
+ break;
+
+ case PNG_CRC_QUIET_USE: /* Quiet/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
+ PNG_FLAG_CRC_ANCILLARY_NOWARN;
+ break;
+
+ case PNG_CRC_ERROR_QUIT: /* Error/quit */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
+ break;
+
+ case PNG_CRC_WARN_DISCARD: /* Warn/discard data */
+
+ case PNG_CRC_DEFAULT:
+ default:
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ break;
+ }
+}
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+/* Is it OK to set a transformation now? Only if png_start_read_image or
+ * png_read_update_info have not been called. It is not necessary for the IHDR
+ * to have been read in all cases; the need_IHDR parameter allows for this
+ * check too.
+ */
+static int
+png_rtran_ok(png_structrp png_ptr, int need_IHDR)
+{
+ if (png_ptr != NULL)
+ {
+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
+ png_app_error(png_ptr,
+ "invalid after png_start_read_image or png_read_update_info");
+
+ else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_app_error(png_ptr, "invalid before the PNG header has been read");
+
+ else
+ {
+ /* Turn on failure to initialize correctly for all transforms. */
+ png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
+
+ return 1; /* Ok */
+ }
+ }
+
+ return 0; /* no png_error possible! */
+}
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+/* Handle alpha and tRNS via a background color */
+void PNGFAPI
+png_set_background_fixed(png_structrp png_ptr,
+ png_const_color_16p background_color, int background_gamma_code,
+ int need_expand, png_fixed_point background_gamma)
+{
+ png_debug(1, "in png_set_background_fixed");
+
+ if (png_rtran_ok(png_ptr, 0) == 0 || background_color == NULL)
+ return;
+
+ if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
+ {
+ png_warning(png_ptr, "Application must supply a known background gamma");
+ return;
+ }
+
+ png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+
+ png_ptr->background = *background_color;
+ png_ptr->background_gamma = background_gamma;
+ png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
+ if (need_expand != 0)
+ png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
+ else
+ png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_background(png_structrp png_ptr,
+ png_const_color_16p background_color, int background_gamma_code,
+ int need_expand, double background_gamma)
+{
+ png_set_background_fixed(png_ptr, background_color, background_gamma_code,
+ need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
+}
+# endif /* FLOATING_POINT */
+#endif /* READ_BACKGROUND */
+
+/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the
+ * one that pngrtran does first (scale) happens. This is necessary to allow the
+ * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.
+ */
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+void PNGAPI
+png_set_scale_16(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_scale_16");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ png_ptr->transformations |= PNG_SCALE_16_TO_8;
+}
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+/* Chop 16-bit depth files to 8-bit depth */
+void PNGAPI
+png_set_strip_16(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_strip_16");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ png_ptr->transformations |= PNG_16_TO_8;
+}
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+void PNGAPI
+png_set_strip_alpha(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_strip_alpha");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ png_ptr->transformations |= PNG_STRIP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
+static png_fixed_point
+translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
+ int is_screen)
+{
+ /* Check for flag values. The main reason for having the old Mac value as a
+ * flag is that it is pretty near impossible to work out what the correct
+ * value is from Apple documentation - a working Mac system is needed to
+ * discover the value!
+ */
+ if (output_gamma == PNG_DEFAULT_sRGB ||
+ output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
+ {
+ /* If there is no sRGB support this just sets the gamma to the standard
+ * sRGB value. (This is a side effect of using this function!)
+ */
+# ifdef PNG_READ_sRGB_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
+# else
+ PNG_UNUSED(png_ptr)
+# endif
+ if (is_screen != 0)
+ output_gamma = PNG_GAMMA_sRGB;
+ else
+ output_gamma = PNG_GAMMA_sRGB_INVERSE;
+ }
+
+ else if (output_gamma == PNG_GAMMA_MAC_18 ||
+ output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
+ {
+ if (is_screen != 0)
+ output_gamma = PNG_GAMMA_MAC_OLD;
+ else
+ output_gamma = PNG_GAMMA_MAC_INVERSE;
+ }
+
+ return output_gamma;
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+static png_fixed_point
+convert_gamma_value(png_structrp png_ptr, double output_gamma)
+{
+ /* The following silently ignores cases where fixed point (times 100,000)
+ * gamma values are passed to the floating point API. This is safe and it
+ * means the fixed point constants work just fine with the floating point
+ * API. The alternative would just lead to undetected errors and spurious
+ * bug reports. Negative values fail inside the _fixed API unless they
+ * correspond to the flag values.
+ */
+ if (output_gamma > 0 && output_gamma < 128)
+ output_gamma *= PNG_FP_1;
+
+ /* This preserves -1 and -2 exactly: */
+ output_gamma = floor(output_gamma + .5);
+
+ if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)
+ png_fixed_error(png_ptr, "gamma value");
+
+ return (png_fixed_point)output_gamma;
+}
+# endif
+#endif /* READ_ALPHA_MODE || READ_GAMMA */
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+void PNGFAPI
+png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
+ png_fixed_point output_gamma)
+{
+ int compose = 0;
+ png_fixed_point file_gamma;
+
+ png_debug(1, "in png_set_alpha_mode");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
+
+ /* Validate the value to ensure it is in a reasonable range. The value
+ * is expected to be 1 or greater, but this range test allows for some
+ * viewing correction values. The intent is to weed out users of this API
+ * who use the inverse of the gamma value accidentally! Since some of these
+ * values are reasonable this may have to be changed:
+ *
+ * 1.6.x: changed from 0.07..3 to 0.01..100 (to accomodate the optimal 16-bit
+ * gamma of 36, and its reciprocal.)
+ */
+ if (output_gamma < 1000 || output_gamma > 10000000)
+ png_error(png_ptr, "output gamma out of expected range");
+
+ /* The default file gamma is the inverse of the output gamma; the output
+ * gamma may be changed below so get the file value first:
+ */
+ file_gamma = png_reciprocal(output_gamma);
+
+ /* There are really 8 possibilities here, composed of any combination
+ * of:
+ *
+ * premultiply the color channels
+ * do not encode non-opaque pixels
+ * encode the alpha as well as the color channels
+ *
+ * The differences disappear if the input/output ('screen') gamma is 1.0,
+ * because then the encoding is a no-op and there is only the choice of
+ * premultiplying the color channels or not.
+ *
+ * png_set_alpha_mode and png_set_background interact because both use
+ * png_compose to do the work. Calling both is only useful when
+ * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along
+ * with a default gamma value. Otherwise PNG_COMPOSE must not be set.
+ */
+ switch (mode)
+ {
+ case PNG_ALPHA_PNG: /* default: png standard */
+ /* No compose, but it may be set by png_set_background! */
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+ break;
+
+ case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */
+ compose = 1;
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+ /* The output is linear: */
+ output_gamma = PNG_FP_1;
+ break;
+
+ case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */
+ compose = 1;
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
+ /* output_gamma records the encoding of opaque pixels! */
+ break;
+
+ case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */
+ compose = 1;
+ png_ptr->transformations |= PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+ break;
+
+ default:
+ png_error(png_ptr, "invalid alpha mode");
+ }
+
+ /* Only set the default gamma if the file gamma has not been set (this has
+ * the side effect that the gamma in a second call to png_set_alpha_mode will
+ * be ignored.)
+ */
+ if (png_ptr->colorspace.gamma == 0)
+ {
+ png_ptr->colorspace.gamma = file_gamma;
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+ }
+
+ /* But always set the output gamma: */
+ png_ptr->screen_gamma = output_gamma;
+
+ /* Finally, if pre-multiplying, set the background fields to achieve the
+ * desired result.
+ */
+ if (compose != 0)
+ {
+ /* And obtain alpha pre-multiplication by composing on black: */
+ memset(&png_ptr->background, 0, (sizeof png_ptr->background));
+ png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */
+ png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
+ png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
+
+ if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+ png_error(png_ptr,
+ "conflicting calls to set alpha mode and background");
+
+ png_ptr->transformations |= PNG_COMPOSE;
+ }
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
+{
+ png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
+ output_gamma));
+}
+# endif
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+/* Dither file to 8-bit. Supply a palette, the current number
+ * of elements in the palette, the maximum number of elements
+ * allowed, and a histogram if possible. If the current number
+ * of colors is greater than the maximum number, the palette will be
+ * modified to fit in the maximum number. "full_quantize" indicates
+ * whether we need a quantizing cube set up for RGB images, or if we
+ * simply are reducing the number of colors in a paletted image.
+ */
+
+typedef struct png_dsort_struct
+{
+ struct png_dsort_struct * next;
+ png_byte left;
+ png_byte right;
+} png_dsort;
+typedef png_dsort * png_dsortp;
+typedef png_dsort * * png_dsortpp;
+
+void PNGAPI
+png_set_quantize(png_structrp png_ptr, png_colorp palette,
+ int num_palette, int maximum_colors, png_const_uint_16p histogram,
+ int full_quantize)
+{
+ png_debug(1, "in png_set_quantize");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ png_ptr->transformations |= PNG_QUANTIZE;
+
+ if (full_quantize == 0)
+ {
+ int i;
+
+ png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
+ (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
+ for (i = 0; i < num_palette; i++)
+ png_ptr->quantize_index[i] = (png_byte)i;
+ }
+
+ if (num_palette > maximum_colors)
+ {
+ if (histogram != NULL)
+ {
+ /* This is easy enough, just throw out the least used colors.
+ * Perhaps not the best solution, but good enough.
+ */
+
+ int i;
+
+ /* Initialize an array to sort colors */
+ png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
+ (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
+
+ /* Initialize the quantize_sort array */
+ for (i = 0; i < num_palette; i++)
+ png_ptr->quantize_sort[i] = (png_byte)i;
+
+ /* Find the least used palette entries by starting a
+ * bubble sort, and running it until we have sorted
+ * out enough colors. Note that we don't care about
+ * sorting all the colors, just finding which are
+ * least used.
+ */
+
+ for (i = num_palette - 1; i >= maximum_colors; i--)
+ {
+ int done; /* To stop early if the list is pre-sorted */
+ int j;
+
+ done = 1;
+ for (j = 0; j < i; j++)
+ {
+ if (histogram[png_ptr->quantize_sort[j]]
+ < histogram[png_ptr->quantize_sort[j + 1]])
+ {
+ png_byte t;
+
+ t = png_ptr->quantize_sort[j];
+ png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
+ png_ptr->quantize_sort[j + 1] = t;
+ done = 0;
+ }
+ }
+
+ if (done != 0)
+ break;
+ }
+
+ /* Swap the palette around, and set up a table, if necessary */
+ if (full_quantize != 0)
+ {
+ int j = num_palette;
+
+ /* Put all the useful colors within the max, but don't
+ * move the others.
+ */
+ for (i = 0; i < maximum_colors; i++)
+ {
+ if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
+ {
+ do
+ j--;
+ while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
+
+ palette[i] = palette[j];
+ }
+ }
+ }
+ else
+ {
+ int j = num_palette;
+
+ /* Move all the used colors inside the max limit, and
+ * develop a translation table.
+ */
+ for (i = 0; i < maximum_colors; i++)
+ {
+ /* Only move the colors we need to */
+ if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
+ {
+ png_color tmp_color;
+
+ do
+ j--;
+ while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
+
+ tmp_color = palette[j];
+ palette[j] = palette[i];
+ palette[i] = tmp_color;
+ /* Indicate where the color went */
+ png_ptr->quantize_index[j] = (png_byte)i;
+ png_ptr->quantize_index[i] = (png_byte)j;
+ }
+ }
+
+ /* Find closest color for those colors we are not using */
+ for (i = 0; i < num_palette; i++)
+ {
+ if ((int)png_ptr->quantize_index[i] >= maximum_colors)
+ {
+ int min_d, k, min_k, d_index;
+
+ /* Find the closest color to one we threw out */
+ d_index = png_ptr->quantize_index[i];
+ min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
+ for (k = 1, min_k = 0; k < maximum_colors; k++)
+ {
+ int d;
+
+ d = PNG_COLOR_DIST(palette[d_index], palette[k]);
+
+ if (d < min_d)
+ {
+ min_d = d;
+ min_k = k;
+ }
+ }
+ /* Point to closest color */
+ png_ptr->quantize_index[i] = (png_byte)min_k;
+ }
+ }
+ }
+ png_free(png_ptr, png_ptr->quantize_sort);
+ png_ptr->quantize_sort = NULL;
+ }
+ else
+ {
+ /* This is much harder to do simply (and quickly). Perhaps
+ * we need to go through a median cut routine, but those
+ * don't always behave themselves with only a few colors
+ * as input. So we will just find the closest two colors,
+ * and throw out one of them (chosen somewhat randomly).
+ * [We don't understand this at all, so if someone wants to
+ * work on improving it, be our guest - AED, GRP]
+ */
+ int i;
+ int max_d;
+ int num_new_palette;
+ png_dsortp t;
+ png_dsortpp hash;
+
+ t = NULL;
+
+ /* Initialize palette index arrays */
+ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
+ (png_alloc_size_t)((png_uint_32)num_palette *
+ (sizeof (png_byte))));
+ png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
+ (png_alloc_size_t)((png_uint_32)num_palette *
+ (sizeof (png_byte))));
+
+ /* Initialize the sort array */
+ for (i = 0; i < num_palette; i++)
+ {
+ png_ptr->index_to_palette[i] = (png_byte)i;
+ png_ptr->palette_to_index[i] = (png_byte)i;
+ }
+
+ hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 *
+ (sizeof (png_dsortp))));
+
+ num_new_palette = num_palette;
+
+ /* Initial wild guess at how far apart the farthest pixel
+ * pair we will be eliminating will be. Larger
+ * numbers mean more areas will be allocated, Smaller
+ * numbers run the risk of not saving enough data, and
+ * having to do this all over again.
+ *
+ * I have not done extensive checking on this number.
+ */
+ max_d = 96;
+
+ while (num_new_palette > maximum_colors)
+ {
+ for (i = 0; i < num_new_palette - 1; i++)
+ {
+ int j;
+
+ for (j = i + 1; j < num_new_palette; j++)
+ {
+ int d;
+
+ d = PNG_COLOR_DIST(palette[i], palette[j]);
+
+ if (d <= max_d)
+ {
+
+ t = (png_dsortp)png_malloc_warn(png_ptr,
+ (png_alloc_size_t)(sizeof (png_dsort)));
+
+ if (t == NULL)
+ break;
+
+ t->next = hash[d];
+ t->left = (png_byte)i;
+ t->right = (png_byte)j;
+ hash[d] = t;
+ }
+ }
+ if (t == NULL)
+ break;
+ }
+
+ if (t != NULL)
+ for (i = 0; i <= max_d; i++)
+ {
+ if (hash[i] != NULL)
+ {
+ png_dsortp p;
+
+ for (p = hash[i]; p; p = p->next)
+ {
+ if ((int)png_ptr->index_to_palette[p->left]
+ < num_new_palette &&
+ (int)png_ptr->index_to_palette[p->right]
+ < num_new_palette)
+ {
+ int j, next_j;
+
+ if (num_new_palette & 0x01)
+ {
+ j = p->left;
+ next_j = p->right;
+ }
+ else
+ {
+ j = p->right;
+ next_j = p->left;
+ }
+
+ num_new_palette--;
+ palette[png_ptr->index_to_palette[j]]
+ = palette[num_new_palette];
+ if (full_quantize == 0)
+ {
+ int k;
+
+ for (k = 0; k < num_palette; k++)
+ {
+ if (png_ptr->quantize_index[k] ==
+ png_ptr->index_to_palette[j])
+ png_ptr->quantize_index[k] =
+ png_ptr->index_to_palette[next_j];
+
+ if ((int)png_ptr->quantize_index[k] ==
+ num_new_palette)
+ png_ptr->quantize_index[k] =
+ png_ptr->index_to_palette[j];
+ }
+ }
+
+ png_ptr->index_to_palette[png_ptr->palette_to_index
+ [num_new_palette]] = png_ptr->index_to_palette[j];
+
+ png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
+ = png_ptr->palette_to_index[num_new_palette];
+
+ png_ptr->index_to_palette[j] =
+ (png_byte)num_new_palette;
+
+ png_ptr->palette_to_index[num_new_palette] =
+ (png_byte)j;
+ }
+ if (num_new_palette <= maximum_colors)
+ break;
+ }
+ if (num_new_palette <= maximum_colors)
+ break;
+ }
+ }
+
+ for (i = 0; i < 769; i++)
+ {
+ if (hash[i] != NULL)
+ {
+ png_dsortp p = hash[i];
+ while (p)
+ {
+ t = p->next;
+ png_free(png_ptr, p);
+ p = t;
+ }
+ }
+ hash[i] = 0;
+ }
+ max_d += 96;
+ }
+ png_free(png_ptr, hash);
+ png_free(png_ptr, png_ptr->palette_to_index);
+ png_free(png_ptr, png_ptr->index_to_palette);
+ png_ptr->palette_to_index = NULL;
+ png_ptr->index_to_palette = NULL;
+ }
+ num_palette = maximum_colors;
+ }
+ if (png_ptr->palette == NULL)
+ {
+ png_ptr->palette = palette;
+ }
+ png_ptr->num_palette = (png_uint_16)num_palette;
+
+ if (full_quantize != 0)
+ {
+ int i;
+ png_bytep distance;
+ int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
+ PNG_QUANTIZE_BLUE_BITS;
+ int num_red = (1 << PNG_QUANTIZE_RED_BITS);
+ int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
+ int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
+ png_size_t num_entries = ((png_size_t)1 << total_bits);
+
+ png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
+ (png_alloc_size_t)(num_entries * (sizeof (png_byte))));
+
+ distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries *
+ (sizeof (png_byte))));
+
+ memset(distance, 0xff, num_entries * (sizeof (png_byte)));
+
+ for (i = 0; i < num_palette; i++)
+ {
+ int ir, ig, ib;
+ int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
+ int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
+ int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
+
+ for (ir = 0; ir < num_red; ir++)
+ {
+ /* int dr = abs(ir - r); */
+ int dr = ((ir > r) ? ir - r : r - ir);
+ int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
+ PNG_QUANTIZE_GREEN_BITS));
+
+ for (ig = 0; ig < num_green; ig++)
+ {
+ /* int dg = abs(ig - g); */
+ int dg = ((ig > g) ? ig - g : g - ig);
+ int dt = dr + dg;
+ int dm = ((dr > dg) ? dr : dg);
+ int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
+
+ for (ib = 0; ib < num_blue; ib++)
+ {
+ int d_index = index_g | ib;
+ /* int db = abs(ib - b); */
+ int db = ((ib > b) ? ib - b : b - ib);
+ int dmax = ((dm > db) ? dm : db);
+ int d = dmax + dt + db;
+
+ if (d < (int)distance[d_index])
+ {
+ distance[d_index] = (png_byte)d;
+ png_ptr->palette_lookup[d_index] = (png_byte)i;
+ }
+ }
+ }
+ }
+ }
+
+ png_free(png_ptr, distance);
+ }
+}
+#endif /* READ_QUANTIZE */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+void PNGFAPI
+png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
+ png_fixed_point file_gamma)
+{
+ png_debug(1, "in png_set_gamma_fixed");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ /* New in libpng-1.5.4 - reserve particular negative values as flags. */
+ scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
+ file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
+
+ /* Checking the gamma values for being >0 was added in 1.5.4 along with the
+ * premultiplied alpha support; this actually hides an undocumented feature
+ * of the previous implementation which allowed gamma processing to be
+ * disabled in background handling. There is no evidence (so far) that this
+ * was being used; however, png_set_background itself accepted and must still
+ * accept '0' for the gamma value it takes, because it isn't always used.
+ *
+ * Since this is an API change (albeit a very minor one that removes an
+ * undocumented API feature) the following checks were only enabled in
+ * libpng-1.6.0.
+ */
+ if (file_gamma <= 0)
+ png_error(png_ptr, "invalid file gamma in png_set_gamma");
+
+ if (scrn_gamma <= 0)
+ png_error(png_ptr, "invalid screen gamma in png_set_gamma");
+
+ /* Set the gamma values unconditionally - this overrides the value in the PNG
+ * file if a gAMA chunk was present. png_set_alpha_mode provides a
+ * different, easier, way to default the file gamma.
+ */
+ png_ptr->colorspace.gamma = file_gamma;
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+ png_ptr->screen_gamma = scrn_gamma;
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
+{
+ png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
+ convert_gamma_value(png_ptr, file_gamma));
+}
+# endif /* FLOATING_POINT */
+#endif /* READ_GAMMA */
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expand paletted images to RGB, expand grayscale images of
+ * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
+ * to alpha channels.
+ */
+void PNGAPI
+png_set_expand(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_expand");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+
+/* GRR 19990627: the following three functions currently are identical
+ * to png_set_expand(). However, it is entirely reasonable that someone
+ * might wish to expand an indexed image to RGB but *not* expand a single,
+ * fully transparent palette entry to a full alpha channel--perhaps instead
+ * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
+ * the transparent color with a particular RGB value, or drop tRNS entirely.
+ * IOW, a future version of the library may make the transformations flag
+ * a bit more fine-grained, with separate bits for each of these three
+ * functions.
+ *
+ * More to the point, these functions make it obvious what libpng will be
+ * doing, whereas "expand" can (and does) mean any number of things.
+ *
+ * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
+ * to expand only the sample depth but not to expand the tRNS to alpha
+ * and its name was changed to png_set_expand_gray_1_2_4_to_8().
+ */
+
+/* Expand paletted images to RGB. */
+void PNGAPI
+png_set_palette_to_rgb(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_palette_to_rgb");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+void PNGAPI
+png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* Expand tRNS chunks to alpha channels. */
+void PNGAPI
+png_set_tRNS_to_alpha(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_tRNS_to_alpha");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+#endif /* READ_EXPAND */
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise
+ * it may not work correctly.)
+ */
+void PNGAPI
+png_set_expand_16(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_expand_16");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+void PNGAPI
+png_set_gray_to_rgb(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_gray_to_rgb");
+
+ if (png_rtran_ok(png_ptr, 0) == 0)
+ return;
+
+ /* Because rgb must be 8 bits or more: */
+ png_set_expand_gray_1_2_4_to_8(png_ptr);
+ png_ptr->transformations |= PNG_GRAY_TO_RGB;
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+void PNGFAPI
+png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
+ png_fixed_point red, png_fixed_point green)
+{
+ png_debug(1, "in png_set_rgb_to_gray");
+
+ /* Need the IHDR here because of the check on color_type below. */
+ /* TODO: fix this */
+ if (png_rtran_ok(png_ptr, 1) == 0)
+ return;
+
+ switch (error_action)
+ {
+ case PNG_ERROR_ACTION_NONE:
+ png_ptr->transformations |= PNG_RGB_TO_GRAY;
+ break;
+
+ case PNG_ERROR_ACTION_WARN:
+ png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
+ break;
+
+ case PNG_ERROR_ACTION_ERROR:
+ png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
+ break;
+
+ default:
+ png_error(png_ptr, "invalid error action to rgb_to_gray");
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ png_ptr->transformations |= PNG_EXPAND;
+#else
+ {
+ /* Make this an error in 1.6 because otherwise the application may assume
+ * that it just worked and get a memory overwrite.
+ */
+ png_error(png_ptr,
+ "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
+
+ /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
+ }
+#endif
+ {
+ if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
+ {
+ png_uint_16 red_int, green_int;
+
+ /* NOTE: this calculation does not round, but this behavior is retained
+ * for consistency; the inaccuracy is very small. The code here always
+ * overwrites the coefficients, regardless of whether they have been
+ * defaulted or set already.
+ */
+ red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
+ green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
+
+ png_ptr->rgb_to_gray_red_coeff = red_int;
+ png_ptr->rgb_to_gray_green_coeff = green_int;
+ png_ptr->rgb_to_gray_coefficients_set = 1;
+ }
+
+ else
+ {
+ if (red >= 0 && green >= 0)
+ png_app_warning(png_ptr,
+ "ignoring out of range rgb_to_gray coefficients");
+
+ /* Use the defaults, from the cHRM chunk if set, else the historical
+ * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See
+ * png_do_rgb_to_gray for more discussion of the values. In this case
+ * the coefficients are not marked as 'set' and are not overwritten if
+ * something has already provided a default.
+ */
+ if (png_ptr->rgb_to_gray_red_coeff == 0 &&
+ png_ptr->rgb_to_gray_green_coeff == 0)
+ {
+ png_ptr->rgb_to_gray_red_coeff = 6968;
+ png_ptr->rgb_to_gray_green_coeff = 23434;
+ /* png_ptr->rgb_to_gray_blue_coeff = 2366; */
+ }
+ }
+ }
+}
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+/* Convert a RGB image to a grayscale of the same width. This allows us,
+ * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
+ */
+
+void PNGAPI
+png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
+ double green)
+{
+ png_set_rgb_to_gray_fixed(png_ptr, error_action,
+ png_fixed(png_ptr, red, "rgb to gray red coefficient"),
+ png_fixed(png_ptr, green, "rgb to gray green coefficient"));
+}
+#endif /* FLOATING POINT */
+
+#endif /* RGB_TO_GRAY */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void PNGAPI
+png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
+ read_user_transform_fn)
+{
+ png_debug(1, "in png_set_read_user_transform_fn");
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ png_ptr->transformations |= PNG_USER_TRANSFORM;
+ png_ptr->read_user_transform_fn = read_user_transform_fn;
+#endif
+}
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* In the case of gamma transformations only do transformations on images where
+ * the [file] gamma and screen_gamma are not close reciprocals, otherwise it
+ * slows things down slightly, and also needlessly introduces small errors.
+ */
+static int /* PRIVATE */
+png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
+{
+ /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
+ * correction as a difference of the overall transform from 1.0
+ *
+ * We want to compare the threshold with s*f - 1, if we get
+ * overflow here it is because of wacky gamma values so we
+ * turn on processing anyway.
+ */
+ png_fixed_point gtest;
+ return !png_muldiv(&gtest, screen_gamma, file_gamma, PNG_FP_1) ||
+ png_gamma_significant(gtest);
+}
+#endif
+
+/* Initialize everything needed for the read. This includes modifying
+ * the palette.
+ */
+
+/* For the moment 'png_init_palette_transformations' and
+ * 'png_init_rgb_transformations' only do some flag canceling optimizations.
+ * The intent is that these two routines should have palette or rgb operations
+ * extracted from 'png_init_read_transformations'.
+ */
+static void /* PRIVATE */
+png_init_palette_transformations(png_structrp png_ptr)
+{
+ /* Called to handle the (input) palette case. In png_do_read_transformations
+ * the first step is to expand the palette if requested, so this code must
+ * take care to only make changes that are invariant with respect to the
+ * palette expansion, or only do them if there is no expansion.
+ *
+ * STRIP_ALPHA has already been handled in the caller (by setting num_trans
+ * to 0.)
+ */
+ int input_has_alpha = 0;
+ int input_has_transparency = 0;
+
+ if (png_ptr->num_trans > 0)
+ {
+ int i;
+
+ /* Ignore if all the entries are opaque (unlikely!) */
+ for (i=0; i<png_ptr->num_trans; ++i)
+ {
+ if (png_ptr->trans_alpha[i] == 255)
+ continue;
+ else if (png_ptr->trans_alpha[i] == 0)
+ input_has_transparency = 1;
+ else
+ {
+ input_has_transparency = 1;
+ input_has_alpha = 1;
+ break;
+ }
+ }
+ }
+
+ /* If no alpha we can optimize. */
+ if (input_has_alpha == 0)
+ {
+ /* Any alpha means background and associative alpha processing is
+ * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
+ * and ENCODE_ALPHA are irrelevant.
+ */
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+
+ if (input_has_transparency == 0)
+ png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
+ }
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* png_set_background handling - deals with the complexity of whether the
+ * background color is in the file format or the screen format in the case
+ * where an 'expand' will happen.
+ */
+
+ /* The following code cannot be entered in the alpha pre-multiplication case
+ * because PNG_BACKGROUND_EXPAND is cancelled below.
+ */
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
+ (png_ptr->transformations & PNG_EXPAND) != 0)
+ {
+ {
+ png_ptr->background.red =
+ png_ptr->palette[png_ptr->background.index].red;
+ png_ptr->background.green =
+ png_ptr->palette[png_ptr->background.index].green;
+ png_ptr->background.blue =
+ png_ptr->palette[png_ptr->background.index].blue;
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
+ {
+ if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
+ {
+ /* Invert the alpha channel (in tRNS) unless the pixels are
+ * going to be expanded, in which case leave it for later
+ */
+ int i, istop = png_ptr->num_trans;
+
+ for (i=0; i<istop; i++)
+ png_ptr->trans_alpha[i] = (png_byte)(255 -
+ png_ptr->trans_alpha[i]);
+ }
+ }
+#endif /* READ_INVERT_ALPHA */
+ }
+ } /* background expand and (therefore) no alpha association. */
+#endif /* READ_EXPAND && READ_BACKGROUND */
+}
+
+static void /* PRIVATE */
+png_init_rgb_transformations(png_structrp png_ptr)
+{
+ /* Added to libpng-1.5.4: check the color type to determine whether there
+ * is any alpha or transparency in the image and simply cancel the
+ * background and alpha mode stuff if there isn't.
+ */
+ int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
+ int input_has_transparency = png_ptr->num_trans > 0;
+
+ /* If no alpha we can optimize. */
+ if (input_has_alpha == 0)
+ {
+ /* Any alpha means background and associative alpha processing is
+ * required, however if the alpha is 0 or 1 throughout OPTIMIZE_ALPHA
+ * and ENCODE_ALPHA are irrelevant.
+ */
+# ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+# endif
+
+ if (input_has_transparency == 0)
+ png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
+ }
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* png_set_background handling - deals with the complexity of whether the
+ * background color is in the file format or the screen format in the case
+ * where an 'expand' will happen.
+ */
+
+ /* The following code cannot be entered in the alpha pre-multiplication case
+ * because PNG_BACKGROUND_EXPAND is cancelled below.
+ */
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0 &&
+ (png_ptr->transformations & PNG_EXPAND) != 0 &&
+ (png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+ /* i.e., GRAY or GRAY_ALPHA */
+ {
+ {
+ /* Expand background and tRNS chunks */
+ int gray = png_ptr->background.gray;
+ int trans_gray = png_ptr->trans_color.gray;
+
+ switch (png_ptr->bit_depth)
+ {
+ case 1:
+ gray *= 0xff;
+ trans_gray *= 0xff;
+ break;
+
+ case 2:
+ gray *= 0x55;
+ trans_gray *= 0x55;
+ break;
+
+ case 4:
+ gray *= 0x11;
+ trans_gray *= 0x11;
+ break;
+
+ default:
+
+ case 8:
+ /* FALLTHROUGH */ /* (Already 8 bits) */
+
+ case 16:
+ /* Already a full 16 bits */
+ break;
+ }
+
+ png_ptr->background.red = png_ptr->background.green =
+ png_ptr->background.blue = (png_uint_16)gray;
+
+ if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0)
+ {
+ png_ptr->trans_color.red = png_ptr->trans_color.green =
+ png_ptr->trans_color.blue = (png_uint_16)trans_gray;
+ }
+ }
+ } /* background expand and (therefore) no alpha association. */
+#endif /* READ_EXPAND && READ_BACKGROUND */
+}
+
+void /* PRIVATE */
+png_init_read_transformations(png_structrp png_ptr)
+{
+ png_debug(1, "in png_init_read_transformations");
+
+ /* This internal function is called from png_read_start_row in pngrutil.c
+ * and it is called before the 'rowbytes' calculation is done, so the code
+ * in here can change or update the transformations flags.
+ *
+ * First do updates that do not depend on the details of the PNG image data
+ * being processed.
+ */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
+ * png_set_alpha_mode and this is another source for a default file gamma so
+ * the test needs to be performed later - here. In addition prior to 1.5.4
+ * the tests were repeated for the PALETTE color type here - this is no
+ * longer necessary (and doesn't seem to have been necessary before.)
+ */
+ {
+ /* The following temporary indicates if overall gamma correction is
+ * required.
+ */
+ int gamma_correction = 0;
+
+ if (png_ptr->colorspace.gamma != 0) /* has been set */
+ {
+ if (png_ptr->screen_gamma != 0) /* screen set too */
+ gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma);
+
+ else
+ /* Assume the output matches the input; a long time default behavior
+ * of libpng, although the standard has nothing to say about this.
+ */
+ png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);
+ }
+
+ else if (png_ptr->screen_gamma != 0)
+ /* The converse - assume the file matches the screen, note that this
+ * perhaps undesireable default can (from 1.5.4) be changed by calling
+ * png_set_alpha_mode (even if the alpha handling mode isn't required
+ * or isn't changed from the default.)
+ */
+ png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);
+
+ else /* neither are set */
+ /* Just in case the following prevents any processing - file and screen
+ * are both assumed to be linear and there is no way to introduce a
+ * third gamma value other than png_set_background with 'UNIQUE', and,
+ * prior to 1.5.4
+ */
+ png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;
+
+ /* We have a gamma value now. */
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+
+ /* Now turn the gamma transformation on or off as appropriate. Notice
+ * that PNG_GAMMA just refers to the file->screen correction. Alpha
+ * composition may independently cause gamma correction because it needs
+ * linear data (e.g. if the file has a gAMA chunk but the screen gamma
+ * hasn't been specified.) In any case this flag may get turned off in
+ * the code immediately below if the transform can be handled outside the
+ * row loop.
+ */
+ if (gamma_correction != 0)
+ png_ptr->transformations |= PNG_GAMMA;
+
+ else
+ png_ptr->transformations &= ~PNG_GAMMA;
+ }
+#endif
+
+ /* Certain transformations have the effect of preventing other
+ * transformations that happen afterward in png_do_read_transformations;
+ * resolve the interdependencies here. From the code of
+ * png_do_read_transformations the order is:
+ *
+ * 1) PNG_EXPAND (including PNG_EXPAND_tRNS)
+ * 2) PNG_STRIP_ALPHA (if no compose)
+ * 3) PNG_RGB_TO_GRAY
+ * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
+ * 5) PNG_COMPOSE
+ * 6) PNG_GAMMA
+ * 7) PNG_STRIP_ALPHA (if compose)
+ * 8) PNG_ENCODE_ALPHA
+ * 9) PNG_SCALE_16_TO_8
+ * 10) PNG_16_TO_8
+ * 11) PNG_QUANTIZE (converts to palette)
+ * 12) PNG_EXPAND_16
+ * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
+ * 14) PNG_INVERT_MONO
+ * 15) PNG_INVERT_ALPHA
+ * 16) PNG_SHIFT
+ * 17) PNG_PACK
+ * 18) PNG_BGR
+ * 19) PNG_PACKSWAP
+ * 20) PNG_FILLER (includes PNG_ADD_ALPHA)
+ * 21) PNG_SWAP_ALPHA
+ * 22) PNG_SWAP_BYTES
+ * 23) PNG_USER_TRANSFORM [must be last]
+ */
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
+ (png_ptr->transformations & PNG_COMPOSE) == 0)
+ {
+ /* Stripping the alpha channel happens immediately after the 'expand'
+ * transformations, before all other transformation, so it cancels out
+ * the alpha handling. It has the side effect negating the effect of
+ * PNG_EXPAND_tRNS too:
+ */
+ png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
+ PNG_EXPAND_tRNS);
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+
+ /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen
+ * so transparency information would remain just so long as it wasn't
+ * expanded. This produces unexpected API changes if the set of things
+ * that do PNG_EXPAND_tRNS changes (perfectly possible given the
+ * documentation - which says ask for what you want, accept what you
+ * get.) This makes the behavior consistent from 1.5.4:
+ */
+ png_ptr->num_trans = 0;
+ }
+#endif /* STRIP_ALPHA supported, no COMPOSE */
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+ /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
+ * settings will have no effect.
+ */
+ if (png_gamma_significant(png_ptr->screen_gamma) == 0)
+ {
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+ }
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ /* Make sure the coefficients for the rgb to gray conversion are set
+ * appropriately.
+ */
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
+ png_colorspace_set_rgb_coefficients(png_ptr);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* Detect gray background and attempt to enable optimization for
+ * gray --> RGB case.
+ *
+ * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
+ * RGB_ALPHA (in which case need_expand is superfluous anyway), the
+ * background color might actually be gray yet not be flagged as such.
+ * This is not a problem for the current code, which uses
+ * PNG_BACKGROUND_IS_GRAY only to decide when to do the
+ * png_do_gray_to_rgb() transformation.
+ *
+ * TODO: this code needs to be revised to avoid the complexity and
+ * interdependencies. The color type of the background should be recorded in
+ * png_set_background, along with the bit depth, then the code has a record
+ * of exactly what color space the background is currently in.
+ */
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) != 0)
+ {
+ /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
+ * the file was grayscale the background value is gray.
+ */
+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+ png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+ }
+
+ else if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+ {
+ /* PNG_COMPOSE: png_set_background was called with need_expand false,
+ * so the color is in the color space of the output or png_set_alpha_mode
+ * was called and the color is black. Ignore RGB_TO_GRAY because that
+ * happens before GRAY_TO_RGB.
+ */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
+ {
+ if (png_ptr->background.red == png_ptr->background.green &&
+ png_ptr->background.red == png_ptr->background.blue)
+ {
+ png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+ png_ptr->background.gray = png_ptr->background.red;
+ }
+ }
+ }
+#endif /* READ_EXPAND && READ_BACKGROUND */
+#endif /* READ_GRAY_TO_RGB */
+
+ /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations
+ * can be performed directly on the palette, and some (such as rgb to gray)
+ * can be optimized inside the palette. This is particularly true of the
+ * composite (background and alpha) stuff, which can be pretty much all done
+ * in the palette even if the result is expanded to RGB or gray afterward.
+ *
+ * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
+ * earlier and the palette stuff is actually handled on the first row. This
+ * leads to the reported bug that the palette returned by png_get_PLTE is not
+ * updated.
+ */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_init_palette_transformations(png_ptr);
+
+ else
+ png_init_rgb_transformations(png_ptr);
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+ defined(PNG_READ_EXPAND_16_SUPPORTED)
+ if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
+ (png_ptr->transformations & PNG_COMPOSE) != 0 &&
+ (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
+ png_ptr->bit_depth != 16)
+ {
+ /* TODO: fix this. Because the expand_16 operation is after the compose
+ * handling the background color must be 8, not 16, bits deep, but the
+ * application will supply a 16-bit value so reduce it here.
+ *
+ * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
+ * present, so that case is ok (until do_expand_16 is moved.)
+ *
+ * NOTE: this discards the low 16 bits of the user supplied background
+ * color, but until expand_16 works properly there is no choice!
+ */
+# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))
+ CHOP(png_ptr->background.red);
+ CHOP(png_ptr->background.green);
+ CHOP(png_ptr->background.blue);
+ CHOP(png_ptr->background.gray);
+# undef CHOP
+ }
+#endif /* READ_BACKGROUND && READ_EXPAND_16 */
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+ (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
+ defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
+ if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) != 0 &&
+ (png_ptr->transformations & PNG_COMPOSE) != 0 &&
+ (png_ptr->transformations & PNG_BACKGROUND_EXPAND) == 0 &&
+ png_ptr->bit_depth == 16)
+ {
+ /* On the other hand, if a 16-bit file is to be reduced to 8-bits per
+ * component this will also happen after PNG_COMPOSE and so the background
+ * color must be pre-expanded here.
+ *
+ * TODO: fix this too.
+ */
+ png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);
+ png_ptr->background.green =
+ (png_uint_16)(png_ptr->background.green * 257);
+ png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);
+ png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);
+ }
+#endif
+
+ /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the
+ * background support (see the comments in scripts/pnglibconf.dfa), this
+ * allows pre-multiplication of the alpha channel to be implemented as
+ * compositing on black. This is probably sub-optimal and has been done in
+ * 1.5.4 betas simply to enable external critique and testing (i.e. to
+ * implement the new API quickly, without lots of internal changes.)
+ */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+# ifdef PNG_READ_BACKGROUND_SUPPORTED
+ /* Includes ALPHA_MODE */
+ png_ptr->background_1 = png_ptr->background;
+# endif
+
+ /* This needs to change - in the palette image case a whole set of tables are
+ * built when it would be quicker to just calculate the correct value for
+ * each palette entry directly. Also, the test is too tricky - why check
+ * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that
+ * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the
+ * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction
+ * the gamma tables will not be built even if composition is required on a
+ * gamma encoded value.
+ *
+ * In 1.5.4 this is addressed below by an additional check on the individual
+ * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
+ * tables.
+ */
+ if ((png_ptr->transformations & PNG_GAMMA) != 0 ||
+ ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0 &&
+ (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
+ png_gamma_significant(png_ptr->screen_gamma) != 0)) ||
+ ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
+ (png_gamma_significant(png_ptr->colorspace.gamma) != 0 ||
+ png_gamma_significant(png_ptr->screen_gamma) != 0
+# ifdef PNG_READ_BACKGROUND_SUPPORTED
+ || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE &&
+ png_gamma_significant(png_ptr->background_gamma) != 0)
+# endif
+ )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
+ png_gamma_significant(png_ptr->screen_gamma) != 0))
+ {
+ png_build_gamma_table(png_ptr, png_ptr->bit_depth);
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+ {
+ /* Issue a warning about this combination: because RGB_TO_GRAY is
+ * optimized to do the gamma transform if present yet do_background has
+ * to do the same thing if both options are set a
+ * double-gamma-correction happens. This is true in all versions of
+ * libpng to date.
+ */
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
+ png_warning(png_ptr,
+ "libpng does not support gamma+background+rgb_to_gray");
+
+ if ((png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) != 0)
+ {
+ /* We don't get to here unless there is a tRNS chunk with non-opaque
+ * entries - see the checking code at the start of this function.
+ */
+ png_color back, back_1;
+ png_colorp palette = png_ptr->palette;
+ int num_palette = png_ptr->num_palette;
+ int i;
+ if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+ {
+
+ back.red = png_ptr->gamma_table[png_ptr->background.red];
+ back.green = png_ptr->gamma_table[png_ptr->background.green];
+ back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+ back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+ back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+ back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+ }
+ else
+ {
+ png_fixed_point g, gs;
+
+ switch (png_ptr->background_gamma_type)
+ {
+ case PNG_BACKGROUND_GAMMA_SCREEN:
+ g = (png_ptr->screen_gamma);
+ gs = PNG_FP_1;
+ break;
+
+ case PNG_BACKGROUND_GAMMA_FILE:
+ g = png_reciprocal(png_ptr->colorspace.gamma);
+ gs = png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma);
+ break;
+
+ case PNG_BACKGROUND_GAMMA_UNIQUE:
+ g = png_reciprocal(png_ptr->background_gamma);
+ gs = png_reciprocal2(png_ptr->background_gamma,
+ png_ptr->screen_gamma);
+ break;
+ default:
+ g = PNG_FP_1; /* back_1 */
+ gs = PNG_FP_1; /* back */
+ break;
+ }
+
+ if (png_gamma_significant(gs) != 0)
+ {
+ back.red = png_gamma_8bit_correct(png_ptr->background.red,
+ gs);
+ back.green = png_gamma_8bit_correct(png_ptr->background.green,
+ gs);
+ back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
+ gs);
+ }
+
+ else
+ {
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+ }
+
+ if (png_gamma_significant(g) != 0)
+ {
+ back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
+ g);
+ back_1.green = png_gamma_8bit_correct(
+ png_ptr->background.green, g);
+ back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
+ g);
+ }
+
+ else
+ {
+ back_1.red = (png_byte)png_ptr->background.red;
+ back_1.green = (png_byte)png_ptr->background.green;
+ back_1.blue = (png_byte)png_ptr->background.blue;
+ }
+ }
+
+ for (i = 0; i < num_palette; i++)
+ {
+ if (i < (int)png_ptr->num_trans &&
+ png_ptr->trans_alpha[i] != 0xff)
+ {
+ if (png_ptr->trans_alpha[i] == 0)
+ {
+ palette[i] = back;
+ }
+ else /* if (png_ptr->trans_alpha[i] != 0xff) */
+ {
+ png_byte v, w;
+
+ v = png_ptr->gamma_to_1[palette[i].red];
+ png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
+ palette[i].red = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[palette[i].green];
+ png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
+ palette[i].green = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[palette[i].blue];
+ png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
+ palette[i].blue = png_ptr->gamma_from_1[w];
+ }
+ }
+ else
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+
+ /* Prevent the transformations being done again.
+ *
+ * NOTE: this is highly dubious; it removes the transformations in
+ * place. This seems inconsistent with the general treatment of the
+ * transformations elsewhere.
+ */
+ png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
+ } /* color_type == PNG_COLOR_TYPE_PALETTE */
+
+ /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
+ else /* color_type != PNG_COLOR_TYPE_PALETTE */
+ {
+ int gs_sig, g_sig;
+ png_fixed_point g = PNG_FP_1; /* Correction to linear */
+ png_fixed_point gs = PNG_FP_1; /* Correction to screen */
+
+ switch (png_ptr->background_gamma_type)
+ {
+ case PNG_BACKGROUND_GAMMA_SCREEN:
+ g = png_ptr->screen_gamma;
+ /* gs = PNG_FP_1; */
+ break;
+
+ case PNG_BACKGROUND_GAMMA_FILE:
+ g = png_reciprocal(png_ptr->colorspace.gamma);
+ gs = png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma);
+ break;
+
+ case PNG_BACKGROUND_GAMMA_UNIQUE:
+ g = png_reciprocal(png_ptr->background_gamma);
+ gs = png_reciprocal2(png_ptr->background_gamma,
+ png_ptr->screen_gamma);
+ break;
+
+ default:
+ png_error(png_ptr, "invalid background gamma type");
+ }
+
+ g_sig = png_gamma_significant(g);
+ gs_sig = png_gamma_significant(gs);
+
+ if (g_sig != 0)
+ png_ptr->background_1.gray = png_gamma_correct(png_ptr,
+ png_ptr->background.gray, g);
+
+ if (gs_sig != 0)
+ png_ptr->background.gray = png_gamma_correct(png_ptr,
+ png_ptr->background.gray, gs);
+
+ if ((png_ptr->background.red != png_ptr->background.green) ||
+ (png_ptr->background.red != png_ptr->background.blue) ||
+ (png_ptr->background.red != png_ptr->background.gray))
+ {
+ /* RGB or RGBA with color background */
+ if (g_sig != 0)
+ {
+ png_ptr->background_1.red = png_gamma_correct(png_ptr,
+ png_ptr->background.red, g);
+
+ png_ptr->background_1.green = png_gamma_correct(png_ptr,
+ png_ptr->background.green, g);
+
+ png_ptr->background_1.blue = png_gamma_correct(png_ptr,
+ png_ptr->background.blue, g);
+ }
+
+ if (gs_sig != 0)
+ {
+ png_ptr->background.red = png_gamma_correct(png_ptr,
+ png_ptr->background.red, gs);
+
+ png_ptr->background.green = png_gamma_correct(png_ptr,
+ png_ptr->background.green, gs);
+
+ png_ptr->background.blue = png_gamma_correct(png_ptr,
+ png_ptr->background.blue, gs);
+ }
+ }
+
+ else
+ {
+ /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
+ png_ptr->background_1.red = png_ptr->background_1.green
+ = png_ptr->background_1.blue = png_ptr->background_1.gray;
+
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ }
+
+ /* The background is now in screen gamma: */
+ png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
+ } /* color_type != PNG_COLOR_TYPE_PALETTE */
+ }/* png_ptr->transformations & PNG_BACKGROUND */
+
+ else
+ /* Transformation does not include PNG_BACKGROUND */
+#endif /* READ_BACKGROUND */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ /* RGB_TO_GRAY needs to have non-gamma-corrected values! */
+ && ((png_ptr->transformations & PNG_EXPAND) == 0 ||
+ (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
+#endif
+ )
+ {
+ png_colorp palette = png_ptr->palette;
+ int num_palette = png_ptr->num_palette;
+ int i;
+
+ /* NOTE: there are other transformations that should probably be in
+ * here too.
+ */
+ for (i = 0; i < num_palette; i++)
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+
+ /* Done the gamma correction. */
+ png_ptr->transformations &= ~PNG_GAMMA;
+ } /* color_type == PALETTE && !PNG_BACKGROUND transformation */
+ }
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ else
+#endif
+#endif /* READ_GAMMA */
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ /* No GAMMA transformation (see the hanging else 4 lines above) */
+ if ((png_ptr->transformations & PNG_COMPOSE) != 0 &&
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
+ {
+ int i;
+ int istop = (int)png_ptr->num_trans;
+ png_color back;
+ png_colorp palette = png_ptr->palette;
+
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+
+ for (i = 0; i < istop; i++)
+ {
+ if (png_ptr->trans_alpha[i] == 0)
+ {
+ palette[i] = back;
+ }
+
+ else if (png_ptr->trans_alpha[i] != 0xff)
+ {
+ /* The png_composite() macro is defined in png.h */
+ png_composite(palette[i].red, palette[i].red,
+ png_ptr->trans_alpha[i], back.red);
+
+ png_composite(palette[i].green, palette[i].green,
+ png_ptr->trans_alpha[i], back.green);
+
+ png_composite(palette[i].blue, palette[i].blue,
+ png_ptr->trans_alpha[i], back.blue);
+ }
+ }
+
+ png_ptr->transformations &= ~PNG_COMPOSE;
+ }
+#endif /* READ_BACKGROUND */
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ if ((png_ptr->transformations & PNG_SHIFT) != 0 &&
+ (png_ptr->transformations & PNG_EXPAND) == 0 &&
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
+ {
+ int i;
+ int istop = png_ptr->num_palette;
+ int shift = 8 - png_ptr->sig_bit.red;
+
+ png_ptr->transformations &= ~PNG_SHIFT;
+
+ /* significant bits can be in the range 1 to 7 for a meaninful result, if
+ * the number of significant bits is 0 then no shift is done (this is an
+ * error condition which is silently ignored.)
+ */
+ if (shift > 0 && shift < 8)
+ for (i=0; i<istop; ++i)
+ {
+ int component = png_ptr->palette[i].red;
+
+ component >>= shift;
+ png_ptr->palette[i].red = (png_byte)component;
+ }
+
+ shift = 8 - png_ptr->sig_bit.green;
+ if (shift > 0 && shift < 8)
+ for (i=0; i<istop; ++i)
+ {
+ int component = png_ptr->palette[i].green;
+
+ component >>= shift;
+ png_ptr->palette[i].green = (png_byte)component;
+ }
+
+ shift = 8 - png_ptr->sig_bit.blue;
+ if (shift > 0 && shift < 8)
+ for (i=0; i<istop; ++i)
+ {
+ int component = png_ptr->palette[i].blue;
+
+ component >>= shift;
+ png_ptr->palette[i].blue = (png_byte)component;
+ }
+ }
+#endif /* READ_SHIFT */
+}
+
+/* Modify the info structure to reflect the transformations. The
+ * info should be updated so a PNG file could be written with it,
+ * assuming the transformations result in valid PNG data.
+ */
+void /* PRIVATE */
+png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_debug(1, "in png_read_transform_info");
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ if ((png_ptr->transformations & PNG_EXPAND) != 0)
+ {
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ /* This check must match what actually happens in
+ * png_do_expand_palette; if it ever checks the tRNS chunk to see if
+ * it is all opaque we must do the same (at present it does not.)
+ */
+ if (png_ptr->num_trans > 0)
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+
+ else
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+
+ info_ptr->bit_depth = 8;
+ info_ptr->num_trans = 0;
+
+ if (png_ptr->palette == NULL)
+ png_error (png_ptr, "Palette is NULL in indexed image");
+ }
+ else
+ {
+ if (png_ptr->num_trans != 0)
+ {
+ if ((png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
+ info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+ }
+ if (info_ptr->bit_depth < 8)
+ info_ptr->bit_depth = 8;
+
+ info_ptr->num_trans = 0;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+ /* The following is almost certainly wrong unless the background value is in
+ * the screen space!
+ */
+ if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+ info_ptr->background = png_ptr->background;
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),
+ * however it seems that the code in png_init_read_transformations, which has
+ * been called before this from png_read_update_info->png_read_start_row
+ * sometimes does the gamma transform and cancels the flag.
+ *
+ * TODO: this looks wrong; the info_ptr should end up with a gamma equal to
+ * the screen_gamma value. The following probably results in weirdness if
+ * the info_ptr is used by the app after the rows have been read.
+ */
+ info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;
+#endif
+
+ if (info_ptr->bit_depth == 16)
+ {
+# ifdef PNG_READ_16BIT_SUPPORTED
+# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
+ info_ptr->bit_depth = 8;
+# endif
+
+# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ if ((png_ptr->transformations & PNG_16_TO_8) != 0)
+ info_ptr->bit_depth = 8;
+# endif
+
+# else
+ /* No 16-bit support: force chopping 16-bit input down to 8, in this case
+ * the app program can chose if both APIs are available by setting the
+ * correct scaling to use.
+ */
+# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ /* For compatibility with previous versions use the strip method by
+ * default. This code works because if PNG_SCALE_16_TO_8 is already
+ * set the code below will do that in preference to the chop.
+ */
+ png_ptr->transformations |= PNG_16_TO_8;
+ info_ptr->bit_depth = 8;
+# else
+
+# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ png_ptr->transformations |= PNG_SCALE_16_TO_8;
+ info_ptr->bit_depth = 8;
+# else
+
+ CONFIGURATION ERROR: you must enable at least one 16 to 8 method
+# endif
+# endif
+#endif /* !READ_16BIT */
+ }
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
+ info_ptr->color_type = (png_byte)(info_ptr->color_type |
+ PNG_COLOR_MASK_COLOR);
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
+ info_ptr->color_type = (png_byte)(info_ptr->color_type &
+ ~PNG_COLOR_MASK_COLOR);
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+ if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
+ {
+ if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
+ png_ptr->palette_lookup != 0 && info_ptr->bit_depth == 8)
+ {
+ info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+ }
+ }
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ if ((png_ptr->transformations & PNG_EXPAND_16) != 0 &&
+ info_ptr->bit_depth == 8 &&
+ info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ info_ptr->bit_depth = 16;
+ }
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACK) != 0 &&
+ (info_ptr->bit_depth < 8))
+ info_ptr->bit_depth = 8;
+#endif
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ info_ptr->channels = 1;
+
+ else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ info_ptr->channels = 3;
+
+ else
+ info_ptr->channels = 1;
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0)
+ {
+ info_ptr->color_type = (png_byte)(info_ptr->color_type &
+ ~PNG_COLOR_MASK_ALPHA);
+ info_ptr->num_trans = 0;
+ }
+#endif
+
+ if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ info_ptr->channels++;
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+ /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
+ if ((png_ptr->transformations & PNG_FILLER) != 0 &&
+ (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
+ info_ptr->color_type == PNG_COLOR_TYPE_GRAY))
+ {
+ info_ptr->channels++;
+ /* If adding a true alpha channel not just filler */
+ if ((png_ptr->transformations & PNG_ADD_ALPHA) != 0)
+ info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+ }
+#endif
+
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
+defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
+ {
+ if (png_ptr->user_transform_depth != 0)
+ info_ptr->bit_depth = png_ptr->user_transform_depth;
+
+ if (png_ptr->user_transform_channels != 0)
+ info_ptr->channels = png_ptr->user_transform_channels;
+ }
+#endif
+
+ info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
+ info_ptr->bit_depth);
+
+ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
+
+ /* Adding in 1.5.4: cache the above value in png_struct so that we can later
+ * check in png_rowbytes that the user buffer won't get overwritten. Note
+ * that the field is not always set - if png_read_update_info isn't called
+ * the application has to either not do any transforms or get the calculation
+ * right itself.
+ */
+ png_ptr->info_rowbytes = info_ptr->rowbytes;
+
+#ifndef PNG_READ_EXPAND_SUPPORTED
+ if (png_ptr != NULL)
+ return;
+#endif
+}
+
+#ifdef PNG_READ_PACK_SUPPORTED
+/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
+ * without changing the actual values. Thus, if you had a row with
+ * a bit depth of 1, you would end up with bytes that only contained
+ * the numbers 0 or 1. If you would rather they contain 0 and 255, use
+ * png_do_shift() after this.
+ */
+static void
+png_do_unpack(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_unpack");
+
+ if (row_info->bit_depth < 8)
+ {
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = 7U - ((row_width + 7U) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x01);
+
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x03);
+
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x0f);
+
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift = 4;
+
+ dp--;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_width * row_info->channels;
+ }
+}
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+/* Reverse the effects of png_do_shift. This routine merely shifts the
+ * pixels back to their significant bits values. Thus, if you have
+ * a row of bit depth 8, but only 5 are significant, this will shift
+ * the values back to 0 through 31.
+ */
+static void
+png_do_unshift(png_row_infop row_info, png_bytep row,
+ png_const_color_8p sig_bits)
+{
+ int color_type;
+
+ png_debug(1, "in png_do_unshift");
+
+ /* The palette case has already been handled in the _init routine. */
+ color_type = row_info->color_type;
+
+ if (color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ int shift[4];
+ int channels = 0;
+ int bit_depth = row_info->bit_depth;
+
+ if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
+ {
+ shift[channels++] = bit_depth - sig_bits->red;
+ shift[channels++] = bit_depth - sig_bits->green;
+ shift[channels++] = bit_depth - sig_bits->blue;
+ }
+
+ else
+ {
+ shift[channels++] = bit_depth - sig_bits->gray;
+ }
+
+ if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ {
+ shift[channels++] = bit_depth - sig_bits->alpha;
+ }
+
+ {
+ int c, have_shift;
+
+ for (c = have_shift = 0; c < channels; ++c)
+ {
+ /* A shift of more than the bit depth is an error condition but it
+ * gets ignored here.
+ */
+ if (shift[c] <= 0 || shift[c] >= bit_depth)
+ shift[c] = 0;
+
+ else
+ have_shift = 1;
+ }
+
+ if (have_shift == 0)
+ return;
+ }
+
+ switch (bit_depth)
+ {
+ default:
+ /* Must be 1bpp gray: should not be here! */
+ /* NOTREACHED */
+ break;
+
+ case 2:
+ /* Must be 2bpp gray */
+ /* assert(channels == 1 && shift[0] == 1) */
+ {
+ png_bytep bp = row;
+ png_bytep bp_end = bp + row_info->rowbytes;
+
+ while (bp < bp_end)
+ {
+ int b = (*bp >> 1) & 0x55;
+ *bp++ = (png_byte)b;
+ }
+ break;
+ }
+
+ case 4:
+ /* Must be 4bpp gray */
+ /* assert(channels == 1) */
+ {
+ png_bytep bp = row;
+ png_bytep bp_end = bp + row_info->rowbytes;
+ int gray_shift = shift[0];
+ int mask = 0xf >> gray_shift;
+
+ mask |= mask << 4;
+
+ while (bp < bp_end)
+ {
+ int b = (*bp >> gray_shift) & mask;
+ *bp++ = (png_byte)b;
+ }
+ break;
+ }
+
+ case 8:
+ /* Single byte components, G, GA, RGB, RGBA */
+ {
+ png_bytep bp = row;
+ png_bytep bp_end = bp + row_info->rowbytes;
+ int channel = 0;
+
+ while (bp < bp_end)
+ {
+ int b = *bp >> shift[channel];
+ if (++channel >= channels)
+ channel = 0;
+ *bp++ = (png_byte)b;
+ }
+ break;
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ case 16:
+ /* Double byte components, G, GA, RGB, RGBA */
+ {
+ png_bytep bp = row;
+ png_bytep bp_end = bp + row_info->rowbytes;
+ int channel = 0;
+
+ while (bp < bp_end)
+ {
+ int value = (bp[0] << 8) + bp[1];
+
+ value >>= shift[channel];
+ if (++channel >= channels)
+ channel = 0;
+ *bp++ = (png_byte)(value >> 8);
+ *bp++ = (png_byte)value;
+ }
+ break;
+ }
+#endif
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+/* Scale rows of bit depth 16 down to 8 accurately */
+static void
+png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_scale_16_to_8");
+
+ if (row_info->bit_depth == 16)
+ {
+ png_bytep sp = row; /* source */
+ png_bytep dp = row; /* destination */
+ png_bytep ep = sp + row_info->rowbytes; /* end+1 */
+
+ while (sp < ep)
+ {
+ /* The input is an array of 16-bit components, these must be scaled to
+ * 8 bits each. For a 16-bit value V the required value (from the PNG
+ * specification) is:
+ *
+ * (V * 255) / 65535
+ *
+ * This reduces to round(V / 257), or floor((V + 128.5)/257)
+ *
+ * Represent V as the two byte value vhi.vlo. Make a guess that the
+ * result is the top byte of V, vhi, then the correction to this value
+ * is:
+ *
+ * error = floor(((V-vhi.vhi) + 128.5) / 257)
+ * = floor(((vlo-vhi) + 128.5) / 257)
+ *
+ * This can be approximated using integer arithmetic (and a signed
+ * shift):
+ *
+ * error = (vlo-vhi+128) >> 8;
+ *
+ * The approximate differs from the exact answer only when (vlo-vhi) is
+ * 128; it then gives a correction of +1 when the exact correction is
+ * 0. This gives 128 errors. The exact answer (correct for all 16-bit
+ * input values) is:
+ *
+ * error = (vlo-vhi+128)*65535 >> 24;
+ *
+ * An alternative arithmetic calculation which also gives no errors is:
+ *
+ * (V * 255 + 32895) >> 16
+ */
+
+ png_int_32 tmp = *sp++; /* must be signed! */
+ tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
+ *dp++ = (png_byte)tmp;
+ }
+
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_info->width * row_info->channels;
+ }
+}
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+static void
+/* Simply discard the low byte. This was the default behavior prior
+ * to libpng-1.5.4.
+ */
+png_do_chop(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_chop");
+
+ if (row_info->bit_depth == 16)
+ {
+ png_bytep sp = row; /* source */
+ png_bytep dp = row; /* destination */
+ png_bytep ep = sp + row_info->rowbytes; /* end+1 */
+
+ while (sp < ep)
+ {
+ *dp++ = *sp;
+ sp += 2; /* skip low byte */
+ }
+
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_info->width * row_info->channels;
+ }
+}
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+static void
+png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_swap_alpha");
+
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This converts from RGBA to ARGB */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ /* This converts from RRGGBBAA to AARRGGBB */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
+ }
+#endif
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This converts from GA to AG */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ /* This converts from GGAA to AAGG */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
+ }
+#endif
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+static void
+png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_uint_32 row_width;
+ png_debug(1, "in png_do_read_invert_alpha");
+
+ row_width = row_info->width;
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This inverts the alpha channel in RGBA */
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+
+/* This does nothing:
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ We can replace it with:
+*/
+ sp-=3;
+ dp=sp;
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ /* This inverts the alpha channel in RRGGBBAA */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = (png_byte)(255 - *(--sp));
+
+/* This does nothing:
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ We can replace it with:
+*/
+ sp-=6;
+ dp=sp;
+ }
+ }
+#endif
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This inverts the alpha channel in GA */
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = *(--sp);
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ else
+ {
+ /* This inverts the alpha channel in GGAA */
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = (png_byte)(255 - *(--sp));
+/*
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+*/
+ sp-=2;
+ dp=sp;
+ }
+ }
+#endif
+ }
+}
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+/* Add filler channel if we have RGB color */
+static void
+png_do_read_filler(png_row_infop row_info, png_bytep row,
+ png_uint_32 filler, png_uint_32 flags)
+{
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ png_byte hi_filler = (png_byte)(filler>>8);
+#endif
+ png_byte lo_filler = (png_byte)filler;
+
+ png_debug(1, "in png_do_read_filler");
+
+ if (
+ row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+ {
+ /* This changes the data from G to GX */
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ row_info->channels = 2;
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+
+ else
+ {
+ /* This changes the data from G to XG */
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 2;
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ else if (row_info->bit_depth == 16)
+ {
+ if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+ {
+ /* This changes the data from GG to GGXX */
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = hi_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ *(--dp) = hi_filler;
+ row_info->channels = 2;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+
+ else
+ {
+ /* This changes the data from GG to XXGG */
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ *(--dp) = hi_filler;
+ }
+ row_info->channels = 2;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ }
+#endif
+ } /* COLOR_TYPE == GRAY */
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+ {
+ /* This changes the data from RGB to RGBX */
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ row_info->channels = 4;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+
+ else
+ {
+ /* This changes the data from RGB to XRGB */
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 4;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ else if (row_info->bit_depth == 16)
+ {
+ if ((flags & PNG_FLAG_FILLER_AFTER) != 0)
+ {
+ /* This changes the data from RRGGBB to RRGGBBXX */
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = hi_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ *(--dp) = hi_filler;
+ row_info->channels = 4;
+ row_info->pixel_depth = 64;
+ row_info->rowbytes = row_width * 8;
+ }
+
+ else
+ {
+ /* This changes the data from RRGGBB to XXRRGGBB */
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ *(--dp) = hi_filler;
+ }
+
+ row_info->channels = 4;
+ row_info->pixel_depth = 64;
+ row_info->rowbytes = row_width * 8;
+ }
+ }
+#endif
+ } /* COLOR_TYPE == RGB */
+}
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+/* Expand grayscale files to RGB, with or without alpha */
+static void
+png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
+{
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ png_debug(1, "in png_do_gray_to_rgb");
+
+ if (row_info->bit_depth >= 8 &&
+ (row_info->color_type & PNG_COLOR_MASK_COLOR) == 0)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This changes G to RGB */
+ png_bytep sp = row + (png_size_t)row_width - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *sp;
+ *(dp--) = *sp;
+ *(dp--) = *(sp--);
+ }
+ }
+
+ else
+ {
+ /* This changes GG to RRGGBB */
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ }
+ }
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This changes GA to RGBA */
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *(sp--);
+ *(dp--) = *sp;
+ *(dp--) = *sp;
+ *(dp--) = *(sp--);
+ }
+ }
+
+ else
+ {
+ /* This changes GGAA to RRGGBBAA */
+ png_bytep sp = row + (png_size_t)row_width * 4 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ }
+ }
+ }
+ row_info->channels = (png_byte)(row_info->channels + 2);
+ row_info->color_type |= PNG_COLOR_MASK_COLOR;
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+/* Reduce RGB files to grayscale, with or without alpha
+ * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
+ * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but
+ * versions dated 1998 through November 2002 have been archived at
+ * https://web.archive.org/web/20000816232553/www.inforamp.net/
+ * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
+ * Charles Poynton poynton at poynton.com
+ *
+ * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+ *
+ * which can be expressed with integers as
+ *
+ * Y = (6969 * R + 23434 * G + 2365 * B)/32768
+ *
+ * Poynton's current link (as of January 2003 through July 2011):
+ * <http://www.poynton.com/notes/colour_and_gamma/>
+ * has changed the numbers slightly:
+ *
+ * Y = 0.2126*R + 0.7152*G + 0.0722*B
+ *
+ * which can be expressed with integers as
+ *
+ * Y = (6966 * R + 23436 * G + 2366 * B)/32768
+ *
+ * Historically, however, libpng uses numbers derived from the ITU-R Rec 709
+ * end point chromaticities and the D65 white point. Depending on the
+ * precision used for the D65 white point this produces a variety of different
+ * numbers, however if the four decimal place value used in ITU-R Rec 709 is
+ * used (0.3127,0.3290) the Y calculation would be:
+ *
+ * Y = (6968 * R + 23435 * G + 2366 * B)/32768
+ *
+ * While this is correct the rounding results in an overflow for white, because
+ * the sum of the rounded coefficients is 32769, not 32768. Consequently
+ * libpng uses, instead, the closest non-overflowing approximation:
+ *
+ * Y = (6968 * R + 23434 * G + 2366 * B)/32768
+ *
+ * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
+ * (including an sRGB chunk) then the chromaticities are used to calculate the
+ * coefficients. See the chunk handling in pngrutil.c for more information.
+ *
+ * In all cases the calculation is to be done in a linear colorspace. If no
+ * gamma information is available to correct the encoding of the original RGB
+ * values this results in an implicit assumption that the original PNG RGB
+ * values were linear.
+ *
+ * Other integer coefficents can be used via png_set_rgb_to_gray(). Because
+ * the API takes just red and green coefficients the blue coefficient is
+ * calculated to make the sum 32768. This will result in different rounding
+ * to that used above.
+ */
+static int
+png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
+
+{
+ int rgb_error = 0;
+
+ png_debug(1, "in png_do_rgb_to_gray");
+
+ if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 &&
+ (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ {
+ PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
+ PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
+ PNG_CONST png_uint_32 bc = 32768 - rc - gc;
+ PNG_CONST png_uint_32 row_width = row_info->width;
+ PNG_CONST int have_alpha =
+ (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
+
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ /* Notice that gamma to/from 1 are not necessarily inverses (if
+ * there is an overall gamma correction). Prior to 1.5.5 this code
+ * checked the linearized values for equality; this doesn't match
+ * the documentation, the original values must be checked.
+ */
+ if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = *(sp++);
+ png_byte green = *(sp++);
+ png_byte blue = *(sp++);
+
+ if (red != green || red != blue)
+ {
+ red = png_ptr->gamma_to_1[red];
+ green = png_ptr->gamma_to_1[green];
+ blue = png_ptr->gamma_to_1[blue];
+
+ rgb_error |= 1;
+ *(dp++) = png_ptr->gamma_from_1[
+ (rc*red + gc*green + bc*blue + 16384)>>15];
+ }
+
+ else
+ {
+ /* If there is no overall correction the table will not be
+ * set.
+ */
+ if (png_ptr->gamma_table != NULL)
+ red = png_ptr->gamma_table[red];
+
+ *(dp++) = red;
+ }
+
+ if (have_alpha != 0)
+ *(dp++) = *(sp++);
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = *(sp++);
+ png_byte green = *(sp++);
+ png_byte blue = *(sp++);
+
+ if (red != green || red != blue)
+ {
+ rgb_error |= 1;
+ /* NOTE: this is the historical approach which simply
+ * truncates the results.
+ */
+ *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
+ }
+
+ else
+ *(dp++) = red;
+
+ if (have_alpha != 0)
+ *(dp++) = *(sp++);
+ }
+ }
+ }
+
+ else /* RGB bit_depth == 16 */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, w;
+ png_byte hi,lo;
+
+ hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo));
+ hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
+ hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo));
+
+ if (red == green && red == blue)
+ {
+ if (png_ptr->gamma_16_table != NULL)
+ w = png_ptr->gamma_16_table[(red & 0xff)
+ >> png_ptr->gamma_shift][red >> 8];
+
+ else
+ w = red;
+ }
+
+ else
+ {
+ png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red & 0xff)
+ >> png_ptr->gamma_shift][red>>8];
+ png_uint_16 green_1 =
+ png_ptr->gamma_16_to_1[(green & 0xff) >>
+ png_ptr->gamma_shift][green>>8];
+ png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue & 0xff)
+ >> png_ptr->gamma_shift][blue>>8];
+ png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
+ + bc*blue_1 + 16384)>>15);
+ w = png_ptr->gamma_16_from_1[(gray16 & 0xff) >>
+ png_ptr->gamma_shift][gray16 >> 8];
+ rgb_error |= 1;
+ }
+
+ *(dp++) = (png_byte)((w>>8) & 0xff);
+ *(dp++) = (png_byte)(w & 0xff);
+
+ if (have_alpha != 0)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ }
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, gray16;
+ png_byte hi,lo;
+
+ hi=*(sp)++; lo=*(sp)++; red = (png_uint_16)((hi << 8) | (lo));
+ hi=*(sp)++; lo=*(sp)++; green = (png_uint_16)((hi << 8) | (lo));
+ hi=*(sp)++; lo=*(sp)++; blue = (png_uint_16)((hi << 8) | (lo));
+
+ if (red != green || red != blue)
+ rgb_error |= 1;
+
+ /* From 1.5.5 in the 16-bit case do the accurate conversion even
+ * in the 'fast' case - this is because this is where the code
+ * ends up when handling linear 16-bit data.
+ */
+ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
+ 15);
+ *(dp++) = (png_byte)((gray16 >> 8) & 0xff);
+ *(dp++) = (png_byte)(gray16 & 0xff);
+
+ if (have_alpha != 0)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ }
+ }
+ }
+ }
+
+ row_info->channels = (png_byte)(row_info->channels - 2);
+ row_info->color_type = (png_byte)(row_info->color_type &
+ ~PNG_COLOR_MASK_COLOR);
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+ return rgb_error;
+}
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+/* Replace any alpha or transparency with the supplied background color.
+ * "background" is already in the screen gamma, while "background_1" is
+ * at a gamma of 1.0. Paletted files have already been taken care of.
+ */
+static void
+png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
+{
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ png_const_bytep gamma_table = png_ptr->gamma_table;
+ png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
+ png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
+ png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
+ png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
+ png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
+ int gamma_shift = png_ptr->gamma_shift;
+ int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
+#endif
+
+ png_bytep sp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ int shift;
+
+ png_debug(1, "in png_do_compose");
+
+ {
+ switch (row_info->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ sp = row;
+ shift = 7;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x01)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
+ tmp |=
+ (unsigned int)(png_ptr->background.gray << shift);
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ if (shift == 0)
+ {
+ shift = 7;
+ sp++;
+ }
+
+ else
+ shift--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+ tmp |=
+ (unsigned int)png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ else
+ {
+ unsigned int p = (*sp >> shift) & 0x03;
+ unsigned int g = (gamma_table [p | (p << 2) |
+ (p << 4) | (p << 6)] >> 6) & 0x03;
+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+ tmp |= (unsigned int)(g << shift);
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ if (shift == 0)
+ {
+ shift = 6;
+ sp++;
+ }
+
+ else
+ shift -= 2;
+ }
+ }
+
+ else
+#endif
+ {
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+ tmp |=
+ (unsigned int)png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ if (shift == 0)
+ {
+ shift = 6;
+ sp++;
+ }
+
+ else
+ shift -= 2;
+ }
+ }
+ break;
+ }
+
+ case 4:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
+ tmp |=
+ (unsigned int)(png_ptr->background.gray << shift);
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ else
+ {
+ unsigned int p = (*sp >> shift) & 0x0f;
+ unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
+ 0x0f;
+ unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
+ tmp |= (unsigned int)(g << shift);
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ if (shift == 0)
+ {
+ shift = 4;
+ sp++;
+ }
+
+ else
+ shift -= 4;
+ }
+ }
+
+ else
+#endif
+ {
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
+ tmp |=
+ (unsigned int)(png_ptr->background.gray << shift);
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ if (shift == 0)
+ {
+ shift = 4;
+ sp++;
+ }
+
+ else
+ shift -= 4;
+ }
+ }
+ break;
+ }
+
+ case 8:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == png_ptr->trans_color.gray)
+ *sp = (png_byte)png_ptr->background.gray;
+
+ else
+ *sp = gamma_table[*sp];
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == png_ptr->trans_color.gray)
+ *sp = (png_byte)png_ptr->background.gray;
+ }
+ }
+ break;
+ }
+
+ case 16:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+ if (v == png_ptr->trans_color.gray)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((png_ptr->background.gray >> 8)
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray
+ & 0xff);
+ }
+
+ else
+ {
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+ if (v == png_ptr->trans_color.gray)
+ {
+ *sp = (png_byte)((png_ptr->background.gray >> 8)
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray
+ & 0xff);
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_RGB:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 3)
+ {
+ if (*sp == png_ptr->trans_color.red &&
+ *(sp + 1) == png_ptr->trans_color.green &&
+ *(sp + 2) == png_ptr->trans_color.blue)
+ {
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
+
+ else
+ {
+ *sp = gamma_table[*sp];
+ *(sp + 1) = gamma_table[*(sp + 1)];
+ *(sp + 2) = gamma_table[*(sp + 2)];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 3)
+ {
+ if (*sp == png_ptr->trans_color.red &&
+ *(sp + 1) == png_ptr->trans_color.green &&
+ *(sp + 2) == png_ptr->trans_color.blue)
+ {
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
+ }
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 6)
+ {
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ if (r == png_ptr->trans_color.red &&
+ g == png_ptr->trans_color.green &&
+ b == png_ptr->trans_color.blue)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+ }
+
+ else
+ {
+ png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 6)
+ {
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ if (r == png_ptr->trans_color.red &&
+ g == png_ptr->trans_color.green &&
+ b == png_ptr->trans_color.blue)
+ {
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 a = *(sp + 1);
+
+ if (a == 0xff)
+ *sp = gamma_table[*sp];
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)png_ptr->background.gray;
+ }
+
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, png_ptr->background_1.gray);
+ if (optimize == 0)
+ w = gamma_from_1[w];
+ *sp = w;
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_byte a = *(sp + 1);
+
+ if (a == 0)
+ *sp = (png_byte)png_ptr->background.gray;
+
+ else if (a < 0xff)
+ png_composite(*sp, *sp, a, png_ptr->background.gray);
+ }
+ }
+ }
+ else /* if (png_ptr->bit_depth == 16) */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
+ {
+ png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+
+ if (a == (png_uint_16)0xffff)
+ {
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((png_ptr->background.gray >> 8)
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
+ }
+
+ else
+ {
+ png_uint_16 g, v, w;
+
+ g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(v, g, a, png_ptr->background_1.gray);
+ if (optimize != 0)
+ w = v;
+ else
+ w = gamma_16_from_1[(v & 0xff) >>
+ gamma_shift][v >> 8];
+ *sp = (png_byte)((w >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(w & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
+ {
+ png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+
+ if (a == 0)
+ {
+ *sp = (png_byte)((png_ptr->background.gray >> 8)
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
+ }
+
+ else if (a < 0xffff)
+ {
+ png_uint_16 g, v;
+
+ g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_composite_16(v, g, a, png_ptr->background.gray);
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0xff)
+ {
+ *sp = gamma_table[*sp];
+ *(sp + 1) = gamma_table[*(sp + 1)];
+ *(sp + 2) = gamma_table[*(sp + 2)];
+ }
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
+
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, png_ptr->background_1.red);
+ if (optimize == 0) w = gamma_from_1[w];
+ *sp = w;
+
+ v = gamma_to_1[*(sp + 1)];
+ png_composite(w, v, a, png_ptr->background_1.green);
+ if (optimize == 0) w = gamma_from_1[w];
+ *(sp + 1) = w;
+
+ v = gamma_to_1[*(sp + 2)];
+ png_composite(w, v, a, png_ptr->background_1.blue);
+ if (optimize == 0) w = gamma_from_1[w];
+ *(sp + 2) = w;
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0)
+ {
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
+
+ else if (a < 0xff)
+ {
+ png_composite(*sp, *sp, a, png_ptr->background.red);
+
+ png_composite(*(sp + 1), *(sp + 1), a,
+ png_ptr->background.green);
+
+ png_composite(*(sp + 2), *(sp + 2), a,
+ png_ptr->background.blue);
+ }
+ }
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 8)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+
+ if (a == (png_uint_16)0xffff)
+ {
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+ }
+
+ else
+ {
+ png_uint_16 v, w;
+
+ v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(w, v, a, png_ptr->background_1.red);
+ if (optimize == 0)
+ w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
+ 8];
+ *sp = (png_byte)((w >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(w & 0xff);
+
+ v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ png_composite_16(w, v, a, png_ptr->background_1.green);
+ if (optimize == 0)
+ w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
+ 8];
+
+ *(sp + 2) = (png_byte)((w >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(w & 0xff);
+
+ v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ png_composite_16(w, v, a, png_ptr->background_1.blue);
+ if (optimize == 0)
+ w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >>
+ 8];
+
+ *(sp + 4) = (png_byte)((w >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(w & 0xff);
+ }
+ }
+ }
+
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 8)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+
+ if (a == 0)
+ {
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+ }
+
+ else if (a < 0xffff)
+ {
+ png_uint_16 v;
+
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ png_composite_16(v, r, a, png_ptr->background.red);
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+
+ png_composite_16(v, g, a, png_ptr->background.green);
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+
+ png_composite_16(v, b, a, png_ptr->background.blue);
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+}
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* Gamma correct the image, avoiding the alpha channel. Make sure
+ * you do this after you deal with the transparency issue on grayscale
+ * or RGB images. If your bit depth is 8, use gamma_table, if it
+ * is 16, use gamma_16_table and gamma_shift. Build these with
+ * build_gamma_table().
+ */
+static void
+png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
+{
+ png_const_bytep gamma_table = png_ptr->gamma_table;
+ png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
+ int gamma_shift = png_ptr->gamma_shift;
+
+ png_bytep sp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_gamma");
+
+ if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
+ (row_info->bit_depth == 16 && gamma_16_table != NULL)))
+ {
+ switch (row_info->color_type)
+ {
+ case PNG_COLOR_TYPE_RGB:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ }
+ }
+
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+
+ *sp = gamma_table[*sp];
+ sp++;
+
+ *sp = gamma_table[*sp];
+ sp++;
+
+ sp++;
+ }
+ }
+
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 4;
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp += 2;
+ }
+ }
+
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 4;
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_GRAY:
+ {
+ if (row_info->bit_depth == 2)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i += 4)
+ {
+ int a = *sp & 0xc0;
+ int b = *sp & 0x30;
+ int c = *sp & 0x0c;
+ int d = *sp & 0x03;
+
+ *sp = (png_byte)(
+ ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
+ ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
+ ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
+ ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
+ sp++;
+ }
+ }
+
+ if (row_info->bit_depth == 4)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i += 2)
+ {
+ int msb = *sp & 0xf0;
+ int lsb = *sp & 0x0f;
+
+ *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
+ | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
+ sp++;
+ }
+ }
+
+ else if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ }
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+/* Encode the alpha channel to the output gamma (the input channel is always
+ * linear.) Called only with color types that have an alpha channel. Needs the
+ * from_1 tables.
+ */
+static void
+png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
+{
+ png_uint_32 row_width = row_info->width;
+
+ png_debug(1, "in png_do_encode_alpha");
+
+ if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ PNG_CONST png_bytep table = png_ptr->gamma_from_1;
+
+ if (table != NULL)
+ {
+ PNG_CONST int step =
+ (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
+
+ /* The alpha channel is the last component: */
+ row += step - 1;
+
+ for (; row_width > 0; --row_width, row += step)
+ *row = table[*row];
+
+ return;
+ }
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
+ PNG_CONST int gamma_shift = png_ptr->gamma_shift;
+
+ if (table != NULL)
+ {
+ PNG_CONST int step =
+ (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
+
+ /* The alpha channel is the last component: */
+ row += step - 2;
+
+ for (; row_width > 0; --row_width, row += step)
+ {
+ png_uint_16 v;
+
+ v = table[*(row + 1) >> gamma_shift][*row];
+ *row = (png_byte)((v >> 8) & 0xff);
+ *(row + 1) = (png_byte)(v & 0xff);
+ }
+
+ return;
+ }
+ }
+ }
+
+ /* Only get to here if called with a weird row_info; no harm has been done,
+ * so just issue a warning.
+ */
+ png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
+}
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expands a palette row to an RGB or RGBA row depending
+ * upon whether you supply trans and num_trans.
+ */
+static void
+png_do_expand_palette(png_row_infop row_info, png_bytep row,
+ png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
+{
+ int shift, value;
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_expand_palette");
+
+ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (row_info->bit_depth < 8)
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
+ shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*sp >> shift) & 0x01)
+ *dp = 1;
+
+ else
+ *dp = 0;
+
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp = (png_byte)value;
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((row_width & 0x01) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x0f;
+ *dp = (png_byte)value;
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift += 4;
+
+ dp--;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+
+ if (row_info->bit_depth == 8)
+ {
+ {
+ if (num_trans > 0)
+ {
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + ((png_size_t)row_width << 2) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if ((int)(*sp) >= num_trans)
+ *dp-- = 0xff;
+
+ else
+ *dp-- = trans_alpha[*sp];
+
+ *dp-- = palette[*sp].blue;
+ *dp-- = palette[*sp].green;
+ *dp-- = palette[*sp].red;
+ sp--;
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ row_info->color_type = 6;
+ row_info->channels = 4;
+ }
+
+ else
+ {
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width * 3) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *dp-- = palette[*sp].blue;
+ *dp-- = palette[*sp].green;
+ *dp-- = palette[*sp].red;
+ sp--;
+ }
+
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 24;
+ row_info->rowbytes = row_width * 3;
+ row_info->color_type = 2;
+ row_info->channels = 3;
+ }
+ }
+ }
+ }
+}
+
+/* If the bit depth < 8, it is expanded to 8. Also, if the already
+ * expanded transparency value is supplied, an alpha channel is built.
+ */
+static void
+png_do_expand(png_row_infop row_info, png_bytep row,
+ png_const_color_16p trans_color)
+{
+ int shift, value;
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_expand");
+
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ unsigned int gray = trans_color != NULL ? trans_color->gray : 0;
+
+ if (row_info->bit_depth < 8)
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ gray = (gray & 0x01) * 0xff;
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
+ shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*sp >> shift) & 0x01)
+ *dp = 0xff;
+
+ else
+ *dp = 0;
+
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+ gray = (gray & 0x03) * 0x55;
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp = (png_byte)(value | (value << 2) | (value << 4) |
+ (value << 6));
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ gray = (gray & 0x0f) * 0x11;
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x0f;
+ *dp = (png_byte)(value | (value << 4));
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift = 4;
+
+ dp--;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+
+ if (trans_color != NULL)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ gray = gray & 0xff;
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + ((png_size_t)row_width << 1) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*sp & 0xffU) == gray)
+ *dp-- = 0;
+
+ else
+ *dp-- = 0xff;
+
+ *dp-- = *sp--;
+ }
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ unsigned int gray_high = (gray >> 8) & 0xff;
+ unsigned int gray_low = gray & 0xff;
+ sp = row + row_info->rowbytes - 1;
+ dp = row + (row_info->rowbytes << 1) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*(sp - 1) & 0xffU) == gray_high &&
+ (*(sp) & 0xffU) == gray_low)
+ {
+ *dp-- = 0;
+ *dp-- = 0;
+ }
+
+ else
+ {
+ *dp-- = 0xff;
+ *dp-- = 0xff;
+ }
+
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+
+ row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+ row_info->channels = 2;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_width);
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
+ trans_color != NULL)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ png_byte red = (png_byte)(trans_color->red & 0xff);
+ png_byte green = (png_byte)(trans_color->green & 0xff);
+ png_byte blue = (png_byte)(trans_color->blue & 0xff);
+ sp = row + (png_size_t)row_info->rowbytes - 1;
+ dp = row + ((png_size_t)row_width << 2) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
+ *dp-- = 0;
+
+ else
+ *dp-- = 0xff;
+
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
+ png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
+ png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
+ png_byte red_low = (png_byte)(trans_color->red & 0xff);
+ png_byte green_low = (png_byte)(trans_color->green & 0xff);
+ png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
+ sp = row + row_info->rowbytes - 1;
+ dp = row + ((png_size_t)row_width << 3) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 5) == red_high &&
+ *(sp - 4) == red_low &&
+ *(sp - 3) == green_high &&
+ *(sp - 2) == green_low &&
+ *(sp - 1) == blue_high &&
+ *(sp ) == blue_low)
+ {
+ *dp-- = 0;
+ *dp-- = 0;
+ }
+
+ else
+ {
+ *dp-- = 0xff;
+ *dp-- = 0xff;
+ }
+
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ row_info->channels = 4;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+/* If the bit depth is 8 and the color type is not a palette type expand the
+ * whole row to 16 bits. Has no effect otherwise.
+ */
+static void
+png_do_expand_16(png_row_infop row_info, png_bytep row)
+{
+ if (row_info->bit_depth == 8 &&
+ row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ /* The row have a sequence of bytes containing [0..255] and we need
+ * to turn it into another row containing [0..65535], to do this we
+ * calculate:
+ *
+ * (input / 255) * 65535
+ *
+ * Which happens to be exactly input * 257 and this can be achieved
+ * simply by byte replication in place (copying backwards).
+ */
+ png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
+ png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */
+ while (dp > sp)
+ {
+ dp[-2] = dp[-1] = *--sp; dp -= 2;
+ }
+
+ row_info->rowbytes *= 2;
+ row_info->bit_depth = 16;
+ row_info->pixel_depth = (png_byte)(row_info->channels * 16);
+ }
+}
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+static void
+png_do_quantize(png_row_infop row_info, png_bytep row,
+ png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
+{
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_quantize");
+
+ if (row_info->bit_depth == 8)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
+ {
+ int r, g, b, p;
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ r = *sp++;
+ g = *sp++;
+ b = *sp++;
+
+ /* This looks real messy, but the compiler will reduce
+ * it down to a reasonable formula. For example, with
+ * 5 bits per color, we get:
+ * p = (((r >> 3) & 0x1f) << 10) |
+ * (((g >> 3) & 0x1f) << 5) |
+ * ((b >> 3) & 0x1f);
+ */
+ p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
+ ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
+ (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
+ (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
+ ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
+ (PNG_QUANTIZE_BLUE_BITS)) |
+ ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
+ ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
+
+ *dp++ = palette_lookup[p];
+ }
+
+ row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+ row_info->channels = 1;
+ row_info->pixel_depth = row_info->bit_depth;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+ palette_lookup != NULL)
+ {
+ int r, g, b, p;
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ r = *sp++;
+ g = *sp++;
+ b = *sp++;
+ sp++;
+
+ p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
+ ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
+ (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
+ (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
+ ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
+ (PNG_QUANTIZE_BLUE_BITS)) |
+ ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
+ ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
+
+ *dp++ = palette_lookup[p];
+ }
+
+ row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+ row_info->channels = 1;
+ row_info->pixel_depth = row_info->bit_depth;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+ quantize_lookup)
+ {
+ sp = row;
+
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ *sp = quantize_lookup[*sp];
+ }
+ }
+ }
+}
+#endif /* READ_QUANTIZE */
+
+/* Transform the row. The order of transformations is significant,
+ * and is very touchy. If you add a transformation, take care to
+ * decide how it fits in with the other transformations here.
+ */
+void /* PRIVATE */
+png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
+{
+ png_debug(1, "in png_do_read_transformations");
+
+ if (png_ptr->row_buf == NULL)
+ {
+ /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
+ * error is incredibly rare and incredibly easy to debug without this
+ * information.
+ */
+ png_error(png_ptr, "NULL row buffer");
+ }
+
+ /* The following is debugging; prior to 1.5.4 the code was never compiled in;
+ * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
+ * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for
+ * all transformations, however in practice the ROW_INIT always gets done on
+ * demand, if necessary.
+ */
+ if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
+ (png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+ {
+ /* Application has failed to call either png_read_start_image() or
+ * png_read_update_info() after setting transforms that expand pixels.
+ * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
+ */
+ png_error(png_ptr, "Uninitialized row");
+ }
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ if ((png_ptr->transformations & PNG_EXPAND) != 0)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_do_expand_palette(row_info, png_ptr->row_buf + 1,
+ png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
+ }
+
+ else
+ {
+ if (png_ptr->num_trans != 0 &&
+ (png_ptr->transformations & PNG_EXPAND_tRNS) != 0)
+ png_do_expand(row_info, png_ptr->row_buf + 1,
+ &(png_ptr->trans_color));
+
+ else
+ png_do_expand(row_info, png_ptr->row_buf + 1,
+ NULL);
+ }
+ }
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
+ (png_ptr->transformations & PNG_COMPOSE) == 0 &&
+ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
+ png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+ 0 /* at_start == false, because SWAP_ALPHA happens later */);
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) != 0)
+ {
+ int rgb_error =
+ png_do_rgb_to_gray(png_ptr, row_info,
+ png_ptr->row_buf + 1);
+
+ if (rgb_error != 0)
+ {
+ png_ptr->rgb_to_gray_status=1;
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+ PNG_RGB_TO_GRAY_WARN)
+ png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+ PNG_RGB_TO_GRAY_ERR)
+ png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+ }
+ }
+#endif
+
+/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
+ *
+ * In most cases, the "simple transparency" should be done prior to doing
+ * gray-to-RGB, or you will have to test 3x as many bytes to check if a
+ * pixel is transparent. You would also need to make sure that the
+ * transparency information is upgraded to RGB.
+ *
+ * To summarize, the current flow is:
+ * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
+ * with background "in place" if transparent,
+ * convert to RGB if necessary
+ * - Gray + alpha -> composite with gray background and remove alpha bytes,
+ * convert to RGB if necessary
+ *
+ * To support RGB backgrounds for gray images we need:
+ * - Gray + simple transparency -> convert to RGB + simple transparency,
+ * compare 3 or 6 bytes and composite with
+ * background "in place" if transparent
+ * (3x compare/pixel compared to doing
+ * composite with gray bkgrnd)
+ * - Gray + alpha -> convert to RGB + alpha, composite with background and
+ * remove alpha bytes (3x float
+ * operations/pixel compared with composite
+ * on gray background)
+ *
+ * Greg's change will do this. The reason it wasn't done before is for
+ * performance, as this increases the per-pixel operations. If we would check
+ * in advance if the background was gray or RGB, and position the gray-to-RGB
+ * transform appropriately, then it would save a lot of work/time.
+ */
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* If gray -> RGB, do so now only if background is non-gray; else do later
+ * for performance reasons
+ */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
+ (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) == 0)
+ png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+ if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+ png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if ((png_ptr->transformations & PNG_GAMMA) != 0 &&
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ /* Because RGB_TO_GRAY does the gamma transform. */
+ (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0 &&
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+ /* Because PNG_COMPOSE does the gamma transform if there is something to
+ * do (if there is an alpha channel or transparency.)
+ */
+ !((png_ptr->transformations & PNG_COMPOSE) != 0 &&
+ ((png_ptr->num_trans != 0) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)) &&
+#endif
+ /* Because png_init_read_transformations transforms the palette, unless
+ * RGB_TO_GRAY will do the transform.
+ */
+ (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
+ png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) != 0 &&
+ (png_ptr->transformations & PNG_COMPOSE) != 0 &&
+ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
+ png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+ 0 /* at_start == false, because SWAP_ALPHA happens later */);
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+ if ((png_ptr->transformations & PNG_ENCODE_ALPHA) != 0 &&
+ (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ if ((png_ptr->transformations & PNG_SCALE_16_TO_8) != 0)
+ png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ /* There is no harm in doing both of these because only one has any effect,
+ * by putting the 'scale' option first if the app asks for scale (either by
+ * calling the API or in a TRANSFORM flag) this is what happens.
+ */
+ if ((png_ptr->transformations & PNG_16_TO_8) != 0)
+ png_do_chop(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+ if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
+ {
+ png_do_quantize(row_info, png_ptr->row_buf + 1,
+ png_ptr->palette_lookup, png_ptr->quantize_index);
+
+ if (row_info->rowbytes == 0)
+ png_error(png_ptr, "png_do_quantize returned rowbytes=0");
+ }
+#endif /* READ_QUANTIZE */
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ /* Do the expansion now, after all the arithmetic has been done. Notice
+ * that previous transformations can handle the PNG_EXPAND_16 flag if this
+ * is efficient (particularly true in the case of gamma correction, where
+ * better accuracy results faster!)
+ */
+ if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
+ png_do_expand_16(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* NOTE: moved here in 1.5.4 (from much later in this list.) */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0 &&
+ (png_ptr->mode & PNG_BACKGROUND_IS_GRAY) != 0)
+ png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_INVERT_SUPPORTED
+ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
+ png_do_invert(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
+ png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ if ((png_ptr->transformations & PNG_SHIFT) != 0)
+ png_do_unshift(row_info, png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACK) != 0)
+ png_do_unpack(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ /* Added at libpng-1.5.10 */
+ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+ png_ptr->num_palette_max >= 0)
+ png_do_check_palette_indexes(png_ptr, row_info);
+#endif
+
+#ifdef PNG_READ_BGR_SUPPORTED
+ if ((png_ptr->transformations & PNG_BGR) != 0)
+ png_do_bgr(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+ png_do_packswap(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+ if ((png_ptr->transformations & PNG_FILLER) != 0)
+ png_do_read_filler(row_info, png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->filler, png_ptr->flags);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
+ png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+#ifdef PNG_READ_SWAP_SUPPORTED
+ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
+ png_do_swap(row_info, png_ptr->row_buf + 1);
+#endif
+#endif
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
+ {
+ if (png_ptr->read_user_transform_fn != NULL)
+ (*(png_ptr->read_user_transform_fn)) /* User read transform function */
+ (png_ptr, /* png_ptr */
+ row_info, /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_size_t rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+ if (png_ptr->user_transform_depth != 0)
+ row_info->bit_depth = png_ptr->user_transform_depth;
+
+ if (png_ptr->user_transform_channels != 0)
+ row_info->channels = png_ptr->user_transform_channels;
+#endif
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth *
+ row_info->channels);
+
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
+ }
+#endif
+}
+
+#endif /* READ_TRANSFORMS */
+#endif /* READ */
diff --git a/xs/src/png/libpng/pngrutil.c b/xs/src/png/libpng/pngrutil.c
new file mode 100644
index 000000000..8692933bd
--- /dev/null
+++ b/xs/src/png/libpng/pngrutil.c
@@ -0,0 +1,4661 @@
+
+/* pngrutil.c - utilities to read a PNG file
+ *
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains routines that are only called from within
+ * libpng itself during the course of reading an image.
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+png_uint_32 PNGAPI
+png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
+{
+ png_uint_32 uval = png_get_uint_32(buf);
+
+ if (uval > PNG_UINT_31_MAX)
+ png_error(png_ptr, "PNG unsigned integer out of range");
+
+ return (uval);
+}
+
+#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
+/* The following is a variation on the above for use with the fixed
+ * point values used for gAMA and cHRM. Instead of png_error it
+ * issues a warning and returns (-1) - an invalid value because both
+ * gAMA and cHRM use *unsigned* integers for fixed point values.
+ */
+#define PNG_FIXED_ERROR (-1)
+
+static png_fixed_point /* PRIVATE */
+png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf)
+{
+ png_uint_32 uval = png_get_uint_32(buf);
+
+ if (uval <= PNG_UINT_31_MAX)
+ return (png_fixed_point)uval; /* known to be in range */
+
+ /* The caller can turn off the warning by passing NULL. */
+ if (png_ptr != NULL)
+ png_warning(png_ptr, "PNG fixed point integer out of range");
+
+ return PNG_FIXED_ERROR;
+}
+#endif
+
+#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
+/* NOTE: the read macros will obscure these definitions, so that if
+ * PNG_USE_READ_MACROS is set the library will not use them internally,
+ * but the APIs will still be available externally.
+ *
+ * The parentheses around "PNGAPI function_name" in the following three
+ * functions are necessary because they allow the macros to co-exist with
+ * these (unused but exported) functions.
+ */
+
+/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
+png_uint_32 (PNGAPI
+png_get_uint_32)(png_const_bytep buf)
+{
+ png_uint_32 uval =
+ ((png_uint_32)(*(buf )) << 24) +
+ ((png_uint_32)(*(buf + 1)) << 16) +
+ ((png_uint_32)(*(buf + 2)) << 8) +
+ ((png_uint_32)(*(buf + 3)) ) ;
+
+ return uval;
+}
+
+/* Grab a signed 32-bit integer from a buffer in big-endian format. The
+ * data is stored in the PNG file in two's complement format and there
+ * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
+ * the following code does a two's complement to native conversion.
+ */
+png_int_32 (PNGAPI
+png_get_int_32)(png_const_bytep buf)
+{
+ png_uint_32 uval = png_get_uint_32(buf);
+ if ((uval & 0x80000000) == 0) /* non-negative */
+ return (png_int_32)uval;
+
+ uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */
+ if ((uval & 0x80000000) == 0) /* no overflow */
+ return -(png_int_32)uval;
+ /* The following has to be safe; this function only gets called on PNG data
+ * and if we get here that data is invalid. 0 is the most safe value and
+ * if not then an attacker would surely just generate a PNG with 0 instead.
+ */
+ return 0;
+}
+
+/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
+png_uint_16 (PNGAPI
+png_get_uint_16)(png_const_bytep buf)
+{
+ /* ANSI-C requires an int value to accomodate at least 16 bits so this
+ * works and allows the compiler not to worry about possible narrowing
+ * on 32-bit systems. (Pre-ANSI systems did not make integers smaller
+ * than 16 bits either.)
+ */
+ unsigned int val =
+ ((unsigned int)(*buf) << 8) +
+ ((unsigned int)(*(buf + 1)));
+
+ return (png_uint_16)val;
+}
+
+#endif /* READ_INT_FUNCTIONS */
+
+/* Read and check the PNG file signature */
+void /* PRIVATE */
+png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_size_t num_checked, num_to_check;
+
+ /* Exit if the user application does not expect a signature. */
+ if (png_ptr->sig_bytes >= 8)
+ return;
+
+ num_checked = png_ptr->sig_bytes;
+ num_to_check = 8 - num_checked;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
+#endif
+
+ /* The signature must be serialized in a single I/O call. */
+ png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
+ png_ptr->sig_bytes = 8;
+
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0)
+ {
+ if (num_checked < 4 &&
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_error(png_ptr, "Not a PNG file");
+ else
+ png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+ }
+ if (num_checked < 3)
+ png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+}
+
+/* Read the chunk header (length + type name).
+ * Put the type name into png_ptr->chunk_name, and return the length.
+ */
+png_uint_32 /* PRIVATE */
+png_read_chunk_header(png_structrp png_ptr)
+{
+ png_byte buf[8];
+ png_uint_32 length;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
+#endif
+
+ /* Read the length and the chunk name.
+ * This must be performed in a single I/O call.
+ */
+ png_read_data(png_ptr, buf, 8);
+ length = png_get_uint_31(png_ptr, buf);
+
+ /* Put the chunk name into png_ptr->chunk_name. */
+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
+
+ png_debug2(0, "Reading %lx chunk, length = %lu",
+ (unsigned long)png_ptr->chunk_name, (unsigned long)length);
+
+ /* Reset the crc and run it over the chunk name. */
+ png_reset_crc(png_ptr);
+ png_calculate_crc(png_ptr, buf + 4, 4);
+
+ /* Check to see if chunk name is valid. */
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+ /* Check for too-large chunk length */
+ png_check_chunk_length(png_ptr, length);
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
+#endif
+
+ return length;
+}
+
+/* Read data, and (optionally) run it through the CRC. */
+void /* PRIVATE */
+png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_read_data(png_ptr, buf, length);
+ png_calculate_crc(png_ptr, buf, length);
+}
+
+/* Optionally skip data and then check the CRC. Depending on whether we
+ * are reading an ancillary or critical chunk, and how the program has set
+ * things up, we may calculate the CRC on the data and print a message.
+ * Returns '1' if there was a CRC error, '0' otherwise.
+ */
+int /* PRIVATE */
+png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
+{
+ /* The size of the local buffer for inflate is a good guess as to a
+ * reasonable size to use for buffering reads from the application.
+ */
+ while (skip > 0)
+ {
+ png_uint_32 len;
+ png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];
+
+ len = (sizeof tmpbuf);
+ if (len > skip)
+ len = skip;
+ skip -= len;
+
+ png_crc_read(png_ptr, tmpbuf, len);
+ }
+
+ if (png_crc_error(png_ptr) != 0)
+ {
+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0 ?
+ (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0 :
+ (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE) != 0)
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ }
+
+ else
+ png_chunk_error(png_ptr, "CRC error");
+
+ return (1);
+ }
+
+ return (0);
+}
+
+/* Compare the CRC stored in the PNG file with that calculated by libpng from
+ * the data it has read thus far.
+ */
+int /* PRIVATE */
+png_crc_error(png_structrp png_ptr)
+{
+ png_byte crc_bytes[4];
+ png_uint_32 crc;
+ int need_crc = 1;
+
+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) != 0)
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+ (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ need_crc = 0;
+ }
+
+ else /* critical */
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) != 0)
+ need_crc = 0;
+ }
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
+#endif
+
+ /* The chunk CRC must be serialized in a single I/O call. */
+ png_read_data(png_ptr, crc_bytes, 4);
+
+ if (need_crc != 0)
+ {
+ crc = png_get_uint_32(crc_bytes);
+ return ((int)(crc != png_ptr->crc));
+ }
+
+ else
+ return (0);
+}
+
+#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\
+ defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_sCAL_SUPPORTED) ||\
+ defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) ||\
+ defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_SEQUENTIAL_READ_SUPPORTED)
+/* Manage the read buffer; this simply reallocates the buffer if it is not small
+ * enough (or if it is not allocated). The routine returns a pointer to the
+ * buffer; if an error occurs and 'warn' is set the routine returns NULL, else
+ * it will call png_error (via png_malloc) on failure. (warn == 2 means
+ * 'silent').
+ */
+static png_bytep
+png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
+{
+ png_bytep buffer = png_ptr->read_buffer;
+
+ if (buffer != NULL && new_size > png_ptr->read_buffer_size)
+ {
+ png_ptr->read_buffer = NULL;
+ png_ptr->read_buffer = NULL;
+ png_ptr->read_buffer_size = 0;
+ png_free(png_ptr, buffer);
+ buffer = NULL;
+ }
+
+ if (buffer == NULL)
+ {
+ buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size));
+
+ if (buffer != NULL)
+ {
+ memset(buffer, 0, new_size); /* just in case */
+ png_ptr->read_buffer = buffer;
+ png_ptr->read_buffer_size = new_size;
+ }
+
+ else if (warn < 2) /* else silent */
+ {
+ if (warn != 0)
+ png_chunk_warning(png_ptr, "insufficient memory to read chunk");
+
+ else
+ png_chunk_error(png_ptr, "insufficient memory to read chunk");
+ }
+ }
+
+ return buffer;
+}
+#endif /* READ_iCCP|iTXt|pCAL|sCAL|sPLT|tEXt|zTXt|SEQUENTIAL_READ */
+
+/* png_inflate_claim: claim the zstream for some nefarious purpose that involves
+ * decompression. Returns Z_OK on success, else a zlib error code. It checks
+ * the owner but, in final release builds, just issues a warning if some other
+ * chunk apparently owns the stream. Prior to release it does a png_error.
+ */
+static int
+png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
+{
+ if (png_ptr->zowner != 0)
+ {
+ char msg[64];
+
+ PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner);
+ /* So the message that results is "<chunk> using zstream"; this is an
+ * internal error, but is very useful for debugging. i18n requirements
+ * are minimal.
+ */
+ (void)png_safecat(msg, (sizeof msg), 4, " using zstream");
+#if PNG_RELEASE_BUILD
+ png_chunk_warning(png_ptr, msg);
+ png_ptr->zowner = 0;
+#else
+ png_chunk_error(png_ptr, msg);
+#endif
+ }
+
+ /* Implementation note: unlike 'png_deflate_claim' this internal function
+ * does not take the size of the data as an argument. Some efficiency could
+ * be gained by using this when it is known *if* the zlib stream itself does
+ * not record the number; however, this is an illusion: the original writer
+ * of the PNG may have selected a lower window size, and we really must
+ * follow that because, for systems with with limited capabilities, we
+ * would otherwise reject the application's attempts to use a smaller window
+ * size (zlib doesn't have an interface to say "this or lower"!).
+ *
+ * inflateReset2 was added to zlib 1.2.4; before this the window could not be
+ * reset, therefore it is necessary to always allocate the maximum window
+ * size with earlier zlibs just in case later compressed chunks need it.
+ */
+ {
+ int ret; /* zlib return code */
+#if ZLIB_VERNUM >= 0x1240
+ int window_bits = 0;
+
+# if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW)
+ if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==
+ PNG_OPTION_ON)
+ {
+ window_bits = 15;
+ png_ptr->zstream_start = 0; /* fixed window size */
+ }
+
+ else
+ {
+ png_ptr->zstream_start = 1;
+ }
+# endif
+
+#endif /* ZLIB_VERNUM >= 0x1240 */
+
+ /* Set this for safety, just in case the previous owner left pointers to
+ * memory allocations.
+ */
+ png_ptr->zstream.next_in = NULL;
+ png_ptr->zstream.avail_in = 0;
+ png_ptr->zstream.next_out = NULL;
+ png_ptr->zstream.avail_out = 0;
+
+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
+ {
+#if ZLIB_VERNUM >= 0x1240
+ ret = inflateReset2(&png_ptr->zstream, window_bits);
+#else
+ ret = inflateReset(&png_ptr->zstream);
+#endif
+ }
+
+ else
+ {
+#if ZLIB_VERNUM >= 0x1240
+ ret = inflateInit2(&png_ptr->zstream, window_bits);
+#else
+ ret = inflateInit(&png_ptr->zstream);
+#endif
+
+ if (ret == Z_OK)
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
+ }
+
+#if ZLIB_VERNUM >= 0x1290 && \
+ defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32)
+ if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
+ /* Turn off validation of the ADLER32 checksum in IDAT chunks */
+ ret = inflateValidate(&png_ptr->zstream, 0);
+#endif
+
+ if (ret == Z_OK)
+ png_ptr->zowner = owner;
+
+ else
+ png_zstream_error(png_ptr, ret);
+
+ return ret;
+ }
+
+#ifdef window_bits
+# undef window_bits
+#endif
+}
+
+#if ZLIB_VERNUM >= 0x1240
+/* Handle the start of the inflate stream if we called inflateInit2(strm,0);
+ * in this case some zlib versions skip validation of the CINFO field and, in
+ * certain circumstances, libpng may end up displaying an invalid image, in
+ * contrast to implementations that call zlib in the normal way (e.g. libpng
+ * 1.5).
+ */
+int /* PRIVATE */
+png_zlib_inflate(png_structrp png_ptr, int flush)
+{
+ if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0)
+ {
+ if ((*png_ptr->zstream.next_in >> 4) > 7)
+ {
+ png_ptr->zstream.msg = "invalid window size (libpng)";
+ return Z_DATA_ERROR;
+ }
+
+ png_ptr->zstream_start = 0;
+ }
+
+ return inflate(&png_ptr->zstream, flush);
+}
+#endif /* Zlib >= 1.2.4 */
+
+#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined (PNG_READ_iTXt_SUPPORTED)
+/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to
+ * allow the caller to do multiple calls if required. If the 'finish' flag is
+ * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must
+ * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and
+ * Z_OK or Z_STREAM_END will be returned on success.
+ *
+ * The input and output sizes are updated to the actual amounts of data consumed
+ * or written, not the amount available (as in a z_stream). The data pointers
+ * are not changed, so the next input is (data+input_size) and the next
+ * available output is (output+output_size).
+ */
+static int
+png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish,
+ /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr,
+ /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr)
+{
+ if (png_ptr->zowner == owner) /* Else not claimed */
+ {
+ int ret;
+ png_alloc_size_t avail_out = *output_size_ptr;
+ png_uint_32 avail_in = *input_size_ptr;
+
+ /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it
+ * can't even necessarily handle 65536 bytes) because the type uInt is
+ * "16 bits or more". Consequently it is necessary to chunk the input to
+ * zlib. This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the
+ * maximum value that can be stored in a uInt.) It is possible to set
+ * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have
+ * a performance advantage, because it reduces the amount of data accessed
+ * at each step and that may give the OS more time to page it in.
+ */
+ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);
+ /* avail_in and avail_out are set below from 'size' */
+ png_ptr->zstream.avail_in = 0;
+ png_ptr->zstream.avail_out = 0;
+
+ /* Read directly into the output if it is available (this is set to
+ * a local buffer below if output is NULL).
+ */
+ if (output != NULL)
+ png_ptr->zstream.next_out = output;
+
+ do
+ {
+ uInt avail;
+ Byte local_buffer[PNG_INFLATE_BUF_SIZE];
+
+ /* zlib INPUT BUFFER */
+ /* The setting of 'avail_in' used to be outside the loop; by setting it
+ * inside it is possible to chunk the input to zlib and simply rely on
+ * zlib to advance the 'next_in' pointer. This allows arbitrary
+ * amounts of data to be passed through zlib at the unavoidable cost of
+ * requiring a window save (memcpy of up to 32768 output bytes)
+ * every ZLIB_IO_MAX input bytes.
+ */
+ avail_in += png_ptr->zstream.avail_in; /* not consumed last time */
+
+ avail = ZLIB_IO_MAX;
+
+ if (avail_in < avail)
+ avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */
+
+ avail_in -= avail;
+ png_ptr->zstream.avail_in = avail;
+
+ /* zlib OUTPUT BUFFER */
+ avail_out += png_ptr->zstream.avail_out; /* not written last time */
+
+ avail = ZLIB_IO_MAX; /* maximum zlib can process */
+
+ if (output == NULL)
+ {
+ /* Reset the output buffer each time round if output is NULL and
+ * make available the full buffer, up to 'remaining_space'
+ */
+ png_ptr->zstream.next_out = local_buffer;
+ if ((sizeof local_buffer) < avail)
+ avail = (sizeof local_buffer);
+ }
+
+ if (avail_out < avail)
+ avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */
+
+ png_ptr->zstream.avail_out = avail;
+ avail_out -= avail;
+
+ /* zlib inflate call */
+ /* In fact 'avail_out' may be 0 at this point, that happens at the end
+ * of the read when the final LZ end code was not passed at the end of
+ * the previous chunk of input data. Tell zlib if we have reached the
+ * end of the output buffer.
+ */
+ ret = PNG_INFLATE(png_ptr, avail_out > 0 ? Z_NO_FLUSH :
+ (finish ? Z_FINISH : Z_SYNC_FLUSH));
+ } while (ret == Z_OK);
+
+ /* For safety kill the local buffer pointer now */
+ if (output == NULL)
+ png_ptr->zstream.next_out = NULL;
+
+ /* Claw back the 'size' and 'remaining_space' byte counts. */
+ avail_in += png_ptr->zstream.avail_in;
+ avail_out += png_ptr->zstream.avail_out;
+
+ /* Update the input and output sizes; the updated values are the amount
+ * consumed or written, effectively the inverse of what zlib uses.
+ */
+ if (avail_out > 0)
+ *output_size_ptr -= avail_out;
+
+ if (avail_in > 0)
+ *input_size_ptr -= avail_in;
+
+ /* Ensure png_ptr->zstream.msg is set (even in the success case!) */
+ png_zstream_error(png_ptr, ret);
+ return ret;
+ }
+
+ else
+ {
+ /* This is a bad internal error. The recovery assigns to the zstream msg
+ * pointer, which is not owned by the caller, but this is safe; it's only
+ * used on errors!
+ */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed");
+ return Z_STREAM_ERROR;
+ }
+}
+
+/*
+ * Decompress trailing data in a chunk. The assumption is that read_buffer
+ * points at an allocated area holding the contents of a chunk with a
+ * trailing compressed part. What we get back is an allocated area
+ * holding the original prefix part and an uncompressed version of the
+ * trailing part (the malloc area passed in is freed).
+ */
+static int
+png_decompress_chunk(png_structrp png_ptr,
+ png_uint_32 chunklength, png_uint_32 prefix_size,
+ png_alloc_size_t *newlength /* must be initialized to the maximum! */,
+ int terminate /*add a '\0' to the end of the uncompressed data*/)
+{
+ /* TODO: implement different limits for different types of chunk.
+ *
+ * The caller supplies *newlength set to the maximum length of the
+ * uncompressed data, but this routine allocates space for the prefix and
+ * maybe a '\0' terminator too. We have to assume that 'prefix_size' is
+ * limited only by the maximum chunk size.
+ */
+ png_alloc_size_t limit = PNG_SIZE_MAX;
+
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_malloc_max > 0 &&
+ png_ptr->user_chunk_malloc_max < limit)
+ limit = png_ptr->user_chunk_malloc_max;
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+ if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+ limit = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+
+ if (limit >= prefix_size + (terminate != 0))
+ {
+ int ret;
+
+ limit -= prefix_size + (terminate != 0);
+
+ if (limit < *newlength)
+ *newlength = limit;
+
+ /* Now try to claim the stream. */
+ ret = png_inflate_claim(png_ptr, png_ptr->chunk_name);
+
+ if (ret == Z_OK)
+ {
+ png_uint_32 lzsize = chunklength - prefix_size;
+
+ ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
+ /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
+ /* output: */ NULL, newlength);
+
+ if (ret == Z_STREAM_END)
+ {
+ /* Use 'inflateReset' here, not 'inflateReset2' because this
+ * preserves the previously decided window size (otherwise it would
+ * be necessary to store the previous window size.) In practice
+ * this doesn't matter anyway, because png_inflate will call inflate
+ * with Z_FINISH in almost all cases, so the window will not be
+ * maintained.
+ */
+ if (inflateReset(&png_ptr->zstream) == Z_OK)
+ {
+ /* Because of the limit checks above we know that the new,
+ * expanded, size will fit in a size_t (let alone an
+ * png_alloc_size_t). Use png_malloc_base here to avoid an
+ * extra OOM message.
+ */
+ png_alloc_size_t new_size = *newlength;
+ png_alloc_size_t buffer_size = prefix_size + new_size +
+ (terminate != 0);
+ png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr,
+ buffer_size));
+
+ if (text != NULL)
+ {
+ memset(text, 0, buffer_size);
+
+ ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
+ png_ptr->read_buffer + prefix_size, &lzsize,
+ text + prefix_size, newlength);
+
+ if (ret == Z_STREAM_END)
+ {
+ if (new_size == *newlength)
+ {
+ if (terminate != 0)
+ text[prefix_size + *newlength] = 0;
+
+ if (prefix_size > 0)
+ memcpy(text, png_ptr->read_buffer, prefix_size);
+
+ {
+ png_bytep old_ptr = png_ptr->read_buffer;
+
+ png_ptr->read_buffer = text;
+ png_ptr->read_buffer_size = buffer_size;
+ text = old_ptr; /* freed below */
+ }
+ }
+
+ else
+ {
+ /* The size changed on the second read, there can be no
+ * guarantee that anything is correct at this point.
+ * The 'msg' pointer has been set to "unexpected end of
+ * LZ stream", which is fine, but return an error code
+ * that the caller won't accept.
+ */
+ ret = PNG_UNEXPECTED_ZLIB_RETURN;
+ }
+ }
+
+ else if (ret == Z_OK)
+ ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */
+
+ /* Free the text pointer (this is the old read_buffer on
+ * success)
+ */
+ png_free(png_ptr, text);
+
+ /* This really is very benign, but it's still an error because
+ * the extra space may otherwise be used as a Trojan Horse.
+ */
+ if (ret == Z_STREAM_END &&
+ chunklength - prefix_size != lzsize)
+ png_chunk_benign_error(png_ptr, "extra compressed data");
+ }
+
+ else
+ {
+ /* Out of memory allocating the buffer */
+ ret = Z_MEM_ERROR;
+ png_zstream_error(png_ptr, Z_MEM_ERROR);
+ }
+ }
+
+ else
+ {
+ /* inflateReset failed, store the error message */
+ png_zstream_error(png_ptr, ret);
+ ret = PNG_UNEXPECTED_ZLIB_RETURN;
+ }
+ }
+
+ else if (ret == Z_OK)
+ ret = PNG_UNEXPECTED_ZLIB_RETURN;
+
+ /* Release the claimed stream */
+ png_ptr->zowner = 0;
+ }
+
+ else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */
+ ret = PNG_UNEXPECTED_ZLIB_RETURN;
+
+ return ret;
+ }
+
+ else
+ {
+ /* Application/configuration limits exceeded */
+ png_zstream_error(png_ptr, Z_MEM_ERROR);
+ return Z_MEM_ERROR;
+ }
+}
+#endif /* READ_zTXt || READ_iTXt */
+#endif /* READ_COMPRESSED_TEXT */
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+/* Perform a partial read and decompress, producing 'avail_out' bytes and
+ * reading from the current chunk as required.
+ */
+static int
+png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
+ png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
+ int finish)
+{
+ if (png_ptr->zowner == png_ptr->chunk_name)
+ {
+ int ret;
+
+ /* next_in and avail_in must have been initialized by the caller. */
+ png_ptr->zstream.next_out = next_out;
+ png_ptr->zstream.avail_out = 0; /* set in the loop */
+
+ do
+ {
+ if (png_ptr->zstream.avail_in == 0)
+ {
+ if (read_size > *chunk_bytes)
+ read_size = (uInt)*chunk_bytes;
+ *chunk_bytes -= read_size;
+
+ if (read_size > 0)
+ png_crc_read(png_ptr, read_buffer, read_size);
+
+ png_ptr->zstream.next_in = read_buffer;
+ png_ptr->zstream.avail_in = read_size;
+ }
+
+ if (png_ptr->zstream.avail_out == 0)
+ {
+ uInt avail = ZLIB_IO_MAX;
+ if (avail > *out_size)
+ avail = (uInt)*out_size;
+ *out_size -= avail;
+
+ png_ptr->zstream.avail_out = avail;
+ }
+
+ /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all
+ * the available output is produced; this allows reading of truncated
+ * streams.
+ */
+ ret = PNG_INFLATE(png_ptr, *chunk_bytes > 0 ?
+ Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
+ }
+ while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
+
+ *out_size += png_ptr->zstream.avail_out;
+ png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */
+
+ /* Ensure the error message pointer is always set: */
+ png_zstream_error(png_ptr, ret);
+ return ret;
+ }
+
+ else
+ {
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed");
+ return Z_STREAM_ERROR;
+ }
+}
+#endif /* READ_iCCP */
+
+/* Read and check the IDHR chunk */
+
+void /* PRIVATE */
+png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte buf[13];
+ png_uint_32 width, height;
+ int bit_depth, color_type, compression_type, filter_type;
+ int interlace_type;
+
+ png_debug(1, "in png_handle_IHDR");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) != 0)
+ png_chunk_error(png_ptr, "out of place");
+
+ /* Check the length */
+ if (length != 13)
+ png_chunk_error(png_ptr, "invalid");
+
+ png_ptr->mode |= PNG_HAVE_IHDR;
+
+ png_crc_read(png_ptr, buf, 13);
+ png_crc_finish(png_ptr, 0);
+
+ width = png_get_uint_31(png_ptr, buf);
+ height = png_get_uint_31(png_ptr, buf + 4);
+ bit_depth = buf[8];
+ color_type = buf[9];
+ compression_type = buf[10];
+ filter_type = buf[11];
+ interlace_type = buf[12];
+
+ /* Set internal variables */
+ png_ptr->width = width;
+ png_ptr->height = height;
+ png_ptr->bit_depth = (png_byte)bit_depth;
+ png_ptr->interlaced = (png_byte)interlace_type;
+ png_ptr->color_type = (png_byte)color_type;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ png_ptr->filter_type = (png_byte)filter_type;
+#endif
+ png_ptr->compression_type = (png_byte)compression_type;
+
+ /* Find number of channels */
+ switch (png_ptr->color_type)
+ {
+ default: /* invalid, png_set_IHDR calls png_error */
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_PALETTE:
+ png_ptr->channels = 1;
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ png_ptr->channels = 3;
+ break;
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ png_ptr->channels = 2;
+ break;
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ png_ptr->channels = 4;
+ break;
+ }
+
+ /* Set up other useful info */
+ png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels);
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
+ png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
+ png_debug1(3, "channels = %d", png_ptr->channels);
+ png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
+ png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
+ color_type, interlace_type, compression_type, filter_type);
+}
+
+/* Read and check the palette */
+void /* PRIVATE */
+png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_color palette[PNG_MAX_PALETTE_LENGTH];
+ int max_palette_length, num, i;
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ png_colorp pal_ptr;
+#endif
+
+ png_debug(1, "in png_handle_PLTE");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ /* Moved to before the 'after IDAT' check below because otherwise duplicate
+ * PLTE chunks are potentially ignored (the spec says there shall not be more
+ * than one PLTE, the error is not treated as benign, so this check trumps
+ * the requirement that PLTE appears before IDAT.)
+ */
+ else if ((png_ptr->mode & PNG_HAVE_PLTE) != 0)
+ png_chunk_error(png_ptr, "duplicate");
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ {
+ /* This is benign because the non-benign error happened before, when an
+ * IDAT was encountered in a color-mapped image with no PLTE.
+ */
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ png_ptr->mode |= PNG_HAVE_PLTE;
+
+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "ignored in grayscale PNG");
+ return;
+ }
+
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
+ {
+ png_crc_finish(png_ptr, length);
+
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ png_chunk_benign_error(png_ptr, "invalid");
+
+ else
+ png_chunk_error(png_ptr, "invalid");
+
+ return;
+ }
+
+ /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */
+ num = (int)length / 3;
+
+ /* If the palette has 256 or fewer entries but is too large for the bit
+ * depth, we don't issue an error, to preserve the behavior of previous
+ * libpng versions. We silently truncate the unused extra palette entries
+ * here.
+ */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ max_palette_length = (1 << png_ptr->bit_depth);
+ else
+ max_palette_length = PNG_MAX_PALETTE_LENGTH;
+
+ if (num > max_palette_length)
+ num = max_palette_length;
+
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ pal_ptr->red = buf[0];
+ pal_ptr->green = buf[1];
+ pal_ptr->blue = buf[2];
+ }
+#else
+ for (i = 0; i < num; i++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ /* Don't depend upon png_color being any order */
+ palette[i].red = buf[0];
+ palette[i].green = buf[1];
+ palette[i].blue = buf[2];
+ }
+#endif
+
+ /* If we actually need the PLTE chunk (ie for a paletted image), we do
+ * whatever the normal CRC configuration tells us. However, if we
+ * have an RGB image, the PLTE can be considered ancillary, so
+ * we will act as though it is.
+ */
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#endif
+ {
+ png_crc_finish(png_ptr, (png_uint_32) (length - (unsigned int)num * 3));
+ }
+
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ else if (png_crc_error(png_ptr) != 0) /* Only if we have a CRC error */
+ {
+ /* If we don't want to use the data from an ancillary chunk,
+ * we have two options: an error abort, or a warning and we
+ * ignore the data in this chunk (which should be OK, since
+ * it's considered ancillary for a RGB or RGBA image).
+ *
+ * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the
+ * chunk type to determine whether to check the ancillary or the critical
+ * flags.
+ */
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE) == 0)
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) != 0)
+ return;
+
+ else
+ png_chunk_error(png_ptr, "CRC error");
+ }
+
+ /* Otherwise, we (optionally) emit a warning and use the chunk. */
+ else if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) == 0)
+ png_chunk_warning(png_ptr, "CRC error");
+ }
+#endif
+
+ /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its
+ * own copy of the palette. This has the side effect that when png_start_row
+ * is called (this happens after any call to png_read_update_info) the
+ * info_ptr palette gets changed. This is extremely unexpected and
+ * confusing.
+ *
+ * Fix this by not sharing the palette in this way.
+ */
+ png_set_PLTE(png_ptr, info_ptr, palette, num);
+
+ /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before
+ * IDAT. Prior to 1.6.0 this was not checked; instead the code merely
+ * checked the apparent validity of a tRNS chunk inserted before PLTE on a
+ * palette PNG. 1.6.0 attempts to rigorously follow the standard and
+ * therefore does a benign error if the erroneous condition is detected *and*
+ * cancels the tRNS if the benign error returns. The alternative is to
+ * amend the standard since it would be rather hypocritical of the standards
+ * maintainers to ignore it.
+ */
+#ifdef PNG_READ_tRNS_SUPPORTED
+ if (png_ptr->num_trans > 0 ||
+ (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0))
+ {
+ /* Cancel this because otherwise it would be used if the transforms
+ * require it. Don't cancel the 'valid' flag because this would prevent
+ * detection of duplicate chunks.
+ */
+ png_ptr->num_trans = 0;
+
+ if (info_ptr != NULL)
+ info_ptr->num_trans = 0;
+
+ png_chunk_benign_error(png_ptr, "tRNS must be after");
+ }
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0)
+ png_chunk_benign_error(png_ptr, "hIST must be after");
+#endif
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0)
+ png_chunk_benign_error(png_ptr, "bKGD must be after");
+#endif
+}
+
+void /* PRIVATE */
+png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_debug(1, "in png_handle_IEND");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0 ||
+ (png_ptr->mode & PNG_HAVE_IDAT) == 0)
+ png_chunk_error(png_ptr, "out of place");
+
+ png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
+
+ png_crc_finish(png_ptr, length);
+
+ if (length != 0)
+ png_chunk_benign_error(png_ptr, "invalid");
+
+ PNG_UNUSED(info_ptr)
+}
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+void /* PRIVATE */
+png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_fixed_point igamma;
+ png_byte buf[4];
+
+ png_debug(1, "in png_handle_gAMA");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ if (length != 4)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 4);
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ igamma = png_get_fixed_point(NULL, buf);
+
+ png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma);
+ png_colorspace_sync(png_ptr, info_ptr);
+}
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+void /* PRIVATE */
+png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ unsigned int truelen, i;
+ png_byte sample_depth;
+ png_byte buf[4];
+
+ png_debug(1, "in png_handle_sBIT");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ truelen = 3;
+ sample_depth = 8;
+ }
+
+ else
+ {
+ truelen = png_ptr->channels;
+ sample_depth = png_ptr->bit_depth;
+ }
+
+ if (length != truelen || length > 4)
+ {
+ png_chunk_benign_error(png_ptr, "invalid");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ buf[0] = buf[1] = buf[2] = buf[3] = sample_depth;
+ png_crc_read(png_ptr, buf, truelen);
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ for (i=0; i<truelen; ++i)
+ {
+ if (buf[i] == 0 || buf[i] > sample_depth)
+ {
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+ }
+
+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ {
+ png_ptr->sig_bit.red = buf[0];
+ png_ptr->sig_bit.green = buf[1];
+ png_ptr->sig_bit.blue = buf[2];
+ png_ptr->sig_bit.alpha = buf[3];
+ }
+
+ else
+ {
+ png_ptr->sig_bit.gray = buf[0];
+ png_ptr->sig_bit.red = buf[0];
+ png_ptr->sig_bit.green = buf[0];
+ png_ptr->sig_bit.blue = buf[0];
+ png_ptr->sig_bit.alpha = buf[1];
+ }
+
+ png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
+}
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+void /* PRIVATE */
+png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte buf[32];
+ png_xy xy;
+
+ png_debug(1, "in png_handle_cHRM");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ if (length != 32)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 32);
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ xy.whitex = png_get_fixed_point(NULL, buf);
+ xy.whitey = png_get_fixed_point(NULL, buf + 4);
+ xy.redx = png_get_fixed_point(NULL, buf + 8);
+ xy.redy = png_get_fixed_point(NULL, buf + 12);
+ xy.greenx = png_get_fixed_point(NULL, buf + 16);
+ xy.greeny = png_get_fixed_point(NULL, buf + 20);
+ xy.bluex = png_get_fixed_point(NULL, buf + 24);
+ xy.bluey = png_get_fixed_point(NULL, buf + 28);
+
+ if (xy.whitex == PNG_FIXED_ERROR ||
+ xy.whitey == PNG_FIXED_ERROR ||
+ xy.redx == PNG_FIXED_ERROR ||
+ xy.redy == PNG_FIXED_ERROR ||
+ xy.greenx == PNG_FIXED_ERROR ||
+ xy.greeny == PNG_FIXED_ERROR ||
+ xy.bluex == PNG_FIXED_ERROR ||
+ xy.bluey == PNG_FIXED_ERROR)
+ {
+ png_chunk_benign_error(png_ptr, "invalid values");
+ return;
+ }
+
+ /* If a colorspace error has already been output skip this chunk */
+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
+ return;
+
+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0)
+ {
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+ png_colorspace_sync(png_ptr, info_ptr);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+ (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy,
+ 1/*prefer cHRM values*/);
+ png_colorspace_sync(png_ptr, info_ptr);
+}
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+void /* PRIVATE */
+png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte intent;
+
+ png_debug(1, "in png_handle_sRGB");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ if (length != 1)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, &intent, 1);
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ /* If a colorspace error has already been output skip this chunk */
+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
+ return;
+
+ /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
+ * this.
+ */
+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) != 0)
+ {
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+ png_colorspace_sync(png_ptr, info_ptr);
+ png_chunk_benign_error(png_ptr, "too many profiles");
+ return;
+ }
+
+ (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent);
+ png_colorspace_sync(png_ptr, info_ptr);
+}
+#endif /* READ_sRGB */
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+void /* PRIVATE */
+png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+/* Note: this does not properly handle profiles that are > 64K under DOS */
+{
+ png_const_charp errmsg = NULL; /* error message output, or no error */
+ int finished = 0; /* crc checked */
+
+ png_debug(1, "in png_handle_iCCP");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE)) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ /* Consistent with all the above colorspace handling an obviously *invalid*
+ * chunk is just ignored, so does not invalidate the color space. An
+ * alternative is to set the 'invalid' flags at the start of this routine
+ * and only clear them in they were not set before and all the tests pass.
+ */
+
+ /* The keyword must be at least one character and there is a
+ * terminator (0) byte and the compression method byte, and the
+ * 'zlib' datastream is at least 11 bytes.
+ */
+ if (length < 14)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too short");
+ return;
+ }
+
+ /* If a colorspace error has already been output skip this chunk */
+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
+ * this.
+ */
+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0)
+ {
+ uInt read_length, keyword_length;
+ char keyword[81];
+
+ /* Find the keyword; the keyword plus separator and compression method
+ * bytes can be at most 81 characters long.
+ */
+ read_length = 81; /* maximum */
+ if (read_length > length)
+ read_length = (uInt)length;
+
+ png_crc_read(png_ptr, (png_bytep)keyword, read_length);
+ length -= read_length;
+
+ /* The minimum 'zlib' stream is assumed to be just the 2 byte header,
+ * 5 bytes minimum 'deflate' stream, and the 4 byte checksum.
+ */
+ if (length < 11)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too short");
+ return;
+ }
+
+ keyword_length = 0;
+ while (keyword_length < 80 && keyword_length < read_length &&
+ keyword[keyword_length] != 0)
+ ++keyword_length;
+
+ /* TODO: make the keyword checking common */
+ if (keyword_length >= 1 && keyword_length <= 79)
+ {
+ /* We only understand '0' compression - deflate - so if we get a
+ * different value we can't safely decode the chunk.
+ */
+ if (keyword_length+1 < read_length &&
+ keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE)
+ {
+ read_length -= keyword_length+2;
+
+ if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK)
+ {
+ Byte profile_header[132]={0};
+ Byte local_buffer[PNG_INFLATE_BUF_SIZE];
+ png_alloc_size_t size = (sizeof profile_header);
+
+ png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
+ png_ptr->zstream.avail_in = read_length;
+ (void)png_inflate_read(png_ptr, local_buffer,
+ (sizeof local_buffer), &length, profile_header, &size,
+ 0/*finish: don't, because the output is too small*/);
+
+ if (size == 0)
+ {
+ /* We have the ICC profile header; do the basic header checks.
+ */
+ const png_uint_32 profile_length =
+ png_get_uint_32(profile_header);
+
+ if (png_icc_check_length(png_ptr, &png_ptr->colorspace,
+ keyword, profile_length) != 0)
+ {
+ /* The length is apparently ok, so we can check the 132
+ * byte header.
+ */
+ if (png_icc_check_header(png_ptr, &png_ptr->colorspace,
+ keyword, profile_length, profile_header,
+ png_ptr->color_type) != 0)
+ {
+ /* Now read the tag table; a variable size buffer is
+ * needed at this point, allocate one for the whole
+ * profile. The header check has already validated
+ * that none of this stuff will overflow.
+ */
+ const png_uint_32 tag_count = png_get_uint_32(
+ profile_header+128);
+ png_bytep profile = png_read_buffer(png_ptr,
+ profile_length, 2/*silent*/);
+
+ if (profile != NULL)
+ {
+ memcpy(profile, profile_header,
+ (sizeof profile_header));
+
+ size = 12 * tag_count;
+
+ (void)png_inflate_read(png_ptr, local_buffer,
+ (sizeof local_buffer), &length,
+ profile + (sizeof profile_header), &size, 0);
+
+ /* Still expect a buffer error because we expect
+ * there to be some tag data!
+ */
+ if (size == 0)
+ {
+ if (png_icc_check_tag_table(png_ptr,
+ &png_ptr->colorspace, keyword, profile_length,
+ profile) != 0)
+ {
+ /* The profile has been validated for basic
+ * security issues, so read the whole thing in.
+ */
+ size = profile_length - (sizeof profile_header)
+ - 12 * tag_count;
+
+ (void)png_inflate_read(png_ptr, local_buffer,
+ (sizeof local_buffer), &length,
+ profile + (sizeof profile_header) +
+ 12 * tag_count, &size, 1/*finish*/);
+
+ if (length > 0 && !(png_ptr->flags &
+ PNG_FLAG_BENIGN_ERRORS_WARN))
+ errmsg = "extra compressed data";
+
+ /* But otherwise allow extra data: */
+ else if (size == 0)
+ {
+ if (length > 0)
+ {
+ /* This can be handled completely, so
+ * keep going.
+ */
+ png_chunk_warning(png_ptr,
+ "extra compressed data");
+ }
+
+ png_crc_finish(png_ptr, length);
+ finished = 1;
+
+# if defined(PNG_sRGB_SUPPORTED) && PNG_sRGB_PROFILE_CHECKS >= 0
+ /* Check for a match against sRGB */
+ png_icc_set_sRGB(png_ptr,
+ &png_ptr->colorspace, profile,
+ png_ptr->zstream.adler);
+# endif
+
+ /* Steal the profile for info_ptr. */
+ if (info_ptr != NULL)
+ {
+ png_free_data(png_ptr, info_ptr,
+ PNG_FREE_ICCP, 0);
+
+ info_ptr->iccp_name = png_voidcast(char*,
+ png_malloc_base(png_ptr,
+ keyword_length+1));
+ if (info_ptr->iccp_name != NULL)
+ {
+ memcpy(info_ptr->iccp_name, keyword,
+ keyword_length+1);
+ info_ptr->iccp_proflen =
+ profile_length;
+ info_ptr->iccp_profile = profile;
+ png_ptr->read_buffer = NULL; /*steal*/
+ info_ptr->free_me |= PNG_FREE_ICCP;
+ info_ptr->valid |= PNG_INFO_iCCP;
+ }
+
+ else
+ {
+ png_ptr->colorspace.flags |=
+ PNG_COLORSPACE_INVALID;
+ errmsg = "out of memory";
+ }
+ }
+
+ /* else the profile remains in the read
+ * buffer which gets reused for subsequent
+ * chunks.
+ */
+
+ if (info_ptr != NULL)
+ png_colorspace_sync(png_ptr, info_ptr);
+
+ if (errmsg == NULL)
+ {
+ png_ptr->zowner = 0;
+ return;
+ }
+ }
+ if (errmsg == NULL)
+ errmsg = png_ptr->zstream.msg;
+ }
+ /* else png_icc_check_tag_table output an error */
+ }
+ else /* profile truncated */
+ errmsg = png_ptr->zstream.msg;
+ }
+
+ else
+ errmsg = "out of memory";
+ }
+
+ /* else png_icc_check_header output an error */
+ }
+
+ /* else png_icc_check_length output an error */
+ }
+
+ else /* profile truncated */
+ errmsg = png_ptr->zstream.msg;
+
+ /* Release the stream */
+ png_ptr->zowner = 0;
+ }
+
+ else /* png_inflate_claim failed */
+ errmsg = png_ptr->zstream.msg;
+ }
+
+ else
+ errmsg = "bad compression method"; /* or missing */
+ }
+
+ else
+ errmsg = "bad keyword";
+ }
+
+ else
+ errmsg = "too many profiles";
+
+ /* Failure: the reason is in 'errmsg' */
+ if (finished == 0)
+ png_crc_finish(png_ptr, length);
+
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+ png_colorspace_sync(png_ptr, info_ptr);
+ if (errmsg != NULL) /* else already output */
+ png_chunk_benign_error(png_ptr, errmsg);
+}
+#endif /* READ_iCCP */
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+void /* PRIVATE */
+png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+ png_bytep entry_start, buffer;
+ png_sPLT_t new_palette;
+ png_sPLT_entryp pp;
+ png_uint_32 data_length;
+ int entry_size, i;
+ png_uint_32 skip = 0;
+ png_uint_32 dl;
+ png_size_t max_dl;
+
+ png_debug(1, "in png_handle_sPLT");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_warning(png_ptr, "No space in chunk cache for sPLT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ }
+#endif
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > 65535U)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too large to fit in memory");
+ return;
+ }
+#endif
+
+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+ if (buffer == NULL)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+
+ /* WARNING: this may break if size_t is less than 32 bits; it is assumed
+ * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
+ * potential breakage point if the types in pngconf.h aren't exactly right.
+ */
+ png_crc_read(png_ptr, buffer, length);
+
+ if (png_crc_finish(png_ptr, skip) != 0)
+ return;
+
+ buffer[length] = 0;
+
+ for (entry_start = buffer; *entry_start; entry_start++)
+ /* Empty loop to find end of name */ ;
+
+ ++entry_start;
+
+ /* A sample depth should follow the separator, and we should be on it */
+ if (length < 2U || entry_start > buffer + (length - 2U))
+ {
+ png_warning(png_ptr, "malformed sPLT chunk");
+ return;
+ }
+
+ new_palette.depth = *entry_start++;
+ entry_size = (new_palette.depth == 8 ? 6 : 10);
+ /* This must fit in a png_uint_32 because it is derived from the original
+ * chunk data length.
+ */
+ data_length = length - (png_uint_32)(entry_start - buffer);
+
+ /* Integrity-check the data length */
+ if ((data_length % (unsigned int)entry_size) != 0)
+ {
+ png_warning(png_ptr, "sPLT chunk has bad length");
+ return;
+ }
+
+ dl = (png_uint_32)(data_length / (unsigned int)entry_size);
+ max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry));
+
+ if (dl > max_dl)
+ {
+ png_warning(png_ptr, "sPLT chunk too long");
+ return;
+ }
+
+ new_palette.nentries = (png_int_32)(data_length / (unsigned int)entry_size);
+
+ new_palette.entries = (png_sPLT_entryp)png_malloc_warn(png_ptr,
+ (png_alloc_size_t) new_palette.nentries * (sizeof (png_sPLT_entry)));
+
+ if (new_palette.entries == NULL)
+ {
+ png_warning(png_ptr, "sPLT chunk requires too much memory");
+ return;
+ }
+
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ for (i = 0; i < new_palette.nentries; i++)
+ {
+ pp = new_palette.entries + i;
+
+ if (new_palette.depth == 8)
+ {
+ pp->red = *entry_start++;
+ pp->green = *entry_start++;
+ pp->blue = *entry_start++;
+ pp->alpha = *entry_start++;
+ }
+
+ else
+ {
+ pp->red = png_get_uint_16(entry_start); entry_start += 2;
+ pp->green = png_get_uint_16(entry_start); entry_start += 2;
+ pp->blue = png_get_uint_16(entry_start); entry_start += 2;
+ pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
+ }
+
+ pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+ }
+#else
+ pp = new_palette.entries;
+
+ for (i = 0; i < new_palette.nentries; i++)
+ {
+
+ if (new_palette.depth == 8)
+ {
+ pp[i].red = *entry_start++;
+ pp[i].green = *entry_start++;
+ pp[i].blue = *entry_start++;
+ pp[i].alpha = *entry_start++;
+ }
+
+ else
+ {
+ pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
+ }
+
+ pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
+ }
+#endif
+
+ /* Discard all chunk data except the name and stash that */
+ new_palette.name = (png_charp)buffer;
+
+ png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
+
+ png_free(png_ptr, new_palette.entries);
+}
+#endif /* READ_sPLT */
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+void /* PRIVATE */
+png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
+
+ png_debug(1, "in png_handle_tRNS");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_byte buf[2];
+
+ if (length != 2)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 2);
+ png_ptr->num_trans = 1;
+ png_ptr->trans_color.gray = png_get_uint_16(buf);
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_byte buf[6];
+
+ if (length != 6)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, length);
+ png_ptr->num_trans = 1;
+ png_ptr->trans_color.red = png_get_uint_16(buf);
+ png_ptr->trans_color.green = png_get_uint_16(buf + 2);
+ png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if ((png_ptr->mode & PNG_HAVE_PLTE) == 0)
+ {
+ /* TODO: is this actually an error in the ISO spec? */
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ if (length > (unsigned int) png_ptr->num_palette ||
+ length > (unsigned int) PNG_MAX_PALETTE_LENGTH ||
+ length == 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, readbuf, length);
+ png_ptr->num_trans = (png_uint_16)length;
+ }
+
+ else
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid with alpha channel");
+ return;
+ }
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ {
+ png_ptr->num_trans = 0;
+ return;
+ }
+
+ /* TODO: this is a horrible side effect in the palette case because the
+ * png_struct ends up with a pointer to the tRNS buffer owned by the
+ * png_info. Fix this.
+ */
+ png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
+ &(png_ptr->trans_color));
+}
+#endif
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+void /* PRIVATE */
+png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ unsigned int truelen;
+ png_byte buf[6];
+ png_color_16 background;
+
+ png_debug(1, "in png_handle_bKGD");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 ||
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ (png_ptr->mode & PNG_HAVE_PLTE) == 0))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ truelen = 1;
+
+ else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ truelen = 6;
+
+ else
+ truelen = 2;
+
+ if (length != truelen)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, truelen);
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ /* We convert the index value into RGB components so that we can allow
+ * arbitrary RGB values for background when we have transparency, and
+ * so it is easy to determine the RGB values of the background color
+ * from the info_ptr struct.
+ */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ background.index = buf[0];
+
+ if (info_ptr != NULL && info_ptr->num_palette != 0)
+ {
+ if (buf[0] >= info_ptr->num_palette)
+ {
+ png_chunk_benign_error(png_ptr, "invalid index");
+ return;
+ }
+
+ background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
+ background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
+ background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
+ }
+
+ else
+ background.red = background.green = background.blue = 0;
+
+ background.gray = 0;
+ }
+
+ else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */
+ {
+ background.index = 0;
+ background.red =
+ background.green =
+ background.blue =
+ background.gray = png_get_uint_16(buf);
+ }
+
+ else
+ {
+ background.index = 0;
+ background.red = png_get_uint_16(buf);
+ background.green = png_get_uint_16(buf + 2);
+ background.blue = png_get_uint_16(buf + 4);
+ background.gray = 0;
+ }
+
+ png_set_bKGD(png_ptr, info_ptr, &background);
+}
+#endif
+
+#ifdef PNG_READ_eXIf_SUPPORTED
+void /* PRIVATE */
+png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ unsigned int i;
+
+ png_debug(1, "in png_handle_eXIf");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ if (length < 2)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too short");
+ return;
+ }
+
+ else if (info_ptr == NULL || (info_ptr->valid & PNG_INFO_eXIf) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ info_ptr->free_me |= PNG_FREE_EXIF;
+
+ info_ptr->eXIf_buf = png_voidcast(png_bytep,
+ png_malloc_warn(png_ptr, length));
+
+ if (info_ptr->eXIf_buf == NULL)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ for (i = 0; i < length; i++)
+ {
+ png_byte buf[1];
+ png_crc_read(png_ptr, buf, 1);
+ info_ptr->eXIf_buf[i] = buf[0];
+ if (i == 1 && buf[0] != 'M' && buf[0] != 'I'
+ && info_ptr->eXIf_buf[0] != buf[0])
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "incorrect byte-order specifier");
+ png_free(png_ptr, info_ptr->eXIf_buf);
+ info_ptr->eXIf_buf = NULL;
+ return;
+ }
+ }
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ png_set_eXIf_1(png_ptr, info_ptr, length, info_ptr->eXIf_buf);
+
+ png_free(png_ptr, info_ptr->eXIf_buf);
+ info_ptr->eXIf_buf = NULL;
+}
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+void /* PRIVATE */
+png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ unsigned int num, i;
+ png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
+
+ png_debug(1, "in png_handle_hIST");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0 ||
+ (png_ptr->mode & PNG_HAVE_PLTE) == 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ num = length / 2 ;
+
+ if (num != (unsigned int) png_ptr->num_palette ||
+ num > (unsigned int) PNG_MAX_PALETTE_LENGTH)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ for (i = 0; i < num; i++)
+ {
+ png_byte buf[2];
+
+ png_crc_read(png_ptr, buf, 2);
+ readbuf[i] = png_get_uint_16(buf);
+ }
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ png_set_hIST(png_ptr, info_ptr, readbuf);
+}
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+void /* PRIVATE */
+png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte buf[9];
+ png_uint_32 res_x, res_y;
+ int unit_type;
+
+ png_debug(1, "in png_handle_pHYs");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 9);
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ res_x = png_get_uint_32(buf);
+ res_y = png_get_uint_32(buf + 4);
+ unit_type = buf[8];
+ png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
+}
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+void /* PRIVATE */
+png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte buf[9];
+ png_int_32 offset_x, offset_y;
+ int unit_type;
+
+ png_debug(1, "in png_handle_oFFs");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 9);
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ offset_x = png_get_int_32(buf);
+ offset_y = png_get_int_32(buf + 4);
+ unit_type = buf[8];
+ png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
+}
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+/* Read the pCAL chunk (described in the PNG Extensions document) */
+void /* PRIVATE */
+png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_int_32 X0, X1;
+ png_byte type, nparams;
+ png_bytep buffer, buf, units, endptr;
+ png_charpp params;
+ int i;
+
+ png_debug(1, "in png_handle_pCAL");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
+ length + 1);
+
+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+
+ if (buffer == NULL)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ png_crc_read(png_ptr, buffer, length);
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ buffer[length] = 0; /* Null terminate the last string */
+
+ png_debug(3, "Finding end of pCAL purpose string");
+ for (buf = buffer; *buf; buf++)
+ /* Empty loop */ ;
+
+ endptr = buffer + length;
+
+ /* We need to have at least 12 bytes after the purpose string
+ * in order to get the parameter information.
+ */
+ if (endptr - buf <= 12)
+ {
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
+ X0 = png_get_int_32((png_bytep)buf+1);
+ X1 = png_get_int_32((png_bytep)buf+5);
+ type = buf[9];
+ nparams = buf[10];
+ units = buf + 11;
+
+ png_debug(3, "Checking pCAL equation type and number of parameters");
+ /* Check that we have the right number of parameters for known
+ * equation types.
+ */
+ if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
+ (type == PNG_EQUATION_BASE_E && nparams != 3) ||
+ (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
+ (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
+ {
+ png_chunk_benign_error(png_ptr, "invalid parameter count");
+ return;
+ }
+
+ else if (type >= PNG_EQUATION_LAST)
+ {
+ png_chunk_benign_error(png_ptr, "unrecognized equation type");
+ }
+
+ for (buf = units; *buf; buf++)
+ /* Empty loop to move past the units string. */ ;
+
+ png_debug(3, "Allocating pCAL parameters array");
+
+ params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
+ nparams * (sizeof (png_charp))));
+
+ if (params == NULL)
+ {
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ /* Get pointers to the start of each parameter string. */
+ for (i = 0; i < nparams; i++)
+ {
+ buf++; /* Skip the null string terminator from previous parameter. */
+
+ png_debug1(3, "Reading pCAL parameter %d", i);
+
+ for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++)
+ /* Empty loop to move past each parameter string */ ;
+
+ /* Make sure we haven't run out of data yet */
+ if (buf > endptr)
+ {
+ png_free(png_ptr, params);
+ png_chunk_benign_error(png_ptr, "invalid data");
+ return;
+ }
+ }
+
+ png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,
+ (png_charp)units, params);
+
+ png_free(png_ptr, params);
+}
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+/* Read the sCAL chunk */
+void /* PRIVATE */
+png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_bytep buffer;
+ png_size_t i;
+ int state;
+
+ png_debug(1, "in png_handle_sCAL");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ /* Need unit type, width, \0, height: minimum 4 bytes */
+ else if (length < 4)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
+ length + 1);
+
+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+
+ if (buffer == NULL)
+ {
+ png_chunk_benign_error(png_ptr, "out of memory");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buffer, length);
+ buffer[length] = 0; /* Null terminate the last string */
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ /* Validate the unit. */
+ if (buffer[0] != 1 && buffer[0] != 2)
+ {
+ png_chunk_benign_error(png_ptr, "invalid unit");
+ return;
+ }
+
+ /* Validate the ASCII numbers, need two ASCII numbers separated by
+ * a '\0' and they need to fit exactly in the chunk data.
+ */
+ i = 1;
+ state = 0;
+
+ if (png_check_fp_number((png_const_charp)buffer, length, &state, &i) == 0 ||
+ i >= length || buffer[i++] != 0)
+ png_chunk_benign_error(png_ptr, "bad width format");
+
+ else if (PNG_FP_IS_POSITIVE(state) == 0)
+ png_chunk_benign_error(png_ptr, "non-positive width");
+
+ else
+ {
+ png_size_t heighti = i;
+
+ state = 0;
+ if (png_check_fp_number((png_const_charp)buffer, length,
+ &state, &i) == 0 || i != length)
+ png_chunk_benign_error(png_ptr, "bad height format");
+
+ else if (PNG_FP_IS_POSITIVE(state) == 0)
+ png_chunk_benign_error(png_ptr, "non-positive height");
+
+ else
+ /* This is the (only) success case. */
+ png_set_sCAL_s(png_ptr, info_ptr, buffer[0],
+ (png_charp)buffer+1, (png_charp)buffer+heighti);
+ }
+}
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+void /* PRIVATE */
+png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte buf[7];
+ png_time mod_time;
+
+ png_debug(1, "in png_handle_tIME");
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) != 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ if (length != 7)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 7);
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ mod_time.second = buf[6];
+ mod_time.minute = buf[5];
+ mod_time.hour = buf[4];
+ mod_time.day = buf[3];
+ mod_time.month = buf[2];
+ mod_time.year = png_get_uint_16(buf);
+
+ png_set_tIME(png_ptr, info_ptr, &mod_time);
+}
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_text text_info;
+ png_bytep buffer;
+ png_charp key;
+ png_charp text;
+ png_uint_32 skip = 0;
+
+ png_debug(1, "in png_handle_tEXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "no space in chunk cache");
+ return;
+ }
+ }
+#endif
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > 65535U)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too large to fit in memory");
+ return;
+ }
+#endif
+
+ buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
+
+ if (buffer == NULL)
+ {
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ png_crc_read(png_ptr, buffer, length);
+
+ if (png_crc_finish(png_ptr, skip) != 0)
+ return;
+
+ key = (png_charp)buffer;
+ key[length] = 0;
+
+ for (text = key; *text; text++)
+ /* Empty loop to find end of key */ ;
+
+ if (text != key + length)
+ text++;
+
+ text_info.compression = PNG_TEXT_COMPRESSION_NONE;
+ text_info.key = key;
+ text_info.lang = NULL;
+ text_info.lang_key = NULL;
+ text_info.itxt_length = 0;
+ text_info.text = text;
+ text_info.text_length = strlen(text);
+
+ if (png_set_text_2(png_ptr, info_ptr, &text_info, 1) != 0)
+ png_warning(png_ptr, "Insufficient memory to process text chunk");
+}
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+/* Note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_const_charp errmsg = NULL;
+ png_bytep buffer;
+ png_uint_32 keyword_length;
+
+ png_debug(1, "in png_handle_zTXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "no space in chunk cache");
+ return;
+ }
+ }
+#endif
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ /* Note, "length" is sufficient here; we won't be adding
+ * a null terminator later.
+ */
+ buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
+
+ if (buffer == NULL)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ png_crc_read(png_ptr, buffer, length);
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ /* TODO: also check that the keyword contents match the spec! */
+ for (keyword_length = 0;
+ keyword_length < length && buffer[keyword_length] != 0;
+ ++keyword_length)
+ /* Empty loop to find end of name */ ;
+
+ if (keyword_length > 79 || keyword_length < 1)
+ errmsg = "bad keyword";
+
+ /* zTXt must have some LZ data after the keyword, although it may expand to
+ * zero bytes; we need a '\0' at the end of the keyword, the compression type
+ * then the LZ data:
+ */
+ else if (keyword_length + 3 > length)
+ errmsg = "truncated";
+
+ else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE)
+ errmsg = "unknown compression type";
+
+ else
+ {
+ png_alloc_size_t uncompressed_length = PNG_SIZE_MAX;
+
+ /* TODO: at present png_decompress_chunk imposes a single application
+ * level memory limit, this should be split to different values for iCCP
+ * and text chunks.
+ */
+ if (png_decompress_chunk(png_ptr, length, keyword_length+2,
+ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+ {
+ png_text text;
+
+ if (png_ptr->read_buffer == NULL)
+ errmsg="Read failure in png_handle_zTXt";
+ else
+ {
+ /* It worked; png_ptr->read_buffer now looks like a tEXt chunk
+ * except for the extra compression type byte and the fact that
+ * it isn't necessarily '\0' terminated.
+ */
+ buffer = png_ptr->read_buffer;
+ buffer[uncompressed_length+(keyword_length+2)] = 0;
+
+ text.compression = PNG_TEXT_COMPRESSION_zTXt;
+ text.key = (png_charp)buffer;
+ text.text = (png_charp)(buffer + keyword_length+2);
+ text.text_length = uncompressed_length;
+ text.itxt_length = 0;
+ text.lang = NULL;
+ text.lang_key = NULL;
+
+ if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
+ errmsg = "insufficient memory";
+ }
+ }
+
+ else
+ errmsg = png_ptr->zstream.msg;
+ }
+
+ if (errmsg != NULL)
+ png_chunk_benign_error(png_ptr, errmsg);
+}
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+/* Note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_const_charp errmsg = NULL;
+ png_bytep buffer;
+ png_uint_32 prefix_length;
+
+ png_debug(1, "in png_handle_iTXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "no space in chunk cache");
+ return;
+ }
+ }
+#endif
+
+ if ((png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
+
+ if (buffer == NULL)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ png_crc_read(png_ptr, buffer, length);
+
+ if (png_crc_finish(png_ptr, 0) != 0)
+ return;
+
+ /* First the keyword. */
+ for (prefix_length=0;
+ prefix_length < length && buffer[prefix_length] != 0;
+ ++prefix_length)
+ /* Empty loop */ ;
+
+ /* Perform a basic check on the keyword length here. */
+ if (prefix_length > 79 || prefix_length < 1)
+ errmsg = "bad keyword";
+
+ /* Expect keyword, compression flag, compression type, language, translated
+ * keyword (both may be empty but are 0 terminated) then the text, which may
+ * be empty.
+ */
+ else if (prefix_length + 5 > length)
+ errmsg = "truncated";
+
+ else if (buffer[prefix_length+1] == 0 ||
+ (buffer[prefix_length+1] == 1 &&
+ buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE))
+ {
+ int compressed = buffer[prefix_length+1] != 0;
+ png_uint_32 language_offset, translated_keyword_offset;
+ png_alloc_size_t uncompressed_length = 0;
+
+ /* Now the language tag */
+ prefix_length += 3;
+ language_offset = prefix_length;
+
+ for (; prefix_length < length && buffer[prefix_length] != 0;
+ ++prefix_length)
+ /* Empty loop */ ;
+
+ /* WARNING: the length may be invalid here, this is checked below. */
+ translated_keyword_offset = ++prefix_length;
+
+ for (; prefix_length < length && buffer[prefix_length] != 0;
+ ++prefix_length)
+ /* Empty loop */ ;
+
+ /* prefix_length should now be at the trailing '\0' of the translated
+ * keyword, but it may already be over the end. None of this arithmetic
+ * can overflow because chunks are at most 2^31 bytes long, but on 16-bit
+ * systems the available allocation may overflow.
+ */
+ ++prefix_length;
+
+ if (compressed == 0 && prefix_length <= length)
+ uncompressed_length = length - prefix_length;
+
+ else if (compressed != 0 && prefix_length < length)
+ {
+ uncompressed_length = PNG_SIZE_MAX;
+
+ /* TODO: at present png_decompress_chunk imposes a single application
+ * level memory limit, this should be split to different values for
+ * iCCP and text chunks.
+ */
+ if (png_decompress_chunk(png_ptr, length, prefix_length,
+ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+ buffer = png_ptr->read_buffer;
+
+ else
+ errmsg = png_ptr->zstream.msg;
+ }
+
+ else
+ errmsg = "truncated";
+
+ if (errmsg == NULL)
+ {
+ png_text text;
+
+ buffer[uncompressed_length+prefix_length] = 0;
+
+ if (compressed == 0)
+ text.compression = PNG_ITXT_COMPRESSION_NONE;
+
+ else
+ text.compression = PNG_ITXT_COMPRESSION_zTXt;
+
+ text.key = (png_charp)buffer;
+ text.lang = (png_charp)buffer + language_offset;
+ text.lang_key = (png_charp)buffer + translated_keyword_offset;
+ text.text = (png_charp)buffer + prefix_length;
+ text.text_length = 0;
+ text.itxt_length = uncompressed_length;
+
+ if (png_set_text_2(png_ptr, info_ptr, &text, 1) != 0)
+ errmsg = "insufficient memory";
+ }
+ }
+
+ else
+ errmsg = "bad compression info";
+
+ if (errmsg != NULL)
+ png_chunk_benign_error(png_ptr, errmsg);
+}
+#endif
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
+static int
+png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
+{
+ png_alloc_size_t limit = PNG_SIZE_MAX;
+
+ if (png_ptr->unknown_chunk.data != NULL)
+ {
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
+ }
+
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_malloc_max > 0 &&
+ png_ptr->user_chunk_malloc_max < limit)
+ limit = png_ptr->user_chunk_malloc_max;
+
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+ if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+ limit = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+
+ if (length <= limit)
+ {
+ PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
+ /* The following is safe because of the PNG_SIZE_MAX init above */
+ png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/;
+ /* 'mode' is a flag array, only the bottom four bits matter here */
+ png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/;
+
+ if (length == 0)
+ png_ptr->unknown_chunk.data = NULL;
+
+ else
+ {
+ /* Do a 'warn' here - it is handled below. */
+ png_ptr->unknown_chunk.data = png_voidcast(png_bytep,
+ png_malloc_warn(png_ptr, length));
+ }
+ }
+
+ if (png_ptr->unknown_chunk.data == NULL && length > 0)
+ {
+ /* This is benign because we clean up correctly */
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits");
+ return 0;
+ }
+
+ else
+ {
+ if (length > 0)
+ png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length);
+ png_crc_finish(png_ptr, 0);
+ return 1;
+ }
+}
+#endif /* READ_UNKNOWN_CHUNKS */
+
+/* Handle an unknown, or known but disabled, chunk */
+void /* PRIVATE */
+png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
+ png_uint_32 length, int keep)
+{
+ int handled = 0; /* the chunk was handled */
+
+ png_debug(1, "in png_handle_unknown");
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+ /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing
+ * the bug which meant that setting a non-default behavior for a specific
+ * chunk would be ignored (the default was always used unless a user
+ * callback was installed).
+ *
+ * 'keep' is the value from the png_chunk_unknown_handling, the setting for
+ * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it
+ * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here.
+ * This is just an optimization to avoid multiple calls to the lookup
+ * function.
+ */
+# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
+# endif
+# endif
+
+ /* One of the following methods will read the chunk or skip it (at least one
+ * of these is always defined because this is the only way to switch on
+ * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ */
+# ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+ /* The user callback takes precedence over the chunk keep value, but the
+ * keep value is still required to validate a save of a critical chunk.
+ */
+ if (png_ptr->read_user_chunk_fn != NULL)
+ {
+ if (png_cache_unknown_chunk(png_ptr, length) != 0)
+ {
+ /* Callback to user unknown chunk handler */
+ int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr,
+ &png_ptr->unknown_chunk);
+
+ /* ret is:
+ * negative: An error occurred; png_chunk_error will be called.
+ * zero: The chunk was not handled, the chunk will be discarded
+ * unless png_set_keep_unknown_chunks has been used to set
+ * a 'keep' behavior for this particular chunk, in which
+ * case that will be used. A critical chunk will cause an
+ * error at this point unless it is to be saved.
+ * positive: The chunk was handled, libpng will ignore/discard it.
+ */
+ if (ret < 0)
+ png_chunk_error(png_ptr, "error in user chunk");
+
+ else if (ret == 0)
+ {
+ /* If the keep value is 'default' or 'never' override it, but
+ * still error out on critical chunks unless the keep value is
+ * 'always' While this is weird it is the behavior in 1.4.12.
+ * A possible improvement would be to obey the value set for the
+ * chunk, but this would be an API change that would probably
+ * damage some applications.
+ *
+ * The png_app_warning below catches the case that matters, where
+ * the application has not set specific save or ignore for this
+ * chunk or global save or ignore.
+ */
+ if (keep < PNG_HANDLE_CHUNK_IF_SAFE)
+ {
+# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE)
+ {
+ png_chunk_warning(png_ptr, "Saving unknown chunk:");
+ png_app_warning(png_ptr,
+ "forcing save of an unhandled chunk;"
+ " please call png_set_keep_unknown_chunks");
+ /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
+ }
+# endif
+ keep = PNG_HANDLE_CHUNK_IF_SAFE;
+ }
+ }
+
+ else /* chunk was handled */
+ {
+ handled = 1;
+ /* Critical chunks can be safely discarded at this point. */
+ keep = PNG_HANDLE_CHUNK_NEVER;
+ }
+ }
+
+ else
+ keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */
+ }
+
+ else
+ /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */
+# endif /* READ_USER_CHUNKS */
+
+# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
+ {
+ /* keep is currently just the per-chunk setting, if there was no
+ * setting change it to the global default now (not that this may
+ * still be AS_DEFAULT) then obtain the cache of the chunk if required,
+ * if not simply skip the chunk.
+ */
+ if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)
+ keep = png_ptr->unknown_default;
+
+ if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
+ PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
+ {
+ if (png_cache_unknown_chunk(png_ptr, length) == 0)
+ keep = PNG_HANDLE_CHUNK_NEVER;
+ }
+
+ else
+ png_crc_finish(png_ptr, length);
+ }
+# else
+# ifndef PNG_READ_USER_CHUNKS_SUPPORTED
+# error no method to support READ_UNKNOWN_CHUNKS
+# endif
+
+ {
+ /* If here there is no read callback pointer set and no support is
+ * compiled in to just save the unknown chunks, so simply skip this
+ * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then
+ * the app has erroneously asked for unknown chunk saving when there
+ * is no support.
+ */
+ if (keep > PNG_HANDLE_CHUNK_NEVER)
+ png_app_error(png_ptr, "no unknown chunk support available");
+
+ png_crc_finish(png_ptr, length);
+ }
+# endif
+
+# ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+ /* Now store the chunk in the chunk list if appropriate, and if the limits
+ * permit it.
+ */
+ if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
+ PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
+ {
+# ifdef PNG_USER_LIMITS_SUPPORTED
+ switch (png_ptr->user_chunk_cache_max)
+ {
+ case 2:
+ png_ptr->user_chunk_cache_max = 1;
+ png_chunk_benign_error(png_ptr, "no space in chunk cache");
+ /* FALLTHROUGH */
+ case 1:
+ /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
+ * chunk being skipped, now there will be a hard error below.
+ */
+ break;
+
+ default: /* not at limit */
+ --(png_ptr->user_chunk_cache_max);
+ /* FALLTHROUGH */
+ case 0: /* no limit */
+# endif /* USER_LIMITS */
+ /* Here when the limit isn't reached or when limits are compiled
+ * out; store the chunk.
+ */
+ png_set_unknown_chunks(png_ptr, info_ptr,
+ &png_ptr->unknown_chunk, 1);
+ handled = 1;
+# ifdef PNG_USER_LIMITS_SUPPORTED
+ break;
+ }
+# endif
+ }
+# else /* no store support: the chunk must be handled by the user callback */
+ PNG_UNUSED(info_ptr)
+# endif
+
+ /* Regardless of the error handling below the cached data (if any) can be
+ * freed now. Notice that the data is not freed if there is a png_error, but
+ * it will be freed by destroy_read_struct.
+ */
+ if (png_ptr->unknown_chunk.data != NULL)
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
+
+#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
+ /* There is no support to read an unknown chunk, so just skip it. */
+ png_crc_finish(png_ptr, length);
+ PNG_UNUSED(info_ptr)
+ PNG_UNUSED(keep)
+#endif /* !READ_UNKNOWN_CHUNKS */
+
+ /* Check for unhandled critical chunks */
+ if (handled == 0 && PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
+ png_chunk_error(png_ptr, "unhandled critical chunk");
+}
+
+/* This function is called to verify that a chunk name is valid.
+ * This function can't have the "critical chunk check" incorporated
+ * into it, since in the future we will need to be able to call user
+ * functions to handle unknown critical chunks after we check that
+ * the chunk name itself is valid.
+ */
+
+/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
+ *
+ * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+ */
+
+void /* PRIVATE */
+png_check_chunk_name(png_const_structrp png_ptr, const png_uint_32 chunk_name)
+{
+ int i;
+ png_uint_32 cn=chunk_name;
+
+ png_debug(1, "in png_check_chunk_name");
+
+ for (i=1; i<=4; ++i)
+ {
+ int c = cn & 0xff;
+
+ if (c < 65 || c > 122 || (c > 90 && c < 97))
+ png_chunk_error(png_ptr, "invalid chunk type");
+
+ cn >>= 8;
+ }
+}
+
+void /* PRIVATE */
+png_check_chunk_length(png_const_structrp png_ptr, const png_uint_32 length)
+{
+ png_alloc_size_t limit = PNG_UINT_31_MAX;
+
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_malloc_max > 0 &&
+ png_ptr->user_chunk_malloc_max < limit)
+ limit = png_ptr->user_chunk_malloc_max;
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+ if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+ limit = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+ if (png_ptr->chunk_name == png_IDAT)
+ {
+ png_alloc_size_t idat_limit = PNG_UINT_31_MAX;
+ size_t row_factor =
+ (png_ptr->width * png_ptr->channels * (png_ptr->bit_depth > 8? 2: 1)
+ + 1 + (png_ptr->interlaced? 6: 0));
+ if (png_ptr->height > PNG_UINT_32_MAX/row_factor)
+ idat_limit=PNG_UINT_31_MAX;
+ else
+ idat_limit = png_ptr->height * row_factor;
+ row_factor = row_factor > 32566? 32566 : row_factor;
+ idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */
+ idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX;
+ limit = limit < idat_limit? idat_limit : limit;
+ }
+
+ if (length > limit)
+ {
+ png_debug2(0," length = %lu, limit = %lu",
+ (unsigned long)length,(unsigned long)limit);
+ png_chunk_error(png_ptr, "chunk data is too large");
+ }
+}
+
+/* Combines the row recently read in with the existing pixels in the row. This
+ * routine takes care of alpha and transparency if requested. This routine also
+ * handles the two methods of progressive display of interlaced images,
+ * depending on the 'display' value; if 'display' is true then the whole row
+ * (dp) is filled from the start by replicating the available pixels. If
+ * 'display' is false only those pixels present in the pass are filled in.
+ */
+void /* PRIVATE */
+png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
+{
+ unsigned int pixel_depth = png_ptr->transformed_pixel_depth;
+ png_const_bytep sp = png_ptr->row_buf + 1;
+ png_alloc_size_t row_width = png_ptr->width;
+ unsigned int pass = png_ptr->pass;
+ png_bytep end_ptr = 0;
+ png_byte end_byte = 0;
+ unsigned int end_mask;
+
+ png_debug(1, "in png_combine_row");
+
+ /* Added in 1.5.6: it should not be possible to enter this routine until at
+ * least one row has been read from the PNG data and transformed.
+ */
+ if (pixel_depth == 0)
+ png_error(png_ptr, "internal row logic error");
+
+ /* Added in 1.5.4: the pixel depth should match the information returned by
+ * any call to png_read_update_info at this point. Do not continue if we got
+ * this wrong.
+ */
+ if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=
+ PNG_ROWBYTES(pixel_depth, row_width))
+ png_error(png_ptr, "internal row size calculation error");
+
+ /* Don't expect this to ever happen: */
+ if (row_width == 0)
+ png_error(png_ptr, "internal row width error");
+
+ /* Preserve the last byte in cases where only part of it will be overwritten,
+ * the multiply below may overflow, we don't care because ANSI-C guarantees
+ * we get the low bits.
+ */
+ end_mask = (pixel_depth * row_width) & 7;
+ if (end_mask != 0)
+ {
+ /* end_ptr == NULL is a flag to say do nothing */
+ end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
+ end_byte = *end_ptr;
+# ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+ /* little-endian byte */
+ end_mask = (unsigned int)(0xff << end_mask);
+
+ else /* big-endian byte */
+# endif
+ end_mask = 0xff >> end_mask;
+ /* end_mask is now the bits to *keep* from the destination row */
+ }
+
+ /* For non-interlaced images this reduces to a memcpy(). A memcpy()
+ * will also happen if interlacing isn't supported or if the application
+ * does not call png_set_interlace_handling(). In the latter cases the
+ * caller just gets a sequence of the unexpanded rows from each interlace
+ * pass.
+ */
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (png_ptr->interlaced != 0 &&
+ (png_ptr->transformations & PNG_INTERLACE) != 0 &&
+ pass < 6 && (display == 0 ||
+ /* The following copies everything for 'display' on passes 0, 2 and 4. */
+ (display == 1 && (pass & 1) != 0)))
+ {
+ /* Narrow images may have no bits in a pass; the caller should handle
+ * this, but this test is cheap:
+ */
+ if (row_width <= PNG_PASS_START_COL(pass))
+ return;
+
+ if (pixel_depth < 8)
+ {
+ /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit
+ * into 32 bits, then a single loop over the bytes using the four byte
+ * values in the 32-bit mask can be used. For the 'display' option the
+ * expanded mask may also not require any masking within a byte. To
+ * make this work the PACKSWAP option must be taken into account - it
+ * simply requires the pixels to be reversed in each byte.
+ *
+ * The 'regular' case requires a mask for each of the first 6 passes,
+ * the 'display' case does a copy for the even passes in the range
+ * 0..6. This has already been handled in the test above.
+ *
+ * The masks are arranged as four bytes with the first byte to use in
+ * the lowest bits (little-endian) regardless of the order (PACKSWAP or
+ * not) of the pixels in each byte.
+ *
+ * NOTE: the whole of this logic depends on the caller of this function
+ * only calling it on rows appropriate to the pass. This function only
+ * understands the 'x' logic; the 'y' logic is handled by the caller.
+ *
+ * The following defines allow generation of compile time constant bit
+ * masks for each pixel depth and each possibility of swapped or not
+ * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index,
+ * is in the range 0..7; and the result is 1 if the pixel is to be
+ * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B'
+ * for the block method.
+ *
+ * With some compilers a compile time expression of the general form:
+ *
+ * (shift >= 32) ? (a >> (shift-32)) : (b >> shift)
+ *
+ * Produces warnings with values of 'shift' in the range 33 to 63
+ * because the right hand side of the ?: expression is evaluated by
+ * the compiler even though it isn't used. Microsoft Visual C (various
+ * versions) and the Intel C compiler are known to do this. To avoid
+ * this the following macros are used in 1.5.6. This is a temporary
+ * solution to avoid destabilizing the code during the release process.
+ */
+# if PNG_USE_COMPILE_TIME_MASKS
+# define PNG_LSR(x,s) ((x)>>((s) & 0x1f))
+# define PNG_LSL(x,s) ((x)<<((s) & 0x1f))
+# else
+# define PNG_LSR(x,s) ((x)>>(s))
+# define PNG_LSL(x,s) ((x)<<(s))
+# endif
+# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\
+ PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)
+# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\
+ PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)
+
+ /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is
+ * little endian - the first pixel is at bit 0 - however the extra
+ * parameter 's' can be set to cause the mask position to be swapped
+ * within each byte, to match the PNG format. This is done by XOR of
+ * the shift with 7, 6 or 4 for bit depths 1, 2 and 4.
+ */
+# define PIXEL_MASK(p,x,d,s) \
+ (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0))))
+
+ /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask.
+ */
+# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
+# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
+
+ /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp
+ * cases the result needs replicating, for the 4-bpp case the above
+ * generates a full 32 bits.
+ */
+# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))
+
+# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\
+ S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\
+ S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d)
+
+# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\
+ B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\
+ B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d)
+
+#if PNG_USE_COMPILE_TIME_MASKS
+ /* Utility macros to construct all the masks for a depth/swap
+ * combination. The 's' parameter says whether the format is PNG
+ * (big endian bytes) or not. Only the three odd-numbered passes are
+ * required for the display/block algorithm.
+ */
+# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\
+ S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }
+
+# define B_MASKS(d,s) { B_MASK(1,d,s), B_MASK(3,d,s), B_MASK(5,d,s) }
+
+# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))
+
+ /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
+ * then pass:
+ */
+ static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
+ {
+ /* Little-endian byte masks for PACKSWAP */
+ { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
+ /* Normal (big-endian byte) masks - PNG format */
+ { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) }
+ };
+
+ /* display_mask has only three entries for the odd passes, so index by
+ * pass>>1.
+ */
+ static PNG_CONST png_uint_32 display_mask[2][3][3] =
+ {
+ /* Little-endian byte masks for PACKSWAP */
+ { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
+ /* Normal (big-endian byte) masks - PNG format */
+ { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) }
+ };
+
+# define MASK(pass,depth,display,png)\
+ ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\
+ row_mask[png][DEPTH_INDEX(depth)][pass])
+
+#else /* !PNG_USE_COMPILE_TIME_MASKS */
+ /* This is the runtime alternative: it seems unlikely that this will
+ * ever be either smaller or faster than the compile time approach.
+ */
+# define MASK(pass,depth,display,png)\
+ ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))
+#endif /* !USE_COMPILE_TIME_MASKS */
+
+ /* Use the appropriate mask to copy the required bits. In some cases
+ * the byte mask will be 0 or 0xff; optimize these cases. row_width is
+ * the number of pixels, but the code copies bytes, so it is necessary
+ * to special case the end.
+ */
+ png_uint_32 pixels_per_byte = 8 / pixel_depth;
+ png_uint_32 mask;
+
+# ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+ mask = MASK(pass, pixel_depth, display, 0);
+
+ else
+# endif
+ mask = MASK(pass, pixel_depth, display, 1);
+
+ for (;;)
+ {
+ png_uint_32 m;
+
+ /* It doesn't matter in the following if png_uint_32 has more than
+ * 32 bits because the high bits always match those in m<<24; it is,
+ * however, essential to use OR here, not +, because of this.
+ */
+ m = mask;
+ mask = (m >> 8) | (m << 24); /* rotate right to good compilers */
+ m &= 0xff;
+
+ if (m != 0) /* something to copy */
+ {
+ if (m != 0xff)
+ *dp = (png_byte)((*dp & ~m) | (*sp & m));
+ else
+ *dp = *sp;
+ }
+
+ /* NOTE: this may overwrite the last byte with garbage if the image
+ * is not an exact number of bytes wide; libpng has always done
+ * this.
+ */
+ if (row_width <= pixels_per_byte)
+ break; /* May need to restore part of the last byte */
+
+ row_width -= pixels_per_byte;
+ ++dp;
+ ++sp;
+ }
+ }
+
+ else /* pixel_depth >= 8 */
+ {
+ unsigned int bytes_to_copy, bytes_to_jump;
+
+ /* Validate the depth - it must be a multiple of 8 */
+ if (pixel_depth & 7)
+ png_error(png_ptr, "invalid user transform pixel depth");
+
+ pixel_depth >>= 3; /* now in bytes */
+ row_width *= pixel_depth;
+
+ /* Regardless of pass number the Adam 7 interlace always results in a
+ * fixed number of pixels to copy then to skip. There may be a
+ * different number of pixels to skip at the start though.
+ */
+ {
+ unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth;
+
+ row_width -= offset;
+ dp += offset;
+ sp += offset;
+ }
+
+ /* Work out the bytes to copy. */
+ if (display != 0)
+ {
+ /* When doing the 'block' algorithm the pixel in the pass gets
+ * replicated to adjacent pixels. This is why the even (0,2,4,6)
+ * passes are skipped above - the entire expanded row is copied.
+ */
+ bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth;
+
+ /* But don't allow this number to exceed the actual row width. */
+ if (bytes_to_copy > row_width)
+ bytes_to_copy = (unsigned int)/*SAFE*/row_width;
+ }
+
+ else /* normal row; Adam7 only ever gives us one pixel to copy. */
+ bytes_to_copy = pixel_depth;
+
+ /* In Adam7 there is a constant offset between where the pixels go. */
+ bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
+
+ /* And simply copy these bytes. Some optimization is possible here,
+ * depending on the value of 'bytes_to_copy'. Special case the low
+ * byte counts, which we know to be frequent.
+ *
+ * Notice that these cases all 'return' rather than 'break' - this
+ * avoids an unnecessary test on whether to restore the last byte
+ * below.
+ */
+ switch (bytes_to_copy)
+ {
+ case 1:
+ for (;;)
+ {
+ *dp = *sp;
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ dp += bytes_to_jump;
+ sp += bytes_to_jump;
+ row_width -= bytes_to_jump;
+ }
+
+ case 2:
+ /* There is a possibility of a partial copy at the end here; this
+ * slows the code down somewhat.
+ */
+ do
+ {
+ dp[0] = sp[0]; dp[1] = sp[1];
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ sp += bytes_to_jump;
+ dp += bytes_to_jump;
+ row_width -= bytes_to_jump;
+ }
+ while (row_width > 1);
+
+ /* And there can only be one byte left at this point: */
+ *dp = *sp;
+ return;
+
+ case 3:
+ /* This can only be the RGB case, so each copy is exactly one
+ * pixel and it is not necessary to check for a partial copy.
+ */
+ for (;;)
+ {
+ dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2];
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ sp += bytes_to_jump;
+ dp += bytes_to_jump;
+ row_width -= bytes_to_jump;
+ }
+
+ default:
+#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
+ /* Check for double byte alignment and, if possible, use a
+ * 16-bit copy. Don't attempt this for narrow images - ones that
+ * are less than an interlace panel wide. Don't attempt it for
+ * wide bytes_to_copy either - use the memcpy there.
+ */
+ if (bytes_to_copy < 16 /*else use memcpy*/ &&
+ png_isaligned(dp, png_uint_16) &&
+ png_isaligned(sp, png_uint_16) &&
+ bytes_to_copy % (sizeof (png_uint_16)) == 0 &&
+ bytes_to_jump % (sizeof (png_uint_16)) == 0)
+ {
+ /* Everything is aligned for png_uint_16 copies, but try for
+ * png_uint_32 first.
+ */
+ if (png_isaligned(dp, png_uint_32) &&
+ png_isaligned(sp, png_uint_32) &&
+ bytes_to_copy % (sizeof (png_uint_32)) == 0 &&
+ bytes_to_jump % (sizeof (png_uint_32)) == 0)
+ {
+ png_uint_32p dp32 = png_aligncast(png_uint_32p,dp);
+ png_const_uint_32p sp32 = png_aligncastconst(
+ png_const_uint_32p, sp);
+ size_t skip = (bytes_to_jump-bytes_to_copy) /
+ (sizeof (png_uint_32));
+
+ do
+ {
+ size_t c = bytes_to_copy;
+ do
+ {
+ *dp32++ = *sp32++;
+ c -= (sizeof (png_uint_32));
+ }
+ while (c > 0);
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ dp32 += skip;
+ sp32 += skip;
+ row_width -= bytes_to_jump;
+ }
+ while (bytes_to_copy <= row_width);
+
+ /* Get to here when the row_width truncates the final copy.
+ * There will be 1-3 bytes left to copy, so don't try the
+ * 16-bit loop below.
+ */
+ dp = (png_bytep)dp32;
+ sp = (png_const_bytep)sp32;
+ do
+ *dp++ = *sp++;
+ while (--row_width > 0);
+ return;
+ }
+
+ /* Else do it in 16-bit quantities, but only if the size is
+ * not too large.
+ */
+ else
+ {
+ png_uint_16p dp16 = png_aligncast(png_uint_16p, dp);
+ png_const_uint_16p sp16 = png_aligncastconst(
+ png_const_uint_16p, sp);
+ size_t skip = (bytes_to_jump-bytes_to_copy) /
+ (sizeof (png_uint_16));
+
+ do
+ {
+ size_t c = bytes_to_copy;
+ do
+ {
+ *dp16++ = *sp16++;
+ c -= (sizeof (png_uint_16));
+ }
+ while (c > 0);
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ dp16 += skip;
+ sp16 += skip;
+ row_width -= bytes_to_jump;
+ }
+ while (bytes_to_copy <= row_width);
+
+ /* End of row - 1 byte left, bytes_to_copy > row_width: */
+ dp = (png_bytep)dp16;
+ sp = (png_const_bytep)sp16;
+ do
+ *dp++ = *sp++;
+ while (--row_width > 0);
+ return;
+ }
+ }
+#endif /* ALIGN_TYPE code */
+
+ /* The true default - use a memcpy: */
+ for (;;)
+ {
+ memcpy(dp, sp, bytes_to_copy);
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ sp += bytes_to_jump;
+ dp += bytes_to_jump;
+ row_width -= bytes_to_jump;
+ if (bytes_to_copy > row_width)
+ bytes_to_copy = (unsigned int)/*SAFE*/row_width;
+ }
+ }
+
+ /* NOT REACHED*/
+ } /* pixel_depth >= 8 */
+
+ /* Here if pixel_depth < 8 to check 'end_ptr' below. */
+ }
+ else
+#endif /* READ_INTERLACING */
+
+ /* If here then the switch above wasn't used so just memcpy the whole row
+ * from the temporary row buffer (notice that this overwrites the end of the
+ * destination row if it is a partial byte.)
+ */
+ memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width));
+
+ /* Restore the overwritten bits from the last byte if necessary. */
+ if (end_ptr != NULL)
+ *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));
+}
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+void /* PRIVATE */
+png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
+ png_uint_32 transformations /* Because these may affect the byte layout */)
+{
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+ /* Offset to next interlace block */
+ static PNG_CONST unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ png_debug(1, "in png_do_read_interlace");
+ if (row != NULL && row_info != NULL)
+ {
+ png_uint_32 final_width;
+
+ final_width = row_info->width * png_pass_inc[pass];
+
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
+ unsigned int sshift, dshift;
+ unsigned int s_start, s_end;
+ int s_inc;
+ int jstop = (int)png_pass_inc[pass];
+ png_byte v;
+ png_uint_32 i;
+ int j;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if ((transformations & PNG_PACKSWAP) != 0)
+ {
+ sshift = ((row_info->width + 7) & 0x07);
+ dshift = ((final_width + 7) & 0x07);
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+
+ else
+#endif
+ {
+ sshift = 7 - ((row_info->width + 7) & 0x07);
+ dshift = 7 - ((final_width + 7) & 0x07);
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ v = (png_byte)((*sp >> sshift) & 0x01);
+ for (j = 0; j < jstop; j++)
+ {
+ unsigned int tmp = *dp & (0x7f7f >> (7 - dshift));
+ tmp |= (unsigned int)(v << dshift);
+ *dp = (png_byte)(tmp & 0xff);
+
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+
+ else
+ dshift = (unsigned int)((int)dshift + s_inc);
+ }
+
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+
+ else
+ sshift = (unsigned int)((int)sshift + s_inc);
+ }
+ break;
+ }
+
+ case 2:
+ {
+ png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
+ png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
+ unsigned int sshift, dshift;
+ unsigned int s_start, s_end;
+ int s_inc;
+ int jstop = (int)png_pass_inc[pass];
+ png_uint_32 i;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if ((transformations & PNG_PACKSWAP) != 0)
+ {
+ sshift = (((row_info->width + 3) & 0x03) << 1);
+ dshift = (((final_width + 3) & 0x03) << 1);
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+
+ else
+#endif
+ {
+ sshift = ((3 - ((row_info->width + 3) & 0x03)) << 1);
+ dshift = ((3 - ((final_width + 3) & 0x03)) << 1);
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v;
+ int j;
+
+ v = (png_byte)((*sp >> sshift) & 0x03);
+ for (j = 0; j < jstop; j++)
+ {
+ unsigned int tmp = *dp & (0x3f3f >> (6 - dshift));
+ tmp |= (unsigned int)(v << dshift);
+ *dp = (png_byte)(tmp & 0xff);
+
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+
+ else
+ dshift = (unsigned int)((int)dshift + s_inc);
+ }
+
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+
+ else
+ sshift = (unsigned int)((int)sshift + s_inc);
+ }
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
+ unsigned int sshift, dshift;
+ unsigned int s_start, s_end;
+ int s_inc;
+ png_uint_32 i;
+ int jstop = (int)png_pass_inc[pass];
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if ((transformations & PNG_PACKSWAP) != 0)
+ {
+ sshift = (((row_info->width + 1) & 0x01) << 2);
+ dshift = (((final_width + 1) & 0x01) << 2);
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+
+ else
+#endif
+ {
+ sshift = ((1 - ((row_info->width + 1) & 0x01)) << 2);
+ dshift = ((1 - ((final_width + 1) & 0x01)) << 2);
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
+ int j;
+
+ for (j = 0; j < jstop; j++)
+ {
+ unsigned int tmp = *dp & (0xf0f >> (4 - dshift));
+ tmp |= (unsigned int)(v << dshift);
+ *dp = (png_byte)(tmp & 0xff);
+
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+
+ else
+ dshift = (unsigned int)((int)dshift + s_inc);
+ }
+
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+
+ else
+ sshift = (unsigned int)((int)sshift + s_inc);
+ }
+ break;
+ }
+
+ default:
+ {
+ png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
+
+ png_bytep sp = row + (png_size_t)(row_info->width - 1)
+ * pixel_bytes;
+
+ png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
+
+ int jstop = (int)png_pass_inc[pass];
+ png_uint_32 i;
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */
+ int j;
+
+ memcpy(v, sp, pixel_bytes);
+
+ for (j = 0; j < jstop; j++)
+ {
+ memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+
+ sp -= pixel_bytes;
+ }
+ break;
+ }
+ }
+
+ row_info->width = final_width;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
+ }
+#ifndef PNG_READ_PACKSWAP_SUPPORTED
+ PNG_UNUSED(transformations) /* Silence compiler warning */
+#endif
+}
+#endif /* READ_INTERLACING */
+
+static void
+png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
+ unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
+ png_bytep rp = row + bpp;
+
+ PNG_UNUSED(prev_row)
+
+ for (i = bpp; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+ rp++;
+ }
+}
+
+static void
+png_read_filter_row_up(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
+ png_bytep rp = row;
+ png_const_bytep pp = prev_row;
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+}
+
+static void
+png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_size_t i;
+ png_bytep rp = row;
+ png_const_bytep pp = prev_row;
+ unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
+ png_size_t istop = row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ ((int)(*pp++) / 2 )) & 0xff);
+
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+ rp++;
+ }
+}
+
+static void
+png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_bytep rp_end = row + row_info->rowbytes;
+ int a, c;
+
+ /* First pixel/byte */
+ c = *prev_row++;
+ a = *row + c;
+ *row++ = (png_byte)a;
+
+ /* Remainder */
+ while (row < rp_end)
+ {
+ int b, pa, pb, pc, p;
+
+ a &= 0xff; /* From previous iteration or start */
+ b = *prev_row++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ /* Find the best predictor, the least of pa, pb, pc favoring the earlier
+ * ones in the case of a tie.
+ */
+ if (pb < pa)
+ {
+ pa = pb; a = b;
+ }
+ if (pc < pa) a = c;
+
+ /* Calculate the current pixel in a, and move the previous row pixel to c
+ * for the next time round the loop
+ */
+ c = b;
+ a += *row;
+ *row++ = (png_byte)a;
+ }
+}
+
+static void
+png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
+ png_bytep rp_end = row + bpp;
+
+ /* Process the first pixel in the row completely (this is the same as 'up'
+ * because there is only one candidate predictor for the first row).
+ */
+ while (row < rp_end)
+ {
+ int a = *row + *prev_row++;
+ *row++ = (png_byte)a;
+ }
+
+ /* Remainder */
+ rp_end = rp_end + (row_info->rowbytes - bpp);
+
+ while (row < rp_end)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ c = *(prev_row - bpp);
+ a = *(row - bpp);
+ b = *prev_row++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ if (pb < pa)
+ {
+ pa = pb; a = b;
+ }
+ if (pc < pa) a = c;
+
+ a += *row;
+ *row++ = (png_byte)a;
+ }
+}
+
+static void
+png_init_filter_functions(png_structrp pp)
+ /* This function is called once for every PNG image (except for PNG images
+ * that only use PNG_FILTER_VALUE_NONE for all rows) to set the
+ * implementations required to reverse the filtering of PNG rows. Reversing
+ * the filter is the first transformation performed on the row data. It is
+ * performed in place, therefore an implementation can be selected based on
+ * the image pixel format. If the implementation depends on image width then
+ * take care to ensure that it works correctly if the image is interlaced -
+ * interlacing causes the actual row width to vary.
+ */
+{
+ unsigned int bpp = (pp->pixel_depth + 7) >> 3;
+
+ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub;
+ pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up;
+ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg;
+ if (bpp == 1)
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+ png_read_filter_row_paeth_1byte_pixel;
+ else
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+ png_read_filter_row_paeth_multibyte_pixel;
+
+#ifdef PNG_FILTER_OPTIMIZATIONS
+ /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to
+ * call to install hardware optimizations for the above functions; simply
+ * replace whatever elements of the pp->read_filter[] array with a hardware
+ * specific (or, for that matter, generic) optimization.
+ *
+ * To see an example of this examine what configure.ac does when
+ * --enable-arm-neon is specified on the command line.
+ */
+ PNG_FILTER_OPTIMIZATIONS(pp, bpp);
+#endif
+}
+
+void /* PRIVATE */
+png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row, int filter)
+{
+ /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define
+ * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic
+ * implementations. See png_init_filter_functions above.
+ */
+ if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
+ {
+ if (pp->read_filter[0] == NULL)
+ png_init_filter_functions(pp);
+
+ pp->read_filter[filter-1](row_info, row, prev_row);
+ }
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+void /* PRIVATE */
+png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
+ png_alloc_size_t avail_out)
+{
+ /* Loop reading IDATs and decompressing the result into output[avail_out] */
+ png_ptr->zstream.next_out = output;
+ png_ptr->zstream.avail_out = 0; /* safety: set below */
+
+ if (output == NULL)
+ avail_out = 0;
+
+ do
+ {
+ int ret;
+ png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];
+
+ if (png_ptr->zstream.avail_in == 0)
+ {
+ uInt avail_in;
+ png_bytep buffer;
+
+ while (png_ptr->idat_size == 0)
+ {
+ png_crc_finish(png_ptr, 0);
+
+ png_ptr->idat_size = png_read_chunk_header(png_ptr);
+ /* This is an error even in the 'check' case because the code just
+ * consumed a non-IDAT header.
+ */
+ if (png_ptr->chunk_name != png_IDAT)
+ png_error(png_ptr, "Not enough image data");
+ }
+
+ avail_in = png_ptr->IDAT_read_size;
+
+ if (avail_in > png_ptr->idat_size)
+ avail_in = (uInt)png_ptr->idat_size;
+
+ /* A PNG with a gradually increasing IDAT size will defeat this attempt
+ * to minimize memory usage by causing lots of re-allocs, but
+ * realistically doing IDAT_read_size re-allocs is not likely to be a
+ * big problem.
+ */
+ buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/);
+
+ png_crc_read(png_ptr, buffer, avail_in);
+ png_ptr->idat_size -= avail_in;
+
+ png_ptr->zstream.next_in = buffer;
+ png_ptr->zstream.avail_in = avail_in;
+ }
+
+ /* And set up the output side. */
+ if (output != NULL) /* standard read */
+ {
+ uInt out = ZLIB_IO_MAX;
+
+ if (out > avail_out)
+ out = (uInt)avail_out;
+
+ avail_out -= out;
+ png_ptr->zstream.avail_out = out;
+ }
+
+ else /* after last row, checking for end */
+ {
+ png_ptr->zstream.next_out = tmpbuf;
+ png_ptr->zstream.avail_out = (sizeof tmpbuf);
+ }
+
+ /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the
+ * process. If the LZ stream is truncated the sequential reader will
+ * terminally damage the stream, above, by reading the chunk header of the
+ * following chunk (it then exits with png_error).
+ *
+ * TODO: deal more elegantly with truncated IDAT lists.
+ */
+ ret = PNG_INFLATE(png_ptr, Z_NO_FLUSH);
+
+ /* Take the unconsumed output back. */
+ if (output != NULL)
+ avail_out += png_ptr->zstream.avail_out;
+
+ else /* avail_out counts the extra bytes */
+ avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out;
+
+ png_ptr->zstream.avail_out = 0;
+
+ if (ret == Z_STREAM_END)
+ {
+ /* Do this for safety; we won't read any more into this row. */
+ png_ptr->zstream.next_out = NULL;
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+
+ if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
+ png_chunk_benign_error(png_ptr, "Extra compressed data");
+ break;
+ }
+
+ if (ret != Z_OK)
+ {
+ png_zstream_error(png_ptr, ret);
+
+ if (output != NULL)
+ png_chunk_error(png_ptr, png_ptr->zstream.msg);
+
+ else /* checking */
+ {
+ png_chunk_benign_error(png_ptr, png_ptr->zstream.msg);
+ return;
+ }
+ }
+ } while (avail_out > 0);
+
+ if (avail_out > 0)
+ {
+ /* The stream ended before the image; this is the same as too few IDATs so
+ * should be handled the same way.
+ */
+ if (output != NULL)
+ png_error(png_ptr, "Not enough image data");
+
+ else /* the deflate stream contained extra data */
+ png_chunk_benign_error(png_ptr, "Too much image data");
+ }
+}
+
+void /* PRIVATE */
+png_read_finish_IDAT(png_structrp png_ptr)
+{
+ /* We don't need any more data and the stream should have ended, however the
+ * LZ end code may actually not have been processed. In this case we must
+ * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk
+ * may still remain to be consumed.
+ */
+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+ {
+ /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in
+ * the compressed stream, but the stream may be damaged too, so even after
+ * this call we may need to terminate the zstream ownership.
+ */
+ png_read_IDAT_data(png_ptr, NULL, 0);
+ png_ptr->zstream.next_out = NULL; /* safety */
+
+ /* Now clear everything out for safety; the following may not have been
+ * done.
+ */
+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0)
+ {
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+ }
+ }
+
+ /* If the zstream has not been released do it now *and* terminate the reading
+ * of the final IDAT chunk.
+ */
+ if (png_ptr->zowner == png_IDAT)
+ {
+ /* Always do this; the pointers otherwise point into the read buffer. */
+ png_ptr->zstream.next_in = NULL;
+ png_ptr->zstream.avail_in = 0;
+
+ /* Now we no longer own the zstream. */
+ png_ptr->zowner = 0;
+
+ /* The slightly weird semantics of the sequential IDAT reading is that we
+ * are always in or at the end of an IDAT chunk, so we always need to do a
+ * crc_finish here. If idat_size is non-zero we also need to read the
+ * spurious bytes at the end of the chunk now.
+ */
+ (void)png_crc_finish(png_ptr, png_ptr->idat_size);
+ }
+}
+
+void /* PRIVATE */
+png_read_finish_row(png_structrp png_ptr)
+{
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+
+ png_debug(1, "in png_read_finish_row");
+ png_ptr->row_number++;
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+ if (png_ptr->interlaced != 0)
+ {
+ png_ptr->row_number = 0;
+
+ /* TO DO: don't do this if prev_row isn't needed (requires
+ * read-ahead of the next row's filter byte.
+ */
+ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+ do
+ {
+ png_ptr->pass++;
+
+ if (png_ptr->pass >= 7)
+ break;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ if ((png_ptr->transformations & PNG_INTERLACE) == 0)
+ {
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+ }
+
+ else /* if (png_ptr->transformations & PNG_INTERLACE) */
+ break; /* libpng deinterlacing sees every row */
+
+ } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
+
+ if (png_ptr->pass < 7)
+ return;
+ }
+
+ /* Here after at the end of the last row of the last pass. */
+ png_read_finish_IDAT(png_ptr);
+}
+#endif /* SEQUENTIAL_READ */
+
+void /* PRIVATE */
+png_read_start_row(png_structrp png_ptr)
+{
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+
+ unsigned int max_pixel_depth;
+ png_size_t row_bytes;
+
+ png_debug(1, "in png_read_start_row");
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+ png_init_read_transformations(png_ptr);
+#endif
+ if (png_ptr->interlaced != 0)
+ {
+ if ((png_ptr->transformations & PNG_INTERLACE) == 0)
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+ png_pass_ystart[0]) / png_pass_yinc[0];
+
+ else
+ png_ptr->num_rows = png_ptr->height;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+ }
+
+ else
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->iwidth = png_ptr->width;
+ }
+
+ max_pixel_depth = (unsigned int)png_ptr->pixel_depth;
+
+ /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpler set of
+ * calculations to calculate the final pixel depth, then
+ * png_do_read_transforms actually does the transforms. This means that the
+ * code which effectively calculates this value is actually repeated in three
+ * separate places. They must all match. Innocent changes to the order of
+ * transformations can and will break libpng in a way that causes memory
+ * overwrites.
+ *
+ * TODO: fix this.
+ */
+#ifdef PNG_READ_PACK_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACK) != 0 && png_ptr->bit_depth < 8)
+ max_pixel_depth = 8;
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ if ((png_ptr->transformations & PNG_EXPAND) != 0)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (png_ptr->num_trans != 0)
+ max_pixel_depth = 32;
+
+ else
+ max_pixel_depth = 24;
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (max_pixel_depth < 8)
+ max_pixel_depth = 8;
+
+ if (png_ptr->num_trans != 0)
+ max_pixel_depth *= 2;
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (png_ptr->num_trans != 0)
+ {
+ max_pixel_depth *= 4;
+ max_pixel_depth /= 3;
+ }
+ }
+ }
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ if ((png_ptr->transformations & PNG_EXPAND_16) != 0)
+ {
+# ifdef PNG_READ_EXPAND_SUPPORTED
+ /* In fact it is an error if it isn't supported, but checking is
+ * the safe way.
+ */
+ if ((png_ptr->transformations & PNG_EXPAND) != 0)
+ {
+ if (png_ptr->bit_depth < 16)
+ max_pixel_depth *= 2;
+ }
+ else
+# endif
+ png_ptr->transformations &= ~PNG_EXPAND_16;
+ }
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+ if ((png_ptr->transformations & (PNG_FILLER)) != 0)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (max_pixel_depth <= 8)
+ max_pixel_depth = 16;
+
+ else
+ max_pixel_depth = 32;
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
+ png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (max_pixel_depth <= 32)
+ max_pixel_depth = 32;
+
+ else
+ max_pixel_depth = 64;
+ }
+ }
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) != 0)
+ {
+ if (
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ (png_ptr->num_trans != 0 &&
+ (png_ptr->transformations & PNG_EXPAND) != 0) ||
+#endif
+#ifdef PNG_READ_FILLER_SUPPORTED
+ (png_ptr->transformations & (PNG_FILLER)) != 0 ||
+#endif
+ png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (max_pixel_depth <= 16)
+ max_pixel_depth = 32;
+
+ else
+ max_pixel_depth = 64;
+ }
+
+ else
+ {
+ if (max_pixel_depth <= 8)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ max_pixel_depth = 32;
+
+ else
+ max_pixel_depth = 24;
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ max_pixel_depth = 64;
+
+ else
+ max_pixel_depth = 48;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
+defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
+ {
+ unsigned int user_pixel_depth = png_ptr->user_transform_depth *
+ png_ptr->user_transform_channels;
+
+ if (user_pixel_depth > max_pixel_depth)
+ max_pixel_depth = user_pixel_depth;
+ }
+#endif
+
+ /* This value is stored in png_struct and double checked in the row read
+ * code.
+ */
+ png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;
+ png_ptr->transformed_pixel_depth = 0; /* calculated on demand */
+
+ /* Align the width on the next larger 8 pixels. Mainly used
+ * for interlacing
+ */
+ row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
+ /* Calculate the maximum bytes needed, adding a byte and a pixel
+ * for safety's sake
+ */
+ row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
+ 1 + ((max_pixel_depth + 7) >> 3U);
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (row_bytes > (png_uint_32)65536L)
+ png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+
+ if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
+ {
+ png_free(png_ptr, png_ptr->big_row_buf);
+ png_free(png_ptr, png_ptr->big_prev_row);
+
+ if (png_ptr->interlaced != 0)
+ png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
+ row_bytes + 48);
+
+ else
+ png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+
+ png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+
+#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
+ /* Use 16-byte aligned memory for row_buf with at least 16 bytes
+ * of padding before and after row_buf; treat prev_row similarly.
+ * NOTE: the alignment is to the start of the pixels, one beyond the start
+ * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this
+ * was incorrect; the filter byte was aligned, which had the exact
+ * opposite effect of that intended.
+ */
+ {
+ png_bytep temp = png_ptr->big_row_buf + 32;
+ int extra = (int)((temp - (png_bytep)0) & 0x0f);
+ png_ptr->row_buf = temp - extra - 1/*filter byte*/;
+
+ temp = png_ptr->big_prev_row + 32;
+ extra = (int)((temp - (png_bytep)0) & 0x0f);
+ png_ptr->prev_row = temp - extra - 1/*filter byte*/;
+ }
+
+#else
+ /* Use 31 bytes of padding before and 17 bytes after row_buf. */
+ png_ptr->row_buf = png_ptr->big_row_buf + 31;
+ png_ptr->prev_row = png_ptr->big_prev_row + 31;
+#endif
+ png_ptr->old_big_row_buf_size = row_bytes + 48;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (png_ptr->rowbytes > 65535)
+ png_error(png_ptr, "This image requires a row greater than 64KB");
+
+#endif
+ if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
+ png_error(png_ptr, "Row has too many bytes to allocate in memory");
+
+ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+ png_debug1(3, "width = %u,", png_ptr->width);
+ png_debug1(3, "height = %u,", png_ptr->height);
+ png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
+ png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
+ png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
+ png_debug1(3, "irowbytes = %lu",
+ (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
+
+ /* The sequential reader needs a buffer for IDAT, but the progressive reader
+ * does not, so free the read buffer now regardless; the sequential reader
+ * reallocates it on demand.
+ */
+ if (png_ptr->read_buffer != NULL)
+ {
+ png_bytep buffer = png_ptr->read_buffer;
+
+ png_ptr->read_buffer_size = 0;
+ png_ptr->read_buffer = NULL;
+ png_free(png_ptr, buffer);
+ }
+
+ /* Finally claim the zstream for the inflate of the IDAT data, use the bits
+ * value from the stream (note that this will result in a fatal error if the
+ * IDAT stream has a bogus deflate header window_bits value, but this should
+ * not be happening any longer!)
+ */
+ if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg);
+
+ png_ptr->flags |= PNG_FLAG_ROW_INIT;
+}
+#endif /* READ */
diff --git a/xs/src/png/libpng/pngset.c b/xs/src/png/libpng/pngset.c
new file mode 100644
index 000000000..6f3a1ee11
--- /dev/null
+++ b/xs/src/png/libpng/pngset.c
@@ -0,0 +1,1802 @@
+
+/* pngset.c - storage of image information into info struct
+ *
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * The functions here are used during reads to store data from the file
+ * into the info struct, and during writes to store application data
+ * into the info struct for writing into the file. This abstracts the
+ * info struct and allows us to change the structure in the future.
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+#ifdef PNG_bKGD_SUPPORTED
+void PNGAPI
+png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_color_16p background)
+{
+ png_debug1(1, "in %s storage function", "bKGD");
+
+ if (png_ptr == NULL || info_ptr == NULL || background == NULL)
+ return;
+
+ info_ptr->background = *background;
+ info_ptr->valid |= PNG_INFO_bKGD;
+}
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+void PNGFAPI
+png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
+ png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
+ png_fixed_point blue_x, png_fixed_point blue_y)
+{
+ png_xy xy;
+
+ png_debug1(1, "in %s storage function", "cHRM fixed");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ xy.redx = red_x;
+ xy.redy = red_y;
+ xy.greenx = green_x;
+ xy.greeny = green_y;
+ xy.bluex = blue_x;
+ xy.bluey = blue_y;
+ xy.whitex = white_x;
+ xy.whitey = white_y;
+
+ if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy,
+ 2/* override with app values*/) != 0)
+ info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+void PNGFAPI
+png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_fixed_point int_red_X, png_fixed_point int_red_Y,
+ png_fixed_point int_red_Z, png_fixed_point int_green_X,
+ png_fixed_point int_green_Y, png_fixed_point int_green_Z,
+ png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
+ png_fixed_point int_blue_Z)
+{
+ png_XYZ XYZ;
+
+ png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ XYZ.red_X = int_red_X;
+ XYZ.red_Y = int_red_Y;
+ XYZ.red_Z = int_red_Z;
+ XYZ.green_X = int_green_X;
+ XYZ.green_Y = int_green_Y;
+ XYZ.green_Z = int_green_Z;
+ XYZ.blue_X = int_blue_X;
+ XYZ.blue_Y = int_blue_Y;
+ XYZ.blue_Z = int_blue_Z;
+
+ if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace,
+ &XYZ, 2) != 0)
+ info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
+ double white_x, double white_y, double red_x, double red_y,
+ double green_x, double green_y, double blue_x, double blue_y)
+{
+ png_set_cHRM_fixed(png_ptr, info_ptr,
+ png_fixed(png_ptr, white_x, "cHRM White X"),
+ png_fixed(png_ptr, white_y, "cHRM White Y"),
+ png_fixed(png_ptr, red_x, "cHRM Red X"),
+ png_fixed(png_ptr, red_y, "cHRM Red Y"),
+ png_fixed(png_ptr, green_x, "cHRM Green X"),
+ png_fixed(png_ptr, green_y, "cHRM Green Y"),
+ png_fixed(png_ptr, blue_x, "cHRM Blue X"),
+ png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
+}
+
+void PNGAPI
+png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
+ double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
+ double blue_X, double blue_Y, double blue_Z)
+{
+ png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
+ png_fixed(png_ptr, red_X, "cHRM Red X"),
+ png_fixed(png_ptr, red_Y, "cHRM Red Y"),
+ png_fixed(png_ptr, red_Z, "cHRM Red Z"),
+ png_fixed(png_ptr, green_X, "cHRM Green X"),
+ png_fixed(png_ptr, green_Y, "cHRM Green Y"),
+ png_fixed(png_ptr, green_Z, "cHRM Green Z"),
+ png_fixed(png_ptr, blue_X, "cHRM Blue X"),
+ png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
+ png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
+}
+# endif /* FLOATING_POINT */
+
+#endif /* cHRM */
+
+#ifdef PNG_eXIf_SUPPORTED
+void PNGAPI
+png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
+ const png_bytep eXIf_buf)
+{
+ png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1");
+ PNG_UNUSED(info_ptr)
+ PNG_UNUSED(eXIf_buf)
+}
+
+void PNGAPI
+png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
+ const png_uint_32 num_exif, const png_bytep eXIf_buf)
+{
+ int i;
+
+ png_debug1(1, "in %s storage function", "eXIf");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (info_ptr->exif)
+ {
+ png_free(png_ptr, info_ptr->exif);
+ info_ptr->exif = NULL;
+ }
+
+ info_ptr->num_exif = num_exif;
+
+ info_ptr->exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr,
+ info_ptr->num_exif));
+
+ if (info_ptr->exif == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for eXIf chunk data");
+ return;
+ }
+
+ info_ptr->free_me |= PNG_FREE_EXIF;
+
+ for (i = 0; i < (int) info_ptr->num_exif; i++)
+ info_ptr->exif[i] = eXIf_buf[i];
+
+ info_ptr->valid |= PNG_INFO_eXIf;
+}
+#endif /* eXIf */
+
+#ifdef PNG_gAMA_SUPPORTED
+void PNGFAPI
+png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_fixed_point file_gamma)
+{
+ png_debug1(1, "in %s storage function", "gAMA");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma);
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma)
+{
+ png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
+ "png_set_gAMA"));
+}
+# endif
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+void PNGAPI
+png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_uint_16p hist)
+{
+ int i;
+
+ png_debug1(1, "in %s storage function", "hIST");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (info_ptr->num_palette == 0 || info_ptr->num_palette
+ > PNG_MAX_PALETTE_LENGTH)
+ {
+ png_warning(png_ptr,
+ "Invalid palette size, hIST allocation skipped");
+
+ return;
+ }
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
+
+ /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
+ * version 1.2.1
+ */
+ info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr,
+ PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16))));
+
+ if (info_ptr->hist == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for hIST chunk data");
+
+ return;
+ }
+
+ info_ptr->free_me |= PNG_FREE_HIST;
+
+ for (i = 0; i < info_ptr->num_palette; i++)
+ info_ptr->hist[i] = hist[i];
+
+ info_ptr->valid |= PNG_INFO_hIST;
+}
+#endif
+
+void PNGAPI
+png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type)
+{
+ png_debug1(1, "in %s storage function", "IHDR");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->width = width;
+ info_ptr->height = height;
+ info_ptr->bit_depth = (png_byte)bit_depth;
+ info_ptr->color_type = (png_byte)color_type;
+ info_ptr->compression_type = (png_byte)compression_type;
+ info_ptr->filter_type = (png_byte)filter_type;
+ info_ptr->interlace_type = (png_byte)interlace_type;
+
+ png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
+ info_ptr->compression_type, info_ptr->filter_type);
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ info_ptr->channels = 1;
+
+ else if ((info_ptr->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ info_ptr->channels = 3;
+
+ else
+ info_ptr->channels = 1;
+
+ if ((info_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ info_ptr->channels++;
+
+ info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
+
+ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
+}
+
+#ifdef PNG_oFFs_SUPPORTED
+void PNGAPI
+png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_int_32 offset_x, png_int_32 offset_y, int unit_type)
+{
+ png_debug1(1, "in %s storage function", "oFFs");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->x_offset = offset_x;
+ info_ptr->y_offset = offset_y;
+ info_ptr->offset_unit_type = (png_byte)unit_type;
+ info_ptr->valid |= PNG_INFO_oFFs;
+}
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+void PNGAPI
+png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
+ int nparams, png_const_charp units, png_charpp params)
+{
+ png_size_t length;
+ int i;
+
+ png_debug1(1, "in %s storage function", "pCAL");
+
+ if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL
+ || (nparams > 0 && params == NULL))
+ return;
+
+ length = strlen(purpose) + 1;
+ png_debug1(3, "allocating purpose for info (%lu bytes)",
+ (unsigned long)length);
+
+ /* TODO: validate format of calibration name and unit name */
+
+ /* Check that the type matches the specification. */
+ if (type < 0 || type > 3)
+ {
+ png_chunk_report(png_ptr, "Invalid pCAL equation type",
+ PNG_CHUNK_WRITE_ERROR);
+ return;
+ }
+
+ if (nparams < 0 || nparams > 255)
+ {
+ png_chunk_report(png_ptr, "Invalid pCAL parameter count",
+ PNG_CHUNK_WRITE_ERROR);
+ return;
+ }
+
+ /* Validate params[nparams] */
+ for (i=0; i<nparams; ++i)
+ {
+ if (params[i] == NULL ||
+ !png_check_fp_string(params[i], strlen(params[i])))
+ {
+ png_chunk_report(png_ptr, "Invalid format for pCAL parameter",
+ PNG_CHUNK_WRITE_ERROR);
+ return;
+ }
+ }
+
+ info_ptr->pcal_purpose = png_voidcast(png_charp,
+ png_malloc_warn(png_ptr, length));
+
+ if (info_ptr->pcal_purpose == NULL)
+ {
+ png_chunk_report(png_ptr, "Insufficient memory for pCAL purpose",
+ PNG_CHUNK_WRITE_ERROR);
+ return;
+ }
+
+ memcpy(info_ptr->pcal_purpose, purpose, length);
+
+ png_debug(3, "storing X0, X1, type, and nparams in info");
+ info_ptr->pcal_X0 = X0;
+ info_ptr->pcal_X1 = X1;
+ info_ptr->pcal_type = (png_byte)type;
+ info_ptr->pcal_nparams = (png_byte)nparams;
+
+ length = strlen(units) + 1;
+ png_debug1(3, "allocating units for info (%lu bytes)",
+ (unsigned long)length);
+
+ info_ptr->pcal_units = png_voidcast(png_charp,
+ png_malloc_warn(png_ptr, length));
+
+ if (info_ptr->pcal_units == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL units");
+
+ return;
+ }
+
+ memcpy(info_ptr->pcal_units, units, length);
+
+ info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
+ (png_size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp)))));
+
+ if (info_ptr->pcal_params == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL params");
+
+ return;
+ }
+
+ memset(info_ptr->pcal_params, 0, ((unsigned int)nparams + 1) *
+ (sizeof (png_charp)));
+
+ for (i = 0; i < nparams; i++)
+ {
+ length = strlen(params[i]) + 1;
+ png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
+ (unsigned long)length);
+
+ info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
+
+ if (info_ptr->pcal_params[i] == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL parameter");
+
+ return;
+ }
+
+ memcpy(info_ptr->pcal_params[i], params[i], length);
+ }
+
+ info_ptr->valid |= PNG_INFO_pCAL;
+ info_ptr->free_me |= PNG_FREE_PCAL;
+}
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+void PNGAPI
+png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
+ int unit, png_const_charp swidth, png_const_charp sheight)
+{
+ png_size_t lengthw = 0, lengthh = 0;
+
+ png_debug1(1, "in %s storage function", "sCAL");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* Double check the unit (should never get here with an invalid
+ * unit unless this is an API call.)
+ */
+ if (unit != 1 && unit != 2)
+ png_error(png_ptr, "Invalid sCAL unit");
+
+ if (swidth == NULL || (lengthw = strlen(swidth)) == 0 ||
+ swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))
+ png_error(png_ptr, "Invalid sCAL width");
+
+ if (sheight == NULL || (lengthh = strlen(sheight)) == 0 ||
+ sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
+ png_error(png_ptr, "Invalid sCAL height");
+
+ info_ptr->scal_unit = (png_byte)unit;
+
+ ++lengthw;
+
+ png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
+
+ info_ptr->scal_s_width = png_voidcast(png_charp,
+ png_malloc_warn(png_ptr, lengthw));
+
+ if (info_ptr->scal_s_width == NULL)
+ {
+ png_warning(png_ptr, "Memory allocation failed while processing sCAL");
+
+ return;
+ }
+
+ memcpy(info_ptr->scal_s_width, swidth, lengthw);
+
+ ++lengthh;
+
+ png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
+
+ info_ptr->scal_s_height = png_voidcast(png_charp,
+ png_malloc_warn(png_ptr, lengthh));
+
+ if (info_ptr->scal_s_height == NULL)
+ {
+ png_free (png_ptr, info_ptr->scal_s_width);
+ info_ptr->scal_s_width = NULL;
+
+ png_warning(png_ptr, "Memory allocation failed while processing sCAL");
+
+ return;
+ }
+
+ memcpy(info_ptr->scal_s_height, sheight, lengthh);
+
+ info_ptr->valid |= PNG_INFO_sCAL;
+ info_ptr->free_me |= PNG_FREE_SCAL;
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
+ double width, double height)
+{
+ png_debug1(1, "in %s storage function", "sCAL");
+
+ /* Check the arguments. */
+ if (width <= 0)
+ png_warning(png_ptr, "Invalid sCAL width ignored");
+
+ else if (height <= 0)
+ png_warning(png_ptr, "Invalid sCAL height ignored");
+
+ else
+ {
+ /* Convert 'width' and 'height' to ASCII. */
+ char swidth[PNG_sCAL_MAX_DIGITS+1];
+ char sheight[PNG_sCAL_MAX_DIGITS+1];
+
+ png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
+ PNG_sCAL_PRECISION);
+ png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
+ PNG_sCAL_PRECISION);
+
+ png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
+ }
+}
+# endif
+
+# ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
+ png_fixed_point width, png_fixed_point height)
+{
+ png_debug1(1, "in %s storage function", "sCAL");
+
+ /* Check the arguments. */
+ if (width <= 0)
+ png_warning(png_ptr, "Invalid sCAL width ignored");
+
+ else if (height <= 0)
+ png_warning(png_ptr, "Invalid sCAL height ignored");
+
+ else
+ {
+ /* Convert 'width' and 'height' to ASCII. */
+ char swidth[PNG_sCAL_MAX_DIGITS+1];
+ char sheight[PNG_sCAL_MAX_DIGITS+1];
+
+ png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width);
+ png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height);
+
+ png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
+ }
+}
+# endif
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+void PNGAPI
+png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_uint_32 res_x, png_uint_32 res_y, int unit_type)
+{
+ png_debug1(1, "in %s storage function", "pHYs");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->x_pixels_per_unit = res_x;
+ info_ptr->y_pixels_per_unit = res_y;
+ info_ptr->phys_unit_type = (png_byte)unit_type;
+ info_ptr->valid |= PNG_INFO_pHYs;
+}
+#endif
+
+void PNGAPI
+png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
+ png_const_colorp palette, int num_palette)
+{
+
+ png_uint_32 max_palette_length;
+
+ png_debug1(1, "in %s storage function", "PLTE");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
+ (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
+
+ if (num_palette < 0 || num_palette > (int) max_palette_length)
+ {
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_error(png_ptr, "Invalid palette length");
+
+ else
+ {
+ png_warning(png_ptr, "Invalid palette length");
+
+ return;
+ }
+ }
+
+ if ((num_palette > 0 && palette == NULL) ||
+ (num_palette == 0
+# ifdef PNG_MNG_FEATURES_SUPPORTED
+ && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
+# endif
+ ))
+ {
+ png_error(png_ptr, "Invalid palette");
+ }
+
+ /* It may not actually be necessary to set png_ptr->palette here;
+ * we do it for backward compatibility with the way the png_handle_tRNS
+ * function used to do the allocation.
+ *
+ * 1.6.0: the above statement appears to be incorrect; something has to set
+ * the palette inside png_struct on read.
+ */
+ png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
+
+ /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
+ * of num_palette entries, in case of an invalid PNG file or incorrect
+ * call to png_set_PLTE() with too-large sample values.
+ */
+ png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
+ PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
+
+ if (num_palette > 0)
+ memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
+ (sizeof (png_color)));
+ info_ptr->palette = png_ptr->palette;
+ info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
+
+ info_ptr->free_me |= PNG_FREE_PLTE;
+
+ info_ptr->valid |= PNG_INFO_PLTE;
+}
+
+#ifdef PNG_sBIT_SUPPORTED
+void PNGAPI
+png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_color_8p sig_bit)
+{
+ png_debug1(1, "in %s storage function", "sBIT");
+
+ if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL)
+ return;
+
+ info_ptr->sig_bit = *sig_bit;
+ info_ptr->valid |= PNG_INFO_sBIT;
+}
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+void PNGAPI
+png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)
+{
+ png_debug1(1, "in %s storage function", "sRGB");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent);
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+void PNGAPI
+png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
+ int srgb_intent)
+{
+ png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace,
+ srgb_intent) != 0)
+ {
+ /* This causes the gAMA and cHRM to be written too */
+ info_ptr->colorspace.flags |=
+ PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
+ }
+
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+#endif /* sRGB */
+
+
+#ifdef PNG_iCCP_SUPPORTED
+void PNGAPI
+png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_charp name, int compression_type,
+ png_const_bytep profile, png_uint_32 proflen)
+{
+ png_charp new_iccp_name;
+ png_bytep new_iccp_profile;
+ png_size_t length;
+
+ png_debug1(1, "in %s storage function", "iCCP");
+
+ if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
+ return;
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ png_app_error(png_ptr, "Invalid iCCP compression method");
+
+ /* Set the colorspace first because this validates the profile; do not
+ * override previously set app cHRM or gAMA here (because likely as not the
+ * application knows better than libpng what the correct values are.) Pass
+ * the info_ptr color_type field to png_colorspace_set_ICC because in the
+ * write case it has not yet been stored in png_ptr.
+ */
+ {
+ int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
+ proflen, profile, info_ptr->color_type);
+
+ png_colorspace_sync_info(png_ptr, info_ptr);
+
+ /* Don't do any of the copying if the profile was bad, or inconsistent. */
+ if (result == 0)
+ return;
+
+ /* But do write the gAMA and cHRM chunks from the profile. */
+ info_ptr->colorspace.flags |=
+ PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
+ }
+
+ length = strlen(name)+1;
+ new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length));
+
+ if (new_iccp_name == NULL)
+ {
+ png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk");
+
+ return;
+ }
+
+ memcpy(new_iccp_name, name, length);
+ new_iccp_profile = png_voidcast(png_bytep,
+ png_malloc_warn(png_ptr, proflen));
+
+ if (new_iccp_profile == NULL)
+ {
+ png_free(png_ptr, new_iccp_name);
+ png_benign_error(png_ptr,
+ "Insufficient memory to process iCCP profile");
+
+ return;
+ }
+
+ memcpy(new_iccp_profile, profile, proflen);
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
+
+ info_ptr->iccp_proflen = proflen;
+ info_ptr->iccp_name = new_iccp_name;
+ info_ptr->iccp_profile = new_iccp_profile;
+ info_ptr->free_me |= PNG_FREE_ICCP;
+ info_ptr->valid |= PNG_INFO_iCCP;
+}
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+void PNGAPI
+png_set_text(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_textp text_ptr, int num_text)
+{
+ int ret;
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
+
+ if (ret != 0)
+ png_error(png_ptr, "Insufficient memory to store text");
+}
+
+int /* PRIVATE */
+png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_textp text_ptr, int num_text)
+{
+ int i;
+
+ png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11U :
+ (unsigned long)png_ptr->chunk_name);
+
+ if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
+ return(0);
+
+ /* Make sure we have enough space in the "text" array in info_struct
+ * to hold all of the incoming text_ptr objects. This compare can't overflow
+ * because max_text >= num_text (anyway, subtract of two positive integers
+ * can't overflow in any case.)
+ */
+ if (num_text > info_ptr->max_text - info_ptr->num_text)
+ {
+ int old_num_text = info_ptr->num_text;
+ int max_text;
+ png_textp new_text = NULL;
+
+ /* Calculate an appropriate max_text, checking for overflow. */
+ max_text = old_num_text;
+ if (num_text <= INT_MAX - max_text)
+ {
+ max_text += num_text;
+
+ /* Round up to a multiple of 8 */
+ if (max_text < INT_MAX-8)
+ max_text = (max_text + 8) & ~0x7;
+
+ else
+ max_text = INT_MAX;
+
+ /* Now allocate a new array and copy the old members in; this does all
+ * the overflow checks.
+ */
+ new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
+ info_ptr->text, old_num_text, max_text-old_num_text,
+ sizeof *new_text));
+ }
+
+ if (new_text == NULL)
+ {
+ png_chunk_report(png_ptr, "too many text chunks",
+ PNG_CHUNK_WRITE_ERROR);
+
+ return 1;
+ }
+
+ png_free(png_ptr, info_ptr->text);
+
+ info_ptr->text = new_text;
+ info_ptr->free_me |= PNG_FREE_TEXT;
+ info_ptr->max_text = max_text;
+ /* num_text is adjusted below as the entries are copied in */
+
+ png_debug1(3, "allocated %d entries for info_ptr->text", max_text);
+ }
+
+ for (i = 0; i < num_text; i++)
+ {
+ size_t text_length, key_len;
+ size_t lang_len, lang_key_len;
+ png_textp textp = &(info_ptr->text[info_ptr->num_text]);
+
+ if (text_ptr[i].key == NULL)
+ continue;
+
+ if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
+ text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
+ {
+ png_chunk_report(png_ptr, "text compression mode is out of range",
+ PNG_CHUNK_WRITE_ERROR);
+ continue;
+ }
+
+ key_len = strlen(text_ptr[i].key);
+
+ if (text_ptr[i].compression <= 0)
+ {
+ lang_len = 0;
+ lang_key_len = 0;
+ }
+
+ else
+# ifdef PNG_iTXt_SUPPORTED
+ {
+ /* Set iTXt data */
+
+ if (text_ptr[i].lang != NULL)
+ lang_len = strlen(text_ptr[i].lang);
+
+ else
+ lang_len = 0;
+
+ if (text_ptr[i].lang_key != NULL)
+ lang_key_len = strlen(text_ptr[i].lang_key);
+
+ else
+ lang_key_len = 0;
+ }
+# else /* iTXt */
+ {
+ png_chunk_report(png_ptr, "iTXt chunk not supported",
+ PNG_CHUNK_WRITE_ERROR);
+ continue;
+ }
+# endif
+
+ if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
+ {
+ text_length = 0;
+# ifdef PNG_iTXt_SUPPORTED
+ if (text_ptr[i].compression > 0)
+ textp->compression = PNG_ITXT_COMPRESSION_NONE;
+
+ else
+# endif
+ textp->compression = PNG_TEXT_COMPRESSION_NONE;
+ }
+
+ else
+ {
+ text_length = strlen(text_ptr[i].text);
+ textp->compression = text_ptr[i].compression;
+ }
+
+ textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr,
+ key_len + text_length + lang_len + lang_key_len + 4));
+
+ if (textp->key == NULL)
+ {
+ png_chunk_report(png_ptr, "text chunk: out of memory",
+ PNG_CHUNK_WRITE_ERROR);
+
+ return 1;
+ }
+
+ png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
+ (unsigned long)(png_uint_32)
+ (key_len + lang_len + lang_key_len + text_length + 4),
+ textp->key);
+
+ memcpy(textp->key, text_ptr[i].key, key_len);
+ *(textp->key + key_len) = '\0';
+
+ if (text_ptr[i].compression > 0)
+ {
+ textp->lang = textp->key + key_len + 1;
+ memcpy(textp->lang, text_ptr[i].lang, lang_len);
+ *(textp->lang + lang_len) = '\0';
+ textp->lang_key = textp->lang + lang_len + 1;
+ memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
+ *(textp->lang_key + lang_key_len) = '\0';
+ textp->text = textp->lang_key + lang_key_len + 1;
+ }
+
+ else
+ {
+ textp->lang=NULL;
+ textp->lang_key=NULL;
+ textp->text = textp->key + key_len + 1;
+ }
+
+ if (text_length != 0)
+ memcpy(textp->text, text_ptr[i].text, text_length);
+
+ *(textp->text + text_length) = '\0';
+
+# ifdef PNG_iTXt_SUPPORTED
+ if (textp->compression > 0)
+ {
+ textp->text_length = 0;
+ textp->itxt_length = text_length;
+ }
+
+ else
+# endif
+ {
+ textp->text_length = text_length;
+ textp->itxt_length = 0;
+ }
+
+ info_ptr->num_text++;
+ png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
+ }
+
+ return(0);
+}
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+void PNGAPI
+png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_timep mod_time)
+{
+ png_debug1(1, "in %s storage function", "tIME");
+
+ if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL ||
+ (png_ptr->mode & PNG_WROTE_tIME) != 0)
+ return;
+
+ if (mod_time->month == 0 || mod_time->month > 12 ||
+ mod_time->day == 0 || mod_time->day > 31 ||
+ mod_time->hour > 23 || mod_time->minute > 59 ||
+ mod_time->second > 60)
+ {
+ png_warning(png_ptr, "Ignoring invalid time value");
+
+ return;
+ }
+
+ info_ptr->mod_time = *mod_time;
+ info_ptr->valid |= PNG_INFO_tIME;
+}
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+void PNGAPI
+png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
+ png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
+{
+ png_debug1(1, "in %s storage function", "tRNS");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+
+ return;
+
+ if (trans_alpha != NULL)
+ {
+ /* It may not actually be necessary to set png_ptr->trans_alpha here;
+ * we do it for backward compatibility with the way the png_handle_tRNS
+ * function used to do the allocation.
+ *
+ * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively
+ * relies on png_set_tRNS storing the information in png_struct
+ * (otherwise it won't be there for the code in pngrtran.c).
+ */
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
+
+ if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
+ {
+ /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
+ info_ptr->trans_alpha = png_voidcast(png_bytep,
+ png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
+ memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
+ }
+ png_ptr->trans_alpha = info_ptr->trans_alpha;
+ }
+
+ if (trans_color != NULL)
+ {
+#ifdef PNG_WARNINGS_SUPPORTED
+ if (info_ptr->bit_depth < 16)
+ {
+ int sample_max = (1 << info_ptr->bit_depth) - 1;
+
+ if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
+ trans_color->gray > sample_max) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
+ (trans_color->red > sample_max ||
+ trans_color->green > sample_max ||
+ trans_color->blue > sample_max)))
+ png_warning(png_ptr,
+ "tRNS chunk has out-of-range samples for bit_depth");
+ }
+#endif
+
+ info_ptr->trans_color = *trans_color;
+
+ if (num_trans == 0)
+ num_trans = 1;
+ }
+
+ info_ptr->num_trans = (png_uint_16)num_trans;
+
+ if (num_trans != 0)
+ {
+ info_ptr->valid |= PNG_INFO_tRNS;
+ info_ptr->free_me |= PNG_FREE_TRNS;
+ }
+}
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+void PNGAPI
+png_set_sPLT(png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)
+/*
+ * entries - array of png_sPLT_t structures
+ * to be added to the list of palettes
+ * in the info structure.
+ *
+ * nentries - number of palette structures to be
+ * added.
+ */
+{
+ png_sPLT_tp np;
+
+ if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)
+ return;
+
+ /* Use the internal realloc function, which checks for all the possible
+ * overflows. Notice that the parameters are (int) and (size_t)
+ */
+ np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
+ info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
+ sizeof *np));
+
+ if (np == NULL)
+ {
+ /* Out of memory or too many chunks */
+ png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR);
+
+ return;
+ }
+
+ png_free(png_ptr, info_ptr->splt_palettes);
+ info_ptr->splt_palettes = np;
+ info_ptr->free_me |= PNG_FREE_SPLT;
+
+ np += info_ptr->splt_palettes_num;
+
+ do
+ {
+ png_size_t length;
+
+ /* Skip invalid input entries */
+ if (entries->name == NULL || entries->entries == NULL)
+ {
+ /* png_handle_sPLT doesn't do this, so this is an app error */
+ png_app_error(png_ptr, "png_set_sPLT: invalid sPLT");
+ /* Just skip the invalid entry */
+ continue;
+ }
+
+ np->depth = entries->depth;
+
+ /* In the event of out-of-memory just return - there's no point keeping
+ * on trying to add sPLT chunks.
+ */
+ length = strlen(entries->name) + 1;
+ np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length));
+
+ if (np->name == NULL)
+ break;
+
+ memcpy(np->name, entries->name, length);
+
+ /* IMPORTANT: we have memory now that won't get freed if something else
+ * goes wrong; this code must free it. png_malloc_array produces no
+ * warnings; use a png_chunk_report (below) if there is an error.
+ */
+ np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr,
+ entries->nentries, sizeof (png_sPLT_entry)));
+
+ if (np->entries == NULL)
+ {
+ png_free(png_ptr, np->name);
+ np->name = NULL;
+ break;
+ }
+
+ np->nentries = entries->nentries;
+ /* This multiply can't overflow because png_malloc_array has already
+ * checked it when doing the allocation.
+ */
+ memcpy(np->entries, entries->entries,
+ (unsigned int)entries->nentries * sizeof (png_sPLT_entry));
+
+ /* Note that 'continue' skips the advance of the out pointer and out
+ * count, so an invalid entry is not added.
+ */
+ info_ptr->valid |= PNG_INFO_sPLT;
+ ++(info_ptr->splt_palettes_num);
+ ++np;
+ ++entries;
+ }
+ while (--nentries);
+
+ if (nentries > 0)
+ png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
+}
+#endif /* sPLT */
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+static png_byte
+check_location(png_const_structrp png_ptr, int location)
+{
+ location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);
+
+ /* New in 1.6.0; copy the location and check it. This is an API
+ * change; previously the app had to use the
+ * png_set_unknown_chunk_location API below for each chunk.
+ */
+ if (location == 0 && (png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+ {
+ /* Write struct, so unknown chunks come from the app */
+ png_app_warning(png_ptr,
+ "png_set_unknown_chunks now expects a valid location");
+ /* Use the old behavior */
+ location = (png_byte)(png_ptr->mode &
+ (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
+ }
+
+ /* This need not be an internal error - if the app calls
+ * png_set_unknown_chunks on a read pointer it must get the location right.
+ */
+ if (location == 0)
+ png_error(png_ptr, "invalid location in png_set_unknown_chunks");
+
+ /* Now reduce the location to the top-most set bit by removing each least
+ * significant bit in turn.
+ */
+ while (location != (location & -location))
+ location &= ~(location & -location);
+
+ /* The cast is safe because 'location' is a bit mask and only the low four
+ * bits are significant.
+ */
+ return (png_byte)location;
+}
+
+void PNGAPI
+png_set_unknown_chunks(png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
+{
+ png_unknown_chunkp np;
+
+ if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 ||
+ unknowns == NULL)
+ return;
+
+ /* Check for the failure cases where support has been disabled at compile
+ * time. This code is hardly ever compiled - it's here because
+ * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this
+ * code) but may be meaningless if the read or write handling of unknown
+ * chunks is not compiled in.
+ */
+# if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \
+ defined(PNG_READ_SUPPORTED)
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+ {
+ png_app_error(png_ptr, "no unknown chunk support on read");
+
+ return;
+ }
+# endif
+# if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \
+ defined(PNG_WRITE_SUPPORTED)
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+ {
+ png_app_error(png_ptr, "no unknown chunk support on write");
+
+ return;
+ }
+# endif
+
+ /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that
+ * unknown critical chunks could be lost with just a warning resulting in
+ * undefined behavior. Now png_chunk_report is used to provide behavior
+ * appropriate to read or write.
+ */
+ np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
+ info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
+ sizeof *np));
+
+ if (np == NULL)
+ {
+ png_chunk_report(png_ptr, "too many unknown chunks",
+ PNG_CHUNK_WRITE_ERROR);
+
+ return;
+ }
+
+ png_free(png_ptr, info_ptr->unknown_chunks);
+ info_ptr->unknown_chunks = np; /* safe because it is initialized */
+ info_ptr->free_me |= PNG_FREE_UNKN;
+
+ np += info_ptr->unknown_chunks_num;
+
+ /* Increment unknown_chunks_num each time round the loop to protect the
+ * just-allocated chunk data.
+ */
+ for (; num_unknowns > 0; --num_unknowns, ++unknowns)
+ {
+ memcpy(np->name, unknowns->name, (sizeof np->name));
+ np->name[(sizeof np->name)-1] = '\0';
+ np->location = check_location(png_ptr, unknowns->location);
+
+ if (unknowns->size == 0)
+ {
+ np->data = NULL;
+ np->size = 0;
+ }
+
+ else
+ {
+ np->data = png_voidcast(png_bytep,
+ png_malloc_base(png_ptr, unknowns->size));
+
+ if (np->data == NULL)
+ {
+ png_chunk_report(png_ptr, "unknown chunk: out of memory",
+ PNG_CHUNK_WRITE_ERROR);
+ /* But just skip storing the unknown chunk */
+ continue;
+ }
+
+ memcpy(np->data, unknowns->data, unknowns->size);
+ np->size = unknowns->size;
+ }
+
+ /* These increments are skipped on out-of-memory for the data - the
+ * unknown chunk entry gets overwritten if the png_chunk_report returns.
+ * This is correct in the read case (the chunk is just dropped.)
+ */
+ ++np;
+ ++(info_ptr->unknown_chunks_num);
+ }
+}
+
+void PNGAPI
+png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
+ int chunk, int location)
+{
+ /* This API is pretty pointless in 1.6.0 because the location can be set
+ * before the call to png_set_unknown_chunks.
+ *
+ * TODO: add a png_app_warning in 1.7
+ */
+ if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 &&
+ chunk < info_ptr->unknown_chunks_num)
+ {
+ if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0)
+ {
+ png_app_error(png_ptr, "invalid unknown chunk location");
+ /* Fake out the pre 1.6.0 behavior: */
+ if (((unsigned int)location & PNG_HAVE_IDAT) != 0) /* undocumented! */
+ location = PNG_AFTER_IDAT;
+
+ else
+ location = PNG_HAVE_IHDR; /* also undocumented */
+ }
+
+ info_ptr->unknown_chunks[chunk].location =
+ check_location(png_ptr, location);
+ }
+}
+#endif /* STORE_UNKNOWN_CHUNKS */
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+png_uint_32 PNGAPI
+png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features)
+{
+ png_debug(1, "in png_permit_mng_features");
+
+ if (png_ptr == NULL)
+ return 0;
+
+ png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES;
+
+ return png_ptr->mng_features_permitted;
+}
+#endif
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+static unsigned int
+add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)
+{
+ unsigned int i;
+
+ /* Utility function: update the 'keep' state of a chunk if it is already in
+ * the list, otherwise add it to the list.
+ */
+ for (i=0; i<count; ++i, list += 5)
+ {
+ if (memcmp(list, add, 4) == 0)
+ {
+ list[4] = (png_byte)keep;
+
+ return count;
+ }
+ }
+
+ if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT)
+ {
+ ++count;
+ memcpy(list, add, 4);
+ list[4] = (png_byte)keep;
+ }
+
+ return count;
+}
+
+void PNGAPI
+png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
+ png_const_bytep chunk_list, int num_chunks_in)
+{
+ png_bytep new_list;
+ unsigned int num_chunks, old_num_chunks;
+
+ if (png_ptr == NULL)
+ return;
+
+ if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST)
+ {
+ png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep");
+
+ return;
+ }
+
+ if (num_chunks_in <= 0)
+ {
+ png_ptr->unknown_default = keep;
+
+ /* '0' means just set the flags, so stop here */
+ if (num_chunks_in == 0)
+ return;
+ }
+
+ if (num_chunks_in < 0)
+ {
+ /* Ignore all unknown chunks and all chunks recognized by
+ * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
+ */
+ static PNG_CONST png_byte chunks_to_ignore[] = {
+ 98, 75, 71, 68, '\0', /* bKGD */
+ 99, 72, 82, 77, '\0', /* cHRM */
+ 101, 88, 73, 102, '\0', /* eXIf */
+ 103, 65, 77, 65, '\0', /* gAMA */
+ 104, 73, 83, 84, '\0', /* hIST */
+ 105, 67, 67, 80, '\0', /* iCCP */
+ 105, 84, 88, 116, '\0', /* iTXt */
+ 111, 70, 70, 115, '\0', /* oFFs */
+ 112, 67, 65, 76, '\0', /* pCAL */
+ 112, 72, 89, 115, '\0', /* pHYs */
+ 115, 66, 73, 84, '\0', /* sBIT */
+ 115, 67, 65, 76, '\0', /* sCAL */
+ 115, 80, 76, 84, '\0', /* sPLT */
+ 115, 84, 69, 82, '\0', /* sTER */
+ 115, 82, 71, 66, '\0', /* sRGB */
+ 116, 69, 88, 116, '\0', /* tEXt */
+ 116, 73, 77, 69, '\0', /* tIME */
+ 122, 84, 88, 116, '\0' /* zTXt */
+ };
+
+ chunk_list = chunks_to_ignore;
+ num_chunks = (unsigned int)/*SAFE*/(sizeof chunks_to_ignore)/5U;
+ }
+
+ else /* num_chunks_in > 0 */
+ {
+ if (chunk_list == NULL)
+ {
+ /* Prior to 1.6.0 this was silently ignored, now it is an app_error
+ * which can be switched off.
+ */
+ png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list");
+
+ return;
+ }
+
+ num_chunks = (unsigned int)num_chunks_in;
+ }
+
+ old_num_chunks = png_ptr->num_chunk_list;
+ if (png_ptr->chunk_list == NULL)
+ old_num_chunks = 0;
+
+ /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow.
+ */
+ if (num_chunks + old_num_chunks > UINT_MAX/5)
+ {
+ png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
+
+ return;
+ }
+
+ /* If these chunks are being reset to the default then no more memory is
+ * required because add_one_chunk above doesn't extend the list if the 'keep'
+ * parameter is the default.
+ */
+ if (keep != 0)
+ {
+ new_list = png_voidcast(png_bytep, png_malloc(png_ptr,
+ 5 * (num_chunks + old_num_chunks)));
+
+ if (old_num_chunks > 0)
+ memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
+ }
+
+ else if (old_num_chunks > 0)
+ new_list = png_ptr->chunk_list;
+
+ else
+ new_list = NULL;
+
+ /* Add the new chunks together with each one's handling code. If the chunk
+ * already exists the code is updated, otherwise the chunk is added to the
+ * end. (In libpng 1.6.0 order no longer matters because this code enforces
+ * the earlier convention that the last setting is the one that is used.)
+ */
+ if (new_list != NULL)
+ {
+ png_const_bytep inlist;
+ png_bytep outlist;
+ unsigned int i;
+
+ for (i=0; i<num_chunks; ++i)
+ {
+ old_num_chunks = add_one_chunk(new_list, old_num_chunks,
+ chunk_list+5*i, keep);
+ }
+
+ /* Now remove any spurious 'default' entries. */
+ num_chunks = 0;
+ for (i=0, inlist=outlist=new_list; i<old_num_chunks; ++i, inlist += 5)
+ {
+ if (inlist[4])
+ {
+ if (outlist != inlist)
+ memcpy(outlist, inlist, 5);
+ outlist += 5;
+ ++num_chunks;
+ }
+ }
+
+ /* This means the application has removed all the specialized handling. */
+ if (num_chunks == 0)
+ {
+ if (png_ptr->chunk_list != new_list)
+ png_free(png_ptr, new_list);
+
+ new_list = NULL;
+ }
+ }
+
+ else
+ num_chunks = 0;
+
+ png_ptr->num_chunk_list = num_chunks;
+
+ if (png_ptr->chunk_list != new_list)
+ {
+ if (png_ptr->chunk_list != NULL)
+ png_free(png_ptr, png_ptr->chunk_list);
+
+ png_ptr->chunk_list = new_list;
+ }
+}
+#endif
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+void PNGAPI
+png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr,
+ png_user_chunk_ptr read_user_chunk_fn)
+{
+ png_debug(1, "in png_set_read_user_chunk_fn");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->read_user_chunk_fn = read_user_chunk_fn;
+ png_ptr->user_chunk_ptr = user_chunk_ptr;
+}
+#endif
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_bytepp row_pointers)
+{
+ png_debug1(1, "in %s storage function", "rows");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (info_ptr->row_pointers != NULL &&
+ (info_ptr->row_pointers != row_pointers))
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+
+ info_ptr->row_pointers = row_pointers;
+
+ if (row_pointers != NULL)
+ info_ptr->valid |= PNG_INFO_IDAT;
+}
+#endif
+
+void PNGAPI
+png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)
+{
+ if (png_ptr == NULL)
+ return;
+
+ if (size == 0 || size > PNG_UINT_31_MAX)
+ png_error(png_ptr, "invalid compression buffer size");
+
+# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+ {
+ png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
+ return;
+ }
+# endif
+
+# ifdef PNG_WRITE_SUPPORTED
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
+ {
+ if (png_ptr->zowner != 0)
+ {
+ png_warning(png_ptr,
+ "Compression buffer size cannot be changed because it is in use");
+
+ return;
+ }
+
+#ifndef __COVERITY__
+ /* Some compilers complain that this is always false. However, it
+ * can be true when integer overflow happens.
+ */
+ if (size > ZLIB_IO_MAX)
+ {
+ png_warning(png_ptr,
+ "Compression buffer size limited to system maximum");
+ size = ZLIB_IO_MAX; /* must fit */
+ }
+#endif
+
+ if (size < 6)
+ {
+ /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
+ * if this is permitted.
+ */
+ png_warning(png_ptr,
+ "Compression buffer size cannot be reduced below 6");
+
+ return;
+ }
+
+ if (png_ptr->zbuffer_size != size)
+ {
+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+ png_ptr->zbuffer_size = (uInt)size;
+ }
+ }
+# endif
+}
+
+void PNGAPI
+png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ info_ptr->valid &= (unsigned int)(~mask);
+}
+
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* This function was added to libpng 1.2.6 */
+void PNGAPI
+png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max,
+ png_uint_32 user_height_max)
+{
+ /* Images with dimensions larger than these limits will be
+ * rejected by png_set_IHDR(). To accept any PNG datastream
+ * regardless of dimensions, set both limits to 0x7fffffff.
+ */
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->user_width_max = user_width_max;
+ png_ptr->user_height_max = user_height_max;
+}
+
+/* This function was added to libpng 1.4.0 */
+void PNGAPI
+png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
+{
+ if (png_ptr != NULL)
+ png_ptr->user_chunk_cache_max = user_chunk_cache_max;
+}
+
+/* This function was added to libpng 1.4.1 */
+void PNGAPI
+png_set_chunk_malloc_max (png_structrp png_ptr,
+ png_alloc_size_t user_chunk_malloc_max)
+{
+ if (png_ptr != NULL)
+ png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
+}
+#endif /* ?SET_USER_LIMITS */
+
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_set_benign_errors(png_structrp png_ptr, int allowed)
+{
+ png_debug(1, "in png_set_benign_errors");
+
+ /* If allowed is 1, png_benign_error() is treated as a warning.
+ *
+ * If allowed is 0, png_benign_error() is treated as an error (which
+ * is the default behavior if png_set_benign_errors() is not called).
+ */
+
+ if (allowed != 0)
+ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN |
+ PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN;
+
+ else
+ png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN |
+ PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN);
+}
+#endif /* BENIGN_ERRORS */
+
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ /* Whether to report invalid palette index; added at libng-1.5.10.
+ * It is possible for an indexed (color-type==3) PNG file to contain
+ * pixels with invalid (out-of-range) indexes if the PLTE chunk has
+ * fewer entries than the image's bit-depth would allow. We recover
+ * from this gracefully by filling any incomplete palette with zeros
+ * (opaque black). By default, when this occurs libpng will issue
+ * a benign error. This API can be used to override that behavior.
+ */
+void PNGAPI
+png_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
+{
+ png_debug(1, "in png_set_check_for_invalid_index");
+
+ if (allowed > 0)
+ png_ptr->num_palette_max = 0;
+
+ else
+ png_ptr->num_palette_max = -1;
+}
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) || \
+ defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
+/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
+ * and if invalid, correct the keyword rather than discarding the entire
+ * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
+ * length, forbids leading or trailing whitespace, multiple internal spaces,
+ * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
+ *
+ * The 'new_key' buffer must be 80 characters in size (for the keyword plus a
+ * trailing '\0'). If this routine returns 0 then there was no keyword, or a
+ * valid one could not be generated, and the caller must png_error.
+ */
+png_uint_32 /* PRIVATE */
+png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
+{
+#ifdef PNG_WARNINGS_SUPPORTED
+ png_const_charp orig_key = key;
+#endif
+ png_uint_32 key_len = 0;
+ int bad_character = 0;
+ int space = 1;
+
+ png_debug(1, "in png_check_keyword");
+
+ if (key == NULL)
+ {
+ *new_key = 0;
+ return 0;
+ }
+
+ while (*key && key_len < 79)
+ {
+ png_byte ch = (png_byte)*key++;
+
+ if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
+ {
+ *new_key++ = ch; ++key_len; space = 0;
+ }
+
+ else if (space == 0)
+ {
+ /* A space or an invalid character when one wasn't seen immediately
+ * before; output just a space.
+ */
+ *new_key++ = 32; ++key_len; space = 1;
+
+ /* If the character was not a space then it is invalid. */
+ if (ch != 32)
+ bad_character = ch;
+ }
+
+ else if (bad_character == 0)
+ bad_character = ch; /* just skip it, record the first error */
+ }
+
+ if (key_len > 0 && space != 0) /* trailing space */
+ {
+ --key_len; --new_key;
+ if (bad_character == 0)
+ bad_character = 32;
+ }
+
+ /* Terminate the keyword */
+ *new_key = 0;
+
+ if (key_len == 0)
+ return 0;
+
+#ifdef PNG_WARNINGS_SUPPORTED
+ /* Try to only output one warning per keyword: */
+ if (*key != 0) /* keyword too long */
+ png_warning(png_ptr, "keyword truncated");
+
+ else if (bad_character != 0)
+ {
+ PNG_WARNING_PARAMETERS(p)
+
+ png_warning_parameter(p, 1, orig_key);
+ png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
+
+ png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
+ }
+#else /* !WARNINGS */
+ PNG_UNUSED(png_ptr)
+#endif /* !WARNINGS */
+
+ return key_len;
+}
+#endif /* TEXT || pCAL || iCCP || sPLT */
+#endif /* READ || WRITE */
diff --git a/xs/src/png/libpng/pngstruct.h b/xs/src/png/libpng/pngstruct.h
new file mode 100644
index 000000000..d83f97125
--- /dev/null
+++ b/xs/src/png/libpng/pngstruct.h
@@ -0,0 +1,483 @@
+
+/* pngstruct.h - header file for PNG reference library
+ *
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* The structure that holds the information to read and write PNG files.
+ * The only people who need to care about what is inside of this are the
+ * people who will be modifying the library for their own special needs.
+ * It should NOT be accessed directly by an application.
+ */
+
+#ifndef PNGSTRUCT_H
+#define PNGSTRUCT_H
+/* zlib.h defines the structure z_stream, an instance of which is included
+ * in this structure and is required for decompressing the LZ compressed
+ * data in PNG files.
+ */
+#ifndef ZLIB_CONST
+ /* We must ensure that zlib uses 'const' in declarations. */
+# define ZLIB_CONST
+#endif
+#include "zlib.h"
+#ifdef const
+ /* zlib.h sometimes #defines const to nothing, undo this. */
+# undef const
+#endif
+
+/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility
+ * with older builds.
+ */
+#if ZLIB_VERNUM < 0x1260
+# define PNGZ_MSG_CAST(s) png_constcast(char*,s)
+# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b)
+#else
+# define PNGZ_MSG_CAST(s) (s)
+# define PNGZ_INPUT_CAST(b) (b)
+#endif
+
+/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
+ * can handle at once. This type need be no larger than 16 bits (so maximum of
+ * 65535), this define allows us to discover how big it is, but limited by the
+ * maximuum for png_size_t. The value can be overriden in a library build
+ * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
+ * lower value (e.g. 255 works). A lower value may help memory usage (slightly)
+ * and may even improve performance on some systems (and degrade it on others.)
+ */
+#ifndef ZLIB_IO_MAX
+# define ZLIB_IO_MAX ((uInt)-1)
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+/* The type of a compression buffer list used by the write code. */
+typedef struct png_compression_buffer
+{
+ struct png_compression_buffer *next;
+ png_byte output[1]; /* actually zbuf_size */
+} png_compression_buffer, *png_compression_bufferp;
+
+#define PNG_COMPRESSION_BUFFER_SIZE(pp)\
+ (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size)
+#endif
+
+/* Colorspace support; structures used in png_struct, png_info and in internal
+ * functions to hold and communicate information about the color space.
+ *
+ * PNG_COLORSPACE_SUPPORTED is only required if the application will perform
+ * colorspace corrections, otherwise all the colorspace information can be
+ * skipped and the size of libpng can be reduced (significantly) by compiling
+ * out the colorspace support.
+ */
+#ifdef PNG_COLORSPACE_SUPPORTED
+/* The chromaticities of the red, green and blue colorants and the chromaticity
+ * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)).
+ */
+typedef struct png_xy
+{
+ png_fixed_point redx, redy;
+ png_fixed_point greenx, greeny;
+ png_fixed_point bluex, bluey;
+ png_fixed_point whitex, whitey;
+} png_xy;
+
+/* The same data as above but encoded as CIE XYZ values. When this data comes
+ * from chromaticities the sum of the Y values is assumed to be 1.0
+ */
+typedef struct png_XYZ
+{
+ png_fixed_point red_X, red_Y, red_Z;
+ png_fixed_point green_X, green_Y, green_Z;
+ png_fixed_point blue_X, blue_Y, blue_Z;
+} png_XYZ;
+#endif /* COLORSPACE */
+
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+/* A colorspace is all the above plus, potentially, profile information;
+ * however at present libpng does not use the profile internally so it is only
+ * stored in the png_info struct (if iCCP is supported.) The rendering intent
+ * is retained here and is checked.
+ *
+ * The file gamma encoding information is also stored here and gamma correction
+ * is done by libpng, whereas color correction must currently be done by the
+ * application.
+ */
+typedef struct png_colorspace
+{
+#ifdef PNG_GAMMA_SUPPORTED
+ png_fixed_point gamma; /* File gamma */
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+ png_xy end_points_xy; /* End points as chromaticities */
+ png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */
+ png_uint_16 rendering_intent; /* Rendering intent of a profile */
+#endif
+
+ /* Flags are always defined to simplify the code. */
+ png_uint_16 flags; /* As defined below */
+} png_colorspace, * PNG_RESTRICT png_colorspacerp;
+
+typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp;
+
+/* General flags for the 'flags' field */
+#define PNG_COLORSPACE_HAVE_GAMMA 0x0001
+#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002
+#define PNG_COLORSPACE_HAVE_INTENT 0x0004
+#define PNG_COLORSPACE_FROM_gAMA 0x0008
+#define PNG_COLORSPACE_FROM_cHRM 0x0010
+#define PNG_COLORSPACE_FROM_sRGB 0x0020
+#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040
+#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */
+#define PNG_COLORSPACE_INVALID 0x8000
+#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags))
+#endif /* COLORSPACE || GAMMA */
+
+struct png_struct_def
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf jmp_buf_local; /* New name in 1.6.0 for jmp_buf in png_struct */
+ png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */
+ jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */
+ size_t jmp_buf_size; /* size of the above, if allocated */
+#endif
+ png_error_ptr error_fn; /* function for printing errors and aborting */
+#ifdef PNG_WARNINGS_SUPPORTED
+ png_error_ptr warning_fn; /* function for printing warnings */
+#endif
+ png_voidp error_ptr; /* user supplied struct for error functions */
+ png_rw_ptr write_data_fn; /* function for writing output data */
+ png_rw_ptr read_data_fn; /* function for reading input data */
+ png_voidp io_ptr; /* ptr to application struct for I/O functions */
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ png_user_transform_ptr read_user_transform_fn; /* user read transform */
+#endif
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+ png_user_transform_ptr write_user_transform_fn; /* user write transform */
+#endif
+
+/* These were added in libpng-1.0.2 */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ png_voidp user_transform_ptr; /* user supplied struct for user transform */
+ png_byte user_transform_depth; /* bit depth of user transformed pixels */
+ png_byte user_transform_channels; /* channels in user transformed pixels */
+#endif
+#endif
+
+ png_uint_32 mode; /* tells us where we are in the PNG file */
+ png_uint_32 flags; /* flags indicating various things to libpng */
+ png_uint_32 transformations; /* which transformations to perform */
+
+ png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */
+ z_stream zstream; /* decompression structure */
+
+#ifdef PNG_WRITE_SUPPORTED
+ png_compression_bufferp zbuffer_list; /* Created on demand during write */
+ uInt zbuffer_size; /* size of the actual buffer */
+
+ int zlib_level; /* holds zlib compression level */
+ int zlib_method; /* holds zlib compression method */
+ int zlib_window_bits; /* holds zlib compression window bits */
+ int zlib_mem_level; /* holds zlib compression memory level */
+ int zlib_strategy; /* holds zlib compression strategy */
+#endif
+/* Added at libpng 1.5.4 */
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+ int zlib_text_level; /* holds zlib compression level */
+ int zlib_text_method; /* holds zlib compression method */
+ int zlib_text_window_bits; /* holds zlib compression window bits */
+ int zlib_text_mem_level; /* holds zlib compression memory level */
+ int zlib_text_strategy; /* holds zlib compression strategy */
+#endif
+/* End of material added at libpng 1.5.4 */
+/* Added at libpng 1.6.0 */
+#ifdef PNG_WRITE_SUPPORTED
+ int zlib_set_level; /* Actual values set into the zstream on write */
+ int zlib_set_method;
+ int zlib_set_window_bits;
+ int zlib_set_mem_level;
+ int zlib_set_strategy;
+#endif
+
+ png_uint_32 width; /* width of image in pixels */
+ png_uint_32 height; /* height of image in pixels */
+ png_uint_32 num_rows; /* number of rows in current pass */
+ png_uint_32 usr_width; /* width of row at start of write */
+ png_size_t rowbytes; /* size of row in bytes */
+ png_uint_32 iwidth; /* width of current interlaced row in pixels */
+ png_uint_32 row_number; /* current row in interlace pass */
+ png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */
+ png_bytep prev_row; /* buffer to save previous (unfiltered) row.
+ * While reading this is a pointer into
+ * big_prev_row; while writing it is separately
+ * allocated if needed.
+ */
+ png_bytep row_buf; /* buffer to save current (unfiltered) row.
+ * While reading, this is a pointer into
+ * big_row_buf; while writing it is separately
+ * allocated.
+ */
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ png_bytep try_row; /* buffer to save trial row when filtering */
+ png_bytep tst_row; /* buffer to save best trial row when filtering */
+#endif
+ png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */
+
+ png_uint_32 idat_size; /* current IDAT size for read */
+ png_uint_32 crc; /* current chunk CRC value */
+ png_colorp palette; /* palette from the input file */
+ png_uint_16 num_palette; /* number of color entries in palette */
+
+/* Added at libpng-1.5.10 */
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ int num_palette_max; /* maximum palette index found in IDAT */
+#endif
+
+ png_uint_16 num_trans; /* number of transparency values */
+ png_byte compression; /* file compression type (always 0) */
+ png_byte filter; /* file filter type (always 0) */
+ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+ png_byte pass; /* current interlace pass (0 - 6) */
+ png_byte do_filter; /* row filter flags (see PNG_FILTER_ in png.h ) */
+ png_byte color_type; /* color type of file */
+ png_byte bit_depth; /* bit depth of file */
+ png_byte usr_bit_depth; /* bit depth of users row: write only */
+ png_byte pixel_depth; /* number of bits per pixel */
+ png_byte channels; /* number of channels in file */
+#ifdef PNG_WRITE_SUPPORTED
+ png_byte usr_channels; /* channels at start of write: write only */
+#endif
+ png_byte sig_bytes; /* magic bytes read/written from start of file */
+ png_byte maximum_pixel_depth;
+ /* pixel depth used for the row buffers */
+ png_byte transformed_pixel_depth;
+ /* pixel depth after read/write transforms */
+#if ZLIB_VERNUM >= 0x1240
+ png_byte zstream_start; /* at start of an input zlib stream */
+#endif /* Zlib >= 1.2.4 */
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+ png_uint_16 filler; /* filler bytes for pixel expansion */
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+ png_byte background_gamma_type;
+ png_fixed_point background_gamma;
+ png_color_16 background; /* background color in screen gamma space */
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ png_color_16 background_1; /* background normalized to gamma 1.0 */
+#endif
+#endif /* bKGD */
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+ png_flush_ptr output_flush_fn; /* Function for flushing output */
+ png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
+ png_uint_32 flush_rows; /* number of rows written since last flush */
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */
+ png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
+
+ png_bytep gamma_table; /* gamma table for 8-bit depth files */
+ png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ png_bytep gamma_from_1; /* converts from 1.0 to screen */
+ png_bytep gamma_to_1; /* converts from file to 1.0 */
+ png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
+ png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
+ png_color_8 sig_bit; /* significant bits in each available channel */
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+ png_color_8 shift; /* shift for significant bit tranformation */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
+ || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_bytep trans_alpha; /* alpha values for paletted files */
+ png_color_16 trans_color; /* transparent color for non-paletted files */
+#endif
+
+ png_read_status_ptr read_row_fn; /* called after each row is decoded */
+ png_write_status_ptr write_row_fn; /* called after each row is encoded */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ png_progressive_info_ptr info_fn; /* called after header data fully read */
+ png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */
+ png_progressive_end_ptr end_fn; /* called after image is complete */
+ png_bytep save_buffer_ptr; /* current location in save_buffer */
+ png_bytep save_buffer; /* buffer for previously read data */
+ png_bytep current_buffer_ptr; /* current location in current_buffer */
+ png_bytep current_buffer; /* buffer for recently used data */
+ png_uint_32 push_length; /* size of current input chunk */
+ png_uint_32 skip_length; /* bytes to skip in input data */
+ png_size_t save_buffer_size; /* amount of data now in save_buffer */
+ png_size_t save_buffer_max; /* total size of save_buffer */
+ png_size_t buffer_size; /* total amount of available input data */
+ png_size_t current_buffer_size; /* amount of data now in current_buffer */
+ int process_mode; /* what push library is currently doing */
+ int cur_palette; /* current push library palette index */
+
+#endif /* PROGRESSIVE_READ */
+
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* For the Borland special 64K segment handler */
+ png_bytepp offset_table_ptr;
+ png_bytep offset_table;
+ png_uint_16 offset_table_number;
+ png_uint_16 offset_table_count;
+ png_uint_16 offset_table_count_free;
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+ png_bytep palette_lookup; /* lookup table for quantizing */
+ png_bytep quantize_index; /* index translation for palette files */
+#endif
+
+/* Options */
+#ifdef PNG_SET_OPTION_SUPPORTED
+ png_uint_32 options; /* On/off state (up to 16 options) */
+#endif
+
+#if PNG_LIBPNG_VER < 10700
+/* To do: remove this from libpng-1.7 */
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+ char time_buffer[29]; /* String to hold RFC 1123 time text */
+#endif
+#endif
+
+/* New members added in libpng-1.0.6 */
+
+ png_uint_32 free_me; /* flags items libpng is responsible for freeing */
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+ png_voidp user_chunk_ptr;
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+ png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
+#endif
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ int unknown_default; /* As PNG_HANDLE_* */
+ unsigned int num_chunk_list; /* Number of entries in the list */
+ png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name
+ * followed by a PNG_HANDLE_* byte */
+#endif
+
+/* New members added in libpng-1.0.3 */
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ png_byte rgb_to_gray_status;
+ /* Added in libpng 1.5.5 to record setting of coefficients: */
+ png_byte rgb_to_gray_coefficients_set;
+ /* These were changed from png_byte in libpng-1.0.6 */
+ png_uint_16 rgb_to_gray_red_coeff;
+ png_uint_16 rgb_to_gray_green_coeff;
+ /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */
+#endif
+
+/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+/* Changed from png_byte to png_uint_32 at version 1.2.0 */
+ png_uint_32 mng_features_permitted;
+#endif
+
+/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ png_byte filter_type;
+#endif
+
+/* New members added in libpng-1.2.0 */
+
+/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_voidp mem_ptr; /* user supplied struct for mem functions */
+ png_malloc_ptr malloc_fn; /* function for allocating memory */
+ png_free_ptr free_fn; /* function for freeing memory */
+#endif
+
+/* New member added in libpng-1.0.13 and 1.2.0 */
+ png_bytep big_row_buf; /* buffer to save current (unfiltered) row */
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+/* The following three members were added at version 1.0.14 and 1.2.4 */
+ png_bytep quantize_sort; /* working sort array */
+ png_bytep index_to_palette; /* where the original index currently is
+ in the palette */
+ png_bytep palette_to_index; /* which original index points to this
+ palette color */
+#endif
+
+/* New members added in libpng-1.0.16 and 1.2.6 */
+ png_byte compression_type;
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ png_uint_32 user_width_max;
+ png_uint_32 user_height_max;
+
+ /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
+ * chunks that can be stored (0 means unlimited).
+ */
+ png_uint_32 user_chunk_cache_max;
+
+ /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
+ * can occupy when decompressed. 0 means unlimited.
+ */
+ png_alloc_size_t user_chunk_malloc_max;
+#endif
+
+/* New member added in libpng-1.0.25 and 1.2.17 */
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+ /* Temporary storage for unknown chunk that the library doesn't recognize,
+ * used while reading the chunk.
+ */
+ png_unknown_chunk unknown_chunk;
+#endif
+
+/* New member added in libpng-1.2.26 */
+ png_size_t old_big_row_buf_size;
+
+#ifdef PNG_READ_SUPPORTED
+/* New member added in libpng-1.2.30 */
+ png_bytep read_buffer; /* buffer for reading chunk data */
+ png_alloc_size_t read_buffer_size; /* current size of the buffer */
+#endif
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ uInt IDAT_read_size; /* limit on read buffer size for IDAT */
+#endif
+
+#ifdef PNG_IO_STATE_SUPPORTED
+/* New member added in libpng-1.4.0 */
+ png_uint_32 io_state;
+#endif
+
+/* New member added in libpng-1.5.6 */
+ png_bytep big_prev_row;
+
+/* New member added in libpng-1.5.7 */
+ void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info,
+ png_bytep row, png_const_bytep prev_row);
+
+#ifdef PNG_READ_SUPPORTED
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+ png_colorspace colorspace;
+#endif
+#endif
+};
+#endif /* PNGSTRUCT_H */
diff --git a/xs/src/png/libpng/pngtest.c b/xs/src/png/libpng/pngtest.c
new file mode 100644
index 000000000..9d5075791
--- /dev/null
+++ b/xs/src/png/libpng/pngtest.c
@@ -0,0 +1,2156 @@
+
+/* pngtest.c - a simple test program to test libpng
+ *
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This program reads in a PNG image, writes it out again, and then
+ * compares the two files. If the files are identical, this shows that
+ * the basic chunk handling, filtering, and (de)compression code is working
+ * properly. It does not currently test all of the transforms, although
+ * it probably should.
+ *
+ * The program will report "FAIL" in certain legitimate cases:
+ * 1) when the compression level or filter selection method is changed.
+ * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
+ * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
+ * exist in the input file.
+ * 4) others not listed here...
+ * In these cases, it is best to check with another tool such as "pngcheck"
+ * to see what the differences between the two files are.
+ *
+ * If a filename is given on the command-line, then this file is used
+ * for the input, rather than the default "pngtest.png". This allows
+ * testing a wide variety of files easily. You can also test a number
+ * of files at once by typing "pngtest -m file1.png file2.png ..."
+ */
+
+#define _POSIX_SOURCE 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Defined so I can write to a file on gui/windowing platforms */
+/* #define STDERR stderr */
+#define STDERR stdout /* For DOS */
+
+#include "png.h"
+
+/* Known chunks that exist in pngtest.png must be supported or pngtest will fail
+ * simply as a result of re-ordering them. This may be fixed in 1.7
+ *
+ * pngtest allocates a single row buffer for each row and overwrites it,
+ * therefore if the write side doesn't support the writing of interlaced images
+ * nothing can be done for an interlaced image (and the code below will fail
+ * horribly trying to write extra data after writing garbage).
+ */
+#if defined PNG_READ_SUPPORTED && /* else nothing can be done */\
+ defined PNG_READ_bKGD_SUPPORTED &&\
+ defined PNG_READ_cHRM_SUPPORTED &&\
+ defined PNG_READ_gAMA_SUPPORTED &&\
+ defined PNG_READ_oFFs_SUPPORTED &&\
+ defined PNG_READ_pCAL_SUPPORTED &&\
+ defined PNG_READ_pHYs_SUPPORTED &&\
+ defined PNG_READ_sBIT_SUPPORTED &&\
+ defined PNG_READ_sCAL_SUPPORTED &&\
+ defined PNG_READ_sRGB_SUPPORTED &&\
+ defined PNG_READ_sPLT_SUPPORTED &&\
+ defined PNG_READ_tEXt_SUPPORTED &&\
+ defined PNG_READ_tIME_SUPPORTED &&\
+ defined PNG_READ_zTXt_SUPPORTED &&\
+ (defined PNG_WRITE_INTERLACING_SUPPORTED || PNG_LIBPNG_VER >= 10700)
+
+#ifdef PNG_ZLIB_HEADER
+# include PNG_ZLIB_HEADER /* defined by pnglibconf.h from 1.7 */
+#else
+# include "zlib.h"
+#endif
+
+/* Copied from pngpriv.h but only used in error messages below. */
+#ifndef PNG_ZBUF_SIZE
+# define PNG_ZBUF_SIZE 8192
+#endif
+#define FCLOSE(file) fclose(file)
+
+#ifndef PNG_STDIO_SUPPORTED
+typedef FILE * png_FILE_p;
+#endif
+
+/* Makes pngtest verbose so we can find problems. */
+#ifndef PNG_DEBUG
+# define PNG_DEBUG 0
+#endif
+
+#if PNG_DEBUG > 1
+# define pngtest_debug(m) ((void)fprintf(stderr, m "\n"))
+# define pngtest_debug1(m,p1) ((void)fprintf(stderr, m "\n", p1))
+# define pngtest_debug2(m,p1,p2) ((void)fprintf(stderr, m "\n", p1, p2))
+#else
+# define pngtest_debug(m) ((void)0)
+# define pngtest_debug1(m,p1) ((void)0)
+# define pngtest_debug2(m,p1,p2) ((void)0)
+#endif
+
+#if !PNG_DEBUG
+# define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */
+#endif
+
+#ifndef PNG_UNUSED
+# define PNG_UNUSED(param) (void)param;
+#endif
+
+/* Turn on CPU timing
+#define PNGTEST_TIMING
+*/
+
+#ifndef PNG_FLOATING_POINT_SUPPORTED
+#undef PNGTEST_TIMING
+#endif
+
+#ifdef PNGTEST_TIMING
+static float t_start, t_stop, t_decode, t_encode, t_misc;
+#include <time.h>
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+#define PNG_tIME_STRING_LENGTH 29
+static int tIME_chunk_present = 0;
+static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present";
+
+#if PNG_LIBPNG_VER < 10619
+#define png_convert_to_rfc1123_buffer(ts, t) tIME_to_str(read_ptr, ts, t)
+
+static int
+tIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t)
+{
+ png_const_charp str = png_convert_to_rfc1123(png_ptr, t);
+
+ if (str == NULL)
+ return 0;
+
+ strcpy(ts, str);
+ return 1;
+}
+#endif /* older libpng */
+#endif
+
+static int verbose = 0;
+static int strict = 0;
+static int relaxed = 0;
+static int xfail = 0;
+static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */
+static int error_count = 0; /* count calls to png_error */
+static int warning_count = 0; /* count calls to png_warning */
+
+/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
+#ifndef png_jmpbuf
+# define png_jmpbuf(png_ptr) png_ptr->jmpbuf
+#endif
+
+/* Defines for unknown chunk handling if required. */
+#ifndef PNG_HANDLE_CHUNK_ALWAYS
+# define PNG_HANDLE_CHUNK_ALWAYS 3
+#endif
+#ifndef PNG_HANDLE_CHUNK_IF_SAFE
+# define PNG_HANDLE_CHUNK_IF_SAFE 2
+#endif
+
+/* Utility to save typing/errors, the argument must be a name */
+#define MEMZERO(var) ((void)memset(&var, 0, sizeof var))
+
+/* Example of using row callbacks to make a simple progress meter */
+static int status_pass = 1;
+static int status_dots_requested = 0;
+static int status_dots = 1;
+
+static void PNGCBAPI
+read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
+{
+ if (png_ptr == NULL || row_number > PNG_UINT_31_MAX)
+ return;
+
+ if (status_pass != pass)
+ {
+ fprintf(stdout, "\n Pass %d: ", pass);
+ status_pass = pass;
+ status_dots = 31;
+ }
+
+ status_dots--;
+
+ if (status_dots == 0)
+ {
+ fprintf(stdout, "\n ");
+ status_dots=30;
+ }
+
+ fprintf(stdout, "r");
+}
+
+#ifdef PNG_WRITE_SUPPORTED
+static void PNGCBAPI
+write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
+{
+ if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7)
+ return;
+
+ fprintf(stdout, "w");
+}
+#endif
+
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+/* Example of using a user transform callback (doesn't do anything at present).
+ */
+static void PNGCBAPI
+read_user_callback(png_structp png_ptr, png_row_infop row_info, png_bytep data)
+{
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(row_info)
+ PNG_UNUSED(data)
+}
+#endif
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+/* Example of using user transform callback (we don't transform anything,
+ * but merely count the zero samples)
+ */
+
+static png_uint_32 zero_samples;
+
+static void PNGCBAPI
+count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
+{
+ png_bytep dp = data;
+ if (png_ptr == NULL)
+ return;
+
+ /* Contents of row_info:
+ * png_uint_32 width width of row
+ * png_uint_32 rowbytes number of bytes in row
+ * png_byte color_type color type of pixels
+ * png_byte bit_depth bit depth of samples
+ * png_byte channels number of channels (1-4)
+ * png_byte pixel_depth bits per pixel (depth*channels)
+ */
+
+ /* Counts the number of zero samples (or zero pixels if color_type is 3 */
+
+ if (row_info->color_type == 0 || row_info->color_type == 3)
+ {
+ int pos = 0;
+ png_uint_32 n, nstop;
+
+ for (n = 0, nstop=row_info->width; n<nstop; n++)
+ {
+ if (row_info->bit_depth == 1)
+ {
+ if (((*dp << pos++ ) & 0x80) == 0)
+ zero_samples++;
+
+ if (pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
+
+ if (row_info->bit_depth == 2)
+ {
+ if (((*dp << (pos+=2)) & 0xc0) == 0)
+ zero_samples++;
+
+ if (pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
+
+ if (row_info->bit_depth == 4)
+ {
+ if (((*dp << (pos+=4)) & 0xf0) == 0)
+ zero_samples++;
+
+ if (pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
+
+ if (row_info->bit_depth == 8)
+ if (*dp++ == 0)
+ zero_samples++;
+
+ if (row_info->bit_depth == 16)
+ {
+ if ((*dp | *(dp+1)) == 0)
+ zero_samples++;
+ dp+=2;
+ }
+ }
+ }
+ else /* Other color types */
+ {
+ png_uint_32 n, nstop;
+ int channel;
+ int color_channels = row_info->channels;
+ if (row_info->color_type > 3)
+ color_channels--;
+
+ for (n = 0, nstop=row_info->width; n<nstop; n++)
+ {
+ for (channel = 0; channel < color_channels; channel++)
+ {
+ if (row_info->bit_depth == 8)
+ if (*dp++ == 0)
+ zero_samples++;
+
+ if (row_info->bit_depth == 16)
+ {
+ if ((*dp | *(dp+1)) == 0)
+ zero_samples++;
+
+ dp+=2;
+ }
+ }
+ if (row_info->color_type > 3)
+ {
+ dp++;
+ if (row_info->bit_depth == 16)
+ dp++;
+ }
+ }
+ }
+}
+#endif /* WRITE_USER_TRANSFORM */
+
+#ifndef PNG_STDIO_SUPPORTED
+/* START of code to validate stdio-free compilation */
+/* These copies of the default read/write functions come from pngrio.c and
+ * pngwio.c. They allow "don't include stdio" testing of the library.
+ * This is the function that does the actual reading of data. If you are
+ * not reading from a standard C stream, you should create a replacement
+ * read_data function and use it at run time with png_set_read_fn(), rather
+ * than changing the library.
+ */
+
+#ifdef PNG_IO_STATE_SUPPORTED
+void
+pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
+ png_uint_32 io_op);
+void
+pngtest_check_io_state(png_structp png_ptr, png_size_t data_length,
+ png_uint_32 io_op)
+{
+ png_uint_32 io_state = png_get_io_state(png_ptr);
+ int err = 0;
+
+ /* Check if the current operation (reading / writing) is as expected. */
+ if ((io_state & PNG_IO_MASK_OP) != io_op)
+ png_error(png_ptr, "Incorrect operation in I/O state");
+
+ /* Check if the buffer size specific to the current location
+ * (file signature / header / data / crc) is as expected.
+ */
+ switch (io_state & PNG_IO_MASK_LOC)
+ {
+ case PNG_IO_SIGNATURE:
+ if (data_length > 8)
+ err = 1;
+ break;
+ case PNG_IO_CHUNK_HDR:
+ if (data_length != 8)
+ err = 1;
+ break;
+ case PNG_IO_CHUNK_DATA:
+ break; /* no restrictions here */
+ case PNG_IO_CHUNK_CRC:
+ if (data_length != 4)
+ err = 1;
+ break;
+ default:
+ err = 1; /* uninitialized */
+ }
+ if (err != 0)
+ png_error(png_ptr, "Bad I/O state or buffer size");
+}
+#endif
+
+static void PNGCBAPI
+pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_size_t check = 0;
+ png_voidp io_ptr;
+
+ /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+ * instead of an int, which is what fread() actually returns.
+ */
+ io_ptr = png_get_io_ptr(png_ptr);
+ if (io_ptr != NULL)
+ {
+ check = fread(data, 1, length, (png_FILE_p)io_ptr);
+ }
+
+ if (check != length)
+ {
+ png_error(png_ptr, "Read Error");
+ }
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ pngtest_check_io_state(png_ptr, length, PNG_IO_READING);
+#endif
+}
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+static void PNGCBAPI
+pngtest_flush(png_structp png_ptr)
+{
+ /* Do nothing; fflush() is said to be just a waste of energy. */
+ PNG_UNUSED(png_ptr) /* Stifle compiler warning */
+}
+#endif
+
+/* This is the function that does the actual writing of data. If you are
+ * not writing to a standard C stream, you should create a replacement
+ * write_data function and use it at run time with png_set_write_fn(), rather
+ * than changing the library.
+ */
+static void PNGCBAPI
+pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_size_t check;
+
+ check = fwrite(data, 1, length, (png_FILE_p)png_get_io_ptr(png_ptr));
+
+ if (check != length)
+ {
+ png_error(png_ptr, "Write Error");
+ }
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ pngtest_check_io_state(png_ptr, length, PNG_IO_WRITING);
+#endif
+}
+#endif /* !STDIO */
+
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway. Replacement functions don't have to do anything
+ * here if you don't want to. In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+typedef struct
+{
+ PNG_CONST char *file_name;
+} pngtest_error_parameters;
+
+static void PNGCBAPI
+pngtest_warning(png_structp png_ptr, png_const_charp message)
+{
+ PNG_CONST char *name = "UNKNOWN (ERROR!)";
+ pngtest_error_parameters *test =
+ (pngtest_error_parameters*)png_get_error_ptr(png_ptr);
+
+ ++warning_count;
+
+ if (test != NULL && test->file_name != NULL)
+ name = test->file_name;
+
+ fprintf(STDERR, "\n%s: libpng warning: %s\n", name, message);
+}
+
+/* This is the default error handling function. Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash. This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static void PNGCBAPI
+pngtest_error(png_structp png_ptr, png_const_charp message)
+{
+ ++error_count;
+
+ pngtest_warning(png_ptr, message);
+ /* We can return because png_error calls the default handler, which is
+ * actually OK in this case.
+ */
+}
+
+/* END of code to validate stdio-free compilation */
+
+/* START of code to validate memory allocation and deallocation */
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+
+/* Allocate memory. For reasonable files, size should never exceed
+ * 64K. However, zlib may allocate more than 64K if you don't tell
+ * it not to. See zconf.h and png.h for more information. zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ *
+ * This piece of code can be compiled to validate max 64K allocations
+ * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K.
+ */
+typedef struct memory_information
+{
+ png_alloc_size_t size;
+ png_voidp pointer;
+ struct memory_information *next;
+} memory_information;
+typedef memory_information *memory_infop;
+
+static memory_infop pinformation = NULL;
+static int current_allocation = 0;
+static int maximum_allocation = 0;
+static int total_allocation = 0;
+static int num_allocations = 0;
+
+png_voidp PNGCBAPI png_debug_malloc PNGARG((png_structp png_ptr,
+ png_alloc_size_t size));
+void PNGCBAPI png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
+
+png_voidp
+PNGCBAPI png_debug_malloc(png_structp png_ptr, png_alloc_size_t size)
+{
+
+ /* png_malloc has already tested for NULL; png_create_struct calls
+ * png_debug_malloc directly, with png_ptr == NULL which is OK
+ */
+
+ if (size == 0)
+ return (NULL);
+
+ /* This calls the library allocator twice, once to get the requested
+ buffer and once to get a new free list entry. */
+ {
+ /* Disable malloc_fn and free_fn */
+ memory_infop pinfo;
+ png_set_mem_fn(png_ptr, NULL, NULL, NULL);
+ pinfo = (memory_infop)png_malloc(png_ptr,
+ (sizeof *pinfo));
+ pinfo->size = size;
+ current_allocation += size;
+ total_allocation += size;
+ num_allocations ++;
+
+ if (current_allocation > maximum_allocation)
+ maximum_allocation = current_allocation;
+
+ pinfo->pointer = png_malloc(png_ptr, size);
+ /* Restore malloc_fn and free_fn */
+
+ png_set_mem_fn(png_ptr,
+ NULL, png_debug_malloc, png_debug_free);
+
+ if (size != 0 && pinfo->pointer == NULL)
+ {
+ current_allocation -= size;
+ total_allocation -= size;
+ png_error(png_ptr,
+ "out of memory in pngtest->png_debug_malloc");
+ }
+
+ pinfo->next = pinformation;
+ pinformation = pinfo;
+ /* Make sure the caller isn't assuming zeroed memory. */
+ memset(pinfo->pointer, 0xdd, pinfo->size);
+
+ if (verbose != 0)
+ printf("png_malloc %lu bytes at %p\n", (unsigned long)size,
+ pinfo->pointer);
+
+ return (png_voidp)(pinfo->pointer);
+ }
+}
+
+/* Free a pointer. It is removed from the list at the same time. */
+void PNGCBAPI
+png_debug_free(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL)
+ fprintf(STDERR, "NULL pointer to png_debug_free.\n");
+
+ if (ptr == 0)
+ {
+#if 0 /* This happens all the time. */
+ fprintf(STDERR, "WARNING: freeing NULL pointer\n");
+#endif
+ return;
+ }
+
+ /* Unlink the element from the list. */
+ if (pinformation != NULL)
+ {
+ memory_infop *ppinfo = &pinformation;
+
+ for (;;)
+ {
+ memory_infop pinfo = *ppinfo;
+
+ if (pinfo->pointer == ptr)
+ {
+ *ppinfo = pinfo->next;
+ current_allocation -= pinfo->size;
+ if (current_allocation < 0)
+ fprintf(STDERR, "Duplicate free of memory\n");
+ /* We must free the list element too, but first kill
+ the memory that is to be freed. */
+ memset(ptr, 0x55, pinfo->size);
+ free(pinfo);
+ pinfo = NULL;
+ break;
+ }
+
+ if (pinfo->next == NULL)
+ {
+ fprintf(STDERR, "Pointer %p not found\n", ptr);
+ break;
+ }
+
+ ppinfo = &pinfo->next;
+ }
+ }
+
+ /* Finally free the data. */
+ if (verbose != 0)
+ printf("Freeing %p\n", ptr);
+
+ if (ptr != NULL)
+ free(ptr);
+ ptr = NULL;
+}
+#endif /* USER_MEM && DEBUG */
+/* END of code to test memory allocation/deallocation */
+
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+/* Demonstration of user chunk support of the sTER and vpAg chunks */
+
+/* (sTER is a public chunk not yet known by libpng. vpAg is a private
+chunk used in ImageMagick to store "virtual page" size). */
+
+static struct user_chunk_data
+{
+ png_const_infop info_ptr;
+ png_uint_32 vpAg_width, vpAg_height;
+ png_byte vpAg_units;
+ png_byte sTER_mode;
+ int location[2];
+}
+user_chunk_data;
+
+/* Used for location and order; zero means nothing. */
+#define have_sTER 0x01
+#define have_vpAg 0x02
+#define before_PLTE 0x10
+#define before_IDAT 0x20
+#define after_IDAT 0x40
+
+static void
+init_callback_info(png_const_infop info_ptr)
+{
+ MEMZERO(user_chunk_data);
+ user_chunk_data.info_ptr = info_ptr;
+}
+
+static int
+set_location(png_structp png_ptr, struct user_chunk_data *data, int what)
+{
+ int location;
+
+ if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0)
+ return 0; /* already have one of these */
+
+ /* Find where we are (the code below zeroes info_ptr to indicate that the
+ * chunks before the first IDAT have been read.)
+ */
+ if (data->info_ptr == NULL) /* after IDAT */
+ location = what | after_IDAT;
+
+ else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0)
+ location = what | before_IDAT;
+
+ else
+ location = what | before_PLTE;
+
+ if (data->location[0] == 0)
+ data->location[0] = location;
+
+ else
+ data->location[1] = location;
+
+ return 1; /* handled */
+}
+
+static int PNGCBAPI
+read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk)
+{
+ struct user_chunk_data *my_user_chunk_data =
+ (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr);
+
+ if (my_user_chunk_data == NULL)
+ png_error(png_ptr, "lost user chunk pointer");
+
+ /* Return one of the following:
+ * return (-n); chunk had an error
+ * return (0); did not recognize
+ * return (n); success
+ *
+ * The unknown chunk structure contains the chunk data:
+ * png_byte name[5];
+ * png_byte *data;
+ * png_size_t size;
+ *
+ * Note that libpng has already taken care of the CRC handling.
+ */
+
+ if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */
+ chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */
+ {
+ /* Found sTER chunk */
+ if (chunk->size != 1)
+ return (-1); /* Error return */
+
+ if (chunk->data[0] != 0 && chunk->data[0] != 1)
+ return (-1); /* Invalid mode */
+
+ if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0)
+ {
+ my_user_chunk_data->sTER_mode=chunk->data[0];
+ return (1);
+ }
+
+ else
+ return (0); /* duplicate sTER - give it to libpng */
+ }
+
+ if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */
+ chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */
+ return (0); /* Did not recognize */
+
+ /* Found ImageMagick vpAg chunk */
+
+ if (chunk->size != 9)
+ return (-1); /* Error return */
+
+ if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0)
+ return (0); /* duplicate vpAg */
+
+ my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data);
+ my_user_chunk_data->vpAg_height = png_get_uint_31(png_ptr, chunk->data + 4);
+ my_user_chunk_data->vpAg_units = chunk->data[8];
+
+ return (1);
+}
+
+#ifdef PNG_WRITE_SUPPORTED
+static void
+write_sTER_chunk(png_structp write_ptr)
+{
+ png_byte sTER[5] = {115, 84, 69, 82, '\0'};
+
+ if (verbose != 0)
+ fprintf(STDERR, "\n stereo mode = %d\n", user_chunk_data.sTER_mode);
+
+ png_write_chunk(write_ptr, sTER, &user_chunk_data.sTER_mode, 1);
+}
+
+static void
+write_vpAg_chunk(png_structp write_ptr)
+{
+ png_byte vpAg[5] = {118, 112, 65, 103, '\0'};
+
+ png_byte vpag_chunk_data[9];
+
+ if (verbose != 0)
+ fprintf(STDERR, " vpAg = %lu x %lu, units = %d\n",
+ (unsigned long)user_chunk_data.vpAg_width,
+ (unsigned long)user_chunk_data.vpAg_height,
+ user_chunk_data.vpAg_units);
+
+ png_save_uint_32(vpag_chunk_data, user_chunk_data.vpAg_width);
+ png_save_uint_32(vpag_chunk_data + 4, user_chunk_data.vpAg_height);
+ vpag_chunk_data[8] = user_chunk_data.vpAg_units;
+ png_write_chunk(write_ptr, vpAg, vpag_chunk_data, 9);
+}
+
+static void
+write_chunks(png_structp write_ptr, int location)
+{
+ int i;
+
+ /* Notice that this preserves the original chunk order, however chunks
+ * intercepted by the callback will be written *after* chunks passed to
+ * libpng. This will actually reverse a pair of sTER chunks or a pair of
+ * vpAg chunks, resulting in an error later. This is not worth worrying
+ * about - the chunks should not be duplicated!
+ */
+ for (i=0; i<2; ++i)
+ {
+ if (user_chunk_data.location[i] == (location | have_sTER))
+ write_sTER_chunk(write_ptr);
+
+ else if (user_chunk_data.location[i] == (location | have_vpAg))
+ write_vpAg_chunk(write_ptr);
+ }
+}
+#endif /* WRITE */
+#else /* !READ_USER_CHUNKS */
+# define write_chunks(pp,loc) ((void)0)
+#endif
+/* END of code to demonstrate user chunk support */
+
+/* START of code to check that libpng has the required text support; this only
+ * checks for the write support because if read support is missing the chunk
+ * will simply not be reported back to pngtest.
+ */
+#ifdef PNG_TEXT_SUPPORTED
+static void
+pngtest_check_text_support(png_structp png_ptr, png_textp text_ptr,
+ int num_text)
+{
+ while (num_text > 0)
+ {
+ switch (text_ptr[--num_text].compression)
+ {
+ case PNG_TEXT_COMPRESSION_NONE:
+ break;
+
+ case PNG_TEXT_COMPRESSION_zTXt:
+# ifndef PNG_WRITE_zTXt_SUPPORTED
+ ++unsupported_chunks;
+ /* In libpng 1.7 this now does an app-error, so stop it: */
+ text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
+# endif
+ break;
+
+ case PNG_ITXT_COMPRESSION_NONE:
+ case PNG_ITXT_COMPRESSION_zTXt:
+# ifndef PNG_WRITE_iTXt_SUPPORTED
+ ++unsupported_chunks;
+ text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
+# endif
+ break;
+
+ default:
+ /* This is an error */
+ png_error(png_ptr, "invalid text chunk compression field");
+ break;
+ }
+ }
+}
+#endif
+/* END of code to check that libpng has the required text support */
+
+/* Test one file */
+static int
+test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
+{
+ static png_FILE_p fpin;
+ static png_FILE_p fpout; /* "static" prevents setjmp corruption */
+ pngtest_error_parameters error_parameters;
+ png_structp read_ptr;
+ png_infop read_info_ptr, end_info_ptr;
+#ifdef PNG_WRITE_SUPPORTED
+ png_structp write_ptr;
+ png_infop write_info_ptr;
+ png_infop write_end_info_ptr;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ int interlace_preserved = 1;
+#endif /* WRITE_FILTER */
+#else /* !WRITE */
+ png_structp write_ptr = NULL;
+ png_infop write_info_ptr = NULL;
+ png_infop write_end_info_ptr = NULL;
+#endif /* !WRITE */
+ png_bytep row_buf;
+ png_uint_32 y;
+ png_uint_32 width, height;
+ volatile int num_passes;
+ int pass;
+ int bit_depth, color_type;
+
+ row_buf = NULL;
+ error_parameters.file_name = inname;
+
+ if ((fpin = fopen(inname, "rb")) == NULL)
+ {
+ fprintf(STDERR, "Could not find input file %s\n", inname);
+ return (1);
+ }
+
+ if ((fpout = fopen(outname, "wb")) == NULL)
+ {
+ fprintf(STDERR, "Could not open output file %s\n", outname);
+ FCLOSE(fpin);
+ return (1);
+ }
+
+ pngtest_debug("Allocating read and write structures");
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ read_ptr =
+ png_create_read_struct_2(PNG_LIBPNG_VER_STRING, NULL,
+ NULL, NULL, NULL, png_debug_malloc, png_debug_free);
+#else
+ read_ptr =
+ png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+#endif
+ png_set_error_fn(read_ptr, &error_parameters, pngtest_error,
+ pngtest_warning);
+
+#ifdef PNG_WRITE_SUPPORTED
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ write_ptr =
+ png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL,
+ NULL, NULL, NULL, png_debug_malloc, png_debug_free);
+#else
+ write_ptr =
+ png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+#endif
+ png_set_error_fn(write_ptr, &error_parameters, pngtest_error,
+ pngtest_warning);
+#endif
+ pngtest_debug("Allocating read_info, write_info and end_info structures");
+ read_info_ptr = png_create_info_struct(read_ptr);
+ end_info_ptr = png_create_info_struct(read_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+ write_info_ptr = png_create_info_struct(write_ptr);
+ write_end_info_ptr = png_create_info_struct(write_ptr);
+#endif
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+ init_callback_info(read_info_ptr);
+ png_set_read_user_chunk_fn(read_ptr, &user_chunk_data,
+ read_user_chunk_callback);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ pngtest_debug("Setting jmpbuf for read struct");
+ if (setjmp(png_jmpbuf(read_ptr)))
+ {
+ fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
+ png_free(read_ptr, row_buf);
+ row_buf = NULL;
+ if (verbose != 0)
+ fprintf(STDERR, " destroy read structs\n");
+ png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+ if (verbose != 0)
+ fprintf(STDERR, " destroy write structs\n");
+ png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+ png_destroy_write_struct(&write_ptr, &write_info_ptr);
+#endif
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (1);
+ }
+
+#ifdef PNG_WRITE_SUPPORTED
+ pngtest_debug("Setting jmpbuf for write struct");
+
+ if (setjmp(png_jmpbuf(write_ptr)))
+ {
+ fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
+ if (verbose != 0)
+ fprintf(STDERR, " destroying read structs\n");
+ png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+ if (verbose != 0)
+ fprintf(STDERR, " destroying write structs\n");
+ png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+ png_destroy_write_struct(&write_ptr, &write_info_ptr);
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (1);
+ }
+#endif
+#endif
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+ if (strict != 0)
+ {
+ /* Treat png_benign_error() as errors on read */
+ png_set_benign_errors(read_ptr, 0);
+
+# ifdef PNG_WRITE_SUPPORTED
+ /* Treat them as errors on write */
+ png_set_benign_errors(write_ptr, 0);
+# endif
+
+ /* if strict is not set, then app warnings and errors are treated as
+ * warnings in release builds, but not in unstable builds; this can be
+ * changed with '--relaxed'.
+ */
+ }
+
+ else if (relaxed != 0)
+ {
+ /* Allow application (pngtest) errors and warnings to pass */
+ png_set_benign_errors(read_ptr, 1);
+
+ /* Turn off CRC checking while reading */
+ png_set_crc_action(read_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
+
+#ifdef PNG_IGNORE_ADLER32
+ /* Turn off ADLER32 checking while reading */
+ png_set_option(read_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON);
+#endif
+
+# ifdef PNG_WRITE_SUPPORTED
+ png_set_benign_errors(write_ptr, 1);
+# endif
+
+ }
+#endif /* BENIGN_ERRORS */
+
+ pngtest_debug("Initializing input and output streams");
+#ifdef PNG_STDIO_SUPPORTED
+ png_init_io(read_ptr, fpin);
+# ifdef PNG_WRITE_SUPPORTED
+ png_init_io(write_ptr, fpout);
+# endif
+#else
+ png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
+# ifdef PNG_WRITE_SUPPORTED
+ png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data,
+# ifdef PNG_WRITE_FLUSH_SUPPORTED
+ pngtest_flush);
+# else
+ NULL);
+# endif
+# endif
+#endif
+
+ if (status_dots_requested == 1)
+ {
+#ifdef PNG_WRITE_SUPPORTED
+ png_set_write_status_fn(write_ptr, write_row_callback);
+#endif
+ png_set_read_status_fn(read_ptr, read_row_callback);
+ }
+
+ else
+ {
+#ifdef PNG_WRITE_SUPPORTED
+ png_set_write_status_fn(write_ptr, NULL);
+#endif
+ png_set_read_status_fn(read_ptr, NULL);
+ }
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ png_set_read_user_transform_fn(read_ptr, read_user_callback);
+#endif
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+ zero_samples = 0;
+ png_set_write_user_transform_fn(write_ptr, count_zero_samples);
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ /* Preserve all the unknown chunks, if possible. If this is disabled then,
+ * even if the png_{get,set}_unknown_chunks stuff is enabled, we can't use
+ * libpng to *save* the unknown chunks on read (because we can't switch the
+ * save option on!)
+ *
+ * Notice that if SET_UNKNOWN_CHUNKS is *not* supported read will discard all
+ * unknown chunks and write will write them all.
+ */
+#ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
+ png_set_keep_unknown_chunks(read_ptr, PNG_HANDLE_CHUNK_ALWAYS,
+ NULL, 0);
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ png_set_keep_unknown_chunks(write_ptr, PNG_HANDLE_CHUNK_ALWAYS,
+ NULL, 0);
+#endif
+#endif
+
+ pngtest_debug("Reading info struct");
+ png_read_info(read_ptr, read_info_ptr);
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+ /* This is a bit of a hack; there is no obvious way in the callback function
+ * to determine that the chunks before the first IDAT have been read, so
+ * remove the info_ptr (which is only used to determine position relative to
+ * PLTE) here to indicate that we are after the IDAT.
+ */
+ user_chunk_data.info_ptr = NULL;
+#endif
+
+ pngtest_debug("Transferring info struct");
+ {
+ int interlace_type, compression_type, filter_type;
+
+ if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
+ &color_type, &interlace_type, &compression_type, &filter_type) != 0)
+ {
+ png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
+ color_type, interlace_type, compression_type, filter_type);
+ /* num_passes may not be available below if interlace support is not
+ * provided by libpng for both read and write.
+ */
+ switch (interlace_type)
+ {
+ case PNG_INTERLACE_NONE:
+ num_passes = 1;
+ break;
+
+ case PNG_INTERLACE_ADAM7:
+ num_passes = 7;
+ break;
+
+ default:
+ png_error(read_ptr, "invalid interlace type");
+ /*NOT REACHED*/
+ }
+ }
+
+ else
+ png_error(read_ptr, "png_get_IHDR failed");
+ }
+#ifdef PNG_FIXED_POINT_SUPPORTED
+#ifdef PNG_cHRM_SUPPORTED
+ {
+ png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
+ blue_y;
+
+ if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y,
+ &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
+ {
+ png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
+ red_y, green_x, green_y, blue_x, blue_y);
+ }
+ }
+#endif
+#ifdef PNG_gAMA_SUPPORTED
+ {
+ png_fixed_point gamma;
+
+ if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0)
+ png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
+ }
+#endif
+#else /* Use floating point versions */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+#ifdef PNG_cHRM_SUPPORTED
+ {
+ double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
+ blue_y;
+
+ if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
+ &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0)
+ {
+ png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
+ red_y, green_x, green_y, blue_x, blue_y);
+ }
+ }
+#endif
+#ifdef PNG_gAMA_SUPPORTED
+ {
+ double gamma;
+
+ if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0)
+ png_set_gAMA(write_ptr, write_info_ptr, gamma);
+ }
+#endif
+#endif /* Floating point */
+#endif /* Fixed point */
+#ifdef PNG_iCCP_SUPPORTED
+ {
+ png_charp name;
+ png_bytep profile;
+ png_uint_32 proflen;
+ int compression_type;
+
+ if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
+ &profile, &proflen) != 0)
+ {
+ png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
+ profile, proflen);
+ }
+ }
+#endif
+#ifdef PNG_sRGB_SUPPORTED
+ {
+ int intent;
+
+ if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0)
+ png_set_sRGB(write_ptr, write_info_ptr, intent);
+ }
+#endif
+ {
+ png_colorp palette;
+ int num_palette;
+
+ if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0)
+ png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
+ }
+#ifdef PNG_bKGD_SUPPORTED
+ {
+ png_color_16p background;
+
+ if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0)
+ {
+ png_set_bKGD(write_ptr, write_info_ptr, background);
+ }
+ }
+#endif
+#ifdef PNG_READ_eXIf_SUPPORTED
+ {
+ png_bytep exif=NULL;
+ png_uint_32 exif_length;
+
+ if (png_get_eXIf_1(read_ptr, read_info_ptr, &exif_length, &exif) != 0)
+ {
+ if (exif_length > 1)
+ fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1],
+ (unsigned long)exif_length);
+# ifdef PNG_WRITE_eXIf_SUPPORTED
+ png_set_eXIf_1(write_ptr, write_info_ptr, exif_length, exif);
+# endif
+ }
+ }
+#endif
+#ifdef PNG_hIST_SUPPORTED
+ {
+ png_uint_16p hist;
+
+ if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0)
+ png_set_hIST(write_ptr, write_info_ptr, hist);
+ }
+#endif
+#ifdef PNG_oFFs_SUPPORTED
+ {
+ png_int_32 offset_x, offset_y;
+ int unit_type;
+
+ if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y,
+ &unit_type) != 0)
+ {
+ png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
+ }
+ }
+#endif
+#ifdef PNG_pCAL_SUPPORTED
+ {
+ png_charp purpose, units;
+ png_charpp params;
+ png_int_32 X0, X1;
+ int type, nparams;
+
+ if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
+ &nparams, &units, &params) != 0)
+ {
+ png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
+ nparams, units, params);
+ }
+ }
+#endif
+#ifdef PNG_pHYs_SUPPORTED
+ {
+ png_uint_32 res_x, res_y;
+ int unit_type;
+
+ if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y,
+ &unit_type) != 0)
+ png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
+ }
+#endif
+#ifdef PNG_sBIT_SUPPORTED
+ {
+ png_color_8p sig_bit;
+
+ if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0)
+ png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
+ }
+#endif
+#ifdef PNG_sCAL_SUPPORTED
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
+ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
+ {
+ int unit;
+ double scal_width, scal_height;
+
+ if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
+ &scal_height) != 0)
+ {
+ png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
+ }
+ }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ {
+ int unit;
+ png_charp scal_width, scal_height;
+
+ if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
+ &scal_height) != 0)
+ {
+ png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width,
+ scal_height);
+ }
+ }
+#endif
+#endif
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+ {
+ png_sPLT_tp entries;
+
+ int num_entries = (int) png_get_sPLT(read_ptr, read_info_ptr, &entries);
+ if (num_entries)
+ {
+ png_set_sPLT(write_ptr, write_info_ptr, entries, num_entries);
+ }
+ }
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+ {
+ png_textp text_ptr;
+ int num_text;
+
+ if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
+ {
+ pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text);
+
+ pngtest_check_text_support(read_ptr, text_ptr, num_text);
+
+ if (verbose != 0)
+ {
+ int i;
+
+ fprintf(STDERR,"\n");
+ for (i=0; i<num_text; i++)
+ {
+ fprintf(STDERR," Text compression[%d]=%d\n",
+ i, text_ptr[i].compression);
+ }
+ }
+
+ png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
+ }
+ }
+#endif
+#ifdef PNG_tIME_SUPPORTED
+ {
+ png_timep mod_time;
+
+ if (png_get_tIME(read_ptr, read_info_ptr, &mod_time) != 0)
+ {
+ png_set_tIME(write_ptr, write_info_ptr, mod_time);
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+ if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0)
+ tIME_string[(sizeof tIME_string) - 1] = '\0';
+
+ else
+ {
+ strncpy(tIME_string, "*** invalid time ***", (sizeof tIME_string));
+ tIME_string[(sizeof tIME_string) - 1] = '\0';
+ }
+
+ tIME_chunk_present++;
+#endif /* TIME_RFC1123 */
+ }
+ }
+#endif
+#ifdef PNG_tRNS_SUPPORTED
+ {
+ png_bytep trans_alpha;
+ int num_trans;
+ png_color_16p trans_color;
+
+ if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans,
+ &trans_color) != 0)
+ {
+ int sample_max = (1 << bit_depth);
+ /* libpng doesn't reject a tRNS chunk with out-of-range samples */
+ if (!((color_type == PNG_COLOR_TYPE_GRAY &&
+ (int)trans_color->gray > sample_max) ||
+ (color_type == PNG_COLOR_TYPE_RGB &&
+ ((int)trans_color->red > sample_max ||
+ (int)trans_color->green > sample_max ||
+ (int)trans_color->blue > sample_max))))
+ png_set_tRNS(write_ptr, write_info_ptr, trans_alpha, num_trans,
+ trans_color);
+ }
+ }
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ {
+ png_unknown_chunkp unknowns;
+ int num_unknowns = png_get_unknown_chunks(read_ptr, read_info_ptr,
+ &unknowns);
+
+ if (num_unknowns != 0)
+ {
+ png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
+ num_unknowns);
+#if PNG_LIBPNG_VER < 10600
+ /* Copy the locations from the read_info_ptr. The automatically
+ * generated locations in write_end_info_ptr are wrong prior to 1.6.0
+ * because they are reset from the write pointer (removed in 1.6.0).
+ */
+ {
+ int i;
+ for (i = 0; i < num_unknowns; i++)
+ png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
+ unknowns[i].location);
+ }
+#endif
+ }
+ }
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+ pngtest_debug("Writing info struct");
+
+ /* Write the info in two steps so that if we write the 'unknown' chunks here
+ * they go to the correct place.
+ */
+ png_write_info_before_PLTE(write_ptr, write_info_ptr);
+
+ write_chunks(write_ptr, before_PLTE); /* before PLTE */
+
+ png_write_info(write_ptr, write_info_ptr);
+
+ write_chunks(write_ptr, before_IDAT); /* after PLTE */
+
+ png_write_info(write_ptr, write_end_info_ptr);
+
+ write_chunks(write_ptr, after_IDAT); /* after IDAT */
+
+#ifdef PNG_COMPRESSION_COMPAT
+ /* Test the 'compatibility' setting here, if it is available. */
+ png_set_compression(write_ptr, PNG_COMPRESSION_COMPAT);
+#endif
+#endif
+
+#ifdef SINGLE_ROWBUF_ALLOC
+ pngtest_debug("Allocating row buffer...");
+ row_buf = (png_bytep)png_malloc(read_ptr,
+ png_get_rowbytes(read_ptr, read_info_ptr));
+
+ pngtest_debug1("\t0x%08lx", (unsigned long)row_buf);
+#endif /* SINGLE_ROWBUF_ALLOC */
+ pngtest_debug("Writing row data");
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) &&\
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ /* Both must be defined for libpng to be able to handle the interlace,
+ * otherwise it gets handled below by simply reading and writing the passes
+ * directly.
+ */
+ if (png_set_interlace_handling(read_ptr) != num_passes)
+ png_error(write_ptr,
+ "png_set_interlace_handling(read): wrong pass count ");
+ if (png_set_interlace_handling(write_ptr) != num_passes)
+ png_error(write_ptr,
+ "png_set_interlace_handling(write): wrong pass count ");
+#else /* png_set_interlace_handling not called on either read or write */
+# define calc_pass_height
+#endif /* not using libpng interlace handling */
+
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_misc += (t_stop - t_start);
+ t_start = t_stop;
+#endif
+ for (pass = 0; pass < num_passes; pass++)
+ {
+# ifdef calc_pass_height
+ png_uint_32 pass_height;
+
+ if (num_passes == 7) /* interlaced */
+ {
+ if (PNG_PASS_COLS(width, pass) > 0)
+ pass_height = PNG_PASS_ROWS(height, pass);
+
+ else
+ pass_height = 0;
+ }
+
+ else /* not interlaced */
+ pass_height = height;
+# else
+# define pass_height height
+# endif
+
+ pngtest_debug1("Writing row data for pass %d", pass);
+ for (y = 0; y < pass_height; y++)
+ {
+#ifndef SINGLE_ROWBUF_ALLOC
+ pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y);
+
+ row_buf = (png_bytep)png_malloc(read_ptr,
+ png_get_rowbytes(read_ptr, read_info_ptr));
+
+ pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf,
+ (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr));
+
+#endif /* !SINGLE_ROWBUF_ALLOC */
+ png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1);
+
+#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_decode += (t_stop - t_start);
+ t_start = t_stop;
+#endif
+ png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_encode += (t_stop - t_start);
+ t_start = t_stop;
+#endif
+#endif /* WRITE */
+
+#ifndef SINGLE_ROWBUF_ALLOC
+ pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y);
+ png_free(read_ptr, row_buf);
+ row_buf = NULL;
+#endif /* !SINGLE_ROWBUF_ALLOC */
+ }
+ }
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+# ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+ png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
+# endif
+# ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
+# endif
+#endif
+
+ pngtest_debug("Reading and writing end_info data");
+
+ png_read_end(read_ptr, end_info_ptr);
+#ifdef PNG_TEXT_SUPPORTED
+ {
+ png_textp text_ptr;
+ int num_text;
+
+ if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
+ {
+ pngtest_debug1("Handling %d iTXt/tEXt/zTXt chunks", num_text);
+
+ pngtest_check_text_support(read_ptr, text_ptr, num_text);
+
+ if (verbose != 0)
+ {
+ int i;
+
+ fprintf(STDERR,"\n");
+ for (i=0; i<num_text; i++)
+ {
+ fprintf(STDERR," Text compression[%d]=%d\n",
+ i, text_ptr[i].compression);
+ }
+ }
+
+ png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
+ }
+ }
+#endif
+#ifdef PNG_READ_eXIf_SUPPORTED
+ {
+ png_bytep exif=NULL;
+ png_uint_32 exif_length;
+
+ if (png_get_eXIf_1(read_ptr, end_info_ptr, &exif_length, &exif) != 0)
+ {
+ if (exif_length > 1)
+ fprintf(STDERR," eXIf type %c%c, %lu bytes\n",exif[0],exif[1],
+ (unsigned long)exif_length);
+# ifdef PNG_WRITE_eXIf_SUPPORTED
+ png_set_eXIf_1(write_ptr, write_end_info_ptr, exif_length, exif);
+# endif
+ }
+ }
+#endif
+#ifdef PNG_tIME_SUPPORTED
+ {
+ png_timep mod_time;
+
+ if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0)
+ {
+ png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+ if (png_convert_to_rfc1123_buffer(tIME_string, mod_time) != 0)
+ tIME_string[(sizeof tIME_string) - 1] = '\0';
+
+ else
+ {
+ strncpy(tIME_string, "*** invalid time ***", sizeof tIME_string);
+ tIME_string[(sizeof tIME_string)-1] = '\0';
+ }
+
+ tIME_chunk_present++;
+#endif /* TIME_RFC1123 */
+ }
+ }
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ {
+ png_unknown_chunkp unknowns;
+ int num_unknowns = png_get_unknown_chunks(read_ptr, end_info_ptr,
+ &unknowns);
+
+ if (num_unknowns != 0)
+ {
+ png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
+ num_unknowns);
+#if PNG_LIBPNG_VER < 10600
+ /* Copy the locations from the read_info_ptr. The automatically
+ * generated locations in write_end_info_ptr are wrong prior to 1.6.0
+ * because they are reset from the write pointer (removed in 1.6.0).
+ */
+ {
+ int i;
+ for (i = 0; i < num_unknowns; i++)
+ png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
+ unknowns[i].location);
+ }
+#endif
+ }
+ }
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+ /* Normally one would use Z_DEFAULT_STRATEGY for text compression.
+ * This is here just to make pngtest replicate the results from libpng
+ * versions prior to 1.5.4, and to test this new API.
+ */
+ png_set_text_compression_strategy(write_ptr, Z_FILTERED);
+#endif
+
+ /* When the unknown vpAg/sTER chunks are written by pngtest the only way to
+ * do it is to write them *before* calling png_write_end. When unknown
+ * chunks are written by libpng, however, they are written just before IEND.
+ * There seems to be no way round this, however vpAg/sTER are not expected
+ * after IDAT.
+ */
+ write_chunks(write_ptr, after_IDAT);
+
+ png_write_end(write_ptr, write_end_info_ptr);
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+ if (verbose != 0)
+ {
+ png_uint_32 iwidth, iheight;
+ iwidth = png_get_image_width(write_ptr, write_info_ptr);
+ iheight = png_get_image_height(write_ptr, write_info_ptr);
+ fprintf(STDERR, "\n Image width = %lu, height = %lu\n",
+ (unsigned long)iwidth, (unsigned long)iheight);
+ }
+#endif
+
+ pngtest_debug("Destroying data structs");
+#ifdef SINGLE_ROWBUF_ALLOC
+ pngtest_debug("destroying row_buf for read_ptr");
+ png_free(read_ptr, row_buf);
+ row_buf = NULL;
+#endif /* SINGLE_ROWBUF_ALLOC */
+ pngtest_debug("destroying read_ptr, read_info_ptr, end_info_ptr");
+ png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+ pngtest_debug("destroying write_end_info_ptr");
+ png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+ pngtest_debug("destroying write_ptr, write_info_ptr");
+ png_destroy_write_struct(&write_ptr, &write_info_ptr);
+#endif
+ pngtest_debug("Destruction complete.");
+
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+
+ /* Summarize any warnings or errors and in 'strict' mode fail the test.
+ * Unsupported chunks can result in warnings, in that case ignore the strict
+ * setting, otherwise fail the test on warnings as well as errors.
+ */
+ if (error_count > 0)
+ {
+ /* We don't really expect to get here because of the setjmp handling
+ * above, but this is safe.
+ */
+ fprintf(STDERR, "\n %s: %d libpng errors found (%d warnings)",
+ inname, error_count, warning_count);
+
+ if (strict != 0)
+ return (1);
+ }
+
+# ifdef PNG_WRITE_SUPPORTED
+ /* If there is no write support nothing was written! */
+ else if (unsupported_chunks > 0)
+ {
+ fprintf(STDERR, "\n %s: unsupported chunks (%d)%s",
+ inname, unsupported_chunks, strict ? ": IGNORED --strict!" : "");
+ }
+# endif
+
+ else if (warning_count > 0)
+ {
+ fprintf(STDERR, "\n %s: %d libpng warnings found",
+ inname, warning_count);
+
+ if (strict != 0)
+ return (1);
+ }
+
+ pngtest_debug("Opening files for comparison");
+ if ((fpin = fopen(inname, "rb")) == NULL)
+ {
+ fprintf(STDERR, "Could not find file %s\n", inname);
+ return (1);
+ }
+
+ if ((fpout = fopen(outname, "rb")) == NULL)
+ {
+ fprintf(STDERR, "Could not find file %s\n", outname);
+ FCLOSE(fpin);
+ return (1);
+ }
+
+#if defined (PNG_WRITE_SUPPORTED) /* else nothing was written */ &&\
+ defined (PNG_WRITE_FILTER_SUPPORTED)
+ if (interlace_preserved != 0) /* else the files will be changed */
+ {
+ for (;;)
+ {
+ static int wrote_question = 0;
+ png_size_t num_in, num_out;
+ char inbuf[256], outbuf[256];
+
+ num_in = fread(inbuf, 1, sizeof inbuf, fpin);
+ num_out = fread(outbuf, 1, sizeof outbuf, fpout);
+
+ if (num_in != num_out)
+ {
+ fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
+ inname, outname);
+
+ if (wrote_question == 0 && unsupported_chunks == 0)
+ {
+ fprintf(STDERR,
+ " Was %s written with the same maximum IDAT"
+ " chunk size (%d bytes),",
+ inname, PNG_ZBUF_SIZE);
+ fprintf(STDERR,
+ "\n filtering heuristic (libpng default), compression");
+ fprintf(STDERR,
+ " level (zlib default),\n and zlib version (%s)?\n\n",
+ ZLIB_VERSION);
+ wrote_question = 1;
+ }
+
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+
+ if (strict != 0 && unsupported_chunks == 0)
+ return (1);
+
+ else
+ return (0);
+ }
+
+ if (num_in == 0)
+ break;
+
+ if (memcmp(inbuf, outbuf, num_in))
+ {
+ fprintf(STDERR, "\nFiles %s and %s are different\n", inname,
+ outname);
+
+ if (wrote_question == 0 && unsupported_chunks == 0)
+ {
+ fprintf(STDERR,
+ " Was %s written with the same maximum"
+ " IDAT chunk size (%d bytes),",
+ inname, PNG_ZBUF_SIZE);
+ fprintf(STDERR,
+ "\n filtering heuristic (libpng default), compression");
+ fprintf(STDERR,
+ " level (zlib default),\n and zlib version (%s)?\n\n",
+ ZLIB_VERSION);
+ wrote_question = 1;
+ }
+
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+
+ /* NOTE: the unsupported_chunks escape is permitted here because
+ * unsupported text chunk compression will result in the compression
+ * mode being changed (to NONE) yet, in the test case, the result
+ * can be exactly the same size!
+ */
+ if (strict != 0 && unsupported_chunks == 0)
+ return (1);
+
+ else
+ return (0);
+ }
+ }
+ }
+#endif /* WRITE && WRITE_FILTER */
+
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+
+ return (0);
+}
+
+/* Input and output filenames */
+#ifdef RISCOS
+static PNG_CONST char *inname = "pngtest/png";
+static PNG_CONST char *outname = "pngout/png";
+#else
+static PNG_CONST char *inname = "pngtest.png";
+static PNG_CONST char *outname = "pngout.png";
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int multiple = 0;
+ int ierror = 0;
+
+ png_structp dummy_ptr;
+
+ fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
+ fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
+ fprintf(STDERR, "%s", png_get_copyright(NULL));
+ /* Show the version of libpng used in building the library */
+ fprintf(STDERR, " library (%lu):%s",
+ (unsigned long)png_access_version_number(),
+ png_get_header_version(NULL));
+
+ /* Show the version of libpng used in building the application */
+ fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
+ PNG_HEADER_VERSION_STRING);
+
+ /* Do some consistency checking on the memory allocation settings, I'm
+ * not sure this matters, but it is nice to know, the first of these
+ * tests should be impossible because of the way the macros are set
+ * in pngconf.h
+ */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+ fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
+#endif
+ /* I think the following can happen. */
+#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
+ fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
+#endif
+
+ if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
+ {
+ fprintf(STDERR,
+ "Warning: versions are different between png.h and png.c\n");
+ fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
+ fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
+ ++ierror;
+ }
+
+ if (argc > 1)
+ {
+ if (strcmp(argv[1], "-m") == 0)
+ {
+ multiple = 1;
+ status_dots_requested = 0;
+ }
+
+ else if (strcmp(argv[1], "-mv") == 0 ||
+ strcmp(argv[1], "-vm") == 0 )
+ {
+ multiple = 1;
+ verbose = 1;
+ status_dots_requested = 1;
+ }
+
+ else if (strcmp(argv[1], "-v") == 0)
+ {
+ verbose = 1;
+ status_dots_requested = 1;
+ inname = argv[2];
+ }
+
+ else if (strcmp(argv[1], "--strict") == 0)
+ {
+ status_dots_requested = 0;
+ verbose = 1;
+ inname = argv[2];
+ strict++;
+ relaxed = 0;
+ multiple=1;
+ }
+
+ else if (strcmp(argv[1], "--relaxed") == 0)
+ {
+ status_dots_requested = 0;
+ verbose = 1;
+ inname = argv[2];
+ strict = 0;
+ relaxed++;
+ multiple=1;
+ }
+ else if (strcmp(argv[1], "--xfail") == 0)
+ {
+ status_dots_requested = 0;
+ verbose = 1;
+ inname = argv[2];
+ strict = 0;
+ xfail++;
+ relaxed++;
+ multiple=1;
+ }
+
+ else
+ {
+ inname = argv[1];
+ status_dots_requested = 0;
+ }
+ }
+
+ if (multiple == 0 && argc == 3 + verbose)
+ outname = argv[2 + verbose];
+
+ if ((multiple == 0 && argc > 3 + verbose) ||
+ (multiple != 0 && argc < 2))
+ {
+ fprintf(STDERR,
+ "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
+ argv[0], argv[0]);
+ fprintf(STDERR,
+ " reads/writes one PNG file (without -m) or multiple files (-m)\n");
+ fprintf(STDERR,
+ " with -m %s is used as a temporary file\n", outname);
+ exit(1);
+ }
+
+ if (multiple != 0)
+ {
+ int i;
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ int allocation_now = current_allocation;
+#endif
+ for (i=2; i<argc; ++i)
+ {
+ int kerror;
+ fprintf(STDERR, "\n Testing %s:", argv[i]);
+#if PNG_DEBUG > 0
+ fprintf(STDERR, "\n");
+#endif
+ kerror = test_one_file(argv[i], outname);
+ if (kerror == 0)
+ {
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+ fprintf(STDERR, "\n PASS (%lu zero samples)\n",
+ (unsigned long)zero_samples);
+#else
+ fprintf(STDERR, " PASS\n");
+#endif
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+ if (tIME_chunk_present != 0)
+ fprintf(STDERR, " tIME = %s\n", tIME_string);
+
+ tIME_chunk_present = 0;
+#endif /* TIME_RFC1123 */
+ }
+
+ else
+ {
+ if (xfail)
+ fprintf(STDERR, " XFAIL\n");
+ else
+ {
+ fprintf(STDERR, " FAIL\n");
+ ierror += kerror;
+ }
+ }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ if (allocation_now != current_allocation)
+ fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+ current_allocation - allocation_now);
+
+ if (current_allocation != 0)
+ {
+ memory_infop pinfo = pinformation;
+
+ fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+ current_allocation);
+
+ while (pinfo != NULL)
+ {
+ fprintf(STDERR, " %lu bytes at %p\n",
+ (unsigned long)pinfo->size,
+ pinfo->pointer);
+ pinfo = pinfo->next;
+ }
+ }
+#endif
+ }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ fprintf(STDERR, " Current memory allocation: %10d bytes\n",
+ current_allocation);
+ fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
+ maximum_allocation);
+ fprintf(STDERR, " Total memory allocation: %10d bytes\n",
+ total_allocation);
+ fprintf(STDERR, " Number of allocations: %10d\n",
+ num_allocations);
+#endif
+ }
+
+ else
+ {
+ int i;
+ for (i = 0; i<3; ++i)
+ {
+ int kerror;
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ int allocation_now = current_allocation;
+#endif
+ if (i == 1)
+ status_dots_requested = 1;
+
+ else if (verbose == 0)
+ status_dots_requested = 0;
+
+ if (i == 0 || verbose == 1 || ierror != 0)
+ {
+ fprintf(STDERR, "\n Testing %s:", inname);
+#if PNG_DEBUG > 0
+ fprintf(STDERR, "\n");
+#endif
+ }
+
+ kerror = test_one_file(inname, outname);
+
+ if (kerror == 0)
+ {
+ if (verbose == 1 || i == 2)
+ {
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+ fprintf(STDERR, "\n PASS (%lu zero samples)\n",
+ (unsigned long)zero_samples);
+#else
+ fprintf(STDERR, " PASS\n");
+#endif
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+ if (tIME_chunk_present != 0)
+ fprintf(STDERR, " tIME = %s\n", tIME_string);
+#endif /* TIME_RFC1123 */
+ }
+ }
+
+ else
+ {
+ if (verbose == 0 && i != 2)
+ {
+ fprintf(STDERR, "\n Testing %s:", inname);
+#if PNG_DEBUG > 0
+ fprintf(STDERR, "\n");
+#endif
+ }
+
+ if (xfail)
+ fprintf(STDERR, " XFAIL\n");
+ else
+ {
+ fprintf(STDERR, " FAIL\n");
+ ierror += kerror;
+ }
+ }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ if (allocation_now != current_allocation)
+ fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+ current_allocation - allocation_now);
+
+ if (current_allocation != 0)
+ {
+ memory_infop pinfo = pinformation;
+
+ fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+ current_allocation);
+
+ while (pinfo != NULL)
+ {
+ fprintf(STDERR, " %lu bytes at %p\n",
+ (unsigned long)pinfo->size, pinfo->pointer);
+ pinfo = pinfo->next;
+ }
+ }
+#endif
+ }
+#if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG
+ fprintf(STDERR, " Current memory allocation: %10d bytes\n",
+ current_allocation);
+ fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
+ maximum_allocation);
+ fprintf(STDERR, " Total memory allocation: %10d bytes\n",
+ total_allocation);
+ fprintf(STDERR, " Number of allocations: %10d\n",
+ num_allocations);
+#endif
+ }
+
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_misc += (t_stop - t_start);
+ t_start = t_stop;
+ fprintf(STDERR, " CPU time used = %.3f seconds",
+ (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
+ fprintf(STDERR, " (decoding %.3f,\n",
+ t_decode/(float)CLOCKS_PER_SEC);
+ fprintf(STDERR, " encoding %.3f ,",
+ t_encode/(float)CLOCKS_PER_SEC);
+ fprintf(STDERR, " other %.3f seconds)\n\n",
+ t_misc/(float)CLOCKS_PER_SEC);
+#endif
+
+ if (ierror == 0)
+ fprintf(STDERR, " libpng passes test\n");
+
+ else
+ fprintf(STDERR, " libpng FAILS test\n");
+
+ dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ fprintf(STDERR, " Default limits:\n");
+ fprintf(STDERR, " width_max = %lu\n",
+ (unsigned long) png_get_user_width_max(dummy_ptr));
+ fprintf(STDERR, " height_max = %lu\n",
+ (unsigned long) png_get_user_height_max(dummy_ptr));
+ if (png_get_chunk_cache_max(dummy_ptr) == 0)
+ fprintf(STDERR, " cache_max = unlimited\n");
+ else
+ fprintf(STDERR, " cache_max = %lu\n",
+ (unsigned long) png_get_chunk_cache_max(dummy_ptr));
+ if (png_get_chunk_malloc_max(dummy_ptr) == 0)
+ fprintf(STDERR, " malloc_max = unlimited\n");
+ else
+ fprintf(STDERR, " malloc_max = %lu\n",
+ (unsigned long) png_get_chunk_malloc_max(dummy_ptr));
+ png_destroy_read_struct(&dummy_ptr, NULL, NULL);
+
+ return (int)(ierror != 0);
+}
+#else
+int
+main(void)
+{
+ fprintf(STDERR,
+ " test ignored because libpng was not built with read support\n");
+ /* And skip this test */
+ return PNG_LIBPNG_VER < 10600 ? 0 : 77;
+}
+#endif
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef png_libpng_version_1_6_34 Your_png_h_is_not_version_1_6_34;
diff --git a/xs/src/png/libpng/pngtrans.c b/xs/src/png/libpng/pngtrans.c
new file mode 100644
index 000000000..6882f0fd7
--- /dev/null
+++ b/xs/src/png/libpng/pngtrans.c
@@ -0,0 +1,864 @@
+
+/* pngtrans.c - transforms the data in a row (used by both readers and writers)
+ *
+ * Last changed in libpng 1.6.33 [September 28, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Turn on BGR-to-RGB mapping */
+void PNGAPI
+png_set_bgr(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_bgr");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_BGR;
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Turn on 16-bit byte swapping */
+void PNGAPI
+png_set_swap(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_swap");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (png_ptr->bit_depth == 16)
+ png_ptr->transformations |= PNG_SWAP_BYTES;
+}
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Turn on pixel packing */
+void PNGAPI
+png_set_packing(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_packing");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (png_ptr->bit_depth < 8)
+ {
+ png_ptr->transformations |= PNG_PACK;
+# ifdef PNG_WRITE_SUPPORTED
+ png_ptr->usr_bit_depth = 8;
+# endif
+ }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Turn on packed pixel swapping */
+void PNGAPI
+png_set_packswap(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_packswap");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (png_ptr->bit_depth < 8)
+ png_ptr->transformations |= PNG_PACKSWAP;
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+void PNGAPI
+png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
+{
+ png_debug(1, "in png_set_shift");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_SHIFT;
+ png_ptr->shift = *true_bits;
+}
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+int PNGAPI
+png_set_interlace_handling(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_interlace handling");
+
+ if (png_ptr != 0 && png_ptr->interlaced != 0)
+ {
+ png_ptr->transformations |= PNG_INTERLACE;
+ return (7);
+ }
+
+ return (1);
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte on read, or remove a filler or alpha byte on write.
+ * The filler type has changed in v0.95 to allow future 2-byte fillers
+ * for 48-bit input data, as well as to avoid problems with some compilers
+ * that don't like bytes as parameters.
+ */
+void PNGAPI
+png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
+{
+ png_debug(1, "in png_set_filler");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* In libpng 1.6 it is possible to determine whether this is a read or write
+ * operation and therefore to do more checking here for a valid call.
+ */
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
+ {
+# ifdef PNG_READ_FILLER_SUPPORTED
+ /* On read png_set_filler is always valid, regardless of the base PNG
+ * format, because other transformations can give a format where the
+ * filler code can execute (basically an 8 or 16-bit component RGB or G
+ * format.)
+ *
+ * NOTE: usr_channels is not used by the read code! (This has led to
+ * confusion in the past.) The filler is only used in the read code.
+ */
+ png_ptr->filler = (png_uint_16)filler;
+# else
+ png_app_error(png_ptr, "png_set_filler not supported on read");
+ PNG_UNUSED(filler) /* not used in the write case */
+ return;
+# endif
+ }
+
+ else /* write */
+ {
+# ifdef PNG_WRITE_FILLER_SUPPORTED
+ /* On write the usr_channels parameter must be set correctly at the
+ * start to record the number of channels in the app-supplied data.
+ */
+ switch (png_ptr->color_type)
+ {
+ case PNG_COLOR_TYPE_RGB:
+ png_ptr->usr_channels = 4;
+ break;
+
+ case PNG_COLOR_TYPE_GRAY:
+ if (png_ptr->bit_depth >= 8)
+ {
+ png_ptr->usr_channels = 2;
+ break;
+ }
+
+ else
+ {
+ /* There simply isn't any code in libpng to strip out bits
+ * from bytes when the components are less than a byte in
+ * size!
+ */
+ png_app_error(png_ptr,
+ "png_set_filler is invalid for"
+ " low bit depth gray output");
+ return;
+ }
+
+ default:
+ png_app_error(png_ptr,
+ "png_set_filler: inappropriate color type");
+ return;
+ }
+# else
+ png_app_error(png_ptr, "png_set_filler not supported on write");
+ return;
+# endif
+ }
+
+ /* Here on success - libpng supports the operation, set the transformation
+ * and the flag to say where the filler channel is.
+ */
+ png_ptr->transformations |= PNG_FILLER;
+
+ if (filler_loc == PNG_FILLER_AFTER)
+ png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
+
+ else
+ png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
+}
+
+/* Added to libpng-1.2.7 */
+void PNGAPI
+png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
+{
+ png_debug(1, "in png_set_add_alpha");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_set_filler(png_ptr, filler, filler_loc);
+ /* The above may fail to do anything. */
+ if ((png_ptr->transformations & PNG_FILLER) != 0)
+ png_ptr->transformations |= PNG_ADD_ALPHA;
+}
+
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_swap_alpha(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_swap_alpha");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_SWAP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_invert_alpha(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_invert_alpha");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_INVERT_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+void PNGAPI
+png_set_invert_mono(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_invert_mono");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_INVERT_MONO;
+}
+
+/* Invert monochrome grayscale data */
+void /* PRIVATE */
+png_do_invert(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_invert");
+
+ /* This test removed from libpng version 1.0.13 and 1.2.0:
+ * if (row_info->bit_depth == 1 &&
+ */
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_bytep rp = row;
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(~(*rp));
+ rp++;
+ }
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ row_info->bit_depth == 8)
+ {
+ png_bytep rp = row;
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i += 2)
+ {
+ *rp = (png_byte)(~(*rp));
+ rp += 2;
+ }
+ }
+
+#ifdef PNG_16BIT_SUPPORTED
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ row_info->bit_depth == 16)
+ {
+ png_bytep rp = row;
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i += 4)
+ {
+ *rp = (png_byte)(~(*rp));
+ *(rp + 1) = (png_byte)(~(*(rp + 1)));
+ rp += 4;
+ }
+ }
+#endif
+}
+#endif
+
+#ifdef PNG_16BIT_SUPPORTED
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swaps byte order on 16-bit depth images */
+void /* PRIVATE */
+png_do_swap(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_swap");
+
+ if (row_info->bit_depth == 16)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop= row_info->width * row_info->channels;
+
+ for (i = 0; i < istop; i++, rp += 2)
+ {
+#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
+ /* Feature added to libpng-1.6.11 for testing purposes, not
+ * enabled by default.
+ */
+ *(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
+#else
+ png_byte t = *rp;
+ *rp = *(rp + 1);
+ *(rp + 1) = t;
+#endif
+ }
+ }
+}
+#endif
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+static PNG_CONST png_byte onebppswaptable[256] = {
+ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+ 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+ 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+ 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+ 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+ 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+ 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+ 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+ 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+ 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+ 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+ 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+ 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+ 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+ 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+ 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+ 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+ 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+ 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+ 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+ 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+ 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+ 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+ 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+ 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+ 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+ 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+ 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+ 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+ 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+ 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+ 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+};
+
+static PNG_CONST png_byte twobppswaptable[256] = {
+ 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
+ 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
+ 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
+ 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
+ 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
+ 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
+ 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
+ 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
+ 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
+ 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
+ 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
+ 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
+ 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
+ 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
+ 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
+ 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
+ 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
+ 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
+ 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
+ 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
+ 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
+ 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
+ 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
+ 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
+ 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
+ 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
+ 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
+ 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
+ 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
+ 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
+ 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
+ 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
+};
+
+static PNG_CONST png_byte fourbppswaptable[256] = {
+ 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
+ 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
+ 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
+ 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
+ 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
+ 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
+ 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
+ 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
+ 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
+ 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
+ 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
+ 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
+ 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
+ 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
+ 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
+ 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
+ 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
+ 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
+ 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
+ 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
+ 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
+ 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
+ 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
+ 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
+ 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
+ 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
+ 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
+ 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
+ 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
+ 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
+ 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
+ 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
+};
+
+/* Swaps pixel packing order within bytes */
+void /* PRIVATE */
+png_do_packswap(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_packswap");
+
+ if (row_info->bit_depth < 8)
+ {
+ png_bytep rp;
+ png_const_bytep end, table;
+
+ end = row + row_info->rowbytes;
+
+ if (row_info->bit_depth == 1)
+ table = onebppswaptable;
+
+ else if (row_info->bit_depth == 2)
+ table = twobppswaptable;
+
+ else if (row_info->bit_depth == 4)
+ table = fourbppswaptable;
+
+ else
+ return;
+
+ for (rp = row; rp < end; rp++)
+ *rp = table[*rp];
+ }
+}
+#endif /* PACKSWAP || WRITE_PACKSWAP */
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+ defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
+ * somewhat weird combination of flags to determine what to do. All the calls
+ * to png_do_strip_filler are changed in 1.5.2 to call this instead with the
+ * correct arguments.
+ *
+ * The routine isn't general - the channel must be the channel at the start or
+ * end (not in the middle) of each pixel.
+ */
+void /* PRIVATE */
+png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
+{
+ png_bytep sp = row; /* source pointer */
+ png_bytep dp = row; /* destination pointer */
+ png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
+
+ /* At the start sp will point to the first byte to copy and dp to where
+ * it is copied to. ep always points just beyond the end of the row, so
+ * the loop simply copies (channels-1) channels until sp reaches ep.
+ *
+ * at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
+ * nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
+ */
+
+ /* GA, GX, XG cases */
+ if (row_info->channels == 2)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ if (at_start != 0) /* Skip initial filler */
+ ++sp;
+ else /* Skip initial channel and, for sp, the filler */
+ {
+ sp += 2; ++dp;
+ }
+
+ /* For a 1 pixel wide image there is nothing to do */
+ while (sp < ep)
+ {
+ *dp++ = *sp; sp += 2;
+ }
+
+ row_info->pixel_depth = 8;
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ if (at_start != 0) /* Skip initial filler */
+ sp += 2;
+ else /* Skip initial channel and, for sp, the filler */
+ {
+ sp += 4; dp += 2;
+ }
+
+ while (sp < ep)
+ {
+ *dp++ = *sp++; *dp++ = *sp; sp += 3;
+ }
+
+ row_info->pixel_depth = 16;
+ }
+
+ else
+ return; /* bad bit depth */
+
+ row_info->channels = 1;
+
+ /* Finally fix the color type if it records an alpha channel */
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ row_info->color_type = PNG_COLOR_TYPE_GRAY;
+ }
+
+ /* RGBA, RGBX, XRGB cases */
+ else if (row_info->channels == 4)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ if (at_start != 0) /* Skip initial filler */
+ ++sp;
+ else /* Skip initial channels and, for sp, the filler */
+ {
+ sp += 4; dp += 3;
+ }
+
+ /* Note that the loop adds 3 to dp and 4 to sp each time. */
+ while (sp < ep)
+ {
+ *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
+ }
+
+ row_info->pixel_depth = 24;
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ if (at_start != 0) /* Skip initial filler */
+ sp += 2;
+ else /* Skip initial channels and, for sp, the filler */
+ {
+ sp += 8; dp += 6;
+ }
+
+ while (sp < ep)
+ {
+ /* Copy 6 bytes, skip 2 */
+ *dp++ = *sp++; *dp++ = *sp++;
+ *dp++ = *sp++; *dp++ = *sp++;
+ *dp++ = *sp++; *dp++ = *sp; sp += 3;
+ }
+
+ row_info->pixel_depth = 48;
+ }
+
+ else
+ return; /* bad bit depth */
+
+ row_info->channels = 3;
+
+ /* Finally fix the color type if it records an alpha channel */
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ row_info->color_type = PNG_COLOR_TYPE_RGB;
+ }
+
+ else
+ return; /* The filler channel has gone already */
+
+ /* Fix the rowbytes value. */
+ row_info->rowbytes = (png_size_t)(dp-row);
+}
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Swaps red and blue bytes within a pixel */
+void /* PRIVATE */
+png_do_bgr(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_bgr");
+
+ if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 3)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 2);
+ *(rp + 2) = save;
+ }
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 4)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 2);
+ *(rp + 2) = save;
+ }
+ }
+ }
+
+#ifdef PNG_16BIT_SUPPORTED
+ else if (row_info->bit_depth == 16)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 6)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 4);
+ *(rp + 4) = save;
+ save = *(rp + 1);
+ *(rp + 1) = *(rp + 5);
+ *(rp + 5) = save;
+ }
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 8)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 4);
+ *(rp + 4) = save;
+ save = *(rp + 1);
+ *(rp + 1) = *(rp + 5);
+ *(rp + 5) = save;
+ }
+ }
+ }
+#endif
+ }
+}
+#endif /* READ_BGR || WRITE_BGR */
+
+#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
+ defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
+/* Added at libpng-1.5.10 */
+void /* PRIVATE */
+png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
+{
+ if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
+ png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
+ {
+ /* Calculations moved outside switch in an attempt to stop different
+ * compiler warnings. 'padding' is in *bits* within the last byte, it is
+ * an 'int' because pixel_depth becomes an 'int' in the expression below,
+ * and this calculation is used because it avoids warnings that other
+ * forms produced on either GCC or MSVC.
+ */
+ int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
+ png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
+
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ /* in this case, all bytes must be 0 so we don't need
+ * to unpack the pixels except for the rightmost one.
+ */
+ for (; rp > png_ptr->row_buf; rp--)
+ {
+ if ((*rp >> padding) != 0)
+ png_ptr->num_palette_max = 1;
+ padding = 0;
+ }
+
+ break;
+ }
+
+ case 2:
+ {
+ for (; rp > png_ptr->row_buf; rp--)
+ {
+ int i = ((*rp >> padding) & 0x03);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ i = (((*rp >> padding) >> 2) & 0x03);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ i = (((*rp >> padding) >> 4) & 0x03);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ i = (((*rp >> padding) >> 6) & 0x03);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ padding = 0;
+ }
+
+ break;
+ }
+
+ case 4:
+ {
+ for (; rp > png_ptr->row_buf; rp--)
+ {
+ int i = ((*rp >> padding) & 0x0f);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ i = (((*rp >> padding) >> 4) & 0x0f);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ padding = 0;
+ }
+
+ break;
+ }
+
+ case 8:
+ {
+ for (; rp > png_ptr->row_buf; rp--)
+ {
+ if (*rp > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = (int) *rp;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+}
+#endif /* CHECK_FOR_INVALID_INDEX */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+void PNGAPI
+png_set_user_transform_info(png_structrp png_ptr, png_voidp
+ user_transform_ptr, int user_transform_depth, int user_transform_channels)
+{
+ png_debug(1, "in png_set_user_transform_info");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+ (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
+ {
+ png_app_error(png_ptr,
+ "info change after png_start_read_image or png_read_update_info");
+ return;
+ }
+#endif
+
+ png_ptr->user_transform_ptr = user_transform_ptr;
+ png_ptr->user_transform_depth = (png_byte)user_transform_depth;
+ png_ptr->user_transform_channels = (png_byte)user_transform_channels;
+}
+#endif
+
+/* This function returns a pointer to the user_transform_ptr associated with
+ * the user transform functions. The application should free any memory
+ * associated with this pointer before png_write_destroy and png_read_destroy
+ * are called.
+ */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+png_voidp PNGAPI
+png_get_user_transform_ptr(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return (NULL);
+
+ return png_ptr->user_transform_ptr;
+}
+#endif
+
+#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
+png_uint_32 PNGAPI
+png_get_current_row_number(png_const_structrp png_ptr)
+{
+ /* See the comments in png.h - this is the sub-image row when reading an
+ * interlaced image.
+ */
+ if (png_ptr != NULL)
+ return png_ptr->row_number;
+
+ return PNG_UINT_32_MAX; /* help the app not to fail silently */
+}
+
+png_byte PNGAPI
+png_get_current_pass_number(png_const_structrp png_ptr)
+{
+ if (png_ptr != NULL)
+ return png_ptr->pass;
+ return 8; /* invalid */
+}
+#endif /* USER_TRANSFORM_INFO */
+#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
+#endif /* READ || WRITE */
diff --git a/xs/src/png/libpng/pngusr.dfa b/xs/src/png/libpng/pngusr.dfa
new file mode 100644
index 000000000..83067c38c
--- /dev/null
+++ b/xs/src/png/libpng/pngusr.dfa
@@ -0,0 +1,14 @@
+# pngusr.dfa
+#
+# Build time configuration of libpng
+#
+# Enter build configuration options in this file
+#
+# Security settings: by default these limits are unset, you can change them
+# here by entering the appropriate values as #defines preceded by '@' (to cause,
+# them to be passed through to the build of pnglibconf.h), for example:
+#
+# @# define PNG_USER_WIDTH_MAX 65535
+# @# define PNG_USER_HEIGHT_MAX 65535
+# @# define PNG_USER_CHUNK_CACHE_MAX 256
+# @# define PNG_USER_CHUNK_MALLOC_MAX 640000
diff --git a/xs/src/png/libpng/pngwio.c b/xs/src/png/libpng/pngwio.c
new file mode 100644
index 000000000..37c7c3a7f
--- /dev/null
+++ b/xs/src/png/libpng/pngwio.c
@@ -0,0 +1,168 @@
+
+/* pngwio.c - functions for data output
+ *
+ * Last changed in libpng 1.6.24 [August 4, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all output. Users who need
+ * special handling are expected to write functions that have the same
+ * arguments as these and perform similar functions, but that possibly
+ * use different output methods. Note that you shouldn't change these
+ * functions, but rather write replacement functions and then change
+ * them at run time with png_set_write_fn(...).
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Write the data to whatever output you are using. The default routine
+ * writes to a file pointer. Note that this routine sometimes gets called
+ * with very small lengths, so you should implement some kind of simple
+ * buffering if you are using unbuffered writes. This should never be asked
+ * to write more than 64K on a 16-bit machine.
+ */
+
+void /* PRIVATE */
+png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)
+{
+ /* NOTE: write_data_fn must not change the buffer! */
+ if (png_ptr->write_data_fn != NULL )
+ (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
+ length);
+
+ else
+ png_error(png_ptr, "Call to NULL write function");
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+/* This is the function that does the actual writing of data. If you are
+ * not writing to a standard C stream, you should create a replacement
+ * write_data function and use it at run time with png_set_write_fn(), rather
+ * than changing the library.
+ */
+void PNGCBAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_size_t check;
+
+ if (png_ptr == NULL)
+ return;
+
+ check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
+
+ if (check != length)
+ png_error(png_ptr, "Write Error");
+}
+#endif
+
+/* This function is called to output any data pending writing (normally
+ * to disk). After png_flush is called, there should be no data pending
+ * writing in any buffers.
+ */
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+void /* PRIVATE */
+png_flush(png_structrp png_ptr)
+{
+ if (png_ptr->output_flush_fn != NULL)
+ (*(png_ptr->output_flush_fn))(png_ptr);
+}
+
+# ifdef PNG_STDIO_SUPPORTED
+void PNGCBAPI
+png_default_flush(png_structp png_ptr)
+{
+ png_FILE_p io_ptr;
+
+ if (png_ptr == NULL)
+ return;
+
+ io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr));
+ fflush(io_ptr);
+}
+# endif
+#endif
+
+/* This function allows the application to supply new output functions for
+ * libpng if standard C streams aren't being used.
+ *
+ * This function takes as its arguments:
+ * png_ptr - pointer to a png output data structure
+ * io_ptr - pointer to user supplied structure containing info about
+ * the output functions. May be NULL.
+ * write_data_fn - pointer to a new output function that takes as its
+ * arguments a pointer to a png_struct, a pointer to
+ * data to be written, and a 32-bit unsigned int that is
+ * the number of bytes to be written. The new write
+ * function should call png_error(png_ptr, "Error msg")
+ * to exit and output any fatal error messages. May be
+ * NULL, in which case libpng's default function will
+ * be used.
+ * flush_data_fn - pointer to a new flush function that takes as its
+ * arguments a pointer to a png_struct. After a call to
+ * the flush function, there should be no data in any buffers
+ * or pending transmission. If the output method doesn't do
+ * any buffering of output, a function prototype must still be
+ * supplied although it doesn't have to do anything. If
+ * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
+ * time, output_flush_fn will be ignored, although it must be
+ * supplied for compatibility. May be NULL, in which case
+ * libpng's default function will be used, if
+ * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not
+ * a good idea if io_ptr does not point to a standard
+ * *FILE structure.
+ */
+void PNGAPI
+png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr,
+ png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->io_ptr = io_ptr;
+
+#ifdef PNG_STDIO_SUPPORTED
+ if (write_data_fn != NULL)
+ png_ptr->write_data_fn = write_data_fn;
+
+ else
+ png_ptr->write_data_fn = png_default_write_data;
+#else
+ png_ptr->write_data_fn = write_data_fn;
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+# ifdef PNG_STDIO_SUPPORTED
+
+ if (output_flush_fn != NULL)
+ png_ptr->output_flush_fn = output_flush_fn;
+
+ else
+ png_ptr->output_flush_fn = png_default_flush;
+
+# else
+ png_ptr->output_flush_fn = output_flush_fn;
+# endif
+#else
+ PNG_UNUSED(output_flush_fn)
+#endif /* WRITE_FLUSH */
+
+#ifdef PNG_READ_SUPPORTED
+ /* It is an error to read while writing a png file */
+ if (png_ptr->read_data_fn != NULL)
+ {
+ png_ptr->read_data_fn = NULL;
+
+ png_warning(png_ptr,
+ "Can't set both read_data_fn and write_data_fn in the"
+ " same structure");
+ }
+#endif
+}
+#endif /* WRITE */
diff --git a/xs/src/png/libpng/pngwrite.c b/xs/src/png/libpng/pngwrite.c
new file mode 100644
index 000000000..a16d77ce0
--- /dev/null
+++ b/xs/src/png/libpng/pngwrite.c
@@ -0,0 +1,2396 @@
+
+/* pngwrite.c - general routines to write a PNG file
+ *
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
+# include <errno.h>
+#endif /* SIMPLIFIED_WRITE_STDIO */
+
+#ifdef PNG_WRITE_SUPPORTED
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+/* Write out all the unknown chunks for the current given location */
+static void
+write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
+ unsigned int where)
+{
+ if (info_ptr->unknown_chunks_num != 0)
+ {
+ png_const_unknown_chunkp up;
+
+ png_debug(5, "writing extra chunks");
+
+ for (up = info_ptr->unknown_chunks;
+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+ ++up)
+ if ((up->location & where) != 0)
+ {
+ /* If per-chunk unknown chunk handling is enabled use it, otherwise
+ * just write the chunks the application has set.
+ */
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ int keep = png_handle_as_unknown(png_ptr, up->name);
+
+ /* NOTE: this code is radically different from the read side in the
+ * matter of handling an ancillary unknown chunk. In the read side
+ * the default behavior is to discard it, in the code below the default
+ * behavior is to write it. Critical chunks are, however, only
+ * written if explicitly listed or if the default is set to write all
+ * unknown chunks.
+ *
+ * The default handling is also slightly weird - it is not possible to
+ * stop the writing of all unsafe-to-copy chunks!
+ *
+ * TODO: REVIEW: this would seem to be a bug.
+ */
+ if (keep != PNG_HANDLE_CHUNK_NEVER &&
+ ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ ||
+ keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (keep == PNG_HANDLE_CHUNK_AS_DEFAULT &&
+ png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS)))
+#endif
+ {
+ /* TODO: review, what is wrong with a zero length unknown chunk? */
+ if (up->size == 0)
+ png_warning(png_ptr, "Writing zero-length unknown chunk");
+
+ png_write_chunk(png_ptr, up->name, up->data, up->size);
+ }
+ }
+ }
+}
+#endif /* WRITE_UNKNOWN_CHUNKS */
+
+/* Writes all the PNG information. This is the suggested way to use the
+ * library. If you have a new chunk to add, make a function to write it,
+ * and put it in the correct location here. If you want the chunk written
+ * after the image data, put it in png_write_end(). I strongly encourage
+ * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
+ * the chunk, as that will keep the code from breaking if you want to just
+ * write a plain PNG file. If you have long comments, I suggest writing
+ * them in png_write_end(), and compressing them.
+ */
+void PNGAPI
+png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
+{
+ png_debug(1, "in png_write_info_before_PLTE");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0)
+ {
+ /* Write PNG signature */
+ png_write_sig(png_ptr);
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) != 0 && \
+ png_ptr->mng_features_permitted != 0)
+ {
+ png_warning(png_ptr,
+ "MNG features are not allowed in a PNG datastream");
+ png_ptr->mng_features_permitted = 0;
+ }
+#endif
+
+ /* Write IHDR information. */
+ png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
+ info_ptr->filter_type,
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ info_ptr->interlace_type
+#else
+ 0
+#endif
+ );
+
+ /* The rest of these check to see if the valid field has the appropriate
+ * flag set, and if it does, writes the chunk.
+ *
+ * 1.6.0: COLORSPACE support controls the writing of these chunks too, and
+ * the chunks will be written if the WRITE routine is there and
+ * information * is available in the COLORSPACE. (See
+ * png_colorspace_sync_info in png.c for where the valid flags get set.)
+ *
+ * Under certain circumstances the colorspace can be invalidated without
+ * syncing the info_struct 'valid' flags; this happens if libpng detects
+ * an error and calls png_error while the color space is being set, yet
+ * the application continues writing the PNG. So check the 'invalid'
+ * flag here too.
+ */
+#ifdef PNG_GAMMA_SUPPORTED
+# ifdef PNG_WRITE_gAMA_SUPPORTED
+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) != 0 &&
+ (info_ptr->valid & PNG_INFO_gAMA) != 0)
+ png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma);
+# endif
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+ /* Write only one of sRGB or an ICC profile. If a profile was supplied
+ * and it matches one of the known sRGB ones issue a warning.
+ */
+# ifdef PNG_WRITE_iCCP_SUPPORTED
+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+ (info_ptr->valid & PNG_INFO_iCCP) != 0)
+ {
+# ifdef PNG_WRITE_sRGB_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_sRGB) != 0)
+ png_app_warning(png_ptr,
+ "profile matches sRGB but writing iCCP instead");
+# endif
+
+ png_write_iCCP(png_ptr, info_ptr->iccp_name,
+ info_ptr->iccp_profile);
+ }
+# ifdef PNG_WRITE_sRGB_SUPPORTED
+ else
+# endif
+# endif
+
+# ifdef PNG_WRITE_sRGB_SUPPORTED
+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+ (info_ptr->valid & PNG_INFO_sRGB) != 0)
+ png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent);
+# endif /* WRITE_sRGB */
+#endif /* COLORSPACE */
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
+ png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+# ifdef PNG_WRITE_cHRM_SUPPORTED
+ if ((info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) == 0 &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) != 0 &&
+ (info_ptr->valid & PNG_INFO_cHRM) != 0)
+ png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy);
+# endif
+#endif
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR);
+#endif
+
+ png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
+ }
+}
+
+void PNGAPI
+png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
+{
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+ int i;
+#endif
+
+ png_debug(1, "in png_write_info");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_write_info_before_PLTE(png_ptr, info_ptr);
+
+ if ((info_ptr->valid & PNG_INFO_PLTE) != 0)
+ png_write_PLTE(png_ptr, info_ptr->palette,
+ (png_uint_32)info_ptr->num_palette);
+
+ else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_error(png_ptr, "Valid palette required for paletted images");
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_tRNS) !=0)
+ {
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+ /* Invert the alpha channel (in tRNS) */
+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0 &&
+ info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ int j, jend;
+
+ jend = info_ptr->num_trans;
+ if (jend > PNG_MAX_PALETTE_LENGTH)
+ jend = PNG_MAX_PALETTE_LENGTH;
+
+ for (j = 0; j<jend; ++j)
+ info_ptr->trans_alpha[j] =
+ (png_byte)(255 - info_ptr->trans_alpha[j]);
+ }
+#endif
+ png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color),
+ info_ptr->num_trans, info_ptr->color_type);
+ }
+#endif
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_bKGD) != 0)
+ png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
+#endif
+
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_eXIf) != 0)
+ png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif);
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_hIST) != 0)
+ png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_oFFs) != 0)
+ png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
+ info_ptr->offset_unit_type);
+#endif
+
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_pCAL) != 0)
+ png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
+ info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
+ info_ptr->pcal_units, info_ptr->pcal_params);
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_sCAL) != 0)
+ png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
+ info_ptr->scal_s_width, info_ptr->scal_s_height);
+#endif /* sCAL */
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_pHYs) != 0)
+ png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
+ info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
+#endif /* pHYs */
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_tIME) != 0)
+ {
+ png_write_tIME(png_ptr, &(info_ptr->mod_time));
+ png_ptr->mode |= PNG_WROTE_tIME;
+ }
+#endif /* tIME */
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_sPLT) != 0)
+ for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+ png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
+#endif /* sPLT */
+
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+ /* Check to see if we need to write text chunks */
+ for (i = 0; i < info_ptr->num_text; i++)
+ {
+ png_debug2(2, "Writing header text chunk %d, type %d", i,
+ info_ptr->text[i].compression);
+ /* An internationalized chunk? */
+ if (info_ptr->text[i].compression > 0)
+ {
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+ /* Write international chunk */
+ png_write_iTXt(png_ptr,
+ info_ptr->text[i].compression,
+ info_ptr->text[i].key,
+ info_ptr->text[i].lang,
+ info_ptr->text[i].lang_key,
+ info_ptr->text[i].text);
+ /* Mark this chunk as written */
+ if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ else
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+#else
+ png_warning(png_ptr, "Unable to write international text");
+#endif
+ }
+
+ /* If we want a compressed text chunk */
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
+ {
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+ /* Write compressed chunk */
+ png_write_zTXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, info_ptr->text[i].compression);
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+#else
+ png_warning(png_ptr, "Unable to write compressed text");
+#endif
+ }
+
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+ /* Write uncompressed chunk */
+ png_write_tEXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text,
+ 0);
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+#else
+ /* Can't get here */
+ png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+ }
+ }
+#endif /* tEXt */
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE);
+#endif
+}
+
+/* Writes the end of the PNG file. If you don't want to write comments or
+ * time information, you can pass NULL for info. If you already wrote these
+ * in png_write_info(), do not write them again here. If you have long
+ * comments, I suggest writing them here, and compressing them.
+ */
+void PNGAPI
+png_write_end(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_debug(1, "in png_write_end");
+
+ if (png_ptr == NULL)
+ return;
+
+ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0)
+ png_error(png_ptr, "No IDATs written into file");
+
+#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ if (png_ptr->num_palette_max > png_ptr->num_palette)
+ png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
+#endif
+
+ /* See if user wants us to write information chunks */
+ if (info_ptr != NULL)
+ {
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+ int i; /* local index variable */
+#endif
+#ifdef PNG_WRITE_tIME_SUPPORTED
+ /* Check to see if user has supplied a time chunk */
+ if ((info_ptr->valid & PNG_INFO_tIME) != 0 &&
+ (png_ptr->mode & PNG_WROTE_tIME) == 0)
+ png_write_tIME(png_ptr, &(info_ptr->mod_time));
+
+#endif
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+ /* Loop through comment chunks */
+ for (i = 0; i < info_ptr->num_text; i++)
+ {
+ png_debug2(2, "Writing trailer text chunk %d, type %d", i,
+ info_ptr->text[i].compression);
+ /* An internationalized chunk? */
+ if (info_ptr->text[i].compression > 0)
+ {
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+ /* Write international chunk */
+ png_write_iTXt(png_ptr,
+ info_ptr->text[i].compression,
+ info_ptr->text[i].key,
+ info_ptr->text[i].lang,
+ info_ptr->text[i].lang_key,
+ info_ptr->text[i].text);
+ /* Mark this chunk as written */
+ if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ else
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+#else
+ png_warning(png_ptr, "Unable to write international text");
+#endif
+ }
+
+ else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+ {
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+ /* Write compressed chunk */
+ png_write_zTXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, info_ptr->text[i].compression);
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+#else
+ png_warning(png_ptr, "Unable to write compressed text");
+#endif
+ }
+
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+ /* Write uncompressed chunk */
+ png_write_tEXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0);
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+#else
+ png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+ }
+ }
+#endif
+
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_eXIf) != 0)
+ png_write_eXIf(png_ptr, info_ptr->exif, info_ptr->num_exif);
+#endif
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
+#endif
+ }
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ /* Write end of PNG file */
+ png_write_IEND(png_ptr);
+
+ /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03,
+ * and restored again in libpng-1.2.30, may cause some applications that
+ * do not set png_ptr->output_flush_fn to crash. If your application
+ * experiences a problem, please try building libpng with
+ * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to
+ * png-mng-implement at lists.sf.net .
+ */
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+# ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED
+ png_flush(png_ptr);
+# endif
+#endif
+}
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+void PNGAPI
+png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime)
+{
+ png_debug(1, "in png_convert_from_struct_tm");
+
+ ptime->year = (png_uint_16)(1900 + ttime->tm_year);
+ ptime->month = (png_byte)(ttime->tm_mon + 1);
+ ptime->day = (png_byte)ttime->tm_mday;
+ ptime->hour = (png_byte)ttime->tm_hour;
+ ptime->minute = (png_byte)ttime->tm_min;
+ ptime->second = (png_byte)ttime->tm_sec;
+}
+
+void PNGAPI
+png_convert_from_time_t(png_timep ptime, time_t ttime)
+{
+ struct tm *tbuf;
+
+ png_debug(1, "in png_convert_from_time_t");
+
+ tbuf = gmtime(&ttime);
+ png_convert_from_struct_tm(ptime, tbuf);
+}
+#endif
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
+{
+#ifndef PNG_USER_MEM_SUPPORTED
+ png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+ error_fn, warn_fn, NULL, NULL, NULL);
+#else
+ return png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
+ warn_fn, NULL, NULL, NULL);
+}
+
+/* Alternate initialize png_ptr structure, and allocate any memory needed */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
+{
+ png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+ error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+#endif /* USER_MEM */
+ if (png_ptr != NULL)
+ {
+ /* Set the zlib control values to defaults; they can be overridden by the
+ * application after the struct has been created.
+ */
+ png_ptr->zbuffer_size = PNG_ZBUF_SIZE;
+
+ /* The 'zlib_strategy' setting is irrelevant because png_default_claim in
+ * pngwutil.c defaults it according to whether or not filters will be
+ * used, and ignores this setting.
+ */
+ png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY;
+ png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION;
+ png_ptr->zlib_mem_level = 8;
+ png_ptr->zlib_window_bits = 15;
+ png_ptr->zlib_method = 8;
+
+#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
+ png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY;
+ png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION;
+ png_ptr->zlib_text_mem_level = 8;
+ png_ptr->zlib_text_window_bits = 15;
+ png_ptr->zlib_text_method = 8;
+#endif /* WRITE_COMPRESSED_TEXT */
+
+ /* This is a highly dubious configuration option; by default it is off,
+ * but it may be appropriate for private builds that are testing
+ * extensions not conformant to the current specification, or of
+ * applications that must not fail to write at all costs!
+ */
+#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED
+ /* In stable builds only warn if an application error can be completely
+ * handled.
+ */
+ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
+#endif
+
+ /* App warnings are warnings in release (or release candidate) builds but
+ * are errors during development.
+ */
+#if PNG_RELEASE_BUILD
+ png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
+#endif
+
+ /* TODO: delay this, it can be done in png_init_io() (if the app doesn't
+ * do it itself) avoiding setting the default function if it is not
+ * required.
+ */
+ png_set_write_fn(png_ptr, NULL, NULL, NULL);
+ }
+
+ return png_ptr;
+}
+
+
+/* Write a few rows of image data. If the image is interlaced,
+ * either you will have to write the 7 sub images, or, if you
+ * have called png_set_interlace_handling(), you will have to
+ * "write" the image seven times.
+ */
+void PNGAPI
+png_write_rows(png_structrp png_ptr, png_bytepp row,
+ png_uint_32 num_rows)
+{
+ png_uint_32 i; /* row counter */
+ png_bytepp rp; /* row pointer */
+
+ png_debug(1, "in png_write_rows");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* Loop through the rows */
+ for (i = 0, rp = row; i < num_rows; i++, rp++)
+ {
+ png_write_row(png_ptr, *rp);
+ }
+}
+
+/* Write the image. You only need to call this function once, even
+ * if you are writing an interlaced image.
+ */
+void PNGAPI
+png_write_image(png_structrp png_ptr, png_bytepp image)
+{
+ png_uint_32 i; /* row index */
+ int pass, num_pass; /* pass variables */
+ png_bytepp rp; /* points to current row */
+
+ if (png_ptr == NULL)
+ return;
+
+ png_debug(1, "in png_write_image");
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Initialize interlace handling. If image is not interlaced,
+ * this will set pass to 1
+ */
+ num_pass = png_set_interlace_handling(png_ptr);
+#else
+ num_pass = 1;
+#endif
+ /* Loop through passes */
+ for (pass = 0; pass < num_pass; pass++)
+ {
+ /* Loop through image */
+ for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
+ {
+ png_write_row(png_ptr, *rp);
+ }
+ }
+}
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Performs intrapixel differencing */
+static void
+png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_intrapixel");
+
+ if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ {
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
+
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)(*rp - *(rp + 1));
+ *(rp + 2) = (png_byte)(*(rp + 2) - *(rp + 1));
+ }
+ }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ else if (row_info->bit_depth == 16)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
+
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0 = (png_uint_32)(*(rp ) << 8) | *(rp + 1);
+ png_uint_32 s1 = (png_uint_32)(*(rp + 2) << 8) | *(rp + 3);
+ png_uint_32 s2 = (png_uint_32)(*(rp + 4) << 8) | *(rp + 5);
+ png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
+ png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
+ *(rp ) = (png_byte)(red >> 8);
+ *(rp + 1) = (png_byte)red;
+ *(rp + 4) = (png_byte)(blue >> 8);
+ *(rp + 5) = (png_byte)blue;
+ }
+ }
+#endif /* WRITE_16BIT */
+ }
+}
+#endif /* MNG_FEATURES */
+
+/* Called by user to write a row of image data */
+void PNGAPI
+png_write_row(png_structrp png_ptr, png_const_bytep row)
+{
+ /* 1.5.6: moved from png_struct to be a local structure: */
+ png_row_info row_info;
+
+ if (png_ptr == NULL)
+ return;
+
+ png_debug2(1, "in png_write_row (row %u, pass %d)",
+ png_ptr->row_number, png_ptr->pass);
+
+ /* Initialize transformations and other stuff if first time */
+ if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+ {
+ /* Make sure we wrote the header info */
+ if ((png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE) == 0)
+ png_error(png_ptr,
+ "png_write_info was never called before png_write_row");
+
+ /* Check for transforms that have been set but were defined out */
+#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
+ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
+ png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
+ if ((png_ptr->transformations & PNG_FILLER) != 0)
+ png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined");
+#endif
+#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
+ defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+ png_warning(png_ptr,
+ "PNG_WRITE_PACKSWAP_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
+ if ((png_ptr->transformations & PNG_PACK) != 0)
+ png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
+ if ((png_ptr->transformations & PNG_SHIFT) != 0)
+ png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
+ if ((png_ptr->transformations & PNG_BGR) != 0)
+ png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
+ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
+ png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined");
+#endif
+
+ png_write_start_row(png_ptr);
+ }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* If interlaced and not interested in row, return */
+ if (png_ptr->interlaced != 0 &&
+ (png_ptr->transformations & PNG_INTERLACE) != 0)
+ {
+ switch (png_ptr->pass)
+ {
+ case 0:
+ if ((png_ptr->row_number & 0x07) != 0)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 1:
+ if ((png_ptr->row_number & 0x07) != 0 || png_ptr->width < 5)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 2:
+ if ((png_ptr->row_number & 0x07) != 4)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 3:
+ if ((png_ptr->row_number & 0x03) != 0 || png_ptr->width < 3)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 4:
+ if ((png_ptr->row_number & 0x03) != 2)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 5:
+ if ((png_ptr->row_number & 0x01) != 0 || png_ptr->width < 2)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 6:
+ if ((png_ptr->row_number & 0x01) == 0)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ default: /* error: ignore it */
+ break;
+ }
+ }
+#endif
+
+ /* Set up row info for transformations */
+ row_info.color_type = png_ptr->color_type;
+ row_info.width = png_ptr->usr_width;
+ row_info.channels = png_ptr->usr_channels;
+ row_info.bit_depth = png_ptr->usr_bit_depth;
+ row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels);
+ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
+
+ png_debug1(3, "row_info->color_type = %d", row_info.color_type);
+ png_debug1(3, "row_info->width = %u", row_info.width);
+ png_debug1(3, "row_info->channels = %d", row_info.channels);
+ png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth);
+ png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth);
+ png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes);
+
+ /* Copy user's row into buffer, leaving room for filter byte. */
+ memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes);
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Handle interlacing */
+ if (png_ptr->interlaced && png_ptr->pass < 6 &&
+ (png_ptr->transformations & PNG_INTERLACE) != 0)
+ {
+ png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass);
+ /* This should always get caught above, but still ... */
+ if (row_info.width == 0)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ }
+#endif
+
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+ /* Handle other transformations */
+ if (png_ptr->transformations != 0)
+ png_do_write_transformations(png_ptr, &row_info);
+#endif
+
+ /* At this point the row_info pixel depth must match the 'transformed' depth,
+ * which is also the output depth.
+ */
+ if (row_info.pixel_depth != png_ptr->pixel_depth ||
+ row_info.pixel_depth != png_ptr->transformed_pixel_depth)
+ png_error(png_ptr, "internal write transform logic error");
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ /* Write filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not write a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+ (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+ {
+ /* Intrapixel differencing */
+ png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1);
+ }
+#endif
+
+/* Added at libpng-1.5.10 */
+#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ /* Check for out-of-range palette index */
+ if (row_info.color_type == PNG_COLOR_TYPE_PALETTE &&
+ png_ptr->num_palette_max >= 0)
+ png_do_check_palette_indexes(png_ptr, &row_info);
+#endif
+
+ /* Find a filter if necessary, filter the row and write it out. */
+ png_write_find_filter(png_ptr, &row_info);
+
+ if (png_ptr->write_row_fn != NULL)
+ (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+/* Set the automatic flush interval or 0 to turn flushing off */
+void PNGAPI
+png_set_flush(png_structrp png_ptr, int nrows)
+{
+ png_debug(1, "in png_set_flush");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->flush_dist = (nrows < 0 ? 0 : (png_uint_32)nrows);
+}
+
+/* Flush the current output buffers now */
+void PNGAPI
+png_write_flush(png_structrp png_ptr)
+{
+ png_debug(1, "in png_write_flush");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* We have already written out all of the data */
+ if (png_ptr->row_number >= png_ptr->num_rows)
+ return;
+
+ png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH);
+ png_ptr->flush_rows = 0;
+ png_flush(png_ptr);
+}
+#endif /* WRITE_FLUSH */
+
+/* Free any memory used in png_ptr struct without freeing the struct itself. */
+static void
+png_write_destroy(png_structrp png_ptr)
+{
+ png_debug(1, "in png_write_destroy");
+
+ /* Free any memory zlib uses */
+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
+ deflateEnd(&png_ptr->zstream);
+
+ /* Free our memory. png_free checks NULL for us. */
+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+ png_free(png_ptr, png_ptr->row_buf);
+ png_ptr->row_buf = NULL;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ png_free(png_ptr, png_ptr->prev_row);
+ png_free(png_ptr, png_ptr->try_row);
+ png_free(png_ptr, png_ptr->tst_row);
+ png_ptr->prev_row = NULL;
+ png_ptr->try_row = NULL;
+ png_ptr->tst_row = NULL;
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ png_free(png_ptr, png_ptr->chunk_list);
+ png_ptr->chunk_list = NULL;
+#endif
+
+ /* The error handling and memory handling information is left intact at this
+ * point: the jmp_buf may still have to be freed. See png_destroy_png_struct
+ * for how this happens.
+ */
+}
+
+/* Free all memory used by the write.
+ * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for
+ * *png_ptr_ptr. Prior to 1.6.0 it would accept such a value and it would free
+ * the passed in info_structs but it would quietly fail to free any of the data
+ * inside them. In 1.6.0 it quietly does nothing (it has to be quiet because it
+ * has no png_ptr.)
+ */
+void PNGAPI
+png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
+{
+ png_debug(1, "in png_destroy_write_struct");
+
+ if (png_ptr_ptr != NULL)
+ {
+ png_structrp png_ptr = *png_ptr_ptr;
+
+ if (png_ptr != NULL) /* added in libpng 1.6.0 */
+ {
+ png_destroy_info_struct(png_ptr, info_ptr_ptr);
+
+ *png_ptr_ptr = NULL;
+ png_write_destroy(png_ptr);
+ png_destroy_png_struct(png_ptr);
+ }
+ }
+}
+
+/* Allow the application to select one or more row filters to use. */
+void PNGAPI
+png_set_filter(png_structrp png_ptr, int method, int filters)
+{
+ png_debug(1, "in png_set_filter");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+ (method == PNG_INTRAPIXEL_DIFFERENCING))
+ method = PNG_FILTER_TYPE_BASE;
+
+#endif
+ if (method == PNG_FILTER_TYPE_BASE)
+ {
+ switch (filters & (PNG_ALL_FILTERS | 0x07))
+ {
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ case 5:
+ case 6:
+ case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
+#endif /* WRITE_FILTER */
+ /* FALLTHROUGH */
+ case PNG_FILTER_VALUE_NONE:
+ png_ptr->do_filter = PNG_FILTER_NONE; break;
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ case PNG_FILTER_VALUE_SUB:
+ png_ptr->do_filter = PNG_FILTER_SUB; break;
+
+ case PNG_FILTER_VALUE_UP:
+ png_ptr->do_filter = PNG_FILTER_UP; break;
+
+ case PNG_FILTER_VALUE_AVG:
+ png_ptr->do_filter = PNG_FILTER_AVG; break;
+
+ case PNG_FILTER_VALUE_PAETH:
+ png_ptr->do_filter = PNG_FILTER_PAETH; break;
+
+ default:
+ png_ptr->do_filter = (png_byte)filters; break;
+#else
+ default:
+ png_app_error(png_ptr, "Unknown row filter for method 0");
+#endif /* WRITE_FILTER */
+ }
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ /* If we have allocated the row_buf, this means we have already started
+ * with the image and we should have allocated all of the filter buffers
+ * that have been selected. If prev_row isn't already allocated, then
+ * it is too late to start using the filters that need it, since we
+ * will be missing the data in the previous row. If an application
+ * wants to start and stop using particular filters during compression,
+ * it should start out with all of the filters, and then remove them
+ * or add them back after the start of compression.
+ *
+ * NOTE: this is a nasty constraint on the code, because it means that the
+ * prev_row buffer must be maintained even if there are currently no
+ * 'prev_row' requiring filters active.
+ */
+ if (png_ptr->row_buf != NULL)
+ {
+ int num_filters;
+ png_alloc_size_t buf_size;
+
+ /* Repeat the checks in png_write_start_row; 1 pixel high or wide
+ * images cannot benefit from certain filters. If this isn't done here
+ * the check below will fire on 1 pixel high images.
+ */
+ if (png_ptr->height == 1)
+ filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
+
+ if (png_ptr->width == 1)
+ filters &= ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH);
+
+ if ((filters & (PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH)) != 0
+ && png_ptr->prev_row == NULL)
+ {
+ /* This is the error case, however it is benign - the previous row
+ * is not available so the filter can't be used. Just warn here.
+ */
+ png_app_warning(png_ptr,
+ "png_set_filter: UP/AVG/PAETH cannot be added after start");
+ filters &= ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
+ }
+
+ num_filters = 0;
+
+ if (filters & PNG_FILTER_SUB)
+ num_filters++;
+
+ if (filters & PNG_FILTER_UP)
+ num_filters++;
+
+ if (filters & PNG_FILTER_AVG)
+ num_filters++;
+
+ if (filters & PNG_FILTER_PAETH)
+ num_filters++;
+
+ /* Allocate needed row buffers if they have not already been
+ * allocated.
+ */
+ buf_size = PNG_ROWBYTES(png_ptr->usr_channels * png_ptr->usr_bit_depth,
+ png_ptr->width) + 1;
+
+ if (png_ptr->try_row == NULL)
+ png_ptr->try_row = png_voidcast(png_bytep,
+ png_malloc(png_ptr, buf_size));
+
+ if (num_filters > 1)
+ {
+ if (png_ptr->tst_row == NULL)
+ png_ptr->tst_row = png_voidcast(png_bytep,
+ png_malloc(png_ptr, buf_size));
+ }
+ }
+ png_ptr->do_filter = (png_byte)filters;
+#endif
+ }
+ else
+ png_error(png_ptr, "Unknown custom filter method");
+}
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* DEPRECATED */
+/* Provide floating and fixed point APIs */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method,
+ int num_weights, png_const_doublep filter_weights,
+ png_const_doublep filter_costs)
+{
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(heuristic_method)
+ PNG_UNUSED(num_weights)
+ PNG_UNUSED(filter_weights)
+ PNG_UNUSED(filter_costs)
+}
+#endif /* FLOATING_POINT */
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method,
+ int num_weights, png_const_fixed_point_p filter_weights,
+ png_const_fixed_point_p filter_costs)
+{
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(heuristic_method)
+ PNG_UNUSED(num_weights)
+ PNG_UNUSED(filter_weights)
+ PNG_UNUSED(filter_costs)
+}
+#endif /* FIXED_POINT */
+#endif /* WRITE_WEIGHTED_FILTER */
+
+#ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
+void PNGAPI
+png_set_compression_level(png_structrp png_ptr, int level)
+{
+ png_debug(1, "in png_set_compression_level");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->zlib_level = level;
+}
+
+void PNGAPI
+png_set_compression_mem_level(png_structrp png_ptr, int mem_level)
+{
+ png_debug(1, "in png_set_compression_mem_level");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->zlib_mem_level = mem_level;
+}
+
+void PNGAPI
+png_set_compression_strategy(png_structrp png_ptr, int strategy)
+{
+ png_debug(1, "in png_set_compression_strategy");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* The flag setting here prevents the libpng dynamic selection of strategy.
+ */
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
+ png_ptr->zlib_strategy = strategy;
+}
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+void PNGAPI
+png_set_compression_window_bits(png_structrp png_ptr, int window_bits)
+{
+ if (png_ptr == NULL)
+ return;
+
+ /* Prior to 1.6.0 this would warn but then set the window_bits value. This
+ * meant that negative window bits values could be selected that would cause
+ * libpng to write a non-standard PNG file with raw deflate or gzip
+ * compressed IDAT or ancillary chunks. Such files can be read and there is
+ * no warning on read, so this seems like a very bad idea.
+ */
+ if (window_bits > 15)
+ {
+ png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+ window_bits = 15;
+ }
+
+ else if (window_bits < 8)
+ {
+ png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+ window_bits = 8;
+ }
+
+ png_ptr->zlib_window_bits = window_bits;
+}
+
+void PNGAPI
+png_set_compression_method(png_structrp png_ptr, int method)
+{
+ png_debug(1, "in png_set_compression_method");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* This would produce an invalid PNG file if it worked, but it doesn't and
+ * deflate will fault it, so it is harmless to just warn here.
+ */
+ if (method != 8)
+ png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+
+ png_ptr->zlib_method = method;
+}
+#endif /* WRITE_CUSTOMIZE_COMPRESSION */
+
+/* The following were added to libpng-1.5.4 */
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+void PNGAPI
+png_set_text_compression_level(png_structrp png_ptr, int level)
+{
+ png_debug(1, "in png_set_text_compression_level");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->zlib_text_level = level;
+}
+
+void PNGAPI
+png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level)
+{
+ png_debug(1, "in png_set_text_compression_mem_level");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->zlib_text_mem_level = mem_level;
+}
+
+void PNGAPI
+png_set_text_compression_strategy(png_structrp png_ptr, int strategy)
+{
+ png_debug(1, "in png_set_text_compression_strategy");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->zlib_text_strategy = strategy;
+}
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+void PNGAPI
+png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits)
+{
+ if (png_ptr == NULL)
+ return;
+
+ if (window_bits > 15)
+ {
+ png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+ window_bits = 15;
+ }
+
+ else if (window_bits < 8)
+ {
+ png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+ window_bits = 8;
+ }
+
+ png_ptr->zlib_text_window_bits = window_bits;
+}
+
+void PNGAPI
+png_set_text_compression_method(png_structrp png_ptr, int method)
+{
+ png_debug(1, "in png_set_text_compression_method");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (method != 8)
+ png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+
+ png_ptr->zlib_text_method = method;
+}
+#endif /* WRITE_CUSTOMIZE_ZTXT_COMPRESSION */
+/* end of API added to libpng-1.5.4 */
+
+void PNGAPI
+png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->write_row_fn = write_row_fn;
+}
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+void PNGAPI
+png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
+ write_user_transform_fn)
+{
+ png_debug(1, "in png_set_write_user_transform_fn");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_USER_TRANSFORM;
+ png_ptr->write_user_transform_fn = write_user_transform_fn;
+}
+#endif
+
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_write_png(png_structrp png_ptr, png_inforp info_ptr,
+ int transforms, voidp params)
+{
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if ((info_ptr->valid & PNG_INFO_IDAT) == 0)
+ {
+ png_app_error(png_ptr, "no rows for png_write_image to write");
+ return;
+ }
+
+ /* Write the file header information. */
+ png_write_info(png_ptr, info_ptr);
+
+ /* ------ these transformations don't touch the info structure ------- */
+
+ /* Invert monochrome pixels */
+ if ((transforms & PNG_TRANSFORM_INVERT_MONO) != 0)
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+ png_set_invert_mono(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_MONO not supported");
+#endif
+
+ /* Shift the pixels up to a legal bit depth and fill in
+ * as appropriate to correctly scale the image.
+ */
+ if ((transforms & PNG_TRANSFORM_SHIFT) != 0)
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+ if ((info_ptr->valid & PNG_INFO_sBIT) != 0)
+ png_set_shift(png_ptr, &info_ptr->sig_bit);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SHIFT not supported");
+#endif
+
+ /* Pack pixels into bytes */
+ if ((transforms & PNG_TRANSFORM_PACKING) != 0)
+#ifdef PNG_WRITE_PACK_SUPPORTED
+ png_set_packing(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKING not supported");
+#endif
+
+ /* Swap location of alpha bytes from ARGB to RGBA */
+ if ((transforms & PNG_TRANSFORM_SWAP_ALPHA) != 0)
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+ png_set_swap_alpha(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ALPHA not supported");
+#endif
+
+ /* Remove a filler (X) from XRGB/RGBX/AG/GA into to convert it into
+ * RGB, note that the code expects the input color type to be G or RGB; no
+ * alpha channel.
+ */
+ if ((transforms & (PNG_TRANSFORM_STRIP_FILLER_AFTER|
+ PNG_TRANSFORM_STRIP_FILLER_BEFORE)) != 0)
+ {
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+ if ((transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) != 0)
+ {
+ if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)
+ png_app_error(png_ptr,
+ "PNG_TRANSFORM_STRIP_FILLER: BEFORE+AFTER not supported");
+
+ /* Continue if ignored - this is the pre-1.6.10 behavior */
+ png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
+ }
+
+ else if ((transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) != 0)
+ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_STRIP_FILLER not supported");
+#endif
+ }
+
+ /* Flip BGR pixels to RGB */
+ if ((transforms & PNG_TRANSFORM_BGR) != 0)
+#ifdef PNG_WRITE_BGR_SUPPORTED
+ png_set_bgr(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_BGR not supported");
+#endif
+
+ /* Swap bytes of 16-bit files to most significant byte first */
+ if ((transforms & PNG_TRANSFORM_SWAP_ENDIAN) != 0)
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+ png_set_swap(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_SWAP_ENDIAN not supported");
+#endif
+
+ /* Swap bits of 1-bit, 2-bit, 4-bit packed pixel formats */
+ if ((transforms & PNG_TRANSFORM_PACKSWAP) != 0)
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+ png_set_packswap(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_PACKSWAP not supported");
+#endif
+
+ /* Invert the alpha channel from opacity to transparency */
+ if ((transforms & PNG_TRANSFORM_INVERT_ALPHA) != 0)
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+ png_set_invert_alpha(png_ptr);
+#else
+ png_app_error(png_ptr, "PNG_TRANSFORM_INVERT_ALPHA not supported");
+#endif
+
+ /* ----------------------- end of transformations ------------------- */
+
+ /* Write the bits */
+ png_write_image(png_ptr, info_ptr->row_pointers);
+
+ /* It is REQUIRED to call this to finish writing the rest of the file */
+ png_write_end(png_ptr, info_ptr);
+
+ PNG_UNUSED(params)
+}
+#endif
+
+
+#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
+/* Initialize the write structure - general purpose utility. */
+static int
+png_image_write_init(png_imagep image)
+{
+ png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image,
+ png_safe_error, png_safe_warning);
+
+ if (png_ptr != NULL)
+ {
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+
+ if (info_ptr != NULL)
+ {
+ png_controlp control = png_voidcast(png_controlp,
+ png_malloc_warn(png_ptr, (sizeof *control)));
+
+ if (control != NULL)
+ {
+ memset(control, 0, (sizeof *control));
+
+ control->png_ptr = png_ptr;
+ control->info_ptr = info_ptr;
+ control->for_write = 1;
+
+ image->opaque = control;
+ return 1;
+ }
+
+ /* Error clean up */
+ png_destroy_info_struct(png_ptr, &info_ptr);
+ }
+
+ png_destroy_write_struct(&png_ptr, NULL);
+ }
+
+ return png_image_error(image, "png_image_write_: out of memory");
+}
+
+/* Arguments to png_image_write_main: */
+typedef struct
+{
+ /* Arguments: */
+ png_imagep image;
+ png_const_voidp buffer;
+ png_int_32 row_stride;
+ png_const_voidp colormap;
+ int convert_to_8bit;
+ /* Local variables: */
+ png_const_voidp first_row;
+ ptrdiff_t row_bytes;
+ png_voidp local_row;
+ /* Byte count for memory writing */
+ png_bytep memory;
+ png_alloc_size_t memory_bytes; /* not used for STDIO */
+ png_alloc_size_t output_bytes; /* running total */
+} png_image_write_control;
+
+/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to
+ * do any necessary byte swapping. The component order is defined by the
+ * png_image format value.
+ */
+static int
+png_write_image_16bit(png_voidp argument)
+{
+ png_image_write_control *display = png_voidcast(png_image_write_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+
+ png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
+ display->first_row);
+ png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
+ png_uint_16p row_end;
+ const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
+ 3 : 1;
+ int aindex = 0;
+ png_uint_32 y = image->height;
+
+ if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ {
+# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+ if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
+ {
+ aindex = -1;
+ ++input_row; /* To point to the first component */
+ ++output_row;
+ }
+ else
+ aindex = (int)channels;
+# else
+ aindex = (int)channels;
+# endif
+ }
+
+ else
+ png_error(png_ptr, "png_write_image: internal call error");
+
+ /* Work out the output row end and count over this, note that the increment
+ * above to 'row' means that row_end can actually be beyond the end of the
+ * row; this is correct.
+ */
+ row_end = output_row + image->width * (channels+1);
+
+ for (; y > 0; --y)
+ {
+ png_const_uint_16p in_ptr = input_row;
+ png_uint_16p out_ptr = output_row;
+
+ while (out_ptr < row_end)
+ {
+ const png_uint_16 alpha = in_ptr[aindex];
+ png_uint_32 reciprocal = 0;
+ int c;
+
+ out_ptr[aindex] = alpha;
+
+ /* Calculate a reciprocal. The correct calculation is simply
+ * component/alpha*65535 << 15. (I.e. 15 bits of precision); this
+ * allows correct rounding by adding .5 before the shift. 'reciprocal'
+ * is only initialized when required.
+ */
+ if (alpha > 0 && alpha < 65535)
+ reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;
+
+ c = (int)channels;
+ do /* always at least one channel */
+ {
+ png_uint_16 component = *in_ptr++;
+
+ /* The following gives 65535 for an alpha of 0, which is fine,
+ * otherwise if 0/0 is represented as some other value there is more
+ * likely to be a discontinuity which will probably damage
+ * compression when moving from a fully transparent area to a
+ * nearly transparent one. (The assumption here is that opaque
+ * areas tend not to be 0 intensity.)
+ */
+ if (component >= alpha)
+ component = 65535;
+
+ /* component<alpha, so component/alpha is less than one and
+ * component*reciprocal is less than 2^31.
+ */
+ else if (component > 0 && alpha < 65535)
+ {
+ png_uint_32 calc = component * reciprocal;
+ calc += 16384; /* round to nearest */
+ component = (png_uint_16)(calc >> 15);
+ }
+
+ *out_ptr++ = component;
+ }
+ while (--c > 0);
+
+ /* Skip to next component (skip the intervening alpha channel) */
+ ++in_ptr;
+ ++out_ptr;
+ }
+
+ png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));
+ input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
+ }
+
+ return 1;
+}
+
+/* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel
+ * is present it must be removed from the components, the components are then
+ * written in sRGB encoding. No components are added or removed.
+ *
+ * Calculate an alpha reciprocal to reverse pre-multiplication. As above the
+ * calculation can be done to 15 bits of accuracy; however, the output needs to
+ * be scaled in the range 0..255*65535, so include that scaling here.
+ */
+# define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
+
+static png_byte
+png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
+ png_uint_32 reciprocal/*from the above macro*/)
+{
+ /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
+ * is represented as some other value there is more likely to be a
+ * discontinuity which will probably damage compression when moving from a
+ * fully transparent area to a nearly transparent one. (The assumption here
+ * is that opaque areas tend not to be 0 intensity.)
+ *
+ * There is a rounding problem here; if alpha is less than 128 it will end up
+ * as 0 when scaled to 8 bits. To avoid introducing spurious colors into the
+ * output change for this too.
+ */
+ if (component >= alpha || alpha < 128)
+ return 255;
+
+ /* component<alpha, so component/alpha is less than one and
+ * component*reciprocal is less than 2^31.
+ */
+ else if (component > 0)
+ {
+ /* The test is that alpha/257 (rounded) is less than 255, the first value
+ * that becomes 255 is 65407.
+ * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore,
+ * be exact!) [Could also test reciprocal != 0]
+ */
+ if (alpha < 65407)
+ {
+ component *= reciprocal;
+ component += 64; /* round to nearest */
+ component >>= 7;
+ }
+
+ else
+ component *= 255;
+
+ /* Convert the component to sRGB. */
+ return (png_byte)PNG_sRGB_FROM_LINEAR(component);
+ }
+
+ else
+ return 0;
+}
+
+static int
+png_write_image_8bit(png_voidp argument)
+{
+ png_image_write_control *display = png_voidcast(png_image_write_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+
+ png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
+ display->first_row);
+ png_bytep output_row = png_voidcast(png_bytep, display->local_row);
+ png_uint_32 y = image->height;
+ const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ?
+ 3 : 1;
+
+ if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ {
+ png_bytep row_end;
+ int aindex;
+
+# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+ if ((image->format & PNG_FORMAT_FLAG_AFIRST) != 0)
+ {
+ aindex = -1;
+ ++input_row; /* To point to the first component */
+ ++output_row;
+ }
+
+ else
+# endif
+ aindex = (int)channels;
+
+ /* Use row_end in place of a loop counter: */
+ row_end = output_row + image->width * (channels+1);
+
+ for (; y > 0; --y)
+ {
+ png_const_uint_16p in_ptr = input_row;
+ png_bytep out_ptr = output_row;
+
+ while (out_ptr < row_end)
+ {
+ png_uint_16 alpha = in_ptr[aindex];
+ png_byte alphabyte = (png_byte)PNG_DIV257(alpha);
+ png_uint_32 reciprocal = 0;
+ int c;
+
+ /* Scale and write the alpha channel. */
+ out_ptr[aindex] = alphabyte;
+
+ if (alphabyte > 0 && alphabyte < 255)
+ reciprocal = UNP_RECIPROCAL(alpha);
+
+ c = (int)channels;
+ do /* always at least one channel */
+ *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
+ while (--c > 0);
+
+ /* Skip to next component (skip the intervening alpha channel) */
+ ++in_ptr;
+ ++out_ptr;
+ } /* while out_ptr < row_end */
+
+ png_write_row(png_ptr, png_voidcast(png_const_bytep,
+ display->local_row));
+ input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
+ } /* while y */
+ }
+
+ else
+ {
+ /* No alpha channel, so the row_end really is the end of the row and it
+ * is sufficient to loop over the components one by one.
+ */
+ png_bytep row_end = output_row + image->width * channels;
+
+ for (; y > 0; --y)
+ {
+ png_const_uint_16p in_ptr = input_row;
+ png_bytep out_ptr = output_row;
+
+ while (out_ptr < row_end)
+ {
+ png_uint_32 component = *in_ptr++;
+
+ component *= 255;
+ *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component);
+ }
+
+ png_write_row(png_ptr, output_row);
+ input_row += (png_uint_16)display->row_bytes/(sizeof (png_uint_16));
+ }
+ }
+
+ return 1;
+}
+
+static void
+png_image_set_PLTE(png_image_write_control *display)
+{
+ const png_imagep image = display->image;
+ const void *cmap = display->colormap;
+ const int entries = image->colormap_entries > 256 ? 256 :
+ (int)image->colormap_entries;
+
+ /* NOTE: the caller must check for cmap != NULL and entries != 0 */
+ const png_uint_32 format = image->format;
+ const unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
+
+# if defined(PNG_FORMAT_BGR_SUPPORTED) &&\
+ defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED)
+ const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
+ (format & PNG_FORMAT_FLAG_ALPHA) != 0;
+# else
+# define afirst 0
+# endif
+
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0;
+# else
+# define bgr 0
+# endif
+
+ int i, num_trans;
+ png_color palette[256];
+ png_byte tRNS[256];
+
+ memset(tRNS, 255, (sizeof tRNS));
+ memset(palette, 0, (sizeof palette));
+
+ for (i=num_trans=0; i<entries; ++i)
+ {
+ /* This gets automatically converted to sRGB with reversal of the
+ * pre-multiplication if the color-map has an alpha channel.
+ */
+ if ((format & PNG_FORMAT_FLAG_LINEAR) != 0)
+ {
+ png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
+
+ entry += (unsigned int)i * channels;
+
+ if ((channels & 1) != 0) /* no alpha */
+ {
+ if (channels >= 3) /* RGB */
+ {
+ palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
+ entry[(2 ^ bgr)]);
+ palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
+ entry[1]);
+ palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
+ entry[bgr]);
+ }
+
+ else /* Gray */
+ palette[i].blue = palette[i].red = palette[i].green =
+ (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry);
+ }
+
+ else /* alpha */
+ {
+ png_uint_16 alpha = entry[afirst ? 0 : channels-1];
+ png_byte alphabyte = (png_byte)PNG_DIV257(alpha);
+ png_uint_32 reciprocal = 0;
+
+ /* Calculate a reciprocal, as in the png_write_image_8bit code above
+ * this is designed to produce a value scaled to 255*65535 when
+ * divided by 128 (i.e. asr 7).
+ */
+ if (alphabyte > 0 && alphabyte < 255)
+ reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha;
+
+ tRNS[i] = alphabyte;
+ if (alphabyte < 255)
+ num_trans = i+1;
+
+ if (channels >= 3) /* RGB */
+ {
+ palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
+ alpha, reciprocal);
+ palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
+ reciprocal);
+ palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
+ reciprocal);
+ }
+
+ else /* gray */
+ palette[i].blue = palette[i].red = palette[i].green =
+ png_unpremultiply(entry[afirst], alpha, reciprocal);
+ }
+ }
+
+ else /* Color-map has sRGB values */
+ {
+ png_const_bytep entry = png_voidcast(png_const_bytep, cmap);
+
+ entry += (unsigned int)i * channels;
+
+ switch (channels)
+ {
+ case 4:
+ tRNS[i] = entry[afirst ? 0 : 3];
+ if (tRNS[i] < 255)
+ num_trans = i+1;
+ /* FALLTHROUGH */
+ case 3:
+ palette[i].blue = entry[afirst + (2 ^ bgr)];
+ palette[i].green = entry[afirst + 1];
+ palette[i].red = entry[afirst + bgr];
+ break;
+
+ case 2:
+ tRNS[i] = entry[1 ^ afirst];
+ if (tRNS[i] < 255)
+ num_trans = i+1;
+ /* FALLTHROUGH */
+ case 1:
+ palette[i].blue = palette[i].red = palette[i].green =
+ entry[afirst];
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+# ifdef afirst
+# undef afirst
+# endif
+# ifdef bgr
+# undef bgr
+# endif
+
+ png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
+ entries);
+
+ if (num_trans > 0)
+ png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
+ num_trans, NULL);
+
+ image->colormap_entries = (png_uint_32)entries;
+}
+
+static int
+png_image_write_main(png_voidp argument)
+{
+ png_image_write_control *display = png_voidcast(png_image_write_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+ png_inforp info_ptr = image->opaque->info_ptr;
+ png_uint_32 format = image->format;
+
+ /* The following four ints are actually booleans */
+ int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
+ int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
+ int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
+ int write_16bit = linear && (display->convert_to_8bit == 0);
+
+# ifdef PNG_BENIGN_ERRORS_SUPPORTED
+ /* Make sure we error out on any bad situation */
+ png_set_benign_errors(png_ptr, 0/*error*/);
+# endif
+
+ /* Default the 'row_stride' parameter if required, also check the row stride
+ * and total image size to ensure that they are within the system limits.
+ */
+ {
+ const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format);
+
+ if (image->width <= 0x7fffffffU/channels) /* no overflow */
+ {
+ png_uint_32 check;
+ const png_uint_32 png_row_stride = image->width * channels;
+
+ if (display->row_stride == 0)
+ display->row_stride = (png_int_32)/*SAFE*/png_row_stride;
+
+ if (display->row_stride < 0)
+ check = (png_uint_32)(-display->row_stride);
+
+ else
+ check = (png_uint_32)display->row_stride;
+
+ if (check >= png_row_stride)
+ {
+ /* Now check for overflow of the image buffer calculation; this
+ * limits the whole image size to 32 bits for API compatibility with
+ * the current, 32-bit, PNG_IMAGE_BUFFER_SIZE macro.
+ */
+ if (image->height > 0xffffffffU/png_row_stride)
+ png_error(image->opaque->png_ptr, "memory image too large");
+ }
+
+ else
+ png_error(image->opaque->png_ptr, "supplied row stride too small");
+ }
+
+ else
+ png_error(image->opaque->png_ptr, "image row stride too large");
+ }
+
+ /* Set the required transforms then write the rows in the correct order. */
+ if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0)
+ {
+ if (display->colormap != NULL && image->colormap_entries > 0)
+ {
+ png_uint_32 entries = image->colormap_entries;
+
+ png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
+ entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
+ PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ png_image_set_PLTE(display);
+ }
+
+ else
+ png_error(image->opaque->png_ptr,
+ "no color-map for color-mapped image");
+ }
+
+ else
+ png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
+ write_16bit ? 16 : 8,
+ ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
+ ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ /* Counter-intuitively the data transformations must be called *after*
+ * png_write_info, not before as in the read code, but the 'set' functions
+ * must still be called before. Just set the color space information, never
+ * write an interlaced image.
+ */
+
+ if (write_16bit != 0)
+ {
+ /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */
+ png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR);
+
+ if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
+ png_set_cHRM_fixed(png_ptr, info_ptr,
+ /* color x y */
+ /* white */ 31270, 32900,
+ /* red */ 64000, 33000,
+ /* green */ 30000, 60000,
+ /* blue */ 15000, 6000
+ );
+ }
+
+ else if ((image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB) == 0)
+ png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
+
+ /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit
+ * space must still be gamma encoded.
+ */
+ else
+ png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
+
+ /* Write the file header. */
+ png_write_info(png_ptr, info_ptr);
+
+ /* Now set up the data transformations (*after* the header is written),
+ * remove the handled transformations from the 'format' flags for checking.
+ *
+ * First check for a little endian system if writing 16-bit files.
+ */
+ if (write_16bit != 0)
+ {
+ PNG_CONST png_uint_16 le = 0x0001;
+
+ if ((*(png_const_bytep) & le) != 0)
+ png_set_swap(png_ptr);
+ }
+
+# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+ if ((format & PNG_FORMAT_FLAG_BGR) != 0)
+ {
+ if (colormap == 0 && (format & PNG_FORMAT_FLAG_COLOR) != 0)
+ png_set_bgr(png_ptr);
+ format &= ~PNG_FORMAT_FLAG_BGR;
+ }
+# endif
+
+# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+ if ((format & PNG_FORMAT_FLAG_AFIRST) != 0)
+ {
+ if (colormap == 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ png_set_swap_alpha(png_ptr);
+ format &= ~PNG_FORMAT_FLAG_AFIRST;
+ }
+# endif
+
+ /* If there are 16 or fewer color-map entries we wrote a lower bit depth
+ * above, but the application data is still byte packed.
+ */
+ if (colormap != 0 && image->colormap_entries <= 16)
+ png_set_packing(png_ptr);
+
+ /* That should have handled all (both) the transforms. */
+ if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |
+ PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0)
+ png_error(png_ptr, "png_write_image: unsupported transformation");
+
+ {
+ png_const_bytep row = png_voidcast(png_const_bytep, display->buffer);
+ ptrdiff_t row_bytes = display->row_stride;
+
+ if (linear != 0)
+ row_bytes *= (sizeof (png_uint_16));
+
+ if (row_bytes < 0)
+ row += (image->height-1) * (-row_bytes);
+
+ display->first_row = row;
+ display->row_bytes = row_bytes;
+ }
+
+ /* Apply 'fast' options if the flag is set. */
+ if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0)
+ {
+ png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS);
+ /* NOTE: determined by experiment using pngstest, this reflects some
+ * balance between the time to write the image once and the time to read
+ * it about 50 times. The speed-up in pngstest was about 10-20% of the
+ * total (user) time on a heavily loaded system.
+ */
+# ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
+ png_set_compression_level(png_ptr, 3);
+# endif
+ }
+
+ /* Check for the cases that currently require a pre-transform on the row
+ * before it is written. This only applies when the input is 16-bit and
+ * either there is an alpha channel or it is converted to 8-bit.
+ */
+ if ((linear != 0 && alpha != 0 ) ||
+ (colormap == 0 && display->convert_to_8bit != 0))
+ {
+ png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
+ png_get_rowbytes(png_ptr, info_ptr)));
+ int result;
+
+ display->local_row = row;
+ if (write_16bit != 0)
+ result = png_safe_execute(image, png_write_image_16bit, display);
+ else
+ result = png_safe_execute(image, png_write_image_8bit, display);
+ display->local_row = NULL;
+
+ png_free(png_ptr, row);
+
+ /* Skip the 'write_end' on error: */
+ if (result == 0)
+ return 0;
+ }
+
+ /* Otherwise this is the case where the input is in a format currently
+ * supported by the rest of the libpng write code; call it directly.
+ */
+ else
+ {
+ png_const_bytep row = png_voidcast(png_const_bytep, display->first_row);
+ ptrdiff_t row_bytes = display->row_bytes;
+ png_uint_32 y = image->height;
+
+ for (; y > 0; --y)
+ {
+ png_write_row(png_ptr, row);
+ row += row_bytes;
+ }
+ }
+
+ png_write_end(png_ptr, info_ptr);
+ return 1;
+}
+
+
+static void (PNGCBAPI
+image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data,
+ png_size_t size)
+{
+ png_image_write_control *display = png_voidcast(png_image_write_control*,
+ png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/);
+ const png_alloc_size_t ob = display->output_bytes;
+
+ /* Check for overflow; this should never happen: */
+ if (size <= ((png_alloc_size_t)-1) - ob)
+ {
+ /* I don't think libpng ever does this, but just in case: */
+ if (size > 0)
+ {
+ if (display->memory_bytes >= ob+size) /* writing */
+ memcpy(display->memory+ob, data, size);
+
+ /* Always update the size: */
+ display->output_bytes = ob+size;
+ }
+ }
+
+ else
+ png_error(png_ptr, "png_image_write_to_memory: PNG too big");
+}
+
+static void (PNGCBAPI
+image_memory_flush)(png_structp png_ptr)
+{
+ PNG_UNUSED(png_ptr)
+}
+
+static int
+png_image_write_memory(png_voidp argument)
+{
+ png_image_write_control *display = png_voidcast(png_image_write_control*,
+ argument);
+
+ /* The rest of the memory-specific init and write_main in an error protected
+ * environment. This case needs to use callbacks for the write operations
+ * since libpng has no built in support for writing to memory.
+ */
+ png_set_write_fn(display->image->opaque->png_ptr, display/*io_ptr*/,
+ image_memory_write, image_memory_flush);
+
+ return png_image_write_main(display);
+}
+
+int PNGAPI
+png_image_write_to_memory(png_imagep image, void *memory,
+ png_alloc_size_t * PNG_RESTRICT memory_bytes, int convert_to_8bit,
+ const void *buffer, png_int_32 row_stride, const void *colormap)
+{
+ /* Write the image to the given buffer, or count the bytes if it is NULL */
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (memory_bytes != NULL && buffer != NULL)
+ {
+ /* This is to give the caller an easier error detection in the NULL
+ * case and guard against uninitialized variable problems:
+ */
+ if (memory == NULL)
+ *memory_bytes = 0;
+
+ if (png_image_write_init(image) != 0)
+ {
+ png_image_write_control display;
+ int result;
+
+ memset(&display, 0, (sizeof display));
+ display.image = image;
+ display.buffer = buffer;
+ display.row_stride = row_stride;
+ display.colormap = colormap;
+ display.convert_to_8bit = convert_to_8bit;
+ display.memory = png_voidcast(png_bytep, memory);
+ display.memory_bytes = *memory_bytes;
+ display.output_bytes = 0;
+
+ result = png_safe_execute(image, png_image_write_memory, &display);
+ png_image_free(image);
+
+ /* write_memory returns true even if we ran out of buffer. */
+ if (result)
+ {
+ /* On out-of-buffer this function returns '0' but still updates
+ * memory_bytes:
+ */
+ if (memory != NULL && display.output_bytes > *memory_bytes)
+ result = 0;
+
+ *memory_bytes = display.output_bytes;
+ }
+
+ return result;
+ }
+
+ else
+ return 0;
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_write_to_memory: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_write_to_memory: incorrect PNG_IMAGE_VERSION");
+
+ else
+ return 0;
+}
+
+#ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
+int PNGAPI
+png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
+ const void *buffer, png_int_32 row_stride, const void *colormap)
+{
+ /* Write the image to the given (FILE*). */
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (file != NULL && buffer != NULL)
+ {
+ if (png_image_write_init(image) != 0)
+ {
+ png_image_write_control display;
+ int result;
+
+ /* This is slightly evil, but png_init_io doesn't do anything other
+ * than this and we haven't changed the standard IO functions so
+ * this saves a 'safe' function.
+ */
+ image->opaque->png_ptr->io_ptr = file;
+
+ memset(&display, 0, (sizeof display));
+ display.image = image;
+ display.buffer = buffer;
+ display.row_stride = row_stride;
+ display.colormap = colormap;
+ display.convert_to_8bit = convert_to_8bit;
+
+ result = png_safe_execute(image, png_image_write_main, &display);
+ png_image_free(image);
+ return result;
+ }
+
+ else
+ return 0;
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_write_to_stdio: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
+
+ else
+ return 0;
+}
+
+int PNGAPI
+png_image_write_to_file(png_imagep image, const char *file_name,
+ int convert_to_8bit, const void *buffer, png_int_32 row_stride,
+ const void *colormap)
+{
+ /* Write the image to the named file. */
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (file_name != NULL && buffer != NULL)
+ {
+ FILE *fp = fopen(file_name, "wb");
+
+ if (fp != NULL)
+ {
+ if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
+ row_stride, colormap) != 0)
+ {
+ int error; /* from fflush/fclose */
+
+ /* Make sure the file is flushed correctly. */
+ if (fflush(fp) == 0 && ferror(fp) == 0)
+ {
+ if (fclose(fp) == 0)
+ return 1;
+
+ error = errno; /* from fclose */
+ }
+
+ else
+ {
+ error = errno; /* from fflush or ferror */
+ (void)fclose(fp);
+ }
+
+ (void)remove(file_name);
+ /* The image has already been cleaned up; this is just used to
+ * set the error (because the original write succeeded).
+ */
+ return png_image_error(image, strerror(error));
+ }
+
+ else
+ {
+ /* Clean up: just the opened file. */
+ (void)fclose(fp);
+ (void)remove(file_name);
+ return 0;
+ }
+ }
+
+ else
+ return png_image_error(image, strerror(errno));
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_write_to_file: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
+
+ else
+ return 0;
+}
+#endif /* SIMPLIFIED_WRITE_STDIO */
+#endif /* SIMPLIFIED_WRITE */
+#endif /* WRITE */
diff --git a/xs/src/png/libpng/pngwtran.c b/xs/src/png/libpng/pngwtran.c
new file mode 100644
index 000000000..377b43e5c
--- /dev/null
+++ b/xs/src/png/libpng/pngwtran.c
@@ -0,0 +1,576 @@
+
+/* pngwtran.c - transforms the data in a row for PNG writers
+ *
+ * Last changed in libpng 1.6.26 [October 20, 2016]
+ * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
+ * row_info bit depth should be 8 (one pixel per byte). The channels
+ * should be 1 (this only happens on grayscale and paletted images).
+ */
+static void
+png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
+{
+ png_debug(1, "in png_do_pack");
+
+ if (row_info->bit_depth == 8 &&
+ row_info->channels == 1)
+ {
+ switch ((int)bit_depth)
+ {
+ case 1:
+ {
+ png_bytep sp, dp;
+ int mask, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ mask = 0x80;
+ v = 0;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (*sp != 0)
+ v |= mask;
+
+ sp++;
+
+ if (mask > 1)
+ mask >>= 1;
+
+ else
+ {
+ mask = 0x80;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+ }
+
+ if (mask != 0x80)
+ *dp = (png_byte)v;
+
+ break;
+ }
+
+ case 2:
+ {
+ png_bytep sp, dp;
+ unsigned int shift;
+ int v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ shift = 6;
+ v = 0;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte value;
+
+ value = (png_byte)(*sp & 0x03);
+ v |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 6;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+
+ else
+ shift -= 2;
+
+ sp++;
+ }
+
+ if (shift != 6)
+ *dp = (png_byte)v;
+
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp, dp;
+ unsigned int shift;
+ int v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ shift = 4;
+ v = 0;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte value;
+
+ value = (png_byte)(*sp & 0x0f);
+ v |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 4;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+
+ else
+ shift -= 4;
+
+ sp++;
+ }
+
+ if (shift != 4)
+ *dp = (png_byte)v;
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ row_info->bit_depth = (png_byte)bit_depth;
+ row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_info->width);
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+/* Shift pixel values to take advantage of whole range. Pass the
+ * true number of bits in bit_depth. The row should be packed
+ * according to row_info->bit_depth. Thus, if you had a row of
+ * bit depth 4, but the pixels only had values from 0 to 7, you
+ * would pass 3 as bit_depth, and this routine would translate the
+ * data to 0 to 15.
+ */
+static void
+png_do_shift(png_row_infop row_info, png_bytep row,
+ png_const_color_8p bit_depth)
+{
+ png_debug(1, "in png_do_shift");
+
+ if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ int shift_start[4], shift_dec[4];
+ unsigned int channels = 0;
+
+ if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->red;
+ shift_dec[channels] = bit_depth->red;
+ channels++;
+
+ shift_start[channels] = row_info->bit_depth - bit_depth->green;
+ shift_dec[channels] = bit_depth->green;
+ channels++;
+
+ shift_start[channels] = row_info->bit_depth - bit_depth->blue;
+ shift_dec[channels] = bit_depth->blue;
+ channels++;
+ }
+
+ else
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->gray;
+ shift_dec[channels] = bit_depth->gray;
+ channels++;
+ }
+
+ if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
+ shift_dec[channels] = bit_depth->alpha;
+ channels++;
+ }
+
+ /* With low row depths, could only be grayscale, so one channel */
+ if (row_info->bit_depth < 8)
+ {
+ png_bytep bp = row;
+ png_size_t i;
+ unsigned int mask;
+ png_size_t row_bytes = row_info->rowbytes;
+
+ if (bit_depth->gray == 1 && row_info->bit_depth == 2)
+ mask = 0x55;
+
+ else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
+ mask = 0x11;
+
+ else
+ mask = 0xff;
+
+ for (i = 0; i < row_bytes; i++, bp++)
+ {
+ int j;
+ unsigned int v, out;
+
+ v = *bp;
+ out = 0;
+
+ for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
+ {
+ if (j > 0)
+ out |= v << j;
+
+ else
+ out |= (v >> (-j)) & mask;
+ }
+
+ *bp = (png_byte)(out & 0xff);
+ }
+ }
+
+ else if (row_info->bit_depth == 8)
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_info->width;
+
+ for (i = 0; i < istop; i++, bp++)
+ {
+
+ const unsigned int c = i%channels;
+ int j;
+ unsigned int v, out;
+
+ v = *bp;
+ out = 0;
+
+ for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+ {
+ if (j > 0)
+ out |= v << j;
+
+ else
+ out |= v >> (-j);
+ }
+
+ *bp = (png_byte)(out & 0xff);
+ }
+ }
+
+ else
+ {
+ png_bytep bp;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_info->width;
+
+ for (bp = row, i = 0; i < istop; i++)
+ {
+ const unsigned int c = i%channels;
+ int j;
+ unsigned int value, v;
+
+ v = png_get_uint_16(bp);
+ value = 0;
+
+ for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+ {
+ if (j > 0)
+ value |= v << j;
+
+ else
+ value |= v >> (-j);
+ }
+ *bp++ = (png_byte)((value >> 8) & 0xff);
+ *bp++ = (png_byte)(value & 0xff);
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+static void
+png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_swap_alpha");
+
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This converts from ARGB to RGBA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save;
+ }
+ }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ else
+ {
+ /* This converts from AARRGGBB to RRGGBBAA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save[2];
+ save[0] = *(sp++);
+ save[1] = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save[0];
+ *(dp++) = save[1];
+ }
+ }
+#endif /* WRITE_16BIT */
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This converts from AG to GA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save;
+ }
+ }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ else
+ {
+ /* This converts from AAGG to GGAA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save[2];
+ save[0] = *(sp++);
+ save[1] = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save[0];
+ *(dp++) = save[1];
+ }
+ }
+#endif /* WRITE_16BIT */
+ }
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+static void
+png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_invert_alpha");
+
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This inverts the alpha channel in RGBA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* Does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=3; dp = sp;
+ *dp = (png_byte)(255 - *(sp++));
+ }
+ }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ else
+ {
+ /* This inverts the alpha channel in RRGGBBAA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* Does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=6; dp = sp;
+ *(dp++) = (png_byte)(255 - *(sp++));
+ *dp = (png_byte)(255 - *(sp++));
+ }
+ }
+#endif /* WRITE_16BIT */
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This inverts the alpha channel in GA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ else
+ {
+ /* This inverts the alpha channel in GGAA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* Does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=2; dp = sp;
+ *(dp++) = (png_byte)(255 - *(sp++));
+ *dp = (png_byte)(255 - *(sp++));
+ }
+ }
+#endif /* WRITE_16BIT */
+ }
+ }
+}
+#endif
+
+/* Transform the data according to the user's wishes. The order of
+ * transformations is significant.
+ */
+void /* PRIVATE */
+png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
+{
+ png_debug(1, "in png_do_write_transformations");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+ if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
+ if (png_ptr->write_user_transform_fn != NULL)
+ (*(png_ptr->write_user_transform_fn)) /* User write transform
+ function */
+ (png_ptr, /* png_ptr */
+ row_info, /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_size_t rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#endif
+
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+ if ((png_ptr->transformations & PNG_FILLER) != 0)
+ png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+ !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
+#endif
+
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
+ png_do_packswap(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACK) != 0)
+ png_do_pack(row_info, png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->bit_depth);
+#endif
+
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+# ifdef PNG_16BIT_SUPPORTED
+ if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
+ png_do_swap(row_info, png_ptr->row_buf + 1);
+# endif
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+ if ((png_ptr->transformations & PNG_SHIFT) != 0)
+ png_do_shift(row_info, png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
+ png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
+ png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_BGR_SUPPORTED
+ if ((png_ptr->transformations & PNG_BGR) != 0)
+ png_do_bgr(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+ if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
+ png_do_invert(row_info, png_ptr->row_buf + 1);
+#endif
+}
+#endif /* WRITE_TRANSFORMS */
+#endif /* WRITE */
diff --git a/xs/src/png/libpng/pngwutil.c b/xs/src/png/libpng/pngwutil.c
new file mode 100644
index 000000000..0d4fb1336
--- /dev/null
+++ b/xs/src/png/libpng/pngwutil.c
@@ -0,0 +1,2784 @@
+
+/* pngwutil.c - utilities to write a PNG file
+ *
+ * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_WRITE_SUPPORTED
+
+#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+/* Place a 32-bit number into a buffer in PNG byte order. We work
+ * with unsigned numbers for convenience, although one supported
+ * ancillary chunk uses signed (two's complement) numbers.
+ */
+void PNGAPI
+png_save_uint_32(png_bytep buf, png_uint_32 i)
+{
+ buf[0] = (png_byte)((i >> 24) & 0xffU);
+ buf[1] = (png_byte)((i >> 16) & 0xffU);
+ buf[2] = (png_byte)((i >> 8) & 0xffU);
+ buf[3] = (png_byte)( i & 0xffU);
+}
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+void PNGAPI
+png_save_uint_16(png_bytep buf, unsigned int i)
+{
+ buf[0] = (png_byte)((i >> 8) & 0xffU);
+ buf[1] = (png_byte)( i & 0xffU);
+}
+#endif
+
+/* Simple function to write the signature. If we have already written
+ * the magic bytes of the signature, or more likely, the PNG stream is
+ * being embedded into another stream and doesn't need its own signature,
+ * we should call png_set_sig_bytes() to tell libpng how many of the
+ * bytes have already been written.
+ */
+void PNGAPI
+png_write_sig(png_structrp png_ptr)
+{
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ /* Inform the I/O callback that the signature is being written */
+ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE;
+#endif
+
+ /* Write the rest of the 8 byte signature */
+ png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
+ (png_size_t)(8 - png_ptr->sig_bytes));
+
+ if (png_ptr->sig_bytes < 3)
+ png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+}
+
+/* Write the start of a PNG chunk. The type is the chunk type.
+ * The total_length is the sum of the lengths of all the data you will be
+ * passing in png_write_chunk_data().
+ */
+static void
+png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name,
+ png_uint_32 length)
+{
+ png_byte buf[8];
+
+#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
+ PNG_CSTRING_FROM_CHUNK(buf, chunk_name);
+ png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length);
+#endif
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ /* Inform the I/O callback that the chunk header is being written.
+ * PNG_IO_CHUNK_HDR requires a single I/O call.
+ */
+ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR;
+#endif
+
+ /* Write the length and the chunk name */
+ png_save_uint_32(buf, length);
+ png_save_uint_32(buf + 4, chunk_name);
+ png_write_data(png_ptr, buf, 8);
+
+ /* Put the chunk name into png_ptr->chunk_name */
+ png_ptr->chunk_name = chunk_name;
+
+ /* Reset the crc and run it over the chunk name */
+ png_reset_crc(png_ptr);
+
+ png_calculate_crc(png_ptr, buf + 4, 4);
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ /* Inform the I/O callback that chunk data will (possibly) be written.
+ * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
+ */
+ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA;
+#endif
+}
+
+void PNGAPI
+png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string,
+ png_uint_32 length)
+{
+ png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length);
+}
+
+/* Write the data of a PNG chunk started with png_write_chunk_header().
+ * Note that multiple calls to this function are allowed, and that the
+ * sum of the lengths from these calls *must* add up to the total_length
+ * given to png_write_chunk_header().
+ */
+void PNGAPI
+png_write_chunk_data(png_structrp png_ptr, png_const_bytep data,
+ png_size_t length)
+{
+ /* Write the data, and run the CRC over it */
+ if (png_ptr == NULL)
+ return;
+
+ if (data != NULL && length > 0)
+ {
+ png_write_data(png_ptr, data, length);
+
+ /* Update the CRC after writing the data,
+ * in case the user I/O routine alters it.
+ */
+ png_calculate_crc(png_ptr, data, length);
+ }
+}
+
+/* Finish a chunk started with png_write_chunk_header(). */
+void PNGAPI
+png_write_chunk_end(png_structrp png_ptr)
+{
+ png_byte buf[4];
+
+ if (png_ptr == NULL) return;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ /* Inform the I/O callback that the chunk CRC is being written.
+ * PNG_IO_CHUNK_CRC requires a single I/O function call.
+ */
+ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC;
+#endif
+
+ /* Write the crc in a single operation */
+ png_save_uint_32(buf, png_ptr->crc);
+
+ png_write_data(png_ptr, buf, (png_size_t)4);
+}
+
+/* Write a PNG chunk all at once. The type is an array of ASCII characters
+ * representing the chunk name. The array must be at least 4 bytes in
+ * length, and does not need to be null terminated. To be safe, pass the
+ * pre-defined chunk names here, and if you need a new one, define it
+ * where the others are defined. The length is the length of the data.
+ * All the data must be present. If that is not possible, use the
+ * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
+ * functions instead.
+ */
+static void
+png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
+ png_const_bytep data, png_size_t length)
+{
+ if (png_ptr == NULL)
+ return;
+
+ /* On 64-bit architectures 'length' may not fit in a png_uint_32. */
+ if (length > PNG_UINT_31_MAX)
+ png_error(png_ptr, "length exceeds PNG maximum");
+
+ png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);
+ png_write_chunk_data(png_ptr, data, length);
+ png_write_chunk_end(png_ptr);
+}
+
+/* This is the API that calls the internal function above. */
+void PNGAPI
+png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
+ png_const_bytep data, png_size_t length)
+{
+ png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
+ length);
+}
+
+/* This is used below to find the size of an image to pass to png_deflate_claim,
+ * so it only needs to be accurate if the size is less than 16384 bytes (the
+ * point at which a lower LZ window size can be used.)
+ */
+static png_alloc_size_t
+png_image_size(png_structrp png_ptr)
+{
+ /* Only return sizes up to the maximum of a png_uint_32; do this by limiting
+ * the width and height used to 15 bits.
+ */
+ png_uint_32 h = png_ptr->height;
+
+ if (png_ptr->rowbytes < 32768 && h < 32768)
+ {
+ if (png_ptr->interlaced != 0)
+ {
+ /* Interlacing makes the image larger because of the replication of
+ * both the filter byte and the padding to a byte boundary.
+ */
+ png_uint_32 w = png_ptr->width;
+ unsigned int pd = png_ptr->pixel_depth;
+ png_alloc_size_t cb_base;
+ int pass;
+
+ for (cb_base=0, pass=0; pass<=6; ++pass)
+ {
+ png_uint_32 pw = PNG_PASS_COLS(w, pass);
+
+ if (pw > 0)
+ cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass);
+ }
+
+ return cb_base;
+ }
+
+ else
+ return (png_ptr->rowbytes+1) * h;
+ }
+
+ else
+ return 0xffffffffU;
+}
+
+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+ /* This is the code to hack the first two bytes of the deflate stream (the
+ * deflate header) to correct the windowBits value to match the actual data
+ * size. Note that the second argument is the *uncompressed* size but the
+ * first argument is the *compressed* data (and it must be deflate
+ * compressed.)
+ */
+static void
+optimize_cmf(png_bytep data, png_alloc_size_t data_size)
+{
+ /* Optimize the CMF field in the zlib stream. The resultant zlib stream is
+ * still compliant to the stream specification.
+ */
+ if (data_size <= 16384) /* else windowBits must be 15 */
+ {
+ unsigned int z_cmf = data[0]; /* zlib compression method and flags */
+
+ if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
+ {
+ unsigned int z_cinfo;
+ unsigned int half_z_window_size;
+
+ z_cinfo = z_cmf >> 4;
+ half_z_window_size = 1U << (z_cinfo + 7);
+
+ if (data_size <= half_z_window_size) /* else no change */
+ {
+ unsigned int tmp;
+
+ do
+ {
+ half_z_window_size >>= 1;
+ --z_cinfo;
+ }
+ while (z_cinfo > 0 && data_size <= half_z_window_size);
+
+ z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
+
+ data[0] = (png_byte)z_cmf;
+ tmp = data[1] & 0xe0;
+ tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
+ data[1] = (png_byte)tmp;
+ }
+ }
+ }
+}
+#endif /* WRITE_OPTIMIZE_CMF */
+
+/* Initialize the compressor for the appropriate type of compression. */
+static int
+png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
+ png_alloc_size_t data_size)
+{
+ if (png_ptr->zowner != 0)
+ {
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
+ char msg[64];
+
+ PNG_STRING_FROM_CHUNK(msg, owner);
+ msg[4] = ':';
+ msg[5] = ' ';
+ PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner);
+ /* So the message that results is "<chunk> using zstream"; this is an
+ * internal error, but is very useful for debugging. i18n requirements
+ * are minimal.
+ */
+ (void)png_safecat(msg, (sizeof msg), 10, " using zstream");
+#endif
+#if PNG_RELEASE_BUILD
+ png_warning(png_ptr, msg);
+
+ /* Attempt sane error recovery */
+ if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */
+ {
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT");
+ return Z_STREAM_ERROR;
+ }
+
+ png_ptr->zowner = 0;
+#else
+ png_error(png_ptr, msg);
+#endif
+ }
+
+ {
+ int level = png_ptr->zlib_level;
+ int method = png_ptr->zlib_method;
+ int windowBits = png_ptr->zlib_window_bits;
+ int memLevel = png_ptr->zlib_mem_level;
+ int strategy; /* set below */
+ int ret; /* zlib return code */
+
+ if (owner == png_IDAT)
+ {
+ if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0)
+ strategy = png_ptr->zlib_strategy;
+
+ else if (png_ptr->do_filter != PNG_FILTER_NONE)
+ strategy = PNG_Z_DEFAULT_STRATEGY;
+
+ else
+ strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY;
+ }
+
+ else
+ {
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+ level = png_ptr->zlib_text_level;
+ method = png_ptr->zlib_text_method;
+ windowBits = png_ptr->zlib_text_window_bits;
+ memLevel = png_ptr->zlib_text_mem_level;
+ strategy = png_ptr->zlib_text_strategy;
+#else
+ /* If customization is not supported the values all come from the
+ * IDAT values except for the strategy, which is fixed to the
+ * default. (This is the pre-1.6.0 behavior too, although it was
+ * implemented in a very different way.)
+ */
+ strategy = Z_DEFAULT_STRATEGY;
+#endif
+ }
+
+ /* Adjust 'windowBits' down if larger than 'data_size'; to stop this
+ * happening just pass 32768 as the data_size parameter. Notice that zlib
+ * requires an extra 262 bytes in the window in addition to the data to be
+ * able to see the whole of the data, so if data_size+262 takes us to the
+ * next windowBits size we need to fix up the value later. (Because even
+ * though deflate needs the extra window, inflate does not!)
+ */
+ if (data_size <= 16384)
+ {
+ /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to
+ * work round a Microsoft Visual C misbehavior which, contrary to C-90,
+ * widens the result of the following shift to 64-bits if (and,
+ * apparently, only if) it is used in a test.
+ */
+ unsigned int half_window_size = 1U << (windowBits-1);
+
+ while (data_size + 262 <= half_window_size)
+ {
+ half_window_size >>= 1;
+ --windowBits;
+ }
+ }
+
+ /* Check against the previous initialized values, if any. */
+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0 &&
+ (png_ptr->zlib_set_level != level ||
+ png_ptr->zlib_set_method != method ||
+ png_ptr->zlib_set_window_bits != windowBits ||
+ png_ptr->zlib_set_mem_level != memLevel ||
+ png_ptr->zlib_set_strategy != strategy))
+ {
+ if (deflateEnd(&png_ptr->zstream) != Z_OK)
+ png_warning(png_ptr, "deflateEnd failed (ignored)");
+
+ png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED;
+ }
+
+ /* For safety clear out the input and output pointers (currently zlib
+ * doesn't use them on Init, but it might in the future).
+ */
+ png_ptr->zstream.next_in = NULL;
+ png_ptr->zstream.avail_in = 0;
+ png_ptr->zstream.next_out = NULL;
+ png_ptr->zstream.avail_out = 0;
+
+ /* Now initialize if required, setting the new parameters, otherwise just
+ * do a simple reset to the previous parameters.
+ */
+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) != 0)
+ ret = deflateReset(&png_ptr->zstream);
+
+ else
+ {
+ ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
+ memLevel, strategy);
+
+ if (ret == Z_OK)
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
+ }
+
+ /* The return code is from either deflateReset or deflateInit2; they have
+ * pretty much the same set of error codes.
+ */
+ if (ret == Z_OK)
+ png_ptr->zowner = owner;
+
+ else
+ png_zstream_error(png_ptr, ret);
+
+ return ret;
+ }
+}
+
+/* Clean up (or trim) a linked list of compression buffers. */
+void /* PRIVATE */
+png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp)
+{
+ png_compression_bufferp list = *listp;
+
+ if (list != NULL)
+ {
+ *listp = NULL;
+
+ do
+ {
+ png_compression_bufferp next = list->next;
+
+ png_free(png_ptr, list);
+ list = next;
+ }
+ while (list != NULL);
+ }
+}
+
+#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
+/* This pair of functions encapsulates the operation of (a) compressing a
+ * text string, and (b) issuing it later as a series of chunk data writes.
+ * The compression_state structure is shared context for these functions
+ * set up by the caller to allow access to the relevant local variables.
+ *
+ * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size
+ * temporary buffers. From 1.6.0 it is retained in png_struct so that it will
+ * be correctly freed in the event of a write error (previous implementations
+ * just leaked memory.)
+ */
+typedef struct
+{
+ png_const_bytep input; /* The uncompressed input data */
+ png_alloc_size_t input_len; /* Its length */
+ png_uint_32 output_len; /* Final compressed length */
+ png_byte output[1024]; /* First block of output */
+} compression_state;
+
+static void
+png_text_compress_init(compression_state *comp, png_const_bytep input,
+ png_alloc_size_t input_len)
+{
+ comp->input = input;
+ comp->input_len = input_len;
+ comp->output_len = 0;
+}
+
+/* Compress the data in the compression state input */
+static int
+png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
+ compression_state *comp, png_uint_32 prefix_len)
+{
+ int ret;
+
+ /* To find the length of the output it is necessary to first compress the
+ * input. The result is buffered rather than using the two-pass algorithm
+ * that is used on the inflate side; deflate is assumed to be slower and a
+ * PNG writer is assumed to have more memory available than a PNG reader.
+ *
+ * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an
+ * upper limit on the output size, but it is always bigger than the input
+ * size so it is likely to be more efficient to use this linked-list
+ * approach.
+ */
+ ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len);
+
+ if (ret != Z_OK)
+ return ret;
+
+ /* Set up the compression buffers, we need a loop here to avoid overflowing a
+ * uInt. Use ZLIB_IO_MAX to limit the input. The output is always limited
+ * by the output buffer size, so there is no need to check that. Since this
+ * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits
+ * in size.
+ */
+ {
+ png_compression_bufferp *end = &png_ptr->zbuffer_list;
+ png_alloc_size_t input_len = comp->input_len; /* may be zero! */
+ png_uint_32 output_len;
+
+ /* zlib updates these for us: */
+ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input);
+ png_ptr->zstream.avail_in = 0; /* Set below */
+ png_ptr->zstream.next_out = comp->output;
+ png_ptr->zstream.avail_out = (sizeof comp->output);
+
+ output_len = png_ptr->zstream.avail_out;
+
+ do
+ {
+ uInt avail_in = ZLIB_IO_MAX;
+
+ if (avail_in > input_len)
+ avail_in = (uInt)input_len;
+
+ input_len -= avail_in;
+
+ png_ptr->zstream.avail_in = avail_in;
+
+ if (png_ptr->zstream.avail_out == 0)
+ {
+ png_compression_buffer *next;
+
+ /* Chunk data is limited to 2^31 bytes in length, so the prefix
+ * length must be counted here.
+ */
+ if (output_len + prefix_len > PNG_UINT_31_MAX)
+ {
+ ret = Z_MEM_ERROR;
+ break;
+ }
+
+ /* Need a new (malloc'ed) buffer, but there may be one present
+ * already.
+ */
+ next = *end;
+ if (next == NULL)
+ {
+ next = png_voidcast(png_compression_bufferp, png_malloc_base
+ (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
+
+ if (next == NULL)
+ {
+ ret = Z_MEM_ERROR;
+ break;
+ }
+
+ /* Link in this buffer (so that it will be freed later) */
+ next->next = NULL;
+ *end = next;
+ }
+
+ png_ptr->zstream.next_out = next->output;
+ png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
+ output_len += png_ptr->zstream.avail_out;
+
+ /* Move 'end' to the next buffer pointer. */
+ end = &next->next;
+ }
+
+ /* Compress the data */
+ ret = deflate(&png_ptr->zstream,
+ input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
+
+ /* Claw back input data that was not consumed (because avail_in is
+ * reset above every time round the loop).
+ */
+ input_len += png_ptr->zstream.avail_in;
+ png_ptr->zstream.avail_in = 0; /* safety */
+ }
+ while (ret == Z_OK);
+
+ /* There may be some space left in the last output buffer. This needs to
+ * be subtracted from output_len.
+ */
+ output_len -= png_ptr->zstream.avail_out;
+ png_ptr->zstream.avail_out = 0; /* safety */
+ comp->output_len = output_len;
+
+ /* Now double check the output length, put in a custom message if it is
+ * too long. Otherwise ensure the z_stream::msg pointer is set to
+ * something.
+ */
+ if (output_len + prefix_len >= PNG_UINT_31_MAX)
+ {
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long");
+ ret = Z_MEM_ERROR;
+ }
+
+ else
+ png_zstream_error(png_ptr, ret);
+
+ /* Reset zlib for another zTXt/iTXt or image data */
+ png_ptr->zowner = 0;
+
+ /* The only success case is Z_STREAM_END, input_len must be 0; if not this
+ * is an internal error.
+ */
+ if (ret == Z_STREAM_END && input_len == 0)
+ {
+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+ /* Fix up the deflate header, if required */
+ optimize_cmf(comp->output, comp->input_len);
+#endif
+ /* But Z_OK is returned, not Z_STREAM_END; this allows the claim
+ * function above to return Z_STREAM_END on an error (though it never
+ * does in the current versions of zlib.)
+ */
+ return Z_OK;
+ }
+
+ else
+ return ret;
+ }
+}
+
+/* Ship the compressed text out via chunk writes */
+static void
+png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)
+{
+ png_uint_32 output_len = comp->output_len;
+ png_const_bytep output = comp->output;
+ png_uint_32 avail = (sizeof comp->output);
+ png_compression_buffer *next = png_ptr->zbuffer_list;
+
+ for (;;)
+ {
+ if (avail > output_len)
+ avail = output_len;
+
+ png_write_chunk_data(png_ptr, output, avail);
+
+ output_len -= avail;
+
+ if (output_len == 0 || next == NULL)
+ break;
+
+ avail = png_ptr->zbuffer_size;
+ output = next->output;
+ next = next->next;
+ }
+
+ /* This is an internal error; 'next' must have been NULL! */
+ if (output_len > 0)
+ png_error(png_ptr, "error writing ancillary chunked compressed data");
+}
+#endif /* WRITE_COMPRESSED_TEXT */
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information. Note that the rest of this code depends upon this
+ * information being correct.
+ */
+void /* PRIVATE */
+png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
+ int bit_depth, int color_type, int compression_type, int filter_type,
+ int interlace_type)
+{
+ png_byte buf[13]; /* Buffer to store the IHDR info */
+ int is_invalid_depth;
+
+ png_debug(1, "in png_write_IHDR");
+
+ /* Check that we have valid input data from the application info */
+ switch (color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ switch (bit_depth)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ case 16:
+#endif
+ png_ptr->channels = 1; break;
+
+ default:
+ png_error(png_ptr,
+ "Invalid bit depth for grayscale image");
+ }
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ is_invalid_depth = (bit_depth != 8);
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ is_invalid_depth = (is_invalid_depth && bit_depth != 16);
+#endif
+ if (is_invalid_depth)
+ png_error(png_ptr, "Invalid bit depth for RGB image");
+
+ png_ptr->channels = 3;
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ switch (bit_depth)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ png_ptr->channels = 1;
+ break;
+
+ default:
+ png_error(png_ptr, "Invalid bit depth for paletted image");
+ }
+ break;
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ is_invalid_depth = (bit_depth != 8);
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ is_invalid_depth = (is_invalid_depth && bit_depth != 16);
+#endif
+ if (is_invalid_depth)
+ png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
+
+ png_ptr->channels = 2;
+ break;
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ is_invalid_depth = (bit_depth != 8);
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ is_invalid_depth = (is_invalid_depth && bit_depth != 16);
+#endif
+ if (is_invalid_depth)
+ png_error(png_ptr, "Invalid bit depth for RGBA image");
+
+ png_ptr->channels = 4;
+ break;
+
+ default:
+ png_error(png_ptr, "Invalid image color type specified");
+ }
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Invalid compression type specified");
+ compression_type = PNG_COMPRESSION_TYPE_BASE;
+ }
+
+ /* Write filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not write a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if (
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) != 0 &&
+ ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
+ (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
+ (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
+#endif
+ filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Invalid filter type specified");
+ filter_type = PNG_FILTER_TYPE_BASE;
+ }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ if (interlace_type != PNG_INTERLACE_NONE &&
+ interlace_type != PNG_INTERLACE_ADAM7)
+ {
+ png_warning(png_ptr, "Invalid interlace type specified");
+ interlace_type = PNG_INTERLACE_ADAM7;
+ }
+#else
+ interlace_type=PNG_INTERLACE_NONE;
+#endif
+
+ /* Save the relevant information */
+ png_ptr->bit_depth = (png_byte)bit_depth;
+ png_ptr->color_type = (png_byte)color_type;
+ png_ptr->interlaced = (png_byte)interlace_type;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ png_ptr->filter_type = (png_byte)filter_type;
+#endif
+ png_ptr->compression_type = (png_byte)compression_type;
+ png_ptr->width = width;
+ png_ptr->height = height;
+
+ png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
+ /* Set the usr info, so any transformations can modify it */
+ png_ptr->usr_width = png_ptr->width;
+ png_ptr->usr_bit_depth = png_ptr->bit_depth;
+ png_ptr->usr_channels = png_ptr->channels;
+
+ /* Pack the header information into the buffer */
+ png_save_uint_32(buf, width);
+ png_save_uint_32(buf + 4, height);
+ buf[8] = (png_byte)bit_depth;
+ buf[9] = (png_byte)color_type;
+ buf[10] = (png_byte)compression_type;
+ buf[11] = (png_byte)filter_type;
+ buf[12] = (png_byte)interlace_type;
+
+ /* Write the chunk */
+ png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
+
+ if ((png_ptr->do_filter) == PNG_NO_FILTERS)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+ png_ptr->bit_depth < 8)
+ png_ptr->do_filter = PNG_FILTER_NONE;
+
+ else
+ png_ptr->do_filter = PNG_ALL_FILTERS;
+ }
+
+ png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */
+}
+
+/* Write the palette. We are careful not to trust png_color to be in the
+ * correct order for PNG, so people can redefine it to any convenient
+ * structure.
+ */
+void /* PRIVATE */
+png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
+ png_uint_32 num_pal)
+{
+ png_uint_32 max_palette_length, i;
+ png_const_colorp pal_ptr;
+ png_byte buf[3];
+
+ png_debug(1, "in png_write_PLTE");
+
+ max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
+ (1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
+
+ if ((
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0 &&
+#endif
+ num_pal == 0) || num_pal > max_palette_length)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_error(png_ptr, "Invalid number of colors in palette");
+ }
+
+ else
+ {
+ png_warning(png_ptr, "Invalid number of colors in palette");
+ return;
+ }
+ }
+
+ if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0)
+ {
+ png_warning(png_ptr,
+ "Ignoring request to write a PLTE chunk in grayscale PNG");
+
+ return;
+ }
+
+ png_ptr->num_palette = (png_uint_16)num_pal;
+ png_debug1(3, "num_palette = %d", png_ptr->num_palette);
+
+ png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3));
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+
+ for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
+ {
+ buf[0] = pal_ptr->red;
+ buf[1] = pal_ptr->green;
+ buf[2] = pal_ptr->blue;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+ }
+
+#else
+ /* This is a little slower but some buggy compilers need to do this
+ * instead
+ */
+ pal_ptr=palette;
+
+ for (i = 0; i < num_pal; i++)
+ {
+ buf[0] = pal_ptr[i].red;
+ buf[1] = pal_ptr[i].green;
+ buf[2] = pal_ptr[i].blue;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+ }
+
+#endif
+ png_write_chunk_end(png_ptr);
+ png_ptr->mode |= PNG_HAVE_PLTE;
+}
+
+/* This is similar to png_text_compress, above, except that it does not require
+ * all of the data at once and, instead of buffering the compressed result,
+ * writes it as IDAT chunks. Unlike png_text_compress it *can* png_error out
+ * because it calls the write interface. As a result it does its own error
+ * reporting and does not return an error code. In the event of error it will
+ * just call png_error. The input data length may exceed 32-bits. The 'flush'
+ * parameter is exactly the same as that to deflate, with the following
+ * meanings:
+ *
+ * Z_NO_FLUSH: normal incremental output of compressed data
+ * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush
+ * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up
+ *
+ * The routine manages the acquire and release of the png_ptr->zstream by
+ * checking and (at the end) clearing png_ptr->zowner; it does some sanity
+ * checks on the 'mode' flags while doing this.
+ */
+void /* PRIVATE */
+png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
+ png_alloc_size_t input_len, int flush)
+{
+ if (png_ptr->zowner != png_IDAT)
+ {
+ /* First time. Ensure we have a temporary buffer for compression and
+ * trim the buffer list if it has more than one entry to free memory.
+ * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been
+ * created at this point, but the check here is quick and safe.
+ */
+ if (png_ptr->zbuffer_list == NULL)
+ {
+ png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,
+ png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
+ png_ptr->zbuffer_list->next = NULL;
+ }
+
+ else
+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next);
+
+ /* It is a terminal error if we can't claim the zstream. */
+ if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg);
+
+ /* The output state is maintained in png_ptr->zstream, so it must be
+ * initialized here after the claim.
+ */
+ png_ptr->zstream.next_out = png_ptr->zbuffer_list->output;
+ png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
+ }
+
+ /* Now loop reading and writing until all the input is consumed or an error
+ * terminates the operation. The _out values are maintained across calls to
+ * this function, but the input must be reset each time.
+ */
+ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);
+ png_ptr->zstream.avail_in = 0; /* set below */
+ for (;;)
+ {
+ int ret;
+
+ /* INPUT: from the row data */
+ uInt avail = ZLIB_IO_MAX;
+
+ if (avail > input_len)
+ avail = (uInt)input_len; /* safe because of the check */
+
+ png_ptr->zstream.avail_in = avail;
+ input_len -= avail;
+
+ ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush);
+
+ /* Include as-yet unconsumed input */
+ input_len += png_ptr->zstream.avail_in;
+ png_ptr->zstream.avail_in = 0;
+
+ /* OUTPUT: write complete IDAT chunks when avail_out drops to zero. Note
+ * that these two zstream fields are preserved across the calls, therefore
+ * there is no need to set these up on entry to the loop.
+ */
+ if (png_ptr->zstream.avail_out == 0)
+ {
+ png_bytep data = png_ptr->zbuffer_list->output;
+ uInt size = png_ptr->zbuffer_size;
+
+ /* Write an IDAT containing the data then reset the buffer. The
+ * first IDAT may need deflate header optimization.
+ */
+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&
+ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+ optimize_cmf(data, png_image_size(png_ptr));
+#endif
+
+ if (size > 0)
+ png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+ png_ptr->mode |= PNG_HAVE_IDAT;
+
+ png_ptr->zstream.next_out = data;
+ png_ptr->zstream.avail_out = size;
+
+ /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with
+ * the same flush parameter until it has finished output, for NO_FLUSH
+ * it doesn't matter.
+ */
+ if (ret == Z_OK && flush != Z_NO_FLUSH)
+ continue;
+ }
+
+ /* The order of these checks doesn't matter much; it just affects which
+ * possible error might be detected if multiple things go wrong at once.
+ */
+ if (ret == Z_OK) /* most likely return code! */
+ {
+ /* If all the input has been consumed then just return. If Z_FINISH
+ * was used as the flush parameter something has gone wrong if we get
+ * here.
+ */
+ if (input_len == 0)
+ {
+ if (flush == Z_FINISH)
+ png_error(png_ptr, "Z_OK on Z_FINISH with output space");
+
+ return;
+ }
+ }
+
+ else if (ret == Z_STREAM_END && flush == Z_FINISH)
+ {
+ /* This is the end of the IDAT data; any pending output must be
+ * flushed. For small PNG files we may still be at the beginning.
+ */
+ png_bytep data = png_ptr->zbuffer_list->output;
+ uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out;
+
+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+ if ((png_ptr->mode & PNG_HAVE_IDAT) == 0 &&
+ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+ optimize_cmf(data, png_image_size(png_ptr));
+#endif
+
+ if (size > 0)
+ png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+ png_ptr->zstream.avail_out = 0;
+ png_ptr->zstream.next_out = NULL;
+ png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
+
+ png_ptr->zowner = 0; /* Release the stream */
+ return;
+ }
+
+ else
+ {
+ /* This is an error condition. */
+ png_zstream_error(png_ptr, ret);
+ png_error(png_ptr, png_ptr->zstream.msg);
+ }
+ }
+}
+
+/* Write an IEND chunk */
+void /* PRIVATE */
+png_write_IEND(png_structrp png_ptr)
+{
+ png_debug(1, "in png_write_IEND");
+
+ png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
+ png_ptr->mode |= PNG_HAVE_IEND;
+}
+
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+/* Write a gAMA chunk */
+void /* PRIVATE */
+png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)
+{
+ png_byte buf[4];
+
+ png_debug(1, "in png_write_gAMA");
+
+ /* file_gamma is saved in 1/100,000ths */
+ png_save_uint_32(buf, (png_uint_32)file_gamma);
+ png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
+}
+#endif
+
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+/* Write a sRGB chunk */
+void /* PRIVATE */
+png_write_sRGB(png_structrp png_ptr, int srgb_intent)
+{
+ png_byte buf[1];
+
+ png_debug(1, "in png_write_sRGB");
+
+ if (srgb_intent >= PNG_sRGB_INTENT_LAST)
+ png_warning(png_ptr,
+ "Invalid sRGB rendering intent specified");
+
+ buf[0]=(png_byte)srgb_intent;
+ png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
+}
+#endif
+
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+/* Write an iCCP chunk */
+void /* PRIVATE */
+png_write_iCCP(png_structrp png_ptr, png_const_charp name,
+ png_const_bytep profile)
+{
+ png_uint_32 name_len;
+ png_uint_32 profile_len;
+ png_byte new_name[81]; /* 1 byte for the compression byte */
+ compression_state comp;
+ png_uint_32 temp;
+
+ png_debug(1, "in png_write_iCCP");
+
+ /* These are all internal problems: the profile should have been checked
+ * before when it was stored.
+ */
+ if (profile == NULL)
+ png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */
+
+ profile_len = png_get_uint_32(profile);
+
+ if (profile_len < 132)
+ png_error(png_ptr, "ICC profile too short");
+
+ temp = (png_uint_32) (*(profile+8));
+ if (temp > 3 && (profile_len & 0x03))
+ png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)");
+
+ {
+ png_uint_32 embedded_profile_len = png_get_uint_32(profile);
+
+ if (profile_len != embedded_profile_len)
+ png_error(png_ptr, "Profile length does not match profile");
+ }
+
+ name_len = png_check_keyword(png_ptr, name, new_name);
+
+ if (name_len == 0)
+ png_error(png_ptr, "iCCP: invalid keyword");
+
+ new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE;
+
+ /* Make sure we include the NULL after the name and the compression type */
+ ++name_len;
+
+ png_text_compress_init(&comp, profile, profile_len);
+
+ /* Allow for keyword terminator and compression byte */
+ if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg);
+
+ png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len);
+
+ png_write_chunk_data(png_ptr, new_name, name_len);
+
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+/* Write a sPLT chunk */
+void /* PRIVATE */
+png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
+{
+ png_uint_32 name_len;
+ png_byte new_name[80];
+ png_byte entrybuf[10];
+ png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
+ png_size_t palette_size = entry_size * (png_size_t)spalette->nentries;
+ png_sPLT_entryp ep;
+#ifndef PNG_POINTER_INDEXING_SUPPORTED
+ int i;
+#endif
+
+ png_debug(1, "in png_write_sPLT");
+
+ name_len = png_check_keyword(png_ptr, spalette->name, new_name);
+
+ if (name_len == 0)
+ png_error(png_ptr, "sPLT: invalid keyword");
+
+ /* Make sure we include the NULL after the name */
+ png_write_chunk_header(png_ptr, png_sPLT,
+ (png_uint_32)(name_len + 2 + palette_size));
+
+ png_write_chunk_data(png_ptr, (png_bytep)new_name,
+ (png_size_t)(name_len + 1));
+
+ png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
+
+ /* Loop through each palette entry, writing appropriately */
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
+ {
+ if (spalette->depth == 8)
+ {
+ entrybuf[0] = (png_byte)ep->red;
+ entrybuf[1] = (png_byte)ep->green;
+ entrybuf[2] = (png_byte)ep->blue;
+ entrybuf[3] = (png_byte)ep->alpha;
+ png_save_uint_16(entrybuf + 4, ep->frequency);
+ }
+
+ else
+ {
+ png_save_uint_16(entrybuf + 0, ep->red);
+ png_save_uint_16(entrybuf + 2, ep->green);
+ png_save_uint_16(entrybuf + 4, ep->blue);
+ png_save_uint_16(entrybuf + 6, ep->alpha);
+ png_save_uint_16(entrybuf + 8, ep->frequency);
+ }
+
+ png_write_chunk_data(png_ptr, entrybuf, entry_size);
+ }
+#else
+ ep=spalette->entries;
+ for (i = 0; i>spalette->nentries; i++)
+ {
+ if (spalette->depth == 8)
+ {
+ entrybuf[0] = (png_byte)ep[i].red;
+ entrybuf[1] = (png_byte)ep[i].green;
+ entrybuf[2] = (png_byte)ep[i].blue;
+ entrybuf[3] = (png_byte)ep[i].alpha;
+ png_save_uint_16(entrybuf + 4, ep[i].frequency);
+ }
+
+ else
+ {
+ png_save_uint_16(entrybuf + 0, ep[i].red);
+ png_save_uint_16(entrybuf + 2, ep[i].green);
+ png_save_uint_16(entrybuf + 4, ep[i].blue);
+ png_save_uint_16(entrybuf + 6, ep[i].alpha);
+ png_save_uint_16(entrybuf + 8, ep[i].frequency);
+ }
+
+ png_write_chunk_data(png_ptr, entrybuf, entry_size);
+ }
+#endif
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+/* Write the sBIT chunk */
+void /* PRIVATE */
+png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
+{
+ png_byte buf[4];
+ png_size_t size;
+
+ png_debug(1, "in png_write_sBIT");
+
+ /* Make sure we don't depend upon the order of PNG_COLOR_8 */
+ if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
+ {
+ png_byte maxbits;
+
+ maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
+ png_ptr->usr_bit_depth);
+
+ if (sbit->red == 0 || sbit->red > maxbits ||
+ sbit->green == 0 || sbit->green > maxbits ||
+ sbit->blue == 0 || sbit->blue > maxbits)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+
+ buf[0] = sbit->red;
+ buf[1] = sbit->green;
+ buf[2] = sbit->blue;
+ size = 3;
+ }
+
+ else
+ {
+ if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+
+ buf[0] = sbit->gray;
+ size = 1;
+ }
+
+ if ((color_type & PNG_COLOR_MASK_ALPHA) != 0)
+ {
+ if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+
+ buf[size++] = sbit->alpha;
+ }
+
+ png_write_complete_chunk(png_ptr, png_sBIT, buf, size);
+}
+#endif
+
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+/* Write the cHRM chunk */
+void /* PRIVATE */
+png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy)
+{
+ png_byte buf[32];
+
+ png_debug(1, "in png_write_cHRM");
+
+ /* Each value is saved in 1/100,000ths */
+ png_save_int_32(buf, xy->whitex);
+ png_save_int_32(buf + 4, xy->whitey);
+
+ png_save_int_32(buf + 8, xy->redx);
+ png_save_int_32(buf + 12, xy->redy);
+
+ png_save_int_32(buf + 16, xy->greenx);
+ png_save_int_32(buf + 20, xy->greeny);
+
+ png_save_int_32(buf + 24, xy->bluex);
+ png_save_int_32(buf + 28, xy->bluey);
+
+ png_write_complete_chunk(png_ptr, png_cHRM, buf, 32);
+}
+#endif
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+/* Write the tRNS chunk */
+void /* PRIVATE */
+png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
+ png_const_color_16p tran, int num_trans, int color_type)
+{
+ png_byte buf[6];
+
+ png_debug(1, "in png_write_tRNS");
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
+ {
+ png_app_warning(png_ptr,
+ "Invalid number of transparent colors specified");
+ return;
+ }
+
+ /* Write the chunk out as it is */
+ png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
+ (png_size_t)num_trans);
+ }
+
+ else if (color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ /* One 16-bit value */
+ if (tran->gray >= (1 << png_ptr->bit_depth))
+ {
+ png_app_warning(png_ptr,
+ "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
+
+ return;
+ }
+
+ png_save_uint_16(buf, tran->gray);
+ png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
+ }
+
+ else if (color_type == PNG_COLOR_TYPE_RGB)
+ {
+ /* Three 16-bit values */
+ png_save_uint_16(buf, tran->red);
+ png_save_uint_16(buf + 2, tran->green);
+ png_save_uint_16(buf + 4, tran->blue);
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)
+#else
+ if ((buf[0] | buf[2] | buf[4]) != 0)
+#endif
+ {
+ png_app_warning(png_ptr,
+ "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+ return;
+ }
+
+ png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
+ }
+
+ else
+ {
+ png_app_warning(png_ptr, "Can't write tRNS with an alpha channel");
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+/* Write the background chunk */
+void /* PRIVATE */
+png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
+{
+ png_byte buf[6];
+
+ png_debug(1, "in png_write_bKGD");
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ (png_ptr->num_palette != 0 ||
+ (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0) &&
+#endif
+ back->index >= png_ptr->num_palette)
+ {
+ png_warning(png_ptr, "Invalid background palette index");
+ return;
+ }
+
+ buf[0] = back->index;
+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
+ }
+
+ else if ((color_type & PNG_COLOR_MASK_COLOR) != 0)
+ {
+ png_save_uint_16(buf, back->red);
+ png_save_uint_16(buf + 2, back->green);
+ png_save_uint_16(buf + 4, back->blue);
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]) != 0)
+#else
+ if ((buf[0] | buf[2] | buf[4]) != 0)
+#endif
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write 16-bit bKGD chunk "
+ "when bit_depth is 8");
+
+ return;
+ }
+
+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
+ }
+
+ else
+ {
+ if (back->gray >= (1 << png_ptr->bit_depth))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
+
+ return;
+ }
+
+ png_save_uint_16(buf, back->gray);
+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_eXIf_SUPPORTED
+/* Write the Exif data */
+void /* PRIVATE */
+png_write_eXIf(png_structrp png_ptr, png_bytep exif, int num_exif)
+{
+ int i;
+ png_byte buf[1];
+
+ png_debug(1, "in png_write_eXIf");
+
+ png_write_chunk_header(png_ptr, png_eXIf, (png_uint_32)(num_exif));
+
+ for (i = 0; i < num_exif; i++)
+ {
+ buf[0] = exif[i];
+ png_write_chunk_data(png_ptr, buf, (png_size_t)1);
+ }
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+/* Write the histogram */
+void /* PRIVATE */
+png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
+{
+ int i;
+ png_byte buf[3];
+
+ png_debug(1, "in png_write_hIST");
+
+ if (num_hist > (int)png_ptr->num_palette)
+ {
+ png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
+ png_ptr->num_palette);
+
+ png_warning(png_ptr, "Invalid number of histogram entries specified");
+ return;
+ }
+
+ png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
+
+ for (i = 0; i < num_hist; i++)
+ {
+ png_save_uint_16(buf, hist[i]);
+ png_write_chunk_data(png_ptr, buf, (png_size_t)2);
+ }
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+/* Write a tEXt chunk */
+void /* PRIVATE */
+png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
+ png_size_t text_len)
+{
+ png_uint_32 key_len;
+ png_byte new_key[80];
+
+ png_debug(1, "in png_write_tEXt");
+
+ key_len = png_check_keyword(png_ptr, key, new_key);
+
+ if (key_len == 0)
+ png_error(png_ptr, "tEXt: invalid keyword");
+
+ if (text == NULL || *text == '\0')
+ text_len = 0;
+
+ else
+ text_len = strlen(text);
+
+ if (text_len > PNG_UINT_31_MAX - (key_len+1))
+ png_error(png_ptr, "tEXt: text too long");
+
+ /* Make sure we include the 0 after the key */
+ png_write_chunk_header(png_ptr, png_tEXt,
+ (png_uint_32)/*checked above*/(key_len + text_len + 1));
+ /*
+ * We leave it to the application to meet PNG-1.0 requirements on the
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+ */
+ png_write_chunk_data(png_ptr, new_key, key_len + 1);
+
+ if (text_len != 0)
+ png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len);
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+/* Write a compressed text chunk */
+void /* PRIVATE */
+png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
+ int compression)
+{
+ png_uint_32 key_len;
+ png_byte new_key[81];
+ compression_state comp;
+
+ png_debug(1, "in png_write_zTXt");
+
+ if (compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+ png_write_tEXt(png_ptr, key, text, 0);
+ return;
+ }
+
+ if (compression != PNG_TEXT_COMPRESSION_zTXt)
+ png_error(png_ptr, "zTXt: invalid compression type");
+
+ key_len = png_check_keyword(png_ptr, key, new_key);
+
+ if (key_len == 0)
+ png_error(png_ptr, "zTXt: invalid keyword");
+
+ /* Add the compression method and 1 for the keyword separator. */
+ new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
+ ++key_len;
+
+ /* Compute the compressed data; do it now for the length */
+ png_text_compress_init(&comp, (png_const_bytep)text,
+ text == NULL ? 0 : strlen(text));
+
+ if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg);
+
+ /* Write start of chunk */
+ png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len);
+
+ /* Write key */
+ png_write_chunk_data(png_ptr, new_key, key_len);
+
+ /* Write the compressed data */
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ /* Close the chunk */
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+/* Write an iTXt chunk */
+void /* PRIVATE */
+png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,
+ png_const_charp lang, png_const_charp lang_key, png_const_charp text)
+{
+ png_uint_32 key_len, prefix_len;
+ png_size_t lang_len, lang_key_len;
+ png_byte new_key[82];
+ compression_state comp;
+
+ png_debug(1, "in png_write_iTXt");
+
+ key_len = png_check_keyword(png_ptr, key, new_key);
+
+ if (key_len == 0)
+ png_error(png_ptr, "iTXt: invalid keyword");
+
+ /* Set the compression flag */
+ switch (compression)
+ {
+ case PNG_ITXT_COMPRESSION_NONE:
+ case PNG_TEXT_COMPRESSION_NONE:
+ compression = new_key[++key_len] = 0; /* no compression */
+ break;
+
+ case PNG_TEXT_COMPRESSION_zTXt:
+ case PNG_ITXT_COMPRESSION_zTXt:
+ compression = new_key[++key_len] = 1; /* compressed */
+ break;
+
+ default:
+ png_error(png_ptr, "iTXt: invalid compression");
+ }
+
+ new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
+ ++key_len; /* for the keywod separator */
+
+ /* We leave it to the application to meet PNG-1.0 requirements on the
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG, however,
+ * specifies that the text is UTF-8 and this really doesn't require any
+ * checking.
+ *
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+ *
+ * TODO: validate the language tag correctly (see the spec.)
+ */
+ if (lang == NULL) lang = ""; /* empty language is valid */
+ lang_len = strlen(lang)+1;
+ if (lang_key == NULL) lang_key = ""; /* may be empty */
+ lang_key_len = strlen(lang_key)+1;
+ if (text == NULL) text = ""; /* may be empty */
+
+ prefix_len = key_len;
+ if (lang_len > PNG_UINT_31_MAX-prefix_len)
+ prefix_len = PNG_UINT_31_MAX;
+ else
+ prefix_len = (png_uint_32)(prefix_len + lang_len);
+
+ if (lang_key_len > PNG_UINT_31_MAX-prefix_len)
+ prefix_len = PNG_UINT_31_MAX;
+ else
+ prefix_len = (png_uint_32)(prefix_len + lang_key_len);
+
+ png_text_compress_init(&comp, (png_const_bytep)text, strlen(text));
+
+ if (compression != 0)
+ {
+ if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ }
+
+ else
+ {
+ if (comp.input_len > PNG_UINT_31_MAX-prefix_len)
+ png_error(png_ptr, "iTXt: uncompressed text too long");
+
+ /* So the string will fit in a chunk: */
+ comp.output_len = (png_uint_32)/*SAFE*/comp.input_len;
+ }
+
+ png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len);
+
+ png_write_chunk_data(png_ptr, new_key, key_len);
+
+ png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len);
+
+ png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len);
+
+ if (compression != 0)
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ else
+ png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.output_len);
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+/* Write the oFFs chunk */
+void /* PRIVATE */
+png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
+ int unit_type)
+{
+ png_byte buf[9];
+
+ png_debug(1, "in png_write_oFFs");
+
+ if (unit_type >= PNG_OFFSET_LAST)
+ png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
+
+ png_save_int_32(buf, x_offset);
+ png_save_int_32(buf + 4, y_offset);
+ buf[8] = (png_byte)unit_type;
+
+ png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
+}
+#endif
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+/* Write the pCAL chunk (described in the PNG extensions document) */
+void /* PRIVATE */
+png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
+ png_int_32 X1, int type, int nparams, png_const_charp units,
+ png_charpp params)
+{
+ png_uint_32 purpose_len;
+ png_size_t units_len, total_len;
+ png_size_tp params_len;
+ png_byte buf[10];
+ png_byte new_purpose[80];
+ int i;
+
+ png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
+
+ if (type >= PNG_EQUATION_LAST)
+ png_error(png_ptr, "Unrecognized equation type for pCAL chunk");
+
+ purpose_len = png_check_keyword(png_ptr, purpose, new_purpose);
+
+ if (purpose_len == 0)
+ png_error(png_ptr, "pCAL: invalid keyword");
+
+ ++purpose_len; /* terminator */
+
+ png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
+ units_len = strlen(units) + (nparams == 0 ? 0 : 1);
+ png_debug1(3, "pCAL units length = %d", (int)units_len);
+ total_len = purpose_len + units_len + 10;
+
+ params_len = (png_size_tp)png_malloc(png_ptr,
+ (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (png_size_t))));
+
+ /* Find the length of each parameter, making sure we don't count the
+ * null terminator for the last parameter.
+ */
+ for (i = 0; i < nparams; i++)
+ {
+ params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
+ png_debug2(3, "pCAL parameter %d length = %lu", i,
+ (unsigned long)params_len[i]);
+ total_len += params_len[i];
+ }
+
+ png_debug1(3, "pCAL total length = %d", (int)total_len);
+ png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);
+ png_write_chunk_data(png_ptr, new_purpose, purpose_len);
+ png_save_int_32(buf, X0);
+ png_save_int_32(buf + 4, X1);
+ buf[8] = (png_byte)type;
+ buf[9] = (png_byte)nparams;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)10);
+ png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
+
+ for (i = 0; i < nparams; i++)
+ {
+ png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);
+ }
+
+ png_free(png_ptr, params_len);
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+/* Write the sCAL chunk */
+void /* PRIVATE */
+png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
+ png_const_charp height)
+{
+ png_byte buf[64];
+ png_size_t wlen, hlen, total_len;
+
+ png_debug(1, "in png_write_sCAL_s");
+
+ wlen = strlen(width);
+ hlen = strlen(height);
+ total_len = wlen + hlen + 2;
+
+ if (total_len > 64)
+ {
+ png_warning(png_ptr, "Can't write sCAL (buffer too small)");
+ return;
+ }
+
+ buf[0] = (png_byte)unit;
+ memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */
+ memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */
+
+ png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
+ png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len);
+}
+#endif
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+/* Write the pHYs chunk */
+void /* PRIVATE */
+png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,
+ png_uint_32 y_pixels_per_unit,
+ int unit_type)
+{
+ png_byte buf[9];
+
+ png_debug(1, "in png_write_pHYs");
+
+ if (unit_type >= PNG_RESOLUTION_LAST)
+ png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
+
+ png_save_uint_32(buf, x_pixels_per_unit);
+ png_save_uint_32(buf + 4, y_pixels_per_unit);
+ buf[8] = (png_byte)unit_type;
+
+ png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
+}
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+/* Write the tIME chunk. Use either png_convert_from_struct_tm()
+ * or png_convert_from_time_t(), or fill in the structure yourself.
+ */
+void /* PRIVATE */
+png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
+{
+ png_byte buf[7];
+
+ png_debug(1, "in png_write_tIME");
+
+ if (mod_time->month > 12 || mod_time->month < 1 ||
+ mod_time->day > 31 || mod_time->day < 1 ||
+ mod_time->hour > 23 || mod_time->second > 60)
+ {
+ png_warning(png_ptr, "Invalid time specified for tIME chunk");
+ return;
+ }
+
+ png_save_uint_16(buf, mod_time->year);
+ buf[2] = mod_time->month;
+ buf[3] = mod_time->day;
+ buf[4] = mod_time->hour;
+ buf[5] = mod_time->minute;
+ buf[6] = mod_time->second;
+
+ png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
+}
+#endif
+
+/* Initializes the row writing capability of libpng */
+void /* PRIVATE */
+png_write_start_row(png_structrp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ png_alloc_size_t buf_size;
+ int usr_pixel_depth;
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ png_byte filters;
+#endif
+
+ png_debug(1, "in png_write_start_row");
+
+ usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
+ buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1;
+
+ /* 1.5.6: added to allow checking in the row write code. */
+ png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;
+ png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;
+
+ /* Set up row buffer */
+ png_ptr->row_buf = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
+
+ png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ filters = png_ptr->do_filter;
+
+ if (png_ptr->height == 1)
+ filters &= 0xff & ~(PNG_FILTER_UP|PNG_FILTER_AVG|PNG_FILTER_PAETH);
+
+ if (png_ptr->width == 1)
+ filters &= 0xff & ~(PNG_FILTER_SUB|PNG_FILTER_AVG|PNG_FILTER_PAETH);
+
+ if (filters == 0)
+ filters = PNG_FILTER_NONE;
+
+ png_ptr->do_filter = filters;
+
+ if (((filters & (PNG_FILTER_SUB | PNG_FILTER_UP | PNG_FILTER_AVG |
+ PNG_FILTER_PAETH)) != 0) && png_ptr->try_row == NULL)
+ {
+ int num_filters = 0;
+
+ png_ptr->try_row = png_voidcast(png_bytep, png_malloc(png_ptr, buf_size));
+
+ if (filters & PNG_FILTER_SUB)
+ num_filters++;
+
+ if (filters & PNG_FILTER_UP)
+ num_filters++;
+
+ if (filters & PNG_FILTER_AVG)
+ num_filters++;
+
+ if (filters & PNG_FILTER_PAETH)
+ num_filters++;
+
+ if (num_filters > 1)
+ png_ptr->tst_row = png_voidcast(png_bytep, png_malloc(png_ptr,
+ buf_size));
+ }
+
+ /* We only need to keep the previous row if we are using one of the following
+ * filters.
+ */
+ if ((filters & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) != 0)
+ png_ptr->prev_row = png_voidcast(png_bytep,
+ png_calloc(png_ptr, buf_size));
+#endif /* WRITE_FILTER */
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* If interlaced, we need to set up width and height of pass */
+ if (png_ptr->interlaced != 0)
+ {
+ if ((png_ptr->transformations & PNG_INTERLACE) == 0)
+ {
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+ png_pass_ystart[0]) / png_pass_yinc[0];
+
+ png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
+ png_pass_start[0]) / png_pass_inc[0];
+ }
+
+ else
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->usr_width = png_ptr->width;
+ }
+ }
+
+ else
+#endif
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->usr_width = png_ptr->width;
+ }
+}
+
+/* Internal use only. Called when finished processing a row of data. */
+void /* PRIVATE */
+png_write_finish_row(png_structrp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ png_debug(1, "in png_write_finish_row");
+
+ /* Next row */
+ png_ptr->row_number++;
+
+ /* See if we are done */
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* If interlaced, go to next pass */
+ if (png_ptr->interlaced != 0)
+ {
+ png_ptr->row_number = 0;
+ if ((png_ptr->transformations & PNG_INTERLACE) != 0)
+ {
+ png_ptr->pass++;
+ }
+
+ else
+ {
+ /* Loop until we find a non-zero width or height pass */
+ do
+ {
+ png_ptr->pass++;
+
+ if (png_ptr->pass >= 7)
+ break;
+
+ png_ptr->usr_width = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+
+ if ((png_ptr->transformations & PNG_INTERLACE) != 0)
+ break;
+
+ } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
+
+ }
+
+ /* Reset the row above the image for the next pass */
+ if (png_ptr->pass < 7)
+ {
+ if (png_ptr->prev_row != NULL)
+ memset(png_ptr->prev_row, 0,
+ (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
+ png_ptr->usr_bit_depth, png_ptr->width)) + 1);
+
+ return;
+ }
+ }
+#endif
+
+ /* If we get here, we've just written the last row, so we need
+ to flush the compressor */
+ png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH);
+}
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+/* Pick out the correct pixels for the interlace pass.
+ * The basic idea here is to go through the row with a source
+ * pointer and a destination pointer (sp and dp), and copy the
+ * correct pixels for the pass. As the row gets compacted,
+ * sp will always be >= dp, so we should never overwrite anything.
+ * See the default: case for the easiest code to understand.
+ */
+void /* PRIVATE */
+png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
+{
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ png_debug(1, "in png_do_write_interlace");
+
+ /* We don't have to do anything on the last pass (6) */
+ if (pass < 6)
+ {
+ /* Each pixel depth is handled separately */
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ unsigned int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ d = 0;
+ shift = 7;
+
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 3);
+ value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 7;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+
+ else
+ shift--;
+
+ }
+ if (shift != 7)
+ *dp = (png_byte)d;
+
+ break;
+ }
+
+ case 2:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ unsigned int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ shift = 6;
+ d = 0;
+
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 2);
+ value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 6;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+
+ else
+ shift -= 2;
+ }
+ if (shift != 6)
+ *dp = (png_byte)d;
+
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ unsigned int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ shift = 4;
+ d = 0;
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 1);
+ value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 4;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+
+ else
+ shift -= 4;
+ }
+ if (shift != 4)
+ *dp = (png_byte)d;
+
+ break;
+ }
+
+ default:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ png_size_t pixel_bytes;
+
+ /* Start at the beginning */
+ dp = row;
+
+ /* Find out how many bytes each pixel takes up */
+ pixel_bytes = (row_info->pixel_depth >> 3);
+
+ /* Loop through the row, only looking at the pixels that matter */
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ /* Find out where the original pixel is */
+ sp = row + (png_size_t)i * pixel_bytes;
+
+ /* Move the pixel */
+ if (dp != sp)
+ memcpy(dp, sp, pixel_bytes);
+
+ /* Next pixel */
+ dp += pixel_bytes;
+ }
+ break;
+ }
+ }
+ /* Set new row width */
+ row_info->width = (row_info->width +
+ png_pass_inc[pass] - 1 -
+ png_pass_start[pass]) /
+ png_pass_inc[pass];
+
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_info->width);
+ }
+}
+#endif
+
+
+/* This filters the row, chooses which filter to use, if it has not already
+ * been specified by the application, and then writes the row out with the
+ * chosen filter.
+ */
+static void /* PRIVATE */
+png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
+ png_size_t row_bytes);
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+static png_size_t /* PRIVATE */
+png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes, const png_size_t lmins)
+{
+ png_bytep rp, dp, lp;
+ png_size_t i;
+ png_size_t sum = 0;
+ unsigned int v;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ v = *dp = *rp;
+#ifdef PNG_USE_ABS
+ sum += 128 - abs((int)v - 128);
+#else
+ sum += (v < 128) ? v : 256 - v;
+#endif
+ }
+
+ for (lp = png_ptr->row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+#ifdef PNG_USE_ABS
+ sum += 128 - abs((int)v - 128);
+#else
+ sum += (v < 128) ? v : 256 - v;
+#endif
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+ return (sum);
+}
+
+static void /* PRIVATE */
+png_setup_sub_row_only(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes)
+{
+ png_bytep rp, dp, lp;
+ png_size_t i;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ *dp = *rp;
+ }
+
+ for (lp = png_ptr->row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+ }
+}
+
+static png_size_t /* PRIVATE */
+png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes,
+ const png_size_t lmins)
+{
+ png_bytep rp, dp, pp;
+ png_size_t i;
+ png_size_t sum = 0;
+ unsigned int v;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < row_bytes;
+ i++, rp++, pp++, dp++)
+ {
+ v = *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+#ifdef PNG_USE_ABS
+ sum += 128 - abs((int)v - 128);
+#else
+ sum += (v < 128) ? v : 256 - v;
+#endif
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+ return (sum);
+}
+static void /* PRIVATE */
+png_setup_up_row_only(png_structrp png_ptr, const png_size_t row_bytes)
+{
+ png_bytep rp, dp, pp;
+ png_size_t i;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_UP;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < row_bytes;
+ i++, rp++, pp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+ }
+}
+
+static png_size_t /* PRIVATE */
+png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes, const png_size_t lmins)
+{
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 i;
+ png_size_t sum = 0;
+ unsigned int v;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+
+#ifdef PNG_USE_ABS
+ sum += 128 - abs((int)v - 128);
+#else
+ sum += (v < 128) ? v : 256 - v;
+#endif
+ }
+
+ for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+ & 0xff);
+
+#ifdef PNG_USE_ABS
+ sum += 128 - abs((int)v - 128);
+#else
+ sum += (v < 128) ? v : 256 - v;
+#endif
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+ return (sum);
+}
+static void /* PRIVATE */
+png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes)
+{
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 i;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+ }
+
+ for (lp = png_ptr->row_buf + 1; i < row_bytes; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+ & 0xff);
+ }
+}
+
+static png_size_t /* PRIVATE */
+png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes, const png_size_t lmins)
+{
+ png_bytep rp, dp, pp, cp, lp;
+ png_size_t i;
+ png_size_t sum = 0;
+ unsigned int v;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+#ifdef PNG_USE_ABS
+ sum += 128 - abs((int)v - 128);
+#else
+ sum += (v < 128) ? v : 256 - v;
+#endif
+ }
+
+ for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
+ i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+
+#ifdef PNG_USE_ABS
+ sum += 128 - abs((int)v - 128);
+#else
+ sum += (v < 128) ? v : 256 - v;
+#endif
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+ return (sum);
+}
+static void /* PRIVATE */
+png_setup_paeth_row_only(png_structrp png_ptr, const png_uint_32 bpp,
+ const png_size_t row_bytes)
+{
+ png_bytep rp, dp, pp, cp, lp;
+ png_size_t i;
+
+ png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH;
+
+ for (i = 0, rp = png_ptr->row_buf + 1, dp = png_ptr->try_row + 1,
+ pp = png_ptr->prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+ }
+
+ for (lp = png_ptr->row_buf + 1, cp = png_ptr->prev_row + 1; i < row_bytes;
+ i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+ }
+}
+#endif /* WRITE_FILTER */
+
+void /* PRIVATE */
+png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
+{
+#ifndef PNG_WRITE_FILTER_SUPPORTED
+ png_write_filtered_row(png_ptr, png_ptr->row_buf, row_info->rowbytes+1);
+#else
+ unsigned int filter_to_do = png_ptr->do_filter;
+ png_bytep row_buf;
+ png_bytep best_row;
+ png_uint_32 bpp;
+ png_size_t mins;
+ png_size_t row_bytes = row_info->rowbytes;
+
+ png_debug(1, "in png_write_find_filter");
+
+ /* Find out how many bytes offset each pixel is */
+ bpp = (row_info->pixel_depth + 7) >> 3;
+
+ row_buf = png_ptr->row_buf;
+ mins = PNG_SIZE_MAX - 256/* so we can detect potential overflow of the
+ running sum */;
+
+ /* The prediction method we use is to find which method provides the
+ * smallest value when summing the absolute values of the distances
+ * from zero, using anything >= 128 as negative numbers. This is known
+ * as the "minimum sum of absolute differences" heuristic. Other
+ * heuristics are the "weighted minimum sum of absolute differences"
+ * (experimental and can in theory improve compression), and the "zlib
+ * predictive" method (not implemented yet), which does test compressions
+ * of lines using different filter methods, and then chooses the
+ * (series of) filter(s) that give minimum compressed data size (VERY
+ * computationally expensive).
+ *
+ * GRR 980525: consider also
+ *
+ * (1) minimum sum of absolute differences from running average (i.e.,
+ * keep running sum of non-absolute differences & count of bytes)
+ * [track dispersion, too? restart average if dispersion too large?]
+ *
+ * (1b) minimum sum of absolute differences from sliding average, probably
+ * with window size <= deflate window (usually 32K)
+ *
+ * (2) minimum sum of squared differences from zero or running average
+ * (i.e., ~ root-mean-square approach)
+ */
+
+
+ /* We don't need to test the 'no filter' case if this is the only filter
+ * that has been chosen, as it doesn't actually do anything to the data.
+ */
+ best_row = png_ptr->row_buf;
+
+ if (PNG_SIZE_MAX/128 <= row_bytes)
+ {
+ /* Overflow can occur in the calculation, just select the lowest set
+ * filter.
+ */
+ filter_to_do &= 0U-filter_to_do;
+ }
+ else if ((filter_to_do & PNG_FILTER_NONE) != 0 &&
+ filter_to_do != PNG_FILTER_NONE)
+ {
+ /* Overflow not possible and multiple filters in the list, including the
+ * 'none' filter.
+ */
+ png_bytep rp;
+ png_size_t sum = 0;
+ png_size_t i;
+ unsigned int v;
+
+ {
+ for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
+ {
+ v = *rp;
+#ifdef PNG_USE_ABS
+ sum += 128 - abs((int)v - 128);
+#else
+ sum += (v < 128) ? v : 256 - v;
+#endif
+ }
+ }
+
+ mins = sum;
+ }
+
+ /* Sub filter */
+ if (filter_to_do == PNG_FILTER_SUB)
+ /* It's the only filter so no testing is needed */
+ {
+ png_setup_sub_row_only(png_ptr, bpp, row_bytes);
+ best_row = png_ptr->try_row;
+ }
+
+ else if ((filter_to_do & PNG_FILTER_SUB) != 0)
+ {
+ png_size_t sum;
+ png_size_t lmins = mins;
+
+ sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->try_row;
+ if (png_ptr->tst_row != NULL)
+ {
+ png_ptr->try_row = png_ptr->tst_row;
+ png_ptr->tst_row = best_row;
+ }
+ }
+ }
+
+ /* Up filter */
+ if (filter_to_do == PNG_FILTER_UP)
+ {
+ png_setup_up_row_only(png_ptr, row_bytes);
+ best_row = png_ptr->try_row;
+ }
+
+ else if ((filter_to_do & PNG_FILTER_UP) != 0)
+ {
+ png_size_t sum;
+ png_size_t lmins = mins;
+
+ sum = png_setup_up_row(png_ptr, row_bytes, lmins);
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->try_row;
+ if (png_ptr->tst_row != NULL)
+ {
+ png_ptr->try_row = png_ptr->tst_row;
+ png_ptr->tst_row = best_row;
+ }
+ }
+ }
+
+ /* Avg filter */
+ if (filter_to_do == PNG_FILTER_AVG)
+ {
+ png_setup_avg_row_only(png_ptr, bpp, row_bytes);
+ best_row = png_ptr->try_row;
+ }
+
+ else if ((filter_to_do & PNG_FILTER_AVG) != 0)
+ {
+ png_size_t sum;
+ png_size_t lmins = mins;
+
+ sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins);
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->try_row;
+ if (png_ptr->tst_row != NULL)
+ {
+ png_ptr->try_row = png_ptr->tst_row;
+ png_ptr->tst_row = best_row;
+ }
+ }
+ }
+
+ /* Paeth filter */
+ if (filter_to_do == PNG_FILTER_PAETH)
+ {
+ png_setup_paeth_row_only(png_ptr, bpp, row_bytes);
+ best_row = png_ptr->try_row;
+ }
+
+ else if ((filter_to_do & PNG_FILTER_PAETH) != 0)
+ {
+ png_size_t sum;
+ png_size_t lmins = mins;
+
+ sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins);
+
+ if (sum < mins)
+ {
+ best_row = png_ptr->try_row;
+ if (png_ptr->tst_row != NULL)
+ {
+ png_ptr->try_row = png_ptr->tst_row;
+ png_ptr->tst_row = best_row;
+ }
+ }
+ }
+
+ /* Do the actual writing of the filtered row data from the chosen filter. */
+ png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);
+
+#endif /* WRITE_FILTER */
+}
+
+
+/* Do the actual writing of a previously filtered row. */
+static void
+png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
+ png_size_t full_row_length/*includes filter byte*/)
+{
+ png_debug(1, "in png_write_filtered_row");
+
+ png_debug1(2, "filter = %d", filtered_row[0]);
+
+ png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH);
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ /* Swap the current and previous rows */
+ if (png_ptr->prev_row != NULL)
+ {
+ png_bytep tptr;
+
+ tptr = png_ptr->prev_row;
+ png_ptr->prev_row = png_ptr->row_buf;
+ png_ptr->row_buf = tptr;
+ }
+#endif /* WRITE_FILTER */
+
+ /* Finish row - updates counters and flushes zlib if last row */
+ png_write_finish_row(png_ptr);
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+ png_ptr->flush_rows++;
+
+ if (png_ptr->flush_dist > 0 &&
+ png_ptr->flush_rows >= png_ptr->flush_dist)
+ {
+ png_write_flush(png_ptr);
+ }
+#endif /* WRITE_FLUSH */
+}
+#endif /* WRITE */
diff --git a/xs/src/png/libpng/powerpc/filter_vsx_intrinsics.c b/xs/src/png/libpng/powerpc/filter_vsx_intrinsics.c
new file mode 100644
index 000000000..e3de496bd
--- /dev/null
+++ b/xs/src/png/libpng/powerpc/filter_vsx_intrinsics.c
@@ -0,0 +1,767 @@
+/* filter_vsx_intrinsics.c - PowerPC optimised filter functions
+ *
+ * Copyright (c) 2017 Glenn Randers-Pehrson
+ * Written by Vadim Barkov, 2017.
+ * Last changed in libpng 1.6.29 [March 16, 2017]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* This code requires -maltivec and -mvsx on the command line: */
+#if PNG_POWERPC_VSX_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
+
+#include <altivec.h>
+
+#if PNG_POWERPC_VSX_OPT > 0
+
+#ifndef __VSX__
+# error "This code requires VSX support (POWER7 and later). Please provide -mvsx compiler flag."
+#endif
+
+#define vec_ld_unaligned(vec,data) vec = vec_vsx_ld(0,data)
+#define vec_st_unaligned(vec,data) vec_vsx_st(vec,0,data)
+
+
+/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d).
+ * They're positioned like this:
+ * prev: c b
+ * row: a d
+ * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be
+ * whichever of a, b, or c is closest to p=a+b-c.
+ * ( this is taken from ../intel/filter_sse2_intrinsics.c )
+ */
+
+#define vsx_declare_common_vars(row_info,row,prev_row,offset) \
+ png_byte i;\
+ png_bytep rp = row + offset;\
+ png_const_bytep pp = prev_row;\
+ png_size_t unaligned_top = 16 - (((png_size_t)rp % 16));\
+ png_size_t istop;\
+ if(unaligned_top == 16)\
+ unaligned_top = 0;\
+ istop = row_info->rowbytes;\
+ if((unaligned_top < istop))\
+ istop -= unaligned_top;\
+ else{\
+ unaligned_top = istop;\
+ istop = 0;\
+ }
+
+void png_read_filter_row_up_vsx(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ vector unsigned char rp_vec;
+ vector unsigned char pp_vec;
+ vsx_declare_common_vars(row_info,row,prev_row,0)
+
+ /* Altivec operations require 16-byte aligned data
+ * but input can be unaligned. So we calculate
+ * unaligned part as usual.
+ */
+ for (i = 0; i < unaligned_top; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+
+ /* Using SIMD while we can */
+ while( istop >= 16 )
+ {
+ rp_vec = vec_ld(0,rp);
+ vec_ld_unaligned(pp_vec,pp);
+
+ rp_vec = vec_add(rp_vec,pp_vec);
+
+ vec_st(rp_vec,0,rp);
+
+ pp += 16;
+ rp += 16;
+ istop -= 16;
+ }
+
+ if(istop > 0)
+ {
+ /* If byte count of row is not divisible by 16
+ * we will process remaining part as usual
+ */
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+}
+
+}
+
+static const vector unsigned char VSX_LEFTSHIFTED1_4 = {16,16,16,16, 0, 1, 2, 3,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_LEFTSHIFTED2_4 = {16,16,16,16,16,16,16,16, 4, 5, 6, 7,16,16,16,16};
+static const vector unsigned char VSX_LEFTSHIFTED3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 8, 9,10,11};
+
+static const vector unsigned char VSX_LEFTSHIFTED1_3 = {16,16,16, 0, 1, 2,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_LEFTSHIFTED2_3 = {16,16,16,16,16,16, 3, 4, 5,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_LEFTSHIFTED3_3 = {16,16,16,16,16,16,16,16,16, 6, 7, 8,16,16,16,16};
+static const vector unsigned char VSX_LEFTSHIFTED4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 9,10,11,16};
+
+static const vector unsigned char VSX_NOT_SHIFTED1_4 = {16,16,16,16, 4, 5, 6, 7,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_NOT_SHIFTED2_4 = {16,16,16,16,16,16,16,16, 8, 9,10,11,16,16,16,16};
+static const vector unsigned char VSX_NOT_SHIFTED3_4 = {16,16,16,16,16,16,16,16,16,16,16,16,12,13,14,15};
+
+static const vector unsigned char VSX_NOT_SHIFTED1_3 = {16,16,16, 3, 4, 5,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_NOT_SHIFTED2_3 = {16,16,16,16,16,16, 6, 7, 8,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_NOT_SHIFTED3_3 = {16,16,16,16,16,16,16,16,16, 9,10,11,16,16,16,16};
+static const vector unsigned char VSX_NOT_SHIFTED4_3 = {16,16,16,16,16,16,16,16,16,16,16,16,12,13,14,16};
+
+static const vector unsigned char VSX_CHAR_ZERO = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+#ifdef __LITTLE_ENDIAN__
+
+static const vector unsigned char VSX_CHAR_TO_SHORT1_4 = { 4,16, 5,16, 6,16, 7,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT2_4 = { 8,16, 9,16,10,16,11,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT3_4 = {12,16,13,16,14,16,15,16,16,16,16,16,16,16,16,16};
+
+static const vector unsigned char VSX_SHORT_TO_CHAR1_4 = {16,16,16,16, 0, 2, 4, 6,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR2_4 = {16,16,16,16,16,16,16,16, 0, 2, 4, 6,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 0, 2, 4, 6};
+
+static const vector unsigned char VSX_CHAR_TO_SHORT1_3 = { 3,16, 4,16, 5,16,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT2_3 = { 6,16, 7,16, 8,16,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT3_3 = { 9,16,10,16,11,16,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT4_3 = {12,16,13,16,14,16,16,16,16,16,16,16,16,16,16,16};
+
+static const vector unsigned char VSX_SHORT_TO_CHAR1_3 = {16,16,16, 0, 2, 4,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR2_3 = {16,16,16,16,16,16, 0, 2, 4,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR3_3 = {16,16,16,16,16,16,16,16,16, 0, 2, 4,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 0, 2, 4,16};
+
+#elif defined(__BIG_ENDIAN__)
+
+static const vector unsigned char VSX_CHAR_TO_SHORT1_4 = {16, 4,16, 5,16, 6,16, 7,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT2_4 = {16, 8,16, 9,16,10,16,11,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT3_4 = {16,12,16,13,16,14,16,15,16,16,16,16,16,16,16,16};
+
+static const vector unsigned char VSX_SHORT_TO_CHAR1_4 = {16,16,16,16, 1, 3, 5, 7,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR2_4 = {16,16,16,16,16,16,16,16, 1, 3, 5, 7,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 1, 3, 5, 7};
+
+static const vector unsigned char VSX_CHAR_TO_SHORT1_3 = {16, 3,16, 4,16, 5,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT2_3 = {16, 6,16, 7,16, 8,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT3_3 = {16, 9,16,10,16,11,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_CHAR_TO_SHORT4_3 = {16,12,16,13,16,14,16,16,16,16,16,16,16,16,16,16};
+
+static const vector unsigned char VSX_SHORT_TO_CHAR1_3 = {16,16,16, 1, 3, 5,16,16,16,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR2_3 = {16,16,16,16,16,16, 1, 3, 5,16,16,16,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR3_3 = {16,16,16,16,16,16,16,16,16, 1, 3, 5,16,16,16,16};
+static const vector unsigned char VSX_SHORT_TO_CHAR4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 1, 3, 5,16};
+
+#endif
+
+#define vsx_char_to_short(vec,offset,bpp) (vector unsigned short)vec_perm((vec),VSX_CHAR_ZERO,VSX_CHAR_TO_SHORT##offset##_##bpp)
+#define vsx_short_to_char(vec,offset,bpp) vec_perm(((vector unsigned char)(vec)),VSX_CHAR_ZERO,VSX_SHORT_TO_CHAR##offset##_##bpp)
+
+#ifdef PNG_USE_ABS
+# define vsx_abs(number) abs(number)
+#else
+# define vsx_abs(number) (number > 0) ? (number) : -(number)
+#endif
+
+void png_read_filter_row_sub4_vsx(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ const png_byte bpp = 4;
+
+ vector unsigned char rp_vec;
+ vector unsigned char part_vec;
+
+ vsx_declare_common_vars(row_info,row,prev_row,bpp)
+
+ PNG_UNUSED(pp)
+
+ /* Altivec operations require 16-byte aligned data
+ * but input can be unaligned. So we calculate
+ * unaligned part as usual.
+ */
+ for (i = 0; i < unaligned_top; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+ rp++;
+ }
+
+ /* Using SIMD while we can */
+ while( istop >= 16 )
+ {
+ for(i=0;i < bpp ; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+ rp++;
+ }
+ rp -= bpp;
+
+ rp_vec = vec_ld(0,rp);
+ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_4);
+ rp_vec = vec_add(rp_vec,part_vec);
+
+ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_4);
+ rp_vec = vec_add(rp_vec,part_vec);
+
+ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_4);
+ rp_vec = vec_add(rp_vec,part_vec);
+
+ vec_st(rp_vec,0,rp);
+
+ rp += 16;
+ istop -= 16;
+ }
+
+ if(istop > 0)
+ for (i = 0; i < istop % 16; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*(rp - bpp))) & 0xff);
+ rp++;
+ }
+
+}
+
+void png_read_filter_row_sub3_vsx(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ const png_byte bpp = 3;
+
+ vector unsigned char rp_vec;
+ vector unsigned char part_vec;
+
+ vsx_declare_common_vars(row_info,row,prev_row,bpp)
+
+ PNG_UNUSED(pp)
+
+ /* Altivec operations require 16-byte aligned data
+ * but input can be unaligned. So we calculate
+ * unaligned part as usual.
+ */
+ for (i = 0; i < unaligned_top; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+ rp++;
+ }
+
+ /* Using SIMD while we can */
+ while( istop >= 16 )
+ {
+ for(i=0;i < bpp ; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+ rp++;
+ }
+ rp -= bpp;
+
+ rp_vec = vec_ld(0,rp);
+ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_3);
+ rp_vec = vec_add(rp_vec,part_vec);
+
+ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_3);
+ rp_vec = vec_add(rp_vec,part_vec);
+
+ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_3);
+ rp_vec = vec_add(rp_vec,part_vec);
+
+ part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED4_3);
+ rp_vec = vec_add(rp_vec,part_vec);
+
+ vec_st(rp_vec,0,rp);
+ rp += 15;
+ istop -= 16;
+
+ /* Since 16 % bpp = 16 % 3 = 1, last element of array must
+ * be proceeded manually
+ */
+ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+ rp++;
+ }
+
+ if(istop > 0)
+ for (i = 0; i < istop % 16; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+ rp++;
+ }
+}
+
+void png_read_filter_row_avg4_vsx(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ const png_byte bpp = 4;
+
+ vector unsigned char rp_vec;
+ vector unsigned char pp_vec;
+ vector unsigned char pp_part_vec;
+ vector unsigned char rp_part_vec;
+ vector unsigned char avg_vec;
+
+ vsx_declare_common_vars(row_info,row,prev_row,bpp)
+ rp -= bpp;
+ if(istop >= bpp)
+ istop -= bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ ((int)(*pp++) / 2 )) & 0xff);
+
+ rp++;
+ }
+
+ /* Altivec operations require 16-byte aligned data
+ * but input can be unaligned. So we calculate
+ * unaligned part as usual.
+ */
+ for (i = 0; i < unaligned_top; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+ rp++;
+ }
+
+ /* Using SIMD while we can */
+ while( istop >= 16 )
+ {
+ for(i=0;i < bpp ; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+ rp++;
+ }
+ rp -= bpp;
+ pp -= bpp;
+
+ vec_ld_unaligned(pp_vec,pp);
+ rp_vec = vec_ld(0,rp);
+
+ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_4);
+ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED1_4);
+ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+ rp_vec = vec_add(rp_vec,avg_vec);
+
+ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_4);
+ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED2_4);
+ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+ rp_vec = vec_add(rp_vec,avg_vec);
+
+ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_4);
+ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED3_4);
+ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+ rp_vec = vec_add(rp_vec,avg_vec);
+
+ vec_st(rp_vec,0,rp);
+
+ rp += 16;
+ pp += 16;
+ istop -= 16;
+ }
+
+ if(istop > 0)
+ for (i = 0; i < istop % 16; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+ rp++;
+ }
+}
+
+void png_read_filter_row_avg3_vsx(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ const png_byte bpp = 3;
+
+ vector unsigned char rp_vec;
+ vector unsigned char pp_vec;
+ vector unsigned char pp_part_vec;
+ vector unsigned char rp_part_vec;
+ vector unsigned char avg_vec;
+
+ vsx_declare_common_vars(row_info,row,prev_row,bpp)
+ rp -= bpp;
+ if(istop >= bpp)
+ istop -= bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ ((int)(*pp++) / 2 )) & 0xff);
+
+ rp++;
+ }
+
+ /* Altivec operations require 16-byte aligned data
+ * but input can be unaligned. So we calculate
+ * unaligned part as usual.
+ */
+ for (i = 0; i < unaligned_top; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+ rp++;
+ }
+
+ /* Using SIMD while we can */
+ while( istop >= 16 )
+ {
+ for(i=0;i < bpp ; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+ rp++;
+ }
+ rp -= bpp;
+ pp -= bpp;
+
+ vec_ld_unaligned(pp_vec,pp);
+ rp_vec = vec_ld(0,rp);
+
+ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_3);
+ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED1_3);
+ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+ rp_vec = vec_add(rp_vec,avg_vec);
+
+ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_3);
+ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED2_3);
+ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+ rp_vec = vec_add(rp_vec,avg_vec);
+
+ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_3);
+ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED3_3);
+ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+ rp_vec = vec_add(rp_vec,avg_vec);
+
+ rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED4_3);
+ pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED4_3);
+ avg_vec = vec_avg(rp_part_vec,pp_part_vec);
+ avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
+ rp_vec = vec_add(rp_vec,avg_vec);
+
+ vec_st(rp_vec,0,rp);
+
+ rp += 15;
+ pp += 15;
+ istop -= 16;
+
+ /* Since 16 % bpp = 16 % 3 = 1, last element of array must
+ * be proceeded manually
+ */
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+ rp++;
+ }
+
+ if(istop > 0)
+ for (i = 0; i < istop % 16; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+ rp++;
+ }
+}
+
+/* Bytewise c ? t : e. */
+#define if_then_else(c,t,e) vec_sel(e,t,c)
+
+#define vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) {\
+ c = *(pp - bpp);\
+ a = *(rp - bpp);\
+ b = *pp++;\
+ p = b - c;\
+ pc = a - c;\
+ pa = vsx_abs(p);\
+ pb = vsx_abs(pc);\
+ pc = vsx_abs(p + pc);\
+ if (pb < pa) pa = pb, a = b;\
+ if (pc < pa) a = c;\
+ a += *rp;\
+ *rp++ = (png_byte)a;\
+ }
+
+void png_read_filter_row_paeth4_vsx(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ const png_byte bpp = 4;
+
+ int a, b, c, pa, pb, pc, p;
+ vector unsigned char rp_vec;
+ vector unsigned char pp_vec;
+ vector unsigned short a_vec,b_vec,c_vec,nearest_vec;
+ vector signed short pa_vec,pb_vec,pc_vec,smallest_vec;
+
+ vsx_declare_common_vars(row_info,row,prev_row,bpp)
+ rp -= bpp;
+ if(istop >= bpp)
+ istop -= bpp;
+
+ /* Process the first pixel in the row completely (this is the same as 'up'
+ * because there is only one candidate predictor for the first row).
+ */
+ for(i = 0; i < bpp ; i++)
+ {
+ *rp = (png_byte)( *rp + *pp);
+ rp++;
+ pp++;
+ }
+
+ for(i = 0; i < unaligned_top ; i++)
+ {
+ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+ }
+
+ while( istop >= 16)
+ {
+ for(i = 0; i < bpp ; i++)
+ {
+ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+ }
+
+ rp -= bpp;
+ pp -= bpp;
+ rp_vec = vec_ld(0,rp);
+ vec_ld_unaligned(pp_vec,pp);
+
+ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_4),1,4);
+ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED1_4),1,4);
+ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_4),1,4);
+ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+ pc_vec = vec_add(pa_vec,pb_vec);
+ pa_vec = vec_abs(pa_vec);
+ pb_vec = vec_abs(pb_vec);
+ pc_vec = vec_abs(pc_vec);
+ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+ nearest_vec = if_then_else(
+ vec_cmpeq(pa_vec,smallest_vec),
+ a_vec,
+ if_then_else(
+ vec_cmpeq(pb_vec,smallest_vec),
+ b_vec,
+ c_vec
+ )
+ );
+ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,1,4)));
+
+ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_4),2,4);
+ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED2_4),2,4);
+ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_4),2,4);
+ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+ pc_vec = vec_add(pa_vec,pb_vec);
+ pa_vec = vec_abs(pa_vec);
+ pb_vec = vec_abs(pb_vec);
+ pc_vec = vec_abs(pc_vec);
+ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+ nearest_vec = if_then_else(
+ vec_cmpeq(pa_vec,smallest_vec),
+ a_vec,
+ if_then_else(
+ vec_cmpeq(pb_vec,smallest_vec),
+ b_vec,
+ c_vec
+ )
+ );
+ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,2,4)));
+
+ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_4),3,4);
+ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED3_4),3,4);
+ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_4),3,4);
+ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+ pc_vec = vec_add(pa_vec,pb_vec);
+ pa_vec = vec_abs(pa_vec);
+ pb_vec = vec_abs(pb_vec);
+ pc_vec = vec_abs(pc_vec);
+ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+ nearest_vec = if_then_else(
+ vec_cmpeq(pa_vec,smallest_vec),
+ a_vec,
+ if_then_else(
+ vec_cmpeq(pb_vec,smallest_vec),
+ b_vec,
+ c_vec
+ )
+ );
+ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,3,4)));
+
+ vec_st(rp_vec,0,rp);
+
+ rp += 16;
+ pp += 16;
+ istop -= 16;
+ }
+
+ if(istop > 0)
+ for (i = 0; i < istop % 16; i++)
+ {
+ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+ }
+}
+
+void png_read_filter_row_paeth3_vsx(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ const png_byte bpp = 3;
+
+ int a, b, c, pa, pb, pc, p;
+ vector unsigned char rp_vec;
+ vector unsigned char pp_vec;
+ vector unsigned short a_vec,b_vec,c_vec,nearest_vec;
+ vector signed short pa_vec,pb_vec,pc_vec,smallest_vec;
+
+ vsx_declare_common_vars(row_info,row,prev_row,bpp)
+ rp -= bpp;
+ if(istop >= bpp)
+ istop -= bpp;
+
+ /* Process the first pixel in the row completely (this is the same as 'up'
+ * because there is only one candidate predictor for the first row).
+ */
+ for(i = 0; i < bpp ; i++)
+ {
+ *rp = (png_byte)( *rp + *pp);
+ rp++;
+ pp++;
+ }
+
+ for(i = 0; i < unaligned_top ; i++)
+ {
+ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+ }
+
+ while( istop >= 16)
+ {
+ for(i = 0; i < bpp ; i++)
+ {
+ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+ }
+
+ rp -= bpp;
+ pp -= bpp;
+ rp_vec = vec_ld(0,rp);
+ vec_ld_unaligned(pp_vec,pp);
+
+ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_3),1,3);
+ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED1_3),1,3);
+ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_3),1,3);
+ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+ pc_vec = vec_add(pa_vec,pb_vec);
+ pa_vec = vec_abs(pa_vec);
+ pb_vec = vec_abs(pb_vec);
+ pc_vec = vec_abs(pc_vec);
+ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+ nearest_vec = if_then_else(
+ vec_cmpeq(pa_vec,smallest_vec),
+ a_vec,
+ if_then_else(
+ vec_cmpeq(pb_vec,smallest_vec),
+ b_vec,
+ c_vec
+ )
+ );
+ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,1,3)));
+
+ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_3),2,3);
+ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED2_3),2,3);
+ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_3),2,3);
+ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+ pc_vec = vec_add(pa_vec,pb_vec);
+ pa_vec = vec_abs(pa_vec);
+ pb_vec = vec_abs(pb_vec);
+ pc_vec = vec_abs(pc_vec);
+ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+ nearest_vec = if_then_else(
+ vec_cmpeq(pa_vec,smallest_vec),
+ a_vec,
+ if_then_else(
+ vec_cmpeq(pb_vec,smallest_vec),
+ b_vec,
+ c_vec
+ )
+ );
+ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,2,3)));
+
+ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_3),3,3);
+ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED3_3),3,3);
+ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_3),3,3);
+ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+ pc_vec = vec_add(pa_vec,pb_vec);
+ pa_vec = vec_abs(pa_vec);
+ pb_vec = vec_abs(pb_vec);
+ pc_vec = vec_abs(pc_vec);
+ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+ nearest_vec = if_then_else(
+ vec_cmpeq(pa_vec,smallest_vec),
+ a_vec,
+ if_then_else(
+ vec_cmpeq(pb_vec,smallest_vec),
+ b_vec,
+ c_vec
+ )
+ );
+ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,3,3)));
+
+ a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED4_3),4,3);
+ b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED4_3),4,3);
+ c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED4_3),4,3);
+ pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
+ pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
+ pc_vec = vec_add(pa_vec,pb_vec);
+ pa_vec = vec_abs(pa_vec);
+ pb_vec = vec_abs(pb_vec);
+ pc_vec = vec_abs(pc_vec);
+ smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
+ nearest_vec = if_then_else(
+ vec_cmpeq(pa_vec,smallest_vec),
+ a_vec,
+ if_then_else(
+ vec_cmpeq(pb_vec,smallest_vec),
+ b_vec,
+ c_vec
+ )
+ );
+ rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,4,3)));
+
+ vec_st(rp_vec,0,rp);
+
+ rp += 15;
+ pp += 15;
+ istop -= 16;
+
+ /* Since 16 % bpp = 16 % 3 = 1, last element of array must
+ * be proceeded manually
+ */
+ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+ }
+
+ if(istop > 0)
+ for (i = 0; i < istop % 16; i++)
+ {
+ vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
+ }
+}
+
+#endif /* PNG_POWERPC_VSX_OPT > 0 */
+#endif /* PNG_POWERPC_VSX_IMPLEMENTATION == 1 (intrinsics) */
+#endif /* READ */
diff --git a/xs/src/png/libpng/powerpc/powerpc_init.c b/xs/src/png/libpng/powerpc/powerpc_init.c
new file mode 100644
index 000000000..07016177c
--- /dev/null
+++ b/xs/src/png/libpng/powerpc/powerpc_init.c
@@ -0,0 +1,125 @@
+
+/* powerpc_init.c - POWERPC optimised filter functions
+ *
+ * Copyright (c) 2017 Glenn Randers-Pehrson
+ * Written by Vadim Barkov, 2017.
+ * Last changed in libpng 1.6.29 [March 16, 2017]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
+ * called.
+ */
+#define _POSIX_SOURCE 1
+
+#include <stdio.h>
+#include "../pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+#if PNG_POWERPC_VSX_OPT > 0
+#ifdef PNG_POWERPC_VSX_CHECK_SUPPORTED /* Do run-time checks */
+/* WARNING: it is strongly recommended that you do not build libpng with
+ * run-time checks for CPU features if at all possible. In the case of the PowerPC
+ * VSX instructions there is no processor-specific way of detecting the
+ * presence of the required support, therefore run-time detection is extremely
+ * OS specific.
+ *
+ * You may set the macro PNG_POWERPC_VSX_FILE to the file name of file containing
+ * a fragment of C source code which defines the png_have_vsx function. There
+ * are a number of implementations in contrib/powerpc-vsx, but the only one that
+ * has partial support is contrib/powerpc-vsx/linux.c - a generic Linux
+ * implementation which reads /proc/cpufino.
+ */
+#ifndef PNG_POWERPC_VSX_FILE
+# ifdef __linux__
+# define PNG_POWERPC_VSX_FILE "contrib/powerpc-vsx/linux_aux.c"
+# endif
+#endif
+
+#ifdef PNG_POWERPC_VSX_FILE
+
+#include <signal.h> /* for sig_atomic_t */
+static int png_have_vsx(png_structp png_ptr);
+#include PNG_POWERPC_VSX_FILE
+
+#else /* PNG_POWERPC_VSX_FILE */
+# error "PNG_POWERPC_VSX_FILE undefined: no support for run-time POWERPC VSX checks"
+#endif /* PNG_POWERPC_VSX_FILE */
+#endif /* PNG_POWERPC_VSX_CHECK_SUPPORTED */
+
+void
+png_init_filter_functions_vsx(png_structp pp, unsigned int bpp)
+{
+ /* The switch statement is compiled in for POWERPC_VSX_API, the call to
+ * png_have_vsx is compiled in for POWERPC_VSX_CHECK. If both are defined
+ * the check is only performed if the API has not set the PowerPC option on
+ * or off explicitly. In this case the check controls what happens.
+ */
+
+#ifdef PNG_POWERPC_VSX_API_SUPPORTED
+ switch ((pp->options >> PNG_POWERPC_VSX) & 3)
+ {
+ case PNG_OPTION_UNSET:
+ /* Allow the run-time check to execute if it has been enabled -
+ * thus both API and CHECK can be turned on. If it isn't supported
+ * this case will fall through to the 'default' below, which just
+ * returns.
+ */
+#endif /* PNG_POWERPC_VSX_API_SUPPORTED */
+#ifdef PNG_POWERPC_VSX_CHECK_SUPPORTED
+ {
+ static volatile sig_atomic_t no_vsx = -1; /* not checked */
+
+ if (no_vsx < 0)
+ no_vsx = !png_have_vsx(pp);
+
+ if (no_vsx)
+ return;
+ }
+#ifdef PNG_POWERPC_VSX_API_SUPPORTED
+ break;
+#endif
+#endif /* PNG_POWERPC_VSX_CHECK_SUPPORTED */
+
+#ifdef PNG_POWERPC_VSX_API_SUPPORTED
+ default: /* OFF or INVALID */
+ return;
+
+ case PNG_OPTION_ON:
+ /* Option turned on */
+ break;
+ }
+#endif
+
+ /* IMPORTANT: any new internal functions used here must be declared using
+ * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the
+ * 'prefix' option to configure works:
+ *
+ * ./configure --with-libpng-prefix=foobar_
+ *
+ * Verify you have got this right by running the above command, doing a build
+ * and examining pngprefix.h; it must contain a #define for every external
+ * function you add. (Notice that this happens automatically for the
+ * initialization function.)
+ */
+ pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_vsx;
+
+ if (bpp == 3)
+ {
+ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_vsx;
+ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_vsx;
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_vsx;
+ }
+
+ else if (bpp == 4)
+ {
+ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_vsx;
+ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_vsx;
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_vsx;
+ }
+}
+#endif /* PNG_POWERPC_VSX_OPT > 0 */
+#endif /* READ */
diff --git a/xs/src/png/libpng/scripts/checksym.awk b/xs/src/png/libpng/scripts/checksym.awk
new file mode 100755
index 000000000..fe3af55e0
--- /dev/null
+++ b/xs/src/png/libpng/scripts/checksym.awk
@@ -0,0 +1,173 @@
+#!/bin/awk -f
+# Check a list of symbols against the master definition
+# (official) list. Arguments:
+#
+# awk -f checksym.awk official-def list-to-check
+#
+# Output is a file in the current directory called 'symbols.new',
+# the value of the awk variable "of" (which can be changed on the
+# command line if required.) stdout holds error messages. Error
+# code indicates success or failure.
+#
+# NOTE: this is a pure, old fashioned, awk script. It will
+# work with any awk
+
+BEGIN{
+ err=0
+ master="" # master file
+ official[1] = "" # defined symbols from master file
+ symbol[1] = "" # defined symbols from png.h
+ removed[1] = "" # removed symbols from png.h
+ lasto = 0 # last ordinal value from png.h
+ mastero = 0 # highest ordinal in master file
+ symbolo = 0 # highest ordinal in png.h
+ missing = "error"# log an error on missing symbols
+ of="symbols.new" # default to a fixed name
+}
+
+# Read existing definitions from the master file (the first
+# file on the command line.) This must be a def file and it
+# has definition lines (others are ignored) of the form:
+#
+# symbol @ordinal
+#
+master == "" {
+ master = FILENAME
+}
+FILENAME==master && NF==2 && $2~/^@/ && $1!~/^;/ {
+ o=0+substr($2,2)
+ if (o > 0) {
+ if (official[o] == "") {
+ official[o] = $1
+ if (o > mastero) mastero = o
+ next
+ } else
+ print master ": duplicated symbol:", official[o] ":", $0
+ } else
+ print master ": bad export line format:", $0
+ err = 1
+}
+FILENAME==master && $1==";missing" && NF==2{
+ # This allows the master file to control how missing symbols
+ # are handled; symbols that aren't in either the master or
+ # the new file. Valid values are 'ignore', 'warning' and
+ # 'error'
+ missing = $2
+}
+FILENAME==master {
+ next
+}
+
+# Read new definitions, these are free form but the lines must
+# just be symbol definitions. Lines will be commented out for
+# 'removed' symbols, introduced in png.h using PNG_REMOVED rather
+# than PNG_EXPORT. Use symbols.dfn or pngwin.dfn to generate the
+# input file.
+#
+# symbol @ordinal # two fields, exported symbol
+# ; symbol @ordinal # three fields, removed symbol
+# ; @ordinal # two fields, the last ordinal
+NF==2 && $1 == ";" && $2 ~ /^@[1-9][0-9]*$/ { # last ordinal
+ o=0+substr($2,2)
+ if (lasto == 0 || lasto == o)
+ lasto=o
+ else {
+ print "png.h: duplicated last ordinal:", lasto, o
+ err = 1
+ }
+ next
+}
+NF==3 && $1 == ";" && $3 ~ /^@[1-9][0-9]*$/ { # removed symbol
+ o=0+substr($3,2)
+ if (removed[o] == "" || removed[o] == $2) {
+ removed[o] = $2
+ if (o > symbolo) symbolo = o
+ } else {
+ print "png.h: duplicated removed symbol", o ": '" removed[o] "' != '" $2 "'"
+ err = 1
+ }
+ next
+}
+NF==2 && $2 ~ /^@[1-9][0-9]*$/ { # exported symbol
+ o=0+substr($2,2)
+ if (symbol[o] == "" || symbol[o] == $1) {
+ symbol[o] = $1
+ if (o > symbolo) symbolo = o
+ } else {
+ print "png.h: duplicated symbol", o ": '" symbol[o] "' != '" $1 "'"
+ err = 1
+ }
+}
+{
+ next # skip all other lines
+}
+
+# At the end check for symbols marked as both duplicated and removed
+END{
+ if (symbolo > lasto) {
+ print "highest symbol ordinal in png.h,", symbolo ", exceeds last ordinal from png.h", lasto
+ err = 1
+ }
+ if (mastero > lasto) {
+ print "highest symbol ordinal in", master ",", mastero ", exceeds last ordinal from png.h", lasto
+ err = 1
+ }
+ unexported=0
+ # Add a standard header to symbols.new:
+ print ";Version INSERT-VERSION-HERE" >of
+ print ";--------------------------------------------------------------" >of
+ print "; LIBPNG symbol list as a Win32 DEF file" >of
+ print "; Contains all the symbols that can be exported from libpng" >of
+ print ";--------------------------------------------------------------" >of
+ print "LIBRARY" >of
+ print "" >of
+ print "EXPORTS" >of
+
+ for (o=1; o<=lasto; ++o) {
+ if (symbol[o] == "" && removed[o] == "") {
+ if (unexported == 0) unexported = o
+ if (official[o] == "") {
+ # missing in export list too, so ok
+ if (o < lasto) continue
+ }
+ }
+ if (unexported != 0) {
+ # Symbols in the .def but not in the new file are errors, but
+ # the 'unexported' symbols aren't in either. By default this
+ # is an error too (see the setting of 'missing' at the start),
+ # but this can be reset on the command line or by stuff in the
+ # file - see the comments above.
+ if (missing != "ignore") {
+ if (o-1 > unexported)
+ print "png.h:", missing ": missing symbols:", unexported "-" o-1
+ else
+ print "png.h:", missing ": missing symbol:", unexported
+ if (missing != "warning")
+ err = 1
+ }
+ unexported = 0
+ }
+ if (symbol[o] != "" && removed[o] != "") {
+ print "png.h: symbol", o, "both exported as '" symbol[o] "' and removed as '" removed[o] "'"
+ err = 1
+ } else if (symbol[o] != official[o]) {
+ # either the symbol is missing somewhere or it changed
+ err = 1
+ if (symbol[o] == "")
+ print "png.h: symbol", o, "is exported as '" official[o] "' in", master
+ else if (official[o] == "")
+ print "png.h: exported symbol", o, "'" symbol[o] "' not present in", master
+ else
+ print "png.h: exported symbol", o, "'" symbol[o] "' exists as '" official[o] "' in", master
+ }
+
+ # Finally generate symbols.new
+ if (symbol[o] != "")
+ print " " symbol[o], "@" o > of
+ }
+
+ if (err != 0) {
+ print "*** A new list is in", of, "***"
+ exit 1
+ }
+}
diff --git a/xs/src/png/libpng/scripts/def.c b/xs/src/png/libpng/scripts/def.c
new file mode 100644
index 000000000..0ffcbeb0c
--- /dev/null
+++ b/xs/src/png/libpng/scripts/def.c
@@ -0,0 +1,29 @@
+/* def.c - define format of libpng.def
+ *
+ * Last changed in libpng version 1.6.16 [December 22, 2014]
+ * Copyright (c) 2011-2014 Glenn Randers-Pehrson
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* Write the export file header: */
+PNG_DFN ";--------------------------------------------------------------"
+PNG_DFN "; LIBPNG module definition file for OS/2"
+PNG_DFN ";--------------------------------------------------------------"
+PNG_DFN ""
+PNG_DFN "; If you give the library an explicit name one or other files"
+PNG_DFN "; may need modifying to support the new name on one or more"
+PNG_DFN "; systems."
+PNG_DFN "LIBRARY"
+PNG_DFN "OS2 DESCRIPTION "PNG image compression library""
+PNG_DFN "OS2 CODE PRELOAD MOVEABLE DISCARDABLE"
+PNG_DFN ""
+PNG_DFN "EXPORTS"
+PNG_DFN ";Version 1.6.35beta02"
+
+#define PNG_EXPORTA(ordinal, type, name, args, attributes)\
+ PNG_DFN "@" SYMBOL_PREFIX "@@" name "@"
+
+#include "../png.h"
diff --git a/xs/src/png/libpng/scripts/dfn.awk b/xs/src/png/libpng/scripts/dfn.awk
new file mode 100755
index 000000000..346b9db7d
--- /dev/null
+++ b/xs/src/png/libpng/scripts/dfn.awk
@@ -0,0 +1,203 @@
+#!/bin/awk -f
+# scripts/dfn.awk - process a .dfn file
+#
+# last changed in libpng version 1.5.19 - August 21, 2014
+#
+# Copyright (c) 2013-2014 Glenn Randers-Pehrson
+#
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+# The output of this script is written to the file given by
+# the variable 'out', which should be set on the command line.
+# Error messages are printed to stdout and if any are printed
+# the script will exit with error code 1.
+
+BEGIN{
+ out="/dev/null" # as a flag
+ out_count=0 # count of output lines
+ err=0 # set if an error occurred
+ sort=0 # sort the output
+ array[""]=""
+}
+
+# The output file must be specified before any input:
+NR==1 && out == "/dev/null" {
+ print "out=output.file must be given on the command line"
+ # but continue without setting the error code; this allows the
+ # script to be checked easily
+}
+
+# Output can be sorted; two lines are recognized
+$1 == "PNG_DFN_START_SORT"{
+ sort=0+$2
+ next
+}
+
+$1 ~ /^PNG_DFN_END_SORT/{
+ # Do a very simple, slow, sort; notice that blank lines won't be
+ # output by this
+ for (entry in array) {
+ while (array[entry] != "") {
+ key = entry
+ value = array[key]
+ array[key] = ""
+
+ for (alt in array) {
+ if (array[alt] != "" && alt < key) {
+ array[key] = value
+ value = array[alt]
+ key = alt
+ array[alt] = ""
+ }
+ }
+
+ print value >out
+ }
+ }
+ sort=0
+ next
+}
+
+/^[^"]*PNG_DFN *".*"[^"]*$/{
+ # A definition line, apparently correctly formatted; extract the
+ # definition then replace any doubled "" that remain with a single
+ # double quote. Notice that the original doubled double quotes
+ # may have been split by tokenization
+ #
+ # Sometimes GCC splits the PNG_DFN lines; we know this has happened
+ # if the quotes aren't closed and must read another line. In this
+ # case it is essential to reject lines that start with '#' because those
+ # are introduced #line directives.
+ orig=$0
+ line=$0
+ lineno=FNR
+ if (lineno == "") lineno=NR
+
+ if (sub(/^[^"]*PNG_DFN *"/,"",line) != 1) {
+ print "line", lineno ": processing failed:"
+ print orig
+ err=1
+ next
+ } else {
+ ++out_count
+ }
+
+ # Now examine quotes within the value:
+ #
+ # @" - delete this and any following spaces
+ # "@ - delete this and any preceding spaces
+ # @' - replace this by a double quote
+ #
+ # This allows macro substitution by the C compiler thus:
+ #
+ # #define first_name John
+ # #define last_name Smith
+ #
+ # PNG_DFN"#define name @'@" first_name "@ @" last_name "@@'"
+ #
+ # Might get C preprocessed to:
+ #
+ # PNG_DFN "#define foo @'@" John "@ @" Smith "@@'"
+ #
+ # Which this script reduces to:
+ #
+ # #define name "John Smith"
+ #
+ while (1) {
+ # While there is an @" remove it and the next "@
+ if (line ~ /@"/) {
+ if (line ~ /@".*"@/) {
+ # Do this special case first to avoid swallowing extra spaces
+ # before or after the @ stuff:
+ if (!sub(/@" *"@/, "", line)) {
+ # Ok, do it in pieces - there has to be a non-space between the
+ # two. NOTE: really weird things happen if a leading @" is
+ # lost - the code will error out below (I believe).
+ if (!sub(/@" */, "", line) || !sub(/ *"@/, "", line)) {
+ print "line", lineno, ": internal error:", orig
+ exit 1
+ }
+ }
+ }
+
+ # There is no matching "@. Assume a split line
+ else while (1) {
+ if (getline nextline) {
+ # If the line starts with '#' it is a preprocesor line directive
+ # from cc -E; skip it:
+ if (nextline !~ /^#/) {
+ line = line " " nextline
+ break
+ }
+ } else {
+ # This is end-of-input - probably a missing "@ on the first line:
+ print "line", lineno ": unbalanced @\" ... \"@ pair"
+ err=1
+ next
+ }
+ }
+
+ # Keep going until all the @" have gone
+ continue
+ }
+
+ # Attempt to remove a trailing " (not preceded by '@') - if this can
+ # be done, stop now; if not assume a split line again
+ if (sub(/"[^"]*$/, "", line))
+ break
+
+ # Read another line
+ while (1) {
+ if (getline nextline) {
+ if (nextline !~ /^#/) {
+ line = line " " nextline
+ # Go back to stripping @" "@ pairs
+ break
+ }
+ } else {
+ print "line", lineno ": unterminated PNG_DFN string"
+ err=1
+ next
+ }
+ }
+ }
+
+ # Put any needed double quotes in (at the end, because these would otherwise
+ # interfere with the processing above.)
+ gsub(/@'/,"\"", line)
+
+ # Remove any trailing spaces (not really required, but for
+ # editorial consistency
+ sub(/ *$/, "", line)
+
+ # Remove trailing CR
+ sub(/ $/, "", line)
+
+ if (sort) {
+ if (split(line, parts) < sort) {
+ print "line", lineno ": missing sort field:", line
+ err=1
+ } else
+ array[parts[sort]] = line
+ }
+
+ else
+ print line >out
+ next
+}
+
+/PNG_DFN/{
+ print "line", NR, "incorrectly formatted PNG_DFN line:"
+ print $0
+ err = 1
+}
+
+END{
+ if (out_count > 0 || err > 0)
+ exit err
+
+ print "no definition lines found"
+ exit 1
+}
diff --git a/xs/src/png/libpng/scripts/genchk.cmake.in b/xs/src/png/libpng/scripts/genchk.cmake.in
new file mode 100644
index 000000000..ab3b9d746
--- /dev/null
+++ b/xs/src/png/libpng/scripts/genchk.cmake.in
@@ -0,0 +1,37 @@
+# genchk.cmake.in
+# Generate .chk from .out with awk (generic), based upon the automake logic.
+
+# Copyright (C) 2016 Glenn Randers-Pehrson
+# Written by Roger Leigh, 2016
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+# Variables substituted from CMakeLists.txt
+set(SRCDIR "@CMAKE_CURRENT_SOURCE_DIR@")
+
+set(AWK "@AWK@")
+
+get_filename_component(INPUTEXT "${INPUT}" EXT)
+get_filename_component(OUTPUTEXT "${OUTPUT}" EXT)
+get_filename_component(INPUTBASE "${INPUT}" NAME_WE)
+get_filename_component(OUTPUTBASE "${OUTPUT}" NAME_WE)
+get_filename_component(INPUTDIR "${INPUT}" PATH)
+get_filename_component(OUTPUTDIR "${OUTPUT}" PATH)
+
+if("${INPUTEXT}" STREQUAL ".out" AND "${OUTPUTEXT}" STREQUAL ".chk")
+ # Generate .chk from .out with awk (generic)
+ file(REMOVE "${OUTPUT}" "${OUTPUTDIR}/${OUTPUTBASE}.new")
+ execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/checksym.awk"
+ "${SRCDIR}/scripts/${INPUTBASE}.def"
+ "of=${OUTPUTDIR}/${OUTPUTBASE}.new"
+ "${INPUT}"
+ RESULT_VARIABLE AWK_FAIL)
+ if(AWK_FAIL)
+ message(FATAL_ERROR "Failed to generate ${OUTPUTDIR}/${OUTPUTBASE}.new")
+ endif()
+ file(RENAME "${OUTPUTDIR}/${OUTPUTBASE}.new" "${OUTPUT}")
+else()
+ message(FATAL_ERROR "Unsupported conversion: ${INPUTEXT} to ${OUTPUTEXT}")
+endif()
diff --git a/xs/src/png/libpng/scripts/genout.cmake.in b/xs/src/png/libpng/scripts/genout.cmake.in
new file mode 100644
index 000000000..01f12de2f
--- /dev/null
+++ b/xs/src/png/libpng/scripts/genout.cmake.in
@@ -0,0 +1,93 @@
+# genout.cmake.in
+# Generate .out from .c with awk (generic), based upon the automake logic.
+
+# Copyright (C) 2016 Glenn Randers-Pehrson
+# Written by Roger Leigh, 2016
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+# Variables substituted from CMakeLists.txt
+set(SRCDIR "@CMAKE_CURRENT_SOURCE_DIR@")
+set(BINDIR "@CMAKE_CURRENT_BINARY_DIR@")
+
+set(AWK "@AWK@")
+set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@")
+set(CMAKE_C_FLAGS @CMAKE_C_FLAGS@)
+set(INCDIR "@CMAKE_CURRENT_BINARY_DIR@")
+set(PNG_PREFIX "@PNG_PREFIX@")
+set(PNGLIB_MAJOR "@PNGLIB_MAJOR@")
+set(PNGLIB_MINOR "@PNGLIB_MINOR@")
+set(PNGLIB_VERSION "@PNGLIB_VERSION@")
+set(ZLIBINCDIR "@ZLIB_INCLUDE_DIR@")
+
+set(PLATFORM_C_FLAGS)
+if(APPLE)
+ set(CMAKE_OSX_ARCHITECTURES "@CMAKE_OSX_ARCHITECTURES@")
+ set(CMAKE_OSX_SYSROOT "@CMAKE_OSX_SYSROOT@")
+ if(CMAKE_OSX_ARCHITECTURES)
+ set(PLATFORM_C_FLAGS ${PLATFORM_C_FLAGS} -arch ${CMAKE_OSX_ARCHITECTURES})
+ endif()
+ if(CMAKE_OSX_SYSROOT)
+ set(PLATFORM_C_FLAGS ${PLATFORM_C_FLAGS} -isysroot ${CMAKE_OSX_SYSROOT})
+ endif()
+endif()
+
+get_filename_component(INPUTEXT "${INPUT}" EXT)
+get_filename_component(OUTPUTEXT "${OUTPUT}" EXT)
+get_filename_component(INPUTBASE "${INPUT}" NAME_WE)
+get_filename_component(OUTPUTBASE "${OUTPUT}" NAME_WE)
+get_filename_component(INPUTDIR "${INPUT}" PATH)
+get_filename_component(OUTPUTDIR "${OUTPUT}" PATH)
+
+if ("${INPUTEXT}" STREQUAL ".c" AND "${OUTPUTEXT}" STREQUAL ".out")
+ get_filename_component(GENDIR "${OUTPUT}" PATH)
+ file(MAKE_DIRECTORY "${GENDIR}")
+
+ file(REMOVE "${OUTPUT}.tf1" "${OUTPUT}.tf2")
+
+ set(INCLUDES "-I${INCDIR}")
+ if(ZLIBINCDIR)
+ foreach(dir ${ZLIBINCDIR})
+ list(APPEND INCLUDES "-I${dir}")
+ endforeach()
+ endif()
+
+ if(PNG_PREFIX)
+ set(PNG_PREFIX_DEF "-DPNG_PREFIX=${PNG_PREFIX}")
+ endif()
+
+ execute_process(COMMAND "${CMAKE_C_COMPILER}" "-E"
+ ${CMAKE_C_FLAGS}
+ ${PLATFORM_C_FLAGS}
+ "-I${SRCDIR}"
+ "-I${BINDIR}"
+ ${INCLUDES}
+ "-DPNGLIB_LIBNAME=PNG${PNGLIB_MAJOR}${PNGLIB_MINOR}_0"
+ "-DPNGLIB_VERSION=${PNGLIB_VERSION}"
+ "-DSYMBOL_PREFIX=${SYMBOL_PREFIX}"
+ "-DPNG_NO_USE_READ_MACROS"
+ "-DPNG_BUILDING_SYMBOL_TABLE"
+ ${PNG_PREFIX_DEF}
+ "${INPUT}"
+ OUTPUT_FILE "${OUTPUT}.tf1"
+ WORKING_DIRECTORY "${BINDIR}"
+ RESULT_VARIABLE CPP_FAIL)
+ if(CPP_FAIL)
+ message(FATAL_ERROR "Failed to generate ${OUTPUT}.tf1")
+ endif()
+
+ execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/dfn.awk"
+ "out=${OUTPUT}.tf2" "${OUTPUT}.tf1"
+ WORKING_DIRECTORY "${BINDIR}"
+ RESULT_VARIABLE AWK_FAIL)
+ if(AWK_FAIL)
+ message(FATAL_ERROR "Failed to generate ${OUTPUT}.tf2")
+ endif()
+
+ file(REMOVE "${OUTPUT}.tf1")
+ file(RENAME "${OUTPUT}.tf2" "${OUTPUT}")
+else()
+ message(FATAL_ERROR "Unsupported conversion: ${INPUTEXT} to ${OUTPUTEXT}")
+endif()
diff --git a/xs/src/png/libpng/scripts/gensrc.cmake.in b/xs/src/png/libpng/scripts/gensrc.cmake.in
new file mode 100644
index 000000000..f28a62266
--- /dev/null
+++ b/xs/src/png/libpng/scripts/gensrc.cmake.in
@@ -0,0 +1,138 @@
+# gensrc.cmake.in
+# Generate source files with awk, based upon the automake logic.
+
+# Copyright (C) 2016 Glenn Randers-Pehrson
+# Written by Roger Leigh, 2016
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+# Variables substituted from CMakeLists.txt
+set(SRCDIR "@CMAKE_CURRENT_SOURCE_DIR@")
+set(BINDIR "@CMAKE_CURRENT_BINARY_DIR@")
+
+set(AWK "@AWK@")
+set(DFA_XTRA "@DFA_XTRA@")
+set(PNG_PREFIX "@PNG_PREFIX@")
+set(PNGLIB_VERSION "@PNGLIB_VERSION@")
+
+if("${OUTPUT}" STREQUAL "scripts/pnglibconf.c")
+ # Generate scripts/pnglibconf.c
+
+ file(REMOVE "${BINDIR}/pnglibconf.tf6" "${BINDIR}/pnglibconf.tf7")
+
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "com ${PNGLIB_VERSION} STANDARD API DEFINITION"
+ COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk"
+ "out=pnglibconf.tf6" "logunsupported=1" "version=search"
+ "${SRCDIR}/pngconf.h" "-"
+ "${SRCDIR}/scripts/pnglibconf.dfa"
+ WORKING_DIRECTORY "${BINDIR}"
+ RESULT_VARIABLE AWK_FAIL)
+ if(AWK_FAIL)
+ message(FATAL_ERROR "Failed to generate pnglibconf.tf6")
+ endif()
+
+ execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk"
+ "out=pnglibconf.tf7" "pnglibconf.tf6"
+ WORKING_DIRECTORY "${BINDIR}"
+ RESULT_VARIABLE AWK_FAIL)
+ if(AWK_FAIL)
+ message(FATAL_ERROR "Failed to generate pnglibconf.tf7")
+ endif()
+
+ file(REMOVE "pnglibconf.tf6")
+ file(MAKE_DIRECTORY "${BINDIR}/scripts")
+ file(RENAME "pnglibconf.tf7" "${BINDIR}/scripts/pnglibconf.c")
+
+elseif ("${OUTPUT}" STREQUAL "pnglibconf.c")
+ # Generate pnglibconf.c
+
+ file(REMOVE "${BINDIR}/pnglibconf.tf4" "${BINDIR}/pnglibconf.tf5")
+
+ execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk"
+ out=pnglibconf.tf4 version=search
+ ${SRCDIR}/pngconf.h ${SRCDIR}/scripts/pnglibconf.dfa
+ ${SRCDIR}/pngusr.dfa ${DFA_XTRA}
+ WORKING_DIRECTORY "${BINDIR}"
+ RESULT_VARIABLE AWK_FAIL)
+ if(AWK_FAIL)
+ message(FATAL_ERROR "Failed to generate pnglibconf.tf4")
+ endif()
+
+ execute_process(COMMAND "${AWK}" -f "${SRCDIR}/scripts/options.awk"
+ out=pnglibconf.tf5 pnglibconf.tf4
+ WORKING_DIRECTORY "${BINDIR}"
+ RESULT_VARIABLE AWK_FAIL)
+ if(AWK_FAIL)
+ message(FATAL_ERROR "Failed to generate pnglibconf.tf5")
+ endif()
+
+ file(REMOVE "pnglibconf.tf4")
+ file(MAKE_DIRECTORY "${BINDIR}/scripts")
+ file(RENAME "pnglibconf.tf5" "${BINDIR}/pnglibconf.c")
+
+elseif ("${OUTPUT}" STREQUAL "pnglibconf.h")
+ # Generate pnglibconf.h
+
+ file(REMOVE "${BINDIR}/${OUTPUT}")
+ if(PNG_PREFIX)
+ file(REMOVE "pnglibconf.tf8")
+
+ execute_process(COMMAND "${AWK}" "s==0 && NR>1{print prev}
+ s==0{prev=\$0}
+ s==1{print \"#define\", \$1, \"${PNG_PREFIX}\" \$1}
+ s==2{print \"#define ${PNG_PREFIX}png_\" \$1, \"PNG_\" \$1}
+ END{print prev}" s=0 pnglibconf.out s=1 "${BINDIR}/scripts/prefix.out"
+ s=2 "${SRCDIR}/scripts/macro.lst"
+ OUTPUT_FILE pnglibconf.tf8
+ RESULT_VARIABLE AWK_FAIL)
+ if(AWK_FAIL)
+ message(FATAL_ERROR "Failed to generate pnglibconf.tf8")
+ endif()
+
+ file(RENAME "pnglibconf.tf8" "${BINDIR}/${OUTPUT}")
+ else()
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E copy "${BINDIR}/pnglibconf.out"
+ "${BINDIR}/${OUTPUT}"
+ RESULT_VARIABLE COPY_FAIL)
+ if(COPY_FAIL)
+ message(FATAL_ERROR "Failed to create pnglibconf.h")
+ endif()
+ endif()
+
+elseif ("${OUTPUT}" STREQUAL "pngprefix.h")
+ # Generate pngprefix.h
+
+ file(REMOVE "${BINDIR}/${OUTPUT}")
+
+ if(PNG_PREFIX)
+ file(REMOVE "pngprefix.tf1")
+
+ execute_process(COMMAND "${AWK}"
+ "{print \"#define\", \$1, \"${PNG_PREFIX}\" \$1}"
+ "${BINDIR}/scripts/intprefix.out"
+ OUTPUT_FILE "pngprefix.tf1"
+ RESULT_VARIABLE AWK_FAIL)
+ if(AWK_FAIL)
+ message(FATAL_ERROR "Failed to generate pngprefix.tf1")
+ endif()
+
+ file(RENAME "pngprefix.tf1" "${BINDIR}/${OUTPUT}")
+ else()
+ file(WRITE "${BINDIR}/${OUTPUT}" "/* No libpng symbol prefix configured. */")
+ endif()
+
+elseif("${OUTPUT}" STREQUAL "scripts/pnglibconf.h.prebuilt")
+ # Generate scripts/pnglibconf.h.prebuilt (fails build)
+
+ message(STATUS "Attempting to build scripts/pnglibconf.h.prebuilt")
+ message(STATUS "This is a machine generated file, but if you want to make")
+ message(STATUS "a new one simply build the 'genfiles' target, and copy")
+ message(STATUS "scripts/pnglibconf.out to scripts/pnglibconf.h.prebuilt")
+ message(STATUS "AND set PNG_ZLIB_VERNUM to 0 (you MUST do this)")
+ message(FATAL_ERROR "Stopping build")
+
+else()
+ message(FATAL_ERROR "Unsupported output: ${OUTPUT}")
+endif()
diff --git a/xs/src/png/libpng/scripts/intprefix.c b/xs/src/png/libpng/scripts/intprefix.c
new file mode 100644
index 000000000..254f8e94b
--- /dev/null
+++ b/xs/src/png/libpng/scripts/intprefix.c
@@ -0,0 +1,22 @@
+
+/* intprefix.c - generate an unprefixed internal symbol list
+ *
+ * Last changed in libpng version 1.6.16 [December 22, 2014]
+ * Copyright (c) 2013-2014 Glenn Randers-Pehrson
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_INTERNAL_DATA(type, name, array)\
+ PNG_DFN "@" name "@"
+
+#define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\
+ PNG_DFN "@" name "@"
+
+#define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\
+ PNG_DFN "@" name "@"
+
+#define PNGPREFIX_H /* self generation */
+#include "../pngpriv.h"
diff --git a/xs/src/png/libpng/scripts/libpng-config-body.in b/xs/src/png/libpng/scripts/libpng-config-body.in
new file mode 100644
index 000000000..b466432d5
--- /dev/null
+++ b/xs/src/png/libpng/scripts/libpng-config-body.in
@@ -0,0 +1,96 @@
+
+usage()
+{
+ cat <<EOF
+Usage: libpng-config [OPTION] ...
+
+Known values for OPTION are:
+
+ --prefix print libpng prefix
+ --libdir print path to directory containing library
+ --libs print library linking information
+ --ccopts print compiler options
+ --cppflags print pre-processor flags
+ --cflags print preprocessor flags, I_opts, and compiler options
+ --I_opts print "-I" include options
+ --L_opts print linker "-L" flags for dynamic linking
+ --R_opts print dynamic linker "-R" or "-rpath" flags
+ --ldopts print linker options
+ --ldflags print linker flags (ldopts, L_opts, R_opts, and libs)
+ --static revise subsequent outputs for static linking
+ --help print this help and exit
+ --version print version information
+EOF
+
+ exit $1
+}
+
+if test $# -eq 0; then
+ usage 1
+fi
+
+while test $# -gt 0; do
+ case "$1" in
+
+ --prefix)
+ echo ${prefix}
+ ;;
+
+ --version)
+ echo ${version}
+ exit 0
+ ;;
+
+ --help)
+ usage 0
+ ;;
+
+ --ccopts)
+ echo ${ccopts}
+ ;;
+
+ --cppflags)
+ echo ${cppflags}
+ ;;
+
+ --cflags)
+ echo ${I_opts} ${cppflags} ${ccopts}
+ ;;
+
+ --libdir)
+ echo ${libdir}
+ ;;
+
+ --libs)
+ echo ${libs}
+ ;;
+
+ --I_opts)
+ echo ${I_opts}
+ ;;
+
+ --L_opts)
+ echo ${L_opts}
+ ;;
+
+ --R_opts)
+ echo ${R_opts}
+ ;;
+
+ --ldflags)
+ echo ${ldflags} ${L_opts} ${R_opts} ${libs}
+ ;;
+
+ --static)
+ R_opts=""
+ ;;
+
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+exit 0
diff --git a/xs/src/png/libpng/scripts/libpng-config-head.in b/xs/src/png/libpng/scripts/libpng-config-head.in
new file mode 100644
index 000000000..64dd3987d
--- /dev/null
+++ b/xs/src/png/libpng/scripts/libpng-config-head.in
@@ -0,0 +1,24 @@
+#! /bin/sh
+
+# libpng-config
+# provides configuration info for libpng.
+
+# Copyright (C) 2002 Glenn Randers-Pehrson
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+# Modeled after libxml-config.
+
+version=1.6.34
+prefix=""
+libdir=""
+libs=""
+I_opts=""
+L_opts=""
+R_opts=""
+cppflags=""
+ccopts=""
+ldopts=""
+
diff --git a/xs/src/png/libpng/scripts/libpng.pc.in b/xs/src/png/libpng/scripts/libpng.pc.in
new file mode 100644
index 000000000..33c65767b
--- /dev/null
+++ b/xs/src/png/libpng/scripts/libpng.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/libpng16
+
+Name: libpng
+Description: Loads and saves PNG files
+Version: 1.6.34
+Libs: -L${libdir} -lpng16
+Cflags: -I${includedir}
diff --git a/xs/src/png/libpng/scripts/options.awk b/xs/src/png/libpng/scripts/options.awk
new file mode 100755
index 000000000..fef5dfd78
--- /dev/null
+++ b/xs/src/png/libpng/scripts/options.awk
@@ -0,0 +1,898 @@
+#!/bin/awk -f
+# scripts/options.awk - library build configuration control
+#
+# last changed in libpng version 1.6.11 - June 5, 2014
+#
+# Copyright (c) 1998-2014 Glenn Randers-Pehrson
+#
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+# The output of this script is written to the file given by
+# the variable 'out'. The script is run twice, once with
+# an intermediate output file, 'options.tmp' then again on
+# that file to produce the final output:
+#
+# awk -f scripts/options.awk out=options.tmp scripts/options.dfa 1>&2
+# awk -f scripts/options.awk out=options.dfn options.tmp 1>&2
+#
+# Some options may be specified on the command line:
+#
+# deb=1 Causes debugging to be output
+# logunsupported=1 Causes all options to be recorded in the output
+# everything=off Causes all options to be disabled by default
+# everything=on Causes all options to be enabled by default
+#
+# If awk fails on your platform, try nawk instead.
+#
+# These options may also be specified in the original input file (and
+# are copied to the preprocessed file).
+
+BEGIN{
+ out="" # intermediate, preprocessed, file
+ pre=-1 # preprocess (first line)
+ version="libpng version unknown" # version information
+ version_file="" # where to find the version
+ err=0 # in-line exit sets this
+ # The following definitions prevent the C preprocessor noticing the lines
+ # that will be in the final output file. Some C preprocessors tokenise
+ # the lines, for example by inserting spaces around operators, and all
+ # C preprocessors notice lines that start with '#', most remove comments.
+ # The technique adopted here is to make the final output lines into
+ # C strings (enclosed in double quotes), preceded by PNG_DFN. As a
+ # consequence the output cannot contain a 'raw' double quote - instead put
+ # @' in, this will be replaced by a single " afterward. See the parser
+ # script dfn.awk for more capabilities (not required here). Note that if
+ # you need a " in a 'setting' in pnglibconf.dfa it must also be @'!
+ dq="@'" # For a single double quote
+ start=" PNG_DFN \"" # Start stuff to output (can't contain a "!)
+ end="\" " # End stuff to output
+ subs="@\" " # Substitute start (substitute a C macro)
+ sube=" \"@" # Substitute end
+ comment=start "/*" # Comment start
+ cend="*/" end # Comment end
+ def=start "#define PNG_" # Arbitrary define
+ sup="_SUPPORTED" end # end supported option
+ und=comment "#undef PNG_" # Unsupported option
+ une="_SUPPORTED" cend # end unsupported option
+ error=start "ERROR:" # error message, terminate with 'end'
+
+ # Variables
+ deb=0 # debug - set on command line
+ everything="" # do not override defaults
+ logunsupported=0 # write unsupported options too
+
+ # Precreate arrays
+ # for each option:
+ option[""] = "" # list of all options: default enabled/disabled
+ done[""] = 1 # marks option as having been output
+ requires[""] = "" # requires by option
+ iffs[""] = "" # if by option
+ enabledby[""] = "" # options that enable it by option
+ sets[""] = "" # settings set by each option
+ setval[""] = "" # value to set (indexed: 'option sets[option]')
+ # for each setting:
+ setting[""] = "" # requires by setting
+ defaults[""] = "" # used for a defaulted value
+ doneset[""] = 1 # marks setting as having been output
+ r[""] = "" # Temporary array
+
+ # For decorating the output file
+ protect = ""
+}
+
+# The output file must be specified before any input:
+out == "" {
+ print "out=output.file must be given on the command line"
+ err = 1
+ exit 1
+}
+
+# The very first line indicates whether we are reading pre-processed
+# input or not, this must come *first* because 'PREPROCESSED' needs
+# to be the very first line in the temporary file.
+pre == -1{
+ if ($0 == "PREPROCESSED") {
+ pre = 0
+ next
+ } else {
+ pre = 1
+ print "PREPROCESSED" >out
+ # And fall through to continue processing
+ }
+}
+
+# While pre-processing if version is set to "search" look for a version string
+# in the following file.
+pre && version == "search" && version_file == ""{
+ version_file = FILENAME
+}
+
+pre && version == "search" && version_file != FILENAME{
+ print "version string not found in", version_file
+ err = 1
+ exit 1
+}
+
+pre && version == "search" && $0 ~ /^ \* libpng version/{
+ version = substr($0, 4)
+ print "version =", version >out
+ next
+}
+
+pre && FILENAME == version_file{
+ next
+}
+
+# variable=value
+# Sets the given variable to the given value (the syntax is fairly
+# free form, except for deb (you are expected to understand how to
+# set the debug variable...)
+#
+# This happens before the check on 'pre' below skips most of the
+# rest of the actions, so the variable settings happen during
+# preprocessing but are recorded in the END action too. This
+# allows them to be set on the command line too.
+$0 ~ /^[ ]*version[ ]*=/{
+ sub(/^[ ]*version[ ]*=[ ]*/, "")
+ version = $0
+ next
+}
+$0 ~ /^[ ]*everything[ =]*off[ ]*$/{
+ everything = "off"
+ next
+}
+$0 ~ /^[ ]*everything[ =]*on[ ]*$/{
+ everything = "on"
+ next
+}
+$0 ~ /^[ ]*logunsupported[ =]*0[ ]*$/{
+ logunsupported = 0
+ next
+}
+$0 ~ /^[ ]*logunsupported[ =]*1[ ]*$/{
+ logunsupported = 1
+ next
+}
+$1 == "deb" && $2 == "=" && NF == 3{
+ deb = $3
+ next
+}
+
+# Preprocessing - this just copies the input file with lines
+# that need preprocessing (just chunk at present) expanded
+# The bare "pre" instead of "pre != 0" crashes under Sunos awk
+pre && $1 != "chunk"{
+ print >out
+ next
+}
+
+# The first characters of the line determine how it is processed,
+# leading spaces are ignored. In general tokens that are not
+# keywords are the names of options. An option 'name' is
+# controlled by the definition of the corresponding macros:
+#
+# PNG_name_SUPPORTED The option is turned on
+# PNG_NO_name
+# PNG_NO_name_SUPPORTED If the first macro is not defined
+# either of these will turn the option off
+#
+# If none of these macros are defined the option is turned on, unless
+# the keyword 'off' is given in a line relating to the option. The
+# keyword 'on' can also be given, but it will be ignored (since it is
+# the default.)
+#
+# In the syntax below a 'name' is indicated by "NAME", other macro
+# values are indicated by "MACRO", as with "NAME" the leading "PNG_"
+# is omitted, but in this case the "NO_" prefix and the "_SUPPORTED"
+# suffix are never used.
+#
+# Each line is introduced by a keyword - the first non-space characters
+# on the line. A line starting with a '#' is a comment - it is totally
+# ignored. Keywords are as follows, a NAME, is simply a macro name
+# without the leading PNG_, PNG_NO_ or the trailing _SUPPORTED.
+
+$1 ~ /^#/ || $0 ~ /^[ ]*$/{
+ next
+}
+
+# com <comment>
+# The whole line is placed in the output file as a comment with
+# the preceding 'com' removed
+$1 == "com"{
+ if (NF > 1) {
+ # sub(/^[ ]*com[ ]*/, "")
+ $1 = ""
+ print comment $0, cend >out
+ } else
+ print start end >out
+ next
+}
+
+# version
+# Inserts a version comment
+$1 == "version" && NF == 1{
+ if (version == "") {
+ print "ERROR: no version string set"
+ err = 1 # prevent END{} running
+ exit 1
+ }
+
+ print comment, version, cend >out
+ next
+}
+
+# file output input protect
+# Informational: the official name of the input file (without
+# make generated local directories), the official name of the
+# output file and, if required, a name to use in a protection
+# macro for the contents.
+$1 == "file" && NF >= 2{
+ print comment, $2, cend >out
+ print comment, "Machine generated file: DO NOT EDIT", cend >out
+ if (NF >= 3)
+ print comment, "Derived from:", $3, cend >out
+ protect = $4
+ if (protect != "") {
+ print start "#ifndef", protect end >out
+ print start "#define", protect end >out
+ }
+ next
+}
+
+# option NAME ( (requires|enables|if) NAME* | on | off | disabled |
+# sets SETTING VALUE+ )*
+#
+# Declares an option 'NAME' and describes its default setting (disabled)
+# and its relationship to other options. The option is disabled
+# unless *all* the options listed after 'requires' are set and at
+# least one of the options listed after 'if' is set. If the
+# option is set then it turns on all the options listed after 'enables'.
+#
+# Note that "enables" takes priority over the required/if/disabled/off
+# setting of the target option.
+#
+# The definition file may list an option as 'disabled': off by default,
+# otherwise the option is enabled: on by default. A later (and it must
+# be later) entry may turn an option on or off explicitly.
+
+$1 == "option" && NF >= 2{
+ opt = $2
+ sub(/,$/,"",opt)
+ onoff = option[opt] # records current (and the default is "", enabled)
+ key = ""
+ istart = 3
+ do {
+ if (istart == 1) { # continuation line
+ val = getline
+
+ if (val != 1) { # error reading it
+ if (val == 0)
+ print "option", opt ": ERROR: missing continuation line"
+ else
+ print "option", opt ": ERROR: error reading continuation line"
+
+ # This is a hard error
+ err = 1 # prevent END{} running
+ exit 1
+ }
+ }
+
+ for (i=istart; i<=NF; ++i) {
+ val=$(i)
+ sub(/,$/,"",val)
+ if (val == "on" || val == "off" || val == "disabled" || val =="enabled") {
+ key = ""
+ if (onoff != val) {
+ # on or off can zap disabled or enabled:
+ if (onoff == "" || (onoff == "disabled" || onoff == "enabled") &&
+ (val == "on" || val == "off")) {
+ # It's easy to mis-spell the option when turning it
+ # on or off, so warn about it here:
+ if (onoff == "" && (val == "on" || val == "off")) {
+ print "option", opt ": ERROR: turning unrecognized option", val
+ # For the moment error out - it is safer
+ err = 1 # prevent END{} running
+ exit 1
+ }
+ onoff = val
+ } else {
+ # Print a message, otherwise the error
+ # below is incomprehensible
+ print "option", opt ": currently", onoff ": attempt to turn", val
+ break
+ }
+ }
+ } else if (val == "requires" || val == "if" || val == "enables" || val =="sets") {
+ key = val
+ } else if (key == "requires") {
+ requires[opt] = requires[opt] " " val
+ } else if (key == "if") {
+ iffs[opt] = iffs[opt] " " val
+ } else if (key == "enables") {
+ enabledby[val] = enabledby[val] " " opt
+ } else if (key == "sets") {
+ sets[opt] = sets[opt] " " val
+ key = "setval"
+ set = val
+ } else if (key == "setval") {
+ setval[opt " " set] = setval[opt " " set] " " val
+ } else
+ break # bad line format
+ }
+
+ istart = 1
+ } while (i > NF && $0 ~ /,$/)
+
+ if (i > NF) {
+ # Set the option, defaulting to 'enabled'
+ if (onoff == "") onoff = "enabled"
+ option[opt] = onoff
+ next
+ }
+ # Else fall through to the error handler
+}
+
+# chunk NAME [requires OPT] [enables LIST] [on|off|disabled]
+# Expands to the 'option' settings appropriate to the reading and
+# writing of an ancillary PNG chunk 'NAME':
+#
+# option READ_NAME requires READ_ANCILLARY_CHUNKS [READ_OPT]
+# option READ_NAME enables NAME LIST
+# [option READ_NAME off]
+# option WRITE_NAME requires WRITE_ANCILLARY_CHUNKS [WRITE_OPT]
+# option WRITE_NAME enables NAME LIST
+# [option WRITE_NAME off]
+
+pre != 0 && $1 == "chunk" && NF >= 2{
+ # 'chunk' is handled on the first pass by writing appropriate
+ # 'option' lines into the intermediate file.
+ opt = $2
+ sub(/,$/,"",opt)
+ onoff = ""
+ reqread = ""
+ reqwrite = ""
+ enables = ""
+ req = 0
+ istart = 3
+ do {
+ if (istart == 1) { # continuation line
+ val = getline
+
+ if (val != 1) { # error reading it
+ if (val == 0)
+ print "chunk", opt ": ERROR: missing continuation line"
+ else
+ print "chunk", opt ": ERROR: error reading continuation line"
+
+ # This is a hard error
+ err = 1 # prevent END{} running
+ exit 1
+ }
+ }
+
+ # read the keywords/additional OPTS
+ for (i=istart; i<=NF; ++i) {
+ val = $(i)
+ sub(/,$/,"",val)
+ if (val == "on" || val == "off" || val == "disabled") {
+ if (onoff != val) {
+ if (onoff == "")
+ onoff = val
+ else
+ break # on/off conflict
+ }
+ req = 0
+ } else if (val == "requires")
+ req = 1
+ else if (val == "enables")
+ req = 2
+ else if (req == 1){
+ reqread = reqread " READ_" val
+ reqwrite = reqwrite " WRITE_" val
+ } else if (req == 2)
+ enables = enables " " val
+ else
+ break # bad line: handled below
+ }
+
+ istart = 1
+ } while (i > NF && $0 ~ /,$/)
+
+ if (i > NF) {
+ # Output new 'option' lines to the intermediate file (out)
+ print "option READ_" opt, "requires READ_ANCILLARY_CHUNKS" reqread, "enables", opt enables , onoff >out
+ print "option WRITE_" opt, "requires WRITE_ANCILLARY_CHUNKS" reqwrite, "enables", opt enables, onoff >out
+ next
+ }
+ # Else hit the error handler below - bad line format!
+}
+
+# setting MACRO ( requires MACRO* )* [ default VALUE ]
+# Behaves in a similar way to 'option' without looking for NO_ or
+# _SUPPORTED; the macro is enabled if it is defined so long as all
+# the 'requires' macros are also defined. The definitions may be
+# empty, an error will be issued if the 'requires' macros are
+# *not* defined. If given the 'default' value is used if the
+# macro is not defined. The default value will be re-tokenised.
+# (BTW: this is somewhat restrictive, it mainly exists for the
+# support of non-standard configurations and numeric parameters,
+# see the uses in scripts/options.dat
+
+$1 == "setting" && (NF == 2 || NF >= 3 && ($3 == "requires" || $3 == "default")){
+ reqs = ""
+ deflt = ""
+ isdef = 0
+ key = ""
+ for (i=3; i<=NF; ++i)
+ if ($(i) == "requires" || $(i) == "default") {
+ key = $(i)
+ if (key == "default") isdef = 1
+ } else if (key == "requires")
+ reqs = reqs " " $(i)
+ else if (key == "default")
+ deflt = deflt " " $(i)
+ else
+ break # Format error, handled below
+
+ setting[$2] = reqs
+ # NOTE: this overwrites a previous value silently
+ if (isdef && deflt == "")
+ deflt = " " # as a flag to force output
+ defaults[$2] = deflt
+ next
+}
+
+# The order of the dependency lines (option, chunk, setting) is irrelevant
+# - the 'enables', 'requires' and 'if' settings will be used to determine
+# the correct order in the output and the final values in pnglibconf.h are
+# not order dependent. 'requires' and 'if' entries take precedence over
+# 'enables' from other options; if an option requires another option it
+# won't be set regardless of any options that enable it unless the other
+# option is also enabled.
+#
+# Similarly 'enables' trumps a NO_ definition in CFLAGS or pngusr.h
+#
+# For simplicity cycles in the definitions are regarded as errors,
+# even if they are not ambiguous.
+# A given NAME can be specified in as many 'option' lines as required, the
+# definitions are additive.
+
+# For backwards compatibility equivalent macros may be listed thus:
+#
+# = [NO_]NAME MACRO
+# Makes -DMACRO equivalent to -DPNG_NO_NAME or -DPNG_NAME_SUPPORTED
+# as appropriate.
+#
+# The definition is injected into the C compiler input when encountered
+# in the second pass (so all these definitions appear *after* the @
+# lines!)
+#
+# 'NAME' is as above, but 'MACRO' is the full text of the equivalent
+# old, deprecated, macro.
+
+$1 == "=" && NF == 3{
+ print "#ifdef PNG_" $3 >out
+ if ($2 ~ /^NO_/)
+ print "# define PNG_" $2 >out
+ else
+ print "# define PNG_" $2 "_SUPPORTED" >out
+ print "#endif" >out
+ next
+}
+
+# Lines may be injected into the C compiler input by preceding them
+# with an "@" character. The line is copied with just the leading
+# @ removed.
+
+$1 ~ /^@/{
+ # sub(/^[ ]*@/, "")
+ $1 = substr($1, 2)
+ print >out
+ next
+}
+
+# Check for unrecognized lines, because of the preprocessing chunk
+# format errors will be detected on the first pass independent of
+# any other format errors.
+{
+ print "options.awk: bad line (" NR "):", $0
+ err = 1 # prevent END{} running
+ exit 1
+}
+
+# For checking purposes names that start with "ok_" or "fail_" are
+# not output to pnglibconf.h and must be either enabled or disabled
+# respectively for the build to succeed. This allows interdependencies
+# between options of the form "at least one of" or "at most one of"
+# to be checked. For example:
+#
+# option FLOATING_POINT enables ok_math
+# option FIXED_POINT enables ok_math
+# This ensures that at least one of FLOATING_POINT and FIXED_POINT
+# must be set for the build to succeed.
+#
+# option fail_math requires FLOATING_POINT FIXED_POINT
+# This means the build will fail if *both* FLOATING_POINT and
+# FIXED_POINT are set (this is an example; in fact both are allowed.)
+#
+# If all these options were given the build would require exactly one
+# of the names to be enabled.
+
+END{
+ # END{} gets run on an exit (a traditional awk feature)
+ if (err) exit 1
+
+ if (pre) {
+ # Record the final value of the variables
+ print "deb =", deb >out
+ if (everything != "") {
+ print "everything =", everything >out
+ }
+ print "logunsupported =", logunsupported >out
+ exit 0
+ }
+
+ # Do the options first (allowing options to set settings). The dependency
+ # tree is thus:
+ #
+ # name > name
+ # name requires name
+ # name if name
+ # name enabledby name
+ #
+ # First build a list 'tree' by option of all the things on which
+ # it depends.
+ print "" >out
+ print "/* OPTIONS */" >out
+ print comment, "options", cend >out
+ for (opt in enabledby) tree[opt] = 1 # may not be explicit options
+ for (opt in option) if (opt != "") {
+ o = option[opt]
+ # option should always be one of the following values
+ if (o != "on" && o != "off" && o != "disabled" && o != "enabled") {
+ print "internal option error (" o ")"
+ exit 1
+ }
+ tree[opt] = "" # so unlisted options marked
+ }
+ for (opt in tree) if (opt != "") {
+ if (tree[opt] == 1) {
+ tree[opt] = ""
+ if (option[opt] != "") {
+ print "internal error (1)"
+ exit 1
+ }
+ # Macros only listed in 'enables' remain off unless
+ # one of the enabling macros is on.
+ option[opt] = "disabled"
+ }
+
+ split("", list) # clear 'list'
+ # Now add every requires, iffs or enabledby entry to 'list'
+ # so that we can add a unique list of requirements to tree[i]
+ split(requires[opt] iffs[opt] enabledby[opt], r)
+ for (i in r) list[r[i]] = 1
+ for (i in list) tree[opt] = tree[opt] " " i
+ }
+
+ # print the tree for extreme debugging
+ if (deb > 2) for (i in tree) if (i != "") print i, "depends-on" tree[i]
+
+ # Ok, now check all options marked explicitly 'on' or 'off':
+ #
+ # If an option[opt] is 'on' then turn on all requires[opt]
+ # If an option[opt] is 'off' then turn off all enabledby[opt]
+ #
+ # Error out if we have to turn 'on' to an 'off' option or vice versa.
+ npending = 0
+ for (opt in option) if (opt != "") {
+ if (option[opt] == "on" || option[opt] == "off") {
+ pending[++npending] = opt
+ }
+ }
+
+ err = 0 # set on error
+ while (npending > 0) {
+ opt = pending[npending--]
+ if (option[opt] == "on") {
+ nreqs = split(requires[opt], r)
+ for (j=1; j<=nreqs; ++j) {
+ if (option[r[j]] == "off") {
+ print "option", opt, "turned on, but requirement", r[j], "is turned off"
+ err = 1
+ } else if (option[r[j]] != "on") {
+ option[r[j]] = "on"
+ pending[++npending] = r[j]
+ }
+ }
+ } else {
+ if (option[opt] != "off") {
+ print "internal error (2)"
+ exit 1
+ }
+ nreqs = split(enabledby[opt], r)
+ for (j=1; j<=nreqs; ++j) {
+ if (option[r[j]] == "on") {
+ print "option", opt, "turned off, but enabled by", r[j], "which is turned on"
+ err = 1
+ } else if (option[r[j]] != "off") {
+ option[r[j]] = "off"
+ pending[++npending] = r[j]
+ }
+ }
+ }
+ }
+ if (err) exit 1
+
+ # Sort options:
+ print "PNG_DFN_START_SORT 2" >out
+
+ # option[i] is now the complete list of all the tokens we may
+ # need to output, go through it as above, depth first.
+ finished = 0
+ while (!finished) {
+ finished = 1
+ movement = 0 # done nothing
+ for (i in option) if (!done[i]) {
+ nreqs = split(tree[i], r)
+ if (nreqs > 0) {
+ for (j=1; j<=nreqs; ++j) if (!done[r[j]]) {
+ break
+ }
+ if (j<=nreqs) {
+ finished = 0
+ continue # next option
+ }
+ }
+
+ # All the requirements have been processed, output
+ # this option. An option is _SUPPORTED if:
+ #
+ # all 'requires' are _SUPPORTED AND
+ # at least one of the 'if' options are _SUPPORTED AND
+ # EITHER:
+ # The name is _SUPPORTED (on the command line)
+ # OR:
+ # an 'enabledby' is _SUPPORTED
+ # OR:
+ # NO_name is not defined AND
+ # the option is not disabled; an option is disabled if:
+ # option == off
+ # option == disabled && everything != on
+ # option == "" && everything == off
+ if (deb) print "option", i
+ print "" >out
+ print "/* option:", i, option[i] >out
+ print " * requires: " requires[i] >out
+ print " * if: " iffs[i] >out
+ print " * enabled-by:" enabledby[i] >out
+ print " * sets: " sets[i], "*/" >out
+ print "#undef PNG_on" >out
+ print "#define PNG_on 1" >out
+
+ # requires
+ nreqs = split(requires[i], r)
+ for (j=1; j<=nreqs; ++j) {
+ print "#ifndef PNG_" r[j] "_SUPPORTED" >out
+ print "# undef PNG_on /*!" r[j] "*/" >out
+ # This error appears in the final output if something
+ # was switched 'on' but the processing above to force
+ # the requires did not work
+ if (option[i] == "on") {
+ print error, i, "requires", r[j] end >out
+ }
+ print "#endif" >out
+ }
+
+ # if
+ have_ifs = 0
+ nreqs = split(iffs[i], r)
+ print "#undef PNG_no_if" >out
+ if (nreqs > 0) {
+ have_ifs = 1
+ print "/* if" iffs[i], "*/" >out
+ print "#define PNG_no_if 1" >out
+ for (j=1; j<=nreqs; ++j) {
+ print "#ifdef PNG_" r[j] "_SUPPORTED" >out
+ print "# undef PNG_no_if /*" r[j] "*/" >out
+ print "#endif" >out
+ }
+ print "#ifdef PNG_no_if /*missing if*/" >out
+ print "# undef PNG_on" >out
+ # There is no checking above for this, because we
+ # don't know which 'if' to choose, so whine about
+ # it here:
+ if (option[i] == "on") {
+ print error, i, "needs one of:", iffs[i] end >out
+ }
+ print "#endif" >out
+ }
+
+ print "#ifdef PNG_on /*requires, if*/" >out
+ # enables
+ print "# undef PNG_not_enabled" >out
+ print "# define PNG_not_enabled 1" >out
+ print " /* enabled by" enabledby[i], "*/" >out
+ nreqs = split(enabledby[i], r)
+ for (j=1; j<=nreqs; ++j) {
+ print "#ifdef PNG_" r[j] "_SUPPORTED" >out
+ print "# undef PNG_not_enabled /*" r[j] "*/" >out
+ # Oops, probably not intended (should be factored
+ # out by the checks above).
+ if (option[i] == "off") {
+ print error, i, "enabled by:", r[j] end >out
+ }
+ print "#endif" >out
+ }
+
+ print "# ifndef PNG_" i "_SUPPORTED /*!command line*/" >out
+ print "# ifdef PNG_not_enabled /*!enabled*/" >out
+ # 'have_ifs' here means that everything = "off" still allows an 'if' on
+ # an otherwise enabled option to turn it on; otherwise the 'if'
+ # handling is effectively disabled by 'everything = off'
+ if (option[i] == "off" || option[i] == "disabled" && everything != "on" || option[i] == "enabled" && everything == "off" && !have_ifs) {
+ print "# undef PNG_on /*default off*/" >out
+ } else {
+ print "# ifdef PNG_NO_" i >out
+ print "# undef PNG_on /*turned off*/" >out
+ print "# endif" >out
+ print "# ifdef PNG_NO_" i "_SUPPORTED" >out
+ print "# undef PNG_on /*turned off*/" >out
+ print "# endif" >out
+ }
+ print "# endif /*!enabled*/" >out
+ print "# ifdef PNG_on" >out
+ # The _SUPPORTED macro must be defined so that dependent
+ # options output later work.
+ print "# define PNG_" i "_SUPPORTED" >out
+ print "# endif" >out
+ print "# endif /*!command line*/" >out
+ # If PNG_on is still set the option should be defined in
+ # pnglibconf.h
+ print "# ifdef PNG_on" >out
+ if (i ~ /^fail_/) {
+ print error, i, "is on: enabled by:" iffs[i] enabledby[i] ", requires" requires[i] end >out
+ } else if (i !~ /^ok_/) {
+ print def i sup >out
+ # Supported option, set required settings
+ nreqs = split(sets[i], r)
+ for (j=1; j<=nreqs; ++j) {
+ print "# ifdef PNG_set_" r[j] >out
+ # Some other option has already set a value:
+ print error, i, "sets", r[j] ": duplicate setting" end >out
+ print error, " previous value: " end "PNG_set_" r[j] >out
+ print "# else" >out
+ # Else set the default: note that this won't accept arbitrary
+ # values, the setval string must be acceptable to all the C
+ # compilers we use. That means it must be VERY simple; a number,
+ # a name or a string.
+ print "# define PNG_set_" r[j], setval[i " " r[j]] >out
+ print "# endif" >out
+ }
+ }
+ print "# endif /* definition */" >out
+ print "#endif /*requires, if*/" >out
+ if (logunsupported || i ~ /^ok_/) {
+ print "#ifndef PNG_on" >out
+ if (logunsupported) {
+ print und i une >out
+ }
+ if (i ~ /^ok_/) {
+ print error, i, "not enabled: requires:" requires[i] ", enabled by:" iffs[i] enabledby[i] end >out
+ }
+ print "#endif" >out
+ }
+
+ done[i] = 1
+ ++movement
+ }
+
+ if (!finished && !movement) {
+ print "option: loop or missing option in dependency tree, cannot process:"
+ for (i in option) if (!done[i]) {
+ print " option", i, "depends on" tree[i], "needs:"
+ nreqs = split(tree[i], r)
+ if (nreqs > 0) for (j=1; j<=nreqs; ++j) if (!done[r[j]]) {
+ print " " r[j]
+ }
+ }
+ exit 1
+ }
+ }
+ print "PNG_DFN_END_SORT" >out
+ print comment, "end of options", cend >out
+
+ # Do the 'setting' values second, the algorithm the standard
+ # tree walk (O(1)) done in an O(2) while/for loop; iterations
+ # settings x depth, outputting the deepest required macros
+ # first.
+ print "" >out
+ print "/* SETTINGS */" >out
+ print comment, "settings", cend >out
+ # Sort (in dfn.awk) on field 2, the setting name
+ print "PNG_DFN_START_SORT 2" >out
+ finished = 0
+ while (!finished) {
+ finished = 1
+ movement = 0 # done nothing
+ for (i in setting) if (!doneset[i]) {
+ nreqs = split(setting[i], r)
+ if (nreqs > 0) {
+ # By default assume the requires values are options, but if there
+ # is no option with that name check for a setting
+ for (j=1; j<=nreqs; ++j) if (option[r[j]] == "" && !doneset[r[j]]) {
+ break
+ }
+ if (j<=nreqs) {
+ finished = 0
+ continue # try a different setting
+ }
+ }
+
+ # All the requirements have been processed, output
+ # this setting.
+ if (deb) print "setting", i
+ deflt = defaults[i]
+ # Remove any spurious trailing spaces
+ sub(/ *$/,"",deflt)
+ # A leading @ means leave it unquoted so the preprocessor
+ # can substitute the build time value
+ if (deflt ~ /^ @/)
+ deflt = " " subs substr(deflt, 3) sube
+ print "" >out
+ print "/* setting: ", i >out
+ print " * requires:" setting[i] >out
+ print " * default: ", defaults[i] deflt, "*/" >out
+ for (j=1; j<=nreqs; ++j) {
+ if (option[r[j]] != "")
+ print "#ifndef PNG_" r[j] "_SUPPORTED" >out
+ else
+ print "#ifndef PNG_" r[j] >out
+ print error, i, "requires", r[j] end >out
+ print "# endif" >out
+ }
+ # The precedence is:
+ #
+ # 1) External definition; trumps:
+ # 2) Option 'sets' value; trumps:
+ # 3) Setting 'default'
+ #
+ print "#ifdef PNG_" i >out
+ # PNG_<i> is defined, so substitute the value:
+ print def i, subs "PNG_" i sube end >out
+ print "#else /* use default */" >out
+ print "# ifdef PNG_set_" i >out
+ # Value from an option 'sets' argument
+ print def i, subs "PNG_set_" i sube end >out
+ # This is so that subsequent tests on the setting work:
+ print "# define PNG_" i, "1" >out
+ if (defaults[i] != "") {
+ print "# else /*default*/" >out
+ print def i deflt end >out
+ print "# define PNG_" i, "1" >out
+ }
+ print "# endif /* defaults */" >out
+ print "#endif /* setting", i, "*/" >out
+
+ doneset[i] = 1
+ ++movement
+ }
+
+ if (!finished && !movement) {
+ print "setting: loop or missing setting in 'requires', cannot process:"
+ for (i in setting) if (!doneset[i]) {
+ print " setting", i, "requires" setting[i]
+ }
+ exit 1
+ }
+ }
+ print "PNG_DFN_END_SORT" >out
+ print comment, "end of settings", cend >out
+
+ # Regular end - everything looks ok
+ if (protect != "") {
+ print start "#endif", "/*", protect, "*/" end >out
+ }
+}
diff --git a/xs/src/png/libpng/scripts/pnglibconf.dfa b/xs/src/png/libpng/scripts/pnglibconf.dfa
new file mode 100644
index 000000000..b298a72f3
--- /dev/null
+++ b/xs/src/png/libpng/scripts/pnglibconf.dfa
@@ -0,0 +1,919 @@
+# scripts/pnglibconf.dfa - library build configuration control
+#
+@/*- pnglibconf.dfn intermediate file
+@ * generated from scripts/pnglibconf.dfa
+@ */
+#
+com pnglibconf.h - library build configuration
+com
+version
+com
+com Copyright (c) 1998-2017 Glenn Randers-Pehrson
+com
+com This code is released under the libpng license.
+com For conditions of distribution and use, see the disclaimer
+com and license in png.h
+com
+
+file pnglibconf.h scripts/pnglibconf.dfa PNGLCONF_H
+
+# This file is preprocessed by scripts/options.awk and the
+# C compiler to generate 'pnglibconf.h' - a list of all the
+# configuration options. The file lists the various options
+# that can *only* be specified during the libpng build;
+# pnglibconf.h freezes the definitions selected for the specific
+# build.
+#
+# The syntax is detailed in scripts/options.awk; this is a summary
+# only:
+#
+# setting <name> [requires ...] [default]
+# #define PNG_<name> <value> /* value comes from current setting */
+# option <name> [requires ...] [if ...] [enables ...] [disabled]
+# #define PNG_<name>_SUPPORTED if the requirements are met and
+# enable the other options listed
+# chunk <name> [requires ...] [enables ...] [disabled]
+# Enable chunk processing for the given ancillary chunk; any
+# 'requires something' expands to READ_something for read and
+# WRITE_something for write, but the enables list members are
+# used as given (e.g. enables GAMMA just expands to that on the
+# correspond READ_name and WRITE_name lines.)
+#
+# "," may be used to separate options on an 'option' line and is ignored; it
+# doesn't change the meaning of the line. (NOT setting, where "," becomes
+# part of the setting!) A comma at the end of an option line causes a
+# continuation (the next line is included in the option too.)
+#
+# Note that the 'on' and 'off' keywords, while valid on both option
+# and chunk, should not be used in this file because they force the
+# relevant options on or off.
+
+#----------------------------------------------------------------------
+
+# The following setting, option and chunk values can all be changed
+# while building libpng:
+#
+# setting: change 'setting' lines to fine tune library performance;
+# changes to the settings don't affect the libpng API functionally
+#
+# option: change 'option' lines to remove or add capabilities from
+# or to the library; options change the library API
+#
+# chunk: change 'chunk' lines to remove capabilities to process
+# optional ('ancillary') chunks. This does not prevent PNG
+# decoding but does change the libpng API because some chunks
+# will be ignored.
+#
+# There are three ways of disabling features, in no particular order:
+#
+# 1) Create 'pngusr.h', enter the required private build information
+# detailed below and #define PNG_NO_<option> for each option you
+# don't want in that file in that file. You can also turn on options
+# using PNG_<option>_SUPPORTED. When you have finished rerun
+# configure and rebuild pnglibconf.h file with -DPNG_USER_CONFIG:
+#
+# make clean
+# CPPFLAGS='-DPNG_USER_CONFIG' ./configure
+# make pnglibconf.h
+#
+# pngusr.h is only used during the creation of pnglibconf.h, but it
+# is safer to ensure that -DPNG_USER_CONFIG is specified throughout
+# the build by changing the CPPFLAGS passed to the initial ./configure
+#
+# 2) Add definitions of the settings you want to change to
+# CPPFLAGS; for example:
+#
+# -DPNG_DEFAULT_READ_MACROS=0
+#
+# (This would change the default to *not* use read macros.) Be
+# very careful to change only settings that don't alter the API
+# because this approach bypasses the private build checking. You
+# can also change settings from pngpriv.h (read pngpriv.h) safely
+# without API changes. Do that in the same way.
+#
+# 3) Write a new '.dfa' file (say 'pngusr.dfa') and in this file
+# provide override values for setting entries and turn option or
+# chunk values explicitly 'on' or 'off':
+#
+# setting FOO default VALUE
+# option BAR [on|off]
+#
+# Then add this file to the options.awk command line (the *first*
+# one) after this file. The make macro DFA_XTRA is provided to make
+# this easier (set it like CPPFLAGS prior to running ./configure).
+# Look at the builds below contrib/pngminim for some extreme examples
+# of how this can be used.
+#
+# Don't edit this file unless you are contributing a patch to
+# libpng and need new or modified options/settings.
+#----------------------------------------------------------------------
+
+# The following causes commented out #undef lines to be written to
+# pnglibconf.h; this can be stopped by logunsupported=0 in a later
+# file or on the command line (after pnglibconf.dfa)
+
+logunsupported = 1
+
+# The following allows the output from configure to modify the contents of
+# pnglibconf.h
+
+@#ifdef HAVE_CONFIG_H
+@# include "config.h"
+@#endif
+
+# PNG_USER_CONFIG has to be defined on the compiler command line
+# to cause pngusr.h to be read while constructing pnglibconf.h
+#
+# If you create a private DLL you need to define the following
+# macros in the file 'pngusr.h' and set -DPNG_USER_CONFIG for
+# compilation (i.e. in CPPFLAGS.)
+# #define PNG_USER_PRIVATEBUILD \
+# <Describes by whom and why this version of the DLL was built>
+# e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons."
+# #define PNG_USER_DLLFNAME_POSTFIX <two-letter postfix that serve to
+# distinguish your DLL from those of the official release. These
+# correspond to the trailing letters that come after the version
+# number and must match your private DLL name>
+# e.g. // private DLL "libpng13gx.dll"
+# #define PNG_USER_DLLFNAME_POSTFIX "gx"
+#
+# The following macros are also at your disposal if you want to complete the
+# DLL VERSIONINFO structure.
+# - PNG_USER_VERSIONINFO_COMMENTS
+# - PNG_USER_VERSIONINFO_COMPANYNAME
+# - PNG_USER_VERSIONINFO_LEGALTRADEMARKS
+
+# It is necessary to include configures definitions here so that AC_DEFINE
+# in configure.ac works in a comprehensible way
+@#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
+@# include "config.h"
+@#endif
+
+@#ifdef PNG_USER_CONFIG
+@# include "pngusr.h"
+@#endif
+
+# This is a special fixup for the Watcom C compiler on Windows, which has
+# multiple procedure call standards. Unless PNG_API_RULE is set explicitly
+# (i.e. if it is not defined at this point) it will be forced to '2' here when
+# using Watcom. This indicates to the other header files that Watcom behaviour
+# is required where appropriate.
+
+@#ifdef __WATCOMC__
+@# ifndef PNG_API_RULE
+@# define PNG_API_RULE 2 /* Use Watcom calling conventions */
+@# endif
+@#endif
+
+# IN DEVELOPMENT
+# These are currently experimental features; define them if you want (NOTE:
+# experimental options must be disabled before they are defined in this file!)
+
+# NONE
+
+# Note that PNG_USER_CONFIG only has an effect when building
+# pnglibconf.h
+
+setting USER_CONFIG
+setting USER_PRIVATEBUILD
+setting USER_DLLFNAME_POSTFIX
+setting USER_VERSIONINFO_COMMENTS
+setting USER_VERSIONINFO_COMPANYNAME
+setting USER_VERSIONINFO_LEGALTRADEMARKS
+
+# Record the 'API rule' used to select calling conventions on
+# those systems that support such things (see all the comments in
+# pngconf.h)
+# Changing this setting has a fundamental affect on the PNG ABI,
+# do not release shared libraries with this changed.
+
+setting API_RULE default 0
+
+# This allows a prefix to be added to the front of every API function name (and
+# therefore every symbol) by redefining all the function names with the prefix
+# at the end of pnglibconf.h. It also turns on similar internal symbol renaming
+# by causing a similar build-time only file, pngprefix.h, to be generated.
+
+setting PREFIX
+
+# Implementation specific control of the optimizations, enabled by those
+# hardware or software options that need it (typically when run-time choices
+# must be made by the user)
+option SET_OPTION disabled
+
+# These options are specific to the ARM NEON hardware optimizations. At present
+# these optimizations depend on GCC specific pre-processing of an assembler (.S)
+# file so they probably won't work with other compilers.
+#
+# ARM_NEON_OPT: unset: check at compile time (__ARM_NEON__ must be defined by
+# the compiler, typically as a result of specifying
+# CC="gcc -mfpu=neon".)
+# 0: disable (even if the CPU has a NEON FPU.)
+# 1: check at run time (via ARM_NEON_{API,CHECK})
+# 2: switch on unconditionally (inadvisable - instead pass
+# -mfpu=neon to GCC in CC)
+# When building libpng avoid using any setting other than '0'; '1' is
+# set automatically when either 'API' or 'CHECK' are configured in,
+# '2' should not be necessary as -mfpu=neon will achieve the same
+# effect as well as applying NEON optimizations to the rest of the
+# libpng code.
+# NOTE: any setting other than '0' requires ALIGNED_MEMORY
+# ARM_NEON_API: (PNG_ARM_NEON == 1) allow the optimization to be switched on
+# with png_set_option
+# ARM_NEON_CHECK: (PNG_ARM_NEON == 1) compile a run-time check to see if Neon
+# extensions are supported. This is poorly supported and
+# deprecated - use the png_set_option API.
+setting ARM_NEON_OPT
+option ARM_NEON_API disabled requires ALIGNED_MEMORY enables SET_OPTION,
+ sets ARM_NEON_OPT 1
+option ARM_NEON_CHECK disabled requires ALIGNED_MEMORY,
+ sets ARM_NEON_OPT 1
+
+# These options are specific to the PowerPC VSX hardware optimizations.
+#
+# POWERPC_VSX_OPT: unset: check at compile time (__PPC64__,__ALTIVEC__,__VSX__
+# must be defined by the compiler, typically as a result
+# of specifying
+# "-mvsx -maltivec" compiler flags)
+# 0: disable (even if the CPU supports VSX.)
+# 1: check at run time (via POWERPC_VSX_{API,CHECK})
+# 2: switch on unconditionally (inadvisable - instead pass
+# -mvsx -maltivec to compiler options)
+# When building libpng avoid using any setting other than '0'; '1' is
+# set automatically when either 'API' or 'CHECK' are configured in,
+# '2' should not be necessary as "-mvsx -maltivec" will achieve the same
+# effect as well as applying VSX optimizations to the rest of the
+# libpng code.
+# POWERPC_VSX_API: (PNG_POWERPC_VSX == 1) allow the optimization to be switched on
+# with png_set_option
+# POWERPC_VSX_CHECK: (PNG_POWERPC_VSX == 1) compile a run-time check to see if VSX
+# extensions are supported. This is supported not for all OSes
+# (see contrib/powerpc/README)
+setting POWERPC_VSX_OPT
+option POWERPC_VSX_API disabled enables SET_OPTION,
+ sets POWERPC_VSX_OPT 1
+option POWERPC_VSX_CHECK disabled,
+ sets POWERPC_VSX_OPT 1
+
+
+# These settings configure the default compression level (0-9) and 'strategy';
+# strategy is as defined by the implementors of zlib. It describes the input
+# data and modifies the zlib parameters in an attempt to optimize the balance
+# between search and huffman encoding in the zlib algorithms. The defaults are
+# the zlib.h defaults - the apparently recursive definition does not arise
+# because the name of the setting is prefixed by PNG_
+#
+# The TEXT values are the defaults when writing compressed text (all forms)
+
+# Include the zlib header so that the defaults below are known
+@# include <zlib.h>
+
+# The '@' here means to substitute the value when pnglibconf.h is built
+setting Z_DEFAULT_COMPRESSION default @Z_DEFAULT_COMPRESSION
+# TODO: why aren't these Z_RLE; zlib.h says that Z_RLE, specifically, is
+# appropriate for PNG images, maybe it doesn't exist in all versions?
+setting Z_DEFAULT_STRATEGY default @Z_FILTERED
+setting Z_DEFAULT_NOFILTER_STRATEGY default @Z_DEFAULT_STRATEGY
+setting ZLIB_VERNUM default @ZLIB_VERNUM
+
+# Linkage of:
+#
+# API: libpng API functions
+# CALLBACK: internal non-file-local callbacks
+# FUNCTION: internal non-file-local functions
+# DATA: internal non-file-local (const) data
+setting LINKAGE_API default extern
+setting LINKAGE_CALLBACK default extern
+setting LINKAGE_FUNCTION default extern
+setting LINKAGE_DATA default extern
+
+setting TEXT_Z_DEFAULT_COMPRESSION default @Z_DEFAULT_COMPRESSION
+setting TEXT_Z_DEFAULT_STRATEGY default @Z_DEFAULT_STRATEGY
+
+# Default to using the read macros
+
+setting DEFAULT_READ_MACROS default 1
+
+# The alternative is to call functions to read PNG values, if
+# the functions are turned *off* the read macros must always
+# be enabled, so turning this off will actually force the
+# USE_READ_MACROS option on (see pngconf.h)
+
+option READ_INT_FUNCTIONS requires READ
+
+# The same for write but these can only be switched off if no writing
+# is required at all - hence the use of a 'disabled', not a 'requires'.
+# If these are needed, they are enabled in the 'WRITE options' section
+# below.
+
+option WRITE_INT_FUNCTIONS disabled
+
+# Error controls
+#
+# WARNINGS: normally on, if off no warnings are generated
+# ERROR_TEXT: normally on, if off errors happen but there is no message
+# ERROR_NUMBERS: unimplemented feature, therefore disabled
+# BENIGN_ERRORS: support for just issuing warnings for recoverable errors
+#
+# BENIGN_READ_ERRORS:
+# By default recoverable errors on read should just generate warnings,
+# generally safe but PNG files that don't conform to the specification will
+# be accepted if a meaningful result can be produced.
+#
+# BENIGN_WRITE_ERRORS:
+# By default recoverable errors on write should just generate warnings,
+# not generally safe because this allows the application to write invalid
+# PNG files. Applications should enable this themselves; it's useful
+# because it means that a failure to write an ancillary chunk can often be
+# ignored.
+
+option WARNINGS
+option ERROR_TEXT
+option ERROR_NUMBERS disabled
+
+option BENIGN_ERRORS
+option BENIGN_WRITE_ERRORS requires BENIGN_ERRORS disabled
+option BENIGN_READ_ERRORS requires BENIGN_ERRORS
+
+
+# Generic options - affect both read and write.
+
+option MNG_FEATURES
+
+# Arithmetic options, the first is the big switch that chooses between internal
+# floating and fixed point arithmetic implementations - it does not affect any
+# APIs. The second two (the _POINT settings) switch off individual APIs.
+#
+# Prior to libpng 1.6.8 one of the API (_POINT) variants had to be selected. At
+# 1.6.8 this restriction has been removed; the simplified API can be used
+# without enabling any of the low level fixed/floating APIs.
+
+option FLOATING_ARITHMETIC
+option FLOATING_POINT
+option FIXED_POINT
+
+# This protects us against compilers that run on a windowing system
+# and thus don't have or would rather us not use the stdio types:
+# stdin, stdout, and stderr. The only one currently used is stderr
+# in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will
+# prevent these from being compiled and used. #defining PNG_NO_STDIO
+# will also prevent these, plus will prevent the entire set of stdio
+# macros and functions (FILE *, printf, etc.) from being compiled and used,
+# unless (PNG_DEBUG > 0) has been #defined.
+
+option STDIO
+option CONSOLE_IO requires STDIO
+
+# Note: prior to 1.5.0 this option could not be disabled if STDIO
+# was enabled. Prior to 1.5.3 this option required STDIO
+
+option TIME_RFC1123
+
+# PNG_SETJMP_NOT_SUPPORTED is an old equivalent for NO_SETJMP
+
+option SETJMP
+= NO_SETJMP SETJMP_NOT_SUPPORTED
+
+# If this is disabled it is not possible for apps to get the
+# values from the 'info' structure, this effectively removes
+# quite a lot of the READ API.
+
+option EASY_ACCESS
+
+# Added at libpng-1.2.0
+
+option USER_MEM
+
+# Added at libpng-1.4.0
+
+option IO_STATE
+
+# Libpng limits: limit the size of images and data on read.
+#
+# If this option is disabled all the limit checking code will be disabled:
+
+option USER_LIMITS requires READ
+
+# The default settings given below for the limits mean that libpng will
+# limit the size of images or the size of data in ancillary chunks to less
+# than the specification or implementation limits. Settings have the
+# following interpretations:
+#
+# USER_WIDTH_MAX: maximum width of an image that will be read
+# USER_HEIGHT_MAX: maximum height
+# USER_CHUNK_MALLOC_MAX: maximum in-memory (decompressed) size of a single chunk
+# USER_CHUNK_CACHE_MAX: maximum number of chunks to be cached
+#
+# Only chunks that are variable in number are counted towards the
+
+# Use 0x7fffffff for unlimited
+setting USER_WIDTH_MAX default 1000000
+setting USER_HEIGHT_MAX default 1000000
+
+# Use 0 for unlimited
+setting USER_CHUNK_CACHE_MAX default 1000
+setting USER_CHUNK_MALLOC_MAX default 8000000
+
+# If this option is enabled APIs to set the above limits at run time are added;
+# without this the hardwired (compile time) limits will be used.
+option SET_USER_LIMITS requires USER_LIMITS
+
+# All of the following options relate to code capabilities for
+# processing image data before creating a PNG or after reading one.
+# You can remove these capabilities safely and still be PNG
+# conformant, however the library that results is still non-standard.
+# See the comments above about how to change options and settings.
+
+# READ options
+#
+# WARNING: in libpng 1.5 maintained configuration compatibility with earlier
+# versions. In some cases turning off an option turned off other options, in
+# others it was ineffective unless dependent options were also turned off.
+# Libpng 1.6 changes this: in general if you turn off an option that affects
+# APIs it stays off and simply disables APIs that depend on it.
+#
+# As a result if you simply port the libpng 1.5 configuration to libpng 1.6 you
+# will probably see build failures due to missing APIs. Fixing these failures
+# requires some, perhaps considerable, knowledge of what your libpng using
+# applications are doing, fortunately there is no great reason for you to move
+# to libpng 1.6; the new interfaces in 1.6 will take several years to become
+# popular.
+
+option READ enables READ_INTERLACING SET_OPTION
+
+# Disabling READ_16BIT does not disable reading 16-bit PNG files, but it
+# forces them to be chopped down to 8-bit, and disables any 16-bit
+# processing after that has happened. You need to be sure to enable
+# READ_SCALE_16_TO_8 or READ_STRIP_16_TO_8 when you disable READ_16BIT for
+# this to work properly. You should disable the other option if you need to
+# ensure a particular conversion (otherwise the app can chose.)
+
+option READ_16BIT requires READ enables 16BIT
+
+option READ_QUANTIZE requires READ
+
+option READ_TRANSFORMS requires READ
+= NO_READ_TRANSFORMS READ_TRANSFORMS_NOT_SUPPORTED
+
+# Read gamma handling. Gamma processing is a core part of libpng and many of
+# the capabilities are dependent on libpng performing gamma correction.
+#
+# In libpng 1.6 disabling gamma processing (setting PNG_NO_READ_GAMMA)
+# consistently disables those parts of the API that depend on it. Prior to
+# 1.6.0 this was not true; the results were unpredictable and varied between
+# releases.
+#
+# If you disable gamma processing and your program no longer compiles you need
+# to ask whether you really need the APIs that are missing. If you do then you
+# almost certainly need the gamma processing.
+#
+# If you handle gamma issues outside libpng then you do not need the libpng
+# gamma processing; and it is an enormous waste of space. You just need to
+# remove the use of libpng APIs that depend on it.
+option READ_GAMMA requires READ_TRANSFORMS, READ_gAMA, READ_sRGB
+
+option READ_ALPHA_MODE requires READ_TRANSFORMS, READ_GAMMA
+option READ_BACKGROUND requires READ_TRANSFORMS, READ_STRIP_ALPHA, READ_GAMMA
+option READ_BGR requires READ_TRANSFORMS
+option READ_EXPAND_16 requires READ_TRANSFORMS, READ_16BIT, READ_EXPAND
+option READ_EXPAND requires READ_TRANSFORMS
+option READ_FILLER requires READ_TRANSFORMS
+option READ_GRAY_TO_RGB requires READ_TRANSFORMS
+option READ_INVERT_ALPHA requires READ_TRANSFORMS
+option READ_INVERT requires READ_TRANSFORMS
+option READ_PACK requires READ_TRANSFORMS
+option READ_PACKSWAP requires READ_TRANSFORMS
+option READ_RGB_TO_GRAY requires READ_TRANSFORMS, READ_GAMMA enables COLORSPACE
+option READ_SCALE_16_TO_8 requires READ_TRANSFORMS
+option READ_SHIFT requires READ_TRANSFORMS
+option READ_STRIP_16_TO_8 requires READ_TRANSFORMS
+option READ_STRIP_ALPHA requires READ_TRANSFORMS
+option READ_SWAP_ALPHA requires READ_TRANSFORMS
+option READ_SWAP requires READ_TRANSFORMS, READ_16BIT
+option READ_USER_TRANSFORM requires READ_TRANSFORMS
+
+option PROGRESSIVE_READ requires READ
+option SEQUENTIAL_READ requires READ
+
+# You can define PNG_NO_PROGRESSIVE_READ if you don't do progressive reading.
+# This is not talking about interlacing capability! You'll still have
+# interlacing unless you turn off the following which is required
+# for PNG-compliant decoders. (In other words, do not do this - in
+# fact it can't be disabled from the command line!)
+#option READ_INTERLACING requires READ
+
+option READ_COMPOSITE_NODIV requires READ
+= NO_READ_COMPOSITE_NODIV NO_READ_COMPOSITED_NODIV
+
+# Inch conversions
+
+option INCH_CONVERSIONS
+= INCH_CONVERSIONS INCH_CONVERSIONS
+
+# API to build a grayscale palette
+# NOTE: this is not used internally by libpng at present.
+
+option BUILD_GRAYSCALE_PALETTE
+
+# WRITE options
+
+option WRITE enables WRITE_INT_FUNCTIONS
+
+# Disabling WRITE_16BIT prevents 16-bit PNG files from being
+# generated.
+option WRITE_16BIT requires WRITE enables 16BIT
+
+option WRITE_TRANSFORMS requires WRITE
+= NO_WRITE_TRANSFORMS WRITE_TRANSFORMS_NOT_SUPPORTED
+
+option WRITE_SHIFT requires WRITE_TRANSFORMS
+option WRITE_PACK requires WRITE_TRANSFORMS
+option WRITE_BGR requires WRITE_TRANSFORMS
+option WRITE_SWAP requires WRITE_TRANSFORMS, WRITE_16BIT
+option WRITE_PACKSWAP requires WRITE_TRANSFORMS
+option WRITE_INVERT requires WRITE_TRANSFORMS
+option WRITE_FILLER requires WRITE_TRANSFORMS
+option WRITE_SWAP_ALPHA requires WRITE_TRANSFORMS
+option WRITE_INVERT_ALPHA requires WRITE_TRANSFORMS
+option WRITE_USER_TRANSFORM requires WRITE_TRANSFORMS
+
+# This is not required for PNG-compliant encoders, but can cause
+# trouble if left undefined
+
+option WRITE_INTERLACING requires WRITE
+
+# Deprecated, will be removed.
+option WRITE_WEIGHTED_FILTER requires WRITE
+
+option WRITE_FLUSH requires WRITE
+
+# Note: these can be turned off explicitly if not required by the
+# apps implementing the user transforms
+option USER_TRANSFORM_PTR if READ_USER_TRANSFORM, WRITE_USER_TRANSFORM
+option USER_TRANSFORM_INFO if READ_USER_TRANSFORM, WRITE_USER_TRANSFORM
+
+# This enables API to set compression parameters for compressing
+# non-IDAT chunks (zTXt, iTXt, iCCP, and unknown chunks). This feature
+# was added at libpng-1.5.3.
+option WRITE_CUSTOMIZE_ZTXT_COMPRESSION requires WRITE
+option WRITE_CUSTOMIZE_COMPRESSION requires WRITE
+
+# Any chunks you are not interested in, you can undef here. The
+# ones that allocate memory may be especially important (hIST,
+# tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info
+# a bit smaller.
+
+# The size of the png_text structure changed in libpng-1.0.6 when
+# iTXt support was added. iTXt support was turned off by default through
+# libpng-1.2.x, to support old apps that malloc the png_text structure
+# instead of calling png_set_text() and letting libpng malloc it. It
+# was turned on by default in libpng-1.4.0.
+
+option READ_ANCILLARY_CHUNKS requires READ
+# PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED is deprecated.
+= NO_READ_ANCILLARY_CHUNKS READ_ANCILLARY_CHUNKS_NOT_SUPPORTED
+
+option WRITE_ANCILLARY_CHUNKS requires WRITE
+# PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED is deprecated.
+= NO_WRITE_ANCILLARY_CHUNKS WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED
+
+# These options disable *all* the text chunks if turned off
+
+option TEXT disabled
+option READ_TEXT requires READ_ANCILLARY_CHUNKS enables TEXT
+option WRITE_TEXT requires WRITE_ANCILLARY_CHUNKS enables TEXT
+
+# Moved to pnglibconf.h at libpng-1.5.0
+# Feature support: in 1.4 this was in pngconf.h, but the following
+# features have no affect on the libpng API. Add library
+# only features to the end of this list. Add features that
+# affect the API above. (Note: the list of chunks follows
+# the library-only settings.)
+#
+# BUILD TIME ONLY OPTIONS
+# These options do not affect the API but rather alter how the
+# API is implemented, they get recorded in pnglibconf.h, but
+# can't be changed by the application.
+
+# Colorspace support (enabled as required); just the support for colorant
+# information. Gamma support, likewise, is just support for the gamma
+# information, READ_GAMMA is required for gamma transformations (so it
+# is possible to read PNG gamma without enabling all the libpng transform
+# code - do this for applications that do their own gamma processing)
+#
+# As of 1.6.0 COLORSPACE is only useful if the application processes the
+# information; this is because the library does not do any colorspace
+# processing, it just validates the data in the PNG file.
+
+option GAMMA disabled
+option COLORSPACE enables GAMMA disabled
+
+# When an ICC profile is read, or png_set, it will be checked for a match
+# against known sRGB profiles if the sRGB handling is enabled. The
+# PNG_sRGB_PROFILE_CHECKS setting controls how much work is done during the
+# check:
+#
+# -1: Don't do any sRGB profile checking.
+#
+# 0: Just validate the profile MD5 signature if present, otherwise use
+# the checks in option 1.
+#
+# 1: Additionally check the length, intent and adler32 checksum of the
+# actual data. If enabled this will reject known profiles that have
+# had the rendering intent in the header changed as well as other edits
+# done without updating the checksum. See the discussion below.
+#
+# 2: Additionally checksum all the data using the ethernet CRC32 algorithm.
+# This makes it more difficult to fake profiles and makes it less likely
+# to get a false positive on profiles with no signature, but is probably
+# just a waste of time since all currently approved ICC sRGB profiles have
+# a secure MD5 signature.
+#
+# The rendering intent. An ICC profile stores an intended rendering intent,
+# but does not include the value in the signature. The intent is documented
+# as the intent that should be used when combining two profiles. The sRGB
+# profile is intended, however, to be used with any of the four defined intents.
+# For this reason the sRGB chunk includes an 'intent' to be used when displaying
+# the image (intent is really a property of the image not the profile.)
+#
+# Unfortunately the iCCP chunk does not. It may therefore be that some
+# applications modify the intent in profiles (including sRGB profiles) to work
+# round this problem. Selecting an option other than option '0' will cause such
+# modified profiles to be rejected.
+#
+# Security. The use of Adler32 and CRC32 checksums does not help significantly
+# with any security issues. It is relatively easy to produce arbitrary profiles
+# with the required checksums on current computer systems. Nevertheless
+# security does not seem to be an issue because the only consequence of a false
+# positive is a false assertion that the profile is an sRGB profile. This might
+# be used to hide data from libpng using applications, but it doesn't seem
+# possible to damage them.
+
+setting sRGB_PROFILE_CHECKS default 2
+
+# Artificially align memory - the code typically aligns to 8 byte
+# boundaries if this is switched on, it's a small waste of space
+# but can help (in theory) on some architectures. Only affects
+# internal structures. Added at libpng 1.4.0
+
+option ALIGNED_MEMORY
+
+# Buggy compilers (e.g., gcc 2.7.2.2) need PNG_NO_POINTER_INDEXING
+# See png[wr]util.c, normally this should always be *on*
+
+option POINTER_INDEXING
+
+# Other defines for things like memory and the like can go here.
+
+# BUILD TIME SETTINGS
+# Like build time options these do not affect the API, but they
+# may be useful to applications because they record details of
+# how the API will behave particularly with regard to overall
+# accuracy.
+
+# This controls how fine the quantizing gets. As this allocates
+# a largish chunk of memory (32K), those who are not as concerned
+# with quantizing quality can decrease some or all of these.
+
+setting QUANTIZE_RED_BITS default 5
+setting QUANTIZE_GREEN_BITS default 5
+setting QUANTIZE_BLUE_BITS default 5
+
+# This controls how fine the gamma correction becomes when you
+# are only interested in 8 bits anyway. Increasing this value
+# results in more memory being used, and more pow() functions
+# being called to fill in the gamma tables. Don't set this value
+# less than 8, and even that may not work (I haven't tested it).
+
+setting MAX_GAMMA_8 default 11
+
+# This controls how much a difference in gamma we can tolerate before
+# we actually start doing gamma conversion, it's a fixed point value,
+# so the default below is 0.05, meaning libpng ignores corrections in
+# the range 0.95 to 1.05
+
+setting GAMMA_THRESHOLD_FIXED default 5000
+
+# Precision to use when converting a floating point value to a PNG
+# extension format string in an sCAL chunk (only relevant if the
+# floating point API is enabled)
+
+setting sCAL_PRECISION default 5
+
+# This is the size of the compression buffer, and thus the size of
+# an IDAT chunk. Make this whatever size you feel is best for your
+# machine. One of these will be allocated per png_struct. When this
+# is full, it writes the data to the disk, and does some other
+# calculations. Making this an extremely small size may slow
+# the library down, but you may want to experiment to determine
+# where it becomes significant, if you are concerned with memory
+# usage. Note that zlib allocates at least 32Kb also. For readers,
+# this describes the size of the buffer available to read the data in.
+# Unless this gets smaller than the size of a row (compressed),
+# it should not make much difference how big this is.
+
+setting ZBUF_SIZE default 8192
+
+# This is the size of the decompression buffer used when counting or checking
+# the decompressed size of an LZ stream from a compressed ancillary chunk; the
+# decompressed data is never used so a different size may be optimal. This size
+# was determined using contrib/libtests/timepng.c with compressed zTXt data
+# around 11MByte in size. Slight speed improvements (up to about 14% in
+# timepng) can be achieved by very large increases (to 32kbyte) on regular data,
+# but highly compressible data shows only around 2% improvement. The size is
+# chosen to minimize the effects of DoS attacks based on using very large
+# amounts of highly compressible data.
+
+setting INFLATE_BUF_SIZE default 1024
+
+# This is the maximum amount of IDAT data that the sequential reader will
+# process at one time. The setting does not affect the size of IDAT chunks
+# read, just the amount read at once. Neither does it affect the progressive
+# reader, which processes just the amount of data the application gives it.
+# The sequential reader is currently unable to process more than one IDAT at
+# once - it has to read and process each one in turn. There is no point setting
+# this to a value larger than the IDAT chunks typically encountered (it would
+# just waste memory) but there may be some point in reducing it below the value
+# of ZBUF_SIZE (the size of IDAT chunks written by libpng.)
+
+setting IDAT_READ_SIZE default PNG_ZBUF_SIZE
+
+# Ancillary chunks
+chunk bKGD
+chunk cHRM enables COLORSPACE
+chunk eXIf
+chunk gAMA enables GAMMA
+chunk hIST
+chunk iCCP enables COLORSPACE, GAMMA
+chunk iTXt enables TEXT
+chunk oFFs
+chunk pCAL
+chunk pHYs
+chunk sBIT
+chunk sCAL
+chunk sPLT
+chunk sRGB enables COLORSPACE, GAMMA, SET_OPTION
+chunk tEXt requires TEXT
+chunk tIME
+chunk tRNS
+chunk zTXt enables TEXT
+
+# This only affects support of the optional PLTE chunk in RGB and RGBA
+# images. Notice that READ_ANCILLARY_CHUNKS therefore disables part
+# of the regular chunk reading too.
+
+option READ_OPT_PLTE requires READ_ANCILLARY_CHUNKS
+
+# Unknown chunk handling
+#
+# 'UNKNOWN_CHUNKS' is a global option to disable all unknown chunk handling on
+# read or write; everything else below requires it (directly or indirectly).
+option UNKNOWN_CHUNKS
+
+# There are three main options to control the ability to read and write unknown
+# chunks. If either read option is turned on then unknown chunks will be read,
+# otherwise they are skipped. If the write option is turned on unknown chunks
+# set by png_set_unknown_chunks will be written otherwise it is an error to call
+# that API on a write struct.
+option WRITE_UNKNOWN_CHUNKS requires WRITE requires UNKNOWN_CHUNKS
+option WRITE_UNKNOWN_CHUNKS enables STORE_UNKNOWN_CHUNKS
+
+# The first way to read user chunks is to have libpng save them for a later call
+# to png_get_unknown_chunks, the application must call
+# png_set_keep_unknown_chunks to cause this to actually happen (see png.h)
+option SAVE_UNKNOWN_CHUNKS requires READ requires SET_UNKNOWN_CHUNKS
+option SAVE_UNKNOWN_CHUNKS enables READ_UNKNOWN_CHUNKS, STORE_UNKNOWN_CHUNKS
+
+# The second approach is to use an application provided callback to process the
+# chunks, the callback can either handle the chunk entirely itself or request
+# that libpng store the chunk for later retrieval via png_get_unknown_chunks.
+#
+# NOTE: If STORE_UNKNOWN_CHUNKS is not enabled (which is the default if
+# both SAVE_UNKNOWN_CHUNKS and WRITE_UNKNOWN_CHUNKS are disabled) then a
+# 0 result from the callback will be ignored because no support for saving
+# unknown chunks has been compiled in. The normal symptom is that your app
+# fails to compile because png_get_unknown_chunks is no longer defined in png.h.
+# If you encounter this issue simply enable STORE_UNKNOWN_CHUNKS in your build.
+#
+# Note that there is no 'WRITE_USER_CHUNKS' so the USER_CHUNKS option is always
+# the same as READ_USER_CHUNKS at present
+option READ_USER_CHUNKS requires READ, UNKNOWN_CHUNKS
+option READ_USER_CHUNKS enables READ_UNKNOWN_CHUNKS, USER_CHUNKS
+
+# Two further options are provided to allow detailed control of the handling.
+# The first enables png_set_keep_unknown_chunks; this allows the default to be
+# changed from discarding unknown chunks and allows per-chunk control. This is
+# required to use the SAVE_UNKNOWN_CHUNKS option. If enabled this option also
+# applies to write (see png.h), otherwise the write API simply writes all the
+# chunks it is given.
+#
+# The second option extends the unknown handling to allow known chunks to be
+# handled as though they were unknown. This option doesn't change any APIs, it
+# merely turns on the code to check known as well as unknown chunks.
+#
+# This option no longer affects the write code. It can be safely disabled and
+# will prevent applications stopping libpng reading known chunks.
+option SET_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS
+option HANDLE_AS_UNKNOWN requires SET_UNKNOWN_CHUNKS
+
+# The following options are derived from the above and should not be turned on
+# explicitly.
+option READ_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS disabled
+option STORE_UNKNOWN_CHUNKS requires UNKNOWN_CHUNKS disabled
+
+option CONVERT_tIME requires WRITE_ANCILLARY_CHUNKS
+# The "tm" structure is not supported on WindowsCE
+
+@#ifdef _WIN32_WCE
+@# define PNG_NO_CONVERT_tIME
+@#endif
+
+option WRITE_FILTER requires WRITE
+
+option SAVE_INT_32 disabled
+# png_save_int_32 is required internally for writing the ancillary chunks oFFs
+# and pCAL and for both reading and writing iCCP (for the generation/checking of
+# the corresponding cHRM/gAMA chunks) if full ICC is supported.
+
+# added at libpng-1.5.4
+
+option WRITE_OPTIMIZE_CMF requires WRITE
+
+option READ_COMPRESSED_TEXT disabled
+option READ_iCCP enables READ_COMPRESSED_TEXT
+option READ_iTXt enables READ_COMPRESSED_TEXT
+option READ_zTXt enables READ_COMPRESSED_TEXT
+
+option WRITE_oFFs enables SAVE_INT_32
+option WRITE_pCAL enables SAVE_INT_32
+option WRITE_cHRM enables SAVE_INT_32
+
+option WRITE_COMPRESSED_TEXT disabled
+option WRITE_iCCP enables WRITE_COMPRESSED_TEXT
+option WRITE_iTXt enables WRITE_COMPRESSED_TEXT
+option WRITE_zTXt enables WRITE_COMPRESSED_TEXT
+
+# Turn this off to disable png_read_png() and png_write_png() and
+# leave the row_pointers member out of the info structure.
+
+option INFO_IMAGE
+
+# added at libpng-1.5.10
+# Turn this off to disable warning about invalid palette index and
+# leave the num_palette_max member out of the png structure.
+
+option CHECK_FOR_INVALID_INDEX enables READ_CHECK_FOR_INVALID_INDEX
+option CHECK_FOR_INVALID_INDEX enables WRITE_CHECK_FOR_INVALID_INDEX
+option READ_CHECK_FOR_INVALID_INDEX requires READ, CHECK_FOR_INVALID_INDEX
+option WRITE_CHECK_FOR_INVALID_INDEX requires WRITE, CHECK_FOR_INVALID_INDEX
+
+# added at libpng-1.5.15
+option GET_PALETTE_MAX enables READ_GET_PALETTE_MAX WRITE_GET_PALETTE_MAX
+option READ_GET_PALETTE_MAX requires READ_CHECK_FOR_INVALID_INDEX disabled
+option WRITE_GET_PALETTE_MAX requires WRITE_CHECK_FOR_INVALID_INDEX disabled
+
+# Simplified API options (added at libpng-1.6.0)
+# In libpng 1.6.8 the handling of these options was changed to used 'requires'
+# throughout, so that disabling some of the low level support always disables
+# the base simplified read/write API. This much simplifies the handling and
+# makes 'everything = off' work in a more intuitive way. It eliminates a
+# previously reported feature that APIs previously enabled by the simplified
+# API couldn't be turned off without explicitly turning off the simplified
+# APIs.
+#
+# Read:
+option SIMPLIFIED_READ,
+ requires SEQUENTIAL_READ, READ_TRANSFORMS, SETJMP, BENIGN_ERRORS,
+ READ_EXPAND, READ_16BIT, READ_EXPAND_16, READ_SCALE_16_TO_8,
+ READ_RGB_TO_GRAY, READ_ALPHA_MODE, READ_BACKGROUND, READ_STRIP_ALPHA,
+ READ_FILLER, READ_SWAP, READ_PACK, READ_GRAY_TO_RGB, READ_GAMMA,
+ READ_tRNS, READ_bKGD, READ_gAMA, READ_cHRM, READ_sRGB, READ_sBIT
+
+# AFIRST and BGR read options:
+# Prior to libpng 1.6.8 these were disabled but switched on if the low level
+# libpng routines that do the swaps were enabled. This worked but was
+# confusing. In libpng 1.6.8 the options were changed to simple 'requires'
+# and are enabled by default. This should work the same way in practice.
+option SIMPLIFIED_READ_AFIRST enables FORMAT_AFIRST,
+ requires SIMPLIFIED_READ READ_SWAP_ALPHA
+
+option SIMPLIFIED_READ_BGR enables FORMAT_BGR,
+ requires SIMPLIFIED_READ READ_BGR
+
+# Write:
+option SIMPLIFIED_WRITE,
+ requires WRITE, SETJMP, WRITE_SWAP, WRITE_PACK,
+ WRITE_tRNS, WRITE_gAMA, WRITE_sRGB, WRITE_cHRM
+
+# 1.6.22: allow simplified write without stdio support:
+option SIMPLIFIED_WRITE_STDIO requires SIMPLIFIED_WRITE STDIO
+
+option SIMPLIFIED_WRITE_AFIRST enables FORMAT_AFIRST,
+ requires SIMPLIFIED_WRITE WRITE_SWAP_ALPHA
+
+option SIMPLIFIED_WRITE_BGR enables FORMAT_BGR,
+ requires SIMPLIFIED_WRITE WRITE_BGR
+
+# Formats:
+option FORMAT_AFIRST disabled
+option FORMAT_BGR disabled
diff --git a/xs/src/png/libpng/scripts/pnglibconf.h.prebuilt b/xs/src/png/libpng/scripts/pnglibconf.h.prebuilt
new file mode 100644
index 000000000..53b5e442c
--- /dev/null
+++ b/xs/src/png/libpng/scripts/pnglibconf.h.prebuilt
@@ -0,0 +1,220 @@
+/* libpng 1.6.34 STANDARD API DEFINITION */
+
+/* pnglibconf.h - library build configuration */
+
+/* Libpng version 1.6.34 - September 29, 2017 */
+
+/* Copyright (c) 1998-2017 Glenn Randers-Pehrson */
+
+/* This code is released under the libpng license. */
+/* For conditions of distribution and use, see the disclaimer */
+/* and license in png.h */
+
+/* pnglibconf.h */
+/* Machine generated file: DO NOT EDIT */
+/* Derived from: scripts/pnglibconf.dfa */
+#ifndef PNGLCONF_H
+#define PNGLCONF_H
+/* options */
+#define PNG_16BIT_SUPPORTED
+#define PNG_ALIGNED_MEMORY_SUPPORTED
+/*#undef PNG_ARM_NEON_API_SUPPORTED*/
+/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
+/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/
+/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/
+#define PNG_BENIGN_ERRORS_SUPPORTED
+#define PNG_BENIGN_READ_ERRORS_SUPPORTED
+/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
+#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#define PNG_COLORSPACE_SUPPORTED
+#define PNG_CONSOLE_IO_SUPPORTED
+#define PNG_CONVERT_tIME_SUPPORTED
+#define PNG_EASY_ACCESS_SUPPORTED
+/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
+#define PNG_ERROR_TEXT_SUPPORTED
+#define PNG_FIXED_POINT_SUPPORTED
+#define PNG_FLOATING_ARITHMETIC_SUPPORTED
+#define PNG_FLOATING_POINT_SUPPORTED
+#define PNG_FORMAT_AFIRST_SUPPORTED
+#define PNG_FORMAT_BGR_SUPPORTED
+#define PNG_GAMMA_SUPPORTED
+#define PNG_GET_PALETTE_MAX_SUPPORTED
+#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#define PNG_INCH_CONVERSIONS_SUPPORTED
+#define PNG_INFO_IMAGE_SUPPORTED
+#define PNG_IO_STATE_SUPPORTED
+#define PNG_MNG_FEATURES_SUPPORTED
+#define PNG_POINTER_INDEXING_SUPPORTED
+#define PNG_PROGRESSIVE_READ_SUPPORTED
+#define PNG_READ_16BIT_SUPPORTED
+#define PNG_READ_ALPHA_MODE_SUPPORTED
+#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#define PNG_READ_BACKGROUND_SUPPORTED
+#define PNG_READ_BGR_SUPPORTED
+#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
+#define PNG_READ_COMPRESSED_TEXT_SUPPORTED
+#define PNG_READ_EXPAND_16_SUPPORTED
+#define PNG_READ_EXPAND_SUPPORTED
+#define PNG_READ_FILLER_SUPPORTED
+#define PNG_READ_GAMMA_SUPPORTED
+#define PNG_READ_GET_PALETTE_MAX_SUPPORTED
+#define PNG_READ_GRAY_TO_RGB_SUPPORTED
+#define PNG_READ_INTERLACING_SUPPORTED
+#define PNG_READ_INT_FUNCTIONS_SUPPORTED
+#define PNG_READ_INVERT_ALPHA_SUPPORTED
+#define PNG_READ_INVERT_SUPPORTED
+#define PNG_READ_OPT_PLTE_SUPPORTED
+#define PNG_READ_PACKSWAP_SUPPORTED
+#define PNG_READ_PACK_SUPPORTED
+#define PNG_READ_QUANTIZE_SUPPORTED
+#define PNG_READ_RGB_TO_GRAY_SUPPORTED
+#define PNG_READ_SCALE_16_TO_8_SUPPORTED
+#define PNG_READ_SHIFT_SUPPORTED
+#define PNG_READ_STRIP_16_TO_8_SUPPORTED
+#define PNG_READ_STRIP_ALPHA_SUPPORTED
+#define PNG_READ_SUPPORTED
+#define PNG_READ_SWAP_ALPHA_SUPPORTED
+#define PNG_READ_SWAP_SUPPORTED
+#define PNG_READ_TEXT_SUPPORTED
+#define PNG_READ_TRANSFORMS_SUPPORTED
+#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_READ_USER_CHUNKS_SUPPORTED
+#define PNG_READ_USER_TRANSFORM_SUPPORTED
+#define PNG_READ_bKGD_SUPPORTED
+#define PNG_READ_cHRM_SUPPORTED
+#define PNG_READ_eXIf_SUPPORTED
+#define PNG_READ_gAMA_SUPPORTED
+#define PNG_READ_hIST_SUPPORTED
+#define PNG_READ_iCCP_SUPPORTED
+#define PNG_READ_iTXt_SUPPORTED
+#define PNG_READ_oFFs_SUPPORTED
+#define PNG_READ_pCAL_SUPPORTED
+#define PNG_READ_pHYs_SUPPORTED
+#define PNG_READ_sBIT_SUPPORTED
+#define PNG_READ_sCAL_SUPPORTED
+#define PNG_READ_sPLT_SUPPORTED
+#define PNG_READ_sRGB_SUPPORTED
+#define PNG_READ_tEXt_SUPPORTED
+#define PNG_READ_tIME_SUPPORTED
+#define PNG_READ_tRNS_SUPPORTED
+#define PNG_READ_zTXt_SUPPORTED
+#define PNG_SAVE_INT_32_SUPPORTED
+#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_SEQUENTIAL_READ_SUPPORTED
+#define PNG_SETJMP_SUPPORTED
+#define PNG_SET_OPTION_SUPPORTED
+#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_SET_USER_LIMITS_SUPPORTED
+#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
+#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_READ_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_SUPPORTED
+#define PNG_STDIO_SUPPORTED
+#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_TEXT_SUPPORTED
+#define PNG_TIME_RFC1123_SUPPORTED
+#define PNG_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_USER_CHUNKS_SUPPORTED
+#define PNG_USER_LIMITS_SUPPORTED
+#define PNG_USER_MEM_SUPPORTED
+#define PNG_USER_TRANSFORM_INFO_SUPPORTED
+#define PNG_USER_TRANSFORM_PTR_SUPPORTED
+#define PNG_WARNINGS_SUPPORTED
+#define PNG_WRITE_16BIT_SUPPORTED
+#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#define PNG_WRITE_BGR_SUPPORTED
+#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
+#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
+#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+#define PNG_WRITE_FILLER_SUPPORTED
+#define PNG_WRITE_FILTER_SUPPORTED
+#define PNG_WRITE_FLUSH_SUPPORTED
+#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED
+#define PNG_WRITE_INTERLACING_SUPPORTED
+#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+#define PNG_WRITE_INVERT_SUPPORTED
+#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+#define PNG_WRITE_PACKSWAP_SUPPORTED
+#define PNG_WRITE_PACK_SUPPORTED
+#define PNG_WRITE_SHIFT_SUPPORTED
+#define PNG_WRITE_SUPPORTED
+#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
+#define PNG_WRITE_SWAP_SUPPORTED
+#define PNG_WRITE_TEXT_SUPPORTED
+#define PNG_WRITE_TRANSFORMS_SUPPORTED
+#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#define PNG_WRITE_bKGD_SUPPORTED
+#define PNG_WRITE_cHRM_SUPPORTED
+#define PNG_WRITE_eXIf_SUPPORTED
+#define PNG_WRITE_gAMA_SUPPORTED
+#define PNG_WRITE_hIST_SUPPORTED
+#define PNG_WRITE_iCCP_SUPPORTED
+#define PNG_WRITE_iTXt_SUPPORTED
+#define PNG_WRITE_oFFs_SUPPORTED
+#define PNG_WRITE_pCAL_SUPPORTED
+#define PNG_WRITE_pHYs_SUPPORTED
+#define PNG_WRITE_sBIT_SUPPORTED
+#define PNG_WRITE_sCAL_SUPPORTED
+#define PNG_WRITE_sPLT_SUPPORTED
+#define PNG_WRITE_sRGB_SUPPORTED
+#define PNG_WRITE_tEXt_SUPPORTED
+#define PNG_WRITE_tIME_SUPPORTED
+#define PNG_WRITE_tRNS_SUPPORTED
+#define PNG_WRITE_zTXt_SUPPORTED
+#define PNG_bKGD_SUPPORTED
+#define PNG_cHRM_SUPPORTED
+#define PNG_eXIf_SUPPORTED
+#define PNG_gAMA_SUPPORTED
+#define PNG_hIST_SUPPORTED
+#define PNG_iCCP_SUPPORTED
+#define PNG_iTXt_SUPPORTED
+#define PNG_oFFs_SUPPORTED
+#define PNG_pCAL_SUPPORTED
+#define PNG_pHYs_SUPPORTED
+#define PNG_sBIT_SUPPORTED
+#define PNG_sCAL_SUPPORTED
+#define PNG_sPLT_SUPPORTED
+#define PNG_sRGB_SUPPORTED
+#define PNG_tEXt_SUPPORTED
+#define PNG_tIME_SUPPORTED
+#define PNG_tRNS_SUPPORTED
+#define PNG_zTXt_SUPPORTED
+/* end of options */
+/* settings */
+#define PNG_API_RULE 0
+#define PNG_DEFAULT_READ_MACROS 1
+#define PNG_GAMMA_THRESHOLD_FIXED 5000
+#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
+#define PNG_INFLATE_BUF_SIZE 1024
+#define PNG_LINKAGE_API extern
+#define PNG_LINKAGE_CALLBACK extern
+#define PNG_LINKAGE_DATA extern
+#define PNG_LINKAGE_FUNCTION extern
+#define PNG_MAX_GAMMA_8 11
+#define PNG_QUANTIZE_BLUE_BITS 5
+#define PNG_QUANTIZE_GREEN_BITS 5
+#define PNG_QUANTIZE_RED_BITS 5
+#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
+#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
+#define PNG_USER_CHUNK_CACHE_MAX 1000
+#define PNG_USER_CHUNK_MALLOC_MAX 8000000
+#define PNG_USER_HEIGHT_MAX 1000000
+#define PNG_USER_WIDTH_MAX 1000000
+#define PNG_ZBUF_SIZE 8192
+#define PNG_ZLIB_VERNUM 0 /* unknown */
+#define PNG_Z_DEFAULT_COMPRESSION (-1)
+#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
+#define PNG_Z_DEFAULT_STRATEGY 1
+#define PNG_sCAL_PRECISION 5
+#define PNG_sRGB_PROFILE_CHECKS 2
+/* end of settings */
+#endif /* PNGLCONF_H */
diff --git a/xs/src/png/libpng/scripts/prefix.c b/xs/src/png/libpng/scripts/prefix.c
new file mode 100644
index 000000000..8b604a091
--- /dev/null
+++ b/xs/src/png/libpng/scripts/prefix.c
@@ -0,0 +1,24 @@
+
+/* prefix.c - generate an unprefixed symbol list
+ *
+ * Last changed in libpng version 1.6.16 [December 22, 2014]
+ * Copyright (c) 2013-2014 Glenn Randers-Pehrson
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_EXPORTA(ordinal, type, name, args, attributes)\
+ PNG_DFN "@" name "@"
+
+/* The configuration information *before* the additional of symbol renames,
+ * the list is the C name list; no symbol prefix.
+ */
+#include "pnglibconf.out"
+
+PNG_DFN_START_SORT 1
+
+#include "../png.h"
+
+PNG_DFN_END_SORT
diff --git a/xs/src/png/libpng/scripts/sym.c b/xs/src/png/libpng/scripts/sym.c
new file mode 100644
index 000000000..ea9e4c507
--- /dev/null
+++ b/xs/src/png/libpng/scripts/sym.c
@@ -0,0 +1,15 @@
+
+/* sym.c - define format of libpng.sym
+ *
+ * Last changed in libpng version 1.6.16 [December 22, 2014]
+ * Copyright (c) 2011-2014 Glenn Randers-Pehrson
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_EXPORTA(ordinal, type, name, args, attributes)\
+ PNG_DFN "@" SYMBOL_PREFIX "@@" name "@"
+
+#include "../png.h"
diff --git a/xs/src/png/libpng/scripts/symbols.c b/xs/src/png/libpng/scripts/symbols.c
new file mode 100644
index 000000000..28b841d8b
--- /dev/null
+++ b/xs/src/png/libpng/scripts/symbols.c
@@ -0,0 +1,58 @@
+
+/* symbols.c - find all exported symbols
+ *
+ * Last changed in libpng version 1.6.16 [December 22, 2014]
+ * Copyright (c) 2011-2014 Glenn Randers-Pehrson
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* NOTE: making 'symbols.chk' checks both that the exported
+ * symbols in the library don't change and (implicitly) that
+ * scripts/pnglibconf.h.prebuilt is as expected.
+ * If scripts/pnglibconf.h.prebuilt is remade using
+ * scripts/pnglibconf.dfa then this checks the .dfa file too.
+ */
+
+#define PNG_EXPORTA(ordinal, type, name, args, attributes)\
+ PNG_DFN "@" name "@ @@" ordinal "@"
+#define PNG_REMOVED(ordinal, type, name, args, attributes)\
+ PNG_DFN "; @" name "@ @@" ordinal "@"
+#define PNG_EXPORT_LAST_ORDINAL(ordinal)\
+ PNG_DFN "; @@" ordinal "@"
+
+/* Read the defaults, but use scripts/pnglibconf.h.prebuilt; the 'standard'
+ * header file.
+ */
+#include "pnglibconf.h.prebuilt"
+#include "../png.h"
+
+/* Some things are turned off by default. Turn these things
+ * on here (by hand) to get the APIs they expose and validate
+ * that no harm is done. This list is the set of options
+ * defaulted to 'off' in scripts/pnglibconf.dfa
+ *
+ * Maintenance: if scripts/pnglibconf.dfa options are changed
+ * from, or to, 'disabled' this needs updating!
+ */
+#define PNG_BENIGN_ERRORS_SUPPORTED
+#define PNG_ERROR_NUMBERS_SUPPORTED
+#define PNG_READ_BIG_ENDIAN_SUPPORTED /* should do nothing! */
+#define PNG_INCH_CONVERSIONS_SUPPORTED
+#define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+#define PNG_SET_OPTION_SUPPORTED
+
+#undef PNG_H
+#include "../png.h"
+
+/* Finally there are a couple of places where option support
+ * actually changes the APIs revealed using a #if/#else/#endif
+ * test in png.h, test these here.
+ */
+#undef PNG_FLOATING_POINT_SUPPORTED /* Exposes 'fixed' APIs */
+#undef PNG_ERROR_TEXT_SUPPORTED /* Exposes unsupported APIs */
+
+#undef PNG_H
+#include "../png.h"
diff --git a/xs/src/png/libpng/scripts/symbols.def b/xs/src/png/libpng/scripts/symbols.def
new file mode 100644
index 000000000..4a3c3ff41
--- /dev/null
+++ b/xs/src/png/libpng/scripts/symbols.def
@@ -0,0 +1,256 @@
+;Version 1.6.35beta02
+;--------------------------------------------------------------
+; LIBPNG symbol list as a Win32 DEF file
+; Contains all the symbols that can be exported from libpng
+;--------------------------------------------------------------
+LIBRARY
+
+EXPORTS
+ png_access_version_number @1
+ png_set_sig_bytes @2
+ png_sig_cmp @3
+ png_create_read_struct @4
+ png_create_write_struct @5
+ png_get_compression_buffer_size @6
+ png_set_compression_buffer_size @7
+ png_set_longjmp_fn @8
+ png_longjmp @9
+ png_reset_zstream @10
+ png_create_read_struct_2 @11
+ png_create_write_struct_2 @12
+ png_write_sig @13
+ png_write_chunk @14
+ png_write_chunk_start @15
+ png_write_chunk_data @16
+ png_write_chunk_end @17
+ png_create_info_struct @18
+ png_info_init_3 @19
+ png_write_info_before_PLTE @20
+ png_write_info @21
+ png_read_info @22
+ png_convert_to_rfc1123 @23
+ png_convert_from_struct_tm @24
+ png_convert_from_time_t @25
+ png_set_expand @26
+ png_set_expand_gray_1_2_4_to_8 @27
+ png_set_palette_to_rgb @28
+ png_set_tRNS_to_alpha @29
+ png_set_bgr @30
+ png_set_gray_to_rgb @31
+ png_set_rgb_to_gray @32
+ png_set_rgb_to_gray_fixed @33
+ png_get_rgb_to_gray_status @34
+ png_build_grayscale_palette @35
+ png_set_strip_alpha @36
+ png_set_swap_alpha @37
+ png_set_invert_alpha @38
+ png_set_filler @39
+ png_set_add_alpha @40
+ png_set_swap @41
+ png_set_packing @42
+ png_set_packswap @43
+ png_set_shift @44
+ png_set_interlace_handling @45
+ png_set_invert_mono @46
+ png_set_background @47
+ png_set_strip_16 @48
+ png_set_quantize @49
+ png_set_gamma @50
+ png_set_flush @51
+ png_write_flush @52
+ png_start_read_image @53
+ png_read_update_info @54
+ png_read_rows @55
+ png_read_row @56
+ png_read_image @57
+ png_write_row @58
+ png_write_rows @59
+ png_write_image @60
+ png_write_end @61
+ png_read_end @62
+ png_destroy_info_struct @63
+ png_destroy_read_struct @64
+ png_destroy_write_struct @65
+ png_set_crc_action @66
+ png_set_filter @67
+ png_set_filter_heuristics @68
+ png_set_compression_level @69
+ png_set_compression_mem_level @70
+ png_set_compression_strategy @71
+ png_set_compression_window_bits @72
+ png_set_compression_method @73
+ png_init_io @74
+ png_set_error_fn @75
+ png_get_error_ptr @76
+ png_set_write_fn @77
+ png_set_read_fn @78
+ png_get_io_ptr @79
+ png_set_read_status_fn @80
+ png_set_write_status_fn @81
+ png_set_mem_fn @82
+ png_get_mem_ptr @83
+ png_set_read_user_transform_fn @84
+ png_set_write_user_transform_fn @85
+ png_set_user_transform_info @86
+ png_get_user_transform_ptr @87
+ png_set_read_user_chunk_fn @88
+ png_get_user_chunk_ptr @89
+ png_set_progressive_read_fn @90
+ png_get_progressive_ptr @91
+ png_process_data @92
+ png_progressive_combine_row @93
+ png_malloc @94
+ png_calloc @95
+ png_malloc_warn @96
+ png_free @97
+ png_free_data @98
+ png_data_freer @99
+ png_malloc_default @100
+ png_free_default @101
+ png_error @102
+ png_chunk_error @103
+ png_err @104
+ png_warning @105
+ png_chunk_warning @106
+ png_benign_error @107
+ png_chunk_benign_error @108
+ png_set_benign_errors @109
+ png_get_valid @110
+ png_get_rowbytes @111
+ png_get_rows @112
+ png_set_rows @113
+ png_get_channels @114
+ png_get_image_width @115
+ png_get_image_height @116
+ png_get_bit_depth @117
+ png_get_color_type @118
+ png_get_filter_type @119
+ png_get_interlace_type @120
+ png_get_compression_type @121
+ png_get_pixels_per_meter @122
+ png_get_x_pixels_per_meter @123
+ png_get_y_pixels_per_meter @124
+ png_get_pixel_aspect_ratio @125
+ png_get_x_offset_pixels @126
+ png_get_y_offset_pixels @127
+ png_get_x_offset_microns @128
+ png_get_y_offset_microns @129
+ png_get_signature @130
+ png_get_bKGD @131
+ png_set_bKGD @132
+ png_get_cHRM @133
+ png_get_cHRM_fixed @134
+ png_set_cHRM @135
+ png_set_cHRM_fixed @136
+ png_get_gAMA @137
+ png_get_gAMA_fixed @138
+ png_set_gAMA @139
+ png_set_gAMA_fixed @140
+ png_get_hIST @141
+ png_set_hIST @142
+ png_get_IHDR @143
+ png_set_IHDR @144
+ png_get_oFFs @145
+ png_set_oFFs @146
+ png_get_pCAL @147
+ png_set_pCAL @148
+ png_get_pHYs @149
+ png_set_pHYs @150
+ png_get_PLTE @151
+ png_set_PLTE @152
+ png_get_sBIT @153
+ png_set_sBIT @154
+ png_get_sRGB @155
+ png_set_sRGB @156
+ png_set_sRGB_gAMA_and_cHRM @157
+ png_get_iCCP @158
+ png_set_iCCP @159
+ png_get_sPLT @160
+ png_set_sPLT @161
+ png_get_text @162
+ png_set_text @163
+ png_get_tIME @164
+ png_set_tIME @165
+ png_get_tRNS @166
+ png_set_tRNS @167
+ png_get_sCAL @168
+ png_get_sCAL_s @169
+ png_set_sCAL @170
+ png_set_sCAL_s @171
+ png_set_keep_unknown_chunks @172
+ png_handle_as_unknown @173
+ png_set_unknown_chunks @174
+ png_set_unknown_chunk_location @175
+ png_get_unknown_chunks @176
+ png_set_invalid @177
+ png_read_png @178
+ png_write_png @179
+ png_get_copyright @180
+ png_get_header_ver @181
+ png_get_header_version @182
+ png_get_libpng_ver @183
+ png_permit_mng_features @184
+ png_set_strip_error_numbers @185
+ png_set_user_limits @186
+ png_get_user_width_max @187
+ png_get_user_height_max @188
+ png_set_chunk_cache_max @189
+ png_get_chunk_cache_max @190
+ png_set_chunk_malloc_max @191
+ png_get_chunk_malloc_max @192
+ png_get_pixels_per_inch @193
+ png_get_x_pixels_per_inch @194
+ png_get_y_pixels_per_inch @195
+ png_get_x_offset_inches @196
+ png_get_y_offset_inches @197
+ png_get_pHYs_dpi @198
+ png_get_io_state @199
+ png_get_uint_32 @201
+ png_get_uint_16 @202
+ png_get_int_32 @203
+ png_get_uint_31 @204
+ png_save_uint_32 @205
+ png_save_int_32 @206
+ png_save_uint_16 @207
+ png_set_gamma_fixed @208
+ png_set_filter_heuristics_fixed @209
+ png_get_pixel_aspect_ratio_fixed @210
+ png_get_x_offset_inches_fixed @211
+ png_get_y_offset_inches_fixed @212
+ png_set_sCAL_fixed @213
+ png_get_sCAL_fixed @214
+ png_set_background_fixed @215
+ png_get_io_chunk_type @216
+ png_get_current_row_number @217
+ png_get_current_pass_number @218
+ png_process_data_pause @219
+ png_process_data_skip @220
+ png_set_expand_16 @221
+ png_set_text_compression_level @222
+ png_set_text_compression_mem_level @223
+ png_set_text_compression_strategy @224
+ png_set_text_compression_window_bits @225
+ png_set_text_compression_method @226
+ png_set_alpha_mode @227
+ png_set_alpha_mode_fixed @228
+ png_set_scale_16 @229
+ png_get_cHRM_XYZ @230
+ png_get_cHRM_XYZ_fixed @231
+ png_set_cHRM_XYZ @232
+ png_set_cHRM_XYZ_fixed @233
+ png_image_begin_read_from_file @234
+ png_image_begin_read_from_stdio @235
+ png_image_begin_read_from_memory @236
+ png_image_finish_read @237
+ png_image_free @238
+ png_image_write_to_file @239
+ png_image_write_to_stdio @240
+ png_convert_to_rfc1123_buffer @241
+ png_set_check_for_invalid_index @242
+ png_get_palette_max @243
+ png_set_option @244
+ png_image_write_to_memory @245
+ png_get_eXIf @246
+ png_set_eXIf @247
+ png_get_eXIf_1 @248
+ png_set_eXIf_1 @249
diff --git a/xs/src/png/libpng/scripts/test.cmake.in b/xs/src/png/libpng/scripts/test.cmake.in
new file mode 100644
index 000000000..fa6a889bb
--- /dev/null
+++ b/xs/src/png/libpng/scripts/test.cmake.in
@@ -0,0 +1,31 @@
+# test.cmake.in
+
+# Copyright (C) 2016 Glenn Randers-Pehrson
+# Written by Roger Leigh, 2016
+
+# This code is released under the libpng license.
+# For conditions of distribution and use, see the disclaimer
+# and license in png.h
+
+set(TEST_OPTIONS "@TEST_OPTIONS@")
+set(TEST_FILES "@TEST_FILES@")
+
+foreach(file ${TEST_FILES})
+ file(TO_NATIVE_PATH "${file}" native_file)
+ list(APPEND NATIVE_TEST_FILES "${native_file}")
+endforeach()
+
+# Add the directory containing libpng to the PATH (Windows only)
+if(WIN32)
+ get_filename_component(LIBPNG_DIR "${LIBPNG}" PATH)
+ file(TO_NATIVE_PATH "${LIBPNG_DIR}" LIBPNG_DIR)
+ set(ENV{PATH} "${LIBPNG_DIR};$ENV{PATH}")
+endif()
+
+execute_process(COMMAND "${CMAKE_COMMAND}" -E echo "Running ${TEST_COMMAND}" ${TEST_OPTIONS} ${NATIVE_TEST_FILES})
+
+execute_process(COMMAND "${TEST_COMMAND}" ${TEST_OPTIONS} ${NATIVE_TEST_FILES}
+ RESULT_VARIABLE TEST_STATUS)
+if(TEST_STATUS)
+ message(FATAL_ERROR "Returned failed status ${TEST_STATUS}!")
+endif()
diff --git a/xs/src/png/libpng/scripts/vers.c b/xs/src/png/libpng/scripts/vers.c
new file mode 100644
index 000000000..de7319716
--- /dev/null
+++ b/xs/src/png/libpng/scripts/vers.c
@@ -0,0 +1,19 @@
+
+/* vers.c - define format of libpng.vers
+ *
+ * Last changed in libpng version 1.6.16 [December 22, 2014]
+ * Copyright (c) 2011-2014 Glenn Randers-Pehrson
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#define PNG_EXPORTA(ordinal, type, name, args, attributes)\
+ PNG_DFN " @" SYMBOL_PREFIX "@@" name "@;"
+
+PNG_DFN "@" PNGLIB_LIBNAME "@ {global:"
+
+#include "../png.h"
+
+PNG_DFN "local: *; };"
diff --git a/xs/src/png/palette.hpp b/xs/src/png/palette.hpp
new file mode 100644
index 000000000..917f28007
--- /dev/null
+++ b/xs/src/png/palette.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_PALETTE_HPP_INCLUDED
+#define PNGPP_PALETTE_HPP_INCLUDED
+
+#include <vector>
+#include "color.hpp"
+
+namespace png
+{
+
+ /**
+ * \brief The palette type. Currently implemented as \c std::vector
+ * of png::color.
+ */
+ typedef std::vector< color > palette;
+
+} // namespace png
+
+#endif // PNGPP_PALETTE_HPP_INCLUDED
diff --git a/xs/src/png/pixel_traits.hpp b/xs/src/png/pixel_traits.hpp
new file mode 100644
index 000000000..8ffdfeedb
--- /dev/null
+++ b/xs/src/png/pixel_traits.hpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_PIXEL_TRAITS_HPP_INCLUDED
+#define PNGPP_PIXEL_TRAITS_HPP_INCLUDED
+
+#include <limits>
+#include "types.hpp"
+
+namespace png
+{
+
+ /**
+ * \brief Pixel traits class template.
+ *
+ * Provides information about pixel color type and components bit depth.
+ * Not implemented--see specializations.
+ *
+ * \see pixel_traits<rgb_pixel>, pixel_traits<rgba_pixel>
+ */
+ template< typename pixel > struct pixel_traits;
+
+ /**
+ * \brief Basic pixel traits class template.
+ *
+ * Provides common implementation for various pixel_traits<>
+ * specializations.
+ */
+ template< typename pixel,
+ typename component,
+ color_type pixel_color_type,
+ int channels_value = sizeof(pixel) / sizeof(component),
+ int bit_depth_value = std::numeric_limits< component >::digits >
+ struct basic_pixel_traits
+ {
+ typedef pixel pixel_type;
+ typedef component component_type;
+
+ static color_type get_color_type()
+ {
+ return pixel_color_type;
+ }
+
+ static const int channels = channels_value;
+ static int get_channels()
+ {
+ return channels;
+ }
+
+ static const int bit_depth = bit_depth_value;
+ static int get_bit_depth()
+ {
+ return bit_depth;
+ }
+ };
+
+ /**
+ * \brief Basic pixel traits class template for pixels with alpha
+ * channel.
+ */
+ template< typename component >
+ struct basic_alpha_pixel_traits
+ {
+ /**
+ * \brief Returns the default alpha channel filler for full
+ * opacity.
+ */
+ static component get_alpha_filler()
+ {
+ return std::numeric_limits< component >::max();
+ }
+ };
+
+} // namespace png
+
+#endif // PNGPP_PIXEL_TRAITS_HPP_INCLUDED
diff --git a/xs/src/png/tRNS.hpp b/xs/src/png/tRNS.hpp
new file mode 100644
index 000000000..ff0181643
--- /dev/null
+++ b/xs/src/png/tRNS.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_TRNS_HPP_INCLUDED
+#define PNGPP_TRNS_HPP_INCLUDED
+
+#include <vector>
+#include "color.hpp"
+
+namespace png
+{
+
+ /**
+ * \brief The palette transparency map type. Currently
+ * implemented as \c std::vector of png::byte.
+ */
+ typedef std::vector< byte > tRNS;
+
+} // namespace png
+
+#endif // PNGPP_TRNS_HPP_INCLUDED
diff --git a/xs/src/png/types.hpp b/xs/src/png/types.hpp
new file mode 100644
index 000000000..1538d6bd2
--- /dev/null
+++ b/xs/src/png/types.hpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_TYPES_HPP_INCLUDED
+#define PNGPP_TYPES_HPP_INCLUDED
+
+#include <png.h>
+
+namespace png
+{
+
+ typedef png_byte byte;
+ typedef png_uint_16 uint_16;
+ typedef png_uint_32 uint_32;
+ typedef png_fixed_point fixed_point;
+ typedef png_color_8 color_info;
+ typedef png_color_16 color_info_16;
+
+ enum color_type
+ {
+ color_type_none = -1,
+ color_type_gray = PNG_COLOR_TYPE_GRAY,
+ color_type_palette = PNG_COLOR_TYPE_PALETTE,
+ color_type_rgb = PNG_COLOR_TYPE_RGB,
+ color_type_rgb_alpha = PNG_COLOR_TYPE_RGB_ALPHA,
+ color_type_gray_alpha = PNG_COLOR_TYPE_GRAY_ALPHA,
+ color_type_rgba = PNG_COLOR_TYPE_RGBA,
+ color_type_ga = PNG_COLOR_TYPE_GA
+ };
+
+ enum color_mask
+ {
+ color_mask_palette = PNG_COLOR_MASK_PALETTE,
+ color_mask_color = PNG_COLOR_MASK_COLOR,
+ color_mask_rgb = color_mask_color,
+ color_mask_alpha = PNG_COLOR_MASK_ALPHA
+ };
+
+ enum filler_type
+ {
+ filler_before = PNG_FILLER_BEFORE,
+ filler_after = PNG_FILLER_AFTER
+ };
+
+ enum rgb_to_gray_error_action
+ {
+ rgb_to_gray_silent = 1,
+ rgb_to_gray_warning = 2,
+ rgb_to_gray_error = 3
+ };
+
+ enum interlace_type
+ {
+ interlace_none = PNG_INTERLACE_NONE,
+ interlace_adam7 = PNG_INTERLACE_ADAM7
+ };
+
+ enum compression_type
+ {
+ compression_type_base = PNG_COMPRESSION_TYPE_BASE,
+ compression_type_default = PNG_COMPRESSION_TYPE_DEFAULT
+ };
+
+ enum filter_type
+ {
+ filter_type_base = PNG_FILTER_TYPE_BASE,
+ intrapixel_differencing = PNG_INTRAPIXEL_DIFFERENCING,
+ filter_type_default = PNG_FILTER_TYPE_DEFAULT
+ };
+
+ enum chunk
+ {
+ chunk_gAMA = PNG_INFO_gAMA,
+ chunk_sBIT = PNG_INFO_sBIT,
+ chunk_cHRM = PNG_INFO_cHRM,
+ chunk_PLTE = PNG_INFO_PLTE,
+ chunk_tRNS = PNG_INFO_tRNS,
+ chunk_bKGD = PNG_INFO_bKGD,
+ chunk_hIST = PNG_INFO_hIST,
+ chunk_pHYs = PNG_INFO_pHYs,
+ chunk_oFFs = PNG_INFO_oFFs,
+ chunk_tIME = PNG_INFO_tIME,
+ chunk_pCAL = PNG_INFO_pCAL,
+ chunk_sRGB = PNG_INFO_sRGB,
+ chunk_iCCP = PNG_INFO_iCCP,
+ chunk_sPLT = PNG_INFO_sPLT,
+ chunk_sCAL = PNG_INFO_sCAL,
+ chunk_IDAT = PNG_INFO_IDAT
+ };
+
+} // namespace png
+
+#endif // PNGPP_TYPES_HPP_INCLUDED
diff --git a/xs/src/png/writer.hpp b/xs/src/png/writer.hpp
new file mode 100644
index 000000000..448dfd50b
--- /dev/null
+++ b/xs/src/png/writer.hpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2007,2008 Alex Shulgin
+ *
+ * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
+ * software; the exact copying conditions are as follows:
+ *
+ * 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.
+ */
+#ifndef PNGPP_WRITER_HPP_INCLUDED
+#define PNGPP_WRITER_HPP_INCLUDED
+
+#include <cassert>
+#include "io_base.hpp"
+
+namespace png
+{
+
+ /**
+ * \brief PNG writer class template. This is the low-level
+ * writing interface--use image class or generator class to
+ * actually write images.
+ *
+ * The \c ostream template parameter specifies the type of output
+ * stream to work with. The \c ostream class should implement the
+ * minimum of the following interface:
+ *
+ * \code
+ * class my_ostream
+ * {
+ * public:
+ * void write(char const*, size_t);
+ * void flush();
+ * bool good();
+ * };
+ * \endcode
+ *
+ * With the semantics similar to the \c std::ostream. Naturally,
+ * \c std::ostream fits this requirement and can be used with the
+ * writer class as is.
+ *
+ * \see image, reader, generator, io_base
+ */
+ template< class ostream >
+ class writer
+ : public io_base
+ {
+ public:
+ /**
+ * \brief Constructs a writer prepared to write PNG image into
+ * a \a stream.
+ */
+ explicit writer(ostream& stream)
+ : io_base(png_create_write_struct(PNG_LIBPNG_VER_STRING,
+ static_cast< io_base* >(this),
+ raise_error,
+ 0))
+ {
+ png_set_write_fn(m_png, & stream, write_data, flush_data);
+ }
+
+ ~writer()
+ {
+ m_end_info.destroy();
+ png_destroy_write_struct(& m_png, m_info.get_png_info_ptr());
+ }
+
+ void write_png() const
+ {
+ if (setjmp(png_jmpbuf(m_png)))
+ {
+ throw error(m_error);
+ }
+ png_write_png(m_png,
+ m_info.get_png_info(),
+ /* transforms = */ 0,
+ /* params = */ 0);
+ }
+
+ /**
+ * \brief Write info about PNG image.
+ */
+ void write_info() const
+ {
+ if (setjmp(png_jmpbuf(m_png)))
+ {
+ throw error(m_error);
+ }
+ m_info.write();
+ }
+
+ /**
+ * \brief Writes a row of image data at a time.
+ */
+ void write_row(byte* bytes)
+ {
+ if (setjmp(png_jmpbuf(m_png)))
+ {
+ throw error(m_error);
+ }
+ png_write_row(m_png, bytes);
+ }
+
+ /**
+ * \brief Reads ending info about PNG image.
+ */
+ void write_end_info() const
+ {
+ if (setjmp(png_jmpbuf(m_png)))
+ {
+ throw error(m_error);
+ }
+ m_end_info.write();
+ }
+
+ private:
+ static void write_data(png_struct* png, byte* data, png_size_t length)
+ {
+ io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
+ writer* wr = static_cast< writer* >(io);
+ wr->reset_error();
+ ostream* stream = reinterpret_cast< ostream* >(png_get_io_ptr(png));
+ try
+ {
+ stream->write(reinterpret_cast< char* >(data), length);
+ if (!stream->good())
+ {
+ wr->set_error("ostream::write() failed");
+ }
+ }
+ catch (std::exception const& error)
+ {
+ wr->set_error(error.what());
+ }
+ catch (...)
+ {
+ assert(!"caught something wrong");
+ wr->set_error("write_data: caught something wrong");
+ }
+ if (wr->is_error())
+ {
+ wr->raise_error();
+ }
+ }
+
+ static void flush_data(png_struct* png)
+ {
+ io_base* io = static_cast< io_base* >(png_get_error_ptr(png));
+ writer* wr = static_cast< writer* >(io);
+ wr->reset_error();
+ ostream* stream = reinterpret_cast< ostream* >(png_get_io_ptr(png));
+ try
+ {
+ stream->flush();
+ if (!stream->good())
+ {
+ wr->set_error("ostream::flush() failed");
+ }
+ }
+ catch (std::exception const& error)
+ {
+ wr->set_error(error.what());
+ }
+ catch (...)
+ {
+ assert(!"caught something wrong");
+ wr->set_error("flush_data: caught something wrong");
+ }
+ if (wr->is_error())
+ {
+ wr->raise_error();
+ }
+ }
+ };
+
+} // namespace png
+
+#endif // PNGPP_WRITER_HPP_INCLUDED
diff --git a/xs/src/png/zlib/CMakeLists.txt b/xs/src/png/zlib/CMakeLists.txt
new file mode 100644
index 000000000..1ea38fef1
--- /dev/null
+++ b/xs/src/png/zlib/CMakeLists.txt
@@ -0,0 +1,253 @@
+cmake_minimum_required(VERSION 2.4.4)
+set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
+
+project(zlib C)
+
+set(VERSION "1.2.11")
+
+option(ASM686 "Enable building i686 assembly implementation")
+option(AMD64 "Enable building amd64 assembly implementation")
+
+set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables")
+set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries")
+set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers")
+set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages")
+set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
+
+include(CheckTypeSize)
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(CheckCSourceCompiles)
+#enable_testing()
+
+check_include_file(sys/types.h HAVE_SYS_TYPES_H)
+check_include_file(stdint.h HAVE_STDINT_H)
+check_include_file(stddef.h HAVE_STDDEF_H)
+
+#
+# Check to see if we have large file support
+#
+set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1)
+# We add these other definitions here because CheckTypeSize.cmake
+# in CMake 2.4.x does not automatically do so and we want
+# compatibility with CMake 2.4.x.
+if(HAVE_SYS_TYPES_H)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H)
+endif()
+if(HAVE_STDINT_H)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H)
+endif()
+if(HAVE_STDDEF_H)
+ list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H)
+endif()
+check_type_size(off64_t OFF64_T)
+if(HAVE_OFF64_T)
+ add_definitions(-D_LARGEFILE64_SOURCE=1)
+endif()
+set(CMAKE_REQUIRED_DEFINITIONS) # clear variable
+
+#
+# Check for fseeko
+#
+check_function_exists(fseeko HAVE_FSEEKO)
+if(NOT HAVE_FSEEKO)
+ add_definitions(-DNO_FSEEKO)
+endif()
+
+#
+# Check for unistd.h
+#
+check_include_file(unistd.h Z_HAVE_UNISTD_H)
+
+if(MSVC)
+ set(CMAKE_DEBUG_POSTFIX "d")
+ add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
+ add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+endif()
+
+if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
+ # If we're doing an out of source build and the user has a zconf.h
+ # in their source tree...
+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h)
+ message(STATUS "Renaming")
+ message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h")
+ message(STATUS "to 'zconf.h.included' because this file is included with zlib")
+ message(STATUS "but CMake generates it automatically in the build directory.")
+ file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included)
+ endif()
+endif()
+
+set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc)
+configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein
+ ${ZLIB_PC} @ONLY)
+configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein
+ ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY)
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
+
+
+#============================================================================
+# zlib
+#============================================================================
+
+set(ZLIB_PUBLIC_HDRS
+ ${CMAKE_CURRENT_BINARY_DIR}/zconf.h
+ zlib.h
+)
+set(ZLIB_PRIVATE_HDRS
+ crc32.h
+ deflate.h
+ gzguts.h
+ inffast.h
+ inffixed.h
+ inflate.h
+ inftrees.h
+ trees.h
+ zutil.h
+)
+set(ZLIB_SRCS
+ adler32.c
+ compress.c
+ crc32.c
+ deflate.c
+ gzclose.c
+ gzlib.c
+ gzread.c
+ gzwrite.c
+ inflate.c
+ infback.c
+ inftrees.c
+ inffast.c
+ trees.c
+ uncompr.c
+ zutil.c
+)
+
+if(NOT MINGW)
+ set(ZLIB_DLL_SRCS
+ win32/zlib1.rc # If present will override custom build rule below.
+ )
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCC)
+ if(ASM686)
+ set(ZLIB_ASMS contrib/asm686/match.S)
+ elseif (AMD64)
+ set(ZLIB_ASMS contrib/amd64/amd64-match.S)
+ endif ()
+
+ if(ZLIB_ASMS)
+ add_definitions(-DASMV)
+ set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE)
+ endif()
+endif()
+
+if(MSVC)
+ if(ASM686)
+ ENABLE_LANGUAGE(ASM_MASM)
+ set(ZLIB_ASMS
+ contrib/masmx86/inffas32.asm
+ contrib/masmx86/match686.asm
+ )
+ elseif (AMD64)
+ ENABLE_LANGUAGE(ASM_MASM)
+ set(ZLIB_ASMS
+ contrib/masmx64/gvmat64.asm
+ contrib/masmx64/inffasx64.asm
+ )
+ endif()
+
+ if(ZLIB_ASMS)
+ add_definitions(-DASMV -DASMINF)
+ endif()
+endif()
+
+# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
+file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)
+string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
+ "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
+
+if(MINGW)
+ # This gets us DLL resource information when compiling on MinGW.
+ if(NOT CMAKE_RC_COMPILER)
+ set(CMAKE_RC_COMPILER windres.exe)
+ endif()
+
+ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
+ COMMAND ${CMAKE_RC_COMPILER}
+ -D GCC_WINDRES
+ -I ${CMAKE_CURRENT_SOURCE_DIR}
+ -I ${CMAKE_CURRENT_BINARY_DIR}
+ -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
+ -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc)
+ set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
+endif(MINGW)
+
+#add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+#set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
+#set_target_properties(zlib PROPERTIES SOVERSION 1)
+
+if(NOT CYGWIN)
+ # This property causes shared libraries on Linux to have the full version
+ # encoded into their final filename. We disable this on Cygwin because
+ # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll
+ # seems to be the default.
+ #
+ # This has no effect with MSVC, on that platform the version info for
+ # the DLL comes from the resource file win32/zlib1.rc
+# set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION})
+endif()
+
+if(UNIX)
+ # On unix-like platforms the library is almost always called libz
+ set_target_properties(
+ # zlib
+ zlibstatic PROPERTIES OUTPUT_NAME z)
+ if(NOT APPLE)
+ # set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"")
+ endif()
+elseif(BUILD_SHARED_LIBS AND WIN32)
+ # Creates zlib1.dll when building shared library version
+ # set_target_properties(zlib PROPERTIES SUFFIX "1.dll")
+endif()
+
+if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
+ install(TARGETS
+# zlib
+ zlibstatic
+ RUNTIME DESTINATION "${INSTALL_BIN_DIR}"
+ ARCHIVE DESTINATION "${INSTALL_LIB_DIR}"
+ LIBRARY DESTINATION "${INSTALL_LIB_DIR}" )
+endif()
+if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
+ install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}")
+endif()
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+ install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3")
+endif()
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+ install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}")
+endif()
+
+#============================================================================
+# Example binaries
+#============================================================================
+
+#add_executable(example test/example.c)
+#target_link_libraries(example zlib)
+#add_test(example example)
+
+#add_executable(minigzip test/minigzip.c)
+#target_link_libraries(minigzip zlib)
+
+#if(HAVE_OFF64_T)
+# add_executable(example64 test/example.c)
+# target_link_libraries(example64 zlib)
+# set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
+# add_test(example64 example64)
+
+# add_executable(minigzip64 test/minigzip.c)
+# target_link_libraries(minigzip64 zlib)
+# set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
+#endif()
diff --git a/xs/src/png/zlib/ChangeLog b/xs/src/png/zlib/ChangeLog
new file mode 100644
index 000000000..30199a65a
--- /dev/null
+++ b/xs/src/png/zlib/ChangeLog
@@ -0,0 +1,1515 @@
+
+ ChangeLog file for zlib
+
+Changes in 1.2.11 (15 Jan 2017)
+- Fix deflate stored bug when pulling last block from window
+- Permit immediate deflateParams changes before any deflate input
+
+Changes in 1.2.10 (2 Jan 2017)
+- Avoid warnings on snprintf() return value
+- Fix bug in deflate_stored() for zero-length input
+- Fix bug in gzwrite.c that produced corrupt gzip files
+- Remove files to be installed before copying them in Makefile.in
+- Add warnings when compiling with assembler code
+
+Changes in 1.2.9 (31 Dec 2016)
+- Fix contrib/minizip to permit unzipping with desktop API [Zouzou]
+- Improve contrib/blast to return unused bytes
+- Assure that gzoffset() is correct when appending
+- Improve compress() and uncompress() to support large lengths
+- Fix bug in test/example.c where error code not saved
+- Remedy Coverity warning [Randers-Pehrson]
+- Improve speed of gzprintf() in transparent mode
+- Fix inflateInit2() bug when windowBits is 16 or 32
+- Change DEBUG macro to ZLIB_DEBUG
+- Avoid uninitialized access by gzclose_w()
+- Allow building zlib outside of the source directory
+- Fix bug that accepted invalid zlib header when windowBits is zero
+- Fix gzseek() problem on MinGW due to buggy _lseeki64 there
+- Loop on write() calls in gzwrite.c in case of non-blocking I/O
+- Add --warn (-w) option to ./configure for more compiler warnings
+- Reject a window size of 256 bytes if not using the zlib wrapper
+- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE
+- Add --debug (-d) option to ./configure to define ZLIB_DEBUG
+- Fix bugs in creating a very large gzip header
+- Add uncompress2() function, which returns the input size used
+- Assure that deflateParams() will not switch functions mid-block
+- Dramatically speed up deflation for level 0 (storing)
+- Add gzfread(), duplicating the interface of fread()
+- Add gzfwrite(), duplicating the interface of fwrite()
+- Add deflateGetDictionary() function
+- Use snprintf() for later versions of Microsoft C
+- Fix *Init macros to use z_ prefix when requested
+- Replace as400 with os400 for OS/400 support [Monnerat]
+- Add crc32_z() and adler32_z() functions with size_t lengths
+- Update Visual Studio project files [AraHaan]
+
+Changes in 1.2.8 (28 Apr 2013)
+- Update contrib/minizip/iowin32.c for Windows RT [Vollant]
+- Do not force Z_CONST for C++
+- Clean up contrib/vstudio [Roß]
+- Correct spelling error in zlib.h
+- Fix mixed line endings in contrib/vstudio
+
+Changes in 1.2.7.3 (13 Apr 2013)
+- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc
+
+Changes in 1.2.7.2 (13 Apr 2013)
+- Change check for a four-byte type back to hexadecimal
+- Fix typo in win32/Makefile.msc
+- Add casts in gzwrite.c for pointer differences
+
+Changes in 1.2.7.1 (24 Mar 2013)
+- Replace use of unsafe string functions with snprintf if available
+- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink]
+- Fix gzgetc undefine when Z_PREFIX set [Turk]
+- Eliminate use of mktemp in Makefile (not always available)
+- Fix bug in 'F' mode for gzopen()
+- Add inflateGetDictionary() function
+- Correct comment in deflate.h
+- Use _snprintf for snprintf in Microsoft C
+- On Darwin, only use /usr/bin/libtool if libtool is not Apple
+- Delete "--version" file if created by "ar --version" [Richard G.]
+- Fix configure check for veracity of compiler error return codes
+- Fix CMake compilation of static lib for MSVC2010 x64
+- Remove unused variable in infback9.c
+- Fix argument checks in gzlog_compress() and gzlog_write()
+- Clean up the usage of z_const and respect const usage within zlib
+- Clean up examples/gzlog.[ch] comparisons of different types
+- Avoid shift equal to bits in type (caused endless loop)
+- Fix uninitialized value bug in gzputc() introduced by const patches
+- Fix memory allocation error in examples/zran.c [Nor]
+- Fix bug where gzopen(), gzclose() would write an empty file
+- Fix bug in gzclose() when gzwrite() runs out of memory
+- Check for input buffer malloc failure in examples/gzappend.c
+- Add note to contrib/blast to use binary mode in stdio
+- Fix comparisons of differently signed integers in contrib/blast
+- Check for invalid code length codes in contrib/puff
+- Fix serious but very rare decompression bug in inftrees.c
+- Update inflateBack() comments, since inflate() can be faster
+- Use underscored I/O function names for WINAPI_FAMILY
+- Add _tr_flush_bits to the external symbols prefixed by --zprefix
+- Add contrib/vstudio/vc10 pre-build step for static only
+- Quote --version-script argument in CMakeLists.txt
+- Don't specify --version-script on Apple platforms in CMakeLists.txt
+- Fix casting error in contrib/testzlib/testzlib.c
+- Fix types in contrib/minizip to match result of get_crc_table()
+- Simplify contrib/vstudio/vc10 with 'd' suffix
+- Add TOP support to win32/Makefile.msc
+- Suport i686 and amd64 assembler builds in CMakeLists.txt
+- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
+- Add vc11 and vc12 build files to contrib/vstudio
+- Add gzvprintf() as an undocumented function in zlib
+- Fix configure for Sun shell
+- Remove runtime check in configure for four-byte integer type
+- Add casts and consts to ease user conversion to C++
+- Add man pages for minizip and miniunzip
+- In Makefile uninstall, don't rm if preceding cd fails
+- Do not return Z_BUF_ERROR if deflateParam() has nothing to write
+
+Changes in 1.2.7 (2 May 2012)
+- Replace use of memmove() with a simple copy for portability
+- Test for existence of strerror
+- Restore gzgetc_ for backward compatibility with 1.2.6
+- Fix build with non-GNU make on Solaris
+- Require gcc 4.0 or later on Mac OS X to use the hidden attribute
+- Include unistd.h for Watcom C
+- Use __WATCOMC__ instead of __WATCOM__
+- Do not use the visibility attribute if NO_VIZ defined
+- Improve the detection of no hidden visibility attribute
+- Avoid using __int64 for gcc or solo compilation
+- Cast to char * in gzprintf to avoid warnings [Zinser]
+- Fix make_vms.com for VAX [Zinser]
+- Don't use library or built-in byte swaps
+- Simplify test and use of gcc hidden attribute
+- Fix bug in gzclose_w() when gzwrite() fails to allocate memory
+- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen()
+- Fix bug in test/minigzip.c for configure --solo
+- Fix contrib/vstudio project link errors [Mohanathas]
+- Add ability to choose the builder in make_vms.com [Schweda]
+- Add DESTDIR support to mingw32 win32/Makefile.gcc
+- Fix comments in win32/Makefile.gcc for proper usage
+- Allow overriding the default install locations for cmake
+- Generate and install the pkg-config file with cmake
+- Build both a static and a shared version of zlib with cmake
+- Include version symbols for cmake builds
+- If using cmake with MSVC, add the source directory to the includes
+- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta]
+- Move obsolete emx makefile to old [Truta]
+- Allow the use of -Wundef when compiling or using zlib
+- Avoid the use of the -u option with mktemp
+- Improve inflate() documentation on the use of Z_FINISH
+- Recognize clang as gcc
+- Add gzopen_w() in Windows for wide character path names
+- Rename zconf.h in CMakeLists.txt to move it out of the way
+- Add source directory in CMakeLists.txt for building examples
+- Look in build directory for zlib.pc in CMakeLists.txt
+- Remove gzflags from zlibvc.def in vc9 and vc10
+- Fix contrib/minizip compilation in the MinGW environment
+- Update ./configure for Solaris, support --64 [Mooney]
+- Remove -R. from Solaris shared build (possible security issue)
+- Avoid race condition for parallel make (-j) running example
+- Fix type mismatch between get_crc_table() and crc_table
+- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler]
+- Fix the path to zlib.map in CMakeLists.txt
+- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe]
+- Add instructions to win32/Makefile.gcc for shared install [Torri]
+
+Changes in 1.2.6.1 (12 Feb 2012)
+- Avoid the use of the Objective-C reserved name "id"
+- Include io.h in gzguts.h for Microsoft compilers
+- Fix problem with ./configure --prefix and gzgetc macro
+- Include gz_header definition when compiling zlib solo
+- Put gzflags() functionality back in zutil.c
+- Avoid library header include in crc32.c for Z_SOLO
+- Use name in GCC_CLASSIC as C compiler for coverage testing, if set
+- Minor cleanup in contrib/minizip/zip.c [Vollant]
+- Update make_vms.com [Zinser]
+- Remove unnecessary gzgetc_ function
+- Use optimized byte swap operations for Microsoft and GNU [Snyder]
+- Fix minor typo in zlib.h comments [Rzesniowiecki]
+
+Changes in 1.2.6 (29 Jan 2012)
+- Update the Pascal interface in contrib/pascal
+- Fix function numbers for gzgetc_ in zlibvc.def files
+- Fix configure.ac for contrib/minizip [Schiffer]
+- Fix large-entry detection in minizip on 64-bit systems [Schiffer]
+- Have ./configure use the compiler return code for error indication
+- Fix CMakeLists.txt for cross compilation [McClure]
+- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes]
+- Fix compilation of contrib/minizip on FreeBSD [Marquez]
+- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath]
+- Include io.h for Turbo C / Borland C on all platforms [Truta]
+- Make version explicit in contrib/minizip/configure.ac [Bosmans]
+- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant]
+- Minor cleanup up contrib/minizip/unzip.c [Vollant]
+- Fix bug when compiling minizip with C++ [Vollant]
+- Protect for long name and extra fields in contrib/minizip [Vollant]
+- Avoid some warnings in contrib/minizip [Vollant]
+- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip
+- Add missing libs to minizip linker command
+- Add support for VPATH builds in contrib/minizip
+- Add an --enable-demos option to contrib/minizip/configure
+- Add the generation of configure.log by ./configure
+- Exit when required parameters not provided to win32/Makefile.gcc
+- Have gzputc return the character written instead of the argument
+- Use the -m option on ldconfig for BSD systems [Tobias]
+- Correct in zlib.map when deflateResetKeep was added
+
+Changes in 1.2.5.3 (15 Jan 2012)
+- Restore gzgetc function for binary compatibility
+- Do not use _lseeki64 under Borland C++ [Truta]
+- Update win32/Makefile.msc to build test/*.c [Truta]
+- Remove old/visualc6 given CMakefile and other alternatives
+- Update AS400 build files and documentation [Monnerat]
+- Update win32/Makefile.gcc to build test/*.c [Truta]
+- Permit stronger flushes after Z_BLOCK flushes
+- Avoid extraneous empty blocks when doing empty flushes
+- Permit Z_NULL arguments to deflatePending
+- Allow deflatePrime() to insert bits in the middle of a stream
+- Remove second empty static block for Z_PARTIAL_FLUSH
+- Write out all of the available bits when using Z_BLOCK
+- Insert the first two strings in the hash table after a flush
+
+Changes in 1.2.5.2 (17 Dec 2011)
+- fix ld error: unable to find version dependency 'ZLIB_1.2.5'
+- use relative symlinks for shared libs
+- Avoid searching past window for Z_RLE strategy
+- Assure that high-water mark initialization is always applied in deflate
+- Add assertions to fill_window() in deflate.c to match comments
+- Update python link in README
+- Correct spelling error in gzread.c
+- Fix bug in gzgets() for a concatenated empty gzip stream
+- Correct error in comment for gz_make()
+- Change gzread() and related to ignore junk after gzip streams
+- Allow gzread() and related to continue after gzclearerr()
+- Allow gzrewind() and gzseek() after a premature end-of-file
+- Simplify gzseek() now that raw after gzip is ignored
+- Change gzgetc() to a macro for speed (~40% speedup in testing)
+- Fix gzclose() to return the actual error last encountered
+- Always add large file support for windows
+- Include zconf.h for windows large file support
+- Include zconf.h.cmakein for windows large file support
+- Update zconf.h.cmakein on make distclean
+- Merge vestigial vsnprintf determination from zutil.h to gzguts.h
+- Clarify how gzopen() appends in zlib.h comments
+- Correct documentation of gzdirect() since junk at end now ignored
+- Add a transparent write mode to gzopen() when 'T' is in the mode
+- Update python link in zlib man page
+- Get inffixed.h and MAKEFIXED result to match
+- Add a ./config --solo option to make zlib subset with no library use
+- Add undocumented inflateResetKeep() function for CAB file decoding
+- Add --cover option to ./configure for gcc coverage testing
+- Add #define ZLIB_CONST option to use const in the z_stream interface
+- Add comment to gzdopen() in zlib.h to use dup() when using fileno()
+- Note behavior of uncompress() to provide as much data as it can
+- Add files in contrib/minizip to aid in building libminizip
+- Split off AR options in Makefile.in and configure
+- Change ON macro to Z_ARG to avoid application conflicts
+- Facilitate compilation with Borland C++ for pragmas and vsnprintf
+- Include io.h for Turbo C / Borland C++
+- Move example.c and minigzip.c to test/
+- Simplify incomplete code table filling in inflate_table()
+- Remove code from inflate.c and infback.c that is impossible to execute
+- Test the inflate code with full coverage
+- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw)
+- Add deflateResetKeep and fix inflateResetKeep to retain dictionary
+- Fix gzwrite.c to accommodate reduced memory zlib compilation
+- Have inflate() with Z_FINISH avoid the allocation of a window
+- Do not set strm->adler when doing raw inflate
+- Fix gzeof() to behave just like feof() when read is not past end of file
+- Fix bug in gzread.c when end-of-file is reached
+- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF
+- Document gzread() capability to read concurrently written files
+- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo]
+
+Changes in 1.2.5.1 (10 Sep 2011)
+- Update FAQ entry on shared builds (#13)
+- Avoid symbolic argument to chmod in Makefile.in
+- Fix bug and add consts in contrib/puff [Oberhumer]
+- Update contrib/puff/zeros.raw test file to have all block types
+- Add full coverage test for puff in contrib/puff/Makefile
+- Fix static-only-build install in Makefile.in
+- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno]
+- Add libz.a dependency to shared in Makefile.in for parallel builds
+- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out
+- Replace $(...) with `...` in configure for non-bash sh [Bowler]
+- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen]
+- Add solaris* to Linux* in configure to allow gcc use [Groffen]
+- Add *bsd* to Linux* case in configure [Bar-Lev]
+- Add inffast.obj to dependencies in win32/Makefile.msc
+- Correct spelling error in deflate.h [Kohler]
+- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc
+- Add test to configure for GNU C looking for gcc in output of $cc -v
+- Add zlib.pc generation to win32/Makefile.gcc [Weigelt]
+- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not
+- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense
+- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser)
+- Make stronger test in zconf.h to include unistd.h for LFS
+- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack]
+- Fix zlib.h LFS support when Z_PREFIX used
+- Add updated as400 support (removed from old) [Monnerat]
+- Avoid deflate sensitivity to volatile input data
+- Avoid division in adler32_combine for NO_DIVIDE
+- Clarify the use of Z_FINISH with deflateBound() amount of space
+- Set binary for output file in puff.c
+- Use u4 type for crc_table to avoid conversion warnings
+- Apply casts in zlib.h to avoid conversion warnings
+- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]
+- Improve inflateSync() documentation to note indeterminancy
+- Add deflatePending() function to return the amount of pending output
+- Correct the spelling of "specification" in FAQ [Randers-Pehrson]
+- Add a check in configure for stdarg.h, use for gzprintf()
+- Check that pointers fit in ints when gzprint() compiled old style
+- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]
+- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]
+- Add debug records in assmebler code [Londer]
+- Update RFC references to use http://tools.ietf.org/html/... [Li]
+- Add --archs option, use of libtool to configure for Mac OS X [Borstel]
+
+Changes in 1.2.5 (19 Apr 2010)
+- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]
+- Default to libdir as sharedlibdir in configure [Nieder]
+- Update copyright dates on modified source files
+- Update trees.c to be able to generate modified trees.h
+- Exit configure for MinGW, suggesting win32/Makefile.gcc
+- Check for NULL path in gz_open [Homurlu]
+
+Changes in 1.2.4.5 (18 Apr 2010)
+- Set sharedlibdir in configure [Torok]
+- Set LDFLAGS in Makefile.in [Bar-Lev]
+- Avoid mkdir objs race condition in Makefile.in [Bowler]
+- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays
+- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C
+- Don't use hidden attribute when it is a warning generator (e.g. Solaris)
+
+Changes in 1.2.4.4 (18 Apr 2010)
+- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok]
+- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty
+- Try to use bash or ksh regardless of functionality of /bin/sh
+- Fix configure incompatibility with NetBSD sh
+- Remove attempt to run under bash or ksh since have better NetBSD fix
+- Fix win32/Makefile.gcc for MinGW [Bar-Lev]
+- Add diagnostic messages when using CROSS_PREFIX in configure
+- Added --sharedlibdir option to configure [Weigelt]
+- Use hidden visibility attribute when available [Frysinger]
+
+Changes in 1.2.4.3 (10 Apr 2010)
+- Only use CROSS_PREFIX in configure for ar and ranlib if they exist
+- Use CROSS_PREFIX for nm [Bar-Lev]
+- Assume _LARGEFILE64_SOURCE defined is equivalent to true
+- Avoid use of undefined symbols in #if with && and ||
+- Make *64 prototypes in gzguts.h consistent with functions
+- Add -shared load option for MinGW in configure [Bowler]
+- Move z_off64_t to public interface, use instead of off64_t
+- Remove ! from shell test in configure (not portable to Solaris)
+- Change +0 macro tests to -0 for possibly increased portability
+
+Changes in 1.2.4.2 (9 Apr 2010)
+- Add consistent carriage returns to readme.txt's in masmx86 and masmx64
+- Really provide prototypes for *64 functions when building without LFS
+- Only define unlink() in minigzip.c if unistd.h not included
+- Update README to point to contrib/vstudio project files
+- Move projects/vc6 to old/ and remove projects/
+- Include stdlib.h in minigzip.c for setmode() definition under WinCE
+- Clean up assembler builds in win32/Makefile.msc [Rowe]
+- Include sys/types.h for Microsoft for off_t definition
+- Fix memory leak on error in gz_open()
+- Symbolize nm as $NM in configure [Weigelt]
+- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt]
+- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined
+- Fix bug in gzeof() to take into account unused input data
+- Avoid initialization of structures with variables in puff.c
+- Updated win32/README-WIN32.txt [Rowe]
+
+Changes in 1.2.4.1 (28 Mar 2010)
+- Remove the use of [a-z] constructs for sed in configure [gentoo 310225]
+- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech]
+- Restore "for debugging" comment on sprintf() in gzlib.c
+- Remove fdopen for MVS from gzguts.h
+- Put new README-WIN32.txt in win32 [Rowe]
+- Add check for shell to configure and invoke another shell if needed
+- Fix big fat stinking bug in gzseek() on uncompressed files
+- Remove vestigial F_OPEN64 define in zutil.h
+- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE
+- Avoid errors on non-LFS systems when applications define LFS macros
+- Set EXE to ".exe" in configure for MINGW [Kahle]
+- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill]
+- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev]
+- Add DLL install in win32/makefile.gcc [Bar-Lev]
+- Allow Linux* or linux* from uname in configure [Bar-Lev]
+- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev]
+- Add cross-compilation prefixes to configure [Bar-Lev]
+- Match type exactly in gz_load() invocation in gzread.c
+- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func
+- Provide prototypes for *64 functions when building zlib without LFS
+- Don't use -lc when linking shared library on MinGW
+- Remove errno.h check in configure and vestigial errno code in zutil.h
+
+Changes in 1.2.4 (14 Mar 2010)
+- Fix VER3 extraction in configure for no fourth subversion
+- Update zlib.3, add docs to Makefile.in to make .pdf out of it
+- Add zlib.3.pdf to distribution
+- Don't set error code in gzerror() if passed pointer is NULL
+- Apply destination directory fixes to CMakeLists.txt [Lowman]
+- Move #cmakedefine's to a new zconf.in.cmakein
+- Restore zconf.h for builds that don't use configure or cmake
+- Add distclean to dummy Makefile for convenience
+- Update and improve INDEX, README, and FAQ
+- Update CMakeLists.txt for the return of zconf.h [Lowman]
+- Update contrib/vstudio/vc9 and vc10 [Vollant]
+- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc
+- Apply license and readme changes to contrib/asm686 [Raiter]
+- Check file name lengths and add -c option in minigzip.c [Li]
+- Update contrib/amd64 and contrib/masmx86/ [Vollant]
+- Avoid use of "eof" parameter in trees.c to not shadow library variable
+- Update make_vms.com for removal of zlibdefs.h [Zinser]
+- Update assembler code and vstudio projects in contrib [Vollant]
+- Remove outdated assembler code contrib/masm686 and contrib/asm586
+- Remove old vc7 and vc8 from contrib/vstudio
+- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe]
+- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open()
+- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant]
+- Remove *64 functions from win32/zlib.def (they're not 64-bit yet)
+- Fix bug in void-returning vsprintf() case in gzwrite.c
+- Fix name change from inflate.h in contrib/inflate86/inffas86.c
+- Check if temporary file exists before removing in make_vms.com [Zinser]
+- Fix make install and uninstall for --static option
+- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta]
+- Update readme.txt in contrib/masmx64 and masmx86 to assemble
+
+Changes in 1.2.3.9 (21 Feb 2010)
+- Expunge gzio.c
+- Move as400 build information to old
+- Fix updates in contrib/minizip and contrib/vstudio
+- Add const to vsnprintf test in configure to avoid warnings [Weigelt]
+- Delete zconf.h (made by configure) [Weigelt]
+- Change zconf.in.h to zconf.h.in per convention [Weigelt]
+- Check for NULL buf in gzgets()
+- Return empty string for gzgets() with len == 1 (like fgets())
+- Fix description of gzgets() in zlib.h for end-of-file, NULL return
+- Update minizip to 1.1 [Vollant]
+- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c
+- Note in zlib.h that gzerror() should be used to distinguish from EOF
+- Remove use of snprintf() from gzlib.c
+- Fix bug in gzseek()
+- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant]
+- Fix zconf.h generation in CMakeLists.txt [Lowman]
+- Improve comments in zconf.h where modified by configure
+
+Changes in 1.2.3.8 (13 Feb 2010)
+- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer]
+- Use z_off64_t in gz_zero() and gz_skip() to match state->skip
+- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t)
+- Revert to Makefile.in from 1.2.3.6 (live with the clutter)
+- Fix missing error return in gzflush(), add zlib.h note
+- Add *64 functions to zlib.map [Levin]
+- Fix signed/unsigned comparison in gz_comp()
+- Use SFLAGS when testing shared linking in configure
+- Add --64 option to ./configure to use -m64 with gcc
+- Fix ./configure --help to correctly name options
+- Have make fail if a test fails [Levin]
+- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson]
+- Remove assembler object files from contrib
+
+Changes in 1.2.3.7 (24 Jan 2010)
+- Always gzopen() with O_LARGEFILE if available
+- Fix gzdirect() to work immediately after gzopen() or gzdopen()
+- Make gzdirect() more precise when the state changes while reading
+- Improve zlib.h documentation in many places
+- Catch memory allocation failure in gz_open()
+- Complete close operation if seek forward in gzclose_w() fails
+- Return Z_ERRNO from gzclose_r() if close() fails
+- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL
+- Return zero for gzwrite() errors to match zlib.h description
+- Return -1 on gzputs() error to match zlib.h description
+- Add zconf.in.h to allow recovery from configure modification [Weigelt]
+- Fix static library permissions in Makefile.in [Weigelt]
+- Avoid warnings in configure tests that hide functionality [Weigelt]
+- Add *BSD and DragonFly to Linux case in configure [gentoo 123571]
+- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212]
+- Avoid access of uninitialized data for first inflateReset2 call [Gomes]
+- Keep object files in subdirectories to reduce the clutter somewhat
+- Remove default Makefile and zlibdefs.h, add dummy Makefile
+- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_
+- Remove zlibdefs.h completely -- modify zconf.h instead
+
+Changes in 1.2.3.6 (17 Jan 2010)
+- Avoid void * arithmetic in gzread.c and gzwrite.c
+- Make compilers happier with const char * for gz_error message
+- Avoid unused parameter warning in inflate.c
+- Avoid signed-unsigned comparison warning in inflate.c
+- Indent #pragma's for traditional C
+- Fix usage of strwinerror() in glib.c, change to gz_strwinerror()
+- Correct email address in configure for system options
+- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser]
+- Update zlib.map [Brown]
+- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok]
+- Apply various fixes to CMakeLists.txt [Lowman]
+- Add checks on len in gzread() and gzwrite()
+- Add error message for no more room for gzungetc()
+- Remove zlib version check in gzwrite()
+- Defer compression of gzprintf() result until need to
+- Use snprintf() in gzdopen() if available
+- Remove USE_MMAP configuration determination (only used by minigzip)
+- Remove examples/pigz.c (available separately)
+- Update examples/gun.c to 1.6
+
+Changes in 1.2.3.5 (8 Jan 2010)
+- Add space after #if in zutil.h for some compilers
+- Fix relatively harmless bug in deflate_fast() [Exarevsky]
+- Fix same problem in deflate_slow()
+- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown]
+- Add deflate_rle() for faster Z_RLE strategy run-length encoding
+- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding
+- Change name of "write" variable in inffast.c to avoid library collisions
+- Fix premature EOF from gzread() in gzio.c [Brown]
+- Use zlib header window size if windowBits is 0 in inflateInit2()
+- Remove compressBound() call in deflate.c to avoid linking compress.o
+- Replace use of errno in gz* with functions, support WinCE [Alves]
+- Provide alternative to perror() in minigzip.c for WinCE [Alves]
+- Don't use _vsnprintf on later versions of MSVC [Lowman]
+- Add CMake build script and input file [Lowman]
+- Update contrib/minizip to 1.1 [Svensson, Vollant]
+- Moved nintendods directory from contrib to .
+- Replace gzio.c with a new set of routines with the same functionality
+- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
+- Update contrib/minizip to 1.1b
+- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h
+
+Changes in 1.2.3.4 (21 Dec 2009)
+- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility
+- Update comments in configure and Makefile.in for default --shared
+- Fix test -z's in configure [Marquess]
+- Build examplesh and minigzipsh when not testing
+- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h
+- Import LDFLAGS from the environment in configure
+- Fix configure to populate SFLAGS with discovered CFLAGS options
+- Adapt make_vms.com to the new Makefile.in [Zinser]
+- Add zlib2ansi script for C++ compilation [Marquess]
+- Add _FILE_OFFSET_BITS=64 test to make test (when applicable)
+- Add AMD64 assembler code for longest match to contrib [Teterin]
+- Include options from $SFLAGS when doing $LDSHARED
+- Simplify 64-bit file support by introducing z_off64_t type
+- Make shared object files in objs directory to work around old Sun cc
+- Use only three-part version number for Darwin shared compiles
+- Add rc option to ar in Makefile.in for when ./configure not run
+- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4*
+- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile
+- Protect against _FILE_OFFSET_BITS being defined when compiling zlib
+- Rename Makefile.in targets allstatic to static and allshared to shared
+- Fix static and shared Makefile.in targets to be independent
+- Correct error return bug in gz_open() by setting state [Brown]
+- Put spaces before ;;'s in configure for better sh compatibility
+- Add pigz.c (parallel implementation of gzip) to examples/
+- Correct constant in crc32.c to UL [Leventhal]
+- Reject negative lengths in crc32_combine()
+- Add inflateReset2() function to work like inflateEnd()/inflateInit2()
+- Include sys/types.h for _LARGEFILE64_SOURCE [Brown]
+- Correct typo in doc/algorithm.txt [Janik]
+- Fix bug in adler32_combine() [Zhu]
+- Catch missing-end-of-block-code error in all inflates and in puff
+ Assures that random input to inflate eventually results in an error
+- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/
+- Update ENOUGH and its usage to reflect discovered bounds
+- Fix gzerror() error report on empty input file [Brown]
+- Add ush casts in trees.c to avoid pedantic runtime errors
+- Fix typo in zlib.h uncompress() description [Reiss]
+- Correct inflate() comments with regard to automatic header detection
+- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)
+- Put new version of gzlog (2.0) in examples with interruption recovery
+- Add puff compile option to permit invalid distance-too-far streams
+- Add puff TEST command options, ability to read piped input
+- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but
+ _LARGEFILE64_SOURCE not defined
+- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart
+- Fix deflateSetDictionary() to use all 32K for output consistency
+- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h)
+- Clear bytes after deflate lookahead to avoid use of uninitialized data
+- Change a limit in inftrees.c to be more transparent to Coverity Prevent
+- Update win32/zlib.def with exported symbols from zlib.h
+- Correct spelling errors in zlib.h [Willem, Sobrado]
+- Allow Z_BLOCK for deflate() to force a new block
+- Allow negative bits in inflatePrime() to delete existing bit buffer
+- Add Z_TREES flush option to inflate() to return at end of trees
+- Add inflateMark() to return current state information for random access
+- Add Makefile for NintendoDS to contrib [Costa]
+- Add -w in configure compile tests to avoid spurious warnings [Beucler]
+- Fix typos in zlib.h comments for deflateSetDictionary()
+- Fix EOF detection in transparent gzread() [Maier]
+
+Changes in 1.2.3.3 (2 October 2006)
+- Make --shared the default for configure, add a --static option
+- Add compile option to permit invalid distance-too-far streams
+- Add inflateUndermine() function which is required to enable above
+- Remove use of "this" variable name for C++ compatibility [Marquess]
+- Add testing of shared library in make test, if shared library built
+- Use ftello() and fseeko() if available instead of ftell() and fseek()
+- Provide two versions of all functions that use the z_off_t type for
+ binary compatibility -- a normal version and a 64-bit offset version,
+ per the Large File Support Extension when _LARGEFILE64_SOURCE is
+ defined; use the 64-bit versions by default when _FILE_OFFSET_BITS
+ is defined to be 64
+- Add a --uname= option to configure to perhaps help with cross-compiling
+
+Changes in 1.2.3.2 (3 September 2006)
+- Turn off silly Borland warnings [Hay]
+- Use off64_t and define _LARGEFILE64_SOURCE when present
+- Fix missing dependency on inffixed.h in Makefile.in
+- Rig configure --shared to build both shared and static [Teredesai, Truta]
+- Remove zconf.in.h and instead create a new zlibdefs.h file
+- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant]
+- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt]
+
+Changes in 1.2.3.1 (16 August 2006)
+- Add watcom directory with OpenWatcom make files [Daniel]
+- Remove #undef of FAR in zconf.in.h for MVS [Fedtke]
+- Update make_vms.com [Zinser]
+- Use -fPIC for shared build in configure [Teredesai, Nicholson]
+- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen]
+- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck]
+- Add some FAQ entries about the contrib directory
+- Update the MVS question in the FAQ
+- Avoid extraneous reads after EOF in gzio.c [Brown]
+- Correct spelling of "successfully" in gzio.c [Randers-Pehrson]
+- Add comments to zlib.h about gzerror() usage [Brown]
+- Set extra flags in gzip header in gzopen() like deflate() does
+- Make configure options more compatible with double-dash conventions
+ [Weigelt]
+- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen]
+- Fix uninstall target in Makefile.in [Truta]
+- Add pkgconfig support [Weigelt]
+- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt]
+- Replace set_data_type() with a more accurate detect_data_type() in
+ trees.c, according to the txtvsbin.txt document [Truta]
+- Swap the order of #include <stdio.h> and #include "zlib.h" in
+ gzio.c, example.c and minigzip.c [Truta]
+- Shut up annoying VS2005 warnings about standard C deprecation [Rowe,
+ Truta] (where?)
+- Fix target "clean" from win32/Makefile.bor [Truta]
+- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe]
+- Update zlib www home address in win32/DLL_FAQ.txt [Truta]
+- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove]
+- Enable browse info in the "Debug" and "ASM Debug" configurations in
+ the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta]
+- Add pkgconfig support [Weigelt]
+- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h,
+ for use in win32/zlib1.rc [Polushin, Rowe, Truta]
+- Add a document that explains the new text detection scheme to
+ doc/txtvsbin.txt [Truta]
+- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta]
+- Move algorithm.txt into doc/ [Truta]
+- Synchronize FAQ with website
+- Fix compressBound(), was low for some pathological cases [Fearnley]
+- Take into account wrapper variations in deflateBound()
+- Set examples/zpipe.c input and output to binary mode for Windows
+- Update examples/zlib_how.html with new zpipe.c (also web site)
+- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems
+ that gcc became pickier in 4.0)
+- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain
+ un-versioned, the patch adds versioning only for symbols introduced in
+ zlib-1.2.0 or later. It also declares as local those symbols which are
+ not designed to be exported." [Levin]
+- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure
+- Do not initialize global static by default in trees.c, add a response
+ NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess]
+- Don't use strerror() in gzio.c under WinCE [Yakimov]
+- Don't use errno.h in zutil.h under WinCE [Yakimov]
+- Move arguments for AR to its usage to allow replacing ar [Marot]
+- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson]
+- Improve inflateInit() and inflateInit2() documentation
+- Fix structure size comment in inflate.h
+- Change configure help option from --h* to --help [Santos]
+
+Changes in 1.2.3 (18 July 2005)
+- Apply security vulnerability fixes to contrib/infback9 as well
+- Clean up some text files (carriage returns, trailing space)
+- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
+
+Changes in 1.2.2.4 (11 July 2005)
+- Add inflatePrime() function for starting inflation at bit boundary
+- Avoid some Visual C warnings in deflate.c
+- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
+ compile
+- Fix some spelling errors in comments [Betts]
+- Correct inflateInit2() error return documentation in zlib.h
+- Add zran.c example of compressed data random access to examples
+ directory, shows use of inflatePrime()
+- Fix cast for assignments to strm->state in inflate.c and infback.c
+- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
+- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
+- Add cast in trees.c t avoid a warning [Oberhumer]
+- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
+- Update make_vms.com [Zinser]
+- Initialize state->write in inflateReset() since copied in inflate_fast()
+- Be more strict on incomplete code sets in inflate_table() and increase
+ ENOUGH and MAXD -- this repairs a possible security vulnerability for
+ invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for
+ discovering the vulnerability and providing test cases.
+- Add ia64 support to configure for HP-UX [Smith]
+- Add error return to gzread() for format or i/o error [Levin]
+- Use malloc.h for OS/2 [Necasek]
+
+Changes in 1.2.2.3 (27 May 2005)
+- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
+- Typecast fread() return values in gzio.c [Vollant]
+- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
+- Fix crc check bug in gzread() after gzungetc() [Heiner]
+- Add the deflateTune() function to adjust internal compression parameters
+- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
+- Remove an incorrect assertion in examples/zpipe.c
+- Add C++ wrapper in infback9.h [Donais]
+- Fix bug in inflateCopy() when decoding fixed codes
+- Note in zlib.h how much deflateSetDictionary() actually uses
+- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
+- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
+- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
+- Add gzdirect() function to indicate transparent reads
+- Update contrib/minizip [Vollant]
+- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
+- Add casts in crc32.c to avoid warnings [Oberhumer]
+- Add contrib/masmx64 [Vollant]
+- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
+
+Changes in 1.2.2.2 (30 December 2004)
+- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
+ avoid implicit memcpy calls (portability for no-library compilation)
+- Increase sprintf() buffer size in gzdopen() to allow for large numbers
+- Add INFLATE_STRICT to check distances against zlib header
+- Improve WinCE errno handling and comments [Chang]
+- Remove comment about no gzip header processing in FAQ
+- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
+- Add updated make_vms.com [Coghlan], update README
+- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
+ fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
+- Add FAQ entry and comments in deflate.c on uninitialized memory access
+- Add Solaris 9 make options in configure [Gilbert]
+- Allow strerror() usage in gzio.c for STDC
+- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
+- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
+- Use z_off_t for adler32_combine() and crc32_combine() lengths
+- Make adler32() much faster for small len
+- Use OS_CODE in deflate() default gzip header
+
+Changes in 1.2.2.1 (31 October 2004)
+- Allow inflateSetDictionary() call for raw inflate
+- Fix inflate header crc check bug for file names and comments
+- Add deflateSetHeader() and gz_header structure for custom gzip headers
+- Add inflateGetheader() to retrieve gzip headers
+- Add crc32_combine() and adler32_combine() functions
+- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
+- Use zstreamp consistently in zlib.h (inflate_back functions)
+- Remove GUNZIP condition from definition of inflate_mode in inflate.h
+ and in contrib/inflate86/inffast.S [Truta, Anderson]
+- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
+- Update projects/README.projects and projects/visualc6 [Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
+- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
+- Use a new algorithm for setting strm->data_type in trees.c [Truta]
+- Do not define an exit() prototype in zutil.c unless DEBUG defined
+- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
+- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
+- Fix Darwin build version identification [Peterson]
+
+Changes in 1.2.2 (3 October 2004)
+- Update zlib.h comments on gzip in-memory processing
+- Set adler to 1 in inflateReset() to support Java test suite [Walles]
+- Add contrib/dotzlib [Ravn]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update contrib/minizip [Vollant]
+- Move contrib/visual-basic.txt to old/ [Truta]
+- Fix assembler builds in projects/visualc6/ [Truta]
+
+Changes in 1.2.1.2 (9 September 2004)
+- Update INDEX file
+- Fix trees.c to update strm->data_type (no one ever noticed!)
+- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
+- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
+- Add limited multitasking protection to DYNAMIC_CRC_TABLE
+- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
+- Don't declare strerror() under VMS [Mozilla]
+- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
+- Update contrib/ada [Anisimkov]
+- Update contrib/minizip [Vollant]
+- Fix configure to not hardcode directories for Darwin [Peterson]
+- Fix gzio.c to not return error on empty files [Brown]
+- Fix indentation; update version in contrib/delphi/ZLib.pas and
+ contrib/pascal/zlibpas.pas [Truta]
+- Update mkasm.bat in contrib/masmx86 [Truta]
+- Update contrib/untgz [Truta]
+- Add projects/README.projects [Truta]
+- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
+- Remove an unnecessary assignment to curr in inftrees.c [Truta]
+- Add OS/2 to exe builds in configure [Poltorak]
+- Remove err dummy parameter in zlib.h [Kientzle]
+
+Changes in 1.2.1.1 (9 January 2004)
+- Update email address in README
+- Several FAQ updates
+- Fix a big fat bug in inftrees.c that prevented decoding valid
+ dynamic blocks with only literals and no distance codes --
+ Thanks to "Hot Emu" for the bug report and sample file
+- Add a note to puff.c on no distance codes case.
+
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+ - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Update win32/DLL_FAQ.txt [Truta]
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and replace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+ - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+ the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+ [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+ and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+ [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+ [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+ INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+ [Truta]
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+ of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+ parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+ to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+ 16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+ Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+ zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+
+Changes in 1.2.0.4 (10 August 2003)
+- Minor FAQ updates
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+- Minor FAQ updates
+
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+ library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+ special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+ - Report 0 for huffman and rle strategies and for level == 0 or 1
+ - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+ - When Z_RLE requested, restrict matches to distance one
+ - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+ - Refine detection of Turbo C need for dummy returns
+ - Refine ZLIB_DLL compilation
+ - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enchance comments in zlib.h on what happens if gzprintf() tries to
+ write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+ - About 20% faster
+ - Does not allocate 32K window unless and until needed
+ - Automatically detects and decompresses gzip streams
+ - Raw inflate no longer needs an extra dummy byte at end
+ - Added inflateBack functions using a callback interface--even faster
+ than inflate, useful for file utilities (gzip, zip)
+ - Added inflateCopy() function to record state for random access on
+ externally generated deflate streams (e.g. in gzip files)
+ - More readable code (I hope)
+- New and improved crc32()
+ - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+ and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+ return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+ is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+ - Document raw deflate and inflate
+ - Update RFCs URL
+ - Point out that zlib and gzip formats are different
+ - Note that Z_BUF_ERROR is not fatal
+ - Document string limit for gzprintf() and possible buffer overflow
+ - Note requirement on avail_out when flushing
+ - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions.
+ This creates a security problem described in
+ http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+ less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+ of 256 bytes. (A complete fix will be available in 1.1.5).
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+ occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+ (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean" (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+ . zutil.c, zutil.h: added "const" for zmem*
+ . Make_vms.com: fixed some typos
+ . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+ . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+ . msdos/Makefile.*: use model-dependent name for the built zlib library
+ . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+ new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+ See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+ completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+ (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+ compression ratio on some files. This also allows inlining _tr_tally for
+ matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+ on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+ the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+ them at run time (thanks to Ken Raeburn for this suggestion). To create
+ trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+ gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occurring only with compression level 0 (thanks to
+ Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+ (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+ (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+ inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+ contrib/asm386/ by Gilles Vollant <info@winimage.com>
+ 386 asm code replacing longest_match().
+ contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+ A C++ I/O streams interface to the zlib gz* functions
+ contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
+ Another C++ I/O streams interface
+ contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+ A very simple tar.gz file extractor using zlib
+ contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+ How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+ level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+ (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+ bit, so the decompressor could decompress all the correct data but went
+ on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+ small and medium models; this makes the library incompatible with previous
+ versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+ avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generate bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+ Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+ and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+ -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+ warning C4746: 'inflate_mask' : unsized array treated as '__far'
+ (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+ not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+ (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+ typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+ was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+ pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+ is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+ (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+ TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+ (one's complement) is now done inside crc32(). WARNING: this is
+ incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+ not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+ Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+ if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+ user-provided history buffer. This is supported only in deflateInit2
+ and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
diff --git a/xs/src/png/zlib/FAQ b/xs/src/png/zlib/FAQ
new file mode 100644
index 000000000..99b7cf92e
--- /dev/null
+++ b/xs/src/png/zlib/FAQ
@@ -0,0 +1,368 @@
+
+ Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://zlib.net/ which may have more recent information.
+The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+ Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+ The zlib sources can be compiled without change to produce a DLL. See the
+ file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the
+ precompiled DLL are found in the zlib web site at http://zlib.net/ .
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+ See
+ * http://marknelson.us/1997/01/01/zlib-engine/
+ * win32/DLL_FAQ.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR.
+
+ Make sure that before the call of compress(), the length of the compressed
+ buffer is equal to the available size of the compressed buffer and not
+ zero. For Visual Basic, check that this parameter is passed by reference
+ ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+
+ Before making the call, make sure that avail_in and avail_out are not zero.
+ When setting the parameter flush equal to Z_FINISH, also make sure that
+ avail_out is big enough to allow processing all pending input. Note that a
+ Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
+ made with more input or output space. A Z_BUF_ERROR may in fact be
+ unavoidable depending on how the functions are used, since it is not
+ possible to tell whether or not there is more output pending when
+ strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a
+ heavily annotated example.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+ It's in zlib.h . Examples of zlib usage are in the files test/example.c
+ and test/minigzip.c, with more in examples/ .
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+ Because we would like to keep zlib as a very small and simple package.
+ zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+ Most of the time, such problems are due to an incorrect usage of zlib.
+ Please try to reproduce the problem with a small program and send the
+ corresponding source to us at zlib@gzip.org . Do not send multi-megabyte
+ data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+ If "make test" produces something like
+
+ example.o(.text+0x154): undefined reference to `gzputc'
+
+ check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+ /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+ See the contrib/delphi directory in the zlib distribution.
+
+11. Can zlib handle .zip archives?
+
+ Not by itself, no. See the directory contrib/minizip in the zlib
+ distribution.
+
+12. Can zlib handle .Z files?
+
+ No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
+ the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+ By default a shared (and a static) library is built for Unix. So:
+
+ make distclean
+ ./configure
+ make
+
+14. How do I install a shared zlib library on Unix?
+
+ After the above, then:
+
+ make install
+
+ However, many flavors of Unix come with a shared zlib already installed.
+ Before going to the trouble of compiling a shared version of zlib and
+ trying to install it, you may want to check if it's already there! If you
+ can #include <zlib.h>, it's there. The -lz option will probably link to
+ it. You can check the version at the top of zlib.h or with the
+ ZLIB_VERSION symbol defined in zlib.h .
+
+15. I have a question about OttoPDF.
+
+ We are not the authors of OttoPDF. The real author is on the OttoPDF web
+ site: Joel Hainley, jhainley@myndkryme.com.
+
+16. Can zlib decode Flate data in an Adobe PDF file?
+
+ Yes. See http://www.pdflib.com/ . To modify PDF forms, see
+ http://sourceforge.net/projects/acroformtool/ .
+
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+
+ After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+ generates an error such as:
+
+ ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+ symbol __register_frame_info: referenced symbol not found
+
+ The symbol __register_frame_info is not part of zlib, it is generated by
+ the C compiler (cc or gcc). You must recompile applications using zlib
+ which have this problem. This problem is specific to Solaris. See
+ http://www.sunfreeware.com for Solaris versions of zlib and applications
+ using zlib.
+
+18. Why does gzip give an error on a file I make with compress/deflate?
+
+ The compress and deflate functions produce data in the zlib format, which
+ is different and incompatible with the gzip format. The gz* functions in
+ zlib on the other hand use the gzip format. Both the zlib and gzip formats
+ use the same compressed data format internally, but have different headers
+ and trailers around the compressed data.
+
+19. Ok, so why are there two different formats?
+
+ The gzip format was designed to retain the directory information about a
+ single file, such as the name and last modification date. The zlib format
+ on the other hand was designed for in-memory and communication channel
+ applications, and has a much more compact header and trailer and uses a
+ faster integrity check than gzip.
+
+20. Well that's nice, but how do I make a gzip file in memory?
+
+ You can request that deflate write the gzip format instead of the zlib
+ format using deflateInit2(). You can also request that inflate decode the
+ gzip format using inflateInit2(). Read zlib.h for more details.
+
+21. Is zlib thread-safe?
+
+ Yes. However any library routines that zlib uses and any application-
+ provided memory allocation routines must also be thread-safe. zlib's gz*
+ functions use stdio library routines, and most of zlib's functions use the
+ library memory allocation routines by default. zlib's *Init* functions
+ allow for the application to provide custom memory allocation routines.
+
+ Of course, you should only operate on any given zlib or gzip stream from a
+ single thread at a time.
+
+22. Can I use zlib in my commercial application?
+
+ Yes. Please read the license in zlib.h.
+
+23. Is zlib under the GNU license?
+
+ No. Please read the license in zlib.h.
+
+24. The license says that altered source versions must be "plainly marked". So
+ what exactly do I need to do to meet that requirement?
+
+ You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
+ particular, the final version number needs to be changed to "f", and an
+ identification string should be appended to ZLIB_VERSION. Version numbers
+ x.x.x.f are reserved for modifications to zlib by others than the zlib
+ maintainers. For example, if the version of the base zlib you are altering
+ is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+ ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
+ update the version strings in deflate.c and inftrees.c.
+
+ For altered source distributions, you should also note the origin and
+ nature of the changes in zlib.h, as well as in ChangeLog and README, along
+ with the dates of the alterations. The origin should include at least your
+ name (or your company's name), and an email address to contact for help or
+ issues with the library.
+
+ Note that distributing a compiled zlib library along with zlib.h and
+ zconf.h is also a source distribution, and so you should change
+ ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+ in zlib.h as you would for a full source distribution.
+
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+ exchange compressed data between them?
+
+ Yes and yes.
+
+26. Will zlib work on a 64-bit machine?
+
+ Yes. It has been tested on 64-bit machines, and has no dependence on any
+ data types being limited to 32-bits in length. If you have any
+ difficulties, please provide a complete problem report to zlib@gzip.org
+
+27. Will zlib decompress data from the PKWare Data Compression Library?
+
+ No. The PKWare DCL uses a completely different compressed data format than
+ does PKZIP and zlib. However, you can look in zlib's contrib/blast
+ directory for a possible solution to your problem.
+
+28. Can I access data randomly in a compressed stream?
+
+ No, not without some preparation. If when compressing you periodically use
+ Z_FULL_FLUSH, carefully write all the pending data at those points, and
+ keep an index of those locations, then you can start decompression at those
+ points. You have to be careful to not use Z_FULL_FLUSH too often, since it
+ can significantly degrade compression. Alternatively, you can scan a
+ deflate stream once to generate an index, and then use that index for
+ random access. See examples/zran.c .
+
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+
+ It has in the past, but we have not heard of any recent evidence. There
+ were working ports of zlib 1.1.4 to MVS, but those links no longer work.
+ If you know of recent, successful applications of zlib on these operating
+ systems, please let us know. Thanks.
+
+30. Is there some simpler, easier to read version of inflate I can look at to
+ understand the deflate format?
+
+ First off, you should read RFC 1951. Second, yes. Look in zlib's
+ contrib/puff directory.
+
+31. Does zlib infringe on any patents?
+
+ As far as we know, no. In fact, that was originally the whole point behind
+ zlib. Look here for some more information:
+
+ http://www.gzip.org/#faq11
+
+32. Can zlib work with greater than 4 GB of data?
+
+ Yes. inflate() and deflate() will process any amount of data correctly.
+ Each call of inflate() or deflate() is limited to input and output chunks
+ of the maximum value that can be stored in the compiler's "unsigned int"
+ type, but there is no limit to the number of chunks. Note however that the
+ strm.total_in and strm_total_out counters may be limited to 4 GB. These
+ counters are provided as a convenience and are not used internally by
+ inflate() or deflate(). The application can easily set up its own counters
+ updated after each call of inflate() or deflate() to count beyond 4 GB.
+ compress() and uncompress() may be limited to 4 GB, since they operate in a
+ single call. gzseek() and gztell() may be limited to 4 GB depending on how
+ zlib is compiled. See the zlibCompileFlags() function in zlib.h.
+
+ The word "may" appears several times above since there is a 4 GB limit only
+ if the compiler's "long" type is 32 bits. If the compiler's "long" type is
+ 64 bits, then the limit is 16 exabytes.
+
+33. Does zlib have any security vulnerabilities?
+
+ The only one that we are aware of is potentially in gzprintf(). If zlib is
+ compiled to use sprintf() or vsprintf(), then there is no protection
+ against a buffer overflow of an 8K string space (or other value as set by
+ gzbuffer()), other than the caller of gzprintf() assuring that the output
+ will not exceed 8K. On the other hand, if zlib is compiled to use
+ snprintf() or vsnprintf(), which should normally be the case, then there is
+ no vulnerability. The ./configure script will display warnings if an
+ insecure variation of sprintf() will be used by gzprintf(). Also the
+ zlibCompileFlags() function will return information on what variant of
+ sprintf() is used by gzprintf().
+
+ If you don't have snprintf() or vsnprintf() and would like one, you can
+ find a portable implementation here:
+
+ http://www.ijs.si/software/snprintf/
+
+ Note that you should be using the most recent version of zlib. Versions
+ 1.1.3 and before were subject to a double-free vulnerability, and versions
+ 1.2.1 and 1.2.2 were subject to an access exception when decompressing
+ invalid compressed data.
+
+34. Is there a Java version of zlib?
+
+ Probably what you want is to use zlib in Java. zlib is already included
+ as part of the Java SDK in the java.util.zip package. If you really want
+ a version of zlib written in the Java language, look on the zlib home
+ page for links: http://zlib.net/ .
+
+35. I get this or that compiler or source-code scanner warning when I crank it
+ up to maximally-pedantic. Can't you guys write proper code?
+
+ Many years ago, we gave up attempting to avoid warnings on every compiler
+ in the universe. It just got to be a waste of time, and some compilers
+ were downright silly as well as contradicted each other. So now, we simply
+ make sure that the code always works.
+
+36. Valgrind (or some similar memory access checker) says that deflate is
+ performing a conditional jump that depends on an uninitialized value.
+ Isn't that a bug?
+
+ No. That is intentional for performance reasons, and the output of deflate
+ is not affected. This only started showing up recently since zlib 1.2.x
+ uses malloc() by default for allocations, whereas earlier versions used
+ calloc(), which zeros out the allocated memory. Even though the code was
+ correct, versions 1.2.4 and later was changed to not stimulate these
+ checkers.
+
+37. Will zlib read the (insert any ancient or arcane format here) compressed
+ data format?
+
+ Probably not. Look in the comp.compression FAQ for pointers to various
+ formats and associated software.
+
+38. How can I encrypt/decrypt zip files with zlib?
+
+ zlib doesn't support encryption. The original PKZIP encryption is very
+ weak and can be broken with freely available programs. To get strong
+ encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
+ compression. For PKZIP compatible "encryption", look at
+ http://www.info-zip.org/
+
+39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+
+ "gzip" is the gzip format, and "deflate" is the zlib format. They should
+ probably have called the second one "zlib" instead to avoid confusion with
+ the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
+ correctly points to the zlib specification in RFC 1950 for the "deflate"
+ transfer encoding, there have been reports of servers and browsers that
+ incorrectly produce or expect raw deflate data per the deflate
+ specification in RFC 1951, most notably Microsoft. So even though the
+ "deflate" transfer encoding using the zlib format would be the more
+ efficient approach (and in fact exactly what the zlib format was designed
+ for), using the "gzip" transfer encoding is probably more reliable due to
+ an unfortunate choice of name on the part of the HTTP 1.1 authors.
+
+ Bottom line: use the gzip format for HTTP 1.1 encoding.
+
+40. Does zlib support the new "Deflate64" format introduced by PKWare?
+
+ No. PKWare has apparently decided to keep that format proprietary, since
+ they have not documented it as they have previous compression formats. In
+ any case, the compression improvements are so modest compared to other more
+ modern approaches, that it's not worth the effort to implement.
+
+41. I'm having a problem with the zip functions in zlib, can you help?
+
+ There are no zip functions in zlib. You are probably using minizip by
+ Giles Vollant, which is found in the contrib directory of zlib. It is not
+ part of zlib. In fact none of the stuff in contrib is part of zlib. The
+ files in there are not supported by the zlib authors. You need to contact
+ the authors of the respective contribution for help.
+
+42. The match.asm code in contrib is under the GNU General Public License.
+ Since it's part of zlib, doesn't that mean that all of zlib falls under the
+ GNU GPL?
+
+ No. The files in contrib are not part of zlib. They were contributed by
+ other authors and are provided as a convenience to the user within the zlib
+ distribution. Each item in contrib has its own license.
+
+43. Is zlib subject to export controls? What is its ECCN?
+
+ zlib is not subject to export controls, and so is classified as EAR99.
+
+44. Can you please sign these lengthy legal documents and fax them back to us
+ so that we can use your software in our product?
+
+ No. Go away. Shoo.
diff --git a/xs/src/png/zlib/INDEX b/xs/src/png/zlib/INDEX
new file mode 100644
index 000000000..2ba064120
--- /dev/null
+++ b/xs/src/png/zlib/INDEX
@@ -0,0 +1,68 @@
+CMakeLists.txt cmake build file
+ChangeLog history of changes
+FAQ Frequently Asked Questions about zlib
+INDEX this file
+Makefile dummy Makefile that tells you to ./configure
+Makefile.in template for Unix Makefile
+README guess what
+configure configure script for Unix
+make_vms.com makefile for VMS
+test/example.c zlib usages examples for build testing
+test/minigzip.c minimal gzip-like functionality for build testing
+test/infcover.c inf*.c code coverage for build coverage testing
+treebuild.xml XML description of source file dependencies
+zconf.h.cmakein zconf.h template for cmake
+zconf.h.in zconf.h template for configure
+zlib.3 Man page for zlib
+zlib.3.pdf Man page in PDF format
+zlib.map Linux symbol information
+zlib.pc.in Template for pkg-config descriptor
+zlib.pc.cmakein zlib.pc template for cmake
+zlib2ansi perl script to convert source files for C++ compilation
+
+amiga/ makefiles for Amiga SAS C
+as400/ makefiles for AS/400
+doc/ documentation for formats and algorithms
+msdos/ makefiles for MSDOS
+nintendods/ makefile for Nintendo DS
+old/ makefiles for various architectures and zlib documentation
+ files that have not yet been updated for zlib 1.2.x
+qnx/ makefiles for QNX
+watcom/ makefiles for OpenWatcom
+win32/ makefiles for Windows
+
+ zlib public header files (required for library use):
+zconf.h
+zlib.h
+
+ private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+crc32.h
+deflate.c
+deflate.h
+gzclose.c
+gzguts.h
+gzlib.c
+gzread.c
+gzwrite.c
+infback.c
+inffast.c
+inffast.h
+inffixed.h
+inflate.c
+inflate.h
+inftrees.c
+inftrees.h
+trees.c
+trees.h
+uncompr.c
+zutil.c
+zutil.h
+
+ source files for sample programs
+See examples/README.examples
+
+ unsupported contributions by third parties
+See contrib/README.contrib
diff --git a/xs/src/png/zlib/Makefile b/xs/src/png/zlib/Makefile
new file mode 100644
index 000000000..6bba86c73
--- /dev/null
+++ b/xs/src/png/zlib/Makefile
@@ -0,0 +1,5 @@
+all:
+ -@echo "Please use ./configure first. Thank you."
+
+distclean:
+ make -f Makefile.in distclean
diff --git a/xs/src/png/zlib/Makefile.in b/xs/src/png/zlib/Makefile.in
new file mode 100644
index 000000000..5a77949ff
--- /dev/null
+++ b/xs/src/png/zlib/Makefile.in
@@ -0,0 +1,410 @@
+# Makefile for zlib
+# Copyright (C) 1995-2017 Jean-loup Gailly, Mark Adler
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+# ./configure; make test
+# Normally configure builds both a static and a shared library.
+# If you want to build just a static library, use: ./configure --static
+
+# To use the asm code, type:
+# cp contrib/asm?86/match.S ./match.S
+# make LOC=-DASMV OBJA=match.o
+
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+# make install
+# To install in $HOME instead of /usr/local, use:
+# make install prefix=$HOME
+
+CC=cc
+
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DZLIB_DEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+# -Wstrict-prototypes -Wmissing-prototypes
+
+SFLAGS=-O
+LDFLAGS=
+TEST_LDFLAGS=-L. libz.a
+LDSHARED=$(CC)
+CPP=$(CC) -E
+
+STATICLIB=libz.a
+SHAREDLIB=libz.so
+SHAREDLIBV=libz.so.1.2.11
+SHAREDLIBM=libz.so.1
+LIBS=$(STATICLIB) $(SHAREDLIBV)
+
+AR=ar
+ARFLAGS=rc
+RANLIB=ranlib
+LDCONFIG=ldconfig
+LDSHAREDLIBC=-lc
+TAR=tar
+SHELL=/bin/sh
+EXE=
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+libdir = ${exec_prefix}/lib
+sharedlibdir = ${libdir}
+includedir = ${prefix}/include
+mandir = ${prefix}/share/man
+man3dir = ${mandir}/man3
+pkgconfigdir = ${libdir}/pkgconfig
+SRCDIR=
+ZINC=
+ZINCOUT=-I.
+
+OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o
+OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o
+OBJC = $(OBJZ) $(OBJG)
+
+PIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo
+PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo
+PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG)
+
+# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo
+OBJA =
+PIC_OBJA =
+
+OBJS = $(OBJC) $(OBJA)
+
+PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA)
+
+all: static shared
+
+static: example$(EXE) minigzip$(EXE)
+
+shared: examplesh$(EXE) minigzipsh$(EXE)
+
+all64: example64$(EXE) minigzip64$(EXE)
+
+check: test
+
+test: all teststatic testshared
+
+teststatic: static
+ @TMPST=tmpst_$$; \
+ if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \
+ echo ' *** zlib test OK ***'; \
+ else \
+ echo ' *** zlib test FAILED ***'; false; \
+ fi; \
+ rm -f $$TMPST
+
+testshared: shared
+ @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+ LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
+ DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
+ SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \
+ TMPSH=tmpsh_$$; \
+ if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \
+ echo ' *** zlib shared test OK ***'; \
+ else \
+ echo ' *** zlib shared test FAILED ***'; false; \
+ fi; \
+ rm -f $$TMPSH
+
+test64: all64
+ @TMP64=tmp64_$$; \
+ if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \
+ echo ' *** zlib 64-bit test OK ***'; \
+ else \
+ echo ' *** zlib 64-bit test FAILED ***'; false; \
+ fi; \
+ rm -f $$TMP64
+
+infcover.o: $(SRCDIR)test/infcover.c $(SRCDIR)zlib.h zconf.h
+ $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/infcover.c
+
+infcover: infcover.o libz.a
+ $(CC) $(CFLAGS) -o $@ infcover.o libz.a
+
+cover: infcover
+ rm -f *.gcda
+ ./infcover
+ gcov inf*.c
+
+libz.a: $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+ -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+match.o: match.S
+ $(CPP) match.S > _match.s
+ $(CC) -c _match.s
+ mv _match.o match.o
+ rm -f _match.s
+
+match.lo: match.S
+ $(CPP) match.S > _match.s
+ $(CC) -c -fPIC _match.s
+ mv _match.o match.lo
+ rm -f _match.s
+
+example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h
+ $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c
+
+minigzip.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h
+ $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/minigzip.c
+
+example64.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h
+ $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/example.c
+
+minigzip64.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h
+ $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/minigzip.c
+
+
+adler32.o: $(SRCDIR)adler32.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)adler32.c
+
+crc32.o: $(SRCDIR)crc32.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c
+
+deflate.o: $(SRCDIR)deflate.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c
+
+infback.o: $(SRCDIR)infback.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)infback.c
+
+inffast.o: $(SRCDIR)inffast.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inffast.c
+
+inflate.o: $(SRCDIR)inflate.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inflate.c
+
+inftrees.o: $(SRCDIR)inftrees.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inftrees.c
+
+trees.o: $(SRCDIR)trees.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)trees.c
+
+zutil.o: $(SRCDIR)zutil.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)zutil.c
+
+compress.o: $(SRCDIR)compress.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)compress.c
+
+uncompr.o: $(SRCDIR)uncompr.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)uncompr.c
+
+gzclose.o: $(SRCDIR)gzclose.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzclose.c
+
+gzlib.o: $(SRCDIR)gzlib.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzlib.c
+
+gzread.o: $(SRCDIR)gzread.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzread.c
+
+gzwrite.o: $(SRCDIR)gzwrite.c
+ $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzwrite.c
+
+
+adler32.lo: $(SRCDIR)adler32.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/adler32.o $(SRCDIR)adler32.c
+ -@mv objs/adler32.o $@
+
+crc32.lo: $(SRCDIR)crc32.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c
+ -@mv objs/crc32.o $@
+
+deflate.lo: $(SRCDIR)deflate.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c
+ -@mv objs/deflate.o $@
+
+infback.lo: $(SRCDIR)infback.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/infback.o $(SRCDIR)infback.c
+ -@mv objs/infback.o $@
+
+inffast.lo: $(SRCDIR)inffast.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inffast.o $(SRCDIR)inffast.c
+ -@mv objs/inffast.o $@
+
+inflate.lo: $(SRCDIR)inflate.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inflate.o $(SRCDIR)inflate.c
+ -@mv objs/inflate.o $@
+
+inftrees.lo: $(SRCDIR)inftrees.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inftrees.o $(SRCDIR)inftrees.c
+ -@mv objs/inftrees.o $@
+
+trees.lo: $(SRCDIR)trees.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/trees.o $(SRCDIR)trees.c
+ -@mv objs/trees.o $@
+
+zutil.lo: $(SRCDIR)zutil.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/zutil.o $(SRCDIR)zutil.c
+ -@mv objs/zutil.o $@
+
+compress.lo: $(SRCDIR)compress.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/compress.o $(SRCDIR)compress.c
+ -@mv objs/compress.o $@
+
+uncompr.lo: $(SRCDIR)uncompr.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/uncompr.o $(SRCDIR)uncompr.c
+ -@mv objs/uncompr.o $@
+
+gzclose.lo: $(SRCDIR)gzclose.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzclose.o $(SRCDIR)gzclose.c
+ -@mv objs/gzclose.o $@
+
+gzlib.lo: $(SRCDIR)gzlib.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzlib.o $(SRCDIR)gzlib.c
+ -@mv objs/gzlib.o $@
+
+gzread.lo: $(SRCDIR)gzread.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzread.o $(SRCDIR)gzread.c
+ -@mv objs/gzread.o $@
+
+gzwrite.lo: $(SRCDIR)gzwrite.c
+ -@mkdir objs 2>/dev/null || test -d objs
+ $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzwrite.o $(SRCDIR)gzwrite.c
+ -@mv objs/gzwrite.o $@
+
+
+placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a
+ $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS)
+ rm -f $(SHAREDLIB) $(SHAREDLIBM)
+ ln -s $@ $(SHAREDLIB)
+ ln -s $@ $(SHAREDLIBM)
+ -@rmdir objs
+
+example$(EXE): example.o $(STATICLIB)
+ $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS)
+
+minigzip$(EXE): minigzip.o $(STATICLIB)
+ $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS)
+
+examplesh$(EXE): example.o $(SHAREDLIBV)
+ $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV)
+
+minigzipsh$(EXE): minigzip.o $(SHAREDLIBV)
+ $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV)
+
+example64$(EXE): example64.o $(STATICLIB)
+ $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS)
+
+minigzip64$(EXE): minigzip64.o $(STATICLIB)
+ $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS)
+
+install-libs: $(LIBS)
+ -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi
+ -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi
+ -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi
+ -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi
+ -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi
+ rm -f $(DESTDIR)$(libdir)/$(STATICLIB)
+ cp $(STATICLIB) $(DESTDIR)$(libdir)
+ chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB)
+ -@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1
+ -@if test -n "$(SHAREDLIBV)"; then \
+ rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \
+ cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \
+ echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \
+ chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \
+ echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \
+ rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
+ ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \
+ ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
+ ($(LDCONFIG) || true) >/dev/null 2>&1; \
+ fi
+ rm -f $(DESTDIR)$(man3dir)/zlib.3
+ cp $(SRCDIR)zlib.3 $(DESTDIR)$(man3dir)
+ chmod 644 $(DESTDIR)$(man3dir)/zlib.3
+ rm -f $(DESTDIR)$(pkgconfigdir)/zlib.pc
+ cp zlib.pc $(DESTDIR)$(pkgconfigdir)
+ chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc
+# The ranlib in install is needed on NeXTSTEP which checks file times
+# ldconfig is for Linux
+
+install: install-libs
+ -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi
+ rm -f $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
+ cp $(SRCDIR)zlib.h zconf.h $(DESTDIR)$(includedir)
+ chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
+
+uninstall:
+ cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h
+ cd $(DESTDIR)$(libdir) && rm -f libz.a; \
+ if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
+ rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
+ fi
+ cd $(DESTDIR)$(man3dir) && rm -f zlib.3
+ cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc
+
+docs: zlib.3.pdf
+
+zlib.3.pdf: $(SRCDIR)zlib.3
+ groff -mandoc -f H -T ps $(SRCDIR)zlib.3 | ps2pdf - $@
+
+zconf.h.cmakein: $(SRCDIR)zconf.h.in
+ -@ TEMPFILE=zconfh_$$; \
+ echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\
+ sed -f $$TEMPFILE $(SRCDIR)zconf.h.in > $@ &&\
+ touch -r $(SRCDIR)zconf.h.in $@ &&\
+ rm $$TEMPFILE
+
+zconf: $(SRCDIR)zconf.h.in
+ cp -p $(SRCDIR)zconf.h.in zconf.h
+
+mostlyclean: clean
+clean:
+ rm -f *.o *.lo *~ \
+ example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \
+ example64$(EXE) minigzip64$(EXE) \
+ infcover \
+ libz.* foo.gz so_locations \
+ _match.s maketree contrib/infback9/*.o
+ rm -rf objs
+ rm -f *.gcda *.gcno *.gcov
+ rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov
+
+maintainer-clean: distclean
+distclean: clean zconf zconf.h.cmakein docs
+ rm -f Makefile zlib.pc configure.log
+ -@rm -f .DS_Store
+ @if [ -f Makefile.in ]; then \
+ printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \
+ printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile ; \
+ touch -r $(SRCDIR)Makefile.in Makefile ; fi
+ @if [ ! -f zconf.h.in ]; then rm -f zconf.h zconf.h.cmakein ; fi
+ @if [ ! -f zlib.3 ]; then rm -f zlib.3.pdf ; fi
+
+tags:
+ etags $(SRCDIR)*.[ch]
+
+adler32.o zutil.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+gzclose.o gzlib.o gzread.o gzwrite.o: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h
+compress.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h
+crc32.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h
+deflate.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+infback.o inflate.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h
+inffast.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h
+inftrees.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h
+trees.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h
+
+adler32.lo zutil.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+gzclose.lo gzlib.lo gzread.lo gzwrite.lo: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h
+compress.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h
+crc32.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h
+deflate.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+infback.lo inflate.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h
+inffast.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h
+inftrees.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h
+trees.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h
diff --git a/xs/src/png/zlib/README b/xs/src/png/zlib/README
new file mode 100644
index 000000000..51106de47
--- /dev/null
+++ b/xs/src/png/zlib/README
@@ -0,0 +1,115 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.11 is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
+rfc1952 (gzip format).
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
+of the library is given in the file test/example.c which also tests that
+the library is working correctly. Another example is given in the file
+test/minigzip.c. The compression library itself is composed of all source
+files in the root directory.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile.in. In short "./configure; make test", and if that goes
+well, "make install" should work for most flavors of Unix. For Windows, use
+one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
+make_vms.com.
+
+Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
+<info@winimage.com> for the Windows DLL version. The zlib home page is
+http://zlib.net/ . Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+
+PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
+
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available at
+http://marknelson.us/1997/01/01/zlib-engine/ .
+
+The changes made in version 1.2.11 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory contrib/ .
+
+zlib is available in Java using the java.util.zip package, documented at
+http://java.sun.com/developer/technicalArticles/Programming/compression/ .
+
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
+at CPAN (Comprehensive Perl Archive Network) sites, including
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
+
+A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
+available in Python 1.5 and later versions, see
+http://docs.python.org/library/zlib.html .
+
+zlib is built into tcl: http://wiki.tcl.tk/4610 .
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info@winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+ -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+ compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+ when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+ necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+ other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS or BEOS.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+
+Acknowledgments:
+
+ The deflate format used by zlib was defined by Phil Katz. The deflate and
+ zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib; they
+ are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign. The sources are provided for free but without
+warranty of any kind. The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes. Please read
+the FAQ for more information on the distribution of modified source versions.
diff --git a/xs/src/png/zlib/adler32.c b/xs/src/png/zlib/adler32.c
new file mode 100644
index 000000000..d0be4380a
--- /dev/null
+++ b/xs/src/png/zlib/adler32.c
@@ -0,0 +1,186 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2011, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
+
+#define BASE 65521U /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware --
+ try it both ways to see which is faster */
+#ifdef NO_DIVIDE
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+ (thank you to John Reiser for pointing this out) */
+# define CHOP(a) \
+ do { \
+ unsigned long tmp = a >> 16; \
+ a &= 0xffffUL; \
+ a += (tmp << 4) - tmp; \
+ } while (0)
+# define MOD28(a) \
+ do { \
+ CHOP(a); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+# define MOD(a) \
+ do { \
+ CHOP(a); \
+ MOD28(a); \
+ } while (0)
+# define MOD63(a) \
+ do { /* this assumes a is not negative */ \
+ z_off64_t tmp = a >> 32; \
+ a &= 0xffffffffL; \
+ a += (tmp << 8) - (tmp << 5) + tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
+ tmp = a >> 16; \
+ a &= 0xffffL; \
+ a += (tmp << 4) - tmp; \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+#else
+# define MOD(a) a %= BASE
+# define MOD28(a) a %= BASE
+# define MOD63(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_z(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ z_size_t len;
+{
+ unsigned long sum2;
+ unsigned n;
+
+ /* split Adler-32 into component sums */
+ sum2 = (adler >> 16) & 0xffff;
+ adler &= 0xffff;
+
+ /* in case user likes doing a byte at a time, keep it fast */
+ if (len == 1) {
+ adler += buf[0];
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 += adler;
+ if (sum2 >= BASE)
+ sum2 -= BASE;
+ return adler | (sum2 << 16);
+ }
+
+ /* initial Adler-32 value (deferred check for len == 1 speed) */
+ if (buf == Z_NULL)
+ return 1L;
+
+ /* in case short lengths are provided, keep it somewhat fast */
+ if (len < 16) {
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ if (adler >= BASE)
+ adler -= BASE;
+ MOD28(sum2); /* only added so many BASE's */
+ return adler | (sum2 << 16);
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while (len >= NMAX) {
+ len -= NMAX;
+ n = NMAX / 16; /* NMAX is divisible by 16 */
+ do {
+ DO16(buf); /* 16 sums unrolled */
+ buf += 16;
+ } while (--n);
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if (len) { /* avoid modulos if none remaining */
+ while (len >= 16) {
+ len -= 16;
+ DO16(buf);
+ buf += 16;
+ }
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* return recombined sums */
+ return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ uInt len;
+{
+ return adler32_z(adler, buf, len);
+}
+
+/* ========================================================================= */
+local uLong adler32_combine_(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off64_t len2;
+{
+ unsigned long sum1;
+ unsigned long sum2;
+ unsigned rem;
+
+ /* for negative len, return invalid adler32 as a clue for debugging */
+ if (len2 < 0)
+ return 0xffffffffUL;
+
+ /* the derivation of this formula is left as an exercise for the reader */
+ MOD63(len2); /* assumes len2 >= 0 */
+ rem = (unsigned)len2;
+ sum1 = adler1 & 0xffff;
+ sum2 = rem * sum1;
+ MOD(sum2);
+ sum1 += (adler2 & 0xffff) + BASE - 1;
+ sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum1 >= BASE) sum1 -= BASE;
+ if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);
+ if (sum2 >= BASE) sum2 -= BASE;
+ return sum1 | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+ uLong adler1;
+ uLong adler2;
+ z_off64_t len2;
+{
+ return adler32_combine_(adler1, adler2, len2);
+}
diff --git a/xs/src/png/zlib/amiga/Makefile.pup b/xs/src/png/zlib/amiga/Makefile.pup
new file mode 100644
index 000000000..8940c120f
--- /dev/null
+++ b/xs/src/png/zlib/amiga/Makefile.pup
@@ -0,0 +1,69 @@
+# Amiga powerUP (TM) Makefile
+# makefile for libpng and SAS C V6.58/7.00 PPC compiler
+# Copyright (C) 1998 by Andreas R. Kleinert
+
+LIBNAME = libzip.a
+
+CC = scppc
+CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \
+ OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER
+AR = ppc-amigaos-ar cr
+RANLIB = ppc-amigaos-ranlib
+LD = ppc-amigaos-ld -r
+LDFLAGS = -o
+LDLIBS = LIB:scppc.a LIB:end.o
+RM = delete quiet
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+ uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example minigzip
+
+check: test
+test: all
+ example
+ echo hello world | minigzip | minigzip -d
+
+$(LIBNAME): $(OBJS)
+ $(AR) $@ $(OBJS)
+ -$(RANLIB) $@
+
+example: example.o $(LIBNAME)
+ $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
+
+minigzip: minigzip.o $(LIBNAME)
+ $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
+
+mostlyclean: clean
+clean:
+ $(RM) *.o example minigzip $(LIBNAME) foo.gz
+
+zip:
+ zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \
+ descrip.mms *.[ch]
+
+tgz:
+ cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
+ zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/xs/src/png/zlib/amiga/Makefile.sas b/xs/src/png/zlib/amiga/Makefile.sas
new file mode 100644
index 000000000..749e29152
--- /dev/null
+++ b/xs/src/png/zlib/amiga/Makefile.sas
@@ -0,0 +1,68 @@
+# SMakefile for zlib
+# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly
+# Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>
+# Amiga, SAS/C 6.56 & Smake
+
+CC=sc
+CFLAGS=OPT
+#CFLAGS=OPT CPU=68030
+#CFLAGS=DEBUG=LINE
+LDFLAGS=LIB z.lib
+
+SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \
+ NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \
+ DEF=POSTINC
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+ uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: SCOPTIONS example minigzip
+
+check: test
+test: all
+ example
+ echo hello world | minigzip | minigzip -d
+
+install: z.lib
+ copy clone zlib.h zconf.h INCLUDE:
+ copy clone z.lib LIB:
+
+z.lib: $(OBJS)
+ oml z.lib r $(OBJS)
+
+example: example.o z.lib
+ $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)
+
+minigzip: minigzip.o z.lib
+ $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)
+
+mostlyclean: clean
+clean:
+ -delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS
+
+SCOPTIONS: Makefile.sas
+ copy to $@ <from <
+$(SCOPTIONS)
+<
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/xs/src/png/zlib/compress.c b/xs/src/png/zlib/compress.c
new file mode 100644
index 000000000..e2db404ab
--- /dev/null
+++ b/xs/src/png/zlib/compress.c
@@ -0,0 +1,86 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+ int level;
+{
+ z_stream stream;
+ int err;
+ const uInt max = (uInt)-1;
+ uLong left;
+
+ left = *destLen;
+ *destLen = 0;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit(&stream, level);
+ if (err != Z_OK) return err;
+
+ stream.next_out = dest;
+ stream.avail_out = 0;
+ stream.next_in = (z_const Bytef *)source;
+ stream.avail_in = 0;
+
+ do {
+ if (stream.avail_out == 0) {
+ stream.avail_out = left > (uLong)max ? max : (uInt)left;
+ left -= stream.avail_out;
+ }
+ if (stream.avail_in == 0) {
+ stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen;
+ sourceLen -= stream.avail_in;
+ }
+ err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH);
+ } while (err == Z_OK);
+
+ *destLen = stream.total_out;
+ deflateEnd(&stream);
+ return err == Z_STREAM_END ? Z_OK : err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+ If the default memLevel or windowBits for deflateInit() is changed, then
+ this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+ uLong sourceLen;
+{
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+ (sourceLen >> 25) + 13;
+}
diff --git a/xs/src/png/zlib/configure b/xs/src/png/zlib/configure
new file mode 100644
index 000000000..e974d1fd7
--- /dev/null
+++ b/xs/src/png/zlib/configure
@@ -0,0 +1,921 @@
+#!/bin/sh
+# configure script for zlib.
+#
+# Normally configure builds both a static and a shared library.
+# If you want to build just a static library, use: ./configure --static
+#
+# To impose specific compiler or flags or install directory, use for example:
+# prefix=$HOME CC=cc CFLAGS="-O4" ./configure
+# or for csh/tcsh users:
+# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
+
+# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
+# If you have problems, try without defining CC and CFLAGS before reporting
+# an error.
+
+# start off configure.log
+echo -------------------- >> configure.log
+echo $0 $* >> configure.log
+date >> configure.log
+
+# get source directory
+SRCDIR=`dirname $0`
+if test $SRCDIR = "."; then
+ ZINC=""
+ ZINCOUT="-I."
+ SRCDIR=""
+else
+ ZINC='-include zconf.h'
+ ZINCOUT='-I. -I$(SRCDIR)'
+ SRCDIR="$SRCDIR/"
+fi
+
+# set command prefix for cross-compilation
+if [ -n "${CHOST}" ]; then
+ uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`"
+ CROSS_PREFIX="${CHOST}-"
+fi
+
+# destination name for static library
+STATICLIB=libz.a
+
+# extract zlib version numbers from zlib.h
+VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}zlib.h`
+VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < ${SRCDIR}zlib.h`
+VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h`
+VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h`
+
+# establish commands for library building
+if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+ AR=${AR-"${CROSS_PREFIX}ar"}
+ test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log
+else
+ AR=${AR-"ar"}
+ test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log
+fi
+ARFLAGS=${ARFLAGS-"rc"}
+if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+ RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"}
+ test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log
+else
+ RANLIB=${RANLIB-"ranlib"}
+fi
+if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+ NM=${NM-"${CROSS_PREFIX}nm"}
+ test -n "${CROSS_PREFIX}" && echo Using ${NM} | tee -a configure.log
+else
+ NM=${NM-"nm"}
+fi
+
+# set defaults before processing command line options
+LDCONFIG=${LDCONFIG-"ldconfig"}
+LDSHAREDLIBC="${LDSHAREDLIBC--lc}"
+ARCHS=
+prefix=${prefix-/usr/local}
+exec_prefix=${exec_prefix-'${prefix}'}
+libdir=${libdir-'${exec_prefix}/lib'}
+sharedlibdir=${sharedlibdir-'${libdir}'}
+includedir=${includedir-'${prefix}/include'}
+mandir=${mandir-'${prefix}/share/man'}
+shared_ext='.so'
+shared=1
+solo=0
+cover=0
+zprefix=0
+zconst=0
+build64=0
+gcc=0
+warn=0
+debug=0
+old_cc="$CC"
+old_cflags="$CFLAGS"
+OBJC='$(OBJZ) $(OBJG)'
+PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)'
+
+# leave this script, optionally in a bad way
+leave()
+{
+ if test "$*" != "0"; then
+ echo "** $0 aborting." | tee -a configure.log
+ fi
+ rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version
+ echo -------------------- >> configure.log
+ echo >> configure.log
+ echo >> configure.log
+ exit $1
+}
+
+# process command line options
+while test $# -ge 1
+do
+case "$1" in
+ -h* | --help)
+ echo 'usage:' | tee -a configure.log
+ echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log
+ echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log
+ echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log
+ exit 0 ;;
+ -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;;
+ -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;;
+ -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;;
+ --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;;
+ -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;;
+ -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;;
+ -p* | --prefix) prefix="$2"; shift; shift ;;
+ -e* | --eprefix) exec_prefix="$2"; shift; shift ;;
+ -l* | --libdir) libdir="$2"; shift; shift ;;
+ -i* | --includedir) includedir="$2"; shift; shift ;;
+ -s* | --shared | --enable-shared) shared=1; shift ;;
+ -t | --static) shared=0; shift ;;
+ --solo) solo=1; shift ;;
+ --cover) cover=1; shift ;;
+ -z* | --zprefix) zprefix=1; shift ;;
+ -6* | --64) build64=1; shift ;;
+ -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;;
+ --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;;
+ --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;;
+ -c* | --const) zconst=1; shift ;;
+ -w* | --warn) warn=1; shift ;;
+ -d* | --debug) debug=1; shift ;;
+ *)
+ echo "unknown option: $1" | tee -a configure.log
+ echo "$0 --help for help" | tee -a configure.log
+ leave 1;;
+ esac
+done
+
+# temporary file name
+test=ztest$$
+
+# put arguments in log, also put test file in log if used in arguments
+show()
+{
+ case "$*" in
+ *$test.c*)
+ echo === $test.c === >> configure.log
+ cat $test.c >> configure.log
+ echo === >> configure.log;;
+ esac
+ echo $* >> configure.log
+}
+
+# check for gcc vs. cc and set compile and link flags based on the system identified by uname
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
+
+test -z "$CC" && echo Checking for ${CROSS_PREFIX}gcc... | tee -a configure.log
+cc=${CC-${CROSS_PREFIX}gcc}
+cflags=${CFLAGS-"-O3"}
+# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
+case "$cc" in
+ *gcc*) gcc=1 ;;
+ *clang*) gcc=1 ;;
+esac
+case `$cc -v 2>&1` in
+ *gcc*) gcc=1 ;;
+ *clang*) gcc=1 ;;
+esac
+
+show $cc -c $test.c
+if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then
+ echo ... using gcc >> configure.log
+ CC="$cc"
+ CFLAGS="${CFLAGS--O3}"
+ SFLAGS="${CFLAGS--O3} -fPIC"
+ if test "$ARCHS"; then
+ CFLAGS="${CFLAGS} ${ARCHS}"
+ LDFLAGS="${LDFLAGS} ${ARCHS}"
+ fi
+ if test $build64 -eq 1; then
+ CFLAGS="${CFLAGS} -m64"
+ SFLAGS="${SFLAGS} -m64"
+ fi
+ if test "$warn" -eq 1; then
+ if test "$zconst" -eq 1; then
+ CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST"
+ else
+ CFLAGS="${CFLAGS} -Wall -Wextra -pedantic"
+ fi
+ fi
+ if test $debug -eq 1; then
+ CFLAGS="${CFLAGS} -DZLIB_DEBUG"
+ SFLAGS="${SFLAGS} -DZLIB_DEBUG"
+ fi
+ if test -z "$uname"; then
+ uname=`(uname -s || echo unknown) 2>/dev/null`
+ fi
+ case "$uname" in
+ Linux* | linux* | GNU | GNU/* | solaris*)
+ LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"} ;;
+ *BSD | *bsd* | DragonFly)
+ LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"}
+ LDCONFIG="ldconfig -m" ;;
+ CYGWIN* | Cygwin* | cygwin* | OS/2*)
+ EXE='.exe' ;;
+ MINGW* | mingw*)
+# temporary bypass
+ rm -f $test.[co] $test $test$shared_ext
+ echo "Please use win32/Makefile.gcc instead." | tee -a configure.log
+ leave 1
+ LDSHARED=${LDSHARED-"$cc -shared"}
+ LDSHAREDLIBC=""
+ EXE='.exe' ;;
+ QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
+ # (alain.bonnefoy@icbt.com)
+ LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;;
+ HP-UX*)
+ LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
+ case `(uname -m || echo unknown) 2>/dev/null` in
+ ia64)
+ shared_ext='.so'
+ SHAREDLIB='libz.so' ;;
+ *)
+ shared_ext='.sl'
+ SHAREDLIB='libz.sl' ;;
+ esac ;;
+ Darwin* | darwin*)
+ shared_ext='.dylib'
+ SHAREDLIB=libz$shared_ext
+ SHAREDLIBV=libz.$VER$shared_ext
+ SHAREDLIBM=libz.$VER1$shared_ext
+ LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"}
+ if libtool -V 2>&1 | grep Apple > /dev/null; then
+ AR="libtool"
+ else
+ AR="/usr/bin/libtool"
+ fi
+ ARFLAGS="-o" ;;
+ *) LDSHARED=${LDSHARED-"$cc -shared"} ;;
+ esac
+else
+ # find system name and corresponding cc options
+ CC=${CC-cc}
+ gcc=0
+ echo ... using $CC >> configure.log
+ if test -z "$uname"; then
+ uname=`(uname -sr || echo unknown) 2>/dev/null`
+ fi
+ case "$uname" in
+ HP-UX*) SFLAGS=${CFLAGS-"-O +z"}
+ CFLAGS=${CFLAGS-"-O"}
+# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
+ LDSHARED=${LDSHARED-"ld -b"}
+ case `(uname -m || echo unknown) 2>/dev/null` in
+ ia64)
+ shared_ext='.so'
+ SHAREDLIB='libz.so' ;;
+ *)
+ shared_ext='.sl'
+ SHAREDLIB='libz.sl' ;;
+ esac ;;
+ IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
+ CFLAGS=${CFLAGS-"-ansi -O2"}
+ LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
+ OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
+ CFLAGS=${CFLAGS-"-O -std1"}
+ LDFLAGS="${LDFLAGS} -Wl,-rpath,."
+ LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;;
+ OSF1*) SFLAGS=${CFLAGS-"-O -std1"}
+ CFLAGS=${CFLAGS-"-O -std1"}
+ LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
+ QNX*) SFLAGS=${CFLAGS-"-4 -O"}
+ CFLAGS=${CFLAGS-"-4 -O"}
+ LDSHARED=${LDSHARED-"cc"}
+ RANLIB=${RANLIB-"true"}
+ AR="cc"
+ ARFLAGS="-A" ;;
+ SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
+ CFLAGS=${CFLAGS-"-O3"}
+ LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;;
+ SunOS\ 5* | solaris*)
+ LDSHARED=${LDSHARED-"cc -G -h libz$shared_ext.$VER1"}
+ SFLAGS=${CFLAGS-"-fast -KPIC"}
+ CFLAGS=${CFLAGS-"-fast"}
+ if test $build64 -eq 1; then
+ # old versions of SunPRO/Workshop/Studio don't support -m64,
+ # but newer ones do. Check for it.
+ flag64=`$CC -flags | egrep -- '^-m64'`
+ if test x"$flag64" != x"" ; then
+ CFLAGS="${CFLAGS} -m64"
+ SFLAGS="${SFLAGS} -m64"
+ else
+ case `(uname -m || echo unknown) 2>/dev/null` in
+ i86*)
+ SFLAGS="$SFLAGS -xarch=amd64"
+ CFLAGS="$CFLAGS -xarch=amd64" ;;
+ *)
+ SFLAGS="$SFLAGS -xarch=v9"
+ CFLAGS="$CFLAGS -xarch=v9" ;;
+ esac
+ fi
+ fi
+ if test -n "$ZINC"; then
+ ZINC='-I- -I. -I$(SRCDIR)'
+ fi
+ ;;
+ SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
+ CFLAGS=${CFLAGS-"-O2"}
+ LDSHARED=${LDSHARED-"ld"} ;;
+ SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
+ CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"}
+ LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;;
+ UNIX_System_V\ 4.2.0)
+ SFLAGS=${CFLAGS-"-KPIC -O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -G"} ;;
+ UNIX_SV\ 4.2MP)
+ SFLAGS=${CFLAGS-"-Kconform_pic -O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -G"} ;;
+ OpenUNIX\ 5)
+ SFLAGS=${CFLAGS-"-KPIC -O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -G"} ;;
+ AIX*) # Courtesy of dbakker@arrayasolutions.com
+ SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+ CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+ LDSHARED=${LDSHARED-"xlc -G"} ;;
+ # send working options for other systems to zlib@gzip.org
+ *) SFLAGS=${CFLAGS-"-O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -shared"} ;;
+ esac
+fi
+
+# destination names for shared library if not defined above
+SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
+SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
+SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
+
+echo >> configure.log
+
+# define functions for testing compiler and library characteristics and logging the results
+
+cat > $test.c <<EOF
+#error error
+EOF
+if ($CC -c $CFLAGS $test.c) 2>/dev/null; then
+ try()
+ {
+ show $*
+ test "`( $* ) 2>&1 | tee -a configure.log`" = ""
+ }
+ echo - using any output from compiler to indicate an error >> configure.log
+else
+ try()
+ {
+ show $*
+ ( $* ) >> configure.log 2>&1
+ ret=$?
+ if test $ret -ne 0; then
+ echo "(exit code "$ret")" >> configure.log
+ fi
+ return $ret
+ }
+fi
+
+tryboth()
+{
+ show $*
+ got=`( $* ) 2>&1`
+ ret=$?
+ printf %s "$got" >> configure.log
+ if test $ret -ne 0; then
+ return $ret
+ fi
+ test "$got" = ""
+}
+
+cat > $test.c << EOF
+int foo() { return 0; }
+EOF
+echo "Checking for obsessive-compulsive compiler options..." >> configure.log
+if try $CC -c $CFLAGS $test.c; then
+ :
+else
+ echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log
+ leave 1
+fi
+
+echo >> configure.log
+
+# see if shared library build supported
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
+if test $shared -eq 1; then
+ echo Checking for shared library support... | tee -a configure.log
+ # we must test in two steps (cc then ld), required at least on SunOS 4.x
+ if try $CC -w -c $SFLAGS $test.c &&
+ try $LDSHARED $SFLAGS -o $test$shared_ext $test.o; then
+ echo Building shared library $SHAREDLIBV with $CC. | tee -a configure.log
+ elif test -z "$old_cc" -a -z "$old_cflags"; then
+ echo No shared library support. | tee -a configure.log
+ shared=0;
+ else
+ echo 'No shared library support; try without defining CC and CFLAGS' | tee -a configure.log
+ shared=0;
+ fi
+fi
+if test $shared -eq 0; then
+ LDSHARED="$CC"
+ ALL="static"
+ TEST="all teststatic"
+ SHAREDLIB=""
+ SHAREDLIBV=""
+ SHAREDLIBM=""
+ echo Building static library $STATICLIB version $VER with $CC. | tee -a configure.log
+else
+ ALL="static shared"
+ TEST="all teststatic testshared"
+fi
+
+# check for underscores in external names for use by assembler code
+CPP=${CPP-"$CC -E"}
+case $CFLAGS in
+ *ASMV*)
+ echo >> configure.log
+ show "$NM $test.o | grep _hello"
+ if test "`$NM $test.o | grep _hello | tee -a configure.log`" = ""; then
+ CPP="$CPP -DNO_UNDERLINE"
+ echo Checking for underline in external names... No. | tee -a configure.log
+ else
+ echo Checking for underline in external names... Yes. | tee -a configure.log
+ fi ;;
+esac
+
+echo >> configure.log
+
+# check for size_t
+cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdlib.h>
+size_t dummy = 0;
+EOF
+if try $CC -c $CFLAGS $test.c; then
+ echo "Checking for size_t... Yes." | tee -a configure.log
+ need_sizet=0
+else
+ echo "Checking for size_t... No." | tee -a configure.log
+ need_sizet=1
+fi
+
+echo >> configure.log
+
+# find the size_t integer type, if needed
+if test $need_sizet -eq 1; then
+ cat > $test.c <<EOF
+long long dummy = 0;
+EOF
+ if try $CC -c $CFLAGS $test.c; then
+ echo "Checking for long long... Yes." | tee -a configure.log
+ cat > $test.c <<EOF
+#include <stdio.h>
+int main(void) {
+ if (sizeof(void *) <= sizeof(int)) puts("int");
+ else if (sizeof(void *) <= sizeof(long)) puts("long");
+ else puts("z_longlong");
+ return 0;
+}
+EOF
+ else
+ echo "Checking for long long... No." | tee -a configure.log
+ cat > $test.c <<EOF
+#include <stdio.h>
+int main(void) {
+ if (sizeof(void *) <= sizeof(int)) puts("int");
+ else puts("long");
+ return 0;
+}
+EOF
+ fi
+ if try $CC $CFLAGS -o $test $test.c; then
+ sizet=`./$test`
+ echo "Checking for a pointer-size integer type..." $sizet"." | tee -a configure.log
+ else
+ echo "Failed to find a pointer-size integer type." | tee -a configure.log
+ leave 1
+ fi
+fi
+
+if test $need_sizet -eq 1; then
+ CFLAGS="${CFLAGS} -DNO_SIZE_T=${sizet}"
+ SFLAGS="${SFLAGS} -DNO_SIZE_T=${sizet}"
+fi
+
+echo >> configure.log
+
+# check for large file support, and if none, check for fseeko()
+cat > $test.c <<EOF
+#include <sys/types.h>
+off64_t dummy = 0;
+EOF
+if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then
+ CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1"
+ SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1"
+ ALL="${ALL} all64"
+ TEST="${TEST} test64"
+ echo "Checking for off64_t... Yes." | tee -a configure.log
+ echo "Checking for fseeko... Yes." | tee -a configure.log
+else
+ echo "Checking for off64_t... No." | tee -a configure.log
+ echo >> configure.log
+ cat > $test.c <<EOF
+#include <stdio.h>
+int main(void) {
+ fseeko(NULL, 0, 0);
+ return 0;
+}
+EOF
+ if try $CC $CFLAGS -o $test $test.c; then
+ echo "Checking for fseeko... Yes." | tee -a configure.log
+ else
+ CFLAGS="${CFLAGS} -DNO_FSEEKO"
+ SFLAGS="${SFLAGS} -DNO_FSEEKO"
+ echo "Checking for fseeko... No." | tee -a configure.log
+ fi
+fi
+
+echo >> configure.log
+
+# check for strerror() for use by gz* functions
+cat > $test.c <<EOF
+#include <string.h>
+#include <errno.h>
+int main() { return strlen(strerror(errno)); }
+EOF
+if try $CC $CFLAGS -o $test $test.c; then
+ echo "Checking for strerror... Yes." | tee -a configure.log
+else
+ CFLAGS="${CFLAGS} -DNO_STRERROR"
+ SFLAGS="${SFLAGS} -DNO_STRERROR"
+ echo "Checking for strerror... No." | tee -a configure.log
+fi
+
+# copy clean zconf.h for subsequent edits
+cp -p ${SRCDIR}zconf.h.in zconf.h
+
+echo >> configure.log
+
+# check for unistd.h and save result in zconf.h
+cat > $test.c <<EOF
+#include <unistd.h>
+int main() { return 0; }
+EOF
+if try $CC -c $CFLAGS $test.c; then
+ sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
+ mv zconf.temp.h zconf.h
+ echo "Checking for unistd.h... Yes." | tee -a configure.log
+else
+ echo "Checking for unistd.h... No." | tee -a configure.log
+fi
+
+echo >> configure.log
+
+# check for stdarg.h and save result in zconf.h
+cat > $test.c <<EOF
+#include <stdarg.h>
+int main() { return 0; }
+EOF
+if try $CC -c $CFLAGS $test.c; then
+ sed < zconf.h "/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
+ mv zconf.temp.h zconf.h
+ echo "Checking for stdarg.h... Yes." | tee -a configure.log
+else
+ echo "Checking for stdarg.h... No." | tee -a configure.log
+fi
+
+# if the z_ prefix was requested, save that in zconf.h
+if test $zprefix -eq 1; then
+ sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h
+ mv zconf.temp.h zconf.h
+ echo >> configure.log
+ echo "Using z_ prefix on all symbols." | tee -a configure.log
+fi
+
+# if --solo compilation was requested, save that in zconf.h and remove gz stuff from object lists
+if test $solo -eq 1; then
+ sed '/#define ZCONF_H/a\
+#define Z_SOLO
+
+' < zconf.h > zconf.temp.h
+ mv zconf.temp.h zconf.h
+OBJC='$(OBJZ)'
+PIC_OBJC='$(PIC_OBJZ)'
+fi
+
+# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X
+if test $cover -eq 1; then
+ CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage"
+ if test -n "$GCC_CLASSIC"; then
+ CC=$GCC_CLASSIC
+ fi
+fi
+
+echo >> configure.log
+
+# conduct a series of tests to resolve eight possible cases of using "vs" or "s" printf functions
+# (using stdarg or not), with or without "n" (proving size of buffer), and with or without a
+# return value. The most secure result is vsnprintf() with a return value. snprintf() with a
+# return value is secure as well, but then gzprintf() will be limited to 20 arguments.
+cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+#include "zconf.h"
+int main()
+{
+#ifndef STDC
+ choke me
+#endif
+ return 0;
+}
+EOF
+if try $CC -c $CFLAGS $test.c; then
+ echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." | tee -a configure.log
+
+ echo >> configure.log
+ cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+int mytest(const char *fmt, ...)
+{
+ char buf[20];
+ va_list ap;
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return 0;
+}
+int main()
+{
+ return (mytest("Hello%d\n", 1));
+}
+EOF
+ if try $CC $CFLAGS -o $test $test.c; then
+ echo "Checking for vsnprintf() in stdio.h... Yes." | tee -a configure.log
+
+ echo >> configure.log
+ cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+int mytest(const char *fmt, ...)
+{
+ int n;
+ char buf[20];
+ va_list ap;
+ va_start(ap, fmt);
+ n = vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return n;
+}
+int main()
+{
+ return (mytest("Hello%d\n", 1));
+}
+EOF
+
+ if try $CC -c $CFLAGS $test.c; then
+ echo "Checking for return value of vsnprintf()... Yes." | tee -a configure.log
+ else
+ CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
+ SFLAGS="$SFLAGS -DHAS_vsnprintf_void"
+ echo "Checking for return value of vsnprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently vsnprintf() does not return a value. zlib" | tee -a configure.log
+ echo " can build but will be open to possible string-format security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
+ fi
+ else
+ CFLAGS="$CFLAGS -DNO_vsnprintf"
+ SFLAGS="$SFLAGS -DNO_vsnprintf"
+ echo "Checking for vsnprintf() in stdio.h... No." | tee -a configure.log
+ echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" | tee -a configure.log
+ echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
+
+ echo >> configure.log
+ cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+int mytest(const char *fmt, ...)
+{
+ int n;
+ char buf[20];
+ va_list ap;
+ va_start(ap, fmt);
+ n = vsprintf(buf, fmt, ap);
+ va_end(ap);
+ return n;
+}
+int main()
+{
+ return (mytest("Hello%d\n", 1));
+}
+EOF
+
+ if try $CC -c $CFLAGS $test.c; then
+ echo "Checking for return value of vsprintf()... Yes." | tee -a configure.log
+ else
+ CFLAGS="$CFLAGS -DHAS_vsprintf_void"
+ SFLAGS="$SFLAGS -DHAS_vsprintf_void"
+ echo "Checking for return value of vsprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently vsprintf() does not return a value. zlib" | tee -a configure.log
+ echo " can build but will be open to possible string-format security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
+ fi
+ fi
+else
+ echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." | tee -a configure.log
+
+ echo >> configure.log
+ cat >$test.c <<EOF
+#include <stdio.h>
+int mytest()
+{
+ char buf[20];
+ snprintf(buf, sizeof(buf), "%s", "foo");
+ return 0;
+}
+int main()
+{
+ return (mytest());
+}
+EOF
+
+ if try $CC $CFLAGS -o $test $test.c; then
+ echo "Checking for snprintf() in stdio.h... Yes." | tee -a configure.log
+
+ echo >> configure.log
+ cat >$test.c <<EOF
+#include <stdio.h>
+int mytest()
+{
+ char buf[20];
+ return snprintf(buf, sizeof(buf), "%s", "foo");
+}
+int main()
+{
+ return (mytest());
+}
+EOF
+
+ if try $CC -c $CFLAGS $test.c; then
+ echo "Checking for return value of snprintf()... Yes." | tee -a configure.log
+ else
+ CFLAGS="$CFLAGS -DHAS_snprintf_void"
+ SFLAGS="$SFLAGS -DHAS_snprintf_void"
+ echo "Checking for return value of snprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently snprintf() does not return a value. zlib" | tee -a configure.log
+ echo " can build but will be open to possible string-format security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
+ fi
+ else
+ CFLAGS="$CFLAGS -DNO_snprintf"
+ SFLAGS="$SFLAGS -DNO_snprintf"
+ echo "Checking for snprintf() in stdio.h... No." | tee -a configure.log
+ echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" | tee -a configure.log
+ echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
+
+ echo >> configure.log
+ cat >$test.c <<EOF
+#include <stdio.h>
+int mytest()
+{
+ char buf[20];
+ return sprintf(buf, "%s", "foo");
+}
+int main()
+{
+ return (mytest());
+}
+EOF
+
+ if try $CC -c $CFLAGS $test.c; then
+ echo "Checking for return value of sprintf()... Yes." | tee -a configure.log
+ else
+ CFLAGS="$CFLAGS -DHAS_sprintf_void"
+ SFLAGS="$SFLAGS -DHAS_sprintf_void"
+ echo "Checking for return value of sprintf()... No." | tee -a configure.log
+ echo " WARNING: apparently sprintf() does not return a value. zlib" | tee -a configure.log
+ echo " can build but will be open to possible string-format security" | tee -a configure.log
+ echo " vulnerabilities." | tee -a configure.log
+ fi
+ fi
+fi
+
+# see if we can hide zlib internal symbols that are linked between separate source files
+if test "$gcc" -eq 1; then
+ echo >> configure.log
+ cat > $test.c <<EOF
+#define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+int ZLIB_INTERNAL foo;
+int main()
+{
+ return 0;
+}
+EOF
+ if tryboth $CC -c $CFLAGS $test.c; then
+ CFLAGS="$CFLAGS -DHAVE_HIDDEN"
+ SFLAGS="$SFLAGS -DHAVE_HIDDEN"
+ echo "Checking for attribute(visibility) support... Yes." | tee -a configure.log
+ else
+ echo "Checking for attribute(visibility) support... No." | tee -a configure.log
+ fi
+fi
+
+# show the results in the log
+echo >> configure.log
+echo ALL = $ALL >> configure.log
+echo AR = $AR >> configure.log
+echo ARFLAGS = $ARFLAGS >> configure.log
+echo CC = $CC >> configure.log
+echo CFLAGS = $CFLAGS >> configure.log
+echo CPP = $CPP >> configure.log
+echo EXE = $EXE >> configure.log
+echo LDCONFIG = $LDCONFIG >> configure.log
+echo LDFLAGS = $LDFLAGS >> configure.log
+echo LDSHARED = $LDSHARED >> configure.log
+echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log
+echo OBJC = $OBJC >> configure.log
+echo PIC_OBJC = $PIC_OBJC >> configure.log
+echo RANLIB = $RANLIB >> configure.log
+echo SFLAGS = $SFLAGS >> configure.log
+echo SHAREDLIB = $SHAREDLIB >> configure.log
+echo SHAREDLIBM = $SHAREDLIBM >> configure.log
+echo SHAREDLIBV = $SHAREDLIBV >> configure.log
+echo STATICLIB = $STATICLIB >> configure.log
+echo TEST = $TEST >> configure.log
+echo VER = $VER >> configure.log
+echo Z_U4 = $Z_U4 >> configure.log
+echo SRCDIR = $SRCDIR >> configure.log
+echo exec_prefix = $exec_prefix >> configure.log
+echo includedir = $includedir >> configure.log
+echo libdir = $libdir >> configure.log
+echo mandir = $mandir >> configure.log
+echo prefix = $prefix >> configure.log
+echo sharedlibdir = $sharedlibdir >> configure.log
+echo uname = $uname >> configure.log
+
+# udpate Makefile with the configure results
+sed < ${SRCDIR}Makefile.in "
+/^CC *=/s#=.*#=$CC#
+/^CFLAGS *=/s#=.*#=$CFLAGS#
+/^SFLAGS *=/s#=.*#=$SFLAGS#
+/^LDFLAGS *=/s#=.*#=$LDFLAGS#
+/^LDSHARED *=/s#=.*#=$LDSHARED#
+/^CPP *=/s#=.*#=$CPP#
+/^STATICLIB *=/s#=.*#=$STATICLIB#
+/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
+/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
+/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
+/^AR *=/s#=.*#=$AR#
+/^ARFLAGS *=/s#=.*#=$ARFLAGS#
+/^RANLIB *=/s#=.*#=$RANLIB#
+/^LDCONFIG *=/s#=.*#=$LDCONFIG#
+/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC#
+/^EXE *=/s#=.*#=$EXE#
+/^SRCDIR *=/s#=.*#=$SRCDIR#
+/^ZINC *=/s#=.*#=$ZINC#
+/^ZINCOUT *=/s#=.*#=$ZINCOUT#
+/^prefix *=/s#=.*#=$prefix#
+/^exec_prefix *=/s#=.*#=$exec_prefix#
+/^libdir *=/s#=.*#=$libdir#
+/^sharedlibdir *=/s#=.*#=$sharedlibdir#
+/^includedir *=/s#=.*#=$includedir#
+/^mandir *=/s#=.*#=$mandir#
+/^OBJC *=/s#=.*#= $OBJC#
+/^PIC_OBJC *=/s#=.*#= $PIC_OBJC#
+/^all: */s#:.*#: $ALL#
+/^test: */s#:.*#: $TEST#
+" > Makefile
+
+# create zlib.pc with the configure results
+sed < ${SRCDIR}zlib.pc.in "
+/^CC *=/s#=.*#=$CC#
+/^CFLAGS *=/s#=.*#=$CFLAGS#
+/^CPP *=/s#=.*#=$CPP#
+/^LDSHARED *=/s#=.*#=$LDSHARED#
+/^STATICLIB *=/s#=.*#=$STATICLIB#
+/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
+/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
+/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
+/^AR *=/s#=.*#=$AR#
+/^ARFLAGS *=/s#=.*#=$ARFLAGS#
+/^RANLIB *=/s#=.*#=$RANLIB#
+/^EXE *=/s#=.*#=$EXE#
+/^prefix *=/s#=.*#=$prefix#
+/^exec_prefix *=/s#=.*#=$exec_prefix#
+/^libdir *=/s#=.*#=$libdir#
+/^sharedlibdir *=/s#=.*#=$sharedlibdir#
+/^includedir *=/s#=.*#=$includedir#
+/^mandir *=/s#=.*#=$mandir#
+/^LDFLAGS *=/s#=.*#=$LDFLAGS#
+" | sed -e "
+s/\@VERSION\@/$VER/g;
+" > zlib.pc
+
+# done
+leave 0
diff --git a/xs/src/png/zlib/contrib/README.contrib b/xs/src/png/zlib/contrib/README.contrib
new file mode 100644
index 000000000..a411d5c39
--- /dev/null
+++ b/xs/src/png/zlib/contrib/README.contrib
@@ -0,0 +1,78 @@
+All files under this contrib directory are UNSUPPORTED. There were
+provided by users of zlib and were not tested by the authors of zlib.
+Use at your own risk. Please contact the authors of the contributions
+for help about these, not the zlib authors. Thanks.
+
+
+ada/ by Dmitriy Anisimkov <anisimkov@yahoo.com>
+ Support for Ada
+ See http://zlib-ada.sourceforge.net/
+
+amd64/ by Mikhail Teterin <mi@ALDAN.algebra.com>
+ asm code for AMD64
+ See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393
+
+asm686/ by Brian Raiter <breadbox@muppetlabs.com>
+ asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+
+blast/ by Mark Adler <madler@alumni.caltech.edu>
+ Decompressor for output of PKWare Data Compression Library (DCL)
+
+delphi/ by Cosmin Truta <cosmint@cs.ubbcluj.ro>
+ Support for Delphi and C++ Builder
+
+dotzlib/ by Henrik Ravn <henrik@ravn.com>
+ Support for Microsoft .Net and Visual C++ .Net
+
+gcc_gvmat64/by Gilles Vollant <info@winimage.com>
+ GCC Version of x86 64-bit (AMD64 and Intel EM64t) code for x64
+ assembler to replace longest_match() and inflate_fast()
+
+infback9/ by Mark Adler <madler@alumni.caltech.edu>
+ Unsupported diffs to infback to decode the deflate64 format
+
+inflate86/ by Chris Anderson <christop@charm.net>
+ Tuned x86 gcc asm code to replace inflate_fast()
+
+iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+ A C++ I/O streams interface to the zlib gz* functions
+
+iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
+ Another C++ I/O streams interface
+
+iostream3/ by Ludwig Schwardt <schwardt@sun.ac.za>
+ and Kevin Ruland <kevin@rodin.wustl.edu>
+ Yet another C++ I/O streams interface
+
+masmx64/ by Gilles Vollant <info@winimage.com>
+ x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to
+ replace longest_match() and inflate_fast(), also masm x86
+ 64-bits translation of Chris Anderson inflate_fast()
+
+masmx86/ by Gilles Vollant <info@winimage.com>
+ x86 asm code to replace longest_match() and inflate_fast(),
+ for Visual C++ and MASM (32 bits).
+ Based on Brian Raiter (asm686) and Chris Anderson (inflate86)
+
+minizip/ by Gilles Vollant <info@winimage.com>
+ Mini zip and unzip based on zlib
+ Includes Zip64 support by Mathias Svensson <mathias@result42.com>
+ See http://www.winimage.com/zLibDll/minizip.html
+
+pascal/ by Bob Dellaca <bobdl@xtra.co.nz> et al.
+ Support for Pascal
+
+puff/ by Mark Adler <madler@alumni.caltech.edu>
+ Small, low memory usage inflate. Also serves to provide an
+ unambiguous description of the deflate format.
+
+testzlib/ by Gilles Vollant <info@winimage.com>
+ Example of the use of zlib
+
+untgz/ by Pedro A. Aranda Gutierrez <paag@tid.es>
+ A very simple tar.gz file extractor using zlib
+
+vstudio/ by Gilles Vollant <info@winimage.com>
+ Building a minizip-enhanced zlib with Microsoft Visual Studio
+ Includes vc11 from kreuzerkrieg and vc12 from davispuh
diff --git a/xs/src/png/zlib/contrib/ada/buffer_demo.adb b/xs/src/png/zlib/contrib/ada/buffer_demo.adb
new file mode 100644
index 000000000..46b863810
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/buffer_demo.adb
@@ -0,0 +1,106 @@
+----------------------------------------------------------------
+-- ZLib for Ada thick binding. --
+-- --
+-- Copyright (C) 2002-2004 Dmitriy Anisimkov --
+-- --
+-- Open source license information is in the zlib.ads file. --
+----------------------------------------------------------------
+--
+-- $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $
+
+-- This demo program provided by Dr Steve Sangwine <sjs@essex.ac.uk>
+--
+-- Demonstration of a problem with Zlib-Ada (already fixed) when a buffer
+-- of exactly the correct size is used for decompressed data, and the last
+-- few bytes passed in to Zlib are checksum bytes.
+
+-- This program compresses a string of text, and then decompresses the
+-- compressed text into a buffer of the same size as the original text.
+
+with Ada.Streams; use Ada.Streams;
+with Ada.Text_IO;
+
+with ZLib; use ZLib;
+
+procedure Buffer_Demo is
+ EOL : Character renames ASCII.LF;
+ Text : constant String
+ := "Four score and seven years ago our fathers brought forth," & EOL &
+ "upon this continent, a new nation, conceived in liberty," & EOL &
+ "and dedicated to the proposition that `all men are created equal'.";
+
+ Source : Stream_Element_Array (1 .. Text'Length);
+ for Source'Address use Text'Address;
+
+begin
+ Ada.Text_IO.Put (Text);
+ Ada.Text_IO.New_Line;
+ Ada.Text_IO.Put_Line
+ ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes");
+
+ declare
+ Compressed_Data : Stream_Element_Array (1 .. Text'Length);
+ L : Stream_Element_Offset;
+ begin
+ Compress : declare
+ Compressor : Filter_Type;
+ I : Stream_Element_Offset;
+ begin
+ Deflate_Init (Compressor);
+
+ -- Compress the whole of T at once.
+
+ Translate (Compressor, Source, I, Compressed_Data, L, Finish);
+ pragma Assert (I = Source'Last);
+
+ Close (Compressor);
+
+ Ada.Text_IO.Put_Line
+ ("Compressed size : "
+ & Stream_Element_Offset'Image (L) & " bytes");
+ end Compress;
+
+ -- Now we decompress the data, passing short blocks of data to Zlib
+ -- (because this demonstrates the problem - the last block passed will
+ -- contain checksum information and there will be no output, only a
+ -- check inside Zlib that the checksum is correct).
+
+ Decompress : declare
+ Decompressor : Filter_Type;
+
+ Uncompressed_Data : Stream_Element_Array (1 .. Text'Length);
+
+ Block_Size : constant := 4;
+ -- This makes sure that the last block contains
+ -- only Adler checksum data.
+
+ P : Stream_Element_Offset := Compressed_Data'First - 1;
+ O : Stream_Element_Offset;
+ begin
+ Inflate_Init (Decompressor);
+
+ loop
+ Translate
+ (Decompressor,
+ Compressed_Data
+ (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)),
+ P,
+ Uncompressed_Data
+ (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last),
+ O,
+ No_Flush);
+
+ Ada.Text_IO.Put_Line
+ ("Total in : " & Count'Image (Total_In (Decompressor)) &
+ ", out : " & Count'Image (Total_Out (Decompressor)));
+
+ exit when P = L;
+ end loop;
+
+ Ada.Text_IO.New_Line;
+ Ada.Text_IO.Put_Line
+ ("Decompressed text matches original text : "
+ & Boolean'Image (Uncompressed_Data = Source));
+ end Decompress;
+ end;
+end Buffer_Demo;
diff --git a/xs/src/png/zlib/contrib/ada/mtest.adb b/xs/src/png/zlib/contrib/ada/mtest.adb
new file mode 100644
index 000000000..c4dfd080f
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/mtest.adb
@@ -0,0 +1,156 @@
+----------------------------------------------------------------
+-- ZLib for Ada thick binding. --
+-- --
+-- Copyright (C) 2002-2003 Dmitriy Anisimkov --
+-- --
+-- Open source license information is in the zlib.ads file. --
+----------------------------------------------------------------
+-- Continuous test for ZLib multithreading. If the test would fail
+-- we should provide thread safe allocation routines for the Z_Stream.
+--
+-- $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $
+
+with ZLib;
+with Ada.Streams;
+with Ada.Numerics.Discrete_Random;
+with Ada.Text_IO;
+with Ada.Exceptions;
+with Ada.Task_Identification;
+
+procedure MTest is
+ use Ada.Streams;
+ use ZLib;
+
+ Stop : Boolean := False;
+
+ pragma Atomic (Stop);
+
+ subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
+
+ package Random_Elements is
+ new Ada.Numerics.Discrete_Random (Visible_Symbols);
+
+ task type Test_Task;
+
+ task body Test_Task is
+ Buffer : Stream_Element_Array (1 .. 100_000);
+ Gen : Random_Elements.Generator;
+
+ Buffer_First : Stream_Element_Offset;
+ Compare_First : Stream_Element_Offset;
+
+ Deflate : Filter_Type;
+ Inflate : Filter_Type;
+
+ procedure Further (Item : in Stream_Element_Array);
+
+ procedure Read_Buffer
+ (Item : out Ada.Streams.Stream_Element_Array;
+ Last : out Ada.Streams.Stream_Element_Offset);
+
+ -------------
+ -- Further --
+ -------------
+
+ procedure Further (Item : in Stream_Element_Array) is
+
+ procedure Compare (Item : in Stream_Element_Array);
+
+ -------------
+ -- Compare --
+ -------------
+
+ procedure Compare (Item : in Stream_Element_Array) is
+ Next_First : Stream_Element_Offset := Compare_First + Item'Length;
+ begin
+ if Buffer (Compare_First .. Next_First - 1) /= Item then
+ raise Program_Error;
+ end if;
+
+ Compare_First := Next_First;
+ end Compare;
+
+ procedure Compare_Write is new ZLib.Write (Write => Compare);
+ begin
+ Compare_Write (Inflate, Item, No_Flush);
+ end Further;
+
+ -----------------
+ -- Read_Buffer --
+ -----------------
+
+ procedure Read_Buffer
+ (Item : out Ada.Streams.Stream_Element_Array;
+ Last : out Ada.Streams.Stream_Element_Offset)
+ is
+ Buff_Diff : Stream_Element_Offset := Buffer'Last - Buffer_First;
+ Next_First : Stream_Element_Offset;
+ begin
+ if Item'Length <= Buff_Diff then
+ Last := Item'Last;
+
+ Next_First := Buffer_First + Item'Length;
+
+ Item := Buffer (Buffer_First .. Next_First - 1);
+
+ Buffer_First := Next_First;
+ else
+ Last := Item'First + Buff_Diff;
+ Item (Item'First .. Last) := Buffer (Buffer_First .. Buffer'Last);
+ Buffer_First := Buffer'Last + 1;
+ end if;
+ end Read_Buffer;
+
+ procedure Translate is new Generic_Translate
+ (Data_In => Read_Buffer,
+ Data_Out => Further);
+
+ begin
+ Random_Elements.Reset (Gen);
+
+ Buffer := (others => 20);
+
+ Main : loop
+ for J in Buffer'Range loop
+ Buffer (J) := Random_Elements.Random (Gen);
+
+ Deflate_Init (Deflate);
+ Inflate_Init (Inflate);
+
+ Buffer_First := Buffer'First;
+ Compare_First := Buffer'First;
+
+ Translate (Deflate);
+
+ if Compare_First /= Buffer'Last + 1 then
+ raise Program_Error;
+ end if;
+
+ Ada.Text_IO.Put_Line
+ (Ada.Task_Identification.Image
+ (Ada.Task_Identification.Current_Task)
+ & Stream_Element_Offset'Image (J)
+ & ZLib.Count'Image (Total_Out (Deflate)));
+
+ Close (Deflate);
+ Close (Inflate);
+
+ exit Main when Stop;
+ end loop;
+ end loop Main;
+ exception
+ when E : others =>
+ Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E));
+ Stop := True;
+ end Test_Task;
+
+ Test : array (1 .. 4) of Test_Task;
+
+ pragma Unreferenced (Test);
+
+ Dummy : Character;
+
+begin
+ Ada.Text_IO.Get_Immediate (Dummy);
+ Stop := True;
+end MTest;
diff --git a/xs/src/png/zlib/contrib/ada/read.adb b/xs/src/png/zlib/contrib/ada/read.adb
new file mode 100644
index 000000000..1f2efbfeb
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/read.adb
@@ -0,0 +1,156 @@
+----------------------------------------------------------------
+-- ZLib for Ada thick binding. --
+-- --
+-- Copyright (C) 2002-2003 Dmitriy Anisimkov --
+-- --
+-- Open source license information is in the zlib.ads file. --
+----------------------------------------------------------------
+
+-- $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $
+
+-- Test/demo program for the generic read interface.
+
+with Ada.Numerics.Discrete_Random;
+with Ada.Streams;
+with Ada.Text_IO;
+
+with ZLib;
+
+procedure Read is
+
+ use Ada.Streams;
+
+ ------------------------------------
+ -- Test configuration parameters --
+ ------------------------------------
+
+ File_Size : Stream_Element_Offset := 100_000;
+
+ Continuous : constant Boolean := False;
+ -- If this constant is True, the test would be repeated again and again,
+ -- with increment File_Size for every iteration.
+
+ Header : constant ZLib.Header_Type := ZLib.Default;
+ -- Do not use Header other than Default in ZLib versions 1.1.4 and older.
+
+ Init_Random : constant := 8;
+ -- We are using the same random sequence, in case of we catch bug,
+ -- so we would be able to reproduce it.
+
+ -- End --
+
+ Pack_Size : Stream_Element_Offset;
+ Offset : Stream_Element_Offset;
+
+ Filter : ZLib.Filter_Type;
+
+ subtype Visible_Symbols
+ is Stream_Element range 16#20# .. 16#7E#;
+
+ package Random_Elements is new
+ Ada.Numerics.Discrete_Random (Visible_Symbols);
+
+ Gen : Random_Elements.Generator;
+ Period : constant Stream_Element_Offset := 200;
+ -- Period constant variable for random generator not to be very random.
+ -- Bigger period, harder random.
+
+ Read_Buffer : Stream_Element_Array (1 .. 2048);
+ Read_First : Stream_Element_Offset;
+ Read_Last : Stream_Element_Offset;
+
+ procedure Reset;
+
+ procedure Read
+ (Item : out Stream_Element_Array;
+ Last : out Stream_Element_Offset);
+ -- this procedure is for generic instantiation of
+ -- ZLib.Read
+ -- reading data from the File_In.
+
+ procedure Read is new ZLib.Read
+ (Read,
+ Read_Buffer,
+ Rest_First => Read_First,
+ Rest_Last => Read_Last);
+
+ ----------
+ -- Read --
+ ----------
+
+ procedure Read
+ (Item : out Stream_Element_Array;
+ Last : out Stream_Element_Offset) is
+ begin
+ Last := Stream_Element_Offset'Min
+ (Item'Last,
+ Item'First + File_Size - Offset);
+
+ for J in Item'First .. Last loop
+ if J < Item'First + Period then
+ Item (J) := Random_Elements.Random (Gen);
+ else
+ Item (J) := Item (J - Period);
+ end if;
+
+ Offset := Offset + 1;
+ end loop;
+ end Read;
+
+ -----------
+ -- Reset --
+ -----------
+
+ procedure Reset is
+ begin
+ Random_Elements.Reset (Gen, Init_Random);
+ Pack_Size := 0;
+ Offset := 1;
+ Read_First := Read_Buffer'Last + 1;
+ Read_Last := Read_Buffer'Last;
+ end Reset;
+
+begin
+ Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
+
+ loop
+ for Level in ZLib.Compression_Level'Range loop
+
+ Ada.Text_IO.Put ("Level ="
+ & ZLib.Compression_Level'Image (Level));
+
+ -- Deflate using generic instantiation.
+
+ ZLib.Deflate_Init
+ (Filter,
+ Level,
+ Header => Header);
+
+ Reset;
+
+ Ada.Text_IO.Put
+ (Stream_Element_Offset'Image (File_Size) & " ->");
+
+ loop
+ declare
+ Buffer : Stream_Element_Array (1 .. 1024);
+ Last : Stream_Element_Offset;
+ begin
+ Read (Filter, Buffer, Last);
+
+ Pack_Size := Pack_Size + Last - Buffer'First + 1;
+
+ exit when Last < Buffer'Last;
+ end;
+ end loop;
+
+ Ada.Text_IO.Put_Line (Stream_Element_Offset'Image (Pack_Size));
+
+ ZLib.Close (Filter);
+ end loop;
+
+ exit when not Continuous;
+
+ File_Size := File_Size + 1;
+ end loop;
+end Read;
diff --git a/xs/src/png/zlib/contrib/ada/readme.txt b/xs/src/png/zlib/contrib/ada/readme.txt
new file mode 100644
index 000000000..ce4d2cadf
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/readme.txt
@@ -0,0 +1,65 @@
+ ZLib for Ada thick binding (ZLib.Ada)
+ Release 1.3
+
+ZLib.Ada is a thick binding interface to the popular ZLib data
+compression library, available at http://www.gzip.org/zlib/.
+It provides Ada-style access to the ZLib C library.
+
+
+ Here are the main changes since ZLib.Ada 1.2:
+
+- Attension: ZLib.Read generic routine have a initialization requirement
+ for Read_Last parameter now. It is a bit incompartible with previous version,
+ but extends functionality, we could use new parameters Allow_Read_Some and
+ Flush now.
+
+- Added Is_Open routines to ZLib and ZLib.Streams packages.
+
+- Add pragma Assert to check Stream_Element is 8 bit.
+
+- Fix extraction to buffer with exact known decompressed size. Error reported by
+ Steve Sangwine.
+
+- Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits
+ computers. Patch provided by Pascal Obry.
+
+- Add Status_Error exception definition.
+
+- Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit.
+
+
+ How to build ZLib.Ada under GNAT
+
+You should have the ZLib library already build on your computer, before
+building ZLib.Ada. Make the directory of ZLib.Ada sources current and
+issue the command:
+
+ gnatmake test -largs -L<directory where libz.a is> -lz
+
+Or use the GNAT project file build for GNAT 3.15 or later:
+
+ gnatmake -Pzlib.gpr -L<directory where libz.a is>
+
+
+ How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2
+
+1. Make a project with all *.ads and *.adb files from the distribution.
+2. Build the libz.a library from the ZLib C sources.
+3. Rename libz.a to z.lib.
+4. Add the library z.lib to the project.
+5. Add the libc.lib library from the ObjectAda distribution to the project.
+6. Build the executable using test.adb as a main procedure.
+
+
+ How to use ZLib.Ada
+
+The source files test.adb and read.adb are small demo programs that show
+the main functionality of ZLib.Ada.
+
+The routines from the package specifications are commented.
+
+
+Homepage: http://zlib-ada.sourceforge.net/
+Author: Dmitriy Anisimkov <anisimkov@yahoo.com>
+
+Contributors: Pascal Obry <pascal@obry.org>, Steve Sangwine <sjs@essex.ac.uk>
diff --git a/xs/src/png/zlib/contrib/ada/test.adb b/xs/src/png/zlib/contrib/ada/test.adb
new file mode 100644
index 000000000..90773acfa
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/test.adb
@@ -0,0 +1,463 @@
+----------------------------------------------------------------
+-- ZLib for Ada thick binding. --
+-- --
+-- Copyright (C) 2002-2003 Dmitriy Anisimkov --
+-- --
+-- Open source license information is in the zlib.ads file. --
+----------------------------------------------------------------
+
+-- $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $
+
+-- The program has a few aims.
+-- 1. Test ZLib.Ada95 thick binding functionality.
+-- 2. Show the example of use main functionality of the ZLib.Ada95 binding.
+-- 3. Build this program automatically compile all ZLib.Ada95 packages under
+-- GNAT Ada95 compiler.
+
+with ZLib.Streams;
+with Ada.Streams.Stream_IO;
+with Ada.Numerics.Discrete_Random;
+
+with Ada.Text_IO;
+
+with Ada.Calendar;
+
+procedure Test is
+
+ use Ada.Streams;
+ use Stream_IO;
+
+ ------------------------------------
+ -- Test configuration parameters --
+ ------------------------------------
+
+ File_Size : Count := 100_000;
+ Continuous : constant Boolean := False;
+
+ Header : constant ZLib.Header_Type := ZLib.Default;
+ -- ZLib.None;
+ -- ZLib.Auto;
+ -- ZLib.GZip;
+ -- Do not use Header other then Default in ZLib versions 1.1.4
+ -- and older.
+
+ Strategy : constant ZLib.Strategy_Type := ZLib.Default_Strategy;
+ Init_Random : constant := 10;
+
+ -- End --
+
+ In_File_Name : constant String := "testzlib.in";
+ -- Name of the input file
+
+ Z_File_Name : constant String := "testzlib.zlb";
+ -- Name of the compressed file.
+
+ Out_File_Name : constant String := "testzlib.out";
+ -- Name of the decompressed file.
+
+ File_In : File_Type;
+ File_Out : File_Type;
+ File_Back : File_Type;
+ File_Z : ZLib.Streams.Stream_Type;
+
+ Filter : ZLib.Filter_Type;
+
+ Time_Stamp : Ada.Calendar.Time;
+
+ procedure Generate_File;
+ -- Generate file of spetsified size with some random data.
+ -- The random data is repeatable, for the good compression.
+
+ procedure Compare_Streams
+ (Left, Right : in out Root_Stream_Type'Class);
+ -- The procedure compearing data in 2 streams.
+ -- It is for compare data before and after compression/decompression.
+
+ procedure Compare_Files (Left, Right : String);
+ -- Compare files. Based on the Compare_Streams.
+
+ procedure Copy_Streams
+ (Source, Target : in out Root_Stream_Type'Class;
+ Buffer_Size : in Stream_Element_Offset := 1024);
+ -- Copying data from one stream to another. It is for test stream
+ -- interface of the library.
+
+ procedure Data_In
+ (Item : out Stream_Element_Array;
+ Last : out Stream_Element_Offset);
+ -- this procedure is for generic instantiation of
+ -- ZLib.Generic_Translate.
+ -- reading data from the File_In.
+
+ procedure Data_Out (Item : in Stream_Element_Array);
+ -- this procedure is for generic instantiation of
+ -- ZLib.Generic_Translate.
+ -- writing data to the File_Out.
+
+ procedure Stamp;
+ -- Store the timestamp to the local variable.
+
+ procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count);
+ -- Print the time statistic with the message.
+
+ procedure Translate is new ZLib.Generic_Translate
+ (Data_In => Data_In,
+ Data_Out => Data_Out);
+ -- This procedure is moving data from File_In to File_Out
+ -- with compression or decompression, depend on initialization of
+ -- Filter parameter.
+
+ -------------------
+ -- Compare_Files --
+ -------------------
+
+ procedure Compare_Files (Left, Right : String) is
+ Left_File, Right_File : File_Type;
+ begin
+ Open (Left_File, In_File, Left);
+ Open (Right_File, In_File, Right);
+ Compare_Streams (Stream (Left_File).all, Stream (Right_File).all);
+ Close (Left_File);
+ Close (Right_File);
+ end Compare_Files;
+
+ ---------------------
+ -- Compare_Streams --
+ ---------------------
+
+ procedure Compare_Streams
+ (Left, Right : in out Ada.Streams.Root_Stream_Type'Class)
+ is
+ Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#);
+ Left_Last, Right_Last : Stream_Element_Offset;
+ begin
+ loop
+ Read (Left, Left_Buffer, Left_Last);
+ Read (Right, Right_Buffer, Right_Last);
+
+ if Left_Last /= Right_Last then
+ Ada.Text_IO.Put_Line ("Compare error :"
+ & Stream_Element_Offset'Image (Left_Last)
+ & " /= "
+ & Stream_Element_Offset'Image (Right_Last));
+
+ raise Constraint_Error;
+
+ elsif Left_Buffer (0 .. Left_Last)
+ /= Right_Buffer (0 .. Right_Last)
+ then
+ Ada.Text_IO.Put_Line ("ERROR: IN and OUT files is not equal.");
+ raise Constraint_Error;
+
+ end if;
+
+ exit when Left_Last < Left_Buffer'Last;
+ end loop;
+ end Compare_Streams;
+
+ ------------------
+ -- Copy_Streams --
+ ------------------
+
+ procedure Copy_Streams
+ (Source, Target : in out Ada.Streams.Root_Stream_Type'Class;
+ Buffer_Size : in Stream_Element_Offset := 1024)
+ is
+ Buffer : Stream_Element_Array (1 .. Buffer_Size);
+ Last : Stream_Element_Offset;
+ begin
+ loop
+ Read (Source, Buffer, Last);
+ Write (Target, Buffer (1 .. Last));
+
+ exit when Last < Buffer'Last;
+ end loop;
+ end Copy_Streams;
+
+ -------------
+ -- Data_In --
+ -------------
+
+ procedure Data_In
+ (Item : out Stream_Element_Array;
+ Last : out Stream_Element_Offset) is
+ begin
+ Read (File_In, Item, Last);
+ end Data_In;
+
+ --------------
+ -- Data_Out --
+ --------------
+
+ procedure Data_Out (Item : in Stream_Element_Array) is
+ begin
+ Write (File_Out, Item);
+ end Data_Out;
+
+ -------------------
+ -- Generate_File --
+ -------------------
+
+ procedure Generate_File is
+ subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
+
+ package Random_Elements is
+ new Ada.Numerics.Discrete_Random (Visible_Symbols);
+
+ Gen : Random_Elements.Generator;
+ Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10;
+
+ Buffer_Count : constant Count := File_Size / Buffer'Length;
+ -- Number of same buffers in the packet.
+
+ Density : constant Count := 30; -- from 0 to Buffer'Length - 2;
+
+ procedure Fill_Buffer (J, D : in Count);
+ -- Change the part of the buffer.
+
+ -----------------
+ -- Fill_Buffer --
+ -----------------
+
+ procedure Fill_Buffer (J, D : in Count) is
+ begin
+ for K in 0 .. D loop
+ Buffer
+ (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1))
+ := Random_Elements.Random (Gen);
+
+ end loop;
+ end Fill_Buffer;
+
+ begin
+ Random_Elements.Reset (Gen, Init_Random);
+
+ Create (File_In, Out_File, In_File_Name);
+
+ Fill_Buffer (1, Buffer'Length - 2);
+
+ for J in 1 .. Buffer_Count loop
+ Write (File_In, Buffer);
+
+ Fill_Buffer (J, Density);
+ end loop;
+
+ -- fill remain size.
+
+ Write
+ (File_In,
+ Buffer
+ (1 .. Stream_Element_Offset
+ (File_Size - Buffer'Length * Buffer_Count)));
+
+ Flush (File_In);
+ Close (File_In);
+ end Generate_File;
+
+ ---------------------
+ -- Print_Statistic --
+ ---------------------
+
+ procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is
+ use Ada.Calendar;
+ use Ada.Text_IO;
+
+ package Count_IO is new Integer_IO (ZLib.Count);
+
+ Curr_Dur : Duration := Clock - Time_Stamp;
+ begin
+ Put (Msg);
+
+ Set_Col (20);
+ Ada.Text_IO.Put ("size =");
+
+ Count_IO.Put
+ (Data_Size,
+ Width => Stream_IO.Count'Image (File_Size)'Length);
+
+ Put_Line (" duration =" & Duration'Image (Curr_Dur));
+ end Print_Statistic;
+
+ -----------
+ -- Stamp --
+ -----------
+
+ procedure Stamp is
+ begin
+ Time_Stamp := Ada.Calendar.Clock;
+ end Stamp;
+
+begin
+ Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
+
+ loop
+ Generate_File;
+
+ for Level in ZLib.Compression_Level'Range loop
+
+ Ada.Text_IO.Put_Line ("Level ="
+ & ZLib.Compression_Level'Image (Level));
+
+ -- Test generic interface.
+ Open (File_In, In_File, In_File_Name);
+ Create (File_Out, Out_File, Z_File_Name);
+
+ Stamp;
+
+ -- Deflate using generic instantiation.
+
+ ZLib.Deflate_Init
+ (Filter => Filter,
+ Level => Level,
+ Strategy => Strategy,
+ Header => Header);
+
+ Translate (Filter);
+ Print_Statistic ("Generic compress", ZLib.Total_Out (Filter));
+ ZLib.Close (Filter);
+
+ Close (File_In);
+ Close (File_Out);
+
+ Open (File_In, In_File, Z_File_Name);
+ Create (File_Out, Out_File, Out_File_Name);
+
+ Stamp;
+
+ -- Inflate using generic instantiation.
+
+ ZLib.Inflate_Init (Filter, Header => Header);
+
+ Translate (Filter);
+ Print_Statistic ("Generic decompress", ZLib.Total_Out (Filter));
+
+ ZLib.Close (Filter);
+
+ Close (File_In);
+ Close (File_Out);
+
+ Compare_Files (In_File_Name, Out_File_Name);
+
+ -- Test stream interface.
+
+ -- Compress to the back stream.
+
+ Open (File_In, In_File, In_File_Name);
+ Create (File_Back, Out_File, Z_File_Name);
+
+ Stamp;
+
+ ZLib.Streams.Create
+ (Stream => File_Z,
+ Mode => ZLib.Streams.Out_Stream,
+ Back => ZLib.Streams.Stream_Access
+ (Stream (File_Back)),
+ Back_Compressed => True,
+ Level => Level,
+ Strategy => Strategy,
+ Header => Header);
+
+ Copy_Streams
+ (Source => Stream (File_In).all,
+ Target => File_Z);
+
+ -- Flushing internal buffers to the back stream.
+
+ ZLib.Streams.Flush (File_Z, ZLib.Finish);
+
+ Print_Statistic ("Write compress",
+ ZLib.Streams.Write_Total_Out (File_Z));
+
+ ZLib.Streams.Close (File_Z);
+
+ Close (File_In);
+ Close (File_Back);
+
+ -- Compare reading from original file and from
+ -- decompression stream.
+
+ Open (File_In, In_File, In_File_Name);
+ Open (File_Back, In_File, Z_File_Name);
+
+ ZLib.Streams.Create
+ (Stream => File_Z,
+ Mode => ZLib.Streams.In_Stream,
+ Back => ZLib.Streams.Stream_Access
+ (Stream (File_Back)),
+ Back_Compressed => True,
+ Header => Header);
+
+ Stamp;
+ Compare_Streams (Stream (File_In).all, File_Z);
+
+ Print_Statistic ("Read decompress",
+ ZLib.Streams.Read_Total_Out (File_Z));
+
+ ZLib.Streams.Close (File_Z);
+ Close (File_In);
+ Close (File_Back);
+
+ -- Compress by reading from compression stream.
+
+ Open (File_Back, In_File, In_File_Name);
+ Create (File_Out, Out_File, Z_File_Name);
+
+ ZLib.Streams.Create
+ (Stream => File_Z,
+ Mode => ZLib.Streams.In_Stream,
+ Back => ZLib.Streams.Stream_Access
+ (Stream (File_Back)),
+ Back_Compressed => False,
+ Level => Level,
+ Strategy => Strategy,
+ Header => Header);
+
+ Stamp;
+ Copy_Streams
+ (Source => File_Z,
+ Target => Stream (File_Out).all);
+
+ Print_Statistic ("Read compress",
+ ZLib.Streams.Read_Total_Out (File_Z));
+
+ ZLib.Streams.Close (File_Z);
+
+ Close (File_Out);
+ Close (File_Back);
+
+ -- Decompress to decompression stream.
+
+ Open (File_In, In_File, Z_File_Name);
+ Create (File_Back, Out_File, Out_File_Name);
+
+ ZLib.Streams.Create
+ (Stream => File_Z,
+ Mode => ZLib.Streams.Out_Stream,
+ Back => ZLib.Streams.Stream_Access
+ (Stream (File_Back)),
+ Back_Compressed => False,
+ Header => Header);
+
+ Stamp;
+
+ Copy_Streams
+ (Source => Stream (File_In).all,
+ Target => File_Z);
+
+ Print_Statistic ("Write decompress",
+ ZLib.Streams.Write_Total_Out (File_Z));
+
+ ZLib.Streams.Close (File_Z);
+ Close (File_In);
+ Close (File_Back);
+
+ Compare_Files (In_File_Name, Out_File_Name);
+ end loop;
+
+ Ada.Text_IO.Put_Line (Count'Image (File_Size) & " Ok.");
+
+ exit when not Continuous;
+
+ File_Size := File_Size + 1;
+ end loop;
+end Test;
diff --git a/xs/src/png/zlib/contrib/ada/zlib-streams.adb b/xs/src/png/zlib/contrib/ada/zlib-streams.adb
new file mode 100644
index 000000000..b6497bae2
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/zlib-streams.adb
@@ -0,0 +1,225 @@
+----------------------------------------------------------------
+-- ZLib for Ada thick binding. --
+-- --
+-- Copyright (C) 2002-2003 Dmitriy Anisimkov --
+-- --
+-- Open source license information is in the zlib.ads file. --
+----------------------------------------------------------------
+
+-- $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $
+
+with Ada.Unchecked_Deallocation;
+
+package body ZLib.Streams is
+
+ -----------
+ -- Close --
+ -----------
+
+ procedure Close (Stream : in out Stream_Type) is
+ procedure Free is new Ada.Unchecked_Deallocation
+ (Stream_Element_Array, Buffer_Access);
+ begin
+ if Stream.Mode = Out_Stream or Stream.Mode = Duplex then
+ -- We should flush the data written by the writer.
+
+ Flush (Stream, Finish);
+
+ Close (Stream.Writer);
+ end if;
+
+ if Stream.Mode = In_Stream or Stream.Mode = Duplex then
+ Close (Stream.Reader);
+ Free (Stream.Buffer);
+ end if;
+ end Close;
+
+ ------------
+ -- Create --
+ ------------
+
+ procedure Create
+ (Stream : out Stream_Type;
+ Mode : in Stream_Mode;
+ Back : in Stream_Access;
+ Back_Compressed : in Boolean;
+ Level : in Compression_Level := Default_Compression;
+ Strategy : in Strategy_Type := Default_Strategy;
+ Header : in Header_Type := Default;
+ Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset
+ := Default_Buffer_Size;
+ Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset
+ := Default_Buffer_Size)
+ is
+
+ subtype Buffer_Subtype is Stream_Element_Array (1 .. Read_Buffer_Size);
+
+ procedure Init_Filter
+ (Filter : in out Filter_Type;
+ Compress : in Boolean);
+
+ -----------------
+ -- Init_Filter --
+ -----------------
+
+ procedure Init_Filter
+ (Filter : in out Filter_Type;
+ Compress : in Boolean) is
+ begin
+ if Compress then
+ Deflate_Init
+ (Filter, Level, Strategy, Header => Header);
+ else
+ Inflate_Init (Filter, Header => Header);
+ end if;
+ end Init_Filter;
+
+ begin
+ Stream.Back := Back;
+ Stream.Mode := Mode;
+
+ if Mode = Out_Stream or Mode = Duplex then
+ Init_Filter (Stream.Writer, Back_Compressed);
+ Stream.Buffer_Size := Write_Buffer_Size;
+ else
+ Stream.Buffer_Size := 0;
+ end if;
+
+ if Mode = In_Stream or Mode = Duplex then
+ Init_Filter (Stream.Reader, not Back_Compressed);
+
+ Stream.Buffer := new Buffer_Subtype;
+ Stream.Rest_First := Stream.Buffer'Last + 1;
+ Stream.Rest_Last := Stream.Buffer'Last;
+ end if;
+ end Create;
+
+ -----------
+ -- Flush --
+ -----------
+
+ procedure Flush
+ (Stream : in out Stream_Type;
+ Mode : in Flush_Mode := Sync_Flush)
+ is
+ Buffer : Stream_Element_Array (1 .. Stream.Buffer_Size);
+ Last : Stream_Element_Offset;
+ begin
+ loop
+ Flush (Stream.Writer, Buffer, Last, Mode);
+
+ Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last));
+
+ exit when Last < Buffer'Last;
+ end loop;
+ end Flush;
+
+ -------------
+ -- Is_Open --
+ -------------
+
+ function Is_Open (Stream : Stream_Type) return Boolean is
+ begin
+ return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer);
+ end Is_Open;
+
+ ----------
+ -- Read --
+ ----------
+
+ procedure Read
+ (Stream : in out Stream_Type;
+ Item : out Stream_Element_Array;
+ Last : out Stream_Element_Offset)
+ is
+
+ procedure Read
+ (Item : out Stream_Element_Array;
+ Last : out Stream_Element_Offset);
+
+ ----------
+ -- Read --
+ ----------
+
+ procedure Read
+ (Item : out Stream_Element_Array;
+ Last : out Stream_Element_Offset) is
+ begin
+ Ada.Streams.Read (Stream.Back.all, Item, Last);
+ end Read;
+
+ procedure Read is new ZLib.Read
+ (Read => Read,
+ Buffer => Stream.Buffer.all,
+ Rest_First => Stream.Rest_First,
+ Rest_Last => Stream.Rest_Last);
+
+ begin
+ Read (Stream.Reader, Item, Last);
+ end Read;
+
+ -------------------
+ -- Read_Total_In --
+ -------------------
+
+ function Read_Total_In (Stream : in Stream_Type) return Count is
+ begin
+ return Total_In (Stream.Reader);
+ end Read_Total_In;
+
+ --------------------
+ -- Read_Total_Out --
+ --------------------
+
+ function Read_Total_Out (Stream : in Stream_Type) return Count is
+ begin
+ return Total_Out (Stream.Reader);
+ end Read_Total_Out;
+
+ -----------
+ -- Write --
+ -----------
+
+ procedure Write
+ (Stream : in out Stream_Type;
+ Item : in Stream_Element_Array)
+ is
+
+ procedure Write (Item : in Stream_Element_Array);
+
+ -----------
+ -- Write --
+ -----------
+
+ procedure Write (Item : in Stream_Element_Array) is
+ begin
+ Ada.Streams.Write (Stream.Back.all, Item);
+ end Write;
+
+ procedure Write is new ZLib.Write
+ (Write => Write,
+ Buffer_Size => Stream.Buffer_Size);
+
+ begin
+ Write (Stream.Writer, Item, No_Flush);
+ end Write;
+
+ --------------------
+ -- Write_Total_In --
+ --------------------
+
+ function Write_Total_In (Stream : in Stream_Type) return Count is
+ begin
+ return Total_In (Stream.Writer);
+ end Write_Total_In;
+
+ ---------------------
+ -- Write_Total_Out --
+ ---------------------
+
+ function Write_Total_Out (Stream : in Stream_Type) return Count is
+ begin
+ return Total_Out (Stream.Writer);
+ end Write_Total_Out;
+
+end ZLib.Streams;
diff --git a/xs/src/png/zlib/contrib/ada/zlib-streams.ads b/xs/src/png/zlib/contrib/ada/zlib-streams.ads
new file mode 100644
index 000000000..8e26cd450
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/zlib-streams.ads
@@ -0,0 +1,114 @@
+----------------------------------------------------------------
+-- ZLib for Ada thick binding. --
+-- --
+-- Copyright (C) 2002-2003 Dmitriy Anisimkov --
+-- --
+-- Open source license information is in the zlib.ads file. --
+----------------------------------------------------------------
+
+-- $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $
+
+package ZLib.Streams is
+
+ type Stream_Mode is (In_Stream, Out_Stream, Duplex);
+
+ type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
+
+ type Stream_Type is
+ new Ada.Streams.Root_Stream_Type with private;
+
+ procedure Read
+ (Stream : in out Stream_Type;
+ Item : out Ada.Streams.Stream_Element_Array;
+ Last : out Ada.Streams.Stream_Element_Offset);
+
+ procedure Write
+ (Stream : in out Stream_Type;
+ Item : in Ada.Streams.Stream_Element_Array);
+
+ procedure Flush
+ (Stream : in out Stream_Type;
+ Mode : in Flush_Mode := Sync_Flush);
+ -- Flush the written data to the back stream,
+ -- all data placed to the compressor is flushing to the Back stream.
+ -- Should not be used until necessary, because it is decreasing
+ -- compression.
+
+ function Read_Total_In (Stream : in Stream_Type) return Count;
+ pragma Inline (Read_Total_In);
+ -- Return total number of bytes read from back stream so far.
+
+ function Read_Total_Out (Stream : in Stream_Type) return Count;
+ pragma Inline (Read_Total_Out);
+ -- Return total number of bytes read so far.
+
+ function Write_Total_In (Stream : in Stream_Type) return Count;
+ pragma Inline (Write_Total_In);
+ -- Return total number of bytes written so far.
+
+ function Write_Total_Out (Stream : in Stream_Type) return Count;
+ pragma Inline (Write_Total_Out);
+ -- Return total number of bytes written to the back stream.
+
+ procedure Create
+ (Stream : out Stream_Type;
+ Mode : in Stream_Mode;
+ Back : in Stream_Access;
+ Back_Compressed : in Boolean;
+ Level : in Compression_Level := Default_Compression;
+ Strategy : in Strategy_Type := Default_Strategy;
+ Header : in Header_Type := Default;
+ Read_Buffer_Size : in Ada.Streams.Stream_Element_Offset
+ := Default_Buffer_Size;
+ Write_Buffer_Size : in Ada.Streams.Stream_Element_Offset
+ := Default_Buffer_Size);
+ -- Create the Comression/Decompression stream.
+ -- If mode is In_Stream then Write operation is disabled.
+ -- If mode is Out_Stream then Read operation is disabled.
+
+ -- If Back_Compressed is true then
+ -- Data written to the Stream is compressing to the Back stream
+ -- and data read from the Stream is decompressed data from the Back stream.
+
+ -- If Back_Compressed is false then
+ -- Data written to the Stream is decompressing to the Back stream
+ -- and data read from the Stream is compressed data from the Back stream.
+
+ -- !!! When the Need_Header is False ZLib-Ada is using undocumented
+ -- ZLib 1.1.4 functionality to do not create/wait for ZLib headers.
+
+ function Is_Open (Stream : Stream_Type) return Boolean;
+
+ procedure Close (Stream : in out Stream_Type);
+
+private
+
+ use Ada.Streams;
+
+ type Buffer_Access is access all Stream_Element_Array;
+
+ type Stream_Type
+ is new Root_Stream_Type with
+ record
+ Mode : Stream_Mode;
+
+ Buffer : Buffer_Access;
+ Rest_First : Stream_Element_Offset;
+ Rest_Last : Stream_Element_Offset;
+ -- Buffer for Read operation.
+ -- We need to have this buffer in the record
+ -- because not all read data from back stream
+ -- could be processed during the read operation.
+
+ Buffer_Size : Stream_Element_Offset;
+ -- Buffer size for write operation.
+ -- We do not need to have this buffer
+ -- in the record because all data could be
+ -- processed in the write operation.
+
+ Back : Stream_Access;
+ Reader : Filter_Type;
+ Writer : Filter_Type;
+ end record;
+
+end ZLib.Streams;
diff --git a/xs/src/png/zlib/contrib/ada/zlib-thin.adb b/xs/src/png/zlib/contrib/ada/zlib-thin.adb
new file mode 100644
index 000000000..0ca4a7120
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/zlib-thin.adb
@@ -0,0 +1,141 @@
+----------------------------------------------------------------
+-- ZLib for Ada thick binding. --
+-- --
+-- Copyright (C) 2002-2003 Dmitriy Anisimkov --
+-- --
+-- Open source license information is in the zlib.ads file. --
+----------------------------------------------------------------
+
+-- $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $
+
+package body ZLib.Thin is
+
+ ZLIB_VERSION : constant Chars_Ptr := zlibVersion;
+
+ Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit;
+
+ --------------
+ -- Avail_In --
+ --------------
+
+ function Avail_In (Strm : in Z_Stream) return UInt is
+ begin
+ return Strm.Avail_In;
+ end Avail_In;
+
+ ---------------
+ -- Avail_Out --
+ ---------------
+
+ function Avail_Out (Strm : in Z_Stream) return UInt is
+ begin
+ return Strm.Avail_Out;
+ end Avail_Out;
+
+ ------------------
+ -- Deflate_Init --
+ ------------------
+
+ function Deflate_Init
+ (strm : Z_Streamp;
+ level : Int;
+ method : Int;
+ windowBits : Int;
+ memLevel : Int;
+ strategy : Int)
+ return Int is
+ begin
+ return deflateInit2
+ (strm,
+ level,
+ method,
+ windowBits,
+ memLevel,
+ strategy,
+ ZLIB_VERSION,
+ Z_Stream_Size);
+ end Deflate_Init;
+
+ ------------------
+ -- Inflate_Init --
+ ------------------
+
+ function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is
+ begin
+ return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size);
+ end Inflate_Init;
+
+ ------------------------
+ -- Last_Error_Message --
+ ------------------------
+
+ function Last_Error_Message (Strm : in Z_Stream) return String is
+ use Interfaces.C.Strings;
+ begin
+ if Strm.msg = Null_Ptr then
+ return "";
+ else
+ return Value (Strm.msg);
+ end if;
+ end Last_Error_Message;
+
+ ------------
+ -- Set_In --
+ ------------
+
+ procedure Set_In
+ (Strm : in out Z_Stream;
+ Buffer : in Voidp;
+ Size : in UInt) is
+ begin
+ Strm.Next_In := Buffer;
+ Strm.Avail_In := Size;
+ end Set_In;
+
+ ------------------
+ -- Set_Mem_Func --
+ ------------------
+
+ procedure Set_Mem_Func
+ (Strm : in out Z_Stream;
+ Opaque : in Voidp;
+ Alloc : in alloc_func;
+ Free : in free_func) is
+ begin
+ Strm.opaque := Opaque;
+ Strm.zalloc := Alloc;
+ Strm.zfree := Free;
+ end Set_Mem_Func;
+
+ -------------
+ -- Set_Out --
+ -------------
+
+ procedure Set_Out
+ (Strm : in out Z_Stream;
+ Buffer : in Voidp;
+ Size : in UInt) is
+ begin
+ Strm.Next_Out := Buffer;
+ Strm.Avail_Out := Size;
+ end Set_Out;
+
+ --------------
+ -- Total_In --
+ --------------
+
+ function Total_In (Strm : in Z_Stream) return ULong is
+ begin
+ return Strm.Total_In;
+ end Total_In;
+
+ ---------------
+ -- Total_Out --
+ ---------------
+
+ function Total_Out (Strm : in Z_Stream) return ULong is
+ begin
+ return Strm.Total_Out;
+ end Total_Out;
+
+end ZLib.Thin;
diff --git a/xs/src/png/zlib/contrib/ada/zlib-thin.ads b/xs/src/png/zlib/contrib/ada/zlib-thin.ads
new file mode 100644
index 000000000..810173cff
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/zlib-thin.ads
@@ -0,0 +1,450 @@
+----------------------------------------------------------------
+-- ZLib for Ada thick binding. --
+-- --
+-- Copyright (C) 2002-2003 Dmitriy Anisimkov --
+-- --
+-- Open source license information is in the zlib.ads file. --
+----------------------------------------------------------------
+
+-- $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $
+
+with Interfaces.C.Strings;
+
+with System;
+
+private package ZLib.Thin is
+
+ -- From zconf.h
+
+ MAX_MEM_LEVEL : constant := 9; -- zconf.h:105
+ -- zconf.h:105
+ MAX_WBITS : constant := 15; -- zconf.h:115
+ -- 32K LZ77 window
+ -- zconf.h:115
+ SEEK_SET : constant := 8#0000#; -- zconf.h:244
+ -- Seek from beginning of file.
+ -- zconf.h:244
+ SEEK_CUR : constant := 1; -- zconf.h:245
+ -- Seek from current position.
+ -- zconf.h:245
+ SEEK_END : constant := 2; -- zconf.h:246
+ -- Set file pointer to EOF plus "offset"
+ -- zconf.h:246
+
+ type Byte is new Interfaces.C.unsigned_char; -- 8 bits
+ -- zconf.h:214
+ type UInt is new Interfaces.C.unsigned; -- 16 bits or more
+ -- zconf.h:216
+ type Int is new Interfaces.C.int;
+
+ type ULong is new Interfaces.C.unsigned_long; -- 32 bits or more
+ -- zconf.h:217
+ subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr;
+
+ type ULong_Access is access ULong;
+ type Int_Access is access Int;
+
+ subtype Voidp is System.Address; -- zconf.h:232
+
+ subtype Byte_Access is Voidp;
+
+ Nul : constant Voidp := System.Null_Address;
+ -- end from zconf
+
+ Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125
+ -- zlib.h:125
+ Z_PARTIAL_FLUSH : constant := 1; -- zlib.h:126
+ -- will be removed, use
+ -- Z_SYNC_FLUSH instead
+ -- zlib.h:126
+ Z_SYNC_FLUSH : constant := 2; -- zlib.h:127
+ -- zlib.h:127
+ Z_FULL_FLUSH : constant := 3; -- zlib.h:128
+ -- zlib.h:128
+ Z_FINISH : constant := 4; -- zlib.h:129
+ -- zlib.h:129
+ Z_OK : constant := 8#0000#; -- zlib.h:132
+ -- zlib.h:132
+ Z_STREAM_END : constant := 1; -- zlib.h:133
+ -- zlib.h:133
+ Z_NEED_DICT : constant := 2; -- zlib.h:134
+ -- zlib.h:134
+ Z_ERRNO : constant := -1; -- zlib.h:135
+ -- zlib.h:135
+ Z_STREAM_ERROR : constant := -2; -- zlib.h:136
+ -- zlib.h:136
+ Z_DATA_ERROR : constant := -3; -- zlib.h:137
+ -- zlib.h:137
+ Z_MEM_ERROR : constant := -4; -- zlib.h:138
+ -- zlib.h:138
+ Z_BUF_ERROR : constant := -5; -- zlib.h:139
+ -- zlib.h:139
+ Z_VERSION_ERROR : constant := -6; -- zlib.h:140
+ -- zlib.h:140
+ Z_NO_COMPRESSION : constant := 8#0000#; -- zlib.h:145
+ -- zlib.h:145
+ Z_BEST_SPEED : constant := 1; -- zlib.h:146
+ -- zlib.h:146
+ Z_BEST_COMPRESSION : constant := 9; -- zlib.h:147
+ -- zlib.h:147
+ Z_DEFAULT_COMPRESSION : constant := -1; -- zlib.h:148
+ -- zlib.h:148
+ Z_FILTERED : constant := 1; -- zlib.h:151
+ -- zlib.h:151
+ Z_HUFFMAN_ONLY : constant := 2; -- zlib.h:152
+ -- zlib.h:152
+ Z_DEFAULT_STRATEGY : constant := 8#0000#; -- zlib.h:153
+ -- zlib.h:153
+ Z_BINARY : constant := 8#0000#; -- zlib.h:156
+ -- zlib.h:156
+ Z_ASCII : constant := 1; -- zlib.h:157
+ -- zlib.h:157
+ Z_UNKNOWN : constant := 2; -- zlib.h:158
+ -- zlib.h:158
+ Z_DEFLATED : constant := 8; -- zlib.h:161
+ -- zlib.h:161
+ Z_NULL : constant := 8#0000#; -- zlib.h:164
+ -- for initializing zalloc, zfree, opaque
+ -- zlib.h:164
+ type gzFile is new Voidp; -- zlib.h:646
+
+ type Z_Stream is private;
+
+ type Z_Streamp is access all Z_Stream; -- zlib.h:89
+
+ type alloc_func is access function
+ (Opaque : Voidp;
+ Items : UInt;
+ Size : UInt)
+ return Voidp; -- zlib.h:63
+
+ type free_func is access procedure (opaque : Voidp; address : Voidp);
+
+ function zlibVersion return Chars_Ptr;
+
+ function Deflate (strm : Z_Streamp; flush : Int) return Int;
+
+ function DeflateEnd (strm : Z_Streamp) return Int;
+
+ function Inflate (strm : Z_Streamp; flush : Int) return Int;
+
+ function InflateEnd (strm : Z_Streamp) return Int;
+
+ function deflateSetDictionary
+ (strm : Z_Streamp;
+ dictionary : Byte_Access;
+ dictLength : UInt)
+ return Int;
+
+ function deflateCopy (dest : Z_Streamp; source : Z_Streamp) return Int;
+ -- zlib.h:478
+
+ function deflateReset (strm : Z_Streamp) return Int; -- zlib.h:495
+
+ function deflateParams
+ (strm : Z_Streamp;
+ level : Int;
+ strategy : Int)
+ return Int; -- zlib.h:506
+
+ function inflateSetDictionary
+ (strm : Z_Streamp;
+ dictionary : Byte_Access;
+ dictLength : UInt)
+ return Int; -- zlib.h:548
+
+ function inflateSync (strm : Z_Streamp) return Int; -- zlib.h:565
+
+ function inflateReset (strm : Z_Streamp) return Int; -- zlib.h:580
+
+ function compress
+ (dest : Byte_Access;
+ destLen : ULong_Access;
+ source : Byte_Access;
+ sourceLen : ULong)
+ return Int; -- zlib.h:601
+
+ function compress2
+ (dest : Byte_Access;
+ destLen : ULong_Access;
+ source : Byte_Access;
+ sourceLen : ULong;
+ level : Int)
+ return Int; -- zlib.h:615
+
+ function uncompress
+ (dest : Byte_Access;
+ destLen : ULong_Access;
+ source : Byte_Access;
+ sourceLen : ULong)
+ return Int;
+
+ function gzopen (path : Chars_Ptr; mode : Chars_Ptr) return gzFile;
+
+ function gzdopen (fd : Int; mode : Chars_Ptr) return gzFile;
+
+ function gzsetparams
+ (file : gzFile;
+ level : Int;
+ strategy : Int)
+ return Int;
+
+ function gzread
+ (file : gzFile;
+ buf : Voidp;
+ len : UInt)
+ return Int;
+
+ function gzwrite
+ (file : in gzFile;
+ buf : in Voidp;
+ len : in UInt)
+ return Int;
+
+ function gzprintf (file : in gzFile; format : in Chars_Ptr) return Int;
+
+ function gzputs (file : in gzFile; s : in Chars_Ptr) return Int;
+
+ function gzgets
+ (file : gzFile;
+ buf : Chars_Ptr;
+ len : Int)
+ return Chars_Ptr;
+
+ function gzputc (file : gzFile; char : Int) return Int;
+
+ function gzgetc (file : gzFile) return Int;
+
+ function gzflush (file : gzFile; flush : Int) return Int;
+
+ function gzseek
+ (file : gzFile;
+ offset : Int;
+ whence : Int)
+ return Int;
+
+ function gzrewind (file : gzFile) return Int;
+
+ function gztell (file : gzFile) return Int;
+
+ function gzeof (file : gzFile) return Int;
+
+ function gzclose (file : gzFile) return Int;
+
+ function gzerror (file : gzFile; errnum : Int_Access) return Chars_Ptr;
+
+ function adler32
+ (adler : ULong;
+ buf : Byte_Access;
+ len : UInt)
+ return ULong;
+
+ function crc32
+ (crc : ULong;
+ buf : Byte_Access;
+ len : UInt)
+ return ULong;
+
+ function deflateInit
+ (strm : Z_Streamp;
+ level : Int;
+ version : Chars_Ptr;
+ stream_size : Int)
+ return Int;
+
+ function deflateInit2
+ (strm : Z_Streamp;
+ level : Int;
+ method : Int;
+ windowBits : Int;
+ memLevel : Int;
+ strategy : Int;
+ version : Chars_Ptr;
+ stream_size : Int)
+ return Int;
+
+ function Deflate_Init
+ (strm : Z_Streamp;
+ level : Int;
+ method : Int;
+ windowBits : Int;
+ memLevel : Int;
+ strategy : Int)
+ return Int;
+ pragma Inline (Deflate_Init);
+
+ function inflateInit
+ (strm : Z_Streamp;
+ version : Chars_Ptr;
+ stream_size : Int)
+ return Int;
+
+ function inflateInit2
+ (strm : in Z_Streamp;
+ windowBits : in Int;
+ version : in Chars_Ptr;
+ stream_size : in Int)
+ return Int;
+
+ function inflateBackInit
+ (strm : in Z_Streamp;
+ windowBits : in Int;
+ window : in Byte_Access;
+ version : in Chars_Ptr;
+ stream_size : in Int)
+ return Int;
+ -- Size of window have to be 2**windowBits.
+
+ function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int;
+ pragma Inline (Inflate_Init);
+
+ function zError (err : Int) return Chars_Ptr;
+
+ function inflateSyncPoint (z : Z_Streamp) return Int;
+
+ function get_crc_table return ULong_Access;
+
+ -- Interface to the available fields of the z_stream structure.
+ -- The application must update next_in and avail_in when avail_in has
+ -- dropped to zero. It must update next_out and avail_out when avail_out
+ -- has dropped to zero. The application must initialize zalloc, zfree and
+ -- opaque before calling the init function.
+
+ procedure Set_In
+ (Strm : in out Z_Stream;
+ Buffer : in Voidp;
+ Size : in UInt);
+ pragma Inline (Set_In);
+
+ procedure Set_Out
+ (Strm : in out Z_Stream;
+ Buffer : in Voidp;
+ Size : in UInt);
+ pragma Inline (Set_Out);
+
+ procedure Set_Mem_Func
+ (Strm : in out Z_Stream;
+ Opaque : in Voidp;
+ Alloc : in alloc_func;
+ Free : in free_func);
+ pragma Inline (Set_Mem_Func);
+
+ function Last_Error_Message (Strm : in Z_Stream) return String;
+ pragma Inline (Last_Error_Message);
+
+ function Avail_Out (Strm : in Z_Stream) return UInt;
+ pragma Inline (Avail_Out);
+
+ function Avail_In (Strm : in Z_Stream) return UInt;
+ pragma Inline (Avail_In);
+
+ function Total_In (Strm : in Z_Stream) return ULong;
+ pragma Inline (Total_In);
+
+ function Total_Out (Strm : in Z_Stream) return ULong;
+ pragma Inline (Total_Out);
+
+ function inflateCopy
+ (dest : in Z_Streamp;
+ Source : in Z_Streamp)
+ return Int;
+
+ function compressBound (Source_Len : in ULong) return ULong;
+
+ function deflateBound
+ (Strm : in Z_Streamp;
+ Source_Len : in ULong)
+ return ULong;
+
+ function gzungetc (C : in Int; File : in gzFile) return Int;
+
+ function zlibCompileFlags return ULong;
+
+private
+
+ type Z_Stream is record -- zlib.h:68
+ Next_In : Voidp := Nul; -- next input byte
+ Avail_In : UInt := 0; -- number of bytes available at next_in
+ Total_In : ULong := 0; -- total nb of input bytes read so far
+ Next_Out : Voidp := Nul; -- next output byte should be put there
+ Avail_Out : UInt := 0; -- remaining free space at next_out
+ Total_Out : ULong := 0; -- total nb of bytes output so far
+ msg : Chars_Ptr; -- last error message, NULL if no error
+ state : Voidp; -- not visible by applications
+ zalloc : alloc_func := null; -- used to allocate the internal state
+ zfree : free_func := null; -- used to free the internal state
+ opaque : Voidp; -- private data object passed to
+ -- zalloc and zfree
+ data_type : Int; -- best guess about the data type:
+ -- ascii or binary
+ adler : ULong; -- adler32 value of the uncompressed
+ -- data
+ reserved : ULong; -- reserved for future use
+ end record;
+
+ pragma Convention (C, Z_Stream);
+
+ pragma Import (C, zlibVersion, "zlibVersion");
+ pragma Import (C, Deflate, "deflate");
+ pragma Import (C, DeflateEnd, "deflateEnd");
+ pragma Import (C, Inflate, "inflate");
+ pragma Import (C, InflateEnd, "inflateEnd");
+ pragma Import (C, deflateSetDictionary, "deflateSetDictionary");
+ pragma Import (C, deflateCopy, "deflateCopy");
+ pragma Import (C, deflateReset, "deflateReset");
+ pragma Import (C, deflateParams, "deflateParams");
+ pragma Import (C, inflateSetDictionary, "inflateSetDictionary");
+ pragma Import (C, inflateSync, "inflateSync");
+ pragma Import (C, inflateReset, "inflateReset");
+ pragma Import (C, compress, "compress");
+ pragma Import (C, compress2, "compress2");
+ pragma Import (C, uncompress, "uncompress");
+ pragma Import (C, gzopen, "gzopen");
+ pragma Import (C, gzdopen, "gzdopen");
+ pragma Import (C, gzsetparams, "gzsetparams");
+ pragma Import (C, gzread, "gzread");
+ pragma Import (C, gzwrite, "gzwrite");
+ pragma Import (C, gzprintf, "gzprintf");
+ pragma Import (C, gzputs, "gzputs");
+ pragma Import (C, gzgets, "gzgets");
+ pragma Import (C, gzputc, "gzputc");
+ pragma Import (C, gzgetc, "gzgetc");
+ pragma Import (C, gzflush, "gzflush");
+ pragma Import (C, gzseek, "gzseek");
+ pragma Import (C, gzrewind, "gzrewind");
+ pragma Import (C, gztell, "gztell");
+ pragma Import (C, gzeof, "gzeof");
+ pragma Import (C, gzclose, "gzclose");
+ pragma Import (C, gzerror, "gzerror");
+ pragma Import (C, adler32, "adler32");
+ pragma Import (C, crc32, "crc32");
+ pragma Import (C, deflateInit, "deflateInit_");
+ pragma Import (C, inflateInit, "inflateInit_");
+ pragma Import (C, deflateInit2, "deflateInit2_");
+ pragma Import (C, inflateInit2, "inflateInit2_");
+ pragma Import (C, zError, "zError");
+ pragma Import (C, inflateSyncPoint, "inflateSyncPoint");
+ pragma Import (C, get_crc_table, "get_crc_table");
+
+ -- since zlib 1.2.0:
+
+ pragma Import (C, inflateCopy, "inflateCopy");
+ pragma Import (C, compressBound, "compressBound");
+ pragma Import (C, deflateBound, "deflateBound");
+ pragma Import (C, gzungetc, "gzungetc");
+ pragma Import (C, zlibCompileFlags, "zlibCompileFlags");
+
+ pragma Import (C, inflateBackInit, "inflateBackInit_");
+
+ -- I stopped binding the inflateBack routines, because realize that
+ -- it does not support zlib and gzip headers for now, and have no
+ -- symmetric deflateBack routines.
+ -- ZLib-Ada is symmetric regarding deflate/inflate data transformation
+ -- and has a similar generic callback interface for the
+ -- deflate/inflate transformation based on the regular Deflate/Inflate
+ -- routines.
+
+ -- pragma Import (C, inflateBack, "inflateBack");
+ -- pragma Import (C, inflateBackEnd, "inflateBackEnd");
+
+end ZLib.Thin;
diff --git a/xs/src/png/zlib/contrib/ada/zlib.adb b/xs/src/png/zlib/contrib/ada/zlib.adb
new file mode 100644
index 000000000..8b6fd686a
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/zlib.adb
@@ -0,0 +1,701 @@
+----------------------------------------------------------------
+-- ZLib for Ada thick binding. --
+-- --
+-- Copyright (C) 2002-2004 Dmitriy Anisimkov --
+-- --
+-- Open source license information is in the zlib.ads file. --
+----------------------------------------------------------------
+
+-- $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $
+
+with Ada.Exceptions;
+with Ada.Unchecked_Conversion;
+with Ada.Unchecked_Deallocation;
+
+with Interfaces.C.Strings;
+
+with ZLib.Thin;
+
+package body ZLib is
+
+ use type Thin.Int;
+
+ type Z_Stream is new Thin.Z_Stream;
+
+ type Return_Code_Enum is
+ (OK,
+ STREAM_END,
+ NEED_DICT,
+ ERRNO,
+ STREAM_ERROR,
+ DATA_ERROR,
+ MEM_ERROR,
+ BUF_ERROR,
+ VERSION_ERROR);
+
+ type Flate_Step_Function is access
+ function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int;
+ pragma Convention (C, Flate_Step_Function);
+
+ type Flate_End_Function is access
+ function (Ctrm : in Thin.Z_Streamp) return Thin.Int;
+ pragma Convention (C, Flate_End_Function);
+
+ type Flate_Type is record
+ Step : Flate_Step_Function;
+ Done : Flate_End_Function;
+ end record;
+
+ subtype Footer_Array is Stream_Element_Array (1 .. 8);
+
+ Simple_GZip_Header : constant Stream_Element_Array (1 .. 10)
+ := (16#1f#, 16#8b#, -- Magic header
+ 16#08#, -- Z_DEFLATED
+ 16#00#, -- Flags
+ 16#00#, 16#00#, 16#00#, 16#00#, -- Time
+ 16#00#, -- XFlags
+ 16#03# -- OS code
+ );
+ -- The simplest gzip header is not for informational, but just for
+ -- gzip format compatibility.
+ -- Note that some code below is using assumption
+ -- Simple_GZip_Header'Last > Footer_Array'Last, so do not make
+ -- Simple_GZip_Header'Last <= Footer_Array'Last.
+
+ Return_Code : constant array (Thin.Int range <>) of Return_Code_Enum
+ := (0 => OK,
+ 1 => STREAM_END,
+ 2 => NEED_DICT,
+ -1 => ERRNO,
+ -2 => STREAM_ERROR,
+ -3 => DATA_ERROR,
+ -4 => MEM_ERROR,
+ -5 => BUF_ERROR,
+ -6 => VERSION_ERROR);
+
+ Flate : constant array (Boolean) of Flate_Type
+ := (True => (Step => Thin.Deflate'Access,
+ Done => Thin.DeflateEnd'Access),
+ False => (Step => Thin.Inflate'Access,
+ Done => Thin.InflateEnd'Access));
+
+ Flush_Finish : constant array (Boolean) of Flush_Mode
+ := (True => Finish, False => No_Flush);
+
+ procedure Raise_Error (Stream : in Z_Stream);
+ pragma Inline (Raise_Error);
+
+ procedure Raise_Error (Message : in String);
+ pragma Inline (Raise_Error);
+
+ procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int);
+
+ procedure Free is new Ada.Unchecked_Deallocation
+ (Z_Stream, Z_Stream_Access);
+
+ function To_Thin_Access is new Ada.Unchecked_Conversion
+ (Z_Stream_Access, Thin.Z_Streamp);
+
+ procedure Translate_GZip
+ (Filter : in out Filter_Type;
+ In_Data : in Ada.Streams.Stream_Element_Array;
+ In_Last : out Ada.Streams.Stream_Element_Offset;
+ Out_Data : out Ada.Streams.Stream_Element_Array;
+ Out_Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode);
+ -- Separate translate routine for make gzip header.
+
+ procedure Translate_Auto
+ (Filter : in out Filter_Type;
+ In_Data : in Ada.Streams.Stream_Element_Array;
+ In_Last : out Ada.Streams.Stream_Element_Offset;
+ Out_Data : out Ada.Streams.Stream_Element_Array;
+ Out_Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode);
+ -- translate routine without additional headers.
+
+ -----------------
+ -- Check_Error --
+ -----------------
+
+ procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is
+ use type Thin.Int;
+ begin
+ if Code /= Thin.Z_OK then
+ Raise_Error
+ (Return_Code_Enum'Image (Return_Code (Code))
+ & ": " & Last_Error_Message (Stream));
+ end if;
+ end Check_Error;
+
+ -----------
+ -- Close --
+ -----------
+
+ procedure Close
+ (Filter : in out Filter_Type;
+ Ignore_Error : in Boolean := False)
+ is
+ Code : Thin.Int;
+ begin
+ if not Ignore_Error and then not Is_Open (Filter) then
+ raise Status_Error;
+ end if;
+
+ Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm));
+
+ if Ignore_Error or else Code = Thin.Z_OK then
+ Free (Filter.Strm);
+ else
+ declare
+ Error_Message : constant String
+ := Last_Error_Message (Filter.Strm.all);
+ begin
+ Free (Filter.Strm);
+ Ada.Exceptions.Raise_Exception
+ (ZLib_Error'Identity,
+ Return_Code_Enum'Image (Return_Code (Code))
+ & ": " & Error_Message);
+ end;
+ end if;
+ end Close;
+
+ -----------
+ -- CRC32 --
+ -----------
+
+ function CRC32
+ (CRC : in Unsigned_32;
+ Data : in Ada.Streams.Stream_Element_Array)
+ return Unsigned_32
+ is
+ use Thin;
+ begin
+ return Unsigned_32 (crc32 (ULong (CRC),
+ Data'Address,
+ Data'Length));
+ end CRC32;
+
+ procedure CRC32
+ (CRC : in out Unsigned_32;
+ Data : in Ada.Streams.Stream_Element_Array) is
+ begin
+ CRC := CRC32 (CRC, Data);
+ end CRC32;
+
+ ------------------
+ -- Deflate_Init --
+ ------------------
+
+ procedure Deflate_Init
+ (Filter : in out Filter_Type;
+ Level : in Compression_Level := Default_Compression;
+ Strategy : in Strategy_Type := Default_Strategy;
+ Method : in Compression_Method := Deflated;
+ Window_Bits : in Window_Bits_Type := Default_Window_Bits;
+ Memory_Level : in Memory_Level_Type := Default_Memory_Level;
+ Header : in Header_Type := Default)
+ is
+ use type Thin.Int;
+ Win_Bits : Thin.Int := Thin.Int (Window_Bits);
+ begin
+ if Is_Open (Filter) then
+ raise Status_Error;
+ end if;
+
+ -- We allow ZLib to make header only in case of default header type.
+ -- Otherwise we would either do header by ourselfs, or do not do
+ -- header at all.
+
+ if Header = None or else Header = GZip then
+ Win_Bits := -Win_Bits;
+ end if;
+
+ -- For the GZip CRC calculation and make headers.
+
+ if Header = GZip then
+ Filter.CRC := 0;
+ Filter.Offset := Simple_GZip_Header'First;
+ else
+ Filter.Offset := Simple_GZip_Header'Last + 1;
+ end if;
+
+ Filter.Strm := new Z_Stream;
+ Filter.Compression := True;
+ Filter.Stream_End := False;
+ Filter.Header := Header;
+
+ if Thin.Deflate_Init
+ (To_Thin_Access (Filter.Strm),
+ Level => Thin.Int (Level),
+ method => Thin.Int (Method),
+ windowBits => Win_Bits,
+ memLevel => Thin.Int (Memory_Level),
+ strategy => Thin.Int (Strategy)) /= Thin.Z_OK
+ then
+ Raise_Error (Filter.Strm.all);
+ end if;
+ end Deflate_Init;
+
+ -----------
+ -- Flush --
+ -----------
+
+ procedure Flush
+ (Filter : in out Filter_Type;
+ Out_Data : out Ada.Streams.Stream_Element_Array;
+ Out_Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode)
+ is
+ No_Data : Stream_Element_Array := (1 .. 0 => 0);
+ Last : Stream_Element_Offset;
+ begin
+ Translate (Filter, No_Data, Last, Out_Data, Out_Last, Flush);
+ end Flush;
+
+ -----------------------
+ -- Generic_Translate --
+ -----------------------
+
+ procedure Generic_Translate
+ (Filter : in out ZLib.Filter_Type;
+ In_Buffer_Size : in Integer := Default_Buffer_Size;
+ Out_Buffer_Size : in Integer := Default_Buffer_Size)
+ is
+ In_Buffer : Stream_Element_Array
+ (1 .. Stream_Element_Offset (In_Buffer_Size));
+ Out_Buffer : Stream_Element_Array
+ (1 .. Stream_Element_Offset (Out_Buffer_Size));
+ Last : Stream_Element_Offset;
+ In_Last : Stream_Element_Offset;
+ In_First : Stream_Element_Offset;
+ Out_Last : Stream_Element_Offset;
+ begin
+ Main : loop
+ Data_In (In_Buffer, Last);
+
+ In_First := In_Buffer'First;
+
+ loop
+ Translate
+ (Filter => Filter,
+ In_Data => In_Buffer (In_First .. Last),
+ In_Last => In_Last,
+ Out_Data => Out_Buffer,
+ Out_Last => Out_Last,
+ Flush => Flush_Finish (Last < In_Buffer'First));
+
+ if Out_Buffer'First <= Out_Last then
+ Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last));
+ end if;
+
+ exit Main when Stream_End (Filter);
+
+ -- The end of in buffer.
+
+ exit when In_Last = Last;
+
+ In_First := In_Last + 1;
+ end loop;
+ end loop Main;
+
+ end Generic_Translate;
+
+ ------------------
+ -- Inflate_Init --
+ ------------------
+
+ procedure Inflate_Init
+ (Filter : in out Filter_Type;
+ Window_Bits : in Window_Bits_Type := Default_Window_Bits;
+ Header : in Header_Type := Default)
+ is
+ use type Thin.Int;
+ Win_Bits : Thin.Int := Thin.Int (Window_Bits);
+
+ procedure Check_Version;
+ -- Check the latest header types compatibility.
+
+ procedure Check_Version is
+ begin
+ if Version <= "1.1.4" then
+ Raise_Error
+ ("Inflate header type " & Header_Type'Image (Header)
+ & " incompatible with ZLib version " & Version);
+ end if;
+ end Check_Version;
+
+ begin
+ if Is_Open (Filter) then
+ raise Status_Error;
+ end if;
+
+ case Header is
+ when None =>
+ Check_Version;
+
+ -- Inflate data without headers determined
+ -- by negative Win_Bits.
+
+ Win_Bits := -Win_Bits;
+ when GZip =>
+ Check_Version;
+
+ -- Inflate gzip data defined by flag 16.
+
+ Win_Bits := Win_Bits + 16;
+ when Auto =>
+ Check_Version;
+
+ -- Inflate with automatic detection
+ -- of gzip or native header defined by flag 32.
+
+ Win_Bits := Win_Bits + 32;
+ when Default => null;
+ end case;
+
+ Filter.Strm := new Z_Stream;
+ Filter.Compression := False;
+ Filter.Stream_End := False;
+ Filter.Header := Header;
+
+ if Thin.Inflate_Init
+ (To_Thin_Access (Filter.Strm), Win_Bits) /= Thin.Z_OK
+ then
+ Raise_Error (Filter.Strm.all);
+ end if;
+ end Inflate_Init;
+
+ -------------
+ -- Is_Open --
+ -------------
+
+ function Is_Open (Filter : in Filter_Type) return Boolean is
+ begin
+ return Filter.Strm /= null;
+ end Is_Open;
+
+ -----------------
+ -- Raise_Error --
+ -----------------
+
+ procedure Raise_Error (Message : in String) is
+ begin
+ Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message);
+ end Raise_Error;
+
+ procedure Raise_Error (Stream : in Z_Stream) is
+ begin
+ Raise_Error (Last_Error_Message (Stream));
+ end Raise_Error;
+
+ ----------
+ -- Read --
+ ----------
+
+ procedure Read
+ (Filter : in out Filter_Type;
+ Item : out Ada.Streams.Stream_Element_Array;
+ Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode := No_Flush)
+ is
+ In_Last : Stream_Element_Offset;
+ Item_First : Ada.Streams.Stream_Element_Offset := Item'First;
+ V_Flush : Flush_Mode := Flush;
+
+ begin
+ pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1);
+ pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last);
+
+ loop
+ if Rest_Last = Buffer'First - 1 then
+ V_Flush := Finish;
+
+ elsif Rest_First > Rest_Last then
+ Read (Buffer, Rest_Last);
+ Rest_First := Buffer'First;
+
+ if Rest_Last < Buffer'First then
+ V_Flush := Finish;
+ end if;
+ end if;
+
+ Translate
+ (Filter => Filter,
+ In_Data => Buffer (Rest_First .. Rest_Last),
+ In_Last => In_Last,
+ Out_Data => Item (Item_First .. Item'Last),
+ Out_Last => Last,
+ Flush => V_Flush);
+
+ Rest_First := In_Last + 1;
+
+ exit when Stream_End (Filter)
+ or else Last = Item'Last
+ or else (Last >= Item'First and then Allow_Read_Some);
+
+ Item_First := Last + 1;
+ end loop;
+ end Read;
+
+ ----------------
+ -- Stream_End --
+ ----------------
+
+ function Stream_End (Filter : in Filter_Type) return Boolean is
+ begin
+ if Filter.Header = GZip and Filter.Compression then
+ return Filter.Stream_End
+ and then Filter.Offset = Footer_Array'Last + 1;
+ else
+ return Filter.Stream_End;
+ end if;
+ end Stream_End;
+
+ --------------
+ -- Total_In --
+ --------------
+
+ function Total_In (Filter : in Filter_Type) return Count is
+ begin
+ return Count (Thin.Total_In (To_Thin_Access (Filter.Strm).all));
+ end Total_In;
+
+ ---------------
+ -- Total_Out --
+ ---------------
+
+ function Total_Out (Filter : in Filter_Type) return Count is
+ begin
+ return Count (Thin.Total_Out (To_Thin_Access (Filter.Strm).all));
+ end Total_Out;
+
+ ---------------
+ -- Translate --
+ ---------------
+
+ procedure Translate
+ (Filter : in out Filter_Type;
+ In_Data : in Ada.Streams.Stream_Element_Array;
+ In_Last : out Ada.Streams.Stream_Element_Offset;
+ Out_Data : out Ada.Streams.Stream_Element_Array;
+ Out_Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode) is
+ begin
+ if Filter.Header = GZip and then Filter.Compression then
+ Translate_GZip
+ (Filter => Filter,
+ In_Data => In_Data,
+ In_Last => In_Last,
+ Out_Data => Out_Data,
+ Out_Last => Out_Last,
+ Flush => Flush);
+ else
+ Translate_Auto
+ (Filter => Filter,
+ In_Data => In_Data,
+ In_Last => In_Last,
+ Out_Data => Out_Data,
+ Out_Last => Out_Last,
+ Flush => Flush);
+ end if;
+ end Translate;
+
+ --------------------
+ -- Translate_Auto --
+ --------------------
+
+ procedure Translate_Auto
+ (Filter : in out Filter_Type;
+ In_Data : in Ada.Streams.Stream_Element_Array;
+ In_Last : out Ada.Streams.Stream_Element_Offset;
+ Out_Data : out Ada.Streams.Stream_Element_Array;
+ Out_Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode)
+ is
+ use type Thin.Int;
+ Code : Thin.Int;
+
+ begin
+ if not Is_Open (Filter) then
+ raise Status_Error;
+ end if;
+
+ if Out_Data'Length = 0 and then In_Data'Length = 0 then
+ raise Constraint_Error;
+ end if;
+
+ Set_Out (Filter.Strm.all, Out_Data'Address, Out_Data'Length);
+ Set_In (Filter.Strm.all, In_Data'Address, In_Data'Length);
+
+ Code := Flate (Filter.Compression).Step
+ (To_Thin_Access (Filter.Strm),
+ Thin.Int (Flush));
+
+ if Code = Thin.Z_STREAM_END then
+ Filter.Stream_End := True;
+ else
+ Check_Error (Filter.Strm.all, Code);
+ end if;
+
+ In_Last := In_Data'Last
+ - Stream_Element_Offset (Avail_In (Filter.Strm.all));
+ Out_Last := Out_Data'Last
+ - Stream_Element_Offset (Avail_Out (Filter.Strm.all));
+ end Translate_Auto;
+
+ --------------------
+ -- Translate_GZip --
+ --------------------
+
+ procedure Translate_GZip
+ (Filter : in out Filter_Type;
+ In_Data : in Ada.Streams.Stream_Element_Array;
+ In_Last : out Ada.Streams.Stream_Element_Offset;
+ Out_Data : out Ada.Streams.Stream_Element_Array;
+ Out_Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode)
+ is
+ Out_First : Stream_Element_Offset;
+
+ procedure Add_Data (Data : in Stream_Element_Array);
+ -- Add data to stream from the Filter.Offset till necessary,
+ -- used for add gzip headr/footer.
+
+ procedure Put_32
+ (Item : in out Stream_Element_Array;
+ Data : in Unsigned_32);
+ pragma Inline (Put_32);
+
+ --------------
+ -- Add_Data --
+ --------------
+
+ procedure Add_Data (Data : in Stream_Element_Array) is
+ Data_First : Stream_Element_Offset renames Filter.Offset;
+ Data_Last : Stream_Element_Offset;
+ Data_Len : Stream_Element_Offset; -- -1
+ Out_Len : Stream_Element_Offset; -- -1
+ begin
+ Out_First := Out_Last + 1;
+
+ if Data_First > Data'Last then
+ return;
+ end if;
+
+ Data_Len := Data'Last - Data_First;
+ Out_Len := Out_Data'Last - Out_First;
+
+ if Data_Len <= Out_Len then
+ Out_Last := Out_First + Data_Len;
+ Data_Last := Data'Last;
+ else
+ Out_Last := Out_Data'Last;
+ Data_Last := Data_First + Out_Len;
+ end if;
+
+ Out_Data (Out_First .. Out_Last) := Data (Data_First .. Data_Last);
+
+ Data_First := Data_Last + 1;
+ Out_First := Out_Last + 1;
+ end Add_Data;
+
+ ------------
+ -- Put_32 --
+ ------------
+
+ procedure Put_32
+ (Item : in out Stream_Element_Array;
+ Data : in Unsigned_32)
+ is
+ D : Unsigned_32 := Data;
+ begin
+ for J in Item'First .. Item'First + 3 loop
+ Item (J) := Stream_Element (D and 16#FF#);
+ D := Shift_Right (D, 8);
+ end loop;
+ end Put_32;
+
+ begin
+ Out_Last := Out_Data'First - 1;
+
+ if not Filter.Stream_End then
+ Add_Data (Simple_GZip_Header);
+
+ Translate_Auto
+ (Filter => Filter,
+ In_Data => In_Data,
+ In_Last => In_Last,
+ Out_Data => Out_Data (Out_First .. Out_Data'Last),
+ Out_Last => Out_Last,
+ Flush => Flush);
+
+ CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last));
+ end if;
+
+ if Filter.Stream_End and then Out_Last <= Out_Data'Last then
+ -- This detection method would work only when
+ -- Simple_GZip_Header'Last > Footer_Array'Last
+
+ if Filter.Offset = Simple_GZip_Header'Last + 1 then
+ Filter.Offset := Footer_Array'First;
+ end if;
+
+ declare
+ Footer : Footer_Array;
+ begin
+ Put_32 (Footer, Filter.CRC);
+ Put_32 (Footer (Footer'First + 4 .. Footer'Last),
+ Unsigned_32 (Total_In (Filter)));
+ Add_Data (Footer);
+ end;
+ end if;
+ end Translate_GZip;
+
+ -------------
+ -- Version --
+ -------------
+
+ function Version return String is
+ begin
+ return Interfaces.C.Strings.Value (Thin.zlibVersion);
+ end Version;
+
+ -----------
+ -- Write --
+ -----------
+
+ procedure Write
+ (Filter : in out Filter_Type;
+ Item : in Ada.Streams.Stream_Element_Array;
+ Flush : in Flush_Mode := No_Flush)
+ is
+ Buffer : Stream_Element_Array (1 .. Buffer_Size);
+ In_Last : Stream_Element_Offset;
+ Out_Last : Stream_Element_Offset;
+ In_First : Stream_Element_Offset := Item'First;
+ begin
+ if Item'Length = 0 and Flush = No_Flush then
+ return;
+ end if;
+
+ loop
+ Translate
+ (Filter => Filter,
+ In_Data => Item (In_First .. Item'Last),
+ In_Last => In_Last,
+ Out_Data => Buffer,
+ Out_Last => Out_Last,
+ Flush => Flush);
+
+ if Out_Last >= Buffer'First then
+ Write (Buffer (1 .. Out_Last));
+ end if;
+
+ exit when In_Last = Item'Last or Stream_End (Filter);
+
+ In_First := In_Last + 1;
+ end loop;
+ end Write;
+
+end ZLib;
diff --git a/xs/src/png/zlib/contrib/ada/zlib.ads b/xs/src/png/zlib/contrib/ada/zlib.ads
new file mode 100644
index 000000000..79ffc4095
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/zlib.ads
@@ -0,0 +1,328 @@
+------------------------------------------------------------------------------
+-- ZLib for Ada thick binding. --
+-- --
+-- Copyright (C) 2002-2004 Dmitriy Anisimkov --
+-- --
+-- This library 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 library 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 library; if not, write to the Free Software Foundation, --
+-- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --
+-- --
+-- As a special exception, if other files instantiate generics from this --
+-- unit, or you link this unit with other files to produce an executable, --
+-- this unit does not by itself cause the resulting executable to be --
+-- covered by the GNU General Public License. This exception does not --
+-- however invalidate any other reasons why the executable file might be --
+-- covered by the GNU Public License. --
+------------------------------------------------------------------------------
+
+-- $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $
+
+with Ada.Streams;
+
+with Interfaces;
+
+package ZLib is
+
+ ZLib_Error : exception;
+ Status_Error : exception;
+
+ type Compression_Level is new Integer range -1 .. 9;
+
+ type Flush_Mode is private;
+
+ type Compression_Method is private;
+
+ type Window_Bits_Type is new Integer range 8 .. 15;
+
+ type Memory_Level_Type is new Integer range 1 .. 9;
+
+ type Unsigned_32 is new Interfaces.Unsigned_32;
+
+ type Strategy_Type is private;
+
+ type Header_Type is (None, Auto, Default, GZip);
+ -- Header type usage have a some limitation for inflate.
+ -- See comment for Inflate_Init.
+
+ subtype Count is Ada.Streams.Stream_Element_Count;
+
+ Default_Memory_Level : constant Memory_Level_Type := 8;
+ Default_Window_Bits : constant Window_Bits_Type := 15;
+
+ ----------------------------------
+ -- Compression method constants --
+ ----------------------------------
+
+ Deflated : constant Compression_Method;
+ -- Only one method allowed in this ZLib version
+
+ ---------------------------------
+ -- Compression level constants --
+ ---------------------------------
+
+ No_Compression : constant Compression_Level := 0;
+ Best_Speed : constant Compression_Level := 1;
+ Best_Compression : constant Compression_Level := 9;
+ Default_Compression : constant Compression_Level := -1;
+
+ --------------------------
+ -- Flush mode constants --
+ --------------------------
+
+ No_Flush : constant Flush_Mode;
+ -- Regular way for compression, no flush
+
+ Partial_Flush : constant Flush_Mode;
+ -- Will be removed, use Z_SYNC_FLUSH instead
+
+ Sync_Flush : constant Flush_Mode;
+ -- All pending output is flushed to the output buffer and the output
+ -- is aligned on a byte boundary, so that the decompressor can get all
+ -- input data available so far. (In particular avail_in is zero after the
+ -- call if enough output space has been provided before the call.)
+ -- Flushing may degrade compression for some compression algorithms and so
+ -- it should be used only when necessary.
+
+ Block_Flush : constant Flush_Mode;
+ -- Z_BLOCK requests that inflate() stop
+ -- if and when it get to the next deflate block boundary. When decoding the
+ -- zlib or gzip format, this will cause inflate() to return immediately
+ -- after the header and before the first block. When doing a raw inflate,
+ -- inflate() will go ahead and process the first block, and will return
+ -- when it gets to the end of that block, or when it runs out of data.
+
+ Full_Flush : constant Flush_Mode;
+ -- All output is flushed as with SYNC_FLUSH, and the compression state
+ -- is reset so that decompression can restart from this point if previous
+ -- compressed data has been damaged or if random access is desired. Using
+ -- Full_Flush too often can seriously degrade the compression.
+
+ Finish : constant Flush_Mode;
+ -- Just for tell the compressor that input data is complete.
+
+ ------------------------------------
+ -- Compression strategy constants --
+ ------------------------------------
+
+ -- RLE stategy could be used only in version 1.2.0 and later.
+
+ Filtered : constant Strategy_Type;
+ Huffman_Only : constant Strategy_Type;
+ RLE : constant Strategy_Type;
+ Default_Strategy : constant Strategy_Type;
+
+ Default_Buffer_Size : constant := 4096;
+
+ type Filter_Type is tagged limited private;
+ -- The filter is for compression and for decompression.
+ -- The usage of the type is depend of its initialization.
+
+ function Version return String;
+ pragma Inline (Version);
+ -- Return string representation of the ZLib version.
+
+ procedure Deflate_Init
+ (Filter : in out Filter_Type;
+ Level : in Compression_Level := Default_Compression;
+ Strategy : in Strategy_Type := Default_Strategy;
+ Method : in Compression_Method := Deflated;
+ Window_Bits : in Window_Bits_Type := Default_Window_Bits;
+ Memory_Level : in Memory_Level_Type := Default_Memory_Level;
+ Header : in Header_Type := Default);
+ -- Compressor initialization.
+ -- When Header parameter is Auto or Default, then default zlib header
+ -- would be provided for compressed data.
+ -- When Header is GZip, then gzip header would be set instead of
+ -- default header.
+ -- When Header is None, no header would be set for compressed data.
+
+ procedure Inflate_Init
+ (Filter : in out Filter_Type;
+ Window_Bits : in Window_Bits_Type := Default_Window_Bits;
+ Header : in Header_Type := Default);
+ -- Decompressor initialization.
+ -- Default header type mean that ZLib default header is expecting in the
+ -- input compressed stream.
+ -- Header type None mean that no header is expecting in the input stream.
+ -- GZip header type mean that GZip header is expecting in the
+ -- input compressed stream.
+ -- Auto header type mean that header type (GZip or Native) would be
+ -- detected automatically in the input stream.
+ -- Note that header types parameter values None, GZip and Auto are
+ -- supported for inflate routine only in ZLib versions 1.2.0.2 and later.
+ -- Deflate_Init is supporting all header types.
+
+ function Is_Open (Filter : in Filter_Type) return Boolean;
+ pragma Inline (Is_Open);
+ -- Is the filter opened for compression or decompression.
+
+ procedure Close
+ (Filter : in out Filter_Type;
+ Ignore_Error : in Boolean := False);
+ -- Closing the compression or decompressor.
+ -- If stream is closing before the complete and Ignore_Error is False,
+ -- The exception would be raised.
+
+ generic
+ with procedure Data_In
+ (Item : out Ada.Streams.Stream_Element_Array;
+ Last : out Ada.Streams.Stream_Element_Offset);
+ with procedure Data_Out
+ (Item : in Ada.Streams.Stream_Element_Array);
+ procedure Generic_Translate
+ (Filter : in out Filter_Type;
+ In_Buffer_Size : in Integer := Default_Buffer_Size;
+ Out_Buffer_Size : in Integer := Default_Buffer_Size);
+ -- Compress/decompress data fetch from Data_In routine and pass the result
+ -- to the Data_Out routine. User should provide Data_In and Data_Out
+ -- for compression/decompression data flow.
+ -- Compression or decompression depend on Filter initialization.
+
+ function Total_In (Filter : in Filter_Type) return Count;
+ pragma Inline (Total_In);
+ -- Returns total number of input bytes read so far
+
+ function Total_Out (Filter : in Filter_Type) return Count;
+ pragma Inline (Total_Out);
+ -- Returns total number of bytes output so far
+
+ function CRC32
+ (CRC : in Unsigned_32;
+ Data : in Ada.Streams.Stream_Element_Array)
+ return Unsigned_32;
+ pragma Inline (CRC32);
+ -- Compute CRC32, it could be necessary for make gzip format
+
+ procedure CRC32
+ (CRC : in out Unsigned_32;
+ Data : in Ada.Streams.Stream_Element_Array);
+ pragma Inline (CRC32);
+ -- Compute CRC32, it could be necessary for make gzip format
+
+ -------------------------------------------------
+ -- Below is more complex low level routines. --
+ -------------------------------------------------
+
+ procedure Translate
+ (Filter : in out Filter_Type;
+ In_Data : in Ada.Streams.Stream_Element_Array;
+ In_Last : out Ada.Streams.Stream_Element_Offset;
+ Out_Data : out Ada.Streams.Stream_Element_Array;
+ Out_Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode);
+ -- Compress/decompress the In_Data buffer and place the result into
+ -- Out_Data. In_Last is the index of last element from In_Data accepted by
+ -- the Filter. Out_Last is the last element of the received data from
+ -- Filter. To tell the filter that incoming data are complete put the
+ -- Flush parameter to Finish.
+
+ function Stream_End (Filter : in Filter_Type) return Boolean;
+ pragma Inline (Stream_End);
+ -- Return the true when the stream is complete.
+
+ procedure Flush
+ (Filter : in out Filter_Type;
+ Out_Data : out Ada.Streams.Stream_Element_Array;
+ Out_Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode);
+ pragma Inline (Flush);
+ -- Flushing the data from the compressor.
+
+ generic
+ with procedure Write
+ (Item : in Ada.Streams.Stream_Element_Array);
+ -- User should provide this routine for accept
+ -- compressed/decompressed data.
+
+ Buffer_Size : in Ada.Streams.Stream_Element_Offset
+ := Default_Buffer_Size;
+ -- Buffer size for Write user routine.
+
+ procedure Write
+ (Filter : in out Filter_Type;
+ Item : in Ada.Streams.Stream_Element_Array;
+ Flush : in Flush_Mode := No_Flush);
+ -- Compress/Decompress data from Item to the generic parameter procedure
+ -- Write. Output buffer size could be set in Buffer_Size generic parameter.
+
+ generic
+ with procedure Read
+ (Item : out Ada.Streams.Stream_Element_Array;
+ Last : out Ada.Streams.Stream_Element_Offset);
+ -- User should provide data for compression/decompression
+ -- thru this routine.
+
+ Buffer : in out Ada.Streams.Stream_Element_Array;
+ -- Buffer for keep remaining data from the previous
+ -- back read.
+
+ Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset;
+ -- Rest_First have to be initialized to Buffer'Last + 1
+ -- Rest_Last have to be initialized to Buffer'Last
+ -- before usage.
+
+ Allow_Read_Some : in Boolean := False;
+ -- Is it allowed to return Last < Item'Last before end of data.
+
+ procedure Read
+ (Filter : in out Filter_Type;
+ Item : out Ada.Streams.Stream_Element_Array;
+ Last : out Ada.Streams.Stream_Element_Offset;
+ Flush : in Flush_Mode := No_Flush);
+ -- Compress/Decompress data from generic parameter procedure Read to the
+ -- Item. User should provide Buffer and initialized Rest_First, Rest_Last
+ -- indicators. If Allow_Read_Some is True, Read routines could return
+ -- Last < Item'Last only at end of stream.
+
+private
+
+ use Ada.Streams;
+
+ pragma Assert (Ada.Streams.Stream_Element'Size = 8);
+ pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8);
+
+ type Flush_Mode is new Integer range 0 .. 5;
+
+ type Compression_Method is new Integer range 8 .. 8;
+
+ type Strategy_Type is new Integer range 0 .. 3;
+
+ No_Flush : constant Flush_Mode := 0;
+ Partial_Flush : constant Flush_Mode := 1;
+ Sync_Flush : constant Flush_Mode := 2;
+ Full_Flush : constant Flush_Mode := 3;
+ Finish : constant Flush_Mode := 4;
+ Block_Flush : constant Flush_Mode := 5;
+
+ Filtered : constant Strategy_Type := 1;
+ Huffman_Only : constant Strategy_Type := 2;
+ RLE : constant Strategy_Type := 3;
+ Default_Strategy : constant Strategy_Type := 0;
+
+ Deflated : constant Compression_Method := 8;
+
+ type Z_Stream;
+
+ type Z_Stream_Access is access all Z_Stream;
+
+ type Filter_Type is tagged limited record
+ Strm : Z_Stream_Access;
+ Compression : Boolean;
+ Stream_End : Boolean;
+ Header : Header_Type;
+ CRC : Unsigned_32;
+ Offset : Stream_Element_Offset;
+ -- Offset for gzip header/footer output.
+ end record;
+
+end ZLib;
diff --git a/xs/src/png/zlib/contrib/ada/zlib.gpr b/xs/src/png/zlib/contrib/ada/zlib.gpr
new file mode 100644
index 000000000..296b22aa9
--- /dev/null
+++ b/xs/src/png/zlib/contrib/ada/zlib.gpr
@@ -0,0 +1,20 @@
+project Zlib is
+
+ for Languages use ("Ada");
+ for Source_Dirs use (".");
+ for Object_Dir use ".";
+ for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo");
+
+ package Compiler is
+ for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst");
+ end Compiler;
+
+ package Linker is
+ for Default_Switches ("ada") use ("-lz");
+ end Linker;
+
+ package Builder is
+ for Default_Switches ("ada") use ("-s", "-gnatQ");
+ end Builder;
+
+end Zlib;
diff --git a/xs/src/png/zlib/contrib/amd64/amd64-match.S b/xs/src/png/zlib/contrib/amd64/amd64-match.S
new file mode 100644
index 000000000..81d4a1c94
--- /dev/null
+++ b/xs/src/png/zlib/contrib/amd64/amd64-match.S
@@ -0,0 +1,452 @@
+/*
+ * match.S -- optimized version of longest_match()
+ * based on the similar work by Gilles Vollant, and Brian Raiter, written 1998
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the BSD License. Use by owners of Che Guevarra
+ * parafernalia is prohibited, where possible, and highly discouraged
+ * elsewhere.
+ */
+
+#ifndef NO_UNDERLINE
+# define match_init _match_init
+# define longest_match _longest_match
+#endif
+
+#define scanend ebx
+#define scanendw bx
+#define chainlenwmask edx /* high word: current chain len low word: s->wmask */
+#define curmatch rsi
+#define curmatchd esi
+#define windowbestlen r8
+#define scanalign r9
+#define scanalignd r9d
+#define window r10
+#define bestlen r11
+#define bestlend r11d
+#define scanstart r12d
+#define scanstartw r12w
+#define scan r13
+#define nicematch r14d
+#define limit r15
+#define limitd r15d
+#define prev rcx
+
+/*
+ * The 258 is a "magic number, not a parameter -- changing it
+ * breaks the hell loose
+ */
+#define MAX_MATCH (258)
+#define MIN_MATCH (3)
+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
+
+/* stack frame offsets */
+#define LocalVarsSize (112)
+#define _chainlenwmask ( 8-LocalVarsSize)(%rsp)
+#define _windowbestlen (16-LocalVarsSize)(%rsp)
+#define save_r14 (24-LocalVarsSize)(%rsp)
+#define save_rsi (32-LocalVarsSize)(%rsp)
+#define save_rbx (40-LocalVarsSize)(%rsp)
+#define save_r12 (56-LocalVarsSize)(%rsp)
+#define save_r13 (64-LocalVarsSize)(%rsp)
+#define save_r15 (80-LocalVarsSize)(%rsp)
+
+
+.globl match_init, longest_match
+
+/*
+ * On AMD64 the first argument of a function (in our case -- the pointer to
+ * deflate_state structure) is passed in %rdi, hence our offsets below are
+ * all off of that.
+ */
+
+/* you can check the structure offset by running
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "deflate.h"
+
+void print_depl()
+{
+deflate_state ds;
+deflate_state *s=&ds;
+printf("size pointer=%u\n",(int)sizeof(void*));
+
+printf("#define dsWSize (%3u)(%%rdi)\n",(int)(((char*)&(s->w_size))-((char*)s)));
+printf("#define dsWMask (%3u)(%%rdi)\n",(int)(((char*)&(s->w_mask))-((char*)s)));
+printf("#define dsWindow (%3u)(%%rdi)\n",(int)(((char*)&(s->window))-((char*)s)));
+printf("#define dsPrev (%3u)(%%rdi)\n",(int)(((char*)&(s->prev))-((char*)s)));
+printf("#define dsMatchLen (%3u)(%%rdi)\n",(int)(((char*)&(s->match_length))-((char*)s)));
+printf("#define dsPrevMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_match))-((char*)s)));
+printf("#define dsStrStart (%3u)(%%rdi)\n",(int)(((char*)&(s->strstart))-((char*)s)));
+printf("#define dsMatchStart (%3u)(%%rdi)\n",(int)(((char*)&(s->match_start))-((char*)s)));
+printf("#define dsLookahead (%3u)(%%rdi)\n",(int)(((char*)&(s->lookahead))-((char*)s)));
+printf("#define dsPrevLen (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_length))-((char*)s)));
+printf("#define dsMaxChainLen (%3u)(%%rdi)\n",(int)(((char*)&(s->max_chain_length))-((char*)s)));
+printf("#define dsGoodMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->good_match))-((char*)s)));
+printf("#define dsNiceMatch (%3u)(%%rdi)\n",(int)(((char*)&(s->nice_match))-((char*)s)));
+}
+
+*/
+
+
+/*
+ to compile for XCode 3.2 on MacOSX x86_64
+ - run "gcc -g -c -DXCODE_MAC_X64_STRUCTURE amd64-match.S"
+ */
+
+
+#ifndef CURRENT_LINX_XCODE_MAC_X64_STRUCTURE
+#define dsWSize ( 68)(%rdi)
+#define dsWMask ( 76)(%rdi)
+#define dsWindow ( 80)(%rdi)
+#define dsPrev ( 96)(%rdi)
+#define dsMatchLen (144)(%rdi)
+#define dsPrevMatch (148)(%rdi)
+#define dsStrStart (156)(%rdi)
+#define dsMatchStart (160)(%rdi)
+#define dsLookahead (164)(%rdi)
+#define dsPrevLen (168)(%rdi)
+#define dsMaxChainLen (172)(%rdi)
+#define dsGoodMatch (188)(%rdi)
+#define dsNiceMatch (192)(%rdi)
+
+#else
+
+#ifndef STRUCT_OFFSET
+# define STRUCT_OFFSET (0)
+#endif
+
+
+#define dsWSize ( 56 + STRUCT_OFFSET)(%rdi)
+#define dsWMask ( 64 + STRUCT_OFFSET)(%rdi)
+#define dsWindow ( 72 + STRUCT_OFFSET)(%rdi)
+#define dsPrev ( 88 + STRUCT_OFFSET)(%rdi)
+#define dsMatchLen (136 + STRUCT_OFFSET)(%rdi)
+#define dsPrevMatch (140 + STRUCT_OFFSET)(%rdi)
+#define dsStrStart (148 + STRUCT_OFFSET)(%rdi)
+#define dsMatchStart (152 + STRUCT_OFFSET)(%rdi)
+#define dsLookahead (156 + STRUCT_OFFSET)(%rdi)
+#define dsPrevLen (160 + STRUCT_OFFSET)(%rdi)
+#define dsMaxChainLen (164 + STRUCT_OFFSET)(%rdi)
+#define dsGoodMatch (180 + STRUCT_OFFSET)(%rdi)
+#define dsNiceMatch (184 + STRUCT_OFFSET)(%rdi)
+
+#endif
+
+
+
+
+.text
+
+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
+
+longest_match:
+/*
+ * Retrieve the function arguments. %curmatch will hold cur_match
+ * throughout the entire function (passed via rsi on amd64).
+ * rdi will hold the pointer to the deflate_state (first arg on amd64)
+ */
+ mov %rsi, save_rsi
+ mov %rbx, save_rbx
+ mov %r12, save_r12
+ mov %r13, save_r13
+ mov %r14, save_r14
+ mov %r15, save_r15
+
+/* uInt wmask = s->w_mask; */
+/* unsigned chain_length = s->max_chain_length; */
+/* if (s->prev_length >= s->good_match) { */
+/* chain_length >>= 2; */
+/* } */
+
+ movl dsPrevLen, %eax
+ movl dsGoodMatch, %ebx
+ cmpl %ebx, %eax
+ movl dsWMask, %eax
+ movl dsMaxChainLen, %chainlenwmask
+ jl LastMatchGood
+ shrl $2, %chainlenwmask
+LastMatchGood:
+
+/* chainlen is decremented once beforehand so that the function can */
+/* use the sign flag instead of the zero flag for the exit test. */
+/* It is then shifted into the high word, to make room for the wmask */
+/* value, which it will always accompany. */
+
+ decl %chainlenwmask
+ shll $16, %chainlenwmask
+ orl %eax, %chainlenwmask
+
+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
+
+ movl dsNiceMatch, %eax
+ movl dsLookahead, %ebx
+ cmpl %eax, %ebx
+ jl LookaheadLess
+ movl %eax, %ebx
+LookaheadLess: movl %ebx, %nicematch
+
+/* register Bytef *scan = s->window + s->strstart; */
+
+ mov dsWindow, %window
+ movl dsStrStart, %limitd
+ lea (%limit, %window), %scan
+
+/* Determine how many bytes the scan ptr is off from being */
+/* dword-aligned. */
+
+ mov %scan, %scanalign
+ negl %scanalignd
+ andl $3, %scanalignd
+
+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
+
+ movl dsWSize, %eax
+ subl $MIN_LOOKAHEAD, %eax
+ xorl %ecx, %ecx
+ subl %eax, %limitd
+ cmovng %ecx, %limitd
+
+/* int best_len = s->prev_length; */
+
+ movl dsPrevLen, %bestlend
+
+/* Store the sum of s->window + best_len in %windowbestlen locally, and in memory. */
+
+ lea (%window, %bestlen), %windowbestlen
+ mov %windowbestlen, _windowbestlen
+
+/* register ush scan_start = *(ushf*)scan; */
+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
+/* Posf *prev = s->prev; */
+
+ movzwl (%scan), %scanstart
+ movzwl -1(%scan, %bestlen), %scanend
+ mov dsPrev, %prev
+
+/* Jump into the main loop. */
+
+ movl %chainlenwmask, _chainlenwmask
+ jmp LoopEntry
+
+.balign 16
+
+/* do {
+ * match = s->window + cur_match;
+ * if (*(ushf*)(match+best_len-1) != scan_end ||
+ * *(ushf*)match != scan_start) continue;
+ * [...]
+ * } while ((cur_match = prev[cur_match & wmask]) > limit
+ * && --chain_length != 0);
+ *
+ * Here is the inner loop of the function. The function will spend the
+ * majority of its time in this loop, and majority of that time will
+ * be spent in the first ten instructions.
+ */
+LookupLoop:
+ andl %chainlenwmask, %curmatchd
+ movzwl (%prev, %curmatch, 2), %curmatchd
+ cmpl %limitd, %curmatchd
+ jbe LeaveNow
+ subl $0x00010000, %chainlenwmask
+ js LeaveNow
+LoopEntry: cmpw -1(%windowbestlen, %curmatch), %scanendw
+ jne LookupLoop
+ cmpw %scanstartw, (%window, %curmatch)
+ jne LookupLoop
+
+/* Store the current value of chainlen. */
+ movl %chainlenwmask, _chainlenwmask
+
+/* %scan is the string under scrutiny, and %prev to the string we */
+/* are hoping to match it up with. In actuality, %esi and %edi are */
+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
+/* initialized to -(MAX_MATCH_8 - scanalign). */
+
+ mov $(-MAX_MATCH_8), %rdx
+ lea (%curmatch, %window), %windowbestlen
+ lea MAX_MATCH_8(%windowbestlen, %scanalign), %windowbestlen
+ lea MAX_MATCH_8(%scan, %scanalign), %prev
+
+/* the prefetching below makes very little difference... */
+ prefetcht1 (%windowbestlen, %rdx)
+ prefetcht1 (%prev, %rdx)
+
+/*
+ * Test the strings for equality, 8 bytes at a time. At the end,
+ * adjust %rdx so that it is offset to the exact byte that mismatched.
+ *
+ * It should be confessed that this loop usually does not represent
+ * much of the total running time. Replacing it with a more
+ * straightforward "rep cmpsb" would not drastically degrade
+ * performance -- unrolling it, for example, makes no difference.
+ */
+
+#undef USE_SSE /* works, but is 6-7% slower, than non-SSE... */
+
+LoopCmps:
+#ifdef USE_SSE
+ /* Preload the SSE registers */
+ movdqu (%windowbestlen, %rdx), %xmm1
+ movdqu (%prev, %rdx), %xmm2
+ pcmpeqb %xmm2, %xmm1
+ movdqu 16(%windowbestlen, %rdx), %xmm3
+ movdqu 16(%prev, %rdx), %xmm4
+ pcmpeqb %xmm4, %xmm3
+ movdqu 32(%windowbestlen, %rdx), %xmm5
+ movdqu 32(%prev, %rdx), %xmm6
+ pcmpeqb %xmm6, %xmm5
+ movdqu 48(%windowbestlen, %rdx), %xmm7
+ movdqu 48(%prev, %rdx), %xmm8
+ pcmpeqb %xmm8, %xmm7
+
+ /* Check the comparisions' results */
+ pmovmskb %xmm1, %rax
+ notw %ax
+ bsfw %ax, %ax
+ jnz LeaveLoopCmps
+
+ /* this is the only iteration of the loop with a possibility of having
+ incremented rdx by 0x108 (each loop iteration add 16*4 = 0x40
+ and (0x40*4)+8=0x108 */
+ add $8, %rdx
+ jz LenMaximum
+ add $8, %rdx
+
+
+ pmovmskb %xmm3, %rax
+ notw %ax
+ bsfw %ax, %ax
+ jnz LeaveLoopCmps
+
+
+ add $16, %rdx
+
+
+ pmovmskb %xmm5, %rax
+ notw %ax
+ bsfw %ax, %ax
+ jnz LeaveLoopCmps
+
+ add $16, %rdx
+
+
+ pmovmskb %xmm7, %rax
+ notw %ax
+ bsfw %ax, %ax
+ jnz LeaveLoopCmps
+
+ add $16, %rdx
+
+ jmp LoopCmps
+LeaveLoopCmps: add %rax, %rdx
+#else
+ mov (%windowbestlen, %rdx), %rax
+ xor (%prev, %rdx), %rax
+ jnz LeaveLoopCmps
+
+ mov 8(%windowbestlen, %rdx), %rax
+ xor 8(%prev, %rdx), %rax
+ jnz LeaveLoopCmps8
+
+ mov 16(%windowbestlen, %rdx), %rax
+ xor 16(%prev, %rdx), %rax
+ jnz LeaveLoopCmps16
+
+ add $24, %rdx
+ jnz LoopCmps
+ jmp LenMaximum
+# if 0
+/*
+ * This three-liner is tantalizingly simple, but bsf is a slow instruction,
+ * and the complicated alternative down below is quite a bit faster. Sad...
+ */
+
+LeaveLoopCmps: bsf %rax, %rax /* find the first non-zero bit */
+ shrl $3, %eax /* divide by 8 to get the byte */
+ add %rax, %rdx
+# else
+LeaveLoopCmps16:
+ add $8, %rdx
+LeaveLoopCmps8:
+ add $8, %rdx
+LeaveLoopCmps: testl $0xFFFFFFFF, %eax /* Check the first 4 bytes */
+ jnz Check16
+ add $4, %rdx
+ shr $32, %rax
+Check16: testw $0xFFFF, %ax
+ jnz LenLower
+ add $2, %rdx
+ shrl $16, %eax
+LenLower: subb $1, %al
+ adc $0, %rdx
+# endif
+#endif
+
+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
+/* then automatically accept it as the best possible match and leave. */
+
+ lea (%prev, %rdx), %rax
+ sub %scan, %rax
+ cmpl $MAX_MATCH, %eax
+ jge LenMaximum
+
+/* If the length of the match is not longer than the best match we */
+/* have so far, then forget it and return to the lookup loop. */
+
+ cmpl %bestlend, %eax
+ jg LongerMatch
+ mov _windowbestlen, %windowbestlen
+ mov dsPrev, %prev
+ movl _chainlenwmask, %edx
+ jmp LookupLoop
+
+/* s->match_start = cur_match; */
+/* best_len = len; */
+/* if (len >= nice_match) break; */
+/* scan_end = *(ushf*)(scan+best_len-1); */
+
+LongerMatch:
+ movl %eax, %bestlend
+ movl %curmatchd, dsMatchStart
+ cmpl %nicematch, %eax
+ jge LeaveNow
+
+ lea (%window, %bestlen), %windowbestlen
+ mov %windowbestlen, _windowbestlen
+
+ movzwl -1(%scan, %rax), %scanend
+ mov dsPrev, %prev
+ movl _chainlenwmask, %chainlenwmask
+ jmp LookupLoop
+
+/* Accept the current string, with the maximum possible length. */
+
+LenMaximum:
+ movl $MAX_MATCH, %bestlend
+ movl %curmatchd, dsMatchStart
+
+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
+/* return s->lookahead; */
+
+LeaveNow:
+ movl dsLookahead, %eax
+ cmpl %eax, %bestlend
+ cmovngl %bestlend, %eax
+LookaheadRet:
+
+/* Restore the registers and return from whence we came. */
+
+ mov save_rsi, %rsi
+ mov save_rbx, %rbx
+ mov save_r12, %r12
+ mov save_r13, %r13
+ mov save_r14, %r14
+ mov save_r15, %r15
+
+ ret
+
+match_init: ret
diff --git a/xs/src/png/zlib/contrib/asm686/README.686 b/xs/src/png/zlib/contrib/asm686/README.686
new file mode 100644
index 000000000..a0bf3bea4
--- /dev/null
+++ b/xs/src/png/zlib/contrib/asm686/README.686
@@ -0,0 +1,51 @@
+This is a patched version of zlib, modified to use
+Pentium-Pro-optimized assembly code in the deflation algorithm. The
+files changed/added by this patch are:
+
+README.686
+match.S
+
+The speedup that this patch provides varies, depending on whether the
+compiler used to build the original version of zlib falls afoul of the
+PPro's speed traps. My own tests show a speedup of around 10-20% at
+the default compression level, and 20-30% using -9, against a version
+compiled using gcc 2.7.2.3. Your mileage may vary.
+
+Note that this code has been tailored for the PPro/PII in particular,
+and will not perform particuarly well on a Pentium.
+
+If you are using an assembler other than GNU as, you will have to
+translate match.S to use your assembler's syntax. (Have fun.)
+
+Brian Raiter
+breadbox@muppetlabs.com
+April, 1998
+
+
+Added for zlib 1.1.3:
+
+The patches come from
+http://www.muppetlabs.com/~breadbox/software/assembly.html
+
+To compile zlib with this asm file, copy match.S to the zlib directory
+then do:
+
+CFLAGS="-O3 -DASMV" ./configure
+make OBJA=match.o
+
+
+Update:
+
+I've been ignoring these assembly routines for years, believing that
+gcc's generated code had caught up with it sometime around gcc 2.95
+and the major rearchitecting of the Pentium 4. However, I recently
+learned that, despite what I believed, this code still has some life
+in it. On the Pentium 4 and AMD64 chips, it continues to run about 8%
+faster than the code produced by gcc 4.1.
+
+In acknowledgement of its continuing usefulness, I've altered the
+license to match that of the rest of zlib. Share and Enjoy!
+
+Brian Raiter
+breadbox@muppetlabs.com
+April, 2007
diff --git a/xs/src/png/zlib/contrib/asm686/match.S b/xs/src/png/zlib/contrib/asm686/match.S
new file mode 100644
index 000000000..fa4210927
--- /dev/null
+++ b/xs/src/png/zlib/contrib/asm686/match.S
@@ -0,0 +1,357 @@
+/* match.S -- x86 assembly version of the zlib longest_match() function.
+ * Optimized for the Intel 686 chips (PPro and later).
+ *
+ * Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com>
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the author be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef NO_UNDERLINE
+#define match_init _match_init
+#define longest_match _longest_match
+#endif
+
+#define MAX_MATCH (258)
+#define MIN_MATCH (3)
+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
+
+/* stack frame offsets */
+
+#define chainlenwmask 0 /* high word: current chain len */
+ /* low word: s->wmask */
+#define window 4 /* local copy of s->window */
+#define windowbestlen 8 /* s->window + bestlen */
+#define scanstart 16 /* first two bytes of string */
+#define scanend 12 /* last two bytes of string */
+#define scanalign 20 /* dword-misalignment of string */
+#define nicematch 24 /* a good enough match size */
+#define bestlen 28 /* size of best match so far */
+#define scan 32 /* ptr to string wanting match */
+
+#define LocalVarsSize (36)
+/* saved ebx 36 */
+/* saved edi 40 */
+/* saved esi 44 */
+/* saved ebp 48 */
+/* return address 52 */
+#define deflatestate 56 /* the function arguments */
+#define curmatch 60
+
+/* All the +zlib1222add offsets are due to the addition of fields
+ * in zlib in the deflate_state structure since the asm code was first written
+ * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+ * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+ * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+ */
+
+#define zlib1222add (8)
+
+#define dsWSize (36+zlib1222add)
+#define dsWMask (44+zlib1222add)
+#define dsWindow (48+zlib1222add)
+#define dsPrev (56+zlib1222add)
+#define dsMatchLen (88+zlib1222add)
+#define dsPrevMatch (92+zlib1222add)
+#define dsStrStart (100+zlib1222add)
+#define dsMatchStart (104+zlib1222add)
+#define dsLookahead (108+zlib1222add)
+#define dsPrevLen (112+zlib1222add)
+#define dsMaxChainLen (116+zlib1222add)
+#define dsGoodMatch (132+zlib1222add)
+#define dsNiceMatch (136+zlib1222add)
+
+
+.file "match.S"
+
+.globl match_init, longest_match
+
+.text
+
+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
+.cfi_sections .debug_frame
+
+longest_match:
+
+.cfi_startproc
+/* Save registers that the compiler may be using, and adjust %esp to */
+/* make room for our stack frame. */
+
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset ebp, -8
+ pushl %edi
+ .cfi_def_cfa_offset 12
+ pushl %esi
+ .cfi_def_cfa_offset 16
+ pushl %ebx
+ .cfi_def_cfa_offset 20
+ subl $LocalVarsSize, %esp
+ .cfi_def_cfa_offset LocalVarsSize+20
+
+/* Retrieve the function arguments. %ecx will hold cur_match */
+/* throughout the entire function. %edx will hold the pointer to the */
+/* deflate_state structure during the function's setup (before */
+/* entering the main loop). */
+
+ movl deflatestate(%esp), %edx
+ movl curmatch(%esp), %ecx
+
+/* uInt wmask = s->w_mask; */
+/* unsigned chain_length = s->max_chain_length; */
+/* if (s->prev_length >= s->good_match) { */
+/* chain_length >>= 2; */
+/* } */
+
+ movl dsPrevLen(%edx), %eax
+ movl dsGoodMatch(%edx), %ebx
+ cmpl %ebx, %eax
+ movl dsWMask(%edx), %eax
+ movl dsMaxChainLen(%edx), %ebx
+ jl LastMatchGood
+ shrl $2, %ebx
+LastMatchGood:
+
+/* chainlen is decremented once beforehand so that the function can */
+/* use the sign flag instead of the zero flag for the exit test. */
+/* It is then shifted into the high word, to make room for the wmask */
+/* value, which it will always accompany. */
+
+ decl %ebx
+ shll $16, %ebx
+ orl %eax, %ebx
+ movl %ebx, chainlenwmask(%esp)
+
+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
+
+ movl dsNiceMatch(%edx), %eax
+ movl dsLookahead(%edx), %ebx
+ cmpl %eax, %ebx
+ jl LookaheadLess
+ movl %eax, %ebx
+LookaheadLess: movl %ebx, nicematch(%esp)
+
+/* register Bytef *scan = s->window + s->strstart; */
+
+ movl dsWindow(%edx), %esi
+ movl %esi, window(%esp)
+ movl dsStrStart(%edx), %ebp
+ lea (%esi,%ebp), %edi
+ movl %edi, scan(%esp)
+
+/* Determine how many bytes the scan ptr is off from being */
+/* dword-aligned. */
+
+ movl %edi, %eax
+ negl %eax
+ andl $3, %eax
+ movl %eax, scanalign(%esp)
+
+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
+
+ movl dsWSize(%edx), %eax
+ subl $MIN_LOOKAHEAD, %eax
+ subl %eax, %ebp
+ jg LimitPositive
+ xorl %ebp, %ebp
+LimitPositive:
+
+/* int best_len = s->prev_length; */
+
+ movl dsPrevLen(%edx), %eax
+ movl %eax, bestlen(%esp)
+
+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
+
+ addl %eax, %esi
+ movl %esi, windowbestlen(%esp)
+
+/* register ush scan_start = *(ushf*)scan; */
+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
+/* Posf *prev = s->prev; */
+
+ movzwl (%edi), %ebx
+ movl %ebx, scanstart(%esp)
+ movzwl -1(%edi,%eax), %ebx
+ movl %ebx, scanend(%esp)
+ movl dsPrev(%edx), %edi
+
+/* Jump into the main loop. */
+
+ movl chainlenwmask(%esp), %edx
+ jmp LoopEntry
+
+.balign 16
+
+/* do {
+ * match = s->window + cur_match;
+ * if (*(ushf*)(match+best_len-1) != scan_end ||
+ * *(ushf*)match != scan_start) continue;
+ * [...]
+ * } while ((cur_match = prev[cur_match & wmask]) > limit
+ * && --chain_length != 0);
+ *
+ * Here is the inner loop of the function. The function will spend the
+ * majority of its time in this loop, and majority of that time will
+ * be spent in the first ten instructions.
+ *
+ * Within this loop:
+ * %ebx = scanend
+ * %ecx = curmatch
+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+ * %esi = windowbestlen - i.e., (window + bestlen)
+ * %edi = prev
+ * %ebp = limit
+ */
+LookupLoop:
+ andl %edx, %ecx
+ movzwl (%edi,%ecx,2), %ecx
+ cmpl %ebp, %ecx
+ jbe LeaveNow
+ subl $0x00010000, %edx
+ js LeaveNow
+LoopEntry: movzwl -1(%esi,%ecx), %eax
+ cmpl %ebx, %eax
+ jnz LookupLoop
+ movl window(%esp), %eax
+ movzwl (%eax,%ecx), %eax
+ cmpl scanstart(%esp), %eax
+ jnz LookupLoop
+
+/* Store the current value of chainlen. */
+
+ movl %edx, chainlenwmask(%esp)
+
+/* Point %edi to the string under scrutiny, and %esi to the string we */
+/* are hoping to match it up with. In actuality, %esi and %edi are */
+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
+/* initialized to -(MAX_MATCH_8 - scanalign). */
+
+ movl window(%esp), %esi
+ movl scan(%esp), %edi
+ addl %ecx, %esi
+ movl scanalign(%esp), %eax
+ movl $(-MAX_MATCH_8), %edx
+ lea MAX_MATCH_8(%edi,%eax), %edi
+ lea MAX_MATCH_8(%esi,%eax), %esi
+
+/* Test the strings for equality, 8 bytes at a time. At the end,
+ * adjust %edx so that it is offset to the exact byte that mismatched.
+ *
+ * We already know at this point that the first three bytes of the
+ * strings match each other, and they can be safely passed over before
+ * starting the compare loop. So what this code does is skip over 0-3
+ * bytes, as much as necessary in order to dword-align the %edi
+ * pointer. (%esi will still be misaligned three times out of four.)
+ *
+ * It should be confessed that this loop usually does not represent
+ * much of the total running time. Replacing it with a more
+ * straightforward "rep cmpsb" would not drastically degrade
+ * performance.
+ */
+LoopCmps:
+ movl (%esi,%edx), %eax
+ xorl (%edi,%edx), %eax
+ jnz LeaveLoopCmps
+ movl 4(%esi,%edx), %eax
+ xorl 4(%edi,%edx), %eax
+ jnz LeaveLoopCmps4
+ addl $8, %edx
+ jnz LoopCmps
+ jmp LenMaximum
+LeaveLoopCmps4: addl $4, %edx
+LeaveLoopCmps: testl $0x0000FFFF, %eax
+ jnz LenLower
+ addl $2, %edx
+ shrl $16, %eax
+LenLower: subb $1, %al
+ adcl $0, %edx
+
+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
+/* then automatically accept it as the best possible match and leave. */
+
+ lea (%edi,%edx), %eax
+ movl scan(%esp), %edi
+ subl %edi, %eax
+ cmpl $MAX_MATCH, %eax
+ jge LenMaximum
+
+/* If the length of the match is not longer than the best match we */
+/* have so far, then forget it and return to the lookup loop. */
+
+ movl deflatestate(%esp), %edx
+ movl bestlen(%esp), %ebx
+ cmpl %ebx, %eax
+ jg LongerMatch
+ movl windowbestlen(%esp), %esi
+ movl dsPrev(%edx), %edi
+ movl scanend(%esp), %ebx
+ movl chainlenwmask(%esp), %edx
+ jmp LookupLoop
+
+/* s->match_start = cur_match; */
+/* best_len = len; */
+/* if (len >= nice_match) break; */
+/* scan_end = *(ushf*)(scan+best_len-1); */
+
+LongerMatch: movl nicematch(%esp), %ebx
+ movl %eax, bestlen(%esp)
+ movl %ecx, dsMatchStart(%edx)
+ cmpl %ebx, %eax
+ jge LeaveNow
+ movl window(%esp), %esi
+ addl %eax, %esi
+ movl %esi, windowbestlen(%esp)
+ movzwl -1(%edi,%eax), %ebx
+ movl dsPrev(%edx), %edi
+ movl %ebx, scanend(%esp)
+ movl chainlenwmask(%esp), %edx
+ jmp LookupLoop
+
+/* Accept the current string, with the maximum possible length. */
+
+LenMaximum: movl deflatestate(%esp), %edx
+ movl $MAX_MATCH, bestlen(%esp)
+ movl %ecx, dsMatchStart(%edx)
+
+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
+/* return s->lookahead; */
+
+LeaveNow:
+ movl deflatestate(%esp), %edx
+ movl bestlen(%esp), %ebx
+ movl dsLookahead(%edx), %eax
+ cmpl %eax, %ebx
+ jg LookaheadRet
+ movl %ebx, %eax
+LookaheadRet:
+
+/* Restore the stack and return from whence we came. */
+
+ addl $LocalVarsSize, %esp
+ .cfi_def_cfa_offset 20
+ popl %ebx
+ .cfi_def_cfa_offset 16
+ popl %esi
+ .cfi_def_cfa_offset 12
+ popl %edi
+ .cfi_def_cfa_offset 8
+ popl %ebp
+ .cfi_def_cfa_offset 4
+.cfi_endproc
+match_init: ret
diff --git a/xs/src/png/zlib/contrib/blast/Makefile b/xs/src/png/zlib/contrib/blast/Makefile
new file mode 100644
index 000000000..9be80bafe
--- /dev/null
+++ b/xs/src/png/zlib/contrib/blast/Makefile
@@ -0,0 +1,8 @@
+blast: blast.c blast.h
+ cc -DTEST -o blast blast.c
+
+test: blast
+ blast < test.pk | cmp - test.txt
+
+clean:
+ rm -f blast blast.o
diff --git a/xs/src/png/zlib/contrib/blast/README b/xs/src/png/zlib/contrib/blast/README
new file mode 100644
index 000000000..e3a60b3f5
--- /dev/null
+++ b/xs/src/png/zlib/contrib/blast/README
@@ -0,0 +1,4 @@
+Read blast.h for purpose and usage.
+
+Mark Adler
+madler@alumni.caltech.edu
diff --git a/xs/src/png/zlib/contrib/blast/blast.c b/xs/src/png/zlib/contrib/blast/blast.c
new file mode 100644
index 000000000..e6e659073
--- /dev/null
+++ b/xs/src/png/zlib/contrib/blast/blast.c
@@ -0,0 +1,466 @@
+/* blast.c
+ * Copyright (C) 2003, 2012, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in blast.h
+ * version 1.3, 24 Aug 2013
+ *
+ * blast.c decompresses data compressed by the PKWare Compression Library.
+ * This function provides functionality similar to the explode() function of
+ * the PKWare library, hence the name "blast".
+ *
+ * This decompressor is based on the excellent format description provided by
+ * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the
+ * example Ben provided in the post is incorrect. The distance 110001 should
+ * instead be 111000. When corrected, the example byte stream becomes:
+ *
+ * 00 04 82 24 25 8f 80 7f
+ *
+ * which decompresses to "AIAIAIAIAIAIA" (without the quotes).
+ */
+
+/*
+ * Change history:
+ *
+ * 1.0 12 Feb 2003 - First version
+ * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data
+ * 1.2 24 Oct 2012 - Add note about using binary mode in stdio
+ * - Fix comparisons of differently signed integers
+ * 1.3 24 Aug 2013 - Return unused input from blast()
+ * - Fix test code to correctly report unused input
+ * - Enable the provision of initial input to blast()
+ */
+
+#include <stddef.h> /* for NULL */
+#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
+#include "blast.h" /* prototype for blast() */
+
+#define local static /* for local function definitions */
+#define MAXBITS 13 /* maximum code length */
+#define MAXWIN 4096 /* maximum window size */
+
+/* input and output state */
+struct state {
+ /* input state */
+ blast_in infun; /* input function provided by user */
+ void *inhow; /* opaque information passed to infun() */
+ unsigned char *in; /* next input location */
+ unsigned left; /* available input at in */
+ int bitbuf; /* bit buffer */
+ int bitcnt; /* number of bits in bit buffer */
+
+ /* input limit error return state for bits() and decode() */
+ jmp_buf env;
+
+ /* output state */
+ blast_out outfun; /* output function provided by user */
+ void *outhow; /* opaque information passed to outfun() */
+ unsigned next; /* index of next write location in out[] */
+ int first; /* true to check distances (for first 4K) */
+ unsigned char out[MAXWIN]; /* output buffer and sliding window */
+};
+
+/*
+ * Return need bits from the input stream. This always leaves less than
+ * eight bits in the buffer. bits() works properly for need == 0.
+ *
+ * Format notes:
+ *
+ * - Bits are stored in bytes from the least significant bit to the most
+ * significant bit. Therefore bits are dropped from the bottom of the bit
+ * buffer, using shift right, and new bytes are appended to the top of the
+ * bit buffer, using shift left.
+ */
+local int bits(struct state *s, int need)
+{
+ int val; /* bit accumulator */
+
+ /* load at least need bits into val */
+ val = s->bitbuf;
+ while (s->bitcnt < need) {
+ if (s->left == 0) {
+ s->left = s->infun(s->inhow, &(s->in));
+ if (s->left == 0) longjmp(s->env, 1); /* out of input */
+ }
+ val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */
+ s->left--;
+ s->bitcnt += 8;
+ }
+
+ /* drop need bits and update buffer, always zero to seven bits left */
+ s->bitbuf = val >> need;
+ s->bitcnt -= need;
+
+ /* return need bits, zeroing the bits above that */
+ return val & ((1 << need) - 1);
+}
+
+/*
+ * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
+ * each length, which for a canonical code are stepped through in order.
+ * symbol[] are the symbol values in canonical order, where the number of
+ * entries is the sum of the counts in count[]. The decoding process can be
+ * seen in the function decode() below.
+ */
+struct huffman {
+ short *count; /* number of symbols of each length */
+ short *symbol; /* canonically ordered symbols */
+};
+
+/*
+ * Decode a code from the stream s using huffman table h. Return the symbol or
+ * a negative value if there is an error. If all of the lengths are zero, i.e.
+ * an empty code, or if the code is incomplete and an invalid code is received,
+ * then -9 is returned after reading MAXBITS bits.
+ *
+ * Format notes:
+ *
+ * - The codes as stored in the compressed data are bit-reversed relative to
+ * a simple integer ordering of codes of the same lengths. Hence below the
+ * bits are pulled from the compressed data one at a time and used to
+ * build the code value reversed from what is in the stream in order to
+ * permit simple integer comparisons for decoding.
+ *
+ * - The first code for the shortest length is all ones. Subsequent codes of
+ * the same length are simply integer decrements of the previous code. When
+ * moving up a length, a one bit is appended to the code. For a complete
+ * code, the last code of the longest length will be all zeros. To support
+ * this ordering, the bits pulled during decoding are inverted to apply the
+ * more "natural" ordering starting with all zeros and incrementing.
+ */
+local int decode(struct state *s, struct huffman *h)
+{
+ int len; /* current number of bits in code */
+ int code; /* len bits being decoded */
+ int first; /* first code of length len */
+ int count; /* number of codes of length len */
+ int index; /* index of first code of length len in symbol table */
+ int bitbuf; /* bits from stream */
+ int left; /* bits left in next or left to process */
+ short *next; /* next number of codes */
+
+ bitbuf = s->bitbuf;
+ left = s->bitcnt;
+ code = first = index = 0;
+ len = 1;
+ next = h->count + 1;
+ while (1) {
+ while (left--) {
+ code |= (bitbuf & 1) ^ 1; /* invert code */
+ bitbuf >>= 1;
+ count = *next++;
+ if (code < first + count) { /* if length len, return symbol */
+ s->bitbuf = bitbuf;
+ s->bitcnt = (s->bitcnt - len) & 7;
+ return h->symbol[index + (code - first)];
+ }
+ index += count; /* else update for next length */
+ first += count;
+ first <<= 1;
+ code <<= 1;
+ len++;
+ }
+ left = (MAXBITS+1) - len;
+ if (left == 0) break;
+ if (s->left == 0) {
+ s->left = s->infun(s->inhow, &(s->in));
+ if (s->left == 0) longjmp(s->env, 1); /* out of input */
+ }
+ bitbuf = *(s->in)++;
+ s->left--;
+ if (left > 8) left = 8;
+ }
+ return -9; /* ran out of codes */
+}
+
+/*
+ * Given a list of repeated code lengths rep[0..n-1], where each byte is a
+ * count (high four bits + 1) and a code length (low four bits), generate the
+ * list of code lengths. This compaction reduces the size of the object code.
+ * Then given the list of code lengths length[0..n-1] representing a canonical
+ * Huffman code for n symbols, construct the tables required to decode those
+ * codes. Those tables are the number of codes of each length, and the symbols
+ * sorted by length, retaining their original order within each length. The
+ * return value is zero for a complete code set, negative for an over-
+ * subscribed code set, and positive for an incomplete code set. The tables
+ * can be used if the return value is zero or positive, but they cannot be used
+ * if the return value is negative. If the return value is zero, it is not
+ * possible for decode() using that table to return an error--any stream of
+ * enough bits will resolve to a symbol. If the return value is positive, then
+ * it is possible for decode() using that table to return an error for received
+ * codes past the end of the incomplete lengths.
+ */
+local int construct(struct huffman *h, const unsigned char *rep, int n)
+{
+ int symbol; /* current symbol when stepping through length[] */
+ int len; /* current length when stepping through h->count[] */
+ int left; /* number of possible codes left of current length */
+ short offs[MAXBITS+1]; /* offsets in symbol table for each length */
+ short length[256]; /* code lengths */
+
+ /* convert compact repeat counts into symbol bit length list */
+ symbol = 0;
+ do {
+ len = *rep++;
+ left = (len >> 4) + 1;
+ len &= 15;
+ do {
+ length[symbol++] = len;
+ } while (--left);
+ } while (--n);
+ n = symbol;
+
+ /* count number of codes of each length */
+ for (len = 0; len <= MAXBITS; len++)
+ h->count[len] = 0;
+ for (symbol = 0; symbol < n; symbol++)
+ (h->count[length[symbol]])++; /* assumes lengths are within bounds */
+ if (h->count[0] == n) /* no codes! */
+ return 0; /* complete, but decode() will fail */
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1; /* one possible code of zero length */
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1; /* one more bit, double codes left */
+ left -= h->count[len]; /* deduct count from possible codes */
+ if (left < 0) return left; /* over-subscribed--return negative */
+ } /* left > 0 means incomplete */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + h->count[len];
+
+ /*
+ * put symbols in table sorted by length, by symbol order within each
+ * length
+ */
+ for (symbol = 0; symbol < n; symbol++)
+ if (length[symbol] != 0)
+ h->symbol[offs[length[symbol]]++] = symbol;
+
+ /* return zero for complete set, positive for incomplete set */
+ return left;
+}
+
+/*
+ * Decode PKWare Compression Library stream.
+ *
+ * Format notes:
+ *
+ * - First byte is 0 if literals are uncoded or 1 if they are coded. Second
+ * byte is 4, 5, or 6 for the number of extra bits in the distance code.
+ * This is the base-2 logarithm of the dictionary size minus six.
+ *
+ * - Compressed data is a combination of literals and length/distance pairs
+ * terminated by an end code. Literals are either Huffman coded or
+ * uncoded bytes. A length/distance pair is a coded length followed by a
+ * coded distance to represent a string that occurs earlier in the
+ * uncompressed data that occurs again at the current location.
+ *
+ * - A bit preceding a literal or length/distance pair indicates which comes
+ * next, 0 for literals, 1 for length/distance.
+ *
+ * - If literals are uncoded, then the next eight bits are the literal, in the
+ * normal bit order in the stream, i.e. no bit-reversal is needed. Similarly,
+ * no bit reversal is needed for either the length extra bits or the distance
+ * extra bits.
+ *
+ * - Literal bytes are simply written to the output. A length/distance pair is
+ * an instruction to copy previously uncompressed bytes to the output. The
+ * copy is from distance bytes back in the output stream, copying for length
+ * bytes.
+ *
+ * - Distances pointing before the beginning of the output data are not
+ * permitted.
+ *
+ * - Overlapped copies, where the length is greater than the distance, are
+ * allowed and common. For example, a distance of one and a length of 518
+ * simply copies the last byte 518 times. A distance of four and a length of
+ * twelve copies the last four bytes three times. A simple forward copy
+ * ignoring whether the length is greater than the distance or not implements
+ * this correctly.
+ */
+local int decomp(struct state *s)
+{
+ int lit; /* true if literals are coded */
+ int dict; /* log2(dictionary size) - 6 */
+ int symbol; /* decoded symbol, extra bits for distance */
+ int len; /* length for copy */
+ unsigned dist; /* distance for copy */
+ int copy; /* copy counter */
+ unsigned char *from, *to; /* copy pointers */
+ static int virgin = 1; /* build tables once */
+ static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */
+ static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */
+ static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */
+ static struct huffman litcode = {litcnt, litsym}; /* length code */
+ static struct huffman lencode = {lencnt, lensym}; /* length code */
+ static struct huffman distcode = {distcnt, distsym};/* distance code */
+ /* bit lengths of literal codes */
+ static const unsigned char litlen[] = {
+ 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8,
+ 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5,
+ 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12,
+ 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27,
+ 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45,
+ 44, 173};
+ /* bit lengths of length codes 0..15 */
+ static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23};
+ /* bit lengths of distance codes 0..63 */
+ static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248};
+ static const short base[16] = { /* base for length codes */
+ 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264};
+ static const char extra[16] = { /* extra bits for length codes */
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
+
+ /* set up decoding tables (once--might not be thread-safe) */
+ if (virgin) {
+ construct(&litcode, litlen, sizeof(litlen));
+ construct(&lencode, lenlen, sizeof(lenlen));
+ construct(&distcode, distlen, sizeof(distlen));
+ virgin = 0;
+ }
+
+ /* read header */
+ lit = bits(s, 8);
+ if (lit > 1) return -1;
+ dict = bits(s, 8);
+ if (dict < 4 || dict > 6) return -2;
+
+ /* decode literals and length/distance pairs */
+ do {
+ if (bits(s, 1)) {
+ /* get length */
+ symbol = decode(s, &lencode);
+ len = base[symbol] + bits(s, extra[symbol]);
+ if (len == 519) break; /* end code */
+
+ /* get distance */
+ symbol = len == 2 ? 2 : dict;
+ dist = decode(s, &distcode) << symbol;
+ dist += bits(s, symbol);
+ dist++;
+ if (s->first && dist > s->next)
+ return -3; /* distance too far back */
+
+ /* copy length bytes from distance bytes back */
+ do {
+ to = s->out + s->next;
+ from = to - dist;
+ copy = MAXWIN;
+ if (s->next < dist) {
+ from += copy;
+ copy = dist;
+ }
+ copy -= s->next;
+ if (copy > len) copy = len;
+ len -= copy;
+ s->next += copy;
+ do {
+ *to++ = *from++;
+ } while (--copy);
+ if (s->next == MAXWIN) {
+ if (s->outfun(s->outhow, s->out, s->next)) return 1;
+ s->next = 0;
+ s->first = 0;
+ }
+ } while (len != 0);
+ }
+ else {
+ /* get literal and write it */
+ symbol = lit ? decode(s, &litcode) : bits(s, 8);
+ s->out[s->next++] = symbol;
+ if (s->next == MAXWIN) {
+ if (s->outfun(s->outhow, s->out, s->next)) return 1;
+ s->next = 0;
+ s->first = 0;
+ }
+ }
+ } while (1);
+ return 0;
+}
+
+/* See comments in blast.h */
+int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow,
+ unsigned *left, unsigned char **in)
+{
+ struct state s; /* input/output state */
+ int err; /* return value */
+
+ /* initialize input state */
+ s.infun = infun;
+ s.inhow = inhow;
+ if (left != NULL && *left) {
+ s.left = *left;
+ s.in = *in;
+ }
+ else
+ s.left = 0;
+ s.bitbuf = 0;
+ s.bitcnt = 0;
+
+ /* initialize output state */
+ s.outfun = outfun;
+ s.outhow = outhow;
+ s.next = 0;
+ s.first = 1;
+
+ /* return if bits() or decode() tries to read past available input */
+ if (setjmp(s.env) != 0) /* if came back here via longjmp(), */
+ err = 2; /* then skip decomp(), return error */
+ else
+ err = decomp(&s); /* decompress */
+
+ /* return unused input */
+ if (left != NULL)
+ *left = s.left;
+ if (in != NULL)
+ *in = s.left ? s.in : NULL;
+
+ /* write any leftover output and update the error code if needed */
+ if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0)
+ err = 1;
+ return err;
+}
+
+#ifdef TEST
+/* Example of how to use blast() */
+#include <stdio.h>
+#include <stdlib.h>
+
+#define CHUNK 16384
+
+local unsigned inf(void *how, unsigned char **buf)
+{
+ static unsigned char hold[CHUNK];
+
+ *buf = hold;
+ return fread(hold, 1, CHUNK, (FILE *)how);
+}
+
+local int outf(void *how, unsigned char *buf, unsigned len)
+{
+ return fwrite(buf, 1, len, (FILE *)how) != len;
+}
+
+/* Decompress a PKWare Compression Library stream from stdin to stdout */
+int main(void)
+{
+ int ret;
+ unsigned left;
+
+ /* decompress to stdout */
+ left = 0;
+ ret = blast(inf, stdin, outf, stdout, &left, NULL);
+ if (ret != 0)
+ fprintf(stderr, "blast error: %d\n", ret);
+
+ /* count any leftover bytes */
+ while (getchar() != EOF)
+ left++;
+ if (left)
+ fprintf(stderr, "blast warning: %u unused bytes of input\n", left);
+
+ /* return blast() error code */
+ return ret;
+}
+#endif
diff --git a/xs/src/png/zlib/contrib/blast/blast.h b/xs/src/png/zlib/contrib/blast/blast.h
new file mode 100644
index 000000000..6cf65eda1
--- /dev/null
+++ b/xs/src/png/zlib/contrib/blast/blast.h
@@ -0,0 +1,83 @@
+/* blast.h -- interface for blast.c
+ Copyright (C) 2003, 2012, 2013 Mark Adler
+ version 1.3, 24 Aug 2013
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the author be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Mark Adler madler@alumni.caltech.edu
+ */
+
+
+/*
+ * blast() decompresses the PKWare Data Compression Library (DCL) compressed
+ * format. It provides the same functionality as the explode() function in
+ * that library. (Note: PKWare overused the "implode" verb, and the format
+ * used by their library implode() function is completely different and
+ * incompatible with the implode compression method supported by PKZIP.)
+ *
+ * The binary mode for stdio functions should be used to assure that the
+ * compressed data is not corrupted when read or written. For example:
+ * fopen(..., "rb") and fopen(..., "wb").
+ */
+
+
+typedef unsigned (*blast_in)(void *how, unsigned char **buf);
+typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len);
+/* Definitions for input/output functions passed to blast(). See below for
+ * what the provided functions need to do.
+ */
+
+
+int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow,
+ unsigned *left, unsigned char **in);
+/* Decompress input to output using the provided infun() and outfun() calls.
+ * On success, the return value of blast() is zero. If there is an error in
+ * the source data, i.e. it is not in the proper format, then a negative value
+ * is returned. If there is not enough input available or there is not enough
+ * output space, then a positive error is returned.
+ *
+ * The input function is invoked: len = infun(how, &buf), where buf is set by
+ * infun() to point to the input buffer, and infun() returns the number of
+ * available bytes there. If infun() returns zero, then blast() returns with
+ * an input error. (blast() only asks for input if it needs it.) inhow is for
+ * use by the application to pass an input descriptor to infun(), if desired.
+ *
+ * If left and in are not NULL and *left is not zero when blast() is called,
+ * then the *left bytes are *in are consumed for input before infun() is used.
+ *
+ * The output function is invoked: err = outfun(how, buf, len), where the bytes
+ * to be written are buf[0..len-1]. If err is not zero, then blast() returns
+ * with an output error. outfun() is always called with len <= 4096. outhow
+ * is for use by the application to pass an output descriptor to outfun(), if
+ * desired.
+ *
+ * If there is any unused input, *left is set to the number of bytes that were
+ * read and *in points to them. Otherwise *left is set to zero and *in is set
+ * to NULL. If left or in are NULL, then they are not set.
+ *
+ * The return codes are:
+ *
+ * 2: ran out of input before completing decompression
+ * 1: output error before completing decompression
+ * 0: successful decompression
+ * -1: literal flag not zero or one
+ * -2: dictionary size not in 4..6
+ * -3: distance is too far back
+ *
+ * At the bottom of blast.c is an example program that uses blast() that can be
+ * compiled to produce a command-line decompression filter by defining TEST.
+ */
diff --git a/xs/src/png/zlib/contrib/blast/test.pk b/xs/src/png/zlib/contrib/blast/test.pk
new file mode 100644
index 000000000..be10b2bbb
--- /dev/null
+++ b/xs/src/png/zlib/contrib/blast/test.pk
Binary files differ
diff --git a/xs/src/png/zlib/contrib/blast/test.txt b/xs/src/png/zlib/contrib/blast/test.txt
new file mode 100644
index 000000000..bfdf1c5dc
--- /dev/null
+++ b/xs/src/png/zlib/contrib/blast/test.txt
@@ -0,0 +1 @@
+AIAIAIAIAIAIA \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/delphi/ZLib.pas b/xs/src/png/zlib/contrib/delphi/ZLib.pas
new file mode 100644
index 000000000..060e19911
--- /dev/null
+++ b/xs/src/png/zlib/contrib/delphi/ZLib.pas
@@ -0,0 +1,557 @@
+{*******************************************************}
+{ }
+{ Borland Delphi Supplemental Components }
+{ ZLIB Data Compression Interface Unit }
+{ }
+{ Copyright (c) 1997,99 Borland Corporation }
+{ }
+{*******************************************************}
+
+{ Updated for zlib 1.2.x by Cosmin Truta <cosmint@cs.ubbcluj.ro> }
+
+unit ZLib;
+
+interface
+
+uses SysUtils, Classes;
+
+type
+ TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
+ TFree = procedure (AppData, Block: Pointer); cdecl;
+
+ // Internal structure. Ignore.
+ TZStreamRec = packed record
+ next_in: PChar; // next input byte
+ avail_in: Integer; // number of bytes available at next_in
+ total_in: Longint; // total nb of input bytes read so far
+
+ next_out: PChar; // next output byte should be put here
+ avail_out: Integer; // remaining free space at next_out
+ total_out: Longint; // total nb of bytes output so far
+
+ msg: PChar; // last error message, NULL if no error
+ internal: Pointer; // not visible by applications
+
+ zalloc: TAlloc; // used to allocate the internal state
+ zfree: TFree; // used to free the internal state
+ AppData: Pointer; // private data object passed to zalloc and zfree
+
+ data_type: Integer; // best guess about the data type: ascii or binary
+ adler: Longint; // adler32 value of the uncompressed data
+ reserved: Longint; // reserved for future use
+ end;
+
+ // Abstract ancestor class
+ TCustomZlibStream = class(TStream)
+ private
+ FStrm: TStream;
+ FStrmPos: Integer;
+ FOnProgress: TNotifyEvent;
+ FZRec: TZStreamRec;
+ FBuffer: array [Word] of Char;
+ protected
+ procedure Progress(Sender: TObject); dynamic;
+ property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
+ constructor Create(Strm: TStream);
+ end;
+
+{ TCompressionStream compresses data on the fly as data is written to it, and
+ stores the compressed data to another stream.
+
+ TCompressionStream is write-only and strictly sequential. Reading from the
+ stream will raise an exception. Using Seek to move the stream pointer
+ will raise an exception.
+
+ Output data is cached internally, written to the output stream only when
+ the internal output buffer is full. All pending output data is flushed
+ when the stream is destroyed.
+
+ The Position property returns the number of uncompressed bytes of
+ data that have been written to the stream so far.
+
+ CompressionRate returns the on-the-fly percentage by which the original
+ data has been compressed: (1 - (CompressedBytes / UncompressedBytes)) * 100
+ If raw data size = 100 and compressed data size = 25, the CompressionRate
+ is 75%
+
+ The OnProgress event is called each time the output buffer is filled and
+ written to the output stream. This is useful for updating a progress
+ indicator when you are writing a large chunk of data to the compression
+ stream in a single call.}
+
+
+ TCompressionLevel = (clNone, clFastest, clDefault, clMax);
+
+ TCompressionStream = class(TCustomZlibStream)
+ private
+ function GetCompressionRate: Single;
+ public
+ constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream);
+ destructor Destroy; override;
+ function Read(var Buffer; Count: Longint): Longint; override;
+ function Write(const Buffer; Count: Longint): Longint; override;
+ function Seek(Offset: Longint; Origin: Word): Longint; override;
+ property CompressionRate: Single read GetCompressionRate;
+ property OnProgress;
+ end;
+
+{ TDecompressionStream decompresses data on the fly as data is read from it.
+
+ Compressed data comes from a separate source stream. TDecompressionStream
+ is read-only and unidirectional; you can seek forward in the stream, but not
+ backwards. The special case of setting the stream position to zero is
+ allowed. Seeking forward decompresses data until the requested position in
+ the uncompressed data has been reached. Seeking backwards, seeking relative
+ to the end of the stream, requesting the size of the stream, and writing to
+ the stream will raise an exception.
+
+ The Position property returns the number of bytes of uncompressed data that
+ have been read from the stream so far.
+
+ The OnProgress event is called each time the internal input buffer of
+ compressed data is exhausted and the next block is read from the input stream.
+ This is useful for updating a progress indicator when you are reading a
+ large chunk of data from the decompression stream in a single call.}
+
+ TDecompressionStream = class(TCustomZlibStream)
+ public
+ constructor Create(Source: TStream);
+ destructor Destroy; override;
+ function Read(var Buffer; Count: Longint): Longint; override;
+ function Write(const Buffer; Count: Longint): Longint; override;
+ function Seek(Offset: Longint; Origin: Word): Longint; override;
+ property OnProgress;
+ end;
+
+
+
+{ CompressBuf compresses data, buffer to buffer, in one call.
+ In: InBuf = ptr to compressed data
+ InBytes = number of bytes in InBuf
+ Out: OutBuf = ptr to newly allocated buffer containing decompressed data
+ OutBytes = number of bytes in OutBuf }
+procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
+ out OutBuf: Pointer; out OutBytes: Integer);
+
+
+{ DecompressBuf decompresses data, buffer to buffer, in one call.
+ In: InBuf = ptr to compressed data
+ InBytes = number of bytes in InBuf
+ OutEstimate = zero, or est. size of the decompressed data
+ Out: OutBuf = ptr to newly allocated buffer containing decompressed data
+ OutBytes = number of bytes in OutBuf }
+procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
+ OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
+
+{ DecompressToUserBuf decompresses data, buffer to buffer, in one call.
+ In: InBuf = ptr to compressed data
+ InBytes = number of bytes in InBuf
+ Out: OutBuf = ptr to user-allocated buffer to contain decompressed data
+ BufSize = number of bytes in OutBuf }
+procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
+ const OutBuf: Pointer; BufSize: Integer);
+
+const
+ zlib_version = '1.2.11';
+
+type
+ EZlibError = class(Exception);
+ ECompressionError = class(EZlibError);
+ EDecompressionError = class(EZlibError);
+
+implementation
+
+uses ZLibConst;
+
+const
+ Z_NO_FLUSH = 0;
+ Z_PARTIAL_FLUSH = 1;
+ Z_SYNC_FLUSH = 2;
+ Z_FULL_FLUSH = 3;
+ Z_FINISH = 4;
+
+ Z_OK = 0;
+ Z_STREAM_END = 1;
+ Z_NEED_DICT = 2;
+ Z_ERRNO = (-1);
+ Z_STREAM_ERROR = (-2);
+ Z_DATA_ERROR = (-3);
+ Z_MEM_ERROR = (-4);
+ Z_BUF_ERROR = (-5);
+ Z_VERSION_ERROR = (-6);
+
+ Z_NO_COMPRESSION = 0;
+ Z_BEST_SPEED = 1;
+ Z_BEST_COMPRESSION = 9;
+ Z_DEFAULT_COMPRESSION = (-1);
+
+ Z_FILTERED = 1;
+ Z_HUFFMAN_ONLY = 2;
+ Z_RLE = 3;
+ Z_DEFAULT_STRATEGY = 0;
+
+ Z_BINARY = 0;
+ Z_ASCII = 1;
+ Z_UNKNOWN = 2;
+
+ Z_DEFLATED = 8;
+
+
+{$L adler32.obj}
+{$L compress.obj}
+{$L crc32.obj}
+{$L deflate.obj}
+{$L infback.obj}
+{$L inffast.obj}
+{$L inflate.obj}
+{$L inftrees.obj}
+{$L trees.obj}
+{$L uncompr.obj}
+{$L zutil.obj}
+
+procedure adler32; external;
+procedure compressBound; external;
+procedure crc32; external;
+procedure deflateInit2_; external;
+procedure deflateParams; external;
+
+function _malloc(Size: Integer): Pointer; cdecl;
+begin
+ Result := AllocMem(Size);
+end;
+
+procedure _free(Block: Pointer); cdecl;
+begin
+ FreeMem(Block);
+end;
+
+procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;
+begin
+ FillChar(P^, count, B);
+end;
+
+procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
+begin
+ Move(source^, dest^, count);
+end;
+
+
+
+// deflate compresses data
+function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
+ recsize: Integer): Integer; external;
+function deflate(var strm: TZStreamRec; flush: Integer): Integer; external;
+function deflateEnd(var strm: TZStreamRec): Integer; external;
+
+// inflate decompresses data
+function inflateInit_(var strm: TZStreamRec; version: PChar;
+ recsize: Integer): Integer; external;
+function inflate(var strm: TZStreamRec; flush: Integer): Integer; external;
+function inflateEnd(var strm: TZStreamRec): Integer; external;
+function inflateReset(var strm: TZStreamRec): Integer; external;
+
+
+function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
+begin
+// GetMem(Result, Items*Size);
+ Result := AllocMem(Items * Size);
+end;
+
+procedure zlibFreeMem(AppData, Block: Pointer); cdecl;
+begin
+ FreeMem(Block);
+end;
+
+{function zlibCheck(code: Integer): Integer;
+begin
+ Result := code;
+ if code < 0 then
+ raise EZlibError.Create('error'); //!!
+end;}
+
+function CCheck(code: Integer): Integer;
+begin
+ Result := code;
+ if code < 0 then
+ raise ECompressionError.Create('error'); //!!
+end;
+
+function DCheck(code: Integer): Integer;
+begin
+ Result := code;
+ if code < 0 then
+ raise EDecompressionError.Create('error'); //!!
+end;
+
+procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
+ out OutBuf: Pointer; out OutBytes: Integer);
+var
+ strm: TZStreamRec;
+ P: Pointer;
+begin
+ FillChar(strm, sizeof(strm), 0);
+ strm.zalloc := zlibAllocMem;
+ strm.zfree := zlibFreeMem;
+ OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
+ GetMem(OutBuf, OutBytes);
+ try
+ strm.next_in := InBuf;
+ strm.avail_in := InBytes;
+ strm.next_out := OutBuf;
+ strm.avail_out := OutBytes;
+ CCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm)));
+ try
+ while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do
+ begin
+ P := OutBuf;
+ Inc(OutBytes, 256);
+ ReallocMem(OutBuf, OutBytes);
+ strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
+ strm.avail_out := 256;
+ end;
+ finally
+ CCheck(deflateEnd(strm));
+ end;
+ ReallocMem(OutBuf, strm.total_out);
+ OutBytes := strm.total_out;
+ except
+ FreeMem(OutBuf);
+ raise
+ end;
+end;
+
+
+procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
+ OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
+var
+ strm: TZStreamRec;
+ P: Pointer;
+ BufInc: Integer;
+begin
+ FillChar(strm, sizeof(strm), 0);
+ strm.zalloc := zlibAllocMem;
+ strm.zfree := zlibFreeMem;
+ BufInc := (InBytes + 255) and not 255;
+ if OutEstimate = 0 then
+ OutBytes := BufInc
+ else
+ OutBytes := OutEstimate;
+ GetMem(OutBuf, OutBytes);
+ try
+ strm.next_in := InBuf;
+ strm.avail_in := InBytes;
+ strm.next_out := OutBuf;
+ strm.avail_out := OutBytes;
+ DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
+ try
+ while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do
+ begin
+ P := OutBuf;
+ Inc(OutBytes, BufInc);
+ ReallocMem(OutBuf, OutBytes);
+ strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
+ strm.avail_out := BufInc;
+ end;
+ finally
+ DCheck(inflateEnd(strm));
+ end;
+ ReallocMem(OutBuf, strm.total_out);
+ OutBytes := strm.total_out;
+ except
+ FreeMem(OutBuf);
+ raise
+ end;
+end;
+
+procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
+ const OutBuf: Pointer; BufSize: Integer);
+var
+ strm: TZStreamRec;
+begin
+ FillChar(strm, sizeof(strm), 0);
+ strm.zalloc := zlibAllocMem;
+ strm.zfree := zlibFreeMem;
+ strm.next_in := InBuf;
+ strm.avail_in := InBytes;
+ strm.next_out := OutBuf;
+ strm.avail_out := BufSize;
+ DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
+ try
+ if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then
+ raise EZlibError.CreateRes(@sTargetBufferTooSmall);
+ finally
+ DCheck(inflateEnd(strm));
+ end;
+end;
+
+// TCustomZlibStream
+
+constructor TCustomZLibStream.Create(Strm: TStream);
+begin
+ inherited Create;
+ FStrm := Strm;
+ FStrmPos := Strm.Position;
+ FZRec.zalloc := zlibAllocMem;
+ FZRec.zfree := zlibFreeMem;
+end;
+
+procedure TCustomZLibStream.Progress(Sender: TObject);
+begin
+ if Assigned(FOnProgress) then FOnProgress(Sender);
+end;
+
+
+// TCompressionStream
+
+constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel;
+ Dest: TStream);
+const
+ Levels: array [TCompressionLevel] of ShortInt =
+ (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
+begin
+ inherited Create(Dest);
+ FZRec.next_out := FBuffer;
+ FZRec.avail_out := sizeof(FBuffer);
+ CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec)));
+end;
+
+destructor TCompressionStream.Destroy;
+begin
+ FZRec.next_in := nil;
+ FZRec.avail_in := 0;
+ try
+ if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
+ while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END)
+ and (FZRec.avail_out = 0) do
+ begin
+ FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
+ FZRec.next_out := FBuffer;
+ FZRec.avail_out := sizeof(FBuffer);
+ end;
+ if FZRec.avail_out < sizeof(FBuffer) then
+ FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out);
+ finally
+ deflateEnd(FZRec);
+ end;
+ inherited Destroy;
+end;
+
+function TCompressionStream.Read(var Buffer; Count: Longint): Longint;
+begin
+ raise ECompressionError.CreateRes(@sInvalidStreamOp);
+end;
+
+function TCompressionStream.Write(const Buffer; Count: Longint): Longint;
+begin
+ FZRec.next_in := @Buffer;
+ FZRec.avail_in := Count;
+ if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
+ while (FZRec.avail_in > 0) do
+ begin
+ CCheck(deflate(FZRec, 0));
+ if FZRec.avail_out = 0 then
+ begin
+ FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
+ FZRec.next_out := FBuffer;
+ FZRec.avail_out := sizeof(FBuffer);
+ FStrmPos := FStrm.Position;
+ Progress(Self);
+ end;
+ end;
+ Result := Count;
+end;
+
+function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
+begin
+ if (Offset = 0) and (Origin = soFromCurrent) then
+ Result := FZRec.total_in
+ else
+ raise ECompressionError.CreateRes(@sInvalidStreamOp);
+end;
+
+function TCompressionStream.GetCompressionRate: Single;
+begin
+ if FZRec.total_in = 0 then
+ Result := 0
+ else
+ Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0;
+end;
+
+
+// TDecompressionStream
+
+constructor TDecompressionStream.Create(Source: TStream);
+begin
+ inherited Create(Source);
+ FZRec.next_in := FBuffer;
+ FZRec.avail_in := 0;
+ DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec)));
+end;
+
+destructor TDecompressionStream.Destroy;
+begin
+ FStrm.Seek(-FZRec.avail_in, 1);
+ inflateEnd(FZRec);
+ inherited Destroy;
+end;
+
+function TDecompressionStream.Read(var Buffer; Count: Longint): Longint;
+begin
+ FZRec.next_out := @Buffer;
+ FZRec.avail_out := Count;
+ if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
+ while (FZRec.avail_out > 0) do
+ begin
+ if FZRec.avail_in = 0 then
+ begin
+ FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));
+ if FZRec.avail_in = 0 then
+ begin
+ Result := Count - FZRec.avail_out;
+ Exit;
+ end;
+ FZRec.next_in := FBuffer;
+ FStrmPos := FStrm.Position;
+ Progress(Self);
+ end;
+ CCheck(inflate(FZRec, 0));
+ end;
+ Result := Count;
+end;
+
+function TDecompressionStream.Write(const Buffer; Count: Longint): Longint;
+begin
+ raise EDecompressionError.CreateRes(@sInvalidStreamOp);
+end;
+
+function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
+var
+ I: Integer;
+ Buf: array [0..4095] of Char;
+begin
+ if (Offset = 0) and (Origin = soFromBeginning) then
+ begin
+ DCheck(inflateReset(FZRec));
+ FZRec.next_in := FBuffer;
+ FZRec.avail_in := 0;
+ FStrm.Position := 0;
+ FStrmPos := 0;
+ end
+ else if ( (Offset >= 0) and (Origin = soFromCurrent)) or
+ ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then
+ begin
+ if Origin = soFromBeginning then Dec(Offset, FZRec.total_out);
+ if Offset > 0 then
+ begin
+ for I := 1 to Offset div sizeof(Buf) do
+ ReadBuffer(Buf, sizeof(Buf));
+ ReadBuffer(Buf, Offset mod sizeof(Buf));
+ end;
+ end
+ else
+ raise EDecompressionError.CreateRes(@sInvalidStreamOp);
+ Result := FZRec.total_out;
+end;
+
+
+end.
diff --git a/xs/src/png/zlib/contrib/delphi/ZLibConst.pas b/xs/src/png/zlib/contrib/delphi/ZLibConst.pas
new file mode 100644
index 000000000..cdfe13671
--- /dev/null
+++ b/xs/src/png/zlib/contrib/delphi/ZLibConst.pas
@@ -0,0 +1,11 @@
+unit ZLibConst;
+
+interface
+
+resourcestring
+ sTargetBufferTooSmall = 'ZLib error: target buffer may be too small';
+ sInvalidStreamOp = 'Invalid stream operation';
+
+implementation
+
+end.
diff --git a/xs/src/png/zlib/contrib/delphi/readme.txt b/xs/src/png/zlib/contrib/delphi/readme.txt
new file mode 100644
index 000000000..2dc9a8bba
--- /dev/null
+++ b/xs/src/png/zlib/contrib/delphi/readme.txt
@@ -0,0 +1,76 @@
+
+Overview
+========
+
+This directory contains an update to the ZLib interface unit,
+distributed by Borland as a Delphi supplemental component.
+
+The original ZLib unit is Copyright (c) 1997,99 Borland Corp.,
+and is based on zlib version 1.0.4. There are a series of bugs
+and security problems associated with that old zlib version, and
+we recommend the users to update their ZLib unit.
+
+
+Summary of modifications
+========================
+
+- Improved makefile, adapted to zlib version 1.2.1.
+
+- Some field types from TZStreamRec are changed from Integer to
+ Longint, for consistency with the zlib.h header, and for 64-bit
+ readiness.
+
+- The zlib_version constant is updated.
+
+- The new Z_RLE strategy has its corresponding symbolic constant.
+
+- The allocation and deallocation functions and function types
+ (TAlloc, TFree, zlibAllocMem and zlibFreeMem) are now cdecl,
+ and _malloc and _free are added as C RTL stubs. As a result,
+ the original C sources of zlib can be compiled out of the box,
+ and linked to the ZLib unit.
+
+
+Suggestions for improvements
+============================
+
+Currently, the ZLib unit provides only a limited wrapper around
+the zlib library, and much of the original zlib functionality is
+missing. Handling compressed file formats like ZIP/GZIP or PNG
+cannot be implemented without having this functionality.
+Applications that handle these formats are either using their own,
+duplicated code, or not using the ZLib unit at all.
+
+Here are a few suggestions:
+
+- Checksum class wrappers around adler32() and crc32(), similar
+ to the Java classes that implement the java.util.zip.Checksum
+ interface.
+
+- The ability to read and write raw deflate streams, without the
+ zlib stream header and trailer. Raw deflate streams are used
+ in the ZIP file format.
+
+- The ability to read and write gzip streams, used in the GZIP
+ file format, and normally produced by the gzip program.
+
+- The ability to select a different compression strategy, useful
+ to PNG and MNG image compression, and to multimedia compression
+ in general. Besides the compression level
+
+ TCompressionLevel = (clNone, clFastest, clDefault, clMax);
+
+ which, in fact, could have used the 'z' prefix and avoided
+ TColor-like symbols
+
+ TCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax);
+
+ there could be a compression strategy
+
+ TCompressionStrategy = (zsDefault, zsFiltered, zsHuffmanOnly, zsRle);
+
+- ZIP and GZIP stream handling via TStreams.
+
+
+--
+Cosmin Truta <cosmint@cs.ubbcluj.ro>
diff --git a/xs/src/png/zlib/contrib/delphi/zlibd32.mak b/xs/src/png/zlib/contrib/delphi/zlibd32.mak
new file mode 100644
index 000000000..9bb00b7cc
--- /dev/null
+++ b/xs/src/png/zlib/contrib/delphi/zlibd32.mak
@@ -0,0 +1,99 @@
+# Makefile for zlib
+# For use with Delphi and C++ Builder under Win32
+# Updated for zlib 1.2.x by Cosmin Truta
+
+# ------------ Borland C++ ------------
+
+# This project uses the Delphi (fastcall/register) calling convention:
+LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl
+
+CC = bcc32
+LD = bcc32
+AR = tlib
+# do not use "-pr" in CFLAGS
+CFLAGS = -a -d -k- -O2 $(LOC)
+LDFLAGS =
+
+
+# variables
+ZLIB_LIB = zlib.lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+ -del $(ZLIB_LIB)
+ $(AR) $(ZLIB_LIB) $(OBJP1)
+ $(AR) $(ZLIB_LIB) $(OBJP2)
+
+
+# testing
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+
+# cleanup
+clean:
+ -del *.obj
+ -del *.exe
+ -del *.lib
+ -del *.tds
+ -del zlib.bak
+ -del foo.gz
+
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib.build b/xs/src/png/zlib/contrib/dotzlib/DotZLib.build
new file mode 100644
index 000000000..e69630cec
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib.build
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<project name="DotZLib" default="build" basedir="./DotZLib">
+ <description>A .Net wrapper library around ZLib1.dll</description>
+
+ <property name="nunit.location" value="c:/program files/NUnit V2.1/bin" />
+ <property name="build.root" value="bin" />
+
+ <property name="debug" value="true" />
+ <property name="nunit" value="true" />
+
+ <property name="build.folder" value="${build.root}/debug/" if="${debug}" />
+ <property name="build.folder" value="${build.root}/release/" unless="${debug}" />
+
+ <target name="clean" description="Remove all generated files">
+ <delete dir="${build.root}" failonerror="false" />
+ </target>
+
+ <target name="build" description="compiles the source code">
+
+ <mkdir dir="${build.folder}" />
+ <csc target="library" output="${build.folder}DotZLib.dll" debug="${debug}">
+ <references basedir="${nunit.location}">
+ <includes if="${nunit}" name="nunit.framework.dll" />
+ </references>
+ <sources>
+ <includes name="*.cs" />
+ <excludes name="UnitTests.cs" unless="${nunit}" />
+ </sources>
+ <arg value="/d:nunit" if="${nunit}" />
+ </csc>
+ </target>
+
+</project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib.chm b/xs/src/png/zlib/contrib/dotzlib/DotZLib.chm
new file mode 100644
index 000000000..f214a444a
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib.chm
Binary files differ
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib.sln b/xs/src/png/zlib/contrib/dotzlib/DotZLib.sln
new file mode 100644
index 000000000..5d533d6bc
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET
+ {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET
+ {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET
+ {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs b/xs/src/png/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs
new file mode 100644
index 000000000..724c5347f
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs
@@ -0,0 +1,58 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("DotZLib")]
+[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Henrik Ravn")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.*")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+// (*) If no key is specified, the assembly is not signed.
+// (*) KeyName refers to a key that has been installed in the Crypto Service
+// Provider (CSP) on your machine. KeyFile refers to a file which contains
+// a key.
+// (*) If the KeyFile and the KeyName values are both specified, the
+// following processing occurs:
+// (1) If the KeyName can be found in the CSP, that key is used.
+// (2) If the KeyName does not exist and the KeyFile does exist, the key
+// in the KeyFile is installed into the CSP and used.
+// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+// When specifying the KeyFile, the location of the KeyFile should be
+// relative to the project output directory which is
+// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+// located in the project directory, you would specify the AssemblyKeyFile
+// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+// documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs b/xs/src/png/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs
new file mode 100644
index 000000000..b110dae6a
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs
@@ -0,0 +1,202 @@
+//
+// © Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+
+namespace DotZLib
+{
+ #region ChecksumGeneratorBase
+ /// <summary>
+ /// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s
+ /// </summary>
+ /// <example></example>
+ public abstract class ChecksumGeneratorBase : ChecksumGenerator
+ {
+ /// <summary>
+ /// The value of the current checksum
+ /// </summary>
+ protected uint _current;
+
+ /// <summary>
+ /// Initializes a new instance of the checksum generator base - the current checksum is
+ /// set to zero
+ /// </summary>
+ public ChecksumGeneratorBase()
+ {
+ _current = 0;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the checksum generator basewith a specified value
+ /// </summary>
+ /// <param name="initialValue">The value to set the current checksum to</param>
+ public ChecksumGeneratorBase(uint initialValue)
+ {
+ _current = initialValue;
+ }
+
+ /// <summary>
+ /// Resets the current checksum to zero
+ /// </summary>
+ public void Reset() { _current = 0; }
+
+ /// <summary>
+ /// Gets the current checksum value
+ /// </summary>
+ public uint Value { get { return _current; } }
+
+ /// <summary>
+ /// Updates the current checksum with part of an array of bytes
+ /// </summary>
+ /// <param name="data">The data to update the checksum with</param>
+ /// <param name="offset">Where in <c>data</c> to start updating</param>
+ /// <param name="count">The number of bytes from <c>data</c> to use</param>
+ /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
+ /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
+ /// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one.
+ /// This is therefore the only method a derived class has to implement</remarks>
+ public abstract void Update(byte[] data, int offset, int count);
+
+ /// <summary>
+ /// Updates the current checksum with an array of bytes.
+ /// </summary>
+ /// <param name="data">The data to update the checksum with</param>
+ public void Update(byte[] data)
+ {
+ Update(data, 0, data.Length);
+ }
+
+ /// <summary>
+ /// Updates the current checksum with the data from a string
+ /// </summary>
+ /// <param name="data">The string to update the checksum with</param>
+ /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
+ public void Update(string data)
+ {
+ Update(Encoding.UTF8.GetBytes(data));
+ }
+
+ /// <summary>
+ /// Updates the current checksum with the data from a string, using a specific encoding
+ /// </summary>
+ /// <param name="data">The string to update the checksum with</param>
+ /// <param name="encoding">The encoding to use</param>
+ public void Update(string data, Encoding encoding)
+ {
+ Update(encoding.GetBytes(data));
+ }
+
+ }
+ #endregion
+
+ #region CRC32
+ /// <summary>
+ /// Implements a CRC32 checksum generator
+ /// </summary>
+ public sealed class CRC32Checksum : ChecksumGeneratorBase
+ {
+ #region DLL imports
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern uint crc32(uint crc, int data, uint length);
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of the CRC32 checksum generator
+ /// </summary>
+ public CRC32Checksum() : base() {}
+
+ /// <summary>
+ /// Initializes a new instance of the CRC32 checksum generator with a specified value
+ /// </summary>
+ /// <param name="initialValue">The value to set the current checksum to</param>
+ public CRC32Checksum(uint initialValue) : base(initialValue) {}
+
+ /// <summary>
+ /// Updates the current checksum with part of an array of bytes
+ /// </summary>
+ /// <param name="data">The data to update the checksum with</param>
+ /// <param name="offset">Where in <c>data</c> to start updating</param>
+ /// <param name="count">The number of bytes from <c>data</c> to use</param>
+ /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
+ /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
+ public override void Update(byte[] data, int offset, int count)
+ {
+ if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+ if ((offset+count) > data.Length) throw new ArgumentException();
+ GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
+ try
+ {
+ _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
+ }
+ finally
+ {
+ hData.Free();
+ }
+ }
+
+ }
+ #endregion
+
+ #region Adler
+ /// <summary>
+ /// Implements a checksum generator that computes the Adler checksum on data
+ /// </summary>
+ public sealed class AdlerChecksum : ChecksumGeneratorBase
+ {
+ #region DLL imports
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern uint adler32(uint adler, int data, uint length);
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of the Adler checksum generator
+ /// </summary>
+ public AdlerChecksum() : base() {}
+
+ /// <summary>
+ /// Initializes a new instance of the Adler checksum generator with a specified value
+ /// </summary>
+ /// <param name="initialValue">The value to set the current checksum to</param>
+ public AdlerChecksum(uint initialValue) : base(initialValue) {}
+
+ /// <summary>
+ /// Updates the current checksum with part of an array of bytes
+ /// </summary>
+ /// <param name="data">The data to update the checksum with</param>
+ /// <param name="offset">Where in <c>data</c> to start updating</param>
+ /// <param name="count">The number of bytes from <c>data</c> to use</param>
+ /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
+ /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
+ public override void Update(byte[] data, int offset, int count)
+ {
+ if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+ if ((offset+count) > data.Length) throw new ArgumentException();
+ GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
+ try
+ {
+ _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
+ }
+ finally
+ {
+ hData.Free();
+ }
+ }
+
+ }
+ #endregion
+
+} \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs b/xs/src/png/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs
new file mode 100644
index 000000000..9c8d60195
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs
@@ -0,0 +1,83 @@
+//
+// © Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Diagnostics;
+
+namespace DotZLib
+{
+
+ /// <summary>
+ /// This class implements a circular buffer
+ /// </summary>
+ internal class CircularBuffer
+ {
+ #region Private data
+ private int _capacity;
+ private int _head;
+ private int _tail;
+ private int _size;
+ private byte[] _buffer;
+ #endregion
+
+ public CircularBuffer(int capacity)
+ {
+ Debug.Assert( capacity > 0 );
+ _buffer = new byte[capacity];
+ _capacity = capacity;
+ _head = 0;
+ _tail = 0;
+ _size = 0;
+ }
+
+ public int Size { get { return _size; } }
+
+ public int Put(byte[] source, int offset, int count)
+ {
+ Debug.Assert( count > 0 );
+ int trueCount = Math.Min(count, _capacity - Size);
+ for (int i = 0; i < trueCount; ++i)
+ _buffer[(_tail+i) % _capacity] = source[offset+i];
+ _tail += trueCount;
+ _tail %= _capacity;
+ _size += trueCount;
+ return trueCount;
+ }
+
+ public bool Put(byte b)
+ {
+ if (Size == _capacity) // no room
+ return false;
+ _buffer[_tail++] = b;
+ _tail %= _capacity;
+ ++_size;
+ return true;
+ }
+
+ public int Get(byte[] destination, int offset, int count)
+ {
+ int trueCount = Math.Min(count,Size);
+ for (int i = 0; i < trueCount; ++i)
+ destination[offset + i] = _buffer[(_head+i) % _capacity];
+ _head += trueCount;
+ _head %= _capacity;
+ _size -= trueCount;
+ return trueCount;
+ }
+
+ public int Get()
+ {
+ if (Size == 0)
+ return -1;
+
+ int result = (int)_buffer[_head++ % _capacity];
+ --_size;
+ return result;
+ }
+
+ }
+}
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib/CodecBase.cs b/xs/src/png/zlib/contrib/dotzlib/DotZLib/CodecBase.cs
new file mode 100644
index 000000000..b0eb78a02
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib/CodecBase.cs
@@ -0,0 +1,198 @@
+//
+// © Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace DotZLib
+{
+ /// <summary>
+ /// Implements the common functionality needed for all <see cref="Codec"/>s
+ /// </summary>
+ public abstract class CodecBase : Codec, IDisposable
+ {
+
+ #region Data members
+
+ /// <summary>
+ /// Instance of the internal zlib buffer structure that is
+ /// passed to all functions in the zlib dll
+ /// </summary>
+ internal ZStream _ztream = new ZStream();
+
+ /// <summary>
+ /// True if the object instance has been disposed, false otherwise
+ /// </summary>
+ protected bool _isDisposed = false;
+
+ /// <summary>
+ /// The size of the internal buffers
+ /// </summary>
+ protected const int kBufferSize = 16384;
+
+ private byte[] _outBuffer = new byte[kBufferSize];
+ private byte[] _inBuffer = new byte[kBufferSize];
+
+ private GCHandle _hInput;
+ private GCHandle _hOutput;
+
+ private uint _checksum = 0;
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of the <c>CodeBase</c> class.
+ /// </summary>
+ public CodecBase()
+ {
+ try
+ {
+ _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);
+ _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);
+ }
+ catch (Exception)
+ {
+ CleanUp(false);
+ throw;
+ }
+ }
+
+
+ #region Codec Members
+
+ /// <summary>
+ /// Occurs when more processed data are available.
+ /// </summary>
+ public event DataAvailableHandler DataAvailable;
+
+ /// <summary>
+ /// Fires the <see cref="DataAvailable"/> event
+ /// </summary>
+ protected void OnDataAvailable()
+ {
+ if (_ztream.total_out > 0)
+ {
+ if (DataAvailable != null)
+ DataAvailable( _outBuffer, 0, (int)_ztream.total_out);
+ resetOutput();
+ }
+ }
+
+ /// <summary>
+ /// Adds more data to the codec to be processed.
+ /// </summary>
+ /// <param name="data">Byte array containing the data to be added to the codec</param>
+ /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+ public void Add(byte[] data)
+ {
+ Add(data,0,data.Length);
+ }
+
+ /// <summary>
+ /// Adds more data to the codec to be processed.
+ /// </summary>
+ /// <param name="data">Byte array containing the data to be added to the codec</param>
+ /// <param name="offset">The index of the first byte to add from <c>data</c></param>
+ /// <param name="count">The number of bytes to add</param>
+ /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+ /// <remarks>This must be implemented by a derived class</remarks>
+ public abstract void Add(byte[] data, int offset, int count);
+
+ /// <summary>
+ /// Finishes up any pending data that needs to be processed and handled.
+ /// </summary>
+ /// <remarks>This must be implemented by a derived class</remarks>
+ public abstract void Finish();
+
+ /// <summary>
+ /// Gets the checksum of the data that has been added so far
+ /// </summary>
+ public uint Checksum { get { return _checksum; } }
+
+ #endregion
+
+ #region Destructor & IDisposable stuff
+
+ /// <summary>
+ /// Destroys this instance
+ /// </summary>
+ ~CodecBase()
+ {
+ CleanUp(false);
+ }
+
+ /// <summary>
+ /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class
+ /// </summary>
+ public void Dispose()
+ {
+ CleanUp(true);
+ }
+
+ /// <summary>
+ /// Performs any codec specific cleanup
+ /// </summary>
+ /// <remarks>This must be implemented by a derived class</remarks>
+ protected abstract void CleanUp();
+
+ // performs the release of the handles and calls the dereived CleanUp()
+ private void CleanUp(bool isDisposing)
+ {
+ if (!_isDisposed)
+ {
+ CleanUp();
+ if (_hInput.IsAllocated)
+ _hInput.Free();
+ if (_hOutput.IsAllocated)
+ _hOutput.Free();
+
+ _isDisposed = true;
+ }
+ }
+
+
+ #endregion
+
+ #region Helper methods
+
+ /// <summary>
+ /// Copies a number of bytes to the internal codec buffer - ready for proccesing
+ /// </summary>
+ /// <param name="data">The byte array that contains the data to copy</param>
+ /// <param name="startIndex">The index of the first byte to copy</param>
+ /// <param name="count">The number of bytes to copy from <c>data</c></param>
+ protected void copyInput(byte[] data, int startIndex, int count)
+ {
+ Array.Copy(data, startIndex, _inBuffer,0, count);
+ _ztream.next_in = _hInput.AddrOfPinnedObject();
+ _ztream.total_in = 0;
+ _ztream.avail_in = (uint)count;
+
+ }
+
+ /// <summary>
+ /// Resets the internal output buffers to a known state - ready for processing
+ /// </summary>
+ protected void resetOutput()
+ {
+ _ztream.total_out = 0;
+ _ztream.avail_out = kBufferSize;
+ _ztream.next_out = _hOutput.AddrOfPinnedObject();
+ }
+
+ /// <summary>
+ /// Updates the running checksum property
+ /// </summary>
+ /// <param name="newSum">The new checksum value</param>
+ protected void setChecksum(uint newSum)
+ {
+ _checksum = newSum;
+ }
+ #endregion
+
+ }
+}
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib/Deflater.cs b/xs/src/png/zlib/contrib/dotzlib/DotZLib/Deflater.cs
new file mode 100644
index 000000000..9039f41f6
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib/Deflater.cs
@@ -0,0 +1,106 @@
+//
+// © Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace DotZLib
+{
+
+ /// <summary>
+ /// Implements a data compressor, using the deflate algorithm in the ZLib dll
+ /// </summary>
+ public sealed class Deflater : CodecBase
+ {
+ #region Dll imports
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
+ private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size);
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern int deflate(ref ZStream sz, int flush);
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern int deflateReset(ref ZStream sz);
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern int deflateEnd(ref ZStream sz);
+ #endregion
+
+ /// <summary>
+ /// Constructs an new instance of the <c>Deflater</c>
+ /// </summary>
+ /// <param name="level">The compression level to use for this <c>Deflater</c></param>
+ public Deflater(CompressLevel level) : base()
+ {
+ int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream));
+ if (retval != 0)
+ throw new ZLibException(retval, "Could not initialize deflater");
+
+ resetOutput();
+ }
+
+ /// <summary>
+ /// Adds more data to the codec to be processed.
+ /// </summary>
+ /// <param name="data">Byte array containing the data to be added to the codec</param>
+ /// <param name="offset">The index of the first byte to add from <c>data</c></param>
+ /// <param name="count">The number of bytes to add</param>
+ /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+ public override void Add(byte[] data, int offset, int count)
+ {
+ if (data == null) throw new ArgumentNullException();
+ if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+ if ((offset+count) > data.Length) throw new ArgumentException();
+
+ int total = count;
+ int inputIndex = offset;
+ int err = 0;
+
+ while (err >= 0 && inputIndex < total)
+ {
+ copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
+ while (err >= 0 && _ztream.avail_in > 0)
+ {
+ err = deflate(ref _ztream, (int)FlushTypes.None);
+ if (err == 0)
+ while (_ztream.avail_out == 0)
+ {
+ OnDataAvailable();
+ err = deflate(ref _ztream, (int)FlushTypes.None);
+ }
+ inputIndex += (int)_ztream.total_in;
+ }
+ }
+ setChecksum( _ztream.adler );
+ }
+
+
+ /// <summary>
+ /// Finishes up any pending data that needs to be processed and handled.
+ /// </summary>
+ public override void Finish()
+ {
+ int err;
+ do
+ {
+ err = deflate(ref _ztream, (int)FlushTypes.Finish);
+ OnDataAvailable();
+ }
+ while (err == 0);
+ setChecksum( _ztream.adler );
+ deflateReset(ref _ztream);
+ resetOutput();
+ }
+
+ /// <summary>
+ /// Closes the internal zlib deflate stream
+ /// </summary>
+ protected override void CleanUp() { deflateEnd(ref _ztream); }
+
+ }
+}
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib/DotZLib.cs b/xs/src/png/zlib/contrib/dotzlib/DotZLib/DotZLib.cs
new file mode 100644
index 000000000..90c7c3b38
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib/DotZLib.cs
@@ -0,0 +1,288 @@
+//
+// © Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+
+
+namespace DotZLib
+{
+
+ #region Internal types
+
+ /// <summary>
+ /// Defines constants for the various flush types used with zlib
+ /// </summary>
+ internal enum FlushTypes
+ {
+ None, Partial, Sync, Full, Finish, Block
+ }
+
+ #region ZStream structure
+ // internal mapping of the zlib zstream structure for marshalling
+ [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)]
+ internal struct ZStream
+ {
+ public IntPtr next_in;
+ public uint avail_in;
+ public uint total_in;
+
+ public IntPtr next_out;
+ public uint avail_out;
+ public uint total_out;
+
+ [MarshalAs(UnmanagedType.LPStr)]
+ string msg;
+ uint state;
+
+ uint zalloc;
+ uint zfree;
+ uint opaque;
+
+ int data_type;
+ public uint adler;
+ uint reserved;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Public enums
+ /// <summary>
+ /// Defines constants for the available compression levels in zlib
+ /// </summary>
+ public enum CompressLevel : int
+ {
+ /// <summary>
+ /// The default compression level with a reasonable compromise between compression and speed
+ /// </summary>
+ Default = -1,
+ /// <summary>
+ /// No compression at all. The data are passed straight through.
+ /// </summary>
+ None = 0,
+ /// <summary>
+ /// The maximum compression rate available.
+ /// </summary>
+ Best = 9,
+ /// <summary>
+ /// The fastest available compression level.
+ /// </summary>
+ Fastest = 1
+ }
+ #endregion
+
+ #region Exception classes
+ /// <summary>
+ /// The exception that is thrown when an error occurs on the zlib dll
+ /// </summary>
+ public class ZLibException : ApplicationException
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
+ /// error message and error code
+ /// </summary>
+ /// <param name="errorCode">The zlib error code that caused the exception</param>
+ /// <param name="msg">A message that (hopefully) describes the error</param>
+ public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg))
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
+ /// error code
+ /// </summary>
+ /// <param name="errorCode">The zlib error code that caused the exception</param>
+ public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode))
+ {
+ }
+ }
+ #endregion
+
+ #region Interfaces
+
+ /// <summary>
+ /// Declares methods and properties that enables a running checksum to be calculated
+ /// </summary>
+ public interface ChecksumGenerator
+ {
+ /// <summary>
+ /// Gets the current value of the checksum
+ /// </summary>
+ uint Value { get; }
+
+ /// <summary>
+ /// Clears the current checksum to 0
+ /// </summary>
+ void Reset();
+
+ /// <summary>
+ /// Updates the current checksum with an array of bytes
+ /// </summary>
+ /// <param name="data">The data to update the checksum with</param>
+ void Update(byte[] data);
+
+ /// <summary>
+ /// Updates the current checksum with part of an array of bytes
+ /// </summary>
+ /// <param name="data">The data to update the checksum with</param>
+ /// <param name="offset">Where in <c>data</c> to start updating</param>
+ /// <param name="count">The number of bytes from <c>data</c> to use</param>
+ /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
+ /// <exception cref="ArgumentNullException"><c>data</c> is a null reference</exception>
+ /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
+ void Update(byte[] data, int offset, int count);
+
+ /// <summary>
+ /// Updates the current checksum with the data from a string
+ /// </summary>
+ /// <param name="data">The string to update the checksum with</param>
+ /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
+ void Update(string data);
+
+ /// <summary>
+ /// Updates the current checksum with the data from a string, using a specific encoding
+ /// </summary>
+ /// <param name="data">The string to update the checksum with</param>
+ /// <param name="encoding">The encoding to use</param>
+ void Update(string data, Encoding encoding);
+ }
+
+
+ /// <summary>
+ /// Represents the method that will be called from a codec when new data
+ /// are available.
+ /// </summary>
+ /// <paramref name="data">The byte array containing the processed data</paramref>
+ /// <paramref name="startIndex">The index of the first processed byte in <c>data</c></paramref>
+ /// <paramref name="count">The number of processed bytes available</paramref>
+ /// <remarks>On return from this method, the data may be overwritten, so grab it while you can.
+ /// You cannot assume that startIndex will be zero.
+ /// </remarks>
+ public delegate void DataAvailableHandler(byte[] data, int startIndex, int count);
+
+ /// <summary>
+ /// Declares methods and events for implementing compressors/decompressors
+ /// </summary>
+ public interface Codec
+ {
+ /// <summary>
+ /// Occurs when more processed data are available.
+ /// </summary>
+ event DataAvailableHandler DataAvailable;
+
+ /// <summary>
+ /// Adds more data to the codec to be processed.
+ /// </summary>
+ /// <param name="data">Byte array containing the data to be added to the codec</param>
+ /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+ void Add(byte[] data);
+
+ /// <summary>
+ /// Adds more data to the codec to be processed.
+ /// </summary>
+ /// <param name="data">Byte array containing the data to be added to the codec</param>
+ /// <param name="offset">The index of the first byte to add from <c>data</c></param>
+ /// <param name="count">The number of bytes to add</param>
+ /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+ void Add(byte[] data, int offset, int count);
+
+ /// <summary>
+ /// Finishes up any pending data that needs to be processed and handled.
+ /// </summary>
+ void Finish();
+
+ /// <summary>
+ /// Gets the checksum of the data that has been added so far
+ /// </summary>
+ uint Checksum { get; }
+
+
+ }
+
+ #endregion
+
+ #region Classes
+ /// <summary>
+ /// Encapsulates general information about the ZLib library
+ /// </summary>
+ public class Info
+ {
+ #region DLL imports
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern uint zlibCompileFlags();
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern string zlibVersion();
+ #endregion
+
+ #region Private stuff
+ private uint _flags;
+
+ // helper function that unpacks a bitsize mask
+ private static int bitSize(uint bits)
+ {
+ switch (bits)
+ {
+ case 0: return 16;
+ case 1: return 32;
+ case 2: return 64;
+ }
+ return -1;
+ }
+ #endregion
+
+ /// <summary>
+ /// Constructs an instance of the <c>Info</c> class.
+ /// </summary>
+ public Info()
+ {
+ _flags = zlibCompileFlags();
+ }
+
+ /// <summary>
+ /// True if the library is compiled with debug info
+ /// </summary>
+ public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } }
+
+ /// <summary>
+ /// True if the library is compiled with assembly optimizations
+ /// </summary>
+ public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } }
+
+ /// <summary>
+ /// Gets the size of the unsigned int that was compiled into Zlib
+ /// </summary>
+ public int SizeOfUInt { get { return bitSize(_flags & 3); } }
+
+ /// <summary>
+ /// Gets the size of the unsigned long that was compiled into Zlib
+ /// </summary>
+ public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } }
+
+ /// <summary>
+ /// Gets the size of the pointers that were compiled into Zlib
+ /// </summary>
+ public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } }
+
+ /// <summary>
+ /// Gets the size of the z_off_t type that was compiled into Zlib
+ /// </summary>
+ public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } }
+
+ /// <summary>
+ /// Gets the version of ZLib as a string, e.g. "1.2.1"
+ /// </summary>
+ public static string Version { get { return zlibVersion(); } }
+ }
+
+ #endregion
+
+}
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj b/xs/src/png/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj
new file mode 100644
index 000000000..dea7fb16a
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj
@@ -0,0 +1,141 @@
+<VisualStudioProject>
+ <CSHARP
+ ProjectType = "Local"
+ ProductVersion = "7.10.3077"
+ SchemaVersion = "2.0"
+ ProjectGuid = "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
+ >
+ <Build>
+ <Settings
+ ApplicationIcon = ""
+ AssemblyKeyContainerName = ""
+ AssemblyName = "DotZLib"
+ AssemblyOriginatorKeyFile = ""
+ DefaultClientScript = "JScript"
+ DefaultHTMLPageLayout = "Grid"
+ DefaultTargetSchema = "IE50"
+ DelaySign = "false"
+ OutputType = "Library"
+ PreBuildEvent = ""
+ PostBuildEvent = ""
+ RootNamespace = "DotZLib"
+ RunPostBuildEvent = "OnBuildSuccess"
+ StartupObject = ""
+ >
+ <Config
+ Name = "Debug"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "DEBUG;TRACE"
+ DocumentationFile = "docs\DotZLib.xml"
+ DebugSymbols = "true"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = "1591"
+ Optimize = "false"
+ OutputPath = "bin\Debug\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ <Config
+ Name = "Release"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "TRACE"
+ DocumentationFile = "docs\DotZLib.xml"
+ DebugSymbols = "false"
+ FileAlignment = "4096"
+ IncrementalBuild = "false"
+ NoStdLib = "false"
+ NoWarn = ""
+ Optimize = "true"
+ OutputPath = "bin\Release\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ </Settings>
+ <References>
+ <Reference
+ Name = "System"
+ AssemblyName = "System"
+ HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.dll"
+ />
+ <Reference
+ Name = "System.Data"
+ AssemblyName = "System.Data"
+ HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
+ />
+ <Reference
+ Name = "System.XML"
+ AssemblyName = "System.Xml"
+ HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
+ />
+ <Reference
+ Name = "nunit.framework"
+ AssemblyName = "nunit.framework"
+ HintPath = "E:\apps\NUnit V2.1\\bin\nunit.framework.dll"
+ AssemblyFolderKey = "hklm\dn\nunit.framework"
+ />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File
+ RelPath = "AssemblyInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "ChecksumImpl.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "CircularBuffer.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "CodecBase.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Deflater.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "DotZLib.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "GZipStream.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "Inflater.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "UnitTests.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ </Include>
+ </Files>
+ </CSHARP>
+</VisualStudioProject>
+
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib/GZipStream.cs b/xs/src/png/zlib/contrib/dotzlib/DotZLib/GZipStream.cs
new file mode 100644
index 000000000..f0eada1d2
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib/GZipStream.cs
@@ -0,0 +1,301 @@
+//
+// © Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace DotZLib
+{
+ /// <summary>
+ /// Implements a compressed <see cref="Stream"/>, in GZip (.gz) format.
+ /// </summary>
+ public class GZipStream : Stream, IDisposable
+ {
+ #region Dll Imports
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
+ private static extern IntPtr gzopen(string name, string mode);
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern int gzclose(IntPtr gzFile);
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern int gzwrite(IntPtr gzFile, int data, int length);
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern int gzread(IntPtr gzFile, int data, int length);
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern int gzgetc(IntPtr gzFile);
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern int gzputc(IntPtr gzFile, int c);
+
+ #endregion
+
+ #region Private data
+ private IntPtr _gzFile;
+ private bool _isDisposed = false;
+ private bool _isWriting;
+ #endregion
+
+ #region Constructors
+ /// <summary>
+ /// Creates a new file as a writeable GZipStream
+ /// </summary>
+ /// <param name="fileName">The name of the compressed file to create</param>
+ /// <param name="level">The compression level to use when adding data</param>
+ /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
+ public GZipStream(string fileName, CompressLevel level)
+ {
+ _isWriting = true;
+ _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level));
+ if (_gzFile == IntPtr.Zero)
+ throw new ZLibException(-1, "Could not open " + fileName);
+ }
+
+ /// <summary>
+ /// Opens an existing file as a readable GZipStream
+ /// </summary>
+ /// <param name="fileName">The name of the file to open</param>
+ /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
+ public GZipStream(string fileName)
+ {
+ _isWriting = false;
+ _gzFile = gzopen(fileName, "rb");
+ if (_gzFile == IntPtr.Zero)
+ throw new ZLibException(-1, "Could not open " + fileName);
+
+ }
+ #endregion
+
+ #region Access properties
+ /// <summary>
+ /// Returns true of this stream can be read from, false otherwise
+ /// </summary>
+ public override bool CanRead
+ {
+ get
+ {
+ return !_isWriting;
+ }
+ }
+
+
+ /// <summary>
+ /// Returns false.
+ /// </summary>
+ public override bool CanSeek
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Returns true if this tsream is writeable, false otherwise
+ /// </summary>
+ public override bool CanWrite
+ {
+ get
+ {
+ return _isWriting;
+ }
+ }
+ #endregion
+
+ #region Destructor & IDispose stuff
+
+ /// <summary>
+ /// Destroys this instance
+ /// </summary>
+ ~GZipStream()
+ {
+ cleanUp(false);
+ }
+
+ /// <summary>
+ /// Closes the external file handle
+ /// </summary>
+ public void Dispose()
+ {
+ cleanUp(true);
+ }
+
+ // Does the actual closing of the file handle.
+ private void cleanUp(bool isDisposing)
+ {
+ if (!_isDisposed)
+ {
+ gzclose(_gzFile);
+ _isDisposed = true;
+ }
+ }
+ #endregion
+
+ #region Basic reading and writing
+ /// <summary>
+ /// Attempts to read a number of bytes from the stream.
+ /// </summary>
+ /// <param name="buffer">The destination data buffer</param>
+ /// <param name="offset">The index of the first destination byte in <c>buffer</c></param>
+ /// <param name="count">The number of bytes requested</param>
+ /// <returns>The number of bytes read</returns>
+ /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
+ /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
+ /// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is &gt; buffer.Length</exception>
+ /// <exception cref="NotSupportedException">If this stream is not readable.</exception>
+ /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ if (!CanRead) throw new NotSupportedException();
+ if (buffer == null) throw new ArgumentNullException();
+ if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+ if ((offset+count) > buffer.Length) throw new ArgumentException();
+ if (_isDisposed) throw new ObjectDisposedException("GZipStream");
+
+ GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+ int result;
+ try
+ {
+ result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
+ if (result < 0)
+ throw new IOException();
+ }
+ finally
+ {
+ h.Free();
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Attempts to read a single byte from the stream.
+ /// </summary>
+ /// <returns>The byte that was read, or -1 in case of error or End-Of-File</returns>
+ public override int ReadByte()
+ {
+ if (!CanRead) throw new NotSupportedException();
+ if (_isDisposed) throw new ObjectDisposedException("GZipStream");
+ return gzgetc(_gzFile);
+ }
+
+ /// <summary>
+ /// Writes a number of bytes to the stream
+ /// </summary>
+ /// <param name="buffer"></param>
+ /// <param name="offset"></param>
+ /// <param name="count"></param>
+ /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
+ /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
+ /// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is &gt; buffer.Length</exception>
+ /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
+ /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ if (!CanWrite) throw new NotSupportedException();
+ if (buffer == null) throw new ArgumentNullException();
+ if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+ if ((offset+count) > buffer.Length) throw new ArgumentException();
+ if (_isDisposed) throw new ObjectDisposedException("GZipStream");
+
+ GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+ try
+ {
+ int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
+ if (result < 0)
+ throw new IOException();
+ }
+ finally
+ {
+ h.Free();
+ }
+ }
+
+ /// <summary>
+ /// Writes a single byte to the stream
+ /// </summary>
+ /// <param name="value">The byte to add to the stream.</param>
+ /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
+ /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
+ public override void WriteByte(byte value)
+ {
+ if (!CanWrite) throw new NotSupportedException();
+ if (_isDisposed) throw new ObjectDisposedException("GZipStream");
+
+ int result = gzputc(_gzFile, (int)value);
+ if (result < 0)
+ throw new IOException();
+ }
+ #endregion
+
+ #region Position & length stuff
+ /// <summary>
+ /// Not supported.
+ /// </summary>
+ /// <param name="value"></param>
+ /// <exception cref="NotSupportedException">Always thrown</exception>
+ public override void SetLength(long value)
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Not suppported.
+ /// </summary>
+ /// <param name="offset"></param>
+ /// <param name="origin"></param>
+ /// <returns></returns>
+ /// <exception cref="NotSupportedException">Always thrown</exception>
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ throw new NotSupportedException();
+ }
+
+ /// <summary>
+ /// Flushes the <c>GZipStream</c>.
+ /// </summary>
+ /// <remarks>In this implementation, this method does nothing. This is because excessive
+ /// flushing may degrade the achievable compression rates.</remarks>
+ public override void Flush()
+ {
+ // left empty on purpose
+ }
+
+ /// <summary>
+ /// Gets/sets the current position in the <c>GZipStream</c>. Not suppported.
+ /// </summary>
+ /// <remarks>In this implementation this property is not supported</remarks>
+ /// <exception cref="NotSupportedException">Always thrown</exception>
+ public override long Position
+ {
+ get
+ {
+ throw new NotSupportedException();
+ }
+ set
+ {
+ throw new NotSupportedException();
+ }
+ }
+
+ /// <summary>
+ /// Gets the size of the stream. Not suppported.
+ /// </summary>
+ /// <remarks>In this implementation this property is not supported</remarks>
+ /// <exception cref="NotSupportedException">Always thrown</exception>
+ public override long Length
+ {
+ get
+ {
+ throw new NotSupportedException();
+ }
+ }
+ #endregion
+ }
+}
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib/Inflater.cs b/xs/src/png/zlib/contrib/dotzlib/DotZLib/Inflater.cs
new file mode 100644
index 000000000..d295f2680
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib/Inflater.cs
@@ -0,0 +1,105 @@
+//
+// © Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace DotZLib
+{
+
+ /// <summary>
+ /// Implements a data decompressor, using the inflate algorithm in the ZLib dll
+ /// </summary>
+ public class Inflater : CodecBase
+ {
+ #region Dll imports
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
+ private static extern int inflateInit_(ref ZStream sz, string vs, int size);
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern int inflate(ref ZStream sz, int flush);
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern int inflateReset(ref ZStream sz);
+
+ [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+ private static extern int inflateEnd(ref ZStream sz);
+ #endregion
+
+ /// <summary>
+ /// Constructs an new instance of the <c>Inflater</c>
+ /// </summary>
+ public Inflater() : base()
+ {
+ int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream));
+ if (retval != 0)
+ throw new ZLibException(retval, "Could not initialize inflater");
+
+ resetOutput();
+ }
+
+
+ /// <summary>
+ /// Adds more data to the codec to be processed.
+ /// </summary>
+ /// <param name="data">Byte array containing the data to be added to the codec</param>
+ /// <param name="offset">The index of the first byte to add from <c>data</c></param>
+ /// <param name="count">The number of bytes to add</param>
+ /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+ public override void Add(byte[] data, int offset, int count)
+ {
+ if (data == null) throw new ArgumentNullException();
+ if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+ if ((offset+count) > data.Length) throw new ArgumentException();
+
+ int total = count;
+ int inputIndex = offset;
+ int err = 0;
+
+ while (err >= 0 && inputIndex < total)
+ {
+ copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
+ err = inflate(ref _ztream, (int)FlushTypes.None);
+ if (err == 0)
+ while (_ztream.avail_out == 0)
+ {
+ OnDataAvailable();
+ err = inflate(ref _ztream, (int)FlushTypes.None);
+ }
+
+ inputIndex += (int)_ztream.total_in;
+ }
+ setChecksum( _ztream.adler );
+ }
+
+
+ /// <summary>
+ /// Finishes up any pending data that needs to be processed and handled.
+ /// </summary>
+ public override void Finish()
+ {
+ int err;
+ do
+ {
+ err = inflate(ref _ztream, (int)FlushTypes.Finish);
+ OnDataAvailable();
+ }
+ while (err == 0);
+ setChecksum( _ztream.adler );
+ inflateReset(ref _ztream);
+ resetOutput();
+ }
+
+ /// <summary>
+ /// Closes the internal zlib inflate stream
+ /// </summary>
+ protected override void CleanUp() { inflateEnd(ref _ztream); }
+
+
+ }
+}
diff --git a/xs/src/png/zlib/contrib/dotzlib/DotZLib/UnitTests.cs b/xs/src/png/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
new file mode 100644
index 000000000..6d8aebb79
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
@@ -0,0 +1,274 @@
+//
+// © Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Collections;
+using System.IO;
+
+// uncomment the define below to include unit tests
+//#define nunit
+#if nunit
+using NUnit.Framework;
+
+// Unit tests for the DotZLib class library
+// ----------------------------------------
+//
+// Use this with NUnit 2 from http://www.nunit.org
+//
+
+namespace DotZLibTests
+{
+ using DotZLib;
+
+ // helper methods
+ internal class Utils
+ {
+ public static bool byteArrEqual( byte[] lhs, byte[] rhs )
+ {
+ if (lhs.Length != rhs.Length)
+ return false;
+ for (int i = lhs.Length-1; i >= 0; --i)
+ if (lhs[i] != rhs[i])
+ return false;
+ return true;
+ }
+
+ }
+
+
+ [TestFixture]
+ public class CircBufferTests
+ {
+ #region Circular buffer tests
+ [Test]
+ public void SinglePutGet()
+ {
+ CircularBuffer buf = new CircularBuffer(10);
+ Assert.AreEqual( 0, buf.Size );
+ Assert.AreEqual( -1, buf.Get() );
+
+ Assert.IsTrue(buf.Put( 1 ));
+ Assert.AreEqual( 1, buf.Size );
+ Assert.AreEqual( 1, buf.Get() );
+ Assert.AreEqual( 0, buf.Size );
+ Assert.AreEqual( -1, buf.Get() );
+ }
+
+ [Test]
+ public void BlockPutGet()
+ {
+ CircularBuffer buf = new CircularBuffer(10);
+ byte[] arr = {1,2,3,4,5,6,7,8,9,10};
+ Assert.AreEqual( 10, buf.Put(arr,0,10) );
+ Assert.AreEqual( 10, buf.Size );
+ Assert.IsFalse( buf.Put(11) );
+ Assert.AreEqual( 1, buf.Get() );
+ Assert.IsTrue( buf.Put(11) );
+
+ byte[] arr2 = (byte[])arr.Clone();
+ Assert.AreEqual( 9, buf.Get(arr2,1,9) );
+ Assert.IsTrue( Utils.byteArrEqual(arr,arr2) );
+ }
+
+ #endregion
+ }
+
+ [TestFixture]
+ public class ChecksumTests
+ {
+ #region CRC32 Tests
+ [Test]
+ public void CRC32_Null()
+ {
+ CRC32Checksum crc32 = new CRC32Checksum();
+ Assert.AreEqual( 0, crc32.Value );
+
+ crc32 = new CRC32Checksum(1);
+ Assert.AreEqual( 1, crc32.Value );
+
+ crc32 = new CRC32Checksum(556);
+ Assert.AreEqual( 556, crc32.Value );
+ }
+
+ [Test]
+ public void CRC32_Data()
+ {
+ CRC32Checksum crc32 = new CRC32Checksum();
+ byte[] data = { 1,2,3,4,5,6,7 };
+ crc32.Update(data);
+ Assert.AreEqual( 0x70e46888, crc32.Value );
+
+ crc32 = new CRC32Checksum();
+ crc32.Update("penguin");
+ Assert.AreEqual( 0x0e5c1a120, crc32.Value );
+
+ crc32 = new CRC32Checksum(1);
+ crc32.Update("penguin");
+ Assert.AreEqual(0x43b6aa94, crc32.Value);
+
+ }
+ #endregion
+
+ #region Adler tests
+
+ [Test]
+ public void Adler_Null()
+ {
+ AdlerChecksum adler = new AdlerChecksum();
+ Assert.AreEqual(0, adler.Value);
+
+ adler = new AdlerChecksum(1);
+ Assert.AreEqual( 1, adler.Value );
+
+ adler = new AdlerChecksum(556);
+ Assert.AreEqual( 556, adler.Value );
+ }
+
+ [Test]
+ public void Adler_Data()
+ {
+ AdlerChecksum adler = new AdlerChecksum(1);
+ byte[] data = { 1,2,3,4,5,6,7 };
+ adler.Update(data);
+ Assert.AreEqual( 0x5b001d, adler.Value );
+
+ adler = new AdlerChecksum();
+ adler.Update("penguin");
+ Assert.AreEqual(0x0bcf02f6, adler.Value );
+
+ adler = new AdlerChecksum(1);
+ adler.Update("penguin");
+ Assert.AreEqual(0x0bd602f7, adler.Value);
+
+ }
+ #endregion
+ }
+
+ [TestFixture]
+ public class InfoTests
+ {
+ #region Info tests
+ [Test]
+ public void Info_Version()
+ {
+ Info info = new Info();
+ Assert.AreEqual("1.2.11", Info.Version);
+ Assert.AreEqual(32, info.SizeOfUInt);
+ Assert.AreEqual(32, info.SizeOfULong);
+ Assert.AreEqual(32, info.SizeOfPointer);
+ Assert.AreEqual(32, info.SizeOfOffset);
+ }
+ #endregion
+ }
+
+ [TestFixture]
+ public class DeflateInflateTests
+ {
+ #region Deflate tests
+ [Test]
+ public void Deflate_Init()
+ {
+ using (Deflater def = new Deflater(CompressLevel.Default))
+ {
+ }
+ }
+
+ private ArrayList compressedData = new ArrayList();
+ private uint adler1;
+
+ private ArrayList uncompressedData = new ArrayList();
+ private uint adler2;
+
+ public void CDataAvail(byte[] data, int startIndex, int count)
+ {
+ for (int i = 0; i < count; ++i)
+ compressedData.Add(data[i+startIndex]);
+ }
+
+ [Test]
+ public void Deflate_Compress()
+ {
+ compressedData.Clear();
+
+ byte[] testData = new byte[35000];
+ for (int i = 0; i < testData.Length; ++i)
+ testData[i] = 5;
+
+ using (Deflater def = new Deflater((CompressLevel)5))
+ {
+ def.DataAvailable += new DataAvailableHandler(CDataAvail);
+ def.Add(testData);
+ def.Finish();
+ adler1 = def.Checksum;
+ }
+ }
+ #endregion
+
+ #region Inflate tests
+ [Test]
+ public void Inflate_Init()
+ {
+ using (Inflater inf = new Inflater())
+ {
+ }
+ }
+
+ private void DDataAvail(byte[] data, int startIndex, int count)
+ {
+ for (int i = 0; i < count; ++i)
+ uncompressedData.Add(data[i+startIndex]);
+ }
+
+ [Test]
+ public void Inflate_Expand()
+ {
+ uncompressedData.Clear();
+
+ using (Inflater inf = new Inflater())
+ {
+ inf.DataAvailable += new DataAvailableHandler(DDataAvail);
+ inf.Add((byte[])compressedData.ToArray(typeof(byte)));
+ inf.Finish();
+ adler2 = inf.Checksum;
+ }
+ Assert.AreEqual( adler1, adler2 );
+ }
+ #endregion
+ }
+
+ [TestFixture]
+ public class GZipStreamTests
+ {
+ #region GZipStream test
+ [Test]
+ public void GZipStream_WriteRead()
+ {
+ using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best))
+ {
+ BinaryWriter writer = new BinaryWriter(gzOut);
+ writer.Write("hi there");
+ writer.Write(Math.PI);
+ writer.Write(42);
+ }
+
+ using (GZipStream gzIn = new GZipStream("gzstream.gz"))
+ {
+ BinaryReader reader = new BinaryReader(gzIn);
+ string s = reader.ReadString();
+ Assert.AreEqual("hi there",s);
+ double d = reader.ReadDouble();
+ Assert.AreEqual(Math.PI, d);
+ int i = reader.ReadInt32();
+ Assert.AreEqual(42,i);
+ }
+
+ }
+ #endregion
+ }
+}
+
+#endif
diff --git a/xs/src/png/zlib/contrib/dotzlib/LICENSE_1_0.txt b/xs/src/png/zlib/contrib/dotzlib/LICENSE_1_0.txt
new file mode 100644
index 000000000..127a5bc39
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/LICENSE_1_0.txt
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/dotzlib/readme.txt b/xs/src/png/zlib/contrib/dotzlib/readme.txt
new file mode 100644
index 000000000..4d8c2dd93
--- /dev/null
+++ b/xs/src/png/zlib/contrib/dotzlib/readme.txt
@@ -0,0 +1,58 @@
+This directory contains a .Net wrapper class library for the ZLib1.dll
+
+The wrapper includes support for inflating/deflating memory buffers,
+.Net streaming wrappers for the gz streams part of zlib, and wrappers
+for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples.
+
+Directory structure:
+--------------------
+
+LICENSE_1_0.txt - License file.
+readme.txt - This file.
+DotZLib.chm - Class library documentation
+DotZLib.build - NAnt build file
+DotZLib.sln - Microsoft Visual Studio 2003 solution file
+
+DotZLib\*.cs - Source files for the class library
+
+Unit tests:
+-----------
+The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher.
+To include unit tests in the build, define nunit before building.
+
+
+Build instructions:
+-------------------
+
+1. Using Visual Studio.Net 2003:
+ Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll)
+ will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on
+ you are building the release or debug version of the library. Check
+ DotZLib/UnitTests.cs for instructions on how to include unit tests in the
+ build.
+
+2. Using NAnt:
+ Open a command prompt with access to the build environment and run nant
+ in the same directory as the DotZLib.build file.
+ You can define 2 properties on the nant command-line to control the build:
+ debug={true|false} to toggle between release/debug builds (default=true).
+ nunit={true|false} to include or esclude unit tests (default=true).
+ Also the target clean will remove binaries.
+ Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release
+ or ./DotZLib/bin/debug, depending on whether you are building the release
+ or debug version of the library.
+
+ Examples:
+ nant -D:debug=false -D:nunit=false
+ will build a release mode version of the library without unit tests.
+ nant
+ will build a debug version of the library with unit tests
+ nant clean
+ will remove all previously built files.
+
+
+---------------------------------
+Copyright (c) Henrik Ravn 2004
+
+Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
diff --git a/xs/src/png/zlib/contrib/gcc_gvmat64/gvmat64.S b/xs/src/png/zlib/contrib/gcc_gvmat64/gvmat64.S
new file mode 100644
index 000000000..23309fa28
--- /dev/null
+++ b/xs/src/png/zlib/contrib/gcc_gvmat64/gvmat64.S
@@ -0,0 +1,574 @@
+/*
+;uInt longest_match_x64(
+; deflate_state *s,
+; IPos cur_match); // current match
+
+; gvmat64.S -- Asm portion of the optimized longest_match for 32 bits x86_64
+; (AMD64 on Athlon 64, Opteron, Phenom
+; and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)
+; this file is translation from gvmat64.asm to GCC 4.x (for Linux, Mac XCode)
+; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+;
+; File written by Gilles Vollant, by converting to assembly the longest_match
+; from Jean-loup Gailly in deflate.c of zLib and infoZip zip.
+; and by taking inspiration on asm686 with masm, optimised assembly code
+; from Brian Raiter, written 1998
+;
+; This software is provided 'as-is', without any express or implied
+; warranty. In no event will the authors be held liable for any damages
+; arising from the use of this software.
+;
+; Permission is granted to anyone to use this software for any purpose,
+; including commercial applications, and to alter it and redistribute it
+; freely, subject to the following restrictions:
+;
+; 1. The origin of this software must not be misrepresented; you must not
+; claim that you wrote the original software. If you use this software
+; in a product, an acknowledgment in the product documentation would be
+; appreciated but is not required.
+; 2. Altered source versions must be plainly marked as such, and must not be
+; misrepresented as being the original software
+; 3. This notice may not be removed or altered from any source distribution.
+;
+; http://www.zlib.net
+; http://www.winimage.com/zLibDll
+; http://www.muppetlabs.com/~breadbox/software/assembly.html
+;
+; to compile this file for zLib, I use option:
+; gcc -c -arch x86_64 gvmat64.S
+
+
+;uInt longest_match(s, cur_match)
+; deflate_state *s;
+; IPos cur_match; // current match /
+;
+; with XCode for Mac, I had strange error with some jump on intel syntax
+; this is why BEFORE_JMP and AFTER_JMP are used
+ */
+
+
+#define BEFORE_JMP .att_syntax
+#define AFTER_JMP .intel_syntax noprefix
+
+#ifndef NO_UNDERLINE
+# define match_init _match_init
+# define longest_match _longest_match
+#endif
+
+.intel_syntax noprefix
+
+.globl match_init, longest_match
+.text
+longest_match:
+
+
+
+#define LocalVarsSize 96
+/*
+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12
+; free register : r14,r15
+; register can be saved : rsp
+*/
+
+#define chainlenwmask (rsp + 8 - LocalVarsSize)
+#define nicematch (rsp + 16 - LocalVarsSize)
+
+#define save_rdi (rsp + 24 - LocalVarsSize)
+#define save_rsi (rsp + 32 - LocalVarsSize)
+#define save_rbx (rsp + 40 - LocalVarsSize)
+#define save_rbp (rsp + 48 - LocalVarsSize)
+#define save_r12 (rsp + 56 - LocalVarsSize)
+#define save_r13 (rsp + 64 - LocalVarsSize)
+#define save_r14 (rsp + 72 - LocalVarsSize)
+#define save_r15 (rsp + 80 - LocalVarsSize)
+
+
+/*
+; all the +4 offsets are due to the addition of pending_buf_size (in zlib
+; in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, remove the +4).
+; Note : these value are good with a 8 bytes boundary pack structure
+*/
+
+#define MAX_MATCH 258
+#define MIN_MATCH 3
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+
+/*
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+
+; all the +zlib1222add offsets are due to the addition of fields
+; in zlib in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+*/
+
+
+
+/* you can check the structure offset by running
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "deflate.h"
+
+void print_depl()
+{
+deflate_state ds;
+deflate_state *s=&ds;
+printf("size pointer=%u\n",(int)sizeof(void*));
+
+printf("#define dsWSize %u\n",(int)(((char*)&(s->w_size))-((char*)s)));
+printf("#define dsWMask %u\n",(int)(((char*)&(s->w_mask))-((char*)s)));
+printf("#define dsWindow %u\n",(int)(((char*)&(s->window))-((char*)s)));
+printf("#define dsPrev %u\n",(int)(((char*)&(s->prev))-((char*)s)));
+printf("#define dsMatchLen %u\n",(int)(((char*)&(s->match_length))-((char*)s)));
+printf("#define dsPrevMatch %u\n",(int)(((char*)&(s->prev_match))-((char*)s)));
+printf("#define dsStrStart %u\n",(int)(((char*)&(s->strstart))-((char*)s)));
+printf("#define dsMatchStart %u\n",(int)(((char*)&(s->match_start))-((char*)s)));
+printf("#define dsLookahead %u\n",(int)(((char*)&(s->lookahead))-((char*)s)));
+printf("#define dsPrevLen %u\n",(int)(((char*)&(s->prev_length))-((char*)s)));
+printf("#define dsMaxChainLen %u\n",(int)(((char*)&(s->max_chain_length))-((char*)s)));
+printf("#define dsGoodMatch %u\n",(int)(((char*)&(s->good_match))-((char*)s)));
+printf("#define dsNiceMatch %u\n",(int)(((char*)&(s->nice_match))-((char*)s)));
+}
+*/
+
+#define dsWSize 68
+#define dsWMask 76
+#define dsWindow 80
+#define dsPrev 96
+#define dsMatchLen 144
+#define dsPrevMatch 148
+#define dsStrStart 156
+#define dsMatchStart 160
+#define dsLookahead 164
+#define dsPrevLen 168
+#define dsMaxChainLen 172
+#define dsGoodMatch 188
+#define dsNiceMatch 192
+
+#define window_size [ rcx + dsWSize]
+#define WMask [ rcx + dsWMask]
+#define window_ad [ rcx + dsWindow]
+#define prev_ad [ rcx + dsPrev]
+#define strstart [ rcx + dsStrStart]
+#define match_start [ rcx + dsMatchStart]
+#define Lookahead [ rcx + dsLookahead] //; 0ffffffffh on infozip
+#define prev_length [ rcx + dsPrevLen]
+#define max_chain_length [ rcx + dsMaxChainLen]
+#define good_match [ rcx + dsGoodMatch]
+#define nice_match [ rcx + dsNiceMatch]
+
+/*
+; windows:
+; parameter 1 in rcx(deflate state s), param 2 in rdx (cur match)
+
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+;
+; All registers must be preserved across the call, except for
+; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.
+
+;
+; gcc on macosx-linux:
+; see http://www.x86-64.org/documentation/abi-0.99.pdf
+; param 1 in rdi, param 2 in rsi
+; rbx, rsp, rbp, r12 to r15 must be preserved
+
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+
+
+;;; Retrieve the function arguments. r8d will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+
+; ms: parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)
+; mac: param 1 in rdi, param 2 rsi
+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx
+*/
+ mov [save_rbx],rbx
+ mov [save_rbp],rbp
+
+
+ mov rcx,rdi
+
+ mov r8d,esi
+
+
+ mov [save_r12],r12
+ mov [save_r13],r13
+ mov [save_r14],r14
+ mov [save_r15],r15
+
+
+//;;; uInt wmask = s->w_mask;
+//;;; unsigned chain_length = s->max_chain_length;
+//;;; if (s->prev_length >= s->good_match) {
+//;;; chain_length >>= 2;
+//;;; }
+
+
+ mov edi, prev_length
+ mov esi, good_match
+ mov eax, WMask
+ mov ebx, max_chain_length
+ cmp edi, esi
+ jl LastMatchGood
+ shr ebx, 2
+LastMatchGood:
+
+//;;; chainlen is decremented once beforehand so that the function can
+//;;; use the sign flag instead of the zero flag for the exit test.
+//;;; It is then shifted into the high word, to make room for the wmask
+//;;; value, which it will always accompany.
+
+ dec ebx
+ shl ebx, 16
+ or ebx, eax
+
+//;;; on zlib only
+//;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+
+
+ mov eax, nice_match
+ mov [chainlenwmask], ebx
+ mov r10d, Lookahead
+ cmp r10d, eax
+ cmovnl r10d, eax
+ mov [nicematch],r10d
+
+
+
+//;;; register Bytef *scan = s->window + s->strstart;
+ mov r10, window_ad
+ mov ebp, strstart
+ lea r13, [r10 + rbp]
+
+//;;; Determine how many bytes the scan ptr is off from being
+//;;; dword-aligned.
+
+ mov r9,r13
+ neg r13
+ and r13,3
+
+//;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+//;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
+
+
+ mov eax, window_size
+ sub eax, MIN_LOOKAHEAD
+
+
+ xor edi,edi
+ sub ebp, eax
+
+ mov r11d, prev_length
+
+ cmovng ebp,edi
+
+//;;; int best_len = s->prev_length;
+
+
+//;;; Store the sum of s->window + best_len in esi locally, and in esi.
+
+ lea rsi,[r10+r11]
+
+//;;; register ush scan_start = *(ushf*)scan;
+//;;; register ush scan_end = *(ushf*)(scan+best_len-1);
+//;;; Posf *prev = s->prev;
+
+ movzx r12d,word ptr [r9]
+ movzx ebx, word ptr [r9 + r11 - 1]
+
+ mov rdi, prev_ad
+
+//;;; Jump into the main loop.
+
+ mov edx, [chainlenwmask]
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ jz LookupLoopIsZero
+
+
+
+LookupLoop1:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+
+
+
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry1:
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jz LookupLoopIsZero
+ AFTER_JMP
+
+LookupLoop2:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ BEFORE_JMP
+ jbe LeaveNow
+ AFTER_JMP
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry2:
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jz LookupLoopIsZero
+ AFTER_JMP
+
+LookupLoop4:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ BEFORE_JMP
+ jbe LeaveNow
+ AFTER_JMP
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry4:
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jnz LookupLoop1
+ jmp LookupLoopIsZero
+ AFTER_JMP
+/*
+;;; do {
+;;; match = s->window + cur_match;
+;;; if (*(ushf*)(match+best_len-1) != scan_end ||
+;;; *(ushf*)match != scan_start) continue;
+;;; [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;; && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;;
+;;; Within this loop:
+;;; ebx = scanend
+;;; r8d = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+*/
+.balign 16
+LookupLoop:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ BEFORE_JMP
+ jbe LeaveNow
+ AFTER_JMP
+ sub edx, 0x00010000
+ BEFORE_JMP
+ js LeaveNow
+ AFTER_JMP
+
+LoopEntry:
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ BEFORE_JMP
+ jnz LookupLoop1
+ AFTER_JMP
+LookupLoopIsZero:
+ cmp r12w, word ptr [r10 + r8]
+ BEFORE_JMP
+ jnz LookupLoop1
+ AFTER_JMP
+
+
+//;;; Store the current value of chainlen.
+ mov [chainlenwmask], edx
+/*
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+*/
+ lea rsi,[r8+r10]
+ mov rdx, 0xfffffffffffffef8 //; -(MAX_MATCH_8)
+ lea rsi, [rsi + r13 + 0x0108] //;MAX_MATCH_8]
+ lea rdi, [r9 + r13 + 0x0108] //;MAX_MATCH_8]
+
+ prefetcht1 [rsi+rdx]
+ prefetcht1 [rdi+rdx]
+
+/*
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust rdx so that it is offset to the exact byte that mismatched.
+;;;
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (rsi will still be misaligned three times out of four.)
+;;;
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+*/
+
+LoopCmps:
+ mov rax, [rsi + rdx]
+ xor rax, [rdi + rdx]
+ jnz LeaveLoopCmps
+
+ mov rax, [rsi + rdx + 8]
+ xor rax, [rdi + rdx + 8]
+ jnz LeaveLoopCmps8
+
+
+ mov rax, [rsi + rdx + 8+8]
+ xor rax, [rdi + rdx + 8+8]
+ jnz LeaveLoopCmps16
+
+ add rdx,8+8+8
+
+ BEFORE_JMP
+ jnz LoopCmps
+ jmp LenMaximum
+ AFTER_JMP
+
+LeaveLoopCmps16: add rdx,8
+LeaveLoopCmps8: add rdx,8
+LeaveLoopCmps:
+
+ test eax, 0x0000FFFF
+ jnz LenLower
+
+ test eax,0xffffffff
+
+ jnz LenLower32
+
+ add rdx,4
+ shr rax,32
+ or ax,ax
+ BEFORE_JMP
+ jnz LenLower
+ AFTER_JMP
+
+LenLower32:
+ shr eax,16
+ add rdx,2
+
+LenLower:
+ sub al, 1
+ adc rdx, 0
+//;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+//;;; then automatically accept it as the best possible match and leave.
+
+ lea rax, [rdi + rdx]
+ sub rax, r9
+ cmp eax, MAX_MATCH
+ BEFORE_JMP
+ jge LenMaximum
+ AFTER_JMP
+/*
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+;///////////////////////////////////
+*/
+ cmp eax, r11d
+ jg LongerMatch
+
+ lea rsi,[r10+r11]
+
+ mov rdi, prev_ad
+ mov edx, [chainlenwmask]
+ BEFORE_JMP
+ jmp LookupLoop
+ AFTER_JMP
+/*
+;;; s->match_start = cur_match;
+;;; best_len = len;
+;;; if (len >= nice_match) break;
+;;; scan_end = *(ushf*)(scan+best_len-1);
+*/
+LongerMatch:
+ mov r11d, eax
+ mov match_start, r8d
+ cmp eax, [nicematch]
+ BEFORE_JMP
+ jge LeaveNow
+ AFTER_JMP
+
+ lea rsi,[r10+rax]
+
+ movzx ebx, word ptr [r9 + rax - 1]
+ mov rdi, prev_ad
+ mov edx, [chainlenwmask]
+ BEFORE_JMP
+ jmp LookupLoop
+ AFTER_JMP
+
+//;;; Accept the current string, with the maximum possible length.
+
+LenMaximum:
+ mov r11d,MAX_MATCH
+ mov match_start, r8d
+
+//;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+//;;; return s->lookahead;
+
+LeaveNow:
+ mov eax, Lookahead
+ cmp r11d, eax
+ cmovng eax, r11d
+
+
+
+//;;; Restore the stack and return from whence we came.
+
+
+// mov rsi,[save_rsi]
+// mov rdi,[save_rdi]
+ mov rbx,[save_rbx]
+ mov rbp,[save_rbp]
+ mov r12,[save_r12]
+ mov r13,[save_r13]
+ mov r14,[save_r14]
+ mov r15,[save_r15]
+
+
+ ret 0
+//; please don't remove this string !
+//; Your can freely use gvmat64 in any free or commercial app
+//; but it is far better don't remove the string in the binary!
+ // db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0
+
+
+match_init:
+ ret 0
+
+
diff --git a/xs/src/png/zlib/contrib/infback9/README b/xs/src/png/zlib/contrib/infback9/README
new file mode 100644
index 000000000..e75ed1329
--- /dev/null
+++ b/xs/src/png/zlib/contrib/infback9/README
@@ -0,0 +1 @@
+See infback9.h for what this is and how to use it.
diff --git a/xs/src/png/zlib/contrib/infback9/infback9.c b/xs/src/png/zlib/contrib/infback9/infback9.c
new file mode 100644
index 000000000..05fb3e338
--- /dev/null
+++ b/xs/src/png/zlib/contrib/infback9/infback9.c
@@ -0,0 +1,615 @@
+/* infback9.c -- inflate deflate64 data using a call-back interface
+ * Copyright (C) 1995-2008 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "infback9.h"
+#include "inftree9.h"
+#include "inflate9.h"
+
+#define WSIZE 65536UL
+
+/*
+ strm provides memory allocation functions in zalloc and zfree, or
+ Z_NULL to use the library memory allocation functions.
+
+ window is a user-supplied window and output buffer that is 64K bytes.
+ */
+int ZEXPORT inflateBack9Init_(strm, window, version, stream_size)
+z_stream FAR *strm;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL || window == Z_NULL)
+ return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+ sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (voidpf)state;
+ state->window = window;
+ return Z_OK;
+}
+
+/*
+ Build and output length and distance decoding tables for fixed code
+ decoding.
+ */
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+void makefixed9(void)
+{
+ unsigned sym, bits, low, size;
+ code *next, *lenfix, *distfix;
+ struct inflate_state state;
+ code fixed[544];
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state.lens[sym++] = 8;
+ while (sym < 256) state.lens[sym++] = 9;
+ while (sym < 280) state.lens[sym++] = 7;
+ while (sym < 288) state.lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state.lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work);
+
+ /* write tables */
+ puts(" /* inffix9.h -- table for decoding deflate64 fixed codes");
+ puts(" * Generated automatically by makefixed9().");
+ puts(" */");
+ puts("");
+ puts(" /* WARNING: this file should *not* be used by applications.");
+ puts(" It is part of the implementation of this library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ puts(" */");
+ puts("");
+ size = 1U << 9;
+ printf(" static const code lenfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 6) == 0) printf("\n ");
+ printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
+ lenfix[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+ size = 1U << 5;
+ printf("\n static const code distfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 5) == 0) printf("\n ");
+ printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
+ distfix[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+}
+#endif /* MAKEFIXED */
+
+/* Macros for inflateBack(): */
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Assure that some input is available. If input is requested, but denied,
+ then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+ do { \
+ if (have == 0) { \
+ have = in(in_desc, &next); \
+ if (have == 0) { \
+ next = Z_NULL; \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+ with an error if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ PULL(); \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflateBack() with
+ an error. */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n <= 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Assure that some output space is available, by writing out the window
+ if it's full. If the write fails, return from inflateBack() with a
+ Z_BUF_ERROR. */
+#define ROOM() \
+ do { \
+ if (left == 0) { \
+ put = window; \
+ left = WSIZE; \
+ wrap = 1; \
+ if (out(out_desc, put, (unsigned)left)) { \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/*
+ strm provides the memory allocation functions and window buffer on input,
+ and provides information on the unused input on return. For Z_DATA_ERROR
+ returns, strm will also provide an error message.
+
+ in() and out() are the call-back input and output functions. When
+ inflateBack() needs more input, it calls in(). When inflateBack() has
+ filled the window with output, or when it completes with data in the
+ window, it calls out() to write out the data. The application must not
+ change the provided input until in() is called again or inflateBack()
+ returns. The application must not change the window/output buffer until
+ inflateBack() returns.
+
+ in() and out() are called with a descriptor parameter provided in the
+ inflateBack() call. This parameter can be a structure that provides the
+ information required to do the read or write, as well as accumulated
+ information on the input and output such as totals and check values.
+
+ in() should return zero on failure. out() should return non-zero on
+ failure. If either in() or out() fails, than inflateBack() returns a
+ Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
+ was in() or out() that caused in the error. Otherwise, inflateBack()
+ returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+ error, or Z_MEM_ERROR if it could not allocate memory for the state.
+ inflateBack() can also return Z_STREAM_ERROR if the input parameters
+ are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc)
+z_stream FAR *strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have; /* available input */
+ unsigned long left; /* available output */
+ inflate_mode mode; /* current inflate mode */
+ int lastblock; /* true if processing last block */
+ int wrap; /* true if the window has wrapped */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned extra; /* extra bits needed */
+ unsigned long length; /* literal or length of data to copy */
+ unsigned long offset; /* distance back to copy string from */
+ unsigned long copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code const FAR *lencode; /* starting table for length/literal codes */
+ code const FAR *distcode; /* starting table for distance codes */
+ unsigned lenbits; /* index bits for lencode */
+ unsigned distbits; /* index bits for distcode */
+ code here; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+#include "inffix9.h"
+
+ /* Check that the strm exists and that the state was initialized */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* Reset the state */
+ strm->msg = Z_NULL;
+ mode = TYPE;
+ lastblock = 0;
+ wrap = 0;
+ window = state->window;
+ next = strm->next_in;
+ have = next != Z_NULL ? strm->avail_in : 0;
+ hold = 0;
+ bits = 0;
+ put = window;
+ left = WSIZE;
+ lencode = Z_NULL;
+ distcode = Z_NULL;
+
+ /* Inflate until end of block marked as last */
+ for (;;)
+ switch (mode) {
+ case TYPE:
+ /* determine and dispatch block type */
+ if (lastblock) {
+ BYTEBITS();
+ mode = DONE;
+ break;
+ }
+ NEEDBITS(3);
+ lastblock = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ lastblock ? " (last)" : ""));
+ mode = STORED;
+ break;
+ case 1: /* fixed block */
+ lencode = lenfix;
+ lenbits = 9;
+ distcode = distfix;
+ distbits = 5;
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ lastblock ? " (last)" : ""));
+ mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ lastblock ? " (last)" : ""));
+ mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+
+ case STORED:
+ /* get and verify stored block length */
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ mode = BAD;
+ break;
+ }
+ length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %lu\n",
+ length));
+ INITBITS();
+
+ /* copy stored block from input to output */
+ while (length != 0) {
+ copy = length;
+ PULL();
+ ROOM();
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ length -= copy;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ mode = TYPE;
+ break;
+
+ case TABLE:
+ /* get dynamic table entries descriptor */
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+ if (state->nlen > 286) {
+ strm->msg = (char *)"too many length symbols";
+ mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: table sizes ok\n"));
+
+ /* get code length code lengths (not a typo) */
+ state->have = 0;
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ lencode = (code const FAR *)(state->next);
+ lenbits = 7;
+ ret = inflate_table9(CODES, state->lens, 19, &(state->next),
+ &(lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+
+ /* get length and distance code code lengths */
+ state->have = 0;
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ here = lencode[BITS(lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.val < 16) {
+ NEEDBITS(here.bits);
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
+ }
+ else {
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ mode = BAD;
+ break;
+ }
+ len = (unsigned)(state->lens[state->have - 1]);
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (mode == BAD) break;
+
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftree9.h
+ concerning the ENOUGH constants, which depend on those values */
+ state->next = state->codes;
+ lencode = (code const FAR *)(state->next);
+ lenbits = 9;
+ ret = inflate_table9(LENS, state->lens, state->nlen,
+ &(state->next), &(lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ mode = BAD;
+ break;
+ }
+ distcode = (code const FAR *)(state->next);
+ distbits = 6;
+ ret = inflate_table9(DISTS, state->lens + state->nlen,
+ state->ndist, &(state->next), &(distbits),
+ state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ mode = LEN;
+
+ case LEN:
+ /* get a literal, length, or end-of-block code */
+ for (;;) {
+ here = lencode[BITS(lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(here.bits);
+ length = (unsigned)here.val;
+
+ /* process literal */
+ if (here.op == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ ROOM();
+ *put++ = (unsigned char)(length);
+ left--;
+ mode = LEN;
+ break;
+ }
+
+ /* process end of block */
+ if (here.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ mode = TYPE;
+ break;
+ }
+
+ /* invalid code */
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ mode = BAD;
+ break;
+ }
+
+ /* length code -- get extra bits, if any */
+ extra = (unsigned)(here.op) & 31;
+ if (extra != 0) {
+ NEEDBITS(extra);
+ length += BITS(extra);
+ DROPBITS(extra);
+ }
+ Tracevv((stderr, "inflate: length %lu\n", length));
+
+ /* get distance code */
+ for (;;) {
+ here = distcode[BITS(distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(here.bits);
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ mode = BAD;
+ break;
+ }
+ offset = (unsigned)here.val;
+
+ /* get distance extra bits, if any */
+ extra = (unsigned)(here.op) & 15;
+ if (extra != 0) {
+ NEEDBITS(extra);
+ offset += BITS(extra);
+ DROPBITS(extra);
+ }
+ if (offset > WSIZE - (wrap ? 0: left)) {
+ strm->msg = (char *)"invalid distance too far back";
+ mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %lu\n", offset));
+
+ /* copy match from window to output */
+ do {
+ ROOM();
+ copy = WSIZE - offset;
+ if (copy < left) {
+ from = put + copy;
+ copy = left - copy;
+ }
+ else {
+ from = put - offset;
+ copy = left;
+ }
+ if (copy > length) copy = length;
+ length -= copy;
+ left -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ } while (length != 0);
+ break;
+
+ case DONE:
+ /* inflate stream terminated properly -- write leftover output */
+ ret = Z_STREAM_END;
+ if (left < WSIZE) {
+ if (out(out_desc, window, (unsigned)(WSIZE - left)))
+ ret = Z_BUF_ERROR;
+ }
+ goto inf_leave;
+
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+
+ default: /* can't happen, but makes compilers happy */
+ ret = Z_STREAM_ERROR;
+ goto inf_leave;
+ }
+
+ /* Return unused input */
+ inf_leave:
+ strm->next_in = next;
+ strm->avail_in = have;
+ return ret;
+}
+
+int ZEXPORT inflateBack9End(strm)
+z_stream FAR *strm;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
diff --git a/xs/src/png/zlib/contrib/infback9/infback9.h b/xs/src/png/zlib/contrib/infback9/infback9.h
new file mode 100644
index 000000000..1073c0a38
--- /dev/null
+++ b/xs/src/png/zlib/contrib/infback9/infback9.h
@@ -0,0 +1,37 @@
+/* infback9.h -- header for using inflateBack9 functions
+ * Copyright (C) 2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * This header file and associated patches provide a decoder for PKWare's
+ * undocumented deflate64 compression method (method 9). Use with infback9.c,
+ * inftree9.h, inftree9.c, and inffix9.h. These patches are not supported.
+ * This should be compiled with zlib, since it uses zutil.h and zutil.o.
+ * This code has not yet been tested on 16-bit architectures. See the
+ * comments in zlib.h for inflateBack() usage. These functions are used
+ * identically, except that there is no windowBits parameter, and a 64K
+ * window must be provided. Also if int's are 16 bits, then a zero for
+ * the third parameter of the "out" function actually means 65536UL.
+ * zlib.h must be included before this header file.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+ZEXTERN int ZEXPORT inflateBack9End OF((z_stream FAR *strm));
+ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define inflateBack9Init(strm, window) \
+ inflateBack9Init_((strm), (window), \
+ ZLIB_VERSION, sizeof(z_stream))
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/xs/src/png/zlib/contrib/infback9/inffix9.h b/xs/src/png/zlib/contrib/infback9/inffix9.h
new file mode 100644
index 000000000..ee5671d2d
--- /dev/null
+++ b/xs/src/png/zlib/contrib/infback9/inffix9.h
@@ -0,0 +1,107 @@
+ /* inffix9.h -- table for decoding deflate64 fixed codes
+ * Generated automatically by makefixed9().
+ */
+
+ /* WARNING: this file should *not* be used by applications.
+ It is part of the implementation of this library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+ static const code lenfix[512] = {
+ {96,7,0},{0,8,80},{0,8,16},{132,8,115},{130,7,31},{0,8,112},
+ {0,8,48},{0,9,192},{128,7,10},{0,8,96},{0,8,32},{0,9,160},
+ {0,8,0},{0,8,128},{0,8,64},{0,9,224},{128,7,6},{0,8,88},
+ {0,8,24},{0,9,144},{131,7,59},{0,8,120},{0,8,56},{0,9,208},
+ {129,7,17},{0,8,104},{0,8,40},{0,9,176},{0,8,8},{0,8,136},
+ {0,8,72},{0,9,240},{128,7,4},{0,8,84},{0,8,20},{133,8,227},
+ {131,7,43},{0,8,116},{0,8,52},{0,9,200},{129,7,13},{0,8,100},
+ {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},
+ {128,7,8},{0,8,92},{0,8,28},{0,9,152},{132,7,83},{0,8,124},
+ {0,8,60},{0,9,216},{130,7,23},{0,8,108},{0,8,44},{0,9,184},
+ {0,8,12},{0,8,140},{0,8,76},{0,9,248},{128,7,3},{0,8,82},
+ {0,8,18},{133,8,163},{131,7,35},{0,8,114},{0,8,50},{0,9,196},
+ {129,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},{0,8,130},
+ {0,8,66},{0,9,228},{128,7,7},{0,8,90},{0,8,26},{0,9,148},
+ {132,7,67},{0,8,122},{0,8,58},{0,9,212},{130,7,19},{0,8,106},
+ {0,8,42},{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},
+ {128,7,5},{0,8,86},{0,8,22},{65,8,0},{131,7,51},{0,8,118},
+ {0,8,54},{0,9,204},{129,7,15},{0,8,102},{0,8,38},{0,9,172},
+ {0,8,6},{0,8,134},{0,8,70},{0,9,236},{128,7,9},{0,8,94},
+ {0,8,30},{0,9,156},{132,7,99},{0,8,126},{0,8,62},{0,9,220},
+ {130,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+ {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{133,8,131},
+ {130,7,31},{0,8,113},{0,8,49},{0,9,194},{128,7,10},{0,8,97},
+ {0,8,33},{0,9,162},{0,8,1},{0,8,129},{0,8,65},{0,9,226},
+ {128,7,6},{0,8,89},{0,8,25},{0,9,146},{131,7,59},{0,8,121},
+ {0,8,57},{0,9,210},{129,7,17},{0,8,105},{0,8,41},{0,9,178},
+ {0,8,9},{0,8,137},{0,8,73},{0,9,242},{128,7,4},{0,8,85},
+ {0,8,21},{144,8,3},{131,7,43},{0,8,117},{0,8,53},{0,9,202},
+ {129,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},
+ {0,8,69},{0,9,234},{128,7,8},{0,8,93},{0,8,29},{0,9,154},
+ {132,7,83},{0,8,125},{0,8,61},{0,9,218},{130,7,23},{0,8,109},
+ {0,8,45},{0,9,186},{0,8,13},{0,8,141},{0,8,77},{0,9,250},
+ {128,7,3},{0,8,83},{0,8,19},{133,8,195},{131,7,35},{0,8,115},
+ {0,8,51},{0,9,198},{129,7,11},{0,8,99},{0,8,35},{0,9,166},
+ {0,8,3},{0,8,131},{0,8,67},{0,9,230},{128,7,7},{0,8,91},
+ {0,8,27},{0,9,150},{132,7,67},{0,8,123},{0,8,59},{0,9,214},
+ {130,7,19},{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},
+ {0,8,75},{0,9,246},{128,7,5},{0,8,87},{0,8,23},{77,8,0},
+ {131,7,51},{0,8,119},{0,8,55},{0,9,206},{129,7,15},{0,8,103},
+ {0,8,39},{0,9,174},{0,8,7},{0,8,135},{0,8,71},{0,9,238},
+ {128,7,9},{0,8,95},{0,8,31},{0,9,158},{132,7,99},{0,8,127},
+ {0,8,63},{0,9,222},{130,7,27},{0,8,111},{0,8,47},{0,9,190},
+ {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},
+ {0,8,16},{132,8,115},{130,7,31},{0,8,112},{0,8,48},{0,9,193},
+ {128,7,10},{0,8,96},{0,8,32},{0,9,161},{0,8,0},{0,8,128},
+ {0,8,64},{0,9,225},{128,7,6},{0,8,88},{0,8,24},{0,9,145},
+ {131,7,59},{0,8,120},{0,8,56},{0,9,209},{129,7,17},{0,8,104},
+ {0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},{0,9,241},
+ {128,7,4},{0,8,84},{0,8,20},{133,8,227},{131,7,43},{0,8,116},
+ {0,8,52},{0,9,201},{129,7,13},{0,8,100},{0,8,36},{0,9,169},
+ {0,8,4},{0,8,132},{0,8,68},{0,9,233},{128,7,8},{0,8,92},
+ {0,8,28},{0,9,153},{132,7,83},{0,8,124},{0,8,60},{0,9,217},
+ {130,7,23},{0,8,108},{0,8,44},{0,9,185},{0,8,12},{0,8,140},
+ {0,8,76},{0,9,249},{128,7,3},{0,8,82},{0,8,18},{133,8,163},
+ {131,7,35},{0,8,114},{0,8,50},{0,9,197},{129,7,11},{0,8,98},
+ {0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+ {128,7,7},{0,8,90},{0,8,26},{0,9,149},{132,7,67},{0,8,122},
+ {0,8,58},{0,9,213},{130,7,19},{0,8,106},{0,8,42},{0,9,181},
+ {0,8,10},{0,8,138},{0,8,74},{0,9,245},{128,7,5},{0,8,86},
+ {0,8,22},{65,8,0},{131,7,51},{0,8,118},{0,8,54},{0,9,205},
+ {129,7,15},{0,8,102},{0,8,38},{0,9,173},{0,8,6},{0,8,134},
+ {0,8,70},{0,9,237},{128,7,9},{0,8,94},{0,8,30},{0,9,157},
+ {132,7,99},{0,8,126},{0,8,62},{0,9,221},{130,7,27},{0,8,110},
+ {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},
+ {96,7,0},{0,8,81},{0,8,17},{133,8,131},{130,7,31},{0,8,113},
+ {0,8,49},{0,9,195},{128,7,10},{0,8,97},{0,8,33},{0,9,163},
+ {0,8,1},{0,8,129},{0,8,65},{0,9,227},{128,7,6},{0,8,89},
+ {0,8,25},{0,9,147},{131,7,59},{0,8,121},{0,8,57},{0,9,211},
+ {129,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},{0,8,137},
+ {0,8,73},{0,9,243},{128,7,4},{0,8,85},{0,8,21},{144,8,3},
+ {131,7,43},{0,8,117},{0,8,53},{0,9,203},{129,7,13},{0,8,101},
+ {0,8,37},{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},
+ {128,7,8},{0,8,93},{0,8,29},{0,9,155},{132,7,83},{0,8,125},
+ {0,8,61},{0,9,219},{130,7,23},{0,8,109},{0,8,45},{0,9,187},
+ {0,8,13},{0,8,141},{0,8,77},{0,9,251},{128,7,3},{0,8,83},
+ {0,8,19},{133,8,195},{131,7,35},{0,8,115},{0,8,51},{0,9,199},
+ {129,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+ {0,8,67},{0,9,231},{128,7,7},{0,8,91},{0,8,27},{0,9,151},
+ {132,7,67},{0,8,123},{0,8,59},{0,9,215},{130,7,19},{0,8,107},
+ {0,8,43},{0,9,183},{0,8,11},{0,8,139},{0,8,75},{0,9,247},
+ {128,7,5},{0,8,87},{0,8,23},{77,8,0},{131,7,51},{0,8,119},
+ {0,8,55},{0,9,207},{129,7,15},{0,8,103},{0,8,39},{0,9,175},
+ {0,8,7},{0,8,135},{0,8,71},{0,9,239},{128,7,9},{0,8,95},
+ {0,8,31},{0,9,159},{132,7,99},{0,8,127},{0,8,63},{0,9,223},
+ {130,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},
+ {0,8,79},{0,9,255}
+ };
+
+ static const code distfix[32] = {
+ {128,5,1},{135,5,257},{131,5,17},{139,5,4097},{129,5,5},
+ {137,5,1025},{133,5,65},{141,5,16385},{128,5,3},{136,5,513},
+ {132,5,33},{140,5,8193},{130,5,9},{138,5,2049},{134,5,129},
+ {142,5,32769},{128,5,2},{135,5,385},{131,5,25},{139,5,6145},
+ {129,5,7},{137,5,1537},{133,5,97},{141,5,24577},{128,5,4},
+ {136,5,769},{132,5,49},{140,5,12289},{130,5,13},{138,5,3073},
+ {134,5,193},{142,5,49153}
+ };
diff --git a/xs/src/png/zlib/contrib/infback9/inflate9.h b/xs/src/png/zlib/contrib/infback9/inflate9.h
new file mode 100644
index 000000000..ee9a79394
--- /dev/null
+++ b/xs/src/png/zlib/contrib/infback9/inflate9.h
@@ -0,0 +1,47 @@
+/* inflate9.h -- internal inflate state definition
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+ TYPE, /* i: waiting for type bits, including last-flag bit */
+ STORED, /* i: waiting for stored size (length and complement) */
+ TABLE, /* i: waiting for dynamic block table lengths */
+ LEN, /* i: waiting for length/lit code */
+ DONE, /* finished check, done -- remain here until reset */
+ BAD /* got a data error -- remain here until reset */
+} inflate_mode;
+
+/*
+ State transitions between above modes -
+
+ (most modes can go to the BAD mode -- not shown for clarity)
+
+ Read deflate blocks:
+ TYPE -> STORED or TABLE or LEN or DONE
+ STORED -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN
+ Read deflate codes:
+ LEN -> LEN or TYPE
+ */
+
+/* state maintained between inflate() calls. Approximately 7K bytes. */
+struct inflate_state {
+ /* sliding window */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ /* dynamic table building */
+ unsigned ncode; /* number of code length code lengths */
+ unsigned nlen; /* number of length code lengths */
+ unsigned ndist; /* number of distance code lengths */
+ unsigned have; /* number of code lengths in lens[] */
+ code FAR *next; /* next available space in codes[] */
+ unsigned short lens[320]; /* temporary storage for code lengths */
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
+};
diff --git a/xs/src/png/zlib/contrib/infback9/inftree9.c b/xs/src/png/zlib/contrib/infback9/inftree9.c
new file mode 100644
index 000000000..5f4a76798
--- /dev/null
+++ b/xs/src/png/zlib/contrib/infback9/inftree9.c
@@ -0,0 +1,324 @@
+/* inftree9.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftree9.h"
+
+#define MAXBITS 15
+
+const char inflate9_copyright[] =
+ " inflate9 1.2.11 Copyright 1995-2017 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/*
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+ */
+int inflate_table9(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+ unsigned len; /* a code's length in bits */
+ unsigned sym; /* index of code symbols */
+ unsigned min, max; /* minimum and maximum code lengths */
+ unsigned root; /* number of index bits for root table */
+ unsigned curr; /* number of index bits for current table */
+ unsigned drop; /* code bits to drop for sub-table */
+ int left; /* number of prefix codes available */
+ unsigned used; /* code entries in table used */
+ unsigned huff; /* Huffman code */
+ unsigned incr; /* for incrementing code, index */
+ unsigned fill; /* index for replicating entries */
+ unsigned low; /* low bits for current root entry */
+ unsigned mask; /* mask for low root bits */
+ code this; /* table entry for duplication */
+ code FAR *next; /* next available space in table */
+ const unsigned short FAR *base; /* base value table to use */
+ const unsigned short FAR *extra; /* extra bits table to use */
+ int end; /* use base and extra for symbol > end */
+ unsigned short count[MAXBITS+1]; /* number of codes of each length */
+ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
+ static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17,
+ 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115,
+ 131, 163, 195, 227, 3, 0, 0};
+ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+ 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
+ 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
+ 133, 133, 133, 133, 144, 77, 202};
+ static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
+ 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
+ 4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153};
+ static const unsigned short dext[32] = { /* Distance codes 0..31 extra */
+ 128, 128, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132,
+ 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138,
+ 139, 139, 140, 140, 141, 141, 142, 142};
+
+ /*
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+
+ The length counts are used for other purposes as well, i.e. finding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ */
+
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ for (len = 0; len <= MAXBITS; len++)
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[sym]]++;
+
+ /* bound code lengths, force root to be within code lengths */
+ root = *bits;
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) return -1; /* no codes! */
+ for (min = 1; min <= MAXBITS; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1;
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ }
+ if (left > 0 && (type == CODES || max != 1))
+ return -1; /* incomplete set */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + count[len];
+
+ /* sort symbols by length, by symbol order within each length */
+ for (sym = 0; sym < codes; sym++)
+ if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+ /*
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked for LENS and DIST tables against
+ the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+ the initial root table size constants. See the comments in inftree9.h
+ for more information.
+
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ */
+
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ end = 19;
+ break;
+ case LENS:
+ base = lbase;
+ base -= 257;
+ extra = lext;
+ extra -= 257;
+ end = 256;
+ break;
+ default: /* DISTS */
+ base = dbase;
+ extra = dext;
+ end = -1;
+ }
+
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = *table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = (unsigned)(-1); /* trigger new sub-table when len > root */
+ used = 1U << root; /* use root table entries */
+ mask = used - 1; /* mask for comparing low */
+
+ /* check available table space */
+ if ((type == LENS && used >= ENOUGH_LENS) ||
+ (type == DISTS && used >= ENOUGH_DISTS))
+ return 1;
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ this.bits = (unsigned char)(len - drop);
+ if ((int)(work[sym]) < end) {
+ this.op = (unsigned char)0;
+ this.val = work[sym];
+ }
+ else if ((int)(work[sym]) > end) {
+ this.op = (unsigned char)(extra[work[sym]]);
+ this.val = base[work[sym]];
+ }
+ else {
+ this.op = (unsigned char)(32 + 64); /* end of block */
+ this.val = 0;
+ }
+
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1U << (len - drop);
+ fill = 1U << curr;
+ do {
+ fill -= incr;
+ next[(huff >> drop) + fill] = this;
+ } while (fill != 0);
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[work[sym]];
+ }
+
+ /* create new sub-table if needed */
+ if (len > root && (huff & mask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+
+ /* increment past last table */
+ next += 1U << curr;
+
+ /* determine length of next table */
+ curr = len - drop;
+ left = (int)(1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ left <<= 1;
+ }
+
+ /* check for enough space */
+ used += 1U << curr;
+ if ((type == LENS && used >= ENOUGH_LENS) ||
+ (type == DISTS && used >= ENOUGH_DISTS))
+ return 1;
+
+ /* point entry in root table to sub-table */
+ low = huff & mask;
+ (*table)[low].op = (unsigned char)curr;
+ (*table)[low].bits = (unsigned char)root;
+ (*table)[low].val = (unsigned short)(next - *table);
+ }
+ }
+
+ /*
+ Fill in rest of table for incomplete codes. This loop is similar to the
+ loop above in incrementing huff for table indices. It is assumed that
+ len is equal to curr + drop, so there is no loop needed to increment
+ through high index bits. When the current sub-table is filled, the loop
+ drops back to the root table to fill in any remaining entries there.
+ */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)(len - drop);
+ this.val = (unsigned short)0;
+ while (huff != 0) {
+ /* when done with sub-table, drop back to root table */
+ if (drop != 0 && (huff & mask) != low) {
+ drop = 0;
+ len = root;
+ next = *table;
+ curr = root;
+ this.bits = (unsigned char)len;
+ }
+
+ /* put invalid code marker in table */
+ next[huff >> drop] = this;
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+ }
+
+ /* set return parameters */
+ *table += used;
+ *bits = root;
+ return 0;
+}
diff --git a/xs/src/png/zlib/contrib/infback9/inftree9.h b/xs/src/png/zlib/contrib/infback9/inftree9.h
new file mode 100644
index 000000000..5ab21f0c6
--- /dev/null
+++ b/xs/src/png/zlib/contrib/infback9/inftree9.h
@@ -0,0 +1,61 @@
+/* inftree9.h -- header to use inftree9.c
+ * Copyright (C) 1995-2008 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables. Each entry provides either the
+ information needed to do the operation requested by the code that
+ indexed that table entry, or it provides a pointer to another
+ table that indexes more bits of the code. op indicates whether
+ the entry is a pointer to another table, a literal, a length or
+ distance, an end-of-block, or an invalid code. For a table
+ pointer, the low four bits of op is the number of index bits of
+ that table. For a length or distance, the low four bits of op
+ is the number of extra bits to get after the code. bits is
+ the number of bits in this code or part of the code to drop off
+ of the bit buffer. val is the actual byte to output in the case
+ of a literal, the base length or distance, or the offset from
+ the current table to the next table. Each entry is four bytes. */
+typedef struct {
+ unsigned char op; /* operation, extra bits, table bits */
+ unsigned char bits; /* bits in this part of the code */
+ unsigned short val; /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+ 00000000 - literal
+ 0000tttt - table link, tttt != 0 is the number of table index bits
+ 100eeeee - length or distance, eeee is the number of extra bits
+ 01100000 - end of block
+ 01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table. The maximum number of code structures is
+ 1446, which is the sum of 852 for literal/length codes and 594 for distance
+ codes. These values were found by exhaustive searches using the program
+ examples/enough.c found in the zlib distribtution. The arguments to that
+ program are the number of symbols, the initial root table size, and the
+ maximum bit length of a code. "enough 286 9 15" for literal/length codes
+ returns returns 852, and "enough 32 6 15" for distance codes returns 594.
+ The initial root table size (9 or 6) is found in the fifth argument of the
+ inflate_table() calls in infback9.c. If the root table size is changed,
+ then these maximum sizes would be need to be recalculated and updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 594
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table9() */
+typedef enum {
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+
+extern int inflate_table9 OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
diff --git a/xs/src/png/zlib/contrib/inflate86/inffas86.c b/xs/src/png/zlib/contrib/inflate86/inffas86.c
new file mode 100644
index 000000000..7292f67b7
--- /dev/null
+++ b/xs/src/png/zlib/contrib/inflate86/inffas86.c
@@ -0,0 +1,1157 @@
+/* inffas86.c is a hand tuned assembler version of
+ *
+ * inffast.c -- fast decoding
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+ * Please use the copyright conditions above.
+ *
+ * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also
+ * slightly quicker on x86 systems because, instead of using rep movsb to copy
+ * data, it uses rep movsw, which moves data in 2-byte chunks instead of single
+ * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
+ * from http://fedora.linux.duke.edu/fc1_x86_64
+ * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
+ * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version,
+ * when decompressing mozilla-source-1.3.tar.gz.
+ *
+ * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
+ * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at
+ * the moment. I have successfully compiled and tested this code with gcc2.96,
+ * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S
+ * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
+ * enabled. I will attempt to merge the MMX code into this version. Newer
+ * versions of this and inffast.S can be found at
+ * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* Mark Adler's comments from inffast.c: */
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start; /* inflate()'s starting value for strm->avail_out */
+{
+ struct inflate_state FAR *state;
+ struct inffast_ar {
+/* 64 32 x86 x86_64 */
+/* ar offset register */
+/* 0 0 */ void *esp; /* esp save */
+/* 8 4 */ void *ebp; /* ebp save */
+/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */
+/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */
+/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */
+/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */
+/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */
+/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */
+/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */
+/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */
+/* 80 40 */ unsigned long hold; /* edx rdx local strm->hold */
+/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */
+/* 92 48 */ unsigned wsize; /* window size */
+/* 96 52 */ unsigned write; /* window write index */
+/*100 56 */ unsigned lmask; /* r12 mask for lcode */
+/*104 60 */ unsigned dmask; /* r13 mask for dcode */
+/*108 64 */ unsigned len; /* r14 match length */
+/*112 68 */ unsigned dist; /* r15 match distance */
+/*116 72 */ unsigned status; /* set when state chng*/
+ } ar;
+
+#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
+#define PAD_AVAIL_IN 6
+#define PAD_AVAIL_OUT 258
+#else
+#define PAD_AVAIL_IN 5
+#define PAD_AVAIL_OUT 257
+#endif
+
+ /* copy state to local variables */
+ state = (struct inflate_state FAR *)strm->state;
+ ar.in = strm->next_in;
+ ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
+ ar.out = strm->next_out;
+ ar.beg = ar.out - (start - strm->avail_out);
+ ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
+ ar.wsize = state->wsize;
+ ar.write = state->wnext;
+ ar.window = state->window;
+ ar.hold = state->hold;
+ ar.bits = state->bits;
+ ar.lcode = state->lencode;
+ ar.dcode = state->distcode;
+ ar.lmask = (1U << state->lenbits) - 1;
+ ar.dmask = (1U << state->distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+
+ /* align in on 1/2 hold size boundary */
+ while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
+ ar.hold += (unsigned long)*ar.in++ << ar.bits;
+ ar.bits += 8;
+ }
+
+#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
+ __asm__ __volatile__ (
+" leaq %0, %%rax\n"
+" movq %%rbp, 8(%%rax)\n" /* save regs rbp and rsp */
+" movq %%rsp, (%%rax)\n"
+" movq %%rax, %%rsp\n" /* make rsp point to &ar */
+" movq 16(%%rsp), %%rsi\n" /* rsi = in */
+" movq 32(%%rsp), %%rdi\n" /* rdi = out */
+" movq 24(%%rsp), %%r9\n" /* r9 = last */
+" movq 48(%%rsp), %%r10\n" /* r10 = end */
+" movq 64(%%rsp), %%rbp\n" /* rbp = lcode */
+" movq 72(%%rsp), %%r11\n" /* r11 = dcode */
+" movq 80(%%rsp), %%rdx\n" /* rdx = hold */
+" movl 88(%%rsp), %%ebx\n" /* ebx = bits */
+" movl 100(%%rsp), %%r12d\n" /* r12d = lmask */
+" movl 104(%%rsp), %%r13d\n" /* r13d = dmask */
+ /* r14d = len */
+ /* r15d = dist */
+" cld\n"
+" cmpq %%rdi, %%r10\n"
+" je .L_one_time\n" /* if only one decode left */
+" cmpq %%rsi, %%r9\n"
+" je .L_one_time\n"
+" jmp .L_do_loop\n"
+
+".L_one_time:\n"
+" movq %%r12, %%r8\n" /* r8 = lmask */
+" cmpb $32, %%bl\n"
+" ja .L_get_length_code_one_time\n"
+
+" lodsl\n" /* eax = *(uint *)in++ */
+" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
+" addb $32, %%bl\n" /* bits += 32 */
+" shlq %%cl, %%rax\n"
+" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
+" jmp .L_get_length_code_one_time\n"
+
+".align 32,0x90\n"
+".L_while_test:\n"
+" cmpq %%rdi, %%r10\n"
+" jbe .L_break_loop\n"
+" cmpq %%rsi, %%r9\n"
+" jbe .L_break_loop\n"
+
+".L_do_loop:\n"
+" movq %%r12, %%r8\n" /* r8 = lmask */
+" cmpb $32, %%bl\n"
+" ja .L_get_length_code\n" /* if (32 < bits) */
+
+" lodsl\n" /* eax = *(uint *)in++ */
+" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
+" addb $32, %%bl\n" /* bits += 32 */
+" shlq %%cl, %%rax\n"
+" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
+
+".L_get_length_code:\n"
+" andq %%rdx, %%r8\n" /* r8 &= hold */
+" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
+
+" movb %%ah, %%cl\n" /* cl = this.bits */
+" subb %%ah, %%bl\n" /* bits -= this.bits */
+" shrq %%cl, %%rdx\n" /* hold >>= this.bits */
+
+" testb %%al, %%al\n"
+" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
+
+" movq %%r12, %%r8\n" /* r8 = lmask */
+" shrl $16, %%eax\n" /* output this.val char */
+" stosb\n"
+
+".L_get_length_code_one_time:\n"
+" andq %%rdx, %%r8\n" /* r8 &= hold */
+" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
+
+".L_dolen:\n"
+" movb %%ah, %%cl\n" /* cl = this.bits */
+" subb %%ah, %%bl\n" /* bits -= this.bits */
+" shrq %%cl, %%rdx\n" /* hold >>= this.bits */
+
+" testb %%al, %%al\n"
+" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
+
+" shrl $16, %%eax\n" /* output this.val char */
+" stosb\n"
+" jmp .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_length_base:\n"
+" movl %%eax, %%r14d\n" /* len = this */
+" shrl $16, %%r14d\n" /* len = this.val */
+" movb %%al, %%cl\n"
+
+" testb $16, %%al\n"
+" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
+" andb $15, %%cl\n" /* op &= 15 */
+" jz .L_decode_distance\n" /* if (!op) */
+
+".L_add_bits_to_len:\n"
+" subb %%cl, %%bl\n"
+" xorl %%eax, %%eax\n"
+" incl %%eax\n"
+" shll %%cl, %%eax\n"
+" decl %%eax\n"
+" andl %%edx, %%eax\n" /* eax &= hold */
+" shrq %%cl, %%rdx\n"
+" addl %%eax, %%r14d\n" /* len += hold & mask[op] */
+
+".L_decode_distance:\n"
+" movq %%r13, %%r8\n" /* r8 = dmask */
+" cmpb $32, %%bl\n"
+" ja .L_get_distance_code\n" /* if (32 < bits) */
+
+" lodsl\n" /* eax = *(uint *)in++ */
+" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
+" addb $32, %%bl\n" /* bits += 32 */
+" shlq %%cl, %%rax\n"
+" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
+
+".L_get_distance_code:\n"
+" andq %%rdx, %%r8\n" /* r8 &= hold */
+" movl (%%r11,%%r8,4), %%eax\n" /* eax = dcode[hold & dmask] */
+
+".L_dodist:\n"
+" movl %%eax, %%r15d\n" /* dist = this */
+" shrl $16, %%r15d\n" /* dist = this.val */
+" movb %%ah, %%cl\n"
+" subb %%ah, %%bl\n" /* bits -= this.bits */
+" shrq %%cl, %%rdx\n" /* hold >>= this.bits */
+" movb %%al, %%cl\n" /* cl = this.op */
+
+" testb $16, %%al\n" /* if ((op & 16) == 0) */
+" jz .L_test_for_second_level_dist\n"
+" andb $15, %%cl\n" /* op &= 15 */
+" jz .L_check_dist_one\n"
+
+".L_add_bits_to_dist:\n"
+" subb %%cl, %%bl\n"
+" xorl %%eax, %%eax\n"
+" incl %%eax\n"
+" shll %%cl, %%eax\n"
+" decl %%eax\n" /* (1 << op) - 1 */
+" andl %%edx, %%eax\n" /* eax &= hold */
+" shrq %%cl, %%rdx\n"
+" addl %%eax, %%r15d\n" /* dist += hold & ((1 << op) - 1) */
+
+".L_check_window:\n"
+" movq %%rsi, %%r8\n" /* save in so from can use it's reg */
+" movq %%rdi, %%rax\n"
+" subq 40(%%rsp), %%rax\n" /* nbytes = out - beg */
+
+" cmpl %%r15d, %%eax\n"
+" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */
+
+" movl %%r14d, %%ecx\n" /* ecx = len */
+" movq %%rdi, %%rsi\n"
+" subq %%r15, %%rsi\n" /* from = out - dist */
+
+" sarl %%ecx\n"
+" jnc .L_copy_two\n" /* if len % 2 == 0 */
+
+" rep movsw\n"
+" movb (%%rsi), %%al\n"
+" movb %%al, (%%rdi)\n"
+" incq %%rdi\n"
+
+" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */
+" jmp .L_while_test\n"
+
+".L_copy_two:\n"
+" rep movsw\n"
+" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */
+" jmp .L_while_test\n"
+
+".align 32,0x90\n"
+".L_check_dist_one:\n"
+" cmpl $1, %%r15d\n" /* if dist 1, is a memset */
+" jne .L_check_window\n"
+" cmpq %%rdi, 40(%%rsp)\n" /* if out == beg, outside window */
+" je .L_check_window\n"
+
+" movl %%r14d, %%ecx\n" /* ecx = len */
+" movb -1(%%rdi), %%al\n"
+" movb %%al, %%ah\n"
+
+" sarl %%ecx\n"
+" jnc .L_set_two\n"
+" movb %%al, (%%rdi)\n"
+" incq %%rdi\n"
+
+".L_set_two:\n"
+" rep stosw\n"
+" jmp .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_length:\n"
+" testb $64, %%al\n"
+" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
+
+" xorl %%eax, %%eax\n"
+" incl %%eax\n"
+" shll %%cl, %%eax\n"
+" decl %%eax\n"
+" andl %%edx, %%eax\n" /* eax &= hold */
+" addl %%r14d, %%eax\n" /* eax += len */
+" movl (%%rbp,%%rax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
+" jmp .L_dolen\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_dist:\n"
+" testb $64, %%al\n"
+" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
+
+" xorl %%eax, %%eax\n"
+" incl %%eax\n"
+" shll %%cl, %%eax\n"
+" decl %%eax\n"
+" andl %%edx, %%eax\n" /* eax &= hold */
+" addl %%r15d, %%eax\n" /* eax += dist */
+" movl (%%r11,%%rax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
+" jmp .L_dodist\n"
+
+".align 32,0x90\n"
+".L_clip_window:\n"
+" movl %%eax, %%ecx\n" /* ecx = nbytes */
+" movl 92(%%rsp), %%eax\n" /* eax = wsize, prepare for dist cmp */
+" negl %%ecx\n" /* nbytes = -nbytes */
+
+" cmpl %%r15d, %%eax\n"
+" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */
+
+" addl %%r15d, %%ecx\n" /* nbytes = dist - nbytes */
+" cmpl $0, 96(%%rsp)\n"
+" jne .L_wrap_around_window\n" /* if (write != 0) */
+
+" movq 56(%%rsp), %%rsi\n" /* from = window */
+" subl %%ecx, %%eax\n" /* eax -= nbytes */
+" addq %%rax, %%rsi\n" /* from += wsize - nbytes */
+
+" movl %%r14d, %%eax\n" /* eax = len */
+" cmpl %%ecx, %%r14d\n"
+" jbe .L_do_copy\n" /* if (nbytes >= len) */
+
+" subl %%ecx, %%eax\n" /* eax -= nbytes */
+" rep movsb\n"
+" movq %%rdi, %%rsi\n"
+" subq %%r15, %%rsi\n" /* from = &out[ -dist ] */
+" jmp .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_wrap_around_window:\n"
+" movl 96(%%rsp), %%eax\n" /* eax = write */
+" cmpl %%eax, %%ecx\n"
+" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */
+
+" movl 92(%%rsp), %%esi\n" /* from = wsize */
+" addq 56(%%rsp), %%rsi\n" /* from += window */
+" addq %%rax, %%rsi\n" /* from += write */
+" subq %%rcx, %%rsi\n" /* from -= nbytes */
+" subl %%eax, %%ecx\n" /* nbytes -= write */
+
+" movl %%r14d, %%eax\n" /* eax = len */
+" cmpl %%ecx, %%eax\n"
+" jbe .L_do_copy\n" /* if (nbytes >= len) */
+
+" subl %%ecx, %%eax\n" /* len -= nbytes */
+" rep movsb\n"
+" movq 56(%%rsp), %%rsi\n" /* from = window */
+" movl 96(%%rsp), %%ecx\n" /* nbytes = write */
+" cmpl %%ecx, %%eax\n"
+" jbe .L_do_copy\n" /* if (nbytes >= len) */
+
+" subl %%ecx, %%eax\n" /* len -= nbytes */
+" rep movsb\n"
+" movq %%rdi, %%rsi\n"
+" subq %%r15, %%rsi\n" /* from = out - dist */
+" jmp .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_contiguous_in_window:\n"
+" movq 56(%%rsp), %%rsi\n" /* rsi = window */
+" addq %%rax, %%rsi\n"
+" subq %%rcx, %%rsi\n" /* from += write - nbytes */
+
+" movl %%r14d, %%eax\n" /* eax = len */
+" cmpl %%ecx, %%eax\n"
+" jbe .L_do_copy\n" /* if (nbytes >= len) */
+
+" subl %%ecx, %%eax\n" /* len -= nbytes */
+" rep movsb\n"
+" movq %%rdi, %%rsi\n"
+" subq %%r15, %%rsi\n" /* from = out - dist */
+" jmp .L_do_copy\n" /* if (nbytes >= len) */
+
+".align 32,0x90\n"
+".L_do_copy:\n"
+" movl %%eax, %%ecx\n" /* ecx = len */
+" rep movsb\n"
+
+" movq %%r8, %%rsi\n" /* move in back to %esi, toss from */
+" jmp .L_while_test\n"
+
+".L_test_for_end_of_block:\n"
+" testb $32, %%al\n"
+" jz .L_invalid_literal_length_code\n"
+" movl $1, 116(%%rsp)\n"
+" jmp .L_break_loop_with_status\n"
+
+".L_invalid_literal_length_code:\n"
+" movl $2, 116(%%rsp)\n"
+" jmp .L_break_loop_with_status\n"
+
+".L_invalid_distance_code:\n"
+" movl $3, 116(%%rsp)\n"
+" jmp .L_break_loop_with_status\n"
+
+".L_invalid_distance_too_far:\n"
+" movl $4, 116(%%rsp)\n"
+" jmp .L_break_loop_with_status\n"
+
+".L_break_loop:\n"
+" movl $0, 116(%%rsp)\n"
+
+".L_break_loop_with_status:\n"
+/* put in, out, bits, and hold back into ar and pop esp */
+" movq %%rsi, 16(%%rsp)\n" /* in */
+" movq %%rdi, 32(%%rsp)\n" /* out */
+" movl %%ebx, 88(%%rsp)\n" /* bits */
+" movq %%rdx, 80(%%rsp)\n" /* hold */
+" movq (%%rsp), %%rax\n" /* restore rbp and rsp */
+" movq 8(%%rsp), %%rbp\n"
+" movq %%rax, %%rsp\n"
+ :
+ : "m" (ar)
+ : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
+ "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
+ );
+#elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 )
+ __asm__ __volatile__ (
+" leal %0, %%eax\n"
+" movl %%esp, (%%eax)\n" /* save esp, ebp */
+" movl %%ebp, 4(%%eax)\n"
+" movl %%eax, %%esp\n"
+" movl 8(%%esp), %%esi\n" /* esi = in */
+" movl 16(%%esp), %%edi\n" /* edi = out */
+" movl 40(%%esp), %%edx\n" /* edx = hold */
+" movl 44(%%esp), %%ebx\n" /* ebx = bits */
+" movl 32(%%esp), %%ebp\n" /* ebp = lcode */
+
+" cld\n"
+" jmp .L_do_loop\n"
+
+".align 32,0x90\n"
+".L_while_test:\n"
+" cmpl %%edi, 24(%%esp)\n" /* out < end */
+" jbe .L_break_loop\n"
+" cmpl %%esi, 12(%%esp)\n" /* in < last */
+" jbe .L_break_loop\n"
+
+".L_do_loop:\n"
+" cmpb $15, %%bl\n"
+" ja .L_get_length_code\n" /* if (15 < bits) */
+
+" xorl %%eax, %%eax\n"
+" lodsw\n" /* al = *(ushort *)in++ */
+" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
+" addb $16, %%bl\n" /* bits += 16 */
+" shll %%cl, %%eax\n"
+" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
+
+".L_get_length_code:\n"
+" movl 56(%%esp), %%eax\n" /* eax = lmask */
+" andl %%edx, %%eax\n" /* eax &= hold */
+" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */
+
+".L_dolen:\n"
+" movb %%ah, %%cl\n" /* cl = this.bits */
+" subb %%ah, %%bl\n" /* bits -= this.bits */
+" shrl %%cl, %%edx\n" /* hold >>= this.bits */
+
+" testb %%al, %%al\n"
+" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
+
+" shrl $16, %%eax\n" /* output this.val char */
+" stosb\n"
+" jmp .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_length_base:\n"
+" movl %%eax, %%ecx\n" /* len = this */
+" shrl $16, %%ecx\n" /* len = this.val */
+" movl %%ecx, 64(%%esp)\n" /* save len */
+" movb %%al, %%cl\n"
+
+" testb $16, %%al\n"
+" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
+" andb $15, %%cl\n" /* op &= 15 */
+" jz .L_decode_distance\n" /* if (!op) */
+" cmpb %%cl, %%bl\n"
+" jae .L_add_bits_to_len\n" /* if (op <= bits) */
+
+" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */
+" xorl %%eax, %%eax\n"
+" lodsw\n" /* al = *(ushort *)in++ */
+" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
+" addb $16, %%bl\n" /* bits += 16 */
+" shll %%cl, %%eax\n"
+" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
+" movb %%ch, %%cl\n" /* move op back to ecx */
+
+".L_add_bits_to_len:\n"
+" subb %%cl, %%bl\n"
+" xorl %%eax, %%eax\n"
+" incl %%eax\n"
+" shll %%cl, %%eax\n"
+" decl %%eax\n"
+" andl %%edx, %%eax\n" /* eax &= hold */
+" shrl %%cl, %%edx\n"
+" addl %%eax, 64(%%esp)\n" /* len += hold & mask[op] */
+
+".L_decode_distance:\n"
+" cmpb $15, %%bl\n"
+" ja .L_get_distance_code\n" /* if (15 < bits) */
+
+" xorl %%eax, %%eax\n"
+" lodsw\n" /* al = *(ushort *)in++ */
+" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
+" addb $16, %%bl\n" /* bits += 16 */
+" shll %%cl, %%eax\n"
+" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
+
+".L_get_distance_code:\n"
+" movl 60(%%esp), %%eax\n" /* eax = dmask */
+" movl 36(%%esp), %%ecx\n" /* ecx = dcode */
+" andl %%edx, %%eax\n" /* eax &= hold */
+" movl (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */
+
+".L_dodist:\n"
+" movl %%eax, %%ebp\n" /* dist = this */
+" shrl $16, %%ebp\n" /* dist = this.val */
+" movb %%ah, %%cl\n"
+" subb %%ah, %%bl\n" /* bits -= this.bits */
+" shrl %%cl, %%edx\n" /* hold >>= this.bits */
+" movb %%al, %%cl\n" /* cl = this.op */
+
+" testb $16, %%al\n" /* if ((op & 16) == 0) */
+" jz .L_test_for_second_level_dist\n"
+" andb $15, %%cl\n" /* op &= 15 */
+" jz .L_check_dist_one\n"
+" cmpb %%cl, %%bl\n"
+" jae .L_add_bits_to_dist\n" /* if (op <= bits) 97.6% */
+
+" movb %%cl, %%ch\n" /* stash op in ch, freeing cl */
+" xorl %%eax, %%eax\n"
+" lodsw\n" /* al = *(ushort *)in++ */
+" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
+" addb $16, %%bl\n" /* bits += 16 */
+" shll %%cl, %%eax\n"
+" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
+" movb %%ch, %%cl\n" /* move op back to ecx */
+
+".L_add_bits_to_dist:\n"
+" subb %%cl, %%bl\n"
+" xorl %%eax, %%eax\n"
+" incl %%eax\n"
+" shll %%cl, %%eax\n"
+" decl %%eax\n" /* (1 << op) - 1 */
+" andl %%edx, %%eax\n" /* eax &= hold */
+" shrl %%cl, %%edx\n"
+" addl %%eax, %%ebp\n" /* dist += hold & ((1 << op) - 1) */
+
+".L_check_window:\n"
+" movl %%esi, 8(%%esp)\n" /* save in so from can use it's reg */
+" movl %%edi, %%eax\n"
+" subl 20(%%esp), %%eax\n" /* nbytes = out - beg */
+
+" cmpl %%ebp, %%eax\n"
+" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */
+
+" movl 64(%%esp), %%ecx\n" /* ecx = len */
+" movl %%edi, %%esi\n"
+" subl %%ebp, %%esi\n" /* from = out - dist */
+
+" sarl %%ecx\n"
+" jnc .L_copy_two\n" /* if len % 2 == 0 */
+
+" rep movsw\n"
+" movb (%%esi), %%al\n"
+" movb %%al, (%%edi)\n"
+" incl %%edi\n"
+
+" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
+" movl 32(%%esp), %%ebp\n" /* ebp = lcode */
+" jmp .L_while_test\n"
+
+".L_copy_two:\n"
+" rep movsw\n"
+" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
+" movl 32(%%esp), %%ebp\n" /* ebp = lcode */
+" jmp .L_while_test\n"
+
+".align 32,0x90\n"
+".L_check_dist_one:\n"
+" cmpl $1, %%ebp\n" /* if dist 1, is a memset */
+" jne .L_check_window\n"
+" cmpl %%edi, 20(%%esp)\n"
+" je .L_check_window\n" /* out == beg, if outside window */
+
+" movl 64(%%esp), %%ecx\n" /* ecx = len */
+" movb -1(%%edi), %%al\n"
+" movb %%al, %%ah\n"
+
+" sarl %%ecx\n"
+" jnc .L_set_two\n"
+" movb %%al, (%%edi)\n"
+" incl %%edi\n"
+
+".L_set_two:\n"
+" rep stosw\n"
+" movl 32(%%esp), %%ebp\n" /* ebp = lcode */
+" jmp .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_length:\n"
+" testb $64, %%al\n"
+" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
+
+" xorl %%eax, %%eax\n"
+" incl %%eax\n"
+" shll %%cl, %%eax\n"
+" decl %%eax\n"
+" andl %%edx, %%eax\n" /* eax &= hold */
+" addl 64(%%esp), %%eax\n" /* eax += len */
+" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
+" jmp .L_dolen\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_dist:\n"
+" testb $64, %%al\n"
+" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
+
+" xorl %%eax, %%eax\n"
+" incl %%eax\n"
+" shll %%cl, %%eax\n"
+" decl %%eax\n"
+" andl %%edx, %%eax\n" /* eax &= hold */
+" addl %%ebp, %%eax\n" /* eax += dist */
+" movl 36(%%esp), %%ecx\n" /* ecx = dcode */
+" movl (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
+" jmp .L_dodist\n"
+
+".align 32,0x90\n"
+".L_clip_window:\n"
+" movl %%eax, %%ecx\n"
+" movl 48(%%esp), %%eax\n" /* eax = wsize */
+" negl %%ecx\n" /* nbytes = -nbytes */
+" movl 28(%%esp), %%esi\n" /* from = window */
+
+" cmpl %%ebp, %%eax\n"
+" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */
+
+" addl %%ebp, %%ecx\n" /* nbytes = dist - nbytes */
+" cmpl $0, 52(%%esp)\n"
+" jne .L_wrap_around_window\n" /* if (write != 0) */
+
+" subl %%ecx, %%eax\n"
+" addl %%eax, %%esi\n" /* from += wsize - nbytes */
+
+" movl 64(%%esp), %%eax\n" /* eax = len */
+" cmpl %%ecx, %%eax\n"
+" jbe .L_do_copy\n" /* if (nbytes >= len) */
+
+" subl %%ecx, %%eax\n" /* len -= nbytes */
+" rep movsb\n"
+" movl %%edi, %%esi\n"
+" subl %%ebp, %%esi\n" /* from = out - dist */
+" jmp .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_wrap_around_window:\n"
+" movl 52(%%esp), %%eax\n" /* eax = write */
+" cmpl %%eax, %%ecx\n"
+" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */
+
+" addl 48(%%esp), %%esi\n" /* from += wsize */
+" addl %%eax, %%esi\n" /* from += write */
+" subl %%ecx, %%esi\n" /* from -= nbytes */
+" subl %%eax, %%ecx\n" /* nbytes -= write */
+
+" movl 64(%%esp), %%eax\n" /* eax = len */
+" cmpl %%ecx, %%eax\n"
+" jbe .L_do_copy\n" /* if (nbytes >= len) */
+
+" subl %%ecx, %%eax\n" /* len -= nbytes */
+" rep movsb\n"
+" movl 28(%%esp), %%esi\n" /* from = window */
+" movl 52(%%esp), %%ecx\n" /* nbytes = write */
+" cmpl %%ecx, %%eax\n"
+" jbe .L_do_copy\n" /* if (nbytes >= len) */
+
+" subl %%ecx, %%eax\n" /* len -= nbytes */
+" rep movsb\n"
+" movl %%edi, %%esi\n"
+" subl %%ebp, %%esi\n" /* from = out - dist */
+" jmp .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_contiguous_in_window:\n"
+" addl %%eax, %%esi\n"
+" subl %%ecx, %%esi\n" /* from += write - nbytes */
+
+" movl 64(%%esp), %%eax\n" /* eax = len */
+" cmpl %%ecx, %%eax\n"
+" jbe .L_do_copy\n" /* if (nbytes >= len) */
+
+" subl %%ecx, %%eax\n" /* len -= nbytes */
+" rep movsb\n"
+" movl %%edi, %%esi\n"
+" subl %%ebp, %%esi\n" /* from = out - dist */
+" jmp .L_do_copy\n" /* if (nbytes >= len) */
+
+".align 32,0x90\n"
+".L_do_copy:\n"
+" movl %%eax, %%ecx\n"
+" rep movsb\n"
+
+" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
+" movl 32(%%esp), %%ebp\n" /* ebp = lcode */
+" jmp .L_while_test\n"
+
+".L_test_for_end_of_block:\n"
+" testb $32, %%al\n"
+" jz .L_invalid_literal_length_code\n"
+" movl $1, 72(%%esp)\n"
+" jmp .L_break_loop_with_status\n"
+
+".L_invalid_literal_length_code:\n"
+" movl $2, 72(%%esp)\n"
+" jmp .L_break_loop_with_status\n"
+
+".L_invalid_distance_code:\n"
+" movl $3, 72(%%esp)\n"
+" jmp .L_break_loop_with_status\n"
+
+".L_invalid_distance_too_far:\n"
+" movl 8(%%esp), %%esi\n"
+" movl $4, 72(%%esp)\n"
+" jmp .L_break_loop_with_status\n"
+
+".L_break_loop:\n"
+" movl $0, 72(%%esp)\n"
+
+".L_break_loop_with_status:\n"
+/* put in, out, bits, and hold back into ar and pop esp */
+" movl %%esi, 8(%%esp)\n" /* save in */
+" movl %%edi, 16(%%esp)\n" /* save out */
+" movl %%ebx, 44(%%esp)\n" /* save bits */
+" movl %%edx, 40(%%esp)\n" /* save hold */
+" movl 4(%%esp), %%ebp\n" /* restore esp, ebp */
+" movl (%%esp), %%esp\n"
+ :
+ : "m" (ar)
+ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
+ );
+#elif defined( _MSC_VER ) && ! defined( _M_AMD64 )
+ __asm {
+ lea eax, ar
+ mov [eax], esp /* save esp, ebp */
+ mov [eax+4], ebp
+ mov esp, eax
+ mov esi, [esp+8] /* esi = in */
+ mov edi, [esp+16] /* edi = out */
+ mov edx, [esp+40] /* edx = hold */
+ mov ebx, [esp+44] /* ebx = bits */
+ mov ebp, [esp+32] /* ebp = lcode */
+
+ cld
+ jmp L_do_loop
+
+ALIGN 4
+L_while_test:
+ cmp [esp+24], edi
+ jbe L_break_loop
+ cmp [esp+12], esi
+ jbe L_break_loop
+
+L_do_loop:
+ cmp bl, 15
+ ja L_get_length_code /* if (15 < bits) */
+
+ xor eax, eax
+ lodsw /* al = *(ushort *)in++ */
+ mov cl, bl /* cl = bits, needs it for shifting */
+ add bl, 16 /* bits += 16 */
+ shl eax, cl
+ or edx, eax /* hold |= *((ushort *)in)++ << bits */
+
+L_get_length_code:
+ mov eax, [esp+56] /* eax = lmask */
+ and eax, edx /* eax &= hold */
+ mov eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */
+
+L_dolen:
+ mov cl, ah /* cl = this.bits */
+ sub bl, ah /* bits -= this.bits */
+ shr edx, cl /* hold >>= this.bits */
+
+ test al, al
+ jnz L_test_for_length_base /* if (op != 0) 45.7% */
+
+ shr eax, 16 /* output this.val char */
+ stosb
+ jmp L_while_test
+
+ALIGN 4
+L_test_for_length_base:
+ mov ecx, eax /* len = this */
+ shr ecx, 16 /* len = this.val */
+ mov [esp+64], ecx /* save len */
+ mov cl, al
+
+ test al, 16
+ jz L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
+ and cl, 15 /* op &= 15 */
+ jz L_decode_distance /* if (!op) */
+ cmp bl, cl
+ jae L_add_bits_to_len /* if (op <= bits) */
+
+ mov ch, cl /* stash op in ch, freeing cl */
+ xor eax, eax
+ lodsw /* al = *(ushort *)in++ */
+ mov cl, bl /* cl = bits, needs it for shifting */
+ add bl, 16 /* bits += 16 */
+ shl eax, cl
+ or edx, eax /* hold |= *((ushort *)in)++ << bits */
+ mov cl, ch /* move op back to ecx */
+
+L_add_bits_to_len:
+ sub bl, cl
+ xor eax, eax
+ inc eax
+ shl eax, cl
+ dec eax
+ and eax, edx /* eax &= hold */
+ shr edx, cl
+ add [esp+64], eax /* len += hold & mask[op] */
+
+L_decode_distance:
+ cmp bl, 15
+ ja L_get_distance_code /* if (15 < bits) */
+
+ xor eax, eax
+ lodsw /* al = *(ushort *)in++ */
+ mov cl, bl /* cl = bits, needs it for shifting */
+ add bl, 16 /* bits += 16 */
+ shl eax, cl
+ or edx, eax /* hold |= *((ushort *)in)++ << bits */
+
+L_get_distance_code:
+ mov eax, [esp+60] /* eax = dmask */
+ mov ecx, [esp+36] /* ecx = dcode */
+ and eax, edx /* eax &= hold */
+ mov eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */
+
+L_dodist:
+ mov ebp, eax /* dist = this */
+ shr ebp, 16 /* dist = this.val */
+ mov cl, ah
+ sub bl, ah /* bits -= this.bits */
+ shr edx, cl /* hold >>= this.bits */
+ mov cl, al /* cl = this.op */
+
+ test al, 16 /* if ((op & 16) == 0) */
+ jz L_test_for_second_level_dist
+ and cl, 15 /* op &= 15 */
+ jz L_check_dist_one
+ cmp bl, cl
+ jae L_add_bits_to_dist /* if (op <= bits) 97.6% */
+
+ mov ch, cl /* stash op in ch, freeing cl */
+ xor eax, eax
+ lodsw /* al = *(ushort *)in++ */
+ mov cl, bl /* cl = bits, needs it for shifting */
+ add bl, 16 /* bits += 16 */
+ shl eax, cl
+ or edx, eax /* hold |= *((ushort *)in)++ << bits */
+ mov cl, ch /* move op back to ecx */
+
+L_add_bits_to_dist:
+ sub bl, cl
+ xor eax, eax
+ inc eax
+ shl eax, cl
+ dec eax /* (1 << op) - 1 */
+ and eax, edx /* eax &= hold */
+ shr edx, cl
+ add ebp, eax /* dist += hold & ((1 << op) - 1) */
+
+L_check_window:
+ mov [esp+8], esi /* save in so from can use it's reg */
+ mov eax, edi
+ sub eax, [esp+20] /* nbytes = out - beg */
+
+ cmp eax, ebp
+ jb L_clip_window /* if (dist > nbytes) 4.2% */
+
+ mov ecx, [esp+64] /* ecx = len */
+ mov esi, edi
+ sub esi, ebp /* from = out - dist */
+
+ sar ecx, 1
+ jnc L_copy_two
+
+ rep movsw
+ mov al, [esi]
+ mov [edi], al
+ inc edi
+
+ mov esi, [esp+8] /* move in back to %esi, toss from */
+ mov ebp, [esp+32] /* ebp = lcode */
+ jmp L_while_test
+
+L_copy_two:
+ rep movsw
+ mov esi, [esp+8] /* move in back to %esi, toss from */
+ mov ebp, [esp+32] /* ebp = lcode */
+ jmp L_while_test
+
+ALIGN 4
+L_check_dist_one:
+ cmp ebp, 1 /* if dist 1, is a memset */
+ jne L_check_window
+ cmp [esp+20], edi
+ je L_check_window /* out == beg, if outside window */
+
+ mov ecx, [esp+64] /* ecx = len */
+ mov al, [edi-1]
+ mov ah, al
+
+ sar ecx, 1
+ jnc L_set_two
+ mov [edi], al /* memset out with from[-1] */
+ inc edi
+
+L_set_two:
+ rep stosw
+ mov ebp, [esp+32] /* ebp = lcode */
+ jmp L_while_test
+
+ALIGN 4
+L_test_for_second_level_length:
+ test al, 64
+ jnz L_test_for_end_of_block /* if ((op & 64) != 0) */
+
+ xor eax, eax
+ inc eax
+ shl eax, cl
+ dec eax
+ and eax, edx /* eax &= hold */
+ add eax, [esp+64] /* eax += len */
+ mov eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/
+ jmp L_dolen
+
+ALIGN 4
+L_test_for_second_level_dist:
+ test al, 64
+ jnz L_invalid_distance_code /* if ((op & 64) != 0) */
+
+ xor eax, eax
+ inc eax
+ shl eax, cl
+ dec eax
+ and eax, edx /* eax &= hold */
+ add eax, ebp /* eax += dist */
+ mov ecx, [esp+36] /* ecx = dcode */
+ mov eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/
+ jmp L_dodist
+
+ALIGN 4
+L_clip_window:
+ mov ecx, eax
+ mov eax, [esp+48] /* eax = wsize */
+ neg ecx /* nbytes = -nbytes */
+ mov esi, [esp+28] /* from = window */
+
+ cmp eax, ebp
+ jb L_invalid_distance_too_far /* if (dist > wsize) */
+
+ add ecx, ebp /* nbytes = dist - nbytes */
+ cmp dword ptr [esp+52], 0
+ jne L_wrap_around_window /* if (write != 0) */
+
+ sub eax, ecx
+ add esi, eax /* from += wsize - nbytes */
+
+ mov eax, [esp+64] /* eax = len */
+ cmp eax, ecx
+ jbe L_do_copy /* if (nbytes >= len) */
+
+ sub eax, ecx /* len -= nbytes */
+ rep movsb
+ mov esi, edi
+ sub esi, ebp /* from = out - dist */
+ jmp L_do_copy
+
+ALIGN 4
+L_wrap_around_window:
+ mov eax, [esp+52] /* eax = write */
+ cmp ecx, eax
+ jbe L_contiguous_in_window /* if (write >= nbytes) */
+
+ add esi, [esp+48] /* from += wsize */
+ add esi, eax /* from += write */
+ sub esi, ecx /* from -= nbytes */
+ sub ecx, eax /* nbytes -= write */
+
+ mov eax, [esp+64] /* eax = len */
+ cmp eax, ecx
+ jbe L_do_copy /* if (nbytes >= len) */
+
+ sub eax, ecx /* len -= nbytes */
+ rep movsb
+ mov esi, [esp+28] /* from = window */
+ mov ecx, [esp+52] /* nbytes = write */
+ cmp eax, ecx
+ jbe L_do_copy /* if (nbytes >= len) */
+
+ sub eax, ecx /* len -= nbytes */
+ rep movsb
+ mov esi, edi
+ sub esi, ebp /* from = out - dist */
+ jmp L_do_copy
+
+ALIGN 4
+L_contiguous_in_window:
+ add esi, eax
+ sub esi, ecx /* from += write - nbytes */
+
+ mov eax, [esp+64] /* eax = len */
+ cmp eax, ecx
+ jbe L_do_copy /* if (nbytes >= len) */
+
+ sub eax, ecx /* len -= nbytes */
+ rep movsb
+ mov esi, edi
+ sub esi, ebp /* from = out - dist */
+ jmp L_do_copy
+
+ALIGN 4
+L_do_copy:
+ mov ecx, eax
+ rep movsb
+
+ mov esi, [esp+8] /* move in back to %esi, toss from */
+ mov ebp, [esp+32] /* ebp = lcode */
+ jmp L_while_test
+
+L_test_for_end_of_block:
+ test al, 32
+ jz L_invalid_literal_length_code
+ mov dword ptr [esp+72], 1
+ jmp L_break_loop_with_status
+
+L_invalid_literal_length_code:
+ mov dword ptr [esp+72], 2
+ jmp L_break_loop_with_status
+
+L_invalid_distance_code:
+ mov dword ptr [esp+72], 3
+ jmp L_break_loop_with_status
+
+L_invalid_distance_too_far:
+ mov esi, [esp+4]
+ mov dword ptr [esp+72], 4
+ jmp L_break_loop_with_status
+
+L_break_loop:
+ mov dword ptr [esp+72], 0
+
+L_break_loop_with_status:
+/* put in, out, bits, and hold back into ar and pop esp */
+ mov [esp+8], esi /* save in */
+ mov [esp+16], edi /* save out */
+ mov [esp+44], ebx /* save bits */
+ mov [esp+40], edx /* save hold */
+ mov ebp, [esp+4] /* restore esp, ebp */
+ mov esp, [esp]
+ }
+#else
+#error "x86 architecture not defined"
+#endif
+
+ if (ar.status > 1) {
+ if (ar.status == 2)
+ strm->msg = "invalid literal/length code";
+ else if (ar.status == 3)
+ strm->msg = "invalid distance code";
+ else
+ strm->msg = "invalid distance too far back";
+ state->mode = BAD;
+ }
+ else if ( ar.status == 1 ) {
+ state->mode = TYPE;
+ }
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ ar.len = ar.bits >> 3;
+ ar.in -= ar.len;
+ ar.bits -= ar.len << 3;
+ ar.hold &= (1U << ar.bits) - 1;
+
+ /* update state and return */
+ strm->next_in = ar.in;
+ strm->next_out = ar.out;
+ strm->avail_in = (unsigned)(ar.in < ar.last ?
+ PAD_AVAIL_IN + (ar.last - ar.in) :
+ PAD_AVAIL_IN - (ar.in - ar.last));
+ strm->avail_out = (unsigned)(ar.out < ar.end ?
+ PAD_AVAIL_OUT + (ar.end - ar.out) :
+ PAD_AVAIL_OUT - (ar.out - ar.end));
+ state->hold = ar.hold;
+ state->bits = ar.bits;
+ return;
+}
+
diff --git a/xs/src/png/zlib/contrib/inflate86/inffast.S b/xs/src/png/zlib/contrib/inflate86/inffast.S
new file mode 100644
index 000000000..2245a2905
--- /dev/null
+++ b/xs/src/png/zlib/contrib/inflate86/inffast.S
@@ -0,0 +1,1368 @@
+/*
+ * inffast.S is a hand tuned assembler version of:
+ *
+ * inffast.c -- fast decoding
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+ * Please use the copyright conditions above.
+ *
+ * This version (Jan-23-2003) of inflate_fast was coded and tested under
+ * GNU/Linux on a pentium 3, using the gcc-3.2 compiler distribution. On that
+ * machine, I found that gzip style archives decompressed about 20% faster than
+ * the gcc-3.2 -O3 -fomit-frame-pointer compiled version. Your results will
+ * depend on how large of a buffer is used for z_stream.next_in & next_out
+ * (8K-32K worked best for my 256K cpu cache) and how much overhead there is in
+ * stream processing I/O and crc32/addler32. In my case, this routine used
+ * 70% of the cpu time and crc32 used 20%.
+ *
+ * I am confident that this version will work in the general case, but I have
+ * not tested a wide variety of datasets or a wide variety of platforms.
+ *
+ * Jan-24-2003 -- Added -DUSE_MMX define for slightly faster inflating.
+ * It should be a runtime flag instead of compile time flag...
+ *
+ * Jan-26-2003 -- Added runtime check for MMX support with cpuid instruction.
+ * With -DUSE_MMX, only MMX code is compiled. With -DNO_MMX, only non-MMX code
+ * is compiled. Without either option, runtime detection is enabled. Runtime
+ * detection should work on all modern cpus and the recomended algorithm (flip
+ * ID bit on eflags and then use the cpuid instruction) is used in many
+ * multimedia applications. Tested under win2k with gcc-2.95 and gas-2.12
+ * distributed with cygwin3. Compiling with gcc-2.95 -c inffast.S -o
+ * inffast.obj generates a COFF object which can then be linked with MSVC++
+ * compiled code. Tested under FreeBSD 4.7 with gcc-2.95.
+ *
+ * Jan-28-2003 -- Tested Athlon XP... MMX mode is slower than no MMX (and
+ * slower than compiler generated code). Adjusted cpuid check to use the MMX
+ * code only for Pentiums < P4 until I have more data on the P4. Speed
+ * improvment is only about 15% on the Athlon when compared with code generated
+ * with MSVC++. Not sure yet, but I think the P4 will also be slower using the
+ * MMX mode because many of it's x86 ALU instructions execute in .5 cycles and
+ * have less latency than MMX ops. Added code to buffer the last 11 bytes of
+ * the input stream since the MMX code grabs bits in chunks of 32, which
+ * differs from the inffast.c algorithm. I don't think there would have been
+ * read overruns where a page boundary was crossed (a segfault), but there
+ * could have been overruns when next_in ends on unaligned memory (unintialized
+ * memory read).
+ *
+ * Mar-13-2003 -- P4 MMX is slightly slower than P4 NO_MMX. I created a C
+ * version of the non-MMX code so that it doesn't depend on zstrm and zstate
+ * structure offsets which are hard coded in this file. This was last tested
+ * with zlib-1.2.0 which is currently in beta testing, newer versions of this
+ * and inffas86.c can be found at http://www.eetbeetee.com/zlib/ and
+ * http://www.charm.net/~christop/zlib/
+ */
+
+
+/*
+ * if you have underscore linking problems (_inflate_fast undefined), try
+ * using -DGAS_COFF
+ */
+#if ! defined( GAS_COFF ) && ! defined( GAS_ELF )
+
+#if defined( WIN32 ) || defined( __CYGWIN__ )
+#define GAS_COFF /* windows object format */
+#else
+#define GAS_ELF
+#endif
+
+#endif /* ! GAS_COFF && ! GAS_ELF */
+
+
+#if defined( GAS_COFF )
+
+/* coff externals have underscores */
+#define inflate_fast _inflate_fast
+#define inflate_fast_use_mmx _inflate_fast_use_mmx
+
+#endif /* GAS_COFF */
+
+
+.file "inffast.S"
+
+.globl inflate_fast
+
+.text
+.align 4,0
+.L_invalid_literal_length_code_msg:
+.string "invalid literal/length code"
+
+.align 4,0
+.L_invalid_distance_code_msg:
+.string "invalid distance code"
+
+.align 4,0
+.L_invalid_distance_too_far_msg:
+.string "invalid distance too far back"
+
+#if ! defined( NO_MMX )
+.align 4,0
+.L_mask: /* mask[N] = ( 1 << N ) - 1 */
+.long 0
+.long 1
+.long 3
+.long 7
+.long 15
+.long 31
+.long 63
+.long 127
+.long 255
+.long 511
+.long 1023
+.long 2047
+.long 4095
+.long 8191
+.long 16383
+.long 32767
+.long 65535
+.long 131071
+.long 262143
+.long 524287
+.long 1048575
+.long 2097151
+.long 4194303
+.long 8388607
+.long 16777215
+.long 33554431
+.long 67108863
+.long 134217727
+.long 268435455
+.long 536870911
+.long 1073741823
+.long 2147483647
+.long 4294967295
+#endif /* NO_MMX */
+
+.text
+
+/*
+ * struct z_stream offsets, in zlib.h
+ */
+#define next_in_strm 0 /* strm->next_in */
+#define avail_in_strm 4 /* strm->avail_in */
+#define next_out_strm 12 /* strm->next_out */
+#define avail_out_strm 16 /* strm->avail_out */
+#define msg_strm 24 /* strm->msg */
+#define state_strm 28 /* strm->state */
+
+/*
+ * struct inflate_state offsets, in inflate.h
+ */
+#define mode_state 0 /* state->mode */
+#define wsize_state 32 /* state->wsize */
+#define write_state 40 /* state->write */
+#define window_state 44 /* state->window */
+#define hold_state 48 /* state->hold */
+#define bits_state 52 /* state->bits */
+#define lencode_state 68 /* state->lencode */
+#define distcode_state 72 /* state->distcode */
+#define lenbits_state 76 /* state->lenbits */
+#define distbits_state 80 /* state->distbits */
+
+/*
+ * inflate_fast's activation record
+ */
+#define local_var_size 64 /* how much local space for vars */
+#define strm_sp 88 /* first arg: z_stream * (local_var_size + 24) */
+#define start_sp 92 /* second arg: unsigned int (local_var_size + 28) */
+
+/*
+ * offsets for local vars on stack
+ */
+#define out 60 /* unsigned char* */
+#define window 56 /* unsigned char* */
+#define wsize 52 /* unsigned int */
+#define write 48 /* unsigned int */
+#define in 44 /* unsigned char* */
+#define beg 40 /* unsigned char* */
+#define buf 28 /* char[ 12 ] */
+#define len 24 /* unsigned int */
+#define last 20 /* unsigned char* */
+#define end 16 /* unsigned char* */
+#define dcode 12 /* code* */
+#define lcode 8 /* code* */
+#define dmask 4 /* unsigned int */
+#define lmask 0 /* unsigned int */
+
+/*
+ * typedef enum inflate_mode consts, in inflate.h
+ */
+#define INFLATE_MODE_TYPE 11 /* state->mode flags enum-ed in inflate.h */
+#define INFLATE_MODE_BAD 26
+
+
+#if ! defined( USE_MMX ) && ! defined( NO_MMX )
+
+#define RUN_TIME_MMX
+
+#define CHECK_MMX 1
+#define DO_USE_MMX 2
+#define DONT_USE_MMX 3
+
+.globl inflate_fast_use_mmx
+
+.data
+
+.align 4,0
+inflate_fast_use_mmx: /* integer flag for run time control 1=check,2=mmx,3=no */
+.long CHECK_MMX
+
+#if defined( GAS_ELF )
+/* elf info */
+.type inflate_fast_use_mmx,@object
+.size inflate_fast_use_mmx,4
+#endif
+
+#endif /* RUN_TIME_MMX */
+
+#if defined( GAS_COFF )
+/* coff info: scl 2 = extern, type 32 = function */
+.def inflate_fast; .scl 2; .type 32; .endef
+#endif
+
+.text
+
+.align 32,0x90
+inflate_fast:
+ pushl %edi
+ pushl %esi
+ pushl %ebp
+ pushl %ebx
+ pushf /* save eflags (strm_sp, state_sp assumes this is 32 bits) */
+ subl $local_var_size, %esp
+ cld
+
+#define strm_r %esi
+#define state_r %edi
+
+ movl strm_sp(%esp), strm_r
+ movl state_strm(strm_r), state_r
+
+ /* in = strm->next_in;
+ * out = strm->next_out;
+ * last = in + strm->avail_in - 11;
+ * beg = out - (start - strm->avail_out);
+ * end = out + (strm->avail_out - 257);
+ */
+ movl avail_in_strm(strm_r), %edx
+ movl next_in_strm(strm_r), %eax
+
+ addl %eax, %edx /* avail_in += next_in */
+ subl $11, %edx /* avail_in -= 11 */
+
+ movl %eax, in(%esp)
+ movl %edx, last(%esp)
+
+ movl start_sp(%esp), %ebp
+ movl avail_out_strm(strm_r), %ecx
+ movl next_out_strm(strm_r), %ebx
+
+ subl %ecx, %ebp /* start -= avail_out */
+ negl %ebp /* start = -start */
+ addl %ebx, %ebp /* start += next_out */
+
+ subl $257, %ecx /* avail_out -= 257 */
+ addl %ebx, %ecx /* avail_out += out */
+
+ movl %ebx, out(%esp)
+ movl %ebp, beg(%esp)
+ movl %ecx, end(%esp)
+
+ /* wsize = state->wsize;
+ * write = state->write;
+ * window = state->window;
+ * hold = state->hold;
+ * bits = state->bits;
+ * lcode = state->lencode;
+ * dcode = state->distcode;
+ * lmask = ( 1 << state->lenbits ) - 1;
+ * dmask = ( 1 << state->distbits ) - 1;
+ */
+
+ movl lencode_state(state_r), %eax
+ movl distcode_state(state_r), %ecx
+
+ movl %eax, lcode(%esp)
+ movl %ecx, dcode(%esp)
+
+ movl $1, %eax
+ movl lenbits_state(state_r), %ecx
+ shll %cl, %eax
+ decl %eax
+ movl %eax, lmask(%esp)
+
+ movl $1, %eax
+ movl distbits_state(state_r), %ecx
+ shll %cl, %eax
+ decl %eax
+ movl %eax, dmask(%esp)
+
+ movl wsize_state(state_r), %eax
+ movl write_state(state_r), %ecx
+ movl window_state(state_r), %edx
+
+ movl %eax, wsize(%esp)
+ movl %ecx, write(%esp)
+ movl %edx, window(%esp)
+
+ movl hold_state(state_r), %ebp
+ movl bits_state(state_r), %ebx
+
+#undef strm_r
+#undef state_r
+
+#define in_r %esi
+#define from_r %esi
+#define out_r %edi
+
+ movl in(%esp), in_r
+ movl last(%esp), %ecx
+ cmpl in_r, %ecx
+ ja .L_align_long /* if in < last */
+
+ addl $11, %ecx /* ecx = &in[ avail_in ] */
+ subl in_r, %ecx /* ecx = avail_in */
+ movl $12, %eax
+ subl %ecx, %eax /* eax = 12 - avail_in */
+ leal buf(%esp), %edi
+ rep movsb /* memcpy( buf, in, avail_in ) */
+ movl %eax, %ecx
+ xorl %eax, %eax
+ rep stosb /* memset( &buf[ avail_in ], 0, 12 - avail_in ) */
+ leal buf(%esp), in_r /* in = buf */
+ movl in_r, last(%esp) /* last = in, do just one iteration */
+ jmp .L_is_aligned
+
+ /* align in_r on long boundary */
+.L_align_long:
+ testl $3, in_r
+ jz .L_is_aligned
+ xorl %eax, %eax
+ movb (in_r), %al
+ incl in_r
+ movl %ebx, %ecx
+ addl $8, %ebx
+ shll %cl, %eax
+ orl %eax, %ebp
+ jmp .L_align_long
+
+.L_is_aligned:
+ movl out(%esp), out_r
+
+#if defined( NO_MMX )
+ jmp .L_do_loop
+#endif
+
+#if defined( USE_MMX )
+ jmp .L_init_mmx
+#endif
+
+/*** Runtime MMX check ***/
+
+#if defined( RUN_TIME_MMX )
+.L_check_mmx:
+ cmpl $DO_USE_MMX, inflate_fast_use_mmx
+ je .L_init_mmx
+ ja .L_do_loop /* > 2 */
+
+ pushl %eax
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ pushf
+ movl (%esp), %eax /* copy eflags to eax */
+ xorl $0x200000, (%esp) /* try toggling ID bit of eflags (bit 21)
+ * to see if cpu supports cpuid...
+ * ID bit method not supported by NexGen but
+ * bios may load a cpuid instruction and
+ * cpuid may be disabled on Cyrix 5-6x86 */
+ popf
+ pushf
+ popl %edx /* copy new eflags to edx */
+ xorl %eax, %edx /* test if ID bit is flipped */
+ jz .L_dont_use_mmx /* not flipped if zero */
+ xorl %eax, %eax
+ cpuid
+ cmpl $0x756e6547, %ebx /* check for GenuineIntel in ebx,ecx,edx */
+ jne .L_dont_use_mmx
+ cmpl $0x6c65746e, %ecx
+ jne .L_dont_use_mmx
+ cmpl $0x49656e69, %edx
+ jne .L_dont_use_mmx
+ movl $1, %eax
+ cpuid /* get cpu features */
+ shrl $8, %eax
+ andl $15, %eax
+ cmpl $6, %eax /* check for Pentium family, is 0xf for P4 */
+ jne .L_dont_use_mmx
+ testl $0x800000, %edx /* test if MMX feature is set (bit 23) */
+ jnz .L_use_mmx
+ jmp .L_dont_use_mmx
+.L_use_mmx:
+ movl $DO_USE_MMX, inflate_fast_use_mmx
+ jmp .L_check_mmx_pop
+.L_dont_use_mmx:
+ movl $DONT_USE_MMX, inflate_fast_use_mmx
+.L_check_mmx_pop:
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %eax
+ jmp .L_check_mmx
+#endif
+
+
+/*** Non-MMX code ***/
+
+#if defined ( NO_MMX ) || defined( RUN_TIME_MMX )
+
+#define hold_r %ebp
+#define bits_r %bl
+#define bitslong_r %ebx
+
+.align 32,0x90
+.L_while_test:
+ /* while (in < last && out < end)
+ */
+ cmpl out_r, end(%esp)
+ jbe .L_break_loop /* if (out >= end) */
+
+ cmpl in_r, last(%esp)
+ jbe .L_break_loop
+
+.L_do_loop:
+ /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
+ *
+ * do {
+ * if (bits < 15) {
+ * hold |= *((unsigned short *)in)++ << bits;
+ * bits += 16
+ * }
+ * this = lcode[hold & lmask]
+ */
+ cmpb $15, bits_r
+ ja .L_get_length_code /* if (15 < bits) */
+
+ xorl %eax, %eax
+ lodsw /* al = *(ushort *)in++ */
+ movb bits_r, %cl /* cl = bits, needs it for shifting */
+ addb $16, bits_r /* bits += 16 */
+ shll %cl, %eax
+ orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
+
+.L_get_length_code:
+ movl lmask(%esp), %edx /* edx = lmask */
+ movl lcode(%esp), %ecx /* ecx = lcode */
+ andl hold_r, %edx /* edx &= hold */
+ movl (%ecx,%edx,4), %eax /* eax = lcode[hold & lmask] */
+
+.L_dolen:
+ /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
+ *
+ * dolen:
+ * bits -= this.bits;
+ * hold >>= this.bits
+ */
+ movb %ah, %cl /* cl = this.bits */
+ subb %ah, bits_r /* bits -= this.bits */
+ shrl %cl, hold_r /* hold >>= this.bits */
+
+ /* check if op is a literal
+ * if (op == 0) {
+ * PUP(out) = this.val;
+ * }
+ */
+ testb %al, %al
+ jnz .L_test_for_length_base /* if (op != 0) 45.7% */
+
+ shrl $16, %eax /* output this.val char */
+ stosb
+ jmp .L_while_test
+
+.L_test_for_length_base:
+ /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = len
+ *
+ * else if (op & 16) {
+ * len = this.val
+ * op &= 15
+ * if (op) {
+ * if (op > bits) {
+ * hold |= *((unsigned short *)in)++ << bits;
+ * bits += 16
+ * }
+ * len += hold & mask[op];
+ * bits -= op;
+ * hold >>= op;
+ * }
+ */
+#define len_r %edx
+ movl %eax, len_r /* len = this */
+ shrl $16, len_r /* len = this.val */
+ movb %al, %cl
+
+ testb $16, %al
+ jz .L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
+ andb $15, %cl /* op &= 15 */
+ jz .L_save_len /* if (!op) */
+ cmpb %cl, bits_r
+ jae .L_add_bits_to_len /* if (op <= bits) */
+
+ movb %cl, %ch /* stash op in ch, freeing cl */
+ xorl %eax, %eax
+ lodsw /* al = *(ushort *)in++ */
+ movb bits_r, %cl /* cl = bits, needs it for shifting */
+ addb $16, bits_r /* bits += 16 */
+ shll %cl, %eax
+ orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
+ movb %ch, %cl /* move op back to ecx */
+
+.L_add_bits_to_len:
+ movl $1, %eax
+ shll %cl, %eax
+ decl %eax
+ subb %cl, bits_r
+ andl hold_r, %eax /* eax &= hold */
+ shrl %cl, hold_r
+ addl %eax, len_r /* len += hold & mask[op] */
+
+.L_save_len:
+ movl len_r, len(%esp) /* save len */
+#undef len_r
+
+.L_decode_distance:
+ /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+ *
+ * if (bits < 15) {
+ * hold |= *((unsigned short *)in)++ << bits;
+ * bits += 16
+ * }
+ * this = dcode[hold & dmask];
+ * dodist:
+ * bits -= this.bits;
+ * hold >>= this.bits;
+ * op = this.op;
+ */
+
+ cmpb $15, bits_r
+ ja .L_get_distance_code /* if (15 < bits) */
+
+ xorl %eax, %eax
+ lodsw /* al = *(ushort *)in++ */
+ movb bits_r, %cl /* cl = bits, needs it for shifting */
+ addb $16, bits_r /* bits += 16 */
+ shll %cl, %eax
+ orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
+
+.L_get_distance_code:
+ movl dmask(%esp), %edx /* edx = dmask */
+ movl dcode(%esp), %ecx /* ecx = dcode */
+ andl hold_r, %edx /* edx &= hold */
+ movl (%ecx,%edx,4), %eax /* eax = dcode[hold & dmask] */
+
+#define dist_r %edx
+.L_dodist:
+ movl %eax, dist_r /* dist = this */
+ shrl $16, dist_r /* dist = this.val */
+ movb %ah, %cl
+ subb %ah, bits_r /* bits -= this.bits */
+ shrl %cl, hold_r /* hold >>= this.bits */
+
+ /* if (op & 16) {
+ * dist = this.val
+ * op &= 15
+ * if (op > bits) {
+ * hold |= *((unsigned short *)in)++ << bits;
+ * bits += 16
+ * }
+ * dist += hold & mask[op];
+ * bits -= op;
+ * hold >>= op;
+ */
+ movb %al, %cl /* cl = this.op */
+
+ testb $16, %al /* if ((op & 16) == 0) */
+ jz .L_test_for_second_level_dist
+ andb $15, %cl /* op &= 15 */
+ jz .L_check_dist_one
+ cmpb %cl, bits_r
+ jae .L_add_bits_to_dist /* if (op <= bits) 97.6% */
+
+ movb %cl, %ch /* stash op in ch, freeing cl */
+ xorl %eax, %eax
+ lodsw /* al = *(ushort *)in++ */
+ movb bits_r, %cl /* cl = bits, needs it for shifting */
+ addb $16, bits_r /* bits += 16 */
+ shll %cl, %eax
+ orl %eax, hold_r /* hold |= *((ushort *)in)++ << bits */
+ movb %ch, %cl /* move op back to ecx */
+
+.L_add_bits_to_dist:
+ movl $1, %eax
+ shll %cl, %eax
+ decl %eax /* (1 << op) - 1 */
+ subb %cl, bits_r
+ andl hold_r, %eax /* eax &= hold */
+ shrl %cl, hold_r
+ addl %eax, dist_r /* dist += hold & ((1 << op) - 1) */
+ jmp .L_check_window
+
+.L_check_window:
+ /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+ * %ecx = nbytes
+ *
+ * nbytes = out - beg;
+ * if (dist <= nbytes) {
+ * from = out - dist;
+ * do {
+ * PUP(out) = PUP(from);
+ * } while (--len > 0) {
+ * }
+ */
+
+ movl in_r, in(%esp) /* save in so from can use it's reg */
+ movl out_r, %eax
+ subl beg(%esp), %eax /* nbytes = out - beg */
+
+ cmpl dist_r, %eax
+ jb .L_clip_window /* if (dist > nbytes) 4.2% */
+
+ movl len(%esp), %ecx
+ movl out_r, from_r
+ subl dist_r, from_r /* from = out - dist */
+
+ subl $3, %ecx
+ movb (from_r), %al
+ movb %al, (out_r)
+ movb 1(from_r), %al
+ movb 2(from_r), %dl
+ addl $3, from_r
+ movb %al, 1(out_r)
+ movb %dl, 2(out_r)
+ addl $3, out_r
+ rep movsb
+
+ movl in(%esp), in_r /* move in back to %esi, toss from */
+ jmp .L_while_test
+
+.align 16,0x90
+.L_check_dist_one:
+ cmpl $1, dist_r
+ jne .L_check_window
+ cmpl out_r, beg(%esp)
+ je .L_check_window
+
+ decl out_r
+ movl len(%esp), %ecx
+ movb (out_r), %al
+ subl $3, %ecx
+
+ movb %al, 1(out_r)
+ movb %al, 2(out_r)
+ movb %al, 3(out_r)
+ addl $4, out_r
+ rep stosb
+
+ jmp .L_while_test
+
+.align 16,0x90
+.L_test_for_second_level_length:
+ /* else if ((op & 64) == 0) {
+ * this = lcode[this.val + (hold & mask[op])];
+ * }
+ */
+ testb $64, %al
+ jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */
+
+ movl $1, %eax
+ shll %cl, %eax
+ decl %eax
+ andl hold_r, %eax /* eax &= hold */
+ addl %edx, %eax /* eax += this.val */
+ movl lcode(%esp), %edx /* edx = lcode */
+ movl (%edx,%eax,4), %eax /* eax = lcode[val + (hold&mask[op])] */
+ jmp .L_dolen
+
+.align 16,0x90
+.L_test_for_second_level_dist:
+ /* else if ((op & 64) == 0) {
+ * this = dcode[this.val + (hold & mask[op])];
+ * }
+ */
+ testb $64, %al
+ jnz .L_invalid_distance_code /* if ((op & 64) != 0) */
+
+ movl $1, %eax
+ shll %cl, %eax
+ decl %eax
+ andl hold_r, %eax /* eax &= hold */
+ addl %edx, %eax /* eax += this.val */
+ movl dcode(%esp), %edx /* edx = dcode */
+ movl (%edx,%eax,4), %eax /* eax = dcode[val + (hold&mask[op])] */
+ jmp .L_dodist
+
+.align 16,0x90
+.L_clip_window:
+ /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+ * %ecx = nbytes
+ *
+ * else {
+ * if (dist > wsize) {
+ * invalid distance
+ * }
+ * from = window;
+ * nbytes = dist - nbytes;
+ * if (write == 0) {
+ * from += wsize - nbytes;
+ */
+#define nbytes_r %ecx
+ movl %eax, nbytes_r
+ movl wsize(%esp), %eax /* prepare for dist compare */
+ negl nbytes_r /* nbytes = -nbytes */
+ movl window(%esp), from_r /* from = window */
+
+ cmpl dist_r, %eax
+ jb .L_invalid_distance_too_far /* if (dist > wsize) */
+
+ addl dist_r, nbytes_r /* nbytes = dist - nbytes */
+ cmpl $0, write(%esp)
+ jne .L_wrap_around_window /* if (write != 0) */
+
+ subl nbytes_r, %eax
+ addl %eax, from_r /* from += wsize - nbytes */
+
+ /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+ * %ecx = nbytes, %eax = len
+ *
+ * if (nbytes < len) {
+ * len -= nbytes;
+ * do {
+ * PUP(out) = PUP(from);
+ * } while (--nbytes);
+ * from = out - dist;
+ * }
+ * }
+ */
+#define len_r %eax
+ movl len(%esp), len_r
+ cmpl nbytes_r, len_r
+ jbe .L_do_copy1 /* if (nbytes >= len) */
+
+ subl nbytes_r, len_r /* len -= nbytes */
+ rep movsb
+ movl out_r, from_r
+ subl dist_r, from_r /* from = out - dist */
+ jmp .L_do_copy1
+
+ cmpl nbytes_r, len_r
+ jbe .L_do_copy1 /* if (nbytes >= len) */
+
+ subl nbytes_r, len_r /* len -= nbytes */
+ rep movsb
+ movl out_r, from_r
+ subl dist_r, from_r /* from = out - dist */
+ jmp .L_do_copy1
+
+.L_wrap_around_window:
+ /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+ * %ecx = nbytes, %eax = write, %eax = len
+ *
+ * else if (write < nbytes) {
+ * from += wsize + write - nbytes;
+ * nbytes -= write;
+ * if (nbytes < len) {
+ * len -= nbytes;
+ * do {
+ * PUP(out) = PUP(from);
+ * } while (--nbytes);
+ * from = window;
+ * nbytes = write;
+ * if (nbytes < len) {
+ * len -= nbytes;
+ * do {
+ * PUP(out) = PUP(from);
+ * } while(--nbytes);
+ * from = out - dist;
+ * }
+ * }
+ * }
+ */
+#define write_r %eax
+ movl write(%esp), write_r
+ cmpl write_r, nbytes_r
+ jbe .L_contiguous_in_window /* if (write >= nbytes) */
+
+ addl wsize(%esp), from_r
+ addl write_r, from_r
+ subl nbytes_r, from_r /* from += wsize + write - nbytes */
+ subl write_r, nbytes_r /* nbytes -= write */
+#undef write_r
+
+ movl len(%esp), len_r
+ cmpl nbytes_r, len_r
+ jbe .L_do_copy1 /* if (nbytes >= len) */
+
+ subl nbytes_r, len_r /* len -= nbytes */
+ rep movsb
+ movl window(%esp), from_r /* from = window */
+ movl write(%esp), nbytes_r /* nbytes = write */
+ cmpl nbytes_r, len_r
+ jbe .L_do_copy1 /* if (nbytes >= len) */
+
+ subl nbytes_r, len_r /* len -= nbytes */
+ rep movsb
+ movl out_r, from_r
+ subl dist_r, from_r /* from = out - dist */
+ jmp .L_do_copy1
+
+.L_contiguous_in_window:
+ /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+ * %ecx = nbytes, %eax = write, %eax = len
+ *
+ * else {
+ * from += write - nbytes;
+ * if (nbytes < len) {
+ * len -= nbytes;
+ * do {
+ * PUP(out) = PUP(from);
+ * } while (--nbytes);
+ * from = out - dist;
+ * }
+ * }
+ */
+#define write_r %eax
+ addl write_r, from_r
+ subl nbytes_r, from_r /* from += write - nbytes */
+#undef write_r
+
+ movl len(%esp), len_r
+ cmpl nbytes_r, len_r
+ jbe .L_do_copy1 /* if (nbytes >= len) */
+
+ subl nbytes_r, len_r /* len -= nbytes */
+ rep movsb
+ movl out_r, from_r
+ subl dist_r, from_r /* from = out - dist */
+
+.L_do_copy1:
+ /* regs: %esi = from, %esi = in, %ebp = hold, %bl = bits, %edi = out
+ * %eax = len
+ *
+ * while (len > 0) {
+ * PUP(out) = PUP(from);
+ * len--;
+ * }
+ * }
+ * } while (in < last && out < end);
+ */
+#undef nbytes_r
+#define in_r %esi
+ movl len_r, %ecx
+ rep movsb
+
+ movl in(%esp), in_r /* move in back to %esi, toss from */
+ jmp .L_while_test
+
+#undef len_r
+#undef dist_r
+
+#endif /* NO_MMX || RUN_TIME_MMX */
+
+
+/*** MMX code ***/
+
+#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
+
+.align 32,0x90
+.L_init_mmx:
+ emms
+
+#undef bits_r
+#undef bitslong_r
+#define bitslong_r %ebp
+#define hold_mm %mm0
+ movd %ebp, hold_mm
+ movl %ebx, bitslong_r
+
+#define used_mm %mm1
+#define dmask2_mm %mm2
+#define lmask2_mm %mm3
+#define lmask_mm %mm4
+#define dmask_mm %mm5
+#define tmp_mm %mm6
+
+ movd lmask(%esp), lmask_mm
+ movq lmask_mm, lmask2_mm
+ movd dmask(%esp), dmask_mm
+ movq dmask_mm, dmask2_mm
+ pxor used_mm, used_mm
+ movl lcode(%esp), %ebx /* ebx = lcode */
+ jmp .L_do_loop_mmx
+
+.align 32,0x90
+.L_while_test_mmx:
+ /* while (in < last && out < end)
+ */
+ cmpl out_r, end(%esp)
+ jbe .L_break_loop /* if (out >= end) */
+
+ cmpl in_r, last(%esp)
+ jbe .L_break_loop
+
+.L_do_loop_mmx:
+ psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
+
+ cmpl $32, bitslong_r
+ ja .L_get_length_code_mmx /* if (32 < bits) */
+
+ movd bitslong_r, tmp_mm
+ movd (in_r), %mm7
+ addl $4, in_r
+ psllq tmp_mm, %mm7
+ addl $32, bitslong_r
+ por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */
+
+.L_get_length_code_mmx:
+ pand hold_mm, lmask_mm
+ movd lmask_mm, %eax
+ movq lmask2_mm, lmask_mm
+ movl (%ebx,%eax,4), %eax /* eax = lcode[hold & lmask] */
+
+.L_dolen_mmx:
+ movzbl %ah, %ecx /* ecx = this.bits */
+ movd %ecx, used_mm
+ subl %ecx, bitslong_r /* bits -= this.bits */
+
+ testb %al, %al
+ jnz .L_test_for_length_base_mmx /* if (op != 0) 45.7% */
+
+ shrl $16, %eax /* output this.val char */
+ stosb
+ jmp .L_while_test_mmx
+
+.L_test_for_length_base_mmx:
+#define len_r %edx
+ movl %eax, len_r /* len = this */
+ shrl $16, len_r /* len = this.val */
+
+ testb $16, %al
+ jz .L_test_for_second_level_length_mmx /* if ((op & 16) == 0) 8% */
+ andl $15, %eax /* op &= 15 */
+ jz .L_decode_distance_mmx /* if (!op) */
+
+ psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
+ movd %eax, used_mm
+ movd hold_mm, %ecx
+ subl %eax, bitslong_r
+ andl .L_mask(,%eax,4), %ecx
+ addl %ecx, len_r /* len += hold & mask[op] */
+
+.L_decode_distance_mmx:
+ psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
+
+ cmpl $32, bitslong_r
+ ja .L_get_dist_code_mmx /* if (32 < bits) */
+
+ movd bitslong_r, tmp_mm
+ movd (in_r), %mm7
+ addl $4, in_r
+ psllq tmp_mm, %mm7
+ addl $32, bitslong_r
+ por %mm7, hold_mm /* hold_mm |= *((uint *)in)++ << bits */
+
+.L_get_dist_code_mmx:
+ movl dcode(%esp), %ebx /* ebx = dcode */
+ pand hold_mm, dmask_mm
+ movd dmask_mm, %eax
+ movq dmask2_mm, dmask_mm
+ movl (%ebx,%eax,4), %eax /* eax = dcode[hold & lmask] */
+
+.L_dodist_mmx:
+#define dist_r %ebx
+ movzbl %ah, %ecx /* ecx = this.bits */
+ movl %eax, dist_r
+ shrl $16, dist_r /* dist = this.val */
+ subl %ecx, bitslong_r /* bits -= this.bits */
+ movd %ecx, used_mm
+
+ testb $16, %al /* if ((op & 16) == 0) */
+ jz .L_test_for_second_level_dist_mmx
+ andl $15, %eax /* op &= 15 */
+ jz .L_check_dist_one_mmx
+
+.L_add_bits_to_dist_mmx:
+ psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
+ movd %eax, used_mm /* save bit length of current op */
+ movd hold_mm, %ecx /* get the next bits on input stream */
+ subl %eax, bitslong_r /* bits -= op bits */
+ andl .L_mask(,%eax,4), %ecx /* ecx = hold & mask[op] */
+ addl %ecx, dist_r /* dist += hold & mask[op] */
+
+.L_check_window_mmx:
+ movl in_r, in(%esp) /* save in so from can use it's reg */
+ movl out_r, %eax
+ subl beg(%esp), %eax /* nbytes = out - beg */
+
+ cmpl dist_r, %eax
+ jb .L_clip_window_mmx /* if (dist > nbytes) 4.2% */
+
+ movl len_r, %ecx
+ movl out_r, from_r
+ subl dist_r, from_r /* from = out - dist */
+
+ subl $3, %ecx
+ movb (from_r), %al
+ movb %al, (out_r)
+ movb 1(from_r), %al
+ movb 2(from_r), %dl
+ addl $3, from_r
+ movb %al, 1(out_r)
+ movb %dl, 2(out_r)
+ addl $3, out_r
+ rep movsb
+
+ movl in(%esp), in_r /* move in back to %esi, toss from */
+ movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */
+ jmp .L_while_test_mmx
+
+.align 16,0x90
+.L_check_dist_one_mmx:
+ cmpl $1, dist_r
+ jne .L_check_window_mmx
+ cmpl out_r, beg(%esp)
+ je .L_check_window_mmx
+
+ decl out_r
+ movl len_r, %ecx
+ movb (out_r), %al
+ subl $3, %ecx
+
+ movb %al, 1(out_r)
+ movb %al, 2(out_r)
+ movb %al, 3(out_r)
+ addl $4, out_r
+ rep stosb
+
+ movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */
+ jmp .L_while_test_mmx
+
+.align 16,0x90
+.L_test_for_second_level_length_mmx:
+ testb $64, %al
+ jnz .L_test_for_end_of_block /* if ((op & 64) != 0) */
+
+ andl $15, %eax
+ psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
+ movd hold_mm, %ecx
+ andl .L_mask(,%eax,4), %ecx
+ addl len_r, %ecx
+ movl (%ebx,%ecx,4), %eax /* eax = lcode[hold & lmask] */
+ jmp .L_dolen_mmx
+
+.align 16,0x90
+.L_test_for_second_level_dist_mmx:
+ testb $64, %al
+ jnz .L_invalid_distance_code /* if ((op & 64) != 0) */
+
+ andl $15, %eax
+ psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
+ movd hold_mm, %ecx
+ andl .L_mask(,%eax,4), %ecx
+ movl dcode(%esp), %eax /* ecx = dcode */
+ addl dist_r, %ecx
+ movl (%eax,%ecx,4), %eax /* eax = lcode[hold & lmask] */
+ jmp .L_dodist_mmx
+
+.align 16,0x90
+.L_clip_window_mmx:
+#define nbytes_r %ecx
+ movl %eax, nbytes_r
+ movl wsize(%esp), %eax /* prepare for dist compare */
+ negl nbytes_r /* nbytes = -nbytes */
+ movl window(%esp), from_r /* from = window */
+
+ cmpl dist_r, %eax
+ jb .L_invalid_distance_too_far /* if (dist > wsize) */
+
+ addl dist_r, nbytes_r /* nbytes = dist - nbytes */
+ cmpl $0, write(%esp)
+ jne .L_wrap_around_window_mmx /* if (write != 0) */
+
+ subl nbytes_r, %eax
+ addl %eax, from_r /* from += wsize - nbytes */
+
+ cmpl nbytes_r, len_r
+ jbe .L_do_copy1_mmx /* if (nbytes >= len) */
+
+ subl nbytes_r, len_r /* len -= nbytes */
+ rep movsb
+ movl out_r, from_r
+ subl dist_r, from_r /* from = out - dist */
+ jmp .L_do_copy1_mmx
+
+ cmpl nbytes_r, len_r
+ jbe .L_do_copy1_mmx /* if (nbytes >= len) */
+
+ subl nbytes_r, len_r /* len -= nbytes */
+ rep movsb
+ movl out_r, from_r
+ subl dist_r, from_r /* from = out - dist */
+ jmp .L_do_copy1_mmx
+
+.L_wrap_around_window_mmx:
+#define write_r %eax
+ movl write(%esp), write_r
+ cmpl write_r, nbytes_r
+ jbe .L_contiguous_in_window_mmx /* if (write >= nbytes) */
+
+ addl wsize(%esp), from_r
+ addl write_r, from_r
+ subl nbytes_r, from_r /* from += wsize + write - nbytes */
+ subl write_r, nbytes_r /* nbytes -= write */
+#undef write_r
+
+ cmpl nbytes_r, len_r
+ jbe .L_do_copy1_mmx /* if (nbytes >= len) */
+
+ subl nbytes_r, len_r /* len -= nbytes */
+ rep movsb
+ movl window(%esp), from_r /* from = window */
+ movl write(%esp), nbytes_r /* nbytes = write */
+ cmpl nbytes_r, len_r
+ jbe .L_do_copy1_mmx /* if (nbytes >= len) */
+
+ subl nbytes_r, len_r /* len -= nbytes */
+ rep movsb
+ movl out_r, from_r
+ subl dist_r, from_r /* from = out - dist */
+ jmp .L_do_copy1_mmx
+
+.L_contiguous_in_window_mmx:
+#define write_r %eax
+ addl write_r, from_r
+ subl nbytes_r, from_r /* from += write - nbytes */
+#undef write_r
+
+ cmpl nbytes_r, len_r
+ jbe .L_do_copy1_mmx /* if (nbytes >= len) */
+
+ subl nbytes_r, len_r /* len -= nbytes */
+ rep movsb
+ movl out_r, from_r
+ subl dist_r, from_r /* from = out - dist */
+
+.L_do_copy1_mmx:
+#undef nbytes_r
+#define in_r %esi
+ movl len_r, %ecx
+ rep movsb
+
+ movl in(%esp), in_r /* move in back to %esi, toss from */
+ movl lcode(%esp), %ebx /* move lcode back to %ebx, toss dist */
+ jmp .L_while_test_mmx
+
+#undef hold_r
+#undef bitslong_r
+
+#endif /* USE_MMX || RUN_TIME_MMX */
+
+
+/*** USE_MMX, NO_MMX, and RUNTIME_MMX from here on ***/
+
+.L_invalid_distance_code:
+ /* else {
+ * strm->msg = "invalid distance code";
+ * state->mode = BAD;
+ * }
+ */
+ movl $.L_invalid_distance_code_msg, %ecx
+ movl $INFLATE_MODE_BAD, %edx
+ jmp .L_update_stream_state
+
+.L_test_for_end_of_block:
+ /* else if (op & 32) {
+ * state->mode = TYPE;
+ * break;
+ * }
+ */
+ testb $32, %al
+ jz .L_invalid_literal_length_code /* if ((op & 32) == 0) */
+
+ movl $0, %ecx
+ movl $INFLATE_MODE_TYPE, %edx
+ jmp .L_update_stream_state
+
+.L_invalid_literal_length_code:
+ /* else {
+ * strm->msg = "invalid literal/length code";
+ * state->mode = BAD;
+ * }
+ */
+ movl $.L_invalid_literal_length_code_msg, %ecx
+ movl $INFLATE_MODE_BAD, %edx
+ jmp .L_update_stream_state
+
+.L_invalid_distance_too_far:
+ /* strm->msg = "invalid distance too far back";
+ * state->mode = BAD;
+ */
+ movl in(%esp), in_r /* from_r has in's reg, put in back */
+ movl $.L_invalid_distance_too_far_msg, %ecx
+ movl $INFLATE_MODE_BAD, %edx
+ jmp .L_update_stream_state
+
+.L_update_stream_state:
+ /* set strm->msg = %ecx, strm->state->mode = %edx */
+ movl strm_sp(%esp), %eax
+ testl %ecx, %ecx /* if (msg != NULL) */
+ jz .L_skip_msg
+ movl %ecx, msg_strm(%eax) /* strm->msg = msg */
+.L_skip_msg:
+ movl state_strm(%eax), %eax /* state = strm->state */
+ movl %edx, mode_state(%eax) /* state->mode = edx (BAD | TYPE) */
+ jmp .L_break_loop
+
+.align 32,0x90
+.L_break_loop:
+
+/*
+ * Regs:
+ *
+ * bits = %ebp when mmx, and in %ebx when non-mmx
+ * hold = %hold_mm when mmx, and in %ebp when non-mmx
+ * in = %esi
+ * out = %edi
+ */
+
+#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
+
+#if defined( RUN_TIME_MMX )
+
+ cmpl $DO_USE_MMX, inflate_fast_use_mmx
+ jne .L_update_next_in
+
+#endif /* RUN_TIME_MMX */
+
+ movl %ebp, %ebx
+
+.L_update_next_in:
+
+#endif
+
+#define strm_r %eax
+#define state_r %edx
+
+ /* len = bits >> 3;
+ * in -= len;
+ * bits -= len << 3;
+ * hold &= (1U << bits) - 1;
+ * state->hold = hold;
+ * state->bits = bits;
+ * strm->next_in = in;
+ * strm->next_out = out;
+ */
+ movl strm_sp(%esp), strm_r
+ movl %ebx, %ecx
+ movl state_strm(strm_r), state_r
+ shrl $3, %ecx
+ subl %ecx, in_r
+ shll $3, %ecx
+ subl %ecx, %ebx
+ movl out_r, next_out_strm(strm_r)
+ movl %ebx, bits_state(state_r)
+ movl %ebx, %ecx
+
+ leal buf(%esp), %ebx
+ cmpl %ebx, last(%esp)
+ jne .L_buf_not_used /* if buf != last */
+
+ subl %ebx, in_r /* in -= buf */
+ movl next_in_strm(strm_r), %ebx
+ movl %ebx, last(%esp) /* last = strm->next_in */
+ addl %ebx, in_r /* in += strm->next_in */
+ movl avail_in_strm(strm_r), %ebx
+ subl $11, %ebx
+ addl %ebx, last(%esp) /* last = &strm->next_in[ avail_in - 11 ] */
+
+.L_buf_not_used:
+ movl in_r, next_in_strm(strm_r)
+
+ movl $1, %ebx
+ shll %cl, %ebx
+ decl %ebx
+
+#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
+
+#if defined( RUN_TIME_MMX )
+
+ cmpl $DO_USE_MMX, inflate_fast_use_mmx
+ jne .L_update_hold
+
+#endif /* RUN_TIME_MMX */
+
+ psrlq used_mm, hold_mm /* hold_mm >>= last bit length */
+ movd hold_mm, %ebp
+
+ emms
+
+.L_update_hold:
+
+#endif /* USE_MMX || RUN_TIME_MMX */
+
+ andl %ebx, %ebp
+ movl %ebp, hold_state(state_r)
+
+#define last_r %ebx
+
+ /* strm->avail_in = in < last ? 11 + (last - in) : 11 - (in - last) */
+ movl last(%esp), last_r
+ cmpl in_r, last_r
+ jbe .L_last_is_smaller /* if (in >= last) */
+
+ subl in_r, last_r /* last -= in */
+ addl $11, last_r /* last += 11 */
+ movl last_r, avail_in_strm(strm_r)
+ jmp .L_fixup_out
+.L_last_is_smaller:
+ subl last_r, in_r /* in -= last */
+ negl in_r /* in = -in */
+ addl $11, in_r /* in += 11 */
+ movl in_r, avail_in_strm(strm_r)
+
+#undef last_r
+#define end_r %ebx
+
+.L_fixup_out:
+ /* strm->avail_out = out < end ? 257 + (end - out) : 257 - (out - end)*/
+ movl end(%esp), end_r
+ cmpl out_r, end_r
+ jbe .L_end_is_smaller /* if (out >= end) */
+
+ subl out_r, end_r /* end -= out */
+ addl $257, end_r /* end += 257 */
+ movl end_r, avail_out_strm(strm_r)
+ jmp .L_done
+.L_end_is_smaller:
+ subl end_r, out_r /* out -= end */
+ negl out_r /* out = -out */
+ addl $257, out_r /* out += 257 */
+ movl out_r, avail_out_strm(strm_r)
+
+#undef end_r
+#undef strm_r
+#undef state_r
+
+.L_done:
+ addl $local_var_size, %esp
+ popf
+ popl %ebx
+ popl %ebp
+ popl %esi
+ popl %edi
+ ret
+
+#if defined( GAS_ELF )
+/* elf info */
+.type inflate_fast,@function
+.size inflate_fast,.-inflate_fast
+#endif
diff --git a/xs/src/png/zlib/contrib/iostream/test.cpp b/xs/src/png/zlib/contrib/iostream/test.cpp
new file mode 100644
index 000000000..7d265b3b5
--- /dev/null
+++ b/xs/src/png/zlib/contrib/iostream/test.cpp
@@ -0,0 +1,24 @@
+
+#include "zfstream.h"
+
+int main() {
+
+ // Construct a stream object with this filebuffer. Anything sent
+ // to this stream will go to standard out.
+ gzofstream os( 1, ios::out );
+
+ // This text is getting compressed and sent to stdout.
+ // To prove this, run 'test | zcat'.
+ os << "Hello, Mommy" << endl;
+
+ os << setcompressionlevel( Z_NO_COMPRESSION );
+ os << "hello, hello, hi, ho!" << endl;
+
+ setcompressionlevel( os, Z_DEFAULT_COMPRESSION )
+ << "I'm compressing again" << endl;
+
+ os.close();
+
+ return 0;
+
+}
diff --git a/xs/src/png/zlib/contrib/iostream/zfstream.cpp b/xs/src/png/zlib/contrib/iostream/zfstream.cpp
new file mode 100644
index 000000000..d0cd85faa
--- /dev/null
+++ b/xs/src/png/zlib/contrib/iostream/zfstream.cpp
@@ -0,0 +1,329 @@
+
+#include "zfstream.h"
+
+gzfilebuf::gzfilebuf() :
+ file(NULL),
+ mode(0),
+ own_file_descriptor(0)
+{ }
+
+gzfilebuf::~gzfilebuf() {
+
+ sync();
+ if ( own_file_descriptor )
+ close();
+
+}
+
+gzfilebuf *gzfilebuf::open( const char *name,
+ int io_mode ) {
+
+ if ( is_open() )
+ return NULL;
+
+ char char_mode[10];
+ char *p = char_mode;
+
+ if ( io_mode & ios::in ) {
+ mode = ios::in;
+ *p++ = 'r';
+ } else if ( io_mode & ios::app ) {
+ mode = ios::app;
+ *p++ = 'a';
+ } else {
+ mode = ios::out;
+ *p++ = 'w';
+ }
+
+ if ( io_mode & ios::binary ) {
+ mode |= ios::binary;
+ *p++ = 'b';
+ }
+
+ // Hard code the compression level
+ if ( io_mode & (ios::out|ios::app )) {
+ *p++ = '9';
+ }
+
+ // Put the end-of-string indicator
+ *p = '\0';
+
+ if ( (file = gzopen(name, char_mode)) == NULL )
+ return NULL;
+
+ own_file_descriptor = 1;
+
+ return this;
+
+}
+
+gzfilebuf *gzfilebuf::attach( int file_descriptor,
+ int io_mode ) {
+
+ if ( is_open() )
+ return NULL;
+
+ char char_mode[10];
+ char *p = char_mode;
+
+ if ( io_mode & ios::in ) {
+ mode = ios::in;
+ *p++ = 'r';
+ } else if ( io_mode & ios::app ) {
+ mode = ios::app;
+ *p++ = 'a';
+ } else {
+ mode = ios::out;
+ *p++ = 'w';
+ }
+
+ if ( io_mode & ios::binary ) {
+ mode |= ios::binary;
+ *p++ = 'b';
+ }
+
+ // Hard code the compression level
+ if ( io_mode & (ios::out|ios::app )) {
+ *p++ = '9';
+ }
+
+ // Put the end-of-string indicator
+ *p = '\0';
+
+ if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
+ return NULL;
+
+ own_file_descriptor = 0;
+
+ return this;
+
+}
+
+gzfilebuf *gzfilebuf::close() {
+
+ if ( is_open() ) {
+
+ sync();
+ gzclose( file );
+ file = NULL;
+
+ }
+
+ return this;
+
+}
+
+int gzfilebuf::setcompressionlevel( int comp_level ) {
+
+ return gzsetparams(file, comp_level, -2);
+
+}
+
+int gzfilebuf::setcompressionstrategy( int comp_strategy ) {
+
+ return gzsetparams(file, -2, comp_strategy);
+
+}
+
+
+streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
+
+ return streampos(EOF);
+
+}
+
+int gzfilebuf::underflow() {
+
+ // If the file hasn't been opened for reading, error.
+ if ( !is_open() || !(mode & ios::in) )
+ return EOF;
+
+ // if a buffer doesn't exists, allocate one.
+ if ( !base() ) {
+
+ if ( (allocate()) == EOF )
+ return EOF;
+ setp(0,0);
+
+ } else {
+
+ if ( in_avail() )
+ return (unsigned char) *gptr();
+
+ if ( out_waiting() ) {
+ if ( flushbuf() == EOF )
+ return EOF;
+ }
+
+ }
+
+ // Attempt to fill the buffer.
+
+ int result = fillbuf();
+ if ( result == EOF ) {
+ // disable get area
+ setg(0,0,0);
+ return EOF;
+ }
+
+ return (unsigned char) *gptr();
+
+}
+
+int gzfilebuf::overflow( int c ) {
+
+ if ( !is_open() || !(mode & ios::out) )
+ return EOF;
+
+ if ( !base() ) {
+ if ( allocate() == EOF )
+ return EOF;
+ setg(0,0,0);
+ } else {
+ if (in_avail()) {
+ return EOF;
+ }
+ if (out_waiting()) {
+ if (flushbuf() == EOF)
+ return EOF;
+ }
+ }
+
+ int bl = blen();
+ setp( base(), base() + bl);
+
+ if ( c != EOF ) {
+
+ *pptr() = c;
+ pbump(1);
+
+ }
+
+ return 0;
+
+}
+
+int gzfilebuf::sync() {
+
+ if ( !is_open() )
+ return EOF;
+
+ if ( out_waiting() )
+ return flushbuf();
+
+ return 0;
+
+}
+
+int gzfilebuf::flushbuf() {
+
+ int n;
+ char *q;
+
+ q = pbase();
+ n = pptr() - q;
+
+ if ( gzwrite( file, q, n) < n )
+ return EOF;
+
+ setp(0,0);
+
+ return 0;
+
+}
+
+int gzfilebuf::fillbuf() {
+
+ int required;
+ char *p;
+
+ p = base();
+
+ required = blen();
+
+ int t = gzread( file, p, required );
+
+ if ( t <= 0) return EOF;
+
+ setg( base(), base(), base()+t);
+
+ return t;
+
+}
+
+gzfilestream_common::gzfilestream_common() :
+ ios( gzfilestream_common::rdbuf() )
+{ }
+
+gzfilestream_common::~gzfilestream_common()
+{ }
+
+void gzfilestream_common::attach( int fd, int io_mode ) {
+
+ if ( !buffer.attach( fd, io_mode) )
+ clear( ios::failbit | ios::badbit );
+ else
+ clear();
+
+}
+
+void gzfilestream_common::open( const char *name, int io_mode ) {
+
+ if ( !buffer.open( name, io_mode ) )
+ clear( ios::failbit | ios::badbit );
+ else
+ clear();
+
+}
+
+void gzfilestream_common::close() {
+
+ if ( !buffer.close() )
+ clear( ios::failbit | ios::badbit );
+
+}
+
+gzfilebuf *gzfilestream_common::rdbuf()
+{
+ return &buffer;
+}
+
+gzifstream::gzifstream() :
+ ios( gzfilestream_common::rdbuf() )
+{
+ clear( ios::badbit );
+}
+
+gzifstream::gzifstream( const char *name, int io_mode ) :
+ ios( gzfilestream_common::rdbuf() )
+{
+ gzfilestream_common::open( name, io_mode );
+}
+
+gzifstream::gzifstream( int fd, int io_mode ) :
+ ios( gzfilestream_common::rdbuf() )
+{
+ gzfilestream_common::attach( fd, io_mode );
+}
+
+gzifstream::~gzifstream() { }
+
+gzofstream::gzofstream() :
+ ios( gzfilestream_common::rdbuf() )
+{
+ clear( ios::badbit );
+}
+
+gzofstream::gzofstream( const char *name, int io_mode ) :
+ ios( gzfilestream_common::rdbuf() )
+{
+ gzfilestream_common::open( name, io_mode );
+}
+
+gzofstream::gzofstream( int fd, int io_mode ) :
+ ios( gzfilestream_common::rdbuf() )
+{
+ gzfilestream_common::attach( fd, io_mode );
+}
+
+gzofstream::~gzofstream() { }
diff --git a/xs/src/png/zlib/contrib/iostream/zfstream.h b/xs/src/png/zlib/contrib/iostream/zfstream.h
new file mode 100644
index 000000000..ed79098a3
--- /dev/null
+++ b/xs/src/png/zlib/contrib/iostream/zfstream.h
@@ -0,0 +1,128 @@
+
+#ifndef zfstream_h
+#define zfstream_h
+
+#include <fstream.h>
+#include "zlib.h"
+
+class gzfilebuf : public streambuf {
+
+public:
+
+ gzfilebuf( );
+ virtual ~gzfilebuf();
+
+ gzfilebuf *open( const char *name, int io_mode );
+ gzfilebuf *attach( int file_descriptor, int io_mode );
+ gzfilebuf *close();
+
+ int setcompressionlevel( int comp_level );
+ int setcompressionstrategy( int comp_strategy );
+
+ inline int is_open() const { return (file !=NULL); }
+
+ virtual streampos seekoff( streamoff, ios::seek_dir, int );
+
+ virtual int sync();
+
+protected:
+
+ virtual int underflow();
+ virtual int overflow( int = EOF );
+
+private:
+
+ gzFile file;
+ short mode;
+ short own_file_descriptor;
+
+ int flushbuf();
+ int fillbuf();
+
+};
+
+class gzfilestream_common : virtual public ios {
+
+ friend class gzifstream;
+ friend class gzofstream;
+ friend gzofstream &setcompressionlevel( gzofstream &, int );
+ friend gzofstream &setcompressionstrategy( gzofstream &, int );
+
+public:
+ virtual ~gzfilestream_common();
+
+ void attach( int fd, int io_mode );
+ void open( const char *name, int io_mode );
+ void close();
+
+protected:
+ gzfilestream_common();
+
+private:
+ gzfilebuf *rdbuf();
+
+ gzfilebuf buffer;
+
+};
+
+class gzifstream : public gzfilestream_common, public istream {
+
+public:
+
+ gzifstream();
+ gzifstream( const char *name, int io_mode = ios::in );
+ gzifstream( int fd, int io_mode = ios::in );
+
+ virtual ~gzifstream();
+
+};
+
+class gzofstream : public gzfilestream_common, public ostream {
+
+public:
+
+ gzofstream();
+ gzofstream( const char *name, int io_mode = ios::out );
+ gzofstream( int fd, int io_mode = ios::out );
+
+ virtual ~gzofstream();
+
+};
+
+template<class T> class gzomanip {
+ friend gzofstream &operator<<(gzofstream &, const gzomanip<T> &);
+public:
+ gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { }
+private:
+ gzofstream &(*func)(gzofstream &, T);
+ T val;
+};
+
+template<class T> gzofstream &operator<<(gzofstream &s, const gzomanip<T> &m)
+{
+ return (*m.func)(s, m.val);
+}
+
+inline gzofstream &setcompressionlevel( gzofstream &s, int l )
+{
+ (s.rdbuf())->setcompressionlevel(l);
+ return s;
+}
+
+inline gzofstream &setcompressionstrategy( gzofstream &s, int l )
+{
+ (s.rdbuf())->setcompressionstrategy(l);
+ return s;
+}
+
+inline gzomanip<int> setcompressionlevel(int l)
+{
+ return gzomanip<int>(&setcompressionlevel,l);
+}
+
+inline gzomanip<int> setcompressionstrategy(int l)
+{
+ return gzomanip<int>(&setcompressionstrategy,l);
+}
+
+#endif
diff --git a/xs/src/png/zlib/contrib/iostream2/zstream.h b/xs/src/png/zlib/contrib/iostream2/zstream.h
new file mode 100644
index 000000000..43d2332b7
--- /dev/null
+++ b/xs/src/png/zlib/contrib/iostream2/zstream.h
@@ -0,0 +1,307 @@
+/*
+ *
+ * Copyright (c) 1997
+ * Christian Michelsen Research AS
+ * Advanced Computing
+ * Fantoftvegen 38, 5036 BERGEN, Norway
+ * http://www.cmr.no
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Christian Michelsen Research AS makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef ZSTREAM__H
+#define ZSTREAM__H
+
+/*
+ * zstream.h - C++ interface to the 'zlib' general purpose compression library
+ * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $
+ */
+
+#include <strstream.h>
+#include <string.h>
+#include <stdio.h>
+#include "zlib.h"
+
+#if defined(_WIN32)
+# include <fcntl.h>
+# include <io.h>
+# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+# define SET_BINARY_MODE(file)
+#endif
+
+class zstringlen {
+public:
+ zstringlen(class izstream&);
+ zstringlen(class ozstream&, const char*);
+ size_t value() const { return val.word; }
+private:
+ struct Val { unsigned char byte; size_t word; } val;
+};
+
+// ----------------------------- izstream -----------------------------
+
+class izstream
+{
+ public:
+ izstream() : m_fp(0) {}
+ izstream(FILE* fp) : m_fp(0) { open(fp); }
+ izstream(const char* name) : m_fp(0) { open(name); }
+ ~izstream() { close(); }
+
+ /* Opens a gzip (.gz) file for reading.
+ * open() can be used to read a file which is not in gzip format;
+ * in this case read() will directly read from the file without
+ * decompression. errno can be checked to distinguish two error
+ * cases (if errno is zero, the zlib error is Z_MEM_ERROR).
+ */
+ void open(const char* name) {
+ if (m_fp) close();
+ m_fp = ::gzopen(name, "rb");
+ }
+
+ void open(FILE* fp) {
+ SET_BINARY_MODE(fp);
+ if (m_fp) close();
+ m_fp = ::gzdopen(fileno(fp), "rb");
+ }
+
+ /* Flushes all pending input if necessary, closes the compressed file
+ * and deallocates all the (de)compression state. The return value is
+ * the zlib error number (see function error() below).
+ */
+ int close() {
+ int r = ::gzclose(m_fp);
+ m_fp = 0; return r;
+ }
+
+ /* Binary read the given number of bytes from the compressed file.
+ */
+ int read(void* buf, size_t len) {
+ return ::gzread(m_fp, buf, len);
+ }
+
+ /* Returns the error message for the last error which occurred on the
+ * given compressed file. errnum is set to zlib error number. If an
+ * error occurred in the file system and not in the compression library,
+ * errnum is set to Z_ERRNO and the application may consult errno
+ * to get the exact error code.
+ */
+ const char* error(int* errnum) {
+ return ::gzerror(m_fp, errnum);
+ }
+
+ gzFile fp() { return m_fp; }
+
+ private:
+ gzFile m_fp;
+};
+
+/*
+ * Binary read the given (array of) object(s) from the compressed file.
+ * If the input file was not in gzip format, read() copies the objects number
+ * of bytes into the buffer.
+ * returns the number of uncompressed bytes actually read
+ * (0 for end of file, -1 for error).
+ */
+template <class T, class Items>
+inline int read(izstream& zs, T* x, Items items) {
+ return ::gzread(zs.fp(), x, items*sizeof(T));
+}
+
+/*
+ * Binary input with the '>' operator.
+ */
+template <class T>
+inline izstream& operator>(izstream& zs, T& x) {
+ ::gzread(zs.fp(), &x, sizeof(T));
+ return zs;
+}
+
+
+inline zstringlen::zstringlen(izstream& zs) {
+ zs > val.byte;
+ if (val.byte == 255) zs > val.word;
+ else val.word = val.byte;
+}
+
+/*
+ * Read length of string + the string with the '>' operator.
+ */
+inline izstream& operator>(izstream& zs, char* x) {
+ zstringlen len(zs);
+ ::gzread(zs.fp(), x, len.value());
+ x[len.value()] = '\0';
+ return zs;
+}
+
+inline char* read_string(izstream& zs) {
+ zstringlen len(zs);
+ char* x = new char[len.value()+1];
+ ::gzread(zs.fp(), x, len.value());
+ x[len.value()] = '\0';
+ return x;
+}
+
+// ----------------------------- ozstream -----------------------------
+
+class ozstream
+{
+ public:
+ ozstream() : m_fp(0), m_os(0) {
+ }
+ ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION)
+ : m_fp(0), m_os(0) {
+ open(fp, level);
+ }
+ ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION)
+ : m_fp(0), m_os(0) {
+ open(name, level);
+ }
+ ~ozstream() {
+ close();
+ }
+
+ /* Opens a gzip (.gz) file for writing.
+ * The compression level parameter should be in 0..9
+ * errno can be checked to distinguish two error cases
+ * (if errno is zero, the zlib error is Z_MEM_ERROR).
+ */
+ void open(const char* name, int level = Z_DEFAULT_COMPRESSION) {
+ char mode[4] = "wb\0";
+ if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
+ if (m_fp) close();
+ m_fp = ::gzopen(name, mode);
+ }
+
+ /* open from a FILE pointer.
+ */
+ void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) {
+ SET_BINARY_MODE(fp);
+ char mode[4] = "wb\0";
+ if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
+ if (m_fp) close();
+ m_fp = ::gzdopen(fileno(fp), mode);
+ }
+
+ /* Flushes all pending output if necessary, closes the compressed file
+ * and deallocates all the (de)compression state. The return value is
+ * the zlib error number (see function error() below).
+ */
+ int close() {
+ if (m_os) {
+ ::gzwrite(m_fp, m_os->str(), m_os->pcount());
+ delete[] m_os->str(); delete m_os; m_os = 0;
+ }
+ int r = ::gzclose(m_fp); m_fp = 0; return r;
+ }
+
+ /* Binary write the given number of bytes into the compressed file.
+ */
+ int write(const void* buf, size_t len) {
+ return ::gzwrite(m_fp, (voidp) buf, len);
+ }
+
+ /* Flushes all pending output into the compressed file. The parameter
+ * _flush is as in the deflate() function. The return value is the zlib
+ * error number (see function gzerror below). flush() returns Z_OK if
+ * the flush_ parameter is Z_FINISH and all output could be flushed.
+ * flush() should be called only when strictly necessary because it can
+ * degrade compression.
+ */
+ int flush(int _flush) {
+ os_flush();
+ return ::gzflush(m_fp, _flush);
+ }
+
+ /* Returns the error message for the last error which occurred on the
+ * given compressed file. errnum is set to zlib error number. If an
+ * error occurred in the file system and not in the compression library,
+ * errnum is set to Z_ERRNO and the application may consult errno
+ * to get the exact error code.
+ */
+ const char* error(int* errnum) {
+ return ::gzerror(m_fp, errnum);
+ }
+
+ gzFile fp() { return m_fp; }
+
+ ostream& os() {
+ if (m_os == 0) m_os = new ostrstream;
+ return *m_os;
+ }
+
+ void os_flush() {
+ if (m_os && m_os->pcount()>0) {
+ ostrstream* oss = new ostrstream;
+ oss->fill(m_os->fill());
+ oss->flags(m_os->flags());
+ oss->precision(m_os->precision());
+ oss->width(m_os->width());
+ ::gzwrite(m_fp, m_os->str(), m_os->pcount());
+ delete[] m_os->str(); delete m_os; m_os = oss;
+ }
+ }
+
+ private:
+ gzFile m_fp;
+ ostrstream* m_os;
+};
+
+/*
+ * Binary write the given (array of) object(s) into the compressed file.
+ * returns the number of uncompressed bytes actually written
+ * (0 in case of error).
+ */
+template <class T, class Items>
+inline int write(ozstream& zs, const T* x, Items items) {
+ return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T));
+}
+
+/*
+ * Binary output with the '<' operator.
+ */
+template <class T>
+inline ozstream& operator<(ozstream& zs, const T& x) {
+ ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));
+ return zs;
+}
+
+inline zstringlen::zstringlen(ozstream& zs, const char* x) {
+ val.byte = 255; val.word = ::strlen(x);
+ if (val.word < 255) zs < (val.byte = val.word);
+ else zs < val;
+}
+
+/*
+ * Write length of string + the string with the '<' operator.
+ */
+inline ozstream& operator<(ozstream& zs, const char* x) {
+ zstringlen len(zs, x);
+ ::gzwrite(zs.fp(), (voidp) x, len.value());
+ return zs;
+}
+
+#ifdef _MSC_VER
+inline ozstream& operator<(ozstream& zs, char* const& x) {
+ return zs < (const char*) x;
+}
+#endif
+
+/*
+ * Ascii write with the << operator;
+ */
+template <class T>
+inline ostream& operator<<(ozstream& zs, const T& x) {
+ zs.os_flush();
+ return zs.os() << x;
+}
+
+#endif
diff --git a/xs/src/png/zlib/contrib/iostream2/zstream_test.cpp b/xs/src/png/zlib/contrib/iostream2/zstream_test.cpp
new file mode 100644
index 000000000..6273f62d6
--- /dev/null
+++ b/xs/src/png/zlib/contrib/iostream2/zstream_test.cpp
@@ -0,0 +1,25 @@
+#include "zstream.h"
+#include <math.h>
+#include <stdlib.h>
+#include <iomanip.h>
+
+void main() {
+ char h[256] = "Hello";
+ char* g = "Goodbye";
+ ozstream out("temp.gz");
+ out < "This works well" < h < g;
+ out.close();
+
+ izstream in("temp.gz"); // read it back
+ char *x = read_string(in), *y = new char[256], z[256];
+ in > y > z;
+ in.close();
+ cout << x << endl << y << endl << z << endl;
+
+ out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results
+ out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl;
+ out << z << endl << y << endl << x << endl;
+ out << 1.1234567890123456789 << endl;
+
+ delete[] x; delete[] y;
+}
diff --git a/xs/src/png/zlib/contrib/iostream3/README b/xs/src/png/zlib/contrib/iostream3/README
new file mode 100644
index 000000000..f7b319ab9
--- /dev/null
+++ b/xs/src/png/zlib/contrib/iostream3/README
@@ -0,0 +1,35 @@
+These classes provide a C++ stream interface to the zlib library. It allows you
+to do things like:
+
+ gzofstream outf("blah.gz");
+ outf << "These go into the gzip file " << 123 << endl;
+
+It does this by deriving a specialized stream buffer for gzipped files, which is
+the way Stroustrup would have done it. :->
+
+The gzifstream and gzofstream classes were originally written by Kevin Ruland
+and made available in the zlib contrib/iostream directory. The older version still
+compiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of
+this version.
+
+The new classes are as standard-compliant as possible, closely following the
+approach of the standard library's fstream classes. It compiles under gcc versions
+3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard
+library naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs
+from the previous one in the following respects:
+- added showmanyc
+- added setbuf, with support for unbuffered output via setbuf(0,0)
+- a few bug fixes of stream behavior
+- gzipped output file opened with default compression level instead of maximum level
+- setcompressionlevel()/strategy() members replaced by single setcompression()
+
+The code is provided "as is", with the permission to use, copy, modify, distribute
+and sell it for any purpose without fee.
+
+Ludwig Schwardt
+<schwardt@sun.ac.za>
+
+DSP Lab
+Electrical & Electronic Engineering Department
+University of Stellenbosch
+South Africa
diff --git a/xs/src/png/zlib/contrib/iostream3/TODO b/xs/src/png/zlib/contrib/iostream3/TODO
new file mode 100644
index 000000000..7032f97be
--- /dev/null
+++ b/xs/src/png/zlib/contrib/iostream3/TODO
@@ -0,0 +1,17 @@
+Possible upgrades to gzfilebuf:
+
+- The ability to do putback (e.g. putbackfail)
+
+- The ability to seek (zlib supports this, but could be slow/tricky)
+
+- Simultaneous read/write access (does it make sense?)
+
+- Support for ios_base::ate open mode
+
+- Locale support?
+
+- Check public interface to see which calls give problems
+ (due to dependence on library internals)
+
+- Override operator<<(ostream&, gzfilebuf*) to allow direct copying
+ of stream buffer to stream ( i.e. os << is.rdbuf(); )
diff --git a/xs/src/png/zlib/contrib/iostream3/test.cc b/xs/src/png/zlib/contrib/iostream3/test.cc
new file mode 100644
index 000000000..94235334f
--- /dev/null
+++ b/xs/src/png/zlib/contrib/iostream3/test.cc
@@ -0,0 +1,50 @@
+/*
+ * Test program for gzifstream and gzofstream
+ *
+ * by Ludwig Schwardt <schwardt@sun.ac.za>
+ * original version by Kevin Ruland <kevin@rodin.wustl.edu>
+ */
+
+#include "zfstream.h"
+#include <iostream> // for cout
+
+int main() {
+
+ gzofstream outf;
+ gzifstream inf;
+ char buf[80];
+
+ outf.open("test1.txt.gz");
+ outf << "The quick brown fox sidestepped the lazy canine\n"
+ << 1.3 << "\nPlan " << 9 << std::endl;
+ outf.close();
+ std::cout << "Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\n"
+ << "The quick brown fox sidestepped the lazy canine\n"
+ << 1.3 << "\nPlan " << 9 << std::endl;
+
+ std::cout << "\nReading 'test1.txt.gz' (buffered) produces:\n";
+ inf.open("test1.txt.gz");
+ while (inf.getline(buf,80,'\n')) {
+ std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
+ }
+ inf.close();
+
+ outf.rdbuf()->pubsetbuf(0,0);
+ outf.open("test2.txt.gz");
+ outf << setcompression(Z_NO_COMPRESSION)
+ << "The quick brown fox sidestepped the lazy canine\n"
+ << 1.3 << "\nPlan " << 9 << std::endl;
+ outf.close();
+ std::cout << "\nWrote the same message to 'test2.txt.gz' in uncompressed form";
+
+ std::cout << "\nReading 'test2.txt.gz' (unbuffered) produces:\n";
+ inf.rdbuf()->pubsetbuf(0,0);
+ inf.open("test2.txt.gz");
+ while (inf.getline(buf,80,'\n')) {
+ std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
+ }
+ inf.close();
+
+ return 0;
+
+}
diff --git a/xs/src/png/zlib/contrib/iostream3/zfstream.cc b/xs/src/png/zlib/contrib/iostream3/zfstream.cc
new file mode 100644
index 000000000..94eb93344
--- /dev/null
+++ b/xs/src/png/zlib/contrib/iostream3/zfstream.cc
@@ -0,0 +1,479 @@
+/*
+ * A C++ I/O streams interface to the zlib gz* functions
+ *
+ * by Ludwig Schwardt <schwardt@sun.ac.za>
+ * original version by Kevin Ruland <kevin@rodin.wustl.edu>
+ *
+ * This version is standard-compliant and compatible with gcc 3.x.
+ */
+
+#include "zfstream.h"
+#include <cstring> // for strcpy, strcat, strlen (mode strings)
+#include <cstdio> // for BUFSIZ
+
+// Internal buffer sizes (default and "unbuffered" versions)
+#define BIGBUFSIZE BUFSIZ
+#define SMALLBUFSIZE 1
+
+/*****************************************************************************/
+
+// Default constructor
+gzfilebuf::gzfilebuf()
+: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false),
+ buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true)
+{
+ // No buffers to start with
+ this->disable_buffer();
+}
+
+// Destructor
+gzfilebuf::~gzfilebuf()
+{
+ // Sync output buffer and close only if responsible for file
+ // (i.e. attached streams should be left open at this stage)
+ this->sync();
+ if (own_fd)
+ this->close();
+ // Make sure internal buffer is deallocated
+ this->disable_buffer();
+}
+
+// Set compression level and strategy
+int
+gzfilebuf::setcompression(int comp_level,
+ int comp_strategy)
+{
+ return gzsetparams(file, comp_level, comp_strategy);
+}
+
+// Open gzipped file
+gzfilebuf*
+gzfilebuf::open(const char *name,
+ std::ios_base::openmode mode)
+{
+ // Fail if file already open
+ if (this->is_open())
+ return NULL;
+ // Don't support simultaneous read/write access (yet)
+ if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
+ return NULL;
+
+ // Build mode string for gzopen and check it [27.8.1.3.2]
+ char char_mode[6] = "\0\0\0\0\0";
+ if (!this->open_mode(mode, char_mode))
+ return NULL;
+
+ // Attempt to open file
+ if ((file = gzopen(name, char_mode)) == NULL)
+ return NULL;
+
+ // On success, allocate internal buffer and set flags
+ this->enable_buffer();
+ io_mode = mode;
+ own_fd = true;
+ return this;
+}
+
+// Attach to gzipped file
+gzfilebuf*
+gzfilebuf::attach(int fd,
+ std::ios_base::openmode mode)
+{
+ // Fail if file already open
+ if (this->is_open())
+ return NULL;
+ // Don't support simultaneous read/write access (yet)
+ if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
+ return NULL;
+
+ // Build mode string for gzdopen and check it [27.8.1.3.2]
+ char char_mode[6] = "\0\0\0\0\0";
+ if (!this->open_mode(mode, char_mode))
+ return NULL;
+
+ // Attempt to attach to file
+ if ((file = gzdopen(fd, char_mode)) == NULL)
+ return NULL;
+
+ // On success, allocate internal buffer and set flags
+ this->enable_buffer();
+ io_mode = mode;
+ own_fd = false;
+ return this;
+}
+
+// Close gzipped file
+gzfilebuf*
+gzfilebuf::close()
+{
+ // Fail immediately if no file is open
+ if (!this->is_open())
+ return NULL;
+ // Assume success
+ gzfilebuf* retval = this;
+ // Attempt to sync and close gzipped file
+ if (this->sync() == -1)
+ retval = NULL;
+ if (gzclose(file) < 0)
+ retval = NULL;
+ // File is now gone anyway (postcondition [27.8.1.3.8])
+ file = NULL;
+ own_fd = false;
+ // Destroy internal buffer if it exists
+ this->disable_buffer();
+ return retval;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// Convert int open mode to mode string
+bool
+gzfilebuf::open_mode(std::ios_base::openmode mode,
+ char* c_mode) const
+{
+ bool testb = mode & std::ios_base::binary;
+ bool testi = mode & std::ios_base::in;
+ bool testo = mode & std::ios_base::out;
+ bool testt = mode & std::ios_base::trunc;
+ bool testa = mode & std::ios_base::app;
+
+ // Check for valid flag combinations - see [27.8.1.3.2] (Table 92)
+ // Original zfstream hardcoded the compression level to maximum here...
+ // Double the time for less than 1% size improvement seems
+ // excessive though - keeping it at the default level
+ // To change back, just append "9" to the next three mode strings
+ if (!testi && testo && !testt && !testa)
+ strcpy(c_mode, "w");
+ if (!testi && testo && !testt && testa)
+ strcpy(c_mode, "a");
+ if (!testi && testo && testt && !testa)
+ strcpy(c_mode, "w");
+ if (testi && !testo && !testt && !testa)
+ strcpy(c_mode, "r");
+ // No read/write mode yet
+// if (testi && testo && !testt && !testa)
+// strcpy(c_mode, "r+");
+// if (testi && testo && testt && !testa)
+// strcpy(c_mode, "w+");
+
+ // Mode string should be empty for invalid combination of flags
+ if (strlen(c_mode) == 0)
+ return false;
+ if (testb)
+ strcat(c_mode, "b");
+ return true;
+}
+
+// Determine number of characters in internal get buffer
+std::streamsize
+gzfilebuf::showmanyc()
+{
+ // Calls to underflow will fail if file not opened for reading
+ if (!this->is_open() || !(io_mode & std::ios_base::in))
+ return -1;
+ // Make sure get area is in use
+ if (this->gptr() && (this->gptr() < this->egptr()))
+ return std::streamsize(this->egptr() - this->gptr());
+ else
+ return 0;
+}
+
+// Fill get area from gzipped file
+gzfilebuf::int_type
+gzfilebuf::underflow()
+{
+ // If something is left in the get area by chance, return it
+ // (this shouldn't normally happen, as underflow is only supposed
+ // to be called when gptr >= egptr, but it serves as error check)
+ if (this->gptr() && (this->gptr() < this->egptr()))
+ return traits_type::to_int_type(*(this->gptr()));
+
+ // If the file hasn't been opened for reading, produce error
+ if (!this->is_open() || !(io_mode & std::ios_base::in))
+ return traits_type::eof();
+
+ // Attempt to fill internal buffer from gzipped file
+ // (buffer must be guaranteed to exist...)
+ int bytes_read = gzread(file, buffer, buffer_size);
+ // Indicates error or EOF
+ if (bytes_read <= 0)
+ {
+ // Reset get area
+ this->setg(buffer, buffer, buffer);
+ return traits_type::eof();
+ }
+ // Make all bytes read from file available as get area
+ this->setg(buffer, buffer, buffer + bytes_read);
+
+ // Return next character in get area
+ return traits_type::to_int_type(*(this->gptr()));
+}
+
+// Write put area to gzipped file
+gzfilebuf::int_type
+gzfilebuf::overflow(int_type c)
+{
+ // Determine whether put area is in use
+ if (this->pbase())
+ {
+ // Double-check pointer range
+ if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
+ return traits_type::eof();
+ // Add extra character to buffer if not EOF
+ if (!traits_type::eq_int_type(c, traits_type::eof()))
+ {
+ *(this->pptr()) = traits_type::to_char_type(c);
+ this->pbump(1);
+ }
+ // Number of characters to write to file
+ int bytes_to_write = this->pptr() - this->pbase();
+ // Overflow doesn't fail if nothing is to be written
+ if (bytes_to_write > 0)
+ {
+ // If the file hasn't been opened for writing, produce error
+ if (!this->is_open() || !(io_mode & std::ios_base::out))
+ return traits_type::eof();
+ // If gzipped file won't accept all bytes written to it, fail
+ if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write)
+ return traits_type::eof();
+ // Reset next pointer to point to pbase on success
+ this->pbump(-bytes_to_write);
+ }
+ }
+ // Write extra character to file if not EOF
+ else if (!traits_type::eq_int_type(c, traits_type::eof()))
+ {
+ // If the file hasn't been opened for writing, produce error
+ if (!this->is_open() || !(io_mode & std::ios_base::out))
+ return traits_type::eof();
+ // Impromptu char buffer (allows "unbuffered" output)
+ char_type last_char = traits_type::to_char_type(c);
+ // If gzipped file won't accept this character, fail
+ if (gzwrite(file, &last_char, 1) != 1)
+ return traits_type::eof();
+ }
+
+ // If you got here, you have succeeded (even if c was EOF)
+ // The return value should therefore be non-EOF
+ if (traits_type::eq_int_type(c, traits_type::eof()))
+ return traits_type::not_eof(c);
+ else
+ return c;
+}
+
+// Assign new buffer
+std::streambuf*
+gzfilebuf::setbuf(char_type* p,
+ std::streamsize n)
+{
+ // First make sure stuff is sync'ed, for safety
+ if (this->sync() == -1)
+ return NULL;
+ // If buffering is turned off on purpose via setbuf(0,0), still allocate one...
+ // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at
+ // least a buffer of size 1 (very inefficient though, therefore make it bigger?)
+ // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)
+ if (!p || !n)
+ {
+ // Replace existing buffer (if any) with small internal buffer
+ this->disable_buffer();
+ buffer = NULL;
+ buffer_size = 0;
+ own_buffer = true;
+ this->enable_buffer();
+ }
+ else
+ {
+ // Replace existing buffer (if any) with external buffer
+ this->disable_buffer();
+ buffer = p;
+ buffer_size = n;
+ own_buffer = false;
+ this->enable_buffer();
+ }
+ return this;
+}
+
+// Write put area to gzipped file (i.e. ensures that put area is empty)
+int
+gzfilebuf::sync()
+{
+ return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// Allocate internal buffer
+void
+gzfilebuf::enable_buffer()
+{
+ // If internal buffer required, allocate one
+ if (own_buffer && !buffer)
+ {
+ // Check for buffered vs. "unbuffered"
+ if (buffer_size > 0)
+ {
+ // Allocate internal buffer
+ buffer = new char_type[buffer_size];
+ // Get area starts empty and will be expanded by underflow as need arises
+ this->setg(buffer, buffer, buffer);
+ // Setup entire internal buffer as put area.
+ // The one-past-end pointer actually points to the last element of the buffer,
+ // so that overflow(c) can safely add the extra character c to the sequence.
+ // These pointers remain in place for the duration of the buffer
+ this->setp(buffer, buffer + buffer_size - 1);
+ }
+ else
+ {
+ // Even in "unbuffered" case, (small?) get buffer is still required
+ buffer_size = SMALLBUFSIZE;
+ buffer = new char_type[buffer_size];
+ this->setg(buffer, buffer, buffer);
+ // "Unbuffered" means no put buffer
+ this->setp(0, 0);
+ }
+ }
+ else
+ {
+ // If buffer already allocated, reset buffer pointers just to make sure no
+ // stale chars are lying around
+ this->setg(buffer, buffer, buffer);
+ this->setp(buffer, buffer + buffer_size - 1);
+ }
+}
+
+// Destroy internal buffer
+void
+gzfilebuf::disable_buffer()
+{
+ // If internal buffer exists, deallocate it
+ if (own_buffer && buffer)
+ {
+ // Preserve unbuffered status by zeroing size
+ if (!this->pbase())
+ buffer_size = 0;
+ delete[] buffer;
+ buffer = NULL;
+ this->setg(0, 0, 0);
+ this->setp(0, 0);
+ }
+ else
+ {
+ // Reset buffer pointers to initial state if external buffer exists
+ this->setg(buffer, buffer, buffer);
+ if (buffer)
+ this->setp(buffer, buffer + buffer_size - 1);
+ else
+ this->setp(0, 0);
+ }
+}
+
+/*****************************************************************************/
+
+// Default constructor initializes stream buffer
+gzifstream::gzifstream()
+: std::istream(NULL), sb()
+{ this->init(&sb); }
+
+// Initialize stream buffer and open file
+gzifstream::gzifstream(const char* name,
+ std::ios_base::openmode mode)
+: std::istream(NULL), sb()
+{
+ this->init(&sb);
+ this->open(name, mode);
+}
+
+// Initialize stream buffer and attach to file
+gzifstream::gzifstream(int fd,
+ std::ios_base::openmode mode)
+: std::istream(NULL), sb()
+{
+ this->init(&sb);
+ this->attach(fd, mode);
+}
+
+// Open file and go into fail() state if unsuccessful
+void
+gzifstream::open(const char* name,
+ std::ios_base::openmode mode)
+{
+ if (!sb.open(name, mode | std::ios_base::in))
+ this->setstate(std::ios_base::failbit);
+ else
+ this->clear();
+}
+
+// Attach to file and go into fail() state if unsuccessful
+void
+gzifstream::attach(int fd,
+ std::ios_base::openmode mode)
+{
+ if (!sb.attach(fd, mode | std::ios_base::in))
+ this->setstate(std::ios_base::failbit);
+ else
+ this->clear();
+}
+
+// Close file
+void
+gzifstream::close()
+{
+ if (!sb.close())
+ this->setstate(std::ios_base::failbit);
+}
+
+/*****************************************************************************/
+
+// Default constructor initializes stream buffer
+gzofstream::gzofstream()
+: std::ostream(NULL), sb()
+{ this->init(&sb); }
+
+// Initialize stream buffer and open file
+gzofstream::gzofstream(const char* name,
+ std::ios_base::openmode mode)
+: std::ostream(NULL), sb()
+{
+ this->init(&sb);
+ this->open(name, mode);
+}
+
+// Initialize stream buffer and attach to file
+gzofstream::gzofstream(int fd,
+ std::ios_base::openmode mode)
+: std::ostream(NULL), sb()
+{
+ this->init(&sb);
+ this->attach(fd, mode);
+}
+
+// Open file and go into fail() state if unsuccessful
+void
+gzofstream::open(const char* name,
+ std::ios_base::openmode mode)
+{
+ if (!sb.open(name, mode | std::ios_base::out))
+ this->setstate(std::ios_base::failbit);
+ else
+ this->clear();
+}
+
+// Attach to file and go into fail() state if unsuccessful
+void
+gzofstream::attach(int fd,
+ std::ios_base::openmode mode)
+{
+ if (!sb.attach(fd, mode | std::ios_base::out))
+ this->setstate(std::ios_base::failbit);
+ else
+ this->clear();
+}
+
+// Close file
+void
+gzofstream::close()
+{
+ if (!sb.close())
+ this->setstate(std::ios_base::failbit);
+}
diff --git a/xs/src/png/zlib/contrib/iostream3/zfstream.h b/xs/src/png/zlib/contrib/iostream3/zfstream.h
new file mode 100644
index 000000000..8574479ae
--- /dev/null
+++ b/xs/src/png/zlib/contrib/iostream3/zfstream.h
@@ -0,0 +1,466 @@
+/*
+ * A C++ I/O streams interface to the zlib gz* functions
+ *
+ * by Ludwig Schwardt <schwardt@sun.ac.za>
+ * original version by Kevin Ruland <kevin@rodin.wustl.edu>
+ *
+ * This version is standard-compliant and compatible with gcc 3.x.
+ */
+
+#ifndef ZFSTREAM_H
+#define ZFSTREAM_H
+
+#include <istream> // not iostream, since we don't need cin/cout
+#include <ostream>
+#include "zlib.h"
+
+/*****************************************************************************/
+
+/**
+ * @brief Gzipped file stream buffer class.
+ *
+ * This class implements basic_filebuf for gzipped files. It doesn't yet support
+ * seeking (allowed by zlib but slow/limited), putback and read/write access
+ * (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
+ * file streambuf.
+*/
+class gzfilebuf : public std::streambuf
+{
+public:
+ // Default constructor.
+ gzfilebuf();
+
+ // Destructor.
+ virtual
+ ~gzfilebuf();
+
+ /**
+ * @brief Set compression level and strategy on the fly.
+ * @param comp_level Compression level (see zlib.h for allowed values)
+ * @param comp_strategy Compression strategy (see zlib.h for allowed values)
+ * @return Z_OK on success, Z_STREAM_ERROR otherwise.
+ *
+ * Unfortunately, these parameters cannot be modified separately, as the
+ * previous zfstream version assumed. Since the strategy is seldom changed,
+ * it can default and setcompression(level) then becomes like the old
+ * setcompressionlevel(level).
+ */
+ int
+ setcompression(int comp_level,
+ int comp_strategy = Z_DEFAULT_STRATEGY);
+
+ /**
+ * @brief Check if file is open.
+ * @return True if file is open.
+ */
+ bool
+ is_open() const { return (file != NULL); }
+
+ /**
+ * @brief Open gzipped file.
+ * @param name File name.
+ * @param mode Open mode flags.
+ * @return @c this on success, NULL on failure.
+ */
+ gzfilebuf*
+ open(const char* name,
+ std::ios_base::openmode mode);
+
+ /**
+ * @brief Attach to already open gzipped file.
+ * @param fd File descriptor.
+ * @param mode Open mode flags.
+ * @return @c this on success, NULL on failure.
+ */
+ gzfilebuf*
+ attach(int fd,
+ std::ios_base::openmode mode);
+
+ /**
+ * @brief Close gzipped file.
+ * @return @c this on success, NULL on failure.
+ */
+ gzfilebuf*
+ close();
+
+protected:
+ /**
+ * @brief Convert ios open mode int to mode string used by zlib.
+ * @return True if valid mode flag combination.
+ */
+ bool
+ open_mode(std::ios_base::openmode mode,
+ char* c_mode) const;
+
+ /**
+ * @brief Number of characters available in stream buffer.
+ * @return Number of characters.
+ *
+ * This indicates number of characters in get area of stream buffer.
+ * These characters can be read without accessing the gzipped file.
+ */
+ virtual std::streamsize
+ showmanyc();
+
+ /**
+ * @brief Fill get area from gzipped file.
+ * @return First character in get area on success, EOF on error.
+ *
+ * This actually reads characters from gzipped file to stream
+ * buffer. Always buffered.
+ */
+ virtual int_type
+ underflow();
+
+ /**
+ * @brief Write put area to gzipped file.
+ * @param c Extra character to add to buffer contents.
+ * @return Non-EOF on success, EOF on error.
+ *
+ * This actually writes characters in stream buffer to
+ * gzipped file. With unbuffered output this is done one
+ * character at a time.
+ */
+ virtual int_type
+ overflow(int_type c = traits_type::eof());
+
+ /**
+ * @brief Installs external stream buffer.
+ * @param p Pointer to char buffer.
+ * @param n Size of external buffer.
+ * @return @c this on success, NULL on failure.
+ *
+ * Call setbuf(0,0) to enable unbuffered output.
+ */
+ virtual std::streambuf*
+ setbuf(char_type* p,
+ std::streamsize n);
+
+ /**
+ * @brief Flush stream buffer to file.
+ * @return 0 on success, -1 on error.
+ *
+ * This calls underflow(EOF) to do the job.
+ */
+ virtual int
+ sync();
+
+//
+// Some future enhancements
+//
+// virtual int_type uflow();
+// virtual int_type pbackfail(int_type c = traits_type::eof());
+// virtual pos_type
+// seekoff(off_type off,
+// std::ios_base::seekdir way,
+// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
+// virtual pos_type
+// seekpos(pos_type sp,
+// std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
+
+private:
+ /**
+ * @brief Allocate internal buffer.
+ *
+ * This function is safe to call multiple times. It will ensure
+ * that a proper internal buffer exists if it is required. If the
+ * buffer already exists or is external, the buffer pointers will be
+ * reset to their original state.
+ */
+ void
+ enable_buffer();
+
+ /**
+ * @brief Destroy internal buffer.
+ *
+ * This function is safe to call multiple times. It will ensure
+ * that the internal buffer is deallocated if it exists. In any
+ * case, it will also reset the buffer pointers.
+ */
+ void
+ disable_buffer();
+
+ /**
+ * Underlying file pointer.
+ */
+ gzFile file;
+
+ /**
+ * Mode in which file was opened.
+ */
+ std::ios_base::openmode io_mode;
+
+ /**
+ * @brief True if this object owns file descriptor.
+ *
+ * This makes the class responsible for closing the file
+ * upon destruction.
+ */
+ bool own_fd;
+
+ /**
+ * @brief Stream buffer.
+ *
+ * For simplicity this remains allocated on the free store for the
+ * entire life span of the gzfilebuf object, unless replaced by setbuf.
+ */
+ char_type* buffer;
+
+ /**
+ * @brief Stream buffer size.
+ *
+ * Defaults to system default buffer size (typically 8192 bytes).
+ * Modified by setbuf.
+ */
+ std::streamsize buffer_size;
+
+ /**
+ * @brief True if this object owns stream buffer.
+ *
+ * This makes the class responsible for deleting the buffer
+ * upon destruction.
+ */
+ bool own_buffer;
+};
+
+/*****************************************************************************/
+
+/**
+ * @brief Gzipped file input stream class.
+ *
+ * This class implements ifstream for gzipped files. Seeking and putback
+ * is not supported yet.
+*/
+class gzifstream : public std::istream
+{
+public:
+ // Default constructor
+ gzifstream();
+
+ /**
+ * @brief Construct stream on gzipped file to be opened.
+ * @param name File name.
+ * @param mode Open mode flags (forced to contain ios::in).
+ */
+ explicit
+ gzifstream(const char* name,
+ std::ios_base::openmode mode = std::ios_base::in);
+
+ /**
+ * @brief Construct stream on already open gzipped file.
+ * @param fd File descriptor.
+ * @param mode Open mode flags (forced to contain ios::in).
+ */
+ explicit
+ gzifstream(int fd,
+ std::ios_base::openmode mode = std::ios_base::in);
+
+ /**
+ * Obtain underlying stream buffer.
+ */
+ gzfilebuf*
+ rdbuf() const
+ { return const_cast<gzfilebuf*>(&sb); }
+
+ /**
+ * @brief Check if file is open.
+ * @return True if file is open.
+ */
+ bool
+ is_open() { return sb.is_open(); }
+
+ /**
+ * @brief Open gzipped file.
+ * @param name File name.
+ * @param mode Open mode flags (forced to contain ios::in).
+ *
+ * Stream will be in state good() if file opens successfully;
+ * otherwise in state fail(). This differs from the behavior of
+ * ifstream, which never sets the state to good() and therefore
+ * won't allow you to reuse the stream for a second file unless
+ * you manually clear() the state. The choice is a matter of
+ * convenience.
+ */
+ void
+ open(const char* name,
+ std::ios_base::openmode mode = std::ios_base::in);
+
+ /**
+ * @brief Attach to already open gzipped file.
+ * @param fd File descriptor.
+ * @param mode Open mode flags (forced to contain ios::in).
+ *
+ * Stream will be in state good() if attach succeeded; otherwise
+ * in state fail().
+ */
+ void
+ attach(int fd,
+ std::ios_base::openmode mode = std::ios_base::in);
+
+ /**
+ * @brief Close gzipped file.
+ *
+ * Stream will be in state fail() if close failed.
+ */
+ void
+ close();
+
+private:
+ /**
+ * Underlying stream buffer.
+ */
+ gzfilebuf sb;
+};
+
+/*****************************************************************************/
+
+/**
+ * @brief Gzipped file output stream class.
+ *
+ * This class implements ofstream for gzipped files. Seeking and putback
+ * is not supported yet.
+*/
+class gzofstream : public std::ostream
+{
+public:
+ // Default constructor
+ gzofstream();
+
+ /**
+ * @brief Construct stream on gzipped file to be opened.
+ * @param name File name.
+ * @param mode Open mode flags (forced to contain ios::out).
+ */
+ explicit
+ gzofstream(const char* name,
+ std::ios_base::openmode mode = std::ios_base::out);
+
+ /**
+ * @brief Construct stream on already open gzipped file.
+ * @param fd File descriptor.
+ * @param mode Open mode flags (forced to contain ios::out).
+ */
+ explicit
+ gzofstream(int fd,
+ std::ios_base::openmode mode = std::ios_base::out);
+
+ /**
+ * Obtain underlying stream buffer.
+ */
+ gzfilebuf*
+ rdbuf() const
+ { return const_cast<gzfilebuf*>(&sb); }
+
+ /**
+ * @brief Check if file is open.
+ * @return True if file is open.
+ */
+ bool
+ is_open() { return sb.is_open(); }
+
+ /**
+ * @brief Open gzipped file.
+ * @param name File name.
+ * @param mode Open mode flags (forced to contain ios::out).
+ *
+ * Stream will be in state good() if file opens successfully;
+ * otherwise in state fail(). This differs from the behavior of
+ * ofstream, which never sets the state to good() and therefore
+ * won't allow you to reuse the stream for a second file unless
+ * you manually clear() the state. The choice is a matter of
+ * convenience.
+ */
+ void
+ open(const char* name,
+ std::ios_base::openmode mode = std::ios_base::out);
+
+ /**
+ * @brief Attach to already open gzipped file.
+ * @param fd File descriptor.
+ * @param mode Open mode flags (forced to contain ios::out).
+ *
+ * Stream will be in state good() if attach succeeded; otherwise
+ * in state fail().
+ */
+ void
+ attach(int fd,
+ std::ios_base::openmode mode = std::ios_base::out);
+
+ /**
+ * @brief Close gzipped file.
+ *
+ * Stream will be in state fail() if close failed.
+ */
+ void
+ close();
+
+private:
+ /**
+ * Underlying stream buffer.
+ */
+ gzfilebuf sb;
+};
+
+/*****************************************************************************/
+
+/**
+ * @brief Gzipped file output stream manipulator class.
+ *
+ * This class defines a two-argument manipulator for gzofstream. It is used
+ * as base for the setcompression(int,int) manipulator.
+*/
+template<typename T1, typename T2>
+ class gzomanip2
+ {
+ public:
+ // Allows insertor to peek at internals
+ template <typename Ta, typename Tb>
+ friend gzofstream&
+ operator<<(gzofstream&,
+ const gzomanip2<Ta,Tb>&);
+
+ // Constructor
+ gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
+ T1 v1,
+ T2 v2);
+ private:
+ // Underlying manipulator function
+ gzofstream&
+ (*func)(gzofstream&, T1, T2);
+
+ // Arguments for manipulator function
+ T1 val1;
+ T2 val2;
+ };
+
+/*****************************************************************************/
+
+// Manipulator function thunks through to stream buffer
+inline gzofstream&
+setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
+{
+ (gzs.rdbuf())->setcompression(l, s);
+ return gzs;
+}
+
+// Manipulator constructor stores arguments
+template<typename T1, typename T2>
+ inline
+ gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
+ T1 v1,
+ T2 v2)
+ : func(f), val1(v1), val2(v2)
+ { }
+
+// Insertor applies underlying manipulator function to stream
+template<typename T1, typename T2>
+ inline gzofstream&
+ operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
+ { return (*m.func)(s, m.val1, m.val2); }
+
+// Insert this onto stream to simplify setting of compression level
+inline gzomanip2<int,int>
+setcompression(int l, int s = Z_DEFAULT_STRATEGY)
+{ return gzomanip2<int,int>(&setcompression, l, s); }
+
+#endif // ZFSTREAM_H
diff --git a/xs/src/png/zlib/contrib/masmx64/bld_ml64.bat b/xs/src/png/zlib/contrib/masmx64/bld_ml64.bat
new file mode 100644
index 000000000..f74bcef5b
--- /dev/null
+++ b/xs/src/png/zlib/contrib/masmx64/bld_ml64.bat
@@ -0,0 +1,2 @@
+ml64.exe /Flinffasx64 /c /Zi inffasx64.asm
+ml64.exe /Flgvmat64 /c /Zi gvmat64.asm
diff --git a/xs/src/png/zlib/contrib/masmx64/gvmat64.asm b/xs/src/png/zlib/contrib/masmx64/gvmat64.asm
new file mode 100644
index 000000000..c1817f1be
--- /dev/null
+++ b/xs/src/png/zlib/contrib/masmx64/gvmat64.asm
@@ -0,0 +1,553 @@
+;uInt longest_match_x64(
+; deflate_state *s,
+; IPos cur_match); /* current match */
+
+; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86_64
+; (AMD64 on Athlon 64, Opteron, Phenom
+; and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)
+; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+;
+; File written by Gilles Vollant, by converting to assembly the longest_match
+; from Jean-loup Gailly in deflate.c of zLib and infoZip zip.
+;
+; and by taking inspiration on asm686 with masm, optimised assembly code
+; from Brian Raiter, written 1998
+;
+; This software is provided 'as-is', without any express or implied
+; warranty. In no event will the authors be held liable for any damages
+; arising from the use of this software.
+;
+; Permission is granted to anyone to use this software for any purpose,
+; including commercial applications, and to alter it and redistribute it
+; freely, subject to the following restrictions:
+;
+; 1. The origin of this software must not be misrepresented; you must not
+; claim that you wrote the original software. If you use this software
+; in a product, an acknowledgment in the product documentation would be
+; appreciated but is not required.
+; 2. Altered source versions must be plainly marked as such, and must not be
+; misrepresented as being the original software
+; 3. This notice may not be removed or altered from any source distribution.
+;
+;
+;
+; http://www.zlib.net
+; http://www.winimage.com/zLibDll
+; http://www.muppetlabs.com/~breadbox/software/assembly.html
+;
+; to compile this file for infozip Zip, I use option:
+; ml64.exe /Flgvmat64 /c /Zi /DINFOZIP gvmat64.asm
+;
+; to compile this file for zLib, I use option:
+; ml64.exe /Flgvmat64 /c /Zi gvmat64.asm
+; Be carrefull to adapt zlib1222add below to your version of zLib
+; (if you use a version of zLib before 1.0.4 or after 1.2.2.2, change
+; value of zlib1222add later)
+;
+; This file compile with Microsoft Macro Assembler (x64) for AMD64
+;
+; ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK
+;
+; (you can get Windows WDK with ml64 for AMD64 from
+; http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price)
+;
+
+
+;uInt longest_match(s, cur_match)
+; deflate_state *s;
+; IPos cur_match; /* current match */
+.code
+longest_match PROC
+
+
+;LocalVarsSize equ 88
+ LocalVarsSize equ 72
+
+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12
+; free register : r14,r15
+; register can be saved : rsp
+
+ chainlenwmask equ rsp + 8 - LocalVarsSize ; high word: current chain len
+ ; low word: s->wmask
+;window equ rsp + xx - LocalVarsSize ; local copy of s->window ; stored in r10
+;windowbestlen equ rsp + xx - LocalVarsSize ; s->window + bestlen , use r10+r11
+;scanstart equ rsp + xx - LocalVarsSize ; first two bytes of string ; stored in r12w
+;scanend equ rsp + xx - LocalVarsSize ; last two bytes of string use ebx
+;scanalign equ rsp + xx - LocalVarsSize ; dword-misalignment of string r13
+;bestlen equ rsp + xx - LocalVarsSize ; size of best match so far -> r11d
+;scan equ rsp + xx - LocalVarsSize ; ptr to string wanting match -> r9
+IFDEF INFOZIP
+ELSE
+ nicematch equ (rsp + 16 - LocalVarsSize) ; a good enough match size
+ENDIF
+
+save_rdi equ rsp + 24 - LocalVarsSize
+save_rsi equ rsp + 32 - LocalVarsSize
+save_rbx equ rsp + 40 - LocalVarsSize
+save_rbp equ rsp + 48 - LocalVarsSize
+save_r12 equ rsp + 56 - LocalVarsSize
+save_r13 equ rsp + 64 - LocalVarsSize
+;save_r14 equ rsp + 72 - LocalVarsSize
+;save_r15 equ rsp + 80 - LocalVarsSize
+
+
+; summary of register usage
+; scanend ebx
+; scanendw bx
+; chainlenwmask edx
+; curmatch rsi
+; curmatchd esi
+; windowbestlen r8
+; scanalign r9
+; scanalignd r9d
+; window r10
+; bestlen r11
+; bestlend r11d
+; scanstart r12d
+; scanstartw r12w
+; scan r13
+; nicematch r14d
+; limit r15
+; limitd r15d
+; prev rcx
+
+; all the +4 offsets are due to the addition of pending_buf_size (in zlib
+; in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, remove the +4).
+; Note : these value are good with a 8 bytes boundary pack structure
+
+
+ MAX_MATCH equ 258
+ MIN_MATCH equ 3
+ MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
+
+
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+
+; all the +zlib1222add offsets are due to the addition of fields
+; in zlib in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+
+
+IFDEF INFOZIP
+
+_DATA SEGMENT
+COMM window_size:DWORD
+; WMask ; 7fff
+COMM window:BYTE:010040H
+COMM prev:WORD:08000H
+; MatchLen : unused
+; PrevMatch : unused
+COMM strstart:DWORD
+COMM match_start:DWORD
+; Lookahead : ignore
+COMM prev_length:DWORD ; PrevLen
+COMM max_chain_length:DWORD
+COMM good_match:DWORD
+COMM nice_match:DWORD
+prev_ad equ OFFSET prev
+window_ad equ OFFSET window
+nicematch equ nice_match
+_DATA ENDS
+WMask equ 07fffh
+
+ELSE
+
+ IFNDEF zlib1222add
+ zlib1222add equ 8
+ ENDIF
+dsWSize equ 56+zlib1222add+(zlib1222add/2)
+dsWMask equ 64+zlib1222add+(zlib1222add/2)
+dsWindow equ 72+zlib1222add
+dsPrev equ 88+zlib1222add
+dsMatchLen equ 128+zlib1222add
+dsPrevMatch equ 132+zlib1222add
+dsStrStart equ 140+zlib1222add
+dsMatchStart equ 144+zlib1222add
+dsLookahead equ 148+zlib1222add
+dsPrevLen equ 152+zlib1222add
+dsMaxChainLen equ 156+zlib1222add
+dsGoodMatch equ 172+zlib1222add
+dsNiceMatch equ 176+zlib1222add
+
+window_size equ [ rcx + dsWSize]
+WMask equ [ rcx + dsWMask]
+window_ad equ [ rcx + dsWindow]
+prev_ad equ [ rcx + dsPrev]
+strstart equ [ rcx + dsStrStart]
+match_start equ [ rcx + dsMatchStart]
+Lookahead equ [ rcx + dsLookahead] ; 0ffffffffh on infozip
+prev_length equ [ rcx + dsPrevLen]
+max_chain_length equ [ rcx + dsMaxChainLen]
+good_match equ [ rcx + dsGoodMatch]
+nice_match equ [ rcx + dsNiceMatch]
+ENDIF
+
+; parameter 1 in r8(deflate state s), param 2 in rdx (cur match)
+
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+;
+; All registers must be preserved across the call, except for
+; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.
+
+
+
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+
+
+;;; Retrieve the function arguments. r8d will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+
+; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)
+
+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx
+
+ mov [save_rdi],rdi
+ mov [save_rsi],rsi
+ mov [save_rbx],rbx
+ mov [save_rbp],rbp
+IFDEF INFOZIP
+ mov r8d,ecx
+ELSE
+ mov r8d,edx
+ENDIF
+ mov [save_r12],r12
+ mov [save_r13],r13
+; mov [save_r14],r14
+; mov [save_r15],r15
+
+
+;;; uInt wmask = s->w_mask;
+;;; unsigned chain_length = s->max_chain_length;
+;;; if (s->prev_length >= s->good_match) {
+;;; chain_length >>= 2;
+;;; }
+
+ mov edi, prev_length
+ mov esi, good_match
+ mov eax, WMask
+ mov ebx, max_chain_length
+ cmp edi, esi
+ jl LastMatchGood
+ shr ebx, 2
+LastMatchGood:
+
+;;; chainlen is decremented once beforehand so that the function can
+;;; use the sign flag instead of the zero flag for the exit test.
+;;; It is then shifted into the high word, to make room for the wmask
+;;; value, which it will always accompany.
+
+ dec ebx
+ shl ebx, 16
+ or ebx, eax
+
+;;; on zlib only
+;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+IFDEF INFOZIP
+ mov [chainlenwmask], ebx
+; on infozip nice_match = [nice_match]
+ELSE
+ mov eax, nice_match
+ mov [chainlenwmask], ebx
+ mov r10d, Lookahead
+ cmp r10d, eax
+ cmovnl r10d, eax
+ mov [nicematch],r10d
+ENDIF
+
+;;; register Bytef *scan = s->window + s->strstart;
+ mov r10, window_ad
+ mov ebp, strstart
+ lea r13, [r10 + rbp]
+
+;;; Determine how many bytes the scan ptr is off from being
+;;; dword-aligned.
+
+ mov r9,r13
+ neg r13
+ and r13,3
+
+;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
+IFDEF INFOZIP
+ mov eax,07efah ; MAX_DIST = (WSIZE-MIN_LOOKAHEAD) (0x8000-(3+8+1))
+ELSE
+ mov eax, window_size
+ sub eax, MIN_LOOKAHEAD
+ENDIF
+ xor edi,edi
+ sub ebp, eax
+
+ mov r11d, prev_length
+
+ cmovng ebp,edi
+
+;;; int best_len = s->prev_length;
+
+
+;;; Store the sum of s->window + best_len in esi locally, and in esi.
+
+ lea rsi,[r10+r11]
+
+;;; register ush scan_start = *(ushf*)scan;
+;;; register ush scan_end = *(ushf*)(scan+best_len-1);
+;;; Posf *prev = s->prev;
+
+ movzx r12d,word ptr [r9]
+ movzx ebx, word ptr [r9 + r11 - 1]
+
+ mov rdi, prev_ad
+
+;;; Jump into the main loop.
+
+ mov edx, [chainlenwmask]
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ jz LookupLoopIsZero
+
+LookupLoop1:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+ sub edx, 00010000h
+ js LeaveNow
+
+LoopEntry1:
+ cmp bx,word ptr [rsi + r8 - 1]
+ jz LookupLoopIsZero
+
+LookupLoop2:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+ sub edx, 00010000h
+ js LeaveNow
+
+LoopEntry2:
+ cmp bx,word ptr [rsi + r8 - 1]
+ jz LookupLoopIsZero
+
+LookupLoop4:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+ sub edx, 00010000h
+ js LeaveNow
+
+LoopEntry4:
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ jnz LookupLoop1
+ jmp LookupLoopIsZero
+
+
+;;; do {
+;;; match = s->window + cur_match;
+;;; if (*(ushf*)(match+best_len-1) != scan_end ||
+;;; *(ushf*)match != scan_start) continue;
+;;; [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;; && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;;
+;;; Within this loop:
+;;; ebx = scanend
+;;; r8d = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+
+LookupLoop:
+ and r8d, edx
+
+ movzx r8d, word ptr [rdi + r8*2]
+ cmp r8d, ebp
+ jbe LeaveNow
+ sub edx, 00010000h
+ js LeaveNow
+
+LoopEntry:
+
+ cmp bx,word ptr [rsi + r8 - 1]
+ jnz LookupLoop1
+LookupLoopIsZero:
+ cmp r12w, word ptr [r10 + r8]
+ jnz LookupLoop1
+
+
+;;; Store the current value of chainlen.
+ mov [chainlenwmask], edx
+
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+
+ lea rsi,[r8+r10]
+ mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8)
+ lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8]
+ lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8]
+
+ prefetcht1 [rsi+rdx]
+ prefetcht1 [rdi+rdx]
+
+
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust rdx so that it is offset to the exact byte that mismatched.
+;;;
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (rsi will still be misaligned three times out of four.)
+;;;
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+
+
+LoopCmps:
+ mov rax, [rsi + rdx]
+ xor rax, [rdi + rdx]
+ jnz LeaveLoopCmps
+
+ mov rax, [rsi + rdx + 8]
+ xor rax, [rdi + rdx + 8]
+ jnz LeaveLoopCmps8
+
+
+ mov rax, [rsi + rdx + 8+8]
+ xor rax, [rdi + rdx + 8+8]
+ jnz LeaveLoopCmps16
+
+ add rdx,8+8+8
+
+ jnz short LoopCmps
+ jmp short LenMaximum
+LeaveLoopCmps16: add rdx,8
+LeaveLoopCmps8: add rdx,8
+LeaveLoopCmps:
+
+ test eax, 0000FFFFh
+ jnz LenLower
+
+ test eax,0ffffffffh
+
+ jnz LenLower32
+
+ add rdx,4
+ shr rax,32
+ or ax,ax
+ jnz LenLower
+
+LenLower32:
+ shr eax,16
+ add rdx,2
+LenLower: sub al, 1
+ adc rdx, 0
+;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+;;; then automatically accept it as the best possible match and leave.
+
+ lea rax, [rdi + rdx]
+ sub rax, r9
+ cmp eax, MAX_MATCH
+ jge LenMaximum
+
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+;///////////////////////////////////
+
+ cmp eax, r11d
+ jg LongerMatch
+
+ lea rsi,[r10+r11]
+
+ mov rdi, prev_ad
+ mov edx, [chainlenwmask]
+ jmp LookupLoop
+
+;;; s->match_start = cur_match;
+;;; best_len = len;
+;;; if (len >= nice_match) break;
+;;; scan_end = *(ushf*)(scan+best_len-1);
+
+LongerMatch:
+ mov r11d, eax
+ mov match_start, r8d
+ cmp eax, [nicematch]
+ jge LeaveNow
+
+ lea rsi,[r10+rax]
+
+ movzx ebx, word ptr [r9 + rax - 1]
+ mov rdi, prev_ad
+ mov edx, [chainlenwmask]
+ jmp LookupLoop
+
+;;; Accept the current string, with the maximum possible length.
+
+LenMaximum:
+ mov r11d,MAX_MATCH
+ mov match_start, r8d
+
+;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+;;; return s->lookahead;
+
+LeaveNow:
+IFDEF INFOZIP
+ mov eax,r11d
+ELSE
+ mov eax, Lookahead
+ cmp r11d, eax
+ cmovng eax, r11d
+ENDIF
+
+;;; Restore the stack and return from whence we came.
+
+
+ mov rsi,[save_rsi]
+ mov rdi,[save_rdi]
+ mov rbx,[save_rbx]
+ mov rbp,[save_rbp]
+ mov r12,[save_r12]
+ mov r13,[save_r13]
+; mov r14,[save_r14]
+; mov r15,[save_r15]
+
+
+ ret 0
+; please don't remove this string !
+; Your can freely use gvmat64 in any free or commercial app
+; but it is far better don't remove the string in the binary!
+ db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0
+longest_match ENDP
+
+match_init PROC
+ ret 0
+match_init ENDP
+
+
+END
diff --git a/xs/src/png/zlib/contrib/masmx64/inffas8664.c b/xs/src/png/zlib/contrib/masmx64/inffas8664.c
new file mode 100644
index 000000000..aa861a333
--- /dev/null
+++ b/xs/src/png/zlib/contrib/masmx64/inffas8664.c
@@ -0,0 +1,186 @@
+/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding
+ * version for AMD64 on Windows using Microsoft C compiler
+ *
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+ * Please use the copyright conditions above.
+ *
+ * 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant
+ *
+ * inffas8664.c call function inffas8664fnc in inffasx64.asm
+ * inffasx64.asm is automatically convert from AMD64 portion of inffas86.c
+ *
+ * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also
+ * slightly quicker on x86 systems because, instead of using rep movsb to copy
+ * data, it uses rep movsw, which moves data in 2-byte chunks instead of single
+ * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
+ * from http://fedora.linux.duke.edu/fc1_x86_64
+ * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
+ * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version,
+ * when decompressing mozilla-source-1.3.tar.gz.
+ *
+ * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
+ * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at
+ * the moment. I have successfully compiled and tested this code with gcc2.96,
+ * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S
+ * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
+ * enabled. I will attempt to merge the MMX code into this version. Newer
+ * versions of this and inffast.S can be found at
+ * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
+ *
+ */
+
+#include <stdio.h>
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* Mark Adler's comments from inffast.c: */
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+
+
+
+ typedef struct inffast_ar {
+/* 64 32 x86 x86_64 */
+/* ar offset register */
+/* 0 0 */ void *esp; /* esp save */
+/* 8 4 */ void *ebp; /* ebp save */
+/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */
+/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */
+/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */
+/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */
+/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */
+/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */
+/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */
+/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */
+/* 80 40 */ size_t /*unsigned long */hold; /* edx rdx local strm->hold */
+/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */
+/* 92 48 */ unsigned wsize; /* window size */
+/* 96 52 */ unsigned write; /* window write index */
+/*100 56 */ unsigned lmask; /* r12 mask for lcode */
+/*104 60 */ unsigned dmask; /* r13 mask for dcode */
+/*108 64 */ unsigned len; /* r14 match length */
+/*112 68 */ unsigned dist; /* r15 match distance */
+/*116 72 */ unsigned status; /* set when state chng*/
+ } type_ar;
+#ifdef ASMINF
+
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start; /* inflate()'s starting value for strm->avail_out */
+{
+ struct inflate_state FAR *state;
+ type_ar ar;
+ void inffas8664fnc(struct inffast_ar * par);
+
+
+
+#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64))
+#define PAD_AVAIL_IN 6
+#define PAD_AVAIL_OUT 258
+#else
+#define PAD_AVAIL_IN 5
+#define PAD_AVAIL_OUT 257
+#endif
+
+ /* copy state to local variables */
+ state = (struct inflate_state FAR *)strm->state;
+
+ ar.in = strm->next_in;
+ ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
+ ar.out = strm->next_out;
+ ar.beg = ar.out - (start - strm->avail_out);
+ ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
+ ar.wsize = state->wsize;
+ ar.write = state->wnext;
+ ar.window = state->window;
+ ar.hold = state->hold;
+ ar.bits = state->bits;
+ ar.lcode = state->lencode;
+ ar.dcode = state->distcode;
+ ar.lmask = (1U << state->lenbits) - 1;
+ ar.dmask = (1U << state->distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+
+ /* align in on 1/2 hold size boundary */
+ while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
+ ar.hold += (unsigned long)*ar.in++ << ar.bits;
+ ar.bits += 8;
+ }
+
+ inffas8664fnc(&ar);
+
+ if (ar.status > 1) {
+ if (ar.status == 2)
+ strm->msg = "invalid literal/length code";
+ else if (ar.status == 3)
+ strm->msg = "invalid distance code";
+ else
+ strm->msg = "invalid distance too far back";
+ state->mode = BAD;
+ }
+ else if ( ar.status == 1 ) {
+ state->mode = TYPE;
+ }
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ ar.len = ar.bits >> 3;
+ ar.in -= ar.len;
+ ar.bits -= ar.len << 3;
+ ar.hold &= (1U << ar.bits) - 1;
+
+ /* update state and return */
+ strm->next_in = ar.in;
+ strm->next_out = ar.out;
+ strm->avail_in = (unsigned)(ar.in < ar.last ?
+ PAD_AVAIL_IN + (ar.last - ar.in) :
+ PAD_AVAIL_IN - (ar.in - ar.last));
+ strm->avail_out = (unsigned)(ar.out < ar.end ?
+ PAD_AVAIL_OUT + (ar.end - ar.out) :
+ PAD_AVAIL_OUT - (ar.out - ar.end));
+ state->hold = (unsigned long)ar.hold;
+ state->bits = ar.bits;
+ return;
+}
+
+#endif
diff --git a/xs/src/png/zlib/contrib/masmx64/inffasx64.asm b/xs/src/png/zlib/contrib/masmx64/inffasx64.asm
new file mode 100644
index 000000000..41ec82392
--- /dev/null
+++ b/xs/src/png/zlib/contrib/masmx64/inffasx64.asm
@@ -0,0 +1,396 @@
+; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding
+; version for AMD64 on Windows using Microsoft C compiler
+;
+; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c
+; inffasx64.asm is called by inffas8664.c, which contain more info.
+
+
+; to compile this file, I use option
+; ml64.exe /Flinffasx64 /c /Zi inffasx64.asm
+; with Microsoft Macro Assembler (x64) for AMD64
+;
+
+; This file compile with Microsoft Macro Assembler (x64) for AMD64
+;
+; ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK
+;
+; (you can get Windows WDK with ml64 for AMD64 from
+; http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price)
+;
+
+
+.code
+inffas8664fnc PROC
+
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+;
+; All registers must be preserved across the call, except for
+; rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch.
+
+
+ mov [rsp-8],rsi
+ mov [rsp-16],rdi
+ mov [rsp-24],r12
+ mov [rsp-32],r13
+ mov [rsp-40],r14
+ mov [rsp-48],r15
+ mov [rsp-56],rbx
+
+ mov rax,rcx
+
+ mov [rax+8], rbp ; /* save regs rbp and rsp */
+ mov [rax], rsp
+
+ mov rsp, rax ; /* make rsp point to &ar */
+
+ mov rsi, [rsp+16] ; /* rsi = in */
+ mov rdi, [rsp+32] ; /* rdi = out */
+ mov r9, [rsp+24] ; /* r9 = last */
+ mov r10, [rsp+48] ; /* r10 = end */
+ mov rbp, [rsp+64] ; /* rbp = lcode */
+ mov r11, [rsp+72] ; /* r11 = dcode */
+ mov rdx, [rsp+80] ; /* rdx = hold */
+ mov ebx, [rsp+88] ; /* ebx = bits */
+ mov r12d, [rsp+100] ; /* r12d = lmask */
+ mov r13d, [rsp+104] ; /* r13d = dmask */
+ ; /* r14d = len */
+ ; /* r15d = dist */
+
+
+ cld
+ cmp r10, rdi
+ je L_one_time ; /* if only one decode left */
+ cmp r9, rsi
+
+ jne L_do_loop
+
+
+L_one_time:
+ mov r8, r12 ; /* r8 = lmask */
+ cmp bl, 32
+ ja L_get_length_code_one_time
+
+ lodsd ; /* eax = *(uint *)in++ */
+ mov cl, bl ; /* cl = bits, needs it for shifting */
+ add bl, 32 ; /* bits += 32 */
+ shl rax, cl
+ or rdx, rax ; /* hold |= *((uint *)in)++ << bits */
+ jmp L_get_length_code_one_time
+
+ALIGN 4
+L_while_test:
+ cmp r10, rdi
+ jbe L_break_loop
+ cmp r9, rsi
+ jbe L_break_loop
+
+L_do_loop:
+ mov r8, r12 ; /* r8 = lmask */
+ cmp bl, 32
+ ja L_get_length_code ; /* if (32 < bits) */
+
+ lodsd ; /* eax = *(uint *)in++ */
+ mov cl, bl ; /* cl = bits, needs it for shifting */
+ add bl, 32 ; /* bits += 32 */
+ shl rax, cl
+ or rdx, rax ; /* hold |= *((uint *)in)++ << bits */
+
+L_get_length_code:
+ and r8, rdx ; /* r8 &= hold */
+ mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */
+
+ mov cl, ah ; /* cl = this.bits */
+ sub bl, ah ; /* bits -= this.bits */
+ shr rdx, cl ; /* hold >>= this.bits */
+
+ test al, al
+ jnz L_test_for_length_base ; /* if (op != 0) 45.7% */
+
+ mov r8, r12 ; /* r8 = lmask */
+ shr eax, 16 ; /* output this.val char */
+ stosb
+
+L_get_length_code_one_time:
+ and r8, rdx ; /* r8 &= hold */
+ mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */
+
+L_dolen:
+ mov cl, ah ; /* cl = this.bits */
+ sub bl, ah ; /* bits -= this.bits */
+ shr rdx, cl ; /* hold >>= this.bits */
+
+ test al, al
+ jnz L_test_for_length_base ; /* if (op != 0) 45.7% */
+
+ shr eax, 16 ; /* output this.val char */
+ stosb
+ jmp L_while_test
+
+ALIGN 4
+L_test_for_length_base:
+ mov r14d, eax ; /* len = this */
+ shr r14d, 16 ; /* len = this.val */
+ mov cl, al
+
+ test al, 16
+ jz L_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */
+ and cl, 15 ; /* op &= 15 */
+ jz L_decode_distance ; /* if (!op) */
+
+L_add_bits_to_len:
+ sub bl, cl
+ xor eax, eax
+ inc eax
+ shl eax, cl
+ dec eax
+ and eax, edx ; /* eax &= hold */
+ shr rdx, cl
+ add r14d, eax ; /* len += hold & mask[op] */
+
+L_decode_distance:
+ mov r8, r13 ; /* r8 = dmask */
+ cmp bl, 32
+ ja L_get_distance_code ; /* if (32 < bits) */
+
+ lodsd ; /* eax = *(uint *)in++ */
+ mov cl, bl ; /* cl = bits, needs it for shifting */
+ add bl, 32 ; /* bits += 32 */
+ shl rax, cl
+ or rdx, rax ; /* hold |= *((uint *)in)++ << bits */
+
+L_get_distance_code:
+ and r8, rdx ; /* r8 &= hold */
+ mov eax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */
+
+L_dodist:
+ mov r15d, eax ; /* dist = this */
+ shr r15d, 16 ; /* dist = this.val */
+ mov cl, ah
+ sub bl, ah ; /* bits -= this.bits */
+ shr rdx, cl ; /* hold >>= this.bits */
+ mov cl, al ; /* cl = this.op */
+
+ test al, 16 ; /* if ((op & 16) == 0) */
+ jz L_test_for_second_level_dist
+ and cl, 15 ; /* op &= 15 */
+ jz L_check_dist_one
+
+L_add_bits_to_dist:
+ sub bl, cl
+ xor eax, eax
+ inc eax
+ shl eax, cl
+ dec eax ; /* (1 << op) - 1 */
+ and eax, edx ; /* eax &= hold */
+ shr rdx, cl
+ add r15d, eax ; /* dist += hold & ((1 << op) - 1) */
+
+L_check_window:
+ mov r8, rsi ; /* save in so from can use it's reg */
+ mov rax, rdi
+ sub rax, [rsp+40] ; /* nbytes = out - beg */
+
+ cmp eax, r15d
+ jb L_clip_window ; /* if (dist > nbytes) 4.2% */
+
+ mov ecx, r14d ; /* ecx = len */
+ mov rsi, rdi
+ sub rsi, r15 ; /* from = out - dist */
+
+ sar ecx, 1
+ jnc L_copy_two ; /* if len % 2 == 0 */
+
+ rep movsw
+ mov al, [rsi]
+ mov [rdi], al
+ inc rdi
+
+ mov rsi, r8 ; /* move in back to %rsi, toss from */
+ jmp L_while_test
+
+L_copy_two:
+ rep movsw
+ mov rsi, r8 ; /* move in back to %rsi, toss from */
+ jmp L_while_test
+
+ALIGN 4
+L_check_dist_one:
+ cmp r15d, 1 ; /* if dist 1, is a memset */
+ jne L_check_window
+ cmp [rsp+40], rdi ; /* if out == beg, outside window */
+ je L_check_window
+
+ mov ecx, r14d ; /* ecx = len */
+ mov al, [rdi-1]
+ mov ah, al
+
+ sar ecx, 1
+ jnc L_set_two
+ mov [rdi], al
+ inc rdi
+
+L_set_two:
+ rep stosw
+ jmp L_while_test
+
+ALIGN 4
+L_test_for_second_level_length:
+ test al, 64
+ jnz L_test_for_end_of_block ; /* if ((op & 64) != 0) */
+
+ xor eax, eax
+ inc eax
+ shl eax, cl
+ dec eax
+ and eax, edx ; /* eax &= hold */
+ add eax, r14d ; /* eax += len */
+ mov eax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/
+ jmp L_dolen
+
+ALIGN 4
+L_test_for_second_level_dist:
+ test al, 64
+ jnz L_invalid_distance_code ; /* if ((op & 64) != 0) */
+
+ xor eax, eax
+ inc eax
+ shl eax, cl
+ dec eax
+ and eax, edx ; /* eax &= hold */
+ add eax, r15d ; /* eax += dist */
+ mov eax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/
+ jmp L_dodist
+
+ALIGN 4
+L_clip_window:
+ mov ecx, eax ; /* ecx = nbytes */
+ mov eax, [rsp+92] ; /* eax = wsize, prepare for dist cmp */
+ neg ecx ; /* nbytes = -nbytes */
+
+ cmp eax, r15d
+ jb L_invalid_distance_too_far ; /* if (dist > wsize) */
+
+ add ecx, r15d ; /* nbytes = dist - nbytes */
+ cmp dword ptr [rsp+96], 0
+ jne L_wrap_around_window ; /* if (write != 0) */
+
+ mov rsi, [rsp+56] ; /* from = window */
+ sub eax, ecx ; /* eax -= nbytes */
+ add rsi, rax ; /* from += wsize - nbytes */
+
+ mov eax, r14d ; /* eax = len */
+ cmp r14d, ecx
+ jbe L_do_copy ; /* if (nbytes >= len) */
+
+ sub eax, ecx ; /* eax -= nbytes */
+ rep movsb
+ mov rsi, rdi
+ sub rsi, r15 ; /* from = &out[ -dist ] */
+ jmp L_do_copy
+
+ALIGN 4
+L_wrap_around_window:
+ mov eax, [rsp+96] ; /* eax = write */
+ cmp ecx, eax
+ jbe L_contiguous_in_window ; /* if (write >= nbytes) */
+
+ mov esi, [rsp+92] ; /* from = wsize */
+ add rsi, [rsp+56] ; /* from += window */
+ add rsi, rax ; /* from += write */
+ sub rsi, rcx ; /* from -= nbytes */
+ sub ecx, eax ; /* nbytes -= write */
+
+ mov eax, r14d ; /* eax = len */
+ cmp eax, ecx
+ jbe L_do_copy ; /* if (nbytes >= len) */
+
+ sub eax, ecx ; /* len -= nbytes */
+ rep movsb
+ mov rsi, [rsp+56] ; /* from = window */
+ mov ecx, [rsp+96] ; /* nbytes = write */
+ cmp eax, ecx
+ jbe L_do_copy ; /* if (nbytes >= len) */
+
+ sub eax, ecx ; /* len -= nbytes */
+ rep movsb
+ mov rsi, rdi
+ sub rsi, r15 ; /* from = out - dist */
+ jmp L_do_copy
+
+ALIGN 4
+L_contiguous_in_window:
+ mov rsi, [rsp+56] ; /* rsi = window */
+ add rsi, rax
+ sub rsi, rcx ; /* from += write - nbytes */
+
+ mov eax, r14d ; /* eax = len */
+ cmp eax, ecx
+ jbe L_do_copy ; /* if (nbytes >= len) */
+
+ sub eax, ecx ; /* len -= nbytes */
+ rep movsb
+ mov rsi, rdi
+ sub rsi, r15 ; /* from = out - dist */
+ jmp L_do_copy ; /* if (nbytes >= len) */
+
+ALIGN 4
+L_do_copy:
+ mov ecx, eax ; /* ecx = len */
+ rep movsb
+
+ mov rsi, r8 ; /* move in back to %esi, toss from */
+ jmp L_while_test
+
+L_test_for_end_of_block:
+ test al, 32
+ jz L_invalid_literal_length_code
+ mov dword ptr [rsp+116], 1
+ jmp L_break_loop_with_status
+
+L_invalid_literal_length_code:
+ mov dword ptr [rsp+116], 2
+ jmp L_break_loop_with_status
+
+L_invalid_distance_code:
+ mov dword ptr [rsp+116], 3
+ jmp L_break_loop_with_status
+
+L_invalid_distance_too_far:
+ mov dword ptr [rsp+116], 4
+ jmp L_break_loop_with_status
+
+L_break_loop:
+ mov dword ptr [rsp+116], 0
+
+L_break_loop_with_status:
+; /* put in, out, bits, and hold back into ar and pop esp */
+ mov [rsp+16], rsi ; /* in */
+ mov [rsp+32], rdi ; /* out */
+ mov [rsp+88], ebx ; /* bits */
+ mov [rsp+80], rdx ; /* hold */
+
+ mov rax, [rsp] ; /* restore rbp and rsp */
+ mov rbp, [rsp+8]
+ mov rsp, rax
+
+
+
+ mov rsi,[rsp-8]
+ mov rdi,[rsp-16]
+ mov r12,[rsp-24]
+ mov r13,[rsp-32]
+ mov r14,[rsp-40]
+ mov r15,[rsp-48]
+ mov rbx,[rsp-56]
+
+ ret 0
+; :
+; : "m" (ar)
+; : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
+; "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
+; );
+
+inffas8664fnc ENDP
+;_TEXT ENDS
+END
diff --git a/xs/src/png/zlib/contrib/masmx64/readme.txt b/xs/src/png/zlib/contrib/masmx64/readme.txt
new file mode 100644
index 000000000..652571c7a
--- /dev/null
+++ b/xs/src/png/zlib/contrib/masmx64/readme.txt
@@ -0,0 +1,31 @@
+Summary
+-------
+This directory contains ASM implementations of the functions
+longest_match() and inflate_fast(), for 64 bits x86 (both AMD64 and Intel EM64t),
+for use with Microsoft Macro Assembler (x64) for AMD64 and Microsoft C++ 64 bits.
+
+gvmat64.asm is written by Gilles Vollant (2005), by using Brian Raiter 686/32 bits
+ assembly optimized version from Jean-loup Gailly original longest_match function
+
+inffasx64.asm and inffas8664.c were written by Chris Anderson, by optimizing
+ original function from Mark Adler
+
+Use instructions
+----------------
+Assemble the .asm files using MASM and put the object files into the zlib source
+directory. You can also get object files here:
+
+ http://www.winimage.com/zLibDll/zlib124_masm_obj.zip
+
+define ASMV and ASMINF in your project. Include inffas8664.c in your source tree,
+and inffasx64.obj and gvmat64.obj as object to link.
+
+
+Build instructions
+------------------
+run bld_64.bat with Microsoft Macro Assembler (x64) for AMD64 (ml64.exe)
+
+ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK
+
+You can get Windows 2003 server DDK with ml64 and cl for AMD64 from
+ http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price)
diff --git a/xs/src/png/zlib/contrib/masmx86/bld_ml32.bat b/xs/src/png/zlib/contrib/masmx86/bld_ml32.bat
new file mode 100644
index 000000000..fcf5755e4
--- /dev/null
+++ b/xs/src/png/zlib/contrib/masmx86/bld_ml32.bat
@@ -0,0 +1,2 @@
+ml /coff /Zi /c /Flmatch686.lst match686.asm
+ml /coff /Zi /c /Flinffas32.lst inffas32.asm
diff --git a/xs/src/png/zlib/contrib/masmx86/inffas32.asm b/xs/src/png/zlib/contrib/masmx86/inffas32.asm
new file mode 100644
index 000000000..cb37a81e4
--- /dev/null
+++ b/xs/src/png/zlib/contrib/masmx86/inffas32.asm
@@ -0,0 +1,1080 @@
+;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding
+; *
+; * inffas32.asm is derivated from inffas86.c, with translation of assembly code
+; *
+; * Copyright (C) 1995-2003 Mark Adler
+; * For conditions of distribution and use, see copyright notice in zlib.h
+; *
+; * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+; * Please use the copyright conditions above.
+; *
+; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
+; * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at
+; * the moment. I have successfully compiled and tested this code with gcc2.96,
+; * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S
+; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
+; * enabled. I will attempt to merge the MMX code into this version. Newer
+; * versions of this and inffast.S can be found at
+; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
+; *
+; * 2005 : modification by Gilles Vollant
+; */
+; For Visual C++ 4.x and higher and ML 6.x and higher
+; ml.exe is in directory \MASM611C of Win95 DDK
+; ml.exe is also distributed in http://www.masm32.com/masmdl.htm
+; and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/
+;
+;
+; compile with command line option
+; ml /coff /Zi /c /Flinffas32.lst inffas32.asm
+
+; if you define NO_GZIP (see inflate.h), compile with
+; ml /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm
+
+
+; zlib122sup is 0 fort zlib 1.2.2.1 and lower
+; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head
+; in inflate_state in inflate.h)
+zlib1222sup equ 8
+
+
+IFDEF GUNZIP
+ INFLATE_MODE_TYPE equ 11
+ INFLATE_MODE_BAD equ 26
+ELSE
+ IFNDEF NO_GUNZIP
+ INFLATE_MODE_TYPE equ 11
+ INFLATE_MODE_BAD equ 26
+ ELSE
+ INFLATE_MODE_TYPE equ 3
+ INFLATE_MODE_BAD equ 17
+ ENDIF
+ENDIF
+
+
+; 75 "inffast.S"
+;FILE "inffast.S"
+
+;;;GLOBAL _inflate_fast
+
+;;;SECTION .text
+
+
+
+ .586p
+ .mmx
+
+ name inflate_fast_x86
+ .MODEL FLAT
+
+_DATA segment
+inflate_fast_use_mmx:
+ dd 1
+
+
+_TEXT segment
+
+
+
+ALIGN 4
+ db 'Fast decoding Code from Chris Anderson'
+ db 0
+
+ALIGN 4
+invalid_literal_length_code_msg:
+ db 'invalid literal/length code'
+ db 0
+
+ALIGN 4
+invalid_distance_code_msg:
+ db 'invalid distance code'
+ db 0
+
+ALIGN 4
+invalid_distance_too_far_msg:
+ db 'invalid distance too far back'
+ db 0
+
+
+ALIGN 4
+inflate_fast_mask:
+dd 0
+dd 1
+dd 3
+dd 7
+dd 15
+dd 31
+dd 63
+dd 127
+dd 255
+dd 511
+dd 1023
+dd 2047
+dd 4095
+dd 8191
+dd 16383
+dd 32767
+dd 65535
+dd 131071
+dd 262143
+dd 524287
+dd 1048575
+dd 2097151
+dd 4194303
+dd 8388607
+dd 16777215
+dd 33554431
+dd 67108863
+dd 134217727
+dd 268435455
+dd 536870911
+dd 1073741823
+dd 2147483647
+dd 4294967295
+
+
+mode_state equ 0 ;/* state->mode */
+wsize_state equ (32+zlib1222sup) ;/* state->wsize */
+write_state equ (36+4+zlib1222sup) ;/* state->write */
+window_state equ (40+4+zlib1222sup) ;/* state->window */
+hold_state equ (44+4+zlib1222sup) ;/* state->hold */
+bits_state equ (48+4+zlib1222sup) ;/* state->bits */
+lencode_state equ (64+4+zlib1222sup) ;/* state->lencode */
+distcode_state equ (68+4+zlib1222sup) ;/* state->distcode */
+lenbits_state equ (72+4+zlib1222sup) ;/* state->lenbits */
+distbits_state equ (76+4+zlib1222sup) ;/* state->distbits */
+
+
+;;SECTION .text
+; 205 "inffast.S"
+;GLOBAL inflate_fast_use_mmx
+
+;SECTION .data
+
+
+; GLOBAL inflate_fast_use_mmx:object
+;.size inflate_fast_use_mmx, 4
+; 226 "inffast.S"
+;SECTION .text
+
+ALIGN 4
+_inflate_fast proc near
+.FPO (16, 4, 0, 0, 1, 0)
+ push edi
+ push esi
+ push ebp
+ push ebx
+ pushfd
+ sub esp,64
+ cld
+
+
+
+
+ mov esi, [esp+88]
+ mov edi, [esi+28]
+
+
+
+
+
+
+
+ mov edx, [esi+4]
+ mov eax, [esi+0]
+
+ add edx,eax
+ sub edx,11
+
+ mov [esp+44],eax
+ mov [esp+20],edx
+
+ mov ebp, [esp+92]
+ mov ecx, [esi+16]
+ mov ebx, [esi+12]
+
+ sub ebp,ecx
+ neg ebp
+ add ebp,ebx
+
+ sub ecx,257
+ add ecx,ebx
+
+ mov [esp+60],ebx
+ mov [esp+40],ebp
+ mov [esp+16],ecx
+; 285 "inffast.S"
+ mov eax, [edi+lencode_state]
+ mov ecx, [edi+distcode_state]
+
+ mov [esp+8],eax
+ mov [esp+12],ecx
+
+ mov eax,1
+ mov ecx, [edi+lenbits_state]
+ shl eax,cl
+ dec eax
+ mov [esp+0],eax
+
+ mov eax,1
+ mov ecx, [edi+distbits_state]
+ shl eax,cl
+ dec eax
+ mov [esp+4],eax
+
+ mov eax, [edi+wsize_state]
+ mov ecx, [edi+write_state]
+ mov edx, [edi+window_state]
+
+ mov [esp+52],eax
+ mov [esp+48],ecx
+ mov [esp+56],edx
+
+ mov ebp, [edi+hold_state]
+ mov ebx, [edi+bits_state]
+; 321 "inffast.S"
+ mov esi, [esp+44]
+ mov ecx, [esp+20]
+ cmp ecx,esi
+ ja L_align_long
+
+ add ecx,11
+ sub ecx,esi
+ mov eax,12
+ sub eax,ecx
+ lea edi, [esp+28]
+ rep movsb
+ mov ecx,eax
+ xor eax,eax
+ rep stosb
+ lea esi, [esp+28]
+ mov [esp+20],esi
+ jmp L_is_aligned
+
+
+L_align_long:
+ test esi,3
+ jz L_is_aligned
+ xor eax,eax
+ mov al, [esi]
+ inc esi
+ mov ecx,ebx
+ add ebx,8
+ shl eax,cl
+ or ebp,eax
+ jmp L_align_long
+
+L_is_aligned:
+ mov edi, [esp+60]
+; 366 "inffast.S"
+L_check_mmx:
+ cmp dword ptr [inflate_fast_use_mmx],2
+ je L_init_mmx
+ ja L_do_loop
+
+ push eax
+ push ebx
+ push ecx
+ push edx
+ pushfd
+ mov eax, [esp]
+ xor dword ptr [esp],0200000h
+
+
+
+
+ popfd
+ pushfd
+ pop edx
+ xor edx,eax
+ jz L_dont_use_mmx
+ xor eax,eax
+ cpuid
+ cmp ebx,0756e6547h
+ jne L_dont_use_mmx
+ cmp ecx,06c65746eh
+ jne L_dont_use_mmx
+ cmp edx,049656e69h
+ jne L_dont_use_mmx
+ mov eax,1
+ cpuid
+ shr eax,8
+ and eax,15
+ cmp eax,6
+ jne L_dont_use_mmx
+ test edx,0800000h
+ jnz L_use_mmx
+ jmp L_dont_use_mmx
+L_use_mmx:
+ mov dword ptr [inflate_fast_use_mmx],2
+ jmp L_check_mmx_pop
+L_dont_use_mmx:
+ mov dword ptr [inflate_fast_use_mmx],3
+L_check_mmx_pop:
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ jmp L_check_mmx
+; 426 "inffast.S"
+ALIGN 4
+L_do_loop:
+; 437 "inffast.S"
+ cmp bl,15
+ ja L_get_length_code
+
+ xor eax,eax
+ lodsw
+ mov cl,bl
+ add bl,16
+ shl eax,cl
+ or ebp,eax
+
+L_get_length_code:
+ mov edx, [esp+0]
+ mov ecx, [esp+8]
+ and edx,ebp
+ mov eax, [ecx+edx*4]
+
+L_dolen:
+
+
+
+
+
+
+ mov cl,ah
+ sub bl,ah
+ shr ebp,cl
+
+
+
+
+
+
+ test al,al
+ jnz L_test_for_length_base
+
+ shr eax,16
+ stosb
+
+L_while_test:
+
+
+ cmp [esp+16],edi
+ jbe L_break_loop
+
+ cmp [esp+20],esi
+ ja L_do_loop
+ jmp L_break_loop
+
+L_test_for_length_base:
+; 502 "inffast.S"
+ mov edx,eax
+ shr edx,16
+ mov cl,al
+
+ test al,16
+ jz L_test_for_second_level_length
+ and cl,15
+ jz L_save_len
+ cmp bl,cl
+ jae L_add_bits_to_len
+
+ mov ch,cl
+ xor eax,eax
+ lodsw
+ mov cl,bl
+ add bl,16
+ shl eax,cl
+ or ebp,eax
+ mov cl,ch
+
+L_add_bits_to_len:
+ mov eax,1
+ shl eax,cl
+ dec eax
+ sub bl,cl
+ and eax,ebp
+ shr ebp,cl
+ add edx,eax
+
+L_save_len:
+ mov [esp+24],edx
+
+
+L_decode_distance:
+; 549 "inffast.S"
+ cmp bl,15
+ ja L_get_distance_code
+
+ xor eax,eax
+ lodsw
+ mov cl,bl
+ add bl,16
+ shl eax,cl
+ or ebp,eax
+
+L_get_distance_code:
+ mov edx, [esp+4]
+ mov ecx, [esp+12]
+ and edx,ebp
+ mov eax, [ecx+edx*4]
+
+
+L_dodist:
+ mov edx,eax
+ shr edx,16
+ mov cl,ah
+ sub bl,ah
+ shr ebp,cl
+; 584 "inffast.S"
+ mov cl,al
+
+ test al,16
+ jz L_test_for_second_level_dist
+ and cl,15
+ jz L_check_dist_one
+ cmp bl,cl
+ jae L_add_bits_to_dist
+
+ mov ch,cl
+ xor eax,eax
+ lodsw
+ mov cl,bl
+ add bl,16
+ shl eax,cl
+ or ebp,eax
+ mov cl,ch
+
+L_add_bits_to_dist:
+ mov eax,1
+ shl eax,cl
+ dec eax
+ sub bl,cl
+ and eax,ebp
+ shr ebp,cl
+ add edx,eax
+ jmp L_check_window
+
+L_check_window:
+; 625 "inffast.S"
+ mov [esp+44],esi
+ mov eax,edi
+ sub eax, [esp+40]
+
+ cmp eax,edx
+ jb L_clip_window
+
+ mov ecx, [esp+24]
+ mov esi,edi
+ sub esi,edx
+
+ sub ecx,3
+ mov al, [esi]
+ mov [edi],al
+ mov al, [esi+1]
+ mov dl, [esi+2]
+ add esi,3
+ mov [edi+1],al
+ mov [edi+2],dl
+ add edi,3
+ rep movsb
+
+ mov esi, [esp+44]
+ jmp L_while_test
+
+ALIGN 4
+L_check_dist_one:
+ cmp edx,1
+ jne L_check_window
+ cmp [esp+40],edi
+ je L_check_window
+
+ dec edi
+ mov ecx, [esp+24]
+ mov al, [edi]
+ sub ecx,3
+
+ mov [edi+1],al
+ mov [edi+2],al
+ mov [edi+3],al
+ add edi,4
+ rep stosb
+
+ jmp L_while_test
+
+ALIGN 4
+L_test_for_second_level_length:
+
+
+
+
+ test al,64
+ jnz L_test_for_end_of_block
+
+ mov eax,1
+ shl eax,cl
+ dec eax
+ and eax,ebp
+ add eax,edx
+ mov edx, [esp+8]
+ mov eax, [edx+eax*4]
+ jmp L_dolen
+
+ALIGN 4
+L_test_for_second_level_dist:
+
+
+
+
+ test al,64
+ jnz L_invalid_distance_code
+
+ mov eax,1
+ shl eax,cl
+ dec eax
+ and eax,ebp
+ add eax,edx
+ mov edx, [esp+12]
+ mov eax, [edx+eax*4]
+ jmp L_dodist
+
+ALIGN 4
+L_clip_window:
+; 721 "inffast.S"
+ mov ecx,eax
+ mov eax, [esp+52]
+ neg ecx
+ mov esi, [esp+56]
+
+ cmp eax,edx
+ jb L_invalid_distance_too_far
+
+ add ecx,edx
+ cmp dword ptr [esp+48],0
+ jne L_wrap_around_window
+
+ sub eax,ecx
+ add esi,eax
+; 749 "inffast.S"
+ mov eax, [esp+24]
+ cmp eax,ecx
+ jbe L_do_copy1
+
+ sub eax,ecx
+ rep movsb
+ mov esi,edi
+ sub esi,edx
+ jmp L_do_copy1
+
+ cmp eax,ecx
+ jbe L_do_copy1
+
+ sub eax,ecx
+ rep movsb
+ mov esi,edi
+ sub esi,edx
+ jmp L_do_copy1
+
+L_wrap_around_window:
+; 793 "inffast.S"
+ mov eax, [esp+48]
+ cmp ecx,eax
+ jbe L_contiguous_in_window
+
+ add esi, [esp+52]
+ add esi,eax
+ sub esi,ecx
+ sub ecx,eax
+
+
+ mov eax, [esp+24]
+ cmp eax,ecx
+ jbe L_do_copy1
+
+ sub eax,ecx
+ rep movsb
+ mov esi, [esp+56]
+ mov ecx, [esp+48]
+ cmp eax,ecx
+ jbe L_do_copy1
+
+ sub eax,ecx
+ rep movsb
+ mov esi,edi
+ sub esi,edx
+ jmp L_do_copy1
+
+L_contiguous_in_window:
+; 836 "inffast.S"
+ add esi,eax
+ sub esi,ecx
+
+
+ mov eax, [esp+24]
+ cmp eax,ecx
+ jbe L_do_copy1
+
+ sub eax,ecx
+ rep movsb
+ mov esi,edi
+ sub esi,edx
+
+L_do_copy1:
+; 862 "inffast.S"
+ mov ecx,eax
+ rep movsb
+
+ mov esi, [esp+44]
+ jmp L_while_test
+; 878 "inffast.S"
+ALIGN 4
+L_init_mmx:
+ emms
+
+
+
+
+
+ movd mm0,ebp
+ mov ebp,ebx
+; 896 "inffast.S"
+ movd mm4,dword ptr [esp+0]
+ movq mm3,mm4
+ movd mm5,dword ptr [esp+4]
+ movq mm2,mm5
+ pxor mm1,mm1
+ mov ebx, [esp+8]
+ jmp L_do_loop_mmx
+
+ALIGN 4
+L_do_loop_mmx:
+ psrlq mm0,mm1
+
+ cmp ebp,32
+ ja L_get_length_code_mmx
+
+ movd mm6,ebp
+ movd mm7,dword ptr [esi]
+ add esi,4
+ psllq mm7,mm6
+ add ebp,32
+ por mm0,mm7
+
+L_get_length_code_mmx:
+ pand mm4,mm0
+ movd eax,mm4
+ movq mm4,mm3
+ mov eax, [ebx+eax*4]
+
+L_dolen_mmx:
+ movzx ecx,ah
+ movd mm1,ecx
+ sub ebp,ecx
+
+ test al,al
+ jnz L_test_for_length_base_mmx
+
+ shr eax,16
+ stosb
+
+L_while_test_mmx:
+
+
+ cmp [esp+16],edi
+ jbe L_break_loop
+
+ cmp [esp+20],esi
+ ja L_do_loop_mmx
+ jmp L_break_loop
+
+L_test_for_length_base_mmx:
+
+ mov edx,eax
+ shr edx,16
+
+ test al,16
+ jz L_test_for_second_level_length_mmx
+ and eax,15
+ jz L_decode_distance_mmx
+
+ psrlq mm0,mm1
+ movd mm1,eax
+ movd ecx,mm0
+ sub ebp,eax
+ and ecx, [inflate_fast_mask+eax*4]
+ add edx,ecx
+
+L_decode_distance_mmx:
+ psrlq mm0,mm1
+
+ cmp ebp,32
+ ja L_get_dist_code_mmx
+
+ movd mm6,ebp
+ movd mm7,dword ptr [esi]
+ add esi,4
+ psllq mm7,mm6
+ add ebp,32
+ por mm0,mm7
+
+L_get_dist_code_mmx:
+ mov ebx, [esp+12]
+ pand mm5,mm0
+ movd eax,mm5
+ movq mm5,mm2
+ mov eax, [ebx+eax*4]
+
+L_dodist_mmx:
+
+ movzx ecx,ah
+ mov ebx,eax
+ shr ebx,16
+ sub ebp,ecx
+ movd mm1,ecx
+
+ test al,16
+ jz L_test_for_second_level_dist_mmx
+ and eax,15
+ jz L_check_dist_one_mmx
+
+L_add_bits_to_dist_mmx:
+ psrlq mm0,mm1
+ movd mm1,eax
+ movd ecx,mm0
+ sub ebp,eax
+ and ecx, [inflate_fast_mask+eax*4]
+ add ebx,ecx
+
+L_check_window_mmx:
+ mov [esp+44],esi
+ mov eax,edi
+ sub eax, [esp+40]
+
+ cmp eax,ebx
+ jb L_clip_window_mmx
+
+ mov ecx,edx
+ mov esi,edi
+ sub esi,ebx
+
+ sub ecx,3
+ mov al, [esi]
+ mov [edi],al
+ mov al, [esi+1]
+ mov dl, [esi+2]
+ add esi,3
+ mov [edi+1],al
+ mov [edi+2],dl
+ add edi,3
+ rep movsb
+
+ mov esi, [esp+44]
+ mov ebx, [esp+8]
+ jmp L_while_test_mmx
+
+ALIGN 4
+L_check_dist_one_mmx:
+ cmp ebx,1
+ jne L_check_window_mmx
+ cmp [esp+40],edi
+ je L_check_window_mmx
+
+ dec edi
+ mov ecx,edx
+ mov al, [edi]
+ sub ecx,3
+
+ mov [edi+1],al
+ mov [edi+2],al
+ mov [edi+3],al
+ add edi,4
+ rep stosb
+
+ mov ebx, [esp+8]
+ jmp L_while_test_mmx
+
+ALIGN 4
+L_test_for_second_level_length_mmx:
+ test al,64
+ jnz L_test_for_end_of_block
+
+ and eax,15
+ psrlq mm0,mm1
+ movd ecx,mm0
+ and ecx, [inflate_fast_mask+eax*4]
+ add ecx,edx
+ mov eax, [ebx+ecx*4]
+ jmp L_dolen_mmx
+
+ALIGN 4
+L_test_for_second_level_dist_mmx:
+ test al,64
+ jnz L_invalid_distance_code
+
+ and eax,15
+ psrlq mm0,mm1
+ movd ecx,mm0
+ and ecx, [inflate_fast_mask+eax*4]
+ mov eax, [esp+12]
+ add ecx,ebx
+ mov eax, [eax+ecx*4]
+ jmp L_dodist_mmx
+
+ALIGN 4
+L_clip_window_mmx:
+
+ mov ecx,eax
+ mov eax, [esp+52]
+ neg ecx
+ mov esi, [esp+56]
+
+ cmp eax,ebx
+ jb L_invalid_distance_too_far
+
+ add ecx,ebx
+ cmp dword ptr [esp+48],0
+ jne L_wrap_around_window_mmx
+
+ sub eax,ecx
+ add esi,eax
+
+ cmp edx,ecx
+ jbe L_do_copy1_mmx
+
+ sub edx,ecx
+ rep movsb
+ mov esi,edi
+ sub esi,ebx
+ jmp L_do_copy1_mmx
+
+ cmp edx,ecx
+ jbe L_do_copy1_mmx
+
+ sub edx,ecx
+ rep movsb
+ mov esi,edi
+ sub esi,ebx
+ jmp L_do_copy1_mmx
+
+L_wrap_around_window_mmx:
+
+ mov eax, [esp+48]
+ cmp ecx,eax
+ jbe L_contiguous_in_window_mmx
+
+ add esi, [esp+52]
+ add esi,eax
+ sub esi,ecx
+ sub ecx,eax
+
+
+ cmp edx,ecx
+ jbe L_do_copy1_mmx
+
+ sub edx,ecx
+ rep movsb
+ mov esi, [esp+56]
+ mov ecx, [esp+48]
+ cmp edx,ecx
+ jbe L_do_copy1_mmx
+
+ sub edx,ecx
+ rep movsb
+ mov esi,edi
+ sub esi,ebx
+ jmp L_do_copy1_mmx
+
+L_contiguous_in_window_mmx:
+
+ add esi,eax
+ sub esi,ecx
+
+
+ cmp edx,ecx
+ jbe L_do_copy1_mmx
+
+ sub edx,ecx
+ rep movsb
+ mov esi,edi
+ sub esi,ebx
+
+L_do_copy1_mmx:
+
+
+ mov ecx,edx
+ rep movsb
+
+ mov esi, [esp+44]
+ mov ebx, [esp+8]
+ jmp L_while_test_mmx
+; 1174 "inffast.S"
+L_invalid_distance_code:
+
+
+
+
+
+ mov ecx, invalid_distance_code_msg
+ mov edx,INFLATE_MODE_BAD
+ jmp L_update_stream_state
+
+L_test_for_end_of_block:
+
+
+
+
+
+ test al,32
+ jz L_invalid_literal_length_code
+
+ mov ecx,0
+ mov edx,INFLATE_MODE_TYPE
+ jmp L_update_stream_state
+
+L_invalid_literal_length_code:
+
+
+
+
+
+ mov ecx, invalid_literal_length_code_msg
+ mov edx,INFLATE_MODE_BAD
+ jmp L_update_stream_state
+
+L_invalid_distance_too_far:
+
+
+
+ mov esi, [esp+44]
+ mov ecx, invalid_distance_too_far_msg
+ mov edx,INFLATE_MODE_BAD
+ jmp L_update_stream_state
+
+L_update_stream_state:
+
+ mov eax, [esp+88]
+ test ecx,ecx
+ jz L_skip_msg
+ mov [eax+24],ecx
+L_skip_msg:
+ mov eax, [eax+28]
+ mov [eax+mode_state],edx
+ jmp L_break_loop
+
+ALIGN 4
+L_break_loop:
+; 1243 "inffast.S"
+ cmp dword ptr [inflate_fast_use_mmx],2
+ jne L_update_next_in
+
+
+
+ mov ebx,ebp
+
+L_update_next_in:
+; 1266 "inffast.S"
+ mov eax, [esp+88]
+ mov ecx,ebx
+ mov edx, [eax+28]
+ shr ecx,3
+ sub esi,ecx
+ shl ecx,3
+ sub ebx,ecx
+ mov [eax+12],edi
+ mov [edx+bits_state],ebx
+ mov ecx,ebx
+
+ lea ebx, [esp+28]
+ cmp [esp+20],ebx
+ jne L_buf_not_used
+
+ sub esi,ebx
+ mov ebx, [eax+0]
+ mov [esp+20],ebx
+ add esi,ebx
+ mov ebx, [eax+4]
+ sub ebx,11
+ add [esp+20],ebx
+
+L_buf_not_used:
+ mov [eax+0],esi
+
+ mov ebx,1
+ shl ebx,cl
+ dec ebx
+
+
+
+
+
+ cmp dword ptr [inflate_fast_use_mmx],2
+ jne L_update_hold
+
+
+
+ psrlq mm0,mm1
+ movd ebp,mm0
+
+ emms
+
+L_update_hold:
+
+
+
+ and ebp,ebx
+ mov [edx+hold_state],ebp
+
+
+
+
+ mov ebx, [esp+20]
+ cmp ebx,esi
+ jbe L_last_is_smaller
+
+ sub ebx,esi
+ add ebx,11
+ mov [eax+4],ebx
+ jmp L_fixup_out
+L_last_is_smaller:
+ sub esi,ebx
+ neg esi
+ add esi,11
+ mov [eax+4],esi
+
+
+
+
+L_fixup_out:
+
+ mov ebx, [esp+16]
+ cmp ebx,edi
+ jbe L_end_is_smaller
+
+ sub ebx,edi
+ add ebx,257
+ mov [eax+16],ebx
+ jmp L_done
+L_end_is_smaller:
+ sub edi,ebx
+ neg edi
+ add edi,257
+ mov [eax+16],edi
+
+
+
+
+
+L_done:
+ add esp,64
+ popfd
+ pop ebx
+ pop ebp
+ pop esi
+ pop edi
+ ret
+_inflate_fast endp
+
+_TEXT ends
+end
diff --git a/xs/src/png/zlib/contrib/masmx86/match686.asm b/xs/src/png/zlib/contrib/masmx86/match686.asm
new file mode 100644
index 000000000..69e0eed01
--- /dev/null
+++ b/xs/src/png/zlib/contrib/masmx86/match686.asm
@@ -0,0 +1,479 @@
+; match686.asm -- Asm portion of the optimized longest_match for 32 bits x86
+; Copyright (C) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+; File written by Gilles Vollant, by converting match686.S from Brian Raiter
+; for MASM. This is as assembly version of longest_match
+; from Jean-loup Gailly in deflate.c
+;
+; http://www.zlib.net
+; http://www.winimage.com/zLibDll
+; http://www.muppetlabs.com/~breadbox/software/assembly.html
+;
+; For Visual C++ 4.x and higher and ML 6.x and higher
+; ml.exe is distributed in
+; http://www.microsoft.com/downloads/details.aspx?FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64
+;
+; this file contain two implementation of longest_match
+;
+; this longest_match was written by Brian raiter (1998), optimized for Pentium Pro
+; (and the faster known version of match_init on modern Core 2 Duo and AMD Phenom)
+;
+; for using an assembly version of longest_match, you need define ASMV in project
+;
+; compile the asm file running
+; ml /coff /Zi /c /Flmatch686.lst match686.asm
+; and do not include match686.obj in your project
+;
+; note: contrib of zLib 1.2.3 and earlier contained both a deprecated version for
+; Pentium (prior Pentium Pro) and this version for Pentium Pro and modern processor
+; with autoselect (with cpu detection code)
+; if you want support the old pentium optimization, you can still use these version
+;
+; this file is not optimized for old pentium, but it compatible with all x86 32 bits
+; processor (starting 80386)
+;
+;
+; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2
+
+;uInt longest_match(s, cur_match)
+; deflate_state *s;
+; IPos cur_match; /* current match */
+
+ NbStack equ 76
+ cur_match equ dword ptr[esp+NbStack-0]
+ str_s equ dword ptr[esp+NbStack-4]
+; 5 dword on top (ret,ebp,esi,edi,ebx)
+ adrret equ dword ptr[esp+NbStack-8]
+ pushebp equ dword ptr[esp+NbStack-12]
+ pushedi equ dword ptr[esp+NbStack-16]
+ pushesi equ dword ptr[esp+NbStack-20]
+ pushebx equ dword ptr[esp+NbStack-24]
+
+ chain_length equ dword ptr [esp+NbStack-28]
+ limit equ dword ptr [esp+NbStack-32]
+ best_len equ dword ptr [esp+NbStack-36]
+ window equ dword ptr [esp+NbStack-40]
+ prev equ dword ptr [esp+NbStack-44]
+ scan_start equ word ptr [esp+NbStack-48]
+ wmask equ dword ptr [esp+NbStack-52]
+ match_start_ptr equ dword ptr [esp+NbStack-56]
+ nice_match equ dword ptr [esp+NbStack-60]
+ scan equ dword ptr [esp+NbStack-64]
+
+ windowlen equ dword ptr [esp+NbStack-68]
+ match_start equ dword ptr [esp+NbStack-72]
+ strend equ dword ptr [esp+NbStack-76]
+ NbStackAdd equ (NbStack-24)
+
+ .386p
+
+ name gvmatch
+ .MODEL FLAT
+
+
+
+; all the +zlib1222add offsets are due to the addition of fields
+; in zlib in the deflate_state structure since the asm code was first written
+; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+
+ zlib1222add equ 8
+
+; Note : these value are good with a 8 bytes boundary pack structure
+ dep_chain_length equ 74h+zlib1222add
+ dep_window equ 30h+zlib1222add
+ dep_strstart equ 64h+zlib1222add
+ dep_prev_length equ 70h+zlib1222add
+ dep_nice_match equ 88h+zlib1222add
+ dep_w_size equ 24h+zlib1222add
+ dep_prev equ 38h+zlib1222add
+ dep_w_mask equ 2ch+zlib1222add
+ dep_good_match equ 84h+zlib1222add
+ dep_match_start equ 68h+zlib1222add
+ dep_lookahead equ 6ch+zlib1222add
+
+
+_TEXT segment
+
+IFDEF NOUNDERLINE
+ public longest_match
+ public match_init
+ELSE
+ public _longest_match
+ public _match_init
+ENDIF
+
+ MAX_MATCH equ 258
+ MIN_MATCH equ 3
+ MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
+
+
+
+MAX_MATCH equ 258
+MIN_MATCH equ 3
+MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1)
+MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h)
+
+
+;;; stack frame offsets
+
+chainlenwmask equ esp + 0 ; high word: current chain len
+ ; low word: s->wmask
+window equ esp + 4 ; local copy of s->window
+windowbestlen equ esp + 8 ; s->window + bestlen
+scanstart equ esp + 16 ; first two bytes of string
+scanend equ esp + 12 ; last two bytes of string
+scanalign equ esp + 20 ; dword-misalignment of string
+nicematch equ esp + 24 ; a good enough match size
+bestlen equ esp + 28 ; size of best match so far
+scan equ esp + 32 ; ptr to string wanting match
+
+LocalVarsSize equ 36
+; saved ebx byte esp + 36
+; saved edi byte esp + 40
+; saved esi byte esp + 44
+; saved ebp byte esp + 48
+; return address byte esp + 52
+deflatestate equ esp + 56 ; the function arguments
+curmatch equ esp + 60
+
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+
+dsWSize equ 36+zlib1222add
+dsWMask equ 44+zlib1222add
+dsWindow equ 48+zlib1222add
+dsPrev equ 56+zlib1222add
+dsMatchLen equ 88+zlib1222add
+dsPrevMatch equ 92+zlib1222add
+dsStrStart equ 100+zlib1222add
+dsMatchStart equ 104+zlib1222add
+dsLookahead equ 108+zlib1222add
+dsPrevLen equ 112+zlib1222add
+dsMaxChainLen equ 116+zlib1222add
+dsGoodMatch equ 132+zlib1222add
+dsNiceMatch equ 136+zlib1222add
+
+
+;;; match686.asm -- Pentium-Pro-optimized version of longest_match()
+;;; Written for zlib 1.1.2
+;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
+;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html
+;;;
+;;
+;; This software is provided 'as-is', without any express or implied
+;; warranty. In no event will the authors be held liable for any damages
+;; arising from the use of this software.
+;;
+;; Permission is granted to anyone to use this software for any purpose,
+;; including commercial applications, and to alter it and redistribute it
+;; freely, subject to the following restrictions:
+;;
+;; 1. The origin of this software must not be misrepresented; you must not
+;; claim that you wrote the original software. If you use this software
+;; in a product, an acknowledgment in the product documentation would be
+;; appreciated but is not required.
+;; 2. Altered source versions must be plainly marked as such, and must not be
+;; misrepresented as being the original software
+;; 3. This notice may not be removed or altered from any source distribution.
+;;
+
+;GLOBAL _longest_match, _match_init
+
+
+;SECTION .text
+
+;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
+
+;_longest_match:
+ IFDEF NOUNDERLINE
+ longest_match proc near
+ ELSE
+ _longest_match proc near
+ ENDIF
+.FPO (9, 4, 0, 0, 1, 0)
+
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+
+ push ebp
+ push edi
+ push esi
+ push ebx
+ sub esp, LocalVarsSize
+
+;;; Retrieve the function arguments. ecx will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+
+ mov edx, [deflatestate]
+ mov ecx, [curmatch]
+
+;;; uInt wmask = s->w_mask;
+;;; unsigned chain_length = s->max_chain_length;
+;;; if (s->prev_length >= s->good_match) {
+;;; chain_length >>= 2;
+;;; }
+
+ mov eax, [edx + dsPrevLen]
+ mov ebx, [edx + dsGoodMatch]
+ cmp eax, ebx
+ mov eax, [edx + dsWMask]
+ mov ebx, [edx + dsMaxChainLen]
+ jl LastMatchGood
+ shr ebx, 2
+LastMatchGood:
+
+;;; chainlen is decremented once beforehand so that the function can
+;;; use the sign flag instead of the zero flag for the exit test.
+;;; It is then shifted into the high word, to make room for the wmask
+;;; value, which it will always accompany.
+
+ dec ebx
+ shl ebx, 16
+ or ebx, eax
+ mov [chainlenwmask], ebx
+
+;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+ mov eax, [edx + dsNiceMatch]
+ mov ebx, [edx + dsLookahead]
+ cmp ebx, eax
+ jl LookaheadLess
+ mov ebx, eax
+LookaheadLess: mov [nicematch], ebx
+
+;;; register Bytef *scan = s->window + s->strstart;
+
+ mov esi, [edx + dsWindow]
+ mov [window], esi
+ mov ebp, [edx + dsStrStart]
+ lea edi, [esi + ebp]
+ mov [scan], edi
+
+;;; Determine how many bytes the scan ptr is off from being
+;;; dword-aligned.
+
+ mov eax, edi
+ neg eax
+ and eax, 3
+ mov [scanalign], eax
+
+;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
+
+ mov eax, [edx + dsWSize]
+ sub eax, MIN_LOOKAHEAD
+ sub ebp, eax
+ jg LimitPositive
+ xor ebp, ebp
+LimitPositive:
+
+;;; int best_len = s->prev_length;
+
+ mov eax, [edx + dsPrevLen]
+ mov [bestlen], eax
+
+;;; Store the sum of s->window + best_len in esi locally, and in esi.
+
+ add esi, eax
+ mov [windowbestlen], esi
+
+;;; register ush scan_start = *(ushf*)scan;
+;;; register ush scan_end = *(ushf*)(scan+best_len-1);
+;;; Posf *prev = s->prev;
+
+ movzx ebx, word ptr [edi]
+ mov [scanstart], ebx
+ movzx ebx, word ptr [edi + eax - 1]
+ mov [scanend], ebx
+ mov edi, [edx + dsPrev]
+
+;;; Jump into the main loop.
+
+ mov edx, [chainlenwmask]
+ jmp short LoopEntry
+
+align 4
+
+;;; do {
+;;; match = s->window + cur_match;
+;;; if (*(ushf*)(match+best_len-1) != scan_end ||
+;;; *(ushf*)match != scan_start) continue;
+;;; [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;; && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;;
+;;; Within this loop:
+;;; ebx = scanend
+;;; ecx = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+
+LookupLoop:
+ and ecx, edx
+ movzx ecx, word ptr [edi + ecx*2]
+ cmp ecx, ebp
+ jbe LeaveNow
+ sub edx, 00010000h
+ js LeaveNow
+LoopEntry: movzx eax, word ptr [esi + ecx - 1]
+ cmp eax, ebx
+ jnz LookupLoop
+ mov eax, [window]
+ movzx eax, word ptr [eax + ecx]
+ cmp eax, [scanstart]
+ jnz LookupLoop
+
+;;; Store the current value of chainlen.
+
+ mov [chainlenwmask], edx
+
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+
+ mov esi, [window]
+ mov edi, [scan]
+ add esi, ecx
+ mov eax, [scanalign]
+ mov edx, 0fffffef8h; -(MAX_MATCH_8)
+ lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]
+ lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]
+
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust edx so that it is offset to the exact byte that mismatched.
+;;;
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (esi will still be misaligned three times out of four.)
+;;;
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+
+LoopCmps:
+ mov eax, [esi + edx]
+ xor eax, [edi + edx]
+ jnz LeaveLoopCmps
+ mov eax, [esi + edx + 4]
+ xor eax, [edi + edx + 4]
+ jnz LeaveLoopCmps4
+ add edx, 8
+ jnz LoopCmps
+ jmp short LenMaximum
+LeaveLoopCmps4: add edx, 4
+LeaveLoopCmps: test eax, 0000FFFFh
+ jnz LenLower
+ add edx, 2
+ shr eax, 16
+LenLower: sub al, 1
+ adc edx, 0
+
+;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+;;; then automatically accept it as the best possible match and leave.
+
+ lea eax, [edi + edx]
+ mov edi, [scan]
+ sub eax, edi
+ cmp eax, MAX_MATCH
+ jge LenMaximum
+
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+
+ mov edx, [deflatestate]
+ mov ebx, [bestlen]
+ cmp eax, ebx
+ jg LongerMatch
+ mov esi, [windowbestlen]
+ mov edi, [edx + dsPrev]
+ mov ebx, [scanend]
+ mov edx, [chainlenwmask]
+ jmp LookupLoop
+
+;;; s->match_start = cur_match;
+;;; best_len = len;
+;;; if (len >= nice_match) break;
+;;; scan_end = *(ushf*)(scan+best_len-1);
+
+LongerMatch: mov ebx, [nicematch]
+ mov [bestlen], eax
+ mov [edx + dsMatchStart], ecx
+ cmp eax, ebx
+ jge LeaveNow
+ mov esi, [window]
+ add esi, eax
+ mov [windowbestlen], esi
+ movzx ebx, word ptr [edi + eax - 1]
+ mov edi, [edx + dsPrev]
+ mov [scanend], ebx
+ mov edx, [chainlenwmask]
+ jmp LookupLoop
+
+;;; Accept the current string, with the maximum possible length.
+
+LenMaximum: mov edx, [deflatestate]
+ mov dword ptr [bestlen], MAX_MATCH
+ mov [edx + dsMatchStart], ecx
+
+;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+;;; return s->lookahead;
+
+LeaveNow:
+ mov edx, [deflatestate]
+ mov ebx, [bestlen]
+ mov eax, [edx + dsLookahead]
+ cmp ebx, eax
+ jg LookaheadRet
+ mov eax, ebx
+LookaheadRet:
+
+;;; Restore the stack and return from whence we came.
+
+ add esp, LocalVarsSize
+ pop ebx
+ pop esi
+ pop edi
+ pop ebp
+
+ ret
+; please don't remove this string !
+; Your can freely use match686 in any free or commercial app if you don't remove the string in the binary!
+ db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah
+
+
+ IFDEF NOUNDERLINE
+ longest_match endp
+ ELSE
+ _longest_match endp
+ ENDIF
+
+ IFDEF NOUNDERLINE
+ match_init proc near
+ ret
+ match_init endp
+ ELSE
+ _match_init proc near
+ ret
+ _match_init endp
+ ENDIF
+
+
+_TEXT ends
+end
diff --git a/xs/src/png/zlib/contrib/masmx86/readme.txt b/xs/src/png/zlib/contrib/masmx86/readme.txt
new file mode 100644
index 000000000..3f8888679
--- /dev/null
+++ b/xs/src/png/zlib/contrib/masmx86/readme.txt
@@ -0,0 +1,27 @@
+
+Summary
+-------
+This directory contains ASM implementations of the functions
+longest_match() and inflate_fast().
+
+
+Use instructions
+----------------
+Assemble using MASM, and copy the object files into the zlib source
+directory, then run the appropriate makefile, as suggested below. You can
+donwload MASM from here:
+
+ http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64
+
+You can also get objects files here:
+
+ http://www.winimage.com/zLibDll/zlib124_masm_obj.zip
+
+Build instructions
+------------------
+* With Microsoft C and MASM:
+nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj"
+
+* With Borland C and TASM:
+make -f win32/Makefile.bor LOCAL_ZLIB="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj" OBJPA="+match686c.obj+match686.obj+inffas32.obj"
+
diff --git a/xs/src/png/zlib/contrib/minizip/Makefile b/xs/src/png/zlib/contrib/minizip/Makefile
new file mode 100644
index 000000000..84eaad20d
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/Makefile
@@ -0,0 +1,25 @@
+CC=cc
+CFLAGS=-O -I../..
+
+UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a
+ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a
+
+.c.o:
+ $(CC) -c $(CFLAGS) $*.c
+
+all: miniunz minizip
+
+miniunz: $(UNZ_OBJS)
+ $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS)
+
+minizip: $(ZIP_OBJS)
+ $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)
+
+test: miniunz minizip
+ ./minizip test readme.txt
+ ./miniunz -l test.zip
+ mv readme.txt readme.old
+ ./miniunz test.zip
+
+clean:
+ /bin/rm -f *.o *~ minizip miniunz
diff --git a/xs/src/png/zlib/contrib/minizip/Makefile.am b/xs/src/png/zlib/contrib/minizip/Makefile.am
new file mode 100644
index 000000000..d343011eb
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/Makefile.am
@@ -0,0 +1,45 @@
+lib_LTLIBRARIES = libminizip.la
+
+if COND_DEMOS
+bin_PROGRAMS = miniunzip minizip
+endif
+
+zlib_top_srcdir = $(top_srcdir)/../..
+zlib_top_builddir = $(top_builddir)/../..
+
+AM_CPPFLAGS = -I$(zlib_top_srcdir)
+AM_LDFLAGS = -L$(zlib_top_builddir)
+
+if WIN32
+iowin32_src = iowin32.c
+iowin32_h = iowin32.h
+endif
+
+libminizip_la_SOURCES = \
+ ioapi.c \
+ mztools.c \
+ unzip.c \
+ zip.c \
+ ${iowin32_src}
+
+libminizip_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 -lz
+
+minizip_includedir = $(includedir)/minizip
+minizip_include_HEADERS = \
+ crypt.h \
+ ioapi.h \
+ mztools.h \
+ unzip.h \
+ zip.h \
+ ${iowin32_h}
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = minizip.pc
+
+EXTRA_PROGRAMS = miniunzip minizip
+
+miniunzip_SOURCES = miniunz.c
+miniunzip_LDADD = libminizip.la
+
+minizip_SOURCES = minizip.c
+minizip_LDADD = libminizip.la -lz
diff --git a/xs/src/png/zlib/contrib/minizip/MiniZip64_Changes.txt b/xs/src/png/zlib/contrib/minizip/MiniZip64_Changes.txt
new file mode 100644
index 000000000..13a1bd91a
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/MiniZip64_Changes.txt
@@ -0,0 +1,6 @@
+
+MiniZip 1.1 was derrived from MiniZip at version 1.01f
+
+Change in 1.0 (Okt 2009)
+ - **TODO - Add history**
+
diff --git a/xs/src/png/zlib/contrib/minizip/MiniZip64_info.txt b/xs/src/png/zlib/contrib/minizip/MiniZip64_info.txt
new file mode 100644
index 000000000..57d715242
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/MiniZip64_info.txt
@@ -0,0 +1,74 @@
+MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson
+
+Introduction
+---------------------
+MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html )
+
+When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0.
+All possible work was done for compatibility.
+
+
+Background
+---------------------
+When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64
+support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ )
+
+That was used as a starting point. And after that ZIP64 support was added to zip.c
+some refactoring and code cleanup was also done.
+
+
+Changed from MiniZip 1.0 to MiniZip 1.1
+---------------------------------------
+* Added ZIP64 support for unzip ( by Even Rouault )
+* Added ZIP64 support for zip ( by Mathias Svensson )
+* Reverted some changed that Even Rouault did.
+* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users.
+* Added unzip patch for BZIP Compression method (patch create by Daniel Borca)
+* Added BZIP Compress method for zip
+* Did some refactoring and code cleanup
+
+
+Credits
+
+ Gilles Vollant - Original MiniZip author
+ Even Rouault - ZIP64 unzip Support
+ Daniel Borca - BZip Compression method support in unzip
+ Mathias Svensson - ZIP64 zip support
+ Mathias Svensson - BZip Compression method support in zip
+
+ Resources
+
+ ZipLayout http://result42.com/projects/ZipFileLayout
+ Command line tool for Windows that shows the layout and information of the headers in a zip archive.
+ Used when debugging and validating the creation of zip files using MiniZip64
+
+
+ ZIP App Note http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+ Zip File specification
+
+
+Notes.
+ * To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined.
+
+License
+----------------------------------------------------------
+ Condition of use and distribution are the same than zlib :
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+----------------------------------------------------------
+
diff --git a/xs/src/png/zlib/contrib/minizip/configure.ac b/xs/src/png/zlib/contrib/minizip/configure.ac
new file mode 100644
index 000000000..5b1197097
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/configure.ac
@@ -0,0 +1,32 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_INIT([minizip], [1.2.11], [bugzilla.redhat.com])
+AC_CONFIG_SRCDIR([minizip.c])
+AM_INIT_AUTOMAKE([foreign])
+LT_INIT
+
+AC_MSG_CHECKING([whether to build example programs])
+AC_ARG_ENABLE([demos], AC_HELP_STRING([--enable-demos], [build example programs]))
+AM_CONDITIONAL([COND_DEMOS], [test "$enable_demos" = yes])
+if test "$enable_demos" = yes
+then
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
+case "${host}" in
+ *-mingw* | mingw*)
+ WIN32="yes"
+ ;;
+ *)
+ ;;
+esac
+AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
+
+
+AC_SUBST([HAVE_UNISTD_H], [0])
+AC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], [])
+AC_CONFIG_FILES([Makefile minizip.pc])
+AC_OUTPUT
diff --git a/xs/src/png/zlib/contrib/minizip/crypt.h b/xs/src/png/zlib/contrib/minizip/crypt.h
new file mode 100644
index 000000000..1e9e8200b
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/crypt.h
@@ -0,0 +1,131 @@
+/* crypt.h -- base code for crypt/uncrypt ZIPfile
+
+
+ Version 1.01e, February 12th, 2005
+
+ Copyright (C) 1998-2005 Gilles Vollant
+
+ This code is a modified version of crypting code in Infozip distribution
+
+ The encryption/decryption parts of this source code (as opposed to the
+ non-echoing password parts) were originally written in Europe. The
+ whole source package can be freely distributed, including from the USA.
+ (Prior to January 2000, re-export from the US was a violation of US law.)
+
+ This encryption code is a direct transcription of the algorithm from
+ Roger Schlafly, described by Phil Katz in the file appnote.txt. This
+ file (appnote.txt) is distributed with the PKZIP program (even in the
+ version without encryption capabilities).
+
+ If you don't need crypting in your application, just define symbols
+ NOCRYPT and NOUNCRYPT.
+
+ This code support the "Traditional PKWARE Encryption".
+
+ The new AES encryption added on Zip format by Winzip (see the page
+ http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
+ Encryption is not supported.
+*/
+
+#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
+
+/***********************************************************************
+ * Return the next byte in the pseudo-random sequence
+ */
+static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
+{
+ unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
+ * unpredictable manner on 16-bit systems; not a problem
+ * with any known compiler so far, though */
+
+ temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
+ return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
+}
+
+/***********************************************************************
+ * Update the encryption keys with the next byte of plain text
+ */
+static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
+{
+ (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
+ (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
+ (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
+ {
+ register int keyshift = (int)((*(pkeys+1)) >> 24);
+ (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
+ }
+ return c;
+}
+
+
+/***********************************************************************
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ */
+static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
+{
+ *(pkeys+0) = 305419896L;
+ *(pkeys+1) = 591751049L;
+ *(pkeys+2) = 878082192L;
+ while (*passwd != '\0') {
+ update_keys(pkeys,pcrc_32_tab,(int)*passwd);
+ passwd++;
+ }
+}
+
+#define zdecode(pkeys,pcrc_32_tab,c) \
+ (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
+
+#define zencode(pkeys,pcrc_32_tab,c,t) \
+ (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
+
+#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+
+#define RAND_HEAD_LEN 12
+ /* "last resort" source for second part of crypt seed pattern */
+# ifndef ZCR_SEED2
+# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
+# endif
+
+static int crypthead(const char* passwd, /* password string */
+ unsigned char* buf, /* where to write header */
+ int bufSize,
+ unsigned long* pkeys,
+ const z_crc_t* pcrc_32_tab,
+ unsigned long crcForCrypting)
+{
+ int n; /* index in random header */
+ int t; /* temporary */
+ int c; /* random byte */
+ unsigned char header[RAND_HEAD_LEN-2]; /* random header */
+ static unsigned calls = 0; /* ensure different random header each time */
+
+ if (bufSize<RAND_HEAD_LEN)
+ return 0;
+
+ /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
+ * output of rand() to get less predictability, since rand() is
+ * often poorly implemented.
+ */
+ if (++calls == 1)
+ {
+ srand((unsigned)(time(NULL) ^ ZCR_SEED2));
+ }
+ init_keys(passwd, pkeys, pcrc_32_tab);
+ for (n = 0; n < RAND_HEAD_LEN-2; n++)
+ {
+ c = (rand() >> 7) & 0xff;
+ header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
+ }
+ /* Encrypt random header (last two bytes is high word of crc) */
+ init_keys(passwd, pkeys, pcrc_32_tab);
+ for (n = 0; n < RAND_HEAD_LEN-2; n++)
+ {
+ buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
+ }
+ buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
+ buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
+ return n;
+}
+
+#endif
diff --git a/xs/src/png/zlib/contrib/minizip/ioapi.c b/xs/src/png/zlib/contrib/minizip/ioapi.c
new file mode 100644
index 000000000..7f5c191b2
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/ioapi.c
@@ -0,0 +1,247 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+*/
+
+#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS)))
+ #define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#if defined(__APPLE__) || defined(IOAPI_NO_64)
+// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
+#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
+#define FTELLO_FUNC(stream) ftello(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
+#else
+#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
+#define FTELLO_FUNC(stream) ftello64(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
+#endif
+
+
+#include "ioapi.h"
+
+voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
+{
+ if (pfilefunc->zfile_func64.zopen64_file != NULL)
+ return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
+ else
+ {
+ return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
+ }
+}
+
+long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
+{
+ if (pfilefunc->zfile_func64.zseek64_file != NULL)
+ return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
+ else
+ {
+ uLong offsetTruncated = (uLong)offset;
+ if (offsetTruncated != offset)
+ return -1;
+ else
+ return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
+ }
+}
+
+ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
+{
+ if (pfilefunc->zfile_func64.zseek64_file != NULL)
+ return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
+ else
+ {
+ uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
+ if ((tell_uLong) == MAXU32)
+ return (ZPOS64_T)-1;
+ else
+ return tell_uLong;
+ }
+}
+
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
+{
+ p_filefunc64_32->zfile_func64.zopen64_file = NULL;
+ p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
+ p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+ p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
+ p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
+ p_filefunc64_32->zfile_func64.ztell64_file = NULL;
+ p_filefunc64_32->zfile_func64.zseek64_file = NULL;
+ p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
+ p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+ p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
+ p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
+ p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
+}
+
+
+
+static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
+static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
+static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
+static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
+static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
+
+static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
+{
+ FILE* file = NULL;
+ const char* mode_fopen = NULL;
+ if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+ mode_fopen = "rb";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+ mode_fopen = "r+b";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+ mode_fopen = "wb";
+
+ if ((filename!=NULL) && (mode_fopen != NULL))
+ file = fopen(filename, mode_fopen);
+ return file;
+}
+
+static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
+{
+ FILE* file = NULL;
+ const char* mode_fopen = NULL;
+ if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+ mode_fopen = "rb";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+ mode_fopen = "r+b";
+ else
+ if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+ mode_fopen = "wb";
+
+ if ((filename!=NULL) && (mode_fopen != NULL))
+ file = FOPEN_FUNC((const char*)filename, mode_fopen);
+ return file;
+}
+
+
+static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
+{
+ uLong ret;
+ ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
+ return ret;
+}
+
+static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
+{
+ uLong ret;
+ ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
+ return ret;
+}
+
+static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
+{
+ long ret;
+ ret = ftell((FILE *)stream);
+ return ret;
+}
+
+
+static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
+{
+ ZPOS64_T ret;
+ ret = FTELLO_FUNC((FILE *)stream);
+ return ret;
+}
+
+static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
+{
+ int fseek_origin=0;
+ long ret;
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ fseek_origin = SEEK_CUR;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ fseek_origin = SEEK_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ fseek_origin = SEEK_SET;
+ break;
+ default: return -1;
+ }
+ ret = 0;
+ if (fseek((FILE *)stream, offset, fseek_origin) != 0)
+ ret = -1;
+ return ret;
+}
+
+static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
+{
+ int fseek_origin=0;
+ long ret;
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ fseek_origin = SEEK_CUR;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ fseek_origin = SEEK_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ fseek_origin = SEEK_SET;
+ break;
+ default: return -1;
+ }
+ ret = 0;
+
+ if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0)
+ ret = -1;
+
+ return ret;
+}
+
+
+static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
+{
+ int ret;
+ ret = fclose((FILE *)stream);
+ return ret;
+}
+
+static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
+{
+ int ret;
+ ret = ferror((FILE *)stream);
+ return ret;
+}
+
+void fill_fopen_filefunc (pzlib_filefunc_def)
+ zlib_filefunc_def* pzlib_filefunc_def;
+{
+ pzlib_filefunc_def->zopen_file = fopen_file_func;
+ pzlib_filefunc_def->zread_file = fread_file_func;
+ pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+ pzlib_filefunc_def->ztell_file = ftell_file_func;
+ pzlib_filefunc_def->zseek_file = fseek_file_func;
+ pzlib_filefunc_def->zclose_file = fclose_file_func;
+ pzlib_filefunc_def->zerror_file = ferror_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
+
+void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen64_file = fopen64_file_func;
+ pzlib_filefunc_def->zread_file = fread_file_func;
+ pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+ pzlib_filefunc_def->ztell64_file = ftell64_file_func;
+ pzlib_filefunc_def->zseek64_file = fseek64_file_func;
+ pzlib_filefunc_def->zclose_file = fclose_file_func;
+ pzlib_filefunc_def->zerror_file = ferror_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
diff --git a/xs/src/png/zlib/contrib/minizip/ioapi.h b/xs/src/png/zlib/contrib/minizip/ioapi.h
new file mode 100644
index 000000000..8dcbdb06e
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/ioapi.h
@@ -0,0 +1,208 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ Changes
+
+ Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
+ Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
+ More if/def section may be needed to support other platforms
+ Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
+ (but you should use iowin32.c for windows instead)
+
+*/
+
+#ifndef _ZLIBIOAPI64_H
+#define _ZLIBIOAPI64_H
+
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
+
+ // Linux needs this to support file operation on files larger then 4+GB
+ // But might need better if/def to select just the platforms that needs them.
+
+ #ifndef __USE_FILE_OFFSET64
+ #define __USE_FILE_OFFSET64
+ #endif
+ #ifndef __USE_LARGEFILE64
+ #define __USE_LARGEFILE64
+ #endif
+ #ifndef _LARGEFILE64_SOURCE
+ #define _LARGEFILE64_SOURCE
+ #endif
+ #ifndef _FILE_OFFSET_BIT
+ #define _FILE_OFFSET_BIT 64
+ #endif
+
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "zlib.h"
+
+#if defined(USE_FILE32API)
+#define fopen64 fopen
+#define ftello64 ftell
+#define fseeko64 fseek
+#else
+#ifdef __FreeBSD__
+#define fopen64 fopen
+#define ftello64 ftello
+#define fseeko64 fseeko
+#endif
+#ifdef _MSC_VER
+ #define fopen64 fopen
+ #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
+ #define ftello64 _ftelli64
+ #define fseeko64 _fseeki64
+ #else // old MSC
+ #define ftello64 ftell
+ #define fseeko64 fseek
+ #endif
+#endif
+#endif
+
+/*
+#ifndef ZPOS64_T
+ #ifdef _WIN32
+ #define ZPOS64_T fpos_t
+ #else
+ #include <stdint.h>
+ #define ZPOS64_T uint64_t
+ #endif
+#endif
+*/
+
+#ifdef HAVE_MINIZIP64_CONF_H
+#include "mz64conf.h"
+#endif
+
+/* a type choosen by DEFINE */
+#ifdef HAVE_64BIT_INT_CUSTOM
+typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
+#else
+#ifdef HAS_STDINT_H
+#include "stdint.h"
+typedef uint64_t ZPOS64_T;
+#else
+
+/* Maximum unsigned 32-bit value used as placeholder for zip64 */
+#define MAXU32 0xffffffff
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 ZPOS64_T;
+#else
+typedef unsigned long long int ZPOS64_T;
+#endif
+#endif
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define ZLIB_FILEFUNC_SEEK_CUR (1)
+#define ZLIB_FILEFUNC_SEEK_END (2)
+#define ZLIB_FILEFUNC_SEEK_SET (0)
+
+#define ZLIB_FILEFUNC_MODE_READ (1)
+#define ZLIB_FILEFUNC_MODE_WRITE (2)
+#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
+
+#define ZLIB_FILEFUNC_MODE_EXISTING (4)
+#define ZLIB_FILEFUNC_MODE_CREATE (8)
+
+
+#ifndef ZCALLBACK
+ #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
+ #define ZCALLBACK CALLBACK
+ #else
+ #define ZCALLBACK
+ #endif
+#endif
+
+
+
+
+typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
+typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
+typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+
+typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
+typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
+
+
+/* here is the "old" 32 bits structure structure */
+typedef struct zlib_filefunc_def_s
+{
+ open_file_func zopen_file;
+ read_file_func zread_file;
+ write_file_func zwrite_file;
+ tell_file_func ztell_file;
+ seek_file_func zseek_file;
+ close_file_func zclose_file;
+ testerror_file_func zerror_file;
+ voidpf opaque;
+} zlib_filefunc_def;
+
+typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
+typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode));
+
+typedef struct zlib_filefunc64_def_s
+{
+ open64_file_func zopen64_file;
+ read_file_func zread_file;
+ write_file_func zwrite_file;
+ tell64_file_func ztell64_file;
+ seek64_file_func zseek64_file;
+ close_file_func zclose_file;
+ testerror_file_func zerror_file;
+ voidpf opaque;
+} zlib_filefunc64_def;
+
+void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+
+/* now internal definition, only for zip.c and unzip.h */
+typedef struct zlib_filefunc64_32_def_s
+{
+ zlib_filefunc64_def zfile_func64;
+ open_file_func zopen32_file;
+ tell_file_func ztell32_file;
+ seek_file_func zseek32_file;
+} zlib_filefunc64_32_def;
+
+
+#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
+#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
+//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
+//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
+#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
+#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
+
+voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
+long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
+ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
+
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
+
+#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
+#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
+#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/xs/src/png/zlib/contrib/minizip/iowin32.c b/xs/src/png/zlib/contrib/minizip/iowin32.c
new file mode 100644
index 000000000..274f39eb1
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/iowin32.c
@@ -0,0 +1,462 @@
+/* iowin32.c -- IO base function header for compress/uncompress .zip
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+*/
+
+#include <stdlib.h>
+
+#include "zlib.h"
+#include "ioapi.h"
+#include "iowin32.h"
+
+#ifndef INVALID_HANDLE_VALUE
+#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
+#endif
+
+#ifndef INVALID_SET_FILE_POINTER
+#define INVALID_SET_FILE_POINTER ((DWORD)-1)
+#endif
+
+
+// see Include/shared/winapifamily.h in the Windows Kit
+#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API)))
+#if WINAPI_FAMILY_ONE_PARTITION(WINAPI_FAMILY, WINAPI_PARTITION_APP)
+#define IOWIN32_USING_WINRT_API 1
+#endif
+#endif
+
+voidpf ZCALLBACK win32_open_file_func OF((voidpf opaque, const char* filename, int mode));
+uLong ZCALLBACK win32_read_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+uLong ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+ZPOS64_T ZCALLBACK win32_tell64_file_func OF((voidpf opaque, voidpf stream));
+long ZCALLBACK win32_seek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+int ZCALLBACK win32_close_file_func OF((voidpf opaque, voidpf stream));
+int ZCALLBACK win32_error_file_func OF((voidpf opaque, voidpf stream));
+
+typedef struct
+{
+ HANDLE hf;
+ int error;
+} WIN32FILE_IOWIN;
+
+
+static void win32_translate_open_mode(int mode,
+ DWORD* lpdwDesiredAccess,
+ DWORD* lpdwCreationDisposition,
+ DWORD* lpdwShareMode,
+ DWORD* lpdwFlagsAndAttributes)
+{
+ *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0;
+
+ if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+ {
+ *lpdwDesiredAccess = GENERIC_READ;
+ *lpdwCreationDisposition = OPEN_EXISTING;
+ *lpdwShareMode = FILE_SHARE_READ;
+ }
+ else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+ {
+ *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
+ *lpdwCreationDisposition = OPEN_EXISTING;
+ }
+ else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+ {
+ *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
+ *lpdwCreationDisposition = CREATE_ALWAYS;
+ }
+}
+
+static voidpf win32_build_iowin(HANDLE hFile)
+{
+ voidpf ret=NULL;
+
+ if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
+ {
+ WIN32FILE_IOWIN w32fiow;
+ w32fiow.hf = hFile;
+ w32fiow.error = 0;
+ ret = malloc(sizeof(WIN32FILE_IOWIN));
+
+ if (ret==NULL)
+ CloseHandle(hFile);
+ else
+ *((WIN32FILE_IOWIN*)ret) = w32fiow;
+ }
+ return ret;
+}
+
+voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode)
+{
+ const char* mode_fopen = NULL;
+ DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+ HANDLE hFile = NULL;
+
+ win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+#ifdef IOWIN32_USING_WINRT_API
+#ifdef UNICODE
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+#else
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ {
+ WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
+ MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
+ hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+ }
+#endif
+#else
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
+
+ return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int mode)
+{
+ const char* mode_fopen = NULL;
+ DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+ HANDLE hFile = NULL;
+
+ win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+#ifdef IOWIN32_USING_WINRT_API
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ {
+ WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
+ MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
+ hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+ }
+#else
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
+
+ return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int mode)
+{
+ const char* mode_fopen = NULL;
+ DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+ HANDLE hFile = NULL;
+
+ win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+#ifdef IOWIN32_USING_WINRT_API
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFile2((LPCWSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition,NULL);
+#else
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
+
+ return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode)
+{
+ const char* mode_fopen = NULL;
+ DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+ HANDLE hFile = NULL;
+
+ win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+#ifdef IOWIN32_USING_WINRT_API
+#ifdef UNICODE
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+#else
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ {
+ WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
+ MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
+ hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+ }
+#endif
+#else
+ if ((filename!=NULL) && (dwDesiredAccess != 0))
+ hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
+
+ return win32_build_iowin(hFile);
+}
+
+
+uLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size)
+{
+ uLong ret=0;
+ HANDLE hFile = NULL;
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+
+ if (hFile != NULL)
+ {
+ if (!ReadFile(hFile, buf, size, &ret, NULL))
+ {
+ DWORD dwErr = GetLastError();
+ if (dwErr == ERROR_HANDLE_EOF)
+ dwErr = 0;
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ }
+ }
+
+ return ret;
+}
+
+
+uLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* buf,uLong size)
+{
+ uLong ret=0;
+ HANDLE hFile = NULL;
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+
+ if (hFile != NULL)
+ {
+ if (!WriteFile(hFile, buf, size, &ret, NULL))
+ {
+ DWORD dwErr = GetLastError();
+ if (dwErr == ERROR_HANDLE_EOF)
+ dwErr = 0;
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ }
+ }
+
+ return ret;
+}
+
+static BOOL MySetFilePointerEx(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos, DWORD dwMoveMethod)
+{
+#ifdef IOWIN32_USING_WINRT_API
+ return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod);
+#else
+ LONG lHigh = pos.HighPart;
+ DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, dwMoveMethod);
+ BOOL fOk = TRUE;
+ if (dwNewPos == 0xFFFFFFFF)
+ if (GetLastError() != NO_ERROR)
+ fOk = FALSE;
+ if ((newPos != NULL) && (fOk))
+ {
+ newPos->LowPart = dwNewPos;
+ newPos->HighPart = lHigh;
+ }
+ return fOk;
+#endif
+}
+
+long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream)
+{
+ long ret=-1;
+ HANDLE hFile = NULL;
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+ if (hFile != NULL)
+ {
+ LARGE_INTEGER pos;
+ pos.QuadPart = 0;
+
+ if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
+ {
+ DWORD dwErr = GetLastError();
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ ret = -1;
+ }
+ else
+ ret=(long)pos.LowPart;
+ }
+ return ret;
+}
+
+ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream)
+{
+ ZPOS64_T ret= (ZPOS64_T)-1;
+ HANDLE hFile = NULL;
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream)->hf;
+
+ if (hFile)
+ {
+ LARGE_INTEGER pos;
+ pos.QuadPart = 0;
+
+ if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
+ {
+ DWORD dwErr = GetLastError();
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ ret = (ZPOS64_T)-1;
+ }
+ else
+ ret=pos.QuadPart;
+ }
+ return ret;
+}
+
+
+long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,int origin)
+{
+ DWORD dwMoveMethod=0xFFFFFFFF;
+ HANDLE hFile = NULL;
+
+ long ret=-1;
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ dwMoveMethod = FILE_CURRENT;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ dwMoveMethod = FILE_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ dwMoveMethod = FILE_BEGIN;
+ break;
+ default: return -1;
+ }
+
+ if (hFile != NULL)
+ {
+ LARGE_INTEGER pos;
+ pos.QuadPart = offset;
+ if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod))
+ {
+ DWORD dwErr = GetLastError();
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ ret = -1;
+ }
+ else
+ ret=0;
+ }
+ return ret;
+}
+
+long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T offset,int origin)
+{
+ DWORD dwMoveMethod=0xFFFFFFFF;
+ HANDLE hFile = NULL;
+ long ret=-1;
+
+ if (stream!=NULL)
+ hFile = ((WIN32FILE_IOWIN*)stream)->hf;
+
+ switch (origin)
+ {
+ case ZLIB_FILEFUNC_SEEK_CUR :
+ dwMoveMethod = FILE_CURRENT;
+ break;
+ case ZLIB_FILEFUNC_SEEK_END :
+ dwMoveMethod = FILE_END;
+ break;
+ case ZLIB_FILEFUNC_SEEK_SET :
+ dwMoveMethod = FILE_BEGIN;
+ break;
+ default: return -1;
+ }
+
+ if (hFile)
+ {
+ LARGE_INTEGER pos;
+ pos.QuadPart = offset;
+ if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod))
+ {
+ DWORD dwErr = GetLastError();
+ ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+ ret = -1;
+ }
+ else
+ ret=0;
+ }
+ return ret;
+}
+
+int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream)
+{
+ int ret=-1;
+
+ if (stream!=NULL)
+ {
+ HANDLE hFile;
+ hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+ if (hFile != NULL)
+ {
+ CloseHandle(hFile);
+ ret=0;
+ }
+ free(stream);
+ }
+ return ret;
+}
+
+int ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream)
+{
+ int ret=-1;
+ if (stream!=NULL)
+ {
+ ret = ((WIN32FILE_IOWIN*)stream) -> error;
+ }
+ return ret;
+}
+
+void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen_file = win32_open_file_func;
+ pzlib_filefunc_def->zread_file = win32_read_file_func;
+ pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+ pzlib_filefunc_def->ztell_file = win32_tell_file_func;
+ pzlib_filefunc_def->zseek_file = win32_seek_file_func;
+ pzlib_filefunc_def->zclose_file = win32_close_file_func;
+ pzlib_filefunc_def->zerror_file = win32_error_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
+
+void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen64_file = win32_open64_file_func;
+ pzlib_filefunc_def->zread_file = win32_read_file_func;
+ pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+ pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+ pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+ pzlib_filefunc_def->zclose_file = win32_close_file_func;
+ pzlib_filefunc_def->zerror_file = win32_error_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
+
+
+void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;
+ pzlib_filefunc_def->zread_file = win32_read_file_func;
+ pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+ pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+ pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+ pzlib_filefunc_def->zclose_file = win32_close_file_func;
+ pzlib_filefunc_def->zerror_file = win32_error_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
+
+
+void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW;
+ pzlib_filefunc_def->zread_file = win32_read_file_func;
+ pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+ pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+ pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+ pzlib_filefunc_def->zclose_file = win32_close_file_func;
+ pzlib_filefunc_def->zerror_file = win32_error_file_func;
+ pzlib_filefunc_def->opaque = NULL;
+}
diff --git a/xs/src/png/zlib/contrib/minizip/iowin32.h b/xs/src/png/zlib/contrib/minizip/iowin32.h
new file mode 100644
index 000000000..0ca0969a7
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/iowin32.h
@@ -0,0 +1,28 @@
+/* iowin32.h -- IO base function header for compress/uncompress .zip
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+*/
+
+#include <windows.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+void fill_win32_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_win32_filefunc64A OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_win32_filefunc64W OF((zlib_filefunc64_def* pzlib_filefunc_def));
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/xs/src/png/zlib/contrib/minizip/make_vms.com b/xs/src/png/zlib/contrib/minizip/make_vms.com
new file mode 100644
index 000000000..9ac13a98f
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/make_vms.com
@@ -0,0 +1,25 @@
+$ if f$search("ioapi.h_orig") .eqs. "" then copy ioapi.h ioapi.h_orig
+$ open/write zdef vmsdefs.h
+$ copy sys$input: zdef
+$ deck
+#define unix
+#define fill_zlib_filefunc64_32_def_from_filefunc32 fillzffunc64from
+#define Write_Zip64EndOfCentralDirectoryLocator Write_Zip64EoDLocator
+#define Write_Zip64EndOfCentralDirectoryRecord Write_Zip64EoDRecord
+#define Write_EndOfCentralDirectoryRecord Write_EoDRecord
+$ eod
+$ close zdef
+$ copy vmsdefs.h,ioapi.h_orig ioapi.h
+$ cc/include=[--]/prefix=all ioapi.c
+$ cc/include=[--]/prefix=all miniunz.c
+$ cc/include=[--]/prefix=all unzip.c
+$ cc/include=[--]/prefix=all minizip.c
+$ cc/include=[--]/prefix=all zip.c
+$ link miniunz,unzip,ioapi,[--]libz.olb/lib
+$ link minizip,zip,ioapi,[--]libz.olb/lib
+$ mcr []minizip test minizip_info.txt
+$ mcr []miniunz -l test.zip
+$ rename minizip_info.txt; minizip_info.txt_old
+$ mcr []miniunz test.zip
+$ delete test.zip;*
+$exit
diff --git a/xs/src/png/zlib/contrib/minizip/miniunz.c b/xs/src/png/zlib/contrib/minizip/miniunz.c
new file mode 100644
index 000000000..3d65401be
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/miniunz.c
@@ -0,0 +1,660 @@
+/*
+ miniunz.c
+ Version 1.1, February 14h, 2010
+ sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+*/
+
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
+ #ifndef __USE_FILE_OFFSET64
+ #define __USE_FILE_OFFSET64
+ #endif
+ #ifndef __USE_LARGEFILE64
+ #define __USE_LARGEFILE64
+ #endif
+ #ifndef _LARGEFILE64_SOURCE
+ #define _LARGEFILE64_SOURCE
+ #endif
+ #ifndef _FILE_OFFSET_BIT
+ #define _FILE_OFFSET_BIT 64
+ #endif
+#endif
+
+#ifdef __APPLE__
+// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
+#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
+#define FTELLO_FUNC(stream) ftello(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
+#else
+#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
+#define FTELLO_FUNC(stream) ftello64(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifdef _WIN32
+# include <direct.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <utime.h>
+#endif
+
+
+#include "unzip.h"
+
+#define CASESENSITIVITY (0)
+#define WRITEBUFFERSIZE (8192)
+#define MAXFILENAME (256)
+
+#ifdef _WIN32
+#define USEWIN32IOAPI
+#include "iowin32.h"
+#endif
+/*
+ mini unzip, demo of unzip package
+
+ usage :
+ Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
+
+ list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
+ if it exists
+*/
+
+
+/* change_file_date : change the date/time of a file
+ filename : the filename of the file where date/time must be modified
+ dosdate : the new date at the MSDos format (4 bytes)
+ tmu_date : the SAME new date at the tm_unz format */
+void change_file_date(filename,dosdate,tmu_date)
+ const char *filename;
+ uLong dosdate;
+ tm_unz tmu_date;
+{
+#ifdef _WIN32
+ HANDLE hFile;
+ FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
+
+ hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
+ 0,NULL,OPEN_EXISTING,0,NULL);
+ GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
+ DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
+ LocalFileTimeToFileTime(&ftLocal,&ftm);
+ SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
+ CloseHandle(hFile);
+#else
+#ifdef unix || __APPLE__
+ struct utimbuf ut;
+ struct tm newdate;
+ newdate.tm_sec = tmu_date.tm_sec;
+ newdate.tm_min=tmu_date.tm_min;
+ newdate.tm_hour=tmu_date.tm_hour;
+ newdate.tm_mday=tmu_date.tm_mday;
+ newdate.tm_mon=tmu_date.tm_mon;
+ if (tmu_date.tm_year > 1900)
+ newdate.tm_year=tmu_date.tm_year - 1900;
+ else
+ newdate.tm_year=tmu_date.tm_year ;
+ newdate.tm_isdst=-1;
+
+ ut.actime=ut.modtime=mktime(&newdate);
+ utime(filename,&ut);
+#endif
+#endif
+}
+
+
+/* mymkdir and change_file_date are not 100 % portable
+ As I don't know well Unix, I wait feedback for the unix portion */
+
+int mymkdir(dirname)
+ const char* dirname;
+{
+ int ret=0;
+#ifdef _WIN32
+ ret = _mkdir(dirname);
+#elif unix
+ ret = mkdir (dirname,0775);
+#elif __APPLE__
+ ret = mkdir (dirname,0775);
+#endif
+ return ret;
+}
+
+int makedir (newdir)
+ char *newdir;
+{
+ char *buffer ;
+ char *p;
+ int len = (int)strlen(newdir);
+
+ if (len <= 0)
+ return 0;
+
+ buffer = (char*)malloc(len+1);
+ if (buffer==NULL)
+ {
+ printf("Error allocating memory\n");
+ return UNZ_INTERNALERROR;
+ }
+ strcpy(buffer,newdir);
+
+ if (buffer[len-1] == '/') {
+ buffer[len-1] = '\0';
+ }
+ if (mymkdir(buffer) == 0)
+ {
+ free(buffer);
+ return 1;
+ }
+
+ p = buffer+1;
+ while (1)
+ {
+ char hold;
+
+ while(*p && *p != '\\' && *p != '/')
+ p++;
+ hold = *p;
+ *p = 0;
+ if ((mymkdir(buffer) == -1) && (errno == ENOENT))
+ {
+ printf("couldn't create directory %s\n",buffer);
+ free(buffer);
+ return 0;
+ }
+ if (hold == 0)
+ break;
+ *p++ = hold;
+ }
+ free(buffer);
+ return 1;
+}
+
+void do_banner()
+{
+ printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
+ printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
+}
+
+void do_help()
+{
+ printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
+ " -e Extract without pathname (junk paths)\n" \
+ " -x Extract with pathname\n" \
+ " -v list files\n" \
+ " -l list files\n" \
+ " -d directory to extract into\n" \
+ " -o overwrite files without prompting\n" \
+ " -p extract crypted file using password\n\n");
+}
+
+void Display64BitsSize(ZPOS64_T n, int size_char)
+{
+ /* to avoid compatibility problem , we do here the conversion */
+ char number[21];
+ int offset=19;
+ int pos_string = 19;
+ number[20]=0;
+ for (;;) {
+ number[offset]=(char)((n%10)+'0');
+ if (number[offset] != '0')
+ pos_string=offset;
+ n/=10;
+ if (offset==0)
+ break;
+ offset--;
+ }
+ {
+ int size_display_string = 19-pos_string;
+ while (size_char > size_display_string)
+ {
+ size_char--;
+ printf(" ");
+ }
+ }
+
+ printf("%s",&number[pos_string]);
+}
+
+int do_list(uf)
+ unzFile uf;
+{
+ uLong i;
+ unz_global_info64 gi;
+ int err;
+
+ err = unzGetGlobalInfo64(uf,&gi);
+ if (err!=UNZ_OK)
+ printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+ printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
+ printf(" ------ ------ ---- ----- ---- ---- ------ ----\n");
+ for (i=0;i<gi.number_entry;i++)
+ {
+ char filename_inzip[256];
+ unz_file_info64 file_info;
+ uLong ratio=0;
+ const char *string_method;
+ char charCrypt=' ';
+ err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+ break;
+ }
+ if (file_info.uncompressed_size>0)
+ ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size);
+
+ /* display a '*' if the file is crypted */
+ if ((file_info.flag & 1) != 0)
+ charCrypt='*';
+
+ if (file_info.compression_method==0)
+ string_method="Stored";
+ else
+ if (file_info.compression_method==Z_DEFLATED)
+ {
+ uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
+ if (iLevel==0)
+ string_method="Defl:N";
+ else if (iLevel==1)
+ string_method="Defl:X";
+ else if ((iLevel==2) || (iLevel==3))
+ string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
+ }
+ else
+ if (file_info.compression_method==Z_BZIP2ED)
+ {
+ string_method="BZip2 ";
+ }
+ else
+ string_method="Unkn. ";
+
+ Display64BitsSize(file_info.uncompressed_size,7);
+ printf(" %6s%c",string_method,charCrypt);
+ Display64BitsSize(file_info.compressed_size,7);
+ printf(" %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
+ ratio,
+ (uLong)file_info.tmu_date.tm_mon + 1,
+ (uLong)file_info.tmu_date.tm_mday,
+ (uLong)file_info.tmu_date.tm_year % 100,
+ (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
+ (uLong)file_info.crc,filename_inzip);
+ if ((i+1)<gi.number_entry)
+ {
+ err = unzGoToNextFile(uf);
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzGoToNextFile\n",err);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
+ unzFile uf;
+ const int* popt_extract_without_path;
+ int* popt_overwrite;
+ const char* password;
+{
+ char filename_inzip[256];
+ char* filename_withoutpath;
+ char* p;
+ int err=UNZ_OK;
+ FILE *fout=NULL;
+ void* buf;
+ uInt size_buf;
+
+ unz_file_info64 file_info;
+ uLong ratio=0;
+ err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+ return err;
+ }
+
+ size_buf = WRITEBUFFERSIZE;
+ buf = (void*)malloc(size_buf);
+ if (buf==NULL)
+ {
+ printf("Error allocating memory\n");
+ return UNZ_INTERNALERROR;
+ }
+
+ p = filename_withoutpath = filename_inzip;
+ while ((*p) != '\0')
+ {
+ if (((*p)=='/') || ((*p)=='\\'))
+ filename_withoutpath = p+1;
+ p++;
+ }
+
+ if ((*filename_withoutpath)=='\0')
+ {
+ if ((*popt_extract_without_path)==0)
+ {
+ printf("creating directory: %s\n",filename_inzip);
+ mymkdir(filename_inzip);
+ }
+ }
+ else
+ {
+ const char* write_filename;
+ int skip=0;
+
+ if ((*popt_extract_without_path)==0)
+ write_filename = filename_inzip;
+ else
+ write_filename = filename_withoutpath;
+
+ err = unzOpenCurrentFilePassword(uf,password);
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
+ }
+
+ if (((*popt_overwrite)==0) && (err==UNZ_OK))
+ {
+ char rep=0;
+ FILE* ftestexist;
+ ftestexist = FOPEN_FUNC(write_filename,"rb");
+ if (ftestexist!=NULL)
+ {
+ fclose(ftestexist);
+ do
+ {
+ char answer[128];
+ int ret;
+
+ printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
+ ret = scanf("%1s",answer);
+ if (ret != 1)
+ {
+ exit(EXIT_FAILURE);
+ }
+ rep = answer[0] ;
+ if ((rep>='a') && (rep<='z'))
+ rep -= 0x20;
+ }
+ while ((rep!='Y') && (rep!='N') && (rep!='A'));
+ }
+
+ if (rep == 'N')
+ skip = 1;
+
+ if (rep == 'A')
+ *popt_overwrite=1;
+ }
+
+ if ((skip==0) && (err==UNZ_OK))
+ {
+ fout=FOPEN_FUNC(write_filename,"wb");
+ /* some zipfile don't contain directory alone before file */
+ if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
+ (filename_withoutpath!=(char*)filename_inzip))
+ {
+ char c=*(filename_withoutpath-1);
+ *(filename_withoutpath-1)='\0';
+ makedir(write_filename);
+ *(filename_withoutpath-1)=c;
+ fout=FOPEN_FUNC(write_filename,"wb");
+ }
+
+ if (fout==NULL)
+ {
+ printf("error opening %s\n",write_filename);
+ }
+ }
+
+ if (fout!=NULL)
+ {
+ printf(" extracting: %s\n",write_filename);
+
+ do
+ {
+ err = unzReadCurrentFile(uf,buf,size_buf);
+ if (err<0)
+ {
+ printf("error %d with zipfile in unzReadCurrentFile\n",err);
+ break;
+ }
+ if (err>0)
+ if (fwrite(buf,err,1,fout)!=1)
+ {
+ printf("error in writing extracted file\n");
+ err=UNZ_ERRNO;
+ break;
+ }
+ }
+ while (err>0);
+ if (fout)
+ fclose(fout);
+
+ if (err==0)
+ change_file_date(write_filename,file_info.dosDate,
+ file_info.tmu_date);
+ }
+
+ if (err==UNZ_OK)
+ {
+ err = unzCloseCurrentFile (uf);
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzCloseCurrentFile\n",err);
+ }
+ }
+ else
+ unzCloseCurrentFile(uf); /* don't lose the error */
+ }
+
+ free(buf);
+ return err;
+}
+
+
+int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
+ unzFile uf;
+ int opt_extract_without_path;
+ int opt_overwrite;
+ const char* password;
+{
+ uLong i;
+ unz_global_info64 gi;
+ int err;
+ FILE* fout=NULL;
+
+ err = unzGetGlobalInfo64(uf,&gi);
+ if (err!=UNZ_OK)
+ printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+
+ for (i=0;i<gi.number_entry;i++)
+ {
+ if (do_extract_currentfile(uf,&opt_extract_without_path,
+ &opt_overwrite,
+ password) != UNZ_OK)
+ break;
+
+ if ((i+1)<gi.number_entry)
+ {
+ err = unzGoToNextFile(uf);
+ if (err!=UNZ_OK)
+ {
+ printf("error %d with zipfile in unzGoToNextFile\n",err);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
+ unzFile uf;
+ const char* filename;
+ int opt_extract_without_path;
+ int opt_overwrite;
+ const char* password;
+{
+ int err = UNZ_OK;
+ if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
+ {
+ printf("file %s not found in the zipfile\n",filename);
+ return 2;
+ }
+
+ if (do_extract_currentfile(uf,&opt_extract_without_path,
+ &opt_overwrite,
+ password) == UNZ_OK)
+ return 0;
+ else
+ return 1;
+}
+
+
+int main(argc,argv)
+ int argc;
+ char *argv[];
+{
+ const char *zipfilename=NULL;
+ const char *filename_to_extract=NULL;
+ const char *password=NULL;
+ char filename_try[MAXFILENAME+16] = "";
+ int i;
+ int ret_value=0;
+ int opt_do_list=0;
+ int opt_do_extract=1;
+ int opt_do_extract_withoutpath=0;
+ int opt_overwrite=0;
+ int opt_extractdir=0;
+ const char *dirname=NULL;
+ unzFile uf=NULL;
+
+ do_banner();
+ if (argc==1)
+ {
+ do_help();
+ return 0;
+ }
+ else
+ {
+ for (i=1;i<argc;i++)
+ {
+ if ((*argv[i])=='-')
+ {
+ const char *p=argv[i]+1;
+
+ while ((*p)!='\0')
+ {
+ char c=*(p++);;
+ if ((c=='l') || (c=='L'))
+ opt_do_list = 1;
+ if ((c=='v') || (c=='V'))
+ opt_do_list = 1;
+ if ((c=='x') || (c=='X'))
+ opt_do_extract = 1;
+ if ((c=='e') || (c=='E'))
+ opt_do_extract = opt_do_extract_withoutpath = 1;
+ if ((c=='o') || (c=='O'))
+ opt_overwrite=1;
+ if ((c=='d') || (c=='D'))
+ {
+ opt_extractdir=1;
+ dirname=argv[i+1];
+ }
+
+ if (((c=='p') || (c=='P')) && (i+1<argc))
+ {
+ password=argv[i+1];
+ i++;
+ }
+ }
+ }
+ else
+ {
+ if (zipfilename == NULL)
+ zipfilename = argv[i];
+ else if ((filename_to_extract==NULL) && (!opt_extractdir))
+ filename_to_extract = argv[i] ;
+ }
+ }
+ }
+
+ if (zipfilename!=NULL)
+ {
+
+# ifdef USEWIN32IOAPI
+ zlib_filefunc64_def ffunc;
+# endif
+
+ strncpy(filename_try, zipfilename,MAXFILENAME-1);
+ /* strncpy doesnt append the trailing NULL, of the string is too long. */
+ filename_try[ MAXFILENAME ] = '\0';
+
+# ifdef USEWIN32IOAPI
+ fill_win32_filefunc64A(&ffunc);
+ uf = unzOpen2_64(zipfilename,&ffunc);
+# else
+ uf = unzOpen64(zipfilename);
+# endif
+ if (uf==NULL)
+ {
+ strcat(filename_try,".zip");
+# ifdef USEWIN32IOAPI
+ uf = unzOpen2_64(filename_try,&ffunc);
+# else
+ uf = unzOpen64(filename_try);
+# endif
+ }
+ }
+
+ if (uf==NULL)
+ {
+ printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
+ return 1;
+ }
+ printf("%s opened\n",filename_try);
+
+ if (opt_do_list==1)
+ ret_value = do_list(uf);
+ else if (opt_do_extract==1)
+ {
+#ifdef _WIN32
+ if (opt_extractdir && _chdir(dirname))
+#else
+ if (opt_extractdir && chdir(dirname))
+#endif
+ {
+ printf("Error changing into %s, aborting\n", dirname);
+ exit(-1);
+ }
+
+ if (filename_to_extract == NULL)
+ ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password);
+ else
+ ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
+ }
+
+ unzClose(uf);
+
+ return ret_value;
+}
diff --git a/xs/src/png/zlib/contrib/minizip/miniunzip.1 b/xs/src/png/zlib/contrib/minizip/miniunzip.1
new file mode 100644
index 000000000..111ac6919
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/miniunzip.1
@@ -0,0 +1,63 @@
+.\" Hey, EMACS: -*- nroff -*-
+.TH miniunzip 1 "Nov 7, 2001"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh disable hyphenation
+.\" .hy enable hyphenation
+.\" .ad l left justify
+.\" .ad b justify to both left and right margins
+.\" .nf disable filling
+.\" .fi enable filling
+.\" .br insert line break
+.\" .sp <n> insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+miniunzip - uncompress and examine ZIP archives
+.SH SYNOPSIS
+.B miniunzip
+.RI [ -exvlo ]
+zipfile [ files_to_extract ] [-d tempdir]
+.SH DESCRIPTION
+.B minizip
+is a simple tool which allows the extraction of compressed file
+archives in the ZIP format used by the MS-DOS utility PKZIP. It was
+written as a demonstration of the
+.IR zlib (3)
+library and therefore lack many of the features of the
+.IR unzip (1)
+program.
+.SH OPTIONS
+A number of options are supported. With the exception of
+.BI \-d\ tempdir
+these must be supplied before any
+other arguments and are:
+.TP
+.BI \-l\ ,\ \-\-v
+List the files in the archive without extracting them.
+.TP
+.B \-o
+Overwrite files without prompting for confirmation.
+.TP
+.B \-x
+Extract files (default).
+.PP
+The
+.I zipfile
+argument is the name of the archive to process. The next argument can be used
+to specify a single file to extract from the archive.
+
+Lastly, the following option can be specified at the end of the command-line:
+.TP
+.BI \-d\ tempdir
+Extract the archive in the directory
+.I tempdir
+rather than the current directory.
+.SH SEE ALSO
+.BR minizip (1),
+.BR zlib (3),
+.BR unzip (1).
+.SH AUTHOR
+This program was written by Gilles Vollant. This manual page was
+written by Mark Brown <broonie@sirena.org.uk>. The -d tempdir option
+was added by Dirk Eddelbuettel <edd@debian.org>.
diff --git a/xs/src/png/zlib/contrib/minizip/minizip.1 b/xs/src/png/zlib/contrib/minizip/minizip.1
new file mode 100644
index 000000000..1154484c1
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/minizip.1
@@ -0,0 +1,46 @@
+.\" Hey, EMACS: -*- nroff -*-
+.TH minizip 1 "May 2, 2001"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh disable hyphenation
+.\" .hy enable hyphenation
+.\" .ad l left justify
+.\" .ad b justify to both left and right margins
+.\" .nf disable filling
+.\" .fi enable filling
+.\" .br insert line break
+.\" .sp <n> insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+minizip - create ZIP archives
+.SH SYNOPSIS
+.B minizip
+.RI [ -o ]
+zipfile [ " files" ... ]
+.SH DESCRIPTION
+.B minizip
+is a simple tool which allows the creation of compressed file archives
+in the ZIP format used by the MS-DOS utility PKZIP. It was written as
+a demonstration of the
+.IR zlib (3)
+library and therefore lack many of the features of the
+.IR zip (1)
+program.
+.SH OPTIONS
+The first argument supplied is the name of the ZIP archive to create or
+.RI -o
+in which case it is ignored and the second argument treated as the
+name of the ZIP file. If the ZIP file already exists it will be
+overwritten.
+.PP
+Subsequent arguments specify a list of files to place in the ZIP
+archive. If none are specified then an empty archive will be created.
+.SH SEE ALSO
+.BR miniunzip (1),
+.BR zlib (3),
+.BR zip (1).
+.SH AUTHOR
+This program was written by Gilles Vollant. This manual page was
+written by Mark Brown <broonie@sirena.org.uk>.
+
diff --git a/xs/src/png/zlib/contrib/minizip/minizip.c b/xs/src/png/zlib/contrib/minizip/minizip.c
new file mode 100644
index 000000000..4288962ec
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/minizip.c
@@ -0,0 +1,520 @@
+/*
+ minizip.c
+ Version 1.1, February 14h, 2010
+ sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+*/
+
+
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
+ #ifndef __USE_FILE_OFFSET64
+ #define __USE_FILE_OFFSET64
+ #endif
+ #ifndef __USE_LARGEFILE64
+ #define __USE_LARGEFILE64
+ #endif
+ #ifndef _LARGEFILE64_SOURCE
+ #define _LARGEFILE64_SOURCE
+ #endif
+ #ifndef _FILE_OFFSET_BIT
+ #define _FILE_OFFSET_BIT 64
+ #endif
+#endif
+
+#ifdef __APPLE__
+// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
+#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
+#define FTELLO_FUNC(stream) ftello(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
+#else
+#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
+#define FTELLO_FUNC(stream) ftello64(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
+#endif
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifdef _WIN32
+# include <direct.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <utime.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+
+#include "zip.h"
+
+#ifdef _WIN32
+ #define USEWIN32IOAPI
+ #include "iowin32.h"
+#endif
+
+
+
+#define WRITEBUFFERSIZE (16384)
+#define MAXFILENAME (256)
+
+#ifdef _WIN32
+uLong filetime(f, tmzip, dt)
+ char *f; /* name of file to get info on */
+ tm_zip *tmzip; /* return value: access, modific. and creation times */
+ uLong *dt; /* dostime */
+{
+ int ret = 0;
+ {
+ FILETIME ftLocal;
+ HANDLE hFind;
+ WIN32_FIND_DATAA ff32;
+
+ hFind = FindFirstFileA(f,&ff32);
+ if (hFind != INVALID_HANDLE_VALUE)
+ {
+ FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
+ FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
+ FindClose(hFind);
+ ret = 1;
+ }
+ }
+ return ret;
+}
+#else
+#ifdef unix || __APPLE__
+uLong filetime(f, tmzip, dt)
+ char *f; /* name of file to get info on */
+ tm_zip *tmzip; /* return value: access, modific. and creation times */
+ uLong *dt; /* dostime */
+{
+ int ret=0;
+ struct stat s; /* results of stat() */
+ struct tm* filedate;
+ time_t tm_t=0;
+
+ if (strcmp(f,"-")!=0)
+ {
+ char name[MAXFILENAME+1];
+ int len = strlen(f);
+ if (len > MAXFILENAME)
+ len = MAXFILENAME;
+
+ strncpy(name, f,MAXFILENAME-1);
+ /* strncpy doesnt append the trailing NULL, of the string is too long. */
+ name[ MAXFILENAME ] = '\0';
+
+ if (name[len - 1] == '/')
+ name[len - 1] = '\0';
+ /* not all systems allow stat'ing a file with / appended */
+ if (stat(name,&s)==0)
+ {
+ tm_t = s.st_mtime;
+ ret = 1;
+ }
+ }
+ filedate = localtime(&tm_t);
+
+ tmzip->tm_sec = filedate->tm_sec;
+ tmzip->tm_min = filedate->tm_min;
+ tmzip->tm_hour = filedate->tm_hour;
+ tmzip->tm_mday = filedate->tm_mday;
+ tmzip->tm_mon = filedate->tm_mon ;
+ tmzip->tm_year = filedate->tm_year;
+
+ return ret;
+}
+#else
+uLong filetime(f, tmzip, dt)
+ char *f; /* name of file to get info on */
+ tm_zip *tmzip; /* return value: access, modific. and creation times */
+ uLong *dt; /* dostime */
+{
+ return 0;
+}
+#endif
+#endif
+
+
+
+
+int check_exist_file(filename)
+ const char* filename;
+{
+ FILE* ftestexist;
+ int ret = 1;
+ ftestexist = FOPEN_FUNC(filename,"rb");
+ if (ftestexist==NULL)
+ ret = 0;
+ else
+ fclose(ftestexist);
+ return ret;
+}
+
+void do_banner()
+{
+ printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n");
+ printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n");
+}
+
+void do_help()
+{
+ printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
+ " -o Overwrite existing file.zip\n" \
+ " -a Append to existing file.zip\n" \
+ " -0 Store only\n" \
+ " -1 Compress faster\n" \
+ " -9 Compress better\n\n" \
+ " -j exclude path. store only the file name.\n\n");
+}
+
+/* calculate the CRC32 of a file,
+ because to encrypt a file, we need known the CRC32 of the file before */
+int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
+{
+ unsigned long calculate_crc=0;
+ int err=ZIP_OK;
+ FILE * fin = FOPEN_FUNC(filenameinzip,"rb");
+
+ unsigned long size_read = 0;
+ unsigned long total_read = 0;
+ if (fin==NULL)
+ {
+ err = ZIP_ERRNO;
+ }
+
+ if (err == ZIP_OK)
+ do
+ {
+ err = ZIP_OK;
+ size_read = (int)fread(buf,1,size_buf,fin);
+ if (size_read < size_buf)
+ if (feof(fin)==0)
+ {
+ printf("error in reading %s\n",filenameinzip);
+ err = ZIP_ERRNO;
+ }
+
+ if (size_read>0)
+ calculate_crc = crc32(calculate_crc,buf,size_read);
+ total_read += size_read;
+
+ } while ((err == ZIP_OK) && (size_read>0));
+
+ if (fin)
+ fclose(fin);
+
+ *result_crc=calculate_crc;
+ printf("file %s crc %lx\n", filenameinzip, calculate_crc);
+ return err;
+}
+
+int isLargeFile(const char* filename)
+{
+ int largeFile = 0;
+ ZPOS64_T pos = 0;
+ FILE* pFile = FOPEN_FUNC(filename, "rb");
+
+ if(pFile != NULL)
+ {
+ int n = FSEEKO_FUNC(pFile, 0, SEEK_END);
+ pos = FTELLO_FUNC(pFile);
+
+ printf("File : %s is %lld bytes\n", filename, pos);
+
+ if(pos >= 0xffffffff)
+ largeFile = 1;
+
+ fclose(pFile);
+ }
+
+ return largeFile;
+}
+
+int main(argc,argv)
+ int argc;
+ char *argv[];
+{
+ int i;
+ int opt_overwrite=0;
+ int opt_compress_level=Z_DEFAULT_COMPRESSION;
+ int opt_exclude_path=0;
+ int zipfilenamearg = 0;
+ char filename_try[MAXFILENAME+16];
+ int zipok;
+ int err=0;
+ int size_buf=0;
+ void* buf=NULL;
+ const char* password=NULL;
+
+
+ do_banner();
+ if (argc==1)
+ {
+ do_help();
+ return 0;
+ }
+ else
+ {
+ for (i=1;i<argc;i++)
+ {
+ if ((*argv[i])=='-')
+ {
+ const char *p=argv[i]+1;
+
+ while ((*p)!='\0')
+ {
+ char c=*(p++);;
+ if ((c=='o') || (c=='O'))
+ opt_overwrite = 1;
+ if ((c=='a') || (c=='A'))
+ opt_overwrite = 2;
+ if ((c>='0') && (c<='9'))
+ opt_compress_level = c-'0';
+ if ((c=='j') || (c=='J'))
+ opt_exclude_path = 1;
+
+ if (((c=='p') || (c=='P')) && (i+1<argc))
+ {
+ password=argv[i+1];
+ i++;
+ }
+ }
+ }
+ else
+ {
+ if (zipfilenamearg == 0)
+ {
+ zipfilenamearg = i ;
+ }
+ }
+ }
+ }
+
+ size_buf = WRITEBUFFERSIZE;
+ buf = (void*)malloc(size_buf);
+ if (buf==NULL)
+ {
+ printf("Error allocating memory\n");
+ return ZIP_INTERNALERROR;
+ }
+
+ if (zipfilenamearg==0)
+ {
+ zipok=0;
+ }
+ else
+ {
+ int i,len;
+ int dot_found=0;
+
+ zipok = 1 ;
+ strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
+ /* strncpy doesnt append the trailing NULL, of the string is too long. */
+ filename_try[ MAXFILENAME ] = '\0';
+
+ len=(int)strlen(filename_try);
+ for (i=0;i<len;i++)
+ if (filename_try[i]=='.')
+ dot_found=1;
+
+ if (dot_found==0)
+ strcat(filename_try,".zip");
+
+ if (opt_overwrite==2)
+ {
+ /* if the file don't exist, we not append file */
+ if (check_exist_file(filename_try)==0)
+ opt_overwrite=1;
+ }
+ else
+ if (opt_overwrite==0)
+ if (check_exist_file(filename_try)!=0)
+ {
+ char rep=0;
+ do
+ {
+ char answer[128];
+ int ret;
+ printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
+ ret = scanf("%1s",answer);
+ if (ret != 1)
+ {
+ exit(EXIT_FAILURE);
+ }
+ rep = answer[0] ;
+ if ((rep>='a') && (rep<='z'))
+ rep -= 0x20;
+ }
+ while ((rep!='Y') && (rep!='N') && (rep!='A'));
+ if (rep=='N')
+ zipok = 0;
+ if (rep=='A')
+ opt_overwrite = 2;
+ }
+ }
+
+ if (zipok==1)
+ {
+ zipFile zf;
+ int errclose;
+# ifdef USEWIN32IOAPI
+ zlib_filefunc64_def ffunc;
+ fill_win32_filefunc64A(&ffunc);
+ zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
+# else
+ zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);
+# endif
+
+ if (zf == NULL)
+ {
+ printf("error opening %s\n",filename_try);
+ err= ZIP_ERRNO;
+ }
+ else
+ printf("creating %s\n",filename_try);
+
+ for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
+ {
+ if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
+ ((argv[i][1]=='o') || (argv[i][1]=='O') ||
+ (argv[i][1]=='a') || (argv[i][1]=='A') ||
+ (argv[i][1]=='p') || (argv[i][1]=='P') ||
+ ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
+ (strlen(argv[i]) == 2)))
+ {
+ FILE * fin;
+ int size_read;
+ const char* filenameinzip = argv[i];
+ const char *savefilenameinzip;
+ zip_fileinfo zi;
+ unsigned long crcFile=0;
+ int zip64 = 0;
+
+ zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
+ zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
+ zi.dosDate = 0;
+ zi.internal_fa = 0;
+ zi.external_fa = 0;
+ filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
+
+/*
+ err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
+ NULL,0,NULL,0,NULL / * comment * /,
+ (opt_compress_level != 0) ? Z_DEFLATED : 0,
+ opt_compress_level);
+*/
+ if ((password != NULL) && (err==ZIP_OK))
+ err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
+
+ zip64 = isLargeFile(filenameinzip);
+
+ /* The path name saved, should not include a leading slash. */
+ /*if it did, windows/xp and dynazip couldn't read the zip file. */
+ savefilenameinzip = filenameinzip;
+ while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
+ {
+ savefilenameinzip++;
+ }
+
+ /*should the zip file contain any path at all?*/
+ if( opt_exclude_path )
+ {
+ const char *tmpptr;
+ const char *lastslash = 0;
+ for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
+ {
+ if( *tmpptr == '\\' || *tmpptr == '/')
+ {
+ lastslash = tmpptr;
+ }
+ }
+ if( lastslash != NULL )
+ {
+ savefilenameinzip = lastslash+1; // base filename follows last slash.
+ }
+ }
+
+ /**/
+ err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
+ NULL,0,NULL,0,NULL /* comment*/,
+ (opt_compress_level != 0) ? Z_DEFLATED : 0,
+ opt_compress_level,0,
+ /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ password,crcFile, zip64);
+
+ if (err != ZIP_OK)
+ printf("error in opening %s in zipfile\n",filenameinzip);
+ else
+ {
+ fin = FOPEN_FUNC(filenameinzip,"rb");
+ if (fin==NULL)
+ {
+ err=ZIP_ERRNO;
+ printf("error in opening %s for reading\n",filenameinzip);
+ }
+ }
+
+ if (err == ZIP_OK)
+ do
+ {
+ err = ZIP_OK;
+ size_read = (int)fread(buf,1,size_buf,fin);
+ if (size_read < size_buf)
+ if (feof(fin)==0)
+ {
+ printf("error in reading %s\n",filenameinzip);
+ err = ZIP_ERRNO;
+ }
+
+ if (size_read>0)
+ {
+ err = zipWriteInFileInZip (zf,buf,size_read);
+ if (err<0)
+ {
+ printf("error in writing %s in the zipfile\n",
+ filenameinzip);
+ }
+
+ }
+ } while ((err == ZIP_OK) && (size_read>0));
+
+ if (fin)
+ fclose(fin);
+
+ if (err<0)
+ err=ZIP_ERRNO;
+ else
+ {
+ err = zipCloseFileInZip(zf);
+ if (err!=ZIP_OK)
+ printf("error in closing %s in the zipfile\n",
+ filenameinzip);
+ }
+ }
+ }
+ errclose = zipClose(zf,NULL);
+ if (errclose != ZIP_OK)
+ printf("error in closing %s\n",filename_try);
+ }
+ else
+ {
+ do_help();
+ }
+
+ free(buf);
+ return 0;
+}
diff --git a/xs/src/png/zlib/contrib/minizip/minizip.pc.in b/xs/src/png/zlib/contrib/minizip/minizip.pc.in
new file mode 100644
index 000000000..69b5b7fdc
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/minizip.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/minizip
+
+Name: minizip
+Description: Minizip zip file manipulation library
+Requires:
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lminizip
+Libs.private: -lz
+Cflags: -I${includedir}
diff --git a/xs/src/png/zlib/contrib/minizip/mztools.c b/xs/src/png/zlib/contrib/minizip/mztools.c
new file mode 100644
index 000000000..96891c2e0
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/mztools.c
@@ -0,0 +1,291 @@
+/*
+ Additional tools for Minizip
+ Code: Xavier Roche '2004
+ License: Same as ZLIB (www.gzip.org)
+*/
+
+/* Code */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "zlib.h"
+#include "unzip.h"
+
+#define READ_8(adr) ((unsigned char)*(adr))
+#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
+#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
+
+#define WRITE_8(buff, n) do { \
+ *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
+} while(0)
+#define WRITE_16(buff, n) do { \
+ WRITE_8((unsigned char*)(buff), n); \
+ WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
+} while(0)
+#define WRITE_32(buff, n) do { \
+ WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
+ WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
+} while(0)
+
+extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
+const char* file;
+const char* fileOut;
+const char* fileOutTmp;
+uLong* nRecovered;
+uLong* bytesRecovered;
+{
+ int err = Z_OK;
+ FILE* fpZip = fopen(file, "rb");
+ FILE* fpOut = fopen(fileOut, "wb");
+ FILE* fpOutCD = fopen(fileOutTmp, "wb");
+ if (fpZip != NULL && fpOut != NULL) {
+ int entries = 0;
+ uLong totalBytes = 0;
+ char header[30];
+ char filename[1024];
+ char extra[1024];
+ int offset = 0;
+ int offsetCD = 0;
+ while ( fread(header, 1, 30, fpZip) == 30 ) {
+ int currentOffset = offset;
+
+ /* File entry */
+ if (READ_32(header) == 0x04034b50) {
+ unsigned int version = READ_16(header + 4);
+ unsigned int gpflag = READ_16(header + 6);
+ unsigned int method = READ_16(header + 8);
+ unsigned int filetime = READ_16(header + 10);
+ unsigned int filedate = READ_16(header + 12);
+ unsigned int crc = READ_32(header + 14); /* crc */
+ unsigned int cpsize = READ_32(header + 18); /* compressed size */
+ unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
+ unsigned int fnsize = READ_16(header + 26); /* file name length */
+ unsigned int extsize = READ_16(header + 28); /* extra field length */
+ filename[0] = extra[0] = '\0';
+
+ /* Header */
+ if (fwrite(header, 1, 30, fpOut) == 30) {
+ offset += 30;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+
+ /* Filename */
+ if (fnsize > 0) {
+ if (fnsize < sizeof(filename)) {
+ if (fread(filename, 1, fnsize, fpZip) == fnsize) {
+ if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
+ offset += fnsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_STREAM_ERROR;
+ break;
+ }
+
+ /* Extra field */
+ if (extsize > 0) {
+ if (extsize < sizeof(extra)) {
+ if (fread(extra, 1, extsize, fpZip) == extsize) {
+ if (fwrite(extra, 1, extsize, fpOut) == extsize) {
+ offset += extsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+ /* Data */
+ {
+ int dataSize = cpsize;
+ if (dataSize == 0) {
+ dataSize = uncpsize;
+ }
+ if (dataSize > 0) {
+ char* data = malloc(dataSize);
+ if (data != NULL) {
+ if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
+ if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
+ offset += dataSize;
+ totalBytes += dataSize;
+ } else {
+ err = Z_ERRNO;
+ }
+ } else {
+ err = Z_ERRNO;
+ }
+ free(data);
+ if (err != Z_OK) {
+ break;
+ }
+ } else {
+ err = Z_MEM_ERROR;
+ break;
+ }
+ }
+ }
+
+ /* Central directory entry */
+ {
+ char header[46];
+ char* comment = "";
+ int comsize = (int) strlen(comment);
+ WRITE_32(header, 0x02014b50);
+ WRITE_16(header + 4, version);
+ WRITE_16(header + 6, version);
+ WRITE_16(header + 8, gpflag);
+ WRITE_16(header + 10, method);
+ WRITE_16(header + 12, filetime);
+ WRITE_16(header + 14, filedate);
+ WRITE_32(header + 16, crc);
+ WRITE_32(header + 20, cpsize);
+ WRITE_32(header + 24, uncpsize);
+ WRITE_16(header + 28, fnsize);
+ WRITE_16(header + 30, extsize);
+ WRITE_16(header + 32, comsize);
+ WRITE_16(header + 34, 0); /* disk # */
+ WRITE_16(header + 36, 0); /* int attrb */
+ WRITE_32(header + 38, 0); /* ext attrb */
+ WRITE_32(header + 42, currentOffset);
+ /* Header */
+ if (fwrite(header, 1, 46, fpOutCD) == 46) {
+ offsetCD += 46;
+
+ /* Filename */
+ if (fnsize > 0) {
+ if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
+ offsetCD += fnsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_STREAM_ERROR;
+ break;
+ }
+
+ /* Extra field */
+ if (extsize > 0) {
+ if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
+ offsetCD += extsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+ /* Comment field */
+ if (comsize > 0) {
+ if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
+ offsetCD += comsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+ /* Success */
+ entries++;
+
+ } else {
+ break;
+ }
+ }
+
+ /* Final central directory */
+ {
+ int entriesZip = entries;
+ char header[22];
+ char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
+ int comsize = (int) strlen(comment);
+ if (entriesZip > 0xffff) {
+ entriesZip = 0xffff;
+ }
+ WRITE_32(header, 0x06054b50);
+ WRITE_16(header + 4, 0); /* disk # */
+ WRITE_16(header + 6, 0); /* disk # */
+ WRITE_16(header + 8, entriesZip); /* hack */
+ WRITE_16(header + 10, entriesZip); /* hack */
+ WRITE_32(header + 12, offsetCD); /* size of CD */
+ WRITE_32(header + 16, offset); /* offset to CD */
+ WRITE_16(header + 20, comsize); /* comment */
+
+ /* Header */
+ if (fwrite(header, 1, 22, fpOutCD) == 22) {
+
+ /* Comment field */
+ if (comsize > 0) {
+ if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
+ err = Z_ERRNO;
+ }
+ }
+
+ } else {
+ err = Z_ERRNO;
+ }
+ }
+
+ /* Final merge (file + central directory) */
+ fclose(fpOutCD);
+ if (err == Z_OK) {
+ fpOutCD = fopen(fileOutTmp, "rb");
+ if (fpOutCD != NULL) {
+ int nRead;
+ char buffer[8192];
+ while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
+ if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+ fclose(fpOutCD);
+ }
+ }
+
+ /* Close */
+ fclose(fpZip);
+ fclose(fpOut);
+
+ /* Wipe temporary file */
+ (void)remove(fileOutTmp);
+
+ /* Number of recovered entries */
+ if (err == Z_OK) {
+ if (nRecovered != NULL) {
+ *nRecovered = entries;
+ }
+ if (bytesRecovered != NULL) {
+ *bytesRecovered = totalBytes;
+ }
+ }
+ } else {
+ err = Z_STREAM_ERROR;
+ }
+ return err;
+}
diff --git a/xs/src/png/zlib/contrib/minizip/mztools.h b/xs/src/png/zlib/contrib/minizip/mztools.h
new file mode 100644
index 000000000..a49a426ec
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/mztools.h
@@ -0,0 +1,37 @@
+/*
+ Additional tools for Minizip
+ Code: Xavier Roche '2004
+ License: Same as ZLIB (www.gzip.org)
+*/
+
+#ifndef _zip_tools_H
+#define _zip_tools_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#include "unzip.h"
+
+/* Repair a ZIP file (missing central directory)
+ file: file to recover
+ fileOut: output file after recovery
+ fileOutTmp: temporary file name used for recovery
+*/
+extern int ZEXPORT unzRepair(const char* file,
+ const char* fileOut,
+ const char* fileOutTmp,
+ uLong* nRecovered,
+ uLong* bytesRecovered);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/xs/src/png/zlib/contrib/minizip/unzip.c b/xs/src/png/zlib/contrib/minizip/unzip.c
new file mode 100644
index 000000000..bcfb9416e
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/unzip.c
@@ -0,0 +1,2125 @@
+/* unzip.c -- IO for uncompress .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+
+ ------------------------------------------------------------------------------------
+ Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
+ compatibility with older software. The following is from the original crypt.c.
+ Code woven in by Terry Thorsen 1/2003.
+
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+
+ crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
+
+ The encryption/decryption parts of this source code (as opposed to the
+ non-echoing password parts) were originally written in Europe. The
+ whole source package can be freely distributed, including from the USA.
+ (Prior to January 2000, re-export from the US was a violation of US law.)
+
+ This encryption code is a direct transcription of the algorithm from
+ Roger Schlafly, described by Phil Katz in the file appnote.txt. This
+ file (appnote.txt) is distributed with the PKZIP program (even in the
+ version without encryption capabilities).
+
+ ------------------------------------------------------------------------------------
+
+ Changes in unzip.c
+
+ 2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
+ 2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
+ 2007-2008 - Even Rouault - Remove old C style function prototypes
+ 2007-2008 - Even Rouault - Add unzip support for ZIP64
+
+ Copyright (C) 2007-2008 Even Rouault
+
+
+ Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
+ Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
+ should only read the compressed/uncompressed size from the Zip64 format if
+ the size from normal header was 0xFFFFFFFF
+ Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
+ Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
+ Patch created by Daniel Borca
+
+ Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
+
+ Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef NOUNCRYPT
+ #define NOUNCRYPT
+#endif
+
+#include "zlib.h"
+#include "unzip.h"
+
+#ifdef STDC
+# include <stddef.h>
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+ extern int errno;
+#else
+# include <errno.h>
+#endif
+
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+
+#ifndef CASESENSITIVITYDEFAULT_NO
+# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
+# define CASESENSITIVITYDEFAULT_NO
+# endif
+#endif
+
+
+#ifndef UNZ_BUFSIZE
+#define UNZ_BUFSIZE (16384)
+#endif
+
+#ifndef UNZ_MAXFILENAMEINZIP
+#define UNZ_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+
+
+const char unz_copyright[] =
+ " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+/* unz_file_info_interntal contain internal info about a file in zipfile*/
+typedef struct unz_file_info64_internal_s
+{
+ ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
+} unz_file_info64_internal;
+
+
+/* file_in_zip_read_info_s contain internal information about a file in zipfile,
+ when reading and decompress it */
+typedef struct
+{
+ char *read_buffer; /* internal buffer for compressed data */
+ z_stream stream; /* zLib stream structure for inflate */
+
+#ifdef HAVE_BZIP2
+ bz_stream bstream; /* bzLib stream structure for bziped */
+#endif
+
+ ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
+ uLong stream_initialised; /* flag set if stream structure is initialised*/
+
+ ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
+ uInt size_local_extrafield;/* size of the local extra field */
+ ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/
+ ZPOS64_T total_out_64;
+
+ uLong crc32; /* crc32 of all data uncompressed */
+ uLong crc32_wait; /* crc32 we must obtain after decompress all */
+ ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
+ ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
+ zlib_filefunc64_32_def z_filefunc;
+ voidpf filestream; /* io structore of the zipfile */
+ uLong compression_method; /* compression method (0==store) */
+ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+ int raw;
+} file_in_zip64_read_info_s;
+
+
+/* unz64_s contain internal information about the zipfile
+*/
+typedef struct
+{
+ zlib_filefunc64_32_def z_filefunc;
+ int is64bitOpenFunction;
+ voidpf filestream; /* io structore of the zipfile */
+ unz_global_info64 gi; /* public global information */
+ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+ ZPOS64_T num_file; /* number of the current file in the zipfile*/
+ ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/
+ ZPOS64_T current_file_ok; /* flag about the usability of the current file*/
+ ZPOS64_T central_pos; /* position of the beginning of the central dir*/
+
+ ZPOS64_T size_central_dir; /* size of the central directory */
+ ZPOS64_T offset_central_dir; /* offset of start of central directory with
+ respect to the starting disk number */
+
+ unz_file_info64 cur_file_info; /* public info about the current file in zip*/
+ unz_file_info64_internal cur_file_info_internal; /* private info about it*/
+ file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
+ file if we are decompressing it */
+ int encrypted;
+
+ int isZip64;
+
+# ifndef NOUNCRYPT
+ unsigned long keys[3]; /* keys defining the pseudo-random sequence */
+ const z_crc_t* pcrc_32_tab;
+# endif
+} unz64_s;
+
+
+#ifndef NOUNCRYPT
+#include "crypt.h"
+#endif
+
+/* ===========================================================================
+ Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+ for end of file.
+ IN assertion: the stream s has been successfully opened for reading.
+*/
+
+
+local int unz64local_getByte OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ int *pi));
+
+local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
+{
+ unsigned char c;
+ int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+ if (err==1)
+ {
+ *pi = (int)c;
+ return UNZ_OK;
+ }
+ else
+ {
+ if (ZERROR64(*pzlib_filefunc_def,filestream))
+ return UNZ_ERRNO;
+ else
+ return UNZ_EOF;
+ }
+}
+
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int unz64local_getShort OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX));
+
+local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<8;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int unz64local_getLong OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX));
+
+local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ uLong *pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<8;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((uLong)i)<<16;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<24;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int unz64local_getLong64 OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ ZPOS64_T *pX));
+
+
+local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream,
+ ZPOS64_T *pX)
+{
+ ZPOS64_T x ;
+ int i = 0;
+ int err;
+
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (ZPOS64_T)i;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<8;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<16;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<24;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<32;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<40;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<48;
+
+ if (err==UNZ_OK)
+ err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x |= ((ZPOS64_T)i)<<56;
+
+ if (err==UNZ_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+/* My own strcmpi / strcasecmp */
+local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
+{
+ for (;;)
+ {
+ char c1=*(fileName1++);
+ char c2=*(fileName2++);
+ if ((c1>='a') && (c1<='z'))
+ c1 -= 0x20;
+ if ((c2>='a') && (c2<='z'))
+ c2 -= 0x20;
+ if (c1=='\0')
+ return ((c2=='\0') ? 0 : -1);
+ if (c2=='\0')
+ return 1;
+ if (c1<c2)
+ return -1;
+ if (c1>c2)
+ return 1;
+ }
+}
+
+
+#ifdef CASESENSITIVITYDEFAULT_NO
+#define CASESENSITIVITYDEFAULTVALUE 2
+#else
+#define CASESENSITIVITYDEFAULTVALUE 1
+#endif
+
+#ifndef STRCMPCASENOSENTIVEFUNCTION
+#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
+#endif
+
+/*
+ Compare two filename (fileName1,fileName2).
+ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ or strcasecmp)
+ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ (like 1 on Unix, 2 on Windows)
+
+*/
+extern int ZEXPORT unzStringFileNameCompare (const char* fileName1,
+ const char* fileName2,
+ int iCaseSensitivity)
+
+{
+ if (iCaseSensitivity==0)
+ iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
+
+ if (iCaseSensitivity==1)
+ return strcmp(fileName1,fileName2);
+
+ return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+
+/*
+ Locate the Central directory of a zipfile (at the end, just before
+ the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos ;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+ ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+ TRYFREE(buf);
+ return uPosFound;
+}
+
+
+/*
+ Locate the Central directory 64 of a zipfile (at the end, just before
+ the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir64 OF((
+ const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream));
+
+local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
+ voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+ uLong uL;
+ ZPOS64_T relativeOffset;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+ ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+ TRYFREE(buf);
+ if (uPosFound == 0)
+ return 0;
+
+ /* Zip64 end of central directory locator */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+
+ /* number of the disk with the start of the zip64 end of central directory */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+ if (uL != 0)
+ return 0;
+
+ /* relative offset of the zip64 end of central directory record */
+ if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
+ return 0;
+
+ /* total number of disks */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+ if (uL != 1)
+ return 0;
+
+ /* Goto end of central directory record */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature */
+ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+ return 0;
+
+ if (uL != 0x06064b50)
+ return 0;
+
+ return relativeOffset;
+}
+
+/*
+ Open a Zip file. path contain the full pathname (by example,
+ on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
+ "zlib/zlib114.zip".
+ If the zipfile cannot be opened (file doesn't exist or in not valid), the
+ return value is NULL.
+ Else, the return value is a unzFile Handle, usable with other function
+ of this unzip package.
+*/
+local unzFile unzOpenInternal (const void *path,
+ zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
+ int is64bitOpenFunction)
+{
+ unz64_s us;
+ unz64_s *s;
+ ZPOS64_T central_pos;
+ uLong uL;
+
+ uLong number_disk; /* number of the current dist, used for
+ spaning ZIP, unsupported, always 0*/
+ uLong number_disk_with_CD; /* number the the disk with central dir, used
+ for spaning ZIP, unsupported, always 0*/
+ ZPOS64_T number_entry_CD; /* total number of entries in
+ the central dir
+ (same than number_entry on nospan) */
+
+ int err=UNZ_OK;
+
+ if (unz_copyright[0]!=' ')
+ return NULL;
+
+ us.z_filefunc.zseek32_file = NULL;
+ us.z_filefunc.ztell32_file = NULL;
+ if (pzlib_filefunc64_32_def==NULL)
+ fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
+ else
+ us.z_filefunc = *pzlib_filefunc64_32_def;
+ us.is64bitOpenFunction = is64bitOpenFunction;
+
+
+
+ us.filestream = ZOPEN64(us.z_filefunc,
+ path,
+ ZLIB_FILEFUNC_MODE_READ |
+ ZLIB_FILEFUNC_MODE_EXISTING);
+ if (us.filestream==NULL)
+ return NULL;
+
+ central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
+ if (central_pos)
+ {
+ uLong uS;
+ ZPOS64_T uL64;
+
+ us.isZip64 = 1;
+
+ if (ZSEEK64(us.z_filefunc, us.filestream,
+ central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* size of zip64 end of central directory record */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* version made by */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* version needed to extract */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of this disk */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central directory on this disk */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central directory */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if ((number_entry_CD!=us.gi.number_entry) ||
+ (number_disk_with_CD!=0) ||
+ (number_disk!=0))
+ err=UNZ_BADZIPFILE;
+
+ /* size of the central directory */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* offset of start of central directory with respect to the
+ starting disk number */
+ if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ us.gi.size_comment = 0;
+ }
+ else
+ {
+ central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
+ if (central_pos==0)
+ err=UNZ_ERRNO;
+
+ us.isZip64 = 0;
+
+ if (ZSEEK64(us.z_filefunc, us.filestream,
+ central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+ /* the signature, already checked */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of this disk */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* total number of entries in the central dir on this disk */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.gi.number_entry = uL;
+
+ /* total number of entries in the central dir */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ number_entry_CD = uL;
+
+ if ((number_entry_CD!=us.gi.number_entry) ||
+ (number_disk_with_CD!=0) ||
+ (number_disk!=0))
+ err=UNZ_BADZIPFILE;
+
+ /* size of the central directory */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.size_central_dir = uL;
+
+ /* offset of start of central directory with respect to the
+ starting disk number */
+ if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ us.offset_central_dir = uL;
+
+ /* zipfile comment length */
+ if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
+ (err==UNZ_OK))
+ err=UNZ_BADZIPFILE;
+
+ if (err!=UNZ_OK)
+ {
+ ZCLOSE64(us.z_filefunc, us.filestream);
+ return NULL;
+ }
+
+ us.byte_before_the_zipfile = central_pos -
+ (us.offset_central_dir+us.size_central_dir);
+ us.central_pos = central_pos;
+ us.pfile_in_zip_read = NULL;
+ us.encrypted = 0;
+
+
+ s=(unz64_s*)ALLOC(sizeof(unz64_s));
+ if( s != NULL)
+ {
+ *s=us;
+ unzGoToFirstFile((unzFile)s);
+ }
+ return (unzFile)s;
+}
+
+
+extern unzFile ZEXPORT unzOpen2 (const char *path,
+ zlib_filefunc_def* pzlib_filefunc32_def)
+{
+ if (pzlib_filefunc32_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+ return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
+ }
+ else
+ return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen2_64 (const void *path,
+ zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ if (pzlib_filefunc_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+ zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+ zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+ return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
+ }
+ else
+ return unzOpenInternal(path, NULL, 1);
+}
+
+extern unzFile ZEXPORT unzOpen (const char *path)
+{
+ return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen64 (const void *path)
+{
+ return unzOpenInternal(path, NULL, 1);
+}
+
+/*
+ Close a ZipFile opened with unzOpen.
+ If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+ these files MUST be closed with unzCloseCurrentFile before call unzClose.
+ return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzClose (unzFile file)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ if (s->pfile_in_zip_read!=NULL)
+ unzCloseCurrentFile(file);
+
+ ZCLOSE64(s->z_filefunc, s->filestream);
+ TRYFREE(s);
+ return UNZ_OK;
+}
+
+
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ *pglobal_info=s->gi;
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
+{
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ /* to do : check if number_entry is not truncated */
+ pglobal_info32->number_entry = (uLong)s->gi.number_entry;
+ pglobal_info32->size_comment = s->gi.size_comment;
+ return UNZ_OK;
+}
+/*
+ Translate date/time from Dos format to tm_unz (readable more easilty)
+*/
+local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
+{
+ ZPOS64_T uDate;
+ uDate = (ZPOS64_T)(ulDosDate>>16);
+ ptm->tm_mday = (uInt)(uDate&0x1f) ;
+ ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
+ ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
+
+ ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
+ ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
+ ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
+}
+
+/*
+ Get Info about the current file in the zipfile, with internal only info
+*/
+local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
+ unz_file_info64 *pfile_info,
+ unz_file_info64_internal
+ *pfile_info_internal,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+
+local int unz64local_GetCurrentFileInfoInternal (unzFile file,
+ unz_file_info64 *pfile_info,
+ unz_file_info64_internal
+ *pfile_info_internal,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize)
+{
+ unz64_s* s;
+ unz_file_info64 file_info;
+ unz_file_info64_internal file_info_internal;
+ int err=UNZ_OK;
+ uLong uMagic;
+ long lSeek=0;
+ uLong uL;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (ZSEEK64(s->z_filefunc, s->filestream,
+ s->pos_in_central_dir+s->byte_before_the_zipfile,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=UNZ_ERRNO;
+
+
+ /* we check the magic */
+ if (err==UNZ_OK)
+ {
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if (uMagic!=0x02014b50)
+ err=UNZ_BADZIPFILE;
+ }
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info.compressed_size = uL;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info.uncompressed_size = uL;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ // relative offset of local header
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ file_info_internal.offset_curfile = uL;
+
+ lSeek+=file_info.size_filename;
+ if ((err==UNZ_OK) && (szFileName!=NULL))
+ {
+ uLong uSizeRead ;
+ if (file_info.size_filename<fileNameBufferSize)
+ {
+ *(szFileName+file_info.size_filename)='\0';
+ uSizeRead = file_info.size_filename;
+ }
+ else
+ uSizeRead = fileNameBufferSize;
+
+ if ((file_info.size_filename>0) && (fileNameBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+ lSeek -= uSizeRead;
+ }
+
+ // Read extrafield
+ if ((err==UNZ_OK) && (extraField!=NULL))
+ {
+ ZPOS64_T uSizeRead ;
+ if (file_info.size_file_extra<extraFieldBufferSize)
+ uSizeRead = file_info.size_file_extra;
+ else
+ uSizeRead = extraFieldBufferSize;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+
+ lSeek += file_info.size_file_extra - (uLong)uSizeRead;
+ }
+ else
+ lSeek += file_info.size_file_extra;
+
+
+ if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
+ {
+ uLong acc = 0;
+
+ // since lSeek now points to after the extra field we need to move back
+ lSeek -= file_info.size_file_extra;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ while(acc < file_info.size_file_extra)
+ {
+ uLong headerId;
+ uLong dataSize;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ /* ZIP64 extra fields */
+ if (headerId == 0x0001)
+ {
+ uLong uL;
+
+ if(file_info.uncompressed_size == MAXU32)
+ {
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info.compressed_size == MAXU32)
+ {
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info_internal.offset_curfile == MAXU32)
+ {
+ /* Relative Header offset */
+ if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ if(file_info.disk_num_start == MAXU32)
+ {
+ /* Disk Start Number */
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+ err=UNZ_ERRNO;
+ }
+
+ }
+ else
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
+ err=UNZ_ERRNO;
+ }
+
+ acc += 2 + 2 + dataSize;
+ }
+ }
+
+ if ((err==UNZ_OK) && (szComment!=NULL))
+ {
+ uLong uSizeRead ;
+ if (file_info.size_file_comment<commentBufferSize)
+ {
+ *(szComment+file_info.size_file_comment)='\0';
+ uSizeRead = file_info.size_file_comment;
+ }
+ else
+ uSizeRead = commentBufferSize;
+
+ if (lSeek!=0)
+ {
+ if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+ lSeek=0;
+ else
+ err=UNZ_ERRNO;
+ }
+
+ if ((file_info.size_file_comment>0) && (commentBufferSize>0))
+ if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
+ err=UNZ_ERRNO;
+ lSeek+=file_info.size_file_comment - uSizeRead;
+ }
+ else
+ lSeek+=file_info.size_file_comment;
+
+
+ if ((err==UNZ_OK) && (pfile_info!=NULL))
+ *pfile_info=file_info;
+
+ if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
+ *pfile_info_internal=file_info_internal;
+
+ return err;
+}
+
+
+
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem.
+*/
+extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
+ unz_file_info64 * pfile_info,
+ char * szFileName, uLong fileNameBufferSize,
+ void *extraField, uLong extraFieldBufferSize,
+ char* szComment, uLong commentBufferSize)
+{
+ return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
+ szFileName,fileNameBufferSize,
+ extraField,extraFieldBufferSize,
+ szComment,commentBufferSize);
+}
+
+extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
+ unz_file_info * pfile_info,
+ char * szFileName, uLong fileNameBufferSize,
+ void *extraField, uLong extraFieldBufferSize,
+ char* szComment, uLong commentBufferSize)
+{
+ int err;
+ unz_file_info64 file_info64;
+ err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
+ szFileName,fileNameBufferSize,
+ extraField,extraFieldBufferSize,
+ szComment,commentBufferSize);
+ if ((err==UNZ_OK) && (pfile_info != NULL))
+ {
+ pfile_info->version = file_info64.version;
+ pfile_info->version_needed = file_info64.version_needed;
+ pfile_info->flag = file_info64.flag;
+ pfile_info->compression_method = file_info64.compression_method;
+ pfile_info->dosDate = file_info64.dosDate;
+ pfile_info->crc = file_info64.crc;
+
+ pfile_info->size_filename = file_info64.size_filename;
+ pfile_info->size_file_extra = file_info64.size_file_extra;
+ pfile_info->size_file_comment = file_info64.size_file_comment;
+
+ pfile_info->disk_num_start = file_info64.disk_num_start;
+ pfile_info->internal_fa = file_info64.internal_fa;
+ pfile_info->external_fa = file_info64.external_fa;
+
+ pfile_info->tmu_date = file_info64.tmu_date,
+
+
+ pfile_info->compressed_size = (uLong)file_info64.compressed_size;
+ pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
+
+ }
+ return err;
+}
+/*
+ Set the current file of the zipfile to the first file.
+ return UNZ_OK if there is no problem
+*/
+extern int ZEXPORT unzGoToFirstFile (unzFile file)
+{
+ int err=UNZ_OK;
+ unz64_s* s;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ s->pos_in_central_dir=s->offset_central_dir;
+ s->num_file=0;
+ err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+/*
+ Set the current file of the zipfile to the next file.
+ return UNZ_OK if there is no problem
+ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+extern int ZEXPORT unzGoToNextFile (unzFile file)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+ if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
+ if (s->num_file+1==s->gi.number_entry)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
+ s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
+ s->num_file++;
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+
+/*
+ Try locate the file szFileName in the zipfile.
+ For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+ return value :
+ UNZ_OK if the file is found. It becomes the current file.
+ UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
+{
+ unz64_s* s;
+ int err;
+
+ /* We remember the 'current' position in the file so that we can jump
+ * back there if we fail.
+ */
+ unz_file_info64 cur_file_infoSaved;
+ unz_file_info64_internal cur_file_info_internalSaved;
+ ZPOS64_T num_fileSaved;
+ ZPOS64_T pos_in_central_dirSaved;
+
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+
+ if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
+ return UNZ_PARAMERROR;
+
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ /* Save the current state */
+ num_fileSaved = s->num_file;
+ pos_in_central_dirSaved = s->pos_in_central_dir;
+ cur_file_infoSaved = s->cur_file_info;
+ cur_file_info_internalSaved = s->cur_file_info_internal;
+
+ err = unzGoToFirstFile(file);
+
+ while (err == UNZ_OK)
+ {
+ char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
+ err = unzGetCurrentFileInfo64(file,NULL,
+ szCurrentFileName,sizeof(szCurrentFileName)-1,
+ NULL,0,NULL,0);
+ if (err == UNZ_OK)
+ {
+ if (unzStringFileNameCompare(szCurrentFileName,
+ szFileName,iCaseSensitivity)==0)
+ return UNZ_OK;
+ err = unzGoToNextFile(file);
+ }
+ }
+
+ /* We failed, so restore the state of the 'current file' to where we
+ * were.
+ */
+ s->num_file = num_fileSaved ;
+ s->pos_in_central_dir = pos_in_central_dirSaved ;
+ s->cur_file_info = cur_file_infoSaved;
+ s->cur_file_info_internal = cur_file_info_internalSaved;
+ return err;
+}
+
+
+/*
+///////////////////////////////////////////
+// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
+// I need random access
+//
+// Further optimization could be realized by adding an ability
+// to cache the directory in memory. The goal being a single
+// comprehensive file read to put the file I need in a memory.
+*/
+
+/*
+typedef struct unz_file_pos_s
+{
+ ZPOS64_T pos_in_zip_directory; // offset in file
+ ZPOS64_T num_of_file; // # of file
+} unz_file_pos;
+*/
+
+extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos)
+{
+ unz64_s* s;
+
+ if (file==NULL || file_pos==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_END_OF_LIST_OF_FILE;
+
+ file_pos->pos_in_zip_directory = s->pos_in_central_dir;
+ file_pos->num_of_file = s->num_file;
+
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetFilePos(
+ unzFile file,
+ unz_file_pos* file_pos)
+{
+ unz64_file_pos file_pos64;
+ int err = unzGetFilePos64(file,&file_pos64);
+ if (err==UNZ_OK)
+ {
+ file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
+ file_pos->num_of_file = (uLong)file_pos64.num_of_file;
+ }
+ return err;
+}
+
+extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL || file_pos==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ /* jump to the right spot */
+ s->pos_in_central_dir = file_pos->pos_in_zip_directory;
+ s->num_file = file_pos->num_of_file;
+
+ /* set the current file */
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ /* return results */
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+extern int ZEXPORT unzGoToFilePos(
+ unzFile file,
+ unz_file_pos* file_pos)
+{
+ unz64_file_pos file_pos64;
+ if (file_pos == NULL)
+ return UNZ_PARAMERROR;
+
+ file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
+ file_pos64.num_of_file = file_pos->num_of_file;
+ return unzGoToFilePos64(file,&file_pos64);
+}
+
+/*
+// Unzip Helper Functions - should be here?
+///////////////////////////////////////////
+*/
+
+/*
+ Read the local header of the current zipfile
+ Check the coherency of the local header and info in the end of central
+ directory about this file
+ store in *piSizeVar the size of extra info in local header
+ (filename and size of extra field data)
+*/
+local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
+ ZPOS64_T * poffset_local_extrafield,
+ uInt * psize_local_extrafield)
+{
+ uLong uMagic,uData,uFlags;
+ uLong size_filename;
+ uLong size_extra_field;
+ int err=UNZ_OK;
+
+ *piSizeVar = 0;
+ *poffset_local_extrafield = 0;
+ *psize_local_extrafield = 0;
+
+ if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
+ s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+
+ if (err==UNZ_OK)
+ {
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if (uMagic!=0x04034b50)
+ err=UNZ_BADZIPFILE;
+ }
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+ err=UNZ_ERRNO;
+/*
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
+ err=UNZ_BADZIPFILE;
+*/
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
+ err=UNZ_ERRNO;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
+ err=UNZ_BADZIPFILE;
+
+ if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+ (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+ (s->cur_file_info.compression_method!=Z_DEFLATED))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
+ err=UNZ_ERRNO;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
+ err=UNZ_ERRNO;
+ else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
+ err=UNZ_ERRNO;
+ else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
+ err=UNZ_BADZIPFILE;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
+ err=UNZ_ERRNO;
+ else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
+ err=UNZ_BADZIPFILE;
+
+ *piSizeVar += (uInt)size_filename;
+
+ if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
+ err=UNZ_ERRNO;
+ *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
+ SIZEZIPLOCALHEADER + size_filename;
+ *psize_local_extrafield = (uInt)size_extra_field;
+
+ *piSizeVar += (uInt)size_extra_field;
+
+ return err;
+}
+
+/*
+ Open for reading data the current file in the zipfile.
+ If there is no error and the file is opened, the return value is UNZ_OK.
+*/
+extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
+ int* level, int raw, const char* password)
+{
+ int err=UNZ_OK;
+ uInt iSizeVar;
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ ZPOS64_T offset_local_extrafield; /* offset of the local extra field */
+ uInt size_local_extrafield; /* size of the local extra field */
+# ifndef NOUNCRYPT
+ char source[12];
+# else
+ if (password != NULL)
+ return UNZ_PARAMERROR;
+# endif
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return UNZ_PARAMERROR;
+
+ if (s->pfile_in_zip_read != NULL)
+ unzCloseCurrentFile(file);
+
+ if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
+ return UNZ_BADZIPFILE;
+
+ pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_INTERNALERROR;
+
+ pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
+ pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
+ pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
+ pfile_in_zip_read_info->pos_local_extrafield=0;
+ pfile_in_zip_read_info->raw=raw;
+
+ if (pfile_in_zip_read_info->read_buffer==NULL)
+ {
+ TRYFREE(pfile_in_zip_read_info);
+ return UNZ_INTERNALERROR;
+ }
+
+ pfile_in_zip_read_info->stream_initialised=0;
+
+ if (method!=NULL)
+ *method = (int)s->cur_file_info.compression_method;
+
+ if (level!=NULL)
+ {
+ *level = 6;
+ switch (s->cur_file_info.flag & 0x06)
+ {
+ case 6 : *level = 1; break;
+ case 4 : *level = 2; break;
+ case 2 : *level = 9; break;
+ }
+ }
+
+ if ((s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+ (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+ (s->cur_file_info.compression_method!=Z_DEFLATED))
+
+ err=UNZ_BADZIPFILE;
+
+ pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
+ pfile_in_zip_read_info->crc32=0;
+ pfile_in_zip_read_info->total_out_64=0;
+ pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
+ pfile_in_zip_read_info->filestream=s->filestream;
+ pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
+ pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
+
+ pfile_in_zip_read_info->stream.total_out = 0;
+
+ if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
+ {
+#ifdef HAVE_BZIP2
+ pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
+ pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
+ pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->bstream.state = (voidpf)0;
+
+ pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+ pfile_in_zip_read_info->stream.zfree = (free_func)0;
+ pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->stream.next_in = (voidpf)0;
+ pfile_in_zip_read_info->stream.avail_in = 0;
+
+ err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
+ if (err == Z_OK)
+ pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
+ else
+ {
+ TRYFREE(pfile_in_zip_read_info);
+ return err;
+ }
+#else
+ pfile_in_zip_read_info->raw=1;
+#endif
+ }
+ else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
+ {
+ pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+ pfile_in_zip_read_info->stream.zfree = (free_func)0;
+ pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+ pfile_in_zip_read_info->stream.next_in = 0;
+ pfile_in_zip_read_info->stream.avail_in = 0;
+
+ err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
+ if (err == Z_OK)
+ pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
+ else
+ {
+ TRYFREE(pfile_in_zip_read_info);
+ return err;
+ }
+ /* windowBits is passed < 0 to tell that there is no zlib header.
+ * Note that in this case inflate *requires* an extra "dummy" byte
+ * after the compressed stream in order to complete decompression and
+ * return Z_STREAM_END.
+ * In unzip, i don't wait absolutely Z_STREAM_END because I known the
+ * size of both compressed and uncompressed data
+ */
+ }
+ pfile_in_zip_read_info->rest_read_compressed =
+ s->cur_file_info.compressed_size ;
+ pfile_in_zip_read_info->rest_read_uncompressed =
+ s->cur_file_info.uncompressed_size ;
+
+
+ pfile_in_zip_read_info->pos_in_zipfile =
+ s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
+ iSizeVar;
+
+ pfile_in_zip_read_info->stream.avail_in = (uInt)0;
+
+ s->pfile_in_zip_read = pfile_in_zip_read_info;
+ s->encrypted = 0;
+
+# ifndef NOUNCRYPT
+ if (password != NULL)
+ {
+ int i;
+ s->pcrc_32_tab = get_crc_table();
+ init_keys(password,s->keys,s->pcrc_32_tab);
+ if (ZSEEK64(s->z_filefunc, s->filestream,
+ s->pfile_in_zip_read->pos_in_zipfile +
+ s->pfile_in_zip_read->byte_before_the_zipfile,
+ SEEK_SET)!=0)
+ return UNZ_INTERNALERROR;
+ if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
+ return UNZ_INTERNALERROR;
+
+ for (i = 0; i<12; i++)
+ zdecode(s->keys,s->pcrc_32_tab,source[i]);
+
+ s->pfile_in_zip_read->pos_in_zipfile+=12;
+ s->encrypted=1;
+ }
+# endif
+
+
+ return UNZ_OK;
+}
+
+extern int ZEXPORT unzOpenCurrentFile (unzFile file)
+{
+ return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
+}
+
+extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password)
+{
+ return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
+}
+
+extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
+{
+ return unzOpenCurrentFile3(file, method, level, raw, NULL);
+}
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ s=(unz64_s*)file;
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+ if (pfile_in_zip_read_info==NULL)
+ return 0; //UNZ_PARAMERROR;
+ return pfile_in_zip_read_info->pos_in_zipfile +
+ pfile_in_zip_read_info->byte_before_the_zipfile;
+}
+
+/** Addition for GDAL : END */
+
+/*
+ Read bytes from the current file.
+ buf contain buffer where data must be copied
+ len the size of buf.
+
+ return the number of byte copied if somes bytes are copied
+ return 0 if the end of file was reached
+ return <0 with error code if there is an error
+ (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len)
+{
+ int err=UNZ_OK;
+ uInt iRead = 0;
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+
+ if (pfile_in_zip_read_info->read_buffer == NULL)
+ return UNZ_END_OF_LIST_OF_FILE;
+ if (len==0)
+ return 0;
+
+ pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+
+ pfile_in_zip_read_info->stream.avail_out = (uInt)len;
+
+ if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
+ (!(pfile_in_zip_read_info->raw)))
+ pfile_in_zip_read_info->stream.avail_out =
+ (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
+
+ if ((len>pfile_in_zip_read_info->rest_read_compressed+
+ pfile_in_zip_read_info->stream.avail_in) &&
+ (pfile_in_zip_read_info->raw))
+ pfile_in_zip_read_info->stream.avail_out =
+ (uInt)pfile_in_zip_read_info->rest_read_compressed+
+ pfile_in_zip_read_info->stream.avail_in;
+
+ while (pfile_in_zip_read_info->stream.avail_out>0)
+ {
+ if ((pfile_in_zip_read_info->stream.avail_in==0) &&
+ (pfile_in_zip_read_info->rest_read_compressed>0))
+ {
+ uInt uReadThis = UNZ_BUFSIZE;
+ if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
+ uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
+ if (uReadThis == 0)
+ return UNZ_EOF;
+ if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->pos_in_zipfile +
+ pfile_in_zip_read_info->byte_before_the_zipfile,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+ if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->read_buffer,
+ uReadThis)!=uReadThis)
+ return UNZ_ERRNO;
+
+
+# ifndef NOUNCRYPT
+ if(s->encrypted)
+ {
+ uInt i;
+ for(i=0;i<uReadThis;i++)
+ pfile_in_zip_read_info->read_buffer[i] =
+ zdecode(s->keys,s->pcrc_32_tab,
+ pfile_in_zip_read_info->read_buffer[i]);
+ }
+# endif
+
+
+ pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+ pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
+
+ pfile_in_zip_read_info->stream.next_in =
+ (Bytef*)pfile_in_zip_read_info->read_buffer;
+ pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
+ }
+
+ if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
+ {
+ uInt uDoCopy,i ;
+
+ if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
+ (pfile_in_zip_read_info->rest_read_compressed == 0))
+ return (iRead==0) ? UNZ_EOF : iRead;
+
+ if (pfile_in_zip_read_info->stream.avail_out <
+ pfile_in_zip_read_info->stream.avail_in)
+ uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
+ else
+ uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
+
+ for (i=0;i<uDoCopy;i++)
+ *(pfile_in_zip_read_info->stream.next_out+i) =
+ *(pfile_in_zip_read_info->stream.next_in+i);
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
+
+ pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
+ pfile_in_zip_read_info->stream.next_out,
+ uDoCopy);
+ pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
+ pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
+ pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
+ pfile_in_zip_read_info->stream.next_out += uDoCopy;
+ pfile_in_zip_read_info->stream.next_in += uDoCopy;
+ pfile_in_zip_read_info->stream.total_out += uDoCopy;
+ iRead += uDoCopy;
+ }
+ else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
+ {
+#ifdef HAVE_BZIP2
+ uLong uTotalOutBefore,uTotalOutAfter;
+ const Bytef *bufBefore;
+ uLong uOutThis;
+
+ pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in;
+ pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in;
+ pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in;
+ pfile_in_zip_read_info->bstream.total_in_hi32 = 0;
+ pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out;
+ pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out;
+ pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
+ pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
+
+ uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
+ bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
+
+ err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
+
+ uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
+ uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+ pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
+ pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
+ iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+ pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
+ pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in;
+ pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32;
+ pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
+ pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
+ pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
+
+ if (err==BZ_STREAM_END)
+ return (iRead==0) ? UNZ_EOF : iRead;
+ if (err!=BZ_OK)
+ break;
+#endif
+ } // end Z_BZIP2ED
+ else
+ {
+ ZPOS64_T uTotalOutBefore,uTotalOutAfter;
+ const Bytef *bufBefore;
+ ZPOS64_T uOutThis;
+ int flush=Z_SYNC_FLUSH;
+
+ uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
+ bufBefore = pfile_in_zip_read_info->stream.next_out;
+
+ /*
+ if ((pfile_in_zip_read_info->rest_read_uncompressed ==
+ pfile_in_zip_read_info->stream.avail_out) &&
+ (pfile_in_zip_read_info->rest_read_compressed == 0))
+ flush = Z_FINISH;
+ */
+ err=inflate(&pfile_in_zip_read_info->stream,flush);
+
+ if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
+ err = Z_DATA_ERROR;
+
+ uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+ uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+ pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+ pfile_in_zip_read_info->crc32 =
+ crc32(pfile_in_zip_read_info->crc32,bufBefore,
+ (uInt)(uOutThis));
+
+ pfile_in_zip_read_info->rest_read_uncompressed -=
+ uOutThis;
+
+ iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+ if (err==Z_STREAM_END)
+ return (iRead==0) ? UNZ_EOF : iRead;
+ if (err!=Z_OK)
+ break;
+ }
+ }
+
+ if (err==Z_OK)
+ return iRead;
+ return err;
+}
+
+
+/*
+ Give the current position in uncompressed data
+*/
+extern z_off_t ZEXPORT unztell (unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ return (z_off_t)pfile_in_zip_read_info->stream.total_out;
+}
+
+extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
+{
+
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return (ZPOS64_T)-1;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return (ZPOS64_T)-1;
+
+ return pfile_in_zip_read_info->total_out_64;
+}
+
+
+/*
+ return 1 if the end of file was reached, 0 elsewhere
+*/
+extern int ZEXPORT unzeof (unzFile file)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+ return 1;
+ else
+ return 0;
+}
+
+
+
+/*
+Read extra field from the current file (opened by unzOpenCurrentFile)
+This is the local-header version of the extra field (sometimes, there is
+more info in the local-header version than in the central-header)
+
+ if buf==NULL, it return the size of the local extra field that can be read
+
+ if buf!=NULL, len is the size of the buffer, the extra header is copied in
+ buf.
+ the return value is the number of bytes copied in buf, or (if <0)
+ the error code
+*/
+extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
+{
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ uInt read_now;
+ ZPOS64_T size_to_read;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+ size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
+ pfile_in_zip_read_info->pos_local_extrafield);
+
+ if (buf==NULL)
+ return (int)size_to_read;
+
+ if (len>size_to_read)
+ read_now = (uInt)size_to_read;
+ else
+ read_now = (uInt)len ;
+
+ if (read_now==0)
+ return 0;
+
+ if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ pfile_in_zip_read_info->offset_local_extrafield +
+ pfile_in_zip_read_info->pos_local_extrafield,
+ ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+ if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+ pfile_in_zip_read_info->filestream,
+ buf,read_now)!=read_now)
+ return UNZ_ERRNO;
+
+ return (int)read_now;
+}
+
+/*
+ Close the file in zip opened with unzOpenCurrentFile
+ Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+extern int ZEXPORT unzCloseCurrentFile (unzFile file)
+{
+ int err=UNZ_OK;
+
+ unz64_s* s;
+ file_in_zip64_read_info_s* pfile_in_zip_read_info;
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+ if (pfile_in_zip_read_info==NULL)
+ return UNZ_PARAMERROR;
+
+
+ if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
+ (!pfile_in_zip_read_info->raw))
+ {
+ if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
+ err=UNZ_CRCERROR;
+ }
+
+
+ TRYFREE(pfile_in_zip_read_info->read_buffer);
+ pfile_in_zip_read_info->read_buffer = NULL;
+ if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
+ inflateEnd(&pfile_in_zip_read_info->stream);
+#ifdef HAVE_BZIP2
+ else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
+ BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
+#endif
+
+
+ pfile_in_zip_read_info->stream_initialised = 0;
+ TRYFREE(pfile_in_zip_read_info);
+
+ s->pfile_in_zip_read=NULL;
+
+ return err;
+}
+
+
+/*
+ Get the global comment string of the ZipFile, in the szComment buffer.
+ uSizeBuf is the size of the szComment buffer.
+ return the number of byte copied or an error code <0
+*/
+extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
+{
+ unz64_s* s;
+ uLong uReadThis ;
+ if (file==NULL)
+ return (int)UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ uReadThis = uSizeBuf;
+ if (uReadThis>s->gi.size_comment)
+ uReadThis = s->gi.size_comment;
+
+ if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return UNZ_ERRNO;
+
+ if (uReadThis>0)
+ {
+ *szComment='\0';
+ if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
+ return UNZ_ERRNO;
+ }
+
+ if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
+ *(szComment+s->gi.size_comment)='\0';
+ return (int)uReadThis;
+}
+
+/* Additions by RX '2004 */
+extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
+{
+ unz64_s* s;
+
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+ if (!s->current_file_ok)
+ return 0;
+ if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
+ if (s->num_file==s->gi.number_entry)
+ return 0;
+ return s->pos_in_central_dir;
+}
+
+extern uLong ZEXPORT unzGetOffset (unzFile file)
+{
+ ZPOS64_T offset64;
+
+ if (file==NULL)
+ return 0; //UNZ_PARAMERROR;
+ offset64 = unzGetOffset64(file);
+ return (uLong)offset64;
+}
+
+extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
+{
+ unz64_s* s;
+ int err;
+
+ if (file==NULL)
+ return UNZ_PARAMERROR;
+ s=(unz64_s*)file;
+
+ s->pos_in_central_dir = pos;
+ s->num_file = s->gi.number_entry; /* hack */
+ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+ &s->cur_file_info_internal,
+ NULL,0,NULL,0,NULL,0);
+ s->current_file_ok = (err == UNZ_OK);
+ return err;
+}
+
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
+{
+ return unzSetOffset64(file,pos);
+}
diff --git a/xs/src/png/zlib/contrib/minizip/unzip.h b/xs/src/png/zlib/contrib/minizip/unzip.h
new file mode 100644
index 000000000..2104e3915
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/unzip.h
@@ -0,0 +1,437 @@
+/* unzip.h -- IO for uncompress .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications of Unzip for Zip64
+ Copyright (C) 2007-2008 Even Rouault
+
+ Modifications for Zip64 support on both zip and unzip
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ ---------------------------------------------------------------------------------
+
+ Condition of use and distribution are the same than zlib :
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ ---------------------------------------------------------------------------------
+
+ Changes
+
+ See header of unzip64.c
+
+*/
+
+#ifndef _unz64_H
+#define _unz64_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+ from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#define UNZ_OK (0)
+#define UNZ_END_OF_LIST_OF_FILE (-100)
+#define UNZ_ERRNO (Z_ERRNO)
+#define UNZ_EOF (0)
+#define UNZ_PARAMERROR (-102)
+#define UNZ_BADZIPFILE (-103)
+#define UNZ_INTERNALERROR (-104)
+#define UNZ_CRCERROR (-105)
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s
+{
+ uInt tm_sec; /* seconds after the minute - [0,59] */
+ uInt tm_min; /* minutes after the hour - [0,59] */
+ uInt tm_hour; /* hours since midnight - [0,23] */
+ uInt tm_mday; /* day of the month - [1,31] */
+ uInt tm_mon; /* months since January - [0,11] */
+ uInt tm_year; /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+ These data comes from the end of central dir */
+typedef struct unz_global_info64_s
+{
+ ZPOS64_T number_entry; /* total number of entries in
+ the central dir on this disk */
+ uLong size_comment; /* size of the global comment of the zipfile */
+} unz_global_info64;
+
+typedef struct unz_global_info_s
+{
+ uLong number_entry; /* total number of entries in
+ the central dir on this disk */
+ uLong size_comment; /* size of the global comment of the zipfile */
+} unz_global_info;
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info64_s
+{
+ uLong version; /* version made by 2 bytes */
+ uLong version_needed; /* version needed to extract 2 bytes */
+ uLong flag; /* general purpose bit flag 2 bytes */
+ uLong compression_method; /* compression method 2 bytes */
+ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
+ uLong crc; /* crc-32 4 bytes */
+ ZPOS64_T compressed_size; /* compressed size 8 bytes */
+ ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */
+ uLong size_filename; /* filename length 2 bytes */
+ uLong size_file_extra; /* extra field length 2 bytes */
+ uLong size_file_comment; /* file comment length 2 bytes */
+
+ uLong disk_num_start; /* disk number start 2 bytes */
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+
+ tm_unz tmu_date;
+} unz_file_info64;
+
+typedef struct unz_file_info_s
+{
+ uLong version; /* version made by 2 bytes */
+ uLong version_needed; /* version needed to extract 2 bytes */
+ uLong flag; /* general purpose bit flag 2 bytes */
+ uLong compression_method; /* compression method 2 bytes */
+ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
+ uLong crc; /* crc-32 4 bytes */
+ uLong compressed_size; /* compressed size 4 bytes */
+ uLong uncompressed_size; /* uncompressed size 4 bytes */
+ uLong size_filename; /* filename length 2 bytes */
+ uLong size_file_extra; /* extra field length 2 bytes */
+ uLong size_file_comment; /* file comment length 2 bytes */
+
+ uLong disk_num_start; /* disk number start 2 bytes */
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+
+ tm_unz tmu_date;
+} unz_file_info;
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+ const char* fileName2,
+ int iCaseSensitivity));
+/*
+ Compare two filename (fileName1,fileName2).
+ If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+ If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+ or strcasecmp)
+ If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+ (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+extern unzFile ZEXPORT unzOpen64 OF((const void *path));
+/*
+ Open a Zip file. path contain the full pathname (by example,
+ on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
+ "zlib/zlib113.zip".
+ If the zipfile cannot be opened (file don't exist or in not valid), the
+ return value is NULL.
+ Else, the return value is a unzFile Handle, usable with other function
+ of this unzip package.
+ the "64" function take a const void* pointer, because the path is just the
+ value passed to the open64_file_func callback.
+ Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
+ is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
+ does not describe the reality
+*/
+
+
+extern unzFile ZEXPORT unzOpen2 OF((const char *path,
+ zlib_filefunc_def* pzlib_filefunc_def));
+/*
+ Open a Zip file, like unzOpen, but provide a set of file low level API
+ for read/write the zip file (see ioapi.h)
+*/
+
+extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
+ zlib_filefunc64_def* pzlib_filefunc_def));
+/*
+ Open a Zip file, like unz64Open, but provide a set of file low level API
+ for read/write the zip file (see ioapi.h)
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+ Close a ZipFile opened with unzOpen.
+ If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+ these files MUST be closed with unzCloseCurrentFile before call unzClose.
+ return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+ unz_global_info *pglobal_info));
+
+extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
+ unz_global_info64 *pglobal_info));
+/*
+ Write info about the ZipFile in the *pglobal_info structure.
+ No preparation of the structure is needed
+ return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+ char *szComment,
+ uLong uSizeBuf));
+/*
+ Get the global comment string of the ZipFile, in the szComment buffer.
+ uSizeBuf is the size of the szComment buffer.
+ return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+ Set the current file of the zipfile to the first file.
+ return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+ Set the current file of the zipfile to the next file.
+ return UNZ_OK if there is no problem
+ return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file,
+ const char *szFileName,
+ int iCaseSensitivity));
+/*
+ Try locate the file szFileName in the zipfile.
+ For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+ return value :
+ UNZ_OK if the file is found. It becomes the current file.
+ UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+/* ****************************************** */
+/* Ryan supplied functions */
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_pos_s
+{
+ uLong pos_in_zip_directory; /* offset in zip file directory */
+ uLong num_of_file; /* # of file */
+} unz_file_pos;
+
+extern int ZEXPORT unzGetFilePos(
+ unzFile file,
+ unz_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos(
+ unzFile file,
+ unz_file_pos* file_pos);
+
+typedef struct unz64_file_pos_s
+{
+ ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */
+ ZPOS64_T num_of_file; /* # of file */
+} unz64_file_pos;
+
+extern int ZEXPORT unzGetFilePos64(
+ unzFile file,
+ unz64_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos64(
+ unzFile file,
+ const unz64_file_pos* file_pos);
+
+/* ****************************************** */
+
+extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
+ unz_file_info64 *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+ unz_file_info *pfile_info,
+ char *szFileName,
+ uLong fileNameBufferSize,
+ void *extraField,
+ uLong extraFieldBufferSize,
+ char *szComment,
+ uLong commentBufferSize));
+/*
+ Get Info about the current file
+ if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+ the current file
+ if szFileName!=NULL, the filemane string will be copied in szFileName
+ (fileNameBufferSize is the size of the buffer)
+ if extraField!=NULL, the extra field information will be copied in extraField
+ (extraFieldBufferSize is the size of the buffer).
+ This is the Central-header version of the extra field
+ if szComment!=NULL, the comment string of the file will be copied in szComment
+ (commentBufferSize is the size of the buffer)
+*/
+
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
+
+/** Addition for GDAL : END */
+
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+ from it, and close it (you can close it before reading all the file)
+ */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+ Open for reading data the current file in the zipfile.
+ If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
+ const char* password));
+/*
+ Open for reading data the current file in the zipfile.
+ password is a crypting password
+ If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
+ int* method,
+ int* level,
+ int raw));
+/*
+ Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+ if raw==1
+ *method will receive method of compression, *level will receive level of
+ compression
+ note : you can set level parameter as NULL (if you did not want known level,
+ but you CANNOT set method parameter as NULL
+*/
+
+extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
+ int* method,
+ int* level,
+ int raw,
+ const char* password));
+/*
+ Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+ if raw==1
+ *method will receive method of compression, *level will receive level of
+ compression
+ note : you can set level parameter as NULL (if you did not want known level,
+ but you CANNOT set method parameter as NULL
+*/
+
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+ Close the file in zip opened with unzOpenCurrentFile
+ Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
+ voidp buf,
+ unsigned len));
+/*
+ Read bytes from the current file (opened by unzOpenCurrentFile)
+ buf contain buffer where data must be copied
+ len the size of buf.
+
+ return the number of byte copied if somes bytes are copied
+ return 0 if the end of file was reached
+ return <0 with error code if there is an error
+ (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+
+extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
+/*
+ Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+ return 1 if the end of file was reached, 0 elsewhere
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+ voidp buf,
+ unsigned len));
+/*
+ Read extra field from the current file (opened by unzOpenCurrentFile)
+ This is the local-header version of the extra field (sometimes, there is
+ more info in the local-header version than in the central-header)
+
+ if buf==NULL, it return the size of the local extra field
+
+ if buf!=NULL, len is the size of the buffer, the extra header is copied in
+ buf.
+ the return value is the number of bytes copied in buf, or (if <0)
+ the error code
+*/
+
+/***************************************************************************/
+
+/* Get the current file offset */
+extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
+extern uLong ZEXPORT unzGetOffset (unzFile file);
+
+/* Set the current file offset */
+extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz64_H */
diff --git a/xs/src/png/zlib/contrib/minizip/zip.c b/xs/src/png/zlib/contrib/minizip/zip.c
new file mode 100644
index 000000000..44e88a9cb
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/zip.c
@@ -0,0 +1,2007 @@
+/* zip.c -- IO on .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ Changes
+ Oct-2009 - Mathias Svensson - Remove old C style function prototypes
+ Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
+ Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
+ Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
+ It is used when recreting zip archive with RAW when deleting items from a zip.
+ ZIP64 data is automatically added to items that needs it, and existing ZIP64 data need to be removed.
+ Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
+ Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "zlib.h"
+#include "zip.h"
+
+#ifdef STDC
+# include <stddef.h>
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+ extern int errno;
+#else
+# include <errno.h>
+#endif
+
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+#ifndef VERSIONMADEBY
+# define VERSIONMADEBY (0x0) /* platform depedent */
+#endif
+
+#ifndef Z_BUFSIZE
+#define Z_BUFSIZE (64*1024) //(16384)
+#endif
+
+#ifndef Z_MAXFILENAMEINZIP
+#define Z_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+/*
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+*/
+
+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
+
+
+// NOT sure that this work on ALL platform
+#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
+
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#ifndef DEF_MEM_LEVEL
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+#endif
+const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+
+#define SIZEDATA_INDATABLOCK (4096-(4*4))
+
+#define LOCALHEADERMAGIC (0x04034b50)
+#define CENTRALHEADERMAGIC (0x02014b50)
+#define ENDHEADERMAGIC (0x06054b50)
+#define ZIP64ENDHEADERMAGIC (0x6064b50)
+#define ZIP64ENDLOCHEADERMAGIC (0x7064b50)
+
+#define FLAG_LOCALHEADER_OFFSET (0x06)
+#define CRC_LOCALHEADER_OFFSET (0x0e)
+
+#define SIZECENTRALHEADER (0x2e) /* 46 */
+
+typedef struct linkedlist_datablock_internal_s
+{
+ struct linkedlist_datablock_internal_s* next_datablock;
+ uLong avail_in_this_block;
+ uLong filled_in_this_block;
+ uLong unused; /* for future use and alignment */
+ unsigned char data[SIZEDATA_INDATABLOCK];
+} linkedlist_datablock_internal;
+
+typedef struct linkedlist_data_s
+{
+ linkedlist_datablock_internal* first_block;
+ linkedlist_datablock_internal* last_block;
+} linkedlist_data;
+
+
+typedef struct
+{
+ z_stream stream; /* zLib stream structure for inflate */
+#ifdef HAVE_BZIP2
+ bz_stream bstream; /* bzLib stream structure for bziped */
+#endif
+
+ int stream_initialised; /* 1 is stream is initialised */
+ uInt pos_in_buffered_data; /* last written byte in buffered_data */
+
+ ZPOS64_T pos_local_header; /* offset of the local header of the file
+ currenty writing */
+ char* central_header; /* central header data for the current file */
+ uLong size_centralExtra;
+ uLong size_centralheader; /* size of the central header for cur file */
+ uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
+ uLong flag; /* flag of the file currently writing */
+
+ int method; /* compression method of file currenty wr.*/
+ int raw; /* 1 for directly writing raw data */
+ Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
+ uLong dosDate;
+ uLong crc32;
+ int encrypt;
+ int zip64; /* Add ZIP64 extened information in the extra field */
+ ZPOS64_T pos_zip64extrainfo;
+ ZPOS64_T totalCompressedData;
+ ZPOS64_T totalUncompressedData;
+#ifndef NOCRYPT
+ unsigned long keys[3]; /* keys defining the pseudo-random sequence */
+ const z_crc_t* pcrc_32_tab;
+ int crypt_header_size;
+#endif
+} curfile64_info;
+
+typedef struct
+{
+ zlib_filefunc64_32_def z_filefunc;
+ voidpf filestream; /* io structore of the zipfile */
+ linkedlist_data central_dir;/* datablock with central dir in construction*/
+ int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
+ curfile64_info ci; /* info on the file curretly writing */
+
+ ZPOS64_T begin_pos; /* position of the beginning of the zipfile */
+ ZPOS64_T add_position_when_writing_offset;
+ ZPOS64_T number_entry;
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+ char *globalcomment;
+#endif
+
+} zip64_internal;
+
+
+#ifndef NOCRYPT
+#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+#include "crypt.h"
+#endif
+
+local linkedlist_datablock_internal* allocate_new_datablock()
+{
+ linkedlist_datablock_internal* ldi;
+ ldi = (linkedlist_datablock_internal*)
+ ALLOC(sizeof(linkedlist_datablock_internal));
+ if (ldi!=NULL)
+ {
+ ldi->next_datablock = NULL ;
+ ldi->filled_in_this_block = 0 ;
+ ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
+ }
+ return ldi;
+}
+
+local void free_datablock(linkedlist_datablock_internal* ldi)
+{
+ while (ldi!=NULL)
+ {
+ linkedlist_datablock_internal* ldinext = ldi->next_datablock;
+ TRYFREE(ldi);
+ ldi = ldinext;
+ }
+}
+
+local void init_linkedlist(linkedlist_data* ll)
+{
+ ll->first_block = ll->last_block = NULL;
+}
+
+local void free_linkedlist(linkedlist_data* ll)
+{
+ free_datablock(ll->first_block);
+ ll->first_block = ll->last_block = NULL;
+}
+
+
+local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
+{
+ linkedlist_datablock_internal* ldi;
+ const unsigned char* from_copy;
+
+ if (ll==NULL)
+ return ZIP_INTERNALERROR;
+
+ if (ll->last_block == NULL)
+ {
+ ll->first_block = ll->last_block = allocate_new_datablock();
+ if (ll->first_block == NULL)
+ return ZIP_INTERNALERROR;
+ }
+
+ ldi = ll->last_block;
+ from_copy = (unsigned char*)buf;
+
+ while (len>0)
+ {
+ uInt copy_this;
+ uInt i;
+ unsigned char* to_copy;
+
+ if (ldi->avail_in_this_block==0)
+ {
+ ldi->next_datablock = allocate_new_datablock();
+ if (ldi->next_datablock == NULL)
+ return ZIP_INTERNALERROR;
+ ldi = ldi->next_datablock ;
+ ll->last_block = ldi;
+ }
+
+ if (ldi->avail_in_this_block < len)
+ copy_this = (uInt)ldi->avail_in_this_block;
+ else
+ copy_this = (uInt)len;
+
+ to_copy = &(ldi->data[ldi->filled_in_this_block]);
+
+ for (i=0;i<copy_this;i++)
+ *(to_copy+i)=*(from_copy+i);
+
+ ldi->filled_in_this_block += copy_this;
+ ldi->avail_in_this_block -= copy_this;
+ from_copy += copy_this ;
+ len -= copy_this;
+ }
+ return ZIP_OK;
+}
+
+
+
+/****************************************************************************/
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+/* ===========================================================================
+ Inputs a long in LSB order to the given file
+ nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
+*/
+
+local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
+local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
+{
+ unsigned char buf[8];
+ int n;
+ for (n = 0; n < nbByte; n++)
+ {
+ buf[n] = (unsigned char)(x & 0xff);
+ x >>= 8;
+ }
+ if (x != 0)
+ { /* data overflow - hack for ZIP64 (X Roche) */
+ for (n = 0; n < nbByte; n++)
+ {
+ buf[n] = 0xff;
+ }
+ }
+
+ if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
+ return ZIP_ERRNO;
+ else
+ return ZIP_OK;
+}
+
+local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
+local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
+{
+ unsigned char* buf=(unsigned char*)dest;
+ int n;
+ for (n = 0; n < nbByte; n++) {
+ buf[n] = (unsigned char)(x & 0xff);
+ x >>= 8;
+ }
+
+ if (x != 0)
+ { /* data overflow - hack for ZIP64 */
+ for (n = 0; n < nbByte; n++)
+ {
+ buf[n] = 0xff;
+ }
+ }
+}
+
+/****************************************************************************/
+
+
+local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
+{
+ uLong year = (uLong)ptm->tm_year;
+ if (year>=1980)
+ year-=1980;
+ else if (year>=80)
+ year-=80;
+ return
+ (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
+ ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
+}
+
+
+/****************************************************************************/
+
+local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
+
+local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
+{
+ unsigned char c;
+ int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+ if (err==1)
+ {
+ *pi = (int)c;
+ return ZIP_OK;
+ }
+ else
+ {
+ if (ZERROR64(*pzlib_filefunc_def,filestream))
+ return ZIP_ERRNO;
+ else
+ return ZIP_EOF;
+ }
+}
+
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
+
+local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<8;
+
+ if (err==ZIP_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
+
+local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
+{
+ uLong x ;
+ int i = 0;
+ int err;
+
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (uLong)i;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<8;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<16;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((uLong)i)<<24;
+
+ if (err==ZIP_OK)
+ *pX = x;
+ else
+ *pX = 0;
+ return err;
+}
+
+local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
+
+
+local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
+{
+ ZPOS64_T x;
+ int i = 0;
+ int err;
+
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x = (ZPOS64_T)i;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<8;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<16;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<24;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<32;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<40;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<48;
+
+ if (err==ZIP_OK)
+ err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+ x += ((ZPOS64_T)i)<<56;
+
+ if (err==ZIP_OK)
+ *pX = x;
+ else
+ *pX = 0;
+
+ return err;
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+/*
+ Locate the Central directory of a zipfile (at the end, just before
+ the global comment)
+*/
+local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+
+local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos ;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+ ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+ TRYFREE(buf);
+ return uPosFound;
+}
+
+/*
+Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
+the global comment)
+*/
+local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+
+local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+ unsigned char* buf;
+ ZPOS64_T uSizeFile;
+ ZPOS64_T uBackRead;
+ ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+ ZPOS64_T uPosFound=0;
+ uLong uL;
+ ZPOS64_T relativeOffset;
+
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+ return 0;
+
+ uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+ if (uMaxBack>uSizeFile)
+ uMaxBack = uSizeFile;
+
+ buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+ if (buf==NULL)
+ return 0;
+
+ uBackRead = 4;
+ while (uBackRead<uMaxBack)
+ {
+ uLong uReadSize;
+ ZPOS64_T uReadPos;
+ int i;
+ if (uBackRead+BUFREADCOMMENT>uMaxBack)
+ uBackRead = uMaxBack;
+ else
+ uBackRead+=BUFREADCOMMENT;
+ uReadPos = uSizeFile-uBackRead ;
+
+ uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+ (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+ if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ break;
+
+ if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+ break;
+
+ for (i=(int)uReadSize-3; (i--)>0;)
+ {
+ // Signature "0x07064b50" Zip64 end of central directory locater
+ if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
+ {
+ uPosFound = uReadPos+i;
+ break;
+ }
+ }
+
+ if (uPosFound!=0)
+ break;
+ }
+
+ TRYFREE(buf);
+ if (uPosFound == 0)
+ return 0;
+
+ /* Zip64 end of central directory locator */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature, already checked */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+
+ /* number of the disk with the start of the zip64 end of central directory */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+ if (uL != 0)
+ return 0;
+
+ /* relative offset of the zip64 end of central directory record */
+ if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
+ return 0;
+
+ /* total number of disks */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+ if (uL != 1)
+ return 0;
+
+ /* Goto Zip64 end of central directory record */
+ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ return 0;
+
+ /* the signature */
+ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+ return 0;
+
+ if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
+ return 0;
+
+ return relativeOffset;
+}
+
+int LoadCentralDirectoryRecord(zip64_internal* pziinit)
+{
+ int err=ZIP_OK;
+ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+
+ ZPOS64_T size_central_dir; /* size of the central directory */
+ ZPOS64_T offset_central_dir; /* offset of start of central directory */
+ ZPOS64_T central_pos;
+ uLong uL;
+
+ uLong number_disk; /* number of the current dist, used for
+ spaning ZIP, unsupported, always 0*/
+ uLong number_disk_with_CD; /* number the the disk with central dir, used
+ for spaning ZIP, unsupported, always 0*/
+ ZPOS64_T number_entry;
+ ZPOS64_T number_entry_CD; /* total number of entries in
+ the central dir
+ (same than number_entry on nospan) */
+ uLong VersionMadeBy;
+ uLong VersionNeeded;
+ uLong size_comment;
+
+ int hasZIP64Record = 0;
+
+ // check first if we find a ZIP64 record
+ central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
+ if(central_pos > 0)
+ {
+ hasZIP64Record = 1;
+ }
+ else if(central_pos == 0)
+ {
+ central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
+ }
+
+/* disable to allow appending to empty ZIP archive
+ if (central_pos==0)
+ err=ZIP_ERRNO;
+*/
+
+ if(hasZIP64Record)
+ {
+ ZPOS64_T sizeEndOfCentralDirectory;
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
+ err=ZIP_ERRNO;
+
+ /* the signature, already checked */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* size of zip64 end of central directory record */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* version made by */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* version needed to extract */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of this disk */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* total number of entries in the central directory on this disk */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* total number of entries in the central directory */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
+ err=ZIP_BADZIPFILE;
+
+ /* size of the central directory */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* offset of start of central directory with respect to the
+ starting disk number */
+ if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ // TODO..
+ // read the comment from the standard central header.
+ size_comment = 0;
+ }
+ else
+ {
+ // Read End of central Directory info
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err=ZIP_ERRNO;
+
+ /* the signature, already checked */
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of this disk */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* number of the disk with the start of the central directory */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
+ err=ZIP_ERRNO;
+
+ /* total number of entries in the central dir on this disk */
+ number_entry = 0;
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ number_entry = uL;
+
+ /* total number of entries in the central dir */
+ number_entry_CD = 0;
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ number_entry_CD = uL;
+
+ if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
+ err=ZIP_BADZIPFILE;
+
+ /* size of the central directory */
+ size_central_dir = 0;
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ size_central_dir = uL;
+
+ /* offset of start of central directory with respect to the starting disk number */
+ offset_central_dir = 0;
+ if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ else
+ offset_central_dir = uL;
+
+
+ /* zipfile global comment length */
+ if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
+ err=ZIP_ERRNO;
+ }
+
+ if ((central_pos<offset_central_dir+size_central_dir) &&
+ (err==ZIP_OK))
+ err=ZIP_BADZIPFILE;
+
+ if (err!=ZIP_OK)
+ {
+ ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
+ return ZIP_ERRNO;
+ }
+
+ if (size_comment>0)
+ {
+ pziinit->globalcomment = (char*)ALLOC(size_comment+1);
+ if (pziinit->globalcomment)
+ {
+ size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
+ pziinit->globalcomment[size_comment]=0;
+ }
+ }
+
+ byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
+ pziinit->add_position_when_writing_offset = byte_before_the_zipfile;
+
+ {
+ ZPOS64_T size_central_dir_to_read = size_central_dir;
+ size_t buf_size = SIZEDATA_INDATABLOCK;
+ void* buf_read = (void*)ALLOC(buf_size);
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
+ err=ZIP_ERRNO;
+
+ while ((size_central_dir_to_read>0) && (err==ZIP_OK))
+ {
+ ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
+ if (read_this > size_central_dir_to_read)
+ read_this = size_central_dir_to_read;
+
+ if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
+ err=ZIP_ERRNO;
+
+ if (err==ZIP_OK)
+ err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
+
+ size_central_dir_to_read-=read_this;
+ }
+ TRYFREE(buf_read);
+ }
+ pziinit->begin_pos = byte_before_the_zipfile;
+ pziinit->number_entry = number_entry_CD;
+
+ if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
+ err=ZIP_ERRNO;
+
+ return err;
+}
+
+
+#endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+
+/************************************************************/
+extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
+{
+ zip64_internal ziinit;
+ zip64_internal* zi;
+ int err=ZIP_OK;
+
+ ziinit.z_filefunc.zseek32_file = NULL;
+ ziinit.z_filefunc.ztell32_file = NULL;
+ if (pzlib_filefunc64_32_def==NULL)
+ fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
+ else
+ ziinit.z_filefunc = *pzlib_filefunc64_32_def;
+
+ ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
+ pathname,
+ (append == APPEND_STATUS_CREATE) ?
+ (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
+ (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
+
+ if (ziinit.filestream == NULL)
+ return NULL;
+
+ if (append == APPEND_STATUS_CREATEAFTER)
+ ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
+
+ ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
+ ziinit.in_opened_file_inzip = 0;
+ ziinit.ci.stream_initialised = 0;
+ ziinit.number_entry = 0;
+ ziinit.add_position_when_writing_offset = 0;
+ init_linkedlist(&(ziinit.central_dir));
+
+
+
+ zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
+ if (zi==NULL)
+ {
+ ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
+ return NULL;
+ }
+
+ /* now we add file in a zipfile */
+# ifndef NO_ADDFILEINEXISTINGZIP
+ ziinit.globalcomment = NULL;
+ if (append == APPEND_STATUS_ADDINZIP)
+ {
+ // Read and Cache Central Directory Records
+ err = LoadCentralDirectoryRecord(&ziinit);
+ }
+
+ if (globalcomment)
+ {
+ *globalcomment = ziinit.globalcomment;
+ }
+# endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+ if (err != ZIP_OK)
+ {
+# ifndef NO_ADDFILEINEXISTINGZIP
+ TRYFREE(ziinit.globalcomment);
+# endif /* !NO_ADDFILEINEXISTINGZIP*/
+ TRYFREE(zi);
+ return NULL;
+ }
+ else
+ {
+ *zi = ziinit;
+ return (zipFile)zi;
+ }
+}
+
+extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
+{
+ if (pzlib_filefunc32_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+ return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
+ }
+ else
+ return zipOpen3(pathname, append, globalcomment, NULL);
+}
+
+extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
+{
+ if (pzlib_filefunc_def != NULL)
+ {
+ zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+ zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+ zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+ zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+ return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
+ }
+ else
+ return zipOpen3(pathname, append, globalcomment, NULL);
+}
+
+
+
+extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
+{
+ return zipOpen3((const void*)pathname,append,NULL,NULL);
+}
+
+extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
+{
+ return zipOpen3(pathname,append,NULL,NULL);
+}
+
+int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
+{
+ /* write the local header */
+ int err;
+ uInt size_filename = (uInt)strlen(filename);
+ uInt size_extrafield = size_extrafield_local;
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
+
+ if (err==ZIP_OK)
+ {
+ if(zi->ci.zip64)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
+ }
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
+
+ // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
+ if (err==ZIP_OK)
+ {
+ if(zi->ci.zip64)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
+ }
+ if (err==ZIP_OK)
+ {
+ if(zi->ci.zip64)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
+ }
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
+
+ if(zi->ci.zip64)
+ {
+ size_extrafield += 20;
+ }
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
+
+ if ((err==ZIP_OK) && (size_filename > 0))
+ {
+ if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
+ err = ZIP_ERRNO;
+ }
+
+ if ((err==ZIP_OK) && (size_extrafield_local > 0))
+ {
+ if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
+ err = ZIP_ERRNO;
+ }
+
+
+ if ((err==ZIP_OK) && (zi->ci.zip64))
+ {
+ // write the Zip64 extended info
+ short HeaderID = 1;
+ short DataSize = 16;
+ ZPOS64_T CompressedSize = 0;
+ ZPOS64_T UncompressedSize = 0;
+
+ // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
+ zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
+
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
+ }
+
+ return err;
+}
+
+/*
+ NOTE.
+ When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
+ before calling this function it can be done with zipRemoveExtraInfoBlock
+
+ It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
+ unnecessary allocations.
+ */
+extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting,
+ uLong versionMadeBy, uLong flagBase, int zip64)
+{
+ zip64_internal* zi;
+ uInt size_filename;
+ uInt size_comment;
+ uInt i;
+ int err = ZIP_OK;
+
+# ifdef NOCRYPT
+ (crcForCrypting);
+ if (password != NULL)
+ return ZIP_PARAMERROR;
+# endif
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+
+#ifdef HAVE_BZIP2
+ if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
+ return ZIP_PARAMERROR;
+#else
+ if ((method!=0) && (method!=Z_DEFLATED))
+ return ZIP_PARAMERROR;
+#endif
+
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 1)
+ {
+ err = zipCloseFileInZip (file);
+ if (err != ZIP_OK)
+ return err;
+ }
+
+ if (filename==NULL)
+ filename="-";
+
+ if (comment==NULL)
+ size_comment = 0;
+ else
+ size_comment = (uInt)strlen(comment);
+
+ size_filename = (uInt)strlen(filename);
+
+ if (zipfi == NULL)
+ zi->ci.dosDate = 0;
+ else
+ {
+ if (zipfi->dosDate != 0)
+ zi->ci.dosDate = zipfi->dosDate;
+ else
+ zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
+ }
+
+ zi->ci.flag = flagBase;
+ if ((level==8) || (level==9))
+ zi->ci.flag |= 2;
+ if (level==2)
+ zi->ci.flag |= 4;
+ if (level==1)
+ zi->ci.flag |= 6;
+ if (password != NULL)
+ zi->ci.flag |= 1;
+
+ zi->ci.crc32 = 0;
+ zi->ci.method = method;
+ zi->ci.encrypt = 0;
+ zi->ci.stream_initialised = 0;
+ zi->ci.pos_in_buffered_data = 0;
+ zi->ci.raw = raw;
+ zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
+ zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
+
+ zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
+
+ zi->ci.size_centralExtra = size_extrafield_global;
+ zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
+ /* version info */
+ zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
+ zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
+ zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
+ zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
+ zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
+ zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
+
+ if (zipfi==NULL)
+ zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
+
+ if (zipfi==NULL)
+ zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
+
+ if(zi->ci.pos_local_header >= 0xffffffff)
+ zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writing_offset,4);
+
+ for (i=0;i<size_filename;i++)
+ *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
+
+ for (i=0;i<size_extrafield_global;i++)
+ *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
+ *(((const char*)extrafield_global)+i);
+
+ for (i=0;i<size_comment;i++)
+ *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
+ size_extrafield_global+i) = *(comment+i);
+ if (zi->ci.central_header == NULL)
+ return ZIP_INTERNALERROR;
+
+ zi->ci.zip64 = zip64;
+ zi->ci.totalCompressedData = 0;
+ zi->ci.totalUncompressedData = 0;
+ zi->ci.pos_zip64extrainfo = 0;
+
+ err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
+
+#ifdef HAVE_BZIP2
+ zi->ci.bstream.avail_in = (uInt)0;
+ zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+ zi->ci.bstream.total_in_hi32 = 0;
+ zi->ci.bstream.total_in_lo32 = 0;
+ zi->ci.bstream.total_out_hi32 = 0;
+ zi->ci.bstream.total_out_lo32 = 0;
+#endif
+
+ zi->ci.stream.avail_in = (uInt)0;
+ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.stream.next_out = zi->ci.buffered_data;
+ zi->ci.stream.total_in = 0;
+ zi->ci.stream.total_out = 0;
+ zi->ci.stream.data_type = Z_BINARY;
+
+#ifdef HAVE_BZIP2
+ if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+#else
+ if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+#endif
+ {
+ if(zi->ci.method == Z_DEFLATED)
+ {
+ zi->ci.stream.zalloc = (alloc_func)0;
+ zi->ci.stream.zfree = (free_func)0;
+ zi->ci.stream.opaque = (voidpf)0;
+
+ if (windowBits>0)
+ windowBits = -windowBits;
+
+ err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
+
+ if (err==Z_OK)
+ zi->ci.stream_initialised = Z_DEFLATED;
+ }
+ else if(zi->ci.method == Z_BZIP2ED)
+ {
+#ifdef HAVE_BZIP2
+ // Init BZip stuff here
+ zi->ci.bstream.bzalloc = 0;
+ zi->ci.bstream.bzfree = 0;
+ zi->ci.bstream.opaque = (voidpf)0;
+
+ err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
+ if(err == BZ_OK)
+ zi->ci.stream_initialised = Z_BZIP2ED;
+#endif
+ }
+
+ }
+
+# ifndef NOCRYPT
+ zi->ci.crypt_header_size = 0;
+ if ((err==Z_OK) && (password != NULL))
+ {
+ unsigned char bufHead[RAND_HEAD_LEN];
+ unsigned int sizeHead;
+ zi->ci.encrypt = 1;
+ zi->ci.pcrc_32_tab = get_crc_table();
+ /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
+
+ sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
+ zi->ci.crypt_header_size = sizeHead;
+
+ if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
+ err = ZIP_ERRNO;
+ }
+# endif
+
+ if (err==Z_OK)
+ zi->in_opened_file_inzip = 1;
+ return err;
+}
+
+extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting,
+ uLong versionMadeBy, uLong flagBase)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, versionMadeBy, flagBase, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, VERSIONMADEBY, 0, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw,
+ int windowBits,int memLevel, int strategy,
+ const char* password, uLong crcForCrypting, int zip64)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ windowBits, memLevel, strategy,
+ password, crcForCrypting, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void* extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int raw, int zip64)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, raw,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void*extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level, int zip64)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, 0,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+ const void* extrafield_local, uInt size_extrafield_local,
+ const void*extrafield_global, uInt size_extrafield_global,
+ const char* comment, int method, int level)
+{
+ return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+ extrafield_local, size_extrafield_local,
+ extrafield_global, size_extrafield_global,
+ comment, method, level, 0,
+ -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+ NULL, 0, VERSIONMADEBY, 0, 0);
+}
+
+local int zip64FlushWriteBuffer(zip64_internal* zi)
+{
+ int err=ZIP_OK;
+
+ if (zi->ci.encrypt != 0)
+ {
+#ifndef NOCRYPT
+ uInt i;
+ int t;
+ for (i=0;i<zi->ci.pos_in_buffered_data;i++)
+ zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
+#endif
+ }
+
+ if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
+ err = ZIP_ERRNO;
+
+ zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
+
+#ifdef HAVE_BZIP2
+ if(zi->ci.method == Z_BZIP2ED)
+ {
+ zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
+ zi->ci.bstream.total_in_lo32 = 0;
+ zi->ci.bstream.total_in_hi32 = 0;
+ }
+ else
+#endif
+ {
+ zi->ci.totalUncompressedData += zi->ci.stream.total_in;
+ zi->ci.stream.total_in = 0;
+ }
+
+
+ zi->ci.pos_in_buffered_data = 0;
+
+ return err;
+}
+
+extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
+{
+ zip64_internal* zi;
+ int err=ZIP_OK;
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 0)
+ return ZIP_PARAMERROR;
+
+ zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
+
+#ifdef HAVE_BZIP2
+ if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
+ {
+ zi->ci.bstream.next_in = (void*)buf;
+ zi->ci.bstream.avail_in = len;
+ err = BZ_RUN_OK;
+
+ while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
+ {
+ if (zi->ci.bstream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+ }
+
+
+ if(err != BZ_RUN_OK)
+ break;
+
+ if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+ {
+ uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
+// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
+ err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN);
+
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
+ }
+ }
+
+ if(err == BZ_RUN_OK)
+ err = ZIP_OK;
+ }
+ else
+#endif
+ {
+ zi->ci.stream.next_in = (Bytef*)buf;
+ zi->ci.stream.avail_in = len;
+
+ while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
+ {
+ if (zi->ci.stream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.stream.next_out = zi->ci.buffered_data;
+ }
+
+
+ if(err != ZIP_OK)
+ break;
+
+ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+ {
+ uLong uTotalOutBefore = zi->ci.stream.total_out;
+ err=deflate(&zi->ci.stream, Z_NO_FLUSH);
+ if(uTotalOutBefore > zi->ci.stream.total_out)
+ {
+ int bBreak = 0;
+ bBreak++;
+ }
+
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+ }
+ else
+ {
+ uInt copy_this,i;
+ if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
+ copy_this = zi->ci.stream.avail_in;
+ else
+ copy_this = zi->ci.stream.avail_out;
+
+ for (i = 0; i < copy_this; i++)
+ *(((char*)zi->ci.stream.next_out)+i) =
+ *(((const char*)zi->ci.stream.next_in)+i);
+ {
+ zi->ci.stream.avail_in -= copy_this;
+ zi->ci.stream.avail_out-= copy_this;
+ zi->ci.stream.next_in+= copy_this;
+ zi->ci.stream.next_out+= copy_this;
+ zi->ci.stream.total_in+= copy_this;
+ zi->ci.stream.total_out+= copy_this;
+ zi->ci.pos_in_buffered_data += copy_this;
+ }
+ }
+ }// while(...)
+ }
+
+ return err;
+}
+
+extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
+{
+ return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
+}
+
+extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
+{
+ zip64_internal* zi;
+ ZPOS64_T compressed_size;
+ uLong invalidValue = 0xffffffff;
+ short datasize = 0;
+ int err=ZIP_OK;
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 0)
+ return ZIP_PARAMERROR;
+ zi->ci.stream.avail_in = 0;
+
+ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+ {
+ while (err==ZIP_OK)
+ {
+ uLong uTotalOutBefore;
+ if (zi->ci.stream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.stream.next_out = zi->ci.buffered_data;
+ }
+ uTotalOutBefore = zi->ci.stream.total_out;
+ err=deflate(&zi->ci.stream, Z_FINISH);
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+ }
+ }
+ else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+ {
+#ifdef HAVE_BZIP2
+ err = BZ_FINISH_OK;
+ while (err==BZ_FINISH_OK)
+ {
+ uLong uTotalOutBefore;
+ if (zi->ci.bstream.avail_out == 0)
+ {
+ if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+ zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+ }
+ uTotalOutBefore = zi->ci.bstream.total_out_lo32;
+ err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
+ if(err == BZ_STREAM_END)
+ err = Z_STREAM_END;
+
+ zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
+ }
+
+ if(err == BZ_FINISH_OK)
+ err = ZIP_OK;
+#endif
+ }
+
+ if (err==Z_STREAM_END)
+ err=ZIP_OK; /* this is normal */
+
+ if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
+ {
+ if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
+ err = ZIP_ERRNO;
+ }
+
+ if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+ {
+ int tmp_err = deflateEnd(&zi->ci.stream);
+ if (err == ZIP_OK)
+ err = tmp_err;
+ zi->ci.stream_initialised = 0;
+ }
+#ifdef HAVE_BZIP2
+ else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+ {
+ int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
+ if (err==ZIP_OK)
+ err = tmperr;
+ zi->ci.stream_initialised = 0;
+ }
+#endif
+
+ if (!zi->ci.raw)
+ {
+ crc32 = (uLong)zi->ci.crc32;
+ uncompressed_size = zi->ci.totalUncompressedData;
+ }
+ compressed_size = zi->ci.totalCompressedData;
+
+# ifndef NOCRYPT
+ compressed_size += zi->ci.crypt_header_size;
+# endif
+
+ // update Current Item crc and sizes,
+ if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
+ {
+ /*version Made by*/
+ zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
+ /*version needed*/
+ zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
+
+ }
+
+ zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
+
+
+ if(compressed_size >= 0xffffffff)
+ zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
+
+ /// set internal file attributes field
+ if (zi->ci.stream.data_type == Z_ASCII)
+ zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
+
+ if(uncompressed_size >= 0xffffffff)
+ zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
+ else
+ zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
+
+ // Add ZIP64 extra info field for uncompressed size
+ if(uncompressed_size >= 0xffffffff)
+ datasize += 8;
+
+ // Add ZIP64 extra info field for compressed size
+ if(compressed_size >= 0xffffffff)
+ datasize += 8;
+
+ // Add ZIP64 extra info field for relative offset to local file header of current file
+ if(zi->ci.pos_local_header >= 0xffffffff)
+ datasize += 8;
+
+ if(datasize > 0)
+ {
+ char* p = NULL;
+
+ if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
+ {
+ // we can not write more data to the buffer that we have room for.
+ return ZIP_BADZIPFILE;
+ }
+
+ p = zi->ci.central_header + zi->ci.size_centralheader;
+
+ // Add Extra Information Header for 'ZIP64 information'
+ zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
+ p += 2;
+ zip64local_putValue_inmemory(p, datasize, 2); // DataSize
+ p += 2;
+
+ if(uncompressed_size >= 0xffffffff)
+ {
+ zip64local_putValue_inmemory(p, uncompressed_size, 8);
+ p += 8;
+ }
+
+ if(compressed_size >= 0xffffffff)
+ {
+ zip64local_putValue_inmemory(p, compressed_size, 8);
+ p += 8;
+ }
+
+ if(zi->ci.pos_local_header >= 0xffffffff)
+ {
+ zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
+ p += 8;
+ }
+
+ // Update how much extra free space we got in the memory buffer
+ // and increase the centralheader size so the new ZIP64 fields are included
+ // ( 4 below is the size of HeaderID and DataSize field )
+ zi->ci.size_centralExtraFree -= datasize + 4;
+ zi->ci.size_centralheader += datasize + 4;
+
+ // Update the extra info size field
+ zi->ci.size_centralExtra += datasize + 4;
+ zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
+ }
+
+ if (err==ZIP_OK)
+ err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
+
+ free(zi->ci.central_header);
+
+ if (err==ZIP_OK)
+ {
+ // Update the LocalFileHeader with the new values.
+
+ ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err = ZIP_ERRNO;
+
+ if (err==ZIP_OK)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
+
+ if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
+ {
+ if(zi->ci.pos_zip64extrainfo > 0)
+ {
+ // Update the size in the ZIP64 extended field.
+ if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err = ZIP_ERRNO;
+
+ if (err==ZIP_OK) /* compressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
+
+ if (err==ZIP_OK) /* uncompressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
+ }
+ else
+ err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
+ }
+ else
+ {
+ if (err==ZIP_OK) /* compressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
+
+ if (err==ZIP_OK) /* uncompressed size, unknown */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
+ }
+
+ if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
+ err = ZIP_ERRNO;
+ }
+
+ zi->number_entry ++;
+ zi->in_opened_file_inzip = 0;
+
+ return err;
+}
+
+extern int ZEXPORT zipCloseFileInZip (zipFile file)
+{
+ return zipCloseFileInZipRaw (file,0,0);
+}
+
+int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
+{
+ int err = ZIP_OK;
+ ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset;
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
+
+ /*num disks*/
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+ /*relative offset*/
+ if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
+
+ /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
+
+ return err;
+}
+
+int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+{
+ int err = ZIP_OK;
+
+ uLong Zip64DataSize = 44;
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
+
+ if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
+
+ if (err==ZIP_OK) /* version made by */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
+
+ if (err==ZIP_OK) /* version needed */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
+
+ if (err==ZIP_OK) /* number of this disk */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+ if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
+
+ if (err==ZIP_OK) /* total number of entries in the central dir */
+ err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
+
+ if (err==ZIP_OK) /* size of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
+
+ if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
+ {
+ ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
+ }
+ return err;
+}
+int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+{
+ int err = ZIP_OK;
+
+ /*signature*/
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
+
+ if (err==ZIP_OK) /* number of this disk */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+ if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+ if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
+ {
+ {
+ if(zi->number_entry >= 0xFFFF)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+ }
+ }
+
+ if (err==ZIP_OK) /* total number of entries in the central dir */
+ {
+ if(zi->number_entry >= 0xFFFF)
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+ }
+
+ if (err==ZIP_OK) /* size of the central directory */
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
+
+ if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
+ {
+ ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
+ if(pos >= 0xffffffff)
+ {
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
+ }
+ else
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writing_offset),4);
+ }
+
+ return err;
+}
+
+int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
+{
+ int err = ZIP_OK;
+ uInt size_global_comment = 0;
+
+ if(global_comment != NULL)
+ size_global_comment = (uInt)strlen(global_comment);
+
+ err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
+
+ if (err == ZIP_OK && size_global_comment > 0)
+ {
+ if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
+ err = ZIP_ERRNO;
+ }
+ return err;
+}
+
+extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
+{
+ zip64_internal* zi;
+ int err = 0;
+ uLong size_centraldir = 0;
+ ZPOS64_T centraldir_pos_inzip;
+ ZPOS64_T pos;
+
+ if (file == NULL)
+ return ZIP_PARAMERROR;
+
+ zi = (zip64_internal*)file;
+
+ if (zi->in_opened_file_inzip == 1)
+ {
+ err = zipCloseFileInZip (file);
+ }
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+ if (global_comment==NULL)
+ global_comment = zi->globalcomment;
+#endif
+
+ centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
+
+ if (err==ZIP_OK)
+ {
+ linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
+ while (ldi!=NULL)
+ {
+ if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
+ {
+ if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
+ err = ZIP_ERRNO;
+ }
+
+ size_centraldir += ldi->filled_in_this_block;
+ ldi = ldi->next_datablock;
+ }
+ }
+ free_linkedlist(&(zi->central_dir));
+
+ pos = centraldir_pos_inzip - zi->add_position_when_writing_offset;
+ if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
+ {
+ ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
+ Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
+
+ Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
+ }
+
+ if (err==ZIP_OK)
+ err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
+
+ if(err == ZIP_OK)
+ err = Write_GlobalComment(zi, global_comment);
+
+ if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
+ if (err == ZIP_OK)
+ err = ZIP_ERRNO;
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+ TRYFREE(zi->globalcomment);
+#endif
+ TRYFREE(zi);
+
+ return err;
+}
+
+extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
+{
+ char* p = pData;
+ int size = 0;
+ char* pNewHeader;
+ char* pTmp;
+ short header;
+ short dataSize;
+
+ int retVal = ZIP_OK;
+
+ if(pData == NULL || *dataLen < 4)
+ return ZIP_PARAMERROR;
+
+ pNewHeader = (char*)ALLOC(*dataLen);
+ pTmp = pNewHeader;
+
+ while(p < (pData + *dataLen))
+ {
+ header = *(short*)p;
+ dataSize = *(((short*)p)+1);
+
+ if( header == sHeader ) // Header found.
+ {
+ p += dataSize + 4; // skip it. do not copy to temp buffer
+ }
+ else
+ {
+ // Extra Info block should not be removed, So copy it to the temp buffer.
+ memcpy(pTmp, p, dataSize + 4);
+ p += dataSize + 4;
+ size += dataSize + 4;
+ }
+
+ }
+
+ if(size < *dataLen)
+ {
+ // clean old extra info block.
+ memset(pData,0, *dataLen);
+
+ // copy the new extra info block over the old
+ if(size > 0)
+ memcpy(pData, pNewHeader, size);
+
+ // set the new extra info size
+ *dataLen = size;
+
+ retVal = ZIP_OK;
+ }
+ else
+ retVal = ZIP_ERRNO;
+
+ TRYFREE(pNewHeader);
+
+ return retVal;
+}
diff --git a/xs/src/png/zlib/contrib/minizip/zip.h b/xs/src/png/zlib/contrib/minizip/zip.h
new file mode 100644
index 000000000..8aaebb623
--- /dev/null
+++ b/xs/src/png/zlib/contrib/minizip/zip.h
@@ -0,0 +1,362 @@
+/* zip.h -- IO on .zip files using zlib
+ Version 1.1, February 14h, 2010
+ part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+ Modifications for Zip64 support
+ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+ For more info read MiniZip_info.txt
+
+ ---------------------------------------------------------------------------
+
+ Condition of use and distribution are the same than zlib :
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ ---------------------------------------------------------------------------
+
+ Changes
+
+ See header of zip.h
+
+*/
+
+#ifndef _zip12_H
+#define _zip12_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#define HAVE_BZIP2
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+ from (void*) without cast */
+typedef struct TagzipFile__ { int unused; } zipFile__;
+typedef zipFile__ *zipFile;
+#else
+typedef voidp zipFile;
+#endif
+
+#define ZIP_OK (0)
+#define ZIP_EOF (0)
+#define ZIP_ERRNO (Z_ERRNO)
+#define ZIP_PARAMERROR (-102)
+#define ZIP_BADZIPFILE (-103)
+#define ZIP_INTERNALERROR (-104)
+
+#ifndef DEF_MEM_LEVEL
+# if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+# else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+# endif
+#endif
+/* default memLevel */
+
+/* tm_zip contain date/time info */
+typedef struct tm_zip_s
+{
+ uInt tm_sec; /* seconds after the minute - [0,59] */
+ uInt tm_min; /* minutes after the hour - [0,59] */
+ uInt tm_hour; /* hours since midnight - [0,23] */
+ uInt tm_mday; /* day of the month - [1,31] */
+ uInt tm_mon; /* months since January - [0,11] */
+ uInt tm_year; /* years - [1980..2044] */
+} tm_zip;
+
+typedef struct
+{
+ tm_zip tmz_date; /* date in understandable format */
+ uLong dosDate; /* if dos_date == 0, tmu_date is used */
+/* uLong flag; */ /* general purpose bit flag 2 bytes */
+
+ uLong internal_fa; /* internal file attributes 2 bytes */
+ uLong external_fa; /* external file attributes 4 bytes */
+} zip_fileinfo;
+
+typedef const char* zipcharpc;
+
+
+#define APPEND_STATUS_CREATE (0)
+#define APPEND_STATUS_CREATEAFTER (1)
+#define APPEND_STATUS_ADDINZIP (2)
+
+extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
+extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
+/*
+ Create a zipfile.
+ pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
+ an Unix computer "zlib/zlib113.zip".
+ if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
+ will be created at the end of the file.
+ (useful if the file contain a self extractor code)
+ if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
+ add files in existing zip (be sure you don't add file that doesn't exist)
+ If the zipfile cannot be opened, the return value is NULL.
+ Else, the return value is a zipFile Handle, usable with other function
+ of this zip package.
+*/
+
+/* Note : there is no delete function into a zipfile.
+ If you want delete file into a zipfile, you must open a zipfile, and create another
+ Of couse, you can use RAW reading and writing to copy the file you did not want delte
+*/
+
+extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
+ int append,
+ zipcharpc* globalcomment,
+ zlib_filefunc_def* pzlib_filefunc_def));
+
+extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
+ int append,
+ zipcharpc* globalcomment,
+ zlib_filefunc64_def* pzlib_filefunc_def));
+
+extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level));
+
+extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int zip64));
+
+/*
+ Open a file in the ZIP for writing.
+ filename : the filename in zip (if NULL, '-' without quote will be used
+ *zipfi contain supplemental information
+ if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
+ contains the extrafield data the the local header
+ if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
+ contains the extrafield data the the local header
+ if comment != NULL, comment contain the comment string
+ method contain the compression method (0 for store, Z_DEFLATED for deflate)
+ level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
+ zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
+ this MUST be '1' if the uncompressed size is >= 0xffffffff.
+
+*/
+
+
+extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw));
+
+
+extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int zip64));
+/*
+ Same than zipOpenNewFileInZip, except if raw=1, we write raw file
+ */
+
+extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting));
+
+extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ int zip64
+ ));
+
+/*
+ Same than zipOpenNewFileInZip2, except
+ windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
+ password : crypting password (NULL for no crypting)
+ crcForCrypting : crc of file to compress (needed for crypting)
+ */
+
+extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ uLong versionMadeBy,
+ uLong flagBase
+ ));
+
+
+extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
+ const char* filename,
+ const zip_fileinfo* zipfi,
+ const void* extrafield_local,
+ uInt size_extrafield_local,
+ const void* extrafield_global,
+ uInt size_extrafield_global,
+ const char* comment,
+ int method,
+ int level,
+ int raw,
+ int windowBits,
+ int memLevel,
+ int strategy,
+ const char* password,
+ uLong crcForCrypting,
+ uLong versionMadeBy,
+ uLong flagBase,
+ int zip64
+ ));
+/*
+ Same than zipOpenNewFileInZip4, except
+ versionMadeBy : value for Version made by field
+ flag : value for flag field (compression level info will be added)
+ */
+
+
+extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
+ const void* buf,
+ unsigned len));
+/*
+ Write data in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
+/*
+ Close the current file in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
+ uLong uncompressed_size,
+ uLong crc32));
+
+extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
+ ZPOS64_T uncompressed_size,
+ uLong crc32));
+
+/*
+ Close the current file in the zipfile, for file opened with
+ parameter raw=1 in zipOpenNewFileInZip2
+ uncompressed_size and crc32 are value for the uncompressed size
+*/
+
+extern int ZEXPORT zipClose OF((zipFile file,
+ const char* global_comment));
+/*
+ Close the zipfile
+*/
+
+
+extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
+/*
+ zipRemoveExtraInfoBlock - Added by Mathias Svensson
+
+ Remove extra information block from a extra information data for the local file header or central directory header
+
+ It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
+
+ 0x0001 is the signature header for the ZIP64 extra information blocks
+
+ usage.
+ Remove ZIP64 Extra information from a central director extra field data
+ zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
+
+ Remove ZIP64 Extra information from a Local File Header extra field data
+ zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _zip64_H */
diff --git a/xs/src/png/zlib/contrib/pascal/example.pas b/xs/src/png/zlib/contrib/pascal/example.pas
new file mode 100644
index 000000000..5518b36a7
--- /dev/null
+++ b/xs/src/png/zlib/contrib/pascal/example.pas
@@ -0,0 +1,599 @@
+(* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Pascal translation
+ * Copyright (C) 1998 by Jacques Nomssi Nzali.
+ * For conditions of distribution and use, see copyright notice in readme.txt
+ *
+ * Adaptation to the zlibpas interface
+ * Copyright (C) 2003 by Cosmin Truta.
+ * For conditions of distribution and use, see copyright notice in readme.txt
+ *)
+
+program example;
+
+{$DEFINE TEST_COMPRESS}
+{DO NOT $DEFINE TEST_GZIO}
+{$DEFINE TEST_DEFLATE}
+{$DEFINE TEST_INFLATE}
+{$DEFINE TEST_FLUSH}
+{$DEFINE TEST_SYNC}
+{$DEFINE TEST_DICT}
+
+uses SysUtils, zlibpas;
+
+const TESTFILE = 'foo.gz';
+
+(* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ *)
+const hello: PChar = 'hello, hello!';
+
+const dictionary: PChar = 'hello';
+
+var dictId: LongInt; (* Adler32 value of the dictionary *)
+
+procedure CHECK_ERR(err: Integer; msg: String);
+begin
+ if err <> Z_OK then
+ begin
+ WriteLn(msg, ' error: ', err);
+ Halt(1);
+ end;
+end;
+
+procedure EXIT_ERR(const msg: String);
+begin
+ WriteLn('Error: ', msg);
+ Halt(1);
+end;
+
+(* ===========================================================================
+ * Test compress and uncompress
+ *)
+{$IFDEF TEST_COMPRESS}
+procedure test_compress(compr: Pointer; comprLen: LongInt;
+ uncompr: Pointer; uncomprLen: LongInt);
+var err: Integer;
+ len: LongInt;
+begin
+ len := StrLen(hello)+1;
+
+ err := compress(compr, comprLen, hello, len);
+ CHECK_ERR(err, 'compress');
+
+ StrCopy(PChar(uncompr), 'garbage');
+
+ err := uncompress(uncompr, uncomprLen, compr, comprLen);
+ CHECK_ERR(err, 'uncompress');
+
+ if StrComp(PChar(uncompr), hello) <> 0 then
+ EXIT_ERR('bad uncompress')
+ else
+ WriteLn('uncompress(): ', PChar(uncompr));
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test read/write of .gz files
+ *)
+{$IFDEF TEST_GZIO}
+procedure test_gzio(const fname: PChar; (* compressed file name *)
+ uncompr: Pointer;
+ uncomprLen: LongInt);
+var err: Integer;
+ len: Integer;
+ zfile: gzFile;
+ pos: LongInt;
+begin
+ len := StrLen(hello)+1;
+
+ zfile := gzopen(fname, 'wb');
+ if zfile = NIL then
+ begin
+ WriteLn('gzopen error');
+ Halt(1);
+ end;
+ gzputc(zfile, 'h');
+ if gzputs(zfile, 'ello') <> 4 then
+ begin
+ WriteLn('gzputs err: ', gzerror(zfile, err));
+ Halt(1);
+ end;
+ {$IFDEF GZ_FORMAT_STRING}
+ if gzprintf(zfile, ', %s!', 'hello') <> 8 then
+ begin
+ WriteLn('gzprintf err: ', gzerror(zfile, err));
+ Halt(1);
+ end;
+ {$ELSE}
+ if gzputs(zfile, ', hello!') <> 8 then
+ begin
+ WriteLn('gzputs err: ', gzerror(zfile, err));
+ Halt(1);
+ end;
+ {$ENDIF}
+ gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *)
+ gzclose(zfile);
+
+ zfile := gzopen(fname, 'rb');
+ if zfile = NIL then
+ begin
+ WriteLn('gzopen error');
+ Halt(1);
+ end;
+
+ StrCopy(PChar(uncompr), 'garbage');
+
+ if gzread(zfile, uncompr, uncomprLen) <> len then
+ begin
+ WriteLn('gzread err: ', gzerror(zfile, err));
+ Halt(1);
+ end;
+ if StrComp(PChar(uncompr), hello) <> 0 then
+ begin
+ WriteLn('bad gzread: ', PChar(uncompr));
+ Halt(1);
+ end
+ else
+ WriteLn('gzread(): ', PChar(uncompr));
+
+ pos := gzseek(zfile, -8, SEEK_CUR);
+ if (pos <> 6) or (gztell(zfile) <> pos) then
+ begin
+ WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile));
+ Halt(1);
+ end;
+
+ if gzgetc(zfile) <> ' ' then
+ begin
+ WriteLn('gzgetc error');
+ Halt(1);
+ end;
+
+ if gzungetc(' ', zfile) <> ' ' then
+ begin
+ WriteLn('gzungetc error');
+ Halt(1);
+ end;
+
+ gzgets(zfile, PChar(uncompr), uncomprLen);
+ uncomprLen := StrLen(PChar(uncompr));
+ if uncomprLen <> 7 then (* " hello!" *)
+ begin
+ WriteLn('gzgets err after gzseek: ', gzerror(zfile, err));
+ Halt(1);
+ end;
+ if StrComp(PChar(uncompr), hello + 6) <> 0 then
+ begin
+ WriteLn('bad gzgets after gzseek');
+ Halt(1);
+ end
+ else
+ WriteLn('gzgets() after gzseek: ', PChar(uncompr));
+
+ gzclose(zfile);
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with small buffers
+ *)
+{$IFDEF TEST_DEFLATE}
+procedure test_deflate(compr: Pointer; comprLen: LongInt);
+var c_stream: z_stream; (* compression stream *)
+ err: Integer;
+ len: LongInt;
+begin
+ len := StrLen(hello)+1;
+
+ c_stream.zalloc := NIL;
+ c_stream.zfree := NIL;
+ c_stream.opaque := NIL;
+
+ err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, 'deflateInit');
+
+ c_stream.next_in := hello;
+ c_stream.next_out := compr;
+
+ while (c_stream.total_in <> len) and
+ (c_stream.total_out < comprLen) do
+ begin
+ c_stream.avail_out := 1; { force small buffers }
+ c_stream.avail_in := 1;
+ err := deflate(c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, 'deflate');
+ end;
+
+ (* Finish the stream, still forcing small buffers: *)
+ while TRUE do
+ begin
+ c_stream.avail_out := 1;
+ err := deflate(c_stream, Z_FINISH);
+ if err = Z_STREAM_END then
+ break;
+ CHECK_ERR(err, 'deflate');
+ end;
+
+ err := deflateEnd(c_stream);
+ CHECK_ERR(err, 'deflateEnd');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflate with small buffers
+ *)
+{$IFDEF TEST_INFLATE}
+procedure test_inflate(compr: Pointer; comprLen : LongInt;
+ uncompr: Pointer; uncomprLen : LongInt);
+var err: Integer;
+ d_stream: z_stream; (* decompression stream *)
+begin
+ StrCopy(PChar(uncompr), 'garbage');
+
+ d_stream.zalloc := NIL;
+ d_stream.zfree := NIL;
+ d_stream.opaque := NIL;
+
+ d_stream.next_in := compr;
+ d_stream.avail_in := 0;
+ d_stream.next_out := uncompr;
+
+ err := inflateInit(d_stream);
+ CHECK_ERR(err, 'inflateInit');
+
+ while (d_stream.total_out < uncomprLen) and
+ (d_stream.total_in < comprLen) do
+ begin
+ d_stream.avail_out := 1; (* force small buffers *)
+ d_stream.avail_in := 1;
+ err := inflate(d_stream, Z_NO_FLUSH);
+ if err = Z_STREAM_END then
+ break;
+ CHECK_ERR(err, 'inflate');
+ end;
+
+ err := inflateEnd(d_stream);
+ CHECK_ERR(err, 'inflateEnd');
+
+ if StrComp(PChar(uncompr), hello) <> 0 then
+ EXIT_ERR('bad inflate')
+ else
+ WriteLn('inflate(): ', PChar(uncompr));
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with large buffers and dynamic change of compression level
+ *)
+{$IFDEF TEST_DEFLATE}
+procedure test_large_deflate(compr: Pointer; comprLen: LongInt;
+ uncompr: Pointer; uncomprLen: LongInt);
+var c_stream: z_stream; (* compression stream *)
+ err: Integer;
+begin
+ c_stream.zalloc := NIL;
+ c_stream.zfree := NIL;
+ c_stream.opaque := NIL;
+
+ err := deflateInit(c_stream, Z_BEST_SPEED);
+ CHECK_ERR(err, 'deflateInit');
+
+ c_stream.next_out := compr;
+ c_stream.avail_out := Integer(comprLen);
+
+ (* At this point, uncompr is still mostly zeroes, so it should compress
+ * very well:
+ *)
+ c_stream.next_in := uncompr;
+ c_stream.avail_in := Integer(uncomprLen);
+ err := deflate(c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, 'deflate');
+ if c_stream.avail_in <> 0 then
+ EXIT_ERR('deflate not greedy');
+
+ (* Feed in already compressed data and switch to no compression: *)
+ deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+ c_stream.next_in := compr;
+ c_stream.avail_in := Integer(comprLen div 2);
+ err := deflate(c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, 'deflate');
+
+ (* Switch back to compressing mode: *)
+ deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+ c_stream.next_in := uncompr;
+ c_stream.avail_in := Integer(uncomprLen);
+ err := deflate(c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, 'deflate');
+
+ err := deflate(c_stream, Z_FINISH);
+ if err <> Z_STREAM_END then
+ EXIT_ERR('deflate should report Z_STREAM_END');
+
+ err := deflateEnd(c_stream);
+ CHECK_ERR(err, 'deflateEnd');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflate with large buffers
+ *)
+{$IFDEF TEST_INFLATE}
+procedure test_large_inflate(compr: Pointer; comprLen: LongInt;
+ uncompr: Pointer; uncomprLen: LongInt);
+var err: Integer;
+ d_stream: z_stream; (* decompression stream *)
+begin
+ StrCopy(PChar(uncompr), 'garbage');
+
+ d_stream.zalloc := NIL;
+ d_stream.zfree := NIL;
+ d_stream.opaque := NIL;
+
+ d_stream.next_in := compr;
+ d_stream.avail_in := Integer(comprLen);
+
+ err := inflateInit(d_stream);
+ CHECK_ERR(err, 'inflateInit');
+
+ while TRUE do
+ begin
+ d_stream.next_out := uncompr; (* discard the output *)
+ d_stream.avail_out := Integer(uncomprLen);
+ err := inflate(d_stream, Z_NO_FLUSH);
+ if err = Z_STREAM_END then
+ break;
+ CHECK_ERR(err, 'large inflate');
+ end;
+
+ err := inflateEnd(d_stream);
+ CHECK_ERR(err, 'inflateEnd');
+
+ if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then
+ begin
+ WriteLn('bad large inflate: ', d_stream.total_out);
+ Halt(1);
+ end
+ else
+ WriteLn('large_inflate(): OK');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with full flush
+ *)
+{$IFDEF TEST_FLUSH}
+procedure test_flush(compr: Pointer; var comprLen : LongInt);
+var c_stream: z_stream; (* compression stream *)
+ err: Integer;
+ len: Integer;
+begin
+ len := StrLen(hello)+1;
+
+ c_stream.zalloc := NIL;
+ c_stream.zfree := NIL;
+ c_stream.opaque := NIL;
+
+ err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, 'deflateInit');
+
+ c_stream.next_in := hello;
+ c_stream.next_out := compr;
+ c_stream.avail_in := 3;
+ c_stream.avail_out := Integer(comprLen);
+ err := deflate(c_stream, Z_FULL_FLUSH);
+ CHECK_ERR(err, 'deflate');
+
+ Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *)
+ c_stream.avail_in := len - 3;
+
+ err := deflate(c_stream, Z_FINISH);
+ if err <> Z_STREAM_END then
+ CHECK_ERR(err, 'deflate');
+
+ err := deflateEnd(c_stream);
+ CHECK_ERR(err, 'deflateEnd');
+
+ comprLen := c_stream.total_out;
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflateSync()
+ *)
+{$IFDEF TEST_SYNC}
+procedure test_sync(compr: Pointer; comprLen: LongInt;
+ uncompr: Pointer; uncomprLen : LongInt);
+var err: Integer;
+ d_stream: z_stream; (* decompression stream *)
+begin
+ StrCopy(PChar(uncompr), 'garbage');
+
+ d_stream.zalloc := NIL;
+ d_stream.zfree := NIL;
+ d_stream.opaque := NIL;
+
+ d_stream.next_in := compr;
+ d_stream.avail_in := 2; (* just read the zlib header *)
+
+ err := inflateInit(d_stream);
+ CHECK_ERR(err, 'inflateInit');
+
+ d_stream.next_out := uncompr;
+ d_stream.avail_out := Integer(uncomprLen);
+
+ inflate(d_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, 'inflate');
+
+ d_stream.avail_in := Integer(comprLen-2); (* read all compressed data *)
+ err := inflateSync(d_stream); (* but skip the damaged part *)
+ CHECK_ERR(err, 'inflateSync');
+
+ err := inflate(d_stream, Z_FINISH);
+ if err <> Z_DATA_ERROR then
+ EXIT_ERR('inflate should report DATA_ERROR');
+ (* Because of incorrect adler32 *)
+
+ err := inflateEnd(d_stream);
+ CHECK_ERR(err, 'inflateEnd');
+
+ WriteLn('after inflateSync(): hel', PChar(uncompr));
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with preset dictionary
+ *)
+{$IFDEF TEST_DICT}
+procedure test_dict_deflate(compr: Pointer; comprLen: LongInt);
+var c_stream: z_stream; (* compression stream *)
+ err: Integer;
+begin
+ c_stream.zalloc := NIL;
+ c_stream.zfree := NIL;
+ c_stream.opaque := NIL;
+
+ err := deflateInit(c_stream, Z_BEST_COMPRESSION);
+ CHECK_ERR(err, 'deflateInit');
+
+ err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary));
+ CHECK_ERR(err, 'deflateSetDictionary');
+
+ dictId := c_stream.adler;
+ c_stream.next_out := compr;
+ c_stream.avail_out := Integer(comprLen);
+
+ c_stream.next_in := hello;
+ c_stream.avail_in := StrLen(hello)+1;
+
+ err := deflate(c_stream, Z_FINISH);
+ if err <> Z_STREAM_END then
+ EXIT_ERR('deflate should report Z_STREAM_END');
+
+ err := deflateEnd(c_stream);
+ CHECK_ERR(err, 'deflateEnd');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflate with a preset dictionary
+ *)
+{$IFDEF TEST_DICT}
+procedure test_dict_inflate(compr: Pointer; comprLen: LongInt;
+ uncompr: Pointer; uncomprLen: LongInt);
+var err: Integer;
+ d_stream: z_stream; (* decompression stream *)
+begin
+ StrCopy(PChar(uncompr), 'garbage');
+
+ d_stream.zalloc := NIL;
+ d_stream.zfree := NIL;
+ d_stream.opaque := NIL;
+
+ d_stream.next_in := compr;
+ d_stream.avail_in := Integer(comprLen);
+
+ err := inflateInit(d_stream);
+ CHECK_ERR(err, 'inflateInit');
+
+ d_stream.next_out := uncompr;
+ d_stream.avail_out := Integer(uncomprLen);
+
+ while TRUE do
+ begin
+ err := inflate(d_stream, Z_NO_FLUSH);
+ if err = Z_STREAM_END then
+ break;
+ if err = Z_NEED_DICT then
+ begin
+ if d_stream.adler <> dictId then
+ EXIT_ERR('unexpected dictionary');
+ err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary));
+ end;
+ CHECK_ERR(err, 'inflate with dict');
+ end;
+
+ err := inflateEnd(d_stream);
+ CHECK_ERR(err, 'inflateEnd');
+
+ if StrComp(PChar(uncompr), hello) <> 0 then
+ EXIT_ERR('bad inflate with dict')
+ else
+ WriteLn('inflate with dictionary: ', PChar(uncompr));
+end;
+{$ENDIF}
+
+var compr, uncompr: Pointer;
+ comprLen, uncomprLen: LongInt;
+
+begin
+ if zlibVersion^ <> ZLIB_VERSION[1] then
+ EXIT_ERR('Incompatible zlib version');
+
+ WriteLn('zlib version: ', zlibVersion);
+ WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags]));
+
+ comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *)
+ uncomprLen := comprLen;
+ GetMem(compr, comprLen);
+ GetMem(uncompr, uncomprLen);
+ if (compr = NIL) or (uncompr = NIL) then
+ EXIT_ERR('Out of memory');
+ (* compr and uncompr are cleared to avoid reading uninitialized
+ * data and to ensure that uncompr compresses well.
+ *)
+ FillChar(compr^, comprLen, 0);
+ FillChar(uncompr^, uncomprLen, 0);
+
+ {$IFDEF TEST_COMPRESS}
+ WriteLn('** Testing compress');
+ test_compress(compr, comprLen, uncompr, uncomprLen);
+ {$ENDIF}
+
+ {$IFDEF TEST_GZIO}
+ WriteLn('** Testing gzio');
+ if ParamCount >= 1 then
+ test_gzio(ParamStr(1), uncompr, uncomprLen)
+ else
+ test_gzio(TESTFILE, uncompr, uncomprLen);
+ {$ENDIF}
+
+ {$IFDEF TEST_DEFLATE}
+ WriteLn('** Testing deflate with small buffers');
+ test_deflate(compr, comprLen);
+ {$ENDIF}
+ {$IFDEF TEST_INFLATE}
+ WriteLn('** Testing inflate with small buffers');
+ test_inflate(compr, comprLen, uncompr, uncomprLen);
+ {$ENDIF}
+
+ {$IFDEF TEST_DEFLATE}
+ WriteLn('** Testing deflate with large buffers');
+ test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+ {$ENDIF}
+ {$IFDEF TEST_INFLATE}
+ WriteLn('** Testing inflate with large buffers');
+ test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+ {$ENDIF}
+
+ {$IFDEF TEST_FLUSH}
+ WriteLn('** Testing deflate with full flush');
+ test_flush(compr, comprLen);
+ {$ENDIF}
+ {$IFDEF TEST_SYNC}
+ WriteLn('** Testing inflateSync');
+ test_sync(compr, comprLen, uncompr, uncomprLen);
+ {$ENDIF}
+ comprLen := uncomprLen;
+
+ {$IFDEF TEST_DICT}
+ WriteLn('** Testing deflate and inflate with preset dictionary');
+ test_dict_deflate(compr, comprLen);
+ test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+ {$ENDIF}
+
+ FreeMem(compr, comprLen);
+ FreeMem(uncompr, uncomprLen);
+end.
diff --git a/xs/src/png/zlib/contrib/pascal/readme.txt b/xs/src/png/zlib/contrib/pascal/readme.txt
new file mode 100644
index 000000000..60e87c8a3
--- /dev/null
+++ b/xs/src/png/zlib/contrib/pascal/readme.txt
@@ -0,0 +1,76 @@
+
+This directory contains a Pascal (Delphi, Kylix) interface to the
+zlib data compression library.
+
+
+Directory listing
+=================
+
+zlibd32.mak makefile for Borland C++
+example.pas usage example of zlib
+zlibpas.pas the Pascal interface to zlib
+readme.txt this file
+
+
+Compatibility notes
+===================
+
+- Although the name "zlib" would have been more normal for the
+ zlibpas unit, this name is already taken by Borland's ZLib unit.
+ This is somehow unfortunate, because that unit is not a genuine
+ interface to the full-fledged zlib functionality, but a suite of
+ class wrappers around zlib streams. Other essential features,
+ such as checksums, are missing.
+ It would have been more appropriate for that unit to have a name
+ like "ZStreams", or something similar.
+
+- The C and zlib-supplied types int, uInt, long, uLong, etc. are
+ translated directly into Pascal types of similar sizes (Integer,
+ LongInt, etc.), to avoid namespace pollution. In particular,
+ there is no conversion of unsigned int into a Pascal unsigned
+ integer. The Word type is non-portable and has the same size
+ (16 bits) both in a 16-bit and in a 32-bit environment, unlike
+ Integer. Even if there is a 32-bit Cardinal type, there is no
+ real need for unsigned int in zlib under a 32-bit environment.
+
+- Except for the callbacks, the zlib function interfaces are
+ assuming the calling convention normally used in Pascal
+ (__pascal for DOS and Windows16, __fastcall for Windows32).
+ Since the cdecl keyword is used, the old Turbo Pascal does
+ not work with this interface.
+
+- The gz* function interfaces are not translated, to avoid
+ interfacing problems with the C runtime library. Besides,
+ gzprintf(gzFile file, const char *format, ...)
+ cannot be translated into Pascal.
+
+
+Legal issues
+============
+
+The zlibpas interface is:
+ Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler.
+ Copyright (C) 1998 by Bob Dellaca.
+ Copyright (C) 2003 by Cosmin Truta.
+
+The example program is:
+ Copyright (C) 1995-2003 by Jean-loup Gailly.
+ Copyright (C) 1998,1999,2000 by Jacques Nomssi Nzali.
+ Copyright (C) 2003 by Cosmin Truta.
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the author be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
diff --git a/xs/src/png/zlib/contrib/pascal/zlibd32.mak b/xs/src/png/zlib/contrib/pascal/zlibd32.mak
new file mode 100644
index 000000000..9bb00b7cc
--- /dev/null
+++ b/xs/src/png/zlib/contrib/pascal/zlibd32.mak
@@ -0,0 +1,99 @@
+# Makefile for zlib
+# For use with Delphi and C++ Builder under Win32
+# Updated for zlib 1.2.x by Cosmin Truta
+
+# ------------ Borland C++ ------------
+
+# This project uses the Delphi (fastcall/register) calling convention:
+LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl
+
+CC = bcc32
+LD = bcc32
+AR = tlib
+# do not use "-pr" in CFLAGS
+CFLAGS = -a -d -k- -O2 $(LOC)
+LDFLAGS =
+
+
+# variables
+ZLIB_LIB = zlib.lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+ -del $(ZLIB_LIB)
+ $(AR) $(ZLIB_LIB) $(OBJP1)
+ $(AR) $(ZLIB_LIB) $(OBJP2)
+
+
+# testing
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+
+# cleanup
+clean:
+ -del *.obj
+ -del *.exe
+ -del *.lib
+ -del *.tds
+ -del zlib.bak
+ -del foo.gz
+
diff --git a/xs/src/png/zlib/contrib/pascal/zlibpas.pas b/xs/src/png/zlib/contrib/pascal/zlibpas.pas
new file mode 100644
index 000000000..a0dff11b5
--- /dev/null
+++ b/xs/src/png/zlib/contrib/pascal/zlibpas.pas
@@ -0,0 +1,276 @@
+(* zlibpas -- Pascal interface to the zlib data compression library
+ *
+ * Copyright (C) 2003 Cosmin Truta.
+ * Derived from original sources by Bob Dellaca.
+ * For conditions of distribution and use, see copyright notice in readme.txt
+ *)
+
+unit zlibpas;
+
+interface
+
+const
+ ZLIB_VERSION = '1.2.11';
+ ZLIB_VERNUM = $12a0;
+
+type
+ alloc_func = function(opaque: Pointer; items, size: Integer): Pointer;
+ cdecl;
+ free_func = procedure(opaque, address: Pointer);
+ cdecl;
+
+ in_func = function(opaque: Pointer; var buf: PByte): Integer;
+ cdecl;
+ out_func = function(opaque: Pointer; buf: PByte; size: Integer): Integer;
+ cdecl;
+
+ z_streamp = ^z_stream;
+ z_stream = packed record
+ next_in: PChar; (* next input byte *)
+ avail_in: Integer; (* number of bytes available at next_in *)
+ total_in: LongInt; (* total nb of input bytes read so far *)
+
+ next_out: PChar; (* next output byte should be put there *)
+ avail_out: Integer; (* remaining free space at next_out *)
+ total_out: LongInt; (* total nb of bytes output so far *)
+
+ msg: PChar; (* last error message, NULL if no error *)
+ state: Pointer; (* not visible by applications *)
+
+ zalloc: alloc_func; (* used to allocate the internal state *)
+ zfree: free_func; (* used to free the internal state *)
+ opaque: Pointer; (* private data object passed to zalloc and zfree *)
+
+ data_type: Integer; (* best guess about the data type: ascii or binary *)
+ adler: LongInt; (* adler32 value of the uncompressed data *)
+ reserved: LongInt; (* reserved for future use *)
+ end;
+
+ gz_headerp = ^gz_header;
+ gz_header = packed record
+ text: Integer; (* true if compressed data believed to be text *)
+ time: LongInt; (* modification time *)
+ xflags: Integer; (* extra flags (not used when writing a gzip file) *)
+ os: Integer; (* operating system *)
+ extra: PChar; (* pointer to extra field or Z_NULL if none *)
+ extra_len: Integer; (* extra field length (valid if extra != Z_NULL) *)
+ extra_max: Integer; (* space at extra (only when reading header) *)
+ name: PChar; (* pointer to zero-terminated file name or Z_NULL *)
+ name_max: Integer; (* space at name (only when reading header) *)
+ comment: PChar; (* pointer to zero-terminated comment or Z_NULL *)
+ comm_max: Integer; (* space at comment (only when reading header) *)
+ hcrc: Integer; (* true if there was or will be a header crc *)
+ done: Integer; (* true when done reading gzip header *)
+ end;
+
+(* constants *)
+const
+ Z_NO_FLUSH = 0;
+ Z_PARTIAL_FLUSH = 1;
+ Z_SYNC_FLUSH = 2;
+ Z_FULL_FLUSH = 3;
+ Z_FINISH = 4;
+ Z_BLOCK = 5;
+ Z_TREES = 6;
+
+ Z_OK = 0;
+ Z_STREAM_END = 1;
+ Z_NEED_DICT = 2;
+ Z_ERRNO = -1;
+ Z_STREAM_ERROR = -2;
+ Z_DATA_ERROR = -3;
+ Z_MEM_ERROR = -4;
+ Z_BUF_ERROR = -5;
+ Z_VERSION_ERROR = -6;
+
+ Z_NO_COMPRESSION = 0;
+ Z_BEST_SPEED = 1;
+ Z_BEST_COMPRESSION = 9;
+ Z_DEFAULT_COMPRESSION = -1;
+
+ Z_FILTERED = 1;
+ Z_HUFFMAN_ONLY = 2;
+ Z_RLE = 3;
+ Z_FIXED = 4;
+ Z_DEFAULT_STRATEGY = 0;
+
+ Z_BINARY = 0;
+ Z_TEXT = 1;
+ Z_ASCII = 1;
+ Z_UNKNOWN = 2;
+
+ Z_DEFLATED = 8;
+
+(* basic functions *)
+function zlibVersion: PChar;
+function deflateInit(var strm: z_stream; level: Integer): Integer;
+function deflate(var strm: z_stream; flush: Integer): Integer;
+function deflateEnd(var strm: z_stream): Integer;
+function inflateInit(var strm: z_stream): Integer;
+function inflate(var strm: z_stream; flush: Integer): Integer;
+function inflateEnd(var strm: z_stream): Integer;
+
+(* advanced functions *)
+function deflateInit2(var strm: z_stream; level, method, windowBits,
+ memLevel, strategy: Integer): Integer;
+function deflateSetDictionary(var strm: z_stream; const dictionary: PChar;
+ dictLength: Integer): Integer;
+function deflateCopy(var dest, source: z_stream): Integer;
+function deflateReset(var strm: z_stream): Integer;
+function deflateParams(var strm: z_stream; level, strategy: Integer): Integer;
+function deflateTune(var strm: z_stream; good_length, max_lazy, nice_length, max_chain: Integer): Integer;
+function deflateBound(var strm: z_stream; sourceLen: LongInt): LongInt;
+function deflatePending(var strm: z_stream; var pending: Integer; var bits: Integer): Integer;
+function deflatePrime(var strm: z_stream; bits, value: Integer): Integer;
+function deflateSetHeader(var strm: z_stream; head: gz_header): Integer;
+function inflateInit2(var strm: z_stream; windowBits: Integer): Integer;
+function inflateSetDictionary(var strm: z_stream; const dictionary: PChar;
+ dictLength: Integer): Integer;
+function inflateSync(var strm: z_stream): Integer;
+function inflateCopy(var dest, source: z_stream): Integer;
+function inflateReset(var strm: z_stream): Integer;
+function inflateReset2(var strm: z_stream; windowBits: Integer): Integer;
+function inflatePrime(var strm: z_stream; bits, value: Integer): Integer;
+function inflateMark(var strm: z_stream): LongInt;
+function inflateGetHeader(var strm: z_stream; var head: gz_header): Integer;
+function inflateBackInit(var strm: z_stream;
+ windowBits: Integer; window: PChar): Integer;
+function inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer;
+ out_fn: out_func; out_desc: Pointer): Integer;
+function inflateBackEnd(var strm: z_stream): Integer;
+function zlibCompileFlags: LongInt;
+
+(* utility functions *)
+function compress(dest: PChar; var destLen: LongInt;
+ const source: PChar; sourceLen: LongInt): Integer;
+function compress2(dest: PChar; var destLen: LongInt;
+ const source: PChar; sourceLen: LongInt;
+ level: Integer): Integer;
+function compressBound(sourceLen: LongInt): LongInt;
+function uncompress(dest: PChar; var destLen: LongInt;
+ const source: PChar; sourceLen: LongInt): Integer;
+
+(* checksum functions *)
+function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt;
+function adler32_combine(adler1, adler2, len2: LongInt): LongInt;
+function crc32(crc: LongInt; const buf: PChar; len: Integer): LongInt;
+function crc32_combine(crc1, crc2, len2: LongInt): LongInt;
+
+(* various hacks, don't look :) *)
+function deflateInit_(var strm: z_stream; level: Integer;
+ const version: PChar; stream_size: Integer): Integer;
+function inflateInit_(var strm: z_stream; const version: PChar;
+ stream_size: Integer): Integer;
+function deflateInit2_(var strm: z_stream;
+ level, method, windowBits, memLevel, strategy: Integer;
+ const version: PChar; stream_size: Integer): Integer;
+function inflateInit2_(var strm: z_stream; windowBits: Integer;
+ const version: PChar; stream_size: Integer): Integer;
+function inflateBackInit_(var strm: z_stream;
+ windowBits: Integer; window: PChar;
+ const version: PChar; stream_size: Integer): Integer;
+
+
+implementation
+
+{$L adler32.obj}
+{$L compress.obj}
+{$L crc32.obj}
+{$L deflate.obj}
+{$L infback.obj}
+{$L inffast.obj}
+{$L inflate.obj}
+{$L inftrees.obj}
+{$L trees.obj}
+{$L uncompr.obj}
+{$L zutil.obj}
+
+function adler32; external;
+function adler32_combine; external;
+function compress; external;
+function compress2; external;
+function compressBound; external;
+function crc32; external;
+function crc32_combine; external;
+function deflate; external;
+function deflateBound; external;
+function deflateCopy; external;
+function deflateEnd; external;
+function deflateInit_; external;
+function deflateInit2_; external;
+function deflateParams; external;
+function deflatePending; external;
+function deflatePrime; external;
+function deflateReset; external;
+function deflateSetDictionary; external;
+function deflateSetHeader; external;
+function deflateTune; external;
+function inflate; external;
+function inflateBack; external;
+function inflateBackEnd; external;
+function inflateBackInit_; external;
+function inflateCopy; external;
+function inflateEnd; external;
+function inflateGetHeader; external;
+function inflateInit_; external;
+function inflateInit2_; external;
+function inflateMark; external;
+function inflatePrime; external;
+function inflateReset; external;
+function inflateReset2; external;
+function inflateSetDictionary; external;
+function inflateSync; external;
+function uncompress; external;
+function zlibCompileFlags; external;
+function zlibVersion; external;
+
+function deflateInit(var strm: z_stream; level: Integer): Integer;
+begin
+ Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function deflateInit2(var strm: z_stream; level, method, windowBits, memLevel,
+ strategy: Integer): Integer;
+begin
+ Result := deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+ ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function inflateInit(var strm: z_stream): Integer;
+begin
+ Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function inflateInit2(var strm: z_stream; windowBits: Integer): Integer;
+begin
+ Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function inflateBackInit(var strm: z_stream;
+ windowBits: Integer; window: PChar): Integer;
+begin
+ Result := inflateBackInit_(strm, windowBits, window,
+ ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function _malloc(Size: Integer): Pointer; cdecl;
+begin
+ GetMem(Result, Size);
+end;
+
+procedure _free(Block: Pointer); cdecl;
+begin
+ FreeMem(Block);
+end;
+
+procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;
+begin
+ FillChar(P^, count, B);
+end;
+
+procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
+begin
+ Move(source^, dest^, count);
+end;
+
+end.
diff --git a/xs/src/png/zlib/contrib/puff/Makefile b/xs/src/png/zlib/contrib/puff/Makefile
new file mode 100644
index 000000000..0e2594c80
--- /dev/null
+++ b/xs/src/png/zlib/contrib/puff/Makefile
@@ -0,0 +1,42 @@
+CFLAGS=-O
+
+puff: puff.o pufftest.o
+
+puff.o: puff.h
+
+pufftest.o: puff.h
+
+test: puff
+ puff zeros.raw
+
+puft: puff.c puff.h pufftest.o
+ cc -fprofile-arcs -ftest-coverage -o puft puff.c pufftest.o
+
+# puff full coverage test (should say 100%)
+cov: puft
+ @rm -f *.gcov *.gcda
+ @puft -w zeros.raw 2>&1 | cat > /dev/null
+ @echo '04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+ @echo '00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+ @echo '00 00 00 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 254
+ @echo '00 01 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+ @echo '01 01 00 fe ff 0a' | xxd -r -p | puft -f 2>&1 | cat > /dev/null
+ @echo '02 7e ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246
+ @echo '02' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+ @echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+ @echo '04 80 49 92 24 49 92 24 71 ff ff 93 11 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 249
+ @echo '04 c0 81 08 00 00 00 00 20 7f eb 0b 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246
+ @echo '0b 00 00' | xxd -r -p | puft -f 2>&1 | cat > /dev/null
+ @echo '1a 07' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246
+ @echo '0c c0 81 00 00 00 00 00 90 ff 6b 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 245
+ @puft -f zeros.raw 2>&1 | cat > /dev/null
+ @echo 'fc 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 253
+ @echo '04 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 252
+ @echo '04 00 24 49' | xxd -r -p | puft 2> /dev/null || test $$? -eq 251
+ @echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 84' | xxd -r -p | puft 2> /dev/null || test $$? -eq 248
+ @echo '04 00 24 e9 ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 250
+ @echo '04 00 24 e9 ff 6d' | xxd -r -p | puft 2> /dev/null || test $$? -eq 247
+ @gcov -n puff.c
+
+clean:
+ rm -f puff puft *.o *.gc*
diff --git a/xs/src/png/zlib/contrib/puff/README b/xs/src/png/zlib/contrib/puff/README
new file mode 100644
index 000000000..bbc4cb595
--- /dev/null
+++ b/xs/src/png/zlib/contrib/puff/README
@@ -0,0 +1,63 @@
+Puff -- A Simple Inflate
+3 Mar 2003
+Mark Adler
+madler@alumni.caltech.edu
+
+What this is --
+
+puff.c provides the routine puff() to decompress the deflate data format. It
+does so more slowly than zlib, but the code is about one-fifth the size of the
+inflate code in zlib, and written to be very easy to read.
+
+Why I wrote this --
+
+puff.c was written to document the deflate format unambiguously, by virtue of
+being working C code. It is meant to supplement RFC 1951, which formally
+describes the deflate format. I have received many questions on details of the
+deflate format, and I hope that reading this code will answer those questions.
+puff.c is heavily commented with details of the deflate format, especially
+those little nooks and cranies of the format that might not be obvious from a
+specification.
+
+puff.c may also be useful in applications where code size or memory usage is a
+very limited resource, and speed is not as important.
+
+How to use it --
+
+Well, most likely you should just be reading puff.c and using zlib for actual
+applications, but if you must ...
+
+Include puff.h in your code, which provides this prototype:
+
+int puff(unsigned char *dest, /* pointer to destination pointer */
+ unsigned long *destlen, /* amount of output space */
+ unsigned char *source, /* pointer to source data pointer */
+ unsigned long *sourcelen); /* amount of input available */
+
+Then you can call puff() to decompress a deflate stream that is in memory in
+its entirety at source, to a sufficiently sized block of memory for the
+decompressed data at dest. puff() is the only external symbol in puff.c The
+only C library functions that puff.c needs are setjmp() and longjmp(), which
+are used to simplify error checking in the code to improve readabilty. puff.c
+does no memory allocation, and uses less than 2K bytes off of the stack.
+
+If destlen is not enough space for the uncompressed data, then inflate will
+return an error without writing more than destlen bytes. Note that this means
+that in order to decompress the deflate data successfully, you need to know
+the size of the uncompressed data ahead of time.
+
+If needed, puff() can determine the size of the uncompressed data with no
+output space. This is done by passing dest equal to (unsigned char *)0. Then
+the initial value of *destlen is ignored and *destlen is set to the length of
+the uncompressed data. So if the size of the uncompressed data is not known,
+then two passes of puff() can be used--first to determine the size, and second
+to do the actual inflation after allocating the appropriate memory. Not
+pretty, but it works. (This is one of the reasons you should be using zlib.)
+
+The deflate format is self-terminating. If the deflate stream does not end
+in *sourcelen bytes, puff() will return an error without reading at or past
+endsource.
+
+On return, *sourcelen is updated to the amount of input data consumed, and
+*destlen is updated to the size of the uncompressed data. See the comments
+in puff.c for the possible return codes for puff().
diff --git a/xs/src/png/zlib/contrib/puff/puff.c b/xs/src/png/zlib/contrib/puff/puff.c
new file mode 100644
index 000000000..c6c90d714
--- /dev/null
+++ b/xs/src/png/zlib/contrib/puff/puff.c
@@ -0,0 +1,840 @@
+/*
+ * puff.c
+ * Copyright (C) 2002-2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in puff.h
+ * version 2.3, 21 Jan 2013
+ *
+ * puff.c is a simple inflate written to be an unambiguous way to specify the
+ * deflate format. It is not written for speed but rather simplicity. As a
+ * side benefit, this code might actually be useful when small code is more
+ * important than speed, such as bootstrap applications. For typical deflate
+ * data, zlib's inflate() is about four times as fast as puff(). zlib's
+ * inflate compiles to around 20K on my machine, whereas puff.c compiles to
+ * around 4K on my machine (a PowerPC using GNU cc). If the faster decode()
+ * function here is used, then puff() is only twice as slow as zlib's
+ * inflate().
+ *
+ * All dynamically allocated memory comes from the stack. The stack required
+ * is less than 2K bytes. This code is compatible with 16-bit int's and
+ * assumes that long's are at least 32 bits. puff.c uses the short data type,
+ * assumed to be 16 bits, for arrays in order to conserve memory. The code
+ * works whether integers are stored big endian or little endian.
+ *
+ * In the comments below are "Format notes" that describe the inflate process
+ * and document some of the less obvious aspects of the format. This source
+ * code is meant to supplement RFC 1951, which formally describes the deflate
+ * format:
+ *
+ * http://www.zlib.org/rfc-deflate.html
+ */
+
+/*
+ * Change history:
+ *
+ * 1.0 10 Feb 2002 - First version
+ * 1.1 17 Feb 2002 - Clarifications of some comments and notes
+ * - Update puff() dest and source pointers on negative
+ * errors to facilitate debugging deflators
+ * - Remove longest from struct huffman -- not needed
+ * - Simplify offs[] index in construct()
+ * - Add input size and checking, using longjmp() to
+ * maintain easy readability
+ * - Use short data type for large arrays
+ * - Use pointers instead of long to specify source and
+ * destination sizes to avoid arbitrary 4 GB limits
+ * 1.2 17 Mar 2002 - Add faster version of decode(), doubles speed (!),
+ * but leave simple version for readabilty
+ * - Make sure invalid distances detected if pointers
+ * are 16 bits
+ * - Fix fixed codes table error
+ * - Provide a scanning mode for determining size of
+ * uncompressed data
+ * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Gailly]
+ * - Add a puff.h file for the interface
+ * - Add braces in puff() for else do [Gailly]
+ * - Use indexes instead of pointers for readability
+ * 1.4 31 Mar 2002 - Simplify construct() code set check
+ * - Fix some comments
+ * - Add FIXLCODES #define
+ * 1.5 6 Apr 2002 - Minor comment fixes
+ * 1.6 7 Aug 2002 - Minor format changes
+ * 1.7 3 Mar 2003 - Added test code for distribution
+ * - Added zlib-like license
+ * 1.8 9 Jan 2004 - Added some comments on no distance codes case
+ * 1.9 21 Feb 2008 - Fix bug on 16-bit integer architectures [Pohland]
+ * - Catch missing end-of-block symbol error
+ * 2.0 25 Jul 2008 - Add #define to permit distance too far back
+ * - Add option in TEST code for puff to write the data
+ * - Add option in TEST code to skip input bytes
+ * - Allow TEST code to read from piped stdin
+ * 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers
+ * - Avoid unsigned comparisons for even happier compilers
+ * 2.2 25 Apr 2010 - Fix bug in variable initializations [Oberhumer]
+ * - Add const where appropriate [Oberhumer]
+ * - Split if's and ?'s for coverage testing
+ * - Break out test code to separate file
+ * - Move NIL to puff.h
+ * - Allow incomplete code only if single code length is 1
+ * - Add full code coverage test to Makefile
+ * 2.3 21 Jan 2013 - Check for invalid code length codes in dynamic blocks
+ */
+
+#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
+#include "puff.h" /* prototype for puff() */
+
+#define local static /* for local function definitions */
+
+/*
+ * Maximums for allocations and loops. It is not useful to change these --
+ * they are fixed by the deflate format.
+ */
+#define MAXBITS 15 /* maximum bits in a code */
+#define MAXLCODES 286 /* maximum number of literal/length codes */
+#define MAXDCODES 30 /* maximum number of distance codes */
+#define MAXCODES (MAXLCODES+MAXDCODES) /* maximum codes lengths to read */
+#define FIXLCODES 288 /* number of fixed literal/length codes */
+
+/* input and output state */
+struct state {
+ /* output state */
+ unsigned char *out; /* output buffer */
+ unsigned long outlen; /* available space at out */
+ unsigned long outcnt; /* bytes written to out so far */
+
+ /* input state */
+ const unsigned char *in; /* input buffer */
+ unsigned long inlen; /* available input at in */
+ unsigned long incnt; /* bytes read so far */
+ int bitbuf; /* bit buffer */
+ int bitcnt; /* number of bits in bit buffer */
+
+ /* input limit error return state for bits() and decode() */
+ jmp_buf env;
+};
+
+/*
+ * Return need bits from the input stream. This always leaves less than
+ * eight bits in the buffer. bits() works properly for need == 0.
+ *
+ * Format notes:
+ *
+ * - Bits are stored in bytes from the least significant bit to the most
+ * significant bit. Therefore bits are dropped from the bottom of the bit
+ * buffer, using shift right, and new bytes are appended to the top of the
+ * bit buffer, using shift left.
+ */
+local int bits(struct state *s, int need)
+{
+ long val; /* bit accumulator (can use up to 20 bits) */
+
+ /* load at least need bits into val */
+ val = s->bitbuf;
+ while (s->bitcnt < need) {
+ if (s->incnt == s->inlen)
+ longjmp(s->env, 1); /* out of input */
+ val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
+ s->bitcnt += 8;
+ }
+
+ /* drop need bits and update buffer, always zero to seven bits left */
+ s->bitbuf = (int)(val >> need);
+ s->bitcnt -= need;
+
+ /* return need bits, zeroing the bits above that */
+ return (int)(val & ((1L << need) - 1));
+}
+
+/*
+ * Process a stored block.
+ *
+ * Format notes:
+ *
+ * - After the two-bit stored block type (00), the stored block length and
+ * stored bytes are byte-aligned for fast copying. Therefore any leftover
+ * bits in the byte that has the last bit of the type, as many as seven, are
+ * discarded. The value of the discarded bits are not defined and should not
+ * be checked against any expectation.
+ *
+ * - The second inverted copy of the stored block length does not have to be
+ * checked, but it's probably a good idea to do so anyway.
+ *
+ * - A stored block can have zero length. This is sometimes used to byte-align
+ * subsets of the compressed data for random access or partial recovery.
+ */
+local int stored(struct state *s)
+{
+ unsigned len; /* length of stored block */
+
+ /* discard leftover bits from current byte (assumes s->bitcnt < 8) */
+ s->bitbuf = 0;
+ s->bitcnt = 0;
+
+ /* get length and check against its one's complement */
+ if (s->incnt + 4 > s->inlen)
+ return 2; /* not enough input */
+ len = s->in[s->incnt++];
+ len |= s->in[s->incnt++] << 8;
+ if (s->in[s->incnt++] != (~len & 0xff) ||
+ s->in[s->incnt++] != ((~len >> 8) & 0xff))
+ return -2; /* didn't match complement! */
+
+ /* copy len bytes from in to out */
+ if (s->incnt + len > s->inlen)
+ return 2; /* not enough input */
+ if (s->out != NIL) {
+ if (s->outcnt + len > s->outlen)
+ return 1; /* not enough output space */
+ while (len--)
+ s->out[s->outcnt++] = s->in[s->incnt++];
+ }
+ else { /* just scanning */
+ s->outcnt += len;
+ s->incnt += len;
+ }
+
+ /* done with a valid stored block */
+ return 0;
+}
+
+/*
+ * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
+ * each length, which for a canonical code are stepped through in order.
+ * symbol[] are the symbol values in canonical order, where the number of
+ * entries is the sum of the counts in count[]. The decoding process can be
+ * seen in the function decode() below.
+ */
+struct huffman {
+ short *count; /* number of symbols of each length */
+ short *symbol; /* canonically ordered symbols */
+};
+
+/*
+ * Decode a code from the stream s using huffman table h. Return the symbol or
+ * a negative value if there is an error. If all of the lengths are zero, i.e.
+ * an empty code, or if the code is incomplete and an invalid code is received,
+ * then -10 is returned after reading MAXBITS bits.
+ *
+ * Format notes:
+ *
+ * - The codes as stored in the compressed data are bit-reversed relative to
+ * a simple integer ordering of codes of the same lengths. Hence below the
+ * bits are pulled from the compressed data one at a time and used to
+ * build the code value reversed from what is in the stream in order to
+ * permit simple integer comparisons for decoding. A table-based decoding
+ * scheme (as used in zlib) does not need to do this reversal.
+ *
+ * - The first code for the shortest length is all zeros. Subsequent codes of
+ * the same length are simply integer increments of the previous code. When
+ * moving up a length, a zero bit is appended to the code. For a complete
+ * code, the last code of the longest length will be all ones.
+ *
+ * - Incomplete codes are handled by this decoder, since they are permitted
+ * in the deflate format. See the format notes for fixed() and dynamic().
+ */
+#ifdef SLOW
+local int decode(struct state *s, const struct huffman *h)
+{
+ int len; /* current number of bits in code */
+ int code; /* len bits being decoded */
+ int first; /* first code of length len */
+ int count; /* number of codes of length len */
+ int index; /* index of first code of length len in symbol table */
+
+ code = first = index = 0;
+ for (len = 1; len <= MAXBITS; len++) {
+ code |= bits(s, 1); /* get next bit */
+ count = h->count[len];
+ if (code - count < first) /* if length len, return symbol */
+ return h->symbol[index + (code - first)];
+ index += count; /* else update for next length */
+ first += count;
+ first <<= 1;
+ code <<= 1;
+ }
+ return -10; /* ran out of codes */
+}
+
+/*
+ * A faster version of decode() for real applications of this code. It's not
+ * as readable, but it makes puff() twice as fast. And it only makes the code
+ * a few percent larger.
+ */
+#else /* !SLOW */
+local int decode(struct state *s, const struct huffman *h)
+{
+ int len; /* current number of bits in code */
+ int code; /* len bits being decoded */
+ int first; /* first code of length len */
+ int count; /* number of codes of length len */
+ int index; /* index of first code of length len in symbol table */
+ int bitbuf; /* bits from stream */
+ int left; /* bits left in next or left to process */
+ short *next; /* next number of codes */
+
+ bitbuf = s->bitbuf;
+ left = s->bitcnt;
+ code = first = index = 0;
+ len = 1;
+ next = h->count + 1;
+ while (1) {
+ while (left--) {
+ code |= bitbuf & 1;
+ bitbuf >>= 1;
+ count = *next++;
+ if (code - count < first) { /* if length len, return symbol */
+ s->bitbuf = bitbuf;
+ s->bitcnt = (s->bitcnt - len) & 7;
+ return h->symbol[index + (code - first)];
+ }
+ index += count; /* else update for next length */
+ first += count;
+ first <<= 1;
+ code <<= 1;
+ len++;
+ }
+ left = (MAXBITS+1) - len;
+ if (left == 0)
+ break;
+ if (s->incnt == s->inlen)
+ longjmp(s->env, 1); /* out of input */
+ bitbuf = s->in[s->incnt++];
+ if (left > 8)
+ left = 8;
+ }
+ return -10; /* ran out of codes */
+}
+#endif /* SLOW */
+
+/*
+ * Given the list of code lengths length[0..n-1] representing a canonical
+ * Huffman code for n symbols, construct the tables required to decode those
+ * codes. Those tables are the number of codes of each length, and the symbols
+ * sorted by length, retaining their original order within each length. The
+ * return value is zero for a complete code set, negative for an over-
+ * subscribed code set, and positive for an incomplete code set. The tables
+ * can be used if the return value is zero or positive, but they cannot be used
+ * if the return value is negative. If the return value is zero, it is not
+ * possible for decode() using that table to return an error--any stream of
+ * enough bits will resolve to a symbol. If the return value is positive, then
+ * it is possible for decode() using that table to return an error for received
+ * codes past the end of the incomplete lengths.
+ *
+ * Not used by decode(), but used for error checking, h->count[0] is the number
+ * of the n symbols not in the code. So n - h->count[0] is the number of
+ * codes. This is useful for checking for incomplete codes that have more than
+ * one symbol, which is an error in a dynamic block.
+ *
+ * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS
+ * This is assured by the construction of the length arrays in dynamic() and
+ * fixed() and is not verified by construct().
+ *
+ * Format notes:
+ *
+ * - Permitted and expected examples of incomplete codes are one of the fixed
+ * codes and any code with a single symbol which in deflate is coded as one
+ * bit instead of zero bits. See the format notes for fixed() and dynamic().
+ *
+ * - Within a given code length, the symbols are kept in ascending order for
+ * the code bits definition.
+ */
+local int construct(struct huffman *h, const short *length, int n)
+{
+ int symbol; /* current symbol when stepping through length[] */
+ int len; /* current length when stepping through h->count[] */
+ int left; /* number of possible codes left of current length */
+ short offs[MAXBITS+1]; /* offsets in symbol table for each length */
+
+ /* count number of codes of each length */
+ for (len = 0; len <= MAXBITS; len++)
+ h->count[len] = 0;
+ for (symbol = 0; symbol < n; symbol++)
+ (h->count[length[symbol]])++; /* assumes lengths are within bounds */
+ if (h->count[0] == n) /* no codes! */
+ return 0; /* complete, but decode() will fail */
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1; /* one possible code of zero length */
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1; /* one more bit, double codes left */
+ left -= h->count[len]; /* deduct count from possible codes */
+ if (left < 0)
+ return left; /* over-subscribed--return negative */
+ } /* left > 0 means incomplete */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + h->count[len];
+
+ /*
+ * put symbols in table sorted by length, by symbol order within each
+ * length
+ */
+ for (symbol = 0; symbol < n; symbol++)
+ if (length[symbol] != 0)
+ h->symbol[offs[length[symbol]]++] = symbol;
+
+ /* return zero for complete set, positive for incomplete set */
+ return left;
+}
+
+/*
+ * Decode literal/length and distance codes until an end-of-block code.
+ *
+ * Format notes:
+ *
+ * - Compressed data that is after the block type if fixed or after the code
+ * description if dynamic is a combination of literals and length/distance
+ * pairs terminated by and end-of-block code. Literals are simply Huffman
+ * coded bytes. A length/distance pair is a coded length followed by a
+ * coded distance to represent a string that occurs earlier in the
+ * uncompressed data that occurs again at the current location.
+ *
+ * - Literals, lengths, and the end-of-block code are combined into a single
+ * code of up to 286 symbols. They are 256 literals (0..255), 29 length
+ * symbols (257..285), and the end-of-block symbol (256).
+ *
+ * - There are 256 possible lengths (3..258), and so 29 symbols are not enough
+ * to represent all of those. Lengths 3..10 and 258 are in fact represented
+ * by just a length symbol. Lengths 11..257 are represented as a symbol and
+ * some number of extra bits that are added as an integer to the base length
+ * of the length symbol. The number of extra bits is determined by the base
+ * length symbol. These are in the static arrays below, lens[] for the base
+ * lengths and lext[] for the corresponding number of extra bits.
+ *
+ * - The reason that 258 gets its own symbol is that the longest length is used
+ * often in highly redundant files. Note that 258 can also be coded as the
+ * base value 227 plus the maximum extra value of 31. While a good deflate
+ * should never do this, it is not an error, and should be decoded properly.
+ *
+ * - If a length is decoded, including its extra bits if any, then it is
+ * followed a distance code. There are up to 30 distance symbols. Again
+ * there are many more possible distances (1..32768), so extra bits are added
+ * to a base value represented by the symbol. The distances 1..4 get their
+ * own symbol, but the rest require extra bits. The base distances and
+ * corresponding number of extra bits are below in the static arrays dist[]
+ * and dext[].
+ *
+ * - Literal bytes are simply written to the output. A length/distance pair is
+ * an instruction to copy previously uncompressed bytes to the output. The
+ * copy is from distance bytes back in the output stream, copying for length
+ * bytes.
+ *
+ * - Distances pointing before the beginning of the output data are not
+ * permitted.
+ *
+ * - Overlapped copies, where the length is greater than the distance, are
+ * allowed and common. For example, a distance of one and a length of 258
+ * simply copies the last byte 258 times. A distance of four and a length of
+ * twelve copies the last four bytes three times. A simple forward copy
+ * ignoring whether the length is greater than the distance or not implements
+ * this correctly. You should not use memcpy() since its behavior is not
+ * defined for overlapped arrays. You should not use memmove() or bcopy()
+ * since though their behavior -is- defined for overlapping arrays, it is
+ * defined to do the wrong thing in this case.
+ */
+local int codes(struct state *s,
+ const struct huffman *lencode,
+ const struct huffman *distcode)
+{
+ int symbol; /* decoded symbol */
+ int len; /* length for copy */
+ unsigned dist; /* distance for copy */
+ static const short lens[29] = { /* Size base for length codes 257..285 */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
+ static const short lext[29] = { /* Extra bits for length codes 257..285 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
+ static const short dists[30] = { /* Offset base for distance codes 0..29 */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577};
+ static const short dext[30] = { /* Extra bits for distance codes 0..29 */
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+ 12, 12, 13, 13};
+
+ /* decode literals and length/distance pairs */
+ do {
+ symbol = decode(s, lencode);
+ if (symbol < 0)
+ return symbol; /* invalid symbol */
+ if (symbol < 256) { /* literal: symbol is the byte */
+ /* write out the literal */
+ if (s->out != NIL) {
+ if (s->outcnt == s->outlen)
+ return 1;
+ s->out[s->outcnt] = symbol;
+ }
+ s->outcnt++;
+ }
+ else if (symbol > 256) { /* length */
+ /* get and compute length */
+ symbol -= 257;
+ if (symbol >= 29)
+ return -10; /* invalid fixed code */
+ len = lens[symbol] + bits(s, lext[symbol]);
+
+ /* get and check distance */
+ symbol = decode(s, distcode);
+ if (symbol < 0)
+ return symbol; /* invalid symbol */
+ dist = dists[symbol] + bits(s, dext[symbol]);
+#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ if (dist > s->outcnt)
+ return -11; /* distance too far back */
+#endif
+
+ /* copy length bytes from distance bytes back */
+ if (s->out != NIL) {
+ if (s->outcnt + len > s->outlen)
+ return 1;
+ while (len--) {
+ s->out[s->outcnt] =
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ dist > s->outcnt ?
+ 0 :
+#endif
+ s->out[s->outcnt - dist];
+ s->outcnt++;
+ }
+ }
+ else
+ s->outcnt += len;
+ }
+ } while (symbol != 256); /* end of block symbol */
+
+ /* done with a valid fixed or dynamic block */
+ return 0;
+}
+
+/*
+ * Process a fixed codes block.
+ *
+ * Format notes:
+ *
+ * - This block type can be useful for compressing small amounts of data for
+ * which the size of the code descriptions in a dynamic block exceeds the
+ * benefit of custom codes for that block. For fixed codes, no bits are
+ * spent on code descriptions. Instead the code lengths for literal/length
+ * codes and distance codes are fixed. The specific lengths for each symbol
+ * can be seen in the "for" loops below.
+ *
+ * - The literal/length code is complete, but has two symbols that are invalid
+ * and should result in an error if received. This cannot be implemented
+ * simply as an incomplete code since those two symbols are in the "middle"
+ * of the code. They are eight bits long and the longest literal/length\
+ * code is nine bits. Therefore the code must be constructed with those
+ * symbols, and the invalid symbols must be detected after decoding.
+ *
+ * - The fixed distance codes also have two invalid symbols that should result
+ * in an error if received. Since all of the distance codes are the same
+ * length, this can be implemented as an incomplete code. Then the invalid
+ * codes are detected while decoding.
+ */
+local int fixed(struct state *s)
+{
+ static int virgin = 1;
+ static short lencnt[MAXBITS+1], lensym[FIXLCODES];
+ static short distcnt[MAXBITS+1], distsym[MAXDCODES];
+ static struct huffman lencode, distcode;
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ int symbol;
+ short lengths[FIXLCODES];
+
+ /* construct lencode and distcode */
+ lencode.count = lencnt;
+ lencode.symbol = lensym;
+ distcode.count = distcnt;
+ distcode.symbol = distsym;
+
+ /* literal/length table */
+ for (symbol = 0; symbol < 144; symbol++)
+ lengths[symbol] = 8;
+ for (; symbol < 256; symbol++)
+ lengths[symbol] = 9;
+ for (; symbol < 280; symbol++)
+ lengths[symbol] = 7;
+ for (; symbol < FIXLCODES; symbol++)
+ lengths[symbol] = 8;
+ construct(&lencode, lengths, FIXLCODES);
+
+ /* distance table */
+ for (symbol = 0; symbol < MAXDCODES; symbol++)
+ lengths[symbol] = 5;
+ construct(&distcode, lengths, MAXDCODES);
+
+ /* do this just once */
+ virgin = 0;
+ }
+
+ /* decode data until end-of-block code */
+ return codes(s, &lencode, &distcode);
+}
+
+/*
+ * Process a dynamic codes block.
+ *
+ * Format notes:
+ *
+ * - A dynamic block starts with a description of the literal/length and
+ * distance codes for that block. New dynamic blocks allow the compressor to
+ * rapidly adapt to changing data with new codes optimized for that data.
+ *
+ * - The codes used by the deflate format are "canonical", which means that
+ * the actual bits of the codes are generated in an unambiguous way simply
+ * from the number of bits in each code. Therefore the code descriptions
+ * are simply a list of code lengths for each symbol.
+ *
+ * - The code lengths are stored in order for the symbols, so lengths are
+ * provided for each of the literal/length symbols, and for each of the
+ * distance symbols.
+ *
+ * - If a symbol is not used in the block, this is represented by a zero as
+ * as the code length. This does not mean a zero-length code, but rather
+ * that no code should be created for this symbol. There is no way in the
+ * deflate format to represent a zero-length code.
+ *
+ * - The maximum number of bits in a code is 15, so the possible lengths for
+ * any code are 1..15.
+ *
+ * - The fact that a length of zero is not permitted for a code has an
+ * interesting consequence. Normally if only one symbol is used for a given
+ * code, then in fact that code could be represented with zero bits. However
+ * in deflate, that code has to be at least one bit. So for example, if
+ * only a single distance base symbol appears in a block, then it will be
+ * represented by a single code of length one, in particular one 0 bit. This
+ * is an incomplete code, since if a 1 bit is received, it has no meaning,
+ * and should result in an error. So incomplete distance codes of one symbol
+ * should be permitted, and the receipt of invalid codes should be handled.
+ *
+ * - It is also possible to have a single literal/length code, but that code
+ * must be the end-of-block code, since every dynamic block has one. This
+ * is not the most efficient way to create an empty block (an empty fixed
+ * block is fewer bits), but it is allowed by the format. So incomplete
+ * literal/length codes of one symbol should also be permitted.
+ *
+ * - If there are only literal codes and no lengths, then there are no distance
+ * codes. This is represented by one distance code with zero bits.
+ *
+ * - The list of up to 286 length/literal lengths and up to 30 distance lengths
+ * are themselves compressed using Huffman codes and run-length encoding. In
+ * the list of code lengths, a 0 symbol means no code, a 1..15 symbol means
+ * that length, and the symbols 16, 17, and 18 are run-length instructions.
+ * Each of 16, 17, and 18 are follwed by extra bits to define the length of
+ * the run. 16 copies the last length 3 to 6 times. 17 represents 3 to 10
+ * zero lengths, and 18 represents 11 to 138 zero lengths. Unused symbols
+ * are common, hence the special coding for zero lengths.
+ *
+ * - The symbols for 0..18 are Huffman coded, and so that code must be
+ * described first. This is simply a sequence of up to 19 three-bit values
+ * representing no code (0) or the code length for that symbol (1..7).
+ *
+ * - A dynamic block starts with three fixed-size counts from which is computed
+ * the number of literal/length code lengths, the number of distance code
+ * lengths, and the number of code length code lengths (ok, you come up with
+ * a better name!) in the code descriptions. For the literal/length and
+ * distance codes, lengths after those provided are considered zero, i.e. no
+ * code. The code length code lengths are received in a permuted order (see
+ * the order[] array below) to make a short code length code length list more
+ * likely. As it turns out, very short and very long codes are less likely
+ * to be seen in a dynamic code description, hence what may appear initially
+ * to be a peculiar ordering.
+ *
+ * - Given the number of literal/length code lengths (nlen) and distance code
+ * lengths (ndist), then they are treated as one long list of nlen + ndist
+ * code lengths. Therefore run-length coding can and often does cross the
+ * boundary between the two sets of lengths.
+ *
+ * - So to summarize, the code description at the start of a dynamic block is
+ * three counts for the number of code lengths for the literal/length codes,
+ * the distance codes, and the code length codes. This is followed by the
+ * code length code lengths, three bits each. This is used to construct the
+ * code length code which is used to read the remainder of the lengths. Then
+ * the literal/length code lengths and distance lengths are read as a single
+ * set of lengths using the code length codes. Codes are constructed from
+ * the resulting two sets of lengths, and then finally you can start
+ * decoding actual compressed data in the block.
+ *
+ * - For reference, a "typical" size for the code description in a dynamic
+ * block is around 80 bytes.
+ */
+local int dynamic(struct state *s)
+{
+ int nlen, ndist, ncode; /* number of lengths in descriptor */
+ int index; /* index of lengths[] */
+ int err; /* construct() return value */
+ short lengths[MAXCODES]; /* descriptor code lengths */
+ short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */
+ short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */
+ struct huffman lencode, distcode; /* length and distance codes */
+ static const short order[19] = /* permutation of code length codes */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ /* construct lencode and distcode */
+ lencode.count = lencnt;
+ lencode.symbol = lensym;
+ distcode.count = distcnt;
+ distcode.symbol = distsym;
+
+ /* get number of lengths in each table, check lengths */
+ nlen = bits(s, 5) + 257;
+ ndist = bits(s, 5) + 1;
+ ncode = bits(s, 4) + 4;
+ if (nlen > MAXLCODES || ndist > MAXDCODES)
+ return -3; /* bad counts */
+
+ /* read code length code lengths (really), missing lengths are zero */
+ for (index = 0; index < ncode; index++)
+ lengths[order[index]] = bits(s, 3);
+ for (; index < 19; index++)
+ lengths[order[index]] = 0;
+
+ /* build huffman table for code lengths codes (use lencode temporarily) */
+ err = construct(&lencode, lengths, 19);
+ if (err != 0) /* require complete code set here */
+ return -4;
+
+ /* read length/literal and distance code length tables */
+ index = 0;
+ while (index < nlen + ndist) {
+ int symbol; /* decoded value */
+ int len; /* last length to repeat */
+
+ symbol = decode(s, &lencode);
+ if (symbol < 0)
+ return symbol; /* invalid symbol */
+ if (symbol < 16) /* length in 0..15 */
+ lengths[index++] = symbol;
+ else { /* repeat instruction */
+ len = 0; /* assume repeating zeros */
+ if (symbol == 16) { /* repeat last length 3..6 times */
+ if (index == 0)
+ return -5; /* no last length! */
+ len = lengths[index - 1]; /* last length */
+ symbol = 3 + bits(s, 2);
+ }
+ else if (symbol == 17) /* repeat zero 3..10 times */
+ symbol = 3 + bits(s, 3);
+ else /* == 18, repeat zero 11..138 times */
+ symbol = 11 + bits(s, 7);
+ if (index + symbol > nlen + ndist)
+ return -6; /* too many lengths! */
+ while (symbol--) /* repeat last or zero symbol times */
+ lengths[index++] = len;
+ }
+ }
+
+ /* check for end-of-block code -- there better be one! */
+ if (lengths[256] == 0)
+ return -9;
+
+ /* build huffman table for literal/length codes */
+ err = construct(&lencode, lengths, nlen);
+ if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
+ return -7; /* incomplete code ok only for single length 1 code */
+
+ /* build huffman table for distance codes */
+ err = construct(&distcode, lengths + nlen, ndist);
+ if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
+ return -8; /* incomplete code ok only for single length 1 code */
+
+ /* decode data until end-of-block code */
+ return codes(s, &lencode, &distcode);
+}
+
+/*
+ * Inflate source to dest. On return, destlen and sourcelen are updated to the
+ * size of the uncompressed data and the size of the deflate data respectively.
+ * On success, the return value of puff() is zero. If there is an error in the
+ * source data, i.e. it is not in the deflate format, then a negative value is
+ * returned. If there is not enough input available or there is not enough
+ * output space, then a positive error is returned. In that case, destlen and
+ * sourcelen are not updated to facilitate retrying from the beginning with the
+ * provision of more input data or more output space. In the case of invalid
+ * inflate data (a negative error), the dest and source pointers are updated to
+ * facilitate the debugging of deflators.
+ *
+ * puff() also has a mode to determine the size of the uncompressed output with
+ * no output written. For this dest must be (unsigned char *)0. In this case,
+ * the input value of *destlen is ignored, and on return *destlen is set to the
+ * size of the uncompressed output.
+ *
+ * The return codes are:
+ *
+ * 2: available inflate data did not terminate
+ * 1: output space exhausted before completing inflate
+ * 0: successful inflate
+ * -1: invalid block type (type == 3)
+ * -2: stored block length did not match one's complement
+ * -3: dynamic block code description: too many length or distance codes
+ * -4: dynamic block code description: code lengths codes incomplete
+ * -5: dynamic block code description: repeat lengths with no first length
+ * -6: dynamic block code description: repeat more than specified lengths
+ * -7: dynamic block code description: invalid literal/length code lengths
+ * -8: dynamic block code description: invalid distance code lengths
+ * -9: dynamic block code description: missing end-of-block code
+ * -10: invalid literal/length or distance code in fixed or dynamic block
+ * -11: distance is too far back in fixed or dynamic block
+ *
+ * Format notes:
+ *
+ * - Three bits are read for each block to determine the kind of block and
+ * whether or not it is the last block. Then the block is decoded and the
+ * process repeated if it was not the last block.
+ *
+ * - The leftover bits in the last byte of the deflate data after the last
+ * block (if it was a fixed or dynamic block) are undefined and have no
+ * expected values to check.
+ */
+int puff(unsigned char *dest, /* pointer to destination pointer */
+ unsigned long *destlen, /* amount of output space */
+ const unsigned char *source, /* pointer to source data pointer */
+ unsigned long *sourcelen) /* amount of input available */
+{
+ struct state s; /* input/output state */
+ int last, type; /* block information */
+ int err; /* return value */
+
+ /* initialize output state */
+ s.out = dest;
+ s.outlen = *destlen; /* ignored if dest is NIL */
+ s.outcnt = 0;
+
+ /* initialize input state */
+ s.in = source;
+ s.inlen = *sourcelen;
+ s.incnt = 0;
+ s.bitbuf = 0;
+ s.bitcnt = 0;
+
+ /* return if bits() or decode() tries to read past available input */
+ if (setjmp(s.env) != 0) /* if came back here via longjmp() */
+ err = 2; /* then skip do-loop, return error */
+ else {
+ /* process blocks until last block or error */
+ do {
+ last = bits(&s, 1); /* one if last block */
+ type = bits(&s, 2); /* block type 0..3 */
+ err = type == 0 ?
+ stored(&s) :
+ (type == 1 ?
+ fixed(&s) :
+ (type == 2 ?
+ dynamic(&s) :
+ -1)); /* type == 3, invalid */
+ if (err != 0)
+ break; /* return with error */
+ } while (!last);
+ }
+
+ /* update the lengths and return */
+ if (err <= 0) {
+ *destlen = s.outcnt;
+ *sourcelen = s.incnt;
+ }
+ return err;
+}
diff --git a/xs/src/png/zlib/contrib/puff/puff.h b/xs/src/png/zlib/contrib/puff/puff.h
new file mode 100644
index 000000000..e23a24543
--- /dev/null
+++ b/xs/src/png/zlib/contrib/puff/puff.h
@@ -0,0 +1,35 @@
+/* puff.h
+ Copyright (C) 2002-2013 Mark Adler, all rights reserved
+ version 2.3, 21 Jan 2013
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the author be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Mark Adler madler@alumni.caltech.edu
+ */
+
+
+/*
+ * See puff.c for purpose and usage.
+ */
+#ifndef NIL
+# define NIL ((unsigned char *)0) /* for no output option */
+#endif
+
+int puff(unsigned char *dest, /* pointer to destination pointer */
+ unsigned long *destlen, /* amount of output space */
+ const unsigned char *source, /* pointer to source data pointer */
+ unsigned long *sourcelen); /* amount of input available */
diff --git a/xs/src/png/zlib/contrib/puff/pufftest.c b/xs/src/png/zlib/contrib/puff/pufftest.c
new file mode 100644
index 000000000..776481488
--- /dev/null
+++ b/xs/src/png/zlib/contrib/puff/pufftest.c
@@ -0,0 +1,165 @@
+/*
+ * pufftest.c
+ * Copyright (C) 2002-2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in puff.h
+ * version 2.3, 21 Jan 2013
+ */
+
+/* Example of how to use puff().
+
+ Usage: puff [-w] [-f] [-nnn] file
+ ... | puff [-w] [-f] [-nnn]
+
+ where file is the input file with deflate data, nnn is the number of bytes
+ of input to skip before inflating (e.g. to skip a zlib or gzip header), and
+ -w is used to write the decompressed data to stdout. -f is for coverage
+ testing, and causes pufftest to fail with not enough output space (-f does
+ a write like -w, so -w is not required). */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "puff.h"
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+# include <fcntl.h>
+# include <io.h>
+# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+# define SET_BINARY_MODE(file)
+#endif
+
+#define local static
+
+/* Return size times approximately the cube root of 2, keeping the result as 1,
+ 3, or 5 times a power of 2 -- the result is always > size, until the result
+ is the maximum value of an unsigned long, where it remains. This is useful
+ to keep reallocations less than ~33% over the actual data. */
+local size_t bythirds(size_t size)
+{
+ int n;
+ size_t m;
+
+ m = size;
+ for (n = 0; m; n++)
+ m >>= 1;
+ if (n < 3)
+ return size + 1;
+ n -= 3;
+ m = size >> n;
+ m += m == 6 ? 2 : 1;
+ m <<= n;
+ return m > size ? m : (size_t)(-1);
+}
+
+/* Read the input file *name, or stdin if name is NULL, into allocated memory.
+ Reallocate to larger buffers until the entire file is read in. Return a
+ pointer to the allocated data, or NULL if there was a memory allocation
+ failure. *len is the number of bytes of data read from the input file (even
+ if load() returns NULL). If the input file was empty or could not be opened
+ or read, *len is zero. */
+local void *load(const char *name, size_t *len)
+{
+ size_t size;
+ void *buf, *swap;
+ FILE *in;
+
+ *len = 0;
+ buf = malloc(size = 4096);
+ if (buf == NULL)
+ return NULL;
+ in = name == NULL ? stdin : fopen(name, "rb");
+ if (in != NULL) {
+ for (;;) {
+ *len += fread((char *)buf + *len, 1, size - *len, in);
+ if (*len < size) break;
+ size = bythirds(size);
+ if (size == *len || (swap = realloc(buf, size)) == NULL) {
+ free(buf);
+ buf = NULL;
+ break;
+ }
+ buf = swap;
+ }
+ fclose(in);
+ }
+ return buf;
+}
+
+int main(int argc, char **argv)
+{
+ int ret, put = 0, fail = 0;
+ unsigned skip = 0;
+ char *arg, *name = NULL;
+ unsigned char *source = NULL, *dest;
+ size_t len = 0;
+ unsigned long sourcelen, destlen;
+
+ /* process arguments */
+ while (arg = *++argv, --argc)
+ if (arg[0] == '-') {
+ if (arg[1] == 'w' && arg[2] == 0)
+ put = 1;
+ else if (arg[1] == 'f' && arg[2] == 0)
+ fail = 1, put = 1;
+ else if (arg[1] >= '0' && arg[1] <= '9')
+ skip = (unsigned)atoi(arg + 1);
+ else {
+ fprintf(stderr, "invalid option %s\n", arg);
+ return 3;
+ }
+ }
+ else if (name != NULL) {
+ fprintf(stderr, "only one file name allowed\n");
+ return 3;
+ }
+ else
+ name = arg;
+ source = load(name, &len);
+ if (source == NULL) {
+ fprintf(stderr, "memory allocation failure\n");
+ return 4;
+ }
+ if (len == 0) {
+ fprintf(stderr, "could not read %s, or it was empty\n",
+ name == NULL ? "<stdin>" : name);
+ free(source);
+ return 3;
+ }
+ if (skip >= len) {
+ fprintf(stderr, "skip request of %d leaves no input\n", skip);
+ free(source);
+ return 3;
+ }
+
+ /* test inflate data with offset skip */
+ len -= skip;
+ sourcelen = (unsigned long)len;
+ ret = puff(NIL, &destlen, source + skip, &sourcelen);
+ if (ret)
+ fprintf(stderr, "puff() failed with return code %d\n", ret);
+ else {
+ fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen);
+ if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n",
+ len - sourcelen);
+ }
+
+ /* if requested, inflate again and write decompressd data to stdout */
+ if (put && ret == 0) {
+ if (fail)
+ destlen >>= 1;
+ dest = malloc(destlen);
+ if (dest == NULL) {
+ fprintf(stderr, "memory allocation failure\n");
+ free(source);
+ return 4;
+ }
+ puff(dest, &destlen, source + skip, &sourcelen);
+ SET_BINARY_MODE(stdout);
+ fwrite(dest, 1, destlen, stdout);
+ free(dest);
+ }
+
+ /* clean up */
+ free(source);
+ return ret;
+}
diff --git a/xs/src/png/zlib/contrib/puff/zeros.raw b/xs/src/png/zlib/contrib/puff/zeros.raw
new file mode 100644
index 000000000..0a90e76b3
--- /dev/null
+++ b/xs/src/png/zlib/contrib/puff/zeros.raw
Binary files differ
diff --git a/xs/src/png/zlib/contrib/testzlib/testzlib.c b/xs/src/png/zlib/contrib/testzlib/testzlib.c
new file mode 100644
index 000000000..8626c92ad
--- /dev/null
+++ b/xs/src/png/zlib/contrib/testzlib/testzlib.c
@@ -0,0 +1,275 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+
+#include "zlib.h"
+
+
+void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B)
+{
+ R->HighPart = A.HighPart - B.HighPart;
+ if (A.LowPart >= B.LowPart)
+ R->LowPart = A.LowPart - B.LowPart;
+ else
+ {
+ R->LowPart = A.LowPart - B.LowPart;
+ R->HighPart --;
+ }
+}
+
+#ifdef _M_X64
+// see http://msdn2.microsoft.com/library/twchhe95(en-us,vs.80).aspx for __rdtsc
+unsigned __int64 __rdtsc(void);
+void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
+{
+ // printf("rdtsc = %I64x\n",__rdtsc());
+ pbeginTime64->QuadPart=__rdtsc();
+}
+
+LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
+{
+ LARGE_INTEGER LIres;
+ unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart));
+ LIres.QuadPart=res;
+ // printf("rdtsc = %I64x\n",__rdtsc());
+ return LIres;
+}
+#else
+#ifdef _M_IX86
+void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
+{
+ DWORD dwEdx,dwEax;
+ _asm
+ {
+ rdtsc
+ mov dwEax,eax
+ mov dwEdx,edx
+ }
+ pbeginTime64->LowPart=dwEax;
+ pbeginTime64->HighPart=dwEdx;
+}
+
+void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
+{
+ myGetRDTSC32(pbeginTime64);
+}
+
+LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
+{
+ LARGE_INTEGER LIres,endTime64;
+ myGetRDTSC32(&endTime64);
+
+ LIres.LowPart=LIres.HighPart=0;
+ MyDoMinus64(&LIres,endTime64,beginTime64);
+ return LIres;
+}
+#else
+void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
+{
+}
+
+void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
+{
+}
+
+LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
+{
+ LARGE_INTEGER lr;
+ lr.QuadPart=0;
+ return lr;
+}
+#endif
+#endif
+
+void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf)
+{
+ if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64)))
+ {
+ pbeginTime64->LowPart = GetTickCount();
+ pbeginTime64->HighPart = 0;
+ }
+}
+
+DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
+{
+ LARGE_INTEGER endTime64,ticksPerSecond,ticks;
+ DWORDLONG ticksShifted,tickSecShifted;
+ DWORD dwLog=16+0;
+ DWORD dwRet;
+ if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64)))
+ dwRet = (GetTickCount() - beginTime64.LowPart)*1;
+ else
+ {
+ MyDoMinus64(&ticks,endTime64,beginTime64);
+ QueryPerformanceFrequency(&ticksPerSecond);
+
+
+ {
+ ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog);
+ tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog);
+
+ }
+
+ dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted));
+ dwRet *=1;
+ }
+ return dwRet;
+}
+
+int ReadFileMemory(const char* filename,long* plFileSize,unsigned char** pFilePtr)
+{
+ FILE* stream;
+ unsigned char* ptr;
+ int retVal=1;
+ stream=fopen(filename, "rb");
+ if (stream==NULL)
+ return 0;
+
+ fseek(stream,0,SEEK_END);
+
+ *plFileSize=ftell(stream);
+ fseek(stream,0,SEEK_SET);
+ ptr=malloc((*plFileSize)+1);
+ if (ptr==NULL)
+ retVal=0;
+ else
+ {
+ if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))
+ retVal=0;
+ }
+ fclose(stream);
+ *pFilePtr=ptr;
+ return retVal;
+}
+
+int main(int argc, char *argv[])
+{
+ int BlockSizeCompress=0x8000;
+ int BlockSizeUncompress=0x8000;
+ int cprLevel=Z_DEFAULT_COMPRESSION ;
+ long lFileSize;
+ unsigned char* FilePtr;
+ long lBufferSizeCpr;
+ long lBufferSizeUncpr;
+ long lCompressedSize=0;
+ unsigned char* CprPtr;
+ unsigned char* UncprPtr;
+ long lSizeCpr,lSizeUncpr;
+ DWORD dwGetTick,dwMsecQP;
+ LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc;
+
+ if (argc<=1)
+ {
+ printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");
+ return 0;
+ }
+
+ if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)
+ {
+ printf("error reading %s\n",argv[1]);
+ return 1;
+ }
+ else printf("file %s read, %u bytes\n",argv[1],lFileSize);
+
+ if (argc>=3)
+ BlockSizeCompress=atol(argv[2]);
+
+ if (argc>=4)
+ BlockSizeUncompress=atol(argv[3]);
+
+ if (argc>=5)
+ cprLevel=(int)atol(argv[4]);
+
+ lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;
+ lBufferSizeUncpr = lBufferSizeCpr;
+
+ CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);
+
+ BeginCountPerfCounter(&li_qp,TRUE);
+ dwGetTick=GetTickCount();
+ BeginCountRdtsc(&li_rdtsc);
+ {
+ z_stream zcpr;
+ int ret=Z_OK;
+ long lOrigToDo = lFileSize;
+ long lOrigDone = 0;
+ int step=0;
+ memset(&zcpr,0,sizeof(z_stream));
+ deflateInit(&zcpr,cprLevel);
+
+ zcpr.next_in = FilePtr;
+ zcpr.next_out = CprPtr;
+
+
+ do
+ {
+ long all_read_before = zcpr.total_in;
+ zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);
+ zcpr.avail_out = BlockSizeCompress;
+ ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);
+ lOrigDone += (zcpr.total_in-all_read_before);
+ lOrigToDo -= (zcpr.total_in-all_read_before);
+ step++;
+ } while (ret==Z_OK);
+
+ lSizeCpr=zcpr.total_out;
+ deflateEnd(&zcpr);
+ dwGetTick=GetTickCount()-dwGetTick;
+ dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
+ dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
+ printf("total compress size = %u, in %u step\n",lSizeCpr,step);
+ printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
+ printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
+ printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
+ }
+
+ CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr);
+ UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);
+
+ BeginCountPerfCounter(&li_qp,TRUE);
+ dwGetTick=GetTickCount();
+ BeginCountRdtsc(&li_rdtsc);
+ {
+ z_stream zcpr;
+ int ret=Z_OK;
+ long lOrigToDo = lSizeCpr;
+ long lOrigDone = 0;
+ int step=0;
+ memset(&zcpr,0,sizeof(z_stream));
+ inflateInit(&zcpr);
+
+ zcpr.next_in = CprPtr;
+ zcpr.next_out = UncprPtr;
+
+
+ do
+ {
+ long all_read_before = zcpr.total_in;
+ zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);
+ zcpr.avail_out = BlockSizeUncompress;
+ ret=inflate(&zcpr,Z_SYNC_FLUSH);
+ lOrigDone += (zcpr.total_in-all_read_before);
+ lOrigToDo -= (zcpr.total_in-all_read_before);
+ step++;
+ } while (ret==Z_OK);
+
+ lSizeUncpr=zcpr.total_out;
+ inflateEnd(&zcpr);
+ dwGetTick=GetTickCount()-dwGetTick;
+ dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
+ dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
+ printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);
+ printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
+ printf("uncpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
+ printf("uncpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
+ }
+
+ if (lSizeUncpr==lFileSize)
+ {
+ if (memcmp(FilePtr,UncprPtr,lFileSize)==0)
+ printf("compare ok\n");
+
+ }
+
+ return 0;
+}
diff --git a/xs/src/png/zlib/contrib/testzlib/testzlib.txt b/xs/src/png/zlib/contrib/testzlib/testzlib.txt
new file mode 100644
index 000000000..e508bb22f
--- /dev/null
+++ b/xs/src/png/zlib/contrib/testzlib/testzlib.txt
@@ -0,0 +1,10 @@
+To build testzLib with Visual Studio 2005:
+
+copy to a directory file from :
+- root of zLib tree
+- contrib/testzlib
+- contrib/masmx86
+- contrib/masmx64
+- contrib/vstudio/vc7
+
+and open testzlib8.sln \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/untgz/Makefile b/xs/src/png/zlib/contrib/untgz/Makefile
new file mode 100644
index 000000000..b54266fba
--- /dev/null
+++ b/xs/src/png/zlib/contrib/untgz/Makefile
@@ -0,0 +1,14 @@
+CC=cc
+CFLAGS=-g
+
+untgz: untgz.o ../../libz.a
+ $(CC) $(CFLAGS) -o untgz untgz.o -L../.. -lz
+
+untgz.o: untgz.c ../../zlib.h
+ $(CC) $(CFLAGS) -c -I../.. untgz.c
+
+../../libz.a:
+ cd ../..; ./configure; make
+
+clean:
+ rm -f untgz untgz.o *~
diff --git a/xs/src/png/zlib/contrib/untgz/Makefile.msc b/xs/src/png/zlib/contrib/untgz/Makefile.msc
new file mode 100644
index 000000000..77b860221
--- /dev/null
+++ b/xs/src/png/zlib/contrib/untgz/Makefile.msc
@@ -0,0 +1,17 @@
+CC=cl
+CFLAGS=-MD
+
+untgz.exe: untgz.obj ..\..\zlib.lib
+ $(CC) $(CFLAGS) untgz.obj ..\..\zlib.lib
+
+untgz.obj: untgz.c ..\..\zlib.h
+ $(CC) $(CFLAGS) -c -I..\.. untgz.c
+
+..\..\zlib.lib:
+ cd ..\..
+ $(MAKE) -f win32\makefile.msc
+ cd contrib\untgz
+
+clean:
+ -del untgz.obj
+ -del untgz.exe
diff --git a/xs/src/png/zlib/contrib/untgz/untgz.c b/xs/src/png/zlib/contrib/untgz/untgz.c
new file mode 100644
index 000000000..2c391e598
--- /dev/null
+++ b/xs/src/png/zlib/contrib/untgz/untgz.c
@@ -0,0 +1,674 @@
+/*
+ * untgz.c -- Display contents and extract files from a gzip'd TAR file
+ *
+ * written by Pedro A. Aranda Gutierrez <paag@tid.es>
+ * adaptation to Unix by Jean-loup Gailly <jloup@gzip.org>
+ * various fixes by Cosmin Truta <cosmint@cs.ubbcluj.ro>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+
+#include "zlib.h"
+
+#ifdef unix
+# include <unistd.h>
+#else
+# include <direct.h>
+# include <io.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+# ifndef F_OK
+# define F_OK 0
+# endif
+# define mkdir(dirname,mode) _mkdir(dirname)
+# ifdef _MSC_VER
+# define access(path,mode) _access(path,mode)
+# define chmod(path,mode) _chmod(path,mode)
+# define strdup(str) _strdup(str)
+# endif
+#else
+# include <utime.h>
+#endif
+
+
+/* values used in typeflag field */
+
+#define REGTYPE '0' /* regular file */
+#define AREGTYPE '\0' /* regular file */
+#define LNKTYPE '1' /* link */
+#define SYMTYPE '2' /* reserved */
+#define CHRTYPE '3' /* character special */
+#define BLKTYPE '4' /* block special */
+#define DIRTYPE '5' /* directory */
+#define FIFOTYPE '6' /* FIFO special */
+#define CONTTYPE '7' /* reserved */
+
+/* GNU tar extensions */
+
+#define GNUTYPE_DUMPDIR 'D' /* file names from dumped directory */
+#define GNUTYPE_LONGLINK 'K' /* long link name */
+#define GNUTYPE_LONGNAME 'L' /* long file name */
+#define GNUTYPE_MULTIVOL 'M' /* continuation of file from another volume */
+#define GNUTYPE_NAMES 'N' /* file name that does not fit into main hdr */
+#define GNUTYPE_SPARSE 'S' /* sparse file */
+#define GNUTYPE_VOLHDR 'V' /* tape/volume header */
+
+
+/* tar header */
+
+#define BLOCKSIZE 512
+#define SHORTNAMESIZE 100
+
+struct tar_header
+{ /* byte offset */
+ char name[100]; /* 0 */
+ char mode[8]; /* 100 */
+ char uid[8]; /* 108 */
+ char gid[8]; /* 116 */
+ char size[12]; /* 124 */
+ char mtime[12]; /* 136 */
+ char chksum[8]; /* 148 */
+ char typeflag; /* 156 */
+ char linkname[100]; /* 157 */
+ char magic[6]; /* 257 */
+ char version[2]; /* 263 */
+ char uname[32]; /* 265 */
+ char gname[32]; /* 297 */
+ char devmajor[8]; /* 329 */
+ char devminor[8]; /* 337 */
+ char prefix[155]; /* 345 */
+ /* 500 */
+};
+
+union tar_buffer
+{
+ char buffer[BLOCKSIZE];
+ struct tar_header header;
+};
+
+struct attr_item
+{
+ struct attr_item *next;
+ char *fname;
+ int mode;
+ time_t time;
+};
+
+enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID };
+
+char *TGZfname OF((const char *));
+void TGZnotfound OF((const char *));
+
+int getoct OF((char *, int));
+char *strtime OF((time_t *));
+int setfiletime OF((char *, time_t));
+void push_attr OF((struct attr_item **, char *, int, time_t));
+void restore_attr OF((struct attr_item **));
+
+int ExprMatch OF((char *, char *));
+
+int makedir OF((char *));
+int matchname OF((int, int, char **, char *));
+
+void error OF((const char *));
+int tar OF((gzFile, int, int, int, char **));
+
+void help OF((int));
+int main OF((int, char **));
+
+char *prog;
+
+const char *TGZsuffix[] = { "\0", ".tar", ".tar.gz", ".taz", ".tgz", NULL };
+
+/* return the file name of the TGZ archive */
+/* or NULL if it does not exist */
+
+char *TGZfname (const char *arcname)
+{
+ static char buffer[1024];
+ int origlen,i;
+
+ strcpy(buffer,arcname);
+ origlen = strlen(buffer);
+
+ for (i=0; TGZsuffix[i]; i++)
+ {
+ strcpy(buffer+origlen,TGZsuffix[i]);
+ if (access(buffer,F_OK) == 0)
+ return buffer;
+ }
+ return NULL;
+}
+
+
+/* error message for the filename */
+
+void TGZnotfound (const char *arcname)
+{
+ int i;
+
+ fprintf(stderr,"%s: Couldn't find ",prog);
+ for (i=0;TGZsuffix[i];i++)
+ fprintf(stderr,(TGZsuffix[i+1]) ? "%s%s, " : "or %s%s\n",
+ arcname,
+ TGZsuffix[i]);
+ exit(1);
+}
+
+
+/* convert octal digits to int */
+/* on error return -1 */
+
+int getoct (char *p,int width)
+{
+ int result = 0;
+ char c;
+
+ while (width--)
+ {
+ c = *p++;
+ if (c == 0)
+ break;
+ if (c == ' ')
+ continue;
+ if (c < '0' || c > '7')
+ return -1;
+ result = result * 8 + (c - '0');
+ }
+ return result;
+}
+
+
+/* convert time_t to string */
+/* use the "YYYY/MM/DD hh:mm:ss" format */
+
+char *strtime (time_t *t)
+{
+ struct tm *local;
+ static char result[32];
+
+ local = localtime(t);
+ sprintf(result,"%4d/%02d/%02d %02d:%02d:%02d",
+ local->tm_year+1900, local->tm_mon+1, local->tm_mday,
+ local->tm_hour, local->tm_min, local->tm_sec);
+ return result;
+}
+
+
+/* set file time */
+
+int setfiletime (char *fname,time_t ftime)
+{
+#ifdef WIN32
+ static int isWinNT = -1;
+ SYSTEMTIME st;
+ FILETIME locft, modft;
+ struct tm *loctm;
+ HANDLE hFile;
+ int result;
+
+ loctm = localtime(&ftime);
+ if (loctm == NULL)
+ return -1;
+
+ st.wYear = (WORD)loctm->tm_year + 1900;
+ st.wMonth = (WORD)loctm->tm_mon + 1;
+ st.wDayOfWeek = (WORD)loctm->tm_wday;
+ st.wDay = (WORD)loctm->tm_mday;
+ st.wHour = (WORD)loctm->tm_hour;
+ st.wMinute = (WORD)loctm->tm_min;
+ st.wSecond = (WORD)loctm->tm_sec;
+ st.wMilliseconds = 0;
+ if (!SystemTimeToFileTime(&st, &locft) ||
+ !LocalFileTimeToFileTime(&locft, &modft))
+ return -1;
+
+ if (isWinNT < 0)
+ isWinNT = (GetVersion() < 0x80000000) ? 1 : 0;
+ hFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+ (isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0),
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return -1;
+ result = SetFileTime(hFile, NULL, NULL, &modft) ? 0 : -1;
+ CloseHandle(hFile);
+ return result;
+#else
+ struct utimbuf settime;
+
+ settime.actime = settime.modtime = ftime;
+ return utime(fname,&settime);
+#endif
+}
+
+
+/* push file attributes */
+
+void push_attr(struct attr_item **list,char *fname,int mode,time_t time)
+{
+ struct attr_item *item;
+
+ item = (struct attr_item *)malloc(sizeof(struct attr_item));
+ if (item == NULL)
+ error("Out of memory");
+ item->fname = strdup(fname);
+ item->mode = mode;
+ item->time = time;
+ item->next = *list;
+ *list = item;
+}
+
+
+/* restore file attributes */
+
+void restore_attr(struct attr_item **list)
+{
+ struct attr_item *item, *prev;
+
+ for (item = *list; item != NULL; )
+ {
+ setfiletime(item->fname,item->time);
+ chmod(item->fname,item->mode);
+ prev = item;
+ item = item->next;
+ free(prev);
+ }
+ *list = NULL;
+}
+
+
+/* match regular expression */
+
+#define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))
+
+int ExprMatch (char *string,char *expr)
+{
+ while (1)
+ {
+ if (ISSPECIAL(*expr))
+ {
+ if (*expr == '/')
+ {
+ if (*string != '\\' && *string != '/')
+ return 0;
+ string ++; expr++;
+ }
+ else if (*expr == '*')
+ {
+ if (*expr ++ == 0)
+ return 1;
+ while (*++string != *expr)
+ if (*string == 0)
+ return 0;
+ }
+ }
+ else
+ {
+ if (*string != *expr)
+ return 0;
+ if (*expr++ == 0)
+ return 1;
+ string++;
+ }
+ }
+}
+
+
+/* recursive mkdir */
+/* abort on ENOENT; ignore other errors like "directory already exists" */
+/* return 1 if OK */
+/* 0 on error */
+
+int makedir (char *newdir)
+{
+ char *buffer = strdup(newdir);
+ char *p;
+ int len = strlen(buffer);
+
+ if (len <= 0) {
+ free(buffer);
+ return 0;
+ }
+ if (buffer[len-1] == '/') {
+ buffer[len-1] = '\0';
+ }
+ if (mkdir(buffer, 0755) == 0)
+ {
+ free(buffer);
+ return 1;
+ }
+
+ p = buffer+1;
+ while (1)
+ {
+ char hold;
+
+ while(*p && *p != '\\' && *p != '/')
+ p++;
+ hold = *p;
+ *p = 0;
+ if ((mkdir(buffer, 0755) == -1) && (errno == ENOENT))
+ {
+ fprintf(stderr,"%s: Couldn't create directory %s\n",prog,buffer);
+ free(buffer);
+ return 0;
+ }
+ if (hold == 0)
+ break;
+ *p++ = hold;
+ }
+ free(buffer);
+ return 1;
+}
+
+
+int matchname (int arg,int argc,char **argv,char *fname)
+{
+ if (arg == argc) /* no arguments given (untgz tgzarchive) */
+ return 1;
+
+ while (arg < argc)
+ if (ExprMatch(fname,argv[arg++]))
+ return 1;
+
+ return 0; /* ignore this for the moment being */
+}
+
+
+/* tar file list or extract */
+
+int tar (gzFile in,int action,int arg,int argc,char **argv)
+{
+ union tar_buffer buffer;
+ int len;
+ int err;
+ int getheader = 1;
+ int remaining = 0;
+ FILE *outfile = NULL;
+ char fname[BLOCKSIZE];
+ int tarmode;
+ time_t tartime;
+ struct attr_item *attributes = NULL;
+
+ if (action == TGZ_LIST)
+ printf(" date time size file\n"
+ " ---------- -------- --------- -------------------------------------\n");
+ while (1)
+ {
+ len = gzread(in, &buffer, BLOCKSIZE);
+ if (len < 0)
+ error(gzerror(in, &err));
+ /*
+ * Always expect complete blocks to process
+ * the tar information.
+ */
+ if (len != BLOCKSIZE)
+ {
+ action = TGZ_INVALID; /* force error exit */
+ remaining = 0; /* force I/O cleanup */
+ }
+
+ /*
+ * If we have to get a tar header
+ */
+ if (getheader >= 1)
+ {
+ /*
+ * if we met the end of the tar
+ * or the end-of-tar block,
+ * we are done
+ */
+ if (len == 0 || buffer.header.name[0] == 0)
+ break;
+
+ tarmode = getoct(buffer.header.mode,8);
+ tartime = (time_t)getoct(buffer.header.mtime,12);
+ if (tarmode == -1 || tartime == (time_t)-1)
+ {
+ buffer.header.name[0] = 0;
+ action = TGZ_INVALID;
+ }
+
+ if (getheader == 1)
+ {
+ strncpy(fname,buffer.header.name,SHORTNAMESIZE);
+ if (fname[SHORTNAMESIZE-1] != 0)
+ fname[SHORTNAMESIZE] = 0;
+ }
+ else
+ {
+ /*
+ * The file name is longer than SHORTNAMESIZE
+ */
+ if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0)
+ error("bad long name");
+ getheader = 1;
+ }
+
+ /*
+ * Act according to the type flag
+ */
+ switch (buffer.header.typeflag)
+ {
+ case DIRTYPE:
+ if (action == TGZ_LIST)
+ printf(" %s <dir> %s\n",strtime(&tartime),fname);
+ if (action == TGZ_EXTRACT)
+ {
+ makedir(fname);
+ push_attr(&attributes,fname,tarmode,tartime);
+ }
+ break;
+ case REGTYPE:
+ case AREGTYPE:
+ remaining = getoct(buffer.header.size,12);
+ if (remaining == -1)
+ {
+ action = TGZ_INVALID;
+ break;
+ }
+ if (action == TGZ_LIST)
+ printf(" %s %9d %s\n",strtime(&tartime),remaining,fname);
+ else if (action == TGZ_EXTRACT)
+ {
+ if (matchname(arg,argc,argv,fname))
+ {
+ outfile = fopen(fname,"wb");
+ if (outfile == NULL) {
+ /* try creating directory */
+ char *p = strrchr(fname, '/');
+ if (p != NULL) {
+ *p = '\0';
+ makedir(fname);
+ *p = '/';
+ outfile = fopen(fname,"wb");
+ }
+ }
+ if (outfile != NULL)
+ printf("Extracting %s\n",fname);
+ else
+ fprintf(stderr, "%s: Couldn't create %s",prog,fname);
+ }
+ else
+ outfile = NULL;
+ }
+ getheader = 0;
+ break;
+ case GNUTYPE_LONGLINK:
+ case GNUTYPE_LONGNAME:
+ remaining = getoct(buffer.header.size,12);
+ if (remaining < 0 || remaining >= BLOCKSIZE)
+ {
+ action = TGZ_INVALID;
+ break;
+ }
+ len = gzread(in, fname, BLOCKSIZE);
+ if (len < 0)
+ error(gzerror(in, &err));
+ if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining)
+ {
+ action = TGZ_INVALID;
+ break;
+ }
+ getheader = 2;
+ break;
+ default:
+ if (action == TGZ_LIST)
+ printf(" %s <---> %s\n",strtime(&tartime),fname);
+ break;
+ }
+ }
+ else
+ {
+ unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;
+
+ if (outfile != NULL)
+ {
+ if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
+ {
+ fprintf(stderr,
+ "%s: Error writing %s -- skipping\n",prog,fname);
+ fclose(outfile);
+ outfile = NULL;
+ remove(fname);
+ }
+ }
+ remaining -= bytes;
+ }
+
+ if (remaining == 0)
+ {
+ getheader = 1;
+ if (outfile != NULL)
+ {
+ fclose(outfile);
+ outfile = NULL;
+ if (action != TGZ_INVALID)
+ push_attr(&attributes,fname,tarmode,tartime);
+ }
+ }
+
+ /*
+ * Abandon if errors are found
+ */
+ if (action == TGZ_INVALID)
+ {
+ error("broken archive");
+ break;
+ }
+ }
+
+ /*
+ * Restore file modes and time stamps
+ */
+ restore_attr(&attributes);
+
+ if (gzclose(in) != Z_OK)
+ error("failed gzclose");
+
+ return 0;
+}
+
+
+/* ============================================================ */
+
+void help(int exitval)
+{
+ printf("untgz version 0.2.1\n"
+ " using zlib version %s\n\n",
+ zlibVersion());
+ printf("Usage: untgz file.tgz extract all files\n"
+ " untgz file.tgz fname ... extract selected files\n"
+ " untgz -l file.tgz list archive contents\n"
+ " untgz -h display this help\n");
+ exit(exitval);
+}
+
+void error(const char *msg)
+{
+ fprintf(stderr, "%s: %s\n", prog, msg);
+ exit(1);
+}
+
+
+/* ============================================================ */
+
+#if defined(WIN32) && defined(__GNUC__)
+int _CRT_glob = 0; /* disable argument globbing in MinGW */
+#endif
+
+int main(int argc,char **argv)
+{
+ int action = TGZ_EXTRACT;
+ int arg = 1;
+ char *TGZfile;
+ gzFile *f;
+
+ prog = strrchr(argv[0],'\\');
+ if (prog == NULL)
+ {
+ prog = strrchr(argv[0],'/');
+ if (prog == NULL)
+ {
+ prog = strrchr(argv[0],':');
+ if (prog == NULL)
+ prog = argv[0];
+ else
+ prog++;
+ }
+ else
+ prog++;
+ }
+ else
+ prog++;
+
+ if (argc == 1)
+ help(0);
+
+ if (strcmp(argv[arg],"-l") == 0)
+ {
+ action = TGZ_LIST;
+ if (argc == ++arg)
+ help(0);
+ }
+ else if (strcmp(argv[arg],"-h") == 0)
+ {
+ help(0);
+ }
+
+ if ((TGZfile = TGZfname(argv[arg])) == NULL)
+ TGZnotfound(argv[arg]);
+
+ ++arg;
+ if ((action == TGZ_LIST) && (arg != argc))
+ help(1);
+
+/*
+ * Process the TGZ file
+ */
+ switch(action)
+ {
+ case TGZ_LIST:
+ case TGZ_EXTRACT:
+ f = gzopen(TGZfile,"rb");
+ if (f == NULL)
+ {
+ fprintf(stderr,"%s: Couldn't gzopen %s\n",prog,TGZfile);
+ return 1;
+ }
+ exit(tar(f, action, arg, argc, argv));
+ break;
+
+ default:
+ error("Unknown option");
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/xs/src/png/zlib/contrib/vstudio/readme.txt b/xs/src/png/zlib/contrib/vstudio/readme.txt
new file mode 100644
index 000000000..48cccc0d2
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/readme.txt
@@ -0,0 +1,78 @@
+Building instructions for the DLL versions of Zlib 1.2.11
+========================================================
+
+This directory contains projects that build zlib and minizip using
+Microsoft Visual C++ 9.0/10.0.
+
+You don't need to build these projects yourself. You can download the
+binaries from:
+ http://www.winimage.com/zLibDll
+
+More information can be found at this site.
+
+
+
+
+
+Build instructions for Visual Studio 2008 (32 bits or 64 bits)
+--------------------------------------------------------------
+- Decompress current zlib, including all contrib/* files
+- Compile assembly code (with Visual Studio Command Prompt) by running:
+ bld_ml64.bat (in contrib\masmx64)
+ bld_ml32.bat (in contrib\masmx86)
+- Open contrib\vstudio\vc9\zlibvc.sln with Microsoft Visual C++ 2008
+- Or run: vcbuild /rebuild contrib\vstudio\vc9\zlibvc.sln "Release|Win32"
+
+Build instructions for Visual Studio 2010 (32 bits or 64 bits)
+--------------------------------------------------------------
+- Decompress current zlib, including all contrib/* files
+- Open contrib\vstudio\vc10\zlibvc.sln with Microsoft Visual C++ 2010
+
+Build instructions for Visual Studio 2012 (32 bits or 64 bits)
+--------------------------------------------------------------
+- Decompress current zlib, including all contrib/* files
+- Open contrib\vstudio\vc11\zlibvc.sln with Microsoft Visual C++ 2012
+
+Build instructions for Visual Studio 2013 (32 bits or 64 bits)
+--------------------------------------------------------------
+- Decompress current zlib, including all contrib/* files
+- Open contrib\vstudio\vc12\zlibvc.sln with Microsoft Visual C++ 2013
+
+Build instructions for Visual Studio 2015 (32 bits or 64 bits)
+--------------------------------------------------------------
+- Decompress current zlib, including all contrib/* files
+- Open contrib\vstudio\vc14\zlibvc.sln with Microsoft Visual C++ 2015
+
+
+Important
+---------
+- To use zlibwapi.dll in your application, you must define the
+ macro ZLIB_WINAPI when compiling your application's source files.
+
+
+Additional notes
+----------------
+- This DLL, named zlibwapi.dll, is compatible to the old zlib.dll built
+ by Gilles Vollant from the zlib 1.1.x sources, and distributed at
+ http://www.winimage.com/zLibDll
+ It uses the WINAPI calling convention for the exported functions, and
+ includes the minizip functionality. If your application needs that
+ particular build of zlib.dll, you can rename zlibwapi.dll to zlib.dll.
+
+- The new DLL was renamed because there exist several incompatible
+ versions of zlib.dll on the Internet.
+
+- There is also an official DLL build of zlib, named zlib1.dll. This one
+ is exporting the functions using the CDECL convention. See the file
+ win32\DLL_FAQ.txt found in this zlib distribution.
+
+- There used to be a ZLIB_DLL macro in zlib 1.1.x, but now this symbol
+ has a slightly different effect. To avoid compatibility problems, do
+ not define it here.
+
+
+Gilles Vollant
+info@winimage.com
+
+Visual Studio 2013 and 2015 Projects from Sean Hunt
+seandhunt_7@yahoo.com
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/miniunz.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc10/miniunz.vcxproj
new file mode 100644
index 000000000..1b3624215
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/miniunz.vcxproj
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694382A}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\miniunz.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters b/xs/src/png/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters
new file mode 100644
index 000000000..0bd12210c
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{048af943-022b-4db6-beeb-a54c34774ee2}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{c1d600d2-888f-4aea-b73e-8b0dd9befa0c}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{0844199a-966b-4f19-81db-1e0125e141b9}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\miniunz.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/minizip.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc10/minizip.vcxproj
new file mode 100644
index 000000000..ccd3651df
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/minizip.vcxproj
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\minizip.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters b/xs/src/png/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters
new file mode 100644
index 000000000..7076d76ff
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{c0419b40-bf50-40da-b153-ff74215b79de}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{bb87b070-735b-478e-92ce-7383abb2f36c}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{f46ab6a6-548f-43cb-ae96-681abb5bd5db}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\minizip.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/testzlib.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc10/testzlib.vcxproj
new file mode 100644
index 000000000..476b8ea45
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/testzlib.vcxproj
@@ -0,0 +1,420 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+ <RootNamespace>testzlib</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\testzlib\testzlib.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters b/xs/src/png/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters
new file mode 100644
index 000000000..327649103
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{c1f6a2e3-5da5-4955-8653-310d3efe05a9}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{c2aaffdc-2c95-4d6f-8466-4bec5890af2c}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{c274fe07-05f2-461c-964b-f6341e4e7eb5}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\compress.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\crc32.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\deflate.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\infback.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inflate.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inftrees.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\testzlib\testzlib.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\trees.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\uncompr.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\zutil.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj
new file mode 100644
index 000000000..8e38876fa
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694366A}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\testzlib\testzlib.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters b/xs/src/png/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters
new file mode 100644
index 000000000..ab87f09f4
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{fa61a89f-93fc-4c89-b29e-36224b7592f4}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{d4b85da0-2ba2-4934-b57f-e2584e3848ee}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{e573e075-00bd-4a7d-bd67-a8cc9bfc5aca}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\testzlib\testzlib.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/zlib.rc b/xs/src/png/zlib/contrib/vstudio/vc10/zlib.rc
new file mode 100644
index 000000000..c4e4b016e
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/zlib.rc
@@ -0,0 +1,32 @@
+#include <windows.h>
+
+#define IDR_VERSION1 1
+IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
+ FILEVERSION 1, 2, 11, 0
+ PRODUCTVERSION 1, 2, 11, 0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS_DOS_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0 // not used
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ //language ID = U.S. English, char set = Windows, Multilingual
+
+ BEGIN
+ VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
+ VALUE "FileVersion", "1.2.11\0"
+ VALUE "InternalName", "zlib\0"
+ VALUE "OriginalFilename", "zlibwapi.dll\0"
+ VALUE "ProductName", "ZLib.DLL\0"
+ VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
+ VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 1252
+ END
+END
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/zlibstat.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc10/zlibstat.vcxproj
new file mode 100644
index 000000000..45389a352
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/zlibstat.vcxproj
@@ -0,0 +1,473 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\gzclose.c" />
+ <ClCompile Include="..\..\..\gzlib.c" />
+ <ClCompile Include="..\..\..\gzread.c" />
+ <ClCompile Include="..\..\..\gzwrite.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\minizip\ioapi.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\minizip\unzip.c" />
+ <ClCompile Include="..\..\minizip\zip.c" />
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters b/xs/src/png/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters
new file mode 100644
index 000000000..0c8b2501c
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{174213f6-7f66-4ae8-a3a8-a1e0a1e6ffdd}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\compress.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\crc32.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\deflate.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\gzclose.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\gzlib.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\gzread.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\gzwrite.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\infback.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inflate.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inftrees.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\ioapi.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\trees.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\uncompr.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\unzip.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\zip.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\zutil.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc">
+ <Filter>Source Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.def b/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.def
new file mode 100644
index 000000000..f876c3bca
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.def
@@ -0,0 +1,153 @@
+LIBRARY
+; zlib data compression and ZIP file I/O library
+
+VERSION 1.2
+
+EXPORTS
+ adler32 @1
+ compress @2
+ crc32 @3
+ deflate @4
+ deflateCopy @5
+ deflateEnd @6
+ deflateInit2_ @7
+ deflateInit_ @8
+ deflateParams @9
+ deflateReset @10
+ deflateSetDictionary @11
+ gzclose @12
+ gzdopen @13
+ gzerror @14
+ gzflush @15
+ gzopen @16
+ gzread @17
+ gzwrite @18
+ inflate @19
+ inflateEnd @20
+ inflateInit2_ @21
+ inflateInit_ @22
+ inflateReset @23
+ inflateSetDictionary @24
+ inflateSync @25
+ uncompress @26
+ zlibVersion @27
+ gzprintf @28
+ gzputc @29
+ gzgetc @30
+ gzseek @31
+ gzrewind @32
+ gztell @33
+ gzeof @34
+ gzsetparams @35
+ zError @36
+ inflateSyncPoint @37
+ get_crc_table @38
+ compress2 @39
+ gzputs @40
+ gzgets @41
+ inflateCopy @42
+ inflateBackInit_ @43
+ inflateBack @44
+ inflateBackEnd @45
+ compressBound @46
+ deflateBound @47
+ gzclearerr @48
+ gzungetc @49
+ zlibCompileFlags @50
+ deflatePrime @51
+ deflatePending @52
+
+ unzOpen @61
+ unzClose @62
+ unzGetGlobalInfo @63
+ unzGetCurrentFileInfo @64
+ unzGoToFirstFile @65
+ unzGoToNextFile @66
+ unzOpenCurrentFile @67
+ unzReadCurrentFile @68
+ unzOpenCurrentFile3 @69
+ unztell @70
+ unzeof @71
+ unzCloseCurrentFile @72
+ unzGetGlobalComment @73
+ unzStringFileNameCompare @74
+ unzLocateFile @75
+ unzGetLocalExtrafield @76
+ unzOpen2 @77
+ unzOpenCurrentFile2 @78
+ unzOpenCurrentFilePassword @79
+
+ zipOpen @80
+ zipOpenNewFileInZip @81
+ zipWriteInFileInZip @82
+ zipCloseFileInZip @83
+ zipClose @84
+ zipOpenNewFileInZip2 @86
+ zipCloseFileInZipRaw @87
+ zipOpen2 @88
+ zipOpenNewFileInZip3 @89
+
+ unzGetFilePos @100
+ unzGoToFilePos @101
+
+ fill_win32_filefunc @110
+
+; zlibwapi v1.2.4 added:
+ fill_win32_filefunc64 @111
+ fill_win32_filefunc64A @112
+ fill_win32_filefunc64W @113
+
+ unzOpen64 @120
+ unzOpen2_64 @121
+ unzGetGlobalInfo64 @122
+ unzGetCurrentFileInfo64 @124
+ unzGetCurrentFileZStreamPos64 @125
+ unztell64 @126
+ unzGetFilePos64 @127
+ unzGoToFilePos64 @128
+
+ zipOpen64 @130
+ zipOpen2_64 @131
+ zipOpenNewFileInZip64 @132
+ zipOpenNewFileInZip2_64 @133
+ zipOpenNewFileInZip3_64 @134
+ zipOpenNewFileInZip4_64 @135
+ zipCloseFileInZipRaw64 @136
+
+; zlib1 v1.2.4 added:
+ adler32_combine @140
+ crc32_combine @142
+ deflateSetHeader @144
+ deflateTune @145
+ gzbuffer @146
+ gzclose_r @147
+ gzclose_w @148
+ gzdirect @149
+ gzoffset @150
+ inflateGetHeader @156
+ inflateMark @157
+ inflatePrime @158
+ inflateReset2 @159
+ inflateUndermine @160
+
+; zlib1 v1.2.6 added:
+ gzgetc_ @161
+ inflateResetKeep @163
+ deflateResetKeep @164
+
+; zlib1 v1.2.7 added:
+ gzopen_w @165
+
+; zlib1 v1.2.8 added:
+ inflateGetDictionary @166
+ gzvprintf @167
+
+; zlib1 v1.2.9 added:
+ inflateCodesUsed @168
+ inflateValidate @169
+ uncompress2 @170
+ gzfread @171
+ gzfwrite @172
+ deflateGetDictionary @173
+ adler32_z @174
+ crc32_z @175
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.sln b/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.sln
new file mode 100644
index 000000000..649f40c7e
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.sln
@@ -0,0 +1,135 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Itanium = Debug|Itanium
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Itanium = Release|Itanium
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium
+ ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32
+ ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.vcxproj
new file mode 100644
index 000000000..7d7c49a6d
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.vcxproj
@@ -0,0 +1,657 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">zlibwapid</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">zlibwapid</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">zlibwapi</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <GenerateMapFile>true</GenerateMapFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <GenerateMapFile>true</GenerateMapFile>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\gzclose.c" />
+ <ClCompile Include="..\..\..\gzlib.c" />
+ <ClCompile Include="..\..\..\gzread.c" />
+ <ClCompile Include="..\..\..\gzwrite.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\minizip\ioapi.c" />
+ <ClCompile Include="..\..\minizip\iowin32.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\minizip\unzip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\zip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\deflate.h" />
+ <ClInclude Include="..\..\..\infblock.h" />
+ <ClInclude Include="..\..\..\infcodes.h" />
+ <ClInclude Include="..\..\..\inffast.h" />
+ <ClInclude Include="..\..\..\inftrees.h" />
+ <ClInclude Include="..\..\..\infutil.h" />
+ <ClInclude Include="..\..\..\zconf.h" />
+ <ClInclude Include="..\..\..\zlib.h" />
+ <ClInclude Include="..\..\..\zutil.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters b/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters
new file mode 100644
index 000000000..22786824f
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{07934a85-8b61-443d-a0ee-b2eedb74f3cd}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{1d99675b-433d-4a21-9e50-ed4ab8b19762}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;fi;fd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{431c0958-fa71-44d0-9084-2d19d100c0cc}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\compress.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\crc32.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\deflate.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\gzclose.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\gzlib.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\gzread.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\gzwrite.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\infback.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inflate.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inftrees.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\ioapi.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\iowin32.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\trees.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\uncompr.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\unzip.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\zip.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\zutil.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc">
+ <Filter>Source Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\deflate.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\infblock.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\infcodes.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\inffast.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\inftrees.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\infutil.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\zconf.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\zlib.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\..\zutil.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc11/miniunz.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc11/miniunz.vcxproj
new file mode 100644
index 000000000..99be63d69
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc11/miniunz.vcxproj
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694382A}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\miniunz.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc11/minizip.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc11/minizip.vcxproj
new file mode 100644
index 000000000..d6e98f4d5
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc11/minizip.vcxproj
@@ -0,0 +1,311 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\minizip.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc11/testzlib.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc11/testzlib.vcxproj
new file mode 100644
index 000000000..0115dd17b
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc11/testzlib.vcxproj
@@ -0,0 +1,426 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+ <RootNamespace>testzlib</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\testzlib\testzlib.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj
new file mode 100644
index 000000000..9d36336eb
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694366A}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\testzlib\testzlib.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc11/zlib.rc b/xs/src/png/zlib/contrib/vstudio/vc11/zlib.rc
new file mode 100644
index 000000000..c4e4b016e
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc11/zlib.rc
@@ -0,0 +1,32 @@
+#include <windows.h>
+
+#define IDR_VERSION1 1
+IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
+ FILEVERSION 1, 2, 11, 0
+ PRODUCTVERSION 1, 2, 11, 0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS_DOS_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0 // not used
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ //language ID = U.S. English, char set = Windows, Multilingual
+
+ BEGIN
+ VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
+ VALUE "FileVersion", "1.2.11\0"
+ VALUE "InternalName", "zlib\0"
+ VALUE "OriginalFilename", "zlibwapi.dll\0"
+ VALUE "ProductName", "ZLib.DLL\0"
+ VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
+ VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 1252
+ END
+END
diff --git a/xs/src/png/zlib/contrib/vstudio/vc11/zlibstat.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc11/zlibstat.vcxproj
new file mode 100644
index 000000000..64b4d869d
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc11/zlibstat.vcxproj
@@ -0,0 +1,464 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\gzclose.c" />
+ <ClCompile Include="..\..\..\gzlib.c" />
+ <ClCompile Include="..\..\..\gzread.c" />
+ <ClCompile Include="..\..\..\gzwrite.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\minizip\ioapi.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\minizip\unzip.c" />
+ <ClCompile Include="..\..\minizip\zip.c" />
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.def b/xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.def
new file mode 100644
index 000000000..f876c3bca
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.def
@@ -0,0 +1,153 @@
+LIBRARY
+; zlib data compression and ZIP file I/O library
+
+VERSION 1.2
+
+EXPORTS
+ adler32 @1
+ compress @2
+ crc32 @3
+ deflate @4
+ deflateCopy @5
+ deflateEnd @6
+ deflateInit2_ @7
+ deflateInit_ @8
+ deflateParams @9
+ deflateReset @10
+ deflateSetDictionary @11
+ gzclose @12
+ gzdopen @13
+ gzerror @14
+ gzflush @15
+ gzopen @16
+ gzread @17
+ gzwrite @18
+ inflate @19
+ inflateEnd @20
+ inflateInit2_ @21
+ inflateInit_ @22
+ inflateReset @23
+ inflateSetDictionary @24
+ inflateSync @25
+ uncompress @26
+ zlibVersion @27
+ gzprintf @28
+ gzputc @29
+ gzgetc @30
+ gzseek @31
+ gzrewind @32
+ gztell @33
+ gzeof @34
+ gzsetparams @35
+ zError @36
+ inflateSyncPoint @37
+ get_crc_table @38
+ compress2 @39
+ gzputs @40
+ gzgets @41
+ inflateCopy @42
+ inflateBackInit_ @43
+ inflateBack @44
+ inflateBackEnd @45
+ compressBound @46
+ deflateBound @47
+ gzclearerr @48
+ gzungetc @49
+ zlibCompileFlags @50
+ deflatePrime @51
+ deflatePending @52
+
+ unzOpen @61
+ unzClose @62
+ unzGetGlobalInfo @63
+ unzGetCurrentFileInfo @64
+ unzGoToFirstFile @65
+ unzGoToNextFile @66
+ unzOpenCurrentFile @67
+ unzReadCurrentFile @68
+ unzOpenCurrentFile3 @69
+ unztell @70
+ unzeof @71
+ unzCloseCurrentFile @72
+ unzGetGlobalComment @73
+ unzStringFileNameCompare @74
+ unzLocateFile @75
+ unzGetLocalExtrafield @76
+ unzOpen2 @77
+ unzOpenCurrentFile2 @78
+ unzOpenCurrentFilePassword @79
+
+ zipOpen @80
+ zipOpenNewFileInZip @81
+ zipWriteInFileInZip @82
+ zipCloseFileInZip @83
+ zipClose @84
+ zipOpenNewFileInZip2 @86
+ zipCloseFileInZipRaw @87
+ zipOpen2 @88
+ zipOpenNewFileInZip3 @89
+
+ unzGetFilePos @100
+ unzGoToFilePos @101
+
+ fill_win32_filefunc @110
+
+; zlibwapi v1.2.4 added:
+ fill_win32_filefunc64 @111
+ fill_win32_filefunc64A @112
+ fill_win32_filefunc64W @113
+
+ unzOpen64 @120
+ unzOpen2_64 @121
+ unzGetGlobalInfo64 @122
+ unzGetCurrentFileInfo64 @124
+ unzGetCurrentFileZStreamPos64 @125
+ unztell64 @126
+ unzGetFilePos64 @127
+ unzGoToFilePos64 @128
+
+ zipOpen64 @130
+ zipOpen2_64 @131
+ zipOpenNewFileInZip64 @132
+ zipOpenNewFileInZip2_64 @133
+ zipOpenNewFileInZip3_64 @134
+ zipOpenNewFileInZip4_64 @135
+ zipCloseFileInZipRaw64 @136
+
+; zlib1 v1.2.4 added:
+ adler32_combine @140
+ crc32_combine @142
+ deflateSetHeader @144
+ deflateTune @145
+ gzbuffer @146
+ gzclose_r @147
+ gzclose_w @148
+ gzdirect @149
+ gzoffset @150
+ inflateGetHeader @156
+ inflateMark @157
+ inflatePrime @158
+ inflateReset2 @159
+ inflateUndermine @160
+
+; zlib1 v1.2.6 added:
+ gzgetc_ @161
+ inflateResetKeep @163
+ deflateResetKeep @164
+
+; zlib1 v1.2.7 added:
+ gzopen_w @165
+
+; zlib1 v1.2.8 added:
+ inflateGetDictionary @166
+ gzvprintf @167
+
+; zlib1 v1.2.9 added:
+ inflateCodesUsed @168
+ inflateValidate @169
+ uncompress2 @170
+ gzfread @171
+ gzfwrite @172
+ deflateGetDictionary @173
+ adler32_z @174
+ crc32_z @175
diff --git a/xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.sln b/xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.sln
new file mode 100644
index 000000000..b7e381266
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.sln
@@ -0,0 +1,117 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Itanium = Debug|Itanium
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Itanium = Release|Itanium
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium
+ ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32
+ ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.vcxproj
new file mode 100644
index 000000000..c4cffccf1
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc11/zlibvc.vcxproj
@@ -0,0 +1,688 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">zlibwapi</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\contrib\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\gzclose.c" />
+ <ClCompile Include="..\..\..\gzlib.c" />
+ <ClCompile Include="..\..\..\gzread.c" />
+ <ClCompile Include="..\..\..\gzwrite.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\minizip\ioapi.c" />
+ <ClCompile Include="..\..\minizip\iowin32.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\minizip\unzip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\zip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\deflate.h" />
+ <ClInclude Include="..\..\..\infblock.h" />
+ <ClInclude Include="..\..\..\infcodes.h" />
+ <ClInclude Include="..\..\..\inffast.h" />
+ <ClInclude Include="..\..\..\inftrees.h" />
+ <ClInclude Include="..\..\..\infutil.h" />
+ <ClInclude Include="..\..\..\zconf.h" />
+ <ClInclude Include="..\..\..\zlib.h" />
+ <ClInclude Include="..\..\..\zutil.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc12/miniunz.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc12/miniunz.vcxproj
new file mode 100644
index 000000000..d88ac7fc7
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc12/miniunz.vcxproj
@@ -0,0 +1,316 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694382A}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\miniunz.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc12/minizip.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc12/minizip.vcxproj
new file mode 100644
index 000000000..f1f239c9e
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc12/minizip.vcxproj
@@ -0,0 +1,313 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\minizip.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc12/testzlib.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc12/testzlib.vcxproj
new file mode 100644
index 000000000..64b2cbe34
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc12/testzlib.vcxproj
@@ -0,0 +1,430 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+ <RootNamespace>testzlib</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\testzlib\testzlib.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc12/testzlibdll.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc12/testzlibdll.vcxproj
new file mode 100644
index 000000000..c66573a8b
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc12/testzlibdll.vcxproj
@@ -0,0 +1,316 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694366A}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\testzlib\testzlib.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc12/zlib.rc b/xs/src/png/zlib/contrib/vstudio/vc12/zlib.rc
new file mode 100644
index 000000000..c4e4b016e
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc12/zlib.rc
@@ -0,0 +1,32 @@
+#include <windows.h>
+
+#define IDR_VERSION1 1
+IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
+ FILEVERSION 1, 2, 11, 0
+ PRODUCTVERSION 1, 2, 11, 0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS_DOS_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0 // not used
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ //language ID = U.S. English, char set = Windows, Multilingual
+
+ BEGIN
+ VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
+ VALUE "FileVersion", "1.2.11\0"
+ VALUE "InternalName", "zlib\0"
+ VALUE "OriginalFilename", "zlibwapi.dll\0"
+ VALUE "ProductName", "ZLib.DLL\0"
+ VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
+ VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 1252
+ END
+END
diff --git a/xs/src/png/zlib/contrib/vstudio/vc12/zlibstat.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc12/zlibstat.vcxproj
new file mode 100644
index 000000000..3fdee7c50
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc12/zlibstat.vcxproj
@@ -0,0 +1,467 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\gzclose.c" />
+ <ClCompile Include="..\..\..\gzlib.c" />
+ <ClCompile Include="..\..\..\gzread.c" />
+ <ClCompile Include="..\..\..\gzwrite.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\minizip\ioapi.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\minizip\unzip.c" />
+ <ClCompile Include="..\..\minizip\zip.c" />
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.def b/xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.def
new file mode 100644
index 000000000..f876c3bca
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.def
@@ -0,0 +1,153 @@
+LIBRARY
+; zlib data compression and ZIP file I/O library
+
+VERSION 1.2
+
+EXPORTS
+ adler32 @1
+ compress @2
+ crc32 @3
+ deflate @4
+ deflateCopy @5
+ deflateEnd @6
+ deflateInit2_ @7
+ deflateInit_ @8
+ deflateParams @9
+ deflateReset @10
+ deflateSetDictionary @11
+ gzclose @12
+ gzdopen @13
+ gzerror @14
+ gzflush @15
+ gzopen @16
+ gzread @17
+ gzwrite @18
+ inflate @19
+ inflateEnd @20
+ inflateInit2_ @21
+ inflateInit_ @22
+ inflateReset @23
+ inflateSetDictionary @24
+ inflateSync @25
+ uncompress @26
+ zlibVersion @27
+ gzprintf @28
+ gzputc @29
+ gzgetc @30
+ gzseek @31
+ gzrewind @32
+ gztell @33
+ gzeof @34
+ gzsetparams @35
+ zError @36
+ inflateSyncPoint @37
+ get_crc_table @38
+ compress2 @39
+ gzputs @40
+ gzgets @41
+ inflateCopy @42
+ inflateBackInit_ @43
+ inflateBack @44
+ inflateBackEnd @45
+ compressBound @46
+ deflateBound @47
+ gzclearerr @48
+ gzungetc @49
+ zlibCompileFlags @50
+ deflatePrime @51
+ deflatePending @52
+
+ unzOpen @61
+ unzClose @62
+ unzGetGlobalInfo @63
+ unzGetCurrentFileInfo @64
+ unzGoToFirstFile @65
+ unzGoToNextFile @66
+ unzOpenCurrentFile @67
+ unzReadCurrentFile @68
+ unzOpenCurrentFile3 @69
+ unztell @70
+ unzeof @71
+ unzCloseCurrentFile @72
+ unzGetGlobalComment @73
+ unzStringFileNameCompare @74
+ unzLocateFile @75
+ unzGetLocalExtrafield @76
+ unzOpen2 @77
+ unzOpenCurrentFile2 @78
+ unzOpenCurrentFilePassword @79
+
+ zipOpen @80
+ zipOpenNewFileInZip @81
+ zipWriteInFileInZip @82
+ zipCloseFileInZip @83
+ zipClose @84
+ zipOpenNewFileInZip2 @86
+ zipCloseFileInZipRaw @87
+ zipOpen2 @88
+ zipOpenNewFileInZip3 @89
+
+ unzGetFilePos @100
+ unzGoToFilePos @101
+
+ fill_win32_filefunc @110
+
+; zlibwapi v1.2.4 added:
+ fill_win32_filefunc64 @111
+ fill_win32_filefunc64A @112
+ fill_win32_filefunc64W @113
+
+ unzOpen64 @120
+ unzOpen2_64 @121
+ unzGetGlobalInfo64 @122
+ unzGetCurrentFileInfo64 @124
+ unzGetCurrentFileZStreamPos64 @125
+ unztell64 @126
+ unzGetFilePos64 @127
+ unzGoToFilePos64 @128
+
+ zipOpen64 @130
+ zipOpen2_64 @131
+ zipOpenNewFileInZip64 @132
+ zipOpenNewFileInZip2_64 @133
+ zipOpenNewFileInZip3_64 @134
+ zipOpenNewFileInZip4_64 @135
+ zipCloseFileInZipRaw64 @136
+
+; zlib1 v1.2.4 added:
+ adler32_combine @140
+ crc32_combine @142
+ deflateSetHeader @144
+ deflateTune @145
+ gzbuffer @146
+ gzclose_r @147
+ gzclose_w @148
+ gzdirect @149
+ gzoffset @150
+ inflateGetHeader @156
+ inflateMark @157
+ inflatePrime @158
+ inflateReset2 @159
+ inflateUndermine @160
+
+; zlib1 v1.2.6 added:
+ gzgetc_ @161
+ inflateResetKeep @163
+ deflateResetKeep @164
+
+; zlib1 v1.2.7 added:
+ gzopen_w @165
+
+; zlib1 v1.2.8 added:
+ inflateGetDictionary @166
+ gzvprintf @167
+
+; zlib1 v1.2.9 added:
+ inflateCodesUsed @168
+ inflateValidate @169
+ uncompress2 @170
+ gzfread @171
+ gzfwrite @172
+ deflateGetDictionary @173
+ adler32_z @174
+ crc32_z @175
diff --git a/xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.sln b/xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.sln
new file mode 100644
index 000000000..dcda22984
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.sln
@@ -0,0 +1,119 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Itanium = Debug|Itanium
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Itanium = Release|Itanium
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium
+ ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32
+ ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.vcxproj
new file mode 100644
index 000000000..ab2b6c360
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc12/zlibvc.vcxproj
@@ -0,0 +1,692 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v120</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">zlibwapi</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\contrib\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\gzclose.c" />
+ <ClCompile Include="..\..\..\gzlib.c" />
+ <ClCompile Include="..\..\..\gzread.c" />
+ <ClCompile Include="..\..\..\gzwrite.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\minizip\ioapi.c" />
+ <ClCompile Include="..\..\minizip\iowin32.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\minizip\unzip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\zip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\deflate.h" />
+ <ClInclude Include="..\..\..\infblock.h" />
+ <ClInclude Include="..\..\..\infcodes.h" />
+ <ClInclude Include="..\..\..\inffast.h" />
+ <ClInclude Include="..\..\..\inftrees.h" />
+ <ClInclude Include="..\..\..\infutil.h" />
+ <ClInclude Include="..\..\..\zconf.h" />
+ <ClInclude Include="..\..\..\zlib.h" />
+ <ClInclude Include="..\..\..\zutil.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc14/miniunz.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc14/miniunz.vcxproj
new file mode 100644
index 000000000..9b5c07587
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc14/miniunz.vcxproj
@@ -0,0 +1,316 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694382A}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\miniunz.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc14/minizip.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc14/minizip.vcxproj
new file mode 100644
index 000000000..968a410a1
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc14/minizip.vcxproj
@@ -0,0 +1,313 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)minizip.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\minizip\minizip.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc14/testzlib.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc14/testzlib.vcxproj
new file mode 100644
index 000000000..2c371252a
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc14/testzlib.vcxproj
@@ -0,0 +1,430 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+ <RootNamespace>testzlib</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\testzlib\testzlib.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc14/testzlibdll.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc14/testzlibdll.vcxproj
new file mode 100644
index 000000000..d87474dec
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc14/testzlibdll.vcxproj
@@ -0,0 +1,316 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694366A}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+ <SubSystem>Console</SubSystem>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <OmitFramePointers>true</OmitFramePointers>
+ <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\testzlib\testzlib.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="zlibvc.vcxproj">
+ <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc14/zlib.rc b/xs/src/png/zlib/contrib/vstudio/vc14/zlib.rc
new file mode 100644
index 000000000..c4e4b016e
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc14/zlib.rc
@@ -0,0 +1,32 @@
+#include <windows.h>
+
+#define IDR_VERSION1 1
+IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
+ FILEVERSION 1, 2, 11, 0
+ PRODUCTVERSION 1, 2, 11, 0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS_DOS_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0 // not used
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ //language ID = U.S. English, char set = Windows, Multilingual
+
+ BEGIN
+ VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
+ VALUE "FileVersion", "1.2.11\0"
+ VALUE "InternalName", "zlib\0"
+ VALUE "OriginalFilename", "zlibwapi.dll\0"
+ VALUE "ProductName", "ZLib.DLL\0"
+ VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
+ VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 1252
+ END
+END
diff --git a/xs/src/png/zlib/contrib/vstudio/vc14/zlibstat.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc14/zlibstat.vcxproj
new file mode 100644
index 000000000..3e4b98639
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc14/zlibstat.vcxproj
@@ -0,0 +1,467 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>OldStyle</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Lib>
+ <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\gzclose.c" />
+ <ClCompile Include="..\..\..\gzlib.c" />
+ <ClCompile Include="..\..\..\gzread.c" />
+ <ClCompile Include="..\..\..\gzwrite.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\minizip\ioapi.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\minizip\unzip.c" />
+ <ClCompile Include="..\..\minizip\zip.c" />
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.def b/xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.def
new file mode 100644
index 000000000..f876c3bca
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.def
@@ -0,0 +1,153 @@
+LIBRARY
+; zlib data compression and ZIP file I/O library
+
+VERSION 1.2
+
+EXPORTS
+ adler32 @1
+ compress @2
+ crc32 @3
+ deflate @4
+ deflateCopy @5
+ deflateEnd @6
+ deflateInit2_ @7
+ deflateInit_ @8
+ deflateParams @9
+ deflateReset @10
+ deflateSetDictionary @11
+ gzclose @12
+ gzdopen @13
+ gzerror @14
+ gzflush @15
+ gzopen @16
+ gzread @17
+ gzwrite @18
+ inflate @19
+ inflateEnd @20
+ inflateInit2_ @21
+ inflateInit_ @22
+ inflateReset @23
+ inflateSetDictionary @24
+ inflateSync @25
+ uncompress @26
+ zlibVersion @27
+ gzprintf @28
+ gzputc @29
+ gzgetc @30
+ gzseek @31
+ gzrewind @32
+ gztell @33
+ gzeof @34
+ gzsetparams @35
+ zError @36
+ inflateSyncPoint @37
+ get_crc_table @38
+ compress2 @39
+ gzputs @40
+ gzgets @41
+ inflateCopy @42
+ inflateBackInit_ @43
+ inflateBack @44
+ inflateBackEnd @45
+ compressBound @46
+ deflateBound @47
+ gzclearerr @48
+ gzungetc @49
+ zlibCompileFlags @50
+ deflatePrime @51
+ deflatePending @52
+
+ unzOpen @61
+ unzClose @62
+ unzGetGlobalInfo @63
+ unzGetCurrentFileInfo @64
+ unzGoToFirstFile @65
+ unzGoToNextFile @66
+ unzOpenCurrentFile @67
+ unzReadCurrentFile @68
+ unzOpenCurrentFile3 @69
+ unztell @70
+ unzeof @71
+ unzCloseCurrentFile @72
+ unzGetGlobalComment @73
+ unzStringFileNameCompare @74
+ unzLocateFile @75
+ unzGetLocalExtrafield @76
+ unzOpen2 @77
+ unzOpenCurrentFile2 @78
+ unzOpenCurrentFilePassword @79
+
+ zipOpen @80
+ zipOpenNewFileInZip @81
+ zipWriteInFileInZip @82
+ zipCloseFileInZip @83
+ zipClose @84
+ zipOpenNewFileInZip2 @86
+ zipCloseFileInZipRaw @87
+ zipOpen2 @88
+ zipOpenNewFileInZip3 @89
+
+ unzGetFilePos @100
+ unzGoToFilePos @101
+
+ fill_win32_filefunc @110
+
+; zlibwapi v1.2.4 added:
+ fill_win32_filefunc64 @111
+ fill_win32_filefunc64A @112
+ fill_win32_filefunc64W @113
+
+ unzOpen64 @120
+ unzOpen2_64 @121
+ unzGetGlobalInfo64 @122
+ unzGetCurrentFileInfo64 @124
+ unzGetCurrentFileZStreamPos64 @125
+ unztell64 @126
+ unzGetFilePos64 @127
+ unzGoToFilePos64 @128
+
+ zipOpen64 @130
+ zipOpen2_64 @131
+ zipOpenNewFileInZip64 @132
+ zipOpenNewFileInZip2_64 @133
+ zipOpenNewFileInZip3_64 @134
+ zipOpenNewFileInZip4_64 @135
+ zipCloseFileInZipRaw64 @136
+
+; zlib1 v1.2.4 added:
+ adler32_combine @140
+ crc32_combine @142
+ deflateSetHeader @144
+ deflateTune @145
+ gzbuffer @146
+ gzclose_r @147
+ gzclose_w @148
+ gzdirect @149
+ gzoffset @150
+ inflateGetHeader @156
+ inflateMark @157
+ inflatePrime @158
+ inflateReset2 @159
+ inflateUndermine @160
+
+; zlib1 v1.2.6 added:
+ gzgetc_ @161
+ inflateResetKeep @163
+ deflateResetKeep @164
+
+; zlib1 v1.2.7 added:
+ gzopen_w @165
+
+; zlib1 v1.2.8 added:
+ inflateGetDictionary @166
+ gzvprintf @167
+
+; zlib1 v1.2.9 added:
+ inflateCodesUsed @168
+ inflateValidate @169
+ uncompress2 @170
+ gzfread @171
+ gzfwrite @172
+ deflateGetDictionary @173
+ adler32_z @174
+ crc32_z @175
diff --git a/xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.sln b/xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.sln
new file mode 100644
index 000000000..6f4a1076a
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.sln
@@ -0,0 +1,119 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Itanium = Debug|Itanium
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Itanium = Release|Itanium
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium
+ ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32
+ ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.vcxproj b/xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.vcxproj
new file mode 100644
index 000000000..f8f673cb0
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc14/zlibvc.vcxproj
@@ -0,0 +1,692 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Itanium">
+ <Configuration>Debug</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+ <Configuration>ReleaseWithoutAsm</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Itanium">
+ <Configuration>Release</Configuration>
+ <Platform>Itanium</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">zlibwapi</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">zlibwapi</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\contrib\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>X64</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ </Link>
+ <PreBuildEvent>
+ <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+ </PreBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Itanium</TargetEnvironment>
+ <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+ </Midl>
+ <ClCompile>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+ <AssemblerOutput>All</AssemblerOutput>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x040c</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+ <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+ <GenerateMapFile>true</GenerateMapFile>
+ <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+ <SubSystem>Windows</SubSystem>
+ <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+ <TargetMachine>MachineIA64</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\adler32.c" />
+ <ClCompile Include="..\..\..\compress.c" />
+ <ClCompile Include="..\..\..\crc32.c" />
+ <ClCompile Include="..\..\..\deflate.c" />
+ <ClCompile Include="..\..\..\gzclose.c" />
+ <ClCompile Include="..\..\..\gzlib.c" />
+ <ClCompile Include="..\..\..\gzread.c" />
+ <ClCompile Include="..\..\..\gzwrite.c" />
+ <ClCompile Include="..\..\..\infback.c" />
+ <ClCompile Include="..\..\masmx64\inffas8664.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\..\inffast.c" />
+ <ClCompile Include="..\..\..\inflate.c" />
+ <ClCompile Include="..\..\..\inftrees.c" />
+ <ClCompile Include="..\..\minizip\ioapi.c" />
+ <ClCompile Include="..\..\minizip\iowin32.c" />
+ <ClCompile Include="..\..\..\trees.c" />
+ <ClCompile Include="..\..\..\uncompr.c" />
+ <ClCompile Include="..\..\minizip\unzip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\minizip\zip.c">
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="..\..\..\zutil.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="zlib.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="zlibvc.def" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\deflate.h" />
+ <ClInclude Include="..\..\..\infblock.h" />
+ <ClInclude Include="..\..\..\infcodes.h" />
+ <ClInclude Include="..\..\..\inffast.h" />
+ <ClInclude Include="..\..\..\inftrees.h" />
+ <ClInclude Include="..\..\..\infutil.h" />
+ <ClInclude Include="..\..\..\zconf.h" />
+ <ClInclude Include="..\..\..\zlib.h" />
+ <ClInclude Include="..\..\..\zutil.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xs/src/png/zlib/contrib/vstudio/vc9/miniunz.vcproj b/xs/src/png/zlib/contrib/vstudio/vc9/miniunz.vcproj
new file mode 100644
index 000000000..038a9e5fa
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc9/miniunz.vcproj
@@ -0,0 +1,565 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="miniunz"
+ ProjectGUID="{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ <Platform
+ Name="Itanium"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="x86\MiniUnzip$(ConfigurationName)"
+ IntermediateDirectory="x86\MiniUnzip$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"
+ OutputFile="$(OutDir)/miniunz.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="x86\MiniUnzip$(ConfigurationName)"
+ IntermediateDirectory="x86\MiniUnzip$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"
+ OutputFile="$(OutDir)/miniunz.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="x64\MiniUnzip$(ConfigurationName)"
+ IntermediateDirectory="x64\MiniUnzip$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"
+ OutputFile="$(OutDir)/miniunz.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Itanium"
+ OutputDirectory="ia64\MiniUnzip$(ConfigurationName)"
+ IntermediateDirectory="ia64\MiniUnzip$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"
+ OutputFile="$(OutDir)/miniunz.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
+ SubSystem="1"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="x64\MiniUnzip$(ConfigurationName)"
+ IntermediateDirectory="x64\MiniUnzip$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"
+ OutputFile="$(OutDir)/miniunz.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Itanium"
+ OutputDirectory="ia64\MiniUnzip$(ConfigurationName)"
+ IntermediateDirectory="ia64\MiniUnzip$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"
+ OutputFile="$(OutDir)/miniunz.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+ >
+ <File
+ RelativePath="..\..\minizip\miniunz.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/xs/src/png/zlib/contrib/vstudio/vc9/minizip.vcproj b/xs/src/png/zlib/contrib/vstudio/vc9/minizip.vcproj
new file mode 100644
index 000000000..ad4023991
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc9/minizip.vcproj
@@ -0,0 +1,562 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="minizip"
+ ProjectGUID="{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ <Platform
+ Name="Itanium"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="x86\MiniZip$(ConfigurationName)"
+ IntermediateDirectory="x86\MiniZip$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"
+ OutputFile="$(OutDir)/minizip.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/minizip.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="x86\MiniZip$(ConfigurationName)"
+ IntermediateDirectory="x86\MiniZip$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"
+ OutputFile="$(OutDir)/minizip.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="x64\$(ConfigurationName)"
+ IntermediateDirectory="x64\$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"
+ OutputFile="$(OutDir)/minizip.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/minizip.pdb"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Itanium"
+ OutputDirectory="ia64\$(ConfigurationName)"
+ IntermediateDirectory="ia64\$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"
+ OutputFile="$(OutDir)/minizip.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/minizip.pdb"
+ SubSystem="1"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="x64\$(ConfigurationName)"
+ IntermediateDirectory="x64\$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"
+ OutputFile="$(OutDir)/minizip.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Itanium"
+ OutputDirectory="ia64\$(ConfigurationName)"
+ IntermediateDirectory="ia64\$(ConfigurationName)"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"
+ OutputFile="$(OutDir)/minizip.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+ >
+ <File
+ RelativePath="..\..\minizip\minizip.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/xs/src/png/zlib/contrib/vstudio/vc9/testzlib.vcproj b/xs/src/png/zlib/contrib/vstudio/vc9/testzlib.vcproj
new file mode 100644
index 000000000..c9f19d24e
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc9/testzlib.vcproj
@@ -0,0 +1,852 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="testzlib"
+ ProjectGUID="{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
+ RootNamespace="testzlib"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ <Platform
+ Name="Itanium"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="x86\TestZlib$(ConfigurationName)"
+ IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\.."
+ PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ AssemblerOutput="4"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="x64\TestZlib$(ConfigurationName)"
+ IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\.."
+ PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ AssemblerListingLocation="$(IntDir)\"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj"
+ GenerateManifest="false"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Itanium"
+ OutputDirectory="ia64\TestZlib$(ConfigurationName)"
+ IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\.."
+ PreprocessorDefinitions="ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ AssemblerOutput="4"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
+ SubSystem="1"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseWithoutAsm|Win32"
+ OutputDirectory="x86\TestZlib$(ConfigurationName)"
+ IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\.."
+ PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseWithoutAsm|x64"
+ OutputDirectory="x64\TestZlib$(ConfigurationName)"
+ IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\.."
+ PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ AssemblerListingLocation="$(IntDir)\"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies=""
+ GenerateManifest="false"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseWithoutAsm|Itanium"
+ OutputDirectory="ia64\TestZlib$(ConfigurationName)"
+ IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\.."
+ PreprocessorDefinitions="ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="x86\TestZlib$(ConfigurationName)"
+ IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\.."
+ PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="x64\TestZlib$(ConfigurationName)"
+ IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="..\..\.."
+ PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ AssemblerListingLocation="$(IntDir)\"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj"
+ GenerateManifest="false"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Itanium"
+ OutputDirectory="ia64\TestZlib$(ConfigurationName)"
+ IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\.."
+ PreprocessorDefinitions="ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+ >
+ <File
+ RelativePath="..\..\..\adler32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\compress.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\crc32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\deflate.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\infback.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\masmx64\inffas8664.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Itanium"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithoutAsm|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithoutAsm|Itanium"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Itanium"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\..\inffast.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\inflate.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\inftrees.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\testzlib\testzlib.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\trees.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\uncompr.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\zutil.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/xs/src/png/zlib/contrib/vstudio/vc9/testzlibdll.vcproj b/xs/src/png/zlib/contrib/vstudio/vc9/testzlibdll.vcproj
new file mode 100644
index 000000000..d7530fd7d
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc9/testzlibdll.vcproj
@@ -0,0 +1,565 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="TestZlibDll"
+ ProjectGUID="{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ <Platform
+ Name="Itanium"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="x86\TestZlibDll$(ConfigurationName)"
+ IntermediateDirectory="x86\TestZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="x86\TestZlibDll$(ConfigurationName)"
+ IntermediateDirectory="x86\TestZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="x64\TestZlibDll$(ConfigurationName)"
+ IntermediateDirectory="x64\TestZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Itanium"
+ OutputDirectory="ia64\TestZlibDll$(ConfigurationName)"
+ IntermediateDirectory="ia64\TestZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="2"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
+ SubSystem="1"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="x64\TestZlibDll$(ConfigurationName)"
+ IntermediateDirectory="x64\TestZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Itanium"
+ OutputDirectory="ia64\TestZlibDll$(ConfigurationName)"
+ IntermediateDirectory="ia64\TestZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="1"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+ StringPooling="true"
+ BasicRuntimeChecks="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"
+ OutputFile="$(OutDir)/testzlib.exe"
+ LinkIncremental="1"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+ >
+ <File
+ RelativePath="..\..\testzlib\testzlib.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc"
+ >
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/xs/src/png/zlib/contrib/vstudio/vc9/zlib.rc b/xs/src/png/zlib/contrib/vstudio/vc9/zlib.rc
new file mode 100644
index 000000000..c4e4b016e
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc9/zlib.rc
@@ -0,0 +1,32 @@
+#include <windows.h>
+
+#define IDR_VERSION1 1
+IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
+ FILEVERSION 1, 2, 11, 0
+ PRODUCTVERSION 1, 2, 11, 0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS 0
+ FILEOS VOS_DOS_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0 // not used
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ //language ID = U.S. English, char set = Windows, Multilingual
+
+ BEGIN
+ VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
+ VALUE "FileVersion", "1.2.11\0"
+ VALUE "InternalName", "zlib\0"
+ VALUE "OriginalFilename", "zlibwapi.dll\0"
+ VALUE "ProductName", "ZLib.DLL\0"
+ VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
+ VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 1252
+ END
+END
diff --git a/xs/src/png/zlib/contrib/vstudio/vc9/zlibstat.vcproj b/xs/src/png/zlib/contrib/vstudio/vc9/zlibstat.vcproj
new file mode 100644
index 000000000..d4ffb46b2
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc9/zlibstat.vcproj
@@ -0,0 +1,835 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="zlibstat"
+ ProjectGUID="{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ <Platform
+ Name="Itanium"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="x86\ZlibStat$(ConfigurationName)"
+ IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"
+ ConfigurationType="4"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+ ExceptionHandling="0"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="false"
+ PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"
+ OutputFile="$(OutDir)\zlibstat.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="x64\ZlibStat$(ConfigurationName)"
+ IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"
+ ConfigurationType="4"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+ ExceptionHandling="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"
+ OutputFile="$(OutDir)\zlibstat.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Itanium"
+ OutputDirectory="ia64\ZlibStat$(ConfigurationName)"
+ IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"
+ ConfigurationType="4"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+ ExceptionHandling="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"
+ OutputFile="$(OutDir)\zlibstat.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="x86\ZlibStat$(ConfigurationName)"
+ IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"
+ ConfigurationType="4"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"
+ AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj "
+ OutputFile="$(OutDir)\zlibstat.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="x64\ZlibStat$(ConfigurationName)"
+ IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"
+ ConfigurationType="4"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"
+ AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "
+ OutputFile="$(OutDir)\zlibstat.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Itanium"
+ OutputDirectory="ia64\ZlibStat$(ConfigurationName)"
+ IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"
+ ConfigurationType="4"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"
+ OutputFile="$(OutDir)\zlibstat.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseWithoutAsm|Win32"
+ OutputDirectory="x86\ZlibStat$(ConfigurationName)"
+ IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"
+ ConfigurationType="4"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"
+ OutputFile="$(OutDir)\zlibstat.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseWithoutAsm|x64"
+ OutputDirectory="x64\ZlibStat$(ConfigurationName)"
+ IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"
+ ConfigurationType="4"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"
+ OutputFile="$(OutDir)\zlibstat.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseWithoutAsm|Itanium"
+ OutputDirectory="ia64\ZlibStat$(ConfigurationName)"
+ IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"
+ ConfigurationType="4"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="2"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"
+ OutputFile="$(OutDir)\zlibstat.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ >
+ <File
+ RelativePath="..\..\..\adler32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\compress.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\crc32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\deflate.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\gzclose.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\gzguts.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\gzlib.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\gzread.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\gzwrite.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\infback.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\masmx64\inffas8664.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Itanium"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Itanium"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithoutAsm|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithoutAsm|Itanium"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\..\inffast.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\inflate.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\inftrees.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\minizip\ioapi.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\trees.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\uncompr.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\minizip\unzip.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\minizip\zip.c"
+ >
+ </File>
+ <File
+ RelativePath=".\zlib.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\zlibvc.def"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\zutil.c"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.def b/xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.def
new file mode 100644
index 000000000..f876c3bca
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.def
@@ -0,0 +1,153 @@
+LIBRARY
+; zlib data compression and ZIP file I/O library
+
+VERSION 1.2
+
+EXPORTS
+ adler32 @1
+ compress @2
+ crc32 @3
+ deflate @4
+ deflateCopy @5
+ deflateEnd @6
+ deflateInit2_ @7
+ deflateInit_ @8
+ deflateParams @9
+ deflateReset @10
+ deflateSetDictionary @11
+ gzclose @12
+ gzdopen @13
+ gzerror @14
+ gzflush @15
+ gzopen @16
+ gzread @17
+ gzwrite @18
+ inflate @19
+ inflateEnd @20
+ inflateInit2_ @21
+ inflateInit_ @22
+ inflateReset @23
+ inflateSetDictionary @24
+ inflateSync @25
+ uncompress @26
+ zlibVersion @27
+ gzprintf @28
+ gzputc @29
+ gzgetc @30
+ gzseek @31
+ gzrewind @32
+ gztell @33
+ gzeof @34
+ gzsetparams @35
+ zError @36
+ inflateSyncPoint @37
+ get_crc_table @38
+ compress2 @39
+ gzputs @40
+ gzgets @41
+ inflateCopy @42
+ inflateBackInit_ @43
+ inflateBack @44
+ inflateBackEnd @45
+ compressBound @46
+ deflateBound @47
+ gzclearerr @48
+ gzungetc @49
+ zlibCompileFlags @50
+ deflatePrime @51
+ deflatePending @52
+
+ unzOpen @61
+ unzClose @62
+ unzGetGlobalInfo @63
+ unzGetCurrentFileInfo @64
+ unzGoToFirstFile @65
+ unzGoToNextFile @66
+ unzOpenCurrentFile @67
+ unzReadCurrentFile @68
+ unzOpenCurrentFile3 @69
+ unztell @70
+ unzeof @71
+ unzCloseCurrentFile @72
+ unzGetGlobalComment @73
+ unzStringFileNameCompare @74
+ unzLocateFile @75
+ unzGetLocalExtrafield @76
+ unzOpen2 @77
+ unzOpenCurrentFile2 @78
+ unzOpenCurrentFilePassword @79
+
+ zipOpen @80
+ zipOpenNewFileInZip @81
+ zipWriteInFileInZip @82
+ zipCloseFileInZip @83
+ zipClose @84
+ zipOpenNewFileInZip2 @86
+ zipCloseFileInZipRaw @87
+ zipOpen2 @88
+ zipOpenNewFileInZip3 @89
+
+ unzGetFilePos @100
+ unzGoToFilePos @101
+
+ fill_win32_filefunc @110
+
+; zlibwapi v1.2.4 added:
+ fill_win32_filefunc64 @111
+ fill_win32_filefunc64A @112
+ fill_win32_filefunc64W @113
+
+ unzOpen64 @120
+ unzOpen2_64 @121
+ unzGetGlobalInfo64 @122
+ unzGetCurrentFileInfo64 @124
+ unzGetCurrentFileZStreamPos64 @125
+ unztell64 @126
+ unzGetFilePos64 @127
+ unzGoToFilePos64 @128
+
+ zipOpen64 @130
+ zipOpen2_64 @131
+ zipOpenNewFileInZip64 @132
+ zipOpenNewFileInZip2_64 @133
+ zipOpenNewFileInZip3_64 @134
+ zipOpenNewFileInZip4_64 @135
+ zipCloseFileInZipRaw64 @136
+
+; zlib1 v1.2.4 added:
+ adler32_combine @140
+ crc32_combine @142
+ deflateSetHeader @144
+ deflateTune @145
+ gzbuffer @146
+ gzclose_r @147
+ gzclose_w @148
+ gzdirect @149
+ gzoffset @150
+ inflateGetHeader @156
+ inflateMark @157
+ inflatePrime @158
+ inflateReset2 @159
+ inflateUndermine @160
+
+; zlib1 v1.2.6 added:
+ gzgetc_ @161
+ inflateResetKeep @163
+ deflateResetKeep @164
+
+; zlib1 v1.2.7 added:
+ gzopen_w @165
+
+; zlib1 v1.2.8 added:
+ inflateGetDictionary @166
+ gzvprintf @167
+
+; zlib1 v1.2.9 added:
+ inflateCodesUsed @168
+ inflateValidate @169
+ uncompress2 @170
+ gzfread @171
+ gzfwrite @172
+ deflateGetDictionary @173
+ adler32_z @174
+ crc32_z @175
diff --git a/xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.sln b/xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.sln
new file mode 100644
index 000000000..75c64c3f4
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.sln
@@ -0,0 +1,144 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestZlibDll", "testzlibdll.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
+ ProjectSection(ProjectDependencies) = postProject
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
+ ProjectSection(ProjectDependencies) = postProject
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Itanium = Debug|Itanium
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Itanium = Release|Itanium
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium
+ ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32
+ ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+ {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+ {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.vcproj b/xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.vcproj
new file mode 100644
index 000000000..95bb241f3
--- /dev/null
+++ b/xs/src/png/zlib/contrib/vstudio/vc9/zlibvc.vcproj
@@ -0,0 +1,1156 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="zlibvc"
+ ProjectGUID="{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+ RootNamespace="zlibvc"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ <Platform
+ Name="Itanium"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="x86\ZlibDll$(ConfigurationName)"
+ IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="2"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName="$(OutDir)/zlibvc.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF"
+ ExceptionHandling="0"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="false"
+ PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ BrowseInformation="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj"
+ OutputFile="$(OutDir)\zlibwapi.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ GenerateManifest="false"
+ ModuleDefinitionFile=".\zlibvc.def"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+ GenerateMapFile="true"
+ MapFileName="$(OutDir)/zlibwapi.map"
+ SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/zlibwapi.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="x64\ZlibDll$(ConfigurationName)"
+ IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="2"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="3"
+ TypeLibraryName="$(OutDir)/zlibvc.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64"
+ ExceptionHandling="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ BrowseInformation="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "
+ OutputFile="$(OutDir)\zlibwapi.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ GenerateManifest="false"
+ ModuleDefinitionFile=".\zlibvc.def"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+ GenerateMapFile="true"
+ MapFileName="$(OutDir)/zlibwapi.map"
+ SubSystem="2"
+ ImportLibrary="$(OutDir)/zlibwapi.lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Itanium"
+ OutputDirectory="ia64\ZlibDll$(ConfigurationName)"
+ IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="2"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="2"
+ TypeLibraryName="$(OutDir)/zlibvc.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"
+ ExceptionHandling="0"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="false"
+ PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ BrowseInformation="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\zlibwapi.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ GenerateManifest="false"
+ ModuleDefinitionFile=".\zlibvc.def"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+ GenerateMapFile="true"
+ MapFileName="$(OutDir)/zlibwapi.map"
+ SubSystem="2"
+ ImportLibrary="$(OutDir)/zlibwapi.lib"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseWithoutAsm|Win32"
+ OutputDirectory="x86\ZlibDll$(ConfigurationName)"
+ IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="2"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName="$(OutDir)/zlibvc.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+ AssemblerOutput="2"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ BrowseInformation="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ OutputFile="$(OutDir)\zlibwapi.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="false"
+ ModuleDefinitionFile=".\zlibvc.def"
+ ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+ GenerateMapFile="true"
+ MapFileName="$(OutDir)/zlibwapi.map"
+ SubSystem="2"
+ OptimizeForWindows98="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/zlibwapi.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseWithoutAsm|x64"
+ OutputDirectory="x64\ZlibDll$(ConfigurationName)"
+ IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="2"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="3"
+ TypeLibraryName="$(OutDir)/zlibvc.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+ AssemblerOutput="2"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ BrowseInformation="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\zlibwapi.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="false"
+ ModuleDefinitionFile=".\zlibvc.def"
+ ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+ GenerateMapFile="true"
+ MapFileName="$(OutDir)/zlibwapi.map"
+ SubSystem="2"
+ OptimizeForWindows98="1"
+ ImportLibrary="$(OutDir)/zlibwapi.lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseWithoutAsm|Itanium"
+ OutputDirectory="ia64\ZlibDll$(ConfigurationName)"
+ IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="2"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="2"
+ TypeLibraryName="$(OutDir)/zlibvc.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+ AssemblerOutput="2"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ BrowseInformation="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\zlibwapi.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="false"
+ ModuleDefinitionFile=".\zlibvc.def"
+ ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+ GenerateMapFile="true"
+ MapFileName="$(OutDir)/zlibwapi.map"
+ SubSystem="2"
+ OptimizeForWindows98="1"
+ ImportLibrary="$(OutDir)/zlibwapi.lib"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="x86\ZlibDll$(ConfigurationName)"
+ IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="2"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName="$(OutDir)/zlibvc.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+ AssemblerOutput="2"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ BrowseInformation="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj "
+ OutputFile="$(OutDir)\zlibwapi.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="false"
+ ModuleDefinitionFile=".\zlibvc.def"
+ ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+ GenerateMapFile="true"
+ MapFileName="$(OutDir)/zlibwapi.map"
+ SubSystem="2"
+ OptimizeForWindows98="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/zlibwapi.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="x64\ZlibDll$(ConfigurationName)"
+ IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="2"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="3"
+ TypeLibraryName="$(OutDir)/zlibvc.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+ AssemblerOutput="2"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ BrowseInformation="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "
+ OutputFile="$(OutDir)\zlibwapi.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="false"
+ ModuleDefinitionFile=".\zlibvc.def"
+ ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+ GenerateMapFile="true"
+ MapFileName="$(OutDir)/zlibwapi.map"
+ SubSystem="2"
+ OptimizeForWindows98="1"
+ ImportLibrary="$(OutDir)/zlibwapi.lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Itanium"
+ OutputDirectory="ia64\ZlibDll$(ConfigurationName)"
+ IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"
+ ConfigurationType="2"
+ InheritedPropertySheets="UpgradeFromVC70.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="2"
+ TypeLibraryName="$(OutDir)/zlibvc.tlb"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+ PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+ AssemblerOutput="2"
+ AssemblerListingLocation="$(IntDir)\"
+ ObjectFile="$(IntDir)\"
+ ProgramDataBaseFileName="$(OutDir)\"
+ BrowseInformation="0"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1036"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\zlibwapi.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateManifest="false"
+ IgnoreAllDefaultLibraries="false"
+ ModuleDefinitionFile=".\zlibvc.def"
+ ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+ GenerateMapFile="true"
+ MapFileName="$(OutDir)/zlibwapi.map"
+ SubSystem="2"
+ OptimizeForWindows98="1"
+ ImportLibrary="$(OutDir)/zlibwapi.lib"
+ TargetMachine="5"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
+ >
+ <File
+ RelativePath="..\..\..\adler32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\compress.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\crc32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\deflate.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\gzclose.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\gzguts.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\gzlib.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\gzread.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\gzwrite.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\infback.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\masmx64\inffas8664.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Itanium"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithoutAsm|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithoutAsm|Itanium"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Itanium"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\..\inffast.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\inflate.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\inftrees.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\minizip\ioapi.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\minizip\iowin32.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\trees.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\uncompr.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\minizip\unzip.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="ZLIB_INTERNAL"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="ZLIB_INTERNAL"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Itanium"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="ZLIB_INTERNAL"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\..\minizip\zip.c"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="ZLIB_INTERNAL"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="ZLIB_INTERNAL"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Itanium"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="ZLIB_INTERNAL"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\zlib.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\zlibvc.def"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\zutil.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;fi;fd"
+ >
+ <File
+ RelativePath="..\..\..\deflate.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\infblock.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\infcodes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\inffast.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\inftrees.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\infutil.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\zconf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\zlib.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\zutil.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/xs/src/png/zlib/crc32.c b/xs/src/png/zlib/crc32.c
new file mode 100644
index 000000000..9580440c0
--- /dev/null
+++ b/xs/src/png/zlib/crc32.c
@@ -0,0 +1,442 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors. This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+ Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+ protection on the static variables used to control the first-use generation
+ of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+ first call get_crc_table() to initialize the tables before allowing more than
+ one thread to use crc32().
+
+ DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
+ */
+
+#ifdef MAKECRCH
+# include <stdio.h>
+# ifndef DYNAMIC_CRC_TABLE
+# define DYNAMIC_CRC_TABLE
+# endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h" /* for STDC and FAR definitions */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#if !defined(NOBYFOUR) && defined(Z_U4)
+# define BYFOUR
+#endif
+#ifdef BYFOUR
+ local unsigned long crc32_little OF((unsigned long,
+ const unsigned char FAR *, z_size_t));
+ local unsigned long crc32_big OF((unsigned long,
+ const unsigned char FAR *, z_size_t));
+# define TBLS 8
+#else
+# define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+ unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
+
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local z_crc_t FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+ local void write_table OF((FILE *, const z_crc_t FAR *));
+#endif /* MAKECRCH */
+/*
+ Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The first table is simply the CRC of all possible eight bit values. This is
+ all the information needed to generate CRCs on data a byte at a time for all
+ combinations of CRC register values and incoming bytes. The remaining tables
+ allow for word-at-a-time CRC calculation for both big-endian and little-
+ endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+ z_crc_t c;
+ int n, k;
+ z_crc_t poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static volatile int first = 1; /* flag to limit concurrent making */
+ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* See if another task is already doing this (not thread-safe, but better
+ than nothing -- significantly reduces duration of vulnerability in
+ case the advice about DYNAMIC_CRC_TABLE is ignored) */
+ if (first) {
+ first = 0;
+
+ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+ poly = 0;
+ for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
+ poly |= (z_crc_t)1 << (31 - p[n]);
+
+ /* generate a crc for every 8-bit value */
+ for (n = 0; n < 256; n++) {
+ c = (z_crc_t)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[0][n] = c;
+ }
+
+#ifdef BYFOUR
+ /* generate crc for each value followed by one, two, and three zeros,
+ and then the byte reversal of those as well as the first table */
+ for (n = 0; n < 256; n++) {
+ c = crc_table[0][n];
+ crc_table[4][n] = ZSWAP32(c);
+ for (k = 1; k < 4; k++) {
+ c = crc_table[0][c & 0xff] ^ (c >> 8);
+ crc_table[k][n] = c;
+ crc_table[k + 4][n] = ZSWAP32(c);
+ }
+ }
+#endif /* BYFOUR */
+
+ crc_table_empty = 0;
+ }
+ else { /* not first */
+ /* wait for the other guy to finish (not efficient, but rare) */
+ while (crc_table_empty)
+ ;
+ }
+
+#ifdef MAKECRCH
+ /* write out CRC tables to crc32.h */
+ {
+ FILE *out;
+
+ out = fopen("crc32.h", "w");
+ if (out == NULL) return;
+ fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+ fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+ fprintf(out, "local const z_crc_t FAR ");
+ fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
+ write_table(out, crc_table[0]);
+# ifdef BYFOUR
+ fprintf(out, "#ifdef BYFOUR\n");
+ for (k = 1; k < 8; k++) {
+ fprintf(out, " },\n {\n");
+ write_table(out, crc_table[k]);
+ }
+ fprintf(out, "#endif\n");
+# endif /* BYFOUR */
+ fprintf(out, " }\n};\n");
+ fclose(out);
+ }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+ FILE *out;
+ const z_crc_t FAR *table;
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
+ (unsigned long)(table[n]),
+ n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const z_crc_t FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+ return (const z_crc_t FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32_z(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ z_size_t len;
+{
+ if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+ if (sizeof(void *) == sizeof(ptrdiff_t)) {
+ z_crc_t endian;
+
+ endian = 1;
+ if (*((unsigned char *)(&endian)))
+ return crc32_little(crc, buf, len);
+ else
+ return crc32_big(crc, buf, len);
+ }
+#endif /* BYFOUR */
+ crc = crc ^ 0xffffffffUL;
+ while (len >= 8) {
+ DO8;
+ len -= 8;
+ }
+ if (len) do {
+ DO1;
+ } while (--len);
+ return crc ^ 0xffffffffUL;
+}
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ uInt len;
+{
+ return crc32_z(crc, buf, len);
+}
+
+#ifdef BYFOUR
+
+/*
+ This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit
+ integer pointer type. This violates the strict aliasing rule, where a
+ compiler can assume, for optimization purposes, that two pointers to
+ fundamentally different types won't ever point to the same memory. This can
+ manifest as a problem only if one of the pointers is written to. This code
+ only reads from those pointers. So long as this code remains isolated in
+ this compilation unit, there won't be a problem. For this reason, this code
+ should not be copied and pasted into a compilation unit in which other code
+ writes to the buffer that is passed to these routines.
+ */
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ z_size_t len;
+{
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
+
+ c = (z_crc_t)crc;
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ len--;
+ }
+
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+ while (len >= 32) {
+ DOLIT32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOLIT4;
+ len -= 4;
+ }
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *buf4++; \
+ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ z_size_t len;
+{
+ register z_crc_t c;
+ register const z_crc_t FAR *buf4;
+
+ c = ZSWAP32((z_crc_t)crc);
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ len--;
+ }
+
+ buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+ while (len >= 32) {
+ DOBIG32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOBIG4;
+ len -= 4;
+ }
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)(ZSWAP32(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+ unsigned long *mat;
+ unsigned long vec;
+{
+ unsigned long sum;
+
+ sum = 0;
+ while (vec) {
+ if (vec & 1)
+ sum ^= *mat;
+ vec >>= 1;
+ mat++;
+ }
+ return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+ unsigned long *square;
+ unsigned long *mat;
+{
+ int n;
+
+ for (n = 0; n < GF2_DIM; n++)
+ square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+local uLong crc32_combine_(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off64_t len2;
+{
+ int n;
+ unsigned long row;
+ unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
+ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
+
+ /* degenerate case (also disallow negative lengths) */
+ if (len2 <= 0)
+ return crc1;
+
+ /* put operator for one zero bit in odd */
+ odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
+ row = 1;
+ for (n = 1; n < GF2_DIM; n++) {
+ odd[n] = row;
+ row <<= 1;
+ }
+
+ /* put operator for two zero bits in even */
+ gf2_matrix_square(even, odd);
+
+ /* put operator for four zero bits in odd */
+ gf2_matrix_square(odd, even);
+
+ /* apply len2 zeros to crc1 (first square will put the operator for one
+ zero byte, eight zero bits, in even) */
+ do {
+ /* apply zeros operator for this bit of len2 */
+ gf2_matrix_square(even, odd);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(even, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ if (len2 == 0)
+ break;
+
+ /* another iteration of the loop with odd and even swapped */
+ gf2_matrix_square(odd, even);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(odd, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ } while (len2 != 0);
+
+ /* return combined crc */
+ crc1 ^= crc2;
+ return crc1;
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+ uLong crc1;
+ uLong crc2;
+ z_off64_t len2;
+{
+ return crc32_combine_(crc1, crc2, len2);
+}
diff --git a/xs/src/png/zlib/crc32.h b/xs/src/png/zlib/crc32.h
new file mode 100644
index 000000000..9e0c77810
--- /dev/null
+++ b/xs/src/png/zlib/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const z_crc_t FAR crc_table[TBLS][256] =
+{
+ {
+ 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+ 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+ 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+ 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+ 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+ 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+ 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+ 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+ 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+ 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+ 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+ 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+ 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+ 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+ 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+ 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+ 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+ 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+ 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+ 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+ 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+ 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+ 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+ 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+ 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+ 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+ 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+ 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+ 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+ 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+ 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+ 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+ 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+ 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+ 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+ 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+ 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+ 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+ 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+ 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+ 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+ 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+ 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+ 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+ 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+ 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+ 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+ 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+ 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+ 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+ 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+ 0x2d02ef8dUL
+#ifdef BYFOUR
+ },
+ {
+ 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+ 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+ 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+ 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+ 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+ 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+ 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+ 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+ 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+ 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+ 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+ 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+ 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+ 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+ 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+ 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+ 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+ 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+ 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+ 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+ 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+ 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+ 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+ 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+ 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+ 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+ 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+ 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+ 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+ 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+ 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+ 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+ 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+ 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+ 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+ 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+ 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+ 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+ 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+ 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+ 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+ 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+ 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+ 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+ 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+ 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+ 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+ 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+ 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+ 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+ 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+ 0x9324fd72UL
+ },
+ {
+ 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+ 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+ 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+ 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+ 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+ 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+ 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+ 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+ 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+ 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+ 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+ 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+ 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+ 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+ 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+ 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+ 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+ 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+ 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+ 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+ 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+ 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+ 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+ 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+ 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+ 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+ 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+ 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+ 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+ 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+ 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+ 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+ 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+ 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+ 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+ 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+ 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+ 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+ 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+ 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+ 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+ 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+ 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+ 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+ 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+ 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+ 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+ 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+ 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+ 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+ 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+ 0xbe9834edUL
+ },
+ {
+ 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+ 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+ 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+ 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+ 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+ 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+ 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+ 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+ 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+ 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+ 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+ 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+ 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+ 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+ 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+ 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+ 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+ 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+ 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+ 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+ 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+ 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+ 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+ 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+ 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+ 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+ 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+ 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+ 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+ 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+ 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+ 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+ 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+ 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+ 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+ 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+ 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+ 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+ 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+ 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+ 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+ 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+ 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+ 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+ 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+ 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+ 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+ 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+ 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+ 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+ 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+ 0xde0506f1UL
+ },
+ {
+ 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+ 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+ 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+ 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+ 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+ 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+ 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+ 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+ 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+ 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+ 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+ 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+ 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+ 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+ 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+ 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+ 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+ 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+ 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+ 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+ 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+ 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+ 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+ 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+ 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+ 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+ 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+ 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+ 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+ 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+ 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+ 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+ 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+ 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+ 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+ 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+ 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+ 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+ 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+ 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+ 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+ 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+ 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+ 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+ 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+ 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+ 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+ 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+ 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+ 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+ 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+ 0x8def022dUL
+ },
+ {
+ 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+ 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+ 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+ 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+ 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+ 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+ 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+ 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+ 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+ 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+ 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+ 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+ 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+ 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+ 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+ 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+ 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+ 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+ 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+ 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+ 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+ 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+ 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+ 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+ 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+ 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+ 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+ 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+ 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+ 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+ 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+ 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+ 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+ 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+ 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+ 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+ 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+ 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+ 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+ 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+ 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+ 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+ 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+ 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+ 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+ 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+ 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+ 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+ 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+ 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+ 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+ 0x72fd2493UL
+ },
+ {
+ 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+ 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+ 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+ 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+ 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+ 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+ 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+ 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+ 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+ 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+ 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+ 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+ 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+ 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+ 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+ 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+ 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+ 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+ 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+ 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+ 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+ 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+ 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+ 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+ 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+ 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+ 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+ 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+ 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+ 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+ 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+ 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+ 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+ 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+ 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+ 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+ 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+ 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+ 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+ 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+ 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+ 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+ 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+ 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+ 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+ 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+ 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+ 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+ 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+ 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+ 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+ 0xed3498beUL
+ },
+ {
+ 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+ 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+ 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+ 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+ 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+ 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+ 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+ 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+ 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+ 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+ 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+ 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+ 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+ 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+ 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+ 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+ 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+ 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+ 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+ 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+ 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+ 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+ 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+ 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+ 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+ 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+ 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+ 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+ 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+ 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+ 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+ 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+ 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+ 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+ 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+ 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+ 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+ 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+ 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+ 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+ 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+ 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+ 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+ 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+ 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+ 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+ 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+ 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+ 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+ 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+ 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+ 0xf10605deUL
+#endif
+ }
+};
diff --git a/xs/src/png/zlib/deflate.c b/xs/src/png/zlib/deflate.c
new file mode 100644
index 000000000..1ec761448
--- /dev/null
+++ b/xs/src/png/zlib/deflate.c
@@ -0,0 +1,2163 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process depends on being able to identify portions
+ * of the input text which are identical to earlier input (within a
+ * sliding window trailing behind the input currently being processed).
+ *
+ * The most straightforward technique turns out to be the fastest for
+ * most input files: try all possible matches and select the longest.
+ * The key feature of this algorithm is that insertions into the string
+ * dictionary are very simple and thus fast, and deletions are avoided
+ * completely. Insertions are performed at each input character, whereas
+ * string matches are performed only when the previous match ends. So it
+ * is preferable to spend more time in matches to allow very fast string
+ * insertions and avoid deletions. The matching algorithm for small
+ * strings is inspired from that of Rabin & Karp. A brute force approach
+ * is used to find longer strings when a small match has been found.
+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ * (by Leonid Broukhis).
+ * A previous version of this file used a more sophisticated algorithm
+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
+ * time, but has a larger average cost, uses more memory and is patented.
+ * However the F&G algorithm may be faster for some highly redundant
+ * files if the parameter max_chain_length (described below) is too large.
+ *
+ * ACKNOWLEDGEMENTS
+ *
+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ * I found it in 'freeze' written by Leonid Broukhis.
+ * Thanks to many people for bug reports and testing.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ * Available in http://tools.ietf.org/html/rfc1951
+ *
+ * A description of the Rabin and Karp algorithm is given in the book
+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ * Fiala,E.R., and Greene,D.H.
+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+ " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ * Function prototypes.
+ */
+typedef enum {
+ need_more, /* block not completed, need more input or more output */
+ block_done, /* block flush performed */
+ finish_started, /* finish started, need only more output at next deflate */
+ finish_done /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local int deflateStateCheck OF((z_streamp strm));
+local void slide_hash OF((deflate_state *s));
+local void fill_window OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow OF((deflate_state *s, int flush));
+#endif
+local block_state deflate_rle OF((deflate_state *s, int flush));
+local block_state deflate_huff OF((deflate_state *s, int flush));
+local void lm_init OF((deflate_state *s));
+local void putShortMSB OF((deflate_state *s, uInt b));
+local void flush_pending OF((z_streamp strm));
+local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+# pragma message("Assembler code may have bugs -- use at your own risk")
+ void match_init OF((void)); /* asm code initialization */
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef ZLIB_DEBUG
+local void check_match OF((deflate_state *s, IPos start, IPos match,
+ int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+# define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+ ush good_length; /* reduce lazy search above this match length */
+ ush max_lazy; /* do not perform lazy search above this match length */
+ ush nice_length; /* quit search above this match length */
+ ush max_chain;
+ compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4, 5, 16, 8, deflate_fast},
+/* 3 */ {4, 6, 32, 32, deflate_fast},
+
+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
+/* 5 */ {8, 16, 32, 32, deflate_slow},
+/* 6 */ {8, 16, 128, 128, deflate_slow},
+/* 7 */ {8, 32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
+#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0))
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN assertion: all calls to UPDATE_HASH are made with consecutive input
+ * characters, so that a running hash key can be computed from the previous
+ * key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN assertion: all calls to INSERT_STRING are made with consecutive input
+ * characters and the first MIN_MATCH bytes of str are valid (except for
+ * the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ===========================================================================
+ * Slide the hash table when sliding the window down (could be avoided with 32
+ * bit values at the expense of memory usage). We slide even when level == 0 to
+ * keep the hash table consistent if we switch back to level > 0 later.
+ */
+local void slide_hash(s)
+ deflate_state *s;
+{
+ unsigned n, m;
+ Posf *p;
+ uInt wsize = s->w_size;
+
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m - wsize : NIL);
+ } while (--n);
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m - wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+ z_streamp strm;
+ int level;
+ const char *version;
+ int stream_size;
+{
+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY, version, stream_size);
+ /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+ version, stream_size)
+ z_streamp strm;
+ int level;
+ int method;
+ int windowBits;
+ int memLevel;
+ int strategy;
+ const char *version;
+ int stream_size;
+{
+ deflate_state *s;
+ int wrap = 1;
+ static const char my_version[] = ZLIB_VERSION;
+
+ ushf *overlay;
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
+ * output size for (length,distance) codes is <= 24 bits.
+ */
+
+ if (version == Z_NULL || version[0] != my_version[0] ||
+ stream_size != sizeof(z_stream)) {
+ return Z_VERSION_ERROR;
+ }
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->msg = Z_NULL;
+ if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+#endif
+ }
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+ if (windowBits < 0) { /* suppress zlib wrapper */
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+#ifdef GZIP
+ else if (windowBits > 15) {
+ wrap = 2; /* write gzip wrapper instead */
+ windowBits -= 16;
+ }
+#endif
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+ windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+ strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) {
+ return Z_STREAM_ERROR;
+ }
+ if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+ if (s == Z_NULL) return Z_MEM_ERROR;
+ strm->state = (struct internal_state FAR *)s;
+ s->strm = strm;
+ s->status = INIT_STATE; /* to pass state test in deflateReset() */
+
+ s->wrap = wrap;
+ s->gzhead = Z_NULL;
+ s->w_bits = (uInt)windowBits;
+ s->w_size = 1 << s->w_bits;
+ s->w_mask = s->w_size - 1;
+
+ s->hash_bits = (uInt)memLevel + 7;
+ s->hash_size = 1 << s->hash_bits;
+ s->hash_mask = s->hash_size - 1;
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+ s->high_water = 0; /* nothing written to s->window yet */
+
+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+ s->pending_buf = (uchf *) overlay;
+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+ s->pending_buf == Z_NULL) {
+ s->status = FINISH_STATE;
+ strm->msg = ERR_MSG(Z_MEM_ERROR);
+ deflateEnd (strm);
+ return Z_MEM_ERROR;
+ }
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+ s->level = level;
+ s->strategy = strategy;
+ s->method = (Byte)method;
+
+ return deflateReset(strm);
+}
+
+/* =========================================================================
+ * Check for a valid deflate stream state. Return 0 if ok, 1 if not.
+ */
+local int deflateStateCheck (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+ if (strm == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
+ return 1;
+ s = strm->state;
+ if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE &&
+#ifdef GZIP
+ s->status != GZIP_STATE &&
+#endif
+ s->status != EXTRA_STATE &&
+ s->status != NAME_STATE &&
+ s->status != COMMENT_STATE &&
+ s->status != HCRC_STATE &&
+ s->status != BUSY_STATE &&
+ s->status != FINISH_STATE))
+ return 1;
+ return 0;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ const Bytef *dictionary;
+ uInt dictLength;
+{
+ deflate_state *s;
+ uInt str, n;
+ int wrap;
+ unsigned avail;
+ z_const unsigned char *next;
+
+ if (deflateStateCheck(strm) || dictionary == Z_NULL)
+ return Z_STREAM_ERROR;
+ s = strm->state;
+ wrap = s->wrap;
+ if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
+ return Z_STREAM_ERROR;
+
+ /* when using zlib wrappers, compute Adler-32 for provided dictionary */
+ if (wrap == 1)
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+ s->wrap = 0; /* avoid computing Adler-32 in read_buf */
+
+ /* if dictionary would fill window, just replace the history */
+ if (dictLength >= s->w_size) {
+ if (wrap == 0) { /* already empty otherwise */
+ CLEAR_HASH(s);
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->insert = 0;
+ }
+ dictionary += dictLength - s->w_size; /* use the tail */
+ dictLength = s->w_size;
+ }
+
+ /* insert dictionary into window and hash */
+ avail = strm->avail_in;
+ next = strm->next_in;
+ strm->avail_in = dictLength;
+ strm->next_in = (z_const Bytef *)dictionary;
+ fill_window(s);
+ while (s->lookahead >= MIN_MATCH) {
+ str = s->strstart;
+ n = s->lookahead - (MIN_MATCH-1);
+ do {
+ UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+ s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+ s->head[s->ins_h] = (Pos)str;
+ str++;
+ } while (--n);
+ s->strstart = str;
+ s->lookahead = MIN_MATCH-1;
+ fill_window(s);
+ }
+ s->strstart += s->lookahead;
+ s->block_start = (long)s->strstart;
+ s->insert = s->lookahead;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ strm->next_in = next;
+ strm->avail_in = avail;
+ s->wrap = wrap;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ Bytef *dictionary;
+ uInt *dictLength;
+{
+ deflate_state *s;
+ uInt len;
+
+ if (deflateStateCheck(strm))
+ return Z_STREAM_ERROR;
+ s = strm->state;
+ len = s->strstart + s->lookahead;
+ if (len > s->w_size)
+ len = s->w_size;
+ if (dictionary != Z_NULL && len)
+ zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len);
+ if (dictLength != Z_NULL)
+ *dictLength = len;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateResetKeep (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+
+ if (deflateStateCheck(strm)) {
+ return Z_STREAM_ERROR;
+ }
+
+ strm->total_in = strm->total_out = 0;
+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+ strm->data_type = Z_UNKNOWN;
+
+ s = (deflate_state *)strm->state;
+ s->pending = 0;
+ s->pending_out = s->pending_buf;
+
+ if (s->wrap < 0) {
+ s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+ }
+ s->status =
+#ifdef GZIP
+ s->wrap == 2 ? GZIP_STATE :
+#endif
+ s->wrap ? INIT_STATE : BUSY_STATE;
+ strm->adler =
+#ifdef GZIP
+ s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+ adler32(0L, Z_NULL, 0);
+ s->last_flush = Z_NO_FLUSH;
+
+ _tr_init(s);
+
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ int ret;
+
+ ret = deflateResetKeep(strm);
+ if (ret == Z_OK)
+ lm_init(strm->state);
+ return ret;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+ z_streamp strm;
+ gz_headerp head;
+{
+ if (deflateStateCheck(strm) || strm->state->wrap != 2)
+ return Z_STREAM_ERROR;
+ strm->state->gzhead = head;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePending (strm, pending, bits)
+ unsigned *pending;
+ int *bits;
+ z_streamp strm;
+{
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+ if (pending != Z_NULL)
+ *pending = strm->state->pending;
+ if (bits != Z_NULL)
+ *bits = strm->state->bi_valid;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+ z_streamp strm;
+ int bits;
+ int value;
+{
+ deflate_state *s;
+ int put;
+
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+ s = strm->state;
+ if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+ return Z_BUF_ERROR;
+ do {
+ put = Buf_size - s->bi_valid;
+ if (put > bits)
+ put = bits;
+ s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
+ s->bi_valid += put;
+ _tr_flush_bits(s);
+ value >>= put;
+ bits -= put;
+ } while (bits);
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+ z_streamp strm;
+ int level;
+ int strategy;
+{
+ deflate_state *s;
+ compress_func func;
+
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+ s = strm->state;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+ return Z_STREAM_ERROR;
+ }
+ func = configuration_table[s->level].func;
+
+ if ((strategy != s->strategy || func != configuration_table[level].func) &&
+ s->high_water) {
+ /* Flush the last buffer: */
+ int err = deflate(strm, Z_BLOCK);
+ if (err == Z_STREAM_ERROR)
+ return err;
+ if (strm->avail_out == 0)
+ return Z_BUF_ERROR;
+ }
+ if (s->level != level) {
+ if (s->level == 0 && s->matches != 0) {
+ if (s->matches == 1)
+ slide_hash(s);
+ else
+ CLEAR_HASH(s);
+ s->matches = 0;
+ }
+ s->level = level;
+ s->max_lazy_match = configuration_table[level].max_lazy;
+ s->good_match = configuration_table[level].good_length;
+ s->nice_match = configuration_table[level].nice_length;
+ s->max_chain_length = configuration_table[level].max_chain;
+ }
+ s->strategy = strategy;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+ z_streamp strm;
+ int good_length;
+ int max_lazy;
+ int nice_length;
+ int max_chain;
+{
+ deflate_state *s;
+
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+ s = strm->state;
+ s->good_match = (uInt)good_length;
+ s->max_lazy_match = (uInt)max_lazy;
+ s->nice_match = nice_length;
+ s->max_chain_length = (uInt)max_chain;
+ return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well. The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds for
+ * every combination of windowBits and memLevel. But even the conservative
+ * upper bound of about 14% expansion does not seem onerous for output buffer
+ * allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+ z_streamp strm;
+ uLong sourceLen;
+{
+ deflate_state *s;
+ uLong complen, wraplen;
+
+ /* conservative upper bound for compressed data */
+ complen = sourceLen +
+ ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
+
+ /* if can't get parameters, return conservative bound plus zlib wrapper */
+ if (deflateStateCheck(strm))
+ return complen + 6;
+
+ /* compute wrapper length */
+ s = strm->state;
+ switch (s->wrap) {
+ case 0: /* raw deflate */
+ wraplen = 0;
+ break;
+ case 1: /* zlib wrapper */
+ wraplen = 6 + (s->strstart ? 4 : 0);
+ break;
+#ifdef GZIP
+ case 2: /* gzip wrapper */
+ wraplen = 18;
+ if (s->gzhead != Z_NULL) { /* user-supplied gzip header */
+ Bytef *str;
+ if (s->gzhead->extra != Z_NULL)
+ wraplen += 2 + s->gzhead->extra_len;
+ str = s->gzhead->name;
+ if (str != Z_NULL)
+ do {
+ wraplen++;
+ } while (*str++);
+ str = s->gzhead->comment;
+ if (str != Z_NULL)
+ do {
+ wraplen++;
+ } while (*str++);
+ if (s->gzhead->hcrc)
+ wraplen += 2;
+ }
+ break;
+#endif
+ default: /* for compiler happiness */
+ wraplen = 6;
+ }
+
+ /* if not default parameters, return conservative bound */
+ if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+ return complen + wraplen;
+
+ /* default settings: return tight bound for that case */
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+ (sourceLen >> 25) + 13 - 6 + wraplen;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+ deflate_state *s;
+ uInt b;
+{
+ put_byte(s, (Byte)(b >> 8));
+ put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output, except for
+ * some deflate_stored() output, goes through this function so some
+ * applications may wish to modify it to avoid allocating a large
+ * strm->next_out buffer and copying into it. (See also read_buf()).
+ */
+local void flush_pending(strm)
+ z_streamp strm;
+{
+ unsigned len;
+ deflate_state *s = strm->state;
+
+ _tr_flush_bits(s);
+ len = s->pending;
+ if (len > strm->avail_out) len = strm->avail_out;
+ if (len == 0) return;
+
+ zmemcpy(strm->next_out, s->pending_out, len);
+ strm->next_out += len;
+ s->pending_out += len;
+ strm->total_out += len;
+ strm->avail_out -= len;
+ s->pending -= len;
+ if (s->pending == 0) {
+ s->pending_out = s->pending_buf;
+ }
+}
+
+/* ===========================================================================
+ * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1].
+ */
+#define HCRC_UPDATE(beg) \
+ do { \
+ if (s->gzhead->hcrc && s->pending > (beg)) \
+ strm->adler = crc32(strm->adler, s->pending_buf + (beg), \
+ s->pending - (beg)); \
+ } while (0)
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+ z_streamp strm;
+ int flush;
+{
+ int old_flush; /* value of flush param for previous deflate call */
+ deflate_state *s;
+
+ if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
+ s = strm->state;
+
+ if (strm->next_out == Z_NULL ||
+ (strm->avail_in != 0 && strm->next_in == Z_NULL) ||
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
+ ERR_RETURN(strm, Z_STREAM_ERROR);
+ }
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+ old_flush = s->last_flush;
+ s->last_flush = flush;
+
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ /* Since avail_out is 0, deflate will be called again with
+ * more output space, but possibly with both pending and
+ * avail_in equal to zero. There won't be anything to do,
+ * but this is not an error situation so make sure we
+ * return OK instead of BUF_ERROR at next call of deflate:
+ */
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ /* Make sure there is something to do and avoid duplicate consecutive
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
+ * returning Z_STREAM_END instead of Z_BUF_ERROR.
+ */
+ } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* Write the header */
+ if (s->status == INIT_STATE) {
+ /* zlib header */
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags;
+
+ if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+ level_flags = 0;
+ else if (s->level < 6)
+ level_flags = 1;
+ else if (s->level == 6)
+ level_flags = 2;
+ else
+ level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ putShortMSB(s, header);
+
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ strm->adler = adler32(0L, Z_NULL, 0);
+ s->status = BUSY_STATE;
+
+ /* Compression must start with an empty pending buffer */
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ }
+#ifdef GZIP
+ if (s->status == GZIP_STATE) {
+ /* gzip header */
+ strm->adler = crc32(0L, Z_NULL, 0);
+ put_byte(s, 31);
+ put_byte(s, 139);
+ put_byte(s, 8);
+ if (s->gzhead == Z_NULL) {
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, OS_CODE);
+ s->status = BUSY_STATE;
+
+ /* Compression must start with an empty pending buffer */
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ }
+ else {
+ put_byte(s, (s->gzhead->text ? 1 : 0) +
+ (s->gzhead->hcrc ? 2 : 0) +
+ (s->gzhead->extra == Z_NULL ? 0 : 4) +
+ (s->gzhead->name == Z_NULL ? 0 : 8) +
+ (s->gzhead->comment == Z_NULL ? 0 : 16)
+ );
+ put_byte(s, (Byte)(s->gzhead->time & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, s->gzhead->os & 0xff);
+ if (s->gzhead->extra != Z_NULL) {
+ put_byte(s, s->gzhead->extra_len & 0xff);
+ put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+ }
+ if (s->gzhead->hcrc)
+ strm->adler = crc32(strm->adler, s->pending_buf,
+ s->pending);
+ s->gzindex = 0;
+ s->status = EXTRA_STATE;
+ }
+ }
+ if (s->status == EXTRA_STATE) {
+ if (s->gzhead->extra != Z_NULL) {
+ ulg beg = s->pending; /* start of bytes to update crc */
+ uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
+ while (s->pending + left > s->pending_buf_size) {
+ uInt copy = s->pending_buf_size - s->pending;
+ zmemcpy(s->pending_buf + s->pending,
+ s->gzhead->extra + s->gzindex, copy);
+ s->pending = s->pending_buf_size;
+ HCRC_UPDATE(beg);
+ s->gzindex += copy;
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ beg = 0;
+ left -= copy;
+ }
+ zmemcpy(s->pending_buf + s->pending,
+ s->gzhead->extra + s->gzindex, left);
+ s->pending += left;
+ HCRC_UPDATE(beg);
+ s->gzindex = 0;
+ }
+ s->status = NAME_STATE;
+ }
+ if (s->status == NAME_STATE) {
+ if (s->gzhead->name != Z_NULL) {
+ ulg beg = s->pending; /* start of bytes to update crc */
+ int val;
+ do {
+ if (s->pending == s->pending_buf_size) {
+ HCRC_UPDATE(beg);
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ beg = 0;
+ }
+ val = s->gzhead->name[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ HCRC_UPDATE(beg);
+ s->gzindex = 0;
+ }
+ s->status = COMMENT_STATE;
+ }
+ if (s->status == COMMENT_STATE) {
+ if (s->gzhead->comment != Z_NULL) {
+ ulg beg = s->pending; /* start of bytes to update crc */
+ int val;
+ do {
+ if (s->pending == s->pending_buf_size) {
+ HCRC_UPDATE(beg);
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ beg = 0;
+ }
+ val = s->gzhead->comment[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ HCRC_UPDATE(beg);
+ }
+ s->status = HCRC_STATE;
+ }
+ if (s->status == HCRC_STATE) {
+ if (s->gzhead->hcrc) {
+ if (s->pending + 2 > s->pending_buf_size) {
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ }
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ strm->adler = crc32(0L, Z_NULL, 0);
+ }
+ s->status = BUSY_STATE;
+
+ /* Compression must start with an empty pending buffer */
+ flush_pending(strm);
+ if (s->pending != 0) {
+ s->last_flush = -1;
+ return Z_OK;
+ }
+ }
+#endif
+
+ /* Start a new block or continue the current one.
+ */
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+ block_state bstate;
+
+ bstate = s->level == 0 ? deflate_stored(s, flush) :
+ s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+ s->strategy == Z_RLE ? deflate_rle(s, flush) :
+ (*(configuration_table[s->level].func))(s, flush);
+
+ if (bstate == finish_started || bstate == finish_done) {
+ s->status = FINISH_STATE;
+ }
+ if (bstate == need_more || bstate == finish_started) {
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+ }
+ return Z_OK;
+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+ * of deflate should use the same flush parameter to make sure
+ * that the flush is complete. So we don't have to output an
+ * empty block here, this will be done at next call. This also
+ * ensures that for a very small output buffer, we emit at most
+ * one empty block.
+ */
+ }
+ if (bstate == block_done) {
+ if (flush == Z_PARTIAL_FLUSH) {
+ _tr_align(s);
+ } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
+ _tr_stored_block(s, (char*)0, 0L, 0);
+ /* For a full flush, this empty block will be recognized
+ * as a special marker by inflate_sync().
+ */
+ if (flush == Z_FULL_FLUSH) {
+ CLEAR_HASH(s); /* forget history */
+ if (s->lookahead == 0) {
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->insert = 0;
+ }
+ }
+ }
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+ return Z_OK;
+ }
+ }
+ }
+
+ if (flush != Z_FINISH) return Z_OK;
+ if (s->wrap <= 0) return Z_STREAM_END;
+
+ /* Write the trailer */
+#ifdef GZIP
+ if (s->wrap == 2) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+ put_byte(s, (Byte)(strm->total_in & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+ }
+ else
+#endif
+ {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ flush_pending(strm);
+ /* If avail_out is zero, the application will call deflate again
+ * to flush the rest.
+ */
+ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+ z_streamp strm;
+{
+ int status;
+
+ if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+
+ status = strm->state->status;
+
+ /* Deallocate in reverse order of allocations: */
+ TRY_FREE(strm, strm->state->pending_buf);
+ TRY_FREE(strm, strm->state->head);
+ TRY_FREE(strm, strm->state->prev);
+ TRY_FREE(strm, strm->state->window);
+
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+ z_streamp dest;
+ z_streamp source;
+{
+#ifdef MAXSEG_64K
+ return Z_STREAM_ERROR;
+#else
+ deflate_state *ds;
+ deflate_state *ss;
+ ushf *overlay;
+
+
+ if (deflateStateCheck(source) || dest == Z_NULL) {
+ return Z_STREAM_ERROR;
+ }
+
+ ss = source->state;
+
+ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+
+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+ if (ds == Z_NULL) return Z_MEM_ERROR;
+ dest->state = (struct internal_state FAR *) ds;
+ zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
+ ds->strm = dest;
+
+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+ ds->pending_buf = (uchf *) overlay;
+
+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+ ds->pending_buf == Z_NULL) {
+ deflateEnd (dest);
+ return Z_MEM_ERROR;
+ }
+ /* following zmemcpy do not work for 16-bit MSDOS */
+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+ zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+ ds->l_desc.dyn_tree = ds->dyn_ltree;
+ ds->d_desc.dyn_tree = ds->dyn_dtree;
+ ds->bl_desc.dyn_tree = ds->bl_tree;
+
+ return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read. All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local unsigned read_buf(strm, buf, size)
+ z_streamp strm;
+ Bytef *buf;
+ unsigned size;
+{
+ unsigned len = strm->avail_in;
+
+ if (len > size) len = size;
+ if (len == 0) return 0;
+
+ strm->avail_in -= len;
+
+ zmemcpy(buf, strm->next_in, len);
+ if (strm->state->wrap == 1) {
+ strm->adler = adler32(strm->adler, buf, len);
+ }
+#ifdef GZIP
+ else if (strm->state->wrap == 2) {
+ strm->adler = crc32(strm->adler, buf, len);
+ }
+#endif
+ strm->next_in += len;
+ strm->total_in += len;
+
+ return len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+ deflate_state *s;
+{
+ s->window_size = (ulg)2L*s->w_size;
+
+ CLEAR_HASH(s);
+
+ /* Set the default configuration parameters:
+ */
+ s->max_lazy_match = configuration_table[s->level].max_lazy;
+ s->good_match = configuration_table[s->level].good_length;
+ s->nice_match = configuration_table[s->level].nice_length;
+ s->max_chain_length = configuration_table[s->level].max_chain;
+
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->lookahead = 0;
+ s->insert = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+ match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = (int)s->prev_length; /* best match length so far */
+ int nice_match = s->nice_match; /* stop if match long enough */
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
+ /* Stop when cur_match becomes <= limit. To simplify the code,
+ * we prevent matches with the string of window index 0.
+ */
+ Posf *prev = s->prev;
+ uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+ /* Compare two bytes at a time. Note: this is not always beneficial.
+ * Try with and without -DUNALIGNED_OK to check.
+ */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
+#else
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
+#endif
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ /* Do not waste too much time if we already have a good match: */
+ if (s->prev_length >= s->good_match) {
+ chain_length >>= 2;
+ }
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead;
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ do {
+ Assert(cur_match < s->strstart, "no future");
+ match = s->window + cur_match;
+
+ /* Skip to next match if the match length cannot increase
+ * or if the match length is less than 2. Note that the checks below
+ * for insufficient lookahead only occur occasionally for performance
+ * reasons. Therefore uninitialized memory will be accessed, and
+ * conditional jumps will be made that depend on those values.
+ * However the length of the match is limited to the lookahead, so
+ * the output of deflate is not affected by the uninitialized values.
+ */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
+ * UNALIGNED_OK if your compiler uses a different size.
+ */
+ if (*(ushf*)(match+best_len-1) != scan_end ||
+ *(ushf*)match != scan_start) continue;
+
+ /* It is not necessary to compare scan[2] and match[2] since they are
+ * always equal when the other bytes match, given that the hash keys
+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
+ * lookahead only every 4th comparison; the 128th check will be made
+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+ * necessary to put more guard bytes at the end of the window, or
+ * to check more often for insufficient lookahead.
+ */
+ Assert(scan[2] == match[2], "scan[2]?");
+ scan++, match++;
+ do {
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ scan < strend);
+ /* The funny "do {}" generates better code on most compilers */
+
+ /* Here, scan <= window+strstart+257 */
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+ if (*scan == *match) scan++;
+
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
+ scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+ if (match[best_len] != scan_end ||
+ match[best_len-1] != scan_end1 ||
+ *match != *scan ||
+ *++match != scan[1]) continue;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match++;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+ scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+ if (len > best_len) {
+ s->match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+ scan_end = *(ushf*)(scan+best_len-1);
+#else
+ scan_end1 = scan[best_len-1];
+ scan_end = scan[best_len];
+#endif
+ }
+ } while ((cur_match = prev[cur_match & wmask]) > limit
+ && --chain_length != 0);
+
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+ return s->lookahead;
+}
+#endif /* ASMV */
+
+#else /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for FASTEST only
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ Assert(cur_match < s->strstart, "no future");
+
+ match = s->window + cur_match;
+
+ /* Return failure if the match length is less than 2:
+ */
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match += 2;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+ s->match_start = cur_match;
+ return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#endif /* FASTEST */
+
+#ifdef ZLIB_DEBUG
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+ deflate_state *s;
+ IPos start, match;
+ int length;
+{
+ /* check that the match is indeed a match */
+ if (zmemcmp(s->window + match,
+ s->window + start, length) != EQUAL) {
+ fprintf(stderr, " start %u, match %u, length %d\n",
+ start, match, length);
+ do {
+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+ } while (--length != 0);
+ z_error("invalid match");
+ }
+ if (z_verbose > 1) {
+ fprintf(stderr,"\\[%d,%d]", start-match, length);
+ do { putc(s->window[start++], stderr); } while (--length != 0);
+ }
+}
+#else
+# define check_match(s, start, match, length)
+#endif /* ZLIB_DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ * At least one byte has been read, or avail_in == 0; reads are
+ * performed for at least two bytes (required for the zip translate_eol
+ * option -- not supported here).
+ */
+local void fill_window(s)
+ deflate_state *s;
+{
+ unsigned n;
+ unsigned more; /* Amount of free space at the end of the window. */
+ uInt wsize = s->w_size;
+
+ Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
+ do {
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+ /* Deal with !@#$% 64K limit: */
+ if (sizeof(int) <= 2) {
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+ more = wsize;
+
+ } else if (more == (unsigned)(-1)) {
+ /* Very unlikely, but possible on 16 bit machine if
+ * strstart == 0 && lookahead == 1 (input done a byte at time)
+ */
+ more--;
+ }
+ }
+
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ if (s->strstart >= wsize+MAX_DIST(s)) {
+
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more);
+ s->match_start -= wsize;
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
+ s->block_start -= (long) wsize;
+ slide_hash(s);
+ more += wsize;
+ }
+ if (s->strm->avail_in == 0) break;
+
+ /* If there was no sliding:
+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ * more == window_size - lookahead - strstart
+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ * => more >= window_size - 2*WSIZE + 2
+ * In the BIG_MEM or MMAP case (not yet supported),
+ * window_size == input_size + MIN_LOOKAHEAD &&
+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ * Otherwise, window_size == 2*WSIZE so more >= 2.
+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+ */
+ Assert(more >= 2, "more < 2");
+
+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+ s->lookahead += n;
+
+ /* Initialize the hash value now that we have some input: */
+ if (s->lookahead + s->insert >= MIN_MATCH) {
+ uInt str = s->strstart - s->insert;
+ s->ins_h = s->window[str];
+ UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ while (s->insert) {
+ UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+ s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+ s->head[s->ins_h] = (Pos)str;
+ str++;
+ s->insert--;
+ if (s->lookahead + s->insert < MIN_MATCH)
+ break;
+ }
+ }
+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+ * but this is not important since only literal bytes will be emitted.
+ */
+
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+ /* If the WIN_INIT bytes after the end of the current data have never been
+ * written, then zero those bytes in order to avoid memory check reports of
+ * the use of uninitialized (or uninitialised as Julian writes) bytes by
+ * the longest match routines. Update the high water mark for the next
+ * time through here. WIN_INIT is set to MAX_MATCH since the longest match
+ * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+ */
+ if (s->high_water < s->window_size) {
+ ulg curr = s->strstart + (ulg)(s->lookahead);
+ ulg init;
+
+ if (s->high_water < curr) {
+ /* Previous high water mark below current data -- zero WIN_INIT
+ * bytes or up to end of window, whichever is less.
+ */
+ init = s->window_size - curr;
+ if (init > WIN_INIT)
+ init = WIN_INIT;
+ zmemzero(s->window + curr, (unsigned)init);
+ s->high_water = curr + init;
+ }
+ else if (s->high_water < (ulg)curr + WIN_INIT) {
+ /* High water mark at or above current data, but below current data
+ * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+ * to end of window, whichever is less.
+ */
+ init = (ulg)curr + WIN_INIT - s->high_water;
+ if (init > s->window_size - s->high_water)
+ init = s->window_size - s->high_water;
+ zmemzero(s->window + s->high_water, (unsigned)init);
+ s->high_water += init;
+ }
+ }
+
+ Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+ "not enough room for search");
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, last) { \
+ _tr_flush_block(s, (s->block_start >= 0L ? \
+ (charf *)&s->window[(unsigned)s->block_start] : \
+ (charf *)Z_NULL), \
+ (ulg)((long)s->strstart - s->block_start), \
+ (last)); \
+ s->block_start = s->strstart; \
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, last) { \
+ FLUSH_BLOCK_ONLY(s, last); \
+ if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
+}
+
+/* Maximum stored block length in deflate format (not including header). */
+#define MAX_STORED 65535
+
+/* Minimum of a and b. */
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ *
+ * In case deflateParams() is used to later switch to a non-zero compression
+ * level, s->matches (otherwise unused when storing) keeps track of the number
+ * of hash table slides to perform. If s->matches is 1, then one hash table
+ * slide will be done when switching. If s->matches is 2, the maximum value
+ * allowed here, then the hash table will be cleared, since two or more slides
+ * is the same as a clear.
+ *
+ * deflate_stored() is written to minimize the number of times an input byte is
+ * copied. It is most efficient with large input and output buffers, which
+ * maximizes the opportunites to have a single copy from next_in to next_out.
+ */
+local block_state deflate_stored(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ /* Smallest worthy block size when not flushing or finishing. By default
+ * this is 32K. This can be as small as 507 bytes for memLevel == 1. For
+ * large input and output buffers, the stored block size will be larger.
+ */
+ unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size);
+
+ /* Copy as many min_block or larger stored blocks directly to next_out as
+ * possible. If flushing, copy the remaining available input to next_out as
+ * stored blocks, if there is enough space.
+ */
+ unsigned len, left, have, last = 0;
+ unsigned used = s->strm->avail_in;
+ do {
+ /* Set len to the maximum size block that we can copy directly with the
+ * available input data and output space. Set left to how much of that
+ * would be copied from what's left in the window.
+ */
+ len = MAX_STORED; /* maximum deflate stored block length */
+ have = (s->bi_valid + 42) >> 3; /* number of header bytes */
+ if (s->strm->avail_out < have) /* need room for header */
+ break;
+ /* maximum stored block length that will fit in avail_out: */
+ have = s->strm->avail_out - have;
+ left = s->strstart - s->block_start; /* bytes left in window */
+ if (len > (ulg)left + s->strm->avail_in)
+ len = left + s->strm->avail_in; /* limit len to the input */
+ if (len > have)
+ len = have; /* limit len to the output */
+
+ /* If the stored block would be less than min_block in length, or if
+ * unable to copy all of the available input when flushing, then try
+ * copying to the window and the pending buffer instead. Also don't
+ * write an empty block when flushing -- deflate() does that.
+ */
+ if (len < min_block && ((len == 0 && flush != Z_FINISH) ||
+ flush == Z_NO_FLUSH ||
+ len != left + s->strm->avail_in))
+ break;
+
+ /* Make a dummy stored block in pending to get the header bytes,
+ * including any pending bits. This also updates the debugging counts.
+ */
+ last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;
+ _tr_stored_block(s, (char *)0, 0L, last);
+
+ /* Replace the lengths in the dummy stored block with len. */
+ s->pending_buf[s->pending - 4] = len;
+ s->pending_buf[s->pending - 3] = len >> 8;
+ s->pending_buf[s->pending - 2] = ~len;
+ s->pending_buf[s->pending - 1] = ~len >> 8;
+
+ /* Write the stored block header bytes. */
+ flush_pending(s->strm);
+
+#ifdef ZLIB_DEBUG
+ /* Update debugging counts for the data about to be copied. */
+ s->compressed_len += len << 3;
+ s->bits_sent += len << 3;
+#endif
+
+ /* Copy uncompressed bytes from the window to next_out. */
+ if (left) {
+ if (left > len)
+ left = len;
+ zmemcpy(s->strm->next_out, s->window + s->block_start, left);
+ s->strm->next_out += left;
+ s->strm->avail_out -= left;
+ s->strm->total_out += left;
+ s->block_start += left;
+ len -= left;
+ }
+
+ /* Copy uncompressed bytes directly from next_in to next_out, updating
+ * the check value.
+ */
+ if (len) {
+ read_buf(s->strm, s->strm->next_out, len);
+ s->strm->next_out += len;
+ s->strm->avail_out -= len;
+ s->strm->total_out += len;
+ }
+ } while (last == 0);
+
+ /* Update the sliding window with the last s->w_size bytes of the copied
+ * data, or append all of the copied data to the existing window if less
+ * than s->w_size bytes were copied. Also update the number of bytes to
+ * insert in the hash tables, in the event that deflateParams() switches to
+ * a non-zero compression level.
+ */
+ used -= s->strm->avail_in; /* number of input bytes directly copied */
+ if (used) {
+ /* If any input was used, then no unused input remains in the window,
+ * therefore s->block_start == s->strstart.
+ */
+ if (used >= s->w_size) { /* supplant the previous history */
+ s->matches = 2; /* clear hash */
+ zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);
+ s->strstart = s->w_size;
+ }
+ else {
+ if (s->window_size - s->strstart <= used) {
+ /* Slide the window down. */
+ s->strstart -= s->w_size;
+ zmemcpy(s->window, s->window + s->w_size, s->strstart);
+ if (s->matches < 2)
+ s->matches++; /* add a pending slide_hash() */
+ }
+ zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);
+ s->strstart += used;
+ }
+ s->block_start = s->strstart;
+ s->insert += MIN(used, s->w_size - s->insert);
+ }
+ if (s->high_water < s->strstart)
+ s->high_water = s->strstart;
+
+ /* If the last block was written to next_out, then done. */
+ if (last)
+ return finish_done;
+
+ /* If flushing and all input has been consumed, then done. */
+ if (flush != Z_NO_FLUSH && flush != Z_FINISH &&
+ s->strm->avail_in == 0 && (long)s->strstart == s->block_start)
+ return block_done;
+
+ /* Fill the window with any remaining input. */
+ have = s->window_size - s->strstart - 1;
+ if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {
+ /* Slide the window down. */
+ s->block_start -= s->w_size;
+ s->strstart -= s->w_size;
+ zmemcpy(s->window, s->window + s->w_size, s->strstart);
+ if (s->matches < 2)
+ s->matches++; /* add a pending slide_hash() */
+ have += s->w_size; /* more space now */
+ }
+ if (have > s->strm->avail_in)
+ have = s->strm->avail_in;
+ if (have) {
+ read_buf(s->strm, s->window + s->strstart, have);
+ s->strstart += have;
+ }
+ if (s->high_water < s->strstart)
+ s->high_water = s->strstart;
+
+ /* There was not enough avail_out to write a complete worthy or flushed
+ * stored block to next_out. Write a stored block to pending instead, if we
+ * have enough input for a worthy block, or if flushing and there is enough
+ * room for the remaining input as a stored block in the pending buffer.
+ */
+ have = (s->bi_valid + 42) >> 3; /* number of header bytes */
+ /* maximum stored block length that will fit in pending: */
+ have = MIN(s->pending_buf_size - have, MAX_STORED);
+ min_block = MIN(have, s->w_size);
+ left = s->strstart - s->block_start;
+ if (left >= min_block ||
+ ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH &&
+ s->strm->avail_in == 0 && left <= have)) {
+ len = MIN(left, have);
+ last = flush == Z_FINISH && s->strm->avail_in == 0 &&
+ len == left ? 1 : 0;
+ _tr_stored_block(s, (charf *)s->window + s->block_start, len, last);
+ s->block_start += len;
+ flush_pending(s->strm);
+ }
+
+ /* We've done all we can with the available input and output. */
+ return last ? finish_started : need_more;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head; /* head of the hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ hash_head = NIL;
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ * At this point we have always match_length < MIN_MATCH
+ */
+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ s->match_length = longest_match (s, hash_head);
+ /* longest_match() sets match_start */
+ }
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->match_start, s->match_length);
+
+ _tr_tally_dist(s, s->strstart - s->match_start,
+ s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+#ifndef FASTEST
+ if (s->match_length <= s->max_insert_length &&
+ s->lookahead >= MIN_MATCH) {
+ s->match_length--; /* string at strstart already in table */
+ do {
+ s->strstart++;
+ INSERT_STRING(s, s->strstart, hash_head);
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+ * always MIN_MATCH bytes ahead.
+ */
+ } while (--s->match_length != 0);
+ s->strstart++;
+ } else
+#endif
+ {
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+ * matter since it will be recomputed at next deflate call.
+ */
+ }
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head; /* head of hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ /* Process the input block. */
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ hash_head = NIL;
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ */
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
+ s->match_length = MIN_MATCH-1;
+
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ s->match_length = longest_match (s, hash_head);
+ /* longest_match() sets match_start */
+
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+ || (s->match_length == MIN_MATCH &&
+ s->strstart - s->match_start > TOO_FAR)
+#endif
+ )) {
+
+ /* If prev_match is also MIN_MATCH, match_start is garbage
+ * but we will ignore the current match anyway.
+ */
+ s->match_length = MIN_MATCH-1;
+ }
+ }
+ /* If there was a match at the previous step and the current
+ * match is not better, output the previous match:
+ */
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+ /* Do not insert strings in hash table beyond this. */
+
+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+ s->prev_length - MIN_MATCH, bflush);
+
+ /* Insert in hash table all strings up to the end of the match.
+ * strstart-1 and strstart are already inserted. If there is not
+ * enough lookahead, the last two strings are not inserted in
+ * the hash table.
+ */
+ s->lookahead -= s->prev_length-1;
+ s->prev_length -= 2;
+ do {
+ if (++s->strstart <= max_insert) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+ } while (--s->prev_length != 0);
+ s->match_available = 0;
+ s->match_length = MIN_MATCH-1;
+ s->strstart++;
+
+ if (bflush) FLUSH_BLOCK(s, 0);
+
+ } else if (s->match_available) {
+ /* If there was no match at the previous position, output a
+ * single literal. If there was a match but the current match
+ * is longer, truncate the previous match to a single literal.
+ */
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ if (bflush) {
+ FLUSH_BLOCK_ONLY(s, 0);
+ }
+ s->strstart++;
+ s->lookahead--;
+ if (s->strm->avail_out == 0) return need_more;
+ } else {
+ /* There is no previous match to compare with, wait for
+ * the next step to decide.
+ */
+ s->match_available = 1;
+ s->strstart++;
+ s->lookahead--;
+ }
+ }
+ Assert (flush != Z_NO_FLUSH, "no flush?");
+ if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ s->match_available = 0;
+ }
+ s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
+#endif /* FASTEST */
+
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one. Do not maintain a hash table. (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+ uInt prev; /* byte at distance one to match */
+ Bytef *scan, *strend; /* scan goes up to strend for length of run */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the longest run, plus one for the unrolled loop.
+ */
+ if (s->lookahead <= MAX_MATCH) {
+ fill_window(s);
+ if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* See how many times the previous byte repeats */
+ s->match_length = 0;
+ if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
+ scan = s->window + s->strstart - 1;
+ prev = *scan;
+ if (prev == *++scan && prev == *++scan && prev == *++scan) {
+ strend = s->window + s->strstart + MAX_MATCH;
+ do {
+ } while (prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ prev == *++scan && prev == *++scan &&
+ scan < strend);
+ s->match_length = MAX_MATCH - (uInt)(strend - scan);
+ if (s->match_length > s->lookahead)
+ s->match_length = s->lookahead;
+ }
+ Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
+ }
+
+ /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->strstart - 1, s->match_length);
+
+ _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+local block_state deflate_huff(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we have a literal to write. */
+ if (s->lookahead == 0) {
+ fill_window(s);
+ if (s->lookahead == 0) {
+ if (flush == Z_NO_FLUSH)
+ return need_more;
+ break; /* flush the current block */
+ }
+ }
+
+ /* Output a literal byte */
+ s->match_length = 0;
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ s->insert = 0;
+ if (flush == Z_FINISH) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (s->last_lit)
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}
diff --git a/xs/src/png/zlib/deflate.h b/xs/src/png/zlib/deflate.h
new file mode 100644
index 000000000..23ecdd312
--- /dev/null
+++ b/xs/src/png/zlib/deflate.h
@@ -0,0 +1,349 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2016 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer creation by deflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip encoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS 256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES 30
+/* number of distance codes */
+
+#define BL_CODES 19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define Buf_size 16
+/* size of bit buffer in bi_buf */
+
+#define INIT_STATE 42 /* zlib header -> BUSY_STATE */
+#ifdef GZIP
+# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */
+#endif
+#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */
+#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */
+#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */
+#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */
+#define BUSY_STATE 113 /* deflate -> FINISH_STATE */
+#define FINISH_STATE 666 /* stream complete */
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+ union {
+ ush freq; /* frequency count */
+ ush code; /* bit string */
+ } fc;
+ union {
+ ush dad; /* father node in Huffman tree */
+ ush len; /* length of bit string */
+ } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad dl.dad
+#define Len dl.len
+
+typedef struct static_tree_desc_s static_tree_desc;
+
+typedef struct tree_desc_s {
+ ct_data *dyn_tree; /* the dynamic tree */
+ int max_code; /* largest code with non zero frequency */
+ const static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ int status; /* as the name implies */
+ Bytef *pending_buf; /* output still pending */
+ ulg pending_buf_size; /* size of pending_buf */
+ Bytef *pending_out; /* next pending byte to output to the stream */
+ ulg pending; /* nb of bytes in the pending buffer */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ gz_headerp gzhead; /* gzip header information to write */
+ ulg gzindex; /* where in extra, name, or comment */
+ Byte method; /* can only be DEFLATED */
+ int last_flush; /* value of flush param for previous deflate call */
+
+ /* used by deflate.c: */
+
+ uInt w_size; /* LZ77 window size (32K by default) */
+ uInt w_bits; /* log2(w_size) (8..16) */
+ uInt w_mask; /* w_size - 1 */
+
+ Bytef *window;
+ /* Sliding window. Input bytes are read into the second half of the window,
+ * and move to the first half later to keep a dictionary of at least wSize
+ * bytes. With this organization, matches are limited to a distance of
+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
+ * performed with a length multiple of the block size. Also, it limits
+ * the window size to 64K, which is quite useful on MSDOS.
+ * To do: use the user input buffer as sliding window.
+ */
+
+ ulg window_size;
+ /* Actual size of window: 2*wSize, except when the user input buffer
+ * is directly used as sliding window.
+ */
+
+ Posf *prev;
+ /* Link to older string with same hash index. To limit the size of this
+ * array to 64K, this link is maintained only for the last 32K strings.
+ * An index in this array is thus a window index modulo 32K.
+ */
+
+ Posf *head; /* Heads of the hash chains or NIL. */
+
+ uInt ins_h; /* hash index of string to be inserted */
+ uInt hash_size; /* number of elements in hash table */
+ uInt hash_bits; /* log2(hash_size) */
+ uInt hash_mask; /* hash_size-1 */
+
+ uInt hash_shift;
+ /* Number of bits by which ins_h must be shifted at each input
+ * step. It must be such that after MIN_MATCH steps, the oldest
+ * byte no longer takes part in the hash key, that is:
+ * hash_shift * MIN_MATCH >= hash_bits
+ */
+
+ long block_start;
+ /* Window position at the beginning of the current output block. Gets
+ * negative when the window is moved backwards.
+ */
+
+ uInt match_length; /* length of best match */
+ IPos prev_match; /* previous match */
+ int match_available; /* set if previous match exists */
+ uInt strstart; /* start of string to insert */
+ uInt match_start; /* start of matching string */
+ uInt lookahead; /* number of valid bytes ahead in window */
+
+ uInt prev_length;
+ /* Length of the best match at previous step. Matches not greater than this
+ * are discarded. This is used in the lazy match evaluation.
+ */
+
+ uInt max_chain_length;
+ /* To speed up deflation, hash chains are never searched beyond this
+ * length. A higher limit improves compression ratio but degrades the
+ * speed.
+ */
+
+ uInt max_lazy_match;
+ /* Attempt to find a better match only when the current match is strictly
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
+ */
+# define max_insert_length max_lazy_match
+ /* Insert new strings in the hash table only if the match length is not
+ * greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+ int level; /* compression level (1..9) */
+ int strategy; /* favor or force Huffman coding*/
+
+ uInt good_match;
+ /* Use a faster search when the previous match is longer than this */
+
+ int nice_match; /* Stop searching when current match exceeds this */
+
+ /* used by trees.c: */
+ /* Didn't use ct_data typedef below to suppress compiler warning */
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
+
+ struct tree_desc_s l_desc; /* desc. for literal tree */
+ struct tree_desc_s d_desc; /* desc. for distance tree */
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
+
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+ int heap_len; /* number of elements in the heap */
+ int heap_max; /* element of largest frequency */
+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ * The same heap array is used to build all trees.
+ */
+
+ uch depth[2*L_CODES+1];
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
+ */
+
+ uchf *l_buf; /* buffer for literals or lengths */
+
+ uInt lit_bufsize;
+ /* Size of match buffer for literals/lengths. There are 4 reasons for
+ * limiting lit_bufsize to 64K:
+ * - frequencies can be kept in 16 bit counters
+ * - if compression is not successful for the first block, all input
+ * data is still in the window so we can still emit a stored block even
+ * when input comes from standard input. (This can also be done for
+ * all blocks if lit_bufsize is not greater than 32K.)
+ * - if compression is not successful for a file smaller than 64K, we can
+ * even emit a stored file instead of a stored block (saving 5 bytes).
+ * This is applicable only for zip (not gzip or zlib).
+ * - creating new Huffman trees less frequently may not provide fast
+ * adaptation to changes in the input data statistics. (Take for
+ * example a binary file with poorly compressible code followed by
+ * a highly compressible string table.) Smaller buffer sizes give
+ * fast adaptation but have of course the overhead of transmitting
+ * trees more frequently.
+ * - I can't count above 4
+ */
+
+ uInt last_lit; /* running index in l_buf */
+
+ ushf *d_buf;
+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
+ * the same number of elements. To use different lengths, an extra flag
+ * array would be necessary.
+ */
+
+ ulg opt_len; /* bit length of current block with optimal trees */
+ ulg static_len; /* bit length of current block with static trees */
+ uInt matches; /* number of string matches in current block */
+ uInt insert; /* bytes at end of window left to insert */
+
+#ifdef ZLIB_DEBUG
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
+#endif
+
+ ush bi_buf;
+ /* Output buffer. bits are inserted starting at the bottom (least
+ * significant bits).
+ */
+ int bi_valid;
+ /* Number of valid bits in bi_buf. All bits above the last valid bit
+ * are always zero.
+ */
+
+ ulg high_water;
+ /* High water mark offset in window for initialized bytes -- bytes above
+ * this are set to zero in order to avoid memory check warnings when
+ * longest match routines access bytes past the input. This is then
+ * updated to the new high water mark.
+ */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+#define WIN_INIT MAX_MATCH
+/* Number of bytes after end of data in window to initialize in order to avoid
+ memory checker errors from longest match routines */
+
+ /* in trees.c */
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+ ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+ ulg stored_len, int last));
+
+#define d_code(dist) \
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef ZLIB_DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+ extern uch ZLIB_INTERNAL _length_code[];
+ extern uch ZLIB_INTERNAL _dist_code[];
+#else
+ extern const uch ZLIB_INTERNAL _length_code[];
+ extern const uch ZLIB_INTERNAL _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+ { uch cc = (c); \
+ s->d_buf[s->last_lit] = 0; \
+ s->l_buf[s->last_lit++] = cc; \
+ s->dyn_ltree[cc].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (uch)(length); \
+ ush dist = (ush)(distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+ flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/xs/src/png/zlib/gzclose.c b/xs/src/png/zlib/gzclose.c
new file mode 100644
index 000000000..caeb99a31
--- /dev/null
+++ b/xs/src/png/zlib/gzclose.c
@@ -0,0 +1,25 @@
+/* gzclose.c -- zlib gzclose() function
+ * Copyright (C) 2004, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* gzclose() is in a separate file so that it is linked in only if it is used.
+ That way the other gzclose functions can be used instead to avoid linking in
+ unneeded compression or decompression routines. */
+int ZEXPORT gzclose(file)
+ gzFile file;
+{
+#ifndef NO_GZCOMPRESS
+ gz_statep state;
+
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
+#else
+ return gzclose_r(file);
+#endif
+}
diff --git a/xs/src/png/zlib/gzguts.h b/xs/src/png/zlib/gzguts.h
new file mode 100644
index 000000000..990a4d251
--- /dev/null
+++ b/xs/src/png/zlib/gzguts.h
@@ -0,0 +1,218 @@
+/* gzguts.h -- zlib internal header definitions for gz* operations
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifdef _LARGEFILE64_SOURCE
+# ifndef _LARGEFILE_SOURCE
+# define _LARGEFILE_SOURCE 1
+# endif
+# ifdef _FILE_OFFSET_BITS
+# undef _FILE_OFFSET_BITS
+# endif
+#endif
+
+#ifdef HAVE_HIDDEN
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
+#include <stdio.h>
+#include "zlib.h"
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+# include <limits.h>
+#endif
+
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
+#include <fcntl.h>
+
+#ifdef _WIN32
+# include <stddef.h>
+#endif
+
+#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
+# include <io.h>
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+# define WIDECHAR
+#endif
+
+#ifdef WINAPI_FAMILY
+# define open _open
+# define read _read
+# define write _write
+# define close _close
+#endif
+
+#ifdef NO_DEFLATE /* for compatibility with old definition */
+# define NO_GZCOMPRESS
+#endif
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(__CYGWIN__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+
+#ifndef HAVE_VSNPRINTF
+# ifdef MSDOS
+/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+ but for now we just assume it doesn't. */
+# define NO_vsnprintf
+# endif
+# ifdef __TURBOC__
+# define NO_vsnprintf
+# endif
+# ifdef WIN32
+/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)
+# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+# define vsnprintf _vsnprintf
+# endif
+# endif
+# endif
+# ifdef __SASC
+# define NO_vsnprintf
+# endif
+# ifdef VMS
+# define NO_vsnprintf
+# endif
+# ifdef __OS400__
+# define NO_vsnprintf
+# endif
+# ifdef __MVS__
+# define NO_vsnprintf
+# endif
+#endif
+
+/* unlike snprintf (which is required in C99), _snprintf does not guarantee
+ null termination of the result -- however this is only used in gzlib.c where
+ the result is assured to fit in the space provided */
+#if defined(_MSC_VER) && _MSC_VER < 1900
+# define snprintf _snprintf
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* since "static" is used to mean two completely different things in C, we
+ define "local" for the non-static meaning of "static", for readability
+ (compile with -Dlocal if your debugger can't find static symbols) */
+
+/* gz* functions always use library allocation functions */
+#ifndef STDC
+ extern voidp malloc OF((uInt size));
+ extern void free OF((voidpf ptr));
+#endif
+
+/* get errno and strerror definition */
+#if defined UNDER_CE
+# include <windows.h>
+# define zstrerror() gz_strwinerror((DWORD)GetLastError())
+#else
+# ifndef NO_STRERROR
+# include <errno.h>
+# define zstrerror() strerror(errno)
+# else
+# define zstrerror() "stdio error (consult errno)"
+# endif
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+#endif
+
+/* default memLevel */
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+
+/* default i/o buffer size -- double this for output when reading (this and
+ twice this must be able to fit in an unsigned type) */
+#define GZBUFSIZE 8192
+
+/* gzip modes, also provide a little integrity check on the passed structure */
+#define GZ_NONE 0
+#define GZ_READ 7247
+#define GZ_WRITE 31153
+#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */
+
+/* values for gz_state how */
+#define LOOK 0 /* look for a gzip header */
+#define COPY 1 /* copy input directly */
+#define GZIP 2 /* decompress a gzip stream */
+
+/* internal gzip file state data structure */
+typedef struct {
+ /* exposed contents for gzgetc() macro */
+ struct gzFile_s x; /* "x" for exposed */
+ /* x.have: number of bytes available at x.next */
+ /* x.next: next output data to deliver or write */
+ /* x.pos: current position in uncompressed data */
+ /* used for both reading and writing */
+ int mode; /* see gzip modes above */
+ int fd; /* file descriptor */
+ char *path; /* path or fd for error messages */
+ unsigned size; /* buffer size, zero if not allocated yet */
+ unsigned want; /* requested buffer size, default is GZBUFSIZE */
+ unsigned char *in; /* input buffer (double-sized when writing) */
+ unsigned char *out; /* output buffer (double-sized when reading) */
+ int direct; /* 0 if processing gzip, 1 if transparent */
+ /* just for reading */
+ int how; /* 0: get header, 1: copy, 2: decompress */
+ z_off64_t start; /* where the gzip data started, for rewinding */
+ int eof; /* true if end of input file reached */
+ int past; /* true if read requested past end */
+ /* just for writing */
+ int level; /* compression level */
+ int strategy; /* compression strategy */
+ /* seek request */
+ z_off64_t skip; /* amount to skip (already rewound if backwards) */
+ int seek; /* true if seek request pending */
+ /* error information */
+ int err; /* error code */
+ char *msg; /* error message */
+ /* zlib inflate or deflate stream */
+ z_stream strm; /* stream structure in-place (not a pointer) */
+} gz_state;
+typedef gz_state FAR *gz_statep;
+
+/* shared functions */
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+#if defined UNDER_CE
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+#endif
+
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
+ value -- needed when comparing unsigned to z_off64_t, which is signed
+ (possible z_off64_t types off_t, off64_t, and long are all signed) */
+#ifdef INT_MAX
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
+#else
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
+# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+#endif
diff --git a/xs/src/png/zlib/gzlib.c b/xs/src/png/zlib/gzlib.c
new file mode 100644
index 000000000..4105e6aff
--- /dev/null
+++ b/xs/src/png/zlib/gzlib.c
@@ -0,0 +1,637 @@
+/* gzlib.c -- zlib functions common to reading and writing gzip files
+ * Copyright (C) 2004-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__)
+# define LSEEK _lseeki64
+#else
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+# define LSEEK lseek64
+#else
+# define LSEEK lseek
+#endif
+#endif
+
+/* Local functions */
+local void gz_reset OF((gz_statep));
+local gzFile gz_open OF((const void *, int, const char *));
+
+#if defined UNDER_CE
+
+/* Map the Windows error number in ERROR to a locale-dependent error message
+ string and return a pointer to it. Typically, the values for ERROR come
+ from GetLastError.
+
+ The string pointed to shall not be modified by the application, but may be
+ overwritten by a subsequent call to gz_strwinerror
+
+ The gz_strwinerror function does not change the current setting of
+ GetLastError. */
+char ZLIB_INTERNAL *gz_strwinerror (error)
+ DWORD error;
+{
+ static char buf[1024];
+
+ wchar_t *msgbuf;
+ DWORD lasterr = GetLastError();
+ DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL,
+ error,
+ 0, /* Default language */
+ (LPVOID)&msgbuf,
+ 0,
+ NULL);
+ if (chars != 0) {
+ /* If there is an \r\n appended, zap it. */
+ if (chars >= 2
+ && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+ chars -= 2;
+ msgbuf[chars] = 0;
+ }
+
+ if (chars > sizeof (buf) - 1) {
+ chars = sizeof (buf) - 1;
+ msgbuf[chars] = 0;
+ }
+
+ wcstombs(buf, msgbuf, chars + 1);
+ LocalFree(msgbuf);
+ }
+ else {
+ sprintf(buf, "unknown win32 error (%ld)", error);
+ }
+
+ SetLastError(lasterr);
+ return buf;
+}
+
+#endif /* UNDER_CE */
+
+/* Reset gzip file state */
+local void gz_reset(state)
+ gz_statep state;
+{
+ state->x.have = 0; /* no output data available */
+ if (state->mode == GZ_READ) { /* for reading ... */
+ state->eof = 0; /* not at end of file */
+ state->past = 0; /* have not read past end yet */
+ state->how = LOOK; /* look for gzip header */
+ }
+ state->seek = 0; /* no seek request pending */
+ gz_error(state, Z_OK, NULL); /* clear error */
+ state->x.pos = 0; /* no uncompressed data yet */
+ state->strm.avail_in = 0; /* no input data yet */
+}
+
+/* Open a gzip file either by name or file descriptor. */
+local gzFile gz_open(path, fd, mode)
+ const void *path;
+ int fd;
+ const char *mode;
+{
+ gz_statep state;
+ z_size_t len;
+ int oflag;
+#ifdef O_CLOEXEC
+ int cloexec = 0;
+#endif
+#ifdef O_EXCL
+ int exclusive = 0;
+#endif
+
+ /* check input */
+ if (path == NULL)
+ return NULL;
+
+ /* allocate gzFile structure to return */
+ state = (gz_statep)malloc(sizeof(gz_state));
+ if (state == NULL)
+ return NULL;
+ state->size = 0; /* no buffers allocated yet */
+ state->want = GZBUFSIZE; /* requested buffer size */
+ state->msg = NULL; /* no error message yet */
+
+ /* interpret mode */
+ state->mode = GZ_NONE;
+ state->level = Z_DEFAULT_COMPRESSION;
+ state->strategy = Z_DEFAULT_STRATEGY;
+ state->direct = 0;
+ while (*mode) {
+ if (*mode >= '0' && *mode <= '9')
+ state->level = *mode - '0';
+ else
+ switch (*mode) {
+ case 'r':
+ state->mode = GZ_READ;
+ break;
+#ifndef NO_GZCOMPRESS
+ case 'w':
+ state->mode = GZ_WRITE;
+ break;
+ case 'a':
+ state->mode = GZ_APPEND;
+ break;
+#endif
+ case '+': /* can't read and write at the same time */
+ free(state);
+ return NULL;
+ case 'b': /* ignore -- will request binary anyway */
+ break;
+#ifdef O_CLOEXEC
+ case 'e':
+ cloexec = 1;
+ break;
+#endif
+#ifdef O_EXCL
+ case 'x':
+ exclusive = 1;
+ break;
+#endif
+ case 'f':
+ state->strategy = Z_FILTERED;
+ break;
+ case 'h':
+ state->strategy = Z_HUFFMAN_ONLY;
+ break;
+ case 'R':
+ state->strategy = Z_RLE;
+ break;
+ case 'F':
+ state->strategy = Z_FIXED;
+ break;
+ case 'T':
+ state->direct = 1;
+ break;
+ default: /* could consider as an error, but just ignore */
+ ;
+ }
+ mode++;
+ }
+
+ /* must provide an "r", "w", or "a" */
+ if (state->mode == GZ_NONE) {
+ free(state);
+ return NULL;
+ }
+
+ /* can't force transparent read */
+ if (state->mode == GZ_READ) {
+ if (state->direct) {
+ free(state);
+ return NULL;
+ }
+ state->direct = 1; /* for empty file */
+ }
+
+ /* save the path name for error messages */
+#ifdef WIDECHAR
+ if (fd == -2) {
+ len = wcstombs(NULL, path, 0);
+ if (len == (z_size_t)-1)
+ len = 0;
+ }
+ else
+#endif
+ len = strlen((const char *)path);
+ state->path = (char *)malloc(len + 1);
+ if (state->path == NULL) {
+ free(state);
+ return NULL;
+ }
+#ifdef WIDECHAR
+ if (fd == -2)
+ if (len)
+ wcstombs(state->path, path, len + 1);
+ else
+ *(state->path) = 0;
+ else
+#endif
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ (void)snprintf(state->path, len + 1, "%s", (const char *)path);
+#else
+ strcpy(state->path, path);
+#endif
+
+ /* compute the flags for open() */
+ oflag =
+#ifdef O_LARGEFILE
+ O_LARGEFILE |
+#endif
+#ifdef O_BINARY
+ O_BINARY |
+#endif
+#ifdef O_CLOEXEC
+ (cloexec ? O_CLOEXEC : 0) |
+#endif
+ (state->mode == GZ_READ ?
+ O_RDONLY :
+ (O_WRONLY | O_CREAT |
+#ifdef O_EXCL
+ (exclusive ? O_EXCL : 0) |
+#endif
+ (state->mode == GZ_WRITE ?
+ O_TRUNC :
+ O_APPEND)));
+
+ /* open the file with the appropriate flags (or just use fd) */
+ state->fd = fd > -1 ? fd : (
+#ifdef WIDECHAR
+ fd == -2 ? _wopen(path, oflag, 0666) :
+#endif
+ open((const char *)path, oflag, 0666));
+ if (state->fd == -1) {
+ free(state->path);
+ free(state);
+ return NULL;
+ }
+ if (state->mode == GZ_APPEND) {
+ LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */
+ state->mode = GZ_WRITE; /* simplify later checks */
+ }
+
+ /* save the current position for rewinding (only if reading) */
+ if (state->mode == GZ_READ) {
+ state->start = LSEEK(state->fd, 0, SEEK_CUR);
+ if (state->start == -1) state->start = 0;
+ }
+
+ /* initialize stream */
+ gz_reset(state);
+
+ /* return stream */
+ return (gzFile)state;
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen(path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen64(path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzdopen(fd, mode)
+ int fd;
+ const char *mode;
+{
+ char *path; /* identifier for error messages */
+ gzFile gz;
+
+ if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
+ return NULL;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
+#else
+ sprintf(path, "<fd:%d>", fd); /* for debugging */
+#endif
+ gz = gz_open(path, fd, mode);
+ free(path);
+ return gz;
+}
+
+/* -- see zlib.h -- */
+#ifdef WIDECHAR
+gzFile ZEXPORT gzopen_w(path, mode)
+ const wchar_t *path;
+ const char *mode;
+{
+ return gz_open(path, -2, mode);
+}
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzbuffer(file, size)
+ gzFile file;
+ unsigned size;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* make sure we haven't already allocated memory */
+ if (state->size != 0)
+ return -1;
+
+ /* check and set requested size */
+ if ((size << 1) < size)
+ return -1; /* need to be able to double it */
+ if (size < 2)
+ size = 2; /* need two bytes to check magic header */
+ state->want = size;
+ return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzrewind(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* back up and start over */
+ if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
+ return -1;
+ gz_reset(state);
+ return 0;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzseek64(file, offset, whence)
+ gzFile file;
+ z_off64_t offset;
+ int whence;
+{
+ unsigned n;
+ z_off64_t ret;
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* check that there's no error */
+ if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+ return -1;
+
+ /* can only seek from start or relative to current position */
+ if (whence != SEEK_SET && whence != SEEK_CUR)
+ return -1;
+
+ /* normalize offset to a SEEK_CUR specification */
+ if (whence == SEEK_SET)
+ offset -= state->x.pos;
+ else if (state->seek)
+ offset += state->skip;
+ state->seek = 0;
+
+ /* if within raw area while reading, just go there */
+ if (state->mode == GZ_READ && state->how == COPY &&
+ state->x.pos + offset >= 0) {
+ ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
+ if (ret == -1)
+ return -1;
+ state->x.have = 0;
+ state->eof = 0;
+ state->past = 0;
+ state->seek = 0;
+ gz_error(state, Z_OK, NULL);
+ state->strm.avail_in = 0;
+ state->x.pos += offset;
+ return state->x.pos;
+ }
+
+ /* calculate skip amount, rewinding if needed for back seek when reading */
+ if (offset < 0) {
+ if (state->mode != GZ_READ) /* writing -- can't go backwards */
+ return -1;
+ offset += state->x.pos;
+ if (offset < 0) /* before start of file! */
+ return -1;
+ if (gzrewind(file) == -1) /* rewind, then skip to offset */
+ return -1;
+ }
+
+ /* if reading, skip what's in output buffer (one less gzgetc() check) */
+ if (state->mode == GZ_READ) {
+ n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
+ (unsigned)offset : state->x.have;
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ offset -= n;
+ }
+
+ /* request skip (if not zero) */
+ if (offset) {
+ state->seek = 1;
+ state->skip = offset;
+ }
+ return state->x.pos + offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzseek(file, offset, whence)
+ gzFile file;
+ z_off_t offset;
+ int whence;
+{
+ z_off64_t ret;
+
+ ret = gzseek64(file, (z_off64_t)offset, whence);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gztell64(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* return position */
+ return state->x.pos + (state->seek ? state->skip : 0);
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gztell(file)
+ gzFile file;
+{
+ z_off64_t ret;
+
+ ret = gztell64(file);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzoffset64(file)
+ gzFile file;
+{
+ z_off64_t offset;
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return -1;
+
+ /* compute and return effective offset in file */
+ offset = LSEEK(state->fd, 0, SEEK_CUR);
+ if (offset == -1)
+ return -1;
+ if (state->mode == GZ_READ) /* reading */
+ offset -= state->strm.avail_in; /* don't count buffered input */
+ return offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzoffset(file)
+ gzFile file;
+{
+ z_off64_t ret;
+
+ ret = gzoffset64(file);
+ return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzeof(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return 0;
+
+ /* return end-of-file state */
+ return state->mode == GZ_READ ? state->past : 0;
+}
+
+/* -- see zlib.h -- */
+const char * ZEXPORT gzerror(file, errnum)
+ gzFile file;
+ int *errnum;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return NULL;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return NULL;
+
+ /* return error information */
+ if (errnum != NULL)
+ *errnum = state->err;
+ return state->err == Z_MEM_ERROR ? "out of memory" :
+ (state->msg == NULL ? "" : state->msg);
+}
+
+/* -- see zlib.h -- */
+void ZEXPORT gzclearerr(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure and check integrity */
+ if (file == NULL)
+ return;
+ state = (gz_statep)file;
+ if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+ return;
+
+ /* clear error and end-of-file */
+ if (state->mode == GZ_READ) {
+ state->eof = 0;
+ state->past = 0;
+ }
+ gz_error(state, Z_OK, NULL);
+}
+
+/* Create an error message in allocated memory and set state->err and
+ state->msg accordingly. Free any previous error message already there. Do
+ not try to free or allocate space if the error is Z_MEM_ERROR (out of
+ memory). Simply save the error message as a static string. If there is an
+ allocation failure constructing the error message, then convert the error to
+ out of memory. */
+void ZLIB_INTERNAL gz_error(state, err, msg)
+ gz_statep state;
+ int err;
+ const char *msg;
+{
+ /* free previously allocated message and clear */
+ if (state->msg != NULL) {
+ if (state->err != Z_MEM_ERROR)
+ free(state->msg);
+ state->msg = NULL;
+ }
+
+ /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
+ if (err != Z_OK && err != Z_BUF_ERROR)
+ state->x.have = 0;
+
+ /* set error code, and if no message, then done */
+ state->err = err;
+ if (msg == NULL)
+ return;
+
+ /* for an out of memory error, return literal string when requested */
+ if (err == Z_MEM_ERROR)
+ return;
+
+ /* construct error message with path */
+ if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
+ NULL) {
+ state->err = Z_MEM_ERROR;
+ return;
+ }
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+ (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
+ "%s%s%s", state->path, ": ", msg);
+#else
+ strcpy(state->msg, state->path);
+ strcat(state->msg, ": ");
+ strcat(state->msg, msg);
+#endif
+}
+
+#ifndef INT_MAX
+/* portably return maximum value for an int (when limits.h presumed not
+ available) -- we need to do this to cover cases where 2's complement not
+ used, since C standard permits 1's complement and sign-bit representations,
+ otherwise we could just use ((unsigned)-1) >> 1 */
+unsigned ZLIB_INTERNAL gz_intmax()
+{
+ unsigned p, q;
+
+ p = 1;
+ do {
+ q = p;
+ p <<= 1;
+ p++;
+ } while (p > q);
+ return q >> 1;
+}
+#endif
diff --git a/xs/src/png/zlib/gzread.c b/xs/src/png/zlib/gzread.c
new file mode 100644
index 000000000..956b91ea7
--- /dev/null
+++ b/xs/src/png/zlib/gzread.c
@@ -0,0 +1,654 @@
+/* gzread.c -- zlib functions for reading gzip files
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
+local int gz_avail OF((gz_statep));
+local int gz_look OF((gz_statep));
+local int gz_decomp OF((gz_statep));
+local int gz_fetch OF((gz_statep));
+local int gz_skip OF((gz_statep, z_off64_t));
+local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
+
+/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
+ state->fd, and update state->eof, state->err, and state->msg as appropriate.
+ This function needs to loop on read(), since read() is not guaranteed to
+ read the number of bytes requested, depending on the type of descriptor. */
+local int gz_load(state, buf, len, have)
+ gz_statep state;
+ unsigned char *buf;
+ unsigned len;
+ unsigned *have;
+{
+ int ret;
+ unsigned get, max = ((unsigned)-1 >> 2) + 1;
+
+ *have = 0;
+ do {
+ get = len - *have;
+ if (get > max)
+ get = max;
+ ret = read(state->fd, buf + *have, get);
+ if (ret <= 0)
+ break;
+ *have += (unsigned)ret;
+ } while (*have < len);
+ if (ret < 0) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ if (ret == 0)
+ state->eof = 1;
+ return 0;
+}
+
+/* Load up input buffer and set eof flag if last data loaded -- return -1 on
+ error, 0 otherwise. Note that the eof flag is set when the end of the input
+ file is reached, even though there may be unused data in the buffer. Once
+ that data has been used, no more attempts will be made to read the file.
+ If strm->avail_in != 0, then the current data is moved to the beginning of
+ the input buffer, and then the remainder of the buffer is loaded with the
+ available data from the input file. */
+local int gz_avail(state)
+ gz_statep state;
+{
+ unsigned got;
+ z_streamp strm = &(state->strm);
+
+ if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+ return -1;
+ if (state->eof == 0) {
+ if (strm->avail_in) { /* copy what's there to the start */
+ unsigned char *p = state->in;
+ unsigned const char *q = strm->next_in;
+ unsigned n = strm->avail_in;
+ do {
+ *p++ = *q++;
+ } while (--n);
+ }
+ if (gz_load(state, state->in + strm->avail_in,
+ state->size - strm->avail_in, &got) == -1)
+ return -1;
+ strm->avail_in += got;
+ strm->next_in = state->in;
+ }
+ return 0;
+}
+
+/* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
+ If this is the first time in, allocate required memory. state->how will be
+ left unchanged if there is no more input data available, will be set to COPY
+ if there is no gzip header and direct copying will be performed, or it will
+ be set to GZIP for decompression. If direct copying, then leftover input
+ data from the input buffer will be copied to the output buffer. In that
+ case, all further file reads will be directly to either the output buffer or
+ a user buffer. If decompressing, the inflate state will be initialized.
+ gz_look() will return 0 on success or -1 on failure. */
+local int gz_look(state)
+ gz_statep state;
+{
+ z_streamp strm = &(state->strm);
+
+ /* allocate read buffers and inflate memory */
+ if (state->size == 0) {
+ /* allocate buffers */
+ state->in = (unsigned char *)malloc(state->want);
+ state->out = (unsigned char *)malloc(state->want << 1);
+ if (state->in == NULL || state->out == NULL) {
+ free(state->out);
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ state->size = state->want;
+
+ /* allocate inflate memory */
+ state->strm.zalloc = Z_NULL;
+ state->strm.zfree = Z_NULL;
+ state->strm.opaque = Z_NULL;
+ state->strm.avail_in = 0;
+ state->strm.next_in = Z_NULL;
+ if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */
+ free(state->out);
+ free(state->in);
+ state->size = 0;
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ }
+
+ /* get at least the magic bytes in the input buffer */
+ if (strm->avail_in < 2) {
+ if (gz_avail(state) == -1)
+ return -1;
+ if (strm->avail_in == 0)
+ return 0;
+ }
+
+ /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
+ a logical dilemma here when considering the case of a partially written
+ gzip file, to wit, if a single 31 byte is written, then we cannot tell
+ whether this is a single-byte file, or just a partially written gzip
+ file -- for here we assume that if a gzip file is being written, then
+ the header will be written in a single operation, so that reading a
+ single byte is sufficient indication that it is not a gzip file) */
+ if (strm->avail_in > 1 &&
+ strm->next_in[0] == 31 && strm->next_in[1] == 139) {
+ inflateReset(strm);
+ state->how = GZIP;
+ state->direct = 0;
+ return 0;
+ }
+
+ /* no gzip header -- if we were decoding gzip before, then this is trailing
+ garbage. Ignore the trailing garbage and finish. */
+ if (state->direct == 0) {
+ strm->avail_in = 0;
+ state->eof = 1;
+ state->x.have = 0;
+ return 0;
+ }
+
+ /* doing raw i/o, copy any leftover input to output -- this assumes that
+ the output buffer is larger than the input buffer, which also assures
+ space for gzungetc() */
+ state->x.next = state->out;
+ if (strm->avail_in) {
+ memcpy(state->x.next, strm->next_in, strm->avail_in);
+ state->x.have = strm->avail_in;
+ strm->avail_in = 0;
+ }
+ state->how = COPY;
+ state->direct = 1;
+ return 0;
+}
+
+/* Decompress from input to the provided next_out and avail_out in the state.
+ On return, state->x.have and state->x.next point to the just decompressed
+ data. If the gzip stream completes, state->how is reset to LOOK to look for
+ the next gzip stream or raw data, once state->x.have is depleted. Returns 0
+ on success, -1 on failure. */
+local int gz_decomp(state)
+ gz_statep state;
+{
+ int ret = Z_OK;
+ unsigned had;
+ z_streamp strm = &(state->strm);
+
+ /* fill output buffer up to end of deflate stream */
+ had = strm->avail_out;
+ do {
+ /* get more input for inflate() */
+ if (strm->avail_in == 0 && gz_avail(state) == -1)
+ return -1;
+ if (strm->avail_in == 0) {
+ gz_error(state, Z_BUF_ERROR, "unexpected end of file");
+ break;
+ }
+
+ /* decompress and handle errors */
+ ret = inflate(strm, Z_NO_FLUSH);
+ if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
+ gz_error(state, Z_STREAM_ERROR,
+ "internal error: inflate stream corrupt");
+ return -1;
+ }
+ if (ret == Z_MEM_ERROR) {
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
+ gz_error(state, Z_DATA_ERROR,
+ strm->msg == NULL ? "compressed data error" : strm->msg);
+ return -1;
+ }
+ } while (strm->avail_out && ret != Z_STREAM_END);
+
+ /* update available output */
+ state->x.have = had - strm->avail_out;
+ state->x.next = strm->next_out - state->x.have;
+
+ /* if the gzip stream completed successfully, look for another */
+ if (ret == Z_STREAM_END)
+ state->how = LOOK;
+
+ /* good decompression */
+ return 0;
+}
+
+/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
+ Data is either copied from the input file or decompressed from the input
+ file depending on state->how. If state->how is LOOK, then a gzip header is
+ looked for to determine whether to copy or decompress. Returns -1 on error,
+ otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
+ end of the input file has been reached and all data has been processed. */
+local int gz_fetch(state)
+ gz_statep state;
+{
+ z_streamp strm = &(state->strm);
+
+ do {
+ switch(state->how) {
+ case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
+ if (gz_look(state) == -1)
+ return -1;
+ if (state->how == LOOK)
+ return 0;
+ break;
+ case COPY: /* -> COPY */
+ if (gz_load(state, state->out, state->size << 1, &(state->x.have))
+ == -1)
+ return -1;
+ state->x.next = state->out;
+ return 0;
+ case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
+ strm->avail_out = state->size << 1;
+ strm->next_out = state->out;
+ if (gz_decomp(state) == -1)
+ return -1;
+ }
+ } while (state->x.have == 0 && (!state->eof || strm->avail_in));
+ return 0;
+}
+
+/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */
+local int gz_skip(state, len)
+ gz_statep state;
+ z_off64_t len;
+{
+ unsigned n;
+
+ /* skip over len bytes or reach end-of-file, whichever comes first */
+ while (len)
+ /* skip over whatever is in output buffer */
+ if (state->x.have) {
+ n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
+ (unsigned)len : state->x.have;
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ len -= n;
+ }
+
+ /* output buffer empty -- return if we're at the end of the input */
+ else if (state->eof && state->strm.avail_in == 0)
+ break;
+
+ /* need more data to skip -- load up output buffer */
+ else {
+ /* get more output, looking for header if required */
+ if (gz_fetch(state) == -1)
+ return -1;
+ }
+ return 0;
+}
+
+/* Read len bytes into buf from file, or less than len up to the end of the
+ input. Return the number of bytes read. If zero is returned, either the
+ end of file was reached, or there was an error. state->err must be
+ consulted in that case to determine which. */
+local z_size_t gz_read(state, buf, len)
+ gz_statep state;
+ voidp buf;
+ z_size_t len;
+{
+ z_size_t got;
+ unsigned n;
+
+ /* if len is zero, avoid unnecessary operations */
+ if (len == 0)
+ return 0;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* get len bytes to buf, or less than len if at the end */
+ got = 0;
+ do {
+ /* set n to the maximum amount of len that fits in an unsigned int */
+ n = -1;
+ if (n > len)
+ n = len;
+
+ /* first just try copying data from the output buffer */
+ if (state->x.have) {
+ if (state->x.have < n)
+ n = state->x.have;
+ memcpy(buf, state->x.next, n);
+ state->x.next += n;
+ state->x.have -= n;
+ }
+
+ /* output buffer empty -- return if we're at the end of the input */
+ else if (state->eof && state->strm.avail_in == 0) {
+ state->past = 1; /* tried to read past end */
+ break;
+ }
+
+ /* need output data -- for small len or new stream load up our output
+ buffer */
+ else if (state->how == LOOK || n < (state->size << 1)) {
+ /* get more output, looking for header if required */
+ if (gz_fetch(state) == -1)
+ return 0;
+ continue; /* no progress yet -- go back to copy above */
+ /* the copy above assures that we will leave with space in the
+ output buffer, allowing at least one gzungetc() to succeed */
+ }
+
+ /* large len -- read directly into user buffer */
+ else if (state->how == COPY) { /* read directly */
+ if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
+ return 0;
+ }
+
+ /* large len -- decompress directly into user buffer */
+ else { /* state->how == GZIP */
+ state->strm.avail_out = n;
+ state->strm.next_out = (unsigned char *)buf;
+ if (gz_decomp(state) == -1)
+ return 0;
+ n = state->x.have;
+ state->x.have = 0;
+ }
+
+ /* update progress */
+ len -= n;
+ buf = (char *)buf + n;
+ got += n;
+ state->x.pos += n;
+ } while (len);
+
+ /* return number of bytes read into user buffer */
+ return got;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzread(file, buf, len)
+ gzFile file;
+ voidp buf;
+ unsigned len;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* since an int is returned, make sure len fits in one, otherwise return
+ with an error (this avoids a flaw in the interface) */
+ if ((int)len < 0) {
+ gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
+ return -1;
+ }
+
+ /* read len or fewer bytes to buf */
+ len = gz_read(state, buf, len);
+
+ /* check for an error */
+ if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
+ return -1;
+
+ /* return the number of bytes read (this is assured to fit in an int) */
+ return (int)len;
+}
+
+/* -- see zlib.h -- */
+z_size_t ZEXPORT gzfread(buf, size, nitems, file)
+ voidp buf;
+ z_size_t size;
+ z_size_t nitems;
+ gzFile file;
+{
+ z_size_t len;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return 0;
+
+ /* compute bytes to read -- error on overflow */
+ len = nitems * size;
+ if (size && len / size != nitems) {
+ gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
+ return 0;
+ }
+
+ /* read len or fewer bytes to buf, return the number of full items read */
+ return len ? gz_read(state, buf, len) / size : 0;
+}
+
+/* -- see zlib.h -- */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+#else
+# undef gzgetc
+#endif
+int ZEXPORT gzgetc(file)
+ gzFile file;
+{
+ int ret;
+ unsigned char buf[1];
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* try output buffer (no need to check for skip request) */
+ if (state->x.have) {
+ state->x.have--;
+ state->x.pos++;
+ return *(state->x.next)++;
+ }
+
+ /* nothing there -- try gz_read() */
+ ret = gz_read(state, buf, 1);
+ return ret < 1 ? -1 : buf[0];
+}
+
+int ZEXPORT gzgetc_(file)
+gzFile file;
+{
+ return gzgetc(file);
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzungetc(c, file)
+ int c;
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return -1;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* can't push EOF */
+ if (c < 0)
+ return -1;
+
+ /* if output buffer empty, put byte at end (allows more pushing) */
+ if (state->x.have == 0) {
+ state->x.have = 1;
+ state->x.next = state->out + (state->size << 1) - 1;
+ state->x.next[0] = (unsigned char)c;
+ state->x.pos--;
+ state->past = 0;
+ return c;
+ }
+
+ /* if no room, give up (must have already done a gzungetc()) */
+ if (state->x.have == (state->size << 1)) {
+ gz_error(state, Z_DATA_ERROR, "out of room to push characters");
+ return -1;
+ }
+
+ /* slide output data if needed and insert byte before existing data */
+ if (state->x.next == state->out) {
+ unsigned char *src = state->out + state->x.have;
+ unsigned char *dest = state->out + (state->size << 1);
+ while (src > state->out)
+ *--dest = *--src;
+ state->x.next = dest;
+ }
+ state->x.have++;
+ state->x.next--;
+ state->x.next[0] = (unsigned char)c;
+ state->x.pos--;
+ state->past = 0;
+ return c;
+}
+
+/* -- see zlib.h -- */
+char * ZEXPORT gzgets(file, buf, len)
+ gzFile file;
+ char *buf;
+ int len;
+{
+ unsigned left, n;
+ char *str;
+ unsigned char *eol;
+ gz_statep state;
+
+ /* check parameters and get internal structure */
+ if (file == NULL || buf == NULL || len < 1)
+ return NULL;
+ state = (gz_statep)file;
+
+ /* check that we're reading and that there's no (serious) error */
+ if (state->mode != GZ_READ ||
+ (state->err != Z_OK && state->err != Z_BUF_ERROR))
+ return NULL;
+
+ /* process a skip request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_skip(state, state->skip) == -1)
+ return NULL;
+ }
+
+ /* copy output bytes up to new line or len - 1, whichever comes first --
+ append a terminating zero to the string (we don't check for a zero in
+ the contents, let the user worry about that) */
+ str = buf;
+ left = (unsigned)len - 1;
+ if (left) do {
+ /* assure that something is in the output buffer */
+ if (state->x.have == 0 && gz_fetch(state) == -1)
+ return NULL; /* error */
+ if (state->x.have == 0) { /* end of file */
+ state->past = 1; /* read past end */
+ break; /* return what we have */
+ }
+
+ /* look for end-of-line in current output buffer */
+ n = state->x.have > left ? left : state->x.have;
+ eol = (unsigned char *)memchr(state->x.next, '\n', n);
+ if (eol != NULL)
+ n = (unsigned)(eol - state->x.next) + 1;
+
+ /* copy through end-of-line, or remainder if not found */
+ memcpy(buf, state->x.next, n);
+ state->x.have -= n;
+ state->x.next += n;
+ state->x.pos += n;
+ left -= n;
+ buf += n;
+ } while (left && eol == NULL);
+
+ /* return terminated string, or if nothing, end of file */
+ if (buf == str)
+ return NULL;
+ buf[0] = 0;
+ return str;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzdirect(file)
+ gzFile file;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* if the state is not known, but we can find out, then do so (this is
+ mainly for right after a gzopen() or gzdopen()) */
+ if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
+ (void)gz_look(state);
+
+ /* return 1 if transparent, 0 if processing a gzip stream */
+ return state->direct;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_r(file)
+ gzFile file;
+{
+ int ret, err;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're reading */
+ if (state->mode != GZ_READ)
+ return Z_STREAM_ERROR;
+
+ /* free memory and close file */
+ if (state->size) {
+ inflateEnd(&(state->strm));
+ free(state->out);
+ free(state->in);
+ }
+ err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
+ gz_error(state, Z_OK, NULL);
+ free(state->path);
+ ret = close(state->fd);
+ free(state);
+ return ret ? Z_ERRNO : err;
+}
diff --git a/xs/src/png/zlib/gzwrite.c b/xs/src/png/zlib/gzwrite.c
new file mode 100644
index 000000000..c7b5651d7
--- /dev/null
+++ b/xs/src/png/zlib/gzwrite.c
@@ -0,0 +1,665 @@
+/* gzwrite.c -- zlib functions for writing gzip files
+ * Copyright (C) 2004-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_init OF((gz_statep));
+local int gz_comp OF((gz_statep, int));
+local int gz_zero OF((gz_statep, z_off64_t));
+local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
+
+/* Initialize state for writing a gzip file. Mark initialization by setting
+ state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
+ success. */
+local int gz_init(state)
+ gz_statep state;
+{
+ int ret;
+ z_streamp strm = &(state->strm);
+
+ /* allocate input buffer (double size for gzprintf) */
+ state->in = (unsigned char *)malloc(state->want << 1);
+ if (state->in == NULL) {
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+
+ /* only need output buffer and deflate state if compressing */
+ if (!state->direct) {
+ /* allocate output buffer */
+ state->out = (unsigned char *)malloc(state->want);
+ if (state->out == NULL) {
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+
+ /* allocate deflate memory, set up for gzip compression */
+ strm->zalloc = Z_NULL;
+ strm->zfree = Z_NULL;
+ strm->opaque = Z_NULL;
+ ret = deflateInit2(strm, state->level, Z_DEFLATED,
+ MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
+ if (ret != Z_OK) {
+ free(state->out);
+ free(state->in);
+ gz_error(state, Z_MEM_ERROR, "out of memory");
+ return -1;
+ }
+ strm->next_in = NULL;
+ }
+
+ /* mark state as initialized */
+ state->size = state->want;
+
+ /* initialize write buffer if compressing */
+ if (!state->direct) {
+ strm->avail_out = state->size;
+ strm->next_out = state->out;
+ state->x.next = strm->next_out;
+ }
+ return 0;
+}
+
+/* Compress whatever is at avail_in and next_in and write to the output file.
+ Return -1 if there is an error writing to the output file or if gz_init()
+ fails to allocate memory, otherwise 0. flush is assumed to be a valid
+ deflate() flush value. If flush is Z_FINISH, then the deflate() state is
+ reset to start a new gzip stream. If gz->direct is true, then simply write
+ to the output file without compressing, and ignore flush. */
+local int gz_comp(state, flush)
+ gz_statep state;
+ int flush;
+{
+ int ret, writ;
+ unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
+ z_streamp strm = &(state->strm);
+
+ /* allocate memory if this is the first time through */
+ if (state->size == 0 && gz_init(state) == -1)
+ return -1;
+
+ /* write directly if requested */
+ if (state->direct) {
+ while (strm->avail_in) {
+ put = strm->avail_in > max ? max : strm->avail_in;
+ writ = write(state->fd, strm->next_in, put);
+ if (writ < 0) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ strm->avail_in -= (unsigned)writ;
+ strm->next_in += writ;
+ }
+ return 0;
+ }
+
+ /* run deflate() on provided input until it produces no more output */
+ ret = Z_OK;
+ do {
+ /* write out current buffer contents if full, or if flushing, but if
+ doing Z_FINISH then don't write until we get to Z_STREAM_END */
+ if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
+ (flush != Z_FINISH || ret == Z_STREAM_END))) {
+ while (strm->next_out > state->x.next) {
+ put = strm->next_out - state->x.next > (int)max ? max :
+ (unsigned)(strm->next_out - state->x.next);
+ writ = write(state->fd, state->x.next, put);
+ if (writ < 0) {
+ gz_error(state, Z_ERRNO, zstrerror());
+ return -1;
+ }
+ state->x.next += writ;
+ }
+ if (strm->avail_out == 0) {
+ strm->avail_out = state->size;
+ strm->next_out = state->out;
+ state->x.next = state->out;
+ }
+ }
+
+ /* compress */
+ have = strm->avail_out;
+ ret = deflate(strm, flush);
+ if (ret == Z_STREAM_ERROR) {
+ gz_error(state, Z_STREAM_ERROR,
+ "internal error: deflate stream corrupt");
+ return -1;
+ }
+ have -= strm->avail_out;
+ } while (have);
+
+ /* if that completed a deflate stream, allow another to start */
+ if (flush == Z_FINISH)
+ deflateReset(strm);
+
+ /* all done, no errors */
+ return 0;
+}
+
+/* Compress len zeros to output. Return -1 on a write error or memory
+ allocation failure by gz_comp(), or 0 on success. */
+local int gz_zero(state, len)
+ gz_statep state;
+ z_off64_t len;
+{
+ int first;
+ unsigned n;
+ z_streamp strm = &(state->strm);
+
+ /* consume whatever's left in the input buffer */
+ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return -1;
+
+ /* compress len zeros (len guaranteed > 0) */
+ first = 1;
+ while (len) {
+ n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
+ (unsigned)len : state->size;
+ if (first) {
+ memset(state->in, 0, n);
+ first = 0;
+ }
+ strm->avail_in = n;
+ strm->next_in = state->in;
+ state->x.pos += n;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return -1;
+ len -= n;
+ }
+ return 0;
+}
+
+/* Write len bytes from buf to file. Return the number of bytes written. If
+ the returned value is less than len, then there was an error. */
+local z_size_t gz_write(state, buf, len)
+ gz_statep state;
+ voidpc buf;
+ z_size_t len;
+{
+ z_size_t put = len;
+
+ /* if len is zero, avoid unnecessary operations */
+ if (len == 0)
+ return 0;
+
+ /* allocate memory if this is the first time through */
+ if (state->size == 0 && gz_init(state) == -1)
+ return 0;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return 0;
+ }
+
+ /* for small len, copy to input buffer, otherwise compress directly */
+ if (len < state->size) {
+ /* copy to input buffer, compress when full */
+ do {
+ unsigned have, copy;
+
+ if (state->strm.avail_in == 0)
+ state->strm.next_in = state->in;
+ have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
+ state->in);
+ copy = state->size - have;
+ if (copy > len)
+ copy = len;
+ memcpy(state->in + have, buf, copy);
+ state->strm.avail_in += copy;
+ state->x.pos += copy;
+ buf = (const char *)buf + copy;
+ len -= copy;
+ if (len && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+ } while (len);
+ }
+ else {
+ /* consume whatever's left in the input buffer */
+ if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+
+ /* directly compress user buffer to file */
+ state->strm.next_in = (z_const Bytef *)buf;
+ do {
+ unsigned n = (unsigned)-1;
+ if (n > len)
+ n = len;
+ state->strm.avail_in = n;
+ state->x.pos += n;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return 0;
+ len -= n;
+ } while (len);
+ }
+
+ /* input was all buffered or compressed */
+ return put;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzwrite(file, buf, len)
+ gzFile file;
+ voidpc buf;
+ unsigned len;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* since an int is returned, make sure len fits in one, otherwise return
+ with an error (this avoids a flaw in the interface) */
+ if ((int)len < 0) {
+ gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
+ return 0;
+ }
+
+ /* write len bytes from buf (the return value will fit in an int) */
+ return (int)gz_write(state, buf, len);
+}
+
+/* -- see zlib.h -- */
+z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
+ voidpc buf;
+ z_size_t size;
+ z_size_t nitems;
+ gzFile file;
+{
+ z_size_t len;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return 0;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return 0;
+
+ /* compute bytes to read -- error on overflow */
+ len = nitems * size;
+ if (size && len / size != nitems) {
+ gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
+ return 0;
+ }
+
+ /* write len bytes to buf, return the number of full items written */
+ return len ? gz_write(state, buf, len) / size : 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputc(file, c)
+ gzFile file;
+ int c;
+{
+ unsigned have;
+ unsigned char buf[1];
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return -1;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return -1;
+ }
+
+ /* try writing to input buffer for speed (state->size == 0 if buffer not
+ initialized) */
+ if (state->size) {
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+ if (have < state->size) {
+ state->in[have] = (unsigned char)c;
+ strm->avail_in++;
+ state->x.pos++;
+ return c & 0xff;
+ }
+ }
+
+ /* no room in buffer or not initialized, use gz_write() */
+ buf[0] = (unsigned char)c;
+ if (gz_write(state, buf, 1) != 1)
+ return -1;
+ return c & 0xff;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputs(file, str)
+ gzFile file;
+ const char *str;
+{
+ int ret;
+ z_size_t len;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return -1;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return -1;
+
+ /* write string */
+ len = strlen(str);
+ ret = gz_write(state, str, len);
+ return ret == 0 && len != 0 ? -1 : ret;
+}
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#include <stdarg.h>
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
+{
+ int len;
+ unsigned left;
+ char *next;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* make sure we have some buffer space */
+ if (state->size == 0 && gz_init(state) == -1)
+ return state->err;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->err;
+ }
+
+ /* do the printf() into the input buffer, put length in len -- the input
+ buffer is double-sized just for this function, so there is guaranteed to
+ be state->size bytes available after the current contents */
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
+ next[state->size - 1] = 0;
+#ifdef NO_vsnprintf
+# ifdef HAS_vsprintf_void
+ (void)vsprintf(next, format, va);
+ for (len = 0; len < state->size; len++)
+ if (next[len] == 0) break;
+# else
+ len = vsprintf(next, format, va);
+# endif
+#else
+# ifdef HAS_vsnprintf_void
+ (void)vsnprintf(next, state->size, format, va);
+ len = strlen(next);
+# else
+ len = vsnprintf(next, state->size, format, va);
+# endif
+#endif
+
+ /* check that printf() results fit in buffer */
+ if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
+ return 0;
+
+ /* update buffer and position, compress first half if past that */
+ strm->avail_in += (unsigned)len;
+ state->x.pos += len;
+ if (strm->avail_in >= state->size) {
+ left = strm->avail_in - state->size;
+ strm->avail_in = state->size;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return state->err;
+ memcpy(state->in, state->in + state->size, left);
+ strm->next_in = state->in;
+ strm->avail_in = left;
+ }
+ return len;
+}
+
+int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
+{
+ va_list va;
+ int ret;
+
+ va_start(va, format);
+ ret = gzvprintf(file, format, va);
+ va_end(va);
+ return ret;
+}
+
+#else /* !STDC && !Z_HAVE_STDARG_H */
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+ gzFile file;
+ const char *format;
+ int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+ unsigned len, left;
+ char *next;
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that can really pass pointer in ints */
+ if (sizeof(int) != sizeof(void *))
+ return Z_STREAM_ERROR;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* make sure we have some buffer space */
+ if (state->size == 0 && gz_init(state) == -1)
+ return state->error;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->error;
+ }
+
+ /* do the printf() into the input buffer, put length in len -- the input
+ buffer is double-sized just for this function, so there is guaranteed to
+ be state->size bytes available after the current contents */
+ if (strm->avail_in == 0)
+ strm->next_in = state->in;
+ next = (char *)(strm->next_in + strm->avail_in);
+ next[state->size - 1] = 0;
+#ifdef NO_snprintf
+# ifdef HAS_sprintf_void
+ sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
+ a13, a14, a15, a16, a17, a18, a19, a20);
+ for (len = 0; len < size; len++)
+ if (next[len] == 0)
+ break;
+# else
+ len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
+ a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#else
+# ifdef HAS_snprintf_void
+ snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+ a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ len = strlen(next);
+# else
+ len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#endif
+
+ /* check that printf() results fit in buffer */
+ if (len == 0 || len >= state->size || next[state->size - 1] != 0)
+ return 0;
+
+ /* update buffer and position, compress first half if past that */
+ strm->avail_in += len;
+ state->x.pos += len;
+ if (strm->avail_in >= state->size) {
+ left = strm->avail_in - state->size;
+ strm->avail_in = state->size;
+ if (gz_comp(state, Z_NO_FLUSH) == -1)
+ return state->err;
+ memcpy(state->in, state->in + state->size, left);
+ strm->next_in = state->in;
+ strm->avail_in = left;
+ }
+ return (int)len;
+}
+
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzflush(file, flush)
+ gzFile file;
+ int flush;
+{
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* check flush parameter */
+ if (flush < 0 || flush > Z_FINISH)
+ return Z_STREAM_ERROR;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->err;
+ }
+
+ /* compress remaining data with requested flush */
+ (void)gz_comp(state, flush);
+ return state->err;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzsetparams(file, level, strategy)
+ gzFile file;
+ int level;
+ int strategy;
+{
+ gz_statep state;
+ z_streamp strm;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+ strm = &(state->strm);
+
+ /* check that we're writing and that there's no error */
+ if (state->mode != GZ_WRITE || state->err != Z_OK)
+ return Z_STREAM_ERROR;
+
+ /* if no change is requested, then do nothing */
+ if (level == state->level && strategy == state->strategy)
+ return Z_OK;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ return state->err;
+ }
+
+ /* change compression parameters for subsequent input */
+ if (state->size) {
+ /* flush previous input with previous parameters before changing */
+ if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
+ return state->err;
+ deflateParams(strm, level, strategy);
+ }
+ state->level = level;
+ state->strategy = strategy;
+ return Z_OK;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_w(file)
+ gzFile file;
+{
+ int ret = Z_OK;
+ gz_statep state;
+
+ /* get internal structure */
+ if (file == NULL)
+ return Z_STREAM_ERROR;
+ state = (gz_statep)file;
+
+ /* check that we're writing */
+ if (state->mode != GZ_WRITE)
+ return Z_STREAM_ERROR;
+
+ /* check for seek request */
+ if (state->seek) {
+ state->seek = 0;
+ if (gz_zero(state, state->skip) == -1)
+ ret = state->err;
+ }
+
+ /* flush, free memory, and close file */
+ if (gz_comp(state, Z_FINISH) == -1)
+ ret = state->err;
+ if (state->size) {
+ if (!state->direct) {
+ (void)deflateEnd(&(state->strm));
+ free(state->out);
+ }
+ free(state->in);
+ }
+ gz_error(state, Z_OK, NULL);
+ free(state->path);
+ if (close(state->fd) == -1)
+ ret = Z_ERRNO;
+ free(state);
+ return ret;
+}
diff --git a/xs/src/png/zlib/infback.c b/xs/src/png/zlib/infback.c
new file mode 100644
index 000000000..59679ecbf
--- /dev/null
+++ b/xs/src/png/zlib/infback.c
@@ -0,0 +1,640 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ This code is largely copied from inflate.c. Normally either infback.o or
+ inflate.o would be linked into an application--not both. The interface
+ with inffast.c is retained so that optimized assembler-coded versions of
+ inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+ strm provides memory allocation functions in zalloc and zfree, or
+ Z_NULL to use the library memory allocation functions.
+
+ windowBits is in the range 8..15, and window is a user-supplied
+ window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_streamp strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL || window == Z_NULL ||
+ windowBits < 8 || windowBits > 15)
+ return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+#endif
+ }
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
+ state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+ sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ state->dmax = 32768U;
+ state->wbits = (uInt)windowBits;
+ state->wsize = 1U << windowBits;
+ state->window = window;
+ state->wnext = 0;
+ state->whave = 0;
+ return Z_OK;
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Assure that some input is available. If input is requested, but denied,
+ then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+ do { \
+ if (have == 0) { \
+ have = in(in_desc, &next); \
+ if (have == 0) { \
+ next = Z_NULL; \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+ with an error if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ PULL(); \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflateBack() with
+ an error. */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Assure that some output space is available, by writing out the window
+ if it's full. If the write fails, return from inflateBack() with a
+ Z_BUF_ERROR. */
+#define ROOM() \
+ do { \
+ if (left == 0) { \
+ put = state->window; \
+ left = state->wsize; \
+ state->whave = left; \
+ if (out(out_desc, put, left)) { \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/*
+ strm provides the memory allocation functions and window buffer on input,
+ and provides information on the unused input on return. For Z_DATA_ERROR
+ returns, strm will also provide an error message.
+
+ in() and out() are the call-back input and output functions. When
+ inflateBack() needs more input, it calls in(). When inflateBack() has
+ filled the window with output, or when it completes with data in the
+ window, it calls out() to write out the data. The application must not
+ change the provided input until in() is called again or inflateBack()
+ returns. The application must not change the window/output buffer until
+ inflateBack() returns.
+
+ in() and out() are called with a descriptor parameter provided in the
+ inflateBack() call. This parameter can be a structure that provides the
+ information required to do the read or write, as well as accumulated
+ information on the input and output such as totals and check values.
+
+ in() should return zero on failure. out() should return non-zero on
+ failure. If either in() or out() fails, than inflateBack() returns a
+ Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
+ was in() or out() that caused in the error. Otherwise, inflateBack()
+ returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+ error, or Z_MEM_ERROR if it could not allocate memory for the state.
+ inflateBack() can also return Z_STREAM_ERROR if the input parameters
+ are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_streamp strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code here; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ /* Check that the strm exists and that the state was initialized */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* Reset the state */
+ strm->msg = Z_NULL;
+ state->mode = TYPE;
+ state->last = 0;
+ state->whave = 0;
+ next = strm->next_in;
+ have = next != Z_NULL ? strm->avail_in : 0;
+ hold = 0;
+ bits = 0;
+ put = state->window;
+ left = state->wsize;
+
+ /* Inflate until end of block marked as last */
+ for (;;)
+ switch (state->mode) {
+ case TYPE:
+ /* determine and dispatch block type */
+ if (state->last) {
+ BYTEBITS();
+ state->mode = DONE;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+
+ case STORED:
+ /* get and verify stored block length */
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+
+ /* copy stored block from input to output */
+ while (state->length != 0) {
+ copy = state->length;
+ PULL();
+ ROOM();
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+
+ case TABLE:
+ /* get dynamic table entries descriptor */
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+
+ /* get code length code lengths (not a typo) */
+ state->have = 0;
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+
+ /* get length and distance code code lengths */
+ state->have = 0;
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.val < 16) {
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
+ }
+ else {
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = (unsigned)(state->lens[state->have - 1]);
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ state->mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+
+ case LEN:
+ /* use inflate_fast() if we have enough input and output */
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ if (state->whave < state->wsize)
+ state->whave = state->wsize - left;
+ inflate_fast(strm, state->wsize);
+ LOAD();
+ break;
+ }
+
+ /* get a literal, length, or end-of-block code */
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(here.bits);
+ state->length = (unsigned)here.val;
+
+ /* process literal */
+ if (here.op == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ ROOM();
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ }
+
+ /* process end of block */
+ if (here.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+
+ /* invalid code */
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+
+ /* length code -- get extra bits, if any */
+ state->extra = (unsigned)(here.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+
+ /* get distance code */
+ for (;;) {
+ here = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(here.bits);
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)here.val;
+
+ /* get distance extra bits, if any */
+ state->extra = (unsigned)(here.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ if (state->offset > state->wsize - (state->whave < state->wsize ?
+ left : 0)) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+
+ /* copy match from window to output */
+ do {
+ ROOM();
+ copy = state->wsize - state->offset;
+ if (copy < left) {
+ from = put + copy;
+ copy = left - copy;
+ }
+ else {
+ from = put - state->offset;
+ copy = left;
+ }
+ if (copy > state->length) copy = state->length;
+ state->length -= copy;
+ left -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ } while (state->length != 0);
+ break;
+
+ case DONE:
+ /* inflate stream terminated properly -- write leftover output */
+ ret = Z_STREAM_END;
+ if (left < state->wsize) {
+ if (out(out_desc, state->window, state->wsize - left))
+ ret = Z_BUF_ERROR;
+ }
+ goto inf_leave;
+
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+
+ default: /* can't happen, but makes compilers happy */
+ ret = Z_STREAM_ERROR;
+ goto inf_leave;
+ }
+
+ /* Return unused input */
+ inf_leave:
+ strm->next_in = next;
+ strm->avail_in = have;
+ return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_streamp strm;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
diff --git a/xs/src/png/zlib/inffast.c b/xs/src/png/zlib/inffast.c
new file mode 100644
index 000000000..0dbd1dbc0
--- /dev/null
+++ b/xs/src/png/zlib/inffast.c
@@ -0,0 +1,323 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef ASMINF
+# pragma message("Assembler code may have bugs -- use at your own risk")
+#else
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+void ZLIB_INTERNAL inflate_fast(strm, start)
+z_streamp strm;
+unsigned start; /* inflate()'s starting value for strm->avail_out */
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *in; /* local strm->next_in */
+ z_const unsigned char FAR *last; /* have enough input while in < last */
+ unsigned char FAR *out; /* local strm->next_out */
+ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
+ unsigned char FAR *end; /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+ unsigned dmax; /* maximum distance from zlib header */
+#endif
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned wnext; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
+ unsigned long hold; /* local strm->hold */
+ unsigned bits; /* local strm->bits */
+ code const FAR *lcode; /* local strm->lencode */
+ code const FAR *dcode; /* local strm->distcode */
+ unsigned lmask; /* mask for first level of length codes */
+ unsigned dmask; /* mask for first level of distance codes */
+ code here; /* retrieved table entry */
+ unsigned op; /* code bits, operation, extra bits, or */
+ /* window position, window bytes to copy */
+ unsigned len; /* match length, unused bytes */
+ unsigned dist; /* match distance */
+ unsigned char FAR *from; /* where to copy match from */
+
+ /* copy state to local variables */
+ state = (struct inflate_state FAR *)strm->state;
+ in = strm->next_in;
+ last = in + (strm->avail_in - 5);
+ out = strm->next_out;
+ beg = out - (start - strm->avail_out);
+ end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+ dmax = state->dmax;
+#endif
+ wsize = state->wsize;
+ whave = state->whave;
+ wnext = state->wnext;
+ window = state->window;
+ hold = state->hold;
+ bits = state->bits;
+ lcode = state->lencode;
+ dcode = state->distcode;
+ lmask = (1U << state->lenbits) - 1;
+ dmask = (1U << state->distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+ do {
+ if (bits < 15) {
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ }
+ here = lcode[hold & lmask];
+ dolen:
+ op = (unsigned)(here.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(here.op);
+ if (op == 0) { /* literal */
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ *out++ = (unsigned char)(here.val);
+ }
+ else if (op & 16) { /* length base */
+ len = (unsigned)(here.val);
+ op &= 15; /* number of extra bits */
+ if (op) {
+ if (bits < op) {
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ }
+ len += (unsigned)hold & ((1U << op) - 1);
+ hold >>= op;
+ bits -= op;
+ }
+ Tracevv((stderr, "inflate: length %u\n", len));
+ if (bits < 15) {
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ }
+ here = dcode[hold & dmask];
+ dodist:
+ op = (unsigned)(here.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(here.op);
+ if (op & 16) { /* distance base */
+ dist = (unsigned)(here.val);
+ op &= 15; /* number of extra bits */
+ if (bits < op) {
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ if (bits < op) {
+ hold += (unsigned long)(*in++) << bits;
+ bits += 8;
+ }
+ }
+ dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+ if (dist > dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ hold >>= op;
+ bits -= op;
+ Tracevv((stderr, "inflate: distance %u\n", dist));
+ op = (unsigned)(out - beg); /* max distance in output */
+ if (dist > op) { /* see if copy from window */
+ op = dist - op; /* distance back in window */
+ if (op > whave) {
+ if (state->sane) {
+ strm->msg =
+ (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ if (len <= op - whave) {
+ do {
+ *out++ = 0;
+ } while (--len);
+ continue;
+ }
+ len -= op - whave;
+ do {
+ *out++ = 0;
+ } while (--op > whave);
+ if (op == 0) {
+ from = out - dist;
+ do {
+ *out++ = *from++;
+ } while (--len);
+ continue;
+ }
+#endif
+ }
+ from = window;
+ if (wnext == 0) { /* very common case */
+ from += wsize - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ *out++ = *from++;
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ else if (wnext < op) { /* wrap around window */
+ from += wsize + wnext - op;
+ op -= wnext;
+ if (op < len) { /* some from end of window */
+ len -= op;
+ do {
+ *out++ = *from++;
+ } while (--op);
+ from = window;
+ if (wnext < len) { /* some from start of window */
+ op = wnext;
+ len -= op;
+ do {
+ *out++ = *from++;
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ }
+ else { /* contiguous in window */
+ from += wnext - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ *out++ = *from++;
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ while (len > 2) {
+ *out++ = *from++;
+ *out++ = *from++;
+ *out++ = *from++;
+ len -= 3;
+ }
+ if (len) {
+ *out++ = *from++;
+ if (len > 1)
+ *out++ = *from++;
+ }
+ }
+ else {
+ from = out - dist; /* copy direct from output */
+ do { /* minimum length is three */
+ *out++ = *from++;
+ *out++ = *from++;
+ *out++ = *from++;
+ len -= 3;
+ } while (len > 2);
+ if (len) {
+ *out++ = *from++;
+ if (len > 1)
+ *out++ = *from++;
+ }
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level distance code */
+ here = dcode[here.val + (hold & ((1U << op) - 1))];
+ goto dodist;
+ }
+ else {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level length code */
+ here = lcode[here.val + (hold & ((1U << op) - 1))];
+ goto dolen;
+ }
+ else if (op & 32) { /* end-of-block */
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ else {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ } while (in < last && out < end);
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ len = bits >> 3;
+ in -= len;
+ bits -= len << 3;
+ hold &= (1U << bits) - 1;
+
+ /* update state and return */
+ strm->next_in = in;
+ strm->next_out = out;
+ strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+ strm->avail_out = (unsigned)(out < end ?
+ 257 + (end - out) : 257 - (out - end));
+ state->hold = hold;
+ state->bits = bits;
+ return;
+}
+
+/*
+ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+ - Using bit fields for code structure
+ - Different op definition to avoid & for extra bits (do & for table bits)
+ - Three separate decoding do-loops for direct, window, and wnext == 0
+ - Special case for distance > 1 copies to do overlapped load and store copy
+ - Explicit branch predictions (based on measured branch probabilities)
+ - Deferring match copy and interspersed it with decoding subsequent codes
+ - Swapping literal/length else
+ - Swapping window/direct else
+ - Larger unrolled copy loops (three is about right)
+ - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/xs/src/png/zlib/inffast.h b/xs/src/png/zlib/inffast.h
new file mode 100644
index 000000000..e5c1aa4ca
--- /dev/null
+++ b/xs/src/png/zlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/xs/src/png/zlib/inffixed.h b/xs/src/png/zlib/inffixed.h
new file mode 100644
index 000000000..d62832776
--- /dev/null
+++ b/xs/src/png/zlib/inffixed.h
@@ -0,0 +1,94 @@
+ /* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by makefixed().
+ */
+
+ /* WARNING: this file should *not* be used by applications.
+ It is part of the implementation of this library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+ static const code lenfix[512] = {
+ {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+ {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+ {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+ {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+ {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+ {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+ {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+ {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+ {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+ {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+ {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+ {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+ {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+ {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+ {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+ {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+ {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+ {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+ {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+ {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+ {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+ {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+ {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+ {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+ {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+ {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+ {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+ {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+ {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+ {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+ {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+ {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+ {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+ {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+ {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+ {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+ {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+ {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+ {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+ {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+ {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+ {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+ {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+ {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+ {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+ {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+ {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+ {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+ {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+ {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+ {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+ {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+ {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+ {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+ {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+ {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+ {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+ {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+ {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+ {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+ {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+ {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+ {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+ {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+ {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+ {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+ {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+ {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+ {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+ {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+ {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+ {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+ {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+ {0,9,255}
+ };
+
+ static const code distfix[32] = {
+ {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+ {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+ {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+ {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+ {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+ {22,5,193},{64,5,0}
+ };
diff --git a/xs/src/png/zlib/inflate.c b/xs/src/png/zlib/inflate.c
new file mode 100644
index 000000000..ac333e8c2
--- /dev/null
+++ b/xs/src/png/zlib/inflate.c
@@ -0,0 +1,1561 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0 24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ * creation of window when not needed, minimize use of window when it is
+ * needed, make inffast.c even faster, implement gzip decoding, and to
+ * improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1 25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2 4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ * to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3 22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ * buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4 1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ * source file infback.c to provide a call-back interface to inflate for
+ * programs like gzip and unzip -- uses window as output buffer to avoid
+ * window copying
+ *
+ * 1.2.beta5 1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ * input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6 4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ * make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7 27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0 9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ * for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ * and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+# ifndef BUILDFIXED
+# define BUILDFIXED
+# endif
+#endif
+
+/* function prototypes */
+local int inflateStateCheck OF((z_streamp strm));
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+ unsigned copy));
+#ifdef BUILDFIXED
+ void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
+ unsigned len));
+
+local int inflateStateCheck(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (strm == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
+ return 1;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state == Z_NULL || state->strm != strm ||
+ state->mode < HEAD || state->mode > SYNC)
+ return 1;
+ return 0;
+}
+
+int ZEXPORT inflateResetKeep(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ strm->total_in = strm->total_out = state->total = 0;
+ strm->msg = Z_NULL;
+ if (state->wrap) /* to support ill-conceived Java test suite */
+ strm->adler = state->wrap & 1;
+ state->mode = HEAD;
+ state->last = 0;
+ state->havedict = 0;
+ state->dmax = 32768U;
+ state->head = Z_NULL;
+ state->hold = 0;
+ state->bits = 0;
+ state->lencode = state->distcode = state->next = state->codes;
+ state->sane = 1;
+ state->back = -1;
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ state->wsize = 0;
+ state->whave = 0;
+ state->wnext = 0;
+ return inflateResetKeep(strm);
+}
+
+int ZEXPORT inflateReset2(strm, windowBits)
+z_streamp strm;
+int windowBits;
+{
+ int wrap;
+ struct inflate_state FAR *state;
+
+ /* get the state */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* extract wrap request from windowBits parameter */
+ if (windowBits < 0) {
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ wrap = (windowBits >> 4) + 5;
+#ifdef GUNZIP
+ if (windowBits < 48)
+ windowBits &= 15;
+#endif
+ }
+
+ /* set number of window bits, free window if different */
+ if (windowBits && (windowBits < 8 || windowBits > 15))
+ return Z_STREAM_ERROR;
+ if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+ ZFREE(strm, state->window);
+ state->window = Z_NULL;
+ }
+
+ /* update state and reset the rest of it */
+ state->wrap = wrap;
+ state->wbits = (unsigned)windowBits;
+ return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+ int ret;
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+#endif
+ }
+ if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+ return Z_STREAM_ERROR;
+#else
+ strm->zfree = zcfree;
+#endif
+ state = (struct inflate_state FAR *)
+ ZALLOC(strm, 1, sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ state->strm = strm;
+ state->window = Z_NULL;
+ state->mode = HEAD; /* to pass state test in inflateReset2() */
+ ret = inflateReset2(strm, windowBits);
+ if (ret != Z_OK) {
+ ZFREE(strm, state);
+ strm->state = Z_NULL;
+ }
+ return ret;
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+ return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (bits < 0) {
+ state->hold = 0;
+ state->bits = 0;
+ return Z_OK;
+ }
+ if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
+ value &= (1L << bits) - 1;
+ state->hold += (unsigned)value << state->bits;
+ state->bits += (uInt)bits;
+ return Z_OK;
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+ Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
+ defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
+ those tables to stdout, which would be piped to inffixed.h. A small program
+ can simply call makefixed to do this:
+
+ void makefixed(void);
+
+ int main(void)
+ {
+ makefixed();
+ return 0;
+ }
+
+ Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+ a.out > inffixed.h
+ */
+void makefixed()
+{
+ unsigned low, size;
+ struct inflate_state state;
+
+ fixedtables(&state);
+ puts(" /* inffixed.h -- table for decoding fixed codes");
+ puts(" * Generated automatically by makefixed().");
+ puts(" */");
+ puts("");
+ puts(" /* WARNING: this file should *not* be used by applications.");
+ puts(" It is part of the implementation of this library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ puts(" */");
+ puts("");
+ size = 1U << 9;
+ printf(" static const code lenfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 7) == 0) printf("\n ");
+ printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
+ state.lencode[low].bits, state.lencode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+ size = 1U << 5;
+ printf("\n static const code distfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 6) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+ state.distcode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+}
+#endif /* MAKEFIXED */
+
+/*
+ Update the window with the last wsize (normally 32K) bytes written before
+ returning. If window does not exist yet, create it. This is only called
+ when a window is already in use, or when output has been written during this
+ inflate call, but the end of the deflate stream has not been reached yet.
+ It is also called to create a window for dictionary data when a dictionary
+ is loaded.
+
+ Providing output buffers larger than 32K to inflate() should provide a speed
+ advantage, since only the last 32K of output is copied to the sliding window
+ upon return from inflate(), and since all distances after the first 32K of
+ output will fall in the output data, making match copies simpler and faster.
+ The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, end, copy)
+z_streamp strm;
+const Bytef *end;
+unsigned copy;
+{
+ struct inflate_state FAR *state;
+ unsigned dist;
+
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* if it hasn't been done already, allocate space for the window */
+ if (state->window == Z_NULL) {
+ state->window = (unsigned char FAR *)
+ ZALLOC(strm, 1U << state->wbits,
+ sizeof(unsigned char));
+ if (state->window == Z_NULL) return 1;
+ }
+
+ /* if window not in use yet, initialize */
+ if (state->wsize == 0) {
+ state->wsize = 1U << state->wbits;
+ state->wnext = 0;
+ state->whave = 0;
+ }
+
+ /* copy state->wsize or less output bytes into the circular window */
+ if (copy >= state->wsize) {
+ zmemcpy(state->window, end - state->wsize, state->wsize);
+ state->wnext = 0;
+ state->whave = state->wsize;
+ }
+ else {
+ dist = state->wsize - state->wnext;
+ if (dist > copy) dist = copy;
+ zmemcpy(state->window + state->wnext, end - copy, dist);
+ copy -= dist;
+ if (copy) {
+ zmemcpy(state->window, end - copy, copy);
+ state->wnext = copy;
+ state->whave = state->wsize;
+ }
+ else {
+ state->wnext += dist;
+ if (state->wnext == state->wsize) state->wnext = 0;
+ if (state->whave < state->wsize) state->whave += dist;
+ }
+ }
+ return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+# define UPDATE(check, buf, len) \
+ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+# define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+# define CRC2(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ check = crc32(check, hbuf, 2); \
+ } while (0)
+
+# define CRC4(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ hbuf[2] = (unsigned char)((word) >> 16); \
+ hbuf[3] = (unsigned char)((word) >> 24); \
+ check = crc32(check, hbuf, 4); \
+ } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+ if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ if (have == 0) goto inf_leave; \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/*
+ inflate() uses a state machine to process as much input data and generate as
+ much output data as possible before returning. The state machine is
+ structured roughly as follows:
+
+ for (;;) switch (state) {
+ ...
+ case STATEn:
+ if (not enough input data or output space to make progress)
+ return;
+ ... make progress ...
+ state = STATEm;
+ break;
+ ...
+ }
+
+ so when inflate() is called again, the same case is attempted again, and
+ if the appropriate resources are provided, the machine proceeds to the
+ next state. The NEEDBITS() macro is usually the way the state evaluates
+ whether it can proceed or should return. NEEDBITS() does the return if
+ the requested bits are not available. The typical use of the BITS macros
+ is:
+
+ NEEDBITS(n);
+ ... do something with BITS(n) ...
+ DROPBITS(n);
+
+ where NEEDBITS(n) either returns from inflate() if there isn't enough
+ input left to load n bits into the accumulator, or it continues. BITS(n)
+ gives the low n bits in the accumulator. When done, DROPBITS(n) drops
+ the low n bits off the accumulator. INITBITS() clears the accumulator
+ and sets the number of available bits to zero. BYTEBITS() discards just
+ enough bits to put the accumulator on a byte boundary. After BYTEBITS()
+ and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+ NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+ if there is no input available. The decoding of variable length codes uses
+ PULLBYTE() directly in order to pull just enough bytes to decode the next
+ code, and no more.
+
+ Some states loop until they get enough input, making sure that enough
+ state information is maintained to continue the loop where it left off
+ if NEEDBITS() returns in the loop. For example, want, need, and keep
+ would all have to actually be part of the saved state in case NEEDBITS()
+ returns:
+
+ case STATEw:
+ while (want < need) {
+ NEEDBITS(n);
+ keep[want++] = BITS(n);
+ DROPBITS(n);
+ }
+ state = STATEx;
+ case STATEx:
+
+ As shown above, if the next state is also the next case, then the break
+ is omitted.
+
+ A state may also return if there is not enough output space available to
+ complete that state. Those states are copying stored data, writing a
+ literal byte, and copying a matching string.
+
+ When returning, a "goto inf_leave" is used to update the total counters,
+ update the check value, and determine whether any progress has been made
+ during that inflate() call in order to return the proper return code.
+ Progress is defined as a change in either strm->avail_in or strm->avail_out.
+ When there is a window, goto inf_leave will update the window with the last
+ output written. If a goto inf_leave occurs in the middle of decompression
+ and there is no window currently, goto inf_leave will create one and copy
+ output to the window for the next call of inflate().
+
+ In this implementation, the flush parameter of inflate() only affects the
+ return code (per zlib.h). inflate() always writes as much as possible to
+ strm->next_out, given the space available and the provided input--the effect
+ documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
+ the allocation of and copying into a sliding window until necessary, which
+ provides the effect documented in zlib.h for Z_FINISH when the entire input
+ stream available. So the only thing the flush parameter actually does is:
+ when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
+ will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+ struct inflate_state FAR *state;
+ z_const unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned in, out; /* save starting available input and output */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code here; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+#ifdef GUNZIP
+ unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
+#endif
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0))
+ return Z_STREAM_ERROR;
+
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
+ LOAD();
+ in = have;
+ out = left;
+ ret = Z_OK;
+ for (;;)
+ switch (state->mode) {
+ case HEAD:
+ if (state->wrap == 0) {
+ state->mode = TYPEDO;
+ break;
+ }
+ NEEDBITS(16);
+#ifdef GUNZIP
+ if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
+ if (state->wbits == 0)
+ state->wbits = 15;
+ state->check = crc32(0L, Z_NULL, 0);
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = FLAGS;
+ break;
+ }
+ state->flags = 0; /* expect zlib header */
+ if (state->head != Z_NULL)
+ state->head->done = -1;
+ if (!(state->wrap & 1) || /* check if zlib header allowed */
+#else
+ if (
+#endif
+ ((BITS(8) << 8) + (hold >> 8)) % 31) {
+ strm->msg = (char *)"incorrect header check";
+ state->mode = BAD;
+ break;
+ }
+ if (BITS(4) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ DROPBITS(4);
+ len = BITS(4) + 8;
+ if (state->wbits == 0)
+ state->wbits = len;
+ if (len > 15 || len > state->wbits) {
+ strm->msg = (char *)"invalid window size";
+ state->mode = BAD;
+ break;
+ }
+ state->dmax = 1U << len;
+ Tracev((stderr, "inflate: zlib header ok\n"));
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = hold & 0x200 ? DICTID : TYPE;
+ INITBITS();
+ break;
+#ifdef GUNZIP
+ case FLAGS:
+ NEEDBITS(16);
+ state->flags = (int)(hold);
+ if ((state->flags & 0xff) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ if (state->flags & 0xe000) {
+ strm->msg = (char *)"unknown header flags set";
+ state->mode = BAD;
+ break;
+ }
+ if (state->head != Z_NULL)
+ state->head->text = (int)((hold >> 8) & 1);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = TIME;
+ case TIME:
+ NEEDBITS(32);
+ if (state->head != Z_NULL)
+ state->head->time = hold;
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC4(state->check, hold);
+ INITBITS();
+ state->mode = OS;
+ case OS:
+ NEEDBITS(16);
+ if (state->head != Z_NULL) {
+ state->head->xflags = (int)(hold & 0xff);
+ state->head->os = (int)(hold >> 8);
+ }
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = EXLEN;
+ case EXLEN:
+ if (state->flags & 0x0400) {
+ NEEDBITS(16);
+ state->length = (unsigned)(hold);
+ if (state->head != Z_NULL)
+ state->head->extra_len = (unsigned)hold;
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC2(state->check, hold);
+ INITBITS();
+ }
+ else if (state->head != Z_NULL)
+ state->head->extra = Z_NULL;
+ state->mode = EXTRA;
+ case EXTRA:
+ if (state->flags & 0x0400) {
+ copy = state->length;
+ if (copy > have) copy = have;
+ if (copy) {
+ if (state->head != Z_NULL &&
+ state->head->extra != Z_NULL) {
+ len = state->head->extra_len - state->length;
+ zmemcpy(state->head->extra + len, next,
+ len + copy > state->head->extra_max ?
+ state->head->extra_max - len : copy);
+ }
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ state->length -= copy;
+ }
+ if (state->length) goto inf_leave;
+ }
+ state->length = 0;
+ state->mode = NAME;
+ case NAME:
+ if (state->flags & 0x0800) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->name != Z_NULL &&
+ state->length < state->head->name_max)
+ state->head->name[state->length++] = (Bytef)len;
+ } while (len && copy < have);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->name = Z_NULL;
+ state->length = 0;
+ state->mode = COMMENT;
+ case COMMENT:
+ if (state->flags & 0x1000) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->comment != Z_NULL &&
+ state->length < state->head->comm_max)
+ state->head->comment[state->length++] = (Bytef)len;
+ } while (len && copy < have);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->comment = Z_NULL;
+ state->mode = HCRC;
+ case HCRC:
+ if (state->flags & 0x0200) {
+ NEEDBITS(16);
+ if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
+ strm->msg = (char *)"header crc mismatch";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ }
+ if (state->head != Z_NULL) {
+ state->head->hcrc = (int)((state->flags >> 9) & 1);
+ state->head->done = 1;
+ }
+ strm->adler = state->check = crc32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ break;
+#endif
+ case DICTID:
+ NEEDBITS(32);
+ strm->adler = state->check = ZSWAP32(hold);
+ INITBITS();
+ state->mode = DICT;
+ case DICT:
+ if (state->havedict == 0) {
+ RESTORE();
+ return Z_NEED_DICT;
+ }
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ case TYPE:
+ if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+ case TYPEDO:
+ if (state->last) {
+ BYTEBITS();
+ state->mode = CHECK;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN_; /* decode codes */
+ if (flush == Z_TREES) {
+ DROPBITS(2);
+ goto inf_leave;
+ }
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+ case STORED:
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+ state->mode = COPY_;
+ if (flush == Z_TREES) goto inf_leave;
+ case COPY_:
+ state->mode = COPY;
+ case COPY:
+ copy = state->length;
+ if (copy) {
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ if (copy == 0) goto inf_leave;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ break;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ state->have = 0;
+ state->mode = LENLENS;
+ case LENLENS:
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (const code FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+ state->have = 0;
+ state->mode = CODELENS;
+ case CODELENS:
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.val < 16) {
+ DROPBITS(here.bits);
+ state->lens[state->have++] = here.val;
+ }
+ else {
+ if (here.val == 16) {
+ NEEDBITS(here.bits + 2);
+ DROPBITS(here.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = state->lens[state->have - 1];
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (here.val == 17) {
+ NEEDBITS(here.bits + 3);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(here.bits + 7);
+ DROPBITS(here.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* check for end-of-block code (better have one) */
+ if (state->lens[256] == 0) {
+ strm->msg = (char *)"invalid code -- missing end-of-block";
+ state->mode = BAD;
+ break;
+ }
+
+ /* build code tables -- note: do not change the lenbits or distbits
+ values here (9 and 6) without reading the comments in inftrees.h
+ concerning the ENOUGH constants, which depend on those values */
+ state->next = state->codes;
+ state->lencode = (const code FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (const code FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN_;
+ if (flush == Z_TREES) goto inf_leave;
+ case LEN_:
+ state->mode = LEN;
+ case LEN:
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ inflate_fast(strm, out);
+ LOAD();
+ if (state->mode == TYPE)
+ state->back = -1;
+ break;
+ }
+ state->back = 0;
+ for (;;) {
+ here = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (here.op && (here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ state->back += last.bits;
+ }
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ state->length = (unsigned)here.val;
+ if ((int)(here.op) == 0) {
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", here.val));
+ state->mode = LIT;
+ break;
+ }
+ if (here.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->back = -1;
+ state->mode = TYPE;
+ break;
+ }
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ state->extra = (unsigned)(here.op) & 15;
+ state->mode = LENEXT;
+ case LENEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ state->back += state->extra;
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->was = state->length;
+ state->mode = DIST;
+ case DIST:
+ for (;;) {
+ here = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((here.op & 0xf0) == 0) {
+ last = here;
+ for (;;) {
+ here = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + here.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ state->back += last.bits;
+ }
+ DROPBITS(here.bits);
+ state->back += here.bits;
+ if (here.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)here.val;
+ state->extra = (unsigned)(here.op) & 15;
+ state->mode = DISTEXT;
+ case DISTEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ state->back += state->extra;
+ }
+#ifdef INFLATE_STRICT
+ if (state->offset > state->dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+ state->mode = MATCH;
+ case MATCH:
+ if (left == 0) goto inf_leave;
+ copy = out - left;
+ if (state->offset > copy) { /* copy from window */
+ copy = state->offset - copy;
+ if (copy > state->whave) {
+ if (state->sane) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ Trace((stderr, "inflate.c too far\n"));
+ copy -= state->whave;
+ if (copy > state->length) copy = state->length;
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = 0;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+#endif
+ }
+ if (copy > state->wnext) {
+ copy -= state->wnext;
+ from = state->window + (state->wsize - copy);
+ }
+ else
+ from = state->window + (state->wnext - copy);
+ if (copy > state->length) copy = state->length;
+ }
+ else { /* copy from output */
+ from = put - state->offset;
+ copy = state->length;
+ }
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+ case LIT:
+ if (left == 0) goto inf_leave;
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ case CHECK:
+ if (state->wrap) {
+ NEEDBITS(32);
+ out -= left;
+ strm->total_out += out;
+ state->total += out;
+ if ((state->wrap & 4) && out)
+ strm->adler = state->check =
+ UPDATE(state->check, put - out, out);
+ out = left;
+ if ((state->wrap & 4) && (
+#ifdef GUNZIP
+ state->flags ? hold :
+#endif
+ ZSWAP32(hold)) != state->check) {
+ strm->msg = (char *)"incorrect data check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: check matches trailer\n"));
+ }
+#ifdef GUNZIP
+ state->mode = LENGTH;
+ case LENGTH:
+ if (state->wrap && state->flags) {
+ NEEDBITS(32);
+ if (hold != (state->total & 0xffffffffUL)) {
+ strm->msg = (char *)"incorrect length check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: length matches trailer\n"));
+ }
+#endif
+ state->mode = DONE;
+ case DONE:
+ ret = Z_STREAM_END;
+ goto inf_leave;
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+ case MEM:
+ return Z_MEM_ERROR;
+ case SYNC:
+ default:
+ return Z_STREAM_ERROR;
+ }
+
+ /*
+ Return from inflate(), updating the total counts and the check value.
+ If there was no progress during the inflate() call, return a buffer
+ error. Call updatewindow() to create and/or update the window state.
+ Note: a memory error from inflate() is non-recoverable.
+ */
+ inf_leave:
+ RESTORE();
+ if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
+ (state->mode < CHECK || flush != Z_FINISH)))
+ if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ in -= strm->avail_in;
+ out -= strm->avail_out;
+ strm->total_in += in;
+ strm->total_out += out;
+ state->total += out;
+ if ((state->wrap & 4) && out)
+ strm->adler = state->check =
+ UPDATE(state->check, strm->next_out - out, out);
+ strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
+ (state->mode == TYPE ? 128 : 0) +
+ (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
+ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+ ret = Z_BUF_ERROR;
+ return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (inflateStateCheck(strm))
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->window != Z_NULL) ZFREE(strm, state->window);
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+Bytef *dictionary;
+uInt *dictLength;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* copy dictionary */
+ if (state->whave && dictionary != Z_NULL) {
+ zmemcpy(dictionary, state->window + state->wnext,
+ state->whave - state->wnext);
+ zmemcpy(dictionary + state->whave - state->wnext,
+ state->window, state->wnext);
+ }
+ if (dictLength != Z_NULL)
+ *dictLength = state->whave;
+ return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+ struct inflate_state FAR *state;
+ unsigned long dictid;
+ int ret;
+
+ /* check state */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->wrap != 0 && state->mode != DICT)
+ return Z_STREAM_ERROR;
+
+ /* check for correct dictionary identifier */
+ if (state->mode == DICT) {
+ dictid = adler32(0L, Z_NULL, 0);
+ dictid = adler32(dictid, dictionary, dictLength);
+ if (dictid != state->check)
+ return Z_DATA_ERROR;
+ }
+
+ /* copy dictionary to window using updatewindow(), which will amend the
+ existing dictionary if appropriate */
+ ret = updatewindow(strm, dictionary + dictLength, dictLength);
+ if (ret) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ state->havedict = 1;
+ Tracev((stderr, "inflate: dictionary set\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+ /* save header structure */
+ state->head = head;
+ head->done = 0;
+ return Z_OK;
+}
+
+/*
+ Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
+ or when out of input. When called, *have is the number of pattern bytes
+ found in order so far, in 0..3. On return *have is updated to the new
+ state. If on return *have equals four, then the pattern was found and the
+ return value is how many bytes were read including the last byte of the
+ pattern. If *have is less than four, then the pattern has not been found
+ yet and the return value is len. In the latter case, syncsearch() can be
+ called again with more data and the *have state. *have is initialized to
+ zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+const unsigned char FAR *buf;
+unsigned len;
+{
+ unsigned got;
+ unsigned next;
+
+ got = *have;
+ next = 0;
+ while (next < len && got < 4) {
+ if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+ got++;
+ else if (buf[next])
+ got = 0;
+ else
+ got = 4 - got;
+ next++;
+ }
+ *have = got;
+ return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+ unsigned len; /* number of bytes to look at or looked at */
+ unsigned long in, out; /* temporary to save total_in and total_out */
+ unsigned char buf[4]; /* to restore bit buffer to byte string */
+ struct inflate_state FAR *state;
+
+ /* check parameters */
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+ /* if first time, start search in bit buffer */
+ if (state->mode != SYNC) {
+ state->mode = SYNC;
+ state->hold <<= state->bits & 7;
+ state->bits -= state->bits & 7;
+ len = 0;
+ while (state->bits >= 8) {
+ buf[len++] = (unsigned char)(state->hold);
+ state->hold >>= 8;
+ state->bits -= 8;
+ }
+ state->have = 0;
+ syncsearch(&(state->have), buf, len);
+ }
+
+ /* search available input */
+ len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+ strm->avail_in -= len;
+ strm->next_in += len;
+ strm->total_in += len;
+
+ /* return no joy or set up to restart inflate() on a new block */
+ if (state->have != 4) return Z_DATA_ERROR;
+ in = strm->total_in; out = strm->total_out;
+ inflateReset(strm);
+ strm->total_in = in; strm->total_out = out;
+ state->mode = TYPE;
+ return Z_OK;
+}
+
+/*
+ Returns true if inflate is currently at the end of a block generated by
+ Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ implementation to provide an additional safety check. PPP uses
+ Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+ block. When decompressing, PPP checks that at the end of input packet,
+ inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+ struct inflate_state FAR *state;
+ struct inflate_state FAR *copy;
+ unsigned char FAR *window;
+ unsigned wsize;
+
+ /* check input */
+ if (inflateStateCheck(source) || dest == Z_NULL)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)source->state;
+
+ /* allocate space */
+ copy = (struct inflate_state FAR *)
+ ZALLOC(source, 1, sizeof(struct inflate_state));
+ if (copy == Z_NULL) return Z_MEM_ERROR;
+ window = Z_NULL;
+ if (state->window != Z_NULL) {
+ window = (unsigned char FAR *)
+ ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+ if (window == Z_NULL) {
+ ZFREE(source, copy);
+ return Z_MEM_ERROR;
+ }
+ }
+
+ /* copy state */
+ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+ zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
+ copy->strm = dest;
+ if (state->lencode >= state->codes &&
+ state->lencode <= state->codes + ENOUGH - 1) {
+ copy->lencode = copy->codes + (state->lencode - state->codes);
+ copy->distcode = copy->codes + (state->distcode - state->codes);
+ }
+ copy->next = copy->codes + (state->next - state->codes);
+ if (window != Z_NULL) {
+ wsize = 1U << state->wbits;
+ zmemcpy(window, state->window, wsize);
+ }
+ copy->window = window;
+ dest->state = (struct internal_state FAR *)copy;
+ return Z_OK;
+}
+
+int ZEXPORT inflateUndermine(strm, subvert)
+z_streamp strm;
+int subvert;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ state->sane = !subvert;
+ return Z_OK;
+#else
+ (void)subvert;
+ state->sane = 1;
+ return Z_DATA_ERROR;
+#endif
+}
+
+int ZEXPORT inflateValidate(strm, check)
+z_streamp strm;
+int check;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (check)
+ state->wrap |= 4;
+ else
+ state->wrap &= ~4;
+ return Z_OK;
+}
+
+long ZEXPORT inflateMark(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (inflateStateCheck(strm))
+ return -(1L << 16);
+ state = (struct inflate_state FAR *)strm->state;
+ return (long)(((unsigned long)((long)state->back)) << 16) +
+ (state->mode == COPY ? state->length :
+ (state->mode == MATCH ? state->was - state->length : 0));
+}
+
+unsigned long ZEXPORT inflateCodesUsed(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (inflateStateCheck(strm)) return (unsigned long)-1;
+ state = (struct inflate_state FAR *)strm->state;
+ return (unsigned long)(state->next - state->codes);
+}
diff --git a/xs/src/png/zlib/inflate.h b/xs/src/png/zlib/inflate.h
new file mode 100644
index 000000000..a46cce6b6
--- /dev/null
+++ b/xs/src/png/zlib/inflate.h
@@ -0,0 +1,125 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip decoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+ HEAD = 16180, /* i: waiting for magic header */
+ FLAGS, /* i: waiting for method and flags (gzip) */
+ TIME, /* i: waiting for modification time (gzip) */
+ OS, /* i: waiting for extra flags and operating system (gzip) */
+ EXLEN, /* i: waiting for extra length (gzip) */
+ EXTRA, /* i: waiting for extra bytes (gzip) */
+ NAME, /* i: waiting for end of file name (gzip) */
+ COMMENT, /* i: waiting for end of comment (gzip) */
+ HCRC, /* i: waiting for header crc (gzip) */
+ DICTID, /* i: waiting for dictionary check value */
+ DICT, /* waiting for inflateSetDictionary() call */
+ TYPE, /* i: waiting for type bits, including last-flag bit */
+ TYPEDO, /* i: same, but skip check to exit inflate on new block */
+ STORED, /* i: waiting for stored size (length and complement) */
+ COPY_, /* i/o: same as COPY below, but only first time in */
+ COPY, /* i/o: waiting for input or output to copy stored block */
+ TABLE, /* i: waiting for dynamic block table lengths */
+ LENLENS, /* i: waiting for code length code lengths */
+ CODELENS, /* i: waiting for length/lit and distance code lengths */
+ LEN_, /* i: same as LEN below, but only first time in */
+ LEN, /* i: waiting for length/lit/eob code */
+ LENEXT, /* i: waiting for length extra bits */
+ DIST, /* i: waiting for distance code */
+ DISTEXT, /* i: waiting for distance extra bits */
+ MATCH, /* o: waiting for output space to copy string */
+ LIT, /* o: waiting for output space to write literal */
+ CHECK, /* i: waiting for 32-bit check value */
+ LENGTH, /* i: waiting for 32-bit length (gzip) */
+ DONE, /* finished check, done -- remain here until reset */
+ BAD, /* got a data error -- remain here until reset */
+ MEM, /* got an inflate() memory error -- remain here until reset */
+ SYNC /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+ State transitions between above modes -
+
+ (most modes can go to BAD or MEM on error -- not shown for clarity)
+
+ Process header:
+ HEAD -> (gzip) or (zlib) or (raw)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+ HCRC -> TYPE
+ (zlib) -> DICTID or TYPE
+ DICTID -> DICT -> TYPE
+ (raw) -> TYPEDO
+ Read deflate blocks:
+ TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+ STORED -> COPY_ -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN_
+ LEN_ -> LEN
+ Read deflate codes in fixed or dynamic block:
+ LEN -> LENEXT or LIT or TYPE
+ LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+ LIT -> LEN
+ Process trailer:
+ CHECK -> LENGTH -> DONE
+ */
+
+/* State maintained between inflate() calls -- approximately 7K bytes, not
+ including the allocated sliding window, which is up to 32K bytes. */
+struct inflate_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ inflate_mode mode; /* current inflate mode */
+ int last; /* true if processing last block */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
+ bit 2 true to validate check value */
+ int havedict; /* true if dictionary provided */
+ int flags; /* gzip header method and flags (0 if zlib) */
+ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
+ unsigned long check; /* protected copy of check value */
+ unsigned long total; /* protected copy of output count */
+ gz_headerp head; /* where to save gzip header information */
+ /* sliding window */
+ unsigned wbits; /* log base 2 of requested window size */
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned wnext; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ /* bit accumulator */
+ unsigned long hold; /* input bit accumulator */
+ unsigned bits; /* number of bits in "in" */
+ /* for string and stored block copying */
+ unsigned length; /* literal or length of data to copy */
+ unsigned offset; /* distance back to copy string from */
+ /* for table and code decoding */
+ unsigned extra; /* extra bits needed */
+ /* fixed and dynamic code tables */
+ code const FAR *lencode; /* starting table for length/literal codes */
+ code const FAR *distcode; /* starting table for distance codes */
+ unsigned lenbits; /* index bits for lencode */
+ unsigned distbits; /* index bits for distcode */
+ /* dynamic table building */
+ unsigned ncode; /* number of code length code lengths */
+ unsigned nlen; /* number of length code lengths */
+ unsigned ndist; /* number of distance code lengths */
+ unsigned have; /* number of code lengths in lens[] */
+ code FAR *next; /* next available space in codes[] */
+ unsigned short lens[320]; /* temporary storage for code lengths */
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
+ int sane; /* if false, allow invalid distance too far */
+ int back; /* bits back of last unprocessed length/lit */
+ unsigned was; /* initial length of match */
+};
diff --git a/xs/src/png/zlib/inftrees.c b/xs/src/png/zlib/inftrees.c
new file mode 100644
index 000000000..2ea08fc13
--- /dev/null
+++ b/xs/src/png/zlib/inftrees.c
@@ -0,0 +1,304 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+ " inflate 1.2.11 Copyright 1995-2017 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/*
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+ */
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+ unsigned len; /* a code's length in bits */
+ unsigned sym; /* index of code symbols */
+ unsigned min, max; /* minimum and maximum code lengths */
+ unsigned root; /* number of index bits for root table */
+ unsigned curr; /* number of index bits for current table */
+ unsigned drop; /* code bits to drop for sub-table */
+ int left; /* number of prefix codes available */
+ unsigned used; /* code entries in table used */
+ unsigned huff; /* Huffman code */
+ unsigned incr; /* for incrementing code, index */
+ unsigned fill; /* index for replicating entries */
+ unsigned low; /* low bits for current root entry */
+ unsigned mask; /* mask for low root bits */
+ code here; /* table entry for duplication */
+ code FAR *next; /* next available space in table */
+ const unsigned short FAR *base; /* base value table to use */
+ const unsigned short FAR *extra; /* extra bits table to use */
+ unsigned match; /* use base and extra for symbol >= match */
+ unsigned short count[MAXBITS+1]; /* number of codes of each length */
+ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
+ static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202};
+ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577, 0, 0};
+ static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+ 28, 28, 29, 29, 64, 64};
+
+ /*
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+
+ The length counts are used for other purposes as well, i.e. finding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ */
+
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ for (len = 0; len <= MAXBITS; len++)
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[sym]]++;
+
+ /* bound code lengths, force root to be within code lengths */
+ root = *bits;
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) { /* no symbols to code at all */
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)1;
+ here.val = (unsigned short)0;
+ *(*table)++ = here; /* make a table to force an error */
+ *(*table)++ = here;
+ *bits = 1;
+ return 0; /* no symbols, but wait for decoding to report error */
+ }
+ for (min = 1; min < max; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1;
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ }
+ if (left > 0 && (type == CODES || max != 1))
+ return -1; /* incomplete set */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + count[len];
+
+ /* sort symbols by length, by symbol order within each length */
+ for (sym = 0; sym < codes; sym++)
+ if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+ /*
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked for LENS and DIST tables against
+ the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+ the initial root table size constants. See the comments in inftrees.h
+ for more information.
+
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ */
+
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ match = 20;
+ break;
+ case LENS:
+ base = lbase;
+ extra = lext;
+ match = 257;
+ break;
+ default: /* DISTS */
+ base = dbase;
+ extra = dext;
+ match = 0;
+ }
+
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = *table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = (unsigned)(-1); /* trigger new sub-table when len > root */
+ used = 1U << root; /* use root table entries */
+ mask = used - 1; /* mask for comparing low */
+
+ /* check available table space */
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
+ return 1;
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ here.bits = (unsigned char)(len - drop);
+ if (work[sym] + 1U < match) {
+ here.op = (unsigned char)0;
+ here.val = work[sym];
+ }
+ else if (work[sym] >= match) {
+ here.op = (unsigned char)(extra[work[sym] - match]);
+ here.val = base[work[sym] - match];
+ }
+ else {
+ here.op = (unsigned char)(32 + 64); /* end of block */
+ here.val = 0;
+ }
+
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1U << (len - drop);
+ fill = 1U << curr;
+ min = fill; /* save offset to next table */
+ do {
+ fill -= incr;
+ next[(huff >> drop) + fill] = here;
+ } while (fill != 0);
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[work[sym]];
+ }
+
+ /* create new sub-table if needed */
+ if (len > root && (huff & mask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+
+ /* increment past last table */
+ next += min; /* here min is 1 << curr */
+
+ /* determine length of next table */
+ curr = len - drop;
+ left = (int)(1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ left <<= 1;
+ }
+
+ /* check for enough space */
+ used += 1U << curr;
+ if ((type == LENS && used > ENOUGH_LENS) ||
+ (type == DISTS && used > ENOUGH_DISTS))
+ return 1;
+
+ /* point entry in root table to sub-table */
+ low = huff & mask;
+ (*table)[low].op = (unsigned char)curr;
+ (*table)[low].bits = (unsigned char)root;
+ (*table)[low].val = (unsigned short)(next - *table);
+ }
+ }
+
+ /* fill in remaining table entry if code is incomplete (guaranteed to have
+ at most one remaining entry, since if the code is incomplete, the
+ maximum code length that was allowed to get this far is one bit) */
+ if (huff != 0) {
+ here.op = (unsigned char)64; /* invalid code marker */
+ here.bits = (unsigned char)(len - drop);
+ here.val = (unsigned short)0;
+ next[huff] = here;
+ }
+
+ /* set return parameters */
+ *table += used;
+ *bits = root;
+ return 0;
+}
diff --git a/xs/src/png/zlib/inftrees.h b/xs/src/png/zlib/inftrees.h
new file mode 100644
index 000000000..baa53a0b1
--- /dev/null
+++ b/xs/src/png/zlib/inftrees.h
@@ -0,0 +1,62 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables. Each entry provides either the
+ information needed to do the operation requested by the code that
+ indexed that table entry, or it provides a pointer to another
+ table that indexes more bits of the code. op indicates whether
+ the entry is a pointer to another table, a literal, a length or
+ distance, an end-of-block, or an invalid code. For a table
+ pointer, the low four bits of op is the number of index bits of
+ that table. For a length or distance, the low four bits of op
+ is the number of extra bits to get after the code. bits is
+ the number of bits in this code or part of the code to drop off
+ of the bit buffer. val is the actual byte to output in the case
+ of a literal, the base length or distance, or the offset from
+ the current table to the next table. Each entry is four bytes. */
+typedef struct {
+ unsigned char op; /* operation, extra bits, table bits */
+ unsigned char bits; /* bits in this part of the code */
+ unsigned short val; /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+ 00000000 - literal
+ 0000tttt - table link, tttt != 0 is the number of table index bits
+ 0001eeee - length or distance, eeee is the number of extra bits
+ 01100000 - end of block
+ 01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table. The maximum number of code structures is
+ 1444, which is the sum of 852 for literal/length codes and 592 for distance
+ codes. These values were found by exhaustive searches using the program
+ examples/enough.c found in the zlib distribtution. The arguments to that
+ program are the number of symbols, the initial root table size, and the
+ maximum bit length of a code. "enough 286 9 15" for literal/length codes
+ returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+ The initial root table size (9 or 6) is found in the fifth argument of the
+ inflate_table() calls in inflate.c and infback.c. If the root table size is
+ changed, then these maximum sizes would be need to be recalculated and
+ updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table() */
+typedef enum {
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
diff --git a/xs/src/png/zlib/make_vms.com b/xs/src/png/zlib/make_vms.com
new file mode 100644
index 000000000..65e9d0cbc
--- /dev/null
+++ b/xs/src/png/zlib/make_vms.com
@@ -0,0 +1,867 @@
+$! make libz under VMS written by
+$! Martin P.J. Zinser
+$!
+$! In case of problems with the install you might contact me at
+$! zinser@zinser.no-ip.info(preferred) or
+$! martin.zinser@eurexchange.com (work)
+$!
+$! Make procedure history for Zlib
+$!
+$!------------------------------------------------------------------------------
+$! Version history
+$! 0.01 20060120 First version to receive a number
+$! 0.02 20061008 Adapt to new Makefile.in
+$! 0.03 20091224 Add support for large file check
+$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite
+$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in
+$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new exmples
+$! subdir path, update module search in makefile.in
+$! 0.07 20120115 Triggered by work done by Alexey Chupahin completly redesigned
+$! shared image creation
+$! 0.08 20120219 Make it work on VAX again, pre-load missing symbols to shared
+$! image
+$! 0.09 20120305 SMS. P1 sets builder ("MMK", "MMS", " " (built-in)).
+$! "" -> automatic, preference: MMK, MMS, built-in.
+$!
+$ on error then goto err_exit
+$!
+$ true = 1
+$ false = 0
+$ tmpnam = "temp_" + f$getjpi("","pid")
+$ tt = tmpnam + ".txt"
+$ tc = tmpnam + ".c"
+$ th = tmpnam + ".h"
+$ define/nolog tconfig 'th'
+$ its_decc = false
+$ its_vaxc = false
+$ its_gnuc = false
+$ s_case = False
+$!
+$! Setup variables holding "config" information
+$!
+$ Make = "''p1'"
+$ name = "Zlib"
+$ version = "?.?.?"
+$ v_string = "ZLIB_VERSION"
+$ v_file = "zlib.h"
+$ ccopt = "/include = []"
+$ lopts = ""
+$ dnsrl = ""
+$ aconf_in_file = "zconf.h.in#zconf.h_in#zconf_h.in"
+$ conf_check_string = ""
+$ linkonly = false
+$ optfile = name + ".opt"
+$ mapfile = name + ".map"
+$ libdefs = ""
+$ vax = f$getsyi("HW_MODEL").lt.1024
+$ axp = f$getsyi("HW_MODEL").ge.1024 .and. f$getsyi("HW_MODEL").lt.4096
+$ ia64 = f$getsyi("HW_MODEL").ge.4096
+$!
+$! 2012-03-05 SMS.
+$! Why is this needed? And if it is needed, why not simply ".not. vax"?
+$!
+$!!! if axp .or. ia64 then set proc/parse=extended
+$!
+$ whoami = f$parse(f$environment("Procedure"),,,,"NO_CONCEAL")
+$ mydef = F$parse(whoami,,,"DEVICE")
+$ mydir = f$parse(whoami,,,"DIRECTORY") - "]["
+$ myproc = f$parse(whoami,,,"Name") + f$parse(whoami,,,"type")
+$!
+$! Check for MMK/MMS
+$!
+$ if (Make .eqs. "")
+$ then
+$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS"
+$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK"
+$ else
+$ Make = f$edit( Make, "trim")
+$ endif
+$!
+$ gosub find_version
+$!
+$ open/write topt tmp.opt
+$ open/write optf 'optfile'
+$!
+$ gosub check_opts
+$!
+$! Look for the compiler used
+$!
+$ gosub check_compiler
+$ close topt
+$ close optf
+$!
+$ if its_decc
+$ then
+$ ccopt = "/prefix=all" + ccopt
+$ if f$trnlnm("SYS") .eqs. ""
+$ then
+$ if axp
+$ then
+$ define sys sys$library:
+$ else
+$ ccopt = "/decc" + ccopt
+$ define sys decc$library_include:
+$ endif
+$ endif
+$!
+$! 2012-03-05 SMS.
+$! Why /NAMES = AS_IS? Why not simply ".not. vax"? And why not on VAX?
+$!
+$ if axp .or. ia64
+$ then
+$ ccopt = ccopt + "/name=as_is/opt=(inline=speed)"
+$ s_case = true
+$ endif
+$ endif
+$ if its_vaxc .or. its_gnuc
+$ then
+$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$ endif
+$!
+$! Build a fake configure input header
+$!
+$ open/write conf_hin config.hin
+$ write conf_hin "#undef _LARGEFILE64_SOURCE"
+$ close conf_hin
+$!
+$!
+$ i = 0
+$FIND_ACONF:
+$ fname = f$element(i,"#",aconf_in_file)
+$ if fname .eqs. "#" then goto AMISS_ERR
+$ if f$search(fname) .eqs. ""
+$ then
+$ i = i + 1
+$ goto find_aconf
+$ endif
+$ open/read/err=aconf_err aconf_in 'fname'
+$ open/write aconf zconf.h
+$ACONF_LOOP:
+$ read/end_of_file=aconf_exit aconf_in line
+$ work = f$edit(line, "compress,trim")
+$ if f$extract(0,6,work) .nes. "#undef"
+$ then
+$ if f$extract(0,12,work) .nes. "#cmakedefine"
+$ then
+$ write aconf line
+$ endif
+$ else
+$ cdef = f$element(1," ",work)
+$ gosub check_config
+$ endif
+$ goto aconf_loop
+$ACONF_EXIT:
+$ write aconf ""
+$ write aconf "/* VMS specifics added by make_vms.com: */"
+$ write aconf "#define VMS 1"
+$ write aconf "#include <unistd.h>"
+$ write aconf "#include <unixio.h>"
+$ write aconf "#ifdef _LARGEFILE"
+$ write aconf "# define off64_t __off64_t"
+$ write aconf "# define fopen64 fopen"
+$ write aconf "# define fseeko64 fseeko"
+$ write aconf "# define lseek64 lseek"
+$ write aconf "# define ftello64 ftell"
+$ write aconf "#endif"
+$ write aconf "#if !defined( __VAX) && (__CRTL_VER >= 70312000)"
+$ write aconf "# define HAVE_VSNPRINTF"
+$ write aconf "#endif"
+$ close aconf_in
+$ close aconf
+$ if f$search("''th'") .nes. "" then delete 'th';*
+$! Build the thing plain or with mms
+$!
+$ write sys$output "Compiling Zlib sources ..."
+$ if make.eqs.""
+$ then
+$ if (f$search( "example.obj;*") .nes. "") then delete example.obj;*
+$ if (f$search( "minigzip.obj;*") .nes. "") then delete minigzip.obj;*
+$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
+ adler32.c zlib.h zconf.h
+$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
+ compress.c zlib.h zconf.h
+$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
+ crc32.c zlib.h zconf.h
+$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
+ deflate.c deflate.h zutil.h zlib.h zconf.h
+$ CALL MAKE gzclose.OBJ "CC ''CCOPT' gzclose" -
+ gzclose.c zutil.h zlib.h zconf.h
+$ CALL MAKE gzlib.OBJ "CC ''CCOPT' gzlib" -
+ gzlib.c zutil.h zlib.h zconf.h
+$ CALL MAKE gzread.OBJ "CC ''CCOPT' gzread" -
+ gzread.c zutil.h zlib.h zconf.h
+$ CALL MAKE gzwrite.OBJ "CC ''CCOPT' gzwrite" -
+ gzwrite.c zutil.h zlib.h zconf.h
+$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
+ infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
+ inffast.c zutil.h zlib.h zconf.h inffast.h
+$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
+ inflate.c zutil.h zlib.h zconf.h infblock.h
+$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
+ inftrees.c zutil.h zlib.h zconf.h inftrees.h
+$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
+ trees.c deflate.h zutil.h zlib.h zconf.h
+$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
+ uncompr.c zlib.h zconf.h
+$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
+ zutil.c zutil.h zlib.h zconf.h
+$ write sys$output "Building Zlib ..."
+$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
+$ write sys$output "Building example..."
+$ CALL MAKE example.OBJ "CC ''CCOPT' [.test]example" -
+ [.test]example.c zlib.h zconf.h
+$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
+$ write sys$output "Building minigzip..."
+$ CALL MAKE minigzip.OBJ "CC ''CCOPT' [.test]minigzip" -
+ [.test]minigzip.c zlib.h zconf.h
+$ call make minigzip.exe -
+ "LINK minigzip,libz.olb/lib" -
+ minigzip.obj libz.olb
+$ else
+$ gosub crea_mms
+$ write sys$output "Make ''name' ''version' with ''Make' "
+$ 'make'
+$ endif
+$!
+$! Create shareable image
+$!
+$ gosub crea_olist
+$ write sys$output "Creating libzshr.exe"
+$ call map_2_shopt 'mapfile' 'optfile'
+$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,'optfile'/opt
+$ write sys$output "Zlib build completed"
+$ delete/nolog tmp.opt;*
+$ exit
+$AMISS_ERR:
+$ write sys$output "No source for config.hin found."
+$ write sys$output "Tried any of ''aconf_in_file'"
+$ goto err_exit
+$CC_ERR:
+$ write sys$output "C compiler required to build ''name'"
+$ goto err_exit
+$ERR_EXIT:
+$ set message/facil/ident/sever/text
+$ close/nolog optf
+$ close/nolog topt
+$ close/nolog aconf_in
+$ close/nolog aconf
+$ close/nolog out
+$ close/nolog min
+$ close/nolog mod
+$ close/nolog h_in
+$ write sys$output "Exiting..."
+$ exit 2
+$!
+$!
+$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES
+$ V = 'F$Verify(0)
+$! P1 = What we are trying to make
+$! P2 = Command to make it
+$! P3 - P8 What it depends on
+$
+$ If F$Search(P1) .Eqs. "" Then Goto Makeit
+$ Time = F$CvTime(F$File(P1,"RDT"))
+$arg=3
+$Loop:
+$ Argument = P'arg
+$ If Argument .Eqs. "" Then Goto Exit
+$ El=0
+$Loop2:
+$ File = F$Element(El," ",Argument)
+$ If File .Eqs. " " Then Goto Endl
+$ AFile = ""
+$Loop3:
+$ OFile = AFile
+$ AFile = F$Search(File)
+$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
+$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
+$ Goto Loop3
+$NextEL:
+$ El = El + 1
+$ Goto Loop2
+$EndL:
+$ arg=arg+1
+$ If arg .Le. 8 Then Goto Loop
+$ Goto Exit
+$
+$Makeit:
+$ VV=F$VERIFY(0)
+$ write sys$output P2
+$ 'P2
+$ VV='F$Verify(VV)
+$Exit:
+$ If V Then Set Verify
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Check command line options and set symbols accordingly
+$!
+$!------------------------------------------------------------------------------
+$! Version history
+$! 0.01 20041206 First version to receive a number
+$! 0.02 20060126 Add new "HELP" target
+$ CHECK_OPTS:
+$ i = 1
+$ OPT_LOOP:
+$ if i .lt. 9
+$ then
+$ cparm = f$edit(p'i',"upcase")
+$!
+$! Check if parameter actually contains something
+$!
+$ if f$edit(cparm,"trim") .nes. ""
+$ then
+$ if cparm .eqs. "DEBUG"
+$ then
+$ ccopt = ccopt + "/noopt/deb"
+$ lopts = lopts + "/deb"
+$ endif
+$ if f$locate("CCOPT=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ ccopt = ccopt + f$extract(start,len,cparm)
+$ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) -
+ then s_case = true
+$ endif
+$ if cparm .eqs. "LINK" then linkonly = true
+$ if f$locate("LOPTS=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ lopts = lopts + f$extract(start,len,cparm)
+$ endif
+$ if f$locate("CC=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ cc_com = f$extract(start,len,cparm)
+ if (cc_com .nes. "DECC") .and. -
+ (cc_com .nes. "VAXC") .and. -
+ (cc_com .nes. "GNUC")
+$ then
+$ write sys$output "Unsupported compiler choice ''cc_com' ignored"
+$ write sys$output "Use DECC, VAXC, or GNUC instead"
+$ else
+$ if cc_com .eqs. "DECC" then its_decc = true
+$ if cc_com .eqs. "VAXC" then its_vaxc = true
+$ if cc_com .eqs. "GNUC" then its_gnuc = true
+$ endif
+$ endif
+$ if f$locate("MAKE=",cparm) .lt. f$length(cparm)
+$ then
+$ start = f$locate("=",cparm) + 1
+$ len = f$length(cparm) - start
+$ mmks = f$extract(start,len,cparm)
+$ if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS")
+$ then
+$ make = mmks
+$ else
+$ write sys$output "Unsupported make choice ''mmks' ignored"
+$ write sys$output "Use MMK or MMS instead"
+$ endif
+$ endif
+$ if cparm .eqs. "HELP" then gosub bhelp
+$ endif
+$ i = i + 1
+$ goto opt_loop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Look for the compiler used
+$!
+$! Version history
+$! 0.01 20040223 First version to receive a number
+$! 0.02 20040229 Save/set value of decc$no_rooted_search_lists
+$! 0.03 20060202 Extend handling of GNU C
+$! 0.04 20090402 Compaq -> hp
+$CHECK_COMPILER:
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then
+$ its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "")
+$ its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "")
+$ its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "")
+$ endif
+$!
+$! Exit if no compiler available
+$!
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then goto CC_ERR
+$ else
+$ if its_decc
+$ then
+$ write sys$output "CC compiler check ... hp C"
+$ if f$trnlnm("decc$no_rooted_search_lists") .nes. ""
+$ then
+$ dnrsl = f$trnlnm("decc$no_rooted_search_lists")
+$ endif
+$ define/nolog decc$no_rooted_search_lists 1
+$ else
+$ if its_vaxc then write sys$output "CC compiler check ... VAX C"
+$ if its_gnuc
+$ then
+$ write sys$output "CC compiler check ... GNU C"
+$ if f$trnlnm(topt) then write topt "gnu_cc:[000000]gcclib.olb/lib"
+$ if f$trnlnm(optf) then write optf "gnu_cc:[000000]gcclib.olb/lib"
+$ cc = "gcc"
+$ endif
+$ if f$trnlnm(topt) then write topt "sys$share:vaxcrtl.exe/share"
+$ if f$trnlnm(optf) then write optf "sys$share:vaxcrtl.exe/share"
+$ endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! If MMS/MMK are available dump out the descrip.mms if required
+$!
+$CREA_MMS:
+$ write sys$output "Creating descrip.mms..."
+$ create descrip.mms
+$ open/append out descrip.mms
+$ copy sys$input: out
+$ deck
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser
+# <zinser@zinser.no-ip.info or martin.zinser@eurexchange.com>
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\
+ gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\
+ deflate.obj, trees.obj, zutil.obj, inflate.obj, \
+ inftrees.obj, inffast.obj
+
+$ eod
+$ write out "CFLAGS=", ccopt
+$ write out "LOPTS=", lopts
+$ write out "all : example.exe minigzip.exe libz.olb"
+$ copy sys$input: out
+$ deck
+ @ write sys$output " Example applications available"
+
+libz.olb : libz.olb($(OBJS))
+ @ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+ link $(LOPTS) example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+ link $(LOPTS) minigzip,libz.olb/lib
+
+clean :
+ delete *.obj;*,libz.olb;*,*.opt;*,*.exe;*
+
+
+# Other dependencies.
+adler32.obj : adler32.c zutil.h zlib.h zconf.h
+compress.obj : compress.c zlib.h zconf.h
+crc32.obj : crc32.c zutil.h zlib.h zconf.h
+deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h
+example.obj : [.test]example.c zlib.h zconf.h
+gzclose.obj : gzclose.c zutil.h zlib.h zconf.h
+gzlib.obj : gzlib.c zutil.h zlib.h zconf.h
+gzread.obj : gzread.c zutil.h zlib.h zconf.h
+gzwrite.obj : gzwrite.c zutil.h zlib.h zconf.h
+inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h
+inflate.obj : inflate.c zutil.h zlib.h zconf.h
+inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h
+minigzip.obj : [.test]minigzip.c zlib.h zconf.h
+trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h
+uncompr.obj : uncompr.c zlib.h zconf.h
+zutil.obj : zutil.c zutil.h zlib.h zconf.h
+infback.obj : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$ eod
+$ close out
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Read list of core library sources from makefile.in and create options
+$! needed to build shareable image
+$!
+$CREA_OLIST:
+$ open/read min makefile.in
+$ open/write mod modules.opt
+$ src_check_list = "OBJZ =#OBJG ="
+$MRLOOP:
+$ read/end=mrdone min rec
+$ i = 0
+$SRC_CHECK_LOOP:
+$ src_check = f$element(i, "#", src_check_list)
+$ i = i+1
+$ if src_check .eqs. "#" then goto mrloop
+$ if (f$extract(0,6,rec) .nes. src_check) then goto src_check_loop
+$ rec = rec - src_check
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .eqs. "\") then goto mrloop
+$MRSLOOP:
+$ read/end=mrdone min rec
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop
+$MRDONE:
+$ close min
+$ close mod
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Take record extracted in crea_olist and split it into single filenames
+$!
+$EXTRA_FILNAM:
+$ myrec = f$edit(rec - "\", "trim,compress")
+$ i = 0
+$FELOOP:
+$ srcfil = f$element(i," ", myrec)
+$ if (srcfil .nes. " ")
+$ then
+$ write mod f$parse(srcfil,,,"NAME"), ".obj"
+$ i = i + 1
+$ goto feloop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Find current Zlib version number
+$!
+$FIND_VERSION:
+$ open/read h_in 'v_file'
+$hloop:
+$ read/end=hdone h_in rec
+$ rec = f$edit(rec,"TRIM")
+$ if (f$extract(0,1,rec) .nes. "#") then goto hloop
+$ rec = f$edit(rec - "#", "TRIM")
+$ if f$element(0," ",rec) .nes. "define" then goto hloop
+$ if f$element(1," ",rec) .eqs. v_string
+$ then
+$ version = 'f$element(2," ",rec)'
+$ goto hdone
+$ endif
+$ goto hloop
+$hdone:
+$ close h_in
+$ return
+$!------------------------------------------------------------------------------
+$!
+$CHECK_CONFIG:
+$!
+$ in_ldef = f$locate(cdef,libdefs)
+$ if (in_ldef .lt. f$length(libdefs))
+$ then
+$ write aconf "#define ''cdef' 1"
+$ libdefs = f$extract(0,in_ldef,libdefs) + -
+ f$extract(in_ldef + f$length(cdef) + 1, -
+ f$length(libdefs) - in_ldef - f$length(cdef) - 1, -
+ libdefs)
+$ else
+$ if (f$type('cdef') .eqs. "INTEGER")
+$ then
+$ write aconf "#define ''cdef' ", 'cdef'
+$ else
+$ if (f$type('cdef') .eqs. "STRING")
+$ then
+$ write aconf "#define ''cdef' ", """", '''cdef'', """"
+$ else
+$ gosub check_cc_def
+$ endif
+$ endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check if this is a define relating to the properties of the C/C++
+$! compiler
+$!
+$ CHECK_CC_DEF:
+$ if (cdef .eqs. "_LARGEFILE64_SOURCE")
+$ then
+$ copy sys$input: 'tc'
+$ deck
+#include "tconfig"
+#define _LARGEFILE
+#include <stdio.h>
+
+int main(){
+FILE *fp;
+ fp = fopen("temp.txt","r");
+ fseeko(fp,1,SEEK_SET);
+ fclose(fp);
+}
+
+$ eod
+$ test_inv = false
+$ comm_h = false
+$ gosub cc_prop_check
+$ return
+$ endif
+$ write aconf "/* ", line, " */"
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check for properties of C/C++ compiler
+$!
+$! Version history
+$! 0.01 20031020 First version to receive a number
+$! 0.02 20031022 Added logic for defines with value
+$! 0.03 20040309 Make sure local config file gets not deleted
+$! 0.04 20041230 Also write include for configure run
+$! 0.05 20050103 Add processing of "comment defines"
+$CC_PROP_CHECK:
+$ cc_prop = true
+$ is_need = false
+$ is_need = (f$extract(0,4,cdef) .eqs. "NEED") .or. (test_inv .eq. true)
+$ if f$search(th) .eqs. "" then create 'th'
+$ set message/nofac/noident/nosever/notext
+$ on error then continue
+$ cc 'tmpnam'
+$ if .not. ($status) then cc_prop = false
+$ on error then continue
+$! The headers might lie about the capabilities of the RTL
+$ link 'tmpnam',tmp.opt/opt
+$ if .not. ($status) then cc_prop = false
+$ set message/fac/ident/sever/text
+$ on error then goto err_exit
+$ delete/nolog 'tmpnam'.*;*/exclude='th'
+$ if (cc_prop .and. .not. is_need) .or. -
+ (.not. cc_prop .and. is_need)
+$ then
+$ write sys$output "Checking for ''cdef'... yes"
+$ if f$type('cdef_val'_yes) .nes. ""
+$ then
+$ if f$type('cdef_val'_yes) .eqs. "INTEGER" -
+ then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_yes)
+$ if f$type('cdef_val'_yes) .eqs. "STRING" -
+ then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_yes)
+$ else
+$ call write_config f$fao("#define !AS 1",cdef)
+$ endif
+$ if (cdef .eqs. "HAVE_FSEEKO") .or. (cdef .eqs. "_LARGE_FILES") .or. -
+ (cdef .eqs. "_LARGEFILE64_SOURCE") then -
+ call write_config f$string("#define _LARGEFILE 1")
+$ else
+$ write sys$output "Checking for ''cdef'... no"
+$ if (comm_h)
+$ then
+ call write_config f$fao("/* !AS */",line)
+$ else
+$ if f$type('cdef_val'_no) .nes. ""
+$ then
+$ if f$type('cdef_val'_no) .eqs. "INTEGER" -
+ then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_no)
+$ if f$type('cdef_val'_no) .eqs. "STRING" -
+ then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_no)
+$ else
+$ call write_config f$fao("#undef !AS",cdef)
+$ endif
+$ endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check for properties of C/C++ compiler with multiple result values
+$!
+$! Version history
+$! 0.01 20040127 First version
+$! 0.02 20050103 Reconcile changes from cc_prop up to version 0.05
+$CC_MPROP_CHECK:
+$ cc_prop = true
+$ i = 1
+$ idel = 1
+$ MT_LOOP:
+$ if f$type(result_'i') .eqs. "STRING"
+$ then
+$ set message/nofac/noident/nosever/notext
+$ on error then continue
+$ cc 'tmpnam'_'i'
+$ if .not. ($status) then cc_prop = false
+$ on error then continue
+$! The headers might lie about the capabilities of the RTL
+$ link 'tmpnam'_'i',tmp.opt/opt
+$ if .not. ($status) then cc_prop = false
+$ set message/fac/ident/sever/text
+$ on error then goto err_exit
+$ delete/nolog 'tmpnam'_'i'.*;*
+$ if (cc_prop)
+$ then
+$ write sys$output "Checking for ''cdef'... ", mdef_'i'
+$ if f$type(mdef_'i') .eqs. "INTEGER" -
+ then call write_config f$fao("#define !AS !UL",cdef,mdef_'i')
+$ if f$type('cdef_val'_yes) .eqs. "STRING" -
+ then call write_config f$fao("#define !AS !AS",cdef,mdef_'i')
+$ goto msym_clean
+$ else
+$ i = i + 1
+$ goto mt_loop
+$ endif
+$ endif
+$ write sys$output "Checking for ''cdef'... no"
+$ call write_config f$fao("#undef !AS",cdef)
+$ MSYM_CLEAN:
+$ if (idel .le. msym_max)
+$ then
+$ delete/sym mdef_'idel'
+$ idel = idel + 1
+$ goto msym_clean
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Write configuration to both permanent and temporary config file
+$!
+$! Version history
+$! 0.01 20031029 First version to receive a number
+$!
+$WRITE_CONFIG: SUBROUTINE
+$ write aconf 'p1'
+$ open/append confh 'th'
+$ write confh 'p1'
+$ close confh
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Analyze the project map file and create the symbol vector for a shareable
+$! image from it
+$!
+$! Version history
+$! 0.01 20120128 First version
+$! 0.02 20120226 Add pre-load logic
+$!
+$ MAP_2_SHOPT: Subroutine
+$!
+$ SAY := "WRITE_ SYS$OUTPUT"
+$!
+$ IF F$SEARCH("''P1'") .EQS. ""
+$ THEN
+$ SAY "MAP_2_SHOPT-E-NOSUCHFILE: Error, inputfile ''p1' not available"
+$ goto exit_m2s
+$ ENDIF
+$ IF "''P2'" .EQS. ""
+$ THEN
+$ SAY "MAP_2_SHOPT: Error, no output file provided"
+$ goto exit_m2s
+$ ENDIF
+$!
+$ module1 = "deflate#deflateEnd#deflateInit_#deflateParams#deflateSetDictionary"
+$ module2 = "gzclose#gzerror#gzgetc#gzgets#gzopen#gzprintf#gzputc#gzputs#gzread"
+$ module3 = "gzseek#gztell#inflate#inflateEnd#inflateInit_#inflateSetDictionary"
+$ module4 = "inflateSync#uncompress#zlibVersion#compress"
+$ open/read map 'p1
+$ if axp .or. ia64
+$ then
+$ open/write aopt a.opt
+$ open/write bopt b.opt
+$ write aopt " CASE_SENSITIVE=YES"
+$ write bopt "SYMBOL_VECTOR= (-"
+$ mod_sym_num = 1
+$ MOD_SYM_LOOP:
+$ if f$type(module'mod_sym_num') .nes. ""
+$ then
+$ mod_in = 0
+$ MOD_SYM_IN:
+$ shared_proc = f$element(mod_in, "#", module'mod_sym_num')
+$ if shared_proc .nes. "#"
+$ then
+$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
+ f$edit(shared_proc,"upcase"),shared_proc)
+$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
+$ mod_in = mod_in + 1
+$ goto mod_sym_in
+$ endif
+$ mod_sym_num = mod_sym_num + 1
+$ goto mod_sym_loop
+$ endif
+$MAP_LOOP:
+$ read/end=map_end map line
+$ if (f$locate("{",line).lt. f$length(line)) .or. -
+ (f$locate("global:", line) .lt. f$length(line))
+$ then
+$ proc = true
+$ goto map_loop
+$ endif
+$ if f$locate("}",line).lt. f$length(line) then proc = false
+$ if f$locate("local:", line) .lt. f$length(line) then proc = false
+$ if proc
+$ then
+$ shared_proc = f$edit(line,"collapse")
+$ chop_semi = f$locate(";", shared_proc)
+$ if chop_semi .lt. f$length(shared_proc) then -
+ shared_proc = f$extract(0, chop_semi, shared_proc)
+$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
+ f$edit(shared_proc,"upcase"),shared_proc)
+$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
+$ endif
+$ goto map_loop
+$MAP_END:
+$ close/nolog aopt
+$ close/nolog bopt
+$ open/append libopt 'p2'
+$ open/read aopt a.opt
+$ open/read bopt b.opt
+$ALOOP:
+$ read/end=aloop_end aopt line
+$ write libopt line
+$ goto aloop
+$ALOOP_END:
+$ close/nolog aopt
+$ sv = ""
+$BLOOP:
+$ read/end=bloop_end bopt svn
+$ if (svn.nes."")
+$ then
+$ if (sv.nes."") then write libopt sv
+$ sv = svn
+$ endif
+$ goto bloop
+$BLOOP_END:
+$ write libopt f$extract(0,f$length(sv)-2,sv), "-"
+$ write libopt ")"
+$ close/nolog bopt
+$ delete/nolog/noconf a.opt;*,b.opt;*
+$ else
+$ if vax
+$ then
+$ open/append libopt 'p2'
+$ mod_sym_num = 1
+$ VMOD_SYM_LOOP:
+$ if f$type(module'mod_sym_num') .nes. ""
+$ then
+$ mod_in = 0
+$ VMOD_SYM_IN:
+$ shared_proc = f$element(mod_in, "#", module'mod_sym_num')
+$ if shared_proc .nes. "#"
+$ then
+$ write libopt f$fao("UNIVERSAL=!AS",-
+ f$edit(shared_proc,"upcase"))
+$ mod_in = mod_in + 1
+$ goto vmod_sym_in
+$ endif
+$ mod_sym_num = mod_sym_num + 1
+$ goto vmod_sym_loop
+$ endif
+$VMAP_LOOP:
+$ read/end=vmap_end map line
+$ if (f$locate("{",line).lt. f$length(line)) .or. -
+ (f$locate("global:", line) .lt. f$length(line))
+$ then
+$ proc = true
+$ goto vmap_loop
+$ endif
+$ if f$locate("}",line).lt. f$length(line) then proc = false
+$ if f$locate("local:", line) .lt. f$length(line) then proc = false
+$ if proc
+$ then
+$ shared_proc = f$edit(line,"collapse")
+$ chop_semi = f$locate(";", shared_proc)
+$ if chop_semi .lt. f$length(shared_proc) then -
+ shared_proc = f$extract(0, chop_semi, shared_proc)
+$ write libopt f$fao("UNIVERSAL=!AS",-
+ f$edit(shared_proc,"upcase"))
+$ endif
+$ goto vmap_loop
+$VMAP_END:
+$ else
+$ write sys$output "Unknown Architecture (Not VAX, AXP, or IA64)"
+$ write sys$output "No options file created"
+$ endif
+$ endif
+$ EXIT_M2S:
+$ close/nolog map
+$ close/nolog libopt
+$ endsubroutine
diff --git a/xs/src/png/zlib/msdos/Makefile.bor b/xs/src/png/zlib/msdos/Makefile.bor
new file mode 100644
index 000000000..3d12a2c25
--- /dev/null
+++ b/xs/src/png/zlib/msdos/Makefile.bor
@@ -0,0 +1,115 @@
+# Makefile for zlib
+# Borland C++
+# Last updated: 15-Mar-2003
+
+# To use, do "make -fmakefile.bor"
+# To compile in small model, set below: MODEL=s
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. For example:
+# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to the LOC macro below:
+# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------ Turbo C++, Borland C++ ------------
+
+# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
+# to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+# type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 0
+
+# memory model: one of s, m, c, l (small, medium, compact, large)
+MODEL=l
+
+# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version
+CC=bcc
+LD=bcc
+AR=tlib
+
+# compiler flags
+# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0
+CFLAGS=-O2 -Z -m$(MODEL) $(LOC)
+
+LDFLAGS=-m$(MODEL) -f-
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+ -del $(ZLIB_LIB)
+ $(AR) $(ZLIB_LIB) $(OBJP1)
+ $(AR) $(ZLIB_LIB) $(OBJP2)
+
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+clean:
+ -del *.obj
+ -del *.lib
+ -del *.exe
+ -del zlib_*.bak
+ -del foo.gz
diff --git a/xs/src/png/zlib/msdos/Makefile.dj2 b/xs/src/png/zlib/msdos/Makefile.dj2
new file mode 100644
index 000000000..59d2037d6
--- /dev/null
+++ b/xs/src/png/zlib/msdos/Makefile.dj2
@@ -0,0 +1,104 @@
+# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+# make -fmakefile.dj2; make test -fmakefile.dj2
+#
+# To install libz.a, zconf.h and zlib.h in the djgpp directories, type:
+#
+# make install -fmakefile.dj2
+#
+# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as
+# in the sample below if the pattern of the DJGPP distribution is to
+# be followed. Remember that, while <sp>'es around <=> are ignored in
+# makefiles, they are *not* in batch files or in djgpp.env.
+# - - - - -
+# [make]
+# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include
+# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib
+# BUTT=-m486
+# - - - - -
+# Alternately, these variables may be defined below, overriding the values
+# in djgpp.env, as
+# INCLUDE_PATH=c:\usr\include
+# LIBRARY_PATH=c:\usr\lib
+
+CC=gcc
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DZLIB_DEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+ -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lz
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=libz.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+ uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+OBJA =
+# to use the asm code: make OBJA=match.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+check: test
+test: all
+ ./example
+ echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+libz.a: $(OBJS) $(OBJA)
+ $(AR) $@ $(OBJS) $(OBJA)
+
+%.exe : %.o $(LIBS)
+ $(LD) $@ $< $(LDLIBS)
+
+# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env .
+
+.PHONY : uninstall clean
+
+install: $(INCL) $(LIBS)
+ -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH)
+ -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH)
+ $(INSTALL) zlib.h $(INCLUDE_PATH)
+ $(INSTALL) zconf.h $(INCLUDE_PATH)
+ $(INSTALL) libz.a $(LIBRARY_PATH)
+
+uninstall:
+ $(RM) $(INCLUDE_PATH)\zlib.h
+ $(RM) $(INCLUDE_PATH)\zconf.h
+ $(RM) $(LIBRARY_PATH)\libz.a
+
+clean:
+ $(RM) *.d
+ $(RM) *.o
+ $(RM) *.exe
+ $(RM) libz.a
+ $(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/xs/src/png/zlib/msdos/Makefile.emx b/xs/src/png/zlib/msdos/Makefile.emx
new file mode 100644
index 000000000..e30f67bed
--- /dev/null
+++ b/xs/src/png/zlib/msdos/Makefile.emx
@@ -0,0 +1,69 @@
+# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+# make -fmakefile.emx; make test -fmakefile.emx
+#
+
+CC=gcc
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DZLIB_DEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+ -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lzlib
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=zlib.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+ uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+test: all
+ ./example
+ echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+zlib.a: $(OBJS)
+ $(AR) $@ $(OBJS)
+
+%.exe : %.o $(LIBS)
+ $(LD) $@ $< $(LDLIBS)
+
+
+.PHONY : clean
+
+clean:
+ $(RM) *.d
+ $(RM) *.o
+ $(RM) *.exe
+ $(RM) zlib.a
+ $(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/xs/src/png/zlib/msdos/Makefile.msc b/xs/src/png/zlib/msdos/Makefile.msc
new file mode 100644
index 000000000..ae8378615
--- /dev/null
+++ b/xs/src/png/zlib/msdos/Makefile.msc
@@ -0,0 +1,112 @@
+# Makefile for zlib
+# Microsoft C 5.1 or later
+# Last updated: 19-Mar-2003
+
+# To use, do "make makefile.msc"
+# To compile in small model, set below: MODEL=S
+
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to the LOC macro below:
+# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------- Microsoft C 5.1 and later -------------
+
+# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
+# to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 0
+
+# Memory model: one of S, M, C, L (small, medium, compact, large)
+MODEL=L
+
+CC=cl
+CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC)
+#-Ox generates bad code with MSC 5.1
+LIB_CFLAGS=-Zl $(CFLAGS)
+
+LD=link
+LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode
+# "/farcall/packcode" are only useful for `large code' memory models
+# but should be a "no-op" for small code models.
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+ $(CC) -c $(LIB_CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+ if exist $(ZLIB_LIB) del $(ZLIB_LIB)
+ lib $(ZLIB_LIB) $(OBJ1);
+ lib $(ZLIB_LIB) $(OBJ2);
+
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB);
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB);
+
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+clean:
+ -del *.obj
+ -del *.lib
+ -del *.exe
+ -del *.map
+ -del zlib_*.bak
+ -del foo.gz
diff --git a/xs/src/png/zlib/msdos/Makefile.tc b/xs/src/png/zlib/msdos/Makefile.tc
new file mode 100644
index 000000000..5aec82a9d
--- /dev/null
+++ b/xs/src/png/zlib/msdos/Makefile.tc
@@ -0,0 +1,100 @@
+# Makefile for zlib
+# Turbo C 2.01, Turbo C++ 1.01
+# Last updated: 15-Mar-2003
+
+# To use, do "make -fmakefile.tc"
+# To compile in small model, set below: MODEL=s
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. For example:
+# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to CFLAGS below:
+# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------ Turbo C 2.01, Turbo C++ 1.01 ------------
+MODEL=l
+CC=tcc
+LD=tcc
+AR=tlib
+# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
+CFLAGS=-O2 -G -Z -m$(MODEL)
+LDFLAGS=-m$(MODEL) -f-
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+ -del $(ZLIB_LIB)
+ $(AR) $(ZLIB_LIB) $(OBJP1)
+ $(AR) $(ZLIB_LIB) $(OBJP2)
+
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+clean:
+ -del *.obj
+ -del *.lib
+ -del *.exe
+ -del zlib_*.bak
+ -del foo.gz
diff --git a/xs/src/png/zlib/nintendods/Makefile b/xs/src/png/zlib/nintendods/Makefile
new file mode 100644
index 000000000..21337d01a
--- /dev/null
+++ b/xs/src/png/zlib/nintendods/Makefile
@@ -0,0 +1,126 @@
+#---------------------------------------------------------------------------------
+.SUFFIXES:
+#---------------------------------------------------------------------------------
+
+ifeq ($(strip $(DEVKITARM)),)
+$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
+endif
+
+include $(DEVKITARM)/ds_rules
+
+#---------------------------------------------------------------------------------
+# TARGET is the name of the output
+# BUILD is the directory where object files & intermediate files will be placed
+# SOURCES is a list of directories containing source code
+# DATA is a list of directories containing data files
+# INCLUDES is a list of directories containing header files
+#---------------------------------------------------------------------------------
+TARGET := $(shell basename $(CURDIR))
+BUILD := build
+SOURCES := ../../
+DATA := data
+INCLUDES := include
+
+#---------------------------------------------------------------------------------
+# options for code generation
+#---------------------------------------------------------------------------------
+ARCH := -mthumb -mthumb-interwork
+
+CFLAGS := -Wall -O2\
+ -march=armv5te -mtune=arm946e-s \
+ -fomit-frame-pointer -ffast-math \
+ $(ARCH)
+
+CFLAGS += $(INCLUDE) -DARM9
+CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
+
+ASFLAGS := $(ARCH) -march=armv5te -mtune=arm946e-s
+LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
+
+#---------------------------------------------------------------------------------
+# list of directories containing libraries, this must be the top level containing
+# include and lib
+#---------------------------------------------------------------------------------
+LIBDIRS := $(LIBNDS)
+
+#---------------------------------------------------------------------------------
+# no real need to edit anything past this point unless you need to add additional
+# rules for different file extensions
+#---------------------------------------------------------------------------------
+ifneq ($(BUILD),$(notdir $(CURDIR)))
+#---------------------------------------------------------------------------------
+
+export OUTPUT := $(CURDIR)/lib/libz.a
+
+export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
+ $(foreach dir,$(DATA),$(CURDIR)/$(dir))
+
+export DEPSDIR := $(CURDIR)/$(BUILD)
+
+CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
+CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
+SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
+BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
+
+#---------------------------------------------------------------------------------
+# use CXX for linking C++ projects, CC for standard C
+#---------------------------------------------------------------------------------
+ifeq ($(strip $(CPPFILES)),)
+#---------------------------------------------------------------------------------
+ export LD := $(CC)
+#---------------------------------------------------------------------------------
+else
+#---------------------------------------------------------------------------------
+ export LD := $(CXX)
+#---------------------------------------------------------------------------------
+endif
+#---------------------------------------------------------------------------------
+
+export OFILES := $(addsuffix .o,$(BINFILES)) \
+ $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
+
+export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
+ $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
+ -I$(CURDIR)/$(BUILD)
+
+.PHONY: $(BUILD) clean all
+
+#---------------------------------------------------------------------------------
+all: $(BUILD)
+ @[ -d $@ ] || mkdir -p include
+ @cp ../../*.h include
+
+lib:
+ @[ -d $@ ] || mkdir -p $@
+
+$(BUILD): lib
+ @[ -d $@ ] || mkdir -p $@
+ @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
+
+#---------------------------------------------------------------------------------
+clean:
+ @echo clean ...
+ @rm -fr $(BUILD) lib
+
+#---------------------------------------------------------------------------------
+else
+
+DEPENDS := $(OFILES:.o=.d)
+
+#---------------------------------------------------------------------------------
+# main targets
+#---------------------------------------------------------------------------------
+$(OUTPUT) : $(OFILES)
+
+#---------------------------------------------------------------------------------
+%.bin.o : %.bin
+#---------------------------------------------------------------------------------
+ @echo $(notdir $<)
+ @$(bin2o)
+
+
+-include $(DEPENDS)
+
+#---------------------------------------------------------------------------------------
+endif
+#---------------------------------------------------------------------------------------
diff --git a/xs/src/png/zlib/nintendods/README b/xs/src/png/zlib/nintendods/README
new file mode 100644
index 000000000..ba7a37dbe
--- /dev/null
+++ b/xs/src/png/zlib/nintendods/README
@@ -0,0 +1,5 @@
+This Makefile requires devkitARM (http://www.devkitpro.org/category/devkitarm/) and works inside "contrib/nds". It is based on a devkitARM template.
+
+Eduardo Costa <eduardo.m.costa@gmail.com>
+January 3, 2009
+
diff --git a/xs/src/png/zlib/old/Makefile.emx b/xs/src/png/zlib/old/Makefile.emx
new file mode 100644
index 000000000..612b03791
--- /dev/null
+++ b/xs/src/png/zlib/old/Makefile.emx
@@ -0,0 +1,69 @@
+# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+# make -fmakefile.emx; make test -fmakefile.emx
+#
+
+CC=gcc -Zwin32
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DZLIB_DEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+ -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lzlib
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=zlib.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
+ gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+test: all
+ ./example
+ echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+zlib.a: $(OBJS)
+ $(AR) $@ $(OBJS)
+
+%.exe : %.o $(LIBS)
+ $(LD) $@ $< $(LDLIBS)
+
+
+.PHONY : clean
+
+clean:
+ $(RM) *.d
+ $(RM) *.o
+ $(RM) *.exe
+ $(RM) zlib.a
+ $(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/xs/src/png/zlib/old/Makefile.riscos b/xs/src/png/zlib/old/Makefile.riscos
new file mode 100644
index 000000000..57e29d3fb
--- /dev/null
+++ b/xs/src/png/zlib/old/Makefile.riscos
@@ -0,0 +1,151 @@
+# Project: zlib_1_03
+# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430
+# test works out-of-the-box, installs `somewhere' on demand
+
+# Toolflags:
+CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah
+C++flags = -c -depend !Depend -IC: -throwback
+Linkflags = -aif -c++ -o $@
+ObjAsmflags = -throwback -NoCache -depend !Depend
+CMHGflags =
+LibFileflags = -c -l -o $@
+Squeezeflags = -o $@
+
+# change the line below to where _you_ want the library installed.
+libdest = lib:zlib
+
+# Final targets:
+@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \
+ @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \
+ @.o.uncompr @.o.zutil
+ LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \
+ @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \
+ @.o.trees @.o.uncompr @.o.zutil
+test: @.minigzip @.example @.lib
+ @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV
+ @echo running tests: hang on.
+ @/@.minigzip -f -9 libc
+ @/@.minigzip -d libc-gz
+ @/@.minigzip -f -1 libc
+ @/@.minigzip -d libc-gz
+ @/@.minigzip -h -9 libc
+ @/@.minigzip -d libc-gz
+ @/@.minigzip -h -1 libc
+ @/@.minigzip -d libc-gz
+ @/@.minigzip -9 libc
+ @/@.minigzip -d libc-gz
+ @/@.minigzip -1 libc
+ @/@.minigzip -d libc-gz
+ @diff @.lib @.libc
+ @echo that should have reported '@.lib and @.libc identical' if you have diff.
+ @/@.example @.fred @.fred
+ @echo that will have given lots of hello!'s.
+
+@.minigzip: @.o.minigzip @.lib C:o.Stubs
+ Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs
+@.example: @.o.example @.lib C:o.Stubs
+ Link $(Linkflags) @.o.example @.lib C:o.Stubs
+
+install: @.lib
+ cdir $(libdest)
+ cdir $(libdest).h
+ @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV
+ @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV
+ @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV
+ @echo okay, installed zlib in $(libdest)
+
+clean:; remove @.minigzip
+ remove @.example
+ remove @.libc
+ -wipe @.o.* F~r~cV
+ remove @.fred
+
+# User-editable dependencies:
+.c.o:
+ cc $(ccflags) -o $@ $<
+
+# Static dependencies:
+
+# Dynamic dependencies:
+o.example: c.example
+o.example: h.zlib
+o.example: h.zconf
+o.minigzip: c.minigzip
+o.minigzip: h.zlib
+o.minigzip: h.zconf
+o.adler32: c.adler32
+o.adler32: h.zlib
+o.adler32: h.zconf
+o.compress: c.compress
+o.compress: h.zlib
+o.compress: h.zconf
+o.crc32: c.crc32
+o.crc32: h.zlib
+o.crc32: h.zconf
+o.deflate: c.deflate
+o.deflate: h.deflate
+o.deflate: h.zutil
+o.deflate: h.zlib
+o.deflate: h.zconf
+o.gzio: c.gzio
+o.gzio: h.zutil
+o.gzio: h.zlib
+o.gzio: h.zconf
+o.infblock: c.infblock
+o.infblock: h.zutil
+o.infblock: h.zlib
+o.infblock: h.zconf
+o.infblock: h.infblock
+o.infblock: h.inftrees
+o.infblock: h.infcodes
+o.infblock: h.infutil
+o.infcodes: c.infcodes
+o.infcodes: h.zutil
+o.infcodes: h.zlib
+o.infcodes: h.zconf
+o.infcodes: h.inftrees
+o.infcodes: h.infblock
+o.infcodes: h.infcodes
+o.infcodes: h.infutil
+o.infcodes: h.inffast
+o.inffast: c.inffast
+o.inffast: h.zutil
+o.inffast: h.zlib
+o.inffast: h.zconf
+o.inffast: h.inftrees
+o.inffast: h.infblock
+o.inffast: h.infcodes
+o.inffast: h.infutil
+o.inffast: h.inffast
+o.inflate: c.inflate
+o.inflate: h.zutil
+o.inflate: h.zlib
+o.inflate: h.zconf
+o.inflate: h.infblock
+o.inftrees: c.inftrees
+o.inftrees: h.zutil
+o.inftrees: h.zlib
+o.inftrees: h.zconf
+o.inftrees: h.inftrees
+o.inftrees: h.inffixed
+o.infutil: c.infutil
+o.infutil: h.zutil
+o.infutil: h.zlib
+o.infutil: h.zconf
+o.infutil: h.infblock
+o.infutil: h.inftrees
+o.infutil: h.infcodes
+o.infutil: h.infutil
+o.trees: c.trees
+o.trees: h.deflate
+o.trees: h.zutil
+o.trees: h.zlib
+o.trees: h.zconf
+o.trees: h.trees
+o.uncompr: c.uncompr
+o.uncompr: h.zlib
+o.uncompr: h.zconf
+o.zutil: c.zutil
+o.zutil: h.zutil
+o.zutil: h.zlib
+o.zutil: h.zconf
diff --git a/xs/src/png/zlib/old/README b/xs/src/png/zlib/old/README
new file mode 100644
index 000000000..800bf0798
--- /dev/null
+++ b/xs/src/png/zlib/old/README
@@ -0,0 +1,3 @@
+This directory contains files that have not been updated for zlib 1.2.x
+
+(Volunteers are encouraged to help clean this up. Thanks.)
diff --git a/xs/src/png/zlib/old/descrip.mms b/xs/src/png/zlib/old/descrip.mms
new file mode 100644
index 000000000..7066da5b5
--- /dev/null
+++ b/xs/src/png/zlib/old/descrip.mms
@@ -0,0 +1,48 @@
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser <m.zinser@gsi.de>
+
+cc_defs =
+c_deb =
+
+.ifdef __DECC__
+pref = /prefix=all
+.endif
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\
+ deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\
+ inftrees.obj, infcodes.obj, infutil.obj, inffast.obj
+
+CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
+
+all : example.exe minigzip.exe
+ @ write sys$output " Example applications available"
+libz.olb : libz.olb($(OBJS))
+ @ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+ link example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+ link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
+
+clean :
+ delete *.obj;*,libz.olb;*
+
+
+# Other dependencies.
+adler32.obj : zutil.h zlib.h zconf.h
+compress.obj : zlib.h zconf.h
+crc32.obj : zutil.h zlib.h zconf.h
+deflate.obj : deflate.h zutil.h zlib.h zconf.h
+example.obj : zlib.h zconf.h
+gzio.obj : zutil.h zlib.h zconf.h
+infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
+inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+inflate.obj : zutil.h zlib.h zconf.h infblock.h
+inftrees.obj : zutil.h zlib.h zconf.h inftrees.h
+infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h
+minigzip.obj : zlib.h zconf.h
+trees.obj : deflate.h zutil.h zlib.h zconf.h
+uncompr.obj : zlib.h zconf.h
+zutil.obj : zutil.h zlib.h zconf.h
diff --git a/xs/src/png/zlib/old/os2/Makefile.os2 b/xs/src/png/zlib/old/os2/Makefile.os2
new file mode 100644
index 000000000..bb426c0d8
--- /dev/null
+++ b/xs/src/png/zlib/old/os2/Makefile.os2
@@ -0,0 +1,136 @@
+# Makefile for zlib under OS/2 using GCC (PGCC)
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+# cp Makefile.os2 ..
+# cd ..
+# make -f Makefile.os2 test
+
+# This makefile will build a static library z.lib, a shared library
+# z.dll and a import library zdll.lib. You can use either z.lib or
+# zdll.lib by specifying either -lz or -lzdll on gcc's command line
+
+CC=gcc -Zomf -s
+
+CFLAGS=-O6 -Wall
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DZLIB_DEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+# -Wstrict-prototypes -Wmissing-prototypes
+
+#################### BUG WARNING: #####################
+## infcodes.c hits a bug in pgcc-1.0, so you have to use either
+## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem)
+## This bug is reportedly fixed in pgcc >1.0, but this was not tested
+CFLAGS+=-fno-force-mem
+
+LDFLAGS=-s -L. -lzdll -Zcrtdll
+LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll
+
+VER=1.1.0
+ZLIB=z.lib
+SHAREDLIB=z.dll
+SHAREDLIBIMP=zdll.lib
+LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP)
+
+AR=emxomfar cr
+IMPLIB=emximp
+RANLIB=echo
+TAR=tar
+SHELL=bash
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
+ zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \
+ algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \
+ nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \
+ contrib/asm386/*.asm contrib/asm386/*.c \
+ contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \
+ contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \
+ contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32
+
+all: example.exe minigzip.exe
+
+test: all
+ @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+ echo hello world | ./minigzip | ./minigzip -d || \
+ echo ' *** minigzip test FAILED ***' ; \
+ if ./example; then \
+ echo ' *** zlib test OK ***'; \
+ else \
+ echo ' *** zlib test FAILED ***'; \
+ fi
+
+$(ZLIB): $(OBJS)
+ $(AR) $@ $(OBJS)
+ -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+$(SHAREDLIB): $(OBJS) os2/z.def
+ $(LDSHARED) -o $@ $^
+
+$(SHAREDLIBIMP): os2/z.def
+ $(IMPLIB) -o $@ $^
+
+example.exe: example.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
+
+minigzip.exe: minigzip.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
+
+clean:
+ rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
+
+distclean: clean
+
+zip:
+ mv Makefile Makefile~; cp -p Makefile.in Makefile
+ rm -f test.c ztest*.c
+ v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+ zip -ul9 zlib$$v $(DISTFILES)
+ mv Makefile~ Makefile
+
+dist:
+ mv Makefile Makefile~; cp -p Makefile.in Makefile
+ rm -f test.c ztest*.c
+ d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+ rm -f $$d.tar.gz; \
+ if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
+ files=""; \
+ for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
+ cd ..; \
+ GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
+ if test ! -d $$d; then rm -f $$d; fi
+ mv Makefile~ Makefile
+
+tags:
+ etags *.[ch]
+
+depend:
+ makedepend -- $(CFLAGS) -- *.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzio.o: zutil.h zlib.h zconf.h
+infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
+infcodes.o: zutil.h zlib.h zconf.h
+infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h
+inffast.o: infblock.h infcodes.h infutil.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h infblock.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/xs/src/png/zlib/old/os2/zlib.def b/xs/src/png/zlib/old/os2/zlib.def
new file mode 100644
index 000000000..4c753f1a3
--- /dev/null
+++ b/xs/src/png/zlib/old/os2/zlib.def
@@ -0,0 +1,51 @@
+;
+; Slightly modified version of ../nt/zlib.dnt :-)
+;
+
+LIBRARY Z
+DESCRIPTION "Zlib compression library for OS/2"
+CODE PRELOAD MOVEABLE DISCARDABLE
+DATA PRELOAD MOVEABLE MULTIPLE
+
+EXPORTS
+ adler32
+ compress
+ crc32
+ deflate
+ deflateCopy
+ deflateEnd
+ deflateInit2_
+ deflateInit_
+ deflateParams
+ deflateReset
+ deflateSetDictionary
+ gzclose
+ gzdopen
+ gzerror
+ gzflush
+ gzopen
+ gzread
+ gzwrite
+ inflate
+ inflateEnd
+ inflateInit2_
+ inflateInit_
+ inflateReset
+ inflateSetDictionary
+ inflateSync
+ uncompress
+ zlibVersion
+ gzprintf
+ gzputc
+ gzgetc
+ gzseek
+ gzrewind
+ gztell
+ gzeof
+ gzsetparams
+ zError
+ inflateSyncPoint
+ get_crc_table
+ compress2
+ gzputs
+ gzgets
diff --git a/xs/src/png/zlib/old/visual-basic.txt b/xs/src/png/zlib/old/visual-basic.txt
new file mode 100644
index 000000000..57efe5812
--- /dev/null
+++ b/xs/src/png/zlib/old/visual-basic.txt
@@ -0,0 +1,160 @@
+See below some functions declarations for Visual Basic.
+
+Frequently Asked Question:
+
+Q: Each time I use the compress function I get the -5 error (not enough
+ room in the output buffer).
+
+A: Make sure that the length of the compressed buffer is passed by
+ reference ("as any"), not by value ("as long"). Also check that
+ before the call of compress this length is equal to the total size of
+ the compressed buffer and not zero.
+
+
+From: "Jon Caruana" <jon-net@usa.net>
+Subject: Re: How to port zlib declares to vb?
+Date: Mon, 28 Oct 1996 18:33:03 -0600
+
+Got the answer! (I haven't had time to check this but it's what I got, and
+looks correct):
+
+He has the following routines working:
+ compress
+ uncompress
+ gzopen
+ gzwrite
+ gzread
+ gzclose
+
+Declares follow: (Quoted from Carlos Rios <c_rios@sonda.cl>, in Vb4 form)
+
+#If Win16 Then 'Use Win16 calls.
+Declare Function compress Lib "ZLIB.DLL" (ByVal compr As
+ String, comprLen As Any, ByVal buf As String, ByVal buflen
+ As Long) As Integer
+Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr
+ As String, uncomprLen As Any, ByVal compr As String, ByVal
+ lcompr As Long) As Integer
+Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As
+ String, ByVal mode As String) As Long
+Declare Function gzread Lib "ZLIB.DLL" (ByVal file As
+ Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
+ As Integer
+Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As
+ Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
+ As Integer
+Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As
+ Long) As Integer
+#Else
+Declare Function compress Lib "ZLIB32.DLL"
+ (ByVal compr As String, comprLen As Any, ByVal buf As
+ String, ByVal buflen As Long) As Integer
+Declare Function uncompress Lib "ZLIB32.DLL"
+ (ByVal uncompr As String, uncomprLen As Any, ByVal compr As
+ String, ByVal lcompr As Long) As Long
+Declare Function gzopen Lib "ZLIB32.DLL"
+ (ByVal file As String, ByVal mode As String) As Long
+Declare Function gzread Lib "ZLIB32.DLL"
+ (ByVal file As Long, ByVal uncompr As String, ByVal
+ uncomprLen As Long) As Long
+Declare Function gzwrite Lib "ZLIB32.DLL"
+ (ByVal file As Long, ByVal uncompr As String, ByVal
+ uncomprLen As Long) As Long
+Declare Function gzclose Lib "ZLIB32.DLL"
+ (ByVal file As Long) As Long
+#End If
+
+-Jon Caruana
+jon-net@usa.net
+Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member
+
+
+Here is another example from Michael <michael_borgsys@hotmail.com> that he
+says conforms to the VB guidelines, and that solves the problem of not
+knowing the uncompressed size by storing it at the end of the file:
+
+'Calling the functions:
+'bracket meaning: <parameter> [optional] {Range of possible values}
+'Call subCompressFile(<path with filename to compress> [, <path with
+filename to write to>, [level of compression {1..9}]])
+'Call subUncompressFile(<path with filename to compress>)
+
+Option Explicit
+Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller'
+Private Const SUCCESS As Long = 0
+Private Const strFilExt As String = ".cpr"
+Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef
+dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long,
+ByVal level As Integer) As Long
+Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef
+dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long)
+As Long
+
+Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal
+strargCprFilPth As String, Optional ByVal intLvl As Integer = 9)
+ Dim strCprPth As String
+ Dim lngOriSiz As Long
+ Dim lngCprSiz As Long
+ Dim bytaryOri() As Byte
+ Dim bytaryCpr() As Byte
+ lngOriSiz = FileLen(strargOriFilPth)
+ ReDim bytaryOri(lngOriSiz - 1)
+ Open strargOriFilPth For Binary Access Read As #1
+ Get #1, , bytaryOri()
+ Close #1
+ strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth)
+'Select file path and name
+ strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) =
+strFilExt, "", strFilExt) 'Add file extension if not exists
+ lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit
+more space then original file size
+ ReDim bytaryCpr(lngCprSiz - 1)
+ If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) =
+SUCCESS Then
+ lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100
+ ReDim Preserve bytaryCpr(lngCprSiz - 1)
+ Open strCprPth For Binary Access Write As #1
+ Put #1, , bytaryCpr()
+ Put #1, , lngOriSiz 'Add the the original size value to the end
+(last 4 bytes)
+ Close #1
+ Else
+ MsgBox "Compression error"
+ End If
+ Erase bytaryCpr
+ Erase bytaryOri
+End Sub
+
+Public Sub subUncompressFile(ByVal strargFilPth As String)
+ Dim bytaryCpr() As Byte
+ Dim bytaryOri() As Byte
+ Dim lngOriSiz As Long
+ Dim lngCprSiz As Long
+ Dim strOriPth As String
+ lngCprSiz = FileLen(strargFilPth)
+ ReDim bytaryCpr(lngCprSiz - 1)
+ Open strargFilPth For Binary Access Read As #1
+ Get #1, , bytaryCpr()
+ Close #1
+ 'Read the original file size value:
+ lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _
+ + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _
+ + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _
+ + bytaryCpr(lngCprSiz - 4)
+ ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value
+ ReDim bytaryOri(lngOriSiz - 1)
+ If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS
+Then
+ strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt))
+ Open strOriPth For Binary Access Write As #1
+ Put #1, , bytaryOri()
+ Close #1
+ Else
+ MsgBox "Uncompression error"
+ End If
+ Erase bytaryCpr
+ Erase bytaryOri
+End Sub
+Public Property Get lngPercentSmaller() As Long
+ lngPercentSmaller = lngpvtPcnSml
+End Property
diff --git a/xs/src/png/zlib/os400/README400 b/xs/src/png/zlib/os400/README400
new file mode 100644
index 000000000..4f98334f5
--- /dev/null
+++ b/xs/src/png/zlib/os400/README400
@@ -0,0 +1,48 @@
+ ZLIB version 1.2.11 for OS/400 installation instructions
+
+1) Download and unpack the zlib tarball to some IFS directory.
+ (i.e.: /path/to/the/zlib/ifs/source/directory)
+
+ If the installed IFS command suppors gzip format, this is straightforward,
+else you have to unpack first to some directory on a system supporting it,
+then move the whole directory to the IFS via the network (via SMB or FTP).
+
+2) Edit the configuration parameters in the compilation script.
+
+ EDTF STMF('/path/to/the/zlib/ifs/source/directory/os400/make.sh')
+
+Tune the parameters according to your needs if not matching the defaults.
+Save the file and exit after edition.
+
+3) Enter qshell, then work in the zlib OS/400 specific directory.
+
+ QSH
+ cd /path/to/the/zlib/ifs/source/directory/os400
+
+4) Compile and install
+
+ sh make.sh
+
+The script will:
+- create the libraries, objects and IFS directories for the zlib environment,
+- compile all modules,
+- create a service program,
+- create a static and a dynamic binding directory,
+- install header files for C/C++ and for ILE/RPG, both for compilation in
+ DB2 and IFS environments.
+
+That's all.
+
+
+Notes: For OS/400 ILE RPG programmers, a /copy member defining the ZLIB
+ API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC).
+ In the ILE environment, the same definitions are available from
+ file zlib.inc located in the same IFS include directory as the
+ C/C++ header files.
+ Please read comments in this member for more information.
+
+ Remember that most foreign textual data are ASCII coded: this
+ implementation does not handle conversion from/to ASCII, so
+ text data code conversions must be done explicitely.
+
+ Mainly for the reason above, always open zipped files in binary mode.
diff --git a/xs/src/png/zlib/os400/bndsrc b/xs/src/png/zlib/os400/bndsrc
new file mode 100644
index 000000000..5e6e0a2f0
--- /dev/null
+++ b/xs/src/png/zlib/os400/bndsrc
@@ -0,0 +1,119 @@
+STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB')
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.1.3 entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("adler32")
+ EXPORT SYMBOL("compress")
+ EXPORT SYMBOL("compress2")
+ EXPORT SYMBOL("crc32")
+ EXPORT SYMBOL("get_crc_table")
+ EXPORT SYMBOL("deflate")
+ EXPORT SYMBOL("deflateEnd")
+ EXPORT SYMBOL("deflateSetDictionary")
+ EXPORT SYMBOL("deflateCopy")
+ EXPORT SYMBOL("deflateReset")
+ EXPORT SYMBOL("deflateParams")
+ EXPORT SYMBOL("deflatePrime")
+ EXPORT SYMBOL("deflateInit_")
+ EXPORT SYMBOL("deflateInit2_")
+ EXPORT SYMBOL("gzopen")
+ EXPORT SYMBOL("gzdopen")
+ EXPORT SYMBOL("gzsetparams")
+ EXPORT SYMBOL("gzread")
+ EXPORT SYMBOL("gzwrite")
+ EXPORT SYMBOL("gzprintf")
+ EXPORT SYMBOL("gzputs")
+ EXPORT SYMBOL("gzgets")
+ EXPORT SYMBOL("gzputc")
+ EXPORT SYMBOL("gzgetc")
+ EXPORT SYMBOL("gzflush")
+ EXPORT SYMBOL("gzseek")
+ EXPORT SYMBOL("gzrewind")
+ EXPORT SYMBOL("gztell")
+ EXPORT SYMBOL("gzeof")
+ EXPORT SYMBOL("gzclose")
+ EXPORT SYMBOL("gzerror")
+ EXPORT SYMBOL("inflate")
+ EXPORT SYMBOL("inflateEnd")
+ EXPORT SYMBOL("inflateSetDictionary")
+ EXPORT SYMBOL("inflateSync")
+ EXPORT SYMBOL("inflateReset")
+ EXPORT SYMBOL("inflateInit_")
+ EXPORT SYMBOL("inflateInit2_")
+ EXPORT SYMBOL("inflateSyncPoint")
+ EXPORT SYMBOL("uncompress")
+ EXPORT SYMBOL("zlibVersion")
+ EXPORT SYMBOL("zError")
+ EXPORT SYMBOL("z_errmsg")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.1 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("compressBound")
+ EXPORT SYMBOL("deflateBound")
+ EXPORT SYMBOL("deflatePending")
+ EXPORT SYMBOL("gzungetc")
+ EXPORT SYMBOL("gzclearerr")
+ EXPORT SYMBOL("inflateBack")
+ EXPORT SYMBOL("inflateBackEnd")
+ EXPORT SYMBOL("inflateBackInit_")
+ EXPORT SYMBOL("inflateCopy")
+ EXPORT SYMBOL("zlibCompileFlags")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.4 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("adler32_combine")
+ EXPORT SYMBOL("adler32_combine64")
+ EXPORT SYMBOL("crc32_combine")
+ EXPORT SYMBOL("crc32_combine64")
+ EXPORT SYMBOL("deflateSetHeader")
+ EXPORT SYMBOL("deflateTune")
+ EXPORT SYMBOL("gzbuffer")
+ EXPORT SYMBOL("gzclose_r")
+ EXPORT SYMBOL("gzclose_w")
+ EXPORT SYMBOL("gzdirect")
+ EXPORT SYMBOL("gzoffset")
+ EXPORT SYMBOL("gzoffset64")
+ EXPORT SYMBOL("gzopen64")
+ EXPORT SYMBOL("gzseek64")
+ EXPORT SYMBOL("gztell64")
+ EXPORT SYMBOL("inflateGetHeader")
+ EXPORT SYMBOL("inflateMark")
+ EXPORT SYMBOL("inflatePrime")
+ EXPORT SYMBOL("inflateReset2")
+ EXPORT SYMBOL("inflateUndermine")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.6 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("deflateResetKeep")
+ EXPORT SYMBOL("gzgetc_")
+ EXPORT SYMBOL("inflateResetKeep")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.8 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("gzvprintf")
+ EXPORT SYMBOL("inflateGetDictionary")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/* Version 1.2.9 additional entry points. */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+ EXPORT SYMBOL("adler32_z")
+ EXPORT SYMBOL("crc32_z")
+ EXPORT SYMBOL("deflateGetDictionary")
+ EXPORT SYMBOL("gzfread")
+ EXPORT SYMBOL("gzfwrite")
+ EXPORT SYMBOL("inflateCodesUsed")
+ EXPORT SYMBOL("inflateValidate")
+ EXPORT SYMBOL("uncompress2")
+
+ENDPGMEXP
diff --git a/xs/src/png/zlib/os400/make.sh b/xs/src/png/zlib/os400/make.sh
new file mode 100644
index 000000000..19eec117a
--- /dev/null
+++ b/xs/src/png/zlib/os400/make.sh
@@ -0,0 +1,366 @@
+#!/bin/sh
+#
+# ZLIB compilation script for the OS/400.
+#
+#
+# This is a shell script since make is not a standard component of OS/400.
+
+
+################################################################################
+#
+# Tunable configuration parameters.
+#
+################################################################################
+
+TARGETLIB='ZLIB' # Target OS/400 program library
+STATBNDDIR='ZLIB_A' # Static binding directory.
+DYNBNDDIR='ZLIB' # Dynamic binding directory.
+SRVPGM="ZLIB" # Service program.
+IFSDIR='/zlib' # IFS support base directory.
+TGTCCSID='500' # Target CCSID of objects
+DEBUG='*NONE' # Debug level
+OPTIMIZE='40' # Optimisation level
+OUTPUT='*NONE' # Compilation output option.
+TGTRLS='V6R1M0' # Target OS release
+
+export TARGETLIB STATBNDDIR DYNBNDDIR SRVPGM IFSDIR
+export TGTCCSID DEBUG OPTIMIZE OUTPUT TGTRLS
+
+
+################################################################################
+#
+# OS/400 specific definitions.
+#
+################################################################################
+
+LIBIFSNAME="/QSYS.LIB/${TARGETLIB}.LIB"
+
+
+################################################################################
+#
+# Procedures.
+#
+################################################################################
+
+# action_needed dest [src]
+#
+# dest is an object to build
+# if specified, src is an object on which dest depends.
+#
+# exit 0 (succeeds) if some action has to be taken, else 1.
+
+action_needed()
+
+{
+ [ ! -e "${1}" ] && return 0
+ [ "${2}" ] || return 1
+ [ "${1}" -ot "${2}" ] && return 0
+ return 1
+}
+
+
+# make_module module_name source_name [additional_definitions]
+#
+# Compile source name into module if needed.
+# As side effect, append the module name to variable MODULES.
+# Set LINK to "YES" if the module has been compiled.
+
+make_module()
+
+{
+ MODULES="${MODULES} ${1}"
+ MODIFSNAME="${LIBIFSNAME}/${1}.MODULE"
+ CSRC="`basename \"${2}\"`"
+
+ if action_needed "${MODIFSNAME}" "${2}"
+ then :
+ elif [ ! "`sed -e \"/<source name=\\\"${CSRC}\\\">/,/<\\\\/source>/!d\" \
+ -e '/<depend /!d' \
+ -e 's/.* name=\"\\([^\"]*\\)\".*/\\1/' < \"${TOPDIR}/treebuild.xml\" |
+ while read HDR
+ do if action_needed \"${MODIFSNAME}\" \"${IFSDIR}/include/${HDR}\"
+ then echo recompile
+ break
+ fi
+ done`" ]
+ then return 0
+ fi
+
+ CMD="CRTCMOD MODULE(${TARGETLIB}/${1}) SRCSTMF('${2}')"
+ CMD="${CMD} SYSIFCOPT(*IFS64IO) OPTION(*INCDIRFIRST)"
+ CMD="${CMD} LOCALETYPE(*LOCALE) FLAG(10)"
+ CMD="${CMD} INCDIR('${IFSDIR}/include' ${INCLUDES})"
+ CMD="${CMD} TGTCCSID(${TGTCCSID}) TGTRLS(${TGTRLS})"
+ CMD="${CMD} OUTPUT(${OUTPUT})"
+ CMD="${CMD} OPTIMIZE(${OPTIMIZE})"
+ CMD="${CMD} DBGVIEW(${DEBUG})"
+ system "${CMD}"
+ LINK=YES
+}
+
+
+# Determine DB2 object name from IFS name.
+
+db2_name()
+
+{
+ basename "${1}" |
+ tr 'a-z-' 'A-Z_' |
+ sed -e 's/\..*//' \
+ -e 's/^\(.\).*\(.........\)$/\1\2/'
+}
+
+
+# Force enumeration types to be the same size as integers.
+
+copy_hfile()
+
+{
+ sed -e '1i\
+#pragma enum(int)\
+' "${@}" -e '$a\
+#pragma enum(pop)\
+'
+}
+
+
+################################################################################
+#
+# Script initialization.
+#
+################################################################################
+
+SCRIPTDIR=`dirname "${0}"`
+
+case "${SCRIPTDIR}" in
+/*) ;;
+*) SCRIPTDIR="`pwd`/${SCRIPTDIR}"
+esac
+
+while true
+do case "${SCRIPTDIR}" in
+ */.) SCRIPTDIR="${SCRIPTDIR%/.}";;
+ *) break;;
+ esac
+done
+
+# The script directory is supposed to be in ${TOPDIR}/os400.
+
+TOPDIR=`dirname "${SCRIPTDIR}"`
+export SCRIPTDIR TOPDIR
+cd "${TOPDIR}"
+
+
+# Extract the version from the master compilation XML file.
+
+VERSION=`sed -e '/^<package /!d' \
+ -e 's/^.* version="\([0-9.]*\)".*$/\1/' -e 'q' \
+ < treebuild.xml`
+export VERSION
+
+################################################################################
+
+
+# Create the OS/400 library if it does not exist.
+
+if action_needed "${LIBIFSNAME}"
+then CMD="CRTLIB LIB(${TARGETLIB}) TEXT('ZLIB: Data compression API')"
+ system "${CMD}"
+fi
+
+
+# Create the DOCS source file if it does not exist.
+
+if action_needed "${LIBIFSNAME}/DOCS.FILE"
+then CMD="CRTSRCPF FILE(${TARGETLIB}/DOCS) RCDLEN(112)"
+ CMD="${CMD} CCSID(${TGTCCSID}) TEXT('Documentation texts')"
+ system "${CMD}"
+fi
+
+# Copy some documentation files if needed.
+
+for TEXT in "${TOPDIR}/ChangeLog" "${TOPDIR}/FAQ" \
+ "${TOPDIR}/README" "${SCRIPTDIR}/README400"
+do MEMBER="${LIBIFSNAME}/DOCS.FILE/`db2_name \"${TEXT}\"`.MBR"
+
+ if action_needed "${MEMBER}" "${TEXT}"
+ then CMD="CPY OBJ('${TEXT}') TOOBJ('${MEMBER}') TOCCSID(${TGTCCSID})"
+ CMD="${CMD} DTAFMT(*TEXT) REPLACE(*YES)"
+ system "${CMD}"
+ fi
+done
+
+
+# Create the OS/400 source program file for the C header files.
+
+SRCPF="${LIBIFSNAME}/H.FILE"
+
+if action_needed "${SRCPF}"
+then CMD="CRTSRCPF FILE(${TARGETLIB}/H) RCDLEN(112)"
+ CMD="${CMD} CCSID(${TGTCCSID}) TEXT('ZLIB: C/C++ header files')"
+ system "${CMD}"
+fi
+
+
+# Create the IFS directory for the C header files.
+
+if action_needed "${IFSDIR}/include"
+then mkdir -p "${IFSDIR}/include"
+fi
+
+# Copy the header files to DB2 library. Link from IFS include directory.
+
+for HFILE in "${TOPDIR}/"*.h
+do DEST="${SRCPF}/`db2_name \"${HFILE}\"`.MBR"
+
+ if action_needed "${DEST}" "${HFILE}"
+ then copy_hfile < "${HFILE}" > tmphdrfile
+
+ # Need to translate to target CCSID.
+
+ CMD="CPY OBJ('`pwd`/tmphdrfile') TOOBJ('${DEST}')"
+ CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)"
+ system "${CMD}"
+ # touch -r "${HFILE}" "${DEST}"
+ rm -f tmphdrfile
+ fi
+
+ IFSFILE="${IFSDIR}/include/`basename \"${HFILE}\"`"
+
+ if action_needed "${IFSFILE}" "${DEST}"
+ then rm -f "${IFSFILE}"
+ ln -s "${DEST}" "${IFSFILE}"
+ fi
+done
+
+
+# Install the ILE/RPG header file.
+
+
+HFILE="${SCRIPTDIR}/zlib.inc"
+DEST="${SRCPF}/ZLIB.INC.MBR"
+
+if action_needed "${DEST}" "${HFILE}"
+then CMD="CPY OBJ('${HFILE}') TOOBJ('${DEST}')"
+ CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)"
+ system "${CMD}"
+ # touch -r "${HFILE}" "${DEST}"
+fi
+
+IFSFILE="${IFSDIR}/include/`basename \"${HFILE}\"`"
+
+if action_needed "${IFSFILE}" "${DEST}"
+then rm -f "${IFSFILE}"
+ ln -s "${DEST}" "${IFSFILE}"
+fi
+
+
+# Create and compile the identification source file.
+
+echo '#pragma comment(user, "ZLIB version '"${VERSION}"'")' > os400.c
+echo '#pragma comment(user, __DATE__)' >> os400.c
+echo '#pragma comment(user, __TIME__)' >> os400.c
+echo '#pragma comment(copyright, "Copyright (C) 1995-2017 Jean-Loup Gailly, Mark Adler. OS/400 version by P. Monnerat.")' >> os400.c
+make_module OS400 os400.c
+LINK= # No need to rebuild service program yet.
+MODULES=
+
+
+# Get source list.
+
+CSOURCES=`sed -e '/<source name="/!d' \
+ -e 's/.* name="\([^"]*\)".*/\1/' < treebuild.xml`
+
+# Compile the sources into modules.
+
+for SRC in ${CSOURCES}
+do MODULE=`db2_name "${SRC}"`
+ make_module "${MODULE}" "${SRC}"
+done
+
+
+# If needed, (re)create the static binding directory.
+
+if action_needed "${LIBIFSNAME}/${STATBNDDIR}.BNDDIR"
+then LINK=YES
+fi
+
+if [ "${LINK}" ]
+then rm -rf "${LIBIFSNAME}/${STATBNDDIR}.BNDDIR"
+ CMD="CRTBNDDIR BNDDIR(${TARGETLIB}/${STATBNDDIR})"
+ CMD="${CMD} TEXT('ZLIB static binding directory')"
+ system "${CMD}"
+
+ for MODULE in ${MODULES}
+ do CMD="ADDBNDDIRE BNDDIR(${TARGETLIB}/${STATBNDDIR})"
+ CMD="${CMD} OBJ((${TARGETLIB}/${MODULE} *MODULE))"
+ system "${CMD}"
+ done
+fi
+
+
+# The exportation file for service program creation must be in a DB2
+# source file, so make sure it exists.
+
+if action_needed "${LIBIFSNAME}/TOOLS.FILE"
+then CMD="CRTSRCPF FILE(${TARGETLIB}/TOOLS) RCDLEN(112)"
+ CMD="${CMD} CCSID(${TGTCCSID}) TEXT('ZLIB: build tools')"
+ system "${CMD}"
+fi
+
+
+DEST="${LIBIFSNAME}/TOOLS.FILE/BNDSRC.MBR"
+
+if action_needed "${SCRIPTDIR}/bndsrc" "${DEST}"
+then CMD="CPY OBJ('${SCRIPTDIR}/bndsrc') TOOBJ('${DEST}')"
+ CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)"
+ system "${CMD}"
+ # touch -r "${SCRIPTDIR}/bndsrc" "${DEST}"
+ LINK=YES
+fi
+
+
+# Build the service program if needed.
+
+if action_needed "${LIBIFSNAME}/${SRVPGM}.SRVPGM"
+then LINK=YES
+fi
+
+if [ "${LINK}" ]
+then CMD="CRTSRVPGM SRVPGM(${TARGETLIB}/${SRVPGM})"
+ CMD="${CMD} SRCFILE(${TARGETLIB}/TOOLS) SRCMBR(BNDSRC)"
+ CMD="${CMD} MODULE(${TARGETLIB}/OS400)"
+ CMD="${CMD} BNDDIR(${TARGETLIB}/${STATBNDDIR})"
+ CMD="${CMD} TEXT('ZLIB ${VERSION} dynamic library')"
+ CMD="${CMD} TGTRLS(${TGTRLS})"
+ system "${CMD}"
+ LINK=YES
+
+ # Duplicate the service program for a versioned backup.
+
+ BACKUP=`echo "${SRVPGM}${VERSION}" |
+ sed -e 's/.*\(..........\)$/\1/' -e 's/\./_/g'`
+ BACKUP="`db2_name \"${BACKUP}\"`"
+ BKUPIFSNAME="${LIBIFSNAME}/${BACKUP}.SRVPGM"
+ rm -f "${BKUPIFSNAME}"
+ CMD="CRTDUPOBJ OBJ(${SRVPGM}) FROMLIB(${TARGETLIB})"
+ CMD="${CMD} OBJTYPE(*SRVPGM) NEWOBJ(${BACKUP})"
+ system "${CMD}"
+fi
+
+
+# If needed, (re)create the dynamic binding directory.
+
+if action_needed "${LIBIFSNAME}/${DYNBNDDIR}.BNDDIR"
+then LINK=YES
+fi
+
+if [ "${LINK}" ]
+then rm -rf "${LIBIFSNAME}/${DYNBNDDIR}.BNDDIR"
+ CMD="CRTBNDDIR BNDDIR(${TARGETLIB}/${DYNBNDDIR})"
+ CMD="${CMD} TEXT('ZLIB dynamic binding directory')"
+ system "${CMD}"
+ CMD="ADDBNDDIRE BNDDIR(${TARGETLIB}/${DYNBNDDIR})"
+ CMD="${CMD} OBJ((*LIBL/${SRVPGM} *SRVPGM))"
+ system "${CMD}"
+fi
diff --git a/xs/src/png/zlib/os400/zlib.inc b/xs/src/png/zlib/os400/zlib.inc
new file mode 100644
index 000000000..c6aca2cbd
--- /dev/null
+++ b/xs/src/png/zlib/os400/zlib.inc
@@ -0,0 +1,527 @@
+ * ZLIB.INC - Interface to the general purpose compression library
+ *
+ * ILE RPG400 version by Patrick Monnerat, DATASPHERE.
+ * Version 1.2.11
+ *
+ *
+ * WARNING:
+ * Procedures inflateInit(), inflateInit2(), deflateInit(),
+ * deflateInit2() and inflateBackInit() need to be called with
+ * two additional arguments:
+ * the package version string and the stream control structure.
+ * size. This is needed because RPG lacks some macro feature.
+ * Call these procedures as:
+ * inflateInit(...: ZLIB_VERSION: %size(z_stream))
+ *
+ /if not defined(ZLIB_H_)
+ /define ZLIB_H_
+ *
+ **************************************************************************
+ * Constants
+ **************************************************************************
+ *
+ * Versioning information.
+ *
+ D ZLIB_VERSION C '1.2.11'
+ D ZLIB_VERNUM C X'12a0'
+ D ZLIB_VER_MAJOR C 1
+ D ZLIB_VER_MINOR C 2
+ D ZLIB_VER_REVISION...
+ D C 11
+ D ZLIB_VER_SUBREVISION...
+ D C 0
+ *
+ * Other equates.
+ *
+ D Z_NO_FLUSH C 0
+ D Z_PARTIAL_FLUSH...
+ D C 1
+ D Z_SYNC_FLUSH C 2
+ D Z_FULL_FLUSH C 3
+ D Z_FINISH C 4
+ D Z_BLOCK C 5
+ D Z_TREES C 6
+ *
+ D Z_OK C 0
+ D Z_STREAM_END C 1
+ D Z_NEED_DICT C 2
+ D Z_ERRNO C -1
+ D Z_STREAM_ERROR C -2
+ D Z_DATA_ERROR C -3
+ D Z_MEM_ERROR C -4
+ D Z_BUF_ERROR C -5
+ D Z_VERSION_ERROR C -6
+ *
+ D Z_NO_COMPRESSION...
+ D C 0
+ D Z_BEST_SPEED C 1
+ D Z_BEST_COMPRESSION...
+ D C 9
+ D Z_DEFAULT_COMPRESSION...
+ D C -1
+ *
+ D Z_FILTERED C 1
+ D Z_HUFFMAN_ONLY C 2
+ D Z_RLE C 3
+ D Z_DEFAULT_STRATEGY...
+ D C 0
+ *
+ D Z_BINARY C 0
+ D Z_ASCII C 1
+ D Z_UNKNOWN C 2
+ *
+ D Z_DEFLATED C 8
+ *
+ D Z_NULL C 0
+ *
+ **************************************************************************
+ * Types
+ **************************************************************************
+ *
+ D z_streamp S * Stream struct ptr
+ D gzFile S * File pointer
+ D gz_headerp S *
+ D z_off_t S 10i 0 Stream offsets
+ D z_off64_t S 20i 0 Stream offsets
+ *
+ **************************************************************************
+ * Structures
+ **************************************************************************
+ *
+ * The GZIP encode/decode stream support structure.
+ *
+ D z_stream DS align based(z_streamp)
+ D zs_next_in * Next input byte
+ D zs_avail_in 10U 0 Byte cnt at next_in
+ D zs_total_in 10U 0 Total bytes read
+ D zs_next_out * Output buffer ptr
+ D zs_avail_out 10U 0 Room left @ next_out
+ D zs_total_out 10U 0 Total bytes written
+ D zs_msg * Last errmsg or null
+ D zs_state * Internal state
+ D zs_zalloc * procptr Int. state allocator
+ D zs_free * procptr Int. state dealloc.
+ D zs_opaque * Private alloc. data
+ D zs_data_type 10i 0 ASC/BIN best guess
+ D zs_adler 10u 0 Uncompr. adler32 val
+ D 10U 0 Reserved
+ D 10U 0 Ptr. alignment
+ *
+ **************************************************************************
+ * Utility function prototypes
+ **************************************************************************
+ *
+ D compress PR 10I 0 extproc('compress')
+ D dest 65535 options(*varsize) Destination buffer
+ D destLen 10U 0 Destination length
+ D source 65535 const options(*varsize) Source buffer
+ D sourceLen 10u 0 value Source length
+ *
+ D compress2 PR 10I 0 extproc('compress2')
+ D dest 65535 options(*varsize) Destination buffer
+ D destLen 10U 0 Destination length
+ D source 65535 const options(*varsize) Source buffer
+ D sourceLen 10U 0 value Source length
+ D level 10I 0 value Compression level
+ *
+ D compressBound PR 10U 0 extproc('compressBound')
+ D sourceLen 10U 0 value
+ *
+ D uncompress PR 10I 0 extproc('uncompress')
+ D dest 65535 options(*varsize) Destination buffer
+ D destLen 10U 0 Destination length
+ D source 65535 const options(*varsize) Source buffer
+ D sourceLen 10U 0 value Source length
+ *
+ D uncompress2 PR 10I 0 extproc('uncompress2')
+ D dest 65535 options(*varsize) Destination buffer
+ D destLen 10U 0 Destination length
+ D source 65535 const options(*varsize) Source buffer
+ D sourceLen 10U 0 Source length
+ *
+ /if not defined(LARGE_FILES)
+ D gzopen PR extproc('gzopen')
+ D like(gzFile)
+ D path * value options(*string) File pathname
+ D mode * value options(*string) Open mode
+ /else
+ D gzopen PR extproc('gzopen64')
+ D like(gzFile)
+ D path * value options(*string) File pathname
+ D mode * value options(*string) Open mode
+ *
+ D gzopen64 PR extproc('gzopen64')
+ D like(gzFile)
+ D path * value options(*string) File pathname
+ D mode * value options(*string) Open mode
+ /endif
+ *
+ D gzdopen PR extproc('gzdopen')
+ D like(gzFile)
+ D fd 10I 0 value File descriptor
+ D mode * value options(*string) Open mode
+ *
+ D gzbuffer PR 10I 0 extproc('gzbuffer')
+ D file value like(gzFile) File pointer
+ D size 10U 0 value
+ *
+ D gzsetparams PR 10I 0 extproc('gzsetparams')
+ D file value like(gzFile) File pointer
+ D level 10I 0 value
+ D strategy 10I 0 value
+ *
+ D gzread PR 10I 0 extproc('gzread')
+ D file value like(gzFile) File pointer
+ D buf 65535 options(*varsize) Buffer
+ D len 10u 0 value Buffer length
+ *
+ D gzfread PR 20I 0 extproc('gzfread')
+ D buf 65535 options(*varsize) Buffer
+ D size 20u 0 value Buffer length
+ D nitems 20u 0 value Buffer length
+ D file value like(gzFile) File pointer
+ *
+ D gzwrite PR 10I 0 extproc('gzwrite')
+ D file value like(gzFile) File pointer
+ D buf 65535 const options(*varsize) Buffer
+ D len 10u 0 value Buffer length
+ *
+ D gzfwrite PR 20I 0 extproc('gzfwrite')
+ D buf 65535 options(*varsize) Buffer
+ D size 20u 0 value Buffer length
+ D nitems 20u 0 value Buffer length
+ D file value like(gzFile) File pointer
+ *
+ D gzputs PR 10I 0 extproc('gzputs')
+ D file value like(gzFile) File pointer
+ D s * value options(*string) String to output
+ *
+ D gzgets PR * extproc('gzgets')
+ D file value like(gzFile) File pointer
+ D buf 65535 options(*varsize) Read buffer
+ D len 10i 0 value Buffer length
+ *
+ D gzputc PR 10i 0 extproc('gzputc')
+ D file value like(gzFile) File pointer
+ D c 10I 0 value Character to write
+ *
+ D gzgetc PR 10i 0 extproc('gzgetc')
+ D file value like(gzFile) File pointer
+ *
+ D gzgetc_ PR 10i 0 extproc('gzgetc_')
+ D file value like(gzFile) File pointer
+ *
+ D gzungetc PR 10i 0 extproc('gzungetc')
+ D c 10I 0 value Character to push
+ D file value like(gzFile) File pointer
+ *
+ D gzflush PR 10i 0 extproc('gzflush')
+ D file value like(gzFile) File pointer
+ D flush 10I 0 value Type of flush
+ *
+ /if not defined(LARGE_FILES)
+ D gzseek PR extproc('gzseek')
+ D like(z_off_t)
+ D file value like(gzFile) File pointer
+ D offset value like(z_off_t) Offset
+ D whence 10i 0 value Origin
+ /else
+ D gzseek PR extproc('gzseek64')
+ D like(z_off_t)
+ D file value like(gzFile) File pointer
+ D offset value like(z_off_t) Offset
+ D whence 10i 0 value Origin
+ *
+ D gzseek64 PR extproc('gzseek64')
+ D like(z_off64_t)
+ D file value like(gzFile) File pointer
+ D offset value like(z_off64_t) Offset
+ D whence 10i 0 value Origin
+ /endif
+ *
+ D gzrewind PR 10i 0 extproc('gzrewind')
+ D file value like(gzFile) File pointer
+ *
+ /if not defined(LARGE_FILES)
+ D gztell PR extproc('gztell')
+ D like(z_off_t)
+ D file value like(gzFile) File pointer
+ /else
+ D gztell PR extproc('gztell64')
+ D like(z_off_t)
+ D file value like(gzFile) File pointer
+ *
+ D gztell64 PR extproc('gztell64')
+ D like(z_off64_t)
+ D file value like(gzFile) File pointer
+ /endif
+ *
+ /if not defined(LARGE_FILES)
+ D gzoffset PR extproc('gzoffset')
+ D like(z_off_t)
+ D file value like(gzFile) File pointer
+ /else
+ D gzoffset PR extproc('gzoffset64')
+ D like(z_off_t)
+ D file value like(gzFile) File pointer
+ *
+ D gzoffset64 PR extproc('gzoffset64')
+ D like(z_off64_t)
+ D file value like(gzFile) File pointer
+ /endif
+ *
+ D gzeof PR 10i 0 extproc('gzeof')
+ D file value like(gzFile) File pointer
+ *
+ D gzdirect PR 10i 0 extproc('gzdirect')
+ D file value like(gzFile) File pointer
+ *
+ D gzclose_r PR 10i 0 extproc('gzclose_r')
+ D file value like(gzFile) File pointer
+ *
+ D gzclose_w PR 10i 0 extproc('gzclose_w')
+ D file value like(gzFile) File pointer
+ *
+ D gzclose PR 10i 0 extproc('gzclose')
+ D file value like(gzFile) File pointer
+ *
+ D gzerror PR * extproc('gzerror') Error string
+ D file value like(gzFile) File pointer
+ D errnum 10I 0 Error code
+ *
+ D gzclearerr PR extproc('gzclearerr')
+ D file value like(gzFile) File pointer
+ *
+ **************************************************************************
+ * Basic function prototypes
+ **************************************************************************
+ *
+ D zlibVersion PR * extproc('zlibVersion') Version string
+ *
+ D deflateInit PR 10I 0 extproc('deflateInit_') Init. compression
+ D strm like(z_stream) Compression stream
+ D level 10I 0 value Compression level
+ D version * value options(*string) Version string
+ D stream_size 10i 0 value Stream struct. size
+ *
+ D deflate PR 10I 0 extproc('deflate') Compress data
+ D strm like(z_stream) Compression stream
+ D flush 10I 0 value Flush type required
+ *
+ D deflateEnd PR 10I 0 extproc('deflateEnd') Termin. compression
+ D strm like(z_stream) Compression stream
+ *
+ D inflateInit PR 10I 0 extproc('inflateInit_') Init. expansion
+ D strm like(z_stream) Expansion stream
+ D version * value options(*string) Version string
+ D stream_size 10i 0 value Stream struct. size
+ *
+ D inflate PR 10I 0 extproc('inflate') Expand data
+ D strm like(z_stream) Expansion stream
+ D flush 10I 0 value Flush type required
+ *
+ D inflateEnd PR 10I 0 extproc('inflateEnd') Termin. expansion
+ D strm like(z_stream) Expansion stream
+ *
+ **************************************************************************
+ * Advanced function prototypes
+ **************************************************************************
+ *
+ D deflateInit2 PR 10I 0 extproc('deflateInit2_') Init. compression
+ D strm like(z_stream) Compression stream
+ D level 10I 0 value Compression level
+ D method 10I 0 value Compression method
+ D windowBits 10I 0 value log2(window size)
+ D memLevel 10I 0 value Mem/cmpress tradeoff
+ D strategy 10I 0 value Compression strategy
+ D version * value options(*string) Version string
+ D stream_size 10i 0 value Stream struct. size
+ *
+ D deflateSetDictionary...
+ D PR 10I 0 extproc('deflateSetDictionary') Init. dictionary
+ D strm like(z_stream) Compression stream
+ D dictionary 65535 const options(*varsize) Dictionary bytes
+ D dictLength 10U 0 value Dictionary length
+ *
+ D deflateCopy PR 10I 0 extproc('deflateCopy') Compress strm 2 strm
+ D dest like(z_stream) Destination stream
+ D source like(z_stream) Source stream
+ *
+ D deflateReset PR 10I 0 extproc('deflateReset') End and init. stream
+ D strm like(z_stream) Compression stream
+ *
+ D deflateParams PR 10I 0 extproc('deflateParams') Change level & strat
+ D strm like(z_stream) Compression stream
+ D level 10I 0 value Compression level
+ D strategy 10I 0 value Compression strategy
+ *
+ D deflateTune PR 10I 0 extproc('deflateTune')
+ D strm like(z_stream) Compression stream
+ D good 10I 0 value
+ D lazy 10I 0 value
+ D nice 10I 0 value
+ D chain 10I 0 value
+ *
+ D deflateBound PR 10U 0 extproc('deflateBound') Change level & strat
+ D strm like(z_stream) Compression stream
+ D sourcelen 10U 0 value Compression level
+ *
+ D deflatePending PR 10I 0 extproc('deflatePending') Change level & strat
+ D strm like(z_stream) Compression stream
+ D pending 10U 0 Pending bytes
+ D bits 10I 0 Pending bits
+ *
+ D deflatePrime PR 10I 0 extproc('deflatePrime') Change level & strat
+ D strm like(z_stream) Compression stream
+ D bits 10I 0 value # of bits to insert
+ D value 10I 0 value Bits to insert
+ *
+ D inflateInit2 PR 10I 0 extproc('inflateInit2_') Init. expansion
+ D strm like(z_stream) Expansion stream
+ D windowBits 10I 0 value log2(window size)
+ D version * value options(*string) Version string
+ D stream_size 10i 0 value Stream struct. size
+ *
+ D inflateSetDictionary...
+ D PR 10I 0 extproc('inflateSetDictionary') Init. dictionary
+ D strm like(z_stream) Expansion stream
+ D dictionary 65535 const options(*varsize) Dictionary bytes
+ D dictLength 10U 0 value Dictionary length
+ *
+ D inflateGetDictionary...
+ D PR 10I 0 extproc('inflateGetDictionary') Get dictionary
+ D strm like(z_stream) Expansion stream
+ D dictionary 65535 options(*varsize) Dictionary bytes
+ D dictLength 10U 0 Dictionary length
+ *
+ D deflateGetDictionary...
+ D PR 10I 0 extproc('deflateGetDictionary') Get dictionary
+ D strm like(z_stream) Expansion stream
+ D dictionary 65535 options(*varsize) Dictionary bytes
+ D dictLength 10U 0 Dictionary length
+ *
+ D inflateSync PR 10I 0 extproc('inflateSync') Sync. expansion
+ D strm like(z_stream) Expansion stream
+ *
+ D inflateCopy PR 10I 0 extproc('inflateCopy')
+ D dest like(z_stream) Destination stream
+ D source like(z_stream) Source stream
+ *
+ D inflateReset PR 10I 0 extproc('inflateReset') End and init. stream
+ D strm like(z_stream) Expansion stream
+ *
+ D inflateReset2 PR 10I 0 extproc('inflateReset2') End and init. stream
+ D strm like(z_stream) Expansion stream
+ D windowBits 10I 0 value Log2(buffer size)
+ *
+ D inflatePrime PR 10I 0 extproc('inflatePrime') Insert bits
+ D strm like(z_stream) Expansion stream
+ D bits 10I 0 value Bit count
+ D value 10I 0 value Bits to insert
+ *
+ D inflateMark PR 10I 0 extproc('inflateMark') Get inflate info
+ D strm like(z_stream) Expansion stream
+ *
+ D inflateCodesUsed...
+ PR 20U 0 extproc('inflateCodesUsed')
+ D strm like(z_stream) Expansion stream
+ *
+ D inflateValidate...
+ PR 20U 0 extproc('inflateValidate')
+ D strm like(z_stream) Expansion stream
+ D check 10I 0 value
+ *
+ D inflateGetHeader...
+ PR 10U 0 extproc('inflateGetHeader')
+ D strm like(z_stream) Expansion stream
+ D head like(gz_headerp)
+ *
+ D deflateSetHeader...
+ PR 10U 0 extproc('deflateSetHeader')
+ D strm like(z_stream) Expansion stream
+ D head like(gz_headerp)
+ *
+ D inflateBackInit...
+ D PR 10I 0 extproc('inflateBackInit_')
+ D strm like(z_stream) Expansion stream
+ D windowBits 10I 0 value Log2(buffer size)
+ D window 65535 options(*varsize) Buffer
+ D version * value options(*string) Version string
+ D stream_size 10i 0 value Stream struct. size
+ *
+ D inflateBack PR 10I 0 extproc('inflateBack')
+ D strm like(z_stream) Expansion stream
+ D in * value procptr Input function
+ D in_desc * value Input descriptor
+ D out * value procptr Output function
+ D out_desc * value Output descriptor
+ *
+ D inflateBackEnd PR 10I 0 extproc('inflateBackEnd')
+ D strm like(z_stream) Expansion stream
+ *
+ D zlibCompileFlags...
+ D PR 10U 0 extproc('zlibCompileFlags')
+ *
+ **************************************************************************
+ * Checksum function prototypes
+ **************************************************************************
+ *
+ D adler32 PR 10U 0 extproc('adler32') New checksum
+ D adler 10U 0 value Old checksum
+ D buf 65535 const options(*varsize) Bytes to accumulate
+ D len 10U 0 value Buffer length
+ *
+ D adler32_combine...
+ PR 10U 0 extproc('adler32_combine') New checksum
+ D adler1 10U 0 value Old checksum
+ D adler2 10U 0 value Old checksum
+ D len2 20U 0 value Buffer length
+ *
+ D adler32_z PR 10U 0 extproc('adler32_z') New checksum
+ D adler 10U 0 value Old checksum
+ D buf 65535 const options(*varsize) Bytes to accumulate
+ D len 20U 0 value Buffer length
+ *
+ D crc32 PR 10U 0 extproc('crc32') New checksum
+ D crc 10U 0 value Old checksum
+ D buf 65535 const options(*varsize) Bytes to accumulate
+ D len 10U 0 value Buffer length
+ *
+ D crc32_combine...
+ PR 10U 0 extproc('crc32_combine') New checksum
+ D crc1 10U 0 value Old checksum
+ D crc2 10U 0 value Old checksum
+ D len2 20U 0 value Buffer length
+ *
+ D crc32_z PR 10U 0 extproc('crc32_z') New checksum
+ D crc 10U 0 value Old checksum
+ D buf 65535 const options(*varsize) Bytes to accumulate
+ D len 20U 0 value Buffer length
+ *
+ **************************************************************************
+ * Miscellaneous function prototypes
+ **************************************************************************
+ *
+ D zError PR * extproc('zError') Error string
+ D err 10I 0 value Error code
+ *
+ D inflateSyncPoint...
+ D PR 10I 0 extproc('inflateSyncPoint')
+ D strm like(z_stream) Expansion stream
+ *
+ D get_crc_table PR * extproc('get_crc_table') Ptr to ulongs
+ *
+ D inflateUndermine...
+ D PR 10I 0 extproc('inflateUndermine')
+ D strm like(z_stream) Expansion stream
+ D arg 10I 0 value Error code
+ *
+ D inflateResetKeep...
+ D PR 10I 0 extproc('inflateResetKeep') End and init. stream
+ D strm like(z_stream) Expansion stream
+ *
+ D deflateResetKeep...
+ D PR 10I 0 extproc('deflateResetKeep') End and init. stream
+ D strm like(z_stream) Expansion stream
+ *
+ /endif
diff --git a/xs/src/png/zlib/qnx/package.qpg b/xs/src/png/zlib/qnx/package.qpg
new file mode 100644
index 000000000..31e8e90db
--- /dev/null
+++ b/xs/src/png/zlib/qnx/package.qpg
@@ -0,0 +1,141 @@
+<QPG:Generation>
+ <QPG:Options>
+ <QPG:User unattended="no" verbosity="2" listfiles="yes"/>
+ <QPG:Defaults type="qnx_package"/>
+ <QPG:Source></QPG:Source>
+ <QPG:Release number="+"/>
+ <QPG:Build></QPG:Build>
+ <QPG:FileSorting strip="yes"/>
+ <QPG:Package targets="combine"/>
+ <QPG:Repository generate="yes"/>
+ <QPG:FinalDir></QPG:FinalDir>
+ <QPG:Cleanup></QPG:Cleanup>
+ </QPG:Options>
+
+ <QPG:Responsible>
+ <QPG:Company></QPG:Company>
+ <QPG:Department></QPG:Department>
+ <QPG:Group></QPG:Group>
+ <QPG:Team></QPG:Team>
+ <QPG:Employee></QPG:Employee>
+ <QPG:EmailAddress></QPG:EmailAddress>
+ </QPG:Responsible>
+
+ <QPG:Values>
+ <QPG:Files>
+ <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
+ <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
+ <QPG:Add file="../libz.so.1.2.11" install="/opt/lib/" user="root:bin" permission="644"/>
+ <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.11"/>
+ <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.11"/>
+ <QPG:Add file="../libz.so.1.2.11" install="/opt/lib/" component="slib"/>
+ </QPG:Files>
+
+ <QPG:PackageFilter>
+ <QPM:PackageManifest>
+ <QPM:PackageDescription>
+ <QPM:PackageType>Library</QPM:PackageType>
+ <QPM:PackageReleaseNotes></QPM:PackageReleaseNotes>
+ <QPM:PackageReleaseUrgency>Medium</QPM:PackageReleaseUrgency>
+ <QPM:PackageRepository></QPM:PackageRepository>
+ <QPM:FileVersion>2.0</QPM:FileVersion>
+ </QPM:PackageDescription>
+
+ <QPM:ProductDescription>
+ <QPM:ProductName>zlib</QPM:ProductName>
+ <QPM:ProductIdentifier>zlib</QPM:ProductIdentifier>
+ <QPM:ProductEmail>alain.bonnefoy@icbt.com</QPM:ProductEmail>
+ <QPM:VendorName>Public</QPM:VendorName>
+ <QPM:VendorInstallName>public</QPM:VendorInstallName>
+ <QPM:VendorURL>www.gzip.org/zlib</QPM:VendorURL>
+ <QPM:VendorEmbedURL></QPM:VendorEmbedURL>
+ <QPM:VendorEmail></QPM:VendorEmail>
+ <QPM:AuthorName>Jean-Loup Gailly,Mark Adler</QPM:AuthorName>
+ <QPM:AuthorURL>www.gzip.org/zlib</QPM:AuthorURL>
+ <QPM:AuthorEmbedURL></QPM:AuthorEmbedURL>
+ <QPM:AuthorEmail>zlib@gzip.org</QPM:AuthorEmail>
+ <QPM:ProductIconSmall></QPM:ProductIconSmall>
+ <QPM:ProductIconLarge></QPM:ProductIconLarge>
+ <QPM:ProductDescriptionShort>A massively spiffy yet delicately unobtrusive compression library.</QPM:ProductDescriptionShort>
+ <QPM:ProductDescriptionLong>zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system.</QPM:ProductDescriptionLong>
+ <QPM:ProductDescriptionURL>http://www.gzip.org/zlib</QPM:ProductDescriptionURL>
+ <QPM:ProductDescriptionEmbedURL></QPM:ProductDescriptionEmbedURL>
+ </QPM:ProductDescription>
+
+ <QPM:ReleaseDescription>
+ <QPM:ReleaseVersion>1.2.11</QPM:ReleaseVersion>
+ <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
+ <QPM:ReleaseStability>Stable</QPM:ReleaseStability>
+ <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
+ <QPM:ReleaseNoteMajor></QPM:ReleaseNoteMajor>
+ <QPM:ExcludeCountries>
+ <QPM:Country></QPM:Country>
+ </QPM:ExcludeCountries>
+
+ <QPM:ReleaseCopyright>No License</QPM:ReleaseCopyright>
+ </QPM:ReleaseDescription>
+
+ <QPM:ContentDescription>
+ <QPM:ContentTopic xmlmultiple="true">Software Development/Libraries and Extensions/C Libraries</QPM:ContentTopic>
+ <QPM:ContentKeyword>zlib,compression</QPM:ContentKeyword>
+ <QPM:TargetOS>qnx6</QPM:TargetOS>
+ <QPM:HostOS>qnx6</QPM:HostOS>
+ <QPM:DisplayEnvironment xmlmultiple="true">None</QPM:DisplayEnvironment>
+ <QPM:TargetAudience xmlmultiple="true">Developer</QPM:TargetAudience>
+ </QPM:ContentDescription>
+ </QPM:PackageManifest>
+ </QPG:PackageFilter>
+
+ <QPG:PackageFilter proc="none" target="none">
+ <QPM:PackageManifest>
+ <QPM:ProductInstallationDependencies>
+ <QPM:ProductRequirements></QPM:ProductRequirements>
+ </QPM:ProductInstallationDependencies>
+
+ <QPM:ProductInstallationProcedure>
+ <QPM:Script xmlmultiple="true">
+ <QPM:ScriptName></QPM:ScriptName>
+ <QPM:ScriptType>Install</QPM:ScriptType>
+ <QPM:ScriptTiming>Post</QPM:ScriptTiming>
+ <QPM:ScriptBlocking>No</QPM:ScriptBlocking>
+ <QPM:ScriptResult>Ignore</QPM:ScriptResult>
+ <QPM:ShortDescription></QPM:ShortDescription>
+ <QPM:UseBinaries>No</QPM:UseBinaries>
+ <QPM:Priority>Optional</QPM:Priority>
+ </QPM:Script>
+ </QPM:ProductInstallationProcedure>
+ </QPM:PackageManifest>
+
+ <QPM:Launch>
+ </QPM:Launch>
+ </QPG:PackageFilter>
+
+ <QPG:PackageFilter type="core" component="none">
+ <QPM:PackageManifest>
+ <QPM:ProductInstallationProcedure>
+ <QPM:OrderDependency xmlmultiple="true">
+ <QPM:Order>InstallOver</QPM:Order>
+ <QPM:Product>zlib</QPM:Product>
+ </QPM:OrderDependency>
+ </QPM:ProductInstallationProcedure>
+ </QPM:PackageManifest>
+
+ <QPM:Launch>
+ </QPM:Launch>
+ </QPG:PackageFilter>
+
+ <QPG:PackageFilter type="core" component="dev">
+ <QPM:PackageManifest>
+ <QPM:ProductInstallationProcedure>
+ <QPM:OrderDependency xmlmultiple="true">
+ <QPM:Order>InstallOver</QPM:Order>
+ <QPM:Product>zlib-dev</QPM:Product>
+ </QPM:OrderDependency>
+ </QPM:ProductInstallationProcedure>
+ </QPM:PackageManifest>
+
+ <QPM:Launch>
+ </QPM:Launch>
+ </QPG:PackageFilter>
+ </QPG:Values>
+</QPG:Generation>
diff --git a/xs/src/png/zlib/treebuild.xml b/xs/src/png/zlib/treebuild.xml
new file mode 100644
index 000000000..fd75525f9
--- /dev/null
+++ b/xs/src/png/zlib/treebuild.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" ?>
+<package name="zlib" version="1.2.11">
+ <library name="zlib" dlversion="1.2.11" dlname="z">
+ <property name="description"> zip compression library </property>
+ <property name="include-target-dir" value="$(@PACKAGE/install-includedir)" />
+
+ <!-- fixme: not implemented yet -->
+ <property name="compiler/c/inline" value="yes" />
+
+ <include-file name="zlib.h" scope="public" mode="644" />
+ <include-file name="zconf.h" scope="public" mode="644" />
+
+ <source name="adler32.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ </source>
+ <source name="compress.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ </source>
+ <source name="crc32.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="crc32.h" />
+ </source>
+ <source name="gzclose.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="gzguts.h" />
+ </source>
+ <source name="gzlib.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="gzguts.h" />
+ </source>
+ <source name="gzread.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="gzguts.h" />
+ </source>
+ <source name="gzwrite.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="gzguts.h" />
+ </source>
+ <source name="uncompr.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ </source>
+ <source name="deflate.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="zutil.h" />
+ <depend name="deflate.h" />
+ </source>
+ <source name="trees.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="zutil.h" />
+ <depend name="deflate.h" />
+ <depend name="trees.h" />
+ </source>
+ <source name="zutil.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="zutil.h" />
+ </source>
+ <source name="inflate.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="zutil.h" />
+ <depend name="inftrees.h" />
+ <depend name="inflate.h" />
+ <depend name="inffast.h" />
+ </source>
+ <source name="infback.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="zutil.h" />
+ <depend name="inftrees.h" />
+ <depend name="inflate.h" />
+ <depend name="inffast.h" />
+ </source>
+ <source name="inftrees.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="zutil.h" />
+ <depend name="inftrees.h" />
+ </source>
+ <source name="inffast.c">
+ <depend name="zlib.h" />
+ <depend name="zconf.h" />
+ <depend name="zutil.h" />
+ <depend name="inftrees.h" />
+ <depend name="inflate.h" />
+ <depend name="inffast.h" />
+ </source>
+ </library>
+</package>
+
+<!--
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DZLIB_DEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+# -Wstrict-prototypes -Wmissing-prototypes
+
+# OBJA =
+# to use the asm code: make OBJA=match.o
+#
+match.o: match.S
+ $(CPP) match.S > _match.s
+ $(CC) -c _match.s
+ mv _match.o match.o
+ rm -f _match.s
+-->
diff --git a/xs/src/png/zlib/trees.c b/xs/src/png/zlib/trees.c
new file mode 100644
index 000000000..50cf4b457
--- /dev/null
+++ b/xs/src/png/zlib/trees.c
@@ -0,0 +1,1203 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2017 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process uses several Huffman trees. The more
+ * common source values are represented by shorter bit sequences.
+ *
+ * Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values). The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ * Storer, James A.
+ * Data Compression: Methods and Theory, pp. 49-50.
+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
+ *
+ * Sedgewick, R.
+ * Algorithms, p290.
+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef ZLIB_DEBUG
+# include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6 16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10 17
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+#define REPZ_11_138 18
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+# include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+ const ct_data *static_tree; /* static tree or NULL */
+ const intf *extra_bits; /* extra bits for each code or NULL */
+ int extra_base; /* base index for extra_bits */
+ int elems; /* max number of elements in the tree */
+ int max_length; /* max bit length for the codes */
+};
+
+local const static_tree_desc static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local const static_tree_desc static_d_desc =
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
+
+local const static_tree_desc static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block OF((deflate_state *s));
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree OF((deflate_state *s, tree_desc *desc));
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local int build_bl_tree OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+ int blcodes));
+local void compress_block OF((deflate_state *s, const ct_data *ltree,
+ const ct_data *dtree));
+local int detect_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup OF((deflate_state *s));
+local void bi_flush OF((deflate_state *s));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef ZLIB_DEBUG
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+ /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* !ZLIB_DEBUG */
+# define send_code(s, c, tree) \
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+ send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+ put_byte(s, (uch)((w) & 0xff)); \
+ put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef ZLIB_DEBUG
+local void send_bits OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+ deflate_state *s;
+ int value; /* value to send */
+ int length; /* number of bits */
+{
+ Tracevv((stderr," l %2d v %4x ", length, value));
+ Assert(length > 0 && length <= 15, "invalid length");
+ s->bits_sent += (ulg)length;
+
+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+ * unused bits in value.
+ */
+ if (s->bi_valid > (int)Buf_size - length) {
+ s->bi_buf |= (ush)value << s->bi_valid;
+ put_short(s, s->bi_buf);
+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+ s->bi_valid += length - Buf_size;
+ } else {
+ s->bi_buf |= (ush)value << s->bi_valid;
+ s->bi_valid += length;
+ }
+}
+#else /* !ZLIB_DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = (int)value;\
+ s->bi_buf |= (ush)val << s->bi_valid;\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf |= (ush)(value) << s->bi_valid;\
+ s->bi_valid += len;\
+ }\
+}
+#endif /* ZLIB_DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+ static int static_init_done = 0;
+ int n; /* iterates over tree elements */
+ int bits; /* bit counter */
+ int length; /* length value */
+ int code; /* code value */
+ int dist; /* distance index */
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ if (static_init_done) return;
+
+ /* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
+ static_l_desc.static_tree = static_ltree;
+ static_l_desc.extra_bits = extra_lbits;
+ static_d_desc.static_tree = static_dtree;
+ static_d_desc.extra_bits = extra_dbits;
+ static_bl_desc.extra_bits = extra_blbits;
+#endif
+
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
+ length = 0;
+ for (code = 0; code < LENGTH_CODES-1; code++) {
+ base_length[code] = length;
+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
+ _length_code[length++] = (uch)code;
+ }
+ }
+ Assert (length == 256, "tr_static_init: length != 256");
+ /* Note that the length 255 (match length 258) can be represented
+ * in two different ways: code 284 + 5 bits or code 285, so we
+ * overwrite length_code[255] to use the best encoding:
+ */
+ _length_code[length-1] = (uch)code;
+
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
+ _dist_code[dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: dist != 256");
+ dist >>= 7; /* from now on, all distances are divided by 128 */
+ for ( ; code < D_CODES; code++) {
+ base_dist[code] = dist << 7;
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+ _dist_code[256 + dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+ /* Construct the codes of the static literal tree */
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+ n = 0;
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+ /* Codes 286 and 287 do not exist, but we must include them in the
+ * tree construction to get a canonical Huffman tree (longest code
+ * all ones)
+ */
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+ /* The static distance tree is trivial: */
+ for (n = 0; n < D_CODES; n++) {
+ static_dtree[n].Len = 5;
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+ }
+ static_init_done = 1;
+
+# ifdef GEN_TREES_H
+ gen_trees_header();
+# endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+# ifndef ZLIB_DEBUG
+# include <stdio.h>
+# endif
+
+# define SEPARATOR(i, last, width) \
+ ((i) == (last)? "\n};\n\n" : \
+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+ FILE *header = fopen("trees.h", "w");
+ int i;
+
+ Assert (header != NULL, "Can't open trees.h");
+ fprintf(header,
+ "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+ for (i = 0; i < L_CODES+2; i++) {
+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+ }
+
+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+ }
+
+ fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
+ for (i = 0; i < DIST_CODE_LEN; i++) {
+ fprintf(header, "%2u%s", _dist_code[i],
+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
+ }
+
+ fprintf(header,
+ "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+ fprintf(header, "%2u%s", _length_code[i],
+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+ }
+
+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+ for (i = 0; i < LENGTH_CODES; i++) {
+ fprintf(header, "%1u%s", base_length[i],
+ SEPARATOR(i, LENGTH_CODES-1, 20));
+ }
+
+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "%5u%s", base_dist[i],
+ SEPARATOR(i, D_CODES-1, 10));
+ }
+
+ fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void ZLIB_INTERNAL _tr_init(s)
+ deflate_state *s;
+{
+ tr_static_init();
+
+ s->l_desc.dyn_tree = s->dyn_ltree;
+ s->l_desc.stat_desc = &static_l_desc;
+
+ s->d_desc.dyn_tree = s->dyn_dtree;
+ s->d_desc.stat_desc = &static_d_desc;
+
+ s->bl_desc.dyn_tree = s->bl_tree;
+ s->bl_desc.stat_desc = &static_bl_desc;
+
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef ZLIB_DEBUG
+ s->compressed_len = 0L;
+ s->bits_sent = 0L;
+#endif
+
+ /* Initialize the first block of the first file: */
+ init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+ deflate_state *s;
+{
+ int n; /* iterates over tree elements */
+
+ /* Initialize the trees. */
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+ s->dyn_ltree[END_BLOCK].Freq = 1;
+ s->opt_len = s->static_len = 0L;
+ s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+ top = s->heap[SMALLEST]; \
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+ pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+ (tree[n].Freq < tree[m].Freq || \
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+ deflate_state *s;
+ ct_data *tree; /* the tree to restore */
+ int k; /* node to move down */
+{
+ int v = s->heap[k];
+ int j = k << 1; /* left son of k */
+ while (j <= s->heap_len) {
+ /* Set j to the smallest of the two sons: */
+ if (j < s->heap_len &&
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+ j++;
+ }
+ /* Exit if v is smaller than both sons */
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+ /* Exchange v with the smallest son */
+ s->heap[k] = s->heap[j]; k = j;
+
+ /* And continue down the tree, setting j to the left son of k */
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ * above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ * array bl_count contains the frequencies for each bit length.
+ * The length opt_len is updated; static_len is also updated if stree is
+ * not null.
+ */
+local void gen_bitlen(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ int max_code = desc->max_code;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ const intf *extra = desc->stat_desc->extra_bits;
+ int base = desc->stat_desc->extra_base;
+ int max_length = desc->stat_desc->max_length;
+ int h; /* heap index */
+ int n, m; /* iterate over the tree elements */
+ int bits; /* bit length */
+ int xbits; /* extra bits */
+ ush f; /* frequency */
+ int overflow = 0; /* number of elements with bit length too large */
+
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+ /* In a first pass, compute the optimal bit lengths (which may
+ * overflow in the case of the bit length tree).
+ */
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+ n = s->heap[h];
+ bits = tree[tree[n].Dad].Len + 1;
+ if (bits > max_length) bits = max_length, overflow++;
+ tree[n].Len = (ush)bits;
+ /* We overwrite tree[n].Dad which is no longer needed */
+
+ if (n > max_code) continue; /* not a leaf node */
+
+ s->bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n-base];
+ f = tree[n].Freq;
+ s->opt_len += (ulg)f * (unsigned)(bits + xbits);
+ if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits);
+ }
+ if (overflow == 0) return;
+
+ Tracev((stderr,"\nbit length overflow\n"));
+ /* This happens for example on obj2 and pic of the Calgary corpus */
+
+ /* Find the first bit length which could increase: */
+ do {
+ bits = max_length-1;
+ while (s->bl_count[bits] == 0) bits--;
+ s->bl_count[bits]--; /* move one leaf down the tree */
+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+ s->bl_count[max_length]--;
+ /* The brother of the overflow item also moves one step up,
+ * but this does not affect bl_count[max_length]
+ */
+ overflow -= 2;
+ } while (overflow > 0);
+
+ /* Now recompute all bit lengths, scanning in increasing frequency.
+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+ * lengths instead of fixing only the wrong ones. This idea is taken
+ * from 'ar' written by Haruhiko Okumura.)
+ */
+ for (bits = max_length; bits != 0; bits--) {
+ n = s->bl_count[bits];
+ while (n != 0) {
+ m = s->heap[--h];
+ if (m > max_code) continue;
+ if ((unsigned) tree[m].Len != (unsigned) bits) {
+ Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq;
+ tree[m].Len = (ush)bits;
+ }
+ n--;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ * zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+ ct_data *tree; /* the tree to decorate */
+ int max_code; /* largest code with non zero frequency */
+ ushf *bl_count; /* number of codes at each bit length */
+{
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+ unsigned code = 0; /* running code value */
+ int bits; /* bit index */
+ int n; /* code index */
+
+ /* The distribution counts are first used to generate the code values
+ * without bit reversal.
+ */
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ code = (code + bl_count[bits-1]) << 1;
+ next_code[bits] = (ush)code;
+ }
+ /* Check that the bit counts in bl_count are consistent. The last code
+ * must be all ones.
+ */
+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+ "inconsistent bit counts");
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++) {
+ int len = tree[n].Len;
+ if (len == 0) continue;
+ /* Now reverse the bits */
+ tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
+
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+ }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ * and corresponding code. The length opt_len is updated; static_len is
+ * also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ int elems = desc->stat_desc->elems;
+ int n, m; /* iterate over heap elements */
+ int max_code = -1; /* largest code with non zero frequency */
+ int node; /* new node being created */
+
+ /* Construct the initial heap, with least frequent element in
+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ * heap[0] is not used.
+ */
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n].Freq != 0) {
+ s->heap[++(s->heap_len)] = max_code = n;
+ s->depth[n] = 0;
+ } else {
+ tree[n].Len = 0;
+ }
+ }
+
+ /* The pkzip format requires that at least one distance code exists,
+ * and that at least one bit should be sent even if there is only one
+ * possible code. So to avoid special checks later on we force at least
+ * two codes of non zero frequency.
+ */
+ while (s->heap_len < 2) {
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+ tree[node].Freq = 1;
+ s->depth[node] = 0;
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+ /* node is 0 or 1 so it does not have extra bits */
+ }
+ desc->max_code = max_code;
+
+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ * establish sub-heaps of increasing lengths:
+ */
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+ /* Construct the Huffman tree by repeatedly combining the least two
+ * frequent nodes.
+ */
+ node = elems; /* next internal node of the tree */
+ do {
+ pqremove(s, tree, n); /* n = node of least frequency */
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+ s->heap[--(s->heap_max)] = m;
+
+ /* Create a new node father of n and m */
+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
+ s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+ s->depth[n] : s->depth[m]) + 1);
+ tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+ if (tree == s->bl_tree) {
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+ }
+#endif
+ /* and insert the new node in the heap */
+ s->heap[SMALLEST] = node++;
+ pqdownheap(s, tree, SMALLEST);
+
+ } while (s->heap_len >= 2);
+
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+ /* At this point, the fields freq and dad are set. We can now
+ * generate the bit lengths.
+ */
+ gen_bitlen(s, (tree_desc *)desc);
+
+ /* The field len is now set, we can generate the bit codes */
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ if (nextlen == 0) max_count = 138, min_count = 3;
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ s->bl_tree[curlen].Freq += count;
+ } else if (curlen != 0) {
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+ s->bl_tree[REP_3_6].Freq++;
+ } else if (count <= 10) {
+ s->bl_tree[REPZ_3_10].Freq++;
+ } else {
+ s->bl_tree[REPZ_11_138].Freq++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
+ if (nextlen == 0) max_count = 138, min_count = 3;
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) {
+ send_code(s, curlen, s->bl_tree); count--;
+ }
+ Assert(count >= 3 && count <= 6, " 3_6?");
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+ } else if (count <= 10) {
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+ } else {
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+ deflate_state *s;
+{
+ int max_blindex; /* index of last bit length code of non zero freq */
+
+ /* Determine the bit length frequencies for literal and distance trees */
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+ /* Build the bit length tree: */
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
+ /* opt_len now includes the length of the tree representations, except
+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+ */
+
+ /* Determine the number of bit length codes to send. The pkzip format
+ * requires that at least 4 bit length codes be sent. (appnote.txt says
+ * 3 but the actual value used is 4.)
+ */
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+ }
+ /* Update opt_len to include the bit length tree and counts */
+ s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4;
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+ s->opt_len, s->static_len));
+
+ return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+ deflate_state *s;
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+ int rank; /* index in bl_order */
+
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+ "too many codes");
+ Tracev((stderr, "\nbl counts: "));
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+ send_bits(s, dcodes-1, 5);
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
+ for (rank = 0; rank < blcodes; rank++) {
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+ }
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int last; /* one if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */
+ bi_windup(s); /* align on byte boundary */
+ put_short(s, (ush)stored_len);
+ put_short(s, (ush)~stored_len);
+ zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
+ s->pending += stored_len;
+#ifdef ZLIB_DEBUG
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+ s->compressed_len += (stored_len + 4) << 3;
+ s->bits_sent += 2*16;
+ s->bits_sent += stored_len<<3;
+#endif
+}
+
+/* ===========================================================================
+ * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
+ */
+void ZLIB_INTERNAL _tr_flush_bits(s)
+ deflate_state *s;
+{
+ bi_flush(s);
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ */
+void ZLIB_INTERNAL _tr_align(s)
+ deflate_state *s;
+{
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef ZLIB_DEBUG
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+ bi_flush(s);
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and write out the encoded block.
+ */
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int last; /* one if this is the last block for a file */
+{
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
+
+ /* Build the Huffman trees unless a stored block is forced */
+ if (s->level > 0) {
+
+ /* Check if the file is binary or text */
+ if (s->strm->data_type == Z_UNKNOWN)
+ s->strm->data_type = detect_data_type(s);
+
+ /* Construct the literal and distance trees */
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+ /* At this point, opt_len and static_len are the total bit lengths of
+ * the compressed block data, excluding the tree representations.
+ */
+
+ /* Build the bit length tree for the above two trees, and get the index
+ * in bl_order of the last bit length code to send.
+ */
+ max_blindex = build_bl_tree(s);
+
+ /* Determine the best encoding. Compute the block lengths in bytes. */
+ opt_lenb = (s->opt_len+3+7)>>3;
+ static_lenb = (s->static_len+3+7)>>3;
+
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+ s->last_lit));
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+ } else {
+ Assert(buf != (char*)0, "lost buf");
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+ }
+
+#ifdef FORCE_STORED
+ if (buf != (char*)0) { /* force stored block */
+#else
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+ /* 4: two words for the lengths */
+#endif
+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ * Otherwise we can't have processed more than WSIZE input bytes since
+ * the last block flush, because compression would have been
+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ * transform a block into a stored block.
+ */
+ _tr_stored_block(s, buf, stored_len, last);
+
+#ifdef FORCE_STATIC
+ } else if (static_lenb >= 0) { /* force static trees */
+#else
+ } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+ send_bits(s, (STATIC_TREES<<1)+last, 3);
+ compress_block(s, (const ct_data *)static_ltree,
+ (const ct_data *)static_dtree);
+#ifdef ZLIB_DEBUG
+ s->compressed_len += 3 + s->static_len;
+#endif
+ } else {
+ send_bits(s, (DYN_TREES<<1)+last, 3);
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+ max_blindex+1);
+ compress_block(s, (const ct_data *)s->dyn_ltree,
+ (const ct_data *)s->dyn_dtree);
+#ifdef ZLIB_DEBUG
+ s->compressed_len += 3 + s->opt_len;
+#endif
+ }
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+ /* The above check is made mod 2^32, for files larger than 512 MB
+ * and uLong implemented on 32 bits.
+ */
+ init_block(s);
+
+ if (last) {
+ bi_windup(s);
+#ifdef ZLIB_DEBUG
+ s->compressed_len += 7; /* align on byte boundary */
+#endif
+ }
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+ s->compressed_len-7*last));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
+ deflate_state *s;
+ unsigned dist; /* distance of matched string */
+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+ s->d_buf[s->last_lit] = (ush)dist;
+ s->l_buf[s->last_lit++] = (uch)lc;
+ if (dist == 0) {
+ /* lc is the unmatched char */
+ s->dyn_ltree[lc].Freq++;
+ } else {
+ s->matches++;
+ /* Here, lc is the match length - MIN_MATCH */
+ dist--; /* dist = match distance - 1 */
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+ s->dyn_dtree[d_code(dist)].Freq++;
+ }
+
+#ifdef TRUNCATE_BLOCK
+ /* Try to guess if it is profitable to stop the current block here */
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+ /* Compute an upper bound for the compressed length */
+ ulg out_length = (ulg)s->last_lit*8L;
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
+ (5L+extra_dbits[dcode]);
+ }
+ out_length >>= 3;
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+ s->last_lit, in_length, out_length,
+ 100L - out_length*100L/in_length));
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+ }
+#endif
+ return (s->last_lit == s->lit_bufsize-1);
+ /* We avoid equality with lit_bufsize because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+ deflate_state *s;
+ const ct_data *ltree; /* literal tree */
+ const ct_data *dtree; /* distance tree */
+{
+ unsigned dist; /* distance of matched string */
+ int lc; /* match length or unmatched char (if dist == 0) */
+ unsigned lx = 0; /* running index in l_buf */
+ unsigned code; /* the code to send */
+ int extra; /* number of extra bits to send */
+
+ if (s->last_lit != 0) do {
+ dist = s->d_buf[lx];
+ lc = s->l_buf[lx++];
+ if (dist == 0) {
+ send_code(s, lc, ltree); /* send a literal byte */
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+ } else {
+ /* Here, lc is the match length - MIN_MATCH */
+ code = _length_code[lc];
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
+ extra = extra_lbits[code];
+ if (extra != 0) {
+ lc -= base_length[code];
+ send_bits(s, lc, extra); /* send the extra length bits */
+ }
+ dist--; /* dist is now the match distance - 1 */
+ code = d_code(dist);
+ Assert (code < D_CODES, "bad d_code");
+
+ send_code(s, code, dtree); /* send the distance code */
+ extra = extra_dbits[code];
+ if (extra != 0) {
+ dist -= (unsigned)base_dist[code];
+ send_bits(s, dist, extra); /* send the extra distance bits */
+ }
+ } /* literal or match pair ? */
+
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+ "pendingBuf overflow");
+
+ } while (lx < s->last_lit);
+
+ send_code(s, END_BLOCK, ltree);
+}
+
+/* ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ * a) There are no non-portable control characters belonging to the
+ * "black list" (0..6, 14..25, 28..31).
+ * b) There is at least one printable character belonging to the
+ * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ * "gray list" that is ignored in this detection algorithm:
+ * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local int detect_data_type(s)
+ deflate_state *s;
+{
+ /* black_mask is the bit mask of black-listed bytes
+ * set bits 0..6, 14..25, and 28..31
+ * 0xf3ffc07f = binary 11110011111111111100000001111111
+ */
+ unsigned long black_mask = 0xf3ffc07fUL;
+ int n;
+
+ /* Check for non-textual ("black-listed") bytes. */
+ for (n = 0; n <= 31; n++, black_mask >>= 1)
+ if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+ return Z_BINARY;
+
+ /* Check for textual ("white-listed") bytes. */
+ if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+ || s->dyn_ltree[13].Freq != 0)
+ return Z_TEXT;
+ for (n = 32; n < LITERALS; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ return Z_TEXT;
+
+ /* There are no "black-listed" or "white-listed" bytes:
+ * this stream either is empty or has tolerated ("gray-listed") bytes only.
+ */
+ return Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+ unsigned code; /* the value to invert */
+ int len; /* its bit length */
+{
+ register unsigned res = 0;
+ do {
+ res |= code & 1;
+ code >>= 1, res <<= 1;
+ } while (--len > 0);
+ return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+ deflate_state *s;
+{
+ if (s->bi_valid == 16) {
+ put_short(s, s->bi_buf);
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ } else if (s->bi_valid >= 8) {
+ put_byte(s, (Byte)s->bi_buf);
+ s->bi_buf >>= 8;
+ s->bi_valid -= 8;
+ }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+ deflate_state *s;
+{
+ if (s->bi_valid > 8) {
+ put_short(s, s->bi_buf);
+ } else if (s->bi_valid > 0) {
+ put_byte(s, (Byte)s->bi_buf);
+ }
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef ZLIB_DEBUG
+ s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
diff --git a/xs/src/png/zlib/trees.h b/xs/src/png/zlib/trees.h
new file mode 100644
index 000000000..d35639d82
--- /dev/null
+++ b/xs/src/png/zlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
+};
+
diff --git a/xs/src/png/zlib/uncompr.c b/xs/src/png/zlib/uncompr.c
new file mode 100644
index 000000000..f03a1a865
--- /dev/null
+++ b/xs/src/png/zlib/uncompr.c
@@ -0,0 +1,93 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Decompresses the source buffer into the destination buffer. *sourceLen is
+ the byte length of the source buffer. Upon entry, *destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit,
+ *destLen is the size of the decompressed data and *sourceLen is the number
+ of source bytes consumed. Upon return, source + *sourceLen points to the
+ first unused input byte.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
+ Z_DATA_ERROR if the input data was corrupted, including if the input data is
+ an incomplete zlib stream.
+*/
+int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong *sourceLen;
+{
+ z_stream stream;
+ int err;
+ const uInt max = (uInt)-1;
+ uLong len, left;
+ Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */
+
+ len = *sourceLen;
+ if (*destLen) {
+ left = *destLen;
+ *destLen = 0;
+ }
+ else {
+ left = 1;
+ dest = buf;
+ }
+
+ stream.next_in = (z_const Bytef *)source;
+ stream.avail_in = 0;
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ stream.next_out = dest;
+ stream.avail_out = 0;
+
+ do {
+ if (stream.avail_out == 0) {
+ stream.avail_out = left > (uLong)max ? max : (uInt)left;
+ left -= stream.avail_out;
+ }
+ if (stream.avail_in == 0) {
+ stream.avail_in = len > (uLong)max ? max : (uInt)len;
+ len -= stream.avail_in;
+ }
+ err = inflate(&stream, Z_NO_FLUSH);
+ } while (err == Z_OK);
+
+ *sourceLen -= len + stream.avail_in;
+ if (dest != buf)
+ *destLen = stream.total_out;
+ else if (stream.total_out && err == Z_BUF_ERROR)
+ left = 1;
+
+ inflateEnd(&stream);
+ return err == Z_STREAM_END ? Z_OK :
+ err == Z_NEED_DICT ? Z_DATA_ERROR :
+ err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
+ err;
+}
+
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return uncompress2(dest, destLen, source, &sourceLen);
+}
diff --git a/xs/src/png/zlib/watcom/watcom_f.mak b/xs/src/png/zlib/watcom/watcom_f.mak
new file mode 100644
index 000000000..37f4d74c1
--- /dev/null
+++ b/xs/src/png/zlib/watcom/watcom_f.mak
@@ -0,0 +1,43 @@
+# Makefile for zlib
+# OpenWatcom flat model
+# Last updated: 28-Dec-2005
+
+# To use, do "wmake -f watcom_f.mak"
+
+C_SOURCE = adler32.c compress.c crc32.c deflate.c &
+ gzclose.c gzlib.c gzread.c gzwrite.c &
+ infback.c inffast.c inflate.c inftrees.c &
+ trees.c uncompr.c zutil.c
+
+OBJS = adler32.obj compress.obj crc32.obj deflate.obj &
+ gzclose.obj gzlib.obj gzread.obj gzwrite.obj &
+ infback.obj inffast.obj inflate.obj inftrees.obj &
+ trees.obj uncompr.obj zutil.obj
+
+CC = wcc386
+LINKER = wcl386
+CFLAGS = -zq -mf -3r -fp3 -s -bt=dos -oilrtfm -fr=nul -wx
+ZLIB_LIB = zlib_f.lib
+
+.C.OBJ:
+ $(CC) $(CFLAGS) $[@
+
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+$(ZLIB_LIB): $(OBJS)
+ wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj
+ wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj
+ wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj
+ wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj
+ wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj
+
+example.exe: $(ZLIB_LIB) example.obj
+ $(LINKER) -ldos32a -fe=example.exe example.obj $(ZLIB_LIB)
+
+minigzip.exe: $(ZLIB_LIB) minigzip.obj
+ $(LINKER) -ldos32a -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)
+
+clean: .SYMBOLIC
+ del *.obj
+ del $(ZLIB_LIB)
+ @echo Cleaning done
diff --git a/xs/src/png/zlib/watcom/watcom_l.mak b/xs/src/png/zlib/watcom/watcom_l.mak
new file mode 100644
index 000000000..193eed7b3
--- /dev/null
+++ b/xs/src/png/zlib/watcom/watcom_l.mak
@@ -0,0 +1,43 @@
+# Makefile for zlib
+# OpenWatcom large model
+# Last updated: 28-Dec-2005
+
+# To use, do "wmake -f watcom_l.mak"
+
+C_SOURCE = adler32.c compress.c crc32.c deflate.c &
+ gzclose.c gzlib.c gzread.c gzwrite.c &
+ infback.c inffast.c inflate.c inftrees.c &
+ trees.c uncompr.c zutil.c
+
+OBJS = adler32.obj compress.obj crc32.obj deflate.obj &
+ gzclose.obj gzlib.obj gzread.obj gzwrite.obj &
+ infback.obj inffast.obj inflate.obj inftrees.obj &
+ trees.obj uncompr.obj zutil.obj
+
+CC = wcc
+LINKER = wcl
+CFLAGS = -zq -ml -s -bt=dos -oilrtfm -fr=nul -wx
+ZLIB_LIB = zlib_l.lib
+
+.C.OBJ:
+ $(CC) $(CFLAGS) $[@
+
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+$(ZLIB_LIB): $(OBJS)
+ wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj
+ wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj
+ wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj
+ wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj
+ wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj
+
+example.exe: $(ZLIB_LIB) example.obj
+ $(LINKER) -fe=example.exe example.obj $(ZLIB_LIB)
+
+minigzip.exe: $(ZLIB_LIB) minigzip.obj
+ $(LINKER) -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)
+
+clean: .SYMBOLIC
+ del *.obj
+ del $(ZLIB_LIB)
+ @echo Cleaning done
diff --git a/xs/src/png/zlib/win32/DLL_FAQ.txt b/xs/src/png/zlib/win32/DLL_FAQ.txt
new file mode 100644
index 000000000..12c009018
--- /dev/null
+++ b/xs/src/png/zlib/win32/DLL_FAQ.txt
@@ -0,0 +1,397 @@
+
+ Frequently Asked Questions about ZLIB1.DLL
+
+
+This document describes the design, the rationale, and the usage
+of the official DLL build of zlib, named ZLIB1.DLL. If you have
+general questions about zlib, you should see the file "FAQ" found
+in the zlib distribution, or at the following location:
+ http://www.gzip.org/zlib/zlib_faq.html
+
+
+ 1. What is ZLIB1.DLL, and how can I get it?
+
+ - ZLIB1.DLL is the official build of zlib as a DLL.
+ (Please remark the character '1' in the name.)
+
+ Pointers to a precompiled ZLIB1.DLL can be found in the zlib
+ web site at:
+ http://www.zlib.net/
+
+ Applications that link to ZLIB1.DLL can rely on the following
+ specification:
+
+ * The exported symbols are exclusively defined in the source
+ files "zlib.h" and "zlib.def", found in an official zlib
+ source distribution.
+ * The symbols are exported by name, not by ordinal.
+ * The exported names are undecorated.
+ * The calling convention of functions is "C" (CDECL).
+ * The ZLIB1.DLL binary is linked to MSVCRT.DLL.
+
+ The archive in which ZLIB1.DLL is bundled contains compiled
+ test programs that must run with a valid build of ZLIB1.DLL.
+ It is recommended to download the prebuilt DLL from the zlib
+ web site, instead of building it yourself, to avoid potential
+ incompatibilities that could be introduced by your compiler
+ and build settings. If you do build the DLL yourself, please
+ make sure that it complies with all the above requirements,
+ and it runs with the precompiled test programs, bundled with
+ the original ZLIB1.DLL distribution.
+
+ If, for any reason, you need to build an incompatible DLL,
+ please use a different file name.
+
+
+ 2. Why did you change the name of the DLL to ZLIB1.DLL?
+ What happened to the old ZLIB.DLL?
+
+ - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required
+ compilation settings that were incompatible to those used by
+ a static build. The DLL settings were supposed to be enabled
+ by defining the macro ZLIB_DLL, before including "zlib.h".
+ Incorrect handling of this macro was silently accepted at
+ build time, resulting in two major problems:
+
+ * ZLIB_DLL was missing from the old makefile. When building
+ the DLL, not all people added it to the build options. In
+ consequence, incompatible incarnations of ZLIB.DLL started
+ to circulate around the net.
+
+ * When switching from using the static library to using the
+ DLL, applications had to define the ZLIB_DLL macro and
+ to recompile all the sources that contained calls to zlib
+ functions. Failure to do so resulted in creating binaries
+ that were unable to run with the official ZLIB.DLL build.
+
+ The only possible solution that we could foresee was to make
+ a binary-incompatible change in the DLL interface, in order to
+ remove the dependency on the ZLIB_DLL macro, and to release
+ the new DLL under a different name.
+
+ We chose the name ZLIB1.DLL, where '1' indicates the major
+ zlib version number. We hope that we will not have to break
+ the binary compatibility again, at least not as long as the
+ zlib-1.x series will last.
+
+ There is still a ZLIB_DLL macro, that can trigger a more
+ efficient build and use of the DLL, but compatibility no
+ longer dependents on it.
+
+
+ 3. Can I build ZLIB.DLL from the new zlib sources, and replace
+ an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier?
+
+ - In principle, you can do it by assigning calling convention
+ keywords to the macros ZEXPORT and ZEXPORTVA. In practice,
+ it depends on what you mean by "an old ZLIB.DLL", because the
+ old DLL exists in several mutually-incompatible versions.
+ You have to find out first what kind of calling convention is
+ being used in your particular ZLIB.DLL build, and to use the
+ same one in the new build. If you don't know what this is all
+ about, you might be better off if you would just leave the old
+ DLL intact.
+
+
+ 4. Can I compile my application using the new zlib interface, and
+ link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or
+ earlier?
+
+ - The official answer is "no"; the real answer depends again on
+ what kind of ZLIB.DLL you have. Even if you are lucky, this
+ course of action is unreliable.
+
+ If you rebuild your application and you intend to use a newer
+ version of zlib (post- 1.1.4), it is strongly recommended to
+ link it to the new ZLIB1.DLL.
+
+
+ 5. Why are the zlib symbols exported by name, and not by ordinal?
+
+ - Although exporting symbols by ordinal is a little faster, it
+ is risky. Any single glitch in the maintenance or use of the
+ DEF file that contains the ordinals can result in incompatible
+ builds and frustrating crashes. Simply put, the benefits of
+ exporting symbols by ordinal do not justify the risks.
+
+ Technically, it should be possible to maintain ordinals in
+ the DEF file, and still export the symbols by name. Ordinals
+ exist in every DLL, and even if the dynamic linking performed
+ at the DLL startup is searching for names, ordinals serve as
+ hints, for a faster name lookup. However, if the DEF file
+ contains ordinals, the Microsoft linker automatically builds
+ an implib that will cause the executables linked to it to use
+ those ordinals, and not the names. It is interesting to
+ notice that the GNU linker for Win32 does not suffer from this
+ problem.
+
+ It is possible to avoid the DEF file if the exported symbols
+ are accompanied by a "__declspec(dllexport)" attribute in the
+ source files. You can do this in zlib by predefining the
+ ZLIB_DLL macro.
+
+
+ 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling
+ convention. Why not use the STDCALL convention?
+ STDCALL is the standard convention in Win32, and I need it in
+ my Visual Basic project!
+
+ (For readability, we use CDECL to refer to the convention
+ triggered by the "__cdecl" keyword, STDCALL to refer to
+ the convention triggered by "__stdcall", and FASTCALL to
+ refer to the convention triggered by "__fastcall".)
+
+ - Most of the native Windows API functions (without varargs) use
+ indeed the WINAPI convention (which translates to STDCALL in
+ Win32), but the standard C functions use CDECL. If a user
+ application is intrinsically tied to the Windows API (e.g.
+ it calls native Windows API functions such as CreateFile()),
+ sometimes it makes sense to decorate its own functions with
+ WINAPI. But if ANSI C or POSIX portability is a goal (e.g.
+ it calls standard C functions such as fopen()), it is not a
+ sound decision to request the inclusion of <windows.h>, or to
+ use non-ANSI constructs, for the sole purpose to make the user
+ functions STDCALL-able.
+
+ The functionality offered by zlib is not in the category of
+ "Windows functionality", but is more like "C functionality".
+
+ Technically, STDCALL is not bad; in fact, it is slightly
+ faster than CDECL, and it works with variable-argument
+ functions, just like CDECL. It is unfortunate that, in spite
+ of using STDCALL in the Windows API, it is not the default
+ convention used by the C compilers that run under Windows.
+ The roots of the problem reside deep inside the unsafety of
+ the K&R-style function prototypes, where the argument types
+ are not specified; but that is another story for another day.
+
+ The remaining fact is that CDECL is the default convention.
+ Even if an explicit convention is hard-coded into the function
+ prototypes inside C headers, problems may appear. The
+ necessity to expose the convention in users' callbacks is one
+ of these problems.
+
+ The calling convention issues are also important when using
+ zlib in other programming languages. Some of them, like Ada
+ (GNAT) and Fortran (GNU G77), have C bindings implemented
+ initially on Unix, and relying on the C calling convention.
+ On the other hand, the pre- .NET versions of Microsoft Visual
+ Basic require STDCALL, while Borland Delphi prefers, although
+ it does not require, FASTCALL.
+
+ In fairness to all possible uses of zlib outside the C
+ programming language, we choose the default "C" convention.
+ Anyone interested in different bindings or conventions is
+ encouraged to maintain specialized projects. The "contrib/"
+ directory from the zlib distribution already holds a couple
+ of foreign bindings, such as Ada, C++, and Delphi.
+
+
+ 7. I need a DLL for my Visual Basic project. What can I do?
+
+ - Define the ZLIB_WINAPI macro before including "zlib.h", when
+ building both the DLL and the user application (except that
+ you don't need to define anything when using the DLL in Visual
+ Basic). The ZLIB_WINAPI macro will switch on the WINAPI
+ (STDCALL) convention. The name of this DLL must be different
+ than the official ZLIB1.DLL.
+
+ Gilles Vollant has contributed a build named ZLIBWAPI.DLL,
+ with the ZLIB_WINAPI macro turned on, and with the minizip
+ functionality built in. For more information, please read
+ the notes inside "contrib/vstudio/readme.txt", found in the
+ zlib distribution.
+
+
+ 8. I need to use zlib in my Microsoft .NET project. What can I
+ do?
+
+ - Henrik Ravn has contributed a .NET wrapper around zlib. Look
+ into contrib/dotzlib/, inside the zlib distribution.
+
+
+ 9. If my application uses ZLIB1.DLL, should I link it to
+ MSVCRT.DLL? Why?
+
+ - It is not required, but it is recommended to link your
+ application to MSVCRT.DLL, if it uses ZLIB1.DLL.
+
+ The executables (.EXE, .DLL, etc.) that are involved in the
+ same process and are using the C run-time library (i.e. they
+ are calling standard C functions), must link to the same
+ library. There are several libraries in the Win32 system:
+ CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc.
+ Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that
+ depend on it should also be linked to MSVCRT.DLL.
+
+
+10. Why are you saying that ZLIB1.DLL and my application should
+ be linked to the same C run-time (CRT) library? I linked my
+ application and my DLLs to different C libraries (e.g. my
+ application to a static library, and my DLLs to MSVCRT.DLL),
+ and everything works fine.
+
+ - If a user library invokes only pure Win32 API (accessible via
+ <windows.h> and the related headers), its DLL build will work
+ in any context. But if this library invokes standard C API,
+ things get more complicated.
+
+ There is a single Win32 library in a Win32 system. Every
+ function in this library resides in a single DLL module, that
+ is safe to call from anywhere. On the other hand, there are
+ multiple versions of the C library, and each of them has its
+ own separate internal state. Standalone executables and user
+ DLLs that call standard C functions must link to a C run-time
+ (CRT) library, be it static or shared (DLL). Intermixing
+ occurs when an executable (not necessarily standalone) and a
+ DLL are linked to different CRTs, and both are running in the
+ same process.
+
+ Intermixing multiple CRTs is possible, as long as their
+ internal states are kept intact. The Microsoft Knowledge Base
+ articles KB94248 "HOWTO: Use the C Run-Time" and KB140584
+ "HOWTO: Link with the Correct C Run-Time (CRT) Library"
+ mention the potential problems raised by intermixing.
+
+ If intermixing works for you, it's because your application
+ and DLLs are avoiding the corruption of each of the CRTs'
+ internal states, maybe by careful design, or maybe by fortune.
+
+ Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such
+ as those provided by Borland, raises similar problems.
+
+
+11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?
+
+ - MSVCRT.DLL exists on every Windows 95 with a new service pack
+ installed, or with Microsoft Internet Explorer 4 or later, and
+ on all other Windows 4.x or later (Windows 98, Windows NT 4,
+ or later). It is freely distributable; if not present in the
+ system, it can be downloaded from Microsoft or from other
+ software provider for free.
+
+ The fact that MSVCRT.DLL does not exist on a virgin Windows 95
+ is not so problematic. Windows 95 is scarcely found nowadays,
+ Microsoft ended its support a long time ago, and many recent
+ applications from various vendors, including Microsoft, do not
+ even run on it. Furthermore, no serious user should run
+ Windows 95 without a proper update installed.
+
+
+12. Why are you not linking ZLIB1.DLL to
+ <<my favorite C run-time library>> ?
+
+ - We considered and abandoned the following alternatives:
+
+ * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or
+ LIBCMT.LIB) is not a good option. People are using the DLL
+ mainly to save disk space. If you are linking your program
+ to a static C library, you may as well consider linking zlib
+ in statically, too.
+
+ * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because
+ CRTDLL.DLL is present on every Win32 installation.
+ Unfortunately, it has a series of problems: it does not
+ work properly with Microsoft's C++ libraries, it does not
+ provide support for 64-bit file offsets, (and so on...),
+ and Microsoft discontinued its support a long time ago.
+
+ * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied
+ with the Microsoft .NET platform, and Visual C++ 7.0/7.1,
+ raises problems related to the status of ZLIB1.DLL as a
+ system component. According to the Microsoft Knowledge Base
+ article KB326922 "INFO: Redistribution of the Shared C
+ Runtime Component in Visual C++ .NET", MSVCR70.DLL and
+ MSVCR71.DLL are not supposed to function as system DLLs,
+ because they may clash with MSVCRT.DLL. Instead, the
+ application's installer is supposed to put these DLLs
+ (if needed) in the application's private directory.
+ If ZLIB1.DLL depends on a non-system runtime, it cannot
+ function as a redistributable system component.
+
+ * Linking ZLIB1.DLL to non-Microsoft runtimes, such as
+ Borland's, or Cygwin's, raises problems related to the
+ reliable presence of these runtimes on Win32 systems.
+ It's easier to let the DLL build of zlib up to the people
+ who distribute these runtimes, and who may proceed as
+ explained in the answer to Question 14.
+
+
+13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL,
+ how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0
+ (Visual Studio .NET) or newer?
+
+ - Due to the problems explained in the Microsoft Knowledge Base
+ article KB326922 (see the previous answer), the C runtime that
+ comes with the VC7 environment is no longer considered a
+ system component. That is, it should not be assumed that this
+ runtime exists, or may be installed in a system directory.
+ Since ZLIB1.DLL is supposed to be a system component, it may
+ not depend on a non-system component.
+
+ In order to link ZLIB1.DLL and your application to MSVCRT.DLL
+ in VC7, you need the library of Visual C++ 6.0 or older. If
+ you don't have this library at hand, it's probably best not to
+ use ZLIB1.DLL.
+
+ We are hoping that, in the future, Microsoft will provide a
+ way to build applications linked to a proper system runtime,
+ from the Visual C++ environment. Until then, you have a
+ couple of alternatives, such as linking zlib in statically.
+ If your application requires dynamic linking, you may proceed
+ as explained in the answer to Question 14.
+
+
+14. I need to link my own DLL build to a CRT different than
+ MSVCRT.DLL. What can I do?
+
+ - Feel free to rebuild the DLL from the zlib sources, and link
+ it the way you want. You should, however, clearly state that
+ your build is unofficial. You should give it a different file
+ name, and/or install it in a private directory that can be
+ accessed by your application only, and is not visible to the
+ others (i.e. it's neither in the PATH, nor in the SYSTEM or
+ SYSTEM32 directories). Otherwise, your build may clash with
+ applications that link to the official build.
+
+ For example, in Cygwin, zlib is linked to the Cygwin runtime
+ CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.
+
+
+15. May I include additional pieces of code that I find useful,
+ link them in ZLIB1.DLL, and export them?
+
+ - No. A legitimate build of ZLIB1.DLL must not include code
+ that does not originate from the official zlib source code.
+ But you can make your own private DLL build, under a different
+ file name, as suggested in the previous answer.
+
+ For example, zlib is a part of the VCL library, distributed
+ with Borland Delphi and C++ Builder. The DLL build of VCL
+ is a redistributable file, named VCLxx.DLL.
+
+
+16. May I remove some functionality out of ZLIB1.DLL, by enabling
+ macros like NO_GZCOMPRESS or NO_GZIP at compile time?
+
+ - No. A legitimate build of ZLIB1.DLL must provide the complete
+ zlib functionality, as implemented in the official zlib source
+ code. But you can make your own private DLL build, under a
+ different file name, as suggested in the previous answer.
+
+
+17. I made my own ZLIB1.DLL build. Can I test it for compliance?
+
+ - We prefer that you download the official DLL from the zlib
+ web site. If you need something peculiar from this DLL, you
+ can send your suggestion to the zlib mailing list.
+
+ However, in case you do rebuild the DLL yourself, you can run
+ it with the test programs found in the DLL distribution.
+ Running these test programs is not a guarantee of compliance,
+ but a failure can imply a detected problem.
+
+**
+
+This document is written and maintained by
+Cosmin Truta <cosmint@cs.ubbcluj.ro>
diff --git a/xs/src/png/zlib/win32/Makefile.bor b/xs/src/png/zlib/win32/Makefile.bor
new file mode 100644
index 000000000..d152bbb7f
--- /dev/null
+++ b/xs/src/png/zlib/win32/Makefile.bor
@@ -0,0 +1,110 @@
+# Makefile for zlib
+# Borland C++ for Win32
+#
+# Usage:
+# make -f win32/Makefile.bor
+# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj
+
+# ------------ Borland C++ ------------
+
+# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or
+# added to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+CC = bcc32
+AS = bcc32
+LD = bcc32
+AR = tlib
+CFLAGS = -a -d -k- -O2 $(LOC)
+ASFLAGS = $(LOC)
+LDFLAGS = $(LOC)
+
+
+# variables
+ZLIB_LIB = zlib.lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+#OBJA =
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+#OBJPA=
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $<
+
+.asm.obj:
+ $(AS) -c $(ASFLAGS) $<
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA)
+ -del $(ZLIB_LIB)
+ $(AR) $(ZLIB_LIB) $(OBJP1)
+ $(AR) $(ZLIB_LIB) $(OBJP2)
+ $(AR) $(ZLIB_LIB) $(OBJPA)
+
+
+# testing
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+
+# cleanup
+clean:
+ -del $(ZLIB_LIB)
+ -del *.obj
+ -del *.exe
+ -del *.tds
+ -del zlib.bak
+ -del foo.gz
diff --git a/xs/src/png/zlib/win32/Makefile.gcc b/xs/src/png/zlib/win32/Makefile.gcc
new file mode 100644
index 000000000..305be50af
--- /dev/null
+++ b/xs/src/png/zlib/win32/Makefile.gcc
@@ -0,0 +1,182 @@
+# Makefile for zlib, derived from Makefile.dj2.
+# Modified for mingw32 by C. Spieler, 6/16/98.
+# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.
+# Last updated: Mar 2012.
+# Tested under Cygwin and MinGW.
+
+# Copyright (C) 1995-2003 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type from the top level zlib directory:
+#
+# make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc
+#
+# To use the asm code, type:
+# cp contrib/asm?86/match.S ./match.S
+# make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc
+#
+# To install libz.a, zconf.h and zlib.h in the system directories, type:
+#
+# make install -fwin32/Makefile.gcc
+#
+# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set.
+#
+# To install the shared lib, append SHARED_MODE=1 to the make command :
+#
+# make install -fwin32/Makefile.gcc SHARED_MODE=1
+
+# Note:
+# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),
+# the DLL name should be changed from "zlib1.dll".
+
+STATICLIB = libz.a
+SHAREDLIB = zlib1.dll
+IMPLIB = libz.dll.a
+
+#
+# Set to 1 if shared object needs to be installed
+#
+SHARED_MODE=0
+
+#LOC = -DASMV
+#LOC = -DZLIB_DEBUG -g
+
+PREFIX =
+CC = $(PREFIX)gcc
+CFLAGS = $(LOC) -O3 -Wall
+
+AS = $(CC)
+ASFLAGS = $(LOC) -Wall
+
+LD = $(CC)
+LDFLAGS = $(LOC)
+
+AR = $(PREFIX)ar
+ARFLAGS = rcs
+
+RC = $(PREFIX)windres
+RCFLAGS = --define GCC_WINDRES
+
+STRIP = $(PREFIX)strip
+
+CP = cp -fp
+# If GNU install is available, replace $(CP) with install.
+INSTALL = $(CP)
+RM = rm -f
+
+prefix ?= /usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
+ gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
+OBJA =
+
+all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example.exe minigzip.exe example_d.exe minigzip_d.exe
+
+test: example.exe minigzip.exe
+ ./example
+ echo hello world | ./minigzip | ./minigzip -d
+
+testdll: example_d.exe minigzip_d.exe
+ ./example_d
+ echo hello world | ./minigzip_d | ./minigzip_d -d
+
+.c.o:
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+.S.o:
+ $(AS) $(ASFLAGS) -c -o $@ $<
+
+$(STATICLIB): $(OBJS) $(OBJA)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA)
+
+$(IMPLIB): $(SHAREDLIB)
+
+$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
+ $(CC) -shared -Wl,--out-implib,$(IMPLIB) $(LDFLAGS) \
+ -o $@ win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
+ $(STRIP) $@
+
+example.exe: example.o $(STATICLIB)
+ $(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB)
+ $(STRIP) $@
+
+minigzip.exe: minigzip.o $(STATICLIB)
+ $(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB)
+ $(STRIP) $@
+
+example_d.exe: example.o $(IMPLIB)
+ $(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB)
+ $(STRIP) $@
+
+minigzip_d.exe: minigzip.o $(IMPLIB)
+ $(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB)
+ $(STRIP) $@
+
+example.o: test/example.c zlib.h zconf.h
+ $(CC) $(CFLAGS) -I. -c -o $@ test/example.c
+
+minigzip.o: test/minigzip.c zlib.h zconf.h
+ $(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c
+
+zlibrc.o: win32/zlib1.rc
+ $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc
+
+.PHONY: install uninstall clean
+
+install: zlib.h zconf.h $(STATICLIB) $(IMPLIB)
+ @if test -z "$(DESTDIR)$(INCLUDE_PATH)" -o -z "$(DESTDIR)$(LIBRARY_PATH)" -o -z "$(DESTDIR)$(BINARY_PATH)"; then \
+ echo INCLUDE_PATH, LIBRARY_PATH, and BINARY_PATH must be specified; \
+ exit 1; \
+ fi
+ -@mkdir -p '$(DESTDIR)$(INCLUDE_PATH)'
+ -@mkdir -p '$(DESTDIR)$(LIBRARY_PATH)' '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig
+ -if [ "$(SHARED_MODE)" = "1" ]; then \
+ mkdir -p '$(DESTDIR)$(BINARY_PATH)'; \
+ $(INSTALL) $(SHAREDLIB) '$(DESTDIR)$(BINARY_PATH)'; \
+ $(INSTALL) $(IMPLIB) '$(DESTDIR)$(LIBRARY_PATH)'; \
+ fi
+ -$(INSTALL) zlib.h '$(DESTDIR)$(INCLUDE_PATH)'
+ -$(INSTALL) zconf.h '$(DESTDIR)$(INCLUDE_PATH)'
+ -$(INSTALL) $(STATICLIB) '$(DESTDIR)$(LIBRARY_PATH)'
+ sed \
+ -e 's|@prefix@|${prefix}|g' \
+ -e 's|@exec_prefix@|${exec_prefix}|g' \
+ -e 's|@libdir@|$(LIBRARY_PATH)|g' \
+ -e 's|@sharedlibdir@|$(LIBRARY_PATH)|g' \
+ -e 's|@includedir@|$(INCLUDE_PATH)|g' \
+ -e 's|@VERSION@|'`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' zlib.h`'|g' \
+ zlib.pc.in > '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig/zlib.pc
+
+uninstall:
+ -if [ "$(SHARED_MODE)" = "1" ]; then \
+ $(RM) '$(DESTDIR)$(BINARY_PATH)'/$(SHAREDLIB); \
+ $(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(IMPLIB); \
+ fi
+ -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zlib.h
+ -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zconf.h
+ -$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(STATICLIB)
+
+clean:
+ -$(RM) $(STATICLIB)
+ -$(RM) $(SHAREDLIB)
+ -$(RM) $(IMPLIB)
+ -$(RM) *.o
+ -$(RM) *.exe
+ -$(RM) foo.gz
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/xs/src/png/zlib/win32/Makefile.msc b/xs/src/png/zlib/win32/Makefile.msc
new file mode 100644
index 000000000..6831882de
--- /dev/null
+++ b/xs/src/png/zlib/win32/Makefile.msc
@@ -0,0 +1,163 @@
+# Makefile for zlib using Microsoft (Visual) C
+# zlib is copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+#
+# Usage:
+# nmake -f win32/Makefile.msc (standard build)
+# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build)
+# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \
+# OBJA="inffas32.obj match686.obj" (use ASM code, x86)
+# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \
+# OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" (use ASM code, x64)
+
+# The toplevel directory of the source tree.
+#
+TOP = .
+
+# optional build flags
+LOC =
+
+# variables
+STATICLIB = zlib.lib
+SHAREDLIB = zlib1.dll
+IMPLIB = zdll.lib
+
+CC = cl
+AS = ml
+LD = link
+AR = lib
+RC = rc
+CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC)
+WFLAGS = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
+ASFLAGS = -coff -Zi $(LOC)
+LDFLAGS = -nologo -debug -incremental:no -opt:ref
+ARFLAGS = -nologo
+RCFLAGS = /dWIN32 /r
+
+OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \
+ gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj
+OBJA =
+
+
+# targets
+all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
+ example.exe minigzip.exe example_d.exe minigzip_d.exe
+
+$(STATICLIB): $(OBJS) $(OBJA)
+ $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA)
+
+$(IMPLIB): $(SHAREDLIB)
+
+$(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res
+ $(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \
+ -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res
+ if exist $@.manifest \
+ mt -nologo -manifest $@.manifest -outputresource:$@;2
+
+example.exe: example.obj $(STATICLIB)
+ $(LD) $(LDFLAGS) example.obj $(STATICLIB)
+ if exist $@.manifest \
+ mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+minigzip.exe: minigzip.obj $(STATICLIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(STATICLIB)
+ if exist $@.manifest \
+ mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+example_d.exe: example.obj $(IMPLIB)
+ $(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB)
+ if exist $@.manifest \
+ mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+minigzip_d.exe: minigzip.obj $(IMPLIB)
+ $(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB)
+ if exist $@.manifest \
+ mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+{$(TOP)}.c.obj:
+ $(CC) -c $(WFLAGS) $(CFLAGS) $<
+
+{$(TOP)/test}.c.obj:
+ $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $<
+
+{$(TOP)/contrib/masmx64}.c.obj:
+ $(CC) -c $(WFLAGS) $(CFLAGS) $<
+
+{$(TOP)/contrib/masmx64}.asm.obj:
+ $(AS) -c $(ASFLAGS) $<
+
+{$(TOP)/contrib/masmx86}.asm.obj:
+ $(AS) -c $(ASFLAGS) $<
+
+adler32.obj: $(TOP)/adler32.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+compress.obj: $(TOP)/compress.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+crc32.obj: $(TOP)/crc32.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/crc32.h
+
+deflate.obj: $(TOP)/deflate.c $(TOP)/deflate.h $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
+
+gzclose.obj: $(TOP)/gzclose.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+gzlib.obj: $(TOP)/gzlib.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+gzread.obj: $(TOP)/gzread.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+gzwrite.obj: $(TOP)/gzwrite.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+infback.obj: $(TOP)/infback.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+ $(TOP)/inffast.h $(TOP)/inffixed.h
+
+inffast.obj: $(TOP)/inffast.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+ $(TOP)/inffast.h
+
+inflate.obj: $(TOP)/inflate.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+ $(TOP)/inffast.h $(TOP)/inffixed.h
+
+inftrees.obj: $(TOP)/inftrees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h
+
+trees.obj: $(TOP)/trees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/deflate.h $(TOP)/trees.h
+
+uncompr.obj: $(TOP)/uncompr.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+zutil.obj: $(TOP)/zutil.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
+
+gvmat64.obj: $(TOP)/contrib\masmx64\gvmat64.asm
+
+inffasx64.obj: $(TOP)/contrib\masmx64\inffasx64.asm
+
+inffas8664.obj: $(TOP)/contrib\masmx64\inffas8664.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h \
+ $(TOP)/inftrees.h $(TOP)/inflate.h $(TOP)/inffast.h
+
+inffas32.obj: $(TOP)/contrib\masmx86\inffas32.asm
+
+match686.obj: $(TOP)/contrib\masmx86\match686.asm
+
+example.obj: $(TOP)/test/example.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+zlib1.res: $(TOP)/win32/zlib1.rc
+ $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/zlib1.rc
+
+# testing
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+testdll: example_d.exe minigzip_d.exe
+ example_d
+ echo hello world | minigzip_d | minigzip_d -d
+
+
+# cleanup
+clean:
+ -del $(STATICLIB)
+ -del $(SHAREDLIB)
+ -del $(IMPLIB)
+ -del *.obj
+ -del *.res
+ -del *.exp
+ -del *.exe
+ -del *.pdb
+ -del *.manifest
+ -del foo.gz
diff --git a/xs/src/png/zlib/win32/README-WIN32.txt b/xs/src/png/zlib/win32/README-WIN32.txt
new file mode 100644
index 000000000..df7ab7f4b
--- /dev/null
+++ b/xs/src/png/zlib/win32/README-WIN32.txt
@@ -0,0 +1,103 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.11 is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format).
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org). Two compiled
+examples are distributed in this package, example and minigzip. The example_d
+and minigzip_d flavors validate that the zlib1.dll file is working correctly.
+
+Questions about zlib should be sent to <zlib@gzip.org>. The zlib home page
+is http://zlib.net/ . Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+
+PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html
+before asking for help.
+
+
+Manifest:
+
+The package zlib-1.2.11-win32-x86.zip will contain the following files:
+
+ README-WIN32.txt This document
+ ChangeLog Changes since previous zlib packages
+ DLL_FAQ.txt Frequently asked questions about zlib1.dll
+ zlib.3.pdf Documentation of this library in Adobe Acrobat format
+
+ example.exe A statically-bound example (using zlib.lib, not the dll)
+ example.pdb Symbolic information for debugging example.exe
+
+ example_d.exe A zlib1.dll bound example (using zdll.lib)
+ example_d.pdb Symbolic information for debugging example_d.exe
+
+ minigzip.exe A statically-bound test program (using zlib.lib, not the dll)
+ minigzip.pdb Symbolic information for debugging minigzip.exe
+
+ minigzip_d.exe A zlib1.dll bound test program (using zdll.lib)
+ minigzip_d.pdb Symbolic information for debugging minigzip_d.exe
+
+ zlib.h Install these files into the compilers' INCLUDE path to
+ zconf.h compile programs which use zlib.lib or zdll.lib
+
+ zdll.lib Install these files into the compilers' LIB path if linking
+ zdll.exp a compiled program to the zlib1.dll binary
+
+ zlib.lib Install these files into the compilers' LIB path to link zlib
+ zlib.pdb into compiled programs, without zlib1.dll runtime dependency
+ (zlib.pdb provides debugging info to the compile time linker)
+
+ zlib1.dll Install this binary shared library into the system PATH, or
+ the program's runtime directory (where the .exe resides)
+ zlib1.pdb Install in the same directory as zlib1.dll, in order to debug
+ an application crash using WinDbg or similar tools.
+
+All .pdb files above are entirely optional, but are very useful to a developer
+attempting to diagnose program misbehavior or a crash. Many additional
+important files for developers can be found in the zlib127.zip source package
+available from http://zlib.net/ - review that package's README file for details.
+
+
+Acknowledgments:
+
+The deflate format used by zlib was defined by Phil Katz. The deflate and
+zlib specifications were written by L. Peter Deutsch. Thanks to all the
+people who reported problems and suggested various improvements in zlib; they
+are too numerous to cite here.
+
+
+Copyright notice:
+
+ (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign. The sources are provided for free but without
+warranty of any kind. The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes. Please read
+the FAQ for more information on the distribution of modified source versions.
diff --git a/xs/src/png/zlib/win32/VisualC.txt b/xs/src/png/zlib/win32/VisualC.txt
new file mode 100644
index 000000000..1005b2194
--- /dev/null
+++ b/xs/src/png/zlib/win32/VisualC.txt
@@ -0,0 +1,3 @@
+
+To build zlib using the Microsoft Visual C++ environment,
+use the appropriate project from the contrib/vstudio/ directory.
diff --git a/xs/src/png/zlib/win32/zlib.def b/xs/src/png/zlib/win32/zlib.def
new file mode 100644
index 000000000..a2188b000
--- /dev/null
+++ b/xs/src/png/zlib/win32/zlib.def
@@ -0,0 +1,94 @@
+; zlib data compression library
+EXPORTS
+; basic functions
+ zlibVersion
+ deflate
+ deflateEnd
+ inflate
+ inflateEnd
+; advanced functions
+ deflateSetDictionary
+ deflateGetDictionary
+ deflateCopy
+ deflateReset
+ deflateParams
+ deflateTune
+ deflateBound
+ deflatePending
+ deflatePrime
+ deflateSetHeader
+ inflateSetDictionary
+ inflateGetDictionary
+ inflateSync
+ inflateCopy
+ inflateReset
+ inflateReset2
+ inflatePrime
+ inflateMark
+ inflateGetHeader
+ inflateBack
+ inflateBackEnd
+ zlibCompileFlags
+; utility functions
+ compress
+ compress2
+ compressBound
+ uncompress
+ uncompress2
+ gzopen
+ gzdopen
+ gzbuffer
+ gzsetparams
+ gzread
+ gzfread
+ gzwrite
+ gzfwrite
+ gzprintf
+ gzvprintf
+ gzputs
+ gzgets
+ gzputc
+ gzgetc
+ gzungetc
+ gzflush
+ gzseek
+ gzrewind
+ gztell
+ gzoffset
+ gzeof
+ gzdirect
+ gzclose
+ gzclose_r
+ gzclose_w
+ gzerror
+ gzclearerr
+; large file functions
+ gzopen64
+ gzseek64
+ gztell64
+ gzoffset64
+ adler32_combine64
+ crc32_combine64
+; checksum functions
+ adler32
+ adler32_z
+ crc32
+ crc32_z
+ adler32_combine
+ crc32_combine
+; various hacks, don't look :)
+ deflateInit_
+ deflateInit2_
+ inflateInit_
+ inflateInit2_
+ inflateBackInit_
+ gzgetc_
+ zError
+ inflateSyncPoint
+ get_crc_table
+ inflateUndermine
+ inflateValidate
+ inflateCodesUsed
+ inflateResetKeep
+ deflateResetKeep
+ gzopen_w
diff --git a/xs/src/png/zlib/win32/zlib1.rc b/xs/src/png/zlib/win32/zlib1.rc
new file mode 100644
index 000000000..234e641c3
--- /dev/null
+++ b/xs/src/png/zlib/win32/zlib1.rc
@@ -0,0 +1,40 @@
+#include <winver.h>
+#include "../zlib.h"
+
+#ifdef GCC_WINDRES
+VS_VERSION_INFO VERSIONINFO
+#else
+VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
+#endif
+ FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
+ PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS 1
+#else
+ FILEFLAGS 0
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0 // not used
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ //language ID = U.S. English, char set = Windows, Multilingual
+ BEGIN
+ VALUE "FileDescription", "zlib data compression library\0"
+ VALUE "FileVersion", ZLIB_VERSION "\0"
+ VALUE "InternalName", "zlib1.dll\0"
+ VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0"
+ VALUE "OriginalFilename", "zlib1.dll\0"
+ VALUE "ProductName", "zlib\0"
+ VALUE "ProductVersion", ZLIB_VERSION "\0"
+ VALUE "Comments", "For more information visit http://www.zlib.net/\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 1252
+ END
+END
diff --git a/xs/src/png/zlib/zconf.h.cmakein b/xs/src/png/zlib/zconf.h.cmakein
new file mode 100644
index 000000000..a7f24cce6
--- /dev/null
+++ b/xs/src/png/zlib/zconf.h.cmakein
@@ -0,0 +1,536 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+#cmakedefine Z_PREFIX
+#cmakedefine Z_HAVE_UNISTD_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# define adler32_z z_adler32_z
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define crc32_z z_crc32_z
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateGetDictionary z_deflateGetDictionary
+# define deflateInit z_deflateInit
+# define deflateInit2 z_deflateInit2
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzfread z_gzfread
+# define gzfwrite z_gzfwrite
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzvprintf z_gzvprintf
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit z_inflateBackInit
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCodesUsed z_inflateCodesUsed
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetDictionary z_inflateGetDictionary
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit z_inflateInit
+# define inflateInit2 z_inflateInit2
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateResetKeep z_inflateResetKeep
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateValidate z_inflateValidate
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# define uncompress2 z_uncompress2
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+#ifdef Z_SOLO
+ typedef unsigned long z_size_t;
+#else
+# define z_longlong long long
+# if defined(NO_SIZE_T)
+ typedef unsigned NO_SIZE_T z_size_t;
+# elif defined(STDC)
+# include <stddef.h>
+ typedef size_t z_size_t;
+# else
+ typedef unsigned long z_size_t;
+# endif
+# undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include <stdarg.h> /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include <stddef.h> /* for wchar_t */
+# endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/xs/src/png/zlib/zconf.h.in b/xs/src/png/zlib/zconf.h.in
new file mode 100644
index 000000000..5e1d68a00
--- /dev/null
+++ b/xs/src/png/zlib/zconf.h.in
@@ -0,0 +1,534 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# define adler32_z z_adler32_z
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define crc32_z z_crc32_z
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateGetDictionary z_deflateGetDictionary
+# define deflateInit z_deflateInit
+# define deflateInit2 z_deflateInit2
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzfread z_gzfread
+# define gzfwrite z_gzfwrite
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzvprintf z_gzvprintf
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit z_inflateBackInit
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCodesUsed z_inflateCodesUsed
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetDictionary z_inflateGetDictionary
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit z_inflateInit
+# define inflateInit2 z_inflateInit2
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateResetKeep z_inflateResetKeep
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateValidate z_inflateValidate
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# define uncompress2 z_uncompress2
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+#ifdef Z_SOLO
+ typedef unsigned long z_size_t;
+#else
+# define z_longlong long long
+# if defined(NO_SIZE_T)
+ typedef unsigned NO_SIZE_T z_size_t;
+# elif defined(STDC)
+# include <stddef.h>
+ typedef size_t z_size_t;
+# else
+ typedef unsigned long z_size_t;
+# endif
+# undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include <stdarg.h> /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include <stddef.h> /* for wchar_t */
+# endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/xs/src/png/zlib/zconf.h.included b/xs/src/png/zlib/zconf.h.included
new file mode 100644
index 000000000..5e1d68a00
--- /dev/null
+++ b/xs/src/png/zlib/zconf.h.included
@@ -0,0 +1,534 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
+# define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+# define _dist_code z__dist_code
+# define _length_code z__length_code
+# define _tr_align z__tr_align
+# define _tr_flush_bits z__tr_flush_bits
+# define _tr_flush_block z__tr_flush_block
+# define _tr_init z__tr_init
+# define _tr_stored_block z__tr_stored_block
+# define _tr_tally z__tr_tally
+# define adler32 z_adler32
+# define adler32_combine z_adler32_combine
+# define adler32_combine64 z_adler32_combine64
+# define adler32_z z_adler32_z
+# ifndef Z_SOLO
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# endif
+# define crc32 z_crc32
+# define crc32_combine z_crc32_combine
+# define crc32_combine64 z_crc32_combine64
+# define crc32_z z_crc32_z
+# define deflate z_deflate
+# define deflateBound z_deflateBound
+# define deflateCopy z_deflateCopy
+# define deflateEnd z_deflateEnd
+# define deflateGetDictionary z_deflateGetDictionary
+# define deflateInit z_deflateInit
+# define deflateInit2 z_deflateInit2
+# define deflateInit2_ z_deflateInit2_
+# define deflateInit_ z_deflateInit_
+# define deflateParams z_deflateParams
+# define deflatePending z_deflatePending
+# define deflatePrime z_deflatePrime
+# define deflateReset z_deflateReset
+# define deflateResetKeep z_deflateResetKeep
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateSetHeader z_deflateSetHeader
+# define deflateTune z_deflateTune
+# define deflate_copyright z_deflate_copyright
+# define get_crc_table z_get_crc_table
+# ifndef Z_SOLO
+# define gz_error z_gz_error
+# define gz_intmax z_gz_intmax
+# define gz_strwinerror z_gz_strwinerror
+# define gzbuffer z_gzbuffer
+# define gzclearerr z_gzclearerr
+# define gzclose z_gzclose
+# define gzclose_r z_gzclose_r
+# define gzclose_w z_gzclose_w
+# define gzdirect z_gzdirect
+# define gzdopen z_gzdopen
+# define gzeof z_gzeof
+# define gzerror z_gzerror
+# define gzflush z_gzflush
+# define gzfread z_gzfread
+# define gzfwrite z_gzfwrite
+# define gzgetc z_gzgetc
+# define gzgetc_ z_gzgetc_
+# define gzgets z_gzgets
+# define gzoffset z_gzoffset
+# define gzoffset64 z_gzoffset64
+# define gzopen z_gzopen
+# define gzopen64 z_gzopen64
+# ifdef _WIN32
+# define gzopen_w z_gzopen_w
+# endif
+# define gzprintf z_gzprintf
+# define gzputc z_gzputc
+# define gzputs z_gzputs
+# define gzread z_gzread
+# define gzrewind z_gzrewind
+# define gzseek z_gzseek
+# define gzseek64 z_gzseek64
+# define gzsetparams z_gzsetparams
+# define gztell z_gztell
+# define gztell64 z_gztell64
+# define gzungetc z_gzungetc
+# define gzvprintf z_gzvprintf
+# define gzwrite z_gzwrite
+# endif
+# define inflate z_inflate
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define inflateBackInit z_inflateBackInit
+# define inflateBackInit_ z_inflateBackInit_
+# define inflateCodesUsed z_inflateCodesUsed
+# define inflateCopy z_inflateCopy
+# define inflateEnd z_inflateEnd
+# define inflateGetDictionary z_inflateGetDictionary
+# define inflateGetHeader z_inflateGetHeader
+# define inflateInit z_inflateInit
+# define inflateInit2 z_inflateInit2
+# define inflateInit2_ z_inflateInit2_
+# define inflateInit_ z_inflateInit_
+# define inflateMark z_inflateMark
+# define inflatePrime z_inflatePrime
+# define inflateReset z_inflateReset
+# define inflateReset2 z_inflateReset2
+# define inflateResetKeep z_inflateResetKeep
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateUndermine z_inflateUndermine
+# define inflateValidate z_inflateValidate
+# define inflate_copyright z_inflate_copyright
+# define inflate_fast z_inflate_fast
+# define inflate_table z_inflate_table
+# ifndef Z_SOLO
+# define uncompress z_uncompress
+# define uncompress2 z_uncompress2
+# endif
+# define zError z_zError
+# ifndef Z_SOLO
+# define zcalloc z_zcalloc
+# define zcfree z_zcfree
+# endif
+# define zlibCompileFlags z_zlibCompileFlags
+# define zlibVersion z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+# define Byte z_Byte
+# define Bytef z_Bytef
+# define alloc_func z_alloc_func
+# define charf z_charf
+# define free_func z_free_func
+# ifndef Z_SOLO
+# define gzFile z_gzFile
+# endif
+# define gz_header z_gz_header
+# define gz_headerp z_gz_headerp
+# define in_func z_in_func
+# define intf z_intf
+# define out_func z_out_func
+# define uInt z_uInt
+# define uIntf z_uIntf
+# define uLong z_uLong
+# define uLongf z_uLongf
+# define voidp z_voidp
+# define voidpc z_voidpc
+# define voidpf z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+# define gz_header_s z_gz_header_s
+# define internal_state z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+# define z_const const
+#else
+# define z_const
+#endif
+
+#ifdef Z_SOLO
+ typedef unsigned long z_size_t;
+#else
+# define z_longlong long long
+# if defined(NO_SIZE_T)
+ typedef unsigned NO_SIZE_T z_size_t;
+# elif defined(STDC)
+# include <stddef.h>
+ typedef size_t z_size_t;
+# else
+ typedef unsigned long z_size_t;
+# endif
+# undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+# if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# define Z_ARG(args) args
+# else
+# define Z_ARG(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+# include <limits.h>
+# if (UINT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned
+# elif (ULONG_MAX == 0xffffffffUL)
+# define Z_U4 unsigned long
+# elif (USHRT_MAX == 0xffffffffUL)
+# define Z_U4 unsigned short
+# endif
+#endif
+
+#ifdef Z_U4
+ typedef Z_U4 z_crc_t;
+#else
+ typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
+# define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+# ifndef Z_SOLO
+# include <sys/types.h> /* for off_t */
+# endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+# include <stdarg.h> /* for va_list */
+# endif
+#endif
+
+#ifdef _WIN32
+# ifndef Z_SOLO
+# include <stddef.h> /* for wchar_t */
+# endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+# define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# ifndef z_off_t
+# define z_off_t off_t
+# endif
+# endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+# define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+# define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+# define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+# define z_off64_t off64_t
+#else
+# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+# define z_off64_t __int64
+# else
+# define z_off64_t z_off_t
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+ #pragma map(deflateInit_,"DEIN")
+ #pragma map(deflateInit2_,"DEIN2")
+ #pragma map(deflateEnd,"DEEND")
+ #pragma map(deflateBound,"DEBND")
+ #pragma map(inflateInit_,"ININ")
+ #pragma map(inflateInit2_,"ININ2")
+ #pragma map(inflateEnd,"INEND")
+ #pragma map(inflateSync,"INSY")
+ #pragma map(inflateSetDictionary,"INSEDI")
+ #pragma map(compressBound,"CMBND")
+ #pragma map(inflate_table,"INTABL")
+ #pragma map(inflate_fast,"INFA")
+ #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/xs/src/png/zlib/zlib.3 b/xs/src/png/zlib/zlib.3
new file mode 100644
index 000000000..bda4eb073
--- /dev/null
+++ b/xs/src/png/zlib/zlib.3
@@ -0,0 +1,149 @@
+.TH ZLIB 3 "15 Jan 2017"
+.SH NAME
+zlib \- compression/decompression library
+.SH SYNOPSIS
+[see
+.I zlib.h
+for full description]
+.SH DESCRIPTION
+The
+.I zlib
+library is a general purpose data compression library.
+The code is thread safe, assuming that the standard library functions
+used are thread safe, such as memory allocation routines.
+It provides in-memory compression and decompression functions,
+including integrity checks of the uncompressed data.
+This version of the library supports only one compression method (deflation)
+but other algorithms may be added later
+with the same stream interface.
+.LP
+Compression can be done in a single step if the buffers are large enough
+or can be done by repeated calls of the compression function.
+In the latter case,
+the application must provide more input and/or consume the output
+(providing more output space) before each call.
+.LP
+The library also supports reading and writing files in
+.IR gzip (1)
+(.gz) format
+with an interface similar to that of stdio.
+.LP
+The library does not install any signal handler.
+The decoder checks the consistency of the compressed data,
+so the library should never crash even in the case of corrupted input.
+.LP
+All functions of the compression library are documented in the file
+.IR zlib.h .
+The distribution source includes examples of use of the library
+in the files
+.I test/example.c
+and
+.IR test/minigzip.c,
+as well as other examples in the
+.IR examples/
+directory.
+.LP
+Changes to this version are documented in the file
+.I ChangeLog
+that accompanies the source.
+.LP
+.I zlib
+is built in to many languages and operating systems, including but not limited to
+Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go.
+.LP
+An experimental package to read and write files in the .zip format,
+written on top of
+.I zlib
+by Gilles Vollant (info@winimage.com),
+is available at:
+.IP
+http://www.winimage.com/zLibDll/minizip.html
+and also in the
+.I contrib/minizip
+directory of the main
+.I zlib
+source distribution.
+.SH "SEE ALSO"
+The
+.I zlib
+web site can be found at:
+.IP
+http://zlib.net/
+.LP
+The data format used by the
+.I zlib
+library is described by RFC
+(Request for Comments) 1950 to 1952 in the files:
+.IP
+http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format)
+.br
+http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format)
+.br
+http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format)
+.LP
+Mark Nelson wrote an article about
+.I zlib
+for the Jan. 1997 issue of Dr. Dobb's Journal;
+a copy of the article is available at:
+.IP
+http://marknelson.us/1997/01/01/zlib-engine/
+.SH "REPORTING PROBLEMS"
+Before reporting a problem,
+please check the
+.I zlib
+web site to verify that you have the latest version of
+.IR zlib ;
+otherwise,
+obtain the latest version and see if the problem still exists.
+Please read the
+.I zlib
+FAQ at:
+.IP
+http://zlib.net/zlib_faq.html
+.LP
+before asking for help.
+Send questions and/or comments to zlib@gzip.org,
+or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
+.SH AUTHORS AND LICENSE
+Version 1.2.11
+.LP
+Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+.LP
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+.LP
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+.LP
+.nr step 1 1
+.IP \n[step]. 3
+The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software
+in a product, an acknowledgment in the product documentation would be
+appreciated but is not required.
+.IP \n+[step].
+Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+.IP \n+[step].
+This notice may not be removed or altered from any source distribution.
+.LP
+Jean-loup Gailly Mark Adler
+.br
+jloup@gzip.org madler@alumni.caltech.edu
+.LP
+The deflate format used by
+.I zlib
+was defined by Phil Katz.
+The deflate and
+.I zlib
+specifications were written by L. Peter Deutsch.
+Thanks to all the people who reported problems and suggested various
+improvements in
+.IR zlib ;
+who are too numerous to cite here.
+.LP
+UNIX manual page by R. P. C. Rodgers,
+U.S. National Library of Medicine (rodgers@nlm.nih.gov).
+.\" end of man page
diff --git a/xs/src/png/zlib/zlib.3.pdf b/xs/src/png/zlib/zlib.3.pdf
new file mode 100644
index 000000000..6fa519c5b
--- /dev/null
+++ b/xs/src/png/zlib/zlib.3.pdf
Binary files differ
diff --git a/xs/src/png/zlib/zlib.h b/xs/src/png/zlib/zlib.h
new file mode 100644
index 000000000..f09cdaf1e
--- /dev/null
+++ b/xs/src/png/zlib/zlib.h
@@ -0,0 +1,1912 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.11, January 15th, 2017
+
+ Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+ (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.11"
+#define ZLIB_VERNUM 0x12b0
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 11
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed data.
+ This version of the library supports only one compression method (deflation)
+ but other algorithms will be added later and will have the same stream
+ interface.
+
+ Compression can be done in a single step if the buffers are large enough,
+ or can be done by repeated calls of the compression function. In the latter
+ case, the application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip and raw deflate streams in
+ memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never crash
+ even in the case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ z_const Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total number of input bytes read so far */
+
+ Bytef *next_out; /* next output byte will go here */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total number of bytes output so far */
+
+ z_const char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text
+ for deflate, or the decoding state for inflate */
+ uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has dropped
+ to zero. It must update next_out and avail_out when avail_out has dropped
+ to zero. The application must initialize zalloc, zfree and opaque before
+ calling the init function. All other fields are set by the compression
+ library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe. In that case, zlib is thread-safe. When zalloc and zfree are
+ Z_NULL on entry to the initialization function, they are set to internal
+ routines that use the standard library functions malloc() and free().
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this if
+ the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers
+ returned by zalloc for objects of exactly 65536 bytes *must* have their
+ offset normalized to zero. The default allocation function provided by this
+ library ensures this (see zutil.c). To reduce memory requirements and avoid
+ any allocation of 64K objects, at the expense of compression ratio, compile
+ the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or progress
+ reports. After compression, total_in holds the total size of the
+ uncompressed data and may be saved for use by the decompressor (particularly
+ if the decompressor wants to decompress everything in a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+#define Z_TREES 6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field for deflate() */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is not
+ compatible with the zlib.h header file used by the application. This check
+ is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller. If
+ zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+ allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at all
+ (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION
+ requests a default compromise between speed and compression (currently
+ equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if level is not a valid compression level, or
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION). msg is set to null
+ if there is no error message. deflateInit does not perform any compression:
+ this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Generate more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary. Some output may be provided even if
+ flush is zero.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating avail_in or avail_out accordingly; avail_out should
+ never be zero before the call. The application can consume the compressed
+ output when it wants, for example when the output buffer is full (avail_out
+ == 0), or after each call of deflate(). If deflate returns Z_OK and with
+ zero avail_out, it must be called again after making room in the output
+ buffer because there might be more output pending. See deflatePending(),
+ which can be used if desired to determine whether or not there is more ouput
+ in that case.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumulate before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In
+ particular avail_in is zero after the call if enough output space has been
+ provided before the call.) Flushing may degrade compression for some
+ compression algorithms and so it should be used only when necessary. This
+ completes the current deflate block and follows it with an empty stored block
+ that is three bits plus filler bits to the next byte, followed by four bytes
+ (00 00 ff ff).
+
+ If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+ output buffer, but the output is not aligned to a byte boundary. All of the
+ input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+ This completes the current deflate block and follows it with an empty fixed
+ codes block that is 10 bits long. This assures that enough bytes are output
+ in order for the decompressor to finish the block before the empty fixed
+ codes block.
+
+ If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+ for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+ seven bits of the current block are held to be written as the next byte after
+ the next deflate block is completed. In this case, the decompressor may not
+ be provided enough bits at this point in order to complete decompression of
+ the data provided so far to the compressor. It may need to wait for the next
+ block to be emitted. This is for advanced applications that need to control
+ the emission of deflate blocks.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there was
+ enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this
+ function must be called again with Z_FINISH and more output space (updated
+ avail_out) but no more input data, until it returns with Z_STREAM_END or an
+ error. After deflate has returned Z_STREAM_END, the only possible operations
+ on the stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used in the first deflate call after deflateInit if all the
+ compression is to be done in a single step. In order to complete in one
+ call, avail_out must be at least the value returned by deflateBound (see
+ below). Then deflate is guaranteed to return Z_STREAM_END. If not enough
+ output space is provided, deflate will not return Z_STREAM_END, and it must
+ be called again as described above.
+
+ deflate() sets strm->adler to the Adler-32 checksum of all input read
+ so far (that is, total_in bytes). If a gzip stream is being generated, then
+ strm->adler will be the CRC-32 checksum of the input read so far. (See
+ deflateInit2 below.)
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is
+ considered binary. This field is only for information purposes and does not
+ affect the compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was Z_NULL or the state was inadvertently written over
+ by the application), or Z_BUF_ERROR if no progress is possible (for example
+ avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and
+ deflate() can be called again with more input and more output space to
+ continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case, msg
+ may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. In the current version of inflate, the provided input is not
+ read or consumed. The allocation of a sliding window will be deferred to
+ the first call of inflate (if the decompression does not complete on the
+ first call). If zalloc and zfree are set to Z_NULL, inflateInit updates
+ them to use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit does not perform any decompression.
+ Actual decompression will be done by inflate(). So next_in, and avail_in,
+ next_out, and avail_out are unused and unchanged. The current
+ implementation of inflateInit() does not process any header information --
+ that is deferred until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), then next_in and avail_in are updated
+ accordingly, and processing will resume at this point for the next call of
+ inflate().
+
+ - Generate more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there is
+ no more input data or no more space in the output buffer (see below about
+ the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming more
+ output, and updating the next_* and avail_* values accordingly. If the
+ caller of inflate() does not provide both available input and available
+ output space, it is possible that there will be no progress made. The
+ application can consume the uncompressed output when it wants, for example
+ when the output buffer is full (avail_out == 0), or after each call of
+ inflate(). If inflate returns Z_OK and with zero avail_out, it must be
+ called again after making room in the output buffer because there might be
+ more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+ Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate()
+ stop if and when it gets to the next deflate block boundary. When decoding
+ the zlib or gzip format, this will cause inflate() to return immediately
+ after the header and before the first block. When doing a raw inflate,
+ inflate() will go ahead and process the first block, and will return when it
+ gets to the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ To assist in this, on return inflate() always sets strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64 if
+ inflate() is currently decoding the last block in the deflate stream, plus
+ 128 if inflate() returned immediately after decoding an end-of-block code or
+ decoding the complete header up to just before the first byte of the deflate
+ stream. The end-of-block will not be indicated until all of the uncompressed
+ data from that block has been written to strm->next_out. The number of
+ unused bits may in general be greater than seven, except when bit 7 of
+ data_type is set, in which case the number of unused bits will be less than
+ eight. data_type is set as noted here every time inflate() returns for all
+ flush options, and so can be used to determine the amount of currently
+ consumed input in bits.
+
+ The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+ end of each deflate block header is reached, before any actual data in that
+ block is decoded. This allows the caller to determine the length of the
+ deflate block header for later use in random access within a deflate block.
+ 256 is added to the value of strm->data_type when inflate() returns
+ immediately after reaching the end of the deflate block header.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step (a
+ single call of inflate), the parameter flush should be set to Z_FINISH. In
+ this case all pending input is processed and all pending output is flushed;
+ avail_out must be large enough to hold all of the uncompressed data for the
+ operation to complete. (The size of the uncompressed data may have been
+ saved by the compressor for this purpose.) The use of Z_FINISH is not
+ required to perform an inflation in one step. However it may be used to
+ inform inflate that a faster approach can be used for the single inflate()
+ call. Z_FINISH also informs inflate to not maintain a sliding window if the
+ stream completes, which reduces inflate's memory footprint. If the stream
+ does not complete, either because not all of the stream is provided or not
+ enough output space is provided, then a sliding window will be allocated and
+ inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+ been used.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the effects of the flush parameter in this implementation are
+ on the return value of inflate() as noted below, when inflate() returns early
+ when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+ memory for a sliding window when Z_FINISH is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the Adler-32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed Adler-32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically, if requested when
+ initializing with inflateInit2(). Any information contained in the gzip
+ header is not retained unless inflateGetHeader() is used. When processing
+ gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+ produced so far. The CRC-32 is checked against the gzip trailer, as is the
+ uncompressed length, modulo 2^32.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value, in which case strm->msg points to a string with a more specific
+ error), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ next_in or next_out was Z_NULL, or the state was inadvertently written over
+ by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR
+ if no progress was possible or if there was not enough room in the output
+ buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may
+ then call inflateSync() to look for a good compression block if a partial
+ recovery of the data is to be attempted.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any pending
+ output.
+
+ inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state
+ was inconsistent.
+*/
+
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by the
+ caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ For the current implementation of deflate(), a windowBits value of 8 (a
+ window size of 256 bytes) is not supported. As a result, a request for 8
+ will result in 9 (a 512-byte window). In that case, providing 8 to
+ inflateInit2() will result in an error when the zlib header with 9 is
+ checked against the initialization of inflate(). The remedy is to not use 8
+ with deflateInit2() with this initialization, or at least in that case use 9
+ with inflateInit2().
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute a check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero), no
+ header crc, and the operating system will be set to the appropriate value,
+ if the operating system was determined at compile time. If a gzip stream is
+ being written, strm->adler is a CRC-32 instead of an Adler-32.
+
+ For raw deflate or gzip encoding, a request for a 256-byte window is
+ rejected as invalid, since only the zlib header provides a means of
+ transmitting the window size to the decompressor.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but is
+ slow and reduces compression ratio; memLevel=9 uses maximum memory for
+ optimal speed. The default value is 8. See zconf.h for total memory usage
+ as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as
+ fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The
+ strategy parameter only affects the compression ratio but not the
+ correctness of the compressed output even if it is not set appropriately.
+ Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+ decoder for special applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+ method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+ incompatible with the version assumed by the caller (ZLIB_VERSION). msg is
+ set to null if there is no error message. deflateInit2 does not perform any
+ compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. When using the zlib format, this
+ function must be called immediately after deflateInit, deflateInit2 or
+ deflateReset, and before any call of deflate. When doing raw deflate, this
+ function must be called either before any call of deflate, or immediately
+ after the completion of a deflate block, i.e. after all input has been
+ consumed and all output has been delivered when using any of the flush
+ options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
+ compressor and decompressor must use exactly the same dictionary (see
+ inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size
+ provided in deflateInit or deflateInit2. Thus the strings most likely to be
+ useful should be put at the end of the dictionary, not at the front. In
+ addition, the current implementation of deflate will use at most the window
+ size minus 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the Adler-32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The Adler-32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ Adler-32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if not at a block boundary for raw deflate). deflateSetDictionary does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength));
+/*
+ Returns the sliding dictionary being maintained by deflate. dictLength is
+ set to the number of bytes in the dictionary, and that many bytes are copied
+ to dictionary. dictionary must have enough space, where 32768 bytes is
+ always enough. If deflateGetDictionary() is called with dictionary equal to
+ Z_NULL, then only the dictionary length is returned, and nothing is copied.
+ Similary, if dictLength is Z_NULL, then it is not set.
+
+ deflateGetDictionary() may return a length less than the window size, even
+ when more than the window size in input has been provided. It may return up
+ to 258 bytes less in that case, due to how zlib's implementation of deflate
+ manages the sliding window and lookahead for matches, where matches can be
+ up to 258 bytes long. If the application needs the last window-size bytes of
+ input, then that would need to be saved by the application outside of zlib.
+
+ deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+ stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and can
+ consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit, but
+ does not free and reallocate the internal compression state. The stream
+ will leave the compression level and any other attributes that may have been
+ set unchanged.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2(). This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different strategy.
+ If the compression approach (which is a function of the level) or the
+ strategy is changed, and if any input has been consumed in a previous
+ deflate() call, then the input available so far is compressed with the old
+ level and strategy using deflate(strm, Z_BLOCK). There are three approaches
+ for the compression levels 0, 1..3, and 4..9 respectively. The new level
+ and strategy will take effect at the next call of deflate().
+
+ If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
+ not have enough output space to complete, then the parameter change will not
+ take effect. In this case, deflateParams() can be called again with the
+ same parameters and more output space to try again.
+
+ In order to assure a change in the parameters on the first try, the
+ deflate stream should be flushed using deflate() with Z_BLOCK or other flush
+ request until strm.avail_out is not zero, before calling deflateParams().
+ Then no more input data should be provided before the deflateParams() call.
+ If this is done, the old level and strategy will be applied to the data
+ compressed before deflateParams(), and the new level and strategy will be
+ applied to the the data compressed after deflateParams().
+
+ deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream
+ state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if
+ there was not enough output space to complete the compression of the
+ available input data before a change in the strategy or approach. Note that
+ in the case of a Z_BUF_ERROR, the parameters are not changed. A return
+ value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be
+ retried with more output space.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit() or
+ deflateInit2(), and after deflateSetHeader(), if used. This would be used
+ to allocate an output buffer for deflation in a single pass, and so would be
+ called before deflate(). If that first deflate() call is provided the
+ sourceLen input bytes, an output buffer allocated to the size returned by
+ deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+ to return Z_STREAM_END. Note that it is possible for the compressed size to
+ be larger than the value returned by deflateBound() if flush options other
+ than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+ unsigned *pending,
+ int *bits));
+/*
+ deflatePending() returns the number of bytes and bits of output that have
+ been generated, but not yet provided in the available output. The bytes not
+ provided would be due to the available output space having being consumed.
+ The number of bits of output not provided are between 0 and 7, where they
+ await more bits to join them in order to fill out a full byte. If pending
+ or bits are Z_NULL, then those values are not set.
+
+ deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the bits
+ leftover from a previous deflate stream when appending to it. As such, this
+ function can only be used for raw deflate, and must be used before the first
+ deflate() call after a deflateInit2() or deflateReset(). bits must be less
+ than or equal to 16, and that many of the least significant bits of value
+ will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+ room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be zero to request that inflate use the window size in
+ the zlib header of the compressed stream.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an Adler-32 or a CRC-32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a
+ CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see
+ below), inflate() will not automatically decode concatenated gzip streams.
+ inflate() will return Z_STREAM_END at the end of the gzip stream. The state
+ would need to be reset to continue decoding a subsequent gzip stream.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+ invalid, such as a null pointer to the structure. msg is set to null if
+ there is no error message. inflateInit2 does not perform any decompression
+ apart from possibly reading the zlib header if present: actual decompression
+ will be done by inflate(). (So next_in and avail_in may be modified, but
+ next_out and avail_out are unused and unchanged.) The current implementation
+ of inflateInit2() does not process any header information -- that is
+ deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the Adler-32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called at any
+ time to set the dictionary. If the provided dictionary is smaller than the
+ window and there is already data in the window, then the provided dictionary
+ will amend what's there. The application must insure that the dictionary
+ that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect Adler-32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+ Bytef *dictionary,
+ uInt *dictLength));
+/*
+ Returns the sliding dictionary being maintained by inflate. dictLength is
+ set to the number of bytes in the dictionary, and that many bytes are copied
+ to dictionary. dictionary must have enough space, where 32768 bytes is
+ always enough. If inflateGetDictionary() is called with dictionary equal to
+ Z_NULL, then only the dictionary length is returned, and nothing is copied.
+ Similary, if dictLength is Z_NULL, then it is not set.
+
+ inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+ stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a possible full flush point (see above
+ for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+ All full flush points have this pattern, but not all occurrences of this
+ pattern are full flush points.
+
+ inflateSync returns Z_OK if a possible full flush point has been found,
+ Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+ has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+ In the success case, the application may save the current current value of
+ total_in which indicates where valid compressed data was found. In the
+ error case, the application may repeatedly call inflateSync, providing more
+ input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being Z_NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate the internal decompression state. The
+ stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+ int windowBits));
+/*
+ This function is the same as inflateReset, but it also permits changing
+ the wrap and window size requests. The windowBits parameter is interpreted
+ the same as it is for inflateInit2. If the window size is changed, then the
+ memory allocated for the window is freed, and the window will be reallocated
+ by inflate() if needed.
+
+ inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+ the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ If bits is negative, then the input stream bit buffer is emptied. Then
+ inflatePrime() can be called again to put bits in the buffer. This is used
+ to clear out bits leftover after feeding inflate a block description prior
+ to feeding inflate codes.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+ This function returns two values, one in the lower 16 bits of the return
+ value, and the other in the remaining upper bits, obtained by shifting the
+ return value down 16 bits. If the upper value is -1 and the lower value is
+ zero, then inflate() is currently decoding information outside of a block.
+ If the upper value is -1 and the lower value is non-zero, then inflate is in
+ the middle of a stored block, with the lower value equaling the number of
+ bytes from the input remaining to copy. If the upper value is not -1, then
+ it is the number of bits back from the current bit position in the input of
+ the code (literal or length/distance pair) currently being processed. In
+ that case the lower value is the number of bytes already emitted for that
+ code.
+
+ A code is being processed if inflate is waiting for more input to complete
+ decoding of the code, or if it has completed decoding but is waiting for
+ more output space to write the literal or match data.
+
+ inflateMark() is used to mark locations in the input data for random
+ access, which may be at bit positions, and to note those cases where the
+ output of a code may span boundaries of random access blocks. The current
+ location in the input stream can be determined from avail_in and data_type
+ as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+ inflateMark returns the value noted above, or -65536 if the provided
+ source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be
+ used to force inflate() to return immediately after header processing is
+ complete and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When any
+ of extra, name, or comment are not Z_NULL and the respective field is not
+ present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+ allocated, or Z_VERSION_ERROR if the version of the library does not match
+ the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *,
+ z_const unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is potentially more efficient than
+ inflate() for file i/o applications, in that it avoids copying between the
+ output and the sliding window by simply making the window itself the output
+ buffer. inflate() can be faster on modern CPUs when used with large
+ buffers. inflateBack() trusts the application to not change the output
+ buffer passed by the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free the
+ allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects only
+ the raw deflate stream to decompress. This is different from the default
+ behavior of inflate(), which expects a zlib header and trailer around the
+ deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero -- buf is ignored in that
+ case -- and inflateBack() will return a buffer error. inflateBack() will
+ call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].
+ out() should return zero on success, or non-zero on failure. If out()
+ returns non-zero, inflateBack() will return with an error. Neither in() nor
+ out() are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+ in the deflate stream (in which case strm->msg is set to indicate the nature
+ of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+ In the case of Z_BUF_ERROR, an input or output error can be distinguished
+ using strm->next_in which will be Z_NULL only if in() returned an error. If
+ strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+ non-zero. (in() will always be called before out(), so strm->next_in is
+ assured to be defined if out() returns non-zero.) Note that inflateBack()
+ cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: ZLIB_DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the basic
+ stream-oriented functions. To simplify the interface, some default options
+ are assumed (compression level and memory usage, standard memory allocation
+ functions). The source code of these utility functions can be modified if
+ you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed data. compress() is equivalent to compress2() with a level
+ parameter of Z_DEFAULT_COMPRESSION.
+
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed data.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before a
+ compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total size
+ of the destination buffer, which must be large enough to hold the entire
+ uncompressed data. (The size of the uncompressed data must have been saved
+ previously by the compressor and transmitted to the decompressor by some
+ mechanism outside the scope of this compression library.) Upon exit, destLen
+ is the actual size of the uncompressed data.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
+ the case where there is not enough room, uncompress() will fill the output
+ buffer with the uncompressed data up to that point.
+*/
+
+ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong *sourceLen));
+/*
+ Same as uncompress, except that sourceLen is a pointer, where the
+ length of the source is *sourceLen. On return, *sourceLen is the number of
+ source bytes consumed.
+*/
+
+ /* gzip file access functions */
+
+/*
+ This library supports reading and writing files in gzip (.gz) format with
+ an interface similar to that of stdio, using the functions that start with
+ "gz". The gzip format is different from the zlib format. gzip is a gzip
+ wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+ Opens a gzip (.gz) file for reading or writing. The mode parameter is as
+ in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+ a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+ compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+ for fixed code compression as in "wb9F". (See the description of
+ deflateInit2 for more information about the strategy parameter.) 'T' will
+ request transparent writing or appending with no compression and not using
+ the gzip format.
+
+ "a" can be used instead of "w" to request that the gzip stream that will
+ be written be appended to the file. "+" will result in an error, since
+ reading and writing to the same gzip file is not supported. The addition of
+ "x" when writing will create the file exclusively, which fails if the file
+ already exists. On systems that support it, the addition of "e" when
+ reading or writing will set the flag to close the file on an execve() call.
+
+ These functions, as well as gzip, will read and decode a sequence of gzip
+ streams in a file. The append function of gzopen() can be used to create
+ such a file. (Also see gzflush() for another way to do this.) When
+ appending, gzopen does not test whether the file begins with a gzip stream,
+ nor does it look for the end of the gzip streams to begin appending. gzopen
+ will simply append a gzip stream to the existing file.
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression. When
+ reading, this will be detected automatically by looking for the magic two-
+ byte gzip header.
+
+ gzopen returns NULL if the file could not be opened, if there was
+ insufficient memory to allocate the gzFile state, or if an invalid mode was
+ specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+ errno can be checked to determine if the reason gzopen failed was that the
+ file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen associates a gzFile with the file descriptor fd. File descriptors
+ are obtained from calls like open, dup, creat, pipe or fileno (if the file
+ has been previously opened with fopen). The mode parameter is as in gzopen.
+
+ The next call of gzclose on the returned gzFile will also close the file
+ descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+ fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+ mode);. The duplicated descriptor should be saved to avoid a leak, since
+ gzdopen does not close fd if it fails. If you are using fileno() to get the
+ file descriptor from a FILE *, then you will have to use dup() to avoid
+ double-close()ing the file descriptor. Both gzclose() and fclose() will
+ close the associated file descriptor, so they need to have different file
+ descriptors.
+
+ gzdopen returns NULL if there was insufficient memory to allocate the
+ gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+ provided, or '+' was provided), or if fd is -1. The file descriptor is not
+ used until the next gz* read, write, seek, or close operation, so gzdopen
+ will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+ Set the internal buffer size used by this library's functions. The
+ default buffer size is 8192 bytes. This function must be called after
+ gzopen() or gzdopen(), and before any other calls that read or write the
+ file. The buffer memory allocation is always deferred to the first read or
+ write. Three times that size in buffer space is allocated. A larger buffer
+ size of, for example, 64K or 128K bytes will noticeably increase the speed
+ of decompression (reading).
+
+ The new buffer size also affects the maximum length for gzprintf().
+
+ gzbuffer() returns 0 on success, or -1 on failure, such as being called
+ too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters. Previously provided
+ data is flushed before the parameter change.
+
+ gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not
+ opened for writing, Z_ERRNO if there is an error writing the flushed data,
+ or Z_MEM_ERROR if there is a memory allocation error.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file. If
+ the input file is not in gzip format, gzread copies the given number of
+ bytes into the buffer directly from the file.
+
+ After reaching the end of a gzip stream in the input, gzread will continue
+ to read, looking for another gzip stream. Any number of gzip streams may be
+ concatenated in the input file, and will all be decompressed by gzread().
+ If something other than a gzip stream is encountered after a gzip stream,
+ that remaining trailing garbage is ignored (and no error is returned).
+
+ gzread can be used to read a gzip file that is being concurrently written.
+ Upon reaching the end of the input, gzread will return with the available
+ data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+ gzclearerr can be used to clear the end of file indicator in order to permit
+ gzread to be tried again. Z_OK indicates that a gzip stream was completed
+ on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
+ middle of a gzip stream. Note that gzread does not return -1 in the event
+ of an incomplete gzip stream. This error is deferred until gzclose(), which
+ will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+ stream. Alternatively, gzerror can be used before gzclose to detect this
+ case.
+
+ gzread returns the number of uncompressed bytes actually read, less than
+ len for end of file, or -1 for error. If len is too large to fit in an int,
+ then nothing is read, -1 is returned, and the error state is set to
+ Z_STREAM_ERROR.
+*/
+
+ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
+ gzFile file));
+/*
+ Read up to nitems items of size size from file to buf, otherwise operating
+ as gzread() does. This duplicates the interface of stdio's fread(), with
+ size_t request and return types. If the library defines size_t, then
+ z_size_t is identical to size_t. If not, then z_size_t is an unsigned
+ integer type that can contain a pointer.
+
+ gzfread() returns the number of full items read of size size, or zero if
+ the end of the file was reached and a full item could not be read, or if
+ there was an error. gzerror() must be consulted if zero is returned in
+ order to determine if there was an error. If the multiplication of size and
+ nitems overflows, i.e. the product does not fit in a z_size_t, then nothing
+ is read, zero is returned, and the error state is set to Z_STREAM_ERROR.
+
+ In the event that the end of file is reached and only a partial item is
+ available at the end, i.e. the remaining uncompressed data length is not a
+ multiple of size, then the final partial item is nevetheless read into buf
+ and the end-of-file flag is set. The length of the partial item read is not
+ provided, but could be inferred from the result of gztell(). This behavior
+ is the same as the behavior of fread() implementations in common libraries,
+ but it prevents the direct use of gzfread() to read a concurrently written
+ file, reseting and retrying on end-of-file, when size is not 1.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes written or 0 in case of
+ error.
+*/
+
+ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
+ z_size_t nitems, gzFile file));
+/*
+ gzfwrite() writes nitems items of size size from buf to file, duplicating
+ the interface of stdio's fwrite(), with size_t request and return types. If
+ the library defines size_t, then z_size_t is identical to size_t. If not,
+ then z_size_t is an unsigned integer type that can contain a pointer.
+
+ gzfwrite() returns the number of full items written of size size, or zero
+ if there was an error. If the multiplication of size and nitems overflows,
+ i.e. the product does not fit in a z_size_t, then nothing is written, zero
+ is returned, and the error state is set to Z_STREAM_ERROR.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the arguments to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written, or a negative zlib error code in case
+ of error. The number of uncompressed bytes written is limited to 8191, or
+ one less than the buffer size given to gzbuffer(). The caller should assure
+ that this limit is not exceeded. If it is exceeded, then gzprintf() will
+ return an error (0) with nothing written. In this case, there may also be a
+ buffer overflow with unpredictable consequences, which is possible only if
+ zlib was compiled with the insecure functions sprintf() or vsprintf()
+ because the secure snprintf() or vsnprintf() functions were not available.
+ This can be determined using zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or a
+ newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. If any characters are read or if len == 1, the
+ string is terminated with a null character. If no characters are read due
+ to an end-of-file or len < 1, then the buffer is left untouched.
+
+ gzgets returns buf which is a null-terminated string, or it returns NULL
+ for end-of-file or in case of error. If there was an error, the contents at
+ buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file. gzputc
+ returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte or -1
+ in case of end of file or error. This is implemented as a macro for speed.
+ As such, it does not do all of the checking the other functions do. I.e.
+ it does not check to see if file is NULL, nor whether the structure file
+ points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read as the first character
+ on the next read. At least one character of push-back is allowed.
+ gzungetc() returns the character pushed, or -1 on failure. gzungetc() will
+ fail if c is -1, and may fail if a character has been pushed but not read
+ yet. If gzungetc is used immediately after gzopen or gzdopen, at least the
+ output buffer size of pushed characters is allowed. (See gzbuffer above.)
+ The pushed character will be discarded if the stream is repositioned with
+ gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter flush
+ is as in the deflate() function. The return value is the zlib error number
+ (see function gzerror below). gzflush is only permitted when writing.
+
+ If the flush parameter is Z_FINISH, the remaining data is written and the
+ gzip stream is completed in the output. If gzwrite() is called again, a new
+ gzip stream will be started in the output. gzread() is able to read such
+ concatenated gzip streams.
+
+ gzflush should be called only when strictly necessary because it will
+ degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+
+ Returns the starting position for the next gzread or gzwrite on the given
+ compressed file. This position represents a number of bytes in the
+ uncompressed data stream, and is zero when starting, even if appending or
+ reading a gzip stream from the middle of a file using gzdopen().
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+ Returns the current offset in the file being read or written. This offset
+ includes the count of bytes that precede the gzip stream, for example when
+ appending or when using gzdopen() for reading. When reading, the offset
+ does not include as yet unused buffered input. This information can be used
+ for a progress indicator. On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns true (1) if the end-of-file indicator has been set while reading,
+ false (0) otherwise. Note that the end-of-file indicator is set only if the
+ read tried to go past the end of the input, but came up short. Therefore,
+ just like feof(), gzeof() may return false even if there is no more data to
+ read, in the event that the last read request was for the exact number of
+ bytes remaining in the input file. This will happen if the input file size
+ is an exact multiple of the buffer size.
+
+ If gzeof() returns true, then the read functions will return no more data,
+ unless the end-of-file indicator is reset by gzclearerr() and the input file
+ has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns true (1) if file is being copied directly while reading, or false
+ (0) if file is a gzip stream being decompressed.
+
+ If the input file is empty, gzdirect() will return true, since the input
+ does not contain a gzip stream.
+
+ If gzdirect() is used immediately after gzopen() or gzdopen() it will
+ cause buffers to be allocated to allow reading the file to determine if it
+ is a gzip file. Therefore if gzbuffer() is used, it should be called before
+ gzdirect().
+
+ When writing, gzdirect() returns true (1) if transparent writing was
+ requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
+ gzdirect() is not needed when writing. Transparent writing must be
+ explicitly requested, so the application already knows the answer. When
+ linking statically, using gzdirect() will include all of the zlib code for
+ gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file and
+ deallocates the (de)compression state. Note that once file is closed, you
+ cannot call gzerror with file, since its structures have been deallocated.
+ gzclose must not be called more than once on the same file, just as free
+ must not be called more than once on the same allocation.
+
+ gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+ file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+ last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+ Same as gzclose(), but gzclose_r() is only for use when reading, and
+ gzclose_w() is only for use when writing or appending. The advantage to
+ using these instead of gzclose() is that they avoid linking in zlib
+ compression or decompression code that is not used when only reading or only
+ writing respectively. If gzclose() is used, then both compression and
+ decompression code will be included the application when linking to a static
+ zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the given
+ compressed file. errnum is set to zlib error number. If an error occurred
+ in the file system and not in the compression library, errnum is set to
+ Z_ERRNO and the application may consult errno to get the exact error code.
+
+ The application must not modify the returned string. Future calls to
+ this function may invalidate the previously returned string. If file is
+ closed, then the string previously returned by gzerror will no longer be
+ available.
+
+ gzerror() should be used to distinguish errors from end-of-file for those
+ functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the compression
+ library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is Z_NULL, this function returns the
+ required initial value for the checksum.
+
+ An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed
+ much faster.
+
+ Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf,
+ z_size_t len));
+/*
+ Same as adler32(), but with a size_t length.
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
+ that the z_off_t type (like off_t) is a signed integer. If len2 is
+ negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is Z_NULL, this function returns the required
+ initial value for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
+
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf,
+ z_size_t len));
+/*
+ Same as crc32(), but with a size_t length.
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#ifdef Z_PREFIX_SET
+# define z_deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+# define z_inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+# define z_inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+# define z_inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+#else
+# define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+# define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+# define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+ (int)sizeof(z_stream))
+# define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, (int)sizeof(z_stream))
+#endif
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure. Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro. The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously. They can
+ * only be used by the gzgetc() macro. You have been warned.
+ */
+struct gzFile_s {
+ unsigned have;
+ unsigned char *next;
+ z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
+#ifdef Z_PREFIX_SET
+# undef z_gzgetc
+# define z_gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#else
+# define gzgetc(g) \
+ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+ ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+# ifdef Z_PREFIX_SET
+# define z_gzopen z_gzopen64
+# define z_gzseek z_gzseek64
+# define z_gztell z_gztell64
+# define z_gzoffset z_gzoffset64
+# define z_adler32_combine z_adler32_combine64
+# define z_crc32_combine z_crc32_combine64
+# else
+# define gzopen gzopen64
+# define gzseek gzseek64
+# define gztell gztell64
+# define gzoffset gzoffset64
+# define adler32_combine adler32_combine64
+# define crc32_combine crc32_combine64
+# endif
+# ifndef Z_LARGE64
+ ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+# endif
+#else
+ ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* undocumented functions */
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
+ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int));
+ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp));
+ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
+#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO)
+ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
+ const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifndef Z_SOLO
+ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+ const char *format,
+ va_list va));
+# endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/xs/src/png/zlib/zlib.map b/xs/src/png/zlib/zlib.map
new file mode 100644
index 000000000..82ce98cf7
--- /dev/null
+++ b/xs/src/png/zlib/zlib.map
@@ -0,0 +1,94 @@
+ZLIB_1.2.0 {
+ global:
+ compressBound;
+ deflateBound;
+ inflateBack;
+ inflateBackEnd;
+ inflateBackInit_;
+ inflateCopy;
+ local:
+ deflate_copyright;
+ inflate_copyright;
+ inflate_fast;
+ inflate_table;
+ zcalloc;
+ zcfree;
+ z_errmsg;
+ gz_error;
+ gz_intmax;
+ _*;
+};
+
+ZLIB_1.2.0.2 {
+ gzclearerr;
+ gzungetc;
+ zlibCompileFlags;
+} ZLIB_1.2.0;
+
+ZLIB_1.2.0.8 {
+ deflatePrime;
+} ZLIB_1.2.0.2;
+
+ZLIB_1.2.2 {
+ adler32_combine;
+ crc32_combine;
+ deflateSetHeader;
+ inflateGetHeader;
+} ZLIB_1.2.0.8;
+
+ZLIB_1.2.2.3 {
+ deflateTune;
+ gzdirect;
+} ZLIB_1.2.2;
+
+ZLIB_1.2.2.4 {
+ inflatePrime;
+} ZLIB_1.2.2.3;
+
+ZLIB_1.2.3.3 {
+ adler32_combine64;
+ crc32_combine64;
+ gzopen64;
+ gzseek64;
+ gztell64;
+ inflateUndermine;
+} ZLIB_1.2.2.4;
+
+ZLIB_1.2.3.4 {
+ inflateReset2;
+ inflateMark;
+} ZLIB_1.2.3.3;
+
+ZLIB_1.2.3.5 {
+ gzbuffer;
+ gzoffset;
+ gzoffset64;
+ gzclose_r;
+ gzclose_w;
+} ZLIB_1.2.3.4;
+
+ZLIB_1.2.5.1 {
+ deflatePending;
+} ZLIB_1.2.3.5;
+
+ZLIB_1.2.5.2 {
+ deflateResetKeep;
+ gzgetc_;
+ inflateResetKeep;
+} ZLIB_1.2.5.1;
+
+ZLIB_1.2.7.1 {
+ inflateGetDictionary;
+ gzvprintf;
+} ZLIB_1.2.5.2;
+
+ZLIB_1.2.9 {
+ inflateCodesUsed;
+ inflateValidate;
+ uncompress2;
+ gzfread;
+ gzfwrite;
+ deflateGetDictionary;
+ adler32_z;
+ crc32_z;
+} ZLIB_1.2.7.1;
diff --git a/xs/src/png/zlib/zlib.pc.cmakein b/xs/src/png/zlib/zlib.pc.cmakein
new file mode 100644
index 000000000..a5e642938
--- /dev/null
+++ b/xs/src/png/zlib/zlib.pc.cmakein
@@ -0,0 +1,13 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=@INSTALL_LIB_DIR@
+sharedlibdir=@INSTALL_LIB_DIR@
+includedir=@INSTALL_INC_DIR@
+
+Name: zlib
+Description: zlib compression library
+Version: @VERSION@
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
diff --git a/xs/src/png/zlib/zlib.pc.in b/xs/src/png/zlib/zlib.pc.in
new file mode 100644
index 000000000..7e5acf9c7
--- /dev/null
+++ b/xs/src/png/zlib/zlib.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+sharedlibdir=@sharedlibdir@
+includedir=@includedir@
+
+Name: zlib
+Description: zlib compression library
+Version: @VERSION@
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
diff --git a/xs/src/png/zlib/zlib2ansi b/xs/src/png/zlib/zlib2ansi
new file mode 100644
index 000000000..15e3e165f
--- /dev/null
+++ b/xs/src/png/zlib/zlib2ansi
@@ -0,0 +1,152 @@
+#!/usr/bin/perl
+
+# Transform K&R C function definitions into ANSI equivalent.
+#
+# Author: Paul Marquess
+# Version: 1.0
+# Date: 3 October 2006
+
+# TODO
+#
+# Asumes no function pointer parameters. unless they are typedefed.
+# Assumes no literal strings that look like function definitions
+# Assumes functions start at the beginning of a line
+
+use strict;
+use warnings;
+
+local $/;
+$_ = <>;
+
+my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments
+
+my $d1 = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ;
+my $decl = qr{ $sp (?: \w+ $sp )+ $d1 }xo ;
+my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ;
+
+
+while (s/^
+ ( # Start $1
+ ( # Start $2
+ .*? # Minimal eat content
+ ( ^ \w [\w\s\*]+ ) # $3 -- function name
+ \s* # optional whitespace
+ ) # $2 - Matched up to before parameter list
+
+ \( \s* # Literal "(" + optional whitespace
+ ( [^\)]+ ) # $4 - one or more anythings except ")"
+ \s* \) # optional whitespace surrounding a Literal ")"
+
+ ( (?: $dList )+ ) # $5
+
+ $sp ^ { # literal "{" at start of line
+ ) # Remember to $1
+ //xsom
+ )
+{
+ my $all = $1 ;
+ my $prefix = $2;
+ my $param_list = $4 ;
+ my $params = $5;
+
+ StripComments($params);
+ StripComments($param_list);
+ $param_list =~ s/^\s+//;
+ $param_list =~ s/\s+$//;
+
+ my $i = 0 ;
+ my %pList = map { $_ => $i++ }
+ split /\s*,\s*/, $param_list;
+ my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ;
+
+ my @params = split /\s*;\s*/, $params;
+ my @outParams = ();
+ foreach my $p (@params)
+ {
+ if ($p =~ /,/)
+ {
+ my @bits = split /\s*,\s*/, $p;
+ my $first = shift @bits;
+ $first =~ s/^\s*//;
+ push @outParams, $first;
+ $first =~ /^(\w+\s*)/;
+ my $type = $1 ;
+ push @outParams, map { $type . $_ } @bits;
+ }
+ else
+ {
+ $p =~ s/^\s+//;
+ push @outParams, $p;
+ }
+ }
+
+
+ my %tmp = map { /$pMatch/; $_ => $pList{$1} }
+ @outParams ;
+
+ @outParams = map { " $_" }
+ sort { $tmp{$a} <=> $tmp{$b} }
+ @outParams ;
+
+ print $prefix ;
+ print "(\n" . join(",\n", @outParams) . ")\n";
+ print "{" ;
+
+}
+
+# Output any trailing code.
+print ;
+exit 0;
+
+
+sub StripComments
+{
+
+ no warnings;
+
+ # Strip C & C++ coments
+ # From the perlfaq
+ $_[0] =~
+
+ s{
+ /\* ## Start of /* ... */ comment
+ [^*]*\*+ ## Non-* followed by 1-or-more *'s
+ (
+ [^/*][^*]*\*+
+ )* ## 0-or-more things which don't start with /
+ ## but do end with '*'
+ / ## End of /* ... */ comment
+
+ | ## OR C++ Comment
+ // ## Start of C++ comment //
+ [^\n]* ## followed by 0-or-more non end of line characters
+
+ | ## OR various things which aren't comments:
+
+ (
+ " ## Start of " ... " string
+ (
+ \\. ## Escaped char
+ | ## OR
+ [^"\\] ## Non "\
+ )*
+ " ## End of " ... " string
+
+ | ## OR
+
+ ' ## Start of ' ... ' string
+ (
+ \\. ## Escaped char
+ | ## OR
+ [^'\\] ## Non '\
+ )*
+ ' ## End of ' ... ' string
+
+ | ## OR
+
+ . ## Anything other char
+ [^/"'\\]* ## Chars which doesn't start a comment, string or escape
+ )
+ }{$2}gxs;
+
+}
diff --git a/xs/src/png/zlib/zutil.c b/xs/src/png/zlib/zutil.c
new file mode 100644
index 000000000..a76c6b0c7
--- /dev/null
+++ b/xs/src/png/zlib/zutil.c
@@ -0,0 +1,325 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2017 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+#ifndef Z_SOLO
+# include "gzguts.h"
+#endif
+
+z_const char * const z_errmsg[10] = {
+ (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */
+ (z_const char *)"stream end", /* Z_STREAM_END 1 */
+ (z_const char *)"", /* Z_OK 0 */
+ (z_const char *)"file error", /* Z_ERRNO (-1) */
+ (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */
+ (z_const char *)"data error", /* Z_DATA_ERROR (-3) */
+ (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */
+ (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */
+ (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */
+ (z_const char *)""
+};
+
+
+const char * ZEXPORT zlibVersion()
+{
+ return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+ uLong flags;
+
+ flags = 0;
+ switch ((int)(sizeof(uInt))) {
+ case 2: break;
+ case 4: flags += 1; break;
+ case 8: flags += 2; break;
+ default: flags += 3;
+ }
+ switch ((int)(sizeof(uLong))) {
+ case 2: break;
+ case 4: flags += 1 << 2; break;
+ case 8: flags += 2 << 2; break;
+ default: flags += 3 << 2;
+ }
+ switch ((int)(sizeof(voidpf))) {
+ case 2: break;
+ case 4: flags += 1 << 4; break;
+ case 8: flags += 2 << 4; break;
+ default: flags += 3 << 4;
+ }
+ switch ((int)(sizeof(z_off_t))) {
+ case 2: break;
+ case 4: flags += 1 << 6; break;
+ case 8: flags += 2 << 6; break;
+ default: flags += 3 << 6;
+ }
+#ifdef ZLIB_DEBUG
+ flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+ flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+ flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+ flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+ flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+ flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+ flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+ flags += 1L << 20;
+#endif
+#ifdef FASTEST
+ flags += 1L << 21;
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+# ifdef NO_vsnprintf
+ flags += 1L << 25;
+# ifdef HAS_vsprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_vsnprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#else
+ flags += 1L << 24;
+# ifdef NO_snprintf
+ flags += 1L << 25;
+# ifdef HAS_sprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_snprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#endif
+ return flags;
+}
+
+#ifdef ZLIB_DEBUG
+#include <stdlib.h>
+# ifndef verbose
+# define verbose 0
+# endif
+int ZLIB_INTERNAL z_verbose = verbose;
+
+void ZLIB_INTERNAL z_error (m)
+ char *m;
+{
+ fprintf(stderr, "%s\n", m);
+ exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+ int err;
+{
+ return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used.
+ */
+ int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void ZLIB_INTERNAL zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+#ifndef Z_SOLO
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ voidpf org_ptr;
+ voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ voidpf buf;
+ ulg bsize = (ulg)items*size;
+
+ (void)opaque;
+
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
+ * will return a usable pointer which doesn't have to be normalized.
+ */
+ if (bsize < 65520L) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+ int n;
+
+ (void)opaque;
+
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = 0; n < next_ptr; n++) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
+{
+ (void)opaque;
+ return _halloc((long)items, size);
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+ (void)opaque;
+ _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern voidp calloc OF((uInt items, uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
+ voidpf opaque;
+ unsigned items;
+ unsigned size;
+{
+ (void)opaque;
+ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+ (voidpf)calloc(items, size);
+}
+
+void ZLIB_INTERNAL zcfree (opaque, ptr)
+ voidpf opaque;
+ voidpf ptr;
+{
+ (void)opaque;
+ free(ptr);
+}
+
+#endif /* MY_ZCALLOC */
+
+#endif /* !Z_SOLO */
diff --git a/xs/src/png/zlib/zutil.h b/xs/src/png/zlib/zutil.h
new file mode 100644
index 000000000..b079ea6a8
--- /dev/null
+++ b/xs/src/png/zlib/zutil.h
@@ -0,0 +1,271 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#ifdef HAVE_HIDDEN
+# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+# define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+
+#if defined(STDC) && !defined(Z_SOLO)
+# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+# include <stddef.h>
+# endif
+# include <string.h>
+# include <stdlib.h>
+#endif
+
+#ifdef Z_SOLO
+ typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* since "static" is used to mean two completely different things in C, we
+ define "local" for the non-static meaning of "static", for readability
+ (compile with -Dlocal if your debugger can't find static symbols) */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+# define OS_CODE 0x00
+# ifndef Z_SOLO
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# endif
+# endif
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 1
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 2
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#ifdef __370__
+# if __TARGET_LIB__ < 0x20000000
+# define OS_CODE 4
+# elif __TARGET_LIB__ < 0x40000000
+# define OS_CODE 11
+# else
+# define OS_CODE 8
+# endif
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 5
+#endif
+
+#ifdef OS2
+# define OS_CODE 6
+# if defined(M_I86) && !defined(Z_SOLO)
+# include <malloc.h>
+# endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 7
+# ifndef Z_SOLO
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __acorn
+# define OS_CODE 13
+#endif
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+# define OS_CODE 10
+#endif
+
+#ifdef _BEOS_
+# define OS_CODE 16
+#endif
+
+#ifdef __TOS_OS400__
+# define OS_CODE 18
+#endif
+
+#ifdef __APPLE__
+# define OS_CODE 19
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+# if defined(_WIN32_WCE)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef _PTRDIFF_T_DEFINED
+ typedef int ptrdiff_t;
+# define _PTRDIFF_T_DEFINED
+# endif
+# else
+# define fdopen(fd,type) _fdopen(fd,type)
+# endif
+#endif
+
+#if defined(__BORLANDC__) && !defined(MSDOS)
+ #pragma warn -8004
+ #pragma warn -8008
+ #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_WIN32) && \
+ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+ ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+ ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
+ /* common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 3 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#if defined(pyr) || defined(Z_SOLO)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef ZLIB_DEBUG
+# include <stdio.h>
+ extern int ZLIB_INTERNAL z_verbose;
+ extern void ZLIB_INTERNAL z_error OF((char *m));
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+#ifndef Z_SOLO
+ voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+ unsigned size));
+ void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
+#endif
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+#endif /* ZUTIL_H */
diff --git a/xs/src/poly2tri/common/utils.h b/xs/src/poly2tri/common/utils.h
index ffb713f58..4bcb76361 100644
--- a/xs/src/poly2tri/common/utils.h
+++ b/xs/src/poly2tri/common/utils.h
@@ -33,7 +33,9 @@
#define UTILS_H
// Otherwise #defines like M_PI are undeclared under Visual Studio
-#define _USE_MATH_DEFINES
+#ifndef _USE_MATH_DEFINES
+ #define _USE_MATH_DEFINES
+#endif /* _USE_MATH_DEFINES */
#include <exception>
#include <math.h>
diff --git a/xs/src/qhull/Announce.txt b/xs/src/qhull/Announce.txt
new file mode 100644
index 000000000..635cff1af
--- /dev/null
+++ b/xs/src/qhull/Announce.txt
@@ -0,0 +1,47 @@
+
+ Qhull 2015.2 2016/01/18
+
+ http://www.qhull.org
+ git@github.com:qhull/qhull.git
+ http://www.geomview.org
+
+Qhull computes convex hulls, Delaunay triangulations, Voronoi diagrams,
+furthest-site Voronoi diagrams, and halfspace intersections about a point.
+It runs in 2-d, 3-d, 4-d, or higher. It implements the Quickhull algorithm
+for computing convex hulls. Qhull handles round-off errors from floating
+point arithmetic. It can approximate a convex hull.
+
+The program includes options for hull volume, facet area, partial hulls,
+input transformations, randomization, tracing, multiple output formats, and
+execution statistics. The program can be called from within your application.
+You can view the results in 2-d, 3-d and 4-d with Geomview.
+
+To download Qhull:
+ http://www.qhull.org/download
+ git@github.com:qhull/qhull.git
+
+Download qhull-96.ps for:
+
+ Barber, C. B., D.P. Dobkin, and H.T. Huhdanpaa, "The
+ Quickhull Algorithm for Convex Hulls," ACM Trans. on
+ Mathematical Software, 22(4):469-483, Dec. 1996.
+ http://www.acm.org/pubs/citations/journals/toms/1996-22-4/p469-barber/
+ http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405
+
+Abstract:
+
+The convex hull of a set of points is the smallest convex set that contains
+the points. This article presents a practical convex hull algorithm that
+combines the two-dimensional Quickhull Algorithm with the general dimension
+Beneath-Beyond Algorithm. It is similar to the randomized, incremental
+algorithms for convex hull and Delaunay triangulation. We provide empirical
+evidence that the algorithm runs faster when the input contains non-extreme
+points, and that it uses less memory.
+
+Computational geometry algorithms have traditionally assumed that input sets
+are well behaved. When an algorithm is implemented with floating point
+arithmetic, this assumption can lead to serious errors. We briefly describe
+a solution to this problem when computing the convex hull in two, three, or
+four dimensions. The output is a set of "thick" facets that contain all
+possible exact convex hulls of the input. A variation is effective in five
+or more dimensions.
diff --git a/xs/src/qhull/CMakeLists.txt b/xs/src/qhull/CMakeLists.txt
new file mode 100644
index 000000000..d798b018f
--- /dev/null
+++ b/xs/src/qhull/CMakeLists.txt
@@ -0,0 +1,128 @@
+
+# This CMake file is written specifically to integrate qhull library with Slic3rPE
+# (see https://github.com/prusa3d/Slic3r for more information about the project)
+#
+# Only original libraries qhullstatic_r and qhullcpp are included.
+# They are built as a single statically linked library.
+#
+# Created by modification of the original qhull CMakeLists.
+# Lukas Matena (25.7.2018), lukasmatena@seznam.cz
+
+
+project(qhull)
+cmake_minimum_required(VERSION 2.6)
+
+# Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, qhull-warn.pri
+set(qhull_VERSION2 "2015.2 2016/01/18") # not used, See global.c, global_r.c, rbox.c, rbox_r.c
+set(qhull_VERSION "7.2.0") # Advance every release
+
+#include(CMakeModules/CheckLFS.cmake)
+#option(WITH_LFS "Enable Large File Support" ON)
+#check_lfs(WITH_LFS)
+
+
+message(STATUS "qhull Version: ${qhull_VERSION} (static linking)")
+
+
+set(libqhull_HEADERS
+ # reentrant qhull HEADERS:
+ src/libqhull_r/libqhull_r.h
+ src/libqhull_r/geom_r.h
+ src/libqhull_r/io_r.h
+ src/libqhull_r/mem_r.h
+ src/libqhull_r/merge_r.h
+ src/libqhull_r/poly_r.h
+ src/libqhull_r/qhull_ra.h
+ src/libqhull_r/qset_r.h
+ src/libqhull_r/random_r.h
+ src/libqhull_r/stat_r.h
+ src/libqhull_r/user_r.h
+
+ # C++ interface to reentrant Qhull HEADERS:
+ src/libqhullcpp/Coordinates.h
+ src/libqhullcpp/functionObjects.h
+ src/libqhullcpp/PointCoordinates.h
+ src/libqhullcpp/Qhull.h
+ src/libqhullcpp/QhullError.h
+ src/libqhullcpp/QhullFacet.h
+ src/libqhullcpp/QhullFacetList.h
+ src/libqhullcpp/QhullFacetSet.h
+ src/libqhullcpp/QhullHyperplane.h
+ src/libqhullcpp/QhullIterator.h
+ src/libqhullcpp/QhullLinkedList.h
+ src/libqhullcpp/QhullPoint.h
+ src/libqhullcpp/QhullPoints.h
+ src/libqhullcpp/QhullPointSet.h
+ src/libqhullcpp/QhullQh.h
+ src/libqhullcpp/QhullRidge.h
+ src/libqhullcpp/QhullSet.h
+ src/libqhullcpp/QhullSets.h
+ src/libqhullcpp/QhullStat.h
+ src/libqhullcpp/QhullVertex.h
+ src/libqhullcpp/QhullVertexSet.h
+ src/libqhullcpp/RboxPoints.h
+ src/libqhullcpp/RoadError.h
+ src/libqhullcpp/RoadLogEvent.h
+ src/qhulltest/RoadTest.h
+)
+
+set(libqhull_SOURCES
+ # reentrant qhull SOURCES:
+ src/libqhull_r/global_r.c
+ src/libqhull_r/stat_r.c
+ src/libqhull_r/geom2_r.c
+ src/libqhull_r/poly2_r.c
+ src/libqhull_r/merge_r.c
+ src/libqhull_r/libqhull_r.c
+ src/libqhull_r/geom_r.c
+ src/libqhull_r/poly_r.c
+ src/libqhull_r/qset_r.c
+ src/libqhull_r/mem_r.c
+ src/libqhull_r/random_r.c
+ src/libqhull_r/usermem_r.c
+ src/libqhull_r/userprintf_r.c
+ src/libqhull_r/io_r.c
+ src/libqhull_r/user_r.c
+ src/libqhull_r/rboxlib_r.c
+ src/libqhull_r/userprintf_rbox_r.c
+
+ # C++ interface to reentrant Qhull SOURCES:
+ src/libqhullcpp/Coordinates.cpp
+ src/libqhullcpp/PointCoordinates.cpp
+ src/libqhullcpp/Qhull.cpp
+ src/libqhullcpp/QhullFacet.cpp
+ src/libqhullcpp/QhullFacetList.cpp
+ src/libqhullcpp/QhullFacetSet.cpp
+ src/libqhullcpp/QhullHyperplane.cpp
+ src/libqhullcpp/QhullPoint.cpp
+ src/libqhullcpp/QhullPointSet.cpp
+ src/libqhullcpp/QhullPoints.cpp
+ src/libqhullcpp/QhullQh.cpp
+ src/libqhullcpp/QhullRidge.cpp
+ src/libqhullcpp/QhullSet.cpp
+ src/libqhullcpp/QhullStat.cpp
+ src/libqhullcpp/QhullVertex.cpp
+ src/libqhullcpp/QhullVertexSet.cpp
+ src/libqhullcpp/RboxPoints.cpp
+ src/libqhullcpp/RoadError.cpp
+ src/libqhullcpp/RoadLogEvent.cpp
+
+ # headers for both (libqhullr and libqhullcpp:
+ ${libqhull_HEADERS}
+)
+
+
+##################################################
+# combined library (reentrant qhull and qhullcpp) for Slic3r:
+set(qhull_STATIC qhull)
+add_library(${qhull_STATIC} STATIC ${libqhull_SOURCES})
+set_target_properties(${qhull_STATIC} PROPERTIES
+ VERSION ${qhull_VERSION})
+
+if(UNIX)
+ target_link_libraries(${qhull_STATIC} m)
+endif(UNIX)
+##################################################
+
+# LIBDIR is defined in the main xs CMake file:
+target_include_directories(${qhull_STATIC} PRIVATE ${LIBDIR}/qhull/src)
diff --git a/xs/src/qhull/COPYING.txt b/xs/src/qhull/COPYING.txt
new file mode 100644
index 000000000..2895ec6a3
--- /dev/null
+++ b/xs/src/qhull/COPYING.txt
@@ -0,0 +1,38 @@
+ Qhull, Copyright (c) 1993-2015
+
+ C.B. Barber
+ Arlington, MA
+
+ and
+
+ The National Science and Technology Research Center for
+ Computation and Visualization of Geometric Structures
+ (The Geometry Center)
+ University of Minnesota
+
+ email: qhull@qhull.org
+
+This software includes Qhull from C.B. Barber and The Geometry Center.
+Qhull is copyrighted as noted above. Qhull is free software and may
+be obtained via http from www.qhull.org. It may be freely copied, modified,
+and redistributed under the following conditions:
+
+1. All copyright notices must remain intact in all files.
+
+2. A copy of this text file must be distributed along with any copies
+ of Qhull that you redistribute; this includes copies that you have
+ modified, or copies of programs or other software products that
+ include Qhull.
+
+3. If you modify Qhull, you must include a notice giving the
+ name of the person performing the modification, the date of
+ modification, and the reason for such modification.
+
+4. When distributing modified versions of Qhull, or other software
+ products that include Qhull, you must provide notice that the original
+ source code may be obtained as noted above.
+
+5. There is no warranty or other guarantee of fitness for Qhull, it is
+ provided solely "as is". Bug reports or fixes may be sent to
+ qhull_bug@qhull.org; the authors may or may not act on them as
+ they desire.
diff --git a/xs/src/qhull/README.txt b/xs/src/qhull/README.txt
new file mode 100644
index 000000000..f4c7a3b22
--- /dev/null
+++ b/xs/src/qhull/README.txt
@@ -0,0 +1,623 @@
+This distribution of qhull library is only meant for interfacing qhull with Slic3rPE
+(https://github.com/prusa3d/Slic3r).
+
+The qhull source file was acquired from https://github.com/qhull/qhull at revision
+f0bd8ceeb84b554d7cdde9bbfae7d3351270478c.
+
+No changes to the qhull library were made, except for
+- setting REALfloat=1 in user_r.h to enforce calculations in floats
+- modifying CMakeLists.txt (the original was renamed to origCMakeLists.txt)
+
+Many thanks to C. Bradford Barber and all contributors.
+
+Lukas Matena (lukasmatena@seznam.cz)
+25.7.2018
+
+
+See original contents of the README file below.
+
+======================================================================================
+======================================================================================
+======================================================================================
+
+
+Name
+
+ qhull, rbox 2015.2 2016/01/18
+
+Convex hull, Delaunay triangulation, Voronoi diagrams, Halfspace intersection
+
+ Documentation:
+ html/index.htm
+ <http://www.qhull.org/html>
+
+ Available from:
+ <http://www.qhull.org>
+ <http://www.qhull.org/download>
+ <http://github.com/qhull/qhull> (git@github.com:qhull/qhull.git)
+
+ News and a paper:
+ <http://www.qhull.org/news>
+ <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405>
+
+ Version 1 (simplicial only):
+ <http://www.qhull.org/download/qhull-1.0.tar.gz>
+
+Purpose
+
+ Qhull is a general dimension convex hull program that reads a set
+ of points from stdin, and outputs the smallest convex set that contains
+ the points to stdout. It also generates Delaunay triangulations, Voronoi
+ diagrams, furthest-site Voronoi diagrams, and halfspace intersections
+ about a point.
+
+ Rbox is a useful tool in generating input for Qhull; it generates
+ hypercubes, diamonds, cones, circles, simplices, spirals,
+ lattices, and random points.
+
+ Qhull produces graphical output for Geomview. This helps with
+ understanding the output. <http://www.geomview.org>
+
+Environment requirements
+
+ Qhull and rbox should run on all 32-bit and 64-bit computers. Use
+ an ANSI C or C++ compiler to compile the program. The software is
+ self-contained. It comes with examples and test scripts.
+
+ Qhull's C++ interface uses the STL. The C++ test program uses QTestLib
+ from the Qt Framework. Qhull's C++ interface may change without
+ notice. Eventually, it will move into the qhull shared library.
+
+ Qhull is copyrighted software. Please read COPYING.txt and REGISTER.txt
+ before using or distributing Qhull.
+
+To cite Qhull, please use
+
+ Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., "The Quickhull
+ algorithm for convex hulls," ACM Trans. on Mathematical Software,
+ 22(4):469-483, Dec 1996, http://www.qhull.org.
+
+To modify Qhull, particularly the C++ interface
+
+ Qhull is on GitHub
+ (http://github.com/qhull/qhull, git@github.com:qhull/qhull.git)
+
+ For internal documentation, see html/qh-code.htm
+
+To install Qhull
+
+ Qhull is precompiled for Windows 32-bit, otherwise it needs compilation.
+
+ Qhull includes Makefiles for gcc and other targets, CMakeLists.txt for CMake,
+ .sln/.vcproj/.vcxproj files for Microsoft Visual Studio, and .pro files
+ for Qt Creator. It compiles under Windows with mingw.
+
+ Install and build instructions follow.
+
+ See the end of this document for a list of distributed files.
+
+-----------------
+Installing Qhull on Windows 10, 8, 7 (32- or 64-bit), Windows XP, and Windows NT
+
+ The zip file contains rbox.exe, qhull.exe, qconvex.exe, qdelaunay.exe,
+ qhalf.exe, qvoronoi.exe, testqset.exe, user_eg*.exe, documentation files,
+ and source files. Qhull.exe and user-eg3.exe are compiled with the reentrant
+ library while the other executables use the non-reentrant library.
+
+ To install Qhull:
+ - Unzip the files into a directory (e.g., named 'qhull')
+ - Click on QHULL-GO or open a command window into Qhull's bin directory.
+ - Test with 'rbox D4 | qhull'
+
+ To uninstall Qhull
+ - Delete the qhull directory
+
+ To learn about Qhull:
+ - Execute 'qconvex' for a synopsis and examples.
+ - Execute 'rbox 10 | qconvex' to compute the convex hull of 10 random points.
+ - Execute 'rbox 10 | qconvex i TO file' to write results to 'file'.
+ - Browse the documentation: qhull\html\index.htm
+ - If an error occurs, Windows sends the error to stdout instead of stderr.
+ Use 'TO xxx' to send normal output to xxx
+
+ To improve the command window
+ - Double-click the window bar to increase the size of the window
+ - Right-click the window bar
+ - Select Properties
+ - Check QuickEdit Mode
+ Select text with right-click or Enter
+ Paste text with right-click
+ - Change Font to Lucinda Console
+ - Change Layout to Screen Buffer Height 999, Window Size Height 55
+ - Change Colors to Screen Background White, Screen Text Black
+ - Click OK
+ - Select 'Modify shortcut that started this window', then OK
+
+ If you use qhull a lot, install a bash shell such as
+ MSYS (www.mingw.org/wiki/msys), Road Bash (www.qhull.org/bash),
+ or Cygwin (www.cygwin.com).
+
+-----------------
+Installing Qhull on Unix with gcc
+
+ To build Qhull, static libraries, shared library, and C++ interface
+ - Download and extract Qhull (either GitHub, .tgz file, or .zip file)
+ - make
+ - export LD_LIBRARY_PATH=$PWD/lib:$LD_LIBRARY_PATH
+
+ The Makefiles may be edited for other compilers.
+ If 'testqset' exits with an error, qhull is broken
+
+ A simple Makefile for Qhull is in src/libqhull and src/libqhull_r.
+ To build the Qhull executables and libqhullstatic
+ - Extract Qhull from qhull...tgz or qhull...zip
+ - cd src/libqhull_r # cd src/libqhull
+ - make
+
+
+-----------------
+Installing Qhull with CMake 2.6 or later
+
+ See CMakeLists.txt for examples and further build instructions
+
+ To build Qhull, static libraries, shared library, and C++ interface
+ - Download and extract Qhull (either GitHub, .tgz file, or .zip file)
+ - cd build
+ - cmake --help # List build generators
+ - make -G "<generator>" .. && cmake ..
+ - cmake ..
+ - make
+ - make install
+
+ The ".." is important. It refers to the parent directory (i.e., qhull/)
+
+ On Windows, CMake installs to C:/Program Files/qhull. 64-bit generators
+ have a "Win64" tag.
+
+ If creating a qhull package, please include a pkg-config file based on build/qhull*.pc.in
+
+ If cmake fails with "No CMAKE_C_COMPILER could be found"
+ - cmake was not able to find the build environment specified by -G "..."
+
+-----------------
+Installing Qhull with Qt
+
+ To build Qhull, including its C++ test (qhulltest)
+ - Download and extract Qhull (either GitHub, .tgz file, or .zip file)
+ - Load src/qhull-all.pro into QtCreator
+ - Build
+
+-------------------
+Working with Qhull's C++ interface
+
+ See html/qh-code.htm#cpp for calling Qhull from C++ programs
+
+ See html/qh-code.htm#reentrant for converting from Qhull-2012
+
+ Examples of using the C++ interface
+ user_eg3_r.cpp
+ qhulltest/*_test.cpp
+
+ Qhull's C++ interface is likely to change. Stay current with GitHub.
+
+ To clone Qhull's next branch from http://github.com/qhull/qhull
+ git init
+ git clone git@github.com:qhull/qhull.git
+ cd qhull
+ git checkout next
+ ...
+ git pull origin next
+
+ Compile qhullcpp and libqhullstatic_r with the same compiler. Both libraries
+ use the C routines setjmp() and longjmp() for error handling. They must
+ be compiled with the same compiler.
+
+-------------------
+Calling Qhull from C programs
+
+ See html/qh-code.htm#library for calling Qhull from C programs
+
+ See html/qh-code.htm#reentrant for converting from Qhull-2012
+
+ Warning: You will need to understand Qhull's data structures and read the
+ code. Most users will find it easier to call Qhull as an external command.
+
+ The new, reentrant 'C' code (src/libqhull_r), passes a pointer to qhT
+ to most Qhull routines. This allows multiple instances of Qhull to run
+ at the same time. It simplifies the C++ interface.
+
+ The non-reentrant 'C' code (src/libqhull) looks unusual. It refers to
+ Qhull's global data structure, qhT, through a 'qh' macro (e.g., 'qh ferr').
+ This allows the same code to use static memory or heap memory.
+ If qh_QHpointer is defined, qh_qh is a pointer to an allocated qhT;
+ otherwise qh_qh is a global static data structure of type qhT.
+
+------------------
+Compiling Qhull with Microsoft Visual C++
+
+ To compile 32-bit Qhull with Microsoft Visual C++ 2010 and later
+ - Download and extract Qhull (either GitHub, .tgz file, or .zip file)
+ - Load solution build/qhull-32.sln
+ - Build target 'Win32'
+ - Project qhulltest requires Qt for DevStudio (http://www.qt.io)
+ Set the QTDIR environment variable to your Qt directory (e.g., c:/qt/5.2.0/5.2.0/msvc2012)
+ If QTDIR is incorrect, precompile will fail with 'Can not locate the file specified'
+
+ To compile 64-bit Qhull with Microsoft Visual C++ 2010 and later
+ - 64-bit Qhull has larger data structures due to 64-bit pointers
+ - Download and extract Qhull (either GitHub, .tgz file, or .zip file)
+ - Load solution build/qhull-64.sln
+ - Build target 'Win32'
+ - Project qhulltest requires Qt for DevStudio (http://www.qt.io)
+ Set the QTDIR environment variable to your Qt directory (e.g., c:/qt/5.2.0/5.2.0/msvc2012_64)
+ If QTDIR is incorrect, precompile will fail with 'Can not locate the file specified'
+
+ To compile Qhull with Microsoft Visual C++ 2005 (vcproj files)
+ - Download and extract Qhull (either GitHub, .tgz file, or .zip file)
+ - Load solution build/qhull.sln
+ - Build target 'win32' (not 'x64')
+ - Project qhulltest requires Qt for DevStudio (http://www.qt.io)
+ Set the QTDIR environment variable to your Qt directory (e.g., c:/qt/4.7.4)
+ If QTDIR is incorrect, precompile will fail with 'Can not locate the file specified'
+
+-----------------
+Compiling Qhull with Qt Creator
+
+ Qt (http://www.qt.io) is a C++ framework for Windows, Linux, and Macintosh
+
+ Qhull uses QTestLib to test qhull's C++ interface (see src/qhulltest/)
+
+ To compile Qhull with Qt Creator
+ - Download and extract Qhull (either GitHub, .tgz file, or .zip file)
+ - Download the Qt SDK
+ - Start Qt Creator
+ - Load src/qhull-all.pro
+ - Build
+
+-----------------
+Compiling Qhull with mingw on Windows
+
+ To compile Qhull with MINGW
+ - Download and extract Qhull (either GitHub, .tgz file, or .zip file)
+ - Install Road Bash (http://www.qhull.org/bash)
+ or install MSYS (http://www.mingw.org/wiki/msys)
+ - Install MINGW-w64 (http://sourceforge.net/projects/mingw-w64).
+ Mingw is included with Qt SDK.
+ - make
+
+-----------------
+Compiling Qhull with cygwin on Windows
+
+ To compile Qhull with cygwin
+ - Download and extract Qhull (either GitHub, .tgz file, or .zip file)
+ - Install cygwin (http://www.cygwin.com)
+ - Include packages for gcc, make, ar, and ln
+ - make
+
+-----------------
+Compiling from Makfile without gcc
+
+ The file, qhull-src.tgz, contains documentation and source files for
+ qhull and rbox.
+
+ To unpack the tgz file
+ - tar zxf qhull-src.tgz
+ - cd qhull
+ - Use qhull/Makefile
+ Simpler Makefiles are qhull/src/libqhull/Makefile and qhull/src/libqhull_r/Makefile
+
+ Compiling qhull and rbox with Makefile
+ - in Makefile, check the CC, CCOPTS1, PRINTMAN, and PRINTC defines
+ - the defaults are gcc and enscript
+ - CCOPTS1 should include the ANSI flag. It defines __STDC__
+ - in user.h, check the definitions of qh_SECticks and qh_CPUclock.
+ - use '#define qh_CLOCKtype 2' for timing runs longer than 1 hour
+ - type: make
+ - this builds: qhull qconvex qdelaunay qhalf qvoronoi rbox libqhull.a libqhull_r.a
+ - type: make doc
+ - this prints the man page
+ - See also qhull/html/index.htm
+ - if your compiler reports many errors, it is probably not a ANSI C compiler
+ - you will need to set the -ansi switch or find another compiler
+ - if your compiler warns about missing prototypes for fprintf() etc.
+ - this is ok, your compiler should have these in stdio.h
+ - if your compiler warns about missing prototypes for memset() etc.
+ - include memory.h in qhull_a.h
+ - if your compiler reports "global.c: storage size of 'qh_qh' isn't known"
+ - delete the initializer "={0}" in global.c, stat.c and mem.c
+ - if your compiler warns about "stat.c: improper initializer"
+ - this is ok, the initializer is not used
+ - if you have trouble building libqhull.a with 'ar'
+ - try 'make -f Makefile.txt qhullx'
+ - if the code compiles, the qhull test case will automatically execute
+ - if an error occurs, there's an incompatibility between machines
+ - If you can, try a different compiler
+ - You can turn off the Qhull memory manager with qh_NOmem in mem.h
+ - You can turn off compiler optimization (-O2 in Makefile)
+ - If you find the source of the problem, please let us know
+ - to install the programs and their man pages:
+ - define MANDIR and BINDIR
+ - type 'make install'
+
+ - if you have Geomview (www.geomview.org)
+ - try 'rbox 100 | qconvex G >a' and load 'a' into Geomview
+ - run 'q_eg' for Geomview examples of Qhull output (see qh-eg.htm)
+
+------------------
+Compiling on other machines and compilers
+
+ Qhull may compile with Borland C++ 5.0 bcc32. A Makefile is included.
+ Execute 'cd src/libqhull; make -f Mborland'. If you use the Borland IDE, set
+ the ANSI option in Options:Project:Compiler:Source:Language-compliance.
+
+ Qhull may compile with Borland C++ 4.02 for Win32 and DOS Power Pack.
+ Use 'cd src/libqhull; make -f Mborland -D_DPMI'. Qhull 1.0 compiles with
+ Borland C++ 4.02. For rbox 1.0, use "bcc32 -WX -w- -O2-e -erbox -lc rbox.c".
+ Use the same options for Qhull 1.0. [D. Zwick]
+
+ If you have troubles with the memory manager, you can turn it off by
+ defining qh_NOmem in mem.h.
+
+-----------------
+Distributed files
+
+ README.txt // Instructions for installing Qhull
+ REGISTER.txt // Qhull registration
+ COPYING.txt // Copyright notice
+ QHULL-GO.lnk // Windows icon for eg/qhull-go.bat
+ Announce.txt // Announcement
+ CMakeLists.txt // CMake build file (2.6 or later)
+ CMakeModules/CheckLFS.cmake // enables Large File Support in cmake
+ File_id.diz // Package descriptor
+ index.htm // Home page
+ Makefile // Makefile for gcc and other compilers
+ qhull*.md5sum // md5sum for all files
+
+ bin/* // Qhull executables and dll (.zip only)
+ build/qhull*.pc.in // pkg-config templates for qhull_r, qhull, and qhull_p
+ build/qhull-32.sln // 32-bit DevStudio solution and project files (2010 and later)
+ build/*-32.vcxproj
+ build/qhull-64.sln // 64-bit DevStudio solution and project files (2010 and later)
+ build/*-64.vcxproj
+ build/qhull.sln // DevStudio solution and project files (2005 and 2009)
+ build/*.vcproj
+ eg/* // Test scripts and geomview files from q_eg
+ html/index.htm // Manual
+ html/qh-faq.htm // Frequently asked questions
+ html/qh-get.htm // Download page
+ html/qhull-cpp.xml // C++ style notes as a Road FAQ (www.qhull.org/road)
+ src/Changes.txt // Change history for Qhull and rbox
+ src/qhull-all.pro // Qt project
+
+eg/
+ q_eg // shell script for Geomview examples (eg.01.cube)
+ q_egtest // shell script for Geomview test examples
+ q_test // shell script to test qhull
+ q_test-ok.txt // output from q_test
+ qhulltest-ok.txt // output from qhulltest (Qt only)
+ make-vcproj.sh // bash shell script to create vcproj and vcxprog files
+ qhull-zip.sh // bash shell script for distribution files
+
+rbox consists of (bin, html):
+ rbox.exe // Win32 executable (.zip only)
+ rbox.htm // html manual
+ rbox.man // Unix man page
+ rbox.txt
+
+qhull consists of (bin, html):
+ qconvex.exe // Win32 executables and dlls (.zip download only)
+ qhull.exe // Built with the reentrant library (about 2% slower)
+ qdelaunay.exe
+ qhalf.exe
+ qvoronoi.exe
+ qhull_r.dll
+ qhull-go.bat // command window
+ qconvex.htm // html manual
+ qdelaun.htm
+ qdelau_f.htm
+ qhalf.htm
+ qvoronoi.htm
+ qvoron_f.htm
+ qh-eg.htm
+ qh-code.htm
+ qh-impre.htm
+ index.htm
+ qh-opt*.htm
+ qh-quick.htm
+ qh--*.gif // images for manual
+ normal_voronoi_knauss_oesterle.jpg
+ qhull.man // Unix man page
+ qhull.txt
+
+bin/
+ msvcr80.dll // Visual C++ redistributable file (.zip download only)
+
+src/
+ qhull/unix.c // Qhull and rbox applications using non-reentrant libqhullstatic.a
+ rbox/rbox.c
+ qconvex/qconvex.c
+ qhalf/qhalf.c
+ qdelaunay/qdelaunay.c
+ qvoronoi/qvoronoi.c
+
+ qhull/unix_r.c // Qhull and rbox applications using reentrant libqhullstatic_r.a
+ rbox/rbox_r.c
+ qconvex/qconvex_r.c // Qhull applications built with reentrant libqhull_r/Makefile
+ qhalf/qhalf_r.c
+ qdelaunay/qdelaun_r.c
+ qvoronoi/qvoronoi_r.c
+
+ user_eg/user_eg_r.c // example of using qhull_r.dll from a user program
+ user_eg2/user_eg2_r.c // example of using libqhullstatic_r.a from a user program
+ user_eg3/user_eg3_r.cpp // example of Qhull's C++ interface libqhullcpp with libqhullstatic_r.a
+ qhulltest/qhulltest.cpp // Test of Qhull's C++ interface using Qt's QTestLib
+ qhull-*.pri // Include files for Qt projects
+ testqset_r/testqset_r.c // Test of reentrant qset_r.c and mem_r.c
+ testqset/testqset.c // Test of non-rentrant qset.c and mem.c
+
+
+src/libqhull
+ libqhull.pro // Qt project for non-rentrant, shared library (qhull.dll)
+ index.htm // design documentation for libqhull
+ qh-*.htm
+ qhull-exports.def // Export Definition file for Visual C++
+ Makefile // Simple gcc Makefile for qhull and libqhullstatic.a
+ Mborland // Makefile for Borland C++ 5.0
+
+ libqhull.h // header file for qhull
+ user.h // header file of user definable constants
+ libqhull.c // Quickhull algorithm with partitioning
+ user.c // user re-definable functions
+ usermem.c
+ userprintf.c
+ userprintf_rbox.c
+
+ qhull_a.h // include files for libqhull/*.c
+ geom.c // geometric routines
+ geom2.c
+ geom.h
+ global.c // global variables
+ io.c // input-output routines
+ io.h
+ mem.c // memory routines, this is stand-alone code
+ mem.h
+ merge.c // merging of non-convex facets
+ merge.h
+ poly.c // polyhedron routines
+ poly2.c
+ poly.h
+ qset.c // set routines, this only depends on mem.c
+ qset.h
+ random.c // utilities w/ Park & Miller's random number generator
+ random.h
+ rboxlib.c // point set generator for rbox
+ stat.c // statistics
+ stat.h
+
+src/libqhull_r
+ libqhull_r.pro // Qt project for rentrant, shared library (qhull_r.dll)
+ index.htm // design documentation for libqhull_r
+ qh-*_r.htm
+ qhull-exports_r.def // Export Definition file for Visual C++
+ Makefile // Simple gcc Makefile for qhull and libqhullstatic.a
+
+ libqhull_r.h // header file for qhull
+ user_r.h // header file of user definable constants
+ libqhull_r.c // Quickhull algorithm wi_r.hpartitioning
+ user_r.c // user re-definable functions
+ usermem.c
+ userprintf.c
+ userprintf_rbox.c
+ qhull_ra.h // include files for libqhull/*_r.c
+ geom_r.c // geometric routines
+ geom2.c
+ geom_r.h
+ global_r.c // global variables
+ io_r.c // input-output routines
+ io_r.h
+ mem_r.c // memory routines, this is stand-alone code
+ mem.h
+ merge_r.c // merging of non-convex facets
+ merge.h
+ poly_r.c // polyhedron routines
+ poly2.c
+ poly_r.h
+ qset_r.c // set routines, this only depends on mem_r.c
+ qset.h
+ random_r.c // utilities w/ Park & Miller's random number generator
+ random.h
+ rboxlib_r.c // point set generator for rbox
+ stat_r.c // statistics
+ stat.h
+
+src/libqhullcpp/
+ libqhullcpp.pro // Qt project for renentrant, static C++ library
+ Qhull.cpp // Calls libqhull_r.c from C++
+ Qhull.h
+ qt-qhull.cpp // Supporting methods for Qt
+
+ Coordinates.cpp // input classes
+ Coordinates.h
+
+ PointCoordinates.cpp
+ PointCoordinates.h
+ RboxPoints.cpp // call rboxlib.c from C++
+ RboxPoints.h
+
+ QhullFacet.cpp // data structure classes
+ QhullFacet.h
+ QhullHyperplane.cpp
+ QhullHyperplane.h
+ QhullPoint.cpp
+ QhullPoint.h
+ QhullQh.cpp
+ QhullRidge.cpp
+ QhullRidge.h
+ QhullVertex.cpp
+ QhullVertex.h
+
+ QhullFacetList.cpp // collection classes
+ QhullFacetList.h
+ QhullFacetSet.cpp
+ QhullFacetSet.h
+ QhullIterator.h
+ QhullLinkedList.h
+ QhullPoints.cpp
+ QhullPoints.h
+ QhullPointSet.cpp
+ QhullPointSet.h
+ QhullSet.cpp
+ QhullSet.h
+ QhullSets.h
+ QhullVertexSet.cpp
+ QhullVertexSet.h
+
+ functionObjects.h // supporting classes
+ QhullError.cpp
+ QhullError.h
+ QhullQh.cpp
+ QhullQh.h
+ QhullStat.cpp
+ QhullStat.h
+ RoadError.cpp // Supporting base classes
+ RoadError.h
+ RoadLogEvent.cpp
+ RoadLogEvent.h
+ usermem_r-cpp.cpp // Optional override for qh_exit() to throw an error
+
+src/libqhullstatic/
+ libqhullstatic.pro // Qt project for non-reentrant, static library
+
+src/libqhullstatic_r/
+ libqhullstatic_r.pro // Qt project for reentrant, static library
+
+src/qhulltest/
+ qhulltest.pro // Qt project for test of C++ interface
+ Coordinates_test.cpp // Test of each class
+ PointCoordinates_test.cpp
+ Qhull_test.cpp
+ QhullFacet_test.cpp
+ QhullFacetList_test.cpp
+ QhullFacetSet_test.cpp
+ QhullHyperplane_test.cpp
+ QhullLinkedList_test.cpp
+ QhullPoint_test.cpp
+ QhullPoints_test.cpp
+ QhullPointSet_test.cpp
+ QhullRidge_test.cpp
+ QhullSet_test.cpp
+ QhullVertex_test.cpp
+ QhullVertexSet_test.cpp
+ RboxPoints_test.cpp
+ RoadTest.cpp // Run multiple test files with QTestLib
+ RoadTest.h
+
+-----------------
+Authors:
+
+ C. Bradford Barber Hannu Huhdanpaa (Version 1.0)
+ bradb@shore.net hannu@qhull.org
+
+ Qhull 1.0 and 2.0 were developed under NSF grants NSF/DMS-8920161
+ and NSF-CCR-91-15793 750-7504 at the Geometry Center and Harvard
+ University. If you find Qhull useful, please let us know.
diff --git a/xs/src/qhull/REGISTER.txt b/xs/src/qhull/REGISTER.txt
new file mode 100644
index 000000000..16ccb1a58
--- /dev/null
+++ b/xs/src/qhull/REGISTER.txt
@@ -0,0 +1,32 @@
+Dear Qhull User
+
+We would like to find out how you are using our software. Think of
+Qhull as a new kind of shareware: you share your science and successes
+with us, and we share our software and support with you.
+
+If you use Qhull, please send us a note telling
+us what you are doing with it.
+
+We need to know:
+
+ (1) What you are working on - an abstract of your work would be
+ fine.
+
+ (2) How Qhull has helped you, for example, by increasing your
+ productivity or allowing you to do things you could not do
+ before. If Qhull had a direct bearing on your work, please
+ tell us about this.
+
+We encourage you to cite Qhull in your publications.
+
+To cite Qhull, please use
+
+ Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., "The Quickhull
+ algorithm for convex hulls," ACM Trans. on Mathematical Software,
+ 22(4):469-483, Dec 1996, http://www.qhull.org.
+
+Please send e-mail to
+
+ bradb@shore.net
+
+Thank you!
diff --git a/xs/src/qhull/html/index.htm b/xs/src/qhull/html/index.htm
new file mode 100644
index 000000000..ca4789b47
--- /dev/null
+++ b/xs/src/qhull/html/index.htm
@@ -0,0 +1,935 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<meta name="GENERATOR" content="Microsoft FrontPage 2.0">
+<title>Qhull manual</title>
+<!-- Navigation links
+NOTE -- verify all links by 'grep href=' 'grep name=' add # 'sort /+7'
+ index.htm
+-->
+</head>
+
+<body>
+
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b><a
+href="http://www.qhull.org/news">News</a> about Qhull<br>
+<b>Up:</b> <a href="http://www.qhull.org/html/qh-faq.htm">FAQ</a> about Qhull<br>
+<b>To:</b> <a href="#TOC">Qhull manual: Table of Contents</a>
+(please wait while loading) <br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/fixed.html"><img
+src="qh--rand.gif" alt="[random-fixed]" align="middle"
+width="100" height="100"></a> Qhull manual </h1>
+
+<p>Qhull is a general dimension code for computing convex hulls,
+Delaunay triangulations, halfspace intersections about a point, Voronoi
+diagrams, furthest-site Delaunay triangulations, and
+furthest-site Voronoi diagrams. These structures have
+applications in science, engineering, statistics, and
+mathematics. See <a
+href="http://www.cs.mcgill.ca/~fukuda/soft/polyfaq/polyfaq.html">Fukuda's
+introduction</a> to convex hulls, Delaunay triangulations,
+Voronoi diagrams, and linear programming. For a detailed
+introduction, see O'Rourke [<a href="#orou94">'94</a>], <i>Computational
+Geometry in C</i>.
+</p>
+
+<p>There are six programs. Except for rbox, they use
+the same code. Each program includes instructions and examples.
+<blockquote>
+<ul>
+<li><a href="qconvex.htm">qconvex</a> -- convex hulls
+<li><a href="qdelaun.htm">qdelaunay</a> -- Delaunay triangulations and
+ furthest-site Delaunay triangulations
+<li><a href="qhalf.htm">qhalf</a> -- halfspace intersections about a point
+<li><a href="qhull.htm">qhull</a> -- all structures with additional options
+<li><a href="qvoronoi.htm">qvoronoi</a> -- Voronoi diagrams and
+ furthest-site Voronoi diagrams
+<li><a href="rbox.htm">rbox</a> -- generate point distributions for qhull
+</ul>
+</blockquote>
+
+<p>Qhull implements the Quickhull algorithm for computing the
+convex hull. Qhull includes options
+for hull volume, facet area, multiple output formats, and
+graphical output. It can approximate a convex hull. </p>
+
+<p>Qhull handles roundoff errors from floating point
+arithmetic. It generates a convex hull with "thick" facets.
+A facet's outer plane is clearly above all of the points;
+its inner plane is clearly below the facet's vertices. Any
+exact convex hull must lie between the inner and outer plane.
+
+<p>Qhull uses merged facets, triangulated output, or joggled
+input. Triangulated output triangulates non-simplicial, merged
+facets. Joggled input also
+guarantees simplicial output, but it
+is less accurate than merged facets. For merged facets, Qhull
+reports the maximum outer and inner plane.
+
+<p><i>Brad Barber, Arlington, MA</i></p>
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<h2><a href="#TOP">&#187;</a><a name="TOC">Qhull manual: Table of
+Contents </a></h2>
+
+<ul>
+ <li><a href="#when">When</a> to use Qhull
+ <ul>
+ <li><a href="http://www.qhull.org/news">News</a> for Qhull
+ with new features and reported bugs.
+ <li><a href="http://www.qhull.org">Home</a> for Qhull with additional URLs
+ (<a href=index.htm>local copy</a>)
+ <li><a href="http://www.qhull.org/html/qh-faq.htm">FAQ</a> for Qhull (<a href="qh-faq.htm">local copy</a>)
+ <li><a href="http://www.qhull.org/download">Download</a> Qhull (<a href=qh-get.htm>local copy</a>)
+ <li><a href="qh-quick.htm#programs">Quick</a> reference for Qhull and its <a href="qh-quick.htm#options">options</a>
+ <p>
+ <li><a href="../COPYING.txt">COPYING.txt</a> - copyright notice<br>
+ <li><a href="../REGISTER.txt">REGISTER.txt</a> - registration<br>
+ <li><a href="../README.txt">README.txt</a> - installation
+ instructions<br>
+ <li><a href="../src/Changes.txt">Changes.txt</a> - change history <br>
+ <li><a href="qhull.txt">qhull.txt</a> - Unix manual page
+ </ul>
+ <p>
+ <li><a href="#description">Description</a> of Qhull
+ <ul>
+ <li><a href="#definition">de</a>finition &#149; <a
+ href="#input">in</a>put &#149; <a href="#output">ou</a>tput
+ &#149; <a href="#algorithm">al</a>gorithm &#149; <a
+ href="#structure">da</a>ta structure </li>
+ <li><a href="qh-impre.htm">Imprecision</a> in Qhull</li>
+ <li><a href="qh-impre.htm#joggle">Merged facets</a> or joggled input
+ <li><a href="qh-eg.htm">Examples</a> of Qhull</li>
+ </ul>
+ <p>
+ <li><a href=qh-quick.htm#programs>Qhull programs</a>, with instructions and examples
+ <ul>
+ <li><a href="qconvex.htm">qconvex</a> -- convex hulls
+ <li><a href="qdelaun.htm">qdelaunay</a> -- Delaunay triangulations and
+ furthest-site Delaunay triangulations
+ <li><a href="qhalf.htm">qhalf</a> -- halfspace intersections about a point
+ <li><a href="qhull.htm">qhull</a> -- all structures with additional options
+ <li><a href="qvoronoi.htm">qvoronoi</a> -- Voronoi diagrams and
+ furthest-site Voronoi diagrams
+ <li><a href="rbox.htm">rbox</a> -- generate point distributions for qhull
+ </ul>
+ <p>
+ <li><a href="qh-quick.htm#options">Qhull options</a><ul>
+ <li><a href="qh-opto.htm#output">Output</a> formats</li>
+ <li><a href="qh-optf.htm#format">Additional</a> I/O
+ formats</li>
+ <li><a href="qh-optg.htm#geomview">Geomview</a>
+ output options</li>
+ <li><a href="qh-optp.htm#print">Print</a> options</li>
+ <li><a href="qh-optq.htm#qhull">Qhull</a> control
+ options</li>
+ <li><a href="qh-optc.htm#prec">Precision</a> options</li>
+ <li><a href="qh-optt.htm#trace">Trace</a> options</li>
+ </ul>
+ </li>
+ <p>
+ <li><a href="#geomview">Geomview</a>, Qhull's graphical viewer</li>
+ <ul>
+ <li><a href="#geomview-install">Installing Geomview</a></li>
+ <li><a href="#geomview-use">Using Geomview</a></li>
+ <li><a href="#geomview-win">Building Geomview for Windows</a></li>
+ </ul>
+ <p>
+ <li><a href="qh-code.htm">Qhull internals</a><ul>
+ <li><a href="qh-code.htm#reentrant">Reentrant</a> Qhull</li>
+ <li><a href="qh-code.htm#convert">How to convert</a> code to reentrant Qhull</li>
+ <li><a href="qh-code.htm#64bit">Qhull</a> on 64-bit computers</li>
+ <li><a href="qh-code.htm#cpp">Calling</a> Qhull
+ from C++ programs</li>
+ <li><a href="qh-code.htm#library">Calling</a> Qhull
+ from C programs</li>
+ <li><a href="qh-code.htm#performance">Performance</a>
+ of Qhull</li>
+ <li><a href="qh-code.htm#enhance">Enhancements</a> to
+ Qhull</li>
+ <li><a href="../src/libqhull_r/index.htm">Reentrant</a> Qhull functions, macros, and
+ data structures </li>
+ <li><a href="../src/libqhull/index.htm">Qhull</a> functions, macros, and
+ data structures </li>
+ </ul>
+ </li>
+ <p>
+ <li>Related URLs
+ <ul>
+
+ <li><a href="news:comp.graphics.algorithms">Newsgroup</a>:
+ comp.graphics.algorithms
+ <li><a
+ href="http://www.faqs.org/faqs/graphics/algorithms-faq/">FAQ</a> for computer graphics algorithms and
+ Exaflop's <a href="http://exaflop.org/docs/cgafaq/cga6.html">geometric</a> structures.
+ <li>Amenta's <a href="http://www.geom.uiuc.edu/software/cglist">Directory
+ of Computational Geometry Software </a></li>
+ <li>Erickson's <a
+ href="http://compgeom.cs.uiuc.edu/~jeffe/compgeom/code.html">Computational
+ Geometry Software</a> </li>
+ <li>Fukuda's <a
+ href="http://www.cs.mcgill.ca/~fukuda/soft/polyfaq/polyfaq.html">
+ introduction</a> to convex hulls, Delaunay triangulations,
+ Voronoi diagrams, and linear programming.
+ <li>Stony Brook's <a
+ href="http://www.cs.sunysb.edu/~algorith/major_section/1.6.shtml">Algorithm Repository</a> on computational geometry.
+ </li>
+ </ul>
+ <p>
+ <li><a href="#bugs">What to do</a> if something goes wrong</li>
+ <li><a href="#email">Email</a></li>
+ <li><a href="#authors">Authors</a></li>
+ <li><a href="#ref">References</a></li>
+ <li><a href="#acknowledge">Acknowledgments</a></li>
+</ul>
+<h2><a href="#TOC">&#187;</a><a name="when">When to use Qhull</a></h2>
+<blockquote>
+
+<p>Qhull constructs convex hulls, Delaunay triangulations,
+halfspace intersections about a point, Voronoi diagrams, furthest-site Delaunay
+triangulations, and furthest-site Voronoi diagrams.</p>
+
+<p>For convex hulls and halfspace intersections, Qhull may be used
+for 2-d upto 8-d. For Voronoi diagrams and Delaunay triangulations, Qhull may be
+used for 2-d upto 7-d. In higher dimensions, the size of the output
+grows rapidly and Qhull does not work well with virtual memory.
+If <i>n</i> is the size of
+the input and <i>d</i> is the dimension (d>=3), the size of the output
+and execution time
+grows by <i>n^(floor(d/2)</i>
+[see <a href=qh-code.htm#performance>Performance</a>]. For example, do
+not try to build a 16-d convex hull of 1000 points. It will
+have on the order of 1,000,000,000,000,000,000,000,000 facets.
+
+<p>On a 600 MHz Pentium 3, Qhull computes the 2-d convex hull of
+300,000 cocircular points in 11 seconds. It computes the
+2-d Delaunay triangulation and 3-d convex hull of 120,000 points
+in 12 seconds. It computes the
+3-d Delaunay triangulation and 4-d convex hull of 40,000 points
+in 18 seconds. It computes the
+4-d Delaunay triangulation and 5-d convex hull of 6,000 points
+in 12 seconds. It computes the
+5-d Delaunay triangulation and 6-d convex hull of 1,000 points
+in 12 seconds. It computes the
+6-d Delaunay triangulation and 7-d convex hull of 300 points
+in 15 seconds. It computes the
+7-d Delaunay triangulation and 8-d convex hull of 120 points
+in 15 seconds. It computes the
+8-d Delaunay triangulation and 9-d convex hull of 70 points
+in 15 seconds. It computes the
+9-d Delaunay triangulation and 10-d convex hull of 50 points
+in 17 seconds. The 10-d convex hull of 50 points has about 90,000 facets.
+
+<!-- duplicated in index.htm and html/index.htm -->
+<p>Qhull does <i>not</i> support constrained Delaunay
+triangulations, triangulation of non-convex surfaces, mesh
+generation of non-convex objects, or medium-sized inputs in 9-D
+and higher. </p>
+
+<p>This is a big package with many options. It is one of the
+fastest available. It is the only 3-d code that handles precision
+problems due to floating point arithmetic. For example, it
+implements the identity function for extreme points (see <a
+href="qh-impre.htm">Imprecision in Qhull</a>). </p>
+
+<p>[2016] A newly discovered, bad case for Qhull is multiple, nearly incident points within a 10^-13 ball of 3-d and higher
+Delaunay triangulations (input sites in the unit cube). Nearly incident points within substantially
+smaller or larger balls are OK. Error QH6271 is reported if a problem occurs. A future release of Qhull
+will handle this case. For more information, see "Nearly coincident points on an edge" in <a href="../html/qh-impre.htm#limit">Limitations of merged facets</a>
+
+<p>If you need a short code for convex hull, Delaunay
+triangulation, or Voronoi volumes consider Clarkson's <a
+href="http://www.netlib.org/voronoi/hull.html">hull
+program</a>. If you need 2-d Delaunay triangulations consider
+Shewchuk's <a href="http://www.cs.cmu.edu/~quake/triangle.html">triangle
+program</a>. It is much faster than Qhull and it allows
+constraints. Both programs use exact arithmetic. They are in <a
+href="http://www.netlib.org/voronoi/">http://www.netlib.org/voronoi/</a>.
+
+<p>If your input is in general position (i.e., no coplanar or colinear points),
+<li><a href="https://github.com/tomilov/quickhull/blob/master/include/quickhull.hpp">Tomilov's quickhull.hpp</a> (<a href"http://habrahabr.ru/post/245221/"documentation-ru</a/>)
+or Qhull <a
+href="http://www.qhull.org/download">version
+1.0</a> may meet your needs. Both programs detect precision problems,
+but do not handle them.</p>
+
+<p><a href=http://www.cgal.org>CGAL</a> is a library of efficient and reliable
+geometric algorithms. It uses C++ templates and the Boost library to produce dimension-specific
+code. This allows more efficient use of memory than Qhull's general-dimension
+code. CGAL simulates arbitrary precision while Qhull handles round-off error
+with thick facets. Compare the two approaches with <a href="http://doc.cgal.org/latest/Manual/devman_robustness.html">Robustness Issues in CGAL</a>,
+and <a href+"qh-impre.htm">Imprecision in Qhull</a>.
+
+
+<p><a href=http://www.algorithmic-solutions.com/enleda.htm>Leda</a> is a
+library for writing computational
+geometry programs and other combinatorial algorithms. It
+includes routines for computing 3-d convex
+hulls, 2-d Delaunay triangulations, and 3-d Delaunay triangulations.
+It provides rational arithmetic and graphical output. It runs on most
+platforms.
+
+<p>If your problem is in high dimensions with a few,
+non-simplicial facets, try Fukuda's <a
+href="http://www.cs.mcgill.ca/~fukuda/soft/cdd_home/cdd.html">cdd</a>.
+It is much faster than Qhull for these distributions. </p>
+
+<p>Custom software for 2-d and 3-d convex hulls may be faster
+than Qhull. Custom software should use less memory. Qhull uses
+general-dimension data structures and code. The data structures
+support non-simplicial facets.</p>
+
+<p>Qhull is not suitable for mesh generation or triangulation of
+arbitrary surfaces. You may use Qhull if the surface is convex or
+completely visible from an interior point (e.g., a star-shaped
+polyhedron). First, project each site to a sphere that is
+centered at the interior point. Then, compute the convex hull of
+the projected sites. The facets of the convex hull correspond to
+a triangulation of the surface. For mesh generation of arbitrary
+surfaces, see <a
+href="http://www.robertschneiders.de/meshgeneration/meshgeneration.html">Schneiders'
+Finite Element Mesh Generation</a>.</p>
+
+<p>Qhull is not suitable for constrained Delaunay triangulations.
+With a lot of work, you can write a program that uses Qhull to
+add constraints by adding additional points to the triangulation.</p>
+
+<p>Qhull is not suitable for the subdivision of arbitrary
+objects. Use <tt>qdelaunay</tt> to subdivide a convex object.</p>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a><a name="description">Description of
+Qhull </a></h2>
+<blockquote>
+
+<h3><a href="#TOC">&#187;</a><a name="definition">definition</a></h3>
+<blockquote>
+
+<p>The <i>convex hull</i> of a point set <i>P</i> is the smallest
+convex set that contains <i>P</i>. If <i>P</i> is finite, the
+convex hull defines a matrix <i>A</i> and a vector <i>b</i> such
+that for all <i>x</i> in <i>P</i>, <i>Ax+b &lt;= [0,...]</i>. </p>
+
+<p>Qhull computes the convex hull in 2-d, 3-d, 4-d, and higher
+dimensions. Qhull represents a convex hull as a list of facets.
+Each facet has a set of vertices, a set of neighboring facets,
+and a halfspace. A halfspace is defined by a unit normal and an
+offset (i.e., a row of <i>A</i> and an element of <i>b</i>). </p>
+
+<p>Qhull accounts for round-off error. It returns
+&quot;thick&quot; facets defined by two parallel hyperplanes. The
+outer planes contain all input points. The inner planes exclude
+all output vertices. See <a href="qh-impre.htm#imprecise">Imprecise
+convex hulls</a>.</p>
+
+<p>Qhull may be used for the Delaunay triangulation or the
+Voronoi diagram of a set of points. It may be used for the
+intersection of halfspaces. </p>
+
+</blockquote>
+<h3><a href="#TOC">&#187;</a><a name="input">input format</a></h3>
+<blockquote>
+
+<p>The input data on <tt>stdin</tt> consists of:</p>
+
+<ul>
+ <li>first line contains the dimension</li>
+ <li>second line contains the number of input points</li>
+ <li>remaining lines contain point coordinates</li>
+</ul>
+
+<p>For example: </p>
+
+<pre>
+ 3 #sample 3-d input
+ 5
+ 0.4 -0.5 1.0
+ 1000 -1e-5 -100
+ 0.3 0.2 0.1
+ 1.0 1.0 1.0
+ 0 0 0
+</pre>
+
+<p>Input may be entered by hand. End the input with a control-D
+(^D) character. </p>
+
+<p>To input data from a file, use I/O redirection or '<a
+href="qh-optt.htm#TI">TI file</a>'. The filename may not
+include spaces or quotes.</p>
+
+<p>A comment starts with a non-numeric character and continues to
+the end of line. The first comment is reported in summaries and
+statistics. With multiple <tt>qhull</tt> commands, use option '<a
+href="qh-optf.htm#FQ">FQ</a>' to place a comment in the output.</p>
+
+<p>The dimension and number of points can be reversed. Comments
+and line breaks are ignored. Error reporting is better if there
+is one point per line.</p>
+
+</blockquote>
+<h3><a href="#TOC">&#187;</a><a name="option">option format</a></h3>
+<blockquote>
+
+<p>Use options to specify the output formats and control
+Qhull. The <tt>qhull</tt> program takes all options. The
+other programs use a subset of the options. They disallow
+experimental and inappropriate options.
+
+<blockquote>
+<ul>
+<li>
+qconvex == qhull
+<li>
+qdelaunay == qhull d Qbb
+<li>
+qhalf == qhull H
+<li>
+qvoronoi == qhull v Qbb
+</ul>
+</blockquote>
+
+<p>Single letters are used for output formats and precision
+constants. The other options are grouped into menus for formats
+('<a href="qh-optf.htm#format">F</a>'), Geomview ('<a
+href="qh-optg.htm#geomview">G </a>'), printing ('<a
+href="qh-optp.htm#print">P</a>'), Qhull control ('<a
+href="qh-optq.htm#qhull">Q </a>'), and tracing ('<a
+href="qh-optt.htm#trace">T</a>'). The menu options may be listed
+together (e.g., 'GrD3' for 'Gr' and 'GD3'). Options may be in any
+order. Capitalized options take a numeric argument (except for '<a
+href="qh-optp.htm#PG">PG</a>' and '<a href="qh-optf.htm#format">F</a>'
+options). Use option '<a href="qh-optf.htm#FO">FO</a>' to print
+the selected options.</p>
+
+<p>Qhull uses zero-relative indexing. If there are <i>n</i>
+points, the index of the first point is <i>0</i> and the index of
+the last point is <i>n-1</i>.</p>
+
+<p>The default options are:</p>
+
+<ul>
+ <li>summary output ('<a href="qh-opto.htm#s">s</a>') </li>
+ <li>merged facets ('<a href="qh-optc.htm#C0">C-0</a>' in 2-d,
+ 3-d, 4-d; '<a href="qh-optq.htm#Qx">Qx</a>' in 5-d and
+ up)</li>
+</ul>
+
+<p>Except for bounding box
+('<a href="qh-optq.htm#Qbk">Qbk:n</a>', etc.), drop facets
+('<a href="qh-optp.htm#Pdk">Pdk:n</a>', etc.), and
+Qhull command ('<a href="qh-optf.htm#FQ">FQ</a>'), only the last
+occurence of an option counts.
+Bounding box and drop facets may be repeated for each dimension.
+Option 'FQ' may be repeated any number of times.
+
+<p>The Unix <tt>tcsh</tt> and <tt>ksh </tt>shells make it easy to
+try out different options. In Windows 95, use a command window with <tt>doskey</tt>
+and a window scroller (e.g., <tt>peruse</tt>). </p>
+
+</blockquote>
+<h3><a href="#TOC">&#187;</a><a name="output">output format</a></h3>
+<blockquote>
+
+<p>To write the results to a file, use I/O redirection or '<a
+href="qh-optt.htm#TO">TO file</a>'. Windows 95 users should use
+'TO file' or the console. If a filename is surrounded by single quotes,
+it may include spaces.
+</p>
+
+<p>The default output option is a short summary ('<a
+href="qh-opto.htm#s">s</a>') to <tt>stdout</tt>. There are many
+others (see <a href="qh-opto.htm">output</a> and <a
+href="qh-optf.htm">formats</a>). You can list vertex incidences,
+vertices and facets, vertex coordinates, or facet normals. You
+can view Qhull objects with Geomview, Mathematica, or Maple. You can
+print the internal data structures. You can call Qhull from your
+application (see <a href="qh-code.htm#library">Qhull library</a>).</p>
+
+<p>For example, 'qhull <a href="qh-opto.htm#o">o</a>' lists the
+vertices and facets of the convex hull. </p>
+
+<p>Error messages and additional summaries ('<a
+href="qh-opto.htm#s">s</a>') go to <tt>stderr</tt>. Unless
+redirected, <tt>stderr</tt> is the console.</p>
+
+</blockquote>
+<h3><a href="#TOC">&#187;</a><a name="algorithm">algorithm</a></h3>
+<blockquote>
+
+<p>Qhull implements the Quickhull algorithm for convex hull
+[Barber et al. <a href="#bar-dob96">'96</a>]. This algorithm
+combines the 2-d Quickhull algorithm with the <em>n</em>-d
+beneath-beyond algorithm [c.f., Preparata &amp; Shamos <a
+href="#pre-sha85">'85</a>]. It is similar to the randomized
+algorithms of Clarkson and others [Clarkson &amp; Shor <a
+href="#cla-sho89">'89</a>; Clarkson et al. <a href="#cla-meh93">'93</a>;
+Mulmuley <a href="#mulm94">'94</a>]. For a demonstration, see <a
+href="qh-eg.htm#how">How Qhull adds a point</a>. The main
+advantages of Quickhull are output sensitive performance (in
+terms of the number of extreme points), reduced space
+requirements, and floating-point error handling. </p>
+
+</blockquote>
+<h3><a href="#TOC">&#187;</a><a name="structure">data structures</a></h3>
+<blockquote>
+
+<p>Qhull produces the following data structures for dimension <i>d</i>:
+</p>
+
+<ul>
+ <li>A <em>coordinate</em> is a real number in floating point
+ format. </li>
+ <li>A <em>point</em> is an array of <i>d</i> coordinates.
+ With option '<a href="qh-optq.htm#QJn">QJ</a>', the
+ coordinates are joggled by a small amount. </li>
+ <li>A <em>vertex</em> is an input point. </li>
+ <li>A <em>hyperplane</em> is <i>d</i> normal coefficients and
+ an offset. The length of the normal is one. The
+ hyperplane defines a halfspace. If <i>V</i> is a normal, <i>b</i>
+ is an offset, and <i>x</i> is a point inside the convex
+ hull, then <i>Vx+b &lt;0</i>.</li>
+ <li>An <em>outer plane</em> is a positive
+ offset from a hyperplane. When Qhull is done, all points
+ will be below all outer planes.</li>
+ <li>An <em>inner plane</em> is a negative
+ offset from a hyperplane. When Qhull is done, all
+ vertices will be above the corresponding inner planes.</li>
+ <li>An <em>orientation</em> is either 'top' or 'bottom'. It is the
+ topological equivalent of a hyperplane's geometric
+ orientation. </li>
+ <li>A <em>simplicial facet</em> is a set of
+ <i>d</i> neighboring facets, a set of <i>d</i> vertices, a
+ hyperplane equation, an inner plane, an outer plane, and
+ an orientation. For example in 3-d, a simplicial facet is
+ a triangle. </li>
+ <li>A <em>centrum</em> is a point on a facet's hyperplane. A
+ centrum is the average of a facet's vertices. Neighboring
+ facets are <em>convex</em> if each centrum is below the
+ neighbor facet's hyperplane. </li>
+ <li>A <em>ridge</em> is a set of <i>d-1</i> vertices, two
+ neighboring facets, and an orientation. For example in
+ 3-d, a ridge is a line segment. </li>
+ <li>A <em>non-simplicial facet</em> is a set of ridges, a
+ hyperplane equation, a centrum, an outer plane, and an
+ inner plane. The ridges determine a set of neighboring
+ facets, a set of vertices, and an orientation. Qhull
+ produces a non-simplicial facet when it merges two facets
+ together. For example, a cube has six non-simplicial
+ facets. </li>
+</ul>
+
+<p>For examples, use option '<a href="qh-opto.htm#f">f</a>'. See <a
+href="../src/libqhull/qh-poly.htm">polyhedron operations</a> for further
+design documentation. </p>
+
+</blockquote>
+<h3><a href="#TOC">&#187;</a>Imprecision in Qhull</h3>
+<blockquote>
+
+<p>See <a href="qh-impre.htm">Imprecision in Qhull</a> and <a href="qh-impre.htm#joggle">Merged facets or joggled input</a></p>
+
+</blockquote>
+<h3><a href="#TOC">&#187;</a>Examples of Qhull</h3>
+<blockquote>
+
+<p>See <a href="qh-eg.htm">Examples of Qhull</a>. Most of these examples require <a href="#geomview">Geomview</a>.
+Some of the examples have <a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/welcome.html">pictures
+</a>.</p>
+
+</blockquote>
+</blockquote>
+<h2><a href="#TOC">&#187;</a>Options for using Qhull </h2>
+<blockquote>
+
+<p>See <a href="qh-quick.htm#options">Options</a>.</p>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a>Qhull internals </h2>
+<blockquote>
+
+<p>See <a href="qh-code.htm">Internals</a>.</p>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a><a name="geomview">Geomview, Qhull's
+graphical viewer</a></h2>
+<blockquote>
+
+<p><a href="http://www.geomview.org">Geomview</a>
+is an interactive geometry viewing program.
+Geomview provides a good visualization of Qhull's 2-d and 3-d results.
+
+<p>Qhull includes <a href="qh-eg.htm">Examples of Qhull</a> that may be viewed with Geomview.
+
+<p>Geomview can help visulalize a 3-d Delaunay triangulation or the surface of a 4-d convex hull,
+Use option '<a href="qh-optq.htm#QVn">QVn</a>' to select the 3-D facets adjacent to a vertex.
+
+<p>You may use Geomview to create movies that animate your objects (c.f., <a href="http://www.geomview.org/FAQ/answers.shtml#mpeg">How can I create a video animation?</a>).
+Geomview helped create the <a href="http://www.geom.uiuc.edu/video/">mathematical videos</a> "Not Knot", "Outside In", and "The Shape of Space" from the Geometry Center.
+
+
+<h3><a href="#TOC">&#187;</a><a name="geomview-install">Installing Geomview</a></h3>
+<blockquote>
+
+<p>Geomview is an <a href=http://sourceforge.net/projects/geomview>open source project</a>
+under SourceForge.
+
+<p>
+For build instructions see
+<a href="http://www.geomview.org/download/">Downloading Geomview</a>.
+Geomview builds under Linux, Unix, Macintosh OS X, and Windows.
+
+<p>Geomview has <a href="https://packages.debian.org/search?keywords=geomview">installable packages</a> for Debian and Ubuntu.
+The OS X build needs Xcode, an X11 SDK, and Lesstif or Motif.
+The Windows build uses Cygwin (see <a href="#geomview-win">Building Geomview</a> below for instructions).
+
+<p>If using Xforms (e.g., for Geomview's <a href="http://www.geomview.org/docs/html/Modules.html">External Modules</a>), install the 'libXpm-devel' package from cygwin and move the xforms directory into your geomview directory, e.g.,<br><tt>mv xforms-1.2.4 geomview-1.9.5/xforms</tt>
+
+<p>Geomview's <a href="http://www.geom.uiuc.edu/software/geomview/docs/NDview/manpagehelp.html">ndview<a/> provides multiple views into 4-d and higher objects.
+This module is out-of-date (<a href="http://sourceforge.net/p/geomview/mailman/message/2004152/">geomview-users: 4dview</a>).
+Download NDview-sgi.tar.Z at <a href="ftp://www.geom.uiuc.edu/pub/software/geomview/newpieces/sgi">newpieces</a> and 4dview at <a href="https://stuff.mit.edu/afs/sipb/project/3d/arch/sgi_62/lib/Geomview/modules/">Geomview/modules</a>.
+
+</blockquote>
+<h3><a href="#TOC">&#187;</a><a name="geomview-use">Using Geomview</a></h3>
+<blockquote>
+
+<p>Use Geomview to view <a href="qh-eg.htm">Examples of Qhull</a>. You can spin the convex hull, fly a camera through its facets,
+and see how Qhull produces thick facets in response to round-off error.
+
+<p>Follow these instructions to view 'eg,01.cube' from Examples of Qhull
+<ol>
+<li>Launch an XTerm command shell
+<ul>
+<li>If needed, start the X terminal server, Use 'xinit' or 'startx' in /usr/X11R6/bin<br><tt>xinit -- -multiwindow -clipboard</tt><br><tt>startx</tt>
+<li>Start an XTerm command shell. In Windows, click the Cygwin/bash icon on your desktop.
+<li>Set the DISPLAY variable, e.g.,<br><tt>export DISPLAY=:0</tt><br><tt>export DISPLAY=:0 >>~/.bashenv</tt>
+</ul>
+<li>Use Qhull's <a href="qh-optg.htm">Geomview options</a> to create a geomview object
+<ul>
+<li><tt>rbox c D3 | qconvex G >eg.01.cube</tt>
+<li>On windows, convert the output to Unix text format with 'd2u'<br><tt>rbox c D3 | qconvex G | d2u >eg.01.cube</tt><br><tt>d2u eg.*</tt>
+</ul>
+<li>Run Geomview
+<ul>
+<li>Start Geomview with your example<br><tt>./geomview eg.01.cube</tt>
+<li>Follow the instructions in <a href="http://www.geomview.org/docs/html/Tutorial.html">Gemoview Tutorial</a>
+<li>Geomview creates the <i>Geomview control panel</i> with Targets and External Module, the <i>Geomview toolbar</i> with buttons for controlling Geomview, and the <i>Geomview camera window</i> showing a cube.
+<li>Clear the camera window by selecting your object in the Targets list and 'Edit > Delete' or 'dd'
+<li>Load the <i>Geomview files panel</i>. Select 'Open' in the 'File' menu.
+<li>Set 'Filter' in the files panel to your example directory followed by '/*' (e.g., '/usr/local/qhull-2015.2/eg/*')
+<li>Click 'Filter' in the files panel to view your examples in the 'Files' list.
+<li>Load another example into the camera window by selecting it and clicking 'OK'.
+<li>Review the instructions for <a href="http://www.geomview.org/docs/html/Interaction.html">Interacting with Geomview</a>
+<li>When viewing multiple objects at once, you may want to turn off normalization. In the 'Inspect > Apperance' control panel, set 'Normalize' to 'None'.
+</ul>
+</ol>
+
+<p>Geomview defines GCL (a textual API for controlling Geomview) and OOGL (a textual file format for defining objects).
+<ul>
+<li>To control Geomview, you may use any program that reads and writes from stdin and stdout. For example, it could report Qhull's information about a vertex identified by a double-click 'pick' event.
+<li><a href="http://www.geomview.org/docs/html/GCL.html">GCL</a> command language for controlling Geomview
+<li><a href="http://www.geomview.org/docs/html/OOGL-File-Formats.html">OOGL</a> file format for defining objects (<a href="http://www.geomview.org/docs/oogltour.html">tutorial</a>).
+<li><a href="http://www.geomview.org/docs/html/Modules.html">External Modules</a> for interacting with Geomview via GCL
+<li>Interact with your objects via <a href="http://www.geomview.org/docs/html/pick.html">pick</a> commands in response to right-mouse double clicks. Enable pick events with the <a href="http://www.geomview.org/docs/html/interest.html">interest</a> command.
+</ul>
+
+</blockquote>
+<h3><a href="#TOC">&#187;</a><a name="geomview-win">Building Geomview for Windows</a></h3>
+<blockquote>
+
+<p>Compile Geomview under Cygwin. For detailed instructions, see
+<a href="http://www.ee.surrey.ac.uk/Personal/L.Wood/software/SaVi/building-under-Windows/"
+>Building Savi and Geomview under Windows</a>. These instructions are somewhat out-of-date. Updated
+instructions follow.
+
+<p>How to compile Geomview under 32-bit Cygwin (October 2015)</p>
+<ol>
+<li><b>Note:</b> L. Wood has run into multiple issues with Geomview on Cygwin. He recommends Virtualbox/Ubuntu
+and a one-click install of geomview via the Ubuntu package. See his Savi/Geomview link above.
+<li>Install 32-bit <a href="http://cygwin.com/">Cygwin</a> as follows.
+For additional guidance, see Cygwin's <a href="https://cygwin.com/install.html">Installing and Updating Cygwin Packages</a>
+and <a href="http://www.qhull.org/road/road-faq/xml/cmdline.xml#setup-cygwin">Setup cygwin</a>.
+<ul>
+<li>Launch the cygwin installer.
+<li>Select a mirror from <a href="http://cygwin.com/mirrors.html">Cygwin mirrors</a> (e.g., http://mirrors.kernel.org/sourceware/cygwin/ in California).
+<li>Select the packages to install. Besides the cygwin packages listed in the Savi/Windows instructions consider adding
+<ul>
+<li><b>Default</b> -- libXm-devel (required for /usr/include/Xm/Xm.h)
+<li><b>Devel</b> -- bashdb, gcc-core (in place of gcc), gdb
+<li><b>Lib</b> -- libGL-devel, libGLU1 (required, obsolete), libGLU-devel (required, obsolete), libjpeg-devel(XForms), libXext-devel (required), libXpm-devel (Xforms)
+libGL and lib
+<li><b>Math</b> -- bc
+<li><b>Net</b> -- autossh, inetutils, openssh
+<li><b>System</b> -- chere
+<li><b>Utils</b> -- dos2unix (required for qhull), keychain
+<li>If installing perl, ActiveState Perl may be a better choice than cygwin's perl. Perl is not used by Geomview or Qhull.
+<li><a href="https://cygwin.com/cgi-bin2/package-grep.cgi">Cygwin Package Search</a> -- Search for cygwin programs and packages
+</ul>
+<li>Click 'Next' to download and install the packages.
+<li>If the download is incomplete, try again.
+<li>If you try again after a successful install, cygwin will uninstall and reinstall all modules..
+<li>Click on the 'Cywin Terminal' icon on the Desktop. It sets up a user directory in /home from /etc/skel/...
+<li>Mount your disk drives<br>mount c: /c # Ignore the warning /c does not exist
+</ul>
+<li>Consider installing the <a href="http://www.qhull.org/bash/doc/road-bash.html">Road Bash</a> scripts (/etc/road-*) from <a href="http://www.qhull.org/road/">Road</a>.
+They define aliases and functions for Unix command shells (Unix, Linux, Mac OS X, Windows),
+<ul>
+<li>Download Road Bash and unzip the downloaded file
+<li>Copy .../bash/etc/road-* to the Cywin /etc directory (by default, C:\cygwin\etc).
+<li>Using the cygwin terminal, convert the road scripts to Unix format<br>d2u /etc/road-*
+<li>Try it<br>source /etc/road-home.bashrc
+<li>Install it<br>cp /etc/road-home.bashrc ~/.bashrc
+</ul>
+<li>Launch the X terminal server from '<tt>Start > All programs > Cygwin-X > Xwin Server</tt>'. Alternatively, run 'startx'
+<li>Launch an XTerm shell
+<ul>
+<li>Right click the Cywin icon on the system tray in the Windows taskbar.
+<li>Select '<tt>System Tools > XTerm</tt>'
+</ul>
+<li>Download and extract Geomview -- <a href="http://www.geomview.org/download/">Downloading Geomview</a>
+<li>Compile Geomview
+<ul>
+<li>./configure
+<li>make
+</ul>
+<li>If './configure' fails, check 'config.log' at the failing step. Look carefully for missing libraries, etc. The <a href="http://www.geomview.org/FAQ/answers.shtml">Geomview FAQ</a> contains suggestions (e.g., "configure claims it can't find OpenGl").
+<li>If 'make' fails, read the output carefully for error messages. Usually it is a missing include file or package. Locate and install the missing cygwin packages
+(<a href="https://cygwin.com/cgi-bin2/package-grep.cgi">Cygwin Package Search</a>).
+</ol>
+
+</blockquote>
+</blockquote>
+<h2><a href="#TOC">&#187;</a><a name="bugs">What to do if something
+goes wrong</a></h2>
+<blockquote>
+
+<p>Please report bugs to <a href=mailto:qhull_bug@qhull.org>qhull_bug@qhull.org</a>
+</a>. Please report if Qhull crashes. Please report if Qhull
+generates an &quot;internal error&quot;. Please report if Qhull
+produces a poor approximate hull in 2-d, 3-d or 4-d. Please
+report documentation errors. Please report missing or incorrect
+links.</p>
+
+<p>If you do not understand something, try a small example. The <a
+href="rbox.htm">rbox</a> program is an easy way to generate
+test cases. The <a href="#geomview">Geomview</a> program helps to
+visualize the output from Qhull.</p>
+
+<p>If Qhull does not compile, it is due to an incompatibility
+between your system and ours. The first thing to check is that
+your compiler is ANSI standard. Qhull produces a compiler error
+if __STDC__ is not defined. You may need to set a flag (e.g.,
+'-A' or '-ansi').</p>
+
+<p>If Qhull compiles but crashes on the test case (rbox D4),
+there's still incompatibility between your system and ours.
+Sometimes it is due to memory management. This can be turned off
+with qh_NOmem in mem.h. Please let us know if you figure out how
+to fix these problems. </p>
+
+<p>If you doubt the output from Qhull, add option '<a
+href="qh-optt.htm#Tv">Tv</a>'. It checks that every point is
+inside the outer planes of the convex hull. It checks that every
+facet is convex with its neighbors. It checks the topology of the
+convex hull.</p>
+
+<p>Qhull should work on all inputs. It may report precision
+errors if you turn off merged facets with option '<a
+href="qh-optq.htm#Q0">Q0</a>'. This can get as bad as facets with
+flipped orientation or two facets with the same vertices. You'll
+get a long help message if you run into such a case. They are
+easy to generate with <tt>rbox</tt>.</p>
+
+<p>If you do find a problem, try to simplify it before reporting
+the error. Try different size inputs to locate the smallest one
+that causes an error. You're welcome to hunt through the code
+using the execution trace ('<a href="qh-optt.htm#Tn">T4</a>') as
+a guide. This is especially true if you're incorporating Qhull
+into your own program. </p>
+
+<p>When you report an error, please attach a data set to the end
+of your message. Include the options that you used with Qhull,
+the results of option '<a href="qh-optf.htm#FO">FO</a>', and any
+messages generated by Qhull. This allows me to see the error for
+myself. Qhull is maintained part-time. </p>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a><a name="email">Email</a></h2>
+<blockquote>
+
+<p>Please send correspondence to Brad Barber at <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+and report bugs to <a href=mailto:qhull_bug@qhull.org>qhull_bug@qhull.org</a>
+</a>. Let me know how you use Qhull. If you mention it in a
+paper, please send a reference and abstract.</p>
+
+<p>If you would like to get Qhull announcements (e.g., a new
+version) and news (any bugs that get fixed, etc.), let us know
+and we will add you to our mailing list. For Internet news about geometric algorithms
+and convex hulls, look at comp.graphics.algorithms and
+sci.math.num-analysis. For Qhull news look at <a
+href="http://www.qhull.org/news">qhull-news.html</a>.</p>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a><a name="authors">Authors</a></h2>
+<blockquote>
+
+<pre>
+ C. Bradford Barber Hannu Huhdanpaa
+ bradb@shore.net hannu@qhull.org
+</pre>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a><a name="acknowledge">Acknowledgments</a></h2>
+<blockquote>
+
+<p>A special thanks to David Dobkin for his guidance. A special
+thanks to Albert Marden, Victor Milenkovic, the Geometry Center,
+and Harvard University for supporting this work.</p>
+
+<p>A special thanks to Mark Phillips, Robert Miner, and Stuart Levy for running the Geometry
+ Center web site long after the Geometry Center closed.
+ Stuart moved the web site to the University of Illinois at Champaign-Urbana.
+Mark and Robert are founders of <a href=http://www.geomtech.com>Geometry Technologies</a>.
+Mark, Stuart, and Tamara Munzner are the original authors of <a href=http://www.geomview.org>Geomview</a>.
+
+<p>A special thanks to <a href="http://www.endocardial.com/">Endocardial
+Solutions, Inc.</a> of St. Paul, Minnesota for their support of the
+internal documentation (<a href=../src/libqhull/index.htm>src/libqhull/index.htm</a>). They use Qhull to build 3-d models of
+heart chambers.</p>
+
+<p>Qhull 1.0 and 2.0 were developed under National Science Foundation
+grants NSF/DMS-8920161 and NSF-CCR-91-15793 750-7504. If you find
+it useful, please let us know.</p>
+
+<p>The Geometry Center was supported by grant DMS-8920161 from the
+National Science Foundation, by grant DOE/DE-FG02-92ER25137 from
+the Department of Energy, by the University of Minnesota, and by
+Minnesota Technology, Inc.</p>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a><a name="ref">References</a></h2>
+<blockquote>
+
+<p><a name="aure91">Aurenhammer</a>, F., &quot;Voronoi diagrams
+-- A survey of a fundamental geometric data structure,&quot; <i>ACM
+Computing Surveys</i>, 1991, 23:345-405. </p>
+
+<p><a name="bar-dob96">Barber</a>, C. B., D.P. Dobkin, and H.T.
+Huhdanpaa, &quot;The Quickhull Algorithm for Convex Hulls,&quot; <i>ACM
+Transactions on Mathematical Software</i>, 22(4):469-483, Dec 1996, www.qhull.org
+[<a
+href="http://portal.acm.org/citation.cfm?doid=235815.235821">http://portal.acm.org</a>;
+<a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405">http://citeseerx.ist.psu.edu</a>].
+</p>
+
+<p><a name="cla-sho89">Clarkson</a>, K.L. and P.W. Shor,
+&quot;Applications of random sampling in computational geometry,
+II&quot;, <i>Discrete Computational Geometry</i>, 4:387-421, 1989</p>
+
+<p><a name="cla-meh93">Clarkson</a>, K.L., K. Mehlhorn, and R.
+Seidel, &quot;Four results on randomized incremental
+construction,&quot; <em>Computational Geometry: Theory and
+Applications</em>, vol. 3, p. 185-211, 1993.</p>
+
+<p><a name="devi01">Devillers</a>, et. al.,
+"Walking in a triangulation," <i>ACM Symposium on
+Computational Geometry</i>, June 3-5,2001, Medford MA.
+
+<p><a name="dob-kir90">Dobkin</a>, D.P. and D.G. Kirkpatrick,
+&quot;Determining the separation of preprocessed polyhedra--a
+unified approach,&quot; in <i>Proc. 17th Inter. Colloq. Automata
+Lang. Program.</i>, in <i>Lecture Notes in Computer Science</i>,
+Springer-Verlag, 443:400-413, 1990. </p>
+
+<p><a name="edel01">Edelsbrunner</a>, H, <i>Geometry and Topology for Mesh Generation</i>,
+Cambridge University Press, 2001.
+
+<p><a name=gart99>Gartner, B.</a>, "Fast and robust smallest enclosing balls", <i>Algorithms - ESA '99</i>, LNCS 1643.
+
+<p><a name=golub83>Golub, G.H. and van Loan, C.F.</a>, <i>Matric Computations</i>, Baltimore, Maryland, USA: John Hopkins Press, 1983
+
+<p><a name="fort93">Fortune, S.</a>, &quot;Computational
+geometry,&quot; in R. Martin, editor, <i>Directions in Geometric
+Computation</i>, Information Geometers, 47 Stockers Avenue,
+Winchester, SO22 5LB, UK, ISBN 1-874728-02-X, 1993.</p>
+
+<p><a name="mile93">Milenkovic, V.</a>, &quot;Robust polygon
+modeling,&quot; Computer-Aided Design, vol. 25, p. 546-566,
+September 1993. </p>
+
+<p><a name="muck96">Mucke</a>, E.P., I. Saias, B. Zhu, <i>Fast
+randomized point location without preprocessing in Two- and
+Three-dimensional Delaunay Triangulations</i>, ACM Symposium on
+Computational Geometry, p. 274-283, 1996 [<a
+href="http://www.geom.uiuc.edu/software/cglist/GeomDir/">GeomDir</a>].
+</p>
+
+<p><a name="mulm94">Mulmuley</a>, K., <i>Computational Geometry,
+An Introduction Through Randomized Algorithms</i>, Prentice-Hall,
+NJ, 1994.</p>
+
+<p><a name="orou94">O'Rourke</a>, J., <i>Computational Geometry
+in C</i>, Cambridge University Press, 1994.</p>
+
+<p><a name="pre-sha85">Preparata</a>, F. and M. Shamos, <i>Computational
+Geometry</i>, Springer-Verlag, New York, 1985.</p>
+
+</blockquote>
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b><a
+href="http://www.qhull.org/news">News</a> about Qhull<br>
+<b>Up:</b> <a href="http://www.qhull.org/html/qh-faq.htm">FAQ</a> about Qhull<br>
+<b>To:</b> <a href="#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>Dn:</b> <a href="qh-impre.htm">Imprecision in Qhull</a><br>
+<b>Dn:</b> <a href="qh-eg.htm">Description of Qhull examples</a><br>
+<b>Dn:</b> <a href="qh-code.htm">Qhull internals</a><br>
+<b>Dn:</b> <a href="../src/libqhull/index.htm">Qhull functions, macros, and data
+structures</a>
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/normal_voronoi_knauss_oesterle.jpg b/xs/src/qhull/html/normal_voronoi_knauss_oesterle.jpg
new file mode 100644
index 000000000..f46d42127
--- /dev/null
+++ b/xs/src/qhull/html/normal_voronoi_knauss_oesterle.jpg
Binary files differ
diff --git a/xs/src/qhull/html/qconvex.htm b/xs/src/qhull/html/qconvex.htm
new file mode 100644
index 000000000..38a363b08
--- /dev/null
+++ b/xs/src/qhull/html/qconvex.htm
@@ -0,0 +1,630 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>qconvex -- convex hull</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<a name="TOP"><b>Up</b></a><b>:</b>
+<a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a> -- Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/cone.html"><img
+src="qh--cone.gif" alt="[cone]" align="middle" width="100"
+height="100"></a>qconvex -- convex hull</h1>
+
+<p>The convex hull of a set of points is the smallest convex set
+containing the points. See the detailed introduction by O'Rourke
+[<a href="index.htm#orou94">'94</a>]. See <a
+href="index.htm#description">Description of Qhull</a> and <a
+href="qh-eg.htm#how">How Qhull adds a point</a>.</p>
+
+<blockquote>
+<dl>
+ <dt><b>Example:</b> rbox 10 D3 | qconvex <a
+ href="qh-opto.htm#s">s</a> <a href="qh-opto.htm#o">o</a> <a
+ href="qh-optt.htm#TO">TO result</a></dt>
+ <dd>Compute the 3-d convex hull of 10 random points. Write a
+ summary to the console and the points and facets to
+ 'result'.</dd>
+
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox c | qconvex <a
+ href="qh-opto.htm#n">n</a></dt>
+ <dd>Print the normals for each facet of a cube.</dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox c | qconvex <a
+ href="qh-opto.htm#i">i</a> <a href="qh-optq.htm#Qt">Qt</a></dt>
+ <dd>Print the triangulated facets of a cube.</dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox y 500 W0 | qconvex</dt>
+ <dd>Compute the convex hull of a simplex with 500
+ points on its surface.</dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox x W1e-12 1000 | qconvex
+ <a href="qh-optq.htm#QR">QR0</a></dt>
+ <dd>Compute the convex hull of 1000 points near the
+ surface of a randomly rotated simplex. Report
+ the maximum thickness of a facet.</dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox 1000 s | qconvex <a
+ href="qh-opto.htm#s">s</a> <a
+ href="qh-optf.htm#FA">FA</a> </dt>
+ <dd>Compute the convex hull of 1000 cospherical
+ points. Verify the results and print a summary
+ with the total area and volume.</dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox d D12 | qconvex <a
+ href="qh-optq.htm#QRn">QR0</a> <a
+ href="qh-optf.htm#FA">FA</a></dt>
+ <dd>Compute the convex hull of a 12-d diamond.
+ Randomly rotate the input. Note the large number
+ of facets and the small volume.</dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox c D7 | qconvex <a
+ href="qh-optf.htm#FA">FA</a> <a
+ href="qh-optt.htm#TFn">TF1000</a></dt>
+ <dd>Compute the convex hull of the 7-d hypercube.
+ Report on progress every 1000 facets. Computing
+ the convex hull of the 9-d hypercube takes too
+ much time and space. </dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox c d D2 | qconvex <a
+ href="qh-optq.htm#Qc">Qc</a> <a
+ href="qh-opto.htm#s">s</a> <a
+ href="qh-opto.htm#f">f</a> <a
+ href="qh-optf.htm#Fx">Fx</a> | more</dt>
+ <dd>Dump all fields of all facets for a square and a
+ diamond. Also print a summary and a list of
+ vertices. Note the coplanar points.</dd>
+ <dt>&nbsp;</dt>
+</dl>
+</blockquote>
+
+<p>Except for rbox, all of the qhull programs compute a convex hull.
+
+<p>By default, Qhull merges coplanar facets. For example, the convex
+hull of a cube's vertices has six facets.
+
+<p>If you use '<a href="qh-optq.htm#Qt">Qt</a>' (triangulated output),
+all facets will be simplicial (e.g., triangles in 2-d). For the cube
+example, it will have 12 facets. Some facets may be
+degenerate and have zero area.
+
+<p>If you use '<a href="qh-optq.htm#QJn">QJ</a>' (joggled input),
+all facets will be simplicial. The corresponding vertices will be
+slightly perturbed and identical points will be joggled apart.
+Joggled input is less accurate that triangulated
+output.See <a
+href="qh-impre.htm#joggle">Merged facets or joggled input</a>. </p>
+
+<p>The output for 4-d convex hulls may be confusing if the convex
+hull contains non-simplicial facets (e.g., a hypercube). See
+<a href=qh-faq.htm#extra>Why
+are there extra points in a 4-d or higher convex hull?</a><br>
+</p>
+</p>
+
+<p>The 'qconvex' program is equivalent to
+'<a href=qhull.htm#outputs>qhull</a>' in 2-d to 4-d, and
+'<a href=qhull.htm#outputs>qhull</a> <a href=qh-optq.htm#Qx>Qx</a>'
+in 5-d and higher. It disables the following Qhull
+<a href=qh-quick.htm#options>options</a>: <i>d v H Qbb Qf Qg Qm
+Qr Qu Qv Qx Qz TR E V Fp Gt Q0,etc</i>.
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<h3><a href="#TOP">&#187;</a><a name="synopsis">qconvex synopsis</a></h3>
+<pre>
+qconvex- compute the convex hull.
+ input (stdin): dimension, number of points, point coordinates
+ comments start with a non-numeric character
+
+options (qconvex.htm):
+ Qt - triangulated output
+ QJ - joggle input instead of merging facets
+ Tv - verify result: structure, convexity, and point inclusion
+ . - concise list of all options
+ - - one-line description of all options
+
+output options (subset):
+ s - summary of results (default)
+ i - vertices incident to each facet
+ n - normals with offsets
+ p - vertex coordinates (includes coplanar points if 'Qc')
+ Fx - extreme points (convex hull vertices)
+ FA - compute total area and volume
+ o - OFF format (dim, n, points, facets)
+ G - Geomview output (2-d, 3-d, and 4-d)
+ m - Mathematica output (2-d and 3-d)
+ QVn - print facets that include point n, -n if not
+ TO file- output results to file, may be enclosed in single quotes
+
+examples:
+ rbox c D2 | qconvex s n rbox c D2 | qconvex i
+ rbox c D2 | qconvex o rbox 1000 s | qconvex s Tv FA
+ rbox c d D2 | qconvex s Qc Fx rbox y 1000 W0 | qconvex s n
+ rbox y 1000 W0 | qconvex s QJ rbox d G1 D12 | qconvex QR0 FA Pp
+ rbox c D7 | qconvex FA TF1000
+</pre>
+
+<h3><a href="#TOP">&#187;</a><a name="input">qconvex
+input</a></h3>
+<blockquote>
+
+<p>The input data on <tt>stdin</tt> consists of:</p>
+<ul>
+ <li>dimension
+ <li>number of points</li>
+ <li>point coordinates</li>
+</ul>
+
+<p>Use I/O redirection (e.g., qconvex &lt; data.txt), a pipe (e.g., rbox 10 | qconvex),
+or the '<a href=qh-optt.htm#TI>TI</a>' option (e.g., qconvex TI data.txt).
+
+<p>Comments start with a non-numeric character. Error reporting is
+simpler if there is one point per line. Dimension
+and number of points may be reversed.
+
+<p>Here is the input for computing the convex
+hull of the unit cube. The output is the normals, one
+per facet.</p>
+
+<blockquote>
+ <p>rbox c &gt; data </p>
+ <pre>
+3 RBOX c
+8
+ -0.5 -0.5 -0.5
+ -0.5 -0.5 0.5
+ -0.5 0.5 -0.5
+ -0.5 0.5 0.5
+ 0.5 -0.5 -0.5
+ 0.5 -0.5 0.5
+ 0.5 0.5 -0.5
+ 0.5 0.5 0.5
+</pre>
+ <p>qconvex s n &lt; data</p>
+ <pre>
+
+Convex hull of 8 points in 3-d:
+
+ Number of vertices: 8
+ Number of facets: 6
+ Number of non-simplicial facets: 6
+
+Statistics for: RBOX c | QCONVEX s n
+
+ Number of points processed: 8
+ Number of hyperplanes created: 11
+ Number of distance tests for qhull: 35
+ Number of merged facets: 6
+ Number of distance tests for merging: 84
+ CPU seconds to compute hull (after input): 0.081
+
+4
+6
+ 0 0 -1 -0.5
+ 0 -1 0 -0.5
+ 1 0 0 -0.5
+ -1 0 0 -0.5
+ 0 1 0 -0.5
+ 0 0 1 -0.5
+</pre>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="outputs">qconvex outputs</a></h3>
+<blockquote>
+
+<p>These options control the output of qconvex. They may be used
+individually or together.</p>
+<blockquote>
+<dl compact>
+ <dt>&nbsp;</dt>
+ <dd><b>Vertices</b></dd>
+ <dt><a href="qh-optf.htm#Fx">Fx</a></dt>
+ <dd>list extreme points (i.e., vertices). The first line is the number of
+ extreme points. Each point is listed, one per line. The cube example
+ has eight vertices.</dd>
+ <dt><a href="qh-optf.htm#Fv">Fv</a></dt>
+ <dd>list vertices for each facet. The first line is the number of facets.
+ Each remaining line starts with the number of vertices. For the cube example,
+ each facet has four vertices.</dd>
+ <dt><a href="qh-opto.htm#i">i</a></dt>
+ <dd>list vertices for each facet. The first line is the number of facets. The
+ remaining lines list the vertices for each facet. In 4-d and
+ higher, triangulate non-simplicial facets by adding an extra point.</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Coordinates</b></dd>
+ <dt><a href="qh-opto.htm#o">o</a></dt>
+ <dd>print vertices and facets of the convex hull in OFF format. The
+ first line is the dimension. The second line is the number of
+ vertices, facets, and ridges. The vertex
+ coordinates are next, followed by the facets. Each facet starts with
+ the number of vertices. The cube example has four vertices per facet.</dd>
+ <dt><a href="qh-optf.htm#Ft">Ft</a></dt>
+ <dd>print a triangulation of the convex hull in OFF format. The first line
+ is the dimension. The second line is the number of vertices and added points,
+ followed by the number of facets and the number of ridges.
+ The vertex coordinates are next, followed by the centrum coordinates. There is
+ one centrum for each non-simplicial facet.
+ The cube example has six centrums, one per square.
+ Each facet starts with the number of vertices or centrums.
+ In the cube example, each facet uses two vertices and one centrum.</dd>
+ <dt><a href="qh-opto.htm#p">p</a></dt>
+ <dd>print vertex coordinates. The first line is the dimension and the second
+ line is the number of vertices. The following lines are the coordinates of each
+ vertex. The cube example has eight vertices.</dd>
+ <dt><a href="qh-optq.htm#Qc">Qc</a> <a href="qh-opto.htm#p">p</a></dt>
+ <dd>print coordinates of vertices and coplanar points. The first line is the dimension.
+ The second line is the number of vertices and coplanar points. The coordinates
+ are next, one line per point. Use '<a href="qh-optq.htm#Qc">Qc</a> <a href="qh-optq.htm#Qi">Qi</a> p'
+ to print the coordinates of all points.</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Facets</b></dd>
+ <dt><a href="qh-optf.htm#Fn">Fn</a></dt>
+ <dd>list neighboring facets for each facet. The first line is the
+ number of facets. Each remaining line starts with the number of
+ neighboring facets. The cube example has four neighbors per facet.</dd>
+ <dt><a href="qh-optf.htm#FN">FN</a></dt>
+ <dd>list neighboring facets for each point. The first line is the
+ total number of points. Each remaining line starts with the number of
+ neighboring facets. Each vertex of the cube example has three neighboring
+ facets. Use '<a href="qh-optq.htm#Qc">Qc</a> <a href="qh-optq.htm#Qi">Qi</a> FN'
+ to include coplanar and interior points. </dd>
+ <dt><a href="qh-optf.htm#Fa">Fa</a></dt>
+ <dd>print area for each facet. The first line is the number of facets.
+ Facet area follows, one line per facet. For the cube example, each facet has area one.</dd>
+ <dt><a href="qh-optf.htm#FI">FI</a></dt>
+ <dd>list facet IDs. The first line is the number of
+ facets. The IDs follow, one per line.</dd>
+
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Coplanar and interior points</b></dd>
+ <dt><a href="qh-optf.htm#Fc">Fc</a></dt>
+ <dd>list coplanar points for each facet. The first line is the number
+ of facets. The remaining lines start with the number of coplanar points.
+ A coplanar point is assigned to one facet.</dd>
+ <dt><a href="qh-optq.htm#Qi">Qi</a> <a href="qh-optf.htm#Fc">Fc</a></dt>
+ <dd>list interior points for each facet. The first line is the number
+ of facets. The remaining lines start with the number of interior points.
+ A coplanar point is assigned to one facet.</dd>
+ <dt><a href="qh-optf.htm#FP">FP</a></dt>
+ <dd>print distance to nearest vertex for coplanar points. The first line is the
+ number of coplanar points. Each remaining line starts with the point ID of
+ a vertex, followed by the point ID of a coplanar point, its facet, and distance.
+ Use '<a href="qh-optq.htm#Qc">Qc</a> <a href="qh-optq.htm#Qi">Qi</a>
+ <a href="qh-optf.htm#FP">FP</a>' for coplanar and interior points.</dd>
+
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Hyperplanes</b></dd>
+ <dt><a href="qh-opto.htm#n">n</a></dt>
+ <dd>print hyperplane for each facet. The first line is the dimension. The
+ second line is the number of facets. Each remaining line is the hyperplane's
+ coefficients followed by its offset.</dd>
+ <dt><a href="qh-optf.htm#Fo">Fo</a></dt>
+ <dd>print outer plane for each facet. The output plane is above all points.
+ The first line is the dimension. The
+ second line is the number of facets. Each remaining line is the outer plane's
+ coefficients followed by its offset.</dd>
+ <dt><a href="qh-optf.htm#Fi">Fi</a></dt>
+ <dd>print inner plane for each facet. The inner plane of a facet is
+ below its vertices.
+ The first line is the dimension. The
+ second line is the number of facets. Each remaining line is the inner plane's
+ coefficients followed by its offset.</dd>
+
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a href="qh-opto.htm#s">s</a></dt>
+ <dd>print summary for the convex hull. Use '<a
+ href="qh-optf.htm#Fs">Fs</a>' and '<a
+ href="qh-optf.htm#FS">FS</a>' if you need numeric data.</dd>
+ <dt><a href="qh-optf.htm#FA">FA</a></dt>
+ <dd>compute total area and volume for '<a
+ href="qh-opto.htm#s">s</a>' and '<a href="qh-optf.htm#FS">FS</a>'</dd>
+ <dt><a href="qh-opto.htm#m">m</a></dt>
+ <dd>Mathematica output for the convex hull in 2-d or 3-d.</dd>
+ <dt><a href="qh-optf.htm#FM">FM</a></dt>
+ <dd>Maple output for the convex hull in 2-d or 3-d.</dd>
+ <dt><a href="qh-optg.htm#G">G</a></dt>
+ <dd>Geomview output for the convex hull in 2-d, 3-d, or 4-d.</dd>
+
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Scaling and rotation</b></dd>
+ <dt><a href="qh-optq.htm#Qbk">Qbk:n</a></dt>
+ <dd>scale k'th coordinate to lower bound.</dd>
+ <dt><a href="qh-optq.htm#QBk">QBk:n</a></dt>
+ <dd>scale k'th coordinate to upper bound.</dd>
+ <dt><a href="qh-optq.htm#QbB">QbB</a></dt>
+ <dd>scale input to unit cube centered at the origin.</dd>
+ <dt><a href="qh-optq.htm#QRn">QRn</a></dt>
+ <dd>randomly rotate the input with a random seed of n. If n=0, the
+ seed is the time. If n=-1, use time for the random seed, but do
+ not rotate the input.</dd>
+ <dt><a href="qh-optq.htm#Qb0">Qbk:0Bk:0</a></dt>
+ <dd>remove k'th coordinate from input. This computes the
+ convex hull in one lower dimension.</dd>
+</dl>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="controls">qconvex controls</a></h3>
+<blockquote>
+
+<p>These options provide additional control:</p>
+
+<blockquote>
+<dl compact>
+ <dt><a href="qh-optq.htm#Qt">Qt</a></dt>
+ <dd>triangulated output. Qhull triangulates non-simplicial facets. It may produce
+ degenerate facets of zero area.</dd>
+ <dt><a href="qh-optq.htm#QJn">QJ</a></dt>
+ <dd>joggle the input instead of merging facets. This guarantees simplicial facets
+ (e.g., triangles in 3-d). It is less accurate than triangulated output ('Qt').</dd>
+ <dt><a href="qh-optq.htm#Qc">Qc</a></dt>
+ <dd>keep coplanar points</dd>
+ <dt><a href="qh-optq.htm#Qi">Qi</a></dt>
+ <dd>keep interior points</dd>
+ <dt><a href="qh-opto.htm#f">f </a></dt>
+ <dd>facet dump. Print the data structure for each facet.</dd>
+ <dt><a href="qh-optq.htm#QVn">QVn</a></dt>
+ <dd>select facets containing point <em>n</em> as a vertex,</dd>
+ <dt><a href="qh-optq.htm#QGn">QGn</a></dt>
+ <dd>select facets that are visible from point <em>n</em>
+ (marked 'good'). Use <em>-n</em> for the remainder.</dd>
+ <dt><a href="qh-optp.htm#PDk">PDk:0</a></dt>
+ <dd>select facets with a negative coordinate for dimension <i>k</i></dd>
+ <dt><a href="qh-optt.htm#TFn">TFn</a></dt>
+ <dd>report progress after constructing <em>n</em> facets</dd>
+ <dt><a href="qh-optt.htm#Tv">Tv</a></dt>
+ <dd>verify result</dd>
+ <dt><a href="qh-optt.htm#TO">TI file</a></dt>
+ <dd>input data from file. The filename may not use spaces or quotes.</dd>
+ <dt><a href="qh-optt.htm#TO">TO file</a></dt>
+ <dd>output results to file. Use single quotes if the filename
+ contains spaces (e.g., <tt>TO 'file with spaces.txt'</tt></dd>
+ <dt><a href="qh-optq.htm#Qs">Qs</a></dt>
+ <dd>search all points for the initial simplex. If Qhull can
+ not construct an initial simplex, it reports a
+descriptive message. Usually, the point set is degenerate and one
+or more dimensions should be removed ('<a href="qh-optq.htm#Qb0">Qbk:0Bk:0</a>').
+If not, use option 'Qs'. It performs an exhaustive search for the
+best initial simplex. This is expensive is high dimensions.</dd>
+</dl>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="graphics">qconvex graphics</a></h3>
+<blockquote>
+
+<p>Display 2-d, 3-d, and 4-d convex hulls with Geomview ('<a
+href="qh-optg.htm#G">G</a>').</p>
+
+<p>Display 2-d and 3-d convex hulls with Mathematica ('<a
+href="qh-opto.htm#m">m</a>').</p>
+
+<p>To view 4-d convex hulls in 3-d, use '<a
+href="qh-optp.htm#Pdk">Pd0d1d2d3</a>' to select the positive
+octant and '<a href="qh-optg.htm#GDn">GrD2</a>' to drop dimension
+2. </p>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="notes">qconvex notes</a></h3>
+<blockquote>
+
+<p>Qhull always computes a convex hull. The
+convex hull may be used for other geometric structures. The
+general technique is to transform the structure into an
+equivalent convex hull problem. For example, the Delaunay
+triangulation is equivalent to the convex hull of the input sites
+after lifting the points to a paraboloid.</p>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="conventions">qconvex
+conventions</a></h3>
+<blockquote>
+
+<p>The following terminology is used for convex hulls in Qhull.
+See <a href="index.htm#structure">Qhull's data structures</a>.</p>
+
+<ul>
+ <li><em>point</em> - <em>d</em> coordinates</li>
+ <li><em>vertex</em> - extreme point of the input set</li>
+ <li><em>ridge</em> - <i>d-1</i> vertices between two
+ neighboring facets</li>
+ <li><em>hyperplane</em> - halfspace defined by a unit normal
+ and offset</li>
+ <li><em>coplanar point</em> - a nearly incident point to a
+ hyperplane</li>
+ <li><em>centrum</em> - a point on the hyperplane for testing
+ convexity</li>
+ <li><em>facet</em> - a facet with vertices, ridges, coplanar
+ points, neighboring facets, and hyperplane</li>
+ <li><em>simplicial facet</em> - a facet with <em>d</em>
+ vertices, <em>d</em> ridges, and <em>d</em> neighbors</li>
+ <li><em>non-simplicial facet</em> - a facet with more than <em>d</em>
+ vertices</li>
+ <li><em>good facet</em> - a facet selected by '<a
+ href="qh-optq.htm#QVn">QVn</a>', etc.</li>
+</ul>
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="options">qconvex options</a></h3>
+
+<pre>
+qconvex- compute the convex hull
+ http://www.qhull.org
+
+input (stdin):
+ first lines: dimension and number of points (or vice-versa).
+ other lines: point coordinates, best if one point per line
+ comments: start with a non-numeric character
+
+options:
+ Qt - triangulated output
+ QJ - joggle input instead of merging facets
+ Qc - keep coplanar points with nearest facet
+ Qi - keep interior points with nearest facet
+
+Qhull control options:
+ Qbk:n - scale coord k so that low bound is n
+ QBk:n - scale coord k so that upper bound is n (QBk is 0.5)
+ QbB - scale input to unit cube centered at the origin
+ Qbk:0Bk:0 - remove k-th coordinate from input
+ QJn - randomly joggle input in range [-n,n]
+ QRn - random rotation (n=seed, n=0 time, n=-1 time/no rotate)
+ Qs - search all points for the initial simplex
+ QGn - good facet if visible from point n, -n for not visible
+ QVn - good facet if it includes point n, -n if not
+
+Trace options:
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events
+ Tc - check frequently during execution
+ Ts - print statistics
+ Tv - verify result: structure, convexity, and point inclusion
+ Tz - send all output to stdout
+ TFn - report summary when n or more facets created
+ TI file - input data from file, no spaces or single quotes
+ TO file - output results to file, may be enclosed in single quotes
+ TPn - turn on tracing when point n added to hull
+ TMn - turn on tracing at merge n
+ TWn - trace merge facets when width > n
+ TVn - stop qhull after adding point n, -n for before (see TCn)
+ TCn - stop qhull after building cone for point n (see TVn)
+
+Precision options:
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge
+ Rn - randomly perturb computations by a factor of [1-n,1+n]
+ Un - max distance below plane for a new, coplanar point
+ Wn - min facet width for outside point (before roundoff)
+
+Output formats (may be combined; if none, produces a summary to stdout):
+ f - facet dump
+ G - Geomview output (see below)
+ i - vertices incident to each facet
+ m - Mathematica output (2-d and 3-d)
+ n - normals with offsets
+ o - OFF file format (dim, points and facets; Voronoi regions)
+ p - point coordinates
+ s - summary (stderr)
+
+More formats:
+ Fa - area for each facet
+ FA - compute total area and volume for option 's'
+ Fc - count plus coplanar points for each facet
+ use 'Qc' (default) for coplanar and 'Qi' for interior
+ FC - centrum for each facet
+ Fd - use cdd format for input (homogeneous with offset first)
+ FD - use cdd format for numeric output (offset first)
+ FF - facet dump without ridges
+ Fi - inner plane for each facet
+ FI - ID for each facet
+ Fm - merge count for each facet (511 max)
+ FM - Maple output (2-d and 3-d)
+ Fn - count plus neighboring facets for each facet
+ FN - count plus neighboring facets for each point
+ Fo - outer plane (or max_outside) for each facet
+ FO - options and precision constants
+ FP - nearest vertex for each coplanar point
+ FQ - command used for qconvex
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,
+ for output: #vertices, #facets,
+ #coplanar points, #non-simplicial facets
+ #real (2), max outer plane, min vertex
+ FS - sizes: #int (0)
+ #real(2) tot area, tot volume
+ Ft - triangulation with centrums for non-simplicial facets (OFF format)
+ Fv - count plus vertices for each facet
+ FV - average of vertices (a feasible point for 'H')
+ Fx - extreme points (in order for 2-d)
+
+Geomview output (2-d, 3-d, and 4-d)
+ Ga - all points as dots
+ Gp - coplanar points and vertices as radii
+ Gv - vertices as spheres
+ Gi - inner planes only
+ Gn - no planes
+ Go - outer planes only
+ Gc - centrums
+ Gh - hyperplane intersections
+ Gr - ridges
+ GDn - drop dimension n in 3-d and 4-d output
+
+Print options:
+ PAn - keep n largest facets by area
+ Pdk:n - drop facet if normal[k] &lt;= n (default 0.0)
+ PDk:n - drop facet if normal[k] >= n
+ Pg - print good facets (needs 'QGn' or 'QVn')
+ PFn - keep facets whose area is at least n
+ PG - print neighbors of good facets
+ PMn - keep n facets with most merges
+ Po - force output. If error, output neighborhood of facet
+ Pp - do not report precision problems
+
+ . - list of all options
+ - - one line descriptions of all options
+
+</pre>
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149;<a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qdelau_f.htm b/xs/src/qhull/html/qdelau_f.htm
new file mode 100644
index 000000000..d8981e16b
--- /dev/null
+++ b/xs/src/qhull/html/qdelau_f.htm
@@ -0,0 +1,416 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>qdelaunay Qu -- furthest-site Delaunay triangulation</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<a name="TOP"><b>Up</b></a><b>:</b>
+<a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html"><img
+src="qh--dt.gif" alt="[delaunay]" align="middle" width="100"
+height="100"></a>qdelaunay Qu -- furthest-site Delaunay triangulation</h1>
+
+<p>The furthest-site Delaunay triangulation corresponds to the upper facets of the <a href="qdelaun.htm">Delaunay construction</a>.
+Its vertices are the
+extreme points of the input sites.
+It is the dual of the <a
+href="qvoron_f.htm">furthest-site Voronoi diagram</a>.
+
+<blockquote>
+<dl>
+ <dt><b>Example:</b> rbox 10 D2 | qdelaunay <a
+ href="qh-optq.htm#Qu">Qu</a> <a
+ href="qh-optq.htm#Qt">Qt</a> <a href="qh-opto.htm#s">s</a>
+ <a href="qh-opto.htm#i">i</a> <a href="qh-optt.htm#TO">TO
+ result</a></dt>
+ <dd>Compute the 2-d, furthest-site Delaunay triangulation of 10 random
+ points. Triangulate the output.
+ Write a summary to the console and the regions to
+ 'result'.</dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox 10 D2 | qdelaunay <a
+ href="qh-optq.htm#Qu">Qu</a> <a
+ href="qh-optq.htm#QJn">QJ</a> <a href="qh-opto.htm#s">s</a>
+ <a href="qh-opto.htm#i">i</a> <a href="qh-optt.htm#TO">TO
+ result</a></dt>
+ <dd>Compute the 2-d, furthest-site Delaunay triangulation of 10 random
+ points. Joggle the input to guarantee triangular output.
+ Write a summary to the console and the regions to
+ 'result'.</dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox r y c G1 D2 | qdelaunay <a
+ href="qh-optq.htm#Qu">Qu</a> <a href="qh-opto.htm#s">s</a>
+ <a href="qh-optf.htm#Fv">Fv</a> <a href="qh-optt.htm#TO">TO
+ result</a></dt>
+ <dd>Compute the 2-d, furthest-site Delaunay triangulation of a triangle inside
+ a square.
+ Write a summary to the console and unoriented regions to 'result'.
+ Merge regions for cocircular input sites (e.g., the square).
+ The square is the only furthest-site
+ Delaunay region.</dd>
+</dl>
+</blockquote>
+
+<p>As with the Delaunay triangulation, Qhull computes the
+furthest-site Delaunay triangulation by lifting the input sites to a
+paraboloid. The lower facets correspond to the Delaunay
+triangulation while the upper facets correspond to the
+furthest-site triangulation. Neither triangulation includes
+&quot;vertical&quot; facets (i.e., facets whose last hyperplane
+coefficient is nearly zero). Vertical facets correspond to input
+sites that are coplanar to the convex hull of the input. An
+example is points on the boundary of a lattice.</p>
+
+<p>By default, qdelaunay merges cocircular and cospherical regions.
+For example, the furthest-site Delaunay triangulation of a square inside a diamond
+('rbox D2 c d G4 | qdelaunay Qu') consists of one region (the diamond).
+
+<p>If you use '<a href="qh-optq.htm#Qt">Qt</a>' (triangulated output),
+all furthest-site Delaunay regions will be simplicial (e.g., triangles in 2-d).
+Some regions may be
+degenerate and have zero area.
+
+<p>If you use '<a href="qh-optq.htm#QJn">QJ</a>' (joggled input), all furthest-site
+Delaunay regions
+will be simplicial (e.g., triangles in 2-d). Joggled input
+is less accurate than triangulated output ('Qt'). See <a
+href="qh-impre.htm#joggle">Merged facets or joggled input</a>. </p>
+
+<p>The output for 3-d, furthest-site Delaunay triangulations may be confusing if the
+input contains cospherical data. See the FAQ item
+<a href=qh-faq.htm#extra>Why
+are there extra points in a 4-d or higher convex hull?</a>
+Avoid these problems with triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>') or
+joggled input ('<a href="qh-optq.htm#QJn">QJ</a>').
+</p>
+
+<p>The 'qdelaunay' program is equivalent to
+'<a href=qhull.htm#outputs>qhull d</a> <a href=qh-optq.htm#Qbb>Qbb</a>' in 2-d to 3-d, and
+'<a href=qhull.htm#outputs>qhull d</a> <a href=qh-optq.htm#Qbb>Qbb</a> <a href=qh-optq.htm#Qx>Qx</a>'
+in 4-d and higher. It disables the following Qhull
+<a href=qh-quick.htm#options>options</a>: <i>d n v H U Qb QB Qc Qf Qg Qi
+Qm Qr QR Qv Qx TR E V FC Fi Fo Fp FV Q0,etc</i>.
+
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<h3><a href="#TOP">&#187;</a><a name="synopsis">furthest-site qdelaunay synopsis</a></h3>
+<blockquote>
+
+See <a href="qdelaun.htm#synopsis">qdelaunay synopsis</a>. The same
+program is used for both constructions. Use option '<a href="qh-optq.htm#Qu">Qu</a>'
+for furthest-site Delaunay triangulations.
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="input">furthest-site qdelaunay
+input</a></h3>
+
+<blockquote>
+<p>The input data on <tt>stdin</tt> consists of:</p>
+<ul>
+ <li>dimension
+ <li>number of points</li>
+ <li>point coordinates</li>
+</ul>
+
+<p>Use I/O redirection (e.g., qdelaunay Qu &lt; data.txt), a pipe (e.g., rbox 10 | qdelaunay Qu),
+or the '<a href=qh-optt.htm#TI>TI</a>' option (e.g., qdelaunay Qu TI data.txt).
+
+<p>For example, this is a square containing four random points.
+Its furthest-site Delaunay
+triangulation contains one square.
+<p>
+<blockquote>
+<tt>rbox c 4 D2 &gt; data</tt>
+<blockquote><pre>
+2 RBOX c 4 D2
+8
+-0.4999921736307369 -0.3684622117955817
+0.2556053225468894 -0.0413498678629751
+0.0327672376602583 -0.2810408135699488
+-0.452955383763607 0.17886471718444
+ -0.5 -0.5
+ -0.5 0.5
+ 0.5 -0.5
+ 0.5 0.5
+</pre></blockquote>
+
+<p><tt>qdelaunay Qu i &lt; data</tt>
+<blockquote><pre>
+
+Furthest-site Delaunay triangulation by the convex hull of 8 points in 3-d:
+
+ Number of input sites: 8
+ Number of Delaunay regions: 1
+ Number of non-simplicial Delaunay regions: 1
+
+Statistics for: RBOX c 4 D2 | QDELAUNAY s Qu i
+
+ Number of points processed: 8
+ Number of hyperplanes created: 20
+ Number of facets in hull: 11
+ Number of distance tests for qhull: 34
+ Number of merged facets: 1
+ Number of distance tests for merging: 107
+ CPU seconds to compute hull (after input): 0.02
+
+1
+7 6 4 5
+</pre></blockquote>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="outputs">furthest-site qdelaunay
+outputs</a></h3>
+<blockquote>
+
+<p>These options control the output of furthest-site Delaunay triangulations:</p>
+<blockquote>
+
+<dl compact>
+ <dd><b>furthest-site Delaunay regions</b></dd>
+ <dt><a href="qh-opto.htm#i">i</a></dt>
+ <dd>list input sites for each furthest-site Delaunay region. The first line is the number of regions. The
+ remaining lines list the input sites for each region. The regions are
+ oriented. In 3-d and
+ higher, report cospherical sites by adding extra points. For the points-in-square example,
+ the square is the only furthest-site Delaunay region.</dd>
+ <dt><a href="qh-optf.htm#Fv">Fv</a></dt>
+ <dd>list input sites for each furthest-site Delaunay region. The first line is the number of regions.
+ Each remaining line starts with the number of input sites. The regions
+ are unoriented. For the points-in-square example,
+ the square is the only furthest-site Delaunay region.</dd>
+ <dt><a href="qh-optf.htm#Ft">Ft</a></dt>
+ <dd>print a triangulation of the furthest-site Delaunay regions in OFF format. The first line
+ is the dimension. The second line is the number of input sites and added points,
+ followed by the number of simplices and the number of ridges.
+ The input coordinates are next, followed by the centrum coordinates. There is
+ one centrum for each non-simplicial furthest-site Delaunay region. Each remaining line starts
+ with dimension+1. The
+ simplices are oriented.
+ For the points-in-square example, the square has a centrum at the
+ origin. It splits the square into four triangular regions.</dd>
+ <dt><a href="qh-optf.htm#Fn">Fn</a></dt>
+ <dd>list neighboring regions for each furthest-site Delaunay region. The first line is the
+ number of regions. Each remaining line starts with the number of
+ neighboring regions. Negative indices (e.g., <em>-1</em>) indicate regions
+ outside of the furthest-site Delaunay triangulation.
+ For the points-in-square example, the four neighboring regions
+ are outside of the triangulation. They belong to the regular
+ Delaunay triangulation.</dd>
+ <dt><a href="qh-optf.htm#FN">FN</a></dt>
+ <dd>list the furthest-site Delaunay regions for each input site. The first line is the
+ total number of input sites. Each remaining line starts with the number of
+ furthest-site Delaunay regions. Negative indices (e.g., <em>-1</em>) indicate regions
+ outside of the furthest-site Delaunay triangulation.
+ For the points-in-square example, the four random points belong to no region
+ while the square's vertices belong to region <em>0</em> and three
+ regions outside of the furthest-site Delaunay triangulation.</dd>
+ <dt><a href="qh-optf.htm#Fa">Fa</a></dt>
+ <dd>print area for each furthest-site Delaunay region. The first line is the number of regions.
+ The areas follow, one line per region. For the points-in-square example, the
+ square has unit area. </dd>
+
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Input sites</b></dd>
+ <dt><a href="qh-optf.htm#Fx">Fx</a></dt>
+ <dd>list extreme points of the input sites. These points are vertices of the furthest-point
+ Delaunay triangulation. They are on the
+ boundary of the convex hull. The first line is the number of
+ extreme points. Each point is listed, one per line. The points-in-square example
+ has four extreme points.</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a href="qh-optf.htm#FA">FA</a></dt>
+ <dd>compute total area for '<a href="qh-opto.htm#s">s</a>'
+ and '<a href="qh-optf.htm#FS">FS</a>'. This is the
+ same as the area of the convex hull.</dd>
+ <dt><a href="qh-opto.htm#o">o</a></dt>
+ <dd>print upper facets of the corresponding convex hull (a
+ paraboloid)</dd>
+ <dt><a href="qh-opto.htm#m">m</a></dt>
+ <dd>Mathematica output for the upper facets of the paraboloid (2-d triangulations).</dd>
+ <dt><a href="qh-optf.htm#FM">FM</a></dt>
+ <dd>Maple output for the upper facets of the paraboloid (2-d triangulations).</dd>
+ <dt><a href="qh-optg.htm#G">G</a></dt>
+ <dd>Geomview output for the paraboloid (2-d or 3-d triangulations).</dd>
+ <dt><a href="qh-opto.htm#s">s</a></dt>
+ <dd>print summary for the furthest-site Delaunay triangulation. Use '<a
+ href="qh-optf.htm#Fs">Fs</a>' and '<a
+ href="qh-optf.htm#FS">FS</a>' for numeric data.</dd>
+</dl>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="controls">furthest-site qdelaunay
+controls</a></h3>
+<blockquote>
+
+<p>These options provide additional control:</p>
+<blockquote>
+
+<dl compact>
+ <dt><a href="qh-optq.htm#Qu">Qu</a></dt>
+ <dd>must be used for furthest-site Delaunay triangulation.</dd>
+ <dt><a href="qh-optq.htm#Qt">Qt</a></dt>
+ <dd>triangulated output. Qhull triangulates non-simplicial facets. It may produce
+ degenerate facets of zero area.</dd>
+ <dt><a href="qh-optq.htm#QJn">QJ</a></dt>
+ <dd>joggle the input to avoid cospherical and coincident
+ sites. It is less accurate than triangulated output ('Qt').</dd>
+ <dt><a href="qh-optq.htm#QVn">QVn</a></dt>
+ <dd>select facets adjacent to input site <em>n</em> (marked
+ 'good').</dd>
+ <dt><a href="qh-optt.htm#Tv">Tv</a></dt>
+ <dd>verify result.</dd>
+ <dt><a href="qh-optt.htm#TO">TI file</a></dt>
+ <dd>input data from file. The filename may not use spaces or quotes.</dd>
+ <dt><a href="qh-optt.htm#TO">TO file</a></dt>
+ <dd>output results to file. Use single quotes if the filename
+ contains spaces (e.g., <tt>TO 'file with spaces.txt'</tt></dd>
+ <dt><a href="qh-optt.htm#TFn">TFn</a></dt>
+ <dd>report progress after constructing <em>n</em> facets</dd>
+ <dt><a href="qh-optp.htm#PDk">PDk:1</a></dt>
+ <dd>include upper and lower facets in the output. Set <em>k</em>
+ to the last dimension (e.g., 'PD2:1' for 2-d inputs). </dd>
+ <dt><a href="qh-opto.htm#f">f</a></dt>
+ <dd>facet dump. Print the data structure for each facet (i.e., furthest-site Delaunay region).</dd>
+</dl>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="graphics">furthest-site qdelaunay
+graphics</a></h3>
+<blockquote>
+
+See <a href="qdelaun.htm#graphics">Delaunay graphics</a>.
+They are the same except for Mathematica and Maple output.
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="notes">furthest-site
+qdelaunay notes</a></h3>
+<blockquote>
+
+<p>The furthest-site Delaunay triangulation does not
+record coincident input sites. Use <tt>qdelaunay</tt> instead.
+
+<p><tt>qdelaunay Qu</tt> does not work for purely cocircular
+or cospherical points (e.g., rbox c | qdelaunay Qu). Instead,
+use <tt>qdelaunay Qz</tt> -- when all points are vertices of the convex
+hull of the input sites, the Delaunay triangulation is the same
+as the furthest-site Delaunay triangulation.
+
+<p>A non-simplicial, furthest-site Delaunay region indicates nearly cocircular or
+cospherical input sites. To avoid non-simplicial regions triangulate
+the output ('<a href="qh-optq.htm#Qt">Qt</a>') or joggle
+the input ('<a href="qh-optq.htm#QJn">QJ</a>'). Joggled input
+is less accurate than triangulated output.
+You may also triangulate
+non-simplicial regions with option '<a
+href="qh-optf.htm#Ft">Ft</a>'. It adds
+the centrum to non-simplicial regions. Alternatively, use an <a
+href="qh-impre.htm#exact">exact arithmetic code</a>.</p>
+
+<p>Furthest-site Delaunay triangulations do not include facets that are
+coplanar with the convex hull of the input sites. A facet is
+coplanar if the last coefficient of its normal is
+nearly zero (see <a href="../src/libqhull/user.h#ZEROdelaunay">qh_ZEROdelaunay</a>).
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="conventions">furthest-site qdelaunay conventions</a></h3>
+<blockquote>
+
+<p>The following terminology is used for furthest-site Delaunay
+triangulations in Qhull. The underlying structure is the upper
+facets of a convex hull in one higher dimension. See <a
+href="qconvex.htm#conventions">convex hull conventions</a>, <a
+href="qdelaun.htm#conventions">Delaunay conventions</a>,
+and <a href="index.htm#structure">Qhull's data structures</a></p>
+<blockquote>
+<ul>
+ <li><em>input site</em> - a point in the input (one dimension
+ lower than a point on the convex hull)</li>
+ <li><em>point</em> - <i>d+1</i> coordinates. The last
+ coordinate is the sum of the squares of the input site's
+ coordinates</li>
+ <li><em>vertex</em> - a point on the paraboloid. It
+ corresponds to a unique input site. </li>
+ <li><em>furthest-site Delaunay facet</em> - an upper facet of the
+ paraboloid. The last coefficient of its normal is
+ clearly positive.</li>
+ <li><em>furthest-site Delaunay region</em> - a furthest-site Delaunay
+ facet projected to the input sites</li>
+ <li><em>non-simplicial facet</em> - more than <em>d</em>
+ points are cocircular or cospherical</li>
+ <li><em>good facet</em> - a furthest-site Delaunay facet with optional
+ restrictions by '<a href="qh-optq.htm#QVn">QVn</a>', etc.</li>
+</ul>
+</blockquote>
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="options">furthest-site qdelaunay options</a></h3>
+<blockquote>
+
+See <a href="qdelaun.htm#options">qdelaunay options</a>. The same
+program is used for both constructions. Use option '<a href="qh-optq.htm#Qu">Qu</a>'
+for furthest-site Delaunay triangulations.
+
+</blockquote>
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qdelaun.htm b/xs/src/qhull/html/qdelaun.htm
new file mode 100644
index 000000000..a42223c66
--- /dev/null
+++ b/xs/src/qhull/html/qdelaun.htm
@@ -0,0 +1,628 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>qdelaunay -- Delaunay triangulation</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<a name="TOP"><b>Up</b></a><b>:</b>
+<a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html"><img
+src="qh--dt.gif" alt="[delaunay]" align="middle" width="100"
+height="100"></a>qdelaunay -- Delaunay triangulation</h1>
+
+<p>The Delaunay triangulation is the triangulation with empty
+circumspheres. It has many useful properties and applications.
+See the survey article by Aurenhammer [<a
+href="index.htm#aure91">'91</a>] and the detailed introduction
+by O'Rourke [<a href="index.htm#orou94">'94</a>]. </p>
+
+<blockquote>
+<dl>
+ <dt><b>Example:</b> rbox r y c G0.1 D2 | qdelaunay <a href="qh-opto.htm#s">s</a>
+ <a href="qh-optf.htm#Fv">Fv</a> <a href="qh-optt.htm#TO">TO
+ result</a></dt>
+ <dd>Compute the 2-d Delaunay triangulation of a triangle and
+ a small square.
+ Write a summary to the console and unoriented regions to 'result'.
+ Merge regions for cocircular input sites (i.e., the
+ square).</dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox r y c G0.1 D2 | qdelaunay <a href="qh-opto.htm#s">s</a>
+ <a href="qh-optf.htm#Fv">Fv</a> <a href="qh-optq.htm#Qt">Qt</a></dt>
+ <dd>Compute the 2-d Delaunay triangulation of a triangle and
+ a small square. Write a summary and unoriented
+ regions to the console. Produce triangulated output.</dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox 10 D2 | qdelaunay <a
+ href="qh-optq.htm#QJn">QJ</a> <a href="qh-opto.htm#s">s</a>
+ <a href="qh-opto.htm#i">i</a> <a href="qh-optt.htm#TO">TO
+ result</a></dt>
+ <dd>Compute the 2-d Delaunay triangulation of 10 random
+ points. Joggle the input to guarantee triangular output.
+ Write a summary to the console and the regions to
+ 'result'.</dd>
+</dl>
+</blockquote>
+
+<p>Qhull computes the Delaunay triangulation by computing a
+convex hull. It lifts the input sites to a paraboloid by adding
+the sum of the squares of the coordinates. It scales the height
+of the paraboloid to improve numeric precision ('<a href=qh-optq.htm#Qbb>Qbb</a>').
+It computes the convex
+hull of the lifted sites, and projects the lower convex hull to
+the input.
+
+<p>Each region of the Delaunay triangulation
+corresponds to a facet of the lower half of the convex hull.
+Facets of the upper half of the convex hull correspond to the <a
+href="qdelau_f.htm">furthest-site Delaunay triangulation</a>.
+See the examples, <a href="qh-eg.htm#delaunay">Delaunay and
+Voronoi diagrams</a>.</p>
+
+<p>See <a href="http://www.qhull.org/html/qh-faq.htm#TOC">Qhull FAQ</a> - Delaunay and
+Voronoi diagram questions.</p>
+
+<p>By default, qdelaunay merges cocircular and cospherical regions.
+For example, the Delaunay triangulation of a square inside a diamond
+('rbox D2 c d G4 | qdelaunay') contains one region for the square.
+
+<p>Use option '<a href="qh-optq.htm#Qz">Qz</a>' if the input is circular, cospherical, or
+nearly so. It improves precision by adding a point "at infinity," above the corresponding paraboloid.
+
+<p>If you use '<a href="qh-optq.htm#Qt">Qt</a>' (triangulated output),
+all Delaunay regions will be simplicial (e.g., triangles in 2-d).
+Some regions may be
+degenerate and have zero area. Triangulated output identifies coincident
+points.
+
+<p>If you use '<a href="qh-optq.htm#QJn">QJ</a>' (joggled input), all Delaunay regions
+will be simplicial (e.g., triangles in 2-d). Coincident points will
+create small regions since the points are joggled apart. Joggled input
+is less accurate than triangulated output ('Qt'). See <a
+href="qh-impre.htm#joggle">Merged facets or joggled input</a>. </p>
+
+<p>The output for 3-d Delaunay triangulations may be confusing if the
+input contains cospherical data. See the FAQ item
+<a href=qh-faq.htm#extra>Why
+are there extra points in a 4-d or higher convex hull?</a>
+Avoid these problems with triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>') or
+joggled input ('<a href="qh-optq.htm#QJn">QJ</a>').
+</p>
+
+<p>The 'qdelaunay' program is equivalent to
+'<a href=qhull.htm#outputs>qhull d</a> <a href=qh-optq.htm#Qbb>Qbb</a>' in 2-d to 3-d, and
+'<a href=qhull.htm#outputs>qhull d</a> <a href=qh-optq.htm#Qbb>Qbb</a> <a href=qh-optq.htm#Qx>Qx</a>'
+in 4-d and higher. It disables the following Qhull
+<a href=qh-quick.htm#options>options</a>: <i>d n v H U Qb QB Qc Qf Qg Qi
+Qm Qr QR Qv Qx TR E V FC Fi Fo Fp Ft FV Q0,etc</i>.
+
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<h3><a href="#TOP">&#187;</a><a name="synopsis">qdelaunay synopsis</a></h3>
+
+<pre>
+qdelaunay- compute the Delaunay triangulation.
+ input (stdin): dimension, number of points, point coordinates
+ comments start with a non-numeric character
+
+options (qdelaun.htm):
+ Qt - triangulated output
+ QJ - joggle input instead of merging facets
+ Qu - furthest-site Delaunay triangulation
+ Tv - verify result: structure, convexity, and in-circle test
+ . - concise list of all options
+ - - one-line description of all options
+
+output options (subset):
+ s - summary of results (default)
+ i - vertices incident to each Delaunay region
+ Fx - extreme points (vertices of the convex hull)
+ o - OFF format (shows the points lifted to a paraboloid)
+ G - Geomview output (2-d and 3-d points lifted to a paraboloid)
+ m - Mathematica output (2-d inputs lifted to a paraboloid)
+ QVn - print Delaunay regions that include point n, -n if not
+ TO file- output results to file, may be enclosed in single quotes
+
+examples:
+ rbox c P0 D2 | qdelaunay s o rbox c P0 D2 | qdelaunay i
+ rbox c P0 D3 | qdelaunay Fv Qt rbox c P0 D2 | qdelaunay s Qu Fv
+ rbox c G1 d D2 | qdelaunay s i rbox c G1 d D2 | qdelaunay s i Qt
+ rbox M3,4 z 100 D2 | qdelaunay s rbox M3,4 z 100 D2 | qdelaunay s Qt
+</pre>
+
+
+<h3><a href="#TOP">&#187;</a><a name="input">qdelaunay
+input</a></h3>
+
+<blockquote>
+<p>The input data on <tt>stdin</tt> consists of:</p>
+<ul>
+ <li>dimension
+ <li>number of points</li>
+ <li>point coordinates</li>
+</ul>
+
+<p>Use I/O redirection (e.g., qdelaunay &lt; data.txt), a pipe (e.g., rbox 10 | qdelaunay),
+or the '<a href=qh-optt.htm#TI>TI</a>' option (e.g., qdelaunay TI data.txt).
+
+<p>For example, this is four cocircular points inside a square. Its Delaunay
+triangulation contains 8 triangles and one four-sided
+figure.
+<p>
+<blockquote>
+<tt>rbox s 4 W0 c G1 D2 &gt; data</tt>
+<blockquote><pre>
+2 RBOX s 4 W0 c D2
+8
+-0.4941988586954018 -0.07594397977563715
+-0.06448037284989526 0.4958248496365813
+0.4911154367094632 0.09383830681375946
+-0.348353580869097 -0.3586778257652367
+ -1 -1
+ -1 1
+ 1 -1
+ 1 1
+</pre></blockquote>
+
+<p><tt>qdelaunay s i &lt; data</tt>
+<blockquote><pre>
+
+Delaunay triangulation by the convex hull of 8 points in 3-d
+
+ Number of input sites: 8
+ Number of Delaunay regions: 9
+ Number of non-simplicial Delaunay regions: 1
+
+Statistics for: RBOX s 4 W0 c D2 | QDELAUNAY s i
+
+ Number of points processed: 8
+ Number of hyperplanes created: 18
+ Number of facets in hull: 10
+ Number of distance tests for qhull: 33
+ Number of merged facets: 2
+ Number of distance tests for merging: 102
+ CPU seconds to compute hull (after input): 0.028
+
+9
+1 7 5
+6 3 4
+2 3 6
+7 2 6
+2 7 1
+0 5 4
+3 0 4
+0 1 5
+1 0 3 2
+</pre></blockquote>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="outputs">qdelaunay
+outputs</a></h3>
+<blockquote>
+
+<p>These options control the output of Delaunay triangulations:</p>
+<blockquote>
+
+<dl compact>
+ <dd><b>Delaunay regions</b></dd>
+ <dt><a href="qh-opto.htm#i">i</a></dt>
+ <dd>list input sites for each Delaunay region. The first line is the number of regions. The
+ remaining lines list the input sites for each region. The regions are
+ oriented. In 3-d and
+ higher, report cospherical sites by adding extra points. Use triangulated
+ output ('<a href="qh-optq.htm#Qt">Qt</a>') to avoid non-simpicial regions. For the circle-in-square example,
+ eight Delaunay regions are triangular and the ninth has four input sites.</dd>
+ <dt><a href="qh-optf.htm#Fv">Fv</a></dt>
+ <dd>list input sites for each Delaunay region. The first line is the number of regions.
+ Each remaining line starts with the number of input sites. The regions
+ are unoriented. For the circle-in-square example,
+ eight Delaunay regions are triangular and the ninth has four input sites.</dd>
+ <dt><a href="qh-optf.htm#Fn">Fn</a></dt>
+ <dd>list neighboring regions for each Delaunay region. The first line is the
+ number of regions. Each remaining line starts with the number of
+ neighboring regions. Negative indices (e.g., <em>-1</em>) indicate regions
+ outside of the Delaunay triangulation.
+ For the circle-in-square example, the four regions on the square are neighbors to
+ the region-at-infinity.</dd>
+ <dt><a href="qh-optf.htm#FN">FN</a></dt>
+ <dd>list the Delaunay regions for each input site. The first line is the
+ total number of input sites. Each remaining line starts with the number of
+ Delaunay regions. Negative indices (e.g., <em>-1</em>) indicate regions
+ outside of the Delaunay triangulation.
+ For the circle-in-square example, each point on the circle belongs to four
+ Delaunay regions. Use '<a href="qh-optq.htm#Qc">Qc</a> FN'
+ to include coincident input sites and deleted vertices. </dd>
+ <dt><a href="qh-optf.htm#Fa">Fa</a></dt>
+ <dd>print area for each Delaunay region. The first line is the number of regions.
+ The areas follow, one line per region. For the circle-in-square example, the
+ cocircular region has area 0.4. </dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Input sites</b></dd>
+ <dt><a href="qh-optf.htm#Fc">Fc</a></dt>
+ <dd>list coincident input sites for each Delaunay region.
+ The first line is the number of regions. The remaining lines start with
+ the number of coincident sites and deleted vertices. Deleted vertices
+ indicate highly degenerate input (see'<a href="qh-optf.htm#Fs">Fs</a>').
+ A coincident site is assigned to one Delaunay
+ region. Do not use '<a href="qh-optq.htm#QJn">QJ</a>' with 'Fc'; the joggle will separate
+ coincident sites.</dd>
+ <dt><a href="qh-optf.htm#FP">FP</a></dt>
+ <dd>print coincident input sites with distance to
+ nearest site (i.e., vertex). The first line is the
+ number of coincident sites. Each remaining line starts with the point ID of
+ an input site, followed by the point ID of a coincident point, its region, and distance.
+ Includes deleted vertices which
+ indicate highly degenerate input (see'<a href="qh-optf.htm#Fs">Fs</a>').
+ Do not use '<a href="qh-optq.htm#QJn">QJ</a>' with 'FP'; the joggle will separate
+ coincident sites.</dd>
+ <dt><a href="qh-optf.htm#Fx">Fx</a></dt>
+ <dd>list extreme points of the input sites. These points are on the
+ boundary of the convex hull. The first line is the number of
+ extreme points. Each point is listed, one per line. The circle-in-square example
+ has four extreme points.</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a href="qh-optf.htm#FA">FA</a></dt>
+ <dd>compute total area for '<a href="qh-opto.htm#s">s</a>'
+ and '<a href="qh-optf.htm#FS">FS</a>'</dd>
+ <dt><a href="qh-opto.htm#o">o</a></dt>
+ <dd>print lower facets of the corresponding convex hull (a
+ paraboloid)</dd>
+ <dt><a href="qh-opto.htm#m">m</a></dt>
+ <dd>Mathematica output for the lower facets of the paraboloid (2-d triangulations).</dd>
+ <dt><a href="qh-optf.htm#FM">FM</a></dt>
+ <dd>Maple output for the lower facets of the paraboloid (2-d triangulations).</dd>
+ <dt><a href="qh-optg.htm#G">G</a></dt>
+ <dd>Geomview output for the paraboloid (2-d or 3-d triangulations).</dd>
+ <dt><a href="qh-opto.htm#s">s</a></dt>
+ <dd>print summary for the Delaunay triangulation. Use '<a
+ href="qh-optf.htm#Fs">Fs</a>' and '<a
+ href="qh-optf.htm#FS">FS</a>' for numeric data.</dd>
+</dl>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="controls">qdelaunay
+controls</a></h3>
+<blockquote>
+
+<p>These options provide additional control:</p>
+<blockquote>
+
+<dl compact>
+ <dt><a href="qh-optq.htm#Qt">Qt</a></dt>
+ <dd>triangulated output. Qhull triangulates non-simplicial facets. It may produce
+degenerate facets of zero area.</dd>
+ <dt><a href="qh-optq.htm#QJn">QJ</a></dt>
+ <dd>joggle the input to avoid cospherical and coincident
+ sites. It is less accurate than triangulated output ('Qt').</dd>
+ <dt><a href="qh-optq.htm#Qu">Qu</a></dt>
+ <dd>compute the <a href="qdelau_f.htm">furthest-site Delaunay triangulation</a>.</dd>
+ <dt><a href="qh-optq.htm#Qz">Qz</a></dt>
+ <dd>add a point above the paraboloid to reduce precision
+ errors. Use it for nearly cocircular/cospherical input
+ (e.g., 'rbox c | qdelaunay Qz'). The point is printed for
+ options '<a href="qh-optf.htm#Ft">Ft</a>' and '<a
+ href="qh-opto.htm#o">o</a>'.</dd>
+ <dt><a href="qh-optq.htm#QVn">QVn</a></dt>
+ <dd>select facets adjacent to input site <em>n</em> (marked
+ 'good').</dd>
+ <dt><a href="qh-optt.htm#Tv">Tv</a></dt>
+ <dd>verify result.</dd>
+ <dt><a href="qh-optt.htm#TO">TI file</a></dt>
+ <dd>input data from file. The filename may not use spaces or quotes.</dd>
+ <dt><a href="qh-optt.htm#TO">TO file</a></dt>
+ <dd>output results to file. Use single quotes if the filename
+ contains spaces (e.g., <tt>TO 'file with spaces.txt'</tt></dd>
+ <dt><a href="qh-optt.htm#TFn">TFn</a></dt>
+ <dd>report progress after constructing <em>n</em> facets</dd>
+ <dt><a href="qh-optp.htm#PDk">PDk:1</a></dt>
+ <dd>include upper and lower facets in the output. Set <em>k</em>
+ to the last dimension (e.g., 'PD2:1' for 2-d inputs). </dd>
+ <dt><a href="qh-opto.htm#f">f</a></dt>
+ <dd>facet dump. Print the data structure for each facet (i.e., Delaunay region).</dd>
+</dl>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="graphics">qdelaunay
+graphics</a></h3>
+<blockquote>
+
+<p>For 2-d and 3-d Delaunay triangulations, Geomview ('qdelaunay <a
+href="qh-optg.htm#G">G</a>') displays the corresponding convex
+hull (a paraboloid). </p>
+
+<p>To view a 2-d Delaunay triangulation, use 'qdelaunay <a
+href="qh-optg.htm#GDn">GrD2</a>' to drop the last dimension. This
+is the same as viewing the hull without perspective (see
+Geomview's 'cameras' menu). </p>
+
+<p>To view a 3-d Delaunay triangulation, use 'qdelaunay <a
+href="qh-optg.htm#GDn">GrD3</a>' to drop the last dimension. You
+may see extra edges. These are interior edges that Geomview moves
+towards the viewer (see 'lines closer' in Geomview's camera
+options). Use option '<a href="qh-optg.htm#Gt">Gt</a>' to make
+the outer ridges transparent in 3-d. See <a
+href="qh-eg.htm#delaunay">Delaunay and Voronoi examples</a>.</p>
+
+<p>For 2-d Delaunay triangulations, Mathematica ('<a
+href="qh-opto.htm#m">m</a>') and Maple ('<a
+href="qh-optf.htm#FM">FM</a>') output displays the lower facets of the corresponding convex
+hull (a paraboloid). </p>
+
+<p>For 2-d, furthest-site Delaunay triangulations, Maple and Mathematica output ('<a
+href="qh-optq.htm#Qu">Qu</a> <a
+href="qh-opto.htm#m">m</a>') displays the upper facets of the corresponding convex
+hull (a paraboloid). </p>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="notes">qdelaunay
+notes</a></h3>
+<blockquote>
+
+<p>You can simplify the Delaunay triangulation by enclosing the input
+sites in a large square or cube. This is particularly recommended
+for cocircular or cospherical input data.
+
+<p>A non-simplicial Delaunay region indicates nearly cocircular or
+cospherical input sites. To avoid non-simplicial regions either triangulate
+the output ('<a href="qh-optq.htm#Qt">Qt</a>') or joggle
+the input ('<a href="qh-optq.htm#QJn">QJ</a>'). Triangulated output
+is more accurate than joggled input. Alternatively, use an <a
+href="qh-impre.htm#exact">exact arithmetic code</a>.</p>
+
+<p>Delaunay triangulations do not include facets that are
+coplanar with the convex hull of the input sites. A facet is
+coplanar if the last coefficient of its normal is
+nearly zero (see <a href="../src/libqhull/user.h#ZEROdelaunay">qh_ZEROdelaunay</a>).
+
+<p>See <a href=qh-impre.htm#delaunay>Imprecision issues :: Delaunay triangulations</a>
+for a discussion of precision issues. Deleted vertices indicate
+highly degenerate input. They are listed in the summary output and
+option '<a href="qh-optf.htm#Fs">Fs</a>'.</p>
+
+<p>To compute the Delaunay triangulation of points on a sphere,
+compute their convex hull. If the sphere is the unit sphere at
+the origin, the facet normals are the Voronoi vertices of the
+input. The points may be restricted to a hemisphere. [S. Fortune]
+</p>
+
+<p>The 3-d Delaunay triangulation of regular points on a half
+spiral (e.g., 'rbox 100 l | qdelaunay') has quadratic size, while the Delaunay triangulation
+of random 3-d points is
+approximately linear for reasonably sized point sets.
+
+<p>With the <a href="qh-code.htm#library">Qhull library</a>, you
+can use <tt>qh_findbestfacet</tt> in <tt>poly2.c</tt> to locate the facet
+that contains a point. You should first lift the point to the
+paraboloid (i.e., the last coordinate is the sum of the squares
+of the point's coordinates -- <tt>qh_setdelaunay</tt>). Do not use options
+'<a href="qh-optq.htm#Qbb">Qbb</a>', '<a href="qh-optq.htm#QbB">QbB</a>',
+'<a href="qh-optq.htm#Qbk">Qbk:n</a>', or '<a
+href="qh-optq.htm#QBk">QBk:n</a>' since these scale the last
+coordinate. </p>
+
+<p>If a point is interior to the convex hull of the input set, it
+is interior to the adjacent vertices of the Delaunay
+triangulation. This is demonstrated by the following pipe for
+point 0:
+
+<pre>
+ qdelaunay &lt;data s FQ QV0 p | qconvex s Qb3:0B3:0 p
+</pre>
+
+<p>The first call to qdelaunay returns the neighboring points of
+point 0 in the Delaunay triangulation. The second call to qconvex
+returns the vertices of the convex hull of these points (after
+dropping the lifted coordinate). If point 0 is interior to the
+original point set, it is interior to the reduced point set. </p>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="conventions">qdelaunay conventions</a></h3>
+<blockquote>
+
+<p>The following terminology is used for Delaunay triangulations
+in Qhull for dimension <i>d</i>. The underlying structure is the
+lower facets of a convex hull in dimension <i>d+1</i>. For
+further information, see <a href="index.htm#structure">data
+structures</a> and <a href="qconvex.htm#conventions">convex hull
+conventions</a>.</p>
+<blockquote>
+<ul>
+ <li><em>input site</em> - a point in the input (one dimension
+ lower than a point on the convex hull)</li>
+ <li><em>point</em> - a point has <i>d+1</i> coordinates. The
+ last coordinate is the sum of the squares of the input
+ site's coordinates</li>
+ <li><em>coplanar point</em> - a <em>coincident</em>
+ input site or a deleted vertex. Deleted vertices
+ indicate highly degenerate input.</li>
+ <li><em>vertex</em> - a point on the paraboloid. It
+ corresponds to a unique input site. </li>
+ <li><em>point-at-infinity</em> - a point added above the
+ paraboloid by option '<a href="qh-optq.htm#Qz">Qz</a>'</li>
+ <li><em>lower facet</em> - a facet corresponding to a
+ Delaunay region. The last coefficient of its normal is
+ clearly negative.</li>
+ <li><em>upper facet</em> - a facet corresponding to a
+ furthest-site Delaunay region. The last coefficient of
+ its normal is clearly positive. </li>
+ <li><em>Delaunay region</em> - a
+ lower facet projected to the input sites</li>
+ <li><em>upper Delaunay region</em> - an upper facet projected
+ to the input sites</li>
+ <li><em>non-simplicial facet</em> - more than <em>d</em>
+ input sites are cocircular or cospherical</li>
+ <li><em>good facet</em> - a Delaunay region with optional
+ restrictions by '<a href="qh-optq.htm#QVn">QVn</a>', etc.</li>
+</ul>
+</blockquote>
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="options">qdelaunay options</a></h3>
+
+<pre>
+qdelaunay- compute the Delaunay triangulation
+ http://www.qhull.org
+
+input (stdin):
+ first lines: dimension and number of points (or vice-versa).
+ other lines: point coordinates, best if one point per line
+ comments: start with a non-numeric character
+
+options:
+ Qt - triangulated output
+ QJ - joggle input instead of merging facets
+ Qu - compute furthest-site Delaunay triangulation
+
+Qhull control options:
+ QJn - randomly joggle input in range [-n,n]
+ Qs - search all points for the initial simplex
+ Qz - add point-at-infinity to Delaunay triangulation
+ QGn - print Delaunay region if visible from point n, -n if not
+ QVn - print Delaunay regions that include point n, -n if not
+
+Trace options:
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events
+ Tc - check frequently during execution
+ Ts - print statistics
+ Tv - verify result: structure, convexity, and in-circle test
+ Tz - send all output to stdout
+ TFn - report summary when n or more facets created
+ TI file - input data from file, no spaces or single quotes
+ TO file - output results to file, may be enclosed in single quotes
+ TPn - turn on tracing when point n added to hull
+ TMn - turn on tracing at merge n
+ TWn - trace merge facets when width > n
+ TVn - stop qhull after adding point n, -n for before (see TCn)
+ TCn - stop qhull after building cone for point n (see TVn)
+
+Precision options:
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge
+ Rn - randomly perturb computations by a factor of [1-n,1+n]
+ Wn - min facet width for outside point (before roundoff)
+
+Output formats (may be combined; if none, produces a summary to stdout):
+ f - facet dump
+ G - Geomview output (see below)
+ i - vertices incident to each Delaunay region
+ m - Mathematica output (2-d only, lifted to a paraboloid)
+ o - OFF format (dim, points, and facets as a paraboloid)
+ p - point coordinates (lifted to a paraboloid)
+ s - summary (stderr)
+
+More formats:
+ Fa - area for each Delaunay region
+ FA - compute total area for option 's'
+ Fc - count plus coincident points for each Delaunay region
+ Fd - use cdd format for input (homogeneous with offset first)
+ FD - use cdd format for numeric output (offset first)
+ FF - facet dump without ridges
+ FI - ID of each Delaunay region
+ Fm - merge count for each Delaunay region (511 max)
+ FM - Maple output (2-d only, lifted to a paraboloid)
+ Fn - count plus neighboring region for each Delaunay region
+ FN - count plus neighboring region for each point
+ FO - options and precision constants
+ FP - nearest point and distance for each coincident point
+ FQ - command used for qdelaunay
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,
+ for output: #vertices, #Delaunay regions,
+ #coincident points, #non-simplicial regions
+ #real (2), max outer plane, min vertex
+ FS - sizes: #int (0)
+ #real (2), tot area, 0
+ Fv - count plus vertices for each Delaunay region
+ Fx - extreme points of Delaunay triangulation (on convex hull)
+
+Geomview options (2-d and 3-d)
+ Ga - all points as dots
+ Gp - coplanar points and vertices as radii
+ Gv - vertices as spheres
+ Gi - inner planes only
+ Gn - no planes
+ Go - outer planes only
+ Gc - centrums
+ Gh - hyperplane intersections
+ Gr - ridges
+ GDn - drop dimension n in 3-d and 4-d output
+ Gt - transparent outer ridges to view 3-d Delaunay
+
+Print options:
+ PAn - keep n largest Delaunay regions by area
+ Pdk:n - drop facet if normal[k] &lt;= n (default 0.0)
+ PDk:n - drop facet if normal[k] >= n
+ Pg - print good Delaunay regions (needs 'QGn' or 'QVn')
+ PFn - keep Delaunay regions whose area is at least n
+ PG - print neighbors of good regions (needs 'QGn' or 'QVn')
+ PMn - keep n Delaunay regions with most merges
+ Po - force output. If error, output neighborhood of facet
+ Pp - do not report precision problems
+
+ . - list of all options
+ - - one line descriptions of all options
+</pre>
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh--4d.gif b/xs/src/qhull/html/qh--4d.gif
new file mode 100644
index 000000000..08be18c8a
--- /dev/null
+++ b/xs/src/qhull/html/qh--4d.gif
Binary files differ
diff --git a/xs/src/qhull/html/qh--cone.gif b/xs/src/qhull/html/qh--cone.gif
new file mode 100644
index 000000000..78470ee8f
--- /dev/null
+++ b/xs/src/qhull/html/qh--cone.gif
Binary files differ
diff --git a/xs/src/qhull/html/qh--dt.gif b/xs/src/qhull/html/qh--dt.gif
new file mode 100644
index 000000000..b6d4e2672
--- /dev/null
+++ b/xs/src/qhull/html/qh--dt.gif
Binary files differ
diff --git a/xs/src/qhull/html/qh--geom.gif b/xs/src/qhull/html/qh--geom.gif
new file mode 100644
index 000000000..9c70b5499
--- /dev/null
+++ b/xs/src/qhull/html/qh--geom.gif
Binary files differ
diff --git a/xs/src/qhull/html/qh--half.gif b/xs/src/qhull/html/qh--half.gif
new file mode 100644
index 000000000..80a4d0883
--- /dev/null
+++ b/xs/src/qhull/html/qh--half.gif
Binary files differ
diff --git a/xs/src/qhull/html/qh--rand.gif b/xs/src/qhull/html/qh--rand.gif
new file mode 100644
index 000000000..4d4e4daee
--- /dev/null
+++ b/xs/src/qhull/html/qh--rand.gif
Binary files differ
diff --git a/xs/src/qhull/html/qh-code.htm b/xs/src/qhull/html/qh-code.htm
new file mode 100644
index 000000000..fff7faddb
--- /dev/null
+++ b/xs/src/qhull/html/qh-code.htm
@@ -0,0 +1,1062 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Qhull code</title>
+<!-- Navigation links -->
+</head>
+
+<body>
+
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page for Qhull</a>
+<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual: Table of
+Contents</a><br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#TOC">Qhull code</a>: Table of Contents
+(please wait while loading) <br>
+<b>Dn:</b> <a href="../src/libqhull_r/index.htm">Qhull functions</a>, macros, and data
+structures
+</p>
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/4dcube.html"><img
+src="qh--4d.gif" alt="[4-d cube]" align="middle" width="100"
+height="100"></a> Qhull code</h1>
+
+<p>This section discusses the code for Qhull. </p>
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<h2><a href="#TOP">&#187;</a><a name="TOC">Qhull code: Table of
+Contents </a></h2>
+
+<ul>
+ <li><a href="#reentrant">Reentrant</a> Qhull
+ <li><a href="#convert">How to convert</a> code to reentrant Qhull
+ <li><a href="#64bit">Qhull</a> on 64-bit computers
+ <li><a href="#cpp">Calling</a> Qhull from C++ programs
+ <ul>
+ <li><a href="#questions-cpp">Cpp questions for Qhull</a></li>
+ <li><a href="#coordinate-cpp">CoordinateIterator</a></li>
+ <li><a href="#qhull-cpp">Qhull</a></li>
+ <li><a href="#error-cpp">QhullError</a></li>
+ <li><a href="#facet-cpp">QhullFacet</a></li>
+ <li><a href="#facetlist-cpp">QhullFacetList</a></li>
+ <li><a href="#facetset-cpp">QhullFacetSet</a></li>
+ <li><a href="#iterator-cpp">QhullIterator</a></li>
+ <li><a href="#linkedlist-cpp">QhullLinkedList</a></li>
+ <li><a href="#point-cpp">QhullPoint</a></li>
+ <li><a href="#qh-cpp">QhullQh</a></li>
+ <li><a href="#pointset-cpp">QhullPointSet</a></li>
+ <li><a href="#ridge-cpp">QhullRidge</a></li>
+ <li><a href="#ridgeset-cpp">QhullRidgeSet</a></li>
+ <li><a href="#set-cpp">QhullSet</a></li>
+ <li><a href="#vertex-cpp">QhullVertex</a></li>
+ <li><a href="#vertexlist-cpp">QhullVertexList</a></li>
+ <li><a href="#vertexset-cpp">QhullVertexSet</a></li>
+ <li><a href="#rbox-cpp">RboxPoints</a></li>
+ </ul>
+ <li><a href="#library">Calling</a> Qhull from C programs
+ <ul>
+ <li><a href="#exit">How to avoid</a> exit(), fprintf(), stderr, and stdout</li>
+ <li><a href="#constrained">Constrained Delaunay</a>
+ triangulation</li>
+ <li><a href="#dids">Delaunay triangulations</a> and point indices</li>
+ <li><a href="#findfacet">Locate facet</a> with
+ qh_findbestfacet()</li>
+ <li><a href="#inc">On-line construction</a> with
+ qh_addpoint()</li>
+ <li><a href="#mem">Sets and quick memory</a> allocation</li>
+ <li><a href="#tricoplanar">Tricoplanar facets</a> and option 'Qt'</li>
+ <li><a href="#vneighbor">Vertex neighbors</a> of a vertex</li>
+ <li><a href="#vertices">Voronoi vertices</a> of a region</li>
+ <li><a href="#ridge">Voronoi vertices</a> of a ridge</li>
+ </ul>
+ </li>
+ <li><a href="#performance">Performance</a> of Qhull</li>
+ <li><a href="#enhance">Enhancements</a> to Qhull</li>
+ <li><a href="../src/libqhull_r/index.htm">Qhull</a> functions, macros, and data
+ structures </li>
+</ul>
+
+<hr>
+
+<h2><a href="#TOC">&#187;</a><a name="reentrant">Reentrant Qhull</a></h2>
+
+<p>Qhull-2015 introduces reentrant Qhull (libqhull_r). Reentrant Qhull uses a qhT* argument instead of global data structures.
+The qhT* pointer is the first argument to most Qhull routines. It allows multiple instances of Qhull to run at the same time.
+It simplifies the C++ interface to Qhull.
+
+<p>New code should be written with libqhull_r. Existing users of libqhull should consider converting to libqhull_r.
+Although libqhull will be supported indefinitely, improvements may not be implemented.
+Reentrant qhull is 1-2% slower than non-reentrant qhull.
+
+<p><b>Note:</b> Reentrant Qhull is <i>not</i> thread safe. Do not invoke Qhull routines with the same qhT* pointer from multiple threads.
+
+<h2><a href="#TOC">&#187;</a><a name="convert">How to convert</a> code to reentrant Qhull</h2>
+
+<p>C++ users need to convert to libqhull_r.
+The new C++ interface does a better, but not perfect, job of hiding Qhull's C data structures.
+The previous C++ interface was unusual due to Qhull's global data structures.
+
+<p>All other users should consider converting to libqhull_r. The conversion is straight forward.
+The original conversion of libqhull to libqhull_r required thousands of changes, mostly global
+search and replace. The first run of Qhull (unix_r.c) produced the same
+output, and nearly the same log files, as the original (unix.c).
+
+<p>Suggestions to help with conversion.
+<ul>
+<li>Compare qconvex_r.c with qconvex.c. Define a qhT object and a pointer it. The qhT* pointer is the first argument to most Qhull functions.
+Clear <tt>qh_qh-&lt;NOerrext</tt> before calling qh_initflags(). Invoke QHULL_LIB_CHECK to check for a compatible Qhull library.
+<li>Compare user_eg2_r.c with user_eg2.c
+<li>Compare user_eg_r.c with user_eg.c. If you use qhT before invoking qh_init_A, call qh_zero() to clear the qhT object.
+user_eg_r.c includes multiple Qhull runs.
+<li>Review user_eg3_r.cpp. As with the other programs, invoke QHULL_LIB_CHECK.
+Simple C++ programs should compile as is.
+<li>Compare QhullFacet.cpp with the same file in Qhull-2012.1. UsingLibQhull was replaced with the macro QH_TRY_() and '<tt>qh_qh-&lt;NOerrext= true</tt>'.
+<li>For detailed notes on libqhull_r, see "libqhull_r (reentrant Qhull)" and "Source code changes for libqhull_r" in <a href="../src/Changes.txt">Changes.txt</a>.
+<li>For detailed notes on libqhullcpp, see "C++ interface" and following sections in <a href="../src/Changes.txt">Changes.txt</a>.
+<li>For regexps and conversion notes, see <a href="http://www.qhull.org/html/README_r.txt">README_r.txt</a> (unedited).
+</ul>
+
+<h2><a href="#TOC">&#187;</a><a name="64bit">Qhull on 64-bit computers</a></h2>
+
+<p>Qhull compiles for 64-bit hosts. Since the size of a pointer on a 64-bit host is double the size on a 32-bit host,
+memory consumption increases about 50% for simplicial facets and up-to 100% for non-simplicial facets.
+
+<p>You can check memory consumption with option <a href="qh-optt.htm#Ts">Ts</a>. It includes the size of
+each data structure:
+<ul>
+<li>32-bit -- merge 24 ridge 20 vertex 28 facet 88 normal 24 ridge vertices 16 facet vertices or neighbors 20
+<li>64-bit -- merge 32 ridge 32 vertex 48 facet 120 normal 32 ridge vertices 40 facet vertices or neighbors 48
+</ul>
+
+<p>For Qhull 2015, the maximum identifier for ridges, vertices, and facets was increased
+from 24-bits to 32-bits. This allows for larger convex hulls, but may increase the size of
+the corresponding data structures. The sizes for Qhull 2012.1 were
+<ul>
+<li>32-bit -- merge 24 ridge 16 vertex 24 facet 88
+<li>64-bit -- merge 32 ridge 32 vertex 40 facet 120
+</ul>
+
+<h2><a href="#TOC">&#187;</a><a name="cpp">Calling Qhull from
+C++ programs</a></h2>
+
+<p>Qhull 2015 uses reentrant Qhull for its C++ interface. If you used
+the C++ interface from qhull 2012.1, you may need to adjust how you initialize and use
+the Qhull classes. See <a href="#convert">How to convert code to reentrant Qhull</a>.
+
+<p>
+Qhull's C++ interface allows you to explore the results of running Qhull.
+It provides access to Qhull's data structures.
+Most of the classes derive from the corresponding qhull data structure.
+For example, <a href="#facet-cpp">QhullFacet</a> is an instance of Qhull's <a href="../src/libqhull_r/libqhull_r.h#facetT">facetT</a>.
+</p>
+
+<p>You can retain most of the data in Qhull and use the C++ interface to explore its results.
+Each object contains a reference the Qhull's data structure (via QhullQh), making the C++ representation less memory efficient.
+</p>
+
+<p>Besides using the C++ interface, you can also use libqhull_r directly. For example,
+the FOREACHfacet_(...) macro will visit each facet in turn.
+</p>
+
+<p>The C++ interface to Qhull is incomplete. You may need to extend the interface.
+If so, you will need to understand Qhull's data structures and read the code.
+
+Example (c.f., <code>user_eg3 eg-100</code>). It prints the facets generated by Qhull.
+
+<pre>
+ RboxPoints rbox;
+ rbox.appendRandomPoints("100");
+ Qhull qhull;
+ qhull.runQhull("", rbox);
+ QhullFacetList facets(qhull);
+ cout<< facets;
+</pre>
+
+<p>
+The C++ iterface for RboxPoints redefines the fprintf() calls
+in rboxlib.c. Instead of writing its output to stdout, RboxPoints appends
+the output to a std::vector.
+The same technique may be used for calling Qhull from C++.
+</p>
+<ul><li>
+Run Qhull with option '<a href="qh-optt.htm#Ta">Ta</a>' to annotate the
+output with qh_fprintf() identifiers.
+</li><li>
+Redefine qh_fprintf() for these identifiers.
+</li><li>
+See RboxPoints.cpp for an example.
+</li></ul>
+<p>
+Since the C++ interface uses reentrant Qhull, multiple threads may run Qhull at the same time. Each thread is
+one run of Qhull.
+</p>
+
+<p>
+Do <i>not</i> have two threads accessing the same Qhull instance. Qhull is not thread-safe.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="coordinate-cpp">CoordinateIterator</a></h3>
+<p>
+A CoordinateIterator or ConstCoordinateIterator [RboxPoints.cpp] is a <code>std::vector&lt;realT>::iterator</code> for Rbox and Qhull coordinates.
+It is the result type of <a href="#rbox-cpp">RboxPoints</a>.coordinates().
+</p>
+
+<p>Qhull does not use CoordinateIterator for its data structures. A point in Qhull is an array of reals instead of a std::vector.
+See <a href="#point-cpp">QhullPoint</a>.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="qhull-cpp">Qhull</a></h3>
+<p>
+Qhull is the top-level class for running Qhull.
+It initializes Qhull, runs the computation, and records errors.
+It provides access to the global data structure <a href="#qh-cpp">QhullQh</a>,
+Qhull's <a href="#facet-cpp">facets</a>, and <a href="#vertex-cpp">vertices</a>.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="error-cpp">QhullError</a></h3>
+<p>
+QhullError is derived from <code>std::exception</code>. It reports errors from Qhull and captures the output to stderr.
+</p>
+
+<p>
+If error handling is not set up, Qhull exits with a code from 1 to 5. The codes are defined by
+qh_ERR* in libqhull_r.h. The exit is via qh_exit() in usermem_r.c.
+The C++ interface does not report the
+captured output in QhullError. Call Qhull::setErrorStream to send output to cerr instead.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="facet-cpp">QhullFacet</a></h3>
+<p>
+A QhullFacet is a facet of the convex hull, a region of the Delaunay triangulation, a vertex of a Voronoi diagram,
+or an intersection of the halfspace intersection about a point.
+A QhullFacet has a set of <a href="#vertex-cpp">QhullVertex</a>, a set of <a href="#ridge-cpp">QhullRidge</a>, and
+a set of neighboring QhullFacets.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="facetlist-cpp">QhullFacetList</a></h3>
+<p>
+A QhullFacetList is a linked list of <a href="#facet-cpp">QhullFacet</a>. The result of <code>Qhull.runQhull</code> is a QhullFacetList stored
+in <a href="#qh-cpp">QhullQh</a>.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="facetset-cpp">QhullFacetSet</a></h3>
+<p>
+A QhullFacetSet is a <a href="#set-cpp">QhullSet</a> of <a href="#facet-cpp">QhullFacet</a>. QhullFacetSet may be ordered or unordered. The neighboring facets of a QhullFacet is a QhullFacetSet.
+The neighbors of a <a href="#facet-cpp">QhullFacet</a> is a QhullFacetSet.
+The neighbors are ordered for simplicial facets, matching the opposite vertex of the facet.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="iterator-cpp">QhullIterator</a></h3>
+<p>
+QhullIterator contains macros for defining Java-style iterator templates from a STL-style iterator template.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="linkedlist-cpp">QhullLinkedList</a></h3>
+<p>
+A QhullLinkedLIst is a template for linked lists with next and previous pointers.
+<a href="#facetlist-cpp">QhullFacetList</a> and <a href="#facetlist-cpp">QhullVertexList</a> are QhullLinkedLists.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="point-cpp">QhullPoint</a></h3>
+<p>
+A QhullPoint is an array of point coordinates, typically doubles. The length of the array is <a href="#qh-cpp">QhullQh</a>.hull_dim.
+The identifier of a QhullPoint is its 0-based index from QhullQh.first_point followed by QhullQh.other_points.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="pointset-cpp">QhullPointSet</a></h3>
+<p>
+A QhullPointSet is a <a href="#set-cpp">QhullSet</a> of <a href="#point-cpp">QhullPoint</a>. The QhullPointSet of a <a href="#facet-cpp">QhullFacet</a> is its coplanar points.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="qh-cpp">QhullQh</a></h3>
+<p>
+QhullQh is the root of Qhull's data structure.
+It contains initialized constants, sets, buffers, and variables.
+It contains an array and a set of <a href="#point-cpp">QhullPoint</a>,
+a list of <a href="#facet-cpp">QhullFacet</a>, and a list of <a href="#vertex-cpp">QhullVertex</a>.
+The points are the input to Qhull. The facets and vertices are the result of running Qhull.
+</p>
+
+<p>
+Qhull's functions access QhullQh through the global variable, <code>qh_qh</code>.
+The global data structures, qh_stat and qh_mem, record statistics and manage memory respectively.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="ridge-cpp">QhullRidge</a></h3>
+
+<p>
+A QhullRidge represents the edge between two <a href="#facet-cpp">QhullFacet</a>'s.
+It is always simplicial with qh.hull_dim-1 <a href="#vertex-cpp">QhullVertex</a>)'s.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="ridgeset-cpp">QhullRidgeSet</a></h3>
+
+<p>
+A QhullRidgeSet is a <a href="#set-cpp">QhullSet</a> of <a href="#ridge-cpp">QhullRidge</a>. Each <a href="#facet-cpp">QhullFacet</a> contains a QhullRidgeSet.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="set-cpp">QhullSet</a></h3>
+
+<p>
+A QhullSet is a set of pointers to objects. QhullSets may be ordered or unordered. They are the core data structure for Qhull.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="vertex-cpp">QhullVertex</a></h3>
+
+<p>
+A QhullVertex is a vertex of the convex hull. A simplicial <a href="#facet-cpp">QhullFacet</a> has qh.hull_dim-1 vertices. A QhullVertex contains a <a href="#point-cpp">QhullPoint</a>.
+It may list its neighboring <a href="#facet-cpp">QhullFacet</a>'s.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="vertexlist-cpp">QhullVertexList</a></h3>
+
+<p>
+A QhullVertexList is a <a href="#linkedlist-cpp">QhullLinkedList</a> of <a href="#vertex-cpp">QhullVertex</a>.
+The global data structure, <a href="#qh-cpp">QhullQh</a> contains a QhullVertexList of all
+the vertices.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="vertexset-cpp">QhullVertexSet</a></h3>
+
+<p>
+A QhullVertexSet is a <a href="#set-cpp">QhullSet</a> of <a href="#vertex-cpp">QhullVertex</a>.
+The QhullVertexSet of a <a href="#facet-cpp">QhullFacet</a> is the vertices of the facet. It is
+ordered for simplicial facets and unordered for non-simplicial facets.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="rbox-cpp">RboxPoints</a></h3>
+
+<p>
+RboxPoints is a std::vector of point coordinates (<a href="#point-cpp">QhullPoint</a>).
+It's iterator is <a href="#coordinate-cpp">CoordinateIterator</a>.
+</p>
+<p>
+<code>RboxPoints.appendRandomPoints()</code> appends points from a variety of distributions such as uniformly distributed within a cube and random points on a sphere.
+It can also append a cube's vertices or specific points.
+</p>
+
+<h3><a href="#TOC">&#187;</a><a name="questions-cpp">Cpp questions for Qhull</a></h3>
+
+Developing C++ code requires many conventions, idioms, and technical details.
+The following questions have either
+mystified the author or do not have a clear answer. See also
+<a href="http://www.qhull.org/road/road-faq/xml/cpp-guideline.xml">C++ and Perl Guidelines</a>.
+and FIXUP notes in the code.
+Please add notes to <a href="http://github.com/qhull/qhull/wiki">Qhull Wiki</a>.
+
+<ul>
+<li>FIXUP QH11028 Should return reference, but get reference to temporary
+<pre>iterator Coordinates::operator++() { return iterator(++i); }</pre>
+<li>size() as size_t, size_type, or int
+<li>Should all containers have a reserve()?
+<li>Qhull.feasiblePoint interface
+<li>How to avoid copy constructor while logging, maybeThrowQhullMessage()
+<li>How to configure Qhull output. Trace and results should go to stdout/stderr
+<li>Qhull and RboxPoints messaging. e.g., ~Qhull, hasQhullMessage(). Rename them as QhullErrorMessage?
+<li>How to add additional output to an error message, e.g., qh_setprint
+<li>Is idx the best name for an index? It's rather cryptic, but BSD strings.h defines index().
+<li>Qhull::feasiblePoint Qhull::useOutputStream as field or getter?
+<li>Define virtual functions for user customization of Qhull (e.g., qh_fprintf, qh_memfree,etc.)
+<li>Figure out RoadError::global_log. clearQhullMessage currently clearGlobalLog
+<li>Should the false QhullFacet be NULL or empty? e.g., QhullFacet::tricoplanarOwner() and QhullFacetSet::end()
+<li>Should output format for floats be predefined (qh_REAL_1, 2.2g, 10.7g) or as currently set for stream
+<li>Should cout << !point.defined() be blank or 'undefined'
+<li>Infinite point as !defined()
+<li>qlist and qlinkedlist define pointer, reference, size_type, difference_type, const_pointer, const_reference for the class but not for iterator and const_iterator
+ vector.h -- <pre>reference operator[](difference_type _Off) const</pre>
+<li>When forwarding an implementation is base() an approriate name (e.g., Coordinates::iterator::base() as std::vector<coordT>::iterator).
+<li>When forwarding an implementation, does not work "returning address of temporary"
+<li>Also --, +=, and -=
+ <pre>iterator &operator++() { return iterator(i++); }</pre>
+<li>if vector<coordT> inheritance is bad, is QhullVertexSet OK?
+<li>Should QhullPointSet define pointer and reference data types?
+</ul>
+
+<h2><a href="#TOC">&#187;</a><a name="library">Calling Qhull from
+C programs</a></h2>
+
+<p><b>Warning:</b> Qhull was not designed for calling from C
+programs. You may find the <a href="#cpp">C++ interface</a> easier to use.
+You will need to understand the data structures and read the code.
+Most users will find it easier to call Qhull as an external
+command.
+
+<p>For examples of calling Qhull, see GNU Octave's
+<a href=http://www.gnu.org/software/octave/doc/interpreter/Geometry.html>computational geometry code</a>,
+and Qhull's
+<a href=../src/user_eg/user_eg_r.c>user_eg_r.c</a>,
+<a href=../src/user_eg2/user_eg2_r.c>user_eg2_r.c</a>, and
+<a href=../src/libqhull_r/user_r.c>user_r.c</a>. To see how Qhull calls its library, read
+<a href=../src/qhull/unix_r.c>unix_r.c</a>,
+<a href=../src/qconvex/qconvex.c>qconvex.c</a>,
+<a href=../src/qdelaunay/qdelaun.c>qdelaun.c</a>,
+<a href=../src/qhalf/qhalf.c>qhalf.c</a>, and
+<a href=../src/qvoronoi/qvoronoi.c>qvoronoi.c</a>. The '*_r.c' files are reentrant, otherwise they are non-reentrant.
+Either version may be used. New code should use reentrant Qhull.
+
+<p>See <a href="../src/libqhull_r/index.htm">Reentrant Qhull functions, macros, and data
+structures</a> for internal documentation of Qhull. The
+documentation provides an overview and index. To use the library
+you will need to read and understand the code. For most users, it
+is better to write data to a file, call the qhull program, and
+read the results from the output file.</p>
+
+<p>If you use non-reentrant Qhull, be aware of the macros &quot;qh&quot;
+and &quot;qhstat&quot;, e.g., &quot;qh hull_dim&quot;. They are
+defined in <tt>libqhull.h</tt>. They allow the global data
+structures to be pre-allocated (faster access) or dynamically
+allocated (allows multiple copies). </p>
+
+<p>Qhull's <tt>Makefile</tt> produces a library, <tt>libqhull_r.a</tt>,
+for inclusion in your programs. First review <tt>libqhull_r.h</tt>.
+This defines the data structures used by Qhull and provides
+prototypes for the top-level functions.
+Most users will only need libqhull_r.h in their programs. For
+example, the Qhull program is defined with <tt>libqhull_r.h</tt> and <tt>unix_r.c</tt>.
+To access all functions, use <tt>qhull_ra.h</tt>. Include the file
+with &quot;<tt>#include &lt;libqhull_r/qhull_ra.h&gt;</tt>&quot;. This
+avoids potential name conflicts.</p>
+
+<p>If you use the Qhull library, you are on your own as far as
+bugs go. Start with small examples for which you know the output.
+If you get a bug, try to duplicate it with the Qhull program. The
+'<a href="qh-optt.htm#Tc">Tc</a>' option will catch many problems
+as they occur. When an error occurs, use '<a
+href="qh-optt.htm#Tn">T4</a> <a href="qh-optt.htm#TPn">TPn</a>'
+to trace from the last point added to the hull. Compare your
+trace with the trace output from the Qhull program.</p>
+
+<p>Errors in the Qhull library are more likely than errors in the
+Qhull program. These are usually due to feature interactions that
+do not occur in the Qhull program. Please report all errors that
+you find in the Qhull library. Please include suggestions for
+improvement. </p>
+
+<h3><a href="#TOC">&#187;</a><a name="exit">How to avoid exit(), fprintf(), stderr, and stdout</a></h3>
+
+<p>Qhull sends output to qh.fout and errors, log messages, and summaries to qh.ferr. qh.fout is normally
+stdout and qh.ferr is stderr. qh.fout may be redefined by option '<a
+href="qh-optt.htm#TO">TO</a>' or the caller. qh.ferr may be redirected to qh.fout by option '<a
+href="qh-optt.htm#Tz">Tz</a>'.</p>
+
+<p>Qhull does not use stderr, stdout, fprintf(), or exit() directly.</p>
+
+<p>Qhull reports errors via qh_errexit() by writting a message to qh.ferr and invoking longjmp().
+This returns the caller to the corresponding setjmp() (c.f., QH_TRY_ in QhullQh.h). If
+qh_errexit() is not available, Qhull functions call qh_exit(). qh_exit() normally calls exit(),
+but may be redefined by the user. An example is
+libqhullcpp/usermem_r-cpp.cpp. It redefines qh_exit() as a 'throw'.</p>
+
+<p>If qh_meminit() or qh_new_qhull() is called with ferr==NULL, then they set ferr to stderr.
+Otherwise the Qhull libraries use qh->ferr and qh->qhmem.ferr for error output.</p>
+
+<p>If an error occurs before qh->ferr is initialized, Qhull invokes qh_fprintf_stderr(). The user
+may redefine this function along with qh_exit(), qh_malloc(), and qh_free().
+
+<p>The Qhull libraries write output via qh_fprintf() [userprintf_r.c]. Otherwise, the Qhull
+libraries do not use stdout, fprintf(), or printf(). Like qh_exit(), the user may redefine
+qh_fprintf().</p>
+
+<h3><a href="#TOC">&#187;</a><a name="mem">sets and quick memory
+allocation</a></h3>
+
+<p>You can use <tt>mem_r.c</tt> and <tt>qset_r.c</tt> individually. <tt>Mem_r.c
+</tt>implements quick-fit memory allocation. It is faster than
+malloc/free in applications that allocate and deallocate lots of
+memory. </p>
+
+<p><tt>Qset_r.c</tt> implements sets and related collections. It's
+the inner loop of Qhull, so speed is more important than
+abstraction. Set iteration is particularly fast. <tt>qset_r.c</tt>
+just includes the functions needed for Qhull. </p>
+
+<h3><a href="#TOC">&#187;</a><a name="dids">Delaunay triangulations
+and point indices</a></h3>
+
+<p>Here some unchecked code to print the point indices of each
+Delaunay triangle. Use option 'QJ' if you want to avoid
+non-simplicial facets. Note that upper Delaunay regions are
+skipped. These facets correspond to the furthest-site Delaunay
+triangulation. </p>
+
+<blockquote>
+ <pre>
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+
+ FORALLfacets {
+ if (!facet-&gt;upperdelaunay) {
+ printf (&quot;%d&quot;, qh_setsize (facet-&gt;vertices);
+ FOREACHvertex_(facet-&gt;vertices)
+ printf (&quot; %d&quot;, qh_pointid (vertex-&gt;point));
+ printf (&quot;\n&quot;);
+ }
+ }
+
+</pre>
+</blockquote>
+
+<h3><a href="#TOC">&#187;</a><a name="findfacet">locate a facet with
+qh_findbestfacet()</a></h3>
+
+<p>The routine qh_findbestfacet in <tt>poly2_r.c</tt> is
+particularly useful. It uses a directed search to locate the
+facet that is furthest below a point. For Delaunay
+triangulations, this facet is the Delaunay triangle that contains
+the lifted point. For convex hulls, the distance of a point to
+the convex hull is either the distance to this facet or the
+distance to a subface of the facet.</p>
+
+<blockquote>
+<p><b>Warning:</b> If triangulated output ('<a href=qh-optq.htm#Qt>Qt</a>') and
+the best facet is triangulated, qh_findbestfacet() returns one of
+the corresponding 'tricoplanar' facets. The actual best facet may be a different
+tricoplanar facet.
+<p>
+See qh_nearvertex() in poly2.c for sample code to visit each
+tricoplanar facet. To identify the correct tricoplanar facet,
+see Devillers, et. al., [<a href="index.htm#devi01">'01</a>]
+and Mucke, et al [<a href="index.htm#muck96">'96</a>]. If you
+implement this test in general dimension, please notify
+<a href="mailto:qhull@qhull.org">qhull@qhull.org</a>.
+</blockquote>
+
+<p>qh_findbestfacet performs an exhaustive search if its directed
+search returns a facet that is above the point. This occurs when
+the point is inside the hull or if the curvature of the convex
+hull is less than the curvature of a sphere centered at the point
+(e.g., a point near a lens-shaped convex hull). When the later
+occurs, the distance function is bimodal and a directed search
+may return a facet on the far side of the convex hull. </p>
+
+<p>Algorithms that retain the previously constructed hulls
+usually avoid an exhaustive search for the best facet. You may
+use a hierarchical decomposition of the convex hull [Dobkin and
+Kirkpatrick <a href="index.htm#dob-kir90">'90</a>]. </p>
+
+<p>To use qh_findbestfacet with Delaunay triangulations, lift the
+point to a paraboloid by summing the squares of its coordinates
+(see qh_setdelaunay in geom2_r.c). Do not scale the input with
+options 'Qbk', 'QBk', 'QbB' or 'Qbb'. See Mucke, et al [<a
+href="index.htm#muck96">'96</a>] for a good point location
+algorithm.</p>
+
+<p>The intersection of a ray with the convex hull may be found by
+locating the facet closest to a distant point on the ray.
+Intersecting the ray with the facet's hyperplane gives a new
+point to test. </p>
+
+<h3><a href="#TOC">&#187;</a><a name="inc">on-line construction with
+qh_addpoint()</a></h3>
+
+<p>The Qhull library may be used for the on-line construction of
+convex hulls, Delaunay triangulations, and halfspace
+intersections about a point. It may be slower than implementations that retain
+intermediate convex hulls (e.g., Clarkson's <a
+href="http://www.netlib.org/voronoi/hull.html">hull
+program</a>). These implementations always use a directed search.
+For the on-line construction of convex hulls and halfspace
+intersections, Qhull may use an exhaustive search
+(qh_findbestfacet). </p>
+
+<p>You may use qh_findbestfacet and qh_addpoint (<tt>libqhull.c</tt>) to add a point to
+a convex hull. Do not modify the point's coordinates since
+qh_addpoint does not make a copy of the coordinates. For Delaunay
+triangulations, you need to lift the point to a paraboloid by
+summing the squares of the coordinates (see qh_setdelaunay in
+geom2.c). Do not scale the input with options 'Qbk', 'QBk', 'QbB'
+or 'Qbb'. Do not deallocate the point's coordinates. You need to
+provide a facet that is below the point (<a href="#findfacet">qh_findbestfacet</a>).
+</p>
+
+<p>You can not delete points. Another limitation is that Qhull
+uses the initial set of points to determine the maximum roundoff
+error (via the upper and lower bounds for each coordinate). </p>
+
+<p>For many applications, it is better to rebuild the hull from
+scratch for each new point. This is especially true if the point
+set is small or if many points are added at a time.</p>
+
+<p>Calling qh_addpoint from your program may be slower than
+recomputing the convex hull with qh_qhull. This is especially
+true if the added points are not appended to the qh first_point
+array. In this case, Qhull must search a set to determine a
+point's ID. [R. Weber] </p>
+
+<p>See user_eg.c for examples of the on-line construction of
+convex hulls, Delaunay triangulations, and halfspace
+intersections. The outline is: </p>
+
+<blockquote>
+ <pre>
+initialize qhull with an initial set of points
+qh_qhull();
+
+for each additional point p
+ append p to the end of the point array or allocate p separately
+ lift p to the paraboloid by calling qh_setdelaunay
+ facet= qh_findbestfacet (p, !qh_ALL, &amp;bestdist, &amp;isoutside);
+ if (isoutside)
+ if (!qh_addpoint (point, facet, False))
+ break; /* user requested an early exit with 'TVn' or 'TCn' */
+
+call qh_check_maxout() to compute outer planes
+terminate qhull</pre>
+</blockquote>
+
+<h3><a href="#TOC">&#187;</a><a name="constrained">Constrained
+Delaunay triangulation </a></h3>
+
+<p>With a fair amount of work, Qhull is suitable for constrained
+Delaunay triangulation. See Shewchuk, ACM Symposium on
+Computational Geometry, Minneapolis 1998.</p>
+
+<p>Here's a quick way to add a constraint to a Delaunay
+triangulation: subdivide the constraint into pieces shorter than
+the minimum feature separation. You will need an independent
+check of the constraint in the output since the minimum feature
+separation may be incorrect. [H. Geron] </p>
+
+<h3><a href="#TOC">&#187;</a><a name="tricoplanar">Tricoplanar facets and option 'Qt'</h3>
+
+<p>Option '<a href=qh-optq.htm#Qt>Qt</a>' triangulates non-simplicial
+facets (e.g., a square facet in 3-d or a cubical facet in 4-d).
+All facets share the same apex (i.e., the first vertex in facet->vertices).
+For each triangulated facet, Qhull
+sets facet->tricoplanar true and copies facet->center, facet->normal, facet->offset, and facet->maxoutside. One of
+the facets owns facet->normal; its facet->keepcentrum is true.
+If facet->isarea is false, facet->triowner points to the owning
+facet.
+
+<p>Qhull sets facet->degenerate if the facet's vertices belong
+to the same ridge of the non-simplicial facet.
+
+<p>To visit each tricoplanar facet of a non-simplicial facet,
+either visit all neighbors of the apex or recursively visit
+all neighbors of a tricoplanar facet. The tricoplanar facets
+will have the same facet->center.</p>
+
+<p>See <a href=../src/libqhull_r/io_r.c#detvridge>qh_detvridge</a> for an example of ignoring tricoplanar facets.</p>
+
+<h3><a href="#TOC">&#187;</a><a name="vertices">Voronoi vertices of a
+region</a></h3>
+
+<p>The following code iterates over all Voronoi vertices for each
+Voronoi region. Qhull computes Voronoi vertices from the convex
+hull that corresponds to a Delaunay triangulation. An input site
+corresponds to a vertex of the convex hull and a Voronoi vertex
+corresponds to an adjacent facet. A facet is
+&quot;upperdelaunay&quot; if it corresponds to a Voronoi vertex
+&quot;at-infinity&quot;. Qhull uses qh_printvoronoi in <tt>io.c</tt>
+for '<a href=qvoronoi.htm>qvoronoi</a> <a href="qh-opto.htm#o">o'</a> </p>
+
+<blockquote>
+ <pre>
+/* please review this code for correctness */
+qh_setvoronoi_all();
+FORALLvertices {
+ site_id = qh_pointid (vertex-&gt;point);
+ if (qh hull_dim == 3)
+ qh_order_vertexneighbors(vertex);
+ infinity_seen = 0;
+ FOREACHneighbor_(vertex) {
+ if (neighbor-&gt;upperdelaunay) {
+ if (!infinity_seen) {
+ infinity_seen = 1;
+ ... process a Voronoi vertex &quot;at infinity&quot; ...
+ }
+ }else {
+ voronoi_vertex = neighbor-&gt;center;
+ ... your code goes here ...
+ }
+ }
+}
+</pre>
+</blockquote>
+
+<h3><a href="#TOC">&#187;</a><a name="ridge">Voronoi vertices of a
+ridge</a></h3>
+
+<p>Qhull uses qh_printvdiagram() in io.c to print the ridges of a
+Voronoi diagram for option '<a href="qh-optf.htm#Fv2">Fv</a>'.
+The helper function qh_eachvoronoi() does the real work. It calls
+the callback 'printvridge' for each ridge of the Voronoi diagram.
+</p>
+
+<p>You may call qh_printvdiagram2(), qh_eachvoronoi(), or
+qh_eachvoronoi_all() with your own function. If you do not need
+the total number of ridges, you can skip the first call to
+qh_printvdiagram2(). See qh_printvridge() and qh_printvnorm() in
+io.c for examples. </p>
+
+<h3><a href="#TOC">&#187;</a><a name="vneighbor">vertex neighbors of
+a vertex</a></h3>
+
+<p>To visit all of the vertices that share an edge with a vertex:
+</p>
+
+<ul>
+ <li>Generate neighbors for each vertex with
+ qh_vertexneighbors in <tt>poly2.c</tt>. </li>
+ <li>For simplicial facets, visit the vertices of each
+ neighbor </li>
+ <li>For non-simplicial facets, <ul>
+ <li>Generate ridges for neighbors with qh_makeridges
+ in <tt>merge.c</tt>. </li>
+ <li>Generate ridges for a vertex with qh_vertexridges
+ in <tt>merge.c</tt>. </li>
+ <li>Visit the vertices of these ridges. </li>
+ </ul>
+ </li>
+</ul>
+
+<p>For non-simplicial facets, the ridges form a simplicial
+decomposition of the (d-2)-faces between each pair of facets --
+if you need 1-faces, you probably need to generate the full face
+graph of the convex hull. </p>
+
+<h2><a href="#TOC">&#187;</a><a name="performance">Performance of
+Qhull </a></h2>
+
+<p>Empirically, Qhull's performance is balanced in the sense that
+the average case happens on average. This may always be true if
+the precision of the input is limited to at most <i>O(log n)</i>
+bits. Empirically, the maximum number of vertices occurs at the
+end of constructing the hull. </p>
+
+<p>Let <i>n</i> be the number of input points, <i>v</i> be the
+number of output vertices, and <i>f_v </i>be the maximum number
+of facets for a convex hull of <i>v</i> vertices. If both
+conditions hold, Qhull runs in <i>O(n log v)</i> in 2-d and 3-d
+and <i>O(n f_v/v)</i> otherwise. The function <i>f_v</i>
+increases rapidly with dimension. It is <em>O(v^floor(d/2) /
+floor(d/2)!)</em>.</p>
+
+<p>The time complexity for merging is unknown. Options '<a
+href="qh-optc.htm#C0">C-0</a>' and '<a href="qh-optq.htm#Qx">Qx</a>'
+(defaults) handle precision problems due to floating-point
+arithmetic. They are optimized for simplicial outputs. </p>
+
+<p>When running large data sets, you should monitor Qhull's
+performance with the '<a href="qh-optt.htm#TFn">TFn</a>' option.
+The time per facet is approximately constant. In high-d with many
+merged facets, the size of the ridge sets grows rapidly. For
+example the product of 8-d simplices contains 18 facets and
+500,000 ridges. This will increase the time needed per facet. </p>
+
+<p>As dimension increases, the number of facets and ridges in a
+convex hull grows rapidly for the same number of vertices. For
+example, the convex hull of 300 cospherical points in 6-d has
+30,000 facets. </p>
+
+<p>If Qhull appears to stop processing facets, check the memory
+usage of Qhull. If more than 5-10% of Qhull is in virtual memory,
+its performance will degrade rapidly. </p>
+
+<p>When building hulls in 20-d and higher, you can follow the
+progress of Qhull with option '<a href="qh-optt.htm#Tn">T1</a>'.
+It reports each major event in processing a point. </p>
+
+<p>To reduce memory requirements, recompile Qhull for
+single-precision reals (REALfloat in <tt>user.h</tt>).
+Single-precision does not work with joggle ('<a
+href="qh-optq.htm#QJn">QJ</a>'). Check qh_MEMalign in <tt>user.h</tt>
+and the match between free list sizes and data structure sizes
+(see the end of the statistics report from '<a
+href="qh-optt.htm#Ts">Ts</a>'). If free list sizes do not match,
+you may be able to use a smaller qh_MEMalign. Setting
+qh_COMPUTEfurthest saves a small amount of memory, as does
+clearing qh_MAXoutside (both in <tt>user.h</tt>).</p>
+
+<p>Shewchuk is working on a 3-d version of his triangle
+program. It is optimized for 3-d simplicial Delaunay triangulation
+and uses less memory than Qhull.</p>
+
+<p>To reduce the size of the Qhull executable, consider
+qh_NOtrace and qh_KEEPstatistics 0 in <tt>user.h</tt>. By
+changing <tt>user.c </tt>you can also remove the input/output
+code in <tt>io.c</tt>. If you don't need facet merging, then
+version 1.01 of Qhull is much smaller. It contains some bugs that
+prevent Qhull from initializing in simple test cases. It is
+slower in high dimensions.</p>
+
+<p>The precision options, '<a href="qh-optc.htm#Vn">Vn</a>', '<a
+href="qh-optc.htm#Wn">Wn</a>', '<a href="qh-optc.htm#Un">Un</a>'.
+'<a href="qh-optc.htm#An">A-n</a>', '<a href="qh-optc.htm#Cn">C-n</a>',
+'<a href="qh-optc.htm#An2">An</a>', '<a href="qh-optc.htm#Cn2">Cn</a>',
+and '<a href="qh-optq.htm#Qx">Qx</a>', may have large effects on
+Qhull performance. You will need to experiment to find the best
+combination for your application. </p>
+
+<p>The verify option ('<a href="qh-optt.htm#Tv">Tv</a>') checks
+every point after the hull is complete. If facet merging is used,
+it checks that every point is inside every facet. This can take a
+very long time if there are many points and many facets. You can
+interrupt the verify without losing your output. If facet merging
+is not used and there are many points and facets, Qhull uses a
+directed search instead of an exhaustive search. This should be
+fast enough for most point sets. Directed search is not used for
+facet merging because directed search was already used for
+updating the facets' outer planes.</p>
+
+<p>The check-frequently option ('<a href="qh-optt.htm#Tc">Tc</a>')
+becomes expensive as the dimension increases. The verify option
+('<a href="qh-optt.htm#Tv">Tv</a>') performs many of the same
+checks before outputting the results.</p>
+
+<p>Options '<a href="qh-optq.htm#Q0">Q0</a>' (no pre-merging), '<a
+href="qh-optq.htm#Q3">Q3</a>' (no checks for redundant vertices),
+'<a href="qh-optq.htm#Q5">Q5</a>' (no updates for outer planes),
+and '<a href="qh-optq.htm#Q8">Q8</a>' (no near-interior points)
+increase Qhull's speed. The corresponding operations may not be
+needed in your application.</p>
+
+<p>In 2-d and 3-d, a partial hull may be faster to produce.
+Option '<a href="qh-optq.htm#QGn">QgGn</a>' only builds facets
+visible to point n. Option '<a href="qh-optq.htm#QVn">QgVn</a>'
+only builds facets that contain point n. In higher-dimensions,
+this does not reduce the number of facets.</p>
+
+<p><tt>User.h</tt> includes a number of performance-related
+constants. Changes may improve Qhull performance on your data
+sets. To understand their effect on performance, you will need to
+read the corresponding code. </p>
+
+<p>GNU <tt>gprof</tt> reports that the dominate cost for 3-d
+convex hull of cosperical points is qh_distplane(), mainly called
+from qh_findbestnew(). The dominate cost for 3-d Delaunay triangulation
+is creating new facets in qh_addpoint(), while qh_distplane() remains
+the most expensive function.
+
+</p>
+<h2><a href="#TOC">&#187;</a><a name="enhance">Enhancements to Qhull </a></h2>
+
+<p>There are many ways in which Qhull can be improved. </p>
+
+<pre>
+[Jan 2016] Suggestions
+------------
+To do for a future verson of Qhull
+ - Add a post-merge pass for Delaunay slivers. Merge into a neighbor with a circumsphere that includes the opposite point. [M. Treacy]
+ - Add a merge pass before cone creation to remove duplicate subridges between horizon facets
+ - Option to add a bounding box for Delaunay triangulations, e,g., nearly coincident points
+ - Report error when rbox Cn,r,m does not produce points (e.g., 'r' distributions)
+ - Rescale output to match 'QbB' on input [J. Metz, 1/30/2014 12:21p]
+ - Run through valgrind
+ - Notes to compgeom on conformant triangulation and Voronoi volume
+ - Git: Create signed tags for Qhull versions
+ - Implement weighted Delaunay triangulation and weighted Voronoi diagram [A. Liebscher]
+ e.g., Sugihara, "Three-dimensional convex hull as a fruitful source of diagrams," Theoretical Computer Science, 2000, 235:325-337
+ - testqset: test qh_setdelnth and move-to-front
+ - Makefile: Re-review gcc/g++ warnings. OK in 2011.
+ - Break up -Wextra into its components or figure out how to override -Wunused-but-set-variable
+ unused-but-set-variable is reporting incorrectly. All instances are annotated.
+ - CMakelists.txt: Why are files duplicated for cmake build
+ - CMakeLists.txt: configure the 'ctest' target
+ - The size of maxpoints in qh_maxsimplex should be d+3 unique points to help avoid QH6154
+
+ - Can countT be defined as 'int', 'unsigned int', or 64-bit int?
+ countT is currently defined as 'int' in qset_r.h
+ Vertex ID and ridge ID perhaps should be countT, They are currently 'unsigned'
+ Check use of 'int' vs. countT in all cpp code
+ Check use of 'int' vs. countT in all c code
+ qset_r.h defines countT -- duplicates code in user_r.h -- need to add to qset.h/user.h
+ countT -1 used as a flag in Coordinates.mid(), QhullFacet->id()
+ Also QhullPoints indexOf and lastIndexOf
+ Also QhullPointSet indexOf and lastIndexOf
+ Coordinates.indexOf assumes countT is signed (from end)
+ Coordinates.lastIndexOf assumes countT is signed (from end)
+ All error messages with countT are wrong, convert to int?
+ RboxPoints.qh_fprintf_rbox, etc. message 9393 assumes countT but may be int, va_arg(args, countT); Need to split
+
+------------
+To do for a furture version of the C++ interface
+ - Fix C++ memory leak in user_eg3 [M. Sandim]
+ - Document C++ using Doxygen conventions (//! and //!<)
+ - Should Qhull manage the output formats for doubles? QH11010 user_r.h defines qh_REAL_1 as %6.8g
+ - Allocate memory for QhullSet using Qhull.qhmem. Create default constructors for QhullVertexSet etc. Also mid() etc.
+ - Add interior point for automatic translation?
+ - Add hasNext() to all next() iterators (e.g., QhullVertex)
+ - Add defineAs() to each object
+ - Write a program with concurrent Qhull
+ - Write QhullStat and QhullStat_test
+ - Add QList and vector instance of facetT*, etc.
+ - Generalize QhullPointSetIterator
+ - qh-code.htm: Document changes to C++ interface.
+ Organize C++ documentation into collection classes, etc.
+ - Review all C++ classes and C++ tests
+ - QhullVertexSet uses QhullSetBase::referenceSetT() to free it's memory. Probably needed elsewhere
+ - The Boost Graph Library provides C++ classes for graph data structures. It may help
+ enhance Qhull's C++ interface [Dr. Dobb's 9/00 p. 29-38; OOPSLA '99 p. 399-414].
+
+[Jan 2010] Suggestions
+ - Generate vcproj from qtpro files
+ cd qtpro && qmake -spec win32-msvc2005 -tp vc -recursive
+ sed -i 's/C\:\/bash\/local\/qhull\/qtpro\///' qhull-all.sln
+ Change qhullcpp to libqhull.dll
+ Allow both builds on same host (keep /tmp separate)
+ - Make distribution -- remove tmp, news, .git, leftovers from project, change CRLF
+ search for 2010.1, Dates
+ qhulltest --all added to output
+ Add md5sum
+ Add test of user_eg3, etc.
+ - C++ class for access to statistics, accumulate vs. add
+ - Add dialog box to RoadError-- a virtual function?
+ - Option 'Gt' does not make visible all facets of the mesh example, rbox 32 M1,0,1 | qhull d Gt
+ - Option to select bounded Voronoi regions [A. Uzunovic]
+ - Merge small volume boundary cells into unbounded regions [Dominik Szczerba]
+ - Postmerge with merge options
+ - Add const to C code
+ - Add modify operators and MutablePointCoordinateIterator to PointCoordinates
+ - Add Qtest::toString() functions for QhullPoint and others. QByteArray and qstrdup()
+ - Fix option Qt for conformant triangulations of merged facets
+ - Investigate flipped facet -- rbox 100 s D3 t1263080158 | qhull R1e-3 Tcv Qc
+ - Add doc comments to c++ code
+ - Measure performance of Qhull, seconds per point by dimension
+ - Report potential wraparound of 64-bit ints -- e.g., a large set or points
+
+Documentation
+- Qhull::addPoint(). Problems with qh_findbestfacet and otherpoints see
+ qh-code.htm#inc on-line construction with qh_addpoint()
+- How to handle 64-bit possible loss of data. WARN64, ptr_intT, size_t/int
+- Show custom of qh_fprintf
+- grep 'qh_mem ' x | sort | awk '{ print $2; }' | uniq -c | grep -vE ' (2|4|6|8|10|12|14|16|20|64|162)[^0-9]'
+- qtpro/qhulltest contains .pro and Makefile. Remove Makefiles by setting shadow directory to ../../tmp/projectname
+- Rules for use of qh_qh and multi processes
+ UsingQhull
+ errorIfAnotherUser
+ ~QhullPoints() needs ownership of qh_qh
+ Does !qh_pointer work?
+ When is qh_qh required? Minimize the time.
+ qhmem, qhstat.ferr
+ qhull_inuse==1 when qhull globals active [not useful?]
+ rbox_inuse==1 when rbox globals active
+ - Multithreaded -- call largest dimension for infinityPoint() and origin()
+ - Better documentation for qhmem totshort, freesize, etc.
+ - how to change .h, .c, and .cpp to text/html. OK in Opera
+ - QhullVertex.dimension() is not quite correct, epensive
+ - Check globalAngleEpsilon
+ - Deprecate save_qhull()
+
+[Dec 2003] Here is a partial list:
+ - fix finddelaunay() in user_eg.c for tricoplanar facets
+ - write a BGL, C++ interface to Qhull
+ http://www.boost.org/libs/graph/doc/table_of_contents.html
+ - change qh_save_qhull to swap the qhT structure instead of using pointers
+ - change error handling and tracing to be independent of 'qh ferr'
+ - determine the maximum width for a given set of parameters
+ - prove that directed search locates all coplanar facets
+ - in high-d merging, can a loop of facets become disconnected?
+ - find a way to improve inner hulls in 5-d and higher
+ - determine the best policy for facet visibility ('<a href="qh-optc.htm#Vn">Vn</a>')
+ - determine the limitations of '<a href="qh-optq.htm#Qg">Qg</a>'
+
+Precision improvements:
+ - For 'Qt', resolve cross-linked, butterfly ridges.
+ May allow retriangulation in qh_addpoint().
+ - for Delaunay triangulations ('d' or 'v') under joggled input ('QJ'),
+ remove vertical facets whose lowest vertex may be coplanar with convex hull
+ - review use of 'Qbb' with 'd QJ'. Is MAXabs_coord better than MAXwidth?
+ - check Sugihara and Iri's better in-sphere test [Canadian
+ Conf. on Comp. Geo., 1989; Univ. of Tokyo RMI 89-05]
+ - replace centrum with center of mass and facet area
+ - handle numeric overflow in qh_normalize and elsewhere
+ - merge flipped facets into non-flipped neighbors.
+ currently they merge into best neighbor (appears ok)
+ - determine min norm for Cramer's rule (qh_sethyperplane_det). It looks high.
+ - improve facet width for very narrow distributions
+
+New features:
+ - implement Matlab's tsearch() using Qhull
+ - compute volume of Voronoi regions. You need to determine the dual face
+ graph in all dimensions [see Clarkson's hull program]
+ - compute alpha shapes [see Clarkson's hull program]
+ - implement deletion of Delaunay vertices
+ see Devillers, ACM Symposium on Computational Geometry, Minneapolis 1999.
+ - compute largest empty circle [see O'Rourke, chapter 5.5.3] [Hase]
+ - list redundant (i.e., coincident) vertices [Spitz]
+ - implement Mucke, et al, ['96] for point location in Delaunay triangulations
+ - implement convex hull of moving points
+ - implement constrained Delaunay diagrams
+ see Shewchuk, ACM Symposium on Computational Geometry, Minneapolis 1998.
+ - estimate outer volume of hull
+ - automatically determine lower dimensional hulls
+ - allow &quot;color&quot; data for input points
+ need to insert a coordinate for Delaunay triangulations
+
+Input/output improvements:
+ - Support the VTK Visualization Toolkit, http://www.kitware.com/vtk.html
+ - generate output data array for Qhull library [Gautier]
+ - need improved DOS window with screen fonts, scrollbar, cut/paste
+ - generate Geomview output for Voronoi ridges and unbounded rays
+ - generate Geomview output for halfspace intersection
+ - generate Geomview display of furthest-site Voronoi diagram
+ - use '<a href="qh-optg.htm#GDn">GDn</a>' to view 5-d facets in 4-d
+ - convert Geomview output for other 3-d viewers
+ - add interactive output option to avoid recomputing a hull
+ - orient vertex neighbors for '<a href="qh-optf.htm#Fv">Fv</a>' in 3-d and 2-d
+ - track total number of ridges for summary and logging
+
+Performance improvements:
+ - optimize Qhull for 2-d Delaunay triangulations
+ - use O'Rourke's <a href="index.htm#orou94">'94</a> vertex-&gt;duplicate_edge
+ - add bucketing
+ - better to specialize all of the code (ca. 2-3x faster w/o merging)
+ - use updated LU decomposition to speed up hyperplane construction
+ - [Gill et al. 1974, Math. Comp. 28:505-35]
+ - construct hyperplanes from the corresponding horizon/visible facets
+ - for merging in high d, do not use vertex-&gt;neighbors
+
+</pre>
+
+<p>Please let us know about your applications and improvements. </p>
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home
+page for Qhull</a> <br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual: Table of
+Contents</a><br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#TOC">Qhull code</a>: Table of Contents <br>
+<b>Dn:</b> <a href="../src/libqhull_r/index.htm">Qhull functions</a>, macros, and data
+structures <!-- GC common information -->
+
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see changes.txt <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-eg.htm b/xs/src/qhull/html/qh-eg.htm
new file mode 100644
index 000000000..a08f0d13f
--- /dev/null
+++ b/xs/src/qhull/html/qh-eg.htm
@@ -0,0 +1,693 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Examples of Qhull</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a href="http://www.qhull.org">Home
+page</a> for Qhull <br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To: </b><a href="#TOC">Qhull examples: Table of Contents</a> (please wait
+while loading)<br>
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/half.html"><img
+src="qh--half.gif" alt="[halfspace]" align="middle" width="100"
+height="100"></a> Examples of Qhull</h1>
+
+<p>This section of the Qhull manual will introduce you to Qhull
+and its options. Each example is a file for viewing with <a
+href="index.htm#geomview">Geomview</a>. You will need to
+use a Unix computer with a copy of Geomview.
+<p>
+If you are not running Unix, you can view <a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/welcome.html">pictures</a>
+for some of the examples. To understand Qhull without Geomview, try the
+examples in <a href="qh-quick.htm#programs">Programs</a> and
+<a href="qh-quick.htm#programs">Programs/input</a>. You can also try small
+examples that you compute by hand. Use <a href="rbox.htm">rbox</a>
+to generate examples.
+<p>
+To generate the Geomview examples, execute the shell script <tt>eg/q_eg</tt>.
+It uses <tt>rbox</tt>. The shell script <tt>eg/q_egtest</tt> generates
+test examples, and <tt>eg/q_test</tt> exercises the code. If you
+find yourself viewing the inside of a 3-d example, use Geomview's
+normalization option on the 'obscure' menu.</p>
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<h2><a href="#TOP">&#187;</a><a name="TOC">Qhull examples: Table of
+Contents </a></h2>
+
+<ul>
+ <li><a href="#2d">2-d and 3-d examples</a></li>
+ <li><a href="#how">How Qhull adds a point</a></li>
+ <li><a href="#joggle">Triangulated output or joggled input</a></li>
+ <li><a href="#delaunay">Delaunay and Voronoi diagrams</a></li>
+ <li><a href="#merge">Facet merging for imprecision</a></li>
+ <li><a href="#4d">4-d objects</a></li>
+ <li><a href="#half">Halfspace intersections</a></li>
+</ul>
+
+<hr>
+<ul>
+ <li><a href="#TOC">&#187;</a><a name="2d">2-d and 3-d examples</a><ul>
+ <li><a href="#01">eg.01.cube</a></li>
+ <li><a href="#02">eg.02.diamond.cube</a></li>
+ <li><a href="#03">eg.03.sphere</a></li>
+ <li><a href="#04">eg.04.circle</a></li>
+ <li><a href="#05">eg.05.spiral</a></li>
+ <li><a href="#06">eg.06.merge.square</a></li>
+ <li><a href="#07">eg.07.box</a></li>
+ <li><a href="#08a">eg.08a.cube.sphere</a></li>
+ <li><a href="#08b">eg.08b.diamond.sphere</a></li>
+ <li><a href="#09">eg.09.lens</a></li>
+ </ul>
+ </li>
+ <li><a href="#TOC">&#187;</a><a name="how">How Qhull adds a point</a><ul>
+ <li><a href="#10a">eg.10a.sphere.visible</a></li>
+ <li><a href="#10b">eg.10b.sphere.beyond</a></li>
+ <li><a href="#10c">eg.10c.sphere.horizon</a></li>
+ <li><a href="#10d">eg.10d.sphere.cone</a></li>
+ <li><a href="#10e">eg.10e.sphere.new</a></li>
+ <li><a href="#14">eg.14.sphere.corner</a></li>
+ </ul>
+ </li>
+ <li><a href="#TOC">&#187;</a> <a name="joggle">Triangulated output or joggled input</a>
+ <ul>
+ <li><a href="#15a">eg.15a.surface</a></li>
+ <li><a href="#15b">eg.15b.triangle</a></li>
+ <li><a href="#15c">eg.15c.joggle</a></li>
+ </ul>
+ <li><a href="#TOC">&#187;</a><a name="delaunay"> Delaunay and
+ Voronoi diagrams</a><ul>
+ <li><a href="#17a">eg.17a.delaunay.2</a></li>
+ <li><a href="#17b">eg.17b.delaunay.2i</a></li>
+ <li><a href="#17c">eg.17c.delaunay.2-3</a></li>
+ <li><a href="#17d">eg.17d.voronoi.2</a></li>
+ <li><a href="#17e">eg.17e.voronoi.2i</a></li>
+ <li><a href="#17f">eg.17f.delaunay.3</a></li>
+ <li><a href="#18a">eg.18a.furthest.2-3</a></li>
+ <li><a href="#18b">eg.18b.furthest-up.2-3</a></li>
+ <li><a href="#18c">eg.18c.furthest.2</a></li>
+ <li><a href="#19">eg.19.voronoi.region.3</a></li>
+ </ul>
+ </li>
+ <li><a href="#TOC">&#187;</a><a name="merge">Facet merging for
+ imprecision </a><ul>
+ <li><a href="#20">eg.20.cone</a></li>
+ <li><a href="#21a">eg.21a.roundoff.errors</a></li>
+ <li><a href="#21b">eg.21b.roundoff.fixed</a></li>
+ <li><a href="#22a">eg.22a.merge.sphere.01</a></li>
+ <li><a href="#22b">eg.22b.merge.sphere.-01</a></li>
+ <li><a href="#22c">eg.22c.merge.sphere.05</a></li>
+ <li><a href="#22d">eg.22d.merge.sphere.-05</a></li>
+ <li><a href="#23">eg.23.merge.cube</a></li>
+ </ul>
+ </li>
+ <li><a href="#TOC">&#187;</a><a name="4d">4-d objects</a><ul>
+ <li><a href="#24">eg.24.merge.cube.4d-in-3d</a></li>
+ <li><a href="#30">eg.30.4d.merge.cube</a></li>
+ <li><a href="#31">eg.31.4d.delaunay</a></li>
+ <li><a href="#32">eg.32.4d.octant</a></li>
+ </ul>
+ </li>
+ <li><a href="#TOC">&#187;</a><a name="half">Halfspace
+ intersections</a><ul>
+ <li><a href="#33a">eg.33a.cone</a></li>
+ <li><a href="#33b">eg.33b.cone.dual</a></li>
+ <li><a href="#33c">eg.33c.cone.halfspace</a></li>
+ </ul>
+ </li>
+</ul>
+
+<hr>
+
+<h2><a href="#TOC">&#187;</a>2-d and 3-d examples</h2>
+
+<h3><a href="#2d">&#187;</a><a name="01">rbox c D3 | qconvex G
+&gt;eg.01.cube </a></h3>
+
+<p>The first example is a cube in 3-d. The color of each facet
+indicates its normal. For example, normal [0,0,1] along the Z
+axis is (r=0.5, g=0.5, b=1.0). With the 'Dn' option in <tt>rbox</tt>,
+you can generate hypercubes in any dimension. Above 7-d the
+number of intermediate facets grows rapidly. Use '<a
+href="qh-optt.htm#TFn">TFn</a>' to track qconvex's progress. Note
+that each facet is a square that qconvex merged from coplanar
+triangles.</p>
+
+<h3><a href="#2d">&#187;</a><a name="02">rbox c d G3.0 | qconvex G
+&gt;eg.02.diamond.cube </a></h3>
+
+<p>The second example is a cube plus a diamond ('d') scaled by <tt>rbox</tt>'s
+'G' option. In higher dimensions, diamonds are much simpler than
+hypercubes. </p>
+
+<h3><a href="#2d">&#187;</a><a name="03">rbox s 100 D3 | qconvex G
+&gt;eg.03.sphere </a></h3>
+
+<p>The <tt>rbox s</tt> option generates random points and
+projects them to the d-sphere. All points should be on the convex
+hull. Notice that random points look more clustered than you
+might expect. You can get a smoother distribution by merging
+facets and printing the vertices, e.g.,<i> rbox 1000 s | qconvex
+A-0.95 p | qconvex G &gt;eg.99</i>.</p>
+
+<h3><a href="#2d">&#187;</a><a name="04">rbox s 100 D2 | qconvex G
+&gt;eg.04.circle </a></h3>
+
+<p>In 2-d, there are many ways to generate a convex hull. One of
+the earliest algorithms, and one of the fastest, is the 2-d
+Quickhull algorithm [c.f., Preparata &amp; Shamos <a
+href="index.htm#pre-sha85">'85</a>]. It was the model for
+Qhull.</p>
+
+<h3><a href="#2d">&#187;</a><a name="05">rbox 10 l | qconvex G
+&gt;eg.05.spiral </a></h3>
+
+<p>One rotation of a spiral.</p>
+
+<h3><a href="#2d">&#187;</a><a name="06">rbox 1000 D2 | qconvex C-0.03
+Qc Gapcv &gt;eg.06.merge.square</a></h3>
+
+<p>This demonstrates how Qhull handles precision errors. Option '<a
+href="qh-optc.htm#Cn">C-0.03</a>' requires a clearly convex angle
+between adjacent facets. Otherwise, Qhull merges the facets. </p>
+
+<p>This is the convex hull of random points in a square. The
+facets have thickness because they must be outside all points and
+must include their vertices. The colored lines represent the
+original points and the spheres represent the vertices. Floating
+in the middle of each facet is the centrum. Each centrum is at
+least 0.03 below the planes of its neighbors. This guarantees
+that the facets are convex.</p>
+
+<h3><a href="#2d">&#187;</a><a name="07">rbox 1000 D3 | qconvex G
+&gt;eg.07.box </a></h3>
+
+<p>Here's the same distribution but in 3-d with Qhull handling
+machine roundoff errors. Note the large number of facets. </p>
+
+<h3><a href="#2d">&#187;</a><a name="08a">rbox c G0.4 s 500 | qconvex G
+&gt;eg.08a.cube.sphere </a></h3>
+
+<p>The sphere is just barely poking out of the cube. Try the same
+distribution with randomization turned on ('<a
+href="qh-optq.htm#Qr">Qr</a>'). This turns Qhull into a
+randomized incremental algorithm. To compare Qhull and
+randomization, look at the number of hyperplanes created and the
+number of points partitioned. Don't compare CPU times since Qhull's
+implementation of randomization is inefficient. The number of
+hyperplanes and partitionings indicate the dominant costs for
+Qhull. With randomization, you'll notice that the number of
+facets created is larger than before. This is especially true as
+you increase the number of points. It is because the randomized
+algorithm builds most of the sphere before it adds the cube's
+vertices.</p>
+
+<h3><a href="#2d">&#187;</a><a name="08b">rbox d G0.6 s 500 | qconvex G
+&gt;eg.08b.diamond.sphere </a></h3>
+
+<p>This is a combination of the diamond distribution and the
+sphere.</p>
+
+<h3><a href="#2d">&#187;</a><a name="09">rbox 100 L3 G0.5 s | qconvex
+G &gt;eg.09.lens </a></h3>
+
+<p>Each half of the lens distribution lies on a sphere of radius
+three. A directed search for the furthest facet below a point
+(e.g., qh_findbest in <tt>geom.c</tt>) may fail if started from
+an arbitrary facet. For example, if the first facet is on the
+opposite side of the lens, a directed search will report that the
+point is inside the convex hull even though it is outside. This
+problem occurs whenever the curvature of the convex hull is less
+than a sphere centered at the test point. </p>
+
+<p>To prevent this problem, Qhull does not use directed search
+all the time. When Qhull processes a point on the edge of the
+lens, it partitions the remaining points with an exhaustive
+search instead of a directed search (see qh_findbestnew in <tt>geom2.c</tt>).
+</p>
+
+<h2><a href="#TOC">&#187;</a>How Qhull adds a point</h2>
+
+<h3><a href="#how">&#187;</a><a name="10a">rbox 100 s P0.5,0.5,0.5 |
+qconvex Ga QG0 &gt;eg.10a.sphere.visible</a></h3>
+
+<p>The next 4 examples show how Qhull adds a point. The point
+[0.5,0.5,0.5] is at one corner of the bounding box. Qhull adds a
+point using the beneath-beyond algorithm. First Qhull finds all
+of the facets that are visible from the point. Qhull will replace
+these facets with new facets.</p>
+
+<h3><a href="#how">&#187;</a><a name="10b">rbox 100 s
+P0.5,0.5,0.5|qconvex Ga QG-0 &gt;eg.10b.sphere.beyond </a></h3>
+
+<p>These are the facets that are not visible from the point.
+Qhull will keep these facets.</p>
+
+<h3><a href="#how">&#187;</a><a name="10c">rbox 100 s P0.5,0.5,0.5 |
+qconvex PG Ga QG0 &gt;eg.10c.sphere.horizon </a></h3>
+
+<p>These facets are the horizon facets; they border the visible
+facets. The inside edges are the horizon ridges. Each horizon
+ridge will form the base for a new facet.</p>
+
+<h3><a href="#how">&#187;</a><a name="10d">rbox 100 s P0.5,0.5,0.5 |
+qconvex Ga QV0 PgG &gt;eg.10d.sphere.cone </a></h3>
+
+<p>This is the cone of points from the new point to the horizon
+facets. Try combining this image with <tt>eg.10c.sphere.horizon</tt>
+and <tt>eg.10a.sphere.visible</tt>.
+</p>
+
+<h3><a href="#how">&#187;</a><a name="10e">rbox 100 s P0.5,0.5,0.5 |
+qconvex Ga &gt;eg.10e.sphere.new</a></h3>
+
+<p>This is the convex hull after [0.5,0.5,0.5] has been added.
+Note that in actual practice, the above sequence would never
+happen. Unlike the randomized algorithms, Qhull always processes
+a point that is furthest in an outside set. A point like
+[0.5,0.5,0.5] would be one of the first points processed.</p>
+
+<h3><a href="#how">&#187;</a><a name="14">rbox 100 s P0.5,0.5,0.5 |
+qhull Ga QV0g Q0 &gt;eg.14.sphere.corner</a></h3>
+
+<p>The '<a href="qh-optq.htm#QVn">QVn</a>', '<a
+href="qh-optq.htm#QGn">QGn </a>' and '<a href="qh-optp.htm#Pdk">Pdk</a>'
+options define good facets for Qhull. In this case '<a
+href="qh-optq.htm#QVn">QV0</a>' defines the 0'th point
+[0.5,0.5,0.5] as the good vertex, and '<a href="qh-optq.htm#Qg">Qg</a>'
+tells Qhull to only build facets that might be part of a good
+facet. This technique reduces output size in low dimensions. It
+does not work with facet merging.</p>
+
+<h2><a href="#TOC">&#187;</a>Triangulated output or joggled input</h2>
+
+<h3><a href="#joggle">&#187;</a><a name="15a">rbox 500 W0 | qconvex QR0 Qc Gvp &gt;eg.15a.surface</a></h3>
+
+<p>This is the convex hull of 500 points on the surface of
+a cube. Note the large, non-simplicial facet for each face.
+Qhull merges non-convex facets.
+
+<p>If the facets were not merged, Qhull
+would report precision problems. For example, turn off facet merging
+with option '<a href="qh-optq.htm#Q0">Q0</a>'. Qhull may report concave
+facets, flipped facets, or other precision errors:
+<blockquote>
+rbox 500 W0 | qhull QR0 Q0
+</blockquote>
+
+<p>
+<h3><a href="#joggle">&#187;</a><a name="15b">rbox 500 W0 | qconvex QR0 Qt Qc Gvp &gt;eg.15b.triangle</a></h3>
+
+<p>Like the previous examples, this is the convex hull of 500 points on the
+surface of a cube. Option '<a href="qh-optq.htm#Qt">Qt</a>' triangulates the
+non-simplicial facets. Triangulated output is
+particularly helpful for Delaunay triangulations.
+
+<p>
+<h3><a href="#joggle">&#187;</a><a name="15c">rbox 500 W0 | qconvex QR0 QJ5e-2 Qc Gvp &gt;eg.15c.joggle</a></h3>
+
+<p>This is the convex hull of 500 joggled points on the surface of
+a cube. The option '<a href="qh-optq.htm#QJn">QJ5e-2</a>'
+sets a very large joggle to make the effect visible. Notice
+that all of the facets are triangles. If you rotate the cube,
+you'll see red-yellow lines for coplanar points.
+<p>
+With option '<a href="qh-optq.htm#QJn">QJ</a>', Qhull joggles the
+input to avoid precision problems. It adds a small random number
+to each input coordinate. If a precision
+error occurs, it increases the joggle and tries again. It repeats
+this process until no precision problems occur.
+<p>
+Joggled input is a simple solution to precision problems in
+computational geometry. Qhull can also merge facets to handle
+precision problems. See <a href="qh-impre.htm#joggle">Merged facets or joggled input</a>.
+
+<h2><a href="#TOC">&#187;</a>Delaunay and Voronoi diagrams</h2>
+
+<h3><a href="#delaunay">&#187;</a><a name="17a">qdelaunay Qt
+&lt;eg.data.17 GnraD2 &gt;eg.17a.delaunay.2</a></h3>
+
+<p>
+The input file, <tt>eg.data.17</tt>, consists of a square, 15 random
+points within the outside half of the square, and 6 co-circular
+points centered on the square.
+
+<p>The Delaunay triangulation is the triangulation with empty
+circumcircles. The input for this example is unusual because it
+includes six co-circular points. Every triangular subset of these
+points has the same circumcircle. Option '<a href="qh-optq.htm#Qt">Qt</a>'
+triangulates the co-circular facet.</p>
+
+<h3><a href="#delaunay">&#187;</a><a name="17b">qdelaunay &lt;eg.data.17
+GnraD2 &gt;eg.17b.delaunay.2i</a></h3>
+
+<p>This is the same example without triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>'). qdelaunay
+merges the non-unique Delaunay triangles into a hexagon.</p>
+
+<h3><a href="#delaunay">&#187;</a><a name="17c">qdelaunay &lt;eg.data.17
+Ga &gt;eg.17c.delaunay.2-3 </a></h3>
+
+<p>This is how Qhull generated both diagrams. Use Geomview's
+'obscure' menu to turn off normalization, and Geomview's
+'cameras' menu to turn off perspective. Then load this <a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html">object</a>
+with one of the previous diagrams.</p>
+
+<p>The points are lifted to a paraboloid by summing the squares
+of each coordinate. These are the light blue points. Then the
+convex hull is taken. That's what you see here. If you look up
+the Z-axis, you'll see that points and edges coincide.</p>
+
+<h3><a href="#delaunay">&#187;</a><a name="17d">qvoronoi QJ
+&lt;eg.data.17 Gna &gt;eg.17d.voronoi.2</a></h3>
+
+<p>The Voronoi diagram is the dual of the Delaunay triangulation.
+Here you see the original sites and the Voronoi vertices.
+Notice the each
+vertex is equidistant from three sites. The edges indicate the
+Voronoi region for a site. Qhull does not draw the unbounded
+edges. Instead, it draws extra edges to close the unbounded
+Voronoi regions. You may find it helpful to enclose the input
+points in a square. You can compute the unbounded
+rays from option '<a href="qh-optf.htm#Fo2">Fo</a>'.
+</p>
+
+<p>Instead
+of triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>'), this
+example uses joggled input ('<a href="qh-optq.htm#QJn">QJ</a>').
+Normally, you should use neither 'QJ' nor 'Qt' for Voronoi diagrams.
+
+<h3><a href="#delaunay">&#187;</a><a name="17e">qvoronoi &lt;eg.data.17
+Gna &gt;eg.17e.voronoi.2i </a></h3>
+
+<p>This looks the same as the previous diagrams, but take a look
+at the data. Run 'qvoronoi p &lt;eg/eg.data.17'. This prints
+the Voronoi vertices.
+
+<p>With 'QJ', there are four nearly identical Voronoi vertices
+within 10^-11 of the origin. Option 'QJ' joggled the input. After the joggle,
+the cocircular
+input sites are no longer cocircular. The corresponding Voronoi vertices are
+similar but not identical.
+
+<p>This example does not use options 'Qt' or 'QJ'. The cocircular
+input sites define one Voronoi vertex near the origin. </p>
+
+<p>Option 'Qt' would triangulate the corresponding Delaunay region into
+four triangles. Each triangle is assigned the same Voronoi vertex.</p>
+
+<h3><a href="#delaunay">&#187;</a><a name="17f"> rbox c G0.1 d |
+qdelaunay Gt Qz &lt;eg.17f.delaunay.3 </a></h3>
+
+<p>This is the 3-d Delaunay triangulation of a small cube inside
+a prism. Since the outside ridges are transparent, it shows the
+interior of the outermost facets. If you slice open the
+triangulation with Geomview's ginsu, you will see that the innermost
+facet is a cube. Note the use of '<a href="qh-optq.htm#Qz">Qz</a>'
+to add a point &quot;at infinity&quot;. This avoids a degenerate
+input due to cospherical points.</p>
+
+<h3><a href="#delaunay">&#187;</a><a name="18a">rbox 10 D2 d | qdelaunay
+Qu G &gt;eg.18a.furthest.2-3 </a></h3>
+
+<p>The furthest-site Voronoi diagram contains Voronoi regions for
+points that are <i>furthest </i>from an input site. It is the
+dual of the furthest-site Delaunay triangulation. You can
+determine the furthest-site Delaunay triangulation from the
+convex hull of the lifted points (<a href="#17c">eg.17c.delaunay.2-3</a>).
+The upper convex hull (blue) generates the furthest-site Delaunay
+triangulation. </p>
+
+<h3><a href="#delaunay">&#187;</a><a name="18b">rbox 10 D2 d | qdelaunay
+Qu Pd2 G &gt;eg.18b.furthest-up.2-3</a></h3>
+
+<p>This is the upper convex hull of the preceding example. The
+furthest-site Delaunay triangulation is the projection of the
+upper convex hull back to the input points. The furthest-site
+Voronoi vertices are the circumcenters of the furthest-site
+Delaunay triangles. </p>
+
+<h3><a href="#delaunay">&#187;</a><a name="18c">rbox 10 D2 d | qvoronoi
+Qu Gv &gt;eg.18c.furthest.2</a></h3>
+
+<p>This shows an incomplete furthest-site Voronoi diagram. It
+only shows regions with more than two vertices. The regions are
+artificially truncated. The actual regions are unbounded. You can
+print the regions' vertices with 'qvoronoi Qu <a
+href="qh-opto.htm#o">o</a>'. </p>
+
+<p>Use Geomview's 'obscure' menu to turn off normalization, and
+Geomview's 'cameras' menu to turn off perspective. Then load this
+with the upper convex hull.</p>
+
+<h3><a href="#delaunay">&#187;</a><a name="19">rbox 10 D3 | qvoronoi QV5
+p | qconvex G &gt;eg.19.voronoi.region.3 </a></h3>
+
+<p>This shows the Voronoi region for input site 5 of a 3-d
+Voronoi diagram.</p>
+
+<h2><a href="#TOC">&#187;</a>Facet merging for imprecision</h2>
+
+<h3><a href="#merge">&#187;</a><a name="20">rbox r s 20 Z1 G0.2 |
+qconvex G &gt;eg.20.cone </a></h3>
+
+<p>There are two things unusual about this <a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/cone.html">cone</a>.
+One is the large flat disk at one end and the other is the
+rectangles about the middle. That's how the points were
+generated, and if those points were exact, this is the correct
+hull. But <tt>rbox</tt> used floating point arithmetic to
+generate the data. So the precise convex hull should have been
+triangles instead of rectangles. By requiring convexity, Qhull
+has recovered the original design.</p>
+
+<h3><a href="#merge">&#187;</a><a name="21a">rbox 200 s | qhull Q0
+R0.01 Gav Po &gt;eg.21a.roundoff.errors </a></h3>
+
+<p>This is the convex hull of 200 cospherical points with
+precision errors ignored ('<a href="qh-optq.htm#Q0">Q0</a>'). To
+demonstrate the effect of roundoff error, we've added a random
+perturbation ('<a href="qh-optc.htm#Rn">R0.01</a>') to every
+distance and hyperplane calculation. Qhull, like all other convex
+hull algorithms with floating point arithmetic, makes
+inconsistent decisions and generates wildly wrong results. In
+this case, one or more facets are flipped over. These facets have
+the wrong color. You can also turn on 'normals' in Geomview's
+appearances menu and turn off 'facing normals'. There should be
+some white lines pointing in the wrong direction. These
+correspond to flipped facets. </p>
+
+<p>Different machines may not produce this picture. If your
+machine generated a long error message, decrease the number of
+points or the random perturbation ('<a href="qh-optc.htm#Rn">R0.01</a>').
+If it did not report flipped facets, increase the number of
+points or perturbation.</p>
+
+<h3><a href="#merge">&#187;</a><a name="21b">rbox 200 s | qconvex Qc
+R0.01 Gpav &gt;eg.21b.roundoff.fixed </a></h3>
+
+<p>Qhull handles the random perturbations and returns an
+imprecise <a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/fixed.html">sphere</a>.
+In this case, the output is a weak approximation to the points.
+This is because a random perturbation of '<a
+href="qh-optc.htm#Rn">R0.01 </a>' is equivalent to losing all but
+1.8 digits of precision. The outer planes float above the points
+because Qhull needs to allow for the maximum roundoff error. </p>
+<p>
+If you start with a smaller random perturbation, you
+can use joggle ('<a href="qh-optq.htm#QJn">QJn</a>') to avoid
+precision problems. You need to set <i>n</i> significantly
+larger than the random perturbation. For example, try
+'rbox 200 s | qconvex Qc R1e-4 QJ1e-1'.
+
+<h3><a href="#merge">&#187;</a><a name="22a">rbox 1000 s| qconvex C0.01
+Qc Gcrp &gt;eg.22a.merge.sphere.01</a></h3>
+
+<h3><a href="#merge">&#187;</a><a name="22b">rbox 1000 s| qconvex
+C-0.01 Qc Gcrp &gt;eg.22b.merge.sphere.-01</a></h3>
+
+<h3><a href="#merge">&#187;</a><a name="22c">rbox 1000 s| qconvex C0.05
+Qc Gcrpv &gt;eg.22c.merge.sphere.05</a></h3>
+
+<h3><a href="#merge">&#187;</a><a name="22d">rbox 1000 s| qconvex
+C-0.05 Qc Gcrpv &gt;eg.22d.merge.sphere.-05</a></h3>
+
+<p>The next four examples compare post-merging and pre-merging ('<a
+href="qh-optc.htm#Cn2">Cn</a>' vs. '<a href="qh-optc.htm#Cn">C-n</a>').
+Qhull uses '-' as a flag to indicate pre-merging.</p>
+
+<p>Post-merging happens after the convex hull is built. During
+post-merging, Qhull repeatedly merges an independent set of
+non-convex facets. For a given set of parameters, the result is
+about as good as one can hope for.</p>
+
+<p>Pre-merging does the same thing as post-merging, except that
+it happens after adding each point to the convex hull. With
+pre-merging, Qhull guarantees a convex hull, but the facets are
+wider than those from post-merging. If a pre-merge option is not
+specified, Qhull handles machine round-off errors.</p>
+
+<p>You may see coplanar points appearing slightly outside
+the facets of the last example. This is becomes Geomview moves
+line segments forward toward the viewer. You can avoid the
+effect by setting 'lines closer' to '0' in Geomview's camera menu.
+
+<h3><a href="#merge">&#187;</a><a name="23">rbox 1000 | qconvex s
+Gcprvah C0.1 Qc &gt;eg.23.merge.cube</a></h3>
+
+<p>Here's the 3-d imprecise cube with all of the Geomview
+options. There's spheres for the vertices, radii for the coplanar
+points, dots for the interior points, hyperplane intersections,
+centrums, and inner and outer planes. The radii are shorter than
+the spheres because this uses post-merging ('<a href="qh-optc.htm#Cn2">C0.1</a>')
+instead of pre-merging.
+
+<h2><a href="#TOC">&#187;</a>4-d objects</h2>
+
+<p>With Qhull and Geomview you can develop an intuitive sense of
+4-d surfaces. When you get into trouble, think of viewing the
+surface of a 3-d sphere in a 2-d plane.</p>
+
+<h3><a href="#4d">&#187;</a><a name="24">rbox 5000 D4 | qconvex s GD0v
+Pd0:0.5 C-0.02 C0.1 &gt;eg.24.merge.cube.4d-in-3d</a></h3>
+
+<p>Here's one facet of the imprecise cube in 4-d. It's projected
+into 3-d (the '<a href="qh-optg.htm#GDn">GDn</a>' option drops
+dimension n). Each ridge consists of two triangles between this
+facet and the neighboring facet. In this case, Geomview displays
+the topological ridges, i.e., as triangles between three
+vertices. That is why the cube looks lopsided.</p>
+
+<h3><a href="#4d">&#187;</a><a name="30">rbox 5000 D4 | qconvex s
+C-0.02 C0.1 Gh &gt;eg.30.4d.merge.cube </a></h3>
+
+<p><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/4dcube.html">Here</a>
+is the equivalent in 4-d of the imprecise <a href="#06">square</a>
+and imprecise <a href="#23">cube</a>. It's the imprecise convex
+hull of 5000 random points in a hypercube. It's a full 4-d object
+so Geomview's <tt>ginsu </tt>does not work. If you view it in
+Geomview, you'll be inside the hypercube. To view 4-d objects
+directly, either load the <tt>4dview</tt> module or the <tt>ndview
+</tt>module. For <tt>4dview</tt>, you must have started Geomview
+in the same directory as the object. For <tt>ndview</tt>,
+initialize a set of windows with the prefab menu, and load the
+object through Geomview. The <tt>4dview</tt> module includes an
+option for slicing along any hyperplane. If you do this in the x,
+y, or z plane, you'll see the inside of a hypercube.</p>
+
+<p>The '<a href="qh-optg.htm#Gh">Gh</a>' option prints the
+geometric intersections between adjacent facets. Note the strong
+convexity constraint for post-merging ('<a href="qh-optc.htm#Cn2">C0.1</a>').
+It deletes the small facets.</p>
+
+<h3><a href="#4d">&#187;</a><a name="31">rbox 20 D3 | qdelaunay G
+&gt;eg.31.4d.delaunay </a></h3>
+
+<p>The Delaunay triangulation of 3-d sites corresponds to a 4-d
+convex hull. You can't see 4-d directly but each facet is a 3-d
+object that you can project to 3-d. This is exactly the same as
+projecting a 2-d facet of a soccer ball onto a plane.</p>
+
+<p>Here we see all of the facets together. You can use Geomview's
+<tt>ndview</tt> to look at the object from several directions.
+Try turning on edges in the appearance menu. You'll notice that
+some edges seem to disappear. That's because the object is
+actually two sets of overlapping facets.</p>
+
+<p>You can slice the object apart using Geomview's <tt>4dview</tt>.
+With <tt>4dview</tt>, try slicing along the w axis to get a
+single set of facets and then slice along the x axis to look
+inside. Another interesting picture is to slice away the equator
+in the w dimension.</p>
+
+<h3><a href="#4d">&#187;</a><a name="32">rbox 30 s D4 | qconvex s G
+Pd0d1d2D3</a></h3>
+
+<p>This is the positive octant of the convex hull of 30 4-d
+points. When looking at 4-d, it's easier to look at just a few
+facets at once. If you picked a facet that was directly above
+you, then that facet looks exactly the same in 3-d as it looks in
+4-d. If you pick several facets, then you need to imagine that
+the space of a facet is rotated relative to its neighbors. Try
+Geomview's <tt>ndview</tt> on this example.</p>
+
+<h2><a href="#TOC">&#187;</a>Halfspace intersections</h2>
+
+<h3><a href="#half">&#187;</a><a name="33a">rbox 10 r s Z1 G0.3 |
+qconvex G &gt;eg.33a.cone </a></h3>
+
+<h3><a href="#half">&#187;</a><a name="33b">rbox 10 r s Z1 G0.3 |
+qconvex FV n | qhalf G &gt;eg.33b.cone.dual</a></h3>
+
+<h3><a href="#half">&#187;</a><a name="33c">rbox 10 r s Z1 G0.3 |
+qconvex FV n | qhalf Fp | qconvex G &gt;eg.33c.cone.halfspace</a></h3>
+
+<p>These examples illustrate halfspace intersection. The first
+picture is the convex hull of two 20-gons plus an apex. The
+second picture is the dual of the first. Try loading <a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/half.html">both</a>
+at once. Each vertex of the second picture corresponds to a facet
+or halfspace of the first. The vertices with four edges
+correspond to a facet with four neighbors. Similarly the facets
+correspond to vertices. A facet's normal coefficients divided by
+its negative offset is the vertice's coordinates. The coordinates
+are the intersection of the original halfspaces. </p>
+
+<p>The third picture shows how Qhull can go back and forth
+between equivalent representations. It starts with a cone,
+generates the halfspaces that define each facet of the cone, and
+then intersects these halfspaces. Except for roundoff error, the
+third picture is a duplicate of the first. </p>
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home
+page for Qhull</a> <br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual: Table of Contents</a><br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To: </b><a href="#TOC">Qhull examples: Table of Contents</a> (please wait
+while loading)<br>
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-faq.htm b/xs/src/qhull/html/qh-faq.htm
new file mode 100644
index 000000000..feda544a7
--- /dev/null
+++ b/xs/src/qhull/html/qh-faq.htm
@@ -0,0 +1,1547 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<meta name="GENERATOR" content="Microsoft FrontPage 2.0">
+<title>Qhull FAQ</title>
+<!-- Navigation links
+NOTE -- verify all links by 'grep href=' 'grep name=' add # 'sort /+7'
+<base href> does not work since #TOC is relative to base instead of doc
+-->
+</head>
+
+<body>
+
+<p><a name="TOP"><b>Up:</b></a> <a
+ href="http://www.qhull.org">Home page</a> for Qhull
+(http://www.qhull.org)<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#TOC">FAQ: Table of Contents</a> (please
+wait while loading) <br>
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+ href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/4dcube.html"><IMG
+ align=middle alt ="[4-d cube]"
+ height=100 src="qh--4d.gif" width=100 ></a> Frequently Asked Questions about Qhull</h1><!--
+<p><i>This is the most recent FAQ. It was updated Sept. 13, 1999.</i>
+-->
+<p>If your question does not appear here, see: </p>
+
+<ul>
+ <li><a href="http://www.qhull.org/news">News</a> about Qhull
+ <li><a href="index.htm#TOC">Qhull manual:</a> table of contents
+ <li><a href="../README.txt">Installation</a> instructions for Qhull and rbox
+
+ <li><a href="mailto:qhull@qhull.org">Send e-mail</a> to
+ qhull@qhull.org
+ <li><a href="mailto:qhull_bug@qhull.org">Report bugs</a>
+ to qhull_bug@qhull.org </li>
+</ul>
+
+<p>Qhull is a general dimension code for computing convex hulls,
+Delaunay triangulations, halfspace intersections about a point,
+Voronoi diagrams, furthest-site Delaunay triangulations, and
+furthest-site Voronoi diagrams. These structures have
+applications in science, engineering, statistics, and
+mathematics. For a detailed introduction, see O'Rourke [<a
+ href="index.htm#orou94" >'94</a>], <i>Computational Geometry in C</i>.
+</p>
+
+<p>There are separate programs for each application of
+Qhull. These programs disable experimental and inappropriate
+options. If you prefer, you may use Qhull directly. All programs
+run the same code.
+
+<p>Version 3.1 added triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>').
+It should be used for Delaunay triangulations instead of
+using joggled input ('<a href="qh-optq.htm#QJn">QJ</a>').
+
+<p><i>Brad Barber, Arlington MA,
+2010/01/09 <!--
+--> </i></p>
+
+<p><b>Copyright &copy; 1998-2015 C.B. Barber</b></p>
+
+<hr>
+
+<h2><a href="#TOP">&#187;</a><a name="TOC">FAQ: Table of Contents </a></h2>
+
+<p>Within each category, the most recently asked questions are
+first.
+<ul>
+ <li>Startup questions <ul>
+ <li><a href="#console">How</a> do I run Qhull from Windows?
+ <li><a href="#input">How</a> do I enter points for Qhull?
+ <li><a href="#learn">How</a> do I learn to use Qhull?</li>
+ </ul>
+ <li>Convex hull questions<ul>
+ <li><a href="#area">How</a> do I report just the area and volume of a
+ convex hull?
+ <li><a href="#extra">Why</a> are there extra points in a 4-d or higher
+ convex hull?
+ <li><a href="#dup">How</a> do I report duplicate
+ vertices? </li>
+ </ul>
+ <li>Delaunay triangulation questions<ul>
+ <li><a href="#flat">How</a> do I get rid of nearly flat Delaunay
+ triangles?
+ <li><a href="#vclosest">How</a> do I find the Delaunay triangle or Voronoi
+ region that is closest to a point?
+
+ <li><a href="#mesh">How</a> do I compute the Delaunay triangulation of a
+ non-convex object?
+
+ <li><a href="#mesh">How</a> do I mesh a volume from a set of triangulated
+ surface points?
+
+ <li><a href="#constrained">Can</a> Qhull produce a triangular mesh for an
+ object?
+
+ <li><a href="#dridges">For</a> 3-d Delaunay triangulations, how do I
+ report the triangles of each tetrahedron?
+
+ <li><a href="#3dd">How</a> do I construct a 3-d Delaunay triangulation?
+ <li><a href="#2d">How</a> do I get the triangles for a 2-d Delaunay
+ triangulation and the vertices of its Voronoi diagram?
+ <li><a href="#big">Can </a>Qhull triangulate a
+ hundred 16-d points?</li>
+ </ul>
+
+ <li>Voronoi diagram questions<ul>
+ <li>See also "Delaunay diagram questions". Qhull computes the Voronoi diagram from the Delaunay triagulation.
+ <li><a href="#volume">How</a> do I compute the volume of a Voronoi region?
+ <li><a href="#maxsphere">How</a> do I get the radii of the empty
+ spheres for each Voronoi vertex?
+
+ <li><a href="#square">What</a> is the Voronoi diagram of a square?
+
+ <li><a href="#vsphere">How</a> do I construct the Voronoi diagram of
+ cospherical points?
+ <li><a href="#rays">Can</a> Qhull compute the unbounded rays of the
+ Voronoi diagram?
+ </ul>
+ <li>Approximation questions<ul>
+ <li><a href="#simplex">How</a> do I approximate data
+ with a simplex?</li>
+ </ul>
+ <li>Halfspace questions<ul>
+ <li><a href="#halfspace">How</a> do I compute the
+ intersection of halfspaces with Qhull?</li>
+ </ul>
+ <li><a name="library">Qhull library</a> questions<ul>
+ <li><a href="#math">Is</a> Qhull available for Mathematica, Matlab, or
+ Maple?
+
+ <li><a href="#ridges">Why</a> are there too few ridges?
+ <li><a href="#call">Can</a> Qhull use coordinates without placing them in
+ a data file?
+ <li><a href="#size">How</a> large are Qhull's data structures?
+ <li><a href="#inc">Can</a> Qhull construct convex hulls and Delaunay
+ triangulations one point at a time?
+ <li><a href="#ridges2">How</a> do I visit the ridges of a Delaunay
+ triangulation?
+ <li><a href="#listd">How</a> do I visit the Delaunay facets?
+ <LI><a
+ href="#outside">When</a> is a point outside or inside a facet?
+ <li><a href="#closest">How</a> do I find the facet that is closest to a
+ point?
+ <li><a href="#vclosest">How</a> do I find the Delaunay triangle or Voronoi
+ region that is closest to a point?
+ <li><a href="#vertices">How</a> do I list the vertices?
+ <li><a href="#test">How</a> do I test code that uses the Qhull library?
+ <li><a href="#orient">When</a> I compute a plane
+ equation from a facet, I sometimes get an
+ outward-pointing normal and sometimes an
+ inward-pointing normal</li>
+ </ul>
+ </li>
+</ul>
+
+<hr>
+
+<h2><a href="#TOC">&#187;</a><a name="startup">Startup</a> questions</h2>
+
+<h4><a href="#TOC">&#187;</a><a name="console">How</a> do I run Qhull
+from Windows?</h4><blockquote>
+
+<p>Qhull is a console program. You will first need a command window
+(i.e., a "command prompt"). You can double click on
+'eg\Qhull-go.bat'. </p>
+
+<blockquote><ul>
+ <li>Type 'qconvex', 'qdelaunay', 'qhalf', 'qvoronoi,
+ 'qhull', and 'rbox' for a synopsis of each program.
+
+ <li>Type 'rbox c D2 | qconvex s i' to compute the
+ convex hull of a square.
+
+ <li>Type 'rbox c D2 | qconvex s i TO results.txt' to
+ write the results to the file 'results.txt'. A summary is still printed on
+ the the console.
+
+ <li>Type 'rbox c D2' to see the input format for
+ qconvex.
+
+ <li>Type 'qconvex &lt; data.txt s i TO results.txt' to
+ read input data from 'data.txt'.
+
+ <li>If you want to enter data by hand, type 'qconvex s i TO
+ results.txt' to read input data from the console. Type in
+ the numbers and end with a ctrl-D. </li>
+</ul></blockquote>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="input">How</a> do I enter
+points for Qhull?</h4><blockquote>
+
+<p>Qhull takes its data from standard input. For example, create
+a file named 'data.txt' with the following contents: </p>
+
+<blockquote>
+ <pre>
+2 #sample 2-d input
+5 #number of points
+1 2 #coordinates of points
+-1.1 3
+3 2.2
+4 5
+-10 -10
+</pre>
+</blockquote>
+
+<p>Then call qconvex with 'qconvex &lt; data.txt'. It will print a
+summary of the convex hull. Use 'qconvex &lt; data.txt o' to print
+the vertices and edges. See also <a href="index.htm#input">input
+format</a>. </p>
+
+<p>You can generate sample data with rbox, e.g., 'rbox 10'
+generates 10 random points in 3-d. Use a pipe ('|') to run rbox
+and qhull together, e.g., </p>
+
+<blockquote>
+ <p>rbox c | qconvex o </p>
+</blockquote>
+
+<p>computes the convex hull of a cube. </p>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="learn">How</a> do I learn to
+use Qhull?</h4><blockquote>
+
+<p>First read: </p>
+
+<ul>
+ <li><a href="index.htm">Introduction</a> to Qhull
+ <li><a href="index.htm#when">When</a> to use Qhull
+ <li><a href="qconvex.htm">qconvex</a> -- convex hull
+ <li><a href="qdelaun.htm">qdelaunay</a> -- Delaunay triangulation
+ <li><a href="qhalf.htm">qhalf</a> -- half-space intersection about a point
+
+ <li><a href="qvoronoi.htm">qvoronoi</a> -- Voronoi diagram
+ <li><a href="rbox.htm">Rbox</a>, for sample inputs
+ <li><a href="qh-eg.htm">Examples</a> of Qhull</li>
+</ul>
+
+<p>Look at Qhull's on-line documentation: </p>
+
+<ul>
+ <li>'qconvex' gives a synopsis of qconvex and its options
+
+ <li>'rbox' lists all of the options for generating point
+ sets
+ <li>'qconvex - | more' lists the options for qconvex
+ <li>'qconvex .' gives a concise list of options
+ <li>'qdelaunay', 'qhalf', 'qvoronoi', and 'qhull' also have a synopsis and option list</li>
+</ul>
+
+<p>Then try out the Qhull programs on small examples. </p>
+
+<ul>
+ <li>'rbox c' lists the vertices of a cube
+ <li>'rbox c | qconvex' is the convex hull of a cube
+ <li>'rbox c | qconvex o' lists the vertices and facets of
+ a cube
+ <li>'rbox c | qconvex Qt o' triangulates the cube
+ <li>'rbox c | qconvex QJ o' joggles the input and
+ triangulates the cube
+ <li>'rbox c D2 | qconvex' generates the convex hull of a
+ square
+ <li>'rbox c D4 | qconvex' generates the convex hull of a
+ hypercube
+ <li>'rbox 6 s D2 | qconvex p Fx' lists 6 random points in
+ a circle and lists the vertices of their convex hull in order
+ <li>'rbox c D2 c G2 | qdelaunay' computes the Delaunay
+ triangulation of two embedded squares. It merges the cospherical facets.
+ <li>'rbox c D2 c G2 | qdelaunay Qt' computes the Delaunay
+ triangulation of two embedded squares. It triangulates the cospherical facets.
+ <li>'rbox c D2 c G2 | qvoronoi o' computes the
+ corresponding Voronoi vertices and regions.
+ <li>'rbox c D2 c G2 | qvoronio Fv' shows the Voronoi diagram
+ for the previous example. Each line is one edge of the
+ diagram. The first number is 4, the next two numbers list
+ a pair of input sites, and the last two numbers list the
+ corresponding pair of Voronoi vertices. </li>
+</ul>
+
+<p>Install <a href="http://www.geomview.org">Geomview</a>
+if you are running SGI Irix, Solaris, SunOS, Linux, HP, IBM
+RS/6000, DEC Alpha, or Next. You can then visualize the output of
+Qhull. Qhull comes with Geomview <a href="qh-eg.htm">examples</a>.
+</p>
+
+<p>Then try Qhull with a small example of your application. Work
+out the results by hand. Then experiment with Qhull's options to
+find the ones that you need. </p>
+
+<p>You will need to decide how Qhull should handle precision
+problems. It can triangulate the output ('<a
+ href="qh-optq.htm#Qt" >Qt</a>'), joggle the input ('<a
+ href="qh-optq.htm#QJn" >QJ</a>'), or merge facets (the default). </p>
+
+<ul>
+ <li>With joggle, Qhull produces simplicial (i.e.,
+ triangular) output by joggling the input. After joggle,
+ no points are cocircular or cospherical.
+ <li>With facet merging, Qhull produces a better
+ approximation and does not modify the input.
+ <li>With triangulated output, Qhull merges facets and triangulates
+ the result.</li>
+ <li>See <a href="qh-impre.htm#joggle">Merged facets or joggled input</a>. </li>
+</ul>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a><a name="convex">Convex hull questions</a></h2>
+
+<h4><a href="#TOC">&#187;</a><a name="area">How</a> do I report just the area
+ and volume of a convex hull?</h4><blockquote>
+
+Use option 'FS'. For example,
+
+<blockquote><pre>
+C:\qhull>rbox 10 | qconvex FS
+0
+2 2.192915621644613 0.2027867899638665
+
+C:\qhull>rbox 10 | qconvex FA
+
+Convex hull of 10 points in 3-d:
+
+ Number of vertices: 10
+ Number of facets: 16
+
+Statistics for: RBOX 10 | QCONVEX FA
+
+ Number of points processed: 10
+ Number of hyperplanes created: 28
+ Number of distance tests for qhull: 44
+ CPU seconds to compute hull (after input): 0
+ Total facet area: 2.1929156
+ Total volume: 0.20278679
+</pre></blockquote>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="extra">Why</a> are there extra
+points in a 4-d or higher convex hull?</h4><blockquote>
+
+<p>You may see extra points if you use options '<a
+ href="qh-opto.htm#i" >i</a>' or '<a href="qh-optf.htm#Ft">Ft</a>'
+ without using triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>').
+The extra points occur when a facet is non-simplicial (i.e., a
+facet with more than <i>d</i> vertices). For example, Qhull
+reports the following for one facet of the convex hull of a hypercube.
+Option 'Pd0:0.5' returns the facet along the positive-x axis: </p>
+
+<blockquote>
+ <pre>
+rbox c D4 | qconvex i Pd0:0.5
+12
+17 13 14 15
+17 13 12 14
+17 11 13 15
+17 14 11 15
+17 10 11 14
+17 14 12 8
+17 12 13 8
+17 10 14 8
+17 11 10 8
+17 13 9 8
+17 9 11 8
+17 11 9 13
+</pre>
+</blockquote>
+
+<p>The 4-d hypercube has 16 vertices; so point "17" was
+added by qconvex. Qhull adds the point in order to report a
+simplicial decomposition of the facet. The point corresponds to
+the "centrum" which Qhull computes to test for
+convexity. </p>
+
+<p>Triangulate the output ('<a href="qh-optq.htm#Qt">Qt</a>') to avoid the extra points.
+Since the hypercube is 4-d, each simplicial facet is a tetrahedron.
+<blockquote>
+<pre>
+C:\qhull3.1>rbox c D4 | qconvex i Pd0:0.5 Qt
+9
+9 13 14 15
+12 9 13 14
+9 11 13 15
+11 9 14 15
+9 10 11 14
+12 9 14 8
+9 12 13 8
+9 10 14 8
+10 9 11 8
+</pre>
+</blockquote>
+
+<p>Use the '<a href="qh-optf.htm#Fv">Fv</a>' option to print the
+vertices of simplicial and non-simplicial facets. For example,
+here is the same hypercube facet with option 'Fv' instead of 'i':
+</p>
+
+<blockquote>
+ <pre>
+C:\qhull&gt;rbox c D4 | qconvex Pd0:0.5 Fv
+1
+8 9 10 12 11 13 14 15 8
+</pre>
+</blockquote>
+
+<p>The coordinates of the extra point are printed with the '<A
+ href="qh-optf.htm#Ft" >Ft</a>' option. </p>
+
+<blockquote>
+ <pre>
+rbox c D4 | qconvex Pd0:0.5 Ft
+4
+17 12 3
+ -0.5 -0.5 -0.5 -0.5
+ -0.5 -0.5 -0.5 0.5
+ -0.5 -0.5 0.5 -0.5
+ -0.5 -0.5 0.5 0.5
+ -0.5 0.5 -0.5 -0.5
+ -0.5 0.5 -0.5 0.5
+ -0.5 0.5 0.5 -0.5
+ -0.5 0.5 0.5 0.5
+ 0.5 -0.5 -0.5 -0.5
+ 0.5 -0.5 -0.5 0.5
+ 0.5 -0.5 0.5 -0.5
+ 0.5 -0.5 0.5 0.5
+ 0.5 0.5 -0.5 -0.5
+ 0.5 0.5 -0.5 0.5
+ 0.5 0.5 0.5 -0.5
+ 0.5 0.5 0.5 0.5
+ 0.5 0 0 0
+4 16 13 14 15
+4 16 13 12 14
+4 16 11 13 15
+4 16 14 11 15
+4 16 10 11 14
+4 16 14 12 8
+4 16 12 13 8
+4 16 10 14 8
+4 16 11 10 8
+4 16 13 9 8
+4 16 9 11 8
+4 16 11 9 13
+</pre>
+</blockquote>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="dup">How</a> do I report
+duplicate vertices?</h4><blockquote>
+
+<p>There's no direct way. You can use option
+'<a href="qh-optf.htm#FP">FP</a>' to
+report the distance to the nearest vertex for coplanar input
+points. Select the minimum distance for a duplicated vertex, and
+locate all input sites less than this distance. </p>
+
+<p>For Delaunay triangulations, all coplanar points are nearly
+incident to a vertex. If you want a report of coincident input
+sites, do not use option '<a href="qh-optq.htm#QJn">QJ</a>'. By
+adding a small random quantity to each input coordinate, it
+prevents coincident input sites. </p>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a><a name="delaunay">Delaunay triangulation questions</a></h2>
+
+<h4><a href="#TOC">&#187;</a><a name="flat">How</a> do I get rid of
+nearly flat Delaunay triangles?</h4><blockquote>
+
+<p>Nearly flat triangles occur when boundary points are nearly
+collinear or coplanar. They also occur for nearly coincident
+points. Both events can easily occur when using joggle. For example
+(rbox 10 W0 D2 | qdelaunay QJ Fa) lists the areas of the Delaunay
+triangles of 10 points on the boundary of a square. Some of
+these triangles are nearly flat. This occurs when one point
+is joggled inside of two other points. In this case, nearly flat
+triangles do not occur with triangulated output (rbox 10 W0 D2 | qdelaunay Qt Fa).
+
+
+<p>Another example, (rbox c P0 P0 D2 | qdelaunay QJ Fa), computes the
+areas of the Delaunay triangles for the unit square and two
+instances of the origin. Four of the triangles have an area
+of 0.25 while two have an area of 2.0e-11. The later are due to
+the duplicated origin. With triangulated output (rbox c P0 P0 D2 | qdelaunay Qt Fa)
+there are four triangles of equal area.
+
+<p>Nearly flat triangles also occur without using joggle. For
+example, (rbox c P0 P0,0.4999999999 | qdelaunay Fa), computes
+the areas of the Delaunay triangles for the unit square,
+a nearly collinear point, and the origin. One triangle has an
+area of 3.3e-11.
+
+<p>Unfortunately, none of Qhull's merging options remove nearly
+flat Delaunay triangles due to nearly collinear or coplanar boundary
+points.
+The merging options concern the empty circumsphere
+property of Delaunay triangles. This is independent of the area of
+the Delaunay triangles. Qhull does handle nearly coincident points.
+
+<p>If you are calling Qhull from a program, you can merge slivers into an adjacent facet.
+In d dimensions with simplicial facets (e.g., from 'Qt'), each facet has
+d+1 neighbors. Each neighbor shares d vertices of the facet's d+1 vertices. Let the
+other vertex be the <i>opposite</i> vertex. For each neighboring facet, if its circumsphere
+includes the opposite.vertex, the two facets can be merged. [M. Treacy]
+
+<p>You can handle collinear or coplanar boundary points by
+enclosing the points in a box. For example,
+(rbox c P0 P0,0.4999999999 c G1 | qdelaunay Fa), surrounds the
+previous points with [(1,1), (1,-1), (-1,-1), (-1, 1)].
+Its Delaunay triangulation does not include a
+nearly flat triangle. The box also simplifies the graphical
+output from Qhull.
+
+<p>Without joggle, Qhull lists coincident points as "coplanar"
+points. For example, (rbox c P0 P0 D2 | qdelaunay Fa), ignores
+the duplicated origin and lists four triangles of size 0.25.
+Use 'Fc' to list the coincident points (e.g.,
+rbox c P0 P0 D2 | qdelaunay Fc).
+
+<p>There is no easy way to determine coincident points with joggle.
+Joggle removes all coincident, cocircular, and cospherical points
+before running Qhull. Instead use facet merging (the default)
+or triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>').
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="mesh">How</a> do I compute
+the Delaunay triangulation of a non-convex object?</h4><blockquote>
+
+<p>A similar question is
+"How do I mesh a volume from a set of triangulated surface points?"
+
+<p>This is an instance of the constrained Delaunay Triangulation
+problem. Qhull does not handle constraints. The boundary of the
+Delaunay triangulation is always convex. But if the input set
+contains enough points, the triangulation will include the
+boundary. The number of points needed depends on the input.
+
+<p>Shewchuk has developed a theory of constrained Delaunay triangulations.
+See his
+<a href="http://www.cs.cmu.edu/~jrs/jrspapers.html#cdt">paper</a> at the
+1998 Computational Geometry Conference. Using these ideas, constraints
+could be added to Qhull. They would have many applications.
+
+<p>There is a large literature on mesh generation and many commercial
+offerings. For pointers see
+<a href="http://www.imr.sandia.gov/papers/topics.html">Owen's International Meshing Roundtable</a>
+and <a href="http://www.robertschneiders.de/meshgeneration/meshgeneration.html">Schneiders'
+Finite Element Mesh Generation page</a>.</p>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="constrained">Can</a> Qhull
+produce a triangular mesh for an object?</h4><blockquote>
+
+<p>Yes for convex objects, no for non-convex objects. For
+non-convex objects, it triangulates the concavities. Unless the
+object has many points on its surface, triangles may cross the
+surface. </p>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="dridges">For</a> 3-d Delaunay
+triangulations, how do I report the triangles of each
+tetrahedron?</h4><blockquote>
+
+<p>For points in general position, a 3-d Delaunay triangulation
+generates tetrahedron. Each face of a tetrahedron is a triangle.
+For example, the 3-d Delaunay triangulation of random points on
+the surface of a cube, is a cellular structure of tetrahedron. </p>
+
+<p>Use triangulated output ('qdelaunay Qt i') or joggled input ('qdelaunay QJ i')
+to generate the Delaunay triangulation.
+Option 'i' reports each tetrahedron. The triangles are
+every combination of 3 vertices. Each triangle is a
+"ridge" of the Delaunay triangulation. </p>
+
+<p>For example, </p>
+
+<pre>
+ rbox 10 | qdelaunay Qt i
+ 14
+ 9 5 8 7
+ 0 9 8 7
+ 5 3 8 7
+ 3 0 8 7
+ 5 4 8 1
+ 4 6 8 1
+ 2 9 5 8
+ 4 2 5 8
+ 4 2 9 5
+ 6 2 4 8
+ 9 2 0 8
+ 2 6 0 8
+ 2 4 9 1
+ 2 6 4 1
+</pre>
+
+<p>is the Delaunay triangulation of 10 random points. Ridge 9-5-8
+occurs twice. Once for tetrahedron 9 5 8 7 and the other for
+tetrahedron 2 9 5 8. </p>
+
+<p>You can also use the Qhull library to generate the triangles.
+See "<a href="#ridges2">How</a> do I visit the ridges of a
+Delaunay triangulation?"</p>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="3dd">How</a> do I construct a
+3-d Delaunay triangulation?</h4><blockquote>
+
+<p>For 3-d Delaunay triangulations with cospherical input sites,
+use triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>') or
+joggled input ('<a href="qh-optq.htm#QJn">QJ</a>'). Otherwise
+option 'i' will
+triangulate non-simplicial facets by adding a point to the facet.
+
+<p>If you want non-simplicial output for cospherical sites, use
+option
+'<a href="qh-optf.htm#Fv">Fv</a>' or '<a href="qh-opto.htm#o">o</a>'.
+For option 'o', ignore the last coordinate. It is the lifted
+coordinate for the corresponding convex hull in 4-d.
+
+<p>The following example is a cube
+inside a tetrahedron. The 8-vertex facet is the cube. Ignore the
+last coordinates. </p>
+
+<blockquote>
+ <pre>
+C:\qhull&gt;rbox r y c G0.1 | qdelaunay Fv
+4
+12 20 44
+ 0.5 0 0 0.3055555555555555
+ 0 0.5 0 0.3055555555555555
+ 0 0 0.5 0.3055555555555555
+ -0.5 -0.5 -0.5 0.9999999999999999
+ -0.1 -0.1 -0.1 -6.938893903907228e-018
+ -0.1 -0.1 0.1 -6.938893903907228e-018
+ -0.1 0.1 -0.1 -6.938893903907228e-018
+ -0.1 0.1 0.1 -6.938893903907228e-018
+ 0.1 -0.1 -0.1 -6.938893903907228e-018
+ 0.1 -0.1 0.1 -6.938893903907228e-018
+ 0.1 0.1 -0.1 -6.938893903907228e-018
+ 0.1 0.1 0.1 -6.938893903907228e-018
+4 2 11 1 0
+4 10 1 0 3
+4 11 10 1 0
+4 2 9 0 3
+4 9 11 2 0
+4 7 2 1 3
+4 11 7 2 1
+4 8 10 0 3
+4 9 8 0 3
+5 8 9 10 11 0
+4 10 6 1 3
+4 6 7 1 3
+5 6 8 10 4 3
+5 6 7 10 11 1
+4 5 9 2 3
+4 7 5 2 3
+5 5 8 9 4 3
+5 5 6 7 4 3
+8 5 6 8 7 9 10 11 4
+5 5 7 9 11 2
+</pre>
+</blockquote>
+
+<p>If you want simplicial output use options
+'<a href="qh-optq.htm#Qt">Qt</a> <A
+ href="qh-optf.htm#Ft" >i</a>' or
+'<a href="qh-optq.htm#QJn">QJ</a> <A
+ href="qh-optf.htm#Ft" >i</a>', e.g.,
+</p>
+
+<blockquote>
+ <pre>
+rbox r y c G0.1 | qdelaunay Qt i
+31
+2 11 1 0
+11 10 1 0
+9 11 2 0
+11 7 2 1
+8 10 0 3
+9 8 0 3
+10 6 1 3
+6 7 1 3
+5 9 2 3
+7 5 2 3
+9 8 10 11
+8 10 11 0
+9 8 11 0
+6 8 10 4
+8 6 10 3
+6 8 4 3
+6 7 10 11
+10 6 11 1
+6 7 11 1
+8 5 4 3
+5 8 9 3
+5 6 4 3
+6 5 7 3
+5 9 10 11
+8 5 9 10
+7 5 10 11
+5 6 7 10
+8 5 10 4
+5 6 10 4
+5 9 11 2
+7 5 11 2
+</pre>
+</blockquote>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="2d">How</a> do I get the
+triangles for a 2-d Delaunay triangulation and the vertices of
+its Voronoi diagram?</h4><blockquote>
+
+<p>To compute the Delaunay triangles indexed by the indices of
+the input sites, use </p>
+
+<blockquote>
+ <p>rbox 10 D2 | qdelaunay Qt i </p>
+</blockquote>
+
+<p>To compute the Voronoi vertices and the Voronoi region for
+each input site, use </p>
+
+<blockquote>
+ <p>rbox 10 D2 | qvoronoi o </p>
+</blockquote>
+
+<p>To compute each edge ("ridge") of the Voronoi
+diagram for each pair of adjacent input sites, use</p>
+
+<blockquote>
+ <p>rbox 10 D2 | qvoronoi Fv </p>
+</blockquote>
+
+<p>To compute the area and volume of the Voronoi region for input site 5 (site 0 is the first one),
+use </p>
+
+<blockquote>
+ <p>rbox 10 D2 | qvoronoi QV5 p | qconvex s FS </p>
+</blockquote>
+
+<p>To compute the lines ("hyperplanes") that define the
+Voronoi region for input site 5, use </p>
+
+<blockquote>
+ <p>rbox 10 D2 | qvoronoi QV5 p | qconvex n </p>
+</blockquote>
+or
+<blockquote>
+ <p>rbox 10 D2 | qvoronoi QV5 Fi Fo</p>
+</blockquote>
+
+<p>To list the extreme points of the input sites use </p>
+
+<blockquote>
+ <p>rbox 10 D2 | qdelaunay Fx </p>
+</blockquote>
+
+<p>You will get the same point ids with </p>
+
+<blockquote>
+ <p>rbox 10 D2 | qconvex Fx </p>
+</blockquote>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="big">Can </a>Qhull triangulate
+a hundred 16-d points?</h4><blockquote>
+
+<p>No. This is an immense structure. A triangulation of 19, 16-d
+points has 43 simplices. If you add one point at a time, the
+triangulation increased as follows: 43, 189, 523, 1289, 2830,
+6071, 11410, 20487. The last triangulation for 26 points used 13
+megabytes of memory. When Qhull uses virtual memory, it becomes
+too slow to use. </p>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a><a name="voronoi">Voronoi
+diagram questions</a></h2>
+
+<h4><a href="#TOC">&#187;</a><a name="volume">How</a> do I compute the volume of a Voronoi region?</h4><blockquote>
+
+<p>For each Voronoi region, compute the convex hull of the region's Voronoi vertices. The volume of each convex hull is the volume
+of the corresponding Vornoi region.</p>
+
+<p>For example, to compute the volume of the bounded Voronoi region about [0,0,0]: output the origin's Voronoi vertices and
+compute the volume of their convex hull. The last number from option '<a href="qh-optf.htm#FS">FS</a>' is the volume.</p>
+<blockquote><pre>
+rbox P0 10 | qvoronoi QV0 p | qhull FS
+0
+2 1.448134756744281 0.1067973560800857
+</pre></blockquote>
+
+<p>For another example, see <a href="#2d">How</a> do I get the triangles for a 2-d Delaunay
+ triangulation and the vertices of its Voronoi diagram?</p>
+
+<p>This approach is slow if you are using the command line. A faster approcach is to call Qhull from
+a program. The fastest method is Clarkson's <a href="http://www.netlib.org/voronoi/hull.html">hull</a> program.
+It computes the volume for all Voronoi regions.</p>
+
+<p>An unbounded Voronoi region does not have a volume.</p>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="maxsphere">How</a> do I get the radii of the empty
+ spheres for each Voronoi vertex?</h4><blockquote>
+
+Use option '<a href="qh-optf.htm#Fi">Fi</a>' to list each bisector (i.e. Delaunay ridge). Then compute the
+minimum distance for each Voronoi vertex.
+
+<p>There's other ways to get the same information. Let me know if you
+find a better method.
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="square">What</a> is the Voronoi diagram
+ of a square?</h4><blockquote>
+
+<p>
+Consider a square,
+<blockquote><pre>
+C:\qhull&gt;rbox c D2
+2 RBOX c D2
+4
+ -0.5 -0.5
+ -0.5 0.5
+ 0.5 -0.5
+ 0.5 0.5
+</pre></blockquote>
+
+<p>There's two ways to compute the Voronoi diagram: with facet merging
+or with joggle. With facet merging, the
+result is:
+
+<blockquote><pre>
+C:\qhull&gt;rbox c D2 | qvoronoi Qz
+
+Voronoi diagram by the convex hull of 5 points in 3-d:
+
+ Number of Voronoi regions and at-infinity: 5
+ Number of Voronoi vertices: 1
+ Number of facets in hull: 5
+
+Statistics for: RBOX c D2 | QVORONOI Qz
+
+ Number of points processed: 5
+ Number of hyperplanes created: 7
+ Number of distance tests for qhull: 8
+ Number of merged facets: 1
+ Number of distance tests for merging: 29
+ CPU seconds to compute hull (after input): 0
+
+C:\qhull&gt;rbox c D2 | qvoronoi Qz o
+2
+2 5 1
+-10.101 -10.101
+ 0 0
+2 0 1
+2 0 1
+2 0 1
+2 0 1
+0
+
+C:\qhull&gt;rbox c D2 | qvoronoi Qz Fv
+4
+4 0 1 0 1
+4 0 2 0 1
+4 1 3 0 1
+4 2 3 0 1
+</pre></blockquote>
+
+<p>There is one Voronoi vertex at the origin and rays from the origin
+along each of the coordinate axes.
+The last line '4 2 3 0 1' means that there is
+a ray that bisects input points #2 and #3 from infinity (vertex 0) to
+the origin (vertex 1).
+Option 'Qz' adds an artificial point since the input is cocircular.
+Coordinates -10.101 indicate the
+vertex at infinity.
+
+<p>With triangulated output, the Voronoi vertex is
+duplicated:
+
+<blockquote><pre>
+C:\qhull3.1>rbox c D2 | qvoronoi Qt Qz
+
+Voronoi diagram by the convex hull of 5 points in 3-d:
+
+ Number of Voronoi regions and at-infinity: 5
+ Number of Voronoi vertices: 2
+ Number of triangulated facets: 1
+
+Statistics for: RBOX c D2 | QVORONOI Qt Qz
+
+ Number of points processed: 5
+ Number of hyperplanes created: 7
+ Number of facets in hull: 6
+ Number of distance tests for qhull: 8
+ Number of distance tests for merging: 33
+ Number of distance tests for checking: 30
+ Number of merged facets: 1
+ CPU seconds to compute hull (after input): 0.05
+
+C:\qhull3.1>rbox c D2 | qvoronoi Qt Qz o
+2
+3 5 1
+-10.101 -10.101
+ 0 0
+ 0 0
+3 2 0 1
+2 1 0
+2 2 0
+3 2 0 1
+0
+
+C:\qhull3.1>rbox c D2 | qvoronoi Qt Qz Fv
+4
+4 0 2 0 2
+4 0 1 0 1
+4 1 3 0 1
+4 2 3 0 2
+</pre></blockquote>
+
+
+<p>With joggle, the input is no longer cocircular and the Voronoi vertex is
+split into two:
+
+<blockquote><pre>
+C:\qhull&gt;rbox c D2 | qvoronoi Qt Qz
+
+C:\qhull&gt;rbox c D2 | qvoronoi QJ o
+2
+3 4 1
+-10.101 -10.101
+-4.71511718558304e-012 -1.775812830118184e-011
+9.020340030474472e-012 -4.02267108512433e-012
+2 0 1
+3 2 1 0
+3 2 0 1
+2 2 0
+
+C:\qhull&gt;rbox c D2 | qvoronoi QJ Fv
+5
+4 0 2 0 1
+4 0 1 0 1
+4 1 2 1 2
+4 1 3 0 2
+4 2 3 0 2
+</pre></blockquote>
+
+<p>Note that the Voronoi diagram includes the same rays as
+ before plus a short edge between the two vertices.</p>
+
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="vsphere">How</a> do I construct
+the Voronoi diagram of cospherical points?</h4><blockquote>
+
+<p>Three-d terrain data can be approximated with cospherical
+points. The Delaunay triangulation of cospherical points is the
+same as their convex hull. If the points lie on the unit sphere,
+the facet normals are the Voronoi vertices [via S. Fortune]. </p>
+
+<p>For example, consider the points {[1,0,0], [-1,0,0], [0,1,0],
+...}. Their convex hull is: </p>
+
+<pre>
+rbox d G1 | qconvex o
+3
+6 8 12
+ 0 0 -1
+ 0 0 1
+ 0 -1 0
+ 0 1 0
+ -1 0 0
+ 1 0 0
+3 3 1 4
+3 1 3 5
+3 0 3 4
+3 3 0 5
+3 2 1 5
+3 1 2 4
+3 2 0 4
+3 0 2 5
+</pre>
+
+<p>The facet normals are: </p>
+
+<pre>
+rbox d G1 | qconvex n
+4
+8
+-0.5773502691896258 0.5773502691896258 0.5773502691896258 -0.5773502691896258
+ 0.5773502691896258 0.5773502691896258 0.5773502691896258 -0.5773502691896258
+-0.5773502691896258 0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+ 0.5773502691896258 0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+ 0.5773502691896258 -0.5773502691896258 0.5773502691896258 -0.5773502691896258
+-0.5773502691896258 -0.5773502691896258 0.5773502691896258 -0.5773502691896258
+-0.5773502691896258 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+ 0.5773502691896258 -0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+</pre>
+
+<p>If you drop the offset from each line (the last number), each
+line is the Voronoi vertex for the corresponding facet. The
+neighboring facets for each point define the Voronoi region for
+each point. For example: </p>
+
+<pre>
+rbox d G1 | qconvex FN
+6
+4 7 3 2 6
+4 5 0 1 4
+4 7 4 5 6
+4 3 1 0 2
+4 6 2 0 5
+4 7 3 1 4
+</pre>
+
+<p>The Voronoi vertices {7, 3, 2, 6} define the Voronoi region
+for point 0. Point 0 is [0,0,-1]. Its Voronoi vertices are </p>
+
+<pre>
+-0.5773502691896258 0.5773502691896258 -0.5773502691896258
+ 0.5773502691896258 0.5773502691896258 -0.5773502691896258
+-0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+ 0.5773502691896258 -0.5773502691896258 -0.5773502691896258
+</pre>
+
+<p>In this case, the Voronoi vertices are oriented, but in
+general they are unordered. </p>
+
+<p>By taking the dual of the Delaunay triangulation, you can
+construct the Voronoi diagram. For cospherical points, the convex
+hull vertices for each facet, define the input sites for each
+Voronoi vertex. In 3-d, the input sites are oriented. For
+example: </p>
+
+<pre>
+rbox d G1 | qconvex i
+8
+3 1 4
+1 3 5
+0 3 4
+3 0 5
+2 1 5
+1 2 4
+2 0 4
+0 2 5
+</pre>
+
+<p>The convex hull vertices for facet 0 are {3, 1, 4}. So Voronoi
+vertex 0 (i.e., [-0.577, 0.577, 0.577]) is the Voronoi vertex for
+input sites {3, 1, 4} (i.e., {[0,1,0], [0,0,1], [-1,0,0]}). </p>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="rays">Can</a> Qhull compute the
+unbounded rays of the Voronoi diagram?</h4><blockquote>
+
+<p>Use '<a href="qh-optf.htm#Fo2">Fo</a>' to compute the separating
+hyperplanes for unbounded Voronoi regions. The corresponding ray
+goes to infinity from the Voronoi vertices. If you enclose the
+input sites in a large enough box, the outermost bounded regions
+will represent the unbounded regions of the original points. </p>
+
+<p>If you do not box the input sites, you can identify the
+unbounded regions. They list '0' as a vertex. Vertex 0 represents
+"infinity". Each unbounded ray includes vertex 0 in
+option '<a href="qh-optf.htm#Fv2">Fv</a>. See <A
+ href="qvoronoi.htm#graphics" >Voronoi graphics</a> and <A
+ href="qvoronoi.htm#notes" >Voronoi notes</a>. </p>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a>Approximation questions</h2>
+
+<h4><a href="#TOC">&#187;</a><a name="simplex">How</a> do I
+approximate data with a simplex</h4><blockquote>
+
+<p>Qhull may be used to help select a simplex that approximates a
+data set. It will take experimentation. Geomview will help to
+visualize the results. This task may be difficult to do in 5-d
+and higher. Use rbox options 'x' and 'y' to produce random
+distributions within a simplex. Your methods work if you can
+recover the simplex. </p>
+
+<p>Use Qhull's precision options to get a first approximation to
+the hull, say with 10 to 50 facets. For example, try 'C0.05' to
+remove small facets after constructing the hull. Use 'W0.05' to
+ignore points within 0.05 of a facet. Use 'PA5' to print the five
+largest facets by area. </p>
+
+<p>Then use other methods to fit a simplex to this data. Remove
+outlying vertices with few nearby points. Look for large facets
+in different quadrants. You can use option 'Pd0d1d2' to print all
+the facets in a quadrant. </p>
+
+<p>In 4-d and higher, use the outer planes (option 'Fo' or
+'facet-&gt;maxoutside') since the hyperplane of an approximate
+facet may be below many of the input points. </p>
+
+<p>For example, consider fitting a cube to 1000 uniformly random
+points in the unit cube. In this case, the first try was good: </p>
+
+<blockquote>
+ <pre>
+rbox 1000 | qconvex W0.05 C0.05 PA6 Fo
+4
+6
+0.35715408374381 0.08706467018177928 -0.9299788727015564 -0.5985514741284483
+0.995841591359023 -0.02512604712761577 0.08756829720435189 -0.5258834069202866
+0.02448099521570909 -0.02685210459017302 0.9993396046151313 -0.5158104982631999
+-0.9990223929415094 -0.01261133513150079 0.04236994958247349 -0.509218270408407
+-0.0128069014364698 -0.9998380680115362 0.01264203427283151 -0.5002512653670584
+0.01120895057872914 0.01803671994177704 -0.9997744926535512 -0.5056824072956361
+</pre>
+</blockquote>
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a>Halfspace questions</h2>
+
+<h4><a href="#TOC">&#187;</a><a name="halfspace">How</a> do I compute the
+ intersection of halfspaces with Qhull?</h4><blockquote>
+
+<p>Qhull computes the halfspace intersection about a point. The
+point must be inside all of the halfspaces. Given a point, a
+duality turns a halfspace intersection problem into a convex
+hull problem.
+
+<p>Use linear programming if you
+do not know a point in the interior of the halfspaces.
+See the <a href="qhalf.htm#notes">notes</a> for qhalf. You will need
+ a linear programming code. This may require a fair amount of work to
+ implement.</p>
+
+
+
+</blockquote>
+<h2><a href="#TOC">&#187;</a><a name="library">Qhull library
+questions</a></h2>
+
+<h4><a href="#TOC">&#187;</a><a name="math">Is</a> Qhull available for Mathematica, Matlab, or Maple?</h4><blockquote>
+
+<p><b>MATLAB</b>
+
+<p>Z. You of <a href="http://www.mathworks.com">MathWorks</a> added qhull to MATLAB 6.
+See functions <a href="http://www.mathworks.com/help/techdoc/ref/convhulln.html"
+ >convhulln</a>,
+ <a href="http://www.mathworks.com/help/techdoc/ref/delaunayn.html"
+ >delaunayn</a>,
+ <a href="http://www.mathworks.com/help/techdoc/ref/griddata3.html"
+ >griddata3</a>,
+ <a href="http://www.mathworks.com/help/techdoc/ref/griddatan.html"
+ >griddatan</a>,
+ <a href="http://www.mathworks.com/help/techdoc/ref/tsearch.html"
+ >tsearch</a>,
+ <a href="http://www.mathworks.com/help/techdoc/ref/tsearchn.html"
+ >tsearchn</a>, and
+ <a href="http://www.mathworks.com/help/techdoc/ref/voronoin.html"
+ >voronoin</a>. V. Brumberg update MATLAB R14 for Qhull 2003.1 and triangulated output.
+
+<p>Engwirda wrote <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=10307&objectType=file">mesh2d</a> for unstructured mesh generation in MATLAB.
+It is based on the iterative method of Persson and generally results in better quality meshes than delaunay refinement.
+
+
+<p><b>Mathematica and Maple</b>
+
+<p>See <a href="http://library.wolfram.com/infocenter/MathSource/1160/"
+ >qh-math</a>
+for a Delaunay interface to Mathematica. It includes projects for CodeWarrior
+on the Macintosh and Visual C++ on Win32 PCs.
+
+<p>See Mathematica ('<a
+href="qh-opto.htm#m">m</a>') and Maple ('<a
+href="qh-optf.htm#FM">FM</a>') output options.
+
+<p></p>
+</blockquote><h4><a href="#TOC">&#187;</a><a name="ridges">Why</a> are there too few ridges?</h4><blockquote>
+
+The following sample code may produce fewer ridges than expected:
+
+<blockquote><pre>
+ facetT *facetp;
+ ridgeT *ridge, **ridgep;
+
+ FORALLfacets {
+ printf("facet f%d\n", facet->id);
+ FOREACHridge_(facet->ridges) {
+ printf(" ridge r%d between f%d and f%d\n", ridge->id, ridge->top->id, ridge->bottom->id);
+ }
+ }
+</pre></blockquote>
+
+<p> Qhull does not create ridges for simplicial facets.
+Instead it computes ridges from facet-&gt;neighbors. To make ridges for a
+simplicial facet, use qh_makeridges() in merge.c. Usefacet-&gt;visit_id to visit
+each ridge once (instead of twice). For example,
+
+<blockquote><pre>
+ facetT *facet, *neighbor;
+ ridgeT *ridge, **ridgep;
+
+ qh visit_id++;
+ FORALLfacets {
+ printf("facet f%d\n", facet->id);
+ qh_makeridges(facet);
+ facet->visitId= qh visit_id;
+ FOREACHridge_(facet->ridges) {
+ neighbor= otherfacet_(ridge, visible);
+ if (neighbor->visitid != qh visit_id)
+ printf(" ridge r%d between f%d and f%d\n", ridge->id, ridge->top->id, ridge->bottom->id);
+ }
+ }
+</pre></blockquote>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="call">Can</a> Qhull use coordinates without placing
+ them in a data file?</h4><blockquote>
+
+<p>You may call Qhull from a program. Please use the reentrant Qhull library (libqhullstatic_r.a, libqhull_r.so, or qhull_r.dll).
+
+See user_eg.c and "Qhull-template" in user_r.c for examples..
+
+See <a href="qh-code.htm">Qhull internals</a> for an introduction to Qhull's reentrant library and its C++ interface.
+
+<p>Hint: Start with a small example for which you know the
+ answer.</p>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="size">How</a> large are Qhull's data structures?</h4><blockquote>
+
+<p>Qhull uses a general-dimension data structure.
+The size depends on the dimension. Use option 'Ts' to print
+out the memory statistics [e.g., 'rbox D2 10 | qconvex Ts'].
+
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="inc">Can</a> Qhull construct
+convex hulls and Delaunay triangulations one point at a time?</h4><blockquote>
+
+<p>The Qhull library may be used to construct convex hulls and
+Delaunay triangulations one point at a time. It may not be used
+for deleting points or moving points. </p>
+
+<p>Qhull is designed for batch processing. Neither Clarkson's
+randomized incremental algorithm nor Qhull are designed for
+on-line operation. For many applications, it is better to
+reconstruct the convex hull or Delaunay triangulation from
+scratch for each new point. </p>
+
+<p>With random point sets and on-line processing, Clarkson's
+algorithm should run faster than Qhull. Clarkson uses the
+intermediate facets to reject new, interior points, while Qhull,
+when used on-line, visits every facet to reject such points. If
+used on-line for n points, Clarkson may take O(n) times as much
+memory as the average off-line case, while Qhull's space
+requirement does not change. </p>
+
+<p>If you triangulate the output before adding all the points
+(option 'Qt' and procedure qh_triangulate), you must set
+option '<a href="qh-optq.htm#Q11">Q11</a>'. It duplicates the
+normals of triangulated facets and recomputes the centrums.
+This should be avoided for regular use since triangulated facets
+are not clearly convex with their neighbors. It appears to
+work most of the time, but fails for cases that Qhull normally
+handles well [see the test call to qh_triangulate in qh_addpoint].
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="ridges2">How</a> do I visit the
+ridges of a Delaunay triangulation?</h4><blockquote>
+
+<p>To visit the ridges of a Delaunay triangulation, visit each
+facet. Each ridge will appear twice since it belongs to two
+facets. In pseudo-code: </p>
+
+<pre>
+ for each facet of the triangulation
+ if the facet is Delaunay (i.e., part of the lower convex hull)
+ for each ridge of the facet
+ if the ridge's neighboring facet has not been visited
+ ... process a ridge of the Delaunay triangulation ...
+</pre>
+
+<p>In undebugged, C code: </p>
+
+<pre>
+ qh visit_id++;
+ FORALLfacets_(facetlist)
+ if (!facet-&gt;upperdelaunay) {
+ facet-&gt;visitid= qh visit_id;
+ qh_makeridges(facet);
+ FOREACHridge_(facet-&gt;ridges) {
+ neighbor= otherfacet_(ridge, facet);
+ if (neighbor-&gt;visitid != qh visit_id) {
+ /* Print ridge here with facet-id and neighbor-id */
+ /*fprintf(fp, "f%d\tf%d\t",facet-&gt;id,neighbor-&gt;ID);*/
+ FOREACHvertex_(ridge-&gt;vertices)
+ fprintf(fp,"%d ",qh_pointid (vertex-&gt;point) );
+ qh_printfacetNvertex_simplicial (fp, facet, format);
+ fprintf(fp," ");
+ if(neighbor-&gt;upperdelaunay)
+ fprintf(fp," -1 -1 -1 -1 ");
+ else
+ qh_printfacetNvertex_simplicial (fp, neighbor, format);
+ fprintf(fp,"\n");
+ }
+ }
+ }
+ }
+</pre>
+
+<p>Qhull should be redesigned as a class library, or at least as
+an API. It currently provides everything needed, but the
+programmer has to do a lot of work. Hopefully someone will write
+C++ wrapper classes or a Python module for Qhull. </p>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="listd">How</a> do I visit the
+Delaunay regions?</h4><blockquote>
+
+<p>Qhull constructs a Delaunay triangulation by lifting the
+input sites to a paraboloid. The Delaunay triangulation
+corresponds to the lower convex hull of the lifted points. To
+visit each facet of the lower convex hull, use: </p>
+
+<pre>
+ facetT *facet;
+
+ ...
+ FORALLfacets {
+ if (!facet-&gt;upperdelaunay) {
+ ... only facets for Delaunay regions ...
+ }
+ }
+</pre>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="outside">When</a> is a point
+outside or inside a facet?</h4><blockquote>
+
+<p>A point is outside of a facet if it is clearly outside the
+facet's outer plane. The outer plane is defined by an offset
+(facet-&gt;maxoutside) from the facet's hyperplane. </p>
+
+<pre>
+ facetT *facet;
+ pointT *point;
+ realT dist;
+
+ ...
+ qh_distplane(point, facet, &amp;dist);
+ if (dist &gt; facet-&gt;maxoutside + 2 * qh DISTround) {
+ /* point is clearly outside of facet */
+ }
+</pre>
+
+<p>A point is inside of a facet if it is clearly inside the
+facet's inner plane. The inner plane is computed as the maximum
+distance of a vertex to the facet. It may be computed for an
+individual facet, or you may use the maximum over all facets. For
+example: </p>
+
+<pre>
+ facetT *facet;
+ pointT *point;
+ realT dist;
+
+ ...
+ qh_distplane(point, facet, &amp;dist);
+ if (dist &lt; qh min_vertex - 2 * qh DISTround) {
+ /* point is clearly inside of facet */
+ }
+</pre>
+
+<p>Both tests include two qh.DISTrounds because the computation
+of the furthest point from a facet may be off by qh.DISTround and
+the computation of the current distance to the facet may be off
+by qh.DISTround. </p>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="closest">How</a> do I find the
+facet that is closest to a point?</h4><blockquote>
+
+<p>Use qh_findbestfacet(). For example, </p>
+
+<pre>
+ coordT point[ DIM ];
+ boolT isoutside;
+ realT bestdist;
+ facetT *facet;
+
+ ... set coordinates for point ...
+
+ facet= qh_findbestfacet (point, qh_ALL, &amp;bestdist, &amp;isoutside);
+
+ /* 'facet' is the closest facet to 'point' */
+</pre>
+
+<p>qh_findbestfacet() performs a directed search for the facet
+furthest below the point. If the point lies inside this facet,
+qh_findbestfacet() performs an exhaustive search of all facets.
+An exhaustive search may be needed because a facet on the far
+side of a lens-shaped distribution may be closer to a point than
+all of the facet's neighbors. The exhaustive search may be
+skipped for spherical distributions. </p>
+
+<p>Also see, "<a href="#vclosest">How</a> do I find the
+Delaunay triangle that is closest to a
+point?" </p>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="vclosest">How</a> do I find the
+Delaunay triangle or Voronoi region that is closest to a point?</h4><blockquote>
+
+<p>A Delaunay triangulation subdivides the plane, or in general
+dimension, subdivides space. Given a point, how do you determine
+the subdivision containing the point? Or, given a set of points,
+how do you determine the subdivision containing each point of the set?
+Efficiency is important -- an exhaustive search of the subdivision
+is too slow.
+
+<p>First compute the Delaunay triangle with qh_new_qhull() in user_r.c or Qhull::runQhull().
+Lift the point to the paraboloid by summing the squares of the
+coordinates. Use qh_findbestfacet() [poly2.c] to find the closest Delaunay
+triangle. Determine the closest vertex to find the corresponding
+Voronoi region. Do not use options
+'<a href="qh-optq.htm#Qbb">Qbb</a>', '<a href="qh-optq.htm#QbB">QbB</a>',
+'<a href="qh-optq.htm#Qbk">Qbk:n</a>', or '<A
+ href="qh-optq.htm#QBk" >QBk:n</a>' since these scale the last
+coordinate. Optimizations of qh_findbestfacet() should
+be possible for Delaunay triangulations.</p>
+
+<p>You first need to lift the point to the paraboloid (i.e., the
+last coordinate is the sum of the squares of the point's coordinates).
+The
+routine, qh_setdelaunay() [geom2.c], lifts an array of points to the
+paraboloid. The following excerpt is from findclosest() in
+user_eg.c. </p>
+
+<pre>
+ coordT point[ DIM + 1]; /* one extra coordinate for lifting the point */
+ boolT isoutside;
+ realT bestdist;
+ facetT *facet;
+
+ ... set coordinates for point[] ...
+
+ qh_setdelaunay (DIM+1, 1, point);
+ facet= qh_findbestfacet (point, qh_ALL, &amp;bestdist, &amp;isoutside);
+ /* 'facet' is the closest Delaunay triangle to 'point' */
+</pre>
+
+<p>The returned facet either contains the point or it is the
+closest Delaunay triangle along the convex hull of the input set.
+
+<p>Point location is an active research area in Computational
+Geometry. For a practical approach, see Mucke, et al, "Fast randomized
+point location without preprocessing in two- and
+three-dimensional Delaunay triangulations," <i>Computational
+Geometry '96</i>, p. 274-283, May 1996.
+For an introduction to planar point location see [O'Rourke '93].
+Also see, "<A
+ href="#closest" >How</a> do I find the facet that is closest to a
+point?" </p>
+
+<p>To locate the closest Voronoi region, determine the closest
+vertex of the closest Delaunay triangle. </p>
+
+<pre>
+ realT dist, bestdist= REALmax;
+ vertexT *bestvertex= NULL, *vertex, **vertexp;
+
+ /* 'facet' is the closest Delaunay triangle to 'point' */
+
+ FOREACHvertex_( facet-&gt;vertices ) {
+ dist= qh_pointdist( point, vertex-&gt;point, DIM );
+ if (dist &lt; bestdist) {
+ bestdist= dist;
+ bestvertex= vertex;
+ }
+ }
+ /* 'bestvertex' represents the Voronoi region closest to 'point'. The corresponding
+ input site is 'bestvertex-&gt;point' */
+</pre>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="vertices">How</a> do I list the
+vertices?</h4><blockquote>
+
+<p>To list the vertices (i.e., extreme points) of the convex hull
+use </p>
+
+<blockquote>
+ <pre>
+ vertexT *vertex;
+
+ FORALLvertices {
+ ...
+ // vertex-&gt;point is the coordinates of the vertex
+ // qh_pointid(vertex-&gt;point) is the point ID of the vertex
+ ...
+ }
+ </pre>
+</blockquote>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="test">How</a> do I test code
+that uses the Qhull library?</h4><blockquote>
+
+<p>Compare the output from your program with the output from the
+Qhull program. Use option 'T1' or 'T4' to trace what Qhull is
+doing. Prepare a <i>small</i> example for which you know the
+output. Run the example through the Qhull program and your code.
+Compare the trace outputs. If you do everything right, the two
+trace outputs should be almost the same. The trace output will
+also guide you to the functions that you need to review. </p>
+
+</blockquote><h4><a href="#TOC">&#187;</a><a name="orient">When</a> I compute a
+plane equation from a facet, I sometimes get an outward-pointing
+normal and sometimes an inward-pointing normal</h4><blockquote>
+
+<p>Qhull orients simplicial facets, and prints oriented output
+for 'i', 'Ft', and other options. The orientation depends on <i>both</i>
+the vertex order and the flag facet-&gt;toporient.</p>
+
+<p>Qhull does not orient
+ non-simplicial facets. Instead it orients the facet's ridges. These are
+ printed with the 'Qt' and 'Ft' option. The facet's hyperplane is oriented. </p>
+
+</blockquote>
+<hr><!-- Navigation links -->
+
+<p><a><b>Up:</b> </a><a
+ href="http://www.qhull.org">Home page for Qhull</a><br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#TOC">FAQ: Table of Contents</a><br><!-- GC common information -->
+
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><IMG align=middle
+ height=40 src="qh--geom.gif" width=40 ></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created:
+Sept. 25, 1995 --- <!-- hhmts start -->Last modified: see top
+<!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-get.htm b/xs/src/qhull/html/qh-get.htm
new file mode 100644
index 000000000..c39ed2256
--- /dev/null
+++ b/xs/src/qhull/html/qh-get.htm
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Qhull Downloads</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><b>Up:</b> <a href="http://www.qhull.org"><i>Qhull Home Page</i></a><br>
+</p>
+
+<hr>
+
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/cone.html"><img
+src="../html/qh--cone.gif" alt="[CONE]" align="middle"
+width="100" height="100"></a> Qhull Downloads</h1>
+
+<ul>
+ <li><a href="http://www.qhull.org">Qhull Home Page</a> <p>Qhull
+ computes the convex hull, Delaunay triangulation, Voronoi diagram, halfspace
+ intersection about a point, furthest-site Delaunay
+ triangulation, and furthest-site Voronoi diagram. It
+ runs in 2-d, 3-d, 4-d, and higher dimensions. It
+ implements the Quickhull algorithm for computing the
+ convex hull. Qhull handles roundoff errors from floating
+ point arithmetic. It can approximate a convex hull. </p>
+
+ <p>Visit <a href="http://www.qhull.org/news">Qhull News</a>
+ for news, bug reports, change history, and users.
+ If you use Qhull 2003.1 or 2009.1, please upgrade to 2015.2 or apply
+ <a href="http://www.qhull.org/download/poly.c-qh_gethash.patch">poly.c-qh_gethash.patch</a>.</p>
+ </li>
+ <li><a
+ href="http://www.qhull.org/download/qhull-2015.2.zip">Download:
+ Qhull 2015.2 for Windows 10, 8, 7, XP, and NT</a> (2.6 MB,
+ <a href="http://www.qhull.org/README.txt">readme</a>,
+ <a href="http://www.qhull.org/download/qhull-2015.2.md5sum">md5sum</a>,
+ <a href="http://www.qhull.org/download/qhull-2015.2.zip.md5sum">contents</a>)
+ <p>Type: console programs for Windows (32- or 64-bit)</p>
+ <p>Includes 32-bit executables, documentation, and sources files. It runs in a
+ command window. Qhull may be compiled for 64-bits.</p>
+ </li>
+ <li><a href="http://github.com/qhull/qhull/wiki">GitHub Qhull</a> (git@github.com:qhull/qhull.git)
+ <p>Type: git repository for Qhull. See recent <a href="https://github.com/qhull/qhull/blob/master/src/Changes.txt">Changes.txt</a></p>
+ <p>Includes documentation, source files, C++ interface, and test programs. It builds with gcc, mingw,
+ CMake, DevStudio, and Qt Creator.
+ </p>
+ </li>
+ <li><a href="http://www.qhull.org/download/qhull-2015-src-7.2.0.tgz">Download: Qhull 2015.2 for Unix</a> (1.0 MB,
+ <a href="http://www.qhull.org/README.txt">readme</a>,
+ <a href="http://www.qhull.org/download/qhull-2015.2.md5sum">md5sum</a>,
+ <a href="http://www.qhull.org/download/qhull-2015-src-7.2.0.tgz.md5sum">contents</a>)
+ <p>Type: C/C++ source code for 32-bit and 64-bit architectures. See <a href="http://www.qhull.org/src/Changes.txt">Changes.txt</a></p>
+ <p>Includes documentation, source files, Makefiles, CMakeLists.txt, DevStudio projects, and Qt projects.
+ Includes preliminary C++ support.</p>
+ <p>Download and search sites for pre-built packages include
+ <ul>
+ <li><a href="https://launchpad.net/ubuntu/+source/qhull">https://launchpad.net/ubuntu/+source/qhull</a>
+ <li><a href="http://software.opensuse.org/download.html?project=openSUSE%3AFactory&package=qhull">http://software.opensuse.org/download.html?project=openSUSE%3AFactory&package=qhull</a>
+ <li><a href="https://www.archlinux.org/packages/extra/i686/qhull/">https://www.archlinux.org/packages/extra/i686/qhull/</a>
+ <li><a href="http://rpmfind.net/linux/rpm2html/search.php?query=qhull">http://rpmfind.net/linux/rpm2html/search.php?query=qhull</a>
+ <li><a href="http://rpm.pbone.net/index.php3/stat/3/srodzaj/1/search/qhull">http://rpm.pbone.net/index.php3/stat/3/srodzaj/1/search/qhull</a>
+ </ul></p>
+ </li>
+
+ <li><a
+ href="http://dl.acm.org/author_page.cfm?id=81100129162">Download:
+ Article about Qhull</a> (307K)
+ <p>Type: PDF on ACM Digital Library (from this page only)</p>
+ <p>Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T.,
+ &quot;The Quickhull algorithm for convex hulls,&quot; <i>ACM
+ Transactions on Mathematical Software</i>, 22(4):469-483, Dec 1996 [<a
+ href="http://portal.acm.org/citation.cfm?doid=235815.235821">abstract</a>].</p>
+ </li>
+
+ <li><a
+ href="http://www.qhull.org/download/qhull-1.0.tar.gz">Download:
+ Qhull version 1.0</a> (92K) <p>Type: C source code for
+ 32-bit architectures </p>
+ <p>Version 1.0 is a fifth the size of version 2.4. It
+ computes convex hulls and Delaunay triangulations. If a
+ precision error occurs, it stops with an error message.
+ It reports an initialization error for inputs made with
+ 0/1 coordinates. </p>
+ <p>Version 1.0 compiles on a PC with Borland C++ 4.02 for
+ Win32 and DOS Power Pack. The options for rbox are
+ &quot;bcc32 -WX -w- -O2-e -erbox -lc rbox.c&quot;. The
+ options for qhull are the same. [D. Zwick] </p>
+ </li>
+</ul>
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org"><i>Qhull Home Page</i></a><br>
+<!-- GC common information --></p>
+
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="../html/qh--geom.gif" alt="[HOME]"
+align="middle"></a> <i>The Geometry Center Home Page</i> </p>
+
+<p>Comments to: <a href="mailto:qhull@qhull.org">qhull@qhull.org</a><br>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-impre.htm b/xs/src/qhull/html/qh-impre.htm
new file mode 100644
index 000000000..cfbe0acb8
--- /dev/null
+++ b/xs/src/qhull/html/qh-impre.htm
@@ -0,0 +1,826 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Imprecision in Qhull</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a href="http://www.qhull.org">Home
+page</a> for Qhull <br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of
+Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To: </b><a href="#TOC">Qhull imprecision</a>: Table of Contents
+(please wait while loading)
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/4dcube.html"><img
+src="qh--4d.gif" alt="[4-d cube]" align="middle" width="100"
+height="100"></a> Imprecision in Qhull</h1>
+
+<p>This section of the Qhull manual discusses the problems caused
+by coplanar points and why Qhull uses options '<a
+href="qh-optc.htm#C0">C-0</a>' or '<a href="qh-optq.htm#Qx">Qx</a>'
+by default. If you ignore precision issues with option '<a
+href="qh-optq.htm#Q0">Q0</a>', the output from Qhull can be
+arbitrarily bad. Qhull avoids precision problems if you merge facets (the default) or joggle
+the input ('<a
+href="qh-optq.htm#QJn">QJ</a>'). </p>
+
+<p>Use option '<a href="qh-optt.htm#Tv">Tv</a>' to verify the
+output from Qhull. It verifies that adjacent facets are clearly
+convex. It verifies that all points are on or below all facets. </p>
+
+<p>Qhull automatically tests for convexity if it detects
+precision errors while constructing the hull. </p>
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<h2><a href="#TOP">&#187;</a><a name="TOC">Qhull
+imprecision: Table of Contents </a></h2>
+
+<ul>
+ <li><a href="#prec">Precision problems</a></li>
+ <li><a href="#joggle">Merged facets or joggled input</a></li>
+ <li><a href="#delaunay">Delaunay triangulations</a></li>
+ <li><a href="#halfspace">Halfspace intersection/a></li>
+ <li><a href="#imprecise">Merged facets</a></li>
+ <li><a href="#how">How Qhull merges facets</a></li>
+ <li><a href="#limit">Limitations of merged facets</a></li>
+ <li><a href="#injoggle">Joggled input</a></li>
+ <li><a href="#exact">Exact arithmetic</a></li>
+ <li><a href="#approximate">Approximating a convex hull</a></li>
+</ul>
+
+<hr>
+
+<h2><a href="#TOC">&#187;</a><a name="prec">Precision problems</a></h2>
+
+<p>Since Qhull uses floating point arithmetic, roundoff error
+occurs with each calculation. This causes problems for
+geometric algorithms. Other floating point codes for convex
+hulls, Delaunay triangulations, and Voronoi diagrams also suffer
+from these problems. Qhull handles most of them.</p>
+
+<p>There are several kinds of precision errors:</p>
+
+<ul>
+ <li>Representation error occurs when there are not enough
+ digits to represent a number, e.g., 1/3.</li>
+ <li>Measurement error occurs when the input coordinates are
+ from measurements. </li>
+ <li>Roundoff error occurs when a calculation is rounded to a
+ fixed number of digits, e.g., a floating point
+ calculation.</li>
+ <li>Approximation error occurs when the user wants an
+ approximate result because the exact result contains too
+ much detail.</li>
+</ul>
+
+<p>Under imprecision, calculations may return erroneous results.
+For example, roundoff error can turn a small, positive number
+into a small, negative number. See Milenkovic [<a
+href="index.htm#mile93">'93</a>] for a discussion of <em>strict
+robust geometry</em>. Qhull does not meet Milenkovic's criterion
+for accuracy. Qhull's error bound is empirical instead of
+theoretical.</p>
+
+<p>Qhull 1.0 checked for precision errors but did not handle
+them. The output could contain concave facets, facets with
+inverted orientation (&quot;flipped&quot; facets), more than two
+facets adjacent to a ridge, and two facets with exactly the same
+set of vertices.</p>
+
+<p>Qhull 2.4 and later automatically handles errors due to
+machine round-off. Option '<a href="qh-optc.htm#C0">C-0</a>' or '<a
+href="qh-optq.htm#Qx">Qx</a>' is set by default. In 5-d and
+higher, the output is clearly convex but an input point could be
+outside of the hull. This may be corrected by using option '<a
+href="qh-optc.htm#C0">C-0</a>', but then the output may contain
+wide facets.</p>
+
+<p>Qhull 2.5 and later provides option '<a href="qh-optq.htm#QJn">QJ</a>'
+to joggled input. Each input coordinate is modified by a
+small, random quantity. If a precision error occurs, a larger
+modification is tried. When no precision errors occur, Qhull is
+done. </p>
+
+<p>Qhull 3.1 and later provides option '<a href="qh-optq.htm#Qt">Qt</a>'
+for triangulated output. This removes the need for
+joggled input ('<a href="qh-optq.htm#QJn">QJ</a>').
+Non-simplicial facets are triangulated.
+The facets may have zero area.
+Triangulated output is particularly useful for Delaunay triangulations.</p>
+
+<p>By handling round-off errors, Qhull can provide a variety of
+output formats. For example, it can return the halfspace that
+defines each facet ('<a href="qh-opto.htm#n">n</a>'). The
+halfspaces include roundoff error. If the halfspaces were exact,
+their intersection would return the original extreme points. With
+imprecise halfspaces and exact arithmetic, nearly incident points
+may be returned for an original extreme point. By handling
+roundoff error, Qhull returns one intersection point for each of
+the original extreme points. Qhull may split or merge an extreme
+point, but this appears to be unlikely.</p>
+
+<p>The following pipe implements the identity function for
+extreme points (with roundoff):
+<blockquote>
+ qconvex <a href="qh-optf.htm#FV">FV</a> <a
+ href="qh-opto.htm#n">n</a> | qhalf <a href="qh-optf.htm#Fp">Fp</a>
+</blockquote>
+
+<p>Bernd Gartner published his
+<a href=http://www.inf.ethz.ch/personal/gaertner/miniball.html>Miniball</a>
+algorithm ["Fast and robust smallest enclosing balls", <i>Algorithms - ESA '99</i>, LNCS 1643].
+It uses floating point arithmetic and a carefully designed primitive operation.
+It is practical to 20-D or higher, and identifies at least two points on the
+convex hull of the input set. Like Qhull, it is an incremental algorithm that
+processes points furthest from the intermediate result and ignores
+points that are close to the intermediate result.
+
+<h2><a href="#TOC">&#187;</a><a name="joggle">Merged facets or joggled input</a></h2>
+
+<p>This section discusses the choice between merged facets and joggled input.
+By default, Qhull uses merged facets to handle
+precision problems. With option '<a href="qh-optq.htm#QJn">QJ</a>',
+the input is joggled. See <a href="qh-eg.htm#joggle">examples</a>
+of joggled input and triangulated output.
+<ul>
+<li>Use merged facets (the default)
+when you want non-simplicial output (e.g., the faces of a cube).
+<li>Use merged facets and triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>') when
+you want simplicial output and coplanar facets (e.g., triangles for a Delaunay triangulation).
+<li>Use joggled input ('<a href="qh-optq.htm#QJn">QJ</a>') when you need clearly-convex,
+simplicial output.
+</ul>
+
+<p>The choice between merged facets and joggled input depends on
+the application. Both run about the same speed. Joggled input may
+be faster if the initial joggle is sufficiently large to avoid
+precision errors.
+
+<p>Most applications should used merged facets
+with triangulated output. </p>
+
+<p>Use merged facets (the
+default, '<a href="qh-optc.htm#C0">C-0</a>')
+or triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>') if </p>
+
+<ul>
+ <li>Your application supports non-simplicial facets, or
+ it allows degenerate, simplicial facets (option '<a href="qh-optq.htm#Qt">Qt</a>'). </li>
+ <li>You do not want the input modified. </li>
+ <li>You want to set additional options for approximating the
+ hull. </li>
+ <li>You use single precision arithmetic (<a href="../src/libqhull/user.h#realT">realT</a>).
+ </li>
+</ul>
+
+<p>Use joggled input ('<a href="qh-optq.htm#QJn">QJ</a>') if </p>
+
+<ul>
+ <li>Your application needs clearly convex, simplicial output</li>
+ <li>Your application supports perturbed input points and narrow triangles.</li>
+ <li>Seven significant digits is sufficient accuracy.</li>
+</ul>
+
+<p>You may use both techniques or combine joggle with
+post-merging ('<a href="qh-optc.htm#Cn2">Cn</a>'). </p>
+
+<p>Other researchers have used techniques similar to joggled
+input. Sullivan and Beichel [ref?] randomly perturb the input
+before computing the Delaunay triangulation. Corkum and Wyllie
+[news://comp.graphics, 1990] randomly rotate a polytope before
+testing point inclusion. Edelsbrunner and Mucke [Symp. Comp.
+Geo., 1988] and Yap [J. Comp. Sys. Sci., 1990] symbolically
+perturb the input to remove singularities. </p>
+
+<p>Merged facets ('<a href="qh-optc.htm#C0">C-0</a>') handles
+precision problems directly. If a precision problem occurs, Qhull
+merges one of the offending facets into one of its neighbors.
+Since all precision problems in Qhull are associated with one or
+more facets, Qhull will either fix the problem or attempt to merge the
+last remaining facets. </p>
+
+<h2><a href="#TOC">&#187;</a><a name="delaunay">Delaunay
+triangulations </a></h2>
+
+<p>Programs that use Delaunay triangulations traditionally assume
+a triangulated input. By default, <a href=qdelaun.htm>qdelaunay</a>
+merges regions with cocircular or cospherical input sites.
+If you want a simplicial triangulation
+use triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>') or joggled
+input ('<a href="qh-optq.htm#QJn">QJ</a>').
+
+<p>For Delaunay triangulations, triangulated
+output should produce good results. All points are within roundoff error of
+a paraboloid. If two points are nearly incident, one will be a
+coplanar point. So all points are clearly separated and convex.
+If qhull reports deleted vertices, the triangulation
+may contain serious precision faults. Deleted vertices are reported
+in the summary ('<a href="qh-opto.htm#s">s</a>', '<a href="qh-optf.htm#Fs">Fs</a>'</p>
+
+<p>You should use option '<a href="qh-optq.htm#Qbb">Qbb</a>' with Delaunay
+triangulations. It scales the last coordinate and may reduce
+roundoff error. It is automatically set for <a href=qdelaun.htm>qdelaunay</a>,
+<a href=qvoronoi.htm>qvoronoi</a>, and option '<a
+href="qh-optq.htm#QJn">QJ</a>'.</p>
+
+<p>Edelsbrunner, H, <i>Geometry and Topology for Mesh Generation</i>, Cambridge University Press, 2001.
+Good mathematical treatise on Delaunay triangulation and mesh generation for 2-d
+and 3-d surfaces. The chapter on surface simplification is
+particularly interesting. It is similar to facet merging in Qhull.
+
+<p>Veron and Leon published an algorithm for shape preserving polyhedral
+simplification with bounded error [<i>Computers and Graphics</i>, 22.5:565-585, 1998].
+It remove nodes using front propagation and multiple remeshing.
+
+<h2><a href="#TOC">&#187;</a><a name="halfspace">Halfspace intersection</a></h2>
+
+<p>
+The identity pipe for Qhull reveals some precision questions for
+halfspace intersections. The identity pipe creates the convex hull of
+a set of points and intersects the facets' hyperplanes. It should return the input
+points, but narrow distributions may drop points while offset distributions may add
+points. It may be better to normalize the input set about the origin.
+For example, compare the first results with the later two results: [T. Abraham]
+<blockquote>
+ rbox 100 s t | tee r | qconvex FV n | qhalf Fp | cat - r | /bin/sort -n | tail
+<br>
+ rbox 100 L1e5 t | tee r | qconvex FV n | qhalf Fp | cat - r | /bin/sort -n | tail
+<br>
+ rbox 100 s O10 t | tee r | qconvex FV n | qhalf Fp | cat - r | /bin/sort -n | tail
+</blockquote>
+
+
+<h2><a href="#TOC">&#187;</a><a name="imprecise">Merged facets </a></h2>
+
+<p>Qhull detects precision
+problems when computing distances. A precision problem occurs if
+the distance computation is less than the maximum roundoff error.
+Qhull treats the result of a hyperplane computation as if it
+were exact.</p>
+
+<p>Qhull handles precision problems by merging non-convex facets.
+The result of merging two facets is a thick facet defined by an <i>inner
+plane</i> and an <i>outer plane</i>. The inner and outer planes
+are offsets from the facet's hyperplane. The inner plane is
+clearly below the facet's vertices. At the end of Qhull, the
+outer planes are clearly above all input points. Any exact convex
+hull must lie between the inner and outer planes.</p>
+
+<p>Qhull tests for convexity by computing a point for each facet.
+This point is called the facet's <i>centrum</i>. It is the
+arithmetic center of the facet's vertices projected to the
+facet's hyperplane. For simplicial facets with <em>d</em>
+vertices, the centrum is equivalent to the centroid or center of
+gravity. </p>
+
+<p>Two neighboring facets are convex if each centrum is clearly
+below the other hyperplane. The '<a href="qh-optc.htm#Cn2">Cn</a>'
+or '<a href="qh-optc.htm#Cn">C-n</a>' options sets the centrum's
+radius to <i>n </i>. A centrum is clearly below a hyperplane if
+the computed distance from the centrum to the hyperplane is
+greater than the centrum's radius plus two maximum roundoff
+errors. Two are required because the centrum can be the maximum
+roundoff error above its hyperplane and the distance computation
+can be high by the maximum roundoff error.</p>
+
+<p>With the '<a href="qh-optc.htm#Cn">C-n</a>' or '<a
+href="qh-optc.htm#An">A-n </a>' options, Qhull merges non-convex
+facets while constructing the hull. The remaining facets are
+clearly convex. With the '<a href="qh-optq.htm#Qx">Qx </a>'
+option, Qhull merges coplanar facets after constructing the hull.
+While constructing the hull, it merges coplanar horizon facets,
+flipped facets, concave facets and duplicated ridges. With '<a
+href="qh-optq.htm#Qx">Qx</a>', coplanar points may be missed, but
+it appears to be unlikely.</p>
+
+<p>If the user sets the '<a href="qh-optc.htm#An2">An</a>' or '<a
+href="qh-optc.htm#An">A-n</a>' option, then all neighboring
+facets are clearly convex and the maximum (exact) cosine of an
+angle is <i>n</i>.</p>
+
+<p>If '<a href="qh-optc.htm#C0">C-0</a>' or '<a
+href="qh-optq.htm#Qx">Qx</a>' is used without other precision
+options (default), Qhull tests vertices instead of centrums for
+adjacent simplices. In 3-d, if simplex <i>abc</i> is adjacent to
+simplex <i>bcd</i>, Qhull tests that vertex <i>a</i> is clearly
+below simplex <i>bcd </i>, and vertex <i>d</i> is clearly below
+simplex <i>abc</i>. When building the hull, Qhull tests vertices
+if the horizon is simplicial and no merges occur. </p>
+
+<h2><a href="#TOC">&#187;</a><a name="how">How Qhull merges facets</a></h2>
+
+<p>If two facets are not clearly convex, then Qhull removes one
+or the other facet by merging the facet into a neighbor. It
+selects the merge which minimizes the distance from the
+neighboring hyperplane to the facet's vertices. Qhull also
+performs merges when a facet has fewer than <i>d</i> neighbors (called a
+degenerate facet), when a facet's vertices are included in a
+neighboring facet's vertices (called a redundant facet), when a
+facet's orientation is flipped, or when a ridge occurs between
+more than two facets.</p>
+
+<p>Qhull performs merges in a series of passes sorted by merge
+angle. Each pass merges those facets which haven't already been
+merged in that pass. After a pass, Qhull checks for redundant
+vertices. For example, if a vertex has only two neighbors in 3-d,
+the vertex is redundant and Qhull merges it into an adjacent
+vertex.</p>
+
+<p>Merging two simplicial facets creates a non-simplicial facet
+of <em>d+1</em> vertices. Additional merges create larger facets.
+When merging facet A into facet B, Qhull retains facet B's
+hyperplane. It merges the vertices, neighbors, and ridges of both
+facets. It recomputes the centrum if a wide merge has not
+occurred (qh_WIDEcoplanar) and the number of extra vertices is
+smaller than a constant (qh_MAXnewcentrum).</p>
+
+
+<h2><a href="#TOC">&#187;</a><a name="limit">Limitations of merged
+facets</a></h2>
+
+<ul>
+<li><b>Uneven dimensions</b> --
+If one coordinate has a larger absolute value than other
+coordinates, it may dominate the effect of roundoff errors on
+distance computations. You may use option '<a
+href="qh-optq.htm#QbB">QbB</a>' to scale points to the unit cube.
+For Delaunay triangulations and Voronoi diagrams, <a href=qdelaun.htm>qdelaunay</a>
+and <a href=qvoronoi.htm>qvoronoi</a> always set
+option '<a href="qh-optq.htm#Qbb">Qbb</a>'. It scales the last
+coordinate to [0,m] where <i>m</i> is the maximum width of the
+other coordinates. Option '<a href="qh-optq.htm#Qbb">Qbb</a>' is
+needed for Delaunay triangulations of integer coordinates
+and nearly cocircular points.
+
+<p>For example, compare
+<pre>
+ rbox 1000 W0 t | qconvex Qb2:-1e-14B2:1e-14
+</pre>
+with
+<pre>
+ rbox 1000 W0 t | qconvex
+</pre>
+The distributions are the same but the first is compressed to a 2e-14 slab.
+<p>
+<li><b>Post-merging of coplanar facets</b> -- In 5-d and higher, option '<a href="qh-optq.htm#Qx">Qx</a>'
+(default) delays merging of coplanar facets until post-merging.
+This may allow &quot;dents&quot; to occur in the intermediate
+convex hulls. A point may be poorly partitioned and force a poor
+approximation. See option '<a href="qh-optq.htm#Qx">Qx</a>' for
+further discussion.</p>
+
+<p>This is difficult to produce in 5-d and higher. Option '<a href="qh-optq.htm#Q6">Q6</a>' turns off merging of concave
+facets. This is similar to 'Qx'. It may lead to serious precision errors,
+for example,
+<pre>
+ rbox 10000 W1e-13 | qhull Q6 Tv
+</pre>
+
+<p>
+<li><b>Maximum facet width</b> --
+Qhull reports the maximum outer plane and inner planes (if
+more than roundoff error apart). There is no upper bound
+for either figure. This is an area for further research. Qhull
+does a good job of post-merging in all dimensions. Qhull does a
+good job of pre-merging in 2-d, 3-d, and 4-d. With the '<a
+href="qh-optq.htm#Qx">Qx</a>' option, it does a good job in
+higher dimensions. In 5-d and higher, Qhull does poorly at
+detecting redundant vertices. </p>
+
+<p>In the summary ('<a href="qh-opto.htm#s">s</a>'), look at the
+ratio between the maximum facet width and the maximum width of a
+single merge, e.g., &quot;(3.4x)&quot;. Qhull usually reports a
+ratio of four or lower in 3-d and six or lower in 4-d. If it
+reports a ratio greater than 10, this may indicate an
+implementation error. Narrow distributions (see following) may
+produce wide facets.
+
+<p>For example, if special processing for narrow distributions is
+turned off ('<a href="qh-optq.htm#Q10">Q10</a>'), qhull may produce
+a wide facet:</p>
+<pre>
+ rbox 1000 L100000 s G1e-16 t1002074964 | qhull Tv Q10
+</pre>
+
+<p>
+<li><b>Narrow distribution</b> -- In 3-d, a narrow distribution may result in a poor
+approximation. For example, if you do not use qdelaunay nor option
+'<a href="qh-optq.htm#Qbb">Qbb</a>', the furthest-site
+Delaunay triangulation of nearly cocircular points may produce a poor
+approximation:
+<pre>
+ rbox s 5000 W1e-13 D2 t1002151341 | qhull d Qt
+ rbox 1000 s W1e-13 t1002231672 | qhull d Tv
+</pre>
+
+<p>During
+construction of the hull, a point may be above two
+facets with opposite orientations that span the input
+set. Even though the point may be nearly coplanar with both
+facets, and can be distant from the precise convex
+hull of the input sites. Additional facets leave the point distant from
+a facet. To fix this problem, add option '<a href="qh-optq.htm#Qbb">Qbb</a>'
+(it scales the last coordinate). Option '<a href="qh-optq.htm#Qbb">Qbb</a>'
+is automatically set for <a href=qdelaun.htm>qdelaunay</a> and <a href=qvoronoi.htm>qvoronoi</a>.
+
+<p>Qhull generates a warning if the initial simplex is narrow.
+For narrow distributions, Qhull changes how it processes coplanar
+points -- it does not make a point coplanar until the hull is
+finished.
+Use option '<a href="qh-optq.htm#Q10">Q10</a>' to try Qhull without
+special processing for narrow distributions.
+For example, special processing is needed for:
+<pre>
+ rbox 1000 L100000 s G1e-16 t1002074964 | qhull Tv Q10
+</pre>
+
+<p>You may turn off the warning message by reducing
+qh_WARNnarrow in <tt>user.h</tt> or by setting option
+'<a href="qh-optp.htm#Pp">Pp</a>'. </p>
+
+<p>Similar problems occur for distributions with a large flat facet surrounded
+with many small facet at a sharp angle to the large facet.
+Qhull 3.1 fixes most of these problems, but a poor approximation can occur.
+A point may be left outside of the convex hull ('<a href="qh-optt.htm#Tv">Tv</a>').
+Examples include
+the furthest-site Delaunay triangulation of nearly cocircular points plus the origin, and the convex hull of a cone of nearly cocircular points. The width of the band is 10^-13.
+<pre>
+ rbox s 1000 W1e-13 P0 D2 t996799242 | qhull d Tv
+ rbox 1000 s Z1 G1e-13 t1002152123 | qhull Tv
+ rbox 1000 s Z1 G1e-13 t1002231668 | qhull Tv
+</pre>
+
+<p>
+<li><b>Quadratic running time</b> -- If the output contains large, non-simplicial
+facets, the running time for Qhull may be quadratic in the size of the triangulated
+output. For example, <tt>rbox 1000 s W1e-13 c G2 | qhull d</tt> is 4 times
+faster for 500 points. The convex hull contains two large nearly spherical facets and
+many nearly coplanar facets. Each new point retriangulates the spherical facet and repartitions the remaining points into all of the nearly coplanar facets.
+In this case, quadratic running time is avoided if you use qdelaunay,
+add option '<a href="qh-optq.htm#Qbb">Qbb</a>',
+or add the origin ('P0') to the input.
+<p>
+<li><b>Nearly coincident points within 1e-13</b> --
+Multiple, nearly coincident points within a 1e-13 ball of points in the unit cube
+may lead to wide facets or quadratic running time.
+For example, the convex hull a 1000 coincident, cospherical points in 4-D,
+or the 3-D Delaunay triangulation of nearly coincident points, may lead to very
+wide facets (e.g., 2267021951.3x).
+
+<p>For Delaunay triangulations, the problem typically occurs for extreme points of the input
+set (i.e., on the edge between the upper and lower convex hull). After multiple facet merges, four
+facets may share the same, duplicate ridge and must be merged.
+Some of these facets may be long and narrow, leading to a very wide merged facet.
+If so, error QH6271 is reported. It may be overriden with option '<a href="qh-optq.htm#Q12">Q12</a>'.
+
+<p>Duplicate ridges occur when the horizon facets for a new point is "pinched".
+In a duplicate ridge, a subridge (e.g., a line segment in 3-d) is shared by two horizon facets.
+At least two of its vertices are nearly coincident. It is easy to generate coincident points with
+option 'Cn,r,m' of rbox. It generates n points within an r ball for each of m input sites. For example,
+every point of the following distributions has a nearly coincident point within a 1e-13 ball.
+Substantially smaller or larger balls do not lead to pinched horizons.
+<pre>
+ rbox 1000 C1,1e-13 D4 s t | qhull
+ rbox 75 C1,1e-13 t | qhull d
+</pre>
+For Delaunay triangulations, a bounding box may alleviate this error (e.g., <tt>rbox 500 C1,1E-13 t c G1 | qhull d</tt>).
+A later release of qhull will avoid pinched horizons by merging duplicate subridges. A subridge is
+merged by merging adjacent vertices.
+<p>
+<li><b>Facet with zero-area</b> --
+It is possible for a zero-area facet to be convex with its
+neighbors. This can occur if the hyperplanes of neighboring
+facets are above the facet's centrum, and the facet's hyperplane
+is above the neighboring centrums. Qhull computes the facet's
+hyperplane so that it passes through the facet's vertices. The
+vertices can be collinear. </p>
+
+<p>
+<li><b>No more facets</b> -- Qhull reports an error if there are <em>d+1</em> facets left
+and two of the facets are not clearly convex. This typically
+occurs when the convexity constraints are too strong or the input
+points are degenerate. The former is more likely in 5-d and
+higher -- especially with option '<a href="qh-optc.htm#Cn">C-n</a>'.</p>
+
+<p>
+<li><b>Deleted cone</b> -- Lots of merging can end up deleting all
+of the new facets for a point. This is a rare event that has
+only been seen while debugging the code.
+
+<p>
+<li><b>Triangulated output leads to precision problems</b> -- With sufficient
+merging, the ridges of a non-simplicial facet may have serious topological
+and geometric problems. A ridge may be between more than two
+neighboring facets. If so, their triangulation ('<a href="qh-optq.htm#Qt">Qt</a>')
+will fail since two facets have the same vertex set. Furthermore,
+a triangulated facet may have flipped orientation compared to its
+neighbors.</li>
+
+<p>The triangulation process detects degenerate facets with
+only two neighbors. These are marked degenerate. They have
+zero area.
+
+<p>
+<li><b>Coplanar points</b> --
+Option '<a href="qh-optq.htm#Qc">Qc</a>' is determined by
+qh_check_maxout() after constructing the hull. Qhull needs to
+retain all possible coplanar points in the facets' coplanar sets.
+This depends on qh_RATIOnearInside in <tt>user.h.</tt>
+Furthermore, the cutoff for a coplanar point is arbitrarily set
+at the minimum vertex. If coplanar points are important to your
+application, remove the interior points by hand (set '<a
+href="qh-optq.htm#Qc">Qc</a> <a href="qh-optq.htm#Qi">Qi</a>') or
+make qh_RATIOnearInside sufficiently large.</p>
+
+<p>
+<li><b>Maximum roundoff error</b> -- Qhull computes the maximum roundoff error from the maximum
+coordinates of the point set. Usually the maximum roundoff error
+is a reasonable choice for all distance computations. The maximum
+roundoff error could be computed separately for each point or for
+each distance computation. This is expensive and it conflicts
+with option '<a href="qh-optc.htm#Cn">C-n</a>'.
+
+<p>
+<li><b>All flipped or upper Delaunay</b> -- When a lot of merging occurs for
+Delaunay triangulations, a new point may lead to no good facets. For example,
+try a strong convexity constraint:
+<pre>
+ rbox 1000 s t993602376 | qdelaunay C-1e-3
+</pre>
+
+</ul>
+
+<h2><a href="#TOC">&#187;</a><a name="injoggle">Joggled input</a></h2>
+
+<p>Joggled input is a simple work-around for precision problems
+in computational geometry [&quot;joggle: to shake or jar
+slightly,&quot; Amer. Heritage Dictionary]. Other names are
+<i>jostled input</i> or <i>random perturbation</i>.
+Qhull joggles the
+input by modifying each coordinate by a small random quantity. If
+a precision problem occurs, Qhull joggles the input with a larger
+quantity and the algorithm is restarted. This process continues
+until no precision problems occur. Unless all inputs incur
+precision problems, Qhull will terminate. Qhull adjusts the inner
+and outer planes to account for the joggled input. </p>
+
+<p>Neither joggle nor merged facets has an upper bound for the width of the output
+facets, but both methods work well in practice. Joggled input is
+easier to justify. Precision errors occur when the points are
+nearly singular. For example, four points may be coplanar or
+three points may be collinear. Consider a line and an incident
+point. A precision error occurs if the point is within some
+epsilon of the line. Now joggle the point away from the line by a
+small, uniformly distributed, random quantity. If the point is
+changed by more than epsilon, the precision error is avoided. The
+probability of this event depends on the maximum joggle. Once the
+maximum joggle is larger than epsilon, doubling the maximum
+joggle will halve the probability of a precision error. </p>
+
+<p>With actual data, an analysis would need to account for each
+point changing independently and other computations. It is easier
+to determine the probabilities empirically ('<a href="qh-optt.htm#TRn">TRn</a>') . For example, consider
+computing the convex hull of the unit cube centered on the
+origin. The arithmetic has 16 significant decimal digits. </p>
+
+<blockquote>
+ <p><b>Convex hull of unit cube</b> </p>
+ <table border="1">
+ <tr>
+ <th align="left">joggle</th>
+ <th align="right">error prob. </th>
+ </tr>
+ <tr>
+ <td align="right">1.0e-15</td>
+ <td align="center">0.983 </td>
+ </tr>
+ <tr>
+ <td align="right">2.0e-15</td>
+ <td align="center">0.830 </td>
+ </tr>
+ <tr>
+ <td align="right">4.0e-15</td>
+ <td align="center">0.561 </td>
+ </tr>
+ <tr>
+ <td align="right">8.0e-15</td>
+ <td align="center">0.325 </td>
+ </tr>
+ <tr>
+ <td align="right">1.6e-14</td>
+ <td align="center">0.185 </td>
+ </tr>
+ <tr>
+ <td align="right">3.2e-14</td>
+ <td align="center">0.099 </td>
+ </tr>
+ <tr>
+ <td align="right">6.4e-14</td>
+ <td align="center">0.051 </td>
+ </tr>
+ <tr>
+ <td align="right">1.3e-13</td>
+ <td align="center">0.025 </td>
+ </tr>
+ <tr>
+ <td align="right">2.6e-13</td>
+ <td align="center">0.010 </td>
+ </tr>
+ <tr>
+ <td align="right">5.1e-13</td>
+ <td align="center">0.004 </td>
+ </tr>
+ <tr>
+ <td align="right">1.0e-12</td>
+ <td align="center">0.002 </td>
+ </tr>
+ <tr>
+ <td align="right">2.0e-12</td>
+ <td align="center">0.001 </td>
+ </tr>
+ </table>
+</blockquote>
+
+<p>A larger joggle is needed for multiple points. Since the
+number of potential singularities increases, the probability of
+one or more precision errors increases. Here is an example. </p>
+
+<blockquote>
+ <p><b>Convex hull of 1000 points on unit cube</b> </p>
+ <table border="1">
+ <tr>
+ <th align="left">joggle</th>
+ <th align="right">error prob. </th>
+ </tr>
+ <tr>
+ <td align="right">1.0e-12</td>
+ <td align="center">0.870 </td>
+ </tr>
+ <tr>
+ <td align="right">2.0e-12</td>
+ <td align="center">0.700 </td>
+ </tr>
+ <tr>
+ <td align="right">4.0e-12</td>
+ <td align="center">0.450 </td>
+ </tr>
+ <tr>
+ <td align="right">8.0e-12</td>
+ <td align="center">0.250 </td>
+ </tr>
+ <tr>
+ <td align="right">1.6e-11</td>
+ <td align="center">0.110 </td>
+ </tr>
+ <tr>
+ <td align="right">3.2e-11</td>
+ <td align="center">0.065 </td>
+ </tr>
+ <tr>
+ <td align="right">6.4e-11</td>
+ <td align="center">0.030 </td>
+ </tr>
+ <tr>
+ <td align="right">1.3e-10</td>
+ <td align="center">0.010 </td>
+ </tr>
+ <tr>
+ <td align="right">2.6e-10</td>
+ <td align="center">0.008 </td>
+ </tr>
+ <tr>
+ <td align="right">5.1e-09</td>
+ <td align="center">0.003 </td>
+ </tr>
+ </table>
+</blockquote>
+
+<p>Other distributions behave similarly. No distribution should
+behave significantly worse. In Euclidean space, the probability
+measure of all singularities is zero. With floating point
+numbers, the probability of a singularity is non-zero. With
+sufficient digits, the probability of a singularity is extremely
+small for random data. For a sufficiently large joggle, all data
+is nearly random data. </p>
+
+<p>Qhull uses an initial joggle of 30,000 times the maximum
+roundoff error for a distance computation. This avoids most
+potential singularities. If a failure occurs, Qhull retries at
+the initial joggle (in case bad luck occurred). If it occurs
+again, Qhull increases the joggle by ten-fold and tries again.
+This process repeats until the joggle is a hundredth of the width
+of the input points. Qhull reports an error after 100 attempts.
+This should never happen with double-precision arithmetic. Once
+the probability of success is non-zero, the probability of
+success increases about ten-fold at each iteration. The
+probability of repeated failures becomes extremely small. </p>
+
+<p>Merged facets produces a significantly better approximation.
+Empirically, the maximum separation between inner and outer
+facets is about 30 times the maximum roundoff error for a
+distance computation. This is about 2,000 times better than
+joggled input. Most applications though will not notice the
+difference. </p>
+
+<h2><a href="#TOC">&#187;</a><a name="exact">Exact arithmetic</a></h2>
+
+<p>Exact arithmetic may be used instead of floating point.
+Singularities such as coplanar points can either be handled
+directly or the input can be symbolically perturbed. Using exact
+arithmetic is slower than using floating point arithmetic and the
+output may take more space. Chaining a sequence of operations
+increases the time and space required. Some operations are
+difficult to do.</p>
+
+<p>Clarkson's <a
+href="http://www.netlib.org/voronoi/hull.html">hull
+program</a> and Shewchuk's <a
+href="http://www.cs.cmu.edu/~quake/triangle.html">triangle
+program</a> are practical implementations of exact arithmetic.</p>
+
+<p>Clarkson limits the input precision to about fifteen digits.
+This reduces the number of nearly singular computations. When a
+determinant is nearly singular, he uses exact arithmetic to
+compute a precise result.</p>
+
+<h2><a href="#TOC">&#187;</a><a name="approximate">Approximating a
+convex hull</a></h2>
+
+<p>Qhull may be used for approximating a convex hull. This is
+particularly valuable in 5-d and higher where hulls can be
+immense. You can use '<a href="qh-optq.htm#Qx">Qx</a> <a
+href="qh-optc.htm#Cn">C-n</a>' to merge facets as the hull is
+being constructed. Then use '<a href="qh-optc.htm#Cn2">Cn</a>'
+and/or '<a href="qh-optc.htm#An2">An</a>' to merge small facets
+during post-processing. You can print the <i>n</i> largest facets
+with option '<a href="qh-optp.htm#PAn">PAn</a>'. You can print
+facets whose area is at least <i>n</i> with option '<a
+href="qh-optp.htm#PFn">PFn</a>'. You can output the outer planes
+and an interior point with '<a href="qh-optf.htm#FV">FV</a> <a
+href="qh-optf.htm#Fo">Fo</a>' and then compute their intersection
+with 'qhalf'. </p>
+
+<p>To approximate a convex hull in 6-d and higher, use
+post-merging with '<a href="qh-optc.htm#Wn">Wn</a>' (e.g., qhull
+W1e-1 C1e-2 TF2000). Pre-merging with a convexity constraint
+(e.g., qhull Qx C-1e-2) often produces a poor approximation or
+terminates with a simplex. Option '<a href="qh-optq.htm#QbB">QbB</a>'
+may help to spread out the data.</p>
+
+<p>You will need to experiment to determine a satisfactory set of
+options. Use <a href="rbox.htm">rbox</a> to generate test sets
+quickly and <a href="index.htm#geomview">Geomview</a> to view
+the results. You will probably want to write your own driver for
+Qhull using the Qhull library. For example, you could select the
+largest facet in each quadrant.</p>
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home
+page</a> for Qhull <br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of
+Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#TOC">Qhull imprecision: Table of Contents</a>
+
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-optc.htm b/xs/src/qhull/html/qh-optc.htm
new file mode 100644
index 000000000..87308180d
--- /dev/null
+++ b/xs/src/qhull/html/qh-optc.htm
@@ -0,0 +1,292 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Qhull precision options</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html"><img
+src="qh--dt.gif" alt="[delaunay]" align="middle" width="100"
+height="100"></a> Qhull precision options</h1>
+
+This section lists the precision options for Qhull. These options are
+indicated by an upper-case letter followed by a number.
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<p><a href="index.htm#TOC">&#187;</a> <a href="qh-quick.htm#programs">Programs</a>
+<a name="prec">&#149;</a> <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<h2>Precision options</h2>
+
+<p>Most users will not need to set these options. They are best
+used for <a href="qh-impre.htm#approximate">approximating</a> a
+convex hull. They may also be used for testing Qhull's handling
+of precision errors.</p>
+
+<p>By default, Qhull uses options '<a href="#C0">C-0</a>' for
+2-d, 3-d and 4-d, and '<a href="qh-optq.htm#Qx">Qx</a>' for 5-d
+and higher. These options use facet merging to handle precision
+errors. You may also use joggled input '<a href="qh-optq.htm#QJn">QJ</a>'
+to avoid precision problems.
+For more information see <a
+href="qh-impre.htm">Imprecision in Qhull</a>.</p>
+
+<dl compact>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a href="#Cn2">Cn</a></dt>
+ <dd>centrum radius for post-merging</dd>
+ <dt><a href="#Cn">C-n</a></dt>
+ <dd>centrum radius for pre-merging</dd>
+ <dt><a href="#An2">An</a></dt>
+ <dd>cosine of maximum angle for post-merging</dd>
+ <dt><a href="#An">A-n</a></dt>
+ <dd>cosine of maximum angle for pre-merging</dd>
+ <dt><a href="qh-optq.htm#Qx">Qx</a></dt>
+ <dd>exact pre-merges (allows coplanar facets)</dd>
+ <dt><a href="#C0">C-0</a></dt>
+ <dd>handle all precision errors</dd>
+ <dt><a href="#Wn">Wn</a></dt>
+ <dd>min distance above plane for outside points</dd>
+</dl>
+
+<dl compact>
+ <dt>&nbsp;</dt>
+ <dd><b>Experimental</b></dd>
+ <dt><a href="#Un">Un</a></dt>
+ <dd>max distance below plane for a new, coplanar point</dd>
+ <dt><a href="#En">En</a></dt>
+ <dd>max roundoff error for distance computation</dd>
+ <dt><a href="#Vn">Vn</a></dt>
+ <dd>min distance above plane for a visible facet</dd>
+ <dt><a href="#Rn">Rn</a></dt>
+ <dd>randomly perturb computations by a factor of [1-n,1+n]</dd>
+</dl>
+
+<dl compact>
+</dl>
+
+<hr>
+
+<h3><a href="#prec">&#187;</a><a name="An">A-n - cosine of maximum
+angle for pre-merging.</a></h3>
+
+<p>Pre-merging occurs while Qhull constructs the hull. It is
+indicated by '<a href="#Cn">C-n</a>', 'A-n', or '<a
+href="qh-optq.htm#Qx">Qx</a>'.</p>
+
+<p>If the angle between a pair of facet normals is greater than <i>n</i>,
+Qhull merges one of the facets into a neighbor. It selects the
+facet that is closest to a neighboring facet.</p>
+
+<p>For example, option 'A-0.99' merges facets during the
+construction of the hull. If the cosine of the angle between
+facets is greater than 0.99, one or the other facet is merged.
+Qhull accounts for the maximum roundoff error.</p>
+
+<p>If 'A-n' is set without '<a href="#Cn">C-n</a>', then '<a
+href="#C0">C-0</a>' is automatically set. </p>
+
+<p>In 5-d and higher, you should set '<a href="qh-optq.htm#Qx">Qx</a>'
+along with 'A-n'. It skips merges of coplanar facets until after
+the hull is constructed and before '<a href="#An2">An</a>' and '<a
+href="#Cn2">Cn</a>' are checked. </p>
+
+<h3><a href="#prec">&#187;</a><a name="An2">An - cosine of maximum angle for
+post-merging.</a></h3>
+
+<p>Post merging occurs after the hull is constructed. For
+example, option 'A0.99' merges a facet if the cosine of the angle
+between facets is greater than 0.99. Qhull accounts for the
+maximum roundoff error.</p>
+
+<p>If 'An' is set without '<a href="#Cn2">Cn</a>', then '<a
+href="#Cn2">C0</a>' is automatically set. </p>
+
+<h3><a href="#prec">&#187;</a><a name="C0">C-0 - handle all precision
+errors </a></h3>
+
+<p>Qhull handles precision errors by merging facets. The 'C-0'
+option handles all precision errors in 2-d, 3-d, and 4-d. It is
+set by default. It may be used in higher dimensions, but
+sometimes the facet width grows rapidly. It is usually better to
+use '<a href="qh-optq.htm#Qx">Qx</a>' in 5-d and higher.
+Use '<a href="qh-optq.htm#QJn">QJ</a>' to joggle the input
+instead of merging facets.
+Use '<a
+href="qh-optq.htm#Q0">Q0</a>' to turn both options off.</p>
+
+<p>Qhull optimizes 'C-0' (&quot;_zero-centrum&quot;) by testing
+vertices instead of centrums for adjacent simplices. This may be
+slower in higher dimensions if merges decrease the number of
+processed points. The optimization may be turned off by setting a
+small value such as 'C-1e-30'. See <a href="qh-impre.htm">How
+Qhull handles imprecision</a>.</p>
+
+<h3><a href="#prec">&#187;</a><a name="Cn">C-n - centrum radius for
+pre-merging</a></h3>
+
+<p>Pre-merging occurs while Qhull constructs the hull. It is
+indicated by 'C-n', '<a href="#An">A-n</a>', or '<a
+href="qh-optq.htm#Qx">Qx</a>'.</p>
+
+<p>The <i>centrum</i> of a facet is a point on the facet for
+testing facet convexity. It is the average of the vertices
+projected to the facet's hyperplane. Two adjacent facets are
+convex if each centrum is clearly below the other facet. </p>
+
+<p>If adjacent facets are non-convex, one of the facets is merged
+into a neighboring facet. Qhull merges the facet that is closest
+to a neighboring facet. </p>
+
+<p>For option 'C-n', <i>n</i> is the centrum radius. For example,
+'C-0.001' merges facets whenever the centrum is less than 0.001
+from a neighboring hyperplane. Qhull accounts for roundoff error
+when testing the centrum.</p>
+
+<p>In 5-d and higher, you should set '<a href="qh-optq.htm#Qx">Qx</a>'
+along with 'C-n'. It skips merges of coplanar facets until after
+the hull is constructed and before '<a href="#An2">An</a>' and '<a
+href="#Cn2">Cn</a>' are checked. </p>
+
+<h3><a href="#prec">&#187;</a><a name="Cn2">Cn - centrum radius for
+post-merging</a></h3>
+
+<p>Post-merging occurs after Qhull constructs the hull. It is
+indicated by '<a href="#Cn2">Cn</a>' or '<a href="#An2">An</a>'. </p>
+
+<p>For option '<a href="#Cn2">Cn</a>', <i>n</i> is the centrum
+radius. For example, 'C0.001' merges facets when the centrum is
+less than 0.001 from a neighboring hyperplane. Qhull accounts for
+roundoff error when testing the centrum.</p>
+
+<p>Both pre-merging and post-merging may be defined. If only
+post-merging is used ('<a href="qh-optq.htm#Q0">Q0</a>' with
+'Cn'), Qhull may fail to produce a hull due to precision errors
+during the hull's construction.</p>
+
+<h3><a href="#prec">&#187;</a><a name="En">En - max roundoff error
+for distance computations</a></h3>
+
+<p>This allows the user to change the maximum roundoff error
+computed by Qhull. The value computed by Qhull may be overly
+pessimistic. If 'En' is set too small, then the output may not be
+convex. The statistic &quot;max. distance of a new vertex to a
+facet&quot; (from option '<a href="qh-optt.htm#Ts">Ts</a>') is a
+reasonable upper bound for the actual roundoff error. </p>
+
+<h3><a href="#prec">&#187;</a><a name="Rn">Rn - randomly perturb
+computations </a></h3>
+
+<p>This option perturbs every distance, hyperplane, and angle
+computation by up to <i>(+/- n * max_coord)</i>. It simulates the
+effect of roundoff errors. Unless '<a href="#En">En</a>' is
+explicitly set, it is adjusted for 'Rn'. The command 'qhull Rn'
+will generate a convex hull despite the perturbations. See the <a
+href="qh-eg.htm#merge">Examples </a>section for an example.</p>
+
+<p>Options 'Rn C-n' have the effect of '<a href="#Wn">W2n</a>'
+and '<a href="#Cn">C-2n</a>'. To use time as the random number
+seed, use option '<a href="qh-optq.htm#QRn">QR-1</a>'.</p>
+
+<h3><a href="#prec">&#187;</a><a name="Un">Un - max distance for a
+new, coplanar point </a></h3>
+
+<p>This allows the user to set coplanarity. When pre-merging ('<a
+href="#Cn">C-n </a>', '<a href="#An">A-n</a>' or '<a
+href="qh-optq.htm#Qx">Qx</a>'), Qhull merges a new point into any
+coplanar facets. The default value for 'Un' is '<a href="#Vn">Vn</a>'.</p>
+
+<h3><a href="#prec">&#187;</a><a name="Vn">Vn - min distance for a
+visible facet </a></h3>
+
+<p>This allows the user to set facet visibility. When adding a
+point to the convex hull, Qhull determines all facets that are
+visible from the point. A facet is visible if the distance from
+the point to the facet is greater than 'Vn'.</p>
+
+<p>Without merging, the default value for 'Vn' is the roundoff
+error ('<a href="#En">En</a>'). With merging, the default value
+is the pre-merge centrum ('<a href="#Cn">C-n</a>') in 2-d or 3-d,
+or three times that in other dimensions. If the outside width is
+specified with option '<a href="#Wn">Wn </a>', the maximum,
+default value for 'Vn' is '<a href="#Wn">Wn</a>'.</p>
+
+<p>Qhull warns if 'Vn' is greater than '<a href="#Wn">Wn</a>' and
+furthest outside ('<a href="qh-optq.htm#Qf">Qf</a>') is not
+selected; this combination usually results in flipped facets
+(i.e., reversed normals).</p>
+
+<h3><a href="#prec">&#187;</a><a name="Wn">Wn - min distance above
+plane for outside points</a></h3>
+
+<p>Points are added to the convex hull only if they are clearly
+outside of a facet. A point is outside of a facet if its distance
+to the facet is greater than 'Wn'. Without pre-merging, the
+default value for 'Wn' is '<a href="#En">En </a>'. If the user
+specifies pre-merging and does not set 'Wn', than 'Wn' is set to
+the maximum of '<a href="#Cn">C-n</a>' and <i>maxcoord*(1 - </i><a
+href="#An"><i>A-n</i></a><i>)</i>.</p>
+
+<p>This option is good for <a href="qh-impre.htm#approximate">approximating</a>
+a convex hull.</p>
+
+<p>Options '<a href="qh-optq.htm#Qc">Qc</a>' and '<a
+href="qh-optq.htm#Qi">Qi</a>' use the minimum vertex to
+distinguish coplanar points from interior points.</p>
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-optf.htm b/xs/src/qhull/html/qh-optf.htm
new file mode 100644
index 000000000..3c7a2b1db
--- /dev/null
+++ b/xs/src/qhull/html/qh-optf.htm
@@ -0,0 +1,736 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Qhull format options (F)</title>
+</head>
+
+<body><!-- Navigation links -->
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+<hr>
+<!-- Main text of document -->
+<h1><a
+ href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html"><IMG
+ align=middle alt=[delaunay] height=100
+ src="qh--dt.gif" width=100 ></a> Qhull format options (F)</h1>
+
+<p>This section lists the format options for Qhull. These options
+are indicated by 'F' followed by a letter. See <A
+ href="qh-opto.htm#output" >Output</a>, <a href="qh-optp.htm#print">Print</a>,
+and <a href="qh-optg.htm#geomview">Geomview</a> for other output
+options. </p>
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<p><a href="index.htm#TOC">&#187;</a> <a href="qh-quick.htm#programs">Programs</a>
+<a name="format">&#149;</a> <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<h2>Additional input &amp; output formats</h2>
+
+<p>These options allow for automatic processing of Qhull output.
+Options '<a href="qh-opto.htm#i">i</a>', '<a href="qh-opto.htm#o">o</a>',
+'<a href="qh-opto.htm#n">n</a>', and '<a href="qh-opto.htm#p">p</a>'
+may also be used.</p>
+
+<dl compact>
+ <dt>
+ <dd><b>Summary and control</b>
+ <dt><a href="#FA">FA</a>
+ <dd>compute total area and volume for option '<A
+ href="qh-opto.htm#s">s</a>'
+
+ <dt><a href="#FV">FV</a>
+ <dd>print average vertex (interior point for '<A
+ href="qhalf.htm">qhalf</a>')
+ <dt><a href="#FQ">FQ</a>
+ <dd>print command for qhull and input
+ <dt><a href="#FO">FO</a>
+ <dd>print options to stderr or stdout
+ <dt><a href="#FS">FS</a>
+ <dd>print sizes: total area and volume
+ <dt><a href="#Fs">Fs</a>
+ <dd>print summary: dim, #points, total vertices and
+ facets, #vertices, #facets, max outer and inner plane
+ <dt><a href="#Fd">Fd</a>
+ <dd>use format for input (offset first)
+ <dt><a href="#FD">FD</a>
+ <dd>use cdd format for normals (offset first)
+ <dt><a href="#FM">FM</a>
+ <dd>print Maple output (2-d and 3-d)
+ <dt>
+ <dt>
+ <dd><b>Facets, points, and vertices</b>
+ <dt><a href="#Fa">Fa</a>
+ <dd>print area for each facet
+ <dt><a href="#FC">FC</a>
+ <dd>print centrum for each facet
+ <dt><a href="#Fc">Fc</a>
+ <dd>print coplanar points for each facet
+ <dt><a href="#Fx">Fx</a>
+ <dd>print extreme points (i.e., vertices) of convex hull.
+
+ <dt><a href="#FF">FF</a>
+ <dd>print facets w/o ridges
+ <dt><a href="#FI">FI</a>
+ <dd>print ID for each facet
+ <dt><a href="#Fi">Fi</a>
+ <dd>print inner planes for each facet
+ <dt><a href="#Fm">Fm</a>
+ <dd>print merge count for each facet (511 max)
+ <dt><a href="#FP">FP</a>
+ <dd>print nearest vertex for coplanar points
+ <dt><a href="#Fn">Fn</a>
+ <dd>print neighboring facets for each facet
+ <dt><a href="#FN">FN</a>
+ <dd>print neighboring facets for each point
+ <dt><a href="#Fo">Fo</a>
+ <dd>print outer planes for each facet
+ <dt><a href="#Ft">Ft</a>
+ <dd>print triangulation with added points
+ <dt><a href="#Fv">Fv</a>
+ <dd>print vertices for each facet
+ <dt>
+ <dt>
+ <dd><b>Delaunay, Voronoi, and halfspace</b>
+ <dt><a href="#Fx">Fx</a>
+ <dd>print extreme input sites of Delaunay triangulation
+ or Voronoi diagram.
+ <dt><a href="#Fp">Fp</a>
+ <dd>print points at halfspace intersections
+ <dt><a href="#Fi2">Fi</a>
+ <dd>print separating hyperplanes for inner, bounded
+ Voronoi regions
+ <dt><a href="#Fo2">Fo</a>
+ <dd>print separating hyperplanes for outer, unbounded
+ Voronoi regions
+ <dt><a href="#Fv2">Fv</a>
+ <dd>print Voronoi diagram as ridges for each input pair
+ <dt><a href="#FC">FC</a>
+ <dd>print Voronoi vertex ("center") for each facet</dd>
+</dl>
+
+<hr>
+
+<h3><a href="#format">&#187;</a><a name="Fa">Fa - print area for each
+facet </a></h3>
+
+<p>The first line is the number of facets. The remaining lines
+are the area for each facet, one facet per line. See '<A
+ href="#FA" >FA</a>' and '<a href="#FS">FS</a>' for computing the total area and volume.</p>
+
+<p>Use '<a href="qh-optp.htm#PAn">PAn</a>' for printing the n
+largest facets. Use option '<a href="qh-optp.htm#PFn">PFn</a>'
+for printing facets larger than <i>n</i>.</p>
+
+<p>For Delaunay triangulations, the area is the area of each
+Delaunay triangle. For Voronoi vertices, the area is the area of
+the dual facet to each vertex. </p>
+
+<p>Qhull uses the centrum and ridges to triangulate
+non-simplicial facets. The area for non-simplicial facets is the
+sum of the areas for each triangle. It is an approximation of the
+actual area. The ridge's vertices are projected to the facet's
+hyperplane. If a vertex is far below a facet (qh_WIDEcoplanar in <tt>user.h</tt>),
+the corresponding triangles are ignored.</p>
+
+<p>For non-simplicial facets, vertices are often below the
+facet's hyperplane. If so, the approximation is less than the
+actual value and it may be significantly less. </p>
+
+<h3><a href="#format">&#187;</a><a name="FA">FA - compute total area
+and volume for option 's' </a></h3>
+
+<p>With option 'FA', Qhull includes the total area and volume in
+the summary ('<a href="qh-opto.htm#s">s</a>'). Option '<a href="#FS">FS</a>' also includes the total area and volume.
+If facets are
+merged, the area and volume are approximations. Option 'FA' is
+automatically set for options '<a href="#Fa">Fa</a>', '<A
+ href="qh-optp.htm#PAn" >PAn</a>', and '<a href="qh-optp.htm#PFn">PFn</a>'.
+</p>
+
+<p>With '<a href="qdelaun.htm">qdelaunay</a> <A
+ href="qh-opto.htm#s" >s</a> FA', Qhull computes the total area of
+the Delaunay triangulation. This equals the volume of the convex
+hull of the data points. With options '<a href="qdelau_f.htm">qdelaunay Qu</a>
+<a href="qh-opto.htm#s">s</a> FA', Qhull computes the
+total area of the furthest-site Delaunay triangulation. This
+equals of the total area of the Delaunay triangulation. </p>
+
+<p>See '<a href="#Fa">Fa</a>' for further details. Option '<a href="#FS">FS</a>' also computes the total area and volume.</p>
+
+<h3><a href="#format">&#187;</a><a name="Fc">Fc - print coplanar
+points for each facet </a></h3>
+
+<p>The output starts with the number of facets. Then each facet
+is printed one per line. Each line is the number of coplanar
+points followed by the point ids. </p>
+
+<p>By default, option 'Fc' reports coplanar points
+('<a href="qh-optq.htm#Qc">Qc</a>'). You may also use
+option '<a href="qh-optq.htm#Qi">Qi</a>'. Options 'Qi Fc' prints
+interior points while 'Qci Fc' prints both coplanar and interior
+points.
+
+<p>Each coplanar point or interior point is assigned to the
+facet it is furthest above (resp., least below). </p>
+
+<p>Use 'Qc <a href="qh-opto.htm#p">p</a>' to print vertex and
+coplanar point coordinates. Use '<a href="qh-optf.htm#Fv">Fv</a>'
+to print vertices. </p>
+
+<h3><a href="#format">&#187;</a><a name="FC">FC - print centrum or
+Voronoi vertex for each facet </a></h3>
+
+<p>The output starts with the dimension followed by the number of
+facets. Then each facet centrum is printed, one per line. For
+<a href="qvoronoi.htm">qvoronoi</a>, Voronoi vertices are
+printed instead. </p>
+
+<h3><a href="#format">&#187;</a><a name="Fd">Fd - use cdd format for
+input </a></h3>
+
+<p>The input starts with comments. The first comment is reported
+in the summary. Data starts after a "begin" line. The
+next line is the number of points followed by the dimension plus
+one and "real" or "integer". Then the points
+are listed with a leading "1" or "1.0". The
+data ends with an "end" line.</p>
+
+<p>For halfspaces ('<a href="qhalf.htm">qhalf</a> Fd'),
+the input format is the same. Each halfspace starts with its
+offset. The signs of the offset and coefficients are the
+opposite of Qhull's
+convention. The first two lines of the input may be an interior
+point in '<a href="#FV">FV</a>' format.</p>
+
+<h3><a href="#format">&#187;</a><a name="FD">FD - use cdd format for
+normals </a></h3>
+
+<p>Option 'FD' prints normals ('<a href="qh-opto.htm#n">n</a>', '<A
+ href="#Fo" >Fo</a>', '<a href="#Fi">Fi</a>') or points ('<A
+ href="qh-opto.htm#p" >p</a>') in cdd format. The first line is the
+command line that invoked Qhull. Data starts with a
+"begin" line. The next line is the number of normals or
+points followed by the dimension plus one and "real".
+Then the normals or points are listed with the offset before the
+coefficients. The offset for points is 1.0. For normals,
+the offset and coefficients use the opposite sign from Qhull.
+The data ends with an "end" line.</p>
+
+<h3><a href="#format">&#187;</a><a name="FF">FF - print facets w/o
+ridges </a></h3>
+
+<p>Option 'FF' prints all fields of all facets (as in '<A
+ href="qh-opto.htm#f" >f</a>') without printing the ridges. This is
+useful in higher dimensions where a facet may have many ridges.
+For simplicial facets, options 'FF' and '<a href="qh-opto.htm#f">f
+</a>' are equivalent.</p>
+
+<h3><a href="#format">&#187;</a><a name="Fi">Fi - print inner planes
+for each facet </a></h3>
+
+<p>The first line is the dimension plus one. The second line is
+the number of facets. The remainder is one inner plane per line.
+The format is the same as option '<a href="qh-opto.htm#n">n</a>'.</p>
+
+<p>The inner plane is a plane that is below the facet's vertices.
+It is an offset from the facet's hyperplane. It includes a
+roundoff error for computing the vertex distance.</p>
+
+<p>Note that the inner planes for Geomview output ('<A
+ href="qh-optg.htm#Gi" >Gi</a>') include an additional offset for
+vertex visualization and roundoff error. </p>
+
+<h3><a href="#format">&#187;</a><a name="Fi2">Fi - print separating
+hyperplanes for inner, bounded Voronoi regions</a></h3>
+
+<p>With <a href="qvoronoi.htm" >qvoronoi</a>, 'Fi' prints the
+separating hyperplanes for inner, bounded regions of the Voronoi
+diagram. The first line is the number of ridges. Then each
+hyperplane is printed, one per line. A line starts with the
+number of indices and floats. The first pair of indices indicates
+an adjacent pair of input sites. The next <i>d</i> floats are the
+normalized coefficients for the hyperplane, and the last float is
+the offset. The hyperplane is oriented toward '<A
+ href="qh-optq.htm#QVn" >QVn</a>' (if defined), or the first input
+site of the pair. </p>
+
+<p>Use '<a href="qh-optf.htm#Fo2">Fo</a>' for unbounded regions,
+and '<a href="qh-optf.htm#Fv2">Fv</a>' for the corresponding
+Voronoi vertices. </p>
+
+<p>Use '<a href="qh-optt.htm#Tv">Tv</a>' to verify that the
+hyperplanes are perpendicular bisectors. It will list relevant
+statistics to stderr. The hyperplane is a perpendicular bisector
+if the midpoint of the input sites lies on the plane, all Voronoi
+vertices in the ridge lie on the plane, and the angle between the
+input sites and the plane is ninety degrees. This is true if all
+statistics are zero. Roundoff and computation errors make these
+non-zero. The deviations appear to be largest when the
+corresponding Delaunay triangles are large and thin; for example,
+the Voronoi diagram of nearly cospherical points. </p>
+
+<h3><a href="#format">&#187;</a><a name="FI">FI - print ID for each
+facet </a></h3>
+
+<p>Print facet identifiers. These are used internally and listed
+with options '<a href="qh-opto.htm#f">f</a>' and '<a href="#FF">FF</a>'.
+Options '<a href="#Fn">Fn </a>' and '<a href="#FN">FN</a>' use
+facet identifiers for negative indices. </p>
+
+<h3><a href="#format">&#187;</a><a name="Fm">Fm - print merge count
+for each facet </a></h3>
+
+<p>The first line is the number of facets. The remainder is the
+number of merges for each facet, one per line. At most 511 merges
+are reported for a facet. See '<a href="qh-optp.htm#PMn">PMn</a>'
+for printing the facets with the most merges. </p>
+
+<h3><a href="#format">&#187;</a><a name="FM">FM - print Maple
+output </a></h3>
+
+<p>Qhull writes a Maple file for 2-d and 3-d convex hulls,
+2-d and 3-d halfspace intersections,
+and 2-d Delaunay triangulations. Qhull produces a 2-d
+or 3-d plot.
+
+<p><i>Warning</i>: This option has not been tested in Maple.
+
+<p>[From T. K. Abraham with help from M. R. Feinberg and N. Platinova.]
+The following steps apply while working within the
+Maple worksheet environment :
+<ol>
+<li>Generate the data and store it as an array . For example, in 3-d, data generated
+in Maple is of the form : x[i],y[i],z[i]
+<p>
+<li>Create a single variable and assign the entire array of data points to this variable.
+Use the "seq" command within square brackets as shown in the following example.
+(The square brackets are essential for the rest of the steps to work.)
+<p>
+>data:=[seq([x[i],y[i],z[i]],i=1..n)]:# here n is the number of data points
+
+<li>Next we need to write the data to a file to be read by qhull. Before
+writing the data to a file, make sure that the qhull executable files and
+the data file lie in the same subdirectory. If the executable files are
+stored in the "C:\qhull3.1\" subdirectory, then save the file in the same
+subdirectory, say "C:\qhull3.1\datafile.txt". For the sake of integrity of
+the data file , it is best to first ensure that the data file does not
+exist before writing into the data file. This can be done by running a
+delete command first . To write the data to the file, use the "writedata"
+and the "writedata[APPEND]" commands as illustrated in the following example :
+<p>
+>system("del c:\\qhull3.1\\datafile.txt");#To erase any previous versions of the file
+<br>>writedata("c:\\qhull3.1\\datafile.txt ",[3, nops(data)]);#writing in qhull format
+<br>>writedata[APPEND]("c:\\ qhull3.1\\datafile.txt ", data);#writing the data points
+<li>
+Use the 'FM' option to produce Maple output. Store the output as a ".mpl" file.
+For example, using the file we created above, we type the following (in DOS environment)
+<p>
+qconvex s FM &lt;datafile.txt >dataplot.mpl
+
+<li>
+To read 3-d output in Maple, we use the 'read' command followed by
+a 'display3d' command. For example (in Maple environment):
+<p>
+>with (plots):
+<br>>read `c:\\qhull3.1\\dataplot.mpl`:#IMPORTANT - Note that the punctuation mark used is ' and NOT '. The correct punctuation mark is the one next to the key for "1" (not the punctuation mark near the enter key)
+<br>> qhullplot:=%:
+<br>> display3d(qhullplot);
+</ol>
+
+<p>For Delaunay triangulation orthogonal projection is better.
+
+<p>For halfspace intersections, Qhull produces the dual
+convex hull.
+
+<p>See <a href="qh-faq.htm#math">Is Qhull available for Maple?</a>
+for other URLs.
+
+<h3><a href="#format">&#187;</a><a name="Fn">Fn - print neighboring
+facets for each facet </a></h3>
+
+<p>The output starts with the number of facets. Then each facet
+is printed one per line. Each line is the number of neighbors
+followed by an index for each neighbor. The indices match the
+other facet output formats.</p>
+
+<p>For simplicial facets, each neighbor is opposite
+the corresponding vertex (option '<a href="#Fv">Fv</a>').
+Do not compare to option '<a href="qh-opto.htm#i">i</a>'. Option 'i'
+orients facets by reversing the order of two vertices. For non-simplicial facets,
+the neighbors are unordered.
+
+<p>A negative index indicates an unprinted facet due to printing
+only good facets ('<a href="qh-optp.htm#Pg">Pg</a>', <a href="qdelaun.htm" >qdelaunay</a>,
+<a href="qvoronoi.htm" >qvoronoi</a>). It
+is the negation of the facet's ID (option '<a href="#FI">FI</a>').
+For example, negative indices are used for facets "at
+infinity" in the Delaunay triangulation.</p>
+
+<h3><a href="#format">&#187;</a><a name="FN">FN - print neighboring
+facets for each point </a></h3>
+
+<p>The first line is the number of points. Then each point is
+printed, one per line. For unassigned points (either interior or
+coplanar), the line is "0". For assigned coplanar
+points ('<a href="qh-optq.htm#Qc">Qc</a>'), the line is
+"1" followed by the index of the facet that is furthest
+below the point. For assigned interior points ('<A
+ href="qh-optq.htm#Qi" >Qi</a>'), the line is "1"
+followed by the index of the facet that is least above the point.
+For vertices that do not belong to good facet, the line is
+"0"</p>
+
+<p>For vertices of good facets, the line is the number of
+neighboring facets followed by the facet indices. The indices
+correspond to the other '<a href="#format">F</a>' formats. In 4-d
+and higher, the facets are sorted by index. In 3-d, the facets
+are in adjacency order (not oriented).</p>
+
+<p>A negative index indicates an unprinted facet due to printing
+only good facets (<a href="qdelaun.htm" >qdelaunay</a>,
+<a href="qvoronoi.htm" >qvoronoi</a>, '<a href="qh-optp.htm#Pdk">Pdk</a>',
+'<a href="qh-optp.htm#Pg">Pg</a>'). It is the negation of the
+facet's ID ('<a href="#FI"> FI</a>'). For example, negative
+indices are used for facets "at infinity" in the
+Delaunay triangulation.</p>
+
+<p>For Voronoi vertices, option 'FN' lists the vertices of the
+Voronoi region for each input site. Option 'FN' lists the regions
+in site ID order. Option 'FN' corresponds to the second half of
+option '<a href="qh-opto.htm#o">o</a>'. To convert from 'FN' to '<A
+ href="qh-opto.htm#o" >o</a>', replace negative indices with zero
+and increment non-negative indices by one. </p>
+
+<p>If you are using the <a href="qh-code.htm#library">Qhull
+library</a> or <a href="qh-code.htm#cpp">C++ interface</a>, option 'FN' has the side effect of reordering the
+neighbors for a vertex </p>
+
+<h3><a href="#format">&#187;</a><a name="Fo">Fo - print outer planes
+for each facet </a></h3>
+
+<p>The first line is the dimension plus one. The second line is
+the number of facets. The remainder is one outer plane per line.
+The format is the same as option '<a href="qh-opto.htm#n">n</a>'.</p>
+
+<p>The outer plane is a plane that is above all points. It is an
+offset from the facet's hyperplane. It includes a roundoff error
+for computing the point distance. When testing the outer plane
+(e.g., '<a href="qh-optt.htm#Tv">Tv</a>'), another roundoff error
+should be added for the tested point.</p>
+
+<p>If outer planes are not checked ('<a href="qh-optq.htm#Q5">Q5</a>')
+or not computed (!qh_MAXoutside), the maximum, computed outside
+distance is used instead. This can be much larger than the actual
+outer planes.</p>
+
+<p>Note that the outer planes for Geomview output ('<A
+ href="qh-optg.htm#G" >G</a>') include an additional offset for
+vertex/point visualization, 'lines closer,' and roundoff error.</p>
+
+<h3><a href="#format">&#187;</a><a name="Fo2">Fo - print separating
+hyperplanes for outer, unbounded Voronoi regions</a></h3>
+
+<p>With <a href="qvoronoi.htm" >qvoronoi</a>, 'Fo' prints the
+separating hyperplanes for outer, unbounded regions of the
+Voronoi diagram. The first line is the number of ridges. Then
+each hyperplane is printed, one per line. A line starts with the
+number of indices and floats. The first pair of indices indicates
+an adjacent pair of input sites. The next <i>d</i> floats are the
+normalized coefficients for the hyperplane, and the last float is
+the offset. The hyperplane is oriented toward '<A
+ href="qh-optq.htm#QVn" >QVn</a>' (if defined), or the first input
+site of the pair. </p>
+
+<p>Option 'Fo' gives the hyperplanes for the unbounded rays of
+the unbounded regions of the Voronoi diagram. Each hyperplane
+goes through the midpoint of the corresponding input sites. The
+rays are directed away from the input sites. </p>
+
+<p>Use '<a href="qh-optf.htm#Fi2">Fi</a>' for bounded regions,
+and '<a href="qh-optf.htm#Fv2">Fv</a>' for the corresponding
+Voronoi vertices. Use '<a href="qh-optt.htm#Tv">Tv</a>' to verify
+that the corresponding Voronoi vertices lie on the hyperplane. </p>
+
+<h3><a href="#format">&#187;</a><a name="FO">FO - print list of
+selected options </a></h3>
+
+<p>Lists selected options and default values to stderr.
+Additional 'FO's are printed to stdout. </p>
+
+<h3><a href="#format">&#187;</a><a name="Fp">Fp - print points at
+halfspace intersections</a></h3>
+
+<p>The first line is the number of intersection points. The
+remainder is one intersection point per line. A intersection
+point is the intersection of <i>d</i> or more halfspaces from
+'<a href="qhalf.htm">qhalf</a>'. It corresponds to a
+facet of the dual polytope. The "infinity" point
+[-10.101,-10.101,...] indicates an unbounded intersection.</p>
+
+<p>If [x,y,z] are the dual facet's normal coefficients and <i>b&lt;0</i>
+is its offset, the halfspace intersection occurs at
+[x/-b,y/-b,z/-b] plus the interior point. If <i>b&gt;=0</i>, the
+halfspace intersection is unbounded. </p>
+
+<h3><a href="#format">&#187;</a><a name="FP">FP - print nearest
+vertex for coplanar points </a></h3>
+
+<p>The output starts with the number of coplanar points. Then
+each coplanar point is printed one per line. Each line is the
+point ID of the closest vertex, the point ID of the coplanar
+point, the corresponding facet ID, and the distance. Sort the
+lines to list the coplanar points nearest to each vertex. </p>
+
+<p>Use options '<a href="qh-optq.htm#Qc">Qc</a>' and/or '<A
+ href="qh-optq.htm#Qi" >Qi</a>' with 'FP'. Options 'Qc FP' prints
+coplanar points while 'Qci FP' prints coplanar and interior
+points. Option 'Qc' is automatically selected if 'Qi' is not
+selected.
+
+<p>For Delaunay triangulations (<a href="qdelaun.htm" >qdelaunay</a>
+or <a href="qvoronoi.htm" >qvoronoi</a>), a coplanar point is nearly
+incident to a vertex. The distance is the distance in the
+original point set.</p>
+
+<p>If imprecision problems are severe, Qhull will delete input
+sites when constructing the Delaunay triangulation. Option 'FP' will
+list these points along with coincident points.</p>
+
+<p>If there are many coplanar or coincident points and non-simplicial
+facets are triangulated ('<a href="qh-optq.htm#Qt">Qt</a>'), option
+'FP' may be inefficient. It redetermines the original vertex set
+for each coplanar point.</p>
+
+<h3><a href="#format">&#187;</a><a name="FQ">FQ - print command for
+qhull and input </a></h3>
+
+<p>Prints qhull and input command, e.g., "rbox 10 s | qhull
+FQ". Option 'FQ' may be repeated multiple times.</p>
+
+<h3><a href="#format">&#187;</a><a name="Fs">Fs - print summary</a></h3>
+
+<p>The first line consists of number of integers ("10")
+followed by the:
+<ul>
+<li>dimension
+<li>number of points
+<li>number of vertices
+<li>number of facets
+<li>number of vertices selected for output
+<li>number of facets selected for output
+<li>number of coplanar points for selected facets
+<li>number of nonsimplicial or merged facets selected for
+ output
+<LI>number of deleted vertices</LI>
+<LI>number of triangulated facets ('<a href="qh-optq.htm#Qt">Qt</a>')</LI>
+</ul>
+
+<p>The second line consists of the number of reals
+("2") followed by the:
+<ul>
+<li>maximum offset to an outer plane
+<li>minimum offset to an inner plane.</li>
+</ul>
+Roundoff and joggle are included.
+<P></P>
+
+<p>For Delaunay triangulations and Voronoi diagrams, the
+number of deleted vertices should be zero. If greater than zero, then the
+input is highly degenerate and coplanar points are not necessarily coincident
+points. For example, <tt>'RBOX 1000 s W1e-13 t995138628 | QHULL d Qbb'</tt> reports
+deleted vertices; the input is nearly cospherical.</p>
+
+<P>Later versions of Qhull may produce additional integers or reals.</P>
+
+<h3><a href="#format">&#187;</a><a name="FS">FS - print sizes</a></h3>
+
+<p>The first line consists of the number of integers
+("0"). The second line consists of the number of reals
+("2"), followed by the total facet area, and the total
+volume. Later versions of Qhull may produce additional integers
+or reals.</p>
+
+<p>The total volume measures the volume of the intersection of
+the halfspaces defined by each facet. It is computed from the
+facet area. Both area and volume are approximations for
+non-simplicial facets. See option '<a href="#Fa">Fa </a>' for
+further notes. Option '<a href="#FA">FA </a>' also computes the total area and volume. </p>
+
+<h3><a href="#format">&#187;</a><a name="Ft">Ft - print triangulation</a></h3>
+
+<p>Prints a triangulation with added points for non-simplicial
+facets. The output is </p>
+
+<ul>
+ <li>The first line is the dimension
+ <li>The second line is the number of points, the number
+ of facets, and the number of ridges.
+ <li>All of the input points follow, one per line.
+ <li>The centrums follow, one per non-simplicial facet
+ <li>Then the facets follow as a list of point indices
+ preceded by the number of points. The simplices are
+ oriented. </li>
+</ul>
+
+<p>For convex hulls with simplicial facets, the output is the
+same as option '<a href="qh-opto.htm#o">o</a>'.</p>
+
+<p>The added points are the centrums of the non-simplicial
+facets. Except for large facets, the centrum is the average
+vertex coordinate projected to the facet's hyperplane. Large
+facets may use an old centrum to avoid recomputing the centrum
+after each merge. In either case, the centrum is clearly below
+neighboring facets. See <a href="qh-impre.htm">Precision issues</a>.
+</p>
+
+<p>The new simplices will not be clearly convex with their
+neighbors and they will not satisfy the Delaunay property. They
+may even have a flipped orientation. Use triangulated input ('<A
+ href="qh-optq.htm#Qt">Qt</a>') for Delaunay triangulations.
+
+<p>For Delaunay triangulations with simplicial facets, the output is the
+same as option '<a href="qh-opto.htm#o">o</a>' without the lifted
+coordinate. Since 'Ft' is invalid for merged Delaunay facets, option
+'Ft' is not available for qdelaunay or qvoronoi. It may be used with
+joggled input ('<a href="qh-optq.htm#QJn" >QJ</a>') or triangulated output ('<A
+ href="qh-optq.htm#Qt" >Qt</a>'), for example, rbox 10 c G 0.01 | qhull d QJ Ft</p>
+
+<p>If you add a point-at-infinity with '<a href="qh-optq.htm#Qz">Qz</a>',
+it is printed after the input sites and before any centrums. It
+will not be used in a Delaunay facet.</p>
+
+<h3><a href="#format">&#187;</a><a name="Fv">Fv - print vertices for
+each facet</a></h3>
+
+<p>The first line is the number of facets. Then each facet is
+printed, one per line. Each line is the number of vertices
+followed by the corresponding point ids. Vertices are listed in
+the order they were added to the hull (the last one added is the
+first listed).
+</p>
+<p>Option '<a href="qh-opto.htm#i">i</a>' also lists the vertices,
+but it orients facets by reversing the order of two
+vertices. Option 'i' triangulates non-simplicial, 4-d and higher facets by
+adding vertices for the centrums.
+</p>
+
+<h3><a href="#format">&#187;</a><a name="Fv2">Fv - print Voronoi
+diagram</a></h3>
+
+<p>With <a href="qvoronoi.htm" >qvoronoi</a>, 'Fv' prints the
+Voronoi diagram or furthest-site Voronoi diagram. The first line
+is the number of ridges. Then each ridge is printed, one per
+line. The first number is the count of indices. The second pair
+of indices indicates a pair of input sites. The remaining indices
+list the corresponding ridge of Voronoi vertices. Vertex 0 is the
+vertex-at-infinity. It indicates an unbounded ray. </p>
+
+<p>All vertices of a ridge are coplanar. If the ridge is
+unbounded, add the midpoint of the pair of input sites. The
+unbounded ray is directed from the Voronoi vertices to infinity. </p>
+
+<p>Use '<a href="qh-optf.htm#Fo2">Fo</a>' for separating
+hyperplanes of outer, unbounded regions. Use '<A
+ href="qh-optf.htm#Fi2" >Fi</a>' for separating hyperplanes of
+inner, bounded regions. </p>
+
+<p>Option 'Fv' does not list ridges that require more than one
+midpoint. For example, the Voronoi diagram of cospherical points
+lists zero ridges (e.g., 'rbox 10 s | qvoronoi Fv Qz').
+Other examples are the Voronoi diagrams of a rectangular mesh
+(e.g., 'rbox 27 M1,0 | qvoronoi Fv') or a point set with
+a rectangular corner (e.g.,
+'rbox P4,4,4 P4,2,4 P2,4,4 P4,4,2 10 | qvoronoi Fv').
+Both cases miss unbounded rays at the corners.
+To determine these ridges, surround the points with a
+large cube (e.g., 'rbox 10 s c G2.0 | qvoronoi Fv Qz').
+The cube needs to be large enough to bound all Voronoi regions of the original point set.
+Please report any other cases that are missed. If you
+can formally describe these cases or
+write code to handle them, please send email to <A
+ href="mailto:qhull@qhull.org" >qhull@qhull.org</a>. </p>
+
+<h3><a href="#format">&#187;</a><a name="FV">FV - print average
+vertex </a></h3>
+
+<p>The average vertex is the average of all vertex coordinates.
+It is an interior point for halfspace intersection. The first
+line is the dimension and "1"; the second line is the
+coordinates. For example,</p>
+
+<blockquote>
+ <p>qconvex FV <A
+ href="qh-opto.htm#n">n</a> | qhalf <a href="#Fp">Fp</a></p>
+</blockquote>
+
+<p>prints the extreme points of the original point set (roundoff
+included). </p>
+
+<h3><a href="#format">&#187;</a><a name="Fx">Fx - print extreme
+points (vertices) of convex hulls and Delaunay triangulations</a></h3>
+
+<p>The first line is the number of points. The following lines
+give the index of the corresponding points. The first point is
+'0'. </p>
+
+<p>In 2-d, the extreme points (vertices) are listed in
+counterclockwise order (by qh_ORIENTclock in user.h). </p>
+
+<p>In 3-d and higher convex hulls, the extreme points (vertices)
+are sorted by index. This is the same order as option '<A
+ href="qh-opto.htm#p" >p</a>' when it doesn't include coplanar or
+interior points. </p>
+
+<p>For Delaunay triangulations, 'Fx' lists the extreme
+points of the input sites (i.e., the vertices of their convex hull). The points
+are unordered. <!-- Navigation links --> </p>
+
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p><!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><IMG align=middle
+ height=40 src="qh--geom.gif" width=40 ></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created:
+Sept. 25, 1995 --- <!-- hhmts start -->Last modified: see top
+<!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-optg.htm b/xs/src/qhull/html/qh-optg.htm
new file mode 100644
index 000000000..a56e29df1
--- /dev/null
+++ b/xs/src/qhull/html/qh-optg.htm
@@ -0,0 +1,274 @@
+<html>
+
+<head>
+<title>Qhull Geomview options (G)</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<hr>
+<!-- Main text of document -->
+
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html"><img
+src="qh--dt.gif" alt="[delaunay]" align="middle" width="100"
+height="100"></a> Qhull Geomview options (G)</h1>
+
+This section lists the Geomview options for Qhull. These options are
+indicated by 'G' followed by a letter. See
+<a href="qh-opto.htm#output">Output</a>, <a href="qh-optp.htm#print">Print</a>,
+and <a href="qh-optf.htm#format">Format</a> for other output options.
+
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<p><a href="index.htm#TOC">&#187;</a> <a href="qh-quick.htm#programs">Programs</a>
+<a name="geomview">&#149;</a> <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<h2>Geomview output options</h2>
+
+<p><a href="http://www.geomview.org">Geomview</a> is the graphical
+viewer for visualizing Qhull output in 2-d, 3-d and 4-d.</p>
+
+<p>Geomview displays each facet of the convex hull. The color of
+a facet is determined by the coefficients of the facet's normal
+equation. For imprecise hulls, Geomview displays the inner and
+outer hull. Geomview can also display points, ridges, vertices,
+coplanar points, and facet intersections. </p>
+
+<p>For 2-d Delaunay triangulations, Geomview displays the
+corresponding paraboloid. Geomview displays the 2-d Voronoi
+diagram. For halfspace intersections, it displays the
+dual convex hull. </p>
+
+<dl compact>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a href="#G">G</a></dt>
+ <dd>display Geomview output</dd>
+ <dt><a href="#Gt">Gt</a></dt>
+ <dd>display transparent 3-d Delaunay triangulation</dd>
+ <dt><a href="#GDn">GDn</a></dt>
+ <dd>drop dimension n in 3-d and 4-d output </dd>
+
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Specific</b></dd>
+ <dt><a href="#Ga">Ga</a></dt>
+ <dd>display all points as dots</dd>
+ <dt><a href="#Gc">Gc</a></dt>
+ <dd>display centrums (2-d, 3-d)</dd>
+ <dt><a href="#Gp">Gp</a></dt>
+ <dd>display coplanar points and vertices as radii</dd>
+ <dt><a href="#Gh">Gh</a></dt>
+ <dd>display hyperplane intersections</dd>
+ <dt><a href="#Gi">Gi</a></dt>
+ <dd>display inner planes only (2-d, 3-d)</dd>
+ <dt><a href="#Go">Go</a></dt>
+ <dd>display outer planes only (2-d, 3-d)</dd>
+ <dt><a href="#Gr">Gr</a></dt>
+ <dd>display ridges (3-d)</dd>
+ <dt><a href="#Gv">Gv</a></dt>
+ <dd>display vertices as spheres</dd>
+ <dt><a href="#Gn">Gn</a></dt>
+ <dd>do not display planes</dd>
+
+</dl>
+
+<hr>
+
+<h3><a href="#geomview">&#187;</a><a name="G">G - produce output for
+viewing with Geomview</a></h3>
+
+<p>By default, option 'G' displays edges in 2-d, outer planes in
+3-d, and ridges in 4-d.</p>
+
+<p>A ridge can be explicit or implicit. An explicit ridge is a <i>(d-1)</i>-dimensional
+simplex between two facets. In 4-d, the explicit ridges are
+triangles. An implicit ridge is the topological intersection of
+two neighboring facets. It is the union of explicit ridges.</p>
+
+<p>For non-simplicial 4-d facets, the explicit ridges can be
+quite complex. When displaying a ridge in 4-d, Qhull projects the
+ridge's vertices to one of its facets' hyperplanes. Use '<a
+href="#Gh">Gh</a>' to project ridges to the intersection of both
+hyperplanes. This usually results in a cleaner display. </p>
+
+<p>For 2-d Delaunay triangulations, Geomview displays the
+corresponding paraboloid. Geomview displays the 2-d Voronoi
+diagram. For halfspace intersections, it displays the
+dual convex hull.
+
+<h3><a href="#geomview">&#187;</a><a name="Ga">Ga - display all
+points as dots </a></h3>
+
+<p>Each input point is displayed as a green dot.</p>
+
+<h3><a href="#geomview">&#187;</a><a name="Gc">Gc - display centrums
+(3-d) </a></h3>
+
+<p>The centrum is defined by a green radius sitting on a blue
+plane. The plane corresponds to the facet's hyperplane. If you
+sight along a facet's hyperplane, you will see that all
+neighboring centrums are below the facet. The radius is defined
+by '<a href="qh-optc.htm#Cn">C-n</a>' or '<a
+href="qh-optc.htm#Cn2">Cn</a>'.</p>
+
+<h3><a href="#geomview">&#187;</a><a name="GDn">GDn - drop dimension
+n in 3-d and 4-d output </a></h3>
+
+<p>The result is a 2-d or 3-d object. In 4-d, this corresponds to
+viewing the 4-d object from the nth axis without perspective.
+It's best to view 4-d objects in pieces. Use the '<a
+href="qh-optp.htm#Pdk">Pdk</a>' '<a href="qh-optp.htm#Pg">Pg</a>'
+'<a href="qh-optp.htm#PG">PG</a>' '<a href="qh-optq.htm#QGn">QGn</a>'
+and '<a href="qh-optq.htm#QVn">QVn</a>' options to select a few
+facets. If one of the facets is perpendicular to an axis, then
+projecting along that axis will show the facet exactly as it is
+in 4-d. If you generate many facets, use Geomview's <tt>ginsu</tt>
+module to view the interior</p>
+
+<p>To view multiple 4-d dimensions at once, output the object
+without 'GDn' and read it with Geomview's <tt>ndview</tt>. As you
+rotate the object in one set of dimensions, you can see how it
+changes in other sets of dimensions.</p>
+
+<p>For additional control over 4-d objects, output the object
+without 'GDn' and read it with Geomview's <tt>4dview</tt>. You
+can slice the object along any 4-d plane. You can also flip the
+halfspace that's deleted when slicing. By combining these
+features, you can get some interesting cross sections.</p>
+
+<h3><a href="#geomview">&#187;</a><a name="Gh">Gh - display
+hyperplane intersections (3-d, 4-d)</a></h3>
+
+<p>In 3-d, the intersection is a black line. It lies on two
+neighboring hyperplanes, c.f., the blue squares associated with
+centrums ('<a href="#Gc">Gc </a>'). In 4-d, the ridges are
+projected to the intersection of both hyperplanes. If you turn on
+edges (Geomview's 'appearances' menu), each triangle corresponds
+to one ridge. The ridges may overlap each other.</p>
+
+<h3><a href="#geomview">&#187;</a><a name="Gi">Gi - display inner
+planes only (2-d, 3-d)</a></h3>
+
+<p>The inner plane of a facet is below all of its vertices. It is
+parallel to the facet's hyperplane. The inner plane's color is
+the opposite of the outer plane's color, i.e., <i>[1-r,1-g,1-b] </i>.
+Its edges are determined by the vertices.</p>
+
+<h3><a href="#geomview">&#187;</a><a name="Gn">Gn - do not display
+planes </a></h3>
+
+<p>By default, Geomview displays the precise plane (no merging)
+or both inner and output planes (if merging). If merging,
+Geomview does not display the inner plane if the the difference
+between inner and outer is too small.</p>
+
+<h3><a href="#geomview">&#187;</a><a name="Go">Go - display outer
+planes only (2-d, 3-d)</a></h3>
+
+<p>The outer plane of a facet is above all input points. It is
+parallel to the facet's hyperplane. Its color is determined by
+the facet's normal, and its edges are determined by the vertices.</p>
+
+<h3><a href="#geomview">&#187;</a><a name="Gp">Gp - display coplanar
+points and vertices as radii </a></h3>
+
+<p>Coplanar points ('<a href="qh-optq.htm#Qc">Qc</a>'), interior
+points ('<a href="qh-optq.htm#Qi">Qi</a>'), outside points ('<a
+href="qh-optt.htm#TCn">TCn</a>' or '<a href="qh-optt.htm#TVn">TVn</a>'),
+and vertices are displayed as red and yellow radii. The radii are
+perpendicular to the corresponding facet. Vertices are aligned
+with an interior point. The radii define a ball which corresponds
+to the imprecision of the point. The imprecision is the maximum
+of the roundoff error, the centrum radius, and <i>maxcoord * (1 -
+</i><a href="qh-optc.htm#An"><i>A-n</i></a><i>)</i>. It is at
+least 1/20'th of the maximum coordinate, and ignores post merging
+if pre-merging is done.</p>
+
+<p>If '<a href="qh-optg.htm#Gv">Gv</a>' (print vertices as
+spheres) is also selected, option 'Gp' displays coplanar
+points as radii. Select options <a href="qh-optq.htm#Qc">Qc</a>'
+and/or '<a href="qh-optq.htm#Qi">Qi</a>'. Options 'Qc Gpv' displays
+coplanar points while 'Qci Gpv' displays coplanar and interior
+points. Option 'Qc' is automatically selected if 'Qi' is not
+selected with options 'Gpv'.
+
+<h3><a href="#geomview">&#187;</a><a name="Gr">Gr - display ridges
+(3-d) </a></h3>
+
+<p>A ridge connects the two vertices that are shared by
+neighboring facets. It is displayed in green. A ridge is the
+topological edge between two facets while the hyperplane
+intersection is the geometric edge between two facets. Ridges are
+always displayed in 4-d.</p>
+
+<h3><a href="#geomview">&#187;</a><a name="Gt">Gt - transparent 3-d
+Delaunay </a></h3>
+
+<p>A 3-d Delaunay triangulation looks like a convex hull with
+interior facets. Option 'Gt' removes the outside ridges to reveal
+the outermost facets. It automatically sets options '<a
+href="#Gr">Gr</a>' and '<a href="#GDn">GDn</a>'. See example <a
+href="qh-eg.htm#17f">eg.17f.delaunay.3</a>.</p>
+
+<h3><a href="#geomview">&#187;</a><a name="Gv">Gv - display vertices
+as spheres (2-d, 3-d)</a></h3>
+
+<p>The radius of the sphere corresponds to the imprecision of the
+data. See '<a href="#Gp">Gp</a>' for determining the radius.</p>
+
+<!-- Navigation links -->
+
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+<!-- GC common information -->
+
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-opto.htm b/xs/src/qhull/html/qh-opto.htm
new file mode 100644
index 000000000..e7b21745c
--- /dev/null
+++ b/xs/src/qhull/html/qh-opto.htm
@@ -0,0 +1,353 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Qhull output options</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html"><img
+src="qh--dt.gif" alt="[delaunay]" align="middle" width="100"
+height="100"></a> Qhull output options</h1>
+
+<p>This section lists the output options for Qhull. These options
+are indicated by lower case characters. See <a
+href="qh-optf.htm#format">Formats</a>, <a
+href="qh-optp.htm#print">Print</a>, and <a
+href="qh-optg.htm#geomview">Geomview</a> for other output
+options. </p>
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<p><a href="index.htm#TOC">&#187;</a> <a href="qh-quick.htm#programs">Programs</a>
+<a name="output">&#149;</a> <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<h2>Output options</h2>
+
+<p>Qhull prints its output to standard out. All output is printed
+text. The default output is a summary (option '<a href="#s">s</a>').
+Other outputs may be specified as follows. </p>
+
+<dl compact>
+ <dt><a href="#f">f</a></dt>
+ <dd>print all fields of all facets</dd>
+ <dt><a href="#n">n</a></dt>
+ <dd>print hyperplane normals with offsets</dd>
+ <dt><a href="#m">m</a></dt>
+ <dd>print Mathematica output (2-d and 3-d)</dd>
+ <dt><a href="#o">o</a></dt>
+ <dd>print OFF file format (dim, points and facets)</dd>
+ <dt><a href="#s">s</a></dt>
+ <dd>print summary to stderr</dd>
+ <dt><a href="#p">p</a></dt>
+ <dd>print vertex and point coordinates</dd>
+ <dt><a href="#i">i</a></dt>
+ <dd>print vertices incident to each facet </dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Related options</b></dd>
+ <dt><a href="qh-optf.htm#format">F</a></dt>
+ <dd>additional input/output formats</dd>
+ <dt><a href="qh-optg.htm#geomview">G</a></dt>
+ <dd>Geomview output</dd>
+ <dt><a href="qh-optp.htm#print">P</a></dt>
+ <dd>Print options</dd>
+ <dt><a href="qh-optf.htm#Ft">Ft</a></dt>
+ <dd>print triangulation with added points</dd>
+ <dt>&nbsp;</dt>
+</dl>
+
+<hr>
+
+<h3><a href="#output">&#187;</a><a name="f">f - print all fields of
+all facets </a></h3>
+
+<p>Print <a href=../src/libqhull.h#facetT>all fields</a> of all facets.
+The facet is the primary <a href=index.htm#structure>data structure</a> for
+Qhull.
+
+<p>Option 'f' is for
+debugging. Most of the fields are available via the '<a
+href="qh-optf.htm#format">F</a>' options. If you need specialized
+information from Qhull, you can use the <a
+href="qh-code.htm#library">Qhull library</a> or <a
+href="qh-code.htm#cpp">C++ interface</a>.</p>
+
+<p>Use the '<a href="qh-optf.htm#FF">FF</a>' option to print the
+facets but not the ridges. </p>
+
+<h3><a href="#output">&#187;</a><a name="i">i - print vertices
+incident to each facet </a></h3>
+
+<p>The first line is the number of facets. The remaining lines
+list the vertices for each facet, one facet per line. The indices
+are 0-relative indices of the corresponding input points. The
+facets are oriented. Option '<a href="qh-optf.htm#Fv">Fv</a>'
+displays an unoriented list of vertices with a vertex count per
+line. Options '<a href="qh-opto.htm#o">o</a>' and '<a
+href="qh-optf.htm#Ft">Ft</a>' displays coordinates for each
+vertex prior to the vertices for each facet. </p>
+
+<p>Simplicial facets (e.g., triangles in 3-d) consist of <i>d</i>
+vertices. Non-simplicial facets in 3-d consist of 4 or more
+vertices. For example, a facet of a cube consists of 4 vertices.
+Use option '<a href="qh-optq.htm#Qt">Qt</a>' to triangulate non-simplicial facets.</p>
+
+<p>For 4-d and higher convex hulls and 3-d and higher Delaunay
+triangulations, <i>d</i> vertices are listed for all facets. A
+non-simplicial facet is triangulated with its centrum and each
+ridge. The index of the centrum is higher than any input point.
+Use option '<a href="qh-optf.htm#Fv">Fv</a>' to list the vertices
+of non-simplicial facets as is. Use option '<a
+href="qh-optf.htm#Ft">Ft</a>' to print the coordinates of the
+centrums as well as those of the input points. </p>
+
+<h3><a href="#output">&#187;</a><a name="m">m - print Mathematica
+output </a></h3>
+
+<p>Qhull writes a Mathematica file for 2-d and 3-d convex hulls,
+2-d and 3-d halfspace intersections,
+and 2-d Delaunay triangulations. Qhull produces a list of
+objects that you can assign to a variable in Mathematica, for
+example: &quot;<tt>list= &lt;&lt; &lt;outputfilename&gt; </tt>&quot;.
+If the object is 2-d, it can be visualized by &quot;<tt>Show[Graphics[list]]
+</tt>&quot;. For 3-d objects the command is &quot;<tt>Show[Graphics3D[list]]
+</tt>&quot;. Now the object can be manipulated by commands of the
+form <tt>&quot;Show[%, &lt;parametername&gt; -&gt;
+&lt;newvalue&gt;]</tt>&quot;. </p>
+
+<p>For Delaunay triangulation orthogonal projection is better.
+This can be specified, for example, by &quot;<tt>BoxRatios:
+Show[%, BoxRatios -&gt; {1, 1, 1e-8}]</tt>&quot;. To see the
+meaningful side of the 3-d object used to visualize 2-d Delaunay,
+you need to change the viewpoint: &quot;<tt>Show[%, ViewPoint
+-&gt; {0, 0, -1}]</tt>&quot;. By specifying different viewpoints
+you can slowly rotate objects. </p>
+
+<p>For halfspace intersections, Qhull produces the dual
+convex hull.
+
+<p>See <a href="qh-faq.htm#math">Is Qhull available for Mathematica?</a>
+for URLs.
+
+<h3><a href="#output">&#187;</a><a name="n">n - print hyperplane
+normals with offsets </a></h3>
+
+<p>The first line is the dimension plus one. The second line is
+the number of facets. The remaining lines are the normals for
+each facet, one normal per line. The facet's offset follows its
+normal coefficients.</p>
+
+<p>The normals point outward, i.e., the convex hull satisfies <i>Ax
+&lt;= -b </i>where <i>A</i> is the matrix of coefficients and <i>b</i>
+is the vector of offsets.</p>
+
+<p>A point is <i>inside</i> or <i>below</i> a hyperplane if its distance
+to the hyperplane is negative. A point is <i>outside</i> or <i>above</i> a hyperplane
+if its distance to the hyperplane is positive. Otherwise a point is <i>on</i> or
+<i>coplanar to</i> the hyperplane.
+
+<p>If cdd output is specified ('<a href="qh-optf.htm#FD">FD</a>'),
+Qhull prints the command line, the keyword &quot;begin&quot;, the
+number of facets, the dimension (plus one), the keyword
+&quot;real&quot;, and the normals for each facet. The facet's
+negative offset precedes its normal coefficients (i.e., if the
+origin is an interior point, the offset is positive). Qhull ends
+the output with the keyword &quot;end&quot;. </p>
+
+<h3><a href="#output">&#187;</a><a name="o">o - print OFF file format
+</a></h3>
+
+<p>The output is: </p>
+
+<ul>
+ <li>The first line is the dimension </li>
+ <li>The second line is the number of points, the number of
+ facets, and the number of ridges. </li>
+ <li>All of the input points follow, one per line. </li>
+ <li>Then Qhull prints the vertices for each facet. Each facet
+ is on a separate line. The first number is the number of
+ vertices. The remainder is the indices of the
+ corresponding points. The vertices are oriented in 2-d,
+ 3-d, and in simplicial facets. </li>
+</ul>
+
+<p>Option '<a href="qh-optf.htm#Ft">Ft</a>' prints the same
+information with added points for non-simplicial facets.</p>
+
+<p>Option '<a href="qh-opto.htm#i">i</a>' displays vertices
+without the point coordinates. Option '<a href="qh-opto.htm#p">p</a>'
+displays the point coordinates without vertex and facet information.</p>
+
+<p>In 3-d, Geomview can load the file directly if you delete the
+first line (e.g., by piping through '<tt>tail +2</tt>').</p>
+
+<p>For Voronoi diagrams (<a href=qvoronoi.htm>qvoronoi</a>), option
+'o' prints Voronoi vertices and Voronoi regions instead of input
+points and facets. The first vertex is the infinity vertex
+[-10.101, -10.101, ...]. Then, option 'o' lists the vertices in
+the Voronoi region for each input site. The regions appear in
+site ID order. In 2-d, the vertices of a Voronoi region are
+sorted by adjacency (non-oriented). In 3-d and higher, the
+Voronoi vertices are sorted by index. See the '<a
+href="qh-optf.htm#FN">FN</a>' option for listing Voronoi regions
+without listing Voronoi vertices.</p>
+
+<p>If you are using the Qhull library, options 'v o' have the
+side effect of reordering the neighbors for a vertex.</p>
+
+<h3><a href="#output">&#187;</a><a name="p">p - print vertex and
+point coordinates </a></h3>
+
+<p>The first line is the dimension. The second line is the number
+of vertices. The remaining lines are the vertices, one vertex per
+line. A vertex consists of its point coordinates</p>
+
+<p>With the '<a href="qh-optg.htm#Gc">Gc</a>' and '<a
+href="qh-optg.htm#Gi">Gi</a>' options, option 'p' also prints
+coplanar and interior points respectively.</p>
+
+<p>For <a href=qvoronoi.htm>qvoronoi</a>, it prints the
+coordinates of each Voronoi vertex.</p>
+
+<p>For <a href=qdelaun.htm>qdelaunay</a>, it prints the
+input sites as lifted to a paraboloid. For <a href=qhalf.htm>qhalf</a>
+it prints the dual points. For both, option 'p' is the same as the first
+section of option '<a href="qh-opto.htm#o">o</a>'.</p>
+
+<p>Use '<a href="qh-optf.htm#Fx">Fx</a>' to list the point ids of
+the extreme points (i.e., vertices). </p>
+
+<p>If a subset of the facets is selected ('<a
+href="qh-optp.htm#Pdk">Pdk</a>', '<a href="qh-optp.htm#PDk">PDk</a>',
+'<a href="qh-optp.htm#Pg">Pg</a>' options), option 'p' only
+prints vertices and points associated with those facets.</p>
+
+<p>If cdd-output format is selected ('<a href="qh-optf.htm#FD">FD</a>'),
+the first line is &quot;begin&quot;. The second line is the
+number of vertices, the dimension plus one, and &quot;real&quot;.
+The vertices follow with a leading &quot;1&quot;. Output ends
+with &quot;end&quot;. </p>
+
+<h3><a href="#output">&#187;</a><a name="s">s - print summary to
+stderr </a></h3>
+
+<p>The default output of Qhull is a summary to stderr. Options '<a
+href="qh-optf.htm#FS">FS</a>' and '<a href="qh-optf.htm#Fs">Fs</a>'
+produce the same information for programs. <b>Note</b>: Windows 95 and 98
+treats stderr the same as stdout. Use option '<a href="qh-optt.htm#TO">TO file</a>' to separate
+stderr and stdout.</p>
+
+<p>The summary lists the number of input points, the dimension,
+the number of vertices in the convex hull, and the number of
+facets in the convex hull. It lists the number of selected
+(&quot;good&quot;) facets for options '<a href="qh-optp.htm#Pg">Pg</a>',
+'<a href="qh-optp.htm#Pdk">Pdk</a>', <a href=qdelaun.htm>qdelaunay</a>,
+or <a href=qvoronoi.htm>qvoronoi</a> (Delaunay triangulations only
+use the lower half of a convex hull). It lists the number of
+coplanar points. For Delaunay triangulations without '<a
+href="qh-optq.htm#Qc">Qc</a>', it lists the total number of
+coplanar points. It lists the number of simplicial facets in
+the output.</p>
+
+<p>The terminology depends on the output structure. </p>
+
+<p>The summary lists these statistics:</p>
+
+<ul>
+ <li>number of points processed by Qhull </li>
+ <li>number of hyperplanes created</li>
+ <li>number of distance tests (not counting statistics,
+ summary, and checking) </li>
+ <li>number of merged facets (if any)</li>
+ <li>number of distance tests for merging (if any)</li>
+ <li>CPU seconds to compute the hull</li>
+ <li>the maximum joggle for '<a href="qh-optq.htm#QJn">QJ</a>'<br>
+ or, the probability of precision errors for '<a
+ href="qh-optq.htm#QJn">QJ</a> <a href="qh-optt.htm#TRn">TRn</a>'
+ </li>
+ <li>total area and volume (if computed, see '<a
+ href="qh-optf.htm#FS">FS</a>' '<a href="qh-optf.htm#FA">FA</a>'
+ '<a href="qh-optf.htm#Fa">Fa</a>' '<a
+ href="qh-optp.htm#PAn">PAn</a>')</li>
+ <li>max. distance of a point above a facet (if non-zero)</li>
+ <li>max. distance of a vertex below a facet (if non-zero)</li>
+</ul>
+
+<p>The statistics include intermediate hulls. For example 'rbox d
+D4 | qhull' reports merged facets even though the final hull is
+simplicial. </p>
+
+<p>Qhull starts counting CPU seconds after it has read and
+projected the input points. It stops counting before producing
+output. In the code, CPU seconds measures the execution time of
+function qhull() in <tt>libqhull.c</tt>. If the number of CPU
+seconds is clearly wrong, check qh_SECticks in <tt>user.h</tt>. </p>
+
+<p>The last two figures measure the maximum distance from a point
+or vertex to a facet. They are not printed if less than roundoff
+or if not merging. They account for roundoff error in computing
+the distance (c.f., option '<a href="qh-optc.htm#Rn">Rn</a>').
+Use '<a href="qh-optf.htm#Fs">Fs</a>' to report the maximum outer
+and inner plane. </p>
+
+<p>A number may appear in parentheses after the maximum distance
+(e.g., 2.1x). It is the ratio between the maximum distance and
+the worst-case distance due to merging two simplicial facets. It
+should be small for 2-d, 3-d, and 4-d, and for higher dimensions
+with '<a href="qh-optq.htm#Qx">Qx</a>'. It is not printed if less
+than 0.05. </p>
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-optp.htm b/xs/src/qhull/html/qh-optp.htm
new file mode 100644
index 000000000..9c6df90f5
--- /dev/null
+++ b/xs/src/qhull/html/qh-optp.htm
@@ -0,0 +1,253 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Qhull print options (P)</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html"><img
+src="qh--dt.gif" alt="[delaunay]" align="middle" width="100"
+height="100"></a> Qhull print options (P)</h1>
+
+This section lists the print options for Qhull. These options are
+indicated by 'P' followed by a letter. See
+<a href="qh-opto.htm#output">Output</a>, <a href="qh-optg.htm#geomview">Geomview</a>,
+and <a href="qh-optf.htm#format">Format</a> for other output options.
+
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<p><a href="index.htm#TOC">&#187;</a> <a href="qh-quick.htm#programs">Programs</a>
+<a name="format">&#149;</a> <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<h2>Print options</h2>
+<blockquote>
+<dl compact>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a href="#Pp">Pp</a></dt>
+ <dd>do not report precision problems </dd>
+ <dt><a href="#Po">Po</a></dt>
+ <dd>force output despite precision problems</dd>
+ <dt><a href="#Po2">Po</a></dt>
+ <dd>if error, output neighborhood of facet</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Select</b></dd>
+ <dt><a href="#Pdk">Pdk:n</a></dt>
+ <dd>print facets with normal[k] &gt;= n (default 0.0)</dd>
+ <dt><a href="#PDk">PDk:n</a></dt>
+ <dd>print facets with normal[k] &lt;= n </dd>
+ <dt><a href="#PFn">PFn</a></dt>
+ <dd>print facets whose area is at least n</dd>
+ <dt><a href="#Pg">Pg</a></dt>
+ <dd>print good facets only (needs '<a href="qh-optq.htm#QGn">QGn</a>'
+ or '<a href="qh-optq.htm#QVn">QVn </a>')</dd>
+ <dt><a href="#PMn">PMn</a></dt>
+ <dd>print n facets with most merges</dd>
+ <dt><a href="#PAn">PAn</a></dt>
+ <dd>print n largest facets by area</dd>
+ <dt><a href="#PG">PG</a></dt>
+ <dd>print neighbors of good facets</dd>
+</dl>
+</blockquote>
+<hr>
+
+<h3><a href="#print">&#187;</a><a name="PAn">PAn - keep n largest
+facets by area</a></h3>
+
+<p>The <i>n</i> largest facets are marked good for printing. This
+may be useful for <a href="qh-impre.htm#approximate">approximating
+a hull</a>. Unless '<a href="#PG">PG</a>' is set, '<a href="#Pg">Pg</a>'
+is automatically set. </p>
+
+<h3><a href="#print">&#187;</a><a name="Pdk">Pdk:n - print facet if
+normal[k] &gt;= n </a></h3>
+
+<p>For a given output, print only those facets with <i>normal[k] &gt;= n</i>
+and <i>drop</i> the others. For example, 'Pd0:0.5' prints facets with <i>normal[0]
+&gt;= 0.5 </i>. The default value of <i>n</i> is zero. For
+example in 3-d, 'Pd0d1d2' prints facets in the positive octant.
+<p>
+If no facets match, the closest facet is returned.</p>
+<p>
+On Windows 95, do not combine multiple options. A 'd' is considered
+part of a number. For example, use 'Pd0:0.5 Pd1:0.5' instead of
+'Pd0:0.5d1:0.5'.
+
+<h3><a href="#print">&#187;</a><a name="PDk">PDk:n - print facet if
+normal[k] &lt;= n</a></h3>
+
+<p>For a given output, print only those facets with <i>normal[k] &lt;= n</i>
+and <i>drop</i> the others.
+For example, 'PD0:0.5' prints facets with <i>normal[0]
+&lt;= 0.5 </i>. The default value of <i>n</i> is zero. For
+example in 3-d, 'PD0D1D2' displays facets in the negative octant.
+<p>
+If no facets match, the closest facet is returned.</p>
+
+<p>In 2-d, 'd G PD2' displays the Delaunay triangulation instead
+of the corresponding paraboloid. </p>
+
+<p>Be careful of placing 'Dk' or 'dk' immediately after a real
+number. Some compilers treat the 'D' as a double precision
+exponent. </p>
+
+<h3><a href="#print">&#187;</a><a name="PFn">PFn - keep facets whose
+area is at least n</a></h3>
+
+<p>The facets with area at least <i>n</i> are marked good for
+printing. This may be useful for <a
+href="qh-impre.htm#approximate">approximating a hull</a>. Unless
+'<a href="#PG">PG</a>' is set, '<a href="#Pg">Pg</a>' is
+automatically set. </p>
+
+<h3><a href="#print">&#187;</a><a name="Pg">Pg - print good facets </a></h3>
+
+<p>Qhull can mark facets as &quot;good&quot;. This is used to</p>
+
+<ul>
+ <li>mark the lower convex hull for Delaunay triangulations
+ and Voronoi diagrams</li>
+ <li>mark the facets that are visible from a point (the '<a
+ href="qh-optq.htm#QGn">QGn </a>' option)</li>
+ <li>mark the facets that contain a point (the '<a
+ href="qh-optq.htm#QVn">QVn</a>' option).</li>
+ <li>indicate facets with a large enough area (options '<a
+ href="#PAn">PAn</a>' and '<a href="#PFn">PFn</a>')</li>
+</ul>
+
+<p>Option '<a href="#Pg">Pg</a>' only prints good facets that
+also meet '<a href="#Pdk">Pdk</a>' and '<a href="#PDk">PDk</a>'
+options. It is automatically set for options '<a href="#PAn">PAn</a>',
+'<a href="#PFn">PFn </a>', '<a href="qh-optq.htm#QGn">QGn</a>',
+and '<a href="qh-optq.htm#QVn">QVn</a>'.</p>
+
+<h3><a href="#print">&#187;</a><a name="PG">PG - print neighbors of
+good facets</a></h3>
+
+<p>Option 'PG' can be used with or without option '<a href="#Pg">Pg</a>'
+to print the neighbors of good facets. For example, options '<a
+href="qh-optq.htm#QGn">QGn</a>' and '<a href="qh-optq.htm#QVn">QVn</a>'
+print the horizon facets for point <i>n. </i></p>
+
+<h3><a href="#print">&#187;</a><a name="PMn">PMn - keep n facets with
+most merges</a></h3>
+
+<p>The n facets with the most merges are marked good for
+printing. This may be useful for <a
+href="qh-impre.htm#approximate">approximating a hull</a>. Unless
+'<a href="#PG">PG</a>' is set, '<a href="#Pg">Pg</a>' is
+automatically set. </p>
+
+<p>Use option '<a href="qh-optf.htm#Fm">Fm</a>' to print merges
+per facet.
+
+<h3><a href="#print">&#187;</a><a name="Po">Po - force output despite
+precision problems</a></h3>
+
+<p>Use options 'Po' and '<a href="qh-optq.htm#Q0">Q0</a>' if you
+can not merge facets, triangulate the output ('<a href="qh-optq.htm#Qt">Qt</a>'),
+or joggle the input (<a href="qh-optq.htm#QJn">QJ</a>).
+
+<p>Option 'Po' can not force output when
+duplicate ridges or duplicate facets occur. It may produce
+erroneous results. For these reasons, merged facets, joggled input, or <a
+href="qh-impre.htm#exact">exact arithmetic</a> are better.</p>
+
+<p>If you need a simplicial Delaunay triangulation, use
+joggled input '<a href="qh-optq.htm#QJn">QJ</a>' or triangulated
+output '<a
+href="qh-optf.htm#Ft">Ft</a>'.
+
+<p>Option 'Po' may be used without '<a href="qh-optq.htm#Q0">Q0</a>'
+to remove some steps from Qhull or to output the neighborhood of
+an error.</p>
+
+<p>Option 'Po' may be used with option '<a href="qh-optq.htm#Q5">Q5</a>')
+to skip qh_check_maxout (i.e., do not determine the maximum outside distance).
+This can save a significant amount of time.
+
+<p>If option 'Po' is used,</p>
+
+<ul>
+ <li>most precision errors allow Qhull to continue. </li>
+ <li>verify ('<a href="qh-optt.htm#Tv">Tv</a>') does not check
+ coplanar points.</li>
+ <li>points are not partitioned into flipped facets and a
+ flipped facet is always visible to a point. This may
+ delete flipped facets from the output. </li>
+</ul>
+
+<h3><a href="#print">&#187;</a><a name="Po2">Po - if error, output
+neighborhood of facet</a></h3>
+
+<p>If an error occurs before the completion of Qhull and tracing
+is not active, 'Po' outputs a neighborhood of the erroneous
+facets (if any). It uses the current output options.</p>
+
+<p>See '<a href="qh-optp.htm#Po">Po</a>' - force output despite
+precision problems.
+
+<h3><a href="#print">&#187;</a><a name="Pp">Pp - do not report
+precision problems </a></h3>
+
+<p>With option 'Pp', Qhull does not print statistics about
+precision problems, and it removes some of the warnings. It
+removes the narrow hull warning.</p>
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-optq.htm b/xs/src/qhull/html/qh-optq.htm
new file mode 100644
index 000000000..2edbb1fd4
--- /dev/null
+++ b/xs/src/qhull/html/qh-optq.htm
@@ -0,0 +1,731 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Qhull control options (Q)</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html"><img
+src="qh--dt.gif" alt="[delaunay]" align="middle" width="100"
+height="100"></a> Qhull control options (Q)</h1>
+
+<p>This section lists the control options for Qhull. These
+options are indicated by 'Q' followed by a letter. </p>
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<p><a href="index.htm#TOC">&#187;</a> <a href="qh-quick.htm#programs">Programs</a>
+<a name="qhull">&#149;</a> <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<h2>Qhull control options</h2>
+
+<dl compact>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a href="#Qu">Qu</a></dt>
+ <dd>compute upper hull for furthest-site Delaunay
+ triangulation </dd>
+ <dt><a href="#Qc">Qc</a></dt>
+ <dd>keep coplanar points with nearest facet</dd>
+ <dt><a href="#Qi">Qi</a></dt>
+ <dd>keep interior points with nearest facet</dd>
+ <dt><a href="#QJn">QJ</a></dt>
+ <dd>joggled input to avoid precision problems</dd>
+ <dt><a href="#Qt">Qt</a></dt>
+ <dd>triangulated output</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Precision handling</b></dd>
+ <dt><a href="#Qz">Qz</a></dt>
+ <dd>add a point-at-infinity for Delaunay triangulations</dd>
+ <dt><a href="#Qx">Qx</a></dt>
+ <dd>exact pre-merges (allows coplanar facets)</dd>
+ <dt><a href="#Qs">Qs</a></dt>
+ <dd>search all points for the initial simplex</dd>
+ <dt><a href="#Qbb">Qbb</a></dt>
+ <dd>scale last coordinate to [0,m] for Delaunay</dd>
+ <dt><a href="#Qv">Qv</a></dt>
+ <dd>test vertex neighbors for convexity</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Transform input</b></dd>
+ <dt><a href="#Qb0">Qbk:0Bk:0</a></dt>
+ <dd>drop dimension k from input</dd>
+ <dt><a href="#QRn">QRn</a></dt>
+ <dd>random rotation (n=seed, n=0 time, n=-1 time/no rotate)</dd>
+ <dt><a href="#Qbk">Qbk:n</a></dt>
+ <dd>scale coord[k] to low bound of n (default -0.5)</dd>
+ <dt><a href="#QBk">QBk:n</a></dt>
+ <dd>scale coord[k] to upper bound of n (default 0.5)</dd>
+ <dt><a href="#QbB">QbB</a></dt>
+ <dd>scale input to fit the unit cube</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Select facets</b></dd>
+ <dt><a href="#QVn">QVn</a></dt>
+ <dd>good facet if it includes point n, -n if not</dd>
+ <dt><a href="#QGn">QGn</a></dt>
+ <dd>good facet if visible from point n, -n for not visible</dd>
+ <dt><a href="#Qg">Qg</a></dt>
+ <dd>only build good facets (needs '<a href="#QGn">QGn</a>', '<a
+ href="#QVn">QVn </a>', or '<a href="qh-optp.htm#Pdk">Pdk</a>')</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Experimental</b></dd>
+ <dt><a href="#Q4">Q4</a></dt>
+ <dd>avoid merging old facets into new facets</dd>
+ <dt><a href="#Q5">Q5</a></dt>
+ <dd>do not correct outer planes at end of qhull</dd>
+ <dt><a href="#Q3">Q3</a></dt>
+ <dd>do not merge redundant vertices</dd>
+ <dt><a href="#Q6">Q6</a></dt>
+ <dd>do not pre-merge concave or coplanar facets</dd>
+ <dt><a href="#Q0">Q0</a></dt>
+ <dd>do not pre-merge facets with 'C-0' or 'Qx'</dd>
+ <dt><a href="#Q8">Q8</a></dt>
+ <dd>ignore near-interior points</dd>
+ <dt><a href="#Q2">Q2</a></dt>
+ <dd>merge all non-convex at once instead of independent sets</dd>
+ <dt><a href="#Qf">Qf</a></dt>
+ <dd>partition point to furthest outside facet</dd>
+ <dt><a href="#Q7">Q7</a></dt>
+ <dd>process facets depth-first instead of breadth-first</dd>
+ <dt><a href="#Q9">Q9</a></dt>
+ <dd>process furthest of furthest points</dd>
+ <dt><a href="#Q10">Q10</a></dt>
+ <dd>no special processing for narrow distributions</dd>
+ <dt><a href="#Q11">Q11</a></dt>
+ <dd>copy normals and recompute centrums for tricoplanar facets</dd>
+ <dt><a href="#Q12">Q12</a></dt>
+ <dd>do not error on wide merge due to duplicate ridge and nearly coincident points</dd>
+ <dt><a href="#Qm">Qm</a></dt>
+ <dd>process points only if they would increase the max. outer
+ plane </dd>
+ <dt><a href="#Qr">Qr</a></dt>
+ <dd>process random outside points instead of furthest one</dd>
+ <dt><a href="#Q1">Q1</a></dt>
+ <dd>sort merges by type instead of angle</dd>
+</dl>
+
+<hr>
+
+<h3><a href="#qhull">&#187;</a><a name="Qbb">Qbb - scale the last
+coordinate to [0,m] for Delaunay</a></h3>
+
+<p>After scaling with option 'Qbb', the lower bound of the last
+coordinate will be 0 and the upper bound will be the maximum
+width of the other coordinates. Scaling happens after projecting
+the points to a paraboloid and scaling other coordinates. </p>
+
+<p>Option 'Qbb' is automatically set for <a href=qdelaun.htm>qdelaunay</a>
+and <a href=qvoronoi.htm>qvoronoi</a>. Option 'Qbb' is automatically set for joggled input '<a
+href="qh-optq.htm#QJn">QJ</a>'. </p>
+
+<p>Option 'Qbb' should be used for Delaunay triangulations with
+integer coordinates. Since the last coordinate is the sum of
+squares, it may be much larger than the other coordinates. For
+example, <tt>rbox 10000 D2 B1e8 | qhull d</tt> has precision
+problems while <tt>rbox 10000 D2 B1e8 | qhull d Qbb</tt> is OK. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="QbB">QbB - scale the input to
+fit the unit cube</a></h3>
+
+<p>After scaling with option 'QbB', the lower bound will be -0.5
+and the upper bound +0.5 in all dimensions. For different bounds
+change qh_DEFAULTbox in <tt>user.h</tt> (0.5 is best for <a
+href="index.htm#geomview">Geomview</a>).</p>
+
+<p>For Delaunay and Voronoi diagrams, scaling happens after
+projection to the paraboloid. Under precise arithmetic, scaling
+does not change the topology of the convex hull. Scaling may
+reduce precision errors if coordinate values vary widely.</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qbk">Qbk:n - scale coord[k]
+to low bound</a></h3>
+
+<p>After scaling, the lower bound for dimension k of the input
+points will be n. 'Qbk' scales coord[k] to -0.5. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="QBk">QBk:n - scale coord[k]
+to upper bound </a></h3>
+
+<p>After scaling, the upper bound for dimension k of the input
+points will be n. 'QBk' scales coord[k] to 0.5. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qb0">Qbk:0Bk:0 - drop
+dimension k from the input points</a></h3>
+
+<p>Drop dimension<em> k </em>from the input points. For example,
+'Qb1:0B1:0' deletes the y-coordinate from all input points. This
+allows the user to take convex hulls of sub-dimensional objects.
+It happens before the Delaunay and Voronoi transformation.
+It happens after the halfspace transformation for both the data
+and the feasible point.</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qc">Qc - keep coplanar points
+with nearest facet </a></h3>
+
+<p>During construction of the hull, a point is coplanar if it is
+between '<a href="qh-optc.htm#Wn">Wn</a>' above and '<a
+href="qh-optc.htm#Un">Un</a>' below a facet's hyperplane. A
+different definition is used for output from Qhull. </p>
+
+<p>For output, a coplanar point is above the minimum vertex
+(i.e., above the inner plane). With joggle ('<a
+href="qh-optq.htm#QJn">QJ</a>'), a coplanar point includes points
+within one joggle of the inner plane. </p>
+
+<p>With option 'Qc', output formats '<a href="qh-opto.htm#p">p </a>',
+'<a href="qh-opto.htm#f">f</a>', '<a href="qh-optg.htm#Gp">Gp</a>',
+'<a href="qh-optf.htm#Fc">Fc</a>', '<a href="qh-optf.htm#FN">FN</a>',
+and '<a href="qh-optf.htm#FP">FP</a>' will print the coplanar
+points. With options 'Qc <a href="#Qi">Qi</a>' these outputs
+include the interior points.</p>
+
+<p>For Delaunay triangulations (<a href=qdelaun.htm>qdelaunay</a>
+or <a href=qvoronoi.htm>qvoronoi</a>), a coplanar point is a point
+that is nearly incident to a vertex. All input points are either
+vertices of the triangulation or coplanar.</p>
+
+<p>Qhull stores coplanar points with a facet. While constructing
+the hull, it retains all points within qh_RATIOnearInside
+(user.h) of a facet. In qh_check_maxout(), it uses these points
+to determine the outer plane for each facet. With option 'Qc',
+qh_check_maxout() retains points above the minimum vertex for the
+hull. Other points are removed. If qh_RATIOnearInside is wrong or
+if options '<a href="#Q5">Q5</a> <a href="#Q8">Q8</a>' are set, a
+coplanar point may be missed in the output (see <a
+href="qh-impre.htm#limit">Qhull limitations</a>).</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qf">Qf - partition point to
+furthest outside facet </a></h3>
+
+<p>After adding a new point to the convex hull, Qhull partitions
+the outside points and coplanar points of the old, visible
+facets. Without the '<a href="qh-opto.htm#f">f </a>' option and
+merging, it assigns a point to the first facet that it is outside
+('<a href="qh-optc.htm#Wn">Wn</a>'). When merging, it assigns a
+point to the first facet that is more than several times outside
+(see qh_DISToutside in user.h).</p>
+
+<p>If option 'Qf' is selected, Qhull performs a directed search
+(no merging) or an exhaustive search (merging) of new facets.
+Option 'Qf' may reduce precision errors if pre-merging does not
+occur.</p>
+
+<p>Option '<a href="#Q9">Q9</a>' processes the furthest of all
+furthest points.</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qg">Qg - only build good
+facets (needs 'QGn' 'QVn' or 'Pdk') </a></h3>
+
+<p>Qhull has several options for defining and printing good
+facets. With the '<a href="#Qg">Qg</a>' option, Qhull will only
+build those facets that it needs to determine the good facets in
+the output. This may speed up Qhull in 2-d and 3-d. It is
+useful for furthest-site Delaunay
+triangulations (<a href=qdelau_f.htm>qdelaunay Qu</a>,
+invoke with 'qhull d Qbb <a href="#Qu">Qu</a> Qg').
+It is not effective in higher
+dimensions because many facets see a given point and contain a
+given vertex. It is not guaranteed to work for all combinations.</p>
+
+<p>See '<a href="#QGn">QGn</a>', '<a href="#QVn">QVn</a>', and '<a
+href="qh-optp.htm#Pdk">Pdk</a>' for defining good facets, and '<a
+href="qh-optp.htm#Pg">Pg</a>' and '<a href="qh-optp.htm#PG">PG</a>'
+for printing good facets and their neighbors. If pre-merging ('<a
+href="qh-optc.htm#Cn">C-n</a>') is not used and there are
+coplanar facets, then 'Qg Pg' may produce a different result than
+'<a href="qh-optp.htm#Pg">Pg</a>'. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="QGn">QGn - good facet if
+visible from point n, -n for not visible </a></h3>
+
+<p>With option 'QGn', a facet is good (see '<a href="#Qg">Qg</a>'
+and '<a href="qh-optp.htm#Pg">Pg</a>') if it is visible from
+point n. If <i>n &lt; 0</i>, a facet is good if it is not visible
+from point n. Point n is not added to the hull (unless '<a
+href="qh-optt.htm#TCn">TCn</a>' or '<a href="qh-optt.htm#TPn">TPn</a>').</p>
+
+<p>With <a href="rbox.htm">rbox</a>, use the 'Pn,m,r' option
+to define your point; it will be point 0 ('QG0'). </p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qi">Qi - keep interior points
+with nearest facet </a></h3>
+
+<p>Normally Qhull ignores points that are clearly interior to the
+convex hull. With option 'Qi', Qhull treats interior points the
+same as coplanar points. Option 'Qi' does not retain coplanar
+points. You will probably want '<a href="#Qc">Qc </a>' as well. </p>
+
+<p>Option 'Qi' is automatically set for '<a href=qdelaun.htm>qdelaunay</a>
+<a href="#Qc">Qc</a>' and '<a href=qvoronoi.htm>qvoronoi</a>
+<a href="#Qc">Qc</a>'. If you use
+'<a href=qdelaun.htm>qdelaunay</a> Qi' or '<a href=qvoronoi.htm>qvoronoi</a>
+Qi', option '<a href="qh-opto.htm#s">s</a>' reports all nearly
+incident points while option '<a href="qh-optf.htm#Fs">Fs</a>'
+reports the number of interior points (should always be zero).</p>
+
+<p>With option 'Qi', output formats '<a href="qh-opto.htm#p">p</a>',
+'<a href="qh-opto.htm#f">f</a>','<a href="qh-optg.htm#Gp">Gp</a>',
+'<a href="qh-optf.htm#Fc">Fc</a>', '<a href="qh-optf.htm#FN">FN</a>',
+and '<a href="qh-optf.htm#FP">FP</a>' include interior points. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="QJ">QJ</a> or <a name="QJn">QJn</a> - joggled
+input to avoid precision errors</a></h3>
+
+<p>Option 'QJ' or 'QJn' joggles each input coordinate by adding a
+random number in the range [-n,n]. If a precision error occurs,
+It tries again. If precision errors still occur, Qhull increases <i>n</i>
+ten-fold and tries again. The maximum value for increasing <i>n</i>
+is 0.01 times the maximum width of the input. Option 'QJ' selects
+a default value for <i>n</i>. <a href="../src/user.h#JOGGLEdefault">User.h</a>
+defines these parameters and a maximum number of retries. See <a
+href="qh-impre.htm#joggle">Merged facets or joggled input</a>. </p>
+
+<p>Users of joggled input should consider converting to
+triangulated output ('<a href="../html/qh-optq.htm#Qt">Qt</a>'). Triangulated output is
+approximately 1000 times more accurate than joggled input.
+
+<p>Option 'QJ' also sets '<a href="qh-optq.htm#Qbb">Qbb</a>' for
+Delaunay triangulations and Voronoi diagrams. It does not set
+'Qbb' if '<a href="qh-optq.htm#Qbk">Qbk:n</a>' or '<a
+href="qh-optq.htm#QBk">QBk:n</a>' are set. </p>
+
+<p>If 'QJn' is set, Qhull does not merge facets unless requested
+to. All facets are simplicial (triangular in 2-d). This may be
+important for your application. You may also use triangulated output
+('<a href="qh-optq.htm#Qt">Qt</a>') or Option '<a href="qh-optf.htm#Ft">Ft</a>'.
+
+<p>Qhull adjusts the outer and inner planes for 'QJn' ('<a
+href="qh-optf.htm#Fs">Fs</a>'). They are increased by <i>sqrt(d)*n</i>
+to account for the maximum distance between a joggled point and
+the corresponding input point. Coplanar points ('<a
+href="qh-optq.htm#Qc">Qc</a>') require an additional <i>sqrt(d)*n</i>
+since vertices and coplanar points may be joggled in opposite
+directions. </p>
+
+<p>For Delaunay triangulations (<a href=qdelaun.htm>qdelaunay</a>), joggle
+happens before lifting the input sites to a paraboloid. Instead of
+'QJ', you may use triangulated output ('<a
+href="qh-optq.htm#Qt">Qt</a>')</p>
+
+<p>This option is deprecated for Voronoi diagrams (<a href=qvoronoi.htm>qvoronoi</a>).
+It triangulates cospherical points, leading to duplicated Voronoi vertices.</p>
+
+<p>By default, 'QJn' uses a fixed random number seed. To use time
+as the random number seed, select '<a href="qh-optq.htm#QRn">QR-1</a>'.
+The summary ('<a href="qh-opto.htm#s">s</a>') will show the
+selected seed as 'QR-n'.
+
+<p>With 'QJn', Qhull does not error on degenerate hyperplane
+computations. Except for Delaunay and Voronoi computations, Qhull
+does not error on coplanar points. </p>
+
+<p>Use option '<a href="qh-optf.htm#FO">FO</a>' to display the
+selected options. Option 'FO' displays the joggle and the joggle
+seed. If Qhull restarts, it will redisplay the options. </p>
+
+<p>Use option '<a href="qh-optt.htm#TRn">TRn</a>' to estimate the
+probability that Qhull will fail for a given 'QJn'.
+
+<h3><a href="#qhull">&#187;</a><a name="Qm">Qm - only process points
+that increase the maximum outer plane </a></h3>
+
+<p>Qhull reports the maximum outer plane in its summary ('<a
+href="qh-opto.htm#s">s</a>'). With option 'Qm', Qhull does not
+process points that are below the current, maximum outer plane.
+This is equivalent to always adjusting '<a href="qh-optc.htm#Wn">Wn
+</a>' to the maximum distance of a coplanar point to a facet. It
+is ignored for points above the upper convex hull of a Delaunay
+triangulation. Option 'Qm' is no longer important for merging.</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qr">Qr - process random
+outside points instead of furthest ones </a></h3>
+
+<p>Normally, Qhull processes the furthest point of a facet's
+outside points. Option 'Qr' instead selects a random outside
+point for processing. This makes Qhull equivalent to the
+randomized incremental algorithms.</p>
+
+<p>The original randomization algorithm by Clarkson and Shor [<a
+href="index.htm#cla-sho89">'89</a>] used a conflict list which
+is equivalent to Qhull's outside set. Later randomized algorithms
+retained the previously constructed facets. </p>
+
+<p>To compare Qhull to the randomized algorithms with option
+'Qr', compare &quot;hyperplanes constructed&quot; and
+&quot;distance tests&quot;. Qhull does not report CPU time
+because the randomization is inefficient. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="QRn">QRn - random rotation </a></h3>
+
+<p>Option 'QRn' randomly rotates the input. For Delaunay
+triangulations (<a href=qdelaun.htm>qdelaunay</a> or <a href=qvoronoi.htm>qvoronoi</a>),
+it rotates the lifted points about
+the last axis. </p>
+
+<p>If <em>n=0</em>, use time as the random number seed. If <em>n&gt;0</em>,
+use n as the random number seed. If <em>n=-1</em>, don't rotate
+but use time as the random number seed. If <em>n&lt;-1</em>,
+don't rotate but use <em>n</em> as the random number seed. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qs">Qs - search all points
+for the initial simplex </a></h3>
+
+<p>Qhull constructs an initial simplex from <i>d+1</i> points. It
+selects points with the maximum and minimum coordinates and
+non-zero determinants. If this fails, it searches all other
+points. In 8-d and higher, Qhull selects points with the minimum
+x or maximum coordinate (see qh_initialvertices in <tt>poly2.c </tt>).
+It rejects points with nearly zero determinants. This should work
+for almost all input sets.</p>
+
+<p>If Qhull can not construct an initial simplex, it reports a
+descriptive message. Usually, the point set is degenerate and one
+or more dimensions should be removed ('<a href="#Qb0">Qbk:0Bk:0</a>').
+If not, use option 'Qs'. It performs an exhaustive search for the
+best initial simplex. This is expensive is high dimensions. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qt">Qt - triangulated output</a></h3>
+
+<p>By default, qhull merges facets to handle precision errors. This
+produces non-simplicial facets (e.g., the convex hull of a cube has 6 square
+facets). Each facet is non-simplicial because it has four vertices.
+
+<p>Use option 'Qt' to triangulate all non-simplicial facets before generating
+results. Alternatively, use joggled input ('<a href="#QJn">QJ</a>') to
+prevent non-simplical facets. Unless '<a href="qh-optp.htm#Pp">Pp</a>' is set,
+qhull produces a warning if 'QJ' and 'Qt' are used together.
+
+<p>For Delaunay triangulations (<a href=qdelaun.htm>qdelaunay</a>), triangulation
+occurs after lifting the input sites to a paraboloid and computing the convex hull.
+</p>
+
+<p>Option 'Qt' is deprecated for Voronoi diagrams (<a href=qvoronoi.htm>qvoronoi</a>).
+It triangulates cospherical points, leading to duplicated Voronoi vertices.</p>
+
+<p>Option 'Qt' may produce degenerate facets with zero area.</p>
+
+<p>Facet area and hull volumes may differ with and without
+'Qt'. The triangulations are different and different triangles
+may be ignored due to precision errors.
+
+<p>With sufficient merging, the ridges of a non-simplicial facet may share more than two neighboring facets. If so, their triangulation ('<a href="#Qt">Qt</a>') will fail since two facets have the same vertex set. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qu">Qu - compute upper hull
+for furthest-site Delaunay triangulation </a></h3>
+
+<p>When computing a Delaunay triangulation (<a href=qdelaun.htm>qdelaunay</a>
+or <a href=qvoronoi.htm>qvoronoi</a>),
+Qhull computes both the the convex hull of points on a
+paraboloid. It normally prints facets of the lower hull. These
+correspond to the Delaunay triangulation. With option 'Qu', Qhull
+prints facets of the upper hull. These correspond to the <a
+href="qdelau_f.htm">furthest-site Delaunay triangulation</a>
+and the <a href="qvoron_f.htm">furthest-site Voronoi diagram</a>.</p>
+
+<p>Option 'qhull d Qbb Qu <a href="#Qg">Qg</a>' may improve the speed of option
+'Qu'. If you use the Qhull library, a faster method is 1) use
+Qhull to compute the convex hull of the input sites; 2) take the
+extreme points (vertices) of the convex hull; 3) add one interior
+point (e.g.,
+'<a href="qh-optf.htm#FV">FV</a>', the average of <em>d</em> extreme points); 4) run
+'qhull d Qbb Qu' or 'qhull v Qbb Qu' on these points.</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qv">Qv - test vertex
+neighbors for convexity </a></h3>
+
+<p>Normally, Qhull tests all facet neighbors for convexity.
+Non-neighboring facets which share a vertex may not satisfy the
+convexity constraint. This occurs when a facet undercuts the
+centrum of another facet. They should still be convex. Option
+'Qv' extends Qhull's convexity testing to all neighboring facets
+of each vertex. The extra testing occurs after the hull is
+constructed.. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="QVn">QVn - good facet if it
+includes point n, -n if not </a></h3>
+
+<p>With option 'QVn', a facet is good ('<a href="#Qg">Qg</a>',
+'<a href="qh-optp.htm#Pg">Pg</a>') if one of its vertices is
+point n. If <i>n&lt;0</i>, a good facet does not include point n.
+
+<p>If options '<a href="qh-optp.htm#PG">PG</a>'
+and '<a href="#Qg">Qg</a>' are not set, option '<a href="qh-optp.htm#Pg">Pg</a>'
+(print only good)
+is automatically set.
+</p>
+
+<p>Option 'QVn' behaves oddly with options '<a href="qh-optf.htm#Fx">Fx</a>'
+and '<a href=qvoronoi.htm>qvoronoi</a> <a href="qh-optf.htm#Fv2">Fv</a>'.
+
+<p>If used with option '<a href="#Qg">Qg</a>' (only process good facets), point n is
+either in the initial simplex or it is the first
+point added to the hull. Options 'QVn Qg' require either '<a href="#QJn">QJ</a>' or
+'<a href="#Q0">Q0</a>' (no merging).</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qx">Qx - exact pre-merges
+(allows coplanar facets) </a></h3>
+
+<p>Option 'Qx' performs exact merges while building the hull.
+Option 'Qx' is set by default in 5-d and higher. Use option '<a
+href="#Q0">Q0</a>' to not use 'Qx' by default. Unless otherwise
+specified, option 'Qx' sets option '<a href="qh-optc.htm#C0">C-0</a>'.
+</p>
+
+<p>The &quot;exact&quot; merges are merging a point into a
+coplanar facet (defined by '<a href="qh-optc.htm#Vn">Vn </a>', '<a
+href="qh-optc.htm#Un">Un</a>', and '<a href="qh-optc.htm#Cn">C-n</a>'),
+merging concave facets, merging duplicate ridges, and merging
+flipped facets. Coplanar merges and angle coplanar merges ('<a
+href="qh-optc.htm#An">A-n</a>') are not performed. Concavity
+testing is delayed until a merge occurs.</p>
+
+<p>After the hull is built, all coplanar merges are performed
+(defined by '<a href="qh-optc.htm#Cn">C-n</a>' and '<a
+href="qh-optc.htm#An">A-n</a>'), then post-merges are performed
+(defined by '<a href="qh-optc.htm#Cn2">Cn</a>' and '<a
+href="qh-optc.htm#An2">An</a>'). If facet progress is logged ('<a
+href="qh-optt.htm#TFn">TFn</a>'), Qhull reports each phase and
+prints intermediate summaries and statistics ('<a
+href="qh-optt.htm#Ts">Ts</a>'). </p>
+
+<p>Without 'Qx' in 5-d and higher, options '<a
+href="qh-optc.htm#Cn">C-n</a>' and '<a href="qh-optc.htm#An">A-n</a>'
+may merge too many facets. Since redundant vertices are not
+removed effectively, facets become increasingly wide. </p>
+
+<p>Option 'Qx' may report a wide facet. With 'Qx', coplanar
+facets are not merged. This can produce a &quot;dent&quot; in an
+intermediate hull. If a point is partitioned into a dent and it
+is below the surrounding facets but above other facets, one or
+more wide facets will occur. In practice, this is unlikely. To
+observe this effect, run Qhull with option '<a href="#Q6">Q6</a>'
+which doesn't pre-merge concave facets. A concave facet makes a
+large dent in the intermediate hull.</p>
+
+<p>Option 'Qx' may set an outer plane below one of the input
+points. A coplanar point may be assigned to the wrong facet
+because of a &quot;dent&quot; in an intermediate hull. After
+constructing the hull, Qhull double checks all outer planes with
+qh_check_maxout in <tt>poly2.c </tt>. If a coplanar point is
+assigned to the wrong facet, qh_check_maxout may reach a local
+maximum instead of locating all coplanar facets. This appears to
+be unlikely.</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Qz">Qz - add a
+point-at-infinity for Delaunay triangulations</a></h3>
+
+<p>Option 'Qz' adds a point above the paraboloid of lifted sites
+for a Delaunay triangulation. It allows the Delaunay
+triangulation of cospherical sites. It reduces precision errors
+for nearly cospherical sites.</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Q0">Q0 - no merging with C-0
+and Qx</a></h3>
+
+<p>Turn off default merge options '<a href="qh-optc.htm#C0">C-0</a>'
+and '<a href="#Qx">Qx</a>'. </p>
+
+<p>With 'Q0' and without other pre-merge options, Qhull ignores
+precision issues while constructing the convex hull. This may
+lead to precision errors. If so, a descriptive warning is
+generated. See <a href="qh-impre.htm">Precision issues</a>.</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Q1">Q1 - sort merges by type
+instead of angle </a></h3>
+
+<p>Qhull sorts the coplanar facets before picking a subset of the
+facets to merge. It merges concave and flipped facets first. Then
+it merges facets that meet at a steep angle. With 'Q1', Qhull
+sorts merges by type (coplanar, angle coplanar, concave) instead
+of by angle. This may make the facets wider. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="Q2">Q2 - merge all non-convex
+at once instead of independent sets </a></h3>
+
+<p>With 'Q2', Qhull merges all facets at once instead of
+performing merges in independent sets. This may make the facets
+wider. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="Q3">Q3 - do not merge
+redundant vertices </a></h3>
+
+<p>With 'Q3', Qhull does not remove redundant vertices. In 6-d
+and higher, Qhull never removes redundant vertices (since
+vertices are highly interconnected). Option 'Q3' may be faster,
+but it may result in wider facets. Its effect is easiest to see
+in 3-d and 4-d.</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Q4">Q4 - avoid merging </a>old
+facets into new facets</h3>
+
+<p>With 'Q4', Qhull avoids merges of an old facet into a new
+facet. This sometimes improves facet width and sometimes makes it
+worse. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="Q5">Q5 - do not correct outer
+planes at end of qhull </a></h3>
+
+<p>When merging facets or approximating a hull, Qhull tests
+coplanar points and outer planes after constructing the hull. It
+does this by performing a directed search (qh_findbest in <tt>geom.c</tt>).
+It includes points that are just inside the hull. </p>
+
+<p>With options 'Q5' or '<a href="qh-optp.htm#Po">Po</a>', Qhull
+does not test outer planes. The maximum outer plane is used
+instead. Coplanar points ('<a href="#Qc">Qc</a>') are defined by
+'<a href="qh-optc.htm#Un">Un</a>'. An input point may be outside
+of the maximum outer plane (this appears to be unlikely). An
+interior point may be above '<a href="qh-optc.htm#Un">Un</a>'
+from a hyperplane.</p>
+
+<p>Option 'Q5' may be used if outer planes are not needed. Outer
+planes are needed for options '<a href="qh-opto.htm#s">s</a>', '<a
+href="qh-optg.htm#G">G</a>', '<a href="qh-optg.htm#Go">Go </a>',
+'<a href="qh-optf.htm#Fs">Fs</a>', '<a href="qh-optf.htm#Fo">Fo</a>',
+'<a href="qh-optf.htm#FF">FF</a>', and '<a href="qh-opto.htm#f">f</a>'.</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Q6">Q6 - do not pre-merge
+concave or coplanar facets </a></h3>
+
+<p>With 'Q6', Qhull does not pre-merge concave or coplanar
+facets. This demonstrates the effect of &quot;dents&quot; when
+using '<a href="#Qx">Qx</a>'. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="Q7">Q7 - depth-first
+processing instead of breadth-first </a></h3>
+
+<p>With 'Q7', Qhull processes facets in depth-first order instead
+of breadth-first order. This may increase the locality of
+reference in low dimensions. If so, Qhull may be able to use
+virtual memory effectively. </p>
+
+<p>In 5-d and higher, many facets are visible from each
+unprocessed point. So each iteration may access a large
+proportion of allocated memory. This makes virtual memory
+ineffectual. Once real memory is used up, Qhull will spend most
+of its time waiting for I/O.</p>
+
+<p>Under 'Q7', Qhull runs slower and the facets may be wider. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="Q8">Q8 - ignore near-interior
+points </a></h3>
+
+<p>With 'Q8' and merging, Qhull does not process interior points
+that are near to a facet (as defined by qh_RATIOnearInside in
+user.h). This avoids partitioning steps. It may miss a coplanar
+point when adjusting outer hulls in qh_check_maxout(). The best
+value for qh_RATIOnearInside is not known. Options 'Q8 <a
+href="#Qc">Qc</a>' may be sufficient. </p>
+
+<h3><a href="#qhull">&#187;</a><a name="Q9">Q9 - process furthest of
+furthest points </a></h3>
+
+<p>With 'Q9', Qhull processes the furthest point of all outside
+sets. This may reduce precision problems. The furthest point of
+all outside sets is not necessarily the furthest point from the
+convex hull.</p>
+
+<h3><a href="#qhull">&#187;</a><a name="Q10">Q10 - no special processing
+for narrow distributions</a></h3>
+
+<p>With 'Q10', Qhull does not special-case narrow distributions.
+See <a href=qh-impre.htm#limit>Limitations of merged facets</a> for
+more information.
+
+<h3><a href="#qhull">&#187;</a><a name="Q11">Q11 - copy normals and recompute
+centrums for
+tricoplanar facets</a></h3>
+
+Option '<a href="#Qt">Qt</a>' triangulates non-simplicial facets
+into "tricoplanar" facets.
+Normally tricoplanar facets share the same normal, centrum, and
+Voronoi vertex. They can not be merged or replaced. With
+option 'Q11', Qhull duplicates the normal and Voronoi vertex.
+It recomputes the centrum.
+
+<p>Use 'Q11' if you use the Qhull library to add points
+incrementally and call qh_triangulate() after each point.
+Otherwise, Qhull will report an error when it tries to
+merge and replace a tricoplanar facet.
+
+<p>With sufficient merging and new points, option 'Q11' may
+lead to precision problems such
+as duplicate ridges and concave facets. For example, if qh_triangulate()
+is added to qh_addpoint(), RBOX 1000 s W1e-12 t1001813667 P0 | QHULL d Q11 Tv,
+reports an error due to a duplicate ridge.
+
+<h3><a href="#qhull">&#187;</a><a name="Q12">Q12 - do not error
+on wide merge due to duplicate ridge and nearly coincident points</a></h3>
+
+<p>In 3-d and higher Delaunay Triangulations or 4-d and higher convex hulls, multiple,
+nearly coincident points may lead to very wide facets. An error is reported if a
+merge across a duplicate ridge would increase the facet width by 100x or more.
+
+<p>Use option 'Q12' to log a warning instead of throwing an error.
+
+<p>For Delaunay triangulations, a bounding box may alleviate this error (e.g., <tt>rbox 500 C1,1E-13 t c G1 | qhull d</tt>).
+This avoids the ill-defined edge between upper and lower convex hulls.
+The problem will be fixed in a future release of Qhull.
+
+<p>To demonstrate the problem, use rbox option 'Cn,r,m' to generate nearly coincident points.
+For more information, see "Nearly coincident points on an edge"
+in <a href="qh-impre.htm#limit"</a>Nearly coincident points on an edge</a>.
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-optt.htm b/xs/src/qhull/html/qh-optt.htm
new file mode 100644
index 000000000..0709f58c6
--- /dev/null
+++ b/xs/src/qhull/html/qh-optt.htm
@@ -0,0 +1,278 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Qhull trace options (T)</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html"><img
+src="qh--dt.gif" alt="[delaunay]" align="middle" width="100"
+height="100"></a> Qhull trace options (T)</h1>
+
+This section lists the trace options for Qhull. These options are
+indicated by 'T' followed by a letter.
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<p><a href="index.htm#TOC">&#187;</a> <a href="qh-quick.htm#programs">Programs</a>
+<a name="trace">&#149;</a> <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<h2>Trace options</h2>
+
+<dl compact>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a href="#Tz">Tz</a></dt>
+ <dd>output error information to stdout instead of stderr</dd>
+ <dt><a href="#TI">TI file</a></dt>
+ <dd>input data from a file</dd>
+ <dt><a href="#TO">TO file</a></dt>
+ <dd>output results to a file</dd>
+ <dt><a href="#Ts">Ts</a></dt>
+ <dd>print statistics</dd>
+ <dt><a href="#TFn">TFn</a></dt>
+ <dd>report progress whenever n or more facets created</dd>
+ <dt><a href="#TRn">TRn</a></dt>
+ <dd>rerun qhull n times</dd>
+ <dt><a href="#Tv">Tv</a></dt>
+ <dd>verify result: structure, convexity, and point inclusion</dd>
+
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Debugging</b></dd>
+ <dt><a href="#Tc">Tc</a></dt>
+ <dd>check frequently during execution</dd>
+ <dt><a href="#TVn2">TVn</a></dt>
+ <dd>stop qhull after adding point n </dd>
+ <dt><a href="#TCn">TCn</a></dt>
+ <dd>stop qhull after building cone for point n</dd>
+ <dt><a href="#TVn">TV-n</a></dt>
+ <dd>stop qhull before adding point n</dd>
+ <dt><a href="#Tn">T4</a></dt>
+ <dd>trace at level n, 4=all, 5=mem/gauss, -1= events</dd>
+ <dt><a href="#TWn">TWn</a></dt>
+ <dd>trace merge facets when width &gt; n</dd>
+ <dt><a href="#TMn">TMn</a></dt>
+ <dd>turn on tracing at merge n</dd>
+ <dt><a href="#TPn">TPn</a></dt>
+ <dd>turn on tracing when point n added to hull</dd>
+</dl>
+
+<hr>
+
+<h3><a href="#trace">&#187;</a><a name="Tc">Tc - check frequently
+during execution </a></h3>
+
+<p>Qhull includes frequent checks of its data structures. Option
+'Tc' will catch most inconsistency errors. It is slow and should
+not be used for production runs. Option '<a href="#Tv">Tv</a>'
+performs the same checks after the hull is constructed.</p>
+
+<h3><a href="#trace">&#187;</a><a name="TCn">TCn - stop qhull after
+building cone for point n</a></h3>
+
+<p>Qhull builds a cone from the point to its horizon facets.
+Option 'TCn' stops Qhull just after building the cone. The output
+for '<a href="qh-opto.htm#f">f</a>' includes the cone and the old
+hull.'. </p>
+
+<h3><a href="#trace">&#187;</a><a name="TFn">TFn - report summary
+whenever n or more facets created </a></h3>
+
+<p>Option 'TFn' reports progress whenever more than n facets are
+created. The test occurs just before adding a new point to the
+hull. During post-merging, 'TFn' reports progress after more than
+<i>n/2</i> merges. </p>
+
+<h3><a href="#trace">&#187;</a><a name="TI">TI file - input data from file</a></h3>
+
+<p>Input data from 'file' instead of stdin. The filename may not
+contain spaces or use single quotes.
+You may use I/O redirection
+instead (e.g., 'rbox 10 | qdelaunay >results').</P>
+
+<h3><a href="#trace">&#187;</a><a name="TMn">TMn - turn on tracing at
+merge n </a></h3>
+
+<p>Turn on tracing at n'th merge. </p>
+
+<h3><a href="#trace">&#187;</a><a name="Tn">Tn - trace at level n</a></h3>
+
+<p>Qhull includes full execution tracing. 'T-1' traces events.
+'T1' traces the overall execution of the program. 'T2' and 'T3'
+trace overall execution and geometric and topological events.
+'T4' traces the algorithm. 'T5' includes information about memory
+allocation and Gaussian elimination. 'T1' is useful for logging
+progress of Qhull in high dimensions.</p>
+
+<p>Option 'Tn' can produce large amounts of output. Use options '<a
+href="#TPn">TPn</a>', '<a href="#TWn">TWn</a>', and '<a href="#TMn">TMn</a>' to selectively
+turn on tracing. Since all errors report the last processed
+point, option '<a href="#TPn">TPn</a>' is particularly useful.</p>
+
+<p>Different executions of the same program may produce different
+traces and different results. The reason is that Qhull uses hashing
+to match ridges of non-simplicial facets. For performance reasons,
+the hash computation uses
+memory addresses which may change across executions.
+
+<h3><a href="#trace">&#187;</a><a name="TO">TO file - output results to file</a></h3>
+
+<p>Redirect stdout to 'file'. The filename may be enclosed in
+single quotes. Unix and Windows NT users may use I/O redirection
+instead (e.g., 'rbox 10 | qdelaunay >results').</P>
+<p>
+Windows95 users should always use 'TO file'. If they use I/O redirection,
+error output is not sent to the console. Qhull uses single quotes instead
+of double quotes because a missing double quote can
+freeze Windows95 (e.g., do not run, rbox 10 | qhull TO &quot;x)</p>
+<p>
+
+<h3><a href="#trace">&#187;</a><a name="TPn">TPn - turn on tracing
+when point n added to hull </a></h3>
+
+<p>Option 'TPn' turns on tracing when point n is added to
+the hull. It also traces partitions of point n. This option
+reduces the output size when tracing. It is the normal
+method to determine the cause of a Qhull error. All Qhull errors
+report the last point added.
+
+<p>Use options 'TPn <a href="qh-optt.htm#TVn">TVn</a>' to
+trace the addition of point n to the convex hull and stop when done.</p>
+
+<p>If used with option '<a href="qh-optt.htm#TWn">TWn</a>',
+'TPn' turns off tracing after adding point n to the hull.
+Use options 'TPn TWn' to
+trace the addition of point n to the convex hull, partitions
+of point n, and wide merges.</p>
+
+<h3><a href="#trace">&#187;</a><a name="TRn">TRn - rerun qhull n times</a></h3>
+
+<p>Option 'TRn' reruns Qhull n times. It is usually used
+with '<a href="qh-optq.htm#QJn">QJn</a>' to determine the probability
+that a given joggle will fail. The summary
+('<a href="qh-opto.htm#s">s</a>') lists the failure
+rate and the precision errors that occurred.
+Option '<a href="#Ts">Ts</a>' will report statistics for
+all of the runs. Trace and output options only apply to the last
+run. An event trace, '<a href="#Tn">T-1</a>' reports events for all runs.
+
+<p>Tracing applies to the last run of Qhull. If an error
+is reported, the options list the run number as "_run".
+To trace this run, set 'TRn' to the same value.</p>
+
+<h3><a href="#trace">&#187;</a><a name="Ts">Ts - print statistics </a></h3>
+
+<p>Option 'Ts' collects statistics and prints them to stderr. For
+Delaunay triangulations, the angle statistics are restricted to
+the lower or upper envelope.</p>
+
+<h3><a href="#trace">&#187;</a><a name="Tv">Tv - verify result:
+structure, convexity, and point inclusion </a></h3>
+
+<p>Option 'Tv' checks the topological structure, convexity, and
+point inclusion. If precision problems occurred, facet convexity
+is tested whether or not 'Tv' is selected. Option 'Tv' does not
+check point inclusion if forcing output with '<a
+href="qh-optp.htm#Po">Po</a>', or if '<a href="qh-optq.htm#Q5">Q5</a>'
+is set. </p>
+
+<p>The convex hull of a set of points is the smallest polytope
+that includes the points. Option 'Tv' tests point inclusion.
+Qhull verifies that all points are below all outer planes
+(facet-&gt;maxoutside). Point inclusion is exhaustive if merging
+or if the facet-point product is small enough; otherwise Qhull
+verifies each point with a directed search (qh_findbest). To
+force an exhaustive test when using option '<a
+href="qh-optc.htm#C0">C-0</a>' (default), use 'C-1e-30' instead. </p>
+
+<p>Point inclusion testing occurs after producing output. It
+prints a message to stderr unless option '<a
+href="qh-optp.htm#Pp">Pp</a>' is used. This allows the user to
+interrupt Qhull without changing the output. </p>
+
+<p>With '<a href=qvoronoi.htm>qvoronoi</a> <a href="qh-optf.htm#Fi2">Fi</a>'
+and '<a href=qvoronoi.htm>qvoronoi</a> <a href="qh-optf.htm#Fo2">Fo</a>',
+option 'Tv' collects statistics that verify all Voronoi vertices lie
+on the separating hyperplane, and for bounded regions, all
+separating hyperplanes are perpendicular bisectors.
+
+<h3><a href="#trace">&#187;</a><a name="TVn">TV-n - stop qhull before
+adding point n</a></h3>
+
+<p>Qhull adds one point at a time to the convex hull. See <a
+href="qh-eg.htm#how">how Qhull adds a point</a>. Option 'TV-n'
+stops Qhull just before adding a new point. Output shows the hull
+at this time.</p>
+
+<h3><a href="#trace">&#187;</a><a name="TVn2">TVn - stop qhull after
+adding point n</a></h3>
+
+<p>Option 'TVn' stops Qhull after it has added point n. Output
+shows the hull at this time.</p>
+
+<h3><a href="#trace">&#187;</a><a name="TWn">TWn - trace merge facets
+when width &gt; n </a></h3>
+
+<p>Along with TMn, this option allows the user to determine the
+cause of a wide merge.</p>
+<h3><a href="#trace">&#187;</a><a name="Tz">Tz - send all output to
+stdout </a></h3>
+
+<p>Redirect stderr to stdout. </p>
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qh-quick.htm b/xs/src/qhull/html/qh-quick.htm
new file mode 100644
index 000000000..9d52e7d75
--- /dev/null
+++ b/xs/src/qhull/html/qh-quick.htm
@@ -0,0 +1,495 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Qhull quick reference</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOC"><b>Up:</b></a> <a href="http://www.qhull.org">Home
+page for Qhull</a> <br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a> <br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="qh-code.htm#TOC">Qhull internals</a><br>
+<b>To:</b> <a href="../src/libqhull/index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="../src/libqhull/index.htm#TOC">Qhull files</a><br>
+<b>To:</b> <a href="../src/libqhull/qh-geom.htm">Geom</a> &#149; <a href="../src/libqhull/qh-globa.htm">Global</a>
+&#149; <a href="../src/libqhull/qh-io.htm">Io</a> &#149; <a href="../src/libqhull/qh-mem.htm">Mem</a>
+&#149; <a href="../src/libqhull/qh-merge.htm">Merge</a> &#149; <a href="../src/libqhull/qh-poly.htm">Poly</a>
+&#149; <a href="../src/libqhull/qh-qhull.htm">Qhull</a> &#149; <a href="../src/libqhull/qh-set.htm">Set</a>
+&#149; <a href="../src/libqhull/qh-stat.htm">Stat</a> &#149; <a href="../src/libqhull/qh-user.htm">User</a>
+</p>
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/cone.html"><img
+src="qh--cone.gif" alt="[cone]" align="middle" width="100"
+height="100"></a> Qhull quick reference</h1>
+
+This section lists all programs and options in Qhull.
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<p>
+<a name="programs">&nbsp;</a>
+<hr>
+<b>Qhull programs</b>
+<p><a href="#TOC">&#187;</a> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<dl>
+ <dt><a href="qconvex.htm">qconvex</a> -- convex hull</dt>
+ <dd><a href="qconvex.htm#synopsis">sy</a>nopsis &#149; <a
+ href="qconvex.htm#input">in</a>put &#149; <a
+ href="qconvex.htm#outputs">ou</a>tputs &#149; <a
+ href="qconvex.htm#controls">co</a>ntrols &#149; <a
+ href="qconvex.htm#graphics">gr</a>aphics &#149; <a
+ href="qconvex.htm#notes">no</a>tes &#149; <a
+ href="qconvex.htm#conventions">co</a>nventions &#149; <a
+ href="qconvex.htm#options">op</a>tions</dd>
+ <dt>&nbsp;</dt>
+ <dt><a href="qdelaun.htm">qdelaunay</a> -- Delaunay triangulation</dt>
+ <dd><a href="qdelaun.htm#synopsis">sy</a>nopsis &#149; <a
+ href="qdelaun.htm#input">in</a>put &#149; <a
+ href="qdelaun.htm#outputs">ou</a>tputs &#149; <a
+ href="qdelaun.htm#controls">co</a>ntrols &#149; <a
+ href="qdelaun.htm#graphics">gr</a>aphics &#149; <a
+ href="qdelaun.htm#notes">no</a>tes &#149; <a
+ href="qdelaun.htm#conventions">co</a>nventions &#149; <a
+ href="qdelaun.htm#options">op</a>tions</dd>
+ <dt>&nbsp;</dt>
+ <dt><a href="qdelau_f.htm">qdelaunay Qu</a> -- furthest-site Delaunay triangulation</dt>
+ <dd><a href="qdelau_f.htm#synopsis">sy</a>nopsis &#149; <a
+ href="qdelau_f.htm#input">in</a>put &#149; <a
+ href="qdelau_f.htm#outputs">ou</a>tputs &#149; <a
+ href="qdelau_f.htm#controls">co</a>ntrols &#149; <a
+ href="qdelau_f.htm#graphics">gr</a>aphics &#149; <a
+ href="qdelau_f.htm#notes">no</a>tes &#149; <a
+ href="qdelau_f.htm#conventions">co</a>nventions &#149; <a
+ href="qdelau_f.htm#options">op</a>tions</dd>
+ <dt>&nbsp;</dt>
+ <dt><a href="qhalf.htm">qhalf</a> -- halfspace intersection about a point</dt>
+ <dd><a href="qhalf.htm#synopsis">sy</a>nopsis &#149; <a
+ href="qhalf.htm#input">in</a>put &#149; <a
+ href="qhalf.htm#outputs">ou</a>tputs &#149; <a
+ href="qhalf.htm#controls">co</a>ntrols &#149; <a
+ href="qhalf.htm#graphics">gr</a>aphics &#149; <a
+ href="qhalf.htm#notes">no</a>tes &#149; <a
+ href="qhalf.htm#conventions">co</a>nventions &#149; <a
+ href="qhalf.htm#options">op</a>tions</dd>
+ <dt>&nbsp;</dt>
+ <dt><a href="qvoronoi.htm">qvoronoi</a> -- Voronoi diagram</dt>
+ <dd><a href="qvoronoi.htm#synopsis">sy</a>nopsis &#149; <a
+ href="qvoronoi.htm#input">in</a>put &#149; <a
+ href="qvoronoi.htm#outputs">ou</a>tputs &#149;
+ <a href="qvoronoi.htm#controls">co</a>ntrols &#149; <a
+ href="qvoronoi.htm#graphics">gr</a>aphics &#149; <a
+ href="qvoronoi.htm#notes">no</a>tes &#149; <a
+ href="qvoronoi.htm#conventions">co</a>nventions &#149; <a
+ href="qvoronoi.htm#options">op</a>tions</dd>
+ <dt>&nbsp;</dt>
+ <dt><a href="qvoron_f.htm">qvoronoi Qu</a> -- furthest-site Voronoi diagram</dt>
+ <dd><a href="qvoron_f.htm#synopsis">sy</a>nopsis &#149; <a
+ href="qvoron_f.htm#input">in</a>put &#149; <a
+ href="qvoron_f.htm#outputs">ou</a>tputs &#149; <a
+ href="qvoron_f.htm#controls">co</a>ntrols &#149; <a
+ href="qvoron_f.htm#graphics">gr</a>aphics &#149; <a
+ href="qvoron_f.htm#notes">no</a>tes &#149; <a
+ href="qvoron_f.htm#conventions">co</a>nventions &#149; <a
+ href="qvoron_f.htm#options">op</a>tions</dd>
+ <dt>&nbsp;</dt>
+ <dt><a href="rbox.htm">rbox</a> -- generate point distributions for qhull</dt>
+ <dd><a href="rbox.htm#synopsis">sy</a>nopsis &#149; <a
+ href="rbox.htm#outputs">ou</a>tputs &#149; <a
+ href="rbox.htm#examples">ex</a>amples &#149; <a
+ href="rbox.htm#notes">no</a>tes &#149; <a
+ href="rbox.htm#options">op</a>tions</dd>
+ <dt>&nbsp;</dt>
+ <dt><a href="qhull.htm">qhull</a> -- convex hull and related structures</dt>
+ <dd><a href="qhull.htm#synopsis">sy</a>nopsis &#149; <a
+ href="qhull.htm#input">in</a>put &#149; <a
+ href="qhull.htm#outputs">ou</a>tputs &#149; <a
+ href="qhull.htm#controls">co</a>ntrols &#149; <a
+ href="qhull.htm#options">op</a>tions</dd>
+ </dl>
+<a name="options">&nbsp;</a>
+<hr>
+<b>Qhull options</b>
+
+<p><a href="#TOC">&#187;</a> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a></p>
+
+<p><table>
+<!-- Note: keep all lines the same for easy reorganization -->
+<tr>
+<td><nobr>'<a href=qh-optf.htm#Fa>Fa</a>'
+Farea
+</nobr></td><td><nobr>'<a href=qh-optf.htm#Fa>FA</a>'
+FArea-total
+</nobr></td><td><nobr>'<a href=qh-optf.htm#Fc>Fc</a>'
+Fcoplanars
+</nobr></td><td><nobr>'<a href=qh-optf.htm#FC>FC</a>'
+FCentrums
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optf.htm#Fd>Fd</a>'
+Fd-cdd-in
+</nobr></td><td><nobr>'<a href=qh-optf.htm#FD>FD</a>'
+FD-cdd-out
+</nobr></td><td><nobr>'<a href=qh-optf.htm#FF>FF</a>'
+FF-dump-xridge
+</nobr></td><td><nobr>'<a href=qh-optf.htm#Fi>Fi</a>'
+Finner
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optf.htm#Fi2>Fi</a>'
+Finner_bounded
+</nobr></td><td><nobr>'<a href=qh-optf.htm#FI>FI</a>'
+FIDs
+</nobr></td><td><nobr>'<a href=qh-optf.htm#Fm>Fm</a>'
+Fmerges
+</nobr></td><td><nobr>'<a href=qh-optf.htm#FM>FM</a>'
+FMaple
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optf.htm#Fn>Fn</a>'
+Fneighbors
+</nobr></td><td><nobr>'<a href=qh-optf.htm#FN>FN</a>'
+FNeigh-vertex
+</nobr></td><td><nobr>'<a href=qh-optf.htm#Fo>Fo</a>'
+Fouter
+</nobr></td><td><nobr>'<a href=qh-optf.htm#Fo2>Fo</a>'
+Fouter_unbounded
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optf.htm#FO>FO</a>'
+FOptions
+</nobr></td><td><nobr>'<a href=qh-optf.htm#Fp>Fp</a>'
+Fpoint-intersect
+</nobr></td><td><nobr>'<a href=qh-optf.htm#FP>FP</a>'
+FPoint_near
+</nobr></td><td><nobr>'<a href=qh-optf.htm#FQ>FQ</a>'
+FQhull
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optf.htm#Fs>Fs</a>'
+Fsummary
+</nobr></td><td><nobr>'<a href=qh-optf.htm#FS>FS</a>'
+FSize
+</nobr></td><td><nobr>'<a href=qh-optf.htm#Ft>Ft</a>'
+Ftriangles
+</nobr></td><td><nobr>'<a href=qh-optf.htm#Fv>Fv</a>'
+Fvertices
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optf.htm#Fv2>Fv</a>'
+Fvoronoi
+</nobr></td><td><nobr>'<a href=qh-optf.htm#FV>FV</a>'
+FVertex-ave
+</nobr></td><td><nobr>'<a href=qh-optf.htm#Fx>Fx</a>'
+Fxtremes
+</nobr></td><td colspan=2><nobr>
+<a href=qh-impre.htm#joggle>Merged facets or joggled input</a>
+
+</nobr></td></tr>
+<tr><td>&nbsp;</td></tr><tr>
+<td><nobr>'<a href=qh-optp.htm#PAn>PAn</a>'
+PArea-keep
+</nobr></td><td><nobr>'<a href=qh-optp.htm#Pdk>Pdk:n</a>'
+Pdrop_low
+</nobr></td><td><nobr>'<a href=qh-optp.htm#PDk>PDk:n</a>'
+Pdrop_high
+</nobr></td><td><nobr>'<a href=qh-optp.htm#Pg>Pg</a>'
+Pgood
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optp.htm#PFn>PFn</a>'
+PFacet_area_keep
+</nobr></td><td><nobr>'<a href=qh-optp.htm#PG>PG</a>'
+PGood_neighbors
+</nobr></td><td><nobr>'<a href=qh-optp.htm#PMn>PMn</a>'
+PMerge-keep
+</nobr></td><td><nobr>'<a href=qh-optp.htm#Po>Po</a>'
+Poutput_forced
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optp.htm#Po2>Po</a>'
+Poutput_error
+</nobr></td><td><nobr>'<a href=qh-optp.htm#Pp>Pp</a>'
+Pprecision_not
+
+</nobr></td></tr>
+<tr><td>&nbsp;</td></tr><tr>
+<td><nobr>'<a href=qhull.htm#outputs>d</a>'
+delaunay
+</nobr></td><td><nobr>'<a href=qhull.htm#outputs>v</a>'
+voronoi
+</nobr></td><td><nobr>'<a href=qh-optg.htm>G</a>'
+Geomview
+</nobr></td><td><nobr>'<a href=qhull.htm#outputs>H</a>'
+Halfspace
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-opto.htm#f>f</a>'
+facet_dump
+</nobr></td><td><nobr>'<a href=qh-opto.htm#i>i</a>'
+incidences
+</nobr></td><td><nobr>'<a href=qh-opto.htm#m>m</a>'
+mathematica
+</nobr></td><td><nobr>'<a href=qh-opto.htm#n>n</a>'
+normals
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-opto.htm#o>o</a>'
+OFF_format
+</nobr></td><td><nobr>'<a href=qh-opto.htm#p>p</a>'
+points
+</nobr></td><td><nobr>'<a href=qh-opto.htm#s>s</a>'
+summary
+
+</nobr></td></tr>
+<tr><td>&nbsp;</td></tr><tr>
+<td><nobr>'<a href=qh-optg.htm#Gv>Gv</a>'
+Gvertices
+</nobr></td><td><nobr>'<a href=qh-optg.htm#Gp>Gp</a>'
+Gpoints
+</nobr></td><td><nobr>'<a href=qh-optg.htm#Ga>Ga</a>'
+Gall_points
+</nobr></td><td><nobr>'<a href=qh-optg.htm#Gn>Gn</a>'
+Gno_planes
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optg.htm#Gi>Gi</a>'
+Ginner
+</nobr></td><td><nobr>'<a href=qh-optg.htm#Gc>Gc</a>'
+Gcentrums
+</nobr></td><td><nobr>'<a href=qh-optg.htm#Gh>Gh</a>'
+Ghyperplanes
+</nobr></td><td><nobr>'<a href=qh-optg.htm#Gr>Gr</a>'
+Gridges
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optg.htm#Go>Go</a>'
+Gouter
+</nobr></td><td><nobr>'<a href=qh-optg.htm#GDn>GDn</a>'
+GDrop_dim
+</nobr></td><td><nobr>'<a href=qh-optg.htm#Gt>Gt</a>'
+Gtransparent
+
+</nobr></td></tr>
+<tr><td>&nbsp;</td></tr><tr>
+<td><nobr>'<a href=qh-optt.htm#Tn>T4</a>'
+T4_trace
+</nobr></td><td><nobr>'<a href=qh-optt.htm#Tc>Tc</a>'
+Tcheck_often
+</nobr></td><td><nobr>'<a href=qh-optt.htm#Ts>Ts</a>'
+Tstatistics
+</nobr></td><td><nobr>'<a href=qh-optt.htm#Tv>Tv</a>'
+Tverify
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optt.htm#Tz>Tz</a>'
+Tz_stdout
+</nobr></td><td><nobr>'<a href=qh-optt.htm#TFn>TFn</a>'
+TFacet_log
+<td><nobr>'<a href=qh-optt.htm#TI>TI file</a>'
+TInput_file
+</nobr></td><td><nobr>'<a href=qh-optt.htm#TPn>TPn</a>'
+TPoint_trace
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optt.htm#TMn>TMn</a>'
+TMerge_trace
+</nobr></td><td><nobr>'<a href=qh-optt.htm#TO>TO file</a>'
+TOutput_file
+</nobr></td><td><nobr>'<a href=qh-optt.htm#TRn>TRn</a>'
+TRerun
+</nobr></td><td><nobr>'<a href=qh-optt.htm#TWn>TWn</a>'
+TWide_trace
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optt.htm#TVn>TV-n</a>'
+TVertex_stop_before
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optt.htm#TVn2>TVn</a>'
+TVertex_stop_after
+</nobr></td><td><nobr>'<a href=qh-optt.htm#TCn>TCn</a>'
+TCone_stop_after
+
+</nobr></td></tr>
+<tr><td>&nbsp;</td></tr><tr>
+<td><nobr>'<a href=qh-optc.htm#An>A-n</a>'
+Angle_max_pre
+</nobr></td><td><nobr>'<a href=qh-optc.htm#An2>An</a>'
+Angle_max_post
+</nobr></td><td><nobr>'<a href=qh-optc.htm#C0>C-0</a>'
+Centrum_roundoff
+</nobr></td><td><nobr>'<a href=qh-optc.htm#Cn>C-n</a>'
+Centrum_size_pre
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optc.htm#Cn2>Cn</a>'
+Centrum_size_post
+</nobr></td><td><nobr>'<a href=qh-optc.htm#En>En</a>'
+Error_round
+</nobr></td><td><nobr>'<a href=qh-optc.htm#Rn>Rn</a>'
+Random_dist
+</nobr></td><td><nobr>'<a href=qh-optc.htm#Vn>Vn</a>'
+Visible_min
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optc.htm#Un>Un</a>'
+Ucoplanar_max
+</nobr></td><td><nobr>'<a href=qh-optc.htm#Wn>Wn</a>'
+Wide_outside
+
+</nobr></td></tr>
+<tr><td>&nbsp;</td></tr><tr>
+<td><nobr>'<a href=qh-optq.htm#Qbk>Qbk:n</a>'
+Qbound_low
+</nobr></td><td><nobr>'<a href=qh-optq.htm#QBk>QBk:n</a>'
+QBound_high
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Qb0>Qbk:0Bk:0</a>'
+Qbound_drop
+</nobr></td><td><nobr>'<a href=qh-optq.htm#QbB>QbB</a>'
+QbB-scale-box
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optq.htm#Qbb>Qbb</a>'
+Qbb-scale-last
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Qc>Qc</a>'
+Qcoplanar
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Qf>Qf</a>'
+Qfurthest
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Qg>Qg</a>'
+Qgood_only
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optq.htm#QGn>QGn</a>'
+QGood_point
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Qi>Qi</a>'
+Qinterior
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Qm>Qm</a>'
+Qmax_out
+</nobr></td><td><nobr>'<a href=qh-optq.htm#QJn>QJn</a>'
+QJoggle
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optq.htm#Qr>Qr</a>'
+Qrandom
+</nobr></td><td><nobr>'<a href=qh-optq.htm#QRn>QRn</a>'
+QRotate
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Qs>Qs</a>'
+Qsearch_1st
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Qt>Qt</a>'
+Qtriangulate
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optq.htm#Qu>Qu</a>'
+QupperDelaunay
+</nobr><td><nobr>'<a href=qh-optq.htm#QVn>QVn</a>'
+QVertex_good
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Qv>Qv</a>'
+Qvneighbors
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Qx>Qx</a>'
+Qxact_merge
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optq.htm#Qz>Qz</a>'
+Qzinfinite
+
+</nobr></td></tr>
+<tr><td>&nbsp;</td></tr><tr>
+<td><nobr>'<a href=qh-optq.htm#Q0>Q0</a>'
+Q0_no_premerge
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Q1>Q1</a>'
+Q1_no_angle
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Q2>Q2</a>'
+Q2_no_independ
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Q3>Q3</a>'
+Q3_no_redundant
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optq.htm#Q4>Q4</a>'
+Q4_no_old
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Q5>Q5</a>'
+Q5_no_check_out
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Q6>Q6</a>'
+Q6_no_concave
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Q7>Q7</a>'
+Q7_depth_first
+
+</nobr></td></tr><tr>
+<td><nobr>'<a href=qh-optq.htm#Q8>Q8</a>'
+Q8_no_near_in
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Q9>Q9</a>'
+Q9_pick_furthest
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Q10>Q10</a>'
+Q10_no_narrow
+</nobr></td><td><nobr>'<a href=qh-optq.htm#Q11>Q11</a>'
+Q11_trinormals
+</td></tr></table>
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home
+page for Qhull</a> <br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a> <br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="qh-code.htm#TOC">Qhull internals</a><br>
+<b>To:</b> <a href="../src/libqhull/index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="../src/libqhull/index.htm#TOC">Qhull files</a><br>
+<b>To:</b> <a href="../src/libqhull/qh-geom.htm">Geom</a> &#149; <a href="../src/libqhull/qh-globa.htm">Global</a>
+&#149; <a href="../src/libqhull/qh-io.htm">Io</a> &#149; <a href="../src/libqhull/qh-mem.htm">Mem</a>
+&#149; <a href="../src/libqhull/qh-merge.htm">Merge</a> &#149; <a href="../src/libqhull/qh-poly.htm">Poly</a>
+&#149; <a href="../src/libqhull/qh-qhull.htm">Qhull</a> &#149; <a href="../src/libqhull/qh-set.htm">Set</a>
+&#149; <a href="../src/libqhull/qh-stat.htm">Stat</a> &#149; <a href="../src/libqhull/qh-user.htm">User</a><br>
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qhalf.htm b/xs/src/qhull/html/qhalf.htm
new file mode 100644
index 000000000..c87fe719e
--- /dev/null
+++ b/xs/src/qhull/html/qhalf.htm
@@ -0,0 +1,626 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>qhalf -- halfspace intersection about a point</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up</b></a><b>:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/half.html"><img
+src="qh--half.gif" alt="[halfspace]" align="middle" width="100"
+height="100"></a>qhalf -- halfspace intersection about a point</h1>
+
+<p>The intersection of a set of halfspaces is a polytope. The
+polytope may be unbounded. See Preparata &amp; Shamos [<a
+href="index.htm#pre-sha85">'85</a>] for a discussion. In low
+dimensions, halfspace intersection may be used for linear
+programming.
+
+<blockquote>
+<dl compact>
+ <dt><p><b>Example:</b> rbox c | qconvex <a href="qh-optf.htm#FQ">FQ</a> <a href="qh-optf.htm#FV">FV</a>
+ <a href="qh-opto.htm#n">n</a> | qhalf <a
+ href="qh-optf.htm#Fp">Fp</a></dt>
+ <dd>Print the intersection of the facets of a cube. <tt>rbox c</tt>
+ generates the vertices of a cube. <tt>qconvex FV n</tt> returns of average
+ of the cube's vertices (in this case, the origin) and the halfspaces
+ that define the cube. <tt>qhalf Fp</tt> computes the intersection of
+ the halfspaces about the origin. The intersection is the vertices
+ of the original cube.</dd>
+
+ <dt><p><b>Example:</b> rbox c d G0.55 | qconvex <a href="qh-optf.htm#FQ">FQ</a> <a href="qh-optf.htm#FV">FV</a>
+ <a href="qh-opto.htm#n">n</a> | qhalf <a
+ href="qh-optf.htm#Fp">Fp</a></dt>
+ <dd>Print the intersection of the facets of a cube and a diamond. There
+ are 24 facets and 14 intersection points. Four facets define each diamond
+ vertex. Six facets define each cube vertex.
+ </dd>
+
+ <dt><p><b>Example:</b> rbox c d G0.55 | qconvex <a href="qh-optf.htm#FQ">FQ</a> <a href="qh-optf.htm#FV">FV</a>
+ <a href="qh-opto.htm#n">n</a> | qhalf <a
+ href="qh-optf.htm#Fp">Fp</a>
+ <a href="qh-optq.htm#Qt">Qt</a></dt>
+ <dd>Same as above except triangulate before computing
+ the intersection points. Three facets define each intersection
+ point. There are two duplicates of the diamond and four duplicates of the cube.
+ </dd>
+
+ <dt><p><b>Example:</b> rbox 10 s t10 | qconvex <a href="qh-optf.htm#FQ">FQ</a> <a href="qh-optf.htm#FV">FV</a>
+ <a href="qh-opto.htm#n">n</a> | qhalf <a
+ href="qh-optf.htm#Fp">Fp</a> <a
+ href="qh-optf.htm#Fn">Fn</a></dt>
+ <dd>Print the intersection of the facets of the convex hull of 10 cospherical points.
+ Include the intersection points and the neighboring intersections.
+ As in the previous examples, the intersection points are nearly the same as the
+ original input points.
+ </dd>
+</dl>
+</blockquote>
+
+<p>In Qhull, a <i>halfspace</i> is defined by the points on or below a hyperplane.
+The distance of each point to the hyperplane is less than or equal to zero.
+
+<p>Qhull computes a halfspace intersection by the geometric
+duality between points and halfspaces.
+See <a href="qh-eg.htm#half">halfspace examples</a>,
+<a href="#notes">qhalf notes</a>, and
+option 'p' of <a href="#outputs">qhalf outputs</a>. </p>
+
+<p>Qhalf's <a href="#outputs">outputs</a> are the intersection
+points (<a href="qh-optf.htm#Fp">Fp</a>) and
+the neighboring intersection points (<a href="qh-optf.htm#Fn">Fn</a>).
+For random inputs, halfspace
+intersections are usually defined by more than <i>d</i> halfspaces. See the sphere example.
+
+<p>You can try triangulated output ('<a href="qh-optq.htm#Qt">Qt</a>') and joggled input ('<a href="qh-optq.htm#QJn">QJ</a>').
+It demonstrates that triangulated output is more accurate than joggled input.
+
+<p>If you use '<a href="qh-optq.htm#Qt">Qt</a>' (triangulated output), all
+halfspace intersections are simplicial (e.g., three halfspaces per
+intersection in 3-d). In 3-d, if more than three halfspaces intersect
+at the same point, triangulated output will produce
+duplicate intersections, one for each additional halfspace. See the third example, or
+add 'Qt' to the sphere example.</p>
+
+<p>If you use '<a href="qh-optq.htm#QJn">QJ</a>' (joggled input), all halfspace
+intersections are simplicial. This may lead to nearly identical
+intersections. For example, either replace 'Qt' with 'QJ' above, or add
+'QJ' to the sphere example.
+See <a
+href="qh-impre.htm#joggle">Merged facets or joggled input</a>. </p>
+
+<p>The 'qhalf' program is equivalent to
+'<a href=qhull.htm#outputs>qhull H</a>' in 2-d to 4-d, and
+'<a href=qhull.htm#outputs>qhull H</a> <a href=qh-optq.htm#Qx>Qx</a>'
+in 5-d and higher. It disables the following Qhull
+<a href=qh-quick.htm#options>options</a>: <i>d n v Qbb QbB Qf Qg Qm
+Qr QR Qv Qx Qz TR E V Fa FA FC FD FS Ft FV Gt Q0,etc</i>.
+
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+
+<h3><a href="#TOP">&#187;</a><a name="synopsis">qhalf synopsis</a></h3>
+<pre>
+qhalf- halfspace intersection about a point.
+ input (stdin): [dim, 1, interior point]
+ dim+1, n
+ halfspace coefficients + offset
+ comments start with a non-numeric character
+
+options (qhalf.htm):
+ Hn,n - specify coordinates of interior point
+ Qt - triangulated output
+ QJ - joggle input instead of merging facets
+ Tv - verify result: structure, convexity, and redundancy
+ . - concise list of all options
+ - - one-line description of all options
+
+output options (subset):
+ s - summary of results (default)
+ Fp - intersection coordinates
+ Fv - non-redundant halfspaces incident to each intersection
+ Fx - non-redundant halfspaces
+ o - OFF file format (dual convex hull)
+ G - Geomview output (dual convex hull)
+ m - Mathematica output (dual convex hull)
+ QVn - print intersections for halfspace n, -n if not
+ TO file - output results to file, may be enclosed in single quotes
+
+examples:
+ rbox d | qconvex n | qhalf s H0,0,0 Fp
+ rbox c | qconvex FV n | qhalf s i
+ rbox c | qconvex FV n | qhalf s o
+</pre>
+
+<h3><a href="#TOP">&#187;</a><a name="input">qhalf input</a></h3>
+
+<blockquote>
+<p>The input data on <tt>stdin</tt> consists of:</p>
+<ul>
+ <li>[optional] interior point
+ <ul>
+ <li>dimension
+ <li>1
+ <li>coordinates of interior point
+ </ul>
+ <li>dimension + 1
+ <li>number of halfspaces</li>
+ <li>halfspace coefficients followed by offset</li>
+</ul>
+
+<p>Use I/O redirection (e.g., qhalf &lt; data.txt), a pipe (e.g., rbox c | qconvex FV n | qhalf),
+or the '<a href=qh-optt.htm#TI>TI</a>' option (e.g., qhalf TI data.txt).
+
+<p>Qhull needs an interior point to compute the halfspace
+intersection. An interior point is clearly inside all of the halfspaces.
+A point is <i>inside</i> a halfspace if its distance to the corresponding hyperplane is negative.
+
+<p>The interior point may be listed at the beginning of the input (as shown above).
+If not, option
+'Hn,n' defines the interior point as
+[n,n,0,...] where <em>0</em> is the default coordinate (e.g.,
+'H0' is the origin). Use linear programming if you do not know
+the interior point (see <a href="#notes">halfspace notes</a>),</p>
+
+<p>The input to qhalf is a set of halfspaces that are defined by their hyperplanes.
+Each halfspace is defined by
+<em>d</em> coefficients followed by a signed offset. This defines
+a linear inequality. The coefficients define a vector that is
+normal to the halfspace.
+The vector may have any length. If it
+has length one, the offset is the distance from the origin to the
+halfspace's boundary. Points in the halfspace have a negative distance to the hyperplane.
+The distance from the interior point to each
+halfspace is likewise negative.</p>
+
+<p>The halfspace format is the same as Qhull's output options '<a
+href="qh-opto.htm#n">n</a>', '<a href="qh-optf.htm#Fo">Fo</a>',
+and '<a href="qh-optf.htm#Fi">Fi</a>'. Use option '<a
+href="qh-optf.htm#Fd">Fd</a>' to use cdd format for the
+halfspaces.</p>
+
+<p>For example, here is the input for computing the intersection
+of halfplanes that form a cube.</p>
+
+<blockquote>
+ <p>rbox c | qconvex FQ FV n TO data </p>
+ <pre>
+RBOX c | QCONVEX FQ FV n
+3 1
+ 0 0 0
+4
+6
+ 0 0 -1 -0.5
+ 0 -1 0 -0.5
+ 1 0 0 -0.5
+ -1 0 0 -0.5
+ 0 1 0 -0.5
+ 0 0 1 -0.5
+</pre>
+ <p>qhalf s Fp &lt; data </p>
+ <pre>
+
+Halfspace intersection by the convex hull of 6 points in 3-d:
+
+ Number of halfspaces: 6
+ Number of non-redundant halfspaces: 6
+ Number of intersection points: 8
+
+Statistics for: RBOX c | QCONVEX FQ FV n | QHALF s Fp
+
+ Number of points processed: 6
+ Number of hyperplanes created: 11
+ Number of distance tests for qhull: 11
+ Number of merged facets: 1
+ Number of distance tests for merging: 45
+ CPU seconds to compute hull (after input): 0
+
+3
+3
+8
+ -0.5 0.5 0.5
+ 0.5 0.5 0.5
+ -0.5 0.5 -0.5
+ 0.5 0.5 -0.5
+ 0.5 -0.5 0.5
+ -0.5 -0.5 0.5
+ -0.5 -0.5 -0.5
+ 0.5 -0.5 -0.5
+</pre>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="outputs">qhalf outputs</a></h3>
+<blockquote>
+
+<p>The following options control the output for halfspace
+intersection.</p>
+<blockquote>
+<dl compact>
+ <dt>&nbsp;</dt>
+ <dd><b>Intersections</b></dd>
+ <dt><a href="qh-optf.htm#FN">FN</a></dt>
+ <dd>list intersection points for each non-redundant
+ halfspace. The first line
+ is the number of non-redundant halfspaces. Each remaining
+ lines starts with the number of intersection points. For the cube
+ example, each halfspace has four intersection points.</dd>
+ <dt><a href="qh-optf.htm#Fn">Fn</a></dt>
+ <dd>list neighboring intersections for each intersection point. The first line
+ is the number of intersection points. Each remaining line
+ starts with the number of neighboring intersections. For the cube
+ example, each intersection point has three neighboring intersections.
+ <p>
+ In 3-d, a non-simplicial intersection has more than three neighboring
+ intersections. For random data (e.g., the sphere example), non-simplicial intersections are the norm.
+ Option '<a href="qh-optq.htm#Qt">Qt</a>' produces three
+ neighboring intersections per intersection by duplicating the intersection
+ points. Option <a href="qh-optq.htm#QJn">QJ</a>' produces three
+ neighboring intersections per intersection by joggling the hyperplanes and
+ hence their intersections.
+ </dd>
+ <dt><a href="qh-optf.htm#Fp">Fp</a></dt>
+ <dd>print intersection coordinates. The first line is the dimension and the
+ second line is the number of intersection points. The following lines are the
+ coordinates of each intersection.</dd>
+ <dt><a href="qh-optf.htm#FI">FI</a></dt>
+ <dd>list intersection IDs. The first line is the number of
+ intersections. The IDs follow, one per line.</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Halfspaces</b></dd>
+ <dt><a href="qh-optf.htm#Fx">Fx</a></dt>
+ <dd>list non-redundant halfspaces. The first line is the number of
+ non-redundant halfspaces. The other lines list one halfspace per line.
+ A halfspace is <i>non-redundant</i> if it
+ defines a facet of the intersection. Redundant halfspaces are ignored. For
+ the cube example, all of the halfspaces are non-redundant.
+ </dd>
+ <dt><a href="qh-optf.htm#Fv">Fv</a></dt>
+ <dd>list non-redundant halfspaces incident to each intersection point.
+ The first line is the number of
+ non-redundant halfspaces. Each remaining line starts with the number
+ of non-redundant halfspaces. For the
+ cube example, each intersection is incident to three halfspaces.</dd>
+ <dt><a href="qh-opto.htm#i">i</a></dt>
+ <dd>list non-redundant halfspaces incident to each intersection point. The first
+ line is the number of intersection points. Each remaining line
+ lists the incident, non-redundant halfspaces. For the
+ cube example, each intersection is incident to three halfspaces.
+ </dd>
+ <dt><a href="qh-optf.htm#Fc">Fc</a></dt>
+ <dd>list coplanar halfspaces for each intersection point. The first line is
+ the number of intersection points. Each remaining line starts with
+ the number of coplanar halfspaces. A coplanar halfspace is listed for
+ one intersection point even though it is coplanar to multiple intersection
+ points.</dd>
+ <dt><a href="qh-optq.htm#Qc">Qi</a> <a href="qh-optf.htm#Fc">Fc</a></dt>
+ <dd>list redundant halfspaces for each intersection point. The first line is
+ the number of intersection points. Each remaining line starts with
+ the number of redundant halfspaces. Use options '<a href="qh-optq.htm#Qc">Qc</a> Qi Fc' to list
+ coplanar and redundant halfspaces.</dd>
+
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a href="qh-opto.htm#s">s</a></dt>
+ <dd>print summary for the halfspace intersection. Use '<a
+ href="qh-optf.htm#Fs">Fs</a>' if you need numeric data.</dd>
+ <dt><a href="qh-opto.htm#o">o</a></dt>
+ <dd>print vertices and facets of the dual convex hull. The
+ first line is the dimension. The second line is the number of
+ vertices, facets, and ridges. The vertex
+ coordinates are next, followed by the facets, one per line.</dd>
+ <dt><a href="qh-opto.htm#p">p</a></dt>
+ <dd>print vertex coordinates of the dual convex hull. Each vertex corresponds
+ to a non-redundant halfspace. Its coordinates are the negative of the hyperplane's coefficients
+ divided by the offset plus the inner product of the coefficients and
+ the interior point (-c/(b+a.p).
+ Options 'p <a href="qh-optq.htm#Qc">Qc</a>' includes coplanar halfspaces.
+ Options 'p <a href="qh-optq.htm#Qi">Qi</a>' includes redundant halfspaces.</dd>
+ <dt><a href="qh-opto.htm#m">m</a></dt>
+ <dd>Mathematica output for the dual convex hull in 2-d or 3-d.</dd>
+ <dt><a href="qh-optf.htm#FM">FM</a></dt>
+ <dd>Maple output for the dual convex hull in 2-d or 3-d.</dd>
+ <dt><a href="qh-optg.htm#G">G</a></dt>
+ <dd>Geomview output for the dual convex hull in 2-d, 3-d, or 4-d.</dd>
+ </dl>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="controls">qhalf controls</a></h3>
+<blockquote>
+
+<p>These options provide additional control:</p>
+
+<blockquote>
+<dl compact>
+ <dt><a href="qh-optq.htm#Qt">Qt</a></dt>
+ <dd>triangulated output. If a 3-d intersection is defined by more than
+ three hyperplanes, Qhull produces duplicate intersections -- one for
+ each extra hyperplane.</dd>
+ <dt><a href="qh-optq.htm#QJn">QJ</a></dt>
+ <dd>joggle the input instead of merging facets. In 3-d, this guarantees that
+ each intersection is defined by three hyperplanes.</dd>
+ <dt><a href="qh-opto.htm#f">f </a></dt>
+ <dd>facet dump. Print the data structure for each intersection (i.e.,
+ facet)</dd>
+ <dt><a href="qh-optt.htm#TFn">TFn</a></dt>
+ <dd>report summary after constructing <em>n</em>
+ intersections</dd>
+ <dt><a href="qh-optq.htm#QVn">QVn</a></dt>
+ <dd>select intersection points for halfspace <em>n</em>
+ (marked 'good')</dd>
+ <dt><a href="qh-optq.htm#QGn">QGn</a></dt>
+ <dd>select intersection points that are visible to halfspace <em>n</em>
+ (marked 'good'). Use <em>-n</em> for the remainder.</dd>
+ <dt><a href="qh-optq.htm#Qb0">Qbk:0Bk:0</a></dt>
+ <dd>remove the k-th coordinate from the input. This computes the
+ halfspace intersection in one lower dimension.</dd>
+ <dt><a href="qh-optt.htm#Tv">Tv</a></dt>
+ <dd>verify result</dd>
+ <dt><a href="qh-optt.htm#TO">TI file</a></dt>
+ <dd>input data from file. The filename may not use spaces or quotes.</dd>
+ <dt><a href="qh-optt.htm#TO">TO file</a></dt>
+ <dd>output results to file. Use single quotes if the filename
+ contains spaces (e.g., <tt>TO 'file with spaces.txt'</tt></dd>
+ <dt><a href="qh-optq.htm#Qs">Qs</a></dt>
+ <dd>search all points for the initial simplex. If Qhull can
+ not construct an initial simplex, it reports a
+descriptive message. Usually, the point set is degenerate and one
+or more dimensions should be removed ('<a href="qh-optq.htm#Qb0">Qbk:0Bk:0</a>').
+If not, use option 'Qs'. It performs an exhaustive search for the
+best initial simplex. This is expensive is high dimensions.</dd>
+</dl>
+</blockquote>
+
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="graphics">qhalf graphics</a></h3>
+<blockquote>
+
+<p>To view the results with Geomview, compute the convex hull of
+the intersection points ('qhull FQ H0 Fp | qhull G'). See <a
+href="qh-eg.htm#half">Halfspace examples</a>.</p>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="notes">qhalf notes</a></h3>
+<blockquote>
+
+<p>See <a href="qh-impre.htm#halfspace">halfspace intersection</a> for precision issues related to qhalf.</p>
+
+<p>If you do not know an interior point for the halfspaces, use
+linear programming to find one. Assume, <em>n</em> halfspaces
+defined by: <em>aj*x1+bj*x2+cj*x3+dj&lt;=0, j=1..n</em>. Perform
+the following linear program: </p>
+
+<blockquote>
+ <p>max(x5) aj*x1+bj*x2+cj*x3+dj*x4+x5&lt;=0, j=1..n</p>
+</blockquote>
+
+<p>Then, if <em>[x1,x2,x3,x4,x5]</em> is an optimal solution with
+<em>x4&gt;0</em> and <em>x5&gt;0</em> we get: </p>
+
+<blockquote>
+ <p>aj*(x1/x4)+bj*(x2/x4)+cj*(x3/x4)+dj&lt;=(-x5/x4) j=1..n and (-x5/x4)&lt;0,
+ </p>
+</blockquote>
+
+<p>and conclude that the point <em>[x1/x4,x2/x4,x3/x4]</em> is in
+the interior of all the halfspaces. Since <em>x5</em> is
+optimal, this point is &quot;way in&quot; the interior (good
+for precision errors).</p>
+
+<p>After finding an interior point, the rest of the intersection
+algorithm is from Preparata &amp; Shamos [<a
+href="index.htm#pre-sha85">'85</a>, p. 316, &quot;A simple case
+...&quot;]. Translate the halfspaces so that the interior point
+is the origin. Calculate the dual polytope. The dual polytope is
+the convex hull of the vertices dual to the original faces in
+regard to the unit sphere (i.e., halfspaces at distance <em>d</em>
+from the origin are dual to vertices at distance <em>1/d</em>).
+Then calculate the resulting polytope, which is the dual of the
+dual polytope, and translate the origin back to the interior
+point [S. Spitz, S. Teller, D. Strawn].</p>
+
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="conventions">qhalf
+conventions</a></h3>
+<blockquote>
+
+<p>The following terminology is used for halfspace intersection
+in Qhull. This is the hardest structure to understand. The
+underlying structure is a convex hull with one vertex per
+non-redundant halfspace. See <a href="#conventions">convex hull
+conventions</a> and <a href="index.htm#structure">Qhull's data structures</a>.</p>
+
+<ul>
+ <li><em>interior point</em> - a point in the intersection of
+ the halfspaces. Qhull needs an interior point to compute
+ the intersection. See <a href="#input">halfspace input</a>.</li>
+ <li><em>halfspace</em> - <em>d</em> coordinates for the
+ normal and a signed offset. The distance to an interior
+ point is negative.</li>
+ <li><em>non-redundant halfspace</em> - a halfspace that
+ defines an output facet</li>
+ <li><em>vertex</em> - a dual vertex in the convex hull
+ corresponding to a non-redundant halfspace</li>
+ <li><em>coplanar point</em> - the dual point corresponding to
+ a similar halfspace</li>
+ <li><em>interior point</em> - the dual point corresponding to
+ a redundant halfspace</li>
+ <li><em>intersection point</em>- the intersection of <em>d</em>
+ or more non-redundant halfspaces</li>
+ <li><em>facet</em> - a dual facet in the convex hull
+ corresponding to an intersection point</li>
+ <li><em>non-simplicial facet</em> - more than <em>d</em>
+ halfspaces intersect at a point</li>
+ <li><em>good facet</em> - an intersection point that
+ satisfies restriction '<a href="qh-optq.htm#QVn">QVn</a>',
+ etc.</li>
+</ul>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="options">qhalf options</a></h3>
+
+<pre>
+qhalf- compute the intersection of halfspaces about a point
+ http://www.qhull.org
+
+input (stdin):
+ optional interior point: dimension, 1, coordinates
+ first lines: dimension+1 and number of halfspaces
+ other lines: halfspace coefficients followed by offset
+ comments: start with a non-numeric character
+
+options:
+ Hn,n - specify coordinates of interior point
+ Qt - triangulated ouput
+ QJ - joggle input instead of merging facets
+ Qc - keep coplanar halfspaces
+ Qi - keep other redundant halfspaces
+
+Qhull control options:
+ QJn - randomly joggle input in range [-n,n]
+ Qbk:0Bk:0 - remove k-th coordinate from input
+ Qs - search all halfspaces for the initial simplex
+ QGn - print intersection if redundant to halfspace n, -n for not
+ QVn - print intersections for halfspace n, -n if not
+
+Trace options:
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events
+ Tc - check frequently during execution
+ Ts - print statistics
+ Tv - verify result: structure, convexity, and redundancy
+ Tz - send all output to stdout
+ TFn - report summary when n or more facets created
+ TI file - input data from file, no spaces or single quotes
+ TO file - output results to file, may be enclosed in single quotes
+ TPn - turn on tracing when halfspace n added to intersection
+ TMn - turn on tracing at merge n
+ TWn - trace merge facets when width > n
+ TVn - stop qhull after adding halfspace n, -n for before (see TCn)
+ TCn - stop qhull after building cone for halfspace n (see TVn)
+
+Precision options:
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge
+ Rn - randomly perturb computations by a factor of [1-n,1+n]
+ Un - max distance below plane for a new, coplanar halfspace
+ Wn - min facet width for outside halfspace (before roundoff)
+
+Output formats (may be combined; if none, produces a summary to stdout):
+ f - facet dump
+ G - Geomview output (dual convex hull)
+ i - non-redundant halfspaces incident to each intersection
+ m - Mathematica output (dual convex hull)
+ o - OFF format (dual convex hull: dimension, points, and facets)
+ p - vertex coordinates of dual convex hull (coplanars if 'Qc' or 'Qi')
+ s - summary (stderr)
+
+More formats:
+ Fc - count plus redundant halfspaces for each intersection
+ - Qc (default) for coplanar and Qi for other redundant
+ Fd - use cdd format for input (homogeneous with offset first)
+ FF - facet dump without ridges
+ FI - ID of each intersection
+ Fm - merge count for each intersection (511 max)
+ FM - Maple output (dual convex hull)
+ Fn - count plus neighboring intersections for each intersection
+ FN - count plus intersections for each non-redundant halfspace
+ FO - options and precision constants
+ Fp - dim, count, and intersection coordinates
+ FP - nearest halfspace and distance for each redundant halfspace
+ FQ - command used for qhalf
+ Fs - summary: #int (8), dim, #halfspaces, #non-redundant, #intersections
+ for output: #non-redundant, #intersections, #coplanar
+ halfspaces, #non-simplicial intersections
+ #real (2), max outer plane, min vertex
+ Fv - count plus non-redundant halfspaces for each intersection
+ Fx - non-redundant halfspaces
+
+Geomview output (2-d, 3-d and 4-d; dual convex hull)
+ Ga - all points (i.e., transformed halfspaces) as dots
+ Gp - coplanar points and vertices as radii
+ Gv - vertices (i.e., non-redundant halfspaces) as spheres
+ Gi - inner planes (i.e., halfspace intersections) only
+ Gn - no planes
+ Go - outer planes only
+ Gc - centrums
+ Gh - hyperplane intersections
+ Gr - ridges
+ GDn - drop dimension n in 3-d and 4-d output
+
+Print options:
+ PAn - keep n largest facets (i.e., intersections) by area
+ Pdk:n- drop facet if normal[k] &lt;= n (default 0.0)
+ PDk:n- drop facet if normal[k] >= n
+ Pg - print good facets (needs 'QGn' or 'QVn')
+ PFn - keep facets whose area is at least n
+ PG - print neighbors of good facets
+ PMn - keep n facets with most merges
+ Po - force output. If error, output neighborhood of facet
+ Pp - do not report precision problems
+
+ . - list of all options
+ - - one line descriptions of all options
+</pre>
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
+
diff --git a/xs/src/qhull/html/qhull-cpp.xml b/xs/src/qhull/html/qhull-cpp.xml
new file mode 100644
index 000000000..ae755e826
--- /dev/null
+++ b/xs/src/qhull/html/qhull-cpp.xml
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="utf-8"?>
+<?xml-stylesheet type="text/xsl" href="../../road-faq/xsl/road-faq.xsl"?>
+
+<rf:topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://schemas.roadintranet.org/road-faq-1 /road/road-faq/xsl/road-faq.xsd"
+ xmlns:rf="http://schemas.roadintranet.org/road-faq-1"
+ title=" C++ interface to Qhull"
+ file="qhull-cpp.xml"
+ fileid="$Id: //main/2015/qhull/html/qhull-cpp.xml#2 $$Change: 2027 $"
+ fileChange="$DateTime: 2015/11/09 23:18:11 $$Author: bbarber $">
+ <div><h4>Qhull C++ -- C++ interface to Qhull</h4></div>
+ <rf:copyright>
+ <a href="../cpp/COPYING.txt">Copyright</a> (c) 2009-2015, C.B. Barber
+ </rf:copyright>
+ <rf:section id="cpp-cpp-links" title="Useful Links for Qhull C++">
+ <div>
+ <p> This draft
+ document records some of the design decisions for Qhull C++. Convert it to HTML by road-faq.xsl from <a href="http://www.qhull.org/road/road-faq/road-faq.html">road-faq</a>.
+
+ Please send comments and suggestions to <a
+ href="mailto:bradb@shore.net">bradb@shore.net</a>
+ </p>
+ </div>
+ <div class="twocol">
+ <div class="col leftcol">
+ Help
+ <ul><li>
+ </li><li>
+ </li><li>
+ </li></ul>
+ </div>
+ <div class="col rightcol">
+ <ul><li>
+ </li><li>
+ </li></ul>
+ </div>
+ </div>
+ <div>
+ . <!-- clear the two column display -->
+ </div>
+
+ </rf:section>
+ <rf:section id="qhull-api" title="Qhull's collection classes">
+
+ <rf:item id="collection-api" title="API for Qhull collections" date="Feb 2009" author="bbarber">
+ Qhull's collection APIs are modeled on Qt's collection API (QList, QVector, QHash) w/o QT_STRICT_ITERATORS. They support STL and Qt programming.
+
+ <p>Some of Qhull's collection classes derive from STL classes. If so,
+ please avoid additional STL functions and operators added by inheritance.
+ These collection classes may be rewritten to derive from Qt classes instead.
+ See Road's <rf:iref item="cpp-collection-api"/>.
+ </p>
+
+
+ Qhull's collection API (where applicable). For documentation, see Qt's QList, QMap, QListIterator, QMapIterator, QMutableListIterator, and QMutableMapIterator
+ <ul><li>
+ STL types [list, qlinkedlist, qlist, qvector, vector] -- const_iterator, iterator
+ </li><li>
+ STL types describing iterators [list, qlinkedlist, qlist, qvector, vector] -- const_pointer, const_reference, difference_type,
+ pointer, reference, size_type, value_type.
+ Pointer and reference types not defined if unavailable (not needed for &lt;algorithm&gt;)
+ </li><li>
+ const_iterator, iterator types -- difference_type, iterator_category, pointer, reference, value_type
+ </li><li>
+ Qt types [qlinkedlist, qlist, qvector] -- ConstIterator, Iterator, QhullclassIterator, MutableQhullclassIterator.
+ Qt's foreach requires const_iterator.
+ </li><li>
+ Types for sets/maps [hash_map, QHash] -- key_compare, key_type, mapped_type
+ </li><li>
+ Constructor -- default constructor, copy constructor, assignment operator, destructor
+ </li><li>
+ Conversion -- to/from/as corresponding C, STL, and Qt constructs. Include toQList and toStdVector (may be filtered, e.g., QhullFacetSet).
+ Do not define fromStdList and fromQList if container is not reference counted (i.e., acts like a value)
+ </li><li>
+ Get/set -- configuration options for class
+ </li><li>
+ STL-style iterator - begin, constBegin, constEnd, end, key, value, =, *, [], ->, ++, --, +, -, ==, !=, &lt;,
+ &lt;=, &gt;, &gt;=, const_iterator(iterator), iterator COMPARE const_iterator.
+ An iterator is an abstraction of a pointer. It is not aware of its container.
+ </li><li>
+ Java-style iterator [qiterator.h] - countRemaining, findNext, findPrevious, hasNext, hasPrevious, next, peekNext, peekPrevious, previous, toBack, toFront, = Coordinates
+ </li><li>
+ Mutable Java-style iterator adds - insert, remove, setValue, value
+ </li><li>
+ Element access -- back, first, front, last
+ </li><li>
+ Element access w/ index -- [], at (const&amp; only), constData, data, mid, value
+ </li><li>
+ Read-only - (int)count, empty, isEmpty, (size_t)size. Count() and size() may be filtered. If so, they may be zero when !empty().
+ </li><li>
+ Read-only for sets/maps - capacity, key, keys, reserve, resize, values
+ </li><li>
+ Operator - ==, !=, +, +=, &lt;&lt;
+ </li><li>
+ Read-write -- append, clear, erase, insert, move, prepend, pop_back, pop_front, push_back, push_front, removeAll, removeAt, removeFirst, removeLast, replace,
+ swap, takeAt, takeFirst, takeLast
+ </li><li>
+ Read-write for sets/maps -- insertMulti, squeeze, take, unite
+ </li><li>
+ Search -- contains(const T &amp;), count(const T &amp;), indexOf, lastIndexOf
+ </li><li>
+ Search for sets/maps -- constFind, lowerBound, upperBound
+ </li><li>
+ Stream I/O -- stream &lt;&lt;
+ </li></ul>
+
+ STL list and vector -- For unfiltered access to each element.
+ <ul><li>
+ <a href="http://stdcxx.apache.org/doc/stdlibug/16-3.html">Apache: Creating your own containers</a> -- requirements for STL containers. Iterators should define the types from 'iterator_traits'.
+ </li><li>
+ STL types -- allocator_type, const_iterator, const_pointer, const_reference, const_reverse_iterator, difference_type, iterator, iterator_category, pointer, reference, reverse_iterator, size_type, value_type
+ </li><li>
+ STL constructors -- MyType(), MyType(count), MyType(count, value), MyType(first, last),
+ MyType(MyType&amp;),
+ </li><li>
+ STL getter/setters -- at (random_access only), back, begin, capacity, end, front, rbegin, rend, size, max_size
+ </li><li>
+ STL predicates -- empty
+ </li><li>
+ STL iterator types -- const_pointer, const_reference, difference_type, iterator_category, pointer, reference, value_type
+ </li><li>
+ STL iterator operators -- *, -&lt;, ++, --, +=, -=, +, -, [], ==, !=, &lt;, &gt;, &gt;=, &lt;=
+ </li><li>
+ STL operators -- =, [] (random_access only), ==, !=, &lt;, &gt;, &lt;=, &gt;=
+ </li><li>
+ STL modifiers -- assign, clear, erase, insert, pop_back, push_back, reserve, resize, swap
+ </li><li>
+ </li></ul>
+
+ Qt Qlist -- For unfiltered access to each element
+ <ul><li>
+ </li><li>
+ Additional Qt types -- ConstIterator, Iterator, QListIterator, QMutableListIterator
+ </li><li>
+ Additional Qt get/set -- constBegin, constEnd, count, first, last, value (random_access only)
+ </li><li>
+ Additional Qt predicates -- isEmpty
+ </li><li>
+ Additional Qt -- mid (random_access only)
+ </li><li>
+ Additional Qt search -- contains, count(T&amp;), indexOf (random_access only), lastIndeOf (random_access only)
+ </li><li>
+ Additional Qt modifiers -- append, insert(index,value) (random_access only), move (random_access only), pop_front, prepend, push_front, removeAll, removeAt (random_access only), removeFirst, removeLast, replace, swap by index, takeAt, takeFirst, takeLast
+ </li><li>
+ Additional Qt operators -- +, &lt;&lt;, +=,
+ stream &lt;&lt; and &gt;&gt;
+ </li><li>
+ Unsupported types by Qt -- allocator_type, const_reverse_iterator, reverse_iterator
+ </li><li>
+ Unsupported accessors by Qt -- max_size, rbegin, rend
+ </li><li>
+ Unsupported constructors by Qt -- multi-value constructors
+ </li><li>
+ unsupported modifiers by Qt -- assign, muli-value inserts, STL's swaps
+ </li><li>
+ </li></ul>
+
+ STL map and Qt QMap. These use nearly the same API as list and vector classes. They add the following.
+ <ul><li>
+ STL types -- key_compare, key_type, mapped_type
+ </li><li>
+ STL search -- equal_range, find, lower_bound, upper_bound
+ </li><li>
+ Qt removes -- equal_range, key_compare
+ </li><li>
+ Qt renames -- lowerBound, upperBound
+ </li><li>
+ Qt adds -- constFind, insertMulti, key, keys, take, uniqueKeys, unite, values
+ </li><li>
+ Not applicable to map and QMap -- at, back, pop_back, pop_front, push_back, push_front, swap
+ </li><li>
+ Not applicable to QMap -- append, first, last, lastIndexOf, mid, move, prepend, removeAll, removeAt, removeFirst, removeLast, replace, squeeze, takeAt, takeFirst, takeLast
+ </li><li>
+ Not applicable to map -- assign
+ </li></ul>
+
+ Qt QHash. STL extensions provide similar classes, e.g., Microsoft's stdext::hash_set. THey are nearly the same as QMap
+ <ul><li>
+ </li><li>
+ </li><li>
+ Not applicable to Qhash -- lowerBound, unite, upperBound,
+ </li><li>
+ Qt adds -- squeeze
+ </li></ul>
+ </rf:item>
+ <rf:item id="class-api" title="API for Qhull collections" date="Feb 2009" author="bbarber">
+ <ul><li>
+ check... -- Throw error on failure
+ </li><li>
+ try... -- Return false on failure. Do not throw errors.
+ </li><li>
+ ...Temporarily -- lifetime depends on source. e.g., toByteArrayTemporarily
+ </li><li>
+ ...p -- indicates pointer-to.
+ </li><li>
+ end... -- points to one beyond the last available
+ </li><li>
+ private functions -- No syntactic indication. They may become public later on.
+ </li><li>
+ Error messages -- Preceed error messages with the name of the class throwing the error (e.g. "ClassName: ..."). If this is an internal error, use "ClassName inconsistent: ..."
+ </li><li>
+ parameter order -- qhRunId, dimension, coordinates, count.
+ </li><li>
+ toClass -- Convert into a Class object (makes a deep copy)
+ </li><li>
+ qRunId -- Requires Qh installed. Some routines allow 0 for limited info (e.g., operator&lt;&lt;)
+ </li><li>
+ Disable methods in derived classes -- If the default constructor, copy constructor, or copy assignment is disabled, it should be also disabled in derived classes (better error messages).
+ </li><li>
+ Constructor order -- default constructor, other constructors, copy constructor, copy assignment, destructor
+ </li></ul>
+ </rf:item>
+ </rf:section>
+</rf:topic>
diff --git a/xs/src/qhull/html/qhull.htm b/xs/src/qhull/html/qhull.htm
new file mode 100644
index 000000000..0a2aa75e0
--- /dev/null
+++ b/xs/src/qhull/html/qhull.htm
@@ -0,0 +1,473 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>qhull -- convex hull and related structures</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><b><a name="TOP">Up</a></b><b>:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis &#149; <a href="#input">in</a>put
+&#149; <a href="#outputs">ou</a>tputs &#149; <a href="#controls">co</a>ntrols
+&#149; <a href="#options">op</a>tions
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/cone.html"><img
+src="qh--cone.gif" alt="[cone]" align="middle" width="100"
+height="100"></a>qhull -- convex hull and related structures</h1>
+
+<p>The convex hull of a set of points is the smallest convex set
+containing the points. The Delaunay triangulation and furthest-site
+Delaunay triangulation are equivalent to a convex hull in one
+higher dimension. Halfspace intersection about a point is
+equivalent to a convex hull by polar duality.
+
+<p>The <tt>qhull</tt> program provides options to build these
+structures and to experiment with the process. Use the
+<a href=qconvex.htm>qconvex</a>,
+<a href=qdelaun.htm>qdelaunay</a>, <a href=qhalf.htm>qhalf</a>,
+and <a href=qvoronoi.htm>qvoronoi</a> programs
+to build specific structures. You may use <tt>qhull</tt> instead.
+It takes the same options and uses the same code.
+<blockquote>
+<dl>
+ <dt><b>Example:</b> rbox 1000 D3 | qhull
+ <a href="qh-optc.htm#Cn">C-1e-4</a>
+ <a href="qh-optf.htm#FO">FO</a>
+ <a href="qh-optt.htm#Ts">Ts</a>
+ </dt>
+ <dd>Compute the 3-d convex hull of 1000 random
+ points.
+ Centrums must be 10^-4 below neighboring
+ hyperplanes. Print the options and precision constants.
+ When done, print statistics. These options may be
+ used with any of the Qhull programs.</dd>
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox 1000 D3 | qhull <a href=qhull.htm#outputs>d</a>
+ <a href="qh-optq.htm#Qbb">Qbb</a>
+ <a href="qh-optc.htm#Rn">R1e-4</a>
+ <a href="qh-optq.htm#Q0">Q0</a></dt>
+ <dd>Compute the 3-d Delaunay triangulation of 1000 random
+ points. Randomly perturb all calculations by
+ [0.9999,1.0001]. Do not correct precision problems.
+ This leads to serious precision errors.</dd>
+</dl>
+</blockquote>
+<p>Use the following equivalences when calling <tt>qhull</tt> in 2-d to 4-d (a 3-d
+Delaunay triangulation is a 4-d convex hull):
+<blockquote>
+<ul>
+<li>
+<a href="qconvex.htm">qconvex</a> == qhull
+<li>
+<a href=qdelaun.htm>qdelaunay</a> == qhull d <a href="qh-optq.htm#Qbb">Qbb</a>
+<li>
+<a href=qhalf.htm>qhalf</a> == qhull H
+<li>
+<a href=qvoronoi.htm>qvoronoi</a> == qhull v <a href="qh-optq.htm#Qbb">Qbb</a>
+</ul>
+</blockquote>
+
+<p>Use the following equivalences when calling <tt>qhull</tt> in 5-d and higher (a 4-d
+Delaunay triangulation is a 5-d convex hull):
+<blockquote>
+<ul>
+<li>
+<a href="qconvex.htm">qconvex</a> == qhull <a href="qh-optq.htm#Qx">Qx</a>
+<li>
+<a href=qdelaun.htm>qdelaunay</a> == qhull d <a href="qh-optq.htm#Qbb">Qbb</a> <a href="qh-optq.htm#Qx">Qx</a>
+<li>
+<a href=qhalf.htm>qhalf</a> == qhull H <a href="qh-optq.htm#Qx">Qx</a>
+<li>
+<a href=qvoronoi.htm>qvoronoi</a> == qhull v <a href="qh-optq.htm#Qbb">Qbb</a> <a href="qh-optq.htm#Qx">Qx</a>
+</ul>
+</blockquote>
+
+
+<p>By default, Qhull merges coplanar facets. For example, the convex
+hull of a cube's vertices has six facets.
+
+<p>If you use '<a href="qh-optq.htm#Qt">Qt</a>' (triangulated output),
+all facets will be simplicial (e.g., triangles in 2-d). For the cube
+example, it will have 12 facets. Some facets may be
+degenerate and have zero area.
+
+<p>If you use '<a href="qh-optq.htm#QJn">QJ</a>' (joggled input),
+all facets will be simplicial. The corresponding vertices will be
+slightly perturbed. Joggled input is less accurate that triangulated
+output.See <a
+href="qh-impre.htm#joggle">Merged facets or joggled input</a>. </p>
+
+<p>The output for 4-d convex hulls may be confusing if the convex
+hull contains non-simplicial facets (e.g., a hypercube). See
+<a href=qh-faq.htm#extra>Why
+are there extra points in a 4-d or higher convex hull?</a><br>
+</p>
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+
+<h3><a href="#TOP">&#187;</a><a name="synopsis">qhull synopsis</a></h3>
+<pre>
+qhull- compute convex hulls and related structures.
+ input (stdin): dimension, n, point coordinates
+ comments start with a non-numeric character
+ halfspace: use dim+1 and put offsets after coefficients
+
+options (qh-quick.htm):
+ d - Delaunay triangulation by lifting points to a paraboloid
+ d Qu - furthest-site Delaunay triangulation (upper convex hull)
+ v - Voronoi diagram as the dual of the Delaunay triangulation
+ v Qu - furthest-site Voronoi diagram
+ H1,1 - Halfspace intersection about [1,1,0,...] via polar duality
+ Qt - triangulated output
+ QJ - joggle input instead of merging facets
+ Tv - verify result: structure, convexity, and point inclusion
+ . - concise list of all options
+ - - one-line description of all options
+
+Output options (subset):
+ s - summary of results (default)
+ i - vertices incident to each facet
+ n - normals with offsets
+ p - vertex coordinates (if 'Qc', includes coplanar points)
+ if 'v', Voronoi vertices
+ Fp - halfspace intersections
+ Fx - extreme points (convex hull vertices)
+ FA - compute total area and volume
+ o - OFF format (if 'v', outputs Voronoi regions)
+ G - Geomview output (2-d, 3-d and 4-d)
+ m - Mathematica output (2-d and 3-d)
+ QVn - print facets that include point n, -n if not
+ TO file- output results to file, may be enclosed in single quotes
+
+examples:
+ rbox c d D2 | qhull Qc s f Fx | more rbox 1000 s | qhull Tv s FA
+ rbox 10 D2 | qhull d QJ s i TO result rbox 10 D2 | qhull v Qbb Qt p
+ rbox 10 D2 | qhull d Qu QJ m rbox 10 D2 | qhull v Qu QJ o
+ rbox c | qhull n rbox c | qhull FV n | qhull H Fp
+ rbox d D12 | qhull QR0 FA rbox c D7 | qhull FA TF1000
+ rbox y 1000 W0 | qhull rbox 10 | qhull v QJ o Fv
+</pre>
+
+<h3><a href="#TOP">&#187;</a><a name="input">qhull input</a></h3>
+<blockquote>
+
+<p>The input data on <tt>stdin</tt> consists of:</p>
+<ul>
+ <li>dimension
+ <li>number of points</li>
+ <li>point coordinates</li>
+</ul>
+
+<p>Use I/O redirection (e.g., qhull &lt; data.txt), a pipe (e.g., rbox 10 | qhull),
+or the '<a href=qh-optt.htm#TI>TI</a>' option (e.g., qhull TI data.txt).
+
+<p>Comments start with a non-numeric character. Error reporting is
+simpler if there is one point per line. Dimension
+and number of points may be reversed. For halfspace intersection,
+an interior point may be prepended (see <a href=qhalf.htm#input>qhalf input</a>).
+
+<p>Here is the input for computing the convex
+hull of the unit cube. The output is the normals, one
+per facet.</p>
+
+<blockquote>
+ <p>rbox c &gt; data </p>
+ <pre>
+3 RBOX c
+8
+ -0.5 -0.5 -0.5
+ -0.5 -0.5 0.5
+ -0.5 0.5 -0.5
+ -0.5 0.5 0.5
+ 0.5 -0.5 -0.5
+ 0.5 -0.5 0.5
+ 0.5 0.5 -0.5
+ 0.5 0.5 0.5
+</pre>
+ <p>qhull s n &lt; data</p>
+ <pre>
+
+Convex hull of 8 points in 3-d:
+
+ Number of vertices: 8
+ Number of facets: 6
+ Number of non-simplicial facets: 6
+
+Statistics for: RBOX c | QHULL s n
+
+ Number of points processed: 8
+ Number of hyperplanes created: 11
+ Number of distance tests for qhull: 35
+ Number of merged facets: 6
+ Number of distance tests for merging: 84
+ CPU seconds to compute hull (after input): 0.081
+
+4
+6
+ 0 0 -1 -0.5
+ 0 -1 0 -0.5
+ 1 0 0 -0.5
+ -1 0 0 -0.5
+ 0 1 0 -0.5
+ 0 0 1 -0.5
+</pre>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="outputs">qhull outputs</a></h3>
+<blockquote>
+
+<p>These options control the output of qhull. They may be used
+individually or together.</p>
+<blockquote>
+<dl compact>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a>qhull</a></dt>
+ <dd>compute the convex hull of the input points.
+ See <a href=qconvex.htm>qconvex</a>.</dd>
+ <dt><a name="d">qhull d Qbb</a></dt>
+ <dd>compute the Delaunay triangulation by lifting the points
+ to a paraboloid. Use option '<a href="qh-optq.htm#Qbb">Qbb</a>'
+ to scale the paraboloid and improve numeric precision.
+ See <a href=qdelaun.htm>qdelaunay</a>.</dd>
+ <dt><a name="v">qhull v Qbb</a></dt>
+ <dd>compute the Voronoi diagram by computing the Delaunay
+ triangulation. Use option '<a href="qh-optq.htm#Qbb">Qbb</a>'
+ to scale the paraboloid and improve numeric precision.
+ See <a href=qvoronoi.htm>qvoronoi</a>.</dd>
+ <dt><a name="H">qhull H</a></dt>
+ <dd>compute the halfspace intersection about a point via polar
+ duality. The point is below the hyperplane that defines the halfspace.
+ See <a href=qhalf.htm>qhalf</a>.</dd>
+</dl>
+</blockquote>
+
+<p>For a full list of output options see
+<blockquote>
+<ul>
+ <li><a href="qh-opto.htm#output">Output</a> formats</li>
+ <li><a href="qh-optf.htm#format">Additional</a> I/O
+ formats</li>
+ <li><a href="qh-optg.htm#geomview">Geomview</a>
+ output options</li>
+ <li><a href="qh-optp.htm#print">Print</a> options</li>
+</ul>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="controls">qhull controls</a></h3>
+<blockquote>
+
+<p>For a full list of control options see
+<blockquote>
+<ul>
+ <li><a href="qh-optq.htm#qhull">Qhull</a> control
+ options</li>
+ <li><a href="qh-optc.htm#prec">Precision</a> options</li>
+ <li><a href="qh-optt.htm#trace">Trace</a> options</li>
+</ul>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="options">qhull options</a></h3>
+
+<pre>
+qhull- compute convex hulls and related structures.
+ http://www.qhull.org
+
+input (stdin):
+ first lines: dimension and number of points (or vice-versa).
+ other lines: point coordinates, best if one point per line
+ comments: start with a non-numeric character
+ halfspaces: use dim plus one and put offset after coefficients.
+ May be preceded by a single interior point ('H').
+
+options:
+ d - Delaunay triangulation by lifting points to a paraboloid
+ d Qu - furthest-site Delaunay triangulation (upper convex hull)
+ v - Voronoi diagram (dual of the Delaunay triangulation)
+ v Qu - furthest-site Voronoi diagram
+ Hn,n,... - halfspace intersection about point [n,n,0,...]
+ Qt - triangulated output
+ QJ - joggle input instead of merging facets
+ Qc - keep coplanar points with nearest facet
+ Qi - keep interior points with nearest facet
+
+Qhull control options:
+ Qbk:n - scale coord k so that low bound is n
+ QBk:n - scale coord k so that upper bound is n (QBk is 0.5)
+ QbB - scale input to unit cube centered at the origin
+ Qbb - scale last coordinate to [0,m] for Delaunay triangulations
+ Qbk:0Bk:0 - remove k-th coordinate from input
+ QJn - randomly joggle input in range [-n,n]
+ QRn - random rotation (n=seed, n=0 time, n=-1 time/no rotate)
+ Qf - partition point to furthest outside facet
+ Qg - only build good facets (needs 'QGn', 'QVn', or 'PdD')
+ Qm - only process points that would increase max_outside
+ Qr - process random outside points instead of furthest ones
+ Qs - search all points for the initial simplex
+ Qu - for 'd' or 'v', compute upper hull without point at-infinity
+ returns furthest-site Delaunay triangulation
+ Qv - test vertex neighbors for convexity
+ Qx - exact pre-merges (skips coplanar and anglomaniacs facets)
+ Qz - add point-at-infinity to Delaunay triangulation
+ QGn - good facet if visible from point n, -n for not visible
+ QVn - good facet if it includes point n, -n if not
+ Q0 - turn off default p remerge with 'C-0'/'Qx'
+ Q1 - sort merges by type instead of angle
+ Q2 - merge all non-convex at once instead of independent sets
+ Q3 - do not merge redundant vertices
+ Q4 - avoid old>new merges
+ Q5 - do not correct outer planes at end of qhull
+ Q6 - do not pre-merge concave or coplanar facets
+ Q7 - depth-first processing instead of breadth-first
+ Q8 - do not process near-inside points
+ Q9 - process furthest of furthest points
+ Q10 - no special processing for narrow distributions
+ Q11 - copy normals and recompute centrums for tricoplanar facets
+ Q12 - do not error on wide merge due to duplicate ridge and nearly coincident points
+
+Towpaths Trace options:
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events
+ Tc - check frequently during execution
+ Ts - print statistics
+ Tv - verify result: structure, convexity, and point inclusion
+ Tz - send all output to stdout
+ TFn - report summary when n or more facets created
+ TI file - input data from file, no spaces or single quotes
+ TO file - output results to file, may be enclosed in single quotes
+ TPn - turn on tracing when point n added to hull
+ TMn - turn on tracing at merge n
+ TWn - trace merge facets when width > n
+ TRn - rerun qhull n times. Use with 'QJn'
+ TVn - stop qhull after adding point n, -n for before (see TCn)
+ TCn - stop qhull after building cone for point n (see TVn)
+
+Precision options:
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge
+ En - max roundoff error for distance computation
+ Rn - randomly perturb computations by a factor of [1-n,1+n]
+ Vn - min distance above plane for a visible facet (default 3C-n or En)
+ Un - max distance below plane for a new, coplanar point (default Vn)
+ Wn - min facet width for outside point (before roundoff, default 2Vn)
+
+Output formats (may be combined; if none, produces a summary to stdout):
+ f - facet dump
+ G - Geomview output (see below)
+ i - vertices incident to each facet
+ m - Mathematica output (2-d and 3-d)
+ o - OFF format (dim, points and facets; Voronoi regions)
+ n - normals with offsets
+ p - vertex coordinates or Voronoi vertices (coplanar points if 'Qc')
+ s - summary (stderr)
+
+More formats:
+ Fa - area for each facet
+ FA - compute total area and volume for option 's'
+ Fc - count plus coplanar points for each facet
+ use 'Qc' (default) for coplanar and 'Qi' for interior
+ FC - centrum or Voronoi center for each facet
+ Fd - use cdd format for input (homogeneous with offset first)
+ FD - use cdd format for numeric output (offset first)
+ FF - facet dump without ridges
+ Fi - inner plane for each facet
+ for 'v', separating hyperplanes for bounded Voronoi regions
+ FI - ID of each facet
+ Fm - merge count for each facet (511 max)
+ FM - Maple output (2-d and 3-d)
+ Fn - count plus neighboring facets for each facet
+ FN - count plus neighboring facets for each point
+ Fo - outer plane (or max_outside) for each facet
+ for 'v', separating hyperplanes for unbounded Voronoi regions
+ FO - options and precision constants
+ Fp - dim, count, and intersection coordinates (halfspace only)
+ FP - nearest vertex and distance for each coplanar point
+ FQ - command used for qhull
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,
+ output: #vertices, #facets, #coplanars, #nonsimplicial
+ #real (2), max outer plane, min vertex
+ FS - sizes: #int (0)
+ #real(2) tot area, tot volume
+ Ft - triangulation with centrums for non-simplicial facets (OFF format)
+ Fv - count plus vertices for each facet
+ for 'v', Voronoi diagram as Voronoi vertices for pairs of sites
+ FV - average of vertices (a feasible point for 'H')
+ Fx - extreme points (in order for 2-d)
+
+Geomview options (2-d, 3-d, and 4-d; 2-d Voronoi)
+ Ga - all points as dots
+ Gp - coplanar points and vertices as radii
+ Gv - vertices as spheres
+ Gi - inner planes only
+ Gn - no planes
+ Go - outer planes only
+ Gc - centrums
+ Gh - hyperplane intersections
+ Gr - ridges
+ GDn - drop dimension n in 3-d and 4-d output
+ Gt - for 3-d 'd', transparent outer ridges
+
+Print options:
+ PAn - keep n largest facets by area
+ Pdk:n - drop facet if normal[k] &lt;= n (default 0.0)
+ PDk:n - drop facet if normal[k] >= n
+ Pg - print good facets (needs 'QGn' or 'QVn')
+ PFn - keep facets whose area is at least n
+ PG - print neighbors of good facets
+ PMn - keep n facets with most merges
+ Po - force output. If error, output neighborhood of facet
+ Pp - do not report precision problems
+
+ . - list of all options
+ - - one line descriptions of all options
+</pre>
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis &#149; <a href="#input">in</a>put
+&#149; <a href="#outputs">ou</a>tputs &#149; <a href="#controls">co</a>ntrols
+&#149; <a href="#options">op</a>tions
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qhull.man b/xs/src/qhull/html/qhull.man
new file mode 100644
index 000000000..8d1dc08ac
--- /dev/null
+++ b/xs/src/qhull/html/qhull.man
@@ -0,0 +1,1008 @@
+.\" This is the Unix manual page for qhull, written in nroff, the standard
+.\" manual formatter for Unix systems. To format it, type
+.\"
+.\" nroff -man qhull.man
+.\"
+.\" This will print a formatted copy to standard output. If you want
+.\" to ensure that the output is plain ASCII, free of any control
+.\" characters that nroff uses for underlining etc, pipe the output
+.\" through "col -b":
+.\"
+.\" nroff -man qhull.man | col -b
+.\"
+.\" Warning: a leading quote "'" or dot "." will not format correctly
+.\"
+.TH qhull 1 "2003/12/30" "Geometry Center"
+.SH NAME
+qhull \- convex hull, Delaunay triangulation, Voronoi diagram,
+halfspace intersection about a point, hull volume, facet area
+.SH SYNOPSIS
+.nf
+qhull- compute convex hulls and related structures
+ input (stdin): dimension, #points, point coordinates
+ first comment (non-numeric) is listed in the summary
+ halfspace: use dim plus one with offsets after coefficients
+
+options (qh-quick.htm):
+ d - Delaunay triangulation by lifting points to a paraboloid
+ v - Voronoi diagram via the Delaunay triangulation
+ H1,1 - Halfspace intersection about [1,1,0,...]
+ d Qu - Furthest-site Delaunay triangulation (upper convex hull)
+ v Qu - Furthest-site Voronoi diagram
+ Qt - triangulated output
+ QJ - Joggle the input to avoid precision problems
+ . - concise list of all options
+ - - one-line description of all options
+
+Output options (subset):
+ FA - compute total area and volume
+ Fx - extreme points (convex hull vertices)
+ G - Geomview output (2-d, 3-d and 4-d)
+ Fp - halfspace intersection coordinates
+ m - Mathematica output (2-d and 3-d)
+ n - normals with offsets
+ o - OFF file format (if Voronoi, outputs regions)
+ TO file- output results to file, may be enclosed in single quotes
+ f - print all fields of all facets
+ s - summary of results (default)
+ Tv - verify result: structure, convexity, and point inclusion
+ p - vertex coordinates (centers for Voronoi)
+ i - vertices incident to each facet
+
+example:
+ rbox 1000 s | qhull Tv s FA
+.fi
+
+ - html manual: index.htm
+ - installation: README.txt
+ - see also: COPYING.txt, REGISTER.txt, Changes.txt
+ - WWW: <http://www.qhull.org>
+ - GIT: <git@github.com:qhull/qhull.git>
+ - mirror: <http://www6.uniovi.es/ftp/pub/mirrors/geom.umn.edu/software/ghindex.html>
+ - news: <http://www.qhull.org/news>
+ - Geomview: <http://www.geomview.org>
+ - news group: <news:comp.graphics.algorithms>
+ - FAQ: <http://www.faqs.org/faqs/graphics/algorithms-faq/>
+ - email: qhull@qhull.org
+ - bug reports: qhull_bug@qhull.org
+
+The sections are:
+ - INTRODUCTION
+ - DESCRIPTION, a description of Qhull
+ - IMPRECISION, how Qhull handles imprecision
+ - OPTIONS
+ - Input and output options
+ - Additional input/output formats
+ - Precision options
+ - Geomview options
+ - Print options
+ - Qhull options
+ - Trace options
+ - BUGS
+ - E-MAIL
+ - SEE ALSO
+ - AUTHORS
+ - ACKNOWLEGEMENTS
+
+This man page briefly describes all Qhull options. Please report
+any mismatches with Qhull's html manual (index.htm).
+
+.PP
+.SH INTRODUCTION
+Qhull is a general dimension code for computing convex hulls, Delaunay
+triangulations, Voronoi diagram, furthest\[hy]site Voronoi diagram,
+furthest\[hy]site Delaunay triangulations, and
+halfspace intersections about a point. It implements the Quickhull algorithm for
+computing the convex hull. Qhull handles round\[hy]off errors from floating
+point arithmetic. It can approximate a convex hull.
+
+The program includes options for hull volume, facet area, partial hulls,
+input transformations, randomization, tracing, multiple output formats, and
+execution statistics. The program can be called from within your application.
+You can view the results in 2\[hy]d, 3\[hy]d and 4\[hy]d with Geomview.
+.PP
+.SH DESCRIPTION
+.PP
+The format of input is the following: first line contains the dimension,
+second line contains the number of input points, and point coordinates follow.
+The dimension and number of points can be reversed.
+Comments and line breaks are ignored. A comment starts with a
+non\[hy]numeric character and continues to the end of line. The first comment
+is reported in summaries and statistics.
+Error reporting is
+better if there is one point per line.
+.PP
+The default printout option is a short summary. There are many
+other output formats.
+.PP
+Qhull implements the Quickhull algorithm for convex hull. This algorithm combines
+the 2\[hy]d Quickhull algorithm with the n\[hy]d beneath\[hy]beyond algorithm
+[c.f., Preparata & Shamos '85].
+It is similar to the randomized algorithms of Clarkson and
+others [Clarkson et al. '93]. The main
+advantages of Quickhull are output sensitive performance, reduced
+space requirements, and automatic handling of precision problems.
+.PP
+The data structure produced by Qhull consists of vertices, ridges, and facets.
+A vertex is a point of the input set. A ridge is a set of d vertices
+and two neighboring facets. For example in 3\[hy]d, a ridge is an edge of the
+polyhedron. A facet is a set of ridges, a set of neighboring facets, a set
+of incident vertices, and a hyperplane equation. For simplicial facets, the
+ridges are defined by the vertices and neighboring facets. When Qhull
+merges two facets, it produces a non\[hy]simplicial
+facet. A non\[hy]simplicial facet has more than d neighbors and may share more than
+one ridge with a neighbor.
+.PP
+.SH IMPRECISION
+.PP
+Since Qhull uses floating point arithmetic, roundoff error may occur for each
+calculation. This causes problems
+for most geometric algorithms.
+.PP
+Qhull automatically sets option 'C\-0' in 2\[hy]d, 3\[hy]d, and 4\[hy]d, or
+option 'Qx' in 5\[hy]d and higher. These options handle precision problems
+by merging facets. Alternatively, use option 'QJ' to joggle the
+input.
+.PP
+With 'C\-0', Qhull merges non\[hy]convex
+facets while constructing the hull. The remaining facets are
+clearly convex. With 'Qx', Qhull merges
+coplanar horizon facets, flipped facets, concave facets and
+duplicated ridges. It merges coplanar facets after constructing
+the hull.
+With 'Qx', coplanar points may be missed, but it
+appears to be unlikely.
+.PP
+To guarantee triangular output, joggle the input with option 'QJ'. Facet
+merging will not occur.
+.SH OPTIONS
+.PP
+To get a list of the most important options, execute 'qhull' by itself.
+To get a complete list of options,
+execute 'qhull \-'.
+To get a complete, concise list of options, execute 'qhull .'.
+
+Options can be in any order.
+Capitalized options take an argument (except 'PG' and 'F' options).
+Single letters are used for output formats and precision constants. The
+other options are grouped into menus for other output formats ('F'),
+Geomview output ('G'),
+printing ('P'), Qhull control ('Q'), and tracing ('T').
+.TP
+Main options:
+.TP
+default
+Compute the convex hull of the input points. Report a summary of
+the result.
+.TP
+d
+Compute the Delaunay triangulation by lifting the input points to a
+paraboloid. The 'o' option prints the input points and facets.
+The 'QJ' option guarantees triangular output. The 'Ft'
+option prints a triangulation. It adds points (the centrums) to non\[hy]simplicial
+facets.
+.TP
+v
+Compute the Voronoi diagram from the Delaunay triangulation.
+The 'p' option prints the Voronoi vertices.
+The 'o' option prints the Voronoi vertices and the
+vertices in each Voronoi region. It lists regions in
+site ID order.
+The 'Fv' option prints each ridge of the Voronoi diagram.
+The first or zero'th vertex
+indicates the infinity vertex. Its coordinates are
+qh_INFINITE (\-10.101). It indicates unbounded Voronoi
+regions or degenerate Delaunay triangles.
+.TP
+Hn,n,...
+Compute halfspace intersection about [n,n,0,...].
+The input is a set of halfspaces
+defined in the same format as 'n', 'Fo', and 'Fi'.
+Use 'Fp' to print the intersection points. Use 'Fv'
+to list the intersection points for each halfspace. The
+other output formats display the dual convex hull.
+
+The point [n,n,n,...] is a feasible point for the halfspaces, i.e.,
+a point that is inside all
+of the halfspaces (Hx+b <= 0). The default coordinate value is 0.
+
+The input may start with a feasible point. If so, use 'H' by itself.
+The input starts with a feasible point when the first number is the dimension,
+the second number is "1", and the coordinates complete a line. The 'FV'
+option produces a feasible point for a convex hull.
+.TP
+d Qu
+Compute the furthest\[hy]site Delaunay triangulation from the upper
+convex hull. The 'o' option prints the input points and facets.
+The 'QJ' option guarantees triangular otuput. You can also use 'Ft'
+to triangulate via the centrums of non\[hy]simplicial
+facets.
+.TP
+v Qu
+Compute the furthest\[hy]site Voronoi diagram.
+The 'p' option prints the Voronoi vertices.
+The 'o' option prints the Voronoi vertices and the
+vertices in each Voronoi region.
+The 'Fv' option prints each ridge of the Voronoi diagram.
+The first or zero'th vertex
+indicates the infinity vertex at infinity. Its coordinates are
+qh_INFINITE (\-10.101). It indicates unbounded Voronoi regions
+and degenerate Delaunay triangles.
+.PP
+.TP
+Input/Output options:
+.TP
+f
+Print out all facets and all fields of each facet.
+.TP
+G
+Output the hull in Geomview format. For imprecise hulls,
+Geomview displays the inner and outer hull. Geomview can also
+display points, ridges, vertices, coplanar points, and
+facet intersections. See below for a list of options.
+
+For Delaunay triangulations, 'G' displays the
+corresponding paraboloid. For halfspace intersection, 'G' displays the
+dual polytope.
+.TP
+i
+Output the incident vertices for each facet.
+Qhull prints the number of facets followed by the
+vertices of each facet. One facet is printed per line. The numbers
+are the 0\[hy]relative indices of the corresponding input points.
+The facets
+are oriented.
+
+In 4d and higher,
+Qhull triangulates non\[hy]simplicial facets. Each apex (the first vertex) is
+a created point that corresponds to the facet's centrum. Its index is greater
+than the indices of the input points. Each base
+corresponds to a simplicial ridge between two facets.
+To print the vertices without triangulation, use option 'Fv'.
+.TP
+m
+Output the hull in Mathematica format. Qhull writes a Mathematica file for 2\[hy]d and 3\[hy]d
+convex hulls and for 2\[hy]d Delaunay triangulations. Qhull produces a list of objects
+that you can assign to a variable in Mathematica, for example:
+"list= << <outputfilename> ". If the object is 2\[hy]d, it can be
+visualized by "Show[Graphics[list]] ". For 3\[hy]d objects the command is
+"Show[Graphics3D[list]]".
+.TP
+n
+Output the normal equation for each facet.
+Qhull prints the dimension (plus one), the number of facets,
+and the normals for each facet. The facet's offset follows its
+normal coefficients.
+.TP
+o
+Output the facets in OFF file format.
+Qhull prints the dimension, number of points, number
+of facets, and number of ridges. Then it prints the coordinates of
+the input points and the vertices for each facet. Each facet is on
+a separate line. The first number is the number of vertices. The
+remainder are the indices of the corresponding points. The vertices are
+oriented in 2\[hy]d, 3\[hy]d, and in simplicial facets.
+
+For 2\[hy]d Voronoi diagrams,
+the vertices are sorted by adjacency, but not oriented. In 3\[hy]d and higher,
+the Voronoi vertices are sorted by index.
+See the 'v' option for more information.
+.TP
+p
+Output the coordinates of each vertex point.
+Qhull prints the dimension, the number of points,
+and the coordinates for each vertex.
+With the 'Gc' and 'Gi' options, it also prints coplanar
+and interior points. For Voronoi diagrams, it prints the coordinates
+of each Voronoi vertex.
+.TP
+s
+Print a summary to stderr. If no output options
+are specified at all, a summary goes to stdout. The summary lists
+the number of input points, the dimension, the number of vertices
+in the convex hull, the number of facets in the convex hull, the
+number of good facets (if 'Pg'), and statistics.
+
+The last two statistics (if needed) measure the maximum distance
+from a point or vertex to a
+facet. The number in parenthesis (e.g., 2.1x) is the ratio between the
+maximum distance and the worst\[hy]case distance due to merging
+two simplicial facets.
+.PP
+.TP
+Precision options
+.TP
+An
+Maximum angle given as a cosine. If the angle between a pair of facet
+normals
+is greater than n, Qhull merges one of the facets into a neighbor.
+If 'n' is negative, Qhull tests angles after adding
+each point to the hull (pre\[hy]merging).
+If 'n' is positive, Qhull tests angles after
+constructing the hull (post\[hy]merging).
+Both pre\[hy] and post\[hy]merging can be defined.
+
+Option 'C0' or 'C\-0' is set if the corresponding 'Cn' or 'C\-n'
+is not set. If 'Qx'
+is set, then 'A\-n' and 'C\-n' are checked after the hull is constructed
+and before 'An' and 'Cn' are checked.
+.TP
+Cn
+Centrum radius.
+If a centrum is less than n below a neighboring facet, Qhull merges one
+of the facets.
+If 'n' is negative or '\-0', Qhull tests and merges facets after adding
+each point to the hull. This is called "pre\[hy]merging". If 'n' is positive,
+Qhull tests for convexity after constructing the hull ("post\[hy]merging").
+Both pre\[hy] and post\[hy]merging can be defined.
+
+For 5\[hy]d and higher, 'Qx' should be used
+instead of 'C\-n'. Otherwise, most or all facets may be merged
+together.
+.TP
+En
+Maximum roundoff error for distance computations.
+.TP
+Rn
+Randomly perturb distance computations up to +/\- n * max_coord.
+This option perturbs every distance, hyperplane, and angle computation.
+To use time as the random number seed, use option 'QR\-1'.
+.TP
+Vn
+Minimum distance for a facet to be visible.
+A facet is visible if the distance from the point to the
+facet is greater than 'Vn'.
+
+Without merging, the default value for 'Vn' is the round\[hy]off error ('En').
+With merging, the default value is the pre\[hy]merge centrum ('C\-n') in 2\[hy]d or
+3\[hy]d, or three times that in other dimensions. If the outside width
+is specified ('Wn'), the maximum, default value for 'Vn' is 'Wn'.
+.TP
+Un
+Maximum distance below a facet for a point to be coplanar to the facet. The
+default value is 'Vn'.
+.TP
+Wn
+Minimum outside width of the hull. Points are added to the convex hull
+only if they are clearly outside of a facet. A point is outside of a
+facet if its distance to the facet is greater than 'Wn'. The normal
+value for 'Wn' is 'En'. If the user specifies pre\[hy]merging and
+does not set 'Wn', than 'Wn' is set
+to the premerge 'Cn' and maxcoord*(1\-An).
+.PP
+.TP
+Additional input/output formats
+.TP
+Fa
+Print area for each facet.
+For Delaunay triangulations, the area is the area of the triangle.
+For Voronoi diagrams, the area is the area of the dual facet.
+Use 'PAn' for printing the n largest facets, and option 'PFn' for
+printing facets larger than 'n'.
+
+The area for non\[hy]simplicial facets is the sum of the
+areas for each ridge to the centrum. Vertices far below
+the facet's hyperplane are ignored.
+The reported area may be significantly less than the actual area.
+.TP
+FA
+Compute the total area and volume for option 's'. It is an approximation
+for non\[hy]simplicial facets (see 'Fa').
+.TP
+Fc
+Print coplanar points for each facet. The output starts with the
+number of facets. Then each facet is printed one per line. Each line
+is the number of coplanar points followed by the point ids.
+Option 'Qi' includes the interior points. Each coplanar point (interior point) is
+assigned to the facet it is furthest above (resp., least below).
+.TP
+FC
+Print centrums for each facet. The output starts with the
+dimension followed by the number of facets.
+Then each facet centrum is printed, one per line.
+.TP
+Fd
+Read input in cdd format with homogeneous points.
+The input starts with comments. The first comment is reported in
+the summary.
+Data starts after a "begin" line. The next line is the number of points
+followed by the dimension+1 and "real" or "integer". Then the points
+are listed with a leading "1" or "1.0". The data ends with an "end" line.
+
+For halfspaces ('Fd Hn,n,...'), the input format is the same. Each halfspace
+starts with its offset. The sign of the offset is the opposite of Qhull's
+convention.
+.TP
+FD
+Print normals ('n', 'Fo', 'Fi') or points ('p') in cdd format.
+The first line is the command line that invoked Qhull.
+Data starts with a "begin" line. The next line is the number of normals or points
+followed by the dimension+1 and "real". Then the normals or points
+are listed with the offset before the coefficients. The offset for points is
+1.0. The offset for normals has the opposite sign.
+The data ends with an "end" line.
+.TP
+FF
+Print facets (as in 'f') without printing the ridges.
+.TP
+Fi
+Print inner planes for each facet. The inner plane is below all vertices.
+.TP
+Fi
+Print separating hyperplanes for bounded, inner regions of the Voronoi
+diagram. The first line is the number
+of ridges. Then each hyperplane is printed, one per line. A line starts
+with the number of indices and floats. The first pair lists
+adjacent input
+sites, the next d floats are the normalized coefficients for the hyperplane,
+and the last float is the offset. The hyperplane is oriented toward 'QVn'
+(if defined), or the first input site of the pair. Use 'Tv' to
+verify that the hyperplanes are perpendicular bisectors. Use 'Fo' for
+unbounded regions, and 'Fv' for the corresponding Voronoi vertices.
+.TP
+FI
+Print facet identifiers.
+.TP
+Fm
+Print number of merges for each facet. At most 511 merges are reported for
+a facet. See 'PMn' for printing the facets with the most merges.
+.TP
+FM
+Output the hull in Maple format. Qhull writes a Maple
+file for 2\[hy]d and 3\[hy]d
+convex hulls and for 2\[hy]d Delaunay triangulations. Qhull produces a '.mpl'
+file for displaying with display3d().
+.TP
+Fn
+Print neighbors for each facet. The output starts with the number of facets.
+Then each facet is printed one per line. Each line
+is the number of neighbors followed by an index for each neighbor. The indices
+match the other facet output formats.
+
+A negative index indicates an unprinted
+facet due to printing only good facets ('Pg'). It is the negation of the facet's
+ID (option 'FI').
+For example, negative indices are used for facets
+"at infinity" in the Delaunay triangulation.
+.TP
+FN
+Print vertex neighbors or coplanar facet for each point.
+The first line is the number
+of points. Then each point is printed, one per line. If the
+point is coplanar, the line is "1" followed by the facet's ID.
+If the point is
+not a selected vertex, the line is "0".
+Otherwise, each line is the number of
+neighbors followed by the corresponding facet indices (see 'Fn').
+.TP
+Fo
+Print outer planes for each facet in the same format as 'n'.
+The outer plane is above all points.
+.TP
+Fo
+Print separating hyperplanes for unbounded, outer regions of the Voronoi
+diagram. The first line is the number
+of ridges. Then each hyperplane is printed, one per line. A line starts
+with the number of indices and floats. The first pair lists
+adjacent input
+sites, the next d floats are the normalized coefficients for the hyperplane,
+and the last float is the offset. The hyperplane is oriented toward 'QVn'
+(if defined), or the first input site of the pair. Use 'Tv' to
+verify that the hyperplanes are perpendicular bisectors. Use 'Fi' for
+bounded regions, and 'Fv' for the corresponding Voronoi vertices.
+.TP
+FO
+List all options to stderr, including the default values. Additional 'FO's
+are printed to stdout.
+.TP
+Fp
+Print points for halfspace intersections (option 'Hn,n,...'). Each
+intersection corresponds to a facet of the dual polytope.
+The "infinity" point [\-10.101,\-10.101,...]
+indicates an unbounded intersection.
+.TP
+FP
+For each coplanar point ('Qc') print the point ID of the nearest vertex,
+the point ID, the facet ID, and the distance.
+.TP
+FQ
+Print command used for qhull and input.
+.TP
+Fs
+Print a summary. The first line consists of the number of integers ("8"),
+followed by the dimension, the number of points, the number of vertices,
+the number of facets, the number of vertices selected for output, the
+number of facets selected for output, the number of coplanar points selected
+for output, number of simplicial, unmerged facets in output
+
+The second line consists of the number of reals ("2"),
+followed by the maxmimum offset to an outer plane and and minimum offset to
+an inner plane. Roundoff is included. Later
+versions of Qhull may produce additional integers or reals.
+.TP
+FS
+Print the size of the hull. The first line consists of the number of integers ("0").
+The second line consists of the number of reals ("2"),
+followed by the total facet area, and the total volume.
+Later
+versions of Qhull may produce additional integers or reals.
+
+The total volume measures the volume
+of the intersection of the halfspaces defined by each facet.
+Both area and volume are
+approximations for non\[hy]simplicial facets. See option 'Fa'.
+.TP
+Ft
+Print a triangulation with added points for non\[hy]simplicial
+facets. The first line is the dimension and the second line is the
+number of points and the number of facets. The points follow, one
+per line, then the facets follow as a list of point indices. With option 'Qz', the
+points include the point\[hy]at\[hy]infinity.
+.TP
+Fv
+Print vertices for each facet. The first line is the number
+of facets. Then each facet is printed, one per line. Each line is
+the number of vertices followed by the corresponding point ids. Vertices
+are listed in the order they were added to the hull (the last one is first).
+.TP
+Fv
+Print all ridges of a Voronoi diagram. The first line is the number
+of ridges. Then each ridge is printed, one per line. A line starts
+with the number of indices. The first pair lists adjacent input
+sites, the remaining indices list Voronoi vertices. Vertex '0' indicates
+the vertex\[hy]at\[hy]infinity (i.e., an unbounded ray). In 3\[hy]d, the vertices
+are listed in order. See 'Fi' and 'Fo' for separating hyperplanes.
+.TP
+FV
+Print average vertex. The average vertex is a feasible point
+for halfspace intersection.
+.TP
+Fx
+List extreme points (vertices) of the convex hull. The first line
+is the number of points. The other lines give the indices of the
+corresponding points. The first point is '0'. In 2\[hy]d, the points
+occur in counter\[hy]clockwise order; otherwise they occur in input order.
+For Delaunay triangulations, 'Fx' lists the extreme points of the
+input sites. The points are unordered.
+.PP
+.TP
+Geomview options
+.TP
+G
+Produce a file for viewing with Geomview. Without other options,
+Qhull displays edges in 2\[hy]d, outer planes in 3\[hy]d, and ridges in 4\[hy]d.
+A ridge can be
+explicit or implicit. An explicit ridge is a dim\-1 dimensional simplex
+between two facets.
+In 4\[hy]d, the explicit ridges are triangles.
+When displaying a ridge in 4\[hy]d, Qhull projects the ridge's vertices to
+one of its facets' hyperplanes.
+Use 'Gh' to
+project ridges to the intersection of both hyperplanes.
+.TP
+Ga
+Display all input points as dots.
+.TP
+Gc
+Display the centrum for each facet in 3\[hy]d. The centrum is defined by a
+green radius sitting on a blue plane. The plane corresponds to the
+facet's hyperplane.
+The radius is defined by 'C\-n' or 'Cn'.
+.TP
+GDn
+Drop dimension n in 3\[hy]d or 4\[hy]d. The result is a 2\[hy]d or 3\[hy]d object.
+.TP
+Gh
+Display hyperplane intersections in 3\[hy]d and 4\[hy]d. In 3\[hy]d, the
+intersection is a black line. It lies on two neighboring hyperplanes
+(c.f., the blue squares associated with centrums ('Gc')). In 4\[hy]d,
+the ridges are projected to the intersection of both hyperplanes.
+.TP
+Gi
+Display inner planes in 2\[hy]d and 3\[hy]d. The inner plane of a facet
+is below all of its vertices. It is parallel to the facet's hyperplane.
+The inner plane's color is the opposite (1\-r,1\-g,1\-b) of the outer
+plane. Its edges are determined by the vertices.
+.TP
+Gn
+Do not display inner or outer planes. By default,
+Geomview displays the precise plane (no merging) or both
+inner and output planes (merging). Under merging, Geomview does
+not display the inner plane if the
+the difference between inner and outer is too small.
+.TP
+Go
+Display outer planes in 2\[hy]d and 3\[hy]d. The outer plane of a facet
+is above all input points. It is parallel to the facet's hyperplane.
+Its color is determined by the facet's normal, and its
+edges are determined by the vertices.
+.TP
+Gp
+Display coplanar points and vertices as radii. A radius defines a ball
+which corresponds to the imprecision of the point. The imprecision is
+the maximum of the roundoff error, the centrum radius, and maxcoord *
+(1\-An). It is at least 1/20'th of the maximum coordinate,
+and ignores post\[hy]merging if pre\[hy]merging is done.
+.TP
+Gr
+Display ridges in 3\[hy]d. A ridge connects the two vertices that are shared
+by neighboring facets. Ridges are always displayed in 4\[hy]d.
+.TP
+Gt
+A 3\[hy]d Delaunay triangulation looks like a convex hull with interior
+facets. Option 'Gt' removes the outside ridges to reveal the outermost
+facets. It automatically sets options 'Gr' and 'GDn'.
+.TP
+Gv
+Display vertices as spheres. The radius of the sphere corresponds to
+the imprecision of the data. See 'Gp' for determining the radius.
+.PP
+.TP
+Print options
+.TP
+PAn
+Only the n largest facets are marked good for printing.
+Unless 'PG' is set, 'Pg' is automatically set.
+.TP
+Pdk:n
+Drop facet from output if normal[k] <= n. The option 'Pdk' uses the
+default value of 0 for n.
+.TP
+PDk:n
+Drop facet from output if normal[k] >= n. The option 'PDk' uses the
+default value of 0 for n.
+.TP
+PFn
+Only facets with area at least 'n' are marked good for printing.
+Unless 'PG' is set, 'Pg' is automatically set.
+.TP
+Pg
+Print only good facets. A good facet is either visible from a point
+(the 'QGn' option) or includes a point (the 'QVn' option). It also meets the
+requirements of 'Pdk' and 'PDk' options. Option 'Pg' is automatically
+set for options 'PAn' and 'PFn'.
+.TP
+PG
+Print neighbors of good facets.
+.TP
+PMn
+Only the n facets with the most merges are marked good for printing.
+Unless 'PG' is set, 'Pg' is automatically set.
+.TP
+Po
+Force output despite precision problems. Verify ('Tv') does not check
+coplanar points.
+Flipped facets are reported and concave facets are counted.
+If 'Po' is used, points are not
+partitioned into flipped facets and a flipped facet is always visible
+to a point.
+Also, if an error occurs before the completion of Qhull and tracing is
+not active, 'Po' outputs a neighborhood of the erroneous facets
+(if any).
+.TP
+Pp
+Do not report precision problems.
+.PP
+.TP
+Qhull control options
+.TP
+Qbk:0Bk:0
+Drop dimension k from the input points. This allows the user to
+take convex hulls of sub\[hy]dimensional objects. It happens before
+the Delaunay and Voronoi transformation.
+.TP
+QbB
+Scale the input points to fit the unit cube. After scaling, the lower
+bound will be \-0.5 and the upper bound +0.5 in all dimensions.
+For Delaunay and
+Voronoi diagrams, scaling happens after projection to the paraboloid.
+Under precise
+arithmetic, scaling does not change the topology of the convex hull.
+.TP
+Qbb
+Scale the last coordinate to [0, m] where m is the maximum absolute
+value of the other coordinates. For Delaunay and
+Voronoi diagrams, scaling happens after projection to the paraboloid.
+It reduces roundoff error for inputs with integer coordinates.
+Under precise
+arithmetic, scaling does not change the topology of the convex hull.
+.TP
+Qbk:n
+Scale the k'th coordinate of the input points. After scaling, the lower
+bound of the input points will be n. 'Qbk' scales to \-0.5.
+.TP
+QBk:n
+Scale the k'th coordinate of the input points. After scaling, the upper
+bound will be n. 'QBk' scales to +0.5.
+.TP
+Qc
+Keep coplanar points with the nearest facet. Output
+formats 'p', 'f', 'Gp', 'Fc', 'FN', and 'FP' will print the points.
+.TP
+Qf
+Partition points to the furthest outside facet.
+.TP
+Qg
+Only build good facets. With the 'Qg' option, Qhull will only build
+those facets that it needs to determine the good facets in the output.
+See 'QGn', 'QVn', and 'PdD' for defining good facets, and 'Pg' and 'PG'
+for printing good facets and their neighbors.
+.TP
+QGn
+A facet is good (see 'Qg' and 'Pg') if it is visible from point n. If n < 0, a facet is
+good if it is not visible from point n. Point n is not added to the
+hull (unless 'TCn' or 'TPn').
+With rbox, use the 'Pn,m,r' option to define your point; it
+will be point 0 (QG0).
+.TP
+Qi
+Keep interior points with the nearest facet.
+Output formats 'p', 'f', 'Gp', 'FN', 'FP', and 'Fc' will print the points.
+.TP
+QJn
+Joggle each input coordinate by adding a random number in [\-n,n]. If a
+precision error occurs, then qhull increases n and tries again. It does
+not increase n beyond a certain value, and it stops after a certain number
+of attempts [see user.h]. Option 'QJ'
+selects a default value for n. The output will be simplicial. For
+Delaunay triangulations, 'QJn' sets 'Qbb' to scale the last coordinate
+(not if 'Qbk:n' or 'QBk:n' is set).
+\'QJn' is deprecated for Voronoi diagrams. See also 'Qt'.
+.TP
+Qm
+Only process points that would otherwise increase max_outside. Other
+points are treated as coplanar or interior points.
+.TP
+Qr
+Process random outside points instead of furthest ones. This makes
+Qhull equivalent to the randomized incremental algorithms. CPU time
+is not reported since the randomization is inefficient.
+.TP
+QRn
+Randomly rotate the input points. If n=0, use time as the random number seed.
+If n>0, use n as the random number seed. If n=\-1, don't rotate but use
+time as the random number seed. For Delaunay triangulations ('d' and 'v'),
+rotate about the last axis.
+.TP
+Qs
+Search all points for the initial simplex.
+.TP
+Qt
+Triangulated output. Triangulate all non\[hy]simplicial facets.
+\'Qt' is deprecated for Voronoi diagrams. See also 'Qt'.
+.TP
+Qv
+Test vertex neighbors for convexity after post\[hy]merging.
+To use the 'Qv' option, you also need to set a merge option
+(e.g., 'Qx' or 'C\-0').
+.TP
+QVn
+A good facet (see 'Qg' and 'Pg') includes point n. If n<0, then a good facet does not
+include point n. The point is either in the initial simplex or it
+is the first point added to the hull. Option 'QVn' may not be used with merging.
+.TP
+Qx
+Perform exact merges while building the hull. The "exact" merges
+are merging a point into a coplanar facet (defined by 'Vn', 'Un',
+and 'C\-n'), merging concave facets, merging duplicate ridges, and
+merging flipped facets. Coplanar merges and angle coplanar merges ('A\-n')
+are not performed. Concavity testing is delayed until a merge occurs.
+
+After
+the hull is built, all coplanar merges are performed (defined by 'C\-n'
+and 'A\-n'), then post\[hy]merges are performed
+(defined by 'Cn' and 'An').
+.TP
+Qz
+Add a point "at infinity" that is above the paraboloid for Delaunay triangulations
+and Voronoi diagrams. This reduces precision problems and allows the triangulation
+of cospherical points.
+.PP
+.TP
+Qhull experiments and speedups
+.TP
+Q0
+Turn off pre\[hy]merging as a default option.
+With 'Q0'/'Qx' and without explicit pre\[hy]merge options, Qhull
+ignores precision issues while constructing the convex hull. This
+may lead to precision errors. If so, a descriptive warning is
+generated.
+.TP
+Q1
+With 'Q1', Qhull sorts merges by type (coplanar, angle coplanar, concave)
+instead of by angle.
+.TP
+Q2
+With 'Q2', Qhull merges all facets at once instead of using
+independent sets of merges and then retesting.
+.TP
+Q3
+With 'Q3', Qhull does not remove redundant vertices.
+.TP
+Q4
+With 'Q4', Qhull avoids merges of an old facet into a new facet.
+.TP
+Q5
+With 'Q5', Qhull does not correct outer planes at the end. The
+maximum outer plane is used instead.
+.TP
+Q6
+With 'Q6', Qhull does not pre\[hy]merge concave or coplanar facets.
+.TP
+Q7
+With 'Q7', Qhull processes facets in depth\[hy]first order instead of
+breadth\[hy]first order.
+.TP
+Q8
+With 'Q8' and merging, Qhull does not retain near\[hy]interior points for adjusting
+outer planes. 'Qc' will probably retain
+all points that adjust outer planes.
+.TP
+Q9
+With 'Q9', Qhull processes the furthest of all outside sets at each iteration.
+.TP
+Q10
+With 'Q10', Qhull does not use special processing for narrow distributions.
+.TP
+Q11
+With 'Q11', Qhull copies normals and recompute centrums for tricoplanar facets.
+.TP
+Q12
+With 'Q12', Qhull does not report a very wide merge due to a duplicated ridge with nearly coincident vertices
+.PP
+.TP
+Trace options
+.TP
+Tn
+Trace at level n. Qhull includes full execution tracing. 'T\-1'
+traces events. 'T1' traces
+the overall execution of the program. 'T2' and 'T3' trace overall
+execution and geometric and topological events. 'T4' traces the
+algorithm. 'T5' includes information about memory allocation and
+Gaussian elimination.
+.TP
+Ta
+Annotate output with codes that identify the
+corresponding qh_fprintf() statement.
+.TP
+Tc
+Check frequently during execution. This will catch most inconsistency
+errors.
+.TP
+TCn
+Stop Qhull after building the cone of new facets for point n. The
+output for 'f' includes the cone and the old hull.
+See also 'TVn'.
+.TP
+TFn
+Report progress whenever more than n facets are created
+During post\[hy]merging, 'TFn'
+reports progress after more than n/2 merges.
+.TP
+TI file
+Input data from 'file'. The filename may not include spaces or
+quotes.
+.TP
+TO file
+Output results to 'file'. The name may be enclosed in single
+quotes.
+.TP
+TPn
+Turn on tracing when point n is added to the hull. Trace
+partitions of point n. If used with TWn, turn off
+tracing after adding point n to the hull.
+.TP
+TRn
+Rerun qhull n times. Usually used with 'QJn' to determine the
+probability that a given joggle will fail.
+.TP
+Ts
+Collect statistics and print to stderr at the end of execution.
+.TP
+Tv
+Verify the convex hull. This checks the topological structure, facet
+convexity, and point inclusion.
+If precision problems occurred, facet convexity is tested whether or
+not 'Tv' is selected.
+Option 'Tv' does not check point inclusion if forcing output with 'Po',
+or if 'Q5' is set.
+
+For point inclusion testing, Qhull verifies that all points are below
+all outer planes (facet\->maxoutside). Point inclusion is exhaustive
+if merging or if the facet\[hy]point product is small enough;
+otherwise Qhull verifies each point with a directed
+search (qh_findbest).
+
+Point inclusion testing occurs after producing output. It prints
+a message to stderr unless option 'Pp' is used. This
+allows the user to interrupt Qhull without changing the output.
+.TP
+TVn
+Stop Qhull after adding point n. If n < 0, stop Qhull before adding
+point n. Output shows the hull at this time. See also 'TCn'
+.TP
+TMn
+Turn on tracing at n'th merge.
+.TP
+TWn
+Trace merge facets when the width is greater than n.
+.TP
+Tz
+Redirect stderr to stdout.
+.PP
+.SH BUGS
+Please report bugs to Brad Barber at qhull_bug@qhull.org.
+
+If Qhull does not compile, it is due to an incompatibility between your
+system and ours. The first thing to check is that your compiler is
+ANSI standard. If it is, check the man page for the best options, or
+find someone to help you. If you locate the cause of your problem,
+please send email since it might help others.
+
+If Qhull compiles but crashes on the test case (rbox D4), there's
+still incompatibility between your system and ours. Typically it's
+been due to mem.c and memory alignment. You can use qh_NOmem in mem.h
+to turn off memory management. Please let us know if you figure out
+how to fix these problems.
+
+If you do find a problem, try to simplify it before reporting the
+error. Try different size inputs to locate the smallest one that
+causes an error. You're welcome to hunt through the code using the
+execution trace as a guide. This is especially true if you're
+incorporating Qhull into your own program.
+
+When you do report an error, please attach a data set to the
+end of your message. This allows us to see the error for ourselves.
+Qhull is maintained part\[hy]time.
+.PP
+.SH E\[hy]MAIL
+Please send correspondence to qhull@qhull.org and report bugs to
+qhull_bug@qhull.org. Let us know how you use Qhull. If you
+mention it in a paper, please send the reference and an abstract.
+
+If you would like to get Qhull announcements (e.g., a new version)
+and news (any bugs that get fixed, etc.), let us know and we will add you to
+our mailing list. If you would like to communicate with other
+Qhull users, we will add you to the qhull_users alias.
+For Internet news about geometric algorithms and convex hulls, look at
+comp.graphics.algorithms and sci.math.num\-analysis
+
+.SH SEE ALSO
+rbox(1)
+
+Barber, C. B., D.P. Dobkin, and H.T. Huhdanpaa,
+"The Quickhull Algorithm for Convex Hulls," ACM
+Trans. on Mathematical Software, 22(4):469\[en]483, Dec. 1996.
+http://portal.acm.org/citation.cfm?doid=235815.235821
+http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405
+
+Clarkson, K.L., K. Mehlhorn, and R. Seidel, "Four results on randomized
+incremental construction," Computational Geometry: Theory and Applications,
+vol. 3, p. 185\[en]211, 1993.
+
+Preparata, F. and M. Shamos, Computational
+Geometry, Springer\[hy]Verlag, New York, 1985.
+
+.PP
+.SH AUTHORS
+.nf
+ C. Bradford Barber Hannu Huhdanpaa
+ bradb@shore.net hannu@qhull.org
+
+ .fi
+
+.SH ACKNOWLEDGEMENTS
+
+A special thanks to Albert Marden, Victor Milenkovic, the Geometry Center,
+Harvard University, and Endocardial Solutions, Inc. for supporting this work.
+
+Qhull 1.0 and 2.0 were developed under National Science Foundation
+grants NSF/DMS\[hy]8920161 and NSF\[hy]CCR\[hy]91\[hy]15793 750\[hy]7504. David Dobkin
+guided the original work at Princeton University.
+If you find it useful, please let us know.
+
+The Geometry Center is supported by grant DMS\[hy]8920161 from the National
+Science Foundation, by grant DOE/DE\[hy]FG02\[hy]92ER25137 from the Department
+of Energy, by the University of Minnesota, and by Minnesota Technology, Inc.
+
+Qhull is available from http://www.qhull.org
diff --git a/xs/src/qhull/html/qhull.txt b/xs/src/qhull/html/qhull.txt
new file mode 100644
index 000000000..03753547e
--- /dev/null
+++ b/xs/src/qhull/html/qhull.txt
@@ -0,0 +1,1263 @@
+
+
+
+qhull(1) qhull(1)
+
+
+NAME
+ qhull - convex hull, Delaunay triangulation, Voronoi dia-
+ gram, halfspace intersection about a point, hull volume, facet area
+
+SYNOPSIS
+ qhull- compute convex hulls and related structures
+ input (stdin): dimension, #points, point coordinates
+ first comment (non-numeric) is listed in the summary
+ halfspace: use dim plus one with offsets after coefficients
+
+ options (qh-quick.htm):
+ d - Delaunay triangulation by lifting points to a paraboloid
+ v - Voronoi diagram via the Delaunay triangulation
+ H1,1 - Halfspace intersection about [1,1,0,...]
+ d Qu - Furthest-site Delaunay triangulation (upper convex hull)
+ v Qu - Furthest-site Voronoi diagram
+ QJ - Joggle the input to avoid precision problems
+ . - concise list of all options
+ - - one-line description of all options
+
+ Output options (subset):
+ FA - compute total area and volume
+ Fx - extreme points (convex hull vertices)
+ G - Geomview output (2-d, 3-d and 4-d)
+ Fp - halfspace intersection coordinates
+ m - Mathematica output (2-d and 3-d)
+ n - normals with offsets
+ o - OFF file format (if Voronoi, outputs regions)
+ TO file- output results to file, may be enclosed in single quotes
+ f - print all fields of all facets
+ s - summary of results (default)
+ Tv - verify result: structure, convexity, and point inclusion
+ p - vertex coordinates
+ i - vertices incident to each facet
+
+ example:
+ rbox 1000 s | qhull Tv s FA
+
+ - html manual: index.htm
+ - installation: README.txt
+ - see also: COPYING.txt, REGISTER.txt, Changes.txt
+ - WWW: <http://www.qhull.org>
+ - GIT: <git@github.com:qhull/qhull.git>
+ - mirror: <http://www6.uniovi.es/ftp/pub/mirrors/geom.umn.edu/software/ghindex.html>
+ - news: <http://www.qhull.org/news>
+ - Geomview: <http://www.geomview.org>
+ - news group: <news:comp.graphics.algorithms>
+ - FAQ: <http://www.faqs.org/faqs/graphics/algorithms-faq/>
+ - email: qhull@qhull.org
+ - bug reports: qhull_bug@qhull.org
+
+
+
+
+Geometry Center 2003/12/30 1
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ The sections are:
+ - INTRODUCTION
+ - DESCRIPTION, a description of Qhull
+ - IMPRECISION, how Qhull handles imprecision
+ - OPTIONS
+ - Input and output options
+ - Additional input/output formats
+ - Precision options
+ - Geomview options
+ - Print options
+ - Qhull options
+ - Trace options
+ - BUGS
+ - E-MAIL
+ - SEE ALSO
+ - AUTHORS
+ - ACKNOWLEGEMENTS
+
+ This man page briefly describes all Qhull options. Please
+ report any mismatches with Qhull's html manual (qh-
+ man.htm).
+
+
+
+INTRODUCTION
+ Qhull is a general dimension code for computing convex
+ hulls, Delaunay triangulations, Voronoi diagram, furthest-
+ site Voronoi diagram, furthest-site Delaunay triangula-
+ tions, and halfspace intersections about a point. It
+ implements the Quickhull algorithm for computing the con-
+ vex hull. Qhull handles round-off errors from floating
+ point arithmetic. It can approximate a convex hull.
+
+ The program includes options for hull volume, facet area,
+ partial hulls, input transformations, randomization, trac-
+ ing, multiple output formats, and execution statistics.
+ The program can be called from within your application.
+ You can view the results in 2-d, 3-d and 4-d with
+ Geomview.
+
+
+DESCRIPTION
+ The format of input is the following: first line contains
+ the dimension, second line contains the number of input
+ points, and point coordinates follow. The dimension and
+ number of points can be reversed. Comments and line
+ breaks are ignored. A comment starts with a non-numeric
+ character and continues to the end of line. The first
+ comment is reported in summaries and statistics. Error
+ reporting is better if there is one point per line.
+
+ The default printout option is a short summary. There are
+ many other output formats.
+
+
+
+
+Geometry Center 2003/12/30 2
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ Qhull implements the Quickhull algorithm for convex hull.
+ This algorithm combines the 2-d Quickhull algorithm with
+ the n-d beneath-beyond algorithm [c.f., Preparata & Shamos
+ '85]. It is similar to the randomized algorithms of
+ Clarkson and others [Clarkson et al. '93]. The main
+ advantages of Quickhull are output sensitive performance,
+ reduced space requirements, and automatic handling of pre-
+ cision problems.
+
+ The data structure produced by Qhull consists of vertices,
+ ridges, and facets. A vertex is a point of the input set.
+ A ridge is a set of d vertices and two neighboring facets.
+ For example in 3-d, a ridge is an edge of the polyhedron.
+ A facet is a set of ridges, a set of neighboring facets, a
+ set of incident vertices, and a hyperplane equation. For
+ simplicial facets, the ridges are defined by the vertices
+ and neighboring facets. When Qhull merges two facets, it
+ produces a non-simplicial facet. A non-simplicial facet
+ has more than d neighbors and may share more than one
+ ridge with a neighbor.
+
+
+IMPRECISION
+ Since Qhull uses floating point arithmetic, roundoff error
+ may occur for each calculation. This causes problems for
+ most geometric algorithms.
+
+ Qhull automatically sets option 'C-0' in 2-d, 3-d, and
+ 4-d, or option 'Qx' in 5-d and higher. These options han-
+ dle precision problems by merging facets. Alternatively,
+ use option 'QJ' to joggle the input.
+
+ With 'C-0', Qhull merges non-convex facets while con-
+ structing the hull. The remaining facets are clearly con-
+ vex. With 'Qx', Qhull merges coplanar horizon facets,
+ flipped facets, concave facets and duplicated ridges. It
+ merges coplanar facets after constructing the hull. With
+ 'Qx', coplanar points may be missed, but it appears to be
+ unlikely.
+
+ To guarantee triangular output, joggle the input with
+ option 'QJ'. Facet merging will not occur.
+
+OPTIONS
+ To get a list of the most important options, execute
+ 'qhull' by itself. To get a complete list of options,
+ execute 'qhull -'. To get a complete, concise list of
+ options, execute 'qhull .'.
+
+ Options can be in any order. Capitalized options take an
+ argument (except 'PG' and 'F' options). Single letters
+ are used for output formats and precision constants. The
+ other options are grouped into menus for other output for-
+ mats ('F'), Geomview output ('G'), printing ('P'), Qhull
+
+
+
+Geometry Center 2003/12/30 3
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ control ('Q'), and tracing ('T').
+
+ Main options:
+
+ default
+ Compute the convex hull of the input points.
+ Report a summary of the result.
+
+ d Compute the Delaunay triangulation by lifting the
+ input points to a paraboloid. The 'o' option
+ prints the input points and facets. The 'QJ'
+ option guarantees triangular output. The 'Ft'
+ option prints a triangulation. It adds points (the
+ centrums) to non-simplicial facets.
+
+ v Compute the Voronoi diagram from the Delaunay tri-
+ angulation. The 'p' option prints the Voronoi ver-
+ tices. The 'o' option prints the Voronoi vertices
+ and the vertices in each Voronoi region. It lists
+ regions in site id order. The 'Fv' option prints
+ each ridge of the Voronoi diagram. The first or
+ zero'th vertex indicates the infinity vertex. Its
+ coordinates are qh_INFINITE (-10.101). It indi-
+ cates unbounded Voronoi regions or degenerate
+ Delaunay triangles.
+
+ Hn,n,...
+ Compute halfspace intersection about [n,n,0,...].
+ The input is a set of halfspaces defined in the
+ same format as 'n', 'Fo', and 'Fi'. Use 'Fp' to
+ print the intersection points. Use 'Fv' to list
+ the intersection points for each halfspace. The
+ other output formats display the dual convex hull.
+
+ The point [n,n,n,...] is a feasible point for the
+ halfspaces, i.e., a point that is inside all of the
+ halfspaces (Hx+b <= 0). The default coordinate
+ value is 0.
+
+ The input may start with a feasible point. If so,
+ use 'H' by itself. The input starts with a feasi-
+ ble point when the first number is the dimension,
+ the second number is "1", and the coordinates com-
+ plete a line. The 'FV' option produces a feasible
+ point for a convex hull.
+
+ d Qu Compute the furthest-site Delaunay triangulation
+ from the upper convex hull. The 'o' option prints
+ the input points and facets. The 'QJ' option guar-
+ antees triangular otuput. You can also use facets.
+
+ v Qu Compute the furthest-site Voronoi diagram. The 'p'
+ option prints the Voronoi vertices. The 'o' option
+ prints the Voronoi vertices and the vertices in
+
+
+
+Geometry Center 2003/12/30 4
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ each Voronoi region. The 'Fv' option prints each
+ ridge of the Voronoi diagram. The first or zero'th
+ vertex indicates the infinity vertex at infinity.
+ Its coordinates are qh_INFINITE (-10.101). It
+ indicates unbounded Voronoi regions and degenerate
+ Delaunay triangles.
+
+ Qt Triangulated output.
+
+
+ Input/Output options:
+
+ f Print out all facets and all fields of each facet.
+
+ G Output the hull in Geomview format. For imprecise
+ hulls, Geomview displays the inner and outer hull.
+ Geomview can also display points, ridges, vertices,
+ coplanar points, and facet intersections. See
+ below for a list of options.
+
+ For Delaunay triangulations, 'G' displays the cor-
+ responding paraboloid. For halfspace intersection,
+ 'G' displays the dual polytope.
+
+ i Output the incident vertices for each facet. Qhull
+ prints the number of facets followed by the ver-
+ tices of each facet. One facet is printed per
+ line. The numbers are the 0-relative indices of
+ the corresponding input points. The facets are
+ oriented.
+
+ In 4-d and higher, Qhull triangulates non-simpli-
+ cial facets. Each apex (the first vertex) is a
+ created point that corresponds to the facet's cen-
+ trum. Its index is greater than the indices of the
+ input points. Each base corresponds to a simpli-
+ cial ridge between two facets. To print the ver-
+ tices without triangulation, use option 'Fv'.
+
+ m Output the hull in Mathematica format. Qhull
+ writes a Mathematica file for 2-d and 3-d convex
+ hulls and for 2-d Delaunay triangulations. Qhull
+ produces a list of objects that you can assign to a
+ variable in Mathematica, for example: "list= <<
+ <outputfilename> ". If the object is 2-d, it can be
+ visualized by "Show[Graphics[list]] ". For 3-d
+ objects the command is "Show[Graphics3D[list]]".
+
+ n Output the normal equation for each facet. Qhull
+ prints the dimension (plus one), the number of
+ facets, and the normals for each facet. The
+ facet's offset follows its normal coefficients.
+
+ o Output the facets in OFF file format. Qhull prints
+ the dimension, number of points, number of facets,
+ and number of ridges. Then it prints the
+
+
+
+Geometry Center 2003/12/30 5
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ coordinates of the input points and the vertices
+ for each facet. Each facet is on a separate line.
+ The first number is the number of vertices. The
+ remainder are the indices of the corresponding
+ points. The vertices are oriented in 2-d, 3-d, and
+ in simplicial facets.
+
+ For 2-d Voronoi diagrams, the vertices are sorted
+ by adjacency, but not oriented. In 3-d and higher,
+ the Voronoi vertices are sorted by index. See the
+ 'v' option for more information.
+
+ p Output the coordinates of each vertex point. Qhull
+ prints the dimension, the number of points, and the
+ coordinates for each vertex. With the 'Gc' and
+ 'Gi' options, it also prints coplanar and interior
+ points. For Voronoi diagrams, it prints the coor-
+ dinates of each Voronoi vertex.
+
+ s Print a summary to stderr. If no output options
+ are specified at all, a summary goes to stdout.
+ The summary lists the number of input points, the
+ dimension, the number of vertices in the convex
+ hull, the number of facets in the convex hull, the
+ number of good facets (if 'Pg'), and statistics.
+
+ The last two statistics (if needed) measure the
+ maximum distance from a point or vertex to a facet.
+ The number in parenthesis (e.g., 2.1x) is the ratio
+ between the maximum distance and the worst-case
+ distance due to merging two simplicial facets.
+
+
+ Precision options
+
+ An Maximum angle given as a cosine. If the angle
+ between a pair of facet normals is greater than n, Qhull
+ merges one of the facets into a neighbor. If 'n'
+ is negative, Qhull tests angles after adding each
+ point to the hull (pre-merging). If 'n' is posi-
+ tive, Qhull tests angles after constructing the
+ hull (post-merging). Both pre- and post-merging
+ can be defined.
+
+ Option 'C0' or 'C-0' is set if the corresponding
+ 'Cn' or 'C-n' is not set. If 'Qx' is set, then 'A-
+ n' and 'C-n' are checked after the hull is con-
+ structed and before 'An' and 'Cn' are checked.
+
+ Cn Centrum radius. If a centrum is less than n below
+ a neighboring facet, Qhull merges one of the
+ facets. If 'n' is negative or '-0', Qhull tests
+ and merges facets after adding each point to the
+ hull. This is called "pre-merging". If 'n' is
+
+
+
+Geometry Center 2003/12/30 6
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ positive, Qhull tests for convexity after con-
+ structing the hull ("post-merging"). Both pre- and
+ post-merging can be defined.
+
+ For 5-d and higher, 'Qx' should be used instead of
+ 'C-n'. Otherwise, most or all facets may be merged
+ together.
+
+ En Maximum roundoff error for distance computations.
+
+ Rn Randomly perturb distance computations up to +/- n
+ * max_coord. This option perturbs every distance,
+ hyperplane, and angle computation. To use time as
+ the random number seed, use option 'QR-1'.
+
+ Vn Minimum distance for a facet to be visible. A
+ facet is visible if the distance from the point to
+ the facet is greater than 'Vn'.
+
+ Without merging, the default value for 'Vn' is the
+ round-off error ('En'). With merging, the default
+ value is the pre-merge centrum ('C-n') in 2-d or
+ 3--d, or three times that in other dimensions. If
+ the outside width is specified ('Wn'), the maximum,
+ default value for 'Vn' is 'Wn'.
+
+ Un Maximum distance below a facet for a point to be
+ coplanar to the facet. The default value is 'Vn'.
+
+ Wn Minimum outside width of the hull. Points are
+ added to the convex hull only if they are clearly
+ outside of a facet. A point is outside of a facet
+ if its distance to the facet is greater than 'Wn'.
+ The normal value for 'Wn' is 'En'. If the user
+ specifies pre-merging and does not set 'Wn', than
+ 'Wn' is set to the premerge 'Cn' and maxco-
+ ord*(1-An).
+
+
+ Additional input/output formats
+
+ Fa Print area for each facet. For Delaunay triangula-
+ tions, the area is the area of the triangle. For
+ Voronoi diagrams, the area is the area of the dual
+ facet. Use 'PAn' for printing the n largest
+ facets, and option 'PFn' for printing facets larger
+ than 'n'.
+
+ The area for non-simplicial facets is the sum of
+ the areas for each ridge to the centrum. Vertices
+ far below the facet's hyperplane are ignored. The
+ reported area may be significantly less than the
+ actual area.
+
+
+
+
+Geometry Center 2003/12/30 7
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ FA Compute the total area and volume for option 's'.
+ It is an approximation for non-simplicial facets
+ (see 'Fa').
+
+ Fc Print coplanar points for each facet. The output
+ starts with the number of facets. Then each facet
+ is printed one per line. Each line is the number
+ of coplanar points followed by the point ids.
+ Option 'Qi' includes the interior points. Each
+ coplanar point (interior point) is assigned to the
+ facet it is furthest above (resp., least below).
+
+ FC Print centrums for each facet. The output starts
+ with the dimension followed by the number of
+ facets. Then each facet centrum is printed, one
+ per line.
+
+ Fd Read input in cdd format with homogeneous points.
+ The input starts with comments. The first comment
+ is reported in the summary. Data starts after a
+ "begin" line. The next line is the number of
+ points followed by the dimension+1 and "real" or
+ "integer". Then the points are listed with a
+ leading "1" or "1.0". The data ends with an "end"
+ line.
+
+ For halfspaces ('Fd Hn,n,...'), the input format is
+ the same. Each halfspace starts with its offset.
+ The sign of the offset is the opposite of Qhull's
+ convention.
+
+ FD Print normals ('n', 'Fo', 'Fi') or points ('p') in
+ cdd format. The first line is the command line
+ that invoked Qhull. Data starts with a "begin"
+ line. The next line is the number of normals or
+ points followed by the dimension+1 and "real".
+ Then the normals or points are listed with the
+ offset before the coefficients. The offset for
+ points is 1.0. The offset for normals has the
+ opposite sign. The data ends with an "end" line.
+
+ FF Print facets (as in 'f') without printing the
+ ridges.
+
+ Fi Print inner planes for each facet. The inner plane
+ is below all vertices.
+
+ Fi Print separating hyperplanes for bounded, inner
+ regions of the Voronoi diagram. The first line is
+ the number of ridges. Then each hyperplane is
+ printed, one per line. A line starts with the num-
+ ber of indices and floats. The first pair lists
+ adjacent input sites, the next d floats are the
+ normalized coefficients for the hyperplane, and the
+
+
+
+Geometry Center 2003/12/30 8
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ last float is the offset. The hyperplane is ori-
+ ented toward verify that the hyperplanes are per-
+ pendicular bisectors. Use 'Fo' for unbounded
+ regions, and 'Fv' for the corresponding Voronoi
+ vertices.
+
+ FI Print facet identifiers.
+
+ Fm Print number of merges for each facet. At most 511
+ merges are reported for a facet. See 'PMn' for
+ printing the facets with the most merges.
+
+ FM Output the hull in Maple format. See 'm'
+
+ Fn Print neighbors for each facet. The output starts
+ with the number of facets. Then each facet is
+ printed one per line. Each line is the number of
+ neighbors followed by an index for each neighbor.
+ The indices match the other facet output formats.
+
+ A negative index indicates an unprinted facet due
+ to printing only good facets ('Pg'). It is the
+ negation of the facet's id (option 'FI'). For
+ example, negative indices are used for facets "at
+ infinity" in the Delaunay triangulation.
+
+ FN Print vertex neighbors or coplanar facet for each
+ point. The first line is the number of points.
+ Then each point is printed, one per line. If the
+ point is coplanar, the line is "1" followed by the
+ facet's id. If the point is not a selected vertex,
+ the line is "0". Otherwise, each line is the num-
+ ber of neighbors followed by the corresponding
+ facet indices (see 'Fn').
+
+ Fo Print outer planes for each facet in the same for-
+ mat as 'n'. The outer plane is above all points.
+
+ Fo Print separating hyperplanes for unbounded, outer
+ regions of the Voronoi diagram. The first line is
+ the number of ridges. Then each hyperplane is
+ printed, one per line. A line starts with the num-
+ ber of indices and floats. The first pair lists
+ adjacent input sites, the next d floats are the
+ normalized coefficients for the hyperplane, and the
+ last float is the offset. The hyperplane is ori-
+ ented toward verify that the hyperplanes are per-
+ pendicular bisectors. Use 'Fi' for bounded
+ regions, and 'Fv' for the corresponding Voronoi
+ vertices.
+
+ FO List all options to stderr, including the default
+ values. Additional 'FO's are printed to stdout.
+
+ Fp Print points for halfspace intersections (option
+ 'Hn,n,...'). Each intersection corresponds to a
+
+
+
+Geometry Center 2003/12/30 9
+
+
+
+qhull(1) qhull(1)
+
+
+ facet of the dual polytope. The "infinity" point
+ [-10.101,-10.101,...] indicates an unbounded
+ intersection.
+
+ FP For each coplanar point ('Qc') print the point id
+ of the nearest vertex, the point id, the facet id,
+ and the distance.
+
+ FQ Print command used for qhull and input.
+
+ Fs Print a summary. The first line consists of the
+ number of integers ("7"), followed by the dimen-
+ sion, the number of points, the number of vertices,
+ the number of facets, the number of vertices
+ selected for output, the number of facets selected
+ for output, the number of coplanar points selected
+ for output.
+
+ The second line consists of the number of reals
+ ("2"), followed by the maxmimum offset to an outer
+ plane and and minimum offset to an inner plane.
+ Roundoff is included. Later versions of Qhull may
+ produce additional integers or reals.
+
+ FS Print the size of the hull. The first line con-
+ sists of the number of integers ("0"). The second
+ line consists of the number of reals ("2"), fol-
+ lowed by the total facet area, and the total vol-
+ ume. Later versions of Qhull may produce addi-
+ tional integers or reals.
+
+ The total volume measures the volume of the inter-
+ section of the halfspaces defined by each facet.
+ Both area and volume are approximations for non-
+ simplicial facets. See option 'Fa'.
+
+ Ft Print a triangulation with added points for non-
+ simplicial facets. The first line is the dimension
+ and the second line is the number of points and the
+ number of facets. The points follow, one per line,
+ then the facets follow as a list of point indices.
+ With option points include the point-at-infinity.
+
+ Fv Print vertices for each facet. The first line is
+ the number of facets. Then each facet is printed,
+ one per line. Each line is the number of vertices
+ followed by the corresponding point ids. Vertices
+ are listed in the order they were added to the hull
+ (the last one is first).
+
+ Fv Print all ridges of a Voronoi diagram. The first
+ line is the number of ridges. Then each ridge is
+ printed, one per line. A line starts with the num-
+ ber of indices. The first pair lists adjacent
+
+
+
+Geometry Center 2003/12/30 10
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ input sites, the remaining indices list Voronoi
+ vertices. Vertex '0' indicates the vertex-at-
+ infinity (i.e., an unbounded ray). In 3-d, the
+ vertices are listed in order. See 'Fi' and 'Fo'
+ for separating hyperplanes.
+
+ FV Print average vertex. The average vertex is a fea-
+ sible point for halfspace intersection.
+
+ Fx List extreme points (vertices) of the convex hull.
+ The first line is the number of points. The other
+ lines give the indices of the corresponding points.
+ The first point is '0'. In 2-d, the points occur
+ in counter-clockwise order; otherwise they occur in
+ input order. For Delaunay triangulations, 'Fx'
+ lists the extreme points of the input sites. The
+ points are unordered.
+
+
+ Geomview options
+
+ G Produce a file for viewing with Geomview. Without
+ other options, Qhull displays edges in 2-d, outer
+ planes in 3-d, and ridges in 4-d. A ridge can be
+ explicit or implicit. An explicit ridge is a dim-1
+ dimensional simplex between two facets. In 4-d,
+ the explicit ridges are triangles. When displaying
+ a ridge in 4-d, Qhull projects the ridge's vertices
+ to one of its facets' hyperplanes. Use 'Gh' to
+ project ridges to the intersection of both hyper-
+ planes.
+
+ Ga Display all input points as dots.
+
+ Gc Display the centrum for each facet in 3-d. The
+ centrum is defined by a green radius sitting on a
+ blue plane. The plane corresponds to the facet's
+ hyperplane. The radius is defined by 'C-n' or
+ 'Cn'.
+
+ GDn Drop dimension n in 3-d or 4-d. The result is a
+ 2-d or 3-d object.
+
+ Gh Display hyperplane intersections in 3-d and 4-d.
+ In 3-d, the intersection is a black line. It lies
+ on two neighboring hyperplanes (c.f., the blue
+ squares associated with centrums ('Gc')). In 4-d,
+ the ridges are projected to the intersection of
+ both hyperplanes.
+
+ Gi Display inner planes in 2-d and 3-d. The inner
+ plane of a facet is below all of its vertices. It
+ is parallel to the facet's hyperplane. The inner
+ plane's color is the opposite (1-r,1-g,1-b) of the
+
+
+
+Geometry Center 2003/12/30 11
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ outer plane. Its edges are determined by the ver-
+ tices.
+
+ Gn Do not display inner or outer planes. By default,
+ Geomview displays the precise plane (no merging) or
+ both inner and output planes (merging). Under
+ merging, Geomview does not display the inner plane
+ if the the difference between inner and outer is
+ too small.
+
+ Go Display outer planes in 2-d and 3-d. The outer
+ plane of a facet is above all input points. It is
+ parallel to the facet's hyperplane. Its color is
+ determined by the facet's normal, and its edges are
+ determined by the vertices.
+
+ Gp Display coplanar points and vertices as radii. A
+ radius defines a ball which corresponds to the
+ imprecision of the point. The imprecision is the
+ maximum of the roundoff error, the centrum radius,
+ and maxcoord * (1-An). It is at least 1/20'th of
+ the maximum coordinate, and ignores post-merging if
+ pre-merging is done.
+
+ Gr Display ridges in 3-d. A ridge connects the two
+ vertices that are shared by neighboring facets.
+ Ridges are always displayed in 4-d.
+
+ Gt A 3-d Delaunay triangulation looks like a convex
+ hull with interior facets. Option 'Gt' removes the
+ outside ridges to reveal the outermost facets. It
+ automatically sets options 'Gr' and 'GDn'.
+
+ Gv Display vertices as spheres. The radius of the
+ sphere corresponds to the imprecision of the data.
+ See 'Gp' for determining the radius.
+
+
+ Print options
+
+ PAn Only the n largest facets are marked good for
+ printing. Unless 'PG' is set, 'Pg' is automati-
+ cally set.
+
+ Pdk:n Drop facet from output if normal[k] <= n. The
+ option 'Pdk' uses the default value of 0 for n.
+
+ PDk:n Drop facet from output if normal[k] >= n. The
+ option 'PDk' uses the default value of 0 for n.
+
+ PFn Only facets with area at least 'n' are marked good
+ for printing. Unless 'PG' is set, 'Pg' is automat-
+ ically set.
+
+
+
+
+Geometry Center 2003/12/30 12
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ Pg Print only good facets. A good facet is either
+ visible from a point (the 'QGn' option) or includes
+ a point (the 'QVn' option). It also meets the
+ requirements of 'Pdk' and 'PDk' options. Option
+ 'Pg' is automatically set for options 'PAn' and
+ 'PFn'.
+
+ PG Print neighbors of good facets.
+
+ PMn Only the n facets with the most merges are marked
+ good for printing. Unless 'PG' is set, 'Pg' is
+ automatically set.
+
+ Po Force output despite precision problems. Verify ('Tv') does not check
+ coplanar points. Flipped facets are reported and
+ concave facets are counted. If 'Po' is used,
+ points are not partitioned into flipped facets and
+ a flipped facet is always visible to a point.
+ Also, if an error occurs before the completion of
+ Qhull and tracing is not active, 'Po' outputs a
+ neighborhood of the erroneous facets (if any).
+
+ Pp Do not report precision problems.
+
+
+ Qhull control options
+
+ Qbk:0Bk:0
+ Drop dimension k from the input points. This
+ allows the user to take convex hulls of sub-dimen-
+ sional objects. It happens before the Delaunay and
+ Voronoi transformation.
+
+ QbB Scale the input points to fit the unit cube. After
+ scaling, the lower bound will be -0.5 and the upper
+ bound +0.5 in all dimensions. For Delaunay and
+ Voronoi diagrams, scaling happens after projection
+ to the paraboloid. Under precise arithmetic, scal-
+ ing does not change the topology of the convex
+ hull.
+
+ Qbb Scale the last coordinate to [0, m] where m is the
+ maximum absolute value of the other coordinates.
+ For Delaunay and Voronoi diagrams, scaling happens
+ after projection to the paraboloid. It reduces
+ roundoff error for inputs with integer coordinates.
+ Under precise arithmetic, scaling does not change
+ the topology of the convex hull.
+
+ Qbk:n Scale the k'th coordinate of the input points.
+ After scaling, the lower bound of the input points
+ will be n. 'Qbk' scales to -0.5.
+
+
+
+Geometry Center 2003/12/30 13
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ QBk:n Scale the k'th coordinate of the input points.
+ After scaling, the upper bound will be n. 'QBk'
+ scales to +0.5.
+
+ Qc Keep coplanar points with the nearest facet. Out-
+ put formats 'p', 'f', 'Gp', 'Fc', 'FN', and 'FP'
+ will print the points.
+
+ Qf Partition points to the furthest outside facet.
+
+ Qg Only build good facets. With the 'Qg' option,
+ Qhull will only build those facets that it needs to
+ determine the good facets in the output. See
+ 'QGn', 'QVn', and 'PdD' for defining good facets,
+ and 'Pg' and 'PG' for printing good facets and
+ their neighbors.
+
+ QGn A facet is good (see 'Qg' and 'Pg') if it is visi-
+ ble from point n. If n < 0, a facet is good if it
+ is not visible from point n. Point n is not added
+ to the hull (unless 'TCn' or 'TPn'). With rbox,
+ use the 'Pn,m,r' option to define your point; it
+ will be point 0 (QG0).
+
+ Qi Keep interior points with the nearest facet. Out-
+ put formats 'p', 'f', 'Gp', 'FN', 'FP', and 'Fc'
+ will print the points.
+
+ QJn Joggle each input coordinate by adding a random
+ number in [-n,n]. If a precision error occurs,
+ then qhull increases n and tries again. It does
+ not increase n beyond a certain value, and it stops
+ after a certain number of attempts [see user.h].
+ Option 'QJ' selects a default value for n. The
+ output will be simplicial. For Delaunay triangula-
+ tions, 'QJn' sets 'Qbb' to scale the last coordi-
+ nate (not if 'Qbk:n' or 'QBk:n' is set). 'QJn' is
+ deprecated for Voronoi diagrams. See also 'Qt'.
+
+ Qm Only process points that would otherwise increase
+ max_outside. Other points are treated as coplanar
+ or interior points.
+
+ Qr Process random outside points instead of furthest
+ ones. This makes Qhull equivalent to the random-
+ ized incremental algorithms. CPU time is not
+ reported since the randomization is inefficient.
+
+ QRn Randomly rotate the input points. If n=0, use time
+ as the random number seed. If n>0, use n as the
+ random number seed. If n=-1, don't rotate but use
+ time as the random number seed. For Delaunay tri-
+ angulations ('d' and 'v'), rotate about the last
+ axis.
+
+
+
+
+Geometry Center 2003/12/30 14
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ Qs Search all points for the initial simplex.
+
+ Qt Triangulated output. Triangulate non-simplicial
+ facets. 'Qt' is deprecated for Voronoi diagrams.
+ See also 'QJn'
+
+ Qv Test vertex neighbors for convexity after post-
+ merging. To use the 'Qv' option, you also need to
+ set a merge option (e.g., 'Qx' or 'C-0').
+
+ QVn A good facet (see 'Qg' and 'Pg') includes point n.
+ If n<0, then a good facet does not include point n.
+ The point is either in the initial simplex or it is
+ the first point added to the hull. Option 'QVn'
+ may not be used with merging.
+
+ Qx Perform exact merges while building the hull. The
+ "exact" merges are merging a point into a coplanar
+ facet (defined by 'Vn', 'Un', and 'C-n'), merging
+ concave facets, merging duplicate ridges, and merg-
+ ing flipped facets. Coplanar merges and angle
+ coplanar merges ('A-n') are not performed. Concav-
+ ity testing is delayed until a merge occurs.
+
+ After the hull is built, all coplanar merges are
+ performed (defined by 'C-n' and 'A-n'), then post-
+ merges are performed (defined by 'Cn' and 'An').
+
+ Qz Add a point "at infinity" that is above the
+ paraboloid for Delaunay triangulations and Voronoi
+ diagrams. This reduces precision problems and
+ allows the triangulation of cospherical points.
+
+
+ Qhull experiments and speedups
+
+ Q0 Turn off pre-merging as a default option. With
+ 'Q0'/'Qx' and without explicit pre-merge options,
+ Qhull ignores precision issues while constructing
+ the convex hull. This may lead to precision
+ errors. If so, a descriptive warning is generated.
+
+ Q1 With 'Q1', Qhull sorts merges by type (coplanar,
+ angle coplanar, concave) instead of by angle.
+
+ Q2 With 'Q2', Qhull merges all facets at once instead
+ of using independent sets of merges and then
+ retesting.
+
+ Q3 With 'Q3', Qhull does not remove redundant ver-
+ tices.
+
+ Q4 With 'Q4', Qhull avoids merges of an old facet into
+ a new facet.
+
+ Q5 With 'Q5', Qhull does not correct outer planes at
+ the end. The maximum outer plane is used instead.
+
+
+
+
+Geometry Center 2003/12/30 15
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ Q6 With 'Q6', Qhull does not pre-merge concave or
+ coplanar facets.
+
+ Q7 With 'Q7', Qhull processes facets in depth-first
+ order instead of breadth-first order.
+
+ Q8 With 'Q8' and merging, Qhull does not retain near-
+ interior points for adjusting outer planes. 'Qc'
+ will probably retain all points that adjust outer
+ planes.
+
+ Q9 With 'Q9', Qhull processes the furthest of all out-
+ side sets at each iteration.
+
+ Q10 With 'Q10', Qhull does not use special processing
+ for narrow distributions.
+
+ Q11 With 'Q11', Qhull copies normals and recomputes
+ centrums for tricoplanar facets.
+
+ Q12 With 'Q12', Qhull does not report a very wide merge due
+ to a duplicated ridge with nearly coincident vertices
+
+ Trace options
+
+ Tn Trace at level n. Qhull includes full execution
+ tracing. 'T-1' traces events. 'T1' traces the
+ overall execution of the program. 'T2' and 'T3'
+ trace overall execution and geometric and topologi-
+ cal events. 'T4' traces the algorithm. 'T5'
+ includes information about memory allocation and
+ Gaussian elimination.
+
+ Ta Annotate output with codes that identify the
+ corresponding qh_fprintf() statement.
+
+ Tc Check frequently during execution. This will catch
+ most inconsistency errors.
+
+ TCn Stop Qhull after building the cone of new facets
+ for point n. The output for 'f' includes the cone
+ and the old hull. See also 'TVn'.
+
+ TFn Report progress whenever more than n facets are
+ created During post-merging, 'TFn' reports progress
+ after more than n/2 merges.
+
+ TI file
+ Input data from 'file'. The filename may not include
+ spaces or quotes.
+
+ TO file
+ Output results to 'file'. The name may be enclosed
+ in single quotes.
+
+ TPn Turn on tracing when point n is added to the hull.
+ Trace partitions of point n. If used with TWn, turn off
+ tracing after adding point n to the hull.
+
+ TRn Rerun qhull n times. Usually used with 'QJn' to
+ determine the probability that a given joggle will
+ fail.
+
+ Ts Collect statistics and print to stderr at the end
+ of execution.
+
+ Tv Verify the convex hull. This checks the topologi-
+ cal structure, facet convexity, and point inclu-
+ sion. If precision problems occurred, facet con-
+ vexity is tested whether or not 'Tv' is selected.
+ Option 'Tv' does not check point inclusion if
+
+
+
+Geometry Center 2003/12/30 16
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ forcing output with 'Po', or if 'Q5' is set.
+
+ For point inclusion testing, Qhull verifies that
+ all points are below all outer planes (facet->max-
+ outside). Point inclusion is exhaustive if merging
+ or if the facet-point product is small enough; oth-
+ erwise Qhull verifies each point with a directed
+ search (qh_findbest).
+
+ Point inclusion testing occurs after producing out-
+ put. It prints a message to stderr unless option
+ 'Pp' is used. This allows the user to interrupt
+ Qhull without changing the output.
+
+ TVn Stop Qhull after adding point n. If n < 0, stop
+ Qhull before adding point n. Output shows the hull
+ at this time. See also 'TCn'
+
+ TMn Turn on tracing at n'th merge.
+
+ TWn Trace merge facets when the width is greater than
+ n.
+
+ Tz Redirect stderr to stdout.
+
+
+BUGS
+ Please report bugs to Brad Barber at
+ qhull_bug@qhull.org.
+
+ If Qhull does not compile, it is due to an incompatibility
+ between your system and ours. The first thing to check is
+ that your compiler is ANSI standard. If it is, check the
+ man page for the best options, or find someone to help
+ you. If you locate the cause of your problem, please send
+ email since it might help others.
+
+ If Qhull compiles but crashes on the test case (rbox D4),
+ there's still incompatibility between your system and
+ ours. Typically it's been due to mem.c and memory align-
+ ment. You can use qh_NOmem in mem.h to turn off memory
+ management. Please let us know if you figure out how to
+ fix these problems.
+
+ If you do find a problem, try to simplify it before
+ reporting the error. Try different size inputs to locate
+ the smallest one that causes an error. You're welcome to
+ hunt through the code using the execution trace as a
+ guide. This is especially true if you're incorporating
+ Qhull into your own program.
+
+ When you do report an error, please attach a data set to
+ the end of your message. This allows us to see the error
+ for ourselves. Qhull is maintained part-time.
+
+
+
+Geometry Center 2003/12/30 17
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+E-MAIL
+ Please send correspondence to qhull@qhull.org and
+ report bugs to qhull_bug@qhull.org. Let us know how
+ you use Qhull. If you mention it in a paper, please send
+ the reference and an abstract.
+
+ If you would like to get Qhull announcements (e.g., a new
+ version) and news (any bugs that get fixed, etc.), let us
+ know and we will add you to our mailing list. If you
+ would like to communicate with other Qhull users, we will
+ add you to the qhull_users alias. For Internet news about
+ geometric algorithms and convex hulls, look at comp.graph-
+ ics.algorithms and sci.math.num-analysis
+
+
+SEE ALSO
+ rbox(1)
+
+ Barber, C. B., D.P. Dobkin, and H.T. Huhdanpaa, "The
+ Quickhull Algorithm for Convex Hulls," ACM Trans. on Math-
+ ematical Software, 22(4):469-483, Dec. 1996.
+ http://portal.acm.org/citation.cfm?doid=235815.235821
+ http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405
+
+
+ Clarkson, K.L., K. Mehlhorn, and R. Seidel, "Four results
+ on randomized incremental construction," Computational
+ Geometry: Theory and Applications, vol. 3, p. 185-211,
+ 1993.
+
+ Preparata, F. and M. Shamos, Computational Geometry,
+ Springer-Verlag, New York, 1985.
+
+
+
+AUTHORS
+ C. Bradford Barber Hannu Huhdanpaa
+ bradb@shore.net hannu@qhull.org
+
+
+
+ACKNOWLEDGEMENTS
+ A special thanks to Albert Marden, Victor Milenkovic, the
+ Geometry Center, Harvard University, and Endocardial Solu-
+ tions, Inc. for supporting this work.
+
+ Qhull 1.0 and 2.0 were developed under National Science Foundation
+ grants NSF/DMS-8920161 and NSF-CCR-91-15793 750-7504. David Dobkin
+
+
+
+Geometry Center 2003/12/30 18
+
+
+
+
+
+qhull(1) qhull(1)
+
+
+ guided the original work at Princeton University. If you find it
+ useful, please let us know.
+
+ The Geometry Center was supported by grant DMS-8920161 from the National
+ Science Foundation, by grant DOE/DE-FG02-92ER25137 from the Department
+ of Energy, by the University of Minnesota, and by Minnesota Technology, Inc.
+
+ Qhull is available from http://www.qhull.org
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Geometry Center 2003/12/30 19
+
+
diff --git a/xs/src/qhull/html/qvoron_f.htm b/xs/src/qhull/html/qvoron_f.htm
new file mode 100644
index 000000000..db538b5ab
--- /dev/null
+++ b/xs/src/qhull/html/qvoron_f.htm
@@ -0,0 +1,396 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>qvoronoi Qu -- furthest-site Voronoi diagram</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<a name="TOP"><b>Up</b></a><b>:</b>
+<a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/delaunay.html"><img
+src="qh--dt.gif" alt="[delaunay]" align="middle" width="100"
+height="100"></a>qvoronoi Qu -- furthest-site Voronoi diagram</h1>
+
+<p>The furthest-site Voronoi diagram is the furthest-neighbor map for a set of
+points. Each region contains those points that are further
+from one input site than any other input site. See the
+survey article by Aurenhammer [<a href="index.htm#aure91">'91</a>]
+and the brief introduction by O'Rourke [<a
+href="index.htm#orou94">'94</a>]. The furthest-site Voronoi diagram is the dual of the <a
+href="qdelau_f.htm">furthest-site Delaunay triangulation</a>.
+</p>
+
+<blockquote>
+<dl>
+ <dt><b>Example:</b> rbox 10 D2 | qvoronoi <a
+ href="qh-optq.htm#Qu">Qu</a> <a href="qh-opto.htm#s">s</a>
+ <a href="qh-opto.htm#o">o</a> <a href="qh-optt.htm#TO">TO
+ result</a></dt>
+ <dd>Compute the 2-d, furthest-site Voronoi diagram of 10
+ random points. Write a summary to the console and the Voronoi
+ regions and vertices to 'result'. The first vertex of the
+ result indicates unbounded regions. Almost all regions
+ are unbounded.</dd>
+</dl>
+
+<dl>
+ <dt><b>Example:</b> rbox r y c G1 D2 | qvoronoi <a
+ href="qh-optq.htm#Qu">Qu</a>
+ <a href="qh-opto.htm#s">s</a>
+ <a href="qh-optf.htm#Fn">Fn</a> <a href="qh-optt.htm#TO">TO
+ result</a></dt>
+ <dd>Compute the 2-d furthest-site Voronoi diagram of a square
+ and a small triangle. Write a summary to the console and the Voronoi
+ vertices for each input site to 'result'.
+ The origin is the only furthest-site Voronoi vertex. The
+ negative indices indicate vertices-at-infinity.</dd>
+</dl>
+</blockquote>
+
+<p>
+Qhull computes the furthest-site Voronoi diagram via the <a href="qdelau_f.htm">
+furthest-site Delaunay triangulation</a>.
+Each furthest-site Voronoi vertex is the circumcenter of an upper
+facet of the Delaunay triangulation. Each furthest-site Voronoi
+region corresponds to a vertex of the Delaunay triangulation
+(i.e., an input site).</p>
+
+<p>See <a href="http://www.qhull.org/html/qh-faq.htm#TOC">Qhull FAQ</a> - Delaunay and
+Voronoi diagram questions.</p>
+
+<p>The 'qvonoroi' program is equivalent to
+'<a href=qhull.htm#outputs>qhull v</a> <a href=qh-optq.htm#Qbb>Qbb</a>' in 2-d to 3-d, and
+'<a href=qhull.htm#outputs>qhull v</a> <a href=qh-optq.htm#Qbb>Qbb</a> <a href=qh-optq.htm#Qx>Qx</a>'
+in 4-d and higher. It disables the following Qhull
+<a href=qh-quick.htm#options>options</a>: <i>d n m v H U Qb
+QB Qc Qf Qg Qi Qm Qr QR Qv Qx TR E V Fa FA FC Fp FS Ft FV Gt Q0,etc</i>.
+
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<hr>
+<h3><a href="#TOP">&#187;</a><a name="synopsis">furthest-site qvoronoi synopsis</a></h3>
+<blockquote>
+
+See <a href="qvoronoi.htm#synopsis">qvoronoi synopsis</a>. The same
+program is used for both constructions. Use option '<a href="qh-optq.htm#Qu">Qu</a>'
+for furthest-site Voronoi diagrams.
+
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="input">furthest-site qvoronoi
+input</a></h3>
+<blockquote>
+<p>The input data on <tt>stdin</tt> consists of:</p>
+<ul>
+ <li>dimension
+ <li>number of points</li>
+ <li>point coordinates</li>
+</ul>
+
+<p>Use I/O redirection (e.g., qvoronoi Qu &lt; data.txt), a pipe (e.g., rbox 10 | qvoronoi Qu),
+or the '<a href=qh-optt.htm#TI>TI</a>' option (e.g., qvoronoi TI data.txt Qu).
+
+<p>For example, this is a square containing four random points.
+Its furthest-site Voronoi diagram has on vertex and four unbounded,
+separating hyperplanes (i.e., the coordinate axes)
+<p>
+<blockquote>
+<tt>rbox c 4 D2 &gt; data</tt>
+<blockquote><pre>
+2 RBOX c 4 D2
+8
+-0.4999921736307369 -0.3684622117955817
+0.2556053225468894 -0.0413498678629751
+0.0327672376602583 -0.2810408135699488
+-0.452955383763607 0.17886471718444
+ -0.5 -0.5
+ -0.5 0.5
+ 0.5 -0.5
+ 0.5 0.5
+</pre></blockquote>
+
+<p><tt>qvoronoi Qu s Fo &lt; data</tt>
+<blockquote><pre>
+
+Furthest-site Voronoi vertices by the convex hull of 8 points in 3-d:
+
+ Number of Voronoi regions: 8
+ Number of Voronoi vertices: 1
+ Number of non-simplicial Voronoi vertices: 1
+
+Statistics for: RBOX c 4 D2 | QVORONOI Qu s Fo
+
+ Number of points processed: 8
+ Number of hyperplanes created: 20
+ Number of facets in hull: 11
+ Number of distance tests for qhull: 34
+ Number of merged facets: 1
+ Number of distance tests for merging: 107
+ CPU seconds to compute hull (after input): 0
+
+4
+5 4 5 0 1 0
+5 4 6 1 0 0
+5 5 7 1 0 0
+5 6 7 0 1 0
+</pre></blockquote>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a> <a name="outputs">furthest-site qvoronoi
+outputs</a></h3>
+<blockquote>
+
+<p>These options control the output of furthest-site Voronoi diagrams.</p>
+<blockquote>
+
+<dl compact>
+ <dt>&nbsp;</dt>
+ <dd><b>furthest-site Voronoi vertices</b></dd>
+ <dt><a href="qh-opto.htm#p">p</a></dt>
+ <dd>print the coordinates of the furthest-site Voronoi vertices. The first line
+ is the dimension. The second line is the number of vertices. Each
+ remaining line is a furthest-site Voronoi vertex. The points-in-square example
+ has one furthest-site Voronoi vertex at the origin.</dd>
+ <dt><a href="qh-optf.htm#Fn">Fn</a></dt>
+ <dd>list the neighboring furthest-site Voronoi vertices for each furthest-site Voronoi
+ vertex. The first line is the number of Voronoi vertices. Each
+ remaining line starts with the number of neighboring vertices. Negative indices (e.g., <em>-1</em>) indicate vertices
+ outside of the Voronoi diagram. In the points-in-square example, the
+ Voronoi vertex at the origin has four neighbors-at-infinity.</dd>
+ <dt><a href="qh-optf.htm#FN">FN</a></dt>
+ <dd>list the furthest-site Voronoi vertices for each furthest-site Voronoi region. The first line is
+ the number of Voronoi regions. Each remaining line starts with the
+ number of Voronoi vertices. Negative indices (e.g., <em>-1</em>) indicate vertices
+ outside of the Voronoi diagram.
+ In the points-in-square example, all regions share the Voronoi vertex
+ at the origin.</dd>
+
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>furthest-site Voronoi regions</b></dd>
+ <dt><a href="qh-opto.htm#o">o</a></dt>
+ <dd>print the furthest-site Voronoi regions in OFF format. The first line is the
+ dimension. The second line is the number of vertices, the number
+ of input sites, and "1". The third line represents the vertex-at-infinity.
+ Its coordinates are "-10.101". The next lines are the coordinates
+ of the furthest-site Voronoi vertices. Each remaining line starts with the number
+ of Voronoi vertices in a Voronoi region. In 2-d, the vertices are
+listed in adjacency order (unoriented). In 3-d and higher, the
+vertices are listed in numeric order. In the points-in-square
+ example, each unbounded region includes the Voronoi vertex at
+ the origin. Lines consisting of <em>0</em> indicate
+ interior input sites. </dd>
+ <dt><a href="qh-optf.htm#Fi2">Fi</a></dt>
+ <dd>print separating hyperplanes for inner, bounded furthest-site Voronoi
+ regions. The first number is the number of separating
+ hyperplanes. Each remaining line starts with <i>3+dim</i>. The
+ next two numbers are adjacent input sites. The next <i>dim</i>
+ numbers are the coefficients of the separating hyperplane. The
+ last number is its offset. The are no bounded, separating hyperplanes
+ for the points-in-square example.</dd>
+ <dt><a href="qh-optf.htm#Fo2">Fo</a></dt>
+ <dd>print separating hyperplanes for outer, unbounded furthest-site Voronoi
+ regions. The first number is the number of separating
+ hyperplanes. Each remaining line starts with <i>3+dim</i>. The
+ next two numbers are adjacent input sites on the convex hull. The
+ next <i>dim</i>
+ numbers are the coefficients of the separating hyperplane. The
+ last number is its offset. The points-in-square example has four
+ unbounded, separating hyperplanes.</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Input sites</b></dd>
+ <dt><a href="qh-optf.htm#Fv2">Fv</a></dt>
+ <dd>list ridges of furthest-site Voronoi vertices for pairs of input sites. The
+ first line is the number of ridges. Each remaining line starts with
+ two plus the number of Voronoi vertices in the ridge. The next
+ two numbers are two adjacent input sites. The remaining numbers list
+ the Voronoi vertices. As with option 'o', a <em>0</em> indicates
+ the vertex-at-infinity
+ and an unbounded, separating hyperplane.
+ The perpendicular bisector (separating hyperplane)
+ of the input sites is a flat through these vertices.
+ In the points-in-square example, the ridge for each edge of the square
+ is unbounded.</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a href="qh-opto.htm#s">s</a></dt>
+ <dd>print summary of the furthest-site Voronoi diagram. Use '<a
+ href="qh-optf.htm#Fs">Fs</a>' for numeric data.</dd>
+ <dt><a href="qh-opto.htm#i">i</a></dt>
+ <dd>list input sites for each <a href=qdelau_f.htm>furthest-site Delaunay region</a>. Use option '<a href="qh-optp.htm#Pp">Pp</a>'
+ to avoid the warning. The first line is the number of regions. The
+ remaining lines list the input sites for each region. The regions are
+ oriented. In the points-in-square example, the square region has four
+ input sites. In 3-d and higher, report cospherical sites by adding extra points.
+ </dd>
+ <dt><a href="qh-optg.htm#G">G</a></dt>
+ <dd>Geomview output for 2-d furthest-site Voronoi diagrams.</dd>
+ </dl>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a> <a name="controls">furthest-site qvoronoi
+controls</a></h3>
+<blockquote>
+
+<p>These options provide additional control:</p>
+<blockquote>
+
+<dl compact>
+ <dt><a href="qh-optq.htm#Qu">Qu</a></dt>
+ <dd>must be used.</dd>
+ <dt><a href="qh-optq.htm#QVn">QVn</a></dt>
+ <dd>select furthest-site Voronoi vertices for input site <em>n</em> </dd>
+ <dt><a href="qh-optt.htm#Tv">Tv</a></dt>
+ <dd>verify result</dd>
+ <dt><a href="qh-optt.htm#TO">TI file</a></dt>
+ <dd>input data from file. The filename may not use spaces or quotes.</dd>
+ <dt><a href="qh-optt.htm#TO">TO file</a></dt>
+ <dd>output results to file. Use single quotes if the filename
+ contains spaces (e.g., <tt>TO 'file with spaces.txt'</tt></dd>
+ <dt><a href="qh-optt.htm#TFn">TFn</a></dt>
+ <dd>report progress after constructing <em>n</em> facets</dd>
+ <dt><a href="qh-optp.htm#PDk">PDk:1</a></dt>
+ <dd>include upper and lower facets in the output. Set <em>k</em>
+ to the last dimension (e.g., 'PD2:1' for 2-d inputs). </dd>
+ <dt><a href="qh-opto.htm#f">f </a></dt>
+ <dd>facet dump. Print the data structure for each facet (i.e.,
+ furthest-site Voronoi vertex).</dd>
+</dl>
+
+</blockquote>
+</blockquote>
+<h3><a href="#TOP">&#187;</a> <a name="graphics">furthest-site qvoronoi
+graphics</a></h3>
+<blockquote>
+<p>In 2-d, Geomview output ('<a href="qh-optg.htm#G">G</a>')
+displays a furthest-site Voronoi diagram with extra edges to
+close the unbounded furthest-site Voronoi regions. All regions
+will be unbounded. Since the points-in-box example has only
+one furthest-site Voronoi vertex, the Geomview output is one
+point.</p>
+
+<p>See the <a href="qh-eg.htm#delaunay">Delaunay and Voronoi
+examples</a> for a 2-d example. Turn off normalization (on
+Geomview's 'obscure' menu) when comparing the furthest-site
+Voronoi diagram with the corresponding Voronoi diagram. </p>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="notes">furthest-site qvoronoi
+notes</a></h3>
+<blockquote>
+
+<p>See <a href="qvoronoi.htm#notes">Voronoi notes</a>.</p>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="conventions">furthest-site qvoronoi conventions</a></h3>
+<blockquote>
+
+<p>The following terminology is used for furthest-site Voronoi
+diagrams in Qhull. The underlying structure is a furthest-site
+Delaunay triangulation from a convex hull in one higher
+dimension. Upper facets of the Delaunay triangulation correspond
+to vertices of the furthest-site Voronoi diagram. Vertices of the
+furthest-site Delaunay triangulation correspond to input sites.
+They also define regions of the furthest-site Voronoi diagram.
+All vertices are extreme points of the input sites. See <a
+href="qconvex.htm#conventions">qconvex conventions</a>, <a
+href="qdelau_f.htm#conventions">furthest-site delaunay
+conventions</a>, and <a href="index.htm#structure">Qhull's data structures</a>.</p>
+
+<ul>
+ <li><em>input site</em> - a point in the input (one dimension
+ lower than a point on the convex hull)</li>
+ <li><em>point</em> - a point has <i>d+1</i> coordinates. The
+ last coordinate is the sum of the squares of the input
+ site's coordinates</li>
+ <li><em>vertex</em> - a point on the upper facets of the
+ paraboloid. It corresponds to a unique input site. </li>
+ <li><em>furthest-site Delaunay facet</em> - an upper facet of the
+ paraboloid. The last coefficient of its normal is
+ clearly positive.</li>
+ <li><em>furthest-site Voronoi vertex</em> - the circumcenter
+ of a furthest-site Delaunay facet</li>
+ <li><em>furthest-site Voronoi region</em> - the region of
+ Euclidean space further from an input site than any other
+ input site. Qhull lists the furthest-site Voronoi
+ vertices that define each furthest-site Voronoi region.</li>
+ <li><em>furthest-site Voronoi diagram</em> - the graph of the
+ furthest-site Voronoi regions with the ridges (edges)
+ between the regions.</li>
+ <li><em>infinity vertex</em> - the Voronoi vertex for
+ unbounded furthest-site Voronoi regions in '<a
+ href="qh-opto.htm#o">o</a>' output format. Its
+ coordinates are <em>-10.101</em>.</li>
+ <li><em>good facet</em> - an furthest-site Voronoi vertex with
+ optional restrictions by '<a href="qh-optq.htm#QVn">QVn</a>',
+ etc.</li>
+</ul>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="options">furthest-site qvoronoi options</a></h3>
+<blockquote>
+
+See <a href="qvoronoi.htm#options">qvoronoi options</a>. The same
+program is used for both constructions. Use option '<a href="qh-optq.htm#Qu">Qu</a>'
+for furthest-site Voronoi diagrams.
+</blockquote>
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/qvoronoi.htm b/xs/src/qhull/html/qvoronoi.htm
new file mode 100644
index 000000000..6d81d48c1
--- /dev/null
+++ b/xs/src/qhull/html/qvoronoi.htm
@@ -0,0 +1,667 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>qvoronoi -- Voronoi diagram</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<a name="TOP"><b>Up</b></a><b>:</b>
+<a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.archinect.com/gallery/displayimage.php?pos=-4658"><img
+src="normal_voronoi_knauss_oesterle.jpg" alt="[voronoi]" align="middle"
+height="100"></a>qvoronoi -- Voronoi diagram</h1>
+
+<p>The Voronoi diagram is the nearest-neighbor map for a set of
+points. Each region contains those points that are nearer
+one input site than any other input site. It has many useful properties and applications. See the
+survey article by Aurenhammer [<a href="index.htm#aure91">'91</a>]
+and the detailed introduction by O'Rourke [<a
+href="index.htm#orou94">'94</a>]. The Voronoi diagram is the
+dual of the <a href=qdelaun.htm>Delaunay triangulation</a>. </p>
+
+<blockquote>
+<dl>
+ <dt><b>Example:</b> rbox 10 D3 | qvoronoi <a href="qh-opto.htm#s">s</a>
+ <a href="qh-opto.htm#o">o</a> <a href="qh-optt.htm#TO">TO
+ result</a></dt>
+ <dd>Compute the 3-d Voronoi diagram of 10 random points. Write a
+ summary to the console and the Voronoi vertices and
+ regions to 'result'. The first vertex of the result
+ indicates unbounded regions.</dd>
+
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox r y c G0.1 D2 | qvoronoi
+ <a href="qh-opto.htm#s">s</a>
+ <a href="qh-opto.htm#o">o</a> <a href="qh-optt.htm#TO">TO
+ result</a></dt>
+ <dd>Compute the 2-d Voronoi diagram of a triangle and a small
+ square. Write a
+ summary to the console and Voronoi vertices and regions
+ to 'result'. Report a single Voronoi vertex for
+ cocircular input sites. The first vertex of the result
+ indicates unbounded regions. The origin is the Voronoi
+ vertex for the square.</dd>
+
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox r y c G0.1 D2 | qvoronoi <a href="qh-optf.htm#Fv2">Fv</a>
+ <a href="qh-optt.htm#TO">TO result</a></dt>
+ <dd>Compute the 2-d Voronoi diagram of a triangle and a small
+ square. Write a
+ summary to the console and the Voronoi ridges to
+ 'result'. Each ridge is the perpendicular bisector of a
+ pair of input sites. Vertex &quot;0&quot; indicates
+ unbounded ridges. Vertex &quot;8&quot; is the Voronoi
+ vertex for the square.</dd>
+
+ <dt>&nbsp;</dt>
+ <dt><b>Example:</b> rbox r y c G0.1 D2 | qvoronoi <a href="qh-optf.htm#Fi2">Fi</a></dt>
+ <dd>Print the bounded, separating hyperplanes for the 2-d Voronoi diagram of a
+ triangle and a small
+ square. Note the four hyperplanes (i.e., lines) for Voronoi vertex
+ &quot;8&quot;. It is at the origin.
+ </dd>
+</dl>
+</blockquote>
+
+<p>Qhull computes the Voronoi diagram via the <a href="qdelaun.htm">Delaunay
+triangulation</a>. Each Voronoi
+vertex is the circumcenter of a facet of the Delaunay
+triangulation. Each Voronoi region corresponds to a vertex (i.e., input site) of the
+Delaunay triangulation. </p>
+
+<p>Qhull outputs the Voronoi vertices for each Voronoi region. With
+option '<a href="qh-optf.htm#Fv2">Fv</a>',
+it lists all ridges of the Voronoi diagram with the corresponding
+pairs of input sites. With
+options '<a href="qh-optf.htm#Fi2">Fi</a>' and '<a href="qh-optf.htm#Fo2">Fo</a>',
+it lists the bounded and unbounded separating hyperplanes.
+You can also output a single Voronoi region
+for further processing [see <a href="#graphics">graphics</a>].</p>
+
+<p>Use option '<a href="qh-optq.htm#Qz">Qz</a>' if the input is circular, cospherical, or
+nearly so. It improves precision by adding a point "at infinity," above the corresponding paraboloid.
+
+<p>See <a href="http://www.qhull.org/html/qh-faq.htm#TOC">Qhull FAQ</a> - Delaunay and
+Voronoi diagram questions.</p>
+
+<p>The 'qvonoroi' program is equivalent to
+'<a href=qhull.htm#outputs>qhull v</a> <a href=qh-optq.htm#Qbb>Qbb</a>' in 2-d to 3-d, and
+'<a href=qhull.htm#outputs>qhull v</a> <a href=qh-optq.htm#Qbb>Qbb</a> <a href=qh-optq.htm#Qx>Qx</a>'
+in 4-d and higher. It disables the following Qhull
+<a href=qh-quick.htm#options>options</a>: <i>d n v Qbb QbB Qf Qg Qm
+Qr QR Qv Qx Qz TR E V Fa FA FC FD FS Ft FV Gt Q0,etc</i>.
+
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+
+<p>Voronoi image by KOOK Architecture, Silvan Oesterle and Michael Knauss.
+
+<hr>
+<h3><a href="#TOP">&#187;</a><a name="synopsis">qvoronoi synopsis</a></h3>
+
+<pre>
+qvoronoi- compute the Voronoi diagram.
+ input (stdin): dimension, number of points, point coordinates
+ comments start with a non-numeric character
+
+options (qh-voron.htm):
+ Qu - compute furthest-site Voronoi diagram
+ Tv - verify result: structure, convexity, and in-circle test
+ . - concise list of all options
+ - - one-line description of all options
+
+output options (subset):
+ s - summary of results (default)
+ p - Voronoi vertices
+ o - OFF file format (dim, Voronoi vertices, and Voronoi regions)
+ FN - count and Voronoi vertices for each Voronoi region
+ Fv - Voronoi diagram as Voronoi vertices between adjacent input sites
+ Fi - separating hyperplanes for bounded regions, 'Fo' for unbounded
+ G - Geomview output (2-d only)
+ QVn - Voronoi vertices for input point n, -n if not
+ TO file- output results to file, may be enclosed in single quotes
+
+examples:
+rbox c P0 D2 | qvoronoi s o rbox c P0 D2 | qvoronoi Fi
+rbox c P0 D2 | qvoronoi Fo rbox c P0 D2 | qvoronoi Fv
+rbox c P0 D2 | qvoronoi s Qu Fv rbox c P0 D2 | qvoronoi Qu Fo
+rbox c G1 d D2 | qvoronoi s p rbox c P0 D2 | qvoronoi s Fv QV0
+</pre>
+
+<h3><a href="#TOP">&#187;</a><a name="input">qvoronoi input</a></h3>
+<blockquote>
+The input data on <tt>stdin</tt> consists of:
+<ul>
+ <li>dimension
+ <li>number of points</li>
+ <li>point coordinates</li>
+</ul>
+
+<p>Use I/O redirection (e.g., qvoronoi &lt; data.txt), a pipe (e.g., rbox 10 | qvoronoi),
+or the '<a href=qh-optt.htm#TI>TI</a>' option (e.g., qvoronoi TI data.txt).
+
+<p>For example, this is four cocircular points inside a square. Their Voronoi
+diagram has nine vertices and eight regions. Notice the Voronoi vertex
+at the origin, and the Voronoi vertices (on each axis) for the four
+sides of the square.
+<p>
+<blockquote>
+<tt>rbox s 4 W0 c G1 D2 &gt; data</tt>
+<blockquote><pre>
+2 RBOX s 4 W0 c D2
+8
+-0.4941988586954018 -0.07594397977563715
+-0.06448037284989526 0.4958248496365813
+0.4911154367094632 0.09383830681375946
+-0.348353580869097 -0.3586778257652367
+ -1 -1
+ -1 1
+ 1 -1
+ 1 1
+</pre></blockquote>
+
+<p><tt>qvoronoi s p &lt; data</tt>
+<blockquote><pre>
+
+Voronoi diagram by the convex hull of 8 points in 3-d:
+
+ Number of Voronoi regions: 8
+ Number of Voronoi vertices: 9
+ Number of non-simplicial Voronoi vertices: 1
+
+Statistics for: RBOX s 4 W0 c D2 | QVORONOI s p
+
+ Number of points processed: 8
+ Number of hyperplanes created: 18
+ Number of facets in hull: 10
+ Number of distance tests for qhull: 33
+ Number of merged facets: 2
+ Number of distance tests for merging: 102
+ CPU seconds to compute hull (after input): 0.094
+
+2
+9
+4.217546450968612e-17 1.735507986399734
+-8.402566836762659e-17 -1.364368854147395
+0.3447488772716865 -0.6395484723719818
+1.719446929853986 2.136555906154247e-17
+0.4967882915039657 0.68662371396699
+-1.729928876283549 1.343733067524222e-17
+-0.8906163241424728 -0.4594150543829102
+-0.6656840313875723 0.5003013793414868
+-7.318364664277155e-19 -1.188217818408333e-16
+</pre></blockquote>
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a> <a name="outputs">qvoronoi
+outputs</a></h3>
+<blockquote>
+
+<p>These options control the output of Voronoi diagrams.</p>
+<blockquote>
+
+<dl compact>
+ <dt>&nbsp;</dt>
+ <dd><b>Voronoi vertices</b></dd>
+ <dt><a href="qh-opto.htm#p">p</a></dt>
+ <dd>print the coordinates of the Voronoi vertices. The first line
+ is the dimension. The second line is the number of vertices. Each
+ remaining line is a Voronoi vertex.</dd>
+ <dt><a href="qh-optf.htm#Fn">Fn</a></dt>
+ <dd>list the neighboring Voronoi vertices for each Voronoi
+ vertex. The first line is the number of Voronoi vertices. Each
+ remaining line starts with the number of neighboring vertices.
+ Negative vertices (e.g., <em>-1</em>) indicate vertices
+ outside of the Voronoi diagram.
+ In the circle-in-box example, the
+ Voronoi vertex at the origin has four neighbors.</dd>
+ <dt><a href="qh-optf.htm#FN">FN</a></dt>
+ <dd>list the Voronoi vertices for each Voronoi region. The first line is
+ the number of Voronoi regions. Each remaining line starts with the
+ number of Voronoi vertices. Negative indices (e.g., <em>-1</em>) indicate vertices
+ outside of the Voronoi diagram.
+ In the circle-in-box example, the four bounded regions are defined by four
+ Voronoi vertices.</dd>
+
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Voronoi regions</b></dd>
+ <dt><a href="qh-opto.htm#o">o</a></dt>
+ <dd>print the Voronoi regions in OFF format. The first line is the
+ dimension. The second line is the number of vertices, the number
+ of input sites, and "1". The third line represents the vertex-at-infinity.
+ Its coordinates are "-10.101". The next lines are the coordinates
+ of the Voronoi vertices. Each remaining line starts with the number
+ of Voronoi vertices in a Voronoi region. In 2-d, the vertices are
+listed in adjacency order (unoriented). In 3-d and higher, the
+vertices are listed in numeric order. In the circle-in-square
+ example, each bounded region includes the Voronoi vertex at
+ the origin. Lines consisting of <em>0</em> indicate
+ coplanar input sites or '<a href="qh-optq.htm#Qz">Qz</a>'. </dd>
+ <dt><a href="qh-optf.htm#Fi2">Fi</a></dt>
+ <dd>print separating hyperplanes for inner, bounded Voronoi
+ regions. The first number is the number of separating
+ hyperplanes. Each remaining line starts with <i>3+dim</i>. The
+ next two numbers are adjacent input sites. The next <i>dim</i>
+ numbers are the coefficients of the separating hyperplane. The
+ last number is its offset. Use '<a href="qh-optt.htm#Tv">Tv</a>' to verify that the
+hyperplanes are perpendicular bisectors. It will list relevant
+statistics to stderr. </dd>
+ <dt><a href="qh-optf.htm#Fo2">Fo</a></dt>
+ <dd>print separating hyperplanes for outer, unbounded Voronoi
+ regions. The first number is the number of separating
+ hyperplanes. Each remaining line starts with <i>3+dim</i>. The
+ next two numbers are adjacent input sites on the convex hull. The
+ next <i>dim</i>
+ numbers are the coefficients of the separating hyperplane. The
+ last number is its offset. Use '<a href="qh-optt.htm#Tv">Tv</a>' to verify that the
+hyperplanes are perpendicular bisectors. It will list relevant
+statistics to stderr,</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>Input sites</b></dd>
+ <dt><a href="qh-optf.htm#Fv2">Fv</a></dt>
+ <dd>list ridges of Voronoi vertices for pairs of input sites. The
+ first line is the number of ridges. Each remaining line starts with
+ two plus the number of Voronoi vertices in the ridge. The next
+ two numbers are two adjacent input sites. The remaining numbers list
+ the Voronoi vertices. As with option 'o', a <em>0</em> indicates
+ the vertex-at-infinity
+ and an unbounded, separating hyperplane.
+ The perpendicular bisector (separating hyperplane)
+ of the input sites is a flat through these vertices.
+ In the circle-in-square example, the ridge for each edge of the square
+ is unbounded.</dd>
+ <dt><a href="qh-optf.htm#Fc">Fc</a></dt>
+ <dd>list coincident input sites for each Voronoi vertex.
+ The first line is the number of vertices. The remaining lines start with
+ the number of coincident sites and deleted vertices. Deleted vertices
+ indicate highly degenerate input (see'<a href="qh-optf.htm#Fs">Fs</a>').
+ A coincident site is assigned to one Voronoi
+ vertex. Do not use '<a href="qh-optq.htm#QJn">QJ</a>' with 'Fc'; the joggle will separate
+ coincident sites.</dd>
+ <dt><a href="qh-optf.htm#FP">FP</a></dt>
+ <dd>print coincident input sites with distance to
+ nearest site (i.e., vertex). The first line is the
+ number of coincident sites. Each remaining line starts with the point ID of
+ an input site, followed by the point ID of a coincident point, its vertex, and distance.
+ Includes deleted vertices which
+ indicate highly degenerate input (see'<a href="qh-optf.htm#Fs">Fs</a>').
+ Do not use '<a href="qh-optq.htm#QJn">QJ</a>' with 'FP'; the joggle will separate
+ coincident sites.</dd>
+ <dt>&nbsp;</dt>
+ <dt>&nbsp;</dt>
+ <dd><b>General</b></dd>
+ <dt><a href="qh-opto.htm#s">s</a></dt>
+ <dd>print summary of the Voronoi diagram. Use '<a
+ href="qh-optf.htm#Fs">Fs</a>' for numeric data.</dd>
+ <dt><a href="qh-opto.htm#i">i</a></dt>
+ <dd>list input sites for each <a href=qdelaun.htm>Delaunay region</a>. Use option '<a href="qh-optp.htm#Pp">Pp</a>'
+ to avoid the warning. The first line is the number of regions. The
+ remaining lines list the input sites for each region. The regions are
+ oriented. In the circle-in-square example, the cocircular region has four
+ edges. In 3-d and higher, report cospherical sites by adding extra points.
+ </dd>
+ <dt><a href="qh-optg.htm#G">G</a></dt>
+ <dd>Geomview output for 2-d Voronoi diagrams.</dd>
+ </dl>
+</blockquote>
+</blockquote>
+<h3><a href="#TOP">&#187;</a> <a name="controls">qvoronoi
+controls</a></h3>
+<blockquote>
+
+<p>These options provide additional control:</p>
+<blockquote>
+
+<dl compact>
+ <dt><a href="qh-optq.htm#Qu">Qu</a></dt>
+ <dd>compute the <a href="qvoron_f.htm">furthest-site Voronoi diagram</a>.</dd>
+ <dt><a href="qh-optq.htm#QVn">QVn</a></dt>
+ <dd>select Voronoi vertices for input site <em>n</em> </dd>
+ <dt><a href="qh-optq.htm#Qz">Qz</a></dt>
+ <dd>add a point above the paraboloid to reduce precision
+ errors. Use it for nearly cocircular/cospherical input
+ (e.g., 'rbox c | qvoronoi Qz').</dd>
+ <dt><a href="qh-optt.htm#Tv">Tv</a></dt>
+ <dd>verify result</dd>
+ <dt><a href="qh-optt.htm#TO">TI file</a></dt>
+ <dd>input data from file. The filename may not use spaces or quotes.</dd>
+ <dt><a href="qh-optt.htm#TO">TO file</a></dt>
+ <dd>output results to file. Use single quotes if the filename
+ contains spaces (e.g., <tt>TO 'file with spaces.txt'</tt></dd>
+ <dt><a href="qh-optt.htm#TFn">TFn</a></dt>
+ <dd>report progress after constructing <em>n</em> facets</dd>
+ <dt><a href="qh-optp.htm#PDk">PDk:1</a></dt>
+ <dd>include upper and lower facets in the output. Set <em>k</em>
+ to the last dimension (e.g., 'PD2:1' for 2-d inputs). </dd>
+ <dt><a href="qh-opto.htm#f">f </a></dt>
+ <dd>facet dump. Print the data structure for each facet (i.e.,
+ Voronoi vertex).</dd>
+</dl>
+
+</blockquote>
+</blockquote>
+<h3><a href="#TOP">&#187;</a> <a name="graphics">qvoronoi
+graphics</a></h3>
+<blockquote>
+
+<p>In 2-d, Geomview output ('<a href="qh-optg.htm#G">G</a>')
+displays a Voronoi diagram with extra edges to close the
+unbounded Voronoi regions. To view the unbounded rays, enclose
+the input points in a square.</p>
+
+<p>You can also view <i>individual</i> Voronoi regions in 3-d. To
+view the Voronoi region for site 3 in Geomview, execute</p>
+
+<blockquote>
+ <p>qvoronoi &lt;data <a href="qh-optq.htm#QVn">QV3</a> <a
+ href="qh-opto.htm#p">p</a> | qconvex s G &gt;output</p>
+</blockquote>
+
+<p>The <tt>qvoronoi</tt> command returns the Voronoi vertices
+for input site 3. The <tt>qconvex</tt> command computes their convex hull.
+This is the Voronoi region for input site 3. Its
+hyperplane normals (qconvex 'n') are the same as the separating hyperplanes
+from options '<a href="qh-optf.htm#Fi">Fi</a>'
+and '<a href="qh-optf.htm#Fo">Fo</a>' (up to roundoff error).
+
+<p>See the <a href="qh-eg.htm#delaunay">Delaunay and Voronoi
+examples</a> for 2-d and 3-d examples. Turn off normalization (on
+Geomview's 'obscure' menu) when comparing the Voronoi diagram
+with the corresponding Delaunay triangulation. </p>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="notes">qvoronoi
+notes</a></h3>
+<blockquote>
+
+<p>You can simplify the Voronoi diagram by enclosing the input
+sites in a large square or cube. This is particularly recommended
+for cocircular or cospherical input data.</p>
+
+<p>See <a href="#graphics">Voronoi graphics</a> for computing
+the convex hull of a Voronoi region. </p>
+
+<p>Voronoi diagrams do not include facets that are
+coplanar with the convex hull of the input sites. A facet is
+coplanar if the last coefficient of its normal is
+nearly zero (see <a href="../src/user.h#ZEROdelaunay">qh_ZEROdelaunay</a>).
+
+<p>Unbounded regions can be confusing. For example, '<tt>rbox c |
+qvoronoi Qz o</tt>' produces the Voronoi regions for the vertices
+of a cube centered at the origin. All regions are unbounded. The
+output is </p>
+
+<blockquote>
+ <pre>3
+2 9 1
+-10.101 -10.101 -10.101
+ 0 0 0
+2 0 1
+2 0 1
+2 0 1
+2 0 1
+2 0 1
+2 0 1
+2 0 1
+2 0 1
+0
+</pre>
+</blockquote>
+
+<p>The first line is the dimension. The second line is the number
+of vertices and the number of regions. There is one region per
+input point plus a region for the point-at-infinity added by
+option '<a href="qh-optq.htm#Qz">Qz</a>'. The next two lines
+lists the Voronoi vertices. The first vertex is the infinity
+vertex. It is indicate by the coordinates <em>-10.101</em>. The
+second vertex is the origin. The next nine lines list the
+regions. Each region lists two vertices -- the infinity vertex
+and the origin. The last line is &quot;0&quot; because no region
+is associated with the point-at-infinity. A &quot;0&quot; would
+also be listed for nearly incident input sites. </p>
+
+<p>To use option '<a href="qh-optf.htm#Fv">Fv</a>', add an
+interior point. For example, </p>
+
+<blockquote>
+ <pre>
+rbox c P0 | qvoronoi Fv
+20
+5 0 7 1 3 5
+5 0 3 1 4 5
+5 0 5 1 2 3
+5 0 1 1 2 4
+5 0 6 2 3 6
+5 0 2 2 4 6
+5 0 4 4 5 6
+5 0 8 5 3 6
+5 1 2 0 2 4
+5 1 3 0 1 4
+5 1 5 0 1 2
+5 2 4 0 4 6
+5 2 6 0 2 6
+5 3 4 0 4 5
+5 3 7 0 1 5
+5 4 8 0 6 5
+5 5 6 0 2 3
+5 5 7 0 1 3
+5 6 8 0 6 3
+5 7 8 0 3 5
+</pre>
+</blockquote>
+
+<p>The output consists of 20 ridges and each ridge lists a pair
+of input sites and a triplet of Voronoi vertices. The first eight
+ridges connect the origin ('P0'). The remainder list the edges of
+the cube. Each edge generates an unbounded ray through the
+midpoint. The corresponding separating planes ('Fo') follow each
+pair of coordinate axes. </p>
+
+<p>Options '<a href="qh-optq.htm#Qt">Qt</a>' (triangulated output)
+and '<a href="qh-optq.htm#QJn">QJ</a>' (joggled input) are deprecated. They may produce
+unexpected results. If you use these options, cocircular and cospherical input sites will
+produce duplicate or nearly duplicate Voronoi vertices. See also <a
+href="qh-impre.htm#joggle">Merged facets or joggled input</a>. </p>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="conventions">qvoronoi conventions</a></h3>
+<blockquote>
+
+<p>The following terminology is used for Voronoi diagrams in
+Qhull. The underlying structure is a Delaunay triangulation from
+a convex hull in one higher dimension. Facets of the Delaunay
+triangulation correspond to vertices of the Voronoi diagram.
+Vertices of the Delaunay triangulation correspond to input sites.
+They also correspond to regions of the Voronoi diagram. See <a
+href="qconvex.htm#conventions">convex hull conventions</a>, <a
+href="qdelaun.htm#conventions">Delaunay conventions</a>, and
+<a href="index.htm#structure">Qhull's data structures</a>.</p>
+<blockquote>
+
+<ul>
+ <li><em>input site</em> - a point in the input (one dimension
+ lower than a point on the convex hull)</li>
+ <li><em>point</em> - a point has <i>d+1</i> coordinates. The
+ last coordinate is the sum of the squares of the input
+ site's coordinates</li>
+ <li><em>coplanar point</em> - a <em>nearly incident</em>
+ input site</li>
+ <li><em>vertex</em> - a point on the paraboloid. It
+ corresponds to a unique input site. </li>
+ <li><em>point-at-infinity</em> - a point added above the
+ paraboloid by option '<a href="qh-optq.htm#Qz">Qz</a>'</li>
+ <li><em>Delaunay facet</em> - a lower facet of the
+ paraboloid. The last coefficient of its normal is
+ clearly negative.</li>
+ <li><em>Voronoi vertex</em> - the circumcenter of a Delaunay
+ facet</li>
+ <li><em>Voronoi region</em> - the Voronoi vertices for an
+ input site. The region of Euclidean space nearest to an
+ input site.</li>
+ <li><em>Voronoi diagram</em> - the graph of the Voronoi
+ regions. It includes the ridges (i.e., edges) between the
+ regions.</li>
+ <li><em>vertex-at-infinity</em> - the Voronoi vertex that
+ indicates unbounded Voronoi regions in '<a
+ href="qh-opto.htm#o">o</a>' output format. Its
+ coordinates are <em>-10.101</em>.</li>
+ <li><em>good facet</em> - a Voronoi vertex with optional
+ restrictions by '<a href="qh-optq.htm#QVn">QVn</a>', etc.</li>
+</ul>
+
+</blockquote>
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="options">qvoronoi options</a></h3>
+
+<pre>
+qvoronoi- compute the Voronoi diagram
+ http://www.qhull.org
+
+input (stdin):
+ first lines: dimension and number of points (or vice-versa).
+ other lines: point coordinates, best if one point per line
+ comments: start with a non-numeric character
+
+options:
+ Qu - compute furthest-site Voronoi diagram
+
+Qhull control options:
+ QJn - randomly joggle input in range [-n,n]
+ Qs - search all points for the initial simplex
+ Qz - add point-at-infinity to Voronoi diagram
+ QGn - Voronoi vertices if visible from point n, -n if not
+ QVn - Voronoi vertices for input point n, -n if not
+
+Trace options:
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events
+ Tc - check frequently during execution
+ Ts - statistics
+ Tv - verify result: structure, convexity, and in-circle test
+ Tz - send all output to stdout
+ TFn - report summary when n or more facets created
+ TI file - input data from file, no spaces or single quotes
+ TO file - output results to file, may be enclosed in single quotes
+ TPn - turn on tracing when point n added to hull
+ TMn - turn on tracing at merge n
+ TWn - trace merge facets when width > n
+ TVn - stop qhull after adding point n, -n for before (see TCn)
+ TCn - stop qhull after building cone for point n (see TVn)
+
+Precision options:
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge
+ Rn - randomly perturb computations by a factor of [1-n,1+n]
+ Wn - min facet width for non-coincident point (before roundoff)
+
+Output formats (may be combined; if none, produces a summary to stdout):
+ s - summary to stderr
+ p - Voronoi vertices
+ o - OFF format (dim, Voronoi vertices, and Voronoi regions)
+ i - Delaunay regions (use 'Pp' to avoid warning)
+ f - facet dump
+
+More formats:
+ Fc - count plus coincident points (by Voronoi vertex)
+ Fd - use cdd format for input (homogeneous with offset first)
+ FD - use cdd format for output (offset first)
+ FF - facet dump without ridges
+ Fi - separating hyperplanes for bounded Voronoi regions
+ FI - ID for each Voronoi vertex
+ Fm - merge count for each Voronoi vertex (511 max)
+ Fn - count plus neighboring Voronoi vertices for each Voronoi vertex
+ FN - count and Voronoi vertices for each Voronoi region
+ Fo - separating hyperplanes for unbounded Voronoi regions
+ FO - options and precision constants
+ FP - nearest point and distance for each coincident point
+ FQ - command used for qvoronoi
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,
+ for output: #Voronoi regions, #Voronoi vertices,
+ #coincident points, #non-simplicial regions
+ #real (2), max outer plane and min vertex
+ Fv - Voronoi diagram as Voronoi vertices between adjacent input sites
+ Fx - extreme points of Delaunay triangulation (on convex hull)
+
+Geomview options (2-d only)
+ Ga - all points as dots
+ Gp - coplanar points and vertices as radii
+ Gv - vertices as spheres
+ Gi - inner planes only
+ Gn - no planes
+ Go - outer planes only
+ Gc - centrums
+ Gh - hyperplane intersections
+ Gr - ridges
+ GDn - drop dimension n in 3-d and 4-d output
+
+Print options:
+ PAn - keep n largest Voronoi vertices by 'area'
+ Pdk:n - drop facet if normal[k] &lt;= n (default 0.0)
+ PDk:n - drop facet if normal[k] >= n
+ Pg - print good Voronoi vertices (needs 'QGn' or 'QVn')
+ PFn - keep Voronoi vertices whose 'area' is at least n
+ PG - print neighbors of good Voronoi vertices
+ PMn - keep n Voronoi vertices with most merges
+ Po - force output. If error, output neighborhood of facet
+ Pp - do not report precision problems
+
+ . - list of all options
+ - - one line descriptions of all options
+</pre>
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis
+&#149; <a href="#input">in</a>put &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#controls">co</a>ntrols &#149; <a href="#graphics">gr</a>aphics
+&#149; <a href="#notes">no</a>tes &#149; <a href="#conventions">co</a>nventions
+&#149; <a href="#options">op</a>tions
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/rbox.htm b/xs/src/qhull/html/rbox.htm
new file mode 100644
index 000000000..9c28face5
--- /dev/null
+++ b/xs/src/qhull/html/rbox.htm
@@ -0,0 +1,277 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>rbox -- generate point distributions</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><b><a name="TOP">Up:</a></b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#examples">ex</a>amples &#149; <a href="#notes">no</a>tes
+&#149; <a href="#options">op</a>tions
+<hr>
+<!-- Main text of document -->
+<h1><a
+href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/cone.html"><img
+src="qh--cone.gif" alt="[CONE]" align="middle" width="100"
+height="100"></a>rbox -- generate point distributions</h1>
+
+<blockquote>
+ rbox generates random or regular points according to the
+ options given, and outputs the points to stdout. The
+ points are generated in a cube, unless 's', 'x', or 'y'
+ are given.
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="synopsis">rbox synopsis</a></h3>
+<pre>
+rbox- generate various point distributions. Default is random in cube.
+
+args (any order, space separated):
+ 3000 number of random points in cube, lens, spiral, sphere or grid
+ D3 dimension 3-d
+ c add a unit cube to the output ('c G2.0' sets size)
+ d add a unit diamond to the output ('d G2.0' sets size)
+ l generate a regular 3-d spiral
+ r generate a regular polygon, ('r s Z1 G0.1' makes a cone)
+ s generate cospherical points
+ x generate random points in simplex, may use 'r' or 'Wn'
+ y same as 'x', plus simplex
+ Cn,r,m add n nearly coincident points within radius r of m points
+ Pn,m,r add point [n,m,r] first, pads with 0
+
+ Ln lens distribution of radius n. Also 's', 'r', 'G', 'W'.
+ Mn,m,r lattice (Mesh) rotated by [n,-m,0], [m,n,0], [0,0,r], ...
+ '27 M1,0,1' is {0,1,2} x {0,1,2} x {0,1,2}. Try 'M3,4 z'.
+ W0.1 random distribution within 0.1 of the cube's or sphere's surface
+ Z0.5 s random points in a 0.5 disk projected to a sphere
+ Z0.5 s G0.6 same as Z0.5 within a 0.6 gap
+
+ Bn bounding box coordinates, default 0.5
+ h output as homogeneous coordinates for cdd
+ n remove command line from the first line of output
+ On offset coordinates by n
+ t use time as the random number seed (default is command line)
+ tn use n as the random number seed
+ z print integer coordinates, default 'Bn' is 1e+06
+</pre>
+
+<h3><a href="#TOP">&#187;</a><a name="outputs">rbox outputs</a></h3>
+<blockquote>
+
+The format of the output is the following: first line contains
+ the dimension and a comment, second line contains the
+ number of points, and the following lines contain the points,
+ one point per line. Points are represented by their coordinate values.
+
+<p>For example, <tt>rbox c 10 D2</tt> generates
+<blockquote>
+<pre>
+2 RBOX c 10 D2
+14
+-0.4999921736307369 -0.3684622117955817
+0.2556053225468894 -0.0413498678629751
+0.0327672376602583 -0.2810408135699488
+-0.452955383763607 0.17886471718444
+0.1792964061529342 0.4346928963760779
+-0.1164979223315585 0.01941637230982666
+0.3309653464993139 -0.4654278894564396
+-0.4465383649305798 0.02970019358182344
+0.1711493843897706 -0.4923018137852678
+-0.1165843490665633 -0.433157762450313
+ -0.5 -0.5
+ -0.5 0.5
+ 0.5 -0.5
+ 0.5 0.5
+</pre>
+
+</blockquote>
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="examples">rbox examples</a></h3>
+
+<pre>
+ rbox 10
+ 10 random points in the unit cube centered at the
+ origin.
+
+ rbox 10 s D2
+ 10 random points on a 2-d circle.
+
+ rbox 100 W0
+ 100 random points on the surface of a cube.
+
+ rbox 1000 s D4
+ 1000 random points on a 4-d sphere.
+
+ rbox c D5 O0.5
+ a 5-d hypercube with one corner at the origin.
+
+ rbox d D10
+ a 10-d diamond.
+
+ rbox x 1000 r W0
+ 100 random points on the surface of a fixed simplex
+
+ rbox y D12
+ a 12-d simplex.
+
+ rbox l 10
+ 10 random points along a spiral
+
+ rbox l 10 r
+ 10 regular points along a spiral plus two end
+ points
+
+ rbox 1000 L10000 D4 s
+ 1000 random points on the surface of a narrow lens.
+
+ rbox 1000 L100000 s G1e-6
+ 1000 random points near the edge of a narrow lens
+
+ rbox c G2 d G3
+ a cube with coordinates +2/-2 and a diamond with
+ coordinates +3/-3.
+
+ rbox 64 M3,4 z
+ a rotated, {0,1,2,3} x {0,1,2,3} x {0,1,2,3} lat-
+ tice (Mesh) of integer points.
+
+ rbox P0 P0 P0 P0 P0
+ 5 copies of the origin in 3-d. Try 'rbox P0 P0 P0
+ P0 P0 | qhull QJ'.
+
+ r 100 s Z1 G0.1
+ two cospherical 100-gons plus another cospherical
+ point.
+
+ 100 s Z1
+ a cone of points.
+
+ 100 s Z1e-7
+ a narrow cone of points with many precision errors.
+</pre>
+
+<h3><a href="#TOP">&#187;</a><a name="notes">rbox notes</a></h3>
+<blockquote>
+Some combinations of arguments generate odd results.
+
+</blockquote>
+<h3><a href="#TOP">&#187;</a><a name="options">rbox options</a></h3>
+
+<pre>
+ n number of points
+
+ Dn dimension n-d (default 3-d)
+
+ Bn bounding box coordinates (default 0.5)
+
+ l spiral distribution, available only in 3-d
+
+ Ln lens distribution of radius n. May be used with
+ 's', 'r', 'G', and 'W'.
+
+ Mn,m,r lattice (Mesh) rotated by {[n,-m,0], [m,n,0],
+ [0,0,r], ...}. Use 'Mm,n' for a rigid rotation
+ with r = sqrt(n^2+m^2). 'M1,0' is an orthogonal
+ lattice. For example, '27 M1,0' is {0,1,2} x
+ {0,1,2} x {0,1,2}.
+
+ s cospherical points randomly generated in a cube and
+ projected to the unit sphere
+
+ x simplicial distribution. It is fixed for option
+ 'r'. May be used with 'W'.
+
+ y simplicial distribution plus a simplex. Both 'x'
+ and 'y' generate the same points.
+
+ Wn restrict points to distance n of the surface of a
+ sphere or a cube
+
+ c add a unit cube to the output
+
+ c Gm add a cube with all combinations of +m and -m to
+ the output
+
+ d add a unit diamond to the output.
+
+ d Gm add a diamond made of 0, +m and -m to the output
+
+ Cn,r,m add n nearly coincident points within radius r of m points
+
+ Pn,m,r add point [n,m,r] to the output first. Pad coordi-
+ nates with 0.0.
+
+ n Remove the command line from the first line of out-
+ put.
+
+ On offset the data by adding n to each coordinate.
+
+ t use time in seconds as the random number seed
+ (default is command line).
+
+ tn set the random number seed to n.
+
+ z generate integer coordinates. Use 'Bn' to change
+ the range. The default is 'B1e6' for six-digit
+ coordinates. In R^4, seven-digit coordinates will
+ overflow hyperplane normalization.
+
+ Zn s restrict points to a disk about the z+ axis and the
+ sphere (default Z1.0). Includes the opposite pole.
+ 'Z1e-6' generates degenerate points under single
+ precision.
+
+ Zn Gm s
+ same as Zn with an empty center (default G0.5).
+
+ r s D2 generate a regular polygon
+
+ r s Z1 G0.1
+ generate a regular cone
+</pre>
+
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual</a>: Table of Contents<br>
+<b>To:</b> <a href="qh-quick.htm#programs">Programs</a>
+&#149; <a href="qh-quick.htm#options">Options</a>
+&#149; <a href="qh-opto.htm#output">Output</a>
+&#149; <a href="qh-optf.htm#format">Formats</a>
+&#149; <a href="qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="qh-optp.htm#print">Print</a>
+&#149; <a href="qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="qh-optc.htm#prec">Precision</a>
+&#149; <a href="qh-optt.htm#trace">Trace</a>
+&#149; <a href="../src/libqhull_r/index.htm">Functions</a><br>
+<b>To:</b> <a href="#synopsis">sy</a>nopsis &#149; <a href="#outputs">ou</a>tputs
+&#149; <a href="#examples">ex</a>amples &#149; <a href="#notes">no</a>tes
+&#149; <a href="#options">op</a>tions
+<!-- GC common information -->
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="qh--geom.gif"
+align="middle" width="40" height="40"></a><i>The Geometry Center
+Home Page </i></p>
+
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+<br>
+Created: Sept. 25, 1995 --- <!-- hhmts start --> Last modified: August 12, 1998 <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/html/rbox.man b/xs/src/qhull/html/rbox.man
new file mode 100644
index 000000000..3ea6395e6
--- /dev/null
+++ b/xs/src/qhull/html/rbox.man
@@ -0,0 +1,176 @@
+.\" This is the Unix manual page for rbox, written in nroff, the standard
+.\" manual formatter for Unix systems. To format it, type
+.\"
+.\" nroff -man rbox.man
+.\"
+.\" This will print a formatted copy to standard output. If you want
+.\" to ensure that the output is plain ascii, free of any control
+.\" characters that nroff uses for underlining etc, pipe the output
+.\" through "col -b":
+.\"
+.\" nroff -man rbox.man | col -b
+.\"
+.TH rbox 1 "August 10, 1998" "Geometry Center"
+.SH NAME
+rbox \- generate point distributions for qhull
+.SH SYNOPSIS
+Command "rbox" (w/o arguments) lists the options.
+.SH DESCRIPTION
+.PP
+rbox generates random or regular points according to the options given, and
+outputs
+the points to stdout. The points are generated in a cube, unless 's' or 'k'
+option is
+given. The format of the output is the following: first line
+contains the dimension and a comment,
+second line contains the number of points, and the
+following lines contain the points, one point per line. Points are represented
+by their coordinate values.
+.SH EXAMPLES
+.TP
+rbox 10
+10 random points in the unit cube centered at the origin.
+.TP
+rbox 10 s D2
+10 random points on a 2\[hy]d circle.
+.TP
+rbox 100 W0
+100 random points on the surface of a cube.
+.TP
+rbox 1000 s D4
+1000 random points on a 4\[hy]d sphere.
+.TP
+rbox c D5 O0.5
+a 5\[hy]d hypercube with one corner at the origin.
+.TP
+rbox d D10
+a 10\[hy]d diamond.
+.TP
+rbox x 1000 r W0
+100 random points on the surface of a fixed simplex
+.TP
+rbox y D12
+a 12\[hy]d simplex.
+.TP
+rbox l 10
+10 random points along a spiral
+.TP
+rbox l 10 r
+10 regular points along a spiral plus two end points
+.TP
+rbox 1000 L10000 D4 s
+1000 random points on the surface of a narrow lens.
+.TP
+rbox c G2 d G3
+a cube with coordinates +2/\-2 and a diamond with coordinates +3/\-3.
+.TP
+rbox 64 M3,4 z
+a rotated, {0,1,2,3} x {0,1,2,3} x {0,1,2,3} lattice (Mesh) of integer
+points. 'rbox 64 M1,0' is orthogonal.
+.TP
+rbox P0 P0 P0 P0 P0
+5 copies of the origin in 3\-d. Try 'rbox P0 P0 P0 P0 P0 | qhull QJ'.
+.TP
+r 100 s Z1 G0.1
+two cospherical 100\-gons plus another cospherical point.
+.TP
+100 s Z1
+a cone of points.
+.TP
+100 s Z1e\-7
+a narrow cone of points with many precision errors.
+.SH OPTIONS
+.TP
+n
+number of points
+.TP
+Dn
+dimension n\[hy]d (default 3\[hy]d)
+.TP
+Bn
+bounding box coordinates (default 0.5)
+.TP
+l
+spiral distribution, available only in 3\[hy]d
+.TP
+Ln
+lens distribution of radius n. May be used with 's', 'r', 'G', and 'W'.
+.TP
+Mn,m,r
+lattice (Mesh) rotated by {[n,\-m,0], [m,n,0], [0,0,r], ...}.
+Use 'Mm,n' for a rigid rotation with r = sqrt(n^2+m^2). 'M1,0' is an
+orthogonal lattice. For example, '27 M1,0' is {0,1,2} x {0,1,2} x
+{0,1,2}. '27 M3,4 z' is a rotated integer lattice.
+.TP
+s
+cospherical points randomly generated in a cube and projected to the unit sphere
+.TP
+x
+simplicial distribution. It is fixed for option 'r'. May be used with 'W'.
+.TP
+y
+simplicial distribution plus a simplex. Both 'x' and 'y' generate the same points.
+.TP
+Wn
+restrict points to distance n of the surface of a sphere or a cube
+.TP
+c
+add a unit cube to the output
+.TP
+c Gm
+add a cube with all combinations of +m and \-m to the output
+.TP
+d
+add a unit diamond to the output.
+.TP
+d Gm
+add a diamond made of 0, +m and \-m to the output
+.TP
+Cn,r,m
+add n nearly coincident points within radius r of m points
+.TP
+Pn,m,r
+add point [n,m,r] to the output first. Pad coordinates with 0.0.
+.TP
+n
+Remove the command line from the first line of output.
+.TP
+On
+offset the data by adding n to each coordinate.
+.TP
+t
+use time in seconds as the random number seed (default is command line).
+.TP
+tn
+set the random number seed to n.
+.TP
+z
+generate integer coordinates. Use 'Bn' to change the range.
+The default is 'B1e6' for six\[hy]digit coordinates. In R^4, seven\[hy]digit
+coordinates will overflow hyperplane normalization.
+.TP
+Zn s
+restrict points to a disk about the z+ axis and the sphere (default Z1.0).
+Includes the opposite pole. 'Z1e\-6' generates degenerate points under
+single precision.
+.TP
+Zn Gm s
+same as Zn with an empty center (default G0.5).
+.TP
+r s D2
+generate a regular polygon
+.TP
+r s Z1 G0.1
+generate a regular cone
+.SH BUGS
+Some combinations of arguments generate odd results.
+
+Report bugs to qhull_bug@qhull.org, other correspondence to qhull@qhull.org
+.SH SEE ALSO
+qhull(1)
+.SH AUTHOR
+.nf
+C. Bradford Barber
+bradb@shore.net
+.fi
+
diff --git a/xs/src/qhull/html/rbox.txt b/xs/src/qhull/html/rbox.txt
new file mode 100644
index 000000000..e3cf72189
--- /dev/null
+++ b/xs/src/qhull/html/rbox.txt
@@ -0,0 +1,195 @@
+
+
+
+rbox(1) rbox(1)
+
+
+NAME
+ rbox - generate point distributions for qhull
+
+SYNOPSIS
+ Command "rbox" (w/o arguments) lists the options.
+
+DESCRIPTION
+ rbox generates random or regular points according to the
+ options given, and outputs the points to stdout. The
+ points are generated in a cube, unless 's' or given. The
+ format of the output is the following: first line contains
+ the dimension and a comment, second line contains the num-
+ ber of points, and the following lines contain the points,
+ one point per line. Points are represented by their coor-
+ dinate values.
+
+EXAMPLES
+ rbox 10
+ 10 random points in the unit cube centered at the
+ origin.
+
+ rbox 10 s D2
+ 10 random points on a 2-d circle.
+
+ rbox 100 W0
+ 100 random points on the surface of a cube.
+
+ rbox 1000 s D4
+ 1000 random points on a 4-d sphere.
+
+ rbox c D5 O0.5
+ a 5-d hypercube with one corner at the origin.
+
+ rbox d D10
+ a 10-d diamond.
+
+ rbox x 1000 r W0
+ 100 random points on the surface of a fixed simplex
+
+ rbox y D12
+ a 12-d simplex.
+
+ rbox l 10
+ 10 random points along a spiral
+
+ rbox l 10 r
+ 10 regular points along a spiral plus two end
+ points
+
+ rbox 1000 L10000 D4 s
+ 1000 random points on the surface of a narrow lens.
+
+ rbox c G2 d G3
+ a cube with coordinates +2/-2 and a diamond with
+
+
+
+Geometry Center August 10, 1998 1
+
+
+
+
+
+rbox(1) rbox(1)
+
+
+ coordinates +3/-3.
+
+ rbox 64 M3,4 z
+ a rotated, {0,1,2,3} x {0,1,2,3} x {0,1,2,3} lat-
+ tice (Mesh) of integer points.
+
+ rbox P0 P0 P0 P0 P0
+ 5 copies of the origin in 3-d. Try 'rbox P0 P0 P0
+ P0 P0 | qhull QJ'.
+
+ r 100 s Z1 G0.1
+ two cospherical 100-gons plus another cospherical
+ point.
+
+ 100 s Z1
+ a cone of points.
+
+ 100 s Z1e-7
+ a narrow cone of points with many precision errors.
+
+OPTIONS
+ n number of points
+
+ Dn dimension n-d (default 3-d)
+
+ Bn bounding box coordinates (default 0.5)
+
+ l spiral distribution, available only in 3-d
+
+ Ln lens distribution of radius n. May be used with
+ 's', 'r', 'G', and 'W'.
+
+ Mn,m,r lattice (Mesh) rotated by {[n,-m,0], [m,n,0],
+ [0,0,r], ...}. Use 'Mm,n' for a rigid rotation
+ with r = sqrt(n^2+m^2). 'M1,0' is an orthogonal
+ lattice. For example, '27 M1,0' is {0,1,2} x
+ {0,1,2} x {0,1,2}.
+
+ s cospherical points randomly generated in a cube and
+ projected to the unit sphere
+
+ x simplicial distribution. It is fixed for option
+ 'r'. May be used with 'W'.
+
+ y simplicial distribution plus a simplex. Both 'x'
+ and 'y' generate the same points.
+
+ Wn restrict points to distance n of the surface of a
+ sphere or a cube
+
+ c add a unit cube to the output
+
+ c Gm add a cube with all combinations of +m and -m to
+ the output
+
+
+
+Geometry Center August 10, 1998 2
+
+
+
+
+
+rbox(1) rbox(1)
+
+
+ d add a unit diamond to the output.
+
+ d Gm add a diamond made of 0, +m and -m to the output
+
+ Cn,r,m add n nearly coincident points within radius r of m points
+
+ Pn,m,r add point [n,m,r] to the output first. Pad coordi-
+ nates with 0.0.
+
+ n Remove the command line from the first line of out-
+ put.
+
+ On offset the data by adding n to each coordinate.
+
+ t use time in seconds as the random number seed
+ (default is command line).
+
+ tn set the random number seed to n.
+
+ z generate integer coordinates. Use 'Bn' to change
+ the range. The default is 'B1e6' for six-digit
+ coordinates. In R^4, seven-digit coordinates will
+ overflow hyperplane normalization.
+
+ Zn s restrict points to a disk about the z+ axis and the
+ sphere (default Z1.0). Includes the opposite pole.
+ 'Z1e-6' generates degenerate points under single
+ precision.
+
+ Zn Gm s
+ same as Zn with an empty center (default G0.5).
+
+ r s D2 generate a regular polygon
+
+ r s Z1 G0.1
+ generate a regular cone
+
+BUGS
+ Some combinations of arguments generate odd results.
+
+ Report bugs to qhull_bug@qhull.org, other correspon-
+ dence to qhull@qhull.org
+
+SEE ALSO
+ qhull(1)
+
+AUTHOR
+ C. Bradford Barber
+ bradb@shore.net
+
+
+
+
+
+Geometry Center August 10, 1998 3
+
+
diff --git a/xs/src/qhull/index.htm b/xs/src/qhull/index.htm
new file mode 100644
index 000000000..4ea7806c9
--- /dev/null
+++ b/xs/src/qhull/index.htm
@@ -0,0 +1,284 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+
+<head>
+<title>Qhull code for Convex Hull, Delaunay Triangulation, Voronoi Diagram, and Halfspace Intersection about a Point</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<b>URL:</b> <a href="http://www.qhull.org">http://www.qhull.org</a>
+<br><b>To:</b>
+<a href="http://www.qhull.org/news">News</a>
+&#149; <a href="http://www.qhull.org/download">Download</a>
+&#149; <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405">CiteSeer</a>
+&#149; <a href=http://images.google.com/images?q=qhull&num=100>Images</a>
+&#149; <a href="html/index.htm#TOC">Manual</a>
+&#149; <a href="http://www.qhull.org/html/qh-faq.htm">FAQ</a>
+&#149; <a href="html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="html/qh-quick.htm#options">Options</a>
+</p>
+
+<hr>
+<!-- Main text of document -->
+<table>
+<tr><td valign=top>
+ <h1>Qhull</h1>
+ <a
+ href="http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/cone.html"><img
+ src="html/qh--cone.gif" alt="[CONE]" align="middle" width="100"
+ height="100"></a>
+</td><td>
+Qhull computes the convex hull, Delaunay triangulation, Voronoi diagram,
+halfspace intersection about a point, furthest-site Delaunay
+triangulation, and furthest-site Voronoi diagram. The source code runs in
+2-d, 3-d, 4-d, and higher dimensions. Qhull implements the Quickhull
+algorithm for computing the convex hull. It handles roundoff
+errors from floating point arithmetic. It computes volumes,
+surface areas, and approximations to the convex hull.</p>
+
+<!-- duplicated in index.htm and html/index.htm -->
+<p>Qhull does <i>not</i> support triangulation of non-convex surfaces, mesh
+generation of non-convex objects, medium-sized inputs in 9-D
+and higher, alpha shapes, weighted Voronoi diagrams, Voronoi volumes, or
+constrained Delaunay triangulations, </p>
+
+<p>Qhull 2015.2 introduces reentrant Qhull. It allows concurrent Qhull runs and simplifies the C++ interface to Qhull.
+If you call Qhull from your program, you should use reentrant Qhull (libqhull_r) instead of qh_QHpointer (libqhull).
+If you use Qhull 2003.1. please upgrade or apply <a href="http://www.qhull.org/download/poly.c-qh_gethash.patch">poly.c-qh_gethash.patch</a>.
+</p>
+</td></tr></table>
+
+<hr>
+<form method=get action=http://www.google.com/search>
+<input type=hidden name=sitesearch value=www.qhull.org>
+<input type=hidden name=num value=100>
+<ul>
+ <li><a href="http://www.qhull.org/news">News</a> and
+ <a href="http://www.qhull.org/news/qhull-news.html#bugs">Bugs</a>
+ about Qhull 2015.2 2016/01/18</li>
+ <li><a href="http://www.qhull.org/download">Download</a> Qhull (<a href="http://www.qhull.org/src/Changes.txt">changes</a>)</li>
+ <li><a href=http://github.com/qhull/qhull/wiki>GitHub</a> C++ interface to Qhull
+ <li><a href="html/index.htm">Manual</a> for Qhull and rbox
+ <li><a href="html/index.htm#geomview">Geomview</a> for 3-D and 4-D visualization of Qhull output
+ <li><input name=as_q size=10 value="">
+ <input type="submit" value="Search">
+ www.qhull.org
+ <p>
+ <li><a href="http://www.qhull.org/news/qhull-news.html#users">How</a> is Qhull used?</li>
+ <li><a href="http://scholar.google.com/scholar?cites=13151392091060773178&as_sdt=40000005">Google Scholar</a>,
+ <a href="http://libra.msra.cn/Publication/232063/the-quickhull-algorithm-for-convex-hulls">Microsoft Academic</a>,
+ and <a href="http://citeseerx.ist.psu.edu/showciting?doi=10.1.1.117.405&sort=cite">CiteSeer</a>
+ references to Qhull
+ <li>
+ <a href=http://www.google.com/search?as_q=qhull+-debian+-cvs+-gentoo+-pool+-mirrors&num=100>Google</a> Qhull,
+ <a href="http://images.google.com/images?q=qhull&num=100">Images</a>,
+ <a href="http://www.google.com/#q=qhull&tbm=bks">Books</a>,
+ <a href="http://www.google.com/search?q=qhull&tbm=pts">Patents</a>,
+ <a href="http://groups.google.com/groups?as_q=qhull&num=100&as_scoring=d">Newsgroups</a>,
+ <a href="http://www.google.com/search?q=qhull&tbm=blg">Blogs</a>,
+ and <a href=http://www.googlism.com/who_is/q/qhull/>Who is</a> Qhull?
+
+
+ <p>
+ <li><a href=http://www.mathworks.com/>MATLAB</a> uses Qhull for their n-d computational geometry functions:
+ <a href=http://www.mathworks.com/help/techdoc/ref/convhulln.html>convhulln</a>
+ <a href=http://www.mathworks.com/help/techdoc/ref/delaunayn.html>delaunayn</a>
+ <a href=http://www.mathworks.com/help/techdoc/ref/griddatan.html>griddatan</a>
+ <a href=http://www.mathworks.com/help/techdoc/ref/voronoin.html>voronoin</a>.
+ </li>
+ <li>The <a href="http://cran.r-project.org/web/packages/geometry/geometry.pdf">geometry</a> package of <a href="http://www.r-project.org/">R</a> provides <a href="http://geometry.r-forge.r-project.org/">Qhull in R</a>.
+ <li>The <a href="http://packages.debian.org/sid/octave3.2">Debian build</a> of
+ <a href=http://www.octave.org/>GNU Octave</a> includes Qhull for <a href="http://www.gnu.org/software/octave/doc/interpreter/Geometry.html">computational geometry<a>.
+ <li><a href=http://www.wolfram.com/products/mathematica/>Mathematica</a>'s Delaunay interface <a href=http://library.wolfram.com/infocenter/MathSource/1160/>qh-math</a>
+ and <a href="http://portal.uni-freiburg.de/imteksimulation/downloads/ims">QHullInterface</a>
+ <li>The <a href="http://docs.scipy.org/doc/scipy/reference/tutorial/spatial.html">scipy.spatial</a> of <a href="http://scipy.org/">SciPy</a> is implemented with Qhull. It includes
+ support for Delaunay triangulations,
+</ul>
+</form>
+
+<p><b>Introduction</b>
+<ul>
+ <li><a
+ href="http://www.cs.mcgill.ca/~fukuda/soft/polyfaq/polyfaq.html"
+ >Fukuda's introduction</a> to convex hulls, Delaunay
+ triangulations, Voronoi diagrams, and linear programming</li>
+ <li><a
+ href="http://www.cse.unsw.edu.au/~lambert/java/3d/hull.html"
+ >Lambert's Java</a> visualization of convex hull algorithms </li>
+ <li><a
+ href="http://www.algorithmic-solutions.info/leda_guide/geometryalgorithms.html"
+ >LEDA Guide</a> to geometry algorithms
+ <li><a
+ href="http://mathworld.wolfram.com/ComputationalGeometry.html"
+ >MathWorld's</a> Computational Geometry from Wolfram Research
+ <li><a
+ href="http://www.cs.sunysb.edu/~algorith/major_section/1.6.shtml"
+ >Skiena's</a> Computational Geometry from his <i>Algorithm Design Manual</i>.
+ <li><a
+ href="http://www.cs.sunysb.edu/~algorith/major_section/1.6.shtml"
+ >Stony Brook</a> Algorithm Repository, computational geometry</li>
+</ul>
+
+<p><b>Qhull Documentation and Support</b>
+<ul>
+ <li><a href="html/index.htm">Manual</a> for Qhull and rbox
+ <table><tr><td>
+ <ul>
+ <li><a href="html/index.htm#description">Description</a> of Qhull
+ <li><a href="html/qh-impre.htm">Imprecision</a> in Qhull
+ <li><a href="html/qh-quick.htm#programs">Programs</a> and <a href="html/qh-quick.htm#options">Options</a>
+ quick reference
+ <li><a href="html/qconvex.htm">qconvex</a> -- convex hull
+ <li><a href="html/qdelaun.htm">qdelaunay</a> -- Delaunay triangulation
+ <li><a href="html/qvoronoi.htm">qvoronoi</a> -- Voronoi diagram
+ <li><a href="html/qhalf.htm">qhalf</a> -- halfspace intersection about a point
+ <li><a href="html/rbox.htm">rbox</a> -- generate point distributions
+ </ul></td><td><ul>
+ <li><a href="http://www.qhull.org/html/qh-faq.htm">Frequently</a> asked
+ questions about Qhull</li>
+ <li><a href="html/index.htm#geomview">Geomview</a> for visualizing Qhull
+ <li><a href="COPYING.txt">COPYING.txt</a> - copyright notice<br>
+ <li><a href="REGISTER.txt">REGISTER.txt</a> - registration<br>
+ <li><a href="README.txt">README.txt</a> - installation
+ instructions<br>
+ <li><a href="src/Changes.txt">Changes.txt</a> - change history <br>
+ <li><a href="html/qh-code.htm">Calling Qhull</a> from your program
+ <li><a href="src/libqhull_r/index.htm">Reentrant</a> Qhull functions, macros, and data structures with source
+ </ul>
+ </td></tr></table>
+ <li>Send e-mail to <a href=mailto:qhull@qhull.org>qhull@qhull.org</a> </li>
+ <li>Report bugs to <a
+ href="mailto:qhull_bug@qhull.org">qhull_bug@qhull.org</a>
+</ul>
+
+<p><b>Related URLs</b>
+<ul>
+ <li><a href="http://www.geom.uiuc.edu/software/cglist">Amenta's directory</a> of
+ computational geometry software </li>
+
+ <li><a href=http://www.boost.org/libs/graph/doc/table_of_contents.html>BGL</a>
+ Boost Graph Library provides C++ classes for graph data structures
+and algorithms,
+ <li><a
+ href="http://www.netlib.org/voronoi/hull.html">Clarkson's
+ hull </a>program with exact arithmetic for convex hulls, Delaunay triangulations,
+ Voronoi volumes, and alpha shapes. </li>
+ <li><a href="http://compgeom.cs.uiuc.edu/~jeffe/compgeom/compgeom.html">Erickson's
+ Computational</a> Geometry Pages and
+ <a href="http://compgeom.cs.uiuc.edu/~jeffe/compgeom/code.html">Software</a>
+ <li><a
+ href="http://www.cs.mcgill.ca/~fukuda/soft/cdd_home/cdd.html">Fukuda's
+ cdd</a> program for halfspace intersection and convex hulls (<a
+ href="http://www.csb.ethz.ch/tools/polco">Polco/Java</a>)</li>
+ <li><a href="http://www.inf.ethz.ch/personal/gaertner/miniball.html">Gartner's
+ Miniball</a> for fast and robust smallest enclosing balls (up to 20-d)
+
+ <li><a href=http://www.algorithmic-solutions.com/enleda.htm>Leda</a>
+and <a href=http://www.cgal.org/>CGAL</a> libraries for writing computational
+geometry programs and other combinatorial algorithms
+ <li><a href=http://www.mathtools.net/>Mathtools.net</a> of scientific and engineering
+ software
+ <li><a href="http://www.imr.sandia.gov/papers/topics.html">Owen's International Meshing</a> Roundtable
+ <li><a
+ href="http://www.robertschneiders.de/meshgeneration/meshgeneration.html">Schneiders'
+ Finite Element</a> Mesh Generation page</li>
+ <li><a href="http://www.cs.cmu.edu/~quake/triangle.html">Shewchuk's
+ triangle </a>program for 2-d Delaunay</li>
+ <li><a href=http://www.voronoi.com>Voronoi Web Site</a> for all things Voronoi
+ <li>Young's <a href="http://homepage.usask.ca/~ijm451/finite/fe_resources/">Internet Finite Element Resources</a>
+ <li><a href="http://www.uic.nnov.ru/~zny/skeleton/">Zolotykh's Skeleton</a> generates all extreme rays of a polyhedral cone using the Double Description Method</li>
+ <li><a href="https://github.com/tomilov/quickhull/blob/master/include/quickhull.hpp">Tomilov's quickhull.hpp</a> (<a href="http://habrahabr.ru/post/245221/">doc-ru</a>) implements the Quickhull algorithm for points in general position.
+</ul>
+
+<p><b>FAQs and Newsgroups</b>
+<ul>
+ <li><a
+ href="http://www.faqs.org/faqs/graphics/algorithms-faq/">FAQ</a>
+ for computer graphics algorithms
+ (Exaflop.org: <a href="http://exaflop.org/docs/cgafaq/cga6.html">geometric</a> structures)
+ </li>
+ <li><a
+ href="http://www-unix.mcs.anl.gov/otc/Guide/faq/linear-programming-faq.html">FAQ
+ </a>for linear programming </li>
+ <li><a href="news:comp.graphics.algorithms">Newsgroup</a>:
+ comp.graphics.algorithms </li>
+ <li><a href="news:comp.soft-sys.matlab">Newsgroup</a>:
+ comp.soft-sys.matlab</li>
+ <li><a href="news:sci.math.num-analysis">Newsgroup</a>:
+ sci.math.num-analysis </li>
+ <li><a href="news:sci.op-research">Newsgroup</a>:
+ sci.op-research </li>
+</ul>
+</blockquote>
+<hr>
+
+<p>The program includes options for input transformations,
+randomization, tracing, multiple output formats, and execution
+statistics. The program can be called from within your
+application. </p>
+
+<p>You can view the results in 2-d, 3-d and 4-d with <a
+href="http://www.geomview.org">Geomview</a>. An alternative
+is <a href=http://www.vtk.org/>VTK</a>.</p>
+
+<p>For an article about Qhull, download from
+ <a href="http://dl.acm.org/authorize?89250">ACM</a> or <a
+ href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405">CiteSeer</a>:
+</p>
+
+<blockquote>
+ <p>Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T., &quot;The
+ Quickhull algorithm for convex hulls,&quot; <i>ACM Trans. on
+ Mathematical Software</i>, 22(4):469-483, Dec 1996, http://www.qhull.org</p>
+</blockquote>
+
+<p>Abstract: </p>
+
+<blockquote>
+ <p>The convex hull of a set of points is the smallest convex
+ set that contains the points. This article presents a
+ practical convex hull algorithm that combines the
+ two-dimensional Quickhull Algorithm with the general
+ dimension Beneath-Beyond Algorithm. It is similar to the
+ randomized, incremental algorithms for convex hull and
+ Delaunay triangulation. We provide empirical evidence that
+ the algorithm runs faster when the input contains non-extreme
+ points, and that it uses less memory. </p>
+ <p>Computational geometry algorithms have traditionally
+ assumed that input sets are well behaved. When an algorithm
+ is implemented with floating point arithmetic, this
+ assumption can lead to serious errors. We briefly describe a
+ solution to this problem when computing the convex hull in
+ two, three, or four dimensions. The output is a set of
+ "thick" facets that contain all possible exact convex hulls
+ of the input. A variation is effective in five or more
+ dimensions. </p>
+</blockquote>
+<!-- Navigation links -->
+<hr>
+
+<p><b>Up:</b> <a href="http://www.geom.uiuc.edu/software/past-projects.html"><i>Past Software
+Projects of the Geometry Center</i></a> <br>
+<b>URL:</b> <a href="http://www.qhull.org">http://www.qhull.org</a>
+<br><b>To:</b>
+<a href="http://www.qhull.org/news">News</a>
+&#149; <a href="http://www.qhull.org/download">Download</a>
+&#149; <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.117.405">CiteSeer</a>
+&#149; <a href=http://images.google.com/images?q=qhull&num=100>Images</a>
+&#149; <a href="html/index.htm#TOC">Manual</a>
+&#149; <a href="http://www.qhull.org/html/qh-faq.htm">FAQ</a>
+&#149; <a href="html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="html/qh-quick.htm#options">Options</a>
+<!-- GC common information --></p>
+
+<hr>
+
+<p><a href="http://www.geom.uiuc.edu/"><img src="html/qh--geom.gif" alt="[HOME]"
+align="middle"></a> <i>The Geometry Center Home Page</i> </p>
+
+<p>Comments to: <a href="mailto:qhull@qhull.org">qhull@qhull.org</a>
+<br>
+Created: May 17 1995 --- <!-- hhmts start -->
+</body>
+</html>
diff --git a/xs/src/qhull/origCMakeLists.txt b/xs/src/qhull/origCMakeLists.txt
new file mode 100644
index 000000000..1034d1dea
--- /dev/null
+++ b/xs/src/qhull/origCMakeLists.txt
@@ -0,0 +1,426 @@
+# CMakeLists.txt -- CMake configuration file for qhull, qhull6, and related programs
+#
+# To install CMake
+# Download from http://www.cmake.org/download/
+#
+# To find the available targets for CMake -G "..."
+# cmake --help
+#
+# To build with MSYS/mingw
+# cd build && cmake -G "MSYS Makefiles" .. && cmake ..
+# make
+# make install
+#
+# To uninstall on unix or MSYS/mingw
+# xargs rm <build/install_manifest.txt
+#
+# To build Qhull with Visual Studio projects, run cmake twice
+# To install bin/doc/include/lib in the current directory
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 11 2012" .. && cmake -DCMAKE_INSTALL_PREFIX=.. ..
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 11 2012 Win64" .. && cmake -DCMAKE_INSTALL_PREFIX=.. ..
+# To install into Program Files/qhull
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 11 2012" .. && cmake ..
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 11 2012 Win64" .. && cmake ..
+# To build for Visual Studio 2005 and install into Program Files/qhull
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 8 2005" .. && cmake ..
+# mkdir -p build-cmake && cd build-cmake && cmake -G "Visual Studio 8 2005 Win64" .. && cmake ..
+# Double click build-cmake/qhull-all.sln
+# Build INSTALL to copy files into C:/Program Files/qhull
+#
+# Additional build targets
+# qhullp -- Same as qhull using qh_QHpointer and deprecated libqhull_p
+# user_egp -- Same as user_eg using qh_QHpointer and deprecated libqhull_p
+#
+# Notes on Visual Studio projects
+# You may need to copy bin/msvcr80.dll into C:/Program Files/qhull/bin
+# If using library debug targets, please rename with '_d' (e.g., qhullstatic_d.lib)
+#
+# Troubleshooting
+# "No CMAKE_C_COMPILER could be found"
+# cmake was not able to find the build environment specified (e.g., Visual Studio 11)
+#
+# To uninstall on Windows
+# Delete C:/Program Files/qhull
+#
+# If creating a qhull package, please include a pkg-config file based on build/qhull*.pc.in
+#
+# For qhulltest, use the Qt build (src/qhull-all.pro)
+#
+# Qhull ships with cmake-derived sln and proj files for DevStudio 8 2005
+# See eg/make-vcproj.sh
+# Change to relative paths
+# Remove ZERO_CHECK, ALL_BUILD, and INSTALL projects
+# Change targets to bin/ and lib/ directories
+# Disable incremental linking and ilk files (LinkIncremental="1")
+# Disable Run-Time Type Info (rtti)
+# Remove src/libqhullcpp from most of the AdditionalIncludeDirectories
+# Remove CMAKE_INTDIR from PreprocessorDefinitions
+# Adjust target names and destinations (e.g., lib/libqhullstatic_rd.a)
+#
+# $Id: //main/2015/qhull/CMakeLists.txt#8 $$Change: 2066 $
+# $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+
+project(qhull)
+cmake_minimum_required(VERSION 2.6)
+
+# Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, qhull-warn.pri
+set(qhull_VERSION2 "2015.2 2016/01/18") # not used, See global.c, global_r.c, rbox.c, rbox_r.c
+set(qhull_VERSION "7.2.0") # Advance every release
+
+# SOVERSION -- qhull 2003 = empty, 2009 = 5, 2010-2012 = 6, 2015 (reentrant) = 7
+set(qhull_SOVERSION 7) # For SOVERSION
+
+include(CMakeModules/CheckLFS.cmake)
+option(WITH_LFS "Enable Large File Support" ON)
+check_lfs(WITH_LFS)
+
+if(INCLUDE_INSTALL_DIR)
+else()
+set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include)
+endif()
+if(LIB_INSTALL_DIR)
+else()
+set(LIB_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/lib)
+endif()
+if(BIN_INSTALL_DIR)
+else()
+set(BIN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/bin)
+endif()
+if(MAN_INSTALL_DIR)
+else()
+ if(WIN32)
+ set(MAN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/man/man1)
+ else()
+ set(MAN_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/man/man1)
+ endif()
+endif()
+if(DOC_INSTALL_DIR)
+else()
+ if(WIN32)
+ set(DOC_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/doc)
+ else()
+ set(DOC_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/doc/qhull)
+ endif()
+endif()
+message(STATUS)
+message(STATUS "========== qhull Build Information ==========")
+message(STATUS "Build Version: ${qhull_VERSION}")
+message(STATUS "Install Prefix (CMAKE_INSTALL_PREFIX): ${CMAKE_INSTALL_PREFIX}")
+message(STATUS "Binary Directory (BIN_INSTALL_DIR): ${BIN_INSTALL_DIR}")
+message(STATUS "Library Directory (LIB_INSTALL_DIR): ${LIB_INSTALL_DIR}")
+message(STATUS "Include Directory (INCLUDE_INSTALL_DIR): ${INCLUDE_INSTALL_DIR}")
+message(STATUS "Documentation Directory (DOC_INSTALL_DIR): ${DOC_INSTALL_DIR}")
+message(STATUS "Man Pages Directory (MAN_INSTALL_DIR): ${MAN_INSTALL_DIR}")
+message(STATUS "Build Type (CMAKE_BUILD_TYPE): ${CMAKE_BUILD_TYPE}")
+message(STATUS "To override these options, add -D{OPTION_NAME}=... to the cmake command")
+message(STATUS " Build the debug targets -DCMAKE_BUILD_TYPE=Debug")
+message(STATUS)
+message(STATUS "To build and install qhull, enter \"make\" and \"make install\"")
+message(STATUS "To smoketest qhull, enter \"ctest\"")
+message(STATUS)
+
+
+# ---------------------------------------
+# Define library source files and variables
+#
+# Files for individual targets are defined with the target
+# ---------------------------------------
+
+# Order libqhull object files by frequency of execution. Small files at end.
+
+# Non-reentrant Qhull
+set(
+ libqhull_HEADERS
+ src/libqhull/libqhull.h
+ src/libqhull/geom.h
+ src/libqhull/io.h
+ src/libqhull/mem.h
+ src/libqhull/merge.h
+ src/libqhull/poly.h
+ src/libqhull/qhull_a.h
+ src/libqhull/qset.h
+ src/libqhull/random.h
+ src/libqhull/stat.h
+ src/libqhull/user.h
+)
+set(
+ libqhull_SOURCES
+ src/libqhull/global.c
+ src/libqhull/stat.c
+ src/libqhull/geom2.c
+ src/libqhull/poly2.c
+ src/libqhull/merge.c
+ src/libqhull/libqhull.c
+ src/libqhull/geom.c
+ src/libqhull/poly.c
+ src/libqhull/qset.c
+ src/libqhull/mem.c
+ src/libqhull/random.c
+ src/libqhull/usermem.c
+ src/libqhull/userprintf.c
+ src/libqhull/io.c
+ src/libqhull/user.c
+ src/libqhull/rboxlib.c
+ src/libqhull/userprintf_rbox.c
+ ${libqhull_HEADERS}
+)
+
+set(
+ libqhull_DOC
+ src/libqhull/index.htm
+ src/libqhull/qh-geom.htm
+ src/libqhull/qh-globa.htm
+ src/libqhull/qh-io.htm
+ src/libqhull/qh-mem.htm
+ src/libqhull/qh-merge.htm
+ src/libqhull/qh-poly.htm
+ src/libqhull/qh-qhull.htm
+ src/libqhull/qh-set.htm
+ src/libqhull/qh-stat.htm
+ src/libqhull/qh-user.htm
+ src/libqhull/DEPRECATED.txt
+)
+
+set(
+ testqset_HEADERS
+ src/libqhull/mem.h
+ src/libqhull/qset.h
+)
+set(
+ testqset_SOURCES
+ src/libqhull/qset.c
+ src/libqhull/mem.c
+ src/libqhull/usermem.c
+ src/testqset/testqset.c
+ ${testqset_HEADERS}
+)
+
+# Reeentrant Qhull
+
+set(
+ libqhullr_HEADERS
+ src/libqhull_r/libqhull_r.h
+ src/libqhull_r/geom_r.h
+ src/libqhull_r/io_r.h
+ src/libqhull_r/mem_r.h
+ src/libqhull_r/merge_r.h
+ src/libqhull_r/poly_r.h
+ src/libqhull_r/qhull_ra.h
+ src/libqhull_r/qset_r.h
+ src/libqhull_r/random_r.h
+ src/libqhull_r/stat_r.h
+ src/libqhull_r/user_r.h
+)
+set(
+ libqhullr_SOURCES
+ src/libqhull_r/global_r.c
+ src/libqhull_r/stat_r.c
+ src/libqhull_r/geom2_r.c
+ src/libqhull_r/poly2_r.c
+ src/libqhull_r/merge_r.c
+ src/libqhull_r/libqhull_r.c
+ src/libqhull_r/geom_r.c
+ src/libqhull_r/poly_r.c
+ src/libqhull_r/qset_r.c
+ src/libqhull_r/mem_r.c
+ src/libqhull_r/random_r.c
+ src/libqhull_r/usermem_r.c
+ src/libqhull_r/userprintf_r.c
+ src/libqhull_r/io_r.c
+ src/libqhull_r/user_r.c
+ src/libqhull_r/rboxlib_r.c
+ src/libqhull_r/userprintf_rbox_r.c
+ ${libqhullr_HEADERS}
+)
+
+set(
+ libqhullr_DOC
+ src/libqhull_r/index.htm
+ src/libqhull_r/qh-geom_r.htm
+ src/libqhull_r/qh-globa_r.htm
+ src/libqhull_r/qh-io_r.htm
+ src/libqhull_r/qh-mem_r.htm
+ src/libqhull_r/qh-merge_r.htm
+ src/libqhull_r/qh-poly_r.htm
+ src/libqhull_r/qh-qhull_r.htm
+ src/libqhull_r/qh-set_r.htm
+ src/libqhull_r/qh-stat_r.htm
+ src/libqhull_r/qh-user_r.htm
+)
+
+set(
+ testqsetr_HEADERS
+ src/libqhull_r/mem_r.h
+ src/libqhull_r/qset_r.h
+)
+set(
+ testqsetr_SOURCES
+ src/libqhull_r/qset_r.c
+ src/libqhull_r/mem_r.c
+ src/libqhull_r/usermem_r.c
+ src/testqset_r/testqset_r.c
+ ${testqsetr_HEADERS}
+)
+
+# C++ interface to reentrant Qhull
+
+set(
+ libqhullcpp_HEADERS
+ src/libqhullcpp/Coordinates.h
+ src/libqhullcpp/functionObjects.h
+ src/libqhullcpp/PointCoordinates.h
+ src/libqhullcpp/Qhull.h
+ src/libqhullcpp/QhullError.h
+ src/libqhullcpp/QhullFacet.h
+ src/libqhullcpp/QhullFacetList.h
+ src/libqhullcpp/QhullFacetSet.h
+ src/libqhullcpp/QhullHyperplane.h
+ src/libqhullcpp/QhullIterator.h
+ src/libqhullcpp/QhullLinkedList.h
+ src/libqhullcpp/QhullPoint.h
+ src/libqhullcpp/QhullPoints.h
+ src/libqhullcpp/QhullPointSet.h
+ src/libqhullcpp/QhullQh.h
+ src/libqhullcpp/QhullRidge.h
+ src/libqhullcpp/QhullSet.h
+ src/libqhullcpp/QhullSets.h
+ src/libqhullcpp/QhullStat.h
+ src/libqhullcpp/QhullVertex.h
+ src/libqhullcpp/QhullVertexSet.h
+ src/libqhullcpp/RboxPoints.h
+ src/libqhullcpp/RoadError.h
+ src/libqhullcpp/RoadLogEvent.h
+ src/qhulltest/RoadTest.h
+)
+
+set(
+ libqhullcpp_SOURCES
+ src/libqhullcpp/Coordinates.cpp
+ src/libqhullcpp/PointCoordinates.cpp
+ src/libqhullcpp/Qhull.cpp
+ src/libqhullcpp/QhullFacet.cpp
+ src/libqhullcpp/QhullFacetList.cpp
+ src/libqhullcpp/QhullFacetSet.cpp
+ src/libqhullcpp/QhullHyperplane.cpp
+ src/libqhullcpp/QhullPoint.cpp
+ src/libqhullcpp/QhullPointSet.cpp
+ src/libqhullcpp/QhullPoints.cpp
+ src/libqhullcpp/QhullQh.cpp
+ src/libqhullcpp/QhullRidge.cpp
+ src/libqhullcpp/QhullSet.cpp
+ src/libqhullcpp/QhullStat.cpp
+ src/libqhullcpp/QhullVertex.cpp
+ src/libqhullcpp/QhullVertexSet.cpp
+ src/libqhullcpp/RboxPoints.cpp
+ src/libqhullcpp/RoadError.cpp
+ src/libqhullcpp/RoadLogEvent.cpp
+ ${libqhullcpp_HEADERS}
+)
+
+# Documentation files (index.htm refers to html/...)
+
+set(
+ doc_FILES
+ README.txt
+ REGISTER.txt
+ Announce.txt
+ COPYING.txt
+ index.htm
+)
+
+include_directories(${CMAKE_SOURCE_DIR}/src)
+
+if(CMAKE_BUILD_TYPE MATCHES "[dD]ebug")
+ set(qhull_CPP qhullcpp_d)
+ set(qhull_SHARED qhull_d)
+ set(qhull_SHAREDP qhull_pd)
+ set(qhull_SHAREDR qhull_rd)
+ set(qhull_STATIC qhullstatic_d)
+ set(qhull_STATICR qhullstatic_rd)
+else()
+ set(qhull_CPP qhullcpp)
+ set(qhull_SHARED libqhull) # Temporarily avoid name conflict with qhull executable
+ set(qhull_SHAREDP qhull_p)
+ set(qhull_SHAREDR qhull_r)
+ set(qhull_STATIC qhullstatic)
+ set(qhull_STATICR qhullstatic_r)
+endif()
+
+
+
+# ---------------------------------------
+# Define static libraries qhullstatic (non-reentrant) and qhullstatic_r (reentrant)
+# ---------------------------------------
+
+add_library(${qhull_STATIC} STATIC ${libqhull_SOURCES})
+set_target_properties(${qhull_STATIC} PROPERTIES
+ VERSION ${qhull_VERSION})
+
+add_library(${qhull_STATICR} STATIC ${libqhullr_SOURCES})
+set_target_properties(${qhull_STATICR} PROPERTIES
+ VERSION ${qhull_VERSION})
+
+if(UNIX)
+ target_link_libraries(${qhull_STATIC} m)
+ target_link_libraries(${qhull_STATICR} m)
+endif(UNIX)
+
+# ---------------------------------------
+# Define C++ static library qhullcpp
+# Do not create libqhullcpp as a shared library. Qhull C++ classes may change layout and size.
+# ---------------------------------------
+
+add_library(${qhull_CPP} STATIC ${libqhullcpp_SOURCES})
+set_target_properties(${qhull_CPP} PROPERTIES
+ VERSION ${qhull_VERSION})
+
+# ---------------------------------------
+# Define qhull executables linked to qhullstatic library
+# qhull is linked to reentrant qhull (more flexible)
+# the others are linked to non-reentrant qhull (somewhat faster)
+# ---------------------------------------
+
+set(qhull_SOURCES src/qhull/unix_r.c)
+set(rbox_SOURCES src/rbox/rbox.c)
+set(qconvex_SOURCES src/qconvex/qconvex.c)
+set(qdelaunay_SOURCES src/qdelaunay/qdelaun.c)
+set(qvoronoi_SOURCES src/qvoronoi/qvoronoi.c)
+set(qhalf_SOURCES src/qhalf/qhalf.c)
+
+add_executable(qhull ${qhull_SOURCES})
+target_link_libraries(qhull ${qhull_STATICR})
+
+add_executable(rbox ${rbox_SOURCES})
+target_link_libraries(rbox ${qhull_STATIC})
+
+add_executable(qconvex ${qconvex_SOURCES})
+target_link_libraries(qconvex ${qhull_STATIC})
+
+add_executable(qdelaunay ${qdelaunay_SOURCES})
+target_link_libraries(qdelaunay ${qhull_STATIC})
+
+add_executable(qvoronoi ${qvoronoi_SOURCES})
+target_link_libraries(qvoronoi ${qhull_STATIC})
+
+add_executable(qhalf ${qhalf_SOURCES})
+target_link_libraries(qhalf ${qhull_STATIC})
+
+
+# ---------------------------------------
+# Define install
+# ---------------------------------------
+
+install(TARGETS ${qhull_TARGETS_INSTALL}
+ RUNTIME DESTINATION ${BIN_INSTALL_DIR}
+ LIBRARY DESTINATION ${LIB_INSTALL_DIR}
+ ARCHIVE DESTINATION ${LIB_INSTALL_DIR})
+
+install(FILES ${libqhull_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull)
+install(FILES ${libqhull_DOC} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull)
+install(FILES ${libqhullr_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull_r)
+install(FILES ${libqhullr_DOC} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhull_r)
+install(FILES ${libqhullcpp_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/libqhullcpp)
+install(FILES html/qhull.man DESTINATION ${MAN_INSTALL_DIR} RENAME qhull.1)
+install(FILES html/rbox.man DESTINATION ${MAN_INSTALL_DIR} RENAME rbox.1)
+install(FILES ${doc_FILES} DESTINATION ${DOC_INSTALL_DIR})
+install(DIRECTORY html/ DESTINATION ${DOC_INSTALL_DIR})
diff --git a/xs/src/qhull/src/Changes.txt b/xs/src/qhull/src/Changes.txt
new file mode 100644
index 000000000..2dbf41e39
--- /dev/null
+++ b/xs/src/qhull/src/Changes.txt
@@ -0,0 +1,2129 @@
+$Id: //main/2015/qhull/src/Changes.txt#29 $
+
+.............This file lists all changes to qhull and rbox.....................
+
+------------
+Need help
+ - Write an incremental addPoint using bucketed inputs and facet location search (see CGAL)
+ - Compute hyperplanes in parallel (cf. qh_setfactplane)
+ - Create Voronoi volumes and topology using a parallel implementation
+ - Produce conformant triangulations for merged facets using option 'Qt'
+ - Integrate 4dview with Geomview 1.9.5
+ - Qhull needs RPM and Debian builds (CMake's CPackRMP and CPackDeb).
+ - Qhull needs a mirror/archive site for old and new builds
+ - Constrained delaunay triangulation via Shewchuk's algorithm (ACM Symp. Comp. Geo., 1998)
+ - More enhancements -- http://www.qhull.org/html/qh-code.htm#enhance
+ - The C++ interface needs work. Give it a try and make it better.
+ http://github.com/qhull/qhull/wiki
+
+Octave creates endpoints for the ridges that would extend to infinity to be able to draw the diagram [M. Voss]
+
+------
+Qhull 2016.1
+ - Move 'extern "C" {}' logic from C++ to C headers [C. Atkins, github]
+
+ - Explanation of clobbered warning for Qhull::runQhull and qh_new_qhull
+ - html/index.htm: Add "Nearly coincident points" to "When to use Qhull"
+ - html/index.htm: Add Tomilov's qhullhull.hpp for general position input.
+ - index.htm: Add Tomilov's qhullhull.hpp for general position input.
+ - qh-faq.htm: Add a note about merging slivers in a Delaunay triangulation [M. Treacy]
+
+------------
+Qhull 2015.2 2016/01/18 (7.2.0)
+ - Fixed memory leak in ~QhullQh [M. Sandim]
+ QhullQh.cpp: call checkAndFreeQhullMemory() in the destructor. Otherwise memT is not freed.
+ Remove checkAndFreeQhullMemory() from Qhull.h. It is not needed.
+ Remove calls to checkAndFreeQhullMemory in qhulltest. It is called by ~QhullQh()
+ libqhull_r.h: Document qh_ASvornoi and facetT.center
+ qh_freeqhull: if qh_NOmem, use qh_ALL
+ qh_memalloc: short memory is freed by qh_memfreeshort unless qh_NOmem
+ qh_memstatistics (mem.c): call qh_memcheck() as done in mem_r.c
+ qh_new_qhull calls qh_memcheck
+ qh_newvertex: free vertex on error
+ qh_projectinput: Free memory allocations on error
+ qh_rboxpoints: free simplex on error
+ qh_sethalfspace_all: Fixed memory leak on error QH8032 feasible not inside halfspace
+ qh_triangulate_facet: For TRInormals ('Q11') replace qh_copypoints with qh_memalloc
+ qh_triangulate_facet: Document qh.TRInormals
+ qh_voronoi_center: Free center on error
+ qhulltest: Fixed memory leak of s_testcases by calling RoadTest::deleteTests()
+ qhulltest: The 'add_*_test' functions append the test object to RoadTest::s_testcases
+ ~RoadTest: declare virtual for Q_OBJECT, removeAll not needed
+ user_eg2: Check memory at end of each run
+ user_r.h: Add QHULL_CRTDBG for invoking Microsoft's memory leak detector
+ use _MSC_VER instead of QHULL_OS_WIN for QHULL_CRTDBG
+ Call qh_freeqhull with qh_ALL/!qh_ALL instead of 'True/False'
+ Include user_r.h with RoadError,h for QHULL_CRTDBG
+ Invoke _CrtSetDbgFlag... at beginning of program
+ Moved user_r.h/libqhull_r.h/qhull_ra.h as first include (for QHULL_CRTDBG)
+ Moved QHULL_OS_WIN from qhull_ra.h to user_r.h
+ Removed __CYGWIN__ from QHULL_OS_WIN (same as Qt's qglobal.h)
+
+ - check_dupridge: A bounding box is not sufficient to avoid dupridge errors
+ - qh_findbestneighor: Error if qh.CENTERtype is qh_ASvoronoi (i.e., no merging now)
+ - qh_printstatlevel: Remove unused parameter, 'start'
+ - QhullLinkedList::last() and back(): Return T instead of T& (T is computed)
+
+ - qh-code.htm: "How to convert code to reentrant Qhull"
+ Update "Nearly coincident points on an edge"
+ Add 2012 size of data structures to "Qhull on 64-bit computers"
+ - html/index.htm: Add CGAL to "When to use"
+ - qh-optq.htm: Add documentation for option 'Q12'
+ - Move suggestions from Changes.txt to qh-code.htm#enhance
+ - user_r.h: Fixed qh-us_r.html links
+ - Fixed links in html pages
+
+ - QhullIterator and QhullLinkedList: Include <iterator> [B. Boeckel]
+ - Moved include file for each C++ source file to the top of the includes
+ - Prepend cpp includes with "libqhullcpp/"
+ - RoadLogEvent includes RoadLogEvent.h
+ - QhullIterator.h: Only QHULL_DECLARE_SEQUENTIAL_ITERATOR is used.
+
+ - Compared src/libqhull/* to src/libqhull_r/* and resolved differences
+ - qh_printpoint in io.c skips qh_IDnone like io_r.c
+ - qhull_p-exports.def: Added three missing exports
+ - set_r.h: Removed countT. Too many issues
+
+ - libqhull_r/Makefile: Add help prompts to 'make qtest'
+ - libqhull.pro: Add '../libqhull/' to sources and headers
+ - libqhull/Makefile: Fixed -I,./,,/src
+
+ - qhull-zip.sh: Add CMakeModules to tarball [C. Rosenvik]
+ - CMakeLists.txt: Add targets qhullp and user_egp for qh_QHpointer and libqhull_p
+ - Reorganized 'make help'
+ - Makefile cleanall: Delete testqset and qhulltest from bin/
+ - Fix filetype of Unix-only files
+ - Fix Unix line endings for Makefile and check in qhull-zip.sh
+ - Fix Windows line-endings and check in qhull-zip.sh
+ - qhull-zip.sh: Check for Unix text files
+
+ ------------
+Qhull 2015.1 2016/01/03 (7.1.0)
+ - Add Rbox option 'Cn,r,m' to add nearly coincident points. Trigger for duplicate ridges
+ - Add Qhull option 'Q12' to ignore error on wide merge due to duplicate ridge
+
+ - qh_findbestlower: Call qh_findfacet_all to fix rare "flipped or upper Delaunay" error QH6228.
+ QH6228 input provided by J. Metz. Reported (date order): L. Fiaschi, N. Bowler, A. Liebscher, V. Vieira, N. Rhinehart, N. Vance, P. Shafer
+ - qh_check_dupridge: Check if wide merge due to duplicate ridge from nearly coincident points
+ - qh_initialhull: Fix error messages for initial simplex is flat
+ - qh_determinant: increased 2-d and 3-d nearzero by 10x due to a counter-example
+ - rbox: Add qh_outcoord() to output coordinates w/ or w/o iscdd
+ - qh_meminit (mem.c): Add call to qh_memcheck
+ - Compare libqhull/... to libqhull_r/... and resolve differences
+ - Update builds for DevStudio (qhull.sln for msdev 2005..2009, qhull-32.sln and qhull-64.sln for recent releases)
+
+ - qh-impre.htm: Add a section about precision errors for 'Nearly coincident points on an edge'
+ - html/index.htm#geomview: Document how to install, build, and use Geomview.
+ - html/index.htm: Emphasize program links and move related urls to end
+ - qhull/index.htm: Emphasize manual, geomview, and imprecision
+ - Fix documentation links in libqhull_r/index.htm
+ - Add 'Functions' link to documentation headers
+ - Change '<A>...</A>' to '<a>...</a>'
+ - libqhull_r/index.htm -- Add instructions for configuring web browsers for source links.
+ - libqhull_r/ -- Fix source links for ..._r.htm files
+
+------------
+Qhull 2015.0.7 2015/11/09 (7.0.7)
+ - Fix return type of operator-> in QhullLinkedList and other collection classes [F. Jares]
+ - Fix return types for QhullLinkedList
+ - Fix return types for QhullPoints
+ - Simplify return type for Coordinates::operator[] (same as QList)
+ - Add const to operators for QhullSet::iterator and add documentation
+ - Coordinates.h: Fix return types for operations of iterator and const_iterator
+ - Drop use of Perforce changelist number in qhull_VERSION of CMakeLists.txt
+ - Rename the md5sum files as *.tgz.md5sum instead of *-tgz.md5sum
+ - Fix build dependency for testqset_r [asekez]
+ - rbox.c depends on Qhull due to qh_lib_check which uses qh_version2 for error messages
+ - QhullFacet_test.cpp: Annotate Qhull invocations. Allows their repetition.
+ - QhullFacet_test.cpp: Adjust epsilon on distance tests
+ - Do not create libqhullcpp as a shared library. Qhull C++ classes may change layout and size.
+ - qhull-cpp.xml: Make a relative path to road-faq.xsl
+
+------------
+Qhull 2015.0.6 2015/10/20 (7.0.6.2013)
+ - In the libraries, exit() is only called from qh_exit(). qh_exit may be redefined.
+ - Add qh_fprintf_stderr to usermem.c. May be overridden to avoid use of stderr [D. Sterratt]
+ Add usermem to testqset builds
+ Used by qh_fprintf_rbox
+ - Remove most instances of stderr/stdout from libqhull, libqhull_r, and libqhullcpp [D. Sterratt]
+ qh_fprintf_stderr may be redefined. qh_meminit and qh_new_qhull use stderr as the default ferr
+ - qh_initflags: Use qh.fout instead of stdout for 'TO file'. A library caller may define a different qh.fout.
+ - qh_settemppush: Call qh_fprintf() instead of fprintf() on error.
+ - Rename qh_call_qhull as "Qhull-template" from user.c. Updated its references.
+
+ - qh-code.htm: "How to avoid</a> exit(), fprintf(), stderr, and stdout"
+ - html/index.htm: Fix table of contents for qh-code
+ - libqhull_r/index.htm: Rewrite introduction to Reentrant Qhull
+ - qh-faq.htm: Rewrite "Can Qhull use coordinates without placing them in a data file?"
+ - qh-get.html: Link to github
+ - Remove qhull_interface.cpp from the documentation
+
+------------
+Qhull 2015.0.5 2015/10/12 (7.0.5.1995)
+- qh_new_qhull: default 'errfile' is 'stderr'. outfile and errfile are optional [B. Pearlmutter]
+- qh_new_qhull: returns qh_ERRinput instead of exit() if qhull_cmd is not "qhull ..." [B. Pearlmutter]
+- qhalf_r.c,etc: Add clear of qh.NOerrexit
+- global.c: gcc 4.4.0 mingw32 segfault cleared by adding comment
+- usermem_r-cpp.cpp: Optional file to redefine qh_exit() as throw "QH10003.." [B. Pearlmutter]
+ qh_exit() is called by qhull_r when qh_errexit() is not available.
+
+- html/index.htm: Add bibliographic reference to Golub & van Loan and other references [R. Gaul]
+- qhalf.htm: A halfspace is the points on or below a hyperplane [D. Strawn]
+- qh-opto.htm#n: Defined inside, outside, on, above, and below a hyperplane [D. Strawn]
+- qhalf.htm#notes: Recast the linear program using negative halfspaces (as used by Qhull) [D. Strawn]
+- qhull_a.h: Fix comment '#include "libqhull/qhull_a.h" [fe rew]
+
+- build/qhull*.pc.in: Templates for pkg-config (derived from Fedorra) [P. McMunn]
+ https://bitbucket.org/mgorny/pkg-config-spec/src/c1bf12afe0df6d95f2fe3f5e1ffb4c50f018825d/pkg-config-spec.txt?at=master&fileviewer=file-view-default
+- Makefile: Remove user_eg3.o from LIBQHULLCPP_OBJS
+- Makefile: Add .h dependencies for unix_r.o, etc.
+- libqhull/Makefile: Fix build of rbox
+- libqhull_r/Makefile: Fix build -I
+- qhull.sln/user_eg3: Add dependency on libcpp
+- Removed bin/libqhull_r.dll (should be qhull_r.dll)
+- Removed build/qhulltest.vcproj (see build/qhulltest/qhulltest.vcproj)
+
+------------
+Qhull 2015.0.4 2015/9/30 (7.0.4.1984)
+ - qh-get.htm: Unix tarball includes version number (e.g., qhull-2015-src-7.1.0.1940.tgz) [Hauptman]
+ - qglobal.c: Add qh_version2 with Unix version for "-V" option [Hauptman]
+ - build/qhull-32.sln, *-32.vcxproj: Add Visual Studio 32-bit build for 2010+
+ - build/qhull-64.sln, *-64.vcxproj: Add Visual Studio 64-bit build for 2010+ [G. Lodron]
+ - make-vcproj.sh: Restore to eg/... It is required for Visual Studio builds
+ - README.txt: updated builds and reentrant Qhull
+ - Add documentation for QHULL_LIB_CHECK
+ - qh_lib_check: Check for unknown QHULL_LIB_TYPE
+ - qh-code.htm: Add memory requirements for 32- and 64-bit
+
+------------
+Qhull 2015.0.3 2015/9/22
+ - qh_mem, qh_merge: Log before 'delete' instead of afterwards [Coverity, K. Schwehr]
+ - qh_merge: Test for NULL horizon in qh_checkzero [Coverity, K. Schwehr]
+ - qh_matchneighbor: Check for matchfacet not a neighbor of facet [Coverity, K. Schwehr]
+ - qh_triangulate: Explicit check for visible==NULL [Coverity, K. Schwehr]
+ - qh_findbestfacet (unused by qhull): Fix test of isoutside [Coverity, K. Schwehr]
+ - qh_check_maxout: Check bestfacet!=0 for logging its id [Coverity, K. Schwehr]
+ - qh_nearvertex: Check for bestvertex not found [Coverity, K. Schwehr]
+ - qh_checkfacet: Check for missing neighbors of simplicial facets [Coverity, K. Schwehr]
+ - qh_setdelnth: Check 'nth' before using it [Coverity, K. Schwehr]
+ - Annotate code for Coverity warnings (most of these protected by qh_errexit) [K. Schwehr]
+
+ - qh_printfacet3math: explicit format string (duplicates change to io.c) [B. Pearlmutter]
+ - libqhull_r.h: fix spelling error (duplicates change to libqhull.h) [B. Pearlmutter]
+ - unix_r.c: fix spelling error (duplicates change to unix.c) [B. Pearlmutter]
+ - qhull_a.h: define qhullUnused() only if defined(__cplusplus) [R. Stogner]
+ - qh_version: Use const char str[]= "string" instead of const char * str= "string" [U. Drepper, p. 27]
+ - qh_newvertex: Use UINT_MAX instead of 0xFFFFFFFF
+ - qh_newridge: Use UINT_MAX instead of 0xFFFFFFFF
+ - Reviewed FIXUP notes
+
+ - QhullRidge_test: t_foreach use 'foreach(const QhullVertex &v, vertices)
+ - Made '#include "RoadTest.h" consistent across all C++ tests
+
+ - qh-code.htm: May also use libqhull_r (e.g., FOREACHfacet_(...))
+ - qh-get.htm: Add list of download build repositories
+
+ - Add CMakeModules/CheckLFS.cmake: Enables Large File Support [B. Pearlmutter]
+ - Makefile: Use -fpic at all times instead of -fPIC, [U. Drepper p. 15]
+
+------------
+Qhull 2015.0.2 2015/9/1
+ - global_r.c: Fixed spelling of /* duplicated in...qh_clear_outputflags */ [K. Schwehr]
+ - Replaced Gitorious with GitHub
+ - Moved 'to do' comments into Changes.txt
+
+------------
+Qhull 2015.0.1 2015/8/31
+
+ Source code changes
+ - Increased size of vertexT.id and ridgeT.id to 2^32 [H. Strandenes, C. Carson, K. Nguyen]
+ Reworded the warning message for ridgeT.id overflow. It does not affect Qhull output
+ - Add qh_lib_check to check for a compatible Qhull library.
+ Programs should call QHULL_LIB_CHECK before calling Qhull.
+ - Include headers prefixed with libqhull/, libqhull_r/, or libqhullcpp/
+ - Renamed debugging routines dfacet/dvertex to qh_dfacet/qh_dvertex
+ - Rewrote user_eg, user_eg2, and user_eg3 as reentrant code
+ - Renamed 'qh_rand_seed' to 'qh_last_random'. Declare it as DATA
+ - qh_initqhull_start2 sets qh->NOerrexit on initialization
+ User must clear NOerrexit after setjmp()
+
+ Other source code changes
+ - Define ptr_intT as 'long long' for __MINGW64__ [A. Voskov]
+ - poly_r.c: initialize horizon_skip [K. Schwehr]
+ - Removed vertexT.dim and MAX_vdim. It is not used by reentrant Qhull.
+ - Removed qhull_inuse. Not used by C++
+ - Removed old __MWERKS__/__POWERPC__ code that speed up SIOUX I/O
+ - Moved #include libqhull/... before system includes (e.g., <stdio.h>
+ - Comment-out _isatty declaration. Avoids "C4273 ... inconsistent dll linkage"
+ - Add random.h/random_r.h as an include file to random.c/random_r.c
+ - Rename rbox routines to qh_roundi/qh_out1/qh_out2n/qh_out3n
+ - Rename dfacet and dvertex to qh_dfacet and qh_dvertex
+ - Replace 'qhmem .zzz' with 'qhmem.zzz'
+ - Removed spaces between function name and parentheses
+ - Rename 'enum statistics' to 'enum qh_statistics'
+ - Declare rbox as DATA in qhull-exports.def and qhull_p-exports.def
+ - In comments, use 'qh.zzz' to reference qhT fields
+ - In qh_fprintf, use qhmem.ferr to report errors
+ - qh_fprintf may be called for errors in qh_initstatistics and qh_meminit
+ - qh_pointid returns qh_IDnone, qh_IDinterior, qh_IDunknown in place of -3, -2, -1 resp.
+ - getid_() returns qh_IDunknown in place of -1
+ - After qh_meminit, qhmem.ferr is non-zero (stderr is the default)
+ - Update qh_MEMalign in testqset.c to user.h (with realT and void*)
+ - Split rboxT into a header file
+ - Add rboxlib.h to libqhull_a.h
+ - Rename PI to qh_PI and extend to 30 digits
+ - Rename MAXdim to qh_MAXdim
+ - Change spacing for type annotations '*' and '&' in C++ header files
+ - Test for !rbox_output/cpp_object in qh_fprintf_rbox
+ - Remove 'inline' annotation from explicit inline declarations
+ - Column 25 formatting for iterators, etc.
+ - Use '#//!\name' for section headers
+ - QhullFacet.cpp: zinc_(Zdistio);
+ - Clear qhT.ALLOWrestart in qh_errexit
+ - Replace longjmp with qh_errexit_rbox in qh_rboxpoints
+ - Add jmpExtra after rbox_errexit to protect against compiler errors
+ - Add qh.ISqhullQh to indicate initialization by QhullQh()
+ - Add library warnings to 'rbox D4', user_eg, user_eg2, user_eg3
+ - Add headers to q_eg, q_egtest, and q_test
+ - Check that qh.NOerrexit is cleared before call to qh_initflags
+
+Qhull documentation
+ - README.txt: Added references to qh-code.htm
+ - README.txt: Added section 'Calling Qhull from C programs'
+ - qh-code.htm: Moved Performance after C++ and C interface
+ - qh-code.htm: Moved Cpp Questions to end of the C++ section
+ - qh-code.htm: Fixed documentation for 'include' path. It should be include/libqhull
+ - qconvex.htm: Fixed documentation for 'i'. It triangulates in 4-d and higher [ref]
+ - Clarified qhalf space documentation for the interior point [J. Santos]
+ - rbox.c: Version is same date as qh_version in global.c
+ - gobal_r.c: Version includes a '.r' suffix to indicate 'reentrant'
+
+Qhull builds
+ - Development moved to http://github.com/qhull/qhull
+ git clone git@github.com:qhull/qhull.git
+ - Exchanged make targets for testing.
+ 'make test' is a quick test of qhull programs.
+ 'make testall' is a thorough test
+ - Added 'make help' and 'make test' to libqhull and libqhull_r Makefiles
+ - CMakeLists.txt: Remove libqhull, libqhull_r, and libqhullcpp from include_directories
+ - CMakeLists.txt: Add qhull_SHAREDR for qhull_r
+ - CMakeLists.txt: Retain qhull_SHARED and qhull_SHAREDP (qh_QHpointer)
+ - CMakeLists.txt: Move qhull_SHARED and qhull_SHAREDP (qh_QHpointer) to qhull_TARGETS_OLD
+ Drop qhull_STATICP (use qhull_SHAREDP or qhull_STATIC)
+ Set SOVERSION and VERSION for shared libraries
+ - Move qhull_p-exports.def back to libqhull
+ - Switched to mingw-w64-install for gcc
+ - Improved prompts for 'make'
+ - qhull-all.pro: Remove user_eg3.cpp from OTHER_FILES
+ - libqhull.pro: Ordered object files by frequency of execution, as done before
+ - Add the folder name to C++ includes and remove libqhullcpp from INCLUDEPATH
+ - Changed CONFIG+=qtestlib to QT+=testlib
+ - Changed Makefile to gcc -O3 (was -O2)
+ - Changed libqhull/libqhull_r Makefiles to both produce rbox, qhull, ..., user_eg, and user_eg2
+ - Removed Debian 'config/...'. It was needed for Qhull 2012.
+
+libqhull_r (reentrant Qhull)
+ - Replaced qh_qh with a parameter to each procedure [P. Klosterman]
+ No more globally defined data structures in Qhull
+ Simplified multithreading and C++ user interface
+ All functions are reentrant (Qt: "A reentrant function can ... be called simultaneously from multiple threads, but only if each invocation uses its own data.")
+ No more qh_QHpointer.
+ See user_eg3 and qhulltest
+ New libraries
+ libqhull_r -- Shared library with reentrant sources (e.g., poly_r.h and poly_r.c which replace libqhull's poly.h and poly.c)
+ libqhullstatic_r -- Static library with the same sources as libqhull_r
+ libqhullcpp -- The C++ interface using libqhullstatic_r (further notes below)
+ New executables
+ testqset_r -- Test qset_r.c (the reentrant version of qset.c
+
+ Source code changes for libqhull_r
+ - Add qh_zero() to initialize and zero memory for qh_new_qhull
+ - Remove qh_save_qhull(), qh_restore_qhull(), and qh.old_qhstat from global_r.c
+ - Remove qh_freeqhull2() (global_r.c)
+ - Remove qh_freestatistics() (stat_r.c)
+ - Remove qh_compare_vertexpoint (qhT is not available, unused code)
+ - Remove conditional code for __POWERPC__ from unix_r.c and rbox_r.c
+ - Move qh_last_random into qh->last_random (random_r.c)
+ - Rename sources files with a '_r' suffix. qhull_a.h becomes qhull_ra.h
+ - Replace 'qh' macro with 'qh->'
+ - Replace global qhT with parameter-0
+ - Add qhmemT to beginning of qhT. It may not be used standalone.
+ - Add qhstatT to end of qhT
+ - Remove qhull_inuse
+ - Change qhmem.zzz to qh->qhmem.zzz
+ - Replace qh_qhstat with qh->qhstat
+ - Remove qh_freestatistics
+ - Replace qh_last_random with qh->last_random
+ - Replace rboxT with qh->rbox_errexit, rbox_isinteger, rbox_out_offset
+ - Replace rbox.ferr/fout with qh->ferr/fout
+ - No qh for qh_exit, qh_free, qh_malloc, qh_strtod, qh_strtol, qh_stddev
+ - New qmake include files qhull-app-c_r.pri, qhull-app-shared_r.pri, qhull-libqhull-src_r.pri
+ - Replace 'int' with 'countT' and 'COUNTmax' for large counts and identifiers
+ - qhset converted to countT
+ - Removed vertexT.dim -- No longer needed by cpp
+ Removed MAX_vdim
+ - Guarantee that qh->run_id!=0. Old code assumed that qh_RANDOMint was 31 bits
+
+Changes to libqhullcpp
+ - Added QhullVertexSet.h to libqhullcpp.pro and libqhullpcpp.pro
+ - QhullVertexSet: error if qhsettemp_defined at copy constructor/assignment (otherwise double free)
+ - Enable QhullSet.operator=. Copy constructor and assignment only copies pointers
+ - Changed QhullPoint.operator==() to sqrt(distanceEpsilon)
+ - Added assignment of base class QhullPoints to PointCoordinates.operator=
+ - Enable QhullPoints.operator=
+ - Rename PointCoordinates.point_comment to describe_points
+ - Add 'typename T' to definition of QhullSet<T>::value()
+
+C++ interface
+ - Reimplemented C++ interface on reentrant libqhull_r instead of libqhull
+ - Prepend include files with libqhullcpp/
+ - Replaced UsingLibQhull with QhullQh and macro QH_TRY
+ Removed UsingLibQhull.currentAngleEpsilon and related routines
+ Removed UsingLibQhull_test.cpp
+ Replaced globalDistanceEpsilon with QhullQh.distanceEpsilon
+ Replaced globalAngleEpsilon with QhullQh.angleEpsilon
+ Moved UsingQhullLib.checkQhullMemoryEmpty to QhullQh.checkAndFreeQhullMemory
+ Replaced FACTORepsilon=10 with QhullQh.factor_epsilon=1.0
+ - To avoid -Wshadow for QhullQh*, use 'qqh' for parameters and 'qh()' for methods
+ - Moved messaging from Qhull to QhullQh
+ - Add check of RboxPoints* in qh_fprintf_rbox
+ - Renamed Qhull.initializeQhull to Qhull.allocateQhullQh
+ Added qh_freeqhull(!qh_ALL) as done by unix.c and other programs
+ - Moved QhullPoints.extraCoordinatesCount into QhullPoints.cpp
+ - Replaced section tags with '#//!\name ...'
+ - Removed qhRunId from print() to ostream.
+ - Removed print() to ostream. Use '<< qhullPoint' or '<< qhullPoint.print("message")'
+
+C++ interface for most classes
+ - Remove qhRunId
+ - Add QhullQh *qh_qh to all types
+ Pointer comparisons of facetT,etc. do not test corresponding qh_qh
+ Added to end of type for debugging information, unless wasteful alignment
+ - Add QhullQh * to all constructors
+ - All constructors may use Qhull & instead of QhullQh *
+ - For inherited QhullQh types, change to 'protected'
+ - Renamed 'o' to 'other' except where used extensively in iterators
+ - Except for conditional code, merged the Conversion section into GetSet
+ - Removed empty(). Use isEmpty() instead
+ - Add operator= instead of keeping it private
+ - print_message=0 not allowed. Use "" instead.
+ - Rename isDefined() to isValid() to match Qt conventions
+
+C++ interface by class
+ - Coordinates
+ Removed empty(). Use isEmpty() instead
+ Added append(dim, coordT*)
+ Reformated the iterators
+ Convert to countT
+ - PointCoordinates
+ Added constructors for Qhull or QhullQh* (provides access to QhullPoint.operator==)
+ Removed PointCoordinates(int pointDimension) since PointCoordinates should have a comment. Also, it is ambiguous with PointCoordinates(QhullQh*)
+ Renamed point_comment to describe_points
+ Convert to countT
+ - Qhull
+ Remove qhull_run_i
+ Remove qh_active
+ Replace property feasiblePoint with field feasible_point and methods setFeasiblePoint/feasiblePoint
+ Returns qh.feasible_point if defined
+ Moved useOutputStream to QhullQh use_output_stream
+ Renamed useOutputStream() to hasOutputStream()
+ Replaced qhull_dimension with qh->input_dim //! Dimension of result (qh.hull_dim or one less for Delaunay/Voronoi)
+ Removed global s_qhull_output= 0;
+ Move qhull_status, qhull_message, error_stream, output_stream to QhullQh
+ Renamed qhullQh() to qh()
+ Added check of base address to allocateQhullQh(), Was not needed for qhullpcpp
+ - QhullFacet
+ Constructor requires Qhull or QhullQh* pointer
+ Convert to countT
+ Dropped implicit conversion from facetT
+ Dropped runId
+ Add print("message") to replace print()
+ - QhullFacetList
+ Constructor requires Qhull or QhullQh* pointer
+ Convert to countT
+ Dropped runId
+ - QhullFacetSet
+ Removed empty(). Use isEmpty() instead
+ Constructor requires Qhull or QhullQh* pointer
+ Convert to countT
+ Dropped runId
+ Add operator=
+ Implement print("message")
+ - QhullHyperplane
+ Add hyperplaneAngle() method
+ Rewrite operator== to use hyperplaneAngle()
+ Reorganize fields to keep pointers aligned
+ Except for default constructor requires Qhull or QhullQh* pointer
+ Enable copy assignment
+ Reorganized header
+ - QhullLinkedList
+ Add operator=
+ Removed empty(). Use isEmpty() instead
+ Convert to countT
+ iterator(T) made iterator(const T &)
+ const_iterator(T) made const_iterator(const T &)
+ const_iterator(iterator) made const_iterator(const iterator &)
+ - QhullPoint
+ Add constructors for Qhull or QhullQh* pointer (for id() and operator==)
+ Add defineAs(coordT*)
+ Add getBaseT() and base_type for QhullSet<QhullPoint>
+ Added checks for point_coordinates==0
+ Removed static QhullPoint::id(), use QhullPoint.id() instead
+ distance() throws an error if dimension doesn't agree or if a point is undefined
+ Convert to countT
+ If !qh_qh, operator==() requires equal coordinates
+ Use cout<<p instead of cout<<p.print()
+ Reorganized
+ - QhullPoints
+ Add constructors for Qhull and QhullQh* (for qh.hull_dim, QhullPoint::operator==)
+ Remove QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh)
+ Add operator=
+ Removed empty(). Use isEmpty() instead
+ Convert to countT
+ operator==() tests if pointers are the same. Ituses distanceEpsilon if qh_qh is defined
+ Reorganized
+ - QhullPoints::Iterator and ConstIterator
+ Removed default constructors
+ Add constructors for Qhull and QhullQh* (for qh.hull_dim, QhullPoint::operator==)
+ Moved test of dimension from QHULL_ASSERT to operator==
+ Added QHULL_ASSERT of qh_qh
+ Convert to countT
+ - QhullPointSet
+ Constructor requires Qhull or QhullQh* instead of dimension()
+ Add operator=
+ Removed empty(). Use isEmpty() instead
+ Convert to countT
+ Always print print_message
+ Drop print(). Replace with print("")
+ - QhullQh
+ Added methods hasOutputStream(), disableOutputStream(), and enableOutputStream() (was Qhull UseOutputStream)
+ Add test of qh.NOerrexit to maybeThrowQhullMessage()
+ Add qhull_status, qhull_message, error_stream, output_stream from Qhull
+ Add factor_epsilon
+ - QhullRidge
+ Constructor requires Qhull or QhullQh* pointer
+ Dropped implicit conversion from ridgeT
+ Converted otherFacet() to 'const &'
+ Converted nextRidge3d() to 'const &'
+ Message for '<< QhullRidge' replaces " - " instead of preceding it
+ - QhullSet
+ Removed empty(). Use isEmpty() instead
+ Constructor requires Qhull or QhullQh* pointer
+ Convert to countT
+ Add operator=
+ - QhullVertex
+ Constructor requires Qhull or QhullQh* pointer
+ Convert to countT
+ Dropped implicit conversion from vertexT
+ Add message to '<< QhullVertex'
+ - QhullVertexSet
+ Removed empty(). Use isEmpty() instead
+ Constructor requires Qhull or QhullQh* pointer
+ Convert to countT
+ - UsingQhullLib
+ Removed
+ Replace setGlobalDistanceEpsilon with setFactorEpsilon
+ Replace globalDistanceEpsilon with distanceEpsilon
+
+------------
+Qhull 2012.1 2012/02/18 6.3.1.1494
+ - Fix CMakeLists for libqhull with MATCHES [P. Gajdos]
+
+------------
+Qhull 2012.1 2012/02/18 6.3.1.1490
+
+Code changes
+ - Require option 'Qz' for Delaunay triangulation/Voronoi diagram
+ of cocircular/cospherical points [D. Sheehy]
+ - qh_errexit: Do not call qh_printsummary or qh_printstats on qh_ERRinput
+ - Change error QH6227 (all degenerate) from qh_ERRinput to qh_ERRprec
+ - Change error QH6159 (ID overflow) from qh_ERRinput to qh_ERRqhull
+ - eg/q_eg, q_egtest, q_test: Run if qconvex is in $PATH [M. Atzeri]
+
+Build changes [M. Atzeri]
+ - Install to share/doc/qhull instead of share/doc/packages/qhull
+ - On Unix systems, install to share/man/man1 instead of man/man1
+ - CMakeLists: Remove the installation of user_eg* and testqset
+ - CMakeLists: Remove VERSION from qhull executables and libraries
+ - CMakeLists: Define qhull_SOVERSION instead of qhull_MAJOR
+ - CMakeLists: Set SOVERSION for shared libraries
+ - Rename libraries to qhull, qhull_d, qhull_p, and qhull_pd
+ libqhull6_p.vcproj is now libqhull_p.vcproj
+ mingw builds as libqhull.dll
+ cygwin builds as cygqhull-6.dll
+ linux builds as libqhull.so.6.3.1 with symbolic link as libqhull.so
+ - Developers using qhull 2011:
+ libqhull6.so is now libqhull_p.so. Do not use libqhull.so.
+ qhull6.dll is now qhull_p.dll. Do not use qhull.dll.
+ - Merged road/ into libqhullcpp/ and qhulltest/
+ Moved RoadLogEvent.* and RoadError.* to libqhullcpp
+ Moved RoadTest.* to qhulltest (requires Qt)
+ Installed RoadTest.h in libqhullcpp
+
+Doc changes
+ - index.htm: Mathworks uses qhull for n-d
+ - qhull.htm: Fix qhull for qconvex
+ - qdelaun.htm/qvoronoi.htm: Use option 'Qz' for circular/cospherical inputs
+ - make help: Display targets
+ - Makefile: Better messaging
+
+------------
+Qhull 2012.1 2012/02/02 6.3.0.1483
+
+Bug fixes
+ - Fixed qset.c for -fno-strict-aliasing. This gcc option is no longer needed
+ (disallow two pointers of differing types to the same memory location)
+ - Fixed error in qh_setappend_set if first set full and second set empty
+ - qh_setdelnth, qh_setdelnth_sorted: fixed wording of error message
+ - qh_setcheck: error message listed size and max backwards.
+ - qh_setequal: Allow NULL set as documented
+ - qh_setindex: Allow NULL set as documented
+ - qh_settemppush: report error if NULL
+
+Code changes
+ - Add testqset: low level test of qset.c with mem.c
+ - qh_setendpointer: Implements QSet::endPointer()
+ - Assigned unique error code for qh_gethash
+
+Build changes
+ - Added qhull.dll(.so) for Octave and other Debian builds
+ The global data structure qh_qh is statically defined (no qh_QHpointer)
+ Linked user_eg2 with qhull.dll (libqhull.so) instead of qhullstatic
+ Added qh_dllimport to libqhull.h for qhull.dll with MSVC
+ Changed qhull-app-shared.pri to use libqhull (without qh_QHpointer)
+ - Renamed libqhull6.so to libqhull6_p.so
+ Renamed qhull6.dll to qhull6_p.dll
+ The _p libraries (e.g., libqhull6_p.so) require -Dqh_QHpointer
+ Renamed qhull6.vcproj to libqhull6_p.vcproj
+ Added libqhullp/libqhullp.pro for shared library (libqhull6_p.so)
+ Added qhull-app-sharedp.pri for shared libraries with qh_QHpointer
+ - Install libqhull/*.htm files into include/libqhull
+ - Removed libqhull/qhull.h-deprecated [J. Eaton]
+ - Other changes to Makefile builds
+ Added 'make qtestall' as a smoketest of each qhull program
+ src/libqhull/Makefile: Use 'ar -rs ...' instead of ranlib
+ src/libqhull/Makefile: Fixed targets for cleanall
+ - Other changes to DevStudio builds
+ Moved pdb files for qhull libraries to lib/
+ AdditionalIncludeDirectories: Removed ../src/libqhullcpp
+ Use build-cmake/ for the DevStudio CMake build
+ - Other changes to Qt builds
+ Renamed qhull-libsrc.pri to qhull-libqhull-src.pri
+ - Added explicit d2u conversions to qhull-zip.sh
+ - Fixed \n vs. \r\n issues for Windows source files
+
+ Draft of Debian/AutoConf build (untested)
+ - Adjusted the Makefile.am's for the new directory structure.
+ - Added testqset to bin_PROGRAMS
+ - config/bootstrap.sh copies program sources into src/libqhull
+ - Kept qh_QHpointer=0 (static global data structure, qh_qh). It is faster.
+ Planning a new interface (qhull7?) which passes qh_qh as a parameter
+ - Added config/changelog from the 2003.1 Debian build
+ - Moved the debian/patches directory to config/
+ Optional patches to change smoketest message and turn on qh_QHpointer
+ - Deleted the debian directory. It was the old Debian build from 2003.1
+ Rafael Laboissiere's config directory replaced this build..
+ - Deleted Make-conf.sh (also the old Debian build)
+
+Doc changes
+ - FAQ: Updated notes on computing volume of a Voronoi region
+ - Added direct link to ACM Digital Library for downloading the qhull paper
+ - Added link to Qhull in R
+ - qset.c: Updated notes about NULL sets
+ - qh_setappend: clarify qh_setappend for NULL newelem
+ - qh_setdellast: Fix head note
+ - Add build/README.txt
+ - Add uninstall instructions to README.txt and CMakeLists.txt
+ - Added instructions to create build/*.vcproj to CMakeLists.txt
+ - Update copyright to 2012
+ - Updated page links. Added Google books, patents, and blogs.
+
+-----------
+Qhull 2009.1.3 2011/12/06
+ configure: Add -fno-strict-aliasing if $GCC, Required for gcc 4.1+
+
+------------
+Qhull 2011.2 2011/11/29 6.2.1.1446
+
+Bug fixes
+ - qh_new_qhull: Call qh_prepare_output if !outfile [A. Aldoma]
+ No effect on qhull users since qh_prepare_output is always called.
+ - Replace Qhull-go.pif with Qhull-go.lnk for Windows 7 64-bit [lots]
+ - Error if qh_newhashtable, qh_setnew, or qh_memalloc overflows [X. Cheng]
+ For example, 'rbox 64 D32' overflows hash table for qh_matchnewfacets
+ Qhull uses 32-bit ints for identifiers, counts, and sizes. See "WARN64"
+ - q_eg, q_test: change tail +3 to tail -n +3 [N. Dubray, M. Atzeri]
+ - Qhull-go.bat: Changed 'cmd' to '%comspec%'
+
+Build changes
+ - Added src/libqhull/Makefile for simple gcc build of executables and lib
+ - qhulltest.vcproj: Replaced full path to QT with $QTDIR (e.g., c:/qt/4.7.4)
+ - Split userprintf_rbox.c from userprintf.c,
+ Otherwise qhull brings in rboxlib and rbox brings in libqhull
+ - Makefile: qhullx target must be after LIBQHULLS_OBJS
+ - Makefile: Explicitly list rbox dependencies for qhullx target
+ - MBorland: Fixed tabs
+ - Placed $LIBQHULLS_OBJS in same order. Frequently called ones together.
+ - Update file lists for Make-config.sh [O. Lahaye]
+ - CMakeLists: add README.txt,etc. to DOC_INSTALL_DIR [M. Atzeri]
+ - Restored qhull.h-deprecated.
+ qhull.h conflicts with Qhull.h on Windows systems [C. Abela]
+ - make-config.sh: Add warning that it is out-of-date
+ - Remove extra space in '#! /bin/sh' in q_eg, etc. [P. Cheeseman]
+
+Source changes
+ - libqhull.h: Added qh_True and qh_False for True/False [A. Mutzel]
+ Did not remove or replace True/False since it is used everywhere
+ - Moved error message from qh_argv_to_command to caller. Avoids dependency.
+ - user_eg3.c: Use '10 D2' as default rbox (e.g., 'user_eg3 rbox qhull d')
+ - user.c, user_eg2.c: Add test of qh_qh as done in user_eg.c
+ - q_test: Removed duplicate test of qhull C-0.02
+
+Documentation
+ - index.html: Added ACM Authorizer link to ACM Trans. Math. Software
+ - Split Delaunay and Voronoi FAQs
+ - FAQ: How to compute the volume of a Voronoi region [C, Brinch]
+ - Add 'FS' to qconvex prompt (total area and volume)
+ - Add clarification to 'Fv' about corner input sites [O. Can]
+ - Qhull-go.bat: Removed out-of-date advice. Added title.
+ - qh-code.htm: Updated the discussion of multi-threading for C++ [I. Pirwani]
+
+Qhull 2009.1.2 2011/11/21
+ - Revert to LF line endings [P. Cheeseman]
+ - Remove out-of-date material from qhull-go.bat
+ - Replaced QHULL-GO with a lnk file
+
+Qhull 2011.1 2011/05/23 6.2.0.1385 (exe/dll files unchanged)
+ - delaunay.vcproj: Fixed qhullstatic_d.lib for debug and minrelsize builds
+ - Did not redate the distribution
+
+Qhull 2011.1 2011/05/18 6.2.0.1385 (exe/dll files unchanged)
+ - Add 'm' library to shared and static targets on Unix [A. Bouchard]
+
+Qhull 2011.1 2011/05/14 6.2.0.1383 (exe/dll files unchanged)
+ - PointCoordinates.cpp: Add #include <iterator> [R. Richter, S. Pasko]
+ - Remove deprecated libqhull/qhull.h
+ Use libqhull/libqhull.h instead. Avoids confusion with libqhullcpp/Qhull.h
+ - Makefile: Add LIBDIR, INCDIR, and DESTDIR to install [L.H. de Mello]
+ Separate MAN install from DOC install
+ Create install directories
+ Installs headers to include/libqhull, include/libqhullcpp, include/road
+ - CMakeLists.txt: Add MAN_INSTALL_DIR for qhull.1 and rbox.1 man pages
+ Add RoadTest.h to include/road for Qt users (road_HEADERS)
+ - Renamed md5sum files to avoid two extensions
+ - qh-get.htm: Add Readme links and 2009.1 note.
+ - qh-optf.htm: Fix link
+ - index.htm: Updated Google Scholar link
+ - qhull-zip.sh: Improved error message.
+
+------------
+Qhull 2011.1 2011/04/17 6.2.0.1373
+
+Changes to deliverables
+ - qvoronoi: Deprecated 'Qt' and 'QJn'. Removed from documentation and prompts.
+ These options produced duplicate Voronoi vertices for cospherical data.
+ - Removed doskey from Qhull-go.bat. It is incompatible with Windows 7
+ - Added 'facets' argument to user_eg3.cpp
+ - user_eg links with shared library
+ - qhulltest.cpp: Add closing prompt.
+
+Changes to build system
+ - Reorganized source directories
+ - Moved executables to bin directory
+ - Add CMake build for all targets (CMakeFiles.txt) [M. Moll assisted]
+ - Add gcc build for all targets (Makefile)
+ - Fixed location of qhull.man and rbox.man [M. Moll]
+ - Add DevStudio builds for all targets (build/*.vcproj)
+ - Added shared library (lib/qhull6.dll)
+ Added qh_QHpointer_dllimport to work around problems with MSVC
+ - Added static libraries with and without qh_QHpointer (lib/qhullstatic.lib)
+ - Added eg/make-vcproj.sh to create vcproj/sln files from cmake and qmake
+ - Document location of qh_QHpointer
+ - Use shadow build directory
+ - Made -fno-strict-aliasing conditional on gcc version
+ - Added src/qhull-app-cpp.pri, src/qhull-app-c.pri, etc. for common settings
+ - Add .gitignore with ignored files and directories.
+ - Use .git/info/exclude for locally excluded files.
+ - Fixed MBorland for new directory structure
+ - cleanall (Makefile): Delete 'linked' programs due to libqhull_r and libqhull/Makefile
+
+Changes to documentation
+ - qvoronoi.htm: Remove quotes from qvoronoi example
+ - qhull-cpp.xml: Add naming conventions
+ - index.htm: Add Google Scholar references
+ - qh-optf.htm: Add note about order of 'Fn' matching 'Fv' order [Q. Pan]
+ - Add patch for old builds in qh-get.htm
+ - Added C++ compiling instructions to README.txt
+ - Add instructions for fixing the DOS window
+ - Changed DOS window to command window
+ - Fixed html links
+ - qh-get.htm: Dropped the Spanish mirror site. It was disabled.
+
+Changes to C code
+ - mem.h: Define ptr_intT as 'long long' for Microsoft Windows _win64 builds.
+ On Linux and Mac, 'long' is 64-bits on a 64-bit host
+ - Added qh_QHpointer_dllimport to work around MSVC problem
+ - qconvex.c,etc.: Define prototype for _isatty
+ - Define MSG_QHULL_ERROR in user.h
+ - Move MSG_FIXUP to 11000 and updated FIXUP QH11...
+
+Changes to test code
+ - Add note to q_test than R1e-3 may error (qh-code.htm, Enhancements)
+ - Add test for executables to q_eg, etc.
+ - Fixed Qhull-go.bat. QHULL-GO invokes it with command.com,
+
+Changes to C++ interface
+ - QhullFacet: Added isSimplicial, isTopOrient, isTriCoplanar, isUpperDelaunay
+ - Added Qhull::defineVertexFacetNeighbors() for facetNeighbors of vertices.
+ Automatically called for facet merging and Voronoi diagrams
+ Do not print QhullVertex::facetNeighbors is !facetNeighborsDefined()
+ - Assigned FIXUP identifiers
+ - QhullError: Add copy constructor, assignment operator, and destructor
+ - Add throw() specifiers to RoadError and QhullError
+ - Renamed RoadError::defined() to RoadError::isDefined()
+ - Add #error to Qhull.h if qh_QHpointer is not defined
+
+Changes to C++ code
+ - Fixed bug reported by renangms. Vertex output throws error QH10034
+ and defineVertexNeighbors() does not exist.
+ - Define QHULL_USES_QT for qt-qhull.cpp [renangms]
+ - Reviewed all copy constructors and copy assignments. Updated comments.
+ Defined Qhull copy constructor and copy assignment [G. Rivet-Sabourin]
+ Disabled UsingQhullLib default constructor, copy construct, and copy assign
+ - Merged changes from J. Obermayr in gitorious/jobermayrs-qhull:next
+ - Fix strncat limit in rboxlib.c and global.c
+ - Changes to CMakeLists.txt for openSUSE
+ - Fixed additional uses of strncat
+ - Fixed QhullFacet::PrintRidges to check hasNextRidge3d()
+ - Removed gcc warnings for shadowing from code (src/qhull-warn.pri)
+ - Removed semicolon after extern "C" {...}
+ - Removed experimental QhullEvent/QhullLog
+ - Use fabs() instead of abs() to avoid accidental conversions to int
+ - Fixed type of vertex->neighbors in qh_printvoronoi [no effect on results]
+ - Removed unnecessary if statement in qh_printvoronoi
+
+------------
+qhull 2010.1 2010/01/14
+- Fixed quote for #include in qhull.h [U.Hergenhahn, K.Roland]
+- Add qt-qhull.cpp with Qt conditional code
+- Add libqhullp.proj
+- Add libqhull5 to Readme, Announce, download
+- Reviewed #pragma
+- Reviewed FIXUP and assigned QH tags
+- All projects compile with warnings enabled
+- Replaced 'up' glyphs with &#187;
+- Moved cpp questions to qh-code.htm#questions-cpp
+- Moved suggestions to qh-code.htm#enhance
+- Moved documentation requests to qh-code.htm#enhance
+- Add md5sum file to distributions
+- Switched to DevStudio builds to avoid dependent libraries, 10% slower
+ Removed user_eg3.exe and qhullcpp.dll from Windows build
+ Fix qhull.sln and project files for qh_QHpointer
+- Add eg/qhull-zip.sh to build qhull distribution files
+
+------------
+qhull 2010.1 2010/01/10
+- Test for NULL fp in qh_eachvoronoi [D. Szczerba]
+
+qhull 2010.1 2010/01/09
+
+Changes to build and distribution
+- Use qh_QHpointer=0 for libqhull.a, qhull, rbox, etc.
+ Use -Dqh_QHpointer for libqhullp.a, qhullcpp.dll, etc.
+ qh_QHpointer [2010, gcc] 4% time 4% space, [2003, msvc] 8% time 2% space
+- Add config/ and project/debian/ for Autoconf build [R. Laboissiere]
+ from debian branch in git and http://savannah.nongnu.org/cvs/?group=qhull
+- Add CMakeLists.txt [kwilliams]
+- Fix tabs in Makefile.txt [mschamschula]
+- Add -fno-strict-aliasing to Makefile for gcc 4.1, 4.2, and 4.3 qset segfault
+- Remove user_eg.exe and user_eg2.exe from Windows distribution
+- Order object files by frequency of execution for better locality.
+
+Changes to source
+- Remove ptr_intT from qh_matchvertices. It was int since the beginning.
+- user.h requires <time.h> for CLOCKS_PER_SEC
+- Move ostream<<QhullFacetList from inline to compiled.
+- Removed ConvexHull/ from git. Not used.
+
+------------
+qhull 2009.1.1 2010/01/09
+- Patch release of 2009.1.
+ qh_gethash allowed a negative result, causing overwrite or segfault
+ See git:qhull/project/patch/qhull-2003.1/poly.c-qh_gethash.patch
+ Compared results of q_test, q_eg, q_egtest with patched poly.c, qhull-2003.1
+
+------------
+qhull 2010.1 2010/01/07
+- Assign type to qh.old_qhstat and memT.tempstack [amorilia]
+- Replace tabs with spaces.
+- Fix qh_pointid in case ptr_intT is unsigned
+
+qhull 2010.1 2010/01/06
+- Fixed serious bug in qh_gethash [poly.c]
+- Documentation and build system are incomplete (see above)
+- First release of C++ interface [qh-code.htm]
+- Development moved to http://gitorious.org/qhull
+ git clone git@gitorious.org:qhull/qhull.git
+- Did not fix conformant tesselations for 'Qt'.
+ For details, see http://www.qhull.org/news#bugs of May 2007 and Dec 2006.
+- Use g++ builds for Windows distribution (10% faster than msvc2005)
+ Combined vcproj/ and qtproj/ into project/
+ vcproj will be replaced by qmake generated files
+
+------------
+qhull 2010.0.3 2010/01/05
+Fixed bugs
+- 'QJn': Fix qh.STOPcone in qh_build_withrestart(). It was not cleared.
+- qh_initqhull_outputflags [global.c]: warn about Qc only if QHULLfinished
+ otherwise set if needed
+
+qhull 2010.0.2 2010/01/04
+
+Fixed bugs
+- qh_gethash [poly.c]: fix sign conversion.
+ Previously, the result may be negative, leading to a segfault.
+ The bug is more likely with large address spaces
+ Reviewed all uses of %(modulo) for remainder with negative arguments
+- Reviewed output of q_test and compared to results from 2003.1
+
+Breaking code changes
+- Return type of qh_gethash changed from unsigned to int. Matches 'size'
+- addhash takes a signed hash
+ qh_addhash( newelem, hashtable, hashsize, hash )
+
+Code changes
+- Test for qh_qh in qh_printf
+- Makefile.txt corrected for libqhull build [amorilia]
+- Renamed index to idx to avoid shadowing BSD strings.h [kwilliams]
+
+qhull 2010.0.1 2010/01/03
+
+New Features:
+ - Added option 'Ta' to annotate output with message codes
+
+Preliminary C++ support:
+ - C++ declarations may change without warning
+ - Preliminary documentation for Qhull's C++ interface [qh-code.htm#cpp, qhull-cpp.xml]
+ - Added user_eg3 as an example of Qhull.cpp
+ - Removed qhull_interface.cpp. Use Qhull.cpp instead.
+ If math.h breaks '#include qhull_a.h', preceed it with '#include math.h'
+
+Changes to qhull options and results
+ - Allow 'd' and 'v' as the filename for 'TO ..' and 'TI ...' in qdelaunay [M. Jambon]
+ - 'rbox tN' requires an integer (previously allowed floats)
+ - Allow quoted filenames for 'TO ...' and 'TI ...'
+ - Prefix error messages and warnings with a message code (e.g., QH6012)
+ - Fixed rbox ignoring flags that were not separated by spaces
+ - Report all hidden options before exiting in qh_checkflags()
+ - Defined qh_OPTIONline [user.h] as max length of option line ('FO')
+ - Report error if negative arguments to rbox 'G', 'L', 'Z'
+ - Unknown rbox flag changed from a warning to an error
+ - Set error status 4 qh_ERRmem if rbox runs out of memory
+ - Removed extra spaces at end of line
+
+Breaking Code Changes:
+ - Renamed qh.coplanarset to coplanarfacetset. Avoids conflict with facetT.coplanarset
+ - qh_restore_qhull() zeroes out qh.old_qhstat and qh.old_tempstack. Ownership moved.
+ - Rewrote save_qhull/restore_qhull
+ - Add Ztotcheck to zzdef_ [R. Gardener]
+ - Changed qh_malloc to size_t (was unsigned long)
+ - Declare qh_PRINT instead of int [kwilliams]
+ - In qh_printafacet(), changed error output to 'qh ferr'
+
+Bug fixes to C code:
+ - Use gcc 4.4.0 or later. gcc 4.2.1, 4.2.2, and 4.3.2 -O2 segfaults in qset.c . gcc 4.1.1 was OK
+ See bug report http://gcc.gnu.org/ml/gcc-bugs/2007-09/msg00474.html
+ - Rewrite qh_setappend to avoid g++ 4.1, 4.2, and 4.3 strict_aliasing error.
+ Orion Poplawski (orion@cora.nwra.com)
+ http://www.rpmfind.net/linux/RPM/fedora/12/ppc/qhull-devel-2003.1-13.fc12.ppc64.html
+ - Fixed qh_findfacet_all(), "REALmin" should be "-REALmax" [L.A. Taylor].
+ Effects library users for convex hulls and halfspace intersections.
+ - qh_printfacet [io.c] Removed extra space for neighboring facets
+ - Report error if d points, Delaunay, and not Qz
+ - Fixed double-free of facet->centrum for triangulated facets
+ - Fixed mindist initialization if !testcentrum in io.c findbest_test [Ratcliff]
+ - Fixed parentheses around warning for missing 'Qc' [qh_initqhull_outputflags]
+ - Fixed rbox buffer overflow of 'command' when appending seedbuf
+ - Fixed option string for 'rbox t t999'. Although seed was correctly set to 999,
+ a random seed was appended to the rbox comment (e.g., 'rbox t t999 t32343')
+ - Fixed upper bound of sanity check for qh_RANDOMmax in qh_initqhull_globals()
+
+Changes to C code
+ - Reordered #include from specific to general. Move up .h for module.
+ - Removed qh.old_stat -- never used
+ - Removed qh_clearcenters from qh_freeqhull. Duplicated by qh_delfacet
+ - qh_printcenter [io.c] removed unreachable fprintf argument
+ - qh_getarea() [geom2.c] ignored on multiple calls (qh.hasAreaVolume)
+ - qh_getarea() [geom2.c] checks facet->isarea. Set by QhullFacet.facetArea()
+ - qh_triangulate() [poly2.c] ignored on multiple calls (qh.hasTriangulation)
+ - Add statistics for vertex_visit and visit_id to buildtracing
+ - Defined scale and offset parameters for qh_randomfactor
+
+Bug fixes and changes to mem.c/mem.h
+ - Fixed qhmem.totshort (total short memory in use)
+ - Memory tracing (T5) redone for sort order by object
+ - Added full tracing for short memory allocations.
+ - Added qhmem.totfree (total short memory on freelists)
+ Increases size of qh_memalloc_ and qh_memfree_
+ - Added qhmem.totdropped (leftover freesize at end of each short buffer)
+ - Added qhmem.totunused (short size - request size)
+ - Added qhmem.totbuffer (total short memory buffer w/o links)
+ - Added memory statistics to qh_NOmem;
+ - Added qh_memtotal to track allocated memory
+ - Renamed qh_memfree parameter to 'insize' for consistency with qh_memalloc
+ - Removed qhmem.curlong. qa_memfreeshort computes curlong from cntlong and cntfree
+ - In mem.h, changed ptr_intT to long. qh_meminit() checks that it holds a 'void*'
+
+Fixed g++ and devstudio warnings
+ - Except for bit field conversions, compiles cleanly with
+ -Wall -Wextra -Wshadow -Wcast-qual -Wwrite-strings -Wno-sign-conversion -Wconversion
+ - Fixed warnings at VC8, level 4
+ - Fix data types to remove conversion warnings [kwilliams]
+ - Use size_t for calls to malloc,etc [kwilliams]
+ Retained int sizes for qset.h and mem.h. Follows Qt convention
+ and is easier to work with. int can be 64-bits if 2 billion facets
+ - Change literal strings to const char* [kwilliams]
+ - Added type casts to SETfirst and SETsecond [amorilia+alphax]
+ - getid_() returns an int [kwilliams]
+ - Add missing const annotations [kwilliams]
+ - Fixed 64-bit warnings (marked with "WARN64")
+ - Convert sizeof to (int) for int parameters
+ - In libqhull.c, added explicit casts from long to float, Avoids warning
+ - In global.c, cast time() to int for QRandom-seed. Avoids warning
+
+Changes to C code for C++ support
+ - Add sln, vcproj, and qtpro files for building Qhull -- add to README notes
+ - Added dim to vertexT for cpp interface. Reduced size of qh.vertex_visit
+ - qh_produce_output [io.c] may be called multiple times (C++ interface)
+ - Moved SETsizeaddr_() to qset.h for use by QhullSet.cpp
+ - Option 'Tz' sets flag qh.USEstdout for QhullPoints.cpp
+ - Added support for multiple output runs from QhullPoints.outputQhull
+ - qh_clear_outputflags() resets the output flags
+ - qh_initqhull_outputflags split from qh_initqhull_globals
+ - Added qh.run_id, a random identifier for this instance of Qhull (QhullPoints)
+ - For qh.run_id, initqhull_start initializes qh_RANDOMseed to time instead of 1
+ - Extracted qh_argv_to_command (random.c) from qh_init_qhull_command and fixed a buffer overflow
+ - Moved qh_strtod/qh_strtol from global.c to random.c for use in rboxlib.c
+ - Split out random functions into random.c
+ - Added message codes to qh_fprintf(). See its definition in user.c
+ - Replaced exit, malloc, free, fprintf, and fputs with qh_malloc,...[J.W. Ratcliff]
+ - Added qh_fprintf, qh_malloc, qh_free, ph_printhelp_narrowhull to user.c
+ - Moved qh_printhelp_degenerate and qh_printhelp_singular from io.c to user.c
+ - Clear qh.ERREXITcalled at end of qh_errexit().
+
+Documentation:
+ - Fixed out-of-date CiteSeer references
+ - Renamed html/qh-in.htm to html/qh-code.htm
+ - Add reference to 'Qt' to 'i'
+ - Add reference to 'FS' to 'FA'
+ - qh-impre.htm discusses precision issues for halfspace intersection
+ - Add cross references between options 'FA' and 'FS'
+ - Added link to Wolfram Research's MathWorld site
+ - Updated Fukuda's links
+ - Changed copyright to C.B. Barber for C++, documentation, and merge.c
+ - Updated Qhull citation with page numbers.
+ - Proposed project: constructing Voronoi diagram
+ - Proposed project: computing Voronoi volumes
+ - Replaced tabs with spaces in qhull.txt and rbox.txt
+
+------------
+qhull 2009.1 2009/6/11
+
+This is a maintenance release done by Rafael Laboissiere <rafael@debian.org>.
+ - src/rbox.c (main): Avoid problems of evaluation order when
+ pre-incrementing arguments of strtod
+ - src/io.c (qh_produce_output), src/stat.c (qh_initstatistics): Use %lu
+ instead of %d in the format string for arguments of type size_t
+ - html/qhull.man, html/rbox.man: Fix several syntax, macros, and hyphen
+ problems in man pages
+ - The Autotools files have been generated with modern version of autoconf (2.63),
+ automake/aclocal (1.10.2), and libtool (2.2.6)
+ - Some character issues in the man pages are fixed
+
+------------
+qhull 2003.1 2003/12/30
+
+New Features:
+ - Add Maple output ('FM') for 2-d and 3-d convex hulls [T. Abraham]
+
+Breaking Code Changes:
+ - Annotate C code with 'const'. An ANSI compatible compiler is required.
+
+Bug Fixes and Code Changes:
+ - Fixed qh_findbest() for upperdelaunay facets w/o better, lower neighbors
+ For library users and some qhull users [A. Cutti, E. Milloti, K. Sun]
+ - Preserved qhmem.ferr in qh_memfreeshort() for library users
+ - Removed 'static' from qh_compare... for io.h and merge.h [V. Brumberg]
+ - Split out qh_initqhull_start2() to avoid allocating qh_qh
+ - Split out qh_freeqhull2() to avoid freeing qh_qh
+ - Split out qh_produce_output2() and qh_prepare_output()
+ - qh_initstatistics() frees a previously existing qh_qhstat
+ - qh_initqhull_start2() checks that qh_initstatistics() called first
+
+Documentation:
+ - Add warning to findDelaunay() and qh_in.htm about tricoplanar facets
+ - Noted Edelsbrunner's Geometry & Topology for Mesh Generation [qh-impre.htm]
+ - Noted Gartner's Miniball algorithm [qh_impre.htm]
+ - Noted Veron and Leon's shape preserving simplification [qh_impre.htm]
+
+qhull 2003.1 2003/12/19
+
+Bug Fixes:
+ - Reversed coordinate order for qh.ATinfinity in qh_projectinput [V. Brumberg]
+ This effects:
+ Qhull library 'd' or 'v' users with 'Qz' and unequal coordinate ranges.
+ qdelaunay/qvoronoi users with 'Qbk:0Bk:0', 'Qz', and unequal coordinate ranges
+
+Changes to code:
+ - Replaced qh_VERSION with qh_version in global.c [B. Pearlmutter]
+ The previous techniques were either clumsy or caused compiler errors
+ - Removed unused variables from qh_findbest and qh_findbestnew [B. Pearlmutter]
+ - Note that qh.TESTpoints was added in 2002.1 for tsearch implementation
+
+Changes to distribution:
+ - Added Unix distribution including Debian files [R. Laboissiere]
+ The previous Unix distribution is now the source distribution
+ - Added rpm distribution [L. Mazet]
+ - Investigated generation of Win32 dll. Need to define a C++ interface.
+
+Changes to documentation:
+ - Moved Qhull to www.qhull.org (geom.umn.edu is not available)
+ - The Geometry Center is archived at http://www.geom.uiuc.edu
+ - Reviewed introduction to each program
+ Triangulated output ('Qt') is more accurate than joggled input ('QJ')
+ qdelaunay is 'qhull d Qbb' [C. Ulbrich]
+ qvoronoi is 'qhull v Qbb'
+ Added example of non-simplicial intersection to halfspace intersections
+ - Added warning about using the Qhull library.
+ - Added qhull timings to When to use Qhull [C. Ulbrich]
+ - Reorganized the home page index and the manual index
+ - Moved qh-home.htm to index.htm
+
+Changes to examples
+ - Fixed options for eg/eg.t23.voronoi.imprecise [B. Pearlmutter]
+
+
+------------
+qhull 2002.1 2002/8/20
+
+Changes to distribution:
+ - Set up savannah.nongnu.org/projects/qhull/ [R. Laboissiere]
+ - Set up www.thesa.com as a backup
+ - Added qh-get.htm, a local copy of the download page
+ - Added Visual C++ interface to Qhull, qhull_interface.cpp [K. Erleben]
+ - Use HTTP instead of FTP for downloading Qhull
+ - Renamed qhull-1.0.sit.hqx
+
+Bug fixes:
+ - Fixed sign of coefficients for cdd halfspaces ('FD','Fd') [T. Abraham]
+
+Changes to code:
+ - Replace qh_version with qh_VERSION in libqhull.h.
+ Allows shared libraries and single point of definition
+ - Added qh.TESTpoints for future implementation of tsearch
+
+Changes to build
+ - Makefile.txt works under cygwin
+ - Added Make-config.sh to create a Debian build [R. Laboissiere]
+ - Added .exe to Makefile.txt#clean.
+ - In README, use -fno-strict-aliasing with gcc-2.95.1 [Karas, Krishnaswami]
+ - Fixed chmod in Makefile.txt [B. Karas]
+
+Documentation updates
+ - Documented input options for each program [A. Montesinos]
+ - FAQ: "How to get the radii of the empty spheres for Voronoi vertices"
+
+URL updates:
+ - Changed official URL from locate/qhull to software/qhull
+ - Changed URLs from relative to absolute in qh-home.htm and qh-get.htm
+ - Added URL for Newsgroup: comp.soft-sys.matlab
+ - Added URL for GNU Octave
+ - Added URLs for Google and Google Groups
+ - Replaced qhull_mail.html and qhull_bug.html with mailto links.
+ - Removed URL for Computational Geometry Tribune
+ - Changed URL for locate/cglist to software/cglist
+ - Used site relative links for qh-home.htm
+
+------------
+qhull 3.1 2001/10/04
+
+New features
+ - Added option 'Qt' to triangulate non-simplicial facets
+ - Added option 'TI file' to input data from file
+ - Added option 'Q10' to prevent special processing for narrow distributions
+ e.g., RBOX 1000 L100000 s G1e-6 t1001803691 | QHULL Tv Q10
+ - Tried to compute Voronoi volumes ('Pv'). Requires dual face graph--not easy
+ See Clarkson's hull program for code.
+
+Changes to options
+ - Added numtricoplanars to 'Fs'. Number of good, triangulated facets for 'Qt'
+ - Added Zdelvertextot to 'Fs'. If non-zero and Delaunay, input is degenerate
+ - Qhull command ('FQ') may be repeated.
+ - If 'TPn' and 'TWn' defined, trace the addition of point 'n'
+ otherwise continue tracing (previously it stopped in 4-d)
+ - Removed 'Ft' from qdelaunay. Use 'Qt o' or 'qhull d QJ Qt' instead.
+ For non-simplicial regions, 'Ft' does not satisify the Delaunay property.
+ - If 'Po' or 'TVn', qhull checks outer planes. Use 'Q5' to turn off.
+ - If 'T4', print facet lists and check polygon after adding each point
+
+Corrections to code
+ - rbox: allow 'c' and 'd' with 's r', meshes, etc.
+ - qh_findbest: redesigned as directed search. qh_findbesthorizon for coplanar
+ qh_findbest is faster for many distributions
+ - qh_findbestnew: redesigned to search horizon of coplanar best newfacets
+ needed for distributions with a sharp edge,
+ e.g., rbox 1000 s Z1 G1e-13 | qhull Tv
+ - qh_findbest/qh_findbestnew: search neighbors of better horizon facets
+ was needed for RBOX 1000 s Z1 G1e-13 t996564279 | qhull Tv
+ and RBOX 1000 s W1e-13 P0 t996547055 | QHULL d Qbb Qc Tv
+ - qh_findbest with noupper: could return an upperdelaunay facet if dist>qh.MINoutside.
+ - qh_findbestnew: allow facet->upperdelaunay if dist > qh.MINoutside
+ - qh_partitioncoplanar: call qh_partitionpoint if outside and perpendicular
+ for distributions with a sharp edge
+ - qh_partitionvisible: report precision error if all newfacets degenerate.
+ was needed for RBOX 1000 s W1e-13 t995138628 | QHULL d
+ - qh_createsimplex: clears qh.num_visible, may be non-zero with 'TRn QJ'
+
+Changes to prompts, warnings, and statistics
+ - For Delaunay & Voronoi, 's' reports deleted vertices due to facet merging.
+ They were incorrectly reported as nearly incident points.
+ - Warn if recompute centrum after constructing hull
+ - Simplified narrow hull warning and print all digits of cosine.
+ A narrow hull may lead to a point outside of the hull.
+ - Print total vertices deleted instead of ave. per iteration (Zdelvertextot)
+ - Improved tracing for qh_partitionpoint and qh_partitioncoplanar
+ - Added number of distance tests for checking outer planes (qh_check_maxout)
+ - Simplified "qhull precision error: Only n facets remain."
+ - Included 'TRn' in the causes of a premature exit
+
+Changes to documentation
+ - README.txt: Added quickstart instructions for Visual C++
+ - rbox: Added example of edge of narrow lens, rbox 1000 L100000 s G1e-6
+ - Added cross references between options 'o' and 'p'.
+ - qh-eg.html: added examples comparing 'Qt', 'QJ', and neither 'Qt' nor 'QJ'
+ eg.15a.surface, eg.15b.triangle, eg.17a.delaunay.2, etc.
+ - Reorganized and enhanced discussion of precision problems in qh_impre.htm
+ - Fixed spelling errors [K. Briggs]
+ - Fixed link errors, validated HTML, and spell checked [HomeSite]
+ - Removed unnecessary #TOP links
+ - Added source links to the qh-quick.htm's header and footer
+ - qh-geom.htm, qh-poly.htm: add links to Voronoi functions in io.c
+ - src/index.htm: Added how to search libqhull.h for qhull options
+ - qvoronoi.htm/qdelaun.htm: 'Fc' and 'FN' includes deleted vertices
+
+Changes to URLs
+ - Added http://www.voronoi.com and http://www.magic-software.com
+
+Changes to code
+ - qh_qhull: if 'TVn' or 'TCn' do not call qh_check_maxout and qh_nearcoplanar
+ - reviewed time profile. Qhull is slower. Optimized qh_findbestnew()
+ - qh_addpoint: Added warning note about avoiding a local minimum
+ - qh_checkpolygon: report qh.facet_next error if NARROWhull & dist>MINoutside
+ - qh_findbest: renamed "newfacets" parameter to "isnewfacets" since it is boolT
+ - qh_findbest/qh_findbestnew: testhorizon even if !MERGING
+ Otherwise qhull c D6 | qhull Q0 Tv assigns coplanar points
+ - qh_resetlists: add qh_RESETvisible for qh_triangulate
+ - qh_findbest: search better facets first. Rewritten.
+ - qh_findbest: increased minminsearch, always check coplanar facets.
+ See: RBOX 1000 s Z1 G1e-13 t996564279 | QHULL Tv
+ - qh_findbestnew: report precision error for deleted cones [rare event]
+ e.g.: RBOX 1000 s W1e-13 P0 t1001034076 | QHULL d Qbb Qc Tv
+ - qh_findbesthorizon: search horizon of qh.coplanarset. New.
+ - qh_findbestsharp: replaced with qh_sharpnewfacets followed by qh_findbestnew
+ - qh_partitionpoint, Delaunay sites can not be inside. Otherwise points may
+ be outside upperDelaunay facets yet not near-inside Delaunay facets
+ See: RBOX s 1000 t993602376 | QHULL C-1e-3 d Qbb FA Tv
+ - qh_partitioncoplanar: call qh_findbest/qh_findbestnew with qh DELAUNAY
+ - qh_printlists: format long lines
+ - qh_printvertex: format long lines
+ - user.h: tightened qh_WARNnarrow and qh_MAXnarrow. Do not see problems
+ until they are -1.0.
+ - user.h: defined qh_DISToutside, qh_SEARCHdist, and qh_USEfindbestnew
+ - qh_checkfacet: in 3-d, allow #ridges > #vertices. Can get a vertex twice
+ in a ridge list, e.g, RBOX 1000 s W1e-13 t995849315 D2 | QHULL d Tc Tv
+
+Changes to FAQ
+ - Recommended use of triangulated output ('Qt')
+
+Changes to distribution
+ - Recompiled in Visual C++ 5.0 with optimization (as was version 2.6)
+ - q_test: Added bad cases for Qhull and tests for new features
+
+Changes to Qhull library
+ - Added qh_triangulate() to poly2.c. It triangulates the output.
+ - Added option 'Q11' to copy normals and recompute centrums for tricoplanar facets
+ 'FP' may not print the nearest vertex for coplanar points
+ Use option 'Q11' when adding points after qh_triangulate()
+
+------------
+qhull 3.0 2001/02/11
+
+Changes to distribution
+ - added qconvex, qdelaunay, qhalf, and qvoronoi
+ - added qhull-interface.cpp on calling Qhull from C++ [K. Erleben]
+ - renamed to qhull3.0/.
+ - added eg/, html/, and src/ directories
+
+Changes to URLs
+ - MathLab6 qhull: convhulln, delaunayn, griddatan, tsearchn, vororoin [Z. You]
+ - Wolfram Research wrote a Mathematica interface for qdelaunay [Hinton]
+ - Geomview moved from www.geom.umn.edu to www.geomview.org [M. Phillips}
+ - added URLs for tcsh and cygwin to README.txt
+
+Changes to documentation
+ - reorganized table of contents and renamed qh-man.htm to index.htm
+ - wrote program documentation, dropped qh-opt.htm and qh-optv.htm
+ - added quick reference, qh-quick.htm
+ - reorganized qh-rbox.htm and renamed it to rbox.htm
+ - split up qh-c.htm for quick navigation
+
+Corrections to code
+ - fixed type of arg for error message in qh_initqhull_globals [N. Max]
+ - fixed incorrect initialization of qh MINdenom_1 for scalepoints
+ - fixed drop dim for 'H Qbk:0Bk:0'. Added qh.feasible_point to qh_projectinput
+ - qh_WARNnarrow is angle between facet normals. Negate for warning message.
+ - statistics for Wangle/etc. concerns facet normals. Reworded [E. Voth]
+ - fixed error message for 'FC v'
+ - report cospherical points if Delaunay and error in qh_scalelast()
+
+Changes to code
+ - turn on Pg if (QVn or QGn) and not (Qg or PG)
+ - turn on Qc if format option 'Fc', 'FP', or 'Gp' (removes warning)
+ - removed last good facet unless ONLYgood ('Qg').
+ - added count of non-simplicial or merged facets to 'FS'
+ - added count of non-simplicial facets to 's' (OK if #vertices==dim)
+ - added Znonsimplicial and Znowsimplicial to 'Ts'
+ - allow Mathematica output of dual polytope for halfspace intersection
+ - added qh_checkflags to globals.c for multiple front ends
+ - qh_initqhull_globals sets qh.MERGING if qh.MERGEexact
+ - removed hashentryT. It is no longer used.
+
+Changes to prompts and warnings
+ - reorganized prompts
+ - reorganized synopsis for rbox.c
+ - print warning if 'Fc' or 'FP' with 'd QJ'. Coincident points are unlikely.
+ - ignore warning if options 'v i Pp'. qvoronoi users may need Delaunay tri.
+ - reworded warning if 'Pg' and 'QVn' is not a vertex.
+ - reworded warning for 'Qx Tv', qh_check_points() in poly2.c
+ - if 'Pp', turn off warning for 'Qbb' without 'd' or 'v'
+ - in qh_printsummary() of Voronoi and Delaunay, distinguish QVn, QGn, Pdn, PDn
+
+Changes to FAQ
+ - added FAQ item for nearly flat Delaunay triangles [Z. You]
+ - added FAQ item for area and volume [R. Konatham]
+ - added FAQ item for Voronoi diagram of a square [J. Yong]
+ - edited FAQ item on point location in Delaunay triangles [Z. You]
+ - added FAQ item on nearly flat Delaunay triangles [Dehghani]
+ - added FAQ item about halfspace intersection [V. Tyberghein]
+ - added FAQ item for missing ridges [M. Schmidt]
+ - added FAQ item about qh_call_qhull [R. Snyder]
+ - added FAQ item about memory statistics [Masi]
+ - added FAQ item on meshing non-convex objects
+ - added FAQ item on MATLAB and Mathematica interface
+
+------------
+qhull 2.6 1999/04/19
+ - fixed memory overwrite (no effect) in qh_initstatistics() [K. Ford]
+ - added zdoc11 to qh-stat.h#ZZdef for !qh_KEEPstatistics [K. Ford]
+ - enhanced qh_initqhull_globals() test of qh_RANDOMint and qh_RANDOMmax
+ - added debugging option to always return qh_RANDOMmax from qh_rand()
+ - fixed option 'Qr', qh_initialvertices(), to allow a broken qh_rand()
+ fixed option 'Qr', qh_nextfurthest(), to allow narrow hulls
+ Option 'Qr' simulates the random incremental algorithm for convex hulls
+ - added note that qh.num_outside includes coplanar points for narrow hulls
+ - added FAQ items for triangles/ridges of 3-d Delaunay triangulation[P. Kumar]
+ - added FAQ item about on-line processing with the Qhull library [O. Skare]
+ - changed name of option 'Error-roundoff' to 'Distance-roundoff'
+
+------------
+qhull 2.6 1998/12/30
+ - for the unbounded rays of the Voronoi diagram, use a large box [Schmidt]
+ e.g., 'rbox P4,4,4 P4,2,4 P2,4,4 P4,4,2 10 | qhull v Fv' fails for point 0
+ while 'rbox P4,4,4 P4,2,4 P2,4,4 P4,4,2 10 c G5 | qhull v Fv' is OK.
+ - fixed qh_new_qhull() to use outfile/errfile instead of stdout/stderr [Ford]
+ - clarified COPYING.txt for use in other programs [Archer]
+ - improved qh_readpoints() error message for incorrect point count.
+ - added FAQ item for closest triangle to a point [Sminchisescu & Heijting]
+ - added FAQ item for is a point outside of a facet [Beardsley]
+ - added FAQ item for visiting facets of the Delaunay triangulation [Heijting]
+ - added link to Erickson's Computational Geometry Software
+ - added link to Sharman's HTML version of the comp.graphics.algorithms FAQ
+ - added link to Owen's Meshing Research Corner
+ - added note to 'd' about quadratic size of 'rbox 100 l | qhull d' [Kumar]
+ - added 'about a point' to mentions of halfspace intersection
+ - added request to qh-code.htm to compute largest empty circle [Hase]
+ - the DOS window in Windows NT is better than the DOS window in Windows 95
+ - removed obsolete qh_findfacet() from qh-c.htm [Sminchisescu]
+
+------------
+qhull 2.6 1998/8/12
+ new and modified features
+ - rbox: added option Mn,m,r to generate a rotated lattice or mesh
+ - rbox: report error if more than one of 'l', 'x', 'L', 's', or 'M'
+
+ Qhull library changes
+ - added qh_new_qhull() to user.c for calling qhull() from a program [D. Zwick]
+ rewrote user_eg.c to use qh_new_qhull(). Added qh_QHpointer example.
+ - added qh_CLOCKtype 2 in user.h to call times() for CPU time [B. Hemkemeier]
+ - renamed set.c/set.h to avoid conflict with STL's set.h [G. van den Bergen]
+ can also use '#include <qhull/qhull_a.h>' for Qhull library
+
+ fixed errors
+ - fixed qh_init_B() to call qh_initqhull_mem() once only [D. Zwick]
+ This only effects Qhull library users of qh_QHpointer.
+ - fixed qh_mergecycle_all() to check for redundant vertices [J. Nagle]
+ e.g., 'rbox M3,4 64 | qhull Qc' should report 8 vertices & 48 coplanars
+ - fixed gmcoord initialization in qh_setfacetplane() for qh.RANDOMdist
+ - turn off qh.RANDOMdist during qh_printfacetheader()
+ - fixed error messages for unknown option flags
+
+ documentation changes
+ - added note to FAQ on the Voronoi diagram of cospherical points [H. Hase]
+ - added note to 'Qu' on furthest-site Delaunay triangulation via convex hull
+ - added note to 'QJ' about coplanar points on the convex hull of the input
+ - added note that 'o' and 'FN' list Voronoi regions in site id order [Arvind]
+ - added links to Fukuda's introduction to convex hulls, etc. [H. Hase]
+ - added .c and .h source files to web distribution and qh-c.htm [J. Sands]
+ - documented qh_ZEROdelaunay. Delaunay and Voronoi diagrams do not include
+ facets that are coplanar with the convex hull of the input sites.
+
+ modified code
+ - replaced computed minnorm in qh_sethyperplane_det with distance test
+ - removed 'qh rand_seed' since random number generator is independent of qhull
+ - dropt 'qhull-PPC.sit.bin' from the distribution (out-of-date) [M. Harris]
+
+------------
+qhull 2.5 1998/5/4
+
+ fixed errors
+ - removed zero-area Delaunay triangles and furthest-site triangles [I. Beichl]
+ Zero-area triangles occur for points coplanar with the input's convex hull.
+ - replaced qh.MINnorm with computed minnorm in qh_sethyperplane_det [J. Nagle]
+ qh.MINnorm was incorrect for the convex hull of the "teapot" example.
+ Qhull runs 0-20% slower in 3-d and 4-d.
+ - allow 'Qg' with furthest-site Delaunay triangulation (may be faster)
+ - removed extra space in definition of FOREACHmerge_() for Alpha cc [R. LeRoy]
+ - fixed innerouter type in qh_printvdiagram2 [does not effect code, R. Adams]
+
+ documentation changes
+ - to browse qh-c.htm, set MIME type of .c and .h files to text/html
+ - added example of 3-d Delaunay triangulation to q-faq.htm
+ - added Delaunay and Voronoi examples to qh-optv.htm
+
+------------
+qhull 2.5 1998/2/4
+ - added option 'v Fi' for separating hyperplanes of bounded Voronoi regions
+ - added option 'v Fo' for separating hyperplanes of unbounded Voronoi regions
+ - option 'Pp' turns off the warning, "initial hull is narrow"
+ - fixed partial, 3-d Voronoi diagrams (i.e., 'v Fv QVn Tc')
+ - fixed missing statistics in qh_allstat* [T. Johnson]
+ - rearranged qh_printvdiagram. Use qh_eachvoronoi to iterate Voronoi ridges.
+ - added qh_check_points to qh-math.c
+
+qhull 2.5 1998/1/28
+ - added option 'Fv' to print the Voronoi diagram
+ - added rbox option 'x' to generate random points in a simplex
+ - added rbox option 'y' to generate a simplex and random points
+ - added rbox option 'On' to offset the output
+ - add unpacking instructions to README.txt
+ - updated discussion of forced output, 'Po'
+ - sorted the options alphabetically
+ - removed __STDC__ check from libqhull.h for VisualC++
+ - moved qh_markvoronoi from qh_printvoronoi and cleared facet->seen flags
+ - added facet->seen2 flag for 'Fv'
+
+qhull 2.5 1998/1/16
+ - fixed initialization of qh.last_low on restart of 'd QJ'
+ - renamed qh_JOGGLEmax to qh_JOGGLEmaxincrease
+ - updated URL for Fukuda's cdd program
+
+qhull 2.5 1998/1/12
+
+New or modified features
+ - added option 'Fx' to print vertices by point id [G. Harris, T. McClendon]
+ in 2-d, the vertices are printed in counter-clockwise order
+ for Delaunay triangl., 'Fx' lists the extreme points of the input sites
+ - added option 'QJ' to randomly joggle input instead of merging facets
+ - added option 'TO file' to output results to a file. Needed for Windows95.
+ - added option 'TRn' to rerun Qhull n times. Use to collect joggle statistics
+
+Corrections
+ - fixed 2-d facet orientation for 'i' and 'o' outputs
+ - for Mathematica 2.2 ('m') changed %10.8g to %16.8f [A. Zhaxybayev]
+ - fixed incorrect warning for 'QV0 Qg' in qh_initbuild [B. Wythoff]
+ - fixed unaccessible statistic if !qh_KEEPstatistics for Wnewvertexmax
+ - fixed overestimate of qh ONEmerge for point sets outside of
+ first quadrant and far from the origin
+ - fixed overestimate of 'Qbb' for point sets far from the origin
+ - fixed potential overestimate of qh DISTround under 'Qbb'
+ - fixed 'p' printing coplanar points of unselected facets
+ - fixed 'Ft' printing centrums unnecessarily in 2-d
+
+Changes to documentation
+ - wrote internal design documentation (qh-c.htm)
+ - started frequently asked questions (qh-faq.htm)
+ - added a section on joggled input to qh-impre.htm
+ - added joggle example to qh-eg.htm (eg.15.joggle)
+ - changed q_eg to use 'QJ' instead of 'Q0' were appropriate
+ - added an example to each of the main options
+ - added examples to rbox.htm
+ - added examples to the synopsis
+ - added a reference to Mucke, et al ['96], Fast randomized point location ...
+ - added code for printing Delaunay triangles to qh-code.htm [A. Tsui]
+ - options 'Pdk' and 'PDk' do not drop on equality
+
+Improvements to the code
+ - reviewed warning messages for Qhull options in qh_initflags
+ - added warning to 's' if premature exit from 'TCn' or 'TVn'
+ - 's' prints max distance above/below only if qh.MERGING
+ - reduced maxoutside in qh_check_bestdist/qh_check_points for 'Rn'
+ - in post-merging, rebuild centrums of large facets that become small
+ - lowered cutoff for coplanar facets for ischeckmax/qh_findbest
+ - removed qh_check_maxout for 'Wn Q0'
+ - reset tracing after 'TPn' adds point in 4-d and higher
+
+Changes for the Qhull library
+ - changed qh_setdelaunay to call qh_scalelast if used with 'Qbb' or 'QJ'
+ Delaunay callers to qh_findbestfacet, qh_addpoint, or qh_findfacet_all
+ should always use qh_setdelaunay as in user_eg.c
+ - defined qh.outside_err to check points against a given epsilon [E. Voth]
+ - added header to user_eg.c to avoid its incorporation into qhull [C. Begnis]
+ - added qh_nearcoplanar() calls to user_eg.c
+ only needed if use 'QJ'
+ - expanded __STDC__ warning message in libqhull.h [C. Begnis]
+ - renamed qh maxmaxcoord to qh MAXabs_coord
+ - replaced qh MAXlowcoord with qh MAXabs_coord
+ - random seed ('QR-n') is reset in qh_initqhull_globals after testing
+ - replaced 'FO' options "_max-coord/_min-coord" with "_max-width"/qh.MAXwidth
+
+Other changes to Qhull functions
+ - report error for !bestfacet in qh_findbest (it shouldn't happen) [H. Meuret]
+ - set newbest in qh_findbest only if bestfacet updated
+ - renamed facet parameter for qh_findbest
+ - added maxdist argument to qh_checkpoint
+ - moved 'FO' output after qh_partitionall
+ - separated qh_initbuild from qh_qhull
+ - reinitialize globals modified by qh_buildhull
+ - moved initialization of qh.GOODvertexp & qh.GOODpointp to qh_initbuild
+ - separated qh_nearcoplanar from qh_check_maxout
+ - separated qh_geomplanes from qh_printfacet2geom, etc.
+ - separated qh_freebuild from qh_freeqhull
+ - separated qh_outerinner from io.c to return outer and inner planes
+ - separated qh_distround and qh_detroundoff from qh_maxmin
+
+
+------------
+qhull 2.4 97/4/2
+
+New or modified features
+ - made 'C-0' and 'Qx' default options. Use 'Q0' to not handle roundoff errors
+ - removed point-at-infinity from Delaunay/Voronoi.
+ you no longer need to use 'Qu PDk'
+ - added 'Qz' to add a point-at-infinity to Delaunay and Voronoi constructions
+ - added published version of qhull article in ACM Trans Math Software
+ - ported qhull to Windows95 under Visual C++ and Borland C++
+ - added 'Ft' for triangulation by adding the centrums of non-simplicial facets
+ - added 'Gt' to display 3-d Delaunay triangulations with a transparent hull
+ - changed definition of coplanar point in output to qh min_vertex (see 'Qc')
+ it was qh MAXcoplanar ('Un') [could make vertices non-coplanar]
+ - automatically set 'Qi' for options 'd Qc' and 'v Qc'.
+ - reworded summary ('s') for Delaunay/Voronoi/halfspace.
+ use 'Fs' and 'FS' for summary statistics.
+ - for summary 's' of Delaunay/Voronoi, display number of coplanars for facets
+ if none, display total number of coplanars (i.e., non-vertices)
+ - input comment is first non-numeric text (previously limited to header)
+ - added input warning if use 'Qbb' without 'd' or 'v'
+ - 'Q3' can not be followed with a numeric option
+
+Corrections
+ - fixed qh_partitioncoplanar() to not drop interior points if 'Qi' is used
+ - fixed 'FP d' to report distance in point set instead of paraboloid
+ - fixed qh_findbest() to search all coplanar facets for qh_check_maxout()
+
+Changes to documentation
+ - added example eg.17f.delaunay.3 to show a triangulation of cospherical sites
+ - split up qh-opt.htm into multiple pieces
+ - split off qh-code.htm for Qhull code
+ - renamed .html files to .htm for Windows95
+ - rewrote qh-optv.htm on Delaunay triangulation and Voronoi vertices
+ - added 'man' pages qhull.txt and rbox.txt. These list all the options
+ - removed 'txt' versions of html files
+ - added note to 'PDk' about avoiding a 'd' option immediately after a float
+ - under option 'd', display the triangulation with 'GrD3', not 'GnrD3'
+
+Changes to the Qhull library
+ - added 'format' argument to qh_printfacetNvertex_nonsimplicial() in io.c
+ - removed C++ type errors [J. Stern, S. Marino]
+ - created SETelemt, SETfirstt, etc. for specifying data types.
+ - use SETelem,etc. for assignments.
+ - changed setT.maxsize to 'int' to prevent type conversion warnings
+ - changed FOREACH.. to a comma expression for better code and less warning
+ - changed qh.vertex_visit and .visit_id to unsigned int to prevent warnings
+ - changed clock() to qh_CPUclock (user.h)
+ - qh_init_B() and qh_readpoints() do not set qh.ATinfinity for Delaunay tri.
+ - qh_setvoronoi_all() sets upper Delaunay facets if qh.UPPERdelaunay is set
+ - qh_nearvertex() returns distance in dim-1 for qh.DELAUNAY
+ - removed MSDOS path from qhull_command. Spaces in Win95 tripped qh_setflags
+ - removed memory.h from qhull_a.h. memset,etc. should be in strings.h
+ - split qh_prompt into pieces for Visual C++
+ - added note to qh_addpoint that coordinates can not be deallocated
+ - added Baker '89 to constrained Delaunay diagrams under Enhancements
+ please let me know if you try this
+ - added request for unbounded Voronoi rays to Enhancements
+ please let me know if you try this
+
+------------
+qhull V2.3 96/6/5
+ - fixed total area of Delaunay triangulation. [A. Enge]
+ It should ignore facets on the upper-envelope.
+ - if 'd Qu FA', the total area is summed over the upper-Delaunay triangles
+ - fixed sign of area for Delaunay triangulations.
+ - fixed cdd input format for Delaunay triangulation. [A. Enge]
+ - for cdd input, allow feasible point for halfspaces.
+ - warning if cdd output format for centrums, halfspace intersections, or OFF.
+ - print '0' for area ('Fa') if area is not computed for a facet
+ - option 'QR-n' sets random number seed to n without rotating input
+ - fixed qh_findbest() to retest coplanar and flipped facets after a restart
+ - for 'd Qu Ts' collects angle statistics for upper Delaunay facets
+
+ Changes to the Qhull library
+ - expanded user_eg.c for incremental constructions and Delaunay triangulation
+ - added discussion of incremental construction to qh_man.html#library
+ - WARNING: The default value of qh ATinfinity was changed from True to False.
+ A new flag, qh UPPERdelaunay, was defined for 'Qu'.
+ Please set qh ATinfinity if you explicitly add the point "at-infinity"
+ Please set qh ATinfinity if you explicitly call qh_projectinput.
+ Please set qh UPPERdelaunay if you explicitly cleared qh ATinfinity.
+ Other users do not need to change their code.
+ Now you can build a Delaunay triangulation without creating a point
+ "at-infinity". This removes a potential, hard-to-understand error.
+ qh_readpoints sets qh ATinfinity for options 'd' or 'v' without 'Qu'.
+ qh_initB sets qh ATinfinity for qh PROJECTdelaunay w/o qh UPPERdelaunay.
+ qh_projectinput adds a point "at-infinity" only if qh ATinfinity is set.
+ - added qh_setdelaunay to geom2.c to project points to paraboloid
+ - added qh_findbestfacet() to poly2.c to replace qh_findfacet()
+ - removed procedure qh_findfacet(). It does not always work.
+ - removed NULL option for facet in qh_addpoint(). It does not always work.
+ - added noupper parameter to qh_findbest.
+ - added search of upperdelaunay facets to qh_findbest()
+ - allowed qh_findbest() to start with a flipped or upperdelaunay facet
+ - removed qh_nonupper() -- it is no longer needed
+ - allow space at end of options
+ - fixed qh_projectinput for furthest-site Delaunay (qh PROJECTdelaunay 'd Qu')
+ - added voids to procedure declarations with empty parameter lists
+
+------------
+qhull V2.3 96/3/25
+ - fixed missing qh_check_maxout when coplanar points and no merged facets.
+ - fixed qh_freeqhull/allmem (e.g., if qh_NOmem) [only custom code] [E. Voth]
+ - fixed qh_freeqhull to free qh interior_point [E. Voth]
+ - fixed main() to free all of memory if qh_NOmem. Include "mem.h" [E. Voth]
+ - reset f.newcycle link in qh_mergecycle_all [E. Voth]
+ - fixed false error if 'Tc', coplanar points, and a narrow hull
+ - turn off 'Rn' when computing statistics, checking code, or tracing code
+ - removed ={0} from global.c and stat.c to reduce compiler warnings
+ - changed Makefile dependences to $(HFILES) for all but unix.o, set.o, mem.o
+ - pulled out qh_printpointid and reordered qh_pointid [E. Voth]
+ - removed some compiler warnings
+ - moved 'FO' print of options to just before qh_buildhull
+ - changed 'FO' to list difference from -1 for _narrow-hull
+
+------------
+qhull V2.2 96/2/15
+ - detect narrow initial hulls (cosine of min angle < qh_MAXnarrow in user.h).
+ Write warning if cosine < qh_WARNnarrow in user.h. If narrow (qh NARROWhull),
+ partition coplanar points as outside points and delay coplanar test to end.
+ Needed for RBOX 1000 L100000 s G1e-6 t995127886 | QHULL Tv
+ See 'limitations' in qh-impre.html for further discussion.
+ - corrected some confusions between 'FV' and 'Fv' in qh-opt.html
+ - fixed initialization error for small Voronoi diagrams (e.g., [0,0], [1,0], [0,1]) [J. Velez]
+ - fixed bad return from qh_mindiff in geom2.c
+ - for initial hull, first process facet with furthest outside point (qh_furthestnext)
+ - added facet->notfurthest flag for recomputing furthest point
+ - added check for __STDC__ (needs ANSI C) [E. Voth]
+ - reduced warning messages from [E. Voth]. e[1] in setT still reports a warning.
+ - added a cube to the discussion of option 'v' (Voronoi) in qh-opt.html [J. Velez]
+ - added notes about adjacent vertices to "Calling Qhull" in qh-man.html [R. Lewis & J. Velez]
+ - added note about 'lines closer' when viewing 3-d Delaunay triangulations [P. Kallberg]
+ - added option 'Q9' to always process furthest of furthest outside points.
+ - removed option 'Pp' from q_eg and qh-eg.html.
+
+------------
+qhull V2.2 95/12/28
+ - added option 'Qbb' to scale the last coordinate to [0,m] (max prev coord).
+ This reduces roundoff errors for Delaunay triangulations with integer coordinates.
+ - changed option 'Qu d' to print out the furthest-site Delaunay triangulation
+ Use options 'Qu d PD2' to compute the normal 2-d Delaunay triangulation without
+ the point at infinity.
+ - added notes to the documentation of option 'd'
+ - added notes to limitations of how Qhull handles imprecision
+ - added warning if options 'FP', 'Fc', or 'Gp' without option 'Qc' or 'Qi'
+ - added note to options 'PDk:n' and 'Pdk:n' that closest facet is returned if none match
+ - added check that 'Qbk' and 'QBk' does not invert paraboloid for 'd'
+ - added notes that qh_findfacet and qh_addpoint require lifted points for Delaunay triangulations
+ - fixed 'rbox s 5000 W1e-13 D2 | qhull d Qcu C-0 Qbb'
+ - fixed option 'QbB' (qh SCALEpoints was not set)
+ - fixed minor confusion between 'Gc' (print centrums) and 'Gp' (print points)
+ - rewrote qh_findbestnew for upper convex hull, Delaunay facets
+ - changed option name for 'Gp' from 'Gcoplanar' to 'Gpoints'
+ - changed "nearest" facet for 'Pdk' to threshold - normal
+ - reworked qh GOODclosest for 'Qg'
+ - added note that 'Qg' does not always work
+ - recorded option 'C-0' as "_zero-merge" in option 'FO'
+ - refined qh DISTround in qh_maxmin/geom2.c for Delaunay triangulations
+
+qhull V2.2 95/12/4
+ - Version 2.2 fixes an important bug in computing Delaunay triangulations
+ and convex hulls with edges sharper than ninety degrees. The problem
+ occurs when processing a point at a sharp edge. A directed search can
+ not be used for partitioning because one side may hide facets from the
+ other side. The new lens-shaped distribution for rbox demonstrates the
+ problem. For example, 'rbox 100 L3 G0.5 s | qhull Tv' fails for Version 2.1.
+ O. Schramm found the bug when computing the Delaunay triangulation of points
+ near an outside edge.
+
+ I rewrote qh_findbest and related functions. Qh_findbest
+ uses an exhaustive test for sharp edges (qh_findbest_sharp).
+ Qh_findbest avoids the upper convex hull of Delaunay triangulations.
+
+ Options 'd' and 'v' no longer assign coplanar points to the upper convex hull.
+
+ Qh_check_maxout tests near-inside points. It ignores fully inside points.
+ When done, it removes near-inside points from the coplanar sets.
+
+ If you use qh_addpoint or qh_findbest, please review the function headers.
+ They do not work for lens-shaped hulls for arbitrary facets. They do work for
+ Delaunay triangulations.
+
+ Changes to options for V2.2
+ - added 'Qu' for computing the furthest-site Delaunay triangulation (upper hull)
+ and furthest-site Voronoi vertices.
+ - added 'FP' to print nearest vertex for coplanar points
+ - added coplanar count to 'Fs' and 's'
+ - added number of similar points to summary for Delaunay/Voronoi
+ - Option 'Qc' is no longer necessary when merging.
+ - 'o' format for Voronoi vertices ('v') generates "0" lines for similar points
+ - 'QRn' for Delaunay ('d' or 'v') now rotates about the Z axis (see qh_init_B).
+ Otherwise Qhull does not identify the upper hull
+ - removed option 'Qa' for "all points outside". In V2.1 it was automatically
+ set for 'd'. Even though it was a bad idea, it revealed the above bug.
+ - for option list ('FO'), added version, values for one-merge, maxpos, maxneg,
+ and near-inside, and flags for zero-centrum
+ - optimized 'C-0' and 'Qx'. These options ("zero-centrum") test vertices
+ instead of centrums for adjacent simplicial facets.
+ - if 'Tv', report number of points that are not verified due to qh_findbest
+ - Option 'Q8' ignores near-inside points.
+
+ rbox 95/12/3
+ - added lens distribution ('Ln') It may be used with 's', 'r', 'Wn', and 'Gn'
+ - removed default point count except for the test case, 'Dn'
+ - divided main() of rbox.c into sections
+
+ Documentation changes for V2.2
+ - added examples for lens distribution and furthest-site Delaunay triangulation
+ and renumbered the examples for q_eg
+ - described facet orientation in 'data structure' section [P. Soikkonen]
+ - added notes to qh-man.html/"What to do if something goes wrong"
+ - added note about using 'Tv' to verify the results [O. Schramm]
+ - expanded definition of f_r in Performance section [S. Grundmann]
+ - noted that Geomview display of a Voronoi diagram adds extra edges
+ for unbounded Voronoi cells
+ - rewrote error "convexity constraints may be too strong" [D. Newland]
+ - added limitations section to "Imprecision in Qhull"
+ - added note about zero-area facets to 'Imprecise convex hulls' in qh-impre.html
+ - added note to 'Qi' that it does not retain coplanar points
+ - added note that option 'Q5' may be used if outer planes are not needed
+ - added note to README.txt about Irix 5.1 [C. Goudeseune]
+ - added code fragment for visiting Voronoi vertices to "Calling Qhull" [M. Downes]
+ - added note about qh_addpoint() to "Calling Qhull" [M. Downes]
+
+ Errors fixed for V2.2
+ - use qh_sethyperplane_gauss if 3-d or 4-d norm is less than qh MINnorm
+ - count Zcentrumtests if qh_NOstat
+ - reversed sign convention for qh_sethyperplane_gauss
+ it was opposite to qh_sethyperplane_det
+ this effects qh_determinant and qh_detsimplex
+ - fixed error in qh_findgood_all with multiple restrictions, e.g., 'QVn Pdk'
+ - fixed call to qh_clearcenters for qh_produce_output
+ - in qh_errexit, report p0 if last furthest point
+
+ Changes for users of the Qhull library
+ - user code needs to define qh_version (see user_eg.c)
+ - merged initialization code into qh_init_A and qh_init_B [M. Mazzario]
+ old code works as before.
+ qh_initflags also sets qh qhull_command for qh_initthresholds
+ redid initialization for user_eg.c
+ - simplified user_eg.c. It computes the convex hull of a cube.
+ - added qh_setvoronoi_all in poly2.c to compute Voronoi centers
+ added related note to call_qhull
+ - added qh_findfacet to use in place of qh_findbest
+ - added qh_nearvertex to return nearest vertex in facet to point
+ - redid notes on multiple, concurrent calls in call_qhull/user.c
+ - changed BoolT to unsigned int (prevent implicit enum conversion warnings)
+ - added upperdelaunay to facetT. It indicates a facet of the upper convex hull.
+ - converted qhull-PPC.sit for CodeWarrior 7
+
+ Code changes for V2.2
+ - simplified calls to setjmp() for Cray J916 [Salazar & Velez]
+ - replaced fprintf(fp,string) with fputs in io.c
+ - 'qh num_coplanar' removed (too expensive and not used).
+ - added numcoplanars to qh_countfacets()
+ - added min norm to qh_normalize2(). qh_normalize() wasn't changed
+ - removed type casts from qh_point and qh_pointid [Salazar & Velez]
+ - account for roundoff error in detecting upper convex hull (qh ANGLEround).
+ - post merging uses qh_findbestnew for partitioning
+ - qh_findbestnew for qh_partitioncoplanar goes to best facet
+ - 'Qm' always processes points above the upper hull of a Delaunay triangulation
+ - GOODvertex initialized with qh_findbestnew instead of qh_findbest
+ - for 'v', qh_facetcenter returns furthest-neighbor vertex if 'Qu'
+ - added test for qh feasible_point if use 'Fp' and qh_sethalfspace_all
+ - reviewed Sugihara's algorithm for topologically robust beneath-beyond
+ - on error, report if qhull in post-merging or has completed
+ - if tracing, option 'FO' and qhull command always printed
+ - added current furthest point ("during p%d") to 'T-1' events
+ - added 'TWn' tracing for vertices of new facets (qh_setfacetplane)
+ - added 'TWn' tracing for vertices in an output facet (qh_check_maxout)
+ - reorganized split between poly/poly2.c and geom/geom2.c
+ - reordered object files in Makefile
+
+------------
+qhull V2.1 95/9/25
+ - converted qhull.man to html format, many edits
+ - referenced Shewchuk's triangle program and Schneiders' Mesh Generation page
+ - added option 'Qa' to force all points outside
+ automatically set for "precise" Delaunay or Voronoi [Salazar & Velez]
+ it is turned off by merging, 'Wn', 'Qc' or 'Qi'
+ - added coplanar points to option 'FN'
+ - moved option 'FO' to include default precision options
+ - changed default random number generator to qh_rand in geom2.c (user.h)
+
+ other code changes
+ - fixed option comment Pdrop-facets-dim-less, Qbound-dim-low, QbBound-unit-box
+ - defined ptr_intT for converting 64-bit ptrs to 'unsigned long' [D. Bremner]
+ - defined setelemT to distinguish actual size from pointers [D. Bremner]
+ use either e[...].p or e[...].i (user-level code should use set.h macros)
+ - changed %x to %p in format statements for pointers [D. Bremner]
+ - added test of REALmax,etc. to qh_maxmin [H. Poulard]
+ - added type parameter to qh_memalloc_() macro for type conversion
+ - added type conversion to qh_memalloc() calls where missing
+ - added type conversion to calls into set.c that return void*
+
+ other documentation changes:
+ - new URLs for graphics images
+ - fixed comment for facetT.neighbors in libqhull.h [P. Soikkonen]
+ - changed recommendations for precision errors in qh_printhelp_degenerate()
+ - added recommendation for 'V0' (facet is visible if distance >= 0)
+ - added note about 'long double' to user.h [S. Grundmann]
+ - added note about zero area Delaunay triangles for the 'v' option
+ - added note about locating Delaunay triangles to option 'd' [A. Curtis]
+ - added note that coplanar vertices correspond to duplicate points for 'd'
+ - added note about option 'd' automatically setting 'PDk' (lower convex hull)
+ - added note about precision errors to option 'd' [many users]
+ - added note about qh_findbest() to the Qhull library section [L. Lai]
+ - 'make install' renames qhull.man to qhull.1 for Unix [M. Phillips]
+ - renamed README, etc. to *.txt to match WWW conventions [D. Cervone]
+
+------------
+qhull V2.1 7/10/95
+ - in 2-d, 'v o' lists the vertex at infinity in order [R. Critchlow]
+ - it used to always list the vertex at infinity ("0") first
+ - rewrote description of 'v' option (Voronoi vertices and 2-d diagrams)
+ - added 'PFn' for printing facets whose area is at least 'n' [D. Holland]
+ - prefixed 'Q',etc. to the 'Q',etc. options in the long help prompt
+ - fixed references to 'Fv' and 'FV' options under option 'Hn,n,n'
+ - updated reference to cdd, <ftp://ifor13.ethz.ch/pub/fukuda/cdd/>
+ - in set.c, added some missing type coercions for qhmem.tempstack
+
+qhull V2.1 6/12/95
+ - replaced qhull.ps with qhull-2.ps (paper submitted to ACM TOMS)
+ - use BUFSIZ for setvbuf for Power Macintosh
+ - number of good facets printed if QVn, QGn, Pd, or PD
+ - added Makefile for Borland C++ 4.02 with Win32 [D. Zwick]
+ - added note to Enhancements section of qhull.1 about constrained
+ Delaunay triangulations [T. Rasanen]
+
+qhull V2.1 6/7/95
+ - fixed qh_facetarea_simplex() for non-simplicial facets [L. Schramm]
+ - fixed cast in qh_point and qh_pointid for 64-bit architectures
+ - fixed URL for Amenta's list of computational geometry software
+ - fixed cast in qh_meminitbuffers for qhmem.freelists
+ - added test for !qh half_space in qh readpoints
+ - clarified options for qh_printhelp_singular()
+ - discussed non-simplicial facet area under option 'Fa' in qhull.1
+
+qhull V2.1 6/3/95
+ - home page for Qhull and new descriptions for the Qhull examples
+ http://www.qhull.org
+ - changed SIOUX buffering for Power Macintosh. It runs fast now.
+ added a project file for Metrowerk's C
+ - note in README about compiling qhull on the PC
+
+qhull V2.1 beta 5/15/95
+
+ ======= main changes ========
+ - added halfspace intersection ('Hn,n,n')
+ - facet merging is better, especially for high dimensions
+ - added 'Qx' for exact merges of coplanar points and precision faults
+ - facet merging is faster, especially for high dimensions.
+ e.g., convex hull of the 8-d hypercube is seven times faster
+ - added 'F' output formats for printing each aspect of the convex hull
+ - format 'Fa' computes facet areas, total area, and total volume
+ - format 'FO' writes a descriptive list of selected options to stderr
+ - moved all customization options to user.h
+ - changed the default precision to 'double' since it's needed for Delaunay.
+ using 'float' is faster and takes less space (REALfloat in user.h)
+ - option 'Qm' is no longer important for facet merging
+ - removed need for 'Qs' by selecting initial simplex with pos. determinants
+ - renamed 'Qv' to 'Q7' since virtual memory does not work well for qhull
+ - Qhull is available for the Power Mac (no graphical output)
+
+ ====== other new and modified options ===========
+ - changed default MINvisible ('Vn') to a multiple of premerge_centrum ('C-n')
+ - added 'Un' option to set width of facet for coplanar points.
+ This replaces the previous rules for determining coplanar points.
+ - changed default MINoutside ('Wn') to twice MINvisible ('Vn')
+ - Geomview output adjusts point radii for MINvisible 'Vn'
+ - the input format allows the number of points to precede the dimension
+ - options 'v' 'd' 'FAn' and 'FMn' record good facets ('Pg')
+ - added 'Fd' and 'FD' options for homogeneous coordinates in cdd format
+ - in rbox, added 'h' flag to generate homogeneous coordinates in cdd format
+ - option 'PAn' prints out the n facets with the largest area
+ - option 'PMn' prints out the n facets with the most merges
+ - option 'Po' under tracing ('Tn') no longer tries to write erroneous facets
+ - option 'TCn' only prints the old 'visible' facets for 'f'
+ - 'TFn' reports intermediate results when post-merging
+ - option 'Ts' with option 'TFn' prints intermediate statistics
+ - the message for 'Tv' reports if it is checking outer planes
+ - 'Tz' sends stderr output to stdout
+ - added 'Q1' to ignore angle when sorting merges (merges are worse)
+ - added 'Q2' to not perform merges in independent sets (merges are worse)
+ - added 'Q3' to not remove redundant vertices (faster)
+ - added 'Q4' to avoid merges of old facets into new facets (does worse)
+ - added 'Q5' to skip qh_check_maxout (faster, but less accurate)
+ - added 'Q6' to skip pre-merge of concave and coplanar facets
+ - added 'Qv' for testing vertex neighbors for convexity (needs merge option)
+ - added warning if mix Geomview output with other outputs ('Po' turns off)
+ - options 'o v' for 3-d and higher sort the Voronoi vertices by index
+
+ ======= documentation =======
+ - rewrote the introduction and precision sections
+ - added a section on performance
+ - added an example on halfspace intersection
+ - installed examples of Qhull in
+ <http://www.geom.uiuc.edu/graphics/pix/Special_Topics/Computational_Geometry/>
+
+ ======= Makefile, user.h, and messages =======
+ - Makefile calls ./qhull, ./rbox, and prints short prompt for qhull
+ - added new statistics, e.g., for buildhull
+ - changed default qh_RANDOMtype to RAND_MAX with rand()
+ - added comment about numeric overflow to printhelp_singular
+ - reorganized the code to improve locality of reference
+ - option in mem.h (qh_NOmem) to turn off memory management in qhull
+ - option in user.h (qh_NOtrace) to turn off tracing in qhull
+ - option in user.h (qh_NOmerge) to turn off merging in qhull.
+ - use this instead of redefining qh_merge_nonconvex in user.c
+ - simplified user_eg.c. See qh_call_qhull() in user.c for the full version
+
+ ======== bug fixes ============
+ - fixed error in number of points for 'rbox 100 r' (odd distribution)
+ - fixed performance error in qh_degen_redundant_neighbors
+ - qh_partitionpoint now sets facet->maxoutside for first outside point
+ - fixed performance error in partitioning when merging a large, regular cone
+ - removed memory leak in qh_appendmergeset
+ - removed double free of qh line under errors in qh_readinput()
+ - forcing output on error ('Po') fixed for options 'n' 'o' 'i' 's'
+ - fixed optimization error on HP machines [fprintf(... *p++)]
+
+ ======== changes to libqhull.h for user code =======
+ - qh_collectstatistics and qh_printstatistics removed from libqhull.h.
+ should use qh_printallstatistics instead
+ - qh_findbest uses boolT for newfacets
+ - added qh_findbestnew for non-simplicial facets. qh_findbest is
+ too slow in this case since it needs to look at many nearly coplanar
+ facets.
+ - renamed qh_voronoi/qh_centrum to qh_ASvoronoi, qh_AScentrum
+ - changed facet->id to 32-bits, added new flags for merging
+ - added facet->f for facet pointers while merging and for facet area
+ - added dfacet/dvertex for printing facets/vertices while debugging
+ - added qh_produce_output and qh_printsummary
+
+ ======== changes to code ==========
+ - moved qh_setfacetplane from qh_makenewfacets to qh_makenewplanes
+ - added qh_setfree2, qh_setcompact, and qh_setduplicate to set.c
+ - qh_findgooddist returns list of visible facets instead of setting global
+ - in qh_check_maxout, inside points may be added to coplanar list.
+ - qh_findbestnew used for qh_partitionall. It is faster.
+ - in qh_findbest, changed searchdist to MINvisible+max_outside+DISTround.
+ MINvisible is the default MAXcoplanar.
+ - cleaned up list management via qh_resetlists
+ - uses facet->dupridge to indicate duplicated ridges instead of ->seen
+ - qh_buildtracing records CPU time relative to qh hulltime instead of 0
+
+ ========== changes to merging =======
+ - many performance improvements, especially in high-d.
+ - when merging, qh_findbest and qh_findbestnew stops search at qh_DISToutside
+ - vertex neighbors delayed until first merge
+ - post merges reported every TFn/2 merges
+ - vertex merging turned off in 7-d and higher (lots of work, no benefit).
+ vertex merging moved to qh_qhull_postmerging in 6-d.
+ - replaced qh min_vertex with MAXcoplanar for determining coplanarity
+ - pick closest facets to merge in duplicate ridge instead of flip/flip
+ (see qh_matchduplicates in poly2.c)
+ - optimize merge of simplex into a facet
+ - optimize merge of a "samecycle" of facets into a coplanar horizon facet
+ - cleaned up qh_forcedmerges/qh_flippedmerges and removed facet->newmerge
+ - rewrote qh_merge_degenredundant with separate queue
+ - qh_facetdegen replaced by facet->degenredun
+ - flipped neighbors no longer merged in preference to flip/non-flip pairs
+ - removed angle argument from qh_merge_degenredundant and qh_mergefacet
+ only used for tracing
+ - getmergeset_initial had extra test of neighbor->simplicial
+ - ridge->nonconvex is now set on only one ridge between non-convex facets
+ - moved centrum deletion to qh_updatetested
+ - qh_isnewmerge(facet) changed to facet->newmerge (removed NEWmerges)
+ - qh_findbestneighbor reports correct distance even if testcentrum
+ - added hull_dim factor to qh_BESTcentrum
+ - removed horizon preference in qh_merge_nonconvex (qh AVOIDold)
+ - facet->keepcentrum if qh WIDEfacet or qh_MAXnewcentrum extra vertices
+
+------------
+qhull V2.02 1/25/95
+ - rbox 'z' prints integer coordinates, use 'Bn' to change range
+ - fixed rare bug in qh_check_maxout when qh_bestfacet returns NULL
+ - fixed performance bug in findbestneighbor, should be + BESTnonconvex
+ - renamed 'notgood' flag in 'f' option to 'notG' flag (caused confusion)
+ - changed qh.hulltime to (unsigned) to prevent negative CPU times
+ - added random perturbations to qh_getangle under the 'Rn' option
+ - reviewed the documentation and enhancement list
+ - added discussion of how to intersect halfspaces using qhull
+ - replaced expression that caused incorrect code under an old version of gcc
+ - added buffer after qh.errexit in case 'jmp_buf' has the wrong size
+ - rewrote qh_printhelp_singular for lower-dimensional inputs
+ - rewrote qh_printhelp_degenerate
+ - added options for qh_RANDOMint in qhull_a.h
+ - changed time format for 'TFn' to %02d
+
+------------
+qhull V2.01 6/20/94
+ - fixed bug in qh_matchnewfacets that occured when memory alignment makes
+ facet->neighbors larger than necessary.
+ - fixed bug in computing worst-case simplicial merge of angle coplanar
+ facets (ONEmerge). This decreases (...x) in printsummary.
+
+qhull V2.01 6/17/94
+ - added recommendation for 'Qcm' to documentation and help prompts
+ - added an input warning to qh_check_points ('Tv') if coplanars and no 'Qc'
+ - qh_partitionpoint: always counts coplanar partitions (Zcoplanarpart)
+ - rewrote qh_printhelp_degenerate to emphasize option 'C-0'
+ - For Geomview output, roundoff is not needed when printing the inner and
+ outer planes. This improves Geomview output for the 'Rn' option.
+ - For Geomview output without coplanar points or vertices, qh_GEOMepislon
+ is not needed. This removes the edge gap when displaying a Voronoi cell.
+ - For Geomview output 'Gp', direct vertices to the interior point
+ instead of the arithmetic center of the displayed vertices.
+
+qhull V2.01 6/11/94
+ - if pre-merge, 'Qf' is automatically set. Otherwise an outside point may
+ be dropt by qh_findbest(). This slows down partitioning.
+ - always use 'Qc' if merging and all facet->maxoutside's must be right.
+ Otherwise distributions with many coplanar points may occassionally
+ miss a coplanar point for a facet. This is because qh_findbest, when
+ called by qh_check_maxout, can become stuck at a local maximum if
+ the search is started at an arbitrary facet. With 'Qc', the search
+ is started from a coplanar facet. For example,
+ rbox 1000 W8e-6 t | qhull C-0 Tv
+ will (rarely) report that a facet->minoutside is incorrect
+ - option 'Pp' turns off "Verifying" message for 'Tv'
+ - added qh_copynonconvex to qh_renameridgevertex (fixes rare error)
+ - 'rbox tn' sets random seed to n
+ - 'rbox t' reports random seed in comment line
+ - qh_errexit reports rbox_command | qhull_command and 'QR' random seed
+ - added additional tracing to bestdist and setfacetplane
+ - in qh_checkconvex, need to test coplanar against 0 instead of -DISTround
+ - in qh_checkconvex, always test centrums if merging. The opposite
+ vertex of a simplicial facet may be coplanar since a vertex of
+ a simplicial facet may be above the facet's hyperplane.
+ - fixed error handling in qh_checkconvex when merging
+ - in qh_printsummary, one merge ratio not printed if less than 'Wn'
+ - documented that 'Tv' verifies all facet->maxoutside
+
+qhull V2.01 6/2/94
+ - 's' prints summary to stderr
+ - multiple output formats printed in order to stdout
+ - added statistic for worst-case distance for merging simplicial facets
+ can not hope for a better "max distance above/below facet"
+ print factor for "max distance.."/"merge simplicial" in printsummary
+ - fixed error in scaling input with min/max reversed ('Qb0:1B0:-1')
+ - fixed error in scaling if project & Delaunay & scale ('d Qb0:0B1:0b2:0')
+ - user_eg.c: qh_delpoint removed since it does not always work
+ - user_eg.c now works for either convex hull or Delaunay triangulation
+ - added PROJECTdelaunay for Delaunay triangulations and Voronoi diagrams
+ with libqhull.a and user_eg.c
+ - user_eg.c: if project or scale input, need to copy points
+ - user_eg.c: default just defines main, added fprintf's for qh_errprint etc.
+ - qh_gausselim: a 0 pivot no longer zeros the rest of the array,
+ need the remaining elements for area computation
+ - qh_qhull: restore cos_max, centrum_radius at end of POSTmerging
+ - qh_checkflipped with !allerror is >=0.0 instead of >0.0
+ - removed -Wall from gcc due to unnecesssary "warning: implicit declaration"
+ - renamed 'new' variables and fields to allow compilation by g++
+ - added README notes on C++, and "size isn't known"
+ - updated manual on 'Qg' with coplanar facets and no merging ('rbox c D7')
+ 'Qg Pg' and 'Pg' produce different results because of precision problems
+
+------------
+Converting from qhull 1.01 to qhull 2.00
+ - 'qhull An' is now 'qhull Wn'
+ option 'Wn Po' is faster but it doesn't check coplanars
+ - 'qhull g' is now 'qhull G', and the output formats are different
+ - 'qhull c' is now 'qhull Tc'
+ - 'qhull f' is now 'qhull Qf'
+ - 'qhull o' is now 'qhull Po'
+ - 'qhull b' is now always done
+ - qhull and rbox now use floats, change REALfloat in libqhull.h for doubles
+ - qhull 2.00 fixes several initialization errors and performanace errors
+ e.g., "singular input" on data with lots of 0 coordinates
+ - 'rbox b' is now 'rbox c G0.48'
+ - all rbox distributions are now scaled to a 0.5 box (use 'Bn' to change)
+ - rbox now adds a comment line. This may be removed by 'rbox n'
+ - 'rbox r s Z G' no longer includes the positive pole
+ - no changes to the Macintosh version
+
+qhull V2.00 5/23/94
+ - if force output ('Po'), facet->maxoutside= 'Wn' since coplanars not updated
+ convexity checked if precision problems or verify ('Tv')
+ - if merging, new facets always checked for flipped orientation
+ - a facet is visible (findhorizon) under 'Qm' if distance > max_vertex
+ - if using 'Qm' then min. outside is max_vertex instead of max_outside
+ - default is random()/srandom() in qhull_a.h, checked in initqhull_globals
+ - created internal strtod since strtod may skip spacing after number
+ - removed lower bound (1.0) for qh maxmaxcoord
+ - divzero needs to handle 0/0 and large/small
+ - decreased size of precise vertices
+ - need to initialize qh MINdenom_1 for scalepoints
+ - added factor of qh maxmaxcoord into DISTround (needed for offset)
+ - 'Rn' perturbs distance computations by random +/-n
+ - check_points needs an extra DISTround to get from precise point to computed
+ - rewrote some of the IMPRECISION section in qhull.man
+ - added the input format to the qhull prompt
+ - moved include files to qhull_a.h since some compilers do not use float.h
+ - added qhull.1 and rbox.1 since SGI does not ship nroff
+ - reduced cutoff for printpointvect
+ - use time for qhull random seed only if QR0 or QR-1
+ - radius of vertices and coplanar points determined by pre-merge values
+
+qhull V2.00 5/12/94
+ - facet2point (io.c) used vertex0 instead of vertex1
+ - can't print visible facets after cone is attached
+ - shouldn't check output after STOPcone (TCn)
+ - statistic 'Wminvertex' and 'Wmaxoutside' only if MERGING or APPROXhull
+ - 'make doc' uses lineprinter format for paging
+ - warning if Gpv in 4-d
+
+qhull V2.b05 5/9/94
+ - decreased size of precise vertices
+ - precise facets in 2-d print hyperplanes
+ - accounted for GOODpoint in printsummary
+ - added IMPRECISION section to qhull.man
+ - 'Qg' does work in 7-d unless there's many coplanar facets
+
diff --git a/xs/src/qhull/src/libqhull/DEPRECATED.txt b/xs/src/qhull/src/libqhull/DEPRECATED.txt
new file mode 100644
index 000000000..617275c14
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/DEPRECATED.txt
@@ -0,0 +1,29 @@
+
+qhull/src/libqhull
+
+ This directory contains the non-reentrant version of qhull, libqhull.
+
+ New code should use the reentrant version of qhull (libqhull_r).
+ It allows multiple instances of qhull to run at the same time. On
+ modern architectures, it is nearly as fast as libqhull.
+
+ Qhull programs may be built with either library. Each program has a
+ reentrant version (e.g., qconvex_r.c) and a non-reentrant
+ version (qconvex.c). The programs, rbox, qconvex, qdelaunay, qhalf,
+ and qvoronoi, are built with libqhull. The qhull program is built
+ with libqhull_r.
+
+ Qhull's C++ interface requires libqhull_r. If you previously used the
+ C++ interface, you will need to update your code. See Changes.txt for
+ suggestions.
+
+ The C code in libqhull looks unusual because of the 'qh' macro. The 'qh'
+ macro controls access to Qhull's global data structure, qhT. If
+ 'qh_QHpointer' is defined, 'qh' is 'qh_qh->' and 'qh_qh' is defined as
+ 'qhT *qh_qh', otherwise 'qh' is 'qh_qh.' and 'qh_qh' is defined as
+ 'qhT qh_qh'.
+
+ libqhull will be supported indefinitely. The qh_QHpointer variation
+ of libqhull will be not be retested each release. It is replaced by
+ libqhull_r.
+
diff --git a/xs/src/qhull/src/libqhull/Makefile b/xs/src/qhull/src/libqhull/Makefile
new file mode 100644
index 000000000..bcad65777
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/Makefile
@@ -0,0 +1,240 @@
+# Simple gcc Makefile for non-reentrant qhull and rbox (default gcc/g++)
+#
+# make help
+# See README.txt and ../../Makefile
+#
+# Variables
+# BINDIR directory where to copy executables
+# DESTDIR destination directory for 'make install'
+# DOCDIR directory where to copy html documentation
+# INCDIR directory where to copy headers
+# LIBDIR directory where to copy libraries
+# MANDIR directory where to copy manual pages
+# PRINTMAN command for printing manual pages
+# PRINTC command for printing C files
+# CC ANSI C or C++ compiler
+# CC_OPTS1 options used to compile .c files
+# CC_OPTS2 options used to link .o files
+# CC_OPTS3 options to build shared libraries
+#
+# LIBQHULL_OBJS .o files for linking
+# LIBQHULL_HDRS .h files for printing
+# CFILES .c files for printing
+# DOCFILES documentation files
+# FILES miscellaneous files for printing
+# TFILES .txt versions of html files
+# FILES all other files
+# LIBQHULL_OBJS specifies the object files of libqhullstatic_r.a
+#
+# Results
+# rbox Generates points sets for qhull, qconvex, etc.
+# qhull Computes convex hulls and related structures
+# qconvex, qdelaunay, qhalf, qvoronoi
+# Specializations of qhull for each geometric structure
+# libqhullstatic_r.a Static library for non-reentrant qhull
+# testqset_r Standalone test of non-reentrant qset_r.c with mem_r.c
+# user_eg An example of using qhull (non-reentrant)
+# user_eg2 An example of using qhull (non-reentrant)
+#
+# Make targets
+# make Build results using gcc or another compiler
+# make clean Remove object files
+# make cleanall Remove generated files
+# make doc Print documentation
+# make help
+# make install Copy qhull, rbox, qhull.1, rbox.1 to BINDIR, MANDIR
+# make new Rebuild qhull and rbox from source
+# make printall Print all files
+# make qtest Quick test of qset, rbox, and qhull
+# make test Quck test of qhull, qconvex, etc.
+#
+# Do not replace tabs with spaces. Needed for build rules
+# Unix line endings (\n)
+# $Id: //main/2015/qhull/src/libqhull/Makefile#8 $
+
+DESTDIR = /usr/local
+BINDIR = $(DESTDIR)/bin
+INCDIR = $(DESTDIR)/include
+LIBDIR = $(DESTDIR)/lib
+DOCDIR = $(DESTDIR)/share/doc/qhull
+MANDIR = $(DESTDIR)/share/man/man1
+
+# if you do not have enscript, try a2ps or just use lpr. The files are text.
+PRINTMAN = enscript -2rl
+PRINTC = enscript -2r
+# PRINTMAN = lpr
+# PRINTC = lpr
+
+#for Gnu's gcc compiler, -O3 for optimization, -g for debugging, -pg for profiling
+# -fpic needed for gcc x86_64-linux-gnu. Not needed for mingw
+CC = gcc
+CC_OPTS1 = -O3 -ansi -I../../src -fpic $(CC_WARNINGS)
+
+# for Sun's cc compiler, -fast or O2 for optimization, -g for debugging, -Xc for ANSI
+#CC = cc
+#CC_OPTS1 = -Xc -v -fast -I../../src
+
+# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
+#CC = cc
+#CC_OPTS1 = -ansi -O2 -I../../src
+
+# for Next cc compiler with fat executable
+#CC = cc
+#CC_OPTS1 = -ansi -O2 -I../../src -arch m68k -arch i386 -arch hppa
+
+# For loader, ld,
+CC_OPTS2 = $(CC_OPTS1)
+
+# Default targets for make
+
+all: qhull_links qhull_all qtest
+
+help:
+ head -n 50 Makefile
+
+clean:
+ rm -f *.o
+ # Delete linked files from other directories [qhull_links]
+ rm -f qconvex.c unix.c qdelaun.c qhalf.c qvoronoi.c rbox.c
+ rm -f user_eg.c user_eg2.c testqset.c
+
+cleanall: clean
+ rm -f qconvex qdelaunay qhalf qvoronoi qhull *.exe
+ rm -f core user_eg user_eg2 testqset libqhullstatic.a
+
+doc:
+ $(PRINTMAN) $(TXTFILES) $(DOCFILES)
+
+install:
+ mkdir -p $(BINDIR)
+ mkdir -p $(DOCDIR)
+ mkdir -p $(INCDIR)/libqhull
+ mkdir -p $(MANDIR)
+ cp -p qconvex qdelaunay qhalf qhull qvoronoi rbox $(BINDIR)
+ cp -p libqhullstatic.a $(LIBDIR)
+ cp -p ../../html/qhull.man $(MANDIR)/qhull.1
+ cp -p ../../html/rbox.man $(MANDIR)/rbox.1
+ cp -p ../../html/* $(DOCDIR)
+ cp *.h $(INCDIR)/libqhull
+
+new: cleanall all
+
+printall: doc printh printc printf
+
+printh:
+ $(PRINTC) $(LIBQHULL_HDRS)
+
+printc:
+ $(PRINTC) $(CFILES)
+
+# LIBQHULL_OBJS_1 ordered by frequency of execution with small files at end. Better locality.
+# Same definitions as ../../Makefile
+
+LIBQHULLS_OBJS_1= global.o stat.o geom2.o poly2.o merge.o \
+ libqhull.o geom.o poly.o qset.o mem.o random.o
+
+LIBQHULLS_OBJS_2= $(LIBQHULLS_OBJS_1) usermem.o userprintf.o io.o user.o
+
+LIBQHULLS_OBJS= $(LIBQHULLS_OBJS_2) rboxlib.o userprintf_rbox.o
+
+LIBQHULL_HDRS= user.h libqhull.h qhull_a.h geom.h \
+ io.h mem.h merge.h poly.h random.h \
+ qset.h stat.h
+
+# CFILES ordered alphabetically after libqhull.c
+CFILES= ../qhull/unix.c libqhull.c geom.c geom2.c global.c io.c \
+ mem.c merge.c poly.c poly2.c random.c rboxlib.c \
+ qset.c stat.c user.c usermem.c userprintf.c \
+ ../qconvex/qconvex.c ../qdelaunay/qdelaun.c ../qhalf/qhalf.c ../qvoronoi/qvoronoi.c
+
+TXTFILES= ../../Announce.txt ../../REGISTER.txt ../../COPYING.txt ../../README.txt ../Changes.txt
+DOCFILES= ../../html/rbox.txt ../../html/qhull.txt
+
+.c.o:
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+
+# Work around problems with ../ in Red Hat Linux
+qhull_links:
+ # On MINSYS, 'ln -s' may create a copy instead of a symbolic link
+ [ -f qconvex.c ] || ln -s ../qconvex/qconvex.c
+ [ -f qdelaun.c ] || ln -s ../qdelaunay/qdelaun.c
+ [ -f qhalf.c ] || ln -s ../qhalf/qhalf.c
+ [ -f qvoronoi.c ] || ln -s ../qvoronoi/qvoronoi.c
+ [ -f rbox.c ] || ln -s ../rbox/rbox.c
+ [ -f testqset.c ] || ln -s ../testqset/testqset.c
+ [ -f unix.c ] || ln -s ../qhull/unix.c
+ [ -f user_eg.c ] || ln -s ../user_eg/user_eg.c
+ [ -f user_eg2.c ] || ln -s ../user_eg2/user_eg2.c
+
+# compile qhull without using bin/libqhullstatic.a
+qhull_all: qconvex.o qdelaun.o qhalf.o qvoronoi.o unix.o user_eg.o user_eg2.o rbox.o testqset.o $(LIBQHULLS_OBJS)
+ $(CC) -o qconvex $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qconvex.o
+ $(CC) -o qdelaunay $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qdelaun.o
+ $(CC) -o qhalf $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qhalf.o
+ $(CC) -o qvoronoi $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qvoronoi.o
+ $(CC) -o qhull $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) unix.o
+ $(CC) -o rbox $(CC_OPTS2) -lm $(LIBQHULLS_OBJS) rbox.o
+ $(CC) -o user_eg $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) user_eg.o
+ $(CC) -o user_eg2 $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_1) user_eg2.o usermem.o userprintf.o io.o
+ $(CC) -o testqset $(CC_OPTS2) -lm mem.o qset.o usermem.o testqset.o
+ -ar -rs libqhullstatic.a $(LIBQHULLS_OBJS)
+ #libqhullstatic.a is not needed for qhull
+ #If 'ar -rs' fails try using 'ar -s' with 'ranlib'
+ #ranlib libqhullstatic.a
+
+qtest:
+ @echo ============================================
+ @echo == make qtest ==============================
+ @echo ============================================
+ @echo -n "== "
+ @date
+ @echo
+ @echo Testing qset.c and mem.c with testqset
+ ./testqset 10000
+ @echo Run the qhull smoketest
+ ./rbox D4 | ./qhull
+ @echo ============================================
+ @echo == To smoketest qhull programs
+ @echo '== make test'
+ @echo ============================================
+ @echo
+ @echo ============================================
+ @echo == For all make targets
+ @echo '== make help'
+ @echo ============================================
+ @echo
+
+test: qtest
+ @echo ==============================
+ @echo ========= qconvex ============
+ @echo ==============================
+ -./rbox 10 | ./qconvex Tv
+ @echo
+ @echo ==============================
+ @echo ========= qdelaunay ==========
+ @echo ==============================
+ -./rbox 10 | ./qdelaunay Tv
+ @echo
+ @echo ==============================
+ @echo ========= qhalf ==============
+ @echo ==============================
+ -./rbox 10 | ./qconvex FQ FV n Tv | ./qhalf Tv
+ @echo
+ @echo ==============================
+ @echo ========= qvoronoi ===========
+ @echo ==============================
+ -./rbox 10 | ./qvoronoi Tv
+ @echo
+ @echo ==============================
+ @echo ========= user_eg ============
+ @echo == w/o shared library ========
+ @echo ==============================
+ -./user_eg
+ @echo
+ @echo ==============================
+ @echo ========= user_eg2 ===========
+ @echo ==============================
+ -./user_eg2
+ @echo
+
+# end of Makefile
diff --git a/xs/src/qhull/src/libqhull/Mborland b/xs/src/qhull/src/libqhull/Mborland
new file mode 100644
index 000000000..46d88dbd4
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/Mborland
@@ -0,0 +1,206 @@
+#########################################################################
+# Borland C++ 4.02 for Win32 and DOS Power Pack #
+# Makefile for qhull and rbox #
+# #
+# make -fMborland all to produce qconvex, qhull, and rbox #
+# make -fMborland user_eg to produce user_eg #
+# make -fMborland user_eg2 to produce user_eg2 #
+# make -fMborland new to rebuild qhull and rbox from source #
+# make -fMborland clean to remove object files #
+# make -fMborland cleanall to remove all generated files #
+# make -fMborland test to test rbox and qhull #
+# #
+# Author: D. Zwick of Germany, C.B. Barber #
+#########################################################################
+
+CC = bcc32 # 32 bit compiler for DOS
+ # bcc32i - Intel's compiler
+LINKER = $(CC) # bcc calls tlink32 with needed options
+CFLAGS = -w- -A -O2
+ # -w- no warnings, bcc doesn't handle assigns in conditions
+ # -A Ansi standard
+ # -X no auto-dependency outputs
+ # -v debugging, use CCOPTS for both
+ # -O2 optimization
+!if $d(_DPMI)
+LFLAGS = -WX -w- # -WX loads DPMI library
+!else
+LFLAGS = -lap -lx -lc
+ # -lap 32-bit console application
+ # -lx no map file
+ # -lc case is significant
+!endif
+
+EXERB = rbox
+EXEQH = qhull
+EXEQC = qconvex
+EXEQD = qdelaunay
+EXEQV = qvoronoi
+EXEQF = qhalf
+EXEEG = user_eg
+EXEEG2 = user_eg2
+
+TMPFILE = BCC32tmp.cfg
+
+OBJS1 = global.obj stat.obj geom2.obj poly2.obj merge.obj
+OBJS2 = libqhull.obj geom.obj poly.obj qset.obj mem.obj
+OBJS3 = random.obj usermem.obj userprintf.obj io.obj user.obj
+OBJS4 = rboxlib.obj random.obj usermem.obj userprintf_rbox.obj
+
+HFILES1 = libqhull.h stat.h qhull_a.h user.h
+
+
+# General rules
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $<
+
+# Default
+
+all: $(EXERB) $(EXEQH) $(EXEQC) $(EXEQD) $(EXEQV) $(EXEQF) test
+
+help:
+ @echo USAGE:
+ @echo "make all to produce qhull, rbox, qconvex, qdelaun, qvoronoi, qhalf"
+ @echo "make user_eg to produce user_eg"
+ @echo "make user_eg2 to produce user_eg2"
+ @echo "make new to rebuild qhull and rbox from source"
+ @echo "make clean to remove object files"
+ @echo "make cleanall to remove all generated file"
+ @echo "make test to test rbox and qhull"
+ @echo OPTIONS (default is 32-bit console app):
+ @echo "-D_DPMI for C++ 4.01 and DOS Power Pack"
+
+# Executables
+
+$(EXEQH): ..\..\bin\$(EXEQH).exe
+ @echo Made ..\..\bin\$(EXEQH).exe
+
+unix.obj: ..\qhull\unix.c
+..\..\bin\$(EXEQH).exe: unix.obj $(OBJS1) $(OBJS2) $(OBJS3)
+ @echo unix.obj > $(TMPFILE)
+ @echo $(OBJS1) >> $(TMPFILE)
+ @echo $(OBJS2) >> $(TMPFILE)
+ @echo $(OBJS3) >> $(TMPFILE)
+ $(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
+
+$(EXEQC): ..\..\bin\$(EXEQC).exe
+ @echo Made ..\..\bin\$(EXEQC).exe
+
+qconvex.obj: ..\qconvex\qconvex.c
+..\..\bin\$(EXEQC).exe: qconvex.obj $(OBJS1) $(OBJS2) $(OBJS3)
+ @echo qconvex.obj > $(TMPFILE)
+ @echo $(OBJS1) >> $(TMPFILE)
+ @echo $(OBJS2) >> $(TMPFILE)
+ @echo $(OBJS3) >> $(TMPFILE)
+ $(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
+
+$(EXEQD): ..\..\bin\$(EXEQD).exe
+ @echo Made ..\..\bin\$(EXEQD).exe
+
+qdelaun.obj: ..\qdelaunay\qdelaun.c
+..\..\bin\$(EXEQD).exe: qdelaun.obj $(OBJS1) $(OBJS2) $(OBJS3)
+ @echo qdelaun.obj > $(TMPFILE)
+ @echo $(OBJS1) >> $(TMPFILE)
+ @echo $(OBJS2) >> $(TMPFILE)
+ @echo $(OBJS3) >> $(TMPFILE)
+ $(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
+
+$(EXEQV): ..\..\bin\$(EXEQV).exe
+ @echo Made ..\..\bin\$(EXEQV).exe
+
+qvoronoi.obj: ..\qvoronoi\qvoronoi.c
+..\..\bin\$(EXEQV).exe: qvoronoi.obj $(OBJS1) $(OBJS2) $(OBJS3)
+ @echo qvoronoi.obj > $(TMPFILE)
+ @echo $(OBJS1) >> $(TMPFILE)
+ @echo $(OBJS2) >> $(TMPFILE)
+ @echo $(OBJS3) >> $(TMPFILE)
+ $(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
+
+$(EXEQF): ..\..\bin\$(EXEQF).exe
+ @echo Made ..\..\bin\$(EXEQF).exe
+
+qhalf.obj: ..\qhalf\qhalf.c
+..\..\bin\$(EXEQF).exe: qhalf.obj $(OBJS1) $(OBJS2) $(OBJS3)
+ @echo qhalf.obj > $(TMPFILE)
+ @echo $(OBJS1) >> $(TMPFILE)
+ @echo $(OBJS2) >> $(TMPFILE)
+ @echo $(OBJS3) >> $(TMPFILE)
+ $(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
+
+$(EXEEG): ..\..\bin\$(EXEEG).exe
+ @echo Made ..\..\bin\$(EXEEG).exe
+
+user_eg.obj: ..\user_eg\user_eg.c
+..\..\bin\$(EXEEG).exe: user_eg.obj $(OBJS1) $(OBJS2) $(OBJS3)
+ @echo user_eg.obj > $(TMPFILE)
+ @echo $(OBJS1) >> $(TMPFILE)
+ @echo $(OBJS2) >> $(TMPFILE)
+ @echo $(OBJS3) >> $(TMPFILE)
+ $(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
+
+$(EXEEG2): ..\..\bin\$(EXEEG2).exe
+ @echo Made ..\..\bin\$(EXEEG2).exe
+
+user_eg2.obj: ..\user_eg2\user_eg2.c
+..\..\bin\$(EXEEG2).exe: user_eg2.obj $(OBJS1) $(OBJS2) $(OBJS3)
+ @echo user_eg2.obj > $(TMPFILE)
+ @echo $(OBJS1) >> $(TMPFILE)
+ @echo $(OBJS2) >> $(TMPFILE)
+ @echo $(OBJS3) >> $(TMPFILE)
+ $(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
+
+$(EXERB): ..\..\bin\$(EXERB).exe
+ @echo Made ..\..\bin\$(EXERB).exe
+
+rbox.obj: ..\rbox\rbox.c
+..\..\bin\$(EXERB).exe: rbox.obj $(OBJS4)
+ @echo rbox.obj > $(TMPFILE)
+ @echo $(OBJS4) >> $(TMPFILE)
+ $(LINKER) -e$@ $(CFLAGS) $(LFLAGS) @$(TMPFILE)
+
+# Test rbox and qhull
+
+test:
+ @..\..\bin\rbox D4 > test.x
+ @..\..\bin\qhull <test.x
+ @del test.x
+
+# Clean up
+
+clean:
+ @del *.obj
+ @del $(TMPFILE)
+
+cleanall: clean
+ @del ..\..\bin\$(EXERB).exe
+ @del ..\..\bin\$(EXEQC).exe
+ @del ..\..\bin\$(EXEQD).exe
+ @del ..\..\bin\$(EXEQF).exe
+ @del ..\..\bin\$(EXEQH).exe
+ @del ..\..\bin\$(EXEQV).exe
+ @del ..\..\bin\$(EXEEG).exe
+ @del ..\..\bin\$(EXEEG2).exe
+ @del ..\q_test.x
+ @del ..\q_test.log.1
+
+# Clean up and rebuild all
+
+new: cleanall all
+
+# Header file dependencies
+
+libqhull.obj stat.obj user.obj global.obj usermem.obj userprintf.obj: $(HFILES1)
+random.obj: libqhull.h random.h
+geom.obj geom2.obj: $(HFILES1) geom.h
+poly.obj poly2.obj: $(HFILES1) poly.h
+io.obj: $(HFILES1) io.h
+merge.obj: $(HFILES1) merge.h
+mem.obj: mem.h
+qset.obj: qset.h mem.h
+unix.obj: libqhull.h user.h
+qconvex.obj: libqhull.h user.h
+qdelaun.obj: libqhull.h user.h
+qhalf.obj: libqhull.h user.h
+qvoronoi.obj: libqhull.h user.h
+rbox.obj: user.h
diff --git a/xs/src/qhull/src/libqhull/geom.c b/xs/src/qhull/src/libqhull/geom.c
new file mode 100644
index 000000000..71444f05a
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/geom.c
@@ -0,0 +1,1234 @@
+/*<html><pre> -<a href="qh-geom.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ geom.c
+ geometric routines of qhull
+
+ see qh-geom.htm and geom.h
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/geom.c#2 $$Change: 1995 $
+ $DateTime: 2015/10/13 21:59:42 $$Author: bbarber $
+
+ infrequent code goes into geom2.c
+*/
+
+#include "qhull_a.h"
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="distplane">-</a>
+
+ qh_distplane( point, facet, dist )
+ return distance from point to facet
+
+ returns:
+ dist
+ if qh.RANDOMdist, joggles result
+
+ notes:
+ dist > 0 if point is above facet (i.e., outside)
+ does not error (for qh_sortfacets, qh_outerinner)
+
+ see:
+ qh_distnorm in geom2.c
+ qh_distplane [geom.c], QhullFacet::distance, and QhullHyperplane::distance are copies
+*/
+void qh_distplane(pointT *point, facetT *facet, realT *dist) {
+ coordT *normal= facet->normal, *coordp, randr;
+ int k;
+
+ switch (qh hull_dim){
+ case 2:
+ *dist= facet->offset + point[0] * normal[0] + point[1] * normal[1];
+ break;
+ case 3:
+ *dist= facet->offset + point[0] * normal[0] + point[1] * normal[1] + point[2] * normal[2];
+ break;
+ case 4:
+ *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3];
+ break;
+ case 5:
+ *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4];
+ break;
+ case 6:
+ *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5];
+ break;
+ case 7:
+ *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6];
+ break;
+ case 8:
+ *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6]+point[7]*normal[7];
+ break;
+ default:
+ *dist= facet->offset;
+ coordp= point;
+ for (k=qh hull_dim; k--; )
+ *dist += *coordp++ * *normal++;
+ break;
+ }
+ zinc_(Zdistplane);
+ if (!qh RANDOMdist && qh IStracing < 4)
+ return;
+ if (qh RANDOMdist) {
+ randr= qh_RANDOMint;
+ *dist += (2.0 * randr / qh_RANDOMmax - 1.0) *
+ qh RANDOMfactor * qh MAXabs_coord;
+ }
+ if (qh IStracing >= 4) {
+ qh_fprintf(qh ferr, 8001, "qh_distplane: ");
+ qh_fprintf(qh ferr, 8002, qh_REAL_1, *dist);
+ qh_fprintf(qh ferr, 8003, "from p%d to f%d\n", qh_pointid(point), facet->id);
+ }
+ return;
+} /* distplane */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="findbest">-</a>
+
+ qh_findbest( point, startfacet, bestoutside, qh_ISnewfacets, qh_NOupper, dist, isoutside, numpart )
+ find facet that is furthest below a point
+ for upperDelaunay facets
+ returns facet only if !qh_NOupper and clearly above
+
+ input:
+ starts search at 'startfacet' (can not be flipped)
+ if !bestoutside(qh_ALL), stops at qh.MINoutside
+
+ returns:
+ best facet (reports error if NULL)
+ early out if isoutside defined and bestdist > qh.MINoutside
+ dist is distance to facet
+ isoutside is true if point is outside of facet
+ numpart counts the number of distance tests
+
+ see also:
+ qh_findbestnew()
+
+ notes:
+ If merging (testhorizon), searches horizon facets of coplanar best facets because
+ after qh_distplane, this and qh_partitionpoint are the most expensive in 3-d
+ avoid calls to distplane, function calls, and real number operations.
+ caller traces result
+ Optimized for outside points. Tried recording a search set for qh_findhorizon.
+ Made code more complicated.
+
+ when called by qh_partitionvisible():
+ indicated by qh_ISnewfacets
+ qh.newfacet_list is list of simplicial, new facets
+ qh_findbestnew set if qh_sharpnewfacets returns True (to use qh_findbestnew)
+ qh.bestfacet_notsharp set if qh_sharpnewfacets returns False
+
+ when called by qh_findfacet(), qh_partitionpoint(), qh_partitioncoplanar(),
+ qh_check_bestdist(), qh_addpoint()
+ indicated by !qh_ISnewfacets
+ returns best facet in neighborhood of given facet
+ this is best facet overall if dist > - qh.MAXcoplanar
+ or hull has at least a "spherical" curvature
+
+ design:
+ initialize and test for early exit
+ repeat while there are better facets
+ for each neighbor of facet
+ exit if outside facet found
+ test for better facet
+ if point is inside and partitioning
+ test for new facets with a "sharp" intersection
+ if so, future calls go to qh_findbestnew()
+ test horizon facets
+*/
+facetT *qh_findbest(pointT *point, facetT *startfacet,
+ boolT bestoutside, boolT isnewfacets, boolT noupper,
+ realT *dist, boolT *isoutside, int *numpart) {
+ realT bestdist= -REALmax/2 /* avoid underflow */;
+ facetT *facet, *neighbor, **neighborp;
+ facetT *bestfacet= NULL, *lastfacet= NULL;
+ int oldtrace= qh IStracing;
+ unsigned int visitid= ++qh visit_id;
+ int numpartnew=0;
+ boolT testhorizon = True; /* needed if precise, e.g., rbox c D6 | qhull Q0 Tv */
+
+ zinc_(Zfindbest);
+ if (qh IStracing >= 3 || (qh TRACElevel && qh TRACEpoint >= 0 && qh TRACEpoint == qh_pointid(point))) {
+ if (qh TRACElevel > qh IStracing)
+ qh IStracing= qh TRACElevel;
+ qh_fprintf(qh ferr, 8004, "qh_findbest: point p%d starting at f%d isnewfacets? %d, unless %d exit if > %2.2g\n",
+ qh_pointid(point), startfacet->id, isnewfacets, bestoutside, qh MINoutside);
+ qh_fprintf(qh ferr, 8005, " testhorizon? %d noupper? %d", testhorizon, noupper);
+ qh_fprintf(qh ferr, 8006, " Last point added was p%d.", qh furthest_id);
+ qh_fprintf(qh ferr, 8007, " Last merge was #%d. max_outside %2.2g\n", zzval_(Ztotmerge), qh max_outside);
+ }
+ if (isoutside)
+ *isoutside= True;
+ if (!startfacet->flipped) { /* test startfacet */
+ *numpart= 1;
+ qh_distplane(point, startfacet, dist); /* this code is duplicated below */
+ if (!bestoutside && *dist >= qh MINoutside
+ && (!startfacet->upperdelaunay || !noupper)) {
+ bestfacet= startfacet;
+ goto LABELreturn_best;
+ }
+ bestdist= *dist;
+ if (!startfacet->upperdelaunay) {
+ bestfacet= startfacet;
+ }
+ }else
+ *numpart= 0;
+ startfacet->visitid= visitid;
+ facet= startfacet;
+ while (facet) {
+ trace4((qh ferr, 4001, "qh_findbest: neighbors of f%d, bestdist %2.2g f%d\n",
+ facet->id, bestdist, getid_(bestfacet)));
+ lastfacet= facet;
+ FOREACHneighbor_(facet) {
+ if (!neighbor->newfacet && isnewfacets)
+ continue;
+ if (neighbor->visitid == visitid)
+ continue;
+ neighbor->visitid= visitid;
+ if (!neighbor->flipped) { /* code duplicated above */
+ (*numpart)++;
+ qh_distplane(point, neighbor, dist);
+ if (*dist > bestdist) {
+ if (!bestoutside && *dist >= qh MINoutside
+ && (!neighbor->upperdelaunay || !noupper)) {
+ bestfacet= neighbor;
+ goto LABELreturn_best;
+ }
+ if (!neighbor->upperdelaunay) {
+ bestfacet= neighbor;
+ bestdist= *dist;
+ break; /* switch to neighbor */
+ }else if (!bestfacet) {
+ bestdist= *dist;
+ break; /* switch to neighbor */
+ }
+ } /* end of *dist>bestdist */
+ } /* end of !flipped */
+ } /* end of FOREACHneighbor */
+ facet= neighbor; /* non-NULL only if *dist>bestdist */
+ } /* end of while facet (directed search) */
+ if (isnewfacets) {
+ if (!bestfacet) {
+ bestdist= -REALmax/2;
+ bestfacet= qh_findbestnew(point, startfacet->next, &bestdist, bestoutside, isoutside, &numpartnew);
+ testhorizon= False; /* qh_findbestnew calls qh_findbesthorizon */
+ }else if (!qh findbest_notsharp && bestdist < - qh DISTround) {
+ if (qh_sharpnewfacets()) {
+ /* seldom used, qh_findbestnew will retest all facets */
+ zinc_(Zfindnewsharp);
+ bestfacet= qh_findbestnew(point, bestfacet, &bestdist, bestoutside, isoutside, &numpartnew);
+ testhorizon= False; /* qh_findbestnew calls qh_findbesthorizon */
+ qh findbestnew= True;
+ }else
+ qh findbest_notsharp= True;
+ }
+ }
+ if (!bestfacet)
+ bestfacet= qh_findbestlower(lastfacet, point, &bestdist, numpart);
+ if (testhorizon)
+ bestfacet= qh_findbesthorizon(!qh_IScheckmax, point, bestfacet, noupper, &bestdist, &numpartnew);
+ *dist= bestdist;
+ if (isoutside && bestdist < qh MINoutside)
+ *isoutside= False;
+LABELreturn_best:
+ zadd_(Zfindbesttot, *numpart);
+ zmax_(Zfindbestmax, *numpart);
+ (*numpart) += numpartnew;
+ qh IStracing= oldtrace;
+ return bestfacet;
+} /* findbest */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="findbesthorizon">-</a>
+
+ qh_findbesthorizon( qh_IScheckmax, point, startfacet, qh_NOupper, &bestdist, &numpart )
+ search coplanar and better horizon facets from startfacet/bestdist
+ ischeckmax turns off statistics and minsearch update
+ all arguments must be initialized
+ returns(ischeckmax):
+ best facet
+ returns(!ischeckmax):
+ best facet that is not upperdelaunay
+ allows upperdelaunay that is clearly outside
+ returns:
+ bestdist is distance to bestfacet
+ numpart -- updates number of distance tests
+
+ notes:
+ no early out -- use qh_findbest() or qh_findbestnew()
+ Searches coplanar or better horizon facets
+
+ when called by qh_check_maxout() (qh_IScheckmax)
+ startfacet must be closest to the point
+ Otherwise, if point is beyond and below startfacet, startfacet may be a local minimum
+ even though other facets are below the point.
+ updates facet->maxoutside for good, visited facets
+ may return NULL
+
+ searchdist is qh.max_outside + 2 * DISTround
+ + max( MINvisible('Vn'), MAXcoplanar('Un'));
+ This setting is a guess. It must be at least max_outside + 2*DISTround
+ because a facet may have a geometric neighbor across a vertex
+
+ design:
+ for each horizon facet of coplanar best facets
+ continue if clearly inside
+ unless upperdelaunay or clearly outside
+ update best facet
+*/
+facetT *qh_findbesthorizon(boolT ischeckmax, pointT* point, facetT *startfacet, boolT noupper, realT *bestdist, int *numpart) {
+ facetT *bestfacet= startfacet;
+ realT dist;
+ facetT *neighbor, **neighborp, *facet;
+ facetT *nextfacet= NULL; /* optimize last facet of coplanarfacetset */
+ int numpartinit= *numpart, coplanarfacetset_size;
+ unsigned int visitid= ++qh visit_id;
+ boolT newbest= False; /* for tracing */
+ realT minsearch, searchdist; /* skip facets that are too far from point */
+
+ if (!ischeckmax) {
+ zinc_(Zfindhorizon);
+ }else {
+#if qh_MAXoutside
+ if ((!qh ONLYgood || startfacet->good) && *bestdist > startfacet->maxoutside)
+ startfacet->maxoutside= *bestdist;
+#endif
+ }
+ searchdist= qh_SEARCHdist; /* multiple of qh.max_outside and precision constants */
+ minsearch= *bestdist - searchdist;
+ if (ischeckmax) {
+ /* Always check coplanar facets. Needed for RBOX 1000 s Z1 G1e-13 t996564279 | QHULL Tv */
+ minimize_(minsearch, -searchdist);
+ }
+ coplanarfacetset_size= 0;
+ facet= startfacet;
+ while (True) {
+ trace4((qh ferr, 4002, "qh_findbesthorizon: neighbors of f%d bestdist %2.2g f%d ischeckmax? %d noupper? %d minsearch %2.2g searchdist %2.2g\n",
+ facet->id, *bestdist, getid_(bestfacet), ischeckmax, noupper,
+ minsearch, searchdist));
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid == visitid)
+ continue;
+ neighbor->visitid= visitid;
+ if (!neighbor->flipped) {
+ qh_distplane(point, neighbor, &dist);
+ (*numpart)++;
+ if (dist > *bestdist) {
+ if (!neighbor->upperdelaunay || ischeckmax || (!noupper && dist >= qh MINoutside)) {
+ bestfacet= neighbor;
+ *bestdist= dist;
+ newbest= True;
+ if (!ischeckmax) {
+ minsearch= dist - searchdist;
+ if (dist > *bestdist + searchdist) {
+ zinc_(Zfindjump); /* everything in qh.coplanarfacetset at least searchdist below */
+ coplanarfacetset_size= 0;
+ }
+ }
+ }
+ }else if (dist < minsearch)
+ continue; /* if ischeckmax, dist can't be positive */
+#if qh_MAXoutside
+ if (ischeckmax && dist > neighbor->maxoutside)
+ neighbor->maxoutside= dist;
+#endif
+ } /* end of !flipped */
+ if (nextfacet) {
+ if (!coplanarfacetset_size++) {
+ SETfirst_(qh coplanarfacetset)= nextfacet;
+ SETtruncate_(qh coplanarfacetset, 1);
+ }else
+ qh_setappend(&qh coplanarfacetset, nextfacet); /* Was needed for RBOX 1000 s W1e-13 P0 t996547055 | QHULL d Qbb Qc Tv
+ and RBOX 1000 s Z1 G1e-13 t996564279 | qhull Tv */
+ }
+ nextfacet= neighbor;
+ } /* end of EACHneighbor */
+ facet= nextfacet;
+ if (facet)
+ nextfacet= NULL;
+ else if (!coplanarfacetset_size)
+ break;
+ else if (!--coplanarfacetset_size) {
+ facet= SETfirstt_(qh coplanarfacetset, facetT);
+ SETtruncate_(qh coplanarfacetset, 0);
+ }else
+ facet= (facetT*)qh_setdellast(qh coplanarfacetset);
+ } /* while True, for each facet in qh.coplanarfacetset */
+ if (!ischeckmax) {
+ zadd_(Zfindhorizontot, *numpart - numpartinit);
+ zmax_(Zfindhorizonmax, *numpart - numpartinit);
+ if (newbest)
+ zinc_(Zparthorizon);
+ }
+ trace4((qh ferr, 4003, "qh_findbesthorizon: newbest? %d bestfacet f%d bestdist %2.2g\n", newbest, getid_(bestfacet), *bestdist));
+ return bestfacet;
+} /* findbesthorizon */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="findbestnew">-</a>
+
+ qh_findbestnew( point, startfacet, dist, isoutside, numpart )
+ find best newfacet for point
+ searches all of qh.newfacet_list starting at startfacet
+ searches horizon facets of coplanar best newfacets
+ searches all facets if startfacet == qh.facet_list
+ returns:
+ best new or horizon facet that is not upperdelaunay
+ early out if isoutside and not 'Qf'
+ dist is distance to facet
+ isoutside is true if point is outside of facet
+ numpart is number of distance tests
+
+ notes:
+ Always used for merged new facets (see qh_USEfindbestnew)
+ Avoids upperdelaunay facet unless (isoutside and outside)
+
+ Uses qh.visit_id, qh.coplanarfacetset.
+ If share visit_id with qh_findbest, coplanarfacetset is incorrect.
+
+ If merging (testhorizon), searches horizon facets of coplanar best facets because
+ a point maybe coplanar to the bestfacet, below its horizon facet,
+ and above a horizon facet of a coplanar newfacet. For example,
+ rbox 1000 s Z1 G1e-13 | qhull
+ rbox 1000 s W1e-13 P0 t992110337 | QHULL d Qbb Qc
+
+ qh_findbestnew() used if
+ qh_sharpnewfacets -- newfacets contains a sharp angle
+ if many merges, qh_premerge found a merge, or 'Qf' (qh.findbestnew)
+
+ see also:
+ qh_partitionall() and qh_findbest()
+
+ design:
+ for each new facet starting from startfacet
+ test distance from point to facet
+ return facet if clearly outside
+ unless upperdelaunay and a lowerdelaunay exists
+ update best facet
+ test horizon facets
+*/
+facetT *qh_findbestnew(pointT *point, facetT *startfacet,
+ realT *dist, boolT bestoutside, boolT *isoutside, int *numpart) {
+ realT bestdist= -REALmax/2;
+ facetT *bestfacet= NULL, *facet;
+ int oldtrace= qh IStracing, i;
+ unsigned int visitid= ++qh visit_id;
+ realT distoutside= 0.0;
+ boolT isdistoutside; /* True if distoutside is defined */
+ boolT testhorizon = True; /* needed if precise, e.g., rbox c D6 | qhull Q0 Tv */
+
+ if (!startfacet) {
+ if (qh MERGING)
+ qh_fprintf(qh ferr, 6001, "qhull precision error (qh_findbestnew): merging has formed and deleted a cone of new facets. Can not continue.\n");
+ else
+ qh_fprintf(qh ferr, 6002, "qhull internal error (qh_findbestnew): no new facets for point p%d\n",
+ qh furthest_id);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ zinc_(Zfindnew);
+ if (qh BESToutside || bestoutside)
+ isdistoutside= False;
+ else {
+ isdistoutside= True;
+ distoutside= qh_DISToutside; /* multiple of qh.MINoutside & qh.max_outside, see user.h */
+ }
+ if (isoutside)
+ *isoutside= True;
+ *numpart= 0;
+ if (qh IStracing >= 3 || (qh TRACElevel && qh TRACEpoint >= 0 && qh TRACEpoint == qh_pointid(point))) {
+ if (qh TRACElevel > qh IStracing)
+ qh IStracing= qh TRACElevel;
+ qh_fprintf(qh ferr, 8008, "qh_findbestnew: point p%d facet f%d. Stop? %d if dist > %2.2g\n",
+ qh_pointid(point), startfacet->id, isdistoutside, distoutside);
+ qh_fprintf(qh ferr, 8009, " Last point added p%d visitid %d.", qh furthest_id, visitid);
+ qh_fprintf(qh ferr, 8010, " Last merge was #%d.\n", zzval_(Ztotmerge));
+ }
+ /* visit all new facets starting with startfacet, maybe qh facet_list */
+ for (i=0, facet=startfacet; i < 2; i++, facet= qh newfacet_list) {
+ FORALLfacet_(facet) {
+ if (facet == startfacet && i)
+ break;
+ facet->visitid= visitid;
+ if (!facet->flipped) {
+ qh_distplane(point, facet, dist);
+ (*numpart)++;
+ if (*dist > bestdist) {
+ if (!facet->upperdelaunay || *dist >= qh MINoutside) {
+ bestfacet= facet;
+ if (isdistoutside && *dist >= distoutside)
+ goto LABELreturn_bestnew;
+ bestdist= *dist;
+ }
+ }
+ } /* end of !flipped */
+ } /* FORALLfacet from startfacet or qh newfacet_list */
+ }
+ if (testhorizon || !bestfacet) /* testhorizon is always True. Keep the same code as qh_findbest */
+ bestfacet= qh_findbesthorizon(!qh_IScheckmax, point, bestfacet ? bestfacet : startfacet,
+ !qh_NOupper, &bestdist, numpart);
+ *dist= bestdist;
+ if (isoutside && *dist < qh MINoutside)
+ *isoutside= False;
+LABELreturn_bestnew:
+ zadd_(Zfindnewtot, *numpart);
+ zmax_(Zfindnewmax, *numpart);
+ trace4((qh ferr, 4004, "qh_findbestnew: bestfacet f%d bestdist %2.2g\n", getid_(bestfacet), *dist));
+ qh IStracing= oldtrace;
+ return bestfacet;
+} /* findbestnew */
+
+/* ============ hyperplane functions -- keep code together [?] ============ */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="backnormal">-</a>
+
+ qh_backnormal( rows, numrow, numcol, sign, normal, nearzero )
+ given an upper-triangular rows array and a sign,
+ solve for normal equation x using back substitution over rows U
+
+ returns:
+ normal= x
+
+ if will not be able to divzero() when normalized(qh.MINdenom_2 and qh.MINdenom_1_2),
+ if fails on last row
+ this means that the hyperplane intersects [0,..,1]
+ sets last coordinate of normal to sign
+ otherwise
+ sets tail of normal to [...,sign,0,...], i.e., solves for b= [0...0]
+ sets nearzero
+
+ notes:
+ assumes numrow == numcol-1
+
+ see Golub & van Loan, 1983, Eq. 4.4-9 for "Gaussian elimination with complete pivoting"
+
+ solves Ux=b where Ax=b and PA=LU
+ b= [0,...,0,sign or 0] (sign is either -1 or +1)
+ last row of A= [0,...,0,1]
+
+ 1) Ly=Pb == y=b since P only permutes the 0's of b
+
+ design:
+ for each row from end
+ perform back substitution
+ if near zero
+ use qh_divzero for division
+ if zero divide and not last row
+ set tail of normal to 0
+*/
+void qh_backnormal(realT **rows, int numrow, int numcol, boolT sign,
+ coordT *normal, boolT *nearzero) {
+ int i, j;
+ coordT *normalp, *normal_tail, *ai, *ak;
+ realT diagonal;
+ boolT waszero;
+ int zerocol= -1;
+
+ normalp= normal + numcol - 1;
+ *normalp--= (sign ? -1.0 : 1.0);
+ for (i=numrow; i--; ) {
+ *normalp= 0.0;
+ ai= rows[i] + i + 1;
+ ak= normalp+1;
+ for (j=i+1; j < numcol; j++)
+ *normalp -= *ai++ * *ak++;
+ diagonal= (rows[i])[i];
+ if (fabs_(diagonal) > qh MINdenom_2)
+ *(normalp--) /= diagonal;
+ else {
+ waszero= False;
+ *normalp= qh_divzero(*normalp, diagonal, qh MINdenom_1_2, &waszero);
+ if (waszero) {
+ zerocol= i;
+ *(normalp--)= (sign ? -1.0 : 1.0);
+ for (normal_tail= normalp+2; normal_tail < normal + numcol; normal_tail++)
+ *normal_tail= 0.0;
+ }else
+ normalp--;
+ }
+ }
+ if (zerocol != -1) {
+ zzinc_(Zback0);
+ *nearzero= True;
+ trace4((qh ferr, 4005, "qh_backnormal: zero diagonal at column %d.\n", i));
+ qh_precision("zero diagonal on back substitution");
+ }
+} /* backnormal */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="gausselim">-</a>
+
+ qh_gausselim( rows, numrow, numcol, sign )
+ Gaussian elimination with partial pivoting
+
+ returns:
+ rows is upper triangular (includes row exchanges)
+ flips sign for each row exchange
+ sets nearzero if pivot[k] < qh.NEARzero[k], else clears it
+
+ notes:
+ if nearzero, the determinant's sign may be incorrect.
+ assumes numrow <= numcol
+
+ design:
+ for each row
+ determine pivot and exchange rows if necessary
+ test for near zero
+ perform gaussian elimination step
+*/
+void qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero) {
+ realT *ai, *ak, *rowp, *pivotrow;
+ realT n, pivot, pivot_abs= 0.0, temp;
+ int i, j, k, pivoti, flip=0;
+
+ *nearzero= False;
+ for (k=0; k < numrow; k++) {
+ pivot_abs= fabs_((rows[k])[k]);
+ pivoti= k;
+ for (i=k+1; i < numrow; i++) {
+ if ((temp= fabs_((rows[i])[k])) > pivot_abs) {
+ pivot_abs= temp;
+ pivoti= i;
+ }
+ }
+ if (pivoti != k) {
+ rowp= rows[pivoti];
+ rows[pivoti]= rows[k];
+ rows[k]= rowp;
+ *sign ^= 1;
+ flip ^= 1;
+ }
+ if (pivot_abs <= qh NEARzero[k]) {
+ *nearzero= True;
+ if (pivot_abs == 0.0) { /* remainder of column == 0 */
+ if (qh IStracing >= 4) {
+ qh_fprintf(qh ferr, 8011, "qh_gausselim: 0 pivot at column %d. (%2.2g < %2.2g)\n", k, pivot_abs, qh DISTround);
+ qh_printmatrix(qh ferr, "Matrix:", rows, numrow, numcol);
+ }
+ zzinc_(Zgauss0);
+ qh_precision("zero pivot for Gaussian elimination");
+ goto LABELnextcol;
+ }
+ }
+ pivotrow= rows[k] + k;
+ pivot= *pivotrow++; /* signed value of pivot, and remainder of row */
+ for (i=k+1; i < numrow; i++) {
+ ai= rows[i] + k;
+ ak= pivotrow;
+ n= (*ai++)/pivot; /* divzero() not needed since |pivot| >= |*ai| */
+ for (j= numcol - (k+1); j--; )
+ *ai++ -= n * *ak++;
+ }
+ LABELnextcol:
+ ;
+ }
+ wmin_(Wmindenom, pivot_abs); /* last pivot element */
+ if (qh IStracing >= 5)
+ qh_printmatrix(qh ferr, "qh_gausselem: result", rows, numrow, numcol);
+} /* gausselim */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="getangle">-</a>
+
+ qh_getangle( vect1, vect2 )
+ returns the dot product of two vectors
+ if qh.RANDOMdist, joggles result
+
+ notes:
+ the angle may be > 1.0 or < -1.0 because of roundoff errors
+
+*/
+realT qh_getangle(pointT *vect1, pointT *vect2) {
+ realT angle= 0, randr;
+ int k;
+
+ for (k=qh hull_dim; k--; )
+ angle += *vect1++ * *vect2++;
+ if (qh RANDOMdist) {
+ randr= qh_RANDOMint;
+ angle += (2.0 * randr / qh_RANDOMmax - 1.0) *
+ qh RANDOMfactor;
+ }
+ trace4((qh ferr, 4006, "qh_getangle: %2.2g\n", angle));
+ return(angle);
+} /* getangle */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="getcenter">-</a>
+
+ qh_getcenter( vertices )
+ returns arithmetic center of a set of vertices as a new point
+
+ notes:
+ allocates point array for center
+*/
+pointT *qh_getcenter(setT *vertices) {
+ int k;
+ pointT *center, *coord;
+ vertexT *vertex, **vertexp;
+ int count= qh_setsize(vertices);
+
+ if (count < 2) {
+ qh_fprintf(qh ferr, 6003, "qhull internal error (qh_getcenter): not defined for %d points\n", count);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ center= (pointT *)qh_memalloc(qh normal_size);
+ for (k=0; k < qh hull_dim; k++) {
+ coord= center+k;
+ *coord= 0.0;
+ FOREACHvertex_(vertices)
+ *coord += vertex->point[k];
+ *coord /= count; /* count>=2 by QH6003 */
+ }
+ return(center);
+} /* getcenter */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="getcentrum">-</a>
+
+ qh_getcentrum( facet )
+ returns the centrum for a facet as a new point
+
+ notes:
+ allocates the centrum
+*/
+pointT *qh_getcentrum(facetT *facet) {
+ realT dist;
+ pointT *centrum, *point;
+
+ point= qh_getcenter(facet->vertices);
+ zzinc_(Zcentrumtests);
+ qh_distplane(point, facet, &dist);
+ centrum= qh_projectpoint(point, facet, dist);
+ qh_memfree(point, qh normal_size);
+ trace4((qh ferr, 4007, "qh_getcentrum: for f%d, %d vertices dist= %2.2g\n",
+ facet->id, qh_setsize(facet->vertices), dist));
+ return centrum;
+} /* getcentrum */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="getdistance">-</a>
+
+ qh_getdistance( facet, neighbor, mindist, maxdist )
+ returns the maxdist and mindist distance of any vertex from neighbor
+
+ returns:
+ the max absolute value
+
+ design:
+ for each vertex of facet that is not in neighbor
+ test the distance from vertex to neighbor
+*/
+realT qh_getdistance(facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist) {
+ vertexT *vertex, **vertexp;
+ realT dist, maxd, mind;
+
+ FOREACHvertex_(facet->vertices)
+ vertex->seen= False;
+ FOREACHvertex_(neighbor->vertices)
+ vertex->seen= True;
+ mind= 0.0;
+ maxd= 0.0;
+ FOREACHvertex_(facet->vertices) {
+ if (!vertex->seen) {
+ zzinc_(Zbestdist);
+ qh_distplane(vertex->point, neighbor, &dist);
+ if (dist < mind)
+ mind= dist;
+ else if (dist > maxd)
+ maxd= dist;
+ }
+ }
+ *mindist= mind;
+ *maxdist= maxd;
+ mind= -mind;
+ if (maxd > mind)
+ return maxd;
+ else
+ return mind;
+} /* getdistance */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="normalize">-</a>
+
+ qh_normalize( normal, dim, toporient )
+ normalize a vector and report if too small
+ does not use min norm
+
+ see:
+ qh_normalize2
+*/
+void qh_normalize(coordT *normal, int dim, boolT toporient) {
+ qh_normalize2( normal, dim, toporient, NULL, NULL);
+} /* normalize */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="normalize2">-</a>
+
+ qh_normalize2( normal, dim, toporient, minnorm, ismin )
+ normalize a vector and report if too small
+ qh.MINdenom/MINdenom1 are the upper limits for divide overflow
+
+ returns:
+ normalized vector
+ flips sign if !toporient
+ if minnorm non-NULL,
+ sets ismin if normal < minnorm
+
+ notes:
+ if zero norm
+ sets all elements to sqrt(1.0/dim)
+ if divide by zero (divzero())
+ sets largest element to +/-1
+ bumps Znearlysingular
+
+ design:
+ computes norm
+ test for minnorm
+ if not near zero
+ normalizes normal
+ else if zero norm
+ sets normal to standard value
+ else
+ uses qh_divzero to normalize
+ if nearzero
+ sets norm to direction of maximum value
+*/
+void qh_normalize2(coordT *normal, int dim, boolT toporient,
+ realT *minnorm, boolT *ismin) {
+ int k;
+ realT *colp, *maxp, norm= 0, temp, *norm1, *norm2, *norm3;
+ boolT zerodiv;
+
+ norm1= normal+1;
+ norm2= normal+2;
+ norm3= normal+3;
+ if (dim == 2)
+ norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1));
+ else if (dim == 3)
+ norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2));
+ else if (dim == 4) {
+ norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2)
+ + (*norm3)*(*norm3));
+ }else if (dim > 4) {
+ norm= (*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2)
+ + (*norm3)*(*norm3);
+ for (k=dim-4, colp=normal+4; k--; colp++)
+ norm += (*colp) * (*colp);
+ norm= sqrt(norm);
+ }
+ if (minnorm) {
+ if (norm < *minnorm)
+ *ismin= True;
+ else
+ *ismin= False;
+ }
+ wmin_(Wmindenom, norm);
+ if (norm > qh MINdenom) {
+ if (!toporient)
+ norm= -norm;
+ *normal /= norm;
+ *norm1 /= norm;
+ if (dim == 2)
+ ; /* all done */
+ else if (dim == 3)
+ *norm2 /= norm;
+ else if (dim == 4) {
+ *norm2 /= norm;
+ *norm3 /= norm;
+ }else if (dim >4) {
+ *norm2 /= norm;
+ *norm3 /= norm;
+ for (k=dim-4, colp=normal+4; k--; )
+ *colp++ /= norm;
+ }
+ }else if (norm == 0.0) {
+ temp= sqrt(1.0/dim);
+ for (k=dim, colp=normal; k--; )
+ *colp++ = temp;
+ }else {
+ if (!toporient)
+ norm= -norm;
+ for (k=dim, colp=normal; k--; colp++) { /* k used below */
+ temp= qh_divzero(*colp, norm, qh MINdenom_1, &zerodiv);
+ if (!zerodiv)
+ *colp= temp;
+ else {
+ maxp= qh_maxabsval(normal, dim);
+ temp= ((*maxp * norm >= 0.0) ? 1.0 : -1.0);
+ for (k=dim, colp=normal; k--; colp++)
+ *colp= 0.0;
+ *maxp= temp;
+ zzinc_(Znearlysingular);
+ trace0((qh ferr, 1, "qh_normalize: norm=%2.2g too small during p%d\n",
+ norm, qh furthest_id));
+ return;
+ }
+ }
+ }
+} /* normalize */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="projectpoint">-</a>
+
+ qh_projectpoint( point, facet, dist )
+ project point onto a facet by dist
+
+ returns:
+ returns a new point
+
+ notes:
+ if dist= distplane(point,facet)
+ this projects point to hyperplane
+ assumes qh_memfree_() is valid for normal_size
+*/
+pointT *qh_projectpoint(pointT *point, facetT *facet, realT dist) {
+ pointT *newpoint, *np, *normal;
+ int normsize= qh normal_size;
+ int k;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+
+ qh_memalloc_(normsize, freelistp, newpoint, pointT);
+ np= newpoint;
+ normal= facet->normal;
+ for (k=qh hull_dim; k--; )
+ *(np++)= *point++ - dist * *normal++;
+ return(newpoint);
+} /* projectpoint */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="setfacetplane">-</a>
+
+ qh_setfacetplane( facet )
+ sets the hyperplane for a facet
+ if qh.RANDOMdist, joggles hyperplane
+
+ notes:
+ uses global buffers qh.gm_matrix and qh.gm_row
+ overwrites facet->normal if already defined
+ updates Wnewvertex if PRINTstatistics
+ sets facet->upperdelaunay if upper envelope of Delaunay triangulation
+
+ design:
+ copy vertex coordinates to qh.gm_matrix/gm_row
+ compute determinate
+ if nearzero
+ recompute determinate with gaussian elimination
+ if nearzero
+ force outside orientation by testing interior point
+*/
+void qh_setfacetplane(facetT *facet) {
+ pointT *point;
+ vertexT *vertex, **vertexp;
+ int normsize= qh normal_size;
+ int k,i, oldtrace= 0;
+ realT dist;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+ coordT *coord, *gmcoord;
+ pointT *point0= SETfirstt_(facet->vertices, vertexT)->point;
+ boolT nearzero= False;
+
+ zzinc_(Zsetplane);
+ if (!facet->normal)
+ qh_memalloc_(normsize, freelistp, facet->normal, coordT);
+ if (facet == qh tracefacet) {
+ oldtrace= qh IStracing;
+ qh IStracing= 5;
+ qh_fprintf(qh ferr, 8012, "qh_setfacetplane: facet f%d created.\n", facet->id);
+ qh_fprintf(qh ferr, 8013, " Last point added to hull was p%d.", qh furthest_id);
+ if (zzval_(Ztotmerge))
+ qh_fprintf(qh ferr, 8014, " Last merge was #%d.", zzval_(Ztotmerge));
+ qh_fprintf(qh ferr, 8015, "\n\nCurrent summary is:\n");
+ qh_printsummary(qh ferr);
+ }
+ if (qh hull_dim <= 4) {
+ i= 0;
+ if (qh RANDOMdist) {
+ gmcoord= qh gm_matrix;
+ FOREACHvertex_(facet->vertices) {
+ qh gm_row[i++]= gmcoord;
+ coord= vertex->point;
+ for (k=qh hull_dim; k--; )
+ *(gmcoord++)= *coord++ * qh_randomfactor(qh RANDOMa, qh RANDOMb);
+ }
+ }else {
+ FOREACHvertex_(facet->vertices)
+ qh gm_row[i++]= vertex->point;
+ }
+ qh_sethyperplane_det(qh hull_dim, qh gm_row, point0, facet->toporient,
+ facet->normal, &facet->offset, &nearzero);
+ }
+ if (qh hull_dim > 4 || nearzero) {
+ i= 0;
+ gmcoord= qh gm_matrix;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->point != point0) {
+ qh gm_row[i++]= gmcoord;
+ coord= vertex->point;
+ point= point0;
+ for (k=qh hull_dim; k--; )
+ *(gmcoord++)= *coord++ - *point++;
+ }
+ }
+ qh gm_row[i]= gmcoord; /* for areasimplex */
+ if (qh RANDOMdist) {
+ gmcoord= qh gm_matrix;
+ for (i=qh hull_dim-1; i--; ) {
+ for (k=qh hull_dim; k--; )
+ *(gmcoord++) *= qh_randomfactor(qh RANDOMa, qh RANDOMb);
+ }
+ }
+ qh_sethyperplane_gauss(qh hull_dim, qh gm_row, point0, facet->toporient,
+ facet->normal, &facet->offset, &nearzero);
+ if (nearzero) {
+ if (qh_orientoutside(facet)) {
+ trace0((qh ferr, 2, "qh_setfacetplane: flipped orientation after testing interior_point during p%d\n", qh furthest_id));
+ /* this is part of using Gaussian Elimination. For example in 5-d
+ 1 1 1 1 0
+ 1 1 1 1 1
+ 0 0 0 1 0
+ 0 1 0 0 0
+ 1 0 0 0 0
+ norm= 0.38 0.38 -0.76 0.38 0
+ has a determinate of 1, but g.e. after subtracting pt. 0 has
+ 0's in the diagonal, even with full pivoting. It does work
+ if you subtract pt. 4 instead. */
+ }
+ }
+ }
+ facet->upperdelaunay= False;
+ if (qh DELAUNAY) {
+ if (qh UPPERdelaunay) { /* matches qh_triangulate_facet and qh.lower_threshold in qh_initbuild */
+ if (facet->normal[qh hull_dim -1] >= qh ANGLEround * qh_ZEROdelaunay)
+ facet->upperdelaunay= True;
+ }else {
+ if (facet->normal[qh hull_dim -1] > -qh ANGLEround * qh_ZEROdelaunay)
+ facet->upperdelaunay= True;
+ }
+ }
+ if (qh PRINTstatistics || qh IStracing || qh TRACElevel || qh JOGGLEmax < REALmax) {
+ qh old_randomdist= qh RANDOMdist;
+ qh RANDOMdist= False;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->point != point0) {
+ boolT istrace= False;
+ zinc_(Zdiststat);
+ qh_distplane(vertex->point, facet, &dist);
+ dist= fabs_(dist);
+ zinc_(Znewvertex);
+ wadd_(Wnewvertex, dist);
+ if (dist > wwval_(Wnewvertexmax)) {
+ wwval_(Wnewvertexmax)= dist;
+ if (dist > qh max_outside) {
+ qh max_outside= dist; /* used by qh_maxouter() */
+ if (dist > qh TRACEdist)
+ istrace= True;
+ }
+ }else if (-dist > qh TRACEdist)
+ istrace= True;
+ if (istrace) {
+ qh_fprintf(qh ferr, 8016, "qh_setfacetplane: ====== vertex p%d(v%d) increases max_outside to %2.2g for new facet f%d last p%d\n",
+ qh_pointid(vertex->point), vertex->id, dist, facet->id, qh furthest_id);
+ qh_errprint("DISTANT", facet, NULL, NULL, NULL);
+ }
+ }
+ }
+ qh RANDOMdist= qh old_randomdist;
+ }
+ if (qh IStracing >= 3) {
+ qh_fprintf(qh ferr, 8017, "qh_setfacetplane: f%d offset %2.2g normal: ",
+ facet->id, facet->offset);
+ for (k=0; k < qh hull_dim; k++)
+ qh_fprintf(qh ferr, 8018, "%2.2g ", facet->normal[k]);
+ qh_fprintf(qh ferr, 8019, "\n");
+ }
+ if (facet == qh tracefacet)
+ qh IStracing= oldtrace;
+} /* setfacetplane */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="sethyperplane_det">-</a>
+
+ qh_sethyperplane_det( dim, rows, point0, toporient, normal, offset, nearzero )
+ given dim X dim array indexed by rows[], one row per point,
+ toporient(flips all signs),
+ and point0 (any row)
+ set normalized hyperplane equation from oriented simplex
+
+ returns:
+ normal (normalized)
+ offset (places point0 on the hyperplane)
+ sets nearzero if hyperplane not through points
+
+ notes:
+ only defined for dim == 2..4
+ rows[] is not modified
+ solves det(P-V_0, V_n-V_0, ..., V_1-V_0)=0, i.e. every point is on hyperplane
+ see Bower & Woodworth, A programmer's geometry, Butterworths 1983.
+
+ derivation of 3-d minnorm
+ Goal: all vertices V_i within qh.one_merge of hyperplane
+ Plan: exactly translate the facet so that V_0 is the origin
+ exactly rotate the facet so that V_1 is on the x-axis and y_2=0.
+ exactly rotate the effective perturbation to only effect n_0
+ this introduces a factor of sqrt(3)
+ n_0 = ((y_2-y_0)*(z_1-z_0) - (z_2-z_0)*(y_1-y_0)) / norm
+ Let M_d be the max coordinate difference
+ Let M_a be the greater of M_d and the max abs. coordinate
+ Let u be machine roundoff and distround be max error for distance computation
+ The max error for n_0 is sqrt(3) u M_a M_d / norm. n_1 is approx. 1 and n_2 is approx. 0
+ The max error for distance of V_1 is sqrt(3) u M_a M_d M_d / norm. Offset=0 at origin
+ Then minnorm = 1.8 u M_a M_d M_d / qh.ONEmerge
+ Note that qh.one_merge is approx. 45.5 u M_a and norm is usually about M_d M_d
+
+ derivation of 4-d minnorm
+ same as above except rotate the facet so that V_1 on x-axis and w_2, y_3, w_3=0
+ [if two vertices fixed on x-axis, can rotate the other two in yzw.]
+ n_0 = det3_(...) = y_2 det2_(z_1, w_1, z_3, w_3) = - y_2 w_1 z_3
+ [all other terms contain at least two factors nearly zero.]
+ The max error for n_0 is sqrt(4) u M_a M_d M_d / norm
+ Then minnorm = 2 u M_a M_d M_d M_d / qh.ONEmerge
+ Note that qh.one_merge is approx. 82 u M_a and norm is usually about M_d M_d M_d
+*/
+void qh_sethyperplane_det(int dim, coordT **rows, coordT *point0,
+ boolT toporient, coordT *normal, realT *offset, boolT *nearzero) {
+ realT maxround, dist;
+ int i;
+ pointT *point;
+
+
+ if (dim == 2) {
+ normal[0]= dY(1,0);
+ normal[1]= dX(0,1);
+ qh_normalize2(normal, dim, toporient, NULL, NULL);
+ *offset= -(point0[0]*normal[0]+point0[1]*normal[1]);
+ *nearzero= False; /* since nearzero norm => incident points */
+ }else if (dim == 3) {
+ normal[0]= det2_(dY(2,0), dZ(2,0),
+ dY(1,0), dZ(1,0));
+ normal[1]= det2_(dX(1,0), dZ(1,0),
+ dX(2,0), dZ(2,0));
+ normal[2]= det2_(dX(2,0), dY(2,0),
+ dX(1,0), dY(1,0));
+ qh_normalize2(normal, dim, toporient, NULL, NULL);
+ *offset= -(point0[0]*normal[0] + point0[1]*normal[1]
+ + point0[2]*normal[2]);
+ maxround= qh DISTround;
+ for (i=dim; i--; ) {
+ point= rows[i];
+ if (point != point0) {
+ dist= *offset + (point[0]*normal[0] + point[1]*normal[1]
+ + point[2]*normal[2]);
+ if (dist > maxround || dist < -maxround) {
+ *nearzero= True;
+ break;
+ }
+ }
+ }
+ }else if (dim == 4) {
+ normal[0]= - det3_(dY(2,0), dZ(2,0), dW(2,0),
+ dY(1,0), dZ(1,0), dW(1,0),
+ dY(3,0), dZ(3,0), dW(3,0));
+ normal[1]= det3_(dX(2,0), dZ(2,0), dW(2,0),
+ dX(1,0), dZ(1,0), dW(1,0),
+ dX(3,0), dZ(3,0), dW(3,0));
+ normal[2]= - det3_(dX(2,0), dY(2,0), dW(2,0),
+ dX(1,0), dY(1,0), dW(1,0),
+ dX(3,0), dY(3,0), dW(3,0));
+ normal[3]= det3_(dX(2,0), dY(2,0), dZ(2,0),
+ dX(1,0), dY(1,0), dZ(1,0),
+ dX(3,0), dY(3,0), dZ(3,0));
+ qh_normalize2(normal, dim, toporient, NULL, NULL);
+ *offset= -(point0[0]*normal[0] + point0[1]*normal[1]
+ + point0[2]*normal[2] + point0[3]*normal[3]);
+ maxround= qh DISTround;
+ for (i=dim; i--; ) {
+ point= rows[i];
+ if (point != point0) {
+ dist= *offset + (point[0]*normal[0] + point[1]*normal[1]
+ + point[2]*normal[2] + point[3]*normal[3]);
+ if (dist > maxround || dist < -maxround) {
+ *nearzero= True;
+ break;
+ }
+ }
+ }
+ }
+ if (*nearzero) {
+ zzinc_(Zminnorm);
+ trace0((qh ferr, 3, "qh_sethyperplane_det: degenerate norm during p%d.\n", qh furthest_id));
+ zzinc_(Znearlysingular);
+ }
+} /* sethyperplane_det */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="sethyperplane_gauss">-</a>
+
+ qh_sethyperplane_gauss( dim, rows, point0, toporient, normal, offset, nearzero )
+ given(dim-1) X dim array of rows[i]= V_{i+1} - V_0 (point0)
+ set normalized hyperplane equation from oriented simplex
+
+ returns:
+ normal (normalized)
+ offset (places point0 on the hyperplane)
+
+ notes:
+ if nearzero
+ orientation may be incorrect because of incorrect sign flips in gausselim
+ solves [V_n-V_0,...,V_1-V_0, 0 .. 0 1] * N == [0 .. 0 1]
+ or [V_n-V_0,...,V_1-V_0, 0 .. 0 1] * N == [0]
+ i.e., N is normal to the hyperplane, and the unnormalized
+ distance to [0 .. 1] is either 1 or 0
+
+ design:
+ perform gaussian elimination
+ flip sign for negative values
+ perform back substitution
+ normalize result
+ compute offset
+*/
+void qh_sethyperplane_gauss(int dim, coordT **rows, pointT *point0,
+ boolT toporient, coordT *normal, coordT *offset, boolT *nearzero) {
+ coordT *pointcoord, *normalcoef;
+ int k;
+ boolT sign= toporient, nearzero2= False;
+
+ qh_gausselim(rows, dim-1, dim, &sign, nearzero);
+ for (k=dim-1; k--; ) {
+ if ((rows[k])[k] < 0)
+ sign ^= 1;
+ }
+ if (*nearzero) {
+ zzinc_(Znearlysingular);
+ trace0((qh ferr, 4, "qh_sethyperplane_gauss: nearly singular or axis parallel hyperplane during p%d.\n", qh furthest_id));
+ qh_backnormal(rows, dim-1, dim, sign, normal, &nearzero2);
+ }else {
+ qh_backnormal(rows, dim-1, dim, sign, normal, &nearzero2);
+ if (nearzero2) {
+ zzinc_(Znearlysingular);
+ trace0((qh ferr, 5, "qh_sethyperplane_gauss: singular or axis parallel hyperplane at normalization during p%d.\n", qh furthest_id));
+ }
+ }
+ if (nearzero2)
+ *nearzero= True;
+ qh_normalize2(normal, dim, True, NULL, NULL);
+ pointcoord= point0;
+ normalcoef= normal;
+ *offset= -(*pointcoord++ * *normalcoef++);
+ for (k=dim-1; k--; )
+ *offset -= *pointcoord++ * *normalcoef++;
+} /* sethyperplane_gauss */
+
+
+
diff --git a/xs/src/qhull/src/libqhull/geom.h b/xs/src/qhull/src/libqhull/geom.h
new file mode 100644
index 000000000..16ef48d2d
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/geom.h
@@ -0,0 +1,176 @@
+/*<html><pre> -<a href="qh-geom.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ geom.h
+ header file for geometric routines
+
+ see qh-geom.htm and geom.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/geom.h#1 $$Change: 1981 $
+ $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
+*/
+
+#ifndef qhDEFgeom
+#define qhDEFgeom 1
+
+#include "libqhull.h"
+
+/* ============ -macros- ======================== */
+
+/*-<a href="qh-geom.htm#TOC"
+ >--------------------------------</a><a name="fabs_">-</a>
+
+ fabs_(a)
+ returns the absolute value of a
+*/
+#define fabs_( a ) ((( a ) < 0 ) ? -( a ):( a ))
+
+/*-<a href="qh-geom.htm#TOC"
+ >--------------------------------</a><a name="fmax_">-</a>
+
+ fmax_(a,b)
+ returns the maximum value of a and b
+*/
+#define fmax_( a,b ) ( ( a ) < ( b ) ? ( b ) : ( a ) )
+
+/*-<a href="qh-geom.htm#TOC"
+ >--------------------------------</a><a name="fmin_">-</a>
+
+ fmin_(a,b)
+ returns the minimum value of a and b
+*/
+#define fmin_( a,b ) ( ( a ) > ( b ) ? ( b ) : ( a ) )
+
+/*-<a href="qh-geom.htm#TOC"
+ >--------------------------------</a><a name="maximize_">-</a>
+
+ maximize_(maxval, val)
+ set maxval to val if val is greater than maxval
+*/
+#define maximize_( maxval, val ) { if (( maxval ) < ( val )) ( maxval )= ( val ); }
+
+/*-<a href="qh-geom.htm#TOC"
+ >--------------------------------</a><a name="minimize_">-</a>
+
+ minimize_(minval, val)
+ set minval to val if val is less than minval
+*/
+#define minimize_( minval, val ) { if (( minval ) > ( val )) ( minval )= ( val ); }
+
+/*-<a href="qh-geom.htm#TOC"
+ >--------------------------------</a><a name="det2_">-</a>
+
+ det2_(a1, a2,
+ b1, b2)
+
+ compute a 2-d determinate
+*/
+#define det2_( a1,a2,b1,b2 ) (( a1 )*( b2 ) - ( a2 )*( b1 ))
+
+/*-<a href="qh-geom.htm#TOC"
+ >--------------------------------</a><a name="det3_">-</a>
+
+ det3_(a1, a2, a3,
+ b1, b2, b3,
+ c1, c2, c3)
+
+ compute a 3-d determinate
+*/
+#define det3_( a1,a2,a3,b1,b2,b3,c1,c2,c3 ) ( ( a1 )*det2_( b2,b3,c2,c3 ) \
+ - ( b1 )*det2_( a2,a3,c2,c3 ) + ( c1 )*det2_( a2,a3,b2,b3 ) )
+
+/*-<a href="qh-geom.htm#TOC"
+ >--------------------------------</a><a name="dX">-</a>
+
+ dX( p1, p2 )
+ dY( p1, p2 )
+ dZ( p1, p2 )
+
+ given two indices into rows[],
+
+ compute the difference between X, Y, or Z coordinates
+*/
+#define dX( p1,p2 ) ( *( rows[p1] ) - *( rows[p2] ))
+#define dY( p1,p2 ) ( *( rows[p1]+1 ) - *( rows[p2]+1 ))
+#define dZ( p1,p2 ) ( *( rows[p1]+2 ) - *( rows[p2]+2 ))
+#define dW( p1,p2 ) ( *( rows[p1]+3 ) - *( rows[p2]+3 ))
+
+/*============= prototypes in alphabetical order, infrequent at end ======= */
+
+void qh_backnormal(realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero);
+void qh_distplane(pointT *point, facetT *facet, realT *dist);
+facetT *qh_findbest(pointT *point, facetT *startfacet,
+ boolT bestoutside, boolT isnewfacets, boolT noupper,
+ realT *dist, boolT *isoutside, int *numpart);
+facetT *qh_findbesthorizon(boolT ischeckmax, pointT *point,
+ facetT *startfacet, boolT noupper, realT *bestdist, int *numpart);
+facetT *qh_findbestnew(pointT *point, facetT *startfacet, realT *dist,
+ boolT bestoutside, boolT *isoutside, int *numpart);
+void qh_gausselim(realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero);
+realT qh_getangle(pointT *vect1, pointT *vect2);
+pointT *qh_getcenter(setT *vertices);
+pointT *qh_getcentrum(facetT *facet);
+realT qh_getdistance(facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist);
+void qh_normalize(coordT *normal, int dim, boolT toporient);
+void qh_normalize2(coordT *normal, int dim, boolT toporient,
+ realT *minnorm, boolT *ismin);
+pointT *qh_projectpoint(pointT *point, facetT *facet, realT dist);
+
+void qh_setfacetplane(facetT *newfacets);
+void qh_sethyperplane_det(int dim, coordT **rows, coordT *point0,
+ boolT toporient, coordT *normal, realT *offset, boolT *nearzero);
+void qh_sethyperplane_gauss(int dim, coordT **rows, pointT *point0,
+ boolT toporient, coordT *normal, coordT *offset, boolT *nearzero);
+boolT qh_sharpnewfacets(void);
+
+/*========= infrequently used code in geom2.c =============*/
+
+coordT *qh_copypoints(coordT *points, int numpoints, int dimension);
+void qh_crossproduct(int dim, realT vecA[3], realT vecB[3], realT vecC[3]);
+realT qh_determinant(realT **rows, int dim, boolT *nearzero);
+realT qh_detjoggle(pointT *points, int numpoints, int dimension);
+void qh_detroundoff(void);
+realT qh_detsimplex(pointT *apex, setT *points, int dim, boolT *nearzero);
+realT qh_distnorm(int dim, pointT *point, pointT *normal, realT *offsetp);
+realT qh_distround(int dimension, realT maxabs, realT maxsumabs);
+realT qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv);
+realT qh_facetarea(facetT *facet);
+realT qh_facetarea_simplex(int dim, coordT *apex, setT *vertices,
+ vertexT *notvertex, boolT toporient, coordT *normal, realT *offset);
+pointT *qh_facetcenter(setT *vertices);
+facetT *qh_findgooddist(pointT *point, facetT *facetA, realT *distp, facetT **facetlist);
+void qh_getarea(facetT *facetlist);
+boolT qh_gram_schmidt(int dim, realT **rows);
+boolT qh_inthresholds(coordT *normal, realT *angle);
+void qh_joggleinput(void);
+realT *qh_maxabsval(realT *normal, int dim);
+setT *qh_maxmin(pointT *points, int numpoints, int dimension);
+realT qh_maxouter(void);
+void qh_maxsimplex(int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex);
+realT qh_minabsval(realT *normal, int dim);
+int qh_mindiff(realT *vecA, realT *vecB, int dim);
+boolT qh_orientoutside(facetT *facet);
+void qh_outerinner(facetT *facet, realT *outerplane, realT *innerplane);
+coordT qh_pointdist(pointT *point1, pointT *point2, int dim);
+void qh_printmatrix(FILE *fp, const char *string, realT **rows, int numrow, int numcol);
+void qh_printpoints(FILE *fp, const char *string, setT *points);
+void qh_projectinput(void);
+void qh_projectpoints(signed char *project, int n, realT *points,
+ int numpoints, int dim, realT *newpoints, int newdim);
+void qh_rotateinput(realT **rows);
+void qh_rotatepoints(realT *points, int numpoints, int dim, realT **rows);
+void qh_scaleinput(void);
+void qh_scalelast(coordT *points, int numpoints, int dim, coordT low,
+ coordT high, coordT newhigh);
+void qh_scalepoints(pointT *points, int numpoints, int dim,
+ realT *newlows, realT *newhighs);
+boolT qh_sethalfspace(int dim, coordT *coords, coordT **nextp,
+ coordT *normal, coordT *offset, coordT *feasible);
+coordT *qh_sethalfspace_all(int dim, int count, coordT *halfspaces, pointT *feasible);
+pointT *qh_voronoi_center(int dim, setT *points);
+
+#endif /* qhDEFgeom */
+
+
+
diff --git a/xs/src/qhull/src/libqhull/geom2.c b/xs/src/qhull/src/libqhull/geom2.c
new file mode 100644
index 000000000..82ec4936e
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/geom2.c
@@ -0,0 +1,2094 @@
+/*<html><pre> -<a href="qh-geom.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+
+ geom2.c
+ infrequently used geometric routines of qhull
+
+ see qh-geom.htm and geom.h
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/geom2.c#6 $$Change: 2065 $
+ $DateTime: 2016/01/18 13:51:04 $$Author: bbarber $
+
+ frequently used code goes into geom.c
+*/
+
+#include "qhull_a.h"
+
+/*================== functions in alphabetic order ============*/
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="copypoints">-</a>
+
+ qh_copypoints( points, numpoints, dimension)
+ return qh_malloc'd copy of points
+ notes:
+ qh_free the returned points to avoid a memory leak
+*/
+coordT *qh_copypoints(coordT *points, int numpoints, int dimension) {
+ int size;
+ coordT *newpoints;
+
+ size= numpoints * dimension * (int)sizeof(coordT);
+ if (!(newpoints=(coordT*)qh_malloc((size_t)size))) {
+ qh_fprintf(qh ferr, 6004, "qhull error: insufficient memory to copy %d points\n",
+ numpoints);
+ qh_errexit(qh_ERRmem, NULL, NULL);
+ }
+ memcpy((char *)newpoints, (char *)points, (size_t)size); /* newpoints!=0 by QH6004 */
+ return newpoints;
+} /* copypoints */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="crossproduct">-</a>
+
+ qh_crossproduct( dim, vecA, vecB, vecC )
+ crossproduct of 2 dim vectors
+ C= A x B
+
+ notes:
+ from Glasner, Graphics Gems I, p. 639
+ only defined for dim==3
+*/
+void qh_crossproduct(int dim, realT vecA[3], realT vecB[3], realT vecC[3]){
+
+ if (dim == 3) {
+ vecC[0]= det2_(vecA[1], vecA[2],
+ vecB[1], vecB[2]);
+ vecC[1]= - det2_(vecA[0], vecA[2],
+ vecB[0], vecB[2]);
+ vecC[2]= det2_(vecA[0], vecA[1],
+ vecB[0], vecB[1]);
+ }
+} /* vcross */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="determinant">-</a>
+
+ qh_determinant( rows, dim, nearzero )
+ compute signed determinant of a square matrix
+ uses qh.NEARzero to test for degenerate matrices
+
+ returns:
+ determinant
+ overwrites rows and the matrix
+ if dim == 2 or 3
+ nearzero iff determinant < qh NEARzero[dim-1]
+ (!quite correct, not critical)
+ if dim >= 4
+ nearzero iff diagonal[k] < qh NEARzero[k]
+*/
+realT qh_determinant(realT **rows, int dim, boolT *nearzero) {
+ realT det=0;
+ int i;
+ boolT sign= False;
+
+ *nearzero= False;
+ if (dim < 2) {
+ qh_fprintf(qh ferr, 6005, "qhull internal error (qh_determinate): only implemented for dimension >= 2\n");
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }else if (dim == 2) {
+ det= det2_(rows[0][0], rows[0][1],
+ rows[1][0], rows[1][1]);
+ if (fabs_(det) < 10*qh NEARzero[1]) /* not really correct, what should this be? */
+ *nearzero= True;
+ }else if (dim == 3) {
+ det= det3_(rows[0][0], rows[0][1], rows[0][2],
+ rows[1][0], rows[1][1], rows[1][2],
+ rows[2][0], rows[2][1], rows[2][2]);
+ if (fabs_(det) < 10*qh NEARzero[2]) /* what should this be? det 5.5e-12 was flat for qh_maxsimplex of qdelaunay 0,0 27,27 -36,36 -9,63 */
+ *nearzero= True;
+ }else {
+ qh_gausselim(rows, dim, dim, &sign, nearzero); /* if nearzero, diagonal still ok*/
+ det= 1.0;
+ for (i=dim; i--; )
+ det *= (rows[i])[i];
+ if (sign)
+ det= -det;
+ }
+ return det;
+} /* determinant */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="detjoggle">-</a>
+
+ qh_detjoggle( points, numpoints, dimension )
+ determine default max joggle for point array
+ as qh_distround * qh_JOGGLEdefault
+
+ returns:
+ initial value for JOGGLEmax from points and REALepsilon
+
+ notes:
+ computes DISTround since qh_maxmin not called yet
+ if qh SCALElast, last dimension will be scaled later to MAXwidth
+
+ loop duplicated from qh_maxmin
+*/
+realT qh_detjoggle(pointT *points, int numpoints, int dimension) {
+ realT abscoord, distround, joggle, maxcoord, mincoord;
+ pointT *point, *pointtemp;
+ realT maxabs= -REALmax;
+ realT sumabs= 0;
+ realT maxwidth= 0;
+ int k;
+
+ for (k=0; k < dimension; k++) {
+ if (qh SCALElast && k == dimension-1)
+ abscoord= maxwidth;
+ else if (qh DELAUNAY && k == dimension-1) /* will qh_setdelaunay() */
+ abscoord= 2 * maxabs * maxabs; /* may be low by qh hull_dim/2 */
+ else {
+ maxcoord= -REALmax;
+ mincoord= REALmax;
+ FORALLpoint_(points, numpoints) {
+ maximize_(maxcoord, point[k]);
+ minimize_(mincoord, point[k]);
+ }
+ maximize_(maxwidth, maxcoord-mincoord);
+ abscoord= fmax_(maxcoord, -mincoord);
+ }
+ sumabs += abscoord;
+ maximize_(maxabs, abscoord);
+ } /* for k */
+ distround= qh_distround(qh hull_dim, maxabs, sumabs);
+ joggle= distround * qh_JOGGLEdefault;
+ maximize_(joggle, REALepsilon * qh_JOGGLEdefault);
+ trace2((qh ferr, 2001, "qh_detjoggle: joggle=%2.2g maxwidth=%2.2g\n", joggle, maxwidth));
+ return joggle;
+} /* detjoggle */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="detroundoff">-</a>
+
+ qh_detroundoff()
+ determine maximum roundoff errors from
+ REALepsilon, REALmax, REALmin, qh.hull_dim, qh.MAXabs_coord,
+ qh.MAXsumcoord, qh.MAXwidth, qh.MINdenom_1
+
+ accounts for qh.SETroundoff, qh.RANDOMdist, qh MERGEexact
+ qh.premerge_cos, qh.postmerge_cos, qh.premerge_centrum,
+ qh.postmerge_centrum, qh.MINoutside,
+ qh_RATIOnearinside, qh_COPLANARratio, qh_WIDEcoplanar
+
+ returns:
+ sets qh.DISTround, etc. (see below)
+ appends precision constants to qh.qhull_options
+
+ see:
+ qh_maxmin() for qh.NEARzero
+
+ design:
+ determine qh.DISTround for distance computations
+ determine minimum denominators for qh_divzero
+ determine qh.ANGLEround for angle computations
+ adjust qh.premerge_cos,... for roundoff error
+ determine qh.ONEmerge for maximum error due to a single merge
+ determine qh.NEARinside, qh.MAXcoplanar, qh.MINvisible,
+ qh.MINoutside, qh.WIDEfacet
+ initialize qh.max_vertex and qh.minvertex
+*/
+void qh_detroundoff(void) {
+
+ qh_option("_max-width", NULL, &qh MAXwidth);
+ if (!qh SETroundoff) {
+ qh DISTround= qh_distround(qh hull_dim, qh MAXabs_coord, qh MAXsumcoord);
+ if (qh RANDOMdist)
+ qh DISTround += qh RANDOMfactor * qh MAXabs_coord;
+ qh_option("Error-roundoff", NULL, &qh DISTround);
+ }
+ qh MINdenom= qh MINdenom_1 * qh MAXabs_coord;
+ qh MINdenom_1_2= sqrt(qh MINdenom_1 * qh hull_dim) ; /* if will be normalized */
+ qh MINdenom_2= qh MINdenom_1_2 * qh MAXabs_coord;
+ /* for inner product */
+ qh ANGLEround= 1.01 * qh hull_dim * REALepsilon;
+ if (qh RANDOMdist)
+ qh ANGLEround += qh RANDOMfactor;
+ if (qh premerge_cos < REALmax/2) {
+ qh premerge_cos -= qh ANGLEround;
+ if (qh RANDOMdist)
+ qh_option("Angle-premerge-with-random", NULL, &qh premerge_cos);
+ }
+ if (qh postmerge_cos < REALmax/2) {
+ qh postmerge_cos -= qh ANGLEround;
+ if (qh RANDOMdist)
+ qh_option("Angle-postmerge-with-random", NULL, &qh postmerge_cos);
+ }
+ qh premerge_centrum += 2 * qh DISTround; /*2 for centrum and distplane()*/
+ qh postmerge_centrum += 2 * qh DISTround;
+ if (qh RANDOMdist && (qh MERGEexact || qh PREmerge))
+ qh_option("Centrum-premerge-with-random", NULL, &qh premerge_centrum);
+ if (qh RANDOMdist && qh POSTmerge)
+ qh_option("Centrum-postmerge-with-random", NULL, &qh postmerge_centrum);
+ { /* compute ONEmerge, max vertex offset for merging simplicial facets */
+ realT maxangle= 1.0, maxrho;
+
+ minimize_(maxangle, qh premerge_cos);
+ minimize_(maxangle, qh postmerge_cos);
+ /* max diameter * sin theta + DISTround for vertex to its hyperplane */
+ qh ONEmerge= sqrt((realT)qh hull_dim) * qh MAXwidth *
+ sqrt(1.0 - maxangle * maxangle) + qh DISTround;
+ maxrho= qh hull_dim * qh premerge_centrum + qh DISTround;
+ maximize_(qh ONEmerge, maxrho);
+ maxrho= qh hull_dim * qh postmerge_centrum + qh DISTround;
+ maximize_(qh ONEmerge, maxrho);
+ if (qh MERGING)
+ qh_option("_one-merge", NULL, &qh ONEmerge);
+ }
+ qh NEARinside= qh ONEmerge * qh_RATIOnearinside; /* only used if qh KEEPnearinside */
+ if (qh JOGGLEmax < REALmax/2 && (qh KEEPcoplanar || qh KEEPinside)) {
+ realT maxdist; /* adjust qh.NEARinside for joggle */
+ qh KEEPnearinside= True;
+ maxdist= sqrt((realT)qh hull_dim) * qh JOGGLEmax + qh DISTround;
+ maxdist= 2*maxdist; /* vertex and coplanar point can joggle in opposite directions */
+ maximize_(qh NEARinside, maxdist); /* must agree with qh_nearcoplanar() */
+ }
+ if (qh KEEPnearinside)
+ qh_option("_near-inside", NULL, &qh NEARinside);
+ if (qh JOGGLEmax < qh DISTround) {
+ qh_fprintf(qh ferr, 6006, "qhull error: the joggle for 'QJn', %.2g, is below roundoff for distance computations, %.2g\n",
+ qh JOGGLEmax, qh DISTround);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (qh MINvisible > REALmax/2) {
+ if (!qh MERGING)
+ qh MINvisible= qh DISTround;
+ else if (qh hull_dim <= 3)
+ qh MINvisible= qh premerge_centrum;
+ else
+ qh MINvisible= qh_COPLANARratio * qh premerge_centrum;
+ if (qh APPROXhull && qh MINvisible > qh MINoutside)
+ qh MINvisible= qh MINoutside;
+ qh_option("Visible-distance", NULL, &qh MINvisible);
+ }
+ if (qh MAXcoplanar > REALmax/2) {
+ qh MAXcoplanar= qh MINvisible;
+ qh_option("U-coplanar-distance", NULL, &qh MAXcoplanar);
+ }
+ if (!qh APPROXhull) { /* user may specify qh MINoutside */
+ qh MINoutside= 2 * qh MINvisible;
+ if (qh premerge_cos < REALmax/2)
+ maximize_(qh MINoutside, (1- qh premerge_cos) * qh MAXabs_coord);
+ qh_option("Width-outside", NULL, &qh MINoutside);
+ }
+ qh WIDEfacet= qh MINoutside;
+ maximize_(qh WIDEfacet, qh_WIDEcoplanar * qh MAXcoplanar);
+ maximize_(qh WIDEfacet, qh_WIDEcoplanar * qh MINvisible);
+ qh_option("_wide-facet", NULL, &qh WIDEfacet);
+ if (qh MINvisible > qh MINoutside + 3 * REALepsilon
+ && !qh BESToutside && !qh FORCEoutput)
+ qh_fprintf(qh ferr, 7001, "qhull input warning: minimum visibility V%.2g is greater than \nminimum outside W%.2g. Flipped facets are likely.\n",
+ qh MINvisible, qh MINoutside);
+ qh max_vertex= qh DISTround;
+ qh min_vertex= -qh DISTround;
+ /* numeric constants reported in printsummary */
+} /* detroundoff */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="detsimplex">-</a>
+
+ qh_detsimplex( apex, points, dim, nearzero )
+ compute determinant of a simplex with point apex and base points
+
+ returns:
+ signed determinant and nearzero from qh_determinant
+
+ notes:
+ uses qh.gm_matrix/qh.gm_row (assumes they're big enough)
+
+ design:
+ construct qm_matrix by subtracting apex from points
+ compute determinate
+*/
+realT qh_detsimplex(pointT *apex, setT *points, int dim, boolT *nearzero) {
+ pointT *coorda, *coordp, *gmcoord, *point, **pointp;
+ coordT **rows;
+ int k, i=0;
+ realT det;
+
+ zinc_(Zdetsimplex);
+ gmcoord= qh gm_matrix;
+ rows= qh gm_row;
+ FOREACHpoint_(points) {
+ if (i == dim)
+ break;
+ rows[i++]= gmcoord;
+ coordp= point;
+ coorda= apex;
+ for (k=dim; k--; )
+ *(gmcoord++)= *coordp++ - *coorda++;
+ }
+ if (i < dim) {
+ qh_fprintf(qh ferr, 6007, "qhull internal error (qh_detsimplex): #points %d < dimension %d\n",
+ i, dim);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ det= qh_determinant(rows, dim, nearzero);
+ trace2((qh ferr, 2002, "qh_detsimplex: det=%2.2g for point p%d, dim %d, nearzero? %d\n",
+ det, qh_pointid(apex), dim, *nearzero));
+ return det;
+} /* detsimplex */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="distnorm">-</a>
+
+ qh_distnorm( dim, point, normal, offset )
+ return distance from point to hyperplane at normal/offset
+
+ returns:
+ dist
+
+ notes:
+ dist > 0 if point is outside of hyperplane
+
+ see:
+ qh_distplane in geom.c
+*/
+realT qh_distnorm(int dim, pointT *point, pointT *normal, realT *offsetp) {
+ coordT *normalp= normal, *coordp= point;
+ realT dist;
+ int k;
+
+ dist= *offsetp;
+ for (k=dim; k--; )
+ dist += *(coordp++) * *(normalp++);
+ return dist;
+} /* distnorm */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="distround">-</a>
+
+ qh_distround(dimension, maxabs, maxsumabs )
+ compute maximum round-off error for a distance computation
+ to a normalized hyperplane
+ maxabs is the maximum absolute value of a coordinate
+ maxsumabs is the maximum possible sum of absolute coordinate values
+
+ returns:
+ max dist round for REALepsilon
+
+ notes:
+ calculate roundoff error according to Golub & van Loan, 1983, Lemma 3.2-1, "Rounding Errors"
+ use sqrt(dim) since one vector is normalized
+ or use maxsumabs since one vector is < 1
+*/
+realT qh_distround(int dimension, realT maxabs, realT maxsumabs) {
+ realT maxdistsum, maxround;
+
+ maxdistsum= sqrt((realT)dimension) * maxabs;
+ minimize_( maxdistsum, maxsumabs);
+ maxround= REALepsilon * (dimension * maxdistsum * 1.01 + maxabs);
+ /* adds maxabs for offset */
+ trace4((qh ferr, 4008, "qh_distround: %2.2g maxabs %2.2g maxsumabs %2.2g maxdistsum %2.2g\n",
+ maxround, maxabs, maxsumabs, maxdistsum));
+ return maxround;
+} /* distround */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="divzero">-</a>
+
+ qh_divzero( numer, denom, mindenom1, zerodiv )
+ divide by a number that's nearly zero
+ mindenom1= minimum denominator for dividing into 1.0
+
+ returns:
+ quotient
+ sets zerodiv and returns 0.0 if it would overflow
+
+ design:
+ if numer is nearly zero and abs(numer) < abs(denom)
+ return numer/denom
+ else if numer is nearly zero
+ return 0 and zerodiv
+ else if denom/numer non-zero
+ return numer/denom
+ else
+ return 0 and zerodiv
+*/
+realT qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv) {
+ realT temp, numerx, denomx;
+
+
+ if (numer < mindenom1 && numer > -mindenom1) {
+ numerx= fabs_(numer);
+ denomx= fabs_(denom);
+ if (numerx < denomx) {
+ *zerodiv= False;
+ return numer/denom;
+ }else {
+ *zerodiv= True;
+ return 0.0;
+ }
+ }
+ temp= denom/numer;
+ if (temp > mindenom1 || temp < -mindenom1) {
+ *zerodiv= False;
+ return numer/denom;
+ }else {
+ *zerodiv= True;
+ return 0.0;
+ }
+} /* divzero */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="facetarea">-</a>
+
+ qh_facetarea( facet )
+ return area for a facet
+
+ notes:
+ if non-simplicial,
+ uses centrum to triangulate facet and sums the projected areas.
+ if (qh DELAUNAY),
+ computes projected area instead for last coordinate
+ assumes facet->normal exists
+ projecting tricoplanar facets to the hyperplane does not appear to make a difference
+
+ design:
+ if simplicial
+ compute area
+ else
+ for each ridge
+ compute area from centrum to ridge
+ negate area if upper Delaunay facet
+*/
+realT qh_facetarea(facetT *facet) {
+ vertexT *apex;
+ pointT *centrum;
+ realT area= 0.0;
+ ridgeT *ridge, **ridgep;
+
+ if (facet->simplicial) {
+ apex= SETfirstt_(facet->vertices, vertexT);
+ area= qh_facetarea_simplex(qh hull_dim, apex->point, facet->vertices,
+ apex, facet->toporient, facet->normal, &facet->offset);
+ }else {
+ if (qh CENTERtype == qh_AScentrum)
+ centrum= facet->center;
+ else
+ centrum= qh_getcentrum(facet);
+ FOREACHridge_(facet->ridges)
+ area += qh_facetarea_simplex(qh hull_dim, centrum, ridge->vertices,
+ NULL, (boolT)(ridge->top == facet), facet->normal, &facet->offset);
+ if (qh CENTERtype != qh_AScentrum)
+ qh_memfree(centrum, qh normal_size);
+ }
+ if (facet->upperdelaunay && qh DELAUNAY)
+ area= -area; /* the normal should be [0,...,1] */
+ trace4((qh ferr, 4009, "qh_facetarea: f%d area %2.2g\n", facet->id, area));
+ return area;
+} /* facetarea */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="facetarea_simplex">-</a>
+
+ qh_facetarea_simplex( dim, apex, vertices, notvertex, toporient, normal, offset )
+ return area for a simplex defined by
+ an apex, a base of vertices, an orientation, and a unit normal
+ if simplicial or tricoplanar facet,
+ notvertex is defined and it is skipped in vertices
+
+ returns:
+ computes area of simplex projected to plane [normal,offset]
+ returns 0 if vertex too far below plane (qh WIDEfacet)
+ vertex can't be apex of tricoplanar facet
+
+ notes:
+ if (qh DELAUNAY),
+ computes projected area instead for last coordinate
+ uses qh gm_matrix/gm_row and qh hull_dim
+ helper function for qh_facetarea
+
+ design:
+ if Notvertex
+ translate simplex to apex
+ else
+ project simplex to normal/offset
+ translate simplex to apex
+ if Delaunay
+ set last row/column to 0 with -1 on diagonal
+ else
+ set last row to Normal
+ compute determinate
+ scale and flip sign for area
+*/
+realT qh_facetarea_simplex(int dim, coordT *apex, setT *vertices,
+ vertexT *notvertex, boolT toporient, coordT *normal, realT *offset) {
+ pointT *coorda, *coordp, *gmcoord;
+ coordT **rows, *normalp;
+ int k, i=0;
+ realT area, dist;
+ vertexT *vertex, **vertexp;
+ boolT nearzero;
+
+ gmcoord= qh gm_matrix;
+ rows= qh gm_row;
+ FOREACHvertex_(vertices) {
+ if (vertex == notvertex)
+ continue;
+ rows[i++]= gmcoord;
+ coorda= apex;
+ coordp= vertex->point;
+ normalp= normal;
+ if (notvertex) {
+ for (k=dim; k--; )
+ *(gmcoord++)= *coordp++ - *coorda++;
+ }else {
+ dist= *offset;
+ for (k=dim; k--; )
+ dist += *coordp++ * *normalp++;
+ if (dist < -qh WIDEfacet) {
+ zinc_(Znoarea);
+ return 0.0;
+ }
+ coordp= vertex->point;
+ normalp= normal;
+ for (k=dim; k--; )
+ *(gmcoord++)= (*coordp++ - dist * *normalp++) - *coorda++;
+ }
+ }
+ if (i != dim-1) {
+ qh_fprintf(qh ferr, 6008, "qhull internal error (qh_facetarea_simplex): #points %d != dim %d -1\n",
+ i, dim);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ rows[i]= gmcoord;
+ if (qh DELAUNAY) {
+ for (i=0; i < dim-1; i++)
+ rows[i][dim-1]= 0.0;
+ for (k=dim; k--; )
+ *(gmcoord++)= 0.0;
+ rows[dim-1][dim-1]= -1.0;
+ }else {
+ normalp= normal;
+ for (k=dim; k--; )
+ *(gmcoord++)= *normalp++;
+ }
+ zinc_(Zdetsimplex);
+ area= qh_determinant(rows, dim, &nearzero);
+ if (toporient)
+ area= -area;
+ area *= qh AREAfactor;
+ trace4((qh ferr, 4010, "qh_facetarea_simplex: area=%2.2g for point p%d, toporient %d, nearzero? %d\n",
+ area, qh_pointid(apex), toporient, nearzero));
+ return area;
+} /* facetarea_simplex */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="facetcenter">-</a>
+
+ qh_facetcenter( vertices )
+ return Voronoi center (Voronoi vertex) for a facet's vertices
+
+ returns:
+ return temporary point equal to the center
+
+ see:
+ qh_voronoi_center()
+*/
+pointT *qh_facetcenter(setT *vertices) {
+ setT *points= qh_settemp(qh_setsize(vertices));
+ vertexT *vertex, **vertexp;
+ pointT *center;
+
+ FOREACHvertex_(vertices)
+ qh_setappend(&points, vertex->point);
+ center= qh_voronoi_center(qh hull_dim-1, points);
+ qh_settempfree(&points);
+ return center;
+} /* facetcenter */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="findgooddist">-</a>
+
+ qh_findgooddist( point, facetA, dist, facetlist )
+ find best good facet visible for point from facetA
+ assumes facetA is visible from point
+
+ returns:
+ best facet, i.e., good facet that is furthest from point
+ distance to best facet
+ NULL if none
+
+ moves good, visible facets (and some other visible facets)
+ to end of qh facet_list
+
+ notes:
+ uses qh visit_id
+
+ design:
+ initialize bestfacet if facetA is good
+ move facetA to end of facetlist
+ for each facet on facetlist
+ for each unvisited neighbor of facet
+ move visible neighbors to end of facetlist
+ update best good neighbor
+ if no good neighbors, update best facet
+*/
+facetT *qh_findgooddist(pointT *point, facetT *facetA, realT *distp,
+ facetT **facetlist) {
+ realT bestdist= -REALmax, dist;
+ facetT *neighbor, **neighborp, *bestfacet=NULL, *facet;
+ boolT goodseen= False;
+
+ if (facetA->good) {
+ zzinc_(Zcheckpart); /* calls from check_bestdist occur after print stats */
+ qh_distplane(point, facetA, &bestdist);
+ bestfacet= facetA;
+ goodseen= True;
+ }
+ qh_removefacet(facetA);
+ qh_appendfacet(facetA);
+ *facetlist= facetA;
+ facetA->visitid= ++qh visit_id;
+ FORALLfacet_(*facetlist) {
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid == qh visit_id)
+ continue;
+ neighbor->visitid= qh visit_id;
+ if (goodseen && !neighbor->good)
+ continue;
+ zzinc_(Zcheckpart);
+ qh_distplane(point, neighbor, &dist);
+ if (dist > 0) {
+ qh_removefacet(neighbor);
+ qh_appendfacet(neighbor);
+ if (neighbor->good) {
+ goodseen= True;
+ if (dist > bestdist) {
+ bestdist= dist;
+ bestfacet= neighbor;
+ }
+ }
+ }
+ }
+ }
+ if (bestfacet) {
+ *distp= bestdist;
+ trace2((qh ferr, 2003, "qh_findgooddist: p%d is %2.2g above good facet f%d\n",
+ qh_pointid(point), bestdist, bestfacet->id));
+ return bestfacet;
+ }
+ trace4((qh ferr, 4011, "qh_findgooddist: no good facet for p%d above f%d\n",
+ qh_pointid(point), facetA->id));
+ return NULL;
+} /* findgooddist */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="getarea">-</a>
+
+ qh_getarea( facetlist )
+ set area of all facets in facetlist
+ collect statistics
+ nop if hasAreaVolume
+
+ returns:
+ sets qh totarea/totvol to total area and volume of convex hull
+ for Delaunay triangulation, computes projected area of the lower or upper hull
+ ignores upper hull if qh ATinfinity
+
+ notes:
+ could compute outer volume by expanding facet area by rays from interior
+ the following attempt at perpendicular projection underestimated badly:
+ qh.totoutvol += (-dist + facet->maxoutside + qh DISTround)
+ * area/ qh hull_dim;
+ design:
+ for each facet on facetlist
+ compute facet->area
+ update qh.totarea and qh.totvol
+*/
+void qh_getarea(facetT *facetlist) {
+ realT area;
+ realT dist;
+ facetT *facet;
+
+ if (qh hasAreaVolume)
+ return;
+ if (qh REPORTfreq)
+ qh_fprintf(qh ferr, 8020, "computing area of each facet and volume of the convex hull\n");
+ else
+ trace1((qh ferr, 1001, "qh_getarea: computing volume and area for each facet\n"));
+ qh totarea= qh totvol= 0.0;
+ FORALLfacet_(facetlist) {
+ if (!facet->normal)
+ continue;
+ if (facet->upperdelaunay && qh ATinfinity)
+ continue;
+ if (!facet->isarea) {
+ facet->f.area= qh_facetarea(facet);
+ facet->isarea= True;
+ }
+ area= facet->f.area;
+ if (qh DELAUNAY) {
+ if (facet->upperdelaunay == qh UPPERdelaunay)
+ qh totarea += area;
+ }else {
+ qh totarea += area;
+ qh_distplane(qh interior_point, facet, &dist);
+ qh totvol += -dist * area/ qh hull_dim;
+ }
+ if (qh PRINTstatistics) {
+ wadd_(Wareatot, area);
+ wmax_(Wareamax, area);
+ wmin_(Wareamin, area);
+ }
+ }
+ qh hasAreaVolume= True;
+} /* getarea */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="gram_schmidt">-</a>
+
+ qh_gram_schmidt( dim, row )
+ implements Gram-Schmidt orthogonalization by rows
+
+ returns:
+ false if zero norm
+ overwrites rows[dim][dim]
+
+ notes:
+ see Golub & van Loan, 1983, Algorithm 6.2-2, "Modified Gram-Schmidt"
+ overflow due to small divisors not handled
+
+ design:
+ for each row
+ compute norm for row
+ if non-zero, normalize row
+ for each remaining rowA
+ compute inner product of row and rowA
+ reduce rowA by row * inner product
+*/
+boolT qh_gram_schmidt(int dim, realT **row) {
+ realT *rowi, *rowj, norm;
+ int i, j, k;
+
+ for (i=0; i < dim; i++) {
+ rowi= row[i];
+ for (norm= 0.0, k= dim; k--; rowi++)
+ norm += *rowi * *rowi;
+ norm= sqrt(norm);
+ wmin_(Wmindenom, norm);
+ if (norm == 0.0) /* either 0 or overflow due to sqrt */
+ return False;
+ for (k=dim; k--; )
+ *(--rowi) /= norm;
+ for (j=i+1; j < dim; j++) {
+ rowj= row[j];
+ for (norm= 0.0, k=dim; k--; )
+ norm += *rowi++ * *rowj++;
+ for (k=dim; k--; )
+ *(--rowj) -= *(--rowi) * norm;
+ }
+ }
+ return True;
+} /* gram_schmidt */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="inthresholds">-</a>
+
+ qh_inthresholds( normal, angle )
+ return True if normal within qh.lower_/upper_threshold
+
+ returns:
+ estimate of angle by summing of threshold diffs
+ angle may be NULL
+ smaller "angle" is better
+
+ notes:
+ invalid if qh.SPLITthresholds
+
+ see:
+ qh.lower_threshold in qh_initbuild()
+ qh_initthresholds()
+
+ design:
+ for each dimension
+ test threshold
+*/
+boolT qh_inthresholds(coordT *normal, realT *angle) {
+ boolT within= True;
+ int k;
+ realT threshold;
+
+ if (angle)
+ *angle= 0.0;
+ for (k=0; k < qh hull_dim; k++) {
+ threshold= qh lower_threshold[k];
+ if (threshold > -REALmax/2) {
+ if (normal[k] < threshold)
+ within= False;
+ if (angle) {
+ threshold -= normal[k];
+ *angle += fabs_(threshold);
+ }
+ }
+ if (qh upper_threshold[k] < REALmax/2) {
+ threshold= qh upper_threshold[k];
+ if (normal[k] > threshold)
+ within= False;
+ if (angle) {
+ threshold -= normal[k];
+ *angle += fabs_(threshold);
+ }
+ }
+ }
+ return within;
+} /* inthresholds */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="joggleinput">-</a>
+
+ qh_joggleinput()
+ randomly joggle input to Qhull by qh.JOGGLEmax
+ initial input is qh.first_point/qh.num_points of qh.hull_dim
+ repeated calls use qh.input_points/qh.num_points
+
+ returns:
+ joggles points at qh.first_point/qh.num_points
+ copies data to qh.input_points/qh.input_malloc if first time
+ determines qh.JOGGLEmax if it was zero
+ if qh.DELAUNAY
+ computes the Delaunay projection of the joggled points
+
+ notes:
+ if qh.DELAUNAY, unnecessarily joggles the last coordinate
+ the initial 'QJn' may be set larger than qh_JOGGLEmaxincrease
+
+ design:
+ if qh.DELAUNAY
+ set qh.SCALElast for reduced precision errors
+ if first call
+ initialize qh.input_points to the original input points
+ if qh.JOGGLEmax == 0
+ determine default qh.JOGGLEmax
+ else
+ increase qh.JOGGLEmax according to qh.build_cnt
+ joggle the input by adding a random number in [-qh.JOGGLEmax,qh.JOGGLEmax]
+ if qh.DELAUNAY
+ sets the Delaunay projection
+*/
+void qh_joggleinput(void) {
+ int i, seed, size;
+ coordT *coordp, *inputp;
+ realT randr, randa, randb;
+
+ if (!qh input_points) { /* first call */
+ qh input_points= qh first_point;
+ qh input_malloc= qh POINTSmalloc;
+ size= qh num_points * qh hull_dim * sizeof(coordT);
+ if (!(qh first_point=(coordT*)qh_malloc((size_t)size))) {
+ qh_fprintf(qh ferr, 6009, "qhull error: insufficient memory to joggle %d points\n",
+ qh num_points);
+ qh_errexit(qh_ERRmem, NULL, NULL);
+ }
+ qh POINTSmalloc= True;
+ if (qh JOGGLEmax == 0.0) {
+ qh JOGGLEmax= qh_detjoggle(qh input_points, qh num_points, qh hull_dim);
+ qh_option("QJoggle", NULL, &qh JOGGLEmax);
+ }
+ }else { /* repeated call */
+ if (!qh RERUN && qh build_cnt > qh_JOGGLEretry) {
+ if (((qh build_cnt-qh_JOGGLEretry-1) % qh_JOGGLEagain) == 0) {
+ realT maxjoggle= qh MAXwidth * qh_JOGGLEmaxincrease;
+ if (qh JOGGLEmax < maxjoggle) {
+ qh JOGGLEmax *= qh_JOGGLEincrease;
+ minimize_(qh JOGGLEmax, maxjoggle);
+ }
+ }
+ }
+ qh_option("QJoggle", NULL, &qh JOGGLEmax);
+ }
+ if (qh build_cnt > 1 && qh JOGGLEmax > fmax_(qh MAXwidth/4, 0.1)) {
+ qh_fprintf(qh ferr, 6010, "qhull error: the current joggle for 'QJn', %.2g, is too large for the width\nof the input. If possible, recompile Qhull with higher-precision reals.\n",
+ qh JOGGLEmax);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ /* for some reason, using qh ROTATErandom and qh_RANDOMseed does not repeat the run. Use 'TRn' instead */
+ seed= qh_RANDOMint;
+ qh_option("_joggle-seed", &seed, NULL);
+ trace0((qh ferr, 6, "qh_joggleinput: joggle input by %2.2g with seed %d\n",
+ qh JOGGLEmax, seed));
+ inputp= qh input_points;
+ coordp= qh first_point;
+ randa= 2.0 * qh JOGGLEmax/qh_RANDOMmax;
+ randb= -qh JOGGLEmax;
+ size= qh num_points * qh hull_dim;
+ for (i=size; i--; ) {
+ randr= qh_RANDOMint;
+ *(coordp++)= *(inputp++) + (randr * randa + randb);
+ }
+ if (qh DELAUNAY) {
+ qh last_low= qh last_high= qh last_newhigh= REALmax;
+ qh_setdelaunay(qh hull_dim, qh num_points, qh first_point);
+ }
+} /* joggleinput */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="maxabsval">-</a>
+
+ qh_maxabsval( normal, dim )
+ return pointer to maximum absolute value of a dim vector
+ returns NULL if dim=0
+*/
+realT *qh_maxabsval(realT *normal, int dim) {
+ realT maxval= -REALmax;
+ realT *maxp= NULL, *colp, absval;
+ int k;
+
+ for (k=dim, colp= normal; k--; colp++) {
+ absval= fabs_(*colp);
+ if (absval > maxval) {
+ maxval= absval;
+ maxp= colp;
+ }
+ }
+ return maxp;
+} /* maxabsval */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="maxmin">-</a>
+
+ qh_maxmin( points, numpoints, dimension )
+ return max/min points for each dimension
+ determine max and min coordinates
+
+ returns:
+ returns a temporary set of max and min points
+ may include duplicate points. Does not include qh.GOODpoint
+ sets qh.NEARzero, qh.MAXabs_coord, qh.MAXsumcoord, qh.MAXwidth
+ qh.MAXlastcoord, qh.MINlastcoord
+ initializes qh.max_outside, qh.min_vertex, qh.WAScoplanar, qh.ZEROall_ok
+
+ notes:
+ loop duplicated in qh_detjoggle()
+
+ design:
+ initialize global precision variables
+ checks definition of REAL...
+ for each dimension
+ for each point
+ collect maximum and minimum point
+ collect maximum of maximums and minimum of minimums
+ determine qh.NEARzero for Gaussian Elimination
+*/
+setT *qh_maxmin(pointT *points, int numpoints, int dimension) {
+ int k;
+ realT maxcoord, temp;
+ pointT *minimum, *maximum, *point, *pointtemp;
+ setT *set;
+
+ qh max_outside= 0.0;
+ qh MAXabs_coord= 0.0;
+ qh MAXwidth= -REALmax;
+ qh MAXsumcoord= 0.0;
+ qh min_vertex= 0.0;
+ qh WAScoplanar= False;
+ if (qh ZEROcentrum)
+ qh ZEROall_ok= True;
+ if (REALmin < REALepsilon && REALmin < REALmax && REALmin > -REALmax
+ && REALmax > 0.0 && -REALmax < 0.0)
+ ; /* all ok */
+ else {
+ qh_fprintf(qh ferr, 6011, "qhull error: floating point constants in user.h are wrong\n\
+REALepsilon %g REALmin %g REALmax %g -REALmax %g\n",
+ REALepsilon, REALmin, REALmax, -REALmax);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ set= qh_settemp(2*dimension);
+ for (k=0; k < dimension; k++) {
+ if (points == qh GOODpointp)
+ minimum= maximum= points + dimension;
+ else
+ minimum= maximum= points;
+ FORALLpoint_(points, numpoints) {
+ if (point == qh GOODpointp)
+ continue;
+ if (maximum[k] < point[k])
+ maximum= point;
+ else if (minimum[k] > point[k])
+ minimum= point;
+ }
+ if (k == dimension-1) {
+ qh MINlastcoord= minimum[k];
+ qh MAXlastcoord= maximum[k];
+ }
+ if (qh SCALElast && k == dimension-1)
+ maxcoord= qh MAXwidth;
+ else {
+ maxcoord= fmax_(maximum[k], -minimum[k]);
+ if (qh GOODpointp) {
+ temp= fmax_(qh GOODpointp[k], -qh GOODpointp[k]);
+ maximize_(maxcoord, temp);
+ }
+ temp= maximum[k] - minimum[k];
+ maximize_(qh MAXwidth, temp);
+ }
+ maximize_(qh MAXabs_coord, maxcoord);
+ qh MAXsumcoord += maxcoord;
+ qh_setappend(&set, maximum);
+ qh_setappend(&set, minimum);
+ /* calculation of qh NEARzero is based on Golub & van Loan, 1983,
+ Eq. 4.4-13 for "Gaussian elimination with complete pivoting".
+ Golub & van Loan say that n^3 can be ignored and 10 be used in
+ place of rho */
+ qh NEARzero[k]= 80 * qh MAXsumcoord * REALepsilon;
+ }
+ if (qh IStracing >=1)
+ qh_printpoints(qh ferr, "qh_maxmin: found the max and min points(by dim):", set);
+ return(set);
+} /* maxmin */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="maxouter">-</a>
+
+ qh_maxouter()
+ return maximum distance from facet to outer plane
+ normally this is qh.max_outside+qh.DISTround
+ does not include qh.JOGGLEmax
+
+ see:
+ qh_outerinner()
+
+ notes:
+ need to add another qh.DISTround if testing actual point with computation
+
+ for joggle:
+ qh_setfacetplane() updated qh.max_outer for Wnewvertexmax (max distance to vertex)
+ need to use Wnewvertexmax since could have a coplanar point for a high
+ facet that is replaced by a low facet
+ need to add qh.JOGGLEmax if testing input points
+*/
+realT qh_maxouter(void) {
+ realT dist;
+
+ dist= fmax_(qh max_outside, qh DISTround);
+ dist += qh DISTround;
+ trace4((qh ferr, 4012, "qh_maxouter: max distance from facet to outer plane is %2.2g max_outside is %2.2g\n", dist, qh max_outside));
+ return dist;
+} /* maxouter */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="maxsimplex">-</a>
+
+ qh_maxsimplex( dim, maxpoints, points, numpoints, simplex )
+ determines maximum simplex for a set of points
+ starts from points already in simplex
+ skips qh.GOODpointp (assumes that it isn't in maxpoints)
+
+ returns:
+ simplex with dim+1 points
+
+ notes:
+ assumes at least pointsneeded points in points
+ maximizes determinate for x,y,z,w, etc.
+ uses maxpoints as long as determinate is clearly non-zero
+
+ design:
+ initialize simplex with at least two points
+ (find points with max or min x coordinate)
+ for each remaining dimension
+ add point that maximizes the determinate
+ (use points from maxpoints first)
+*/
+void qh_maxsimplex(int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex) {
+ pointT *point, **pointp, *pointtemp, *maxpoint, *minx=NULL, *maxx=NULL;
+ boolT nearzero, maxnearzero= False;
+ int k, sizinit;
+ realT maxdet= -REALmax, det, mincoord= REALmax, maxcoord= -REALmax;
+
+ sizinit= qh_setsize(*simplex);
+ if (sizinit < 2) {
+ if (qh_setsize(maxpoints) >= 2) {
+ FOREACHpoint_(maxpoints) {
+ if (maxcoord < point[0]) {
+ maxcoord= point[0];
+ maxx= point;
+ }
+ if (mincoord > point[0]) {
+ mincoord= point[0];
+ minx= point;
+ }
+ }
+ }else {
+ FORALLpoint_(points, numpoints) {
+ if (point == qh GOODpointp)
+ continue;
+ if (maxcoord < point[0]) {
+ maxcoord= point[0];
+ maxx= point;
+ }
+ if (mincoord > point[0]) {
+ mincoord= point[0];
+ minx= point;
+ }
+ }
+ }
+ qh_setunique(simplex, minx);
+ if (qh_setsize(*simplex) < 2)
+ qh_setunique(simplex, maxx);
+ sizinit= qh_setsize(*simplex);
+ if (sizinit < 2) {
+ qh_precision("input has same x coordinate");
+ if (zzval_(Zsetplane) > qh hull_dim+1) {
+ qh_fprintf(qh ferr, 6012, "qhull precision error (qh_maxsimplex for voronoi_center):\n%d points with the same x coordinate.\n",
+ qh_setsize(maxpoints)+numpoints);
+ qh_errexit(qh_ERRprec, NULL, NULL);
+ }else {
+ qh_fprintf(qh ferr, 6013, "qhull input error: input is less than %d-dimensional since it has the same x coordinate\n", qh hull_dim);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ }
+ }
+ for (k=sizinit; k < dim+1; k++) {
+ maxpoint= NULL;
+ maxdet= -REALmax;
+ FOREACHpoint_(maxpoints) {
+ if (!qh_setin(*simplex, point)) {
+ det= qh_detsimplex(point, *simplex, k, &nearzero);
+ if ((det= fabs_(det)) > maxdet) {
+ maxdet= det;
+ maxpoint= point;
+ maxnearzero= nearzero;
+ }
+ }
+ }
+ if (!maxpoint || maxnearzero) {
+ zinc_(Zsearchpoints);
+ if (!maxpoint) {
+ trace0((qh ferr, 7, "qh_maxsimplex: searching all points for %d-th initial vertex.\n", k+1));
+ }else {
+ trace0((qh ferr, 8, "qh_maxsimplex: searching all points for %d-th initial vertex, better than p%d det %2.2g\n",
+ k+1, qh_pointid(maxpoint), maxdet));
+ }
+ FORALLpoint_(points, numpoints) {
+ if (point == qh GOODpointp)
+ continue;
+ if (!qh_setin(*simplex, point)) {
+ det= qh_detsimplex(point, *simplex, k, &nearzero);
+ if ((det= fabs_(det)) > maxdet) {
+ maxdet= det;
+ maxpoint= point;
+ maxnearzero= nearzero;
+ }
+ }
+ }
+ } /* !maxpoint */
+ if (!maxpoint) {
+ qh_fprintf(qh ferr, 6014, "qhull internal error (qh_maxsimplex): not enough points available\n");
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ qh_setappend(simplex, maxpoint);
+ trace1((qh ferr, 1002, "qh_maxsimplex: selected point p%d for %d`th initial vertex, det=%2.2g\n",
+ qh_pointid(maxpoint), k+1, maxdet));
+ } /* k */
+} /* maxsimplex */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="minabsval">-</a>
+
+ qh_minabsval( normal, dim )
+ return minimum absolute value of a dim vector
+*/
+realT qh_minabsval(realT *normal, int dim) {
+ realT minval= 0;
+ realT maxval= 0;
+ realT *colp;
+ int k;
+
+ for (k=dim, colp=normal; k--; colp++) {
+ maximize_(maxval, *colp);
+ minimize_(minval, *colp);
+ }
+ return fmax_(maxval, -minval);
+} /* minabsval */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="mindiff">-</a>
+
+ qh_mindif( vecA, vecB, dim )
+ return index of min abs. difference of two vectors
+*/
+int qh_mindiff(realT *vecA, realT *vecB, int dim) {
+ realT mindiff= REALmax, diff;
+ realT *vecAp= vecA, *vecBp= vecB;
+ int k, mink= 0;
+
+ for (k=0; k < dim; k++) {
+ diff= *vecAp++ - *vecBp++;
+ diff= fabs_(diff);
+ if (diff < mindiff) {
+ mindiff= diff;
+ mink= k;
+ }
+ }
+ return mink;
+} /* mindiff */
+
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="orientoutside">-</a>
+
+ qh_orientoutside( facet )
+ make facet outside oriented via qh.interior_point
+
+ returns:
+ True if facet reversed orientation.
+*/
+boolT qh_orientoutside(facetT *facet) {
+ int k;
+ realT dist;
+
+ qh_distplane(qh interior_point, facet, &dist);
+ if (dist > 0) {
+ for (k=qh hull_dim; k--; )
+ facet->normal[k]= -facet->normal[k];
+ facet->offset= -facet->offset;
+ return True;
+ }
+ return False;
+} /* orientoutside */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="outerinner">-</a>
+
+ qh_outerinner( facet, outerplane, innerplane )
+ if facet and qh.maxoutdone (i.e., qh_check_maxout)
+ returns outer and inner plane for facet
+ else
+ returns maximum outer and inner plane
+ accounts for qh.JOGGLEmax
+
+ see:
+ qh_maxouter(), qh_check_bestdist(), qh_check_points()
+
+ notes:
+ outerplaner or innerplane may be NULL
+ facet is const
+ Does not error (QhullFacet)
+
+ includes qh.DISTround for actual points
+ adds another qh.DISTround if testing with floating point arithmetic
+*/
+void qh_outerinner(facetT *facet, realT *outerplane, realT *innerplane) {
+ realT dist, mindist;
+ vertexT *vertex, **vertexp;
+
+ if (outerplane) {
+ if (!qh_MAXoutside || !facet || !qh maxoutdone) {
+ *outerplane= qh_maxouter(); /* includes qh.DISTround */
+ }else { /* qh_MAXoutside ... */
+#if qh_MAXoutside
+ *outerplane= facet->maxoutside + qh DISTround;
+#endif
+
+ }
+ if (qh JOGGLEmax < REALmax/2)
+ *outerplane += qh JOGGLEmax * sqrt((realT)qh hull_dim);
+ }
+ if (innerplane) {
+ if (facet) {
+ mindist= REALmax;
+ FOREACHvertex_(facet->vertices) {
+ zinc_(Zdistio);
+ qh_distplane(vertex->point, facet, &dist);
+ minimize_(mindist, dist);
+ }
+ *innerplane= mindist - qh DISTround;
+ }else
+ *innerplane= qh min_vertex - qh DISTround;
+ if (qh JOGGLEmax < REALmax/2)
+ *innerplane -= qh JOGGLEmax * sqrt((realT)qh hull_dim);
+ }
+} /* outerinner */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="pointdist">-</a>
+
+ qh_pointdist( point1, point2, dim )
+ return distance between two points
+
+ notes:
+ returns distance squared if 'dim' is negative
+*/
+coordT qh_pointdist(pointT *point1, pointT *point2, int dim) {
+ coordT dist, diff;
+ int k;
+
+ dist= 0.0;
+ for (k= (dim > 0 ? dim : -dim); k--; ) {
+ diff= *point1++ - *point2++;
+ dist += diff * diff;
+ }
+ if (dim > 0)
+ return(sqrt(dist));
+ return dist;
+} /* pointdist */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="printmatrix">-</a>
+
+ qh_printmatrix( fp, string, rows, numrow, numcol )
+ print matrix to fp given by row vectors
+ print string as header
+
+ notes:
+ print a vector by qh_printmatrix(fp, "", &vect, 1, len)
+*/
+void qh_printmatrix(FILE *fp, const char *string, realT **rows, int numrow, int numcol) {
+ realT *rowp;
+ realT r; /*bug fix*/
+ int i,k;
+
+ qh_fprintf(fp, 9001, "%s\n", string);
+ for (i=0; i < numrow; i++) {
+ rowp= rows[i];
+ for (k=0; k < numcol; k++) {
+ r= *rowp++;
+ qh_fprintf(fp, 9002, "%6.3g ", r);
+ }
+ qh_fprintf(fp, 9003, "\n");
+ }
+} /* printmatrix */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="printpoints">-</a>
+
+ qh_printpoints( fp, string, points )
+ print pointids to fp for a set of points
+ if string, prints string and 'p' point ids
+*/
+void qh_printpoints(FILE *fp, const char *string, setT *points) {
+ pointT *point, **pointp;
+
+ if (string) {
+ qh_fprintf(fp, 9004, "%s", string);
+ FOREACHpoint_(points)
+ qh_fprintf(fp, 9005, " p%d", qh_pointid(point));
+ qh_fprintf(fp, 9006, "\n");
+ }else {
+ FOREACHpoint_(points)
+ qh_fprintf(fp, 9007, " %d", qh_pointid(point));
+ qh_fprintf(fp, 9008, "\n");
+ }
+} /* printpoints */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="projectinput">-</a>
+
+ qh_projectinput()
+ project input points using qh.lower_bound/upper_bound and qh DELAUNAY
+ if qh.lower_bound[k]=qh.upper_bound[k]= 0,
+ removes dimension k
+ if halfspace intersection
+ removes dimension k from qh.feasible_point
+ input points in qh first_point, num_points, input_dim
+
+ returns:
+ new point array in qh first_point of qh hull_dim coordinates
+ sets qh POINTSmalloc
+ if qh DELAUNAY
+ projects points to paraboloid
+ lowbound/highbound is also projected
+ if qh ATinfinity
+ adds point "at-infinity"
+ if qh POINTSmalloc
+ frees old point array
+
+ notes:
+ checks that qh.hull_dim agrees with qh.input_dim, PROJECTinput, and DELAUNAY
+
+
+ design:
+ sets project[k] to -1 (delete), 0 (keep), 1 (add for Delaunay)
+ determines newdim and newnum for qh hull_dim and qh num_points
+ projects points to newpoints
+ projects qh.lower_bound to itself
+ projects qh.upper_bound to itself
+ if qh DELAUNAY
+ if qh ATINFINITY
+ projects points to paraboloid
+ computes "infinity" point as vertex average and 10% above all points
+ else
+ uses qh_setdelaunay to project points to paraboloid
+*/
+void qh_projectinput(void) {
+ int k,i;
+ int newdim= qh input_dim, newnum= qh num_points;
+ signed char *project;
+ int projectsize= (qh input_dim+1)*sizeof(*project);
+ pointT *newpoints, *coord, *infinity;
+ realT paraboloid, maxboloid= 0;
+
+ project= (signed char*)qh_memalloc(projectsize);
+ memset((char*)project, 0, (size_t)projectsize);
+ for (k=0; k < qh input_dim; k++) { /* skip Delaunay bound */
+ if (qh lower_bound[k] == 0 && qh upper_bound[k] == 0) {
+ project[k]= -1;
+ newdim--;
+ }
+ }
+ if (qh DELAUNAY) {
+ project[k]= 1;
+ newdim++;
+ if (qh ATinfinity)
+ newnum++;
+ }
+ if (newdim != qh hull_dim) {
+ qh_memfree(project, projectsize);
+ qh_fprintf(qh ferr, 6015, "qhull internal error (qh_projectinput): dimension after projection %d != hull_dim %d\n", newdim, qh hull_dim);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ if (!(newpoints= qh temp_malloc= (coordT*)qh_malloc(newnum*newdim*sizeof(coordT)))){
+ qh_memfree(project, projectsize);
+ qh_fprintf(qh ferr, 6016, "qhull error: insufficient memory to project %d points\n",
+ qh num_points);
+ qh_errexit(qh_ERRmem, NULL, NULL);
+ }
+ /* qh_projectpoints throws error if mismatched dimensions */
+ qh_projectpoints(project, qh input_dim+1, qh first_point,
+ qh num_points, qh input_dim, newpoints, newdim);
+ trace1((qh ferr, 1003, "qh_projectinput: updating lower and upper_bound\n"));
+ qh_projectpoints(project, qh input_dim+1, qh lower_bound,
+ 1, qh input_dim+1, qh lower_bound, newdim+1);
+ qh_projectpoints(project, qh input_dim+1, qh upper_bound,
+ 1, qh input_dim+1, qh upper_bound, newdim+1);
+ if (qh HALFspace) {
+ if (!qh feasible_point) {
+ qh_memfree(project, projectsize);
+ qh_fprintf(qh ferr, 6017, "qhull internal error (qh_projectinput): HALFspace defined without qh.feasible_point\n");
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ qh_projectpoints(project, qh input_dim, qh feasible_point,
+ 1, qh input_dim, qh feasible_point, newdim);
+ }
+ qh_memfree(project, projectsize);
+ if (qh POINTSmalloc)
+ qh_free(qh first_point);
+ qh first_point= newpoints;
+ qh POINTSmalloc= True;
+ qh temp_malloc= NULL;
+ if (qh DELAUNAY && qh ATinfinity) {
+ coord= qh first_point;
+ infinity= qh first_point + qh hull_dim * qh num_points;
+ for (k=qh hull_dim-1; k--; )
+ infinity[k]= 0.0;
+ for (i=qh num_points; i--; ) {
+ paraboloid= 0.0;
+ for (k=0; k < qh hull_dim-1; k++) {
+ paraboloid += *coord * *coord;
+ infinity[k] += *coord;
+ coord++;
+ }
+ *(coord++)= paraboloid;
+ maximize_(maxboloid, paraboloid);
+ }
+ /* coord == infinity */
+ for (k=qh hull_dim-1; k--; )
+ *(coord++) /= qh num_points;
+ *(coord++)= maxboloid * 1.1;
+ qh num_points++;
+ trace0((qh ferr, 9, "qh_projectinput: projected points to paraboloid for Delaunay\n"));
+ }else if (qh DELAUNAY) /* !qh ATinfinity */
+ qh_setdelaunay( qh hull_dim, qh num_points, qh first_point);
+} /* projectinput */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="projectpoints">-</a>
+
+ qh_projectpoints( project, n, points, numpoints, dim, newpoints, newdim )
+ project points/numpoints/dim to newpoints/newdim
+ if project[k] == -1
+ delete dimension k
+ if project[k] == 1
+ add dimension k by duplicating previous column
+ n is size of project
+
+ notes:
+ newpoints may be points if only adding dimension at end
+
+ design:
+ check that 'project' and 'newdim' agree
+ for each dimension
+ if project == -1
+ skip dimension
+ else
+ determine start of column in newpoints
+ determine start of column in points
+ if project == +1, duplicate previous column
+ copy dimension (column) from points to newpoints
+*/
+void qh_projectpoints(signed char *project, int n, realT *points,
+ int numpoints, int dim, realT *newpoints, int newdim) {
+ int testdim= dim, oldk=0, newk=0, i,j=0,k;
+ realT *newp, *oldp;
+
+ for (k=0; k < n; k++)
+ testdim += project[k];
+ if (testdim != newdim) {
+ qh_fprintf(qh ferr, 6018, "qhull internal error (qh_projectpoints): newdim %d should be %d after projection\n",
+ newdim, testdim);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ for (j=0; j<n; j++) {
+ if (project[j] == -1)
+ oldk++;
+ else {
+ newp= newpoints+newk++;
+ if (project[j] == +1) {
+ if (oldk >= dim)
+ continue;
+ oldp= points+oldk;
+ }else
+ oldp= points+oldk++;
+ for (i=numpoints; i--; ) {
+ *newp= *oldp;
+ newp += newdim;
+ oldp += dim;
+ }
+ }
+ if (oldk >= dim)
+ break;
+ }
+ trace1((qh ferr, 1004, "qh_projectpoints: projected %d points from dim %d to dim %d\n",
+ numpoints, dim, newdim));
+} /* projectpoints */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="rotateinput">-</a>
+
+ qh_rotateinput( rows )
+ rotate input using row matrix
+ input points given by qh first_point, num_points, hull_dim
+ assumes rows[dim] is a scratch buffer
+ if qh POINTSmalloc, overwrites input points, else mallocs a new array
+
+ returns:
+ rotated input
+ sets qh POINTSmalloc
+
+ design:
+ see qh_rotatepoints
+*/
+void qh_rotateinput(realT **rows) {
+
+ if (!qh POINTSmalloc) {
+ qh first_point= qh_copypoints(qh first_point, qh num_points, qh hull_dim);
+ qh POINTSmalloc= True;
+ }
+ qh_rotatepoints(qh first_point, qh num_points, qh hull_dim, rows);
+} /* rotateinput */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="rotatepoints">-</a>
+
+ qh_rotatepoints( points, numpoints, dim, row )
+ rotate numpoints points by a d-dim row matrix
+ assumes rows[dim] is a scratch buffer
+
+ returns:
+ rotated points in place
+
+ design:
+ for each point
+ for each coordinate
+ use row[dim] to compute partial inner product
+ for each coordinate
+ rotate by partial inner product
+*/
+void qh_rotatepoints(realT *points, int numpoints, int dim, realT **row) {
+ realT *point, *rowi, *coord= NULL, sum, *newval;
+ int i,j,k;
+
+ if (qh IStracing >= 1)
+ qh_printmatrix(qh ferr, "qh_rotatepoints: rotate points by", row, dim, dim);
+ for (point= points, j= numpoints; j--; point += dim) {
+ newval= row[dim];
+ for (i=0; i < dim; i++) {
+ rowi= row[i];
+ coord= point;
+ for (sum= 0.0, k= dim; k--; )
+ sum += *rowi++ * *coord++;
+ *(newval++)= sum;
+ }
+ for (k=dim; k--; )
+ *(--coord)= *(--newval);
+ }
+} /* rotatepoints */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="scaleinput">-</a>
+
+ qh_scaleinput()
+ scale input points using qh low_bound/high_bound
+ input points given by qh first_point, num_points, hull_dim
+ if qh POINTSmalloc, overwrites input points, else mallocs a new array
+
+ returns:
+ scales coordinates of points to low_bound[k], high_bound[k]
+ sets qh POINTSmalloc
+
+ design:
+ see qh_scalepoints
+*/
+void qh_scaleinput(void) {
+
+ if (!qh POINTSmalloc) {
+ qh first_point= qh_copypoints(qh first_point, qh num_points, qh hull_dim);
+ qh POINTSmalloc= True;
+ }
+ qh_scalepoints(qh first_point, qh num_points, qh hull_dim,
+ qh lower_bound, qh upper_bound);
+} /* scaleinput */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="scalelast">-</a>
+
+ qh_scalelast( points, numpoints, dim, low, high, newhigh )
+ scale last coordinate to [0,m] for Delaunay triangulations
+ input points given by points, numpoints, dim
+
+ returns:
+ changes scale of last coordinate from [low, high] to [0, newhigh]
+ overwrites last coordinate of each point
+ saves low/high/newhigh in qh.last_low, etc. for qh_setdelaunay()
+
+ notes:
+ when called by qh_setdelaunay, low/high may not match actual data
+
+ design:
+ compute scale and shift factors
+ apply to last coordinate of each point
+*/
+void qh_scalelast(coordT *points, int numpoints, int dim, coordT low,
+ coordT high, coordT newhigh) {
+ realT scale, shift;
+ coordT *coord;
+ int i;
+ boolT nearzero= False;
+
+ trace4((qh ferr, 4013, "qh_scalelast: scale last coordinate from [%2.2g, %2.2g] to [0,%2.2g]\n",
+ low, high, newhigh));
+ qh last_low= low;
+ qh last_high= high;
+ qh last_newhigh= newhigh;
+ scale= qh_divzero(newhigh, high - low,
+ qh MINdenom_1, &nearzero);
+ if (nearzero) {
+ if (qh DELAUNAY)
+ qh_fprintf(qh ferr, 6019, "qhull input error: can not scale last coordinate. Input is cocircular\n or cospherical. Use option 'Qz' to add a point at infinity.\n");
+ else
+ qh_fprintf(qh ferr, 6020, "qhull input error: can not scale last coordinate. New bounds [0, %2.2g] are too wide for\nexisting bounds [%2.2g, %2.2g] (width %2.2g)\n",
+ newhigh, low, high, high-low);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ shift= - low * newhigh / (high-low);
+ coord= points + dim - 1;
+ for (i=numpoints; i--; coord += dim)
+ *coord= *coord * scale + shift;
+} /* scalelast */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="scalepoints">-</a>
+
+ qh_scalepoints( points, numpoints, dim, newlows, newhighs )
+ scale points to new lowbound and highbound
+ retains old bound when newlow= -REALmax or newhigh= +REALmax
+
+ returns:
+ scaled points
+ overwrites old points
+
+ design:
+ for each coordinate
+ compute current low and high bound
+ compute scale and shift factors
+ scale all points
+ enforce new low and high bound for all points
+*/
+void qh_scalepoints(pointT *points, int numpoints, int dim,
+ realT *newlows, realT *newhighs) {
+ int i,k;
+ realT shift, scale, *coord, low, high, newlow, newhigh, mincoord, maxcoord;
+ boolT nearzero= False;
+
+ for (k=0; k < dim; k++) {
+ newhigh= newhighs[k];
+ newlow= newlows[k];
+ if (newhigh > REALmax/2 && newlow < -REALmax/2)
+ continue;
+ low= REALmax;
+ high= -REALmax;
+ for (i=numpoints, coord=points+k; i--; coord += dim) {
+ minimize_(low, *coord);
+ maximize_(high, *coord);
+ }
+ if (newhigh > REALmax/2)
+ newhigh= high;
+ if (newlow < -REALmax/2)
+ newlow= low;
+ if (qh DELAUNAY && k == dim-1 && newhigh < newlow) {
+ qh_fprintf(qh ferr, 6021, "qhull input error: 'Qb%d' or 'QB%d' inverts paraboloid since high bound %.2g < low bound %.2g\n",
+ k, k, newhigh, newlow);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ scale= qh_divzero(newhigh - newlow, high - low,
+ qh MINdenom_1, &nearzero);
+ if (nearzero) {
+ qh_fprintf(qh ferr, 6022, "qhull input error: %d'th dimension's new bounds [%2.2g, %2.2g] too wide for\nexisting bounds [%2.2g, %2.2g]\n",
+ k, newlow, newhigh, low, high);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ shift= (newlow * high - low * newhigh)/(high-low);
+ coord= points+k;
+ for (i=numpoints; i--; coord += dim)
+ *coord= *coord * scale + shift;
+ coord= points+k;
+ if (newlow < newhigh) {
+ mincoord= newlow;
+ maxcoord= newhigh;
+ }else {
+ mincoord= newhigh;
+ maxcoord= newlow;
+ }
+ for (i=numpoints; i--; coord += dim) {
+ minimize_(*coord, maxcoord); /* because of roundoff error */
+ maximize_(*coord, mincoord);
+ }
+ trace0((qh ferr, 10, "qh_scalepoints: scaled %d'th coordinate [%2.2g, %2.2g] to [%.2g, %.2g] for %d points by %2.2g and shifted %2.2g\n",
+ k, low, high, newlow, newhigh, numpoints, scale, shift));
+ }
+} /* scalepoints */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="setdelaunay">-</a>
+
+ qh_setdelaunay( dim, count, points )
+ project count points to dim-d paraboloid for Delaunay triangulation
+
+ dim is one more than the dimension of the input set
+ assumes dim is at least 3 (i.e., at least a 2-d Delaunay triangulation)
+
+ points is a dim*count realT array. The first dim-1 coordinates
+ are the coordinates of the first input point. array[dim] is
+ the first coordinate of the second input point. array[2*dim] is
+ the first coordinate of the third input point.
+
+ if qh.last_low defined (i.e., 'Qbb' called qh_scalelast)
+ calls qh_scalelast to scale the last coordinate the same as the other points
+
+ returns:
+ for each point
+ sets point[dim-1] to sum of squares of coordinates
+ scale points to 'Qbb' if needed
+
+ notes:
+ to project one point, use
+ qh_setdelaunay(qh hull_dim, 1, point)
+
+ Do not use options 'Qbk', 'QBk', or 'QbB' since they scale
+ the coordinates after the original projection.
+
+*/
+void qh_setdelaunay(int dim, int count, pointT *points) {
+ int i, k;
+ coordT *coordp, coord;
+ realT paraboloid;
+
+ trace0((qh ferr, 11, "qh_setdelaunay: project %d points to paraboloid for Delaunay triangulation\n", count));
+ coordp= points;
+ for (i=0; i < count; i++) {
+ coord= *coordp++;
+ paraboloid= coord*coord;
+ for (k=dim-2; k--; ) {
+ coord= *coordp++;
+ paraboloid += coord*coord;
+ }
+ *coordp++ = paraboloid;
+ }
+ if (qh last_low < REALmax/2)
+ qh_scalelast(points, count, dim, qh last_low, qh last_high, qh last_newhigh);
+} /* setdelaunay */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="sethalfspace">-</a>
+
+ qh_sethalfspace( dim, coords, nextp, normal, offset, feasible )
+ set point to dual of halfspace relative to feasible point
+ halfspace is normal coefficients and offset.
+
+ returns:
+ false and prints error if feasible point is outside of hull
+ overwrites coordinates for point at dim coords
+ nextp= next point (coords)
+ does not call qh_errexit
+
+ design:
+ compute distance from feasible point to halfspace
+ divide each normal coefficient by -dist
+*/
+boolT qh_sethalfspace(int dim, coordT *coords, coordT **nextp,
+ coordT *normal, coordT *offset, coordT *feasible) {
+ coordT *normp= normal, *feasiblep= feasible, *coordp= coords;
+ realT dist;
+ realT r; /*bug fix*/
+ int k;
+ boolT zerodiv;
+
+ dist= *offset;
+ for (k=dim; k--; )
+ dist += *(normp++) * *(feasiblep++);
+ if (dist > 0)
+ goto LABELerroroutside;
+ normp= normal;
+ if (dist < -qh MINdenom) {
+ for (k=dim; k--; )
+ *(coordp++)= *(normp++) / -dist;
+ }else {
+ for (k=dim; k--; ) {
+ *(coordp++)= qh_divzero(*(normp++), -dist, qh MINdenom_1, &zerodiv);
+ if (zerodiv)
+ goto LABELerroroutside;
+ }
+ }
+ *nextp= coordp;
+ if (qh IStracing >= 4) {
+ qh_fprintf(qh ferr, 8021, "qh_sethalfspace: halfspace at offset %6.2g to point: ", *offset);
+ for (k=dim, coordp=coords; k--; ) {
+ r= *coordp++;
+ qh_fprintf(qh ferr, 8022, " %6.2g", r);
+ }
+ qh_fprintf(qh ferr, 8023, "\n");
+ }
+ return True;
+LABELerroroutside:
+ feasiblep= feasible;
+ normp= normal;
+ qh_fprintf(qh ferr, 6023, "qhull input error: feasible point is not clearly inside halfspace\nfeasible point: ");
+ for (k=dim; k--; )
+ qh_fprintf(qh ferr, 8024, qh_REAL_1, r=*(feasiblep++));
+ qh_fprintf(qh ferr, 8025, "\n halfspace: ");
+ for (k=dim; k--; )
+ qh_fprintf(qh ferr, 8026, qh_REAL_1, r=*(normp++));
+ qh_fprintf(qh ferr, 8027, "\n at offset: ");
+ qh_fprintf(qh ferr, 8028, qh_REAL_1, *offset);
+ qh_fprintf(qh ferr, 8029, " and distance: ");
+ qh_fprintf(qh ferr, 8030, qh_REAL_1, dist);
+ qh_fprintf(qh ferr, 8031, "\n");
+ return False;
+} /* sethalfspace */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="sethalfspace_all">-</a>
+
+ qh_sethalfspace_all( dim, count, halfspaces, feasible )
+ generate dual for halfspace intersection with feasible point
+ array of count halfspaces
+ each halfspace is normal coefficients followed by offset
+ the origin is inside the halfspace if the offset is negative
+ feasible is a point inside all halfspaces (http://www.qhull.org/html/qhalf.htm#notes)
+
+ returns:
+ malloc'd array of count X dim-1 points
+
+ notes:
+ call before qh_init_B or qh_initqhull_globals
+ free memory when done
+ unused/untested code: please email bradb@shore.net if this works ok for you
+ if using option 'Fp', qh->feasible_point must be set (e.g., to 'feasible')
+ qh->feasible_point is a malloc'd array that is freed by qh_freebuffers.
+
+ design:
+ see qh_sethalfspace
+*/
+coordT *qh_sethalfspace_all(int dim, int count, coordT *halfspaces, pointT *feasible) {
+ int i, newdim;
+ pointT *newpoints;
+ coordT *coordp, *normalp, *offsetp;
+
+ trace0((qh ferr, 12, "qh_sethalfspace_all: compute dual for halfspace intersection\n"));
+ newdim= dim - 1;
+ if (!(newpoints=(coordT*)qh_malloc(count*newdim*sizeof(coordT)))){
+ qh_fprintf(qh ferr, 6024, "qhull error: insufficient memory to compute dual of %d halfspaces\n",
+ count);
+ qh_errexit(qh_ERRmem, NULL, NULL);
+ }
+ coordp= newpoints;
+ normalp= halfspaces;
+ for (i=0; i < count; i++) {
+ offsetp= normalp + newdim;
+ if (!qh_sethalfspace(newdim, coordp, &coordp, normalp, offsetp, feasible)) {
+ qh_free(newpoints); /* feasible is not inside halfspace as reported by qh_sethalfspace */
+ qh_fprintf(qh ferr, 8032, "The halfspace was at index %d\n", i);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ normalp= offsetp + 1;
+ }
+ return newpoints;
+} /* sethalfspace_all */
+
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="sharpnewfacets">-</a>
+
+ qh_sharpnewfacets()
+
+ returns:
+ true if could be an acute angle (facets in different quadrants)
+
+ notes:
+ for qh_findbest
+
+ design:
+ for all facets on qh.newfacet_list
+ if two facets are in different quadrants
+ set issharp
+*/
+boolT qh_sharpnewfacets(void) {
+ facetT *facet;
+ boolT issharp = False;
+ int *quadrant, k;
+
+ quadrant= (int*)qh_memalloc(qh hull_dim * sizeof(int));
+ FORALLfacet_(qh newfacet_list) {
+ if (facet == qh newfacet_list) {
+ for (k=qh hull_dim; k--; )
+ quadrant[ k]= (facet->normal[ k] > 0);
+ }else {
+ for (k=qh hull_dim; k--; ) {
+ if (quadrant[ k] != (facet->normal[ k] > 0)) {
+ issharp= True;
+ break;
+ }
+ }
+ }
+ if (issharp)
+ break;
+ }
+ qh_memfree( quadrant, qh hull_dim * sizeof(int));
+ trace3((qh ferr, 3001, "qh_sharpnewfacets: %d\n", issharp));
+ return issharp;
+} /* sharpnewfacets */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="voronoi_center">-</a>
+
+ qh_voronoi_center( dim, points )
+ return Voronoi center for a set of points
+ dim is the orginal dimension of the points
+ gh.gm_matrix/qh.gm_row are scratch buffers
+
+ returns:
+ center as a temporary point (qh_memalloc)
+ if non-simplicial,
+ returns center for max simplex of points
+
+ notes:
+ only called by qh_facetcenter
+ from Bowyer & Woodwark, A Programmer's Geometry, 1983, p. 65
+
+ design:
+ if non-simplicial
+ determine max simplex for points
+ translate point0 of simplex to origin
+ compute sum of squares of diagonal
+ compute determinate
+ compute Voronoi center (see Bowyer & Woodwark)
+*/
+pointT *qh_voronoi_center(int dim, setT *points) {
+ pointT *point, **pointp, *point0;
+ pointT *center= (pointT*)qh_memalloc(qh center_size);
+ setT *simplex;
+ int i, j, k, size= qh_setsize(points);
+ coordT *gmcoord;
+ realT *diffp, sum2, *sum2row, *sum2p, det, factor;
+ boolT nearzero, infinite;
+
+ if (size == dim+1)
+ simplex= points;
+ else if (size < dim+1) {
+ qh_memfree(center, qh center_size);
+ qh_fprintf(qh ferr, 6025, "qhull internal error (qh_voronoi_center):\n need at least %d points to construct a Voronoi center\n",
+ dim+1);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ simplex= points; /* never executed -- avoids warning */
+ }else {
+ simplex= qh_settemp(dim+1);
+ qh_maxsimplex(dim, points, NULL, 0, &simplex);
+ }
+ point0= SETfirstt_(simplex, pointT);
+ gmcoord= qh gm_matrix;
+ for (k=0; k < dim; k++) {
+ qh gm_row[k]= gmcoord;
+ FOREACHpoint_(simplex) {
+ if (point != point0)
+ *(gmcoord++)= point[k] - point0[k];
+ }
+ }
+ sum2row= gmcoord;
+ for (i=0; i < dim; i++) {
+ sum2= 0.0;
+ for (k=0; k < dim; k++) {
+ diffp= qh gm_row[k] + i;
+ sum2 += *diffp * *diffp;
+ }
+ *(gmcoord++)= sum2;
+ }
+ det= qh_determinant(qh gm_row, dim, &nearzero);
+ factor= qh_divzero(0.5, det, qh MINdenom, &infinite);
+ if (infinite) {
+ for (k=dim; k--; )
+ center[k]= qh_INFINITE;
+ if (qh IStracing)
+ qh_printpoints(qh ferr, "qh_voronoi_center: at infinity for ", simplex);
+ }else {
+ for (i=0; i < dim; i++) {
+ gmcoord= qh gm_matrix;
+ sum2p= sum2row;
+ for (k=0; k < dim; k++) {
+ qh gm_row[k]= gmcoord;
+ if (k == i) {
+ for (j=dim; j--; )
+ *(gmcoord++)= *sum2p++;
+ }else {
+ FOREACHpoint_(simplex) {
+ if (point != point0)
+ *(gmcoord++)= point[k] - point0[k];
+ }
+ }
+ }
+ center[i]= qh_determinant(qh gm_row, dim, &nearzero)*factor + point0[i];
+ }
+#ifndef qh_NOtrace
+ if (qh IStracing >= 3) {
+ qh_fprintf(qh ferr, 8033, "qh_voronoi_center: det %2.2g factor %2.2g ", det, factor);
+ qh_printmatrix(qh ferr, "center:", &center, 1, dim);
+ if (qh IStracing >= 5) {
+ qh_printpoints(qh ferr, "points", simplex);
+ FOREACHpoint_(simplex)
+ qh_fprintf(qh ferr, 8034, "p%d dist %.2g, ", qh_pointid(point),
+ qh_pointdist(point, center, dim));
+ qh_fprintf(qh ferr, 8035, "\n");
+ }
+ }
+#endif
+ }
+ if (simplex != points)
+ qh_settempfree(&simplex);
+ return center;
+} /* voronoi_center */
+
diff --git a/xs/src/qhull/src/libqhull/global.c b/xs/src/qhull/src/libqhull/global.c
new file mode 100644
index 000000000..0328fea7b
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/global.c
@@ -0,0 +1,2217 @@
+
+/*<html><pre> -<a href="qh-globa.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ global.c
+ initializes all the globals of the qhull application
+
+ see README
+
+ see libqhull.h for qh.globals and function prototypes
+
+ see qhull_a.h for internal functions
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/global.c#17 $$Change: 2066 $
+ $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+ */
+
+#include "qhull_a.h"
+
+/*========= qh definition -- globals defined in libqhull.h =======================*/
+
+#if qh_QHpointer
+qhT *qh_qh= NULL; /* pointer to all global variables */
+#else
+qhT qh_qh; /* all global variables.
+ Add "= {0}" if this causes a compiler error.
+ Also qh_qhstat in stat.c and qhmem in mem.c. */
+#endif
+
+/*-<a href ="qh-globa.htm#TOC"
+ >--------------------------------</a><a name="qh_version">-</a>
+
+ qh_version
+ version string by year and date
+ qh_version2 for Unix users and -V
+
+ the revision increases on code changes only
+
+ notes:
+ change date: Changes.txt, Announce.txt, index.htm, README.txt,
+ qhull-news.html, Eudora signatures, CMakeLists.txt
+ change version: README.txt, qh-get.htm, File_id.diz, Makefile.txt, CMakeLists.txt
+ check that CmakeLists @version is the same as qh_version2
+ change year: Copying.txt
+ check download size
+ recompile user_eg.c, rbox.c, libqhull.c, qconvex.c, qdelaun.c qvoronoi.c, qhalf.c, testqset.c
+*/
+
+const char qh_version[]= "2015.2 2016/01/18";
+const char qh_version2[]= "qhull 7.2.0 (2015.2 2016/01/18)";
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="appendprint">-</a>
+
+ qh_appendprint( printFormat )
+ append printFormat to qh.PRINTout unless already defined
+*/
+void qh_appendprint(qh_PRINT format) {
+ int i;
+
+ for (i=0; i < qh_PRINTEND; i++) {
+ if (qh PRINTout[i] == format && format != qh_PRINTqhull)
+ break;
+ if (!qh PRINTout[i]) {
+ qh PRINTout[i]= format;
+ break;
+ }
+ }
+} /* appendprint */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="checkflags">-</a>
+
+ qh_checkflags( commandStr, hiddenFlags )
+ errors if commandStr contains hiddenFlags
+ hiddenFlags starts and ends with a space and is space delimited (checked)
+
+ notes:
+ ignores first word (e.g., "qconvex i")
+ use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
+
+ see:
+ qh_initflags() initializes Qhull according to commandStr
+*/
+void qh_checkflags(char *command, char *hiddenflags) {
+ char *s= command, *t, *chkerr; /* qh_skipfilename is non-const */
+ char key, opt, prevopt;
+ char chkkey[]= " ";
+ char chkopt[]= " ";
+ char chkopt2[]= " ";
+ boolT waserr= False;
+
+ if (*hiddenflags != ' ' || hiddenflags[strlen(hiddenflags)-1] != ' ') {
+ qh_fprintf(qh ferr, 6026, "qhull error (qh_checkflags): hiddenflags must start and end with a space: \"%s\"", hiddenflags);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (strpbrk(hiddenflags, ",\n\r\t")) {
+ qh_fprintf(qh ferr, 6027, "qhull error (qh_checkflags): hiddenflags contains commas, newlines, or tabs: \"%s\"", hiddenflags);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ while (*s && !isspace(*s)) /* skip program name */
+ s++;
+ while (*s) {
+ while (*s && isspace(*s))
+ s++;
+ if (*s == '-')
+ s++;
+ if (!*s)
+ break;
+ key = *s++;
+ chkerr = NULL;
+ if (key == 'T' && (*s == 'I' || *s == 'O')) { /* TI or TO 'file name' */
+ s= qh_skipfilename(++s);
+ continue;
+ }
+ chkkey[1]= key;
+ if (strstr(hiddenflags, chkkey)) {
+ chkerr= chkkey;
+ }else if (isupper(key)) {
+ opt= ' ';
+ prevopt= ' ';
+ chkopt[1]= key;
+ chkopt2[1]= key;
+ while (!chkerr && *s && !isspace(*s)) {
+ opt= *s++;
+ if (isalpha(opt)) {
+ chkopt[2]= opt;
+ if (strstr(hiddenflags, chkopt))
+ chkerr= chkopt;
+ if (prevopt != ' ') {
+ chkopt2[2]= prevopt;
+ chkopt2[3]= opt;
+ if (strstr(hiddenflags, chkopt2))
+ chkerr= chkopt2;
+ }
+ }else if (key == 'Q' && isdigit(opt) && prevopt != 'b'
+ && (prevopt == ' ' || islower(prevopt))) {
+ chkopt[2]= opt;
+ if (strstr(hiddenflags, chkopt))
+ chkerr= chkopt;
+ }else {
+ qh_strtod(s-1, &t);
+ if (s < t)
+ s= t;
+ }
+ prevopt= opt;
+ }
+ }
+ if (chkerr) {
+ *chkerr= '\'';
+ chkerr[strlen(chkerr)-1]= '\'';
+ qh_fprintf(qh ferr, 6029, "qhull error: option %s is not used with this program.\n It may be used with qhull.\n", chkerr);
+ waserr= True;
+ }
+ }
+ if (waserr)
+ qh_errexit(qh_ERRinput, NULL, NULL);
+} /* checkflags */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="qh_clear_outputflags">-</a>
+
+ qh_clear_outputflags()
+ Clear output flags for QhullPoints
+*/
+void qh_clear_outputflags(void) {
+ int i,k;
+
+ qh ANNOTATEoutput= False;
+ qh DOintersections= False;
+ qh DROPdim= -1;
+ qh FORCEoutput= False;
+ qh GETarea= False;
+ qh GOODpoint= 0;
+ qh GOODpointp= NULL;
+ qh GOODthreshold= False;
+ qh GOODvertex= 0;
+ qh GOODvertexp= NULL;
+ qh IStracing= 0;
+ qh KEEParea= False;
+ qh KEEPmerge= False;
+ qh KEEPminArea= REALmax;
+ qh PRINTcentrums= False;
+ qh PRINTcoplanar= False;
+ qh PRINTdots= False;
+ qh PRINTgood= False;
+ qh PRINTinner= False;
+ qh PRINTneighbors= False;
+ qh PRINTnoplanes= False;
+ qh PRINToptions1st= False;
+ qh PRINTouter= False;
+ qh PRINTprecision= True;
+ qh PRINTridges= False;
+ qh PRINTspheres= False;
+ qh PRINTstatistics= False;
+ qh PRINTsummary= False;
+ qh PRINTtransparent= False;
+ qh SPLITthresholds= False;
+ qh TRACElevel= 0;
+ qh TRInormals= False;
+ qh USEstdout= False;
+ qh VERIFYoutput= False;
+ for (k=qh input_dim+1; k--; ) { /* duplicated in qh_initqhull_buffers and qh_clear_outputflags */
+ qh lower_threshold[k]= -REALmax;
+ qh upper_threshold[k]= REALmax;
+ qh lower_bound[k]= -REALmax;
+ qh upper_bound[k]= REALmax;
+ }
+
+ for (i=0; i < qh_PRINTEND; i++) {
+ qh PRINTout[i]= qh_PRINTnone;
+ }
+
+ if (!qh qhull_commandsiz2)
+ qh qhull_commandsiz2= (int)strlen(qh qhull_command); /* WARN64 */
+ else {
+ qh qhull_command[qh qhull_commandsiz2]= '\0';
+ }
+ if (!qh qhull_optionsiz2)
+ qh qhull_optionsiz2= (int)strlen(qh qhull_options); /* WARN64 */
+ else {
+ qh qhull_options[qh qhull_optionsiz2]= '\0';
+ qh qhull_optionlen= qh_OPTIONline; /* start a new line */
+ }
+} /* clear_outputflags */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="clock">-</a>
+
+ qh_clock()
+ return user CPU time in 100ths (qh_SECtick)
+ only defined for qh_CLOCKtype == 2
+
+ notes:
+ use first value to determine time 0
+ from Stevens '92 8.15
+*/
+unsigned long qh_clock(void) {
+
+#if (qh_CLOCKtype == 2)
+ struct tms time;
+ static long clktck; /* initialized first call and never updated */
+ double ratio, cpu;
+ unsigned long ticks;
+
+ if (!clktck) {
+ if ((clktck= sysconf(_SC_CLK_TCK)) < 0) {
+ qh_fprintf(qh ferr, 6030, "qhull internal error (qh_clock): sysconf() failed. Use qh_CLOCKtype 1 in user.h\n");
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ }
+ if (times(&time) == -1) {
+ qh_fprintf(qh ferr, 6031, "qhull internal error (qh_clock): times() failed. Use qh_CLOCKtype 1 in user.h\n");
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ ratio= qh_SECticks / (double)clktck;
+ ticks= time.tms_utime * ratio;
+ return ticks;
+#else
+ qh_fprintf(qh ferr, 6032, "qhull internal error (qh_clock): use qh_CLOCKtype 2 in user.h\n");
+ qh_errexit(qh_ERRqhull, NULL, NULL); /* never returns */
+ return 0;
+#endif
+} /* clock */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="freebuffers">-</a>
+
+ qh_freebuffers()
+ free up global memory buffers
+
+ notes:
+ must match qh_initbuffers()
+*/
+void qh_freebuffers(void) {
+
+ trace5((qh ferr, 5001, "qh_freebuffers: freeing up global memory buffers\n"));
+ /* allocated by qh_initqhull_buffers */
+ qh_memfree(qh NEARzero, qh hull_dim * sizeof(realT));
+ qh_memfree(qh lower_threshold, (qh input_dim+1) * sizeof(realT));
+ qh_memfree(qh upper_threshold, (qh input_dim+1) * sizeof(realT));
+ qh_memfree(qh lower_bound, (qh input_dim+1) * sizeof(realT));
+ qh_memfree(qh upper_bound, (qh input_dim+1) * sizeof(realT));
+ qh_memfree(qh gm_matrix, (qh hull_dim+1) * qh hull_dim * sizeof(coordT));
+ qh_memfree(qh gm_row, (qh hull_dim+1) * sizeof(coordT *));
+ qh NEARzero= qh lower_threshold= qh upper_threshold= NULL;
+ qh lower_bound= qh upper_bound= NULL;
+ qh gm_matrix= NULL;
+ qh gm_row= NULL;
+ qh_setfree(&qh other_points);
+ qh_setfree(&qh del_vertices);
+ qh_setfree(&qh coplanarfacetset);
+ if (qh line) /* allocated by qh_readinput, freed if no error */
+ qh_free(qh line);
+ if (qh half_space)
+ qh_free(qh half_space);
+ if (qh temp_malloc)
+ qh_free(qh temp_malloc);
+ if (qh feasible_point) /* allocated by qh_readfeasible */
+ qh_free(qh feasible_point);
+ if (qh feasible_string) /* allocated by qh_initflags */
+ qh_free(qh feasible_string);
+ qh line= qh feasible_string= NULL;
+ qh half_space= qh feasible_point= qh temp_malloc= NULL;
+ /* usually allocated by qh_readinput */
+ if (qh first_point && qh POINTSmalloc) {
+ qh_free(qh first_point);
+ qh first_point= NULL;
+ }
+ if (qh input_points && qh input_malloc) { /* set by qh_joggleinput */
+ qh_free(qh input_points);
+ qh input_points= NULL;
+ }
+ trace5((qh ferr, 5002, "qh_freebuffers: finished\n"));
+} /* freebuffers */
+
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="freebuild">-</a>
+
+ qh_freebuild( allmem )
+ free global memory used by qh_initbuild and qh_buildhull
+ if !allmem,
+ does not free short memory (e.g., facetT, freed by qh_memfreeshort)
+
+ design:
+ free centrums
+ free each vertex
+ mark unattached ridges
+ for each facet
+ free ridges
+ free outside set, coplanar set, neighbor set, ridge set, vertex set
+ free facet
+ free hash table
+ free interior point
+ free merge set
+ free temporary sets
+*/
+void qh_freebuild(boolT allmem) {
+ facetT *facet;
+ vertexT *vertex;
+ ridgeT *ridge, **ridgep;
+ mergeT *merge, **mergep;
+
+ trace1((qh ferr, 1005, "qh_freebuild: free memory from qh_inithull and qh_buildhull\n"));
+ if (qh del_vertices)
+ qh_settruncate(qh del_vertices, 0);
+ if (allmem) {
+ while ((vertex= qh vertex_list)) {
+ if (vertex->next)
+ qh_delvertex(vertex);
+ else {
+ qh_memfree(vertex, (int)sizeof(vertexT));
+ qh newvertex_list= qh vertex_list= NULL;
+ }
+ }
+ }else if (qh VERTEXneighbors) {
+ FORALLvertices
+ qh_setfreelong(&(vertex->neighbors));
+ }
+ qh VERTEXneighbors= False;
+ qh GOODclosest= NULL;
+ if (allmem) {
+ FORALLfacets {
+ FOREACHridge_(facet->ridges)
+ ridge->seen= False;
+ }
+ FORALLfacets {
+ if (facet->visible) {
+ FOREACHridge_(facet->ridges) {
+ if (!otherfacet_(ridge, facet)->visible)
+ ridge->seen= True; /* an unattached ridge */
+ }
+ }
+ }
+ while ((facet= qh facet_list)) {
+ FOREACHridge_(facet->ridges) {
+ if (ridge->seen) {
+ qh_setfree(&(ridge->vertices));
+ qh_memfree(ridge, (int)sizeof(ridgeT));
+ }else
+ ridge->seen= True;
+ }
+ qh_setfree(&(facet->outsideset));
+ qh_setfree(&(facet->coplanarset));
+ qh_setfree(&(facet->neighbors));
+ qh_setfree(&(facet->ridges));
+ qh_setfree(&(facet->vertices));
+ if (facet->next)
+ qh_delfacet(facet);
+ else {
+ qh_memfree(facet, (int)sizeof(facetT));
+ qh visible_list= qh newfacet_list= qh facet_list= NULL;
+ }
+ }
+ }else {
+ FORALLfacets {
+ qh_setfreelong(&(facet->outsideset));
+ qh_setfreelong(&(facet->coplanarset));
+ if (!facet->simplicial) {
+ qh_setfreelong(&(facet->neighbors));
+ qh_setfreelong(&(facet->ridges));
+ qh_setfreelong(&(facet->vertices));
+ }
+ }
+ }
+ qh_setfree(&(qh hash_table));
+ qh_memfree(qh interior_point, qh normal_size);
+ qh interior_point= NULL;
+ FOREACHmerge_(qh facet_mergeset) /* usually empty */
+ qh_memfree(merge, (int)sizeof(mergeT));
+ qh facet_mergeset= NULL; /* temp set */
+ qh degen_mergeset= NULL; /* temp set */
+ qh_settempfree_all();
+} /* freebuild */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="freeqhull">-</a>
+
+ qh_freeqhull( allmem )
+ see qh_freeqhull2
+ if qh_QHpointer, frees qh_qh
+*/
+void qh_freeqhull(boolT allmem) {
+ qh_freeqhull2(allmem);
+#if qh_QHpointer
+ qh_free(qh_qh);
+ qh_qh= NULL;
+#endif
+}
+
+/*-<a href="qh-globa.htm#TOC"
+>-------------------------------</a><a name="freeqhull2">-</a>
+
+qh_freeqhull2( allmem )
+ free global memory and set qhT to 0
+ if !allmem,
+ does not free short memory (freed by qh_memfreeshort unless qh_NOmem)
+
+notes:
+ sets qh.NOerrexit in case caller forgets to
+ Does not throw errors
+
+see:
+ see qh_initqhull_start2()
+
+design:
+ free global and temporary memory from qh_initbuild and qh_buildhull
+ free buffers
+ free statistics
+*/
+void qh_freeqhull2(boolT allmem) {
+
+ qh NOerrexit= True; /* no more setjmp since called at exit and ~QhullQh */
+ trace1((qh ferr, 1006, "qh_freeqhull: free global memory\n"));
+ qh_freebuild(allmem);
+ qh_freebuffers();
+ qh_freestatistics();
+#if qh_QHpointer
+ memset((char *)qh_qh, 0, sizeof(qhT));
+ /* qh_qh freed by caller, qh_freeqhull() */
+#else
+ memset((char *)&qh_qh, 0, sizeof(qhT));
+#endif
+ qh NOerrexit= True;
+} /* freeqhull2 */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="init_A">-</a>
+
+ qh_init_A( infile, outfile, errfile, argc, argv )
+ initialize memory and stdio files
+ convert input options to option string (qh.qhull_command)
+
+ notes:
+ infile may be NULL if qh_readpoints() is not called
+
+ errfile should always be defined. It is used for reporting
+ errors. outfile is used for output and format options.
+
+ argc/argv may be 0/NULL
+
+ called before error handling initialized
+ qh_errexit() may not be used
+*/
+void qh_init_A(FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]) {
+ qh_meminit(errfile);
+ qh_initqhull_start(infile, outfile, errfile);
+ qh_init_qhull_command(argc, argv);
+} /* init_A */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="init_B">-</a>
+
+ qh_init_B( points, numpoints, dim, ismalloc )
+ initialize globals for points array
+
+ points has numpoints dim-dimensional points
+ points[0] is the first coordinate of the first point
+ points[1] is the second coordinate of the first point
+ points[dim] is the first coordinate of the second point
+
+ ismalloc=True
+ Qhull will call qh_free(points) on exit or input transformation
+ ismalloc=False
+ Qhull will allocate a new point array if needed for input transformation
+
+ qh.qhull_command
+ is the option string.
+ It is defined by qh_init_B(), qh_qhull_command(), or qh_initflags
+
+ returns:
+ if qh.PROJECTinput or (qh.DELAUNAY and qh.PROJECTdelaunay)
+ projects the input to a new point array
+
+ if qh.DELAUNAY,
+ qh.hull_dim is increased by one
+ if qh.ATinfinity,
+ qh_projectinput adds point-at-infinity for Delaunay tri.
+
+ if qh.SCALEinput
+ changes the upper and lower bounds of the input, see qh_scaleinput()
+
+ if qh.ROTATEinput
+ rotates the input by a random rotation, see qh_rotateinput()
+ if qh.DELAUNAY
+ rotates about the last coordinate
+
+ notes:
+ called after points are defined
+ qh_errexit() may be used
+*/
+void qh_init_B(coordT *points, int numpoints, int dim, boolT ismalloc) {
+ qh_initqhull_globals(points, numpoints, dim, ismalloc);
+ if (qhmem.LASTsize == 0)
+ qh_initqhull_mem();
+ /* mem.c and qset.c are initialized */
+ qh_initqhull_buffers();
+ qh_initthresholds(qh qhull_command);
+ if (qh PROJECTinput || (qh DELAUNAY && qh PROJECTdelaunay))
+ qh_projectinput();
+ if (qh SCALEinput)
+ qh_scaleinput();
+ if (qh ROTATErandom >= 0) {
+ qh_randommatrix(qh gm_matrix, qh hull_dim, qh gm_row);
+ if (qh DELAUNAY) {
+ int k, lastk= qh hull_dim-1;
+ for (k=0; k < lastk; k++) {
+ qh gm_row[k][lastk]= 0.0;
+ qh gm_row[lastk][k]= 0.0;
+ }
+ qh gm_row[lastk][lastk]= 1.0;
+ }
+ qh_gram_schmidt(qh hull_dim, qh gm_row);
+ qh_rotateinput(qh gm_row);
+ }
+} /* init_B */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="init_qhull_command">-</a>
+
+ qh_init_qhull_command( argc, argv )
+ build qh.qhull_command from argc/argv
+ Calls qh_exit if qhull_command is too short
+
+ returns:
+ a space-delimited string of options (just as typed)
+
+ notes:
+ makes option string easy to input and output
+
+ argc/argv may be 0/NULL
+*/
+void qh_init_qhull_command(int argc, char *argv[]) {
+
+ if (!qh_argv_to_command(argc, argv, qh qhull_command, (int)sizeof(qh qhull_command))){
+ /* Assumes qh.ferr is defined. */
+ qh_fprintf(qh ferr, 6033, "qhull input error: more than %d characters in command line\n",
+ (int)sizeof(qh qhull_command));
+ qh_exit(qh_ERRinput); /* error reported, can not use qh_errexit */
+ }
+} /* init_qhull_command */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="initflags">-</a>
+
+ qh_initflags( commandStr )
+ set flags and initialized constants from commandStr
+ calls qh_exit() if qh->NOerrexit
+
+ returns:
+ sets qh.qhull_command to command if needed
+
+ notes:
+ ignores first word (e.g., "qhull d")
+ use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
+
+ see:
+ qh_initthresholds() continues processing of 'Pdn' and 'PDn'
+ 'prompt' in unix.c for documentation
+
+ design:
+ for each space-delimited option group
+ if top-level option
+ check syntax
+ append appropriate option to option string
+ set appropriate global variable or append printFormat to print options
+ else
+ for each sub-option
+ check syntax
+ append appropriate option to option string
+ set appropriate global variable or append printFormat to print options
+*/
+void qh_initflags(char *command) {
+ int k, i, lastproject;
+ char *s= command, *t, *prev_s, *start, key;
+ boolT isgeom= False, wasproject;
+ realT r;
+
+ if(qh NOerrexit){/* without this comment, segfault in gcc 4.4.0 mingw32 */
+ qh_fprintf(qh ferr, 6245, "qhull initflags error: qh.NOerrexit was not cleared before calling qh_initflags(). It should be cleared after setjmp(). Exit qhull.");
+ qh_exit(6245);
+ }
+ if (command <= &qh qhull_command[0] || command > &qh qhull_command[0] + sizeof(qh qhull_command)) {
+ if (command != &qh qhull_command[0]) {
+ *qh qhull_command= '\0';
+ strncat(qh qhull_command, command, sizeof(qh qhull_command)-strlen(qh qhull_command)-1);
+ }
+ while (*s && !isspace(*s)) /* skip program name */
+ s++;
+ }
+ while (*s) {
+ while (*s && isspace(*s))
+ s++;
+ if (*s == '-')
+ s++;
+ if (!*s)
+ break;
+ prev_s= s;
+ switch (*s++) {
+ case 'd':
+ qh_option("delaunay", NULL, NULL);
+ qh DELAUNAY= True;
+ break;
+ case 'f':
+ qh_option("facets", NULL, NULL);
+ qh_appendprint(qh_PRINTfacets);
+ break;
+ case 'i':
+ qh_option("incidence", NULL, NULL);
+ qh_appendprint(qh_PRINTincidences);
+ break;
+ case 'm':
+ qh_option("mathematica", NULL, NULL);
+ qh_appendprint(qh_PRINTmathematica);
+ break;
+ case 'n':
+ qh_option("normals", NULL, NULL);
+ qh_appendprint(qh_PRINTnormals);
+ break;
+ case 'o':
+ qh_option("offFile", NULL, NULL);
+ qh_appendprint(qh_PRINToff);
+ break;
+ case 'p':
+ qh_option("points", NULL, NULL);
+ qh_appendprint(qh_PRINTpoints);
+ break;
+ case 's':
+ qh_option("summary", NULL, NULL);
+ qh PRINTsummary= True;
+ break;
+ case 'v':
+ qh_option("voronoi", NULL, NULL);
+ qh VORONOI= True;
+ qh DELAUNAY= True;
+ break;
+ case 'A':
+ if (!isdigit(*s) && *s != '.' && *s != '-')
+ qh_fprintf(qh ferr, 7002, "qhull warning: no maximum cosine angle given for option 'An'. Ignored.\n");
+ else {
+ if (*s == '-') {
+ qh premerge_cos= -qh_strtod(s, &s);
+ qh_option("Angle-premerge-", NULL, &qh premerge_cos);
+ qh PREmerge= True;
+ }else {
+ qh postmerge_cos= qh_strtod(s, &s);
+ qh_option("Angle-postmerge", NULL, &qh postmerge_cos);
+ qh POSTmerge= True;
+ }
+ qh MERGING= True;
+ }
+ break;
+ case 'C':
+ if (!isdigit(*s) && *s != '.' && *s != '-')
+ qh_fprintf(qh ferr, 7003, "qhull warning: no centrum radius given for option 'Cn'. Ignored.\n");
+ else {
+ if (*s == '-') {
+ qh premerge_centrum= -qh_strtod(s, &s);
+ qh_option("Centrum-premerge-", NULL, &qh premerge_centrum);
+ qh PREmerge= True;
+ }else {
+ qh postmerge_centrum= qh_strtod(s, &s);
+ qh_option("Centrum-postmerge", NULL, &qh postmerge_centrum);
+ qh POSTmerge= True;
+ }
+ qh MERGING= True;
+ }
+ break;
+ case 'E':
+ if (*s == '-')
+ qh_fprintf(qh ferr, 7004, "qhull warning: negative maximum roundoff given for option 'An'. Ignored.\n");
+ else if (!isdigit(*s))
+ qh_fprintf(qh ferr, 7005, "qhull warning: no maximum roundoff given for option 'En'. Ignored.\n");
+ else {
+ qh DISTround= qh_strtod(s, &s);
+ qh_option("Distance-roundoff", NULL, &qh DISTround);
+ qh SETroundoff= True;
+ }
+ break;
+ case 'H':
+ start= s;
+ qh HALFspace= True;
+ qh_strtod(s, &t);
+ while (t > s) {
+ if (*t && !isspace(*t)) {
+ if (*t == ',')
+ t++;
+ else
+ qh_fprintf(qh ferr, 7006, "qhull warning: origin for Halfspace intersection should be 'Hn,n,n,...'\n");
+ }
+ s= t;
+ qh_strtod(s, &t);
+ }
+ if (start < t) {
+ if (!(qh feasible_string= (char*)calloc((size_t)(t-start+1), (size_t)1))) {
+ qh_fprintf(qh ferr, 6034, "qhull error: insufficient memory for 'Hn,n,n'\n");
+ qh_errexit(qh_ERRmem, NULL, NULL);
+ }
+ strncpy(qh feasible_string, start, (size_t)(t-start));
+ qh_option("Halfspace-about", NULL, NULL);
+ qh_option(qh feasible_string, NULL, NULL);
+ }else
+ qh_option("Halfspace", NULL, NULL);
+ break;
+ case 'R':
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 7007, "qhull warning: missing random perturbation for option 'Rn'. Ignored\n");
+ else {
+ qh RANDOMfactor= qh_strtod(s, &s);
+ qh_option("Random_perturb", NULL, &qh RANDOMfactor);
+ qh RANDOMdist= True;
+ }
+ break;
+ case 'V':
+ if (!isdigit(*s) && *s != '-')
+ qh_fprintf(qh ferr, 7008, "qhull warning: missing visible distance for option 'Vn'. Ignored\n");
+ else {
+ qh MINvisible= qh_strtod(s, &s);
+ qh_option("Visible", NULL, &qh MINvisible);
+ }
+ break;
+ case 'U':
+ if (!isdigit(*s) && *s != '-')
+ qh_fprintf(qh ferr, 7009, "qhull warning: missing coplanar distance for option 'Un'. Ignored\n");
+ else {
+ qh MAXcoplanar= qh_strtod(s, &s);
+ qh_option("U-coplanar", NULL, &qh MAXcoplanar);
+ }
+ break;
+ case 'W':
+ if (*s == '-')
+ qh_fprintf(qh ferr, 7010, "qhull warning: negative outside width for option 'Wn'. Ignored.\n");
+ else if (!isdigit(*s))
+ qh_fprintf(qh ferr, 7011, "qhull warning: missing outside width for option 'Wn'. Ignored\n");
+ else {
+ qh MINoutside= qh_strtod(s, &s);
+ qh_option("W-outside", NULL, &qh MINoutside);
+ qh APPROXhull= True;
+ }
+ break;
+ /************ sub menus ***************/
+ case 'F':
+ while (*s && !isspace(*s)) {
+ switch (*s++) {
+ case 'a':
+ qh_option("Farea", NULL, NULL);
+ qh_appendprint(qh_PRINTarea);
+ qh GETarea= True;
+ break;
+ case 'A':
+ qh_option("FArea-total", NULL, NULL);
+ qh GETarea= True;
+ break;
+ case 'c':
+ qh_option("Fcoplanars", NULL, NULL);
+ qh_appendprint(qh_PRINTcoplanars);
+ break;
+ case 'C':
+ qh_option("FCentrums", NULL, NULL);
+ qh_appendprint(qh_PRINTcentrums);
+ break;
+ case 'd':
+ qh_option("Fd-cdd-in", NULL, NULL);
+ qh CDDinput= True;
+ break;
+ case 'D':
+ qh_option("FD-cdd-out", NULL, NULL);
+ qh CDDoutput= True;
+ break;
+ case 'F':
+ qh_option("FFacets-xridge", NULL, NULL);
+ qh_appendprint(qh_PRINTfacets_xridge);
+ break;
+ case 'i':
+ qh_option("Finner", NULL, NULL);
+ qh_appendprint(qh_PRINTinner);
+ break;
+ case 'I':
+ qh_option("FIDs", NULL, NULL);
+ qh_appendprint(qh_PRINTids);
+ break;
+ case 'm':
+ qh_option("Fmerges", NULL, NULL);
+ qh_appendprint(qh_PRINTmerges);
+ break;
+ case 'M':
+ qh_option("FMaple", NULL, NULL);
+ qh_appendprint(qh_PRINTmaple);
+ break;
+ case 'n':
+ qh_option("Fneighbors", NULL, NULL);
+ qh_appendprint(qh_PRINTneighbors);
+ break;
+ case 'N':
+ qh_option("FNeighbors-vertex", NULL, NULL);
+ qh_appendprint(qh_PRINTvneighbors);
+ break;
+ case 'o':
+ qh_option("Fouter", NULL, NULL);
+ qh_appendprint(qh_PRINTouter);
+ break;
+ case 'O':
+ if (qh PRINToptions1st) {
+ qh_option("FOptions", NULL, NULL);
+ qh_appendprint(qh_PRINToptions);
+ }else
+ qh PRINToptions1st= True;
+ break;
+ case 'p':
+ qh_option("Fpoint-intersect", NULL, NULL);
+ qh_appendprint(qh_PRINTpointintersect);
+ break;
+ case 'P':
+ qh_option("FPoint-nearest", NULL, NULL);
+ qh_appendprint(qh_PRINTpointnearest);
+ break;
+ case 'Q':
+ qh_option("FQhull", NULL, NULL);
+ qh_appendprint(qh_PRINTqhull);
+ break;
+ case 's':
+ qh_option("Fsummary", NULL, NULL);
+ qh_appendprint(qh_PRINTsummary);
+ break;
+ case 'S':
+ qh_option("FSize", NULL, NULL);
+ qh_appendprint(qh_PRINTsize);
+ qh GETarea= True;
+ break;
+ case 't':
+ qh_option("Ftriangles", NULL, NULL);
+ qh_appendprint(qh_PRINTtriangles);
+ break;
+ case 'v':
+ /* option set in qh_initqhull_globals */
+ qh_appendprint(qh_PRINTvertices);
+ break;
+ case 'V':
+ qh_option("FVertex-average", NULL, NULL);
+ qh_appendprint(qh_PRINTaverage);
+ break;
+ case 'x':
+ qh_option("Fxtremes", NULL, NULL);
+ qh_appendprint(qh_PRINTextremes);
+ break;
+ default:
+ s--;
+ qh_fprintf(qh ferr, 7012, "qhull warning: unknown 'F' output option %c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ }
+ break;
+ case 'G':
+ isgeom= True;
+ qh_appendprint(qh_PRINTgeom);
+ while (*s && !isspace(*s)) {
+ switch (*s++) {
+ case 'a':
+ qh_option("Gall-points", NULL, NULL);
+ qh PRINTdots= True;
+ break;
+ case 'c':
+ qh_option("Gcentrums", NULL, NULL);
+ qh PRINTcentrums= True;
+ break;
+ case 'h':
+ qh_option("Gintersections", NULL, NULL);
+ qh DOintersections= True;
+ break;
+ case 'i':
+ qh_option("Ginner", NULL, NULL);
+ qh PRINTinner= True;
+ break;
+ case 'n':
+ qh_option("Gno-planes", NULL, NULL);
+ qh PRINTnoplanes= True;
+ break;
+ case 'o':
+ qh_option("Gouter", NULL, NULL);
+ qh PRINTouter= True;
+ break;
+ case 'p':
+ qh_option("Gpoints", NULL, NULL);
+ qh PRINTcoplanar= True;
+ break;
+ case 'r':
+ qh_option("Gridges", NULL, NULL);
+ qh PRINTridges= True;
+ break;
+ case 't':
+ qh_option("Gtransparent", NULL, NULL);
+ qh PRINTtransparent= True;
+ break;
+ case 'v':
+ qh_option("Gvertices", NULL, NULL);
+ qh PRINTspheres= True;
+ break;
+ case 'D':
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 6035, "qhull input error: missing dimension for option 'GDn'\n");
+ else {
+ if (qh DROPdim >= 0)
+ qh_fprintf(qh ferr, 7013, "qhull warning: can only drop one dimension. Previous 'GD%d' ignored\n",
+ qh DROPdim);
+ qh DROPdim= qh_strtol(s, &s);
+ qh_option("GDrop-dim", &qh DROPdim, NULL);
+ }
+ break;
+ default:
+ s--;
+ qh_fprintf(qh ferr, 7014, "qhull warning: unknown 'G' print option %c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ }
+ break;
+ case 'P':
+ while (*s && !isspace(*s)) {
+ switch (*s++) {
+ case 'd': case 'D': /* see qh_initthresholds() */
+ key= s[-1];
+ i= qh_strtol(s, &s);
+ r= 0;
+ if (*s == ':') {
+ s++;
+ r= qh_strtod(s, &s);
+ }
+ if (key == 'd')
+ qh_option("Pdrop-facets-dim-less", &i, &r);
+ else
+ qh_option("PDrop-facets-dim-more", &i, &r);
+ break;
+ case 'g':
+ qh_option("Pgood-facets", NULL, NULL);
+ qh PRINTgood= True;
+ break;
+ case 'G':
+ qh_option("PGood-facet-neighbors", NULL, NULL);
+ qh PRINTneighbors= True;
+ break;
+ case 'o':
+ qh_option("Poutput-forced", NULL, NULL);
+ qh FORCEoutput= True;
+ break;
+ case 'p':
+ qh_option("Pprecision-ignore", NULL, NULL);
+ qh PRINTprecision= False;
+ break;
+ case 'A':
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 6036, "qhull input error: missing facet count for keep area option 'PAn'\n");
+ else {
+ qh KEEParea= qh_strtol(s, &s);
+ qh_option("PArea-keep", &qh KEEParea, NULL);
+ qh GETarea= True;
+ }
+ break;
+ case 'F':
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 6037, "qhull input error: missing facet area for option 'PFn'\n");
+ else {
+ qh KEEPminArea= qh_strtod(s, &s);
+ qh_option("PFacet-area-keep", NULL, &qh KEEPminArea);
+ qh GETarea= True;
+ }
+ break;
+ case 'M':
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 6038, "qhull input error: missing merge count for option 'PMn'\n");
+ else {
+ qh KEEPmerge= qh_strtol(s, &s);
+ qh_option("PMerge-keep", &qh KEEPmerge, NULL);
+ }
+ break;
+ default:
+ s--;
+ qh_fprintf(qh ferr, 7015, "qhull warning: unknown 'P' print option %c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ }
+ break;
+ case 'Q':
+ lastproject= -1;
+ while (*s && !isspace(*s)) {
+ switch (*s++) {
+ case 'b': case 'B': /* handled by qh_initthresholds */
+ key= s[-1];
+ if (key == 'b' && *s == 'B') {
+ s++;
+ r= qh_DEFAULTbox;
+ qh SCALEinput= True;
+ qh_option("QbBound-unit-box", NULL, &r);
+ break;
+ }
+ if (key == 'b' && *s == 'b') {
+ s++;
+ qh SCALElast= True;
+ qh_option("Qbbound-last", NULL, NULL);
+ break;
+ }
+ k= qh_strtol(s, &s);
+ r= 0.0;
+ wasproject= False;
+ if (*s == ':') {
+ s++;
+ if ((r= qh_strtod(s, &s)) == 0.0) {
+ t= s; /* need true dimension for memory allocation */
+ while (*t && !isspace(*t)) {
+ if (toupper(*t++) == 'B'
+ && k == qh_strtol(t, &t)
+ && *t++ == ':'
+ && qh_strtod(t, &t) == 0.0) {
+ qh PROJECTinput++;
+ trace2((qh ferr, 2004, "qh_initflags: project dimension %d\n", k));
+ qh_option("Qb-project-dim", &k, NULL);
+ wasproject= True;
+ lastproject= k;
+ break;
+ }
+ }
+ }
+ }
+ if (!wasproject) {
+ if (lastproject == k && r == 0.0)
+ lastproject= -1; /* doesn't catch all possible sequences */
+ else if (key == 'b') {
+ qh SCALEinput= True;
+ if (r == 0.0)
+ r= -qh_DEFAULTbox;
+ qh_option("Qbound-dim-low", &k, &r);
+ }else {
+ qh SCALEinput= True;
+ if (r == 0.0)
+ r= qh_DEFAULTbox;
+ qh_option("QBound-dim-high", &k, &r);
+ }
+ }
+ break;
+ case 'c':
+ qh_option("Qcoplanar-keep", NULL, NULL);
+ qh KEEPcoplanar= True;
+ break;
+ case 'f':
+ qh_option("Qfurthest-outside", NULL, NULL);
+ qh BESToutside= True;
+ break;
+ case 'g':
+ qh_option("Qgood-facets-only", NULL, NULL);
+ qh ONLYgood= True;
+ break;
+ case 'i':
+ qh_option("Qinterior-keep", NULL, NULL);
+ qh KEEPinside= True;
+ break;
+ case 'm':
+ qh_option("Qmax-outside-only", NULL, NULL);
+ qh ONLYmax= True;
+ break;
+ case 'r':
+ qh_option("Qrandom-outside", NULL, NULL);
+ qh RANDOMoutside= True;
+ break;
+ case 's':
+ qh_option("Qsearch-initial-simplex", NULL, NULL);
+ qh ALLpoints= True;
+ break;
+ case 't':
+ qh_option("Qtriangulate", NULL, NULL);
+ qh TRIangulate= True;
+ break;
+ case 'T':
+ qh_option("QTestPoints", NULL, NULL);
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 6039, "qhull input error: missing number of test points for option 'QTn'\n");
+ else {
+ qh TESTpoints= qh_strtol(s, &s);
+ qh_option("QTestPoints", &qh TESTpoints, NULL);
+ }
+ break;
+ case 'u':
+ qh_option("QupperDelaunay", NULL, NULL);
+ qh UPPERdelaunay= True;
+ break;
+ case 'v':
+ qh_option("Qvertex-neighbors-convex", NULL, NULL);
+ qh TESTvneighbors= True;
+ break;
+ case 'x':
+ qh_option("Qxact-merge", NULL, NULL);
+ qh MERGEexact= True;
+ break;
+ case 'z':
+ qh_option("Qz-infinity-point", NULL, NULL);
+ qh ATinfinity= True;
+ break;
+ case '0':
+ qh_option("Q0-no-premerge", NULL, NULL);
+ qh NOpremerge= True;
+ break;
+ case '1':
+ if (!isdigit(*s)) {
+ qh_option("Q1-no-angle-sort", NULL, NULL);
+ qh ANGLEmerge= False;
+ break;
+ }
+ switch (*s++) {
+ case '0':
+ qh_option("Q10-no-narrow", NULL, NULL);
+ qh NOnarrow= True;
+ break;
+ case '1':
+ qh_option("Q11-trinormals Qtriangulate", NULL, NULL);
+ qh TRInormals= True;
+ qh TRIangulate= True;
+ break;
+ case '2':
+ qh_option("Q12-no-wide-dup", NULL, NULL);
+ qh NOwide= True;
+ break;
+ default:
+ s--;
+ qh_fprintf(qh ferr, 7016, "qhull warning: unknown 'Q' qhull option 1%c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ break;
+ case '2':
+ qh_option("Q2-no-merge-independent", NULL, NULL);
+ qh MERGEindependent= False;
+ goto LABELcheckdigit;
+ break; /* no warnings */
+ case '3':
+ qh_option("Q3-no-merge-vertices", NULL, NULL);
+ qh MERGEvertices= False;
+ LABELcheckdigit:
+ if (isdigit(*s))
+ qh_fprintf(qh ferr, 7017, "qhull warning: can not follow '1', '2', or '3' with a digit. '%c' skipped.\n",
+ *s++);
+ break;
+ case '4':
+ qh_option("Q4-avoid-old-into-new", NULL, NULL);
+ qh AVOIDold= True;
+ break;
+ case '5':
+ qh_option("Q5-no-check-outer", NULL, NULL);
+ qh SKIPcheckmax= True;
+ break;
+ case '6':
+ qh_option("Q6-no-concave-merge", NULL, NULL);
+ qh SKIPconvex= True;
+ break;
+ case '7':
+ qh_option("Q7-no-breadth-first", NULL, NULL);
+ qh VIRTUALmemory= True;
+ break;
+ case '8':
+ qh_option("Q8-no-near-inside", NULL, NULL);
+ qh NOnearinside= True;
+ break;
+ case '9':
+ qh_option("Q9-pick-furthest", NULL, NULL);
+ qh PICKfurthest= True;
+ break;
+ case 'G':
+ i= qh_strtol(s, &t);
+ if (qh GOODpoint)
+ qh_fprintf(qh ferr, 7018, "qhull warning: good point already defined for option 'QGn'. Ignored\n");
+ else if (s == t)
+ qh_fprintf(qh ferr, 7019, "qhull warning: missing good point id for option 'QGn'. Ignored\n");
+ else if (i < 0 || *s == '-') {
+ qh GOODpoint= i-1;
+ qh_option("QGood-if-dont-see-point", &i, NULL);
+ }else {
+ qh GOODpoint= i+1;
+ qh_option("QGood-if-see-point", &i, NULL);
+ }
+ s= t;
+ break;
+ case 'J':
+ if (!isdigit(*s) && *s != '-')
+ qh JOGGLEmax= 0.0;
+ else {
+ qh JOGGLEmax= (realT) qh_strtod(s, &s);
+ qh_option("QJoggle", NULL, &qh JOGGLEmax);
+ }
+ break;
+ case 'R':
+ if (!isdigit(*s) && *s != '-')
+ qh_fprintf(qh ferr, 7020, "qhull warning: missing random seed for option 'QRn'. Ignored\n");
+ else {
+ qh ROTATErandom= i= qh_strtol(s, &s);
+ if (i > 0)
+ qh_option("QRotate-id", &i, NULL );
+ else if (i < -1)
+ qh_option("QRandom-seed", &i, NULL );
+ }
+ break;
+ case 'V':
+ i= qh_strtol(s, &t);
+ if (qh GOODvertex)
+ qh_fprintf(qh ferr, 7021, "qhull warning: good vertex already defined for option 'QVn'. Ignored\n");
+ else if (s == t)
+ qh_fprintf(qh ferr, 7022, "qhull warning: no good point id given for option 'QVn'. Ignored\n");
+ else if (i < 0) {
+ qh GOODvertex= i - 1;
+ qh_option("QV-good-facets-not-point", &i, NULL);
+ }else {
+ qh_option("QV-good-facets-point", &i, NULL);
+ qh GOODvertex= i + 1;
+ }
+ s= t;
+ break;
+ default:
+ s--;
+ qh_fprintf(qh ferr, 7023, "qhull warning: unknown 'Q' qhull option %c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ }
+ break;
+ case 'T':
+ while (*s && !isspace(*s)) {
+ if (isdigit(*s) || *s == '-')
+ qh IStracing= qh_strtol(s, &s);
+ else switch (*s++) {
+ case 'a':
+ qh_option("Tannotate-output", NULL, NULL);
+ qh ANNOTATEoutput= True;
+ break;
+ case 'c':
+ qh_option("Tcheck-frequently", NULL, NULL);
+ qh CHECKfrequently= True;
+ break;
+ case 's':
+ qh_option("Tstatistics", NULL, NULL);
+ qh PRINTstatistics= True;
+ break;
+ case 'v':
+ qh_option("Tverify", NULL, NULL);
+ qh VERIFYoutput= True;
+ break;
+ case 'z':
+ if (qh ferr == qh_FILEstderr) {
+ /* The C++ interface captures the output in qh_fprint_qhull() */
+ qh_option("Tz-stdout", NULL, NULL);
+ qh USEstdout= True;
+ }else if (!qh fout)
+ qh_fprintf(qh ferr, 7024, "qhull warning: output file undefined(stdout). Option 'Tz' ignored.\n");
+ else {
+ qh_option("Tz-stdout", NULL, NULL);
+ qh USEstdout= True;
+ qh ferr= qh fout;
+ qhmem.ferr= qh fout;
+ }
+ break;
+ case 'C':
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 7025, "qhull warning: missing point id for cone for trace option 'TCn'. Ignored\n");
+ else {
+ i= qh_strtol(s, &s);
+ qh_option("TCone-stop", &i, NULL);
+ qh STOPcone= i + 1;
+ }
+ break;
+ case 'F':
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 7026, "qhull warning: missing frequency count for trace option 'TFn'. Ignored\n");
+ else {
+ qh REPORTfreq= qh_strtol(s, &s);
+ qh_option("TFacet-log", &qh REPORTfreq, NULL);
+ qh REPORTfreq2= qh REPORTfreq/2; /* for tracemerging() */
+ }
+ break;
+ case 'I':
+ if (!isspace(*s))
+ qh_fprintf(qh ferr, 7027, "qhull warning: missing space between 'TI' and filename, %s\n", s);
+ while (isspace(*s))
+ s++;
+ t= qh_skipfilename(s);
+ {
+ char filename[qh_FILENAMElen];
+
+ qh_copyfilename(filename, (int)sizeof(filename), s, (int)(t-s)); /* WARN64 */
+ s= t;
+ if (!freopen(filename, "r", stdin)) {
+ qh_fprintf(qh ferr, 6041, "qhull error: could not open file \"%s\".", filename);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }else {
+ qh_option("TInput-file", NULL, NULL);
+ qh_option(filename, NULL, NULL);
+ }
+ }
+ break;
+ case 'O':
+ if (!isspace(*s))
+ qh_fprintf(qh ferr, 7028, "qhull warning: missing space between 'TO' and filename, %s\n", s);
+ while (isspace(*s))
+ s++;
+ t= qh_skipfilename(s);
+ {
+ char filename[qh_FILENAMElen];
+
+ qh_copyfilename(filename, (int)sizeof(filename), s, (int)(t-s)); /* WARN64 */
+ s= t;
+ if (!qh fout) {
+ qh_fprintf(qh ferr, 6266, "qhull input warning: qh.fout was not set by caller. Cannot use option 'TO' to redirect output. Ignoring option 'TO'\n");
+ }else if (!freopen(filename, "w", qh fout)) {
+ qh_fprintf(qh ferr, 6044, "qhull error: could not open file \"%s\".", filename);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }else {
+ qh_option("TOutput-file", NULL, NULL);
+ qh_option(filename, NULL, NULL);
+ }
+ }
+ break;
+ case 'P':
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 7029, "qhull warning: missing point id for trace option 'TPn'. Ignored\n");
+ else {
+ qh TRACEpoint= qh_strtol(s, &s);
+ qh_option("Trace-point", &qh TRACEpoint, NULL);
+ }
+ break;
+ case 'M':
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 7030, "qhull warning: missing merge id for trace option 'TMn'. Ignored\n");
+ else {
+ qh TRACEmerge= qh_strtol(s, &s);
+ qh_option("Trace-merge", &qh TRACEmerge, NULL);
+ }
+ break;
+ case 'R':
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 7031, "qhull warning: missing rerun count for trace option 'TRn'. Ignored\n");
+ else {
+ qh RERUN= qh_strtol(s, &s);
+ qh_option("TRerun", &qh RERUN, NULL);
+ }
+ break;
+ case 'V':
+ i= qh_strtol(s, &t);
+ if (s == t)
+ qh_fprintf(qh ferr, 7032, "qhull warning: missing furthest point id for trace option 'TVn'. Ignored\n");
+ else if (i < 0) {
+ qh STOPpoint= i - 1;
+ qh_option("TV-stop-before-point", &i, NULL);
+ }else {
+ qh STOPpoint= i + 1;
+ qh_option("TV-stop-after-point", &i, NULL);
+ }
+ s= t;
+ break;
+ case 'W':
+ if (!isdigit(*s))
+ qh_fprintf(qh ferr, 7033, "qhull warning: missing max width for trace option 'TWn'. Ignored\n");
+ else {
+ qh TRACEdist= (realT) qh_strtod(s, &s);
+ qh_option("TWide-trace", NULL, &qh TRACEdist);
+ }
+ break;
+ default:
+ s--;
+ qh_fprintf(qh ferr, 7034, "qhull warning: unknown 'T' trace option %c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ }
+ break;
+ default:
+ qh_fprintf(qh ferr, 7035, "qhull warning: unknown flag %c(%x)\n", (int)s[-1],
+ (int)s[-1]);
+ break;
+ }
+ if (s-1 == prev_s && *s && !isspace(*s)) {
+ qh_fprintf(qh ferr, 7036, "qhull warning: missing space after flag %c(%x); reserved for menu. Skipped.\n",
+ (int)*prev_s, (int)*prev_s);
+ while (*s && !isspace(*s))
+ s++;
+ }
+ }
+ if (qh STOPcone && qh JOGGLEmax < REALmax/2)
+ qh_fprintf(qh ferr, 7078, "qhull warning: 'TCn' (stopCone) ignored when used with 'QJn' (joggle)\n");
+ if (isgeom && !qh FORCEoutput && qh PRINTout[1])
+ qh_fprintf(qh ferr, 7037, "qhull warning: additional output formats are not compatible with Geomview\n");
+ /* set derived values in qh_initqhull_globals */
+} /* initflags */
+
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="initqhull_buffers">-</a>
+
+ qh_initqhull_buffers()
+ initialize global memory buffers
+
+ notes:
+ must match qh_freebuffers()
+*/
+void qh_initqhull_buffers(void) {
+ int k;
+
+ qh TEMPsize= (qhmem.LASTsize - sizeof(setT))/SETelemsize;
+ if (qh TEMPsize <= 0 || qh TEMPsize > qhmem.LASTsize)
+ qh TEMPsize= 8; /* e.g., if qh_NOmem */
+ qh other_points= qh_setnew(qh TEMPsize);
+ qh del_vertices= qh_setnew(qh TEMPsize);
+ qh coplanarfacetset= qh_setnew(qh TEMPsize);
+ qh NEARzero= (realT *)qh_memalloc(qh hull_dim * sizeof(realT));
+ qh lower_threshold= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
+ qh upper_threshold= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
+ qh lower_bound= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
+ qh upper_bound= (realT *)qh_memalloc((qh input_dim+1) * sizeof(realT));
+ for (k=qh input_dim+1; k--; ) { /* duplicated in qh_initqhull_buffers and qh_clear_outputflags */
+ qh lower_threshold[k]= -REALmax;
+ qh upper_threshold[k]= REALmax;
+ qh lower_bound[k]= -REALmax;
+ qh upper_bound[k]= REALmax;
+ }
+ qh gm_matrix= (coordT *)qh_memalloc((qh hull_dim+1) * qh hull_dim * sizeof(coordT));
+ qh gm_row= (coordT **)qh_memalloc((qh hull_dim+1) * sizeof(coordT *));
+} /* initqhull_buffers */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="initqhull_globals">-</a>
+
+ qh_initqhull_globals( points, numpoints, dim, ismalloc )
+ initialize globals
+ if ismalloc
+ points were malloc'd and qhull should free at end
+
+ returns:
+ sets qh.first_point, num_points, input_dim, hull_dim and others
+ seeds random number generator (seed=1 if tracing)
+ modifies qh.hull_dim if ((qh.DELAUNAY and qh.PROJECTdelaunay) or qh.PROJECTinput)
+ adjust user flags as needed
+ also checks DIM3 dependencies and constants
+
+ notes:
+ do not use qh_point() since an input transformation may move them elsewhere
+
+ see:
+ qh_initqhull_start() sets default values for non-zero globals
+
+ design:
+ initialize points array from input arguments
+ test for qh.ZEROcentrum
+ (i.e., use opposite vertex instead of cetrum for convexity testing)
+ initialize qh.CENTERtype, qh.normal_size,
+ qh.center_size, qh.TRACEpoint/level,
+ initialize and test random numbers
+ qh_initqhull_outputflags() -- adjust and test output flags
+*/
+void qh_initqhull_globals(coordT *points, int numpoints, int dim, boolT ismalloc) {
+ int seed, pointsneeded, extra= 0, i, randi, k;
+ realT randr;
+ realT factorial;
+
+ time_t timedata;
+
+ trace0((qh ferr, 13, "qh_initqhull_globals: for %s | %s\n", qh rbox_command,
+ qh qhull_command));
+ qh POINTSmalloc= ismalloc;
+ qh first_point= points;
+ qh num_points= numpoints;
+ qh hull_dim= qh input_dim= dim;
+ if (!qh NOpremerge && !qh MERGEexact && !qh PREmerge && qh JOGGLEmax > REALmax/2) {
+ qh MERGING= True;
+ if (qh hull_dim <= 4) {
+ qh PREmerge= True;
+ qh_option("_pre-merge", NULL, NULL);
+ }else {
+ qh MERGEexact= True;
+ qh_option("Qxact_merge", NULL, NULL);
+ }
+ }else if (qh MERGEexact)
+ qh MERGING= True;
+ if (!qh NOpremerge && qh JOGGLEmax > REALmax/2) {
+#ifdef qh_NOmerge
+ qh JOGGLEmax= 0.0;
+#endif
+ }
+ if (qh TRIangulate && qh JOGGLEmax < REALmax/2 && qh PRINTprecision)
+ qh_fprintf(qh ferr, 7038, "qhull warning: joggle('QJ') always produces simplicial output. Triangulated output('Qt') does nothing.\n");
+ if (qh JOGGLEmax < REALmax/2 && qh DELAUNAY && !qh SCALEinput && !qh SCALElast) {
+ qh SCALElast= True;
+ qh_option("Qbbound-last-qj", NULL, NULL);
+ }
+ if (qh MERGING && !qh POSTmerge && qh premerge_cos > REALmax/2
+ && qh premerge_centrum == 0) {
+ qh ZEROcentrum= True;
+ qh ZEROall_ok= True;
+ qh_option("_zero-centrum", NULL, NULL);
+ }
+ if (qh JOGGLEmax < REALmax/2 && REALepsilon > 2e-8 && qh PRINTprecision)
+ qh_fprintf(qh ferr, 7039, "qhull warning: real epsilon, %2.2g, is probably too large for joggle('QJn')\nRecompile with double precision reals(see user.h).\n",
+ REALepsilon);
+#ifdef qh_NOmerge
+ if (qh MERGING) {
+ qh_fprintf(qh ferr, 6045, "qhull input error: merging not installed(qh_NOmerge + 'Qx', 'Cn' or 'An')\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+#endif
+ if (qh DELAUNAY && qh KEEPcoplanar && !qh KEEPinside) {
+ qh KEEPinside= True;
+ qh_option("Qinterior-keep", NULL, NULL);
+ }
+ if (qh DELAUNAY && qh HALFspace) {
+ qh_fprintf(qh ferr, 6046, "qhull input error: can not use Delaunay('d') or Voronoi('v') with halfspace intersection('H')\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (!qh DELAUNAY && (qh UPPERdelaunay || qh ATinfinity)) {
+ qh_fprintf(qh ferr, 6047, "qhull input error: use upper-Delaunay('Qu') or infinity-point('Qz') with Delaunay('d') or Voronoi('v')\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (qh UPPERdelaunay && qh ATinfinity) {
+ qh_fprintf(qh ferr, 6048, "qhull input error: can not use infinity-point('Qz') with upper-Delaunay('Qu')\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (qh SCALElast && !qh DELAUNAY && qh PRINTprecision)
+ qh_fprintf(qh ferr, 7040, "qhull input warning: option 'Qbb' (scale-last-coordinate) is normally used with 'd' or 'v'\n");
+ qh DOcheckmax= (!qh SKIPcheckmax && qh MERGING );
+ qh KEEPnearinside= (qh DOcheckmax && !(qh KEEPinside && qh KEEPcoplanar)
+ && !qh NOnearinside);
+ if (qh MERGING)
+ qh CENTERtype= qh_AScentrum;
+ else if (qh VORONOI)
+ qh CENTERtype= qh_ASvoronoi;
+ if (qh TESTvneighbors && !qh MERGING) {
+ qh_fprintf(qh ferr, 6049, "qhull input error: test vertex neighbors('Qv') needs a merge option\n");
+ qh_errexit(qh_ERRinput, NULL ,NULL);
+ }
+ if (qh PROJECTinput || (qh DELAUNAY && qh PROJECTdelaunay)) {
+ qh hull_dim -= qh PROJECTinput;
+ if (qh DELAUNAY) {
+ qh hull_dim++;
+ if (qh ATinfinity)
+ extra= 1;
+ }
+ }
+ if (qh hull_dim <= 1) {
+ qh_fprintf(qh ferr, 6050, "qhull error: dimension %d must be > 1\n", qh hull_dim);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ for (k=2, factorial=1.0; k < qh hull_dim; k++)
+ factorial *= k;
+ qh AREAfactor= 1.0 / factorial;
+ trace2((qh ferr, 2005, "qh_initqhull_globals: initialize globals. dim %d numpoints %d malloc? %d projected %d to hull_dim %d\n",
+ dim, numpoints, ismalloc, qh PROJECTinput, qh hull_dim));
+ qh normal_size= qh hull_dim * sizeof(coordT);
+ qh center_size= qh normal_size - sizeof(coordT);
+ pointsneeded= qh hull_dim+1;
+ if (qh hull_dim > qh_DIMmergeVertex) {
+ qh MERGEvertices= False;
+ qh_option("Q3-no-merge-vertices-dim-high", NULL, NULL);
+ }
+ if (qh GOODpoint)
+ pointsneeded++;
+#ifdef qh_NOtrace
+ if (qh IStracing) {
+ qh_fprintf(qh ferr, 6051, "qhull input error: tracing is not installed(qh_NOtrace in user.h)");
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+#endif
+ if (qh RERUN > 1) {
+ qh TRACElastrun= qh IStracing; /* qh_build_withrestart duplicates next conditional */
+ if (qh IStracing != -1)
+ qh IStracing= 0;
+ }else if (qh TRACEpoint != qh_IDunknown || qh TRACEdist < REALmax/2 || qh TRACEmerge) {
+ qh TRACElevel= (qh IStracing? qh IStracing : 3);
+ qh IStracing= 0;
+ }
+ if (qh ROTATErandom == 0 || qh ROTATErandom == -1) {
+ seed= (int)time(&timedata);
+ if (qh ROTATErandom == -1) {
+ seed= -seed;
+ qh_option("QRandom-seed", &seed, NULL );
+ }else
+ qh_option("QRotate-random", &seed, NULL);
+ qh ROTATErandom= seed;
+ }
+ seed= qh ROTATErandom;
+ if (seed == INT_MIN) /* default value */
+ seed= 1;
+ else if (seed < 0)
+ seed= -seed;
+ qh_RANDOMseed_(seed);
+ randr= 0.0;
+ for (i=1000; i--; ) {
+ randi= qh_RANDOMint;
+ randr += randi;
+ if (randi > qh_RANDOMmax) {
+ qh_fprintf(qh ferr, 8036, "\
+qhull configuration error (qh_RANDOMmax in user.h):\n\
+ random integer %d > qh_RANDOMmax(%.8g)\n",
+ randi, qh_RANDOMmax);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ }
+ qh_RANDOMseed_(seed);
+ randr = randr/1000;
+ if (randr < qh_RANDOMmax * 0.1
+ || randr > qh_RANDOMmax * 0.9)
+ qh_fprintf(qh ferr, 8037, "\
+qhull configuration warning (qh_RANDOMmax in user.h):\n\
+ average of 1000 random integers (%.2g) is much different than expected (%.2g).\n\
+ Is qh_RANDOMmax (%.2g) wrong?\n",
+ randr, qh_RANDOMmax * 0.5, qh_RANDOMmax);
+ qh RANDOMa= 2.0 * qh RANDOMfactor/qh_RANDOMmax;
+ qh RANDOMb= 1.0 - qh RANDOMfactor;
+ if (qh_HASHfactor < 1.1) {
+ qh_fprintf(qh ferr, 6052, "qhull internal error (qh_initqhull_globals): qh_HASHfactor %d must be at least 1.1. Qhull uses linear hash probing\n",
+ qh_HASHfactor);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ if (numpoints+extra < pointsneeded) {
+ qh_fprintf(qh ferr, 6214, "qhull input error: not enough points(%d) to construct initial simplex (need %d)\n",
+ numpoints, pointsneeded);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ qh_initqhull_outputflags();
+} /* initqhull_globals */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="initqhull_mem">-</a>
+
+ qh_initqhull_mem( )
+ initialize mem.c for qhull
+ qh.hull_dim and qh.normal_size determine some of the allocation sizes
+ if qh.MERGING,
+ includes ridgeT
+ calls qh_user_memsizes() to add up to 10 additional sizes for quick allocation
+ (see numsizes below)
+
+ returns:
+ mem.c already for qh_memalloc/qh_memfree (errors if called beforehand)
+
+ notes:
+ qh_produceoutput() prints memsizes
+
+*/
+void qh_initqhull_mem(void) {
+ int numsizes;
+ int i;
+
+ numsizes= 8+10;
+ qh_meminitbuffers(qh IStracing, qh_MEMalign, numsizes,
+ qh_MEMbufsize,qh_MEMinitbuf);
+ qh_memsize((int)sizeof(vertexT));
+ if (qh MERGING) {
+ qh_memsize((int)sizeof(ridgeT));
+ qh_memsize((int)sizeof(mergeT));
+ }
+ qh_memsize((int)sizeof(facetT));
+ i= sizeof(setT) + (qh hull_dim - 1) * SETelemsize; /* ridge.vertices */
+ qh_memsize(i);
+ qh_memsize(qh normal_size); /* normal */
+ i += SETelemsize; /* facet.vertices, .ridges, .neighbors */
+ qh_memsize(i);
+ qh_user_memsizes();
+ qh_memsetup();
+} /* initqhull_mem */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="initqhull_outputflags">-</a>
+
+ qh_initqhull_outputflags
+ initialize flags concerned with output
+
+ returns:
+ adjust user flags as needed
+
+ see:
+ qh_clear_outputflags() resets the flags
+
+ design:
+ test for qh.PRINTgood (i.e., only print 'good' facets)
+ check for conflicting print output options
+*/
+void qh_initqhull_outputflags(void) {
+ boolT printgeom= False, printmath= False, printcoplanar= False;
+ int i;
+
+ trace3((qh ferr, 3024, "qh_initqhull_outputflags: %s\n", qh qhull_command));
+ if (!(qh PRINTgood || qh PRINTneighbors)) {
+ if (qh KEEParea || qh KEEPminArea < REALmax/2 || qh KEEPmerge || qh DELAUNAY
+ || (!qh ONLYgood && (qh GOODvertex || qh GOODpoint))) {
+ qh PRINTgood= True;
+ qh_option("Pgood", NULL, NULL);
+ }
+ }
+ if (qh PRINTtransparent) {
+ if (qh hull_dim != 4 || !qh DELAUNAY || qh VORONOI || qh DROPdim >= 0) {
+ qh_fprintf(qh ferr, 6215, "qhull input error: transparent Delaunay('Gt') needs 3-d Delaunay('d') w/o 'GDn'\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ qh DROPdim = 3;
+ qh PRINTridges = True;
+ }
+ for (i=qh_PRINTEND; i--; ) {
+ if (qh PRINTout[i] == qh_PRINTgeom)
+ printgeom= True;
+ else if (qh PRINTout[i] == qh_PRINTmathematica || qh PRINTout[i] == qh_PRINTmaple)
+ printmath= True;
+ else if (qh PRINTout[i] == qh_PRINTcoplanars)
+ printcoplanar= True;
+ else if (qh PRINTout[i] == qh_PRINTpointnearest)
+ printcoplanar= True;
+ else if (qh PRINTout[i] == qh_PRINTpointintersect && !qh HALFspace) {
+ qh_fprintf(qh ferr, 6053, "qhull input error: option 'Fp' is only used for \nhalfspace intersection('Hn,n,n').\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }else if (qh PRINTout[i] == qh_PRINTtriangles && (qh HALFspace || qh VORONOI)) {
+ qh_fprintf(qh ferr, 6054, "qhull input error: option 'Ft' is not available for Voronoi vertices or halfspace intersection\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }else if (qh PRINTout[i] == qh_PRINTcentrums && qh VORONOI) {
+ qh_fprintf(qh ferr, 6055, "qhull input error: option 'FC' is not available for Voronoi vertices('v')\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }else if (qh PRINTout[i] == qh_PRINTvertices) {
+ if (qh VORONOI)
+ qh_option("Fvoronoi", NULL, NULL);
+ else
+ qh_option("Fvertices", NULL, NULL);
+ }
+ }
+ if (printcoplanar && qh DELAUNAY && qh JOGGLEmax < REALmax/2) {
+ if (qh PRINTprecision)
+ qh_fprintf(qh ferr, 7041, "qhull input warning: 'QJ' (joggle) will usually prevent coincident input sites for options 'Fc' and 'FP'\n");
+ }
+ if (printmath && (qh hull_dim > 3 || qh VORONOI)) {
+ qh_fprintf(qh ferr, 6056, "qhull input error: Mathematica and Maple output is only available for 2-d and 3-d convex hulls and 2-d Delaunay triangulations\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (printgeom) {
+ if (qh hull_dim > 4) {
+ qh_fprintf(qh ferr, 6057, "qhull input error: Geomview output is only available for 2-d, 3-d and 4-d\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (qh PRINTnoplanes && !(qh PRINTcoplanar + qh PRINTcentrums
+ + qh PRINTdots + qh PRINTspheres + qh DOintersections + qh PRINTridges)) {
+ qh_fprintf(qh ferr, 6058, "qhull input error: no output specified for Geomview\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (qh VORONOI && (qh hull_dim > 3 || qh DROPdim >= 0)) {
+ qh_fprintf(qh ferr, 6059, "qhull input error: Geomview output for Voronoi diagrams only for 2-d\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ /* can not warn about furthest-site Geomview output: no lower_threshold */
+ if (qh hull_dim == 4 && qh DROPdim == -1 &&
+ (qh PRINTcoplanar || qh PRINTspheres || qh PRINTcentrums)) {
+ qh_fprintf(qh ferr, 7042, "qhull input warning: coplanars, vertices, and centrums output not\n\
+available for 4-d output(ignored). Could use 'GDn' instead.\n");
+ qh PRINTcoplanar= qh PRINTspheres= qh PRINTcentrums= False;
+ }
+ }
+ if (!qh KEEPcoplanar && !qh KEEPinside && !qh ONLYgood) {
+ if ((qh PRINTcoplanar && qh PRINTspheres) || printcoplanar) {
+ if (qh QHULLfinished) {
+ qh_fprintf(qh ferr, 7072, "qhull output warning: ignoring coplanar points, option 'Qc' was not set for the first run of qhull.\n");
+ }else {
+ qh KEEPcoplanar = True;
+ qh_option("Qcoplanar", NULL, NULL);
+ }
+ }
+ }
+ qh PRINTdim= qh hull_dim;
+ if (qh DROPdim >=0) { /* after Geomview checks */
+ if (qh DROPdim < qh hull_dim) {
+ qh PRINTdim--;
+ if (!printgeom || qh hull_dim < 3)
+ qh_fprintf(qh ferr, 7043, "qhull input warning: drop dimension 'GD%d' is only available for 3-d/4-d Geomview\n", qh DROPdim);
+ }else
+ qh DROPdim= -1;
+ }else if (qh VORONOI) {
+ qh DROPdim= qh hull_dim-1;
+ qh PRINTdim= qh hull_dim-1;
+ }
+} /* qh_initqhull_outputflags */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="initqhull_start">-</a>
+
+ qh_initqhull_start( infile, outfile, errfile )
+ allocate memory if needed and call qh_initqhull_start2()
+*/
+void qh_initqhull_start(FILE *infile, FILE *outfile, FILE *errfile) {
+
+#if qh_QHpointer
+ if (qh_qh) {
+ qh_fprintf(errfile, 6205, "qhull error (qh_initqhull_start): qh_qh already defined. Call qh_save_qhull() first\n");
+ qh_exit(qh_ERRqhull); /* no error handler */
+ }
+ if (!(qh_qh= (qhT *)qh_malloc(sizeof(qhT)))) {
+ qh_fprintf(errfile, 6060, "qhull error (qh_initqhull_start): insufficient memory\n");
+ qh_exit(qh_ERRmem); /* no error handler */
+ }
+#endif
+ qh_initstatistics();
+ qh_initqhull_start2(infile, outfile, errfile);
+} /* initqhull_start */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="initqhull_start2">-</a>
+
+ qh_initqhull_start2( infile, outfile, errfile )
+ start initialization of qhull
+ initialize statistics, stdio, default values for global variables
+ assumes qh_qh is defined
+ notes:
+ report errors elsewhere, error handling and g_qhull_output [Qhull.cpp, QhullQh()] not in initialized
+ see:
+ qh_maxmin() determines the precision constants
+ qh_freeqhull2()
+*/
+void qh_initqhull_start2(FILE *infile, FILE *outfile, FILE *errfile) {
+ time_t timedata;
+ int seed;
+
+ qh_CPUclock; /* start the clock(for qh_clock). One-shot. */
+#if qh_QHpointer
+ memset((char *)qh_qh, 0, sizeof(qhT)); /* every field is 0, FALSE, NULL */
+#else
+ memset((char *)&qh_qh, 0, sizeof(qhT));
+#endif
+ qh ANGLEmerge= True;
+ qh DROPdim= -1;
+ qh ferr= errfile;
+ qh fin= infile;
+ qh fout= outfile;
+ qh furthest_id= qh_IDunknown;
+ qh JOGGLEmax= REALmax;
+ qh KEEPminArea = REALmax;
+ qh last_low= REALmax;
+ qh last_high= REALmax;
+ qh last_newhigh= REALmax;
+ qh max_outside= 0.0;
+ qh max_vertex= 0.0;
+ qh MAXabs_coord= 0.0;
+ qh MAXsumcoord= 0.0;
+ qh MAXwidth= -REALmax;
+ qh MERGEindependent= True;
+ qh MINdenom_1= fmax_(1.0/REALmax, REALmin); /* used by qh_scalepoints */
+ qh MINoutside= 0.0;
+ qh MINvisible= REALmax;
+ qh MAXcoplanar= REALmax;
+ qh outside_err= REALmax;
+ qh premerge_centrum= 0.0;
+ qh premerge_cos= REALmax;
+ qh PRINTprecision= True;
+ qh PRINTradius= 0.0;
+ qh postmerge_cos= REALmax;
+ qh postmerge_centrum= 0.0;
+ qh ROTATErandom= INT_MIN;
+ qh MERGEvertices= True;
+ qh totarea= 0.0;
+ qh totvol= 0.0;
+ qh TRACEdist= REALmax;
+ qh TRACEpoint= qh_IDunknown; /* recompile or use 'TPn' */
+ qh tracefacet_id= UINT_MAX; /* recompile to trace a facet */
+ qh tracevertex_id= UINT_MAX; /* recompile to trace a vertex */
+ seed= (int)time(&timedata);
+ qh_RANDOMseed_(seed);
+ qh run_id= qh_RANDOMint;
+ if(!qh run_id)
+ qh run_id++; /* guarantee non-zero */
+ qh_option("run-id", &qh run_id, NULL);
+ strcat(qh qhull, "qhull");
+} /* initqhull_start2 */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="initthresholds">-</a>
+
+ qh_initthresholds( commandString )
+ set thresholds for printing and scaling from commandString
+
+ returns:
+ sets qh.GOODthreshold or qh.SPLITthreshold if 'Pd0D1' used
+
+ see:
+ qh_initflags(), 'Qbk' 'QBk' 'Pdk' and 'PDk'
+ qh_inthresholds()
+
+ design:
+ for each 'Pdn' or 'PDn' option
+ check syntax
+ set qh.lower_threshold or qh.upper_threshold
+ set qh.GOODthreshold if an unbounded threshold is used
+ set qh.SPLITthreshold if a bounded threshold is used
+*/
+void qh_initthresholds(char *command) {
+ realT value;
+ int idx, maxdim, k;
+ char *s= command; /* non-const due to strtol */
+ char key;
+
+ maxdim= qh input_dim;
+ if (qh DELAUNAY && (qh PROJECTdelaunay || qh PROJECTinput))
+ maxdim++;
+ while (*s) {
+ if (*s == '-')
+ s++;
+ if (*s == 'P') {
+ s++;
+ while (*s && !isspace(key= *s++)) {
+ if (key == 'd' || key == 'D') {
+ if (!isdigit(*s)) {
+ qh_fprintf(qh ferr, 7044, "qhull warning: no dimension given for Print option '%c' at: %s. Ignored\n",
+ key, s-1);
+ continue;
+ }
+ idx= qh_strtol(s, &s);
+ if (idx >= qh hull_dim) {
+ qh_fprintf(qh ferr, 7045, "qhull warning: dimension %d for Print option '%c' is >= %d. Ignored\n",
+ idx, key, qh hull_dim);
+ continue;
+ }
+ if (*s == ':') {
+ s++;
+ value= qh_strtod(s, &s);
+ if (fabs((double)value) > 1.0) {
+ qh_fprintf(qh ferr, 7046, "qhull warning: value %2.4g for Print option %c is > +1 or < -1. Ignored\n",
+ value, key);
+ continue;
+ }
+ }else
+ value= 0.0;
+ if (key == 'd')
+ qh lower_threshold[idx]= value;
+ else
+ qh upper_threshold[idx]= value;
+ }
+ }
+ }else if (*s == 'Q') {
+ s++;
+ while (*s && !isspace(key= *s++)) {
+ if (key == 'b' && *s == 'B') {
+ s++;
+ for (k=maxdim; k--; ) {
+ qh lower_bound[k]= -qh_DEFAULTbox;
+ qh upper_bound[k]= qh_DEFAULTbox;
+ }
+ }else if (key == 'b' && *s == 'b')
+ s++;
+ else if (key == 'b' || key == 'B') {
+ if (!isdigit(*s)) {
+ qh_fprintf(qh ferr, 7047, "qhull warning: no dimension given for Qhull option %c. Ignored\n",
+ key);
+ continue;
+ }
+ idx= qh_strtol(s, &s);
+ if (idx >= maxdim) {
+ qh_fprintf(qh ferr, 7048, "qhull warning: dimension %d for Qhull option %c is >= %d. Ignored\n",
+ idx, key, maxdim);
+ continue;
+ }
+ if (*s == ':') {
+ s++;
+ value= qh_strtod(s, &s);
+ }else if (key == 'b')
+ value= -qh_DEFAULTbox;
+ else
+ value= qh_DEFAULTbox;
+ if (key == 'b')
+ qh lower_bound[idx]= value;
+ else
+ qh upper_bound[idx]= value;
+ }
+ }
+ }else {
+ while (*s && !isspace(*s))
+ s++;
+ }
+ while (isspace(*s))
+ s++;
+ }
+ for (k=qh hull_dim; k--; ) {
+ if (qh lower_threshold[k] > -REALmax/2) {
+ qh GOODthreshold= True;
+ if (qh upper_threshold[k] < REALmax/2) {
+ qh SPLITthresholds= True;
+ qh GOODthreshold= False;
+ break;
+ }
+ }else if (qh upper_threshold[k] < REALmax/2)
+ qh GOODthreshold= True;
+ }
+} /* initthresholds */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="lib_check">-</a>
+
+ qh_lib_check( qhullLibraryType, qhTsize, vertexTsize, ridgeTsize, facetTsize, setTsize, qhmemTsize )
+ Report error if library does not agree with caller
+
+ notes:
+ NOerrors -- qh_lib_check can not call qh_errexit()
+*/
+void qh_lib_check(int qhullLibraryType, int qhTsize, int vertexTsize, int ridgeTsize, int facetTsize, int setTsize, int qhmemTsize) {
+ boolT iserror= False;
+
+#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG) /* user_r.h */
+ // _CrtSetBreakAlloc(744); /* Break at memalloc {744}, or 'watch' _crtBreakAlloc */
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) );
+ _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
+ _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
+ _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
+ _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
+ _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
+ _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
+#endif
+
+ if (qhullLibraryType==QHULL_NON_REENTRANT) { /* 0 */
+ if (qh_QHpointer) {
+ qh_fprintf_stderr(6246, "qh_lib_check: Incorrect qhull library called. Caller uses a static qhT while library uses a dynamic qhT via qh_QHpointer. Both caller and library are non-reentrant.\n");
+ iserror= True;
+ }
+ }else if (qhullLibraryType==QHULL_QH_POINTER) { /* 1 */
+ if (!qh_QHpointer) {
+ qh_fprintf_stderr(6247, "qh_lib_check: Incorrect qhull library called. Caller uses a dynamic qhT via qh_QHpointer while library uses a static qhT. Both caller and library are non-reentrant.\n");
+ iserror= True;
+ }
+ }else if (qhullLibraryType==QHULL_REENTRANT) { /* 2 */
+ qh_fprintf_stderr(6248, "qh_lib_check: Incorrect qhull library called. Caller uses reentrant Qhull while library is non-reentrant\n");
+ iserror= True;
+ }else{
+ qh_fprintf_stderr(6262, "qh_lib_check: Expecting qhullLibraryType QHULL_NON_REENTRANT(0), QHULL_QH_POINTER(1), or QHULL_REENTRANT(2). Got %d\n", qhullLibraryType);
+ iserror= True;
+ }
+ if (qhTsize != sizeof(qhT)) {
+ qh_fprintf_stderr(6249, "qh_lib_check: Incorrect qhull library called. Size of qhT for caller is %d, but for library is %d.\n", qhTsize, sizeof(qhT));
+ iserror= True;
+ }
+ if (vertexTsize != sizeof(vertexT)) {
+ qh_fprintf_stderr(6250, "qh_lib_check: Incorrect qhull library called. Size of vertexT for caller is %d, but for library is %d.\n", vertexTsize, sizeof(vertexT));
+ iserror= True;
+ }
+ if (ridgeTsize != sizeof(ridgeT)) {
+ qh_fprintf_stderr(6251, "qh_lib_check: Incorrect qhull library called. Size of ridgeT for caller is %d, but for library is %d.\n", ridgeTsize, sizeof(ridgeT));
+ iserror= True;
+ }
+ if (facetTsize != sizeof(facetT)) {
+ qh_fprintf_stderr(6252, "qh_lib_check: Incorrect qhull library called. Size of facetT for caller is %d, but for library is %d.\n", facetTsize, sizeof(facetT));
+ iserror= True;
+ }
+ if (setTsize && setTsize != sizeof(setT)) {
+ qh_fprintf_stderr(6253, "qh_lib_check: Incorrect qhull library called. Size of setT for caller is %d, but for library is %d.\n", setTsize, sizeof(setT));
+ iserror= True;
+ }
+ if (qhmemTsize && qhmemTsize != sizeof(qhmemT)) {
+ qh_fprintf_stderr(6254, "qh_lib_check: Incorrect qhull library called. Size of qhmemT for caller is %d, but for library is %d.\n", qhmemTsize, sizeof(qhmemT));
+ iserror= True;
+ }
+ if (iserror) {
+ if(qh_QHpointer){
+ qh_fprintf_stderr(6255, "qh_lib_check: Cannot continue. Library '%s' uses a dynamic qhT via qh_QHpointer (e.g., qhull_p.so)\n", qh_version2);
+ }else{
+ qh_fprintf_stderr(6256, "qh_lib_check: Cannot continue. Library '%s' uses a static qhT (e.g., libqhull.so)\n", qh_version2);
+ }
+ qh_exit(qh_ERRqhull); /* can not use qh_errexit() */
+ }
+} /* lib_check */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="option">-</a>
+
+ qh_option( option, intVal, realVal )
+ add an option description to qh.qhull_options
+
+ notes:
+ NOerrors -- qh_option can not call qh_errexit() [qh_initqhull_start2]
+ will be printed with statistics ('Ts') and errors
+ strlen(option) < 40
+*/
+void qh_option(const char *option, int *i, realT *r) {
+ char buf[200];
+ int len, maxlen;
+
+ sprintf(buf, " %s", option);
+ if (i)
+ sprintf(buf+strlen(buf), " %d", *i);
+ if (r)
+ sprintf(buf+strlen(buf), " %2.2g", *r);
+ len= (int)strlen(buf); /* WARN64 */
+ qh qhull_optionlen += len;
+ maxlen= sizeof(qh qhull_options) - len -1;
+ maximize_(maxlen, 0);
+ if (qh qhull_optionlen >= qh_OPTIONline && maxlen > 0) {
+ qh qhull_optionlen= len;
+ strncat(qh qhull_options, "\n", (size_t)(maxlen--));
+ }
+ strncat(qh qhull_options, buf, (size_t)maxlen);
+} /* option */
+
+#if qh_QHpointer
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="restore_qhull">-</a>
+
+ qh_restore_qhull( oldqh )
+ restores a previously saved qhull
+ also restores qh_qhstat and qhmem.tempstack
+ Sets *oldqh to NULL
+ notes:
+ errors if current qhull hasn't been saved or freed
+ uses qhmem for error reporting
+
+ NOTE 1998/5/11:
+ Freeing memory after qh_save_qhull and qh_restore_qhull
+ is complicated. The procedures will be redesigned.
+
+ see:
+ qh_save_qhull(), UsingLibQhull
+*/
+void qh_restore_qhull(qhT **oldqh) {
+
+ if (*oldqh && strcmp((*oldqh)->qhull, "qhull")) {
+ qh_fprintf(qhmem.ferr, 6061, "qhull internal error (qh_restore_qhull): %p is not a qhull data structure\n",
+ *oldqh);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ if (qh_qh) {
+ qh_fprintf(qhmem.ferr, 6062, "qhull internal error (qh_restore_qhull): did not save or free existing qhull\n");
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ if (!*oldqh || !(*oldqh)->old_qhstat) {
+ qh_fprintf(qhmem.ferr, 6063, "qhull internal error (qh_restore_qhull): did not previously save qhull %p\n",
+ *oldqh);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ qh_qh= *oldqh;
+ *oldqh= NULL;
+ qh_qhstat= qh old_qhstat;
+ qhmem.tempstack= qh old_tempstack;
+ qh old_qhstat= 0;
+ qh old_tempstack= 0;
+ trace1((qh ferr, 1007, "qh_restore_qhull: restored qhull from %p\n", *oldqh));
+} /* restore_qhull */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="save_qhull">-</a>
+
+ qh_save_qhull( )
+ saves qhull for a later qh_restore_qhull
+ also saves qh_qhstat and qhmem.tempstack
+
+ returns:
+ qh_qh=NULL
+
+ notes:
+ need to initialize qhull or call qh_restore_qhull before continuing
+
+ NOTE 1998/5/11:
+ Freeing memory after qh_save_qhull and qh_restore_qhull
+ is complicated. The procedures will be redesigned.
+
+ see:
+ qh_restore_qhull()
+*/
+qhT *qh_save_qhull(void) {
+ qhT *oldqh;
+
+ trace1((qhmem.ferr, 1045, "qh_save_qhull: save qhull %p\n", qh_qh));
+ if (!qh_qh) {
+ qh_fprintf(qhmem.ferr, 6064, "qhull internal error (qh_save_qhull): qhull not initialized\n");
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ qh old_qhstat= qh_qhstat;
+ qh_qhstat= NULL;
+ qh old_tempstack= qhmem.tempstack;
+ qhmem.tempstack= NULL;
+ oldqh= qh_qh;
+ qh_qh= NULL;
+ return oldqh;
+} /* save_qhull */
+
+#endif
+
diff --git a/xs/src/qhull/src/libqhull/index.htm b/xs/src/qhull/src/libqhull/index.htm
new file mode 100644
index 000000000..62b9d9970
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/index.htm
@@ -0,0 +1,264 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>Qhull functions, macros, and data structures</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code</a><br>
+<b>To:</b> <a href="#TOC">Qhull files</a><br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
+&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
+&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
+&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
+&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+
+<hr>
+<!-- Main text of document. -->
+
+<h1>Qhull functions, macros, and data structures</h1>
+<blockquote>
+<p>The following sections provide an overview and index to
+Qhull's functions, macros, and data structures.
+Each section starts with an introduction.
+See also <a href=../../html/qh-code.htm#library>Calling
+Qhull from C programs</a> and <a href="../../html/qh-code.htm#cpp">Calling Qhull from C++ programs</a>.</p>
+
+<p>Qhull uses the following conventions:</p>
+<blockquote>
+
+<ul>
+<li>in code, global variables start with &quot;qh &quot;
+<li>in documentation, global variables start with 'qh.'
+<li>constants start with an upper case word
+<li>important globals include an '_'
+<li>functions, macros, and constants start with &quot;qh_&quot;</li>
+<li>data types end in &quot;T&quot;</li>
+<li>macros with arguments end in &quot;_&quot;</li>
+<li>iterators are macros that use local variables</li>
+<li>iterators for sets start with &quot;FOREACH&quot;</li>
+<li>iterators for lists start with &quot;FORALL&quot;</li>
+<li>qhull options are in single quotes (e.g., 'Pdn')</li>
+<li>lists are sorted alphabetically</li>
+<li>preprocessor directives on left margin for older compilers</li>
+</ul>
+</blockquote>
+<p>
+When reading the code, please note that the
+global data structure, 'qh', is a macro. It
+either expands to &quot;qh_qh.&quot; or to
+&quot;qh_qh-&gt;&quot;. The later is used for
+applications which run concurrent calls to qh_qhull().
+<p>
+When reading code with an editor, a search for
+'<i>&quot;function</i>'
+will locate the header of <i>qh_function</i>. A search for '<i>* function</i>'
+will locate the tail of <i>qh_function</i>.
+
+<p>A useful starting point is <a href="libqhull.h">libqhull.h</a>. It defines most
+of Qhull data structures and top-level functions. Search for <i>'PFn'</i> to
+determine the corresponding constant in Qhull. Search for <i>'Fp'</i> to
+determine the corresponding <a href="libqhull.h#qh_PRINT">qh_PRINT...</a> constant.
+Search <a href="io.c">io.c</a> to learn how the print function is implemented.</p>
+
+<p>If your web browser is configured for .c and .h files, the function, macro, and data type links
+go to the corresponding source location. To configure your web browser for .c and .h files.
+<ul>
+<li>In the Download Preferences or Options panel, add file extensions 'c' and 'h' to mime type 'text/html'.
+<li>Opera 12.10
+<ol>
+<li>In Tools > Preferences > Advanced > Downloads
+<li>Uncheck 'Hide file types opened with Opera'
+<li>Quick find 'html'
+<li>Select 'text/html' > Edit
+<li>Add File extensions 'c,h,'
+<li>Click 'OK'
+</ol>
+<li>Internet Explorer -- Mime types are not available from 'Internet Options'. Is there a registry key for these settings?
+<li>Firefox -- Mime types are not available from 'Preferences'. Is there an add-on to change the file extensions for a mime type?
+<li>Chrome -- Can Chrome be configured?
+</ul>
+
+<p>
+Please report documentation and link errors
+to <a href="mailto:qhull-bug@qhull.org">qhull-bug@qhull.org</a>.
+</blockquote>
+
+<p><b>Copyright &copy; 1997-2015 C.B. Barber</b></p>
+
+<hr>
+
+<h2><a href="#TOP">&#187;</a><a name="TOC">Qhull files</a> </h2>
+<blockquote>
+
+<p>This sections lists the .c and .h files for Qhull. Please
+refer to these files for detailed information.</p>
+<blockquote>
+
+<dl>
+<dt><a href="../../Makefile"><b>Makefile</b></a><b>, </b><a href="../../CMakeLists.txt"><b>CMakeLists.txt</b></a></dt>
+<dd><tt>Makefile</tt> is preconfigured for gcc. <tt>CMakeLists.txt</tt> supports multiple
+platforms with <a href=http://www.cmake.org/>CMake</a>.
+Qhull includes project files for Visual Studio and Qt.
+</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="libqhull.h"><b>libqhull.h</b></a> </dt>
+<dd>Include file for the Qhull library (<tt>libqhull.so</tt>, <tt>qhull.dll</tt>, <tt>libqhullstatic.a</tt>).
+Data structures are documented under <a href="qh-poly.htm">Poly</a>.
+Global variables are documented under <a href="qh-globa.htm">Global</a>.
+Other data structures and variables are documented under
+<a href="qh-qhull.htm#TOC">Qhull</a> or <a href="qh-geom.htm"><b>Geom</b></a><b>.</b></dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-geom.htm"><b>Geom</b></a><b>, </b>
+<a href="geom.h"><b>geom.h</b></a><b>, </b>
+<a href="geom.c"><b>geom.c</b></a><b>, </b>
+<a href="geom2.c"><b>geom2.c</b></a><b>, </b>
+<a href="random.c"><b>random.c</b></a><b>, </b>
+<a href="random.h"><b>random.h</b></a></dt>
+<dd>Geometric routines. These routines implement mathematical
+functions such as Gaussian elimination and geometric
+routines needed for Qhull. Frequently used routines are
+in <tt>geom.c</tt> while infrequent ones are in <tt>geom2.c</tt>.
+</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-globa.htm"><b>Global</b></a><b>, </b>
+<a href="global.c"><b>global.c</b></a><b>, </b>
+<a href="libqhull.h"><b>libqhull.h</b></a> </dt>
+<dd>Global routines. Qhull uses a global data structure, <tt>qh</tt>,
+to store globally defined constants, lists, sets, and
+variables.
+<tt>global.c</tt> initializes and frees these
+structures. </dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-io.htm"><b>Io</b></a><b>, </b><a href="io.h"><b>io.h</b></a><b>,
+</b><a href="io.c"><b>io.c</b></a> </dt>
+<dd>Input and output routines. Qhull provides a wide range of
+input and output options.</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-mem.htm"><b>Mem</b></a><b>, </b>
+<a href="mem.h"><b>mem.h</b></a><b>, </b>
+<a href="mem.c"><b>mem.c</b></a> </dt>
+<dd>Memory routines. Qhull provides memory allocation and
+deallocation. It uses quick-fit allocation.</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-merge.htm"><b>Merge</b></a><b>, </b>
+<a href="merge.h"><b>merge.h</b></a><b>, </b>
+<a href="merge.c"><b>merge.c</b></a> </dt>
+<dd>Merge routines. Qhull handles precision problems by
+merged facets or joggled input. These routines merge simplicial facets,
+merge non-simplicial facets, merge cycles of facets, and
+rename redundant vertices.</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-poly.htm"><b>Poly</b></a><b>, </b>
+<a href="poly.h"><b>poly.h</b></a><b>, </b>
+<a href="poly.c"><b>poly.c</b></a><b>, </b>
+<a href="poly2.c"><b>poly2.c</b></a><b>, </b>
+<a href="libqhull.h"><b>libqhull.h</b></a> </dt>
+<dd>Polyhedral routines. Qhull produces a polyhedron as a
+list of facets with vertices, neighbors, ridges, and
+geometric information. <tt>libqhull.h</tt> defines the main
+data structures. Frequently used routines are in <tt>poly.c</tt>
+while infrequent ones are in <tt>poly2.c</tt>.</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-qhull.htm#TOC"><b>Qhull</b></a><b>, </b>
+<a href="libqhull.c"><b>libqhull.c</b></a><b>, </b>
+<a href="libqhull.h"><b>libqhull.h</b></a><b>, </b>
+<a href="qhull_a.h"><b>qhull_a.h</b></a><b>, </b>
+<a href="../qhullo/unix.c"><b>unix.c</b></a> <b>, </b>
+<a href="../qconvex/qconvex.c"><b>qconvex.c</b></a> <b>, </b>
+<a href="../qdelaunay/qdelaun.c"><b>qdelaun.c</b></a> <b>, </b>
+<a href="../qhalf/qhalf.c"><b>qhalf.c</b></a> <b>, </b>
+<a href="../qvoronoi/qvoronoi.c"><b>qvoronoi.c</b></a> </dt>
+<dd>Top-level routines. The Quickhull algorithm is
+implemented by <tt>libqhull.c</tt>. <tt>qhull_a.h</tt>
+includes all header files. </dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-set.htm"><b>Set</b></a><b>, </b>
+<a href="qset.h"><b>qset.h</b></a><b>, </b>
+<a href="qset.c"><b>qset.c</b></a> </dt>
+<dd>Set routines. Qhull implements its data structures as
+sets. A set is an array of pointers that is expanded as
+needed. This is a separate package that may be used in
+other applications. </dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-stat.htm"><b>Stat</b></a><b>, </b>
+<a href="stat.h"><b>stat.h</b></a><b>, </b>
+<a href="stat.c"><b>stat.c</b></a> </dt>
+<dd>Statistical routines. Qhull maintains statistics about
+its implementation. </dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-user.htm"><b>User</b></a><b>, </b>
+<a href="user.h"><b>user.h</b></a><b>, </b>
+<a href="user.c"><b>user.c</b></a><b>, </b>
+<a href="../user_eg/user_eg.c"><b>user_eg.c</b></a><b>, </b>
+<a href="../user_eg2/user_eg2.c"><b>user_eg2.c</b></a><b>, </b>
+</dt>
+<dd>User-defined routines. Qhull allows the user to configure
+the code with defined constants and specialized routines.
+</dd>
+</dl>
+</blockquote>
+
+</blockquote>
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="#TOC">Qhull files</a><br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
+<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
+&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
+&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
+&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
+&#149; <a href="qh-user.htm">User</a><br>
+
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull/io.c b/xs/src/qhull/src/libqhull/io.c
new file mode 100644
index 000000000..401987ec0
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/io.c
@@ -0,0 +1,4062 @@
+/*<html><pre> -<a href="qh-io.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ io.c
+ Input/Output routines of qhull application
+
+ see qh-io.htm and io.h
+
+ see user.c for qh_errprint and qh_printfacetlist
+
+ unix.c calls qh_readpoints and qh_produce_output
+
+ unix.c and user.c are the only callers of io.c functions
+ This allows the user to avoid loading io.o from qhull.a
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/io.c#5 $$Change: 2064 $
+ $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
+*/
+
+#include "qhull_a.h"
+
+/*========= -functions in alphabetical order after qh_produce_output() =====*/
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="produce_output">-</a>
+
+ qh_produce_output()
+ qh_produce_output2()
+ prints out the result of qhull in desired format
+ qh_produce_output2() does not call qh_prepare_output()
+ if qh.GETarea
+ computes and prints area and volume
+ qh.PRINTout[] is an array of output formats
+
+ notes:
+ prints output in qh.PRINTout order
+*/
+void qh_produce_output(void) {
+ int tempsize= qh_setsize(qhmem.tempstack);
+
+ qh_prepare_output();
+ qh_produce_output2();
+ if (qh_setsize(qhmem.tempstack) != tempsize) {
+ qh_fprintf(qh ferr, 6206, "qhull internal error (qh_produce_output): temporary sets not empty(%d)\n",
+ qh_setsize(qhmem.tempstack));
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+} /* produce_output */
+
+
+void qh_produce_output2(void) {
+ int i, tempsize= qh_setsize(qhmem.tempstack), d_1;
+
+ if (qh PRINTsummary)
+ qh_printsummary(qh ferr);
+ else if (qh PRINTout[0] == qh_PRINTnone)
+ qh_printsummary(qh fout);
+ for (i=0; i < qh_PRINTEND; i++)
+ qh_printfacets(qh fout, qh PRINTout[i], qh facet_list, NULL, !qh_ALL);
+ qh_allstatistics();
+ if (qh PRINTprecision && !qh MERGING && (qh JOGGLEmax > REALmax/2 || qh RERUN))
+ qh_printstats(qh ferr, qhstat precision, NULL);
+ if (qh VERIFYoutput && (zzval_(Zridge) > 0 || zzval_(Zridgemid) > 0))
+ qh_printstats(qh ferr, qhstat vridges, NULL);
+ if (qh PRINTstatistics) {
+ qh_printstatistics(qh ferr, "");
+ qh_memstatistics(qh ferr);
+ d_1= sizeof(setT) + (qh hull_dim - 1) * SETelemsize;
+ qh_fprintf(qh ferr, 8040, "\
+ size in bytes: merge %d ridge %d vertex %d facet %d\n\
+ normal %d ridge vertices %d facet vertices or neighbors %d\n",
+ (int)sizeof(mergeT), (int)sizeof(ridgeT),
+ (int)sizeof(vertexT), (int)sizeof(facetT),
+ qh normal_size, d_1, d_1 + SETelemsize);
+ }
+ if (qh_setsize(qhmem.tempstack) != tempsize) {
+ qh_fprintf(qh ferr, 6065, "qhull internal error (qh_produce_output2): temporary sets not empty(%d)\n",
+ qh_setsize(qhmem.tempstack));
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+} /* produce_output2 */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="dfacet">-</a>
+
+ qh_dfacet( id )
+ print facet by id, for debugging
+
+*/
+void qh_dfacet(unsigned id) {
+ facetT *facet;
+
+ FORALLfacets {
+ if (facet->id == id) {
+ qh_printfacet(qh fout, facet);
+ break;
+ }
+ }
+} /* dfacet */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="dvertex">-</a>
+
+ qh_dvertex( id )
+ print vertex by id, for debugging
+*/
+void qh_dvertex(unsigned id) {
+ vertexT *vertex;
+
+ FORALLvertices {
+ if (vertex->id == id) {
+ qh_printvertex(qh fout, vertex);
+ break;
+ }
+ }
+} /* dvertex */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="compare_facetarea">-</a>
+
+ qh_compare_facetarea( p1, p2 )
+ used by qsort() to order facets by area
+*/
+int qh_compare_facetarea(const void *p1, const void *p2) {
+ const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)p2);
+
+ if (!a->isarea)
+ return -1;
+ if (!b->isarea)
+ return 1;
+ if (a->f.area > b->f.area)
+ return 1;
+ else if (a->f.area == b->f.area)
+ return 0;
+ return -1;
+} /* compare_facetarea */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="compare_facetmerge">-</a>
+
+ qh_compare_facetmerge( p1, p2 )
+ used by qsort() to order facets by number of merges
+*/
+int qh_compare_facetmerge(const void *p1, const void *p2) {
+ const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)p2);
+
+ return(a->nummerge - b->nummerge);
+} /* compare_facetvisit */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="compare_facetvisit">-</a>
+
+ qh_compare_facetvisit( p1, p2 )
+ used by qsort() to order facets by visit id or id
+*/
+int qh_compare_facetvisit(const void *p1, const void *p2) {
+ const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)p2);
+ int i,j;
+
+ if (!(i= a->visitid))
+ i= 0 - a->id; /* do not convert to int, sign distinguishes id from visitid */
+ if (!(j= b->visitid))
+ j= 0 - b->id;
+ return(i - j);
+} /* compare_facetvisit */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="compare_vertexpoint">-</a>
+
+ qh_compare_vertexpoint( p1, p2 )
+ used by qsort() to order vertices by point id
+
+ Not used. Not available in libqhull_r.h since qh_pointid depends on qh
+*/
+int qh_compare_vertexpoint(const void *p1, const void *p2) {
+ const vertexT *a= *((vertexT *const*)p1), *b= *((vertexT *const*)p2);
+
+ return((qh_pointid(a->point) > qh_pointid(b->point)?1:-1));
+} /* compare_vertexpoint */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="copyfilename">-</a>
+
+ qh_copyfilename( dest, size, source, length )
+ copy filename identified by qh_skipfilename()
+
+ notes:
+ see qh_skipfilename() for syntax
+*/
+void qh_copyfilename(char *filename, int size, const char* source, int length) {
+ char c= *source;
+
+ if (length > size + 1) {
+ qh_fprintf(qh ferr, 6040, "qhull error: filename is more than %d characters, %s\n", size-1, source);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ strncpy(filename, source, length);
+ filename[length]= '\0';
+ if (c == '\'' || c == '"') {
+ char *s= filename + 1;
+ char *t= filename;
+ while (*s) {
+ if (*s == c) {
+ if (s[-1] == '\\')
+ t[-1]= c;
+ }else
+ *t++= *s;
+ s++;
+ }
+ *t= '\0';
+ }
+} /* copyfilename */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="countfacets">-</a>
+
+ qh_countfacets( facetlist, facets, printall,
+ numfacets, numsimplicial, totneighbors, numridges, numcoplanar, numtricoplanars )
+ count good facets for printing and set visitid
+ if allfacets, ignores qh_skipfacet()
+
+ notes:
+ qh_printsummary and qh_countfacets must match counts
+
+ returns:
+ numfacets, numsimplicial, total neighbors, numridges, coplanars
+ each facet with ->visitid indicating 1-relative position
+ ->visitid==0 indicates not good
+
+ notes
+ numfacets >= numsimplicial
+ if qh.NEWfacets,
+ does not count visible facets (matches qh_printafacet)
+
+ design:
+ for all facets on facetlist and in facets set
+ unless facet is skipped or visible (i.e., will be deleted)
+ mark facet->visitid
+ update counts
+*/
+void qh_countfacets(facetT *facetlist, setT *facets, boolT printall,
+ int *numfacetsp, int *numsimplicialp, int *totneighborsp, int *numridgesp, int *numcoplanarsp, int *numtricoplanarsp) {
+ facetT *facet, **facetp;
+ int numfacets= 0, numsimplicial= 0, numridges= 0, totneighbors= 0, numcoplanars= 0, numtricoplanars= 0;
+
+ FORALLfacet_(facetlist) {
+ if ((facet->visible && qh NEWfacets)
+ || (!printall && qh_skipfacet(facet)))
+ facet->visitid= 0;
+ else {
+ facet->visitid= ++numfacets;
+ totneighbors += qh_setsize(facet->neighbors);
+ if (facet->simplicial) {
+ numsimplicial++;
+ if (facet->keepcentrum && facet->tricoplanar)
+ numtricoplanars++;
+ }else
+ numridges += qh_setsize(facet->ridges);
+ if (facet->coplanarset)
+ numcoplanars += qh_setsize(facet->coplanarset);
+ }
+ }
+
+ FOREACHfacet_(facets) {
+ if ((facet->visible && qh NEWfacets)
+ || (!printall && qh_skipfacet(facet)))
+ facet->visitid= 0;
+ else {
+ facet->visitid= ++numfacets;
+ totneighbors += qh_setsize(facet->neighbors);
+ if (facet->simplicial){
+ numsimplicial++;
+ if (facet->keepcentrum && facet->tricoplanar)
+ numtricoplanars++;
+ }else
+ numridges += qh_setsize(facet->ridges);
+ if (facet->coplanarset)
+ numcoplanars += qh_setsize(facet->coplanarset);
+ }
+ }
+ qh visit_id += numfacets+1;
+ *numfacetsp= numfacets;
+ *numsimplicialp= numsimplicial;
+ *totneighborsp= totneighbors;
+ *numridgesp= numridges;
+ *numcoplanarsp= numcoplanars;
+ *numtricoplanarsp= numtricoplanars;
+} /* countfacets */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="detvnorm">-</a>
+
+ qh_detvnorm( vertex, vertexA, centers, offset )
+ compute separating plane of the Voronoi diagram for a pair of input sites
+ centers= set of facets (i.e., Voronoi vertices)
+ facet->visitid= 0 iff vertex-at-infinity (i.e., unbounded)
+
+ assumes:
+ qh_ASvoronoi and qh_vertexneighbors() already set
+
+ returns:
+ norm
+ a pointer into qh.gm_matrix to qh.hull_dim-1 reals
+ copy the data before reusing qh.gm_matrix
+ offset
+ if 'QVn'
+ sign adjusted so that qh.GOODvertexp is inside
+ else
+ sign adjusted so that vertex is inside
+
+ qh.gm_matrix= simplex of points from centers relative to first center
+
+ notes:
+ in io.c so that code for 'v Tv' can be removed by removing io.c
+ returns pointer into qh.gm_matrix to avoid tracking of temporary memory
+
+ design:
+ determine midpoint of input sites
+ build points as the set of Voronoi vertices
+ select a simplex from points (if necessary)
+ include midpoint if the Voronoi region is unbounded
+ relocate the first vertex of the simplex to the origin
+ compute the normalized hyperplane through the simplex
+ orient the hyperplane toward 'QVn' or 'vertex'
+ if 'Tv' or 'Ts'
+ if bounded
+ test that hyperplane is the perpendicular bisector of the input sites
+ test that Voronoi vertices not in the simplex are still on the hyperplane
+ free up temporary memory
+*/
+pointT *qh_detvnorm(vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp) {
+ facetT *facet, **facetp;
+ int i, k, pointid, pointidA, point_i, point_n;
+ setT *simplex= NULL;
+ pointT *point, **pointp, *point0, *midpoint, *normal, *inpoint;
+ coordT *coord, *gmcoord, *normalp;
+ setT *points= qh_settemp(qh TEMPsize);
+ boolT nearzero= False;
+ boolT unbounded= False;
+ int numcenters= 0;
+ int dim= qh hull_dim - 1;
+ realT dist, offset, angle, zero= 0.0;
+
+ midpoint= qh gm_matrix + qh hull_dim * qh hull_dim; /* last row */
+ for (k=0; k < dim; k++)
+ midpoint[k]= (vertex->point[k] + vertexA->point[k])/2;
+ FOREACHfacet_(centers) {
+ numcenters++;
+ if (!facet->visitid)
+ unbounded= True;
+ else {
+ if (!facet->center)
+ facet->center= qh_facetcenter(facet->vertices);
+ qh_setappend(&points, facet->center);
+ }
+ }
+ if (numcenters > dim) {
+ simplex= qh_settemp(qh TEMPsize);
+ qh_setappend(&simplex, vertex->point);
+ if (unbounded)
+ qh_setappend(&simplex, midpoint);
+ qh_maxsimplex(dim, points, NULL, 0, &simplex);
+ qh_setdelnth(simplex, 0);
+ }else if (numcenters == dim) {
+ if (unbounded)
+ qh_setappend(&points, midpoint);
+ simplex= points;
+ }else {
+ qh_fprintf(qh ferr, 6216, "qhull internal error (qh_detvnorm): too few points(%d) to compute separating plane\n", numcenters);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ i= 0;
+ gmcoord= qh gm_matrix;
+ point0= SETfirstt_(simplex, pointT);
+ FOREACHpoint_(simplex) {
+ if (qh IStracing >= 4)
+ qh_printmatrix(qh ferr, "qh_detvnorm: Voronoi vertex or midpoint",
+ &point, 1, dim);
+ if (point != point0) {
+ qh gm_row[i++]= gmcoord;
+ coord= point0;
+ for (k=dim; k--; )
+ *(gmcoord++)= *point++ - *coord++;
+ }
+ }
+ qh gm_row[i]= gmcoord; /* does not overlap midpoint, may be used later for qh_areasimplex */
+ normal= gmcoord;
+ qh_sethyperplane_gauss(dim, qh gm_row, point0, True,
+ normal, &offset, &nearzero);
+ if (qh GOODvertexp == vertexA->point)
+ inpoint= vertexA->point;
+ else
+ inpoint= vertex->point;
+ zinc_(Zdistio);
+ dist= qh_distnorm(dim, inpoint, normal, &offset);
+ if (dist > 0) {
+ offset= -offset;
+ normalp= normal;
+ for (k=dim; k--; ) {
+ *normalp= -(*normalp);
+ normalp++;
+ }
+ }
+ if (qh VERIFYoutput || qh PRINTstatistics) {
+ pointid= qh_pointid(vertex->point);
+ pointidA= qh_pointid(vertexA->point);
+ if (!unbounded) {
+ zinc_(Zdiststat);
+ dist= qh_distnorm(dim, midpoint, normal, &offset);
+ if (dist < 0)
+ dist= -dist;
+ zzinc_(Zridgemid);
+ wwmax_(Wridgemidmax, dist);
+ wwadd_(Wridgemid, dist);
+ trace4((qh ferr, 4014, "qh_detvnorm: points %d %d midpoint dist %2.2g\n",
+ pointid, pointidA, dist));
+ for (k=0; k < dim; k++)
+ midpoint[k]= vertexA->point[k] - vertex->point[k]; /* overwrites midpoint! */
+ qh_normalize(midpoint, dim, False);
+ angle= qh_distnorm(dim, midpoint, normal, &zero); /* qh_detangle uses dim+1 */
+ if (angle < 0.0)
+ angle= angle + 1.0;
+ else
+ angle= angle - 1.0;
+ if (angle < 0.0)
+ angle -= angle;
+ trace4((qh ferr, 4015, "qh_detvnorm: points %d %d angle %2.2g nearzero %d\n",
+ pointid, pointidA, angle, nearzero));
+ if (nearzero) {
+ zzinc_(Zridge0);
+ wwmax_(Wridge0max, angle);
+ wwadd_(Wridge0, angle);
+ }else {
+ zzinc_(Zridgeok)
+ wwmax_(Wridgeokmax, angle);
+ wwadd_(Wridgeok, angle);
+ }
+ }
+ if (simplex != points) {
+ FOREACHpoint_i_(points) {
+ if (!qh_setin(simplex, point)) {
+ facet= SETelemt_(centers, point_i, facetT);
+ zinc_(Zdiststat);
+ dist= qh_distnorm(dim, point, normal, &offset);
+ if (dist < 0)
+ dist= -dist;
+ zzinc_(Zridge);
+ wwmax_(Wridgemax, dist);
+ wwadd_(Wridge, dist);
+ trace4((qh ferr, 4016, "qh_detvnorm: points %d %d Voronoi vertex %d dist %2.2g\n",
+ pointid, pointidA, facet->visitid, dist));
+ }
+ }
+ }
+ }
+ *offsetp= offset;
+ if (simplex != points)
+ qh_settempfree(&simplex);
+ qh_settempfree(&points);
+ return normal;
+} /* detvnorm */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="detvridge">-</a>
+
+ qh_detvridge( vertexA )
+ determine Voronoi ridge from 'seen' neighbors of vertexA
+ include one vertex-at-infinite if an !neighbor->visitid
+
+ returns:
+ temporary set of centers (facets, i.e., Voronoi vertices)
+ sorted by center id
+*/
+setT *qh_detvridge(vertexT *vertex) {
+ setT *centers= qh_settemp(qh TEMPsize);
+ setT *tricenters= qh_settemp(qh TEMPsize);
+ facetT *neighbor, **neighborp;
+ boolT firstinf= True;
+
+ FOREACHneighbor_(vertex) {
+ if (neighbor->seen) {
+ if (neighbor->visitid) {
+ if (!neighbor->tricoplanar || qh_setunique(&tricenters, neighbor->center))
+ qh_setappend(&centers, neighbor);
+ }else if (firstinf) {
+ firstinf= False;
+ qh_setappend(&centers, neighbor);
+ }
+ }
+ }
+ qsort(SETaddr_(centers, facetT), (size_t)qh_setsize(centers),
+ sizeof(facetT *), qh_compare_facetvisit);
+ qh_settempfree(&tricenters);
+ return centers;
+} /* detvridge */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="detvridge3">-</a>
+
+ qh_detvridge3( atvertex, vertex )
+ determine 3-d Voronoi ridge from 'seen' neighbors of atvertex and vertex
+ include one vertex-at-infinite for !neighbor->visitid
+ assumes all facet->seen2= True
+
+ returns:
+ temporary set of centers (facets, i.e., Voronoi vertices)
+ listed in adjacency order (!oriented)
+ all facet->seen2= True
+
+ design:
+ mark all neighbors of atvertex
+ for each adjacent neighbor of both atvertex and vertex
+ if neighbor selected
+ add neighbor to set of Voronoi vertices
+*/
+setT *qh_detvridge3(vertexT *atvertex, vertexT *vertex) {
+ setT *centers= qh_settemp(qh TEMPsize);
+ setT *tricenters= qh_settemp(qh TEMPsize);
+ facetT *neighbor, **neighborp, *facet= NULL;
+ boolT firstinf= True;
+
+ FOREACHneighbor_(atvertex)
+ neighbor->seen2= False;
+ FOREACHneighbor_(vertex) {
+ if (!neighbor->seen2) {
+ facet= neighbor;
+ break;
+ }
+ }
+ while (facet) {
+ facet->seen2= True;
+ if (neighbor->seen) {
+ if (facet->visitid) {
+ if (!facet->tricoplanar || qh_setunique(&tricenters, facet->center))
+ qh_setappend(&centers, facet);
+ }else if (firstinf) {
+ firstinf= False;
+ qh_setappend(&centers, facet);
+ }
+ }
+ FOREACHneighbor_(facet) {
+ if (!neighbor->seen2) {
+ if (qh_setin(vertex->neighbors, neighbor))
+ break;
+ else
+ neighbor->seen2= True;
+ }
+ }
+ facet= neighbor;
+ }
+ if (qh CHECKfrequently) {
+ FOREACHneighbor_(vertex) {
+ if (!neighbor->seen2) {
+ qh_fprintf(qh ferr, 6217, "qhull internal error (qh_detvridge3): neighbors of vertex p%d are not connected at facet %d\n",
+ qh_pointid(vertex->point), neighbor->id);
+ qh_errexit(qh_ERRqhull, neighbor, NULL);
+ }
+ }
+ }
+ FOREACHneighbor_(atvertex)
+ neighbor->seen2= True;
+ qh_settempfree(&tricenters);
+ return centers;
+} /* detvridge3 */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="eachvoronoi">-</a>
+
+ qh_eachvoronoi( fp, printvridge, vertex, visitall, innerouter, inorder )
+ if visitall,
+ visit all Voronoi ridges for vertex (i.e., an input site)
+ else
+ visit all unvisited Voronoi ridges for vertex
+ all vertex->seen= False if unvisited
+ assumes
+ all facet->seen= False
+ all facet->seen2= True (for qh_detvridge3)
+ all facet->visitid == 0 if vertex_at_infinity
+ == index of Voronoi vertex
+ >= qh.num_facets if ignored
+ innerouter:
+ qh_RIDGEall-- both inner (bounded) and outer(unbounded) ridges
+ qh_RIDGEinner- only inner
+ qh_RIDGEouter- only outer
+
+ if inorder
+ orders vertices for 3-d Voronoi diagrams
+
+ returns:
+ number of visited ridges (does not include previously visited ridges)
+
+ if printvridge,
+ calls printvridge( fp, vertex, vertexA, centers)
+ fp== any pointer (assumes FILE*)
+ vertex,vertexA= pair of input sites that define a Voronoi ridge
+ centers= set of facets (i.e., Voronoi vertices)
+ ->visitid == index or 0 if vertex_at_infinity
+ ordered for 3-d Voronoi diagram
+ notes:
+ uses qh.vertex_visit
+
+ see:
+ qh_eachvoronoi_all()
+
+ design:
+ mark selected neighbors of atvertex
+ for each selected neighbor (either Voronoi vertex or vertex-at-infinity)
+ for each unvisited vertex
+ if atvertex and vertex share more than d-1 neighbors
+ bump totalcount
+ if printvridge defined
+ build the set of shared neighbors (i.e., Voronoi vertices)
+ call printvridge
+*/
+int qh_eachvoronoi(FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder) {
+ boolT unbounded;
+ int count;
+ facetT *neighbor, **neighborp, *neighborA, **neighborAp;
+ setT *centers;
+ setT *tricenters= qh_settemp(qh TEMPsize);
+
+ vertexT *vertex, **vertexp;
+ boolT firstinf;
+ unsigned int numfacets= (unsigned int)qh num_facets;
+ int totridges= 0;
+
+ qh vertex_visit++;
+ atvertex->seen= True;
+ if (visitall) {
+ FORALLvertices
+ vertex->seen= False;
+ }
+ FOREACHneighbor_(atvertex) {
+ if (neighbor->visitid < numfacets)
+ neighbor->seen= True;
+ }
+ FOREACHneighbor_(atvertex) {
+ if (neighbor->seen) {
+ FOREACHvertex_(neighbor->vertices) {
+ if (vertex->visitid != qh vertex_visit && !vertex->seen) {
+ vertex->visitid= qh vertex_visit;
+ count= 0;
+ firstinf= True;
+ qh_settruncate(tricenters, 0);
+ FOREACHneighborA_(vertex) {
+ if (neighborA->seen) {
+ if (neighborA->visitid) {
+ if (!neighborA->tricoplanar || qh_setunique(&tricenters, neighborA->center))
+ count++;
+ }else if (firstinf) {
+ count++;
+ firstinf= False;
+ }
+ }
+ }
+ if (count >= qh hull_dim - 1) { /* e.g., 3 for 3-d Voronoi */
+ if (firstinf) {
+ if (innerouter == qh_RIDGEouter)
+ continue;
+ unbounded= False;
+ }else {
+ if (innerouter == qh_RIDGEinner)
+ continue;
+ unbounded= True;
+ }
+ totridges++;
+ trace4((qh ferr, 4017, "qh_eachvoronoi: Voronoi ridge of %d vertices between sites %d and %d\n",
+ count, qh_pointid(atvertex->point), qh_pointid(vertex->point)));
+ if (printvridge && fp) {
+ if (inorder && qh hull_dim == 3+1) /* 3-d Voronoi diagram */
+ centers= qh_detvridge3(atvertex, vertex);
+ else
+ centers= qh_detvridge(vertex);
+ (*printvridge)(fp, atvertex, vertex, centers, unbounded);
+ qh_settempfree(&centers);
+ }
+ }
+ }
+ }
+ }
+ }
+ FOREACHneighbor_(atvertex)
+ neighbor->seen= False;
+ qh_settempfree(&tricenters);
+ return totridges;
+} /* eachvoronoi */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="eachvoronoi_all">-</a>
+
+ qh_eachvoronoi_all( fp, printvridge, isUpper, innerouter, inorder )
+ visit all Voronoi ridges
+
+ innerouter:
+ see qh_eachvoronoi()
+
+ if inorder
+ orders vertices for 3-d Voronoi diagrams
+
+ returns
+ total number of ridges
+
+ if isUpper == facet->upperdelaunay (i.e., a Vornoi vertex)
+ facet->visitid= Voronoi vertex index(same as 'o' format)
+ else
+ facet->visitid= 0
+
+ if printvridge,
+ calls printvridge( fp, vertex, vertexA, centers)
+ [see qh_eachvoronoi]
+
+ notes:
+ Not used for qhull.exe
+ same effect as qh_printvdiagram but ridges not sorted by point id
+*/
+int qh_eachvoronoi_all(FILE *fp, printvridgeT printvridge, boolT isUpper, qh_RIDGE innerouter, boolT inorder) {
+ facetT *facet;
+ vertexT *vertex;
+ int numcenters= 1; /* vertex 0 is vertex-at-infinity */
+ int totridges= 0;
+
+ qh_clearcenters(qh_ASvoronoi);
+ qh_vertexneighbors();
+ maximize_(qh visit_id, (unsigned) qh num_facets);
+ FORALLfacets {
+ facet->visitid= 0;
+ facet->seen= False;
+ facet->seen2= True;
+ }
+ FORALLfacets {
+ if (facet->upperdelaunay == isUpper)
+ facet->visitid= numcenters++;
+ }
+ FORALLvertices
+ vertex->seen= False;
+ FORALLvertices {
+ if (qh GOODvertex > 0 && qh_pointid(vertex->point)+1 != qh GOODvertex)
+ continue;
+ totridges += qh_eachvoronoi(fp, printvridge, vertex,
+ !qh_ALL, innerouter, inorder);
+ }
+ return totridges;
+} /* eachvoronoi_all */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="facet2point">-</a>
+
+ qh_facet2point( facet, point0, point1, mindist )
+ return two projected temporary vertices for a 2-d facet
+ may be non-simplicial
+
+ returns:
+ point0 and point1 oriented and projected to the facet
+ returns mindist (maximum distance below plane)
+*/
+void qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mindist) {
+ vertexT *vertex0, *vertex1;
+ realT dist;
+
+ if (facet->toporient ^ qh_ORIENTclock) {
+ vertex0= SETfirstt_(facet->vertices, vertexT);
+ vertex1= SETsecondt_(facet->vertices, vertexT);
+ }else {
+ vertex1= SETfirstt_(facet->vertices, vertexT);
+ vertex0= SETsecondt_(facet->vertices, vertexT);
+ }
+ zadd_(Zdistio, 2);
+ qh_distplane(vertex0->point, facet, &dist);
+ *mindist= dist;
+ *point0= qh_projectpoint(vertex0->point, facet, dist);
+ qh_distplane(vertex1->point, facet, &dist);
+ minimize_(*mindist, dist);
+ *point1= qh_projectpoint(vertex1->point, facet, dist);
+} /* facet2point */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="facetvertices">-</a>
+
+ qh_facetvertices( facetlist, facets, allfacets )
+ returns temporary set of vertices in a set and/or list of facets
+ if allfacets, ignores qh_skipfacet()
+
+ returns:
+ vertices with qh.vertex_visit
+
+ notes:
+ optimized for allfacets of facet_list
+
+ design:
+ if allfacets of facet_list
+ create vertex set from vertex_list
+ else
+ for each selected facet in facets or facetlist
+ append unvisited vertices to vertex set
+*/
+setT *qh_facetvertices(facetT *facetlist, setT *facets, boolT allfacets) {
+ setT *vertices;
+ facetT *facet, **facetp;
+ vertexT *vertex, **vertexp;
+
+ qh vertex_visit++;
+ if (facetlist == qh facet_list && allfacets && !facets) {
+ vertices= qh_settemp(qh num_vertices);
+ FORALLvertices {
+ vertex->visitid= qh vertex_visit;
+ qh_setappend(&vertices, vertex);
+ }
+ }else {
+ vertices= qh_settemp(qh TEMPsize);
+ FORALLfacet_(facetlist) {
+ if (!allfacets && qh_skipfacet(facet))
+ continue;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->visitid != qh vertex_visit) {
+ vertex->visitid= qh vertex_visit;
+ qh_setappend(&vertices, vertex);
+ }
+ }
+ }
+ }
+ FOREACHfacet_(facets) {
+ if (!allfacets && qh_skipfacet(facet))
+ continue;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->visitid != qh vertex_visit) {
+ vertex->visitid= qh vertex_visit;
+ qh_setappend(&vertices, vertex);
+ }
+ }
+ }
+ return vertices;
+} /* facetvertices */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="geomplanes">-</a>
+
+ qh_geomplanes( facet, outerplane, innerplane )
+ return outer and inner planes for Geomview
+ qh.PRINTradius is size of vertices and points (includes qh.JOGGLEmax)
+
+ notes:
+ assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
+*/
+void qh_geomplanes(facetT *facet, realT *outerplane, realT *innerplane) {
+ realT radius;
+
+ if (qh MERGING || qh JOGGLEmax < REALmax/2) {
+ qh_outerinner(facet, outerplane, innerplane);
+ radius= qh PRINTradius;
+ if (qh JOGGLEmax < REALmax/2)
+ radius -= qh JOGGLEmax * sqrt((realT)qh hull_dim); /* already accounted for in qh_outerinner() */
+ *outerplane += radius;
+ *innerplane -= radius;
+ if (qh PRINTcoplanar || qh PRINTspheres) {
+ *outerplane += qh MAXabs_coord * qh_GEOMepsilon;
+ *innerplane -= qh MAXabs_coord * qh_GEOMepsilon;
+ }
+ }else
+ *innerplane= *outerplane= 0;
+} /* geomplanes */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="markkeep">-</a>
+
+ qh_markkeep( facetlist )
+ mark good facets that meet qh.KEEParea, qh.KEEPmerge, and qh.KEEPminArea
+ ignores visible facets (!part of convex hull)
+
+ returns:
+ may clear facet->good
+ recomputes qh.num_good
+
+ design:
+ get set of good facets
+ if qh.KEEParea
+ sort facets by area
+ clear facet->good for all but n largest facets
+ if qh.KEEPmerge
+ sort facets by merge count
+ clear facet->good for all but n most merged facets
+ if qh.KEEPminarea
+ clear facet->good if area too small
+ update qh.num_good
+*/
+void qh_markkeep(facetT *facetlist) {
+ facetT *facet, **facetp;
+ setT *facets= qh_settemp(qh num_facets);
+ int size, count;
+
+ trace2((qh ferr, 2006, "qh_markkeep: only keep %d largest and/or %d most merged facets and/or min area %.2g\n",
+ qh KEEParea, qh KEEPmerge, qh KEEPminArea));
+ FORALLfacet_(facetlist) {
+ if (!facet->visible && facet->good)
+ qh_setappend(&facets, facet);
+ }
+ size= qh_setsize(facets);
+ if (qh KEEParea) {
+ qsort(SETaddr_(facets, facetT), (size_t)size,
+ sizeof(facetT *), qh_compare_facetarea);
+ if ((count= size - qh KEEParea) > 0) {
+ FOREACHfacet_(facets) {
+ facet->good= False;
+ if (--count == 0)
+ break;
+ }
+ }
+ }
+ if (qh KEEPmerge) {
+ qsort(SETaddr_(facets, facetT), (size_t)size,
+ sizeof(facetT *), qh_compare_facetmerge);
+ if ((count= size - qh KEEPmerge) > 0) {
+ FOREACHfacet_(facets) {
+ facet->good= False;
+ if (--count == 0)
+ break;
+ }
+ }
+ }
+ if (qh KEEPminArea < REALmax/2) {
+ FOREACHfacet_(facets) {
+ if (!facet->isarea || facet->f.area < qh KEEPminArea)
+ facet->good= False;
+ }
+ }
+ qh_settempfree(&facets);
+ count= 0;
+ FORALLfacet_(facetlist) {
+ if (facet->good)
+ count++;
+ }
+ qh num_good= count;
+} /* markkeep */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="markvoronoi">-</a>
+
+ qh_markvoronoi( facetlist, facets, printall, isLower, numcenters )
+ mark voronoi vertices for printing by site pairs
+
+ returns:
+ temporary set of vertices indexed by pointid
+ isLower set if printing lower hull (i.e., at least one facet is lower hull)
+ numcenters= total number of Voronoi vertices
+ bumps qh.printoutnum for vertex-at-infinity
+ clears all facet->seen and sets facet->seen2
+
+ if selected
+ facet->visitid= Voronoi vertex id
+ else if upper hull (or 'Qu' and lower hull)
+ facet->visitid= 0
+ else
+ facet->visitid >= qh num_facets
+
+ notes:
+ ignores qh.ATinfinity, if defined
+*/
+setT *qh_markvoronoi(facetT *facetlist, setT *facets, boolT printall, boolT *isLowerp, int *numcentersp) {
+ int numcenters=0;
+ facetT *facet, **facetp;
+ setT *vertices;
+ boolT isLower= False;
+
+ qh printoutnum++;
+ qh_clearcenters(qh_ASvoronoi); /* in case, qh_printvdiagram2 called by user */
+ qh_vertexneighbors();
+ vertices= qh_pointvertex();
+ if (qh ATinfinity)
+ SETelem_(vertices, qh num_points-1)= NULL;
+ qh visit_id++;
+ maximize_(qh visit_id, (unsigned) qh num_facets);
+ FORALLfacet_(facetlist) {
+ if (printall || !qh_skipfacet(facet)) {
+ if (!facet->upperdelaunay) {
+ isLower= True;
+ break;
+ }
+ }
+ }
+ FOREACHfacet_(facets) {
+ if (printall || !qh_skipfacet(facet)) {
+ if (!facet->upperdelaunay) {
+ isLower= True;
+ break;
+ }
+ }
+ }
+ FORALLfacets {
+ if (facet->normal && (facet->upperdelaunay == isLower))
+ facet->visitid= 0; /* facetlist or facets may overwrite */
+ else
+ facet->visitid= qh visit_id;
+ facet->seen= False;
+ facet->seen2= True;
+ }
+ numcenters++; /* qh_INFINITE */
+ FORALLfacet_(facetlist) {
+ if (printall || !qh_skipfacet(facet))
+ facet->visitid= numcenters++;
+ }
+ FOREACHfacet_(facets) {
+ if (printall || !qh_skipfacet(facet))
+ facet->visitid= numcenters++;
+ }
+ *isLowerp= isLower;
+ *numcentersp= numcenters;
+ trace2((qh ferr, 2007, "qh_markvoronoi: isLower %d numcenters %d\n", isLower, numcenters));
+ return vertices;
+} /* markvoronoi */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="order_vertexneighbors">-</a>
+
+ qh_order_vertexneighbors( vertex )
+ order facet neighbors of a 2-d or 3-d vertex by adjacency
+
+ notes:
+ does not orient the neighbors
+
+ design:
+ initialize a new neighbor set with the first facet in vertex->neighbors
+ while vertex->neighbors non-empty
+ select next neighbor in the previous facet's neighbor set
+ set vertex->neighbors to the new neighbor set
+*/
+void qh_order_vertexneighbors(vertexT *vertex) {
+ setT *newset;
+ facetT *facet, *neighbor, **neighborp;
+
+ trace4((qh ferr, 4018, "qh_order_vertexneighbors: order neighbors of v%d for 3-d\n", vertex->id));
+ newset= qh_settemp(qh_setsize(vertex->neighbors));
+ facet= (facetT*)qh_setdellast(vertex->neighbors);
+ qh_setappend(&newset, facet);
+ while (qh_setsize(vertex->neighbors)) {
+ FOREACHneighbor_(vertex) {
+ if (qh_setin(facet->neighbors, neighbor)) {
+ qh_setdel(vertex->neighbors, neighbor);
+ qh_setappend(&newset, neighbor);
+ facet= neighbor;
+ break;
+ }
+ }
+ if (!neighbor) {
+ qh_fprintf(qh ferr, 6066, "qhull internal error (qh_order_vertexneighbors): no neighbor of v%d for f%d\n",
+ vertex->id, facet->id);
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ }
+ qh_setfree(&vertex->neighbors);
+ qh_settemppop();
+ vertex->neighbors= newset;
+} /* order_vertexneighbors */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="prepare_output">-</a>
+
+ qh_prepare_output( )
+ prepare for qh_produce_output2() according to
+ qh.KEEPminArea, KEEParea, KEEPmerge, GOODvertex, GOODthreshold, GOODpoint, ONLYgood, SPLITthresholds
+ does not reset facet->good
+
+ notes
+ except for PRINTstatistics, no-op if previously called with same options
+*/
+void qh_prepare_output(void) {
+ if (qh VORONOI) {
+ qh_clearcenters(qh_ASvoronoi); /* must be before qh_triangulate */
+ qh_vertexneighbors();
+ }
+ if (qh TRIangulate && !qh hasTriangulation) {
+ qh_triangulate();
+ if (qh VERIFYoutput && !qh CHECKfrequently)
+ qh_checkpolygon(qh facet_list);
+ }
+ qh_findgood_all(qh facet_list);
+ if (qh GETarea)
+ qh_getarea(qh facet_list);
+ if (qh KEEParea || qh KEEPmerge || qh KEEPminArea < REALmax/2)
+ qh_markkeep(qh facet_list);
+ if (qh PRINTstatistics)
+ qh_collectstatistics();
+}
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printafacet">-</a>
+
+ qh_printafacet( fp, format, facet, printall )
+ print facet to fp in given output format (see qh.PRINTout)
+
+ returns:
+ nop if !printall and qh_skipfacet()
+ nop if visible facet and NEWfacets and format != PRINTfacets
+ must match qh_countfacets
+
+ notes
+ preserves qh.visit_id
+ facet->normal may be null if PREmerge/MERGEexact and STOPcone before merge
+
+ see
+ qh_printbegin() and qh_printend()
+
+ design:
+ test for printing facet
+ call appropriate routine for format
+ or output results directly
+*/
+void qh_printafacet(FILE *fp, qh_PRINT format, facetT *facet, boolT printall) {
+ realT color[4], offset, dist, outerplane, innerplane;
+ boolT zerodiv;
+ coordT *point, *normp, *coordp, **pointp, *feasiblep;
+ int k;
+ vertexT *vertex, **vertexp;
+ facetT *neighbor, **neighborp;
+
+ if (!printall && qh_skipfacet(facet))
+ return;
+ if (facet->visible && qh NEWfacets && format != qh_PRINTfacets)
+ return;
+ qh printoutnum++;
+ switch (format) {
+ case qh_PRINTarea:
+ if (facet->isarea) {
+ qh_fprintf(fp, 9009, qh_REAL_1, facet->f.area);
+ qh_fprintf(fp, 9010, "\n");
+ }else
+ qh_fprintf(fp, 9011, "0\n");
+ break;
+ case qh_PRINTcoplanars:
+ qh_fprintf(fp, 9012, "%d", qh_setsize(facet->coplanarset));
+ FOREACHpoint_(facet->coplanarset)
+ qh_fprintf(fp, 9013, " %d", qh_pointid(point));
+ qh_fprintf(fp, 9014, "\n");
+ break;
+ case qh_PRINTcentrums:
+ qh_printcenter(fp, format, NULL, facet);
+ break;
+ case qh_PRINTfacets:
+ qh_printfacet(fp, facet);
+ break;
+ case qh_PRINTfacets_xridge:
+ qh_printfacetheader(fp, facet);
+ break;
+ case qh_PRINTgeom: /* either 2 , 3, or 4-d by qh_printbegin */
+ if (!facet->normal)
+ break;
+ for (k=qh hull_dim; k--; ) {
+ color[k]= (facet->normal[k]+1.0)/2.0;
+ maximize_(color[k], -1.0);
+ minimize_(color[k], +1.0);
+ }
+ qh_projectdim3(color, color);
+ if (qh PRINTdim != qh hull_dim)
+ qh_normalize2(color, 3, True, NULL, NULL);
+ if (qh hull_dim <= 2)
+ qh_printfacet2geom(fp, facet, color);
+ else if (qh hull_dim == 3) {
+ if (facet->simplicial)
+ qh_printfacet3geom_simplicial(fp, facet, color);
+ else
+ qh_printfacet3geom_nonsimplicial(fp, facet, color);
+ }else {
+ if (facet->simplicial)
+ qh_printfacet4geom_simplicial(fp, facet, color);
+ else
+ qh_printfacet4geom_nonsimplicial(fp, facet, color);
+ }
+ break;
+ case qh_PRINTids:
+ qh_fprintf(fp, 9015, "%d\n", facet->id);
+ break;
+ case qh_PRINTincidences:
+ case qh_PRINToff:
+ case qh_PRINTtriangles:
+ if (qh hull_dim == 3 && format != qh_PRINTtriangles)
+ qh_printfacet3vertex(fp, facet, format);
+ else if (facet->simplicial || qh hull_dim == 2 || format == qh_PRINToff)
+ qh_printfacetNvertex_simplicial(fp, facet, format);
+ else
+ qh_printfacetNvertex_nonsimplicial(fp, facet, qh printoutvar++, format);
+ break;
+ case qh_PRINTinner:
+ qh_outerinner(facet, NULL, &innerplane);
+ offset= facet->offset - innerplane;
+ goto LABELprintnorm;
+ break; /* prevent warning */
+ case qh_PRINTmerges:
+ qh_fprintf(fp, 9016, "%d\n", facet->nummerge);
+ break;
+ case qh_PRINTnormals:
+ offset= facet->offset;
+ goto LABELprintnorm;
+ break; /* prevent warning */
+ case qh_PRINTouter:
+ qh_outerinner(facet, &outerplane, NULL);
+ offset= facet->offset - outerplane;
+ LABELprintnorm:
+ if (!facet->normal) {
+ qh_fprintf(fp, 9017, "no normal for facet f%d\n", facet->id);
+ break;
+ }
+ if (qh CDDoutput) {
+ qh_fprintf(fp, 9018, qh_REAL_1, -offset);
+ for (k=0; k < qh hull_dim; k++)
+ qh_fprintf(fp, 9019, qh_REAL_1, -facet->normal[k]);
+ }else {
+ for (k=0; k < qh hull_dim; k++)
+ qh_fprintf(fp, 9020, qh_REAL_1, facet->normal[k]);
+ qh_fprintf(fp, 9021, qh_REAL_1, offset);
+ }
+ qh_fprintf(fp, 9022, "\n");
+ break;
+ case qh_PRINTmathematica: /* either 2 or 3-d by qh_printbegin */
+ case qh_PRINTmaple:
+ if (qh hull_dim == 2)
+ qh_printfacet2math(fp, facet, format, qh printoutvar++);
+ else
+ qh_printfacet3math(fp, facet, format, qh printoutvar++);
+ break;
+ case qh_PRINTneighbors:
+ qh_fprintf(fp, 9023, "%d", qh_setsize(facet->neighbors));
+ FOREACHneighbor_(facet)
+ qh_fprintf(fp, 9024, " %d",
+ neighbor->visitid ? neighbor->visitid - 1: 0 - neighbor->id);
+ qh_fprintf(fp, 9025, "\n");
+ break;
+ case qh_PRINTpointintersect:
+ if (!qh feasible_point) {
+ qh_fprintf(qh ferr, 6067, "qhull input error (qh_printafacet): option 'Fp' needs qh feasible_point\n");
+ qh_errexit( qh_ERRinput, NULL, NULL);
+ }
+ if (facet->offset > 0)
+ goto LABELprintinfinite;
+ point= coordp= (coordT*)qh_memalloc(qh normal_size);
+ normp= facet->normal;
+ feasiblep= qh feasible_point;
+ if (facet->offset < -qh MINdenom) {
+ for (k=qh hull_dim; k--; )
+ *(coordp++)= (*(normp++) / - facet->offset) + *(feasiblep++);
+ }else {
+ for (k=qh hull_dim; k--; ) {
+ *(coordp++)= qh_divzero(*(normp++), facet->offset, qh MINdenom_1,
+ &zerodiv) + *(feasiblep++);
+ if (zerodiv) {
+ qh_memfree(point, qh normal_size);
+ goto LABELprintinfinite;
+ }
+ }
+ }
+ qh_printpoint(fp, NULL, point);
+ qh_memfree(point, qh normal_size);
+ break;
+ LABELprintinfinite:
+ for (k=qh hull_dim; k--; )
+ qh_fprintf(fp, 9026, qh_REAL_1, qh_INFINITE);
+ qh_fprintf(fp, 9027, "\n");
+ break;
+ case qh_PRINTpointnearest:
+ FOREACHpoint_(facet->coplanarset) {
+ int id, id2;
+ vertex= qh_nearvertex(facet, point, &dist);
+ id= qh_pointid(vertex->point);
+ id2= qh_pointid(point);
+ qh_fprintf(fp, 9028, "%d %d %d " qh_REAL_1 "\n", id, id2, facet->id, dist);
+ }
+ break;
+ case qh_PRINTpoints: /* VORONOI only by qh_printbegin */
+ if (qh CDDoutput)
+ qh_fprintf(fp, 9029, "1 ");
+ qh_printcenter(fp, format, NULL, facet);
+ break;
+ case qh_PRINTvertices:
+ qh_fprintf(fp, 9030, "%d", qh_setsize(facet->vertices));
+ FOREACHvertex_(facet->vertices)
+ qh_fprintf(fp, 9031, " %d", qh_pointid(vertex->point));
+ qh_fprintf(fp, 9032, "\n");
+ break;
+ default:
+ break;
+ }
+} /* printafacet */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printbegin">-</a>
+
+ qh_printbegin( )
+ prints header for all output formats
+
+ returns:
+ checks for valid format
+
+ notes:
+ uses qh.visit_id for 3/4off
+ changes qh.interior_point if printing centrums
+ qh_countfacets clears facet->visitid for non-good facets
+
+ see
+ qh_printend() and qh_printafacet()
+
+ design:
+ count facets and related statistics
+ print header for format
+*/
+void qh_printbegin(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
+ int numfacets, numsimplicial, numridges, totneighbors, numcoplanars, numtricoplanars;
+ int i, num;
+ facetT *facet, **facetp;
+ vertexT *vertex, **vertexp;
+ setT *vertices;
+ pointT *point, **pointp, *pointtemp;
+
+ qh printoutnum= 0;
+ qh_countfacets(facetlist, facets, printall, &numfacets, &numsimplicial,
+ &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
+ switch (format) {
+ case qh_PRINTnone:
+ break;
+ case qh_PRINTarea:
+ qh_fprintf(fp, 9033, "%d\n", numfacets);
+ break;
+ case qh_PRINTcoplanars:
+ qh_fprintf(fp, 9034, "%d\n", numfacets);
+ break;
+ case qh_PRINTcentrums:
+ if (qh CENTERtype == qh_ASnone)
+ qh_clearcenters(qh_AScentrum);
+ qh_fprintf(fp, 9035, "%d\n%d\n", qh hull_dim, numfacets);
+ break;
+ case qh_PRINTfacets:
+ case qh_PRINTfacets_xridge:
+ if (facetlist)
+ qh_printvertexlist(fp, "Vertices and facets:\n", facetlist, facets, printall);
+ break;
+ case qh_PRINTgeom:
+ if (qh hull_dim > 4) /* qh_initqhull_globals also checks */
+ goto LABELnoformat;
+ if (qh VORONOI && qh hull_dim > 3) /* PRINTdim == DROPdim == hull_dim-1 */
+ goto LABELnoformat;
+ if (qh hull_dim == 2 && (qh PRINTridges || qh DOintersections))
+ qh_fprintf(qh ferr, 7049, "qhull warning: output for ridges and intersections not implemented in 2-d\n");
+ if (qh hull_dim == 4 && (qh PRINTinner || qh PRINTouter ||
+ (qh PRINTdim == 4 && qh PRINTcentrums)))
+ qh_fprintf(qh ferr, 7050, "qhull warning: output for outer/inner planes and centrums not implemented in 4-d\n");
+ if (qh PRINTdim == 4 && (qh PRINTspheres))
+ qh_fprintf(qh ferr, 7051, "qhull warning: output for vertices not implemented in 4-d\n");
+ if (qh PRINTdim == 4 && qh DOintersections && qh PRINTnoplanes)
+ qh_fprintf(qh ferr, 7052, "qhull warning: 'Gnh' generates no output in 4-d\n");
+ if (qh PRINTdim == 2) {
+ qh_fprintf(fp, 9036, "{appearance {linewidth 3} LIST # %s | %s\n",
+ qh rbox_command, qh qhull_command);
+ }else if (qh PRINTdim == 3) {
+ qh_fprintf(fp, 9037, "{appearance {+edge -evert linewidth 2} LIST # %s | %s\n",
+ qh rbox_command, qh qhull_command);
+ }else if (qh PRINTdim == 4) {
+ qh visit_id++;
+ num= 0;
+ FORALLfacet_(facetlist) /* get number of ridges to be printed */
+ qh_printend4geom(NULL, facet, &num, printall);
+ FOREACHfacet_(facets)
+ qh_printend4geom(NULL, facet, &num, printall);
+ qh ridgeoutnum= num;
+ qh printoutvar= 0; /* counts number of ridges in output */
+ qh_fprintf(fp, 9038, "LIST # %s | %s\n", qh rbox_command, qh qhull_command);
+ }
+
+ if (qh PRINTdots) {
+ qh printoutnum++;
+ num= qh num_points + qh_setsize(qh other_points);
+ if (qh DELAUNAY && qh ATinfinity)
+ num--;
+ if (qh PRINTdim == 4)
+ qh_fprintf(fp, 9039, "4VECT %d %d 1\n", num, num);
+ else
+ qh_fprintf(fp, 9040, "VECT %d %d 1\n", num, num);
+
+ for (i=num; i--; ) {
+ if (i % 20 == 0)
+ qh_fprintf(fp, 9041, "\n");
+ qh_fprintf(fp, 9042, "1 ");
+ }
+ qh_fprintf(fp, 9043, "# 1 point per line\n1 ");
+ for (i=num-1; i--; ) { /* num at least 3 for D2 */
+ if (i % 20 == 0)
+ qh_fprintf(fp, 9044, "\n");
+ qh_fprintf(fp, 9045, "0 ");
+ }
+ qh_fprintf(fp, 9046, "# 1 color for all\n");
+ FORALLpoints {
+ if (!qh DELAUNAY || !qh ATinfinity || qh_pointid(point) != qh num_points-1) {
+ if (qh PRINTdim == 4)
+ qh_printpoint(fp, NULL, point);
+ else
+ qh_printpoint3(fp, point);
+ }
+ }
+ FOREACHpoint_(qh other_points) {
+ if (qh PRINTdim == 4)
+ qh_printpoint(fp, NULL, point);
+ else
+ qh_printpoint3(fp, point);
+ }
+ qh_fprintf(fp, 9047, "0 1 1 1 # color of points\n");
+ }
+
+ if (qh PRINTdim == 4 && !qh PRINTnoplanes)
+ /* 4dview loads up multiple 4OFF objects slowly */
+ qh_fprintf(fp, 9048, "4OFF %d %d 1\n", 3*qh ridgeoutnum, qh ridgeoutnum);
+ qh PRINTcradius= 2 * qh DISTround; /* include test DISTround */
+ if (qh PREmerge) {
+ maximize_(qh PRINTcradius, qh premerge_centrum + qh DISTround);
+ }else if (qh POSTmerge)
+ maximize_(qh PRINTcradius, qh postmerge_centrum + qh DISTround);
+ qh PRINTradius= qh PRINTcradius;
+ if (qh PRINTspheres + qh PRINTcoplanar)
+ maximize_(qh PRINTradius, qh MAXabs_coord * qh_MINradius);
+ if (qh premerge_cos < REALmax/2) {
+ maximize_(qh PRINTradius, (1- qh premerge_cos) * qh MAXabs_coord);
+ }else if (!qh PREmerge && qh POSTmerge && qh postmerge_cos < REALmax/2) {
+ maximize_(qh PRINTradius, (1- qh postmerge_cos) * qh MAXabs_coord);
+ }
+ maximize_(qh PRINTradius, qh MINvisible);
+ if (qh JOGGLEmax < REALmax/2)
+ qh PRINTradius += qh JOGGLEmax * sqrt((realT)qh hull_dim);
+ if (qh PRINTdim != 4 &&
+ (qh PRINTcoplanar || qh PRINTspheres || qh PRINTcentrums)) {
+ vertices= qh_facetvertices(facetlist, facets, printall);
+ if (qh PRINTspheres && qh PRINTdim <= 3)
+ qh_printspheres(fp, vertices, qh PRINTradius);
+ if (qh PRINTcoplanar || qh PRINTcentrums) {
+ qh firstcentrum= True;
+ if (qh PRINTcoplanar&& !qh PRINTspheres) {
+ FOREACHvertex_(vertices)
+ qh_printpointvect2(fp, vertex->point, NULL, qh interior_point, qh PRINTradius);
+ }
+ FORALLfacet_(facetlist) {
+ if (!printall && qh_skipfacet(facet))
+ continue;
+ if (!facet->normal)
+ continue;
+ if (qh PRINTcentrums && qh PRINTdim <= 3)
+ qh_printcentrum(fp, facet, qh PRINTcradius);
+ if (!qh PRINTcoplanar)
+ continue;
+ FOREACHpoint_(facet->coplanarset)
+ qh_printpointvect2(fp, point, facet->normal, NULL, qh PRINTradius);
+ FOREACHpoint_(facet->outsideset)
+ qh_printpointvect2(fp, point, facet->normal, NULL, qh PRINTradius);
+ }
+ FOREACHfacet_(facets) {
+ if (!printall && qh_skipfacet(facet))
+ continue;
+ if (!facet->normal)
+ continue;
+ if (qh PRINTcentrums && qh PRINTdim <= 3)
+ qh_printcentrum(fp, facet, qh PRINTcradius);
+ if (!qh PRINTcoplanar)
+ continue;
+ FOREACHpoint_(facet->coplanarset)
+ qh_printpointvect2(fp, point, facet->normal, NULL, qh PRINTradius);
+ FOREACHpoint_(facet->outsideset)
+ qh_printpointvect2(fp, point, facet->normal, NULL, qh PRINTradius);
+ }
+ }
+ qh_settempfree(&vertices);
+ }
+ qh visit_id++; /* for printing hyperplane intersections */
+ break;
+ case qh_PRINTids:
+ qh_fprintf(fp, 9049, "%d\n", numfacets);
+ break;
+ case qh_PRINTincidences:
+ if (qh VORONOI && qh PRINTprecision)
+ qh_fprintf(qh ferr, 7053, "qhull warning: writing Delaunay. Use 'p' or 'o' for Voronoi centers\n");
+ qh printoutvar= qh vertex_id; /* centrum id for non-simplicial facets */
+ if (qh hull_dim <= 3)
+ qh_fprintf(fp, 9050, "%d\n", numfacets);
+ else
+ qh_fprintf(fp, 9051, "%d\n", numsimplicial+numridges);
+ break;
+ case qh_PRINTinner:
+ case qh_PRINTnormals:
+ case qh_PRINTouter:
+ if (qh CDDoutput)
+ qh_fprintf(fp, 9052, "%s | %s\nbegin\n %d %d real\n", qh rbox_command,
+ qh qhull_command, numfacets, qh hull_dim+1);
+ else
+ qh_fprintf(fp, 9053, "%d\n%d\n", qh hull_dim+1, numfacets);
+ break;
+ case qh_PRINTmathematica:
+ case qh_PRINTmaple:
+ if (qh hull_dim > 3) /* qh_initbuffers also checks */
+ goto LABELnoformat;
+ if (qh VORONOI)
+ qh_fprintf(qh ferr, 7054, "qhull warning: output is the Delaunay triangulation\n");
+ if (format == qh_PRINTmaple) {
+ if (qh hull_dim == 2)
+ qh_fprintf(fp, 9054, "PLOT(CURVES(\n");
+ else
+ qh_fprintf(fp, 9055, "PLOT3D(POLYGONS(\n");
+ }else
+ qh_fprintf(fp, 9056, "{\n");
+ qh printoutvar= 0; /* counts number of facets for notfirst */
+ break;
+ case qh_PRINTmerges:
+ qh_fprintf(fp, 9057, "%d\n", numfacets);
+ break;
+ case qh_PRINTpointintersect:
+ qh_fprintf(fp, 9058, "%d\n%d\n", qh hull_dim, numfacets);
+ break;
+ case qh_PRINTneighbors:
+ qh_fprintf(fp, 9059, "%d\n", numfacets);
+ break;
+ case qh_PRINToff:
+ case qh_PRINTtriangles:
+ if (qh VORONOI)
+ goto LABELnoformat;
+ num = qh hull_dim;
+ if (format == qh_PRINToff || qh hull_dim == 2)
+ qh_fprintf(fp, 9060, "%d\n%d %d %d\n", num,
+ qh num_points+qh_setsize(qh other_points), numfacets, totneighbors/2);
+ else { /* qh_PRINTtriangles */
+ qh printoutvar= qh num_points+qh_setsize(qh other_points); /* first centrum */
+ if (qh DELAUNAY)
+ num--; /* drop last dimension */
+ qh_fprintf(fp, 9061, "%d\n%d %d %d\n", num, qh printoutvar
+ + numfacets - numsimplicial, numsimplicial + numridges, totneighbors/2);
+ }
+ FORALLpoints
+ qh_printpointid(qh fout, NULL, num, point, qh_IDunknown);
+ FOREACHpoint_(qh other_points)
+ qh_printpointid(qh fout, NULL, num, point, qh_IDunknown);
+ if (format == qh_PRINTtriangles && qh hull_dim > 2) {
+ FORALLfacets {
+ if (!facet->simplicial && facet->visitid)
+ qh_printcenter(qh fout, format, NULL, facet);
+ }
+ }
+ break;
+ case qh_PRINTpointnearest:
+ qh_fprintf(fp, 9062, "%d\n", numcoplanars);
+ break;
+ case qh_PRINTpoints:
+ if (!qh VORONOI)
+ goto LABELnoformat;
+ if (qh CDDoutput)
+ qh_fprintf(fp, 9063, "%s | %s\nbegin\n%d %d real\n", qh rbox_command,
+ qh qhull_command, numfacets, qh hull_dim);
+ else
+ qh_fprintf(fp, 9064, "%d\n%d\n", qh hull_dim-1, numfacets);
+ break;
+ case qh_PRINTvertices:
+ qh_fprintf(fp, 9065, "%d\n", numfacets);
+ break;
+ case qh_PRINTsummary:
+ default:
+ LABELnoformat:
+ qh_fprintf(qh ferr, 6068, "qhull internal error (qh_printbegin): can not use this format for dimension %d\n",
+ qh hull_dim);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+} /* printbegin */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printcenter">-</a>
+
+ qh_printcenter( fp, string, facet )
+ print facet->center as centrum or Voronoi center
+ string may be NULL. Don't include '%' codes.
+ nop if qh CENTERtype neither CENTERvoronoi nor CENTERcentrum
+ if upper envelope of Delaunay triangulation and point at-infinity
+ prints qh_INFINITE instead;
+
+ notes:
+ defines facet->center if needed
+ if format=PRINTgeom, adds a 0 if would otherwise be 2-d
+ Same as QhullFacet::printCenter
+*/
+void qh_printcenter(FILE *fp, qh_PRINT format, const char *string, facetT *facet) {
+ int k, num;
+
+ if (qh CENTERtype != qh_ASvoronoi && qh CENTERtype != qh_AScentrum)
+ return;
+ if (string)
+ qh_fprintf(fp, 9066, string);
+ if (qh CENTERtype == qh_ASvoronoi) {
+ num= qh hull_dim-1;
+ if (!facet->normal || !facet->upperdelaunay || !qh ATinfinity) {
+ if (!facet->center)
+ facet->center= qh_facetcenter(facet->vertices);
+ for (k=0; k < num; k++)
+ qh_fprintf(fp, 9067, qh_REAL_1, facet->center[k]);
+ }else {
+ for (k=0; k < num; k++)
+ qh_fprintf(fp, 9068, qh_REAL_1, qh_INFINITE);
+ }
+ }else /* qh.CENTERtype == qh_AScentrum */ {
+ num= qh hull_dim;
+ if (format == qh_PRINTtriangles && qh DELAUNAY)
+ num--;
+ if (!facet->center)
+ facet->center= qh_getcentrum(facet);
+ for (k=0; k < num; k++)
+ qh_fprintf(fp, 9069, qh_REAL_1, facet->center[k]);
+ }
+ if (format == qh_PRINTgeom && num == 2)
+ qh_fprintf(fp, 9070, " 0\n");
+ else
+ qh_fprintf(fp, 9071, "\n");
+} /* printcenter */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printcentrum">-</a>
+
+ qh_printcentrum( fp, facet, radius )
+ print centrum for a facet in OOGL format
+ radius defines size of centrum
+ 2-d or 3-d only
+
+ returns:
+ defines facet->center if needed
+*/
+void qh_printcentrum(FILE *fp, facetT *facet, realT radius) {
+ pointT *centrum, *projpt;
+ boolT tempcentrum= False;
+ realT xaxis[4], yaxis[4], normal[4], dist;
+ realT green[3]={0, 1, 0};
+ vertexT *apex;
+ int k;
+
+ if (qh CENTERtype == qh_AScentrum) {
+ if (!facet->center)
+ facet->center= qh_getcentrum(facet);
+ centrum= facet->center;
+ }else {
+ centrum= qh_getcentrum(facet);
+ tempcentrum= True;
+ }
+ qh_fprintf(fp, 9072, "{appearance {-normal -edge normscale 0} ");
+ if (qh firstcentrum) {
+ qh firstcentrum= False;
+ qh_fprintf(fp, 9073, "{INST geom { define centrum CQUAD # f%d\n\
+-0.3 -0.3 0.0001 0 0 1 1\n\
+ 0.3 -0.3 0.0001 0 0 1 1\n\
+ 0.3 0.3 0.0001 0 0 1 1\n\
+-0.3 0.3 0.0001 0 0 1 1 } transform { \n", facet->id);
+ }else
+ qh_fprintf(fp, 9074, "{INST geom { : centrum } transform { # f%d\n", facet->id);
+ apex= SETfirstt_(facet->vertices, vertexT);
+ qh_distplane(apex->point, facet, &dist);
+ projpt= qh_projectpoint(apex->point, facet, dist);
+ for (k=qh hull_dim; k--; ) {
+ xaxis[k]= projpt[k] - centrum[k];
+ normal[k]= facet->normal[k];
+ }
+ if (qh hull_dim == 2) {
+ xaxis[2]= 0;
+ normal[2]= 0;
+ }else if (qh hull_dim == 4) {
+ qh_projectdim3(xaxis, xaxis);
+ qh_projectdim3(normal, normal);
+ qh_normalize2(normal, qh PRINTdim, True, NULL, NULL);
+ }
+ qh_crossproduct(3, xaxis, normal, yaxis);
+ qh_fprintf(fp, 9075, "%8.4g %8.4g %8.4g 0\n", xaxis[0], xaxis[1], xaxis[2]);
+ qh_fprintf(fp, 9076, "%8.4g %8.4g %8.4g 0\n", yaxis[0], yaxis[1], yaxis[2]);
+ qh_fprintf(fp, 9077, "%8.4g %8.4g %8.4g 0\n", normal[0], normal[1], normal[2]);
+ qh_printpoint3(fp, centrum);
+ qh_fprintf(fp, 9078, "1 }}}\n");
+ qh_memfree(projpt, qh normal_size);
+ qh_printpointvect(fp, centrum, facet->normal, NULL, radius, green);
+ if (tempcentrum)
+ qh_memfree(centrum, qh normal_size);
+} /* printcentrum */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printend">-</a>
+
+ qh_printend( fp, format )
+ prints trailer for all output formats
+
+ see:
+ qh_printbegin() and qh_printafacet()
+
+*/
+void qh_printend(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
+ int num;
+ facetT *facet, **facetp;
+
+ if (!qh printoutnum)
+ qh_fprintf(qh ferr, 7055, "qhull warning: no facets printed\n");
+ switch (format) {
+ case qh_PRINTgeom:
+ if (qh hull_dim == 4 && qh DROPdim < 0 && !qh PRINTnoplanes) {
+ qh visit_id++;
+ num= 0;
+ FORALLfacet_(facetlist)
+ qh_printend4geom(fp, facet,&num, printall);
+ FOREACHfacet_(facets)
+ qh_printend4geom(fp, facet, &num, printall);
+ if (num != qh ridgeoutnum || qh printoutvar != qh ridgeoutnum) {
+ qh_fprintf(qh ferr, 6069, "qhull internal error (qh_printend): number of ridges %d != number printed %d and at end %d\n", qh ridgeoutnum, qh printoutvar, num);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ }else
+ qh_fprintf(fp, 9079, "}\n");
+ break;
+ case qh_PRINTinner:
+ case qh_PRINTnormals:
+ case qh_PRINTouter:
+ if (qh CDDoutput)
+ qh_fprintf(fp, 9080, "end\n");
+ break;
+ case qh_PRINTmaple:
+ qh_fprintf(fp, 9081, "));\n");
+ break;
+ case qh_PRINTmathematica:
+ qh_fprintf(fp, 9082, "}\n");
+ break;
+ case qh_PRINTpoints:
+ if (qh CDDoutput)
+ qh_fprintf(fp, 9083, "end\n");
+ break;
+ default:
+ break;
+ }
+} /* printend */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printend4geom">-</a>
+
+ qh_printend4geom( fp, facet, numridges, printall )
+ helper function for qh_printbegin/printend
+
+ returns:
+ number of printed ridges
+
+ notes:
+ just counts printed ridges if fp=NULL
+ uses facet->visitid
+ must agree with qh_printfacet4geom...
+
+ design:
+ computes color for facet from its normal
+ prints each ridge of facet
+*/
+void qh_printend4geom(FILE *fp, facetT *facet, int *nump, boolT printall) {
+ realT color[3];
+ int i, num= *nump;
+ facetT *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+
+ if (!printall && qh_skipfacet(facet))
+ return;
+ if (qh PRINTnoplanes || (facet->visible && qh NEWfacets))
+ return;
+ if (!facet->normal)
+ return;
+ if (fp) {
+ for (i=0; i < 3; i++) {
+ color[i]= (facet->normal[i]+1.0)/2.0;
+ maximize_(color[i], -1.0);
+ minimize_(color[i], +1.0);
+ }
+ }
+ facet->visitid= qh visit_id;
+ if (facet->simplicial) {
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid != qh visit_id) {
+ if (fp)
+ qh_fprintf(fp, 9084, "3 %d %d %d %8.4g %8.4g %8.4g 1 # f%d f%d\n",
+ 3*num, 3*num+1, 3*num+2, color[0], color[1], color[2],
+ facet->id, neighbor->id);
+ num++;
+ }
+ }
+ }else {
+ FOREACHridge_(facet->ridges) {
+ neighbor= otherfacet_(ridge, facet);
+ if (neighbor->visitid != qh visit_id) {
+ if (fp)
+ qh_fprintf(fp, 9085, "3 %d %d %d %8.4g %8.4g %8.4g 1 #r%d f%d f%d\n",
+ 3*num, 3*num+1, 3*num+2, color[0], color[1], color[2],
+ ridge->id, facet->id, neighbor->id);
+ num++;
+ }
+ }
+ }
+ *nump= num;
+} /* printend4geom */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printextremes">-</a>
+
+ qh_printextremes( fp, facetlist, facets, printall )
+ print extreme points for convex hulls or halfspace intersections
+
+ notes:
+ #points, followed by ids, one per line
+
+ sorted by id
+ same order as qh_printpoints_out if no coplanar/interior points
+*/
+void qh_printextremes(FILE *fp, facetT *facetlist, setT *facets, boolT printall) {
+ setT *vertices, *points;
+ pointT *point;
+ vertexT *vertex, **vertexp;
+ int id;
+ int numpoints=0, point_i, point_n;
+ int allpoints= qh num_points + qh_setsize(qh other_points);
+
+ points= qh_settemp(allpoints);
+ qh_setzero(points, 0, allpoints);
+ vertices= qh_facetvertices(facetlist, facets, printall);
+ FOREACHvertex_(vertices) {
+ id= qh_pointid(vertex->point);
+ if (id >= 0) {
+ SETelem_(points, id)= vertex->point;
+ numpoints++;
+ }
+ }
+ qh_settempfree(&vertices);
+ qh_fprintf(fp, 9086, "%d\n", numpoints);
+ FOREACHpoint_i_(points) {
+ if (point)
+ qh_fprintf(fp, 9087, "%d\n", point_i);
+ }
+ qh_settempfree(&points);
+} /* printextremes */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printextremes_2d">-</a>
+
+ qh_printextremes_2d( fp, facetlist, facets, printall )
+ prints point ids for facets in qh_ORIENTclock order
+
+ notes:
+ #points, followed by ids, one per line
+ if facetlist/facets are disjoint than the output includes skips
+ errors if facets form a loop
+ does not print coplanar points
+*/
+void qh_printextremes_2d(FILE *fp, facetT *facetlist, setT *facets, boolT printall) {
+ int numfacets, numridges, totneighbors, numcoplanars, numsimplicial, numtricoplanars;
+ setT *vertices;
+ facetT *facet, *startfacet, *nextfacet;
+ vertexT *vertexA, *vertexB;
+
+ qh_countfacets(facetlist, facets, printall, &numfacets, &numsimplicial,
+ &totneighbors, &numridges, &numcoplanars, &numtricoplanars); /* marks qh visit_id */
+ vertices= qh_facetvertices(facetlist, facets, printall);
+ qh_fprintf(fp, 9088, "%d\n", qh_setsize(vertices));
+ qh_settempfree(&vertices);
+ if (!numfacets)
+ return;
+ facet= startfacet= facetlist ? facetlist : SETfirstt_(facets, facetT);
+ qh vertex_visit++;
+ qh visit_id++;
+ do {
+ if (facet->toporient ^ qh_ORIENTclock) {
+ vertexA= SETfirstt_(facet->vertices, vertexT);
+ vertexB= SETsecondt_(facet->vertices, vertexT);
+ nextfacet= SETfirstt_(facet->neighbors, facetT);
+ }else {
+ vertexA= SETsecondt_(facet->vertices, vertexT);
+ vertexB= SETfirstt_(facet->vertices, vertexT);
+ nextfacet= SETsecondt_(facet->neighbors, facetT);
+ }
+ if (facet->visitid == qh visit_id) {
+ qh_fprintf(qh ferr, 6218, "Qhull internal error (qh_printextremes_2d): loop in facet list. facet %d nextfacet %d\n",
+ facet->id, nextfacet->id);
+ qh_errexit2(qh_ERRqhull, facet, nextfacet);
+ }
+ if (facet->visitid) {
+ if (vertexA->visitid != qh vertex_visit) {
+ vertexA->visitid= qh vertex_visit;
+ qh_fprintf(fp, 9089, "%d\n", qh_pointid(vertexA->point));
+ }
+ if (vertexB->visitid != qh vertex_visit) {
+ vertexB->visitid= qh vertex_visit;
+ qh_fprintf(fp, 9090, "%d\n", qh_pointid(vertexB->point));
+ }
+ }
+ facet->visitid= qh visit_id;
+ facet= nextfacet;
+ }while (facet && facet != startfacet);
+} /* printextremes_2d */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printextremes_d">-</a>
+
+ qh_printextremes_d( fp, facetlist, facets, printall )
+ print extreme points of input sites for Delaunay triangulations
+
+ notes:
+ #points, followed by ids, one per line
+
+ unordered
+*/
+void qh_printextremes_d(FILE *fp, facetT *facetlist, setT *facets, boolT printall) {
+ setT *vertices;
+ vertexT *vertex, **vertexp;
+ boolT upperseen, lowerseen;
+ facetT *neighbor, **neighborp;
+ int numpoints=0;
+
+ vertices= qh_facetvertices(facetlist, facets, printall);
+ qh_vertexneighbors();
+ FOREACHvertex_(vertices) {
+ upperseen= lowerseen= False;
+ FOREACHneighbor_(vertex) {
+ if (neighbor->upperdelaunay)
+ upperseen= True;
+ else
+ lowerseen= True;
+ }
+ if (upperseen && lowerseen) {
+ vertex->seen= True;
+ numpoints++;
+ }else
+ vertex->seen= False;
+ }
+ qh_fprintf(fp, 9091, "%d\n", numpoints);
+ FOREACHvertex_(vertices) {
+ if (vertex->seen)
+ qh_fprintf(fp, 9092, "%d\n", qh_pointid(vertex->point));
+ }
+ qh_settempfree(&vertices);
+} /* printextremes_d */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacet">-</a>
+
+ qh_printfacet( fp, facet )
+ prints all fields of a facet to fp
+
+ notes:
+ ridges printed in neighbor order
+*/
+void qh_printfacet(FILE *fp, facetT *facet) {
+
+ qh_printfacetheader(fp, facet);
+ if (facet->ridges)
+ qh_printfacetridges(fp, facet);
+} /* printfacet */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacet2geom">-</a>
+
+ qh_printfacet2geom( fp, facet, color )
+ print facet as part of a 2-d VECT for Geomview
+
+ notes:
+ assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
+ mindist is calculated within io.c. maxoutside is calculated elsewhere
+ so a DISTround error may have occurred.
+*/
+void qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]) {
+ pointT *point0, *point1;
+ realT mindist, innerplane, outerplane;
+ int k;
+
+ qh_facet2point(facet, &point0, &point1, &mindist);
+ qh_geomplanes(facet, &outerplane, &innerplane);
+ if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner))
+ qh_printfacet2geom_points(fp, point0, point1, facet, outerplane, color);
+ if (qh PRINTinner || (!qh PRINTnoplanes && !qh PRINTouter &&
+ outerplane - innerplane > 2 * qh MAXabs_coord * qh_GEOMepsilon)) {
+ for (k=3; k--; )
+ color[k]= 1.0 - color[k];
+ qh_printfacet2geom_points(fp, point0, point1, facet, innerplane, color);
+ }
+ qh_memfree(point1, qh normal_size);
+ qh_memfree(point0, qh normal_size);
+} /* printfacet2geom */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacet2geom_points">-</a>
+
+ qh_printfacet2geom_points( fp, point1, point2, facet, offset, color )
+ prints a 2-d facet as a VECT with 2 points at some offset.
+ The points are on the facet's plane.
+*/
+void qh_printfacet2geom_points(FILE *fp, pointT *point1, pointT *point2,
+ facetT *facet, realT offset, realT color[3]) {
+ pointT *p1= point1, *p2= point2;
+
+ qh_fprintf(fp, 9093, "VECT 1 2 1 2 1 # f%d\n", facet->id);
+ if (offset != 0.0) {
+ p1= qh_projectpoint(p1, facet, -offset);
+ p2= qh_projectpoint(p2, facet, -offset);
+ }
+ qh_fprintf(fp, 9094, "%8.4g %8.4g %8.4g\n%8.4g %8.4g %8.4g\n",
+ p1[0], p1[1], 0.0, p2[0], p2[1], 0.0);
+ if (offset != 0.0) {
+ qh_memfree(p1, qh normal_size);
+ qh_memfree(p2, qh normal_size);
+ }
+ qh_fprintf(fp, 9095, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
+} /* printfacet2geom_points */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacet2math">-</a>
+
+ qh_printfacet2math( fp, facet, format, notfirst )
+ print 2-d Maple or Mathematica output for a facet
+ may be non-simplicial
+
+ notes:
+ use %16.8f since Mathematica 2.2 does not handle exponential format
+ see qh_printfacet3math
+*/
+void qh_printfacet2math(FILE *fp, facetT *facet, qh_PRINT format, int notfirst) {
+ pointT *point0, *point1;
+ realT mindist;
+ const char *pointfmt;
+
+ qh_facet2point(facet, &point0, &point1, &mindist);
+ if (notfirst)
+ qh_fprintf(fp, 9096, ",");
+ if (format == qh_PRINTmaple)
+ pointfmt= "[[%16.8f, %16.8f], [%16.8f, %16.8f]]\n";
+ else
+ pointfmt= "Line[{{%16.8f, %16.8f}, {%16.8f, %16.8f}}]\n";
+ qh_fprintf(fp, 9097, pointfmt, point0[0], point0[1], point1[0], point1[1]);
+ qh_memfree(point1, qh normal_size);
+ qh_memfree(point0, qh normal_size);
+} /* printfacet2math */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacet3geom_nonsimplicial">-</a>
+
+ qh_printfacet3geom_nonsimplicial( fp, facet, color )
+ print Geomview OFF for a 3-d nonsimplicial facet.
+ if DOintersections, prints ridges to unvisited neighbors(qh visit_id)
+
+ notes
+ uses facet->visitid for intersections and ridges
+*/
+void qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) {
+ ridgeT *ridge, **ridgep;
+ setT *projectedpoints, *vertices;
+ vertexT *vertex, **vertexp, *vertexA, *vertexB;
+ pointT *projpt, *point, **pointp;
+ facetT *neighbor;
+ realT dist, outerplane, innerplane;
+ int cntvertices, k;
+ realT black[3]={0, 0, 0}, green[3]={0, 1, 0};
+
+ qh_geomplanes(facet, &outerplane, &innerplane);
+ vertices= qh_facet3vertex(facet); /* oriented */
+ cntvertices= qh_setsize(vertices);
+ projectedpoints= qh_settemp(cntvertices);
+ FOREACHvertex_(vertices) {
+ zinc_(Zdistio);
+ qh_distplane(vertex->point, facet, &dist);
+ projpt= qh_projectpoint(vertex->point, facet, dist);
+ qh_setappend(&projectedpoints, projpt);
+ }
+ if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner))
+ qh_printfacet3geom_points(fp, projectedpoints, facet, outerplane, color);
+ if (qh PRINTinner || (!qh PRINTnoplanes && !qh PRINTouter &&
+ outerplane - innerplane > 2 * qh MAXabs_coord * qh_GEOMepsilon)) {
+ for (k=3; k--; )
+ color[k]= 1.0 - color[k];
+ qh_printfacet3geom_points(fp, projectedpoints, facet, innerplane, color);
+ }
+ FOREACHpoint_(projectedpoints)
+ qh_memfree(point, qh normal_size);
+ qh_settempfree(&projectedpoints);
+ qh_settempfree(&vertices);
+ if ((qh DOintersections || qh PRINTridges)
+ && (!facet->visible || !qh NEWfacets)) {
+ facet->visitid= qh visit_id;
+ FOREACHridge_(facet->ridges) {
+ neighbor= otherfacet_(ridge, facet);
+ if (neighbor->visitid != qh visit_id) {
+ if (qh DOintersections)
+ qh_printhyperplaneintersection(fp, facet, neighbor, ridge->vertices, black);
+ if (qh PRINTridges) {
+ vertexA= SETfirstt_(ridge->vertices, vertexT);
+ vertexB= SETsecondt_(ridge->vertices, vertexT);
+ qh_printline3geom(fp, vertexA->point, vertexB->point, green);
+ }
+ }
+ }
+ }
+} /* printfacet3geom_nonsimplicial */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacet3geom_points">-</a>
+
+ qh_printfacet3geom_points( fp, points, facet, offset )
+ prints a 3-d facet as OFF Geomview object.
+ offset is relative to the facet's hyperplane
+ Facet is determined as a list of points
+*/
+void qh_printfacet3geom_points(FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]) {
+ int k, n= qh_setsize(points), i;
+ pointT *point, **pointp;
+ setT *printpoints;
+
+ qh_fprintf(fp, 9098, "{ OFF %d 1 1 # f%d\n", n, facet->id);
+ if (offset != 0.0) {
+ printpoints= qh_settemp(n);
+ FOREACHpoint_(points)
+ qh_setappend(&printpoints, qh_projectpoint(point, facet, -offset));
+ }else
+ printpoints= points;
+ FOREACHpoint_(printpoints) {
+ for (k=0; k < qh hull_dim; k++) {
+ if (k == qh DROPdim)
+ qh_fprintf(fp, 9099, "0 ");
+ else
+ qh_fprintf(fp, 9100, "%8.4g ", point[k]);
+ }
+ if (printpoints != points)
+ qh_memfree(point, qh normal_size);
+ qh_fprintf(fp, 9101, "\n");
+ }
+ if (printpoints != points)
+ qh_settempfree(&printpoints);
+ qh_fprintf(fp, 9102, "%d ", n);
+ for (i=0; i < n; i++)
+ qh_fprintf(fp, 9103, "%d ", i);
+ qh_fprintf(fp, 9104, "%8.4g %8.4g %8.4g 1.0 }\n", color[0], color[1], color[2]);
+} /* printfacet3geom_points */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacet3geom_simplicial">-</a>
+
+ qh_printfacet3geom_simplicial( )
+ print Geomview OFF for a 3-d simplicial facet.
+
+ notes:
+ may flip color
+ uses facet->visitid for intersections and ridges
+
+ assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
+ innerplane may be off by qh DISTround. Maxoutside is calculated elsewhere
+ so a DISTround error may have occurred.
+*/
+void qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]) {
+ setT *points, *vertices;
+ vertexT *vertex, **vertexp, *vertexA, *vertexB;
+ facetT *neighbor, **neighborp;
+ realT outerplane, innerplane;
+ realT black[3]={0, 0, 0}, green[3]={0, 1, 0};
+ int k;
+
+ qh_geomplanes(facet, &outerplane, &innerplane);
+ vertices= qh_facet3vertex(facet);
+ points= qh_settemp(qh TEMPsize);
+ FOREACHvertex_(vertices)
+ qh_setappend(&points, vertex->point);
+ if (qh PRINTouter || (!qh PRINTnoplanes && !qh PRINTinner))
+ qh_printfacet3geom_points(fp, points, facet, outerplane, color);
+ if (qh PRINTinner || (!qh PRINTnoplanes && !qh PRINTouter &&
+ outerplane - innerplane > 2 * qh MAXabs_coord * qh_GEOMepsilon)) {
+ for (k=3; k--; )
+ color[k]= 1.0 - color[k];
+ qh_printfacet3geom_points(fp, points, facet, innerplane, color);
+ }
+ qh_settempfree(&points);
+ qh_settempfree(&vertices);
+ if ((qh DOintersections || qh PRINTridges)
+ && (!facet->visible || !qh NEWfacets)) {
+ facet->visitid= qh visit_id;
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid != qh visit_id) {
+ vertices= qh_setnew_delnthsorted(facet->vertices, qh hull_dim,
+ SETindex_(facet->neighbors, neighbor), 0);
+ if (qh DOintersections)
+ qh_printhyperplaneintersection(fp, facet, neighbor, vertices, black);
+ if (qh PRINTridges) {
+ vertexA= SETfirstt_(vertices, vertexT);
+ vertexB= SETsecondt_(vertices, vertexT);
+ qh_printline3geom(fp, vertexA->point, vertexB->point, green);
+ }
+ qh_setfree(&vertices);
+ }
+ }
+ }
+} /* printfacet3geom_simplicial */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacet3math">-</a>
+
+ qh_printfacet3math( fp, facet, notfirst )
+ print 3-d Maple or Mathematica output for a facet
+
+ notes:
+ may be non-simplicial
+ use %16.8f since Mathematica 2.2 does not handle exponential format
+ see qh_printfacet2math
+*/
+void qh_printfacet3math(FILE *fp, facetT *facet, qh_PRINT format, int notfirst) {
+ vertexT *vertex, **vertexp;
+ setT *points, *vertices;
+ pointT *point, **pointp;
+ boolT firstpoint= True;
+ realT dist;
+ const char *pointfmt, *endfmt;
+
+ if (notfirst)
+ qh_fprintf(fp, 9105, ",\n");
+ vertices= qh_facet3vertex(facet);
+ points= qh_settemp(qh_setsize(vertices));
+ FOREACHvertex_(vertices) {
+ zinc_(Zdistio);
+ qh_distplane(vertex->point, facet, &dist);
+ point= qh_projectpoint(vertex->point, facet, dist);
+ qh_setappend(&points, point);
+ }
+ if (format == qh_PRINTmaple) {
+ qh_fprintf(fp, 9106, "[");
+ pointfmt= "[%16.8f, %16.8f, %16.8f]";
+ endfmt= "]";
+ }else {
+ qh_fprintf(fp, 9107, "Polygon[{");
+ pointfmt= "{%16.8f, %16.8f, %16.8f}";
+ endfmt= "}]";
+ }
+ FOREACHpoint_(points) {
+ if (firstpoint)
+ firstpoint= False;
+ else
+ qh_fprintf(fp, 9108, ",\n");
+ qh_fprintf(fp, 9109, pointfmt, point[0], point[1], point[2]);
+ }
+ FOREACHpoint_(points)
+ qh_memfree(point, qh normal_size);
+ qh_settempfree(&points);
+ qh_settempfree(&vertices);
+ qh_fprintf(fp, 9110, "%s", endfmt);
+} /* printfacet3math */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacet3vertex">-</a>
+
+ qh_printfacet3vertex( fp, facet, format )
+ print vertices in a 3-d facet as point ids
+
+ notes:
+ prints number of vertices first if format == qh_PRINToff
+ the facet may be non-simplicial
+*/
+void qh_printfacet3vertex(FILE *fp, facetT *facet, qh_PRINT format) {
+ vertexT *vertex, **vertexp;
+ setT *vertices;
+
+ vertices= qh_facet3vertex(facet);
+ if (format == qh_PRINToff)
+ qh_fprintf(fp, 9111, "%d ", qh_setsize(vertices));
+ FOREACHvertex_(vertices)
+ qh_fprintf(fp, 9112, "%d ", qh_pointid(vertex->point));
+ qh_fprintf(fp, 9113, "\n");
+ qh_settempfree(&vertices);
+} /* printfacet3vertex */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacet4geom_nonsimplicial">-</a>
+
+ qh_printfacet4geom_nonsimplicial( )
+ print Geomview 4OFF file for a 4d nonsimplicial facet
+ prints all ridges to unvisited neighbors (qh.visit_id)
+ if qh.DROPdim
+ prints in OFF format
+
+ notes:
+ must agree with printend4geom()
+*/
+void qh_printfacet4geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]) {
+ facetT *neighbor;
+ ridgeT *ridge, **ridgep;
+ vertexT *vertex, **vertexp;
+ pointT *point;
+ int k;
+ realT dist;
+
+ facet->visitid= qh visit_id;
+ if (qh PRINTnoplanes || (facet->visible && qh NEWfacets))
+ return;
+ FOREACHridge_(facet->ridges) {
+ neighbor= otherfacet_(ridge, facet);
+ if (neighbor->visitid == qh visit_id)
+ continue;
+ if (qh PRINTtransparent && !neighbor->good)
+ continue;
+ if (qh DOintersections)
+ qh_printhyperplaneintersection(fp, facet, neighbor, ridge->vertices, color);
+ else {
+ if (qh DROPdim >= 0)
+ qh_fprintf(fp, 9114, "OFF 3 1 1 # f%d\n", facet->id);
+ else {
+ qh printoutvar++;
+ qh_fprintf(fp, 9115, "# r%d between f%d f%d\n", ridge->id, facet->id, neighbor->id);
+ }
+ FOREACHvertex_(ridge->vertices) {
+ zinc_(Zdistio);
+ qh_distplane(vertex->point,facet, &dist);
+ point=qh_projectpoint(vertex->point,facet, dist);
+ for (k=0; k < qh hull_dim; k++) {
+ if (k != qh DROPdim)
+ qh_fprintf(fp, 9116, "%8.4g ", point[k]);
+ }
+ qh_fprintf(fp, 9117, "\n");
+ qh_memfree(point, qh normal_size);
+ }
+ if (qh DROPdim >= 0)
+ qh_fprintf(fp, 9118, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]);
+ }
+ }
+} /* printfacet4geom_nonsimplicial */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacet4geom_simplicial">-</a>
+
+ qh_printfacet4geom_simplicial( fp, facet, color )
+ print Geomview 4OFF file for a 4d simplicial facet
+ prints triangles for unvisited neighbors (qh.visit_id)
+
+ notes:
+ must agree with printend4geom()
+*/
+void qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]) {
+ setT *vertices;
+ facetT *neighbor, **neighborp;
+ vertexT *vertex, **vertexp;
+ int k;
+
+ facet->visitid= qh visit_id;
+ if (qh PRINTnoplanes || (facet->visible && qh NEWfacets))
+ return;
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid == qh visit_id)
+ continue;
+ if (qh PRINTtransparent && !neighbor->good)
+ continue;
+ vertices= qh_setnew_delnthsorted(facet->vertices, qh hull_dim,
+ SETindex_(facet->neighbors, neighbor), 0);
+ if (qh DOintersections)
+ qh_printhyperplaneintersection(fp, facet, neighbor, vertices, color);
+ else {
+ if (qh DROPdim >= 0)
+ qh_fprintf(fp, 9119, "OFF 3 1 1 # ridge between f%d f%d\n",
+ facet->id, neighbor->id);
+ else {
+ qh printoutvar++;
+ qh_fprintf(fp, 9120, "# ridge between f%d f%d\n", facet->id, neighbor->id);
+ }
+ FOREACHvertex_(vertices) {
+ for (k=0; k < qh hull_dim; k++) {
+ if (k != qh DROPdim)
+ qh_fprintf(fp, 9121, "%8.4g ", vertex->point[k]);
+ }
+ qh_fprintf(fp, 9122, "\n");
+ }
+ if (qh DROPdim >= 0)
+ qh_fprintf(fp, 9123, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]);
+ }
+ qh_setfree(&vertices);
+ }
+} /* printfacet4geom_simplicial */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacetNvertex_nonsimplicial">-</a>
+
+ qh_printfacetNvertex_nonsimplicial( fp, facet, id, format )
+ print vertices for an N-d non-simplicial facet
+ triangulates each ridge to the id
+*/
+void qh_printfacetNvertex_nonsimplicial(FILE *fp, facetT *facet, int id, qh_PRINT format) {
+ vertexT *vertex, **vertexp;
+ ridgeT *ridge, **ridgep;
+
+ if (facet->visible && qh NEWfacets)
+ return;
+ FOREACHridge_(facet->ridges) {
+ if (format == qh_PRINTtriangles)
+ qh_fprintf(fp, 9124, "%d ", qh hull_dim);
+ qh_fprintf(fp, 9125, "%d ", id);
+ if ((ridge->top == facet) ^ qh_ORIENTclock) {
+ FOREACHvertex_(ridge->vertices)
+ qh_fprintf(fp, 9126, "%d ", qh_pointid(vertex->point));
+ }else {
+ FOREACHvertexreverse12_(ridge->vertices)
+ qh_fprintf(fp, 9127, "%d ", qh_pointid(vertex->point));
+ }
+ qh_fprintf(fp, 9128, "\n");
+ }
+} /* printfacetNvertex_nonsimplicial */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacetNvertex_simplicial">-</a>
+
+ qh_printfacetNvertex_simplicial( fp, facet, format )
+ print vertices for an N-d simplicial facet
+ prints vertices for non-simplicial facets
+ 2-d facets (orientation preserved by qh_mergefacet2d)
+ PRINToff ('o') for 4-d and higher
+*/
+void qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, qh_PRINT format) {
+ vertexT *vertex, **vertexp;
+
+ if (format == qh_PRINToff || format == qh_PRINTtriangles)
+ qh_fprintf(fp, 9129, "%d ", qh_setsize(facet->vertices));
+ if ((facet->toporient ^ qh_ORIENTclock)
+ || (qh hull_dim > 2 && !facet->simplicial)) {
+ FOREACHvertex_(facet->vertices)
+ qh_fprintf(fp, 9130, "%d ", qh_pointid(vertex->point));
+ }else {
+ FOREACHvertexreverse12_(facet->vertices)
+ qh_fprintf(fp, 9131, "%d ", qh_pointid(vertex->point));
+ }
+ qh_fprintf(fp, 9132, "\n");
+} /* printfacetNvertex_simplicial */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacetheader">-</a>
+
+ qh_printfacetheader( fp, facet )
+ prints header fields of a facet to fp
+
+ notes:
+ for 'f' output and debugging
+ Same as QhullFacet::printHeader()
+*/
+void qh_printfacetheader(FILE *fp, facetT *facet) {
+ pointT *point, **pointp, *furthest;
+ facetT *neighbor, **neighborp;
+ realT dist;
+
+ if (facet == qh_MERGEridge) {
+ qh_fprintf(fp, 9133, " MERGEridge\n");
+ return;
+ }else if (facet == qh_DUPLICATEridge) {
+ qh_fprintf(fp, 9134, " DUPLICATEridge\n");
+ return;
+ }else if (!facet) {
+ qh_fprintf(fp, 9135, " NULLfacet\n");
+ return;
+ }
+ qh old_randomdist= qh RANDOMdist;
+ qh RANDOMdist= False;
+ qh_fprintf(fp, 9136, "- f%d\n", facet->id);
+ qh_fprintf(fp, 9137, " - flags:");
+ if (facet->toporient)
+ qh_fprintf(fp, 9138, " top");
+ else
+ qh_fprintf(fp, 9139, " bottom");
+ if (facet->simplicial)
+ qh_fprintf(fp, 9140, " simplicial");
+ if (facet->tricoplanar)
+ qh_fprintf(fp, 9141, " tricoplanar");
+ if (facet->upperdelaunay)
+ qh_fprintf(fp, 9142, " upperDelaunay");
+ if (facet->visible)
+ qh_fprintf(fp, 9143, " visible");
+ if (facet->newfacet)
+ qh_fprintf(fp, 9144, " new");
+ if (facet->tested)
+ qh_fprintf(fp, 9145, " tested");
+ if (!facet->good)
+ qh_fprintf(fp, 9146, " notG");
+ if (facet->seen)
+ qh_fprintf(fp, 9147, " seen");
+ if (facet->coplanar)
+ qh_fprintf(fp, 9148, " coplanar");
+ if (facet->mergehorizon)
+ qh_fprintf(fp, 9149, " mergehorizon");
+ if (facet->keepcentrum)
+ qh_fprintf(fp, 9150, " keepcentrum");
+ if (facet->dupridge)
+ qh_fprintf(fp, 9151, " dupridge");
+ if (facet->mergeridge && !facet->mergeridge2)
+ qh_fprintf(fp, 9152, " mergeridge1");
+ if (facet->mergeridge2)
+ qh_fprintf(fp, 9153, " mergeridge2");
+ if (facet->newmerge)
+ qh_fprintf(fp, 9154, " newmerge");
+ if (facet->flipped)
+ qh_fprintf(fp, 9155, " flipped");
+ if (facet->notfurthest)
+ qh_fprintf(fp, 9156, " notfurthest");
+ if (facet->degenerate)
+ qh_fprintf(fp, 9157, " degenerate");
+ if (facet->redundant)
+ qh_fprintf(fp, 9158, " redundant");
+ qh_fprintf(fp, 9159, "\n");
+ if (facet->isarea)
+ qh_fprintf(fp, 9160, " - area: %2.2g\n", facet->f.area);
+ else if (qh NEWfacets && facet->visible && facet->f.replace)
+ qh_fprintf(fp, 9161, " - replacement: f%d\n", facet->f.replace->id);
+ else if (facet->newfacet) {
+ if (facet->f.samecycle && facet->f.samecycle != facet)
+ qh_fprintf(fp, 9162, " - shares same visible/horizon as f%d\n", facet->f.samecycle->id);
+ }else if (facet->tricoplanar /* !isarea */) {
+ if (facet->f.triowner)
+ qh_fprintf(fp, 9163, " - owner of normal & centrum is facet f%d\n", facet->f.triowner->id);
+ }else if (facet->f.newcycle)
+ qh_fprintf(fp, 9164, " - was horizon to f%d\n", facet->f.newcycle->id);
+ if (facet->nummerge)
+ qh_fprintf(fp, 9165, " - merges: %d\n", facet->nummerge);
+ qh_printpointid(fp, " - normal: ", qh hull_dim, facet->normal, qh_IDunknown);
+ qh_fprintf(fp, 9166, " - offset: %10.7g\n", facet->offset);
+ if (qh CENTERtype == qh_ASvoronoi || facet->center)
+ qh_printcenter(fp, qh_PRINTfacets, " - center: ", facet);
+#if qh_MAXoutside
+ if (facet->maxoutside > qh DISTround)
+ qh_fprintf(fp, 9167, " - maxoutside: %10.7g\n", facet->maxoutside);
+#endif
+ if (!SETempty_(facet->outsideset)) {
+ furthest= (pointT*)qh_setlast(facet->outsideset);
+ if (qh_setsize(facet->outsideset) < 6) {
+ qh_fprintf(fp, 9168, " - outside set(furthest p%d):\n", qh_pointid(furthest));
+ FOREACHpoint_(facet->outsideset)
+ qh_printpoint(fp, " ", point);
+ }else if (qh_setsize(facet->outsideset) < 21) {
+ qh_printpoints(fp, " - outside set:", facet->outsideset);
+ }else {
+ qh_fprintf(fp, 9169, " - outside set: %d points.", qh_setsize(facet->outsideset));
+ qh_printpoint(fp, " Furthest", furthest);
+ }
+#if !qh_COMPUTEfurthest
+ qh_fprintf(fp, 9170, " - furthest distance= %2.2g\n", facet->furthestdist);
+#endif
+ }
+ if (!SETempty_(facet->coplanarset)) {
+ furthest= (pointT*)qh_setlast(facet->coplanarset);
+ if (qh_setsize(facet->coplanarset) < 6) {
+ qh_fprintf(fp, 9171, " - coplanar set(furthest p%d):\n", qh_pointid(furthest));
+ FOREACHpoint_(facet->coplanarset)
+ qh_printpoint(fp, " ", point);
+ }else if (qh_setsize(facet->coplanarset) < 21) {
+ qh_printpoints(fp, " - coplanar set:", facet->coplanarset);
+ }else {
+ qh_fprintf(fp, 9172, " - coplanar set: %d points.", qh_setsize(facet->coplanarset));
+ qh_printpoint(fp, " Furthest", furthest);
+ }
+ zinc_(Zdistio);
+ qh_distplane(furthest, facet, &dist);
+ qh_fprintf(fp, 9173, " furthest distance= %2.2g\n", dist);
+ }
+ qh_printvertices(fp, " - vertices:", facet->vertices);
+ qh_fprintf(fp, 9174, " - neighboring facets:");
+ FOREACHneighbor_(facet) {
+ if (neighbor == qh_MERGEridge)
+ qh_fprintf(fp, 9175, " MERGE");
+ else if (neighbor == qh_DUPLICATEridge)
+ qh_fprintf(fp, 9176, " DUP");
+ else
+ qh_fprintf(fp, 9177, " f%d", neighbor->id);
+ }
+ qh_fprintf(fp, 9178, "\n");
+ qh RANDOMdist= qh old_randomdist;
+} /* printfacetheader */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacetridges">-</a>
+
+ qh_printfacetridges( fp, facet )
+ prints ridges of a facet to fp
+
+ notes:
+ ridges printed in neighbor order
+ assumes the ridges exist
+ for 'f' output
+ same as QhullFacet::printRidges
+*/
+void qh_printfacetridges(FILE *fp, facetT *facet) {
+ facetT *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+ int numridges= 0;
+
+
+ if (facet->visible && qh NEWfacets) {
+ qh_fprintf(fp, 9179, " - ridges(ids may be garbage):");
+ FOREACHridge_(facet->ridges)
+ qh_fprintf(fp, 9180, " r%d", ridge->id);
+ qh_fprintf(fp, 9181, "\n");
+ }else {
+ qh_fprintf(fp, 9182, " - ridges:\n");
+ FOREACHridge_(facet->ridges)
+ ridge->seen= False;
+ if (qh hull_dim == 3) {
+ ridge= SETfirstt_(facet->ridges, ridgeT);
+ while (ridge && !ridge->seen) {
+ ridge->seen= True;
+ qh_printridge(fp, ridge);
+ numridges++;
+ ridge= qh_nextridge3d(ridge, facet, NULL);
+ }
+ }else {
+ FOREACHneighbor_(facet) {
+ FOREACHridge_(facet->ridges) {
+ if (otherfacet_(ridge,facet) == neighbor) {
+ ridge->seen= True;
+ qh_printridge(fp, ridge);
+ numridges++;
+ }
+ }
+ }
+ }
+ if (numridges != qh_setsize(facet->ridges)) {
+ qh_fprintf(fp, 9183, " - all ridges:");
+ FOREACHridge_(facet->ridges)
+ qh_fprintf(fp, 9184, " r%d", ridge->id);
+ qh_fprintf(fp, 9185, "\n");
+ }
+ FOREACHridge_(facet->ridges) {
+ if (!ridge->seen)
+ qh_printridge(fp, ridge);
+ }
+ }
+} /* printfacetridges */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printfacets">-</a>
+
+ qh_printfacets( fp, format, facetlist, facets, printall )
+ prints facetlist and/or facet set in output format
+
+ notes:
+ also used for specialized formats ('FO' and summary)
+ turns off 'Rn' option since want actual numbers
+*/
+void qh_printfacets(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
+ int numfacets, numsimplicial, numridges, totneighbors, numcoplanars, numtricoplanars;
+ facetT *facet, **facetp;
+ setT *vertices;
+ coordT *center;
+ realT outerplane, innerplane;
+
+ qh old_randomdist= qh RANDOMdist;
+ qh RANDOMdist= False;
+ if (qh CDDoutput && (format == qh_PRINTcentrums || format == qh_PRINTpointintersect || format == qh_PRINToff))
+ qh_fprintf(qh ferr, 7056, "qhull warning: CDD format is not available for centrums, halfspace\nintersections, and OFF file format.\n");
+ if (format == qh_PRINTnone)
+ ; /* print nothing */
+ else if (format == qh_PRINTaverage) {
+ vertices= qh_facetvertices(facetlist, facets, printall);
+ center= qh_getcenter(vertices);
+ qh_fprintf(fp, 9186, "%d 1\n", qh hull_dim);
+ qh_printpointid(fp, NULL, qh hull_dim, center, qh_IDunknown);
+ qh_memfree(center, qh normal_size);
+ qh_settempfree(&vertices);
+ }else if (format == qh_PRINTextremes) {
+ if (qh DELAUNAY)
+ qh_printextremes_d(fp, facetlist, facets, printall);
+ else if (qh hull_dim == 2)
+ qh_printextremes_2d(fp, facetlist, facets, printall);
+ else
+ qh_printextremes(fp, facetlist, facets, printall);
+ }else if (format == qh_PRINToptions)
+ qh_fprintf(fp, 9187, "Options selected for Qhull %s:\n%s\n", qh_version, qh qhull_options);
+ else if (format == qh_PRINTpoints && !qh VORONOI)
+ qh_printpoints_out(fp, facetlist, facets, printall);
+ else if (format == qh_PRINTqhull)
+ qh_fprintf(fp, 9188, "%s | %s\n", qh rbox_command, qh qhull_command);
+ else if (format == qh_PRINTsize) {
+ qh_fprintf(fp, 9189, "0\n2 ");
+ qh_fprintf(fp, 9190, qh_REAL_1, qh totarea);
+ qh_fprintf(fp, 9191, qh_REAL_1, qh totvol);
+ qh_fprintf(fp, 9192, "\n");
+ }else if (format == qh_PRINTsummary) {
+ qh_countfacets(facetlist, facets, printall, &numfacets, &numsimplicial,
+ &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
+ vertices= qh_facetvertices(facetlist, facets, printall);
+ qh_fprintf(fp, 9193, "10 %d %d %d %d %d %d %d %d %d %d\n2 ", qh hull_dim,
+ qh num_points + qh_setsize(qh other_points),
+ qh num_vertices, qh num_facets - qh num_visible,
+ qh_setsize(vertices), numfacets, numcoplanars,
+ numfacets - numsimplicial, zzval_(Zdelvertextot),
+ numtricoplanars);
+ qh_settempfree(&vertices);
+ qh_outerinner(NULL, &outerplane, &innerplane);
+ qh_fprintf(fp, 9194, qh_REAL_2n, outerplane, innerplane);
+ }else if (format == qh_PRINTvneighbors)
+ qh_printvneighbors(fp, facetlist, facets, printall);
+ else if (qh VORONOI && format == qh_PRINToff)
+ qh_printvoronoi(fp, format, facetlist, facets, printall);
+ else if (qh VORONOI && format == qh_PRINTgeom) {
+ qh_printbegin(fp, format, facetlist, facets, printall);
+ qh_printvoronoi(fp, format, facetlist, facets, printall);
+ qh_printend(fp, format, facetlist, facets, printall);
+ }else if (qh VORONOI
+ && (format == qh_PRINTvertices || format == qh_PRINTinner || format == qh_PRINTouter))
+ qh_printvdiagram(fp, format, facetlist, facets, printall);
+ else {
+ qh_printbegin(fp, format, facetlist, facets, printall);
+ FORALLfacet_(facetlist)
+ qh_printafacet(fp, format, facet, printall);
+ FOREACHfacet_(facets)
+ qh_printafacet(fp, format, facet, printall);
+ qh_printend(fp, format, facetlist, facets, printall);
+ }
+ qh RANDOMdist= qh old_randomdist;
+} /* printfacets */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printhyperplaneintersection">-</a>
+
+ qh_printhyperplaneintersection( fp, facet1, facet2, vertices, color )
+ print Geomview OFF or 4OFF for the intersection of two hyperplanes in 3-d or 4-d
+*/
+void qh_printhyperplaneintersection(FILE *fp, facetT *facet1, facetT *facet2,
+ setT *vertices, realT color[3]) {
+ realT costheta, denominator, dist1, dist2, s, t, mindenom, p[4];
+ vertexT *vertex, **vertexp;
+ int i, k;
+ boolT nearzero1, nearzero2;
+
+ costheta= qh_getangle(facet1->normal, facet2->normal);
+ denominator= 1 - costheta * costheta;
+ i= qh_setsize(vertices);
+ if (qh hull_dim == 3)
+ qh_fprintf(fp, 9195, "VECT 1 %d 1 %d 1 ", i, i);
+ else if (qh hull_dim == 4 && qh DROPdim >= 0)
+ qh_fprintf(fp, 9196, "OFF 3 1 1 ");
+ else
+ qh printoutvar++;
+ qh_fprintf(fp, 9197, "# intersect f%d f%d\n", facet1->id, facet2->id);
+ mindenom= 1 / (10.0 * qh MAXabs_coord);
+ FOREACHvertex_(vertices) {
+ zadd_(Zdistio, 2);
+ qh_distplane(vertex->point, facet1, &dist1);
+ qh_distplane(vertex->point, facet2, &dist2);
+ s= qh_divzero(-dist1 + costheta * dist2, denominator,mindenom,&nearzero1);
+ t= qh_divzero(-dist2 + costheta * dist1, denominator,mindenom,&nearzero2);
+ if (nearzero1 || nearzero2)
+ s= t= 0.0;
+ for (k=qh hull_dim; k--; )
+ p[k]= vertex->point[k] + facet1->normal[k] * s + facet2->normal[k] * t;
+ if (qh PRINTdim <= 3) {
+ qh_projectdim3(p, p);
+ qh_fprintf(fp, 9198, "%8.4g %8.4g %8.4g # ", p[0], p[1], p[2]);
+ }else
+ qh_fprintf(fp, 9199, "%8.4g %8.4g %8.4g %8.4g # ", p[0], p[1], p[2], p[3]);
+ if (nearzero1+nearzero2)
+ qh_fprintf(fp, 9200, "p%d(coplanar facets)\n", qh_pointid(vertex->point));
+ else
+ qh_fprintf(fp, 9201, "projected p%d\n", qh_pointid(vertex->point));
+ }
+ if (qh hull_dim == 3)
+ qh_fprintf(fp, 9202, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
+ else if (qh hull_dim == 4 && qh DROPdim >= 0)
+ qh_fprintf(fp, 9203, "3 0 1 2 %8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
+} /* printhyperplaneintersection */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printline3geom">-</a>
+
+ qh_printline3geom( fp, pointA, pointB, color )
+ prints a line as a VECT
+ prints 0's for qh.DROPdim
+
+ notes:
+ if pointA == pointB,
+ it's a 1 point VECT
+*/
+void qh_printline3geom(FILE *fp, pointT *pointA, pointT *pointB, realT color[3]) {
+ int k;
+ realT pA[4], pB[4];
+
+ qh_projectdim3(pointA, pA);
+ qh_projectdim3(pointB, pB);
+ if ((fabs(pA[0] - pB[0]) > 1e-3) ||
+ (fabs(pA[1] - pB[1]) > 1e-3) ||
+ (fabs(pA[2] - pB[2]) > 1e-3)) {
+ qh_fprintf(fp, 9204, "VECT 1 2 1 2 1\n");
+ for (k=0; k < 3; k++)
+ qh_fprintf(fp, 9205, "%8.4g ", pB[k]);
+ qh_fprintf(fp, 9206, " # p%d\n", qh_pointid(pointB));
+ }else
+ qh_fprintf(fp, 9207, "VECT 1 1 1 1 1\n");
+ for (k=0; k < 3; k++)
+ qh_fprintf(fp, 9208, "%8.4g ", pA[k]);
+ qh_fprintf(fp, 9209, " # p%d\n", qh_pointid(pointA));
+ qh_fprintf(fp, 9210, "%8.4g %8.4g %8.4g 1\n", color[0], color[1], color[2]);
+}
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printneighborhood">-</a>
+
+ qh_printneighborhood( fp, format, facetA, facetB, printall )
+ print neighborhood of one or two facets
+
+ notes:
+ calls qh_findgood_all()
+ bumps qh.visit_id
+*/
+void qh_printneighborhood(FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall) {
+ facetT *neighbor, **neighborp, *facet;
+ setT *facets;
+
+ if (format == qh_PRINTnone)
+ return;
+ qh_findgood_all(qh facet_list);
+ if (facetA == facetB)
+ facetB= NULL;
+ facets= qh_settemp(2*(qh_setsize(facetA->neighbors)+1));
+ qh visit_id++;
+ for (facet= facetA; facet; facet= ((facet == facetA) ? facetB : NULL)) {
+ if (facet->visitid != qh visit_id) {
+ facet->visitid= qh visit_id;
+ qh_setappend(&facets, facet);
+ }
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid == qh visit_id)
+ continue;
+ neighbor->visitid= qh visit_id;
+ if (printall || !qh_skipfacet(neighbor))
+ qh_setappend(&facets, neighbor);
+ }
+ }
+ qh_printfacets(fp, format, NULL, facets, printall);
+ qh_settempfree(&facets);
+} /* printneighborhood */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printpoint">-</a>
+
+ qh_printpoint( fp, string, point )
+ qh_printpointid( fp, string, dim, point, id )
+ prints the coordinates of a point
+
+ returns:
+ if string is defined
+ prints 'string p%d'. Skips p%d if id=qh_IDunknown(-1) or qh_IDnone(-3)
+
+ notes:
+ nop if point is NULL
+ Same as QhullPoint's printPoint
+*/
+void qh_printpoint(FILE *fp, const char *string, pointT *point) {
+ int id= qh_pointid( point);
+
+ qh_printpointid( fp, string, qh hull_dim, point, id);
+} /* printpoint */
+
+void qh_printpointid(FILE *fp, const char *string, int dim, pointT *point, int id) {
+ int k;
+ realT r; /*bug fix*/
+
+ if (!point)
+ return;
+ if (string) {
+ qh_fprintf(fp, 9211, "%s", string);
+ if (id != qh_IDunknown && id != qh_IDnone)
+ qh_fprintf(fp, 9212, " p%d: ", id);
+ }
+ for (k=dim; k--; ) {
+ r= *point++;
+ if (string)
+ qh_fprintf(fp, 9213, " %8.4g", r);
+ else
+ qh_fprintf(fp, 9214, qh_REAL_1, r);
+ }
+ qh_fprintf(fp, 9215, "\n");
+} /* printpointid */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printpoint3">-</a>
+
+ qh_printpoint3( fp, point )
+ prints 2-d, 3-d, or 4-d point as Geomview 3-d coordinates
+*/
+void qh_printpoint3(FILE *fp, pointT *point) {
+ int k;
+ realT p[4];
+
+ qh_projectdim3(point, p);
+ for (k=0; k < 3; k++)
+ qh_fprintf(fp, 9216, "%8.4g ", p[k]);
+ qh_fprintf(fp, 9217, " # p%d\n", qh_pointid(point));
+} /* printpoint3 */
+
+/*----------------------------------------
+-printpoints- print pointids for a set of points starting at index
+ see geom.c
+*/
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printpoints_out">-</a>
+
+ qh_printpoints_out( fp, facetlist, facets, printall )
+ prints vertices, coplanar/inside points, for facets by their point coordinates
+ allows qh.CDDoutput
+
+ notes:
+ same format as qhull input
+ if no coplanar/interior points,
+ same order as qh_printextremes
+*/
+void qh_printpoints_out(FILE *fp, facetT *facetlist, setT *facets, boolT printall) {
+ int allpoints= qh num_points + qh_setsize(qh other_points);
+ int numpoints=0, point_i, point_n;
+ setT *vertices, *points;
+ facetT *facet, **facetp;
+ pointT *point, **pointp;
+ vertexT *vertex, **vertexp;
+ int id;
+
+ points= qh_settemp(allpoints);
+ qh_setzero(points, 0, allpoints);
+ vertices= qh_facetvertices(facetlist, facets, printall);
+ FOREACHvertex_(vertices) {
+ id= qh_pointid(vertex->point);
+ if (id >= 0)
+ SETelem_(points, id)= vertex->point;
+ }
+ if (qh KEEPinside || qh KEEPcoplanar || qh KEEPnearinside) {
+ FORALLfacet_(facetlist) {
+ if (!printall && qh_skipfacet(facet))
+ continue;
+ FOREACHpoint_(facet->coplanarset) {
+ id= qh_pointid(point);
+ if (id >= 0)
+ SETelem_(points, id)= point;
+ }
+ }
+ FOREACHfacet_(facets) {
+ if (!printall && qh_skipfacet(facet))
+ continue;
+ FOREACHpoint_(facet->coplanarset) {
+ id= qh_pointid(point);
+ if (id >= 0)
+ SETelem_(points, id)= point;
+ }
+ }
+ }
+ qh_settempfree(&vertices);
+ FOREACHpoint_i_(points) {
+ if (point)
+ numpoints++;
+ }
+ if (qh CDDoutput)
+ qh_fprintf(fp, 9218, "%s | %s\nbegin\n%d %d real\n", qh rbox_command,
+ qh qhull_command, numpoints, qh hull_dim + 1);
+ else
+ qh_fprintf(fp, 9219, "%d\n%d\n", qh hull_dim, numpoints);
+ FOREACHpoint_i_(points) {
+ if (point) {
+ if (qh CDDoutput)
+ qh_fprintf(fp, 9220, "1 ");
+ qh_printpoint(fp, NULL, point);
+ }
+ }
+ if (qh CDDoutput)
+ qh_fprintf(fp, 9221, "end\n");
+ qh_settempfree(&points);
+} /* printpoints_out */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printpointvect">-</a>
+
+ qh_printpointvect( fp, point, normal, center, radius, color )
+ prints a 2-d, 3-d, or 4-d point as 3-d VECT's relative to normal or to center point
+*/
+void qh_printpointvect(FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]) {
+ realT diff[4], pointA[4];
+ int k;
+
+ for (k=qh hull_dim; k--; ) {
+ if (center)
+ diff[k]= point[k]-center[k];
+ else if (normal)
+ diff[k]= normal[k];
+ else
+ diff[k]= 0;
+ }
+ if (center)
+ qh_normalize2(diff, qh hull_dim, True, NULL, NULL);
+ for (k=qh hull_dim; k--; )
+ pointA[k]= point[k]+diff[k] * radius;
+ qh_printline3geom(fp, point, pointA, color);
+} /* printpointvect */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printpointvect2">-</a>
+
+ qh_printpointvect2( fp, point, normal, center, radius )
+ prints a 2-d, 3-d, or 4-d point as 2 3-d VECT's for an imprecise point
+*/
+void qh_printpointvect2(FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius) {
+ realT red[3]={1, 0, 0}, yellow[3]={1, 1, 0};
+
+ qh_printpointvect(fp, point, normal, center, radius, red);
+ qh_printpointvect(fp, point, normal, center, -radius, yellow);
+} /* printpointvect2 */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printridge">-</a>
+
+ qh_printridge( fp, ridge )
+ prints the information in a ridge
+
+ notes:
+ for qh_printfacetridges()
+ same as operator<< [QhullRidge.cpp]
+*/
+void qh_printridge(FILE *fp, ridgeT *ridge) {
+
+ qh_fprintf(fp, 9222, " - r%d", ridge->id);
+ if (ridge->tested)
+ qh_fprintf(fp, 9223, " tested");
+ if (ridge->nonconvex)
+ qh_fprintf(fp, 9224, " nonconvex");
+ qh_fprintf(fp, 9225, "\n");
+ qh_printvertices(fp, " vertices:", ridge->vertices);
+ if (ridge->top && ridge->bottom)
+ qh_fprintf(fp, 9226, " between f%d and f%d\n",
+ ridge->top->id, ridge->bottom->id);
+} /* printridge */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printspheres">-</a>
+
+ qh_printspheres( fp, vertices, radius )
+ prints 3-d vertices as OFF spheres
+
+ notes:
+ inflated octahedron from Stuart Levy earth/mksphere2
+*/
+void qh_printspheres(FILE *fp, setT *vertices, realT radius) {
+ vertexT *vertex, **vertexp;
+
+ qh printoutnum++;
+ qh_fprintf(fp, 9227, "{appearance {-edge -normal normscale 0} {\n\
+INST geom {define vsphere OFF\n\
+18 32 48\n\
+\n\
+0 0 1\n\
+1 0 0\n\
+0 1 0\n\
+-1 0 0\n\
+0 -1 0\n\
+0 0 -1\n\
+0.707107 0 0.707107\n\
+0 -0.707107 0.707107\n\
+0.707107 -0.707107 0\n\
+-0.707107 0 0.707107\n\
+-0.707107 -0.707107 0\n\
+0 0.707107 0.707107\n\
+-0.707107 0.707107 0\n\
+0.707107 0.707107 0\n\
+0.707107 0 -0.707107\n\
+0 0.707107 -0.707107\n\
+-0.707107 0 -0.707107\n\
+0 -0.707107 -0.707107\n\
+\n\
+3 0 6 11\n\
+3 0 7 6 \n\
+3 0 9 7 \n\
+3 0 11 9\n\
+3 1 6 8 \n\
+3 1 8 14\n\
+3 1 13 6\n\
+3 1 14 13\n\
+3 2 11 13\n\
+3 2 12 11\n\
+3 2 13 15\n\
+3 2 15 12\n\
+3 3 9 12\n\
+3 3 10 9\n\
+3 3 12 16\n\
+3 3 16 10\n\
+3 4 7 10\n\
+3 4 8 7\n\
+3 4 10 17\n\
+3 4 17 8\n\
+3 5 14 17\n\
+3 5 15 14\n\
+3 5 16 15\n\
+3 5 17 16\n\
+3 6 13 11\n\
+3 7 8 6\n\
+3 9 10 7\n\
+3 11 12 9\n\
+3 14 8 17\n\
+3 15 13 14\n\
+3 16 12 15\n\
+3 17 10 16\n} transforms { TLIST\n");
+ FOREACHvertex_(vertices) {
+ qh_fprintf(fp, 9228, "%8.4g 0 0 0 # v%d\n 0 %8.4g 0 0\n0 0 %8.4g 0\n",
+ radius, vertex->id, radius, radius);
+ qh_printpoint3(fp, vertex->point);
+ qh_fprintf(fp, 9229, "1\n");
+ }
+ qh_fprintf(fp, 9230, "}}}\n");
+} /* printspheres */
+
+
+/*----------------------------------------------
+-printsummary-
+ see libqhull.c
+*/
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printvdiagram">-</a>
+
+ qh_printvdiagram( fp, format, facetlist, facets, printall )
+ print voronoi diagram
+ # of pairs of input sites
+ #indices site1 site2 vertex1 ...
+
+ sites indexed by input point id
+ point 0 is the first input point
+ vertices indexed by 'o' and 'p' order
+ vertex 0 is the 'vertex-at-infinity'
+ vertex 1 is the first Voronoi vertex
+
+ see:
+ qh_printvoronoi()
+ qh_eachvoronoi_all()
+
+ notes:
+ if all facets are upperdelaunay,
+ prints upper hull (furthest-site Voronoi diagram)
+*/
+void qh_printvdiagram(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
+ setT *vertices;
+ int totcount, numcenters;
+ boolT isLower;
+ qh_RIDGE innerouter= qh_RIDGEall;
+ printvridgeT printvridge= NULL;
+
+ if (format == qh_PRINTvertices) {
+ innerouter= qh_RIDGEall;
+ printvridge= qh_printvridge;
+ }else if (format == qh_PRINTinner) {
+ innerouter= qh_RIDGEinner;
+ printvridge= qh_printvnorm;
+ }else if (format == qh_PRINTouter) {
+ innerouter= qh_RIDGEouter;
+ printvridge= qh_printvnorm;
+ }else {
+ qh_fprintf(qh ferr, 6219, "Qhull internal error (qh_printvdiagram): unknown print format %d.\n", format);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ vertices= qh_markvoronoi(facetlist, facets, printall, &isLower, &numcenters);
+ totcount= qh_printvdiagram2(NULL, NULL, vertices, innerouter, False);
+ qh_fprintf(fp, 9231, "%d\n", totcount);
+ totcount= qh_printvdiagram2(fp, printvridge, vertices, innerouter, True /* inorder*/);
+ qh_settempfree(&vertices);
+#if 0 /* for testing qh_eachvoronoi_all */
+ qh_fprintf(fp, 9232, "\n");
+ totcount= qh_eachvoronoi_all(fp, printvridge, qh UPPERdelaunay, innerouter, True /* inorder*/);
+ qh_fprintf(fp, 9233, "%d\n", totcount);
+#endif
+} /* printvdiagram */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printvdiagram2">-</a>
+
+ qh_printvdiagram2( fp, printvridge, vertices, innerouter, inorder )
+ visit all pairs of input sites (vertices) for selected Voronoi vertices
+ vertices may include NULLs
+
+ innerouter:
+ qh_RIDGEall print inner ridges(bounded) and outer ridges(unbounded)
+ qh_RIDGEinner print only inner ridges
+ qh_RIDGEouter print only outer ridges
+
+ inorder:
+ print 3-d Voronoi vertices in order
+
+ assumes:
+ qh_markvoronoi marked facet->visitid for Voronoi vertices
+ all facet->seen= False
+ all facet->seen2= True
+
+ returns:
+ total number of Voronoi ridges
+ if printvridge,
+ calls printvridge( fp, vertex, vertexA, centers) for each ridge
+ [see qh_eachvoronoi()]
+
+ see:
+ qh_eachvoronoi_all()
+*/
+int qh_printvdiagram2(FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder) {
+ int totcount= 0;
+ int vertex_i, vertex_n;
+ vertexT *vertex;
+
+ FORALLvertices
+ vertex->seen= False;
+ FOREACHvertex_i_(vertices) {
+ if (vertex) {
+ if (qh GOODvertex > 0 && qh_pointid(vertex->point)+1 != qh GOODvertex)
+ continue;
+ totcount += qh_eachvoronoi(fp, printvridge, vertex, !qh_ALL, innerouter, inorder);
+ }
+ }
+ return totcount;
+} /* printvdiagram2 */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printvertex">-</a>
+
+ qh_printvertex( fp, vertex )
+ prints the information in a vertex
+ Duplicated as operator<< [QhullVertex.cpp]
+*/
+void qh_printvertex(FILE *fp, vertexT *vertex) {
+ pointT *point;
+ int k, count= 0;
+ facetT *neighbor, **neighborp;
+ realT r; /*bug fix*/
+
+ if (!vertex) {
+ qh_fprintf(fp, 9234, " NULLvertex\n");
+ return;
+ }
+ qh_fprintf(fp, 9235, "- p%d(v%d):", qh_pointid(vertex->point), vertex->id);
+ point= vertex->point;
+ if (point) {
+ for (k=qh hull_dim; k--; ) {
+ r= *point++;
+ qh_fprintf(fp, 9236, " %5.2g", r);
+ }
+ }
+ if (vertex->deleted)
+ qh_fprintf(fp, 9237, " deleted");
+ if (vertex->delridge)
+ qh_fprintf(fp, 9238, " ridgedeleted");
+ qh_fprintf(fp, 9239, "\n");
+ if (vertex->neighbors) {
+ qh_fprintf(fp, 9240, " neighbors:");
+ FOREACHneighbor_(vertex) {
+ if (++count % 100 == 0)
+ qh_fprintf(fp, 9241, "\n ");
+ qh_fprintf(fp, 9242, " f%d", neighbor->id);
+ }
+ qh_fprintf(fp, 9243, "\n");
+ }
+} /* printvertex */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printvertexlist">-</a>
+
+ qh_printvertexlist( fp, string, facetlist, facets, printall )
+ prints vertices used by a facetlist or facet set
+ tests qh_skipfacet() if !printall
+*/
+void qh_printvertexlist(FILE *fp, const char* string, facetT *facetlist,
+ setT *facets, boolT printall) {
+ vertexT *vertex, **vertexp;
+ setT *vertices;
+
+ vertices= qh_facetvertices(facetlist, facets, printall);
+ qh_fprintf(fp, 9244, "%s", string);
+ FOREACHvertex_(vertices)
+ qh_printvertex(fp, vertex);
+ qh_settempfree(&vertices);
+} /* printvertexlist */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printvertices">-</a>
+
+ qh_printvertices( fp, string, vertices )
+ prints vertices in a set
+ duplicated as printVertexSet [QhullVertex.cpp]
+*/
+void qh_printvertices(FILE *fp, const char* string, setT *vertices) {
+ vertexT *vertex, **vertexp;
+
+ qh_fprintf(fp, 9245, "%s", string);
+ FOREACHvertex_(vertices)
+ qh_fprintf(fp, 9246, " p%d(v%d)", qh_pointid(vertex->point), vertex->id);
+ qh_fprintf(fp, 9247, "\n");
+} /* printvertices */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printvneighbors">-</a>
+
+ qh_printvneighbors( fp, facetlist, facets, printall )
+ print vertex neighbors of vertices in facetlist and facets ('FN')
+
+ notes:
+ qh_countfacets clears facet->visitid for non-printed facets
+
+ design:
+ collect facet count and related statistics
+ if necessary, build neighbor sets for each vertex
+ collect vertices in facetlist and facets
+ build a point array for point->vertex and point->coplanar facet
+ for each point
+ list vertex neighbors or coplanar facet
+*/
+void qh_printvneighbors(FILE *fp, facetT* facetlist, setT *facets, boolT printall) {
+ int numfacets, numsimplicial, numridges, totneighbors, numneighbors, numcoplanars, numtricoplanars;
+ setT *vertices, *vertex_points, *coplanar_points;
+ int numpoints= qh num_points + qh_setsize(qh other_points);
+ vertexT *vertex, **vertexp;
+ int vertex_i, vertex_n;
+ facetT *facet, **facetp, *neighbor, **neighborp;
+ pointT *point, **pointp;
+
+ qh_countfacets(facetlist, facets, printall, &numfacets, &numsimplicial,
+ &totneighbors, &numridges, &numcoplanars, &numtricoplanars); /* sets facet->visitid */
+ qh_fprintf(fp, 9248, "%d\n", numpoints);
+ qh_vertexneighbors();
+ vertices= qh_facetvertices(facetlist, facets, printall);
+ vertex_points= qh_settemp(numpoints);
+ coplanar_points= qh_settemp(numpoints);
+ qh_setzero(vertex_points, 0, numpoints);
+ qh_setzero(coplanar_points, 0, numpoints);
+ FOREACHvertex_(vertices)
+ qh_point_add(vertex_points, vertex->point, vertex);
+ FORALLfacet_(facetlist) {
+ FOREACHpoint_(facet->coplanarset)
+ qh_point_add(coplanar_points, point, facet);
+ }
+ FOREACHfacet_(facets) {
+ FOREACHpoint_(facet->coplanarset)
+ qh_point_add(coplanar_points, point, facet);
+ }
+ FOREACHvertex_i_(vertex_points) {
+ if (vertex) {
+ numneighbors= qh_setsize(vertex->neighbors);
+ qh_fprintf(fp, 9249, "%d", numneighbors);
+ if (qh hull_dim == 3)
+ qh_order_vertexneighbors(vertex);
+ else if (qh hull_dim >= 4)
+ qsort(SETaddr_(vertex->neighbors, facetT), (size_t)numneighbors,
+ sizeof(facetT *), qh_compare_facetvisit);
+ FOREACHneighbor_(vertex)
+ qh_fprintf(fp, 9250, " %d",
+ neighbor->visitid ? neighbor->visitid - 1 : 0 - neighbor->id);
+ qh_fprintf(fp, 9251, "\n");
+ }else if ((facet= SETelemt_(coplanar_points, vertex_i, facetT)))
+ qh_fprintf(fp, 9252, "1 %d\n",
+ facet->visitid ? facet->visitid - 1 : 0 - facet->id);
+ else
+ qh_fprintf(fp, 9253, "0\n");
+ }
+ qh_settempfree(&coplanar_points);
+ qh_settempfree(&vertex_points);
+ qh_settempfree(&vertices);
+} /* printvneighbors */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printvoronoi">-</a>
+
+ qh_printvoronoi( fp, format, facetlist, facets, printall )
+ print voronoi diagram in 'o' or 'G' format
+ for 'o' format
+ prints voronoi centers for each facet and for infinity
+ for each vertex, lists ids of printed facets or infinity
+ assumes facetlist and facets are disjoint
+ for 'G' format
+ prints an OFF object
+ adds a 0 coordinate to center
+ prints infinity but does not list in vertices
+
+ see:
+ qh_printvdiagram()
+
+ notes:
+ if 'o',
+ prints a line for each point except "at-infinity"
+ if all facets are upperdelaunay,
+ reverses lower and upper hull
+*/
+void qh_printvoronoi(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
+ int k, numcenters, numvertices= 0, numneighbors, numinf, vid=1, vertex_i, vertex_n;
+ facetT *facet, **facetp, *neighbor, **neighborp;
+ setT *vertices;
+ vertexT *vertex;
+ boolT isLower;
+ unsigned int numfacets= (unsigned int) qh num_facets;
+
+ vertices= qh_markvoronoi(facetlist, facets, printall, &isLower, &numcenters);
+ FOREACHvertex_i_(vertices) {
+ if (vertex) {
+ numvertices++;
+ numneighbors = numinf = 0;
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid == 0)
+ numinf= 1;
+ else if (neighbor->visitid < numfacets)
+ numneighbors++;
+ }
+ if (numinf && !numneighbors) {
+ SETelem_(vertices, vertex_i)= NULL;
+ numvertices--;
+ }
+ }
+ }
+ if (format == qh_PRINTgeom)
+ qh_fprintf(fp, 9254, "{appearance {+edge -face} OFF %d %d 1 # Voronoi centers and cells\n",
+ numcenters, numvertices);
+ else
+ qh_fprintf(fp, 9255, "%d\n%d %d 1\n", qh hull_dim-1, numcenters, qh_setsize(vertices));
+ if (format == qh_PRINTgeom) {
+ for (k=qh hull_dim-1; k--; )
+ qh_fprintf(fp, 9256, qh_REAL_1, 0.0);
+ qh_fprintf(fp, 9257, " 0 # infinity not used\n");
+ }else {
+ for (k=qh hull_dim-1; k--; )
+ qh_fprintf(fp, 9258, qh_REAL_1, qh_INFINITE);
+ qh_fprintf(fp, 9259, "\n");
+ }
+ FORALLfacet_(facetlist) {
+ if (facet->visitid && facet->visitid < numfacets) {
+ if (format == qh_PRINTgeom)
+ qh_fprintf(fp, 9260, "# %d f%d\n", vid++, facet->id);
+ qh_printcenter(fp, format, NULL, facet);
+ }
+ }
+ FOREACHfacet_(facets) {
+ if (facet->visitid && facet->visitid < numfacets) {
+ if (format == qh_PRINTgeom)
+ qh_fprintf(fp, 9261, "# %d f%d\n", vid++, facet->id);
+ qh_printcenter(fp, format, NULL, facet);
+ }
+ }
+ FOREACHvertex_i_(vertices) {
+ numneighbors= 0;
+ numinf=0;
+ if (vertex) {
+ if (qh hull_dim == 3)
+ qh_order_vertexneighbors(vertex);
+ else if (qh hull_dim >= 4)
+ qsort(SETaddr_(vertex->neighbors, facetT),
+ (size_t)qh_setsize(vertex->neighbors),
+ sizeof(facetT *), qh_compare_facetvisit);
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid == 0)
+ numinf= 1;
+ else if (neighbor->visitid < numfacets)
+ numneighbors++;
+ }
+ }
+ if (format == qh_PRINTgeom) {
+ if (vertex) {
+ qh_fprintf(fp, 9262, "%d", numneighbors);
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid && neighbor->visitid < numfacets)
+ qh_fprintf(fp, 9263, " %d", neighbor->visitid);
+ }
+ qh_fprintf(fp, 9264, " # p%d(v%d)\n", vertex_i, vertex->id);
+ }else
+ qh_fprintf(fp, 9265, " # p%d is coplanar or isolated\n", vertex_i);
+ }else {
+ if (numinf)
+ numneighbors++;
+ qh_fprintf(fp, 9266, "%d", numneighbors);
+ if (vertex) {
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid == 0) {
+ if (numinf) {
+ numinf= 0;
+ qh_fprintf(fp, 9267, " %d", neighbor->visitid);
+ }
+ }else if (neighbor->visitid < numfacets)
+ qh_fprintf(fp, 9268, " %d", neighbor->visitid);
+ }
+ }
+ qh_fprintf(fp, 9269, "\n");
+ }
+ }
+ if (format == qh_PRINTgeom)
+ qh_fprintf(fp, 9270, "}\n");
+ qh_settempfree(&vertices);
+} /* printvoronoi */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printvnorm">-</a>
+
+ qh_printvnorm( fp, vertex, vertexA, centers, unbounded )
+ print one separating plane of the Voronoi diagram for a pair of input sites
+ unbounded==True if centers includes vertex-at-infinity
+
+ assumes:
+ qh_ASvoronoi and qh_vertexneighbors() already set
+
+ note:
+ parameter unbounded is UNUSED by this callback
+
+ see:
+ qh_printvdiagram()
+ qh_eachvoronoi()
+*/
+void qh_printvnorm(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
+ pointT *normal;
+ realT offset;
+ int k;
+ QHULL_UNUSED(unbounded);
+
+ normal= qh_detvnorm(vertex, vertexA, centers, &offset);
+ qh_fprintf(fp, 9271, "%d %d %d ",
+ 2+qh hull_dim, qh_pointid(vertex->point), qh_pointid(vertexA->point));
+ for (k=0; k< qh hull_dim-1; k++)
+ qh_fprintf(fp, 9272, qh_REAL_1, normal[k]);
+ qh_fprintf(fp, 9273, qh_REAL_1, offset);
+ qh_fprintf(fp, 9274, "\n");
+} /* printvnorm */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printvridge">-</a>
+
+ qh_printvridge( fp, vertex, vertexA, centers, unbounded )
+ print one ridge of the Voronoi diagram for a pair of input sites
+ unbounded==True if centers includes vertex-at-infinity
+
+ see:
+ qh_printvdiagram()
+
+ notes:
+ the user may use a different function
+ parameter unbounded is UNUSED
+*/
+void qh_printvridge(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
+ facetT *facet, **facetp;
+ QHULL_UNUSED(unbounded);
+
+ qh_fprintf(fp, 9275, "%d %d %d", qh_setsize(centers)+2,
+ qh_pointid(vertex->point), qh_pointid(vertexA->point));
+ FOREACHfacet_(centers)
+ qh_fprintf(fp, 9276, " %d", facet->visitid);
+ qh_fprintf(fp, 9277, "\n");
+} /* printvridge */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="projectdim3">-</a>
+
+ qh_projectdim3( source, destination )
+ project 2-d 3-d or 4-d point to a 3-d point
+ uses qh.DROPdim and qh.hull_dim
+ source and destination may be the same
+
+ notes:
+ allocate 4 elements to destination just in case
+*/
+void qh_projectdim3(pointT *source, pointT *destination) {
+ int i,k;
+
+ for (k=0, i=0; k < qh hull_dim; k++) {
+ if (qh hull_dim == 4) {
+ if (k != qh DROPdim)
+ destination[i++]= source[k];
+ }else if (k == qh DROPdim)
+ destination[i++]= 0;
+ else
+ destination[i++]= source[k];
+ }
+ while (i < 3)
+ destination[i++]= 0.0;
+} /* projectdim3 */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="readfeasible">-</a>
+
+ qh_readfeasible( dim, curline )
+ read feasible point from current line and qh.fin
+
+ returns:
+ number of lines read from qh.fin
+ sets qh.feasible_point with malloc'd coordinates
+
+ notes:
+ checks for qh.HALFspace
+ assumes dim > 1
+
+ see:
+ qh_setfeasible
+*/
+int qh_readfeasible(int dim, const char *curline) {
+ boolT isfirst= True;
+ int linecount= 0, tokcount= 0;
+ const char *s;
+ char *t, firstline[qh_MAXfirst+1];
+ coordT *coords, value;
+
+ if (!qh HALFspace) {
+ qh_fprintf(qh ferr, 6070, "qhull input error: feasible point(dim 1 coords) is only valid for halfspace intersection\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (qh feasible_string)
+ qh_fprintf(qh ferr, 7057, "qhull input warning: feasible point(dim 1 coords) overrides 'Hn,n,n' feasible point for halfspace intersection\n");
+ if (!(qh feasible_point= (coordT*)qh_malloc(dim* sizeof(coordT)))) {
+ qh_fprintf(qh ferr, 6071, "qhull error: insufficient memory for feasible point\n");
+ qh_errexit(qh_ERRmem, NULL, NULL);
+ }
+ coords= qh feasible_point;
+ while ((s= (isfirst ? curline : fgets(firstline, qh_MAXfirst, qh fin)))) {
+ if (isfirst)
+ isfirst= False;
+ else
+ linecount++;
+ while (*s) {
+ while (isspace(*s))
+ s++;
+ value= qh_strtod(s, &t);
+ if (s == t)
+ break;
+ s= t;
+ *(coords++)= value;
+ if (++tokcount == dim) {
+ while (isspace(*s))
+ s++;
+ qh_strtod(s, &t);
+ if (s != t) {
+ qh_fprintf(qh ferr, 6072, "qhull input error: coordinates for feasible point do not finish out the line: %s\n",
+ s);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ return linecount;
+ }
+ }
+ }
+ qh_fprintf(qh ferr, 6073, "qhull input error: only %d coordinates. Could not read %d-d feasible point.\n",
+ tokcount, dim);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ return 0;
+} /* readfeasible */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="readpoints">-</a>
+
+ qh_readpoints( numpoints, dimension, ismalloc )
+ read points from qh.fin into qh.first_point, qh.num_points
+ qh.fin is lines of coordinates, one per vertex, first line number of points
+ if 'rbox D4',
+ gives message
+ if qh.ATinfinity,
+ adds point-at-infinity for Delaunay triangulations
+
+ returns:
+ number of points, array of point coordinates, dimension, ismalloc True
+ if qh.DELAUNAY & !qh.PROJECTinput, projects points to paraboloid
+ and clears qh.PROJECTdelaunay
+ if qh.HALFspace, reads optional feasible point, reads halfspaces,
+ converts to dual.
+
+ for feasible point in "cdd format" in 3-d:
+ 3 1
+ coordinates
+ comments
+ begin
+ n 4 real/integer
+ ...
+ end
+
+ notes:
+ dimension will change in qh_initqhull_globals if qh.PROJECTinput
+ uses malloc() since qh_mem not initialized
+ FIXUP QH11012: qh_readpoints needs rewriting, too long
+*/
+coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc) {
+ coordT *points, *coords, *infinity= NULL;
+ realT paraboloid, maxboloid= -REALmax, value;
+ realT *coordp= NULL, *offsetp= NULL, *normalp= NULL;
+ char *s= 0, *t, firstline[qh_MAXfirst+1];
+ int diminput=0, numinput=0, dimfeasible= 0, newnum, k, tempi;
+ int firsttext=0, firstshort=0, firstlong=0, firstpoint=0;
+ int tokcount= 0, linecount=0, maxcount, coordcount=0;
+ boolT islong, isfirst= True, wasbegin= False;
+ boolT isdelaunay= qh DELAUNAY && !qh PROJECTinput;
+
+ if (qh CDDinput) {
+ while ((s= fgets(firstline, qh_MAXfirst, qh fin))) {
+ linecount++;
+ if (qh HALFspace && linecount == 1 && isdigit(*s)) {
+ dimfeasible= qh_strtol(s, &s);
+ while (isspace(*s))
+ s++;
+ if (qh_strtol(s, &s) == 1)
+ linecount += qh_readfeasible(dimfeasible, s);
+ else
+ dimfeasible= 0;
+ }else if (!memcmp(firstline, "begin", (size_t)5) || !memcmp(firstline, "BEGIN", (size_t)5))
+ break;
+ else if (!*qh rbox_command)
+ strncat(qh rbox_command, s, sizeof(qh rbox_command)-1);
+ }
+ if (!s) {
+ qh_fprintf(qh ferr, 6074, "qhull input error: missing \"begin\" for cdd-formated input\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ }
+ while (!numinput && (s= fgets(firstline, qh_MAXfirst, qh fin))) {
+ linecount++;
+ if (!memcmp(s, "begin", (size_t)5) || !memcmp(s, "BEGIN", (size_t)5))
+ wasbegin= True;
+ while (*s) {
+ while (isspace(*s))
+ s++;
+ if (!*s)
+ break;
+ if (!isdigit(*s)) {
+ if (!*qh rbox_command) {
+ strncat(qh rbox_command, s, sizeof(qh rbox_command)-1);
+ firsttext= linecount;
+ }
+ break;
+ }
+ if (!diminput)
+ diminput= qh_strtol(s, &s);
+ else {
+ numinput= qh_strtol(s, &s);
+ if (numinput == 1 && diminput >= 2 && qh HALFspace && !qh CDDinput) {
+ linecount += qh_readfeasible(diminput, s); /* checks if ok */
+ dimfeasible= diminput;
+ diminput= numinput= 0;
+ }else
+ break;
+ }
+ }
+ }
+ if (!s) {
+ qh_fprintf(qh ferr, 6075, "qhull input error: short input file. Did not find dimension and number of points\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (diminput > numinput) {
+ tempi= diminput; /* exchange dim and n, e.g., for cdd input format */
+ diminput= numinput;
+ numinput= tempi;
+ }
+ if (diminput < 2) {
+ qh_fprintf(qh ferr, 6220,"qhull input error: dimension %d(first number) should be at least 2\n",
+ diminput);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (isdelaunay) {
+ qh PROJECTdelaunay= False;
+ if (qh CDDinput)
+ *dimension= diminput;
+ else
+ *dimension= diminput+1;
+ *numpoints= numinput;
+ if (qh ATinfinity)
+ (*numpoints)++;
+ }else if (qh HALFspace) {
+ *dimension= diminput - 1;
+ *numpoints= numinput;
+ if (diminput < 3) {
+ qh_fprintf(qh ferr, 6221,"qhull input error: dimension %d(first number, includes offset) should be at least 3 for halfspaces\n",
+ diminput);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (dimfeasible) {
+ if (dimfeasible != *dimension) {
+ qh_fprintf(qh ferr, 6222,"qhull input error: dimension %d of feasible point is not one less than dimension %d for halfspaces\n",
+ dimfeasible, diminput);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ }else
+ qh_setfeasible(*dimension);
+ }else {
+ if (qh CDDinput)
+ *dimension= diminput-1;
+ else
+ *dimension= diminput;
+ *numpoints= numinput;
+ }
+ qh normal_size= *dimension * sizeof(coordT); /* for tracing with qh_printpoint */
+ if (qh HALFspace) {
+ qh half_space= coordp= (coordT*)qh_malloc(qh normal_size + sizeof(coordT));
+ if (qh CDDinput) {
+ offsetp= qh half_space;
+ normalp= offsetp + 1;
+ }else {
+ normalp= qh half_space;
+ offsetp= normalp + *dimension;
+ }
+ }
+ qh maxline= diminput * (qh_REALdigits + 5);
+ maximize_(qh maxline, 500);
+ qh line= (char*)qh_malloc((qh maxline+1) * sizeof(char));
+ *ismalloc= True; /* use malloc since memory not setup */
+ coords= points= qh temp_malloc= /* numinput and diminput >=2 by QH6220 */
+ (coordT*)qh_malloc((*numpoints)*(*dimension)*sizeof(coordT));
+ if (!coords || !qh line || (qh HALFspace && !qh half_space)) {
+ qh_fprintf(qh ferr, 6076, "qhull error: insufficient memory to read %d points\n",
+ numinput);
+ qh_errexit(qh_ERRmem, NULL, NULL);
+ }
+ if (isdelaunay && qh ATinfinity) {
+ infinity= points + numinput * (*dimension);
+ for (k= (*dimension) - 1; k--; )
+ infinity[k]= 0.0;
+ }
+ maxcount= numinput * diminput;
+ paraboloid= 0.0;
+ while ((s= (isfirst ? s : fgets(qh line, qh maxline, qh fin)))) {
+ if (!isfirst) {
+ linecount++;
+ if (*s == 'e' || *s == 'E') {
+ if (!memcmp(s, "end", (size_t)3) || !memcmp(s, "END", (size_t)3)) {
+ if (qh CDDinput )
+ break;
+ else if (wasbegin)
+ qh_fprintf(qh ferr, 7058, "qhull input warning: the input appears to be in cdd format. If so, use 'Fd'\n");
+ }
+ }
+ }
+ islong= False;
+ while (*s) {
+ while (isspace(*s))
+ s++;
+ value= qh_strtod(s, &t);
+ if (s == t) {
+ if (!*qh rbox_command)
+ strncat(qh rbox_command, s, sizeof(qh rbox_command)-1);
+ if (*s && !firsttext)
+ firsttext= linecount;
+ if (!islong && !firstshort && coordcount)
+ firstshort= linecount;
+ break;
+ }
+ if (!firstpoint)
+ firstpoint= linecount;
+ s= t;
+ if (++tokcount > maxcount)
+ continue;
+ if (qh HALFspace) {
+ if (qh CDDinput)
+ *(coordp++)= -value; /* both coefficients and offset */
+ else
+ *(coordp++)= value;
+ }else {
+ *(coords++)= value;
+ if (qh CDDinput && !coordcount) {
+ if (value != 1.0) {
+ qh_fprintf(qh ferr, 6077, "qhull input error: for cdd format, point at line %d does not start with '1'\n",
+ linecount);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ coords--;
+ }else if (isdelaunay) {
+ paraboloid += value * value;
+ if (qh ATinfinity) {
+ if (qh CDDinput)
+ infinity[coordcount-1] += value;
+ else
+ infinity[coordcount] += value;
+ }
+ }
+ }
+ if (++coordcount == diminput) {
+ coordcount= 0;
+ if (isdelaunay) {
+ *(coords++)= paraboloid;
+ maximize_(maxboloid, paraboloid);
+ paraboloid= 0.0;
+ }else if (qh HALFspace) {
+ if (!qh_sethalfspace(*dimension, coords, &coords, normalp, offsetp, qh feasible_point)) {
+ qh_fprintf(qh ferr, 8048, "The halfspace was on line %d\n", linecount);
+ if (wasbegin)
+ qh_fprintf(qh ferr, 8049, "The input appears to be in cdd format. If so, you should use option 'Fd'\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ coordp= qh half_space;
+ }
+ while (isspace(*s))
+ s++;
+ if (*s) {
+ islong= True;
+ if (!firstlong)
+ firstlong= linecount;
+ }
+ }
+ }
+ if (!islong && !firstshort && coordcount)
+ firstshort= linecount;
+ if (!isfirst && s - qh line >= qh maxline) {
+ qh_fprintf(qh ferr, 6078, "qhull input error: line %d contained more than %d characters\n",
+ linecount, (int) (s - qh line)); /* WARN64 */
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ isfirst= False;
+ }
+ if (tokcount != maxcount) {
+ newnum= fmin_(numinput, tokcount/diminput);
+ qh_fprintf(qh ferr, 7073,"\
+qhull warning: instead of %d %d-dimensional points, input contains\n\
+%d points and %d extra coordinates. Line %d is the first\npoint",
+ numinput, diminput, tokcount/diminput, tokcount % diminput, firstpoint);
+ if (firsttext)
+ qh_fprintf(qh ferr, 8051, ", line %d is the first comment", firsttext);
+ if (firstshort)
+ qh_fprintf(qh ferr, 8052, ", line %d is the first short\nline", firstshort);
+ if (firstlong)
+ qh_fprintf(qh ferr, 8053, ", line %d is the first long line", firstlong);
+ qh_fprintf(qh ferr, 8054, ". Continue with %d points.\n", newnum);
+ numinput= newnum;
+ if (isdelaunay && qh ATinfinity) {
+ for (k= tokcount % diminput; k--; )
+ infinity[k] -= *(--coords);
+ *numpoints= newnum+1;
+ }else {
+ coords -= tokcount % diminput;
+ *numpoints= newnum;
+ }
+ }
+ if (isdelaunay && qh ATinfinity) {
+ for (k= (*dimension) -1; k--; )
+ infinity[k] /= numinput;
+ if (coords == infinity)
+ coords += (*dimension) -1;
+ else {
+ for (k=0; k < (*dimension) -1; k++)
+ *(coords++)= infinity[k];
+ }
+ *(coords++)= maxboloid * 1.1;
+ }
+ if (qh rbox_command[0]) {
+ qh rbox_command[strlen(qh rbox_command)-1]= '\0';
+ if (!strcmp(qh rbox_command, "./rbox D4"))
+ qh_fprintf(qh ferr, 8055, "\n\
+This is the qhull test case. If any errors or core dumps occur,\n\
+recompile qhull with 'make new'. If errors still occur, there is\n\
+an incompatibility. You should try a different compiler. You can also\n\
+change the choices in user.h. If you discover the source of the problem,\n\
+please send mail to qhull_bug@qhull.org.\n\
+\n\
+Type 'qhull' for a short list of options.\n");
+ }
+ qh_free(qh line);
+ qh line= NULL;
+ if (qh half_space) {
+ qh_free(qh half_space);
+ qh half_space= NULL;
+ }
+ qh temp_malloc= NULL;
+ trace1((qh ferr, 1008,"qh_readpoints: read in %d %d-dimensional points\n",
+ numinput, diminput));
+ return(points);
+} /* readpoints */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="setfeasible">-</a>
+
+ qh_setfeasible( dim )
+ set qh.feasible_point from qh.feasible_string in "n,n,n" or "n n n" format
+
+ notes:
+ "n,n,n" already checked by qh_initflags()
+ see qh_readfeasible()
+ called only once from qh_new_qhull, otherwise leaks memory
+*/
+void qh_setfeasible(int dim) {
+ int tokcount= 0;
+ char *s;
+ coordT *coords, value;
+
+ if (!(s= qh feasible_string)) {
+ qh_fprintf(qh ferr, 6223, "\
+qhull input error: halfspace intersection needs a feasible point.\n\
+Either prepend the input with 1 point or use 'Hn,n,n'. See manual.\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (!(qh feasible_point= (pointT*)qh_malloc(dim * sizeof(coordT)))) {
+ qh_fprintf(qh ferr, 6079, "qhull error: insufficient memory for 'Hn,n,n'\n");
+ qh_errexit(qh_ERRmem, NULL, NULL);
+ }
+ coords= qh feasible_point;
+ while (*s) {
+ value= qh_strtod(s, &s);
+ if (++tokcount > dim) {
+ qh_fprintf(qh ferr, 7059, "qhull input warning: more coordinates for 'H%s' than dimension %d\n",
+ qh feasible_string, dim);
+ break;
+ }
+ *(coords++)= value;
+ if (*s)
+ s++;
+ }
+ while (++tokcount <= dim)
+ *(coords++)= 0.0;
+} /* setfeasible */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="skipfacet">-</a>
+
+ qh_skipfacet( facet )
+ returns 'True' if this facet is not to be printed
+
+ notes:
+ based on the user provided slice thresholds and 'good' specifications
+*/
+boolT qh_skipfacet(facetT *facet) {
+ facetT *neighbor, **neighborp;
+
+ if (qh PRINTneighbors) {
+ if (facet->good)
+ return !qh PRINTgood;
+ FOREACHneighbor_(facet) {
+ if (neighbor->good)
+ return False;
+ }
+ return True;
+ }else if (qh PRINTgood)
+ return !facet->good;
+ else if (!facet->normal)
+ return True;
+ return(!qh_inthresholds(facet->normal, NULL));
+} /* skipfacet */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="skipfilename">-</a>
+
+ qh_skipfilename( string )
+ returns pointer to character after filename
+
+ notes:
+ skips leading spaces
+ ends with spacing or eol
+ if starts with ' or " ends with the same, skipping \' or \"
+ For qhull, qh_argv_to_command() only uses double quotes
+*/
+char *qh_skipfilename(char *filename) {
+ char *s= filename; /* non-const due to return */
+ char c;
+
+ while (*s && isspace(*s))
+ s++;
+ c= *s++;
+ if (c == '\0') {
+ qh_fprintf(qh ferr, 6204, "qhull input error: filename expected, none found.\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (c == '\'' || c == '"') {
+ while (*s !=c || s[-1] == '\\') {
+ if (!*s) {
+ qh_fprintf(qh ferr, 6203, "qhull input error: missing quote after filename -- %s\n", filename);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ s++;
+ }
+ s++;
+ }
+ else while (*s && !isspace(*s))
+ s++;
+ return s;
+} /* skipfilename */
+
diff --git a/xs/src/qhull/src/libqhull/io.h b/xs/src/qhull/src/libqhull/io.h
new file mode 100644
index 000000000..eca0369d3
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/io.h
@@ -0,0 +1,159 @@
+/*<html><pre> -<a href="qh-io.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ io.h
+ declarations of Input/Output functions
+
+ see README, libqhull.h and io.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/io.h#1 $$Change: 1981 $
+ $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
+*/
+
+#ifndef qhDEFio
+#define qhDEFio 1
+
+#include "libqhull.h"
+
+/*============ constants and flags ==================*/
+
+/*-<a href="qh-io.htm#TOC"
+ >--------------------------------</a><a name="qh_MAXfirst">-</a>
+
+ qh_MAXfirst
+ maximum length of first two lines of stdin
+*/
+#define qh_MAXfirst 200
+
+/*-<a href="qh-io.htm#TOC"
+ >--------------------------------</a><a name="qh_MINradius">-</a>
+
+ qh_MINradius
+ min radius for Gp and Gv, fraction of maxcoord
+*/
+#define qh_MINradius 0.02
+
+/*-<a href="qh-io.htm#TOC"
+ >--------------------------------</a><a name="qh_GEOMepsilon">-</a>
+
+ qh_GEOMepsilon
+ adjust outer planes for 'lines closer' and geomview roundoff.
+ This prevents bleed through.
+*/
+#define qh_GEOMepsilon 2e-3
+
+/*-<a href="qh-io.htm#TOC"
+ >--------------------------------</a><a name="qh_WHITESPACE">-</a>
+
+ qh_WHITESPACE
+ possible values of white space
+*/
+#define qh_WHITESPACE " \n\t\v\r\f"
+
+
+/*-<a href="qh-io.htm#TOC"
+ >--------------------------------</a><a name="RIDGE">-</a>
+
+ qh_RIDGE
+ to select which ridges to print in qh_eachvoronoi
+*/
+typedef enum
+{
+ qh_RIDGEall = 0, qh_RIDGEinner, qh_RIDGEouter
+}
+qh_RIDGE;
+
+/*-<a href="qh-io.htm#TOC"
+ >--------------------------------</a><a name="printvridgeT">-</a>
+
+ printvridgeT
+ prints results of qh_printvdiagram
+
+ see:
+ <a href="io.c#printvridge">qh_printvridge</a> for an example
+*/
+typedef void (*printvridgeT)(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
+
+/*============== -prototypes in alphabetical order =========*/
+
+void qh_dfacet(unsigned id);
+void qh_dvertex(unsigned id);
+int qh_compare_facetarea(const void *p1, const void *p2);
+int qh_compare_facetmerge(const void *p1, const void *p2);
+int qh_compare_facetvisit(const void *p1, const void *p2);
+int qh_compare_vertexpoint(const void *p1, const void *p2); /* not used, not in libqhull_r.h */
+void qh_copyfilename(char *filename, int size, const char* source, int length);
+void qh_countfacets(facetT *facetlist, setT *facets, boolT printall,
+ int *numfacetsp, int *numsimplicialp, int *totneighborsp,
+ int *numridgesp, int *numcoplanarsp, int *numnumtricoplanarsp);
+pointT *qh_detvnorm(vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp);
+setT *qh_detvridge(vertexT *vertex);
+setT *qh_detvridge3(vertexT *atvertex, vertexT *vertex);
+int qh_eachvoronoi(FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder);
+int qh_eachvoronoi_all(FILE *fp, printvridgeT printvridge, boolT isUpper, qh_RIDGE innerouter, boolT inorder);
+void qh_facet2point(facetT *facet, pointT **point0, pointT **point1, realT *mindist);
+setT *qh_facetvertices(facetT *facetlist, setT *facets, boolT allfacets);
+void qh_geomplanes(facetT *facet, realT *outerplane, realT *innerplane);
+void qh_markkeep(facetT *facetlist);
+setT *qh_markvoronoi(facetT *facetlist, setT *facets, boolT printall, boolT *isLowerp, int *numcentersp);
+void qh_order_vertexneighbors(vertexT *vertex);
+void qh_prepare_output(void);
+void qh_printafacet(FILE *fp, qh_PRINT format, facetT *facet, boolT printall);
+void qh_printbegin(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
+void qh_printcenter(FILE *fp, qh_PRINT format, const char *string, facetT *facet);
+void qh_printcentrum(FILE *fp, facetT *facet, realT radius);
+void qh_printend(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
+void qh_printend4geom(FILE *fp, facetT *facet, int *num, boolT printall);
+void qh_printextremes(FILE *fp, facetT *facetlist, setT *facets, boolT printall);
+void qh_printextremes_2d(FILE *fp, facetT *facetlist, setT *facets, boolT printall);
+void qh_printextremes_d(FILE *fp, facetT *facetlist, setT *facets, boolT printall);
+void qh_printfacet(FILE *fp, facetT *facet);
+void qh_printfacet2math(FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
+void qh_printfacet2geom(FILE *fp, facetT *facet, realT color[3]);
+void qh_printfacet2geom_points(FILE *fp, pointT *point1, pointT *point2,
+ facetT *facet, realT offset, realT color[3]);
+void qh_printfacet3math(FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
+void qh_printfacet3geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
+void qh_printfacet3geom_points(FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]);
+void qh_printfacet3geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
+void qh_printfacet3vertex(FILE *fp, facetT *facet, qh_PRINT format);
+void qh_printfacet4geom_nonsimplicial(FILE *fp, facetT *facet, realT color[3]);
+void qh_printfacet4geom_simplicial(FILE *fp, facetT *facet, realT color[3]);
+void qh_printfacetNvertex_nonsimplicial(FILE *fp, facetT *facet, int id, qh_PRINT format);
+void qh_printfacetNvertex_simplicial(FILE *fp, facetT *facet, qh_PRINT format);
+void qh_printfacetheader(FILE *fp, facetT *facet);
+void qh_printfacetridges(FILE *fp, facetT *facet);
+void qh_printfacets(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
+void qh_printhyperplaneintersection(FILE *fp, facetT *facet1, facetT *facet2,
+ setT *vertices, realT color[3]);
+void qh_printneighborhood(FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall);
+void qh_printline3geom(FILE *fp, pointT *pointA, pointT *pointB, realT color[3]);
+void qh_printpoint(FILE *fp, const char *string, pointT *point);
+void qh_printpointid(FILE *fp, const char *string, int dim, pointT *point, int id);
+void qh_printpoint3(FILE *fp, pointT *point);
+void qh_printpoints_out(FILE *fp, facetT *facetlist, setT *facets, boolT printall);
+void qh_printpointvect(FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]);
+void qh_printpointvect2(FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius);
+void qh_printridge(FILE *fp, ridgeT *ridge);
+void qh_printspheres(FILE *fp, setT *vertices, realT radius);
+void qh_printvdiagram(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
+int qh_printvdiagram2(FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder);
+void qh_printvertex(FILE *fp, vertexT *vertex);
+void qh_printvertexlist(FILE *fp, const char* string, facetT *facetlist,
+ setT *facets, boolT printall);
+void qh_printvertices(FILE *fp, const char* string, setT *vertices);
+void qh_printvneighbors(FILE *fp, facetT* facetlist, setT *facets, boolT printall);
+void qh_printvoronoi(FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
+void qh_printvnorm(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
+void qh_printvridge(FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
+void qh_produce_output(void);
+void qh_produce_output2(void);
+void qh_projectdim3(pointT *source, pointT *destination);
+int qh_readfeasible(int dim, const char *curline);
+coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
+void qh_setfeasible(int dim);
+boolT qh_skipfacet(facetT *facet);
+char *qh_skipfilename(char *filename);
+
+#endif /* qhDEFio */
diff --git a/xs/src/qhull/src/libqhull/libqhull.c b/xs/src/qhull/src/libqhull/libqhull.c
new file mode 100644
index 000000000..7696a8a9f
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/libqhull.c
@@ -0,0 +1,1403 @@
+/*<html><pre> -<a href="qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ libqhull.c
+ Quickhull algorithm for convex hulls
+
+ qhull() and top-level routines
+
+ see qh-qhull.htm, libqhull.h, unix.c
+
+ see qhull_a.h for internal functions
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/libqhull.c#3 $$Change: 2047 $
+ $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $
+*/
+
+#include "qhull_a.h"
+
+/*============= functions in alphabetic order after qhull() =======*/
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="qhull">-</a>
+
+ qh_qhull()
+ compute DIM3 convex hull of qh.num_points starting at qh.first_point
+ qh contains all global options and variables
+
+ returns:
+ returns polyhedron
+ qh.facet_list, qh.num_facets, qh.vertex_list, qh.num_vertices,
+
+ returns global variables
+ qh.hulltime, qh.max_outside, qh.interior_point, qh.max_vertex, qh.min_vertex
+
+ returns precision constants
+ qh.ANGLEround, centrum_radius, cos_max, DISTround, MAXabs_coord, ONEmerge
+
+ notes:
+ unless needed for output
+ qh.max_vertex and qh.min_vertex are max/min due to merges
+
+ see:
+ to add individual points to either qh.num_points
+ use qh_addpoint()
+
+ if qh.GETarea
+ qh_produceoutput() returns qh.totarea and qh.totvol via qh_getarea()
+
+ design:
+ record starting time
+ initialize hull and partition points
+ build convex hull
+ unless early termination
+ update facet->maxoutside for vertices, coplanar, and near-inside points
+ error if temporary sets exist
+ record end time
+*/
+
+void qh_qhull(void) {
+ int numoutside;
+
+ qh hulltime= qh_CPUclock;
+ if (qh RERUN || qh JOGGLEmax < REALmax/2)
+ qh_build_withrestart();
+ else {
+ qh_initbuild();
+ qh_buildhull();
+ }
+ if (!qh STOPpoint && !qh STOPcone) {
+ if (qh ZEROall_ok && !qh TESTvneighbors && qh MERGEexact)
+ qh_checkzero( qh_ALL);
+ if (qh ZEROall_ok && !qh TESTvneighbors && !qh WAScoplanar) {
+ trace2((qh ferr, 2055, "qh_qhull: all facets are clearly convex and no coplanar points. Post-merging and check of maxout not needed.\n"));
+ qh DOcheckmax= False;
+ }else {
+ if (qh MERGEexact || (qh hull_dim > qh_DIMreduceBuild && qh PREmerge))
+ qh_postmerge("First post-merge", qh premerge_centrum, qh premerge_cos,
+ (qh POSTmerge ? False : qh TESTvneighbors));
+ else if (!qh POSTmerge && qh TESTvneighbors)
+ qh_postmerge("For testing vertex neighbors", qh premerge_centrum,
+ qh premerge_cos, True);
+ if (qh POSTmerge)
+ qh_postmerge("For post-merging", qh postmerge_centrum,
+ qh postmerge_cos, qh TESTvneighbors);
+ if (qh visible_list == qh facet_list) { /* i.e., merging done */
+ qh findbestnew= True;
+ qh_partitionvisible(/*qh.visible_list*/ !qh_ALL, &numoutside);
+ qh findbestnew= False;
+ qh_deletevisible(/*qh.visible_list*/);
+ qh_resetlists(False, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
+ }
+ }
+ if (qh DOcheckmax){
+ if (qh REPORTfreq) {
+ qh_buildtracing(NULL, NULL);
+ qh_fprintf(qh ferr, 8115, "\nTesting all coplanar points.\n");
+ }
+ qh_check_maxout();
+ }
+ if (qh KEEPnearinside && !qh maxoutdone)
+ qh_nearcoplanar();
+ }
+ if (qh_setsize(qhmem.tempstack) != 0) {
+ qh_fprintf(qh ferr, 6164, "qhull internal error (qh_qhull): temporary sets not empty(%d)\n",
+ qh_setsize(qhmem.tempstack));
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ qh hulltime= qh_CPUclock - qh hulltime;
+ qh QHULLfinished= True;
+ trace1((qh ferr, 1036, "Qhull: algorithm completed\n"));
+} /* qhull */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="addpoint">-</a>
+
+ qh_addpoint( furthest, facet, checkdist )
+ add point (usually furthest point) above facet to hull
+ if checkdist,
+ check that point is above facet.
+ if point is not outside of the hull, uses qh_partitioncoplanar()
+ assumes that facet is defined by qh_findbestfacet()
+ else if facet specified,
+ assumes that point is above facet (major damage if below)
+ for Delaunay triangulations,
+ Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
+ Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates.
+
+ returns:
+ returns False if user requested an early termination
+ qh.visible_list, newfacet_list, delvertex_list, NEWfacets may be defined
+ updates qh.facet_list, qh.num_facets, qh.vertex_list, qh.num_vertices
+ clear qh.maxoutdone (will need to call qh_check_maxout() for facet->maxoutside)
+ if unknown point, adds a pointer to qh.other_points
+ do not deallocate the point's coordinates
+
+ notes:
+ assumes point is near its best facet and not at a local minimum of a lens
+ distributions. Use qh_findbestfacet to avoid this case.
+ uses qh.visible_list, qh.newfacet_list, qh.delvertex_list, qh.NEWfacets
+
+ see also:
+ qh_triangulate() -- triangulate non-simplicial facets
+
+ design:
+ add point to other_points if needed
+ if checkdist
+ if point not above facet
+ partition coplanar point
+ exit
+ exit if pre STOPpoint requested
+ find horizon and visible facets for point
+ make new facets for point to horizon
+ make hyperplanes for point
+ compute balance statistics
+ match neighboring new facets
+ update vertex neighbors and delete interior vertices
+ exit if STOPcone requested
+ merge non-convex new facets
+ if merge found, many merges, or 'Qf'
+ use qh_findbestnew() instead of qh_findbest()
+ partition outside points from visible facets
+ delete visible facets
+ check polyhedron if requested
+ exit if post STOPpoint requested
+ reset working lists of facets and vertices
+*/
+boolT qh_addpoint(pointT *furthest, facetT *facet, boolT checkdist) {
+ int goodvisible, goodhorizon;
+ vertexT *vertex;
+ facetT *newfacet;
+ realT dist, newbalance, pbalance;
+ boolT isoutside= False;
+ int numpart, numpoints, numnew, firstnew;
+
+ qh maxoutdone= False;
+ if (qh_pointid(furthest) == qh_IDunknown)
+ qh_setappend(&qh other_points, furthest);
+ if (!facet) {
+ qh_fprintf(qh ferr, 6213, "qhull internal error (qh_addpoint): NULL facet. Need to call qh_findbestfacet first\n");
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ if (checkdist) {
+ facet= qh_findbest(furthest, facet, !qh_ALL, !qh_ISnewfacets, !qh_NOupper,
+ &dist, &isoutside, &numpart);
+ zzadd_(Zpartition, numpart);
+ if (!isoutside) {
+ zinc_(Znotmax); /* last point of outsideset is no longer furthest. */
+ facet->notfurthest= True;
+ qh_partitioncoplanar(furthest, facet, &dist);
+ return True;
+ }
+ }
+ qh_buildtracing(furthest, facet);
+ if (qh STOPpoint < 0 && qh furthest_id == -qh STOPpoint-1) {
+ facet->notfurthest= True;
+ return False;
+ }
+ qh_findhorizon(furthest, facet, &goodvisible, &goodhorizon);
+ if (qh ONLYgood && !(goodvisible+goodhorizon) && !qh GOODclosest) {
+ zinc_(Znotgood);
+ facet->notfurthest= True;
+ /* last point of outsideset is no longer furthest. This is ok
+ since all points of the outside are likely to be bad */
+ qh_resetlists(False, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
+ return True;
+ }
+ zzinc_(Zprocessed);
+ firstnew= qh facet_id;
+ vertex= qh_makenewfacets(furthest /*visible_list, attaches if !ONLYgood */);
+ qh_makenewplanes(/* newfacet_list */);
+ numnew= qh facet_id - firstnew;
+ newbalance= numnew - (realT) (qh num_facets-qh num_visible)
+ * qh hull_dim/qh num_vertices;
+ wadd_(Wnewbalance, newbalance);
+ wadd_(Wnewbalance2, newbalance * newbalance);
+ if (qh ONLYgood
+ && !qh_findgood(qh newfacet_list, goodhorizon) && !qh GOODclosest) {
+ FORALLnew_facets
+ qh_delfacet(newfacet);
+ qh_delvertex(vertex);
+ qh_resetlists(True, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
+ zinc_(Znotgoodnew);
+ facet->notfurthest= True;
+ return True;
+ }
+ if (qh ONLYgood)
+ qh_attachnewfacets(/*visible_list*/);
+ qh_matchnewfacets();
+ qh_updatevertices();
+ if (qh STOPcone && qh furthest_id == qh STOPcone-1) {
+ facet->notfurthest= True;
+ return False; /* visible_list etc. still defined */
+ }
+ qh findbestnew= False;
+ if (qh PREmerge || qh MERGEexact) {
+ qh_premerge(vertex, qh premerge_centrum, qh premerge_cos);
+ if (qh_USEfindbestnew)
+ qh findbestnew= True;
+ else {
+ FORALLnew_facets {
+ if (!newfacet->simplicial) {
+ qh findbestnew= True; /* use qh_findbestnew instead of qh_findbest*/
+ break;
+ }
+ }
+ }
+ }else if (qh BESToutside)
+ qh findbestnew= True;
+ qh_partitionvisible(/*qh.visible_list*/ !qh_ALL, &numpoints);
+ qh findbestnew= False;
+ qh findbest_notsharp= False;
+ zinc_(Zpbalance);
+ pbalance= numpoints - (realT) qh hull_dim /* assumes all points extreme */
+ * (qh num_points - qh num_vertices)/qh num_vertices;
+ wadd_(Wpbalance, pbalance);
+ wadd_(Wpbalance2, pbalance * pbalance);
+ qh_deletevisible(/*qh.visible_list*/);
+ zmax_(Zmaxvertex, qh num_vertices);
+ qh NEWfacets= False;
+ if (qh IStracing >= 4) {
+ if (qh num_facets < 2000)
+ qh_printlists();
+ qh_printfacetlist(qh newfacet_list, NULL, True);
+ qh_checkpolygon(qh facet_list);
+ }else if (qh CHECKfrequently) {
+ if (qh num_facets < 50)
+ qh_checkpolygon(qh facet_list);
+ else
+ qh_checkpolygon(qh newfacet_list);
+ }
+ if (qh STOPpoint > 0 && qh furthest_id == qh STOPpoint-1)
+ return False;
+ qh_resetlists(True, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
+ /* qh_triangulate(); to test qh.TRInormals */
+ trace2((qh ferr, 2056, "qh_addpoint: added p%d new facets %d new balance %2.2g point balance %2.2g\n",
+ qh_pointid(furthest), numnew, newbalance, pbalance));
+ return True;
+} /* addpoint */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="build_withrestart">-</a>
+
+ qh_build_withrestart()
+ allow restarts due to qh.JOGGLEmax while calling qh_buildhull()
+ qh_errexit always undoes qh_build_withrestart()
+ qh.FIRSTpoint/qh.NUMpoints is point array
+ it may be moved by qh_joggleinput()
+*/
+void qh_build_withrestart(void) {
+ int restart;
+
+ qh ALLOWrestart= True;
+ while (True) {
+ restart= setjmp(qh restartexit); /* simple statement for CRAY J916 */
+ if (restart) { /* only from qh_precision() */
+ zzinc_(Zretry);
+ wmax_(Wretrymax, qh JOGGLEmax);
+ /* QH7078 warns about using 'TCn' with 'QJn' */
+ qh STOPcone= qh_IDunknown; /* if break from joggle, prevents normal output */
+ }
+ if (!qh RERUN && qh JOGGLEmax < REALmax/2) {
+ if (qh build_cnt > qh_JOGGLEmaxretry) {
+ qh_fprintf(qh ferr, 6229, "qhull precision error: %d attempts to construct a convex hull\n\
+ with joggled input. Increase joggle above 'QJ%2.2g'\n\
+ or modify qh_JOGGLE... parameters in user.h\n",
+ qh build_cnt, qh JOGGLEmax);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ if (qh build_cnt && !restart)
+ break;
+ }else if (qh build_cnt && qh build_cnt >= qh RERUN)
+ break;
+ qh STOPcone= 0;
+ qh_freebuild(True); /* first call is a nop */
+ qh build_cnt++;
+ if (!qh qhull_optionsiz)
+ qh qhull_optionsiz= (int)strlen(qh qhull_options); /* WARN64 */
+ else {
+ qh qhull_options [qh qhull_optionsiz]= '\0';
+ qh qhull_optionlen= qh_OPTIONline; /* starts a new line */
+ }
+ qh_option("_run", &qh build_cnt, NULL);
+ if (qh build_cnt == qh RERUN) {
+ qh IStracing= qh TRACElastrun; /* duplicated from qh_initqhull_globals */
+ if (qh TRACEpoint != qh_IDunknown || qh TRACEdist < REALmax/2 || qh TRACEmerge) {
+ qh TRACElevel= (qh IStracing? qh IStracing : 3);
+ qh IStracing= 0;
+ }
+ qhmem.IStracing= qh IStracing;
+ }
+ if (qh JOGGLEmax < REALmax/2)
+ qh_joggleinput();
+ qh_initbuild();
+ qh_buildhull();
+ if (qh JOGGLEmax < REALmax/2 && !qh MERGING)
+ qh_checkconvex(qh facet_list, qh_ALGORITHMfault);
+ }
+ qh ALLOWrestart= False;
+} /* qh_build_withrestart */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="buildhull">-</a>
+
+ qh_buildhull()
+ construct a convex hull by adding outside points one at a time
+
+ returns:
+
+ notes:
+ may be called multiple times
+ checks facet and vertex lists for incorrect flags
+ to recover from STOPcone, call qh_deletevisible and qh_resetlists
+
+ design:
+ check visible facet and newfacet flags
+ check newlist vertex flags and qh.STOPcone/STOPpoint
+ for each facet with a furthest outside point
+ add point to facet
+ exit if qh.STOPcone or qh.STOPpoint requested
+ if qh.NARROWhull for initial simplex
+ partition remaining outside points to coplanar sets
+*/
+void qh_buildhull(void) {
+ facetT *facet;
+ pointT *furthest;
+ vertexT *vertex;
+ int id;
+
+ trace1((qh ferr, 1037, "qh_buildhull: start build hull\n"));
+ FORALLfacets {
+ if (facet->visible || facet->newfacet) {
+ qh_fprintf(qh ferr, 6165, "qhull internal error (qh_buildhull): visible or new facet f%d in facet list\n",
+ facet->id);
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ }
+ FORALLvertices {
+ if (vertex->newlist) {
+ qh_fprintf(qh ferr, 6166, "qhull internal error (qh_buildhull): new vertex f%d in vertex list\n",
+ vertex->id);
+ qh_errprint("ERRONEOUS", NULL, NULL, NULL, vertex);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ id= qh_pointid(vertex->point);
+ if ((qh STOPpoint>0 && id == qh STOPpoint-1) ||
+ (qh STOPpoint<0 && id == -qh STOPpoint-1) ||
+ (qh STOPcone>0 && id == qh STOPcone-1)) {
+ trace1((qh ferr, 1038,"qh_buildhull: stop point or cone P%d in initial hull\n", id));
+ return;
+ }
+ }
+ qh facet_next= qh facet_list; /* advance facet when processed */
+ while ((furthest= qh_nextfurthest(&facet))) {
+ qh num_outside--; /* if ONLYmax, furthest may not be outside */
+ if (!qh_addpoint(furthest, facet, qh ONLYmax))
+ break;
+ }
+ if (qh NARROWhull) /* move points from outsideset to coplanarset */
+ qh_outcoplanar( /* facet_list */ );
+ if (qh num_outside && !furthest) {
+ qh_fprintf(qh ferr, 6167, "qhull internal error (qh_buildhull): %d outside points were never processed.\n", qh num_outside);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ trace1((qh ferr, 1039, "qh_buildhull: completed the hull construction\n"));
+} /* buildhull */
+
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="buildtracing">-</a>
+
+ qh_buildtracing( furthest, facet )
+ trace an iteration of qh_buildhull() for furthest point and facet
+ if !furthest, prints progress message
+
+ returns:
+ tracks progress with qh.lastreport
+ updates qh.furthest_id (-3 if furthest is NULL)
+ also resets visit_id, vertext_visit on wrap around
+
+ see:
+ qh_tracemerging()
+
+ design:
+ if !furthest
+ print progress message
+ exit
+ if 'TFn' iteration
+ print progress message
+ else if tracing
+ trace furthest point and facet
+ reset qh.visit_id and qh.vertex_visit if overflow may occur
+ set qh.furthest_id for tracing
+*/
+void qh_buildtracing(pointT *furthest, facetT *facet) {
+ realT dist= 0;
+ float cpu;
+ int total, furthestid;
+ time_t timedata;
+ struct tm *tp;
+ vertexT *vertex;
+
+ qh old_randomdist= qh RANDOMdist;
+ qh RANDOMdist= False;
+ if (!furthest) {
+ time(&timedata);
+ tp= localtime(&timedata);
+ cpu= (float)qh_CPUclock - (float)qh hulltime;
+ cpu /= (float)qh_SECticks;
+ total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
+ qh_fprintf(qh ferr, 8118, "\n\
+At %02d:%02d:%02d & %2.5g CPU secs, qhull has created %d facets and merged %d.\n\
+ The current hull contains %d facets and %d vertices. Last point was p%d\n",
+ tp->tm_hour, tp->tm_min, tp->tm_sec, cpu, qh facet_id -1,
+ total, qh num_facets, qh num_vertices, qh furthest_id);
+ return;
+ }
+ furthestid= qh_pointid(furthest);
+ if (qh TRACEpoint == furthestid) {
+ qh IStracing= qh TRACElevel;
+ qhmem.IStracing= qh TRACElevel;
+ }else if (qh TRACEpoint != qh_IDunknown && qh TRACEdist < REALmax/2) {
+ qh IStracing= 0;
+ qhmem.IStracing= 0;
+ }
+ if (qh REPORTfreq && (qh facet_id-1 > qh lastreport+qh REPORTfreq)) {
+ qh lastreport= qh facet_id-1;
+ time(&timedata);
+ tp= localtime(&timedata);
+ cpu= (float)qh_CPUclock - (float)qh hulltime;
+ cpu /= (float)qh_SECticks;
+ total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
+ zinc_(Zdistio);
+ qh_distplane(furthest, facet, &dist);
+ qh_fprintf(qh ferr, 8119, "\n\
+At %02d:%02d:%02d & %2.5g CPU secs, qhull has created %d facets and merged %d.\n\
+ The current hull contains %d facets and %d vertices. There are %d\n\
+ outside points. Next is point p%d(v%d), %2.2g above f%d.\n",
+ tp->tm_hour, tp->tm_min, tp->tm_sec, cpu, qh facet_id -1,
+ total, qh num_facets, qh num_vertices, qh num_outside+1,
+ furthestid, qh vertex_id, dist, getid_(facet));
+ }else if (qh IStracing >=1) {
+ cpu= (float)qh_CPUclock - (float)qh hulltime;
+ cpu /= (float)qh_SECticks;
+ qh_distplane(furthest, facet, &dist);
+ qh_fprintf(qh ferr, 8120, "qh_addpoint: add p%d(v%d) to hull of %d facets(%2.2g above f%d) and %d outside at %4.4g CPU secs. Previous was p%d.\n",
+ furthestid, qh vertex_id, qh num_facets, dist,
+ getid_(facet), qh num_outside+1, cpu, qh furthest_id);
+ }
+ zmax_(Zvisit2max, (int)qh visit_id/2);
+ if (qh visit_id > (unsigned) INT_MAX) { /* 31 bits */
+ zinc_(Zvisit);
+ qh visit_id= 0;
+ FORALLfacets
+ facet->visitid= 0;
+ }
+ zmax_(Zvvisit2max, (int)qh vertex_visit/2);
+ if (qh vertex_visit > (unsigned) INT_MAX) { /* 31 bits */
+ zinc_(Zvvisit);
+ qh vertex_visit= 0;
+ FORALLvertices
+ vertex->visitid= 0;
+ }
+ qh furthest_id= furthestid;
+ qh RANDOMdist= qh old_randomdist;
+} /* buildtracing */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="errexit2">-</a>
+
+ qh_errexit2( exitcode, facet, otherfacet )
+ return exitcode to system after an error
+ report two facets
+
+ returns:
+ assumes exitcode non-zero
+
+ see:
+ normally use qh_errexit() in user.c(reports a facet and a ridge)
+*/
+void qh_errexit2(int exitcode, facetT *facet, facetT *otherfacet) {
+
+ qh_errprint("ERRONEOUS", facet, otherfacet, NULL, NULL);
+ qh_errexit(exitcode, NULL, NULL);
+} /* errexit2 */
+
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="findhorizon">-</a>
+
+ qh_findhorizon( point, facet, goodvisible, goodhorizon )
+ given a visible facet, find the point's horizon and visible facets
+ for all facets, !facet-visible
+
+ returns:
+ returns qh.visible_list/num_visible with all visible facets
+ marks visible facets with ->visible
+ updates count of good visible and good horizon facets
+ updates qh.max_outside, qh.max_vertex, facet->maxoutside
+
+ see:
+ similar to qh_delpoint()
+
+ design:
+ move facet to qh.visible_list at end of qh.facet_list
+ for all visible facets
+ for each unvisited neighbor of a visible facet
+ compute distance of point to neighbor
+ if point above neighbor
+ move neighbor to end of qh.visible_list
+ else if point is coplanar with neighbor
+ update qh.max_outside, qh.max_vertex, neighbor->maxoutside
+ mark neighbor coplanar (will create a samecycle later)
+ update horizon statistics
+*/
+void qh_findhorizon(pointT *point, facetT *facet, int *goodvisible, int *goodhorizon) {
+ facetT *neighbor, **neighborp, *visible;
+ int numhorizon= 0, coplanar= 0;
+ realT dist;
+
+ trace1((qh ferr, 1040,"qh_findhorizon: find horizon for point p%d facet f%d\n",qh_pointid(point),facet->id));
+ *goodvisible= *goodhorizon= 0;
+ zinc_(Ztotvisible);
+ qh_removefacet(facet); /* visible_list at end of qh facet_list */
+ qh_appendfacet(facet);
+ qh num_visible= 1;
+ if (facet->good)
+ (*goodvisible)++;
+ qh visible_list= facet;
+ facet->visible= True;
+ facet->f.replace= NULL;
+ if (qh IStracing >=4)
+ qh_errprint("visible", facet, NULL, NULL, NULL);
+ qh visit_id++;
+ FORALLvisible_facets {
+ if (visible->tricoplanar && !qh TRInormals) {
+ qh_fprintf(qh ferr, 6230, "Qhull internal error (qh_findhorizon): does not work for tricoplanar facets. Use option 'Q11'\n");
+ qh_errexit(qh_ERRqhull, visible, NULL);
+ }
+ visible->visitid= qh visit_id;
+ FOREACHneighbor_(visible) {
+ if (neighbor->visitid == qh visit_id)
+ continue;
+ neighbor->visitid= qh visit_id;
+ zzinc_(Znumvisibility);
+ qh_distplane(point, neighbor, &dist);
+ if (dist > qh MINvisible) {
+ zinc_(Ztotvisible);
+ qh_removefacet(neighbor); /* append to end of qh visible_list */
+ qh_appendfacet(neighbor);
+ neighbor->visible= True;
+ neighbor->f.replace= NULL;
+ qh num_visible++;
+ if (neighbor->good)
+ (*goodvisible)++;
+ if (qh IStracing >=4)
+ qh_errprint("visible", neighbor, NULL, NULL, NULL);
+ }else {
+ if (dist > - qh MAXcoplanar) {
+ neighbor->coplanar= True;
+ zzinc_(Zcoplanarhorizon);
+ qh_precision("coplanar horizon");
+ coplanar++;
+ if (qh MERGING) {
+ if (dist > 0) {
+ maximize_(qh max_outside, dist);
+ maximize_(qh max_vertex, dist);
+#if qh_MAXoutside
+ maximize_(neighbor->maxoutside, dist);
+#endif
+ }else
+ minimize_(qh min_vertex, dist); /* due to merge later */
+ }
+ trace2((qh ferr, 2057, "qh_findhorizon: point p%d is coplanar to horizon f%d, dist=%2.7g < qh MINvisible(%2.7g)\n",
+ qh_pointid(point), neighbor->id, dist, qh MINvisible));
+ }else
+ neighbor->coplanar= False;
+ zinc_(Ztothorizon);
+ numhorizon++;
+ if (neighbor->good)
+ (*goodhorizon)++;
+ if (qh IStracing >=4)
+ qh_errprint("horizon", neighbor, NULL, NULL, NULL);
+ }
+ }
+ }
+ if (!numhorizon) {
+ qh_precision("empty horizon");
+ qh_fprintf(qh ferr, 6168, "qhull precision error (qh_findhorizon): empty horizon\n\
+QhullPoint p%d was above all facets.\n", qh_pointid(point));
+ qh_printfacetlist(qh facet_list, NULL, True);
+ qh_errexit(qh_ERRprec, NULL, NULL);
+ }
+ trace1((qh ferr, 1041, "qh_findhorizon: %d horizon facets(good %d), %d visible(good %d), %d coplanar\n",
+ numhorizon, *goodhorizon, qh num_visible, *goodvisible, coplanar));
+ if (qh IStracing >= 4 && qh num_facets < 50)
+ qh_printlists();
+} /* findhorizon */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="nextfurthest">-</a>
+
+ qh_nextfurthest( visible )
+ returns next furthest point and visible facet for qh_addpoint()
+ starts search at qh.facet_next
+
+ returns:
+ removes furthest point from outside set
+ NULL if none available
+ advances qh.facet_next over facets with empty outside sets
+
+ design:
+ for each facet from qh.facet_next
+ if empty outside set
+ advance qh.facet_next
+ else if qh.NARROWhull
+ determine furthest outside point
+ if furthest point is not outside
+ advance qh.facet_next(point will be coplanar)
+ remove furthest point from outside set
+*/
+pointT *qh_nextfurthest(facetT **visible) {
+ facetT *facet;
+ int size, idx;
+ realT randr, dist;
+ pointT *furthest;
+
+ while ((facet= qh facet_next) != qh facet_tail) {
+ if (!facet->outsideset) {
+ qh facet_next= facet->next;
+ continue;
+ }
+ SETreturnsize_(facet->outsideset, size);
+ if (!size) {
+ qh_setfree(&facet->outsideset);
+ qh facet_next= facet->next;
+ continue;
+ }
+ if (qh NARROWhull) {
+ if (facet->notfurthest)
+ qh_furthestout(facet);
+ furthest= (pointT*)qh_setlast(facet->outsideset);
+#if qh_COMPUTEfurthest
+ qh_distplane(furthest, facet, &dist);
+ zinc_(Zcomputefurthest);
+#else
+ dist= facet->furthestdist;
+#endif
+ if (dist < qh MINoutside) { /* remainder of outside set is coplanar for qh_outcoplanar */
+ qh facet_next= facet->next;
+ continue;
+ }
+ }
+ if (!qh RANDOMoutside && !qh VIRTUALmemory) {
+ if (qh PICKfurthest) {
+ qh_furthestnext(/* qh.facet_list */);
+ facet= qh facet_next;
+ }
+ *visible= facet;
+ return((pointT*)qh_setdellast(facet->outsideset));
+ }
+ if (qh RANDOMoutside) {
+ int outcoplanar = 0;
+ if (qh NARROWhull) {
+ FORALLfacets {
+ if (facet == qh facet_next)
+ break;
+ if (facet->outsideset)
+ outcoplanar += qh_setsize( facet->outsideset);
+ }
+ }
+ randr= qh_RANDOMint;
+ randr= randr/(qh_RANDOMmax+1);
+ idx= (int)floor((qh num_outside - outcoplanar) * randr);
+ FORALLfacet_(qh facet_next) {
+ if (facet->outsideset) {
+ SETreturnsize_(facet->outsideset, size);
+ if (!size)
+ qh_setfree(&facet->outsideset);
+ else if (size > idx) {
+ *visible= facet;
+ return((pointT*)qh_setdelnth(facet->outsideset, idx));
+ }else
+ idx -= size;
+ }
+ }
+ qh_fprintf(qh ferr, 6169, "qhull internal error (qh_nextfurthest): num_outside %d is too low\nby at least %d, or a random real %g >= 1.0\n",
+ qh num_outside, idx+1, randr);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }else { /* VIRTUALmemory */
+ facet= qh facet_tail->previous;
+ if (!(furthest= (pointT*)qh_setdellast(facet->outsideset))) {
+ if (facet->outsideset)
+ qh_setfree(&facet->outsideset);
+ qh_removefacet(facet);
+ qh_prependfacet(facet, &qh facet_list);
+ continue;
+ }
+ *visible= facet;
+ return furthest;
+ }
+ }
+ return NULL;
+} /* nextfurthest */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="partitionall">-</a>
+
+ qh_partitionall( vertices, points, numpoints )
+ partitions all points in points/numpoints to the outsidesets of facets
+ vertices= vertices in qh.facet_list(!partitioned)
+
+ returns:
+ builds facet->outsideset
+ does not partition qh.GOODpoint
+ if qh.ONLYgood && !qh.MERGING,
+ does not partition qh.GOODvertex
+
+ notes:
+ faster if qh.facet_list sorted by anticipated size of outside set
+
+ design:
+ initialize pointset with all points
+ remove vertices from pointset
+ remove qh.GOODpointp from pointset (unless it's qh.STOPcone or qh.STOPpoint)
+ for all facets
+ for all remaining points in pointset
+ compute distance from point to facet
+ if point is outside facet
+ remove point from pointset (by not reappending)
+ update bestpoint
+ append point or old bestpoint to facet's outside set
+ append bestpoint to facet's outside set (furthest)
+ for all points remaining in pointset
+ partition point into facets' outside sets and coplanar sets
+*/
+void qh_partitionall(setT *vertices, pointT *points, int numpoints){
+ setT *pointset;
+ vertexT *vertex, **vertexp;
+ pointT *point, **pointp, *bestpoint;
+ int size, point_i, point_n, point_end, remaining, i, id;
+ facetT *facet;
+ realT bestdist= -REALmax, dist, distoutside;
+
+ trace1((qh ferr, 1042, "qh_partitionall: partition all points into outside sets\n"));
+ pointset= qh_settemp(numpoints);
+ qh num_outside= 0;
+ pointp= SETaddr_(pointset, pointT);
+ for (i=numpoints, point= points; i--; point += qh hull_dim)
+ *(pointp++)= point;
+ qh_settruncate(pointset, numpoints);
+ FOREACHvertex_(vertices) {
+ if ((id= qh_pointid(vertex->point)) >= 0)
+ SETelem_(pointset, id)= NULL;
+ }
+ id= qh_pointid(qh GOODpointp);
+ if (id >=0 && qh STOPcone-1 != id && -qh STOPpoint-1 != id)
+ SETelem_(pointset, id)= NULL;
+ if (qh GOODvertexp && qh ONLYgood && !qh MERGING) { /* matches qhull()*/
+ if ((id= qh_pointid(qh GOODvertexp)) >= 0)
+ SETelem_(pointset, id)= NULL;
+ }
+ if (!qh BESToutside) { /* matches conditional for qh_partitionpoint below */
+ distoutside= qh_DISToutside; /* multiple of qh.MINoutside & qh.max_outside, see user.h */
+ zval_(Ztotpartition)= qh num_points - qh hull_dim - 1; /*misses GOOD... */
+ remaining= qh num_facets;
+ point_end= numpoints;
+ FORALLfacets {
+ size= point_end/(remaining--) + 100;
+ facet->outsideset= qh_setnew(size);
+ bestpoint= NULL;
+ point_end= 0;
+ FOREACHpoint_i_(pointset) {
+ if (point) {
+ zzinc_(Zpartitionall);
+ qh_distplane(point, facet, &dist);
+ if (dist < distoutside)
+ SETelem_(pointset, point_end++)= point;
+ else {
+ qh num_outside++;
+ if (!bestpoint) {
+ bestpoint= point;
+ bestdist= dist;
+ }else if (dist > bestdist) {
+ qh_setappend(&facet->outsideset, bestpoint);
+ bestpoint= point;
+ bestdist= dist;
+ }else
+ qh_setappend(&facet->outsideset, point);
+ }
+ }
+ }
+ if (bestpoint) {
+ qh_setappend(&facet->outsideset, bestpoint);
+#if !qh_COMPUTEfurthest
+ facet->furthestdist= bestdist;
+#endif
+ }else
+ qh_setfree(&facet->outsideset);
+ qh_settruncate(pointset, point_end);
+ }
+ }
+ /* if !qh BESToutside, pointset contains points not assigned to outsideset */
+ if (qh BESToutside || qh MERGING || qh KEEPcoplanar || qh KEEPinside) {
+ qh findbestnew= True;
+ FOREACHpoint_i_(pointset) {
+ if (point)
+ qh_partitionpoint(point, qh facet_list);
+ }
+ qh findbestnew= False;
+ }
+ zzadd_(Zpartitionall, zzval_(Zpartition));
+ zzval_(Zpartition)= 0;
+ qh_settempfree(&pointset);
+ if (qh IStracing >= 4)
+ qh_printfacetlist(qh facet_list, NULL, True);
+} /* partitionall */
+
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="partitioncoplanar">-</a>
+
+ qh_partitioncoplanar( point, facet, dist )
+ partition coplanar point to a facet
+ dist is distance from point to facet
+ if dist NULL,
+ searches for bestfacet and does nothing if inside
+ if qh.findbestnew set,
+ searches new facets instead of using qh_findbest()
+
+ returns:
+ qh.max_ouside updated
+ if qh.KEEPcoplanar or qh.KEEPinside
+ point assigned to best coplanarset
+
+ notes:
+ facet->maxoutside is updated at end by qh_check_maxout
+
+ design:
+ if dist undefined
+ find best facet for point
+ if point sufficiently below facet (depends on qh.NEARinside and qh.KEEPinside)
+ exit
+ if keeping coplanar/nearinside/inside points
+ if point is above furthest coplanar point
+ append point to coplanar set (it is the new furthest)
+ update qh.max_outside
+ else
+ append point one before end of coplanar set
+ else if point is clearly outside of qh.max_outside and bestfacet->coplanarset
+ and bestfacet is more than perpendicular to facet
+ repartition the point using qh_findbest() -- it may be put on an outsideset
+ else
+ update qh.max_outside
+*/
+void qh_partitioncoplanar(pointT *point, facetT *facet, realT *dist) {
+ facetT *bestfacet;
+ pointT *oldfurthest;
+ realT bestdist, dist2= 0, angle;
+ int numpart= 0, oldfindbest;
+ boolT isoutside;
+
+ qh WAScoplanar= True;
+ if (!dist) {
+ if (qh findbestnew)
+ bestfacet= qh_findbestnew(point, facet, &bestdist, qh_ALL, &isoutside, &numpart);
+ else
+ bestfacet= qh_findbest(point, facet, qh_ALL, !qh_ISnewfacets, qh DELAUNAY,
+ &bestdist, &isoutside, &numpart);
+ zinc_(Ztotpartcoplanar);
+ zzadd_(Zpartcoplanar, numpart);
+ if (!qh DELAUNAY && !qh KEEPinside) { /* for 'd', bestdist skips upperDelaunay facets */
+ if (qh KEEPnearinside) {
+ if (bestdist < -qh NEARinside) {
+ zinc_(Zcoplanarinside);
+ trace4((qh ferr, 4062, "qh_partitioncoplanar: point p%d is more than near-inside facet f%d dist %2.2g findbestnew %d\n",
+ qh_pointid(point), bestfacet->id, bestdist, qh findbestnew));
+ return;
+ }
+ }else if (bestdist < -qh MAXcoplanar) {
+ trace4((qh ferr, 4063, "qh_partitioncoplanar: point p%d is inside facet f%d dist %2.2g findbestnew %d\n",
+ qh_pointid(point), bestfacet->id, bestdist, qh findbestnew));
+ zinc_(Zcoplanarinside);
+ return;
+ }
+ }
+ }else {
+ bestfacet= facet;
+ bestdist= *dist;
+ }
+ if (bestdist > qh max_outside) {
+ if (!dist && facet != bestfacet) {
+ zinc_(Zpartangle);
+ angle= qh_getangle(facet->normal, bestfacet->normal);
+ if (angle < 0) {
+ /* typically due to deleted vertex and coplanar facets, e.g.,
+ RBOX 1000 s Z1 G1e-13 t1001185205 | QHULL Tv */
+ zinc_(Zpartflip);
+ trace2((qh ferr, 2058, "qh_partitioncoplanar: repartition point p%d from f%d. It is above flipped facet f%d dist %2.2g\n",
+ qh_pointid(point), facet->id, bestfacet->id, bestdist));
+ oldfindbest= qh findbestnew;
+ qh findbestnew= False;
+ qh_partitionpoint(point, bestfacet);
+ qh findbestnew= oldfindbest;
+ return;
+ }
+ }
+ qh max_outside= bestdist;
+ if (bestdist > qh TRACEdist) {
+ qh_fprintf(qh ferr, 8122, "qh_partitioncoplanar: ====== p%d from f%d increases max_outside to %2.2g of f%d last p%d\n",
+ qh_pointid(point), facet->id, bestdist, bestfacet->id, qh furthest_id);
+ qh_errprint("DISTANT", facet, bestfacet, NULL, NULL);
+ }
+ }
+ if (qh KEEPcoplanar + qh KEEPinside + qh KEEPnearinside) {
+ oldfurthest= (pointT*)qh_setlast(bestfacet->coplanarset);
+ if (oldfurthest) {
+ zinc_(Zcomputefurthest);
+ qh_distplane(oldfurthest, bestfacet, &dist2);
+ }
+ if (!oldfurthest || dist2 < bestdist)
+ qh_setappend(&bestfacet->coplanarset, point);
+ else
+ qh_setappend2ndlast(&bestfacet->coplanarset, point);
+ }
+ trace4((qh ferr, 4064, "qh_partitioncoplanar: point p%d is coplanar with facet f%d(or inside) dist %2.2g\n",
+ qh_pointid(point), bestfacet->id, bestdist));
+} /* partitioncoplanar */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="partitionpoint">-</a>
+
+ qh_partitionpoint( point, facet )
+ assigns point to an outside set, coplanar set, or inside set (i.e., dropt)
+ if qh.findbestnew
+ uses qh_findbestnew() to search all new facets
+ else
+ uses qh_findbest()
+
+ notes:
+ after qh_distplane(), this and qh_findbest() are most expensive in 3-d
+
+ design:
+ find best facet for point
+ (either exhaustive search of new facets or directed search from facet)
+ if qh.NARROWhull
+ retain coplanar and nearinside points as outside points
+ if point is outside bestfacet
+ if point above furthest point for bestfacet
+ append point to outside set (it becomes the new furthest)
+ if outside set was empty
+ move bestfacet to end of qh.facet_list (i.e., after qh.facet_next)
+ update bestfacet->furthestdist
+ else
+ append point one before end of outside set
+ else if point is coplanar to bestfacet
+ if keeping coplanar points or need to update qh.max_outside
+ partition coplanar point into bestfacet
+ else if near-inside point
+ partition as coplanar point into bestfacet
+ else is an inside point
+ if keeping inside points
+ partition as coplanar point into bestfacet
+*/
+void qh_partitionpoint(pointT *point, facetT *facet) {
+ realT bestdist;
+ boolT isoutside;
+ facetT *bestfacet;
+ int numpart;
+#if qh_COMPUTEfurthest
+ realT dist;
+#endif
+
+ if (qh findbestnew)
+ bestfacet= qh_findbestnew(point, facet, &bestdist, qh BESToutside, &isoutside, &numpart);
+ else
+ bestfacet= qh_findbest(point, facet, qh BESToutside, qh_ISnewfacets, !qh_NOupper,
+ &bestdist, &isoutside, &numpart);
+ zinc_(Ztotpartition);
+ zzadd_(Zpartition, numpart);
+ if (qh NARROWhull) {
+ if (qh DELAUNAY && !isoutside && bestdist >= -qh MAXcoplanar)
+ qh_precision("nearly incident point(narrow hull)");
+ if (qh KEEPnearinside) {
+ if (bestdist >= -qh NEARinside)
+ isoutside= True;
+ }else if (bestdist >= -qh MAXcoplanar)
+ isoutside= True;
+ }
+
+ if (isoutside) {
+ if (!bestfacet->outsideset
+ || !qh_setlast(bestfacet->outsideset)) {
+ qh_setappend(&(bestfacet->outsideset), point);
+ if (!bestfacet->newfacet) {
+ qh_removefacet(bestfacet); /* make sure it's after qh facet_next */
+ qh_appendfacet(bestfacet);
+ }
+#if !qh_COMPUTEfurthest
+ bestfacet->furthestdist= bestdist;
+#endif
+ }else {
+#if qh_COMPUTEfurthest
+ zinc_(Zcomputefurthest);
+ qh_distplane(oldfurthest, bestfacet, &dist);
+ if (dist < bestdist)
+ qh_setappend(&(bestfacet->outsideset), point);
+ else
+ qh_setappend2ndlast(&(bestfacet->outsideset), point);
+#else
+ if (bestfacet->furthestdist < bestdist) {
+ qh_setappend(&(bestfacet->outsideset), point);
+ bestfacet->furthestdist= bestdist;
+ }else
+ qh_setappend2ndlast(&(bestfacet->outsideset), point);
+#endif
+ }
+ qh num_outside++;
+ trace4((qh ferr, 4065, "qh_partitionpoint: point p%d is outside facet f%d new? %d (or narrowhull)\n",
+ qh_pointid(point), bestfacet->id, bestfacet->newfacet));
+ }else if (qh DELAUNAY || bestdist >= -qh MAXcoplanar) { /* for 'd', bestdist skips upperDelaunay facets */
+ zzinc_(Zcoplanarpart);
+ if (qh DELAUNAY)
+ qh_precision("nearly incident point");
+ if ((qh KEEPcoplanar + qh KEEPnearinside) || bestdist > qh max_outside)
+ qh_partitioncoplanar(point, bestfacet, &bestdist);
+ else {
+ trace4((qh ferr, 4066, "qh_partitionpoint: point p%d is coplanar to facet f%d (dropped)\n",
+ qh_pointid(point), bestfacet->id));
+ }
+ }else if (qh KEEPnearinside && bestdist > -qh NEARinside) {
+ zinc_(Zpartnear);
+ qh_partitioncoplanar(point, bestfacet, &bestdist);
+ }else {
+ zinc_(Zpartinside);
+ trace4((qh ferr, 4067, "qh_partitionpoint: point p%d is inside all facets, closest to f%d dist %2.2g\n",
+ qh_pointid(point), bestfacet->id, bestdist));
+ if (qh KEEPinside)
+ qh_partitioncoplanar(point, bestfacet, &bestdist);
+ }
+} /* partitionpoint */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="partitionvisible">-</a>
+
+ qh_partitionvisible( allpoints, numoutside )
+ partitions points in visible facets to qh.newfacet_list
+ qh.visible_list= visible facets
+ for visible facets
+ 1st neighbor (if any) points to a horizon facet or a new facet
+ if allpoints(!used),
+ repartitions coplanar points
+
+ returns:
+ updates outside sets and coplanar sets of qh.newfacet_list
+ updates qh.num_outside (count of outside points)
+
+ notes:
+ qh.findbest_notsharp should be clear (extra work if set)
+
+ design:
+ for all visible facets with outside set or coplanar set
+ select a newfacet for visible facet
+ if outside set
+ partition outside set into new facets
+ if coplanar set and keeping coplanar/near-inside/inside points
+ if allpoints
+ partition coplanar set into new facets, may be assigned outside
+ else
+ partition coplanar set into coplanar sets of new facets
+ for each deleted vertex
+ if allpoints
+ partition vertex into new facets, may be assigned outside
+ else
+ partition vertex into coplanar sets of new facets
+*/
+void qh_partitionvisible(/*qh.visible_list*/ boolT allpoints, int *numoutside) {
+ facetT *visible, *newfacet;
+ pointT *point, **pointp;
+ int coplanar=0, size;
+ unsigned count;
+ vertexT *vertex, **vertexp;
+
+ if (qh ONLYmax)
+ maximize_(qh MINoutside, qh max_vertex);
+ *numoutside= 0;
+ FORALLvisible_facets {
+ if (!visible->outsideset && !visible->coplanarset)
+ continue;
+ newfacet= visible->f.replace;
+ count= 0;
+ while (newfacet && newfacet->visible) {
+ newfacet= newfacet->f.replace;
+ if (count++ > qh facet_id)
+ qh_infiniteloop(visible);
+ }
+ if (!newfacet)
+ newfacet= qh newfacet_list;
+ if (newfacet == qh facet_tail) {
+ qh_fprintf(qh ferr, 6170, "qhull precision error (qh_partitionvisible): all new facets deleted as\n degenerate facets. Can not continue.\n");
+ qh_errexit(qh_ERRprec, NULL, NULL);
+ }
+ if (visible->outsideset) {
+ size= qh_setsize(visible->outsideset);
+ *numoutside += size;
+ qh num_outside -= size;
+ FOREACHpoint_(visible->outsideset)
+ qh_partitionpoint(point, newfacet);
+ }
+ if (visible->coplanarset && (qh KEEPcoplanar + qh KEEPinside + qh KEEPnearinside)) {
+ size= qh_setsize(visible->coplanarset);
+ coplanar += size;
+ FOREACHpoint_(visible->coplanarset) {
+ if (allpoints) /* not used */
+ qh_partitionpoint(point, newfacet);
+ else
+ qh_partitioncoplanar(point, newfacet, NULL);
+ }
+ }
+ }
+ FOREACHvertex_(qh del_vertices) {
+ if (vertex->point) {
+ if (allpoints) /* not used */
+ qh_partitionpoint(vertex->point, qh newfacet_list);
+ else
+ qh_partitioncoplanar(vertex->point, qh newfacet_list, NULL);
+ }
+ }
+ trace1((qh ferr, 1043,"qh_partitionvisible: partitioned %d points from outsidesets and %d points from coplanarsets\n", *numoutside, coplanar));
+} /* partitionvisible */
+
+
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="precision">-</a>
+
+ qh_precision( reason )
+ restart on precision errors if not merging and if 'QJn'
+*/
+void qh_precision(const char *reason) {
+
+ if (qh ALLOWrestart && !qh PREmerge && !qh MERGEexact) {
+ if (qh JOGGLEmax < REALmax/2) {
+ trace0((qh ferr, 26, "qh_precision: qhull restart because of %s\n", reason));
+ /* May be called repeatedly if qh->ALLOWrestart */
+ longjmp(qh restartexit, qh_ERRprec);
+ }
+ }
+} /* qh_precision */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="printsummary">-</a>
+
+ qh_printsummary( fp )
+ prints summary to fp
+
+ notes:
+ not in io.c so that user_eg.c can prevent io.c from loading
+ qh_printsummary and qh_countfacets must match counts
+
+ design:
+ determine number of points, vertices, and coplanar points
+ print summary
+*/
+void qh_printsummary(FILE *fp) {
+ realT ratio, outerplane, innerplane;
+ float cpu;
+ int size, id, nummerged, numvertices, numcoplanars= 0, nonsimplicial=0;
+ int goodused;
+ facetT *facet;
+ const char *s;
+ int numdel= zzval_(Zdelvertextot);
+ int numtricoplanars= 0;
+
+ size= qh num_points + qh_setsize(qh other_points);
+ numvertices= qh num_vertices - qh_setsize(qh del_vertices);
+ id= qh_pointid(qh GOODpointp);
+ FORALLfacets {
+ if (facet->coplanarset)
+ numcoplanars += qh_setsize( facet->coplanarset);
+ if (facet->good) {
+ if (facet->simplicial) {
+ if (facet->keepcentrum && facet->tricoplanar)
+ numtricoplanars++;
+ }else if (qh_setsize(facet->vertices) != qh hull_dim)
+ nonsimplicial++;
+ }
+ }
+ if (id >=0 && qh STOPcone-1 != id && -qh STOPpoint-1 != id)
+ size--;
+ if (qh STOPcone || qh STOPpoint)
+ qh_fprintf(fp, 9288, "\nAt a premature exit due to 'TVn', 'TCn', 'TRn', or precision error with 'QJn'.");
+ if (qh UPPERdelaunay)
+ goodused= qh GOODvertex + qh GOODpoint + qh SPLITthresholds;
+ else if (qh DELAUNAY)
+ goodused= qh GOODvertex + qh GOODpoint + qh GOODthreshold;
+ else
+ goodused= qh num_good;
+ nummerged= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
+ if (qh VORONOI) {
+ if (qh UPPERdelaunay)
+ qh_fprintf(fp, 9289, "\n\
+Furthest-site Voronoi vertices by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
+ else
+ qh_fprintf(fp, 9290, "\n\
+Voronoi diagram by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
+ qh_fprintf(fp, 9291, " Number of Voronoi regions%s: %d\n",
+ qh ATinfinity ? " and at-infinity" : "", numvertices);
+ if (numdel)
+ qh_fprintf(fp, 9292, " Total number of deleted points due to merging: %d\n", numdel);
+ if (numcoplanars - numdel > 0)
+ qh_fprintf(fp, 9293, " Number of nearly incident points: %d\n", numcoplanars - numdel);
+ else if (size - numvertices - numdel > 0)
+ qh_fprintf(fp, 9294, " Total number of nearly incident points: %d\n", size - numvertices - numdel);
+ qh_fprintf(fp, 9295, " Number of%s Voronoi vertices: %d\n",
+ goodused ? " 'good'" : "", qh num_good);
+ if (nonsimplicial)
+ qh_fprintf(fp, 9296, " Number of%s non-simplicial Voronoi vertices: %d\n",
+ goodused ? " 'good'" : "", nonsimplicial);
+ }else if (qh DELAUNAY) {
+ if (qh UPPERdelaunay)
+ qh_fprintf(fp, 9297, "\n\
+Furthest-site Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
+ else
+ qh_fprintf(fp, 9298, "\n\
+Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
+ qh_fprintf(fp, 9299, " Number of input sites%s: %d\n",
+ qh ATinfinity ? " and at-infinity" : "", numvertices);
+ if (numdel)
+ qh_fprintf(fp, 9300, " Total number of deleted points due to merging: %d\n", numdel);
+ if (numcoplanars - numdel > 0)
+ qh_fprintf(fp, 9301, " Number of nearly incident points: %d\n", numcoplanars - numdel);
+ else if (size - numvertices - numdel > 0)
+ qh_fprintf(fp, 9302, " Total number of nearly incident points: %d\n", size - numvertices - numdel);
+ qh_fprintf(fp, 9303, " Number of%s Delaunay regions: %d\n",
+ goodused ? " 'good'" : "", qh num_good);
+ if (nonsimplicial)
+ qh_fprintf(fp, 9304, " Number of%s non-simplicial Delaunay regions: %d\n",
+ goodused ? " 'good'" : "", nonsimplicial);
+ }else if (qh HALFspace) {
+ qh_fprintf(fp, 9305, "\n\
+Halfspace intersection by the convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
+ qh_fprintf(fp, 9306, " Number of halfspaces: %d\n", size);
+ qh_fprintf(fp, 9307, " Number of non-redundant halfspaces: %d\n", numvertices);
+ if (numcoplanars) {
+ if (qh KEEPinside && qh KEEPcoplanar)
+ s= "similar and redundant";
+ else if (qh KEEPinside)
+ s= "redundant";
+ else
+ s= "similar";
+ qh_fprintf(fp, 9308, " Number of %s halfspaces: %d\n", s, numcoplanars);
+ }
+ qh_fprintf(fp, 9309, " Number of intersection points: %d\n", qh num_facets - qh num_visible);
+ if (goodused)
+ qh_fprintf(fp, 9310, " Number of 'good' intersection points: %d\n", qh num_good);
+ if (nonsimplicial)
+ qh_fprintf(fp, 9311, " Number of%s non-simplicial intersection points: %d\n",
+ goodused ? " 'good'" : "", nonsimplicial);
+ }else {
+ qh_fprintf(fp, 9312, "\n\
+Convex hull of %d points in %d-d:\n\n", size, qh hull_dim);
+ qh_fprintf(fp, 9313, " Number of vertices: %d\n", numvertices);
+ if (numcoplanars) {
+ if (qh KEEPinside && qh KEEPcoplanar)
+ s= "coplanar and interior";
+ else if (qh KEEPinside)
+ s= "interior";
+ else
+ s= "coplanar";
+ qh_fprintf(fp, 9314, " Number of %s points: %d\n", s, numcoplanars);
+ }
+ qh_fprintf(fp, 9315, " Number of facets: %d\n", qh num_facets - qh num_visible);
+ if (goodused)
+ qh_fprintf(fp, 9316, " Number of 'good' facets: %d\n", qh num_good);
+ if (nonsimplicial)
+ qh_fprintf(fp, 9317, " Number of%s non-simplicial facets: %d\n",
+ goodused ? " 'good'" : "", nonsimplicial);
+ }
+ if (numtricoplanars)
+ qh_fprintf(fp, 9318, " Number of triangulated facets: %d\n", numtricoplanars);
+ qh_fprintf(fp, 9319, "\nStatistics for: %s | %s",
+ qh rbox_command, qh qhull_command);
+ if (qh ROTATErandom != INT_MIN)
+ qh_fprintf(fp, 9320, " QR%d\n\n", qh ROTATErandom);
+ else
+ qh_fprintf(fp, 9321, "\n\n");
+ qh_fprintf(fp, 9322, " Number of points processed: %d\n", zzval_(Zprocessed));
+ qh_fprintf(fp, 9323, " Number of hyperplanes created: %d\n", zzval_(Zsetplane));
+ if (qh DELAUNAY)
+ qh_fprintf(fp, 9324, " Number of facets in hull: %d\n", qh num_facets - qh num_visible);
+ qh_fprintf(fp, 9325, " Number of distance tests for qhull: %d\n", zzval_(Zpartition)+
+ zzval_(Zpartitionall)+zzval_(Znumvisibility)+zzval_(Zpartcoplanar));
+#if 0 /* NOTE: must print before printstatistics() */
+ {realT stddev, ave;
+ qh_fprintf(fp, 9326, " average new facet balance: %2.2g\n",
+ wval_(Wnewbalance)/zval_(Zprocessed));
+ stddev= qh_stddev(zval_(Zprocessed), wval_(Wnewbalance),
+ wval_(Wnewbalance2), &ave);
+ qh_fprintf(fp, 9327, " new facet standard deviation: %2.2g\n", stddev);
+ qh_fprintf(fp, 9328, " average partition balance: %2.2g\n",
+ wval_(Wpbalance)/zval_(Zpbalance));
+ stddev= qh_stddev(zval_(Zpbalance), wval_(Wpbalance),
+ wval_(Wpbalance2), &ave);
+ qh_fprintf(fp, 9329, " partition standard deviation: %2.2g\n", stddev);
+ }
+#endif
+ if (nummerged) {
+ qh_fprintf(fp, 9330," Number of distance tests for merging: %d\n",zzval_(Zbestdist)+
+ zzval_(Zcentrumtests)+zzval_(Zdistconvex)+zzval_(Zdistcheck)+
+ zzval_(Zdistzero));
+ qh_fprintf(fp, 9331," Number of distance tests for checking: %d\n",zzval_(Zcheckpart));
+ qh_fprintf(fp, 9332," Number of merged facets: %d\n", nummerged);
+ }
+ if (!qh RANDOMoutside && qh QHULLfinished) {
+ cpu= (float)qh hulltime;
+ cpu /= (float)qh_SECticks;
+ wval_(Wcpu)= cpu;
+ qh_fprintf(fp, 9333, " CPU seconds to compute hull (after input): %2.4g\n", cpu);
+ }
+ if (qh RERUN) {
+ if (!qh PREmerge && !qh MERGEexact)
+ qh_fprintf(fp, 9334, " Percentage of runs with precision errors: %4.1f\n",
+ zzval_(Zretry)*100.0/qh build_cnt); /* careful of order */
+ }else if (qh JOGGLEmax < REALmax/2) {
+ if (zzval_(Zretry))
+ qh_fprintf(fp, 9335, " After %d retries, input joggled by: %2.2g\n",
+ zzval_(Zretry), qh JOGGLEmax);
+ else
+ qh_fprintf(fp, 9336, " Input joggled by: %2.2g\n", qh JOGGLEmax);
+ }
+ if (qh totarea != 0.0)
+ qh_fprintf(fp, 9337, " %s facet area: %2.8g\n",
+ zzval_(Ztotmerge) ? "Approximate" : "Total", qh totarea);
+ if (qh totvol != 0.0)
+ qh_fprintf(fp, 9338, " %s volume: %2.8g\n",
+ zzval_(Ztotmerge) ? "Approximate" : "Total", qh totvol);
+ if (qh MERGING) {
+ qh_outerinner(NULL, &outerplane, &innerplane);
+ if (outerplane > 2 * qh DISTround) {
+ qh_fprintf(fp, 9339, " Maximum distance of %spoint above facet: %2.2g",
+ (qh QHULLfinished ? "" : "merged "), outerplane);
+ ratio= outerplane/(qh ONEmerge + qh DISTround);
+ /* don't report ratio if MINoutside is large */
+ if (ratio > 0.05 && 2* qh ONEmerge > qh MINoutside && qh JOGGLEmax > REALmax/2)
+ qh_fprintf(fp, 9340, " (%.1fx)\n", ratio);
+ else
+ qh_fprintf(fp, 9341, "\n");
+ }
+ if (innerplane < -2 * qh DISTround) {
+ qh_fprintf(fp, 9342, " Maximum distance of %svertex below facet: %2.2g",
+ (qh QHULLfinished ? "" : "merged "), innerplane);
+ ratio= -innerplane/(qh ONEmerge+qh DISTround);
+ if (ratio > 0.05 && qh JOGGLEmax > REALmax/2)
+ qh_fprintf(fp, 9343, " (%.1fx)\n", ratio);
+ else
+ qh_fprintf(fp, 9344, "\n");
+ }
+ }
+ qh_fprintf(fp, 9345, "\n");
+} /* printsummary */
+
+
diff --git a/xs/src/qhull/src/libqhull/libqhull.h b/xs/src/qhull/src/libqhull/libqhull.h
new file mode 100644
index 000000000..677085808
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/libqhull.h
@@ -0,0 +1,1140 @@
+/*<html><pre> -<a href="qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ libqhull.h
+ user-level header file for using qhull.a library
+
+ see qh-qhull.htm, qhull_a.h
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/libqhull.h#7 $$Change: 2066 $
+ $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+
+ NOTE: access to qh_qh is via the 'qh' macro. This allows
+ qh_qh to be either a pointer or a structure. An example
+ of using qh is "qh.DROPdim" which accesses the DROPdim
+ field of qh_qh. Similarly, access to qh_qhstat is via
+ the 'qhstat' macro.
+
+ includes function prototypes for libqhull.c, geom.c, global.c, io.c, user.c
+
+ use mem.h for mem.c
+ use qset.h for qset.c
+
+ see unix.c for an example of using libqhull.h
+
+ recompile qhull if you change this file
+*/
+
+#ifndef qhDEFlibqhull
+#define qhDEFlibqhull 1
+
+/*=========================== -included files ==============*/
+
+/* user_r.h first for QHULL_CRTDBG */
+#include "user.h" /* user definable constants (e.g., qh_QHpointer) */
+
+#include "mem.h" /* Needed qhT in libqhull_r.h. Here for compatibility */
+#include "qset.h" /* Needed for QHULL_LIB_CHECK */
+/* include stat_r.h after defining boolT. Needed for qhT in libqhull_r.h. Here for compatibility and statT */
+
+#include <setjmp.h>
+#include <float.h>
+#include <time.h>
+#include <stdio.h>
+
+#if __MWERKS__ && __POWERPC__
+#include <SIOUX.h>
+#include <Files.h>
+#include <Desk.h>
+#endif
+
+#ifndef __STDC__
+#ifndef __cplusplus
+#if !_MSC_VER
+#error Neither __STDC__ nor __cplusplus is defined. Please use strict ANSI C or C++ to compile
+#error Qhull. You may need to turn off compiler extensions in your project configuration. If
+#error your compiler is a standard C compiler, you can delete this warning from libqhull.h
+#endif
+#endif
+#endif
+
+/*============ constants and basic types ====================*/
+
+extern const char qh_version[]; /* defined in global.c */
+extern const char qh_version2[]; /* defined in global.c */
+
+/*-<a href="qh-geom.htm#TOC"
+ >--------------------------------</a><a name="coordT">-</a>
+
+ coordT
+ coordinates and coefficients are stored as realT (i.e., double)
+
+ notes:
+ Qhull works well if realT is 'float'. If so joggle (QJ) is not effective.
+
+ Could use 'float' for data and 'double' for calculations (realT vs. coordT)
+ This requires many type casts, and adjusted error bounds.
+ Also C compilers may do expressions in double anyway.
+*/
+#define coordT realT
+
+/*-<a href="qh-geom.htm#TOC"
+ >--------------------------------</a><a name="pointT">-</a>
+
+ pointT
+ a point is an array of coordinates, usually qh.hull_dim
+ qh_pointid returns
+ qh_IDnone if point==0 or qh is undefined
+ qh_IDinterior for qh.interior_point
+ qh_IDunknown if point is neither in qh.first_point... nor qh.other_points
+
+ notes:
+ qh.STOPcone and qh.STOPpoint assume that qh_IDunknown==-1 (other negative numbers indicate points)
+ qh_IDunknown is also returned by getid_() for unknown facet, ridge, or vertex
+*/
+#define pointT coordT
+typedef enum
+{
+ qh_IDnone = -3, qh_IDinterior = -2, qh_IDunknown = -1
+}
+qh_pointT;
+
+/*-<a href="qh-qhull.htm#TOC"
+ >--------------------------------</a><a name="flagT">-</a>
+
+ flagT
+ Boolean flag as a bit
+*/
+#define flagT unsigned int
+
+/*-<a href="qh-qhull.htm#TOC"
+ >--------------------------------</a><a name="boolT">-</a>
+
+ boolT
+ boolean value, either True or False
+
+ notes:
+ needed for portability
+ Use qh_False/qh_True as synonyms
+*/
+#define boolT unsigned int
+#ifdef False
+#undef False
+#endif
+#ifdef True
+#undef True
+#endif
+#define False 0
+#define True 1
+#define qh_False 0
+#define qh_True 1
+
+#include "stat.h" /* after define of boolT */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >--------------------------------</a><a name="CENTERtype">-</a>
+
+ qh_CENTER
+ to distinguish facet->center
+*/
+typedef enum
+{
+ qh_ASnone = 0, /* If not MERGING and not VORONOI */
+ qh_ASvoronoi, /* Set by qh_clearcenters on qh_prepare_output, or if not MERGING and VORONOI */
+ qh_AScentrum /* If MERGING (assumed during merging) */
+}
+qh_CENTER;
+
+/*-<a href="qh-qhull.htm#TOC"
+ >--------------------------------</a><a name="qh_PRINT">-</a>
+
+ qh_PRINT
+ output formats for printing (qh.PRINTout).
+ 'Fa' 'FV' 'Fc' 'FC'
+
+
+ notes:
+ some of these names are similar to qhT names. The similar names are only
+ used in switch statements in qh_printbegin() etc.
+*/
+typedef enum {qh_PRINTnone= 0,
+ qh_PRINTarea, qh_PRINTaverage, /* 'Fa' 'FV' 'Fc' 'FC' */
+ qh_PRINTcoplanars, qh_PRINTcentrums,
+ qh_PRINTfacets, qh_PRINTfacets_xridge, /* 'f' 'FF' 'G' 'FI' 'Fi' 'Fn' */
+ qh_PRINTgeom, qh_PRINTids, qh_PRINTinner, qh_PRINTneighbors,
+ qh_PRINTnormals, qh_PRINTouter, qh_PRINTmaple, /* 'n' 'Fo' 'i' 'm' 'Fm' 'FM', 'o' */
+ qh_PRINTincidences, qh_PRINTmathematica, qh_PRINTmerges, qh_PRINToff,
+ qh_PRINToptions, qh_PRINTpointintersect, /* 'FO' 'Fp' 'FP' 'p' 'FQ' 'FS' */
+ qh_PRINTpointnearest, qh_PRINTpoints, qh_PRINTqhull, qh_PRINTsize,
+ qh_PRINTsummary, qh_PRINTtriangles, /* 'Fs' 'Ft' 'Fv' 'FN' 'Fx' */
+ qh_PRINTvertices, qh_PRINTvneighbors, qh_PRINTextremes,
+ qh_PRINTEND} qh_PRINT;
+
+/*-<a href="qh-qhull.htm#TOC"
+ >--------------------------------</a><a name="qh_ALL">-</a>
+
+ qh_ALL
+ argument flag for selecting everything
+*/
+#define qh_ALL True
+#define qh_NOupper True /* argument for qh_findbest */
+#define qh_IScheckmax True /* argument for qh_findbesthorizon */
+#define qh_ISnewfacets True /* argument for qh_findbest */
+#define qh_RESETvisible True /* argument for qh_resetlists */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >--------------------------------</a><a name="qh_ERR">-</a>
+
+ qh_ERR
+ Qhull exit codes, for indicating errors
+ See: MSG_ERROR and MSG_WARNING [user.h]
+*/
+#define qh_ERRnone 0 /* no error occurred during qhull */
+#define qh_ERRinput 1 /* input inconsistency */
+#define qh_ERRsingular 2 /* singular input data */
+#define qh_ERRprec 3 /* precision error */
+#define qh_ERRmem 4 /* insufficient memory, matches mem.h */
+#define qh_ERRqhull 5 /* internal error detected, matches mem.h */
+
+/*-<a href="qh-qhull.htm#TOC"
+>--------------------------------</a><a name="qh_FILEstderr">-</a>
+
+qh_FILEstderr
+Fake stderr to distinguish error output from normal output
+For C++ interface. Must redefine qh_fprintf_qhull
+*/
+#define qh_FILEstderr ((FILE*)1)
+
+/* ============ -structures- ====================
+ each of the following structures is defined by a typedef
+ all realT and coordT fields occur at the beginning of a structure
+ (otherwise space may be wasted due to alignment)
+ define all flags together and pack into 32-bit number
+ DEFsetT is likewise defined in
+ mem.h and qset.h
+*/
+
+typedef struct vertexT vertexT;
+typedef struct ridgeT ridgeT;
+typedef struct facetT facetT;
+#ifndef DEFsetT
+#define DEFsetT 1
+typedef struct setT setT; /* defined in qset.h */
+#endif
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="facetT">-</a>
+
+ facetT
+ defines a facet
+
+ notes:
+ qhull() generates the hull as a list of facets.
+
+ topological information:
+ f.previous,next doubly-linked list of facets
+ f.vertices set of vertices
+ f.ridges set of ridges
+ f.neighbors set of neighbors
+ f.toporient True if facet has top-orientation (else bottom)
+
+ geometric information:
+ f.offset,normal hyperplane equation
+ f.maxoutside offset to outer plane -- all points inside
+ f.center centrum for testing convexity
+ f.simplicial True if facet is simplicial
+ f.flipped True if facet does not include qh.interior_point
+
+ for constructing hull:
+ f.visible True if facet on list of visible facets (will be deleted)
+ f.newfacet True if facet on list of newly created facets
+ f.coplanarset set of points coplanar with this facet
+ (includes near-inside points for later testing)
+ f.outsideset set of points outside of this facet
+ f.furthestdist distance to furthest point of outside set
+ f.visitid marks visited facets during a loop
+ f.replace replacement facet for to-be-deleted, visible facets
+ f.samecycle,newcycle cycle of facets for merging into horizon facet
+
+ see below for other flags and fields
+*/
+struct facetT {
+#if !qh_COMPUTEfurthest
+ coordT furthestdist;/* distance to furthest point of outsideset */
+#endif
+#if qh_MAXoutside
+ coordT maxoutside; /* max computed distance of point to facet
+ Before QHULLfinished this is an approximation
+ since maxdist not always set for mergefacet
+ Actual outer plane is +DISTround and
+ computed outer plane is +2*DISTround */
+#endif
+ coordT offset; /* exact offset of hyperplane from origin */
+ coordT *normal; /* normal of hyperplane, hull_dim coefficients */
+ /* if tricoplanar, shared with a neighbor */
+ union { /* in order of testing */
+ realT area; /* area of facet, only in io.c if ->isarea */
+ facetT *replace; /* replacement facet if ->visible and NEWfacets
+ is NULL only if qh_mergedegen_redundant or interior */
+ facetT *samecycle; /* cycle of facets from the same visible/horizon intersection,
+ if ->newfacet */
+ facetT *newcycle; /* in horizon facet, current samecycle of new facets */
+ facetT *trivisible; /* visible facet for ->tricoplanar facets during qh_triangulate() */
+ facetT *triowner; /* owner facet for ->tricoplanar, !isarea facets w/ ->keepcentrum */
+ }f;
+ coordT *center; /* set according to qh.CENTERtype */
+ /* qh_ASnone: no center (not MERGING) */
+ /* qh_AScentrum: centrum for testing convexity (qh_getcentrum) */
+ /* assumed qh_AScentrum while merging */
+ /* qh_ASvoronoi: Voronoi center (qh_facetcenter) */
+ /* after constructing the hull, it may be changed (qh_clearcenter) */
+ /* if tricoplanar and !keepcentrum, shared with a neighbor */
+ facetT *previous; /* previous facet in the facet_list */
+ facetT *next; /* next facet in the facet_list */
+ setT *vertices; /* vertices for this facet, inverse sorted by ID
+ if simplicial, 1st vertex was apex/furthest */
+ setT *ridges; /* explicit ridges for nonsimplicial facets.
+ for simplicial facets, neighbors define the ridges */
+ setT *neighbors; /* neighbors of the facet. If simplicial, the kth
+ neighbor is opposite the kth vertex, and the first
+ neighbor is the horizon facet for the first vertex*/
+ setT *outsideset; /* set of points outside this facet
+ if non-empty, last point is furthest
+ if NARROWhull, includes coplanars for partitioning*/
+ setT *coplanarset; /* set of points coplanar with this facet
+ > qh.min_vertex and <= facet->max_outside
+ a point is assigned to the furthest facet
+ if non-empty, last point is furthest away */
+ unsigned visitid; /* visit_id, for visiting all neighbors,
+ all uses are independent */
+ unsigned id; /* unique identifier from qh.facet_id */
+ unsigned nummerge:9; /* number of merges */
+#define qh_MAXnummerge 511 /* 2^9-1, 32 flags total, see "flags:" in io.c */
+ flagT tricoplanar:1; /* True if TRIangulate and simplicial and coplanar with a neighbor */
+ /* all tricoplanars share the same apex */
+ /* all tricoplanars share the same ->center, ->normal, ->offset, ->maxoutside */
+ /* ->keepcentrum is true for the owner. It has the ->coplanareset */
+ /* if ->degenerate, does not span facet (one logical ridge) */
+ /* during qh_triangulate, f.trivisible points to original facet */
+ flagT newfacet:1; /* True if facet on qh.newfacet_list (new or merged) */
+ flagT visible:1; /* True if visible facet (will be deleted) */
+ flagT toporient:1; /* True if created with top orientation
+ after merging, use ridge orientation */
+ flagT simplicial:1;/* True if simplicial facet, ->ridges may be implicit */
+ flagT seen:1; /* used to perform operations only once, like visitid */
+ flagT seen2:1; /* used to perform operations only once, like visitid */
+ flagT flipped:1; /* True if facet is flipped */
+ flagT upperdelaunay:1; /* True if facet is upper envelope of Delaunay triangulation */
+ flagT notfurthest:1; /* True if last point of outsideset is not furthest*/
+
+/*-------- flags primarily for output ---------*/
+ flagT good:1; /* True if a facet marked good for output */
+ flagT isarea:1; /* True if facet->f.area is defined */
+
+/*-------- flags for merging ------------------*/
+ flagT dupridge:1; /* True if duplicate ridge in facet */
+ flagT mergeridge:1; /* True if facet or neighbor contains a qh_MERGEridge
+ ->normal defined (also defined for mergeridge2) */
+ flagT mergeridge2:1; /* True if neighbor contains a qh_MERGEridge (mark_dupridges */
+ flagT coplanar:1; /* True if horizon facet is coplanar at last use */
+ flagT mergehorizon:1; /* True if will merge into horizon (->coplanar) */
+ flagT cycledone:1;/* True if mergecycle_all already done */
+ flagT tested:1; /* True if facet convexity has been tested (false after merge */
+ flagT keepcentrum:1; /* True if keep old centrum after a merge, or marks owner for ->tricoplanar */
+ flagT newmerge:1; /* True if facet is newly merged for reducevertices */
+ flagT degenerate:1; /* True if facet is degenerate (degen_mergeset or ->tricoplanar) */
+ flagT redundant:1; /* True if facet is redundant (degen_mergeset) */
+};
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="ridgeT">-</a>
+
+ ridgeT
+ defines a ridge
+
+ notes:
+ a ridge is hull_dim-1 simplex between two neighboring facets. If the
+ facets are non-simplicial, there may be more than one ridge between
+ two facets. E.G. a 4-d hypercube has two triangles between each pair
+ of neighboring facets.
+
+ topological information:
+ vertices a set of vertices
+ top,bottom neighboring facets with orientation
+
+ geometric information:
+ tested True if ridge is clearly convex
+ nonconvex True if ridge is non-convex
+*/
+struct ridgeT {
+ setT *vertices; /* vertices belonging to this ridge, inverse sorted by ID
+ NULL if a degen ridge (matchsame) */
+ facetT *top; /* top facet this ridge is part of */
+ facetT *bottom; /* bottom facet this ridge is part of */
+ unsigned id; /* unique identifier. Same size as vertex_id and ridge_id */
+ flagT seen:1; /* used to perform operations only once */
+ flagT tested:1; /* True when ridge is tested for convexity */
+ flagT nonconvex:1; /* True if getmergeset detected a non-convex neighbor
+ only one ridge between neighbors may have nonconvex */
+};
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="vertexT">-</a>
+
+ vertexT
+ defines a vertex
+
+ topological information:
+ next,previous doubly-linked list of all vertices
+ neighbors set of adjacent facets (only if qh.VERTEXneighbors)
+
+ geometric information:
+ point array of DIM3 coordinates
+*/
+struct vertexT {
+ vertexT *next; /* next vertex in vertex_list */
+ vertexT *previous; /* previous vertex in vertex_list */
+ pointT *point; /* hull_dim coordinates (coordT) */
+ setT *neighbors; /* neighboring facets of vertex, qh_vertexneighbors()
+ inits in io.c or after first merge */
+ unsigned id; /* unique identifier. Same size as qh.vertex_id and qh.ridge_id */
+ unsigned visitid; /* for use with qh.vertex_visit, size must match */
+ flagT seen:1; /* used to perform operations only once */
+ flagT seen2:1; /* another seen flag */
+ flagT delridge:1; /* vertex was part of a deleted ridge */
+ flagT deleted:1; /* true if vertex on qh.del_vertices */
+ flagT newlist:1; /* true if vertex on qh.newvertex_list */
+};
+
+/*======= -global variables -qh ============================*/
+
+/*-<a href="qh-globa.htm#TOC"
+ >--------------------------------</a><a name="qh">-</a>
+
+ qh
+ all global variables for qhull are in qh, qhmem, and qhstat
+
+ notes:
+ qhmem is defined in mem.h, qhstat is defined in stat.h, qhrbox is defined in rboxpoints.h
+ Access to qh_qh is via the "qh" macro. See qh_QHpointer in user.h
+
+ All global variables for qhull are in qh, qhmem, and qhstat
+ qh must be unique for each instance of qhull
+ qhstat may be shared between qhull instances.
+ qhmem may be shared across multiple instances of Qhull.
+ Rbox uses global variables rbox_inuse and rbox, but does not persist data across calls.
+
+ Qhull is not multi-threaded. Global state could be stored in thread-local storage.
+
+ QHULL_LIB_CHECK checks that a program and the corresponding
+ qhull library were built with the same type of header files.
+*/
+
+typedef struct qhT qhT;
+
+#define QHULL_NON_REENTRANT 0
+#define QHULL_QH_POINTER 1
+#define QHULL_REENTRANT 2
+
+#if qh_QHpointer_dllimport
+#define qh qh_qh->
+__declspec(dllimport) extern qhT *qh_qh; /* allocated in global.c */
+#define QHULL_LIB_TYPE QHULL_QH_POINTER
+
+#elif qh_QHpointer
+#define qh qh_qh->
+extern qhT *qh_qh; /* allocated in global.c */
+#define QHULL_LIB_TYPE QHULL_QH_POINTER
+
+#elif qh_dllimport
+#define qh qh_qh.
+__declspec(dllimport) extern qhT qh_qh; /* allocated in global.c */
+#define QHULL_LIB_TYPE QHULL_NON_REENTRANT
+
+#else
+#define qh qh_qh.
+extern qhT qh_qh;
+#define QHULL_LIB_TYPE QHULL_NON_REENTRANT
+#endif
+
+#define QHULL_LIB_CHECK qh_lib_check(QHULL_LIB_TYPE, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), sizeof(setT), sizeof(qhmemT));
+#define QHULL_LIB_CHECK_RBOX qh_lib_check(QHULL_LIB_TYPE, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), 0, 0);
+
+struct qhT {
+
+/*-<a href="qh-globa.htm#TOC"
+ >--------------------------------</a><a name="qh-const">-</a>
+
+ qh constants
+ configuration flags and constants for Qhull
+
+ notes:
+ The user configures Qhull by defining flags. They are
+ copied into qh by qh_setflags(). qh-quick.htm#options defines the flags.
+*/
+ boolT ALLpoints; /* true 'Qs' if search all points for initial simplex */
+ boolT ANGLEmerge; /* true 'Qa' if sort potential merges by angle */
+ boolT APPROXhull; /* true 'Wn' if MINoutside set */
+ realT MINoutside; /* 'Wn' min. distance for an outside point */
+ boolT ANNOTATEoutput; /* true 'Ta' if annotate output with message codes */
+ boolT ATinfinity; /* true 'Qz' if point num_points-1 is "at-infinity"
+ for improving precision in Delaunay triangulations */
+ boolT AVOIDold; /* true 'Q4' if avoid old->new merges */
+ boolT BESToutside; /* true 'Qf' if partition points into best outsideset */
+ boolT CDDinput; /* true 'Pc' if input uses CDD format (1.0/offset first) */
+ boolT CDDoutput; /* true 'PC' if print normals in CDD format (offset first) */
+ boolT CHECKfrequently; /* true 'Tc' if checking frequently */
+ realT premerge_cos; /* 'A-n' cos_max when pre merging */
+ realT postmerge_cos; /* 'An' cos_max when post merging */
+ boolT DELAUNAY; /* true 'd' if computing DELAUNAY triangulation */
+ boolT DOintersections; /* true 'Gh' if print hyperplane intersections */
+ int DROPdim; /* drops dim 'GDn' for 4-d -> 3-d output */
+ boolT FORCEoutput; /* true 'Po' if forcing output despite degeneracies */
+ int GOODpoint; /* 1+n for 'QGn', good facet if visible/not(-) from point n*/
+ pointT *GOODpointp; /* the actual point */
+ boolT GOODthreshold; /* true if qh.lower_threshold/upper_threshold defined
+ false if qh.SPLITthreshold */
+ int GOODvertex; /* 1+n, good facet if vertex for point n */
+ pointT *GOODvertexp; /* the actual point */
+ boolT HALFspace; /* true 'Hn,n,n' if halfspace intersection */
+ boolT ISqhullQh; /* Set by Qhull.cpp on initialization */
+ int IStracing; /* trace execution, 0=none, 1=least, 4=most, -1=events */
+ int KEEParea; /* 'PAn' number of largest facets to keep */
+ boolT KEEPcoplanar; /* true 'Qc' if keeping nearest facet for coplanar points */
+ boolT KEEPinside; /* true 'Qi' if keeping nearest facet for inside points
+ set automatically if 'd Qc' */
+ int KEEPmerge; /* 'PMn' number of facets to keep with most merges */
+ realT KEEPminArea; /* 'PFn' minimum facet area to keep */
+ realT MAXcoplanar; /* 'Un' max distance below a facet to be coplanar*/
+ boolT MERGEexact; /* true 'Qx' if exact merges (coplanar, degen, dupridge, flipped) */
+ boolT MERGEindependent; /* true 'Q2' if merging independent sets */
+ boolT MERGING; /* true if exact-, pre- or post-merging, with angle and centrum tests */
+ realT premerge_centrum; /* 'C-n' centrum_radius when pre merging. Default is round-off */
+ realT postmerge_centrum; /* 'Cn' centrum_radius when post merging. Default is round-off */
+ boolT MERGEvertices; /* true 'Q3' if merging redundant vertices */
+ realT MINvisible; /* 'Vn' min. distance for a facet to be visible */
+ boolT NOnarrow; /* true 'Q10' if no special processing for narrow distributions */
+ boolT NOnearinside; /* true 'Q8' if ignore near-inside points when partitioning */
+ boolT NOpremerge; /* true 'Q0' if no defaults for C-0 or Qx */
+ boolT NOwide; /* true 'Q12' if no error on wide merge due to duplicate ridge */
+ boolT ONLYgood; /* true 'Qg' if process points with good visible or horizon facets */
+ boolT ONLYmax; /* true 'Qm' if only process points that increase max_outside */
+ boolT PICKfurthest; /* true 'Q9' if process furthest of furthest points*/
+ boolT POSTmerge; /* true if merging after buildhull (Cn or An) */
+ boolT PREmerge; /* true if merging during buildhull (C-n or A-n) */
+ /* NOTE: some of these names are similar to qh_PRINT names */
+ boolT PRINTcentrums; /* true 'Gc' if printing centrums */
+ boolT PRINTcoplanar; /* true 'Gp' if printing coplanar points */
+ int PRINTdim; /* print dimension for Geomview output */
+ boolT PRINTdots; /* true 'Ga' if printing all points as dots */
+ boolT PRINTgood; /* true 'Pg' if printing good facets */
+ boolT PRINTinner; /* true 'Gi' if printing inner planes */
+ boolT PRINTneighbors; /* true 'PG' if printing neighbors of good facets */
+ boolT PRINTnoplanes; /* true 'Gn' if printing no planes */
+ boolT PRINToptions1st; /* true 'FO' if printing options to stderr */
+ boolT PRINTouter; /* true 'Go' if printing outer planes */
+ boolT PRINTprecision; /* false 'Pp' if not reporting precision problems */
+ qh_PRINT PRINTout[qh_PRINTEND]; /* list of output formats to print */
+ boolT PRINTridges; /* true 'Gr' if print ridges */
+ boolT PRINTspheres; /* true 'Gv' if print vertices as spheres */
+ boolT PRINTstatistics; /* true 'Ts' if printing statistics to stderr */
+ boolT PRINTsummary; /* true 's' if printing summary to stderr */
+ boolT PRINTtransparent; /* true 'Gt' if print transparent outer ridges */
+ boolT PROJECTdelaunay; /* true if DELAUNAY, no readpoints() and
+ need projectinput() for Delaunay in qh_init_B */
+ int PROJECTinput; /* number of projected dimensions 'bn:0Bn:0' */
+ boolT QUICKhelp; /* true if quick help message for degen input */
+ boolT RANDOMdist; /* true if randomly change distplane and setfacetplane */
+ realT RANDOMfactor; /* maximum random perturbation */
+ realT RANDOMa; /* qh_randomfactor is randr * RANDOMa + RANDOMb */
+ realT RANDOMb;
+ boolT RANDOMoutside; /* true if select a random outside point */
+ int REPORTfreq; /* buildtracing reports every n facets */
+ int REPORTfreq2; /* tracemerging reports every REPORTfreq/2 facets */
+ int RERUN; /* 'TRn' rerun qhull n times (qh.build_cnt) */
+ int ROTATErandom; /* 'QRn' seed, 0 time, >= rotate input */
+ boolT SCALEinput; /* true 'Qbk' if scaling input */
+ boolT SCALElast; /* true 'Qbb' if scale last coord to max prev coord */
+ boolT SETroundoff; /* true 'E' if qh.DISTround is predefined */
+ boolT SKIPcheckmax; /* true 'Q5' if skip qh_check_maxout */
+ boolT SKIPconvex; /* true 'Q6' if skip convexity testing during pre-merge */
+ boolT SPLITthresholds; /* true if upper_/lower_threshold defines a region
+ used only for printing (!for qh.ONLYgood) */
+ int STOPcone; /* 'TCn' 1+n for stopping after cone for point n */
+ /* also used by qh_build_withresart for err exit*/
+ int STOPpoint; /* 'TVn' 'TV-n' 1+n for stopping after/before(-)
+ adding point n */
+ int TESTpoints; /* 'QTn' num of test points after qh.num_points. Test points always coplanar. */
+ boolT TESTvneighbors; /* true 'Qv' if test vertex neighbors at end */
+ int TRACElevel; /* 'Tn' conditional IStracing level */
+ int TRACElastrun; /* qh.TRACElevel applies to last qh.RERUN */
+ int TRACEpoint; /* 'TPn' start tracing when point n is a vertex */
+ realT TRACEdist; /* 'TWn' start tracing when merge distance too big */
+ int TRACEmerge; /* 'TMn' start tracing before this merge */
+ boolT TRIangulate; /* true 'Qt' if triangulate non-simplicial facets */
+ boolT TRInormals; /* true 'Q11' if triangulate duplicates ->normal and ->center (sets Qt) */
+ boolT UPPERdelaunay; /* true 'Qu' if computing furthest-site Delaunay */
+ boolT USEstdout; /* true 'Tz' if using stdout instead of stderr */
+ boolT VERIFYoutput; /* true 'Tv' if verify output at end of qhull */
+ boolT VIRTUALmemory; /* true 'Q7' if depth-first processing in buildhull */
+ boolT VORONOI; /* true 'v' if computing Voronoi diagram */
+
+ /*--------input constants ---------*/
+ realT AREAfactor; /* 1/(hull_dim-1)! for converting det's to area */
+ boolT DOcheckmax; /* true if calling qh_check_maxout (qh_initqhull_globals) */
+ char *feasible_string; /* feasible point 'Hn,n,n' for halfspace intersection */
+ coordT *feasible_point; /* as coordinates, both malloc'd */
+ boolT GETarea; /* true 'Fa', 'FA', 'FS', 'PAn', 'PFn' if compute facet area/Voronoi volume in io.c */
+ boolT KEEPnearinside; /* true if near-inside points in coplanarset */
+ int hull_dim; /* dimension of hull, set by initbuffers */
+ int input_dim; /* dimension of input, set by initbuffers */
+ int num_points; /* number of input points */
+ pointT *first_point; /* array of input points, see POINTSmalloc */
+ boolT POINTSmalloc; /* true if qh.first_point/num_points allocated */
+ pointT *input_points; /* copy of original qh.first_point for input points for qh_joggleinput */
+ boolT input_malloc; /* true if qh.input_points malloc'd */
+ char qhull_command[256];/* command line that invoked this program */
+ int qhull_commandsiz2; /* size of qhull_command at qh_clear_outputflags */
+ char rbox_command[256]; /* command line that produced the input points */
+ char qhull_options[512];/* descriptive list of options */
+ int qhull_optionlen; /* length of last line */
+ int qhull_optionsiz; /* size of qhull_options at qh_build_withrestart */
+ int qhull_optionsiz2; /* size of qhull_options at qh_clear_outputflags */
+ int run_id; /* non-zero, random identifier for this instance of qhull */
+ boolT VERTEXneighbors; /* true if maintaining vertex neighbors */
+ boolT ZEROcentrum; /* true if 'C-0' or 'C-0 Qx'. sets ZEROall_ok */
+ realT *upper_threshold; /* don't print if facet->normal[k]>=upper_threshold[k]
+ must set either GOODthreshold or SPLITthreshold
+ if Delaunay, default is 0.0 for upper envelope */
+ realT *lower_threshold; /* don't print if facet->normal[k] <=lower_threshold[k] */
+ realT *upper_bound; /* scale point[k] to new upper bound */
+ realT *lower_bound; /* scale point[k] to new lower bound
+ project if both upper_ and lower_bound == 0 */
+
+/*-<a href="qh-globa.htm#TOC"
+ >--------------------------------</a><a name="qh-prec">-</a>
+
+ qh precision constants
+ precision constants for Qhull
+
+ notes:
+ qh_detroundoff() computes the maximum roundoff error for distance
+ and other computations. It also sets default values for the
+ qh constants above.
+*/
+ realT ANGLEround; /* max round off error for angles */
+ realT centrum_radius; /* max centrum radius for convexity (roundoff added) */
+ realT cos_max; /* max cosine for convexity (roundoff added) */
+ realT DISTround; /* max round off error for distances, 'E' overrides qh_distround() */
+ realT MAXabs_coord; /* max absolute coordinate */
+ realT MAXlastcoord; /* max last coordinate for qh_scalelast */
+ realT MAXsumcoord; /* max sum of coordinates */
+ realT MAXwidth; /* max rectilinear width of point coordinates */
+ realT MINdenom_1; /* min. abs. value for 1/x */
+ realT MINdenom; /* use divzero if denominator < MINdenom */
+ realT MINdenom_1_2; /* min. abs. val for 1/x that allows normalization */
+ realT MINdenom_2; /* use divzero if denominator < MINdenom_2 */
+ realT MINlastcoord; /* min. last coordinate for qh_scalelast */
+ boolT NARROWhull; /* set in qh_initialhull if angle < qh_MAXnarrow */
+ realT *NEARzero; /* hull_dim array for near zero in gausselim */
+ realT NEARinside; /* keep points for qh_check_maxout if close to facet */
+ realT ONEmerge; /* max distance for merging simplicial facets */
+ realT outside_err; /* application's epsilon for coplanar points
+ qh_check_bestdist() qh_check_points() reports error if point outside */
+ realT WIDEfacet; /* size of wide facet for skipping ridge in
+ area computation and locking centrum */
+
+/*-<a href="qh-globa.htm#TOC"
+ >--------------------------------</a><a name="qh-codetern">-</a>
+
+ qh internal constants
+ internal constants for Qhull
+*/
+ char qhull[sizeof("qhull")]; /* "qhull" for checking ownership while debugging */
+ jmp_buf errexit; /* exit label for qh_errexit, defined by setjmp() and NOerrexit */
+ char jmpXtra[40]; /* extra bytes in case jmp_buf is defined wrong by compiler */
+ jmp_buf restartexit; /* restart label for qh_errexit, defined by setjmp() and ALLOWrestart */
+ char jmpXtra2[40]; /* extra bytes in case jmp_buf is defined wrong by compiler*/
+ FILE *fin; /* pointer to input file, init by qh_initqhull_start2 */
+ FILE *fout; /* pointer to output file */
+ FILE *ferr; /* pointer to error file */
+ pointT *interior_point; /* center point of the initial simplex*/
+ int normal_size; /* size in bytes for facet normals and point coords*/
+ int center_size; /* size in bytes for Voronoi centers */
+ int TEMPsize; /* size for small, temporary sets (in quick mem) */
+
+/*-<a href="qh-globa.htm#TOC"
+ >--------------------------------</a><a name="qh-lists">-</a>
+
+ qh facet and vertex lists
+ defines lists of facets, new facets, visible facets, vertices, and
+ new vertices. Includes counts, next ids, and trace ids.
+ see:
+ qh_resetlists()
+*/
+ facetT *facet_list; /* first facet */
+ facetT *facet_tail; /* end of facet_list (dummy facet) */
+ facetT *facet_next; /* next facet for buildhull()
+ previous facets do not have outside sets
+ NARROWhull: previous facets may have coplanar outside sets for qh_outcoplanar */
+ facetT *newfacet_list; /* list of new facets to end of facet_list */
+ facetT *visible_list; /* list of visible facets preceding newfacet_list,
+ facet->visible set */
+ int num_visible; /* current number of visible facets */
+ unsigned tracefacet_id; /* set at init, then can print whenever */
+ facetT *tracefacet; /* set in newfacet/mergefacet, undone in delfacet*/
+ unsigned tracevertex_id; /* set at buildtracing, can print whenever */
+ vertexT *tracevertex; /* set in newvertex, undone in delvertex*/
+ vertexT *vertex_list; /* list of all vertices, to vertex_tail */
+ vertexT *vertex_tail; /* end of vertex_list (dummy vertex) */
+ vertexT *newvertex_list; /* list of vertices in newfacet_list, to vertex_tail
+ all vertices have 'newlist' set */
+ int num_facets; /* number of facets in facet_list
+ includes visible faces (num_visible) */
+ int num_vertices; /* number of vertices in facet_list */
+ int num_outside; /* number of points in outsidesets (for tracing and RANDOMoutside)
+ includes coplanar outsideset points for NARROWhull/qh_outcoplanar() */
+ int num_good; /* number of good facets (after findgood_all) */
+ unsigned facet_id; /* ID of next, new facet from newfacet() */
+ unsigned ridge_id; /* ID of next, new ridge from newridge() */
+ unsigned vertex_id; /* ID of next, new vertex from newvertex() */
+
+/*-<a href="qh-globa.htm#TOC"
+ >--------------------------------</a><a name="qh-var">-</a>
+
+ qh global variables
+ defines minimum and maximum distances, next visit ids, several flags,
+ and other global variables.
+ initialize in qh_initbuild or qh_maxmin if used in qh_buildhull
+*/
+ unsigned long hulltime; /* ignore time to set up input and randomize */
+ /* use unsigned to avoid wrap-around errors */
+ boolT ALLOWrestart; /* true if qh_precision can use qh.restartexit */
+ int build_cnt; /* number of calls to qh_initbuild */
+ qh_CENTER CENTERtype; /* current type of facet->center, qh_CENTER */
+ int furthest_id; /* pointid of furthest point, for tracing */
+ facetT *GOODclosest; /* closest facet to GOODthreshold in qh_findgood */
+ boolT hasAreaVolume; /* true if totarea, totvol was defined by qh_getarea */
+ boolT hasTriangulation; /* true if triangulation created by qh_triangulate */
+ realT JOGGLEmax; /* set 'QJn' if randomly joggle input */
+ boolT maxoutdone; /* set qh_check_maxout(), cleared by qh_addpoint() */
+ realT max_outside; /* maximum distance from a point to a facet,
+ before roundoff, not simplicial vertices
+ actual outer plane is +DISTround and
+ computed outer plane is +2*DISTround */
+ realT max_vertex; /* maximum distance (>0) from vertex to a facet,
+ before roundoff, due to a merge */
+ realT min_vertex; /* minimum distance (<0) from vertex to a facet,
+ before roundoff, due to a merge
+ if qh.JOGGLEmax, qh_makenewplanes sets it
+ recomputed if qh.DOcheckmax, default -qh.DISTround */
+ boolT NEWfacets; /* true while visible facets invalid due to new or merge
+ from makecone/attachnewfacets to deletevisible */
+ boolT findbestnew; /* true if partitioning calls qh_findbestnew */
+ boolT findbest_notsharp; /* true if new facets are at least 90 degrees */
+ boolT NOerrexit; /* true if qh.errexit is not available, cleared after setjmp */
+ realT PRINTcradius; /* radius for printing centrums */
+ realT PRINTradius; /* radius for printing vertex spheres and points */
+ boolT POSTmerging; /* true when post merging */
+ int printoutvar; /* temporary variable for qh_printbegin, etc. */
+ int printoutnum; /* number of facets printed */
+ boolT QHULLfinished; /* True after qhull() is finished */
+ realT totarea; /* 'FA': total facet area computed by qh_getarea, hasAreaVolume */
+ realT totvol; /* 'FA': total volume computed by qh_getarea, hasAreaVolume */
+ unsigned int visit_id; /* unique ID for searching neighborhoods, */
+ unsigned int vertex_visit; /* unique ID for searching vertices, reset with qh_buildtracing */
+ boolT ZEROall_ok; /* True if qh_checkzero always succeeds */
+ boolT WAScoplanar; /* True if qh_partitioncoplanar (qh_check_maxout) */
+
+/*-<a href="qh-globa.htm#TOC"
+ >--------------------------------</a><a name="qh-set">-</a>
+
+ qh global sets
+ defines sets for merging, initial simplex, hashing, extra input points,
+ and deleted vertices
+*/
+ setT *facet_mergeset; /* temporary set of merges to be done */
+ setT *degen_mergeset; /* temporary set of degenerate and redundant merges */
+ setT *hash_table; /* hash table for matching ridges in qh_matchfacets
+ size is setsize() */
+ setT *other_points; /* additional points */
+ setT *del_vertices; /* vertices to partition and delete with visible
+ facets. Have deleted set for checkfacet */
+
+/*-<a href="qh-globa.htm#TOC"
+ >--------------------------------</a><a name="qh-buf">-</a>
+
+ qh global buffers
+ defines buffers for maxtrix operations, input, and error messages
+*/
+ coordT *gm_matrix; /* (dim+1)Xdim matrix for geom.c */
+ coordT **gm_row; /* array of gm_matrix rows */
+ char* line; /* malloc'd input line of maxline+1 chars */
+ int maxline;
+ coordT *half_space; /* malloc'd input array for halfspace (qh normal_size+coordT) */
+ coordT *temp_malloc; /* malloc'd input array for points */
+
+/*-<a href="qh-globa.htm#TOC"
+ >--------------------------------</a><a name="qh-static">-</a>
+
+ qh static variables
+ defines static variables for individual functions
+
+ notes:
+ do not use 'static' within a function. Multiple instances of qhull
+ may exist.
+
+ do not assume zero initialization, 'QPn' may cause a restart
+*/
+ boolT ERREXITcalled; /* true during qh_errexit (prevents duplicate calls */
+ boolT firstcentrum; /* for qh_printcentrum */
+ boolT old_randomdist; /* save RANDOMdist flag during io, tracing, or statistics */
+ setT *coplanarfacetset; /* set of coplanar facets for searching qh_findbesthorizon() */
+ realT last_low; /* qh_scalelast parameters for qh_setdelaunay */
+ realT last_high;
+ realT last_newhigh;
+ unsigned lastreport; /* for qh_buildtracing */
+ int mergereport; /* for qh_tracemerging */
+ qhstatT *old_qhstat; /* for saving qh_qhstat in save_qhull() and UsingLibQhull. Free with qh_free() */
+ setT *old_tempstack; /* for saving qhmem.tempstack in save_qhull */
+ int ridgeoutnum; /* number of ridges for 4OFF output (qh_printbegin,etc) */
+};
+
+/*=========== -macros- =========================*/
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="otherfacet_">-</a>
+
+ otherfacet_(ridge, facet)
+ return neighboring facet for a ridge in facet
+*/
+#define otherfacet_(ridge, facet) \
+ (((ridge)->top == (facet)) ? (ridge)->bottom : (ridge)->top)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="getid_">-</a>
+
+ getid_(p)
+ return int ID for facet, ridge, or vertex
+ return qh_IDunknown(-1) if NULL
+*/
+#define getid_(p) ((p) ? (int)((p)->id) : qh_IDunknown)
+
+/*============== FORALL macros ===================*/
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FORALLfacets">-</a>
+
+ FORALLfacets { ... }
+ assign 'facet' to each facet in qh.facet_list
+
+ notes:
+ uses 'facetT *facet;'
+ assumes last facet is a sentinel
+
+ see:
+ FORALLfacet_( facetlist )
+*/
+#define FORALLfacets for (facet=qh facet_list;facet && facet->next;facet=facet->next)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FORALLpoints">-</a>
+
+ FORALLpoints { ... }
+ assign 'point' to each point in qh.first_point, qh.num_points
+
+ declare:
+ coordT *point, *pointtemp;
+*/
+#define FORALLpoints FORALLpoint_(qh first_point, qh num_points)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FORALLpoint_">-</a>
+
+ FORALLpoint_( points, num) { ... }
+ assign 'point' to each point in points array of num points
+
+ declare:
+ coordT *point, *pointtemp;
+*/
+#define FORALLpoint_(points, num) for (point= (points), \
+ pointtemp= (points)+qh hull_dim*(num); point < pointtemp; point += qh hull_dim)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FORALLvertices">-</a>
+
+ FORALLvertices { ... }
+ assign 'vertex' to each vertex in qh.vertex_list
+
+ declare:
+ vertexT *vertex;
+
+ notes:
+ assumes qh.vertex_list terminated with a sentinel
+*/
+#define FORALLvertices for (vertex=qh vertex_list;vertex && vertex->next;vertex= vertex->next)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHfacet_">-</a>
+
+ FOREACHfacet_( facets ) { ... }
+ assign 'facet' to each facet in facets
+
+ declare:
+ facetT *facet, **facetp;
+
+ see:
+ <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHfacet_(facets) FOREACHsetelement_(facetT, facets, facet)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHneighbor_">-</a>
+
+ FOREACHneighbor_( facet ) { ... }
+ assign 'neighbor' to each neighbor in facet->neighbors
+
+ FOREACHneighbor_( vertex ) { ... }
+ assign 'neighbor' to each neighbor in vertex->neighbors
+
+ declare:
+ facetT *neighbor, **neighborp;
+
+ see:
+ <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHneighbor_(facet) FOREACHsetelement_(facetT, facet->neighbors, neighbor)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHpoint_">-</a>
+
+ FOREACHpoint_( points ) { ... }
+ assign 'point' to each point in points set
+
+ declare:
+ pointT *point, **pointp;
+
+ see:
+ <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHpoint_(points) FOREACHsetelement_(pointT, points, point)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHridge_">-</a>
+
+ FOREACHridge_( ridges ) { ... }
+ assign 'ridge' to each ridge in ridges set
+
+ declare:
+ ridgeT *ridge, **ridgep;
+
+ see:
+ <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHridge_(ridges) FOREACHsetelement_(ridgeT, ridges, ridge)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHvertex_">-</a>
+
+ FOREACHvertex_( vertices ) { ... }
+ assign 'vertex' to each vertex in vertices set
+
+ declare:
+ vertexT *vertex, **vertexp;
+
+ see:
+ <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHvertex_(vertices) FOREACHsetelement_(vertexT, vertices,vertex)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHfacet_i_">-</a>
+
+ FOREACHfacet_i_( facets ) { ... }
+ assign 'facet' and 'facet_i' for each facet in facets set
+
+ declare:
+ facetT *facet;
+ int facet_n, facet_i;
+
+ see:
+ <a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+*/
+#define FOREACHfacet_i_(facets) FOREACHsetelement_i_(facetT, facets, facet)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHneighbor_i_">-</a>
+
+ FOREACHneighbor_i_( facet ) { ... }
+ assign 'neighbor' and 'neighbor_i' for each neighbor in facet->neighbors
+
+ FOREACHneighbor_i_( vertex ) { ... }
+ assign 'neighbor' and 'neighbor_i' for each neighbor in vertex->neighbors
+
+ declare:
+ facetT *neighbor;
+ int neighbor_n, neighbor_i;
+
+ see:
+ <a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+*/
+#define FOREACHneighbor_i_(facet) FOREACHsetelement_i_(facetT, facet->neighbors, neighbor)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHpoint_i_">-</a>
+
+ FOREACHpoint_i_( points ) { ... }
+ assign 'point' and 'point_i' for each point in points set
+
+ declare:
+ pointT *point;
+ int point_n, point_i;
+
+ see:
+ <a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+*/
+#define FOREACHpoint_i_(points) FOREACHsetelement_i_(pointT, points, point)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHridge_i_">-</a>
+
+ FOREACHridge_i_( ridges ) { ... }
+ assign 'ridge' and 'ridge_i' for each ridge in ridges set
+
+ declare:
+ ridgeT *ridge;
+ int ridge_n, ridge_i;
+
+ see:
+ <a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+*/
+#define FOREACHridge_i_(ridges) FOREACHsetelement_i_(ridgeT, ridges, ridge)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHvertex_i_">-</a>
+
+ FOREACHvertex_i_( vertices ) { ... }
+ assign 'vertex' and 'vertex_i' for each vertex in vertices set
+
+ declare:
+ vertexT *vertex;
+ int vertex_n, vertex_i;
+
+ see:
+ <a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+*/
+#define FOREACHvertex_i_(vertices) FOREACHsetelement_i_(vertexT, vertices,vertex)
+
+/********* -libqhull.c prototypes (duplicated from qhull_a.h) **********************/
+
+void qh_qhull(void);
+boolT qh_addpoint(pointT *furthest, facetT *facet, boolT checkdist);
+void qh_printsummary(FILE *fp);
+
+/********* -user.c prototypes (alphabetical) **********************/
+
+void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge);
+void qh_errprint(const char* string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex);
+int qh_new_qhull(int dim, int numpoints, coordT *points, boolT ismalloc,
+ char *qhull_cmd, FILE *outfile, FILE *errfile);
+void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall);
+void qh_printhelp_degenerate(FILE *fp);
+void qh_printhelp_narrowhull(FILE *fp, realT minangle);
+void qh_printhelp_singular(FILE *fp);
+void qh_user_memsizes(void);
+
+/********* -usermem.c prototypes (alphabetical) **********************/
+void qh_exit(int exitcode);
+void qh_fprintf_stderr(int msgcode, const char *fmt, ... );
+void qh_free(void *mem);
+void *qh_malloc(size_t size);
+
+/********* -userprintf.c and userprintf_rbox.c prototypes **********************/
+void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... );
+void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... );
+
+/***** -geom.c/geom2.c/random.c prototypes (duplicated from geom.h, random.h) ****************/
+
+facetT *qh_findbest(pointT *point, facetT *startfacet,
+ boolT bestoutside, boolT newfacets, boolT noupper,
+ realT *dist, boolT *isoutside, int *numpart);
+facetT *qh_findbestnew(pointT *point, facetT *startfacet,
+ realT *dist, boolT bestoutside, boolT *isoutside, int *numpart);
+boolT qh_gram_schmidt(int dim, realT **rows);
+void qh_outerinner(facetT *facet, realT *outerplane, realT *innerplane);
+void qh_printsummary(FILE *fp);
+void qh_projectinput(void);
+void qh_randommatrix(realT *buffer, int dim, realT **row);
+void qh_rotateinput(realT **rows);
+void qh_scaleinput(void);
+void qh_setdelaunay(int dim, int count, pointT *points);
+coordT *qh_sethalfspace_all(int dim, int count, coordT *halfspaces, pointT *feasible);
+
+/***** -global.c prototypes (alphabetical) ***********************/
+
+unsigned long qh_clock(void);
+void qh_checkflags(char *command, char *hiddenflags);
+void qh_clear_outputflags(void);
+void qh_freebuffers(void);
+void qh_freeqhull(boolT allmem);
+void qh_freeqhull2(boolT allmem);
+void qh_init_A(FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]);
+void qh_init_B(coordT *points, int numpoints, int dim, boolT ismalloc);
+void qh_init_qhull_command(int argc, char *argv[]);
+void qh_initbuffers(coordT *points, int numpoints, int dim, boolT ismalloc);
+void qh_initflags(char *command);
+void qh_initqhull_buffers(void);
+void qh_initqhull_globals(coordT *points, int numpoints, int dim, boolT ismalloc);
+void qh_initqhull_mem(void);
+void qh_initqhull_outputflags(void);
+void qh_initqhull_start(FILE *infile, FILE *outfile, FILE *errfile);
+void qh_initqhull_start2(FILE *infile, FILE *outfile, FILE *errfile);
+void qh_initthresholds(char *command);
+void qh_lib_check(int qhullLibraryType, int qhTsize, int vertexTsize, int ridgeTsize, int facetTsize, int setTsize, int qhmemTsize);
+void qh_option(const char *option, int *i, realT *r);
+#if qh_QHpointer
+void qh_restore_qhull(qhT **oldqh);
+qhT *qh_save_qhull(void);
+#endif
+
+/***** -io.c prototypes (duplicated from io.h) ***********************/
+
+void qh_dfacet(unsigned id);
+void qh_dvertex(unsigned id);
+void qh_printneighborhood(FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall);
+void qh_produce_output(void);
+coordT *qh_readpoints(int *numpoints, int *dimension, boolT *ismalloc);
+
+
+/********* -mem.c prototypes (duplicated from mem.h) **********************/
+
+void qh_meminit(FILE *ferr);
+void qh_memfreeshort(int *curlong, int *totlong);
+
+/********* -poly.c/poly2.c prototypes (duplicated from poly.h) **********************/
+
+void qh_check_output(void);
+void qh_check_points(void);
+setT *qh_facetvertices(facetT *facetlist, setT *facets, boolT allfacets);
+facetT *qh_findbestfacet(pointT *point, boolT bestoutside,
+ realT *bestdist, boolT *isoutside);
+vertexT *qh_nearvertex(facetT *facet, pointT *point, realT *bestdistp);
+pointT *qh_point(int id);
+setT *qh_pointfacet(void /*qh.facet_list*/);
+int qh_pointid(pointT *point);
+setT *qh_pointvertex(void /*qh.facet_list*/);
+void qh_setvoronoi_all(void);
+void qh_triangulate(void /*qh.facet_list*/);
+
+/********* -rboxlib.c prototypes **********************/
+int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command);
+void qh_errexit_rbox(int exitcode);
+
+/********* -stat.c prototypes (duplicated from stat.h) **********************/
+
+void qh_collectstatistics(void);
+void qh_printallstatistics(FILE *fp, const char *string);
+
+#endif /* qhDEFlibqhull */
diff --git a/xs/src/qhull/src/libqhull/libqhull.pro b/xs/src/qhull/src/libqhull/libqhull.pro
new file mode 100644
index 000000000..18005da59
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/libqhull.pro
@@ -0,0 +1,67 @@
+# -------------------------------------------------
+# libqhull.pro -- Qt project for Qhull shared library
+# -------------------------------------------------
+
+include(../qhull-warn.pri)
+
+DESTDIR = ../../lib
+DLLDESTDIR = ../../bin
+TEMPLATE = lib
+CONFIG += shared warn_on
+CONFIG -= qt
+
+build_pass:CONFIG(debug, debug|release):{
+ TARGET = qhull_d
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release):{
+ TARGET = qhull
+ OBJECTS_DIR = Release
+}
+win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
+
+win32-msvc* : DEF_FILE += ../../src/libqhull/qhull-exports.def
+
+# Order object files by frequency of execution. Small files at end.
+
+# libqhull/libqhull.pro and ../qhull-libqhull-src.pri have the same SOURCES and HEADERS
+SOURCES += ../libqhull/global.c
+SOURCES += ../libqhull/stat.c
+SOURCES += ../libqhull/geom2.c
+SOURCES += ../libqhull/poly2.c
+SOURCES += ../libqhull/merge.c
+SOURCES += ../libqhull/libqhull.c
+SOURCES += ../libqhull/geom.c
+SOURCES += ../libqhull/poly.c
+SOURCES += ../libqhull/qset.c
+SOURCES += ../libqhull/mem.c
+SOURCES += ../libqhull/random.c
+SOURCES += ../libqhull/usermem.c
+SOURCES += ../libqhull/userprintf.c
+SOURCES += ../libqhull/io.c
+SOURCES += ../libqhull/user.c
+SOURCES += ../libqhull/rboxlib.c
+SOURCES += ../libqhull/userprintf_rbox.c
+
+HEADERS += ../libqhull/geom.h
+HEADERS += ../libqhull/io.h
+HEADERS += ../libqhull/libqhull.h
+HEADERS += ../libqhull/mem.h
+HEADERS += ../libqhull/merge.h
+HEADERS += ../libqhull/poly.h
+HEADERS += ../libqhull/random.h
+HEADERS += ../libqhull/qhull_a.h
+HEADERS += ../libqhull/qset.h
+HEADERS += ../libqhull/stat.h
+HEADERS += ../libqhull/user.h
+
+OTHER_FILES += Mborland
+OTHER_FILES += qh-geom.htm
+OTHER_FILES += qh-globa.htm
+OTHER_FILES += qh-io.htm
+OTHER_FILES += qh-mem.htm
+OTHER_FILES += qh-merge.htm
+OTHER_FILES += qh-poly.htm
+OTHER_FILES += qh-qhull.htm
+OTHER_FILES += qh-set.htm
+OTHER_FILES += qh-stat.htm
+OTHER_FILES += qh-user.htm
diff --git a/xs/src/qhull/src/libqhull/mem.c b/xs/src/qhull/src/libqhull/mem.c
new file mode 100644
index 000000000..db72bb4e1
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/mem.c
@@ -0,0 +1,576 @@
+/*<html><pre> -<a href="qh-mem.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ mem.c
+ memory management routines for qhull
+
+ This is a standalone program.
+
+ To initialize memory:
+
+ qh_meminit(stderr);
+ qh_meminitbuffers(qh IStracing, qh_MEMalign, 7, qh_MEMbufsize,qh_MEMinitbuf);
+ qh_memsize((int)sizeof(facetT));
+ qh_memsize((int)sizeof(facetT));
+ ...
+ qh_memsetup();
+
+ To free up all memory buffers:
+ qh_memfreeshort(&curlong, &totlong);
+
+ if qh_NOmem,
+ malloc/free is used instead of mem.c
+
+ notes:
+ uses Quickfit algorithm (freelists for commonly allocated sizes)
+ assumes small sizes for freelists (it discards the tail of memory buffers)
+
+ see:
+ qh-mem.htm and mem.h
+ global.c (qh_initbuffers) for an example of using mem.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/mem.c#7 $$Change: 2065 $
+ $DateTime: 2016/01/18 13:51:04 $$Author: bbarber $
+*/
+
+#include "user.h" /* for QHULL_CRTDBG */
+#include "mem.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef qhDEFlibqhull
+typedef struct ridgeT ridgeT;
+typedef struct facetT facetT;
+#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
+#pragma warning( disable : 4127) /* conditional expression is constant */
+#pragma warning( disable : 4706) /* assignment within conditional function */
+#endif
+void qh_errexit(int exitcode, facetT *, ridgeT *);
+void qh_exit(int exitcode);
+void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... );
+void qh_fprintf_stderr(int msgcode, const char *fmt, ... );
+void qh_free(void *mem);
+void *qh_malloc(size_t size);
+#endif
+
+/*============ -global data structure ==============
+ see mem.h for definition
+*/
+
+qhmemT qhmem= {0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0}; /* remove "= {0}" if this causes a compiler error */
+
+#ifndef qh_NOmem
+
+/*============= internal functions ==============*/
+
+static int qh_intcompare(const void *i, const void *j);
+
+/*========== functions in alphabetical order ======== */
+
+/*-<a href="qh-mem.htm#TOC"
+ >-------------------------------</a><a name="intcompare">-</a>
+
+ qh_intcompare( i, j )
+ used by qsort and bsearch to compare two integers
+*/
+static int qh_intcompare(const void *i, const void *j) {
+ return(*((const int *)i) - *((const int *)j));
+} /* intcompare */
+
+
+/*-<a href="qh-mem.htm#TOC"
+ >--------------------------------</a><a name="memalloc">-</a>
+
+ qh_memalloc( insize )
+ returns object of insize bytes
+ qhmem is the global memory structure
+
+ returns:
+ pointer to allocated memory
+ errors if insufficient memory
+
+ notes:
+ use explicit type conversion to avoid type warnings on some compilers
+ actual object may be larger than insize
+ use qh_memalloc_() for inline code for quick allocations
+ logs allocations if 'T5'
+ caller is responsible for freeing the memory.
+ short memory is freed on shutdown by qh_memfreeshort unless qh_NOmem
+
+ design:
+ if size < qhmem.LASTsize
+ if qhmem.freelists[size] non-empty
+ return first object on freelist
+ else
+ round up request to size of qhmem.freelists[size]
+ allocate new allocation buffer if necessary
+ allocate object from allocation buffer
+ else
+ allocate object with qh_malloc() in user.c
+*/
+void *qh_memalloc(int insize) {
+ void **freelistp, *newbuffer;
+ int idx, size, n;
+ int outsize, bufsize;
+ void *object;
+
+ if (insize<0) {
+ qh_fprintf(qhmem.ferr, 6235, "qhull error (qh_memalloc): negative request size (%d). Did int overflow due to high-D?\n", insize); /* WARN64 */
+ qh_errexit(qhmem_ERRmem, NULL, NULL);
+ }
+ if (insize>=0 && insize <= qhmem.LASTsize) {
+ idx= qhmem.indextable[insize];
+ outsize= qhmem.sizetable[idx];
+ qhmem.totshort += outsize;
+ freelistp= qhmem.freelists+idx;
+ if ((object= *freelistp)) {
+ qhmem.cntquick++;
+ qhmem.totfree -= outsize;
+ *freelistp= *((void **)*freelistp); /* replace freelist with next object */
+#ifdef qh_TRACEshort
+ n= qhmem.cntshort+qhmem.cntquick+qhmem.freeshort;
+ if (qhmem.IStracing >= 5)
+ qh_fprintf(qhmem.ferr, 8141, "qh_mem %p n %8d alloc quick: %d bytes (tot %d cnt %d)\n", object, n, outsize, qhmem.totshort, qhmem.cntshort+qhmem.cntquick-qhmem.freeshort);
+#endif
+ return(object);
+ }else {
+ qhmem.cntshort++;
+ if (outsize > qhmem.freesize) {
+ qhmem.totdropped += qhmem.freesize;
+ if (!qhmem.curbuffer)
+ bufsize= qhmem.BUFinit;
+ else
+ bufsize= qhmem.BUFsize;
+ if (!(newbuffer= qh_malloc((size_t)bufsize))) {
+ qh_fprintf(qhmem.ferr, 6080, "qhull error (qh_memalloc): insufficient memory to allocate short memory buffer (%d bytes)\n", bufsize);
+ qh_errexit(qhmem_ERRmem, NULL, NULL);
+ }
+ *((void **)newbuffer)= qhmem.curbuffer; /* prepend newbuffer to curbuffer
+ list. newbuffer!=0 by QH6080 */
+ qhmem.curbuffer= newbuffer;
+ size= (sizeof(void **) + qhmem.ALIGNmask) & ~qhmem.ALIGNmask;
+ qhmem.freemem= (void *)((char *)newbuffer+size);
+ qhmem.freesize= bufsize - size;
+ qhmem.totbuffer += bufsize - size; /* easier to check */
+ /* Periodically test totbuffer. It matches at beginning and exit of every call */
+ n = qhmem.totshort + qhmem.totfree + qhmem.totdropped + qhmem.freesize - outsize;
+ if (qhmem.totbuffer != n) {
+ qh_fprintf(qhmem.ferr, 6212, "qh_memalloc internal error: short totbuffer %d != totshort+totfree... %d\n", qhmem.totbuffer, n);
+ qh_errexit(qhmem_ERRmem, NULL, NULL);
+ }
+ }
+ object= qhmem.freemem;
+ qhmem.freemem= (void *)((char *)qhmem.freemem + outsize);
+ qhmem.freesize -= outsize;
+ qhmem.totunused += outsize - insize;
+#ifdef qh_TRACEshort
+ n= qhmem.cntshort+qhmem.cntquick+qhmem.freeshort;
+ if (qhmem.IStracing >= 5)
+ qh_fprintf(qhmem.ferr, 8140, "qh_mem %p n %8d alloc short: %d bytes (tot %d cnt %d)\n", object, n, outsize, qhmem.totshort, qhmem.cntshort+qhmem.cntquick-qhmem.freeshort);
+#endif
+ return object;
+ }
+ }else { /* long allocation */
+ if (!qhmem.indextable) {
+ qh_fprintf(qhmem.ferr, 6081, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n");
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ outsize= insize;
+ qhmem.cntlong++;
+ qhmem.totlong += outsize;
+ if (qhmem.maxlong < qhmem.totlong)
+ qhmem.maxlong= qhmem.totlong;
+ if (!(object= qh_malloc((size_t)outsize))) {
+ qh_fprintf(qhmem.ferr, 6082, "qhull error (qh_memalloc): insufficient memory to allocate %d bytes\n", outsize);
+ qh_errexit(qhmem_ERRmem, NULL, NULL);
+ }
+ if (qhmem.IStracing >= 5)
+ qh_fprintf(qhmem.ferr, 8057, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, outsize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
+ }
+ return(object);
+} /* memalloc */
+
+
+/*-<a href="qh-mem.htm#TOC"
+ >--------------------------------</a><a name="memcheck">-</a>
+
+ qh_memcheck( )
+*/
+void qh_memcheck(void) {
+ int i, count, totfree= 0;
+ void *object;
+
+ if (qhmem.ferr == 0 || qhmem.IStracing < 0 || qhmem.IStracing > 10 || (((qhmem.ALIGNmask+1) & qhmem.ALIGNmask) != 0)) {
+ qh_fprintf_stderr(6244, "qh_memcheck error: either qhmem is overwritten or qhmem is not initialized. Call qh_meminit() or qh_new_qhull() before calling qh_mem routines. ferr 0x%x IsTracing %d ALIGNmask 0x%x", qhmem.ferr, qhmem.IStracing, qhmem.ALIGNmask);
+ qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
+ }
+ if (qhmem.IStracing != 0)
+ qh_fprintf(qhmem.ferr, 8143, "qh_memcheck: check size of freelists on qhmem\nqh_memcheck: A segmentation fault indicates an overwrite of qhmem\n");
+ for (i=0; i < qhmem.TABLEsize; i++) {
+ count=0;
+ for (object= qhmem.freelists[i]; object; object= *((void **)object))
+ count++;
+ totfree += qhmem.sizetable[i] * count;
+ }
+ if (totfree != qhmem.totfree) {
+ qh_fprintf(qhmem.ferr, 6211, "Qhull internal error (qh_memcheck): totfree %d not equal to freelist total %d\n", qhmem.totfree, totfree);
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ if (qhmem.IStracing != 0)
+ qh_fprintf(qhmem.ferr, 8144, "qh_memcheck: total size of freelists totfree is the same as qhmem.totfree\n", totfree);
+} /* memcheck */
+
+/*-<a href="qh-mem.htm#TOC"
+ >--------------------------------</a><a name="memfree">-</a>
+
+ qh_memfree( object, insize )
+ free up an object of size bytes
+ size is insize from qh_memalloc
+
+ notes:
+ object may be NULL
+ type checking warns if using (void **)object
+ use qh_memfree_() for quick free's of small objects
+
+ design:
+ if size <= qhmem.LASTsize
+ append object to corresponding freelist
+ else
+ call qh_free(object)
+*/
+void qh_memfree(void *object, int insize) {
+ void **freelistp;
+ int idx, outsize;
+
+ if (!object)
+ return;
+ if (insize <= qhmem.LASTsize) {
+ qhmem.freeshort++;
+ idx= qhmem.indextable[insize];
+ outsize= qhmem.sizetable[idx];
+ qhmem.totfree += outsize;
+ qhmem.totshort -= outsize;
+ freelistp= qhmem.freelists + idx;
+ *((void **)object)= *freelistp;
+ *freelistp= object;
+#ifdef qh_TRACEshort
+ idx= qhmem.cntshort+qhmem.cntquick+qhmem.freeshort;
+ if (qhmem.IStracing >= 5)
+ qh_fprintf(qhmem.ferr, 8142, "qh_mem %p n %8d free short: %d bytes (tot %d cnt %d)\n", object, idx, outsize, qhmem.totshort, qhmem.cntshort+qhmem.cntquick-qhmem.freeshort);
+#endif
+ }else {
+ qhmem.freelong++;
+ qhmem.totlong -= insize;
+ if (qhmem.IStracing >= 5)
+ qh_fprintf(qhmem.ferr, 8058, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, insize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
+ qh_free(object);
+ }
+} /* memfree */
+
+
+/*-<a href="qh-mem.htm#TOC"
+ >-------------------------------</a><a name="memfreeshort">-</a>
+
+ qh_memfreeshort( curlong, totlong )
+ frees up all short and qhmem memory allocations
+
+ returns:
+ number and size of current long allocations
+
+ see:
+ qh_freeqhull(allMem)
+ qh_memtotal(curlong, totlong, curshort, totshort, maxlong, totbuffer);
+*/
+void qh_memfreeshort(int *curlong, int *totlong) {
+ void *buffer, *nextbuffer;
+ FILE *ferr;
+
+ *curlong= qhmem.cntlong - qhmem.freelong;
+ *totlong= qhmem.totlong;
+ for (buffer= qhmem.curbuffer; buffer; buffer= nextbuffer) {
+ nextbuffer= *((void **) buffer);
+ qh_free(buffer);
+ }
+ qhmem.curbuffer= NULL;
+ if (qhmem.LASTsize) {
+ qh_free(qhmem.indextable);
+ qh_free(qhmem.freelists);
+ qh_free(qhmem.sizetable);
+ }
+ ferr= qhmem.ferr;
+ memset((char *)&qhmem, 0, sizeof(qhmem)); /* every field is 0, FALSE, NULL */
+ qhmem.ferr= ferr;
+} /* memfreeshort */
+
+
+/*-<a href="qh-mem.htm#TOC"
+ >--------------------------------</a><a name="meminit">-</a>
+
+ qh_meminit( ferr )
+ initialize qhmem and test sizeof( void*)
+ Does not throw errors. qh_exit on failure
+*/
+void qh_meminit(FILE *ferr) {
+
+ memset((char *)&qhmem, 0, sizeof(qhmem)); /* every field is 0, FALSE, NULL */
+ if (ferr)
+ qhmem.ferr= ferr;
+ else
+ qhmem.ferr= stderr;
+ if (sizeof(void*) < sizeof(int)) {
+ qh_fprintf(qhmem.ferr, 6083, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d. qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
+ qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
+ }
+ if (sizeof(void*) > sizeof(ptr_intT)) {
+ qh_fprintf(qhmem.ferr, 6084, "qhull internal error (qh_meminit): sizeof(void*) %d > sizeof(ptr_intT) %d. Change ptr_intT in mem.h to 'long long'\n", (int)sizeof(void*), (int)sizeof(ptr_intT));
+ qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
+ }
+ qh_memcheck();
+} /* meminit */
+
+/*-<a href="qh-mem.htm#TOC"
+ >-------------------------------</a><a name="meminitbuffers">-</a>
+
+ qh_meminitbuffers( tracelevel, alignment, numsizes, bufsize, bufinit )
+ initialize qhmem
+ if tracelevel >= 5, trace memory allocations
+ alignment= desired address alignment for memory allocations
+ numsizes= number of freelists
+ bufsize= size of additional memory buffers for short allocations
+ bufinit= size of initial memory buffer for short allocations
+*/
+void qh_meminitbuffers(int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
+
+ qhmem.IStracing= tracelevel;
+ qhmem.NUMsizes= numsizes;
+ qhmem.BUFsize= bufsize;
+ qhmem.BUFinit= bufinit;
+ qhmem.ALIGNmask= alignment-1;
+ if (qhmem.ALIGNmask & ~qhmem.ALIGNmask) {
+ qh_fprintf(qhmem.ferr, 6085, "qhull internal error (qh_meminit): memory alignment %d is not a power of 2\n", alignment);
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ qhmem.sizetable= (int *) calloc((size_t)numsizes, sizeof(int));
+ qhmem.freelists= (void **) calloc((size_t)numsizes, sizeof(void *));
+ if (!qhmem.sizetable || !qhmem.freelists) {
+ qh_fprintf(qhmem.ferr, 6086, "qhull error (qh_meminit): insufficient memory\n");
+ qh_errexit(qhmem_ERRmem, NULL, NULL);
+ }
+ if (qhmem.IStracing >= 1)
+ qh_fprintf(qhmem.ferr, 8059, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment);
+} /* meminitbuffers */
+
+/*-<a href="qh-mem.htm#TOC"
+ >-------------------------------</a><a name="memsetup">-</a>
+
+ qh_memsetup()
+ set up memory after running memsize()
+*/
+void qh_memsetup(void) {
+ int k,i;
+
+ qsort(qhmem.sizetable, (size_t)qhmem.TABLEsize, sizeof(int), qh_intcompare);
+ qhmem.LASTsize= qhmem.sizetable[qhmem.TABLEsize-1];
+ if (qhmem.LASTsize >= qhmem.BUFsize || qhmem.LASTsize >= qhmem.BUFinit) {
+ qh_fprintf(qhmem.ferr, 6087, "qhull error (qh_memsetup): largest mem size %d is >= buffer size %d or initial buffer size %d\n",
+ qhmem.LASTsize, qhmem.BUFsize, qhmem.BUFinit);
+ qh_errexit(qhmem_ERRmem, NULL, NULL);
+ }
+ if (!(qhmem.indextable= (int *)qh_malloc((qhmem.LASTsize+1) * sizeof(int)))) {
+ qh_fprintf(qhmem.ferr, 6088, "qhull error (qh_memsetup): insufficient memory\n");
+ qh_errexit(qhmem_ERRmem, NULL, NULL);
+ }
+ for (k=qhmem.LASTsize+1; k--; )
+ qhmem.indextable[k]= k;
+ i= 0;
+ for (k=0; k <= qhmem.LASTsize; k++) {
+ if (qhmem.indextable[k] <= qhmem.sizetable[i])
+ qhmem.indextable[k]= i;
+ else
+ qhmem.indextable[k]= ++i;
+ }
+} /* memsetup */
+
+/*-<a href="qh-mem.htm#TOC"
+ >-------------------------------</a><a name="memsize">-</a>
+
+ qh_memsize( size )
+ define a free list for this size
+*/
+void qh_memsize(int size) {
+ int k;
+
+ if (qhmem.LASTsize) {
+ qh_fprintf(qhmem.ferr, 6089, "qhull error (qh_memsize): called after qhmem_setup\n");
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ size= (size + qhmem.ALIGNmask) & ~qhmem.ALIGNmask;
+ for (k=qhmem.TABLEsize; k--; ) {
+ if (qhmem.sizetable[k] == size)
+ return;
+ }
+ if (qhmem.TABLEsize < qhmem.NUMsizes)
+ qhmem.sizetable[qhmem.TABLEsize++]= size;
+ else
+ qh_fprintf(qhmem.ferr, 7060, "qhull warning (memsize): free list table has room for only %d sizes\n", qhmem.NUMsizes);
+} /* memsize */
+
+
+/*-<a href="qh-mem.htm#TOC"
+ >-------------------------------</a><a name="memstatistics">-</a>
+
+ qh_memstatistics( fp )
+ print out memory statistics
+
+ Verifies that qhmem.totfree == sum of freelists
+*/
+void qh_memstatistics(FILE *fp) {
+ int i;
+ int count;
+ void *object;
+
+ qh_memcheck();
+ qh_fprintf(fp, 9278, "\nmemory statistics:\n\
+%7d quick allocations\n\
+%7d short allocations\n\
+%7d long allocations\n\
+%7d short frees\n\
+%7d long frees\n\
+%7d bytes of short memory in use\n\
+%7d bytes of short memory in freelists\n\
+%7d bytes of dropped short memory\n\
+%7d bytes of unused short memory (estimated)\n\
+%7d bytes of long memory allocated (max, except for input)\n\
+%7d bytes of long memory in use (in %d pieces)\n\
+%7d bytes of short memory buffers (minus links)\n\
+%7d bytes per short memory buffer (initially %d bytes)\n",
+ qhmem.cntquick, qhmem.cntshort, qhmem.cntlong,
+ qhmem.freeshort, qhmem.freelong,
+ qhmem.totshort, qhmem.totfree,
+ qhmem.totdropped + qhmem.freesize, qhmem.totunused,
+ qhmem.maxlong, qhmem.totlong, qhmem.cntlong - qhmem.freelong,
+ qhmem.totbuffer, qhmem.BUFsize, qhmem.BUFinit);
+ if (qhmem.cntlarger) {
+ qh_fprintf(fp, 9279, "%7d calls to qh_setlarger\n%7.2g average copy size\n",
+ qhmem.cntlarger, ((float)qhmem.totlarger)/(float)qhmem.cntlarger);
+ qh_fprintf(fp, 9280, " freelists(bytes->count):");
+ }
+ for (i=0; i < qhmem.TABLEsize; i++) {
+ count=0;
+ for (object= qhmem.freelists[i]; object; object= *((void **)object))
+ count++;
+ qh_fprintf(fp, 9281, " %d->%d", qhmem.sizetable[i], count);
+ }
+ qh_fprintf(fp, 9282, "\n\n");
+} /* memstatistics */
+
+
+/*-<a href="qh-mem.htm#TOC"
+ >-------------------------------</a><a name="NOmem">-</a>
+
+ qh_NOmem
+ turn off quick-fit memory allocation
+
+ notes:
+ uses qh_malloc() and qh_free() instead
+*/
+#else /* qh_NOmem */
+
+void *qh_memalloc(int insize) {
+ void *object;
+
+ if (!(object= qh_malloc((size_t)insize))) {
+ qh_fprintf(qhmem.ferr, 6090, "qhull error (qh_memalloc): insufficient memory\n");
+ qh_errexit(qhmem_ERRmem, NULL, NULL);
+ }
+ qhmem.cntlong++;
+ qhmem.totlong += insize;
+ if (qhmem.maxlong < qhmem.totlong)
+ qhmem.maxlong= qhmem.totlong;
+ if (qhmem.IStracing >= 5)
+ qh_fprintf(qhmem.ferr, 8060, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, insize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
+ return object;
+}
+
+void qh_memfree(void *object, int insize) {
+
+ if (!object)
+ return;
+ qh_free(object);
+ qhmem.freelong++;
+ qhmem.totlong -= insize;
+ if (qhmem.IStracing >= 5)
+ qh_fprintf(qhmem.ferr, 8061, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qhmem.cntlong+qhmem.freelong, insize, qhmem.totlong, qhmem.cntlong-qhmem.freelong);
+}
+
+void qh_memfreeshort(int *curlong, int *totlong) {
+ *totlong= qhmem.totlong;
+ *curlong= qhmem.cntlong - qhmem.freelong;
+ memset((char *)&qhmem, 0, sizeof(qhmem)); /* every field is 0, FALSE, NULL */
+}
+
+void qh_meminit(FILE *ferr) {
+
+ memset((char *)&qhmem, 0, sizeof(qhmem)); /* every field is 0, FALSE, NULL */
+ if (ferr)
+ qhmem.ferr= ferr;
+ else
+ qhmem.ferr= stderr;
+ if (sizeof(void*) < sizeof(int)) {
+ qh_fprintf(qhmem.ferr, 6091, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d. qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+}
+
+void qh_meminitbuffers(int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
+
+ qhmem.IStracing= tracelevel;
+}
+
+void qh_memsetup(void) {
+
+}
+
+void qh_memsize(int size) {
+
+}
+
+void qh_memstatistics(FILE *fp) {
+
+ qh_fprintf(fp, 9409, "\nmemory statistics:\n\
+%7d long allocations\n\
+%7d long frees\n\
+%7d bytes of long memory allocated (max, except for input)\n\
+%7d bytes of long memory in use (in %d pieces)\n",
+ qhmem.cntlong,
+ qhmem.freelong,
+ qhmem.maxlong, qhmem.totlong, qhmem.cntlong - qhmem.freelong);
+}
+
+#endif /* qh_NOmem */
+
+/*-<a href="qh-mem.htm#TOC"
+>-------------------------------</a><a name="memtotlong">-</a>
+
+ qh_memtotal( totlong, curlong, totshort, curshort, maxlong, totbuffer )
+ Return the total, allocated long and short memory
+
+ returns:
+ Returns the total current bytes of long and short allocations
+ Returns the current count of long and short allocations
+ Returns the maximum long memory and total short buffer (minus one link per buffer)
+ Does not error (UsingLibQhull.cpp)
+*/
+void qh_memtotal(int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer) {
+ *totlong= qhmem.totlong;
+ *curlong= qhmem.cntlong - qhmem.freelong;
+ *totshort= qhmem.totshort;
+ *curshort= qhmem.cntshort + qhmem.cntquick - qhmem.freeshort;
+ *maxlong= qhmem.maxlong;
+ *totbuffer= qhmem.totbuffer;
+} /* memtotlong */
+
diff --git a/xs/src/qhull/src/libqhull/mem.h b/xs/src/qhull/src/libqhull/mem.h
new file mode 100644
index 000000000..453f319df
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/mem.h
@@ -0,0 +1,222 @@
+/*<html><pre> -<a href="qh-mem.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ mem.h
+ prototypes for memory management functions
+
+ see qh-mem.htm, mem.c and qset.h
+
+ for error handling, writes message and calls
+ qh_errexit(qhmem_ERRmem, NULL, NULL) if insufficient memory
+ and
+ qh_errexit(qhmem_ERRqhull, NULL, NULL) otherwise
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/mem.h#2 $$Change: 2062 $
+ $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+*/
+
+#ifndef qhDEFmem
+#define qhDEFmem 1
+
+#include <stdio.h>
+
+/*-<a href="qh-mem.htm#TOC"
+ >-------------------------------</a><a name="NOmem">-</a>
+
+ qh_NOmem
+ turn off quick-fit memory allocation
+
+ notes:
+ mem.c implements Quickfit memory allocation for about 20% time
+ savings. If it fails on your machine, try to locate the
+ problem, and send the answer to qhull@qhull.org. If this can
+ not be done, define qh_NOmem to use malloc/free instead.
+
+ #define qh_NOmem
+*/
+
+/*-<a href="qh-mem.htm#TOC"
+>-------------------------------</a><a name="TRACEshort">-</a>
+
+qh_TRACEshort
+Trace short and quick memory allocations at T5
+
+*/
+#define qh_TRACEshort
+
+/*-------------------------------------------
+ to avoid bus errors, memory allocation must consider alignment requirements.
+ malloc() automatically takes care of alignment. Since mem.c manages
+ its own memory, we need to explicitly specify alignment in
+ qh_meminitbuffers().
+
+ A safe choice is sizeof(double). sizeof(float) may be used if doubles
+ do not occur in data structures and pointers are the same size. Be careful
+ of machines (e.g., DEC Alpha) with large pointers. If gcc is available,
+ use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)).
+
+ see <a href="user.h#MEMalign">qh_MEMalign</a> in user.h for qhull's alignment
+*/
+
+#define qhmem_ERRmem 4 /* matches qh_ERRmem in libqhull.h */
+#define qhmem_ERRqhull 5 /* matches qh_ERRqhull in libqhull.h */
+
+/*-<a href="qh-mem.htm#TOC"
+ >--------------------------------</a><a name="ptr_intT">-</a>
+
+ ptr_intT
+ for casting a void * to an integer-type that holds a pointer
+ Used for integer expressions (e.g., computing qh_gethash() in poly.c)
+
+ notes:
+ WARN64 -- these notes indicate 64-bit issues
+ On 64-bit machines, a pointer may be larger than an 'int'.
+ qh_meminit()/mem.c checks that 'ptr_intT' holds a 'void*'
+ ptr_intT is typically a signed value, but not necessarily so
+ size_t is typically unsigned, but should match the parameter type
+ Qhull uses int instead of size_t except for system calls such as malloc, qsort, qh_malloc, etc.
+ This matches Qt convention and is easier to work with.
+*/
+#if (defined(__MINGW64__)) && defined(_WIN64)
+typedef long long ptr_intT;
+#elif (_MSC_VER) && defined(_WIN64)
+typedef long long ptr_intT;
+#else
+typedef long ptr_intT;
+#endif
+
+/*-<a href="qh-mem.htm#TOC"
+ >--------------------------------</a><a name="qhmemT">-</a>
+
+ qhmemT
+ global memory structure for mem.c
+
+ notes:
+ users should ignore qhmem except for writing extensions
+ qhmem is allocated in mem.c
+
+ qhmem could be swapable like qh and qhstat, but then
+ multiple qh's and qhmem's would need to keep in synch.
+ A swapable qhmem would also waste memory buffers. As long
+ as memory operations are atomic, there is no problem with
+ multiple qh structures being active at the same time.
+ If you need separate address spaces, you can swap the
+ contents of qhmem.
+*/
+typedef struct qhmemT qhmemT;
+extern qhmemT qhmem;
+
+#ifndef DEFsetT
+#define DEFsetT 1
+typedef struct setT setT; /* defined in qset.h */
+#endif
+
+/* Update qhmem in mem.c if add or remove fields */
+struct qhmemT { /* global memory management variables */
+ int BUFsize; /* size of memory allocation buffer */
+ int BUFinit; /* initial size of memory allocation buffer */
+ int TABLEsize; /* actual number of sizes in free list table */
+ int NUMsizes; /* maximum number of sizes in free list table */
+ int LASTsize; /* last size in free list table */
+ int ALIGNmask; /* worst-case alignment, must be 2^n-1 */
+ void **freelists; /* free list table, linked by offset 0 */
+ int *sizetable; /* size of each freelist */
+ int *indextable; /* size->index table */
+ void *curbuffer; /* current buffer, linked by offset 0 */
+ void *freemem; /* free memory in curbuffer */
+ int freesize; /* size of freemem in bytes */
+ setT *tempstack; /* stack of temporary memory, managed by users */
+ FILE *ferr; /* file for reporting errors when 'qh' may be undefined */
+ int IStracing; /* =5 if tracing memory allocations */
+ int cntquick; /* count of quick allocations */
+ /* Note: removing statistics doesn't effect speed */
+ int cntshort; /* count of short allocations */
+ int cntlong; /* count of long allocations */
+ int freeshort; /* count of short memfrees */
+ int freelong; /* count of long memfrees */
+ int totbuffer; /* total short memory buffers minus buffer links */
+ int totdropped; /* total dropped memory at end of short memory buffers (e.g., freesize) */
+ int totfree; /* total size of free, short memory on freelists */
+ int totlong; /* total size of long memory in use */
+ int maxlong; /* maximum totlong */
+ int totshort; /* total size of short memory in use */
+ int totunused; /* total unused short memory (estimated, short size - request size of first allocations) */
+ int cntlarger; /* count of setlarger's */
+ int totlarger; /* total copied by setlarger */
+};
+
+
+/*==================== -macros ====================*/
+
+/*-<a href="qh-mem.htm#TOC"
+ >--------------------------------</a><a name="memalloc_">-</a>
+
+ qh_memalloc_(insize, freelistp, object, type)
+ returns object of size bytes
+ assumes size<=qhmem.LASTsize and void **freelistp is a temp
+*/
+
+#if defined qh_NOmem
+#define qh_memalloc_(insize, freelistp, object, type) {\
+ object= (type*)qh_memalloc(insize); }
+#elif defined qh_TRACEshort
+#define qh_memalloc_(insize, freelistp, object, type) {\
+ freelistp= NULL; /* Avoid warnings */ \
+ object= (type*)qh_memalloc(insize); }
+#else /* !qh_NOmem */
+
+#define qh_memalloc_(insize, freelistp, object, type) {\
+ freelistp= qhmem.freelists + qhmem.indextable[insize];\
+ if ((object= (type*)*freelistp)) {\
+ qhmem.totshort += qhmem.sizetable[qhmem.indextable[insize]]; \
+ qhmem.totfree -= qhmem.sizetable[qhmem.indextable[insize]]; \
+ qhmem.cntquick++; \
+ *freelistp= *((void **)*freelistp);\
+ }else object= (type*)qh_memalloc(insize);}
+#endif
+
+/*-<a href="qh-mem.htm#TOC"
+ >--------------------------------</a><a name="memfree_">-</a>
+
+ qh_memfree_(object, insize, freelistp)
+ free up an object
+
+ notes:
+ object may be NULL
+ assumes size<=qhmem.LASTsize and void **freelistp is a temp
+*/
+#if defined qh_NOmem
+#define qh_memfree_(object, insize, freelistp) {\
+ qh_memfree(object, insize); }
+#elif defined qh_TRACEshort
+#define qh_memfree_(object, insize, freelistp) {\
+ freelistp= NULL; /* Avoid warnings */ \
+ qh_memfree(object, insize); }
+#else /* !qh_NOmem */
+
+#define qh_memfree_(object, insize, freelistp) {\
+ if (object) { \
+ qhmem.freeshort++;\
+ freelistp= qhmem.freelists + qhmem.indextable[insize];\
+ qhmem.totshort -= qhmem.sizetable[qhmem.indextable[insize]]; \
+ qhmem.totfree += qhmem.sizetable[qhmem.indextable[insize]]; \
+ *((void **)object)= *freelistp;\
+ *freelistp= object;}}
+#endif
+
+/*=============== prototypes in alphabetical order ============*/
+
+void *qh_memalloc(int insize);
+void qh_memcheck(void);
+void qh_memfree(void *object, int insize);
+void qh_memfreeshort(int *curlong, int *totlong);
+void qh_meminit(FILE *ferr);
+void qh_meminitbuffers(int tracelevel, int alignment, int numsizes,
+ int bufsize, int bufinit);
+void qh_memsetup(void);
+void qh_memsize(int size);
+void qh_memstatistics(FILE *fp);
+void qh_memtotal(int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer);
+
+#endif /* qhDEFmem */
diff --git a/xs/src/qhull/src/libqhull/merge.c b/xs/src/qhull/src/libqhull/merge.c
new file mode 100644
index 000000000..22104dc03
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/merge.c
@@ -0,0 +1,3628 @@
+/*<html><pre> -<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ merge.c
+ merges non-convex facets
+
+ see qh-merge.htm and merge.h
+
+ other modules call qh_premerge() and qh_postmerge()
+
+ the user may call qh_postmerge() to perform additional merges.
+
+ To remove deleted facets and vertices (qhull() in libqhull.c):
+ qh_partitionvisible(!qh_ALL, &numoutside); // visible_list, newfacet_list
+ qh_deletevisible(); // qh.visible_list
+ qh_resetlists(False, qh_RESETvisible); // qh.visible_list newvertex_list newfacet_list
+
+ assumes qh.CENTERtype= centrum
+
+ merges occur in qh_mergefacet and in qh_mergecycle
+ vertex->neighbors not set until the first merge occurs
+
+ Copyright (c) 1993-2015 C.B. Barber.
+ $Id: //main/2015/qhull/src/libqhull/merge.c#4 $$Change: 2064 $
+ $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
+*/
+
+#include "qhull_a.h"
+
+#ifndef qh_NOmerge
+
+/*===== functions(alphabetical after premerge and postmerge) ======*/
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="premerge">-</a>
+
+ qh_premerge( apex, maxcentrum )
+ pre-merge nonconvex facets in qh.newfacet_list for apex
+ maxcentrum defines coplanar and concave (qh_test_appendmerge)
+
+ returns:
+ deleted facets added to qh.visible_list with facet->visible set
+
+ notes:
+ uses globals, qh.MERGEexact, qh.PREmerge
+
+ design:
+ mark duplicate ridges in qh.newfacet_list
+ merge facet cycles in qh.newfacet_list
+ merge duplicate ridges and concave facets in qh.newfacet_list
+ check merged facet cycles for degenerate and redundant facets
+ merge degenerate and redundant facets
+ collect coplanar and concave facets
+ merge concave, coplanar, degenerate, and redundant facets
+*/
+void qh_premerge(vertexT *apex, realT maxcentrum, realT maxangle) {
+ boolT othermerge= False;
+ facetT *newfacet;
+
+ if (qh ZEROcentrum && qh_checkzero(!qh_ALL))
+ return;
+ trace2((qh ferr, 2008, "qh_premerge: premerge centrum %2.2g angle %2.2g for apex v%d facetlist f%d\n",
+ maxcentrum, maxangle, apex->id, getid_(qh newfacet_list)));
+ if (qh IStracing >= 4 && qh num_facets < 50)
+ qh_printlists();
+ qh centrum_radius= maxcentrum;
+ qh cos_max= maxangle;
+ qh degen_mergeset= qh_settemp(qh TEMPsize);
+ qh facet_mergeset= qh_settemp(qh TEMPsize);
+ if (qh hull_dim >=3) {
+ qh_mark_dupridges(qh newfacet_list); /* facet_mergeset */
+ qh_mergecycle_all(qh newfacet_list, &othermerge);
+ qh_forcedmerges(&othermerge /* qh.facet_mergeset */);
+ FORALLnew_facets { /* test samecycle merges */
+ if (!newfacet->simplicial && !newfacet->mergeridge)
+ qh_degen_redundant_neighbors(newfacet, NULL);
+ }
+ if (qh_merge_degenredundant())
+ othermerge= True;
+ }else /* qh.hull_dim == 2 */
+ qh_mergecycle_all(qh newfacet_list, &othermerge);
+ qh_flippedmerges(qh newfacet_list, &othermerge);
+ if (!qh MERGEexact || zzval_(Ztotmerge)) {
+ zinc_(Zpremergetot);
+ qh POSTmerging= False;
+ qh_getmergeset_initial(qh newfacet_list);
+ qh_all_merges(othermerge, False);
+ }
+ qh_settempfree(&qh facet_mergeset);
+ qh_settempfree(&qh degen_mergeset);
+} /* premerge */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="postmerge">-</a>
+
+ qh_postmerge( reason, maxcentrum, maxangle, vneighbors )
+ post-merge nonconvex facets as defined by maxcentrum and maxangle
+ 'reason' is for reporting progress
+ if vneighbors,
+ calls qh_test_vneighbors at end of qh_all_merge
+ if firstmerge,
+ calls qh_reducevertices before qh_getmergeset
+
+ returns:
+ if first call (qh.visible_list != qh.facet_list),
+ builds qh.facet_newlist, qh.newvertex_list
+ deleted facets added to qh.visible_list with facet->visible
+ qh.visible_list == qh.facet_list
+
+ notes:
+
+
+ design:
+ if first call
+ set qh.visible_list and qh.newfacet_list to qh.facet_list
+ add all facets to qh.newfacet_list
+ mark non-simplicial facets, facet->newmerge
+ set qh.newvertext_list to qh.vertex_list
+ add all vertices to qh.newvertex_list
+ if a pre-merge occured
+ set vertex->delridge {will retest the ridge}
+ if qh.MERGEexact
+ call qh_reducevertices()
+ if no pre-merging
+ merge flipped facets
+ determine non-convex facets
+ merge all non-convex facets
+*/
+void qh_postmerge(const char *reason, realT maxcentrum, realT maxangle,
+ boolT vneighbors) {
+ facetT *newfacet;
+ boolT othermerges= False;
+ vertexT *vertex;
+
+ if (qh REPORTfreq || qh IStracing) {
+ qh_buildtracing(NULL, NULL);
+ qh_printsummary(qh ferr);
+ if (qh PRINTstatistics)
+ qh_printallstatistics(qh ferr, "reason");
+ qh_fprintf(qh ferr, 8062, "\n%s with 'C%.2g' and 'A%.2g'\n",
+ reason, maxcentrum, maxangle);
+ }
+ trace2((qh ferr, 2009, "qh_postmerge: postmerge. test vneighbors? %d\n",
+ vneighbors));
+ qh centrum_radius= maxcentrum;
+ qh cos_max= maxangle;
+ qh POSTmerging= True;
+ qh degen_mergeset= qh_settemp(qh TEMPsize);
+ qh facet_mergeset= qh_settemp(qh TEMPsize);
+ if (qh visible_list != qh facet_list) { /* first call */
+ qh NEWfacets= True;
+ qh visible_list= qh newfacet_list= qh facet_list;
+ FORALLnew_facets {
+ newfacet->newfacet= True;
+ if (!newfacet->simplicial)
+ newfacet->newmerge= True;
+ zinc_(Zpostfacets);
+ }
+ qh newvertex_list= qh vertex_list;
+ FORALLvertices
+ vertex->newlist= True;
+ if (qh VERTEXneighbors) { /* a merge has occurred */
+ FORALLvertices
+ vertex->delridge= True; /* test for redundant, needed? */
+ if (qh MERGEexact) {
+ if (qh hull_dim <= qh_DIMreduceBuild)
+ qh_reducevertices(); /* was skipped during pre-merging */
+ }
+ }
+ if (!qh PREmerge && !qh MERGEexact)
+ qh_flippedmerges(qh newfacet_list, &othermerges);
+ }
+ qh_getmergeset_initial(qh newfacet_list);
+ qh_all_merges(False, vneighbors);
+ qh_settempfree(&qh facet_mergeset);
+ qh_settempfree(&qh degen_mergeset);
+} /* post_merge */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="all_merges">-</a>
+
+ qh_all_merges( othermerge, vneighbors )
+ merge all non-convex facets
+
+ set othermerge if already merged facets (for qh_reducevertices)
+ if vneighbors
+ tests vertex neighbors for convexity at end
+ qh.facet_mergeset lists the non-convex ridges in qh_newfacet_list
+ qh.degen_mergeset is defined
+ if qh.MERGEexact && !qh.POSTmerging,
+ does not merge coplanar facets
+
+ returns:
+ deleted facets added to qh.visible_list with facet->visible
+ deleted vertices added qh.delvertex_list with vertex->delvertex
+
+ notes:
+ unless !qh.MERGEindependent,
+ merges facets in independent sets
+ uses qh.newfacet_list as argument since merges call qh_removefacet()
+
+ design:
+ while merges occur
+ for each merge in qh.facet_mergeset
+ unless one of the facets was already merged in this pass
+ merge the facets
+ test merged facets for additional merges
+ add merges to qh.facet_mergeset
+ if vertices record neighboring facets
+ rename redundant vertices
+ update qh.facet_mergeset
+ if vneighbors ??
+ tests vertex neighbors for convexity at end
+*/
+void qh_all_merges(boolT othermerge, boolT vneighbors) {
+ facetT *facet1, *facet2;
+ mergeT *merge;
+ boolT wasmerge= True, isreduce;
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+ vertexT *vertex;
+ mergeType mergetype;
+ int numcoplanar=0, numconcave=0, numdegenredun= 0, numnewmerges= 0;
+
+ trace2((qh ferr, 2010, "qh_all_merges: starting to merge facets beginning from f%d\n",
+ getid_(qh newfacet_list)));
+ while (True) {
+ wasmerge= False;
+ while (qh_setsize(qh facet_mergeset)) {
+ while ((merge= (mergeT*)qh_setdellast(qh facet_mergeset))) {
+ facet1= merge->facet1;
+ facet2= merge->facet2;
+ mergetype= merge->type;
+ qh_memfree_(merge, (int)sizeof(mergeT), freelistp);
+ if (facet1->visible || facet2->visible) /*deleted facet*/
+ continue;
+ if ((facet1->newfacet && !facet1->tested)
+ || (facet2->newfacet && !facet2->tested)) {
+ if (qh MERGEindependent && mergetype <= MRGanglecoplanar)
+ continue; /* perform independent sets of merges */
+ }
+ qh_merge_nonconvex(facet1, facet2, mergetype);
+ numdegenredun += qh_merge_degenredundant();
+ numnewmerges++;
+ wasmerge= True;
+ if (mergetype == MRGconcave)
+ numconcave++;
+ else /* MRGcoplanar or MRGanglecoplanar */
+ numcoplanar++;
+ } /* while setdellast */
+ if (qh POSTmerging && qh hull_dim <= qh_DIMreduceBuild
+ && numnewmerges > qh_MAXnewmerges) {
+ numnewmerges= 0;
+ qh_reducevertices(); /* otherwise large post merges too slow */
+ }
+ qh_getmergeset(qh newfacet_list); /* facet_mergeset */
+ } /* while mergeset */
+ if (qh VERTEXneighbors) {
+ isreduce= False;
+ if (qh hull_dim >=4 && qh POSTmerging) {
+ FORALLvertices
+ vertex->delridge= True;
+ isreduce= True;
+ }
+ if ((wasmerge || othermerge) && (!qh MERGEexact || qh POSTmerging)
+ && qh hull_dim <= qh_DIMreduceBuild) {
+ othermerge= False;
+ isreduce= True;
+ }
+ if (isreduce) {
+ if (qh_reducevertices()) {
+ qh_getmergeset(qh newfacet_list); /* facet_mergeset */
+ continue;
+ }
+ }
+ }
+ if (vneighbors && qh_test_vneighbors(/* qh.newfacet_list */))
+ continue;
+ break;
+ } /* while (True) */
+ if (qh CHECKfrequently && !qh MERGEexact) {
+ qh old_randomdist= qh RANDOMdist;
+ qh RANDOMdist= False;
+ qh_checkconvex(qh newfacet_list, qh_ALGORITHMfault);
+ /* qh_checkconnect(); [this is slow and it changes the facet order] */
+ qh RANDOMdist= qh old_randomdist;
+ }
+ trace1((qh ferr, 1009, "qh_all_merges: merged %d coplanar facets %d concave facets and %d degen or redundant facets.\n",
+ numcoplanar, numconcave, numdegenredun));
+ if (qh IStracing >= 4 && qh num_facets < 50)
+ qh_printlists();
+} /* all_merges */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="appendmergeset">-</a>
+
+ qh_appendmergeset( facet, neighbor, mergetype, angle )
+ appends an entry to qh.facet_mergeset or qh.degen_mergeset
+
+ angle ignored if NULL or !qh.ANGLEmerge
+
+ returns:
+ merge appended to facet_mergeset or degen_mergeset
+ sets ->degenerate or ->redundant if degen_mergeset
+
+ see:
+ qh_test_appendmerge()
+
+ design:
+ allocate merge entry
+ if regular merge
+ append to qh.facet_mergeset
+ else if degenerate merge and qh.facet_mergeset is all degenerate
+ append to qh.degen_mergeset
+ else if degenerate merge
+ prepend to qh.degen_mergeset
+ else if redundant merge
+ append to qh.degen_mergeset
+*/
+void qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle) {
+ mergeT *merge, *lastmerge;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+
+ if (facet->redundant)
+ return;
+ if (facet->degenerate && mergetype == MRGdegen)
+ return;
+ qh_memalloc_((int)sizeof(mergeT), freelistp, merge, mergeT);
+ merge->facet1= facet;
+ merge->facet2= neighbor;
+ merge->type= mergetype;
+ if (angle && qh ANGLEmerge)
+ merge->angle= *angle;
+ if (mergetype < MRGdegen)
+ qh_setappend(&(qh facet_mergeset), merge);
+ else if (mergetype == MRGdegen) {
+ facet->degenerate= True;
+ if (!(lastmerge= (mergeT*)qh_setlast(qh degen_mergeset))
+ || lastmerge->type == MRGdegen)
+ qh_setappend(&(qh degen_mergeset), merge);
+ else
+ qh_setaddnth(&(qh degen_mergeset), 0, merge);
+ }else if (mergetype == MRGredundant) {
+ facet->redundant= True;
+ qh_setappend(&(qh degen_mergeset), merge);
+ }else /* mergetype == MRGmirror */ {
+ if (facet->redundant || neighbor->redundant) {
+ qh_fprintf(qh ferr, 6092, "qhull error (qh_appendmergeset): facet f%d or f%d is already a mirrored facet\n",
+ facet->id, neighbor->id);
+ qh_errexit2(qh_ERRqhull, facet, neighbor);
+ }
+ if (!qh_setequal(facet->vertices, neighbor->vertices)) {
+ qh_fprintf(qh ferr, 6093, "qhull error (qh_appendmergeset): mirrored facets f%d and f%d do not have the same vertices\n",
+ facet->id, neighbor->id);
+ qh_errexit2(qh_ERRqhull, facet, neighbor);
+ }
+ facet->redundant= True;
+ neighbor->redundant= True;
+ qh_setappend(&(qh degen_mergeset), merge);
+ }
+} /* appendmergeset */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="basevertices">-</a>
+
+ qh_basevertices( samecycle )
+ return temporary set of base vertices for samecycle
+ samecycle is first facet in the cycle
+ assumes apex is SETfirst_( samecycle->vertices )
+
+ returns:
+ vertices(settemp)
+ all ->seen are cleared
+
+ notes:
+ uses qh_vertex_visit;
+
+ design:
+ for each facet in samecycle
+ for each unseen vertex in facet->vertices
+ append to result
+*/
+setT *qh_basevertices(facetT *samecycle) {
+ facetT *same;
+ vertexT *apex, *vertex, **vertexp;
+ setT *vertices= qh_settemp(qh TEMPsize);
+
+ apex= SETfirstt_(samecycle->vertices, vertexT);
+ apex->visitid= ++qh vertex_visit;
+ FORALLsame_cycle_(samecycle) {
+ if (same->mergeridge)
+ continue;
+ FOREACHvertex_(same->vertices) {
+ if (vertex->visitid != qh vertex_visit) {
+ qh_setappend(&vertices, vertex);
+ vertex->visitid= qh vertex_visit;
+ vertex->seen= False;
+ }
+ }
+ }
+ trace4((qh ferr, 4019, "qh_basevertices: found %d vertices\n",
+ qh_setsize(vertices)));
+ return vertices;
+} /* basevertices */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="checkconnect">-</a>
+
+ qh_checkconnect()
+ check that new facets are connected
+ new facets are on qh.newfacet_list
+
+ notes:
+ this is slow and it changes the order of the facets
+ uses qh.visit_id
+
+ design:
+ move first new facet to end of qh.facet_list
+ for all newly appended facets
+ append unvisited neighbors to end of qh.facet_list
+ for all new facets
+ report error if unvisited
+*/
+void qh_checkconnect(void /* qh.newfacet_list */) {
+ facetT *facet, *newfacet, *errfacet= NULL, *neighbor, **neighborp;
+
+ facet= qh newfacet_list;
+ qh_removefacet(facet);
+ qh_appendfacet(facet);
+ facet->visitid= ++qh visit_id;
+ FORALLfacet_(facet) {
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid != qh visit_id) {
+ qh_removefacet(neighbor);
+ qh_appendfacet(neighbor);
+ neighbor->visitid= qh visit_id;
+ }
+ }
+ }
+ FORALLnew_facets {
+ if (newfacet->visitid == qh visit_id)
+ break;
+ qh_fprintf(qh ferr, 6094, "qhull error: f%d is not attached to the new facets\n",
+ newfacet->id);
+ errfacet= newfacet;
+ }
+ if (errfacet)
+ qh_errexit(qh_ERRqhull, errfacet, NULL);
+} /* checkconnect */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="checkzero">-</a>
+
+ qh_checkzero( testall )
+ check that facets are clearly convex for qh.DISTround with qh.MERGEexact
+
+ if testall,
+ test all facets for qh.MERGEexact post-merging
+ else
+ test qh.newfacet_list
+
+ if qh.MERGEexact,
+ allows coplanar ridges
+ skips convexity test while qh.ZEROall_ok
+
+ returns:
+ True if all facets !flipped, !dupridge, normal
+ if all horizon facets are simplicial
+ if all vertices are clearly below neighbor
+ if all opposite vertices of horizon are below
+ clears qh.ZEROall_ok if any problems or coplanar facets
+
+ notes:
+ uses qh.vertex_visit
+ horizon facets may define multiple new facets
+
+ design:
+ for all facets in qh.newfacet_list or qh.facet_list
+ check for flagged faults (flipped, etc.)
+ for all facets in qh.newfacet_list or qh.facet_list
+ for each neighbor of facet
+ skip horizon facets for qh.newfacet_list
+ test the opposite vertex
+ if qh.newfacet_list
+ test the other vertices in the facet's horizon facet
+*/
+boolT qh_checkzero(boolT testall) {
+ facetT *facet, *neighbor, **neighborp;
+ facetT *horizon, *facetlist;
+ int neighbor_i;
+ vertexT *vertex, **vertexp;
+ realT dist;
+
+ if (testall)
+ facetlist= qh facet_list;
+ else {
+ facetlist= qh newfacet_list;
+ FORALLfacet_(facetlist) {
+ horizon= SETfirstt_(facet->neighbors, facetT);
+ if (!horizon->simplicial)
+ goto LABELproblem;
+ if (facet->flipped || facet->dupridge || !facet->normal)
+ goto LABELproblem;
+ }
+ if (qh MERGEexact && qh ZEROall_ok) {
+ trace2((qh ferr, 2011, "qh_checkzero: skip convexity check until first pre-merge\n"));
+ return True;
+ }
+ }
+ FORALLfacet_(facetlist) {
+ qh vertex_visit++;
+ neighbor_i= 0;
+ horizon= NULL;
+ FOREACHneighbor_(facet) {
+ if (!neighbor_i && !testall) {
+ horizon= neighbor;
+ neighbor_i++;
+ continue; /* horizon facet tested in qh_findhorizon */
+ }
+ vertex= SETelemt_(facet->vertices, neighbor_i++, vertexT);
+ vertex->visitid= qh vertex_visit;
+ zzinc_(Zdistzero);
+ qh_distplane(vertex->point, neighbor, &dist);
+ if (dist >= -qh DISTround) {
+ qh ZEROall_ok= False;
+ if (!qh MERGEexact || testall || dist > qh DISTround)
+ goto LABELnonconvex;
+ }
+ }
+ if (!testall && horizon) {
+ FOREACHvertex_(horizon->vertices) {
+ if (vertex->visitid != qh vertex_visit) {
+ zzinc_(Zdistzero);
+ qh_distplane(vertex->point, facet, &dist);
+ if (dist >= -qh DISTround) {
+ qh ZEROall_ok= False;
+ if (!qh MERGEexact || dist > qh DISTround)
+ goto LABELnonconvex;
+ }
+ break;
+ }
+ }
+ }
+ }
+ trace2((qh ferr, 2012, "qh_checkzero: testall %d, facets are %s\n", testall,
+ (qh MERGEexact && !testall) ?
+ "not concave, flipped, or duplicate ridged" : "clearly convex"));
+ return True;
+
+ LABELproblem:
+ qh ZEROall_ok= False;
+ trace2((qh ferr, 2013, "qh_checkzero: facet f%d needs pre-merging\n",
+ facet->id));
+ return False;
+
+ LABELnonconvex:
+ trace2((qh ferr, 2014, "qh_checkzero: facet f%d and f%d are not clearly convex. v%d dist %.2g\n",
+ facet->id, neighbor->id, vertex->id, dist));
+ return False;
+} /* checkzero */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="compareangle">-</a>
+
+ qh_compareangle( angle1, angle2 )
+ used by qsort() to order merges by angle
+*/
+int qh_compareangle(const void *p1, const void *p2) {
+ const mergeT *a= *((mergeT *const*)p1), *b= *((mergeT *const*)p2);
+
+ return((a->angle > b->angle) ? 1 : -1);
+} /* compareangle */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="comparemerge">-</a>
+
+ qh_comparemerge( merge1, merge2 )
+ used by qsort() to order merges
+*/
+int qh_comparemerge(const void *p1, const void *p2) {
+ const mergeT *a= *((mergeT *const*)p1), *b= *((mergeT *const*)p2);
+
+ return(a->type - b->type);
+} /* comparemerge */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="comparevisit">-</a>
+
+ qh_comparevisit( vertex1, vertex2 )
+ used by qsort() to order vertices by their visitid
+*/
+int qh_comparevisit(const void *p1, const void *p2) {
+ const vertexT *a= *((vertexT *const*)p1), *b= *((vertexT *const*)p2);
+
+ return(a->visitid - b->visitid);
+} /* comparevisit */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="copynonconvex">-</a>
+
+ qh_copynonconvex( atridge )
+ set non-convex flag on other ridges (if any) between same neighbors
+
+ notes:
+ may be faster if use smaller ridge set
+
+ design:
+ for each ridge of atridge's top facet
+ if ridge shares the same neighbor
+ set nonconvex flag
+*/
+void qh_copynonconvex(ridgeT *atridge) {
+ facetT *facet, *otherfacet;
+ ridgeT *ridge, **ridgep;
+
+ facet= atridge->top;
+ otherfacet= atridge->bottom;
+ FOREACHridge_(facet->ridges) {
+ if (otherfacet == otherfacet_(ridge, facet) && ridge != atridge) {
+ ridge->nonconvex= True;
+ trace4((qh ferr, 4020, "qh_copynonconvex: moved nonconvex flag from r%d to r%d\n",
+ atridge->id, ridge->id));
+ break;
+ }
+ }
+} /* copynonconvex */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="degen_redundant_facet">-</a>
+
+ qh_degen_redundant_facet( facet )
+ check facet for degen. or redundancy
+
+ notes:
+ bumps vertex_visit
+ called if a facet was redundant but no longer is (qh_merge_degenredundant)
+ qh_appendmergeset() only appends first reference to facet (i.e., redundant)
+
+ see:
+ qh_degen_redundant_neighbors()
+
+ design:
+ test for redundant neighbor
+ test for degenerate facet
+*/
+void qh_degen_redundant_facet(facetT *facet) {
+ vertexT *vertex, **vertexp;
+ facetT *neighbor, **neighborp;
+
+ trace4((qh ferr, 4021, "qh_degen_redundant_facet: test facet f%d for degen/redundant\n",
+ facet->id));
+ FOREACHneighbor_(facet) {
+ qh vertex_visit++;
+ FOREACHvertex_(neighbor->vertices)
+ vertex->visitid= qh vertex_visit;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->visitid != qh vertex_visit)
+ break;
+ }
+ if (!vertex) {
+ qh_appendmergeset(facet, neighbor, MRGredundant, NULL);
+ trace2((qh ferr, 2015, "qh_degen_redundant_facet: f%d is contained in f%d. merge\n", facet->id, neighbor->id));
+ return;
+ }
+ }
+ if (qh_setsize(facet->neighbors) < qh hull_dim) {
+ qh_appendmergeset(facet, facet, MRGdegen, NULL);
+ trace2((qh ferr, 2016, "qh_degen_redundant_neighbors: f%d is degenerate.\n", facet->id));
+ }
+} /* degen_redundant_facet */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="degen_redundant_neighbors">-</a>
+
+ qh_degen_redundant_neighbors( facet, delfacet, )
+ append degenerate and redundant neighbors to facet_mergeset
+ if delfacet,
+ only checks neighbors of both delfacet and facet
+ also checks current facet for degeneracy
+
+ notes:
+ bumps vertex_visit
+ called for each qh_mergefacet() and qh_mergecycle()
+ merge and statistics occur in merge_nonconvex
+ qh_appendmergeset() only appends first reference to facet (i.e., redundant)
+ it appends redundant facets after degenerate ones
+
+ a degenerate facet has fewer than hull_dim neighbors
+ a redundant facet's vertices is a subset of its neighbor's vertices
+ tests for redundant merges first (appendmergeset is nop for others)
+ in a merge, only needs to test neighbors of merged facet
+
+ see:
+ qh_merge_degenredundant() and qh_degen_redundant_facet()
+
+ design:
+ test for degenerate facet
+ test for redundant neighbor
+ test for degenerate neighbor
+*/
+void qh_degen_redundant_neighbors(facetT *facet, facetT *delfacet) {
+ vertexT *vertex, **vertexp;
+ facetT *neighbor, **neighborp;
+ int size;
+
+ trace4((qh ferr, 4022, "qh_degen_redundant_neighbors: test neighbors of f%d with delfacet f%d\n",
+ facet->id, getid_(delfacet)));
+ if ((size= qh_setsize(facet->neighbors)) < qh hull_dim) {
+ qh_appendmergeset(facet, facet, MRGdegen, NULL);
+ trace2((qh ferr, 2017, "qh_degen_redundant_neighbors: f%d is degenerate with %d neighbors.\n", facet->id, size));
+ }
+ if (!delfacet)
+ delfacet= facet;
+ qh vertex_visit++;
+ FOREACHvertex_(facet->vertices)
+ vertex->visitid= qh vertex_visit;
+ FOREACHneighbor_(delfacet) {
+ /* uses early out instead of checking vertex count */
+ if (neighbor == facet)
+ continue;
+ FOREACHvertex_(neighbor->vertices) {
+ if (vertex->visitid != qh vertex_visit)
+ break;
+ }
+ if (!vertex) {
+ qh_appendmergeset(neighbor, facet, MRGredundant, NULL);
+ trace2((qh ferr, 2018, "qh_degen_redundant_neighbors: f%d is contained in f%d. merge\n", neighbor->id, facet->id));
+ }
+ }
+ FOREACHneighbor_(delfacet) { /* redundant merges occur first */
+ if (neighbor == facet)
+ continue;
+ if ((size= qh_setsize(neighbor->neighbors)) < qh hull_dim) {
+ qh_appendmergeset(neighbor, neighbor, MRGdegen, NULL);
+ trace2((qh ferr, 2019, "qh_degen_redundant_neighbors: f%d is degenerate with %d neighbors. Neighbor of f%d.\n", neighbor->id, size, facet->id));
+ }
+ }
+} /* degen_redundant_neighbors */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="find_newvertex">-</a>
+
+ qh_find_newvertex( oldvertex, vertices, ridges )
+ locate new vertex for renaming old vertex
+ vertices is a set of possible new vertices
+ vertices sorted by number of deleted ridges
+
+ returns:
+ newvertex or NULL
+ each ridge includes both vertex and oldvertex
+ vertices sorted by number of deleted ridges
+
+ notes:
+ modifies vertex->visitid
+ new vertex is in one of the ridges
+ renaming will not cause a duplicate ridge
+ renaming will minimize the number of deleted ridges
+ newvertex may not be adjacent in the dual (though unlikely)
+
+ design:
+ for each vertex in vertices
+ set vertex->visitid to number of references in ridges
+ remove unvisited vertices
+ set qh.vertex_visit above all possible values
+ sort vertices by number of references in ridges
+ add each ridge to qh.hash_table
+ for each vertex in vertices
+ look for a vertex that would not cause a duplicate ridge after a rename
+*/
+vertexT *qh_find_newvertex(vertexT *oldvertex, setT *vertices, setT *ridges) {
+ vertexT *vertex, **vertexp;
+ setT *newridges;
+ ridgeT *ridge, **ridgep;
+ int size, hashsize;
+ int hash;
+
+#ifndef qh_NOtrace
+ if (qh IStracing >= 4) {
+ qh_fprintf(qh ferr, 8063, "qh_find_newvertex: find new vertex for v%d from ",
+ oldvertex->id);
+ FOREACHvertex_(vertices)
+ qh_fprintf(qh ferr, 8064, "v%d ", vertex->id);
+ FOREACHridge_(ridges)
+ qh_fprintf(qh ferr, 8065, "r%d ", ridge->id);
+ qh_fprintf(qh ferr, 8066, "\n");
+ }
+#endif
+ FOREACHvertex_(vertices)
+ vertex->visitid= 0;
+ FOREACHridge_(ridges) {
+ FOREACHvertex_(ridge->vertices)
+ vertex->visitid++;
+ }
+ FOREACHvertex_(vertices) {
+ if (!vertex->visitid) {
+ qh_setdelnth(vertices, SETindex_(vertices,vertex));
+ vertexp--; /* repeat since deleted this vertex */
+ }
+ }
+ qh vertex_visit += (unsigned int)qh_setsize(ridges);
+ if (!qh_setsize(vertices)) {
+ trace4((qh ferr, 4023, "qh_find_newvertex: vertices not in ridges for v%d\n",
+ oldvertex->id));
+ return NULL;
+ }
+ qsort(SETaddr_(vertices, vertexT), (size_t)qh_setsize(vertices),
+ sizeof(vertexT *), qh_comparevisit);
+ /* can now use qh vertex_visit */
+ if (qh PRINTstatistics) {
+ size= qh_setsize(vertices);
+ zinc_(Zintersect);
+ zadd_(Zintersecttot, size);
+ zmax_(Zintersectmax, size);
+ }
+ hashsize= qh_newhashtable(qh_setsize(ridges));
+ FOREACHridge_(ridges)
+ qh_hashridge(qh hash_table, hashsize, ridge, oldvertex);
+ FOREACHvertex_(vertices) {
+ newridges= qh_vertexridges(vertex);
+ FOREACHridge_(newridges) {
+ if (qh_hashridge_find(qh hash_table, hashsize, ridge, vertex, oldvertex, &hash)) {
+ zinc_(Zdupridge);
+ break;
+ }
+ }
+ qh_settempfree(&newridges);
+ if (!ridge)
+ break; /* found a rename */
+ }
+ if (vertex) {
+ /* counted in qh_renamevertex */
+ trace2((qh ferr, 2020, "qh_find_newvertex: found v%d for old v%d from %d vertices and %d ridges.\n",
+ vertex->id, oldvertex->id, qh_setsize(vertices), qh_setsize(ridges)));
+ }else {
+ zinc_(Zfindfail);
+ trace0((qh ferr, 14, "qh_find_newvertex: no vertex for renaming v%d(all duplicated ridges) during p%d\n",
+ oldvertex->id, qh furthest_id));
+ }
+ qh_setfree(&qh hash_table);
+ return vertex;
+} /* find_newvertex */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="findbest_test">-</a>
+
+ qh_findbest_test( testcentrum, facet, neighbor, bestfacet, dist, mindist, maxdist )
+ test neighbor of facet for qh_findbestneighbor()
+ if testcentrum,
+ tests centrum (assumes it is defined)
+ else
+ tests vertices
+
+ returns:
+ if a better facet (i.e., vertices/centrum of facet closer to neighbor)
+ updates bestfacet, dist, mindist, and maxdist
+*/
+void qh_findbest_test(boolT testcentrum, facetT *facet, facetT *neighbor,
+ facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp) {
+ realT dist, mindist, maxdist;
+
+ if (testcentrum) {
+ zzinc_(Zbestdist);
+ qh_distplane(facet->center, neighbor, &dist);
+ dist *= qh hull_dim; /* estimate furthest vertex */
+ if (dist < 0) {
+ maxdist= 0;
+ mindist= dist;
+ dist= -dist;
+ }else {
+ mindist= 0;
+ maxdist= dist;
+ }
+ }else
+ dist= qh_getdistance(facet, neighbor, &mindist, &maxdist);
+ if (dist < *distp) {
+ *bestfacet= neighbor;
+ *mindistp= mindist;
+ *maxdistp= maxdist;
+ *distp= dist;
+ }
+} /* findbest_test */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="findbestneighbor">-</a>
+
+ qh_findbestneighbor( facet, dist, mindist, maxdist )
+ finds best neighbor (least dist) of a facet for merging
+
+ returns:
+ returns min and max distances and their max absolute value
+
+ notes:
+ error if qh_ASvoronoi
+ avoids merging old into new
+ assumes ridge->nonconvex only set on one ridge between a pair of facets
+ could use an early out predicate but not worth it
+
+ design:
+ if a large facet
+ will test centrum
+ else
+ will test vertices
+ if a large facet
+ test nonconvex neighbors for best merge
+ else
+ test all neighbors for the best merge
+ if testing centrum
+ get distance information
+*/
+facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT *maxdistp) {
+ facetT *neighbor, **neighborp, *bestfacet= NULL;
+ ridgeT *ridge, **ridgep;
+ boolT nonconvex= True, testcentrum= False;
+ int size= qh_setsize(facet->vertices);
+
+ if(qh CENTERtype==qh_ASvoronoi){
+ qh_fprintf(qh ferr, 6272, "qhull error: cannot call qh_findbestneighor for f%d while qh.CENTERtype is qh_ASvoronoi\n", facet->id);
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ *distp= REALmax;
+ if (size > qh_BESTcentrum2 * qh hull_dim + qh_BESTcentrum) {
+ testcentrum= True;
+ zinc_(Zbestcentrum);
+ if (!facet->center)
+ facet->center= qh_getcentrum(facet);
+ }
+ if (size > qh hull_dim + qh_BESTnonconvex) {
+ FOREACHridge_(facet->ridges) {
+ if (ridge->nonconvex) {
+ neighbor= otherfacet_(ridge, facet);
+ qh_findbest_test(testcentrum, facet, neighbor,
+ &bestfacet, distp, mindistp, maxdistp);
+ }
+ }
+ }
+ if (!bestfacet) {
+ nonconvex= False;
+ FOREACHneighbor_(facet)
+ qh_findbest_test(testcentrum, facet, neighbor,
+ &bestfacet, distp, mindistp, maxdistp);
+ }
+ if (!bestfacet) {
+ qh_fprintf(qh ferr, 6095, "qhull internal error (qh_findbestneighbor): no neighbors for f%d\n", facet->id);
+
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ if (testcentrum)
+ qh_getdistance(facet, bestfacet, mindistp, maxdistp);
+ trace3((qh ferr, 3002, "qh_findbestneighbor: f%d is best neighbor for f%d testcentrum? %d nonconvex? %d dist %2.2g min %2.2g max %2.2g\n",
+ bestfacet->id, facet->id, testcentrum, nonconvex, *distp, *mindistp, *maxdistp));
+ return(bestfacet);
+} /* findbestneighbor */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="flippedmerges">-</a>
+
+ qh_flippedmerges( facetlist, wasmerge )
+ merge flipped facets into best neighbor
+ assumes qh.facet_mergeset at top of temporary stack
+
+ returns:
+ no flipped facets on facetlist
+ sets wasmerge if merge occurred
+ degen/redundant merges passed through
+
+ notes:
+ othermerges not needed since qh.facet_mergeset is empty before & after
+ keep it in case of change
+
+ design:
+ append flipped facets to qh.facetmergeset
+ for each flipped merge
+ find best neighbor
+ merge facet into neighbor
+ merge degenerate and redundant facets
+ remove flipped merges from qh.facet_mergeset
+*/
+void qh_flippedmerges(facetT *facetlist, boolT *wasmerge) {
+ facetT *facet, *neighbor, *facet1;
+ realT dist, mindist, maxdist;
+ mergeT *merge, **mergep;
+ setT *othermerges;
+ int nummerge=0;
+
+ trace4((qh ferr, 4024, "qh_flippedmerges: begin\n"));
+ FORALLfacet_(facetlist) {
+ if (facet->flipped && !facet->visible)
+ qh_appendmergeset(facet, facet, MRGflip, NULL);
+ }
+ othermerges= qh_settemppop(); /* was facet_mergeset */
+ qh facet_mergeset= qh_settemp(qh TEMPsize);
+ qh_settemppush(othermerges);
+ FOREACHmerge_(othermerges) {
+ facet1= merge->facet1;
+ if (merge->type != MRGflip || facet1->visible)
+ continue;
+ if (qh TRACEmerge-1 == zzval_(Ztotmerge))
+ qhmem.IStracing= qh IStracing= qh TRACElevel;
+ neighbor= qh_findbestneighbor(facet1, &dist, &mindist, &maxdist);
+ trace0((qh ferr, 15, "qh_flippedmerges: merge flipped f%d into f%d dist %2.2g during p%d\n",
+ facet1->id, neighbor->id, dist, qh furthest_id));
+ qh_mergefacet(facet1, neighbor, &mindist, &maxdist, !qh_MERGEapex);
+ nummerge++;
+ if (qh PRINTstatistics) {
+ zinc_(Zflipped);
+ wadd_(Wflippedtot, dist);
+ wmax_(Wflippedmax, dist);
+ }
+ qh_merge_degenredundant();
+ }
+ FOREACHmerge_(othermerges) {
+ if (merge->facet1->visible || merge->facet2->visible)
+ qh_memfree(merge, (int)sizeof(mergeT));
+ else
+ qh_setappend(&qh facet_mergeset, merge);
+ }
+ qh_settempfree(&othermerges);
+ if (nummerge)
+ *wasmerge= True;
+ trace1((qh ferr, 1010, "qh_flippedmerges: merged %d flipped facets into a good neighbor\n", nummerge));
+} /* flippedmerges */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="forcedmerges">-</a>
+
+ qh_forcedmerges( wasmerge )
+ merge duplicated ridges
+
+ returns:
+ removes all duplicate ridges on facet_mergeset
+ wasmerge set if merge
+ qh.facet_mergeset may include non-forced merges(none for now)
+ qh.degen_mergeset includes degen/redun merges
+
+ notes:
+ duplicate ridges occur when the horizon is pinched,
+ i.e. a subridge occurs in more than two horizon ridges.
+ could rename vertices that pinch the horizon
+ assumes qh_merge_degenredundant() has not be called
+ othermerges isn't needed since facet_mergeset is empty afterwards
+ keep it in case of change
+
+ design:
+ for each duplicate ridge
+ find current facets by chasing f.replace links
+ check for wide merge due to duplicate ridge
+ determine best direction for facet
+ merge one facet into the other
+ remove duplicate ridges from qh.facet_mergeset
+*/
+void qh_forcedmerges(boolT *wasmerge) {
+ facetT *facet1, *facet2;
+ mergeT *merge, **mergep;
+ realT dist1, dist2, mindist1, mindist2, maxdist1, maxdist2;
+ setT *othermerges;
+ int nummerge=0, numflip=0;
+
+ if (qh TRACEmerge-1 == zzval_(Ztotmerge))
+ qhmem.IStracing= qh IStracing= qh TRACElevel;
+ trace4((qh ferr, 4025, "qh_forcedmerges: begin\n"));
+ othermerges= qh_settemppop(); /* was facet_mergeset */
+ qh facet_mergeset= qh_settemp(qh TEMPsize);
+ qh_settemppush(othermerges);
+ FOREACHmerge_(othermerges) {
+ if (merge->type != MRGridge)
+ continue;
+ if (qh TRACEmerge-1 == zzval_(Ztotmerge))
+ qhmem.IStracing= qh IStracing= qh TRACElevel;
+ facet1= merge->facet1;
+ facet2= merge->facet2;
+ while (facet1->visible) /* must exist, no qh_merge_degenredunant */
+ facet1= facet1->f.replace; /* previously merged facet */
+ while (facet2->visible)
+ facet2= facet2->f.replace; /* previously merged facet */
+ if (facet1 == facet2)
+ continue;
+ if (!qh_setin(facet2->neighbors, facet1)) {
+ qh_fprintf(qh ferr, 6096, "qhull internal error (qh_forcedmerges): f%d and f%d had a duplicate ridge but as f%d and f%d they are no longer neighbors\n",
+ merge->facet1->id, merge->facet2->id, facet1->id, facet2->id);
+ qh_errexit2(qh_ERRqhull, facet1, facet2);
+ }
+ dist1= qh_getdistance(facet1, facet2, &mindist1, &maxdist1);
+ dist2= qh_getdistance(facet2, facet1, &mindist2, &maxdist2);
+ qh_check_dupridge(facet1, dist1, facet2, dist2);
+ if (dist1 < dist2)
+ qh_mergefacet(facet1, facet2, &mindist1, &maxdist1, !qh_MERGEapex);
+ else {
+ qh_mergefacet(facet2, facet1, &mindist2, &maxdist2, !qh_MERGEapex);
+ dist1= dist2;
+ facet1= facet2;
+ }
+ if (facet1->flipped) {
+ zinc_(Zmergeflipdup);
+ numflip++;
+ }else
+ nummerge++;
+ if (qh PRINTstatistics) {
+ zinc_(Zduplicate);
+ wadd_(Wduplicatetot, dist1);
+ wmax_(Wduplicatemax, dist1);
+ }
+ }
+ FOREACHmerge_(othermerges) {
+ if (merge->type == MRGridge)
+ qh_memfree(merge, (int)sizeof(mergeT));
+ else
+ qh_setappend(&qh facet_mergeset, merge);
+ }
+ qh_settempfree(&othermerges);
+ if (nummerge)
+ *wasmerge= True;
+ trace1((qh ferr, 1011, "qh_forcedmerges: merged %d facets and %d flipped facets across duplicated ridges\n",
+ nummerge, numflip));
+} /* forcedmerges */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="getmergeset">-</a>
+
+ qh_getmergeset( facetlist )
+ determines nonconvex facets on facetlist
+ tests !tested ridges and nonconvex ridges of !tested facets
+
+ returns:
+ returns sorted qh.facet_mergeset of facet-neighbor pairs to be merged
+ all ridges tested
+
+ notes:
+ assumes no nonconvex ridges with both facets tested
+ uses facet->tested/ridge->tested to prevent duplicate tests
+ can not limit tests to modified ridges since the centrum changed
+ uses qh.visit_id
+
+ see:
+ qh_getmergeset_initial()
+
+ design:
+ for each facet on facetlist
+ for each ridge of facet
+ if untested ridge
+ test ridge for convexity
+ if non-convex
+ append ridge to qh.facet_mergeset
+ sort qh.facet_mergeset by angle
+*/
+void qh_getmergeset(facetT *facetlist) {
+ facetT *facet, *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+ int nummerges;
+
+ nummerges= qh_setsize(qh facet_mergeset);
+ trace4((qh ferr, 4026, "qh_getmergeset: started.\n"));
+ qh visit_id++;
+ FORALLfacet_(facetlist) {
+ if (facet->tested)
+ continue;
+ facet->visitid= qh visit_id;
+ facet->tested= True; /* must be non-simplicial due to merge */
+ FOREACHneighbor_(facet)
+ neighbor->seen= False;
+ FOREACHridge_(facet->ridges) {
+ if (ridge->tested && !ridge->nonconvex)
+ continue;
+ /* if tested & nonconvex, need to append merge */
+ neighbor= otherfacet_(ridge, facet);
+ if (neighbor->seen) {
+ ridge->tested= True;
+ ridge->nonconvex= False;
+ }else if (neighbor->visitid != qh visit_id) {
+ ridge->tested= True;
+ ridge->nonconvex= False;
+ neighbor->seen= True; /* only one ridge is marked nonconvex */
+ if (qh_test_appendmerge(facet, neighbor))
+ ridge->nonconvex= True;
+ }
+ }
+ }
+ nummerges= qh_setsize(qh facet_mergeset);
+ if (qh ANGLEmerge)
+ qsort(SETaddr_(qh facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_compareangle);
+ else
+ qsort(SETaddr_(qh facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_comparemerge);
+ if (qh POSTmerging) {
+ zadd_(Zmergesettot2, nummerges);
+ }else {
+ zadd_(Zmergesettot, nummerges);
+ zmax_(Zmergesetmax, nummerges);
+ }
+ trace2((qh ferr, 2021, "qh_getmergeset: %d merges found\n", nummerges));
+} /* getmergeset */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="getmergeset_initial">-</a>
+
+ qh_getmergeset_initial( facetlist )
+ determine initial qh.facet_mergeset for facets
+ tests all facet/neighbor pairs on facetlist
+
+ returns:
+ sorted qh.facet_mergeset with nonconvex ridges
+ sets facet->tested, ridge->tested, and ridge->nonconvex
+
+ notes:
+ uses visit_id, assumes ridge->nonconvex is False
+
+ see:
+ qh_getmergeset()
+
+ design:
+ for each facet on facetlist
+ for each untested neighbor of facet
+ test facet and neighbor for convexity
+ if non-convex
+ append merge to qh.facet_mergeset
+ mark one of the ridges as nonconvex
+ sort qh.facet_mergeset by angle
+*/
+void qh_getmergeset_initial(facetT *facetlist) {
+ facetT *facet, *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+ int nummerges;
+
+ qh visit_id++;
+ FORALLfacet_(facetlist) {
+ facet->visitid= qh visit_id;
+ facet->tested= True;
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid != qh visit_id) {
+ if (qh_test_appendmerge(facet, neighbor)) {
+ FOREACHridge_(neighbor->ridges) {
+ if (facet == otherfacet_(ridge, neighbor)) {
+ ridge->nonconvex= True;
+ break; /* only one ridge is marked nonconvex */
+ }
+ }
+ }
+ }
+ }
+ FOREACHridge_(facet->ridges)
+ ridge->tested= True;
+ }
+ nummerges= qh_setsize(qh facet_mergeset);
+ if (qh ANGLEmerge)
+ qsort(SETaddr_(qh facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_compareangle);
+ else
+ qsort(SETaddr_(qh facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_comparemerge);
+ if (qh POSTmerging) {
+ zadd_(Zmergeinittot2, nummerges);
+ }else {
+ zadd_(Zmergeinittot, nummerges);
+ zmax_(Zmergeinitmax, nummerges);
+ }
+ trace2((qh ferr, 2022, "qh_getmergeset_initial: %d merges found\n", nummerges));
+} /* getmergeset_initial */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="hashridge">-</a>
+
+ qh_hashridge( hashtable, hashsize, ridge, oldvertex )
+ add ridge to hashtable without oldvertex
+
+ notes:
+ assumes hashtable is large enough
+
+ design:
+ determine hash value for ridge without oldvertex
+ find next empty slot for ridge
+*/
+void qh_hashridge(setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex) {
+ int hash;
+ ridgeT *ridgeA;
+
+ hash= qh_gethash(hashsize, ridge->vertices, qh hull_dim-1, 0, oldvertex);
+ while (True) {
+ if (!(ridgeA= SETelemt_(hashtable, hash, ridgeT))) {
+ SETelem_(hashtable, hash)= ridge;
+ break;
+ }else if (ridgeA == ridge)
+ break;
+ if (++hash == hashsize)
+ hash= 0;
+ }
+} /* hashridge */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="hashridge_find">-</a>
+
+ qh_hashridge_find( hashtable, hashsize, ridge, vertex, oldvertex, hashslot )
+ returns matching ridge without oldvertex in hashtable
+ for ridge without vertex
+ if oldvertex is NULL
+ matches with any one skip
+
+ returns:
+ matching ridge or NULL
+ if no match,
+ if ridge already in table
+ hashslot= -1
+ else
+ hashslot= next NULL index
+
+ notes:
+ assumes hashtable is large enough
+ can't match ridge to itself
+
+ design:
+ get hash value for ridge without vertex
+ for each hashslot
+ return match if ridge matches ridgeA without oldvertex
+*/
+ridgeT *qh_hashridge_find(setT *hashtable, int hashsize, ridgeT *ridge,
+ vertexT *vertex, vertexT *oldvertex, int *hashslot) {
+ int hash;
+ ridgeT *ridgeA;
+
+ *hashslot= 0;
+ zinc_(Zhashridge);
+ hash= qh_gethash(hashsize, ridge->vertices, qh hull_dim-1, 0, vertex);
+ while ((ridgeA= SETelemt_(hashtable, hash, ridgeT))) {
+ if (ridgeA == ridge)
+ *hashslot= -1;
+ else {
+ zinc_(Zhashridgetest);
+ if (qh_setequal_except(ridge->vertices, vertex, ridgeA->vertices, oldvertex))
+ return ridgeA;
+ }
+ if (++hash == hashsize)
+ hash= 0;
+ }
+ if (!*hashslot)
+ *hashslot= hash;
+ return NULL;
+} /* hashridge_find */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="makeridges">-</a>
+
+ qh_makeridges( facet )
+ creates explicit ridges between simplicial facets
+
+ returns:
+ facet with ridges and without qh_MERGEridge
+ ->simplicial is False
+
+ notes:
+ allows qh_MERGEridge flag
+ uses existing ridges
+ duplicate neighbors ok if ridges already exist (qh_mergecycle_ridges)
+
+ see:
+ qh_mergecycle_ridges()
+
+ design:
+ look for qh_MERGEridge neighbors
+ mark neighbors that already have ridges
+ for each unprocessed neighbor of facet
+ create a ridge for neighbor and facet
+ if any qh_MERGEridge neighbors
+ delete qh_MERGEridge flags (already handled by qh_mark_dupridges)
+*/
+void qh_makeridges(facetT *facet) {
+ facetT *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+ int neighbor_i, neighbor_n;
+ boolT toporient, mergeridge= False;
+
+ if (!facet->simplicial)
+ return;
+ trace4((qh ferr, 4027, "qh_makeridges: make ridges for f%d\n", facet->id));
+ facet->simplicial= False;
+ FOREACHneighbor_(facet) {
+ if (neighbor == qh_MERGEridge)
+ mergeridge= True;
+ else
+ neighbor->seen= False;
+ }
+ FOREACHridge_(facet->ridges)
+ otherfacet_(ridge, facet)->seen= True;
+ FOREACHneighbor_i_(facet) {
+ if (neighbor == qh_MERGEridge)
+ continue; /* fixed by qh_mark_dupridges */
+ else if (!neighbor->seen) { /* no current ridges */
+ ridge= qh_newridge();
+ ridge->vertices= qh_setnew_delnthsorted(facet->vertices, qh hull_dim,
+ neighbor_i, 0);
+ toporient= facet->toporient ^ (neighbor_i & 0x1);
+ if (toporient) {
+ ridge->top= facet;
+ ridge->bottom= neighbor;
+ }else {
+ ridge->top= neighbor;
+ ridge->bottom= facet;
+ }
+#if 0 /* this also works */
+ flip= (facet->toporient ^ neighbor->toporient)^(skip1 & 0x1) ^ (skip2 & 0x1);
+ if (facet->toporient ^ (skip1 & 0x1) ^ flip) {
+ ridge->top= neighbor;
+ ridge->bottom= facet;
+ }else {
+ ridge->top= facet;
+ ridge->bottom= neighbor;
+ }
+#endif
+ qh_setappend(&(facet->ridges), ridge);
+ qh_setappend(&(neighbor->ridges), ridge);
+ }
+ }
+ if (mergeridge) {
+ while (qh_setdel(facet->neighbors, qh_MERGEridge))
+ ; /* delete each one */
+ }
+} /* makeridges */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mark_dupridges">-</a>
+
+ qh_mark_dupridges( facetlist )
+ add duplicated ridges to qh.facet_mergeset
+ facet->dupridge is true
+
+ returns:
+ duplicate ridges on qh.facet_mergeset
+ ->mergeridge/->mergeridge2 set
+ duplicate ridges marked by qh_MERGEridge and both sides facet->dupridge
+ no MERGEridges in neighbor sets
+
+ notes:
+ duplicate ridges occur when the horizon is pinched,
+ i.e. a subridge occurs in more than two horizon ridges.
+ could rename vertices that pinch the horizon (thus removing subridge)
+ uses qh.visit_id
+
+ design:
+ for all facets on facetlist
+ if facet contains a duplicate ridge
+ for each neighbor of facet
+ if neighbor marked qh_MERGEridge (one side of the merge)
+ set facet->mergeridge
+ else
+ if neighbor contains a duplicate ridge
+ and the back link is qh_MERGEridge
+ append duplicate ridge to qh.facet_mergeset
+ for each duplicate ridge
+ make ridge sets in preparation for merging
+ remove qh_MERGEridge from neighbor set
+ for each duplicate ridge
+ restore the missing neighbor from the neighbor set that was qh_MERGEridge
+ add the missing ridge for this neighbor
+*/
+void qh_mark_dupridges(facetT *facetlist) {
+ facetT *facet, *neighbor, **neighborp;
+ int nummerge=0;
+ mergeT *merge, **mergep;
+
+
+ trace4((qh ferr, 4028, "qh_mark_dupridges: identify duplicate ridges\n"));
+ FORALLfacet_(facetlist) {
+ if (facet->dupridge) {
+ FOREACHneighbor_(facet) {
+ if (neighbor == qh_MERGEridge) {
+ facet->mergeridge= True;
+ continue;
+ }
+ if (neighbor->dupridge
+ && !qh_setin(neighbor->neighbors, facet)) { /* qh_MERGEridge */
+ qh_appendmergeset(facet, neighbor, MRGridge, NULL);
+ facet->mergeridge2= True;
+ facet->mergeridge= True;
+ nummerge++;
+ }
+ }
+ }
+ }
+ if (!nummerge)
+ return;
+ FORALLfacet_(facetlist) { /* gets rid of qh_MERGEridge */
+ if (facet->mergeridge && !facet->mergeridge2)
+ qh_makeridges(facet);
+ }
+ FOREACHmerge_(qh facet_mergeset) { /* restore the missing neighbors */
+ if (merge->type == MRGridge) {
+ qh_setappend(&merge->facet2->neighbors, merge->facet1);
+ qh_makeridges(merge->facet1); /* and the missing ridges */
+ }
+ }
+ trace1((qh ferr, 1012, "qh_mark_dupridges: found %d duplicated ridges\n",
+ nummerge));
+} /* mark_dupridges */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="maydropneighbor">-</a>
+
+ qh_maydropneighbor( facet )
+ drop neighbor relationship if no ridge between facet and neighbor
+
+ returns:
+ neighbor sets updated
+ appends degenerate facets to qh.facet_mergeset
+
+ notes:
+ won't cause redundant facets since vertex inclusion is the same
+ may drop vertex and neighbor if no ridge
+ uses qh.visit_id
+
+ design:
+ visit all neighbors with ridges
+ for each unvisited neighbor of facet
+ delete neighbor and facet from the neighbor sets
+ if neighbor becomes degenerate
+ append neighbor to qh.degen_mergeset
+ if facet is degenerate
+ append facet to qh.degen_mergeset
+*/
+void qh_maydropneighbor(facetT *facet) {
+ ridgeT *ridge, **ridgep;
+ realT angledegen= qh_ANGLEdegen;
+ facetT *neighbor, **neighborp;
+
+ qh visit_id++;
+ trace4((qh ferr, 4029, "qh_maydropneighbor: test f%d for no ridges to a neighbor\n",
+ facet->id));
+ FOREACHridge_(facet->ridges) {
+ ridge->top->visitid= qh visit_id;
+ ridge->bottom->visitid= qh visit_id;
+ }
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid != qh visit_id) {
+ trace0((qh ferr, 17, "qh_maydropneighbor: facets f%d and f%d are no longer neighbors during p%d\n",
+ facet->id, neighbor->id, qh furthest_id));
+ zinc_(Zdropneighbor);
+ qh_setdel(facet->neighbors, neighbor);
+ neighborp--; /* repeat, deleted a neighbor */
+ qh_setdel(neighbor->neighbors, facet);
+ if (qh_setsize(neighbor->neighbors) < qh hull_dim) {
+ zinc_(Zdropdegen);
+ qh_appendmergeset(neighbor, neighbor, MRGdegen, &angledegen);
+ trace2((qh ferr, 2023, "qh_maydropneighbors: f%d is degenerate.\n", neighbor->id));
+ }
+ }
+ }
+ if (qh_setsize(facet->neighbors) < qh hull_dim) {
+ zinc_(Zdropdegen);
+ qh_appendmergeset(facet, facet, MRGdegen, &angledegen);
+ trace2((qh ferr, 2024, "qh_maydropneighbors: f%d is degenerate.\n", facet->id));
+ }
+} /* maydropneighbor */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="merge_degenredundant">-</a>
+
+ qh_merge_degenredundant()
+ merge all degenerate and redundant facets
+ qh.degen_mergeset contains merges from qh_degen_redundant_neighbors()
+
+ returns:
+ number of merges performed
+ resets facet->degenerate/redundant
+ if deleted (visible) facet has no neighbors
+ sets ->f.replace to NULL
+
+ notes:
+ redundant merges happen before degenerate ones
+ merging and renaming vertices can result in degen/redundant facets
+
+ design:
+ for each merge on qh.degen_mergeset
+ if redundant merge
+ if non-redundant facet merged into redundant facet
+ recheck facet for redundancy
+ else
+ merge redundant facet into other facet
+*/
+int qh_merge_degenredundant(void) {
+ int size;
+ mergeT *merge;
+ facetT *bestneighbor, *facet1, *facet2;
+ realT dist, mindist, maxdist;
+ vertexT *vertex, **vertexp;
+ int nummerges= 0;
+ mergeType mergetype;
+
+ while ((merge= (mergeT*)qh_setdellast(qh degen_mergeset))) {
+ facet1= merge->facet1;
+ facet2= merge->facet2;
+ mergetype= merge->type;
+ qh_memfree(merge, (int)sizeof(mergeT));
+ if (facet1->visible)
+ continue;
+ facet1->degenerate= False;
+ facet1->redundant= False;
+ if (qh TRACEmerge-1 == zzval_(Ztotmerge))
+ qhmem.IStracing= qh IStracing= qh TRACElevel;
+ if (mergetype == MRGredundant) {
+ zinc_(Zneighbor);
+ while (facet2->visible) {
+ if (!facet2->f.replace) {
+ qh_fprintf(qh ferr, 6097, "qhull internal error (qh_merge_degenredunant): f%d redundant but f%d has no replacement\n",
+ facet1->id, facet2->id);
+ qh_errexit2(qh_ERRqhull, facet1, facet2);
+ }
+ facet2= facet2->f.replace;
+ }
+ if (facet1 == facet2) {
+ qh_degen_redundant_facet(facet1); /* in case of others */
+ continue;
+ }
+ trace2((qh ferr, 2025, "qh_merge_degenredundant: facet f%d is contained in f%d, will merge\n",
+ facet1->id, facet2->id));
+ qh_mergefacet(facet1, facet2, NULL, NULL, !qh_MERGEapex);
+ /* merge distance is already accounted for */
+ nummerges++;
+ }else { /* mergetype == MRGdegen, other merges may have fixed */
+ if (!(size= qh_setsize(facet1->neighbors))) {
+ zinc_(Zdelfacetdup);
+ trace2((qh ferr, 2026, "qh_merge_degenredundant: facet f%d has no neighbors. Deleted\n", facet1->id));
+ qh_willdelete(facet1, NULL);
+ FOREACHvertex_(facet1->vertices) {
+ qh_setdel(vertex->neighbors, facet1);
+ if (!SETfirst_(vertex->neighbors)) {
+ zinc_(Zdegenvertex);
+ trace2((qh ferr, 2027, "qh_merge_degenredundant: deleted v%d because f%d has no neighbors\n",
+ vertex->id, facet1->id));
+ vertex->deleted= True;
+ qh_setappend(&qh del_vertices, vertex);
+ }
+ }
+ nummerges++;
+ }else if (size < qh hull_dim) {
+ bestneighbor= qh_findbestneighbor(facet1, &dist, &mindist, &maxdist);
+ trace2((qh ferr, 2028, "qh_merge_degenredundant: facet f%d has %d neighbors, merge into f%d dist %2.2g\n",
+ facet1->id, size, bestneighbor->id, dist));
+ qh_mergefacet(facet1, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
+ nummerges++;
+ if (qh PRINTstatistics) {
+ zinc_(Zdegen);
+ wadd_(Wdegentot, dist);
+ wmax_(Wdegenmax, dist);
+ }
+ } /* else, another merge fixed the degeneracy and redundancy tested */
+ }
+ }
+ return nummerges;
+} /* merge_degenredundant */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="merge_nonconvex">-</a>
+
+ qh_merge_nonconvex( facet1, facet2, mergetype )
+ remove non-convex ridge between facet1 into facet2
+ mergetype gives why the facet's are non-convex
+
+ returns:
+ merges one of the facets into the best neighbor
+
+ design:
+ if one of the facets is a new facet
+ prefer merging new facet into old facet
+ find best neighbors for both facets
+ merge the nearest facet into its best neighbor
+ update the statistics
+*/
+void qh_merge_nonconvex(facetT *facet1, facetT *facet2, mergeType mergetype) {
+ facetT *bestfacet, *bestneighbor, *neighbor;
+ realT dist, dist2, mindist, mindist2, maxdist, maxdist2;
+
+ if (qh TRACEmerge-1 == zzval_(Ztotmerge))
+ qhmem.IStracing= qh IStracing= qh TRACElevel;
+ trace3((qh ferr, 3003, "qh_merge_nonconvex: merge #%d for f%d and f%d type %d\n",
+ zzval_(Ztotmerge) + 1, facet1->id, facet2->id, mergetype));
+ /* concave or coplanar */
+ if (!facet1->newfacet) {
+ bestfacet= facet2; /* avoid merging old facet if new is ok */
+ facet2= facet1;
+ facet1= bestfacet;
+ }else
+ bestfacet= facet1;
+ bestneighbor= qh_findbestneighbor(bestfacet, &dist, &mindist, &maxdist);
+ neighbor= qh_findbestneighbor(facet2, &dist2, &mindist2, &maxdist2);
+ if (dist < dist2) {
+ qh_mergefacet(bestfacet, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
+ }else if (qh AVOIDold && !facet2->newfacet
+ && ((mindist >= -qh MAXcoplanar && maxdist <= qh max_outside)
+ || dist * 1.5 < dist2)) {
+ zinc_(Zavoidold);
+ wadd_(Wavoidoldtot, dist);
+ wmax_(Wavoidoldmax, dist);
+ trace2((qh ferr, 2029, "qh_merge_nonconvex: avoid merging old facet f%d dist %2.2g. Use f%d dist %2.2g instead\n",
+ facet2->id, dist2, facet1->id, dist2));
+ qh_mergefacet(bestfacet, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
+ }else {
+ qh_mergefacet(facet2, neighbor, &mindist2, &maxdist2, !qh_MERGEapex);
+ dist= dist2;
+ }
+ if (qh PRINTstatistics) {
+ if (mergetype == MRGanglecoplanar) {
+ zinc_(Zacoplanar);
+ wadd_(Wacoplanartot, dist);
+ wmax_(Wacoplanarmax, dist);
+ }else if (mergetype == MRGconcave) {
+ zinc_(Zconcave);
+ wadd_(Wconcavetot, dist);
+ wmax_(Wconcavemax, dist);
+ }else { /* MRGcoplanar */
+ zinc_(Zcoplanar);
+ wadd_(Wcoplanartot, dist);
+ wmax_(Wcoplanarmax, dist);
+ }
+ }
+} /* merge_nonconvex */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergecycle">-</a>
+
+ qh_mergecycle( samecycle, newfacet )
+ merge a cycle of facets starting at samecycle into a newfacet
+ newfacet is a horizon facet with ->normal
+ samecycle facets are simplicial from an apex
+
+ returns:
+ initializes vertex neighbors on first merge
+ samecycle deleted (placed on qh.visible_list)
+ newfacet at end of qh.facet_list
+ deleted vertices on qh.del_vertices
+
+ see:
+ qh_mergefacet()
+ called by qh_mergecycle_all() for multiple, same cycle facets
+
+ design:
+ make vertex neighbors if necessary
+ make ridges for newfacet
+ merge neighbor sets of samecycle into newfacet
+ merge ridges of samecycle into newfacet
+ merge vertex neighbors of samecycle into newfacet
+ make apex of samecycle the apex of newfacet
+ if newfacet wasn't a new facet
+ add its vertices to qh.newvertex_list
+ delete samecycle facets a make newfacet a newfacet
+*/
+void qh_mergecycle(facetT *samecycle, facetT *newfacet) {
+ int traceonce= False, tracerestore= 0;
+ vertexT *apex;
+#ifndef qh_NOtrace
+ facetT *same;
+#endif
+
+ if (newfacet->tricoplanar) {
+ if (!qh TRInormals) {
+ qh_fprintf(qh ferr, 6224, "Qhull internal error (qh_mergecycle): does not work for tricoplanar facets. Use option 'Q11'\n");
+ qh_errexit(qh_ERRqhull, newfacet, NULL);
+ }
+ newfacet->tricoplanar= False;
+ newfacet->keepcentrum= False;
+ }
+ if (!qh VERTEXneighbors)
+ qh_vertexneighbors();
+ zzinc_(Ztotmerge);
+ if (qh REPORTfreq2 && qh POSTmerging) {
+ if (zzval_(Ztotmerge) > qh mergereport + qh REPORTfreq2)
+ qh_tracemerging();
+ }
+#ifndef qh_NOtrace
+ if (qh TRACEmerge == zzval_(Ztotmerge))
+ qhmem.IStracing= qh IStracing= qh TRACElevel;
+ trace2((qh ferr, 2030, "qh_mergecycle: merge #%d for facets from cycle f%d into coplanar horizon f%d\n",
+ zzval_(Ztotmerge), samecycle->id, newfacet->id));
+ if (newfacet == qh tracefacet) {
+ tracerestore= qh IStracing;
+ qh IStracing= 4;
+ qh_fprintf(qh ferr, 8068, "qh_mergecycle: ========= trace merge %d of samecycle %d into trace f%d, furthest is p%d\n",
+ zzval_(Ztotmerge), samecycle->id, newfacet->id, qh furthest_id);
+ traceonce= True;
+ }
+ if (qh IStracing >=4) {
+ qh_fprintf(qh ferr, 8069, " same cycle:");
+ FORALLsame_cycle_(samecycle)
+ qh_fprintf(qh ferr, 8070, " f%d", same->id);
+ qh_fprintf(qh ferr, 8071, "\n");
+ }
+ if (qh IStracing >=4)
+ qh_errprint("MERGING CYCLE", samecycle, newfacet, NULL, NULL);
+#endif /* !qh_NOtrace */
+ apex= SETfirstt_(samecycle->vertices, vertexT);
+ qh_makeridges(newfacet);
+ qh_mergecycle_neighbors(samecycle, newfacet);
+ qh_mergecycle_ridges(samecycle, newfacet);
+ qh_mergecycle_vneighbors(samecycle, newfacet);
+ if (SETfirstt_(newfacet->vertices, vertexT) != apex)
+ qh_setaddnth(&newfacet->vertices, 0, apex); /* apex has last id */
+ if (!newfacet->newfacet)
+ qh_newvertices(newfacet->vertices);
+ qh_mergecycle_facets(samecycle, newfacet);
+ qh_tracemerge(samecycle, newfacet);
+ /* check for degen_redundant_neighbors after qh_forcedmerges() */
+ if (traceonce) {
+ qh_fprintf(qh ferr, 8072, "qh_mergecycle: end of trace facet\n");
+ qh IStracing= tracerestore;
+ }
+} /* mergecycle */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergecycle_all">-</a>
+
+ qh_mergecycle_all( facetlist, wasmerge )
+ merge all samecycles of coplanar facets into horizon
+ don't merge facets with ->mergeridge (these already have ->normal)
+ all facets are simplicial from apex
+ all facet->cycledone == False
+
+ returns:
+ all newfacets merged into coplanar horizon facets
+ deleted vertices on qh.del_vertices
+ sets wasmerge if any merge
+
+ see:
+ calls qh_mergecycle for multiple, same cycle facets
+
+ design:
+ for each facet on facetlist
+ skip facets with duplicate ridges and normals
+ check that facet is in a samecycle (->mergehorizon)
+ if facet only member of samecycle
+ sets vertex->delridge for all vertices except apex
+ merge facet into horizon
+ else
+ mark all facets in samecycle
+ remove facets with duplicate ridges from samecycle
+ merge samecycle into horizon (deletes facets from facetlist)
+*/
+void qh_mergecycle_all(facetT *facetlist, boolT *wasmerge) {
+ facetT *facet, *same, *prev, *horizon;
+ facetT *samecycle= NULL, *nextfacet, *nextsame;
+ vertexT *apex, *vertex, **vertexp;
+ int cycles=0, total=0, facets, nummerge;
+
+ trace2((qh ferr, 2031, "qh_mergecycle_all: begin\n"));
+ for (facet= facetlist; facet && (nextfacet= facet->next); facet= nextfacet) {
+ if (facet->normal)
+ continue;
+ if (!facet->mergehorizon) {
+ qh_fprintf(qh ferr, 6225, "Qhull internal error (qh_mergecycle_all): f%d without normal\n", facet->id);
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ horizon= SETfirstt_(facet->neighbors, facetT);
+ if (facet->f.samecycle == facet) {
+ zinc_(Zonehorizon);
+ /* merge distance done in qh_findhorizon */
+ apex= SETfirstt_(facet->vertices, vertexT);
+ FOREACHvertex_(facet->vertices) {
+ if (vertex != apex)
+ vertex->delridge= True;
+ }
+ horizon->f.newcycle= NULL;
+ qh_mergefacet(facet, horizon, NULL, NULL, qh_MERGEapex);
+ }else {
+ samecycle= facet;
+ facets= 0;
+ prev= facet;
+ for (same= facet->f.samecycle; same; /* FORALLsame_cycle_(facet) */
+ same= (same == facet ? NULL :nextsame)) { /* ends at facet */
+ nextsame= same->f.samecycle;
+ if (same->cycledone || same->visible)
+ qh_infiniteloop(same);
+ same->cycledone= True;
+ if (same->normal) {
+ prev->f.samecycle= same->f.samecycle; /* unlink ->mergeridge */
+ same->f.samecycle= NULL;
+ }else {
+ prev= same;
+ facets++;
+ }
+ }
+ while (nextfacet && nextfacet->cycledone) /* will delete samecycle */
+ nextfacet= nextfacet->next;
+ horizon->f.newcycle= NULL;
+ qh_mergecycle(samecycle, horizon);
+ nummerge= horizon->nummerge + facets;
+ if (nummerge > qh_MAXnummerge)
+ horizon->nummerge= qh_MAXnummerge;
+ else
+ horizon->nummerge= (short unsigned int)nummerge;
+ zzinc_(Zcyclehorizon);
+ total += facets;
+ zzadd_(Zcyclefacettot, facets);
+ zmax_(Zcyclefacetmax, facets);
+ }
+ cycles++;
+ }
+ if (cycles)
+ *wasmerge= True;
+ trace1((qh ferr, 1013, "qh_mergecycle_all: merged %d same cycles or facets into coplanar horizons\n", cycles));
+} /* mergecycle_all */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergecycle_facets">-</a>
+
+ qh_mergecycle_facets( samecycle, newfacet )
+ finish merge of samecycle into newfacet
+
+ returns:
+ samecycle prepended to visible_list for later deletion and partitioning
+ each facet->f.replace == newfacet
+
+ newfacet moved to end of qh.facet_list
+ makes newfacet a newfacet (get's facet1->id if it was old)
+ sets newfacet->newmerge
+ clears newfacet->center (unless merging into a large facet)
+ clears newfacet->tested and ridge->tested for facet1
+
+ adds neighboring facets to facet_mergeset if redundant or degenerate
+
+ design:
+ make newfacet a new facet and set its flags
+ move samecycle facets to qh.visible_list for later deletion
+ unless newfacet is large
+ remove its centrum
+*/
+void qh_mergecycle_facets(facetT *samecycle, facetT *newfacet) {
+ facetT *same, *next;
+
+ trace4((qh ferr, 4030, "qh_mergecycle_facets: make newfacet new and samecycle deleted\n"));
+ qh_removefacet(newfacet); /* append as a newfacet to end of qh facet_list */
+ qh_appendfacet(newfacet);
+ newfacet->newfacet= True;
+ newfacet->simplicial= False;
+ newfacet->newmerge= True;
+
+ for (same= samecycle->f.samecycle; same; same= (same == samecycle ? NULL : next)) {
+ next= same->f.samecycle; /* reused by willdelete */
+ qh_willdelete(same, newfacet);
+ }
+ if (newfacet->center
+ && qh_setsize(newfacet->vertices) <= qh hull_dim + qh_MAXnewcentrum) {
+ qh_memfree(newfacet->center, qh normal_size);
+ newfacet->center= NULL;
+ }
+ trace3((qh ferr, 3004, "qh_mergecycle_facets: merged facets from cycle f%d into f%d\n",
+ samecycle->id, newfacet->id));
+} /* mergecycle_facets */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergecycle_neighbors">-</a>
+
+ qh_mergecycle_neighbors( samecycle, newfacet )
+ add neighbors for samecycle facets to newfacet
+
+ returns:
+ newfacet with updated neighbors and vice-versa
+ newfacet has ridges
+ all neighbors of newfacet marked with qh.visit_id
+ samecycle facets marked with qh.visit_id-1
+ ridges updated for simplicial neighbors of samecycle with a ridge
+
+ notes:
+ assumes newfacet not in samecycle
+ usually, samecycle facets are new, simplicial facets without internal ridges
+ not so if horizon facet is coplanar to two different samecycles
+
+ see:
+ qh_mergeneighbors()
+
+ design:
+ check samecycle
+ delete neighbors from newfacet that are also in samecycle
+ for each neighbor of a facet in samecycle
+ if neighbor is simplicial
+ if first visit
+ move the neighbor relation to newfacet
+ update facet links for its ridges
+ else
+ make ridges for neighbor
+ remove samecycle reference
+ else
+ update neighbor sets
+*/
+void qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet) {
+ facetT *same, *neighbor, **neighborp;
+ int delneighbors= 0, newneighbors= 0;
+ unsigned int samevisitid;
+ ridgeT *ridge, **ridgep;
+
+ samevisitid= ++qh visit_id;
+ FORALLsame_cycle_(samecycle) {
+ if (same->visitid == samevisitid || same->visible)
+ qh_infiniteloop(samecycle);
+ same->visitid= samevisitid;
+ }
+ newfacet->visitid= ++qh visit_id;
+ trace4((qh ferr, 4031, "qh_mergecycle_neighbors: delete shared neighbors from newfacet\n"));
+ FOREACHneighbor_(newfacet) {
+ if (neighbor->visitid == samevisitid) {
+ SETref_(neighbor)= NULL; /* samecycle neighbors deleted */
+ delneighbors++;
+ }else
+ neighbor->visitid= qh visit_id;
+ }
+ qh_setcompact(newfacet->neighbors);
+
+ trace4((qh ferr, 4032, "qh_mergecycle_neighbors: update neighbors\n"));
+ FORALLsame_cycle_(samecycle) {
+ FOREACHneighbor_(same) {
+ if (neighbor->visitid == samevisitid)
+ continue;
+ if (neighbor->simplicial) {
+ if (neighbor->visitid != qh visit_id) {
+ qh_setappend(&newfacet->neighbors, neighbor);
+ qh_setreplace(neighbor->neighbors, same, newfacet);
+ newneighbors++;
+ neighbor->visitid= qh visit_id;
+ FOREACHridge_(neighbor->ridges) { /* update ridge in case of qh_makeridges */
+ if (ridge->top == same) {
+ ridge->top= newfacet;
+ break;
+ }else if (ridge->bottom == same) {
+ ridge->bottom= newfacet;
+ break;
+ }
+ }
+ }else {
+ qh_makeridges(neighbor);
+ qh_setdel(neighbor->neighbors, same);
+ /* same can't be horizon facet for neighbor */
+ }
+ }else { /* non-simplicial neighbor */
+ qh_setdel(neighbor->neighbors, same);
+ if (neighbor->visitid != qh visit_id) {
+ qh_setappend(&neighbor->neighbors, newfacet);
+ qh_setappend(&newfacet->neighbors, neighbor);
+ neighbor->visitid= qh visit_id;
+ newneighbors++;
+ }
+ }
+ }
+ }
+ trace2((qh ferr, 2032, "qh_mergecycle_neighbors: deleted %d neighbors and added %d\n",
+ delneighbors, newneighbors));
+} /* mergecycle_neighbors */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergecycle_ridges">-</a>
+
+ qh_mergecycle_ridges( samecycle, newfacet )
+ add ridges/neighbors for facets in samecycle to newfacet
+ all new/old neighbors of newfacet marked with qh.visit_id
+ facets in samecycle marked with qh.visit_id-1
+ newfacet marked with qh.visit_id
+
+ returns:
+ newfacet has merged ridges
+
+ notes:
+ ridge already updated for simplicial neighbors of samecycle with a ridge
+
+ see:
+ qh_mergeridges()
+ qh_makeridges()
+
+ design:
+ remove ridges between newfacet and samecycle
+ for each facet in samecycle
+ for each ridge in facet
+ update facet pointers in ridge
+ skip ridges processed in qh_mergecycle_neighors
+ free ridges between newfacet and samecycle
+ free ridges between facets of samecycle (on 2nd visit)
+ append remaining ridges to newfacet
+ if simpilicial facet
+ for each neighbor of facet
+ if simplicial facet
+ and not samecycle facet or newfacet
+ make ridge between neighbor and newfacet
+*/
+void qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet) {
+ facetT *same, *neighbor= NULL;
+ int numold=0, numnew=0;
+ int neighbor_i, neighbor_n;
+ unsigned int samevisitid;
+ ridgeT *ridge, **ridgep;
+ boolT toporient;
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+
+ trace4((qh ferr, 4033, "qh_mergecycle_ridges: delete shared ridges from newfacet\n"));
+ samevisitid= qh visit_id -1;
+ FOREACHridge_(newfacet->ridges) {
+ neighbor= otherfacet_(ridge, newfacet);
+ if (neighbor->visitid == samevisitid)
+ SETref_(ridge)= NULL; /* ridge free'd below */
+ }
+ qh_setcompact(newfacet->ridges);
+
+ trace4((qh ferr, 4034, "qh_mergecycle_ridges: add ridges to newfacet\n"));
+ FORALLsame_cycle_(samecycle) {
+ FOREACHridge_(same->ridges) {
+ if (ridge->top == same) {
+ ridge->top= newfacet;
+ neighbor= ridge->bottom;
+ }else if (ridge->bottom == same) {
+ ridge->bottom= newfacet;
+ neighbor= ridge->top;
+ }else if (ridge->top == newfacet || ridge->bottom == newfacet) {
+ qh_setappend(&newfacet->ridges, ridge);
+ numold++; /* already set by qh_mergecycle_neighbors */
+ continue;
+ }else {
+ qh_fprintf(qh ferr, 6098, "qhull internal error (qh_mergecycle_ridges): bad ridge r%d\n", ridge->id);
+ qh_errexit(qh_ERRqhull, NULL, ridge);
+ }
+ if (neighbor == newfacet) {
+ qh_setfree(&(ridge->vertices));
+ qh_memfree_(ridge, (int)sizeof(ridgeT), freelistp);
+ numold++;
+ }else if (neighbor->visitid == samevisitid) {
+ qh_setdel(neighbor->ridges, ridge);
+ qh_setfree(&(ridge->vertices));
+ qh_memfree_(ridge, (int)sizeof(ridgeT), freelistp);
+ numold++;
+ }else {
+ qh_setappend(&newfacet->ridges, ridge);
+ numold++;
+ }
+ }
+ if (same->ridges)
+ qh_settruncate(same->ridges, 0);
+ if (!same->simplicial)
+ continue;
+ FOREACHneighbor_i_(same) { /* note: !newfact->simplicial */
+ if (neighbor->visitid != samevisitid && neighbor->simplicial) {
+ ridge= qh_newridge();
+ ridge->vertices= qh_setnew_delnthsorted(same->vertices, qh hull_dim,
+ neighbor_i, 0);
+ toporient= same->toporient ^ (neighbor_i & 0x1);
+ if (toporient) {
+ ridge->top= newfacet;
+ ridge->bottom= neighbor;
+ }else {
+ ridge->top= neighbor;
+ ridge->bottom= newfacet;
+ }
+ qh_setappend(&(newfacet->ridges), ridge);
+ qh_setappend(&(neighbor->ridges), ridge);
+ numnew++;
+ }
+ }
+ }
+
+ trace2((qh ferr, 2033, "qh_mergecycle_ridges: found %d old ridges and %d new ones\n",
+ numold, numnew));
+} /* mergecycle_ridges */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergecycle_vneighbors">-</a>
+
+ qh_mergecycle_vneighbors( samecycle, newfacet )
+ create vertex neighbors for newfacet from vertices of facets in samecycle
+ samecycle marked with visitid == qh.visit_id - 1
+
+ returns:
+ newfacet vertices with updated neighbors
+ marks newfacet with qh.visit_id-1
+ deletes vertices that are merged away
+ sets delridge on all vertices (faster here than in mergecycle_ridges)
+
+ see:
+ qh_mergevertex_neighbors()
+
+ design:
+ for each vertex of samecycle facet
+ set vertex->delridge
+ delete samecycle facets from vertex neighbors
+ append newfacet to vertex neighbors
+ if vertex only in newfacet
+ delete it from newfacet
+ add it to qh.del_vertices for later deletion
+*/
+void qh_mergecycle_vneighbors(facetT *samecycle, facetT *newfacet) {
+ facetT *neighbor, **neighborp;
+ unsigned int mergeid;
+ vertexT *vertex, **vertexp, *apex;
+ setT *vertices;
+
+ trace4((qh ferr, 4035, "qh_mergecycle_vneighbors: update vertex neighbors for newfacet\n"));
+ mergeid= qh visit_id - 1;
+ newfacet->visitid= mergeid;
+ vertices= qh_basevertices(samecycle); /* temp */
+ apex= SETfirstt_(samecycle->vertices, vertexT);
+ qh_setappend(&vertices, apex);
+ FOREACHvertex_(vertices) {
+ vertex->delridge= True;
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid == mergeid)
+ SETref_(neighbor)= NULL;
+ }
+ qh_setcompact(vertex->neighbors);
+ qh_setappend(&vertex->neighbors, newfacet);
+ if (!SETsecond_(vertex->neighbors)) {
+ zinc_(Zcyclevertex);
+ trace2((qh ferr, 2034, "qh_mergecycle_vneighbors: deleted v%d when merging cycle f%d into f%d\n",
+ vertex->id, samecycle->id, newfacet->id));
+ qh_setdelsorted(newfacet->vertices, vertex);
+ vertex->deleted= True;
+ qh_setappend(&qh del_vertices, vertex);
+ }
+ }
+ qh_settempfree(&vertices);
+ trace3((qh ferr, 3005, "qh_mergecycle_vneighbors: merged vertices from cycle f%d into f%d\n",
+ samecycle->id, newfacet->id));
+} /* mergecycle_vneighbors */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergefacet">-</a>
+
+ qh_mergefacet( facet1, facet2, mindist, maxdist, mergeapex )
+ merges facet1 into facet2
+ mergeapex==qh_MERGEapex if merging new facet into coplanar horizon
+
+ returns:
+ qh.max_outside and qh.min_vertex updated
+ initializes vertex neighbors on first merge
+
+ returns:
+ facet2 contains facet1's vertices, neighbors, and ridges
+ facet2 moved to end of qh.facet_list
+ makes facet2 a newfacet
+ sets facet2->newmerge set
+ clears facet2->center (unless merging into a large facet)
+ clears facet2->tested and ridge->tested for facet1
+
+ facet1 prepended to visible_list for later deletion and partitioning
+ facet1->f.replace == facet2
+
+ adds neighboring facets to facet_mergeset if redundant or degenerate
+
+ notes:
+ mindist/maxdist may be NULL (only if both NULL)
+ traces merge if fmax_(maxdist,-mindist) > TRACEdist
+
+ see:
+ qh_mergecycle()
+
+ design:
+ trace merge and check for degenerate simplex
+ make ridges for both facets
+ update qh.max_outside, qh.max_vertex, qh.min_vertex
+ update facet2->maxoutside and keepcentrum
+ update facet2->nummerge
+ update tested flags for facet2
+ if facet1 is simplicial
+ merge facet1 into facet2
+ else
+ merge facet1's neighbors into facet2
+ merge facet1's ridges into facet2
+ merge facet1's vertices into facet2
+ merge facet1's vertex neighbors into facet2
+ add facet2's vertices to qh.new_vertexlist
+ unless qh_MERGEapex
+ test facet2 for degenerate or redundant neighbors
+ move facet1 to qh.visible_list for later deletion
+ move facet2 to end of qh.newfacet_list
+*/
+void qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex) {
+ boolT traceonce= False;
+ vertexT *vertex, **vertexp;
+ int tracerestore=0, nummerge;
+
+ if (facet1->tricoplanar || facet2->tricoplanar) {
+ if (!qh TRInormals) {
+ qh_fprintf(qh ferr, 6226, "Qhull internal error (qh_mergefacet): does not work for tricoplanar facets. Use option 'Q11'\n");
+ qh_errexit2(qh_ERRqhull, facet1, facet2);
+ }
+ if (facet2->tricoplanar) {
+ facet2->tricoplanar= False;
+ facet2->keepcentrum= False;
+ }
+ }
+ zzinc_(Ztotmerge);
+ if (qh REPORTfreq2 && qh POSTmerging) {
+ if (zzval_(Ztotmerge) > qh mergereport + qh REPORTfreq2)
+ qh_tracemerging();
+ }
+#ifndef qh_NOtrace
+ if (qh build_cnt >= qh RERUN) {
+ if (mindist && (-*mindist > qh TRACEdist || *maxdist > qh TRACEdist)) {
+ tracerestore= 0;
+ qh IStracing= qh TRACElevel;
+ traceonce= True;
+ qh_fprintf(qh ferr, 8075, "qh_mergefacet: ========= trace wide merge #%d(%2.2g) for f%d into f%d, last point was p%d\n", zzval_(Ztotmerge),
+ fmax_(-*mindist, *maxdist), facet1->id, facet2->id, qh furthest_id);
+ }else if (facet1 == qh tracefacet || facet2 == qh tracefacet) {
+ tracerestore= qh IStracing;
+ qh IStracing= 4;
+ traceonce= True;
+ qh_fprintf(qh ferr, 8076, "qh_mergefacet: ========= trace merge #%d involving f%d, furthest is p%d\n",
+ zzval_(Ztotmerge), qh tracefacet_id, qh furthest_id);
+ }
+ }
+ if (qh IStracing >= 2) {
+ realT mergemin= -2;
+ realT mergemax= -2;
+
+ if (mindist) {
+ mergemin= *mindist;
+ mergemax= *maxdist;
+ }
+ qh_fprintf(qh ferr, 8077, "qh_mergefacet: #%d merge f%d into f%d, mindist= %2.2g, maxdist= %2.2g\n",
+ zzval_(Ztotmerge), facet1->id, facet2->id, mergemin, mergemax);
+ }
+#endif /* !qh_NOtrace */
+ if (facet1 == facet2 || facet1->visible || facet2->visible) {
+ qh_fprintf(qh ferr, 6099, "qhull internal error (qh_mergefacet): either f%d and f%d are the same or one is a visible facet\n",
+ facet1->id, facet2->id);
+ qh_errexit2(qh_ERRqhull, facet1, facet2);
+ }
+ if (qh num_facets - qh num_visible <= qh hull_dim + 1) {
+ qh_fprintf(qh ferr, 6227, "\n\
+qhull precision error: Only %d facets remain. Can not merge another\n\
+pair. The input is too degenerate or the convexity constraints are\n\
+too strong.\n", qh hull_dim+1);
+ if (qh hull_dim >= 5 && !qh MERGEexact)
+ qh_fprintf(qh ferr, 8079, "Option 'Qx' may avoid this problem.\n");
+ qh_errexit(qh_ERRprec, NULL, NULL);
+ }
+ if (!qh VERTEXneighbors)
+ qh_vertexneighbors();
+ qh_makeridges(facet1);
+ qh_makeridges(facet2);
+ if (qh IStracing >=4)
+ qh_errprint("MERGING", facet1, facet2, NULL, NULL);
+ if (mindist) {
+ maximize_(qh max_outside, *maxdist);
+ maximize_(qh max_vertex, *maxdist);
+#if qh_MAXoutside
+ maximize_(facet2->maxoutside, *maxdist);
+#endif
+ minimize_(qh min_vertex, *mindist);
+ if (!facet2->keepcentrum
+ && (*maxdist > qh WIDEfacet || *mindist < -qh WIDEfacet)) {
+ facet2->keepcentrum= True;
+ zinc_(Zwidefacet);
+ }
+ }
+ nummerge= facet1->nummerge + facet2->nummerge + 1;
+ if (nummerge >= qh_MAXnummerge)
+ facet2->nummerge= qh_MAXnummerge;
+ else
+ facet2->nummerge= (short unsigned int)nummerge;
+ facet2->newmerge= True;
+ facet2->dupridge= False;
+ qh_updatetested(facet1, facet2);
+ if (qh hull_dim > 2 && qh_setsize(facet1->vertices) == qh hull_dim)
+ qh_mergesimplex(facet1, facet2, mergeapex);
+ else {
+ qh vertex_visit++;
+ FOREACHvertex_(facet2->vertices)
+ vertex->visitid= qh vertex_visit;
+ if (qh hull_dim == 2)
+ qh_mergefacet2d(facet1, facet2);
+ else {
+ qh_mergeneighbors(facet1, facet2);
+ qh_mergevertices(facet1->vertices, &facet2->vertices);
+ }
+ qh_mergeridges(facet1, facet2);
+ qh_mergevertex_neighbors(facet1, facet2);
+ if (!facet2->newfacet)
+ qh_newvertices(facet2->vertices);
+ }
+ if (!mergeapex)
+ qh_degen_redundant_neighbors(facet2, facet1);
+ if (facet2->coplanar || !facet2->newfacet) {
+ zinc_(Zmergeintohorizon);
+ }else if (!facet1->newfacet && facet2->newfacet) {
+ zinc_(Zmergehorizon);
+ }else {
+ zinc_(Zmergenew);
+ }
+ qh_willdelete(facet1, facet2);
+ qh_removefacet(facet2); /* append as a newfacet to end of qh facet_list */
+ qh_appendfacet(facet2);
+ facet2->newfacet= True;
+ facet2->tested= False;
+ qh_tracemerge(facet1, facet2);
+ if (traceonce) {
+ qh_fprintf(qh ferr, 8080, "qh_mergefacet: end of wide tracing\n");
+ qh IStracing= tracerestore;
+ }
+} /* mergefacet */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergefacet2d">-</a>
+
+ qh_mergefacet2d( facet1, facet2 )
+ in 2d, merges neighbors and vertices of facet1 into facet2
+
+ returns:
+ build ridges for neighbors if necessary
+ facet2 looks like a simplicial facet except for centrum, ridges
+ neighbors are opposite the corresponding vertex
+ maintains orientation of facet2
+
+ notes:
+ qh_mergefacet() retains non-simplicial structures
+ they are not needed in 2d, but later routines may use them
+ preserves qh.vertex_visit for qh_mergevertex_neighbors()
+
+ design:
+ get vertices and neighbors
+ determine new vertices and neighbors
+ set new vertices and neighbors and adjust orientation
+ make ridges for new neighbor if needed
+*/
+void qh_mergefacet2d(facetT *facet1, facetT *facet2) {
+ vertexT *vertex1A, *vertex1B, *vertex2A, *vertex2B, *vertexA, *vertexB;
+ facetT *neighbor1A, *neighbor1B, *neighbor2A, *neighbor2B, *neighborA, *neighborB;
+
+ vertex1A= SETfirstt_(facet1->vertices, vertexT);
+ vertex1B= SETsecondt_(facet1->vertices, vertexT);
+ vertex2A= SETfirstt_(facet2->vertices, vertexT);
+ vertex2B= SETsecondt_(facet2->vertices, vertexT);
+ neighbor1A= SETfirstt_(facet1->neighbors, facetT);
+ neighbor1B= SETsecondt_(facet1->neighbors, facetT);
+ neighbor2A= SETfirstt_(facet2->neighbors, facetT);
+ neighbor2B= SETsecondt_(facet2->neighbors, facetT);
+ if (vertex1A == vertex2A) {
+ vertexA= vertex1B;
+ vertexB= vertex2B;
+ neighborA= neighbor2A;
+ neighborB= neighbor1A;
+ }else if (vertex1A == vertex2B) {
+ vertexA= vertex1B;
+ vertexB= vertex2A;
+ neighborA= neighbor2B;
+ neighborB= neighbor1A;
+ }else if (vertex1B == vertex2A) {
+ vertexA= vertex1A;
+ vertexB= vertex2B;
+ neighborA= neighbor2A;
+ neighborB= neighbor1B;
+ }else { /* 1B == 2B */
+ vertexA= vertex1A;
+ vertexB= vertex2A;
+ neighborA= neighbor2B;
+ neighborB= neighbor1B;
+ }
+ /* vertexB always from facet2, neighborB always from facet1 */
+ if (vertexA->id > vertexB->id) {
+ SETfirst_(facet2->vertices)= vertexA;
+ SETsecond_(facet2->vertices)= vertexB;
+ if (vertexB == vertex2A)
+ facet2->toporient= !facet2->toporient;
+ SETfirst_(facet2->neighbors)= neighborA;
+ SETsecond_(facet2->neighbors)= neighborB;
+ }else {
+ SETfirst_(facet2->vertices)= vertexB;
+ SETsecond_(facet2->vertices)= vertexA;
+ if (vertexB == vertex2B)
+ facet2->toporient= !facet2->toporient;
+ SETfirst_(facet2->neighbors)= neighborB;
+ SETsecond_(facet2->neighbors)= neighborA;
+ }
+ qh_makeridges(neighborB);
+ qh_setreplace(neighborB->neighbors, facet1, facet2);
+ trace4((qh ferr, 4036, "qh_mergefacet2d: merged v%d and neighbor f%d of f%d into f%d\n",
+ vertexA->id, neighborB->id, facet1->id, facet2->id));
+} /* mergefacet2d */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergeneighbors">-</a>
+
+ qh_mergeneighbors( facet1, facet2 )
+ merges the neighbors of facet1 into facet2
+
+ see:
+ qh_mergecycle_neighbors()
+
+ design:
+ for each neighbor of facet1
+ if neighbor is also a neighbor of facet2
+ if neighbor is simpilicial
+ make ridges for later deletion as a degenerate facet
+ update its neighbor set
+ else
+ move the neighbor relation to facet2
+ remove the neighbor relation for facet1 and facet2
+*/
+void qh_mergeneighbors(facetT *facet1, facetT *facet2) {
+ facetT *neighbor, **neighborp;
+
+ trace4((qh ferr, 4037, "qh_mergeneighbors: merge neighbors of f%d and f%d\n",
+ facet1->id, facet2->id));
+ qh visit_id++;
+ FOREACHneighbor_(facet2) {
+ neighbor->visitid= qh visit_id;
+ }
+ FOREACHneighbor_(facet1) {
+ if (neighbor->visitid == qh visit_id) {
+ if (neighbor->simplicial) /* is degen, needs ridges */
+ qh_makeridges(neighbor);
+ if (SETfirstt_(neighbor->neighbors, facetT) != facet1) /*keep newfacet->horizon*/
+ qh_setdel(neighbor->neighbors, facet1);
+ else {
+ qh_setdel(neighbor->neighbors, facet2);
+ qh_setreplace(neighbor->neighbors, facet1, facet2);
+ }
+ }else if (neighbor != facet2) {
+ qh_setappend(&(facet2->neighbors), neighbor);
+ qh_setreplace(neighbor->neighbors, facet1, facet2);
+ }
+ }
+ qh_setdel(facet1->neighbors, facet2); /* here for makeridges */
+ qh_setdel(facet2->neighbors, facet1);
+} /* mergeneighbors */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergeridges">-</a>
+
+ qh_mergeridges( facet1, facet2 )
+ merges the ridge set of facet1 into facet2
+
+ returns:
+ may delete all ridges for a vertex
+ sets vertex->delridge on deleted ridges
+
+ see:
+ qh_mergecycle_ridges()
+
+ design:
+ delete ridges between facet1 and facet2
+ mark (delridge) vertices on these ridges for later testing
+ for each remaining ridge
+ rename facet1 to facet2
+*/
+void qh_mergeridges(facetT *facet1, facetT *facet2) {
+ ridgeT *ridge, **ridgep;
+ vertexT *vertex, **vertexp;
+
+ trace4((qh ferr, 4038, "qh_mergeridges: merge ridges of f%d and f%d\n",
+ facet1->id, facet2->id));
+ FOREACHridge_(facet2->ridges) {
+ if ((ridge->top == facet1) || (ridge->bottom == facet1)) {
+ FOREACHvertex_(ridge->vertices)
+ vertex->delridge= True;
+ qh_delridge(ridge); /* expensive in high-d, could rebuild */
+ ridgep--; /*repeat*/
+ }
+ }
+ FOREACHridge_(facet1->ridges) {
+ if (ridge->top == facet1)
+ ridge->top= facet2;
+ else
+ ridge->bottom= facet2;
+ qh_setappend(&(facet2->ridges), ridge);
+ }
+} /* mergeridges */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergesimplex">-</a>
+
+ qh_mergesimplex( facet1, facet2, mergeapex )
+ merge simplicial facet1 into facet2
+ mergeapex==qh_MERGEapex if merging samecycle into horizon facet
+ vertex id is latest (most recently created)
+ facet1 may be contained in facet2
+ ridges exist for both facets
+
+ returns:
+ facet2 with updated vertices, ridges, neighbors
+ updated neighbors for facet1's vertices
+ facet1 not deleted
+ sets vertex->delridge on deleted ridges
+
+ notes:
+ special case code since this is the most common merge
+ called from qh_mergefacet()
+
+ design:
+ if qh_MERGEapex
+ add vertices of facet2 to qh.new_vertexlist if necessary
+ add apex to facet2
+ else
+ for each ridge between facet1 and facet2
+ set vertex->delridge
+ determine the apex for facet1 (i.e., vertex to be merged)
+ unless apex already in facet2
+ insert apex into vertices for facet2
+ add vertices of facet2 to qh.new_vertexlist if necessary
+ add apex to qh.new_vertexlist if necessary
+ for each vertex of facet1
+ if apex
+ rename facet1 to facet2 in its vertex neighbors
+ else
+ delete facet1 from vertex neighors
+ if only in facet2
+ add vertex to qh.del_vertices for later deletion
+ for each ridge of facet1
+ delete ridges between facet1 and facet2
+ append other ridges to facet2 after renaming facet to facet2
+*/
+void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex) {
+ vertexT *vertex, **vertexp, *apex;
+ ridgeT *ridge, **ridgep;
+ boolT issubset= False;
+ int vertex_i= -1, vertex_n;
+ facetT *neighbor, **neighborp, *otherfacet;
+
+ if (mergeapex) {
+ if (!facet2->newfacet)
+ qh_newvertices(facet2->vertices); /* apex is new */
+ apex= SETfirstt_(facet1->vertices, vertexT);
+ if (SETfirstt_(facet2->vertices, vertexT) != apex)
+ qh_setaddnth(&facet2->vertices, 0, apex); /* apex has last id */
+ else
+ issubset= True;
+ }else {
+ zinc_(Zmergesimplex);
+ FOREACHvertex_(facet1->vertices)
+ vertex->seen= False;
+ FOREACHridge_(facet1->ridges) {
+ if (otherfacet_(ridge, facet1) == facet2) {
+ FOREACHvertex_(ridge->vertices) {
+ vertex->seen= True;
+ vertex->delridge= True;
+ }
+ break;
+ }
+ }
+ FOREACHvertex_(facet1->vertices) {
+ if (!vertex->seen)
+ break; /* must occur */
+ }
+ apex= vertex;
+ trace4((qh ferr, 4039, "qh_mergesimplex: merge apex v%d of f%d into facet f%d\n",
+ apex->id, facet1->id, facet2->id));
+ FOREACHvertex_i_(facet2->vertices) {
+ if (vertex->id < apex->id) {
+ break;
+ }else if (vertex->id == apex->id) {
+ issubset= True;
+ break;
+ }
+ }
+ if (!issubset)
+ qh_setaddnth(&facet2->vertices, vertex_i, apex);
+ if (!facet2->newfacet)
+ qh_newvertices(facet2->vertices);
+ else if (!apex->newlist) {
+ qh_removevertex(apex);
+ qh_appendvertex(apex);
+ }
+ }
+ trace4((qh ferr, 4040, "qh_mergesimplex: update vertex neighbors of f%d\n",
+ facet1->id));
+ FOREACHvertex_(facet1->vertices) {
+ if (vertex == apex && !issubset)
+ qh_setreplace(vertex->neighbors, facet1, facet2);
+ else {
+ qh_setdel(vertex->neighbors, facet1);
+ if (!SETsecond_(vertex->neighbors))
+ qh_mergevertex_del(vertex, facet1, facet2);
+ }
+ }
+ trace4((qh ferr, 4041, "qh_mergesimplex: merge ridges and neighbors of f%d into f%d\n",
+ facet1->id, facet2->id));
+ qh visit_id++;
+ FOREACHneighbor_(facet2)
+ neighbor->visitid= qh visit_id;
+ FOREACHridge_(facet1->ridges) {
+ otherfacet= otherfacet_(ridge, facet1);
+ if (otherfacet == facet2) {
+ qh_setdel(facet2->ridges, ridge);
+ qh_setfree(&(ridge->vertices));
+ qh_memfree(ridge, (int)sizeof(ridgeT));
+ qh_setdel(facet2->neighbors, facet1);
+ }else {
+ qh_setappend(&facet2->ridges, ridge);
+ if (otherfacet->visitid != qh visit_id) {
+ qh_setappend(&facet2->neighbors, otherfacet);
+ qh_setreplace(otherfacet->neighbors, facet1, facet2);
+ otherfacet->visitid= qh visit_id;
+ }else {
+ if (otherfacet->simplicial) /* is degen, needs ridges */
+ qh_makeridges(otherfacet);
+ if (SETfirstt_(otherfacet->neighbors, facetT) != facet1)
+ qh_setdel(otherfacet->neighbors, facet1);
+ else { /*keep newfacet->neighbors->horizon*/
+ qh_setdel(otherfacet->neighbors, facet2);
+ qh_setreplace(otherfacet->neighbors, facet1, facet2);
+ }
+ }
+ if (ridge->top == facet1) /* wait until after qh_makeridges */
+ ridge->top= facet2;
+ else
+ ridge->bottom= facet2;
+ }
+ }
+ SETfirst_(facet1->ridges)= NULL; /* it will be deleted */
+ trace3((qh ferr, 3006, "qh_mergesimplex: merged simplex f%d apex v%d into facet f%d\n",
+ facet1->id, getid_(apex), facet2->id));
+} /* mergesimplex */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergevertex_del">-</a>
+
+ qh_mergevertex_del( vertex, facet1, facet2 )
+ delete a vertex because of merging facet1 into facet2
+
+ returns:
+ deletes vertex from facet2
+ adds vertex to qh.del_vertices for later deletion
+*/
+void qh_mergevertex_del(vertexT *vertex, facetT *facet1, facetT *facet2) {
+
+ zinc_(Zmergevertex);
+ trace2((qh ferr, 2035, "qh_mergevertex_del: deleted v%d when merging f%d into f%d\n",
+ vertex->id, facet1->id, facet2->id));
+ qh_setdelsorted(facet2->vertices, vertex);
+ vertex->deleted= True;
+ qh_setappend(&qh del_vertices, vertex);
+} /* mergevertex_del */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergevertex_neighbors">-</a>
+
+ qh_mergevertex_neighbors( facet1, facet2 )
+ merge the vertex neighbors of facet1 to facet2
+
+ returns:
+ if vertex is current qh.vertex_visit
+ deletes facet1 from vertex->neighbors
+ else
+ renames facet1 to facet2 in vertex->neighbors
+ deletes vertices if only one neighbor
+
+ notes:
+ assumes vertex neighbor sets are good
+*/
+void qh_mergevertex_neighbors(facetT *facet1, facetT *facet2) {
+ vertexT *vertex, **vertexp;
+
+ trace4((qh ferr, 4042, "qh_mergevertex_neighbors: merge vertex neighbors of f%d and f%d\n",
+ facet1->id, facet2->id));
+ if (qh tracevertex) {
+ qh_fprintf(qh ferr, 8081, "qh_mergevertex_neighbors: of f%d and f%d at furthest p%d f0= %p\n",
+ facet1->id, facet2->id, qh furthest_id, qh tracevertex->neighbors->e[0].p);
+ qh_errprint("TRACE", NULL, NULL, NULL, qh tracevertex);
+ }
+ FOREACHvertex_(facet1->vertices) {
+ if (vertex->visitid != qh vertex_visit)
+ qh_setreplace(vertex->neighbors, facet1, facet2);
+ else {
+ qh_setdel(vertex->neighbors, facet1);
+ if (!SETsecond_(vertex->neighbors))
+ qh_mergevertex_del(vertex, facet1, facet2);
+ }
+ }
+ if (qh tracevertex)
+ qh_errprint("TRACE", NULL, NULL, NULL, qh tracevertex);
+} /* mergevertex_neighbors */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="mergevertices">-</a>
+
+ qh_mergevertices( vertices1, vertices2 )
+ merges the vertex set of facet1 into facet2
+
+ returns:
+ replaces vertices2 with merged set
+ preserves vertex_visit for qh_mergevertex_neighbors
+ updates qh.newvertex_list
+
+ design:
+ create a merged set of both vertices (in inverse id order)
+*/
+void qh_mergevertices(setT *vertices1, setT **vertices2) {
+ int newsize= qh_setsize(vertices1)+qh_setsize(*vertices2) - qh hull_dim + 1;
+ setT *mergedvertices;
+ vertexT *vertex, **vertexp, **vertex2= SETaddr_(*vertices2, vertexT);
+
+ mergedvertices= qh_settemp(newsize);
+ FOREACHvertex_(vertices1) {
+ if (!*vertex2 || vertex->id > (*vertex2)->id)
+ qh_setappend(&mergedvertices, vertex);
+ else {
+ while (*vertex2 && (*vertex2)->id > vertex->id)
+ qh_setappend(&mergedvertices, *vertex2++);
+ if (!*vertex2 || (*vertex2)->id < vertex->id)
+ qh_setappend(&mergedvertices, vertex);
+ else
+ qh_setappend(&mergedvertices, *vertex2++);
+ }
+ }
+ while (*vertex2)
+ qh_setappend(&mergedvertices, *vertex2++);
+ if (newsize < qh_setsize(mergedvertices)) {
+ qh_fprintf(qh ferr, 6100, "qhull internal error (qh_mergevertices): facets did not share a ridge\n");
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ qh_setfree(vertices2);
+ *vertices2= mergedvertices;
+ qh_settemppop();
+} /* mergevertices */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="neighbor_intersections">-</a>
+
+ qh_neighbor_intersections( vertex )
+ return intersection of all vertices in vertex->neighbors except for vertex
+
+ returns:
+ returns temporary set of vertices
+ does not include vertex
+ NULL if a neighbor is simplicial
+ NULL if empty set
+
+ notes:
+ used for renaming vertices
+
+ design:
+ initialize the intersection set with vertices of the first two neighbors
+ delete vertex from the intersection
+ for each remaining neighbor
+ intersect its vertex set with the intersection set
+ return NULL if empty
+ return the intersection set
+*/
+setT *qh_neighbor_intersections(vertexT *vertex) {
+ facetT *neighbor, **neighborp, *neighborA, *neighborB;
+ setT *intersect;
+ int neighbor_i, neighbor_n;
+
+ FOREACHneighbor_(vertex) {
+ if (neighbor->simplicial)
+ return NULL;
+ }
+ neighborA= SETfirstt_(vertex->neighbors, facetT);
+ neighborB= SETsecondt_(vertex->neighbors, facetT);
+ zinc_(Zintersectnum);
+ if (!neighborA)
+ return NULL;
+ if (!neighborB)
+ intersect= qh_setcopy(neighborA->vertices, 0);
+ else
+ intersect= qh_vertexintersect_new(neighborA->vertices, neighborB->vertices);
+ qh_settemppush(intersect);
+ qh_setdelsorted(intersect, vertex);
+ FOREACHneighbor_i_(vertex) {
+ if (neighbor_i >= 2) {
+ zinc_(Zintersectnum);
+ qh_vertexintersect(&intersect, neighbor->vertices);
+ if (!SETfirst_(intersect)) {
+ zinc_(Zintersectfail);
+ qh_settempfree(&intersect);
+ return NULL;
+ }
+ }
+ }
+ trace3((qh ferr, 3007, "qh_neighbor_intersections: %d vertices in neighbor intersection of v%d\n",
+ qh_setsize(intersect), vertex->id));
+ return intersect;
+} /* neighbor_intersections */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="newvertices">-</a>
+
+ qh_newvertices( vertices )
+ add vertices to end of qh.vertex_list (marks as new vertices)
+
+ returns:
+ vertices on qh.newvertex_list
+ vertex->newlist set
+*/
+void qh_newvertices(setT *vertices) {
+ vertexT *vertex, **vertexp;
+
+ FOREACHvertex_(vertices) {
+ if (!vertex->newlist) {
+ qh_removevertex(vertex);
+ qh_appendvertex(vertex);
+ }
+ }
+} /* newvertices */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="reducevertices">-</a>
+
+ qh_reducevertices()
+ reduce extra vertices, shared vertices, and redundant vertices
+ facet->newmerge is set if merged since last call
+ if !qh.MERGEvertices, only removes extra vertices
+
+ returns:
+ True if also merged degen_redundant facets
+ vertices are renamed if possible
+ clears facet->newmerge and vertex->delridge
+
+ notes:
+ ignored if 2-d
+
+ design:
+ merge any degenerate or redundant facets
+ for each newly merged facet
+ remove extra vertices
+ if qh.MERGEvertices
+ for each newly merged facet
+ for each vertex
+ if vertex was on a deleted ridge
+ rename vertex if it is shared
+ remove delridge flag from new vertices
+*/
+boolT qh_reducevertices(void) {
+ int numshare=0, numrename= 0;
+ boolT degenredun= False;
+ facetT *newfacet;
+ vertexT *vertex, **vertexp;
+
+ if (qh hull_dim == 2)
+ return False;
+ if (qh_merge_degenredundant())
+ degenredun= True;
+ LABELrestart:
+ FORALLnew_facets {
+ if (newfacet->newmerge) {
+ if (!qh MERGEvertices)
+ newfacet->newmerge= False;
+ qh_remove_extravertices(newfacet);
+ }
+ }
+ if (!qh MERGEvertices)
+ return False;
+ FORALLnew_facets {
+ if (newfacet->newmerge) {
+ newfacet->newmerge= False;
+ FOREACHvertex_(newfacet->vertices) {
+ if (vertex->delridge) {
+ if (qh_rename_sharedvertex(vertex, newfacet)) {
+ numshare++;
+ vertexp--; /* repeat since deleted vertex */
+ }
+ }
+ }
+ }
+ }
+ FORALLvertex_(qh newvertex_list) {
+ if (vertex->delridge && !vertex->deleted) {
+ vertex->delridge= False;
+ if (qh hull_dim >= 4 && qh_redundant_vertex(vertex)) {
+ numrename++;
+ if (qh_merge_degenredundant()) {
+ degenredun= True;
+ goto LABELrestart;
+ }
+ }
+ }
+ }
+ trace1((qh ferr, 1014, "qh_reducevertices: renamed %d shared vertices and %d redundant vertices. Degen? %d\n",
+ numshare, numrename, degenredun));
+ return degenredun;
+} /* reducevertices */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="redundant_vertex">-</a>
+
+ qh_redundant_vertex( vertex )
+ detect and rename a redundant vertex
+ vertices have full vertex->neighbors
+
+ returns:
+ returns true if find a redundant vertex
+ deletes vertex(vertex->deleted)
+
+ notes:
+ only needed if vertex->delridge and hull_dim >= 4
+ may add degenerate facets to qh.facet_mergeset
+ doesn't change vertex->neighbors or create redundant facets
+
+ design:
+ intersect vertices of all facet neighbors of vertex
+ determine ridges for these vertices
+ if find a new vertex for vertex amoung these ridges and vertices
+ rename vertex to the new vertex
+*/
+vertexT *qh_redundant_vertex(vertexT *vertex) {
+ vertexT *newvertex= NULL;
+ setT *vertices, *ridges;
+
+ trace3((qh ferr, 3008, "qh_redundant_vertex: check if v%d can be renamed\n", vertex->id));
+ if ((vertices= qh_neighbor_intersections(vertex))) {
+ ridges= qh_vertexridges(vertex);
+ if ((newvertex= qh_find_newvertex(vertex, vertices, ridges)))
+ qh_renamevertex(vertex, newvertex, ridges, NULL, NULL);
+ qh_settempfree(&ridges);
+ qh_settempfree(&vertices);
+ }
+ return newvertex;
+} /* redundant_vertex */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="remove_extravertices">-</a>
+
+ qh_remove_extravertices( facet )
+ remove extra vertices from non-simplicial facets
+
+ returns:
+ returns True if it finds them
+
+ design:
+ for each vertex in facet
+ if vertex not in a ridge (i.e., no longer used)
+ delete vertex from facet
+ delete facet from vertice's neighbors
+ unless vertex in another facet
+ add vertex to qh.del_vertices for later deletion
+*/
+boolT qh_remove_extravertices(facetT *facet) {
+ ridgeT *ridge, **ridgep;
+ vertexT *vertex, **vertexp;
+ boolT foundrem= False;
+
+ trace4((qh ferr, 4043, "qh_remove_extravertices: test f%d for extra vertices\n",
+ facet->id));
+ FOREACHvertex_(facet->vertices)
+ vertex->seen= False;
+ FOREACHridge_(facet->ridges) {
+ FOREACHvertex_(ridge->vertices)
+ vertex->seen= True;
+ }
+ FOREACHvertex_(facet->vertices) {
+ if (!vertex->seen) {
+ foundrem= True;
+ zinc_(Zremvertex);
+ qh_setdelsorted(facet->vertices, vertex);
+ qh_setdel(vertex->neighbors, facet);
+ if (!qh_setsize(vertex->neighbors)) {
+ vertex->deleted= True;
+ qh_setappend(&qh del_vertices, vertex);
+ zinc_(Zremvertexdel);
+ trace2((qh ferr, 2036, "qh_remove_extravertices: v%d deleted because it's lost all ridges\n", vertex->id));
+ }else
+ trace3((qh ferr, 3009, "qh_remove_extravertices: v%d removed from f%d because it's lost all ridges\n", vertex->id, facet->id));
+ vertexp--; /*repeat*/
+ }
+ }
+ return foundrem;
+} /* remove_extravertices */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="rename_sharedvertex">-</a>
+
+ qh_rename_sharedvertex( vertex, facet )
+ detect and rename if shared vertex in facet
+ vertices have full ->neighbors
+
+ returns:
+ newvertex or NULL
+ the vertex may still exist in other facets (i.e., a neighbor was pinched)
+ does not change facet->neighbors
+ updates vertex->neighbors
+
+ notes:
+ a shared vertex for a facet is only in ridges to one neighbor
+ this may undo a pinched facet
+
+ it does not catch pinches involving multiple facets. These appear
+ to be difficult to detect, since an exhaustive search is too expensive.
+
+ design:
+ if vertex only has two neighbors
+ determine the ridges that contain the vertex
+ determine the vertices shared by both neighbors
+ if can find a new vertex in this set
+ rename the vertex to the new vertex
+*/
+vertexT *qh_rename_sharedvertex(vertexT *vertex, facetT *facet) {
+ facetT *neighbor, **neighborp, *neighborA= NULL;
+ setT *vertices, *ridges;
+ vertexT *newvertex;
+
+ if (qh_setsize(vertex->neighbors) == 2) {
+ neighborA= SETfirstt_(vertex->neighbors, facetT);
+ if (neighborA == facet)
+ neighborA= SETsecondt_(vertex->neighbors, facetT);
+ }else if (qh hull_dim == 3)
+ return NULL;
+ else {
+ qh visit_id++;
+ FOREACHneighbor_(facet)
+ neighbor->visitid= qh visit_id;
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid == qh visit_id) {
+ if (neighborA)
+ return NULL;
+ neighborA= neighbor;
+ }
+ }
+ if (!neighborA) {
+ qh_fprintf(qh ferr, 6101, "qhull internal error (qh_rename_sharedvertex): v%d's neighbors not in f%d\n",
+ vertex->id, facet->id);
+ qh_errprint("ERRONEOUS", facet, NULL, NULL, vertex);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ }
+ /* the vertex is shared by facet and neighborA */
+ ridges= qh_settemp(qh TEMPsize);
+ neighborA->visitid= ++qh visit_id;
+ qh_vertexridges_facet(vertex, facet, &ridges);
+ trace2((qh ferr, 2037, "qh_rename_sharedvertex: p%d(v%d) is shared by f%d(%d ridges) and f%d\n",
+ qh_pointid(vertex->point), vertex->id, facet->id, qh_setsize(ridges), neighborA->id));
+ zinc_(Zintersectnum);
+ vertices= qh_vertexintersect_new(facet->vertices, neighborA->vertices);
+ qh_setdel(vertices, vertex);
+ qh_settemppush(vertices);
+ if ((newvertex= qh_find_newvertex(vertex, vertices, ridges)))
+ qh_renamevertex(vertex, newvertex, ridges, facet, neighborA);
+ qh_settempfree(&vertices);
+ qh_settempfree(&ridges);
+ return newvertex;
+} /* rename_sharedvertex */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="renameridgevertex">-</a>
+
+ qh_renameridgevertex( ridge, oldvertex, newvertex )
+ renames oldvertex as newvertex in ridge
+
+ returns:
+
+ design:
+ delete oldvertex from ridge
+ if newvertex already in ridge
+ copy ridge->noconvex to another ridge if possible
+ delete the ridge
+ else
+ insert newvertex into the ridge
+ adjust the ridge's orientation
+*/
+void qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex) {
+ int nth= 0, oldnth;
+ facetT *temp;
+ vertexT *vertex, **vertexp;
+
+ oldnth= qh_setindex(ridge->vertices, oldvertex);
+ qh_setdelnthsorted(ridge->vertices, oldnth);
+ FOREACHvertex_(ridge->vertices) {
+ if (vertex == newvertex) {
+ zinc_(Zdelridge);
+ if (ridge->nonconvex) /* only one ridge has nonconvex set */
+ qh_copynonconvex(ridge);
+ trace2((qh ferr, 2038, "qh_renameridgevertex: ridge r%d deleted. It contained both v%d and v%d\n",
+ ridge->id, oldvertex->id, newvertex->id));
+ qh_delridge(ridge);
+ return;
+ }
+ if (vertex->id < newvertex->id)
+ break;
+ nth++;
+ }
+ qh_setaddnth(&ridge->vertices, nth, newvertex);
+ if (abs(oldnth - nth)%2) {
+ trace3((qh ferr, 3010, "qh_renameridgevertex: swapped the top and bottom of ridge r%d\n",
+ ridge->id));
+ temp= ridge->top;
+ ridge->top= ridge->bottom;
+ ridge->bottom= temp;
+ }
+} /* renameridgevertex */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="renamevertex">-</a>
+
+ qh_renamevertex( oldvertex, newvertex, ridges, oldfacet, neighborA )
+ renames oldvertex as newvertex in ridges
+ gives oldfacet/neighborA if oldvertex is shared between two facets
+
+ returns:
+ oldvertex may still exist afterwards
+
+
+ notes:
+ can not change neighbors of newvertex (since it's a subset)
+
+ design:
+ for each ridge in ridges
+ rename oldvertex to newvertex and delete degenerate ridges
+ if oldfacet not defined
+ for each neighbor of oldvertex
+ delete oldvertex from neighbor's vertices
+ remove extra vertices from neighbor
+ add oldvertex to qh.del_vertices
+ else if oldvertex only between oldfacet and neighborA
+ delete oldvertex from oldfacet and neighborA
+ add oldvertex to qh.del_vertices
+ else oldvertex is in oldfacet and neighborA and other facets (i.e., pinched)
+ delete oldvertex from oldfacet
+ delete oldfacet from oldvertice's neighbors
+ remove extra vertices (e.g., oldvertex) from neighborA
+*/
+void qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges, facetT *oldfacet, facetT *neighborA) {
+ facetT *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+ boolT istrace= False;
+
+ if (qh IStracing >= 2 || oldvertex->id == qh tracevertex_id ||
+ newvertex->id == qh tracevertex_id)
+ istrace= True;
+ FOREACHridge_(ridges)
+ qh_renameridgevertex(ridge, oldvertex, newvertex);
+ if (!oldfacet) {
+ zinc_(Zrenameall);
+ if (istrace)
+ qh_fprintf(qh ferr, 8082, "qh_renamevertex: renamed v%d to v%d in several facets\n",
+ oldvertex->id, newvertex->id);
+ FOREACHneighbor_(oldvertex) {
+ qh_maydropneighbor(neighbor);
+ qh_setdelsorted(neighbor->vertices, oldvertex);
+ if (qh_remove_extravertices(neighbor))
+ neighborp--; /* neighbor may be deleted */
+ }
+ if (!oldvertex->deleted) {
+ oldvertex->deleted= True;
+ qh_setappend(&qh del_vertices, oldvertex);
+ }
+ }else if (qh_setsize(oldvertex->neighbors) == 2) {
+ zinc_(Zrenameshare);
+ if (istrace)
+ qh_fprintf(qh ferr, 8083, "qh_renamevertex: renamed v%d to v%d in oldfacet f%d\n",
+ oldvertex->id, newvertex->id, oldfacet->id);
+ FOREACHneighbor_(oldvertex)
+ qh_setdelsorted(neighbor->vertices, oldvertex);
+ oldvertex->deleted= True;
+ qh_setappend(&qh del_vertices, oldvertex);
+ }else {
+ zinc_(Zrenamepinch);
+ if (istrace || qh IStracing)
+ qh_fprintf(qh ferr, 8084, "qh_renamevertex: renamed pinched v%d to v%d between f%d and f%d\n",
+ oldvertex->id, newvertex->id, oldfacet->id, neighborA->id);
+ qh_setdelsorted(oldfacet->vertices, oldvertex);
+ qh_setdel(oldvertex->neighbors, oldfacet);
+ qh_remove_extravertices(neighborA);
+ }
+} /* renamevertex */
+
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="test_appendmerge">-</a>
+
+ qh_test_appendmerge( facet, neighbor )
+ tests facet/neighbor for convexity
+ appends to mergeset if non-convex
+ if pre-merging,
+ nop if qh.SKIPconvex, or qh.MERGEexact and coplanar
+
+ returns:
+ true if appends facet/neighbor to mergeset
+ sets facet->center as needed
+ does not change facet->seen
+
+ design:
+ if qh.cos_max is defined
+ if the angle between facet normals is too shallow
+ append an angle-coplanar merge to qh.mergeset
+ return True
+ make facet's centrum if needed
+ if facet's centrum is above the neighbor
+ set isconcave
+ else
+ if facet's centrum is not below the neighbor
+ set iscoplanar
+ make neighbor's centrum if needed
+ if neighbor's centrum is above the facet
+ set isconcave
+ else if neighbor's centrum is not below the facet
+ set iscoplanar
+ if isconcave or iscoplanar
+ get angle if needed
+ append concave or coplanar merge to qh.mergeset
+*/
+boolT qh_test_appendmerge(facetT *facet, facetT *neighbor) {
+ realT dist, dist2= -REALmax, angle= -REALmax;
+ boolT isconcave= False, iscoplanar= False, okangle= False;
+
+ if (qh SKIPconvex && !qh POSTmerging)
+ return False;
+ if ((!qh MERGEexact || qh POSTmerging) && qh cos_max < REALmax/2) {
+ angle= qh_getangle(facet->normal, neighbor->normal);
+ zinc_(Zangletests);
+ if (angle > qh cos_max) {
+ zinc_(Zcoplanarangle);
+ qh_appendmergeset(facet, neighbor, MRGanglecoplanar, &angle);
+ trace2((qh ferr, 2039, "qh_test_appendmerge: coplanar angle %4.4g between f%d and f%d\n",
+ angle, facet->id, neighbor->id));
+ return True;
+ }else
+ okangle= True;
+ }
+ if (!facet->center)
+ facet->center= qh_getcentrum(facet);
+ zzinc_(Zcentrumtests);
+ qh_distplane(facet->center, neighbor, &dist);
+ if (dist > qh centrum_radius)
+ isconcave= True;
+ else {
+ if (dist > -qh centrum_radius)
+ iscoplanar= True;
+ if (!neighbor->center)
+ neighbor->center= qh_getcentrum(neighbor);
+ zzinc_(Zcentrumtests);
+ qh_distplane(neighbor->center, facet, &dist2);
+ if (dist2 > qh centrum_radius)
+ isconcave= True;
+ else if (!iscoplanar && dist2 > -qh centrum_radius)
+ iscoplanar= True;
+ }
+ if (!isconcave && (!iscoplanar || (qh MERGEexact && !qh POSTmerging)))
+ return False;
+ if (!okangle && qh ANGLEmerge) {
+ angle= qh_getangle(facet->normal, neighbor->normal);
+ zinc_(Zangletests);
+ }
+ if (isconcave) {
+ zinc_(Zconcaveridge);
+ if (qh ANGLEmerge)
+ angle += qh_ANGLEconcave + 0.5;
+ qh_appendmergeset(facet, neighbor, MRGconcave, &angle);
+ trace0((qh ferr, 18, "qh_test_appendmerge: concave f%d to f%d dist %4.4g and reverse dist %4.4g angle %4.4g during p%d\n",
+ facet->id, neighbor->id, dist, dist2, angle, qh furthest_id));
+ }else /* iscoplanar */ {
+ zinc_(Zcoplanarcentrum);
+ qh_appendmergeset(facet, neighbor, MRGcoplanar, &angle);
+ trace2((qh ferr, 2040, "qh_test_appendmerge: coplanar f%d to f%d dist %4.4g, reverse dist %4.4g angle %4.4g\n",
+ facet->id, neighbor->id, dist, dist2, angle));
+ }
+ return True;
+} /* test_appendmerge */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="test_vneighbors">-</a>
+
+ qh_test_vneighbors()
+ test vertex neighbors for convexity
+ tests all facets on qh.newfacet_list
+
+ returns:
+ true if non-convex vneighbors appended to qh.facet_mergeset
+ initializes vertex neighbors if needed
+
+ notes:
+ assumes all facet neighbors have been tested
+ this can be expensive
+ this does not guarantee that a centrum is below all facets
+ but it is unlikely
+ uses qh.visit_id
+
+ design:
+ build vertex neighbors if necessary
+ for all new facets
+ for all vertices
+ for each unvisited facet neighbor of the vertex
+ test new facet and neighbor for convexity
+*/
+boolT qh_test_vneighbors(void /* qh.newfacet_list */) {
+ facetT *newfacet, *neighbor, **neighborp;
+ vertexT *vertex, **vertexp;
+ int nummerges= 0;
+
+ trace1((qh ferr, 1015, "qh_test_vneighbors: testing vertex neighbors for convexity\n"));
+ if (!qh VERTEXneighbors)
+ qh_vertexneighbors();
+ FORALLnew_facets
+ newfacet->seen= False;
+ FORALLnew_facets {
+ newfacet->seen= True;
+ newfacet->visitid= qh visit_id++;
+ FOREACHneighbor_(newfacet)
+ newfacet->visitid= qh visit_id;
+ FOREACHvertex_(newfacet->vertices) {
+ FOREACHneighbor_(vertex) {
+ if (neighbor->seen || neighbor->visitid == qh visit_id)
+ continue;
+ if (qh_test_appendmerge(newfacet, neighbor))
+ nummerges++;
+ }
+ }
+ }
+ zadd_(Ztestvneighbor, nummerges);
+ trace1((qh ferr, 1016, "qh_test_vneighbors: found %d non-convex, vertex neighbors\n",
+ nummerges));
+ return (nummerges > 0);
+} /* test_vneighbors */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="tracemerge">-</a>
+
+ qh_tracemerge( facet1, facet2 )
+ print trace message after merge
+*/
+void qh_tracemerge(facetT *facet1, facetT *facet2) {
+ boolT waserror= False;
+
+#ifndef qh_NOtrace
+ if (qh IStracing >= 4)
+ qh_errprint("MERGED", facet2, NULL, NULL, NULL);
+ if (facet2 == qh tracefacet || (qh tracevertex && qh tracevertex->newlist)) {
+ qh_fprintf(qh ferr, 8085, "qh_tracemerge: trace facet and vertex after merge of f%d and f%d, furthest p%d\n", facet1->id, facet2->id, qh furthest_id);
+ if (facet2 != qh tracefacet)
+ qh_errprint("TRACE", qh tracefacet,
+ (qh tracevertex && qh tracevertex->neighbors) ?
+ SETfirstt_(qh tracevertex->neighbors, facetT) : NULL,
+ NULL, qh tracevertex);
+ }
+ if (qh tracevertex) {
+ if (qh tracevertex->deleted)
+ qh_fprintf(qh ferr, 8086, "qh_tracemerge: trace vertex deleted at furthest p%d\n",
+ qh furthest_id);
+ else
+ qh_checkvertex(qh tracevertex);
+ }
+ if (qh tracefacet) {
+ qh_checkfacet(qh tracefacet, True, &waserror);
+ if (waserror)
+ qh_errexit(qh_ERRqhull, qh tracefacet, NULL);
+ }
+#endif /* !qh_NOtrace */
+ if (qh CHECKfrequently || qh IStracing >= 4) { /* can't check polygon here */
+ qh_checkfacet(facet2, True, &waserror);
+ if (waserror)
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+} /* tracemerge */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="tracemerging">-</a>
+
+ qh_tracemerging()
+ print trace message during POSTmerging
+
+ returns:
+ updates qh.mergereport
+
+ notes:
+ called from qh_mergecycle() and qh_mergefacet()
+
+ see:
+ qh_buildtracing()
+*/
+void qh_tracemerging(void) {
+ realT cpu;
+ int total;
+ time_t timedata;
+ struct tm *tp;
+
+ qh mergereport= zzval_(Ztotmerge);
+ time(&timedata);
+ tp= localtime(&timedata);
+ cpu= qh_CPUclock;
+ cpu /= qh_SECticks;
+ total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
+ qh_fprintf(qh ferr, 8087, "\n\
+At %d:%d:%d & %2.5g CPU secs, qhull has merged %d facets. The hull\n\
+ contains %d facets and %d vertices.\n",
+ tp->tm_hour, tp->tm_min, tp->tm_sec, cpu,
+ total, qh num_facets - qh num_visible,
+ qh num_vertices-qh_setsize(qh del_vertices));
+} /* tracemerging */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="updatetested">-</a>
+
+ qh_updatetested( facet1, facet2 )
+ clear facet2->tested and facet1->ridge->tested for merge
+
+ returns:
+ deletes facet2->center unless it's already large
+ if so, clears facet2->ridge->tested
+
+ design:
+ clear facet2->tested
+ clear ridge->tested for facet1's ridges
+ if facet2 has a centrum
+ if facet2 is large
+ set facet2->keepcentrum
+ else if facet2 has 3 vertices due to many merges, or not large and post merging
+ clear facet2->keepcentrum
+ unless facet2->keepcentrum
+ clear facet2->center to recompute centrum later
+ clear ridge->tested for facet2's ridges
+*/
+void qh_updatetested(facetT *facet1, facetT *facet2) {
+ ridgeT *ridge, **ridgep;
+ int size;
+
+ facet2->tested= False;
+ FOREACHridge_(facet1->ridges)
+ ridge->tested= False;
+ if (!facet2->center)
+ return;
+ size= qh_setsize(facet2->vertices);
+ if (!facet2->keepcentrum) {
+ if (size > qh hull_dim + qh_MAXnewcentrum) {
+ facet2->keepcentrum= True;
+ zinc_(Zwidevertices);
+ }
+ }else if (size <= qh hull_dim + qh_MAXnewcentrum) {
+ /* center and keepcentrum was set */
+ if (size == qh hull_dim || qh POSTmerging)
+ facet2->keepcentrum= False; /* if many merges need to recompute centrum */
+ }
+ if (!facet2->keepcentrum) {
+ qh_memfree(facet2->center, qh normal_size);
+ facet2->center= NULL;
+ FOREACHridge_(facet2->ridges)
+ ridge->tested= False;
+ }
+} /* updatetested */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="vertexridges">-</a>
+
+ qh_vertexridges( vertex )
+ return temporary set of ridges adjacent to a vertex
+ vertex->neighbors defined
+
+ ntoes:
+ uses qh.visit_id
+ does not include implicit ridges for simplicial facets
+
+ design:
+ for each neighbor of vertex
+ add ridges that include the vertex to ridges
+*/
+setT *qh_vertexridges(vertexT *vertex) {
+ facetT *neighbor, **neighborp;
+ setT *ridges= qh_settemp(qh TEMPsize);
+ int size;
+
+ qh visit_id++;
+ FOREACHneighbor_(vertex)
+ neighbor->visitid= qh visit_id;
+ FOREACHneighbor_(vertex) {
+ if (*neighborp) /* no new ridges in last neighbor */
+ qh_vertexridges_facet(vertex, neighbor, &ridges);
+ }
+ if (qh PRINTstatistics || qh IStracing) {
+ size= qh_setsize(ridges);
+ zinc_(Zvertexridge);
+ zadd_(Zvertexridgetot, size);
+ zmax_(Zvertexridgemax, size);
+ trace3((qh ferr, 3011, "qh_vertexridges: found %d ridges for v%d\n",
+ size, vertex->id));
+ }
+ return ridges;
+} /* vertexridges */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="vertexridges_facet">-</a>
+
+ qh_vertexridges_facet( vertex, facet, ridges )
+ add adjacent ridges for vertex in facet
+ neighbor->visitid==qh.visit_id if it hasn't been visited
+
+ returns:
+ ridges updated
+ sets facet->visitid to qh.visit_id-1
+
+ design:
+ for each ridge of facet
+ if ridge of visited neighbor (i.e., unprocessed)
+ if vertex in ridge
+ append ridge to vertex
+ mark facet processed
+*/
+void qh_vertexridges_facet(vertexT *vertex, facetT *facet, setT **ridges) {
+ ridgeT *ridge, **ridgep;
+ facetT *neighbor;
+
+ FOREACHridge_(facet->ridges) {
+ neighbor= otherfacet_(ridge, facet);
+ if (neighbor->visitid == qh visit_id
+ && qh_setin(ridge->vertices, vertex))
+ qh_setappend(ridges, ridge);
+ }
+ facet->visitid= qh visit_id-1;
+} /* vertexridges_facet */
+
+/*-<a href="qh-merge.htm#TOC"
+ >-------------------------------</a><a name="willdelete">-</a>
+
+ qh_willdelete( facet, replace )
+ moves facet to visible list
+ sets facet->f.replace to replace (may be NULL)
+
+ returns:
+ bumps qh.num_visible
+*/
+void qh_willdelete(facetT *facet, facetT *replace) {
+
+ qh_removefacet(facet);
+ qh_prependfacet(facet, &qh visible_list);
+ qh num_visible++;
+ facet->visible= True;
+ facet->f.replace= replace;
+} /* willdelete */
+
+#else /* qh_NOmerge */
+void qh_premerge(vertexT *apex, realT maxcentrum, realT maxangle) {
+}
+void qh_postmerge(const char *reason, realT maxcentrum, realT maxangle,
+ boolT vneighbors) {
+}
+boolT qh_checkzero(boolT testall) {
+ }
+#endif /* qh_NOmerge */
+
diff --git a/xs/src/qhull/src/libqhull/merge.h b/xs/src/qhull/src/libqhull/merge.h
new file mode 100644
index 000000000..7f5ec3fb6
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/merge.h
@@ -0,0 +1,178 @@
+/*<html><pre> -<a href="qh-merge.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ merge.h
+ header file for merge.c
+
+ see qh-merge.htm and merge.c
+
+ Copyright (c) 1993-2015 C.B. Barber.
+ $Id: //main/2015/qhull/src/libqhull/merge.h#1 $$Change: 1981 $
+ $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
+*/
+
+#ifndef qhDEFmerge
+#define qhDEFmerge 1
+
+#include "libqhull.h"
+
+
+/*============ -constants- ==============*/
+
+/*-<a href="qh-merge.htm#TOC"
+ >--------------------------------</a><a name="qh_ANGLEredundant">-</a>
+
+ qh_ANGLEredundant
+ indicates redundant merge in mergeT->angle
+*/
+#define qh_ANGLEredundant 6.0
+
+/*-<a href="qh-merge.htm#TOC"
+ >--------------------------------</a><a name="qh_ANGLEdegen">-</a>
+
+ qh_ANGLEdegen
+ indicates degenerate facet in mergeT->angle
+*/
+#define qh_ANGLEdegen 5.0
+
+/*-<a href="qh-merge.htm#TOC"
+ >--------------------------------</a><a name="qh_ANGLEconcave">-</a>
+
+ qh_ANGLEconcave
+ offset to indicate concave facets in mergeT->angle
+
+ notes:
+ concave facets are assigned the range of [2,4] in mergeT->angle
+ roundoff error may make the angle less than 2
+*/
+#define qh_ANGLEconcave 1.5
+
+/*-<a href="qh-merge.htm#TOC"
+ >--------------------------------</a><a name="MRG">-</a>
+
+ MRG... (mergeType)
+ indicates the type of a merge (mergeT->type)
+*/
+typedef enum { /* in sort order for facet_mergeset */
+ MRGnone= 0,
+ MRGcoplanar, /* centrum coplanar */
+ MRGanglecoplanar, /* angle coplanar */
+ /* could detect half concave ridges */
+ MRGconcave, /* concave ridge */
+ MRGflip, /* flipped facet. facet1 == facet2 */
+ MRGridge, /* duplicate ridge (qh_MERGEridge) */
+ /* degen and redundant go onto degen_mergeset */
+ MRGdegen, /* degenerate facet (!enough neighbors) facet1 == facet2 */
+ MRGredundant, /* redundant facet (vertex subset) */
+ /* merge_degenredundant assumes degen < redundant */
+ MRGmirror, /* mirror facet from qh_triangulate */
+ ENDmrg
+} mergeType;
+
+/*-<a href="qh-merge.htm#TOC"
+ >--------------------------------</a><a name="qh_MERGEapex">-</a>
+
+ qh_MERGEapex
+ flag for qh_mergefacet() to indicate an apex merge
+*/
+#define qh_MERGEapex True
+
+/*============ -structures- ====================*/
+
+/*-<a href="qh-merge.htm#TOC"
+ >--------------------------------</a><a name="mergeT">-</a>
+
+ mergeT
+ structure used to merge facets
+*/
+
+typedef struct mergeT mergeT;
+struct mergeT { /* initialize in qh_appendmergeset */
+ realT angle; /* angle between normals of facet1 and facet2 */
+ facetT *facet1; /* will merge facet1 into facet2 */
+ facetT *facet2;
+ mergeType type;
+};
+
+
+/*=========== -macros- =========================*/
+
+/*-<a href="qh-merge.htm#TOC"
+ >--------------------------------</a><a name="FOREACHmerge_">-</a>
+
+ FOREACHmerge_( merges ) {...}
+ assign 'merge' to each merge in merges
+
+ notes:
+ uses 'mergeT *merge, **mergep;'
+ if qh_mergefacet(),
+ restart since qh.facet_mergeset may change
+ see <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHmerge_( merges ) FOREACHsetelement_(mergeT, merges, merge)
+
+/*============ prototypes in alphabetical order after pre/postmerge =======*/
+
+void qh_premerge(vertexT *apex, realT maxcentrum, realT maxangle);
+void qh_postmerge(const char *reason, realT maxcentrum, realT maxangle,
+ boolT vneighbors);
+void qh_all_merges(boolT othermerge, boolT vneighbors);
+void qh_appendmergeset(facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle);
+setT *qh_basevertices( facetT *samecycle);
+void qh_checkconnect(void /* qh.new_facets */);
+boolT qh_checkzero(boolT testall);
+int qh_compareangle(const void *p1, const void *p2);
+int qh_comparemerge(const void *p1, const void *p2);
+int qh_comparevisit(const void *p1, const void *p2);
+void qh_copynonconvex(ridgeT *atridge);
+void qh_degen_redundant_facet(facetT *facet);
+void qh_degen_redundant_neighbors(facetT *facet, facetT *delfacet);
+vertexT *qh_find_newvertex(vertexT *oldvertex, setT *vertices, setT *ridges);
+void qh_findbest_test(boolT testcentrum, facetT *facet, facetT *neighbor,
+ facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp);
+facetT *qh_findbestneighbor(facetT *facet, realT *distp, realT *mindistp, realT *maxdistp);
+void qh_flippedmerges(facetT *facetlist, boolT *wasmerge);
+void qh_forcedmerges( boolT *wasmerge);
+void qh_getmergeset(facetT *facetlist);
+void qh_getmergeset_initial(facetT *facetlist);
+void qh_hashridge(setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex);
+ridgeT *qh_hashridge_find(setT *hashtable, int hashsize, ridgeT *ridge,
+ vertexT *vertex, vertexT *oldvertex, int *hashslot);
+void qh_makeridges(facetT *facet);
+void qh_mark_dupridges(facetT *facetlist);
+void qh_maydropneighbor(facetT *facet);
+int qh_merge_degenredundant(void);
+void qh_merge_nonconvex( facetT *facet1, facetT *facet2, mergeType mergetype);
+void qh_mergecycle(facetT *samecycle, facetT *newfacet);
+void qh_mergecycle_all(facetT *facetlist, boolT *wasmerge);
+void qh_mergecycle_facets( facetT *samecycle, facetT *newfacet);
+void qh_mergecycle_neighbors(facetT *samecycle, facetT *newfacet);
+void qh_mergecycle_ridges(facetT *samecycle, facetT *newfacet);
+void qh_mergecycle_vneighbors( facetT *samecycle, facetT *newfacet);
+void qh_mergefacet(facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex);
+void qh_mergefacet2d(facetT *facet1, facetT *facet2);
+void qh_mergeneighbors(facetT *facet1, facetT *facet2);
+void qh_mergeridges(facetT *facet1, facetT *facet2);
+void qh_mergesimplex(facetT *facet1, facetT *facet2, boolT mergeapex);
+void qh_mergevertex_del(vertexT *vertex, facetT *facet1, facetT *facet2);
+void qh_mergevertex_neighbors(facetT *facet1, facetT *facet2);
+void qh_mergevertices(setT *vertices1, setT **vertices);
+setT *qh_neighbor_intersections(vertexT *vertex);
+void qh_newvertices(setT *vertices);
+boolT qh_reducevertices(void);
+vertexT *qh_redundant_vertex(vertexT *vertex);
+boolT qh_remove_extravertices(facetT *facet);
+vertexT *qh_rename_sharedvertex(vertexT *vertex, facetT *facet);
+void qh_renameridgevertex(ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex);
+void qh_renamevertex(vertexT *oldvertex, vertexT *newvertex, setT *ridges,
+ facetT *oldfacet, facetT *neighborA);
+boolT qh_test_appendmerge(facetT *facet, facetT *neighbor);
+boolT qh_test_vneighbors(void /* qh.newfacet_list */);
+void qh_tracemerge(facetT *facet1, facetT *facet2);
+void qh_tracemerging(void);
+void qh_updatetested( facetT *facet1, facetT *facet2);
+setT *qh_vertexridges(vertexT *vertex);
+void qh_vertexridges_facet(vertexT *vertex, facetT *facet, setT **ridges);
+void qh_willdelete(facetT *facet, facetT *replace);
+
+#endif /* qhDEFmerge */
diff --git a/xs/src/qhull/src/libqhull/poly.c b/xs/src/qhull/src/libqhull/poly.c
new file mode 100644
index 000000000..b8db6a9ef
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/poly.c
@@ -0,0 +1,1205 @@
+/*<html><pre> -<a href="qh-poly.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ poly.c
+ implements polygons and simplices
+
+ see qh-poly.htm, poly.h and libqhull.h
+
+ infrequent code is in poly2.c
+ (all but top 50 and their callers 12/3/95)
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/poly.c#3 $$Change: 2064 $
+ $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
+*/
+
+#include "qhull_a.h"
+
+/*======== functions in alphabetical order ==========*/
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="appendfacet">-</a>
+
+ qh_appendfacet( facet )
+ appends facet to end of qh.facet_list,
+
+ returns:
+ updates qh.newfacet_list, facet_next, facet_list
+ increments qh.numfacets
+
+ notes:
+ assumes qh.facet_list/facet_tail is defined (createsimplex)
+
+ see:
+ qh_removefacet()
+
+*/
+void qh_appendfacet(facetT *facet) {
+ facetT *tail= qh facet_tail;
+
+ if (tail == qh newfacet_list)
+ qh newfacet_list= facet;
+ if (tail == qh facet_next)
+ qh facet_next= facet;
+ facet->previous= tail->previous;
+ facet->next= tail;
+ if (tail->previous)
+ tail->previous->next= facet;
+ else
+ qh facet_list= facet;
+ tail->previous= facet;
+ qh num_facets++;
+ trace4((qh ferr, 4044, "qh_appendfacet: append f%d to facet_list\n", facet->id));
+} /* appendfacet */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="appendvertex">-</a>
+
+ qh_appendvertex( vertex )
+ appends vertex to end of qh.vertex_list,
+
+ returns:
+ sets vertex->newlist
+ updates qh.vertex_list, newvertex_list
+ increments qh.num_vertices
+
+ notes:
+ assumes qh.vertex_list/vertex_tail is defined (createsimplex)
+
+*/
+void qh_appendvertex(vertexT *vertex) {
+ vertexT *tail= qh vertex_tail;
+
+ if (tail == qh newvertex_list)
+ qh newvertex_list= vertex;
+ vertex->newlist= True;
+ vertex->previous= tail->previous;
+ vertex->next= tail;
+ if (tail->previous)
+ tail->previous->next= vertex;
+ else
+ qh vertex_list= vertex;
+ tail->previous= vertex;
+ qh num_vertices++;
+ trace4((qh ferr, 4045, "qh_appendvertex: append v%d to vertex_list\n", vertex->id));
+} /* appendvertex */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="attachnewfacets">-</a>
+
+ qh_attachnewfacets( )
+ attach horizon facets to new facets in qh.newfacet_list
+ newfacets have neighbor and ridge links to horizon but not vice versa
+ only needed for qh.ONLYgood
+
+ returns:
+ set qh.NEWfacets
+ horizon facets linked to new facets
+ ridges changed from visible facets to new facets
+ simplicial ridges deleted
+ qh.visible_list, no ridges valid
+ facet->f.replace is a newfacet (if any)
+
+ design:
+ delete interior ridges and neighbor sets by
+ for each visible, non-simplicial facet
+ for each ridge
+ if last visit or if neighbor is simplicial
+ if horizon neighbor
+ delete ridge for horizon's ridge set
+ delete ridge
+ erase neighbor set
+ attach horizon facets and new facets by
+ for all new facets
+ if corresponding horizon facet is simplicial
+ locate corresponding visible facet {may be more than one}
+ link visible facet to new facet
+ replace visible facet with new facet in horizon
+ else it's non-simplicial
+ for all visible neighbors of the horizon facet
+ link visible neighbor to new facet
+ delete visible neighbor from horizon facet
+ append new facet to horizon's neighbors
+ the first ridge of the new facet is the horizon ridge
+ link the new facet into the horizon ridge
+*/
+void qh_attachnewfacets(void /* qh.visible_list, newfacet_list */) {
+ facetT *newfacet= NULL, *neighbor, **neighborp, *horizon, *visible;
+ ridgeT *ridge, **ridgep;
+
+ qh NEWfacets= True;
+ trace3((qh ferr, 3012, "qh_attachnewfacets: delete interior ridges\n"));
+ qh visit_id++;
+ FORALLvisible_facets {
+ visible->visitid= qh visit_id;
+ if (visible->ridges) {
+ FOREACHridge_(visible->ridges) {
+ neighbor= otherfacet_(ridge, visible);
+ if (neighbor->visitid == qh visit_id
+ || (!neighbor->visible && neighbor->simplicial)) {
+ if (!neighbor->visible) /* delete ridge for simplicial horizon */
+ qh_setdel(neighbor->ridges, ridge);
+ qh_setfree(&(ridge->vertices)); /* delete on 2nd visit */
+ qh_memfree(ridge, (int)sizeof(ridgeT));
+ }
+ }
+ SETfirst_(visible->ridges)= NULL;
+ }
+ SETfirst_(visible->neighbors)= NULL;
+ }
+ trace1((qh ferr, 1017, "qh_attachnewfacets: attach horizon facets to new facets\n"));
+ FORALLnew_facets {
+ horizon= SETfirstt_(newfacet->neighbors, facetT);
+ if (horizon->simplicial) {
+ visible= NULL;
+ FOREACHneighbor_(horizon) { /* may have more than one horizon ridge */
+ if (neighbor->visible) {
+ if (visible) {
+ if (qh_setequal_skip(newfacet->vertices, 0, horizon->vertices,
+ SETindex_(horizon->neighbors, neighbor))) {
+ visible= neighbor;
+ break;
+ }
+ }else
+ visible= neighbor;
+ }
+ }
+ if (visible) {
+ visible->f.replace= newfacet;
+ qh_setreplace(horizon->neighbors, visible, newfacet);
+ }else {
+ qh_fprintf(qh ferr, 6102, "qhull internal error (qh_attachnewfacets): couldn't find visible facet for horizon f%d of newfacet f%d\n",
+ horizon->id, newfacet->id);
+ qh_errexit2(qh_ERRqhull, horizon, newfacet);
+ }
+ }else { /* non-simplicial, with a ridge for newfacet */
+ FOREACHneighbor_(horizon) { /* may hold for many new facets */
+ if (neighbor->visible) {
+ neighbor->f.replace= newfacet;
+ qh_setdelnth(horizon->neighbors,
+ SETindex_(horizon->neighbors, neighbor));
+ neighborp--; /* repeat */
+ }
+ }
+ qh_setappend(&horizon->neighbors, newfacet);
+ ridge= SETfirstt_(newfacet->ridges, ridgeT);
+ if (ridge->top == horizon)
+ ridge->bottom= newfacet;
+ else
+ ridge->top= newfacet;
+ }
+ } /* newfacets */
+ if (qh PRINTstatistics) {
+ FORALLvisible_facets {
+ if (!visible->f.replace)
+ zinc_(Zinsidevisible);
+ }
+ }
+} /* attachnewfacets */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="checkflipped">-</a>
+
+ qh_checkflipped( facet, dist, allerror )
+ checks facet orientation to interior point
+
+ if allerror set,
+ tests against qh.DISTround
+ else
+ tests against 0 since tested against DISTround before
+
+ returns:
+ False if it flipped orientation (sets facet->flipped)
+ distance if non-NULL
+*/
+boolT qh_checkflipped(facetT *facet, realT *distp, boolT allerror) {
+ realT dist;
+
+ if (facet->flipped && !distp)
+ return False;
+ zzinc_(Zdistcheck);
+ qh_distplane(qh interior_point, facet, &dist);
+ if (distp)
+ *distp= dist;
+ if ((allerror && dist > -qh DISTround)|| (!allerror && dist >= 0.0)) {
+ facet->flipped= True;
+ zzinc_(Zflippedfacets);
+ trace0((qh ferr, 19, "qh_checkflipped: facet f%d is flipped, distance= %6.12g during p%d\n",
+ facet->id, dist, qh furthest_id));
+ qh_precision("flipped facet");
+ return False;
+ }
+ return True;
+} /* checkflipped */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="delfacet">-</a>
+
+ qh_delfacet( facet )
+ removes facet from facet_list and frees up its memory
+
+ notes:
+ assumes vertices and ridges already freed
+*/
+void qh_delfacet(facetT *facet) {
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+
+ trace4((qh ferr, 4046, "qh_delfacet: delete f%d\n", facet->id));
+ if (facet == qh tracefacet)
+ qh tracefacet= NULL;
+ if (facet == qh GOODclosest)
+ qh GOODclosest= NULL;
+ qh_removefacet(facet);
+ if (!facet->tricoplanar || facet->keepcentrum) {
+ qh_memfree_(facet->normal, qh normal_size, freelistp);
+ if (qh CENTERtype == qh_ASvoronoi) { /* braces for macro calls */
+ qh_memfree_(facet->center, qh center_size, freelistp);
+ }else /* AScentrum */ {
+ qh_memfree_(facet->center, qh normal_size, freelistp);
+ }
+ }
+ qh_setfree(&(facet->neighbors));
+ if (facet->ridges)
+ qh_setfree(&(facet->ridges));
+ qh_setfree(&(facet->vertices));
+ if (facet->outsideset)
+ qh_setfree(&(facet->outsideset));
+ if (facet->coplanarset)
+ qh_setfree(&(facet->coplanarset));
+ qh_memfree_(facet, (int)sizeof(facetT), freelistp);
+} /* delfacet */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="deletevisible">-</a>
+
+ qh_deletevisible()
+ delete visible facets and vertices
+
+ returns:
+ deletes each facet and removes from facetlist
+ at exit, qh.visible_list empty (== qh.newfacet_list)
+
+ notes:
+ ridges already deleted
+ horizon facets do not reference facets on qh.visible_list
+ new facets in qh.newfacet_list
+ uses qh.visit_id;
+*/
+void qh_deletevisible(void /*qh.visible_list*/) {
+ facetT *visible, *nextfacet;
+ vertexT *vertex, **vertexp;
+ int numvisible= 0, numdel= qh_setsize(qh del_vertices);
+
+ trace1((qh ferr, 1018, "qh_deletevisible: delete %d visible facets and %d vertices\n",
+ qh num_visible, numdel));
+ for (visible= qh visible_list; visible && visible->visible;
+ visible= nextfacet) { /* deleting current */
+ nextfacet= visible->next;
+ numvisible++;
+ qh_delfacet(visible);
+ }
+ if (numvisible != qh num_visible) {
+ qh_fprintf(qh ferr, 6103, "qhull internal error (qh_deletevisible): qh num_visible %d is not number of visible facets %d\n",
+ qh num_visible, numvisible);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ qh num_visible= 0;
+ zadd_(Zvisfacettot, numvisible);
+ zmax_(Zvisfacetmax, numvisible);
+ zzadd_(Zdelvertextot, numdel);
+ zmax_(Zdelvertexmax, numdel);
+ FOREACHvertex_(qh del_vertices)
+ qh_delvertex(vertex);
+ qh_settruncate(qh del_vertices, 0);
+} /* deletevisible */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="facetintersect">-</a>
+
+ qh_facetintersect( facetA, facetB, skipa, skipB, prepend )
+ return vertices for intersection of two simplicial facets
+ may include 1 prepended entry (if more, need to settemppush)
+
+ returns:
+ returns set of qh.hull_dim-1 + prepend vertices
+ returns skipped index for each test and checks for exactly one
+
+ notes:
+ does not need settemp since set in quick memory
+
+ see also:
+ qh_vertexintersect and qh_vertexintersect_new
+ use qh_setnew_delnthsorted to get nth ridge (no skip information)
+
+ design:
+ locate skipped vertex by scanning facet A's neighbors
+ locate skipped vertex by scanning facet B's neighbors
+ intersect the vertex sets
+*/
+setT *qh_facetintersect(facetT *facetA, facetT *facetB,
+ int *skipA,int *skipB, int prepend) {
+ setT *intersect;
+ int dim= qh hull_dim, i, j;
+ facetT **neighborsA, **neighborsB;
+
+ neighborsA= SETaddr_(facetA->neighbors, facetT);
+ neighborsB= SETaddr_(facetB->neighbors, facetT);
+ i= j= 0;
+ if (facetB == *neighborsA++)
+ *skipA= 0;
+ else if (facetB == *neighborsA++)
+ *skipA= 1;
+ else if (facetB == *neighborsA++)
+ *skipA= 2;
+ else {
+ for (i=3; i < dim; i++) {
+ if (facetB == *neighborsA++) {
+ *skipA= i;
+ break;
+ }
+ }
+ }
+ if (facetA == *neighborsB++)
+ *skipB= 0;
+ else if (facetA == *neighborsB++)
+ *skipB= 1;
+ else if (facetA == *neighborsB++)
+ *skipB= 2;
+ else {
+ for (j=3; j < dim; j++) {
+ if (facetA == *neighborsB++) {
+ *skipB= j;
+ break;
+ }
+ }
+ }
+ if (i >= dim || j >= dim) {
+ qh_fprintf(qh ferr, 6104, "qhull internal error (qh_facetintersect): f%d or f%d not in others neighbors\n",
+ facetA->id, facetB->id);
+ qh_errexit2(qh_ERRqhull, facetA, facetB);
+ }
+ intersect= qh_setnew_delnthsorted(facetA->vertices, qh hull_dim, *skipA, prepend);
+ trace4((qh ferr, 4047, "qh_facetintersect: f%d skip %d matches f%d skip %d\n",
+ facetA->id, *skipA, facetB->id, *skipB));
+ return(intersect);
+} /* facetintersect */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="gethash">-</a>
+
+ qh_gethash( hashsize, set, size, firstindex, skipelem )
+ return hashvalue for a set with firstindex and skipelem
+
+ notes:
+ returned hash is in [0,hashsize)
+ assumes at least firstindex+1 elements
+ assumes skipelem is NULL, in set, or part of hash
+
+ hashes memory addresses which may change over different runs of the same data
+ using sum for hash does badly in high d
+*/
+int qh_gethash(int hashsize, setT *set, int size, int firstindex, void *skipelem) {
+ void **elemp= SETelemaddr_(set, firstindex, void);
+ ptr_intT hash = 0, elem;
+ unsigned result;
+ int i;
+#ifdef _MSC_VER /* Microsoft Visual C++ -- warn about 64-bit issues */
+#pragma warning( push) /* WARN64 -- ptr_intT holds a 64-bit pointer */
+#pragma warning( disable : 4311) /* 'type cast': pointer truncation from 'void*' to 'ptr_intT' */
+#endif
+
+ switch (size-firstindex) {
+ case 1:
+ hash= (ptr_intT)(*elemp) - (ptr_intT) skipelem;
+ break;
+ case 2:
+ hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] - (ptr_intT) skipelem;
+ break;
+ case 3:
+ hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
+ - (ptr_intT) skipelem;
+ break;
+ case 4:
+ hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
+ + (ptr_intT)elemp[3] - (ptr_intT) skipelem;
+ break;
+ case 5:
+ hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
+ + (ptr_intT)elemp[3] + (ptr_intT)elemp[4] - (ptr_intT) skipelem;
+ break;
+ case 6:
+ hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
+ + (ptr_intT)elemp[3] + (ptr_intT)elemp[4]+ (ptr_intT)elemp[5]
+ - (ptr_intT) skipelem;
+ break;
+ default:
+ hash= 0;
+ i= 3;
+ do { /* this is about 10% in 10-d */
+ if ((elem= (ptr_intT)*elemp++) != (ptr_intT)skipelem) {
+ hash ^= (elem << i) + (elem >> (32-i));
+ i += 3;
+ if (i >= 32)
+ i -= 32;
+ }
+ }while (*elemp);
+ break;
+ }
+ if (hashsize<0) {
+ qh_fprintf(qh ferr, 6202, "qhull internal error: negative hashsize %d passed to qh_gethash [poly.c]\n", hashsize);
+ qh_errexit2(qh_ERRqhull, NULL, NULL);
+ }
+ result= (unsigned)hash;
+ result %= (unsigned)hashsize;
+ /* result= 0; for debugging */
+ return result;
+#ifdef _MSC_VER
+#pragma warning( pop)
+#endif
+} /* gethash */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="makenewfacet">-</a>
+
+ qh_makenewfacet( vertices, toporient, horizon )
+ creates a toporient? facet from vertices
+
+ returns:
+ returns newfacet
+ adds newfacet to qh.facet_list
+ newfacet->vertices= vertices
+ if horizon
+ newfacet->neighbor= horizon, but not vice versa
+ newvertex_list updated with vertices
+*/
+facetT *qh_makenewfacet(setT *vertices, boolT toporient,facetT *horizon) {
+ facetT *newfacet;
+ vertexT *vertex, **vertexp;
+
+ FOREACHvertex_(vertices) {
+ if (!vertex->newlist) {
+ qh_removevertex(vertex);
+ qh_appendvertex(vertex);
+ }
+ }
+ newfacet= qh_newfacet();
+ newfacet->vertices= vertices;
+ newfacet->toporient= (unsigned char)toporient;
+ if (horizon)
+ qh_setappend(&(newfacet->neighbors), horizon);
+ qh_appendfacet(newfacet);
+ return(newfacet);
+} /* makenewfacet */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="makenewplanes">-</a>
+
+ qh_makenewplanes()
+ make new hyperplanes for facets on qh.newfacet_list
+
+ returns:
+ all facets have hyperplanes or are marked for merging
+ doesn't create hyperplane if horizon is coplanar (will merge)
+ updates qh.min_vertex if qh.JOGGLEmax
+
+ notes:
+ facet->f.samecycle is defined for facet->mergehorizon facets
+*/
+void qh_makenewplanes(void /* newfacet_list */) {
+ facetT *newfacet;
+
+ FORALLnew_facets {
+ if (!newfacet->mergehorizon)
+ qh_setfacetplane(newfacet);
+ }
+ if (qh JOGGLEmax < REALmax/2)
+ minimize_(qh min_vertex, -wwval_(Wnewvertexmax));
+} /* makenewplanes */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="makenew_nonsimplicial">-</a>
+
+ qh_makenew_nonsimplicial( visible, apex, numnew )
+ make new facets for ridges of a visible facet
+
+ returns:
+ first newfacet, bumps numnew as needed
+ attaches new facets if !qh.ONLYgood
+ marks ridge neighbors for simplicial visible
+ if (qh.ONLYgood)
+ ridges on newfacet, horizon, and visible
+ else
+ ridge and neighbors between newfacet and horizon
+ visible facet's ridges are deleted
+
+ notes:
+ qh.visit_id if visible has already been processed
+ sets neighbor->seen for building f.samecycle
+ assumes all 'seen' flags initially false
+
+ design:
+ for each ridge of visible facet
+ get neighbor of visible facet
+ if neighbor was already processed
+ delete the ridge (will delete all visible facets later)
+ if neighbor is a horizon facet
+ create a new facet
+ if neighbor coplanar
+ adds newfacet to f.samecycle for later merging
+ else
+ updates neighbor's neighbor set
+ (checks for non-simplicial facet with multiple ridges to visible facet)
+ updates neighbor's ridge set
+ (checks for simplicial neighbor to non-simplicial visible facet)
+ (deletes ridge if neighbor is simplicial)
+
+*/
+#ifndef qh_NOmerge
+facetT *qh_makenew_nonsimplicial(facetT *visible, vertexT *apex, int *numnew) {
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+ ridgeT *ridge, **ridgep;
+ facetT *neighbor, *newfacet= NULL, *samecycle;
+ setT *vertices;
+ boolT toporient;
+ int ridgeid;
+
+ FOREACHridge_(visible->ridges) {
+ ridgeid= ridge->id;
+ neighbor= otherfacet_(ridge, visible);
+ if (neighbor->visible) {
+ if (!qh ONLYgood) {
+ if (neighbor->visitid == qh visit_id) {
+ qh_setfree(&(ridge->vertices)); /* delete on 2nd visit */
+ qh_memfree_(ridge, (int)sizeof(ridgeT), freelistp);
+ }
+ }
+ }else { /* neighbor is an horizon facet */
+ toporient= (ridge->top == visible);
+ vertices= qh_setnew(qh hull_dim); /* makes sure this is quick */
+ qh_setappend(&vertices, apex);
+ qh_setappend_set(&vertices, ridge->vertices);
+ newfacet= qh_makenewfacet(vertices, toporient, neighbor);
+ (*numnew)++;
+ if (neighbor->coplanar) {
+ newfacet->mergehorizon= True;
+ if (!neighbor->seen) {
+ newfacet->f.samecycle= newfacet;
+ neighbor->f.newcycle= newfacet;
+ }else {
+ samecycle= neighbor->f.newcycle;
+ newfacet->f.samecycle= samecycle->f.samecycle;
+ samecycle->f.samecycle= newfacet;
+ }
+ }
+ if (qh ONLYgood) {
+ if (!neighbor->simplicial)
+ qh_setappend(&(newfacet->ridges), ridge);
+ }else { /* qh_attachnewfacets */
+ if (neighbor->seen) {
+ if (neighbor->simplicial) {
+ qh_fprintf(qh ferr, 6105, "qhull internal error (qh_makenew_nonsimplicial): simplicial f%d sharing two ridges with f%d\n",
+ neighbor->id, visible->id);
+ qh_errexit2(qh_ERRqhull, neighbor, visible);
+ }
+ qh_setappend(&(neighbor->neighbors), newfacet);
+ }else
+ qh_setreplace(neighbor->neighbors, visible, newfacet);
+ if (neighbor->simplicial) {
+ qh_setdel(neighbor->ridges, ridge);
+ qh_setfree(&(ridge->vertices));
+ qh_memfree(ridge, (int)sizeof(ridgeT));
+ }else {
+ qh_setappend(&(newfacet->ridges), ridge);
+ if (toporient)
+ ridge->top= newfacet;
+ else
+ ridge->bottom= newfacet;
+ }
+ trace4((qh ferr, 4048, "qh_makenew_nonsimplicial: created facet f%d from v%d and r%d of horizon f%d\n",
+ newfacet->id, apex->id, ridgeid, neighbor->id));
+ }
+ }
+ neighbor->seen= True;
+ } /* for each ridge */
+ if (!qh ONLYgood)
+ SETfirst_(visible->ridges)= NULL;
+ return newfacet;
+} /* makenew_nonsimplicial */
+#else /* qh_NOmerge */
+facetT *qh_makenew_nonsimplicial(facetT *visible, vertexT *apex, int *numnew) {
+ return NULL;
+}
+#endif /* qh_NOmerge */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="makenew_simplicial">-</a>
+
+ qh_makenew_simplicial( visible, apex, numnew )
+ make new facets for simplicial visible facet and apex
+
+ returns:
+ attaches new facets if (!qh.ONLYgood)
+ neighbors between newfacet and horizon
+
+ notes:
+ nop if neighbor->seen or neighbor->visible(see qh_makenew_nonsimplicial)
+
+ design:
+ locate neighboring horizon facet for visible facet
+ determine vertices and orientation
+ create new facet
+ if coplanar,
+ add new facet to f.samecycle
+ update horizon facet's neighbor list
+*/
+facetT *qh_makenew_simplicial(facetT *visible, vertexT *apex, int *numnew) {
+ facetT *neighbor, **neighborp, *newfacet= NULL;
+ setT *vertices;
+ boolT flip, toporient;
+ int horizonskip= 0, visibleskip= 0;
+
+ FOREACHneighbor_(visible) {
+ if (!neighbor->seen && !neighbor->visible) {
+ vertices= qh_facetintersect(neighbor,visible, &horizonskip, &visibleskip, 1);
+ SETfirst_(vertices)= apex;
+ flip= ((horizonskip & 0x1) ^ (visibleskip & 0x1));
+ if (neighbor->toporient)
+ toporient= horizonskip & 0x1;
+ else
+ toporient= (horizonskip & 0x1) ^ 0x1;
+ newfacet= qh_makenewfacet(vertices, toporient, neighbor);
+ (*numnew)++;
+ if (neighbor->coplanar && (qh PREmerge || qh MERGEexact)) {
+#ifndef qh_NOmerge
+ newfacet->f.samecycle= newfacet;
+ newfacet->mergehorizon= True;
+#endif
+ }
+ if (!qh ONLYgood)
+ SETelem_(neighbor->neighbors, horizonskip)= newfacet;
+ trace4((qh ferr, 4049, "qh_makenew_simplicial: create facet f%d top %d from v%d and horizon f%d skip %d top %d and visible f%d skip %d, flip? %d\n",
+ newfacet->id, toporient, apex->id, neighbor->id, horizonskip,
+ neighbor->toporient, visible->id, visibleskip, flip));
+ }
+ }
+ return newfacet;
+} /* makenew_simplicial */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="matchneighbor">-</a>
+
+ qh_matchneighbor( newfacet, newskip, hashsize, hashcount )
+ either match subridge of newfacet with neighbor or add to hash_table
+
+ returns:
+ duplicate ridges are unmatched and marked by qh_DUPLICATEridge
+
+ notes:
+ ridge is newfacet->vertices w/o newskip vertex
+ do not allocate memory (need to free hash_table cleanly)
+ uses linear hash chains
+
+ see also:
+ qh_matchduplicates
+
+ design:
+ for each possible matching facet in qh.hash_table
+ if vertices match
+ set ismatch, if facets have opposite orientation
+ if ismatch and matching facet doesn't have a match
+ match the facets by updating their neighbor sets
+ else
+ indicate a duplicate ridge
+ set facet hyperplane for later testing
+ add facet to hashtable
+ unless the other facet was already a duplicate ridge
+ mark both facets with a duplicate ridge
+ add other facet (if defined) to hash table
+*/
+void qh_matchneighbor(facetT *newfacet, int newskip, int hashsize, int *hashcount) {
+ boolT newfound= False; /* True, if new facet is already in hash chain */
+ boolT same, ismatch;
+ int hash, scan;
+ facetT *facet, *matchfacet;
+ int skip, matchskip;
+
+ hash= qh_gethash(hashsize, newfacet->vertices, qh hull_dim, 1,
+ SETelem_(newfacet->vertices, newskip));
+ trace4((qh ferr, 4050, "qh_matchneighbor: newfacet f%d skip %d hash %d hashcount %d\n",
+ newfacet->id, newskip, hash, *hashcount));
+ zinc_(Zhashlookup);
+ for (scan= hash; (facet= SETelemt_(qh hash_table, scan, facetT));
+ scan= (++scan >= hashsize ? 0 : scan)) {
+ if (facet == newfacet) {
+ newfound= True;
+ continue;
+ }
+ zinc_(Zhashtests);
+ if (qh_matchvertices(1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) {
+ if (SETelem_(newfacet->vertices, newskip) ==
+ SETelem_(facet->vertices, skip)) {
+ qh_precision("two facets with the same vertices");
+ qh_fprintf(qh ferr, 6106, "qhull precision error: Vertex sets are the same for f%d and f%d. Can not force output.\n",
+ facet->id, newfacet->id);
+ qh_errexit2(qh_ERRprec, facet, newfacet);
+ }
+ ismatch= (same == (boolT)((newfacet->toporient ^ facet->toporient)));
+ matchfacet= SETelemt_(facet->neighbors, skip, facetT);
+ if (ismatch && !matchfacet) {
+ SETelem_(facet->neighbors, skip)= newfacet;
+ SETelem_(newfacet->neighbors, newskip)= facet;
+ (*hashcount)--;
+ trace4((qh ferr, 4051, "qh_matchneighbor: f%d skip %d matched with new f%d skip %d\n",
+ facet->id, skip, newfacet->id, newskip));
+ return;
+ }
+ if (!qh PREmerge && !qh MERGEexact) {
+ qh_precision("a ridge with more than two neighbors");
+ qh_fprintf(qh ferr, 6107, "qhull precision error: facets f%d, f%d and f%d meet at a ridge with more than 2 neighbors. Can not continue.\n",
+ facet->id, newfacet->id, getid_(matchfacet));
+ qh_errexit2(qh_ERRprec, facet, newfacet);
+ }
+ SETelem_(newfacet->neighbors, newskip)= qh_DUPLICATEridge;
+ newfacet->dupridge= True;
+ if (!newfacet->normal)
+ qh_setfacetplane(newfacet);
+ qh_addhash(newfacet, qh hash_table, hashsize, hash);
+ (*hashcount)++;
+ if (!facet->normal)
+ qh_setfacetplane(facet);
+ if (matchfacet != qh_DUPLICATEridge) {
+ SETelem_(facet->neighbors, skip)= qh_DUPLICATEridge;
+ facet->dupridge= True;
+ if (!facet->normal)
+ qh_setfacetplane(facet);
+ if (matchfacet) {
+ matchskip= qh_setindex(matchfacet->neighbors, facet);
+ if (matchskip<0) {
+ qh_fprintf(qh ferr, 6260, "qhull internal error (qh_matchneighbor): matchfacet f%d is in f%d neighbors but not vice versa. Can not continue.\n",
+ matchfacet->id, facet->id);
+ qh_errexit2(qh_ERRqhull, matchfacet, facet);
+ }
+ SETelem_(matchfacet->neighbors, matchskip)= qh_DUPLICATEridge; /* matchskip>=0 by QH6260 */
+ matchfacet->dupridge= True;
+ if (!matchfacet->normal)
+ qh_setfacetplane(matchfacet);
+ qh_addhash(matchfacet, qh hash_table, hashsize, hash);
+ *hashcount += 2;
+ }
+ }
+ trace4((qh ferr, 4052, "qh_matchneighbor: new f%d skip %d duplicates ridge for f%d skip %d matching f%d ismatch %d at hash %d\n",
+ newfacet->id, newskip, facet->id, skip,
+ (matchfacet == qh_DUPLICATEridge ? -2 : getid_(matchfacet)),
+ ismatch, hash));
+ return; /* end of duplicate ridge */
+ }
+ }
+ if (!newfound)
+ SETelem_(qh hash_table, scan)= newfacet; /* same as qh_addhash */
+ (*hashcount)++;
+ trace4((qh ferr, 4053, "qh_matchneighbor: no match for f%d skip %d at hash %d\n",
+ newfacet->id, newskip, hash));
+} /* matchneighbor */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="matchnewfacets">-</a>
+
+ qh_matchnewfacets()
+ match newfacets in qh.newfacet_list to their newfacet neighbors
+
+ returns:
+ qh.newfacet_list with full neighbor sets
+ get vertices with nth neighbor by deleting nth vertex
+ if qh.PREmerge/MERGEexact or qh.FORCEoutput
+ sets facet->flippped if flipped normal (also prevents point partitioning)
+ if duplicate ridges and qh.PREmerge/MERGEexact
+ sets facet->dupridge
+ missing neighbor links identifies extra ridges to be merging (qh_MERGEridge)
+
+ notes:
+ newfacets already have neighbor[0] (horizon facet)
+ assumes qh.hash_table is NULL
+ vertex->neighbors has not been updated yet
+ do not allocate memory after qh.hash_table (need to free it cleanly)
+
+ design:
+ delete neighbor sets for all new facets
+ initialize a hash table
+ for all new facets
+ match facet with neighbors
+ if unmatched facets (due to duplicate ridges)
+ for each new facet with a duplicate ridge
+ match it with a facet
+ check for flipped facets
+*/
+void qh_matchnewfacets(void /* qh.newfacet_list */) {
+ int numnew=0, hashcount=0, newskip;
+ facetT *newfacet, *neighbor;
+ int dim= qh hull_dim, hashsize, neighbor_i, neighbor_n;
+ setT *neighbors;
+#ifndef qh_NOtrace
+ int facet_i, facet_n, numfree= 0;
+ facetT *facet;
+#endif
+
+ trace1((qh ferr, 1019, "qh_matchnewfacets: match neighbors for new facets.\n"));
+ FORALLnew_facets {
+ numnew++;
+ { /* inline qh_setzero(newfacet->neighbors, 1, qh hull_dim); */
+ neighbors= newfacet->neighbors;
+ neighbors->e[neighbors->maxsize].i= dim+1; /*may be overwritten*/
+ memset((char *)SETelemaddr_(neighbors, 1, void), 0, dim * SETelemsize);
+ }
+ }
+
+ qh_newhashtable(numnew*(qh hull_dim-1)); /* twice what is normally needed,
+ but every ridge could be DUPLICATEridge */
+ hashsize= qh_setsize(qh hash_table);
+ FORALLnew_facets {
+ for (newskip=1; newskip<qh hull_dim; newskip++) /* furthest/horizon already matched */
+ /* hashsize>0 because hull_dim>1 and numnew>0 */
+ qh_matchneighbor(newfacet, newskip, hashsize, &hashcount);
+#if 0 /* use the following to trap hashcount errors */
+ {
+ int count= 0, k;
+ facetT *facet, *neighbor;
+
+ count= 0;
+ FORALLfacet_(qh newfacet_list) { /* newfacet already in use */
+ for (k=1; k < qh hull_dim; k++) {
+ neighbor= SETelemt_(facet->neighbors, k, facetT);
+ if (!neighbor || neighbor == qh_DUPLICATEridge)
+ count++;
+ }
+ if (facet == newfacet)
+ break;
+ }
+ if (count != hashcount) {
+ qh_fprintf(qh ferr, 8088, "qh_matchnewfacets: after adding facet %d, hashcount %d != count %d\n",
+ newfacet->id, hashcount, count);
+ qh_errexit(qh_ERRqhull, newfacet, NULL);
+ }
+ }
+#endif /* end of trap code */
+ }
+ if (hashcount) {
+ FORALLnew_facets {
+ if (newfacet->dupridge) {
+ FOREACHneighbor_i_(newfacet) {
+ if (neighbor == qh_DUPLICATEridge) {
+ qh_matchduplicates(newfacet, neighbor_i, hashsize, &hashcount);
+ /* this may report MERGEfacet */
+ }
+ }
+ }
+ }
+ }
+ if (hashcount) {
+ qh_fprintf(qh ferr, 6108, "qhull internal error (qh_matchnewfacets): %d neighbors did not match up\n",
+ hashcount);
+ qh_printhashtable(qh ferr);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+#ifndef qh_NOtrace
+ if (qh IStracing >= 2) {
+ FOREACHfacet_i_(qh hash_table) {
+ if (!facet)
+ numfree++;
+ }
+ qh_fprintf(qh ferr, 8089, "qh_matchnewfacets: %d new facets, %d unused hash entries . hashsize %d\n",
+ numnew, numfree, qh_setsize(qh hash_table));
+ }
+#endif /* !qh_NOtrace */
+ qh_setfree(&qh hash_table);
+ if (qh PREmerge || qh MERGEexact) {
+ if (qh IStracing >= 4)
+ qh_printfacetlist(qh newfacet_list, NULL, qh_ALL);
+ FORALLnew_facets {
+ if (newfacet->normal)
+ qh_checkflipped(newfacet, NULL, qh_ALL);
+ }
+ }else if (qh FORCEoutput)
+ qh_checkflipped_all(qh newfacet_list); /* prints warnings for flipped */
+} /* matchnewfacets */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="matchvertices">-</a>
+
+ qh_matchvertices( firstindex, verticesA, skipA, verticesB, skipB, same )
+ tests whether vertices match with a single skip
+ starts match at firstindex since all new facets have a common vertex
+
+ returns:
+ true if matched vertices
+ skip index for each set
+ sets same iff vertices have the same orientation
+
+ notes:
+ assumes skipA is in A and both sets are the same size
+
+ design:
+ set up pointers
+ scan both sets checking for a match
+ test orientation
+*/
+boolT qh_matchvertices(int firstindex, setT *verticesA, int skipA,
+ setT *verticesB, int *skipB, boolT *same) {
+ vertexT **elemAp, **elemBp, **skipBp=NULL, **skipAp;
+
+ elemAp= SETelemaddr_(verticesA, firstindex, vertexT);
+ elemBp= SETelemaddr_(verticesB, firstindex, vertexT);
+ skipAp= SETelemaddr_(verticesA, skipA, vertexT);
+ do if (elemAp != skipAp) {
+ while (*elemAp != *elemBp++) {
+ if (skipBp)
+ return False;
+ skipBp= elemBp; /* one extra like FOREACH */
+ }
+ }while (*(++elemAp));
+ if (!skipBp)
+ skipBp= ++elemBp;
+ *skipB= SETindex_(verticesB, skipB); /* i.e., skipBp - verticesB */
+ *same= !((skipA & 0x1) ^ (*skipB & 0x1)); /* result is 0 or 1 */
+ trace4((qh ferr, 4054, "qh_matchvertices: matched by skip %d(v%d) and skip %d(v%d) same? %d\n",
+ skipA, (*skipAp)->id, *skipB, (*(skipBp-1))->id, *same));
+ return(True);
+} /* matchvertices */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="newfacet">-</a>
+
+ qh_newfacet()
+ return a new facet
+
+ returns:
+ all fields initialized or cleared (NULL)
+ preallocates neighbors set
+*/
+facetT *qh_newfacet(void) {
+ facetT *facet;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+
+ qh_memalloc_((int)sizeof(facetT), freelistp, facet, facetT);
+ memset((char *)facet, (size_t)0, sizeof(facetT));
+ if (qh facet_id == qh tracefacet_id)
+ qh tracefacet= facet;
+ facet->id= qh facet_id++;
+ facet->neighbors= qh_setnew(qh hull_dim);
+#if !qh_COMPUTEfurthest
+ facet->furthestdist= 0.0;
+#endif
+#if qh_MAXoutside
+ if (qh FORCEoutput && qh APPROXhull)
+ facet->maxoutside= qh MINoutside;
+ else
+ facet->maxoutside= qh DISTround;
+#endif
+ facet->simplicial= True;
+ facet->good= True;
+ facet->newfacet= True;
+ trace4((qh ferr, 4055, "qh_newfacet: created facet f%d\n", facet->id));
+ return(facet);
+} /* newfacet */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="newridge">-</a>
+
+ qh_newridge()
+ return a new ridge
+*/
+ridgeT *qh_newridge(void) {
+ ridgeT *ridge;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+
+ qh_memalloc_((int)sizeof(ridgeT), freelistp, ridge, ridgeT);
+ memset((char *)ridge, (size_t)0, sizeof(ridgeT));
+ zinc_(Ztotridges);
+ if (qh ridge_id == UINT_MAX) {
+ qh_fprintf(qh ferr, 7074, "\
+qhull warning: more than 2^32 ridges. Qhull results are OK. Since the ridge ID wraps around to 0, two ridges may have the same identifier.\n");
+ }
+ ridge->id= qh ridge_id++;
+ trace4((qh ferr, 4056, "qh_newridge: created ridge r%d\n", ridge->id));
+ return(ridge);
+} /* newridge */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="pointid">-</a>
+
+ qh_pointid( point )
+ return id for a point,
+ returns qh_IDnone(-3) if null, qh_IDinterior(-2) if interior, or qh_IDunknown(-1) if not known
+
+ alternative code if point is in qh.first_point...
+ unsigned long id;
+ id= ((unsigned long)point - (unsigned long)qh.first_point)/qh.normal_size;
+
+ notes:
+ Valid points are non-negative
+ WARN64 -- id truncated to 32-bits, at most 2G points
+ NOerrors returned (QhullPoint::id)
+ if point not in point array
+ the code does a comparison of unrelated pointers.
+*/
+int qh_pointid(pointT *point) {
+ ptr_intT offset, id;
+
+ if (!point)
+ return qh_IDnone;
+ else if (point == qh interior_point)
+ return qh_IDinterior;
+ else if (point >= qh first_point
+ && point < qh first_point + qh num_points * qh hull_dim) {
+ offset= (ptr_intT)(point - qh first_point);
+ id= offset / qh hull_dim;
+ }else if ((id= qh_setindex(qh other_points, point)) != -1)
+ id += qh num_points;
+ else
+ return qh_IDunknown;
+ return (int)id;
+} /* pointid */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="removefacet">-</a>
+
+ qh_removefacet( facet )
+ unlinks facet from qh.facet_list,
+
+ returns:
+ updates qh.facet_list .newfacet_list .facet_next visible_list
+ decrements qh.num_facets
+
+ see:
+ qh_appendfacet
+*/
+void qh_removefacet(facetT *facet) {
+ facetT *next= facet->next, *previous= facet->previous;
+
+ if (facet == qh newfacet_list)
+ qh newfacet_list= next;
+ if (facet == qh facet_next)
+ qh facet_next= next;
+ if (facet == qh visible_list)
+ qh visible_list= next;
+ if (previous) {
+ previous->next= next;
+ next->previous= previous;
+ }else { /* 1st facet in qh facet_list */
+ qh facet_list= next;
+ qh facet_list->previous= NULL;
+ }
+ qh num_facets--;
+ trace4((qh ferr, 4057, "qh_removefacet: remove f%d from facet_list\n", facet->id));
+} /* removefacet */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="removevertex">-</a>
+
+ qh_removevertex( vertex )
+ unlinks vertex from qh.vertex_list,
+
+ returns:
+ updates qh.vertex_list .newvertex_list
+ decrements qh.num_vertices
+*/
+void qh_removevertex(vertexT *vertex) {
+ vertexT *next= vertex->next, *previous= vertex->previous;
+
+ if (vertex == qh newvertex_list)
+ qh newvertex_list= next;
+ if (previous) {
+ previous->next= next;
+ next->previous= previous;
+ }else { /* 1st vertex in qh vertex_list */
+ qh vertex_list= vertex->next;
+ qh vertex_list->previous= NULL;
+ }
+ qh num_vertices--;
+ trace4((qh ferr, 4058, "qh_removevertex: remove v%d from vertex_list\n", vertex->id));
+} /* removevertex */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="updatevertices">-</a>
+
+ qh_updatevertices()
+ update vertex neighbors and delete interior vertices
+
+ returns:
+ if qh.VERTEXneighbors, updates neighbors for each vertex
+ if qh.newvertex_list,
+ removes visible neighbors from vertex neighbors
+ if qh.newfacet_list
+ adds new facets to vertex neighbors
+ if qh.visible_list
+ interior vertices added to qh.del_vertices for later partitioning
+
+ design:
+ if qh.VERTEXneighbors
+ deletes references to visible facets from vertex neighbors
+ appends new facets to the neighbor list for each vertex
+ checks all vertices of visible facets
+ removes visible facets from neighbor lists
+ marks unused vertices for deletion
+*/
+void qh_updatevertices(void /*qh.newvertex_list, newfacet_list, visible_list*/) {
+ facetT *newfacet= NULL, *neighbor, **neighborp, *visible;
+ vertexT *vertex, **vertexp;
+
+ trace3((qh ferr, 3013, "qh_updatevertices: delete interior vertices and update vertex->neighbors\n"));
+ if (qh VERTEXneighbors) {
+ FORALLvertex_(qh newvertex_list) {
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visible)
+ SETref_(neighbor)= NULL;
+ }
+ qh_setcompact(vertex->neighbors);
+ }
+ FORALLnew_facets {
+ FOREACHvertex_(newfacet->vertices)
+ qh_setappend(&vertex->neighbors, newfacet);
+ }
+ FORALLvisible_facets {
+ FOREACHvertex_(visible->vertices) {
+ if (!vertex->newlist && !vertex->deleted) {
+ FOREACHneighbor_(vertex) { /* this can happen under merging */
+ if (!neighbor->visible)
+ break;
+ }
+ if (neighbor)
+ qh_setdel(vertex->neighbors, visible);
+ else {
+ vertex->deleted= True;
+ qh_setappend(&qh del_vertices, vertex);
+ trace2((qh ferr, 2041, "qh_updatevertices: delete vertex p%d(v%d) in f%d\n",
+ qh_pointid(vertex->point), vertex->id, visible->id));
+ }
+ }
+ }
+ }
+ }else { /* !VERTEXneighbors */
+ FORALLvisible_facets {
+ FOREACHvertex_(visible->vertices) {
+ if (!vertex->newlist && !vertex->deleted) {
+ vertex->deleted= True;
+ qh_setappend(&qh del_vertices, vertex);
+ trace2((qh ferr, 2042, "qh_updatevertices: delete vertex p%d(v%d) in f%d\n",
+ qh_pointid(vertex->point), vertex->id, visible->id));
+ }
+ }
+ }
+ }
+} /* updatevertices */
+
+
+
diff --git a/xs/src/qhull/src/libqhull/poly.h b/xs/src/qhull/src/libqhull/poly.h
new file mode 100644
index 000000000..af8b42077
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/poly.h
@@ -0,0 +1,296 @@
+/*<html><pre> -<a href="qh-poly.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ poly.h
+ header file for poly.c and poly2.c
+
+ see qh-poly.htm, libqhull.h and poly.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/poly.h#3 $$Change: 2047 $
+ $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $
+*/
+
+#ifndef qhDEFpoly
+#define qhDEFpoly 1
+
+#include "libqhull.h"
+
+/*=============== constants ========================== */
+
+/*-<a href="qh-geom.htm#TOC"
+ >--------------------------------</a><a name="ALGORITHMfault">-</a>
+
+ ALGORITHMfault
+ use as argument to checkconvex() to report errors during buildhull
+*/
+#define qh_ALGORITHMfault 0
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="DATAfault">-</a>
+
+ DATAfault
+ use as argument to checkconvex() to report errors during initialhull
+*/
+#define qh_DATAfault 1
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="DUPLICATEridge">-</a>
+
+ DUPLICATEridge
+ special value for facet->neighbor to indicate a duplicate ridge
+
+ notes:
+ set by matchneighbor, used by matchmatch and mark_dupridge
+*/
+#define qh_DUPLICATEridge (facetT *)1L
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="MERGEridge">-</a>
+
+ MERGEridge flag in facet
+ special value for facet->neighbor to indicate a merged ridge
+
+ notes:
+ set by matchneighbor, used by matchmatch and mark_dupridge
+*/
+#define qh_MERGEridge (facetT *)2L
+
+
+/*============ -structures- ====================*/
+
+/*=========== -macros- =========================*/
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FORALLfacet_">-</a>
+
+ FORALLfacet_( facetlist ) { ... }
+ assign 'facet' to each facet in facetlist
+
+ notes:
+ uses 'facetT *facet;'
+ assumes last facet is a sentinel
+
+ see:
+ FORALLfacets
+*/
+#define FORALLfacet_( facetlist ) if (facetlist ) for ( facet=( facetlist ); facet && facet->next; facet= facet->next )
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FORALLnew_facets">-</a>
+
+ FORALLnew_facets { ... }
+ assign 'newfacet' to each facet in qh.newfacet_list
+
+ notes:
+ uses 'facetT *newfacet;'
+ at exit, newfacet==NULL
+*/
+#define FORALLnew_facets for ( newfacet=qh newfacet_list;newfacet && newfacet->next;newfacet=newfacet->next )
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FORALLvertex_">-</a>
+
+ FORALLvertex_( vertexlist ) { ... }
+ assign 'vertex' to each vertex in vertexlist
+
+ notes:
+ uses 'vertexT *vertex;'
+ at exit, vertex==NULL
+*/
+#define FORALLvertex_( vertexlist ) for (vertex=( vertexlist );vertex && vertex->next;vertex= vertex->next )
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FORALLvisible_facets">-</a>
+
+ FORALLvisible_facets { ... }
+ assign 'visible' to each visible facet in qh.visible_list
+
+ notes:
+ uses 'vacetT *visible;'
+ at exit, visible==NULL
+*/
+#define FORALLvisible_facets for (visible=qh visible_list; visible && visible->visible; visible= visible->next)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FORALLsame_">-</a>
+
+ FORALLsame_( newfacet ) { ... }
+ assign 'same' to each facet in newfacet->f.samecycle
+
+ notes:
+ uses 'facetT *same;'
+ stops when it returns to newfacet
+*/
+#define FORALLsame_(newfacet) for (same= newfacet->f.samecycle; same != newfacet; same= same->f.samecycle)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FORALLsame_cycle_">-</a>
+
+ FORALLsame_cycle_( newfacet ) { ... }
+ assign 'same' to each facet in newfacet->f.samecycle
+
+ notes:
+ uses 'facetT *same;'
+ at exit, same == NULL
+*/
+#define FORALLsame_cycle_(newfacet) \
+ for (same= newfacet->f.samecycle; \
+ same; same= (same == newfacet ? NULL : same->f.samecycle))
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHneighborA_">-</a>
+
+ FOREACHneighborA_( facet ) { ... }
+ assign 'neighborA' to each neighbor in facet->neighbors
+
+ FOREACHneighborA_( vertex ) { ... }
+ assign 'neighborA' to each neighbor in vertex->neighbors
+
+ declare:
+ facetT *neighborA, **neighborAp;
+
+ see:
+ <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHneighborA_(facet) FOREACHsetelement_(facetT, facet->neighbors, neighborA)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHvisible_">-</a>
+
+ FOREACHvisible_( facets ) { ... }
+ assign 'visible' to each facet in facets
+
+ notes:
+ uses 'facetT *facet, *facetp;'
+ see <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHvisible_(facets) FOREACHsetelement_(facetT, facets, visible)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHnewfacet_">-</a>
+
+ FOREACHnewfacet_( facets ) { ... }
+ assign 'newfacet' to each facet in facets
+
+ notes:
+ uses 'facetT *newfacet, *newfacetp;'
+ see <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHnewfacet_(facets) FOREACHsetelement_(facetT, facets, newfacet)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHvertexA_">-</a>
+
+ FOREACHvertexA_( vertices ) { ... }
+ assign 'vertexA' to each vertex in vertices
+
+ notes:
+ uses 'vertexT *vertexA, *vertexAp;'
+ see <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHvertexA_(vertices) FOREACHsetelement_(vertexT, vertices, vertexA)
+
+/*-<a href="qh-poly.htm#TOC"
+ >--------------------------------</a><a name="FOREACHvertexreverse12_">-</a>
+
+ FOREACHvertexreverse12_( vertices ) { ... }
+ assign 'vertex' to each vertex in vertices
+ reverse order of first two vertices
+
+ notes:
+ uses 'vertexT *vertex, *vertexp;'
+ see <a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
+
+
+/*=============== prototypes poly.c in alphabetical order ================*/
+
+void qh_appendfacet(facetT *facet);
+void qh_appendvertex(vertexT *vertex);
+void qh_attachnewfacets(void /* qh.visible_list, qh.newfacet_list */);
+boolT qh_checkflipped(facetT *facet, realT *dist, boolT allerror);
+void qh_delfacet(facetT *facet);
+void qh_deletevisible(void /*qh.visible_list, qh.horizon_list*/);
+setT *qh_facetintersect(facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra);
+int qh_gethash(int hashsize, setT *set, int size, int firstindex, void *skipelem);
+facetT *qh_makenewfacet(setT *vertices, boolT toporient, facetT *facet);
+void qh_makenewplanes(void /* newfacet_list */);
+facetT *qh_makenew_nonsimplicial(facetT *visible, vertexT *apex, int *numnew);
+facetT *qh_makenew_simplicial(facetT *visible, vertexT *apex, int *numnew);
+void qh_matchneighbor(facetT *newfacet, int newskip, int hashsize,
+ int *hashcount);
+void qh_matchnewfacets(void);
+boolT qh_matchvertices(int firstindex, setT *verticesA, int skipA,
+ setT *verticesB, int *skipB, boolT *same);
+facetT *qh_newfacet(void);
+ridgeT *qh_newridge(void);
+int qh_pointid(pointT *point);
+void qh_removefacet(facetT *facet);
+void qh_removevertex(vertexT *vertex);
+void qh_updatevertices(void);
+
+
+/*========== -prototypes poly2.c in alphabetical order ===========*/
+
+void qh_addhash(void* newelem, setT *hashtable, int hashsize, int hash);
+void qh_check_bestdist(void);
+void qh_check_dupridge(facetT *facet1, realT dist1, facetT *facet2, realT dist2);
+void qh_check_maxout(void);
+void qh_check_output(void);
+void qh_check_point(pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2);
+void qh_check_points(void);
+void qh_checkconvex(facetT *facetlist, int fault);
+void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp);
+void qh_checkflipped_all(facetT *facetlist);
+void qh_checkpolygon(facetT *facetlist);
+void qh_checkvertex(vertexT *vertex);
+void qh_clearcenters(qh_CENTER type);
+void qh_createsimplex(setT *vertices);
+void qh_delridge(ridgeT *ridge);
+void qh_delvertex(vertexT *vertex);
+setT *qh_facet3vertex(facetT *facet);
+facetT *qh_findbestfacet(pointT *point, boolT bestoutside,
+ realT *bestdist, boolT *isoutside);
+facetT *qh_findbestlower(facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart);
+facetT *qh_findfacet_all(pointT *point, realT *bestdist, boolT *isoutside,
+ int *numpart);
+int qh_findgood(facetT *facetlist, int goodhorizon);
+void qh_findgood_all(facetT *facetlist);
+void qh_furthestnext(void /* qh.facet_list */);
+void qh_furthestout(facetT *facet);
+void qh_infiniteloop(facetT *facet);
+void qh_initbuild(void);
+void qh_initialhull(setT *vertices);
+setT *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints);
+vertexT *qh_isvertex(pointT *point, setT *vertices);
+vertexT *qh_makenewfacets(pointT *point /*horizon_list, visible_list*/);
+void qh_matchduplicates(facetT *atfacet, int atskip, int hashsize, int *hashcount);
+void qh_nearcoplanar(void /* qh.facet_list */);
+vertexT *qh_nearvertex(facetT *facet, pointT *point, realT *bestdistp);
+int qh_newhashtable(int newsize);
+vertexT *qh_newvertex(pointT *point);
+ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp);
+void qh_outcoplanar(void /* facet_list */);
+pointT *qh_point(int id);
+void qh_point_add(setT *set, pointT *point, void *elem);
+setT *qh_pointfacet(void /*qh.facet_list*/);
+setT *qh_pointvertex(void /*qh.facet_list*/);
+void qh_prependfacet(facetT *facet, facetT **facetlist);
+void qh_printhashtable(FILE *fp);
+void qh_printlists(void);
+void qh_resetlists(boolT stats, boolT resetVisible /*qh.newvertex_list qh.newfacet_list qh.visible_list*/);
+void qh_setvoronoi_all(void);
+void qh_triangulate(void /*qh.facet_list*/);
+void qh_triangulate_facet(facetT *facetA, vertexT **first_vertex);
+void qh_triangulate_link(facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB);
+void qh_triangulate_mirror(facetT *facetA, facetT *facetB);
+void qh_triangulate_null(facetT *facetA);
+void qh_vertexintersect(setT **vertexsetA,setT *vertexsetB);
+setT *qh_vertexintersect_new(setT *vertexsetA,setT *vertexsetB);
+void qh_vertexneighbors(void /*qh.facet_list*/);
+boolT qh_vertexsubset(setT *vertexsetA, setT *vertexsetB);
+
+
+#endif /* qhDEFpoly */
diff --git a/xs/src/qhull/src/libqhull/poly2.c b/xs/src/qhull/src/libqhull/poly2.c
new file mode 100644
index 000000000..de3e6ad0b
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/poly2.c
@@ -0,0 +1,3222 @@
+/*<html><pre> -<a href="qh-poly.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ poly2.c
+ implements polygons and simplices
+
+ see qh-poly.htm, poly.h and libqhull.h
+
+ frequently used code is in poly.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/poly2.c#11 $$Change: 2069 $
+ $DateTime: 2016/01/18 22:05:03 $$Author: bbarber $
+*/
+
+#include "qhull_a.h"
+
+/*======== functions in alphabetical order ==========*/
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="addhash">-</a>
+
+ qh_addhash( newelem, hashtable, hashsize, hash )
+ add newelem to linear hash table at hash if not already there
+*/
+void qh_addhash(void* newelem, setT *hashtable, int hashsize, int hash) {
+ int scan;
+ void *elem;
+
+ for (scan= (int)hash; (elem= SETelem_(hashtable, scan));
+ scan= (++scan >= hashsize ? 0 : scan)) {
+ if (elem == newelem)
+ break;
+ }
+ /* loop terminates because qh_HASHfactor >= 1.1 by qh_initbuffers */
+ if (!elem)
+ SETelem_(hashtable, scan)= newelem;
+} /* addhash */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="check_bestdist">-</a>
+
+ qh_check_bestdist()
+ check that all points are within max_outside of the nearest facet
+ if qh.ONLYgood,
+ ignores !good facets
+
+ see:
+ qh_check_maxout(), qh_outerinner()
+
+ notes:
+ only called from qh_check_points()
+ seldom used since qh.MERGING is almost always set
+ if notverified>0 at end of routine
+ some points were well inside the hull. If the hull contains
+ a lens-shaped component, these points were not verified. Use
+ options 'Qi Tv' to verify all points. (Exhaustive check also verifies)
+
+ design:
+ determine facet for each point (if any)
+ for each point
+ start with the assigned facet or with the first facet
+ find the best facet for the point and check all coplanar facets
+ error if point is outside of facet
+*/
+void qh_check_bestdist(void) {
+ boolT waserror= False, unassigned;
+ facetT *facet, *bestfacet, *errfacet1= NULL, *errfacet2= NULL;
+ facetT *facetlist;
+ realT dist, maxoutside, maxdist= -REALmax;
+ pointT *point;
+ int numpart= 0, facet_i, facet_n, notgood= 0, notverified= 0;
+ setT *facets;
+
+ trace1((qh ferr, 1020, "qh_check_bestdist: check points below nearest facet. Facet_list f%d\n",
+ qh facet_list->id));
+ maxoutside= qh_maxouter();
+ maxoutside += qh DISTround;
+ /* one more qh.DISTround for check computation */
+ trace1((qh ferr, 1021, "qh_check_bestdist: check that all points are within %2.2g of best facet\n", maxoutside));
+ facets= qh_pointfacet(/*qh.facet_list*/);
+ if (!qh_QUICKhelp && qh PRINTprecision)
+ qh_fprintf(qh ferr, 8091, "\n\
+qhull output completed. Verifying that %d points are\n\
+below %2.2g of the nearest %sfacet.\n",
+ qh_setsize(facets), maxoutside, (qh ONLYgood ? "good " : ""));
+ FOREACHfacet_i_(facets) { /* for each point with facet assignment */
+ if (facet)
+ unassigned= False;
+ else {
+ unassigned= True;
+ facet= qh facet_list;
+ }
+ point= qh_point(facet_i);
+ if (point == qh GOODpointp)
+ continue;
+ qh_distplane(point, facet, &dist);
+ numpart++;
+ bestfacet= qh_findbesthorizon(!qh_IScheckmax, point, facet, qh_NOupper, &dist, &numpart);
+ /* occurs after statistics reported */
+ maximize_(maxdist, dist);
+ if (dist > maxoutside) {
+ if (qh ONLYgood && !bestfacet->good
+ && !((bestfacet= qh_findgooddist(point, bestfacet, &dist, &facetlist))
+ && dist > maxoutside))
+ notgood++;
+ else {
+ waserror= True;
+ qh_fprintf(qh ferr, 6109, "qhull precision error: point p%d is outside facet f%d, distance= %6.8g maxoutside= %6.8g\n",
+ facet_i, bestfacet->id, dist, maxoutside);
+ if (errfacet1 != bestfacet) {
+ errfacet2= errfacet1;
+ errfacet1= bestfacet;
+ }
+ }
+ }else if (unassigned && dist < -qh MAXcoplanar)
+ notverified++;
+ }
+ qh_settempfree(&facets);
+ if (notverified && !qh DELAUNAY && !qh_QUICKhelp && qh PRINTprecision)
+ qh_fprintf(qh ferr, 8092, "\n%d points were well inside the hull. If the hull contains\n\
+a lens-shaped component, these points were not verified. Use\n\
+options 'Qci Tv' to verify all points.\n", notverified);
+ if (maxdist > qh outside_err) {
+ qh_fprintf(qh ferr, 6110, "qhull precision error (qh_check_bestdist): a coplanar point is %6.2g from convex hull. The maximum value(qh.outside_err) is %6.2g\n",
+ maxdist, qh outside_err);
+ qh_errexit2(qh_ERRprec, errfacet1, errfacet2);
+ }else if (waserror && qh outside_err > REALmax/2)
+ qh_errexit2(qh_ERRprec, errfacet1, errfacet2);
+ /* else if waserror, the error was logged to qh.ferr but does not effect the output */
+ trace0((qh ferr, 20, "qh_check_bestdist: max distance outside %2.2g\n", maxdist));
+} /* check_bestdist */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="check_dupridge">-</a>
+
+ qh_check_dupridge(facet1, dist1, facet2, dist2)
+ Check duplicate ridge between facet1 and facet2 for wide merge
+ dist1 is the maximum distance of facet1's vertices to facet2
+ dist2 is the maximum distance of facet2's vertices to facet1
+
+ Returns
+ Level 1 log of the duplicate ridge with the minimum distance between vertices
+ Throws error if the merge will increase the maximum facet width by qh_WIDEduplicate (100x)
+
+ called from:
+ qh_forcedmerges()
+*/
+#ifndef qh_NOmerge
+void qh_check_dupridge(facetT *facet1, realT dist1, facetT *facet2, realT dist2) {
+ vertexT *vertex, **vertexp, *vertexA, **vertexAp;
+ realT dist, innerplane, mergedist, outerplane, prevdist, ratio;
+ realT minvertex= REALmax;
+
+ mergedist= fmin_(dist1, dist2);
+ qh_outerinner(NULL, &outerplane, &innerplane); /* ratio from qh_printsummary */
+ prevdist= fmax_(outerplane, innerplane);
+ maximize_(prevdist, qh ONEmerge + qh DISTround);
+ maximize_(prevdist, qh MINoutside + qh DISTround);
+ ratio= mergedist/prevdist;
+ FOREACHvertex_(facet1->vertices) { /* The duplicate ridge is between facet1 and facet2, so either facet can be tested */
+ FOREACHvertexA_(facet1->vertices) {
+ if (vertex > vertexA){ /* Test each pair once */
+ dist= qh_pointdist(vertex->point, vertexA->point, qh hull_dim);
+ minimize_(minvertex, dist);
+ }
+ }
+ }
+ trace0((qh ferr, 16, "qh_check_dupridge: duplicate ridge between f%d and f%d due to nearly-coincident vertices (%2.2g), dist %2.2g, reverse dist %2.2g, ratio %2.2g while processing p%d\n",
+ facet1->id, facet2->id, minvertex, dist1, dist2, ratio, qh furthest_id));
+ if (ratio > qh_WIDEduplicate) {
+ qh_fprintf(qh ferr, 6271, "qhull precision error (qh_check_dupridge): wide merge (%.0f times wider) due to duplicate ridge with nearly coincident points (%2.2g) between f%d and f%d, merge dist %2.2g, while processing p%d\n- Ignore error with option 'Q12'\n- To be fixed in a later version of Qhull\n",
+ ratio, minvertex, facet1->id, facet2->id, mergedist, qh furthest_id);
+ if (qh DELAUNAY)
+ qh_fprintf(qh ferr, 8145, "- A bounding box for the input sites may alleviate this error.\n");
+ if(minvertex > qh_WIDEduplicate*prevdist)
+ qh_fprintf(qh ferr, 8146, "- Vertex distance %2.2g is greater than %d times maximum distance %2.2g\n Please report to bradb@shore.net with steps to reproduce and all output\n",
+ minvertex, qh_WIDEduplicate, prevdist);
+ if (!qh NOwide)
+ qh_errexit2(qh_ERRqhull, facet1, facet2);
+ }
+} /* check_dupridge */
+#endif
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="check_maxout">-</a>
+
+ qh_check_maxout()
+ updates qh.max_outside by checking all points against bestfacet
+ if qh.ONLYgood, ignores !good facets
+
+ returns:
+ updates facet->maxoutside via qh_findbesthorizon()
+ sets qh.maxoutdone
+ if printing qh.min_vertex (qh_outerinner),
+ it is updated to the current vertices
+ removes inside/coplanar points from coplanarset as needed
+
+ notes:
+ defines coplanar as min_vertex instead of MAXcoplanar
+ may not need to check near-inside points because of qh.MAXcoplanar
+ and qh.KEEPnearinside (before it was -DISTround)
+
+ see also:
+ qh_check_bestdist()
+
+ design:
+ if qh.min_vertex is needed
+ for all neighbors of all vertices
+ test distance from vertex to neighbor
+ determine facet for each point (if any)
+ for each point with an assigned facet
+ find the best facet for the point and check all coplanar facets
+ (updates outer planes)
+ remove near-inside points from coplanar sets
+*/
+#ifndef qh_NOmerge
+void qh_check_maxout(void) {
+ facetT *facet, *bestfacet, *neighbor, **neighborp, *facetlist;
+ realT dist, maxoutside, minvertex, old_maxoutside;
+ pointT *point;
+ int numpart= 0, facet_i, facet_n, notgood= 0;
+ setT *facets, *vertices;
+ vertexT *vertex;
+
+ trace1((qh ferr, 1022, "qh_check_maxout: check and update maxoutside for each facet.\n"));
+ maxoutside= minvertex= 0;
+ if (qh VERTEXneighbors
+ && (qh PRINTsummary || qh KEEPinside || qh KEEPcoplanar
+ || qh TRACElevel || qh PRINTstatistics
+ || qh PRINTout[0] == qh_PRINTsummary || qh PRINTout[0] == qh_PRINTnone)) {
+ trace1((qh ferr, 1023, "qh_check_maxout: determine actual maxoutside and minvertex\n"));
+ vertices= qh_pointvertex(/*qh.facet_list*/);
+ FORALLvertices {
+ FOREACHneighbor_(vertex) {
+ zinc_(Zdistvertex); /* distance also computed by main loop below */
+ qh_distplane(vertex->point, neighbor, &dist);
+ minimize_(minvertex, dist);
+ if (-dist > qh TRACEdist || dist > qh TRACEdist
+ || neighbor == qh tracefacet || vertex == qh tracevertex)
+ qh_fprintf(qh ferr, 8093, "qh_check_maxout: p%d(v%d) is %.2g from f%d\n",
+ qh_pointid(vertex->point), vertex->id, dist, neighbor->id);
+ }
+ }
+ if (qh MERGING) {
+ wmin_(Wminvertex, qh min_vertex);
+ }
+ qh min_vertex= minvertex;
+ qh_settempfree(&vertices);
+ }
+ facets= qh_pointfacet(/*qh.facet_list*/);
+ do {
+ old_maxoutside= fmax_(qh max_outside, maxoutside);
+ FOREACHfacet_i_(facets) { /* for each point with facet assignment */
+ if (facet) {
+ point= qh_point(facet_i);
+ if (point == qh GOODpointp)
+ continue;
+ zzinc_(Ztotcheck);
+ qh_distplane(point, facet, &dist);
+ numpart++;
+ bestfacet= qh_findbesthorizon(qh_IScheckmax, point, facet, !qh_NOupper, &dist, &numpart);
+ if (bestfacet && dist > maxoutside) {
+ if (qh ONLYgood && !bestfacet->good
+ && !((bestfacet= qh_findgooddist(point, bestfacet, &dist, &facetlist))
+ && dist > maxoutside))
+ notgood++;
+ else
+ maxoutside= dist;
+ }
+ if (dist > qh TRACEdist || (bestfacet && bestfacet == qh tracefacet))
+ qh_fprintf(qh ferr, 8094, "qh_check_maxout: p%d is %.2g above f%d\n",
+ qh_pointid(point), dist, (bestfacet ? bestfacet->id : UINT_MAX));
+ }
+ }
+ }while
+ (maxoutside > 2*old_maxoutside);
+ /* if qh.maxoutside increases substantially, qh_SEARCHdist is not valid
+ e.g., RBOX 5000 s Z1 G1e-13 t1001200614 | qhull */
+ zzadd_(Zcheckpart, numpart);
+ qh_settempfree(&facets);
+ wval_(Wmaxout)= maxoutside - qh max_outside;
+ wmax_(Wmaxoutside, qh max_outside);
+ qh max_outside= maxoutside;
+ qh_nearcoplanar(/*qh.facet_list*/);
+ qh maxoutdone= True;
+ trace1((qh ferr, 1024, "qh_check_maxout: maxoutside %2.2g, min_vertex %2.2g, outside of not good %d\n",
+ maxoutside, qh min_vertex, notgood));
+} /* check_maxout */
+#else /* qh_NOmerge */
+void qh_check_maxout(void) {
+}
+#endif
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="check_output">-</a>
+
+ qh_check_output()
+ performs the checks at the end of qhull algorithm
+ Maybe called after voronoi output. Will recompute otherwise centrums are Voronoi centers instead
+*/
+void qh_check_output(void) {
+ int i;
+
+ if (qh STOPcone)
+ return;
+ if (qh VERIFYoutput | qh IStracing | qh CHECKfrequently) {
+ qh_checkpolygon(qh facet_list);
+ qh_checkflipped_all(qh facet_list);
+ qh_checkconvex(qh facet_list, qh_ALGORITHMfault);
+ }else if (!qh MERGING && qh_newstats(qhstat precision, &i)) {
+ qh_checkflipped_all(qh facet_list);
+ qh_checkconvex(qh facet_list, qh_ALGORITHMfault);
+ }
+} /* check_output */
+
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="check_point">-</a>
+
+ qh_check_point( point, facet, maxoutside, maxdist, errfacet1, errfacet2 )
+ check that point is less than maxoutside from facet
+*/
+void qh_check_point(pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2) {
+ realT dist;
+
+ /* occurs after statistics reported */
+ qh_distplane(point, facet, &dist);
+ if (dist > *maxoutside) {
+ if (*errfacet1 != facet) {
+ *errfacet2= *errfacet1;
+ *errfacet1= facet;
+ }
+ qh_fprintf(qh ferr, 6111, "qhull precision error: point p%d is outside facet f%d, distance= %6.8g maxoutside= %6.8g\n",
+ qh_pointid(point), facet->id, dist, *maxoutside);
+ }
+ maximize_(*maxdist, dist);
+} /* qh_check_point */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="check_points">-</a>
+
+ qh_check_points()
+ checks that all points are inside all facets
+
+ notes:
+ if many points and qh_check_maxout not called (i.e., !qh.MERGING),
+ calls qh_findbesthorizon (seldom done).
+ ignores flipped facets
+ maxoutside includes 2 qh.DISTrounds
+ one qh.DISTround for the computed distances in qh_check_points
+ qh_printafacet and qh_printsummary needs only one qh.DISTround
+ the computation for qh.VERIFYdirect does not account for qh.other_points
+
+ design:
+ if many points
+ use qh_check_bestdist()
+ else
+ for all facets
+ for all points
+ check that point is inside facet
+*/
+void qh_check_points(void) {
+ facetT *facet, *errfacet1= NULL, *errfacet2= NULL;
+ realT total, maxoutside, maxdist= -REALmax;
+ pointT *point, **pointp, *pointtemp;
+ boolT testouter;
+
+ maxoutside= qh_maxouter();
+ maxoutside += qh DISTround;
+ /* one more qh.DISTround for check computation */
+ trace1((qh ferr, 1025, "qh_check_points: check all points below %2.2g of all facet planes\n",
+ maxoutside));
+ if (qh num_good) /* miss counts other_points and !good facets */
+ total= (float)qh num_good * (float)qh num_points;
+ else
+ total= (float)qh num_facets * (float)qh num_points;
+ if (total >= qh_VERIFYdirect && !qh maxoutdone) {
+ if (!qh_QUICKhelp && qh SKIPcheckmax && qh MERGING)
+ qh_fprintf(qh ferr, 7075, "qhull input warning: merging without checking outer planes('Q5' or 'Po').\n\
+Verify may report that a point is outside of a facet.\n");
+ qh_check_bestdist();
+ }else {
+ if (qh_MAXoutside && qh maxoutdone)
+ testouter= True;
+ else
+ testouter= False;
+ if (!qh_QUICKhelp) {
+ if (qh MERGEexact)
+ qh_fprintf(qh ferr, 7076, "qhull input warning: exact merge ('Qx'). Verify may report that a point\n\
+is outside of a facet. See qh-optq.htm#Qx\n");
+ else if (qh SKIPcheckmax || qh NOnearinside)
+ qh_fprintf(qh ferr, 7077, "qhull input warning: no outer plane check ('Q5') or no processing of\n\
+near-inside points ('Q8'). Verify may report that a point is outside\n\
+of a facet.\n");
+ }
+ if (qh PRINTprecision) {
+ if (testouter)
+ qh_fprintf(qh ferr, 8098, "\n\
+Output completed. Verifying that all points are below outer planes of\n\
+all %sfacets. Will make %2.0f distance computations.\n",
+ (qh ONLYgood ? "good " : ""), total);
+ else
+ qh_fprintf(qh ferr, 8099, "\n\
+Output completed. Verifying that all points are below %2.2g of\n\
+all %sfacets. Will make %2.0f distance computations.\n",
+ maxoutside, (qh ONLYgood ? "good " : ""), total);
+ }
+ FORALLfacets {
+ if (!facet->good && qh ONLYgood)
+ continue;
+ if (facet->flipped)
+ continue;
+ if (!facet->normal) {
+ qh_fprintf(qh ferr, 7061, "qhull warning (qh_check_points): missing normal for facet f%d\n", facet->id);
+ continue;
+ }
+ if (testouter) {
+#if qh_MAXoutside
+ maxoutside= facet->maxoutside + 2* qh DISTround;
+ /* one DISTround to actual point and another to computed point */
+#endif
+ }
+ FORALLpoints {
+ if (point != qh GOODpointp)
+ qh_check_point(point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2);
+ }
+ FOREACHpoint_(qh other_points) {
+ if (point != qh GOODpointp)
+ qh_check_point(point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2);
+ }
+ }
+ if (maxdist > qh outside_err) {
+ qh_fprintf(qh ferr, 6112, "qhull precision error (qh_check_points): a coplanar point is %6.2g from convex hull. The maximum value(qh.outside_err) is %6.2g\n",
+ maxdist, qh outside_err );
+ qh_errexit2( qh_ERRprec, errfacet1, errfacet2 );
+ }else if (errfacet1 && qh outside_err > REALmax/2)
+ qh_errexit2( qh_ERRprec, errfacet1, errfacet2 );
+ /* else if errfacet1, the error was logged to qh.ferr but does not effect the output */
+ trace0((qh ferr, 21, "qh_check_points: max distance outside %2.2g\n", maxdist));
+ }
+} /* check_points */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="checkconvex">-</a>
+
+ qh_checkconvex( facetlist, fault )
+ check that each ridge in facetlist is convex
+ fault = qh_DATAfault if reporting errors
+ = qh_ALGORITHMfault otherwise
+
+ returns:
+ counts Zconcaveridges and Zcoplanarridges
+ errors if concaveridge or if merging an coplanar ridge
+
+ note:
+ if not merging,
+ tests vertices for neighboring simplicial facets
+ else if ZEROcentrum,
+ tests vertices for neighboring simplicial facets
+ else
+ tests centrums of neighboring facets
+
+ design:
+ for all facets
+ report flipped facets
+ if ZEROcentrum and simplicial neighbors
+ test vertices for neighboring simplicial facets
+ else
+ test centrum against all neighbors
+*/
+void qh_checkconvex(facetT *facetlist, int fault) {
+ facetT *facet, *neighbor, **neighborp, *errfacet1=NULL, *errfacet2=NULL;
+ vertexT *vertex;
+ realT dist;
+ pointT *centrum;
+ boolT waserror= False, centrum_warning= False, tempcentrum= False, allsimplicial;
+ int neighbor_i;
+
+ trace1((qh ferr, 1026, "qh_checkconvex: check all ridges are convex\n"));
+ if (!qh RERUN) {
+ zzval_(Zconcaveridges)= 0;
+ zzval_(Zcoplanarridges)= 0;
+ }
+ FORALLfacet_(facetlist) {
+ if (facet->flipped) {
+ qh_precision("flipped facet");
+ qh_fprintf(qh ferr, 6113, "qhull precision error: f%d is flipped(interior point is outside)\n",
+ facet->id);
+ errfacet1= facet;
+ waserror= True;
+ continue;
+ }
+ if (qh MERGING && (!qh ZEROcentrum || !facet->simplicial || facet->tricoplanar))
+ allsimplicial= False;
+ else {
+ allsimplicial= True;
+ neighbor_i= 0;
+ FOREACHneighbor_(facet) {
+ vertex= SETelemt_(facet->vertices, neighbor_i++, vertexT);
+ if (!neighbor->simplicial || neighbor->tricoplanar) {
+ allsimplicial= False;
+ continue;
+ }
+ qh_distplane(vertex->point, neighbor, &dist);
+ if (dist > -qh DISTround) {
+ if (fault == qh_DATAfault) {
+ qh_precision("coplanar or concave ridge");
+ qh_fprintf(qh ferr, 6114, "qhull precision error: initial simplex is not convex. Distance=%.2g\n", dist);
+ qh_errexit(qh_ERRsingular, NULL, NULL);
+ }
+ if (dist > qh DISTround) {
+ zzinc_(Zconcaveridges);
+ qh_precision("concave ridge");
+ qh_fprintf(qh ferr, 6115, "qhull precision error: f%d is concave to f%d, since p%d(v%d) is %6.4g above\n",
+ facet->id, neighbor->id, qh_pointid(vertex->point), vertex->id, dist);
+ errfacet1= facet;
+ errfacet2= neighbor;
+ waserror= True;
+ }else if (qh ZEROcentrum) {
+ if (dist > 0) { /* qh_checkzero checks that dist < - qh DISTround */
+ zzinc_(Zcoplanarridges);
+ qh_precision("coplanar ridge");
+ qh_fprintf(qh ferr, 6116, "qhull precision error: f%d is clearly not convex to f%d, since p%d(v%d) is %6.4g above\n",
+ facet->id, neighbor->id, qh_pointid(vertex->point), vertex->id, dist);
+ errfacet1= facet;
+ errfacet2= neighbor;
+ waserror= True;
+ }
+ }else {
+ zzinc_(Zcoplanarridges);
+ qh_precision("coplanar ridge");
+ trace0((qh ferr, 22, "qhull precision error: f%d may be coplanar to f%d, since p%d(v%d) is within %6.4g during p%d\n",
+ facet->id, neighbor->id, qh_pointid(vertex->point), vertex->id, dist, qh furthest_id));
+ }
+ }
+ }
+ }
+ if (!allsimplicial) {
+ if (qh CENTERtype == qh_AScentrum) {
+ if (!facet->center)
+ facet->center= qh_getcentrum(facet);
+ centrum= facet->center;
+ }else {
+ if (!centrum_warning && (!facet->simplicial || facet->tricoplanar)) {
+ centrum_warning= True;
+ qh_fprintf(qh ferr, 7062, "qhull warning: recomputing centrums for convexity test. This may lead to false, precision errors.\n");
+ }
+ centrum= qh_getcentrum(facet);
+ tempcentrum= True;
+ }
+ FOREACHneighbor_(facet) {
+ if (qh ZEROcentrum && facet->simplicial && neighbor->simplicial)
+ continue;
+ if (facet->tricoplanar || neighbor->tricoplanar)
+ continue;
+ zzinc_(Zdistconvex);
+ qh_distplane(centrum, neighbor, &dist);
+ if (dist > qh DISTround) {
+ zzinc_(Zconcaveridges);
+ qh_precision("concave ridge");
+ qh_fprintf(qh ferr, 6117, "qhull precision error: f%d is concave to f%d. Centrum of f%d is %6.4g above f%d\n",
+ facet->id, neighbor->id, facet->id, dist, neighbor->id);
+ errfacet1= facet;
+ errfacet2= neighbor;
+ waserror= True;
+ }else if (dist >= 0.0) { /* if arithmetic always rounds the same,
+ can test against centrum radius instead */
+ zzinc_(Zcoplanarridges);
+ qh_precision("coplanar ridge");
+ qh_fprintf(qh ferr, 6118, "qhull precision error: f%d is coplanar or concave to f%d. Centrum of f%d is %6.4g above f%d\n",
+ facet->id, neighbor->id, facet->id, dist, neighbor->id);
+ errfacet1= facet;
+ errfacet2= neighbor;
+ waserror= True;
+ }
+ }
+ if (tempcentrum)
+ qh_memfree(centrum, qh normal_size);
+ }
+ }
+ if (waserror && !qh FORCEoutput)
+ qh_errexit2(qh_ERRprec, errfacet1, errfacet2);
+} /* checkconvex */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="checkfacet">-</a>
+
+ qh_checkfacet( facet, newmerge, waserror )
+ checks for consistency errors in facet
+ newmerge set if from merge.c
+
+ returns:
+ sets waserror if any error occurs
+
+ checks:
+ vertex ids are inverse sorted
+ unless newmerge, at least hull_dim neighbors and vertices (exactly if simplicial)
+ if non-simplicial, at least as many ridges as neighbors
+ neighbors are not duplicated
+ ridges are not duplicated
+ in 3-d, ridges=verticies
+ (qh.hull_dim-1) ridge vertices
+ neighbors are reciprocated
+ ridge neighbors are facet neighbors and a ridge for every neighbor
+ simplicial neighbors match facetintersect
+ vertex intersection matches vertices of common ridges
+ vertex neighbors and facet vertices agree
+ all ridges have distinct vertex sets
+
+ notes:
+ uses neighbor->seen
+
+ design:
+ check sets
+ check vertices
+ check sizes of neighbors and vertices
+ check for qh_MERGEridge and qh_DUPLICATEridge flags
+ check neighbor set
+ check ridge set
+ check ridges, neighbors, and vertices
+*/
+void qh_checkfacet(facetT *facet, boolT newmerge, boolT *waserrorp) {
+ facetT *neighbor, **neighborp, *errother=NULL;
+ ridgeT *ridge, **ridgep, *errridge= NULL, *ridge2;
+ vertexT *vertex, **vertexp;
+ unsigned previousid= INT_MAX;
+ int numneighbors, numvertices, numridges=0, numRvertices=0;
+ boolT waserror= False;
+ int skipA, skipB, ridge_i, ridge_n, i;
+ setT *intersection;
+
+ if (facet->visible) {
+ qh_fprintf(qh ferr, 6119, "qhull internal error (qh_checkfacet): facet f%d is on the visible_list\n",
+ facet->id);
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ if (!facet->normal) {
+ qh_fprintf(qh ferr, 6120, "qhull internal error (qh_checkfacet): facet f%d does not have a normal\n",
+ facet->id);
+ waserror= True;
+ }
+ qh_setcheck(facet->vertices, "vertices for f", facet->id);
+ qh_setcheck(facet->ridges, "ridges for f", facet->id);
+ qh_setcheck(facet->outsideset, "outsideset for f", facet->id);
+ qh_setcheck(facet->coplanarset, "coplanarset for f", facet->id);
+ qh_setcheck(facet->neighbors, "neighbors for f", facet->id);
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->deleted) {
+ qh_fprintf(qh ferr, 6121, "qhull internal error (qh_checkfacet): deleted vertex v%d in f%d\n", vertex->id, facet->id);
+ qh_errprint("ERRONEOUS", NULL, NULL, NULL, vertex);
+ waserror= True;
+ }
+ if (vertex->id >= previousid) {
+ qh_fprintf(qh ferr, 6122, "qhull internal error (qh_checkfacet): vertices of f%d are not in descending id order at v%d\n", facet->id, vertex->id);
+ waserror= True;
+ break;
+ }
+ previousid= vertex->id;
+ }
+ numneighbors= qh_setsize(facet->neighbors);
+ numvertices= qh_setsize(facet->vertices);
+ numridges= qh_setsize(facet->ridges);
+ if (facet->simplicial) {
+ if (numvertices+numneighbors != 2*qh hull_dim
+ && !facet->degenerate && !facet->redundant) {
+ qh_fprintf(qh ferr, 6123, "qhull internal error (qh_checkfacet): for simplicial facet f%d, #vertices %d + #neighbors %d != 2*qh hull_dim\n",
+ facet->id, numvertices, numneighbors);
+ qh_setprint(qh ferr, "", facet->neighbors);
+ waserror= True;
+ }
+ }else { /* non-simplicial */
+ if (!newmerge
+ &&(numvertices < qh hull_dim || numneighbors < qh hull_dim)
+ && !facet->degenerate && !facet->redundant) {
+ qh_fprintf(qh ferr, 6124, "qhull internal error (qh_checkfacet): for facet f%d, #vertices %d or #neighbors %d < qh hull_dim\n",
+ facet->id, numvertices, numneighbors);
+ waserror= True;
+ }
+ /* in 3-d, can get a vertex twice in an edge list, e.g., RBOX 1000 s W1e-13 t995849315 D2 | QHULL d Tc Tv TP624 TW1e-13 T4 */
+ if (numridges < numneighbors
+ ||(qh hull_dim == 3 && numvertices > numridges && !qh NEWfacets)
+ ||(qh hull_dim == 2 && numridges + numvertices + numneighbors != 6)) {
+ if (!facet->degenerate && !facet->redundant) {
+ qh_fprintf(qh ferr, 6125, "qhull internal error (qh_checkfacet): for facet f%d, #ridges %d < #neighbors %d or(3-d) > #vertices %d or(2-d) not all 2\n",
+ facet->id, numridges, numneighbors, numvertices);
+ waserror= True;
+ }
+ }
+ }
+ FOREACHneighbor_(facet) {
+ if (neighbor == qh_MERGEridge || neighbor == qh_DUPLICATEridge) {
+ qh_fprintf(qh ferr, 6126, "qhull internal error (qh_checkfacet): facet f%d still has a MERGE or DUP neighbor\n", facet->id);
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ neighbor->seen= True;
+ }
+ FOREACHneighbor_(facet) {
+ if (!qh_setin(neighbor->neighbors, facet)) {
+ qh_fprintf(qh ferr, 6127, "qhull internal error (qh_checkfacet): facet f%d has neighbor f%d, but f%d does not have neighbor f%d\n",
+ facet->id, neighbor->id, neighbor->id, facet->id);
+ errother= neighbor;
+ waserror= True;
+ }
+ if (!neighbor->seen) {
+ qh_fprintf(qh ferr, 6128, "qhull internal error (qh_checkfacet): facet f%d has a duplicate neighbor f%d\n",
+ facet->id, neighbor->id);
+ errother= neighbor;
+ waserror= True;
+ }
+ neighbor->seen= False;
+ }
+ FOREACHridge_(facet->ridges) {
+ qh_setcheck(ridge->vertices, "vertices for r", ridge->id);
+ ridge->seen= False;
+ }
+ FOREACHridge_(facet->ridges) {
+ if (ridge->seen) {
+ qh_fprintf(qh ferr, 6129, "qhull internal error (qh_checkfacet): facet f%d has a duplicate ridge r%d\n",
+ facet->id, ridge->id);
+ errridge= ridge;
+ waserror= True;
+ }
+ ridge->seen= True;
+ numRvertices= qh_setsize(ridge->vertices);
+ if (numRvertices != qh hull_dim - 1) {
+ qh_fprintf(qh ferr, 6130, "qhull internal error (qh_checkfacet): ridge between f%d and f%d has %d vertices\n",
+ ridge->top->id, ridge->bottom->id, numRvertices);
+ errridge= ridge;
+ waserror= True;
+ }
+ neighbor= otherfacet_(ridge, facet);
+ neighbor->seen= True;
+ if (!qh_setin(facet->neighbors, neighbor)) {
+ qh_fprintf(qh ferr, 6131, "qhull internal error (qh_checkfacet): for facet f%d, neighbor f%d of ridge r%d not in facet\n",
+ facet->id, neighbor->id, ridge->id);
+ errridge= ridge;
+ waserror= True;
+ }
+ }
+ if (!facet->simplicial) {
+ FOREACHneighbor_(facet) {
+ if (!neighbor->seen) {
+ qh_fprintf(qh ferr, 6132, "qhull internal error (qh_checkfacet): facet f%d does not have a ridge for neighbor f%d\n",
+ facet->id, neighbor->id);
+ errother= neighbor;
+ waserror= True;
+ }
+ intersection= qh_vertexintersect_new(facet->vertices, neighbor->vertices);
+ qh_settemppush(intersection);
+ FOREACHvertex_(facet->vertices) {
+ vertex->seen= False;
+ vertex->seen2= False;
+ }
+ FOREACHvertex_(intersection)
+ vertex->seen= True;
+ FOREACHridge_(facet->ridges) {
+ if (neighbor != otherfacet_(ridge, facet))
+ continue;
+ FOREACHvertex_(ridge->vertices) {
+ if (!vertex->seen) {
+ qh_fprintf(qh ferr, 6133, "qhull internal error (qh_checkfacet): vertex v%d in r%d not in f%d intersect f%d\n",
+ vertex->id, ridge->id, facet->id, neighbor->id);
+ qh_errexit(qh_ERRqhull, facet, ridge);
+ }
+ vertex->seen2= True;
+ }
+ }
+ if (!newmerge) {
+ FOREACHvertex_(intersection) {
+ if (!vertex->seen2) {
+ if (qh IStracing >=3 || !qh MERGING) {
+ qh_fprintf(qh ferr, 6134, "qhull precision error (qh_checkfacet): vertex v%d in f%d intersect f%d but\n\
+ not in a ridge. This is ok under merging. Last point was p%d\n",
+ vertex->id, facet->id, neighbor->id, qh furthest_id);
+ if (!qh FORCEoutput && !qh MERGING) {
+ qh_errprint("ERRONEOUS", facet, neighbor, NULL, vertex);
+ if (!qh MERGING)
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ }
+ }
+ }
+ }
+ qh_settempfree(&intersection);
+ }
+ }else { /* simplicial */
+ FOREACHneighbor_(facet) {
+ if (neighbor->simplicial) {
+ skipA= SETindex_(facet->neighbors, neighbor);
+ skipB= qh_setindex(neighbor->neighbors, facet);
+ if (skipA<0 || skipB<0 || !qh_setequal_skip(facet->vertices, skipA, neighbor->vertices, skipB)) {
+ qh_fprintf(qh ferr, 6135, "qhull internal error (qh_checkfacet): facet f%d skip %d and neighbor f%d skip %d do not match \n",
+ facet->id, skipA, neighbor->id, skipB);
+ errother= neighbor;
+ waserror= True;
+ }
+ }
+ }
+ }
+ if (qh hull_dim < 5 && (qh IStracing > 2 || qh CHECKfrequently)) {
+ FOREACHridge_i_(facet->ridges) { /* expensive */
+ for (i=ridge_i+1; i < ridge_n; i++) {
+ ridge2= SETelemt_(facet->ridges, i, ridgeT);
+ if (qh_setequal(ridge->vertices, ridge2->vertices)) {
+ qh_fprintf(qh ferr, 6227, "Qhull internal error (qh_checkfacet): ridges r%d and r%d have the same vertices\n",
+ ridge->id, ridge2->id);
+ errridge= ridge;
+ waserror= True;
+ }
+ }
+ }
+ }
+ if (waserror) {
+ qh_errprint("ERRONEOUS", facet, errother, errridge, NULL);
+ *waserrorp= True;
+ }
+} /* checkfacet */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="checkflipped_all">-</a>
+
+ qh_checkflipped_all( facetlist )
+ checks orientation of facets in list against interior point
+*/
+void qh_checkflipped_all(facetT *facetlist) {
+ facetT *facet;
+ boolT waserror= False;
+ realT dist;
+
+ if (facetlist == qh facet_list)
+ zzval_(Zflippedfacets)= 0;
+ FORALLfacet_(facetlist) {
+ if (facet->normal && !qh_checkflipped(facet, &dist, !qh_ALL)) {
+ qh_fprintf(qh ferr, 6136, "qhull precision error: facet f%d is flipped, distance= %6.12g\n",
+ facet->id, dist);
+ if (!qh FORCEoutput) {
+ qh_errprint("ERRONEOUS", facet, NULL, NULL, NULL);
+ waserror= True;
+ }
+ }
+ }
+ if (waserror) {
+ qh_fprintf(qh ferr, 8101, "\n\
+A flipped facet occurs when its distance to the interior point is\n\
+greater than %2.2g, the maximum roundoff error.\n", -qh DISTround);
+ qh_errexit(qh_ERRprec, NULL, NULL);
+ }
+} /* checkflipped_all */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="checkpolygon">-</a>
+
+ qh_checkpolygon( facetlist )
+ checks the correctness of the structure
+
+ notes:
+ call with either qh.facet_list or qh.newfacet_list
+ checks num_facets and num_vertices if qh.facet_list
+
+ design:
+ for each facet
+ checks facet and outside set
+ initializes vertexlist
+ for each facet
+ checks vertex set
+ if checking all facets(qh.facetlist)
+ check facet count
+ if qh.VERTEXneighbors
+ check vertex neighbors and count
+ check vertex count
+*/
+void qh_checkpolygon(facetT *facetlist) {
+ facetT *facet;
+ vertexT *vertex, **vertexp, *vertexlist;
+ int numfacets= 0, numvertices= 0, numridges= 0;
+ int totvneighbors= 0, totvertices= 0;
+ boolT waserror= False, nextseen= False, visibleseen= False;
+
+ trace1((qh ferr, 1027, "qh_checkpolygon: check all facets from f%d\n", facetlist->id));
+ if (facetlist != qh facet_list || qh ONLYgood)
+ nextseen= True;
+ FORALLfacet_(facetlist) {
+ if (facet == qh visible_list)
+ visibleseen= True;
+ if (!facet->visible) {
+ if (!nextseen) {
+ if (facet == qh facet_next)
+ nextseen= True;
+ else if (qh_setsize(facet->outsideset)) {
+ if (!qh NARROWhull
+#if !qh_COMPUTEfurthest
+ || facet->furthestdist >= qh MINoutside
+#endif
+ ) {
+ qh_fprintf(qh ferr, 6137, "qhull internal error (qh_checkpolygon): f%d has outside points before qh facet_next\n",
+ facet->id);
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ }
+ }
+ numfacets++;
+ qh_checkfacet(facet, False, &waserror);
+ }
+ }
+ if (qh visible_list && !visibleseen && facetlist == qh facet_list) {
+ qh_fprintf(qh ferr, 6138, "qhull internal error (qh_checkpolygon): visible list f%d no longer on facet list\n", qh visible_list->id);
+ qh_printlists();
+ qh_errexit(qh_ERRqhull, qh visible_list, NULL);
+ }
+ if (facetlist == qh facet_list)
+ vertexlist= qh vertex_list;
+ else if (facetlist == qh newfacet_list)
+ vertexlist= qh newvertex_list;
+ else
+ vertexlist= NULL;
+ FORALLvertex_(vertexlist) {
+ vertex->seen= False;
+ vertex->visitid= 0;
+ }
+ FORALLfacet_(facetlist) {
+ if (facet->visible)
+ continue;
+ if (facet->simplicial)
+ numridges += qh hull_dim;
+ else
+ numridges += qh_setsize(facet->ridges);
+ FOREACHvertex_(facet->vertices) {
+ vertex->visitid++;
+ if (!vertex->seen) {
+ vertex->seen= True;
+ numvertices++;
+ if (qh_pointid(vertex->point) == qh_IDunknown) {
+ qh_fprintf(qh ferr, 6139, "qhull internal error (qh_checkpolygon): unknown point %p for vertex v%d first_point %p\n",
+ vertex->point, vertex->id, qh first_point);
+ waserror= True;
+ }
+ }
+ }
+ }
+ qh vertex_visit += (unsigned int)numfacets;
+ if (facetlist == qh facet_list) {
+ if (numfacets != qh num_facets - qh num_visible) {
+ qh_fprintf(qh ferr, 6140, "qhull internal error (qh_checkpolygon): actual number of facets is %d, cumulative facet count is %d - %d visible facets\n",
+ numfacets, qh num_facets, qh num_visible);
+ waserror= True;
+ }
+ qh vertex_visit++;
+ if (qh VERTEXneighbors) {
+ FORALLvertices {
+ qh_setcheck(vertex->neighbors, "neighbors for v", vertex->id);
+ if (vertex->deleted)
+ continue;
+ totvneighbors += qh_setsize(vertex->neighbors);
+ }
+ FORALLfacet_(facetlist)
+ totvertices += qh_setsize(facet->vertices);
+ if (totvneighbors != totvertices) {
+ qh_fprintf(qh ferr, 6141, "qhull internal error (qh_checkpolygon): vertex neighbors inconsistent. Totvneighbors %d, totvertices %d\n",
+ totvneighbors, totvertices);
+ waserror= True;
+ }
+ }
+ if (numvertices != qh num_vertices - qh_setsize(qh del_vertices)) {
+ qh_fprintf(qh ferr, 6142, "qhull internal error (qh_checkpolygon): actual number of vertices is %d, cumulative vertex count is %d\n",
+ numvertices, qh num_vertices - qh_setsize(qh del_vertices));
+ waserror= True;
+ }
+ if (qh hull_dim == 2 && numvertices != numfacets) {
+ qh_fprintf(qh ferr, 6143, "qhull internal error (qh_checkpolygon): #vertices %d != #facets %d\n",
+ numvertices, numfacets);
+ waserror= True;
+ }
+ if (qh hull_dim == 3 && numvertices + numfacets - numridges/2 != 2) {
+ qh_fprintf(qh ferr, 7063, "qhull warning: #vertices %d + #facets %d - #edges %d != 2\n\
+ A vertex appears twice in a edge list. May occur during merging.",
+ numvertices, numfacets, numridges/2);
+ /* occurs if lots of merging and a vertex ends up twice in an edge list. e.g., RBOX 1000 s W1e-13 t995849315 D2 | QHULL d Tc Tv */
+ }
+ }
+ if (waserror)
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+} /* checkpolygon */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="checkvertex">-</a>
+
+ qh_checkvertex( vertex )
+ check vertex for consistency
+ checks vertex->neighbors
+
+ notes:
+ neighbors checked efficiently in checkpolygon
+*/
+void qh_checkvertex(vertexT *vertex) {
+ boolT waserror= False;
+ facetT *neighbor, **neighborp, *errfacet=NULL;
+
+ if (qh_pointid(vertex->point) == qh_IDunknown) {
+ qh_fprintf(qh ferr, 6144, "qhull internal error (qh_checkvertex): unknown point id %p\n", vertex->point);
+ waserror= True;
+ }
+ if (vertex->id >= qh vertex_id) {
+ qh_fprintf(qh ferr, 6145, "qhull internal error (qh_checkvertex): unknown vertex id %d\n", vertex->id);
+ waserror= True;
+ }
+ if (!waserror && !vertex->deleted) {
+ if (qh_setsize(vertex->neighbors)) {
+ FOREACHneighbor_(vertex) {
+ if (!qh_setin(neighbor->vertices, vertex)) {
+ qh_fprintf(qh ferr, 6146, "qhull internal error (qh_checkvertex): neighbor f%d does not contain v%d\n", neighbor->id, vertex->id);
+ errfacet= neighbor;
+ waserror= True;
+ }
+ }
+ }
+ }
+ if (waserror) {
+ qh_errprint("ERRONEOUS", NULL, NULL, NULL, vertex);
+ qh_errexit(qh_ERRqhull, errfacet, NULL);
+ }
+} /* checkvertex */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="clearcenters">-</a>
+
+ qh_clearcenters( type )
+ clear old data from facet->center
+
+ notes:
+ sets new centertype
+ nop if CENTERtype is the same
+*/
+void qh_clearcenters(qh_CENTER type) {
+ facetT *facet;
+
+ if (qh CENTERtype != type) {
+ FORALLfacets {
+ if (facet->tricoplanar && !facet->keepcentrum)
+ facet->center= NULL; /* center is owned by the ->keepcentrum facet */
+ else if (qh CENTERtype == qh_ASvoronoi){
+ if (facet->center) {
+ qh_memfree(facet->center, qh center_size);
+ facet->center= NULL;
+ }
+ }else /* qh.CENTERtype == qh_AScentrum */ {
+ if (facet->center) {
+ qh_memfree(facet->center, qh normal_size);
+ facet->center= NULL;
+ }
+ }
+ }
+ qh CENTERtype= type;
+ }
+ trace2((qh ferr, 2043, "qh_clearcenters: switched to center type %d\n", type));
+} /* clearcenters */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="createsimplex">-</a>
+
+ qh_createsimplex( vertices )
+ creates a simplex from a set of vertices
+
+ returns:
+ initializes qh.facet_list to the simplex
+ initializes qh.newfacet_list, .facet_tail
+ initializes qh.vertex_list, .newvertex_list, .vertex_tail
+
+ design:
+ initializes lists
+ for each vertex
+ create a new facet
+ for each new facet
+ create its neighbor set
+*/
+void qh_createsimplex(setT *vertices) {
+ facetT *facet= NULL, *newfacet;
+ boolT toporient= True;
+ int vertex_i, vertex_n, nth;
+ setT *newfacets= qh_settemp(qh hull_dim+1);
+ vertexT *vertex;
+
+ qh facet_list= qh newfacet_list= qh facet_tail= qh_newfacet();
+ qh num_facets= qh num_vertices= qh num_visible= 0;
+ qh vertex_list= qh newvertex_list= qh vertex_tail= qh_newvertex(NULL);
+ FOREACHvertex_i_(vertices) {
+ newfacet= qh_newfacet();
+ newfacet->vertices= qh_setnew_delnthsorted(vertices, vertex_n,
+ vertex_i, 0);
+ newfacet->toporient= (unsigned char)toporient;
+ qh_appendfacet(newfacet);
+ newfacet->newfacet= True;
+ qh_appendvertex(vertex);
+ qh_setappend(&newfacets, newfacet);
+ toporient ^= True;
+ }
+ FORALLnew_facets {
+ nth= 0;
+ FORALLfacet_(qh newfacet_list) {
+ if (facet != newfacet)
+ SETelem_(newfacet->neighbors, nth++)= facet;
+ }
+ qh_settruncate(newfacet->neighbors, qh hull_dim);
+ }
+ qh_settempfree(&newfacets);
+ trace1((qh ferr, 1028, "qh_createsimplex: created simplex\n"));
+} /* createsimplex */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="delridge">-</a>
+
+ qh_delridge( ridge )
+ deletes ridge from data structures it belongs to
+ frees up its memory
+
+ notes:
+ in merge.c, caller sets vertex->delridge for each vertex
+ ridges also freed in qh_freeqhull
+*/
+void qh_delridge(ridgeT *ridge) {
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+
+ qh_setdel(ridge->top->ridges, ridge);
+ qh_setdel(ridge->bottom->ridges, ridge);
+ qh_setfree(&(ridge->vertices));
+ qh_memfree_(ridge, (int)sizeof(ridgeT), freelistp);
+} /* delridge */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="delvertex">-</a>
+
+ qh_delvertex( vertex )
+ deletes a vertex and frees its memory
+
+ notes:
+ assumes vertex->adjacencies have been updated if needed
+ unlinks from vertex_list
+*/
+void qh_delvertex(vertexT *vertex) {
+
+ if (vertex == qh tracevertex)
+ qh tracevertex= NULL;
+ qh_removevertex(vertex);
+ qh_setfree(&vertex->neighbors);
+ qh_memfree(vertex, (int)sizeof(vertexT));
+} /* delvertex */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="facet3vertex">-</a>
+
+ qh_facet3vertex( )
+ return temporary set of 3-d vertices in qh_ORIENTclock order
+
+ design:
+ if simplicial facet
+ build set from facet->vertices with facet->toporient
+ else
+ for each ridge in order
+ build set from ridge's vertices
+*/
+setT *qh_facet3vertex(facetT *facet) {
+ ridgeT *ridge, *firstridge;
+ vertexT *vertex;
+ int cntvertices, cntprojected=0;
+ setT *vertices;
+
+ cntvertices= qh_setsize(facet->vertices);
+ vertices= qh_settemp(cntvertices);
+ if (facet->simplicial) {
+ if (cntvertices != 3) {
+ qh_fprintf(qh ferr, 6147, "qhull internal error (qh_facet3vertex): only %d vertices for simplicial facet f%d\n",
+ cntvertices, facet->id);
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ qh_setappend(&vertices, SETfirst_(facet->vertices));
+ if (facet->toporient ^ qh_ORIENTclock)
+ qh_setappend(&vertices, SETsecond_(facet->vertices));
+ else
+ qh_setaddnth(&vertices, 0, SETsecond_(facet->vertices));
+ qh_setappend(&vertices, SETelem_(facet->vertices, 2));
+ }else {
+ ridge= firstridge= SETfirstt_(facet->ridges, ridgeT); /* no infinite */
+ while ((ridge= qh_nextridge3d(ridge, facet, &vertex))) {
+ qh_setappend(&vertices, vertex);
+ if (++cntprojected > cntvertices || ridge == firstridge)
+ break;
+ }
+ if (!ridge || cntprojected != cntvertices) {
+ qh_fprintf(qh ferr, 6148, "qhull internal error (qh_facet3vertex): ridges for facet %d don't match up. got at least %d\n",
+ facet->id, cntprojected);
+ qh_errexit(qh_ERRqhull, facet, ridge);
+ }
+ }
+ return vertices;
+} /* facet3vertex */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="findbestfacet">-</a>
+
+ qh_findbestfacet( point, bestoutside, bestdist, isoutside )
+ find facet that is furthest below a point
+
+ for Delaunay triangulations,
+ Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
+ Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates.
+
+ returns:
+ if bestoutside is set (e.g., qh_ALL)
+ returns best facet that is not upperdelaunay
+ if Delaunay and inside, point is outside circumsphere of bestfacet
+ else
+ returns first facet below point
+ if point is inside, returns nearest, !upperdelaunay facet
+ distance to facet
+ isoutside set if outside of facet
+
+ notes:
+ For tricoplanar facets, this finds one of the tricoplanar facets closest
+ to the point. For Delaunay triangulations, the point may be inside a
+ different tricoplanar facet. See <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
+
+ If inside, qh_findbestfacet performs an exhaustive search
+ this may be too conservative. Sometimes it is clearly required.
+
+ qh_findbestfacet is not used by qhull.
+ uses qh.visit_id and qh.coplanarset
+
+ see:
+ <a href="geom.c#findbest">qh_findbest</a>
+*/
+facetT *qh_findbestfacet(pointT *point, boolT bestoutside,
+ realT *bestdist, boolT *isoutside) {
+ facetT *bestfacet= NULL;
+ int numpart, totpart= 0;
+
+ bestfacet= qh_findbest(point, qh facet_list,
+ bestoutside, !qh_ISnewfacets, bestoutside /* qh_NOupper */,
+ bestdist, isoutside, &totpart);
+ if (*bestdist < -qh DISTround) {
+ bestfacet= qh_findfacet_all(point, bestdist, isoutside, &numpart);
+ totpart += numpart;
+ if ((isoutside && *isoutside && bestoutside)
+ || (isoutside && !*isoutside && bestfacet->upperdelaunay)) {
+ bestfacet= qh_findbest(point, bestfacet,
+ bestoutside, False, bestoutside,
+ bestdist, isoutside, &totpart);
+ totpart += numpart;
+ }
+ }
+ trace3((qh ferr, 3014, "qh_findbestfacet: f%d dist %2.2g isoutside %d totpart %d\n",
+ bestfacet->id, *bestdist, (isoutside ? *isoutside : UINT_MAX), totpart));
+ return bestfacet;
+} /* findbestfacet */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="findbestlower">-</a>
+
+ qh_findbestlower( facet, point, bestdist, numpart )
+ returns best non-upper, non-flipped neighbor of facet for point
+ if needed, searches vertex neighbors
+
+ returns:
+ returns bestdist and updates numpart
+
+ notes:
+ if Delaunay and inside, point is outside of circumsphere of bestfacet
+ called by qh_findbest() for points above an upperdelaunay facet
+
+*/
+facetT *qh_findbestlower(facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart) {
+ facetT *neighbor, **neighborp, *bestfacet= NULL;
+ realT bestdist= -REALmax/2 /* avoid underflow */;
+ realT dist;
+ vertexT *vertex;
+ boolT isoutside= False; /* not used */
+
+ zinc_(Zbestlower);
+ FOREACHneighbor_(upperfacet) {
+ if (neighbor->upperdelaunay || neighbor->flipped)
+ continue;
+ (*numpart)++;
+ qh_distplane(point, neighbor, &dist);
+ if (dist > bestdist) {
+ bestfacet= neighbor;
+ bestdist= dist;
+ }
+ }
+ if (!bestfacet) {
+ zinc_(Zbestlowerv);
+ /* rarely called, numpart does not count nearvertex computations */
+ vertex= qh_nearvertex(upperfacet, point, &dist);
+ qh_vertexneighbors();
+ FOREACHneighbor_(vertex) {
+ if (neighbor->upperdelaunay || neighbor->flipped)
+ continue;
+ (*numpart)++;
+ qh_distplane(point, neighbor, &dist);
+ if (dist > bestdist) {
+ bestfacet= neighbor;
+ bestdist= dist;
+ }
+ }
+ }
+ if (!bestfacet) {
+ zinc_(Zbestlowerall); /* invoked once per point in outsideset */
+ zmax_(Zbestloweralln, qh num_facets);
+ /* [dec'15] Previously reported as QH6228 */
+ trace3((qh ferr, 3025, "qh_findbestlower: all neighbors of facet %d are flipped or upper Delaunay. Search all facets\n",
+ upperfacet->id));
+ /* rarely called */
+ bestfacet= qh_findfacet_all(point, &bestdist, &isoutside, numpart);
+ }
+ *bestdistp= bestdist;
+ trace3((qh ferr, 3015, "qh_findbestlower: f%d dist %2.2g for f%d p%d\n",
+ bestfacet->id, bestdist, upperfacet->id, qh_pointid(point)));
+ return bestfacet;
+} /* findbestlower */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="findfacet_all">-</a>
+
+ qh_findfacet_all( point, bestdist, isoutside, numpart )
+ exhaustive search for facet below a point
+
+ for Delaunay triangulations,
+ Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
+ Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates.
+
+ returns:
+ returns first facet below point
+ if point is inside,
+ returns nearest facet
+ distance to facet
+ isoutside if point is outside of the hull
+ number of distance tests
+
+ notes:
+ primarily for library users, rarely used by Qhull
+*/
+facetT *qh_findfacet_all(pointT *point, realT *bestdist, boolT *isoutside,
+ int *numpart) {
+ facetT *bestfacet= NULL, *facet;
+ realT dist;
+ int totpart= 0;
+
+ *bestdist= -REALmax;
+ *isoutside= False;
+ FORALLfacets {
+ if (facet->flipped || !facet->normal)
+ continue;
+ totpart++;
+ qh_distplane(point, facet, &dist);
+ if (dist > *bestdist) {
+ *bestdist= dist;
+ bestfacet= facet;
+ if (dist > qh MINoutside) {
+ *isoutside= True;
+ break;
+ }
+ }
+ }
+ *numpart= totpart;
+ trace3((qh ferr, 3016, "qh_findfacet_all: f%d dist %2.2g isoutside %d totpart %d\n",
+ getid_(bestfacet), *bestdist, *isoutside, totpart));
+ return bestfacet;
+} /* findfacet_all */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="findgood">-</a>
+
+ qh_findgood( facetlist, goodhorizon )
+ identify good facets for qh.PRINTgood
+ if qh.GOODvertex>0
+ facet includes point as vertex
+ if !match, returns goodhorizon
+ inactive if qh.MERGING
+ if qh.GOODpoint
+ facet is visible or coplanar (>0) or not visible (<0)
+ if qh.GOODthreshold
+ facet->normal matches threshold
+ if !goodhorizon and !match,
+ selects facet with closest angle
+ sets GOODclosest
+
+ returns:
+ number of new, good facets found
+ determines facet->good
+ may update qh.GOODclosest
+
+ notes:
+ qh_findgood_all further reduces the good region
+
+ design:
+ count good facets
+ mark good facets for qh.GOODpoint
+ mark good facets for qh.GOODthreshold
+ if necessary
+ update qh.GOODclosest
+*/
+int qh_findgood(facetT *facetlist, int goodhorizon) {
+ facetT *facet, *bestfacet= NULL;
+ realT angle, bestangle= REALmax, dist;
+ int numgood=0;
+
+ FORALLfacet_(facetlist) {
+ if (facet->good)
+ numgood++;
+ }
+ if (qh GOODvertex>0 && !qh MERGING) {
+ FORALLfacet_(facetlist) {
+ if (!qh_isvertex(qh GOODvertexp, facet->vertices)) {
+ facet->good= False;
+ numgood--;
+ }
+ }
+ }
+ if (qh GOODpoint && numgood) {
+ FORALLfacet_(facetlist) {
+ if (facet->good && facet->normal) {
+ zinc_(Zdistgood);
+ qh_distplane(qh GOODpointp, facet, &dist);
+ if ((qh GOODpoint > 0) ^ (dist > 0.0)) {
+ facet->good= False;
+ numgood--;
+ }
+ }
+ }
+ }
+ if (qh GOODthreshold && (numgood || goodhorizon || qh GOODclosest)) {
+ FORALLfacet_(facetlist) {
+ if (facet->good && facet->normal) {
+ if (!qh_inthresholds(facet->normal, &angle)) {
+ facet->good= False;
+ numgood--;
+ if (angle < bestangle) {
+ bestangle= angle;
+ bestfacet= facet;
+ }
+ }
+ }
+ }
+ if (!numgood && (!goodhorizon || qh GOODclosest)) {
+ if (qh GOODclosest) {
+ if (qh GOODclosest->visible)
+ qh GOODclosest= NULL;
+ else {
+ qh_inthresholds(qh GOODclosest->normal, &angle);
+ if (angle < bestangle)
+ bestfacet= qh GOODclosest;
+ }
+ }
+ if (bestfacet && bestfacet != qh GOODclosest) {
+ if (qh GOODclosest)
+ qh GOODclosest->good= False;
+ qh GOODclosest= bestfacet;
+ bestfacet->good= True;
+ numgood++;
+ trace2((qh ferr, 2044, "qh_findgood: f%d is closest(%2.2g) to thresholds\n",
+ bestfacet->id, bestangle));
+ return numgood;
+ }
+ }else if (qh GOODclosest) { /* numgood > 0 */
+ qh GOODclosest->good= False;
+ qh GOODclosest= NULL;
+ }
+ }
+ zadd_(Zgoodfacet, numgood);
+ trace2((qh ferr, 2045, "qh_findgood: found %d good facets with %d good horizon\n",
+ numgood, goodhorizon));
+ if (!numgood && qh GOODvertex>0 && !qh MERGING)
+ return goodhorizon;
+ return numgood;
+} /* findgood */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="findgood_all">-</a>
+
+ qh_findgood_all( facetlist )
+ apply other constraints for good facets (used by qh.PRINTgood)
+ if qh.GOODvertex
+ facet includes (>0) or doesn't include (<0) point as vertex
+ if last good facet and ONLYgood, prints warning and continues
+ if qh.SPLITthresholds
+ facet->normal matches threshold, or if none, the closest one
+ calls qh_findgood
+ nop if good not used
+
+ returns:
+ clears facet->good if not good
+ sets qh.num_good
+
+ notes:
+ this is like qh_findgood but more restrictive
+
+ design:
+ uses qh_findgood to mark good facets
+ marks facets for qh.GOODvertex
+ marks facets for qh.SPLITthreholds
+*/
+void qh_findgood_all(facetT *facetlist) {
+ facetT *facet, *bestfacet=NULL;
+ realT angle, bestangle= REALmax;
+ int numgood=0, startgood;
+
+ if (!qh GOODvertex && !qh GOODthreshold && !qh GOODpoint
+ && !qh SPLITthresholds)
+ return;
+ if (!qh ONLYgood)
+ qh_findgood(qh facet_list, 0);
+ FORALLfacet_(facetlist) {
+ if (facet->good)
+ numgood++;
+ }
+ if (qh GOODvertex <0 || (qh GOODvertex > 0 && qh MERGING)) {
+ FORALLfacet_(facetlist) {
+ if (facet->good && ((qh GOODvertex > 0) ^ !!qh_isvertex(qh GOODvertexp, facet->vertices))) {
+ if (!--numgood) {
+ if (qh ONLYgood) {
+ qh_fprintf(qh ferr, 7064, "qhull warning: good vertex p%d does not match last good facet f%d. Ignored.\n",
+ qh_pointid(qh GOODvertexp), facet->id);
+ return;
+ }else if (qh GOODvertex > 0)
+ qh_fprintf(qh ferr, 7065, "qhull warning: point p%d is not a vertex('QV%d').\n",
+ qh GOODvertex-1, qh GOODvertex-1);
+ else
+ qh_fprintf(qh ferr, 7066, "qhull warning: point p%d is a vertex for every facet('QV-%d').\n",
+ -qh GOODvertex - 1, -qh GOODvertex - 1);
+ }
+ facet->good= False;
+ }
+ }
+ }
+ startgood= numgood;
+ if (qh SPLITthresholds) {
+ FORALLfacet_(facetlist) {
+ if (facet->good) {
+ if (!qh_inthresholds(facet->normal, &angle)) {
+ facet->good= False;
+ numgood--;
+ if (angle < bestangle) {
+ bestangle= angle;
+ bestfacet= facet;
+ }
+ }
+ }
+ }
+ if (!numgood && bestfacet) {
+ bestfacet->good= True;
+ numgood++;
+ trace0((qh ferr, 23, "qh_findgood_all: f%d is closest(%2.2g) to thresholds\n",
+ bestfacet->id, bestangle));
+ return;
+ }
+ }
+ qh num_good= numgood;
+ trace0((qh ferr, 24, "qh_findgood_all: %d good facets remain out of %d facets\n",
+ numgood, startgood));
+} /* findgood_all */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="furthestnext">-</a>
+
+ qh_furthestnext()
+ set qh.facet_next to facet with furthest of all furthest points
+ searches all facets on qh.facet_list
+
+ notes:
+ this may help avoid precision problems
+*/
+void qh_furthestnext(void /* qh.facet_list */) {
+ facetT *facet, *bestfacet= NULL;
+ realT dist, bestdist= -REALmax;
+
+ FORALLfacets {
+ if (facet->outsideset) {
+#if qh_COMPUTEfurthest
+ pointT *furthest;
+ furthest= (pointT*)qh_setlast(facet->outsideset);
+ zinc_(Zcomputefurthest);
+ qh_distplane(furthest, facet, &dist);
+#else
+ dist= facet->furthestdist;
+#endif
+ if (dist > bestdist) {
+ bestfacet= facet;
+ bestdist= dist;
+ }
+ }
+ }
+ if (bestfacet) {
+ qh_removefacet(bestfacet);
+ qh_prependfacet(bestfacet, &qh facet_next);
+ trace1((qh ferr, 1029, "qh_furthestnext: made f%d next facet(dist %.2g)\n",
+ bestfacet->id, bestdist));
+ }
+} /* furthestnext */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="furthestout">-</a>
+
+ qh_furthestout( facet )
+ make furthest outside point the last point of outsideset
+
+ returns:
+ updates facet->outsideset
+ clears facet->notfurthest
+ sets facet->furthestdist
+
+ design:
+ determine best point of outsideset
+ make it the last point of outsideset
+*/
+void qh_furthestout(facetT *facet) {
+ pointT *point, **pointp, *bestpoint= NULL;
+ realT dist, bestdist= -REALmax;
+
+ FOREACHpoint_(facet->outsideset) {
+ qh_distplane(point, facet, &dist);
+ zinc_(Zcomputefurthest);
+ if (dist > bestdist) {
+ bestpoint= point;
+ bestdist= dist;
+ }
+ }
+ if (bestpoint) {
+ qh_setdel(facet->outsideset, point);
+ qh_setappend(&facet->outsideset, point);
+#if !qh_COMPUTEfurthest
+ facet->furthestdist= bestdist;
+#endif
+ }
+ facet->notfurthest= False;
+ trace3((qh ferr, 3017, "qh_furthestout: p%d is furthest outside point of f%d\n",
+ qh_pointid(point), facet->id));
+} /* furthestout */
+
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="infiniteloop">-</a>
+
+ qh_infiniteloop( facet )
+ report infinite loop error due to facet
+*/
+void qh_infiniteloop(facetT *facet) {
+
+ qh_fprintf(qh ferr, 6149, "qhull internal error (qh_infiniteloop): potential infinite loop detected\n");
+ qh_errexit(qh_ERRqhull, facet, NULL);
+} /* qh_infiniteloop */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="initbuild">-</a>
+
+ qh_initbuild()
+ initialize hull and outside sets with point array
+ qh.FIRSTpoint/qh.NUMpoints is point array
+ if qh.GOODpoint
+ adds qh.GOODpoint to initial hull
+
+ returns:
+ qh_facetlist with initial hull
+ points partioned into outside sets, coplanar sets, or inside
+ initializes qh.GOODpointp, qh.GOODvertexp,
+
+ design:
+ initialize global variables used during qh_buildhull
+ determine precision constants and points with max/min coordinate values
+ if qh.SCALElast, scale last coordinate(for 'd')
+ build initial simplex
+ partition input points into facets of initial simplex
+ set up lists
+ if qh.ONLYgood
+ check consistency
+ add qh.GOODvertex if defined
+*/
+void qh_initbuild( void) {
+ setT *maxpoints, *vertices;
+ facetT *facet;
+ int i, numpart;
+ realT dist;
+ boolT isoutside;
+
+ qh furthest_id= qh_IDunknown;
+ qh lastreport= 0;
+ qh facet_id= qh vertex_id= qh ridge_id= 0;
+ qh visit_id= qh vertex_visit= 0;
+ qh maxoutdone= False;
+
+ if (qh GOODpoint > 0)
+ qh GOODpointp= qh_point(qh GOODpoint-1);
+ else if (qh GOODpoint < 0)
+ qh GOODpointp= qh_point(-qh GOODpoint-1);
+ if (qh GOODvertex > 0)
+ qh GOODvertexp= qh_point(qh GOODvertex-1);
+ else if (qh GOODvertex < 0)
+ qh GOODvertexp= qh_point(-qh GOODvertex-1);
+ if ((qh GOODpoint
+ && (qh GOODpointp < qh first_point /* also catches !GOODpointp */
+ || qh GOODpointp > qh_point(qh num_points-1)))
+ || (qh GOODvertex
+ && (qh GOODvertexp < qh first_point /* also catches !GOODvertexp */
+ || qh GOODvertexp > qh_point(qh num_points-1)))) {
+ qh_fprintf(qh ferr, 6150, "qhull input error: either QGn or QVn point is > p%d\n",
+ qh num_points-1);
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ maxpoints= qh_maxmin(qh first_point, qh num_points, qh hull_dim);
+ if (qh SCALElast)
+ qh_scalelast(qh first_point, qh num_points, qh hull_dim,
+ qh MINlastcoord, qh MAXlastcoord, qh MAXwidth);
+ qh_detroundoff();
+ if (qh DELAUNAY && qh upper_threshold[qh hull_dim-1] > REALmax/2
+ && qh lower_threshold[qh hull_dim-1] < -REALmax/2) {
+ for (i=qh_PRINTEND; i--; ) {
+ if (qh PRINTout[i] == qh_PRINTgeom && qh DROPdim < 0
+ && !qh GOODthreshold && !qh SPLITthresholds)
+ break; /* in this case, don't set upper_threshold */
+ }
+ if (i < 0) {
+ if (qh UPPERdelaunay) { /* matches qh.upperdelaunay in qh_setfacetplane */
+ qh lower_threshold[qh hull_dim-1]= qh ANGLEround * qh_ZEROdelaunay;
+ qh GOODthreshold= True;
+ }else {
+ qh upper_threshold[qh hull_dim-1]= -qh ANGLEround * qh_ZEROdelaunay;
+ if (!qh GOODthreshold)
+ qh SPLITthresholds= True; /* build upper-convex hull even if Qg */
+ /* qh_initqhull_globals errors if Qg without Pdk/etc. */
+ }
+ }
+ }
+ vertices= qh_initialvertices(qh hull_dim, maxpoints, qh first_point, qh num_points);
+ qh_initialhull(vertices); /* initial qh facet_list */
+ qh_partitionall(vertices, qh first_point, qh num_points);
+ if (qh PRINToptions1st || qh TRACElevel || qh IStracing) {
+ if (qh TRACElevel || qh IStracing)
+ qh_fprintf(qh ferr, 8103, "\nTrace level %d for %s | %s\n",
+ qh IStracing ? qh IStracing : qh TRACElevel, qh rbox_command, qh qhull_command);
+ qh_fprintf(qh ferr, 8104, "Options selected for Qhull %s:\n%s\n", qh_version, qh qhull_options);
+ }
+ qh_resetlists(False, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
+ qh facet_next= qh facet_list;
+ qh_furthestnext(/* qh.facet_list */);
+ if (qh PREmerge) {
+ qh cos_max= qh premerge_cos;
+ qh centrum_radius= qh premerge_centrum;
+ }
+ if (qh ONLYgood) {
+ if (qh GOODvertex > 0 && qh MERGING) {
+ qh_fprintf(qh ferr, 6151, "qhull input error: 'Qg QVn' (only good vertex) does not work with merging.\nUse 'QJ' to joggle the input or 'Q0' to turn off merging.\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (!(qh GOODthreshold || qh GOODpoint
+ || (!qh MERGEexact && !qh PREmerge && qh GOODvertexp))) {
+ qh_fprintf(qh ferr, 6152, "qhull input error: 'Qg' (ONLYgood) needs a good threshold('Pd0D0'), a\n\
+good point(QGn or QG-n), or a good vertex with 'QJ' or 'Q0' (QVn).\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (qh GOODvertex > 0 && !qh MERGING /* matches qh_partitionall */
+ && !qh_isvertex(qh GOODvertexp, vertices)) {
+ facet= qh_findbestnew(qh GOODvertexp, qh facet_list,
+ &dist, !qh_ALL, &isoutside, &numpart);
+ zadd_(Zdistgood, numpart);
+ if (!isoutside) {
+ qh_fprintf(qh ferr, 6153, "qhull input error: point for QV%d is inside initial simplex. It can not be made a vertex.\n",
+ qh_pointid(qh GOODvertexp));
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ if (!qh_addpoint(qh GOODvertexp, facet, False)) {
+ qh_settempfree(&vertices);
+ qh_settempfree(&maxpoints);
+ return;
+ }
+ }
+ qh_findgood(qh facet_list, 0);
+ }
+ qh_settempfree(&vertices);
+ qh_settempfree(&maxpoints);
+ trace1((qh ferr, 1030, "qh_initbuild: initial hull created and points partitioned\n"));
+} /* initbuild */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="initialhull">-</a>
+
+ qh_initialhull( vertices )
+ constructs the initial hull as a DIM3 simplex of vertices
+
+ design:
+ creates a simplex (initializes lists)
+ determines orientation of simplex
+ sets hyperplanes for facets
+ doubles checks orientation (in case of axis-parallel facets with Gaussian elimination)
+ checks for flipped facets and qh.NARROWhull
+ checks the result
+*/
+void qh_initialhull(setT *vertices) {
+ facetT *facet, *firstfacet, *neighbor, **neighborp;
+ realT dist, angle, minangle= REALmax;
+#ifndef qh_NOtrace
+ int k;
+#endif
+
+ qh_createsimplex(vertices); /* qh.facet_list */
+ qh_resetlists(False, qh_RESETvisible);
+ qh facet_next= qh facet_list; /* advance facet when processed */
+ qh interior_point= qh_getcenter(vertices);
+ firstfacet= qh facet_list;
+ qh_setfacetplane(firstfacet);
+ zinc_(Znumvisibility); /* needs to be in printsummary */
+ qh_distplane(qh interior_point, firstfacet, &dist);
+ if (dist > 0) {
+ FORALLfacets
+ facet->toporient ^= (unsigned char)True;
+ }
+ FORALLfacets
+ qh_setfacetplane(facet);
+ FORALLfacets {
+ if (!qh_checkflipped(facet, NULL, qh_ALL)) {/* due to axis-parallel facet */
+ trace1((qh ferr, 1031, "qh_initialhull: initial orientation incorrect. Correct all facets\n"));
+ facet->flipped= False;
+ FORALLfacets {
+ facet->toporient ^= (unsigned char)True;
+ qh_orientoutside(facet);
+ }
+ break;
+ }
+ }
+ FORALLfacets {
+ if (!qh_checkflipped(facet, NULL, !qh_ALL)) { /* can happen with 'R0.1' */
+ if (qh DELAUNAY && ! qh ATinfinity) {
+ if (qh UPPERdelaunay)
+ qh_fprintf(qh ferr, 6240, "Qhull precision error: Initial simplex is cocircular or cospherical. Option 'Qs' searches all points. Can not compute the upper Delaunay triangulation or upper Voronoi diagram of cocircular/cospherical points.\n");
+ else
+ qh_fprintf(qh ferr, 6239, "Qhull precision error: Initial simplex is cocircular or cospherical. Use option 'Qz' for the Delaunay triangulation or Voronoi diagram of cocircular/cospherical points. Option 'Qz' adds a point \"at infinity\". Use option 'Qs' to search all points for the initial simplex.\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ qh_precision("initial simplex is flat");
+ qh_fprintf(qh ferr, 6154, "Qhull precision error: Initial simplex is flat (facet %d is coplanar with the interior point)\n",
+ facet->id);
+ qh_errexit(qh_ERRsingular, NULL, NULL); /* calls qh_printhelp_singular */
+ }
+ FOREACHneighbor_(facet) {
+ angle= qh_getangle(facet->normal, neighbor->normal);
+ minimize_( minangle, angle);
+ }
+ }
+ if (minangle < qh_MAXnarrow && !qh NOnarrow) {
+ realT diff= 1.0 + minangle;
+
+ qh NARROWhull= True;
+ qh_option("_narrow-hull", NULL, &diff);
+ if (minangle < qh_WARNnarrow && !qh RERUN && qh PRINTprecision)
+ qh_printhelp_narrowhull(qh ferr, minangle);
+ }
+ zzval_(Zprocessed)= qh hull_dim+1;
+ qh_checkpolygon(qh facet_list);
+ qh_checkconvex(qh facet_list, qh_DATAfault);
+#ifndef qh_NOtrace
+ if (qh IStracing >= 1) {
+ qh_fprintf(qh ferr, 8105, "qh_initialhull: simplex constructed, interior point:");
+ for (k=0; k < qh hull_dim; k++)
+ qh_fprintf(qh ferr, 8106, " %6.4g", qh interior_point[k]);
+ qh_fprintf(qh ferr, 8107, "\n");
+ }
+#endif
+} /* initialhull */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="initialvertices">-</a>
+
+ qh_initialvertices( dim, maxpoints, points, numpoints )
+ determines a non-singular set of initial vertices
+ maxpoints may include duplicate points
+
+ returns:
+ temporary set of dim+1 vertices in descending order by vertex id
+ if qh.RANDOMoutside && !qh.ALLpoints
+ picks random points
+ if dim >= qh_INITIALmax,
+ uses min/max x and max points with non-zero determinants
+
+ notes:
+ unless qh.ALLpoints,
+ uses maxpoints as long as determinate is non-zero
+*/
+setT *qh_initialvertices(int dim, setT *maxpoints, pointT *points, int numpoints) {
+ pointT *point, **pointp;
+ setT *vertices, *simplex, *tested;
+ realT randr;
+ int idx, point_i, point_n, k;
+ boolT nearzero= False;
+
+ vertices= qh_settemp(dim + 1);
+ simplex= qh_settemp(dim+1);
+ if (qh ALLpoints)
+ qh_maxsimplex(dim, NULL, points, numpoints, &simplex);
+ else if (qh RANDOMoutside) {
+ while (qh_setsize(simplex) != dim+1) {
+ randr= qh_RANDOMint;
+ randr= randr/(qh_RANDOMmax+1);
+ idx= (int)floor(qh num_points * randr);
+ while (qh_setin(simplex, qh_point(idx))) {
+ idx++; /* in case qh_RANDOMint always returns the same value */
+ idx= idx < qh num_points ? idx : 0;
+ }
+ qh_setappend(&simplex, qh_point(idx));
+ }
+ }else if (qh hull_dim >= qh_INITIALmax) {
+ tested= qh_settemp(dim+1);
+ qh_setappend(&simplex, SETfirst_(maxpoints)); /* max and min X coord */
+ qh_setappend(&simplex, SETsecond_(maxpoints));
+ qh_maxsimplex(fmin_(qh_INITIALsearch, dim), maxpoints, points, numpoints, &simplex);
+ k= qh_setsize(simplex);
+ FOREACHpoint_i_(maxpoints) {
+ if (point_i & 0x1) { /* first pick up max. coord. points */
+ if (!qh_setin(simplex, point) && !qh_setin(tested, point)){
+ qh_detsimplex(point, simplex, k, &nearzero);
+ if (nearzero)
+ qh_setappend(&tested, point);
+ else {
+ qh_setappend(&simplex, point);
+ if (++k == dim) /* use search for last point */
+ break;
+ }
+ }
+ }
+ }
+ while (k != dim && (point= (pointT*)qh_setdellast(maxpoints))) {
+ if (!qh_setin(simplex, point) && !qh_setin(tested, point)){
+ qh_detsimplex(point, simplex, k, &nearzero);
+ if (nearzero)
+ qh_setappend(&tested, point);
+ else {
+ qh_setappend(&simplex, point);
+ k++;
+ }
+ }
+ }
+ idx= 0;
+ while (k != dim && (point= qh_point(idx++))) {
+ if (!qh_setin(simplex, point) && !qh_setin(tested, point)){
+ qh_detsimplex(point, simplex, k, &nearzero);
+ if (!nearzero){
+ qh_setappend(&simplex, point);
+ k++;
+ }
+ }
+ }
+ qh_settempfree(&tested);
+ qh_maxsimplex(dim, maxpoints, points, numpoints, &simplex);
+ }else
+ qh_maxsimplex(dim, maxpoints, points, numpoints, &simplex);
+ FOREACHpoint_(simplex)
+ qh_setaddnth(&vertices, 0, qh_newvertex(point)); /* descending order */
+ qh_settempfree(&simplex);
+ return vertices;
+} /* initialvertices */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="isvertex">-</a>
+
+ qh_isvertex( point, vertices )
+ returns vertex if point is in vertex set, else returns NULL
+
+ notes:
+ for qh.GOODvertex
+*/
+vertexT *qh_isvertex(pointT *point, setT *vertices) {
+ vertexT *vertex, **vertexp;
+
+ FOREACHvertex_(vertices) {
+ if (vertex->point == point)
+ return vertex;
+ }
+ return NULL;
+} /* isvertex */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="makenewfacets">-</a>
+
+ qh_makenewfacets( point )
+ make new facets from point and qh.visible_list
+
+ returns:
+ qh.newfacet_list= list of new facets with hyperplanes and ->newfacet
+ qh.newvertex_list= list of vertices in new facets with ->newlist set
+
+ if (qh.ONLYgood)
+ newfacets reference horizon facets, but not vice versa
+ ridges reference non-simplicial horizon ridges, but not vice versa
+ does not change existing facets
+ else
+ sets qh.NEWfacets
+ new facets attached to horizon facets and ridges
+ for visible facets,
+ visible->r.replace is corresponding new facet
+
+ see also:
+ qh_makenewplanes() -- make hyperplanes for facets
+ qh_attachnewfacets() -- attachnewfacets if not done here(qh ONLYgood)
+ qh_matchnewfacets() -- match up neighbors
+ qh_updatevertices() -- update vertex neighbors and delvertices
+ qh_deletevisible() -- delete visible facets
+ qh_checkpolygon() --check the result
+ qh_triangulate() -- triangulate a non-simplicial facet
+
+ design:
+ for each visible facet
+ make new facets to its horizon facets
+ update its f.replace
+ clear its neighbor set
+*/
+vertexT *qh_makenewfacets(pointT *point /*visible_list*/) {
+ facetT *visible, *newfacet= NULL, *newfacet2= NULL, *neighbor, **neighborp;
+ vertexT *apex;
+ int numnew=0;
+
+ qh newfacet_list= qh facet_tail;
+ qh newvertex_list= qh vertex_tail;
+ apex= qh_newvertex(point);
+ qh_appendvertex(apex);
+ qh visit_id++;
+ if (!qh ONLYgood)
+ qh NEWfacets= True;
+ FORALLvisible_facets {
+ FOREACHneighbor_(visible)
+ neighbor->seen= False;
+ if (visible->ridges) {
+ visible->visitid= qh visit_id;
+ newfacet2= qh_makenew_nonsimplicial(visible, apex, &numnew);
+ }
+ if (visible->simplicial)
+ newfacet= qh_makenew_simplicial(visible, apex, &numnew);
+ if (!qh ONLYgood) {
+ if (newfacet2) /* newfacet is null if all ridges defined */
+ newfacet= newfacet2;
+ if (newfacet)
+ visible->f.replace= newfacet;
+ else
+ zinc_(Zinsidevisible);
+ SETfirst_(visible->neighbors)= NULL;
+ }
+ }
+ trace1((qh ferr, 1032, "qh_makenewfacets: created %d new facets from point p%d to horizon\n",
+ numnew, qh_pointid(point)));
+ if (qh IStracing >= 4)
+ qh_printfacetlist(qh newfacet_list, NULL, qh_ALL);
+ return apex;
+} /* makenewfacets */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="matchduplicates">-</a>
+
+ qh_matchduplicates( atfacet, atskip, hashsize, hashcount )
+ match duplicate ridges in qh.hash_table for atfacet/atskip
+ duplicates marked with ->dupridge and qh_DUPLICATEridge
+
+ returns:
+ picks match with worst merge (min distance apart)
+ updates hashcount
+
+ see also:
+ qh_matchneighbor
+
+ notes:
+
+ design:
+ compute hash value for atfacet and atskip
+ repeat twice -- once to make best matches, once to match the rest
+ for each possible facet in qh.hash_table
+ if it is a matching facet and pass 2
+ make match
+ unless tricoplanar, mark match for merging (qh_MERGEridge)
+ [e.g., tricoplanar RBOX s 1000 t993602376 | QHULL C-1e-3 d Qbb FA Qt]
+ if it is a matching facet and pass 1
+ test if this is a better match
+ if pass 1,
+ make best match (it will not be merged)
+*/
+#ifndef qh_NOmerge
+void qh_matchduplicates(facetT *atfacet, int atskip, int hashsize, int *hashcount) {
+ boolT same, ismatch;
+ int hash, scan;
+ facetT *facet, *newfacet, *maxmatch= NULL, *maxmatch2= NULL, *nextfacet;
+ int skip, newskip, nextskip= 0, maxskip= 0, maxskip2= 0, makematch;
+ realT maxdist= -REALmax, mindist, dist2, low, high;
+
+ hash= qh_gethash(hashsize, atfacet->vertices, qh hull_dim, 1,
+ SETelem_(atfacet->vertices, atskip));
+ trace2((qh ferr, 2046, "qh_matchduplicates: find duplicate matches for f%d skip %d hash %d hashcount %d\n",
+ atfacet->id, atskip, hash, *hashcount));
+ for (makematch= 0; makematch < 2; makematch++) {
+ qh visit_id++;
+ for (newfacet= atfacet, newskip= atskip; newfacet; newfacet= nextfacet, newskip= nextskip) {
+ zinc_(Zhashlookup);
+ nextfacet= NULL;
+ newfacet->visitid= qh visit_id;
+ for (scan= hash; (facet= SETelemt_(qh hash_table, scan, facetT));
+ scan= (++scan >= hashsize ? 0 : scan)) {
+ if (!facet->dupridge || facet->visitid == qh visit_id)
+ continue;
+ zinc_(Zhashtests);
+ if (qh_matchvertices(1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) {
+ ismatch= (same == (boolT)(newfacet->toporient ^ facet->toporient));
+ if (SETelemt_(facet->neighbors, skip, facetT) != qh_DUPLICATEridge) {
+ if (!makematch) {
+ qh_fprintf(qh ferr, 6155, "qhull internal error (qh_matchduplicates): missing dupridge at f%d skip %d for new f%d skip %d hash %d\n",
+ facet->id, skip, newfacet->id, newskip, hash);
+ qh_errexit2(qh_ERRqhull, facet, newfacet);
+ }
+ }else if (ismatch && makematch) {
+ if (SETelemt_(newfacet->neighbors, newskip, facetT) == qh_DUPLICATEridge) {
+ SETelem_(facet->neighbors, skip)= newfacet;
+ if (newfacet->tricoplanar)
+ SETelem_(newfacet->neighbors, newskip)= facet;
+ else
+ SETelem_(newfacet->neighbors, newskip)= qh_MERGEridge;
+ *hashcount -= 2; /* removed two unmatched facets */
+ trace4((qh ferr, 4059, "qh_matchduplicates: duplicate f%d skip %d matched with new f%d skip %d merge\n",
+ facet->id, skip, newfacet->id, newskip));
+ }
+ }else if (ismatch) {
+ mindist= qh_getdistance(facet, newfacet, &low, &high);
+ dist2= qh_getdistance(newfacet, facet, &low, &high);
+ minimize_(mindist, dist2);
+ if (mindist > maxdist) {
+ maxdist= mindist;
+ maxmatch= facet;
+ maxskip= skip;
+ maxmatch2= newfacet;
+ maxskip2= newskip;
+ }
+ trace3((qh ferr, 3018, "qh_matchduplicates: duplicate f%d skip %d new f%d skip %d at dist %2.2g, max is now f%d f%d\n",
+ facet->id, skip, newfacet->id, newskip, mindist,
+ maxmatch->id, maxmatch2->id));
+ }else { /* !ismatch */
+ nextfacet= facet;
+ nextskip= skip;
+ }
+ }
+ if (makematch && !facet
+ && SETelemt_(facet->neighbors, skip, facetT) == qh_DUPLICATEridge) {
+ qh_fprintf(qh ferr, 6156, "qhull internal error (qh_matchduplicates): no MERGEridge match for duplicate f%d skip %d at hash %d\n",
+ newfacet->id, newskip, hash);
+ qh_errexit(qh_ERRqhull, newfacet, NULL);
+ }
+ }
+ } /* end of for each new facet at hash */
+ if (!makematch) {
+ if (!maxmatch) {
+ qh_fprintf(qh ferr, 6157, "qhull internal error (qh_matchduplicates): no maximum match at duplicate f%d skip %d at hash %d\n",
+ atfacet->id, atskip, hash);
+ qh_errexit(qh_ERRqhull, atfacet, NULL);
+ }
+ SETelem_(maxmatch->neighbors, maxskip)= maxmatch2; /* maxmatch!=0 by QH6157 */
+ SETelem_(maxmatch2->neighbors, maxskip2)= maxmatch;
+ *hashcount -= 2; /* removed two unmatched facets */
+ zzinc_(Zmultiridge);
+ trace0((qh ferr, 25, "qh_matchduplicates: duplicate f%d skip %d matched with new f%d skip %d keep\n",
+ maxmatch->id, maxskip, maxmatch2->id, maxskip2));
+ qh_precision("ridge with multiple neighbors");
+ if (qh IStracing >= 4)
+ qh_errprint("DUPLICATED/MATCH", maxmatch, maxmatch2, NULL, NULL);
+ }
+ }
+} /* matchduplicates */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="nearcoplanar">-</a>
+
+ qh_nearcoplanar()
+ for all facets, remove near-inside points from facet->coplanarset</li>
+ coplanar points defined by innerplane from qh_outerinner()
+
+ returns:
+ if qh KEEPcoplanar && !qh KEEPinside
+ facet->coplanarset only contains coplanar points
+ if qh.JOGGLEmax
+ drops inner plane by another qh.JOGGLEmax diagonal since a
+ vertex could shift out while a coplanar point shifts in
+
+ notes:
+ used for qh.PREmerge and qh.JOGGLEmax
+ must agree with computation of qh.NEARcoplanar in qh_detroundoff()
+ design:
+ if not keeping coplanar or inside points
+ free all coplanar sets
+ else if not keeping both coplanar and inside points
+ remove !coplanar or !inside points from coplanar sets
+*/
+void qh_nearcoplanar(void /* qh.facet_list */) {
+ facetT *facet;
+ pointT *point, **pointp;
+ int numpart;
+ realT dist, innerplane;
+
+ if (!qh KEEPcoplanar && !qh KEEPinside) {
+ FORALLfacets {
+ if (facet->coplanarset)
+ qh_setfree( &facet->coplanarset);
+ }
+ }else if (!qh KEEPcoplanar || !qh KEEPinside) {
+ qh_outerinner(NULL, NULL, &innerplane);
+ if (qh JOGGLEmax < REALmax/2)
+ innerplane -= qh JOGGLEmax * sqrt((realT)qh hull_dim);
+ numpart= 0;
+ FORALLfacets {
+ if (facet->coplanarset) {
+ FOREACHpoint_(facet->coplanarset) {
+ numpart++;
+ qh_distplane(point, facet, &dist);
+ if (dist < innerplane) {
+ if (!qh KEEPinside)
+ SETref_(point)= NULL;
+ }else if (!qh KEEPcoplanar)
+ SETref_(point)= NULL;
+ }
+ qh_setcompact(facet->coplanarset);
+ }
+ }
+ zzadd_(Zcheckpart, numpart);
+ }
+} /* nearcoplanar */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="nearvertex">-</a>
+
+ qh_nearvertex( facet, point, bestdist )
+ return nearest vertex in facet to point
+
+ returns:
+ vertex and its distance
+
+ notes:
+ if qh.DELAUNAY
+ distance is measured in the input set
+ searches neighboring tricoplanar facets (requires vertexneighbors)
+ Slow implementation. Recomputes vertex set for each point.
+ The vertex set could be stored in the qh.keepcentrum facet.
+*/
+vertexT *qh_nearvertex(facetT *facet, pointT *point, realT *bestdistp) {
+ realT bestdist= REALmax, dist;
+ vertexT *bestvertex= NULL, *vertex, **vertexp, *apex;
+ coordT *center;
+ facetT *neighbor, **neighborp;
+ setT *vertices;
+ int dim= qh hull_dim;
+
+ if (qh DELAUNAY)
+ dim--;
+ if (facet->tricoplanar) {
+ if (!qh VERTEXneighbors || !facet->center) {
+ qh_fprintf(qh ferr, 6158, "qhull internal error (qh_nearvertex): qh.VERTEXneighbors and facet->center required for tricoplanar facets\n");
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ vertices= qh_settemp(qh TEMPsize);
+ apex= SETfirstt_(facet->vertices, vertexT);
+ center= facet->center;
+ FOREACHneighbor_(apex) {
+ if (neighbor->center == center) {
+ FOREACHvertex_(neighbor->vertices)
+ qh_setappend(&vertices, vertex);
+ }
+ }
+ }else
+ vertices= facet->vertices;
+ FOREACHvertex_(vertices) {
+ dist= qh_pointdist(vertex->point, point, -dim);
+ if (dist < bestdist) {
+ bestdist= dist;
+ bestvertex= vertex;
+ }
+ }
+ if (facet->tricoplanar)
+ qh_settempfree(&vertices);
+ *bestdistp= sqrt(bestdist);
+ if (!bestvertex) {
+ qh_fprintf(qh ferr, 6261, "qhull internal error (qh_nearvertex): did not find bestvertex for f%d p%d\n", facet->id, qh_pointid(point));
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ trace3((qh ferr, 3019, "qh_nearvertex: v%d dist %2.2g for f%d p%d\n",
+ bestvertex->id, *bestdistp, facet->id, qh_pointid(point))); /* bestvertex!=0 by QH2161 */
+ return bestvertex;
+} /* nearvertex */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="newhashtable">-</a>
+
+ qh_newhashtable( newsize )
+ returns size of qh.hash_table of at least newsize slots
+
+ notes:
+ assumes qh.hash_table is NULL
+ qh_HASHfactor determines the number of extra slots
+ size is not divisible by 2, 3, or 5
+*/
+int qh_newhashtable(int newsize) {
+ int size;
+
+ size= ((newsize+1)*qh_HASHfactor) | 0x1; /* odd number */
+ while (True) {
+ if (newsize<0 || size<0) {
+ qh_fprintf(qhmem.ferr, 6236, "qhull error (qh_newhashtable): negative request (%d) or size (%d). Did int overflow due to high-D?\n", newsize, size); /* WARN64 */
+ qh_errexit(qhmem_ERRmem, NULL, NULL);
+ }
+ if ((size%3) && (size%5))
+ break;
+ size += 2;
+ /* loop terminates because there is an infinite number of primes */
+ }
+ qh hash_table= qh_setnew(size);
+ qh_setzero(qh hash_table, 0, size);
+ return size;
+} /* newhashtable */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="newvertex">-</a>
+
+ qh_newvertex( point )
+ returns a new vertex for point
+*/
+vertexT *qh_newvertex(pointT *point) {
+ vertexT *vertex;
+
+ zinc_(Ztotvertices);
+ vertex= (vertexT *)qh_memalloc((int)sizeof(vertexT));
+ memset((char *) vertex, (size_t)0, sizeof(vertexT));
+ if (qh vertex_id == UINT_MAX) {
+ qh_memfree(vertex, (int)sizeof(vertexT));
+ qh_fprintf(qh ferr, 6159, "qhull error: more than 2^32 vertices. vertexT.id field overflows. Vertices would not be sorted correctly.\n");
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
+ if (qh vertex_id == qh tracevertex_id)
+ qh tracevertex= vertex;
+ vertex->id= qh vertex_id++;
+ vertex->point= point;
+ trace4((qh ferr, 4060, "qh_newvertex: vertex p%d(v%d) created\n", qh_pointid(vertex->point),
+ vertex->id));
+ return(vertex);
+} /* newvertex */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="nextridge3d">-</a>
+
+ qh_nextridge3d( atridge, facet, vertex )
+ return next ridge and vertex for a 3d facet
+ returns NULL on error
+ [for QhullFacet::nextRidge3d] Does not call qh_errexit nor access qh_qh.
+
+ notes:
+ in qh_ORIENTclock order
+ this is a O(n^2) implementation to trace all ridges
+ be sure to stop on any 2nd visit
+ same as QhullRidge::nextRidge3d
+ does not use qh_qh or qh_errexit [QhullFacet.cpp]
+
+ design:
+ for each ridge
+ exit if it is the ridge after atridge
+*/
+ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp) {
+ vertexT *atvertex, *vertex, *othervertex;
+ ridgeT *ridge, **ridgep;
+
+ if ((atridge->top == facet) ^ qh_ORIENTclock)
+ atvertex= SETsecondt_(atridge->vertices, vertexT);
+ else
+ atvertex= SETfirstt_(atridge->vertices, vertexT);
+ FOREACHridge_(facet->ridges) {
+ if (ridge == atridge)
+ continue;
+ if ((ridge->top == facet) ^ qh_ORIENTclock) {
+ othervertex= SETsecondt_(ridge->vertices, vertexT);
+ vertex= SETfirstt_(ridge->vertices, vertexT);
+ }else {
+ vertex= SETsecondt_(ridge->vertices, vertexT);
+ othervertex= SETfirstt_(ridge->vertices, vertexT);
+ }
+ if (vertex == atvertex) {
+ if (vertexp)
+ *vertexp= othervertex;
+ return ridge;
+ }
+ }
+ return NULL;
+} /* nextridge3d */
+#else /* qh_NOmerge */
+void qh_matchduplicates(facetT *atfacet, int atskip, int hashsize, int *hashcount) {
+}
+ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp) {
+
+ return NULL;
+}
+#endif /* qh_NOmerge */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="outcoplanar">-</a>
+
+ qh_outcoplanar()
+ move points from all facets' outsidesets to their coplanarsets
+
+ notes:
+ for post-processing under qh.NARROWhull
+
+ design:
+ for each facet
+ for each outside point for facet
+ partition point into coplanar set
+*/
+void qh_outcoplanar(void /* facet_list */) {
+ pointT *point, **pointp;
+ facetT *facet;
+ realT dist;
+
+ trace1((qh ferr, 1033, "qh_outcoplanar: move outsideset to coplanarset for qh NARROWhull\n"));
+ FORALLfacets {
+ FOREACHpoint_(facet->outsideset) {
+ qh num_outside--;
+ if (qh KEEPcoplanar || qh KEEPnearinside) {
+ qh_distplane(point, facet, &dist);
+ zinc_(Zpartition);
+ qh_partitioncoplanar(point, facet, &dist);
+ }
+ }
+ qh_setfree(&facet->outsideset);
+ }
+} /* outcoplanar */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="point">-</a>
+
+ qh_point( id )
+ return point for a point id, or NULL if unknown
+
+ alternative code:
+ return((pointT *)((unsigned long)qh.first_point
+ + (unsigned long)((id)*qh.normal_size)));
+*/
+pointT *qh_point(int id) {
+
+ if (id < 0)
+ return NULL;
+ if (id < qh num_points)
+ return qh first_point + id * qh hull_dim;
+ id -= qh num_points;
+ if (id < qh_setsize(qh other_points))
+ return SETelemt_(qh other_points, id, pointT);
+ return NULL;
+} /* point */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="point_add">-</a>
+
+ qh_point_add( set, point, elem )
+ stores elem at set[point.id]
+
+ returns:
+ access function for qh_pointfacet and qh_pointvertex
+
+ notes:
+ checks point.id
+*/
+void qh_point_add(setT *set, pointT *point, void *elem) {
+ int id, size;
+
+ SETreturnsize_(set, size);
+ if ((id= qh_pointid(point)) < 0)
+ qh_fprintf(qh ferr, 7067, "qhull internal warning (point_add): unknown point %p id %d\n",
+ point, id);
+ else if (id >= size) {
+ qh_fprintf(qh ferr, 6160, "qhull internal errror(point_add): point p%d is out of bounds(%d)\n",
+ id, size);
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }else
+ SETelem_(set, id)= elem;
+} /* point_add */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="pointfacet">-</a>
+
+ qh_pointfacet()
+ return temporary set of facet for each point
+ the set is indexed by point id
+
+ notes:
+ vertices assigned to one of the facets
+ coplanarset assigned to the facet
+ outside set assigned to the facet
+ NULL if no facet for point (inside)
+ includes qh.GOODpointp
+
+ access:
+ FOREACHfacet_i_(facets) { ... }
+ SETelem_(facets, i)
+
+ design:
+ for each facet
+ add each vertex
+ add each coplanar point
+ add each outside point
+*/
+setT *qh_pointfacet(void /*qh.facet_list*/) {
+ int numpoints= qh num_points + qh_setsize(qh other_points);
+ setT *facets;
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+ pointT *point, **pointp;
+
+ facets= qh_settemp(numpoints);
+ qh_setzero(facets, 0, numpoints);
+ qh vertex_visit++;
+ FORALLfacets {
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->visitid != qh vertex_visit) {
+ vertex->visitid= qh vertex_visit;
+ qh_point_add(facets, vertex->point, facet);
+ }
+ }
+ FOREACHpoint_(facet->coplanarset)
+ qh_point_add(facets, point, facet);
+ FOREACHpoint_(facet->outsideset)
+ qh_point_add(facets, point, facet);
+ }
+ return facets;
+} /* pointfacet */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="pointvertex">-</a>
+
+ qh_pointvertex( )
+ return temporary set of vertices indexed by point id
+ entry is NULL if no vertex for a point
+ this will include qh.GOODpointp
+
+ access:
+ FOREACHvertex_i_(vertices) { ... }
+ SETelem_(vertices, i)
+*/
+setT *qh_pointvertex(void /*qh.facet_list*/) {
+ int numpoints= qh num_points + qh_setsize(qh other_points);
+ setT *vertices;
+ vertexT *vertex;
+
+ vertices= qh_settemp(numpoints);
+ qh_setzero(vertices, 0, numpoints);
+ FORALLvertices
+ qh_point_add(vertices, vertex->point, vertex);
+ return vertices;
+} /* pointvertex */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="prependfacet">-</a>
+
+ qh_prependfacet( facet, facetlist )
+ prepend facet to the start of a facetlist
+
+ returns:
+ increments qh.numfacets
+ updates facetlist, qh.facet_list, facet_next
+
+ notes:
+ be careful of prepending since it can lose a pointer.
+ e.g., can lose _next by deleting and then prepending before _next
+*/
+void qh_prependfacet(facetT *facet, facetT **facetlist) {
+ facetT *prevfacet, *list;
+
+
+ trace4((qh ferr, 4061, "qh_prependfacet: prepend f%d before f%d\n",
+ facet->id, getid_(*facetlist)));
+ if (!*facetlist)
+ (*facetlist)= qh facet_tail;
+ list= *facetlist;
+ prevfacet= list->previous;
+ facet->previous= prevfacet;
+ if (prevfacet)
+ prevfacet->next= facet;
+ list->previous= facet;
+ facet->next= *facetlist;
+ if (qh facet_list == list) /* this may change *facetlist */
+ qh facet_list= facet;
+ if (qh facet_next == list)
+ qh facet_next= facet;
+ *facetlist= facet;
+ qh num_facets++;
+} /* prependfacet */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="printhashtable">-</a>
+
+ qh_printhashtable( fp )
+ print hash table to fp
+
+ notes:
+ not in I/O to avoid bringing io.c in
+
+ design:
+ for each hash entry
+ if defined
+ if unmatched or will merge (NULL, qh_MERGEridge, qh_DUPLICATEridge)
+ print entry and neighbors
+*/
+void qh_printhashtable(FILE *fp) {
+ facetT *facet, *neighbor;
+ int id, facet_i, facet_n, neighbor_i= 0, neighbor_n= 0;
+ vertexT *vertex, **vertexp;
+
+ FOREACHfacet_i_(qh hash_table) {
+ if (facet) {
+ FOREACHneighbor_i_(facet) {
+ if (!neighbor || neighbor == qh_MERGEridge || neighbor == qh_DUPLICATEridge)
+ break;
+ }
+ if (neighbor_i == neighbor_n)
+ continue;
+ qh_fprintf(fp, 9283, "hash %d f%d ", facet_i, facet->id);
+ FOREACHvertex_(facet->vertices)
+ qh_fprintf(fp, 9284, "v%d ", vertex->id);
+ qh_fprintf(fp, 9285, "\n neighbors:");
+ FOREACHneighbor_i_(facet) {
+ if (neighbor == qh_MERGEridge)
+ id= -3;
+ else if (neighbor == qh_DUPLICATEridge)
+ id= -2;
+ else
+ id= getid_(neighbor);
+ qh_fprintf(fp, 9286, " %d", id);
+ }
+ qh_fprintf(fp, 9287, "\n");
+ }
+ }
+} /* printhashtable */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="printlists">-</a>
+
+ qh_printlists( fp )
+ print out facet and vertex list for debugging (without 'f/v' tags)
+*/
+void qh_printlists(void) {
+ facetT *facet;
+ vertexT *vertex;
+ int count= 0;
+
+ qh_fprintf(qh ferr, 8108, "qh_printlists: facets:");
+ FORALLfacets {
+ if (++count % 100 == 0)
+ qh_fprintf(qh ferr, 8109, "\n ");
+ qh_fprintf(qh ferr, 8110, " %d", facet->id);
+ }
+ qh_fprintf(qh ferr, 8111, "\n new facets %d visible facets %d next facet for qh_addpoint %d\n vertices(new %d):",
+ getid_(qh newfacet_list), getid_(qh visible_list), getid_(qh facet_next),
+ getid_(qh newvertex_list));
+ count = 0;
+ FORALLvertices {
+ if (++count % 100 == 0)
+ qh_fprintf(qh ferr, 8112, "\n ");
+ qh_fprintf(qh ferr, 8113, " %d", vertex->id);
+ }
+ qh_fprintf(qh ferr, 8114, "\n");
+} /* printlists */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="resetlists">-</a>
+
+ qh_resetlists( stats, qh_RESETvisible )
+ reset newvertex_list, newfacet_list, visible_list
+ if stats,
+ maintains statistics
+
+ returns:
+ visible_list is empty if qh_deletevisible was called
+*/
+void qh_resetlists(boolT stats, boolT resetVisible /*qh.newvertex_list newfacet_list visible_list*/) {
+ vertexT *vertex;
+ facetT *newfacet, *visible;
+ int totnew=0, totver=0;
+
+ if (stats) {
+ FORALLvertex_(qh newvertex_list)
+ totver++;
+ FORALLnew_facets
+ totnew++;
+ zadd_(Zvisvertextot, totver);
+ zmax_(Zvisvertexmax, totver);
+ zadd_(Znewfacettot, totnew);
+ zmax_(Znewfacetmax, totnew);
+ }
+ FORALLvertex_(qh newvertex_list)
+ vertex->newlist= False;
+ qh newvertex_list= NULL;
+ FORALLnew_facets
+ newfacet->newfacet= False;
+ qh newfacet_list= NULL;
+ if (resetVisible) {
+ FORALLvisible_facets {
+ visible->f.replace= NULL;
+ visible->visible= False;
+ }
+ qh num_visible= 0;
+ }
+ qh visible_list= NULL; /* may still have visible facets via qh_triangulate */
+ qh NEWfacets= False;
+} /* resetlists */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="setvoronoi_all">-</a>
+
+ qh_setvoronoi_all()
+ compute Voronoi centers for all facets
+ includes upperDelaunay facets if qh.UPPERdelaunay ('Qu')
+
+ returns:
+ facet->center is the Voronoi center
+
+ notes:
+ this is unused/untested code
+ please email bradb@shore.net if this works ok for you
+
+ use:
+ FORALLvertices {...} to locate the vertex for a point.
+ FOREACHneighbor_(vertex) {...} to visit the Voronoi centers for a Voronoi cell.
+*/
+void qh_setvoronoi_all(void) {
+ facetT *facet;
+
+ qh_clearcenters(qh_ASvoronoi);
+ qh_vertexneighbors();
+
+ FORALLfacets {
+ if (!facet->normal || !facet->upperdelaunay || qh UPPERdelaunay) {
+ if (!facet->center)
+ facet->center= qh_facetcenter(facet->vertices);
+ }
+ }
+} /* setvoronoi_all */
+
+#ifndef qh_NOmerge
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="triangulate">-</a>
+
+ qh_triangulate()
+ triangulate non-simplicial facets on qh.facet_list,
+ if qh VORONOI, sets Voronoi centers of non-simplicial facets
+ nop if hasTriangulation
+
+ returns:
+ all facets simplicial
+ each tricoplanar facet has ->f.triowner == owner of ->center,normal,etc.
+
+ notes:
+ call after qh_check_output since may switch to Voronoi centers
+ Output may overwrite ->f.triowner with ->f.area
+*/
+void qh_triangulate(void /*qh.facet_list*/) {
+ facetT *facet, *nextfacet, *owner;
+ int onlygood= qh ONLYgood;
+ facetT *neighbor, *visible= NULL, *facet1, *facet2, *new_facet_list= NULL;
+ facetT *orig_neighbor= NULL, *otherfacet;
+ vertexT *new_vertex_list= NULL;
+ mergeT *merge;
+ mergeType mergetype;
+ int neighbor_i, neighbor_n;
+
+ if (qh hasTriangulation)
+ return;
+ trace1((qh ferr, 1034, "qh_triangulate: triangulate non-simplicial facets\n"));
+ if (qh hull_dim == 2)
+ return;
+ if (qh VORONOI) { /* otherwise lose Voronoi centers [could rebuild vertex set from tricoplanar] */
+ qh_clearcenters(qh_ASvoronoi);
+ qh_vertexneighbors();
+ }
+ qh ONLYgood= False; /* for makenew_nonsimplicial */
+ qh visit_id++;
+ qh NEWfacets= True;
+ qh degen_mergeset= qh_settemp(qh TEMPsize);
+ qh newvertex_list= qh vertex_tail;
+ for (facet= qh facet_list; facet && facet->next; facet= nextfacet) { /* non-simplicial facets moved to end */
+ nextfacet= facet->next;
+ if (facet->visible || facet->simplicial)
+ continue;
+ /* triangulate all non-simplicial facets, otherwise merging does not work, e.g., RBOX c P-0.1 P+0.1 P+0.1 D3 | QHULL d Qt Tv */
+ if (!new_facet_list)
+ new_facet_list= facet; /* will be moved to end */
+ qh_triangulate_facet(facet, &new_vertex_list);
+ }
+ trace2((qh ferr, 2047, "qh_triangulate: delete null facets from f%d -- apex same as second vertex\n", getid_(new_facet_list)));
+ for (facet= new_facet_list; facet && facet->next; facet= nextfacet) { /* null facets moved to end */
+ nextfacet= facet->next;
+ if (facet->visible)
+ continue;
+ if (facet->ridges) {
+ if (qh_setsize(facet->ridges) > 0) {
+ qh_fprintf(qh ferr, 6161, "qhull error (qh_triangulate): ridges still defined for f%d\n", facet->id);
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ qh_setfree(&facet->ridges);
+ }
+ if (SETfirst_(facet->vertices) == SETsecond_(facet->vertices)) {
+ zinc_(Ztrinull);
+ qh_triangulate_null(facet);
+ }
+ }
+ trace2((qh ferr, 2048, "qh_triangulate: delete %d or more mirror facets -- same vertices and neighbors\n", qh_setsize(qh degen_mergeset)));
+ qh visible_list= qh facet_tail;
+ while ((merge= (mergeT*)qh_setdellast(qh degen_mergeset))) {
+ facet1= merge->facet1;
+ facet2= merge->facet2;
+ mergetype= merge->type;
+ qh_memfree(merge, (int)sizeof(mergeT));
+ if (mergetype == MRGmirror) {
+ zinc_(Ztrimirror);
+ qh_triangulate_mirror(facet1, facet2);
+ }
+ }
+ qh_settempfree(&qh degen_mergeset);
+ trace2((qh ferr, 2049, "qh_triangulate: update neighbor lists for vertices from v%d\n", getid_(new_vertex_list)));
+ qh newvertex_list= new_vertex_list; /* all vertices of new facets */
+ qh visible_list= NULL;
+ qh_updatevertices(/*qh.newvertex_list, empty newfacet_list and visible_list*/);
+ qh_resetlists(False, !qh_RESETvisible /*qh.newvertex_list, empty newfacet_list and visible_list*/);
+
+ trace2((qh ferr, 2050, "qh_triangulate: identify degenerate tricoplanar facets from f%d\n", getid_(new_facet_list)));
+ trace2((qh ferr, 2051, "qh_triangulate: and replace facet->f.triowner with tricoplanar facets that own center, normal, etc.\n"));
+ FORALLfacet_(new_facet_list) {
+ if (facet->tricoplanar && !facet->visible) {
+ FOREACHneighbor_i_(facet) {
+ if (neighbor_i == 0) { /* first iteration */
+ if (neighbor->tricoplanar)
+ orig_neighbor= neighbor->f.triowner;
+ else
+ orig_neighbor= neighbor;
+ }else {
+ if (neighbor->tricoplanar)
+ otherfacet= neighbor->f.triowner;
+ else
+ otherfacet= neighbor;
+ if (orig_neighbor == otherfacet) {
+ zinc_(Ztridegen);
+ facet->degenerate= True;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ trace2((qh ferr, 2052, "qh_triangulate: delete visible facets -- non-simplicial, null, and mirrored facets\n"));
+ owner= NULL;
+ visible= NULL;
+ for (facet= new_facet_list; facet && facet->next; facet= nextfacet) { /* may delete facet */
+ nextfacet= facet->next;
+ if (facet->visible) {
+ if (facet->tricoplanar) { /* a null or mirrored facet */
+ qh_delfacet(facet);
+ qh num_visible--;
+ }else { /* a non-simplicial facet followed by its tricoplanars */
+ if (visible && !owner) {
+ /* RBOX 200 s D5 t1001471447 | QHULL Qt C-0.01 Qx Qc Tv Qt -- f4483 had 6 vertices/neighbors and 8 ridges */
+ trace2((qh ferr, 2053, "qh_triangulate: all tricoplanar facets degenerate for non-simplicial facet f%d\n",
+ visible->id));
+ qh_delfacet(visible);
+ qh num_visible--;
+ }
+ visible= facet;
+ owner= NULL;
+ }
+ }else if (facet->tricoplanar) {
+ if (facet->f.triowner != visible || visible==NULL) {
+ qh_fprintf(qh ferr, 6162, "qhull error (qh_triangulate): tricoplanar facet f%d not owned by its visible, non-simplicial facet f%d\n", facet->id, getid_(visible));
+ qh_errexit2(qh_ERRqhull, facet, visible);
+ }
+ if (owner)
+ facet->f.triowner= owner;
+ else if (!facet->degenerate) {
+ owner= facet;
+ nextfacet= visible->next; /* rescan tricoplanar facets with owner, visible!=0 by QH6162 */
+ facet->keepcentrum= True; /* one facet owns ->normal, etc. */
+ facet->coplanarset= visible->coplanarset;
+ facet->outsideset= visible->outsideset;
+ visible->coplanarset= NULL;
+ visible->outsideset= NULL;
+ if (!qh TRInormals) { /* center and normal copied to tricoplanar facets */
+ visible->center= NULL;
+ visible->normal= NULL;
+ }
+ qh_delfacet(visible);
+ qh num_visible--;
+ }
+ }
+ }
+ if (visible && !owner) {
+ trace2((qh ferr, 2054, "qh_triangulate: all tricoplanar facets degenerate for last non-simplicial facet f%d\n",
+ visible->id));
+ qh_delfacet(visible);
+ qh num_visible--;
+ }
+ qh NEWfacets= False;
+ qh ONLYgood= onlygood; /* restore value */
+ if (qh CHECKfrequently)
+ qh_checkpolygon(qh facet_list);
+ qh hasTriangulation= True;
+} /* triangulate */
+
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="triangulate_facet">-</a>
+
+ qh_triangulate_facet(qh, facetA, &firstVertex )
+ triangulate a non-simplicial facet
+ if qh.CENTERtype=qh_ASvoronoi, sets its Voronoi center
+ returns:
+ qh.newfacet_list == simplicial facets
+ facet->tricoplanar set and ->keepcentrum false
+ facet->degenerate set if duplicated apex
+ facet->f.trivisible set to facetA
+ facet->center copied from facetA (created if qh_ASvoronoi)
+ qh_eachvoronoi, qh_detvridge, qh_detvridge3 assume centers copied
+ facet->normal,offset,maxoutside copied from facetA
+
+ notes:
+ only called by qh_triangulate
+ qh_makenew_nonsimplicial uses neighbor->seen for the same
+ if qh.TRInormals, newfacet->normal will need qh_free
+ if qh.TRInormals and qh_AScentrum, newfacet->center will need qh_free
+ keepcentrum is also set on Zwidefacet in qh_mergefacet
+ freed by qh_clearcenters
+
+ see also:
+ qh_addpoint() -- add a point
+ qh_makenewfacets() -- construct a cone of facets for a new vertex
+
+ design:
+ if qh_ASvoronoi,
+ compute Voronoi center (facet->center)
+ select first vertex (highest ID to preserve ID ordering of ->vertices)
+ triangulate from vertex to ridges
+ copy facet->center, normal, offset
+ update vertex neighbors
+*/
+void qh_triangulate_facet(facetT *facetA, vertexT **first_vertex) {
+ facetT *newfacet;
+ facetT *neighbor, **neighborp;
+ vertexT *apex;
+ int numnew=0;
+
+ trace3((qh ferr, 3020, "qh_triangulate_facet: triangulate facet f%d\n", facetA->id));
+
+ if (qh IStracing >= 4)
+ qh_printfacet(qh ferr, facetA);
+ FOREACHneighbor_(facetA) {
+ neighbor->seen= False;
+ neighbor->coplanar= False;
+ }
+ if (qh CENTERtype == qh_ASvoronoi && !facetA->center /* matches upperdelaunay in qh_setfacetplane() */
+ && fabs_(facetA->normal[qh hull_dim -1]) >= qh ANGLEround * qh_ZEROdelaunay) {
+ facetA->center= qh_facetcenter(facetA->vertices);
+ }
+ qh_willdelete(facetA, NULL);
+ qh newfacet_list= qh facet_tail;
+ facetA->visitid= qh visit_id;
+ apex= SETfirstt_(facetA->vertices, vertexT);
+ qh_makenew_nonsimplicial(facetA, apex, &numnew);
+ SETfirst_(facetA->neighbors)= NULL;
+ FORALLnew_facets {
+ newfacet->tricoplanar= True;
+ newfacet->f.trivisible= facetA;
+ newfacet->degenerate= False;
+ newfacet->upperdelaunay= facetA->upperdelaunay;
+ newfacet->good= facetA->good;
+ if (qh TRInormals) { /* 'Q11' triangulate duplicates ->normal and ->center */
+ newfacet->keepcentrum= True;
+ if(facetA->normal){
+ newfacet->normal= qh_memalloc(qh normal_size);
+ memcpy((char *)newfacet->normal, facetA->normal, qh normal_size);
+ }
+ if (qh CENTERtype == qh_AScentrum)
+ newfacet->center= qh_getcentrum(newfacet);
+ else if (qh CENTERtype == qh_ASvoronoi && facetA->center){
+ newfacet->center= qh_memalloc(qh center_size);
+ memcpy((char *)newfacet->center, facetA->center, qh center_size);
+ }
+ }else {
+ newfacet->keepcentrum= False;
+ /* one facet will have keepcentrum=True at end of qh_triangulate */
+ newfacet->normal= facetA->normal;
+ newfacet->center= facetA->center;
+ }
+ newfacet->offset= facetA->offset;
+#if qh_MAXoutside
+ newfacet->maxoutside= facetA->maxoutside;
+#endif
+ }
+ qh_matchnewfacets(/*qh.newfacet_list*/);
+ zinc_(Ztricoplanar);
+ zadd_(Ztricoplanartot, numnew);
+ zmax_(Ztricoplanarmax, numnew);
+ qh visible_list= NULL;
+ if (!(*first_vertex))
+ (*first_vertex)= qh newvertex_list;
+ qh newvertex_list= NULL;
+ qh_updatevertices(/*qh.newfacet_list, qh.empty visible_list and qh.newvertex_list*/);
+ qh_resetlists(False, !qh_RESETvisible /*qh.newfacet_list, qh.empty visible_list and qh.newvertex_list*/);
+} /* triangulate_facet */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="triangulate_link">-</a>
+
+ qh_triangulate_link(oldfacetA, facetA, oldfacetB, facetB)
+ relink facetA to facetB via oldfacets
+ returns:
+ adds mirror facets to qh degen_mergeset (4-d and up only)
+ design:
+ if they are already neighbors, the opposing neighbors become MRGmirror facets
+*/
+void qh_triangulate_link(facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB) {
+ int errmirror= False;
+
+ trace3((qh ferr, 3021, "qh_triangulate_link: relink old facets f%d and f%d between neighbors f%d and f%d\n",
+ oldfacetA->id, oldfacetB->id, facetA->id, facetB->id));
+ if (qh_setin(facetA->neighbors, facetB)) {
+ if (!qh_setin(facetB->neighbors, facetA))
+ errmirror= True;
+ else
+ qh_appendmergeset(facetA, facetB, MRGmirror, NULL);
+ }else if (qh_setin(facetB->neighbors, facetA))
+ errmirror= True;
+ if (errmirror) {
+ qh_fprintf(qh ferr, 6163, "qhull error (qh_triangulate_link): mirror facets f%d and f%d do not match for old facets f%d and f%d\n",
+ facetA->id, facetB->id, oldfacetA->id, oldfacetB->id);
+ qh_errexit2(qh_ERRqhull, facetA, facetB);
+ }
+ qh_setreplace(facetB->neighbors, oldfacetB, facetA);
+ qh_setreplace(facetA->neighbors, oldfacetA, facetB);
+} /* triangulate_link */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="triangulate_mirror">-</a>
+
+ qh_triangulate_mirror(facetA, facetB)
+ delete mirrored facets from qh_triangulate_null() and qh_triangulate_mirror
+ a mirrored facet shares the same vertices of a logical ridge
+ design:
+ since a null facet duplicates the first two vertices, the opposing neighbors absorb the null facet
+ if they are already neighbors, the opposing neighbors become MRGmirror facets
+*/
+void qh_triangulate_mirror(facetT *facetA, facetT *facetB) {
+ facetT *neighbor, *neighborB;
+ int neighbor_i, neighbor_n;
+
+ trace3((qh ferr, 3022, "qh_triangulate_mirror: delete mirrored facets f%d and f%d\n",
+ facetA->id, facetB->id));
+ FOREACHneighbor_i_(facetA) {
+ neighborB= SETelemt_(facetB->neighbors, neighbor_i, facetT);
+ if (neighbor == neighborB)
+ continue; /* occurs twice */
+ qh_triangulate_link(facetA, neighbor, facetB, neighborB);
+ }
+ qh_willdelete(facetA, NULL);
+ qh_willdelete(facetB, NULL);
+} /* triangulate_mirror */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="triangulate_null">-</a>
+
+ qh_triangulate_null(facetA)
+ remove null facetA from qh_triangulate_facet()
+ a null facet has vertex #1 (apex) == vertex #2
+ returns:
+ adds facetA to ->visible for deletion after qh_updatevertices
+ qh degen_mergeset contains mirror facets (4-d and up only)
+ design:
+ since a null facet duplicates the first two vertices, the opposing neighbors absorb the null facet
+ if they are already neighbors, the opposing neighbors become MRGmirror facets
+*/
+void qh_triangulate_null(facetT *facetA) {
+ facetT *neighbor, *otherfacet;
+
+ trace3((qh ferr, 3023, "qh_triangulate_null: delete null facet f%d\n", facetA->id));
+ neighbor= SETfirstt_(facetA->neighbors, facetT);
+ otherfacet= SETsecondt_(facetA->neighbors, facetT);
+ qh_triangulate_link(facetA, neighbor, facetA, otherfacet);
+ qh_willdelete(facetA, NULL);
+} /* triangulate_null */
+
+#else /* qh_NOmerge */
+void qh_triangulate(void) {
+}
+#endif /* qh_NOmerge */
+
+ /*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="vertexintersect">-</a>
+
+ qh_vertexintersect( vertexsetA, vertexsetB )
+ intersects two vertex sets (inverse id ordered)
+ vertexsetA is a temporary set at the top of qhmem.tempstack
+
+ returns:
+ replaces vertexsetA with the intersection
+
+ notes:
+ could overwrite vertexsetA if currently too slow
+*/
+void qh_vertexintersect(setT **vertexsetA,setT *vertexsetB) {
+ setT *intersection;
+
+ intersection= qh_vertexintersect_new(*vertexsetA, vertexsetB);
+ qh_settempfree(vertexsetA);
+ *vertexsetA= intersection;
+ qh_settemppush(intersection);
+} /* vertexintersect */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="vertexintersect_new">-</a>
+
+ qh_vertexintersect_new( )
+ intersects two vertex sets (inverse id ordered)
+
+ returns:
+ a new set
+*/
+setT *qh_vertexintersect_new(setT *vertexsetA,setT *vertexsetB) {
+ setT *intersection= qh_setnew(qh hull_dim - 1);
+ vertexT **vertexA= SETaddr_(vertexsetA, vertexT);
+ vertexT **vertexB= SETaddr_(vertexsetB, vertexT);
+
+ while (*vertexA && *vertexB) {
+ if (*vertexA == *vertexB) {
+ qh_setappend(&intersection, *vertexA);
+ vertexA++; vertexB++;
+ }else {
+ if ((*vertexA)->id > (*vertexB)->id)
+ vertexA++;
+ else
+ vertexB++;
+ }
+ }
+ return intersection;
+} /* vertexintersect_new */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="vertexneighbors">-</a>
+
+ qh_vertexneighbors()
+ for each vertex in qh.facet_list,
+ determine its neighboring facets
+
+ returns:
+ sets qh.VERTEXneighbors
+ nop if qh.VERTEXneighbors already set
+ qh_addpoint() will maintain them
+
+ notes:
+ assumes all vertex->neighbors are NULL
+
+ design:
+ for each facet
+ for each vertex
+ append facet to vertex->neighbors
+*/
+void qh_vertexneighbors(void /*qh.facet_list*/) {
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+
+ if (qh VERTEXneighbors)
+ return;
+ trace1((qh ferr, 1035, "qh_vertexneighbors: determining neighboring facets for each vertex\n"));
+ qh vertex_visit++;
+ FORALLfacets {
+ if (facet->visible)
+ continue;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->visitid != qh vertex_visit) {
+ vertex->visitid= qh vertex_visit;
+ vertex->neighbors= qh_setnew(qh hull_dim);
+ }
+ qh_setappend(&vertex->neighbors, facet);
+ }
+ }
+ qh VERTEXneighbors= True;
+} /* vertexneighbors */
+
+/*-<a href="qh-poly.htm#TOC"
+ >-------------------------------</a><a name="vertexsubset">-</a>
+
+ qh_vertexsubset( vertexsetA, vertexsetB )
+ returns True if vertexsetA is a subset of vertexsetB
+ assumes vertexsets are sorted
+
+ note:
+ empty set is a subset of any other set
+*/
+boolT qh_vertexsubset(setT *vertexsetA, setT *vertexsetB) {
+ vertexT **vertexA= (vertexT **) SETaddr_(vertexsetA, vertexT);
+ vertexT **vertexB= (vertexT **) SETaddr_(vertexsetB, vertexT);
+
+ while (True) {
+ if (!*vertexA)
+ return True;
+ if (!*vertexB)
+ return False;
+ if ((*vertexA)->id > (*vertexB)->id)
+ return False;
+ if (*vertexA == *vertexB)
+ vertexA++;
+ vertexB++;
+ }
+ return False; /* avoid warnings */
+} /* vertexsubset */
diff --git a/xs/src/qhull/src/libqhull/qh-geom.htm b/xs/src/qhull/src/libqhull/qh-geom.htm
new file mode 100644
index 000000000..6dc7465eb
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qh-geom.htm
@@ -0,0 +1,295 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>geom.c, geom2.c -- geometric and floating point routines</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm#TOC">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
+&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
+&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
+&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
+&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+</p>
+
+<hr>
+<!-- Main text of document. -->
+
+<h2>geom.c, geom2.c, random.c -- geometric and floating point routines</h2>
+<blockquote>
+<p>Geometrically, a vertex is a point with <em>d</em> coordinates
+and a facet is a halfspace. A <em>halfspace</em> is defined by an
+oriented hyperplane through the facet's vertices. A <em>hyperplane</em>
+is defined by <em>d</em> normalized coefficients and an offset. A
+point is <em>above</em> a facet if its distance to the facet is
+positive.</p>
+
+<p>Qhull uses floating point coordinates for input points,
+vertices, halfspace equations, centrums, and an interior point.</p>
+
+<p>Qhull may be configured for single precision or double
+precision floating point arithmetic (see <a href="user.h#realT">realT</a>
+). </p>
+
+<p>Each floating point operation may incur round-off error (see
+<a href="qh-merge.htm#TOC">Merge</a>). The maximum error for distance
+computations is determined at initialization. The roundoff error
+in halfspace computation is accounted for by computing the
+distance from vertices to the halfspace. </p>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <b>Geom</b>
+<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a> &#149;
+<a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a> &#149;
+<a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a> &#149;
+<a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a> &#149;
+<a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a> </p>
+
+<h3>Index to <a href="geom.c">geom.c</a>,
+<a href="geom2.c">geom2.c</a>, <a href="geom.h">geom.h</a>,
+<a href="random.c">random.c</a>, <a href="random.h">random.h</a>
+</h3>
+
+<ul>
+<li><a href="#gtype">geometric data types and constants</a> </li>
+<li><a href="#gmacro">mathematical macros</a>
+</li>
+<li><a href="#gmath">mathematical functions</a> </li>
+<li><a href="#gcomp">computational geometry functions</a> </li>
+<li><a href="#gpoint">point array functions</a> </li>
+<li><a href="#gfacet">geometric facet functions</a> </li>
+<li><a href="#ground">geometric roundoff functions</a></li>
+</ul>
+
+<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gtype">geometric data types
+and constants</a></h3>
+
+<ul>
+<li><a href="libqhull.h#coordT">coordT</a> coordinates and
+coefficients are stored as realT</li>
+<li><a href="libqhull.h#pointT">pointT</a> a point is an array
+of <tt>DIM3</tt> coordinates </li>
+</ul>
+
+<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gmacro">mathematical macros</a></h3>
+
+<ul>
+<li><a href="geom.h#fabs_">fabs_</a> returns the absolute
+value of a </li>
+<li><a href="geom.h#fmax_">fmax_</a> returns the maximum
+value of a and b </li>
+<li><a href="geom.h#fmin_">fmin_</a> returns the minimum
+value of a and b </li>
+<li><a href="geom.h#maximize_">maximize_</a> maximize a value
+</li>
+<li><a href="geom.h#minimize_">minimize_</a> minimize a value
+</li>
+<li><a href="geom.h#det2_">det2_</a> compute a 2-d
+determinate </li>
+<li><a href="geom.h#det3_">det3_</a> compute a 3-d
+determinate </li>
+<li><a href="geom.h#dX">dX, dY, dZ</a> compute the difference
+between two coordinates </li>
+</ul>
+
+<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gmath">mathematical functions</a></h3>
+
+<ul>
+<li><a href="geom.c#backnormal">qh_backnormal</a> solve for
+normal using back substitution </li>
+<li><a href="geom2.c#crossproduct">qh_crossproduct</a>
+compute the cross product of two 3-d vectors </li>
+<li><a href="geom2.c#determinant">qh_determinant</a> compute
+the determinant of a square matrix </li>
+<li><a href="geom.c#gausselim">qh_gausselim</a> Gaussian
+elimination with partial pivoting </li>
+<li><a href="geom2.c#gram_schmidt">qh_gram_schmidt</a>
+implements Gram-Schmidt orthogonalization by rows </li>
+<li><a href="geom2.c#maxabsval">qh_maxabsval</a> return max
+absolute value of a vector </li>
+<li><a href="geom2.c#minabsval">qh_minabsval</a> return min
+absolute value of a dim vector </li>
+<li><a href="geom2.c#mindiff">qh_mindiff</a> return index of
+min absolute difference of two vectors </li>
+<li><a href="geom.c#normalize">qh_normalize</a> normalize a
+vector </li>
+<li><a href="geom.c#normalize2">qh_normalize2</a> normalize a
+vector and report if too small </li>
+<li><a href="geom2.c#printmatrix">qh_printmatrix</a> print
+matrix given by row vectors </li>
+<li><a href="random.c#rand">qh_rand/srand</a> generate random
+numbers </li>
+<li><a href="random.c#randomfactor">qh_randomfactor</a> return
+a random factor near 1.0 </li>
+<li><a href="random.c#randommatrix">qh_randommatrix</a>
+generate a random dimXdim matrix in range (-1,1) </li>
+</ul>
+
+<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gcomp">computational geometry functions</a></h3>
+
+<ul>
+<li><a href="geom2.c#detsimplex">qh_detsimplex</a> compute
+determinate of a simplex of points </li>
+<li><a href="io.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
+<li><a href="geom2.c#distnorm">qh_distnorm</a> compute
+distance from point to hyperplane as defined by normal and offset</li>
+<li><a href="geom2.c#facetarea_simplex">qh_facetarea_simplex</a>
+return area of a simplex</li>
+<li><a href="geom.c#getangle">qh_getangle</a> return cosine
+of angle (i.e., dot product) </li>
+<li><a href="geom.c#getcenter">qh_getcenter</a> return
+arithmetic center for a set of vertices </li>
+<li><a href="geom2.c#pointdist">qh_pointdist</a> return
+distance between two points </li>
+<li><a href="geom2.c#rotatepoints">qh_rotatepoints</a> rotate
+numpoints points by a row matrix </li>
+<li><a href="geom2.c#sethalfspace">qh_sethalfspace</a> set
+coords to dual of halfspace relative to an interior point </li>
+<li><a href="geom.c#sethyperplane_det">qh_sethyperplane_det</a>
+return hyperplane for oriented simplex using determinates
+</li>
+<li><a href="geom.c#sethyperplane_gauss">qh_sethyperplane_gauss</a>
+return hyperplane for oriented simplex using Gaussian
+elimination </li>
+<li><a href="geom2.c#voronoi_center">qh_voronoi_center</a>
+return Voronoi center for a set of points </li>
+</ul>
+
+<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gpoint">point array functions</a></h3>
+<ul>
+<li><a href="geom2.c#copypoints">qh_copypoints</a> return
+malloc'd copy of points</li>
+<li><a href="geom2.c#joggleinput">qh_joggleinput</a> joggle
+input points by qh.JOGGLEmax </li>
+<li><a href="geom2.c#maxmin">qh_maxmin</a> return max/min
+points for each dimension</li>
+<li><a href="geom2.c#maxsimplex">qh_maxsimplex</a> determines
+maximum simplex for a set of points </li>
+<li><a href="geom2.c#printpoints">qh_printpoints</a> print ids for a
+set of points </li>
+<li><a href="geom2.c#projectinput">qh_projectinput</a> project
+input using qh DELAUNAY and qh low_bound/high_bound </li>
+<li><a href="geom2.c#projectpoints">qh_projectpoints</a>
+project points along one or more dimensions </li>
+<li><a href="geom2.c#rotateinput">qh_rotateinput</a> rotate
+input points using row matrix </li>
+<li><a href="geom2.c#scaleinput">qh_scaleinput</a> scale
+input points using qh low_bound/high_bound </li>
+<li><a href="geom2.c#scalelast">qh_scalelast</a> scale last
+coordinate to [0,m] for Delaunay triangulations </li>
+<li><a href="geom2.c#scalepoints">qh_scalepoints</a> scale
+points to new lowbound and highbound </li>
+<li><a href="geom2.c#setdelaunay">qh_setdelaunay</a> project
+points to paraboloid for Delaunay triangulation </li>
+<li><a href="geom2.c#sethalfspace_all">qh_sethalfspace_all</a>
+generate dual for halfspace intersection with interior
+point </li>
+</ul>
+
+<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="gfacet">geometric facet functions</a></h3>
+<ul>
+<li><a href="geom.c#distplane">qh_distplane</a> return
+distance from point to facet </li>
+<li><a href="geom2.c#facetarea">qh_facetarea</a> return area
+of a facet </li>
+<li><a href="geom2.c#facetcenter">qh_facetcenter</a> return
+Voronoi center for a facet's vertices </li>
+<li><a href="geom.c#findbest">qh_findbest</a> find visible
+facet or best facet for a point </li>
+<li><a href="geom.c#findbesthorizon">qh_findbesthorizon</a>
+update best new facet with horizon facets</li>
+<li><a href="geom.c#findbestnew">qh_findbestnew</a> find best
+new facet for point </li>
+<li><a href="geom2.c#getarea">qh_getarea</a> get area of all
+facets in facetlist, collect statistics </li>
+<li><a href="geom.c#getcentrum">qh_getcentrum</a> return
+centrum for a facet </li>
+<li><a href="geom.c#getdistance">qh_getdistance</a> returns
+the max and min distance of a facet's vertices to a
+neighboring facet</li>
+<li><a href="geom2.c#findgooddist">qh_findgooddist</a> find
+best good facet visible for point from facet </li>
+<li><a href="geom2.c#inthresholds">qh_inthresholds</a> return
+True if facet normal within 'Pdn' and 'PDn'</li>
+<li><a href="geom2.c#orientoutside">qh_orientoutside</a>
+orient facet so that <tt>qh.interior_point</tt> is inside</li>
+<li><a href="geom.c#projectpoint">qh_projectpoint</a> project
+point onto a facet </li>
+<li><a href="geom.c#setfacetplane">qh_setfacetplane</a> sets
+the hyperplane for a facet </li>
+<li><a href="geom2.c#sharpnewfacets">qh_sharpnewfacets</a> true
+if new facets contains a sharp corner</li>
+</ul>
+
+<h3><a href="qh-geom.htm#TOC">&#187;</a><a name="ground">geometric roundoff functions</a></h3>
+<ul>
+<li><a href="geom2.c#detjoggle">qh_detjoggle</a> determine
+default joggle for points and distance roundoff error</li>
+<li><a href="geom2.c#detroundoff">qh_detroundoff</a>
+determine maximum roundoff error and other precision constants</li>
+<li><a href="geom2.c#distround">qh_distround</a> compute
+maximum roundoff error due to a distance computation to a
+normalized hyperplane</li>
+<li><a href="geom2.c#divzero">qh_divzero</a> divide by a
+number that is nearly zero </li>
+<li><a href="geom2.c#maxouter">qh_maxouter</a> return maximum outer
+plane</li>
+<li><a href="geom2.c#outerinner">qh_outerinner</a> return actual
+outer and inner planes
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
+<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
+&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
+&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
+&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
+&#149; <a href="qh-user.htm">User</a><br>
+
+
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull/qh-globa.htm b/xs/src/qhull/src/libqhull/qh-globa.htm
new file mode 100644
index 000000000..c87508b66
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qh-globa.htm
@@ -0,0 +1,165 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>global.c -- global variables and their functions</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm#TOC">Global</a>
+&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
+&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
+&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
+&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+</p>
+
+<hr>
+<!-- Main text of document. -->
+
+<h2>global.c -- global variables and their functions</h2>
+<blockquote>
+<p>Qhull uses a global data structure, <tt>qh</tt>, to store
+globally defined constants, lists, sets, and variables. This
+allows multiple instances of Qhull to execute at the same time.
+The structure may be statically allocated or
+dynamically allocated with malloc(). See
+<a href="user.h#QHpointer">QHpointer</a>.
+</p>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <b>Global</b> &#149;
+<a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a> &#149;
+<a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a> &#149;
+<a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a> &#149;
+<a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a> </p>
+
+<h3>Index to <a href="global.c">global.c</a> and
+<a href="libqhull.h">libqhull.h</a></h3>
+
+<ul>
+<li><a href="#ovar">Qhull's global variables</a> </li>
+<li><a href="#ofunc">Global variable and initialization
+routines</a> </li>
+</ul>
+
+<h3><a href="qh-globa.htm#TOC">&#187;</a><a name="ovar">Qhull's global
+variables</a></h3>
+
+<ul>
+<li><a href=global.c#qh_version>qh_version</a> version string
+<li><a href="libqhull.h#qh">qh</a> all global variables for
+qhull are in <tt>qh,qhmem</tt>, and <tt>qhstat</tt></li>
+<li><a href="libqhull_r.h#qh">QHULL_LIB_CHECK</a> Check for compatible library</li>
+<li><a href="libqhull.h#qh-const">qh constants</a> configuration
+flags and constants for Qhull </li>
+<li><a href="libqhull.h#qh-prec">qh precision constants</a>
+precision constants for Qhull </li>
+<li><a href="libqhull.h#qh-codetern">qh internal constants</a>
+internal constants for Qhull </li>
+<li><a href="libqhull.h#qh-lists">qh facet and vertex lists</a>
+lists of facets and vertices </li>
+<li><a href="libqhull.h#qh-var">qh global variables</a> minimum
+and maximum distances, next visit ids, several flags, and
+other global variables. </li>
+<li><a href="libqhull.h#qh-set">qh global sets</a> global sets
+for merging, hashing, input, etc. </li>
+<li><a href="libqhull.h#qh-buf">qh global buffers</a> buffers
+for matrix operations and input </li>
+<li><a href="libqhull.h#qh-static">qh static variables</a>
+static variables for individual functions </li>
+</ul>
+
+<h3><a href="qh-globa.htm#TOC">&#187;</a><a name="ofunc">Global variable and
+initialization routines</a></h3>
+
+<ul>
+<li><a href="global.c#appendprint">qh_appendprint</a> append
+output format to <tt>qh.PRINTout</tt> </li>
+<li><a href="global.c#freebuffers">qh_freebuffers</a> free
+global memory buffers </li>
+<li><a href="global.c#freeqhull">qh_freeqhull</a> free memory
+used by qhull </li>
+<li><a href="global.c#init_A">qh_init_A</a> called before
+error handling initialized </li>
+<li><a href="global.c#init_B">qh_init_B</a> called after
+points are defined </li>
+<li><a href="global.c#init_qhull_command">qh_init_qhull_command</a>
+build <tt>qh.qhull_command</tt> from <tt>argc/argv</tt></li>
+<li><a href="global.c#initflags">qh_initflags</a> set flags
+and constants from command line </li>
+<li><a href="global.c#initqhull_buffers">qh_initqhull_buffers</a>
+initialize global memory buffers </li>
+<li><a href="global.c#initqhull_globals">qh_initqhull_globals</a>
+initialize global variables </li>
+<li><a href="global.c#initqhull_mem">qh_initqhull_mem</a>
+initialize Qhull memory management </li>
+<li><a href="global.c#initqhull_start">qh_initqhull_start</a>
+allocate qh_qh and call qh_initqhull_start2()
+<li><a href="global.c#initqhull_start2">qh_initqhull_start2</a>
+initialize default values at Qhull startup </li>
+<li><a href="global.c#initthresholds">qh_initthresholds</a>
+initialize 'Pdn' and 'PDn' thresholds </li>
+<li><a href="global.c#lib_check">qh_lib_check</a> check for compatible Qhull library. Invoked by QHULL_LIB_CHECK at start of each program.</li>
+<li><a href="global.c#option">qh_option</a> append option
+description to <tt>qh.global_options</tt> </li>
+<li><a href="global.c#restore_qhull">qh_restore_qhull</a>
+restores a previously saved qhull </li>
+<li><a href="global.c#save_qhull">qh_save_qhull</a> saves
+qhull for a later qh_restore_qhull() </li>
+<li><a href="global.c#strtol">qh_strtol</a> duplicates
+strtod() and strtol() </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
+<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
+&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
+&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
+&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
+&#149; <a href="qh-user.htm">User</a><br>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull/qh-io.htm b/xs/src/qhull/src/libqhull/qh-io.htm
new file mode 100644
index 000000000..5cb591d87
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qh-io.htm
@@ -0,0 +1,305 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>io.c -- input and output operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
+&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
+&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
+&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
+&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+</p>
+<hr>
+
+<h2>io.c -- input and output operations</h2>
+<blockquote>
+
+<p>Qhull provides a wide range of input
+and output options. To organize the code, most output formats use
+the same driver: </p>
+
+<pre>
+ qh_printbegin( fp, format, facetlist, facets, printall );
+
+ FORALLfacet_( facetlist )
+ qh_printafacet( fp, format, facet, printall );
+
+ FOREACHfacet_( facets )
+ qh_printafacet( fp, format, facet, printall );
+
+ qh_printend( fp, format );
+</pre>
+
+<p>Note the 'printall' flag. It selects whether or not
+qh_skipfacet() is tested. </p>
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a> <a name="TOC">&#149;</a>
+<a href="qh-globa.htm#TOC">Global</a> &#149; <b>Io</b> &#149;
+<a href="qh-mem.htm#TOC">Mem</a> &#149; <a href="qh-merge.htm#TOC">Merge</a> &#149;
+<a href="qh-poly.htm#TOC">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149;
+<a href="qh-set.htm#TOC">Set</a> &#149; <a href="qh-stat.htm#TOC">Stat</a> &#149;
+<a href="qh-user.htm#TOC">User</a> </p>
+
+<h3>Index to <a href="io.c">io.c</a> and <a href="io.h">io.h</a></h3>
+
+<ul>
+<li><a href="#iconst">io.h constants and types</a> </li>
+<li><a href="#ilevel">User level functions</a> </li>
+<li><a href="#iprint">Print functions for all output formats</a></li>
+<li><a href="#itext">Text output functions</a> </li>
+<li><a href="#iutil">Text utility functions</a></li>
+<li><a href="#igeom">Geomview output functions</a> </li>
+<li><a href="#iview">Geomview utility functions</a></li>
+</ul>
+
+<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iconst">io.h constants and types</a></h3>
+
+<ul>
+<li><a href="io.h#qh_MAXfirst">qh_MAXfirst</a> maximum length
+of first two lines of stdin </li>
+<li><a href="io.h#qh_WHITESPACE">qh_WHITESPACE</a> possible
+values of white space </li>
+<li><a href="io.h#printvridgeT">printvridgeT</a> function to
+print results of qh_printvdiagram or qh_eachvoronoi</li>
+</ul>
+
+<h3><a href="qh-io.htm#TOC">&#187;</a><a name="ilevel">User level functions</a></h3>
+
+<ul>
+<li><a href="io.c#copyfilename">qh_copyfilename</a>
+copy filename identified by qh_skipfilename
+<li><a href="io.c#eachvoronoi_all">qh_eachvoronoi_all</a>
+visit each Voronoi ridge of the Voronoi diagram
+<li><a href="io.c#prepare_output">qh_prepare_output</a>
+prepare Qhull for output (called by qh_produce_output())
+<li><a href="io.c#printhelp_degenerate">qh_printhelp_degenerate</a>
+prints descriptive message for precision error </li>
+<li><a href="io.c#printhelp_singular">qh_printhelp_singular</a>
+print help message for singular data </li>
+<li><a href="libqhull.c#printsummary">qh_printsummary</a> print
+summary ('s')</li>
+<li><a href="io.c#produce_output">qh_produce_output</a>
+prints out the result of qhull()</li>
+<li><a href="io.c#produce_output">qh_produce_output2</a>
+prints out the result of qhull() without calling qh_prepare_output()</li>
+<li><a href="io.c#readfeasible">qh_readfeasible</a> read
+interior point from remainder and qh fin ('H')</li>
+<li><a href="io.c#readpoints">qh_readpoints</a> read input
+points </li>
+<li><a href="io.c#setfeasible">qh_setfeasible</a> set
+interior point from qh feasible_string ('Hn,n,n')</li>
+<li><a href="io.c#skipfilename">qh_skipfilename</a>
+skip filename in string
+</ul>
+
+<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iprint">Print functions for all
+output formats</a></h3>
+
+<ul>
+<li><a href="io.c#countfacets">qh_countfacets</a> count good
+facets for printing and set visitid </li>
+<li><a href="io.c#markkeep">qh_markkeep</a> mark good facets
+that meet qh.KEEParea ('PAn'), qh.KEEPmerge ('PMn'), and qh.KEEPminArea ('PFn')</li>
+<li><a href="io.c#order_vertexneighbors">qh_order_vertexneighbors</a>
+order neighbors for a 3-d vertex by adjacency ('i', 'o')</li>
+<li><a href="io.c#printafacet">qh_printafacet</a> print facet
+in an output format </li>
+<li><a href="io.c#printbegin">qh_printbegin</a> print header
+for an output format </li>
+<li><a href="io.c#printend">qh_printend</a> print trailer for
+an output format </li>
+<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
+print facets in a facetlist</li>
+<li><a href="io.c#printfacets">qh_printfacets</a> print
+facetlist and/or facet set in an output format </li>
+<li><a href="io.c#printneighborhood">qh_printneighborhood</a>
+print neighborhood of one or two facets ('Po')</li>
+<li><a href="io.c#produce_output">qh_produce_output</a>
+print the results of qh_qhull() </li>
+<li><a href="io.c#skipfacet">qh_skipfacet</a> True if not
+printing this facet ('Pdk:n', 'QVn', 'QGn')</li>
+<li><a href="io.c#facetvertices">qh_facetvertices</a> return
+vertices in a set of facets ('p')</li>
+</ul>
+
+<h3><a href="qh-io.htm#TOC">&#187;</a><a name="itext">Text output functions</a></h3>
+<ul>
+<li><a href="io.c#eachvoronoi">qh_eachvoronoi</a>
+print or visit each Voronoi ridge for an input site of the Voronoi diagram
+<li><a href="io.c#printextremes">qh_printextremes</a> print
+extreme points by point ID (vertices of convex hull) ('Fx')</li>
+<li><a href="io.c#printextremes_2d">qh_printextremes_2d</a> print
+2-d extreme points by point ID ('Fx')</li>
+<li><a href="io.c#printextremes_d">qh_printextremes_d</a> print
+extreme points of input sites for Delaunay triangulations ('Fx')</li>
+<li><a href="io.c#printfacet">qh_printfacet</a> print all
+fields of a facet ('f')</li>
+<li><a href="io.c#printfacet2math">qh_printfacet2math</a> print
+2-d Maple or Mathematica output for a facet ('FM' or 'm')</li>
+<li><a href="io.c#printfacet3math">qh_printfacet3math</a>
+print 3-d Maple or Mathematica facet ('FM' or 'm')</li>
+<li><a href="io.c#printfacet3vertex">qh_printfacet3vertex</a>
+print vertices for a 3-d facet ('i', 'o')</li>
+<li><a href="io.c#printfacetheader">qh_printfacetheader</a>
+prints header fields of a facet ('f')</li>
+<li><a href="io.c#printfacetNvertex_nonsimplicial">qh_printfacetNvertex_nonsimplicial</a>
+print vertices for an N-d non-simplicial facet ('i', 'Ft')</li>
+<li><a href="io.c#printfacetNvertex_simplicial">qh_printfacetNvertex_simplicial</a>
+print vertices for an N-d simplicial facet ('i', 'o', 'Ft')</li>
+<li><a href="io.c#printfacetridges">qh_printfacetridges</a>
+prints ridges of a facet ('f')</li>
+<li><a href="io.c#printpoints_out">qh_printpoints_out</a> prints
+vertices for facets by their point coordinates ('p')</li>
+<li><a href="io.c#printridge">qh_printridge</a> print all
+fields for a ridge ('f')</li>
+<li><a href="io.c#printvdiagram">qh_printvdiagram</a> print
+voronoi diagram as Voronoi vertices for each input pair</li>
+<li><a href="io.c#printvertex">qh_printvertex</a> print all
+fields for a vertex ('f')</li>
+<li><a href="io.c#printvertexlist">qh_printvertexlist</a>
+print vertices used by a list or set of facets ('f')</li>
+<li><a href="io.c#printvertices">qh_printvertices</a> print a
+set of vertices ('f')</li>
+<li><a href="io.c#printvneighbors">qh_printvneighbors</a>
+print vertex neighbors of vertices ('FN')</li>
+<li><a href="io.c#printvoronoi">qh_printvoronoi</a> print
+voronoi diagram in 'o' or 'G' format</li>
+</ul>
+
+<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iutil">Text utility functions</a></h3>
+<ul>
+<li><a href="io.c#dfacet">dfacet</a> print facet by ID </li>
+<li><a href="io.c#dvertex">dvertex</a> print vertex by ID </li>
+<li><a href="io.c#compare_facetarea">qh_compare_facetarea</a>
+used by qsort() to order facets by area </li>
+<li><a href="io.c#compare_facetmerge">qh_compare_facetmerge</a>
+used by qsort() to order facets by number of merges </li>
+<li><a href="io.c#compare_facetvisit">qh_compare_facetvisit</a>
+used by qsort() to order facets by visit ID or ID </li>
+<li><a href="io.c#compare_vertexpoint">qh_compare_vertexpoint</a>
+used by qsort() to order vertices by point ID </li>
+<li><a href="io.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
+<li><a href="io.c#detvridge">qh_detvridge</a> determine Voronoi
+ridge for an input site
+<li><a href="io.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
+ridge for an input site
+<li><a href="io.c#facet2point">qh_facet2point</a> return two
+projected temporary vertices for a 2-d facet ('m', 'G')</li>
+<li><a href="io.c#markvoronoi">qh_markvoronoi</a> mark Voronoi
+vertices for printing
+<li><a href="io.c#printcenter">qh_printcenter</a> print
+facet-&gt;center as centrum or Voronoi center ('Ft', 'v p', 'FC', 'f') </li>
+<li><a href="io.c#printpoint">qh_printpoint</a>, qh_printpointid, print
+coordinates of a point ('p', 'o', 'Fp', 'G', 'f')</li>
+<li><a href="io.c#printpoint3">qh_printpoint3</a> prints 2-d,
+3-d, or 4-d point as 3-d coordinates ('G')</li>
+<li><a href="io.c#printvdiagram2">qh_printvdiagram2</a> print
+voronoi diagram for each ridge of each vertex from qh_markvoronoi</li>
+<li><a href="io.c#printvnorm">qh_printvnorm</a> print
+separating plane of the Voronoi diagram for a pair of input sites</li>
+<li><a href="io.c#printvridge">qh_printvridge</a> print
+ridge of the Voronoi diagram for a pair of input sites</li>
+<li><a href="io.c#projectdim3">qh_projectdim3</a> project 2-d
+3-d or 4-d point to a 3-d point ('G')</li>
+</ul>
+
+<h3><a href="qh-io.htm#TOC">&#187;</a><a name="igeom">Geomview output functions</a></h3>
+<ul>
+<li><a href="io.c#printfacet2geom">qh_printfacet2geom</a>
+print facet as a 2-d VECT object </li>
+<li><a href="io.c#printfacet2geom_points">qh_printfacet2geom_points</a>
+print points as a 2-d VECT object with offset </li>
+<li><a href="io.c#printfacet3geom_nonsimplicial">qh_printfacet3geom_nonsimplicial</a>
+print Geomview OFF for a 3-d nonsimplicial facet. </li>
+<li><a href="io.c#printfacet3geom_points">qh_printfacet3geom_points</a>
+prints a 3-d facet as OFF Geomview object. </li>
+<li><a href="io.c#printfacet3geom_simplicial">qh_printfacet3geom_simplicial</a>
+print Geomview OFF for a 3-d simplicial facet. </li>
+<li><a href="io.c#printfacet4geom_nonsimplicial">qh_printfacet4geom_nonsimplicial</a>
+print Geomview 4OFF file for a 4d nonsimplicial facet </li>
+<li><a href="io.c#printfacet4geom_simplicial">qh_printfacet4geom_simplicial</a>
+print Geomview 4OFF file for a 4d simplicial facet </li>
+<li><a href="io.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
+print hyperplane intersection as OFF or 4OFF </li>
+<li><a href="io.c#printvoronoi">qh_printvoronoi</a> print
+voronoi diagram in 'o' or 'G' format</li>
+</ul>
+<h3><a href="qh-io.htm#TOC">&#187;</a><a name="iview">Geomview utility functions</a></h3>
+<ul>
+<li><a href="io.c#geomplanes">qh_geomplanes</a>
+ return outer and inner planes for Geomview</li>
+<li><a href="io.c#printcentrum">qh_printcentrum</a> print
+centrum for a facet in OOGL format </li>
+<li><a href="io.c#printend4geom">qh_printend4geom</a> helper
+function for qh_printbegin/printend </li>
+<li><a href="io.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
+print Geomview OFF or 4OFF for the intersection of two
+hyperplanes in 3-d or 4-d </li>
+<li><a href="io.c#printline3geom">qh_printline3geom</a> prints a
+line as a VECT </li>
+<li><a href="io.c#printpointvect">qh_printpointvect</a>
+prints a 2-d or 3-d point as 3-d VECT's </li>
+<li><a href="io.c#printpointvect2">qh_printpointvect2</a>
+prints a 2-d or 3-d point as 2 3-d VECT's </li>
+<li><a href="io.c#printspheres">qh_printspheres</a> prints 3-d
+vertices as OFF spheres </li>
+</ul>
+<p>
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
+<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
+&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
+&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
+&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
+&#149; <a href="qh-user.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull/qh-mem.htm b/xs/src/qhull/src/libqhull/qh-mem.htm
new file mode 100644
index 000000000..b993b2229
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qh-mem.htm
@@ -0,0 +1,145 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>mem.c -- memory operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
+&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
+&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
+&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
+&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+</p>
+<hr>
+
+<h2>mem.c -- memory operations</h2>
+<blockquote>
+<p>Qhull uses quick-fit memory allocation. It maintains a
+set of free lists for a variety of small allocations. A
+small request returns a block from the best fitting free
+list. If the free list is empty, Qhull allocates a block
+from a reserved buffer. </p>
+<p>Use 'T5' to trace memory allocations.</p>
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a> &#149;
+<a href="qh-io.htm#TOC">Io</a> &#149; <b>Mem</b>
+&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
+&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="mem.c">mem.c</a> and
+<a href="mem.h">mem.h</a></h3>
+<ul>
+<li><a href="#etype">mem.h data types</a> </li>
+<li><a href="#emacro">mem.h macros</a> </li>
+<li><a href="#efunc">User level functions</a> </li>
+</ul>
+<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="etype">mem.h data types and constants</a></h3>
+<ul>
+<li><a href="mem.h#ptr_intT">ptr_intT</a> for casting
+a void* to an integer-type </li>
+<li><a href="mem.h#qhmemT">qhmemT</a> global memory
+structure for mem.c </li>
+<li><a href="mem.h#NOmem">qh_NOmem</a> disable memory allocation</li>
+</ul>
+<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="emacro">mem.h macros</a></h3>
+<ul>
+<li><a href="mem.h#memalloc_">qh_memalloc_</a>
+allocate memory</li>
+<li><a href="mem.h#memfree_">qh_memfree_</a> free
+memory</li>
+</ul>
+<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="efunc">User level
+functions</a></h3>
+<ul>
+<li><a href="mem.c#memalloc">qh_memalloc</a> allocate
+memory </li>
+<li><a href="mem.c#memcheck">qh_memcheck</a>
+quick check of memory for internal consistency</li>
+<li><a href="mem.c#memfree">qh_memfree</a> free
+memory </li>
+<li><a href="mem.c#meminit">qh_meminit</a> initialize
+memory </li>
+<li><a href="mem.c#memstatistics">qh_memstatistics</a>
+print memory statistics </li>
+<li><a href="mem.c#meminit">qh_memtotlong</a> return total, allocated long memory</li>
+<li><a href="mem.c#NOmem">qh_NOmem</a> allocation routines with malloc() and free()
+</ul>
+
+<h3><a href="qh-mem.htm#TOC">&#187;</a><a name="m">Initialization and
+termination functions</a></h3>
+<ul>
+<li><a href="mem.c#intcompare">qh_intcompare</a> used by
+qsort and bsearch to compare two integers </li>
+<li><a href="mem.c#memfreeshort">qh_memfreeshort</a>
+frees up all short and qhmem memory allocations </li>
+<li><a href="mem.c#meminit">qh_meminit</a> initialize
+memory </li>
+<li><a href="mem.c#meminitbuffers">qh_meminitbuffers</a>
+initialize qhmem </li>
+<li><a href="mem.c#memsetup">qh_memsetup</a> set up
+memory after running memsize() </li>
+<li><a href="mem.c#memsize">qh_memsize</a> define a free
+list for this size </li>
+<li><a href="mem.c#memstatistics">qh_memstatistics</a>
+print out memory statistics </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
+<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
+&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
+&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
+&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
+&#149; <a href="qh-user.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull/qh-merge.htm b/xs/src/qhull/src/libqhull/qh-merge.htm
new file mode 100644
index 000000000..54b97c88e
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qh-merge.htm
@@ -0,0 +1,366 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>merge.c -- facet merge operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
+&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
+&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
+&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
+&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+</p>
+<hr>
+
+<h2>merge.c -- facet merge operations</h2>
+<blockquote>
+<p>Qhull handles precision problems by merged facets or joggled input.
+Except for redundant vertices, it corrects a problem by
+merging two facets. When done, all facets are clearly
+convex. See <a href="../../html/qh-impre.htm">Imprecision in Qhull</a>
+for further information. </p>
+<p>Users may joggle the input ('<a href="../../html/qh-optq.htm#QJn">QJn</a>')
+instead of merging facets. </p>
+<p>Qhull detects and corrects the following problems: </p>
+<ul>
+<li><b>More than two facets meeting at a ridge. </b>When
+Qhull creates facets, it creates an even number
+of facets for each ridge. A convex hull always
+has two facets for each ridge. More than two
+facets may be created if non-adjacent facets
+share a vertex. This is called a <em>duplicate
+ridge</em>. In 2-d, a duplicate ridge would
+create a loop of facets. </li>
+</ul>
+<ul>
+<li><b>A facet contained in another facet. </b>Facet
+merging may leave all vertices of one facet as a
+subset of the vertices of another facet. This is
+called a <em>redundant facet</em>. </li>
+</ul>
+<ul>
+<li><b>A facet with fewer than three neighbors. </b>Facet
+merging may leave a facet with one or two
+neighbors. This is called a <em>degenerate facet</em>.
+</li>
+</ul>
+<ul>
+<li><b>A facet with flipped orientation. </b>A
+facet's hyperplane may define a halfspace that
+does not include the interior point.This is
+called a <em>flipped facet</em>. </li>
+</ul>
+<ul>
+<li><strong>A coplanar horizon facet.</strong> A
+newly processed point may be coplanar with an
+horizon facet. Qhull creates a new facet without
+a hyperplane. It links new facets for the same
+horizon facet together. This is called a <em>samecycle</em>.
+The new facet or samecycle is merged into the
+horizon facet. </li>
+</ul>
+<ul>
+<li><b>Concave facets. </b>A facet's centrum may be
+above a neighboring facet. If so, the facets meet
+at a concave angle. </li>
+</ul>
+<ul>
+<li><b>Coplanar facets. </b>A facet's centrum may be
+coplanar with a neighboring facet (i.e., it is
+neither clearly below nor clearly above the
+facet's hyperplane). Qhull removes coplanar
+facets in independent sets sorted by angle.</li>
+</ul>
+<ul>
+<li><b>Redundant vertex. </b>A vertex may have fewer
+than three neighboring facets. If so, it is
+redundant and may be renamed to an adjacent
+vertex without changing the topological
+structure.This is called a <em>redundant vertex</em>.
+</li>
+</ul>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
+&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
+&#149; <b>Merge</b> &#149; <a href="qh-poly.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
+&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="merge.c">merge.c</a> and
+<a href="merge.h">merge.h</a></h3>
+<ul>
+<li><a href="#mtype">merge.h data types, macros, and
+global sets</a> </li>
+<li><a href="#mconst">merge.h constants</a> </li>
+</ul>
+<ul>
+<li><a href="#mtop">top-level merge functions</a> </li>
+<li><a href="#mset">functions for identifying merges</a></li>
+<li><a href="#mbest">functions for determining the
+best merge</a> </li>
+<li><a href="#mmerge">functions for merging facets</a>
+</li>
+<li><a href="#mcycle">functions for merging a cycle
+of facets</a> </li>
+<li><a href="#mrename">functions for renaming a
+vertex</a> </li>
+<li><a href="#mvertex">functions for identifying
+vertices for renaming</a> </li>
+<li><a href="#mcheck">functions for check and trace</a> </li>
+</ul>
+<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mtype">merge.h data
+types, macros, and global sets</a></h3>
+<ul>
+<li><a href="merge.h#mergeT">mergeT</a> structure to
+identify a merge of two facets</li>
+<li><a href="merge.h#FOREACHmerge_">FOREACHmerge_</a>
+assign 'merge' to each merge in merges </li>
+<li><a href="libqhull.h#qh-set">qh global sets</a>
+qh.facet_mergeset contains non-convex merges
+while qh.degen_mergeset contains degenerate and
+redundant facets</li>
+</ul>
+<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mconst">merge.h
+constants</a></h3>
+<ul>
+<li><a href="libqhull.h#qh-prec">qh precision constants</a>
+precision constants for Qhull </li>
+<li><a href="merge.h#MRG">MRG...</a> indicates the
+type of a merge (mergeT-&gt;type)</li>
+<li><a href="merge.h#qh_ANGLEredundant">qh_ANGLEredundant</a>
+indicates redundant merge in mergeT-&gt;angle </li>
+<li><a href="merge.h#qh_ANGLEdegen">qh_ANGLEdegen</a>
+indicates degenerate facet in mergeT-&gt;angle </li>
+<li><a href="merge.h#qh_ANGLEconcave">qh_ANGLEconcave</a>
+offset to indicate concave facets in
+mergeT-&gt;angle </li>
+<li><a href="merge.h#qh_MERGEapex">qh_MERGEapex</a>
+flag for qh_mergefacet() to indicate an apex
+merge </li>
+</ul>
+<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mtop">top-level merge
+functions</a></h3>
+<ul>
+<li><a href="merge.c#all_merges">qh_all_merges</a>
+merge all non-convex facets </li>
+<li><a href="merge.c#checkzero">qh_checkzero</a>
+check that facets are clearly convex </li>
+<li><a href="merge.c#flippedmerges">qh_flippedmerges</a>
+merge flipped facets into best neighbor </li>
+<li><a href="merge.c#forcedmerges">qh_forcedmerges</a>
+merge all duplicate ridges </li>
+<li><a href="merge.c#merge_degenredundant">qh_merge_degenredundant</a>
+merge degenerate and redundant facets </li>
+<li><a href="merge.c#merge_nonconvex">qh_merge_nonconvex</a>
+merge a non-convex ridge </li>
+<li><a href="merge.c#premerge">qh_premerge</a>
+pre-merge non-convex facets </li>
+<li><a href="merge.c#postmerge">qh_postmerge</a>
+post-merge nonconvex facets as defined by
+maxcentrum/maxangle </li>
+</ul>
+
+<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mset">functions for
+identifying merges</a></h3>
+<ul>
+<li><a href="merge.c#appendmergeset">qh_appendmergeset</a>
+appends an entry to qh.facet_mergeset</li>
+<li><a href="merge.c#compareangle">qh_compareangle</a>
+used by qsort() to order merges </li>
+<li><a href="merge.c#comparemerge">qh_comparemerge</a>
+used by qsort() to order merges </li>
+<li><a href="merge.c#degen_redundant_facet">qh_degen_redundant_facet</a>
+check for a degenerate and redundant facet</li>
+<li><a href="merge.c#degen_redundant_neighbors">qh_degen_redundant_neighbors</a>
+append degenerate and redundant neighbors to
+qh.degen_mergeset </li>
+<li><a href="merge.c#getmergeset_initial">qh_getmergeset_initial</a>
+build initial qh.facet_mergeset </li>
+<li><a href="merge.c#getmergeset">qh_getmergeset</a>
+update qh.facet_mergeset </li>
+<li><a href="merge.c#mark_dupridges">qh_mark_dupridges</a>
+add duplicated ridges to qh.facet_mergeset</li>
+<li><a href="merge.c#maydropneighbor">qh_maydropneighbor</a>
+drop neighbor relationship if no ridge between
+facet and neighbor </li>
+<li><a href="merge.c#test_appendmerge">qh_test_appendmerge</a>
+test a pair of facets for convexity and append to
+qh.facet_mergeset if non-convex </li>
+<li><a href="merge.c#test_vneighbors">qh_test_vneighbors</a>
+test vertex neighbors for convexity </li>
+</ul>
+
+<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mbest">functions for
+determining the best merge</a></h3>
+<ul>
+<li><a href="merge.c#findbest_test">qh_findbest_test</a>
+test neighbor for best merge </li>
+<li><a href="merge.c#findbestneighbor">qh_findbestneighbor</a>
+finds best neighbor of a facet for merging (i.e.,
+closest hyperplane) </li>
+</ul>
+
+<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mmerge">functions for
+merging facets</a></h3>
+<ul>
+<li><a href="merge.c#copynonconvex">qh_copynonconvex</a>
+copy non-convex flag to another ridge for the
+same neighbor </li>
+<li><a href="merge.c#makeridges">qh_makeridges</a>
+creates explicit ridges between simplicial facets
+</li>
+<li><a href="merge.c#mergefacet">qh_mergefacet</a>
+merges one facet into another facet</li>
+<li><a href="merge.c#mergeneighbors">qh_mergeneighbors</a>
+merges the neighbors of two facets </li>
+<li><a href="merge.c#mergeridges">qh_mergeridges</a>
+merges the ridge sets of two facets </li>
+<li><a href="merge.c#mergesimplex">qh_mergesimplex</a>
+merge a simplicial facet into another simplicial
+facet </li>
+<li><a href="merge.c#mergevertex_del">qh_mergevertex_del</a>
+delete a vertex due to merging one facet into
+another facet </li>
+<li><a href="merge.c#mergevertex_neighbors">qh_mergevertex_neighbors</a>
+merge the vertex neighbors of two facets </li>
+<li><a href="merge.c#mergevertices">qh_mergevertices</a>
+merge the vertex sets of two facets </li>
+<li><a href="merge.c#newvertices">qh_newvertices</a>
+register all vertices as new vertices </li>
+<li><a href="merge.c#updatetested">qh_updatetested</a>
+clear tested flags and centrums involved in a
+merge </li>
+<li><a href="merge.c#willdelete">qh_willdelete</a>
+moves facet to qh.visible_list; sets replacement
+or NULL </li>
+</ul>
+
+<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mcycle">functions for
+merging a cycle of facets</a></h3>
+<p>If a point is coplanar with an horizon facet, the
+corresponding new facets are linked together (a <em>samecycle</em>)
+for merging.</p>
+<ul>
+<li><a href="merge.c#basevertices">qh_basevertices</a>
+return temporary set of base vertices for a
+samecycle </li>
+<li><a href="merge.c#mergecycle">qh_mergecycle</a>
+merge a samecycle into a horizon facet </li>
+<li><a href="merge.c#mergecycle_all">qh_mergecycle_all</a>
+merge all samecycles into horizon facets</li>
+<li><a href="merge.c#mergecycle_facets">qh_mergecycle_facets</a>
+finish merge of samecycle </li>
+<li><a href="merge.c#mergecycle_neighbors">qh_mergecycle_neighbors</a>
+merge neighbor sets for samecycle </li>
+<li><a href="merge.c#mergecycle_ridges">qh_mergecycle_ridges</a>
+merge ridge sets for samecycle </li>
+<li><a href="merge.c#mergecycle_vneighbors">qh_mergecycle_vneighbors</a>
+merge vertex neighbor sets for samecycle </li>
+</ul>
+<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mrename">functions
+for renaming a vertex</a></h3>
+<ul>
+<li><a href="merge.c#comparevisit">qh_comparevisit</a>
+used by qsort() to order vertices by visitid</li>
+<li><a href="merge.c#reducevertices">qh_reducevertices</a>
+reduce vertex sets </li>
+<li><a href="merge.c#redundant_vertex">qh_redundant_vertex</a>
+returns true if detect and rename redundant
+vertex </li>
+<li><a href="merge.c#rename_sharedvertex">qh_rename_sharedvertex</a>
+detect and rename a shared vertex </li>
+<li><a href="merge.c#renameridgevertex">qh_renameridgevertex</a>
+rename oldvertex to newvertex in a ridge </li>
+<li><a href="merge.c#renamevertex">qh_renamevertex</a>
+rename oldvertex to newvertex in ridges </li>
+<li><a href="merge.c#remove_extravertices">qh_remove_extravertices</a>
+remove extra vertices in non-simplicial facets </li>
+</ul>
+
+<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mvertex">functions
+for identifying vertices for renaming</a></h3>
+<ul>
+<li><a href="merge.c#find_newvertex">qh_find_newvertex</a>
+locate new vertex for renaming old vertex </li>
+<li><a href="merge.c#hashridge">qh_hashridge</a> add
+ridge to hashtable </li>
+<li><a href="merge.c#hashridge_find">qh_hashridge_find</a>
+returns matching ridge in hashtable</li>
+<li><a href="merge.c#neighbor_intersections">qh_neighbor_intersections</a>
+return intersection of vertex sets for
+neighboring facets </li>
+<li><a href="merge.c#vertexridges">qh_vertexridges</a>
+return temporary set of ridges adjacent to a
+vertex </li>
+<li><a href="merge.c#vertexridges_facet">qh_vertexridges_facet</a>
+add adjacent ridges for a vertex in facet </li>
+</ul>
+
+<h3><a href="qh-merge.htm#TOC">&#187;</a><a name="mcheck">functions for check and
+trace</a></h3>
+<ul>
+<li><a href="merge.c#checkconnect">qh_checkconnect</a>
+check that new facets are connected </li>
+<li><a href="merge.c#tracemerge">qh_tracemerge</a>
+print trace message after merge </li>
+<li><a href="merge.c#tracemerging">qh_tracemerging</a>
+print trace message during post-merging </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
+<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
+&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
+&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
+&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
+&#149; <a href="qh-user.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull/qh-poly.htm b/xs/src/qhull/src/libqhull/qh-poly.htm
new file mode 100644
index 000000000..c8f6b38b0
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qh-poly.htm
@@ -0,0 +1,485 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>poly.c, poly2.c -- polyhedron operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
+&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
+&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
+&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+</p>
+<hr>
+
+<h2>poly.c, poly2.c -- polyhedron operations</h2>
+<blockquote>
+
+<p>Qhull uses dimension-free terminology. Qhull builds a
+polyhedron in dimension <em>d. </em>A <em>polyhedron</em> is a
+simplicial complex of faces with geometric information for the
+top and bottom-level faces. A (<em>d-1</em>)-face is a <em>facet</em>,
+a (<em>d-2</em>)-face is a <em>ridge</em>, and a <em>0</em>-face
+is a <em>vertex</em>. For example in 3-d, a facet is a polygon
+and a ridge is an edge. A facet is built from a ridge (the <em>base</em>)
+and a vertex (the <em>apex</em>). See
+<a href="../../html/index.htm#structure">Qhull's data structures</a>.</p>
+
+<p>Qhull's primary data structure is a polyhedron. A
+polyhedron is a list of facets. Each facet has a set of
+neighboring facets and a set of vertices. Each facet has a
+hyperplane. For example, a tetrahedron has four facets.
+If its vertices are <em>a, b, c, d</em>, and its facets
+are <em>1, 2, 3, 4,</em> the tetrahedron is </p>
+<blockquote>
+<ul>
+<li>facet 1 <ul>
+ <li>vertices: b c d </li>
+ <li>neighbors: 2 3 4 </li>
+</ul>
+</li>
+<li>facet 2 <ul>
+ <li>vertices: a c d </li>
+ <li>neighbors: 1 3 4 </li>
+</ul>
+</li>
+<li>facet 3 <ul>
+ <li>vertices: a b d </li>
+ <li>neighbors: 1 2 4 </li>
+</ul>
+</li>
+<li>facet 4 <ul>
+ <li>vertices: a b c </li>
+ <li>neighbors: 1 2 3 </li>
+</ul>
+</li>
+</ul>
+</blockquote>
+<p>A facet may be simplicial or non-simplicial. In 3-d, a
+<i>simplicial facet</i> has three vertices and three
+neighbors. A <i>nonsimplicial facet</i> has more than
+three vertices and more than three neighbors. A
+nonsimplicial facet has a set of ridges and a centrum. </p>
+<p>
+A simplicial facet has an orientation. An <i>orientation</i>
+is either <i>top</i> or <i>bottom</i>.
+The flag, <tt>facet-&gt;toporient,</tt>
+defines the orientation of the facet's vertices. For example in 3-d,
+'top' is left-handed orientation (i.e., the vertex order follows the direction
+of the left-hand fingers when the thumb is pointing away from the center).
+Except for axis-parallel facets in 5-d and higher, topological orientation
+determines the geometric orientation of the facet's hyperplane.
+
+<p>A nonsimplicial facet is due to merging two or more
+facets. The facet's ridge set determine a simplicial
+decomposition of the facet. Each ridge is a 1-face (i.e.,
+it has two vertices and two neighboring facets). The
+orientation of a ridge is determined by the order of the
+neighboring facets. The flag, <tt>facet-&gt;toporient,</tt>is
+ignored. </p>
+<p>A nonsimplicial facet has a centrum for testing
+convexity. A <i>centrum</i> is a point on the facet's
+hyperplane that is near the center of the facet. Except
+for large facets, it is the arithmetic average of the
+facet's vertices. </p>
+<p>A nonsimplicial facet is an approximation that is
+defined by offsets from the facet's hyperplane. When
+Qhull finishes, the <i>outer plane</i> is above all
+points while the <i>inner plane</i> is below the facet's
+vertices. This guarantees that any exact convex hull
+passes between the inner and outer planes. The outer
+plane is defined by <tt>facet-&gt;maxoutside</tt> while
+the inner plane is computed from the facet's vertices.</p>
+
+<p>Qhull 3.1 includes triangulation of non-simplicial facets
+('<a href="../../html/qh-optq.htm#Qt">Qt</a>').
+These facets,
+called <i>tricoplanar</i>, share the same normal. centrum, and Voronoi center.
+One facet (keepcentrum) owns these data structures.
+While tricoplanar facets are more accurate than the simplicial facets from
+joggled input, they
+may have zero area or flipped orientation.
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
+&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
+&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <b>Poly</b>
+&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
+&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="poly.c">poly.c</a>,
+<a href="poly2.c">poly2.c</a>, <a href="poly.h">poly.h</a>,
+and <a href="libqhull.h">libqhull.h</a></h3>
+<ul>
+<li><a href="#ptype">Data types and global
+lists for polyhedrons</a> </li>
+<li><a href="#pconst">poly.h constants</a> </li>
+<li><a href="#pgall">Global FORALL macros</a> </li>
+<li><a href="#pall">FORALL macros</a> </li>
+<li><a href="#peach">FOREACH macros</a> </li>
+<li><a href="#pieach">Indexed FOREACH macros</a> </li>
+<li><a href="#pmacro">Other macros for polyhedrons</a><p>&nbsp;</li>
+<li><a href="#plist">Facetlist functions</a> </li>
+<li><a href="#pfacet">Facet functions</a> </li>
+<li><a href="#pvertex">Vertex, ridge, and point
+functions</a> </li>
+<li><a href="#phash">Hashtable functions</a> </li>
+<li><a href="#pnew">Allocation and deallocation
+functions</a> </li>
+<li><a href="#pcheck">Check functions</a> </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="ptype">Data
+types and global lists for polyhedrons</a></h3>
+<ul>
+<li><a href="libqhull.h#facetT">facetT</a> defines a
+facet </li>
+<li><a href="libqhull.h#ridgeT">ridgeT</a> defines a
+ridge </li>
+<li><a href="libqhull.h#vertexT">vertexT</a> defines a
+vertex </li>
+<li><a href="libqhull.h#qh-lists">qh facet and vertex
+lists</a> lists of facets and vertices </li>
+<li><a href="libqhull.h#qh-set">qh global sets</a>
+global sets for merging, hashing, input, etc. </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pconst">poly.h constants</a></h3>
+<ul>
+<li><a href="poly.h#ALGORITHMfault">ALGORITHMfault</a>
+flag to not report errors in qh_checkconvex() </li>
+<li><a href="poly.h#DATAfault">DATAfault</a> flag to
+report errors in qh_checkconvex() </li>
+<li><a href="poly.h#DUPLICATEridge">DUPLICATEridge</a>
+special value for facet-&gt;neighbor to indicate
+a duplicate ridge </li>
+<li><a href="poly.h#MERGEridge">MERGEridge</a>
+special value for facet-&gt;neighbor to indicate
+a merged ridge </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pgall">Global FORALL
+macros</a></h3>
+<ul>
+<li><a href="libqhull.h#FORALLfacets">FORALLfacets</a>
+assign 'facet' to each facet in qh.facet_list </li>
+<li><a href="poly.h#FORALLnew_facets">FORALLnew_facets</a>
+assign 'facet' to each facet in qh.newfacet_list </li>
+<li><a href="poly.h#FORALLvisible_facets">FORALLvisible_facets</a>
+assign 'visible' to each visible facet in
+qh.visible_list </li>
+<li><a href="libqhull.h#FORALLpoints">FORALLpoints</a>
+assign 'point' to each point in qh.first_point,
+qh.num_points </li>
+<li><a href="libqhull.h#FORALLvertices">FORALLvertices</a>
+assign 'vertex' to each vertex in qh.vertex_list </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pall">FORALL macros</a></h3>
+<ul>
+<li><a href="poly.h#FORALLfacet_">FORALLfacet_</a>
+assign 'facet' to each facet in facetlist </li>
+<li><a href="libqhull.h#FORALLpoint_">FORALLpoint_</a>
+assign 'point' to each point in points array</li>
+<li><a href="poly.h#FORALLsame_">FORALLsame_</a>
+assign 'same' to each facet in samecycle</li>
+<li><a href="poly.h#FORALLsame_cycle_">FORALLsame_cycle_</a>
+assign 'same' to each facet in samecycle</li>
+<li><a href="poly.h#FORALLvertex_">FORALLvertex_</a>
+assign 'vertex' to each vertex in vertexlist </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="peach">FOREACH macros</a></h3>
+<ul>
+<li><a href="libqhull.h#FOREACHfacet_">FOREACHfacet_</a>
+assign 'facet' to each facet in facets </li>
+<li><a href="libqhull.h#FOREACHneighbor_">FOREACHneighbor_</a>
+assign 'neighbor' to each facet in
+facet-&gt;neighbors or vertex-&gt;neighbors</li>
+<li><a href="poly.h#FOREACHnewfacet_">FOREACHnewfacet_</a>
+assign 'newfacet' to each facet in facet set </li>
+<li><a href="libqhull.h#FOREACHpoint_">FOREACHpoint_</a>
+assign 'point' to each point in points set </li>
+<li><a href="libqhull.h#FOREACHridge_">FOREACHridge_</a>
+assign 'ridge' to each ridge in ridge set </li>
+<li><a href="libqhull.h#FOREACHvertex_">FOREACHvertex_</a>
+assign 'vertex' to each vertex in vertex set </li>
+<li><a href="poly.h#FOREACHvertexA_">FOREACHvertexA_</a>
+assign 'vertexA' to each vertex in vertex set</li>
+<li><a href="poly.h#FOREACHvisible_">FOREACHvisible_</a>
+assign 'visible' to each facet in facet set </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pieach">Indexed
+FOREACH macros</a></h3>
+<ul>
+<li><a href="libqhull.h#FOREACHfacet_i_">FOREACHfacet_i_</a>
+assign 'facet' and 'facet_i' to each facet in
+facet set </li>
+<li><a href="libqhull.h#FOREACHneighbor_i_">FOREACHneighbor_i_</a>
+assign 'neighbor' and 'neighbor_i' to each facet
+in facet-&gt;neighbors or vertex-&gt;neighbors</li>
+<li><a href="libqhull.h#FOREACHpoint_i_">FOREACHpoint_i_</a>
+assign 'point' and 'point_i' to each point in
+points set </li>
+<li><a href="libqhull.h#FOREACHridge_i_">FOREACHridge_i_</a>
+assign 'ridge' and 'ridge_i' to each ridge in
+ridges set </li>
+<li><a href="libqhull.h#FOREACHvertex_i_">FOREACHvertex_i_</a>
+assign 'vertex' and 'vertex_i' to each vertex in
+vertices set </li>
+<li><a href="poly.h#FOREACHvertexreverse12_">FOREACHvertexreverse12_</a>
+assign 'vertex' to each vertex in vertex set;
+reverse the order of first two vertices </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pmacro">Other macros for polyhedrons</a></h3>
+<ul>
+<li><a href="libqhull.h#getid_">getid_</a> return ID for
+a facet, ridge, or vertex </li>
+<li><a href="libqhull.h#otherfacet_">otherfacet_</a>
+return neighboring facet for a ridge in a facet </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="plist">Facetlist
+functions</a></h3>
+<ul>
+<li><a href="poly.c#appendfacet">qh_appendfacet</a>
+appends facet to end of qh.facet_list</li>
+<li><a href="poly.c#attachnewfacets">qh_attachnewfacets</a>
+attach new facets in qh.newfacet_list to the
+horizon </li>
+<li><a href="poly2.c#findgood">qh_findgood</a>
+identify good facets for qh.PRINTgood </li>
+<li><a href="poly2.c#findgood_all">qh_findgood_all</a>
+identify more good facets for qh.PRINTgood </li>
+<li><a href="poly2.c#furthestnext">qh_furthestnext</a>
+move facet with furthest of furthest points to
+facet_next </li>
+<li><a href="poly2.c#initialhull">qh_initialhull</a>
+construct the initial hull as a simplex of
+vertices </li>
+<li><a href="poly2.c#nearcoplanar">qh_nearcoplanar</a>
+ remove near-inside points from coplanar sets</li>
+<li><a href="poly2.c#prependfacet">qh_prependfacet</a>
+prepends facet to start of facetlist </li>
+<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
+print facets in a facetlist</li>
+<li><a href="poly2.c#printlists">qh_printlists</a>
+print out facet list for debugging </li>
+<li><a href="poly.c#removefacet">qh_removefacet</a>
+unlinks facet from qh.facet_list</li>
+<li><a href="poly2.c#resetlists">qh_resetlists</a>
+reset qh.newvertex_list, qh.newfacet_list, and
+qh.visible_list </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pfacet">Facet
+functions</a></h3>
+<ul>
+<li><a href="poly2.c#createsimplex">qh_createsimplex</a>
+create a simplex of facets from a set of vertices
+</li>
+<li><a href="poly2.c#findbestlower">qh_findbestlower</a> find best
+non-upper, non-flipped facet for point at upperfacet</li>
+<li><a href="poly2.c#furthestout">qh_furthestout</a>
+make furthest outside point the last point of a
+facet's outside set </li>
+<li><a href="poly.c#makenew_nonsimplicial">qh_makenew_nonsimplicial</a>
+make new facets from ridges of visible facets </li>
+<li><a href="poly.c#makenew_simplicial">qh_makenew_simplicial</a>
+make new facets for horizon neighbors </li>
+<li><a href="poly.c#makenewfacet">qh_makenewfacet</a>
+create a facet from vertices and apex </li>
+<li><a href="poly2.c#makenewfacets">qh_makenewfacets</a>
+make new facets from vertex, horizon facets, and
+visible facets </li>
+<li><a href="poly.c#makenewplanes">qh_makenewplanes</a>
+make new hyperplanes for facets </li>
+<li><a href="poly2.c#outcoplanar">qh_outcoplanar</a>
+move points from outside set to coplanar set </li>
+<li><a href="poly2.c#setvoronoi_all">qh_setvoronoi_all</a>
+compute Voronoi centers for all facets </li>
+<li><a href="poly2.c#triangulate">qh_triangulate</a>
+triangulate non-simplicial facets</li>
+<li><a href="poly2.c#triangulate_facet">qh_triangulate_facet</a>
+triangulate a non-simplicial facet</li>
+<li><a href="poly2.c#triangulate_link">qh_triangulate_link</a>
+link facets together from qh_triangulate</li>
+<li><a href="poly2.c#triangulate_mirror">qh_triangulate_mirror</a>
+delete mirrored facets from qh_triangulate</li>
+<li><a href="poly2.c#triangulate_null">qh_triangulate_null</a>
+delete null facet from qh_triangulate</li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pvertex">Vertex,
+ridge, and point functions</a></h3>
+<ul>
+<li><a href="poly.c#appendvertex">qh_appendvertex</a>
+append vertex to end of qh.vertex_list, </li>
+<li><a href="io.c#detvridge">qh_detvridge</a> determine Voronoi
+ridge for an input site
+<li><a href="io.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
+ridge for an input site
+<li><a href="poly2.c#facet3vertex">qh_facet3vertex</a>
+return an oriented vertex set for a 3-d facet </li>
+<li><a href="poly.c#facetintersect">qh_facetintersect</a>
+return intersection of simplicial facets </li>
+<li><a href="poly2.c#initialvertices">qh_initialvertices</a>
+return non-singular set of initial vertices </li>
+<li><a href="poly2.c#isvertex">qh_isvertex</a> true
+if point is in a vertex set </li>
+<li><a href="poly2.c#nearvertex">qh_nearvertex</a>
+return nearest vertex to point </li>
+<li><a href="poly2.c#nextridge3d">qh_nextridge3d</a>
+iterate over each ridge and vertex for a 3-d
+facet </li>
+<li><a href="poly2.c#point">qh_point</a> return point
+for a point ID </li>
+<li><a href="poly2.c#pointfacet">qh_pointfacet</a>
+return temporary set of facets indexed by point
+ID </li>
+<li><a href="poly.c#pointid">qh_pointid</a> return ID
+for a point</li>
+<li><a href="poly2.c#pointvertex">qh_pointvertex</a>
+return temporary set of vertices indexed by point
+ID </li>
+<li><a href="poly.c#removevertex">qh_removevertex</a>
+unlink vertex from qh.vertex_list, </li>
+<li><a href="poly.c#updatevertices">qh_updatevertices</a>
+update vertex neighbors and delete interior
+vertices </li>
+<li><a href="poly2.c#vertexintersect">qh_vertexintersect</a>
+intersect two vertex sets </li>
+<li><a href="poly2.c#vertexintersect_new">qh_vertexintersect_new</a>
+return intersection of two vertex sets </li>
+<li><a href="poly2.c#vertexneighbors">qh_vertexneighbors</a>
+for each vertex in hull, determine facet
+neighbors </li>
+<li><a href="poly2.c#vertexsubset">qh_vertexsubset</a>
+returns True if vertexsetA is a subset of
+vertexsetB </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="phash">Hashtable functions</a></h3>
+<ul>
+<li><a href="poly2.c#addhash">qh_addhash</a> add hash
+element to linear hash table</li>
+<li><a href="poly.c#gethash">qh_gethash</a> return
+hash value for a set</li>
+<li><a href="poly2.c#matchduplicates">qh_matchduplicates</a>
+match duplicate ridges in hash table </li>
+<li><a href="poly.c#matchneighbor">qh_matchneighbor</a>
+try to match subridge of new facet with a
+neighbor </li>
+<li><a href="poly.c#matchnewfacets">qh_matchnewfacets</a>
+match new facets with their new facet neighbors </li>
+<li><a href="poly.c#matchvertices">qh_matchvertices</a>
+tests whether a facet and hash entry match at a
+ridge </li>
+<li><a href="poly2.c#newhashtable">qh_newhashtable</a>
+allocate a new qh.hash_table </li>
+<li><a href="poly2.c#printhashtable">qh_printhashtable</a>
+print hash table </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pnew">Allocation and
+deallocation functions</a></h3>
+<ul>
+<li><a href="poly2.c#clearcenters">qh_clearcenters</a>
+clear old data from facet-&gt;center </li>
+<li><a href="poly.c#deletevisible">qh_deletevisible</a>
+delete visible facets and vertices </li>
+<li><a href="poly.c#delfacet">qh_delfacet</a> free up
+the memory occupied by a facet </li>
+<li><a href="poly2.c#delridge">qh_delridge</a> delete
+ridge</li>
+<li><a href="poly2.c#delvertex">qh_delvertex</a>
+delete vertex </li>
+<li><a href="poly.c#newfacet">qh_newfacet</a> create
+and allocate space for a facet </li>
+<li><a href="poly.c#newridge">qh_newridge</a> create
+and allocate space for a ridge </li>
+<li><a href="poly2.c#newvertex">qh_newvertex</a>
+create and allocate space for a vertex </li>
+</ul>
+<h3><a href="qh-poly.htm#TOC">&#187;</a><a name="pcheck">Check
+functions</a></h3>
+<ul>
+<li><a href="poly2.c#check_bestdist">qh_check_bestdist</a>
+check that points are not outside of facets </li>
+<li><a href="poly2.c#check_dupridge">qh_check_dupridge</a>
+check duplicate ridge between facet1 and facet2 for wide merge </li>
+<li><a href="poly2.c#check_maxout">qh_check_maxout</a>
+updates qh.max_outside and checks all points
+against bestfacet </li>
+<li><a href="poly2.c#check_output">qh_check_output</a>
+check topological and geometric output</li>
+<li><a href="poly2.c#check_point">qh_check_point</a>
+check that point is not outside of facet </li>
+<li><a href="poly2.c#check_points">qh_check_points</a>
+check that all points are inside all facets </li>
+<li><a href="poly2.c#checkconvex">qh_checkconvex</a>
+check that each ridge in facetlist is convex </li>
+<li><a href="poly2.c#checkfacet">qh_checkfacet</a>
+check for consistency errors in facet </li>
+<li><a href="poly.c#checkflipped">qh_checkflipped</a>
+check facet orientation to the interior point </li>
+<li><a href="poly2.c#checkflipped_all">qh_checkflipped_all</a>
+check facet orientation for a facet list </li>
+<li><a href="poly2.c#checkpolygon">qh_checkpolygon</a>
+check topological structure </li>
+<li><a href="poly2.c#checkvertex">qh_checkvertex</a>
+check vertex for consistency </li>
+<li><a href="poly2.c#infiniteloop">qh_infiniteloop</a>
+report error for a loop of facets </li>
+<li><a href="poly2.c#printlists">qh_printlists</a>
+print out facet list for debugging </li>
+</ul>
+
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
+<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
+&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
+&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
+&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
+&#149; <a href="qh-user.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull/qh-qhull.htm b/xs/src/qhull/src/libqhull/qh-qhull.htm
new file mode 100644
index 000000000..5212c6422
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qh-qhull.htm
@@ -0,0 +1,279 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>libqhull.c -- top-level functions and basic data types</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
+&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
+&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
+&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
+&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+</p>
+<hr>
+
+<h2>libqhull.c -- top-level functions and basic data types</h2>
+<blockquote>
+<p>Qhull implements the Quickhull algorithm for computing
+the convex hull. The Quickhull algorithm combines two
+well-known algorithms: the 2-d quickhull algorithm and
+the n-d beneath-beyond algorithm. See
+<a href="../../html/index.htm#description">Description of Qhull</a>. </p>
+<p>This section provides an index to the top-level
+functions and base data types. The top-level header file, <tt>libqhull.h</tt>,
+contains prototypes for these functions.</p>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
+&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
+&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
+&#149; <b>Qhull</b> &#149; <a href="qh-set.htm#TOC">Set</a>
+&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="libqhull.c">libqhull.c</a>,
+<a href="libqhull.h">libqhull.h</a>, and
+<a href="../qhull/unix.c">unix.c</a></h3>
+<ul>
+<li><a href="#qtype">libqhull.h and unix.c data types and
+constants</a> </li>
+<li><a href="#qmacro">libqhull.h other macros</a> </li>
+<li><a href="#qfunc">Quickhull routines in call order</a> </li>
+<li><a href="#qinit">Top-level routines for initializing and terminating Qhull</a></li>
+<li><a href="#qin">Top-level routines for reading and modifying the input</a></li>
+<li><a href="#qcall">Top-level routines for calling Qhull</a></li>
+<li><a href="#qout">Top-level routines for returning results</a></li>
+<li><a href="#qtest">Top-level routines for testing and debugging</a></li>
+</ul>
+
+<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qtype">libqhull.h and unix.c
+data types and constants</a></h3>
+<ul>
+<li><a href="libqhull.h#flagT">flagT</a> Boolean flag as
+a bit </li>
+<li><a href="libqhull.h#boolT">boolT</a> boolean value,
+either True or False </li>
+<li><a href="libqhull.h#CENTERtype">CENTERtype</a> to
+distinguish facet-&gt;center </li>
+<li><a href="libqhull.h#qh_PRINT">qh_PRINT</a> output
+formats for printing (qh.PRINTout) </li>
+<li><a href="libqhull.h#qh_ALL">qh_ALL</a> argument flag
+for selecting everything </li>
+<li><a href="libqhull.h#qh_ERR">qh_ERR</a> Qhull exit
+codes for indicating errors </li>
+<li><a href="libqhull.h#qh_FILEstderr">qh_FILEstderr</a> Fake stderr
+to distinguish error output from normal output [C++ only]</li>
+<li><a href="../qhull/unix.c#prompt">qh_prompt</a> version and long prompt for Qhull</li>
+<li><a href="../qhull/unix.c#prompt2">qh_prompt2</a> synopsis for Qhull</li>
+<li><a href="../qhull/unix.c#prompt3">qh_prompt3</a> concise prompt for Qhull</li>
+<li><a href="global.c#qh_version">qh_version</a> version stamp</li>
+</ul>
+
+<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qmacro">libqhull.h other
+macros</a></h3>
+<ul>
+<li><a href="qhull_a.h#traceN">traceN</a> print trace
+message if <em>qh.IStracing &gt;= N</em>. </li>
+<li><a href="qhull_a.h#QHULL_UNUSED">QHULL_UNUSED</a> declare an
+ unused variable to avoid warnings. </li>
+</ul>
+
+<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qfunc">Quickhull
+routines in call order</a></h3>
+<ul>
+<li><a href="../qhull/unix.c#main">main</a> processes the
+command line, calls qhull() to do the work, and
+exits </li>
+<li><a href="libqhull.c#qhull">qh_qhull</a> construct
+the convex hull of a set of points </li>
+<li><a href="libqhull.c#build_withrestart">qh_build_withrestart</a>
+allow restarts while calling qh_buildhull</li>
+<li><a href="poly2.c#initbuild">qh_initbuild</a>
+initialize hull and outside sets with point array</li>
+<li><a href="libqhull.c#partitionall">qh_partitionall</a>
+partition all points into outside sets </li>
+<li><a href="libqhull.c#buildhull">qh_buildhull</a>
+construct a convex hull by adding points one at a
+time </li>
+<li><a href="libqhull.c#nextfurthest">qh_nextfurthest</a>
+return next furthest point for processing </li>
+<li><a href="libqhull.c#buildtracing">qh_buildtracing</a>
+trace an iteration of buildhull </li>
+<li><a href="libqhull.c#addpoint">qh_addpoint</a> add a
+point to the convex hull </li>
+<li><a href="libqhull.c#findhorizon">qh_findhorizon</a>
+find the horizon and visible facets for a point </li>
+<li><a href="libqhull.c#partitionvisible">qh_partitionvisible</a>
+partition points from facets in qh.visible_list
+to facets in qh.newfacet_list </li>
+<li><a href="libqhull.c#partitionpoint">qh_partitionpoint</a>
+partition a point as inside, coplanar with, or
+outside a facet </li>
+<li><a href="libqhull.c#partitioncoplanar">qh_partitioncoplanar</a>
+partition coplanar point into a facet </li>
+<li><a href="libqhull.c#precision">qh_precision</a> restart on precision errors if not merging and if 'QJn'</li>
+</ul>
+
+<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qinit">Top-level routines for initializing and terminating Qhull (in other modules)</a></h3>
+<ul>
+<li><a href="global.c#freebuild">qh_freebuild</a>
+free memory used by qh_initbuild and qh_buildhull
+</li>
+<li><a href="global.c#checkflags">qh_checkflags</a>
+check flags for multiple frontends to qhull
+<li><a href="global.c#freeqhull">qh_freeqhull</a>
+free memory used by qhull </li>
+<li><a href="global.c#init_A">qh_init_A</a> called
+before error handling initialized </li>
+<li><a href="global.c#init_B">qh_init_B</a> called
+after points are defined </li>
+<li><a href="global.c#initflags">qh_initflags</a> set
+flags and constants from command line </li>
+<li><a href="rboxlib.c#rboxpoints">qh_rboxpoints</a>
+generate points for qhull </li>
+<li><a href="global.c#restore_qhull">qh_restore_qhull</a>
+restores a saved qhull </li>
+<li><a href="global.c#save_qhull">qh_save_qhull</a>
+saves qhull for later restoring </li>
+<li><a href="user.c#user_memsizes">qh_user_memsizes</a>
+define additional quick allocation sizes
+</li>
+</ul>
+
+<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qin">Top-level routines for reading and modifying the input (in other modules)</a></h3>
+<ul>
+<li><a href="geom2.c#gram_schmidt">qh_gram_schmidt</a>
+implements Gram-Schmidt orthogonalization by rows </li>
+<li><a href="geom2.c#projectinput">qh_projectinput</a>
+project input along one or more dimensions +
+Delaunay projection </li>
+<li><a href="geom2.c#randommatrix">qh_randommatrix</a>
+generate a random dimXdim matrix in range (-1,1) </li>
+<li><a href="io.c#readpoints">qh_readpoints</a> read
+points from input </li>
+<li><a href="geom2.c#rotateinput">qh_rotateinput</a> rotate
+input points using row matrix </li>
+<li><a href="geom2.c#scaleinput">qh_scaleinput</a> scale
+input points using qh low_bound/high_bound </li>
+<li><a href="geom2.c#setdelaunay">qh_setdelaunay</a> project
+points to paraboloid for Delaunay triangulation </li>
+<li><a href="geom2.c#sethalfspace_all">qh_sethalfspace_all</a>
+generate dual for halfspace intersection with interior
+point </li>
+</ul>
+
+<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qcall">Top-level routines for calling Qhull (in other modules)</a></h3>
+<ul>
+<li><a href="libqhull.c#addpoint">qh_addpoint</a> add
+point to convex hull </li>
+<li><a href="poly2.c#findbestfacet">qh_findbestfacet</a>
+find facet that is furthest below a point </li>
+<li><a href="poly2.c#findfacet_all">qh_findfacet_all</a>
+exhaustive search for facet below a point </li>
+<li><a href="libqhull.c#qhull">qh_qhull</a> construct
+the convex hull of a set of points </li>
+</ul>
+
+<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qout">Top-level routines for returning results (in other modules)</a></h3>
+<ul>
+<li><a href="stat.c#collectstatistics">qh_collectstatistics</a>
+collect statistics for qh.facet_list </li>
+<li><a href="poly2.c#nearvertex">qh_nearvertex</a>
+return nearest vertex to point </li>
+<li><a href="poly2.c#point">qh_point</a> return point
+for a point ID </li>
+<li><a href="poly2.c#pointfacet">qh_pointfacet</a>
+return temporary set of facets indexed by point
+ID </li>
+<li><a href="poly.c#pointid">qh_pointid</a> return ID
+for a point</li>
+<li><a href="poly2.c#pointvertex">qh_pointvertex</a>
+return vertices (if any) for all points</li>
+<li><a href="stat.c#printallstatistics">qh_printallstatistics</a>
+print all statistics </li>
+<li><a href="io.c#printneighborhood">qh_printneighborhood</a>
+print neighborhood of one or two facets </li>
+<li><a href="libqhull.c#printsummary">qh_printsummary</a>
+print summary </li>
+<li><a href="io.c#produce_output">qh_produce_output</a>
+print the results of qh_qhull() </li>
+<li><a href="poly2.c#setvoronoi_all">qh_setvoronoi_all</a>
+compute Voronoi centers for all facets </li>
+</ul>
+
+<h3><a href="qh-qhull.htm#TOC">&#187;</a><a name="qtest">Top-level routines for testing and debugging (in other modules)</a></h3>
+<ul>
+<li><a href="io.c#dfacet">dfacet</a> print facet by
+ID from debugger </li>
+<li><a href="io.c#dvertex">dvertex</a> print vertex
+by ID from debugger </li>
+<li><a href="poly2.c#check_output">qh_check_output</a>
+check output </li>
+<li><a href="poly2.c#check_points">qh_check_points</a>
+verify that all points are inside the convex hull
+</li>
+<li><a href="user.c#errexit">qh_errexit</a> report
+error with a facet and a ridge</li>
+<li><a href="libqhull.c#errexit2">qh_errexit2</a> report
+error with two facets </li>
+<li><a href="user.c#errprint">qh_errprint</a> print
+erroneous facets, ridge, and vertex </li>
+<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
+print all fields for a list of facets </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
+<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
+&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
+&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
+&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
+&#149; <a href="qh-user.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull/qh-set.htm b/xs/src/qhull/src/libqhull/qh-set.htm
new file mode 100644
index 000000000..06e71bbc9
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qh-set.htm
@@ -0,0 +1,308 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>qset.c -- set data type and operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
+&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
+&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
+&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
+&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm">User</a>
+</p>
+<hr>
+
+<h2>qset.c -- set data type and operations</h2>
+<blockquote>
+<p>Qhull's data structures are constructed from sets. The
+functions and macros in qset.c construct, iterate, and
+modify these sets. They are the most frequently called
+functions in Qhull. For this reason, efficiency is the
+primary concern. </p>
+<p>In Qhull, a <i>set</i> is represented by an unordered
+array of pointers with a maximum size and a NULL
+terminator (<a href="qset.h#setT">setT</a>).
+Most sets correspond to mathematical sets
+(i.e., the pointers are unique). Some sets are sorted to
+enforce uniqueness. Some sets are ordered. For example,
+the order of vertices in a ridge determine the ridge's
+orientation. If you reverse the order of adjacent
+vertices, the orientation reverses. Some sets are not
+mathematical sets. They may be indexed as an array and
+they may include NULL pointers. </p>
+<p>The most common operation on a set is to iterate its
+members. This is done with a 'FOREACH...' macro. Each set
+has a custom macro. For example, 'FOREACHvertex_'
+iterates over a set of vertices. Each vertex is assigned
+to the variable 'vertex' from the pointer 'vertexp'. </p>
+<p>Most sets are constructed by appending elements to the
+set. The last element of a set is either NULL or the
+index of the terminating NULL for a partially full set.
+If a set is full, appending an element copies the set to
+a larger array. </p>
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a> &#149;
+<a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a> &#149;
+<a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <b>Set</b>
+&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="qset.c">qset.c</a> and
+<a href="qset.h">qset.h</a></h3>
+<ul>
+<li><a href="#stype">Data types and constants</a> </li>
+<li><a href="#seach">FOREACH macros</a> </li>
+<li><a href="#saccess">access and size macros</a> </li>
+<li><a href="#sint">internal macros</a> </li>
+<li><a href="#saddr">address macros</a><p>&nbsp;</li>
+
+<li><a href="#snew">Allocation and deallocation functions</a> </li>
+<li><a href="#spred">Access and predicate functions</a>
+</li>
+<li><a href="#sadd">Add functions</a> </li>
+<li><a href="#scheck">Check and print functions</a></li>
+<li><a href="#scopy">Copy, compact, and zero functions</a></li>
+<li><a href="#sdel">Delete functions</a> </li>
+<li><a href="#stemp">Temporary set functions</a> </li>
+</ul>
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="stype">Data types and
+constants</a></h3>
+<ul>
+<li><a href="qset.h#SETelemsize">SETelemsize</a> size
+of a set element in bytes </li>
+<li><a href="qset.h#setT">setT</a> a set with a
+maximum size and a current size</li>
+<li><a href="libqhull.h#qh-set">qh global sets</a>
+global sets for temporary sets, etc. </li>
+</ul>
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="seach">FOREACH macros</a></h3>
+<ul>
+<li><a href="qset.h#FOREACHelem_">FOREACHelem_</a>
+assign 'elem' to each element in a set </li>
+<li><a href="qset.h#FOREACHset_">FOREACHset_</a>
+assign 'set' to each set in a set of sets </li>
+<li><a href="qset.h#FOREACHsetelement_">FOREACHsetelement_</a>
+define a FOREACH iterator </li>
+<li><a href="qset.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+define an indexed FOREACH iterator </li>
+<li><a href="qset.h#FOREACHsetelementreverse_">FOREACHsetelementreverse_</a>
+define a reversed FOREACH iterator </li>
+<li><a href="qset.h#FOREACHsetelementreverse12_">FOREACHsetelementreverse12_</a>
+define a FOREACH iterator with e[1] and e[0]
+reversed </li>
+</ul>
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="saccess">Access and
+size macros</a></h3>
+<ul>
+<li><a href="qset.h#SETelem_">SETelem_</a> return the
+n'th element of set </li>
+<li><a href="qset.h#SETelemt_">SETelemt_</a> return
+the n'th element of set as a type</li>
+<li><a href="qset.h#SETempty_">SETempty_</a> return
+true (1) if set is empty </li>
+<li><a href="qset.h#SETfirst_">SETfirst_</a> return
+first element of set </li>
+<li><a href="qset.h#SETfirstt_">SETfirstt_</a> return
+first element of set as a type</li>
+<li><a href="qset.h#SETindex_">SETindex_</a> return
+index of elem in set </li>
+<li><a href="qset.h#SETreturnsize_">SETreturnsize_</a>
+return size of a set (normally use <a href="qset.c#setsize">qh_setsize</a>) </li>
+<li><a href="qset.h#SETsecond_">SETsecond_</a> return
+second element of set </li>
+<li><a href="qset.h#SETsecondt_">SETsecondt_</a>
+return second element of set as a type</li>
+<li><a href="qset.h#SETtruncate_">SETtruncate_</a>
+truncate set to size, i.e., qh_settruncate()</li>
+</ul>
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="sint">Internal macros</a></h3>
+<ul>
+<li><a href="qset.c#SETsizeaddr_">SETsizeaddr_</a>
+return pointer to end element of a set (indicates
+current size) </li>
+</ul>
+
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="saddr">address macros</a></h3>
+<ul>
+<li><a href="qset.h#SETaddr_">SETaddr_</a> return
+address of a set's elements </li>
+<li><a href="qset.h#SETelemaddr_">SETelemaddr_</a>
+return address of the n'th element of a set </li>
+<li><a href="qset.h#SETref_">SETref_</a> l.h.s. for
+modifying the current element in a FOREACH
+iteration </li>
+</ul>
+
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="snew">Allocation and
+deallocation functions</a></h3>
+<ul>
+<li><a href="qset.c#setfree">qh_setfree</a> free the
+space occupied by a set </li>
+<li><a href="qset.c#setfree2">qh_setfree2</a> free a
+set and its elements </li>
+<li><a href="qset.c#setfreelong">qh_setfreelong</a>
+free a set only if it is in long memory </li>
+<li><a href="qset.c#setnew">qh_setnew</a> create a new
+set </li>
+</ul>
+
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="spred">Access and
+predicate functions </a></h3>
+<ul>
+<li><a href="qset.c#setendpointer">qh_setendpointer</a> return
+pointer to NULL terminator of a set</li>
+<li><a href="qset.c#setequal">qh_setequal</a> return 1
+if two sorted sets are equal </li>
+<li><a href="qset.c#setequal_except">qh_setequal_except</a>
+return 1 if two sorted sets are equal except for
+an element </li>
+<li><a href="qset.c#setequal_skip">qh_setequal_skip</a>
+return 1 if two sorted sets are equal except for
+a pair of skipped elements </li>
+<li><a href="qset.c#setequal_skip">qh_setequal_skip</a>
+return 1 if two sorted sets are equal except for
+a pair of skipped elements </li>
+<li><a href="qset.c#setin">qh_setin</a> return 1 if an
+element is in a set </li>
+<li><a href="qset.c#setindex">qh_setindex</a> return
+the index of an element in a set </li>
+<li><a href="qset.c#setlast">qh_setlast</a> return
+last element of a set</li>
+<li><a href="qset.c#setsize">qh_setsize</a> returns
+the size of a set </li>
+</ul>
+
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="sadd">Add functions</a></h3>
+<ul>
+<li><a href="qset.c#setaddnth">qh_setaddnth</a> add a
+element as n'th element of sorted or unsorted set
+</li>
+<li><a href="qset.c#setaddsorted">qh_setaddsorted</a>
+add an element to a sorted set </li>
+<li><a href="qset.c#setappend">qh_setappend</a> append
+an element to a set </li>
+<li><a href="qset.c#setappend_set">qh_setappend_set</a>
+append a set of elements to a set </li>
+<li><a href="qset.c#setappend2ndlast">qh_setappend2ndlast</a>
+add an element as the next to the last element in
+a set </li>
+<li><a href="qset.c#setlarger">qh_setlarger</a> return
+a larger set with the same elements</li>
+<li><a href="qset.c#setreplace">qh_setreplace</a>
+replace one element with another in a set</li>
+<li><a href="qset.c#setunique">qh_setunique</a> add an
+element if it is not already in a set </li>
+</ul>
+
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="scheck">Check and print functions</a></h3>
+<ul>
+<li><a href="qset.c#setcheck">qh_setcheck</a> check a
+set for validity </li>
+<li><a href="qset.c#setprint">qh_setprint</a> print a
+set's elements to fp </li>
+</ul>
+
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="scopy">Copy, compact, and zero functions</a></h3>
+<ul>
+<li><a href="qset.c#setcompact">qh_setcompact</a>
+compact NULLs from an unsorted set </li>
+<li><a href="qset.c#setcopy">qh_setcopy</a> make a
+copy of a sorted or unsorted set </li>
+<li><a href="qset.c#setduplicate">qh_setduplicate</a>
+duplicate a set and its elements </li>
+<li><a href="qset.c#settruncate">qh_settruncate</a>
+truncate a set to size elements </li>
+<li><a href="qset.c#setzero">qh_setzero</a> zero the
+remainder of a set </li>
+</ul>
+
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="sdel">Delete functions</a></h3>
+<ul>
+<li><a href="qset.c#setdel">qh_setdel</a> delete an
+element from an unsorted set. </li>
+<li><a href="qset.c#setdellast">qh_setdellast</a>
+delete and return last element from a set</li>
+<li><a href="qset.c#setdelnth">qh_setdelnth</a> delete
+and return nth element from an unsorted set </li>
+<li><a href="qset.c#setdelnthsorted">qh_setdelnthsorted</a>
+delete and return nth element from a sorted set </li>
+<li><a href="qset.c#setdelsorted">qh_setdelsorted</a>
+delete an element from a sorted set </li>
+<li><a href="qset.c#setnew_delnthsorted">qh_setnew_delnthsorted</a>
+create a sorted set not containing the nth
+element </li>
+</ul>
+
+<h3><a href="qh-set.htm#TOC">&#187;</a><a name="stemp">Temporary set functions</a></h3>
+<ul>
+<li><a href="qset.c#settemp">qh_settemp</a> return a
+temporary set and append it qhmem.tempstack</li>
+<li><a href="qset.c#settempfree">qh_settempfree</a>
+free and pop a set from qhmem.tempstack</li>
+<li><a href="qset.c#settempfree_all">qh_settempfree_all</a>
+free all sets in qhmem.tempstack </li>
+<li><a href="qset.c#settemppop">qh_settemppop</a> pop
+a set from qhmem.tempstack (makes it permanent) </li>
+<li><a href="qset.c#settemppush">qh_settemppush</a>
+push a set unto qhmem.tempstack (makes it
+temporary) </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
+<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
+&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
+&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
+&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
+&#149; <a href="qh-user.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull/qh-stat.htm b/xs/src/qhull/src/libqhull/qh-stat.htm
new file mode 100644
index 000000000..b96854031
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qh-stat.htm
@@ -0,0 +1,163 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>stat.c -- statistical operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
+&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
+&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
+&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
+&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <a href="qh-user.htm">User</a>
+</p>
+<hr>
+
+<h2>stat.c -- statistical operations</h2>
+<blockquote>
+<p>Qhull records many statistics. These functions and
+macros make it inexpensive to add a statistic.
+<p>As with Qhull's global variables, the statistics data structure is
+accessed by a macro, 'qhstat'. If qh_QHpointer is defined, the macro
+is 'qh_qhstat->', otherwise the macro is 'qh_qhstat.'.
+Statistics
+may be turned off in user.h. If so, all but the 'zz'
+statistics are ignored.</p>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
+&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
+&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
+&#149; <b>Stat</b> &#149; <a href="qh-user.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="stat.c">stat.c</a> and
+<a href="stat.h">stat.h</a></h3>
+<ul>
+<li><a href="#ttype">stat.h types</a> </li>
+<li><a href="#tconst">stat.h constants</a> </li>
+<li><a href="#tmacro">stat.h macros</a> </li>
+<li><a href="#tfunc">stat.c functions</a> </li>
+</ul>
+
+<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="ttype">stat.h types</a></h3>
+<ul>
+<li><a href="stat.h#intrealT">intrealT</a> union of
+integer and real</li>
+<li><a href="stat.h#qhstat">qhstat</a> global data
+structure for statistics </li>
+</ul>
+<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="tconst">stat.h
+constants</a></h3>
+<ul>
+<li><a href="stat.h#KEEPstatistics">qh_KEEPstatistics</a> 0 turns off most statistics</li>
+<li><a href="stat.h#statistics">Z..., W...</a> integer (Z) and real (W) statistics
+</li>
+<li><a href="stat.h#ZZstat">ZZstat</a> Z.../W... statistics that
+remain defined if qh_KEEPstatistics=0
+</li>
+<li><a href="stat.h#ztype">ztype</a> zdoc, zinc, etc.
+for definining statistics </li>
+</ul>
+<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="tmacro">stat.h macros</a></h3>
+<ul>
+<li><a href="stat.h#MAYdebugx">MAYdebugx</a> called
+frequently for error trapping </li>
+<li><a href="stat.h#zadd_">zadd_/wadd_</a> add value
+to an integer or real statistic </li>
+<li><a href="stat.h#zdef_">zdef_</a> define a
+statistic </li>
+<li><a href="stat.h#zinc_">zinc_</a> increment an
+integer statistic </li>
+<li><a href="stat.h#zmax_">zmax_/wmax_</a> update
+integer or real maximum statistic </li>
+<li><a href="stat.h#zmin_">zmin_/wmin_</a> update
+integer or real minimum statistic </li>
+<li><a href="stat.h#zval_">zval_/wval_</a> set or
+return value of a statistic </li>
+</ul>
+
+<h3><a href="qh-stat.htm#TOC">&#187;</a><a name="tfunc">stat.c
+functions</a></h3>
+<ul>
+<li><a href="stat.c#allstatA">qh_allstatA</a> define
+statistics in groups of 20 </li>
+<li><a href="stat.c#allstatistics">qh_allstatistics</a>
+reset printed flag for all statistics </li>
+<li><a href="stat.c#collectstatistics">qh_collectstatistics</a>
+collect statistics for qh.facet_list </li>
+<li><a href="stat.c#freestatistics">qh_freestatistics</a>
+free memory used for statistics </li>
+<li><a href="stat.c#initstatistics">qh_initstatistics</a>
+allocate and initialize statistics </li>
+<li><a href="stat.c#newstats">qh_newstats</a> returns
+True if statistics for zdoc </li>
+<li><a href="stat.c#nostatistic">qh_nostatistic</a>
+true if no statistic to print </li>
+<li><a href="stat.c#printallstatistics">qh_printallstatistics</a>
+print all statistics </li>
+<li><a href="stat.c#printstatistics">qh_printstatistics</a>
+print statistics to a file </li>
+<li><a href="stat.c#printstatlevel">qh_printstatlevel</a>
+print level information for a statistic </li>
+<li><a href="stat.c#printstats">qh_printstats</a>
+print statistics for a zdoc group </li>
+<li><a href="stat.c#stddev">qh_stddev</a> compute the
+standard deviation and average from statistics </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
+<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
+&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
+&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
+&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
+&#149; <a href="qh-user.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull/qh-user.htm b/xs/src/qhull/src/libqhull/qh-user.htm
new file mode 100644
index 000000000..6682f4b2f
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qh-user.htm
@@ -0,0 +1,271 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>user.c -- user-definable operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149; <a href="qh-globa.htm">Global</a>
+&#149; <a href="qh-io.htm">Io</a> &#149; <a href="qh-mem.htm">Mem</a>
+&#149; <a href="qh-merge.htm">Merge</a> &#149; <a href="qh-poly.htm">Poly</a>
+&#149; <a href="qh-qhull.htm">Qhull</a> &#149; <a href="qh-set.htm">Set</a>
+&#149; <a href="qh-stat.htm">Stat</a> &#149; <a href="qh-user.htm#TOC">User</a>
+</p>
+<hr>
+<h2>user.c -- user-definable operations</h2>
+<blockquote>
+<p>This section contains functions and constants that the
+user may want to change. </p>
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa.htm#TOC">Global</a>
+&#149; <a href="qh-io.htm#TOC">Io</a> &#149; <a href="qh-mem.htm#TOC">Mem</a>
+&#149; <a href="qh-merge.htm#TOC">Merge</a> &#149; <a href="qh-poly.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull.htm#TOC">Qhull</a> &#149; <a href="qh-set.htm#TOC">Set</a>
+&#149; <a href="qh-stat.htm#TOC">Stat</a> &#149; <b>User</b>
+</p>
+<h3>Index to <a href="user.c">user.c</a>, <a href="usermem.c">usermem.c</a>, <a href="userprintf.c">userprintf.c</a>, <a href="userprintf_rbox.c">userprintf_rbox.c</a> and
+<a href="user.h">user.h</a></h3>
+<ul>
+<li><a href="#qulllib">qhull library constants</a></li>
+<li><a href="#utype">user.h data types and
+configuration macros</a> </li>
+<li><a href="#ujoggle">joggle constants</a></li>
+<li><a href="#uperform">performance related constants</a></li>
+<li><a href="#umemory">memory constants</a></li>
+<li><a href="#ucond">conditional compilation</a></li>
+<li><a href="#umerge">merge constants</a> </li>
+<li><a href="#ufunc">user.c functions</a> </li>
+<li><a href="#u2func">usermem.c functions</a> </li>
+<li><a href="#u3func">userprintf.c functions</a> </li>
+</ul>
+
+<h3><a href="qh-user.htm#TOC">&#187;</a><a name="qulllib">Qhull library constants</a></h3>
+<ul>
+<li><a href="user.h#filenamelen">FILENAMElen</a> -- max length of TI or TO filename </li>
+<li><a href="user.h#msgcode">msgcode</a> -- unique message codes for qh_fprintf </li>
+<li><a href="user.h#qh_OPTIONline">qh_OPTIONline</a> -- max length of option line ('FO')</li>
+</ul>
+
+
+<h3><a href="qh-user.htm#TOC">&#187;</a><a name="utype">user.h data
+types and configuration macros</a></h3>
+<ul>
+<li><a href="user.h#realT">realT, qh_REAL...</a> size
+of floating point numbers </li>
+<li><a href="user.h#countT">countT, COUNTmax</a> size
+of counts and identifiers, typically 'int' or 'long long' </li>
+<li><a href="user.h#CPUclock">qh_CPUclock</a> clock()
+function for reporting the total time spent by
+Qhull </li>
+<li><a href="user.h#RANDOM">qh_RANDOM...</a> random
+number generator </li>
+</ul>
+
+<h3><a href="qh-user.htm#TOC">&#187;</a><a name="udef">definition constants</a></h3>
+<ul>
+<li><a href="user.h#DEFAULTbox">qh_DEFAULTbox</a>
+define default box size for rbox, 'Qbb', and 'QbB' (Geomview expects 0.5) </li>
+<li><a href="user.h#INFINITE">qh_INFINITE</a> on
+output, indicates Voronoi center at infinity </li>
+<li><a href="user.h#ORIENTclock">qh_ORIENTclock</a>
+define convention for orienting facets</li>
+<li><a href="user.h#ZEROdelaunay">qh_ZEROdelaunay</a>
+define facets that are ignored in Delaunay triangulations</li>
+</ul>
+
+<h3><a href="qh-user.htm#TOC">&#187;</a><a name="ujoggle">joggle constants</a></h3>
+<ul>
+<li><a href="user.h#JOGGLEagain">qh_JOGGLEagain</a>
+how often to retry before using qh_JOGGLEmaxincrease
+again </li>
+<li><a href="user.h#JOGGLEdefault">qh_JOGGLEdefault</a>
+default value for qh.JOGGLEmax for 'QP' </li>
+<li><a href="user.h#JOGGLEincrease">qh_JOGGLEincrease</a>
+factor to increase qh.JOGGLEmax on retrys for
+'QPn' </li>
+<li><a href="user.h#JOGGLEmaxincrease">qh_JOGGLEmaxincrease</a> max
+for increasing qh.JOGGLEmax relative to
+qh.MAXwidth </li>
+<li><a href="user.h#JOGGLEretry">qh_JOGGLEmaxretry</a>
+report error if this many retries </li>
+<li><a href="user.h#JOGGLEretry">qh_JOGGLEretry</a>
+how often to retry before using qh_JOGGLEmax </li>
+</ul>
+
+<h3><a href="qh-user.htm#TOC">&#187;</a><a name="uperform">performance
+related constants</a></h3>
+<ul>
+<li><a href="user.h#HASHfactor">qh_HASHfactor</a>
+total/used hash slots </li>
+<li><a href="user.h#INITIALmax">qh_INITIALmax</a> if
+dim &gt;= qh_INITIALmax, use min/max coordinate
+points for initial simplex </li>
+<li><a href="user.h#INITIALsearch">qh_INITIALsearch</a>
+if qh.INITIALmax, search points up to this
+dimension </li>
+<li><a href="user.h#NOtrace">qh_NOtrace</a> disallow
+tracing </li>
+<li><a href="user.h#VERIFYdirect">qh_VERIFYdirect</a>
+'Tv' verifies all <em>points X facets</em> if op
+count is smaller </li>
+</ul>
+
+<h3><a href="qh-user.htm#TOC">&#187;</a><a name="umemory">memory constants</a></h3>
+<ul>
+<li><a href="user.h#MEMalign">qh_MEMalign</a> memory
+alignment for qh_meminitbuffers() in global.c </li>
+<li><a href="user.h#MEMbufsize">qh_MEMbufsize</a>
+size of additional memory buffers </li>
+<li><a href="user.h#MEMinitbuf">qh_MEMinitbuf</a>
+size of initial memory buffer </li>
+</ul>
+
+<h3><a href="qh-user.htm#TOC">&#187;</a><a name="ucond">conditional compilation</a></h3>
+<ul>
+<li><a href="user.h#compiler">compiler</a> defined symbols,
+e.g., _STDC_ and _cplusplus
+
+<li><a href="user.h#COMPUTEfurthest">qh_COMPUTEfurthest</a>
+ compute furthest distance to an outside point instead of storing it with the facet
+<li><a href="user.h#KEEPstatistics">qh_KEEPstatistics</a>
+ enable statistic gathering and reporting with option 'Ts'
+<li><a href="user.h#MAXoutside">qh_MAXoutside</a>
+record outer plane for each facet
+<li><a href="user.h#NOmerge">qh_NOmerge</a>
+disable facet merging
+<li><a href="user.h#NOtrace">qh_NOtrace</a>
+disable tracing with option 'T4'
+<li><a href="user.h#QHpointer">qh_QHpointer</a>
+access global data with pointer or static structure
+<li><a href="user.h#QUICKhelp">qh_QUICKhelp</a>
+use abbreviated help messages, e.g., for degenerate inputs
+</ul>
+
+<h3><a href="qh-user.htm#TOC">&#187;</a><a name="umerge">merge
+constants</a></h3>
+<ul>
+<li><a href="user.h#BESTcentrum">qh_BESTcentrum</a>
+when does qh_findbestneighbor() test centrums? </li>
+<li><a href="user.h#BESTnonconvex">qh_BESTnonconvex</a>
+when does qh_findbestneighbor() test nonconvex
+ridges only? </li>
+<li><a href="user.h#COPLANARratio">qh_COPLANARratio</a>
+what is qh.MINvisible? </li>
+<li><a href="user.h#DIMreduceBuild">qh_DIMreduceBuild</a>
+max dimension for vertex reduction </li>
+<li><a href="user.h#DIMmergeVertex">qh_DIMmergeVertex</a>
+max dimension for vertex merging </li>
+<li><a href="user.h#DISToutside">qh_DISToutside</a>
+when is a point clearly outside of a facet for qh_findbestnew and qh_partitionall</li>
+<li><a href="user.h#MAXnarrow">qh_MAXnarrow</a> max.
+cosine for qh.NARROWhull </li>
+<li><a href="user.h#MAXnewcentrum">qh_MAXnewcentrum</a>
+when does qh_reducevertices_centrum() reset the
+centrum? </li>
+<li><a href="user.h#MAXnewmerges">qh_MAXnewmerges</a>
+when does qh_merge_nonconvex() call
+qh_reducevertices_centrums? </li>
+<li><a href="user.h#RATIOnearinside">qh_RATIOnearinside</a>
+ratio for retaining inside points for
+qh_check_maxout() </li>
+<li><a href="user.h#SEARCHdist">qh_SEARCHdist</a>
+when is facet coplanar with the best facet for qh_findbesthorizon</li>
+<li><a href="user.h#USEfindbestnew">qh_USEfindbestnew</a>
+when to use qh_findbestnew for qh_partitionpoint()</li>
+<li><a href="user.h#WARNnarrow">qh_WARNnarrow</a>
+max. cosine to warn about qh.NARROWhull </li>
+<li><a href="user.h#WIDEcoplanar">qh_WIDEcoplanar</a>
+what is a wide facet? </li>
+<li><a href="user.h#WIDEduplicate">qh_WIDEduplicate</a>
+what is a wide ratio on merging duplicate ridges? </li>
+</ul>
+
+<h3><a href="qh-user.htm#TOC">&#187;</a><a name="ufunc">user.c
+functions</a></h3>
+<ul>
+<li><a href="user.c#qhull_template">Qhull template</a> for calling qh_new_qhull from your program</li>
+<li><a href="user.c#errexit">qh_errexit</a> report
+error and exit qhull()</li>
+<li><a href="user.c#errprint">qh_errprint</a> print
+information about facets and ridges </li>
+<li><a href="user.c#new_qhull">qh_new_qhull</a> call qhull on an array
+of points</li>
+<li><a href="user.c#printfacetlist">qh_printfacetlist</a>
+print all fields of all facets </li>
+</ul>
+
+<h3><a href="qh-user.htm#TOC">&#187;</a><a name="u2func">usermem.c
+functions</a></h3>
+<ul>
+<li><a href="usermem.c#qh_exit">qh_exit</a> exit program, same as exit(). May be redefined as throw "QH10003.." by libqhullcpp/usermem_r-cpp.cpp</li>
+<li><a href="usermem.c#qh_fprintf_stderr">qh_fprintf_stderr</a> print to stderr when qh.ferr is not defined.</li>
+<li><a href="usermem.c#qh_free">qh_free</a> free memory, same as free().</li>
+<li><a href="usermem.c#qh_malloc">qh_malloc</a> allocate memory, same as malloc()</li>
+</ul>
+
+<h3><a href="qh-user.htm#TOC">&#187;</a><a name="u3func">userprintf.c
+ and userprintf_rbox,c functions</a></h3>
+<ul>
+<li><a href="userprintf.c#qh_fprintf">qh_fprintf</a> print
+information from Qhull, sames as fprintf(). </li>
+<li><a href="userprintf_rbox.c#qh_fprintf_rbox">qh_fprintf_rbox</a> print
+information from Rbox, sames as fprintf(). </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom.htm">Geom</a> &#149;
+<a href="qh-globa.htm">Global</a> &#149; <a href="qh-io.htm">Io</a>
+&#149; <a href="qh-mem.htm">Mem</a> &#149; <a href="qh-merge.htm">Merge</a>
+&#149; <a href="qh-poly.htm">Poly</a> &#149; <a href="qh-qhull.htm#TOC">Qhull</a>
+&#149; <a href="qh-set.htm">Set</a> &#149; <a href="qh-stat.htm">Stat</a>
+&#149; <a href="qh-user.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull/qhull-exports.def b/xs/src/qhull/src/libqhull/qhull-exports.def
new file mode 100644
index 000000000..11a42b57e
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qhull-exports.def
@@ -0,0 +1,417 @@
+; qhull-exports.def -- msvc module-definition file
+;
+; Generated from depends.exe by cut-and-paste of exported symbols by mingw gcc
+; [mar'11] 399 symbols
+; Annotate as DATA qh_last_random qh_qh qh_qhstat qhmem rbox rbox_inuse
+; Annotate as __declspec for outside access in win32 -- qh_qh qh_qhstat
+; Same as ../libqhullp/qhull_p-exports.def without qh_save_qhull and qh_restore_qhull
+;
+; $Id: //main/2015/qhull/src/libqhull/qhull-exports.def#3 $$Change: 2047 $
+; $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $
+;
+; Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, and qhull-warn.pri
+VERSION 7.0
+EXPORTS
+qh_addhash
+qh_addpoint
+qh_all_merges
+qh_allstatA
+qh_allstatB
+qh_allstatC
+qh_allstatD
+qh_allstatE
+qh_allstatE2
+qh_allstatF
+qh_allstatG
+qh_allstatH
+qh_allstatI
+qh_allstatistics
+qh_appendfacet
+qh_appendmergeset
+qh_appendprint
+qh_appendvertex
+qh_argv_to_command
+qh_argv_to_command_size
+qh_attachnewfacets
+qh_backnormal
+qh_basevertices
+qh_build_withrestart
+qh_buildhull
+qh_buildtracing
+qh_check_bestdist
+qh_check_dupridge
+qh_check_maxout
+qh_check_output
+qh_check_point
+qh_check_points
+qh_checkconnect
+qh_checkconvex
+qh_checkfacet
+qh_checkflags
+qh_checkflipped
+qh_checkflipped_all
+qh_checkpolygon
+qh_checkvertex
+qh_checkzero
+qh_clear_outputflags
+qh_clearcenters
+qh_clock
+qh_collectstatistics
+qh_compare_facetarea
+qh_compare_facetmerge
+qh_compare_facetvisit
+qh_compare_vertexpoint
+qh_compareangle
+qh_comparemerge
+qh_comparevisit
+qh_copyfilename
+qh_copynonconvex
+qh_copypoints
+qh_countfacets
+qh_createsimplex
+qh_crossproduct
+qh_degen_redundant_facet
+qh_degen_redundant_neighbors
+qh_deletevisible
+qh_delfacet
+qh_delridge
+qh_delvertex
+qh_determinant
+qh_detjoggle
+qh_detroundoff
+qh_detsimplex
+qh_detvnorm
+qh_detvridge
+qh_detvridge3
+qh_dfacet
+qh_distnorm
+qh_distplane
+qh_distround
+qh_divzero
+qh_dvertex
+qh_eachvoronoi
+qh_eachvoronoi_all
+qh_errexit
+qh_errexit2
+qh_errexit_rbox
+qh_errprint
+qh_exit
+qh_facet2point
+qh_facet3vertex
+qh_facetarea
+qh_facetarea_simplex
+qh_facetcenter
+qh_facetintersect
+qh_facetvertices
+qh_find_newvertex
+qh_findbest
+qh_findbest_test
+qh_findbestfacet
+qh_findbesthorizon
+qh_findbestlower
+qh_findbestneighbor
+qh_findbestnew
+qh_findfacet_all
+qh_findgood
+qh_findgood_all
+qh_findgooddist
+qh_findhorizon
+qh_flippedmerges
+qh_forcedmerges
+qh_fprintf
+qh_fprintf_rbox
+qh_fprintf_stderr
+qh_free
+qh_freebuffers
+qh_freebuild
+qh_freeqhull
+qh_freeqhull2
+qh_freestatistics
+qh_furthestnext
+qh_furthestout
+qh_gausselim
+qh_geomplanes
+qh_getangle
+qh_getarea
+qh_getcenter
+qh_getcentrum
+qh_getdistance
+qh_gethash
+qh_getmergeset
+qh_getmergeset_initial
+qh_gram_schmidt
+qh_hashridge
+qh_hashridge_find
+qh_infiniteloop
+qh_init_A
+qh_init_B
+qh_init_qhull_command
+qh_initbuild
+qh_initflags
+qh_initialhull
+qh_initialvertices
+qh_initqhull_buffers
+qh_initqhull_globals
+qh_initqhull_mem
+qh_initqhull_outputflags
+qh_initqhull_start
+qh_initqhull_start2
+qh_initstatistics
+qh_initthresholds
+qh_inthresholds
+qh_isvertex
+qh_joggleinput
+; Mark as DATA, otherwise links a separate qh_last_random. No __declspec.
+qh_last_random DATA
+qh_lib_check
+qh_makenew_nonsimplicial
+qh_makenew_simplicial
+qh_makenewfacet
+qh_makenewfacets
+qh_makenewplanes
+qh_makeridges
+qh_malloc
+qh_mark_dupridges
+qh_markkeep
+qh_markvoronoi
+qh_matchduplicates
+qh_matchneighbor
+qh_matchnewfacets
+qh_matchvertices
+qh_maxabsval
+qh_maxmin
+qh_maxouter
+qh_maxsimplex
+qh_maydropneighbor
+qh_memalloc
+qh_memfree
+qh_memfreeshort
+qh_meminit
+qh_meminitbuffers
+qh_memsetup
+qh_memsize
+qh_memstatistics
+qh_memtotal
+qh_merge_degenredundant
+qh_merge_nonconvex
+qh_mergecycle
+qh_mergecycle_all
+qh_mergecycle_facets
+qh_mergecycle_neighbors
+qh_mergecycle_ridges
+qh_mergecycle_vneighbors
+qh_mergefacet
+qh_mergefacet2d
+qh_mergeneighbors
+qh_mergeridges
+qh_mergesimplex
+qh_mergevertex_del
+qh_mergevertex_neighbors
+qh_mergevertices
+qh_minabsval
+qh_mindiff
+qh_nearcoplanar
+qh_nearvertex
+qh_neighbor_intersections
+qh_new_qhull
+qh_newfacet
+qh_newhashtable
+qh_newridge
+qh_newstats
+qh_newvertex
+qh_newvertices
+qh_nextfurthest
+qh_nextridge3d
+qh_normalize
+qh_normalize2
+qh_nostatistic
+qh_option
+qh_order_vertexneighbors
+qh_orientoutside
+qh_out1
+qh_out2n
+qh_out3n
+qh_outcoplanar
+qh_outerinner
+qh_partitionall
+qh_partitioncoplanar
+qh_partitionpoint
+qh_partitionvisible
+qh_point
+qh_point_add
+qh_pointdist
+qh_pointfacet
+qh_pointid
+qh_pointvertex
+qh_postmerge
+qh_precision
+qh_premerge
+qh_prepare_output
+qh_prependfacet
+qh_printafacet
+qh_printallstatistics
+qh_printbegin
+qh_printcenter
+qh_printcentrum
+qh_printend
+qh_printend4geom
+qh_printextremes
+qh_printextremes_2d
+qh_printextremes_d
+qh_printfacet
+qh_printfacet2geom
+qh_printfacet2geom_points
+qh_printfacet2math
+qh_printfacet3geom_nonsimplicial
+qh_printfacet3geom_points
+qh_printfacet3geom_simplicial
+qh_printfacet3math
+qh_printfacet3vertex
+qh_printfacet4geom_nonsimplicial
+qh_printfacet4geom_simplicial
+qh_printfacetNvertex_nonsimplicial
+qh_printfacetNvertex_simplicial
+qh_printfacetheader
+qh_printfacetlist
+qh_printfacetridges
+qh_printfacets
+qh_printhashtable
+qh_printhelp_degenerate
+qh_printhelp_narrowhull
+qh_printhelp_singular
+qh_printhyperplaneintersection
+qh_printline3geom
+qh_printlists
+qh_printmatrix
+qh_printneighborhood
+qh_printpoint
+qh_printpoint3
+qh_printpointid
+qh_printpoints
+qh_printpoints_out
+qh_printpointvect
+qh_printpointvect2
+qh_printridge
+qh_printspheres
+qh_printstatistics
+qh_printstatlevel
+qh_printstats
+qh_printsummary
+qh_printvdiagram
+qh_printvdiagram2
+qh_printvertex
+qh_printvertexlist
+qh_printvertices
+qh_printvneighbors
+qh_printvnorm
+qh_printvoronoi
+qh_printvridge
+qh_produce_output
+qh_produce_output2
+qh_projectdim3
+qh_projectinput
+qh_projectpoint
+qh_projectpoints
+; Mark as DATA, otherwise links a separate qh_qh. qh_qh and qh_qhstat requires __declspec
+qh_qh DATA
+qh_qhstat DATA
+qh_qhull
+qh_rand
+qh_randomfactor
+qh_randommatrix
+qh_rboxpoints
+qh_readfeasible
+qh_readpoints
+qh_reducevertices
+qh_redundant_vertex
+qh_remove_extravertices
+qh_removefacet
+qh_removevertex
+qh_rename_sharedvertex
+qh_renameridgevertex
+qh_renamevertex
+qh_resetlists
+qh_rotateinput
+qh_rotatepoints
+qh_roundi
+qh_scaleinput
+qh_scalelast
+qh_scalepoints
+qh_setaddnth
+qh_setaddsorted
+qh_setappend
+qh_setappend2ndlast
+qh_setappend_set
+qh_setcheck
+qh_setcompact
+qh_setcopy
+qh_setdel
+qh_setdelaunay
+qh_setdellast
+qh_setdelnth
+qh_setdelnthsorted
+qh_setdelsorted
+qh_setduplicate
+qh_setequal
+qh_setequal_except
+qh_setequal_skip
+qh_setfacetplane
+qh_setfeasible
+qh_setfree
+qh_setfree2
+qh_setfreelong
+qh_sethalfspace
+qh_sethalfspace_all
+qh_sethyperplane_det
+qh_sethyperplane_gauss
+qh_setin
+qh_setindex
+qh_setlarger
+qh_setlast
+qh_setnew
+qh_setnew_delnthsorted
+qh_setprint
+qh_setreplace
+qh_setsize
+qh_settemp
+qh_settempfree
+qh_settempfree_all
+qh_settemppop
+qh_settemppush
+qh_settruncate
+qh_setunique
+qh_setvoronoi_all
+qh_setzero
+qh_sharpnewfacets
+qh_skipfacet
+qh_skipfilename
+qh_srand
+qh_stddev
+qh_strtod
+qh_strtol
+qh_test_appendmerge
+qh_test_vneighbors
+qh_tracemerge
+qh_tracemerging
+qh_triangulate
+qh_triangulate_facet
+qh_triangulate_link
+qh_triangulate_mirror
+qh_triangulate_null
+qh_updatetested
+qh_updatevertices
+qh_user_memsizes
+qh_version
+qh_version2
+qh_vertexintersect
+qh_vertexintersect_new
+qh_vertexneighbors
+qh_vertexridges
+qh_vertexridges_facet
+qh_vertexsubset
+qh_voronoi_center
+qh_willdelete
+; Mark as DATA, otherwise links a separate qhmem. No __declspec
+qhmem DATA
+rbox DATA
+rbox_inuse DATA
diff --git a/xs/src/qhull/src/libqhull/qhull_a.h b/xs/src/qhull/src/libqhull/qhull_a.h
new file mode 100644
index 000000000..729b72327
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qhull_a.h
@@ -0,0 +1,150 @@
+/*<html><pre> -<a href="qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qhull_a.h
+ all header files for compiling qhull with non-reentrant code
+ included before C++ headers for user_r.h:QHULL_CRTDBG
+
+ see qh-qhull.htm
+
+ see libqhull.h for user-level definitions
+
+ see user.h for user-definable constants
+
+ defines internal functions for libqhull.c global.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/qhull_a.h#4 $$Change: 2064 $
+ $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
+
+ Notes: grep for ((" and (" to catch fprintf("lkasdjf");
+ full parens around (x?y:z)
+ use '#include "libqhull/qhull_a.h"' to avoid name clashes
+*/
+
+#ifndef qhDEFqhulla
+#define qhDEFqhulla 1
+
+#include "libqhull.h" /* Includes user_r.h and data types */
+
+#include "stat.h"
+#include "random.h"
+#include "mem.h"
+#include "qset.h"
+#include "geom.h"
+#include "merge.h"
+#include "poly.h"
+#include "io.h"
+
+#include <setjmp.h>
+#include <string.h>
+#include <math.h>
+#include <float.h> /* some compilers will not need float.h */
+#include <limits.h>
+#include <time.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+/*** uncomment here and qset.c
+ if string.h does not define memcpy()
+#include <memory.h>
+*/
+
+#if qh_CLOCKtype == 2 /* defined in user.h from libqhull.h */
+#include <sys/types.h>
+#include <sys/times.h>
+#include <unistd.h>
+#endif
+
+#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
+#pragma warning( disable : 4100) /* unreferenced formal parameter */
+#pragma warning( disable : 4127) /* conditional expression is constant */
+#pragma warning( disable : 4706) /* assignment within conditional function */
+#pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
+#endif
+
+/* ======= -macros- =========== */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >--------------------------------</a><a name="traceN">-</a>
+
+ traceN((qh ferr, 0Nnnn, "format\n", vars));
+ calls qh_fprintf if qh.IStracing >= N
+
+ Add debugging traps to the end of qh_fprintf
+
+ notes:
+ removing tracing reduces code size but doesn't change execution speed
+*/
+#ifndef qh_NOtrace
+#define trace0(args) {if (qh IStracing) qh_fprintf args;}
+#define trace1(args) {if (qh IStracing >= 1) qh_fprintf args;}
+#define trace2(args) {if (qh IStracing >= 2) qh_fprintf args;}
+#define trace3(args) {if (qh IStracing >= 3) qh_fprintf args;}
+#define trace4(args) {if (qh IStracing >= 4) qh_fprintf args;}
+#define trace5(args) {if (qh IStracing >= 5) qh_fprintf args;}
+#else /* qh_NOtrace */
+#define trace0(args) {}
+#define trace1(args) {}
+#define trace2(args) {}
+#define trace3(args) {}
+#define trace4(args) {}
+#define trace5(args) {}
+#endif /* qh_NOtrace */
+
+/*-<a href="qh-qhull.htm#TOC"
+ >--------------------------------</a><a name="QHULL_UNUSED">-</a>
+
+ Define an unused variable to avoid compiler warnings
+
+ Derived from Qt's corelib/global/qglobal.h
+
+*/
+
+#if defined(__cplusplus) && defined(__INTEL_COMPILER) && !defined(QHULL_OS_WIN)
+template <typename T>
+inline void qhullUnused(T &x) { (void)x; }
+# define QHULL_UNUSED(x) qhullUnused(x);
+#else
+# define QHULL_UNUSED(x) (void)x;
+#endif
+
+/***** -libqhull.c prototypes (alphabetical after qhull) ********************/
+
+void qh_qhull(void);
+boolT qh_addpoint(pointT *furthest, facetT *facet, boolT checkdist);
+void qh_buildhull(void);
+void qh_buildtracing(pointT *furthest, facetT *facet);
+void qh_build_withrestart(void);
+void qh_errexit2(int exitcode, facetT *facet, facetT *otherfacet);
+void qh_findhorizon(pointT *point, facetT *facet, int *goodvisible,int *goodhorizon);
+pointT *qh_nextfurthest(facetT **visible);
+void qh_partitionall(setT *vertices, pointT *points,int npoints);
+void qh_partitioncoplanar(pointT *point, facetT *facet, realT *dist);
+void qh_partitionpoint(pointT *point, facetT *facet);
+void qh_partitionvisible(boolT allpoints, int *numpoints);
+void qh_precision(const char *reason);
+void qh_printsummary(FILE *fp);
+
+/***** -global.c internal prototypes (alphabetical) ***********************/
+
+void qh_appendprint(qh_PRINT format);
+void qh_freebuild(boolT allmem);
+void qh_freebuffers(void);
+void qh_initbuffers(coordT *points, int numpoints, int dim, boolT ismalloc);
+
+/***** -stat.c internal prototypes (alphabetical) ***********************/
+
+void qh_allstatA(void);
+void qh_allstatB(void);
+void qh_allstatC(void);
+void qh_allstatD(void);
+void qh_allstatE(void);
+void qh_allstatE2(void);
+void qh_allstatF(void);
+void qh_allstatG(void);
+void qh_allstatH(void);
+void qh_freebuffers(void);
+void qh_initbuffers(coordT *points, int numpoints, int dim, boolT ismalloc);
+
+#endif /* qhDEFqhulla */
diff --git a/xs/src/qhull/src/libqhull/qhull_p-exports.def b/xs/src/qhull/src/libqhull/qhull_p-exports.def
new file mode 100644
index 000000000..cadf8a4fa
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qhull_p-exports.def
@@ -0,0 +1,418 @@
+; qhull_p-exports.def -- msvc module-definition file
+;
+; Generated from depends.exe by cut-and-paste of exported symbols by mingw gcc
+; [mar'11] 399 symbols [jan'15] added 3 symbols
+; Annotate as DATA qh_last_random qh_qh qh_qhstat qhmem rbox rbox_inuse
+; Annotate as __declspec for outside access in win32 -- qh_qh qh_qhstat
+;
+; $Id: //main/2011/qhull/src/libqhull/qhull-exports.def#2 $$Change: 1368 $
+; $DateTime: 2011/04/16 08:12:32 $$Author: bbarber $
+;
+; Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, and qhull-warn.pri
+VERSION 7.0
+EXPORTS
+qh_addhash
+qh_addpoint
+qh_all_merges
+qh_allstatA
+qh_allstatB
+qh_allstatC
+qh_allstatD
+qh_allstatE
+qh_allstatE2
+qh_allstatF
+qh_allstatG
+qh_allstatH
+qh_allstatI
+qh_allstatistics
+qh_appendfacet
+qh_appendmergeset
+qh_appendprint
+qh_appendvertex
+qh_argv_to_command
+qh_argv_to_command_size
+qh_attachnewfacets
+qh_backnormal
+qh_basevertices
+qh_build_withrestart
+qh_buildhull
+qh_buildtracing
+qh_check_bestdist
+qh_check_dupridge
+qh_check_maxout
+qh_check_output
+qh_check_point
+qh_check_points
+qh_checkconnect
+qh_checkconvex
+qh_checkfacet
+qh_checkflags
+qh_checkflipped
+qh_checkflipped_all
+qh_checkpolygon
+qh_checkvertex
+qh_checkzero
+qh_clear_outputflags
+qh_clearcenters
+qh_clock
+qh_collectstatistics
+qh_compare_facetarea
+qh_compare_facetmerge
+qh_compare_facetvisit
+qh_compare_vertexpoint
+qh_compareangle
+qh_comparemerge
+qh_comparevisit
+qh_copyfilename
+qh_copynonconvex
+qh_copypoints
+qh_countfacets
+qh_createsimplex
+qh_crossproduct
+qh_degen_redundant_facet
+qh_degen_redundant_neighbors
+qh_deletevisible
+qh_delfacet
+qh_delridge
+qh_delvertex
+qh_determinant
+qh_detjoggle
+qh_detroundoff
+qh_detsimplex
+qh_detvnorm
+qh_detvridge
+qh_detvridge3
+qh_dfacet
+qh_distnorm
+qh_distplane
+qh_distround
+qh_divzero
+qh_dvertex
+qh_eachvoronoi
+qh_eachvoronoi_all
+qh_errexit
+qh_errexit2
+qh_errexit_rbox
+qh_errprint
+qh_exit
+qh_facet2point
+qh_facet3vertex
+qh_facetarea
+qh_facetarea_simplex
+qh_facetcenter
+qh_facetintersect
+qh_facetvertices
+qh_find_newvertex
+qh_findbest
+qh_findbest_test
+qh_findbestfacet
+qh_findbesthorizon
+qh_findbestlower
+qh_findbestneighbor
+qh_findbestnew
+qh_findfacet_all
+qh_findgood
+qh_findgood_all
+qh_findgooddist
+qh_findhorizon
+qh_flippedmerges
+qh_forcedmerges
+qh_fprintf
+qh_fprintf_rbox
+qh_fprintf_stderr
+qh_free
+qh_freebuffers
+qh_freebuild
+qh_freeqhull
+qh_freeqhull2
+qh_freestatistics
+qh_furthestnext
+qh_furthestout
+qh_gausselim
+qh_geomplanes
+qh_getangle
+qh_getarea
+qh_getcenter
+qh_getcentrum
+qh_getdistance
+qh_gethash
+qh_getmergeset
+qh_getmergeset_initial
+qh_gram_schmidt
+qh_hashridge
+qh_hashridge_find
+qh_infiniteloop
+qh_init_A
+qh_init_B
+qh_init_qhull_command
+qh_initbuild
+qh_initflags
+qh_initialhull
+qh_initialvertices
+qh_initqhull_buffers
+qh_initqhull_globals
+qh_initqhull_mem
+qh_initqhull_outputflags
+qh_initqhull_start
+qh_initqhull_start2
+qh_initstatistics
+qh_initthresholds
+qh_inthresholds
+qh_isvertex
+qh_joggleinput
+; Mark as DATA, otherwise links a separate qh_last_random. No __declspec.
+qh_last_random DATA
+qh_lib_check
+qh_makenew_nonsimplicial
+qh_makenew_simplicial
+qh_makenewfacet
+qh_makenewfacets
+qh_makenewplanes
+qh_makeridges
+qh_malloc
+qh_mark_dupridges
+qh_markkeep
+qh_markvoronoi
+qh_matchduplicates
+qh_matchneighbor
+qh_matchnewfacets
+qh_matchvertices
+qh_maxabsval
+qh_maxmin
+qh_maxouter
+qh_maxsimplex
+qh_maydropneighbor
+qh_memalloc
+qh_memfree
+qh_memfreeshort
+qh_meminit
+qh_meminitbuffers
+qh_memsetup
+qh_memsize
+qh_memstatistics
+qh_memtotal
+qh_merge_degenredundant
+qh_merge_nonconvex
+qh_mergecycle
+qh_mergecycle_all
+qh_mergecycle_facets
+qh_mergecycle_neighbors
+qh_mergecycle_ridges
+qh_mergecycle_vneighbors
+qh_mergefacet
+qh_mergefacet2d
+qh_mergeneighbors
+qh_mergeridges
+qh_mergesimplex
+qh_mergevertex_del
+qh_mergevertex_neighbors
+qh_mergevertices
+qh_minabsval
+qh_mindiff
+qh_nearcoplanar
+qh_nearvertex
+qh_neighbor_intersections
+qh_new_qhull
+qh_newfacet
+qh_newhashtable
+qh_newridge
+qh_newstats
+qh_newvertex
+qh_newvertices
+qh_nextfurthest
+qh_nextridge3d
+qh_normalize
+qh_normalize2
+qh_nostatistic
+qh_option
+qh_order_vertexneighbors
+qh_orientoutside
+qh_out1
+qh_out2n
+qh_out3n
+qh_outcoplanar
+qh_outerinner
+qh_partitionall
+qh_partitioncoplanar
+qh_partitionpoint
+qh_partitionvisible
+qh_point
+qh_point_add
+qh_pointdist
+qh_pointfacet
+qh_pointid
+qh_pointvertex
+qh_postmerge
+qh_precision
+qh_premerge
+qh_prepare_output
+qh_prependfacet
+qh_printafacet
+qh_printallstatistics
+qh_printbegin
+qh_printcenter
+qh_printcentrum
+qh_printend
+qh_printend4geom
+qh_printextremes
+qh_printextremes_2d
+qh_printextremes_d
+qh_printfacet
+qh_printfacet2geom
+qh_printfacet2geom_points
+qh_printfacet2math
+qh_printfacet3geom_nonsimplicial
+qh_printfacet3geom_points
+qh_printfacet3geom_simplicial
+qh_printfacet3math
+qh_printfacet3vertex
+qh_printfacet4geom_nonsimplicial
+qh_printfacet4geom_simplicial
+qh_printfacetNvertex_nonsimplicial
+qh_printfacetNvertex_simplicial
+qh_printfacetheader
+qh_printfacetlist
+qh_printfacetridges
+qh_printfacets
+qh_printhashtable
+qh_printhelp_degenerate
+qh_printhelp_narrowhull
+qh_printhelp_singular
+qh_printhyperplaneintersection
+qh_printline3geom
+qh_printlists
+qh_printmatrix
+qh_printneighborhood
+qh_printpoint
+qh_printpoint3
+qh_printpointid
+qh_printpoints
+qh_printpoints_out
+qh_printpointvect
+qh_printpointvect2
+qh_printridge
+qh_printspheres
+qh_printstatistics
+qh_printstatlevel
+qh_printstats
+qh_printsummary
+qh_printvdiagram
+qh_printvdiagram2
+qh_printvertex
+qh_printvertexlist
+qh_printvertices
+qh_printvneighbors
+qh_printvnorm
+qh_printvoronoi
+qh_printvridge
+qh_produce_output
+qh_produce_output2
+qh_projectdim3
+qh_projectinput
+qh_projectpoint
+qh_projectpoints
+; Mark as DATA, otherwise links a separate qh_qh. qh_qh and qh_qhstat requires __declspec
+qh_qh DATA
+qh_qhstat DATA
+qh_qhull
+qh_rand
+qh_randomfactor
+qh_randommatrix
+qh_rboxpoints
+qh_readfeasible
+qh_readpoints
+qh_reducevertices
+qh_redundant_vertex
+qh_remove_extravertices
+qh_removefacet
+qh_removevertex
+qh_rename_sharedvertex
+qh_renameridgevertex
+qh_renamevertex
+qh_resetlists
+qh_restore_qhull
+qh_rotateinput
+qh_rotatepoints
+qh_roundi
+qh_save_qhull
+qh_scaleinput
+qh_scalelast
+qh_scalepoints
+qh_setaddnth
+qh_setaddsorted
+qh_setappend
+qh_setappend2ndlast
+qh_setappend_set
+qh_setcheck
+qh_setcompact
+qh_setcopy
+qh_setdel
+qh_setdelaunay
+qh_setdellast
+qh_setdelnth
+qh_setdelnthsorted
+qh_setdelsorted
+qh_setduplicate
+qh_setequal
+qh_setequal_except
+qh_setequal_skip
+qh_setfacetplane
+qh_setfeasible
+qh_setfree
+qh_setfree2
+qh_setfreelong
+qh_sethalfspace
+qh_sethalfspace_all
+qh_sethyperplane_det
+qh_sethyperplane_gauss
+qh_setin
+qh_setindex
+qh_setlarger
+qh_setlast
+qh_setnew
+qh_setnew_delnthsorted
+qh_setprint
+qh_setreplace
+qh_setsize
+qh_settemp
+qh_settempfree
+qh_settempfree_all
+qh_settemppop
+qh_settemppush
+qh_settruncate
+qh_setunique
+qh_setvoronoi_all
+qh_setzero
+qh_sharpnewfacets
+qh_skipfacet
+qh_skipfilename
+qh_srand
+qh_stddev
+qh_strtod
+qh_strtol
+qh_test_appendmerge
+qh_test_vneighbors
+qh_tracemerge
+qh_tracemerging
+qh_triangulate
+qh_triangulate_facet
+qh_triangulate_link
+qh_triangulate_mirror
+qh_triangulate_null
+qh_updatetested
+qh_updatevertices
+qh_user_memsizes
+qh_version
+qh_version2
+qh_vertexintersect
+qh_vertexintersect_new
+qh_vertexneighbors
+qh_vertexridges
+qh_vertexridges_facet
+qh_vertexsubset
+qh_voronoi_center
+qh_willdelete
+; Mark as DATA, otherwise links a separate qhmem. No __declspec
+qhmem DATA
+rbox DATA
+rbox_inuse DATA
diff --git a/xs/src/qhull/src/libqhull/qset.c b/xs/src/qhull/src/libqhull/qset.c
new file mode 100644
index 000000000..a969252a7
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qset.c
@@ -0,0 +1,1340 @@
+/*<html><pre> -<a href="qh-set.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qset.c
+ implements set manipulations needed for quickhull
+
+ see qh-set.htm and qset.h
+
+ Be careful of strict aliasing (two pointers of different types
+ that reference the same location). The last slot of a set is
+ either the actual size of the set plus 1, or the NULL terminator
+ of the set (i.e., setelemT).
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/qset.c#3 $$Change: 2062 $
+ $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+*/
+
+#include "user.h" /* for QHULL_CRTDBG */
+#include "qset.h"
+#include "mem.h"
+#include <stdio.h>
+#include <string.h>
+/*** uncomment here and qhull_a.h
+ if string.h does not define memcpy()
+#include <memory.h>
+*/
+
+#ifndef qhDEFlibqhull
+typedef struct ridgeT ridgeT;
+typedef struct facetT facetT;
+void qh_errexit(int exitcode, facetT *, ridgeT *);
+void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... );
+# ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
+# pragma warning( disable : 4127) /* conditional expression is constant */
+# pragma warning( disable : 4706) /* assignment within conditional function */
+# endif
+#endif
+
+/*=============== internal macros ===========================*/
+
+/*============ functions in alphabetical order ===================*/
+
+/*-<a href="qh-set.htm#TOC"
+ >--------------------------------<a name="setaddnth">-</a>
+
+ qh_setaddnth( setp, nth, newelem)
+ adds newelem as n'th element of sorted or unsorted *setp
+
+ notes:
+ *setp and newelem must be defined
+ *setp may be a temp set
+ nth=0 is first element
+ errors if nth is out of bounds
+
+ design:
+ expand *setp if empty or full
+ move tail of *setp up one
+ insert newelem
+*/
+void qh_setaddnth(setT **setp, int nth, void *newelem) {
+ int oldsize, i;
+ setelemT *sizep; /* avoid strict aliasing */
+ setelemT *oldp, *newp;
+
+ if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
+ qh_setlarger(setp);
+ sizep= SETsizeaddr_(*setp);
+ }
+ oldsize= sizep->i - 1;
+ if (nth < 0 || nth > oldsize) {
+ qh_fprintf(qhmem.ferr, 6171, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
+ qh_setprint(qhmem.ferr, "", *setp);
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ sizep->i++;
+ oldp= (setelemT *)SETelemaddr_(*setp, oldsize, void); /* NULL */
+ newp= oldp+1;
+ for (i=oldsize-nth+1; i--; ) /* move at least NULL */
+ (newp--)->p= (oldp--)->p; /* may overwrite *sizep */
+ newp->p= newelem;
+} /* setaddnth */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >--------------------------------<a name="setaddsorted">-</a>
+
+ setaddsorted( setp, newelem )
+ adds an newelem into sorted *setp
+
+ notes:
+ *setp and newelem must be defined
+ *setp may be a temp set
+ nop if newelem already in set
+
+ design:
+ find newelem's position in *setp
+ insert newelem
+*/
+void qh_setaddsorted(setT **setp, void *newelem) {
+ int newindex=0;
+ void *elem, **elemp;
+
+ FOREACHelem_(*setp) { /* could use binary search instead */
+ if (elem < newelem)
+ newindex++;
+ else if (elem == newelem)
+ return;
+ else
+ break;
+ }
+ qh_setaddnth(setp, newindex, newelem);
+} /* setaddsorted */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setappend">-</a>
+
+ qh_setappend( setp, newelem)
+ append newelem to *setp
+
+ notes:
+ *setp may be a temp set
+ *setp and newelem may be NULL
+
+ design:
+ expand *setp if empty or full
+ append newelem to *setp
+
+*/
+void qh_setappend(setT **setp, void *newelem) {
+ setelemT *sizep; /* Avoid strict aliasing. Writing to *endp may overwrite *sizep */
+ setelemT *endp;
+ int count;
+
+ if (!newelem)
+ return;
+ if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
+ qh_setlarger(setp);
+ sizep= SETsizeaddr_(*setp);
+ }
+ count= (sizep->i)++ - 1;
+ endp= (setelemT *)SETelemaddr_(*setp, count, void);
+ (endp++)->p= newelem;
+ endp->p= NULL;
+} /* setappend */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setappend_set">-</a>
+
+ qh_setappend_set( setp, setA)
+ appends setA to *setp
+
+ notes:
+ *setp can not be a temp set
+ *setp and setA may be NULL
+
+ design:
+ setup for copy
+ expand *setp if it is too small
+ append all elements of setA to *setp
+*/
+void qh_setappend_set(setT **setp, setT *setA) {
+ int sizeA, size;
+ setT *oldset;
+ setelemT *sizep;
+
+ if (!setA)
+ return;
+ SETreturnsize_(setA, sizeA);
+ if (!*setp)
+ *setp= qh_setnew(sizeA);
+ sizep= SETsizeaddr_(*setp);
+ if (!(size= sizep->i))
+ size= (*setp)->maxsize;
+ else
+ size--;
+ if (size + sizeA > (*setp)->maxsize) {
+ oldset= *setp;
+ *setp= qh_setcopy(oldset, sizeA);
+ qh_setfree(&oldset);
+ sizep= SETsizeaddr_(*setp);
+ }
+ if (sizeA > 0) {
+ sizep->i= size+sizeA+1; /* memcpy may overwrite */
+ memcpy((char *)&((*setp)->e[size].p), (char *)&(setA->e[0].p), (size_t)(sizeA+1) * SETelemsize);
+ }
+} /* setappend_set */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setappend2ndlast">-</a>
+
+ qh_setappend2ndlast( setp, newelem )
+ makes newelem the next to the last element in *setp
+
+ notes:
+ *setp must have at least one element
+ newelem must be defined
+ *setp may be a temp set
+
+ design:
+ expand *setp if empty or full
+ move last element of *setp up one
+ insert newelem
+*/
+void qh_setappend2ndlast(setT **setp, void *newelem) {
+ setelemT *sizep; /* Avoid strict aliasing. Writing to *endp may overwrite *sizep */
+ setelemT *endp, *lastp;
+ int count;
+
+ if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
+ qh_setlarger(setp);
+ sizep= SETsizeaddr_(*setp);
+ }
+ count= (sizep->i)++ - 1;
+ endp= (setelemT *)SETelemaddr_(*setp, count, void); /* NULL */
+ lastp= endp-1;
+ *(endp++)= *lastp;
+ endp->p= NULL; /* may overwrite *sizep */
+ lastp->p= newelem;
+} /* setappend2ndlast */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setcheck">-</a>
+
+ qh_setcheck( set, typename, id )
+ check set for validity
+ report errors with typename and id
+
+ design:
+ checks that maxsize, actual size, and NULL terminator agree
+*/
+void qh_setcheck(setT *set, const char *tname, unsigned id) {
+ int maxsize, size;
+ int waserr= 0;
+
+ if (!set)
+ return;
+ SETreturnsize_(set, size);
+ maxsize= set->maxsize;
+ if (size > maxsize || !maxsize) {
+ qh_fprintf(qhmem.ferr, 6172, "qhull internal error (qh_setcheck): actual size %d of %s%d is greater than max size %d\n",
+ size, tname, id, maxsize);
+ waserr= 1;
+ }else if (set->e[size].p) {
+ qh_fprintf(qhmem.ferr, 6173, "qhull internal error (qh_setcheck): %s%d(size %d max %d) is not null terminated.\n",
+ tname, id, size-1, maxsize);
+ waserr= 1;
+ }
+ if (waserr) {
+ qh_setprint(qhmem.ferr, "ERRONEOUS", set);
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+} /* setcheck */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setcompact">-</a>
+
+ qh_setcompact( set )
+ remove internal NULLs from an unsorted set
+
+ returns:
+ updated set
+
+ notes:
+ set may be NULL
+ it would be faster to swap tail of set into holes, like qh_setdel
+
+ design:
+ setup pointers into set
+ skip NULLs while copying elements to start of set
+ update the actual size
+*/
+void qh_setcompact(setT *set) {
+ int size;
+ void **destp, **elemp, **endp, **firstp;
+
+ if (!set)
+ return;
+ SETreturnsize_(set, size);
+ destp= elemp= firstp= SETaddr_(set, void);
+ endp= destp + size;
+ while (1) {
+ if (!(*destp++ = *elemp++)) {
+ destp--;
+ if (elemp > endp)
+ break;
+ }
+ }
+ qh_settruncate(set, (int)(destp-firstp)); /* WARN64 */
+} /* setcompact */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setcopy">-</a>
+
+ qh_setcopy( set, extra )
+ make a copy of a sorted or unsorted set with extra slots
+
+ returns:
+ new set
+
+ design:
+ create a newset with extra slots
+ copy the elements to the newset
+
+*/
+setT *qh_setcopy(setT *set, int extra) {
+ setT *newset;
+ int size;
+
+ if (extra < 0)
+ extra= 0;
+ SETreturnsize_(set, size);
+ newset= qh_setnew(size+extra);
+ SETsizeaddr_(newset)->i= size+1; /* memcpy may overwrite */
+ memcpy((char *)&(newset->e[0].p), (char *)&(set->e[0].p), (size_t)(size+1) * SETelemsize);
+ return(newset);
+} /* setcopy */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setdel">-</a>
+
+ qh_setdel( set, oldelem )
+ delete oldelem from an unsorted set
+
+ returns:
+ returns oldelem if found
+ returns NULL otherwise
+
+ notes:
+ set may be NULL
+ oldelem must not be NULL;
+ only deletes one copy of oldelem in set
+
+ design:
+ locate oldelem
+ update actual size if it was full
+ move the last element to the oldelem's location
+*/
+void *qh_setdel(setT *set, void *oldelem) {
+ setelemT *sizep;
+ setelemT *elemp;
+ setelemT *lastp;
+
+ if (!set)
+ return NULL;
+ elemp= (setelemT *)SETaddr_(set, void);
+ while (elemp->p != oldelem && elemp->p)
+ elemp++;
+ if (elemp->p) {
+ sizep= SETsizeaddr_(set);
+ if (!(sizep->i)--) /* if was a full set */
+ sizep->i= set->maxsize; /* *sizep= (maxsize-1)+ 1 */
+ lastp= (setelemT *)SETelemaddr_(set, sizep->i-1, void);
+ elemp->p= lastp->p; /* may overwrite itself */
+ lastp->p= NULL;
+ return oldelem;
+ }
+ return NULL;
+} /* setdel */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setdellast">-</a>
+
+ qh_setdellast( set)
+ return last element of set or NULL
+
+ notes:
+ deletes element from set
+ set may be NULL
+
+ design:
+ return NULL if empty
+ if full set
+ delete last element and set actual size
+ else
+ delete last element and update actual size
+*/
+void *qh_setdellast(setT *set) {
+ int setsize; /* actually, actual_size + 1 */
+ int maxsize;
+ setelemT *sizep;
+ void *returnvalue;
+
+ if (!set || !(set->e[0].p))
+ return NULL;
+ sizep= SETsizeaddr_(set);
+ if ((setsize= sizep->i)) {
+ returnvalue= set->e[setsize - 2].p;
+ set->e[setsize - 2].p= NULL;
+ sizep->i--;
+ }else {
+ maxsize= set->maxsize;
+ returnvalue= set->e[maxsize - 1].p;
+ set->e[maxsize - 1].p= NULL;
+ sizep->i= maxsize;
+ }
+ return returnvalue;
+} /* setdellast */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setdelnth">-</a>
+
+ qh_setdelnth( set, nth )
+ deletes nth element from unsorted set
+ 0 is first element
+
+ returns:
+ returns the element (needs type conversion)
+
+ notes:
+ errors if nth invalid
+
+ design:
+ setup points and check nth
+ delete nth element and overwrite with last element
+*/
+void *qh_setdelnth(setT *set, int nth) {
+ void *elem;
+ setelemT *sizep;
+ setelemT *elemp, *lastp;
+
+ sizep= SETsizeaddr_(set);
+ if ((sizep->i--)==0) /* if was a full set */
+ sizep->i= set->maxsize; /* *sizep= (maxsize-1)+ 1 */
+ if (nth < 0 || nth >= sizep->i) {
+ qh_fprintf(qhmem.ferr, 6174, "qhull internal error (qh_setdelnth): nth %d is out-of-bounds for set:\n", nth);
+ qh_setprint(qhmem.ferr, "", set);
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ elemp= (setelemT *)SETelemaddr_(set, nth, void); /* nth valid by QH6174 */
+ lastp= (setelemT *)SETelemaddr_(set, sizep->i-1, void);
+ elem= elemp->p;
+ elemp->p= lastp->p; /* may overwrite itself */
+ lastp->p= NULL;
+ return elem;
+} /* setdelnth */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setdelnthsorted">-</a>
+
+ qh_setdelnthsorted( set, nth )
+ deletes nth element from sorted set
+
+ returns:
+ returns the element (use type conversion)
+
+ notes:
+ errors if nth invalid
+
+ see also:
+ setnew_delnthsorted
+
+ design:
+ setup points and check nth
+ copy remaining elements down one
+ update actual size
+*/
+void *qh_setdelnthsorted(setT *set, int nth) {
+ void *elem;
+ setelemT *sizep;
+ setelemT *newp, *oldp;
+
+ sizep= SETsizeaddr_(set);
+ if (nth < 0 || (sizep->i && nth >= sizep->i-1) || nth >= set->maxsize) {
+ qh_fprintf(qhmem.ferr, 6175, "qhull internal error (qh_setdelnthsorted): nth %d is out-of-bounds for set:\n", nth);
+ qh_setprint(qhmem.ferr, "", set);
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ newp= (setelemT *)SETelemaddr_(set, nth, void);
+ elem= newp->p;
+ oldp= newp+1;
+ while (((newp++)->p= (oldp++)->p))
+ ; /* copy remaining elements and NULL */
+ if ((sizep->i--)==0) /* if was a full set */
+ sizep->i= set->maxsize; /* *sizep= (max size-1)+ 1 */
+ return elem;
+} /* setdelnthsorted */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setdelsorted">-</a>
+
+ qh_setdelsorted( set, oldelem )
+ deletes oldelem from sorted set
+
+ returns:
+ returns oldelem if it was deleted
+
+ notes:
+ set may be NULL
+
+ design:
+ locate oldelem in set
+ copy remaining elements down one
+ update actual size
+*/
+void *qh_setdelsorted(setT *set, void *oldelem) {
+ setelemT *sizep;
+ setelemT *newp, *oldp;
+
+ if (!set)
+ return NULL;
+ newp= (setelemT *)SETaddr_(set, void);
+ while(newp->p != oldelem && newp->p)
+ newp++;
+ if (newp->p) {
+ oldp= newp+1;
+ while (((newp++)->p= (oldp++)->p))
+ ; /* copy remaining elements */
+ sizep= SETsizeaddr_(set);
+ if ((sizep->i--)==0) /* if was a full set */
+ sizep->i= set->maxsize; /* *sizep= (max size-1)+ 1 */
+ return oldelem;
+ }
+ return NULL;
+} /* setdelsorted */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setduplicate">-</a>
+
+ qh_setduplicate( set, elemsize )
+ duplicate a set of elemsize elements
+
+ notes:
+ use setcopy if retaining old elements
+
+ design:
+ create a new set
+ for each elem of the old set
+ create a newelem
+ append newelem to newset
+*/
+setT *qh_setduplicate(setT *set, int elemsize) {
+ void *elem, **elemp, *newElem;
+ setT *newSet;
+ int size;
+
+ if (!(size= qh_setsize(set)))
+ return NULL;
+ newSet= qh_setnew(size);
+ FOREACHelem_(set) {
+ newElem= qh_memalloc(elemsize);
+ memcpy(newElem, elem, (size_t)elemsize);
+ qh_setappend(&newSet, newElem);
+ }
+ return newSet;
+} /* setduplicate */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setendpointer">-</a>
+
+ qh_setendpointer( set )
+ Returns pointer to NULL terminator of a set's elements
+ set can not be NULL
+
+*/
+void **qh_setendpointer(setT *set) {
+
+ setelemT *sizep= SETsizeaddr_(set);
+ int n= sizep->i;
+ return (n ? &set->e[n-1].p : &sizep->p);
+} /* qh_setendpointer */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setequal">-</a>
+
+ qh_setequal( setA, setB )
+ returns 1 if two sorted sets are equal, otherwise returns 0
+
+ notes:
+ either set may be NULL
+
+ design:
+ check size of each set
+ setup pointers
+ compare elements of each set
+*/
+int qh_setequal(setT *setA, setT *setB) {
+ void **elemAp, **elemBp;
+ int sizeA= 0, sizeB= 0;
+
+ if (setA) {
+ SETreturnsize_(setA, sizeA);
+ }
+ if (setB) {
+ SETreturnsize_(setB, sizeB);
+ }
+ if (sizeA != sizeB)
+ return 0;
+ if (!sizeA)
+ return 1;
+ elemAp= SETaddr_(setA, void);
+ elemBp= SETaddr_(setB, void);
+ if (!memcmp((char *)elemAp, (char *)elemBp, sizeA*SETelemsize))
+ return 1;
+ return 0;
+} /* setequal */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setequal_except">-</a>
+
+ qh_setequal_except( setA, skipelemA, setB, skipelemB )
+ returns 1 if sorted setA and setB are equal except for skipelemA & B
+
+ returns:
+ false if either skipelemA or skipelemB are missing
+
+ notes:
+ neither set may be NULL
+
+ if skipelemB is NULL,
+ can skip any one element of setB
+
+ design:
+ setup pointers
+ search for skipelemA, skipelemB, and mismatches
+ check results
+*/
+int qh_setequal_except(setT *setA, void *skipelemA, setT *setB, void *skipelemB) {
+ void **elemA, **elemB;
+ int skip=0;
+
+ elemA= SETaddr_(setA, void);
+ elemB= SETaddr_(setB, void);
+ while (1) {
+ if (*elemA == skipelemA) {
+ skip++;
+ elemA++;
+ }
+ if (skipelemB) {
+ if (*elemB == skipelemB) {
+ skip++;
+ elemB++;
+ }
+ }else if (*elemA != *elemB) {
+ skip++;
+ if (!(skipelemB= *elemB++))
+ return 0;
+ }
+ if (!*elemA)
+ break;
+ if (*elemA++ != *elemB++)
+ return 0;
+ }
+ if (skip != 2 || *elemB)
+ return 0;
+ return 1;
+} /* setequal_except */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setequal_skip">-</a>
+
+ qh_setequal_skip( setA, skipA, setB, skipB )
+ returns 1 if sorted setA and setB are equal except for elements skipA & B
+
+ returns:
+ false if different size
+
+ notes:
+ neither set may be NULL
+
+ design:
+ setup pointers
+ search for mismatches while skipping skipA and skipB
+*/
+int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB) {
+ void **elemA, **elemB, **skipAp, **skipBp;
+
+ elemA= SETaddr_(setA, void);
+ elemB= SETaddr_(setB, void);
+ skipAp= SETelemaddr_(setA, skipA, void);
+ skipBp= SETelemaddr_(setB, skipB, void);
+ while (1) {
+ if (elemA == skipAp)
+ elemA++;
+ if (elemB == skipBp)
+ elemB++;
+ if (!*elemA)
+ break;
+ if (*elemA++ != *elemB++)
+ return 0;
+ }
+ if (*elemB)
+ return 0;
+ return 1;
+} /* setequal_skip */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setfree">-</a>
+
+ qh_setfree( setp )
+ frees the space occupied by a sorted or unsorted set
+
+ returns:
+ sets setp to NULL
+
+ notes:
+ set may be NULL
+
+ design:
+ free array
+ free set
+*/
+void qh_setfree(setT **setp) {
+ int size;
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+
+ if (*setp) {
+ size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize;
+ if (size <= qhmem.LASTsize) {
+ qh_memfree_(*setp, size, freelistp);
+ }else
+ qh_memfree(*setp, size);
+ *setp= NULL;
+ }
+} /* setfree */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setfree2">-</a>
+
+ qh_setfree2( setp, elemsize )
+ frees the space occupied by a set and its elements
+
+ notes:
+ set may be NULL
+
+ design:
+ free each element
+ free set
+*/
+void qh_setfree2(setT **setp, int elemsize) {
+ void *elem, **elemp;
+
+ FOREACHelem_(*setp)
+ qh_memfree(elem, elemsize);
+ qh_setfree(setp);
+} /* setfree2 */
+
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setfreelong">-</a>
+
+ qh_setfreelong( setp )
+ frees a set only if it's in long memory
+
+ returns:
+ sets setp to NULL if it is freed
+
+ notes:
+ set may be NULL
+
+ design:
+ if set is large
+ free it
+*/
+void qh_setfreelong(setT **setp) {
+ int size;
+
+ if (*setp) {
+ size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize;
+ if (size > qhmem.LASTsize) {
+ qh_memfree(*setp, size);
+ *setp= NULL;
+ }
+ }
+} /* setfreelong */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setin">-</a>
+
+ qh_setin( set, setelem )
+ returns 1 if setelem is in a set, 0 otherwise
+
+ notes:
+ set may be NULL or unsorted
+
+ design:
+ scans set for setelem
+*/
+int qh_setin(setT *set, void *setelem) {
+ void *elem, **elemp;
+
+ FOREACHelem_(set) {
+ if (elem == setelem)
+ return 1;
+ }
+ return 0;
+} /* setin */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setindex">-</a>
+
+ qh_setindex( set, atelem )
+ returns the index of atelem in set.
+ returns -1, if not in set or maxsize wrong
+
+ notes:
+ set may be NULL and may contain nulls.
+ NOerrors returned (qh_pointid, QhullPoint::id)
+
+ design:
+ checks maxsize
+ scans set for atelem
+*/
+int qh_setindex(setT *set, void *atelem) {
+ void **elem;
+ int size, i;
+
+ if (!set)
+ return -1;
+ SETreturnsize_(set, size);
+ if (size > set->maxsize)
+ return -1;
+ elem= SETaddr_(set, void);
+ for (i=0; i < size; i++) {
+ if (*elem++ == atelem)
+ return i;
+ }
+ return -1;
+} /* setindex */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setlarger">-</a>
+
+ qh_setlarger( oldsetp )
+ returns a larger set that contains all elements of *oldsetp
+
+ notes:
+ the set is at least twice as large
+ if temp set, updates qhmem.tempstack
+
+ design:
+ creates a new set
+ copies the old set to the new set
+ updates pointers in tempstack
+ deletes the old set
+*/
+void qh_setlarger(setT **oldsetp) {
+ int size= 1;
+ setT *newset, *set, **setp, *oldset;
+ setelemT *sizep;
+ setelemT *newp, *oldp;
+
+ if (*oldsetp) {
+ oldset= *oldsetp;
+ SETreturnsize_(oldset, size);
+ qhmem.cntlarger++;
+ qhmem.totlarger += size+1;
+ newset= qh_setnew(2 * size);
+ oldp= (setelemT *)SETaddr_(oldset, void);
+ newp= (setelemT *)SETaddr_(newset, void);
+ memcpy((char *)newp, (char *)oldp, (size_t)(size+1) * SETelemsize);
+ sizep= SETsizeaddr_(newset);
+ sizep->i= size+1;
+ FOREACHset_((setT *)qhmem.tempstack) {
+ if (set == oldset)
+ *(setp-1)= newset;
+ }
+ qh_setfree(oldsetp);
+ }else
+ newset= qh_setnew(3);
+ *oldsetp= newset;
+} /* setlarger */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setlast">-</a>
+
+ qh_setlast( set )
+ return last element of set or NULL (use type conversion)
+
+ notes:
+ set may be NULL
+
+ design:
+ return last element
+*/
+void *qh_setlast(setT *set) {
+ int size;
+
+ if (set) {
+ size= SETsizeaddr_(set)->i;
+ if (!size)
+ return SETelem_(set, set->maxsize - 1);
+ else if (size > 1)
+ return SETelem_(set, size - 2);
+ }
+ return NULL;
+} /* setlast */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setnew">-</a>
+
+ qh_setnew( setsize )
+ creates and allocates space for a set
+
+ notes:
+ setsize means the number of elements (!including the NULL terminator)
+ use qh_settemp/qh_setfreetemp if set is temporary
+
+ design:
+ allocate memory for set
+ roundup memory if small set
+ initialize as empty set
+*/
+setT *qh_setnew(int setsize) {
+ setT *set;
+ int sizereceived; /* used if !qh_NOmem */
+ int size;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+
+ if (!setsize)
+ setsize++;
+ size= sizeof(setT) + setsize * SETelemsize;
+ if (size>0 && size <= qhmem.LASTsize) {
+ qh_memalloc_(size, freelistp, set, setT);
+#ifndef qh_NOmem
+ sizereceived= qhmem.sizetable[ qhmem.indextable[size]];
+ if (sizereceived > size)
+ setsize += (sizereceived - size)/SETelemsize;
+#endif
+ }else
+ set= (setT*)qh_memalloc(size);
+ set->maxsize= setsize;
+ set->e[setsize].i= 1;
+ set->e[0].p= NULL;
+ return(set);
+} /* setnew */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setnew_delnthsorted">-</a>
+
+ qh_setnew_delnthsorted( set, size, nth, prepend )
+ creates a sorted set not containing nth element
+ if prepend, the first prepend elements are undefined
+
+ notes:
+ set must be defined
+ checks nth
+ see also: setdelnthsorted
+
+ design:
+ create new set
+ setup pointers and allocate room for prepend'ed entries
+ append head of old set to new set
+ append tail of old set to new set
+*/
+setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend) {
+ setT *newset;
+ void **oldp, **newp;
+ int tailsize= size - nth -1, newsize;
+
+ if (tailsize < 0) {
+ qh_fprintf(qhmem.ferr, 6176, "qhull internal error (qh_setnew_delnthsorted): nth %d is out-of-bounds for set:\n", nth);
+ qh_setprint(qhmem.ferr, "", set);
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ newsize= size-1 + prepend;
+ newset= qh_setnew(newsize);
+ newset->e[newset->maxsize].i= newsize+1; /* may be overwritten */
+ oldp= SETaddr_(set, void);
+ newp= SETaddr_(newset, void) + prepend;
+ switch (nth) {
+ case 0:
+ break;
+ case 1:
+ *(newp++)= *oldp++;
+ break;
+ case 2:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ case 3:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ case 4:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ default:
+ memcpy((char *)newp, (char *)oldp, (size_t)nth * SETelemsize);
+ newp += nth;
+ oldp += nth;
+ break;
+ }
+ oldp++;
+ switch (tailsize) {
+ case 0:
+ break;
+ case 1:
+ *(newp++)= *oldp++;
+ break;
+ case 2:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ case 3:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ case 4:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ default:
+ memcpy((char *)newp, (char *)oldp, (size_t)tailsize * SETelemsize);
+ newp += tailsize;
+ }
+ *newp= NULL;
+ return(newset);
+} /* setnew_delnthsorted */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setprint">-</a>
+
+ qh_setprint( fp, string, set )
+ print set elements to fp with identifying string
+
+ notes:
+ never errors
+*/
+void qh_setprint(FILE *fp, const char* string, setT *set) {
+ int size, k;
+
+ if (!set)
+ qh_fprintf(fp, 9346, "%s set is null\n", string);
+ else {
+ SETreturnsize_(set, size);
+ qh_fprintf(fp, 9347, "%s set=%p maxsize=%d size=%d elems=",
+ string, set, set->maxsize, size);
+ if (size > set->maxsize)
+ size= set->maxsize+1;
+ for (k=0; k < size; k++)
+ qh_fprintf(fp, 9348, " %p", set->e[k].p);
+ qh_fprintf(fp, 9349, "\n");
+ }
+} /* setprint */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setreplace">-</a>
+
+ qh_setreplace( set, oldelem, newelem )
+ replaces oldelem in set with newelem
+
+ notes:
+ errors if oldelem not in the set
+ newelem may be NULL, but it turns the set into an indexed set (no FOREACH)
+
+ design:
+ find oldelem
+ replace with newelem
+*/
+void qh_setreplace(setT *set, void *oldelem, void *newelem) {
+ void **elemp;
+
+ elemp= SETaddr_(set, void);
+ while (*elemp != oldelem && *elemp)
+ elemp++;
+ if (*elemp)
+ *elemp= newelem;
+ else {
+ qh_fprintf(qhmem.ferr, 6177, "qhull internal error (qh_setreplace): elem %p not found in set\n",
+ oldelem);
+ qh_setprint(qhmem.ferr, "", set);
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+} /* setreplace */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setsize">-</a>
+
+ qh_setsize( set )
+ returns the size of a set
+
+ notes:
+ errors if set's maxsize is incorrect
+ same as SETreturnsize_(set)
+ same code for qh_setsize [qset.c] and QhullSetBase::count
+
+ design:
+ determine actual size of set from maxsize
+*/
+int qh_setsize(setT *set) {
+ int size;
+ setelemT *sizep;
+
+ if (!set)
+ return(0);
+ sizep= SETsizeaddr_(set);
+ if ((size= sizep->i)) {
+ size--;
+ if (size > set->maxsize) {
+ qh_fprintf(qhmem.ferr, 6178, "qhull internal error (qh_setsize): current set size %d is greater than maximum size %d\n",
+ size, set->maxsize);
+ qh_setprint(qhmem.ferr, "set: ", set);
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ }else
+ size= set->maxsize;
+ return size;
+} /* setsize */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="settemp">-</a>
+
+ qh_settemp( setsize )
+ return a stacked, temporary set of upto setsize elements
+
+ notes:
+ use settempfree or settempfree_all to release from qhmem.tempstack
+ see also qh_setnew
+
+ design:
+ allocate set
+ append to qhmem.tempstack
+
+*/
+setT *qh_settemp(int setsize) {
+ setT *newset;
+
+ newset= qh_setnew(setsize);
+ qh_setappend(&qhmem.tempstack, newset);
+ if (qhmem.IStracing >= 5)
+ qh_fprintf(qhmem.ferr, 8123, "qh_settemp: temp set %p of %d elements, depth %d\n",
+ newset, newset->maxsize, qh_setsize(qhmem.tempstack));
+ return newset;
+} /* settemp */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="settempfree">-</a>
+
+ qh_settempfree( set )
+ free temporary set at top of qhmem.tempstack
+
+ notes:
+ nop if set is NULL
+ errors if set not from previous qh_settemp
+
+ to locate errors:
+ use 'T2' to find source and then find mis-matching qh_settemp
+
+ design:
+ check top of qhmem.tempstack
+ free it
+*/
+void qh_settempfree(setT **set) {
+ setT *stackedset;
+
+ if (!*set)
+ return;
+ stackedset= qh_settemppop();
+ if (stackedset != *set) {
+ qh_settemppush(stackedset);
+ qh_fprintf(qhmem.ferr, 6179, "qhull internal error (qh_settempfree): set %p(size %d) was not last temporary allocated(depth %d, set %p, size %d)\n",
+ *set, qh_setsize(*set), qh_setsize(qhmem.tempstack)+1,
+ stackedset, qh_setsize(stackedset));
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ qh_setfree(set);
+} /* settempfree */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="settempfree_all">-</a>
+
+ qh_settempfree_all( )
+ free all temporary sets in qhmem.tempstack
+
+ design:
+ for each set in tempstack
+ free set
+ free qhmem.tempstack
+*/
+void qh_settempfree_all(void) {
+ setT *set, **setp;
+
+ FOREACHset_(qhmem.tempstack)
+ qh_setfree(&set);
+ qh_setfree(&qhmem.tempstack);
+} /* settempfree_all */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="settemppop">-</a>
+
+ qh_settemppop( )
+ pop and return temporary set from qhmem.tempstack
+
+ notes:
+ the returned set is permanent
+
+ design:
+ pop and check top of qhmem.tempstack
+*/
+setT *qh_settemppop(void) {
+ setT *stackedset;
+
+ stackedset= (setT*)qh_setdellast(qhmem.tempstack);
+ if (!stackedset) {
+ qh_fprintf(qhmem.ferr, 6180, "qhull internal error (qh_settemppop): pop from empty temporary stack\n");
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ if (qhmem.IStracing >= 5)
+ qh_fprintf(qhmem.ferr, 8124, "qh_settemppop: depth %d temp set %p of %d elements\n",
+ qh_setsize(qhmem.tempstack)+1, stackedset, qh_setsize(stackedset));
+ return stackedset;
+} /* settemppop */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="settemppush">-</a>
+
+ qh_settemppush( set )
+ push temporary set unto qhmem.tempstack (makes it temporary)
+
+ notes:
+ duplicates settemp() for tracing
+
+ design:
+ append set to tempstack
+*/
+void qh_settemppush(setT *set) {
+ if (!set) {
+ qh_fprintf(qhmem.ferr, 6267, "qhull error (qh_settemppush): can not push a NULL temp\n");
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ qh_setappend(&qhmem.tempstack, set);
+ if (qhmem.IStracing >= 5)
+ qh_fprintf(qhmem.ferr, 8125, "qh_settemppush: depth %d temp set %p of %d elements\n",
+ qh_setsize(qhmem.tempstack), set, qh_setsize(set));
+} /* settemppush */
+
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="settruncate">-</a>
+
+ qh_settruncate( set, size )
+ truncate set to size elements
+
+ notes:
+ set must be defined
+
+ see:
+ SETtruncate_
+
+ design:
+ check size
+ update actual size of set
+*/
+void qh_settruncate(setT *set, int size) {
+
+ if (size < 0 || size > set->maxsize) {
+ qh_fprintf(qhmem.ferr, 6181, "qhull internal error (qh_settruncate): size %d out of bounds for set:\n", size);
+ qh_setprint(qhmem.ferr, "", set);
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ set->e[set->maxsize].i= size+1; /* maybe overwritten */
+ set->e[size].p= NULL;
+} /* settruncate */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setunique">-</a>
+
+ qh_setunique( set, elem )
+ add elem to unsorted set unless it is already in set
+
+ notes:
+ returns 1 if it is appended
+
+ design:
+ if elem not in set
+ append elem to set
+*/
+int qh_setunique(setT **set, void *elem) {
+
+ if (!qh_setin(*set, elem)) {
+ qh_setappend(set, elem);
+ return 1;
+ }
+ return 0;
+} /* setunique */
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="setzero">-</a>
+
+ qh_setzero( set, index, size )
+ zero elements from index on
+ set actual size of set to size
+
+ notes:
+ set must be defined
+ the set becomes an indexed set (can not use FOREACH...)
+
+ see also:
+ qh_settruncate
+
+ design:
+ check index and size
+ update actual size
+ zero elements starting at e[index]
+*/
+void qh_setzero(setT *set, int idx, int size) {
+ int count;
+
+ if (idx < 0 || idx >= size || size > set->maxsize) {
+ qh_fprintf(qhmem.ferr, 6182, "qhull internal error (qh_setzero): index %d or size %d out of bounds for set:\n", idx, size);
+ qh_setprint(qhmem.ferr, "", set);
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+ }
+ set->e[set->maxsize].i= size+1; /* may be overwritten */
+ count= size - idx + 1; /* +1 for NULL terminator */
+ memset((char *)SETelemaddr_(set, idx, void), 0, (size_t)count * SETelemsize);
+} /* setzero */
+
+
diff --git a/xs/src/qhull/src/libqhull/qset.h b/xs/src/qhull/src/libqhull/qset.h
new file mode 100644
index 000000000..7e4e7d14f
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/qset.h
@@ -0,0 +1,490 @@
+/*<html><pre> -<a href="qh-set.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qset.h
+ header file for qset.c that implements set
+
+ see qh-set.htm and qset.c
+
+ only uses mem.c, malloc/free
+
+ for error handling, writes message and calls
+ qh_errexit(qhmem_ERRqhull, NULL, NULL);
+
+ set operations satisfy the following properties:
+ - sets have a max size, the actual size (if different) is stored at the end
+ - every set is NULL terminated
+ - sets may be sorted or unsorted, the caller must distinguish this
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/qset.h#2 $$Change: 2062 $
+ $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+*/
+
+#ifndef qhDEFset
+#define qhDEFset 1
+
+#include <stdio.h>
+
+/*================= -structures- ===============*/
+
+#ifndef DEFsetT
+#define DEFsetT 1
+typedef struct setT setT; /* a set is a sorted or unsorted array of pointers */
+#endif
+
+/* [jan'15] Decided not to use countT. Most sets are small. The code uses signed tests */
+
+/*-<a href="qh-set.htm#TOC"
+>----------------------------------------</a><a name="setT">-</a>
+
+setT
+ a set or list of pointers with maximum size and actual size.
+
+variations:
+ unsorted, unique -- a list of unique pointers with NULL terminator
+ user guarantees uniqueness
+ sorted -- a sorted list of unique pointers with NULL terminator
+ qset.c guarantees uniqueness
+ unsorted -- a list of pointers terminated with NULL
+ indexed -- an array of pointers with NULL elements
+
+structure for set of n elements:
+
+ --------------
+ | maxsize
+ --------------
+ | e[0] - a pointer, may be NULL for indexed sets
+ --------------
+ | e[1]
+
+ --------------
+ | ...
+ --------------
+ | e[n-1]
+ --------------
+ | e[n] = NULL
+ --------------
+ | ...
+ --------------
+ | e[maxsize] - n+1 or NULL (determines actual size of set)
+ --------------
+
+*/
+
+/*-- setelemT -- internal type to allow both pointers and indices
+*/
+typedef union setelemT setelemT;
+union setelemT {
+ void *p;
+ int i; /* integer used for e[maxSize] */
+};
+
+struct setT {
+ int maxsize; /* maximum number of elements (except NULL) */
+ setelemT e[1]; /* array of pointers, tail is NULL */
+ /* last slot (unless NULL) is actual size+1
+ e[maxsize]==NULL or e[e[maxsize]-1]==NULL */
+ /* this may generate a warning since e[] contains
+ maxsize elements */
+};
+
+/*=========== -constants- =========================*/
+
+/*-<a href="qh-set.htm#TOC"
+ >-----------------------------------</a><a name="SETelemsize">-</a>
+
+ SETelemsize
+ size of a set element in bytes
+*/
+#define SETelemsize ((int)sizeof(setelemT))
+
+
+/*=========== -macros- =========================*/
+
+/*-<a href="qh-set.htm#TOC"
+ >-----------------------------------</a><a name="FOREACHsetelement_">-</a>
+
+ FOREACHsetelement_(type, set, variable)
+ define FOREACH iterator
+
+ declare:
+ assumes *variable and **variablep are declared
+ no space in "variable)" [DEC Alpha cc compiler]
+
+ each iteration:
+ variable is set element
+ variablep is one beyond variable.
+
+ to repeat an element:
+ variablep--; / *repeat* /
+
+ at exit:
+ variable is NULL at end of loop
+
+ example:
+ #define FOREACHfacet_( facets ) FOREACHsetelement_( facetT, facets, facet )
+
+ notes:
+ use FOREACHsetelement_i_() if need index or include NULLs
+
+ WARNING:
+ nested loops can't use the same variable (define another FOREACH)
+
+ needs braces if nested inside another FOREACH
+ this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
+*/
+#define FOREACHsetelement_(type, set, variable) \
+ if (((variable= NULL), set)) for (\
+ variable##p= (type **)&((set)->e[0].p); \
+ (variable= *variable##p++);)
+
+/*-<a href="qh-set.htm#TOC"
+ >----------------------------------------</a><a name="FOREACHsetelement_i_">-</a>
+
+ FOREACHsetelement_i_(type, set, variable)
+ define indexed FOREACH iterator
+
+ declare:
+ type *variable, variable_n, variable_i;
+
+ each iteration:
+ variable is set element, may be NULL
+ variable_i is index, variable_n is qh_setsize()
+
+ to repeat an element:
+ variable_i--; variable_n-- repeats for deleted element
+
+ at exit:
+ variable==NULL and variable_i==variable_n
+
+ example:
+ #define FOREACHfacet_i_( facets ) FOREACHsetelement_i_( facetT, facets, facet )
+
+ WARNING:
+ nested loops can't use the same variable (define another FOREACH)
+
+ needs braces if nested inside another FOREACH
+ this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
+*/
+#define FOREACHsetelement_i_(type, set, variable) \
+ if (((variable= NULL), set)) for (\
+ variable##_i= 0, variable= (type *)((set)->e[0].p), \
+ variable##_n= qh_setsize(set);\
+ variable##_i < variable##_n;\
+ variable= (type *)((set)->e[++variable##_i].p) )
+
+/*-<a href="qh-set.htm#TOC"
+ >--------------------------------------</a><a name="FOREACHsetelementreverse_">-</a>
+
+ FOREACHsetelementreverse_(type, set, variable)-
+ define FOREACH iterator in reverse order
+
+ declare:
+ assumes *variable and **variablep are declared
+ also declare 'int variabletemp'
+
+ each iteration:
+ variable is set element
+
+ to repeat an element:
+ variabletemp++; / *repeat* /
+
+ at exit:
+ variable is NULL
+
+ example:
+ #define FOREACHvertexreverse_( vertices ) FOREACHsetelementreverse_( vertexT, vertices, vertex )
+
+ notes:
+ use FOREACHsetelementreverse12_() to reverse first two elements
+ WARNING: needs braces if nested inside another FOREACH
+*/
+#define FOREACHsetelementreverse_(type, set, variable) \
+ if (((variable= NULL), set)) for (\
+ variable##temp= qh_setsize(set)-1, variable= qh_setlast(set);\
+ variable; variable= \
+ ((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL))
+
+/*-<a href="qh-set.htm#TOC"
+ >-----------------------------------</a><a name="FOREACHsetelementreverse12_">-</a>
+
+ FOREACHsetelementreverse12_(type, set, variable)-
+ define FOREACH iterator with e[1] and e[0] reversed
+
+ declare:
+ assumes *variable and **variablep are declared
+
+ each iteration:
+ variable is set element
+ variablep is one after variable.
+
+ to repeat an element:
+ variablep--; / *repeat* /
+
+ at exit:
+ variable is NULL at end of loop
+
+ example
+ #define FOREACHvertexreverse12_( vertices ) FOREACHsetelementreverse12_( vertexT, vertices, vertex )
+
+ notes:
+ WARNING: needs braces if nested inside another FOREACH
+*/
+#define FOREACHsetelementreverse12_(type, set, variable) \
+ if (((variable= NULL), set)) for (\
+ variable##p= (type **)&((set)->e[1].p); \
+ (variable= *variable##p); \
+ variable##p == ((type **)&((set)->e[0].p))?variable##p += 2: \
+ (variable##p == ((type **)&((set)->e[1].p))?variable##p--:variable##p++))
+
+/*-<a href="qh-set.htm#TOC"
+ >-----------------------------------</a><a name="FOREACHelem_">-</a>
+
+ FOREACHelem_( set )-
+ iterate elements in a set
+
+ declare:
+ void *elem, *elemp;
+
+ each iteration:
+ elem is set element
+ elemp is one beyond
+
+ to repeat an element:
+ elemp--; / *repeat* /
+
+ at exit:
+ elem == NULL at end of loop
+
+ example:
+ FOREACHelem_(set) {
+
+ notes:
+ WARNING: needs braces if nested inside another FOREACH
+*/
+#define FOREACHelem_(set) FOREACHsetelement_(void, set, elem)
+
+/*-<a href="qh-set.htm#TOC"
+ >-----------------------------------</a><a name="FOREACHset_">-</a>
+
+ FOREACHset_( set )-
+ iterate a set of sets
+
+ declare:
+ setT *set, **setp;
+
+ each iteration:
+ set is set element
+ setp is one beyond
+
+ to repeat an element:
+ setp--; / *repeat* /
+
+ at exit:
+ set == NULL at end of loop
+
+ example
+ FOREACHset_(sets) {
+
+ notes:
+ WARNING: needs braces if nested inside another FOREACH
+*/
+#define FOREACHset_(sets) FOREACHsetelement_(setT, sets, set)
+
+/*-<a href="qh-set.htm#TOC"
+ >-----------------------------------------</a><a name="SETindex_">-</a>
+
+ SETindex_( set, elem )
+ return index of elem in set
+
+ notes:
+ for use with FOREACH iteration
+ WARN64 -- Maximum set size is 2G
+
+ example:
+ i= SETindex_(ridges, ridge)
+*/
+#define SETindex_(set, elem) ((int)((void **)elem##p - (void **)&(set)->e[1].p))
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETref_">-</a>
+
+ SETref_( elem )
+ l.h.s. for modifying the current element in a FOREACH iteration
+
+ example:
+ SETref_(ridge)= anotherridge;
+*/
+#define SETref_(elem) (elem##p[-1])
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETelem_">-</a>
+
+ SETelem_(set, n)
+ return the n'th element of set
+
+ notes:
+ assumes that n is valid [0..size] and that set is defined
+ use SETelemt_() for type cast
+*/
+#define SETelem_(set, n) ((set)->e[n].p)
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETelemt_">-</a>
+
+ SETelemt_(set, n, type)
+ return the n'th element of set as a type
+
+ notes:
+ assumes that n is valid [0..size] and that set is defined
+*/
+#define SETelemt_(set, n, type) ((type*)((set)->e[n].p))
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETelemaddr_">-</a>
+
+ SETelemaddr_(set, n, type)
+ return address of the n'th element of a set
+
+ notes:
+ assumes that n is valid [0..size] and set is defined
+*/
+#define SETelemaddr_(set, n, type) ((type **)(&((set)->e[n].p)))
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETfirst_">-</a>
+
+ SETfirst_(set)
+ return first element of set
+
+*/
+#define SETfirst_(set) ((set)->e[0].p)
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETfirstt_">-</a>
+
+ SETfirstt_(set, type)
+ return first element of set as a type
+
+*/
+#define SETfirstt_(set, type) ((type*)((set)->e[0].p))
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETsecond_">-</a>
+
+ SETsecond_(set)
+ return second element of set
+
+*/
+#define SETsecond_(set) ((set)->e[1].p)
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETsecondt_">-</a>
+
+ SETsecondt_(set, type)
+ return second element of set as a type
+*/
+#define SETsecondt_(set, type) ((type*)((set)->e[1].p))
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETaddr_">-</a>
+
+ SETaddr_(set, type)
+ return address of set's elements
+*/
+#define SETaddr_(set,type) ((type **)(&((set)->e[0].p)))
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETreturnsize_">-</a>
+
+ SETreturnsize_(set, size)
+ return size of a set
+
+ notes:
+ set must be defined
+ use qh_setsize(set) unless speed is critical
+*/
+#define SETreturnsize_(set, size) (((size)= ((set)->e[(set)->maxsize].i))?(--(size)):((size)= (set)->maxsize))
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETempty_">-</a>
+
+ SETempty_(set)
+ return true(1) if set is empty
+
+ notes:
+ set may be NULL
+*/
+#define SETempty_(set) (!set || (SETfirst_(set) ? 0 : 1))
+
+/*-<a href="qh-set.htm#TOC"
+ >-------------------------------<a name="SETsizeaddr_">-</a>
+
+ SETsizeaddr_(set)
+ return pointer to 'actual size+1' of set (set CANNOT be NULL!!)
+ Its type is setelemT* for strict aliasing
+ All SETelemaddr_ must be cast to setelemT
+
+
+ notes:
+ *SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL
+*/
+#define SETsizeaddr_(set) (&((set)->e[(set)->maxsize]))
+
+/*-<a href="qh-set.htm#TOC"
+ >---------------------------------------</a><a name="SETtruncate_">-</a>
+
+ SETtruncate_(set, size)
+ truncate set to size
+
+ see:
+ qh_settruncate()
+
+*/
+#define SETtruncate_(set, size) {set->e[set->maxsize].i= size+1; /* maybe overwritten */ \
+ set->e[size].p= NULL;}
+
+/*======= prototypes in alphabetical order ============*/
+
+void qh_setaddsorted(setT **setp, void *elem);
+void qh_setaddnth(setT **setp, int nth, void *newelem);
+void qh_setappend(setT **setp, void *elem);
+void qh_setappend_set(setT **setp, setT *setA);
+void qh_setappend2ndlast(setT **setp, void *elem);
+void qh_setcheck(setT *set, const char *tname, unsigned id);
+void qh_setcompact(setT *set);
+setT *qh_setcopy(setT *set, int extra);
+void *qh_setdel(setT *set, void *elem);
+void *qh_setdellast(setT *set);
+void *qh_setdelnth(setT *set, int nth);
+void *qh_setdelnthsorted(setT *set, int nth);
+void *qh_setdelsorted(setT *set, void *newelem);
+setT *qh_setduplicate( setT *set, int elemsize);
+void **qh_setendpointer(setT *set);
+int qh_setequal(setT *setA, setT *setB);
+int qh_setequal_except(setT *setA, void *skipelemA, setT *setB, void *skipelemB);
+int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB);
+void qh_setfree(setT **set);
+void qh_setfree2( setT **setp, int elemsize);
+void qh_setfreelong(setT **set);
+int qh_setin(setT *set, void *setelem);
+int qh_setindex(setT *set, void *setelem);
+void qh_setlarger(setT **setp);
+void *qh_setlast(setT *set);
+setT *qh_setnew(int size);
+setT *qh_setnew_delnthsorted(setT *set, int size, int nth, int prepend);
+void qh_setprint(FILE *fp, const char* string, setT *set);
+void qh_setreplace(setT *set, void *oldelem, void *newelem);
+int qh_setsize(setT *set);
+setT *qh_settemp(int setsize);
+void qh_settempfree(setT **set);
+void qh_settempfree_all(void);
+setT *qh_settemppop(void);
+void qh_settemppush(setT *set);
+void qh_settruncate(setT *set, int size);
+int qh_setunique(setT **set, void *elem);
+void qh_setzero(setT *set, int idx, int size);
+
+
+#endif /* qhDEFset */
diff --git a/xs/src/qhull/src/libqhull/random.c b/xs/src/qhull/src/libqhull/random.c
new file mode 100644
index 000000000..176d697ae
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/random.c
@@ -0,0 +1,245 @@
+/*<html><pre> -<a href="index.htm#TOC"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ random.c and utilities
+ Park & Miller's minimimal standard random number generator
+ argc/argv conversion
+
+ Used by rbox. Do not use 'qh'
+*/
+
+#include "libqhull.h"
+#include "random.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
+#pragma warning( disable : 4706) /* assignment within conditional function */
+#pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
+#endif
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="argv_to_command">-</a>
+
+ qh_argv_to_command( argc, argv, command, max_size )
+
+ build command from argc/argv
+ max_size is at least
+
+ returns:
+ a space-delimited string of options (just as typed)
+ returns false if max_size is too short
+
+ notes:
+ silently removes
+ makes option string easy to input and output
+ matches qh_argv_to_command_size()
+
+ argc may be 0
+*/
+int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
+ int i, remaining;
+ char *s;
+ *command= '\0'; /* max_size > 0 */
+
+ if (argc) {
+ if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
+ || (s= strrchr( argv[0], '/')))
+ s++;
+ else
+ s= argv[0];
+ if ((int)strlen(s) < max_size) /* WARN64 */
+ strcpy(command, s);
+ else
+ goto error_argv;
+ if ((s= strstr(command, ".EXE"))
+ || (s= strstr(command, ".exe")))
+ *s= '\0';
+ }
+ for (i=1; i < argc; i++) {
+ s= argv[i];
+ remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2; /* WARN64 */
+ if (!*s || strchr(s, ' ')) {
+ char *t= command + strlen(command);
+ remaining -= 2;
+ if (remaining < 0) {
+ goto error_argv;
+ }
+ *t++= ' ';
+ *t++= '"';
+ while (*s) {
+ if (*s == '"') {
+ if (--remaining < 0)
+ goto error_argv;
+ *t++= '\\';
+ }
+ *t++= *s++;
+ }
+ *t++= '"';
+ *t= '\0';
+ }else if (remaining < 0) {
+ goto error_argv;
+ }else
+ strcat(command, " ");
+ strcat(command, s);
+ }
+ return 1;
+
+error_argv:
+ return 0;
+} /* argv_to_command */
+
+/*-<a href="qh-globa.htm#TOC"
+>-------------------------------</a><a name="argv_to_command_size">-</a>
+
+qh_argv_to_command_size( argc, argv )
+
+ return size to allocate for qh_argv_to_command()
+
+notes:
+ argc may be 0
+ actual size is usually shorter
+*/
+int qh_argv_to_command_size(int argc, char *argv[]) {
+ unsigned int count= 1; /* null-terminator if argc==0 */
+ int i;
+ char *s;
+
+ for (i=0; i<argc; i++){
+ count += (int)strlen(argv[i]) + 1; /* WARN64 */
+ if (i>0 && strchr(argv[i], ' ')) {
+ count += 2; /* quote delimiters */
+ for (s=argv[i]; *s; s++) {
+ if (*s == '"') {
+ count++;
+ }
+ }
+ }
+ }
+ return count;
+} /* argv_to_command_size */
+
+/*-<a href="qh-geom.htm#TOC"
+ >-------------------------------</a><a name="rand">-</a>
+
+ qh_rand()
+ qh_srand( seed )
+ generate pseudo-random number between 1 and 2^31 -2
+
+ notes:
+ For qhull and rbox, called from qh_RANDOMint(),etc. [user.h]
+
+ From Park & Miller's minimal standard random number generator
+ Communications of the ACM, 31:1192-1201, 1988.
+ Does not use 0 or 2^31 -1
+ this is silently enforced by qh_srand()
+ Can make 'Rn' much faster by moving qh_rand to qh_distplane
+*/
+
+/* Global variables and constants */
+
+int qh_last_random= 1; /* define as global variable instead of using qh */
+
+#define qh_rand_a 16807
+#define qh_rand_m 2147483647
+#define qh_rand_q 127773 /* m div a */
+#define qh_rand_r 2836 /* m mod a */
+
+int qh_rand( void) {
+ int lo, hi, test;
+ int seed = qh_last_random;
+
+ hi = seed / qh_rand_q; /* seed div q */
+ lo = seed % qh_rand_q; /* seed mod q */
+ test = qh_rand_a * lo - qh_rand_r * hi;
+ if (test > 0)
+ seed= test;
+ else
+ seed= test + qh_rand_m;
+ qh_last_random= seed;
+ /* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax; for testing */
+ /* seed = qh_RANDOMmax; for testing */
+ return seed;
+} /* rand */
+
+void qh_srand( int seed) {
+ if (seed < 1)
+ qh_last_random= 1;
+ else if (seed >= qh_rand_m)
+ qh_last_random= qh_rand_m - 1;
+ else
+ qh_last_random= seed;
+} /* qh_srand */
+
+/*-<a href="qh-geom.htm#TOC"
+>-------------------------------</a><a name="randomfactor">-</a>
+
+qh_randomfactor( scale, offset )
+ return a random factor r * scale + offset
+
+notes:
+ qh.RANDOMa/b are defined in global.c
+*/
+realT qh_randomfactor(realT scale, realT offset) {
+ realT randr;
+
+ randr= qh_RANDOMint;
+ return randr * scale + offset;
+} /* randomfactor */
+
+/*-<a href="qh-geom.htm#TOC"
+>-------------------------------</a><a name="randommatrix">-</a>
+
+qh_randommatrix( buffer, dim, rows )
+ generate a random dim X dim matrix in range [-1,1]
+ assumes buffer is [dim+1, dim]
+
+returns:
+ sets buffer to random numbers
+ sets rows to rows of buffer
+ sets row[dim] as scratch row
+*/
+void qh_randommatrix(realT *buffer, int dim, realT **rows) {
+ int i, k;
+ realT **rowi, *coord, realr;
+
+ coord= buffer;
+ rowi= rows;
+ for (i=0; i < dim; i++) {
+ *(rowi++)= coord;
+ for (k=0; k < dim; k++) {
+ realr= qh_RANDOMint;
+ *(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
+ }
+ }
+ *rowi= coord;
+} /* randommatrix */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="strtol">-</a>
+
+ qh_strtol( s, endp) qh_strtod( s, endp)
+ internal versions of strtol() and strtod()
+ does not skip trailing spaces
+ notes:
+ some implementations of strtol()/strtod() skip trailing spaces
+*/
+double qh_strtod(const char *s, char **endp) {
+ double result;
+
+ result= strtod(s, endp);
+ if (s < (*endp) && (*endp)[-1] == ' ')
+ (*endp)--;
+ return result;
+} /* strtod */
+
+int qh_strtol(const char *s, char **endp) {
+ int result;
+
+ result= (int) strtol(s, endp, 10); /* WARN64 */
+ if (s< (*endp) && (*endp)[-1] == ' ')
+ (*endp)--;
+ return result;
+} /* strtol */
diff --git a/xs/src/qhull/src/libqhull/random.h b/xs/src/qhull/src/libqhull/random.h
new file mode 100644
index 000000000..0c6896b76
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/random.h
@@ -0,0 +1,34 @@
+/*<html><pre> -<a href="qh-geom.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ random.h
+ header file for random and utility routines
+
+ see qh-geom.htm and random.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/random.h#2 $$Change: 2026 $
+ $DateTime: 2015/11/07 22:44:39 $$Author: bbarber $
+*/
+
+#ifndef qhDEFrandom
+#define qhDEFrandom 1
+
+#include "libqhull.h"
+
+/*============= prototypes in alphabetical order ======= */
+
+
+int qh_argv_to_command(int argc, char *argv[], char* command, int max_size);
+int qh_argv_to_command_size(int argc, char *argv[]);
+int qh_rand( void);
+void qh_srand( int seed);
+realT qh_randomfactor(realT scale, realT offset);
+void qh_randommatrix(realT *buffer, int dim, realT **row);
+int qh_strtol(const char *s, char **endp);
+double qh_strtod(const char *s, char **endp);
+
+#endif /* qhDEFrandom */
+
+
+
diff --git a/xs/src/qhull/src/libqhull/rboxlib.c b/xs/src/qhull/src/libqhull/rboxlib.c
new file mode 100644
index 000000000..f945133fa
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/rboxlib.c
@@ -0,0 +1,870 @@
+/*<html><pre> -<a href="index.htm#TOC"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ rboxlib.c
+ Generate input points
+
+ notes:
+ For documentation, see prompt[] of rbox.c
+ 50 points generated for 'rbox D4'
+
+ WARNING:
+ incorrect range if qh_RANDOMmax is defined wrong (user.h)
+*/
+
+#include "libqhull.h" /* First for user.h */
+#include "random.h"
+
+#include <ctype.h>
+#include <limits.h>
+#include <math.h>
+#include <setjmp.h>
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef _MSC_VER /* Microsoft Visual C++ */
+#pragma warning( disable : 4706) /* assignment within conditional expression. */
+#pragma warning( disable : 4996) /* this function (strncat,sprintf,strcpy) or variable may be unsafe. */
+#endif
+
+#define MAXdim 200
+#define PI 3.1415926535897932384
+
+/* ------------------------------ prototypes ----------------*/
+int qh_roundi( double a);
+void qh_out1( double a);
+void qh_out2n( double a, double b);
+void qh_out3n( double a, double b, double c);
+void qh_outcoord(int iscdd, double *coord, int dim);
+void qh_outcoincident(int coincidentpoints, double radius, int iscdd, double *coord, int dim);
+
+void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... );
+void qh_free(void *mem);
+void *qh_malloc(size_t size);
+int qh_rand( void);
+void qh_srand( int seed);
+
+
+/* ------------------------------ globals -------------------*/
+
+/* No state is carried between rbox requests */
+typedef struct rboxT rboxT;
+struct rboxT {
+ FILE *fout;
+ FILE *ferr;
+ int isinteger;
+ double out_offset;
+ jmp_buf errexit; /* exit label for rboxpoints, defined by setjmp(), called by qh_errexit_rbox() */
+ char jmpXtra[40]; /* extra bytes in case jmp_buf is defined wrong by compiler */
+};
+
+
+int rbox_inuse= 0;
+rboxT rbox;
+
+/*-<a href="qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="rboxpoints">-</a>
+
+ qh_rboxpoints( fout, ferr, rbox_command )
+ Generate points to fout according to rbox options
+ Report errors on ferr
+
+ returns:
+ 0 (qh_ERRnone) on success
+ 1 (qh_ERRinput) on input error
+ 4 (qh_ERRmem) on memory error
+ 5 (qh_ERRqhull) on internal error
+
+ notes:
+ To avoid using stdio, redefine qh_malloc, qh_free, and qh_fprintf_rbox (user.c)
+
+ design:
+ Straight line code (consider defining a struct and functions):
+
+ Parse arguments into variables
+ Determine the number of points
+ Generate the points
+*/
+int qh_rboxpoints(FILE* fout, FILE* ferr, char* rbox_command) {
+ int i,j,k;
+ int gendim;
+ int coincidentcount=0, coincidenttotal=0, coincidentpoints=0;
+ int cubesize, diamondsize, seed=0, count, apex;
+ int dim=3, numpoints=0, totpoints, addpoints=0;
+ int issphere=0, isaxis=0, iscdd=0, islens=0, isregular=0, iswidth=0, addcube=0;
+ int isgap=0, isspiral=0, NOcommand=0, adddiamond=0;
+ int israndom=0, istime=0;
+ int isbox=0, issimplex=0, issimplex2=0, ismesh=0;
+ double width=0.0, gap=0.0, radius=0.0, coincidentradius=0.0;
+ double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
+ double *coordp, *simplex= NULL, *simplexp;
+ int nthroot, mult[MAXdim];
+ double norm, factor, randr, rangap, lensangle=0, lensbase=1;
+ double anglediff, angle, x, y, cube=0.0, diamond=0.0;
+ double box= qh_DEFAULTbox; /* scale all numbers before output */
+ double randmax= qh_RANDOMmax;
+ char command[200], seedbuf[200];
+ char *s= command, *t, *first_point= NULL;
+ time_t timedata;
+ int exitcode;
+
+ if (rbox_inuse) {
+ qh_fprintf_rbox(rbox.ferr, 6188, "rbox error: rbox in use by another process. Please lock calls to rbox.\n");
+ return qh_ERRqhull;
+ }
+ rbox_inuse= True;
+ rbox.ferr= ferr;
+ rbox.fout= fout;
+
+ exitcode= setjmp(rbox.errexit);
+ if (exitcode) {
+ /* same code for error exit and normal return. qh.NOerrexit is set */
+ if (simplex)
+ qh_free(simplex);
+ rbox_inuse= False;
+ return exitcode;
+ }
+
+ *command= '\0';
+ strncat(command, rbox_command, sizeof(command)-strlen(command)-1);
+
+ while (*s && !isspace(*s)) /* skip program name */
+ s++;
+ while (*s) {
+ while (*s && isspace(*s))
+ s++;
+ if (*s == '-')
+ s++;
+ if (!*s)
+ break;
+ if (isdigit(*s)) {
+ numpoints= qh_strtol(s, &s);
+ continue;
+ }
+ /* ============= read flags =============== */
+ switch (*s++) {
+ case 'c':
+ addcube= 1;
+ t= s;
+ while (isspace(*t))
+ t++;
+ if (*t == 'G')
+ cube= qh_strtod(++t, &s);
+ break;
+ case 'd':
+ adddiamond= 1;
+ t= s;
+ while (isspace(*t))
+ t++;
+ if (*t == 'G')
+ diamond= qh_strtod(++t, &s);
+ break;
+ case 'h':
+ iscdd= 1;
+ break;
+ case 'l':
+ isspiral= 1;
+ break;
+ case 'n':
+ NOcommand= 1;
+ break;
+ case 'r':
+ isregular= 1;
+ break;
+ case 's':
+ issphere= 1;
+ break;
+ case 't':
+ istime= 1;
+ if (isdigit(*s)) {
+ seed= qh_strtol(s, &s);
+ israndom= 0;
+ }else
+ israndom= 1;
+ break;
+ case 'x':
+ issimplex= 1;
+ break;
+ case 'y':
+ issimplex2= 1;
+ break;
+ case 'z':
+ rbox.isinteger= 1;
+ break;
+ case 'B':
+ box= qh_strtod(s, &s);
+ isbox= 1;
+ break;
+ case 'C':
+ if (*s)
+ coincidentpoints= qh_strtol(s, &s);
+ if (*s == ',') {
+ ++s;
+ coincidentradius= qh_strtod(s, &s);
+ }
+ if (*s == ',') {
+ ++s;
+ coincidenttotal= qh_strtol(s, &s);
+ }
+ if (*s && !isspace(*s)) {
+ qh_fprintf_rbox(rbox.ferr, 7080, "rbox error: arguments for 'Cn,r,m' are not 'int', 'float', and 'int'. Remaining string is '%s'\n", s);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ if (coincidentpoints==0){
+ qh_fprintf_rbox(rbox.ferr, 6268, "rbox error: missing arguments for 'Cn,r,m' where n is the number of coincident points, r is the radius (default 0.0), and m is the number of points\n");
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ if (coincidentpoints<0 || coincidenttotal<0 || coincidentradius<0.0){
+ qh_fprintf_rbox(rbox.ferr, 6269, "rbox error: negative arguments for 'Cn,m,r' where n (%d) is the number of coincident points, m (%d) is the number of points, and r (%.2g) is the radius (default 0.0)\n", coincidentpoints, coincidenttotal, coincidentradius);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ break;
+ case 'D':
+ dim= qh_strtol(s, &s);
+ if (dim < 1
+ || dim > MAXdim) {
+ qh_fprintf_rbox(rbox.ferr, 6189, "rbox error: dimension, D%d, out of bounds (>=%d or <=0)", dim, MAXdim);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ break;
+ case 'G':
+ if (isdigit(*s))
+ gap= qh_strtod(s, &s);
+ else
+ gap= 0.5;
+ isgap= 1;
+ break;
+ case 'L':
+ if (isdigit(*s))
+ radius= qh_strtod(s, &s);
+ else
+ radius= 10;
+ islens= 1;
+ break;
+ case 'M':
+ ismesh= 1;
+ if (*s)
+ meshn= qh_strtod(s, &s);
+ if (*s == ',') {
+ ++s;
+ meshm= qh_strtod(s, &s);
+ }else
+ meshm= 0.0;
+ if (*s == ',') {
+ ++s;
+ meshr= qh_strtod(s, &s);
+ }else
+ meshr= sqrt(meshn*meshn + meshm*meshm);
+ if (*s && !isspace(*s)) {
+ qh_fprintf_rbox(rbox.ferr, 7069, "rbox warning: assuming 'M3,4,5' since mesh args are not integers or reals\n");
+ meshn= 3.0, meshm=4.0, meshr=5.0;
+ }
+ break;
+ case 'O':
+ rbox.out_offset= qh_strtod(s, &s);
+ break;
+ case 'P':
+ if (!first_point)
+ first_point= s-1;
+ addpoints++;
+ while (*s && !isspace(*s)) /* read points later */
+ s++;
+ break;
+ case 'W':
+ width= qh_strtod(s, &s);
+ iswidth= 1;
+ break;
+ case 'Z':
+ if (isdigit(*s))
+ radius= qh_strtod(s, &s);
+ else
+ radius= 1.0;
+ isaxis= 1;
+ break;
+ default:
+ qh_fprintf_rbox(rbox.ferr, 7070, "rbox error: unknown flag at %s.\nExecute 'rbox' without arguments for documentation.\n", s);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ if (*s && !isspace(*s)) {
+ qh_fprintf_rbox(rbox.ferr, 7071, "rbox error: missing space between flags at %s.\n", s);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ }
+
+ /* ============= defaults, constants, and sizes =============== */
+ if (rbox.isinteger && !isbox)
+ box= qh_DEFAULTzbox;
+ if (addcube) {
+ cubesize= (int)floor(ldexp(1.0,dim)+0.5);
+ if (cube == 0.0)
+ cube= box;
+ }else
+ cubesize= 0;
+ if (adddiamond) {
+ diamondsize= 2*dim;
+ if (diamond == 0.0)
+ diamond= box;
+ }else
+ diamondsize= 0;
+ if (islens) {
+ if (isaxis) {
+ qh_fprintf_rbox(rbox.ferr, 6190, "rbox error: can not combine 'Ln' with 'Zn'\n");
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ if (radius <= 1.0) {
+ qh_fprintf_rbox(rbox.ferr, 6191, "rbox error: lens radius %.2g should be greater than 1.0\n",
+ radius);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ lensangle= asin(1.0/radius);
+ lensbase= radius * cos(lensangle);
+ }
+
+ if (!numpoints) {
+ if (issimplex2)
+ ; /* ok */
+ else if (isregular + issimplex + islens + issphere + isaxis + isspiral + iswidth + ismesh) {
+ qh_fprintf_rbox(rbox.ferr, 6192, "rbox error: missing count\n");
+ qh_errexit_rbox(qh_ERRinput);
+ }else if (adddiamond + addcube + addpoints)
+ ; /* ok */
+ else {
+ numpoints= 50; /* ./rbox D4 is the test case */
+ issphere= 1;
+ }
+ }
+ if ((issimplex + islens + isspiral + ismesh > 1)
+ || (issimplex + issphere + isspiral + ismesh > 1)) {
+ qh_fprintf_rbox(rbox.ferr, 6193, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n");
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ if (coincidentpoints>0 && (numpoints == 0 || coincidenttotal > numpoints)) {
+ qh_fprintf_rbox(rbox.ferr, 6270, "rbox error: 'Cn,r,m' requested n coincident points for each of m points. Either there is no points or m (%d) is greater than the number of points (%d).\n", coincidenttotal, numpoints);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ if (coincidenttotal == 0)
+ coincidenttotal= numpoints;
+
+ /* ============= print header with total points =============== */
+ if (issimplex || ismesh)
+ totpoints= numpoints;
+ else if (issimplex2)
+ totpoints= numpoints+dim+1;
+ else if (isregular) {
+ totpoints= numpoints;
+ if (dim == 2) {
+ if (islens)
+ totpoints += numpoints - 2;
+ }else if (dim == 3) {
+ if (islens)
+ totpoints += 2 * numpoints;
+ else if (isgap)
+ totpoints += 1 + numpoints;
+ else
+ totpoints += 2;
+ }
+ }else
+ totpoints= numpoints + isaxis;
+ totpoints += cubesize + diamondsize + addpoints;
+ totpoints += coincidentpoints*coincidenttotal;
+
+ /* ============= seed randoms =============== */
+ if (istime == 0) {
+ for (s=command; *s; s++) {
+ if (issimplex2 && *s == 'y') /* make 'y' same seed as 'x' */
+ i= 'x';
+ else
+ i= *s;
+ seed= 11*seed + i;
+ }
+ }else if (israndom) {
+ seed= (int)time(&timedata);
+ sprintf(seedbuf, " t%d", seed); /* appends an extra t, not worth removing */
+ strncat(command, seedbuf, sizeof(command)-strlen(command)-1);
+ t= strstr(command, " t ");
+ if (t)
+ strcpy(t+1, t+3); /* remove " t " */
+ } /* else, seed explicitly set to n */
+ qh_RANDOMseed_(seed);
+
+ /* ============= print header =============== */
+
+ if (iscdd)
+ qh_fprintf_rbox(rbox.fout, 9391, "%s\nbegin\n %d %d %s\n",
+ NOcommand ? "" : command,
+ totpoints, dim+1,
+ rbox.isinteger ? "integer" : "real");
+ else if (NOcommand)
+ qh_fprintf_rbox(rbox.fout, 9392, "%d\n%d\n", dim, totpoints);
+ else
+ /* qh_fprintf_rbox special cases 9393 to append 'command' to the RboxPoints.comment() */
+ qh_fprintf_rbox(rbox.fout, 9393, "%d %s\n%d\n", dim, command, totpoints);
+
+ /* ============= explicit points =============== */
+ if ((s= first_point)) {
+ while (s && *s) { /* 'P' */
+ count= 0;
+ if (iscdd)
+ qh_out1( 1.0);
+ while (*++s) {
+ qh_out1( qh_strtod(s, &s));
+ count++;
+ if (isspace(*s) || !*s)
+ break;
+ if (*s != ',') {
+ qh_fprintf_rbox(rbox.ferr, 6194, "rbox error: missing comma after coordinate in %s\n\n", s);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ }
+ if (count < dim) {
+ for (k=dim-count; k--; )
+ qh_out1( 0.0);
+ }else if (count > dim) {
+ qh_fprintf_rbox(rbox.ferr, 6195, "rbox error: %d coordinates instead of %d coordinates in %s\n\n",
+ count, dim, s);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ qh_fprintf_rbox(rbox.fout, 9394, "\n");
+ while ((s= strchr(s, 'P'))) {
+ if (isspace(s[-1]))
+ break;
+ }
+ }
+ }
+
+ /* ============= simplex distribution =============== */
+ if (issimplex+issimplex2) {
+ if (!(simplex= (double*)qh_malloc( dim * (dim+1) * sizeof(double)))) {
+ qh_fprintf_rbox(rbox.ferr, 6196, "rbox error: insufficient memory for simplex\n");
+ qh_errexit_rbox(qh_ERRmem); /* qh_ERRmem */
+ }
+ simplexp= simplex;
+ if (isregular) {
+ for (i=0; i<dim; i++) {
+ for (k=0; k<dim; k++)
+ *(simplexp++)= i==k ? 1.0 : 0.0;
+ }
+ for (k=0; k<dim; k++)
+ *(simplexp++)= -1.0;
+ }else {
+ for (i=0; i<dim+1; i++) {
+ for (k=0; k<dim; k++) {
+ randr= qh_RANDOMint;
+ *(simplexp++)= 2.0 * randr/randmax - 1.0;
+ }
+ }
+ }
+ if (issimplex2) {
+ simplexp= simplex;
+ for (i=0; i<dim+1; i++) {
+ if (iscdd)
+ qh_out1( 1.0);
+ for (k=0; k<dim; k++)
+ qh_out1( *(simplexp++) * box);
+ qh_fprintf_rbox(rbox.fout, 9395, "\n");
+ }
+ }
+ for (j=0; j<numpoints; j++) {
+ if (iswidth)
+ apex= qh_RANDOMint % (dim+1);
+ else
+ apex= -1;
+ for (k=0; k<dim; k++)
+ coord[k]= 0.0;
+ norm= 0.0;
+ for (i=0; i<dim+1; i++) {
+ randr= qh_RANDOMint;
+ factor= randr/randmax;
+ if (i == apex)
+ factor *= width;
+ norm += factor;
+ for (k=0; k<dim; k++) {
+ simplexp= simplex + i*dim + k;
+ coord[k] += factor * (*simplexp);
+ }
+ }
+ for (k=0; k<dim; k++)
+ coord[k] *= box/norm;
+ qh_outcoord(iscdd, coord, dim);
+ if(coincidentcount++ < coincidenttotal)
+ qh_outcoincident(coincidentpoints, coincidentradius, iscdd, coord, dim);
+ }
+ isregular= 0; /* continue with isbox */
+ numpoints= 0;
+ }
+
+ /* ============= mesh distribution =============== */
+ if (ismesh) {
+ nthroot= (int)(pow((double)numpoints, 1.0/dim) + 0.99999);
+ for (k=dim; k--; )
+ mult[k]= 0;
+ for (i=0; i < numpoints; i++) {
+ coordp= coord;
+ for (k=0; k < dim; k++) {
+ if (k == 0)
+ *(coordp++)= mult[0] * meshn + mult[1] * (-meshm);
+ else if (k == 1)
+ *(coordp++)= mult[0] * meshm + mult[1] * meshn;
+ else
+ *(coordp++)= mult[k] * meshr;
+ }
+ qh_outcoord(iscdd, coord, dim);
+ if(coincidentcount++ < coincidenttotal)
+ qh_outcoincident(coincidentpoints, coincidentradius, iscdd, coord, dim);
+ for (k=0; k < dim; k++) {
+ if (++mult[k] < nthroot)
+ break;
+ mult[k]= 0;
+ }
+ }
+ }
+ /* ============= regular points for 's' =============== */
+ else if (isregular && !islens) {
+ if (dim != 2 && dim != 3) {
+ qh_free(simplex);
+ qh_fprintf_rbox(rbox.ferr, 6197, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ if (!isaxis || radius == 0.0) {
+ isaxis= 1;
+ radius= 1.0;
+ }
+ if (dim == 3) {
+ if (iscdd)
+ qh_out1( 1.0);
+ qh_out3n( 0.0, 0.0, -box);
+ if (!isgap) {
+ if (iscdd)
+ qh_out1( 1.0);
+ qh_out3n( 0.0, 0.0, box);
+ }
+ }
+ angle= 0.0;
+ anglediff= 2.0 * PI/numpoints;
+ for (i=0; i < numpoints; i++) {
+ angle += anglediff;
+ x= radius * cos(angle);
+ y= radius * sin(angle);
+ if (dim == 2) {
+ if (iscdd)
+ qh_out1( 1.0);
+ qh_out2n( x*box, y*box);
+ }else {
+ norm= sqrt(1.0 + x*x + y*y);
+ if (iscdd)
+ qh_out1( 1.0);
+ qh_out3n( box*x/norm, box*y/norm, box/norm);
+ if (isgap) {
+ x *= 1-gap;
+ y *= 1-gap;
+ norm= sqrt(1.0 + x*x + y*y);
+ if (iscdd)
+ qh_out1( 1.0);
+ qh_out3n( box*x/norm, box*y/norm, box/norm);
+ }
+ }
+ }
+ }
+ /* ============= regular points for 'r Ln D2' =============== */
+ else if (isregular && islens && dim == 2) {
+ double cos_0;
+
+ angle= lensangle;
+ anglediff= 2 * lensangle/(numpoints - 1);
+ cos_0= cos(lensangle);
+ for (i=0; i < numpoints; i++, angle -= anglediff) {
+ x= radius * sin(angle);
+ y= radius * (cos(angle) - cos_0);
+ if (iscdd)
+ qh_out1( 1.0);
+ qh_out2n( x*box, y*box);
+ if (i != 0 && i != numpoints - 1) {
+ if (iscdd)
+ qh_out1( 1.0);
+ qh_out2n( x*box, -y*box);
+ }
+ }
+ }
+ /* ============= regular points for 'r Ln D3' =============== */
+ else if (isregular && islens && dim != 2) {
+ if (dim != 3) {
+ qh_free(simplex);
+ qh_fprintf_rbox(rbox.ferr, 6198, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ angle= 0.0;
+ anglediff= 2* PI/numpoints;
+ if (!isgap) {
+ isgap= 1;
+ gap= 0.5;
+ }
+ offset= sqrt(radius * radius - (1-gap)*(1-gap)) - lensbase;
+ for (i=0; i < numpoints; i++, angle += anglediff) {
+ x= cos(angle);
+ y= sin(angle);
+ if (iscdd)
+ qh_out1( 1.0);
+ qh_out3n( box*x, box*y, 0.0);
+ x *= 1-gap;
+ y *= 1-gap;
+ if (iscdd)
+ qh_out1( 1.0);
+ qh_out3n( box*x, box*y, box * offset);
+ if (iscdd)
+ qh_out1( 1.0);
+ qh_out3n( box*x, box*y, -box * offset);
+ }
+ }
+ /* ============= apex of 'Zn' distribution + gendim =============== */
+ else {
+ if (isaxis) {
+ gendim= dim-1;
+ if (iscdd)
+ qh_out1( 1.0);
+ for (j=0; j < gendim; j++)
+ qh_out1( 0.0);
+ qh_out1( -box);
+ qh_fprintf_rbox(rbox.fout, 9398, "\n");
+ }else if (islens)
+ gendim= dim-1;
+ else
+ gendim= dim;
+ /* ============= generate random point in unit cube =============== */
+ for (i=0; i < numpoints; i++) {
+ norm= 0.0;
+ for (j=0; j < gendim; j++) {
+ randr= qh_RANDOMint;
+ coord[j]= 2.0 * randr/randmax - 1.0;
+ norm += coord[j] * coord[j];
+ }
+ norm= sqrt(norm);
+ /* ============= dim-1 point of 'Zn' distribution ========== */
+ if (isaxis) {
+ if (!isgap) {
+ isgap= 1;
+ gap= 1.0;
+ }
+ randr= qh_RANDOMint;
+ rangap= 1.0 - gap * randr/randmax;
+ factor= radius * rangap / norm;
+ for (j=0; j<gendim; j++)
+ coord[j]= factor * coord[j];
+ /* ============= dim-1 point of 'Ln s' distribution =========== */
+ }else if (islens && issphere) {
+ if (!isgap) {
+ isgap= 1;
+ gap= 1.0;
+ }
+ randr= qh_RANDOMint;
+ rangap= 1.0 - gap * randr/randmax;
+ factor= rangap / norm;
+ for (j=0; j<gendim; j++)
+ coord[j]= factor * coord[j];
+ /* ============= dim-1 point of 'Ln' distribution ========== */
+ }else if (islens && !issphere) {
+ if (!isgap) {
+ isgap= 1;
+ gap= 1.0;
+ }
+ j= qh_RANDOMint % gendim;
+ if (coord[j] < 0)
+ coord[j]= -1.0 - coord[j] * gap;
+ else
+ coord[j]= 1.0 - coord[j] * gap;
+ /* ============= point of 'l' distribution =============== */
+ }else if (isspiral) {
+ if (dim != 3) {
+ qh_free(simplex);
+ qh_fprintf_rbox(rbox.ferr, 6199, "rbox error: spiral distribution is available only in 3d\n\n");
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ coord[0]= cos(2*PI*i/(numpoints - 1));
+ coord[1]= sin(2*PI*i/(numpoints - 1));
+ coord[2]= 2.0*(double)i/(double)(numpoints-1) - 1.0;
+ /* ============= point of 's' distribution =============== */
+ }else if (issphere) {
+ factor= 1.0/norm;
+ if (iswidth) {
+ randr= qh_RANDOMint;
+ factor *= 1.0 - width * randr/randmax;
+ }
+ for (j=0; j<dim; j++)
+ coord[j]= factor * coord[j];
+ }
+ /* ============= project 'Zn s' point in to sphere =============== */
+ if (isaxis && issphere) {
+ coord[dim-1]= 1.0;
+ norm= 1.0;
+ for (j=0; j<gendim; j++)
+ norm += coord[j] * coord[j];
+ norm= sqrt(norm);
+ for (j=0; j<dim; j++)
+ coord[j]= coord[j] / norm;
+ if (iswidth) {
+ randr= qh_RANDOMint;
+ coord[dim-1] *= 1 - width * randr/randmax;
+ }
+ /* ============= project 'Zn' point onto cube =============== */
+ }else if (isaxis && !issphere) { /* not very interesting */
+ randr= qh_RANDOMint;
+ coord[dim-1]= 2.0 * randr/randmax - 1.0;
+ /* ============= project 'Ln' point out to sphere =============== */
+ }else if (islens) {
+ coord[dim-1]= lensbase;
+ for (j=0, norm= 0; j<dim; j++)
+ norm += coord[j] * coord[j];
+ norm= sqrt(norm);
+ for (j=0; j<dim; j++)
+ coord[j]= coord[j] * radius/ norm;
+ coord[dim-1] -= lensbase;
+ if (iswidth) {
+ randr= qh_RANDOMint;
+ coord[dim-1] *= 1 - width * randr/randmax;
+ }
+ if (qh_RANDOMint > randmax/2)
+ coord[dim-1]= -coord[dim-1];
+ /* ============= project 'Wn' point toward boundary =============== */
+ }else if (iswidth && !issphere) {
+ j= qh_RANDOMint % gendim;
+ if (coord[j] < 0)
+ coord[j]= -1.0 - coord[j] * width;
+ else
+ coord[j]= 1.0 - coord[j] * width;
+ }
+ /* ============= scale point to box =============== */
+ for (k=0; k<dim; k++)
+ coord[k]= coord[k] * box;
+
+ /* ============= write output =============== */
+ qh_outcoord(iscdd, coord, dim);
+ if(coincidentcount++ < coincidenttotal)
+ qh_outcoincident(coincidentpoints, coincidentradius, iscdd, coord, dim);
+ }
+ }
+
+ /* ============= write cube vertices =============== */
+ if (addcube) {
+ for (j=0; j<cubesize; j++) {
+ if (iscdd)
+ qh_out1( 1.0);
+ for (k=dim-1; k>=0; k--) {
+ if (j & ( 1 << k))
+ qh_out1( cube);
+ else
+ qh_out1( -cube);
+ }
+ qh_fprintf_rbox(rbox.fout, 9400, "\n");
+ }
+ }
+
+ /* ============= write diamond vertices =============== */
+ if (adddiamond) {
+ for (j=0; j<diamondsize; j++) {
+ if (iscdd)
+ qh_out1( 1.0);
+ for (k=dim-1; k>=0; k--) {
+ if (j/2 != k)
+ qh_out1( 0.0);
+ else if (j & 0x1)
+ qh_out1( diamond);
+ else
+ qh_out1( -diamond);
+ }
+ qh_fprintf_rbox(rbox.fout, 9401, "\n");
+ }
+ }
+
+ if (iscdd)
+ qh_fprintf_rbox(rbox.fout, 9402, "end\nhull\n");
+
+ /* same code for error exit and normal return */
+ qh_free(simplex);
+ rbox_inuse= False;
+ return qh_ERRnone;
+} /* rboxpoints */
+
+/*------------------------------------------------
+outxxx - output functions for qh_rboxpoints
+*/
+int qh_roundi( double a) {
+ if (a < 0.0) {
+ if (a - 0.5 < INT_MIN) {
+ qh_fprintf_rbox(rbox.ferr, 6200, "rbox input error: negative coordinate %2.2g is too large. Reduce 'Bn'\n", a);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ return (int)(a - 0.5);
+ }else {
+ if (a + 0.5 > INT_MAX) {
+ qh_fprintf_rbox(rbox.ferr, 6201, "rbox input error: coordinate %2.2g is too large. Reduce 'Bn'\n", a);
+ qh_errexit_rbox(qh_ERRinput);
+ }
+ return (int)(a + 0.5);
+ }
+} /* qh_roundi */
+
+void qh_out1(double a) {
+
+ if (rbox.isinteger)
+ qh_fprintf_rbox(rbox.fout, 9403, "%d ", qh_roundi( a+rbox.out_offset));
+ else
+ qh_fprintf_rbox(rbox.fout, 9404, qh_REAL_1, a+rbox.out_offset);
+} /* qh_out1 */
+
+void qh_out2n( double a, double b) {
+
+ if (rbox.isinteger)
+ qh_fprintf_rbox(rbox.fout, 9405, "%d %d\n", qh_roundi(a+rbox.out_offset), qh_roundi(b+rbox.out_offset));
+ else
+ qh_fprintf_rbox(rbox.fout, 9406, qh_REAL_2n, a+rbox.out_offset, b+rbox.out_offset);
+} /* qh_out2n */
+
+void qh_out3n( double a, double b, double c) {
+
+ if (rbox.isinteger)
+ qh_fprintf_rbox(rbox.fout, 9407, "%d %d %d\n", qh_roundi(a+rbox.out_offset), qh_roundi(b+rbox.out_offset), qh_roundi(c+rbox.out_offset));
+ else
+ qh_fprintf_rbox(rbox.fout, 9408, qh_REAL_3n, a+rbox.out_offset, b+rbox.out_offset, c+rbox.out_offset);
+} /* qh_out3n */
+
+void qh_outcoord(int iscdd, double *coord, int dim) {
+ double *p= coord;
+ int k;
+
+ if (iscdd)
+ qh_out1( 1.0);
+ for (k=0; k < dim; k++)
+ qh_out1(*(p++));
+ qh_fprintf_rbox(rbox.fout, 9396, "\n");
+} /* qh_outcoord */
+
+void qh_outcoincident(int coincidentpoints, double radius, int iscdd, double *coord, int dim) {
+ double *p;
+ double randr, delta;
+ int i,k;
+ double randmax= qh_RANDOMmax;
+
+ for (i= 0; i<coincidentpoints; i++) {
+ p= coord;
+ if (iscdd)
+ qh_out1( 1.0);
+ for (k=0; k < dim; k++) {
+ randr= qh_RANDOMint;
+ delta= 2.0 * randr/randmax - 1.0; /* -1..+1 */
+ delta *= radius;
+ qh_out1(*(p++) + delta);
+ }
+ qh_fprintf_rbox(rbox.fout, 9410, "\n");
+ }
+} /* qh_outcoincident */
+
+/*------------------------------------------------
+ Only called from qh_rboxpoints or qh_fprintf_rbox
+ qh_fprintf_rbox is only called from qh_rboxpoints
+*/
+void qh_errexit_rbox(int exitcode)
+{
+ longjmp(rbox.errexit, exitcode);
+} /* qh_errexit_rbox */
+
diff --git a/xs/src/qhull/src/libqhull/stat.c b/xs/src/qhull/src/libqhull/stat.c
new file mode 100644
index 000000000..70196bbb0
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/stat.c
@@ -0,0 +1,717 @@
+/*<html><pre> -<a href="qh-stat.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ stat.c
+ contains all statistics that are collected for qhull
+
+ see qh-stat.htm and stat.h
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/stat.c#5 $$Change: 2062 $
+ $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+*/
+
+#include "qhull_a.h"
+
+/*============ global data structure ==========*/
+
+#if qh_QHpointer
+qhstatT *qh_qhstat=NULL; /* global data structure */
+#else
+qhstatT qh_qhstat; /* add "={0}" if this causes a compiler error */
+#endif
+
+/*========== functions in alphabetic order ================*/
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="allstatA">-</a>
+
+ qh_allstatA()
+ define statistics in groups of 20
+
+ notes:
+ (otherwise, 'gcc -O2' uses too much memory)
+ uses qhstat.next
+*/
+void qh_allstatA(void) {
+
+ /* zdef_(type,name,doc,average) */
+ zzdef_(zdoc, Zdoc2, "precision statistics", -1);
+ zdef_(zinc, Znewvertex, NULL, -1);
+ zdef_(wadd, Wnewvertex, "ave. distance of a new vertex to a facet(!0s)", Znewvertex);
+ zzdef_(wmax, Wnewvertexmax, "max. distance of a new vertex to a facet", -1);
+ zdef_(wmax, Wvertexmax, "max. distance of an output vertex to a facet", -1);
+ zdef_(wmin, Wvertexmin, "min. distance of an output vertex to a facet", -1);
+ zdef_(wmin, Wmindenom, "min. denominator in hyperplane computation", -1);
+
+ qhstat precision= qhstat next; /* call qh_precision for each of these */
+ zzdef_(zdoc, Zdoc3, "precision problems (corrected unless 'Q0' or an error)", -1);
+ zzdef_(zinc, Zcoplanarridges, "coplanar half ridges in output", -1);
+ zzdef_(zinc, Zconcaveridges, "concave half ridges in output", -1);
+ zzdef_(zinc, Zflippedfacets, "flipped facets", -1);
+ zzdef_(zinc, Zcoplanarhorizon, "coplanar horizon facets for new vertices", -1);
+ zzdef_(zinc, Zcoplanarpart, "coplanar points during partitioning", -1);
+ zzdef_(zinc, Zminnorm, "degenerate hyperplanes recomputed with gaussian elimination", -1);
+ zzdef_(zinc, Znearlysingular, "nearly singular or axis-parallel hyperplanes", -1);
+ zzdef_(zinc, Zback0, "zero divisors during back substitute", -1);
+ zzdef_(zinc, Zgauss0, "zero divisors during gaussian elimination", -1);
+ zzdef_(zinc, Zmultiridge, "ridges with multiple neighbors", -1);
+}
+void qh_allstatB(void) {
+ zzdef_(zdoc, Zdoc1, "summary information", -1);
+ zdef_(zinc, Zvertices, "number of vertices in output", -1);
+ zdef_(zinc, Znumfacets, "number of facets in output", -1);
+ zdef_(zinc, Znonsimplicial, "number of non-simplicial facets in output", -1);
+ zdef_(zinc, Znowsimplicial, "number of simplicial facets that were merged", -1);
+ zdef_(zinc, Znumridges, "number of ridges in output", -1);
+ zdef_(zadd, Znumridges, "average number of ridges per facet", Znumfacets);
+ zdef_(zmax, Zmaxridges, "maximum number of ridges", -1);
+ zdef_(zadd, Znumneighbors, "average number of neighbors per facet", Znumfacets);
+ zdef_(zmax, Zmaxneighbors, "maximum number of neighbors", -1);
+ zdef_(zadd, Znumvertices, "average number of vertices per facet", Znumfacets);
+ zdef_(zmax, Zmaxvertices, "maximum number of vertices", -1);
+ zdef_(zadd, Znumvneighbors, "average number of neighbors per vertex", Zvertices);
+ zdef_(zmax, Zmaxvneighbors, "maximum number of neighbors", -1);
+ zdef_(wadd, Wcpu, "cpu seconds for qhull after input", -1);
+ zdef_(zinc, Ztotvertices, "vertices created altogether", -1);
+ zzdef_(zinc, Zsetplane, "facets created altogether", -1);
+ zdef_(zinc, Ztotridges, "ridges created altogether", -1);
+ zdef_(zinc, Zpostfacets, "facets before post merge", -1);
+ zdef_(zadd, Znummergetot, "average merges per facet(at most 511)", Znumfacets);
+ zdef_(zmax, Znummergemax, " maximum merges for a facet(at most 511)", -1);
+ zdef_(zinc, Zangle, NULL, -1);
+ zdef_(wadd, Wangle, "average angle(cosine) of facet normals for all ridges", Zangle);
+ zdef_(wmax, Wanglemax, " maximum angle(cosine) of facet normals across a ridge", -1);
+ zdef_(wmin, Wanglemin, " minimum angle(cosine) of facet normals across a ridge", -1);
+ zdef_(wadd, Wareatot, "total area of facets", -1);
+ zdef_(wmax, Wareamax, " maximum facet area", -1);
+ zdef_(wmin, Wareamin, " minimum facet area", -1);
+}
+void qh_allstatC(void) {
+ zdef_(zdoc, Zdoc9, "build hull statistics", -1);
+ zzdef_(zinc, Zprocessed, "points processed", -1);
+ zzdef_(zinc, Zretry, "retries due to precision problems", -1);
+ zdef_(wmax, Wretrymax, " max. random joggle", -1);
+ zdef_(zmax, Zmaxvertex, "max. vertices at any one time", -1);
+ zdef_(zinc, Ztotvisible, "ave. visible facets per iteration", Zprocessed);
+ zdef_(zinc, Zinsidevisible, " ave. visible facets without an horizon neighbor", Zprocessed);
+ zdef_(zadd, Zvisfacettot, " ave. facets deleted per iteration", Zprocessed);
+ zdef_(zmax, Zvisfacetmax, " maximum", -1);
+ zdef_(zadd, Zvisvertextot, "ave. visible vertices per iteration", Zprocessed);
+ zdef_(zmax, Zvisvertexmax, " maximum", -1);
+ zdef_(zinc, Ztothorizon, "ave. horizon facets per iteration", Zprocessed);
+ zdef_(zadd, Znewfacettot, "ave. new or merged facets per iteration", Zprocessed);
+ zdef_(zmax, Znewfacetmax, " maximum(includes initial simplex)", -1);
+ zdef_(wadd, Wnewbalance, "average new facet balance", Zprocessed);
+ zdef_(wadd, Wnewbalance2, " standard deviation", -1);
+ zdef_(wadd, Wpbalance, "average partition balance", Zpbalance);
+ zdef_(wadd, Wpbalance2, " standard deviation", -1);
+ zdef_(zinc, Zpbalance, " number of trials", -1);
+ zdef_(zinc, Zsearchpoints, "searches of all points for initial simplex", -1);
+ zdef_(zinc, Zdetsimplex, "determinants computed(area & initial hull)", -1);
+ zdef_(zinc, Znoarea, "determinants not computed because vertex too low", -1);
+ zdef_(zinc, Znotmax, "points ignored(!above max_outside)", -1);
+ zdef_(zinc, Znotgood, "points ignored(!above a good facet)", -1);
+ zdef_(zinc, Znotgoodnew, "points ignored(didn't create a good new facet)", -1);
+ zdef_(zinc, Zgoodfacet, "good facets found", -1);
+ zzdef_(zinc, Znumvisibility, "distance tests for facet visibility", -1);
+ zdef_(zinc, Zdistvertex, "distance tests to report minimum vertex", -1);
+ zzdef_(zinc, Ztotcheck, "points checked for facets' outer planes", -1);
+ zzdef_(zinc, Zcheckpart, " ave. distance tests per check", Ztotcheck);
+}
+void qh_allstatD(void) {
+ zdef_(zinc, Zvisit, "resets of visit_id", -1);
+ zdef_(zinc, Zvvisit, " resets of vertex_visit", -1);
+ zdef_(zmax, Zvisit2max, " max visit_id/2", -1);
+ zdef_(zmax, Zvvisit2max, " max vertex_visit/2", -1);
+
+ zdef_(zdoc, Zdoc4, "partitioning statistics(see previous for outer planes)", -1);
+ zzdef_(zadd, Zdelvertextot, "total vertices deleted", -1);
+ zdef_(zmax, Zdelvertexmax, " maximum vertices deleted per iteration", -1);
+ zdef_(zinc, Zfindbest, "calls to findbest", -1);
+ zdef_(zadd, Zfindbesttot, " ave. facets tested", Zfindbest);
+ zdef_(zmax, Zfindbestmax, " max. facets tested", -1);
+ zdef_(zadd, Zfindcoplanar, " ave. coplanar search", Zfindbest);
+ zdef_(zinc, Zfindnew, "calls to findbestnew", -1);
+ zdef_(zadd, Zfindnewtot, " ave. facets tested", Zfindnew);
+ zdef_(zmax, Zfindnewmax, " max. facets tested", -1);
+ zdef_(zinc, Zfindnewjump, " ave. clearly better", Zfindnew);
+ zdef_(zinc, Zfindnewsharp, " calls due to qh_sharpnewfacets", -1);
+ zdef_(zinc, Zfindhorizon, "calls to findhorizon", -1);
+ zdef_(zadd, Zfindhorizontot, " ave. facets tested", Zfindhorizon);
+ zdef_(zmax, Zfindhorizonmax, " max. facets tested", -1);
+ zdef_(zinc, Zfindjump, " ave. clearly better", Zfindhorizon);
+ zdef_(zinc, Zparthorizon, " horizon facets better than bestfacet", -1);
+ zdef_(zinc, Zpartangle, "angle tests for repartitioned coplanar points", -1);
+ zdef_(zinc, Zpartflip, " repartitioned coplanar points for flipped orientation", -1);
+}
+void qh_allstatE(void) {
+ zdef_(zinc, Zpartinside, "inside points", -1);
+ zdef_(zinc, Zpartnear, " inside points kept with a facet", -1);
+ zdef_(zinc, Zcoplanarinside, " inside points that were coplanar with a facet", -1);
+ zdef_(zinc, Zbestlower, "calls to findbestlower", -1);
+ zdef_(zinc, Zbestlowerv, " with search of vertex neighbors", -1);
+ zdef_(zinc, Zbestlowerall, " with rare search of all facets", -1);
+ zdef_(zmax, Zbestloweralln, " facets per search of all facets", -1);
+ zdef_(wadd, Wmaxout, "difference in max_outside at final check", -1);
+ zzdef_(zinc, Zpartitionall, "distance tests for initial partition", -1);
+ zdef_(zinc, Ztotpartition, "partitions of a point", -1);
+ zzdef_(zinc, Zpartition, "distance tests for partitioning", -1);
+ zzdef_(zinc, Zdistcheck, "distance tests for checking flipped facets", -1);
+ zzdef_(zinc, Zdistconvex, "distance tests for checking convexity", -1);
+ zdef_(zinc, Zdistgood, "distance tests for checking good point", -1);
+ zdef_(zinc, Zdistio, "distance tests for output", -1);
+ zdef_(zinc, Zdiststat, "distance tests for statistics", -1);
+ zdef_(zinc, Zdistplane, "total number of distance tests", -1);
+ zdef_(zinc, Ztotpartcoplanar, "partitions of coplanar points or deleted vertices", -1);
+ zzdef_(zinc, Zpartcoplanar, " distance tests for these partitions", -1);
+ zdef_(zinc, Zcomputefurthest, "distance tests for computing furthest", -1);
+}
+void qh_allstatE2(void) {
+ zdef_(zdoc, Zdoc5, "statistics for matching ridges", -1);
+ zdef_(zinc, Zhashlookup, "total lookups for matching ridges of new facets", -1);
+ zdef_(zinc, Zhashtests, "average number of tests to match a ridge", Zhashlookup);
+ zdef_(zinc, Zhashridge, "total lookups of subridges(duplicates and boundary)", -1);
+ zdef_(zinc, Zhashridgetest, "average number of tests per subridge", Zhashridge);
+ zdef_(zinc, Zdupsame, "duplicated ridges in same merge cycle", -1);
+ zdef_(zinc, Zdupflip, "duplicated ridges with flipped facets", -1);
+
+ zdef_(zdoc, Zdoc6, "statistics for determining merges", -1);
+ zdef_(zinc, Zangletests, "angles computed for ridge convexity", -1);
+ zdef_(zinc, Zbestcentrum, "best merges used centrum instead of vertices",-1);
+ zzdef_(zinc, Zbestdist, "distance tests for best merge", -1);
+ zzdef_(zinc, Zcentrumtests, "distance tests for centrum convexity", -1);
+ zzdef_(zinc, Zdistzero, "distance tests for checking simplicial convexity", -1);
+ zdef_(zinc, Zcoplanarangle, "coplanar angles in getmergeset", -1);
+ zdef_(zinc, Zcoplanarcentrum, "coplanar centrums in getmergeset", -1);
+ zdef_(zinc, Zconcaveridge, "concave ridges in getmergeset", -1);
+}
+void qh_allstatF(void) {
+ zdef_(zdoc, Zdoc7, "statistics for merging", -1);
+ zdef_(zinc, Zpremergetot, "merge iterations", -1);
+ zdef_(zadd, Zmergeinittot, "ave. initial non-convex ridges per iteration", Zpremergetot);
+ zdef_(zadd, Zmergeinitmax, " maximum", -1);
+ zdef_(zadd, Zmergesettot, " ave. additional non-convex ridges per iteration", Zpremergetot);
+ zdef_(zadd, Zmergesetmax, " maximum additional in one pass", -1);
+ zdef_(zadd, Zmergeinittot2, "initial non-convex ridges for post merging", -1);
+ zdef_(zadd, Zmergesettot2, " additional non-convex ridges", -1);
+ zdef_(wmax, Wmaxoutside, "max distance of vertex or coplanar point above facet(w/roundoff)", -1);
+ zdef_(wmin, Wminvertex, "max distance of merged vertex below facet(or roundoff)", -1);
+ zdef_(zinc, Zwidefacet, "centrums frozen due to a wide merge", -1);
+ zdef_(zinc, Zwidevertices, "centrums frozen due to extra vertices", -1);
+ zzdef_(zinc, Ztotmerge, "total number of facets or cycles of facets merged", -1);
+ zdef_(zinc, Zmergesimplex, "merged a simplex", -1);
+ zdef_(zinc, Zonehorizon, "simplices merged into coplanar horizon", -1);
+ zzdef_(zinc, Zcyclehorizon, "cycles of facets merged into coplanar horizon", -1);
+ zzdef_(zadd, Zcyclefacettot, " ave. facets per cycle", Zcyclehorizon);
+ zdef_(zmax, Zcyclefacetmax, " max. facets", -1);
+ zdef_(zinc, Zmergeintohorizon, "new facets merged into horizon", -1);
+ zdef_(zinc, Zmergenew, "new facets merged", -1);
+ zdef_(zinc, Zmergehorizon, "horizon facets merged into new facets", -1);
+ zdef_(zinc, Zmergevertex, "vertices deleted by merging", -1);
+ zdef_(zinc, Zcyclevertex, "vertices deleted by merging into coplanar horizon", -1);
+ zdef_(zinc, Zdegenvertex, "vertices deleted by degenerate facet", -1);
+ zdef_(zinc, Zmergeflipdup, "merges due to flipped facets in duplicated ridge", -1);
+ zdef_(zinc, Zneighbor, "merges due to redundant neighbors", -1);
+ zdef_(zadd, Ztestvneighbor, "non-convex vertex neighbors", -1);
+}
+void qh_allstatG(void) {
+ zdef_(zinc, Zacoplanar, "merges due to angle coplanar facets", -1);
+ zdef_(wadd, Wacoplanartot, " average merge distance", Zacoplanar);
+ zdef_(wmax, Wacoplanarmax, " maximum merge distance", -1);
+ zdef_(zinc, Zcoplanar, "merges due to coplanar facets", -1);
+ zdef_(wadd, Wcoplanartot, " average merge distance", Zcoplanar);
+ zdef_(wmax, Wcoplanarmax, " maximum merge distance", -1);
+ zdef_(zinc, Zconcave, "merges due to concave facets", -1);
+ zdef_(wadd, Wconcavetot, " average merge distance", Zconcave);
+ zdef_(wmax, Wconcavemax, " maximum merge distance", -1);
+ zdef_(zinc, Zavoidold, "coplanar/concave merges due to avoiding old merge", -1);
+ zdef_(wadd, Wavoidoldtot, " average merge distance", Zavoidold);
+ zdef_(wmax, Wavoidoldmax, " maximum merge distance", -1);
+ zdef_(zinc, Zdegen, "merges due to degenerate facets", -1);
+ zdef_(wadd, Wdegentot, " average merge distance", Zdegen);
+ zdef_(wmax, Wdegenmax, " maximum merge distance", -1);
+ zdef_(zinc, Zflipped, "merges due to removing flipped facets", -1);
+ zdef_(wadd, Wflippedtot, " average merge distance", Zflipped);
+ zdef_(wmax, Wflippedmax, " maximum merge distance", -1);
+ zdef_(zinc, Zduplicate, "merges due to duplicated ridges", -1);
+ zdef_(wadd, Wduplicatetot, " average merge distance", Zduplicate);
+ zdef_(wmax, Wduplicatemax, " maximum merge distance", -1);
+}
+void qh_allstatH(void) {
+ zdef_(zdoc, Zdoc8, "renamed vertex statistics", -1);
+ zdef_(zinc, Zrenameshare, "renamed vertices shared by two facets", -1);
+ zdef_(zinc, Zrenamepinch, "renamed vertices in a pinched facet", -1);
+ zdef_(zinc, Zrenameall, "renamed vertices shared by multiple facets", -1);
+ zdef_(zinc, Zfindfail, "rename failures due to duplicated ridges", -1);
+ zdef_(zinc, Zdupridge, " duplicate ridges detected", -1);
+ zdef_(zinc, Zdelridge, "deleted ridges due to renamed vertices", -1);
+ zdef_(zinc, Zdropneighbor, "dropped neighbors due to renamed vertices", -1);
+ zdef_(zinc, Zdropdegen, "degenerate facets due to dropped neighbors", -1);
+ zdef_(zinc, Zdelfacetdup, " facets deleted because of no neighbors", -1);
+ zdef_(zinc, Zremvertex, "vertices removed from facets due to no ridges", -1);
+ zdef_(zinc, Zremvertexdel, " deleted", -1);
+ zdef_(zinc, Zintersectnum, "vertex intersections for locating redundant vertices", -1);
+ zdef_(zinc, Zintersectfail, "intersections failed to find a redundant vertex", -1);
+ zdef_(zinc, Zintersect, "intersections found redundant vertices", -1);
+ zdef_(zadd, Zintersecttot, " ave. number found per vertex", Zintersect);
+ zdef_(zmax, Zintersectmax, " max. found for a vertex", -1);
+ zdef_(zinc, Zvertexridge, NULL, -1);
+ zdef_(zadd, Zvertexridgetot, " ave. number of ridges per tested vertex", Zvertexridge);
+ zdef_(zmax, Zvertexridgemax, " max. number of ridges per tested vertex", -1);
+
+ zdef_(zdoc, Zdoc10, "memory usage statistics(in bytes)", -1);
+ zdef_(zadd, Zmemfacets, "for facets and their normals, neighbor and vertex sets", -1);
+ zdef_(zadd, Zmemvertices, "for vertices and their neighbor sets", -1);
+ zdef_(zadd, Zmempoints, "for input points and outside and coplanar sets",-1);
+ zdef_(zadd, Zmemridges, "for ridges and their vertex sets", -1);
+} /* allstat */
+
+void qh_allstatI(void) {
+ qhstat vridges= qhstat next;
+ zzdef_(zdoc, Zdoc11, "Voronoi ridge statistics", -1);
+ zzdef_(zinc, Zridge, "non-simplicial Voronoi vertices for all ridges", -1);
+ zzdef_(wadd, Wridge, " ave. distance to ridge", Zridge);
+ zzdef_(wmax, Wridgemax, " max. distance to ridge", -1);
+ zzdef_(zinc, Zridgemid, "bounded ridges", -1);
+ zzdef_(wadd, Wridgemid, " ave. distance of midpoint to ridge", Zridgemid);
+ zzdef_(wmax, Wridgemidmax, " max. distance of midpoint to ridge", -1);
+ zzdef_(zinc, Zridgeok, "bounded ridges with ok normal", -1);
+ zzdef_(wadd, Wridgeok, " ave. angle to ridge", Zridgeok);
+ zzdef_(wmax, Wridgeokmax, " max. angle to ridge", -1);
+ zzdef_(zinc, Zridge0, "bounded ridges with near-zero normal", -1);
+ zzdef_(wadd, Wridge0, " ave. angle to ridge", Zridge0);
+ zzdef_(wmax, Wridge0max, " max. angle to ridge", -1);
+
+ zdef_(zdoc, Zdoc12, "Triangulation statistics(Qt)", -1);
+ zdef_(zinc, Ztricoplanar, "non-simplicial facets triangulated", -1);
+ zdef_(zadd, Ztricoplanartot, " ave. new facets created(may be deleted)", Ztricoplanar);
+ zdef_(zmax, Ztricoplanarmax, " max. new facets created", -1);
+ zdef_(zinc, Ztrinull, "null new facets deleted(duplicated vertex)", -1);
+ zdef_(zinc, Ztrimirror, "mirrored pairs of new facets deleted(same vertices)", -1);
+ zdef_(zinc, Ztridegen, "degenerate new facets in output(same ridge)", -1);
+} /* allstat */
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="allstatistics">-</a>
+
+ qh_allstatistics()
+ reset printed flag for all statistics
+*/
+void qh_allstatistics(void) {
+ int i;
+
+ for(i=ZEND; i--; )
+ qhstat printed[i]= False;
+} /* allstatistics */
+
+#if qh_KEEPstatistics
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="collectstatistics">-</a>
+
+ qh_collectstatistics()
+ collect statistics for qh.facet_list
+
+*/
+void qh_collectstatistics(void) {
+ facetT *facet, *neighbor, **neighborp;
+ vertexT *vertex, **vertexp;
+ realT dotproduct, dist;
+ int sizneighbors, sizridges, sizvertices, i;
+
+ qh old_randomdist= qh RANDOMdist;
+ qh RANDOMdist= False;
+ zval_(Zmempoints)= qh num_points * qh normal_size +
+ sizeof(qhT) + sizeof(qhstatT);
+ zval_(Zmemfacets)= 0;
+ zval_(Zmemridges)= 0;
+ zval_(Zmemvertices)= 0;
+ zval_(Zangle)= 0;
+ wval_(Wangle)= 0.0;
+ zval_(Znumridges)= 0;
+ zval_(Znumfacets)= 0;
+ zval_(Znumneighbors)= 0;
+ zval_(Znumvertices)= 0;
+ zval_(Znumvneighbors)= 0;
+ zval_(Znummergetot)= 0;
+ zval_(Znummergemax)= 0;
+ zval_(Zvertices)= qh num_vertices - qh_setsize(qh del_vertices);
+ if (qh MERGING || qh APPROXhull || qh JOGGLEmax < REALmax/2)
+ wmax_(Wmaxoutside, qh max_outside);
+ if (qh MERGING)
+ wmin_(Wminvertex, qh min_vertex);
+ FORALLfacets
+ facet->seen= False;
+ if (qh DELAUNAY) {
+ FORALLfacets {
+ if (facet->upperdelaunay != qh UPPERdelaunay)
+ facet->seen= True; /* remove from angle statistics */
+ }
+ }
+ FORALLfacets {
+ if (facet->visible && qh NEWfacets)
+ continue;
+ sizvertices= qh_setsize(facet->vertices);
+ sizneighbors= qh_setsize(facet->neighbors);
+ sizridges= qh_setsize(facet->ridges);
+ zinc_(Znumfacets);
+ zadd_(Znumvertices, sizvertices);
+ zmax_(Zmaxvertices, sizvertices);
+ zadd_(Znumneighbors, sizneighbors);
+ zmax_(Zmaxneighbors, sizneighbors);
+ zadd_(Znummergetot, facet->nummerge);
+ i= facet->nummerge; /* avoid warnings */
+ zmax_(Znummergemax, i);
+ if (!facet->simplicial) {
+ if (sizvertices == qh hull_dim) {
+ zinc_(Znowsimplicial);
+ }else {
+ zinc_(Znonsimplicial);
+ }
+ }
+ if (sizridges) {
+ zadd_(Znumridges, sizridges);
+ zmax_(Zmaxridges, sizridges);
+ }
+ zadd_(Zmemfacets, sizeof(facetT) + qh normal_size + 2*sizeof(setT)
+ + SETelemsize * (sizneighbors + sizvertices));
+ if (facet->ridges) {
+ zadd_(Zmemridges,
+ sizeof(setT) + SETelemsize * sizridges + sizridges *
+ (sizeof(ridgeT) + sizeof(setT) + SETelemsize * (qh hull_dim-1))/2);
+ }
+ if (facet->outsideset)
+ zadd_(Zmempoints, sizeof(setT) + SETelemsize * qh_setsize(facet->outsideset));
+ if (facet->coplanarset)
+ zadd_(Zmempoints, sizeof(setT) + SETelemsize * qh_setsize(facet->coplanarset));
+ if (facet->seen) /* Delaunay upper envelope */
+ continue;
+ facet->seen= True;
+ FOREACHneighbor_(facet) {
+ if (neighbor == qh_DUPLICATEridge || neighbor == qh_MERGEridge
+ || neighbor->seen || !facet->normal || !neighbor->normal)
+ continue;
+ dotproduct= qh_getangle(facet->normal, neighbor->normal);
+ zinc_(Zangle);
+ wadd_(Wangle, dotproduct);
+ wmax_(Wanglemax, dotproduct)
+ wmin_(Wanglemin, dotproduct)
+ }
+ if (facet->normal) {
+ FOREACHvertex_(facet->vertices) {
+ zinc_(Zdiststat);
+ qh_distplane(vertex->point, facet, &dist);
+ wmax_(Wvertexmax, dist);
+ wmin_(Wvertexmin, dist);
+ }
+ }
+ }
+ FORALLvertices {
+ if (vertex->deleted)
+ continue;
+ zadd_(Zmemvertices, sizeof(vertexT));
+ if (vertex->neighbors) {
+ sizneighbors= qh_setsize(vertex->neighbors);
+ zadd_(Znumvneighbors, sizneighbors);
+ zmax_(Zmaxvneighbors, sizneighbors);
+ zadd_(Zmemvertices, sizeof(vertexT) + SETelemsize * sizneighbors);
+ }
+ }
+ qh RANDOMdist= qh old_randomdist;
+} /* collectstatistics */
+#endif /* qh_KEEPstatistics */
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="freestatistics">-</a>
+
+ qh_freestatistics( )
+ free memory used for statistics
+*/
+void qh_freestatistics(void) {
+
+#if qh_QHpointer
+ qh_free(qh_qhstat);
+ qh_qhstat= NULL;
+#endif
+} /* freestatistics */
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="initstatistics">-</a>
+
+ qh_initstatistics( )
+ allocate and initialize statistics
+
+ notes:
+ uses qh_malloc() instead of qh_memalloc() since mem.c not set up yet
+ NOerrors -- qh_initstatistics can not use qh_errexit(), qh_fprintf, or qh.ferr
+ On first call, only qhmem.ferr is defined. qh_memalloc is not setup.
+ Also invoked by QhullQh().
+*/
+void qh_initstatistics(void) {
+ int i;
+ realT realx;
+ int intx;
+
+#if qh_QHpointer
+ if(qh_qhstat){ /* qh_initstatistics may be called from Qhull::resetStatistics() */
+ qh_free(qh_qhstat);
+ qh_qhstat= 0;
+ }
+ if (!(qh_qhstat= (qhstatT *)qh_malloc(sizeof(qhstatT)))) {
+ qh_fprintf_stderr(6183, "qhull error (qh_initstatistics): insufficient memory\n");
+ qh_exit(qh_ERRmem); /* can not use qh_errexit() */
+ }
+#endif
+
+ qhstat next= 0;
+ qh_allstatA();
+ qh_allstatB();
+ qh_allstatC();
+ qh_allstatD();
+ qh_allstatE();
+ qh_allstatE2();
+ qh_allstatF();
+ qh_allstatG();
+ qh_allstatH();
+ qh_allstatI();
+ if (qhstat next > (int)sizeof(qhstat id)) {
+ qh_fprintf(qhmem.ferr, 6184, "qhull error (qh_initstatistics): increase size of qhstat.id[].\n\
+ qhstat.next %d should be <= sizeof(qhstat id) %d\n", qhstat next, (int)sizeof(qhstat id));
+#if 0 /* for locating error, Znumridges should be duplicated */
+ for(i=0; i < ZEND; i++) {
+ int j;
+ for(j=i+1; j < ZEND; j++) {
+ if (qhstat id[i] == qhstat id[j]) {
+ qh_fprintf(qhmem.ferr, 6185, "qhull error (qh_initstatistics): duplicated statistic %d at indices %d and %d\n",
+ qhstat id[i], i, j);
+ }
+ }
+ }
+#endif
+ qh_exit(qh_ERRqhull); /* can not use qh_errexit() */
+ }
+ qhstat init[zinc].i= 0;
+ qhstat init[zadd].i= 0;
+ qhstat init[zmin].i= INT_MAX;
+ qhstat init[zmax].i= INT_MIN;
+ qhstat init[wadd].r= 0;
+ qhstat init[wmin].r= REALmax;
+ qhstat init[wmax].r= -REALmax;
+ for(i=0; i < ZEND; i++) {
+ if (qhstat type[i] > ZTYPEreal) {
+ realx= qhstat init[(unsigned char)(qhstat type[i])].r;
+ qhstat stats[i].r= realx;
+ }else if (qhstat type[i] != zdoc) {
+ intx= qhstat init[(unsigned char)(qhstat type[i])].i;
+ qhstat stats[i].i= intx;
+ }
+ }
+} /* initstatistics */
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="newstats">-</a>
+
+ qh_newstats( )
+ returns True if statistics for zdoc
+
+ returns:
+ next zdoc
+*/
+boolT qh_newstats(int idx, int *nextindex) {
+ boolT isnew= False;
+ int start, i;
+
+ if (qhstat type[qhstat id[idx]] == zdoc)
+ start= idx+1;
+ else
+ start= idx;
+ for(i= start; i < qhstat next && qhstat type[qhstat id[i]] != zdoc; i++) {
+ if (!qh_nostatistic(qhstat id[i]) && !qhstat printed[qhstat id[i]])
+ isnew= True;
+ }
+ *nextindex= i;
+ return isnew;
+} /* newstats */
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="nostatistic">-</a>
+
+ qh_nostatistic( index )
+ true if no statistic to print
+*/
+boolT qh_nostatistic(int i) {
+
+ if ((qhstat type[i] > ZTYPEreal
+ &&qhstat stats[i].r == qhstat init[(unsigned char)(qhstat type[i])].r)
+ || (qhstat type[i] < ZTYPEreal
+ &&qhstat stats[i].i == qhstat init[(unsigned char)(qhstat type[i])].i))
+ return True;
+ return False;
+} /* nostatistic */
+
+#if qh_KEEPstatistics
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="printallstatistics">-</a>
+
+ qh_printallstatistics( fp, string )
+ print all statistics with header 'string'
+*/
+void qh_printallstatistics(FILE *fp, const char *string) {
+
+ qh_allstatistics();
+ qh_collectstatistics();
+ qh_printstatistics(fp, string);
+ qh_memstatistics(fp);
+}
+
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="printstatistics">-</a>
+
+ qh_printstatistics( fp, string )
+ print statistics to a file with header 'string'
+ skips statistics with qhstat.printed[] (reset with qh_allstatistics)
+
+ see:
+ qh_printallstatistics()
+*/
+void qh_printstatistics(FILE *fp, const char *string) {
+ int i, k;
+ realT ave;
+
+ if (qh num_points != qh num_vertices) {
+ wval_(Wpbalance)= 0;
+ wval_(Wpbalance2)= 0;
+ }else
+ wval_(Wpbalance2)= qh_stddev(zval_(Zpbalance), wval_(Wpbalance),
+ wval_(Wpbalance2), &ave);
+ wval_(Wnewbalance2)= qh_stddev(zval_(Zprocessed), wval_(Wnewbalance),
+ wval_(Wnewbalance2), &ave);
+ qh_fprintf(fp, 9350, "\n\
+%s\n\
+ qhull invoked by: %s | %s\n%s with options:\n%s\n", string, qh rbox_command,
+ qh qhull_command, qh_version, qh qhull_options);
+ qh_fprintf(fp, 9351, "\nprecision constants:\n\
+ %6.2g max. abs. coordinate in the (transformed) input('Qbd:n')\n\
+ %6.2g max. roundoff error for distance computation('En')\n\
+ %6.2g max. roundoff error for angle computations\n\
+ %6.2g min. distance for outside points ('Wn')\n\
+ %6.2g min. distance for visible facets ('Vn')\n\
+ %6.2g max. distance for coplanar facets ('Un')\n\
+ %6.2g max. facet width for recomputing centrum and area\n\
+",
+ qh MAXabs_coord, qh DISTround, qh ANGLEround, qh MINoutside,
+ qh MINvisible, qh MAXcoplanar, qh WIDEfacet);
+ if (qh KEEPnearinside)
+ qh_fprintf(fp, 9352, "\
+ %6.2g max. distance for near-inside points\n", qh NEARinside);
+ if (qh premerge_cos < REALmax/2) qh_fprintf(fp, 9353, "\
+ %6.2g max. cosine for pre-merge angle\n", qh premerge_cos);
+ if (qh PREmerge) qh_fprintf(fp, 9354, "\
+ %6.2g radius of pre-merge centrum\n", qh premerge_centrum);
+ if (qh postmerge_cos < REALmax/2) qh_fprintf(fp, 9355, "\
+ %6.2g max. cosine for post-merge angle\n", qh postmerge_cos);
+ if (qh POSTmerge) qh_fprintf(fp, 9356, "\
+ %6.2g radius of post-merge centrum\n", qh postmerge_centrum);
+ qh_fprintf(fp, 9357, "\
+ %6.2g max. distance for merging two simplicial facets\n\
+ %6.2g max. roundoff error for arithmetic operations\n\
+ %6.2g min. denominator for divisions\n\
+ zero diagonal for Gauss: ", qh ONEmerge, REALepsilon, qh MINdenom);
+ for(k=0; k < qh hull_dim; k++)
+ qh_fprintf(fp, 9358, "%6.2e ", qh NEARzero[k]);
+ qh_fprintf(fp, 9359, "\n\n");
+ for(i=0 ; i < qhstat next; )
+ qh_printstats(fp, i, &i);
+} /* printstatistics */
+#endif /* qh_KEEPstatistics */
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="printstatlevel">-</a>
+
+ qh_printstatlevel( fp, id )
+ print level information for a statistic
+
+ notes:
+ nop if id >= ZEND, printed, or same as initial value
+*/
+void qh_printstatlevel(FILE *fp, int id) {
+#define NULLfield " "
+
+ if (id >= ZEND || qhstat printed[id])
+ return;
+ if (qhstat type[id] == zdoc) {
+ qh_fprintf(fp, 9360, "%s\n", qhstat doc[id]);
+ return;
+ }
+ if (qh_nostatistic(id) || !qhstat doc[id])
+ return;
+ qhstat printed[id]= True;
+ if (qhstat count[id] != -1
+ && qhstat stats[(unsigned char)(qhstat count[id])].i == 0)
+ qh_fprintf(fp, 9361, " *0 cnt*");
+ else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] == -1)
+ qh_fprintf(fp, 9362, "%7.2g", qhstat stats[id].r);
+ else if (qhstat type[id] >= ZTYPEreal && qhstat count[id] != -1)
+ qh_fprintf(fp, 9363, "%7.2g", qhstat stats[id].r/ qhstat stats[(unsigned char)(qhstat count[id])].i);
+ else if (qhstat type[id] < ZTYPEreal && qhstat count[id] == -1)
+ qh_fprintf(fp, 9364, "%7d", qhstat stats[id].i);
+ else if (qhstat type[id] < ZTYPEreal && qhstat count[id] != -1)
+ qh_fprintf(fp, 9365, "%7.3g", (realT) qhstat stats[id].i / qhstat stats[(unsigned char)(qhstat count[id])].i);
+ qh_fprintf(fp, 9366, " %s\n", qhstat doc[id]);
+} /* printstatlevel */
+
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="printstats">-</a>
+
+ qh_printstats( fp, index, nextindex )
+ print statistics for a zdoc group
+
+ returns:
+ next zdoc if non-null
+*/
+void qh_printstats(FILE *fp, int idx, int *nextindex) {
+ int j, nexti;
+
+ if (qh_newstats(idx, &nexti)) {
+ qh_fprintf(fp, 9367, "\n");
+ for (j=idx; j<nexti; j++)
+ qh_printstatlevel(fp, qhstat id[j]);
+ }
+ if (nextindex)
+ *nextindex= nexti;
+} /* printstats */
+
+#if qh_KEEPstatistics
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="stddev">-</a>
+
+ qh_stddev( num, tot, tot2, ave )
+ compute the standard deviation and average from statistics
+
+ tot2 is the sum of the squares
+ notes:
+ computes r.m.s.:
+ (x-ave)^2
+ == x^2 - 2x tot/num + (tot/num)^2
+ == tot2 - 2 tot tot/num + tot tot/num
+ == tot2 - tot ave
+*/
+realT qh_stddev(int num, realT tot, realT tot2, realT *ave) {
+ realT stddev;
+
+ *ave= tot/num;
+ stddev= sqrt(tot2/num - *ave * *ave);
+ return stddev;
+} /* stddev */
+
+#endif /* qh_KEEPstatistics */
+
+#if !qh_KEEPstatistics
+void qh_collectstatistics(void) {}
+void qh_printallstatistics(FILE *fp, char *string) {};
+void qh_printstatistics(FILE *fp, char *string) {}
+#endif
+
diff --git a/xs/src/qhull/src/libqhull/stat.h b/xs/src/qhull/src/libqhull/stat.h
new file mode 100644
index 000000000..d86fc0a87
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/stat.h
@@ -0,0 +1,543 @@
+/*<html><pre> -<a href="qh-stat.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ stat.h
+ contains all statistics that are collected for qhull
+
+ see qh-stat.htm and stat.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull/stat.h#4 $$Change: 2062 $
+ $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+
+ recompile qhull if you change this file
+
+ Integer statistics are Z* while real statistics are W*.
+
+ define maydebugx to call a routine at every statistic event
+
+*/
+
+#ifndef qhDEFstat
+#define qhDEFstat 1
+
+#include "libqhull.h"
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="KEEPstatistics">-</a>
+
+ qh_KEEPstatistics
+ 0 turns off statistic gathering (except zzdef/zzinc/zzadd/zzval/wwval)
+*/
+#ifndef qh_KEEPstatistics
+#define qh_KEEPstatistics 1
+#endif
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="statistics">-</a>
+
+ Zxxx for integers, Wxxx for reals
+
+ notes:
+ be sure that all statistics are defined in stat.c
+ otherwise initialization may core dump
+ can pick up all statistics by:
+ grep '[zw].*_[(][ZW]' *.c >z.x
+ remove trailers with query">-</a>
+ remove leaders with query-replace-regexp [ ^I]+ (
+*/
+#if qh_KEEPstatistics
+enum qh_statistics { /* alphabetical after Z/W */
+ Zacoplanar,
+ Wacoplanarmax,
+ Wacoplanartot,
+ Zangle,
+ Wangle,
+ Wanglemax,
+ Wanglemin,
+ Zangletests,
+ Wareatot,
+ Wareamax,
+ Wareamin,
+ Zavoidold,
+ Wavoidoldmax,
+ Wavoidoldtot,
+ Zback0,
+ Zbestcentrum,
+ Zbestdist,
+ Zbestlower,
+ Zbestlowerall,
+ Zbestloweralln,
+ Zbestlowerv,
+ Zcentrumtests,
+ Zcheckpart,
+ Zcomputefurthest,
+ Zconcave,
+ Wconcavemax,
+ Wconcavetot,
+ Zconcaveridges,
+ Zconcaveridge,
+ Zcoplanar,
+ Wcoplanarmax,
+ Wcoplanartot,
+ Zcoplanarangle,
+ Zcoplanarcentrum,
+ Zcoplanarhorizon,
+ Zcoplanarinside,
+ Zcoplanarpart,
+ Zcoplanarridges,
+ Wcpu,
+ Zcyclefacetmax,
+ Zcyclefacettot,
+ Zcyclehorizon,
+ Zcyclevertex,
+ Zdegen,
+ Wdegenmax,
+ Wdegentot,
+ Zdegenvertex,
+ Zdelfacetdup,
+ Zdelridge,
+ Zdelvertextot,
+ Zdelvertexmax,
+ Zdetsimplex,
+ Zdistcheck,
+ Zdistconvex,
+ Zdistgood,
+ Zdistio,
+ Zdistplane,
+ Zdiststat,
+ Zdistvertex,
+ Zdistzero,
+ Zdoc1,
+ Zdoc2,
+ Zdoc3,
+ Zdoc4,
+ Zdoc5,
+ Zdoc6,
+ Zdoc7,
+ Zdoc8,
+ Zdoc9,
+ Zdoc10,
+ Zdoc11,
+ Zdoc12,
+ Zdropdegen,
+ Zdropneighbor,
+ Zdupflip,
+ Zduplicate,
+ Wduplicatemax,
+ Wduplicatetot,
+ Zdupridge,
+ Zdupsame,
+ Zflipped,
+ Wflippedmax,
+ Wflippedtot,
+ Zflippedfacets,
+ Zfindbest,
+ Zfindbestmax,
+ Zfindbesttot,
+ Zfindcoplanar,
+ Zfindfail,
+ Zfindhorizon,
+ Zfindhorizonmax,
+ Zfindhorizontot,
+ Zfindjump,
+ Zfindnew,
+ Zfindnewmax,
+ Zfindnewtot,
+ Zfindnewjump,
+ Zfindnewsharp,
+ Zgauss0,
+ Zgoodfacet,
+ Zhashlookup,
+ Zhashridge,
+ Zhashridgetest,
+ Zhashtests,
+ Zinsidevisible,
+ Zintersect,
+ Zintersectfail,
+ Zintersectmax,
+ Zintersectnum,
+ Zintersecttot,
+ Zmaxneighbors,
+ Wmaxout,
+ Wmaxoutside,
+ Zmaxridges,
+ Zmaxvertex,
+ Zmaxvertices,
+ Zmaxvneighbors,
+ Zmemfacets,
+ Zmempoints,
+ Zmemridges,
+ Zmemvertices,
+ Zmergeflipdup,
+ Zmergehorizon,
+ Zmergeinittot,
+ Zmergeinitmax,
+ Zmergeinittot2,
+ Zmergeintohorizon,
+ Zmergenew,
+ Zmergesettot,
+ Zmergesetmax,
+ Zmergesettot2,
+ Zmergesimplex,
+ Zmergevertex,
+ Wmindenom,
+ Wminvertex,
+ Zminnorm,
+ Zmultiridge,
+ Znearlysingular,
+ Zneighbor,
+ Wnewbalance,
+ Wnewbalance2,
+ Znewfacettot,
+ Znewfacetmax,
+ Znewvertex,
+ Wnewvertex,
+ Wnewvertexmax,
+ Znoarea,
+ Znonsimplicial,
+ Znowsimplicial,
+ Znotgood,
+ Znotgoodnew,
+ Znotmax,
+ Znumfacets,
+ Znummergemax,
+ Znummergetot,
+ Znumneighbors,
+ Znumridges,
+ Znumvertices,
+ Znumvisibility,
+ Znumvneighbors,
+ Zonehorizon,
+ Zpartangle,
+ Zpartcoplanar,
+ Zpartflip,
+ Zparthorizon,
+ Zpartinside,
+ Zpartition,
+ Zpartitionall,
+ Zpartnear,
+ Zpbalance,
+ Wpbalance,
+ Wpbalance2,
+ Zpostfacets,
+ Zpremergetot,
+ Zprocessed,
+ Zremvertex,
+ Zremvertexdel,
+ Zrenameall,
+ Zrenamepinch,
+ Zrenameshare,
+ Zretry,
+ Wretrymax,
+ Zridge,
+ Wridge,
+ Wridgemax,
+ Zridge0,
+ Wridge0,
+ Wridge0max,
+ Zridgemid,
+ Wridgemid,
+ Wridgemidmax,
+ Zridgeok,
+ Wridgeok,
+ Wridgeokmax,
+ Zsearchpoints,
+ Zsetplane,
+ Ztestvneighbor,
+ Ztotcheck,
+ Ztothorizon,
+ Ztotmerge,
+ Ztotpartcoplanar,
+ Ztotpartition,
+ Ztotridges,
+ Ztotvertices,
+ Ztotvisible,
+ Ztricoplanar,
+ Ztricoplanarmax,
+ Ztricoplanartot,
+ Ztridegen,
+ Ztrimirror,
+ Ztrinull,
+ Wvertexmax,
+ Wvertexmin,
+ Zvertexridge,
+ Zvertexridgetot,
+ Zvertexridgemax,
+ Zvertices,
+ Zvisfacettot,
+ Zvisfacetmax,
+ Zvisit,
+ Zvisit2max,
+ Zvisvertextot,
+ Zvisvertexmax,
+ Zvvisit,
+ Zvvisit2max,
+ Zwidefacet,
+ Zwidevertices,
+ ZEND};
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="ZZstat">-</a>
+
+ Zxxx/Wxxx statistics that remain defined if qh_KEEPstatistics=0
+
+ notes:
+ be sure to use zzdef, zzinc, etc. with these statistics (no double checking!)
+*/
+#else
+enum qh_statistics { /* for zzdef etc. macros */
+ Zback0,
+ Zbestdist,
+ Zcentrumtests,
+ Zcheckpart,
+ Zconcaveridges,
+ Zcoplanarhorizon,
+ Zcoplanarpart,
+ Zcoplanarridges,
+ Zcyclefacettot,
+ Zcyclehorizon,
+ Zdelvertextot,
+ Zdistcheck,
+ Zdistconvex,
+ Zdistzero,
+ Zdoc1,
+ Zdoc2,
+ Zdoc3,
+ Zdoc11,
+ Zflippedfacets,
+ Zgauss0,
+ Zminnorm,
+ Zmultiridge,
+ Znearlysingular,
+ Wnewvertexmax,
+ Znumvisibility,
+ Zpartcoplanar,
+ Zpartition,
+ Zpartitionall,
+ Zprocessed,
+ Zretry,
+ Zridge,
+ Wridge,
+ Wridgemax,
+ Zridge0,
+ Wridge0,
+ Wridge0max,
+ Zridgemid,
+ Wridgemid,
+ Wridgemidmax,
+ Zridgeok,
+ Wridgeok,
+ Wridgeokmax,
+ Zsetplane,
+ Ztotcheck,
+ Ztotmerge,
+ ZEND};
+#endif
+
+/*-<a href="qh-stat.htm#TOC"
+ >-------------------------------</a><a name="ztype">-</a>
+
+ ztype
+ the type of a statistic sets its initial value.
+
+ notes:
+ The type should be the same as the macro for collecting the statistic
+*/
+enum ztypes {zdoc,zinc,zadd,zmax,zmin,ZTYPEreal,wadd,wmax,wmin,ZTYPEend};
+
+/*========== macros and constants =============*/
+
+/*-<a href="qh-stat.htm#TOC"
+ >--------------------------------</a><a name="MAYdebugx">-</a>
+
+ MAYdebugx
+ define as maydebug() to be called frequently for error trapping
+*/
+#define MAYdebugx
+
+/*-<a href="qh-stat.htm#TOC"
+ >--------------------------------</a><a name="zdef_">-</a>
+
+ zzdef_, zdef_( type, name, doc, -1)
+ define a statistic (assumes 'qhstat.next= 0;')
+
+ zdef_( type, name, doc, count)
+ define an averaged statistic
+ printed as name/count
+*/
+#define zzdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
+ qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
+#if qh_KEEPstatistics
+#define zdef_(stype,name,string,cnt) qhstat id[qhstat next++]=name; \
+ qhstat doc[name]= string; qhstat count[name]= cnt; qhstat type[name]= stype
+#else
+#define zdef_(type,name,doc,count)
+#endif
+
+/*-<a href="qh-stat.htm#TOC"
+ >--------------------------------</a><a name="zinc_">-</a>
+
+ zzinc_( name ), zinc_( name)
+ increment an integer statistic
+*/
+#define zzinc_(id) {MAYdebugx; qhstat stats[id].i++;}
+#if qh_KEEPstatistics
+#define zinc_(id) {MAYdebugx; qhstat stats[id].i++;}
+#else
+#define zinc_(id) {}
+#endif
+
+/*-<a href="qh-stat.htm#TOC"
+ >--------------------------------</a><a name="zadd_">-</a>
+
+ zzadd_( name, value ), zadd_( name, value ), wadd_( name, value )
+ add value to an integer or real statistic
+*/
+#define zzadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
+#define wwadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
+#if qh_KEEPstatistics
+#define zadd_(id, val) {MAYdebugx; qhstat stats[id].i += (val);}
+#define wadd_(id, val) {MAYdebugx; qhstat stats[id].r += (val);}
+#else
+#define zadd_(id, val) {}
+#define wadd_(id, val) {}
+#endif
+
+/*-<a href="qh-stat.htm#TOC"
+ >--------------------------------</a><a name="zval_">-</a>
+
+ zzval_( name ), zval_( name ), wwval_( name )
+ set or return value of a statistic
+*/
+#define zzval_(id) ((qhstat stats[id]).i)
+#define wwval_(id) ((qhstat stats[id]).r)
+#if qh_KEEPstatistics
+#define zval_(id) ((qhstat stats[id]).i)
+#define wval_(id) ((qhstat stats[id]).r)
+#else
+#define zval_(id) qhstat tempi
+#define wval_(id) qhstat tempr
+#endif
+
+/*-<a href="qh-stat.htm#TOC"
+ >--------------------------------</a><a name="zmax_">-</a>
+
+ zmax_( id, val ), wmax_( id, value )
+ maximize id with val
+*/
+#define wwmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
+#if qh_KEEPstatistics
+#define zmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].i,(val));}
+#define wmax_(id, val) {MAYdebugx; maximize_(qhstat stats[id].r,(val));}
+#else
+#define zmax_(id, val) {}
+#define wmax_(id, val) {}
+#endif
+
+/*-<a href="qh-stat.htm#TOC"
+ >--------------------------------</a><a name="zmin_">-</a>
+
+ zmin_( id, val ), wmin_( id, value )
+ minimize id with val
+*/
+#if qh_KEEPstatistics
+#define zmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].i,(val));}
+#define wmin_(id, val) {MAYdebugx; minimize_(qhstat stats[id].r,(val));}
+#else
+#define zmin_(id, val) {}
+#define wmin_(id, val) {}
+#endif
+
+/*================== stat.h types ==============*/
+
+
+/*-<a href="qh-stat.htm#TOC"
+ >--------------------------------</a><a name="intrealT">-</a>
+
+ intrealT
+ union of integer and real, used for statistics
+*/
+typedef union intrealT intrealT; /* union of int and realT */
+union intrealT {
+ int i;
+ realT r;
+};
+
+/*-<a href="qh-stat.htm#TOC"
+ >--------------------------------</a><a name="qhstat">-</a>
+
+ qhstat
+ global data structure for statistics, similar to qh and qhrbox
+
+ notes:
+ access to qh_qhstat is via the "qhstat" macro. There are two choices
+ qh_QHpointer = 1 access globals via a pointer
+ enables qh_saveqhull() and qh_restoreqhull()
+ = 0 qh_qhstat is a static data structure
+ only one instance of qhull() can be active at a time
+ default value
+ qh_QHpointer is defined in libqhull.h
+ qh_QHpointer_dllimport and qh_dllimport define qh_qh as __declspec(dllimport) [libqhull.h]
+
+ allocated in stat.c using qh_malloc()
+*/
+#ifndef DEFqhstatT
+#define DEFqhstatT 1
+typedef struct qhstatT qhstatT;
+#endif
+
+#if qh_QHpointer_dllimport
+#define qhstat qh_qhstat->
+__declspec(dllimport) extern qhstatT *qh_qhstat;
+#elif qh_QHpointer
+#define qhstat qh_qhstat->
+extern qhstatT *qh_qhstat;
+#elif qh_dllimport
+#define qhstat qh_qhstat.
+__declspec(dllimport) extern qhstatT qh_qhstat;
+#else
+#define qhstat qh_qhstat.
+extern qhstatT qh_qhstat;
+#endif
+struct qhstatT {
+ intrealT stats[ZEND]; /* integer and real statistics */
+ unsigned char id[ZEND+10]; /* id's in print order */
+ const char *doc[ZEND]; /* array of documentation strings */
+ short int count[ZEND]; /* -1 if none, else index of count to use */
+ char type[ZEND]; /* type, see ztypes above */
+ char printed[ZEND]; /* true, if statistic has been printed */
+ intrealT init[ZTYPEend]; /* initial values by types, set initstatistics */
+
+ int next; /* next index for zdef_ */
+ int precision; /* index for precision problems */
+ int vridges; /* index for Voronoi ridges */
+ int tempi;
+ realT tempr;
+};
+
+/*========== function prototypes ===========*/
+
+void qh_allstatA(void);
+void qh_allstatB(void);
+void qh_allstatC(void);
+void qh_allstatD(void);
+void qh_allstatE(void);
+void qh_allstatE2(void);
+void qh_allstatF(void);
+void qh_allstatG(void);
+void qh_allstatH(void);
+void qh_allstatI(void);
+void qh_allstatistics(void);
+void qh_collectstatistics(void);
+void qh_freestatistics(void);
+void qh_initstatistics(void);
+boolT qh_newstats(int idx, int *nextindex);
+boolT qh_nostatistic(int i);
+void qh_printallstatistics(FILE *fp, const char *string);
+void qh_printstatistics(FILE *fp, const char *string);
+void qh_printstatlevel(FILE *fp, int id);
+void qh_printstats(FILE *fp, int idx, int *nextindex);
+realT qh_stddev(int num, realT tot, realT tot2, realT *ave);
+
+#endif /* qhDEFstat */
diff --git a/xs/src/qhull/src/libqhull/user.c b/xs/src/qhull/src/libqhull/user.c
new file mode 100644
index 000000000..d4726eaa3
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/user.c
@@ -0,0 +1,538 @@
+/*<html><pre> -<a href="qh-user.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ user.c
+ user redefinable functions
+
+ see user2.c for qh_fprintf, qh_malloc, qh_free
+
+ see README.txt see COPYING.txt for copyright information.
+
+ see libqhull.h for data structures, macros, and user-callable functions.
+
+ see user_eg.c, user_eg2.c, and unix.c for examples.
+
+ see user.h for user-definable constants
+
+ use qh_NOmem in mem.h to turn off memory management
+ use qh_NOmerge in user.h to turn off facet merging
+ set qh_KEEPstatistics in user.h to 0 to turn off statistics
+
+ This is unsupported software. You're welcome to make changes,
+ but you're on your own if something goes wrong. Use 'Tc' to
+ check frequently. Usually qhull will report an error if
+ a data structure becomes inconsistent. If so, it also reports
+ the last point added to the hull, e.g., 102. You can then trace
+ the execution of qhull with "T4P102".
+
+ Please report any errors that you fix to qhull@qhull.org
+
+ Qhull-template is a template for calling qhull from within your application
+
+ if you recompile and load this module, then user.o will not be loaded
+ from qhull.a
+
+ you can add additional quick allocation sizes in qh_user_memsizes
+
+ if the other functions here are redefined to not use qh_print...,
+ then io.o will not be loaded from qhull.a. See user_eg.c for an
+ example. We recommend keeping io.o for the extra debugging
+ information it supplies.
+*/
+
+#include "qhull_a.h"
+
+#include <stdarg.h>
+
+/*-<a href="qh-user.htm#TOC"
+ >-------------------------------</a><a name="qhull_template">-</a>
+
+ Qhull-template
+ Template for calling qhull from inside your program
+
+ returns:
+ exit code(see qh_ERR... in libqhull.h)
+ all memory freed
+
+ notes:
+ This can be called any number of times.
+*/
+#if 0
+{
+ int dim; /* dimension of points */
+ int numpoints; /* number of points */
+ coordT *points; /* array of coordinates for each point */
+ boolT ismalloc; /* True if qhull should free points in qh_freeqhull() or reallocation */
+ char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
+ FILE *outfile= stdout; /* output from qh_produce_output()
+ use NULL to skip qh_produce_output() */
+ FILE *errfile= stderr; /* error messages from qhull code */
+ int exitcode; /* 0 if no error from qhull */
+ facetT *facet; /* set by FORALLfacets */
+ int curlong, totlong; /* memory remaining after qh_memfreeshort */
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+#if qh_QHpointer /* see user.h */
+ if (qh_qh){ /* should be NULL */
+ qh_printf_stderr(6238, "Qhull link error. The global variable qh_qh was not initialized\n\
+ to NULL by global.c. Please compile this program with -Dqh_QHpointer_dllimport\n\
+ as well as -Dqh_QHpointer, or use libqhullstatic, or use a different tool chain.\n\n");
+ exit(1);
+ }
+#endif
+
+ /* initialize dim, numpoints, points[], ismalloc here */
+ exitcode= qh_new_qhull(dim, numpoints, points, ismalloc,
+ flags, outfile, errfile);
+ if (!exitcode) { /* if no error */
+ /* 'qh facet_list' contains the convex hull */
+ FORALLfacets {
+ /* ... your code ... */
+ }
+ }
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf(errfile, 7068, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong);
+}
+#endif
+
+/*-<a href="qh-user.htm#TOC"
+ >-------------------------------</a><a name="new_qhull">-</a>
+
+ qh_new_qhull( dim, numpoints, points, ismalloc, qhull_cmd, outfile, errfile )
+ build new qhull data structure and return exitcode (0 if no errors)
+ if numpoints=0 and points=NULL, initializes qhull
+
+ notes:
+ do not modify points until finished with results.
+ The qhull data structure contains pointers into the points array.
+ do not call qhull functions before qh_new_qhull().
+ The qhull data structure is not initialized until qh_new_qhull().
+
+ Default errfile is stderr, outfile may be null
+ qhull_cmd must start with "qhull "
+ projects points to a new point array for Delaunay triangulations ('d' and 'v')
+ transforms points into a new point array for halfspace intersection ('H')
+
+
+ To allow multiple, concurrent calls to qhull()
+ - set qh_QHpointer in user.h
+ - use qh_save_qhull and qh_restore_qhull to swap the global data structure between calls.
+ - use qh_freeqhull(qh_ALL) to free intermediate convex hulls
+
+ see:
+ Qhull-template at the beginning of this file.
+ An example of using qh_new_qhull is user_eg.c
+*/
+int qh_new_qhull(int dim, int numpoints, coordT *points, boolT ismalloc,
+ char *qhull_cmd, FILE *outfile, FILE *errfile) {
+ /* gcc may issue a "might be clobbered" warning for dim, points, and ismalloc [-Wclobbered].
+ These parameters are not referenced after a longjmp() and hence not clobbered.
+ See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
+ int exitcode, hulldim;
+ boolT new_ismalloc;
+ static boolT firstcall = True;
+ coordT *new_points;
+ if(!errfile){
+ errfile= stderr;
+ }
+ if (firstcall) {
+ qh_meminit(errfile);
+ firstcall= False;
+ } else {
+ qh_memcheck();
+ }
+ if (strncmp(qhull_cmd, "qhull ", (size_t)6)) {
+ qh_fprintf(errfile, 6186, "qhull error (qh_new_qhull): start qhull_cmd argument with \"qhull \"\n");
+ return qh_ERRinput;
+ }
+ qh_initqhull_start(NULL, outfile, errfile);
+ if(numpoints==0 && points==NULL){
+ trace1((qh ferr, 1047, "qh_new_qhull: initialize Qhull\n"));
+ return 0;
+ }
+ trace1((qh ferr, 1044, "qh_new_qhull: build new Qhull for %d %d-d points with %s\n", numpoints, dim, qhull_cmd));
+ exitcode = setjmp(qh errexit);
+ if (!exitcode)
+ {
+ qh NOerrexit = False;
+ qh_initflags(qhull_cmd);
+ if (qh DELAUNAY)
+ qh PROJECTdelaunay= True;
+ if (qh HALFspace) {
+ /* points is an array of halfspaces,
+ the last coordinate of each halfspace is its offset */
+ hulldim= dim-1;
+ qh_setfeasible(hulldim);
+ new_points= qh_sethalfspace_all(dim, numpoints, points, qh feasible_point);
+ new_ismalloc= True;
+ if (ismalloc)
+ qh_free(points);
+ }else {
+ hulldim= dim;
+ new_points= points;
+ new_ismalloc= ismalloc;
+ }
+ qh_init_B(new_points, numpoints, hulldim, new_ismalloc);
+ qh_qhull();
+ qh_check_output();
+ if (outfile) {
+ qh_produce_output();
+ }else {
+ qh_prepare_output();
+ }
+ if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ }
+ qh NOerrexit = True;
+ return exitcode;
+} /* new_qhull */
+
+/*-<a href="qh-user.htm#TOC"
+ >-------------------------------</a><a name="errexit">-</a>
+
+ qh_errexit( exitcode, facet, ridge )
+ report and exit from an error
+ report facet and ridge if non-NULL
+ reports useful information such as last point processed
+ set qh.FORCEoutput to print neighborhood of facet
+
+ see:
+ qh_errexit2() in libqhull.c for printing 2 facets
+
+ design:
+ check for error within error processing
+ compute qh.hulltime
+ print facet and ridge (if any)
+ report commandString, options, qh.furthest_id
+ print summary and statistics (including precision statistics)
+ if qh_ERRsingular
+ print help text for singular data set
+ exit program via long jump (if defined) or exit()
+*/
+void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
+
+ if (qh ERREXITcalled) {
+ qh_fprintf(qh ferr, 8126, "\nqhull error while processing previous error. Exit program\n");
+ qh_exit(qh_ERRqhull);
+ }
+ qh ERREXITcalled= True;
+ if (!qh QHULLfinished)
+ qh hulltime= qh_CPUclock - qh hulltime;
+ qh_errprint("ERRONEOUS", facet, NULL, ridge, NULL);
+ qh_fprintf(qh ferr, 8127, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command);
+ qh_fprintf(qh ferr, 8128, "Options selected for Qhull %s:\n%s\n", qh_version, qh qhull_options);
+ if (qh furthest_id >= 0) {
+ qh_fprintf(qh ferr, 8129, "Last point added to hull was p%d.", qh furthest_id);
+ if (zzval_(Ztotmerge))
+ qh_fprintf(qh ferr, 8130, " Last merge was #%d.", zzval_(Ztotmerge));
+ if (qh QHULLfinished)
+ qh_fprintf(qh ferr, 8131, "\nQhull has finished constructing the hull.");
+ else if (qh POSTmerging)
+ qh_fprintf(qh ferr, 8132, "\nQhull has started post-merging.");
+ qh_fprintf(qh ferr, 8133, "\n");
+ }
+ if (qh FORCEoutput && (qh QHULLfinished || (!facet && !ridge)))
+ qh_produce_output();
+ else if (exitcode != qh_ERRinput) {
+ if (exitcode != qh_ERRsingular && zzval_(Zsetplane) > qh hull_dim+1) {
+ qh_fprintf(qh ferr, 8134, "\nAt error exit:\n");
+ qh_printsummary(qh ferr);
+ if (qh PRINTstatistics) {
+ qh_collectstatistics();
+ qh_printstatistics(qh ferr, "at error exit");
+ qh_memstatistics(qh ferr);
+ }
+ }
+ if (qh PRINTprecision)
+ qh_printstats(qh ferr, qhstat precision, NULL);
+ }
+ if (!exitcode)
+ exitcode= qh_ERRqhull;
+ else if (exitcode == qh_ERRsingular)
+ qh_printhelp_singular(qh ferr);
+ else if (exitcode == qh_ERRprec && !qh PREmerge)
+ qh_printhelp_degenerate(qh ferr);
+ if (qh NOerrexit) {
+ qh_fprintf(qh ferr, 6187, "qhull error while ending program, or qh->NOerrexit not cleared after setjmp(). Exit program with error.\n");
+ qh_exit(qh_ERRqhull);
+ }
+ qh ERREXITcalled= False;
+ qh NOerrexit= True;
+ qh ALLOWrestart= False; /* longjmp will undo qh_build_withrestart */
+ longjmp(qh errexit, exitcode);
+} /* errexit */
+
+
+/*-<a href="qh-user.htm#TOC"
+ >-------------------------------</a><a name="errprint">-</a>
+
+ qh_errprint( fp, string, atfacet, otherfacet, atridge, atvertex )
+ prints out the information of facets and ridges to fp
+ also prints neighbors and geomview output
+
+ notes:
+ except for string, any parameter may be NULL
+*/
+void qh_errprint(const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
+ int i;
+
+ if (atfacet) {
+ qh_fprintf(qh ferr, 8135, "%s FACET:\n", string);
+ qh_printfacet(qh ferr, atfacet);
+ }
+ if (otherfacet) {
+ qh_fprintf(qh ferr, 8136, "%s OTHER FACET:\n", string);
+ qh_printfacet(qh ferr, otherfacet);
+ }
+ if (atridge) {
+ qh_fprintf(qh ferr, 8137, "%s RIDGE:\n", string);
+ qh_printridge(qh ferr, atridge);
+ if (atridge->top && atridge->top != atfacet && atridge->top != otherfacet)
+ qh_printfacet(qh ferr, atridge->top);
+ if (atridge->bottom
+ && atridge->bottom != atfacet && atridge->bottom != otherfacet)
+ qh_printfacet(qh ferr, atridge->bottom);
+ if (!atfacet)
+ atfacet= atridge->top;
+ if (!otherfacet)
+ otherfacet= otherfacet_(atridge, atfacet);
+ }
+ if (atvertex) {
+ qh_fprintf(qh ferr, 8138, "%s VERTEX:\n", string);
+ qh_printvertex(qh ferr, atvertex);
+ }
+ if (qh fout && qh FORCEoutput && atfacet && !qh QHULLfinished && !qh IStracing) {
+ qh_fprintf(qh ferr, 8139, "ERRONEOUS and NEIGHBORING FACETS to output\n");
+ for (i=0; i < qh_PRINTEND; i++) /* use fout for geomview output */
+ qh_printneighborhood(qh fout, qh PRINTout[i], atfacet, otherfacet,
+ !qh_ALL);
+ }
+} /* errprint */
+
+
+/*-<a href="qh-user.htm#TOC"
+ >-------------------------------</a><a name="printfacetlist">-</a>
+
+ qh_printfacetlist( fp, facetlist, facets, printall )
+ print all fields for a facet list and/or set of facets to fp
+ if !printall,
+ only prints good facets
+
+ notes:
+ also prints all vertices
+*/
+void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) {
+ facetT *facet, **facetp;
+
+ qh_printbegin(qh ferr, qh_PRINTfacets, facetlist, facets, printall);
+ FORALLfacet_(facetlist)
+ qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);
+ FOREACHfacet_(facets)
+ qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall);
+ qh_printend(qh ferr, qh_PRINTfacets, facetlist, facets, printall);
+} /* printfacetlist */
+
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printhelp_degenerate">-</a>
+
+ qh_printhelp_degenerate( fp )
+ prints descriptive message for precision error
+
+ notes:
+ no message if qh_QUICKhelp
+*/
+void qh_printhelp_degenerate(FILE *fp) {
+
+ if (qh MERGEexact || qh PREmerge || qh JOGGLEmax < REALmax/2)
+ qh_fprintf(fp, 9368, "\n\
+A Qhull error has occurred. Qhull should have corrected the above\n\
+precision error. Please send the input and all of the output to\n\
+qhull_bug@qhull.org\n");
+ else if (!qh_QUICKhelp) {
+ qh_fprintf(fp, 9369, "\n\
+Precision problems were detected during construction of the convex hull.\n\
+This occurs because convex hull algorithms assume that calculations are\n\
+exact, but floating-point arithmetic has roundoff errors.\n\
+\n\
+To correct for precision problems, do not use 'Q0'. By default, Qhull\n\
+selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',\n\
+Qhull joggles the input to prevent precision problems. See \"Imprecision\n\
+in Qhull\" (qh-impre.htm).\n\
+\n\
+If you use 'Q0', the output may include\n\
+coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,\n\
+Qhull may produce a ridge with four neighbors or two facets with the same \n\
+vertices. Qhull reports these events when they occur. It stops when a\n\
+concave ridge, flipped facet, or duplicate facet occurs.\n");
+#if REALfloat
+ qh_fprintf(fp, 9370, "\
+\n\
+Qhull is currently using single precision arithmetic. The following\n\
+will probably remove the precision problems:\n\
+ - recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
+#endif
+ if (qh DELAUNAY && !qh SCALElast && qh MAXabs_coord > 1e4)
+ qh_fprintf(fp, 9371, "\
+\n\
+When computing the Delaunay triangulation of coordinates > 1.0,\n\
+ - use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n");
+ if (qh DELAUNAY && !qh ATinfinity)
+ qh_fprintf(fp, 9372, "\
+When computing the Delaunay triangulation:\n\
+ - use 'Qz' to add a point at-infinity. This reduces precision problems.\n");
+
+ qh_fprintf(fp, 9373, "\
+\n\
+If you need triangular output:\n\
+ - use option 'Qt' to triangulate the output\n\
+ - use option 'QJ' to joggle the input points and remove precision errors\n\
+ - use option 'Ft'. It triangulates non-simplicial facets with added points.\n\
+\n\
+If you must use 'Q0',\n\
+try one or more of the following options. They can not guarantee an output.\n\
+ - use 'QbB' to scale the input to a cube.\n\
+ - use 'Po' to produce output and prevent partitioning for flipped facets\n\
+ - use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\
+ - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
+ - options 'Qf', 'Qbb', and 'QR0' may also help\n",
+ qh DISTround);
+ qh_fprintf(fp, 9374, "\
+\n\
+To guarantee simplicial output:\n\
+ - use option 'Qt' to triangulate the output\n\
+ - use option 'QJ' to joggle the input points and remove precision errors\n\
+ - use option 'Ft' to triangulate the output by adding points\n\
+ - use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\
+");
+ }
+} /* printhelp_degenerate */
+
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="printhelp_narrowhull">-</a>
+
+ qh_printhelp_narrowhull( minangle )
+ Warn about a narrow hull
+
+ notes:
+ Alternatively, reduce qh_WARNnarrow in user.h
+
+*/
+void qh_printhelp_narrowhull(FILE *fp, realT minangle) {
+
+ qh_fprintf(fp, 9375, "qhull precision warning: \n\
+The initial hull is narrow (cosine of min. angle is %.16f).\n\
+Is the input lower dimensional (e.g., on a plane in 3-d)? Qhull may\n\
+produce a wide facet. Options 'QbB' (scale to unit box) or 'Qbb' (scale\n\
+last coordinate) may remove this warning. Use 'Pp' to skip this warning.\n\
+See 'Limitations' in qh-impre.htm.\n",
+ -minangle); /* convert from angle between normals to angle between facets */
+} /* printhelp_narrowhull */
+
+/*-<a href="qh-io.htm#TOC"
+ >-------------------------------</a><a name="printhelp_singular">-</a>
+
+ qh_printhelp_singular( fp )
+ prints descriptive message for singular input
+*/
+void qh_printhelp_singular(FILE *fp) {
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+ realT min, max, *coord, dist;
+ int i,k;
+
+ qh_fprintf(fp, 9376, "\n\
+The input to qhull appears to be less than %d dimensional, or a\n\
+computation has overflowed.\n\n\
+Qhull could not construct a clearly convex simplex from points:\n",
+ qh hull_dim);
+ qh_printvertexlist(fp, "", qh facet_list, NULL, qh_ALL);
+ if (!qh_QUICKhelp)
+ qh_fprintf(fp, 9377, "\n\
+The center point is coplanar with a facet, or a vertex is coplanar\n\
+with a neighboring facet. The maximum round off error for\n\
+computing distances is %2.2g. The center point, facets and distances\n\
+to the center point are as follows:\n\n", qh DISTround);
+ qh_printpointid(fp, "center point", qh hull_dim, qh interior_point, qh_IDunknown);
+ qh_fprintf(fp, 9378, "\n");
+ FORALLfacets {
+ qh_fprintf(fp, 9379, "facet");
+ FOREACHvertex_(facet->vertices)
+ qh_fprintf(fp, 9380, " p%d", qh_pointid(vertex->point));
+ zinc_(Zdistio);
+ qh_distplane(qh interior_point, facet, &dist);
+ qh_fprintf(fp, 9381, " distance= %4.2g\n", dist);
+ }
+ if (!qh_QUICKhelp) {
+ if (qh HALFspace)
+ qh_fprintf(fp, 9382, "\n\
+These points are the dual of the given halfspaces. They indicate that\n\
+the intersection is degenerate.\n");
+ qh_fprintf(fp, 9383,"\n\
+These points either have a maximum or minimum x-coordinate, or\n\
+they maximize the determinant for k coordinates. Trial points\n\
+are first selected from points that maximize a coordinate.\n");
+ if (qh hull_dim >= qh_INITIALmax)
+ qh_fprintf(fp, 9384, "\n\
+Because of the high dimension, the min x-coordinate and max-coordinate\n\
+points are used if the determinant is non-zero. Option 'Qs' will\n\
+do a better, though much slower, job. Instead of 'Qs', you can change\n\
+the points by randomly rotating the input with 'QR0'.\n");
+ }
+ qh_fprintf(fp, 9385, "\nThe min and max coordinates for each dimension are:\n");
+ for (k=0; k < qh hull_dim; k++) {
+ min= REALmax;
+ max= -REALmin;
+ for (i=qh num_points, coord= qh first_point+k; i--; coord += qh hull_dim) {
+ maximize_(max, *coord);
+ minimize_(min, *coord);
+ }
+ qh_fprintf(fp, 9386, " %d: %8.4g %8.4g difference= %4.4g\n", k, min, max, max-min);
+ }
+ if (!qh_QUICKhelp) {
+ qh_fprintf(fp, 9387, "\n\
+If the input should be full dimensional, you have several options that\n\
+may determine an initial simplex:\n\
+ - use 'QJ' to joggle the input and make it full dimensional\n\
+ - use 'QbB' to scale the points to the unit cube\n\
+ - use 'QR0' to randomly rotate the input for different maximum points\n\
+ - use 'Qs' to search all points for the initial simplex\n\
+ - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
+ - trace execution with 'T3' to see the determinant for each point.\n",
+ qh DISTround);
+#if REALfloat
+ qh_fprintf(fp, 9388, "\
+ - recompile qhull for realT precision(#define REALfloat 0 in libqhull.h).\n");
+#endif
+ qh_fprintf(fp, 9389, "\n\
+If the input is lower dimensional:\n\
+ - use 'QJ' to joggle the input and make it full dimensional\n\
+ - use 'Qbk:0Bk:0' to delete coordinate k from the input. You should\n\
+ pick the coordinate with the least range. The hull will have the\n\
+ correct topology.\n\
+ - determine the flat containing the points, rotate the points\n\
+ into a coordinate plane, and delete the other coordinates.\n\
+ - add one or more points to make the input full dimensional.\n\
+");
+ }
+} /* printhelp_singular */
+
+/*-<a href="qh-globa.htm#TOC"
+ >-------------------------------</a><a name="user_memsizes">-</a>
+
+ qh_user_memsizes()
+ allocate up to 10 additional, quick allocation sizes
+
+ notes:
+ increase maximum number of allocations in qh_initqhull_mem()
+*/
+void qh_user_memsizes(void) {
+
+ /* qh_memsize(size); */
+} /* user_memsizes */
+
+
diff --git a/xs/src/qhull/src/libqhull/user.h b/xs/src/qhull/src/libqhull/user.h
new file mode 100644
index 000000000..523aa7b4e
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/user.h
@@ -0,0 +1,909 @@
+/*<html><pre> -<a href="qh-user.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ user.h
+ user redefinable constants
+
+ for each source file, user.h is included first
+ see qh-user.htm. see COPYING for copyright information.
+
+ See user.c for sample code.
+
+ before reading any code, review libqhull.h for data structure definitions and
+ the "qh" macro.
+
+Sections:
+ ============= qhull library constants ======================
+ ============= data types and configuration macros ==========
+ ============= performance related constants ================
+ ============= memory constants =============================
+ ============= joggle constants =============================
+ ============= conditional compilation ======================
+ ============= -merge constants- ============================
+
+Code flags --
+ NOerrors -- the code does not call qh_errexit()
+ WARN64 -- the code may be incompatible with 64-bit pointers
+
+*/
+
+#include <time.h>
+
+#ifndef qhDEFuser
+#define qhDEFuser 1
+
+/* Derived from Qt's corelib/global/qglobal.h */
+#if !defined(SAG_COM) && !defined(__CYGWIN__) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
+# define QHULL_OS_WIN
+#elif defined(__MWERKS__) && defined(__INTEL__) /* Metrowerks discontinued before the release of Intel Macs */
+# define QHULL_OS_WIN
+#endif
+/*============================================================*/
+/*============= qhull library constants ======================*/
+/*============================================================*/
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="filenamelen">-</a>
+
+ FILENAMElen -- max length for TI and TO filenames
+
+*/
+
+#define qh_FILENAMElen 500
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="msgcode">-</a>
+
+ msgcode -- Unique message codes for qh_fprintf
+
+ If add new messages, assign these values and increment in user.h and user_r.h
+ See QhullError.h for 10000 errors.
+
+ def counters = [27, 1048, 2059, 3026, 4068, 5003,
+ 6273, 7081, 8147, 9411, 10000, 11029]
+
+ See: qh_ERR* [libqhull.h]
+*/
+
+#define MSG_TRACE0 0
+#define MSG_TRACE1 1000
+#define MSG_TRACE2 2000
+#define MSG_TRACE3 3000
+#define MSG_TRACE4 4000
+#define MSG_TRACE5 5000
+#define MSG_ERROR 6000 /* errors written to qh.ferr */
+#define MSG_WARNING 7000
+#define MSG_STDERR 8000 /* log messages Written to qh.ferr */
+#define MSG_OUTPUT 9000
+#define MSG_QHULL_ERROR 10000 /* errors thrown by QhullError.cpp (QHULLlastError is in QhullError.h) */
+#define MSG_FIXUP 11000 /* FIXUP QH11... */
+#define MSG_MAXLEN 3000 /* qh_printhelp_degenerate() in user.c */
+
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="qh_OPTIONline">-</a>
+
+ qh_OPTIONline -- max length of an option line 'FO'
+*/
+#define qh_OPTIONline 80
+
+/*============================================================*/
+/*============= data types and configuration macros ==========*/
+/*============================================================*/
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="realT">-</a>
+
+ realT
+ set the size of floating point numbers
+
+ qh_REALdigits
+ maximimum number of significant digits
+
+ qh_REAL_1, qh_REAL_2n, qh_REAL_3n
+ format strings for printf
+
+ qh_REALmax, qh_REALmin
+ maximum and minimum (near zero) values
+
+ qh_REALepsilon
+ machine roundoff. Maximum roundoff error for addition and multiplication.
+
+ notes:
+ Select whether to store floating point numbers in single precision (float)
+ or double precision (double).
+
+ Use 'float' to save about 8% in time and 25% in space. This is particularly
+ helpful if high-d where convex hulls are space limited. Using 'float' also
+ reduces the printed size of Qhull's output since numbers have 8 digits of
+ precision.
+
+ Use 'double' when greater arithmetic precision is needed. This is needed
+ for Delaunay triangulations and Voronoi diagrams when you are not merging
+ facets.
+
+ If 'double' gives insufficient precision, your data probably includes
+ degeneracies. If so you should use facet merging (done by default)
+ or exact arithmetic (see imprecision section of manual, qh-impre.htm).
+ You may also use option 'Po' to force output despite precision errors.
+
+ You may use 'long double', but many format statements need to be changed
+ and you may need a 'long double' square root routine. S. Grundmann
+ (sg@eeiwzb.et.tu-dresden.de) has done this. He reports that the code runs
+ much slower with little gain in precision.
+
+ WARNING: on some machines, int f(){realT a= REALmax;return (a == REALmax);}
+ returns False. Use (a > REALmax/2) instead of (a == REALmax).
+
+ REALfloat = 1 all numbers are 'float' type
+ = 0 all numbers are 'double' type
+*/
+#define REALfloat 0
+
+#if (REALfloat == 1)
+#define realT float
+#define REALmax FLT_MAX
+#define REALmin FLT_MIN
+#define REALepsilon FLT_EPSILON
+#define qh_REALdigits 8 /* maximum number of significant digits */
+#define qh_REAL_1 "%6.8g "
+#define qh_REAL_2n "%6.8g %6.8g\n"
+#define qh_REAL_3n "%6.8g %6.8g %6.8g\n"
+
+#elif (REALfloat == 0)
+#define realT double
+#define REALmax DBL_MAX
+#define REALmin DBL_MIN
+#define REALepsilon DBL_EPSILON
+#define qh_REALdigits 16 /* maximum number of significant digits */
+#define qh_REAL_1 "%6.16g "
+#define qh_REAL_2n "%6.16g %6.16g\n"
+#define qh_REAL_3n "%6.16g %6.16g %6.16g\n"
+
+#else
+#error unknown float option
+#endif
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="CPUclock">-</a>
+
+ qh_CPUclock
+ define the clock() function for reporting the total time spent by Qhull
+ returns CPU ticks as a 'long int'
+ qh_CPUclock is only used for reporting the total time spent by Qhull
+
+ qh_SECticks
+ the number of clock ticks per second
+
+ notes:
+ looks for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or assumes microseconds
+ to define a custom clock, set qh_CLOCKtype to 0
+
+ if your system does not use clock() to return CPU ticks, replace
+ qh_CPUclock with the corresponding function. It is converted
+ to 'unsigned long' to prevent wrap-around during long runs. By default,
+ <time.h> defines clock_t as 'long'
+
+ Set qh_CLOCKtype to
+
+ 1 for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or microsecond
+ Note: may fail if more than 1 hour elapsed time
+
+ 2 use qh_clock() with POSIX times() (see global.c)
+*/
+#define qh_CLOCKtype 1 /* change to the desired number */
+
+#if (qh_CLOCKtype == 1)
+
+#if defined(CLOCKS_PER_SECOND)
+#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
+#define qh_SECticks CLOCKS_PER_SECOND
+
+#elif defined(CLOCKS_PER_SEC)
+#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
+#define qh_SECticks CLOCKS_PER_SEC
+
+#elif defined(CLK_TCK)
+#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
+#define qh_SECticks CLK_TCK
+
+#else
+#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
+#define qh_SECticks 1E6
+#endif
+
+#elif (qh_CLOCKtype == 2)
+#define qh_CPUclock qh_clock() /* return CPU clock */
+#define qh_SECticks 100
+
+#else /* qh_CLOCKtype == ? */
+#error unknown clock option
+#endif
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="RANDOM">-</a>
+
+ qh_RANDOMtype, qh_RANDOMmax, qh_RANDOMseed
+ define random number generator
+
+ qh_RANDOMint generates a random integer between 0 and qh_RANDOMmax.
+ qh_RANDOMseed sets the random number seed for qh_RANDOMint
+
+ Set qh_RANDOMtype (default 5) to:
+ 1 for random() with 31 bits (UCB)
+ 2 for rand() with RAND_MAX or 15 bits (system 5)
+ 3 for rand() with 31 bits (Sun)
+ 4 for lrand48() with 31 bits (Solaris)
+ 5 for qh_rand() with 31 bits (included with Qhull)
+
+ notes:
+ Random numbers are used by rbox to generate point sets. Random
+ numbers are used by Qhull to rotate the input ('QRn' option),
+ simulate a randomized algorithm ('Qr' option), and to simulate
+ roundoff errors ('Rn' option).
+
+ Random number generators differ between systems. Most systems provide
+ rand() but the period varies. The period of rand() is not critical
+ since qhull does not normally use random numbers.
+
+ The default generator is Park & Miller's minimal standard random
+ number generator [CACM 31:1195 '88]. It is included with Qhull.
+
+ If qh_RANDOMmax is wrong, qhull will report a warning and Geomview
+ output will likely be invisible.
+*/
+#define qh_RANDOMtype 5 /* *** change to the desired number *** */
+
+#if (qh_RANDOMtype == 1)
+#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, random()/MAX */
+#define qh_RANDOMint random()
+#define qh_RANDOMseed_(seed) srandom(seed);
+
+#elif (qh_RANDOMtype == 2)
+#ifdef RAND_MAX
+#define qh_RANDOMmax ((realT)RAND_MAX)
+#else
+#define qh_RANDOMmax ((realT)32767) /* 15 bits (System 5) */
+#endif
+#define qh_RANDOMint rand()
+#define qh_RANDOMseed_(seed) srand((unsigned)seed);
+
+#elif (qh_RANDOMtype == 3)
+#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, Sun */
+#define qh_RANDOMint rand()
+#define qh_RANDOMseed_(seed) srand((unsigned)seed);
+
+#elif (qh_RANDOMtype == 4)
+#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, lrand38()/MAX */
+#define qh_RANDOMint lrand48()
+#define qh_RANDOMseed_(seed) srand48(seed);
+
+#elif (qh_RANDOMtype == 5)
+#define qh_RANDOMmax ((realT)2147483646UL) /* 31 bits, qh_rand/MAX */
+#define qh_RANDOMint qh_rand()
+#define qh_RANDOMseed_(seed) qh_srand(seed);
+/* unlike rand(), never returns 0 */
+
+#else
+#error: unknown random option
+#endif
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="ORIENTclock">-</a>
+
+ qh_ORIENTclock
+ 0 for inward pointing normals by Geomview convention
+*/
+#define qh_ORIENTclock 0
+
+
+/*============================================================*/
+/*============= joggle constants =============================*/
+/*============================================================*/
+
+/*-<a href="qh-user.htm#TOC"
+>--------------------------------</a><a name="JOGGLEdefault">-</a>
+
+qh_JOGGLEdefault
+default qh.JOGGLEmax is qh.DISTround * qh_JOGGLEdefault
+
+notes:
+rbox s r 100 | qhull QJ1e-15 QR0 generates 90% faults at distround 7e-16
+rbox s r 100 | qhull QJ1e-14 QR0 generates 70% faults
+rbox s r 100 | qhull QJ1e-13 QR0 generates 35% faults
+rbox s r 100 | qhull QJ1e-12 QR0 generates 8% faults
+rbox s r 100 | qhull QJ1e-11 QR0 generates 1% faults
+rbox s r 100 | qhull QJ1e-10 QR0 generates 0% faults
+rbox 1000 W0 | qhull QJ1e-12 QR0 generates 86% faults
+rbox 1000 W0 | qhull QJ1e-11 QR0 generates 20% faults
+rbox 1000 W0 | qhull QJ1e-10 QR0 generates 2% faults
+the later have about 20 points per facet, each of which may interfere
+
+pick a value large enough to avoid retries on most inputs
+*/
+#define qh_JOGGLEdefault 30000.0
+
+/*-<a href="qh-user.htm#TOC"
+>--------------------------------</a><a name="JOGGLEincrease">-</a>
+
+qh_JOGGLEincrease
+factor to increase qh.JOGGLEmax on qh_JOGGLEretry or qh_JOGGLEagain
+*/
+#define qh_JOGGLEincrease 10.0
+
+/*-<a href="qh-user.htm#TOC"
+>--------------------------------</a><a name="JOGGLEretry">-</a>
+
+qh_JOGGLEretry
+if ZZretry = qh_JOGGLEretry, increase qh.JOGGLEmax
+
+notes:
+try twice at the original value in case of bad luck the first time
+*/
+#define qh_JOGGLEretry 2
+
+/*-<a href="qh-user.htm#TOC"
+>--------------------------------</a><a name="JOGGLEagain">-</a>
+
+qh_JOGGLEagain
+every following qh_JOGGLEagain, increase qh.JOGGLEmax
+
+notes:
+1 is OK since it's already failed qh_JOGGLEretry times
+*/
+#define qh_JOGGLEagain 1
+
+/*-<a href="qh-user.htm#TOC"
+>--------------------------------</a><a name="JOGGLEmaxincrease">-</a>
+
+qh_JOGGLEmaxincrease
+maximum qh.JOGGLEmax due to qh_JOGGLEincrease
+relative to qh.MAXwidth
+
+notes:
+qh.joggleinput will retry at this value until qh_JOGGLEmaxretry
+*/
+#define qh_JOGGLEmaxincrease 1e-2
+
+/*-<a href="qh-user.htm#TOC"
+>--------------------------------</a><a name="JOGGLEmaxretry">-</a>
+
+qh_JOGGLEmaxretry
+stop after qh_JOGGLEmaxretry attempts
+*/
+#define qh_JOGGLEmaxretry 100
+
+/*============================================================*/
+/*============= performance related constants ================*/
+/*============================================================*/
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="HASHfactor">-</a>
+
+ qh_HASHfactor
+ total hash slots / used hash slots. Must be at least 1.1.
+
+ notes:
+ =2 for at worst 50% occupancy for qh.hash_table and normally 25% occupancy
+*/
+#define qh_HASHfactor 2
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="VERIFYdirect">-</a>
+
+ qh_VERIFYdirect
+ with 'Tv' verify all points against all facets if op count is smaller
+
+ notes:
+ if greater, calls qh_check_bestdist() instead
+*/
+#define qh_VERIFYdirect 1000000
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="INITIALsearch">-</a>
+
+ qh_INITIALsearch
+ if qh_INITIALmax, search points up to this dimension
+*/
+#define qh_INITIALsearch 6
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="INITIALmax">-</a>
+
+ qh_INITIALmax
+ if dim >= qh_INITIALmax, use min/max coordinate points for initial simplex
+
+ notes:
+ from points with non-zero determinants
+ use option 'Qs' to override (much slower)
+*/
+#define qh_INITIALmax 8
+
+/*============================================================*/
+/*============= memory constants =============================*/
+/*============================================================*/
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="MEMalign">-</a>
+
+ qh_MEMalign
+ memory alignment for qh_meminitbuffers() in global.c
+
+ notes:
+ to avoid bus errors, memory allocation must consider alignment requirements.
+ malloc() automatically takes care of alignment. Since mem.c manages
+ its own memory, we need to explicitly specify alignment in
+ qh_meminitbuffers().
+
+ A safe choice is sizeof(double). sizeof(float) may be used if doubles
+ do not occur in data structures and pointers are the same size. Be careful
+ of machines (e.g., DEC Alpha) with large pointers.
+
+ If using gcc, best alignment is [fmax_() is defined in geom_r.h]
+ #define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *))
+*/
+#define qh_MEMalign ((int)(fmax_(sizeof(realT), sizeof(void *))))
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="MEMbufsize">-</a>
+
+ qh_MEMbufsize
+ size of additional memory buffers
+
+ notes:
+ used for qh_meminitbuffers() in global.c
+*/
+#define qh_MEMbufsize 0x10000 /* allocate 64K memory buffers */
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="MEMinitbuf">-</a>
+
+ qh_MEMinitbuf
+ size of initial memory buffer
+
+ notes:
+ use for qh_meminitbuffers() in global.c
+*/
+#define qh_MEMinitbuf 0x20000 /* initially allocate 128K buffer */
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="INFINITE">-</a>
+
+ qh_INFINITE
+ on output, indicates Voronoi center at infinity
+*/
+#define qh_INFINITE -10.101
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="DEFAULTbox">-</a>
+
+ qh_DEFAULTbox
+ default box size (Geomview expects 0.5)
+
+ qh_DEFAULTbox
+ default box size for integer coorindate (rbox only)
+*/
+#define qh_DEFAULTbox 0.5
+#define qh_DEFAULTzbox 1e6
+
+/*============================================================*/
+/*============= conditional compilation ======================*/
+/*============================================================*/
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="compiler">-</a>
+
+ __cplusplus
+ defined by C++ compilers
+
+ __MSC_VER
+ defined by Microsoft Visual C++
+
+ __MWERKS__ && __INTEL__
+ defined by Metrowerks when compiling for Windows (not Intel-based Macintosh)
+
+ __MWERKS__ && __POWERPC__
+ defined by Metrowerks when compiling for PowerPC-based Macintosh
+ __STDC__
+ defined for strict ANSI C
+*/
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="COMPUTEfurthest">-</a>
+
+ qh_COMPUTEfurthest
+ compute furthest distance to an outside point instead of storing it with the facet
+ =1 to compute furthest
+
+ notes:
+ computing furthest saves memory but costs time
+ about 40% more distance tests for partitioning
+ removes facet->furthestdist
+*/
+#define qh_COMPUTEfurthest 0
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="KEEPstatistics">-</a>
+
+ qh_KEEPstatistics
+ =0 removes most of statistic gathering and reporting
+
+ notes:
+ if 0, code size is reduced by about 4%.
+*/
+#define qh_KEEPstatistics 1
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="MAXoutside">-</a>
+
+ qh_MAXoutside
+ record outer plane for each facet
+ =1 to record facet->maxoutside
+
+ notes:
+ this takes a realT per facet and slightly slows down qhull
+ it produces better outer planes for geomview output
+*/
+#define qh_MAXoutside 1
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="NOmerge">-</a>
+
+ qh_NOmerge
+ disables facet merging if defined
+
+ notes:
+ This saves about 10% space.
+
+ Unless 'Q0'
+ qh_NOmerge sets 'QJ' to avoid precision errors
+
+ #define qh_NOmerge
+
+ see:
+ <a href="mem.h#NOmem">qh_NOmem</a> in mem.c
+
+ see user.c/user_eg.c for removing io.o
+*/
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="NOtrace">-</a>
+
+ qh_NOtrace
+ no tracing if defined
+
+ notes:
+ This saves about 5% space.
+
+ #define qh_NOtrace
+*/
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="QHpointer">-</a>
+
+ qh_QHpointer
+ access global data with pointer or static structure
+
+ qh_QHpointer = 1 access globals via a pointer to allocated memory
+ enables qh_saveqhull() and qh_restoreqhull()
+ [2010, gcc] costs about 4% in time and 4% in space
+ [2003, msvc] costs about 8% in time and 2% in space
+
+ = 0 qh_qh and qh_qhstat are static data structures
+ only one instance of qhull() can be active at a time
+ default value
+
+ qh_QHpointer_dllimport and qh_dllimport define qh_qh as __declspec(dllimport) [libqhull.h]
+ It is required for msvc-2005. It is not needed for gcc.
+
+ notes:
+ [jan'16] qh_QHpointer is deprecated for Qhull. Use libqhull_r instead.
+ all global variables for qhull are in qh, qhmem, and qhstat
+ qh is defined in libqhull.h
+ qhmem is defined in mem.h
+ qhstat is defined in stat.h
+
+*/
+#ifdef qh_QHpointer
+#if qh_dllimport
+#error QH6207 Qhull error: Use qh_QHpointer_dllimport instead of qh_dllimport with qh_QHpointer
+#endif
+#else
+#define qh_QHpointer 0
+#if qh_QHpointer_dllimport
+#error QH6234 Qhull error: Use qh_dllimport instead of qh_QHpointer_dllimport when qh_QHpointer is not defined
+#endif
+#endif
+#if 0 /* sample code */
+ qhT *oldqhA, *oldqhB;
+
+ exitcode= qh_new_qhull(dim, numpoints, points, ismalloc,
+ flags, outfile, errfile);
+ /* use results from first call to qh_new_qhull */
+ oldqhA= qh_save_qhull();
+ exitcode= qh_new_qhull(dimB, numpointsB, pointsB, ismalloc,
+ flags, outfile, errfile);
+ /* use results from second call to qh_new_qhull */
+ oldqhB= qh_save_qhull();
+ qh_restore_qhull(&oldqhA);
+ /* use results from first call to qh_new_qhull */
+ qh_freeqhull(qh_ALL); /* frees all memory used by first call */
+ qh_restore_qhull(&oldqhB);
+ /* use results from second call to qh_new_qhull */
+ qh_freeqhull(!qh_ALL); /* frees long memory used by second call */
+ qh_memfreeshort(&curlong, &totlong); /* frees short memory and memory allocator */
+#endif
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="QUICKhelp">-</a>
+
+ qh_QUICKhelp
+ =1 to use abbreviated help messages, e.g., for degenerate inputs
+*/
+#define qh_QUICKhelp 0
+
+/*============================================================*/
+/*============= -merge constants- ============================*/
+/*============================================================*/
+/*
+ These constants effect facet merging. You probably will not need
+ to modify them. They effect the performance of facet merging.
+*/
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="DIMmergeVertex">-</a>
+
+ qh_DIMmergeVertex
+ max dimension for vertex merging (it is not effective in high-d)
+*/
+#define qh_DIMmergeVertex 6
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="DIMreduceBuild">-</a>
+
+ qh_DIMreduceBuild
+ max dimension for vertex reduction during build (slow in high-d)
+*/
+#define qh_DIMreduceBuild 5
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="BESTcentrum">-</a>
+
+ qh_BESTcentrum
+ if > 2*dim+n vertices, qh_findbestneighbor() tests centrums (faster)
+ else, qh_findbestneighbor() tests all vertices (much better merges)
+
+ qh_BESTcentrum2
+ if qh_BESTcentrum2 * DIM3 + BESTcentrum < #vertices tests centrums
+*/
+#define qh_BESTcentrum 20
+#define qh_BESTcentrum2 2
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="BESTnonconvex">-</a>
+
+ qh_BESTnonconvex
+ if > dim+n neighbors, qh_findbestneighbor() tests nonconvex ridges.
+
+ notes:
+ It is needed because qh_findbestneighbor is slow for large facets
+*/
+#define qh_BESTnonconvex 15
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="MAXnewmerges">-</a>
+
+ qh_MAXnewmerges
+ if >n newmerges, qh_merge_nonconvex() calls qh_reducevertices_centrums.
+
+ notes:
+ It is needed because postmerge can merge many facets at once
+*/
+#define qh_MAXnewmerges 2
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="MAXnewcentrum">-</a>
+
+ qh_MAXnewcentrum
+ if <= dim+n vertices (n approximates the number of merges),
+ reset the centrum in qh_updatetested() and qh_mergecycle_facets()
+
+ notes:
+ needed to reduce cost and because centrums may move too much if
+ many vertices in high-d
+*/
+#define qh_MAXnewcentrum 5
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="COPLANARratio">-</a>
+
+ qh_COPLANARratio
+ for 3-d+ merging, qh.MINvisible is n*premerge_centrum
+
+ notes:
+ for non-merging, it's DISTround
+*/
+#define qh_COPLANARratio 3
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="DISToutside">-</a>
+
+ qh_DISToutside
+ When is a point clearly outside of a facet?
+ Stops search in qh_findbestnew or qh_partitionall
+ qh_findbest uses qh.MINoutside since since it is only called if no merges.
+
+ notes:
+ 'Qf' always searches for best facet
+ if !qh.MERGING, same as qh.MINoutside.
+ if qh_USEfindbestnew, increase value since neighboring facets may be ill-behaved
+ [Note: Zdelvertextot occurs normally with interior points]
+ RBOX 1000 s Z1 G1e-13 t1001188774 | QHULL Tv
+ When there is a sharp edge, need to move points to a
+ clearly good facet; otherwise may be lost in another partitioning.
+ if too big then O(n^2) behavior for partitioning in cone
+ if very small then important points not processed
+ Needed in qh_partitionall for
+ RBOX 1000 s Z1 G1e-13 t1001032651 | QHULL Tv
+ Needed in qh_findbestnew for many instances of
+ RBOX 1000 s Z1 G1e-13 t | QHULL Tv
+
+ See:
+ qh_DISToutside -- when is a point clearly outside of a facet
+ qh_SEARCHdist -- when is facet coplanar with the best facet?
+ qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
+*/
+#define qh_DISToutside ((qh_USEfindbestnew ? 2 : 1) * \
+ fmax_((qh MERGING ? 2 : 1)*qh MINoutside, qh max_outside))
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="RATIOnearinside">-</a>
+
+ qh_RATIOnearinside
+ ratio of qh.NEARinside to qh.ONEmerge for retaining inside points for
+ qh_check_maxout().
+
+ notes:
+ This is overkill since do not know the correct value.
+ It effects whether 'Qc' reports all coplanar points
+ Not used for 'd' since non-extreme points are coplanar
+*/
+#define qh_RATIOnearinside 5
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="SEARCHdist">-</a>
+
+ qh_SEARCHdist
+ When is a facet coplanar with the best facet?
+ qh_findbesthorizon: all coplanar facets of the best facet need to be searched.
+
+ See:
+ qh_DISToutside -- when is a point clearly outside of a facet
+ qh_SEARCHdist -- when is facet coplanar with the best facet?
+ qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
+*/
+#define qh_SEARCHdist ((qh_USEfindbestnew ? 2 : 1) * \
+ (qh max_outside + 2 * qh DISTround + fmax_( qh MINvisible, qh MAXcoplanar)));
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="USEfindbestnew">-</a>
+
+ qh_USEfindbestnew
+ Always use qh_findbestnew for qh_partitionpoint, otherwise use
+ qh_findbestnew if merged new facet or sharpnewfacets.
+
+ See:
+ qh_DISToutside -- when is a point clearly outside of a facet
+ qh_SEARCHdist -- when is facet coplanar with the best facet?
+ qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
+*/
+#define qh_USEfindbestnew (zzval_(Ztotmerge) > 50)
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="WIDEcoplanar">-</a>
+
+ qh_WIDEcoplanar
+ n*MAXcoplanar or n*MINvisible for a WIDEfacet
+
+ if vertex is further than qh.WIDEfacet from the hyperplane
+ then its ridges are not counted in computing the area, and
+ the facet's centrum is frozen.
+
+ notes:
+ qh.WIDEfacet= max(qh.MAXoutside,qh_WIDEcoplanar*qh.MAXcoplanar,
+ qh_WIDEcoplanar * qh.MINvisible);
+*/
+#define qh_WIDEcoplanar 6
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="WIDEduplicate">-</a>
+
+ qh_WIDEduplicate
+ Merge ratio for errexit from qh_forcedmerges due to duplicate ridge
+ Override with option Q12 no-wide-duplicate
+
+ Notes:
+ Merging a duplicate ridge can lead to very wide facets.
+ A future release of qhull will avoid duplicate ridges by removing duplicate sub-ridges from the horizon
+*/
+#define qh_WIDEduplicate 100
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="MAXnarrow">-</a>
+
+ qh_MAXnarrow
+ max. cosine in initial hull that sets qh.NARROWhull
+
+ notes:
+ If qh.NARROWhull, the initial partition does not make
+ coplanar points. If narrow, a coplanar point can be
+ coplanar to two facets of opposite orientations and
+ distant from the exact convex hull.
+
+ Conservative estimate. Don't actually see problems until it is -1.0
+*/
+#define qh_MAXnarrow -0.99999999
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="WARNnarrow">-</a>
+
+ qh_WARNnarrow
+ max. cosine in initial hull to warn about qh.NARROWhull
+
+ notes:
+ this is a conservative estimate.
+ Don't actually see problems until it is -1.0. See qh-impre.htm
+*/
+#define qh_WARNnarrow -0.999999999999999
+
+/*-<a href="qh-user.htm#TOC"
+ >--------------------------------</a><a name="ZEROdelaunay">-</a>
+
+ qh_ZEROdelaunay
+ a zero Delaunay facet occurs for input sites coplanar with their convex hull
+ the last normal coefficient of a zero Delaunay facet is within
+ qh_ZEROdelaunay * qh.ANGLEround of 0
+
+ notes:
+ qh_ZEROdelaunay does not allow for joggled input ('QJ').
+
+ You can avoid zero Delaunay facets by surrounding the input with a box.
+
+ Use option 'PDk:-n' to explicitly define zero Delaunay facets
+ k= dimension of input sites (e.g., 3 for 3-d Delaunay triangulation)
+ n= the cutoff for zero Delaunay facets (e.g., 'PD3:-1e-12')
+*/
+#define qh_ZEROdelaunay 2
+
+/*============================================================*/
+/*============= Microsoft DevStudio ==========================*/
+/*============================================================*/
+
+/*
+ Finding Memory Leaks Using the CRT Library
+ https://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.100).aspx
+
+ Reports enabled in qh_lib_check for Debug window and stderr
+
+ From 2005=>msvcr80d, 2010=>msvcr100d, 2012=>msvcr110d
+
+ Watch: {,,msvcr80d.dll}_crtBreakAlloc Value from {n} in the leak report
+ _CrtSetBreakAlloc(689); // qh_lib_check() [global_r.c]
+
+ Examples
+ http://free-cad.sourceforge.net/SrcDocu/d2/d7f/MemDebug_8cpp_source.html
+ https://github.com/illlust/Game/blob/master/library/MemoryLeak.cpp
+*/
+#if 0 /* off (0) by default for QHULL_CRTDBG */
+#define QHULL_CRTDBG
+#endif
+
+#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+#endif
+#endif /* qh_DEFuser */
+
+
+
diff --git a/xs/src/qhull/src/libqhull/usermem.c b/xs/src/qhull/src/libqhull/usermem.c
new file mode 100644
index 000000000..0e99e8f66
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/usermem.c
@@ -0,0 +1,94 @@
+/*<html><pre> -<a href="qh-user.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ usermem.c
+ qh_exit(), qh_free(), and qh_malloc()
+
+ See README.txt.
+
+ If you redefine one of these functions you must redefine all of them.
+ If you recompile and load this file, then usermem.o will not be loaded
+ from qhull.a or qhull.lib
+
+ See libqhull.h for data structures, macros, and user-callable functions.
+ See user.c for qhull-related, redefinable functions
+ see user.h for user-definable constants
+ See userprintf.c for qh_fprintf and userprintf_rbox.c for qh_fprintf_rbox
+
+ Please report any errors that you fix to qhull@qhull.org
+*/
+
+#include "libqhull.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+/*-<a href="qh-user.htm#TOC"
+ >-------------------------------</a><a name="qh_exit">-</a>
+
+ qh_exit( exitcode )
+ exit program
+
+ notes:
+ qh_exit() is called when qh_errexit() and longjmp() are not available.
+
+ This is the only use of exit() in Qhull
+ To replace qh_exit with 'throw', see libqhullcpp/usermem_r-cpp.cpp
+*/
+void qh_exit(int exitcode) {
+ exit(exitcode);
+} /* exit */
+
+/*-<a href="qh-user.htm#TOC"
+ >-------------------------------</a><a name="qh_fprintf_stderr">-</a>
+
+ qh_fprintf_stderr( msgcode, format, list of args )
+ fprintf to stderr with msgcode (non-zero)
+
+ notes:
+ qh_fprintf_stderr() is called when qh.ferr is not defined, usually due to an initialization error
+
+ It is typically followed by qh_errexit().
+
+ Redefine this function to avoid using stderr
+
+ Use qh_fprintf [userprintf.c] for normal printing
+*/
+void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
+ va_list args;
+
+ va_start(args, fmt);
+ if(msgcode)
+ fprintf(stderr, "QH%.4d ", msgcode);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+} /* fprintf_stderr */
+
+/*-<a href="qh-user.htm#TOC"
+>-------------------------------</a><a name="qh_free">-</a>
+
+ qh_free( mem )
+ free memory
+
+ notes:
+ same as free()
+ No calls to qh_errexit()
+*/
+void qh_free(void *mem) {
+ free(mem);
+} /* free */
+
+/*-<a href="qh-user.htm#TOC"
+ >-------------------------------</a><a name="qh_malloc">-</a>
+
+ qh_malloc( mem )
+ allocate memory
+
+ notes:
+ same as malloc()
+*/
+void *qh_malloc(size_t size) {
+ return malloc(size);
+} /* malloc */
+
+
diff --git a/xs/src/qhull/src/libqhull/userprintf.c b/xs/src/qhull/src/libqhull/userprintf.c
new file mode 100644
index 000000000..190d7cd79
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/userprintf.c
@@ -0,0 +1,66 @@
+/*<html><pre> -<a href="qh-user.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ userprintf.c
+ qh_fprintf()
+
+ see README.txt see COPYING.txt for copyright information.
+
+ If you recompile and load this file, then userprintf.o will not be loaded
+ from qhull.a or qhull.lib
+
+ See libqhull.h for data structures, macros, and user-callable functions.
+ See user.c for qhull-related, redefinable functions
+ see user.h for user-definable constants
+ See usermem.c for qh_exit(), qh_free(), and qh_malloc()
+ see Qhull.cpp and RboxPoints.cpp for examples.
+
+ Please report any errors that you fix to qhull@qhull.org
+*/
+
+#include "libqhull.h"
+#include "mem.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*-<a href="qh-user.htm#TOC"
+ >-------------------------------</a><a name="qh_fprintf">-</a>
+
+ qh_fprintf(fp, msgcode, format, list of args )
+ print arguments to *fp according to format
+ Use qh_fprintf_rbox() for rboxlib.c
+
+ notes:
+ same as fprintf()
+ fgets() is not trapped like fprintf()
+ exit qh_fprintf via qh_errexit()
+ may be called for errors in qh_initstatistics and qh_meminit
+*/
+
+void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... ) {
+ va_list args;
+
+ if (!fp) {
+ /* could use qhmem.ferr, but probably better to be cautious */
+ qh_fprintf_stderr(6232, "Qhull internal error (userprintf.c): fp is 0. Wrong qh_fprintf called.\n");
+ qh_errexit(6232, NULL, NULL);
+ }
+ va_start(args, fmt);
+#if qh_QHpointer
+ if (qh_qh && qh ANNOTATEoutput) {
+#else
+ if (qh ANNOTATEoutput) {
+#endif
+ fprintf(fp, "[QH%.4d]", msgcode);
+ }else if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR ) {
+ fprintf(fp, "QH%.4d ", msgcode);
+ }
+ vfprintf(fp, fmt, args);
+ va_end(args);
+
+ /* Place debugging traps here. Use with option 'Tn' */
+
+} /* qh_fprintf */
+
diff --git a/xs/src/qhull/src/libqhull/userprintf_rbox.c b/xs/src/qhull/src/libqhull/userprintf_rbox.c
new file mode 100644
index 000000000..8edd2001a
--- /dev/null
+++ b/xs/src/qhull/src/libqhull/userprintf_rbox.c
@@ -0,0 +1,53 @@
+/*<html><pre> -<a href="qh-user.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ userprintf_rbox.c
+ qh_fprintf_rbox()
+
+ see README.txt see COPYING.txt for copyright information.
+
+ If you recompile and load this file, then userprintf_rbox.o will not be loaded
+ from qhull.a or qhull.lib
+
+ See libqhull.h for data structures, macros, and user-callable functions.
+ See user.c for qhull-related, redefinable functions
+ see user.h for user-definable constants
+ See usermem.c for qh_exit(), qh_free(), and qh_malloc()
+ see Qhull.cpp and RboxPoints.cpp for examples.
+
+ Please report any errors that you fix to qhull@qhull.org
+*/
+
+#include "libqhull.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*-<a href="qh-user.htm#TOC"
+ >-------------------------------</a><a name="qh_fprintf_rbox">-</a>
+
+ qh_fprintf_rbox(fp, msgcode, format, list of args )
+ print arguments to *fp according to format
+ Use qh_fprintf_rbox() for rboxlib.c
+
+ notes:
+ same as fprintf()
+ fgets() is not trapped like fprintf()
+ exit qh_fprintf_rbox via qh_errexit_rbox()
+*/
+
+void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... ) {
+ va_list args;
+
+ if (!fp) {
+ qh_fprintf_stderr(6231, "Qhull internal error (userprintf_rbox.c): fp is 0. Wrong qh_fprintf_rbox called.\n");
+ qh_errexit_rbox(6231);
+ }
+ if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR)
+ fprintf(fp, "QH%.4d ", msgcode);
+ va_start(args, fmt);
+ vfprintf(fp, fmt, args);
+ va_end(args);
+} /* qh_fprintf_rbox */
+
diff --git a/xs/src/qhull/src/libqhull_r/Makefile b/xs/src/qhull/src/libqhull_r/Makefile
new file mode 100644
index 000000000..5c40969e0
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/Makefile
@@ -0,0 +1,240 @@
+# Simple gcc Makefile for reentrant qhull and rbox (default gcc/g++)
+#
+# make help
+# See README.txt and ../../Makefile
+#
+# Variables
+# BINDIR directory where to copy executables
+# DESTDIR destination directory for 'make install'
+# DOCDIR directory where to copy html documentation
+# INCDIR directory where to copy headers
+# LIBDIR directory where to copy libraries
+# MANDIR directory where to copy manual pages
+# PRINTMAN command for printing manual pages
+# PRINTC command for printing C files
+# CC ANSI C or C++ compiler
+# CC_OPTS1 options used to compile .c files
+# CC_OPTS2 options used to link .o files
+# CC_OPTS3 options to build shared libraries
+#
+# LIBQHULL_OBJS .o files for linking
+# LIBQHULL_HDRS .h files for printing
+# CFILES .c files for printing
+# DOCFILES documentation files
+# FILES miscellaneous files for printing
+# TFILES .txt versions of html files
+# FILES all other files
+# LIBQHULL_OBJS specifies the object files of libqhullstatic_r.a
+#
+# Results
+# rbox Generates points sets for qhull, qconvex, etc.
+# qhull Computes convex hulls and related structures
+# qconvex, qdelaunay, qhalf, qvoronoi
+# Specializations of qhull for each geometric structure
+# libqhullstatic_r.a Static library for reentrant qhull
+# testqset_r Standalone test of reentrant qset_r.c with mem_r.c
+# user_eg An example of using qhull (reentrant)
+# user_eg2 An example of using qhull (reentrant)
+#
+# Make targets
+# make Build results using gcc or another compiler
+# make clean Remove object files
+# make cleanall Remove generated files
+# make doc Print documentation
+# make help
+# make install Copy qhull, rbox, qhull.1, rbox.1 to BINDIR, MANDIR
+# make new Rebuild qhull and rbox from source
+# make printall Print all files
+# make qtest Quick test of qset, rbox, and qhull
+# make test Quck test of qhull, qconvex, etc.
+#
+# Do not replace tabs with spaces. Needed for build rules
+# Unix line endings (\n)
+# $Id: //main/2015/qhull/src/libqhull_r/Makefile#6 $
+
+DESTDIR = /usr/local
+BINDIR = $(DESTDIR)/bin
+INCDIR = $(DESTDIR)/include
+LIBDIR = $(DESTDIR)/lib
+DOCDIR = $(DESTDIR)/share/doc/qhull
+MANDIR = $(DESTDIR)/share/man/man1
+
+# if you do not have enscript, try a2ps or just use lpr. The files are text.
+PRINTMAN = enscript -2rl
+PRINTC = enscript -2r
+# PRINTMAN = lpr
+# PRINTC = lpr
+
+#for Gnu's gcc compiler, -O3 for optimization, -g for debugging, -pg for profiling
+# -fpic needed for gcc x86_64-linux-gnu. Not needed for mingw
+CC = gcc
+CC_OPTS1 = -O3 -ansi -I../../src -fpic $(CC_WARNINGS)
+
+# for Sun's cc compiler, -fast or O2 for optimization, -g for debugging, -Xc for ANSI
+#CC = cc
+#CC_OPTS1 = -Xc -v -fast -I../../src
+
+# for Silicon Graphics cc compiler, -O2 for optimization, -g for debugging
+#CC = cc
+#CC_OPTS1 = -ansi -O2 -I../../src
+
+# for Next cc compiler with fat executable
+#CC = cc
+#CC_OPTS1 = -ansi -O2 -I../../src -arch m68k -arch i386 -arch hppa
+
+# For loader, ld,
+CC_OPTS2 = $(CC_OPTS1)
+
+# Default targets for make
+
+all: qhull_links qhull_all qtest
+
+help:
+ head -n 50 Makefile
+
+clean:
+ rm -f *.o
+ # Delete linked files from other directories [qhull_links]
+ rm -f qconvex_r.c unix_r.c qdelaun_r.c qhalf_r.c qvoronoi_r.c rbox_r.c
+ rm -f user_eg_r.c user_eg2_r.c testqset_r.c
+
+cleanall: clean
+ rm -f qconvex qdelaunay qhalf qvoronoi qhull *.exe
+ rm -f core user_eg_r user_eg2_r testqset_r libqhullstatic_r.a
+
+doc:
+ $(PRINTMAN) $(TXTFILES) $(DOCFILES)
+
+install:
+ mkdir -p $(BINDIR)
+ mkdir -p $(DOCDIR)
+ mkdir -p $(INCDIR)/libqhull
+ mkdir -p $(MANDIR)
+ cp -p qconvex qdelaunay qhalf qhull qvoronoi rbox $(BINDIR)
+ cp -p libqhullstatic_r.a $(LIBDIR)
+ cp -p ../../html/qhull.man $(MANDIR)/qhull.1
+ cp -p ../../html/rbox.man $(MANDIR)/rbox.1
+ cp -p ../../html/* $(DOCDIR)
+ cp *.h $(INCDIR)/libqhull_r
+
+new: cleanall all
+
+printall: doc printh printc printf
+
+printh:
+ $(PRINTC) $(LIBQHULL_HDRS)
+
+printc:
+ $(PRINTC) $(CFILES)
+
+# LIBQHULL_OBJS_1 ordered by frequency of execution with small files at end. Better locality.
+# Same definitions as ../../Makefile
+
+LIBQHULLS_OBJS_1= global_r.o stat_r.o geom2_r.o poly2_r.o merge_r.o \
+ libqhull_r.o geom_r.o poly_r.o qset_r.o mem_r.o random_r.o
+
+LIBQHULLS_OBJS_2= $(LIBQHULLS_OBJS_1) usermem_r.o userprintf_r.o io_r.o user_r.o
+
+LIBQHULLS_OBJS= $(LIBQHULLS_OBJS_2) rboxlib_r.o userprintf_rbox_r.o
+
+LIBQHULL_HDRS= user_r.h libqhull_r.h qhull_ra.h geom_r.h \
+ io_r.h mem_r.h merge_r.h poly_r.h random_r.h \
+ qset_r.h stat_r.h
+
+# CFILES ordered alphabetically after libqhull.c
+CFILES= ../qhull/unix_r.c libqhull_r.c geom_r.c geom2_r.c global_r.c io_r.c \
+ mem_r.c merge_r.c poly_r.c poly2_r.c random_r.c rboxlib_r.c \
+ qset_r.c stat_r.c user_r.c usermem_r.c userprintf_r.c \
+ ../qconvex/qconvex.c ../qdelaunay/qdelaun.c ../qhalf/qhalf.c ../qvoronoi/qvoronoi.c
+
+TXTFILES= ../../Announce.txt ../../REGISTER.txt ../../COPYING.txt ../../README.txt ../Changes.txt
+DOCFILES= ../../html/rbox.txt ../../html/qhull.txt
+
+.c.o:
+ $(CC) -c $(CC_OPTS1) -o $@ $<
+
+# Work around problems with ../ in Red Hat Linux
+qhull_links:
+ # On MINSYS, 'ln -s' may create a copy instead of a symbolic link
+ [ -f qconvex_r.c ] || ln -s ../qconvex/qconvex_r.c
+ [ -f qdelaun_r.c ] || ln -s ../qdelaunay/qdelaun_r.c
+ [ -f qhalf_r.c ] || ln -s ../qhalf/qhalf_r.c
+ [ -f qvoronoi_r.c ] || ln -s ../qvoronoi/qvoronoi_r.c
+ [ -f rbox_r.c ] || ln -s ../rbox/rbox_r.c
+ [ -f testqset_r.c ] || ln -s ../testqset_r/testqset_r.c
+ [ -f unix_r.c ] || ln -s ../qhull/unix_r.c
+ [ -f user_eg_r.c ] || ln -s ../user_eg/user_eg_r.c
+ [ -f user_eg2_r.c ] || ln -s ../user_eg2/user_eg2_r.c
+
+# compile qhull without using bin/libqhullstatic_r.a
+qhull_all: qconvex_r.o qdelaun_r.o qhalf_r.o qvoronoi_r.o unix_r.o user_eg_r.o user_eg2_r.o rbox_r.o testqset_r.o $(LIBQHULLS_OBJS)
+ $(CC) -o qconvex $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qconvex_r.o
+ $(CC) -o qdelaunay $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qdelaun_r.o
+ $(CC) -o qhalf $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qhalf_r.o
+ $(CC) -o qvoronoi $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) qvoronoi_r.o
+ $(CC) -o qhull $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) unix_r.o
+ $(CC) -o rbox $(CC_OPTS2) -lm $(LIBQHULLS_OBJS) rbox_r.o
+ $(CC) -o user_eg $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_2) user_eg_r.o
+ $(CC) -o user_eg2 $(CC_OPTS2) -lm $(LIBQHULLS_OBJS_1) user_eg2_r.o usermem_r.o userprintf_r.o io_r.o
+ $(CC) -o testqset_r $(CC_OPTS2) -lm mem_r.o qset_r.o usermem_r.o testqset_r.o
+ -ar -rs libqhullstatic_r.a $(LIBQHULLS_OBJS)
+ #libqhullstatic_r.a is not needed for qhull
+ #If 'ar -rs' fails try using 'ar -s' with 'ranlib'
+ #ranlib libqhullstatic_r.a
+
+qtest:
+ @echo ============================================
+ @echo == make qtest ==============================
+ @echo ============================================
+ @echo -n "== "
+ @date
+ @echo
+ @echo Testing qset.c and mem.c with testqset
+ ./testqset_r 10000
+ @echo Run the qhull smoketest
+ ./rbox D4 | ./qhull
+ @echo ============================================
+ @echo == To smoketest qhull programs
+ @echo '== make test'
+ @echo ============================================
+ @echo
+ @echo ============================================
+ @echo == For all make targets
+ @echo '== make help'
+ @echo ============================================
+ @echo
+
+test: qtest
+ @echo ==============================
+ @echo ========= qconvex ============
+ @echo ==============================
+ -./rbox 10 | ./qconvex Tv
+ @echo
+ @echo ==============================
+ @echo ========= qdelaunay ==========
+ @echo ==============================
+ -./rbox 10 | ./qdelaunay Tv
+ @echo
+ @echo ==============================
+ @echo ========= qhalf ==============
+ @echo ==============================
+ -./rbox 10 | ./qconvex FQ FV n Tv | ./qhalf Tv
+ @echo
+ @echo ==============================
+ @echo ========= qvoronoi ===========
+ @echo ==============================
+ -./rbox 10 | ./qvoronoi Tv
+ @echo
+ @echo ==============================
+ @echo ========= user_eg ============
+ @echo == w/o shared library ========
+ @echo ==============================
+ -./user_eg
+ @echo
+ @echo ==============================
+ @echo ========= user_eg2 ===========
+ @echo ==============================
+ -./user_eg2
+ @echo
+
+# end of Makefile
diff --git a/xs/src/qhull/src/libqhull_r/geom2_r.c b/xs/src/qhull/src/libqhull_r/geom2_r.c
new file mode 100644
index 000000000..48addba1c
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/geom2_r.c
@@ -0,0 +1,2096 @@
+/*<html><pre> -<a href="qh-geom_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+
+ geom2_r.c
+ infrequently used geometric routines of qhull
+
+ see qh-geom_r.htm and geom_r.h
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/geom2_r.c#6 $$Change: 2065 $
+ $DateTime: 2016/01/18 13:51:04 $$Author: bbarber $
+
+ frequently used code goes into geom_r.c
+*/
+
+#include "qhull_ra.h"
+
+/*================== functions in alphabetic order ============*/
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="copypoints">-</a>
+
+ qh_copypoints(qh, points, numpoints, dimension)
+ return qh_malloc'd copy of points
+
+ notes:
+ qh_free the returned points to avoid a memory leak
+*/
+coordT *qh_copypoints(qhT *qh, coordT *points, int numpoints, int dimension) {
+ int size;
+ coordT *newpoints;
+
+ size= numpoints * dimension * (int)sizeof(coordT);
+ if (!(newpoints= (coordT*)qh_malloc((size_t)size))) {
+ qh_fprintf(qh, qh->ferr, 6004, "qhull error: insufficient memory to copy %d points\n",
+ numpoints);
+ qh_errexit(qh, qh_ERRmem, NULL, NULL);
+ }
+ memcpy((char *)newpoints, (char *)points, (size_t)size); /* newpoints!=0 by QH6004 */
+ return newpoints;
+} /* copypoints */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="crossproduct">-</a>
+
+ qh_crossproduct( dim, vecA, vecB, vecC )
+ crossproduct of 2 dim vectors
+ C= A x B
+
+ notes:
+ from Glasner, Graphics Gems I, p. 639
+ only defined for dim==3
+*/
+void qh_crossproduct(int dim, realT vecA[3], realT vecB[3], realT vecC[3]){
+
+ if (dim == 3) {
+ vecC[0]= det2_(vecA[1], vecA[2],
+ vecB[1], vecB[2]);
+ vecC[1]= - det2_(vecA[0], vecA[2],
+ vecB[0], vecB[2]);
+ vecC[2]= det2_(vecA[0], vecA[1],
+ vecB[0], vecB[1]);
+ }
+} /* vcross */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="determinant">-</a>
+
+ qh_determinant(qh, rows, dim, nearzero )
+ compute signed determinant of a square matrix
+ uses qh.NEARzero to test for degenerate matrices
+
+ returns:
+ determinant
+ overwrites rows and the matrix
+ if dim == 2 or 3
+ nearzero iff determinant < qh->NEARzero[dim-1]
+ (!quite correct, not critical)
+ if dim >= 4
+ nearzero iff diagonal[k] < qh->NEARzero[k]
+*/
+realT qh_determinant(qhT *qh, realT **rows, int dim, boolT *nearzero) {
+ realT det=0;
+ int i;
+ boolT sign= False;
+
+ *nearzero= False;
+ if (dim < 2) {
+ qh_fprintf(qh, qh->ferr, 6005, "qhull internal error (qh_determinate): only implemented for dimension >= 2\n");
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }else if (dim == 2) {
+ det= det2_(rows[0][0], rows[0][1],
+ rows[1][0], rows[1][1]);
+ if (fabs_(det) < 10*qh->NEARzero[1]) /* not really correct, what should this be? */
+ *nearzero= True;
+ }else if (dim == 3) {
+ det= det3_(rows[0][0], rows[0][1], rows[0][2],
+ rows[1][0], rows[1][1], rows[1][2],
+ rows[2][0], rows[2][1], rows[2][2]);
+ if (fabs_(det) < 10*qh->NEARzero[2]) /* what should this be? det 5.5e-12 was flat for qh_maxsimplex of qdelaunay 0,0 27,27 -36,36 -9,63 */
+ *nearzero= True;
+ }else {
+ qh_gausselim(qh, rows, dim, dim, &sign, nearzero); /* if nearzero, diagonal still ok*/
+ det= 1.0;
+ for (i=dim; i--; )
+ det *= (rows[i])[i];
+ if (sign)
+ det= -det;
+ }
+ return det;
+} /* determinant */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="detjoggle">-</a>
+
+ qh_detjoggle(qh, points, numpoints, dimension )
+ determine default max joggle for point array
+ as qh_distround * qh_JOGGLEdefault
+
+ returns:
+ initial value for JOGGLEmax from points and REALepsilon
+
+ notes:
+ computes DISTround since qh_maxmin not called yet
+ if qh->SCALElast, last dimension will be scaled later to MAXwidth
+
+ loop duplicated from qh_maxmin
+*/
+realT qh_detjoggle(qhT *qh, pointT *points, int numpoints, int dimension) {
+ realT abscoord, distround, joggle, maxcoord, mincoord;
+ pointT *point, *pointtemp;
+ realT maxabs= -REALmax;
+ realT sumabs= 0;
+ realT maxwidth= 0;
+ int k;
+
+ for (k=0; k < dimension; k++) {
+ if (qh->SCALElast && k == dimension-1)
+ abscoord= maxwidth;
+ else if (qh->DELAUNAY && k == dimension-1) /* will qh_setdelaunay() */
+ abscoord= 2 * maxabs * maxabs; /* may be low by qh->hull_dim/2 */
+ else {
+ maxcoord= -REALmax;
+ mincoord= REALmax;
+ FORALLpoint_(qh, points, numpoints) {
+ maximize_(maxcoord, point[k]);
+ minimize_(mincoord, point[k]);
+ }
+ maximize_(maxwidth, maxcoord-mincoord);
+ abscoord= fmax_(maxcoord, -mincoord);
+ }
+ sumabs += abscoord;
+ maximize_(maxabs, abscoord);
+ } /* for k */
+ distround= qh_distround(qh, qh->hull_dim, maxabs, sumabs);
+ joggle= distround * qh_JOGGLEdefault;
+ maximize_(joggle, REALepsilon * qh_JOGGLEdefault);
+ trace2((qh, qh->ferr, 2001, "qh_detjoggle: joggle=%2.2g maxwidth=%2.2g\n", joggle, maxwidth));
+ return joggle;
+} /* detjoggle */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="detroundoff">-</a>
+
+ qh_detroundoff(qh)
+ determine maximum roundoff errors from
+ REALepsilon, REALmax, REALmin, qh.hull_dim, qh.MAXabs_coord,
+ qh.MAXsumcoord, qh.MAXwidth, qh.MINdenom_1
+
+ accounts for qh.SETroundoff, qh.RANDOMdist, qh->MERGEexact
+ qh.premerge_cos, qh.postmerge_cos, qh.premerge_centrum,
+ qh.postmerge_centrum, qh.MINoutside,
+ qh_RATIOnearinside, qh_COPLANARratio, qh_WIDEcoplanar
+
+ returns:
+ sets qh.DISTround, etc. (see below)
+ appends precision constants to qh.qhull_options
+
+ see:
+ qh_maxmin() for qh.NEARzero
+
+ design:
+ determine qh.DISTround for distance computations
+ determine minimum denominators for qh_divzero
+ determine qh.ANGLEround for angle computations
+ adjust qh.premerge_cos,... for roundoff error
+ determine qh.ONEmerge for maximum error due to a single merge
+ determine qh.NEARinside, qh.MAXcoplanar, qh.MINvisible,
+ qh.MINoutside, qh.WIDEfacet
+ initialize qh.max_vertex and qh.minvertex
+*/
+void qh_detroundoff(qhT *qh) {
+
+ qh_option(qh, "_max-width", NULL, &qh->MAXwidth);
+ if (!qh->SETroundoff) {
+ qh->DISTround= qh_distround(qh, qh->hull_dim, qh->MAXabs_coord, qh->MAXsumcoord);
+ if (qh->RANDOMdist)
+ qh->DISTround += qh->RANDOMfactor * qh->MAXabs_coord;
+ qh_option(qh, "Error-roundoff", NULL, &qh->DISTround);
+ }
+ qh->MINdenom= qh->MINdenom_1 * qh->MAXabs_coord;
+ qh->MINdenom_1_2= sqrt(qh->MINdenom_1 * qh->hull_dim) ; /* if will be normalized */
+ qh->MINdenom_2= qh->MINdenom_1_2 * qh->MAXabs_coord;
+ /* for inner product */
+ qh->ANGLEround= 1.01 * qh->hull_dim * REALepsilon;
+ if (qh->RANDOMdist)
+ qh->ANGLEround += qh->RANDOMfactor;
+ if (qh->premerge_cos < REALmax/2) {
+ qh->premerge_cos -= qh->ANGLEround;
+ if (qh->RANDOMdist)
+ qh_option(qh, "Angle-premerge-with-random", NULL, &qh->premerge_cos);
+ }
+ if (qh->postmerge_cos < REALmax/2) {
+ qh->postmerge_cos -= qh->ANGLEround;
+ if (qh->RANDOMdist)
+ qh_option(qh, "Angle-postmerge-with-random", NULL, &qh->postmerge_cos);
+ }
+ qh->premerge_centrum += 2 * qh->DISTround; /*2 for centrum and distplane()*/
+ qh->postmerge_centrum += 2 * qh->DISTround;
+ if (qh->RANDOMdist && (qh->MERGEexact || qh->PREmerge))
+ qh_option(qh, "Centrum-premerge-with-random", NULL, &qh->premerge_centrum);
+ if (qh->RANDOMdist && qh->POSTmerge)
+ qh_option(qh, "Centrum-postmerge-with-random", NULL, &qh->postmerge_centrum);
+ { /* compute ONEmerge, max vertex offset for merging simplicial facets */
+ realT maxangle= 1.0, maxrho;
+
+ minimize_(maxangle, qh->premerge_cos);
+ minimize_(maxangle, qh->postmerge_cos);
+ /* max diameter * sin theta + DISTround for vertex to its hyperplane */
+ qh->ONEmerge= sqrt((realT)qh->hull_dim) * qh->MAXwidth *
+ sqrt(1.0 - maxangle * maxangle) + qh->DISTround;
+ maxrho= qh->hull_dim * qh->premerge_centrum + qh->DISTround;
+ maximize_(qh->ONEmerge, maxrho);
+ maxrho= qh->hull_dim * qh->postmerge_centrum + qh->DISTround;
+ maximize_(qh->ONEmerge, maxrho);
+ if (qh->MERGING)
+ qh_option(qh, "_one-merge", NULL, &qh->ONEmerge);
+ }
+ qh->NEARinside= qh->ONEmerge * qh_RATIOnearinside; /* only used if qh->KEEPnearinside */
+ if (qh->JOGGLEmax < REALmax/2 && (qh->KEEPcoplanar || qh->KEEPinside)) {
+ realT maxdist; /* adjust qh.NEARinside for joggle */
+ qh->KEEPnearinside= True;
+ maxdist= sqrt((realT)qh->hull_dim) * qh->JOGGLEmax + qh->DISTround;
+ maxdist= 2*maxdist; /* vertex and coplanar point can joggle in opposite directions */
+ maximize_(qh->NEARinside, maxdist); /* must agree with qh_nearcoplanar() */
+ }
+ if (qh->KEEPnearinside)
+ qh_option(qh, "_near-inside", NULL, &qh->NEARinside);
+ if (qh->JOGGLEmax < qh->DISTround) {
+ qh_fprintf(qh, qh->ferr, 6006, "qhull error: the joggle for 'QJn', %.2g, is below roundoff for distance computations, %.2g\n",
+ qh->JOGGLEmax, qh->DISTround);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (qh->MINvisible > REALmax/2) {
+ if (!qh->MERGING)
+ qh->MINvisible= qh->DISTround;
+ else if (qh->hull_dim <= 3)
+ qh->MINvisible= qh->premerge_centrum;
+ else
+ qh->MINvisible= qh_COPLANARratio * qh->premerge_centrum;
+ if (qh->APPROXhull && qh->MINvisible > qh->MINoutside)
+ qh->MINvisible= qh->MINoutside;
+ qh_option(qh, "Visible-distance", NULL, &qh->MINvisible);
+ }
+ if (qh->MAXcoplanar > REALmax/2) {
+ qh->MAXcoplanar= qh->MINvisible;
+ qh_option(qh, "U-coplanar-distance", NULL, &qh->MAXcoplanar);
+ }
+ if (!qh->APPROXhull) { /* user may specify qh->MINoutside */
+ qh->MINoutside= 2 * qh->MINvisible;
+ if (qh->premerge_cos < REALmax/2)
+ maximize_(qh->MINoutside, (1- qh->premerge_cos) * qh->MAXabs_coord);
+ qh_option(qh, "Width-outside", NULL, &qh->MINoutside);
+ }
+ qh->WIDEfacet= qh->MINoutside;
+ maximize_(qh->WIDEfacet, qh_WIDEcoplanar * qh->MAXcoplanar);
+ maximize_(qh->WIDEfacet, qh_WIDEcoplanar * qh->MINvisible);
+ qh_option(qh, "_wide-facet", NULL, &qh->WIDEfacet);
+ if (qh->MINvisible > qh->MINoutside + 3 * REALepsilon
+ && !qh->BESToutside && !qh->FORCEoutput)
+ qh_fprintf(qh, qh->ferr, 7001, "qhull input warning: minimum visibility V%.2g is greater than \nminimum outside W%.2g. Flipped facets are likely.\n",
+ qh->MINvisible, qh->MINoutside);
+ qh->max_vertex= qh->DISTround;
+ qh->min_vertex= -qh->DISTround;
+ /* numeric constants reported in printsummary */
+} /* detroundoff */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="detsimplex">-</a>
+
+ qh_detsimplex(qh, apex, points, dim, nearzero )
+ compute determinant of a simplex with point apex and base points
+
+ returns:
+ signed determinant and nearzero from qh_determinant
+
+ notes:
+ uses qh.gm_matrix/qh.gm_row (assumes they're big enough)
+
+ design:
+ construct qm_matrix by subtracting apex from points
+ compute determinate
+*/
+realT qh_detsimplex(qhT *qh, pointT *apex, setT *points, int dim, boolT *nearzero) {
+ pointT *coorda, *coordp, *gmcoord, *point, **pointp;
+ coordT **rows;
+ int k, i=0;
+ realT det;
+
+ zinc_(Zdetsimplex);
+ gmcoord= qh->gm_matrix;
+ rows= qh->gm_row;
+ FOREACHpoint_(points) {
+ if (i == dim)
+ break;
+ rows[i++]= gmcoord;
+ coordp= point;
+ coorda= apex;
+ for (k=dim; k--; )
+ *(gmcoord++)= *coordp++ - *coorda++;
+ }
+ if (i < dim) {
+ qh_fprintf(qh, qh->ferr, 6007, "qhull internal error (qh_detsimplex): #points %d < dimension %d\n",
+ i, dim);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ det= qh_determinant(qh, rows, dim, nearzero);
+ trace2((qh, qh->ferr, 2002, "qh_detsimplex: det=%2.2g for point p%d, dim %d, nearzero? %d\n",
+ det, qh_pointid(qh, apex), dim, *nearzero));
+ return det;
+} /* detsimplex */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="distnorm">-</a>
+
+ qh_distnorm( dim, point, normal, offset )
+ return distance from point to hyperplane at normal/offset
+
+ returns:
+ dist
+
+ notes:
+ dist > 0 if point is outside of hyperplane
+
+ see:
+ qh_distplane in geom_r.c
+*/
+realT qh_distnorm(int dim, pointT *point, pointT *normal, realT *offsetp) {
+ coordT *normalp= normal, *coordp= point;
+ realT dist;
+ int k;
+
+ dist= *offsetp;
+ for (k=dim; k--; )
+ dist += *(coordp++) * *(normalp++);
+ return dist;
+} /* distnorm */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="distround">-</a>
+
+ qh_distround(qh, dimension, maxabs, maxsumabs )
+ compute maximum round-off error for a distance computation
+ to a normalized hyperplane
+ maxabs is the maximum absolute value of a coordinate
+ maxsumabs is the maximum possible sum of absolute coordinate values
+
+ returns:
+ max dist round for REALepsilon
+
+ notes:
+ calculate roundoff error according to Golub & van Loan, 1983, Lemma 3.2-1, "Rounding Errors"
+ use sqrt(dim) since one vector is normalized
+ or use maxsumabs since one vector is < 1
+*/
+realT qh_distround(qhT *qh, int dimension, realT maxabs, realT maxsumabs) {
+ realT maxdistsum, maxround;
+
+ maxdistsum= sqrt((realT)dimension) * maxabs;
+ minimize_( maxdistsum, maxsumabs);
+ maxround= REALepsilon * (dimension * maxdistsum * 1.01 + maxabs);
+ /* adds maxabs for offset */
+ trace4((qh, qh->ferr, 4008, "qh_distround: %2.2g maxabs %2.2g maxsumabs %2.2g maxdistsum %2.2g\n",
+ maxround, maxabs, maxsumabs, maxdistsum));
+ return maxround;
+} /* distround */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="divzero">-</a>
+
+ qh_divzero( numer, denom, mindenom1, zerodiv )
+ divide by a number that's nearly zero
+ mindenom1= minimum denominator for dividing into 1.0
+
+ returns:
+ quotient
+ sets zerodiv and returns 0.0 if it would overflow
+
+ design:
+ if numer is nearly zero and abs(numer) < abs(denom)
+ return numer/denom
+ else if numer is nearly zero
+ return 0 and zerodiv
+ else if denom/numer non-zero
+ return numer/denom
+ else
+ return 0 and zerodiv
+*/
+realT qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv) {
+ realT temp, numerx, denomx;
+
+
+ if (numer < mindenom1 && numer > -mindenom1) {
+ numerx= fabs_(numer);
+ denomx= fabs_(denom);
+ if (numerx < denomx) {
+ *zerodiv= False;
+ return numer/denom;
+ }else {
+ *zerodiv= True;
+ return 0.0;
+ }
+ }
+ temp= denom/numer;
+ if (temp > mindenom1 || temp < -mindenom1) {
+ *zerodiv= False;
+ return numer/denom;
+ }else {
+ *zerodiv= True;
+ return 0.0;
+ }
+} /* divzero */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="facetarea">-</a>
+
+ qh_facetarea(qh, facet )
+ return area for a facet
+
+ notes:
+ if non-simplicial,
+ uses centrum to triangulate facet and sums the projected areas.
+ if (qh->DELAUNAY),
+ computes projected area instead for last coordinate
+ assumes facet->normal exists
+ projecting tricoplanar facets to the hyperplane does not appear to make a difference
+
+ design:
+ if simplicial
+ compute area
+ else
+ for each ridge
+ compute area from centrum to ridge
+ negate area if upper Delaunay facet
+*/
+realT qh_facetarea(qhT *qh, facetT *facet) {
+ vertexT *apex;
+ pointT *centrum;
+ realT area= 0.0;
+ ridgeT *ridge, **ridgep;
+
+ if (facet->simplicial) {
+ apex= SETfirstt_(facet->vertices, vertexT);
+ area= qh_facetarea_simplex(qh, qh->hull_dim, apex->point, facet->vertices,
+ apex, facet->toporient, facet->normal, &facet->offset);
+ }else {
+ if (qh->CENTERtype == qh_AScentrum)
+ centrum= facet->center;
+ else
+ centrum= qh_getcentrum(qh, facet);
+ FOREACHridge_(facet->ridges)
+ area += qh_facetarea_simplex(qh, qh->hull_dim, centrum, ridge->vertices,
+ NULL, (boolT)(ridge->top == facet), facet->normal, &facet->offset);
+ if (qh->CENTERtype != qh_AScentrum)
+ qh_memfree(qh, centrum, qh->normal_size);
+ }
+ if (facet->upperdelaunay && qh->DELAUNAY)
+ area= -area; /* the normal should be [0,...,1] */
+ trace4((qh, qh->ferr, 4009, "qh_facetarea: f%d area %2.2g\n", facet->id, area));
+ return area;
+} /* facetarea */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="facetarea_simplex">-</a>
+
+ qh_facetarea_simplex(qh, dim, apex, vertices, notvertex, toporient, normal, offset )
+ return area for a simplex defined by
+ an apex, a base of vertices, an orientation, and a unit normal
+ if simplicial or tricoplanar facet,
+ notvertex is defined and it is skipped in vertices
+
+ returns:
+ computes area of simplex projected to plane [normal,offset]
+ returns 0 if vertex too far below plane (qh->WIDEfacet)
+ vertex can't be apex of tricoplanar facet
+
+ notes:
+ if (qh->DELAUNAY),
+ computes projected area instead for last coordinate
+ uses qh->gm_matrix/gm_row and qh->hull_dim
+ helper function for qh_facetarea
+
+ design:
+ if Notvertex
+ translate simplex to apex
+ else
+ project simplex to normal/offset
+ translate simplex to apex
+ if Delaunay
+ set last row/column to 0 with -1 on diagonal
+ else
+ set last row to Normal
+ compute determinate
+ scale and flip sign for area
+*/
+realT qh_facetarea_simplex(qhT *qh, int dim, coordT *apex, setT *vertices,
+ vertexT *notvertex, boolT toporient, coordT *normal, realT *offset) {
+ pointT *coorda, *coordp, *gmcoord;
+ coordT **rows, *normalp;
+ int k, i=0;
+ realT area, dist;
+ vertexT *vertex, **vertexp;
+ boolT nearzero;
+
+ gmcoord= qh->gm_matrix;
+ rows= qh->gm_row;
+ FOREACHvertex_(vertices) {
+ if (vertex == notvertex)
+ continue;
+ rows[i++]= gmcoord;
+ coorda= apex;
+ coordp= vertex->point;
+ normalp= normal;
+ if (notvertex) {
+ for (k=dim; k--; )
+ *(gmcoord++)= *coordp++ - *coorda++;
+ }else {
+ dist= *offset;
+ for (k=dim; k--; )
+ dist += *coordp++ * *normalp++;
+ if (dist < -qh->WIDEfacet) {
+ zinc_(Znoarea);
+ return 0.0;
+ }
+ coordp= vertex->point;
+ normalp= normal;
+ for (k=dim; k--; )
+ *(gmcoord++)= (*coordp++ - dist * *normalp++) - *coorda++;
+ }
+ }
+ if (i != dim-1) {
+ qh_fprintf(qh, qh->ferr, 6008, "qhull internal error (qh_facetarea_simplex): #points %d != dim %d -1\n",
+ i, dim);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ rows[i]= gmcoord;
+ if (qh->DELAUNAY) {
+ for (i=0; i < dim-1; i++)
+ rows[i][dim-1]= 0.0;
+ for (k=dim; k--; )
+ *(gmcoord++)= 0.0;
+ rows[dim-1][dim-1]= -1.0;
+ }else {
+ normalp= normal;
+ for (k=dim; k--; )
+ *(gmcoord++)= *normalp++;
+ }
+ zinc_(Zdetsimplex);
+ area= qh_determinant(qh, rows, dim, &nearzero);
+ if (toporient)
+ area= -area;
+ area *= qh->AREAfactor;
+ trace4((qh, qh->ferr, 4010, "qh_facetarea_simplex: area=%2.2g for point p%d, toporient %d, nearzero? %d\n",
+ area, qh_pointid(qh, apex), toporient, nearzero));
+ return area;
+} /* facetarea_simplex */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="facetcenter">-</a>
+
+ qh_facetcenter(qh, vertices )
+ return Voronoi center (Voronoi vertex) for a facet's vertices
+
+ returns:
+ return temporary point equal to the center
+
+ see:
+ qh_voronoi_center()
+*/
+pointT *qh_facetcenter(qhT *qh, setT *vertices) {
+ setT *points= qh_settemp(qh, qh_setsize(qh, vertices));
+ vertexT *vertex, **vertexp;
+ pointT *center;
+
+ FOREACHvertex_(vertices)
+ qh_setappend(qh, &points, vertex->point);
+ center= qh_voronoi_center(qh, qh->hull_dim-1, points);
+ qh_settempfree(qh, &points);
+ return center;
+} /* facetcenter */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="findgooddist">-</a>
+
+ qh_findgooddist(qh, point, facetA, dist, facetlist )
+ find best good facet visible for point from facetA
+ assumes facetA is visible from point
+
+ returns:
+ best facet, i.e., good facet that is furthest from point
+ distance to best facet
+ NULL if none
+
+ moves good, visible facets (and some other visible facets)
+ to end of qh->facet_list
+
+ notes:
+ uses qh->visit_id
+
+ design:
+ initialize bestfacet if facetA is good
+ move facetA to end of facetlist
+ for each facet on facetlist
+ for each unvisited neighbor of facet
+ move visible neighbors to end of facetlist
+ update best good neighbor
+ if no good neighbors, update best facet
+*/
+facetT *qh_findgooddist(qhT *qh, pointT *point, facetT *facetA, realT *distp,
+ facetT **facetlist) {
+ realT bestdist= -REALmax, dist;
+ facetT *neighbor, **neighborp, *bestfacet=NULL, *facet;
+ boolT goodseen= False;
+
+ if (facetA->good) {
+ zzinc_(Zcheckpart); /* calls from check_bestdist occur after print stats */
+ qh_distplane(qh, point, facetA, &bestdist);
+ bestfacet= facetA;
+ goodseen= True;
+ }
+ qh_removefacet(qh, facetA);
+ qh_appendfacet(qh, facetA);
+ *facetlist= facetA;
+ facetA->visitid= ++qh->visit_id;
+ FORALLfacet_(*facetlist) {
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid == qh->visit_id)
+ continue;
+ neighbor->visitid= qh->visit_id;
+ if (goodseen && !neighbor->good)
+ continue;
+ zzinc_(Zcheckpart);
+ qh_distplane(qh, point, neighbor, &dist);
+ if (dist > 0) {
+ qh_removefacet(qh, neighbor);
+ qh_appendfacet(qh, neighbor);
+ if (neighbor->good) {
+ goodseen= True;
+ if (dist > bestdist) {
+ bestdist= dist;
+ bestfacet= neighbor;
+ }
+ }
+ }
+ }
+ }
+ if (bestfacet) {
+ *distp= bestdist;
+ trace2((qh, qh->ferr, 2003, "qh_findgooddist: p%d is %2.2g above good facet f%d\n",
+ qh_pointid(qh, point), bestdist, bestfacet->id));
+ return bestfacet;
+ }
+ trace4((qh, qh->ferr, 4011, "qh_findgooddist: no good facet for p%d above f%d\n",
+ qh_pointid(qh, point), facetA->id));
+ return NULL;
+} /* findgooddist */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="getarea">-</a>
+
+ qh_getarea(qh, facetlist )
+ set area of all facets in facetlist
+ collect statistics
+ nop if hasAreaVolume
+
+ returns:
+ sets qh->totarea/totvol to total area and volume of convex hull
+ for Delaunay triangulation, computes projected area of the lower or upper hull
+ ignores upper hull if qh->ATinfinity
+
+ notes:
+ could compute outer volume by expanding facet area by rays from interior
+ the following attempt at perpendicular projection underestimated badly:
+ qh.totoutvol += (-dist + facet->maxoutside + qh->DISTround)
+ * area/ qh->hull_dim;
+ design:
+ for each facet on facetlist
+ compute facet->area
+ update qh.totarea and qh.totvol
+*/
+void qh_getarea(qhT *qh, facetT *facetlist) {
+ realT area;
+ realT dist;
+ facetT *facet;
+
+ if (qh->hasAreaVolume)
+ return;
+ if (qh->REPORTfreq)
+ qh_fprintf(qh, qh->ferr, 8020, "computing area of each facet and volume of the convex hull\n");
+ else
+ trace1((qh, qh->ferr, 1001, "qh_getarea: computing volume and area for each facet\n"));
+ qh->totarea= qh->totvol= 0.0;
+ FORALLfacet_(facetlist) {
+ if (!facet->normal)
+ continue;
+ if (facet->upperdelaunay && qh->ATinfinity)
+ continue;
+ if (!facet->isarea) {
+ facet->f.area= qh_facetarea(qh, facet);
+ facet->isarea= True;
+ }
+ area= facet->f.area;
+ if (qh->DELAUNAY) {
+ if (facet->upperdelaunay == qh->UPPERdelaunay)
+ qh->totarea += area;
+ }else {
+ qh->totarea += area;
+ qh_distplane(qh, qh->interior_point, facet, &dist);
+ qh->totvol += -dist * area/ qh->hull_dim;
+ }
+ if (qh->PRINTstatistics) {
+ wadd_(Wareatot, area);
+ wmax_(Wareamax, area);
+ wmin_(Wareamin, area);
+ }
+ }
+ qh->hasAreaVolume= True;
+} /* getarea */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="gram_schmidt">-</a>
+
+ qh_gram_schmidt(qh, dim, row )
+ implements Gram-Schmidt orthogonalization by rows
+
+ returns:
+ false if zero norm
+ overwrites rows[dim][dim]
+
+ notes:
+ see Golub & van Loan, 1983, Algorithm 6.2-2, "Modified Gram-Schmidt"
+ overflow due to small divisors not handled
+
+ design:
+ for each row
+ compute norm for row
+ if non-zero, normalize row
+ for each remaining rowA
+ compute inner product of row and rowA
+ reduce rowA by row * inner product
+*/
+boolT qh_gram_schmidt(qhT *qh, int dim, realT **row) {
+ realT *rowi, *rowj, norm;
+ int i, j, k;
+
+ for (i=0; i < dim; i++) {
+ rowi= row[i];
+ for (norm= 0.0, k= dim; k--; rowi++)
+ norm += *rowi * *rowi;
+ norm= sqrt(norm);
+ wmin_(Wmindenom, norm);
+ if (norm == 0.0) /* either 0 or overflow due to sqrt */
+ return False;
+ for (k=dim; k--; )
+ *(--rowi) /= norm;
+ for (j=i+1; j < dim; j++) {
+ rowj= row[j];
+ for (norm= 0.0, k=dim; k--; )
+ norm += *rowi++ * *rowj++;
+ for (k=dim; k--; )
+ *(--rowj) -= *(--rowi) * norm;
+ }
+ }
+ return True;
+} /* gram_schmidt */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="inthresholds">-</a>
+
+ qh_inthresholds(qh, normal, angle )
+ return True if normal within qh.lower_/upper_threshold
+
+ returns:
+ estimate of angle by summing of threshold diffs
+ angle may be NULL
+ smaller "angle" is better
+
+ notes:
+ invalid if qh.SPLITthresholds
+
+ see:
+ qh.lower_threshold in qh_initbuild()
+ qh_initthresholds()
+
+ design:
+ for each dimension
+ test threshold
+*/
+boolT qh_inthresholds(qhT *qh, coordT *normal, realT *angle) {
+ boolT within= True;
+ int k;
+ realT threshold;
+
+ if (angle)
+ *angle= 0.0;
+ for (k=0; k < qh->hull_dim; k++) {
+ threshold= qh->lower_threshold[k];
+ if (threshold > -REALmax/2) {
+ if (normal[k] < threshold)
+ within= False;
+ if (angle) {
+ threshold -= normal[k];
+ *angle += fabs_(threshold);
+ }
+ }
+ if (qh->upper_threshold[k] < REALmax/2) {
+ threshold= qh->upper_threshold[k];
+ if (normal[k] > threshold)
+ within= False;
+ if (angle) {
+ threshold -= normal[k];
+ *angle += fabs_(threshold);
+ }
+ }
+ }
+ return within;
+} /* inthresholds */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="joggleinput">-</a>
+
+ qh_joggleinput(qh)
+ randomly joggle input to Qhull by qh.JOGGLEmax
+ initial input is qh.first_point/qh.num_points of qh.hull_dim
+ repeated calls use qh.input_points/qh.num_points
+
+ returns:
+ joggles points at qh.first_point/qh.num_points
+ copies data to qh.input_points/qh.input_malloc if first time
+ determines qh.JOGGLEmax if it was zero
+ if qh.DELAUNAY
+ computes the Delaunay projection of the joggled points
+
+ notes:
+ if qh.DELAUNAY, unnecessarily joggles the last coordinate
+ the initial 'QJn' may be set larger than qh_JOGGLEmaxincrease
+
+ design:
+ if qh.DELAUNAY
+ set qh.SCALElast for reduced precision errors
+ if first call
+ initialize qh.input_points to the original input points
+ if qh.JOGGLEmax == 0
+ determine default qh.JOGGLEmax
+ else
+ increase qh.JOGGLEmax according to qh.build_cnt
+ joggle the input by adding a random number in [-qh.JOGGLEmax,qh.JOGGLEmax]
+ if qh.DELAUNAY
+ sets the Delaunay projection
+*/
+void qh_joggleinput(qhT *qh) {
+ int i, seed, size;
+ coordT *coordp, *inputp;
+ realT randr, randa, randb;
+
+ if (!qh->input_points) { /* first call */
+ qh->input_points= qh->first_point;
+ qh->input_malloc= qh->POINTSmalloc;
+ size= qh->num_points * qh->hull_dim * sizeof(coordT);
+ if (!(qh->first_point=(coordT*)qh_malloc((size_t)size))) {
+ qh_fprintf(qh, qh->ferr, 6009, "qhull error: insufficient memory to joggle %d points\n",
+ qh->num_points);
+ qh_errexit(qh, qh_ERRmem, NULL, NULL);
+ }
+ qh->POINTSmalloc= True;
+ if (qh->JOGGLEmax == 0.0) {
+ qh->JOGGLEmax= qh_detjoggle(qh, qh->input_points, qh->num_points, qh->hull_dim);
+ qh_option(qh, "QJoggle", NULL, &qh->JOGGLEmax);
+ }
+ }else { /* repeated call */
+ if (!qh->RERUN && qh->build_cnt > qh_JOGGLEretry) {
+ if (((qh->build_cnt-qh_JOGGLEretry-1) % qh_JOGGLEagain) == 0) {
+ realT maxjoggle= qh->MAXwidth * qh_JOGGLEmaxincrease;
+ if (qh->JOGGLEmax < maxjoggle) {
+ qh->JOGGLEmax *= qh_JOGGLEincrease;
+ minimize_(qh->JOGGLEmax, maxjoggle);
+ }
+ }
+ }
+ qh_option(qh, "QJoggle", NULL, &qh->JOGGLEmax);
+ }
+ if (qh->build_cnt > 1 && qh->JOGGLEmax > fmax_(qh->MAXwidth/4, 0.1)) {
+ qh_fprintf(qh, qh->ferr, 6010, "qhull error: the current joggle for 'QJn', %.2g, is too large for the width\nof the input. If possible, recompile Qhull with higher-precision reals.\n",
+ qh->JOGGLEmax);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ /* for some reason, using qh->ROTATErandom and qh_RANDOMseed does not repeat the run. Use 'TRn' instead */
+ seed= qh_RANDOMint;
+ qh_option(qh, "_joggle-seed", &seed, NULL);
+ trace0((qh, qh->ferr, 6, "qh_joggleinput: joggle input by %2.2g with seed %d\n",
+ qh->JOGGLEmax, seed));
+ inputp= qh->input_points;
+ coordp= qh->first_point;
+ randa= 2.0 * qh->JOGGLEmax/qh_RANDOMmax;
+ randb= -qh->JOGGLEmax;
+ size= qh->num_points * qh->hull_dim;
+ for (i=size; i--; ) {
+ randr= qh_RANDOMint;
+ *(coordp++)= *(inputp++) + (randr * randa + randb);
+ }
+ if (qh->DELAUNAY) {
+ qh->last_low= qh->last_high= qh->last_newhigh= REALmax;
+ qh_setdelaunay(qh, qh->hull_dim, qh->num_points, qh->first_point);
+ }
+} /* joggleinput */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="maxabsval">-</a>
+
+ qh_maxabsval( normal, dim )
+ return pointer to maximum absolute value of a dim vector
+ returns NULL if dim=0
+*/
+realT *qh_maxabsval(realT *normal, int dim) {
+ realT maxval= -REALmax;
+ realT *maxp= NULL, *colp, absval;
+ int k;
+
+ for (k=dim, colp= normal; k--; colp++) {
+ absval= fabs_(*colp);
+ if (absval > maxval) {
+ maxval= absval;
+ maxp= colp;
+ }
+ }
+ return maxp;
+} /* maxabsval */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="maxmin">-</a>
+
+ qh_maxmin(qh, points, numpoints, dimension )
+ return max/min points for each dimension
+ determine max and min coordinates
+
+ returns:
+ returns a temporary set of max and min points
+ may include duplicate points. Does not include qh.GOODpoint
+ sets qh.NEARzero, qh.MAXabs_coord, qh.MAXsumcoord, qh.MAXwidth
+ qh.MAXlastcoord, qh.MINlastcoord
+ initializes qh.max_outside, qh.min_vertex, qh.WAScoplanar, qh.ZEROall_ok
+
+ notes:
+ loop duplicated in qh_detjoggle()
+
+ design:
+ initialize global precision variables
+ checks definition of REAL...
+ for each dimension
+ for each point
+ collect maximum and minimum point
+ collect maximum of maximums and minimum of minimums
+ determine qh.NEARzero for Gaussian Elimination
+*/
+setT *qh_maxmin(qhT *qh, pointT *points, int numpoints, int dimension) {
+ int k;
+ realT maxcoord, temp;
+ pointT *minimum, *maximum, *point, *pointtemp;
+ setT *set;
+
+ qh->max_outside= 0.0;
+ qh->MAXabs_coord= 0.0;
+ qh->MAXwidth= -REALmax;
+ qh->MAXsumcoord= 0.0;
+ qh->min_vertex= 0.0;
+ qh->WAScoplanar= False;
+ if (qh->ZEROcentrum)
+ qh->ZEROall_ok= True;
+ if (REALmin < REALepsilon && REALmin < REALmax && REALmin > -REALmax
+ && REALmax > 0.0 && -REALmax < 0.0)
+ ; /* all ok */
+ else {
+ qh_fprintf(qh, qh->ferr, 6011, "qhull error: floating point constants in user.h are wrong\n\
+REALepsilon %g REALmin %g REALmax %g -REALmax %g\n",
+ REALepsilon, REALmin, REALmax, -REALmax);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ set= qh_settemp(qh, 2*dimension);
+ for (k=0; k < dimension; k++) {
+ if (points == qh->GOODpointp)
+ minimum= maximum= points + dimension;
+ else
+ minimum= maximum= points;
+ FORALLpoint_(qh, points, numpoints) {
+ if (point == qh->GOODpointp)
+ continue;
+ if (maximum[k] < point[k])
+ maximum= point;
+ else if (minimum[k] > point[k])
+ minimum= point;
+ }
+ if (k == dimension-1) {
+ qh->MINlastcoord= minimum[k];
+ qh->MAXlastcoord= maximum[k];
+ }
+ if (qh->SCALElast && k == dimension-1)
+ maxcoord= qh->MAXwidth;
+ else {
+ maxcoord= fmax_(maximum[k], -minimum[k]);
+ if (qh->GOODpointp) {
+ temp= fmax_(qh->GOODpointp[k], -qh->GOODpointp[k]);
+ maximize_(maxcoord, temp);
+ }
+ temp= maximum[k] - minimum[k];
+ maximize_(qh->MAXwidth, temp);
+ }
+ maximize_(qh->MAXabs_coord, maxcoord);
+ qh->MAXsumcoord += maxcoord;
+ qh_setappend(qh, &set, maximum);
+ qh_setappend(qh, &set, minimum);
+ /* calculation of qh NEARzero is based on Golub & van Loan, 1983,
+ Eq. 4.4-13 for "Gaussian elimination with complete pivoting".
+ Golub & van Loan say that n^3 can be ignored and 10 be used in
+ place of rho */
+ qh->NEARzero[k]= 80 * qh->MAXsumcoord * REALepsilon;
+ }
+ if (qh->IStracing >=1)
+ qh_printpoints(qh, qh->ferr, "qh_maxmin: found the max and min points(by dim):", set);
+ return(set);
+} /* maxmin */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="maxouter">-</a>
+
+ qh_maxouter(qh)
+ return maximum distance from facet to outer plane
+ normally this is qh.max_outside+qh.DISTround
+ does not include qh.JOGGLEmax
+
+ see:
+ qh_outerinner()
+
+ notes:
+ need to add another qh.DISTround if testing actual point with computation
+
+ for joggle:
+ qh_setfacetplane() updated qh.max_outer for Wnewvertexmax (max distance to vertex)
+ need to use Wnewvertexmax since could have a coplanar point for a high
+ facet that is replaced by a low facet
+ need to add qh.JOGGLEmax if testing input points
+*/
+realT qh_maxouter(qhT *qh) {
+ realT dist;
+
+ dist= fmax_(qh->max_outside, qh->DISTround);
+ dist += qh->DISTround;
+ trace4((qh, qh->ferr, 4012, "qh_maxouter: max distance from facet to outer plane is %2.2g max_outside is %2.2g\n", dist, qh->max_outside));
+ return dist;
+} /* maxouter */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="maxsimplex">-</a>
+
+ qh_maxsimplex(qh, dim, maxpoints, points, numpoints, simplex )
+ determines maximum simplex for a set of points
+ starts from points already in simplex
+ skips qh.GOODpointp (assumes that it isn't in maxpoints)
+
+ returns:
+ simplex with dim+1 points
+
+ notes:
+ assumes at least pointsneeded points in points
+ maximizes determinate for x,y,z,w, etc.
+ uses maxpoints as long as determinate is clearly non-zero
+
+ design:
+ initialize simplex with at least two points
+ (find points with max or min x coordinate)
+ for each remaining dimension
+ add point that maximizes the determinate
+ (use points from maxpoints first)
+*/
+void qh_maxsimplex(qhT *qh, int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex) {
+ pointT *point, **pointp, *pointtemp, *maxpoint, *minx=NULL, *maxx=NULL;
+ boolT nearzero, maxnearzero= False;
+ int k, sizinit;
+ realT maxdet= -REALmax, det, mincoord= REALmax, maxcoord= -REALmax;
+
+ sizinit= qh_setsize(qh, *simplex);
+ if (sizinit < 2) {
+ if (qh_setsize(qh, maxpoints) >= 2) {
+ FOREACHpoint_(maxpoints) {
+ if (maxcoord < point[0]) {
+ maxcoord= point[0];
+ maxx= point;
+ }
+ if (mincoord > point[0]) {
+ mincoord= point[0];
+ minx= point;
+ }
+ }
+ }else {
+ FORALLpoint_(qh, points, numpoints) {
+ if (point == qh->GOODpointp)
+ continue;
+ if (maxcoord < point[0]) {
+ maxcoord= point[0];
+ maxx= point;
+ }
+ if (mincoord > point[0]) {
+ mincoord= point[0];
+ minx= point;
+ }
+ }
+ }
+ qh_setunique(qh, simplex, minx);
+ if (qh_setsize(qh, *simplex) < 2)
+ qh_setunique(qh, simplex, maxx);
+ sizinit= qh_setsize(qh, *simplex);
+ if (sizinit < 2) {
+ qh_precision(qh, "input has same x coordinate");
+ if (zzval_(Zsetplane) > qh->hull_dim+1) {
+ qh_fprintf(qh, qh->ferr, 6012, "qhull precision error (qh_maxsimplex for voronoi_center):\n%d points with the same x coordinate.\n",
+ qh_setsize(qh, maxpoints)+numpoints);
+ qh_errexit(qh, qh_ERRprec, NULL, NULL);
+ }else {
+ qh_fprintf(qh, qh->ferr, 6013, "qhull input error: input is less than %d-dimensional since it has the same x coordinate\n", qh->hull_dim);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ }
+ }
+ for (k=sizinit; k < dim+1; k++) {
+ maxpoint= NULL;
+ maxdet= -REALmax;
+ FOREACHpoint_(maxpoints) {
+ if (!qh_setin(*simplex, point)) {
+ det= qh_detsimplex(qh, point, *simplex, k, &nearzero);
+ if ((det= fabs_(det)) > maxdet) {
+ maxdet= det;
+ maxpoint= point;
+ maxnearzero= nearzero;
+ }
+ }
+ }
+ if (!maxpoint || maxnearzero) {
+ zinc_(Zsearchpoints);
+ if (!maxpoint) {
+ trace0((qh, qh->ferr, 7, "qh_maxsimplex: searching all points for %d-th initial vertex.\n", k+1));
+ }else {
+ trace0((qh, qh->ferr, 8, "qh_maxsimplex: searching all points for %d-th initial vertex, better than p%d det %2.2g\n",
+ k+1, qh_pointid(qh, maxpoint), maxdet));
+ }
+ FORALLpoint_(qh, points, numpoints) {
+ if (point == qh->GOODpointp)
+ continue;
+ if (!qh_setin(*simplex, point)) {
+ det= qh_detsimplex(qh, point, *simplex, k, &nearzero);
+ if ((det= fabs_(det)) > maxdet) {
+ maxdet= det;
+ maxpoint= point;
+ maxnearzero= nearzero;
+ }
+ }
+ }
+ } /* !maxpoint */
+ if (!maxpoint) {
+ qh_fprintf(qh, qh->ferr, 6014, "qhull internal error (qh_maxsimplex): not enough points available\n");
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ qh_setappend(qh, simplex, maxpoint);
+ trace1((qh, qh->ferr, 1002, "qh_maxsimplex: selected point p%d for %d`th initial vertex, det=%2.2g\n",
+ qh_pointid(qh, maxpoint), k+1, maxdet));
+ } /* k */
+} /* maxsimplex */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="minabsval">-</a>
+
+ qh_minabsval( normal, dim )
+ return minimum absolute value of a dim vector
+*/
+realT qh_minabsval(realT *normal, int dim) {
+ realT minval= 0;
+ realT maxval= 0;
+ realT *colp;
+ int k;
+
+ for (k=dim, colp=normal; k--; colp++) {
+ maximize_(maxval, *colp);
+ minimize_(minval, *colp);
+ }
+ return fmax_(maxval, -minval);
+} /* minabsval */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="mindiff">-</a>
+
+ qh_mindif(qh, vecA, vecB, dim )
+ return index of min abs. difference of two vectors
+*/
+int qh_mindiff(realT *vecA, realT *vecB, int dim) {
+ realT mindiff= REALmax, diff;
+ realT *vecAp= vecA, *vecBp= vecB;
+ int k, mink= 0;
+
+ for (k=0; k < dim; k++) {
+ diff= *vecAp++ - *vecBp++;
+ diff= fabs_(diff);
+ if (diff < mindiff) {
+ mindiff= diff;
+ mink= k;
+ }
+ }
+ return mink;
+} /* mindiff */
+
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="orientoutside">-</a>
+
+ qh_orientoutside(qh, facet )
+ make facet outside oriented via qh.interior_point
+
+ returns:
+ True if facet reversed orientation.
+*/
+boolT qh_orientoutside(qhT *qh, facetT *facet) {
+ int k;
+ realT dist;
+
+ qh_distplane(qh, qh->interior_point, facet, &dist);
+ if (dist > 0) {
+ for (k=qh->hull_dim; k--; )
+ facet->normal[k]= -facet->normal[k];
+ facet->offset= -facet->offset;
+ return True;
+ }
+ return False;
+} /* orientoutside */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="outerinner">-</a>
+
+ qh_outerinner(qh, facet, outerplane, innerplane )
+ if facet and qh.maxoutdone (i.e., qh_check_maxout)
+ returns outer and inner plane for facet
+ else
+ returns maximum outer and inner plane
+ accounts for qh.JOGGLEmax
+
+ see:
+ qh_maxouter(qh), qh_check_bestdist(), qh_check_points()
+
+ notes:
+ outerplaner or innerplane may be NULL
+ facet is const
+ Does not error (QhullFacet)
+
+ includes qh.DISTround for actual points
+ adds another qh.DISTround if testing with floating point arithmetic
+*/
+void qh_outerinner(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane) {
+ realT dist, mindist;
+ vertexT *vertex, **vertexp;
+
+ if (outerplane) {
+ if (!qh_MAXoutside || !facet || !qh->maxoutdone) {
+ *outerplane= qh_maxouter(qh); /* includes qh.DISTround */
+ }else { /* qh_MAXoutside ... */
+#if qh_MAXoutside
+ *outerplane= facet->maxoutside + qh->DISTround;
+#endif
+
+ }
+ if (qh->JOGGLEmax < REALmax/2)
+ *outerplane += qh->JOGGLEmax * sqrt((realT)qh->hull_dim);
+ }
+ if (innerplane) {
+ if (facet) {
+ mindist= REALmax;
+ FOREACHvertex_(facet->vertices) {
+ zinc_(Zdistio);
+ qh_distplane(qh, vertex->point, facet, &dist);
+ minimize_(mindist, dist);
+ }
+ *innerplane= mindist - qh->DISTround;
+ }else
+ *innerplane= qh->min_vertex - qh->DISTround;
+ if (qh->JOGGLEmax < REALmax/2)
+ *innerplane -= qh->JOGGLEmax * sqrt((realT)qh->hull_dim);
+ }
+} /* outerinner */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="pointdist">-</a>
+
+ qh_pointdist( point1, point2, dim )
+ return distance between two points
+
+ notes:
+ returns distance squared if 'dim' is negative
+*/
+coordT qh_pointdist(pointT *point1, pointT *point2, int dim) {
+ coordT dist, diff;
+ int k;
+
+ dist= 0.0;
+ for (k= (dim > 0 ? dim : -dim); k--; ) {
+ diff= *point1++ - *point2++;
+ dist += diff * diff;
+ }
+ if (dim > 0)
+ return(sqrt(dist));
+ return dist;
+} /* pointdist */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="printmatrix">-</a>
+
+ qh_printmatrix(qh, fp, string, rows, numrow, numcol )
+ print matrix to fp given by row vectors
+ print string as header
+ qh may be NULL if fp is defined
+
+ notes:
+ print a vector by qh_printmatrix(qh, fp, "", &vect, 1, len)
+*/
+void qh_printmatrix(qhT *qh, FILE *fp, const char *string, realT **rows, int numrow, int numcol) {
+ realT *rowp;
+ realT r; /*bug fix*/
+ int i,k;
+
+ qh_fprintf(qh, fp, 9001, "%s\n", string);
+ for (i=0; i < numrow; i++) {
+ rowp= rows[i];
+ for (k=0; k < numcol; k++) {
+ r= *rowp++;
+ qh_fprintf(qh, fp, 9002, "%6.3g ", r);
+ }
+ qh_fprintf(qh, fp, 9003, "\n");
+ }
+} /* printmatrix */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="printpoints">-</a>
+
+ qh_printpoints(qh, fp, string, points )
+ print pointids to fp for a set of points
+ if string, prints string and 'p' point ids
+*/
+void qh_printpoints(qhT *qh, FILE *fp, const char *string, setT *points) {
+ pointT *point, **pointp;
+
+ if (string) {
+ qh_fprintf(qh, fp, 9004, "%s", string);
+ FOREACHpoint_(points)
+ qh_fprintf(qh, fp, 9005, " p%d", qh_pointid(qh, point));
+ qh_fprintf(qh, fp, 9006, "\n");
+ }else {
+ FOREACHpoint_(points)
+ qh_fprintf(qh, fp, 9007, " %d", qh_pointid(qh, point));
+ qh_fprintf(qh, fp, 9008, "\n");
+ }
+} /* printpoints */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="projectinput">-</a>
+
+ qh_projectinput(qh)
+ project input points using qh.lower_bound/upper_bound and qh->DELAUNAY
+ if qh.lower_bound[k]=qh.upper_bound[k]= 0,
+ removes dimension k
+ if halfspace intersection
+ removes dimension k from qh.feasible_point
+ input points in qh->first_point, num_points, input_dim
+
+ returns:
+ new point array in qh->first_point of qh->hull_dim coordinates
+ sets qh->POINTSmalloc
+ if qh->DELAUNAY
+ projects points to paraboloid
+ lowbound/highbound is also projected
+ if qh->ATinfinity
+ adds point "at-infinity"
+ if qh->POINTSmalloc
+ frees old point array
+
+ notes:
+ checks that qh.hull_dim agrees with qh.input_dim, PROJECTinput, and DELAUNAY
+
+
+ design:
+ sets project[k] to -1 (delete), 0 (keep), 1 (add for Delaunay)
+ determines newdim and newnum for qh->hull_dim and qh->num_points
+ projects points to newpoints
+ projects qh.lower_bound to itself
+ projects qh.upper_bound to itself
+ if qh->DELAUNAY
+ if qh->ATINFINITY
+ projects points to paraboloid
+ computes "infinity" point as vertex average and 10% above all points
+ else
+ uses qh_setdelaunay to project points to paraboloid
+*/
+void qh_projectinput(qhT *qh) {
+ int k,i;
+ int newdim= qh->input_dim, newnum= qh->num_points;
+ signed char *project;
+ int projectsize= (qh->input_dim+1)*sizeof(*project);
+ pointT *newpoints, *coord, *infinity;
+ realT paraboloid, maxboloid= 0;
+
+ project= (signed char*)qh_memalloc(qh, projectsize);
+ memset((char*)project, 0, (size_t)projectsize);
+ for (k=0; k < qh->input_dim; k++) { /* skip Delaunay bound */
+ if (qh->lower_bound[k] == 0 && qh->upper_bound[k] == 0) {
+ project[k]= -1;
+ newdim--;
+ }
+ }
+ if (qh->DELAUNAY) {
+ project[k]= 1;
+ newdim++;
+ if (qh->ATinfinity)
+ newnum++;
+ }
+ if (newdim != qh->hull_dim) {
+ qh_memfree(qh, project, projectsize);
+ qh_fprintf(qh, qh->ferr, 6015, "qhull internal error (qh_projectinput): dimension after projection %d != hull_dim %d\n", newdim, qh->hull_dim);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ if (!(newpoints= qh->temp_malloc= (coordT*)qh_malloc(newnum*newdim*sizeof(coordT)))){
+ qh_memfree(qh, project, projectsize);
+ qh_fprintf(qh, qh->ferr, 6016, "qhull error: insufficient memory to project %d points\n",
+ qh->num_points);
+ qh_errexit(qh, qh_ERRmem, NULL, NULL);
+ }
+ /* qh_projectpoints throws error if mismatched dimensions */
+ qh_projectpoints(qh, project, qh->input_dim+1, qh->first_point,
+ qh->num_points, qh->input_dim, newpoints, newdim);
+ trace1((qh, qh->ferr, 1003, "qh_projectinput: updating lower and upper_bound\n"));
+ qh_projectpoints(qh, project, qh->input_dim+1, qh->lower_bound,
+ 1, qh->input_dim+1, qh->lower_bound, newdim+1);
+ qh_projectpoints(qh, project, qh->input_dim+1, qh->upper_bound,
+ 1, qh->input_dim+1, qh->upper_bound, newdim+1);
+ if (qh->HALFspace) {
+ if (!qh->feasible_point) {
+ qh_memfree(qh, project, projectsize);
+ qh_fprintf(qh, qh->ferr, 6017, "qhull internal error (qh_projectinput): HALFspace defined without qh.feasible_point\n");
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ qh_projectpoints(qh, project, qh->input_dim, qh->feasible_point,
+ 1, qh->input_dim, qh->feasible_point, newdim);
+ }
+ qh_memfree(qh, project, projectsize);
+ if (qh->POINTSmalloc)
+ qh_free(qh->first_point);
+ qh->first_point= newpoints;
+ qh->POINTSmalloc= True;
+ qh->temp_malloc= NULL;
+ if (qh->DELAUNAY && qh->ATinfinity) {
+ coord= qh->first_point;
+ infinity= qh->first_point + qh->hull_dim * qh->num_points;
+ for (k=qh->hull_dim-1; k--; )
+ infinity[k]= 0.0;
+ for (i=qh->num_points; i--; ) {
+ paraboloid= 0.0;
+ for (k=0; k < qh->hull_dim-1; k++) {
+ paraboloid += *coord * *coord;
+ infinity[k] += *coord;
+ coord++;
+ }
+ *(coord++)= paraboloid;
+ maximize_(maxboloid, paraboloid);
+ }
+ /* coord == infinity */
+ for (k=qh->hull_dim-1; k--; )
+ *(coord++) /= qh->num_points;
+ *(coord++)= maxboloid * 1.1;
+ qh->num_points++;
+ trace0((qh, qh->ferr, 9, "qh_projectinput: projected points to paraboloid for Delaunay\n"));
+ }else if (qh->DELAUNAY) /* !qh->ATinfinity */
+ qh_setdelaunay(qh, qh->hull_dim, qh->num_points, qh->first_point);
+} /* projectinput */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="projectpoints">-</a>
+
+ qh_projectpoints(qh, project, n, points, numpoints, dim, newpoints, newdim )
+ project points/numpoints/dim to newpoints/newdim
+ if project[k] == -1
+ delete dimension k
+ if project[k] == 1
+ add dimension k by duplicating previous column
+ n is size of project
+
+ notes:
+ newpoints may be points if only adding dimension at end
+
+ design:
+ check that 'project' and 'newdim' agree
+ for each dimension
+ if project == -1
+ skip dimension
+ else
+ determine start of column in newpoints
+ determine start of column in points
+ if project == +1, duplicate previous column
+ copy dimension (column) from points to newpoints
+*/
+void qh_projectpoints(qhT *qh, signed char *project, int n, realT *points,
+ int numpoints, int dim, realT *newpoints, int newdim) {
+ int testdim= dim, oldk=0, newk=0, i,j=0,k;
+ realT *newp, *oldp;
+
+ for (k=0; k < n; k++)
+ testdim += project[k];
+ if (testdim != newdim) {
+ qh_fprintf(qh, qh->ferr, 6018, "qhull internal error (qh_projectpoints): newdim %d should be %d after projection\n",
+ newdim, testdim);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ for (j=0; j<n; j++) {
+ if (project[j] == -1)
+ oldk++;
+ else {
+ newp= newpoints+newk++;
+ if (project[j] == +1) {
+ if (oldk >= dim)
+ continue;
+ oldp= points+oldk;
+ }else
+ oldp= points+oldk++;
+ for (i=numpoints; i--; ) {
+ *newp= *oldp;
+ newp += newdim;
+ oldp += dim;
+ }
+ }
+ if (oldk >= dim)
+ break;
+ }
+ trace1((qh, qh->ferr, 1004, "qh_projectpoints: projected %d points from dim %d to dim %d\n",
+ numpoints, dim, newdim));
+} /* projectpoints */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="rotateinput">-</a>
+
+ qh_rotateinput(qh, rows )
+ rotate input using row matrix
+ input points given by qh->first_point, num_points, hull_dim
+ assumes rows[dim] is a scratch buffer
+ if qh->POINTSmalloc, overwrites input points, else mallocs a new array
+
+ returns:
+ rotated input
+ sets qh->POINTSmalloc
+
+ design:
+ see qh_rotatepoints
+*/
+void qh_rotateinput(qhT *qh, realT **rows) {
+
+ if (!qh->POINTSmalloc) {
+ qh->first_point= qh_copypoints(qh, qh->first_point, qh->num_points, qh->hull_dim);
+ qh->POINTSmalloc= True;
+ }
+ qh_rotatepoints(qh, qh->first_point, qh->num_points, qh->hull_dim, rows);
+} /* rotateinput */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="rotatepoints">-</a>
+
+ qh_rotatepoints(qh, points, numpoints, dim, row )
+ rotate numpoints points by a d-dim row matrix
+ assumes rows[dim] is a scratch buffer
+
+ returns:
+ rotated points in place
+
+ design:
+ for each point
+ for each coordinate
+ use row[dim] to compute partial inner product
+ for each coordinate
+ rotate by partial inner product
+*/
+void qh_rotatepoints(qhT *qh, realT *points, int numpoints, int dim, realT **row) {
+ realT *point, *rowi, *coord= NULL, sum, *newval;
+ int i,j,k;
+
+ if (qh->IStracing >= 1)
+ qh_printmatrix(qh, qh->ferr, "qh_rotatepoints: rotate points by", row, dim, dim);
+ for (point= points, j= numpoints; j--; point += dim) {
+ newval= row[dim];
+ for (i=0; i < dim; i++) {
+ rowi= row[i];
+ coord= point;
+ for (sum= 0.0, k= dim; k--; )
+ sum += *rowi++ * *coord++;
+ *(newval++)= sum;
+ }
+ for (k=dim; k--; )
+ *(--coord)= *(--newval);
+ }
+} /* rotatepoints */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="scaleinput">-</a>
+
+ qh_scaleinput(qh)
+ scale input points using qh->low_bound/high_bound
+ input points given by qh->first_point, num_points, hull_dim
+ if qh->POINTSmalloc, overwrites input points, else mallocs a new array
+
+ returns:
+ scales coordinates of points to low_bound[k], high_bound[k]
+ sets qh->POINTSmalloc
+
+ design:
+ see qh_scalepoints
+*/
+void qh_scaleinput(qhT *qh) {
+
+ if (!qh->POINTSmalloc) {
+ qh->first_point= qh_copypoints(qh, qh->first_point, qh->num_points, qh->hull_dim);
+ qh->POINTSmalloc= True;
+ }
+ qh_scalepoints(qh, qh->first_point, qh->num_points, qh->hull_dim,
+ qh->lower_bound, qh->upper_bound);
+} /* scaleinput */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="scalelast">-</a>
+
+ qh_scalelast(qh, points, numpoints, dim, low, high, newhigh )
+ scale last coordinate to [0,m] for Delaunay triangulations
+ input points given by points, numpoints, dim
+
+ returns:
+ changes scale of last coordinate from [low, high] to [0, newhigh]
+ overwrites last coordinate of each point
+ saves low/high/newhigh in qh.last_low, etc. for qh_setdelaunay()
+
+ notes:
+ when called by qh_setdelaunay, low/high may not match actual data
+
+ design:
+ compute scale and shift factors
+ apply to last coordinate of each point
+*/
+void qh_scalelast(qhT *qh, coordT *points, int numpoints, int dim, coordT low,
+ coordT high, coordT newhigh) {
+ realT scale, shift;
+ coordT *coord;
+ int i;
+ boolT nearzero= False;
+
+ trace4((qh, qh->ferr, 4013, "qh_scalelast: scale last coordinate from [%2.2g, %2.2g] to [0,%2.2g]\n",
+ low, high, newhigh));
+ qh->last_low= low;
+ qh->last_high= high;
+ qh->last_newhigh= newhigh;
+ scale= qh_divzero(newhigh, high - low,
+ qh->MINdenom_1, &nearzero);
+ if (nearzero) {
+ if (qh->DELAUNAY)
+ qh_fprintf(qh, qh->ferr, 6019, "qhull input error: can not scale last coordinate. Input is cocircular\n or cospherical. Use option 'Qz' to add a point at infinity.\n");
+ else
+ qh_fprintf(qh, qh->ferr, 6020, "qhull input error: can not scale last coordinate. New bounds [0, %2.2g] are too wide for\nexisting bounds [%2.2g, %2.2g] (width %2.2g)\n",
+ newhigh, low, high, high-low);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ shift= - low * newhigh / (high-low);
+ coord= points + dim - 1;
+ for (i=numpoints; i--; coord += dim)
+ *coord= *coord * scale + shift;
+} /* scalelast */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="scalepoints">-</a>
+
+ qh_scalepoints(qh, points, numpoints, dim, newlows, newhighs )
+ scale points to new lowbound and highbound
+ retains old bound when newlow= -REALmax or newhigh= +REALmax
+
+ returns:
+ scaled points
+ overwrites old points
+
+ design:
+ for each coordinate
+ compute current low and high bound
+ compute scale and shift factors
+ scale all points
+ enforce new low and high bound for all points
+*/
+void qh_scalepoints(qhT *qh, pointT *points, int numpoints, int dim,
+ realT *newlows, realT *newhighs) {
+ int i,k;
+ realT shift, scale, *coord, low, high, newlow, newhigh, mincoord, maxcoord;
+ boolT nearzero= False;
+
+ for (k=0; k < dim; k++) {
+ newhigh= newhighs[k];
+ newlow= newlows[k];
+ if (newhigh > REALmax/2 && newlow < -REALmax/2)
+ continue;
+ low= REALmax;
+ high= -REALmax;
+ for (i=numpoints, coord=points+k; i--; coord += dim) {
+ minimize_(low, *coord);
+ maximize_(high, *coord);
+ }
+ if (newhigh > REALmax/2)
+ newhigh= high;
+ if (newlow < -REALmax/2)
+ newlow= low;
+ if (qh->DELAUNAY && k == dim-1 && newhigh < newlow) {
+ qh_fprintf(qh, qh->ferr, 6021, "qhull input error: 'Qb%d' or 'QB%d' inverts paraboloid since high bound %.2g < low bound %.2g\n",
+ k, k, newhigh, newlow);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ scale= qh_divzero(newhigh - newlow, high - low,
+ qh->MINdenom_1, &nearzero);
+ if (nearzero) {
+ qh_fprintf(qh, qh->ferr, 6022, "qhull input error: %d'th dimension's new bounds [%2.2g, %2.2g] too wide for\nexisting bounds [%2.2g, %2.2g]\n",
+ k, newlow, newhigh, low, high);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ shift= (newlow * high - low * newhigh)/(high-low);
+ coord= points+k;
+ for (i=numpoints; i--; coord += dim)
+ *coord= *coord * scale + shift;
+ coord= points+k;
+ if (newlow < newhigh) {
+ mincoord= newlow;
+ maxcoord= newhigh;
+ }else {
+ mincoord= newhigh;
+ maxcoord= newlow;
+ }
+ for (i=numpoints; i--; coord += dim) {
+ minimize_(*coord, maxcoord); /* because of roundoff error */
+ maximize_(*coord, mincoord);
+ }
+ trace0((qh, qh->ferr, 10, "qh_scalepoints: scaled %d'th coordinate [%2.2g, %2.2g] to [%.2g, %.2g] for %d points by %2.2g and shifted %2.2g\n",
+ k, low, high, newlow, newhigh, numpoints, scale, shift));
+ }
+} /* scalepoints */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="setdelaunay">-</a>
+
+ qh_setdelaunay(qh, dim, count, points )
+ project count points to dim-d paraboloid for Delaunay triangulation
+
+ dim is one more than the dimension of the input set
+ assumes dim is at least 3 (i.e., at least a 2-d Delaunay triangulation)
+
+ points is a dim*count realT array. The first dim-1 coordinates
+ are the coordinates of the first input point. array[dim] is
+ the first coordinate of the second input point. array[2*dim] is
+ the first coordinate of the third input point.
+
+ if qh.last_low defined (i.e., 'Qbb' called qh_scalelast)
+ calls qh_scalelast to scale the last coordinate the same as the other points
+
+ returns:
+ for each point
+ sets point[dim-1] to sum of squares of coordinates
+ scale points to 'Qbb' if needed
+
+ notes:
+ to project one point, use
+ qh_setdelaunay(qh, qh->hull_dim, 1, point)
+
+ Do not use options 'Qbk', 'QBk', or 'QbB' since they scale
+ the coordinates after the original projection.
+
+*/
+void qh_setdelaunay(qhT *qh, int dim, int count, pointT *points) {
+ int i, k;
+ coordT *coordp, coord;
+ realT paraboloid;
+
+ trace0((qh, qh->ferr, 11, "qh_setdelaunay: project %d points to paraboloid for Delaunay triangulation\n", count));
+ coordp= points;
+ for (i=0; i < count; i++) {
+ coord= *coordp++;
+ paraboloid= coord*coord;
+ for (k=dim-2; k--; ) {
+ coord= *coordp++;
+ paraboloid += coord*coord;
+ }
+ *coordp++ = paraboloid;
+ }
+ if (qh->last_low < REALmax/2)
+ qh_scalelast(qh, points, count, dim, qh->last_low, qh->last_high, qh->last_newhigh);
+} /* setdelaunay */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="sethalfspace">-</a>
+
+ qh_sethalfspace(qh, dim, coords, nextp, normal, offset, feasible )
+ set point to dual of halfspace relative to feasible point
+ halfspace is normal coefficients and offset.
+
+ returns:
+ false and prints error if feasible point is outside of hull
+ overwrites coordinates for point at dim coords
+ nextp= next point (coords)
+ does not call qh_errexit
+
+ design:
+ compute distance from feasible point to halfspace
+ divide each normal coefficient by -dist
+*/
+boolT qh_sethalfspace(qhT *qh, int dim, coordT *coords, coordT **nextp,
+ coordT *normal, coordT *offset, coordT *feasible) {
+ coordT *normp= normal, *feasiblep= feasible, *coordp= coords;
+ realT dist;
+ realT r; /*bug fix*/
+ int k;
+ boolT zerodiv;
+
+ dist= *offset;
+ for (k=dim; k--; )
+ dist += *(normp++) * *(feasiblep++);
+ if (dist > 0)
+ goto LABELerroroutside;
+ normp= normal;
+ if (dist < -qh->MINdenom) {
+ for (k=dim; k--; )
+ *(coordp++)= *(normp++) / -dist;
+ }else {
+ for (k=dim; k--; ) {
+ *(coordp++)= qh_divzero(*(normp++), -dist, qh->MINdenom_1, &zerodiv);
+ if (zerodiv)
+ goto LABELerroroutside;
+ }
+ }
+ *nextp= coordp;
+ if (qh->IStracing >= 4) {
+ qh_fprintf(qh, qh->ferr, 8021, "qh_sethalfspace: halfspace at offset %6.2g to point: ", *offset);
+ for (k=dim, coordp=coords; k--; ) {
+ r= *coordp++;
+ qh_fprintf(qh, qh->ferr, 8022, " %6.2g", r);
+ }
+ qh_fprintf(qh, qh->ferr, 8023, "\n");
+ }
+ return True;
+LABELerroroutside:
+ feasiblep= feasible;
+ normp= normal;
+ qh_fprintf(qh, qh->ferr, 6023, "qhull input error: feasible point is not clearly inside halfspace\nfeasible point: ");
+ for (k=dim; k--; )
+ qh_fprintf(qh, qh->ferr, 8024, qh_REAL_1, r=*(feasiblep++));
+ qh_fprintf(qh, qh->ferr, 8025, "\n halfspace: ");
+ for (k=dim; k--; )
+ qh_fprintf(qh, qh->ferr, 8026, qh_REAL_1, r=*(normp++));
+ qh_fprintf(qh, qh->ferr, 8027, "\n at offset: ");
+ qh_fprintf(qh, qh->ferr, 8028, qh_REAL_1, *offset);
+ qh_fprintf(qh, qh->ferr, 8029, " and distance: ");
+ qh_fprintf(qh, qh->ferr, 8030, qh_REAL_1, dist);
+ qh_fprintf(qh, qh->ferr, 8031, "\n");
+ return False;
+} /* sethalfspace */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="sethalfspace_all">-</a>
+
+ qh_sethalfspace_all(qh, dim, count, halfspaces, feasible )
+ generate dual for halfspace intersection with feasible point
+ array of count halfspaces
+ each halfspace is normal coefficients followed by offset
+ the origin is inside the halfspace if the offset is negative
+ feasible is a point inside all halfspaces (http://www.qhull.org/html/qhalf.htm#notes)
+
+ returns:
+ malloc'd array of count X dim-1 points
+
+ notes:
+ call before qh_init_B or qh_initqhull_globals
+ free memory when done
+ unused/untested code: please email bradb@shore.net if this works ok for you
+ if using option 'Fp', qh->feasible_point must be set (e.g., to 'feasible')
+ qh->feasible_point is a malloc'd array that is freed by qh_freebuffers.
+
+ design:
+ see qh_sethalfspace
+*/
+coordT *qh_sethalfspace_all(qhT *qh, int dim, int count, coordT *halfspaces, pointT *feasible) {
+ int i, newdim;
+ pointT *newpoints;
+ coordT *coordp, *normalp, *offsetp;
+
+ trace0((qh, qh->ferr, 12, "qh_sethalfspace_all: compute dual for halfspace intersection\n"));
+ newdim= dim - 1;
+ if (!(newpoints=(coordT*)qh_malloc(count*newdim*sizeof(coordT)))){
+ qh_fprintf(qh, qh->ferr, 6024, "qhull error: insufficient memory to compute dual of %d halfspaces\n",
+ count);
+ qh_errexit(qh, qh_ERRmem, NULL, NULL);
+ }
+ coordp= newpoints;
+ normalp= halfspaces;
+ for (i=0; i < count; i++) {
+ offsetp= normalp + newdim;
+ if (!qh_sethalfspace(qh, newdim, coordp, &coordp, normalp, offsetp, feasible)) {
+ qh_free(newpoints); /* feasible is not inside halfspace as reported by qh_sethalfspace */
+ qh_fprintf(qh, qh->ferr, 8032, "The halfspace was at index %d\n", i);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ normalp= offsetp + 1;
+ }
+ return newpoints;
+} /* sethalfspace_all */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="sharpnewfacets">-</a>
+
+ qh_sharpnewfacets(qh)
+
+ returns:
+ true if could be an acute angle (facets in different quadrants)
+
+ notes:
+ for qh_findbest
+
+ design:
+ for all facets on qh.newfacet_list
+ if two facets are in different quadrants
+ set issharp
+*/
+boolT qh_sharpnewfacets(qhT *qh) {
+ facetT *facet;
+ boolT issharp = False;
+ int *quadrant, k;
+
+ quadrant= (int*)qh_memalloc(qh, qh->hull_dim * sizeof(int));
+ FORALLfacet_(qh->newfacet_list) {
+ if (facet == qh->newfacet_list) {
+ for (k=qh->hull_dim; k--; )
+ quadrant[ k]= (facet->normal[ k] > 0);
+ }else {
+ for (k=qh->hull_dim; k--; ) {
+ if (quadrant[ k] != (facet->normal[ k] > 0)) {
+ issharp= True;
+ break;
+ }
+ }
+ }
+ if (issharp)
+ break;
+ }
+ qh_memfree(qh, quadrant, qh->hull_dim * sizeof(int));
+ trace3((qh, qh->ferr, 3001, "qh_sharpnewfacets: %d\n", issharp));
+ return issharp;
+} /* sharpnewfacets */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="voronoi_center">-</a>
+
+ qh_voronoi_center(qh, dim, points )
+ return Voronoi center for a set of points
+ dim is the orginal dimension of the points
+ gh.gm_matrix/qh.gm_row are scratch buffers
+
+ returns:
+ center as a temporary point (qh_memalloc)
+ if non-simplicial,
+ returns center for max simplex of points
+
+ notes:
+ only called by qh_facetcenter
+ from Bowyer & Woodwark, A Programmer's Geometry, 1983, p. 65
+
+ design:
+ if non-simplicial
+ determine max simplex for points
+ translate point0 of simplex to origin
+ compute sum of squares of diagonal
+ compute determinate
+ compute Voronoi center (see Bowyer & Woodwark)
+*/
+pointT *qh_voronoi_center(qhT *qh, int dim, setT *points) {
+ pointT *point, **pointp, *point0;
+ pointT *center= (pointT*)qh_memalloc(qh, qh->center_size);
+ setT *simplex;
+ int i, j, k, size= qh_setsize(qh, points);
+ coordT *gmcoord;
+ realT *diffp, sum2, *sum2row, *sum2p, det, factor;
+ boolT nearzero, infinite;
+
+ if (size == dim+1)
+ simplex= points;
+ else if (size < dim+1) {
+ qh_memfree(qh, center, qh->center_size);
+ qh_fprintf(qh, qh->ferr, 6025, "qhull internal error (qh_voronoi_center):\n need at least %d points to construct a Voronoi center\n",
+ dim+1);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ simplex= points; /* never executed -- avoids warning */
+ }else {
+ simplex= qh_settemp(qh, dim+1);
+ qh_maxsimplex(qh, dim, points, NULL, 0, &simplex);
+ }
+ point0= SETfirstt_(simplex, pointT);
+ gmcoord= qh->gm_matrix;
+ for (k=0; k < dim; k++) {
+ qh->gm_row[k]= gmcoord;
+ FOREACHpoint_(simplex) {
+ if (point != point0)
+ *(gmcoord++)= point[k] - point0[k];
+ }
+ }
+ sum2row= gmcoord;
+ for (i=0; i < dim; i++) {
+ sum2= 0.0;
+ for (k=0; k < dim; k++) {
+ diffp= qh->gm_row[k] + i;
+ sum2 += *diffp * *diffp;
+ }
+ *(gmcoord++)= sum2;
+ }
+ det= qh_determinant(qh, qh->gm_row, dim, &nearzero);
+ factor= qh_divzero(0.5, det, qh->MINdenom, &infinite);
+ if (infinite) {
+ for (k=dim; k--; )
+ center[k]= qh_INFINITE;
+ if (qh->IStracing)
+ qh_printpoints(qh, qh->ferr, "qh_voronoi_center: at infinity for ", simplex);
+ }else {
+ for (i=0; i < dim; i++) {
+ gmcoord= qh->gm_matrix;
+ sum2p= sum2row;
+ for (k=0; k < dim; k++) {
+ qh->gm_row[k]= gmcoord;
+ if (k == i) {
+ for (j=dim; j--; )
+ *(gmcoord++)= *sum2p++;
+ }else {
+ FOREACHpoint_(simplex) {
+ if (point != point0)
+ *(gmcoord++)= point[k] - point0[k];
+ }
+ }
+ }
+ center[i]= qh_determinant(qh, qh->gm_row, dim, &nearzero)*factor + point0[i];
+ }
+#ifndef qh_NOtrace
+ if (qh->IStracing >= 3) {
+ qh_fprintf(qh, qh->ferr, 8033, "qh_voronoi_center: det %2.2g factor %2.2g ", det, factor);
+ qh_printmatrix(qh, qh->ferr, "center:", &center, 1, dim);
+ if (qh->IStracing >= 5) {
+ qh_printpoints(qh, qh->ferr, "points", simplex);
+ FOREACHpoint_(simplex)
+ qh_fprintf(qh, qh->ferr, 8034, "p%d dist %.2g, ", qh_pointid(qh, point),
+ qh_pointdist(point, center, dim));
+ qh_fprintf(qh, qh->ferr, 8035, "\n");
+ }
+ }
+#endif
+ }
+ if (simplex != points)
+ qh_settempfree(qh, &simplex);
+ return center;
+} /* voronoi_center */
+
diff --git a/xs/src/qhull/src/libqhull_r/geom_r.c b/xs/src/qhull/src/libqhull_r/geom_r.c
new file mode 100644
index 000000000..8104813ca
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/geom_r.c
@@ -0,0 +1,1234 @@
+/*<html><pre> -<a href="qh-geom_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ geom_r.c
+ geometric routines of qhull
+
+ see qh-geom_r.htm and geom_r.h
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/geom_r.c#2 $$Change: 1995 $
+ $DateTime: 2015/10/13 21:59:42 $$Author: bbarber $
+
+ infrequent code goes into geom2_r.c
+*/
+
+#include "qhull_ra.h"
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="distplane">-</a>
+
+ qh_distplane(qh, point, facet, dist )
+ return distance from point to facet
+
+ returns:
+ dist
+ if qh.RANDOMdist, joggles result
+
+ notes:
+ dist > 0 if point is above facet (i.e., outside)
+ does not error (for qh_sortfacets, qh_outerinner)
+
+ see:
+ qh_distnorm in geom2_r.c
+ qh_distplane [geom_r.c], QhullFacet::distance, and QhullHyperplane::distance are copies
+*/
+void qh_distplane(qhT *qh, pointT *point, facetT *facet, realT *dist) {
+ coordT *normal= facet->normal, *coordp, randr;
+ int k;
+
+ switch (qh->hull_dim){
+ case 2:
+ *dist= facet->offset + point[0] * normal[0] + point[1] * normal[1];
+ break;
+ case 3:
+ *dist= facet->offset + point[0] * normal[0] + point[1] * normal[1] + point[2] * normal[2];
+ break;
+ case 4:
+ *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3];
+ break;
+ case 5:
+ *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4];
+ break;
+ case 6:
+ *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5];
+ break;
+ case 7:
+ *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6];
+ break;
+ case 8:
+ *dist= facet->offset+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6]+point[7]*normal[7];
+ break;
+ default:
+ *dist= facet->offset;
+ coordp= point;
+ for (k=qh->hull_dim; k--; )
+ *dist += *coordp++ * *normal++;
+ break;
+ }
+ zinc_(Zdistplane);
+ if (!qh->RANDOMdist && qh->IStracing < 4)
+ return;
+ if (qh->RANDOMdist) {
+ randr= qh_RANDOMint;
+ *dist += (2.0 * randr / qh_RANDOMmax - 1.0) *
+ qh->RANDOMfactor * qh->MAXabs_coord;
+ }
+ if (qh->IStracing >= 4) {
+ qh_fprintf(qh, qh->ferr, 8001, "qh_distplane: ");
+ qh_fprintf(qh, qh->ferr, 8002, qh_REAL_1, *dist);
+ qh_fprintf(qh, qh->ferr, 8003, "from p%d to f%d\n", qh_pointid(qh, point), facet->id);
+ }
+ return;
+} /* distplane */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="findbest">-</a>
+
+ qh_findbest(qh, point, startfacet, bestoutside, qh_ISnewfacets, qh_NOupper, dist, isoutside, numpart )
+ find facet that is furthest below a point
+ for upperDelaunay facets
+ returns facet only if !qh_NOupper and clearly above
+
+ input:
+ starts search at 'startfacet' (can not be flipped)
+ if !bestoutside(qh_ALL), stops at qh.MINoutside
+
+ returns:
+ best facet (reports error if NULL)
+ early out if isoutside defined and bestdist > qh.MINoutside
+ dist is distance to facet
+ isoutside is true if point is outside of facet
+ numpart counts the number of distance tests
+
+ see also:
+ qh_findbestnew()
+
+ notes:
+ If merging (testhorizon), searches horizon facets of coplanar best facets because
+ after qh_distplane, this and qh_partitionpoint are the most expensive in 3-d
+ avoid calls to distplane, function calls, and real number operations.
+ caller traces result
+ Optimized for outside points. Tried recording a search set for qh_findhorizon.
+ Made code more complicated.
+
+ when called by qh_partitionvisible():
+ indicated by qh_ISnewfacets
+ qh.newfacet_list is list of simplicial, new facets
+ qh_findbestnew set if qh_sharpnewfacets returns True (to use qh_findbestnew)
+ qh.bestfacet_notsharp set if qh_sharpnewfacets returns False
+
+ when called by qh_findfacet(), qh_partitionpoint(), qh_partitioncoplanar(),
+ qh_check_bestdist(), qh_addpoint()
+ indicated by !qh_ISnewfacets
+ returns best facet in neighborhood of given facet
+ this is best facet overall if dist > - qh.MAXcoplanar
+ or hull has at least a "spherical" curvature
+
+ design:
+ initialize and test for early exit
+ repeat while there are better facets
+ for each neighbor of facet
+ exit if outside facet found
+ test for better facet
+ if point is inside and partitioning
+ test for new facets with a "sharp" intersection
+ if so, future calls go to qh_findbestnew()
+ test horizon facets
+*/
+facetT *qh_findbest(qhT *qh, pointT *point, facetT *startfacet,
+ boolT bestoutside, boolT isnewfacets, boolT noupper,
+ realT *dist, boolT *isoutside, int *numpart) {
+ realT bestdist= -REALmax/2 /* avoid underflow */;
+ facetT *facet, *neighbor, **neighborp;
+ facetT *bestfacet= NULL, *lastfacet= NULL;
+ int oldtrace= qh->IStracing;
+ unsigned int visitid= ++qh->visit_id;
+ int numpartnew=0;
+ boolT testhorizon = True; /* needed if precise, e.g., rbox c D6 | qhull Q0 Tv */
+
+ zinc_(Zfindbest);
+ if (qh->IStracing >= 3 || (qh->TRACElevel && qh->TRACEpoint >= 0 && qh->TRACEpoint == qh_pointid(qh, point))) {
+ if (qh->TRACElevel > qh->IStracing)
+ qh->IStracing= qh->TRACElevel;
+ qh_fprintf(qh, qh->ferr, 8004, "qh_findbest: point p%d starting at f%d isnewfacets? %d, unless %d exit if > %2.2g\n",
+ qh_pointid(qh, point), startfacet->id, isnewfacets, bestoutside, qh->MINoutside);
+ qh_fprintf(qh, qh->ferr, 8005, " testhorizon? %d noupper? %d", testhorizon, noupper);
+ qh_fprintf(qh, qh->ferr, 8006, " Last point added was p%d.", qh->furthest_id);
+ qh_fprintf(qh, qh->ferr, 8007, " Last merge was #%d. max_outside %2.2g\n", zzval_(Ztotmerge), qh->max_outside);
+ }
+ if (isoutside)
+ *isoutside= True;
+ if (!startfacet->flipped) { /* test startfacet */
+ *numpart= 1;
+ qh_distplane(qh, point, startfacet, dist); /* this code is duplicated below */
+ if (!bestoutside && *dist >= qh->MINoutside
+ && (!startfacet->upperdelaunay || !noupper)) {
+ bestfacet= startfacet;
+ goto LABELreturn_best;
+ }
+ bestdist= *dist;
+ if (!startfacet->upperdelaunay) {
+ bestfacet= startfacet;
+ }
+ }else
+ *numpart= 0;
+ startfacet->visitid= visitid;
+ facet= startfacet;
+ while (facet) {
+ trace4((qh, qh->ferr, 4001, "qh_findbest: neighbors of f%d, bestdist %2.2g f%d\n",
+ facet->id, bestdist, getid_(bestfacet)));
+ lastfacet= facet;
+ FOREACHneighbor_(facet) {
+ if (!neighbor->newfacet && isnewfacets)
+ continue;
+ if (neighbor->visitid == visitid)
+ continue;
+ neighbor->visitid= visitid;
+ if (!neighbor->flipped) { /* code duplicated above */
+ (*numpart)++;
+ qh_distplane(qh, point, neighbor, dist);
+ if (*dist > bestdist) {
+ if (!bestoutside && *dist >= qh->MINoutside
+ && (!neighbor->upperdelaunay || !noupper)) {
+ bestfacet= neighbor;
+ goto LABELreturn_best;
+ }
+ if (!neighbor->upperdelaunay) {
+ bestfacet= neighbor;
+ bestdist= *dist;
+ break; /* switch to neighbor */
+ }else if (!bestfacet) {
+ bestdist= *dist;
+ break; /* switch to neighbor */
+ }
+ } /* end of *dist>bestdist */
+ } /* end of !flipped */
+ } /* end of FOREACHneighbor */
+ facet= neighbor; /* non-NULL only if *dist>bestdist */
+ } /* end of while facet (directed search) */
+ if (isnewfacets) {
+ if (!bestfacet) {
+ bestdist= -REALmax/2;
+ bestfacet= qh_findbestnew(qh, point, startfacet->next, &bestdist, bestoutside, isoutside, &numpartnew);
+ testhorizon= False; /* qh_findbestnew calls qh_findbesthorizon */
+ }else if (!qh->findbest_notsharp && bestdist < - qh->DISTround) {
+ if (qh_sharpnewfacets(qh)) {
+ /* seldom used, qh_findbestnew will retest all facets */
+ zinc_(Zfindnewsharp);
+ bestfacet= qh_findbestnew(qh, point, bestfacet, &bestdist, bestoutside, isoutside, &numpartnew);
+ testhorizon= False; /* qh_findbestnew calls qh_findbesthorizon */
+ qh->findbestnew= True;
+ }else
+ qh->findbest_notsharp= True;
+ }
+ }
+ if (!bestfacet)
+ bestfacet= qh_findbestlower(qh, lastfacet, point, &bestdist, numpart);
+ if (testhorizon)
+ bestfacet= qh_findbesthorizon(qh, !qh_IScheckmax, point, bestfacet, noupper, &bestdist, &numpartnew);
+ *dist= bestdist;
+ if (isoutside && bestdist < qh->MINoutside)
+ *isoutside= False;
+LABELreturn_best:
+ zadd_(Zfindbesttot, *numpart);
+ zmax_(Zfindbestmax, *numpart);
+ (*numpart) += numpartnew;
+ qh->IStracing= oldtrace;
+ return bestfacet;
+} /* findbest */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="findbesthorizon">-</a>
+
+ qh_findbesthorizon(qh, qh_IScheckmax, point, startfacet, qh_NOupper, &bestdist, &numpart )
+ search coplanar and better horizon facets from startfacet/bestdist
+ ischeckmax turns off statistics and minsearch update
+ all arguments must be initialized
+ returns(ischeckmax):
+ best facet
+ returns(!ischeckmax):
+ best facet that is not upperdelaunay
+ allows upperdelaunay that is clearly outside
+ returns:
+ bestdist is distance to bestfacet
+ numpart -- updates number of distance tests
+
+ notes:
+ no early out -- use qh_findbest() or qh_findbestnew()
+ Searches coplanar or better horizon facets
+
+ when called by qh_check_maxout() (qh_IScheckmax)
+ startfacet must be closest to the point
+ Otherwise, if point is beyond and below startfacet, startfacet may be a local minimum
+ even though other facets are below the point.
+ updates facet->maxoutside for good, visited facets
+ may return NULL
+
+ searchdist is qh.max_outside + 2 * DISTround
+ + max( MINvisible('Vn'), MAXcoplanar('Un'));
+ This setting is a guess. It must be at least max_outside + 2*DISTround
+ because a facet may have a geometric neighbor across a vertex
+
+ design:
+ for each horizon facet of coplanar best facets
+ continue if clearly inside
+ unless upperdelaunay or clearly outside
+ update best facet
+*/
+facetT *qh_findbesthorizon(qhT *qh, boolT ischeckmax, pointT* point, facetT *startfacet, boolT noupper, realT *bestdist, int *numpart) {
+ facetT *bestfacet= startfacet;
+ realT dist;
+ facetT *neighbor, **neighborp, *facet;
+ facetT *nextfacet= NULL; /* optimize last facet of coplanarfacetset */
+ int numpartinit= *numpart, coplanarfacetset_size;
+ unsigned int visitid= ++qh->visit_id;
+ boolT newbest= False; /* for tracing */
+ realT minsearch, searchdist; /* skip facets that are too far from point */
+
+ if (!ischeckmax) {
+ zinc_(Zfindhorizon);
+ }else {
+#if qh_MAXoutside
+ if ((!qh->ONLYgood || startfacet->good) && *bestdist > startfacet->maxoutside)
+ startfacet->maxoutside= *bestdist;
+#endif
+ }
+ searchdist= qh_SEARCHdist; /* multiple of qh.max_outside and precision constants */
+ minsearch= *bestdist - searchdist;
+ if (ischeckmax) {
+ /* Always check coplanar facets. Needed for RBOX 1000 s Z1 G1e-13 t996564279 | QHULL Tv */
+ minimize_(minsearch, -searchdist);
+ }
+ coplanarfacetset_size= 0;
+ facet= startfacet;
+ while (True) {
+ trace4((qh, qh->ferr, 4002, "qh_findbesthorizon: neighbors of f%d bestdist %2.2g f%d ischeckmax? %d noupper? %d minsearch %2.2g searchdist %2.2g\n",
+ facet->id, *bestdist, getid_(bestfacet), ischeckmax, noupper,
+ minsearch, searchdist));
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid == visitid)
+ continue;
+ neighbor->visitid= visitid;
+ if (!neighbor->flipped) {
+ qh_distplane(qh, point, neighbor, &dist);
+ (*numpart)++;
+ if (dist > *bestdist) {
+ if (!neighbor->upperdelaunay || ischeckmax || (!noupper && dist >= qh->MINoutside)) {
+ bestfacet= neighbor;
+ *bestdist= dist;
+ newbest= True;
+ if (!ischeckmax) {
+ minsearch= dist - searchdist;
+ if (dist > *bestdist + searchdist) {
+ zinc_(Zfindjump); /* everything in qh.coplanarfacetset at least searchdist below */
+ coplanarfacetset_size= 0;
+ }
+ }
+ }
+ }else if (dist < minsearch)
+ continue; /* if ischeckmax, dist can't be positive */
+#if qh_MAXoutside
+ if (ischeckmax && dist > neighbor->maxoutside)
+ neighbor->maxoutside= dist;
+#endif
+ } /* end of !flipped */
+ if (nextfacet) {
+ if (!coplanarfacetset_size++) {
+ SETfirst_(qh->coplanarfacetset)= nextfacet;
+ SETtruncate_(qh->coplanarfacetset, 1);
+ }else
+ qh_setappend(qh, &qh->coplanarfacetset, nextfacet); /* Was needed for RBOX 1000 s W1e-13 P0 t996547055 | QHULL d Qbb Qc Tv
+ and RBOX 1000 s Z1 G1e-13 t996564279 | qhull Tv */
+ }
+ nextfacet= neighbor;
+ } /* end of EACHneighbor */
+ facet= nextfacet;
+ if (facet)
+ nextfacet= NULL;
+ else if (!coplanarfacetset_size)
+ break;
+ else if (!--coplanarfacetset_size) {
+ facet= SETfirstt_(qh->coplanarfacetset, facetT);
+ SETtruncate_(qh->coplanarfacetset, 0);
+ }else
+ facet= (facetT*)qh_setdellast(qh->coplanarfacetset);
+ } /* while True, for each facet in qh.coplanarfacetset */
+ if (!ischeckmax) {
+ zadd_(Zfindhorizontot, *numpart - numpartinit);
+ zmax_(Zfindhorizonmax, *numpart - numpartinit);
+ if (newbest)
+ zinc_(Zparthorizon);
+ }
+ trace4((qh, qh->ferr, 4003, "qh_findbesthorizon: newbest? %d bestfacet f%d bestdist %2.2g\n", newbest, getid_(bestfacet), *bestdist));
+ return bestfacet;
+} /* findbesthorizon */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="findbestnew">-</a>
+
+ qh_findbestnew(qh, point, startfacet, dist, isoutside, numpart )
+ find best newfacet for point
+ searches all of qh.newfacet_list starting at startfacet
+ searches horizon facets of coplanar best newfacets
+ searches all facets if startfacet == qh.facet_list
+ returns:
+ best new or horizon facet that is not upperdelaunay
+ early out if isoutside and not 'Qf'
+ dist is distance to facet
+ isoutside is true if point is outside of facet
+ numpart is number of distance tests
+
+ notes:
+ Always used for merged new facets (see qh_USEfindbestnew)
+ Avoids upperdelaunay facet unless (isoutside and outside)
+
+ Uses qh.visit_id, qh.coplanarfacetset.
+ If share visit_id with qh_findbest, coplanarfacetset is incorrect.
+
+ If merging (testhorizon), searches horizon facets of coplanar best facets because
+ a point maybe coplanar to the bestfacet, below its horizon facet,
+ and above a horizon facet of a coplanar newfacet. For example,
+ rbox 1000 s Z1 G1e-13 | qhull
+ rbox 1000 s W1e-13 P0 t992110337 | QHULL d Qbb Qc
+
+ qh_findbestnew() used if
+ qh_sharpnewfacets -- newfacets contains a sharp angle
+ if many merges, qh_premerge found a merge, or 'Qf' (qh.findbestnew)
+
+ see also:
+ qh_partitionall() and qh_findbest()
+
+ design:
+ for each new facet starting from startfacet
+ test distance from point to facet
+ return facet if clearly outside
+ unless upperdelaunay and a lowerdelaunay exists
+ update best facet
+ test horizon facets
+*/
+facetT *qh_findbestnew(qhT *qh, pointT *point, facetT *startfacet,
+ realT *dist, boolT bestoutside, boolT *isoutside, int *numpart) {
+ realT bestdist= -REALmax/2;
+ facetT *bestfacet= NULL, *facet;
+ int oldtrace= qh->IStracing, i;
+ unsigned int visitid= ++qh->visit_id;
+ realT distoutside= 0.0;
+ boolT isdistoutside; /* True if distoutside is defined */
+ boolT testhorizon = True; /* needed if precise, e.g., rbox c D6 | qhull Q0 Tv */
+
+ if (!startfacet) {
+ if (qh->MERGING)
+ qh_fprintf(qh, qh->ferr, 6001, "qhull precision error (qh_findbestnew): merging has formed and deleted a cone of new facets. Can not continue.\n");
+ else
+ qh_fprintf(qh, qh->ferr, 6002, "qhull internal error (qh_findbestnew): no new facets for point p%d\n",
+ qh->furthest_id);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ zinc_(Zfindnew);
+ if (qh->BESToutside || bestoutside)
+ isdistoutside= False;
+ else {
+ isdistoutside= True;
+ distoutside= qh_DISToutside; /* multiple of qh.MINoutside & qh.max_outside, see user.h */
+ }
+ if (isoutside)
+ *isoutside= True;
+ *numpart= 0;
+ if (qh->IStracing >= 3 || (qh->TRACElevel && qh->TRACEpoint >= 0 && qh->TRACEpoint == qh_pointid(qh, point))) {
+ if (qh->TRACElevel > qh->IStracing)
+ qh->IStracing= qh->TRACElevel;
+ qh_fprintf(qh, qh->ferr, 8008, "qh_findbestnew: point p%d facet f%d. Stop? %d if dist > %2.2g\n",
+ qh_pointid(qh, point), startfacet->id, isdistoutside, distoutside);
+ qh_fprintf(qh, qh->ferr, 8009, " Last point added p%d visitid %d.", qh->furthest_id, visitid);
+ qh_fprintf(qh, qh->ferr, 8010, " Last merge was #%d.\n", zzval_(Ztotmerge));
+ }
+ /* visit all new facets starting with startfacet, maybe qh->facet_list */
+ for (i=0, facet=startfacet; i < 2; i++, facet= qh->newfacet_list) {
+ FORALLfacet_(facet) {
+ if (facet == startfacet && i)
+ break;
+ facet->visitid= visitid;
+ if (!facet->flipped) {
+ qh_distplane(qh, point, facet, dist);
+ (*numpart)++;
+ if (*dist > bestdist) {
+ if (!facet->upperdelaunay || *dist >= qh->MINoutside) {
+ bestfacet= facet;
+ if (isdistoutside && *dist >= distoutside)
+ goto LABELreturn_bestnew;
+ bestdist= *dist;
+ }
+ }
+ } /* end of !flipped */
+ } /* FORALLfacet from startfacet or qh->newfacet_list */
+ }
+ if (testhorizon || !bestfacet) /* testhorizon is always True. Keep the same code as qh_findbest */
+ bestfacet= qh_findbesthorizon(qh, !qh_IScheckmax, point, bestfacet ? bestfacet : startfacet,
+ !qh_NOupper, &bestdist, numpart);
+ *dist= bestdist;
+ if (isoutside && *dist < qh->MINoutside)
+ *isoutside= False;
+LABELreturn_bestnew:
+ zadd_(Zfindnewtot, *numpart);
+ zmax_(Zfindnewmax, *numpart);
+ trace4((qh, qh->ferr, 4004, "qh_findbestnew: bestfacet f%d bestdist %2.2g\n", getid_(bestfacet), *dist));
+ qh->IStracing= oldtrace;
+ return bestfacet;
+} /* findbestnew */
+
+/* ============ hyperplane functions -- keep code together [?] ============ */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="backnormal">-</a>
+
+ qh_backnormal(qh, rows, numrow, numcol, sign, normal, nearzero )
+ given an upper-triangular rows array and a sign,
+ solve for normal equation x using back substitution over rows U
+
+ returns:
+ normal= x
+
+ if will not be able to divzero() when normalized(qh.MINdenom_2 and qh.MINdenom_1_2),
+ if fails on last row
+ this means that the hyperplane intersects [0,..,1]
+ sets last coordinate of normal to sign
+ otherwise
+ sets tail of normal to [...,sign,0,...], i.e., solves for b= [0...0]
+ sets nearzero
+
+ notes:
+ assumes numrow == numcol-1
+
+ see Golub & van Loan, 1983, Eq. 4.4-9 for "Gaussian elimination with complete pivoting"
+
+ solves Ux=b where Ax=b and PA=LU
+ b= [0,...,0,sign or 0] (sign is either -1 or +1)
+ last row of A= [0,...,0,1]
+
+ 1) Ly=Pb == y=b since P only permutes the 0's of b
+
+ design:
+ for each row from end
+ perform back substitution
+ if near zero
+ use qh_divzero for division
+ if zero divide and not last row
+ set tail of normal to 0
+*/
+void qh_backnormal(qhT *qh, realT **rows, int numrow, int numcol, boolT sign,
+ coordT *normal, boolT *nearzero) {
+ int i, j;
+ coordT *normalp, *normal_tail, *ai, *ak;
+ realT diagonal;
+ boolT waszero;
+ int zerocol= -1;
+
+ normalp= normal + numcol - 1;
+ *normalp--= (sign ? -1.0 : 1.0);
+ for (i=numrow; i--; ) {
+ *normalp= 0.0;
+ ai= rows[i] + i + 1;
+ ak= normalp+1;
+ for (j=i+1; j < numcol; j++)
+ *normalp -= *ai++ * *ak++;
+ diagonal= (rows[i])[i];
+ if (fabs_(diagonal) > qh->MINdenom_2)
+ *(normalp--) /= diagonal;
+ else {
+ waszero= False;
+ *normalp= qh_divzero(*normalp, diagonal, qh->MINdenom_1_2, &waszero);
+ if (waszero) {
+ zerocol= i;
+ *(normalp--)= (sign ? -1.0 : 1.0);
+ for (normal_tail= normalp+2; normal_tail < normal + numcol; normal_tail++)
+ *normal_tail= 0.0;
+ }else
+ normalp--;
+ }
+ }
+ if (zerocol != -1) {
+ zzinc_(Zback0);
+ *nearzero= True;
+ trace4((qh, qh->ferr, 4005, "qh_backnormal: zero diagonal at column %d.\n", i));
+ qh_precision(qh, "zero diagonal on back substitution");
+ }
+} /* backnormal */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="gausselim">-</a>
+
+ qh_gausselim(qh, rows, numrow, numcol, sign )
+ Gaussian elimination with partial pivoting
+
+ returns:
+ rows is upper triangular (includes row exchanges)
+ flips sign for each row exchange
+ sets nearzero if pivot[k] < qh.NEARzero[k], else clears it
+
+ notes:
+ if nearzero, the determinant's sign may be incorrect.
+ assumes numrow <= numcol
+
+ design:
+ for each row
+ determine pivot and exchange rows if necessary
+ test for near zero
+ perform gaussian elimination step
+*/
+void qh_gausselim(qhT *qh, realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero) {
+ realT *ai, *ak, *rowp, *pivotrow;
+ realT n, pivot, pivot_abs= 0.0, temp;
+ int i, j, k, pivoti, flip=0;
+
+ *nearzero= False;
+ for (k=0; k < numrow; k++) {
+ pivot_abs= fabs_((rows[k])[k]);
+ pivoti= k;
+ for (i=k+1; i < numrow; i++) {
+ if ((temp= fabs_((rows[i])[k])) > pivot_abs) {
+ pivot_abs= temp;
+ pivoti= i;
+ }
+ }
+ if (pivoti != k) {
+ rowp= rows[pivoti];
+ rows[pivoti]= rows[k];
+ rows[k]= rowp;
+ *sign ^= 1;
+ flip ^= 1;
+ }
+ if (pivot_abs <= qh->NEARzero[k]) {
+ *nearzero= True;
+ if (pivot_abs == 0.0) { /* remainder of column == 0 */
+ if (qh->IStracing >= 4) {
+ qh_fprintf(qh, qh->ferr, 8011, "qh_gausselim: 0 pivot at column %d. (%2.2g < %2.2g)\n", k, pivot_abs, qh->DISTround);
+ qh_printmatrix(qh, qh->ferr, "Matrix:", rows, numrow, numcol);
+ }
+ zzinc_(Zgauss0);
+ qh_precision(qh, "zero pivot for Gaussian elimination");
+ goto LABELnextcol;
+ }
+ }
+ pivotrow= rows[k] + k;
+ pivot= *pivotrow++; /* signed value of pivot, and remainder of row */
+ for (i=k+1; i < numrow; i++) {
+ ai= rows[i] + k;
+ ak= pivotrow;
+ n= (*ai++)/pivot; /* divzero() not needed since |pivot| >= |*ai| */
+ for (j= numcol - (k+1); j--; )
+ *ai++ -= n * *ak++;
+ }
+ LABELnextcol:
+ ;
+ }
+ wmin_(Wmindenom, pivot_abs); /* last pivot element */
+ if (qh->IStracing >= 5)
+ qh_printmatrix(qh, qh->ferr, "qh_gausselem: result", rows, numrow, numcol);
+} /* gausselim */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="getangle">-</a>
+
+ qh_getangle(qh, vect1, vect2 )
+ returns the dot product of two vectors
+ if qh.RANDOMdist, joggles result
+
+ notes:
+ the angle may be > 1.0 or < -1.0 because of roundoff errors
+
+*/
+realT qh_getangle(qhT *qh, pointT *vect1, pointT *vect2) {
+ realT angle= 0, randr;
+ int k;
+
+ for (k=qh->hull_dim; k--; )
+ angle += *vect1++ * *vect2++;
+ if (qh->RANDOMdist) {
+ randr= qh_RANDOMint;
+ angle += (2.0 * randr / qh_RANDOMmax - 1.0) *
+ qh->RANDOMfactor;
+ }
+ trace4((qh, qh->ferr, 4006, "qh_getangle: %2.2g\n", angle));
+ return(angle);
+} /* getangle */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="getcenter">-</a>
+
+ qh_getcenter(qh, vertices )
+ returns arithmetic center of a set of vertices as a new point
+
+ notes:
+ allocates point array for center
+*/
+pointT *qh_getcenter(qhT *qh, setT *vertices) {
+ int k;
+ pointT *center, *coord;
+ vertexT *vertex, **vertexp;
+ int count= qh_setsize(qh, vertices);
+
+ if (count < 2) {
+ qh_fprintf(qh, qh->ferr, 6003, "qhull internal error (qh_getcenter): not defined for %d points\n", count);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ center= (pointT *)qh_memalloc(qh, qh->normal_size);
+ for (k=0; k < qh->hull_dim; k++) {
+ coord= center+k;
+ *coord= 0.0;
+ FOREACHvertex_(vertices)
+ *coord += vertex->point[k];
+ *coord /= count; /* count>=2 by QH6003 */
+ }
+ return(center);
+} /* getcenter */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="getcentrum">-</a>
+
+ qh_getcentrum(qh, facet )
+ returns the centrum for a facet as a new point
+
+ notes:
+ allocates the centrum
+*/
+pointT *qh_getcentrum(qhT *qh, facetT *facet) {
+ realT dist;
+ pointT *centrum, *point;
+
+ point= qh_getcenter(qh, facet->vertices);
+ zzinc_(Zcentrumtests);
+ qh_distplane(qh, point, facet, &dist);
+ centrum= qh_projectpoint(qh, point, facet, dist);
+ qh_memfree(qh, point, qh->normal_size);
+ trace4((qh, qh->ferr, 4007, "qh_getcentrum: for f%d, %d vertices dist= %2.2g\n",
+ facet->id, qh_setsize(qh, facet->vertices), dist));
+ return centrum;
+} /* getcentrum */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="getdistance">-</a>
+
+ qh_getdistance(qh, facet, neighbor, mindist, maxdist )
+ returns the maxdist and mindist distance of any vertex from neighbor
+
+ returns:
+ the max absolute value
+
+ design:
+ for each vertex of facet that is not in neighbor
+ test the distance from vertex to neighbor
+*/
+realT qh_getdistance(qhT *qh, facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist) {
+ vertexT *vertex, **vertexp;
+ realT dist, maxd, mind;
+
+ FOREACHvertex_(facet->vertices)
+ vertex->seen= False;
+ FOREACHvertex_(neighbor->vertices)
+ vertex->seen= True;
+ mind= 0.0;
+ maxd= 0.0;
+ FOREACHvertex_(facet->vertices) {
+ if (!vertex->seen) {
+ zzinc_(Zbestdist);
+ qh_distplane(qh, vertex->point, neighbor, &dist);
+ if (dist < mind)
+ mind= dist;
+ else if (dist > maxd)
+ maxd= dist;
+ }
+ }
+ *mindist= mind;
+ *maxdist= maxd;
+ mind= -mind;
+ if (maxd > mind)
+ return maxd;
+ else
+ return mind;
+} /* getdistance */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="normalize">-</a>
+
+ qh_normalize(qh, normal, dim, toporient )
+ normalize a vector and report if too small
+ does not use min norm
+
+ see:
+ qh_normalize2
+*/
+void qh_normalize(qhT *qh, coordT *normal, int dim, boolT toporient) {
+ qh_normalize2(qh, normal, dim, toporient, NULL, NULL);
+} /* normalize */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="normalize2">-</a>
+
+ qh_normalize2(qh, normal, dim, toporient, minnorm, ismin )
+ normalize a vector and report if too small
+ qh.MINdenom/MINdenom1 are the upper limits for divide overflow
+
+ returns:
+ normalized vector
+ flips sign if !toporient
+ if minnorm non-NULL,
+ sets ismin if normal < minnorm
+
+ notes:
+ if zero norm
+ sets all elements to sqrt(1.0/dim)
+ if divide by zero (divzero())
+ sets largest element to +/-1
+ bumps Znearlysingular
+
+ design:
+ computes norm
+ test for minnorm
+ if not near zero
+ normalizes normal
+ else if zero norm
+ sets normal to standard value
+ else
+ uses qh_divzero to normalize
+ if nearzero
+ sets norm to direction of maximum value
+*/
+void qh_normalize2(qhT *qh, coordT *normal, int dim, boolT toporient,
+ realT *minnorm, boolT *ismin) {
+ int k;
+ realT *colp, *maxp, norm= 0, temp, *norm1, *norm2, *norm3;
+ boolT zerodiv;
+
+ norm1= normal+1;
+ norm2= normal+2;
+ norm3= normal+3;
+ if (dim == 2)
+ norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1));
+ else if (dim == 3)
+ norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2));
+ else if (dim == 4) {
+ norm= sqrt((*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2)
+ + (*norm3)*(*norm3));
+ }else if (dim > 4) {
+ norm= (*normal)*(*normal) + (*norm1)*(*norm1) + (*norm2)*(*norm2)
+ + (*norm3)*(*norm3);
+ for (k=dim-4, colp=normal+4; k--; colp++)
+ norm += (*colp) * (*colp);
+ norm= sqrt(norm);
+ }
+ if (minnorm) {
+ if (norm < *minnorm)
+ *ismin= True;
+ else
+ *ismin= False;
+ }
+ wmin_(Wmindenom, norm);
+ if (norm > qh->MINdenom) {
+ if (!toporient)
+ norm= -norm;
+ *normal /= norm;
+ *norm1 /= norm;
+ if (dim == 2)
+ ; /* all done */
+ else if (dim == 3)
+ *norm2 /= norm;
+ else if (dim == 4) {
+ *norm2 /= norm;
+ *norm3 /= norm;
+ }else if (dim >4) {
+ *norm2 /= norm;
+ *norm3 /= norm;
+ for (k=dim-4, colp=normal+4; k--; )
+ *colp++ /= norm;
+ }
+ }else if (norm == 0.0) {
+ temp= sqrt(1.0/dim);
+ for (k=dim, colp=normal; k--; )
+ *colp++ = temp;
+ }else {
+ if (!toporient)
+ norm= -norm;
+ for (k=dim, colp=normal; k--; colp++) { /* k used below */
+ temp= qh_divzero(*colp, norm, qh->MINdenom_1, &zerodiv);
+ if (!zerodiv)
+ *colp= temp;
+ else {
+ maxp= qh_maxabsval(normal, dim);
+ temp= ((*maxp * norm >= 0.0) ? 1.0 : -1.0);
+ for (k=dim, colp=normal; k--; colp++)
+ *colp= 0.0;
+ *maxp= temp;
+ zzinc_(Znearlysingular);
+ trace0((qh, qh->ferr, 1, "qh_normalize: norm=%2.2g too small during p%d\n",
+ norm, qh->furthest_id));
+ return;
+ }
+ }
+ }
+} /* normalize */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="projectpoint">-</a>
+
+ qh_projectpoint(qh, point, facet, dist )
+ project point onto a facet by dist
+
+ returns:
+ returns a new point
+
+ notes:
+ if dist= distplane(point,facet)
+ this projects point to hyperplane
+ assumes qh_memfree_() is valid for normal_size
+*/
+pointT *qh_projectpoint(qhT *qh, pointT *point, facetT *facet, realT dist) {
+ pointT *newpoint, *np, *normal;
+ int normsize= qh->normal_size;
+ int k;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+
+ qh_memalloc_(qh, normsize, freelistp, newpoint, pointT);
+ np= newpoint;
+ normal= facet->normal;
+ for (k=qh->hull_dim; k--; )
+ *(np++)= *point++ - dist * *normal++;
+ return(newpoint);
+} /* projectpoint */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="setfacetplane">-</a>
+
+ qh_setfacetplane(qh, facet )
+ sets the hyperplane for a facet
+ if qh.RANDOMdist, joggles hyperplane
+
+ notes:
+ uses global buffers qh.gm_matrix and qh.gm_row
+ overwrites facet->normal if already defined
+ updates Wnewvertex if PRINTstatistics
+ sets facet->upperdelaunay if upper envelope of Delaunay triangulation
+
+ design:
+ copy vertex coordinates to qh.gm_matrix/gm_row
+ compute determinate
+ if nearzero
+ recompute determinate with gaussian elimination
+ if nearzero
+ force outside orientation by testing interior point
+*/
+void qh_setfacetplane(qhT *qh, facetT *facet) {
+ pointT *point;
+ vertexT *vertex, **vertexp;
+ int normsize= qh->normal_size;
+ int k,i, oldtrace= 0;
+ realT dist;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+ coordT *coord, *gmcoord;
+ pointT *point0= SETfirstt_(facet->vertices, vertexT)->point;
+ boolT nearzero= False;
+
+ zzinc_(Zsetplane);
+ if (!facet->normal)
+ qh_memalloc_(qh, normsize, freelistp, facet->normal, coordT);
+ if (facet == qh->tracefacet) {
+ oldtrace= qh->IStracing;
+ qh->IStracing= 5;
+ qh_fprintf(qh, qh->ferr, 8012, "qh_setfacetplane: facet f%d created.\n", facet->id);
+ qh_fprintf(qh, qh->ferr, 8013, " Last point added to hull was p%d.", qh->furthest_id);
+ if (zzval_(Ztotmerge))
+ qh_fprintf(qh, qh->ferr, 8014, " Last merge was #%d.", zzval_(Ztotmerge));
+ qh_fprintf(qh, qh->ferr, 8015, "\n\nCurrent summary is:\n");
+ qh_printsummary(qh, qh->ferr);
+ }
+ if (qh->hull_dim <= 4) {
+ i= 0;
+ if (qh->RANDOMdist) {
+ gmcoord= qh->gm_matrix;
+ FOREACHvertex_(facet->vertices) {
+ qh->gm_row[i++]= gmcoord;
+ coord= vertex->point;
+ for (k=qh->hull_dim; k--; )
+ *(gmcoord++)= *coord++ * qh_randomfactor(qh, qh->RANDOMa, qh->RANDOMb);
+ }
+ }else {
+ FOREACHvertex_(facet->vertices)
+ qh->gm_row[i++]= vertex->point;
+ }
+ qh_sethyperplane_det(qh, qh->hull_dim, qh->gm_row, point0, facet->toporient,
+ facet->normal, &facet->offset, &nearzero);
+ }
+ if (qh->hull_dim > 4 || nearzero) {
+ i= 0;
+ gmcoord= qh->gm_matrix;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->point != point0) {
+ qh->gm_row[i++]= gmcoord;
+ coord= vertex->point;
+ point= point0;
+ for (k=qh->hull_dim; k--; )
+ *(gmcoord++)= *coord++ - *point++;
+ }
+ }
+ qh->gm_row[i]= gmcoord; /* for areasimplex */
+ if (qh->RANDOMdist) {
+ gmcoord= qh->gm_matrix;
+ for (i=qh->hull_dim-1; i--; ) {
+ for (k=qh->hull_dim; k--; )
+ *(gmcoord++) *= qh_randomfactor(qh, qh->RANDOMa, qh->RANDOMb);
+ }
+ }
+ qh_sethyperplane_gauss(qh, qh->hull_dim, qh->gm_row, point0, facet->toporient,
+ facet->normal, &facet->offset, &nearzero);
+ if (nearzero) {
+ if (qh_orientoutside(qh, facet)) {
+ trace0((qh, qh->ferr, 2, "qh_setfacetplane: flipped orientation after testing interior_point during p%d\n", qh->furthest_id));
+ /* this is part of using Gaussian Elimination. For example in 5-d
+ 1 1 1 1 0
+ 1 1 1 1 1
+ 0 0 0 1 0
+ 0 1 0 0 0
+ 1 0 0 0 0
+ norm= 0.38 0.38 -0.76 0.38 0
+ has a determinate of 1, but g.e. after subtracting pt. 0 has
+ 0's in the diagonal, even with full pivoting. It does work
+ if you subtract pt. 4 instead. */
+ }
+ }
+ }
+ facet->upperdelaunay= False;
+ if (qh->DELAUNAY) {
+ if (qh->UPPERdelaunay) { /* matches qh_triangulate_facet and qh.lower_threshold in qh_initbuild */
+ if (facet->normal[qh->hull_dim -1] >= qh->ANGLEround * qh_ZEROdelaunay)
+ facet->upperdelaunay= True;
+ }else {
+ if (facet->normal[qh->hull_dim -1] > -qh->ANGLEround * qh_ZEROdelaunay)
+ facet->upperdelaunay= True;
+ }
+ }
+ if (qh->PRINTstatistics || qh->IStracing || qh->TRACElevel || qh->JOGGLEmax < REALmax) {
+ qh->old_randomdist= qh->RANDOMdist;
+ qh->RANDOMdist= False;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->point != point0) {
+ boolT istrace= False;
+ zinc_(Zdiststat);
+ qh_distplane(qh, vertex->point, facet, &dist);
+ dist= fabs_(dist);
+ zinc_(Znewvertex);
+ wadd_(Wnewvertex, dist);
+ if (dist > wwval_(Wnewvertexmax)) {
+ wwval_(Wnewvertexmax)= dist;
+ if (dist > qh->max_outside) {
+ qh->max_outside= dist; /* used by qh_maxouter(qh) */
+ if (dist > qh->TRACEdist)
+ istrace= True;
+ }
+ }else if (-dist > qh->TRACEdist)
+ istrace= True;
+ if (istrace) {
+ qh_fprintf(qh, qh->ferr, 8016, "qh_setfacetplane: ====== vertex p%d(v%d) increases max_outside to %2.2g for new facet f%d last p%d\n",
+ qh_pointid(qh, vertex->point), vertex->id, dist, facet->id, qh->furthest_id);
+ qh_errprint(qh, "DISTANT", facet, NULL, NULL, NULL);
+ }
+ }
+ }
+ qh->RANDOMdist= qh->old_randomdist;
+ }
+ if (qh->IStracing >= 3) {
+ qh_fprintf(qh, qh->ferr, 8017, "qh_setfacetplane: f%d offset %2.2g normal: ",
+ facet->id, facet->offset);
+ for (k=0; k < qh->hull_dim; k++)
+ qh_fprintf(qh, qh->ferr, 8018, "%2.2g ", facet->normal[k]);
+ qh_fprintf(qh, qh->ferr, 8019, "\n");
+ }
+ if (facet == qh->tracefacet)
+ qh->IStracing= oldtrace;
+} /* setfacetplane */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="sethyperplane_det">-</a>
+
+ qh_sethyperplane_det(qh, dim, rows, point0, toporient, normal, offset, nearzero )
+ given dim X dim array indexed by rows[], one row per point,
+ toporient(flips all signs),
+ and point0 (any row)
+ set normalized hyperplane equation from oriented simplex
+
+ returns:
+ normal (normalized)
+ offset (places point0 on the hyperplane)
+ sets nearzero if hyperplane not through points
+
+ notes:
+ only defined for dim == 2..4
+ rows[] is not modified
+ solves det(P-V_0, V_n-V_0, ..., V_1-V_0)=0, i.e. every point is on hyperplane
+ see Bower & Woodworth, A programmer's geometry, Butterworths 1983.
+
+ derivation of 3-d minnorm
+ Goal: all vertices V_i within qh.one_merge of hyperplane
+ Plan: exactly translate the facet so that V_0 is the origin
+ exactly rotate the facet so that V_1 is on the x-axis and y_2=0.
+ exactly rotate the effective perturbation to only effect n_0
+ this introduces a factor of sqrt(3)
+ n_0 = ((y_2-y_0)*(z_1-z_0) - (z_2-z_0)*(y_1-y_0)) / norm
+ Let M_d be the max coordinate difference
+ Let M_a be the greater of M_d and the max abs. coordinate
+ Let u be machine roundoff and distround be max error for distance computation
+ The max error for n_0 is sqrt(3) u M_a M_d / norm. n_1 is approx. 1 and n_2 is approx. 0
+ The max error for distance of V_1 is sqrt(3) u M_a M_d M_d / norm. Offset=0 at origin
+ Then minnorm = 1.8 u M_a M_d M_d / qh.ONEmerge
+ Note that qh.one_merge is approx. 45.5 u M_a and norm is usually about M_d M_d
+
+ derivation of 4-d minnorm
+ same as above except rotate the facet so that V_1 on x-axis and w_2, y_3, w_3=0
+ [if two vertices fixed on x-axis, can rotate the other two in yzw.]
+ n_0 = det3_(...) = y_2 det2_(z_1, w_1, z_3, w_3) = - y_2 w_1 z_3
+ [all other terms contain at least two factors nearly zero.]
+ The max error for n_0 is sqrt(4) u M_a M_d M_d / norm
+ Then minnorm = 2 u M_a M_d M_d M_d / qh.ONEmerge
+ Note that qh.one_merge is approx. 82 u M_a and norm is usually about M_d M_d M_d
+*/
+void qh_sethyperplane_det(qhT *qh, int dim, coordT **rows, coordT *point0,
+ boolT toporient, coordT *normal, realT *offset, boolT *nearzero) {
+ realT maxround, dist;
+ int i;
+ pointT *point;
+
+
+ if (dim == 2) {
+ normal[0]= dY(1,0);
+ normal[1]= dX(0,1);
+ qh_normalize2(qh, normal, dim, toporient, NULL, NULL);
+ *offset= -(point0[0]*normal[0]+point0[1]*normal[1]);
+ *nearzero= False; /* since nearzero norm => incident points */
+ }else if (dim == 3) {
+ normal[0]= det2_(dY(2,0), dZ(2,0),
+ dY(1,0), dZ(1,0));
+ normal[1]= det2_(dX(1,0), dZ(1,0),
+ dX(2,0), dZ(2,0));
+ normal[2]= det2_(dX(2,0), dY(2,0),
+ dX(1,0), dY(1,0));
+ qh_normalize2(qh, normal, dim, toporient, NULL, NULL);
+ *offset= -(point0[0]*normal[0] + point0[1]*normal[1]
+ + point0[2]*normal[2]);
+ maxround= qh->DISTround;
+ for (i=dim; i--; ) {
+ point= rows[i];
+ if (point != point0) {
+ dist= *offset + (point[0]*normal[0] + point[1]*normal[1]
+ + point[2]*normal[2]);
+ if (dist > maxround || dist < -maxround) {
+ *nearzero= True;
+ break;
+ }
+ }
+ }
+ }else if (dim == 4) {
+ normal[0]= - det3_(dY(2,0), dZ(2,0), dW(2,0),
+ dY(1,0), dZ(1,0), dW(1,0),
+ dY(3,0), dZ(3,0), dW(3,0));
+ normal[1]= det3_(dX(2,0), dZ(2,0), dW(2,0),
+ dX(1,0), dZ(1,0), dW(1,0),
+ dX(3,0), dZ(3,0), dW(3,0));
+ normal[2]= - det3_(dX(2,0), dY(2,0), dW(2,0),
+ dX(1,0), dY(1,0), dW(1,0),
+ dX(3,0), dY(3,0), dW(3,0));
+ normal[3]= det3_(dX(2,0), dY(2,0), dZ(2,0),
+ dX(1,0), dY(1,0), dZ(1,0),
+ dX(3,0), dY(3,0), dZ(3,0));
+ qh_normalize2(qh, normal, dim, toporient, NULL, NULL);
+ *offset= -(point0[0]*normal[0] + point0[1]*normal[1]
+ + point0[2]*normal[2] + point0[3]*normal[3]);
+ maxround= qh->DISTround;
+ for (i=dim; i--; ) {
+ point= rows[i];
+ if (point != point0) {
+ dist= *offset + (point[0]*normal[0] + point[1]*normal[1]
+ + point[2]*normal[2] + point[3]*normal[3]);
+ if (dist > maxround || dist < -maxround) {
+ *nearzero= True;
+ break;
+ }
+ }
+ }
+ }
+ if (*nearzero) {
+ zzinc_(Zminnorm);
+ trace0((qh, qh->ferr, 3, "qh_sethyperplane_det: degenerate norm during p%d.\n", qh->furthest_id));
+ zzinc_(Znearlysingular);
+ }
+} /* sethyperplane_det */
+
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="sethyperplane_gauss">-</a>
+
+ qh_sethyperplane_gauss(qh, dim, rows, point0, toporient, normal, offset, nearzero )
+ given(dim-1) X dim array of rows[i]= V_{i+1} - V_0 (point0)
+ set normalized hyperplane equation from oriented simplex
+
+ returns:
+ normal (normalized)
+ offset (places point0 on the hyperplane)
+
+ notes:
+ if nearzero
+ orientation may be incorrect because of incorrect sign flips in gausselim
+ solves [V_n-V_0,...,V_1-V_0, 0 .. 0 1] * N == [0 .. 0 1]
+ or [V_n-V_0,...,V_1-V_0, 0 .. 0 1] * N == [0]
+ i.e., N is normal to the hyperplane, and the unnormalized
+ distance to [0 .. 1] is either 1 or 0
+
+ design:
+ perform gaussian elimination
+ flip sign for negative values
+ perform back substitution
+ normalize result
+ compute offset
+*/
+void qh_sethyperplane_gauss(qhT *qh, int dim, coordT **rows, pointT *point0,
+ boolT toporient, coordT *normal, coordT *offset, boolT *nearzero) {
+ coordT *pointcoord, *normalcoef;
+ int k;
+ boolT sign= toporient, nearzero2= False;
+
+ qh_gausselim(qh, rows, dim-1, dim, &sign, nearzero);
+ for (k=dim-1; k--; ) {
+ if ((rows[k])[k] < 0)
+ sign ^= 1;
+ }
+ if (*nearzero) {
+ zzinc_(Znearlysingular);
+ trace0((qh, qh->ferr, 4, "qh_sethyperplane_gauss: nearly singular or axis parallel hyperplane during p%d.\n", qh->furthest_id));
+ qh_backnormal(qh, rows, dim-1, dim, sign, normal, &nearzero2);
+ }else {
+ qh_backnormal(qh, rows, dim-1, dim, sign, normal, &nearzero2);
+ if (nearzero2) {
+ zzinc_(Znearlysingular);
+ trace0((qh, qh->ferr, 5, "qh_sethyperplane_gauss: singular or axis parallel hyperplane at normalization during p%d.\n", qh->furthest_id));
+ }
+ }
+ if (nearzero2)
+ *nearzero= True;
+ qh_normalize2(qh, normal, dim, True, NULL, NULL);
+ pointcoord= point0;
+ normalcoef= normal;
+ *offset= -(*pointcoord++ * *normalcoef++);
+ for (k=dim-1; k--; )
+ *offset -= *pointcoord++ * *normalcoef++;
+} /* sethyperplane_gauss */
+
+
+
diff --git a/xs/src/qhull/src/libqhull_r/geom_r.h b/xs/src/qhull/src/libqhull_r/geom_r.h
new file mode 100644
index 000000000..d73e95345
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/geom_r.h
@@ -0,0 +1,184 @@
+/*<html><pre> -<a href="qh-geom_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ geom_r.h
+ header file for geometric routines
+
+ see qh-geom_r.htm and geom_r.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/geom_r.h#3 $$Change: 2079 $
+ $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+*/
+
+#ifndef qhDEFgeom
+#define qhDEFgeom 1
+
+#include "libqhull_r.h"
+
+/* ============ -macros- ======================== */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >--------------------------------</a><a name="fabs_">-</a>
+
+ fabs_(a)
+ returns the absolute value of a
+*/
+#define fabs_( a ) ((( a ) < 0 ) ? -( a ):( a ))
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >--------------------------------</a><a name="fmax_">-</a>
+
+ fmax_(a,b)
+ returns the maximum value of a and b
+*/
+#define fmax_( a,b ) ( ( a ) < ( b ) ? ( b ) : ( a ) )
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >--------------------------------</a><a name="fmin_">-</a>
+
+ fmin_(a,b)
+ returns the minimum value of a and b
+*/
+#define fmin_( a,b ) ( ( a ) > ( b ) ? ( b ) : ( a ) )
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >--------------------------------</a><a name="maximize_">-</a>
+
+ maximize_(maxval, val)
+ set maxval to val if val is greater than maxval
+*/
+#define maximize_( maxval, val ) { if (( maxval ) < ( val )) ( maxval )= ( val ); }
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >--------------------------------</a><a name="minimize_">-</a>
+
+ minimize_(minval, val)
+ set minval to val if val is less than minval
+*/
+#define minimize_( minval, val ) { if (( minval ) > ( val )) ( minval )= ( val ); }
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >--------------------------------</a><a name="det2_">-</a>
+
+ det2_(a1, a2,
+ b1, b2)
+
+ compute a 2-d determinate
+*/
+#define det2_( a1,a2,b1,b2 ) (( a1 )*( b2 ) - ( a2 )*( b1 ))
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >--------------------------------</a><a name="det3_">-</a>
+
+ det3_(a1, a2, a3,
+ b1, b2, b3,
+ c1, c2, c3)
+
+ compute a 3-d determinate
+*/
+#define det3_( a1,a2,a3,b1,b2,b3,c1,c2,c3 ) ( ( a1 )*det2_( b2,b3,c2,c3 ) \
+ - ( b1 )*det2_( a2,a3,c2,c3 ) + ( c1 )*det2_( a2,a3,b2,b3 ) )
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >--------------------------------</a><a name="dX">-</a>
+
+ dX( p1, p2 )
+ dY( p1, p2 )
+ dZ( p1, p2 )
+
+ given two indices into rows[],
+
+ compute the difference between X, Y, or Z coordinates
+*/
+#define dX( p1,p2 ) ( *( rows[p1] ) - *( rows[p2] ))
+#define dY( p1,p2 ) ( *( rows[p1]+1 ) - *( rows[p2]+1 ))
+#define dZ( p1,p2 ) ( *( rows[p1]+2 ) - *( rows[p2]+2 ))
+#define dW( p1,p2 ) ( *( rows[p1]+3 ) - *( rows[p2]+3 ))
+
+/*============= prototypes in alphabetical order, infrequent at end ======= */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void qh_backnormal(qhT *qh, realT **rows, int numrow, int numcol, boolT sign, coordT *normal, boolT *nearzero);
+void qh_distplane(qhT *qh, pointT *point, facetT *facet, realT *dist);
+facetT *qh_findbest(qhT *qh, pointT *point, facetT *startfacet,
+ boolT bestoutside, boolT isnewfacets, boolT noupper,
+ realT *dist, boolT *isoutside, int *numpart);
+facetT *qh_findbesthorizon(qhT *qh, boolT ischeckmax, pointT *point,
+ facetT *startfacet, boolT noupper, realT *bestdist, int *numpart);
+facetT *qh_findbestnew(qhT *qh, pointT *point, facetT *startfacet, realT *dist,
+ boolT bestoutside, boolT *isoutside, int *numpart);
+void qh_gausselim(qhT *qh, realT **rows, int numrow, int numcol, boolT *sign, boolT *nearzero);
+realT qh_getangle(qhT *qh, pointT *vect1, pointT *vect2);
+pointT *qh_getcenter(qhT *qh, setT *vertices);
+pointT *qh_getcentrum(qhT *qh, facetT *facet);
+realT qh_getdistance(qhT *qh, facetT *facet, facetT *neighbor, realT *mindist, realT *maxdist);
+void qh_normalize(qhT *qh, coordT *normal, int dim, boolT toporient);
+void qh_normalize2(qhT *qh, coordT *normal, int dim, boolT toporient,
+ realT *minnorm, boolT *ismin);
+pointT *qh_projectpoint(qhT *qh, pointT *point, facetT *facet, realT dist);
+
+void qh_setfacetplane(qhT *qh, facetT *newfacets);
+void qh_sethyperplane_det(qhT *qh, int dim, coordT **rows, coordT *point0,
+ boolT toporient, coordT *normal, realT *offset, boolT *nearzero);
+void qh_sethyperplane_gauss(qhT *qh, int dim, coordT **rows, pointT *point0,
+ boolT toporient, coordT *normal, coordT *offset, boolT *nearzero);
+boolT qh_sharpnewfacets(qhT *qh);
+
+/*========= infrequently used code in geom2_r.c =============*/
+
+coordT *qh_copypoints(qhT *qh, coordT *points, int numpoints, int dimension);
+void qh_crossproduct(int dim, realT vecA[3], realT vecB[3], realT vecC[3]);
+realT qh_determinant(qhT *qh, realT **rows, int dim, boolT *nearzero);
+realT qh_detjoggle(qhT *qh, pointT *points, int numpoints, int dimension);
+void qh_detroundoff(qhT *qh);
+realT qh_detsimplex(qhT *qh, pointT *apex, setT *points, int dim, boolT *nearzero);
+realT qh_distnorm(int dim, pointT *point, pointT *normal, realT *offsetp);
+realT qh_distround(qhT *qh, int dimension, realT maxabs, realT maxsumabs);
+realT qh_divzero(realT numer, realT denom, realT mindenom1, boolT *zerodiv);
+realT qh_facetarea(qhT *qh, facetT *facet);
+realT qh_facetarea_simplex(qhT *qh, int dim, coordT *apex, setT *vertices,
+ vertexT *notvertex, boolT toporient, coordT *normal, realT *offset);
+pointT *qh_facetcenter(qhT *qh, setT *vertices);
+facetT *qh_findgooddist(qhT *qh, pointT *point, facetT *facetA, realT *distp, facetT **facetlist);
+void qh_getarea(qhT *qh, facetT *facetlist);
+boolT qh_gram_schmidt(qhT *qh, int dim, realT **rows);
+boolT qh_inthresholds(qhT *qh, coordT *normal, realT *angle);
+void qh_joggleinput(qhT *qh);
+realT *qh_maxabsval(realT *normal, int dim);
+setT *qh_maxmin(qhT *qh, pointT *points, int numpoints, int dimension);
+realT qh_maxouter(qhT *qh);
+void qh_maxsimplex(qhT *qh, int dim, setT *maxpoints, pointT *points, int numpoints, setT **simplex);
+realT qh_minabsval(realT *normal, int dim);
+int qh_mindiff(realT *vecA, realT *vecB, int dim);
+boolT qh_orientoutside(qhT *qh, facetT *facet);
+void qh_outerinner(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane);
+coordT qh_pointdist(pointT *point1, pointT *point2, int dim);
+void qh_printmatrix(qhT *qh, FILE *fp, const char *string, realT **rows, int numrow, int numcol);
+void qh_printpoints(qhT *qh, FILE *fp, const char *string, setT *points);
+void qh_projectinput(qhT *qh);
+void qh_projectpoints(qhT *qh, signed char *project, int n, realT *points,
+ int numpoints, int dim, realT *newpoints, int newdim);
+void qh_rotateinput(qhT *qh, realT **rows);
+void qh_rotatepoints(qhT *qh, realT *points, int numpoints, int dim, realT **rows);
+void qh_scaleinput(qhT *qh);
+void qh_scalelast(qhT *qh, coordT *points, int numpoints, int dim, coordT low,
+ coordT high, coordT newhigh);
+void qh_scalepoints(qhT *qh, pointT *points, int numpoints, int dim,
+ realT *newlows, realT *newhighs);
+boolT qh_sethalfspace(qhT *qh, int dim, coordT *coords, coordT **nextp,
+ coordT *normal, coordT *offset, coordT *feasible);
+coordT *qh_sethalfspace_all(qhT *qh, int dim, int count, coordT *halfspaces, pointT *feasible);
+pointT *qh_voronoi_center(qhT *qh, int dim, setT *points);
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /* qhDEFgeom */
+
+
+
diff --git a/xs/src/qhull/src/libqhull_r/global_r.c b/xs/src/qhull/src/libqhull_r/global_r.c
new file mode 100644
index 000000000..eef465ca1
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/global_r.c
@@ -0,0 +1,2100 @@
+
+/*<html><pre> -<a href="qh-globa_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ global_r.c
+ initializes all the globals of the qhull application
+
+ see README
+
+ see libqhull_r.h for qh.globals and function prototypes
+
+ see qhull_ra.h for internal functions
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/global_r.c#16 $$Change: 2066 $
+ $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+ */
+
+#include "qhull_ra.h"
+
+/*========= qh->definition -- globals defined in libqhull_r.h =======================*/
+
+/*-<a href ="qh-globa_r.htm#TOC"
+ >--------------------------------</a><a name="qh_version">-</a>
+
+ qh_version
+ version string by year and date
+ qh_version2 for Unix users and -V
+
+ the revision increases on code changes only
+
+ notes:
+ change date: Changes.txt, Announce.txt, index.htm, README.txt,
+ qhull-news.html, Eudora signatures, CMakeLists.txt
+ change version: README.txt, qh-get.htm, File_id.diz, Makefile.txt, CMakeLists.txt
+ check that CmakeLists @version is the same as qh_version2
+ change year: Copying.txt
+ check download size
+ recompile user_eg_r.c, rbox_r.c, libqhull_r.c, qconvex_r.c, qdelaun_r.c qvoronoi_r.c, qhalf_r.c, testqset_r.c
+*/
+
+const char qh_version[]= "2015.2.r 2016/01/18";
+const char qh_version2[]= "qhull_r 7.2.0 (2015.2.r 2016/01/18)";
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="appendprint">-</a>
+
+ qh_appendprint(qh, printFormat )
+ append printFormat to qh.PRINTout unless already defined
+*/
+void qh_appendprint(qhT *qh, qh_PRINT format) {
+ int i;
+
+ for (i=0; i < qh_PRINTEND; i++) {
+ if (qh->PRINTout[i] == format && format != qh_PRINTqhull)
+ break;
+ if (!qh->PRINTout[i]) {
+ qh->PRINTout[i]= format;
+ break;
+ }
+ }
+} /* appendprint */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="checkflags">-</a>
+
+ qh_checkflags(qh, commandStr, hiddenFlags )
+ errors if commandStr contains hiddenFlags
+ hiddenFlags starts and ends with a space and is space delimited (checked)
+
+ notes:
+ ignores first word (e.g., "qconvex i")
+ use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
+
+ see:
+ qh_initflags() initializes Qhull according to commandStr
+*/
+void qh_checkflags(qhT *qh, char *command, char *hiddenflags) {
+ char *s= command, *t, *chkerr; /* qh_skipfilename is non-const */
+ char key, opt, prevopt;
+ char chkkey[]= " ";
+ char chkopt[]= " ";
+ char chkopt2[]= " ";
+ boolT waserr= False;
+
+ if (*hiddenflags != ' ' || hiddenflags[strlen(hiddenflags)-1] != ' ') {
+ qh_fprintf(qh, qh->ferr, 6026, "qhull error (qh_checkflags): hiddenflags must start and end with a space: \"%s\"", hiddenflags);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (strpbrk(hiddenflags, ",\n\r\t")) {
+ qh_fprintf(qh, qh->ferr, 6027, "qhull error (qh_checkflags): hiddenflags contains commas, newlines, or tabs: \"%s\"", hiddenflags);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ while (*s && !isspace(*s)) /* skip program name */
+ s++;
+ while (*s) {
+ while (*s && isspace(*s))
+ s++;
+ if (*s == '-')
+ s++;
+ if (!*s)
+ break;
+ key = *s++;
+ chkerr = NULL;
+ if (key == 'T' && (*s == 'I' || *s == 'O')) { /* TI or TO 'file name' */
+ s= qh_skipfilename(qh, ++s);
+ continue;
+ }
+ chkkey[1]= key;
+ if (strstr(hiddenflags, chkkey)) {
+ chkerr= chkkey;
+ }else if (isupper(key)) {
+ opt= ' ';
+ prevopt= ' ';
+ chkopt[1]= key;
+ chkopt2[1]= key;
+ while (!chkerr && *s && !isspace(*s)) {
+ opt= *s++;
+ if (isalpha(opt)) {
+ chkopt[2]= opt;
+ if (strstr(hiddenflags, chkopt))
+ chkerr= chkopt;
+ if (prevopt != ' ') {
+ chkopt2[2]= prevopt;
+ chkopt2[3]= opt;
+ if (strstr(hiddenflags, chkopt2))
+ chkerr= chkopt2;
+ }
+ }else if (key == 'Q' && isdigit(opt) && prevopt != 'b'
+ && (prevopt == ' ' || islower(prevopt))) {
+ chkopt[2]= opt;
+ if (strstr(hiddenflags, chkopt))
+ chkerr= chkopt;
+ }else {
+ qh_strtod(s-1, &t);
+ if (s < t)
+ s= t;
+ }
+ prevopt= opt;
+ }
+ }
+ if (chkerr) {
+ *chkerr= '\'';
+ chkerr[strlen(chkerr)-1]= '\'';
+ qh_fprintf(qh, qh->ferr, 6029, "qhull error: option %s is not used with this program.\n It may be used with qhull.\n", chkerr);
+ waserr= True;
+ }
+ }
+ if (waserr)
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+} /* checkflags */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="qh_clear_outputflags">-</a>
+
+ qh_clear_outputflags(qh)
+ Clear output flags for QhullPoints
+*/
+void qh_clear_outputflags(qhT *qh) {
+ int i,k;
+
+ qh->ANNOTATEoutput= False;
+ qh->DOintersections= False;
+ qh->DROPdim= -1;
+ qh->FORCEoutput= False;
+ qh->GETarea= False;
+ qh->GOODpoint= 0;
+ qh->GOODpointp= NULL;
+ qh->GOODthreshold= False;
+ qh->GOODvertex= 0;
+ qh->GOODvertexp= NULL;
+ qh->IStracing= 0;
+ qh->KEEParea= False;
+ qh->KEEPmerge= False;
+ qh->KEEPminArea= REALmax;
+ qh->PRINTcentrums= False;
+ qh->PRINTcoplanar= False;
+ qh->PRINTdots= False;
+ qh->PRINTgood= False;
+ qh->PRINTinner= False;
+ qh->PRINTneighbors= False;
+ qh->PRINTnoplanes= False;
+ qh->PRINToptions1st= False;
+ qh->PRINTouter= False;
+ qh->PRINTprecision= True;
+ qh->PRINTridges= False;
+ qh->PRINTspheres= False;
+ qh->PRINTstatistics= False;
+ qh->PRINTsummary= False;
+ qh->PRINTtransparent= False;
+ qh->SPLITthresholds= False;
+ qh->TRACElevel= 0;
+ qh->TRInormals= False;
+ qh->USEstdout= False;
+ qh->VERIFYoutput= False;
+ for (k=qh->input_dim+1; k--; ) { /* duplicated in qh_initqhull_buffers and qh_clear_outputflags */
+ qh->lower_threshold[k]= -REALmax;
+ qh->upper_threshold[k]= REALmax;
+ qh->lower_bound[k]= -REALmax;
+ qh->upper_bound[k]= REALmax;
+ }
+
+ for (i=0; i < qh_PRINTEND; i++) {
+ qh->PRINTout[i]= qh_PRINTnone;
+ }
+
+ if (!qh->qhull_commandsiz2)
+ qh->qhull_commandsiz2= (int)strlen(qh->qhull_command); /* WARN64 */
+ else {
+ qh->qhull_command[qh->qhull_commandsiz2]= '\0';
+ }
+ if (!qh->qhull_optionsiz2)
+ qh->qhull_optionsiz2= (int)strlen(qh->qhull_options); /* WARN64 */
+ else {
+ qh->qhull_options[qh->qhull_optionsiz2]= '\0';
+ qh->qhull_optionlen= qh_OPTIONline; /* start a new line */
+ }
+} /* clear_outputflags */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="clock">-</a>
+
+ qh_clock()
+ return user CPU time in 100ths (qh_SECtick)
+ only defined for qh_CLOCKtype == 2
+
+ notes:
+ use first value to determine time 0
+ from Stevens '92 8.15
+*/
+unsigned long qh_clock(qhT *qh) {
+
+#if (qh_CLOCKtype == 2)
+ struct tms time;
+ static long clktck; /* initialized first call and never updated */
+ double ratio, cpu;
+ unsigned long ticks;
+
+ if (!clktck) {
+ if ((clktck= sysconf(_SC_CLK_TCK)) < 0) {
+ qh_fprintf(qh, qh->ferr, 6030, "qhull internal error (qh_clock): sysconf() failed. Use qh_CLOCKtype 1 in user.h\n");
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ }
+ if (times(&time) == -1) {
+ qh_fprintf(qh, qh->ferr, 6031, "qhull internal error (qh_clock): times() failed. Use qh_CLOCKtype 1 in user.h\n");
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ ratio= qh_SECticks / (double)clktck;
+ ticks= time.tms_utime * ratio;
+ return ticks;
+#else
+ qh_fprintf(qh, qh->ferr, 6032, "qhull internal error (qh_clock): use qh_CLOCKtype 2 in user.h\n");
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL); /* never returns */
+ return 0;
+#endif
+} /* clock */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="freebuffers">-</a>
+
+ qh_freebuffers()
+ free up global memory buffers
+
+ notes:
+ must match qh_initbuffers()
+*/
+void qh_freebuffers(qhT *qh) {
+
+ trace5((qh, qh->ferr, 5001, "qh_freebuffers: freeing up global memory buffers\n"));
+ /* allocated by qh_initqhull_buffers */
+ qh_memfree(qh, qh->NEARzero, qh->hull_dim * sizeof(realT));
+ qh_memfree(qh, qh->lower_threshold, (qh->input_dim+1) * sizeof(realT));
+ qh_memfree(qh, qh->upper_threshold, (qh->input_dim+1) * sizeof(realT));
+ qh_memfree(qh, qh->lower_bound, (qh->input_dim+1) * sizeof(realT));
+ qh_memfree(qh, qh->upper_bound, (qh->input_dim+1) * sizeof(realT));
+ qh_memfree(qh, qh->gm_matrix, (qh->hull_dim+1) * qh->hull_dim * sizeof(coordT));
+ qh_memfree(qh, qh->gm_row, (qh->hull_dim+1) * sizeof(coordT *));
+ qh->NEARzero= qh->lower_threshold= qh->upper_threshold= NULL;
+ qh->lower_bound= qh->upper_bound= NULL;
+ qh->gm_matrix= NULL;
+ qh->gm_row= NULL;
+ qh_setfree(qh, &qh->other_points);
+ qh_setfree(qh, &qh->del_vertices);
+ qh_setfree(qh, &qh->coplanarfacetset);
+ if (qh->line) /* allocated by qh_readinput, freed if no error */
+ qh_free(qh->line);
+ if (qh->half_space)
+ qh_free(qh->half_space);
+ if (qh->temp_malloc)
+ qh_free(qh->temp_malloc);
+ if (qh->feasible_point) /* allocated by qh_readfeasible */
+ qh_free(qh->feasible_point);
+ if (qh->feasible_string) /* allocated by qh_initflags */
+ qh_free(qh->feasible_string);
+ qh->line= qh->feasible_string= NULL;
+ qh->half_space= qh->feasible_point= qh->temp_malloc= NULL;
+ /* usually allocated by qh_readinput */
+ if (qh->first_point && qh->POINTSmalloc) {
+ qh_free(qh->first_point);
+ qh->first_point= NULL;
+ }
+ if (qh->input_points && qh->input_malloc) { /* set by qh_joggleinput */
+ qh_free(qh->input_points);
+ qh->input_points= NULL;
+ }
+ trace5((qh, qh->ferr, 5002, "qh_freebuffers: finished\n"));
+} /* freebuffers */
+
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="freebuild">-</a>
+
+ qh_freebuild(qh, allmem )
+ free global memory used by qh_initbuild and qh_buildhull
+ if !allmem,
+ does not free short memory (e.g., facetT, freed by qh_memfreeshort)
+
+ design:
+ free centrums
+ free each vertex
+ mark unattached ridges
+ for each facet
+ free ridges
+ free outside set, coplanar set, neighbor set, ridge set, vertex set
+ free facet
+ free hash table
+ free interior point
+ free merge set
+ free temporary sets
+*/
+void qh_freebuild(qhT *qh, boolT allmem) {
+ facetT *facet;
+ vertexT *vertex;
+ ridgeT *ridge, **ridgep;
+ mergeT *merge, **mergep;
+
+ trace1((qh, qh->ferr, 1005, "qh_freebuild: free memory from qh_inithull and qh_buildhull\n"));
+ if (qh->del_vertices)
+ qh_settruncate(qh, qh->del_vertices, 0);
+ if (allmem) {
+ while ((vertex= qh->vertex_list)) {
+ if (vertex->next)
+ qh_delvertex(qh, vertex);
+ else {
+ qh_memfree(qh, vertex, (int)sizeof(vertexT));
+ qh->newvertex_list= qh->vertex_list= NULL;
+ }
+ }
+ }else if (qh->VERTEXneighbors) {
+ FORALLvertices
+ qh_setfreelong(qh, &(vertex->neighbors));
+ }
+ qh->VERTEXneighbors= False;
+ qh->GOODclosest= NULL;
+ if (allmem) {
+ FORALLfacets {
+ FOREACHridge_(facet->ridges)
+ ridge->seen= False;
+ }
+ FORALLfacets {
+ if (facet->visible) {
+ FOREACHridge_(facet->ridges) {
+ if (!otherfacet_(ridge, facet)->visible)
+ ridge->seen= True; /* an unattached ridge */
+ }
+ }
+ }
+ while ((facet= qh->facet_list)) {
+ FOREACHridge_(facet->ridges) {
+ if (ridge->seen) {
+ qh_setfree(qh, &(ridge->vertices));
+ qh_memfree(qh, ridge, (int)sizeof(ridgeT));
+ }else
+ ridge->seen= True;
+ }
+ qh_setfree(qh, &(facet->outsideset));
+ qh_setfree(qh, &(facet->coplanarset));
+ qh_setfree(qh, &(facet->neighbors));
+ qh_setfree(qh, &(facet->ridges));
+ qh_setfree(qh, &(facet->vertices));
+ if (facet->next)
+ qh_delfacet(qh, facet);
+ else {
+ qh_memfree(qh, facet, (int)sizeof(facetT));
+ qh->visible_list= qh->newfacet_list= qh->facet_list= NULL;
+ }
+ }
+ }else {
+ FORALLfacets {
+ qh_setfreelong(qh, &(facet->outsideset));
+ qh_setfreelong(qh, &(facet->coplanarset));
+ if (!facet->simplicial) {
+ qh_setfreelong(qh, &(facet->neighbors));
+ qh_setfreelong(qh, &(facet->ridges));
+ qh_setfreelong(qh, &(facet->vertices));
+ }
+ }
+ }
+ qh_setfree(qh, &(qh->hash_table));
+ qh_memfree(qh, qh->interior_point, qh->normal_size);
+ qh->interior_point= NULL;
+ FOREACHmerge_(qh->facet_mergeset) /* usually empty */
+ qh_memfree(qh, merge, (int)sizeof(mergeT));
+ qh->facet_mergeset= NULL; /* temp set */
+ qh->degen_mergeset= NULL; /* temp set */
+ qh_settempfree_all(qh);
+} /* freebuild */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="freeqhull">-</a>
+
+ qh_freeqhull(qh, allmem )
+
+ free global memory and set qhT to 0
+ if !allmem,
+ does not free short memory (freed by qh_memfreeshort unless qh_NOmem)
+
+notes:
+ sets qh.NOerrexit in case caller forgets to
+ Does not throw errors
+
+see:
+ see qh_initqhull_start2()
+ For libqhull_r, qhstatT is part of qhT
+
+design:
+ free global and temporary memory from qh_initbuild and qh_buildhull
+ free buffers
+*/
+void qh_freeqhull(qhT *qh, boolT allmem) {
+
+ qh->NOerrexit= True; /* no more setjmp since called at exit and ~QhullQh */
+ trace1((qh, qh->ferr, 1006, "qh_freeqhull: free global memory\n"));
+ qh_freebuild(qh, allmem);
+ qh_freebuffers(qh);
+ /* memset is the same in qh_freeqhull() and qh_initqhull_start2() */
+ memset((char *)qh, 0, sizeof(qhT)-sizeof(qhmemT)-sizeof(qhstatT));
+ qh->NOerrexit= True;
+} /* freeqhull2 */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="init_A">-</a>
+
+ qh_init_A(qh, infile, outfile, errfile, argc, argv )
+ initialize memory and stdio files
+ convert input options to option string (qh.qhull_command)
+
+ notes:
+ infile may be NULL if qh_readpoints() is not called
+
+ errfile should always be defined. It is used for reporting
+ errors. outfile is used for output and format options.
+
+ argc/argv may be 0/NULL
+
+ called before error handling initialized
+ qh_errexit() may not be used
+*/
+void qh_init_A(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]) {
+ qh_meminit(qh, errfile);
+ qh_initqhull_start(qh, infile, outfile, errfile);
+ qh_init_qhull_command(qh, argc, argv);
+} /* init_A */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="init_B">-</a>
+
+ qh_init_B(qh, points, numpoints, dim, ismalloc )
+ initialize globals for points array
+
+ points has numpoints dim-dimensional points
+ points[0] is the first coordinate of the first point
+ points[1] is the second coordinate of the first point
+ points[dim] is the first coordinate of the second point
+
+ ismalloc=True
+ Qhull will call qh_free(points) on exit or input transformation
+ ismalloc=False
+ Qhull will allocate a new point array if needed for input transformation
+
+ qh.qhull_command
+ is the option string.
+ It is defined by qh_init_B(), qh_qhull_command(), or qh_initflags
+
+ returns:
+ if qh.PROJECTinput or (qh.DELAUNAY and qh.PROJECTdelaunay)
+ projects the input to a new point array
+
+ if qh.DELAUNAY,
+ qh.hull_dim is increased by one
+ if qh.ATinfinity,
+ qh_projectinput adds point-at-infinity for Delaunay tri.
+
+ if qh.SCALEinput
+ changes the upper and lower bounds of the input, see qh_scaleinput(qh)
+
+ if qh.ROTATEinput
+ rotates the input by a random rotation, see qh_rotateinput()
+ if qh.DELAUNAY
+ rotates about the last coordinate
+
+ notes:
+ called after points are defined
+ qh_errexit() may be used
+*/
+void qh_init_B(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc) {
+ qh_initqhull_globals(qh, points, numpoints, dim, ismalloc);
+ if (qh->qhmem.LASTsize == 0)
+ qh_initqhull_mem(qh);
+ /* mem_r.c and qset_r.c are initialized */
+ qh_initqhull_buffers(qh);
+ qh_initthresholds(qh, qh->qhull_command);
+ if (qh->PROJECTinput || (qh->DELAUNAY && qh->PROJECTdelaunay))
+ qh_projectinput(qh);
+ if (qh->SCALEinput)
+ qh_scaleinput(qh);
+ if (qh->ROTATErandom >= 0) {
+ qh_randommatrix(qh, qh->gm_matrix, qh->hull_dim, qh->gm_row);
+ if (qh->DELAUNAY) {
+ int k, lastk= qh->hull_dim-1;
+ for (k=0; k < lastk; k++) {
+ qh->gm_row[k][lastk]= 0.0;
+ qh->gm_row[lastk][k]= 0.0;
+ }
+ qh->gm_row[lastk][lastk]= 1.0;
+ }
+ qh_gram_schmidt(qh, qh->hull_dim, qh->gm_row);
+ qh_rotateinput(qh, qh->gm_row);
+ }
+} /* init_B */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="init_qhull_command">-</a>
+
+ qh_init_qhull_command(qh, argc, argv )
+ build qh.qhull_command from argc/argv
+ Calls qh_exit if qhull_command is too short
+
+ returns:
+ a space-delimited string of options (just as typed)
+
+ notes:
+ makes option string easy to input and output
+
+ argc/argv may be 0/NULL
+*/
+void qh_init_qhull_command(qhT *qh, int argc, char *argv[]) {
+
+ if (!qh_argv_to_command(argc, argv, qh->qhull_command, (int)sizeof(qh->qhull_command))){
+ /* Assumes qh.ferr is defined. */
+ qh_fprintf(qh, qh->ferr, 6033, "qhull input error: more than %d characters in command line.\n",
+ (int)sizeof(qh->qhull_command));
+ qh_exit(qh_ERRinput); /* error reported, can not use qh_errexit */
+ }
+} /* init_qhull_command */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="initflags">-</a>
+
+ qh_initflags(qh, commandStr )
+ set flags and initialized constants from commandStr
+ calls qh_exit() if qh->NOerrexit
+
+ returns:
+ sets qh.qhull_command to command if needed
+
+ notes:
+ ignores first word (e.g., "qhull d")
+ use qh_strtol/strtod since strtol/strtod may or may not skip trailing spaces
+
+ see:
+ qh_initthresholds() continues processing of 'Pdn' and 'PDn'
+ 'prompt' in unix_r.c for documentation
+
+ design:
+ for each space-delimited option group
+ if top-level option
+ check syntax
+ append appropriate option to option string
+ set appropriate global variable or append printFormat to print options
+ else
+ for each sub-option
+ check syntax
+ append appropriate option to option string
+ set appropriate global variable or append printFormat to print options
+*/
+void qh_initflags(qhT *qh, char *command) {
+ int k, i, lastproject;
+ char *s= command, *t, *prev_s, *start, key;
+ boolT isgeom= False, wasproject;
+ realT r;
+
+ if(qh->NOerrexit){
+ qh_fprintf(qh, qh->ferr, 6245, "qhull initflags error: qh.NOerrexit was not cleared before calling qh_initflags(). It should be cleared after setjmp(). Exit qhull.");
+ qh_exit(6245);
+ }
+ if (command <= &qh->qhull_command[0] || command > &qh->qhull_command[0] + sizeof(qh->qhull_command)) {
+ if (command != &qh->qhull_command[0]) {
+ *qh->qhull_command= '\0';
+ strncat(qh->qhull_command, command, sizeof(qh->qhull_command)-strlen(qh->qhull_command)-1);
+ }
+ while (*s && !isspace(*s)) /* skip program name */
+ s++;
+ }
+ while (*s) {
+ while (*s && isspace(*s))
+ s++;
+ if (*s == '-')
+ s++;
+ if (!*s)
+ break;
+ prev_s= s;
+ switch (*s++) {
+ case 'd':
+ qh_option(qh, "delaunay", NULL, NULL);
+ qh->DELAUNAY= True;
+ break;
+ case 'f':
+ qh_option(qh, "facets", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTfacets);
+ break;
+ case 'i':
+ qh_option(qh, "incidence", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTincidences);
+ break;
+ case 'm':
+ qh_option(qh, "mathematica", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTmathematica);
+ break;
+ case 'n':
+ qh_option(qh, "normals", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTnormals);
+ break;
+ case 'o':
+ qh_option(qh, "offFile", NULL, NULL);
+ qh_appendprint(qh, qh_PRINToff);
+ break;
+ case 'p':
+ qh_option(qh, "points", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTpoints);
+ break;
+ case 's':
+ qh_option(qh, "summary", NULL, NULL);
+ qh->PRINTsummary= True;
+ break;
+ case 'v':
+ qh_option(qh, "voronoi", NULL, NULL);
+ qh->VORONOI= True;
+ qh->DELAUNAY= True;
+ break;
+ case 'A':
+ if (!isdigit(*s) && *s != '.' && *s != '-')
+ qh_fprintf(qh, qh->ferr, 7002, "qhull warning: no maximum cosine angle given for option 'An'. Ignored.\n");
+ else {
+ if (*s == '-') {
+ qh->premerge_cos= -qh_strtod(s, &s);
+ qh_option(qh, "Angle-premerge-", NULL, &qh->premerge_cos);
+ qh->PREmerge= True;
+ }else {
+ qh->postmerge_cos= qh_strtod(s, &s);
+ qh_option(qh, "Angle-postmerge", NULL, &qh->postmerge_cos);
+ qh->POSTmerge= True;
+ }
+ qh->MERGING= True;
+ }
+ break;
+ case 'C':
+ if (!isdigit(*s) && *s != '.' && *s != '-')
+ qh_fprintf(qh, qh->ferr, 7003, "qhull warning: no centrum radius given for option 'Cn'. Ignored.\n");
+ else {
+ if (*s == '-') {
+ qh->premerge_centrum= -qh_strtod(s, &s);
+ qh_option(qh, "Centrum-premerge-", NULL, &qh->premerge_centrum);
+ qh->PREmerge= True;
+ }else {
+ qh->postmerge_centrum= qh_strtod(s, &s);
+ qh_option(qh, "Centrum-postmerge", NULL, &qh->postmerge_centrum);
+ qh->POSTmerge= True;
+ }
+ qh->MERGING= True;
+ }
+ break;
+ case 'E':
+ if (*s == '-')
+ qh_fprintf(qh, qh->ferr, 7004, "qhull warning: negative maximum roundoff given for option 'An'. Ignored.\n");
+ else if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 7005, "qhull warning: no maximum roundoff given for option 'En'. Ignored.\n");
+ else {
+ qh->DISTround= qh_strtod(s, &s);
+ qh_option(qh, "Distance-roundoff", NULL, &qh->DISTround);
+ qh->SETroundoff= True;
+ }
+ break;
+ case 'H':
+ start= s;
+ qh->HALFspace= True;
+ qh_strtod(s, &t);
+ while (t > s) {
+ if (*t && !isspace(*t)) {
+ if (*t == ',')
+ t++;
+ else
+ qh_fprintf(qh, qh->ferr, 7006, "qhull warning: origin for Halfspace intersection should be 'Hn,n,n,...'\n");
+ }
+ s= t;
+ qh_strtod(s, &t);
+ }
+ if (start < t) {
+ if (!(qh->feasible_string= (char*)calloc((size_t)(t-start+1), (size_t)1))) {
+ qh_fprintf(qh, qh->ferr, 6034, "qhull error: insufficient memory for 'Hn,n,n'\n");
+ qh_errexit(qh, qh_ERRmem, NULL, NULL);
+ }
+ strncpy(qh->feasible_string, start, (size_t)(t-start));
+ qh_option(qh, "Halfspace-about", NULL, NULL);
+ qh_option(qh, qh->feasible_string, NULL, NULL);
+ }else
+ qh_option(qh, "Halfspace", NULL, NULL);
+ break;
+ case 'R':
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 7007, "qhull warning: missing random perturbation for option 'Rn'. Ignored\n");
+ else {
+ qh->RANDOMfactor= qh_strtod(s, &s);
+ qh_option(qh, "Random_perturb", NULL, &qh->RANDOMfactor);
+ qh->RANDOMdist= True;
+ }
+ break;
+ case 'V':
+ if (!isdigit(*s) && *s != '-')
+ qh_fprintf(qh, qh->ferr, 7008, "qhull warning: missing visible distance for option 'Vn'. Ignored\n");
+ else {
+ qh->MINvisible= qh_strtod(s, &s);
+ qh_option(qh, "Visible", NULL, &qh->MINvisible);
+ }
+ break;
+ case 'U':
+ if (!isdigit(*s) && *s != '-')
+ qh_fprintf(qh, qh->ferr, 7009, "qhull warning: missing coplanar distance for option 'Un'. Ignored\n");
+ else {
+ qh->MAXcoplanar= qh_strtod(s, &s);
+ qh_option(qh, "U-coplanar", NULL, &qh->MAXcoplanar);
+ }
+ break;
+ case 'W':
+ if (*s == '-')
+ qh_fprintf(qh, qh->ferr, 7010, "qhull warning: negative outside width for option 'Wn'. Ignored.\n");
+ else if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 7011, "qhull warning: missing outside width for option 'Wn'. Ignored\n");
+ else {
+ qh->MINoutside= qh_strtod(s, &s);
+ qh_option(qh, "W-outside", NULL, &qh->MINoutside);
+ qh->APPROXhull= True;
+ }
+ break;
+ /************ sub menus ***************/
+ case 'F':
+ while (*s && !isspace(*s)) {
+ switch (*s++) {
+ case 'a':
+ qh_option(qh, "Farea", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTarea);
+ qh->GETarea= True;
+ break;
+ case 'A':
+ qh_option(qh, "FArea-total", NULL, NULL);
+ qh->GETarea= True;
+ break;
+ case 'c':
+ qh_option(qh, "Fcoplanars", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTcoplanars);
+ break;
+ case 'C':
+ qh_option(qh, "FCentrums", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTcentrums);
+ break;
+ case 'd':
+ qh_option(qh, "Fd-cdd-in", NULL, NULL);
+ qh->CDDinput= True;
+ break;
+ case 'D':
+ qh_option(qh, "FD-cdd-out", NULL, NULL);
+ qh->CDDoutput= True;
+ break;
+ case 'F':
+ qh_option(qh, "FFacets-xridge", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTfacets_xridge);
+ break;
+ case 'i':
+ qh_option(qh, "Finner", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTinner);
+ break;
+ case 'I':
+ qh_option(qh, "FIDs", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTids);
+ break;
+ case 'm':
+ qh_option(qh, "Fmerges", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTmerges);
+ break;
+ case 'M':
+ qh_option(qh, "FMaple", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTmaple);
+ break;
+ case 'n':
+ qh_option(qh, "Fneighbors", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTneighbors);
+ break;
+ case 'N':
+ qh_option(qh, "FNeighbors-vertex", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTvneighbors);
+ break;
+ case 'o':
+ qh_option(qh, "Fouter", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTouter);
+ break;
+ case 'O':
+ if (qh->PRINToptions1st) {
+ qh_option(qh, "FOptions", NULL, NULL);
+ qh_appendprint(qh, qh_PRINToptions);
+ }else
+ qh->PRINToptions1st= True;
+ break;
+ case 'p':
+ qh_option(qh, "Fpoint-intersect", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTpointintersect);
+ break;
+ case 'P':
+ qh_option(qh, "FPoint-nearest", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTpointnearest);
+ break;
+ case 'Q':
+ qh_option(qh, "FQhull", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTqhull);
+ break;
+ case 's':
+ qh_option(qh, "Fsummary", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTsummary);
+ break;
+ case 'S':
+ qh_option(qh, "FSize", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTsize);
+ qh->GETarea= True;
+ break;
+ case 't':
+ qh_option(qh, "Ftriangles", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTtriangles);
+ break;
+ case 'v':
+ /* option set in qh_initqhull_globals */
+ qh_appendprint(qh, qh_PRINTvertices);
+ break;
+ case 'V':
+ qh_option(qh, "FVertex-average", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTaverage);
+ break;
+ case 'x':
+ qh_option(qh, "Fxtremes", NULL, NULL);
+ qh_appendprint(qh, qh_PRINTextremes);
+ break;
+ default:
+ s--;
+ qh_fprintf(qh, qh->ferr, 7012, "qhull warning: unknown 'F' output option %c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ }
+ break;
+ case 'G':
+ isgeom= True;
+ qh_appendprint(qh, qh_PRINTgeom);
+ while (*s && !isspace(*s)) {
+ switch (*s++) {
+ case 'a':
+ qh_option(qh, "Gall-points", NULL, NULL);
+ qh->PRINTdots= True;
+ break;
+ case 'c':
+ qh_option(qh, "Gcentrums", NULL, NULL);
+ qh->PRINTcentrums= True;
+ break;
+ case 'h':
+ qh_option(qh, "Gintersections", NULL, NULL);
+ qh->DOintersections= True;
+ break;
+ case 'i':
+ qh_option(qh, "Ginner", NULL, NULL);
+ qh->PRINTinner= True;
+ break;
+ case 'n':
+ qh_option(qh, "Gno-planes", NULL, NULL);
+ qh->PRINTnoplanes= True;
+ break;
+ case 'o':
+ qh_option(qh, "Gouter", NULL, NULL);
+ qh->PRINTouter= True;
+ break;
+ case 'p':
+ qh_option(qh, "Gpoints", NULL, NULL);
+ qh->PRINTcoplanar= True;
+ break;
+ case 'r':
+ qh_option(qh, "Gridges", NULL, NULL);
+ qh->PRINTridges= True;
+ break;
+ case 't':
+ qh_option(qh, "Gtransparent", NULL, NULL);
+ qh->PRINTtransparent= True;
+ break;
+ case 'v':
+ qh_option(qh, "Gvertices", NULL, NULL);
+ qh->PRINTspheres= True;
+ break;
+ case 'D':
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 6035, "qhull input error: missing dimension for option 'GDn'\n");
+ else {
+ if (qh->DROPdim >= 0)
+ qh_fprintf(qh, qh->ferr, 7013, "qhull warning: can only drop one dimension. Previous 'GD%d' ignored\n",
+ qh->DROPdim);
+ qh->DROPdim= qh_strtol(s, &s);
+ qh_option(qh, "GDrop-dim", &qh->DROPdim, NULL);
+ }
+ break;
+ default:
+ s--;
+ qh_fprintf(qh, qh->ferr, 7014, "qhull warning: unknown 'G' print option %c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ }
+ break;
+ case 'P':
+ while (*s && !isspace(*s)) {
+ switch (*s++) {
+ case 'd': case 'D': /* see qh_initthresholds() */
+ key= s[-1];
+ i= qh_strtol(s, &s);
+ r= 0;
+ if (*s == ':') {
+ s++;
+ r= qh_strtod(s, &s);
+ }
+ if (key == 'd')
+ qh_option(qh, "Pdrop-facets-dim-less", &i, &r);
+ else
+ qh_option(qh, "PDrop-facets-dim-more", &i, &r);
+ break;
+ case 'g':
+ qh_option(qh, "Pgood-facets", NULL, NULL);
+ qh->PRINTgood= True;
+ break;
+ case 'G':
+ qh_option(qh, "PGood-facet-neighbors", NULL, NULL);
+ qh->PRINTneighbors= True;
+ break;
+ case 'o':
+ qh_option(qh, "Poutput-forced", NULL, NULL);
+ qh->FORCEoutput= True;
+ break;
+ case 'p':
+ qh_option(qh, "Pprecision-ignore", NULL, NULL);
+ qh->PRINTprecision= False;
+ break;
+ case 'A':
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 6036, "qhull input error: missing facet count for keep area option 'PAn'\n");
+ else {
+ qh->KEEParea= qh_strtol(s, &s);
+ qh_option(qh, "PArea-keep", &qh->KEEParea, NULL);
+ qh->GETarea= True;
+ }
+ break;
+ case 'F':
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 6037, "qhull input error: missing facet area for option 'PFn'\n");
+ else {
+ qh->KEEPminArea= qh_strtod(s, &s);
+ qh_option(qh, "PFacet-area-keep", NULL, &qh->KEEPminArea);
+ qh->GETarea= True;
+ }
+ break;
+ case 'M':
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 6038, "qhull input error: missing merge count for option 'PMn'\n");
+ else {
+ qh->KEEPmerge= qh_strtol(s, &s);
+ qh_option(qh, "PMerge-keep", &qh->KEEPmerge, NULL);
+ }
+ break;
+ default:
+ s--;
+ qh_fprintf(qh, qh->ferr, 7015, "qhull warning: unknown 'P' print option %c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ }
+ break;
+ case 'Q':
+ lastproject= -1;
+ while (*s && !isspace(*s)) {
+ switch (*s++) {
+ case 'b': case 'B': /* handled by qh_initthresholds */
+ key= s[-1];
+ if (key == 'b' && *s == 'B') {
+ s++;
+ r= qh_DEFAULTbox;
+ qh->SCALEinput= True;
+ qh_option(qh, "QbBound-unit-box", NULL, &r);
+ break;
+ }
+ if (key == 'b' && *s == 'b') {
+ s++;
+ qh->SCALElast= True;
+ qh_option(qh, "Qbbound-last", NULL, NULL);
+ break;
+ }
+ k= qh_strtol(s, &s);
+ r= 0.0;
+ wasproject= False;
+ if (*s == ':') {
+ s++;
+ if ((r= qh_strtod(s, &s)) == 0.0) {
+ t= s; /* need true dimension for memory allocation */
+ while (*t && !isspace(*t)) {
+ if (toupper(*t++) == 'B'
+ && k == qh_strtol(t, &t)
+ && *t++ == ':'
+ && qh_strtod(t, &t) == 0.0) {
+ qh->PROJECTinput++;
+ trace2((qh, qh->ferr, 2004, "qh_initflags: project dimension %d\n", k));
+ qh_option(qh, "Qb-project-dim", &k, NULL);
+ wasproject= True;
+ lastproject= k;
+ break;
+ }
+ }
+ }
+ }
+ if (!wasproject) {
+ if (lastproject == k && r == 0.0)
+ lastproject= -1; /* doesn't catch all possible sequences */
+ else if (key == 'b') {
+ qh->SCALEinput= True;
+ if (r == 0.0)
+ r= -qh_DEFAULTbox;
+ qh_option(qh, "Qbound-dim-low", &k, &r);
+ }else {
+ qh->SCALEinput= True;
+ if (r == 0.0)
+ r= qh_DEFAULTbox;
+ qh_option(qh, "QBound-dim-high", &k, &r);
+ }
+ }
+ break;
+ case 'c':
+ qh_option(qh, "Qcoplanar-keep", NULL, NULL);
+ qh->KEEPcoplanar= True;
+ break;
+ case 'f':
+ qh_option(qh, "Qfurthest-outside", NULL, NULL);
+ qh->BESToutside= True;
+ break;
+ case 'g':
+ qh_option(qh, "Qgood-facets-only", NULL, NULL);
+ qh->ONLYgood= True;
+ break;
+ case 'i':
+ qh_option(qh, "Qinterior-keep", NULL, NULL);
+ qh->KEEPinside= True;
+ break;
+ case 'm':
+ qh_option(qh, "Qmax-outside-only", NULL, NULL);
+ qh->ONLYmax= True;
+ break;
+ case 'r':
+ qh_option(qh, "Qrandom-outside", NULL, NULL);
+ qh->RANDOMoutside= True;
+ break;
+ case 's':
+ qh_option(qh, "Qsearch-initial-simplex", NULL, NULL);
+ qh->ALLpoints= True;
+ break;
+ case 't':
+ qh_option(qh, "Qtriangulate", NULL, NULL);
+ qh->TRIangulate= True;
+ break;
+ case 'T':
+ qh_option(qh, "QTestPoints", NULL, NULL);
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 6039, "qhull input error: missing number of test points for option 'QTn'\n");
+ else {
+ qh->TESTpoints= qh_strtol(s, &s);
+ qh_option(qh, "QTestPoints", &qh->TESTpoints, NULL);
+ }
+ break;
+ case 'u':
+ qh_option(qh, "QupperDelaunay", NULL, NULL);
+ qh->UPPERdelaunay= True;
+ break;
+ case 'v':
+ qh_option(qh, "Qvertex-neighbors-convex", NULL, NULL);
+ qh->TESTvneighbors= True;
+ break;
+ case 'x':
+ qh_option(qh, "Qxact-merge", NULL, NULL);
+ qh->MERGEexact= True;
+ break;
+ case 'z':
+ qh_option(qh, "Qz-infinity-point", NULL, NULL);
+ qh->ATinfinity= True;
+ break;
+ case '0':
+ qh_option(qh, "Q0-no-premerge", NULL, NULL);
+ qh->NOpremerge= True;
+ break;
+ case '1':
+ if (!isdigit(*s)) {
+ qh_option(qh, "Q1-no-angle-sort", NULL, NULL);
+ qh->ANGLEmerge= False;
+ break;
+ }
+ switch (*s++) {
+ case '0':
+ qh_option(qh, "Q10-no-narrow", NULL, NULL);
+ qh->NOnarrow= True;
+ break;
+ case '1':
+ qh_option(qh, "Q11-trinormals Qtriangulate", NULL, NULL);
+ qh->TRInormals= True;
+ qh->TRIangulate= True;
+ break;
+ case '2':
+ qh_option(qh, "Q12-no-wide-dup", NULL, NULL);
+ qh->NOwide= True;
+ break;
+ default:
+ s--;
+ qh_fprintf(qh, qh->ferr, 7016, "qhull warning: unknown 'Q' qhull option 1%c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ break;
+ case '2':
+ qh_option(qh, "Q2-no-merge-independent", NULL, NULL);
+ qh->MERGEindependent= False;
+ goto LABELcheckdigit;
+ break; /* no warnings */
+ case '3':
+ qh_option(qh, "Q3-no-merge-vertices", NULL, NULL);
+ qh->MERGEvertices= False;
+ LABELcheckdigit:
+ if (isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 7017, "qhull warning: can not follow '1', '2', or '3' with a digit. '%c' skipped.\n",
+ *s++);
+ break;
+ case '4':
+ qh_option(qh, "Q4-avoid-old-into-new", NULL, NULL);
+ qh->AVOIDold= True;
+ break;
+ case '5':
+ qh_option(qh, "Q5-no-check-outer", NULL, NULL);
+ qh->SKIPcheckmax= True;
+ break;
+ case '6':
+ qh_option(qh, "Q6-no-concave-merge", NULL, NULL);
+ qh->SKIPconvex= True;
+ break;
+ case '7':
+ qh_option(qh, "Q7-no-breadth-first", NULL, NULL);
+ qh->VIRTUALmemory= True;
+ break;
+ case '8':
+ qh_option(qh, "Q8-no-near-inside", NULL, NULL);
+ qh->NOnearinside= True;
+ break;
+ case '9':
+ qh_option(qh, "Q9-pick-furthest", NULL, NULL);
+ qh->PICKfurthest= True;
+ break;
+ case 'G':
+ i= qh_strtol(s, &t);
+ if (qh->GOODpoint)
+ qh_fprintf(qh, qh->ferr, 7018, "qhull warning: good point already defined for option 'QGn'. Ignored\n");
+ else if (s == t)
+ qh_fprintf(qh, qh->ferr, 7019, "qhull warning: missing good point id for option 'QGn'. Ignored\n");
+ else if (i < 0 || *s == '-') {
+ qh->GOODpoint= i-1;
+ qh_option(qh, "QGood-if-dont-see-point", &i, NULL);
+ }else {
+ qh->GOODpoint= i+1;
+ qh_option(qh, "QGood-if-see-point", &i, NULL);
+ }
+ s= t;
+ break;
+ case 'J':
+ if (!isdigit(*s) && *s != '-')
+ qh->JOGGLEmax= 0.0;
+ else {
+ qh->JOGGLEmax= (realT) qh_strtod(s, &s);
+ qh_option(qh, "QJoggle", NULL, &qh->JOGGLEmax);
+ }
+ break;
+ case 'R':
+ if (!isdigit(*s) && *s != '-')
+ qh_fprintf(qh, qh->ferr, 7020, "qhull warning: missing random seed for option 'QRn'. Ignored\n");
+ else {
+ qh->ROTATErandom= i= qh_strtol(s, &s);
+ if (i > 0)
+ qh_option(qh, "QRotate-id", &i, NULL );
+ else if (i < -1)
+ qh_option(qh, "QRandom-seed", &i, NULL );
+ }
+ break;
+ case 'V':
+ i= qh_strtol(s, &t);
+ if (qh->GOODvertex)
+ qh_fprintf(qh, qh->ferr, 7021, "qhull warning: good vertex already defined for option 'QVn'. Ignored\n");
+ else if (s == t)
+ qh_fprintf(qh, qh->ferr, 7022, "qhull warning: no good point id given for option 'QVn'. Ignored\n");
+ else if (i < 0) {
+ qh->GOODvertex= i - 1;
+ qh_option(qh, "QV-good-facets-not-point", &i, NULL);
+ }else {
+ qh_option(qh, "QV-good-facets-point", &i, NULL);
+ qh->GOODvertex= i + 1;
+ }
+ s= t;
+ break;
+ default:
+ s--;
+ qh_fprintf(qh, qh->ferr, 7023, "qhull warning: unknown 'Q' qhull option %c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ }
+ break;
+ case 'T':
+ while (*s && !isspace(*s)) {
+ if (isdigit(*s) || *s == '-')
+ qh->IStracing= qh_strtol(s, &s);
+ else switch (*s++) {
+ case 'a':
+ qh_option(qh, "Tannotate-output", NULL, NULL);
+ qh->ANNOTATEoutput= True;
+ break;
+ case 'c':
+ qh_option(qh, "Tcheck-frequently", NULL, NULL);
+ qh->CHECKfrequently= True;
+ break;
+ case 's':
+ qh_option(qh, "Tstatistics", NULL, NULL);
+ qh->PRINTstatistics= True;
+ break;
+ case 'v':
+ qh_option(qh, "Tverify", NULL, NULL);
+ qh->VERIFYoutput= True;
+ break;
+ case 'z':
+ if (qh->ferr == qh_FILEstderr) {
+ /* The C++ interface captures the output in qh_fprint_qhull() */
+ qh_option(qh, "Tz-stdout", NULL, NULL);
+ qh->USEstdout= True;
+ }else if (!qh->fout)
+ qh_fprintf(qh, qh->ferr, 7024, "qhull warning: output file undefined(stdout). Option 'Tz' ignored.\n");
+ else {
+ qh_option(qh, "Tz-stdout", NULL, NULL);
+ qh->USEstdout= True;
+ qh->ferr= qh->fout;
+ qh->qhmem.ferr= qh->fout;
+ }
+ break;
+ case 'C':
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 7025, "qhull warning: missing point id for cone for trace option 'TCn'. Ignored\n");
+ else {
+ i= qh_strtol(s, &s);
+ qh_option(qh, "TCone-stop", &i, NULL);
+ qh->STOPcone= i + 1;
+ }
+ break;
+ case 'F':
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 7026, "qhull warning: missing frequency count for trace option 'TFn'. Ignored\n");
+ else {
+ qh->REPORTfreq= qh_strtol(s, &s);
+ qh_option(qh, "TFacet-log", &qh->REPORTfreq, NULL);
+ qh->REPORTfreq2= qh->REPORTfreq/2; /* for tracemerging() */
+ }
+ break;
+ case 'I':
+ if (!isspace(*s))
+ qh_fprintf(qh, qh->ferr, 7027, "qhull warning: missing space between 'TI' and filename, %s\n", s);
+ while (isspace(*s))
+ s++;
+ t= qh_skipfilename(qh, s);
+ {
+ char filename[qh_FILENAMElen];
+
+ qh_copyfilename(qh, filename, (int)sizeof(filename), s, (int)(t-s)); /* WARN64 */
+ s= t;
+ if (!freopen(filename, "r", stdin)) {
+ qh_fprintf(qh, qh->ferr, 6041, "qhull error: could not open file \"%s\".", filename);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }else {
+ qh_option(qh, "TInput-file", NULL, NULL);
+ qh_option(qh, filename, NULL, NULL);
+ }
+ }
+ break;
+ case 'O':
+ if (!isspace(*s))
+ qh_fprintf(qh, qh->ferr, 7028, "qhull warning: missing space between 'TO' and filename, %s\n", s);
+ while (isspace(*s))
+ s++;
+ t= qh_skipfilename(qh, s);
+ {
+ char filename[qh_FILENAMElen];
+
+ qh_copyfilename(qh, filename, (int)sizeof(filename), s, (int)(t-s)); /* WARN64 */
+ s= t;
+ if (!qh->fout) {
+ qh_fprintf(qh, qh->ferr, 6266, "qhull input warning: qh.fout was not set by caller. Cannot use option 'TO' to redirect output. Ignoring option 'TO'\n");
+ }else if (!freopen(filename, "w", qh->fout)) {
+ qh_fprintf(qh, qh->ferr, 6044, "qhull error: could not open file \"%s\".", filename);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }else {
+ qh_option(qh, "TOutput-file", NULL, NULL);
+ qh_option(qh, filename, NULL, NULL);
+ }
+ }
+ break;
+ case 'P':
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 7029, "qhull warning: missing point id for trace option 'TPn'. Ignored\n");
+ else {
+ qh->TRACEpoint= qh_strtol(s, &s);
+ qh_option(qh, "Trace-point", &qh->TRACEpoint, NULL);
+ }
+ break;
+ case 'M':
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 7030, "qhull warning: missing merge id for trace option 'TMn'. Ignored\n");
+ else {
+ qh->TRACEmerge= qh_strtol(s, &s);
+ qh_option(qh, "Trace-merge", &qh->TRACEmerge, NULL);
+ }
+ break;
+ case 'R':
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 7031, "qhull warning: missing rerun count for trace option 'TRn'. Ignored\n");
+ else {
+ qh->RERUN= qh_strtol(s, &s);
+ qh_option(qh, "TRerun", &qh->RERUN, NULL);
+ }
+ break;
+ case 'V':
+ i= qh_strtol(s, &t);
+ if (s == t)
+ qh_fprintf(qh, qh->ferr, 7032, "qhull warning: missing furthest point id for trace option 'TVn'. Ignored\n");
+ else if (i < 0) {
+ qh->STOPpoint= i - 1;
+ qh_option(qh, "TV-stop-before-point", &i, NULL);
+ }else {
+ qh->STOPpoint= i + 1;
+ qh_option(qh, "TV-stop-after-point", &i, NULL);
+ }
+ s= t;
+ break;
+ case 'W':
+ if (!isdigit(*s))
+ qh_fprintf(qh, qh->ferr, 7033, "qhull warning: missing max width for trace option 'TWn'. Ignored\n");
+ else {
+ qh->TRACEdist= (realT) qh_strtod(s, &s);
+ qh_option(qh, "TWide-trace", NULL, &qh->TRACEdist);
+ }
+ break;
+ default:
+ s--;
+ qh_fprintf(qh, qh->ferr, 7034, "qhull warning: unknown 'T' trace option %c, rest ignored\n", (int)s[0]);
+ while (*++s && !isspace(*s));
+ break;
+ }
+ }
+ break;
+ default:
+ qh_fprintf(qh, qh->ferr, 7035, "qhull warning: unknown flag %c(%x)\n", (int)s[-1],
+ (int)s[-1]);
+ break;
+ }
+ if (s-1 == prev_s && *s && !isspace(*s)) {
+ qh_fprintf(qh, qh->ferr, 7036, "qhull warning: missing space after flag %c(%x); reserved for menu. Skipped.\n",
+ (int)*prev_s, (int)*prev_s);
+ while (*s && !isspace(*s))
+ s++;
+ }
+ }
+ if (qh->STOPcone && qh->JOGGLEmax < REALmax/2)
+ qh_fprintf(qh, qh->ferr, 7078, "qhull warning: 'TCn' (stopCone) ignored when used with 'QJn' (joggle)\n");
+ if (isgeom && !qh->FORCEoutput && qh->PRINTout[1])
+ qh_fprintf(qh, qh->ferr, 7037, "qhull warning: additional output formats are not compatible with Geomview\n");
+ /* set derived values in qh_initqhull_globals */
+} /* initflags */
+
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="initqhull_buffers">-</a>
+
+ qh_initqhull_buffers(qh)
+ initialize global memory buffers
+
+ notes:
+ must match qh_freebuffers()
+*/
+void qh_initqhull_buffers(qhT *qh) {
+ int k;
+
+ qh->TEMPsize= (qh->qhmem.LASTsize - sizeof(setT))/SETelemsize;
+ if (qh->TEMPsize <= 0 || qh->TEMPsize > qh->qhmem.LASTsize)
+ qh->TEMPsize= 8; /* e.g., if qh_NOmem */
+ qh->other_points= qh_setnew(qh, qh->TEMPsize);
+ qh->del_vertices= qh_setnew(qh, qh->TEMPsize);
+ qh->coplanarfacetset= qh_setnew(qh, qh->TEMPsize);
+ qh->NEARzero= (realT *)qh_memalloc(qh, qh->hull_dim * sizeof(realT));
+ qh->lower_threshold= (realT *)qh_memalloc(qh, (qh->input_dim+1) * sizeof(realT));
+ qh->upper_threshold= (realT *)qh_memalloc(qh, (qh->input_dim+1) * sizeof(realT));
+ qh->lower_bound= (realT *)qh_memalloc(qh, (qh->input_dim+1) * sizeof(realT));
+ qh->upper_bound= (realT *)qh_memalloc(qh, (qh->input_dim+1) * sizeof(realT));
+ for (k=qh->input_dim+1; k--; ) { /* duplicated in qh_initqhull_buffers and qh_clear_outputflags */
+ qh->lower_threshold[k]= -REALmax;
+ qh->upper_threshold[k]= REALmax;
+ qh->lower_bound[k]= -REALmax;
+ qh->upper_bound[k]= REALmax;
+ }
+ qh->gm_matrix= (coordT *)qh_memalloc(qh, (qh->hull_dim+1) * qh->hull_dim * sizeof(coordT));
+ qh->gm_row= (coordT **)qh_memalloc(qh, (qh->hull_dim+1) * sizeof(coordT *));
+} /* initqhull_buffers */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="initqhull_globals">-</a>
+
+ qh_initqhull_globals(qh, points, numpoints, dim, ismalloc )
+ initialize globals
+ if ismalloc
+ points were malloc'd and qhull should free at end
+
+ returns:
+ sets qh.first_point, num_points, input_dim, hull_dim and others
+ seeds random number generator (seed=1 if tracing)
+ modifies qh.hull_dim if ((qh.DELAUNAY and qh.PROJECTdelaunay) or qh.PROJECTinput)
+ adjust user flags as needed
+ also checks DIM3 dependencies and constants
+
+ notes:
+ do not use qh_point() since an input transformation may move them elsewhere
+
+ see:
+ qh_initqhull_start() sets default values for non-zero globals
+
+ design:
+ initialize points array from input arguments
+ test for qh.ZEROcentrum
+ (i.e., use opposite vertex instead of cetrum for convexity testing)
+ initialize qh.CENTERtype, qh.normal_size,
+ qh.center_size, qh.TRACEpoint/level,
+ initialize and test random numbers
+ qh_initqhull_outputflags() -- adjust and test output flags
+*/
+void qh_initqhull_globals(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc) {
+ int seed, pointsneeded, extra= 0, i, randi, k;
+ realT randr;
+ realT factorial;
+
+ time_t timedata;
+
+ trace0((qh, qh->ferr, 13, "qh_initqhull_globals: for %s | %s\n", qh->rbox_command,
+ qh->qhull_command));
+ qh->POINTSmalloc= ismalloc;
+ qh->first_point= points;
+ qh->num_points= numpoints;
+ qh->hull_dim= qh->input_dim= dim;
+ if (!qh->NOpremerge && !qh->MERGEexact && !qh->PREmerge && qh->JOGGLEmax > REALmax/2) {
+ qh->MERGING= True;
+ if (qh->hull_dim <= 4) {
+ qh->PREmerge= True;
+ qh_option(qh, "_pre-merge", NULL, NULL);
+ }else {
+ qh->MERGEexact= True;
+ qh_option(qh, "Qxact_merge", NULL, NULL);
+ }
+ }else if (qh->MERGEexact)
+ qh->MERGING= True;
+ if (!qh->NOpremerge && qh->JOGGLEmax > REALmax/2) {
+#ifdef qh_NOmerge
+ qh->JOGGLEmax= 0.0;
+#endif
+ }
+ if (qh->TRIangulate && qh->JOGGLEmax < REALmax/2 && qh->PRINTprecision)
+ qh_fprintf(qh, qh->ferr, 7038, "qhull warning: joggle('QJ') always produces simplicial output. Triangulated output('Qt') does nothing.\n");
+ if (qh->JOGGLEmax < REALmax/2 && qh->DELAUNAY && !qh->SCALEinput && !qh->SCALElast) {
+ qh->SCALElast= True;
+ qh_option(qh, "Qbbound-last-qj", NULL, NULL);
+ }
+ if (qh->MERGING && !qh->POSTmerge && qh->premerge_cos > REALmax/2
+ && qh->premerge_centrum == 0) {
+ qh->ZEROcentrum= True;
+ qh->ZEROall_ok= True;
+ qh_option(qh, "_zero-centrum", NULL, NULL);
+ }
+ if (qh->JOGGLEmax < REALmax/2 && REALepsilon > 2e-8 && qh->PRINTprecision)
+ qh_fprintf(qh, qh->ferr, 7039, "qhull warning: real epsilon, %2.2g, is probably too large for joggle('QJn')\nRecompile with double precision reals(see user.h).\n",
+ REALepsilon);
+#ifdef qh_NOmerge
+ if (qh->MERGING) {
+ qh_fprintf(qh, qh->ferr, 6045, "qhull input error: merging not installed(qh_NOmerge + 'Qx', 'Cn' or 'An')\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+#endif
+ if (qh->DELAUNAY && qh->KEEPcoplanar && !qh->KEEPinside) {
+ qh->KEEPinside= True;
+ qh_option(qh, "Qinterior-keep", NULL, NULL);
+ }
+ if (qh->DELAUNAY && qh->HALFspace) {
+ qh_fprintf(qh, qh->ferr, 6046, "qhull input error: can not use Delaunay('d') or Voronoi('v') with halfspace intersection('H')\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (!qh->DELAUNAY && (qh->UPPERdelaunay || qh->ATinfinity)) {
+ qh_fprintf(qh, qh->ferr, 6047, "qhull input error: use upper-Delaunay('Qu') or infinity-point('Qz') with Delaunay('d') or Voronoi('v')\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (qh->UPPERdelaunay && qh->ATinfinity) {
+ qh_fprintf(qh, qh->ferr, 6048, "qhull input error: can not use infinity-point('Qz') with upper-Delaunay('Qu')\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (qh->SCALElast && !qh->DELAUNAY && qh->PRINTprecision)
+ qh_fprintf(qh, qh->ferr, 7040, "qhull input warning: option 'Qbb' (scale-last-coordinate) is normally used with 'd' or 'v'\n");
+ qh->DOcheckmax= (!qh->SKIPcheckmax && qh->MERGING );
+ qh->KEEPnearinside= (qh->DOcheckmax && !(qh->KEEPinside && qh->KEEPcoplanar)
+ && !qh->NOnearinside);
+ if (qh->MERGING)
+ qh->CENTERtype= qh_AScentrum;
+ else if (qh->VORONOI)
+ qh->CENTERtype= qh_ASvoronoi;
+ if (qh->TESTvneighbors && !qh->MERGING) {
+ qh_fprintf(qh, qh->ferr, 6049, "qhull input error: test vertex neighbors('Qv') needs a merge option\n");
+ qh_errexit(qh, qh_ERRinput, NULL ,NULL);
+ }
+ if (qh->PROJECTinput || (qh->DELAUNAY && qh->PROJECTdelaunay)) {
+ qh->hull_dim -= qh->PROJECTinput;
+ if (qh->DELAUNAY) {
+ qh->hull_dim++;
+ if (qh->ATinfinity)
+ extra= 1;
+ }
+ }
+ if (qh->hull_dim <= 1) {
+ qh_fprintf(qh, qh->ferr, 6050, "qhull error: dimension %d must be > 1\n", qh->hull_dim);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ for (k=2, factorial=1.0; k < qh->hull_dim; k++)
+ factorial *= k;
+ qh->AREAfactor= 1.0 / factorial;
+ trace2((qh, qh->ferr, 2005, "qh_initqhull_globals: initialize globals. dim %d numpoints %d malloc? %d projected %d to hull_dim %d\n",
+ dim, numpoints, ismalloc, qh->PROJECTinput, qh->hull_dim));
+ qh->normal_size= qh->hull_dim * sizeof(coordT);
+ qh->center_size= qh->normal_size - sizeof(coordT);
+ pointsneeded= qh->hull_dim+1;
+ if (qh->hull_dim > qh_DIMmergeVertex) {
+ qh->MERGEvertices= False;
+ qh_option(qh, "Q3-no-merge-vertices-dim-high", NULL, NULL);
+ }
+ if (qh->GOODpoint)
+ pointsneeded++;
+#ifdef qh_NOtrace
+ if (qh->IStracing) {
+ qh_fprintf(qh, qh->ferr, 6051, "qhull input error: tracing is not installed(qh_NOtrace in user.h)");
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+#endif
+ if (qh->RERUN > 1) {
+ qh->TRACElastrun= qh->IStracing; /* qh_build_withrestart duplicates next conditional */
+ if (qh->IStracing != -1)
+ qh->IStracing= 0;
+ }else if (qh->TRACEpoint != qh_IDunknown || qh->TRACEdist < REALmax/2 || qh->TRACEmerge) {
+ qh->TRACElevel= (qh->IStracing? qh->IStracing : 3);
+ qh->IStracing= 0;
+ }
+ if (qh->ROTATErandom == 0 || qh->ROTATErandom == -1) {
+ seed= (int)time(&timedata);
+ if (qh->ROTATErandom == -1) {
+ seed= -seed;
+ qh_option(qh, "QRandom-seed", &seed, NULL );
+ }else
+ qh_option(qh, "QRotate-random", &seed, NULL);
+ qh->ROTATErandom= seed;
+ }
+ seed= qh->ROTATErandom;
+ if (seed == INT_MIN) /* default value */
+ seed= 1;
+ else if (seed < 0)
+ seed= -seed;
+ qh_RANDOMseed_(qh, seed);
+ randr= 0.0;
+ for (i=1000; i--; ) {
+ randi= qh_RANDOMint;
+ randr += randi;
+ if (randi > qh_RANDOMmax) {
+ qh_fprintf(qh, qh->ferr, 8036, "\
+qhull configuration error (qh_RANDOMmax in user.h):\n\
+ random integer %d > qh_RANDOMmax(qh, %.8g)\n",
+ randi, qh_RANDOMmax);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ }
+ qh_RANDOMseed_(qh, seed);
+ randr = randr/1000;
+ if (randr < qh_RANDOMmax * 0.1
+ || randr > qh_RANDOMmax * 0.9)
+ qh_fprintf(qh, qh->ferr, 8037, "\
+qhull configuration warning (qh_RANDOMmax in user.h):\n\
+ average of 1000 random integers (%.2g) is much different than expected (%.2g).\n\
+ Is qh_RANDOMmax (%.2g) wrong?\n",
+ randr, qh_RANDOMmax * 0.5, qh_RANDOMmax);
+ qh->RANDOMa= 2.0 * qh->RANDOMfactor/qh_RANDOMmax;
+ qh->RANDOMb= 1.0 - qh->RANDOMfactor;
+ if (qh_HASHfactor < 1.1) {
+ qh_fprintf(qh, qh->ferr, 6052, "qhull internal error (qh_initqhull_globals): qh_HASHfactor %d must be at least 1.1. Qhull uses linear hash probing\n",
+ qh_HASHfactor);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ if (numpoints+extra < pointsneeded) {
+ qh_fprintf(qh, qh->ferr, 6214, "qhull input error: not enough points(%d) to construct initial simplex (need %d)\n",
+ numpoints, pointsneeded);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ qh_initqhull_outputflags(qh);
+} /* initqhull_globals */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="initqhull_mem">-</a>
+
+ qh_initqhull_mem(qh, )
+ initialize mem_r.c for qhull
+ qh.hull_dim and qh.normal_size determine some of the allocation sizes
+ if qh.MERGING,
+ includes ridgeT
+ calls qh_user_memsizes(qh) to add up to 10 additional sizes for quick allocation
+ (see numsizes below)
+
+ returns:
+ mem_r.c already for qh_memalloc/qh_memfree (errors if called beforehand)
+
+ notes:
+ qh_produceoutput() prints memsizes
+
+*/
+void qh_initqhull_mem(qhT *qh) {
+ int numsizes;
+ int i;
+
+ numsizes= 8+10;
+ qh_meminitbuffers(qh, qh->IStracing, qh_MEMalign, numsizes,
+ qh_MEMbufsize, qh_MEMinitbuf);
+ qh_memsize(qh, (int)sizeof(vertexT));
+ if (qh->MERGING) {
+ qh_memsize(qh, (int)sizeof(ridgeT));
+ qh_memsize(qh, (int)sizeof(mergeT));
+ }
+ qh_memsize(qh, (int)sizeof(facetT));
+ i= sizeof(setT) + (qh->hull_dim - 1) * SETelemsize; /* ridge.vertices */
+ qh_memsize(qh, i);
+ qh_memsize(qh, qh->normal_size); /* normal */
+ i += SETelemsize; /* facet.vertices, .ridges, .neighbors */
+ qh_memsize(qh, i);
+ qh_user_memsizes(qh);
+ qh_memsetup(qh);
+} /* initqhull_mem */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="initqhull_outputflags">-</a>
+
+ qh_initqhull_outputflags
+ initialize flags concerned with output
+
+ returns:
+ adjust user flags as needed
+
+ see:
+ qh_clear_outputflags() resets the flags
+
+ design:
+ test for qh.PRINTgood (i.e., only print 'good' facets)
+ check for conflicting print output options
+*/
+void qh_initqhull_outputflags(qhT *qh) {
+ boolT printgeom= False, printmath= False, printcoplanar= False;
+ int i;
+
+ trace3((qh, qh->ferr, 3024, "qh_initqhull_outputflags: %s\n", qh->qhull_command));
+ if (!(qh->PRINTgood || qh->PRINTneighbors)) {
+ if (qh->KEEParea || qh->KEEPminArea < REALmax/2 || qh->KEEPmerge || qh->DELAUNAY
+ || (!qh->ONLYgood && (qh->GOODvertex || qh->GOODpoint))) {
+ qh->PRINTgood= True;
+ qh_option(qh, "Pgood", NULL, NULL);
+ }
+ }
+ if (qh->PRINTtransparent) {
+ if (qh->hull_dim != 4 || !qh->DELAUNAY || qh->VORONOI || qh->DROPdim >= 0) {
+ qh_fprintf(qh, qh->ferr, 6215, "qhull input error: transparent Delaunay('Gt') needs 3-d Delaunay('d') w/o 'GDn'\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ qh->DROPdim = 3;
+ qh->PRINTridges = True;
+ }
+ for (i=qh_PRINTEND; i--; ) {
+ if (qh->PRINTout[i] == qh_PRINTgeom)
+ printgeom= True;
+ else if (qh->PRINTout[i] == qh_PRINTmathematica || qh->PRINTout[i] == qh_PRINTmaple)
+ printmath= True;
+ else if (qh->PRINTout[i] == qh_PRINTcoplanars)
+ printcoplanar= True;
+ else if (qh->PRINTout[i] == qh_PRINTpointnearest)
+ printcoplanar= True;
+ else if (qh->PRINTout[i] == qh_PRINTpointintersect && !qh->HALFspace) {
+ qh_fprintf(qh, qh->ferr, 6053, "qhull input error: option 'Fp' is only used for \nhalfspace intersection('Hn,n,n').\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }else if (qh->PRINTout[i] == qh_PRINTtriangles && (qh->HALFspace || qh->VORONOI)) {
+ qh_fprintf(qh, qh->ferr, 6054, "qhull input error: option 'Ft' is not available for Voronoi vertices or halfspace intersection\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }else if (qh->PRINTout[i] == qh_PRINTcentrums && qh->VORONOI) {
+ qh_fprintf(qh, qh->ferr, 6055, "qhull input error: option 'FC' is not available for Voronoi vertices('v')\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }else if (qh->PRINTout[i] == qh_PRINTvertices) {
+ if (qh->VORONOI)
+ qh_option(qh, "Fvoronoi", NULL, NULL);
+ else
+ qh_option(qh, "Fvertices", NULL, NULL);
+ }
+ }
+ if (printcoplanar && qh->DELAUNAY && qh->JOGGLEmax < REALmax/2) {
+ if (qh->PRINTprecision)
+ qh_fprintf(qh, qh->ferr, 7041, "qhull input warning: 'QJ' (joggle) will usually prevent coincident input sites for options 'Fc' and 'FP'\n");
+ }
+ if (printmath && (qh->hull_dim > 3 || qh->VORONOI)) {
+ qh_fprintf(qh, qh->ferr, 6056, "qhull input error: Mathematica and Maple output is only available for 2-d and 3-d convex hulls and 2-d Delaunay triangulations\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (printgeom) {
+ if (qh->hull_dim > 4) {
+ qh_fprintf(qh, qh->ferr, 6057, "qhull input error: Geomview output is only available for 2-d, 3-d and 4-d\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (qh->PRINTnoplanes && !(qh->PRINTcoplanar + qh->PRINTcentrums
+ + qh->PRINTdots + qh->PRINTspheres + qh->DOintersections + qh->PRINTridges)) {
+ qh_fprintf(qh, qh->ferr, 6058, "qhull input error: no output specified for Geomview\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (qh->VORONOI && (qh->hull_dim > 3 || qh->DROPdim >= 0)) {
+ qh_fprintf(qh, qh->ferr, 6059, "qhull input error: Geomview output for Voronoi diagrams only for 2-d\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ /* can not warn about furthest-site Geomview output: no lower_threshold */
+ if (qh->hull_dim == 4 && qh->DROPdim == -1 &&
+ (qh->PRINTcoplanar || qh->PRINTspheres || qh->PRINTcentrums)) {
+ qh_fprintf(qh, qh->ferr, 7042, "qhull input warning: coplanars, vertices, and centrums output not\n\
+available for 4-d output(ignored). Could use 'GDn' instead.\n");
+ qh->PRINTcoplanar= qh->PRINTspheres= qh->PRINTcentrums= False;
+ }
+ }
+ if (!qh->KEEPcoplanar && !qh->KEEPinside && !qh->ONLYgood) {
+ if ((qh->PRINTcoplanar && qh->PRINTspheres) || printcoplanar) {
+ if (qh->QHULLfinished) {
+ qh_fprintf(qh, qh->ferr, 7072, "qhull output warning: ignoring coplanar points, option 'Qc' was not set for the first run of qhull.\n");
+ }else {
+ qh->KEEPcoplanar = True;
+ qh_option(qh, "Qcoplanar", NULL, NULL);
+ }
+ }
+ }
+ qh->PRINTdim= qh->hull_dim;
+ if (qh->DROPdim >=0) { /* after Geomview checks */
+ if (qh->DROPdim < qh->hull_dim) {
+ qh->PRINTdim--;
+ if (!printgeom || qh->hull_dim < 3)
+ qh_fprintf(qh, qh->ferr, 7043, "qhull input warning: drop dimension 'GD%d' is only available for 3-d/4-d Geomview\n", qh->DROPdim);
+ }else
+ qh->DROPdim= -1;
+ }else if (qh->VORONOI) {
+ qh->DROPdim= qh->hull_dim-1;
+ qh->PRINTdim= qh->hull_dim-1;
+ }
+} /* qh_initqhull_outputflags */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="initqhull_start">-</a>
+
+ qh_initqhull_start(qh, infile, outfile, errfile )
+ allocate memory if needed and call qh_initqhull_start2()
+*/
+void qh_initqhull_start(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile) {
+
+ qh_initstatistics(qh);
+ qh_initqhull_start2(qh, infile, outfile, errfile);
+} /* initqhull_start */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="initqhull_start2">-</a>
+
+ qh_initqhull_start2(qh, infile, outfile, errfile )
+ start initialization of qhull
+ initialize statistics, stdio, default values for global variables
+ assumes qh is allocated
+ notes:
+ report errors elsewhere, error handling and g_qhull_output [Qhull.cpp, QhullQh()] not in initialized
+ see:
+ qh_maxmin() determines the precision constants
+ qh_freeqhull()
+*/
+void qh_initqhull_start2(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile) {
+ time_t timedata;
+ int seed;
+
+ qh_CPUclock; /* start the clock(for qh_clock). One-shot. */
+ /* memset is the same in qh_freeqhull() and qh_initqhull_start2() */
+ memset((char *)qh, 0, sizeof(qhT)-sizeof(qhmemT)-sizeof(qhstatT)); /* every field is 0, FALSE, NULL */
+ qh->NOerrexit= True;
+ qh->ANGLEmerge= True;
+ qh->DROPdim= -1;
+ qh->ferr= errfile;
+ qh->fin= infile;
+ qh->fout= outfile;
+ qh->furthest_id= qh_IDunknown;
+ qh->JOGGLEmax= REALmax;
+ qh->KEEPminArea = REALmax;
+ qh->last_low= REALmax;
+ qh->last_high= REALmax;
+ qh->last_newhigh= REALmax;
+ qh->last_random= 1;
+ qh->max_outside= 0.0;
+ qh->max_vertex= 0.0;
+ qh->MAXabs_coord= 0.0;
+ qh->MAXsumcoord= 0.0;
+ qh->MAXwidth= -REALmax;
+ qh->MERGEindependent= True;
+ qh->MINdenom_1= fmax_(1.0/REALmax, REALmin); /* used by qh_scalepoints */
+ qh->MINoutside= 0.0;
+ qh->MINvisible= REALmax;
+ qh->MAXcoplanar= REALmax;
+ qh->outside_err= REALmax;
+ qh->premerge_centrum= 0.0;
+ qh->premerge_cos= REALmax;
+ qh->PRINTprecision= True;
+ qh->PRINTradius= 0.0;
+ qh->postmerge_cos= REALmax;
+ qh->postmerge_centrum= 0.0;
+ qh->ROTATErandom= INT_MIN;
+ qh->MERGEvertices= True;
+ qh->totarea= 0.0;
+ qh->totvol= 0.0;
+ qh->TRACEdist= REALmax;
+ qh->TRACEpoint= qh_IDunknown; /* recompile or use 'TPn' */
+ qh->tracefacet_id= UINT_MAX; /* recompile to trace a facet */
+ qh->tracevertex_id= UINT_MAX; /* recompile to trace a vertex */
+ seed= (int)time(&timedata);
+ qh_RANDOMseed_(qh, seed);
+ qh->run_id= qh_RANDOMint;
+ if(!qh->run_id)
+ qh->run_id++; /* guarantee non-zero */
+ qh_option(qh, "run-id", &qh->run_id, NULL);
+ strcat(qh->qhull, "qhull");
+} /* initqhull_start2 */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="initthresholds">-</a>
+
+ qh_initthresholds(qh, commandString )
+ set thresholds for printing and scaling from commandString
+
+ returns:
+ sets qh.GOODthreshold or qh.SPLITthreshold if 'Pd0D1' used
+
+ see:
+ qh_initflags(), 'Qbk' 'QBk' 'Pdk' and 'PDk'
+ qh_inthresholds()
+
+ design:
+ for each 'Pdn' or 'PDn' option
+ check syntax
+ set qh.lower_threshold or qh.upper_threshold
+ set qh.GOODthreshold if an unbounded threshold is used
+ set qh.SPLITthreshold if a bounded threshold is used
+*/
+void qh_initthresholds(qhT *qh, char *command) {
+ realT value;
+ int idx, maxdim, k;
+ char *s= command; /* non-const due to strtol */
+ char key;
+
+ maxdim= qh->input_dim;
+ if (qh->DELAUNAY && (qh->PROJECTdelaunay || qh->PROJECTinput))
+ maxdim++;
+ while (*s) {
+ if (*s == '-')
+ s++;
+ if (*s == 'P') {
+ s++;
+ while (*s && !isspace(key= *s++)) {
+ if (key == 'd' || key == 'D') {
+ if (!isdigit(*s)) {
+ qh_fprintf(qh, qh->ferr, 7044, "qhull warning: no dimension given for Print option '%c' at: %s. Ignored\n",
+ key, s-1);
+ continue;
+ }
+ idx= qh_strtol(s, &s);
+ if (idx >= qh->hull_dim) {
+ qh_fprintf(qh, qh->ferr, 7045, "qhull warning: dimension %d for Print option '%c' is >= %d. Ignored\n",
+ idx, key, qh->hull_dim);
+ continue;
+ }
+ if (*s == ':') {
+ s++;
+ value= qh_strtod(s, &s);
+ if (fabs((double)value) > 1.0) {
+ qh_fprintf(qh, qh->ferr, 7046, "qhull warning: value %2.4g for Print option %c is > +1 or < -1. Ignored\n",
+ value, key);
+ continue;
+ }
+ }else
+ value= 0.0;
+ if (key == 'd')
+ qh->lower_threshold[idx]= value;
+ else
+ qh->upper_threshold[idx]= value;
+ }
+ }
+ }else if (*s == 'Q') {
+ s++;
+ while (*s && !isspace(key= *s++)) {
+ if (key == 'b' && *s == 'B') {
+ s++;
+ for (k=maxdim; k--; ) {
+ qh->lower_bound[k]= -qh_DEFAULTbox;
+ qh->upper_bound[k]= qh_DEFAULTbox;
+ }
+ }else if (key == 'b' && *s == 'b')
+ s++;
+ else if (key == 'b' || key == 'B') {
+ if (!isdigit(*s)) {
+ qh_fprintf(qh, qh->ferr, 7047, "qhull warning: no dimension given for Qhull option %c. Ignored\n",
+ key);
+ continue;
+ }
+ idx= qh_strtol(s, &s);
+ if (idx >= maxdim) {
+ qh_fprintf(qh, qh->ferr, 7048, "qhull warning: dimension %d for Qhull option %c is >= %d. Ignored\n",
+ idx, key, maxdim);
+ continue;
+ }
+ if (*s == ':') {
+ s++;
+ value= qh_strtod(s, &s);
+ }else if (key == 'b')
+ value= -qh_DEFAULTbox;
+ else
+ value= qh_DEFAULTbox;
+ if (key == 'b')
+ qh->lower_bound[idx]= value;
+ else
+ qh->upper_bound[idx]= value;
+ }
+ }
+ }else {
+ while (*s && !isspace(*s))
+ s++;
+ }
+ while (isspace(*s))
+ s++;
+ }
+ for (k=qh->hull_dim; k--; ) {
+ if (qh->lower_threshold[k] > -REALmax/2) {
+ qh->GOODthreshold= True;
+ if (qh->upper_threshold[k] < REALmax/2) {
+ qh->SPLITthresholds= True;
+ qh->GOODthreshold= False;
+ break;
+ }
+ }else if (qh->upper_threshold[k] < REALmax/2)
+ qh->GOODthreshold= True;
+ }
+} /* initthresholds */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="lib_check">-</a>
+
+ qh_lib_check( qhullLibraryType, qhTsize, vertexTsize, ridgeTsize, facetTsize, setTsize, qhmemTsize )
+ Report error if library does not agree with caller
+
+ notes:
+ NOerrors -- qh_lib_check can not call qh_errexit()
+*/
+void qh_lib_check(int qhullLibraryType, int qhTsize, int vertexTsize, int ridgeTsize, int facetTsize, int setTsize, int qhmemTsize) {
+ boolT iserror= False;
+
+#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG) /* user_r.h */
+ // _CrtSetBreakAlloc(744); /* Break at memalloc {744}, or 'watch' _crtBreakAlloc */
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) );
+ _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
+ _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
+ _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
+ _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR );
+ _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
+ _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
+#endif
+
+ if (qhullLibraryType==QHULL_NON_REENTRANT) { /* 0 */
+ qh_fprintf_stderr(6257, "qh_lib_check: Incorrect qhull library called. Caller uses non-reentrant Qhull with a static qhT. Library is reentrant.\n");
+ iserror= True;
+ }else if (qhullLibraryType==QHULL_QH_POINTER) { /* 1 */
+ qh_fprintf_stderr(6258, "qh_lib_check: Incorrect qhull library called. Caller uses non-reentrant Qhull with a dynamic qhT via qh_QHpointer. Library is reentrant.\n");
+ iserror= True;
+ }else if (qhullLibraryType!=QHULL_REENTRANT) { /* 2 */
+ qh_fprintf_stderr(6262, "qh_lib_check: Expecting qhullLibraryType QHULL_NON_REENTRANT(0), QHULL_QH_POINTER(1), or QHULL_REENTRANT(2). Got %d\n", qhullLibraryType);
+ iserror= True;
+ }
+ if (qhTsize != sizeof(qhT)) {
+ qh_fprintf_stderr(6249, "qh_lib_check: Incorrect qhull library called. Size of qhT for caller is %d, but for library is %d.\n", qhTsize, sizeof(qhT));
+ iserror= True;
+ }
+ if (vertexTsize != sizeof(vertexT)) {
+ qh_fprintf_stderr(6250, "qh_lib_check: Incorrect qhull library called. Size of vertexT for caller is %d, but for library is %d.\n", vertexTsize, sizeof(vertexT));
+ iserror= True;
+ }
+ if (ridgeTsize != sizeof(ridgeT)) {
+ qh_fprintf_stderr(6251, "qh_lib_check: Incorrect qhull library called. Size of ridgeT for caller is %d, but for library is %d.\n", ridgeTsize, sizeof(ridgeT));
+ iserror= True;
+ }
+ if (facetTsize != sizeof(facetT)) {
+ qh_fprintf_stderr(6252, "qh_lib_check: Incorrect qhull library called. Size of facetT for caller is %d, but for library is %d.\n", facetTsize, sizeof(facetT));
+ iserror= True;
+ }
+ if (setTsize && setTsize != sizeof(setT)) {
+ qh_fprintf_stderr(6253, "qh_lib_check: Incorrect qhull library called. Size of setT for caller is %d, but for library is %d.\n", setTsize, sizeof(setT));
+ iserror= True;
+ }
+ if (qhmemTsize && qhmemTsize != sizeof(qhmemT)) {
+ qh_fprintf_stderr(6254, "qh_lib_check: Incorrect qhull library called. Size of qhmemT for caller is %d, but for library is %d.\n", qhmemTsize, sizeof(qhmemT));
+ iserror= True;
+ }
+ if (iserror) {
+ qh_fprintf_stderr(6259, "qh_lib_check: Cannot continue. Library '%s' is reentrant (e.g., qhull_r.so)\n", qh_version2);
+ qh_exit(qh_ERRqhull); /* can not use qh_errexit() */
+ }
+} /* lib_check */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="option">-</a>
+
+ qh_option(qh, option, intVal, realVal )
+ add an option description to qh.qhull_options
+
+ notes:
+ NOerrors -- qh_option can not call qh_errexit() [qh_initqhull_start2]
+ will be printed with statistics ('Ts') and errors
+ strlen(option) < 40
+*/
+void qh_option(qhT *qh, const char *option, int *i, realT *r) {
+ char buf[200];
+ int len, maxlen;
+
+ sprintf(buf, " %s", option);
+ if (i)
+ sprintf(buf+strlen(buf), " %d", *i);
+ if (r)
+ sprintf(buf+strlen(buf), " %2.2g", *r);
+ len= (int)strlen(buf); /* WARN64 */
+ qh->qhull_optionlen += len;
+ maxlen= sizeof(qh->qhull_options) - len -1;
+ maximize_(maxlen, 0);
+ if (qh->qhull_optionlen >= qh_OPTIONline && maxlen > 0) {
+ qh->qhull_optionlen= len;
+ strncat(qh->qhull_options, "\n", (size_t)(maxlen--));
+ }
+ strncat(qh->qhull_options, buf, (size_t)maxlen);
+} /* option */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="zero">-</a>
+
+ qh_zero( qh, errfile )
+ Initialize and zero Qhull's memory for qh_new_qhull()
+
+ notes:
+ Not needed in global.c because static variables are initialized to zero
+*/
+void qh_zero(qhT *qh, FILE *errfile) {
+ memset((char *)qh, 0, sizeof(qhT)); /* every field is 0, FALSE, NULL */
+ qh->NOerrexit= True;
+ qh_meminit(qh, errfile);
+} /* zero */
+
diff --git a/xs/src/qhull/src/libqhull_r/index.htm b/xs/src/qhull/src/libqhull_r/index.htm
new file mode 100644
index 000000000..c62030e06
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/index.htm
@@ -0,0 +1,266 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>Reentrant Qhull functions, macros, and data structures</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code</a><br>
+<b>To:</b> <a href="#TOC">Qhull files</a><br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+
+<hr>
+<!-- Main text of document. -->
+
+<h1>Reentrant Qhull functions, macros, and data structures</h1>
+<blockquote>
+<p>The following sections provide an overview and index to
+reentrant Qhull's functions, macros, and data structures.
+Each section starts with an introduction.
+See also <a href=../../html/qh-code.htm#library>Calling
+Qhull from C programs</a> and <a href="../../html/qh-code.htm#cpp">Calling Qhull from C++ programs</a>.</p>
+
+<p>Qhull uses the following conventions:</p>
+<blockquote>
+
+<ul>
+<li>in code, global variables start with &quot;qh &quot;
+<li>in documentation, global variables start with 'qh.'
+<li>constants start with an upper case word
+<li>important globals include an '_'
+<li>functions, macros, and constants start with &quot;qh_&quot;</li>
+<li>data types end in &quot;T&quot;</li>
+<li>macros with arguments end in &quot;_&quot;</li>
+<li>iterators are macros that use local variables</li>
+<li>iterators for sets start with &quot;FOREACH&quot;</li>
+<li>iterators for lists start with &quot;FORALL&quot;</li>
+<li>qhull options are in single quotes (e.g., 'Pdn')</li>
+<li>lists are sorted alphabetically</li>
+<li>preprocessor directives on left margin for older compilers</li>
+</ul>
+</blockquote>
+<p>
+Reentrant Qhull is nearly the same as non-reentrant Qhull. In reentrant
+Qhull, the qhT data structure is the first parameter to most functions. Qhull accesses
+this data structure with 'qh->...'.
+In non-reentrant Qhull, the global data structure is either a struct (qh_QHpointer==0)
+or a pointer (qh_QHpointer==1). The non-reentrant code looks different because this data
+structure is accessed via the 'qh' macro. This macro expands to 'qh_qh.' or 'qh_qh->' (resp.).
+<p>
+When reading code with an editor, a search for
+'<i>&quot;function</i>'
+will locate the header of <i>qh_function</i>. A search for '<i>* function</i>'
+will locate the tail of <i>qh_function</i>.
+
+<p>A useful starting point is <a href="libqhull_r.h">libqhull_r.h</a>. It defines most
+of Qhull data structures and top-level functions. Search for <i>'PFn'</i> to
+determine the corresponding constant in Qhull. Search for <i>'Fp'</i> to
+determine the corresponding <a href="libqhull_r.h#qh_PRINT">qh_PRINT...</a> constant.
+Search <a href="io_r.c">io_r.c</a> to learn how the print function is implemented.</p>
+
+<p>If your web browser is configured for .c and .h files, the function, macro, and data type links
+go to the corresponding source location. To configure your web browser for .c and .h files.
+<ul>
+<li>In the Download Preferences or Options panel, add file extensions 'c' and 'h' to mime type 'text/html'.
+<li>Opera 12.10
+<ol>
+<li>In Tools > Preferences > Advanced > Downloads
+<li>Uncheck 'Hide file types opened with Opera'
+<li>Quick find 'html'
+<li>Select 'text/html' > Edit
+<li>Add File extensions 'c,h,'
+<li>Click 'OK'
+</ol>
+<li>Internet Explorer -- Mime types are not available from 'Internet Options'. Is there a registry key for these settings?
+<li>Firefox -- Mime types are not available from 'Preferences'. Is there an add-on to change the file extensions for a mime type?
+<li>Chrome -- Can Chrome be configured?
+</ul>
+
+<p>
+Please report documentation and link errors
+to <a href="mailto:qhull-bug@qhull.org">qhull-bug@qhull.org</a>.
+</blockquote>
+
+<p><b>Copyright &copy; 1997-2015 C.B. Barber</b></p>
+
+<hr>
+
+<h2><a href="#TOP">&#187;</a><a name="TOC">Qhull files</a> </h2>
+<blockquote>
+
+<p>This sections lists the .c and .h files for Qhull. Please
+refer to these files for detailed information.</p>
+<blockquote>
+
+<dl>
+<dt><a href="../../Makefile"><b>Makefile</b></a><b>, </b><a href="../../CMakeLists.txt"><b>CMakeLists.txt</b></a></dt>
+<dd><tt>Makefile</tt> is preconfigured for gcc. <tt>CMakeLists.txt</tt> supports multiple
+platforms with <a href=http://www.cmake.org/>CMake</a>.
+Qhull includes project files for Visual Studio and Qt.
+</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
+<dd>Include file for the Qhull library (<tt>libqhull.so</tt>, <tt>qhull.dll</tt>, <tt>libqhullstatic.a</tt>).
+Data structures are documented under <a href="qh-poly_r.htm">Poly</a>.
+Global variables are documented under <a href="qh-globa_r.htm">Global</a>.
+Other data structures and variables are documented under
+<a href="qh-qhull_r.htm#TOC">Qhull</a> or <a href="qh-geom_r.htm"><b>Geom</b></a><b>.</b></dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-geom_r.htm"><b>Geom</b></a><b>, </b>
+<a href="geom_r.h"><b>geom_r.h</b></a><b>, </b>
+<a href="geom_r.c"><b>geom_r.c</b></a><b>, </b>
+<a href="geom2_r.c"><b>geom2_r.c</b></a><b>, </b>
+<a href="random_r.c"><b>random_r.c</b></a><b>, </b>
+<a href="random_r.h"><b>random_r.h</b></a></dt>
+<dd>Geometric routines. These routines implement mathematical
+functions such as Gaussian elimination and geometric
+routines needed for Qhull. Frequently used routines are
+in <tt>geom_r.c</tt> while infrequent ones are in <tt>geom2_r.c</tt>.
+</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-globa_r.htm"><b>Global</b></a><b>, </b>
+<a href="global_r.c"><b>global_r.c</b></a><b>, </b>
+<a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
+<dd>Global routines. Qhull uses a global data structure, <tt>qh</tt>,
+to store globally defined constants, lists, sets, and
+variables.
+<tt>global_r.c</tt> initializes and frees these
+structures. </dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-io_r.htm"><b>Io</b></a><b>, </b><a href="io_r.h"><b>io_r.h</b></a><b>,
+</b><a href="io_r.c"><b>io_r.c</b></a> </dt>
+<dd>Input and output routines. Qhull provides a wide range of
+input and output options.</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-mem_r.htm"><b>Mem</b></a><b>, </b>
+<a href="mem_r.h"><b>mem_r.h</b></a><b>, </b>
+<a href="mem_r.c"><b>mem_r.c</b></a> </dt>
+<dd>Memory routines. Qhull provides memory allocation and
+deallocation. It uses quick-fit allocation.</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-merge_r.htm"><b>Merge</b></a><b>, </b>
+<a href="merge_r.h"><b>merge_r.h</b></a><b>, </b>
+<a href="merge_r.c"><b>merge_r.c</b></a> </dt>
+<dd>Merge routines. Qhull handles precision problems by
+merged facets or joggled input. These routines merge simplicial facets,
+merge non-simplicial facets, merge cycles of facets, and
+rename redundant vertices.</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-poly_r.htm"><b>Poly</b></a><b>, </b>
+<a href="poly_r.h"><b>poly_r.h</b></a><b>, </b>
+<a href="poly_r.c"><b>poly_r.c</b></a><b>, </b>
+<a href="poly2_r.c"><b>poly2_r.c</b></a><b>, </b>
+<a href="libqhull_r.h"><b>libqhull_r.h</b></a> </dt>
+<dd>Polyhedral routines. Qhull produces a polyhedron as a
+list of facets with vertices, neighbors, ridges, and
+geometric information. <tt>libqhull_r.h</tt> defines the main
+data structures. Frequently used routines are in <tt>poly_r.c</tt>
+while infrequent ones are in <tt>poly2_r.c</tt>.</dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-qhull_r.htm#TOC"><b>Qhull</b></a><b>, </b>
+<a href="libqhull_r.c"><b>libqhull_r.c</b></a><b>, </b>
+<a href="libqhull_r.h"><b>libqhull_r.h</b></a><b>, </b>
+<a href="qhull_ra.h"><b>qhull_ra.h</b></a><b>, </b>
+<a href="../qhull/unix_r.c"><b>unix_r.c</b></a> <b>, </b>
+<a href="../qconvex/qconvex_r.c"><b>qconvex_r.c</b></a> <b>, </b>
+<a href="../qdelaunay/qdelaun_r.c"><b>qdelaun_r.c</b></a> <b>, </b>
+<a href="../qhalf/qhalf_r.c"><b>qhalf_r.c</b></a> <b>, </b>
+<a href="../qvoronoi/qvoronoi_r.c"><b>qvoronoi_r.c</b></a> </dt>
+<dd>Top-level routines. The Quickhull algorithm is
+implemented by <tt>libqhull_r.c</tt>. <tt>qhull_ra.h</tt>
+includes all header files. </dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-set_r.htm"><b>Set</b></a><b>, </b>
+<a href="qset_r.h"><b>qset_r.h</b></a><b>, </b>
+<a href="qset_r.c"><b>qset_r.c</b></a> </dt>
+<dd>Set routines. Qhull implements its data structures as
+sets. A set is an array of pointers that is expanded as
+needed. This is a separate package that may be used in
+other applications. </dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-stat_r.htm"><b>Stat</b></a><b>, </b>
+<a href="stat_r.h"><b>stat_r.h</b></a><b>, </b>
+<a href="stat_r.c"><b>stat_r.c</b></a> </dt>
+<dd>Statistical routines. Qhull maintains statistics about
+its implementation. </dd>
+
+<dt>&nbsp;</dt>
+<dt><a href="qh-user_r.htm"><b>User</b></a><b>, </b>
+<a href="user_r.h"><b>user_r.h</b></a><b>, </b>
+<a href="user_r.c"><b>user_r.c</b></a><b>, </b>
+<a href="../user_eg/user_eg_r.c"><b>user_eg_r.c</b></a><b>, </b>
+<a href="../user_eg2/user_eg2_r.c"><b>user_eg2_r.c</b></a><b>, </b>
+<a href="../user_eg3/user_eg3_r.cpp"><b>user_eg3_r.cpp</b></a><b>, </b>
+</dt>
+<dd>User-defined routines. Qhull allows the user to configure
+the code with defined constants and specialized routines.
+</dd>
+</dl>
+</blockquote>
+
+</blockquote>
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="#TOC">Qhull files</a><br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull_r/io_r.c b/xs/src/qhull/src/libqhull_r/io_r.c
new file mode 100644
index 000000000..9721a000d
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/io_r.c
@@ -0,0 +1,4062 @@
+/*<html><pre> -<a href="qh-io_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ io_r.c
+ Input/Output routines of qhull application
+
+ see qh-io_r.htm and io_r.h
+
+ see user_r.c for qh_errprint and qh_printfacetlist
+
+ unix_r.c calls qh_readpoints and qh_produce_output
+
+ unix_r.c and user_r.c are the only callers of io_r.c functions
+ This allows the user to avoid loading io_r.o from qhull.a
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/io_r.c#4 $$Change: 2064 $
+ $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
+*/
+
+#include "qhull_ra.h"
+
+/*========= -functions in alphabetical order after qh_produce_output(qh) =====*/
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="produce_output">-</a>
+
+ qh_produce_output(qh)
+ qh_produce_output2(qh)
+ prints out the result of qhull in desired format
+ qh_produce_output2(qh) does not call qh_prepare_output(qh)
+ if qh.GETarea
+ computes and prints area and volume
+ qh.PRINTout[] is an array of output formats
+
+ notes:
+ prints output in qh.PRINTout order
+*/
+void qh_produce_output(qhT *qh) {
+ int tempsize= qh_setsize(qh, qh->qhmem.tempstack);
+
+ qh_prepare_output(qh);
+ qh_produce_output2(qh);
+ if (qh_setsize(qh, qh->qhmem.tempstack) != tempsize) {
+ qh_fprintf(qh, qh->ferr, 6206, "qhull internal error (qh_produce_output): temporary sets not empty(%d)\n",
+ qh_setsize(qh, qh->qhmem.tempstack));
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+} /* produce_output */
+
+
+void qh_produce_output2(qhT *qh) {
+ int i, tempsize= qh_setsize(qh, qh->qhmem.tempstack), d_1;
+
+ if (qh->PRINTsummary)
+ qh_printsummary(qh, qh->ferr);
+ else if (qh->PRINTout[0] == qh_PRINTnone)
+ qh_printsummary(qh, qh->fout);
+ for (i=0; i < qh_PRINTEND; i++)
+ qh_printfacets(qh, qh->fout, qh->PRINTout[i], qh->facet_list, NULL, !qh_ALL);
+ qh_allstatistics(qh);
+ if (qh->PRINTprecision && !qh->MERGING && (qh->JOGGLEmax > REALmax/2 || qh->RERUN))
+ qh_printstats(qh, qh->ferr, qh->qhstat.precision, NULL);
+ if (qh->VERIFYoutput && (zzval_(Zridge) > 0 || zzval_(Zridgemid) > 0))
+ qh_printstats(qh, qh->ferr, qh->qhstat.vridges, NULL);
+ if (qh->PRINTstatistics) {
+ qh_printstatistics(qh, qh->ferr, "");
+ qh_memstatistics(qh, qh->ferr);
+ d_1= sizeof(setT) + (qh->hull_dim - 1) * SETelemsize;
+ qh_fprintf(qh, qh->ferr, 8040, "\
+ size in bytes: merge %d ridge %d vertex %d facet %d\n\
+ normal %d ridge vertices %d facet vertices or neighbors %d\n",
+ (int)sizeof(mergeT), (int)sizeof(ridgeT),
+ (int)sizeof(vertexT), (int)sizeof(facetT),
+ qh->normal_size, d_1, d_1 + SETelemsize);
+ }
+ if (qh_setsize(qh, qh->qhmem.tempstack) != tempsize) {
+ qh_fprintf(qh, qh->ferr, 6065, "qhull internal error (qh_produce_output2): temporary sets not empty(%d)\n",
+ qh_setsize(qh, qh->qhmem.tempstack));
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+} /* produce_output2 */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="dfacet">-</a>
+
+ qh_dfacet(qh, id )
+ print facet by id, for debugging
+
+*/
+void qh_dfacet(qhT *qh, unsigned id) {
+ facetT *facet;
+
+ FORALLfacets {
+ if (facet->id == id) {
+ qh_printfacet(qh, qh->fout, facet);
+ break;
+ }
+ }
+} /* dfacet */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="dvertex">-</a>
+
+ qh_dvertex(qh, id )
+ print vertex by id, for debugging
+*/
+void qh_dvertex(qhT *qh, unsigned id) {
+ vertexT *vertex;
+
+ FORALLvertices {
+ if (vertex->id == id) {
+ qh_printvertex(qh, qh->fout, vertex);
+ break;
+ }
+ }
+} /* dvertex */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="compare_facetarea">-</a>
+
+ qh_compare_facetarea(p1, p2 )
+ used by qsort() to order facets by area
+*/
+int qh_compare_facetarea(const void *p1, const void *p2) {
+ const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)p2);
+
+ if (!a->isarea)
+ return -1;
+ if (!b->isarea)
+ return 1;
+ if (a->f.area > b->f.area)
+ return 1;
+ else if (a->f.area == b->f.area)
+ return 0;
+ return -1;
+} /* compare_facetarea */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="compare_facetmerge">-</a>
+
+ qh_compare_facetmerge(p1, p2 )
+ used by qsort() to order facets by number of merges
+*/
+int qh_compare_facetmerge(const void *p1, const void *p2) {
+ const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)p2);
+
+ return(a->nummerge - b->nummerge);
+} /* compare_facetvisit */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="compare_facetvisit">-</a>
+
+ qh_compare_facetvisit(p1, p2 )
+ used by qsort() to order facets by visit id or id
+*/
+int qh_compare_facetvisit(const void *p1, const void *p2) {
+ const facetT *a= *((facetT *const*)p1), *b= *((facetT *const*)p2);
+ int i,j;
+
+ if (!(i= a->visitid))
+ i= 0 - a->id; /* do not convert to int, sign distinguishes id from visitid */
+ if (!(j= b->visitid))
+ j= 0 - b->id;
+ return(i - j);
+} /* compare_facetvisit */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="compare_vertexpoint">-</a>
+
+ qh_compare_vertexpoint( p1, p2 )
+ used by qsort() to order vertices by point id
+
+ Not usable in qhulllib_r since qh_pointid depends on qh
+
+ int qh_compare_vertexpoint(const void *p1, const void *p2) {
+ const vertexT *a= *((vertexT *const*)p1), *b= *((vertexT *const*)p2);
+
+ return((qh_pointid(qh, a->point) > qh_pointid(qh, b->point)?1:-1));
+}*/
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="copyfilename">-</a>
+
+ qh_copyfilename(qh, dest, size, source, length )
+ copy filename identified by qh_skipfilename()
+
+ notes:
+ see qh_skipfilename() for syntax
+*/
+void qh_copyfilename(qhT *qh, char *filename, int size, const char* source, int length) {
+ char c= *source;
+
+ if (length > size + 1) {
+ qh_fprintf(qh, qh->ferr, 6040, "qhull error: filename is more than %d characters, %s\n", size-1, source);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ strncpy(filename, source, length);
+ filename[length]= '\0';
+ if (c == '\'' || c == '"') {
+ char *s= filename + 1;
+ char *t= filename;
+ while (*s) {
+ if (*s == c) {
+ if (s[-1] == '\\')
+ t[-1]= c;
+ }else
+ *t++= *s;
+ s++;
+ }
+ *t= '\0';
+ }
+} /* copyfilename */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="countfacets">-</a>
+
+ qh_countfacets(qh, facetlist, facets, printall,
+ numfacets, numsimplicial, totneighbors, numridges, numcoplanar, numtricoplanars )
+ count good facets for printing and set visitid
+ if allfacets, ignores qh_skipfacet()
+
+ notes:
+ qh_printsummary and qh_countfacets must match counts
+
+ returns:
+ numfacets, numsimplicial, total neighbors, numridges, coplanars
+ each facet with ->visitid indicating 1-relative position
+ ->visitid==0 indicates not good
+
+ notes
+ numfacets >= numsimplicial
+ if qh.NEWfacets,
+ does not count visible facets (matches qh_printafacet)
+
+ design:
+ for all facets on facetlist and in facets set
+ unless facet is skipped or visible (i.e., will be deleted)
+ mark facet->visitid
+ update counts
+*/
+void qh_countfacets(qhT *qh, facetT *facetlist, setT *facets, boolT printall,
+ int *numfacetsp, int *numsimplicialp, int *totneighborsp, int *numridgesp, int *numcoplanarsp, int *numtricoplanarsp) {
+ facetT *facet, **facetp;
+ int numfacets= 0, numsimplicial= 0, numridges= 0, totneighbors= 0, numcoplanars= 0, numtricoplanars= 0;
+
+ FORALLfacet_(facetlist) {
+ if ((facet->visible && qh->NEWfacets)
+ || (!printall && qh_skipfacet(qh, facet)))
+ facet->visitid= 0;
+ else {
+ facet->visitid= ++numfacets;
+ totneighbors += qh_setsize(qh, facet->neighbors);
+ if (facet->simplicial) {
+ numsimplicial++;
+ if (facet->keepcentrum && facet->tricoplanar)
+ numtricoplanars++;
+ }else
+ numridges += qh_setsize(qh, facet->ridges);
+ if (facet->coplanarset)
+ numcoplanars += qh_setsize(qh, facet->coplanarset);
+ }
+ }
+
+ FOREACHfacet_(facets) {
+ if ((facet->visible && qh->NEWfacets)
+ || (!printall && qh_skipfacet(qh, facet)))
+ facet->visitid= 0;
+ else {
+ facet->visitid= ++numfacets;
+ totneighbors += qh_setsize(qh, facet->neighbors);
+ if (facet->simplicial){
+ numsimplicial++;
+ if (facet->keepcentrum && facet->tricoplanar)
+ numtricoplanars++;
+ }else
+ numridges += qh_setsize(qh, facet->ridges);
+ if (facet->coplanarset)
+ numcoplanars += qh_setsize(qh, facet->coplanarset);
+ }
+ }
+ qh->visit_id += numfacets+1;
+ *numfacetsp= numfacets;
+ *numsimplicialp= numsimplicial;
+ *totneighborsp= totneighbors;
+ *numridgesp= numridges;
+ *numcoplanarsp= numcoplanars;
+ *numtricoplanarsp= numtricoplanars;
+} /* countfacets */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="detvnorm">-</a>
+
+ qh_detvnorm(qh, vertex, vertexA, centers, offset )
+ compute separating plane of the Voronoi diagram for a pair of input sites
+ centers= set of facets (i.e., Voronoi vertices)
+ facet->visitid= 0 iff vertex-at-infinity (i.e., unbounded)
+
+ assumes:
+ qh_ASvoronoi and qh_vertexneighbors() already set
+
+ returns:
+ norm
+ a pointer into qh.gm_matrix to qh.hull_dim-1 reals
+ copy the data before reusing qh.gm_matrix
+ offset
+ if 'QVn'
+ sign adjusted so that qh.GOODvertexp is inside
+ else
+ sign adjusted so that vertex is inside
+
+ qh.gm_matrix= simplex of points from centers relative to first center
+
+ notes:
+ in io_r.c so that code for 'v Tv' can be removed by removing io_r.c
+ returns pointer into qh.gm_matrix to avoid tracking of temporary memory
+
+ design:
+ determine midpoint of input sites
+ build points as the set of Voronoi vertices
+ select a simplex from points (if necessary)
+ include midpoint if the Voronoi region is unbounded
+ relocate the first vertex of the simplex to the origin
+ compute the normalized hyperplane through the simplex
+ orient the hyperplane toward 'QVn' or 'vertex'
+ if 'Tv' or 'Ts'
+ if bounded
+ test that hyperplane is the perpendicular bisector of the input sites
+ test that Voronoi vertices not in the simplex are still on the hyperplane
+ free up temporary memory
+*/
+pointT *qh_detvnorm(qhT *qh, vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp) {
+ facetT *facet, **facetp;
+ int i, k, pointid, pointidA, point_i, point_n;
+ setT *simplex= NULL;
+ pointT *point, **pointp, *point0, *midpoint, *normal, *inpoint;
+ coordT *coord, *gmcoord, *normalp;
+ setT *points= qh_settemp(qh, qh->TEMPsize);
+ boolT nearzero= False;
+ boolT unbounded= False;
+ int numcenters= 0;
+ int dim= qh->hull_dim - 1;
+ realT dist, offset, angle, zero= 0.0;
+
+ midpoint= qh->gm_matrix + qh->hull_dim * qh->hull_dim; /* last row */
+ for (k=0; k < dim; k++)
+ midpoint[k]= (vertex->point[k] + vertexA->point[k])/2;
+ FOREACHfacet_(centers) {
+ numcenters++;
+ if (!facet->visitid)
+ unbounded= True;
+ else {
+ if (!facet->center)
+ facet->center= qh_facetcenter(qh, facet->vertices);
+ qh_setappend(qh, &points, facet->center);
+ }
+ }
+ if (numcenters > dim) {
+ simplex= qh_settemp(qh, qh->TEMPsize);
+ qh_setappend(qh, &simplex, vertex->point);
+ if (unbounded)
+ qh_setappend(qh, &simplex, midpoint);
+ qh_maxsimplex(qh, dim, points, NULL, 0, &simplex);
+ qh_setdelnth(qh, simplex, 0);
+ }else if (numcenters == dim) {
+ if (unbounded)
+ qh_setappend(qh, &points, midpoint);
+ simplex= points;
+ }else {
+ qh_fprintf(qh, qh->ferr, 6216, "qhull internal error (qh_detvnorm): too few points(%d) to compute separating plane\n", numcenters);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ i= 0;
+ gmcoord= qh->gm_matrix;
+ point0= SETfirstt_(simplex, pointT);
+ FOREACHpoint_(simplex) {
+ if (qh->IStracing >= 4)
+ qh_printmatrix(qh, qh->ferr, "qh_detvnorm: Voronoi vertex or midpoint",
+ &point, 1, dim);
+ if (point != point0) {
+ qh->gm_row[i++]= gmcoord;
+ coord= point0;
+ for (k=dim; k--; )
+ *(gmcoord++)= *point++ - *coord++;
+ }
+ }
+ qh->gm_row[i]= gmcoord; /* does not overlap midpoint, may be used later for qh_areasimplex */
+ normal= gmcoord;
+ qh_sethyperplane_gauss(qh, dim, qh->gm_row, point0, True,
+ normal, &offset, &nearzero);
+ if (qh->GOODvertexp == vertexA->point)
+ inpoint= vertexA->point;
+ else
+ inpoint= vertex->point;
+ zinc_(Zdistio);
+ dist= qh_distnorm(dim, inpoint, normal, &offset);
+ if (dist > 0) {
+ offset= -offset;
+ normalp= normal;
+ for (k=dim; k--; ) {
+ *normalp= -(*normalp);
+ normalp++;
+ }
+ }
+ if (qh->VERIFYoutput || qh->PRINTstatistics) {
+ pointid= qh_pointid(qh, vertex->point);
+ pointidA= qh_pointid(qh, vertexA->point);
+ if (!unbounded) {
+ zinc_(Zdiststat);
+ dist= qh_distnorm(dim, midpoint, normal, &offset);
+ if (dist < 0)
+ dist= -dist;
+ zzinc_(Zridgemid);
+ wwmax_(Wridgemidmax, dist);
+ wwadd_(Wridgemid, dist);
+ trace4((qh, qh->ferr, 4014, "qh_detvnorm: points %d %d midpoint dist %2.2g\n",
+ pointid, pointidA, dist));
+ for (k=0; k < dim; k++)
+ midpoint[k]= vertexA->point[k] - vertex->point[k]; /* overwrites midpoint! */
+ qh_normalize(qh, midpoint, dim, False);
+ angle= qh_distnorm(dim, midpoint, normal, &zero); /* qh_detangle uses dim+1 */
+ if (angle < 0.0)
+ angle= angle + 1.0;
+ else
+ angle= angle - 1.0;
+ if (angle < 0.0)
+ angle -= angle;
+ trace4((qh, qh->ferr, 4015, "qh_detvnorm: points %d %d angle %2.2g nearzero %d\n",
+ pointid, pointidA, angle, nearzero));
+ if (nearzero) {
+ zzinc_(Zridge0);
+ wwmax_(Wridge0max, angle);
+ wwadd_(Wridge0, angle);
+ }else {
+ zzinc_(Zridgeok)
+ wwmax_(Wridgeokmax, angle);
+ wwadd_(Wridgeok, angle);
+ }
+ }
+ if (simplex != points) {
+ FOREACHpoint_i_(qh, points) {
+ if (!qh_setin(simplex, point)) {
+ facet= SETelemt_(centers, point_i, facetT);
+ zinc_(Zdiststat);
+ dist= qh_distnorm(dim, point, normal, &offset);
+ if (dist < 0)
+ dist= -dist;
+ zzinc_(Zridge);
+ wwmax_(Wridgemax, dist);
+ wwadd_(Wridge, dist);
+ trace4((qh, qh->ferr, 4016, "qh_detvnorm: points %d %d Voronoi vertex %d dist %2.2g\n",
+ pointid, pointidA, facet->visitid, dist));
+ }
+ }
+ }
+ }
+ *offsetp= offset;
+ if (simplex != points)
+ qh_settempfree(qh, &simplex);
+ qh_settempfree(qh, &points);
+ return normal;
+} /* detvnorm */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="detvridge">-</a>
+
+ qh_detvridge(qh, vertexA )
+ determine Voronoi ridge from 'seen' neighbors of vertexA
+ include one vertex-at-infinite if an !neighbor->visitid
+
+ returns:
+ temporary set of centers (facets, i.e., Voronoi vertices)
+ sorted by center id
+*/
+setT *qh_detvridge(qhT *qh, vertexT *vertex) {
+ setT *centers= qh_settemp(qh, qh->TEMPsize);
+ setT *tricenters= qh_settemp(qh, qh->TEMPsize);
+ facetT *neighbor, **neighborp;
+ boolT firstinf= True;
+
+ FOREACHneighbor_(vertex) {
+ if (neighbor->seen) {
+ if (neighbor->visitid) {
+ if (!neighbor->tricoplanar || qh_setunique(qh, &tricenters, neighbor->center))
+ qh_setappend(qh, &centers, neighbor);
+ }else if (firstinf) {
+ firstinf= False;
+ qh_setappend(qh, &centers, neighbor);
+ }
+ }
+ }
+ qsort(SETaddr_(centers, facetT), (size_t)qh_setsize(qh, centers),
+ sizeof(facetT *), qh_compare_facetvisit);
+ qh_settempfree(qh, &tricenters);
+ return centers;
+} /* detvridge */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="detvridge3">-</a>
+
+ qh_detvridge3(qh, atvertex, vertex )
+ determine 3-d Voronoi ridge from 'seen' neighbors of atvertex and vertex
+ include one vertex-at-infinite for !neighbor->visitid
+ assumes all facet->seen2= True
+
+ returns:
+ temporary set of centers (facets, i.e., Voronoi vertices)
+ listed in adjacency order (!oriented)
+ all facet->seen2= True
+
+ design:
+ mark all neighbors of atvertex
+ for each adjacent neighbor of both atvertex and vertex
+ if neighbor selected
+ add neighbor to set of Voronoi vertices
+*/
+setT *qh_detvridge3(qhT *qh, vertexT *atvertex, vertexT *vertex) {
+ setT *centers= qh_settemp(qh, qh->TEMPsize);
+ setT *tricenters= qh_settemp(qh, qh->TEMPsize);
+ facetT *neighbor, **neighborp, *facet= NULL;
+ boolT firstinf= True;
+
+ FOREACHneighbor_(atvertex)
+ neighbor->seen2= False;
+ FOREACHneighbor_(vertex) {
+ if (!neighbor->seen2) {
+ facet= neighbor;
+ break;
+ }
+ }
+ while (facet) {
+ facet->seen2= True;
+ if (neighbor->seen) {
+ if (facet->visitid) {
+ if (!facet->tricoplanar || qh_setunique(qh, &tricenters, facet->center))
+ qh_setappend(qh, &centers, facet);
+ }else if (firstinf) {
+ firstinf= False;
+ qh_setappend(qh, &centers, facet);
+ }
+ }
+ FOREACHneighbor_(facet) {
+ if (!neighbor->seen2) {
+ if (qh_setin(vertex->neighbors, neighbor))
+ break;
+ else
+ neighbor->seen2= True;
+ }
+ }
+ facet= neighbor;
+ }
+ if (qh->CHECKfrequently) {
+ FOREACHneighbor_(vertex) {
+ if (!neighbor->seen2) {
+ qh_fprintf(qh, qh->ferr, 6217, "qhull internal error (qh_detvridge3): neighbors of vertex p%d are not connected at facet %d\n",
+ qh_pointid(qh, vertex->point), neighbor->id);
+ qh_errexit(qh, qh_ERRqhull, neighbor, NULL);
+ }
+ }
+ }
+ FOREACHneighbor_(atvertex)
+ neighbor->seen2= True;
+ qh_settempfree(qh, &tricenters);
+ return centers;
+} /* detvridge3 */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="eachvoronoi">-</a>
+
+ qh_eachvoronoi(qh, fp, printvridge, vertex, visitall, innerouter, inorder )
+ if visitall,
+ visit all Voronoi ridges for vertex (i.e., an input site)
+ else
+ visit all unvisited Voronoi ridges for vertex
+ all vertex->seen= False if unvisited
+ assumes
+ all facet->seen= False
+ all facet->seen2= True (for qh_detvridge3)
+ all facet->visitid == 0 if vertex_at_infinity
+ == index of Voronoi vertex
+ >= qh.num_facets if ignored
+ innerouter:
+ qh_RIDGEall-- both inner (bounded) and outer(unbounded) ridges
+ qh_RIDGEinner- only inner
+ qh_RIDGEouter- only outer
+
+ if inorder
+ orders vertices for 3-d Voronoi diagrams
+
+ returns:
+ number of visited ridges (does not include previously visited ridges)
+
+ if printvridge,
+ calls printvridge( fp, vertex, vertexA, centers)
+ fp== any pointer (assumes FILE*)
+ vertex,vertexA= pair of input sites that define a Voronoi ridge
+ centers= set of facets (i.e., Voronoi vertices)
+ ->visitid == index or 0 if vertex_at_infinity
+ ordered for 3-d Voronoi diagram
+ notes:
+ uses qh.vertex_visit
+
+ see:
+ qh_eachvoronoi_all()
+
+ design:
+ mark selected neighbors of atvertex
+ for each selected neighbor (either Voronoi vertex or vertex-at-infinity)
+ for each unvisited vertex
+ if atvertex and vertex share more than d-1 neighbors
+ bump totalcount
+ if printvridge defined
+ build the set of shared neighbors (i.e., Voronoi vertices)
+ call printvridge
+*/
+int qh_eachvoronoi(qhT *qh, FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder) {
+ boolT unbounded;
+ int count;
+ facetT *neighbor, **neighborp, *neighborA, **neighborAp;
+ setT *centers;
+ setT *tricenters= qh_settemp(qh, qh->TEMPsize);
+
+ vertexT *vertex, **vertexp;
+ boolT firstinf;
+ unsigned int numfacets= (unsigned int)qh->num_facets;
+ int totridges= 0;
+
+ qh->vertex_visit++;
+ atvertex->seen= True;
+ if (visitall) {
+ FORALLvertices
+ vertex->seen= False;
+ }
+ FOREACHneighbor_(atvertex) {
+ if (neighbor->visitid < numfacets)
+ neighbor->seen= True;
+ }
+ FOREACHneighbor_(atvertex) {
+ if (neighbor->seen) {
+ FOREACHvertex_(neighbor->vertices) {
+ if (vertex->visitid != qh->vertex_visit && !vertex->seen) {
+ vertex->visitid= qh->vertex_visit;
+ count= 0;
+ firstinf= True;
+ qh_settruncate(qh, tricenters, 0);
+ FOREACHneighborA_(vertex) {
+ if (neighborA->seen) {
+ if (neighborA->visitid) {
+ if (!neighborA->tricoplanar || qh_setunique(qh, &tricenters, neighborA->center))
+ count++;
+ }else if (firstinf) {
+ count++;
+ firstinf= False;
+ }
+ }
+ }
+ if (count >= qh->hull_dim - 1) { /* e.g., 3 for 3-d Voronoi */
+ if (firstinf) {
+ if (innerouter == qh_RIDGEouter)
+ continue;
+ unbounded= False;
+ }else {
+ if (innerouter == qh_RIDGEinner)
+ continue;
+ unbounded= True;
+ }
+ totridges++;
+ trace4((qh, qh->ferr, 4017, "qh_eachvoronoi: Voronoi ridge of %d vertices between sites %d and %d\n",
+ count, qh_pointid(qh, atvertex->point), qh_pointid(qh, vertex->point)));
+ if (printvridge && fp) {
+ if (inorder && qh->hull_dim == 3+1) /* 3-d Voronoi diagram */
+ centers= qh_detvridge3(qh, atvertex, vertex);
+ else
+ centers= qh_detvridge(qh, vertex);
+ (*printvridge)(qh, fp, atvertex, vertex, centers, unbounded);
+ qh_settempfree(qh, &centers);
+ }
+ }
+ }
+ }
+ }
+ }
+ FOREACHneighbor_(atvertex)
+ neighbor->seen= False;
+ qh_settempfree(qh, &tricenters);
+ return totridges;
+} /* eachvoronoi */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="eachvoronoi_all">-</a>
+
+ qh_eachvoronoi_all(qh, fp, printvridge, isUpper, innerouter, inorder )
+ visit all Voronoi ridges
+
+ innerouter:
+ see qh_eachvoronoi()
+
+ if inorder
+ orders vertices for 3-d Voronoi diagrams
+
+ returns
+ total number of ridges
+
+ if isUpper == facet->upperdelaunay (i.e., a Vornoi vertex)
+ facet->visitid= Voronoi vertex index(same as 'o' format)
+ else
+ facet->visitid= 0
+
+ if printvridge,
+ calls printvridge( fp, vertex, vertexA, centers)
+ [see qh_eachvoronoi]
+
+ notes:
+ Not used for qhull.exe
+ same effect as qh_printvdiagram but ridges not sorted by point id
+*/
+int qh_eachvoronoi_all(qhT *qh, FILE *fp, printvridgeT printvridge, boolT isUpper, qh_RIDGE innerouter, boolT inorder) {
+ facetT *facet;
+ vertexT *vertex;
+ int numcenters= 1; /* vertex 0 is vertex-at-infinity */
+ int totridges= 0;
+
+ qh_clearcenters(qh, qh_ASvoronoi);
+ qh_vertexneighbors(qh);
+ maximize_(qh->visit_id, (unsigned) qh->num_facets);
+ FORALLfacets {
+ facet->visitid= 0;
+ facet->seen= False;
+ facet->seen2= True;
+ }
+ FORALLfacets {
+ if (facet->upperdelaunay == isUpper)
+ facet->visitid= numcenters++;
+ }
+ FORALLvertices
+ vertex->seen= False;
+ FORALLvertices {
+ if (qh->GOODvertex > 0 && qh_pointid(qh, vertex->point)+1 != qh->GOODvertex)
+ continue;
+ totridges += qh_eachvoronoi(qh, fp, printvridge, vertex,
+ !qh_ALL, innerouter, inorder);
+ }
+ return totridges;
+} /* eachvoronoi_all */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="facet2point">-</a>
+
+ qh_facet2point(qh, facet, point0, point1, mindist )
+ return two projected temporary vertices for a 2-d facet
+ may be non-simplicial
+
+ returns:
+ point0 and point1 oriented and projected to the facet
+ returns mindist (maximum distance below plane)
+*/
+void qh_facet2point(qhT *qh, facetT *facet, pointT **point0, pointT **point1, realT *mindist) {
+ vertexT *vertex0, *vertex1;
+ realT dist;
+
+ if (facet->toporient ^ qh_ORIENTclock) {
+ vertex0= SETfirstt_(facet->vertices, vertexT);
+ vertex1= SETsecondt_(facet->vertices, vertexT);
+ }else {
+ vertex1= SETfirstt_(facet->vertices, vertexT);
+ vertex0= SETsecondt_(facet->vertices, vertexT);
+ }
+ zadd_(Zdistio, 2);
+ qh_distplane(qh, vertex0->point, facet, &dist);
+ *mindist= dist;
+ *point0= qh_projectpoint(qh, vertex0->point, facet, dist);
+ qh_distplane(qh, vertex1->point, facet, &dist);
+ minimize_(*mindist, dist);
+ *point1= qh_projectpoint(qh, vertex1->point, facet, dist);
+} /* facet2point */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="facetvertices">-</a>
+
+ qh_facetvertices(qh, facetlist, facets, allfacets )
+ returns temporary set of vertices in a set and/or list of facets
+ if allfacets, ignores qh_skipfacet()
+
+ returns:
+ vertices with qh.vertex_visit
+
+ notes:
+ optimized for allfacets of facet_list
+
+ design:
+ if allfacets of facet_list
+ create vertex set from vertex_list
+ else
+ for each selected facet in facets or facetlist
+ append unvisited vertices to vertex set
+*/
+setT *qh_facetvertices(qhT *qh, facetT *facetlist, setT *facets, boolT allfacets) {
+ setT *vertices;
+ facetT *facet, **facetp;
+ vertexT *vertex, **vertexp;
+
+ qh->vertex_visit++;
+ if (facetlist == qh->facet_list && allfacets && !facets) {
+ vertices= qh_settemp(qh, qh->num_vertices);
+ FORALLvertices {
+ vertex->visitid= qh->vertex_visit;
+ qh_setappend(qh, &vertices, vertex);
+ }
+ }else {
+ vertices= qh_settemp(qh, qh->TEMPsize);
+ FORALLfacet_(facetlist) {
+ if (!allfacets && qh_skipfacet(qh, facet))
+ continue;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->visitid != qh->vertex_visit) {
+ vertex->visitid= qh->vertex_visit;
+ qh_setappend(qh, &vertices, vertex);
+ }
+ }
+ }
+ }
+ FOREACHfacet_(facets) {
+ if (!allfacets && qh_skipfacet(qh, facet))
+ continue;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->visitid != qh->vertex_visit) {
+ vertex->visitid= qh->vertex_visit;
+ qh_setappend(qh, &vertices, vertex);
+ }
+ }
+ }
+ return vertices;
+} /* facetvertices */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="geomplanes">-</a>
+
+ qh_geomplanes(qh, facet, outerplane, innerplane )
+ return outer and inner planes for Geomview
+ qh.PRINTradius is size of vertices and points (includes qh.JOGGLEmax)
+
+ notes:
+ assume precise calculations in io.c with roundoff covered by qh_GEOMepsilon
+*/
+void qh_geomplanes(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane) {
+ realT radius;
+
+ if (qh->MERGING || qh->JOGGLEmax < REALmax/2) {
+ qh_outerinner(qh, facet, outerplane, innerplane);
+ radius= qh->PRINTradius;
+ if (qh->JOGGLEmax < REALmax/2)
+ radius -= qh->JOGGLEmax * sqrt((realT)qh->hull_dim); /* already accounted for in qh_outerinner() */
+ *outerplane += radius;
+ *innerplane -= radius;
+ if (qh->PRINTcoplanar || qh->PRINTspheres) {
+ *outerplane += qh->MAXabs_coord * qh_GEOMepsilon;
+ *innerplane -= qh->MAXabs_coord * qh_GEOMepsilon;
+ }
+ }else
+ *innerplane= *outerplane= 0;
+} /* geomplanes */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="markkeep">-</a>
+
+ qh_markkeep(qh, facetlist )
+ mark good facets that meet qh.KEEParea, qh.KEEPmerge, and qh.KEEPminArea
+ ignores visible facets (!part of convex hull)
+
+ returns:
+ may clear facet->good
+ recomputes qh.num_good
+
+ design:
+ get set of good facets
+ if qh.KEEParea
+ sort facets by area
+ clear facet->good for all but n largest facets
+ if qh.KEEPmerge
+ sort facets by merge count
+ clear facet->good for all but n most merged facets
+ if qh.KEEPminarea
+ clear facet->good if area too small
+ update qh.num_good
+*/
+void qh_markkeep(qhT *qh, facetT *facetlist) {
+ facetT *facet, **facetp;
+ setT *facets= qh_settemp(qh, qh->num_facets);
+ int size, count;
+
+ trace2((qh, qh->ferr, 2006, "qh_markkeep: only keep %d largest and/or %d most merged facets and/or min area %.2g\n",
+ qh->KEEParea, qh->KEEPmerge, qh->KEEPminArea));
+ FORALLfacet_(facetlist) {
+ if (!facet->visible && facet->good)
+ qh_setappend(qh, &facets, facet);
+ }
+ size= qh_setsize(qh, facets);
+ if (qh->KEEParea) {
+ qsort(SETaddr_(facets, facetT), (size_t)size,
+ sizeof(facetT *), qh_compare_facetarea);
+ if ((count= size - qh->KEEParea) > 0) {
+ FOREACHfacet_(facets) {
+ facet->good= False;
+ if (--count == 0)
+ break;
+ }
+ }
+ }
+ if (qh->KEEPmerge) {
+ qsort(SETaddr_(facets, facetT), (size_t)size,
+ sizeof(facetT *), qh_compare_facetmerge);
+ if ((count= size - qh->KEEPmerge) > 0) {
+ FOREACHfacet_(facets) {
+ facet->good= False;
+ if (--count == 0)
+ break;
+ }
+ }
+ }
+ if (qh->KEEPminArea < REALmax/2) {
+ FOREACHfacet_(facets) {
+ if (!facet->isarea || facet->f.area < qh->KEEPminArea)
+ facet->good= False;
+ }
+ }
+ qh_settempfree(qh, &facets);
+ count= 0;
+ FORALLfacet_(facetlist) {
+ if (facet->good)
+ count++;
+ }
+ qh->num_good= count;
+} /* markkeep */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="markvoronoi">-</a>
+
+ qh_markvoronoi(qh, facetlist, facets, printall, isLower, numcenters )
+ mark voronoi vertices for printing by site pairs
+
+ returns:
+ temporary set of vertices indexed by pointid
+ isLower set if printing lower hull (i.e., at least one facet is lower hull)
+ numcenters= total number of Voronoi vertices
+ bumps qh.printoutnum for vertex-at-infinity
+ clears all facet->seen and sets facet->seen2
+
+ if selected
+ facet->visitid= Voronoi vertex id
+ else if upper hull (or 'Qu' and lower hull)
+ facet->visitid= 0
+ else
+ facet->visitid >= qh->num_facets
+
+ notes:
+ ignores qh.ATinfinity, if defined
+*/
+setT *qh_markvoronoi(qhT *qh, facetT *facetlist, setT *facets, boolT printall, boolT *isLowerp, int *numcentersp) {
+ int numcenters=0;
+ facetT *facet, **facetp;
+ setT *vertices;
+ boolT isLower= False;
+
+ qh->printoutnum++;
+ qh_clearcenters(qh, qh_ASvoronoi); /* in case, qh_printvdiagram2 called by user */
+ qh_vertexneighbors(qh);
+ vertices= qh_pointvertex(qh);
+ if (qh->ATinfinity)
+ SETelem_(vertices, qh->num_points-1)= NULL;
+ qh->visit_id++;
+ maximize_(qh->visit_id, (unsigned) qh->num_facets);
+ FORALLfacet_(facetlist) {
+ if (printall || !qh_skipfacet(qh, facet)) {
+ if (!facet->upperdelaunay) {
+ isLower= True;
+ break;
+ }
+ }
+ }
+ FOREACHfacet_(facets) {
+ if (printall || !qh_skipfacet(qh, facet)) {
+ if (!facet->upperdelaunay) {
+ isLower= True;
+ break;
+ }
+ }
+ }
+ FORALLfacets {
+ if (facet->normal && (facet->upperdelaunay == isLower))
+ facet->visitid= 0; /* facetlist or facets may overwrite */
+ else
+ facet->visitid= qh->visit_id;
+ facet->seen= False;
+ facet->seen2= True;
+ }
+ numcenters++; /* qh_INFINITE */
+ FORALLfacet_(facetlist) {
+ if (printall || !qh_skipfacet(qh, facet))
+ facet->visitid= numcenters++;
+ }
+ FOREACHfacet_(facets) {
+ if (printall || !qh_skipfacet(qh, facet))
+ facet->visitid= numcenters++;
+ }
+ *isLowerp= isLower;
+ *numcentersp= numcenters;
+ trace2((qh, qh->ferr, 2007, "qh_markvoronoi: isLower %d numcenters %d\n", isLower, numcenters));
+ return vertices;
+} /* markvoronoi */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="order_vertexneighbors">-</a>
+
+ qh_order_vertexneighbors(qh, vertex )
+ order facet neighbors of a 2-d or 3-d vertex by adjacency
+
+ notes:
+ does not orient the neighbors
+
+ design:
+ initialize a new neighbor set with the first facet in vertex->neighbors
+ while vertex->neighbors non-empty
+ select next neighbor in the previous facet's neighbor set
+ set vertex->neighbors to the new neighbor set
+*/
+void qh_order_vertexneighbors(qhT *qh, vertexT *vertex) {
+ setT *newset;
+ facetT *facet, *neighbor, **neighborp;
+
+ trace4((qh, qh->ferr, 4018, "qh_order_vertexneighbors: order neighbors of v%d for 3-d\n", vertex->id));
+ newset= qh_settemp(qh, qh_setsize(qh, vertex->neighbors));
+ facet= (facetT*)qh_setdellast(vertex->neighbors);
+ qh_setappend(qh, &newset, facet);
+ while (qh_setsize(qh, vertex->neighbors)) {
+ FOREACHneighbor_(vertex) {
+ if (qh_setin(facet->neighbors, neighbor)) {
+ qh_setdel(vertex->neighbors, neighbor);
+ qh_setappend(qh, &newset, neighbor);
+ facet= neighbor;
+ break;
+ }
+ }
+ if (!neighbor) {
+ qh_fprintf(qh, qh->ferr, 6066, "qhull internal error (qh_order_vertexneighbors): no neighbor of v%d for f%d\n",
+ vertex->id, facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ }
+ qh_setfree(qh, &vertex->neighbors);
+ qh_settemppop(qh);
+ vertex->neighbors= newset;
+} /* order_vertexneighbors */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="prepare_output">-</a>
+
+ qh_prepare_output(qh, )
+ prepare for qh_produce_output2(qh) according to
+ qh.KEEPminArea, KEEParea, KEEPmerge, GOODvertex, GOODthreshold, GOODpoint, ONLYgood, SPLITthresholds
+ does not reset facet->good
+
+ notes
+ except for PRINTstatistics, no-op if previously called with same options
+*/
+void qh_prepare_output(qhT *qh) {
+ if (qh->VORONOI) {
+ qh_clearcenters(qh, qh_ASvoronoi); /* must be before qh_triangulate */
+ qh_vertexneighbors(qh);
+ }
+ if (qh->TRIangulate && !qh->hasTriangulation) {
+ qh_triangulate(qh);
+ if (qh->VERIFYoutput && !qh->CHECKfrequently)
+ qh_checkpolygon(qh, qh->facet_list);
+ }
+ qh_findgood_all(qh, qh->facet_list);
+ if (qh->GETarea)
+ qh_getarea(qh, qh->facet_list);
+ if (qh->KEEParea || qh->KEEPmerge || qh->KEEPminArea < REALmax/2)
+ qh_markkeep(qh, qh->facet_list);
+ if (qh->PRINTstatistics)
+ qh_collectstatistics(qh);
+}
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printafacet">-</a>
+
+ qh_printafacet(qh, fp, format, facet, printall )
+ print facet to fp in given output format (see qh.PRINTout)
+
+ returns:
+ nop if !printall and qh_skipfacet()
+ nop if visible facet and NEWfacets and format != PRINTfacets
+ must match qh_countfacets
+
+ notes
+ preserves qh.visit_id
+ facet->normal may be null if PREmerge/MERGEexact and STOPcone before merge
+
+ see
+ qh_printbegin() and qh_printend()
+
+ design:
+ test for printing facet
+ call appropriate routine for format
+ or output results directly
+*/
+void qh_printafacet(qhT *qh, FILE *fp, qh_PRINT format, facetT *facet, boolT printall) {
+ realT color[4], offset, dist, outerplane, innerplane;
+ boolT zerodiv;
+ coordT *point, *normp, *coordp, **pointp, *feasiblep;
+ int k;
+ vertexT *vertex, **vertexp;
+ facetT *neighbor, **neighborp;
+
+ if (!printall && qh_skipfacet(qh, facet))
+ return;
+ if (facet->visible && qh->NEWfacets && format != qh_PRINTfacets)
+ return;
+ qh->printoutnum++;
+ switch (format) {
+ case qh_PRINTarea:
+ if (facet->isarea) {
+ qh_fprintf(qh, fp, 9009, qh_REAL_1, facet->f.area);
+ qh_fprintf(qh, fp, 9010, "\n");
+ }else
+ qh_fprintf(qh, fp, 9011, "0\n");
+ break;
+ case qh_PRINTcoplanars:
+ qh_fprintf(qh, fp, 9012, "%d", qh_setsize(qh, facet->coplanarset));
+ FOREACHpoint_(facet->coplanarset)
+ qh_fprintf(qh, fp, 9013, " %d", qh_pointid(qh, point));
+ qh_fprintf(qh, fp, 9014, "\n");
+ break;
+ case qh_PRINTcentrums:
+ qh_printcenter(qh, fp, format, NULL, facet);
+ break;
+ case qh_PRINTfacets:
+ qh_printfacet(qh, fp, facet);
+ break;
+ case qh_PRINTfacets_xridge:
+ qh_printfacetheader(qh, fp, facet);
+ break;
+ case qh_PRINTgeom: /* either 2 , 3, or 4-d by qh_printbegin */
+ if (!facet->normal)
+ break;
+ for (k=qh->hull_dim; k--; ) {
+ color[k]= (facet->normal[k]+1.0)/2.0;
+ maximize_(color[k], -1.0);
+ minimize_(color[k], +1.0);
+ }
+ qh_projectdim3(qh, color, color);
+ if (qh->PRINTdim != qh->hull_dim)
+ qh_normalize2(qh, color, 3, True, NULL, NULL);
+ if (qh->hull_dim <= 2)
+ qh_printfacet2geom(qh, fp, facet, color);
+ else if (qh->hull_dim == 3) {
+ if (facet->simplicial)
+ qh_printfacet3geom_simplicial(qh, fp, facet, color);
+ else
+ qh_printfacet3geom_nonsimplicial(qh, fp, facet, color);
+ }else {
+ if (facet->simplicial)
+ qh_printfacet4geom_simplicial(qh, fp, facet, color);
+ else
+ qh_printfacet4geom_nonsimplicial(qh, fp, facet, color);
+ }
+ break;
+ case qh_PRINTids:
+ qh_fprintf(qh, fp, 9015, "%d\n", facet->id);
+ break;
+ case qh_PRINTincidences:
+ case qh_PRINToff:
+ case qh_PRINTtriangles:
+ if (qh->hull_dim == 3 && format != qh_PRINTtriangles)
+ qh_printfacet3vertex(qh, fp, facet, format);
+ else if (facet->simplicial || qh->hull_dim == 2 || format == qh_PRINToff)
+ qh_printfacetNvertex_simplicial(qh, fp, facet, format);
+ else
+ qh_printfacetNvertex_nonsimplicial(qh, fp, facet, qh->printoutvar++, format);
+ break;
+ case qh_PRINTinner:
+ qh_outerinner(qh, facet, NULL, &innerplane);
+ offset= facet->offset - innerplane;
+ goto LABELprintnorm;
+ break; /* prevent warning */
+ case qh_PRINTmerges:
+ qh_fprintf(qh, fp, 9016, "%d\n", facet->nummerge);
+ break;
+ case qh_PRINTnormals:
+ offset= facet->offset;
+ goto LABELprintnorm;
+ break; /* prevent warning */
+ case qh_PRINTouter:
+ qh_outerinner(qh, facet, &outerplane, NULL);
+ offset= facet->offset - outerplane;
+ LABELprintnorm:
+ if (!facet->normal) {
+ qh_fprintf(qh, fp, 9017, "no normal for facet f%d\n", facet->id);
+ break;
+ }
+ if (qh->CDDoutput) {
+ qh_fprintf(qh, fp, 9018, qh_REAL_1, -offset);
+ for (k=0; k < qh->hull_dim; k++)
+ qh_fprintf(qh, fp, 9019, qh_REAL_1, -facet->normal[k]);
+ }else {
+ for (k=0; k < qh->hull_dim; k++)
+ qh_fprintf(qh, fp, 9020, qh_REAL_1, facet->normal[k]);
+ qh_fprintf(qh, fp, 9021, qh_REAL_1, offset);
+ }
+ qh_fprintf(qh, fp, 9022, "\n");
+ break;
+ case qh_PRINTmathematica: /* either 2 or 3-d by qh_printbegin */
+ case qh_PRINTmaple:
+ if (qh->hull_dim == 2)
+ qh_printfacet2math(qh, fp, facet, format, qh->printoutvar++);
+ else
+ qh_printfacet3math(qh, fp, facet, format, qh->printoutvar++);
+ break;
+ case qh_PRINTneighbors:
+ qh_fprintf(qh, fp, 9023, "%d", qh_setsize(qh, facet->neighbors));
+ FOREACHneighbor_(facet)
+ qh_fprintf(qh, fp, 9024, " %d",
+ neighbor->visitid ? neighbor->visitid - 1: 0 - neighbor->id);
+ qh_fprintf(qh, fp, 9025, "\n");
+ break;
+ case qh_PRINTpointintersect:
+ if (!qh->feasible_point) {
+ qh_fprintf(qh, qh->ferr, 6067, "qhull input error (qh_printafacet): option 'Fp' needs qh->feasible_point\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (facet->offset > 0)
+ goto LABELprintinfinite;
+ point= coordp= (coordT*)qh_memalloc(qh, qh->normal_size);
+ normp= facet->normal;
+ feasiblep= qh->feasible_point;
+ if (facet->offset < -qh->MINdenom) {
+ for (k=qh->hull_dim; k--; )
+ *(coordp++)= (*(normp++) / - facet->offset) + *(feasiblep++);
+ }else {
+ for (k=qh->hull_dim; k--; ) {
+ *(coordp++)= qh_divzero(*(normp++), facet->offset, qh->MINdenom_1,
+ &zerodiv) + *(feasiblep++);
+ if (zerodiv) {
+ qh_memfree(qh, point, qh->normal_size);
+ goto LABELprintinfinite;
+ }
+ }
+ }
+ qh_printpoint(qh, fp, NULL, point);
+ qh_memfree(qh, point, qh->normal_size);
+ break;
+ LABELprintinfinite:
+ for (k=qh->hull_dim; k--; )
+ qh_fprintf(qh, fp, 9026, qh_REAL_1, qh_INFINITE);
+ qh_fprintf(qh, fp, 9027, "\n");
+ break;
+ case qh_PRINTpointnearest:
+ FOREACHpoint_(facet->coplanarset) {
+ int id, id2;
+ vertex= qh_nearvertex(qh, facet, point, &dist);
+ id= qh_pointid(qh, vertex->point);
+ id2= qh_pointid(qh, point);
+ qh_fprintf(qh, fp, 9028, "%d %d %d " qh_REAL_1 "\n", id, id2, facet->id, dist);
+ }
+ break;
+ case qh_PRINTpoints: /* VORONOI only by qh_printbegin */
+ if (qh->CDDoutput)
+ qh_fprintf(qh, fp, 9029, "1 ");
+ qh_printcenter(qh, fp, format, NULL, facet);
+ break;
+ case qh_PRINTvertices:
+ qh_fprintf(qh, fp, 9030, "%d", qh_setsize(qh, facet->vertices));
+ FOREACHvertex_(facet->vertices)
+ qh_fprintf(qh, fp, 9031, " %d", qh_pointid(qh, vertex->point));
+ qh_fprintf(qh, fp, 9032, "\n");
+ break;
+ default:
+ break;
+ }
+} /* printafacet */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printbegin">-</a>
+
+ qh_printbegin(qh, )
+ prints header for all output formats
+
+ returns:
+ checks for valid format
+
+ notes:
+ uses qh.visit_id for 3/4off
+ changes qh.interior_point if printing centrums
+ qh_countfacets clears facet->visitid for non-good facets
+
+ see
+ qh_printend() and qh_printafacet()
+
+ design:
+ count facets and related statistics
+ print header for format
+*/
+void qh_printbegin(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
+ int numfacets, numsimplicial, numridges, totneighbors, numcoplanars, numtricoplanars;
+ int i, num;
+ facetT *facet, **facetp;
+ vertexT *vertex, **vertexp;
+ setT *vertices;
+ pointT *point, **pointp, *pointtemp;
+
+ qh->printoutnum= 0;
+ qh_countfacets(qh, facetlist, facets, printall, &numfacets, &numsimplicial,
+ &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
+ switch (format) {
+ case qh_PRINTnone:
+ break;
+ case qh_PRINTarea:
+ qh_fprintf(qh, fp, 9033, "%d\n", numfacets);
+ break;
+ case qh_PRINTcoplanars:
+ qh_fprintf(qh, fp, 9034, "%d\n", numfacets);
+ break;
+ case qh_PRINTcentrums:
+ if (qh->CENTERtype == qh_ASnone)
+ qh_clearcenters(qh, qh_AScentrum);
+ qh_fprintf(qh, fp, 9035, "%d\n%d\n", qh->hull_dim, numfacets);
+ break;
+ case qh_PRINTfacets:
+ case qh_PRINTfacets_xridge:
+ if (facetlist)
+ qh_printvertexlist(qh, fp, "Vertices and facets:\n", facetlist, facets, printall);
+ break;
+ case qh_PRINTgeom:
+ if (qh->hull_dim > 4) /* qh_initqhull_globals also checks */
+ goto LABELnoformat;
+ if (qh->VORONOI && qh->hull_dim > 3) /* PRINTdim == DROPdim == hull_dim-1 */
+ goto LABELnoformat;
+ if (qh->hull_dim == 2 && (qh->PRINTridges || qh->DOintersections))
+ qh_fprintf(qh, qh->ferr, 7049, "qhull warning: output for ridges and intersections not implemented in 2-d\n");
+ if (qh->hull_dim == 4 && (qh->PRINTinner || qh->PRINTouter ||
+ (qh->PRINTdim == 4 && qh->PRINTcentrums)))
+ qh_fprintf(qh, qh->ferr, 7050, "qhull warning: output for outer/inner planes and centrums not implemented in 4-d\n");
+ if (qh->PRINTdim == 4 && (qh->PRINTspheres))
+ qh_fprintf(qh, qh->ferr, 7051, "qhull warning: output for vertices not implemented in 4-d\n");
+ if (qh->PRINTdim == 4 && qh->DOintersections && qh->PRINTnoplanes)
+ qh_fprintf(qh, qh->ferr, 7052, "qhull warning: 'Gnh' generates no output in 4-d\n");
+ if (qh->PRINTdim == 2) {
+ qh_fprintf(qh, fp, 9036, "{appearance {linewidth 3} LIST # %s | %s\n",
+ qh->rbox_command, qh->qhull_command);
+ }else if (qh->PRINTdim == 3) {
+ qh_fprintf(qh, fp, 9037, "{appearance {+edge -evert linewidth 2} LIST # %s | %s\n",
+ qh->rbox_command, qh->qhull_command);
+ }else if (qh->PRINTdim == 4) {
+ qh->visit_id++;
+ num= 0;
+ FORALLfacet_(facetlist) /* get number of ridges to be printed */
+ qh_printend4geom(qh, NULL, facet, &num, printall);
+ FOREACHfacet_(facets)
+ qh_printend4geom(qh, NULL, facet, &num, printall);
+ qh->ridgeoutnum= num;
+ qh->printoutvar= 0; /* counts number of ridges in output */
+ qh_fprintf(qh, fp, 9038, "LIST # %s | %s\n", qh->rbox_command, qh->qhull_command);
+ }
+
+ if (qh->PRINTdots) {
+ qh->printoutnum++;
+ num= qh->num_points + qh_setsize(qh, qh->other_points);
+ if (qh->DELAUNAY && qh->ATinfinity)
+ num--;
+ if (qh->PRINTdim == 4)
+ qh_fprintf(qh, fp, 9039, "4VECT %d %d 1\n", num, num);
+ else
+ qh_fprintf(qh, fp, 9040, "VECT %d %d 1\n", num, num);
+
+ for (i=num; i--; ) {
+ if (i % 20 == 0)
+ qh_fprintf(qh, fp, 9041, "\n");
+ qh_fprintf(qh, fp, 9042, "1 ");
+ }
+ qh_fprintf(qh, fp, 9043, "# 1 point per line\n1 ");
+ for (i=num-1; i--; ) { /* num at least 3 for D2 */
+ if (i % 20 == 0)
+ qh_fprintf(qh, fp, 9044, "\n");
+ qh_fprintf(qh, fp, 9045, "0 ");
+ }
+ qh_fprintf(qh, fp, 9046, "# 1 color for all\n");
+ FORALLpoints {
+ if (!qh->DELAUNAY || !qh->ATinfinity || qh_pointid(qh, point) != qh->num_points-1) {
+ if (qh->PRINTdim == 4)
+ qh_printpoint(qh, fp, NULL, point);
+ else
+ qh_printpoint3(qh, fp, point);
+ }
+ }
+ FOREACHpoint_(qh->other_points) {
+ if (qh->PRINTdim == 4)
+ qh_printpoint(qh, fp, NULL, point);
+ else
+ qh_printpoint3(qh, fp, point);
+ }
+ qh_fprintf(qh, fp, 9047, "0 1 1 1 # color of points\n");
+ }
+
+ if (qh->PRINTdim == 4 && !qh->PRINTnoplanes)
+ /* 4dview loads up multiple 4OFF objects slowly */
+ qh_fprintf(qh, fp, 9048, "4OFF %d %d 1\n", 3*qh->ridgeoutnum, qh->ridgeoutnum);
+ qh->PRINTcradius= 2 * qh->DISTround; /* include test DISTround */
+ if (qh->PREmerge) {
+ maximize_(qh->PRINTcradius, qh->premerge_centrum + qh->DISTround);
+ }else if (qh->POSTmerge)
+ maximize_(qh->PRINTcradius, qh->postmerge_centrum + qh->DISTround);
+ qh->PRINTradius= qh->PRINTcradius;
+ if (qh->PRINTspheres + qh->PRINTcoplanar)
+ maximize_(qh->PRINTradius, qh->MAXabs_coord * qh_MINradius);
+ if (qh->premerge_cos < REALmax/2) {
+ maximize_(qh->PRINTradius, (1- qh->premerge_cos) * qh->MAXabs_coord);
+ }else if (!qh->PREmerge && qh->POSTmerge && qh->postmerge_cos < REALmax/2) {
+ maximize_(qh->PRINTradius, (1- qh->postmerge_cos) * qh->MAXabs_coord);
+ }
+ maximize_(qh->PRINTradius, qh->MINvisible);
+ if (qh->JOGGLEmax < REALmax/2)
+ qh->PRINTradius += qh->JOGGLEmax * sqrt((realT)qh->hull_dim);
+ if (qh->PRINTdim != 4 &&
+ (qh->PRINTcoplanar || qh->PRINTspheres || qh->PRINTcentrums)) {
+ vertices= qh_facetvertices(qh, facetlist, facets, printall);
+ if (qh->PRINTspheres && qh->PRINTdim <= 3)
+ qh_printspheres(qh, fp, vertices, qh->PRINTradius);
+ if (qh->PRINTcoplanar || qh->PRINTcentrums) {
+ qh->firstcentrum= True;
+ if (qh->PRINTcoplanar&& !qh->PRINTspheres) {
+ FOREACHvertex_(vertices)
+ qh_printpointvect2(qh, fp, vertex->point, NULL, qh->interior_point, qh->PRINTradius);
+ }
+ FORALLfacet_(facetlist) {
+ if (!printall && qh_skipfacet(qh, facet))
+ continue;
+ if (!facet->normal)
+ continue;
+ if (qh->PRINTcentrums && qh->PRINTdim <= 3)
+ qh_printcentrum(qh, fp, facet, qh->PRINTcradius);
+ if (!qh->PRINTcoplanar)
+ continue;
+ FOREACHpoint_(facet->coplanarset)
+ qh_printpointvect2(qh, fp, point, facet->normal, NULL, qh->PRINTradius);
+ FOREACHpoint_(facet->outsideset)
+ qh_printpointvect2(qh, fp, point, facet->normal, NULL, qh->PRINTradius);
+ }
+ FOREACHfacet_(facets) {
+ if (!printall && qh_skipfacet(qh, facet))
+ continue;
+ if (!facet->normal)
+ continue;
+ if (qh->PRINTcentrums && qh->PRINTdim <= 3)
+ qh_printcentrum(qh, fp, facet, qh->PRINTcradius);
+ if (!qh->PRINTcoplanar)
+ continue;
+ FOREACHpoint_(facet->coplanarset)
+ qh_printpointvect2(qh, fp, point, facet->normal, NULL, qh->PRINTradius);
+ FOREACHpoint_(facet->outsideset)
+ qh_printpointvect2(qh, fp, point, facet->normal, NULL, qh->PRINTradius);
+ }
+ }
+ qh_settempfree(qh, &vertices);
+ }
+ qh->visit_id++; /* for printing hyperplane intersections */
+ break;
+ case qh_PRINTids:
+ qh_fprintf(qh, fp, 9049, "%d\n", numfacets);
+ break;
+ case qh_PRINTincidences:
+ if (qh->VORONOI && qh->PRINTprecision)
+ qh_fprintf(qh, qh->ferr, 7053, "qhull warning: writing Delaunay. Use 'p' or 'o' for Voronoi centers\n");
+ qh->printoutvar= qh->vertex_id; /* centrum id for non-simplicial facets */
+ if (qh->hull_dim <= 3)
+ qh_fprintf(qh, fp, 9050, "%d\n", numfacets);
+ else
+ qh_fprintf(qh, fp, 9051, "%d\n", numsimplicial+numridges);
+ break;
+ case qh_PRINTinner:
+ case qh_PRINTnormals:
+ case qh_PRINTouter:
+ if (qh->CDDoutput)
+ qh_fprintf(qh, fp, 9052, "%s | %s\nbegin\n %d %d real\n", qh->rbox_command,
+ qh->qhull_command, numfacets, qh->hull_dim+1);
+ else
+ qh_fprintf(qh, fp, 9053, "%d\n%d\n", qh->hull_dim+1, numfacets);
+ break;
+ case qh_PRINTmathematica:
+ case qh_PRINTmaple:
+ if (qh->hull_dim > 3) /* qh_initbuffers also checks */
+ goto LABELnoformat;
+ if (qh->VORONOI)
+ qh_fprintf(qh, qh->ferr, 7054, "qhull warning: output is the Delaunay triangulation\n");
+ if (format == qh_PRINTmaple) {
+ if (qh->hull_dim == 2)
+ qh_fprintf(qh, fp, 9054, "PLOT(CURVES(\n");
+ else
+ qh_fprintf(qh, fp, 9055, "PLOT3D(POLYGONS(\n");
+ }else
+ qh_fprintf(qh, fp, 9056, "{\n");
+ qh->printoutvar= 0; /* counts number of facets for notfirst */
+ break;
+ case qh_PRINTmerges:
+ qh_fprintf(qh, fp, 9057, "%d\n", numfacets);
+ break;
+ case qh_PRINTpointintersect:
+ qh_fprintf(qh, fp, 9058, "%d\n%d\n", qh->hull_dim, numfacets);
+ break;
+ case qh_PRINTneighbors:
+ qh_fprintf(qh, fp, 9059, "%d\n", numfacets);
+ break;
+ case qh_PRINToff:
+ case qh_PRINTtriangles:
+ if (qh->VORONOI)
+ goto LABELnoformat;
+ num = qh->hull_dim;
+ if (format == qh_PRINToff || qh->hull_dim == 2)
+ qh_fprintf(qh, fp, 9060, "%d\n%d %d %d\n", num,
+ qh->num_points+qh_setsize(qh, qh->other_points), numfacets, totneighbors/2);
+ else { /* qh_PRINTtriangles */
+ qh->printoutvar= qh->num_points+qh_setsize(qh, qh->other_points); /* first centrum */
+ if (qh->DELAUNAY)
+ num--; /* drop last dimension */
+ qh_fprintf(qh, fp, 9061, "%d\n%d %d %d\n", num, qh->printoutvar
+ + numfacets - numsimplicial, numsimplicial + numridges, totneighbors/2);
+ }
+ FORALLpoints
+ qh_printpointid(qh, qh->fout, NULL, num, point, qh_IDunknown);
+ FOREACHpoint_(qh->other_points)
+ qh_printpointid(qh, qh->fout, NULL, num, point, qh_IDunknown);
+ if (format == qh_PRINTtriangles && qh->hull_dim > 2) {
+ FORALLfacets {
+ if (!facet->simplicial && facet->visitid)
+ qh_printcenter(qh, qh->fout, format, NULL, facet);
+ }
+ }
+ break;
+ case qh_PRINTpointnearest:
+ qh_fprintf(qh, fp, 9062, "%d\n", numcoplanars);
+ break;
+ case qh_PRINTpoints:
+ if (!qh->VORONOI)
+ goto LABELnoformat;
+ if (qh->CDDoutput)
+ qh_fprintf(qh, fp, 9063, "%s | %s\nbegin\n%d %d real\n", qh->rbox_command,
+ qh->qhull_command, numfacets, qh->hull_dim);
+ else
+ qh_fprintf(qh, fp, 9064, "%d\n%d\n", qh->hull_dim-1, numfacets);
+ break;
+ case qh_PRINTvertices:
+ qh_fprintf(qh, fp, 9065, "%d\n", numfacets);
+ break;
+ case qh_PRINTsummary:
+ default:
+ LABELnoformat:
+ qh_fprintf(qh, qh->ferr, 6068, "qhull internal error (qh_printbegin): can not use this format for dimension %d\n",
+ qh->hull_dim);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+} /* printbegin */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printcenter">-</a>
+
+ qh_printcenter(qh, fp, string, facet )
+ print facet->center as centrum or Voronoi center
+ string may be NULL. Don't include '%' codes.
+ nop if qh->CENTERtype neither CENTERvoronoi nor CENTERcentrum
+ if upper envelope of Delaunay triangulation and point at-infinity
+ prints qh_INFINITE instead;
+
+ notes:
+ defines facet->center if needed
+ if format=PRINTgeom, adds a 0 if would otherwise be 2-d
+ Same as QhullFacet::printCenter
+*/
+void qh_printcenter(qhT *qh, FILE *fp, qh_PRINT format, const char *string, facetT *facet) {
+ int k, num;
+
+ if (qh->CENTERtype != qh_ASvoronoi && qh->CENTERtype != qh_AScentrum)
+ return;
+ if (string)
+ qh_fprintf(qh, fp, 9066, string);
+ if (qh->CENTERtype == qh_ASvoronoi) {
+ num= qh->hull_dim-1;
+ if (!facet->normal || !facet->upperdelaunay || !qh->ATinfinity) {
+ if (!facet->center)
+ facet->center= qh_facetcenter(qh, facet->vertices);
+ for (k=0; k < num; k++)
+ qh_fprintf(qh, fp, 9067, qh_REAL_1, facet->center[k]);
+ }else {
+ for (k=0; k < num; k++)
+ qh_fprintf(qh, fp, 9068, qh_REAL_1, qh_INFINITE);
+ }
+ }else /* qh->CENTERtype == qh_AScentrum */ {
+ num= qh->hull_dim;
+ if (format == qh_PRINTtriangles && qh->DELAUNAY)
+ num--;
+ if (!facet->center)
+ facet->center= qh_getcentrum(qh, facet);
+ for (k=0; k < num; k++)
+ qh_fprintf(qh, fp, 9069, qh_REAL_1, facet->center[k]);
+ }
+ if (format == qh_PRINTgeom && num == 2)
+ qh_fprintf(qh, fp, 9070, " 0\n");
+ else
+ qh_fprintf(qh, fp, 9071, "\n");
+} /* printcenter */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printcentrum">-</a>
+
+ qh_printcentrum(qh, fp, facet, radius )
+ print centrum for a facet in OOGL format
+ radius defines size of centrum
+ 2-d or 3-d only
+
+ returns:
+ defines facet->center if needed
+*/
+void qh_printcentrum(qhT *qh, FILE *fp, facetT *facet, realT radius) {
+ pointT *centrum, *projpt;
+ boolT tempcentrum= False;
+ realT xaxis[4], yaxis[4], normal[4], dist;
+ realT green[3]={0, 1, 0};
+ vertexT *apex;
+ int k;
+
+ if (qh->CENTERtype == qh_AScentrum) {
+ if (!facet->center)
+ facet->center= qh_getcentrum(qh, facet);
+ centrum= facet->center;
+ }else {
+ centrum= qh_getcentrum(qh, facet);
+ tempcentrum= True;
+ }
+ qh_fprintf(qh, fp, 9072, "{appearance {-normal -edge normscale 0} ");
+ if (qh->firstcentrum) {
+ qh->firstcentrum= False;
+ qh_fprintf(qh, fp, 9073, "{INST geom { define centrum CQUAD # f%d\n\
+-0.3 -0.3 0.0001 0 0 1 1\n\
+ 0.3 -0.3 0.0001 0 0 1 1\n\
+ 0.3 0.3 0.0001 0 0 1 1\n\
+-0.3 0.3 0.0001 0 0 1 1 } transform { \n", facet->id);
+ }else
+ qh_fprintf(qh, fp, 9074, "{INST geom { : centrum } transform { # f%d\n", facet->id);
+ apex= SETfirstt_(facet->vertices, vertexT);
+ qh_distplane(qh, apex->point, facet, &dist);
+ projpt= qh_projectpoint(qh, apex->point, facet, dist);
+ for (k=qh->hull_dim; k--; ) {
+ xaxis[k]= projpt[k] - centrum[k];
+ normal[k]= facet->normal[k];
+ }
+ if (qh->hull_dim == 2) {
+ xaxis[2]= 0;
+ normal[2]= 0;
+ }else if (qh->hull_dim == 4) {
+ qh_projectdim3(qh, xaxis, xaxis);
+ qh_projectdim3(qh, normal, normal);
+ qh_normalize2(qh, normal, qh->PRINTdim, True, NULL, NULL);
+ }
+ qh_crossproduct(3, xaxis, normal, yaxis);
+ qh_fprintf(qh, fp, 9075, "%8.4g %8.4g %8.4g 0\n", xaxis[0], xaxis[1], xaxis[2]);
+ qh_fprintf(qh, fp, 9076, "%8.4g %8.4g %8.4g 0\n", yaxis[0], yaxis[1], yaxis[2]);
+ qh_fprintf(qh, fp, 9077, "%8.4g %8.4g %8.4g 0\n", normal[0], normal[1], normal[2]);
+ qh_printpoint3(qh, fp, centrum);
+ qh_fprintf(qh, fp, 9078, "1 }}}\n");
+ qh_memfree(qh, projpt, qh->normal_size);
+ qh_printpointvect(qh, fp, centrum, facet->normal, NULL, radius, green);
+ if (tempcentrum)
+ qh_memfree(qh, centrum, qh->normal_size);
+} /* printcentrum */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printend">-</a>
+
+ qh_printend(qh, fp, format )
+ prints trailer for all output formats
+
+ see:
+ qh_printbegin() and qh_printafacet()
+
+*/
+void qh_printend(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
+ int num;
+ facetT *facet, **facetp;
+
+ if (!qh->printoutnum)
+ qh_fprintf(qh, qh->ferr, 7055, "qhull warning: no facets printed\n");
+ switch (format) {
+ case qh_PRINTgeom:
+ if (qh->hull_dim == 4 && qh->DROPdim < 0 && !qh->PRINTnoplanes) {
+ qh->visit_id++;
+ num= 0;
+ FORALLfacet_(facetlist)
+ qh_printend4geom(qh, fp, facet,&num, printall);
+ FOREACHfacet_(facets)
+ qh_printend4geom(qh, fp, facet, &num, printall);
+ if (num != qh->ridgeoutnum || qh->printoutvar != qh->ridgeoutnum) {
+ qh_fprintf(qh, qh->ferr, 6069, "qhull internal error (qh_printend): number of ridges %d != number printed %d and at end %d\n", qh->ridgeoutnum, qh->printoutvar, num);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ }else
+ qh_fprintf(qh, fp, 9079, "}\n");
+ break;
+ case qh_PRINTinner:
+ case qh_PRINTnormals:
+ case qh_PRINTouter:
+ if (qh->CDDoutput)
+ qh_fprintf(qh, fp, 9080, "end\n");
+ break;
+ case qh_PRINTmaple:
+ qh_fprintf(qh, fp, 9081, "));\n");
+ break;
+ case qh_PRINTmathematica:
+ qh_fprintf(qh, fp, 9082, "}\n");
+ break;
+ case qh_PRINTpoints:
+ if (qh->CDDoutput)
+ qh_fprintf(qh, fp, 9083, "end\n");
+ break;
+ default:
+ break;
+ }
+} /* printend */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printend4geom">-</a>
+
+ qh_printend4geom(qh, fp, facet, numridges, printall )
+ helper function for qh_printbegin/printend
+
+ returns:
+ number of printed ridges
+
+ notes:
+ just counts printed ridges if fp=NULL
+ uses facet->visitid
+ must agree with qh_printfacet4geom...
+
+ design:
+ computes color for facet from its normal
+ prints each ridge of facet
+*/
+void qh_printend4geom(qhT *qh, FILE *fp, facetT *facet, int *nump, boolT printall) {
+ realT color[3];
+ int i, num= *nump;
+ facetT *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+
+ if (!printall && qh_skipfacet(qh, facet))
+ return;
+ if (qh->PRINTnoplanes || (facet->visible && qh->NEWfacets))
+ return;
+ if (!facet->normal)
+ return;
+ if (fp) {
+ for (i=0; i < 3; i++) {
+ color[i]= (facet->normal[i]+1.0)/2.0;
+ maximize_(color[i], -1.0);
+ minimize_(color[i], +1.0);
+ }
+ }
+ facet->visitid= qh->visit_id;
+ if (facet->simplicial) {
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid != qh->visit_id) {
+ if (fp)
+ qh_fprintf(qh, fp, 9084, "3 %d %d %d %8.4g %8.4g %8.4g 1 # f%d f%d\n",
+ 3*num, 3*num+1, 3*num+2, color[0], color[1], color[2],
+ facet->id, neighbor->id);
+ num++;
+ }
+ }
+ }else {
+ FOREACHridge_(facet->ridges) {
+ neighbor= otherfacet_(ridge, facet);
+ if (neighbor->visitid != qh->visit_id) {
+ if (fp)
+ qh_fprintf(qh, fp, 9085, "3 %d %d %d %8.4g %8.4g %8.4g 1 #r%d f%d f%d\n",
+ 3*num, 3*num+1, 3*num+2, color[0], color[1], color[2],
+ ridge->id, facet->id, neighbor->id);
+ num++;
+ }
+ }
+ }
+ *nump= num;
+} /* printend4geom */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printextremes">-</a>
+
+ qh_printextremes(qh, fp, facetlist, facets, printall )
+ print extreme points for convex hulls or halfspace intersections
+
+ notes:
+ #points, followed by ids, one per line
+
+ sorted by id
+ same order as qh_printpoints_out if no coplanar/interior points
+*/
+void qh_printextremes(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall) {
+ setT *vertices, *points;
+ pointT *point;
+ vertexT *vertex, **vertexp;
+ int id;
+ int numpoints=0, point_i, point_n;
+ int allpoints= qh->num_points + qh_setsize(qh, qh->other_points);
+
+ points= qh_settemp(qh, allpoints);
+ qh_setzero(qh, points, 0, allpoints);
+ vertices= qh_facetvertices(qh, facetlist, facets, printall);
+ FOREACHvertex_(vertices) {
+ id= qh_pointid(qh, vertex->point);
+ if (id >= 0) {
+ SETelem_(points, id)= vertex->point;
+ numpoints++;
+ }
+ }
+ qh_settempfree(qh, &vertices);
+ qh_fprintf(qh, fp, 9086, "%d\n", numpoints);
+ FOREACHpoint_i_(qh, points) {
+ if (point)
+ qh_fprintf(qh, fp, 9087, "%d\n", point_i);
+ }
+ qh_settempfree(qh, &points);
+} /* printextremes */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printextremes_2d">-</a>
+
+ qh_printextremes_2d(qh, fp, facetlist, facets, printall )
+ prints point ids for facets in qh_ORIENTclock order
+
+ notes:
+ #points, followed by ids, one per line
+ if facetlist/facets are disjoint than the output includes skips
+ errors if facets form a loop
+ does not print coplanar points
+*/
+void qh_printextremes_2d(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall) {
+ int numfacets, numridges, totneighbors, numcoplanars, numsimplicial, numtricoplanars;
+ setT *vertices;
+ facetT *facet, *startfacet, *nextfacet;
+ vertexT *vertexA, *vertexB;
+
+ qh_countfacets(qh, facetlist, facets, printall, &numfacets, &numsimplicial,
+ &totneighbors, &numridges, &numcoplanars, &numtricoplanars); /* marks qh->visit_id */
+ vertices= qh_facetvertices(qh, facetlist, facets, printall);
+ qh_fprintf(qh, fp, 9088, "%d\n", qh_setsize(qh, vertices));
+ qh_settempfree(qh, &vertices);
+ if (!numfacets)
+ return;
+ facet= startfacet= facetlist ? facetlist : SETfirstt_(facets, facetT);
+ qh->vertex_visit++;
+ qh->visit_id++;
+ do {
+ if (facet->toporient ^ qh_ORIENTclock) {
+ vertexA= SETfirstt_(facet->vertices, vertexT);
+ vertexB= SETsecondt_(facet->vertices, vertexT);
+ nextfacet= SETfirstt_(facet->neighbors, facetT);
+ }else {
+ vertexA= SETsecondt_(facet->vertices, vertexT);
+ vertexB= SETfirstt_(facet->vertices, vertexT);
+ nextfacet= SETsecondt_(facet->neighbors, facetT);
+ }
+ if (facet->visitid == qh->visit_id) {
+ qh_fprintf(qh, qh->ferr, 6218, "Qhull internal error (qh_printextremes_2d): loop in facet list. facet %d nextfacet %d\n",
+ facet->id, nextfacet->id);
+ qh_errexit2(qh, qh_ERRqhull, facet, nextfacet);
+ }
+ if (facet->visitid) {
+ if (vertexA->visitid != qh->vertex_visit) {
+ vertexA->visitid= qh->vertex_visit;
+ qh_fprintf(qh, fp, 9089, "%d\n", qh_pointid(qh, vertexA->point));
+ }
+ if (vertexB->visitid != qh->vertex_visit) {
+ vertexB->visitid= qh->vertex_visit;
+ qh_fprintf(qh, fp, 9090, "%d\n", qh_pointid(qh, vertexB->point));
+ }
+ }
+ facet->visitid= qh->visit_id;
+ facet= nextfacet;
+ }while (facet && facet != startfacet);
+} /* printextremes_2d */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printextremes_d">-</a>
+
+ qh_printextremes_d(qh, fp, facetlist, facets, printall )
+ print extreme points of input sites for Delaunay triangulations
+
+ notes:
+ #points, followed by ids, one per line
+
+ unordered
+*/
+void qh_printextremes_d(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall) {
+ setT *vertices;
+ vertexT *vertex, **vertexp;
+ boolT upperseen, lowerseen;
+ facetT *neighbor, **neighborp;
+ int numpoints=0;
+
+ vertices= qh_facetvertices(qh, facetlist, facets, printall);
+ qh_vertexneighbors(qh);
+ FOREACHvertex_(vertices) {
+ upperseen= lowerseen= False;
+ FOREACHneighbor_(vertex) {
+ if (neighbor->upperdelaunay)
+ upperseen= True;
+ else
+ lowerseen= True;
+ }
+ if (upperseen && lowerseen) {
+ vertex->seen= True;
+ numpoints++;
+ }else
+ vertex->seen= False;
+ }
+ qh_fprintf(qh, fp, 9091, "%d\n", numpoints);
+ FOREACHvertex_(vertices) {
+ if (vertex->seen)
+ qh_fprintf(qh, fp, 9092, "%d\n", qh_pointid(qh, vertex->point));
+ }
+ qh_settempfree(qh, &vertices);
+} /* printextremes_d */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacet">-</a>
+
+ qh_printfacet(qh, fp, facet )
+ prints all fields of a facet to fp
+
+ notes:
+ ridges printed in neighbor order
+*/
+void qh_printfacet(qhT *qh, FILE *fp, facetT *facet) {
+
+ qh_printfacetheader(qh, fp, facet);
+ if (facet->ridges)
+ qh_printfacetridges(qh, fp, facet);
+} /* printfacet */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacet2geom">-</a>
+
+ qh_printfacet2geom(qh, fp, facet, color )
+ print facet as part of a 2-d VECT for Geomview
+
+ notes:
+ assume precise calculations in io_r.c with roundoff covered by qh_GEOMepsilon
+ mindist is calculated within io_r.c. maxoutside is calculated elsewhere
+ so a DISTround error may have occurred.
+*/
+void qh_printfacet2geom(qhT *qh, FILE *fp, facetT *facet, realT color[3]) {
+ pointT *point0, *point1;
+ realT mindist, innerplane, outerplane;
+ int k;
+
+ qh_facet2point(qh, facet, &point0, &point1, &mindist);
+ qh_geomplanes(qh, facet, &outerplane, &innerplane);
+ if (qh->PRINTouter || (!qh->PRINTnoplanes && !qh->PRINTinner))
+ qh_printfacet2geom_points(qh, fp, point0, point1, facet, outerplane, color);
+ if (qh->PRINTinner || (!qh->PRINTnoplanes && !qh->PRINTouter &&
+ outerplane - innerplane > 2 * qh->MAXabs_coord * qh_GEOMepsilon)) {
+ for (k=3; k--; )
+ color[k]= 1.0 - color[k];
+ qh_printfacet2geom_points(qh, fp, point0, point1, facet, innerplane, color);
+ }
+ qh_memfree(qh, point1, qh->normal_size);
+ qh_memfree(qh, point0, qh->normal_size);
+} /* printfacet2geom */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacet2geom_points">-</a>
+
+ qh_printfacet2geom_points(qh, fp, point1, point2, facet, offset, color )
+ prints a 2-d facet as a VECT with 2 points at some offset.
+ The points are on the facet's plane.
+*/
+void qh_printfacet2geom_points(qhT *qh, FILE *fp, pointT *point1, pointT *point2,
+ facetT *facet, realT offset, realT color[3]) {
+ pointT *p1= point1, *p2= point2;
+
+ qh_fprintf(qh, fp, 9093, "VECT 1 2 1 2 1 # f%d\n", facet->id);
+ if (offset != 0.0) {
+ p1= qh_projectpoint(qh, p1, facet, -offset);
+ p2= qh_projectpoint(qh, p2, facet, -offset);
+ }
+ qh_fprintf(qh, fp, 9094, "%8.4g %8.4g %8.4g\n%8.4g %8.4g %8.4g\n",
+ p1[0], p1[1], 0.0, p2[0], p2[1], 0.0);
+ if (offset != 0.0) {
+ qh_memfree(qh, p1, qh->normal_size);
+ qh_memfree(qh, p2, qh->normal_size);
+ }
+ qh_fprintf(qh, fp, 9095, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
+} /* printfacet2geom_points */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacet2math">-</a>
+
+ qh_printfacet2math(qh, fp, facet, format, notfirst )
+ print 2-d Maple or Mathematica output for a facet
+ may be non-simplicial
+
+ notes:
+ use %16.8f since Mathematica 2.2 does not handle exponential format
+ see qh_printfacet3math
+*/
+void qh_printfacet2math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst) {
+ pointT *point0, *point1;
+ realT mindist;
+ const char *pointfmt;
+
+ qh_facet2point(qh, facet, &point0, &point1, &mindist);
+ if (notfirst)
+ qh_fprintf(qh, fp, 9096, ",");
+ if (format == qh_PRINTmaple)
+ pointfmt= "[[%16.8f, %16.8f], [%16.8f, %16.8f]]\n";
+ else
+ pointfmt= "Line[{{%16.8f, %16.8f}, {%16.8f, %16.8f}}]\n";
+ qh_fprintf(qh, fp, 9097, pointfmt, point0[0], point0[1], point1[0], point1[1]);
+ qh_memfree(qh, point1, qh->normal_size);
+ qh_memfree(qh, point0, qh->normal_size);
+} /* printfacet2math */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacet3geom_nonsimplicial">-</a>
+
+ qh_printfacet3geom_nonsimplicial(qh, fp, facet, color )
+ print Geomview OFF for a 3-d nonsimplicial facet.
+ if DOintersections, prints ridges to unvisited neighbors(qh->visit_id)
+
+ notes
+ uses facet->visitid for intersections and ridges
+*/
+void qh_printfacet3geom_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]) {
+ ridgeT *ridge, **ridgep;
+ setT *projectedpoints, *vertices;
+ vertexT *vertex, **vertexp, *vertexA, *vertexB;
+ pointT *projpt, *point, **pointp;
+ facetT *neighbor;
+ realT dist, outerplane, innerplane;
+ int cntvertices, k;
+ realT black[3]={0, 0, 0}, green[3]={0, 1, 0};
+
+ qh_geomplanes(qh, facet, &outerplane, &innerplane);
+ vertices= qh_facet3vertex(qh, facet); /* oriented */
+ cntvertices= qh_setsize(qh, vertices);
+ projectedpoints= qh_settemp(qh, cntvertices);
+ FOREACHvertex_(vertices) {
+ zinc_(Zdistio);
+ qh_distplane(qh, vertex->point, facet, &dist);
+ projpt= qh_projectpoint(qh, vertex->point, facet, dist);
+ qh_setappend(qh, &projectedpoints, projpt);
+ }
+ if (qh->PRINTouter || (!qh->PRINTnoplanes && !qh->PRINTinner))
+ qh_printfacet3geom_points(qh, fp, projectedpoints, facet, outerplane, color);
+ if (qh->PRINTinner || (!qh->PRINTnoplanes && !qh->PRINTouter &&
+ outerplane - innerplane > 2 * qh->MAXabs_coord * qh_GEOMepsilon)) {
+ for (k=3; k--; )
+ color[k]= 1.0 - color[k];
+ qh_printfacet3geom_points(qh, fp, projectedpoints, facet, innerplane, color);
+ }
+ FOREACHpoint_(projectedpoints)
+ qh_memfree(qh, point, qh->normal_size);
+ qh_settempfree(qh, &projectedpoints);
+ qh_settempfree(qh, &vertices);
+ if ((qh->DOintersections || qh->PRINTridges)
+ && (!facet->visible || !qh->NEWfacets)) {
+ facet->visitid= qh->visit_id;
+ FOREACHridge_(facet->ridges) {
+ neighbor= otherfacet_(ridge, facet);
+ if (neighbor->visitid != qh->visit_id) {
+ if (qh->DOintersections)
+ qh_printhyperplaneintersection(qh, fp, facet, neighbor, ridge->vertices, black);
+ if (qh->PRINTridges) {
+ vertexA= SETfirstt_(ridge->vertices, vertexT);
+ vertexB= SETsecondt_(ridge->vertices, vertexT);
+ qh_printline3geom(qh, fp, vertexA->point, vertexB->point, green);
+ }
+ }
+ }
+ }
+} /* printfacet3geom_nonsimplicial */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacet3geom_points">-</a>
+
+ qh_printfacet3geom_points(qh, fp, points, facet, offset )
+ prints a 3-d facet as OFF Geomview object.
+ offset is relative to the facet's hyperplane
+ Facet is determined as a list of points
+*/
+void qh_printfacet3geom_points(qhT *qh, FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]) {
+ int k, n= qh_setsize(qh, points), i;
+ pointT *point, **pointp;
+ setT *printpoints;
+
+ qh_fprintf(qh, fp, 9098, "{ OFF %d 1 1 # f%d\n", n, facet->id);
+ if (offset != 0.0) {
+ printpoints= qh_settemp(qh, n);
+ FOREACHpoint_(points)
+ qh_setappend(qh, &printpoints, qh_projectpoint(qh, point, facet, -offset));
+ }else
+ printpoints= points;
+ FOREACHpoint_(printpoints) {
+ for (k=0; k < qh->hull_dim; k++) {
+ if (k == qh->DROPdim)
+ qh_fprintf(qh, fp, 9099, "0 ");
+ else
+ qh_fprintf(qh, fp, 9100, "%8.4g ", point[k]);
+ }
+ if (printpoints != points)
+ qh_memfree(qh, point, qh->normal_size);
+ qh_fprintf(qh, fp, 9101, "\n");
+ }
+ if (printpoints != points)
+ qh_settempfree(qh, &printpoints);
+ qh_fprintf(qh, fp, 9102, "%d ", n);
+ for (i=0; i < n; i++)
+ qh_fprintf(qh, fp, 9103, "%d ", i);
+ qh_fprintf(qh, fp, 9104, "%8.4g %8.4g %8.4g 1.0 }\n", color[0], color[1], color[2]);
+} /* printfacet3geom_points */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacet3geom_simplicial">-</a>
+
+ qh_printfacet3geom_simplicial(qh, )
+ print Geomview OFF for a 3-d simplicial facet.
+
+ notes:
+ may flip color
+ uses facet->visitid for intersections and ridges
+
+ assume precise calculations in io_r.c with roundoff covered by qh_GEOMepsilon
+ innerplane may be off by qh->DISTround. Maxoutside is calculated elsewhere
+ so a DISTround error may have occurred.
+*/
+void qh_printfacet3geom_simplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]) {
+ setT *points, *vertices;
+ vertexT *vertex, **vertexp, *vertexA, *vertexB;
+ facetT *neighbor, **neighborp;
+ realT outerplane, innerplane;
+ realT black[3]={0, 0, 0}, green[3]={0, 1, 0};
+ int k;
+
+ qh_geomplanes(qh, facet, &outerplane, &innerplane);
+ vertices= qh_facet3vertex(qh, facet);
+ points= qh_settemp(qh, qh->TEMPsize);
+ FOREACHvertex_(vertices)
+ qh_setappend(qh, &points, vertex->point);
+ if (qh->PRINTouter || (!qh->PRINTnoplanes && !qh->PRINTinner))
+ qh_printfacet3geom_points(qh, fp, points, facet, outerplane, color);
+ if (qh->PRINTinner || (!qh->PRINTnoplanes && !qh->PRINTouter &&
+ outerplane - innerplane > 2 * qh->MAXabs_coord * qh_GEOMepsilon)) {
+ for (k=3; k--; )
+ color[k]= 1.0 - color[k];
+ qh_printfacet3geom_points(qh, fp, points, facet, innerplane, color);
+ }
+ qh_settempfree(qh, &points);
+ qh_settempfree(qh, &vertices);
+ if ((qh->DOintersections || qh->PRINTridges)
+ && (!facet->visible || !qh->NEWfacets)) {
+ facet->visitid= qh->visit_id;
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid != qh->visit_id) {
+ vertices= qh_setnew_delnthsorted(qh, facet->vertices, qh->hull_dim,
+ SETindex_(facet->neighbors, neighbor), 0);
+ if (qh->DOintersections)
+ qh_printhyperplaneintersection(qh, fp, facet, neighbor, vertices, black);
+ if (qh->PRINTridges) {
+ vertexA= SETfirstt_(vertices, vertexT);
+ vertexB= SETsecondt_(vertices, vertexT);
+ qh_printline3geom(qh, fp, vertexA->point, vertexB->point, green);
+ }
+ qh_setfree(qh, &vertices);
+ }
+ }
+ }
+} /* printfacet3geom_simplicial */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacet3math">-</a>
+
+ qh_printfacet3math(qh, fp, facet, notfirst )
+ print 3-d Maple or Mathematica output for a facet
+
+ notes:
+ may be non-simplicial
+ use %16.8f since Mathematica 2.2 does not handle exponential format
+ see qh_printfacet2math
+*/
+void qh_printfacet3math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst) {
+ vertexT *vertex, **vertexp;
+ setT *points, *vertices;
+ pointT *point, **pointp;
+ boolT firstpoint= True;
+ realT dist;
+ const char *pointfmt, *endfmt;
+
+ if (notfirst)
+ qh_fprintf(qh, fp, 9105, ",\n");
+ vertices= qh_facet3vertex(qh, facet);
+ points= qh_settemp(qh, qh_setsize(qh, vertices));
+ FOREACHvertex_(vertices) {
+ zinc_(Zdistio);
+ qh_distplane(qh, vertex->point, facet, &dist);
+ point= qh_projectpoint(qh, vertex->point, facet, dist);
+ qh_setappend(qh, &points, point);
+ }
+ if (format == qh_PRINTmaple) {
+ qh_fprintf(qh, fp, 9106, "[");
+ pointfmt= "[%16.8f, %16.8f, %16.8f]";
+ endfmt= "]";
+ }else {
+ qh_fprintf(qh, fp, 9107, "Polygon[{");
+ pointfmt= "{%16.8f, %16.8f, %16.8f}";
+ endfmt= "}]";
+ }
+ FOREACHpoint_(points) {
+ if (firstpoint)
+ firstpoint= False;
+ else
+ qh_fprintf(qh, fp, 9108, ",\n");
+ qh_fprintf(qh, fp, 9109, pointfmt, point[0], point[1], point[2]);
+ }
+ FOREACHpoint_(points)
+ qh_memfree(qh, point, qh->normal_size);
+ qh_settempfree(qh, &points);
+ qh_settempfree(qh, &vertices);
+ qh_fprintf(qh, fp, 9110, "%s", endfmt);
+} /* printfacet3math */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacet3vertex">-</a>
+
+ qh_printfacet3vertex(qh, fp, facet, format )
+ print vertices in a 3-d facet as point ids
+
+ notes:
+ prints number of vertices first if format == qh_PRINToff
+ the facet may be non-simplicial
+*/
+void qh_printfacet3vertex(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format) {
+ vertexT *vertex, **vertexp;
+ setT *vertices;
+
+ vertices= qh_facet3vertex(qh, facet);
+ if (format == qh_PRINToff)
+ qh_fprintf(qh, fp, 9111, "%d ", qh_setsize(qh, vertices));
+ FOREACHvertex_(vertices)
+ qh_fprintf(qh, fp, 9112, "%d ", qh_pointid(qh, vertex->point));
+ qh_fprintf(qh, fp, 9113, "\n");
+ qh_settempfree(qh, &vertices);
+} /* printfacet3vertex */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacet4geom_nonsimplicial">-</a>
+
+ qh_printfacet4geom_nonsimplicial(qh, )
+ print Geomview 4OFF file for a 4d nonsimplicial facet
+ prints all ridges to unvisited neighbors (qh.visit_id)
+ if qh.DROPdim
+ prints in OFF format
+
+ notes:
+ must agree with printend4geom()
+*/
+void qh_printfacet4geom_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]) {
+ facetT *neighbor;
+ ridgeT *ridge, **ridgep;
+ vertexT *vertex, **vertexp;
+ pointT *point;
+ int k;
+ realT dist;
+
+ facet->visitid= qh->visit_id;
+ if (qh->PRINTnoplanes || (facet->visible && qh->NEWfacets))
+ return;
+ FOREACHridge_(facet->ridges) {
+ neighbor= otherfacet_(ridge, facet);
+ if (neighbor->visitid == qh->visit_id)
+ continue;
+ if (qh->PRINTtransparent && !neighbor->good)
+ continue;
+ if (qh->DOintersections)
+ qh_printhyperplaneintersection(qh, fp, facet, neighbor, ridge->vertices, color);
+ else {
+ if (qh->DROPdim >= 0)
+ qh_fprintf(qh, fp, 9114, "OFF 3 1 1 # f%d\n", facet->id);
+ else {
+ qh->printoutvar++;
+ qh_fprintf(qh, fp, 9115, "# r%d between f%d f%d\n", ridge->id, facet->id, neighbor->id);
+ }
+ FOREACHvertex_(ridge->vertices) {
+ zinc_(Zdistio);
+ qh_distplane(qh, vertex->point,facet, &dist);
+ point=qh_projectpoint(qh, vertex->point,facet, dist);
+ for (k=0; k < qh->hull_dim; k++) {
+ if (k != qh->DROPdim)
+ qh_fprintf(qh, fp, 9116, "%8.4g ", point[k]);
+ }
+ qh_fprintf(qh, fp, 9117, "\n");
+ qh_memfree(qh, point, qh->normal_size);
+ }
+ if (qh->DROPdim >= 0)
+ qh_fprintf(qh, fp, 9118, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]);
+ }
+ }
+} /* printfacet4geom_nonsimplicial */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacet4geom_simplicial">-</a>
+
+ qh_printfacet4geom_simplicial(qh, fp, facet, color )
+ print Geomview 4OFF file for a 4d simplicial facet
+ prints triangles for unvisited neighbors (qh.visit_id)
+
+ notes:
+ must agree with printend4geom()
+*/
+void qh_printfacet4geom_simplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]) {
+ setT *vertices;
+ facetT *neighbor, **neighborp;
+ vertexT *vertex, **vertexp;
+ int k;
+
+ facet->visitid= qh->visit_id;
+ if (qh->PRINTnoplanes || (facet->visible && qh->NEWfacets))
+ return;
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid == qh->visit_id)
+ continue;
+ if (qh->PRINTtransparent && !neighbor->good)
+ continue;
+ vertices= qh_setnew_delnthsorted(qh, facet->vertices, qh->hull_dim,
+ SETindex_(facet->neighbors, neighbor), 0);
+ if (qh->DOintersections)
+ qh_printhyperplaneintersection(qh, fp, facet, neighbor, vertices, color);
+ else {
+ if (qh->DROPdim >= 0)
+ qh_fprintf(qh, fp, 9119, "OFF 3 1 1 # ridge between f%d f%d\n",
+ facet->id, neighbor->id);
+ else {
+ qh->printoutvar++;
+ qh_fprintf(qh, fp, 9120, "# ridge between f%d f%d\n", facet->id, neighbor->id);
+ }
+ FOREACHvertex_(vertices) {
+ for (k=0; k < qh->hull_dim; k++) {
+ if (k != qh->DROPdim)
+ qh_fprintf(qh, fp, 9121, "%8.4g ", vertex->point[k]);
+ }
+ qh_fprintf(qh, fp, 9122, "\n");
+ }
+ if (qh->DROPdim >= 0)
+ qh_fprintf(qh, fp, 9123, "3 0 1 2 %8.4g %8.4g %8.4g\n", color[0], color[1], color[2]);
+ }
+ qh_setfree(qh, &vertices);
+ }
+} /* printfacet4geom_simplicial */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacetNvertex_nonsimplicial">-</a>
+
+ qh_printfacetNvertex_nonsimplicial(qh, fp, facet, id, format )
+ print vertices for an N-d non-simplicial facet
+ triangulates each ridge to the id
+*/
+void qh_printfacetNvertex_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, int id, qh_PRINT format) {
+ vertexT *vertex, **vertexp;
+ ridgeT *ridge, **ridgep;
+
+ if (facet->visible && qh->NEWfacets)
+ return;
+ FOREACHridge_(facet->ridges) {
+ if (format == qh_PRINTtriangles)
+ qh_fprintf(qh, fp, 9124, "%d ", qh->hull_dim);
+ qh_fprintf(qh, fp, 9125, "%d ", id);
+ if ((ridge->top == facet) ^ qh_ORIENTclock) {
+ FOREACHvertex_(ridge->vertices)
+ qh_fprintf(qh, fp, 9126, "%d ", qh_pointid(qh, vertex->point));
+ }else {
+ FOREACHvertexreverse12_(ridge->vertices)
+ qh_fprintf(qh, fp, 9127, "%d ", qh_pointid(qh, vertex->point));
+ }
+ qh_fprintf(qh, fp, 9128, "\n");
+ }
+} /* printfacetNvertex_nonsimplicial */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacetNvertex_simplicial">-</a>
+
+ qh_printfacetNvertex_simplicial(qh, fp, facet, format )
+ print vertices for an N-d simplicial facet
+ prints vertices for non-simplicial facets
+ 2-d facets (orientation preserved by qh_mergefacet2d)
+ PRINToff ('o') for 4-d and higher
+*/
+void qh_printfacetNvertex_simplicial(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format) {
+ vertexT *vertex, **vertexp;
+
+ if (format == qh_PRINToff || format == qh_PRINTtriangles)
+ qh_fprintf(qh, fp, 9129, "%d ", qh_setsize(qh, facet->vertices));
+ if ((facet->toporient ^ qh_ORIENTclock)
+ || (qh->hull_dim > 2 && !facet->simplicial)) {
+ FOREACHvertex_(facet->vertices)
+ qh_fprintf(qh, fp, 9130, "%d ", qh_pointid(qh, vertex->point));
+ }else {
+ FOREACHvertexreverse12_(facet->vertices)
+ qh_fprintf(qh, fp, 9131, "%d ", qh_pointid(qh, vertex->point));
+ }
+ qh_fprintf(qh, fp, 9132, "\n");
+} /* printfacetNvertex_simplicial */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacetheader">-</a>
+
+ qh_printfacetheader(qh, fp, facet )
+ prints header fields of a facet to fp
+
+ notes:
+ for 'f' output and debugging
+ Same as QhullFacet::printHeader()
+*/
+void qh_printfacetheader(qhT *qh, FILE *fp, facetT *facet) {
+ pointT *point, **pointp, *furthest;
+ facetT *neighbor, **neighborp;
+ realT dist;
+
+ if (facet == qh_MERGEridge) {
+ qh_fprintf(qh, fp, 9133, " MERGEridge\n");
+ return;
+ }else if (facet == qh_DUPLICATEridge) {
+ qh_fprintf(qh, fp, 9134, " DUPLICATEridge\n");
+ return;
+ }else if (!facet) {
+ qh_fprintf(qh, fp, 9135, " NULLfacet\n");
+ return;
+ }
+ qh->old_randomdist= qh->RANDOMdist;
+ qh->RANDOMdist= False;
+ qh_fprintf(qh, fp, 9136, "- f%d\n", facet->id);
+ qh_fprintf(qh, fp, 9137, " - flags:");
+ if (facet->toporient)
+ qh_fprintf(qh, fp, 9138, " top");
+ else
+ qh_fprintf(qh, fp, 9139, " bottom");
+ if (facet->simplicial)
+ qh_fprintf(qh, fp, 9140, " simplicial");
+ if (facet->tricoplanar)
+ qh_fprintf(qh, fp, 9141, " tricoplanar");
+ if (facet->upperdelaunay)
+ qh_fprintf(qh, fp, 9142, " upperDelaunay");
+ if (facet->visible)
+ qh_fprintf(qh, fp, 9143, " visible");
+ if (facet->newfacet)
+ qh_fprintf(qh, fp, 9144, " new");
+ if (facet->tested)
+ qh_fprintf(qh, fp, 9145, " tested");
+ if (!facet->good)
+ qh_fprintf(qh, fp, 9146, " notG");
+ if (facet->seen)
+ qh_fprintf(qh, fp, 9147, " seen");
+ if (facet->coplanar)
+ qh_fprintf(qh, fp, 9148, " coplanar");
+ if (facet->mergehorizon)
+ qh_fprintf(qh, fp, 9149, " mergehorizon");
+ if (facet->keepcentrum)
+ qh_fprintf(qh, fp, 9150, " keepcentrum");
+ if (facet->dupridge)
+ qh_fprintf(qh, fp, 9151, " dupridge");
+ if (facet->mergeridge && !facet->mergeridge2)
+ qh_fprintf(qh, fp, 9152, " mergeridge1");
+ if (facet->mergeridge2)
+ qh_fprintf(qh, fp, 9153, " mergeridge2");
+ if (facet->newmerge)
+ qh_fprintf(qh, fp, 9154, " newmerge");
+ if (facet->flipped)
+ qh_fprintf(qh, fp, 9155, " flipped");
+ if (facet->notfurthest)
+ qh_fprintf(qh, fp, 9156, " notfurthest");
+ if (facet->degenerate)
+ qh_fprintf(qh, fp, 9157, " degenerate");
+ if (facet->redundant)
+ qh_fprintf(qh, fp, 9158, " redundant");
+ qh_fprintf(qh, fp, 9159, "\n");
+ if (facet->isarea)
+ qh_fprintf(qh, fp, 9160, " - area: %2.2g\n", facet->f.area);
+ else if (qh->NEWfacets && facet->visible && facet->f.replace)
+ qh_fprintf(qh, fp, 9161, " - replacement: f%d\n", facet->f.replace->id);
+ else if (facet->newfacet) {
+ if (facet->f.samecycle && facet->f.samecycle != facet)
+ qh_fprintf(qh, fp, 9162, " - shares same visible/horizon as f%d\n", facet->f.samecycle->id);
+ }else if (facet->tricoplanar /* !isarea */) {
+ if (facet->f.triowner)
+ qh_fprintf(qh, fp, 9163, " - owner of normal & centrum is facet f%d\n", facet->f.triowner->id);
+ }else if (facet->f.newcycle)
+ qh_fprintf(qh, fp, 9164, " - was horizon to f%d\n", facet->f.newcycle->id);
+ if (facet->nummerge)
+ qh_fprintf(qh, fp, 9165, " - merges: %d\n", facet->nummerge);
+ qh_printpointid(qh, fp, " - normal: ", qh->hull_dim, facet->normal, qh_IDunknown);
+ qh_fprintf(qh, fp, 9166, " - offset: %10.7g\n", facet->offset);
+ if (qh->CENTERtype == qh_ASvoronoi || facet->center)
+ qh_printcenter(qh, fp, qh_PRINTfacets, " - center: ", facet);
+#if qh_MAXoutside
+ if (facet->maxoutside > qh->DISTround)
+ qh_fprintf(qh, fp, 9167, " - maxoutside: %10.7g\n", facet->maxoutside);
+#endif
+ if (!SETempty_(facet->outsideset)) {
+ furthest= (pointT*)qh_setlast(facet->outsideset);
+ if (qh_setsize(qh, facet->outsideset) < 6) {
+ qh_fprintf(qh, fp, 9168, " - outside set(furthest p%d):\n", qh_pointid(qh, furthest));
+ FOREACHpoint_(facet->outsideset)
+ qh_printpoint(qh, fp, " ", point);
+ }else if (qh_setsize(qh, facet->outsideset) < 21) {
+ qh_printpoints(qh, fp, " - outside set:", facet->outsideset);
+ }else {
+ qh_fprintf(qh, fp, 9169, " - outside set: %d points.", qh_setsize(qh, facet->outsideset));
+ qh_printpoint(qh, fp, " Furthest", furthest);
+ }
+#if !qh_COMPUTEfurthest
+ qh_fprintf(qh, fp, 9170, " - furthest distance= %2.2g\n", facet->furthestdist);
+#endif
+ }
+ if (!SETempty_(facet->coplanarset)) {
+ furthest= (pointT*)qh_setlast(facet->coplanarset);
+ if (qh_setsize(qh, facet->coplanarset) < 6) {
+ qh_fprintf(qh, fp, 9171, " - coplanar set(furthest p%d):\n", qh_pointid(qh, furthest));
+ FOREACHpoint_(facet->coplanarset)
+ qh_printpoint(qh, fp, " ", point);
+ }else if (qh_setsize(qh, facet->coplanarset) < 21) {
+ qh_printpoints(qh, fp, " - coplanar set:", facet->coplanarset);
+ }else {
+ qh_fprintf(qh, fp, 9172, " - coplanar set: %d points.", qh_setsize(qh, facet->coplanarset));
+ qh_printpoint(qh, fp, " Furthest", furthest);
+ }
+ zinc_(Zdistio);
+ qh_distplane(qh, furthest, facet, &dist);
+ qh_fprintf(qh, fp, 9173, " furthest distance= %2.2g\n", dist);
+ }
+ qh_printvertices(qh, fp, " - vertices:", facet->vertices);
+ qh_fprintf(qh, fp, 9174, " - neighboring facets:");
+ FOREACHneighbor_(facet) {
+ if (neighbor == qh_MERGEridge)
+ qh_fprintf(qh, fp, 9175, " MERGE");
+ else if (neighbor == qh_DUPLICATEridge)
+ qh_fprintf(qh, fp, 9176, " DUP");
+ else
+ qh_fprintf(qh, fp, 9177, " f%d", neighbor->id);
+ }
+ qh_fprintf(qh, fp, 9178, "\n");
+ qh->RANDOMdist= qh->old_randomdist;
+} /* printfacetheader */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacetridges">-</a>
+
+ qh_printfacetridges(qh, fp, facet )
+ prints ridges of a facet to fp
+
+ notes:
+ ridges printed in neighbor order
+ assumes the ridges exist
+ for 'f' output
+ same as QhullFacet::printRidges
+*/
+void qh_printfacetridges(qhT *qh, FILE *fp, facetT *facet) {
+ facetT *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+ int numridges= 0;
+
+
+ if (facet->visible && qh->NEWfacets) {
+ qh_fprintf(qh, fp, 9179, " - ridges(ids may be garbage):");
+ FOREACHridge_(facet->ridges)
+ qh_fprintf(qh, fp, 9180, " r%d", ridge->id);
+ qh_fprintf(qh, fp, 9181, "\n");
+ }else {
+ qh_fprintf(qh, fp, 9182, " - ridges:\n");
+ FOREACHridge_(facet->ridges)
+ ridge->seen= False;
+ if (qh->hull_dim == 3) {
+ ridge= SETfirstt_(facet->ridges, ridgeT);
+ while (ridge && !ridge->seen) {
+ ridge->seen= True;
+ qh_printridge(qh, fp, ridge);
+ numridges++;
+ ridge= qh_nextridge3d(ridge, facet, NULL);
+ }
+ }else {
+ FOREACHneighbor_(facet) {
+ FOREACHridge_(facet->ridges) {
+ if (otherfacet_(ridge,facet) == neighbor) {
+ ridge->seen= True;
+ qh_printridge(qh, fp, ridge);
+ numridges++;
+ }
+ }
+ }
+ }
+ if (numridges != qh_setsize(qh, facet->ridges)) {
+ qh_fprintf(qh, fp, 9183, " - all ridges:");
+ FOREACHridge_(facet->ridges)
+ qh_fprintf(qh, fp, 9184, " r%d", ridge->id);
+ qh_fprintf(qh, fp, 9185, "\n");
+ }
+ FOREACHridge_(facet->ridges) {
+ if (!ridge->seen)
+ qh_printridge(qh, fp, ridge);
+ }
+ }
+} /* printfacetridges */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printfacets">-</a>
+
+ qh_printfacets(qh, fp, format, facetlist, facets, printall )
+ prints facetlist and/or facet set in output format
+
+ notes:
+ also used for specialized formats ('FO' and summary)
+ turns off 'Rn' option since want actual numbers
+*/
+void qh_printfacets(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
+ int numfacets, numsimplicial, numridges, totneighbors, numcoplanars, numtricoplanars;
+ facetT *facet, **facetp;
+ setT *vertices;
+ coordT *center;
+ realT outerplane, innerplane;
+
+ qh->old_randomdist= qh->RANDOMdist;
+ qh->RANDOMdist= False;
+ if (qh->CDDoutput && (format == qh_PRINTcentrums || format == qh_PRINTpointintersect || format == qh_PRINToff))
+ qh_fprintf(qh, qh->ferr, 7056, "qhull warning: CDD format is not available for centrums, halfspace\nintersections, and OFF file format.\n");
+ if (format == qh_PRINTnone)
+ ; /* print nothing */
+ else if (format == qh_PRINTaverage) {
+ vertices= qh_facetvertices(qh, facetlist, facets, printall);
+ center= qh_getcenter(qh, vertices);
+ qh_fprintf(qh, fp, 9186, "%d 1\n", qh->hull_dim);
+ qh_printpointid(qh, fp, NULL, qh->hull_dim, center, qh_IDunknown);
+ qh_memfree(qh, center, qh->normal_size);
+ qh_settempfree(qh, &vertices);
+ }else if (format == qh_PRINTextremes) {
+ if (qh->DELAUNAY)
+ qh_printextremes_d(qh, fp, facetlist, facets, printall);
+ else if (qh->hull_dim == 2)
+ qh_printextremes_2d(qh, fp, facetlist, facets, printall);
+ else
+ qh_printextremes(qh, fp, facetlist, facets, printall);
+ }else if (format == qh_PRINToptions)
+ qh_fprintf(qh, fp, 9187, "Options selected for Qhull %s:\n%s\n", qh_version, qh->qhull_options);
+ else if (format == qh_PRINTpoints && !qh->VORONOI)
+ qh_printpoints_out(qh, fp, facetlist, facets, printall);
+ else if (format == qh_PRINTqhull)
+ qh_fprintf(qh, fp, 9188, "%s | %s\n", qh->rbox_command, qh->qhull_command);
+ else if (format == qh_PRINTsize) {
+ qh_fprintf(qh, fp, 9189, "0\n2 ");
+ qh_fprintf(qh, fp, 9190, qh_REAL_1, qh->totarea);
+ qh_fprintf(qh, fp, 9191, qh_REAL_1, qh->totvol);
+ qh_fprintf(qh, fp, 9192, "\n");
+ }else if (format == qh_PRINTsummary) {
+ qh_countfacets(qh, facetlist, facets, printall, &numfacets, &numsimplicial,
+ &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
+ vertices= qh_facetvertices(qh, facetlist, facets, printall);
+ qh_fprintf(qh, fp, 9193, "10 %d %d %d %d %d %d %d %d %d %d\n2 ", qh->hull_dim,
+ qh->num_points + qh_setsize(qh, qh->other_points),
+ qh->num_vertices, qh->num_facets - qh->num_visible,
+ qh_setsize(qh, vertices), numfacets, numcoplanars,
+ numfacets - numsimplicial, zzval_(Zdelvertextot),
+ numtricoplanars);
+ qh_settempfree(qh, &vertices);
+ qh_outerinner(qh, NULL, &outerplane, &innerplane);
+ qh_fprintf(qh, fp, 9194, qh_REAL_2n, outerplane, innerplane);
+ }else if (format == qh_PRINTvneighbors)
+ qh_printvneighbors(qh, fp, facetlist, facets, printall);
+ else if (qh->VORONOI && format == qh_PRINToff)
+ qh_printvoronoi(qh, fp, format, facetlist, facets, printall);
+ else if (qh->VORONOI && format == qh_PRINTgeom) {
+ qh_printbegin(qh, fp, format, facetlist, facets, printall);
+ qh_printvoronoi(qh, fp, format, facetlist, facets, printall);
+ qh_printend(qh, fp, format, facetlist, facets, printall);
+ }else if (qh->VORONOI
+ && (format == qh_PRINTvertices || format == qh_PRINTinner || format == qh_PRINTouter))
+ qh_printvdiagram(qh, fp, format, facetlist, facets, printall);
+ else {
+ qh_printbegin(qh, fp, format, facetlist, facets, printall);
+ FORALLfacet_(facetlist)
+ qh_printafacet(qh, fp, format, facet, printall);
+ FOREACHfacet_(facets)
+ qh_printafacet(qh, fp, format, facet, printall);
+ qh_printend(qh, fp, format, facetlist, facets, printall);
+ }
+ qh->RANDOMdist= qh->old_randomdist;
+} /* printfacets */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printhyperplaneintersection">-</a>
+
+ qh_printhyperplaneintersection(qh, fp, facet1, facet2, vertices, color )
+ print Geomview OFF or 4OFF for the intersection of two hyperplanes in 3-d or 4-d
+*/
+void qh_printhyperplaneintersection(qhT *qh, FILE *fp, facetT *facet1, facetT *facet2,
+ setT *vertices, realT color[3]) {
+ realT costheta, denominator, dist1, dist2, s, t, mindenom, p[4];
+ vertexT *vertex, **vertexp;
+ int i, k;
+ boolT nearzero1, nearzero2;
+
+ costheta= qh_getangle(qh, facet1->normal, facet2->normal);
+ denominator= 1 - costheta * costheta;
+ i= qh_setsize(qh, vertices);
+ if (qh->hull_dim == 3)
+ qh_fprintf(qh, fp, 9195, "VECT 1 %d 1 %d 1 ", i, i);
+ else if (qh->hull_dim == 4 && qh->DROPdim >= 0)
+ qh_fprintf(qh, fp, 9196, "OFF 3 1 1 ");
+ else
+ qh->printoutvar++;
+ qh_fprintf(qh, fp, 9197, "# intersect f%d f%d\n", facet1->id, facet2->id);
+ mindenom= 1 / (10.0 * qh->MAXabs_coord);
+ FOREACHvertex_(vertices) {
+ zadd_(Zdistio, 2);
+ qh_distplane(qh, vertex->point, facet1, &dist1);
+ qh_distplane(qh, vertex->point, facet2, &dist2);
+ s= qh_divzero(-dist1 + costheta * dist2, denominator,mindenom,&nearzero1);
+ t= qh_divzero(-dist2 + costheta * dist1, denominator,mindenom,&nearzero2);
+ if (nearzero1 || nearzero2)
+ s= t= 0.0;
+ for (k=qh->hull_dim; k--; )
+ p[k]= vertex->point[k] + facet1->normal[k] * s + facet2->normal[k] * t;
+ if (qh->PRINTdim <= 3) {
+ qh_projectdim3(qh, p, p);
+ qh_fprintf(qh, fp, 9198, "%8.4g %8.4g %8.4g # ", p[0], p[1], p[2]);
+ }else
+ qh_fprintf(qh, fp, 9199, "%8.4g %8.4g %8.4g %8.4g # ", p[0], p[1], p[2], p[3]);
+ if (nearzero1+nearzero2)
+ qh_fprintf(qh, fp, 9200, "p%d(coplanar facets)\n", qh_pointid(qh, vertex->point));
+ else
+ qh_fprintf(qh, fp, 9201, "projected p%d\n", qh_pointid(qh, vertex->point));
+ }
+ if (qh->hull_dim == 3)
+ qh_fprintf(qh, fp, 9202, "%8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
+ else if (qh->hull_dim == 4 && qh->DROPdim >= 0)
+ qh_fprintf(qh, fp, 9203, "3 0 1 2 %8.4g %8.4g %8.4g 1.0\n", color[0], color[1], color[2]);
+} /* printhyperplaneintersection */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printline3geom">-</a>
+
+ qh_printline3geom(qh, fp, pointA, pointB, color )
+ prints a line as a VECT
+ prints 0's for qh.DROPdim
+
+ notes:
+ if pointA == pointB,
+ it's a 1 point VECT
+*/
+void qh_printline3geom(qhT *qh, FILE *fp, pointT *pointA, pointT *pointB, realT color[3]) {
+ int k;
+ realT pA[4], pB[4];
+
+ qh_projectdim3(qh, pointA, pA);
+ qh_projectdim3(qh, pointB, pB);
+ if ((fabs(pA[0] - pB[0]) > 1e-3) ||
+ (fabs(pA[1] - pB[1]) > 1e-3) ||
+ (fabs(pA[2] - pB[2]) > 1e-3)) {
+ qh_fprintf(qh, fp, 9204, "VECT 1 2 1 2 1\n");
+ for (k=0; k < 3; k++)
+ qh_fprintf(qh, fp, 9205, "%8.4g ", pB[k]);
+ qh_fprintf(qh, fp, 9206, " # p%d\n", qh_pointid(qh, pointB));
+ }else
+ qh_fprintf(qh, fp, 9207, "VECT 1 1 1 1 1\n");
+ for (k=0; k < 3; k++)
+ qh_fprintf(qh, fp, 9208, "%8.4g ", pA[k]);
+ qh_fprintf(qh, fp, 9209, " # p%d\n", qh_pointid(qh, pointA));
+ qh_fprintf(qh, fp, 9210, "%8.4g %8.4g %8.4g 1\n", color[0], color[1], color[2]);
+}
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printneighborhood">-</a>
+
+ qh_printneighborhood(qh, fp, format, facetA, facetB, printall )
+ print neighborhood of one or two facets
+
+ notes:
+ calls qh_findgood_all()
+ bumps qh.visit_id
+*/
+void qh_printneighborhood(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall) {
+ facetT *neighbor, **neighborp, *facet;
+ setT *facets;
+
+ if (format == qh_PRINTnone)
+ return;
+ qh_findgood_all(qh, qh->facet_list);
+ if (facetA == facetB)
+ facetB= NULL;
+ facets= qh_settemp(qh, 2*(qh_setsize(qh, facetA->neighbors)+1));
+ qh->visit_id++;
+ for (facet= facetA; facet; facet= ((facet == facetA) ? facetB : NULL)) {
+ if (facet->visitid != qh->visit_id) {
+ facet->visitid= qh->visit_id;
+ qh_setappend(qh, &facets, facet);
+ }
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid == qh->visit_id)
+ continue;
+ neighbor->visitid= qh->visit_id;
+ if (printall || !qh_skipfacet(qh, neighbor))
+ qh_setappend(qh, &facets, neighbor);
+ }
+ }
+ qh_printfacets(qh, fp, format, NULL, facets, printall);
+ qh_settempfree(qh, &facets);
+} /* printneighborhood */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printpoint">-</a>
+
+ qh_printpoint(qh, fp, string, point )
+ qh_printpointid(qh, fp, string, dim, point, id )
+ prints the coordinates of a point
+
+ returns:
+ if string is defined
+ prints 'string p%d'. Skips p%d if id=qh_IDunknown(-1) or qh_IDnone(-3)
+
+ notes:
+ nop if point is NULL
+ Same as QhullPoint's printPoint
+*/
+void qh_printpoint(qhT *qh, FILE *fp, const char *string, pointT *point) {
+ int id= qh_pointid(qh, point);
+
+ qh_printpointid(qh, fp, string, qh->hull_dim, point, id);
+} /* printpoint */
+
+void qh_printpointid(qhT *qh, FILE *fp, const char *string, int dim, pointT *point, int id) {
+ int k;
+ realT r; /*bug fix*/
+
+ if (!point)
+ return;
+ if (string) {
+ qh_fprintf(qh, fp, 9211, "%s", string);
+ if (id != qh_IDunknown && id != qh_IDnone)
+ qh_fprintf(qh, fp, 9212, " p%d: ", id);
+ }
+ for (k=dim; k--; ) {
+ r= *point++;
+ if (string)
+ qh_fprintf(qh, fp, 9213, " %8.4g", r);
+ else
+ qh_fprintf(qh, fp, 9214, qh_REAL_1, r);
+ }
+ qh_fprintf(qh, fp, 9215, "\n");
+} /* printpointid */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printpoint3">-</a>
+
+ qh_printpoint3(qh, fp, point )
+ prints 2-d, 3-d, or 4-d point as Geomview 3-d coordinates
+*/
+void qh_printpoint3(qhT *qh, FILE *fp, pointT *point) {
+ int k;
+ realT p[4];
+
+ qh_projectdim3(qh, point, p);
+ for (k=0; k < 3; k++)
+ qh_fprintf(qh, fp, 9216, "%8.4g ", p[k]);
+ qh_fprintf(qh, fp, 9217, " # p%d\n", qh_pointid(qh, point));
+} /* printpoint3 */
+
+/*----------------------------------------
+-printpoints- print pointids for a set of points starting at index
+ see geom_r.c
+*/
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printpoints_out">-</a>
+
+ qh_printpoints_out(qh, fp, facetlist, facets, printall )
+ prints vertices, coplanar/inside points, for facets by their point coordinates
+ allows qh.CDDoutput
+
+ notes:
+ same format as qhull input
+ if no coplanar/interior points,
+ same order as qh_printextremes
+*/
+void qh_printpoints_out(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall) {
+ int allpoints= qh->num_points + qh_setsize(qh, qh->other_points);
+ int numpoints=0, point_i, point_n;
+ setT *vertices, *points;
+ facetT *facet, **facetp;
+ pointT *point, **pointp;
+ vertexT *vertex, **vertexp;
+ int id;
+
+ points= qh_settemp(qh, allpoints);
+ qh_setzero(qh, points, 0, allpoints);
+ vertices= qh_facetvertices(qh, facetlist, facets, printall);
+ FOREACHvertex_(vertices) {
+ id= qh_pointid(qh, vertex->point);
+ if (id >= 0)
+ SETelem_(points, id)= vertex->point;
+ }
+ if (qh->KEEPinside || qh->KEEPcoplanar || qh->KEEPnearinside) {
+ FORALLfacet_(facetlist) {
+ if (!printall && qh_skipfacet(qh, facet))
+ continue;
+ FOREACHpoint_(facet->coplanarset) {
+ id= qh_pointid(qh, point);
+ if (id >= 0)
+ SETelem_(points, id)= point;
+ }
+ }
+ FOREACHfacet_(facets) {
+ if (!printall && qh_skipfacet(qh, facet))
+ continue;
+ FOREACHpoint_(facet->coplanarset) {
+ id= qh_pointid(qh, point);
+ if (id >= 0)
+ SETelem_(points, id)= point;
+ }
+ }
+ }
+ qh_settempfree(qh, &vertices);
+ FOREACHpoint_i_(qh, points) {
+ if (point)
+ numpoints++;
+ }
+ if (qh->CDDoutput)
+ qh_fprintf(qh, fp, 9218, "%s | %s\nbegin\n%d %d real\n", qh->rbox_command,
+ qh->qhull_command, numpoints, qh->hull_dim + 1);
+ else
+ qh_fprintf(qh, fp, 9219, "%d\n%d\n", qh->hull_dim, numpoints);
+ FOREACHpoint_i_(qh, points) {
+ if (point) {
+ if (qh->CDDoutput)
+ qh_fprintf(qh, fp, 9220, "1 ");
+ qh_printpoint(qh, fp, NULL, point);
+ }
+ }
+ if (qh->CDDoutput)
+ qh_fprintf(qh, fp, 9221, "end\n");
+ qh_settempfree(qh, &points);
+} /* printpoints_out */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printpointvect">-</a>
+
+ qh_printpointvect(qh, fp, point, normal, center, radius, color )
+ prints a 2-d, 3-d, or 4-d point as 3-d VECT's relative to normal or to center point
+*/
+void qh_printpointvect(qhT *qh, FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]) {
+ realT diff[4], pointA[4];
+ int k;
+
+ for (k=qh->hull_dim; k--; ) {
+ if (center)
+ diff[k]= point[k]-center[k];
+ else if (normal)
+ diff[k]= normal[k];
+ else
+ diff[k]= 0;
+ }
+ if (center)
+ qh_normalize2(qh, diff, qh->hull_dim, True, NULL, NULL);
+ for (k=qh->hull_dim; k--; )
+ pointA[k]= point[k]+diff[k] * radius;
+ qh_printline3geom(qh, fp, point, pointA, color);
+} /* printpointvect */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printpointvect2">-</a>
+
+ qh_printpointvect2(qh, fp, point, normal, center, radius )
+ prints a 2-d, 3-d, or 4-d point as 2 3-d VECT's for an imprecise point
+*/
+void qh_printpointvect2(qhT *qh, FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius) {
+ realT red[3]={1, 0, 0}, yellow[3]={1, 1, 0};
+
+ qh_printpointvect(qh, fp, point, normal, center, radius, red);
+ qh_printpointvect(qh, fp, point, normal, center, -radius, yellow);
+} /* printpointvect2 */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printridge">-</a>
+
+ qh_printridge(qh, fp, ridge )
+ prints the information in a ridge
+
+ notes:
+ for qh_printfacetridges()
+ same as operator<< [QhullRidge.cpp]
+*/
+void qh_printridge(qhT *qh, FILE *fp, ridgeT *ridge) {
+
+ qh_fprintf(qh, fp, 9222, " - r%d", ridge->id);
+ if (ridge->tested)
+ qh_fprintf(qh, fp, 9223, " tested");
+ if (ridge->nonconvex)
+ qh_fprintf(qh, fp, 9224, " nonconvex");
+ qh_fprintf(qh, fp, 9225, "\n");
+ qh_printvertices(qh, fp, " vertices:", ridge->vertices);
+ if (ridge->top && ridge->bottom)
+ qh_fprintf(qh, fp, 9226, " between f%d and f%d\n",
+ ridge->top->id, ridge->bottom->id);
+} /* printridge */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printspheres">-</a>
+
+ qh_printspheres(qh, fp, vertices, radius )
+ prints 3-d vertices as OFF spheres
+
+ notes:
+ inflated octahedron from Stuart Levy earth/mksphere2
+*/
+void qh_printspheres(qhT *qh, FILE *fp, setT *vertices, realT radius) {
+ vertexT *vertex, **vertexp;
+
+ qh->printoutnum++;
+ qh_fprintf(qh, fp, 9227, "{appearance {-edge -normal normscale 0} {\n\
+INST geom {define vsphere OFF\n\
+18 32 48\n\
+\n\
+0 0 1\n\
+1 0 0\n\
+0 1 0\n\
+-1 0 0\n\
+0 -1 0\n\
+0 0 -1\n\
+0.707107 0 0.707107\n\
+0 -0.707107 0.707107\n\
+0.707107 -0.707107 0\n\
+-0.707107 0 0.707107\n\
+-0.707107 -0.707107 0\n\
+0 0.707107 0.707107\n\
+-0.707107 0.707107 0\n\
+0.707107 0.707107 0\n\
+0.707107 0 -0.707107\n\
+0 0.707107 -0.707107\n\
+-0.707107 0 -0.707107\n\
+0 -0.707107 -0.707107\n\
+\n\
+3 0 6 11\n\
+3 0 7 6 \n\
+3 0 9 7 \n\
+3 0 11 9\n\
+3 1 6 8 \n\
+3 1 8 14\n\
+3 1 13 6\n\
+3 1 14 13\n\
+3 2 11 13\n\
+3 2 12 11\n\
+3 2 13 15\n\
+3 2 15 12\n\
+3 3 9 12\n\
+3 3 10 9\n\
+3 3 12 16\n\
+3 3 16 10\n\
+3 4 7 10\n\
+3 4 8 7\n\
+3 4 10 17\n\
+3 4 17 8\n\
+3 5 14 17\n\
+3 5 15 14\n\
+3 5 16 15\n\
+3 5 17 16\n\
+3 6 13 11\n\
+3 7 8 6\n\
+3 9 10 7\n\
+3 11 12 9\n\
+3 14 8 17\n\
+3 15 13 14\n\
+3 16 12 15\n\
+3 17 10 16\n} transforms { TLIST\n");
+ FOREACHvertex_(vertices) {
+ qh_fprintf(qh, fp, 9228, "%8.4g 0 0 0 # v%d\n 0 %8.4g 0 0\n0 0 %8.4g 0\n",
+ radius, vertex->id, radius, radius);
+ qh_printpoint3(qh, fp, vertex->point);
+ qh_fprintf(qh, fp, 9229, "1\n");
+ }
+ qh_fprintf(qh, fp, 9230, "}}}\n");
+} /* printspheres */
+
+
+/*----------------------------------------------
+-printsummary-
+ see libqhull_r.c
+*/
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printvdiagram">-</a>
+
+ qh_printvdiagram(qh, fp, format, facetlist, facets, printall )
+ print voronoi diagram
+ # of pairs of input sites
+ #indices site1 site2 vertex1 ...
+
+ sites indexed by input point id
+ point 0 is the first input point
+ vertices indexed by 'o' and 'p' order
+ vertex 0 is the 'vertex-at-infinity'
+ vertex 1 is the first Voronoi vertex
+
+ see:
+ qh_printvoronoi()
+ qh_eachvoronoi_all()
+
+ notes:
+ if all facets are upperdelaunay,
+ prints upper hull (furthest-site Voronoi diagram)
+*/
+void qh_printvdiagram(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
+ setT *vertices;
+ int totcount, numcenters;
+ boolT isLower;
+ qh_RIDGE innerouter= qh_RIDGEall;
+ printvridgeT printvridge= NULL;
+
+ if (format == qh_PRINTvertices) {
+ innerouter= qh_RIDGEall;
+ printvridge= qh_printvridge;
+ }else if (format == qh_PRINTinner) {
+ innerouter= qh_RIDGEinner;
+ printvridge= qh_printvnorm;
+ }else if (format == qh_PRINTouter) {
+ innerouter= qh_RIDGEouter;
+ printvridge= qh_printvnorm;
+ }else {
+ qh_fprintf(qh, qh->ferr, 6219, "Qhull internal error (qh_printvdiagram): unknown print format %d.\n", format);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ vertices= qh_markvoronoi(qh, facetlist, facets, printall, &isLower, &numcenters);
+ totcount= qh_printvdiagram2(qh, NULL, NULL, vertices, innerouter, False);
+ qh_fprintf(qh, fp, 9231, "%d\n", totcount);
+ totcount= qh_printvdiagram2(qh, fp, printvridge, vertices, innerouter, True /* inorder*/);
+ qh_settempfree(qh, &vertices);
+#if 0 /* for testing qh_eachvoronoi_all */
+ qh_fprintf(qh, fp, 9232, "\n");
+ totcount= qh_eachvoronoi_all(qh, fp, printvridge, qh->UPPERdelaunay, innerouter, True /* inorder*/);
+ qh_fprintf(qh, fp, 9233, "%d\n", totcount);
+#endif
+} /* printvdiagram */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printvdiagram2">-</a>
+
+ qh_printvdiagram2(qh, fp, printvridge, vertices, innerouter, inorder )
+ visit all pairs of input sites (vertices) for selected Voronoi vertices
+ vertices may include NULLs
+
+ innerouter:
+ qh_RIDGEall print inner ridges(bounded) and outer ridges(unbounded)
+ qh_RIDGEinner print only inner ridges
+ qh_RIDGEouter print only outer ridges
+
+ inorder:
+ print 3-d Voronoi vertices in order
+
+ assumes:
+ qh_markvoronoi marked facet->visitid for Voronoi vertices
+ all facet->seen= False
+ all facet->seen2= True
+
+ returns:
+ total number of Voronoi ridges
+ if printvridge,
+ calls printvridge( fp, vertex, vertexA, centers) for each ridge
+ [see qh_eachvoronoi()]
+
+ see:
+ qh_eachvoronoi_all()
+*/
+int qh_printvdiagram2(qhT *qh, FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder) {
+ int totcount= 0;
+ int vertex_i, vertex_n;
+ vertexT *vertex;
+
+ FORALLvertices
+ vertex->seen= False;
+ FOREACHvertex_i_(qh, vertices) {
+ if (vertex) {
+ if (qh->GOODvertex > 0 && qh_pointid(qh, vertex->point)+1 != qh->GOODvertex)
+ continue;
+ totcount += qh_eachvoronoi(qh, fp, printvridge, vertex, !qh_ALL, innerouter, inorder);
+ }
+ }
+ return totcount;
+} /* printvdiagram2 */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printvertex">-</a>
+
+ qh_printvertex(qh, fp, vertex )
+ prints the information in a vertex
+ Duplicated as operator<< [QhullVertex.cpp]
+*/
+void qh_printvertex(qhT *qh, FILE *fp, vertexT *vertex) {
+ pointT *point;
+ int k, count= 0;
+ facetT *neighbor, **neighborp;
+ realT r; /*bug fix*/
+
+ if (!vertex) {
+ qh_fprintf(qh, fp, 9234, " NULLvertex\n");
+ return;
+ }
+ qh_fprintf(qh, fp, 9235, "- p%d(v%d):", qh_pointid(qh, vertex->point), vertex->id);
+ point= vertex->point;
+ if (point) {
+ for (k=qh->hull_dim; k--; ) {
+ r= *point++;
+ qh_fprintf(qh, fp, 9236, " %5.2g", r);
+ }
+ }
+ if (vertex->deleted)
+ qh_fprintf(qh, fp, 9237, " deleted");
+ if (vertex->delridge)
+ qh_fprintf(qh, fp, 9238, " ridgedeleted");
+ qh_fprintf(qh, fp, 9239, "\n");
+ if (vertex->neighbors) {
+ qh_fprintf(qh, fp, 9240, " neighbors:");
+ FOREACHneighbor_(vertex) {
+ if (++count % 100 == 0)
+ qh_fprintf(qh, fp, 9241, "\n ");
+ qh_fprintf(qh, fp, 9242, " f%d", neighbor->id);
+ }
+ qh_fprintf(qh, fp, 9243, "\n");
+ }
+} /* printvertex */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printvertexlist">-</a>
+
+ qh_printvertexlist(qh, fp, string, facetlist, facets, printall )
+ prints vertices used by a facetlist or facet set
+ tests qh_skipfacet() if !printall
+*/
+void qh_printvertexlist(qhT *qh, FILE *fp, const char* string, facetT *facetlist,
+ setT *facets, boolT printall) {
+ vertexT *vertex, **vertexp;
+ setT *vertices;
+
+ vertices= qh_facetvertices(qh, facetlist, facets, printall);
+ qh_fprintf(qh, fp, 9244, "%s", string);
+ FOREACHvertex_(vertices)
+ qh_printvertex(qh, fp, vertex);
+ qh_settempfree(qh, &vertices);
+} /* printvertexlist */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printvertices">-</a>
+
+ qh_printvertices(qh, fp, string, vertices )
+ prints vertices in a set
+ duplicated as printVertexSet [QhullVertex.cpp]
+*/
+void qh_printvertices(qhT *qh, FILE *fp, const char* string, setT *vertices) {
+ vertexT *vertex, **vertexp;
+
+ qh_fprintf(qh, fp, 9245, "%s", string);
+ FOREACHvertex_(vertices)
+ qh_fprintf(qh, fp, 9246, " p%d(v%d)", qh_pointid(qh, vertex->point), vertex->id);
+ qh_fprintf(qh, fp, 9247, "\n");
+} /* printvertices */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printvneighbors">-</a>
+
+ qh_printvneighbors(qh, fp, facetlist, facets, printall )
+ print vertex neighbors of vertices in facetlist and facets ('FN')
+
+ notes:
+ qh_countfacets clears facet->visitid for non-printed facets
+
+ design:
+ collect facet count and related statistics
+ if necessary, build neighbor sets for each vertex
+ collect vertices in facetlist and facets
+ build a point array for point->vertex and point->coplanar facet
+ for each point
+ list vertex neighbors or coplanar facet
+*/
+void qh_printvneighbors(qhT *qh, FILE *fp, facetT* facetlist, setT *facets, boolT printall) {
+ int numfacets, numsimplicial, numridges, totneighbors, numneighbors, numcoplanars, numtricoplanars;
+ setT *vertices, *vertex_points, *coplanar_points;
+ int numpoints= qh->num_points + qh_setsize(qh, qh->other_points);
+ vertexT *vertex, **vertexp;
+ int vertex_i, vertex_n;
+ facetT *facet, **facetp, *neighbor, **neighborp;
+ pointT *point, **pointp;
+
+ qh_countfacets(qh, facetlist, facets, printall, &numfacets, &numsimplicial,
+ &totneighbors, &numridges, &numcoplanars, &numtricoplanars); /* sets facet->visitid */
+ qh_fprintf(qh, fp, 9248, "%d\n", numpoints);
+ qh_vertexneighbors(qh);
+ vertices= qh_facetvertices(qh, facetlist, facets, printall);
+ vertex_points= qh_settemp(qh, numpoints);
+ coplanar_points= qh_settemp(qh, numpoints);
+ qh_setzero(qh, vertex_points, 0, numpoints);
+ qh_setzero(qh, coplanar_points, 0, numpoints);
+ FOREACHvertex_(vertices)
+ qh_point_add(qh, vertex_points, vertex->point, vertex);
+ FORALLfacet_(facetlist) {
+ FOREACHpoint_(facet->coplanarset)
+ qh_point_add(qh, coplanar_points, point, facet);
+ }
+ FOREACHfacet_(facets) {
+ FOREACHpoint_(facet->coplanarset)
+ qh_point_add(qh, coplanar_points, point, facet);
+ }
+ FOREACHvertex_i_(qh, vertex_points) {
+ if (vertex) {
+ numneighbors= qh_setsize(qh, vertex->neighbors);
+ qh_fprintf(qh, fp, 9249, "%d", numneighbors);
+ if (qh->hull_dim == 3)
+ qh_order_vertexneighbors(qh, vertex);
+ else if (qh->hull_dim >= 4)
+ qsort(SETaddr_(vertex->neighbors, facetT), (size_t)numneighbors,
+ sizeof(facetT *), qh_compare_facetvisit);
+ FOREACHneighbor_(vertex)
+ qh_fprintf(qh, fp, 9250, " %d",
+ neighbor->visitid ? neighbor->visitid - 1 : 0 - neighbor->id);
+ qh_fprintf(qh, fp, 9251, "\n");
+ }else if ((facet= SETelemt_(coplanar_points, vertex_i, facetT)))
+ qh_fprintf(qh, fp, 9252, "1 %d\n",
+ facet->visitid ? facet->visitid - 1 : 0 - facet->id);
+ else
+ qh_fprintf(qh, fp, 9253, "0\n");
+ }
+ qh_settempfree(qh, &coplanar_points);
+ qh_settempfree(qh, &vertex_points);
+ qh_settempfree(qh, &vertices);
+} /* printvneighbors */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printvoronoi">-</a>
+
+ qh_printvoronoi(qh, fp, format, facetlist, facets, printall )
+ print voronoi diagram in 'o' or 'G' format
+ for 'o' format
+ prints voronoi centers for each facet and for infinity
+ for each vertex, lists ids of printed facets or infinity
+ assumes facetlist and facets are disjoint
+ for 'G' format
+ prints an OFF object
+ adds a 0 coordinate to center
+ prints infinity but does not list in vertices
+
+ see:
+ qh_printvdiagram()
+
+ notes:
+ if 'o',
+ prints a line for each point except "at-infinity"
+ if all facets are upperdelaunay,
+ reverses lower and upper hull
+*/
+void qh_printvoronoi(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall) {
+ int k, numcenters, numvertices= 0, numneighbors, numinf, vid=1, vertex_i, vertex_n;
+ facetT *facet, **facetp, *neighbor, **neighborp;
+ setT *vertices;
+ vertexT *vertex;
+ boolT isLower;
+ unsigned int numfacets= (unsigned int) qh->num_facets;
+
+ vertices= qh_markvoronoi(qh, facetlist, facets, printall, &isLower, &numcenters);
+ FOREACHvertex_i_(qh, vertices) {
+ if (vertex) {
+ numvertices++;
+ numneighbors = numinf = 0;
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid == 0)
+ numinf= 1;
+ else if (neighbor->visitid < numfacets)
+ numneighbors++;
+ }
+ if (numinf && !numneighbors) {
+ SETelem_(vertices, vertex_i)= NULL;
+ numvertices--;
+ }
+ }
+ }
+ if (format == qh_PRINTgeom)
+ qh_fprintf(qh, fp, 9254, "{appearance {+edge -face} OFF %d %d 1 # Voronoi centers and cells\n",
+ numcenters, numvertices);
+ else
+ qh_fprintf(qh, fp, 9255, "%d\n%d %d 1\n", qh->hull_dim-1, numcenters, qh_setsize(qh, vertices));
+ if (format == qh_PRINTgeom) {
+ for (k=qh->hull_dim-1; k--; )
+ qh_fprintf(qh, fp, 9256, qh_REAL_1, 0.0);
+ qh_fprintf(qh, fp, 9257, " 0 # infinity not used\n");
+ }else {
+ for (k=qh->hull_dim-1; k--; )
+ qh_fprintf(qh, fp, 9258, qh_REAL_1, qh_INFINITE);
+ qh_fprintf(qh, fp, 9259, "\n");
+ }
+ FORALLfacet_(facetlist) {
+ if (facet->visitid && facet->visitid < numfacets) {
+ if (format == qh_PRINTgeom)
+ qh_fprintf(qh, fp, 9260, "# %d f%d\n", vid++, facet->id);
+ qh_printcenter(qh, fp, format, NULL, facet);
+ }
+ }
+ FOREACHfacet_(facets) {
+ if (facet->visitid && facet->visitid < numfacets) {
+ if (format == qh_PRINTgeom)
+ qh_fprintf(qh, fp, 9261, "# %d f%d\n", vid++, facet->id);
+ qh_printcenter(qh, fp, format, NULL, facet);
+ }
+ }
+ FOREACHvertex_i_(qh, vertices) {
+ numneighbors= 0;
+ numinf=0;
+ if (vertex) {
+ if (qh->hull_dim == 3)
+ qh_order_vertexneighbors(qh, vertex);
+ else if (qh->hull_dim >= 4)
+ qsort(SETaddr_(vertex->neighbors, facetT),
+ (size_t)qh_setsize(qh, vertex->neighbors),
+ sizeof(facetT *), qh_compare_facetvisit);
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid == 0)
+ numinf= 1;
+ else if (neighbor->visitid < numfacets)
+ numneighbors++;
+ }
+ }
+ if (format == qh_PRINTgeom) {
+ if (vertex) {
+ qh_fprintf(qh, fp, 9262, "%d", numneighbors);
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid && neighbor->visitid < numfacets)
+ qh_fprintf(qh, fp, 9263, " %d", neighbor->visitid);
+ }
+ qh_fprintf(qh, fp, 9264, " # p%d(v%d)\n", vertex_i, vertex->id);
+ }else
+ qh_fprintf(qh, fp, 9265, " # p%d is coplanar or isolated\n", vertex_i);
+ }else {
+ if (numinf)
+ numneighbors++;
+ qh_fprintf(qh, fp, 9266, "%d", numneighbors);
+ if (vertex) {
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid == 0) {
+ if (numinf) {
+ numinf= 0;
+ qh_fprintf(qh, fp, 9267, " %d", neighbor->visitid);
+ }
+ }else if (neighbor->visitid < numfacets)
+ qh_fprintf(qh, fp, 9268, " %d", neighbor->visitid);
+ }
+ }
+ qh_fprintf(qh, fp, 9269, "\n");
+ }
+ }
+ if (format == qh_PRINTgeom)
+ qh_fprintf(qh, fp, 9270, "}\n");
+ qh_settempfree(qh, &vertices);
+} /* printvoronoi */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printvnorm">-</a>
+
+ qh_printvnorm(qh, fp, vertex, vertexA, centers, unbounded )
+ print one separating plane of the Voronoi diagram for a pair of input sites
+ unbounded==True if centers includes vertex-at-infinity
+
+ assumes:
+ qh_ASvoronoi and qh_vertexneighbors() already set
+
+ note:
+ parameter unbounded is UNUSED by this callback
+
+ see:
+ qh_printvdiagram()
+ qh_eachvoronoi()
+*/
+void qh_printvnorm(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
+ pointT *normal;
+ realT offset;
+ int k;
+ QHULL_UNUSED(unbounded);
+
+ normal= qh_detvnorm(qh, vertex, vertexA, centers, &offset);
+ qh_fprintf(qh, fp, 9271, "%d %d %d ",
+ 2+qh->hull_dim, qh_pointid(qh, vertex->point), qh_pointid(qh, vertexA->point));
+ for (k=0; k< qh->hull_dim-1; k++)
+ qh_fprintf(qh, fp, 9272, qh_REAL_1, normal[k]);
+ qh_fprintf(qh, fp, 9273, qh_REAL_1, offset);
+ qh_fprintf(qh, fp, 9274, "\n");
+} /* printvnorm */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printvridge">-</a>
+
+ qh_printvridge(qh, fp, vertex, vertexA, centers, unbounded )
+ print one ridge of the Voronoi diagram for a pair of input sites
+ unbounded==True if centers includes vertex-at-infinity
+
+ see:
+ qh_printvdiagram()
+
+ notes:
+ the user may use a different function
+ parameter unbounded is UNUSED
+*/
+void qh_printvridge(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded) {
+ facetT *facet, **facetp;
+ QHULL_UNUSED(unbounded);
+
+ qh_fprintf(qh, fp, 9275, "%d %d %d", qh_setsize(qh, centers)+2,
+ qh_pointid(qh, vertex->point), qh_pointid(qh, vertexA->point));
+ FOREACHfacet_(centers)
+ qh_fprintf(qh, fp, 9276, " %d", facet->visitid);
+ qh_fprintf(qh, fp, 9277, "\n");
+} /* printvridge */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="projectdim3">-</a>
+
+ qh_projectdim3(qh, source, destination )
+ project 2-d 3-d or 4-d point to a 3-d point
+ uses qh.DROPdim and qh.hull_dim
+ source and destination may be the same
+
+ notes:
+ allocate 4 elements to destination just in case
+*/
+void qh_projectdim3(qhT *qh, pointT *source, pointT *destination) {
+ int i,k;
+
+ for (k=0, i=0; k < qh->hull_dim; k++) {
+ if (qh->hull_dim == 4) {
+ if (k != qh->DROPdim)
+ destination[i++]= source[k];
+ }else if (k == qh->DROPdim)
+ destination[i++]= 0;
+ else
+ destination[i++]= source[k];
+ }
+ while (i < 3)
+ destination[i++]= 0.0;
+} /* projectdim3 */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="readfeasible">-</a>
+
+ qh_readfeasible(qh, dim, curline )
+ read feasible point from current line and qh.fin
+
+ returns:
+ number of lines read from qh.fin
+ sets qh.feasible_point with malloc'd coordinates
+
+ notes:
+ checks for qh.HALFspace
+ assumes dim > 1
+
+ see:
+ qh_setfeasible
+*/
+int qh_readfeasible(qhT *qh, int dim, const char *curline) {
+ boolT isfirst= True;
+ int linecount= 0, tokcount= 0;
+ const char *s;
+ char *t, firstline[qh_MAXfirst+1];
+ coordT *coords, value;
+
+ if (!qh->HALFspace) {
+ qh_fprintf(qh, qh->ferr, 6070, "qhull input error: feasible point(dim 1 coords) is only valid for halfspace intersection\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (qh->feasible_string)
+ qh_fprintf(qh, qh->ferr, 7057, "qhull input warning: feasible point(dim 1 coords) overrides 'Hn,n,n' feasible point for halfspace intersection\n");
+ if (!(qh->feasible_point= (coordT*)qh_malloc(dim* sizeof(coordT)))) {
+ qh_fprintf(qh, qh->ferr, 6071, "qhull error: insufficient memory for feasible point\n");
+ qh_errexit(qh, qh_ERRmem, NULL, NULL);
+ }
+ coords= qh->feasible_point;
+ while ((s= (isfirst ? curline : fgets(firstline, qh_MAXfirst, qh->fin)))) {
+ if (isfirst)
+ isfirst= False;
+ else
+ linecount++;
+ while (*s) {
+ while (isspace(*s))
+ s++;
+ value= qh_strtod(s, &t);
+ if (s == t)
+ break;
+ s= t;
+ *(coords++)= value;
+ if (++tokcount == dim) {
+ while (isspace(*s))
+ s++;
+ qh_strtod(s, &t);
+ if (s != t) {
+ qh_fprintf(qh, qh->ferr, 6072, "qhull input error: coordinates for feasible point do not finish out the line: %s\n",
+ s);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ return linecount;
+ }
+ }
+ }
+ qh_fprintf(qh, qh->ferr, 6073, "qhull input error: only %d coordinates. Could not read %d-d feasible point.\n",
+ tokcount, dim);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ return 0;
+} /* readfeasible */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="readpoints">-</a>
+
+ qh_readpoints(qh, numpoints, dimension, ismalloc )
+ read points from qh.fin into qh.first_point, qh.num_points
+ qh.fin is lines of coordinates, one per vertex, first line number of points
+ if 'rbox D4',
+ gives message
+ if qh.ATinfinity,
+ adds point-at-infinity for Delaunay triangulations
+
+ returns:
+ number of points, array of point coordinates, dimension, ismalloc True
+ if qh.DELAUNAY & !qh.PROJECTinput, projects points to paraboloid
+ and clears qh.PROJECTdelaunay
+ if qh.HALFspace, reads optional feasible point, reads halfspaces,
+ converts to dual.
+
+ for feasible point in "cdd format" in 3-d:
+ 3 1
+ coordinates
+ comments
+ begin
+ n 4 real/integer
+ ...
+ end
+
+ notes:
+ dimension will change in qh_initqhull_globals if qh.PROJECTinput
+ uses malloc() since qh_mem not initialized
+ FIXUP QH11012: qh_readpoints needs rewriting, too long
+*/
+coordT *qh_readpoints(qhT *qh, int *numpoints, int *dimension, boolT *ismalloc) {
+ coordT *points, *coords, *infinity= NULL;
+ realT paraboloid, maxboloid= -REALmax, value;
+ realT *coordp= NULL, *offsetp= NULL, *normalp= NULL;
+ char *s= 0, *t, firstline[qh_MAXfirst+1];
+ int diminput=0, numinput=0, dimfeasible= 0, newnum, k, tempi;
+ int firsttext=0, firstshort=0, firstlong=0, firstpoint=0;
+ int tokcount= 0, linecount=0, maxcount, coordcount=0;
+ boolT islong, isfirst= True, wasbegin= False;
+ boolT isdelaunay= qh->DELAUNAY && !qh->PROJECTinput;
+
+ if (qh->CDDinput) {
+ while ((s= fgets(firstline, qh_MAXfirst, qh->fin))) {
+ linecount++;
+ if (qh->HALFspace && linecount == 1 && isdigit(*s)) {
+ dimfeasible= qh_strtol(s, &s);
+ while (isspace(*s))
+ s++;
+ if (qh_strtol(s, &s) == 1)
+ linecount += qh_readfeasible(qh, dimfeasible, s);
+ else
+ dimfeasible= 0;
+ }else if (!memcmp(firstline, "begin", (size_t)5) || !memcmp(firstline, "BEGIN", (size_t)5))
+ break;
+ else if (!*qh->rbox_command)
+ strncat(qh->rbox_command, s, sizeof(qh->rbox_command)-1);
+ }
+ if (!s) {
+ qh_fprintf(qh, qh->ferr, 6074, "qhull input error: missing \"begin\" for cdd-formated input\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ }
+ while (!numinput && (s= fgets(firstline, qh_MAXfirst, qh->fin))) {
+ linecount++;
+ if (!memcmp(s, "begin", (size_t)5) || !memcmp(s, "BEGIN", (size_t)5))
+ wasbegin= True;
+ while (*s) {
+ while (isspace(*s))
+ s++;
+ if (!*s)
+ break;
+ if (!isdigit(*s)) {
+ if (!*qh->rbox_command) {
+ strncat(qh->rbox_command, s, sizeof(qh->rbox_command)-1);
+ firsttext= linecount;
+ }
+ break;
+ }
+ if (!diminput)
+ diminput= qh_strtol(s, &s);
+ else {
+ numinput= qh_strtol(s, &s);
+ if (numinput == 1 && diminput >= 2 && qh->HALFspace && !qh->CDDinput) {
+ linecount += qh_readfeasible(qh, diminput, s); /* checks if ok */
+ dimfeasible= diminput;
+ diminput= numinput= 0;
+ }else
+ break;
+ }
+ }
+ }
+ if (!s) {
+ qh_fprintf(qh, qh->ferr, 6075, "qhull input error: short input file. Did not find dimension and number of points\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (diminput > numinput) {
+ tempi= diminput; /* exchange dim and n, e.g., for cdd input format */
+ diminput= numinput;
+ numinput= tempi;
+ }
+ if (diminput < 2) {
+ qh_fprintf(qh, qh->ferr, 6220,"qhull input error: dimension %d(first number) should be at least 2\n",
+ diminput);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (isdelaunay) {
+ qh->PROJECTdelaunay= False;
+ if (qh->CDDinput)
+ *dimension= diminput;
+ else
+ *dimension= diminput+1;
+ *numpoints= numinput;
+ if (qh->ATinfinity)
+ (*numpoints)++;
+ }else if (qh->HALFspace) {
+ *dimension= diminput - 1;
+ *numpoints= numinput;
+ if (diminput < 3) {
+ qh_fprintf(qh, qh->ferr, 6221,"qhull input error: dimension %d(first number, includes offset) should be at least 3 for halfspaces\n",
+ diminput);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (dimfeasible) {
+ if (dimfeasible != *dimension) {
+ qh_fprintf(qh, qh->ferr, 6222,"qhull input error: dimension %d of feasible point is not one less than dimension %d for halfspaces\n",
+ dimfeasible, diminput);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ }else
+ qh_setfeasible(qh, *dimension);
+ }else {
+ if (qh->CDDinput)
+ *dimension= diminput-1;
+ else
+ *dimension= diminput;
+ *numpoints= numinput;
+ }
+ qh->normal_size= *dimension * sizeof(coordT); /* for tracing with qh_printpoint */
+ if (qh->HALFspace) {
+ qh->half_space= coordp= (coordT*)qh_malloc(qh->normal_size + sizeof(coordT));
+ if (qh->CDDinput) {
+ offsetp= qh->half_space;
+ normalp= offsetp + 1;
+ }else {
+ normalp= qh->half_space;
+ offsetp= normalp + *dimension;
+ }
+ }
+ qh->maxline= diminput * (qh_REALdigits + 5);
+ maximize_(qh->maxline, 500);
+ qh->line= (char*)qh_malloc((qh->maxline+1) * sizeof(char));
+ *ismalloc= True; /* use malloc since memory not setup */
+ coords= points= qh->temp_malloc= /* numinput and diminput >=2 by QH6220 */
+ (coordT*)qh_malloc((*numpoints)*(*dimension)*sizeof(coordT));
+ if (!coords || !qh->line || (qh->HALFspace && !qh->half_space)) {
+ qh_fprintf(qh, qh->ferr, 6076, "qhull error: insufficient memory to read %d points\n",
+ numinput);
+ qh_errexit(qh, qh_ERRmem, NULL, NULL);
+ }
+ if (isdelaunay && qh->ATinfinity) {
+ infinity= points + numinput * (*dimension);
+ for (k= (*dimension) - 1; k--; )
+ infinity[k]= 0.0;
+ }
+ maxcount= numinput * diminput;
+ paraboloid= 0.0;
+ while ((s= (isfirst ? s : fgets(qh->line, qh->maxline, qh->fin)))) {
+ if (!isfirst) {
+ linecount++;
+ if (*s == 'e' || *s == 'E') {
+ if (!memcmp(s, "end", (size_t)3) || !memcmp(s, "END", (size_t)3)) {
+ if (qh->CDDinput )
+ break;
+ else if (wasbegin)
+ qh_fprintf(qh, qh->ferr, 7058, "qhull input warning: the input appears to be in cdd format. If so, use 'Fd'\n");
+ }
+ }
+ }
+ islong= False;
+ while (*s) {
+ while (isspace(*s))
+ s++;
+ value= qh_strtod(s, &t);
+ if (s == t) {
+ if (!*qh->rbox_command)
+ strncat(qh->rbox_command, s, sizeof(qh->rbox_command)-1);
+ if (*s && !firsttext)
+ firsttext= linecount;
+ if (!islong && !firstshort && coordcount)
+ firstshort= linecount;
+ break;
+ }
+ if (!firstpoint)
+ firstpoint= linecount;
+ s= t;
+ if (++tokcount > maxcount)
+ continue;
+ if (qh->HALFspace) {
+ if (qh->CDDinput)
+ *(coordp++)= -value; /* both coefficients and offset */
+ else
+ *(coordp++)= value;
+ }else {
+ *(coords++)= value;
+ if (qh->CDDinput && !coordcount) {
+ if (value != 1.0) {
+ qh_fprintf(qh, qh->ferr, 6077, "qhull input error: for cdd format, point at line %d does not start with '1'\n",
+ linecount);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ coords--;
+ }else if (isdelaunay) {
+ paraboloid += value * value;
+ if (qh->ATinfinity) {
+ if (qh->CDDinput)
+ infinity[coordcount-1] += value;
+ else
+ infinity[coordcount] += value;
+ }
+ }
+ }
+ if (++coordcount == diminput) {
+ coordcount= 0;
+ if (isdelaunay) {
+ *(coords++)= paraboloid;
+ maximize_(maxboloid, paraboloid);
+ paraboloid= 0.0;
+ }else if (qh->HALFspace) {
+ if (!qh_sethalfspace(qh, *dimension, coords, &coords, normalp, offsetp, qh->feasible_point)) {
+ qh_fprintf(qh, qh->ferr, 8048, "The halfspace was on line %d\n", linecount);
+ if (wasbegin)
+ qh_fprintf(qh, qh->ferr, 8049, "The input appears to be in cdd format. If so, you should use option 'Fd'\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ coordp= qh->half_space;
+ }
+ while (isspace(*s))
+ s++;
+ if (*s) {
+ islong= True;
+ if (!firstlong)
+ firstlong= linecount;
+ }
+ }
+ }
+ if (!islong && !firstshort && coordcount)
+ firstshort= linecount;
+ if (!isfirst && s - qh->line >= qh->maxline) {
+ qh_fprintf(qh, qh->ferr, 6078, "qhull input error: line %d contained more than %d characters\n",
+ linecount, (int) (s - qh->line)); /* WARN64 */
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ isfirst= False;
+ }
+ if (tokcount != maxcount) {
+ newnum= fmin_(numinput, tokcount/diminput);
+ qh_fprintf(qh, qh->ferr, 7073,"\
+qhull warning: instead of %d %d-dimensional points, input contains\n\
+%d points and %d extra coordinates. Line %d is the first\npoint",
+ numinput, diminput, tokcount/diminput, tokcount % diminput, firstpoint);
+ if (firsttext)
+ qh_fprintf(qh, qh->ferr, 8051, ", line %d is the first comment", firsttext);
+ if (firstshort)
+ qh_fprintf(qh, qh->ferr, 8052, ", line %d is the first short\nline", firstshort);
+ if (firstlong)
+ qh_fprintf(qh, qh->ferr, 8053, ", line %d is the first long line", firstlong);
+ qh_fprintf(qh, qh->ferr, 8054, ". Continue with %d points.\n", newnum);
+ numinput= newnum;
+ if (isdelaunay && qh->ATinfinity) {
+ for (k= tokcount % diminput; k--; )
+ infinity[k] -= *(--coords);
+ *numpoints= newnum+1;
+ }else {
+ coords -= tokcount % diminput;
+ *numpoints= newnum;
+ }
+ }
+ if (isdelaunay && qh->ATinfinity) {
+ for (k= (*dimension) -1; k--; )
+ infinity[k] /= numinput;
+ if (coords == infinity)
+ coords += (*dimension) -1;
+ else {
+ for (k=0; k < (*dimension) -1; k++)
+ *(coords++)= infinity[k];
+ }
+ *(coords++)= maxboloid * 1.1;
+ }
+ if (qh->rbox_command[0]) {
+ qh->rbox_command[strlen(qh->rbox_command)-1]= '\0';
+ if (!strcmp(qh->rbox_command, "./rbox D4"))
+ qh_fprintf(qh, qh->ferr, 8055, "\n\
+This is the qhull test case. If any errors or core dumps occur,\n\
+recompile qhull with 'make new'. If errors still occur, there is\n\
+an incompatibility. You should try a different compiler. You can also\n\
+change the choices in user.h. If you discover the source of the problem,\n\
+please send mail to qhull_bug@qhull.org.\n\
+\n\
+Type 'qhull' for a short list of options.\n");
+ }
+ qh_free(qh->line);
+ qh->line= NULL;
+ if (qh->half_space) {
+ qh_free(qh->half_space);
+ qh->half_space= NULL;
+ }
+ qh->temp_malloc= NULL;
+ trace1((qh, qh->ferr, 1008,"qh_readpoints: read in %d %d-dimensional points\n",
+ numinput, diminput));
+ return(points);
+} /* readpoints */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="setfeasible">-</a>
+
+ qh_setfeasible(qh, dim )
+ set qh.feasible_point from qh.feasible_string in "n,n,n" or "n n n" format
+
+ notes:
+ "n,n,n" already checked by qh_initflags()
+ see qh_readfeasible()
+ called only once from qh_new_qhull, otherwise leaks memory
+*/
+void qh_setfeasible(qhT *qh, int dim) {
+ int tokcount= 0;
+ char *s;
+ coordT *coords, value;
+
+ if (!(s= qh->feasible_string)) {
+ qh_fprintf(qh, qh->ferr, 6223, "\
+qhull input error: halfspace intersection needs a feasible point.\n\
+Either prepend the input with 1 point or use 'Hn,n,n'. See manual.\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (!(qh->feasible_point= (pointT*)qh_malloc(dim * sizeof(coordT)))) {
+ qh_fprintf(qh, qh->ferr, 6079, "qhull error: insufficient memory for 'Hn,n,n'\n");
+ qh_errexit(qh, qh_ERRmem, NULL, NULL);
+ }
+ coords= qh->feasible_point;
+ while (*s) {
+ value= qh_strtod(s, &s);
+ if (++tokcount > dim) {
+ qh_fprintf(qh, qh->ferr, 7059, "qhull input warning: more coordinates for 'H%s' than dimension %d\n",
+ qh->feasible_string, dim);
+ break;
+ }
+ *(coords++)= value;
+ if (*s)
+ s++;
+ }
+ while (++tokcount <= dim)
+ *(coords++)= 0.0;
+} /* setfeasible */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="skipfacet">-</a>
+
+ qh_skipfacet(qh, facet )
+ returns 'True' if this facet is not to be printed
+
+ notes:
+ based on the user provided slice thresholds and 'good' specifications
+*/
+boolT qh_skipfacet(qhT *qh, facetT *facet) {
+ facetT *neighbor, **neighborp;
+
+ if (qh->PRINTneighbors) {
+ if (facet->good)
+ return !qh->PRINTgood;
+ FOREACHneighbor_(facet) {
+ if (neighbor->good)
+ return False;
+ }
+ return True;
+ }else if (qh->PRINTgood)
+ return !facet->good;
+ else if (!facet->normal)
+ return True;
+ return(!qh_inthresholds(qh, facet->normal, NULL));
+} /* skipfacet */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="skipfilename">-</a>
+
+ qh_skipfilename(qh, string )
+ returns pointer to character after filename
+
+ notes:
+ skips leading spaces
+ ends with spacing or eol
+ if starts with ' or " ends with the same, skipping \' or \"
+ For qhull, qh_argv_to_command() only uses double quotes
+*/
+char *qh_skipfilename(qhT *qh, char *filename) {
+ char *s= filename; /* non-const due to return */
+ char c;
+
+ while (*s && isspace(*s))
+ s++;
+ c= *s++;
+ if (c == '\0') {
+ qh_fprintf(qh, qh->ferr, 6204, "qhull input error: filename expected, none found.\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (c == '\'' || c == '"') {
+ while (*s !=c || s[-1] == '\\') {
+ if (!*s) {
+ qh_fprintf(qh, qh->ferr, 6203, "qhull input error: missing quote after filename -- %s\n", filename);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ s++;
+ }
+ s++;
+ }
+ else while (*s && !isspace(*s))
+ s++;
+ return s;
+} /* skipfilename */
+
diff --git a/xs/src/qhull/src/libqhull_r/io_r.h b/xs/src/qhull/src/libqhull_r/io_r.h
new file mode 100644
index 000000000..12e05ae7a
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/io_r.h
@@ -0,0 +1,167 @@
+/*<html><pre> -<a href="qh-io_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ io_r.h
+ declarations of Input/Output functions
+
+ see README, libqhull_r.h and io_r.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/io_r.h#3 $$Change: 2079 $
+ $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+*/
+
+#ifndef qhDEFio
+#define qhDEFio 1
+
+#include "libqhull_r.h"
+
+/*============ constants and flags ==================*/
+
+/*-<a href="qh-io_r.htm#TOC"
+ >--------------------------------</a><a name="qh_MAXfirst">-</a>
+
+ qh_MAXfirst
+ maximum length of first two lines of stdin
+*/
+#define qh_MAXfirst 200
+
+/*-<a href="qh-io_r.htm#TOC"
+ >--------------------------------</a><a name="qh_MINradius">-</a>
+
+ qh_MINradius
+ min radius for Gp and Gv, fraction of maxcoord
+*/
+#define qh_MINradius 0.02
+
+/*-<a href="qh-io_r.htm#TOC"
+ >--------------------------------</a><a name="qh_GEOMepsilon">-</a>
+
+ qh_GEOMepsilon
+ adjust outer planes for 'lines closer' and geomview roundoff.
+ This prevents bleed through.
+*/
+#define qh_GEOMepsilon 2e-3
+
+/*-<a href="qh-io_r.htm#TOC"
+ >--------------------------------</a><a name="qh_WHITESPACE">-</a>
+
+ qh_WHITESPACE
+ possible values of white space
+*/
+#define qh_WHITESPACE " \n\t\v\r\f"
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >--------------------------------</a><a name="RIDGE">-</a>
+
+ qh_RIDGE
+ to select which ridges to print in qh_eachvoronoi
+*/
+typedef enum
+{
+ qh_RIDGEall = 0, qh_RIDGEinner, qh_RIDGEouter
+}
+qh_RIDGE;
+
+/*-<a href="qh-io_r.htm#TOC"
+ >--------------------------------</a><a name="printvridgeT">-</a>
+
+ printvridgeT
+ prints results of qh_printvdiagram
+
+ see:
+ <a href="io_r.c#printvridge">qh_printvridge</a> for an example
+*/
+typedef void (*printvridgeT)(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
+
+/*============== -prototypes in alphabetical order =========*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void qh_dfacet(qhT *qh, unsigned id);
+void qh_dvertex(qhT *qh, unsigned id);
+int qh_compare_facetarea(const void *p1, const void *p2);
+int qh_compare_facetmerge(const void *p1, const void *p2);
+int qh_compare_facetvisit(const void *p1, const void *p2);
+/* int qh_compare_vertexpoint(const void *p1, const void *p2); Not useable since it depends on qh */
+void qh_copyfilename(qhT *qh, char *filename, int size, const char* source, int length);
+void qh_countfacets(qhT *qh, facetT *facetlist, setT *facets, boolT printall,
+ int *numfacetsp, int *numsimplicialp, int *totneighborsp,
+ int *numridgesp, int *numcoplanarsp, int *numnumtricoplanarsp);
+pointT *qh_detvnorm(qhT *qh, vertexT *vertex, vertexT *vertexA, setT *centers, realT *offsetp);
+setT *qh_detvridge(qhT *qh, vertexT *vertex);
+setT *qh_detvridge3(qhT *qh, vertexT *atvertex, vertexT *vertex);
+int qh_eachvoronoi(qhT *qh, FILE *fp, printvridgeT printvridge, vertexT *atvertex, boolT visitall, qh_RIDGE innerouter, boolT inorder);
+int qh_eachvoronoi_all(qhT *qh, FILE *fp, printvridgeT printvridge, boolT isUpper, qh_RIDGE innerouter, boolT inorder);
+void qh_facet2point(qhT *qh, facetT *facet, pointT **point0, pointT **point1, realT *mindist);
+setT *qh_facetvertices(qhT *qh, facetT *facetlist, setT *facets, boolT allfacets);
+void qh_geomplanes(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane);
+void qh_markkeep(qhT *qh, facetT *facetlist);
+setT *qh_markvoronoi(qhT *qh, facetT *facetlist, setT *facets, boolT printall, boolT *isLowerp, int *numcentersp);
+void qh_order_vertexneighbors(qhT *qh, vertexT *vertex);
+void qh_prepare_output(qhT *qh);
+void qh_printafacet(qhT *qh, FILE *fp, qh_PRINT format, facetT *facet, boolT printall);
+void qh_printbegin(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
+void qh_printcenter(qhT *qh, FILE *fp, qh_PRINT format, const char *string, facetT *facet);
+void qh_printcentrum(qhT *qh, FILE *fp, facetT *facet, realT radius);
+void qh_printend(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
+void qh_printend4geom(qhT *qh, FILE *fp, facetT *facet, int *num, boolT printall);
+void qh_printextremes(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
+void qh_printextremes_2d(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
+void qh_printextremes_d(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
+void qh_printfacet(qhT *qh, FILE *fp, facetT *facet);
+void qh_printfacet2math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
+void qh_printfacet2geom(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
+void qh_printfacet2geom_points(qhT *qh, FILE *fp, pointT *point1, pointT *point2,
+ facetT *facet, realT offset, realT color[3]);
+void qh_printfacet3math(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format, int notfirst);
+void qh_printfacet3geom_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
+void qh_printfacet3geom_points(qhT *qh, FILE *fp, setT *points, facetT *facet, realT offset, realT color[3]);
+void qh_printfacet3geom_simplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
+void qh_printfacet3vertex(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format);
+void qh_printfacet4geom_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
+void qh_printfacet4geom_simplicial(qhT *qh, FILE *fp, facetT *facet, realT color[3]);
+void qh_printfacetNvertex_nonsimplicial(qhT *qh, FILE *fp, facetT *facet, int id, qh_PRINT format);
+void qh_printfacetNvertex_simplicial(qhT *qh, FILE *fp, facetT *facet, qh_PRINT format);
+void qh_printfacetheader(qhT *qh, FILE *fp, facetT *facet);
+void qh_printfacetridges(qhT *qh, FILE *fp, facetT *facet);
+void qh_printfacets(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
+void qh_printhyperplaneintersection(qhT *qh, FILE *fp, facetT *facet1, facetT *facet2,
+ setT *vertices, realT color[3]);
+void qh_printneighborhood(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall);
+void qh_printline3geom(qhT *qh, FILE *fp, pointT *pointA, pointT *pointB, realT color[3]);
+void qh_printpoint(qhT *qh, FILE *fp, const char *string, pointT *point);
+void qh_printpointid(qhT *qh, FILE *fp, const char *string, int dim, pointT *point, int id);
+void qh_printpoint3(qhT *qh, FILE *fp, pointT *point);
+void qh_printpoints_out(qhT *qh, FILE *fp, facetT *facetlist, setT *facets, boolT printall);
+void qh_printpointvect(qhT *qh, FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius, realT color[3]);
+void qh_printpointvect2(qhT *qh, FILE *fp, pointT *point, coordT *normal, pointT *center, realT radius);
+void qh_printridge(qhT *qh, FILE *fp, ridgeT *ridge);
+void qh_printspheres(qhT *qh, FILE *fp, setT *vertices, realT radius);
+void qh_printvdiagram(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
+int qh_printvdiagram2(qhT *qh, FILE *fp, printvridgeT printvridge, setT *vertices, qh_RIDGE innerouter, boolT inorder);
+void qh_printvertex(qhT *qh, FILE *fp, vertexT *vertex);
+void qh_printvertexlist(qhT *qh, FILE *fp, const char* string, facetT *facetlist,
+ setT *facets, boolT printall);
+void qh_printvertices(qhT *qh, FILE *fp, const char* string, setT *vertices);
+void qh_printvneighbors(qhT *qh, FILE *fp, facetT* facetlist, setT *facets, boolT printall);
+void qh_printvoronoi(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetlist, setT *facets, boolT printall);
+void qh_printvnorm(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
+void qh_printvridge(qhT *qh, FILE *fp, vertexT *vertex, vertexT *vertexA, setT *centers, boolT unbounded);
+void qh_produce_output(qhT *qh);
+void qh_produce_output2(qhT *qh);
+void qh_projectdim3(qhT *qh, pointT *source, pointT *destination);
+int qh_readfeasible(qhT *qh, int dim, const char *curline);
+coordT *qh_readpoints(qhT *qh, int *numpoints, int *dimension, boolT *ismalloc);
+void qh_setfeasible(qhT *qh, int dim);
+boolT qh_skipfacet(qhT *qh, facetT *facet);
+char *qh_skipfilename(qhT *qh, char *filename);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* qhDEFio */
diff --git a/xs/src/qhull/src/libqhull_r/libqhull_r.c b/xs/src/qhull/src/libqhull_r/libqhull_r.c
new file mode 100644
index 000000000..0fe0c980d
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/libqhull_r.c
@@ -0,0 +1,1403 @@
+/*<html><pre> -<a href="qh-qhull_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ libqhull_r.c
+ Quickhull algorithm for convex hulls
+
+ qhull() and top-level routines
+
+ see qh-qhull_r.htm, libqhull.h, unix_r.c
+
+ see qhull_ra.h for internal functions
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/libqhull_r.c#2 $$Change: 2047 $
+ $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $
+*/
+
+#include "qhull_ra.h"
+
+/*============= functions in alphabetic order after qhull() =======*/
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="qhull">-</a>
+
+ qh_qhull(qh)
+ compute DIM3 convex hull of qh.num_points starting at qh.first_point
+ qh->contains all global options and variables
+
+ returns:
+ returns polyhedron
+ qh.facet_list, qh.num_facets, qh.vertex_list, qh.num_vertices,
+
+ returns global variables
+ qh.hulltime, qh.max_outside, qh.interior_point, qh.max_vertex, qh.min_vertex
+
+ returns precision constants
+ qh.ANGLEround, centrum_radius, cos_max, DISTround, MAXabs_coord, ONEmerge
+
+ notes:
+ unless needed for output
+ qh.max_vertex and qh.min_vertex are max/min due to merges
+
+ see:
+ to add individual points to either qh.num_points
+ use qh_addpoint()
+
+ if qh.GETarea
+ qh_produceoutput() returns qh.totarea and qh.totvol via qh_getarea()
+
+ design:
+ record starting time
+ initialize hull and partition points
+ build convex hull
+ unless early termination
+ update facet->maxoutside for vertices, coplanar, and near-inside points
+ error if temporary sets exist
+ record end time
+*/
+
+void qh_qhull(qhT *qh) {
+ int numoutside;
+
+ qh->hulltime= qh_CPUclock;
+ if (qh->RERUN || qh->JOGGLEmax < REALmax/2)
+ qh_build_withrestart(qh);
+ else {
+ qh_initbuild(qh);
+ qh_buildhull(qh);
+ }
+ if (!qh->STOPpoint && !qh->STOPcone) {
+ if (qh->ZEROall_ok && !qh->TESTvneighbors && qh->MERGEexact)
+ qh_checkzero(qh, qh_ALL);
+ if (qh->ZEROall_ok && !qh->TESTvneighbors && !qh->WAScoplanar) {
+ trace2((qh, qh->ferr, 2055, "qh_qhull: all facets are clearly convex and no coplanar points. Post-merging and check of maxout not needed.\n"));
+ qh->DOcheckmax= False;
+ }else {
+ if (qh->MERGEexact || (qh->hull_dim > qh_DIMreduceBuild && qh->PREmerge))
+ qh_postmerge(qh, "First post-merge", qh->premerge_centrum, qh->premerge_cos,
+ (qh->POSTmerge ? False : qh->TESTvneighbors));
+ else if (!qh->POSTmerge && qh->TESTvneighbors)
+ qh_postmerge(qh, "For testing vertex neighbors", qh->premerge_centrum,
+ qh->premerge_cos, True);
+ if (qh->POSTmerge)
+ qh_postmerge(qh, "For post-merging", qh->postmerge_centrum,
+ qh->postmerge_cos, qh->TESTvneighbors);
+ if (qh->visible_list == qh->facet_list) { /* i.e., merging done */
+ qh->findbestnew= True;
+ qh_partitionvisible(qh /*qh.visible_list*/, !qh_ALL, &numoutside);
+ qh->findbestnew= False;
+ qh_deletevisible(qh /*qh.visible_list*/);
+ qh_resetlists(qh, False, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
+ }
+ }
+ if (qh->DOcheckmax){
+ if (qh->REPORTfreq) {
+ qh_buildtracing(qh, NULL, NULL);
+ qh_fprintf(qh, qh->ferr, 8115, "\nTesting all coplanar points.\n");
+ }
+ qh_check_maxout(qh);
+ }
+ if (qh->KEEPnearinside && !qh->maxoutdone)
+ qh_nearcoplanar(qh);
+ }
+ if (qh_setsize(qh, qh->qhmem.tempstack) != 0) {
+ qh_fprintf(qh, qh->ferr, 6164, "qhull internal error (qh_qhull): temporary sets not empty(%d)\n",
+ qh_setsize(qh, qh->qhmem.tempstack));
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ qh->hulltime= qh_CPUclock - qh->hulltime;
+ qh->QHULLfinished= True;
+ trace1((qh, qh->ferr, 1036, "Qhull: algorithm completed\n"));
+} /* qhull */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="addpoint">-</a>
+
+ qh_addpoint(qh, furthest, facet, checkdist )
+ add point (usually furthest point) above facet to hull
+ if checkdist,
+ check that point is above facet.
+ if point is not outside of the hull, uses qh_partitioncoplanar()
+ assumes that facet is defined by qh_findbestfacet()
+ else if facet specified,
+ assumes that point is above facet (major damage if below)
+ for Delaunay triangulations,
+ Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
+ Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates.
+
+ returns:
+ returns False if user requested an early termination
+ qh.visible_list, newfacet_list, delvertex_list, NEWfacets may be defined
+ updates qh.facet_list, qh.num_facets, qh.vertex_list, qh.num_vertices
+ clear qh.maxoutdone (will need to call qh_check_maxout() for facet->maxoutside)
+ if unknown point, adds a pointer to qh.other_points
+ do not deallocate the point's coordinates
+
+ notes:
+ assumes point is near its best facet and not at a local minimum of a lens
+ distributions. Use qh_findbestfacet to avoid this case.
+ uses qh.visible_list, qh.newfacet_list, qh.delvertex_list, qh.NEWfacets
+
+ see also:
+ qh_triangulate() -- triangulate non-simplicial facets
+
+ design:
+ add point to other_points if needed
+ if checkdist
+ if point not above facet
+ partition coplanar point
+ exit
+ exit if pre STOPpoint requested
+ find horizon and visible facets for point
+ make new facets for point to horizon
+ make hyperplanes for point
+ compute balance statistics
+ match neighboring new facets
+ update vertex neighbors and delete interior vertices
+ exit if STOPcone requested
+ merge non-convex new facets
+ if merge found, many merges, or 'Qf'
+ use qh_findbestnew() instead of qh_findbest()
+ partition outside points from visible facets
+ delete visible facets
+ check polyhedron if requested
+ exit if post STOPpoint requested
+ reset working lists of facets and vertices
+*/
+boolT qh_addpoint(qhT *qh, pointT *furthest, facetT *facet, boolT checkdist) {
+ int goodvisible, goodhorizon;
+ vertexT *vertex;
+ facetT *newfacet;
+ realT dist, newbalance, pbalance;
+ boolT isoutside= False;
+ int numpart, numpoints, numnew, firstnew;
+
+ qh->maxoutdone= False;
+ if (qh_pointid(qh, furthest) == qh_IDunknown)
+ qh_setappend(qh, &qh->other_points, furthest);
+ if (!facet) {
+ qh_fprintf(qh, qh->ferr, 6213, "qhull internal error (qh_addpoint): NULL facet. Need to call qh_findbestfacet first\n");
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ if (checkdist) {
+ facet= qh_findbest(qh, furthest, facet, !qh_ALL, !qh_ISnewfacets, !qh_NOupper,
+ &dist, &isoutside, &numpart);
+ zzadd_(Zpartition, numpart);
+ if (!isoutside) {
+ zinc_(Znotmax); /* last point of outsideset is no longer furthest. */
+ facet->notfurthest= True;
+ qh_partitioncoplanar(qh, furthest, facet, &dist);
+ return True;
+ }
+ }
+ qh_buildtracing(qh, furthest, facet);
+ if (qh->STOPpoint < 0 && qh->furthest_id == -qh->STOPpoint-1) {
+ facet->notfurthest= True;
+ return False;
+ }
+ qh_findhorizon(qh, furthest, facet, &goodvisible, &goodhorizon);
+ if (qh->ONLYgood && !(goodvisible+goodhorizon) && !qh->GOODclosest) {
+ zinc_(Znotgood);
+ facet->notfurthest= True;
+ /* last point of outsideset is no longer furthest. This is ok
+ since all points of the outside are likely to be bad */
+ qh_resetlists(qh, False, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
+ return True;
+ }
+ zzinc_(Zprocessed);
+ firstnew= qh->facet_id;
+ vertex= qh_makenewfacets(qh, furthest /*visible_list, attaches if !ONLYgood */);
+ qh_makenewplanes(qh /* newfacet_list */);
+ numnew= qh->facet_id - firstnew;
+ newbalance= numnew - (realT) (qh->num_facets-qh->num_visible)
+ * qh->hull_dim/qh->num_vertices;
+ wadd_(Wnewbalance, newbalance);
+ wadd_(Wnewbalance2, newbalance * newbalance);
+ if (qh->ONLYgood
+ && !qh_findgood(qh, qh->newfacet_list, goodhorizon) && !qh->GOODclosest) {
+ FORALLnew_facets
+ qh_delfacet(qh, newfacet);
+ qh_delvertex(qh, vertex);
+ qh_resetlists(qh, True, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
+ zinc_(Znotgoodnew);
+ facet->notfurthest= True;
+ return True;
+ }
+ if (qh->ONLYgood)
+ qh_attachnewfacets(qh /*visible_list*/);
+ qh_matchnewfacets(qh);
+ qh_updatevertices(qh);
+ if (qh->STOPcone && qh->furthest_id == qh->STOPcone-1) {
+ facet->notfurthest= True;
+ return False; /* visible_list etc. still defined */
+ }
+ qh->findbestnew= False;
+ if (qh->PREmerge || qh->MERGEexact) {
+ qh_premerge(qh, vertex, qh->premerge_centrum, qh->premerge_cos);
+ if (qh_USEfindbestnew)
+ qh->findbestnew= True;
+ else {
+ FORALLnew_facets {
+ if (!newfacet->simplicial) {
+ qh->findbestnew= True; /* use qh_findbestnew instead of qh_findbest*/
+ break;
+ }
+ }
+ }
+ }else if (qh->BESToutside)
+ qh->findbestnew= True;
+ qh_partitionvisible(qh /*qh.visible_list*/, !qh_ALL, &numpoints);
+ qh->findbestnew= False;
+ qh->findbest_notsharp= False;
+ zinc_(Zpbalance);
+ pbalance= numpoints - (realT) qh->hull_dim /* assumes all points extreme */
+ * (qh->num_points - qh->num_vertices)/qh->num_vertices;
+ wadd_(Wpbalance, pbalance);
+ wadd_(Wpbalance2, pbalance * pbalance);
+ qh_deletevisible(qh /*qh.visible_list*/);
+ zmax_(Zmaxvertex, qh->num_vertices);
+ qh->NEWfacets= False;
+ if (qh->IStracing >= 4) {
+ if (qh->num_facets < 2000)
+ qh_printlists(qh);
+ qh_printfacetlist(qh, qh->newfacet_list, NULL, True);
+ qh_checkpolygon(qh, qh->facet_list);
+ }else if (qh->CHECKfrequently) {
+ if (qh->num_facets < 50)
+ qh_checkpolygon(qh, qh->facet_list);
+ else
+ qh_checkpolygon(qh, qh->newfacet_list);
+ }
+ if (qh->STOPpoint > 0 && qh->furthest_id == qh->STOPpoint-1)
+ return False;
+ qh_resetlists(qh, True, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
+ /* qh_triangulate(qh); to test qh.TRInormals */
+ trace2((qh, qh->ferr, 2056, "qh_addpoint: added p%d new facets %d new balance %2.2g point balance %2.2g\n",
+ qh_pointid(qh, furthest), numnew, newbalance, pbalance));
+ return True;
+} /* addpoint */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="build_withrestart">-</a>
+
+ qh_build_withrestart(qh)
+ allow restarts due to qh.JOGGLEmax while calling qh_buildhull()
+ qh_errexit always undoes qh_build_withrestart()
+ qh.FIRSTpoint/qh.NUMpoints is point array
+ it may be moved by qh_joggleinput(qh)
+*/
+void qh_build_withrestart(qhT *qh) {
+ int restart;
+
+ qh->ALLOWrestart= True;
+ while (True) {
+ restart= setjmp(qh->restartexit); /* simple statement for CRAY J916 */
+ if (restart) { /* only from qh_precision() */
+ zzinc_(Zretry);
+ wmax_(Wretrymax, qh->JOGGLEmax);
+ /* QH7078 warns about using 'TCn' with 'QJn' */
+ qh->STOPcone= qh_IDunknown; /* if break from joggle, prevents normal output */
+ }
+ if (!qh->RERUN && qh->JOGGLEmax < REALmax/2) {
+ if (qh->build_cnt > qh_JOGGLEmaxretry) {
+ qh_fprintf(qh, qh->ferr, 6229, "qhull precision error: %d attempts to construct a convex hull\n\
+ with joggled input. Increase joggle above 'QJ%2.2g'\n\
+ or modify qh_JOGGLE... parameters in user.h\n",
+ qh->build_cnt, qh->JOGGLEmax);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ if (qh->build_cnt && !restart)
+ break;
+ }else if (qh->build_cnt && qh->build_cnt >= qh->RERUN)
+ break;
+ qh->STOPcone= 0;
+ qh_freebuild(qh, True); /* first call is a nop */
+ qh->build_cnt++;
+ if (!qh->qhull_optionsiz)
+ qh->qhull_optionsiz= (int)strlen(qh->qhull_options); /* WARN64 */
+ else {
+ qh->qhull_options [qh->qhull_optionsiz]= '\0';
+ qh->qhull_optionlen= qh_OPTIONline; /* starts a new line */
+ }
+ qh_option(qh, "_run", &qh->build_cnt, NULL);
+ if (qh->build_cnt == qh->RERUN) {
+ qh->IStracing= qh->TRACElastrun; /* duplicated from qh_initqhull_globals */
+ if (qh->TRACEpoint != qh_IDunknown || qh->TRACEdist < REALmax/2 || qh->TRACEmerge) {
+ qh->TRACElevel= (qh->IStracing? qh->IStracing : 3);
+ qh->IStracing= 0;
+ }
+ qh->qhmem.IStracing= qh->IStracing;
+ }
+ if (qh->JOGGLEmax < REALmax/2)
+ qh_joggleinput(qh);
+ qh_initbuild(qh);
+ qh_buildhull(qh);
+ if (qh->JOGGLEmax < REALmax/2 && !qh->MERGING)
+ qh_checkconvex(qh, qh->facet_list, qh_ALGORITHMfault);
+ }
+ qh->ALLOWrestart= False;
+} /* qh_build_withrestart */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="buildhull">-</a>
+
+ qh_buildhull(qh)
+ construct a convex hull by adding outside points one at a time
+
+ returns:
+
+ notes:
+ may be called multiple times
+ checks facet and vertex lists for incorrect flags
+ to recover from STOPcone, call qh_deletevisible and qh_resetlists
+
+ design:
+ check visible facet and newfacet flags
+ check newlist vertex flags and qh.STOPcone/STOPpoint
+ for each facet with a furthest outside point
+ add point to facet
+ exit if qh.STOPcone or qh.STOPpoint requested
+ if qh.NARROWhull for initial simplex
+ partition remaining outside points to coplanar sets
+*/
+void qh_buildhull(qhT *qh) {
+ facetT *facet;
+ pointT *furthest;
+ vertexT *vertex;
+ int id;
+
+ trace1((qh, qh->ferr, 1037, "qh_buildhull: start build hull\n"));
+ FORALLfacets {
+ if (facet->visible || facet->newfacet) {
+ qh_fprintf(qh, qh->ferr, 6165, "qhull internal error (qh_buildhull): visible or new facet f%d in facet list\n",
+ facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ }
+ FORALLvertices {
+ if (vertex->newlist) {
+ qh_fprintf(qh, qh->ferr, 6166, "qhull internal error (qh_buildhull): new vertex f%d in vertex list\n",
+ vertex->id);
+ qh_errprint(qh, "ERRONEOUS", NULL, NULL, NULL, vertex);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ id= qh_pointid(qh, vertex->point);
+ if ((qh->STOPpoint>0 && id == qh->STOPpoint-1) ||
+ (qh->STOPpoint<0 && id == -qh->STOPpoint-1) ||
+ (qh->STOPcone>0 && id == qh->STOPcone-1)) {
+ trace1((qh, qh->ferr, 1038,"qh_buildhull: stop point or cone P%d in initial hull\n", id));
+ return;
+ }
+ }
+ qh->facet_next= qh->facet_list; /* advance facet when processed */
+ while ((furthest= qh_nextfurthest(qh, &facet))) {
+ qh->num_outside--; /* if ONLYmax, furthest may not be outside */
+ if (!qh_addpoint(qh, furthest, facet, qh->ONLYmax))
+ break;
+ }
+ if (qh->NARROWhull) /* move points from outsideset to coplanarset */
+ qh_outcoplanar(qh /* facet_list */ );
+ if (qh->num_outside && !furthest) {
+ qh_fprintf(qh, qh->ferr, 6167, "qhull internal error (qh_buildhull): %d outside points were never processed.\n", qh->num_outside);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ trace1((qh, qh->ferr, 1039, "qh_buildhull: completed the hull construction\n"));
+} /* buildhull */
+
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="buildtracing">-</a>
+
+ qh_buildtracing(qh, furthest, facet )
+ trace an iteration of qh_buildhull() for furthest point and facet
+ if !furthest, prints progress message
+
+ returns:
+ tracks progress with qh.lastreport
+ updates qh.furthest_id (-3 if furthest is NULL)
+ also resets visit_id, vertext_visit on wrap around
+
+ see:
+ qh_tracemerging()
+
+ design:
+ if !furthest
+ print progress message
+ exit
+ if 'TFn' iteration
+ print progress message
+ else if tracing
+ trace furthest point and facet
+ reset qh.visit_id and qh.vertex_visit if overflow may occur
+ set qh.furthest_id for tracing
+*/
+void qh_buildtracing(qhT *qh, pointT *furthest, facetT *facet) {
+ realT dist= 0;
+ float cpu;
+ int total, furthestid;
+ time_t timedata;
+ struct tm *tp;
+ vertexT *vertex;
+
+ qh->old_randomdist= qh->RANDOMdist;
+ qh->RANDOMdist= False;
+ if (!furthest) {
+ time(&timedata);
+ tp= localtime(&timedata);
+ cpu= (float)qh_CPUclock - (float)qh->hulltime;
+ cpu /= (float)qh_SECticks;
+ total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
+ qh_fprintf(qh, qh->ferr, 8118, "\n\
+At %02d:%02d:%02d & %2.5g CPU secs, qhull has created %d facets and merged %d.\n\
+ The current hull contains %d facets and %d vertices. Last point was p%d\n",
+ tp->tm_hour, tp->tm_min, tp->tm_sec, cpu, qh->facet_id -1,
+ total, qh->num_facets, qh->num_vertices, qh->furthest_id);
+ return;
+ }
+ furthestid= qh_pointid(qh, furthest);
+ if (qh->TRACEpoint == furthestid) {
+ qh->IStracing= qh->TRACElevel;
+ qh->qhmem.IStracing= qh->TRACElevel;
+ }else if (qh->TRACEpoint != qh_IDunknown && qh->TRACEdist < REALmax/2) {
+ qh->IStracing= 0;
+ qh->qhmem.IStracing= 0;
+ }
+ if (qh->REPORTfreq && (qh->facet_id-1 > qh->lastreport+qh->REPORTfreq)) {
+ qh->lastreport= qh->facet_id-1;
+ time(&timedata);
+ tp= localtime(&timedata);
+ cpu= (float)qh_CPUclock - (float)qh->hulltime;
+ cpu /= (float)qh_SECticks;
+ total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
+ zinc_(Zdistio);
+ qh_distplane(qh, furthest, facet, &dist);
+ qh_fprintf(qh, qh->ferr, 8119, "\n\
+At %02d:%02d:%02d & %2.5g CPU secs, qhull has created %d facets and merged %d.\n\
+ The current hull contains %d facets and %d vertices. There are %d\n\
+ outside points. Next is point p%d(v%d), %2.2g above f%d.\n",
+ tp->tm_hour, tp->tm_min, tp->tm_sec, cpu, qh->facet_id -1,
+ total, qh->num_facets, qh->num_vertices, qh->num_outside+1,
+ furthestid, qh->vertex_id, dist, getid_(facet));
+ }else if (qh->IStracing >=1) {
+ cpu= (float)qh_CPUclock - (float)qh->hulltime;
+ cpu /= (float)qh_SECticks;
+ qh_distplane(qh, furthest, facet, &dist);
+ qh_fprintf(qh, qh->ferr, 8120, "qh_addpoint: add p%d(v%d) to hull of %d facets(%2.2g above f%d) and %d outside at %4.4g CPU secs. Previous was p%d.\n",
+ furthestid, qh->vertex_id, qh->num_facets, dist,
+ getid_(facet), qh->num_outside+1, cpu, qh->furthest_id);
+ }
+ zmax_(Zvisit2max, (int)qh->visit_id/2);
+ if (qh->visit_id > (unsigned) INT_MAX) { /* 31 bits */
+ zinc_(Zvisit);
+ qh->visit_id= 0;
+ FORALLfacets
+ facet->visitid= 0;
+ }
+ zmax_(Zvvisit2max, (int)qh->vertex_visit/2);
+ if (qh->vertex_visit > (unsigned) INT_MAX) { /* 31 bits */
+ zinc_(Zvvisit);
+ qh->vertex_visit= 0;
+ FORALLvertices
+ vertex->visitid= 0;
+ }
+ qh->furthest_id= furthestid;
+ qh->RANDOMdist= qh->old_randomdist;
+} /* buildtracing */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="errexit2">-</a>
+
+ qh_errexit2(qh, exitcode, facet, otherfacet )
+ return exitcode to system after an error
+ report two facets
+
+ returns:
+ assumes exitcode non-zero
+
+ see:
+ normally use qh_errexit() in user.c(reports a facet and a ridge)
+*/
+void qh_errexit2(qhT *qh, int exitcode, facetT *facet, facetT *otherfacet) {
+
+ qh_errprint(qh, "ERRONEOUS", facet, otherfacet, NULL, NULL);
+ qh_errexit(qh, exitcode, NULL, NULL);
+} /* errexit2 */
+
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="findhorizon">-</a>
+
+ qh_findhorizon(qh, point, facet, goodvisible, goodhorizon )
+ given a visible facet, find the point's horizon and visible facets
+ for all facets, !facet-visible
+
+ returns:
+ returns qh.visible_list/num_visible with all visible facets
+ marks visible facets with ->visible
+ updates count of good visible and good horizon facets
+ updates qh.max_outside, qh.max_vertex, facet->maxoutside
+
+ see:
+ similar to qh_delpoint()
+
+ design:
+ move facet to qh.visible_list at end of qh.facet_list
+ for all visible facets
+ for each unvisited neighbor of a visible facet
+ compute distance of point to neighbor
+ if point above neighbor
+ move neighbor to end of qh.visible_list
+ else if point is coplanar with neighbor
+ update qh.max_outside, qh.max_vertex, neighbor->maxoutside
+ mark neighbor coplanar (will create a samecycle later)
+ update horizon statistics
+*/
+void qh_findhorizon(qhT *qh, pointT *point, facetT *facet, int *goodvisible, int *goodhorizon) {
+ facetT *neighbor, **neighborp, *visible;
+ int numhorizon= 0, coplanar= 0;
+ realT dist;
+
+ trace1((qh, qh->ferr, 1040,"qh_findhorizon: find horizon for point p%d facet f%d\n",qh_pointid(qh, point),facet->id));
+ *goodvisible= *goodhorizon= 0;
+ zinc_(Ztotvisible);
+ qh_removefacet(qh, facet); /* visible_list at end of qh->facet_list */
+ qh_appendfacet(qh, facet);
+ qh->num_visible= 1;
+ if (facet->good)
+ (*goodvisible)++;
+ qh->visible_list= facet;
+ facet->visible= True;
+ facet->f.replace= NULL;
+ if (qh->IStracing >=4)
+ qh_errprint(qh, "visible", facet, NULL, NULL, NULL);
+ qh->visit_id++;
+ FORALLvisible_facets {
+ if (visible->tricoplanar && !qh->TRInormals) {
+ qh_fprintf(qh, qh->ferr, 6230, "Qhull internal error (qh_findhorizon): does not work for tricoplanar facets. Use option 'Q11'\n");
+ qh_errexit(qh, qh_ERRqhull, visible, NULL);
+ }
+ visible->visitid= qh->visit_id;
+ FOREACHneighbor_(visible) {
+ if (neighbor->visitid == qh->visit_id)
+ continue;
+ neighbor->visitid= qh->visit_id;
+ zzinc_(Znumvisibility);
+ qh_distplane(qh, point, neighbor, &dist);
+ if (dist > qh->MINvisible) {
+ zinc_(Ztotvisible);
+ qh_removefacet(qh, neighbor); /* append to end of qh->visible_list */
+ qh_appendfacet(qh, neighbor);
+ neighbor->visible= True;
+ neighbor->f.replace= NULL;
+ qh->num_visible++;
+ if (neighbor->good)
+ (*goodvisible)++;
+ if (qh->IStracing >=4)
+ qh_errprint(qh, "visible", neighbor, NULL, NULL, NULL);
+ }else {
+ if (dist > - qh->MAXcoplanar) {
+ neighbor->coplanar= True;
+ zzinc_(Zcoplanarhorizon);
+ qh_precision(qh, "coplanar horizon");
+ coplanar++;
+ if (qh->MERGING) {
+ if (dist > 0) {
+ maximize_(qh->max_outside, dist);
+ maximize_(qh->max_vertex, dist);
+#if qh_MAXoutside
+ maximize_(neighbor->maxoutside, dist);
+#endif
+ }else
+ minimize_(qh->min_vertex, dist); /* due to merge later */
+ }
+ trace2((qh, qh->ferr, 2057, "qh_findhorizon: point p%d is coplanar to horizon f%d, dist=%2.7g < qh->MINvisible(%2.7g)\n",
+ qh_pointid(qh, point), neighbor->id, dist, qh->MINvisible));
+ }else
+ neighbor->coplanar= False;
+ zinc_(Ztothorizon);
+ numhorizon++;
+ if (neighbor->good)
+ (*goodhorizon)++;
+ if (qh->IStracing >=4)
+ qh_errprint(qh, "horizon", neighbor, NULL, NULL, NULL);
+ }
+ }
+ }
+ if (!numhorizon) {
+ qh_precision(qh, "empty horizon");
+ qh_fprintf(qh, qh->ferr, 6168, "qhull precision error (qh_findhorizon): empty horizon\n\
+QhullPoint p%d was above all facets.\n", qh_pointid(qh, point));
+ qh_printfacetlist(qh, qh->facet_list, NULL, True);
+ qh_errexit(qh, qh_ERRprec, NULL, NULL);
+ }
+ trace1((qh, qh->ferr, 1041, "qh_findhorizon: %d horizon facets(good %d), %d visible(good %d), %d coplanar\n",
+ numhorizon, *goodhorizon, qh->num_visible, *goodvisible, coplanar));
+ if (qh->IStracing >= 4 && qh->num_facets < 50)
+ qh_printlists(qh);
+} /* findhorizon */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="nextfurthest">-</a>
+
+ qh_nextfurthest(qh, visible )
+ returns next furthest point and visible facet for qh_addpoint()
+ starts search at qh.facet_next
+
+ returns:
+ removes furthest point from outside set
+ NULL if none available
+ advances qh.facet_next over facets with empty outside sets
+
+ design:
+ for each facet from qh.facet_next
+ if empty outside set
+ advance qh.facet_next
+ else if qh.NARROWhull
+ determine furthest outside point
+ if furthest point is not outside
+ advance qh.facet_next(point will be coplanar)
+ remove furthest point from outside set
+*/
+pointT *qh_nextfurthest(qhT *qh, facetT **visible) {
+ facetT *facet;
+ int size, idx;
+ realT randr, dist;
+ pointT *furthest;
+
+ while ((facet= qh->facet_next) != qh->facet_tail) {
+ if (!facet->outsideset) {
+ qh->facet_next= facet->next;
+ continue;
+ }
+ SETreturnsize_(facet->outsideset, size);
+ if (!size) {
+ qh_setfree(qh, &facet->outsideset);
+ qh->facet_next= facet->next;
+ continue;
+ }
+ if (qh->NARROWhull) {
+ if (facet->notfurthest)
+ qh_furthestout(qh, facet);
+ furthest= (pointT*)qh_setlast(facet->outsideset);
+#if qh_COMPUTEfurthest
+ qh_distplane(qh, furthest, facet, &dist);
+ zinc_(Zcomputefurthest);
+#else
+ dist= facet->furthestdist;
+#endif
+ if (dist < qh->MINoutside) { /* remainder of outside set is coplanar for qh_outcoplanar */
+ qh->facet_next= facet->next;
+ continue;
+ }
+ }
+ if (!qh->RANDOMoutside && !qh->VIRTUALmemory) {
+ if (qh->PICKfurthest) {
+ qh_furthestnext(qh /* qh->facet_list */);
+ facet= qh->facet_next;
+ }
+ *visible= facet;
+ return((pointT*)qh_setdellast(facet->outsideset));
+ }
+ if (qh->RANDOMoutside) {
+ int outcoplanar = 0;
+ if (qh->NARROWhull) {
+ FORALLfacets {
+ if (facet == qh->facet_next)
+ break;
+ if (facet->outsideset)
+ outcoplanar += qh_setsize(qh, facet->outsideset);
+ }
+ }
+ randr= qh_RANDOMint;
+ randr= randr/(qh_RANDOMmax+1);
+ idx= (int)floor((qh->num_outside - outcoplanar) * randr);
+ FORALLfacet_(qh->facet_next) {
+ if (facet->outsideset) {
+ SETreturnsize_(facet->outsideset, size);
+ if (!size)
+ qh_setfree(qh, &facet->outsideset);
+ else if (size > idx) {
+ *visible= facet;
+ return((pointT*)qh_setdelnth(qh, facet->outsideset, idx));
+ }else
+ idx -= size;
+ }
+ }
+ qh_fprintf(qh, qh->ferr, 6169, "qhull internal error (qh_nextfurthest): num_outside %d is too low\nby at least %d, or a random real %g >= 1.0\n",
+ qh->num_outside, idx+1, randr);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }else { /* VIRTUALmemory */
+ facet= qh->facet_tail->previous;
+ if (!(furthest= (pointT*)qh_setdellast(facet->outsideset))) {
+ if (facet->outsideset)
+ qh_setfree(qh, &facet->outsideset);
+ qh_removefacet(qh, facet);
+ qh_prependfacet(qh, facet, &qh->facet_list);
+ continue;
+ }
+ *visible= facet;
+ return furthest;
+ }
+ }
+ return NULL;
+} /* nextfurthest */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="partitionall">-</a>
+
+ qh_partitionall(qh, vertices, points, numpoints )
+ partitions all points in points/numpoints to the outsidesets of facets
+ vertices= vertices in qh.facet_list(!partitioned)
+
+ returns:
+ builds facet->outsideset
+ does not partition qh.GOODpoint
+ if qh.ONLYgood && !qh.MERGING,
+ does not partition qh.GOODvertex
+
+ notes:
+ faster if qh.facet_list sorted by anticipated size of outside set
+
+ design:
+ initialize pointset with all points
+ remove vertices from pointset
+ remove qh.GOODpointp from pointset (unless it's qh.STOPcone or qh.STOPpoint)
+ for all facets
+ for all remaining points in pointset
+ compute distance from point to facet
+ if point is outside facet
+ remove point from pointset (by not reappending)
+ update bestpoint
+ append point or old bestpoint to facet's outside set
+ append bestpoint to facet's outside set (furthest)
+ for all points remaining in pointset
+ partition point into facets' outside sets and coplanar sets
+*/
+void qh_partitionall(qhT *qh, setT *vertices, pointT *points, int numpoints){
+ setT *pointset;
+ vertexT *vertex, **vertexp;
+ pointT *point, **pointp, *bestpoint;
+ int size, point_i, point_n, point_end, remaining, i, id;
+ facetT *facet;
+ realT bestdist= -REALmax, dist, distoutside;
+
+ trace1((qh, qh->ferr, 1042, "qh_partitionall: partition all points into outside sets\n"));
+ pointset= qh_settemp(qh, numpoints);
+ qh->num_outside= 0;
+ pointp= SETaddr_(pointset, pointT);
+ for (i=numpoints, point= points; i--; point += qh->hull_dim)
+ *(pointp++)= point;
+ qh_settruncate(qh, pointset, numpoints);
+ FOREACHvertex_(vertices) {
+ if ((id= qh_pointid(qh, vertex->point)) >= 0)
+ SETelem_(pointset, id)= NULL;
+ }
+ id= qh_pointid(qh, qh->GOODpointp);
+ if (id >=0 && qh->STOPcone-1 != id && -qh->STOPpoint-1 != id)
+ SETelem_(pointset, id)= NULL;
+ if (qh->GOODvertexp && qh->ONLYgood && !qh->MERGING) { /* matches qhull()*/
+ if ((id= qh_pointid(qh, qh->GOODvertexp)) >= 0)
+ SETelem_(pointset, id)= NULL;
+ }
+ if (!qh->BESToutside) { /* matches conditional for qh_partitionpoint below */
+ distoutside= qh_DISToutside; /* multiple of qh.MINoutside & qh.max_outside, see user.h */
+ zval_(Ztotpartition)= qh->num_points - qh->hull_dim - 1; /*misses GOOD... */
+ remaining= qh->num_facets;
+ point_end= numpoints;
+ FORALLfacets {
+ size= point_end/(remaining--) + 100;
+ facet->outsideset= qh_setnew(qh, size);
+ bestpoint= NULL;
+ point_end= 0;
+ FOREACHpoint_i_(qh, pointset) {
+ if (point) {
+ zzinc_(Zpartitionall);
+ qh_distplane(qh, point, facet, &dist);
+ if (dist < distoutside)
+ SETelem_(pointset, point_end++)= point;
+ else {
+ qh->num_outside++;
+ if (!bestpoint) {
+ bestpoint= point;
+ bestdist= dist;
+ }else if (dist > bestdist) {
+ qh_setappend(qh, &facet->outsideset, bestpoint);
+ bestpoint= point;
+ bestdist= dist;
+ }else
+ qh_setappend(qh, &facet->outsideset, point);
+ }
+ }
+ }
+ if (bestpoint) {
+ qh_setappend(qh, &facet->outsideset, bestpoint);
+#if !qh_COMPUTEfurthest
+ facet->furthestdist= bestdist;
+#endif
+ }else
+ qh_setfree(qh, &facet->outsideset);
+ qh_settruncate(qh, pointset, point_end);
+ }
+ }
+ /* if !qh->BESToutside, pointset contains points not assigned to outsideset */
+ if (qh->BESToutside || qh->MERGING || qh->KEEPcoplanar || qh->KEEPinside) {
+ qh->findbestnew= True;
+ FOREACHpoint_i_(qh, pointset) {
+ if (point)
+ qh_partitionpoint(qh, point, qh->facet_list);
+ }
+ qh->findbestnew= False;
+ }
+ zzadd_(Zpartitionall, zzval_(Zpartition));
+ zzval_(Zpartition)= 0;
+ qh_settempfree(qh, &pointset);
+ if (qh->IStracing >= 4)
+ qh_printfacetlist(qh, qh->facet_list, NULL, True);
+} /* partitionall */
+
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="partitioncoplanar">-</a>
+
+ qh_partitioncoplanar(qh, point, facet, dist )
+ partition coplanar point to a facet
+ dist is distance from point to facet
+ if dist NULL,
+ searches for bestfacet and does nothing if inside
+ if qh.findbestnew set,
+ searches new facets instead of using qh_findbest()
+
+ returns:
+ qh.max_ouside updated
+ if qh.KEEPcoplanar or qh.KEEPinside
+ point assigned to best coplanarset
+
+ notes:
+ facet->maxoutside is updated at end by qh_check_maxout
+
+ design:
+ if dist undefined
+ find best facet for point
+ if point sufficiently below facet (depends on qh.NEARinside and qh.KEEPinside)
+ exit
+ if keeping coplanar/nearinside/inside points
+ if point is above furthest coplanar point
+ append point to coplanar set (it is the new furthest)
+ update qh.max_outside
+ else
+ append point one before end of coplanar set
+ else if point is clearly outside of qh.max_outside and bestfacet->coplanarset
+ and bestfacet is more than perpendicular to facet
+ repartition the point using qh_findbest() -- it may be put on an outsideset
+ else
+ update qh.max_outside
+*/
+void qh_partitioncoplanar(qhT *qh, pointT *point, facetT *facet, realT *dist) {
+ facetT *bestfacet;
+ pointT *oldfurthest;
+ realT bestdist, dist2= 0, angle;
+ int numpart= 0, oldfindbest;
+ boolT isoutside;
+
+ qh->WAScoplanar= True;
+ if (!dist) {
+ if (qh->findbestnew)
+ bestfacet= qh_findbestnew(qh, point, facet, &bestdist, qh_ALL, &isoutside, &numpart);
+ else
+ bestfacet= qh_findbest(qh, point, facet, qh_ALL, !qh_ISnewfacets, qh->DELAUNAY,
+ &bestdist, &isoutside, &numpart);
+ zinc_(Ztotpartcoplanar);
+ zzadd_(Zpartcoplanar, numpart);
+ if (!qh->DELAUNAY && !qh->KEEPinside) { /* for 'd', bestdist skips upperDelaunay facets */
+ if (qh->KEEPnearinside) {
+ if (bestdist < -qh->NEARinside) {
+ zinc_(Zcoplanarinside);
+ trace4((qh, qh->ferr, 4062, "qh_partitioncoplanar: point p%d is more than near-inside facet f%d dist %2.2g findbestnew %d\n",
+ qh_pointid(qh, point), bestfacet->id, bestdist, qh->findbestnew));
+ return;
+ }
+ }else if (bestdist < -qh->MAXcoplanar) {
+ trace4((qh, qh->ferr, 4063, "qh_partitioncoplanar: point p%d is inside facet f%d dist %2.2g findbestnew %d\n",
+ qh_pointid(qh, point), bestfacet->id, bestdist, qh->findbestnew));
+ zinc_(Zcoplanarinside);
+ return;
+ }
+ }
+ }else {
+ bestfacet= facet;
+ bestdist= *dist;
+ }
+ if (bestdist > qh->max_outside) {
+ if (!dist && facet != bestfacet) {
+ zinc_(Zpartangle);
+ angle= qh_getangle(qh, facet->normal, bestfacet->normal);
+ if (angle < 0) {
+ /* typically due to deleted vertex and coplanar facets, e.g.,
+ RBOX 1000 s Z1 G1e-13 t1001185205 | QHULL Tv */
+ zinc_(Zpartflip);
+ trace2((qh, qh->ferr, 2058, "qh_partitioncoplanar: repartition point p%d from f%d. It is above flipped facet f%d dist %2.2g\n",
+ qh_pointid(qh, point), facet->id, bestfacet->id, bestdist));
+ oldfindbest= qh->findbestnew;
+ qh->findbestnew= False;
+ qh_partitionpoint(qh, point, bestfacet);
+ qh->findbestnew= oldfindbest;
+ return;
+ }
+ }
+ qh->max_outside= bestdist;
+ if (bestdist > qh->TRACEdist) {
+ qh_fprintf(qh, qh->ferr, 8122, "qh_partitioncoplanar: ====== p%d from f%d increases max_outside to %2.2g of f%d last p%d\n",
+ qh_pointid(qh, point), facet->id, bestdist, bestfacet->id, qh->furthest_id);
+ qh_errprint(qh, "DISTANT", facet, bestfacet, NULL, NULL);
+ }
+ }
+ if (qh->KEEPcoplanar + qh->KEEPinside + qh->KEEPnearinside) {
+ oldfurthest= (pointT*)qh_setlast(bestfacet->coplanarset);
+ if (oldfurthest) {
+ zinc_(Zcomputefurthest);
+ qh_distplane(qh, oldfurthest, bestfacet, &dist2);
+ }
+ if (!oldfurthest || dist2 < bestdist)
+ qh_setappend(qh, &bestfacet->coplanarset, point);
+ else
+ qh_setappend2ndlast(qh, &bestfacet->coplanarset, point);
+ }
+ trace4((qh, qh->ferr, 4064, "qh_partitioncoplanar: point p%d is coplanar with facet f%d(or inside) dist %2.2g\n",
+ qh_pointid(qh, point), bestfacet->id, bestdist));
+} /* partitioncoplanar */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="partitionpoint">-</a>
+
+ qh_partitionpoint(qh, point, facet )
+ assigns point to an outside set, coplanar set, or inside set (i.e., dropt)
+ if qh.findbestnew
+ uses qh_findbestnew() to search all new facets
+ else
+ uses qh_findbest()
+
+ notes:
+ after qh_distplane(), this and qh_findbest() are most expensive in 3-d
+
+ design:
+ find best facet for point
+ (either exhaustive search of new facets or directed search from facet)
+ if qh.NARROWhull
+ retain coplanar and nearinside points as outside points
+ if point is outside bestfacet
+ if point above furthest point for bestfacet
+ append point to outside set (it becomes the new furthest)
+ if outside set was empty
+ move bestfacet to end of qh.facet_list (i.e., after qh.facet_next)
+ update bestfacet->furthestdist
+ else
+ append point one before end of outside set
+ else if point is coplanar to bestfacet
+ if keeping coplanar points or need to update qh.max_outside
+ partition coplanar point into bestfacet
+ else if near-inside point
+ partition as coplanar point into bestfacet
+ else is an inside point
+ if keeping inside points
+ partition as coplanar point into bestfacet
+*/
+void qh_partitionpoint(qhT *qh, pointT *point, facetT *facet) {
+ realT bestdist;
+ boolT isoutside;
+ facetT *bestfacet;
+ int numpart;
+#if qh_COMPUTEfurthest
+ realT dist;
+#endif
+
+ if (qh->findbestnew)
+ bestfacet= qh_findbestnew(qh, point, facet, &bestdist, qh->BESToutside, &isoutside, &numpart);
+ else
+ bestfacet= qh_findbest(qh, point, facet, qh->BESToutside, qh_ISnewfacets, !qh_NOupper,
+ &bestdist, &isoutside, &numpart);
+ zinc_(Ztotpartition);
+ zzadd_(Zpartition, numpart);
+ if (qh->NARROWhull) {
+ if (qh->DELAUNAY && !isoutside && bestdist >= -qh->MAXcoplanar)
+ qh_precision(qh, "nearly incident point(narrow hull)");
+ if (qh->KEEPnearinside) {
+ if (bestdist >= -qh->NEARinside)
+ isoutside= True;
+ }else if (bestdist >= -qh->MAXcoplanar)
+ isoutside= True;
+ }
+
+ if (isoutside) {
+ if (!bestfacet->outsideset
+ || !qh_setlast(bestfacet->outsideset)) {
+ qh_setappend(qh, &(bestfacet->outsideset), point);
+ if (!bestfacet->newfacet) {
+ qh_removefacet(qh, bestfacet); /* make sure it's after qh->facet_next */
+ qh_appendfacet(qh, bestfacet);
+ }
+#if !qh_COMPUTEfurthest
+ bestfacet->furthestdist= bestdist;
+#endif
+ }else {
+#if qh_COMPUTEfurthest
+ zinc_(Zcomputefurthest);
+ qh_distplane(qh, oldfurthest, bestfacet, &dist);
+ if (dist < bestdist)
+ qh_setappend(qh, &(bestfacet->outsideset), point);
+ else
+ qh_setappend2ndlast(qh, &(bestfacet->outsideset), point);
+#else
+ if (bestfacet->furthestdist < bestdist) {
+ qh_setappend(qh, &(bestfacet->outsideset), point);
+ bestfacet->furthestdist= bestdist;
+ }else
+ qh_setappend2ndlast(qh, &(bestfacet->outsideset), point);
+#endif
+ }
+ qh->num_outside++;
+ trace4((qh, qh->ferr, 4065, "qh_partitionpoint: point p%d is outside facet f%d new? %d (or narrowhull)\n",
+ qh_pointid(qh, point), bestfacet->id, bestfacet->newfacet));
+ }else if (qh->DELAUNAY || bestdist >= -qh->MAXcoplanar) { /* for 'd', bestdist skips upperDelaunay facets */
+ zzinc_(Zcoplanarpart);
+ if (qh->DELAUNAY)
+ qh_precision(qh, "nearly incident point");
+ if ((qh->KEEPcoplanar + qh->KEEPnearinside) || bestdist > qh->max_outside)
+ qh_partitioncoplanar(qh, point, bestfacet, &bestdist);
+ else {
+ trace4((qh, qh->ferr, 4066, "qh_partitionpoint: point p%d is coplanar to facet f%d (dropped)\n",
+ qh_pointid(qh, point), bestfacet->id));
+ }
+ }else if (qh->KEEPnearinside && bestdist > -qh->NEARinside) {
+ zinc_(Zpartnear);
+ qh_partitioncoplanar(qh, point, bestfacet, &bestdist);
+ }else {
+ zinc_(Zpartinside);
+ trace4((qh, qh->ferr, 4067, "qh_partitionpoint: point p%d is inside all facets, closest to f%d dist %2.2g\n",
+ qh_pointid(qh, point), bestfacet->id, bestdist));
+ if (qh->KEEPinside)
+ qh_partitioncoplanar(qh, point, bestfacet, &bestdist);
+ }
+} /* partitionpoint */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="partitionvisible">-</a>
+
+ qh_partitionvisible(qh, allpoints, numoutside )
+ partitions points in visible facets to qh.newfacet_list
+ qh.visible_list= visible facets
+ for visible facets
+ 1st neighbor (if any) points to a horizon facet or a new facet
+ if allpoints(!used),
+ repartitions coplanar points
+
+ returns:
+ updates outside sets and coplanar sets of qh.newfacet_list
+ updates qh.num_outside (count of outside points)
+
+ notes:
+ qh.findbest_notsharp should be clear (extra work if set)
+
+ design:
+ for all visible facets with outside set or coplanar set
+ select a newfacet for visible facet
+ if outside set
+ partition outside set into new facets
+ if coplanar set and keeping coplanar/near-inside/inside points
+ if allpoints
+ partition coplanar set into new facets, may be assigned outside
+ else
+ partition coplanar set into coplanar sets of new facets
+ for each deleted vertex
+ if allpoints
+ partition vertex into new facets, may be assigned outside
+ else
+ partition vertex into coplanar sets of new facets
+*/
+void qh_partitionvisible(qhT *qh /*qh.visible_list*/, boolT allpoints, int *numoutside) {
+ facetT *visible, *newfacet;
+ pointT *point, **pointp;
+ int coplanar=0, size;
+ unsigned count;
+ vertexT *vertex, **vertexp;
+
+ if (qh->ONLYmax)
+ maximize_(qh->MINoutside, qh->max_vertex);
+ *numoutside= 0;
+ FORALLvisible_facets {
+ if (!visible->outsideset && !visible->coplanarset)
+ continue;
+ newfacet= visible->f.replace;
+ count= 0;
+ while (newfacet && newfacet->visible) {
+ newfacet= newfacet->f.replace;
+ if (count++ > qh->facet_id)
+ qh_infiniteloop(qh, visible);
+ }
+ if (!newfacet)
+ newfacet= qh->newfacet_list;
+ if (newfacet == qh->facet_tail) {
+ qh_fprintf(qh, qh->ferr, 6170, "qhull precision error (qh_partitionvisible): all new facets deleted as\n degenerate facets. Can not continue.\n");
+ qh_errexit(qh, qh_ERRprec, NULL, NULL);
+ }
+ if (visible->outsideset) {
+ size= qh_setsize(qh, visible->outsideset);
+ *numoutside += size;
+ qh->num_outside -= size;
+ FOREACHpoint_(visible->outsideset)
+ qh_partitionpoint(qh, point, newfacet);
+ }
+ if (visible->coplanarset && (qh->KEEPcoplanar + qh->KEEPinside + qh->KEEPnearinside)) {
+ size= qh_setsize(qh, visible->coplanarset);
+ coplanar += size;
+ FOREACHpoint_(visible->coplanarset) {
+ if (allpoints) /* not used */
+ qh_partitionpoint(qh, point, newfacet);
+ else
+ qh_partitioncoplanar(qh, point, newfacet, NULL);
+ }
+ }
+ }
+ FOREACHvertex_(qh->del_vertices) {
+ if (vertex->point) {
+ if (allpoints) /* not used */
+ qh_partitionpoint(qh, vertex->point, qh->newfacet_list);
+ else
+ qh_partitioncoplanar(qh, vertex->point, qh->newfacet_list, NULL);
+ }
+ }
+ trace1((qh, qh->ferr, 1043,"qh_partitionvisible: partitioned %d points from outsidesets and %d points from coplanarsets\n", *numoutside, coplanar));
+} /* partitionvisible */
+
+
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="precision">-</a>
+
+ qh_precision(qh, reason )
+ restart on precision errors if not merging and if 'QJn'
+*/
+void qh_precision(qhT *qh, const char *reason) {
+
+ if (qh->ALLOWrestart && !qh->PREmerge && !qh->MERGEexact) {
+ if (qh->JOGGLEmax < REALmax/2) {
+ trace0((qh, qh->ferr, 26, "qh_precision: qhull restart because of %s\n", reason));
+ /* May be called repeatedly if qh->ALLOWrestart */
+ longjmp(qh->restartexit, qh_ERRprec);
+ }
+ }
+} /* qh_precision */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="printsummary">-</a>
+
+ qh_printsummary(qh, fp )
+ prints summary to fp
+
+ notes:
+ not in io_r.c so that user_eg.c can prevent io_r.c from loading
+ qh_printsummary and qh_countfacets must match counts
+
+ design:
+ determine number of points, vertices, and coplanar points
+ print summary
+*/
+void qh_printsummary(qhT *qh, FILE *fp) {
+ realT ratio, outerplane, innerplane;
+ float cpu;
+ int size, id, nummerged, numvertices, numcoplanars= 0, nonsimplicial=0;
+ int goodused;
+ facetT *facet;
+ const char *s;
+ int numdel= zzval_(Zdelvertextot);
+ int numtricoplanars= 0;
+
+ size= qh->num_points + qh_setsize(qh, qh->other_points);
+ numvertices= qh->num_vertices - qh_setsize(qh, qh->del_vertices);
+ id= qh_pointid(qh, qh->GOODpointp);
+ FORALLfacets {
+ if (facet->coplanarset)
+ numcoplanars += qh_setsize(qh, facet->coplanarset);
+ if (facet->good) {
+ if (facet->simplicial) {
+ if (facet->keepcentrum && facet->tricoplanar)
+ numtricoplanars++;
+ }else if (qh_setsize(qh, facet->vertices) != qh->hull_dim)
+ nonsimplicial++;
+ }
+ }
+ if (id >=0 && qh->STOPcone-1 != id && -qh->STOPpoint-1 != id)
+ size--;
+ if (qh->STOPcone || qh->STOPpoint)
+ qh_fprintf(qh, fp, 9288, "\nAt a premature exit due to 'TVn', 'TCn', 'TRn', or precision error with 'QJn'.");
+ if (qh->UPPERdelaunay)
+ goodused= qh->GOODvertex + qh->GOODpoint + qh->SPLITthresholds;
+ else if (qh->DELAUNAY)
+ goodused= qh->GOODvertex + qh->GOODpoint + qh->GOODthreshold;
+ else
+ goodused= qh->num_good;
+ nummerged= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
+ if (qh->VORONOI) {
+ if (qh->UPPERdelaunay)
+ qh_fprintf(qh, fp, 9289, "\n\
+Furthest-site Voronoi vertices by the convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
+ else
+ qh_fprintf(qh, fp, 9290, "\n\
+Voronoi diagram by the convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
+ qh_fprintf(qh, fp, 9291, " Number of Voronoi regions%s: %d\n",
+ qh->ATinfinity ? " and at-infinity" : "", numvertices);
+ if (numdel)
+ qh_fprintf(qh, fp, 9292, " Total number of deleted points due to merging: %d\n", numdel);
+ if (numcoplanars - numdel > 0)
+ qh_fprintf(qh, fp, 9293, " Number of nearly incident points: %d\n", numcoplanars - numdel);
+ else if (size - numvertices - numdel > 0)
+ qh_fprintf(qh, fp, 9294, " Total number of nearly incident points: %d\n", size - numvertices - numdel);
+ qh_fprintf(qh, fp, 9295, " Number of%s Voronoi vertices: %d\n",
+ goodused ? " 'good'" : "", qh->num_good);
+ if (nonsimplicial)
+ qh_fprintf(qh, fp, 9296, " Number of%s non-simplicial Voronoi vertices: %d\n",
+ goodused ? " 'good'" : "", nonsimplicial);
+ }else if (qh->DELAUNAY) {
+ if (qh->UPPERdelaunay)
+ qh_fprintf(qh, fp, 9297, "\n\
+Furthest-site Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
+ else
+ qh_fprintf(qh, fp, 9298, "\n\
+Delaunay triangulation by the convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
+ qh_fprintf(qh, fp, 9299, " Number of input sites%s: %d\n",
+ qh->ATinfinity ? " and at-infinity" : "", numvertices);
+ if (numdel)
+ qh_fprintf(qh, fp, 9300, " Total number of deleted points due to merging: %d\n", numdel);
+ if (numcoplanars - numdel > 0)
+ qh_fprintf(qh, fp, 9301, " Number of nearly incident points: %d\n", numcoplanars - numdel);
+ else if (size - numvertices - numdel > 0)
+ qh_fprintf(qh, fp, 9302, " Total number of nearly incident points: %d\n", size - numvertices - numdel);
+ qh_fprintf(qh, fp, 9303, " Number of%s Delaunay regions: %d\n",
+ goodused ? " 'good'" : "", qh->num_good);
+ if (nonsimplicial)
+ qh_fprintf(qh, fp, 9304, " Number of%s non-simplicial Delaunay regions: %d\n",
+ goodused ? " 'good'" : "", nonsimplicial);
+ }else if (qh->HALFspace) {
+ qh_fprintf(qh, fp, 9305, "\n\
+Halfspace intersection by the convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
+ qh_fprintf(qh, fp, 9306, " Number of halfspaces: %d\n", size);
+ qh_fprintf(qh, fp, 9307, " Number of non-redundant halfspaces: %d\n", numvertices);
+ if (numcoplanars) {
+ if (qh->KEEPinside && qh->KEEPcoplanar)
+ s= "similar and redundant";
+ else if (qh->KEEPinside)
+ s= "redundant";
+ else
+ s= "similar";
+ qh_fprintf(qh, fp, 9308, " Number of %s halfspaces: %d\n", s, numcoplanars);
+ }
+ qh_fprintf(qh, fp, 9309, " Number of intersection points: %d\n", qh->num_facets - qh->num_visible);
+ if (goodused)
+ qh_fprintf(qh, fp, 9310, " Number of 'good' intersection points: %d\n", qh->num_good);
+ if (nonsimplicial)
+ qh_fprintf(qh, fp, 9311, " Number of%s non-simplicial intersection points: %d\n",
+ goodused ? " 'good'" : "", nonsimplicial);
+ }else {
+ qh_fprintf(qh, fp, 9312, "\n\
+Convex hull of %d points in %d-d:\n\n", size, qh->hull_dim);
+ qh_fprintf(qh, fp, 9313, " Number of vertices: %d\n", numvertices);
+ if (numcoplanars) {
+ if (qh->KEEPinside && qh->KEEPcoplanar)
+ s= "coplanar and interior";
+ else if (qh->KEEPinside)
+ s= "interior";
+ else
+ s= "coplanar";
+ qh_fprintf(qh, fp, 9314, " Number of %s points: %d\n", s, numcoplanars);
+ }
+ qh_fprintf(qh, fp, 9315, " Number of facets: %d\n", qh->num_facets - qh->num_visible);
+ if (goodused)
+ qh_fprintf(qh, fp, 9316, " Number of 'good' facets: %d\n", qh->num_good);
+ if (nonsimplicial)
+ qh_fprintf(qh, fp, 9317, " Number of%s non-simplicial facets: %d\n",
+ goodused ? " 'good'" : "", nonsimplicial);
+ }
+ if (numtricoplanars)
+ qh_fprintf(qh, fp, 9318, " Number of triangulated facets: %d\n", numtricoplanars);
+ qh_fprintf(qh, fp, 9319, "\nStatistics for: %s | %s",
+ qh->rbox_command, qh->qhull_command);
+ if (qh->ROTATErandom != INT_MIN)
+ qh_fprintf(qh, fp, 9320, " QR%d\n\n", qh->ROTATErandom);
+ else
+ qh_fprintf(qh, fp, 9321, "\n\n");
+ qh_fprintf(qh, fp, 9322, " Number of points processed: %d\n", zzval_(Zprocessed));
+ qh_fprintf(qh, fp, 9323, " Number of hyperplanes created: %d\n", zzval_(Zsetplane));
+ if (qh->DELAUNAY)
+ qh_fprintf(qh, fp, 9324, " Number of facets in hull: %d\n", qh->num_facets - qh->num_visible);
+ qh_fprintf(qh, fp, 9325, " Number of distance tests for qhull: %d\n", zzval_(Zpartition)+
+ zzval_(Zpartitionall)+zzval_(Znumvisibility)+zzval_(Zpartcoplanar));
+#if 0 /* NOTE: must print before printstatistics() */
+ {realT stddev, ave;
+ qh_fprintf(qh, fp, 9326, " average new facet balance: %2.2g\n",
+ wval_(Wnewbalance)/zval_(Zprocessed));
+ stddev= qh_stddev(zval_(Zprocessed), wval_(Wnewbalance),
+ wval_(Wnewbalance2), &ave);
+ qh_fprintf(qh, fp, 9327, " new facet standard deviation: %2.2g\n", stddev);
+ qh_fprintf(qh, fp, 9328, " average partition balance: %2.2g\n",
+ wval_(Wpbalance)/zval_(Zpbalance));
+ stddev= qh_stddev(zval_(Zpbalance), wval_(Wpbalance),
+ wval_(Wpbalance2), &ave);
+ qh_fprintf(qh, fp, 9329, " partition standard deviation: %2.2g\n", stddev);
+ }
+#endif
+ if (nummerged) {
+ qh_fprintf(qh, fp, 9330," Number of distance tests for merging: %d\n",zzval_(Zbestdist)+
+ zzval_(Zcentrumtests)+zzval_(Zdistconvex)+zzval_(Zdistcheck)+
+ zzval_(Zdistzero));
+ qh_fprintf(qh, fp, 9331," Number of distance tests for checking: %d\n",zzval_(Zcheckpart));
+ qh_fprintf(qh, fp, 9332," Number of merged facets: %d\n", nummerged);
+ }
+ if (!qh->RANDOMoutside && qh->QHULLfinished) {
+ cpu= (float)qh->hulltime;
+ cpu /= (float)qh_SECticks;
+ wval_(Wcpu)= cpu;
+ qh_fprintf(qh, fp, 9333, " CPU seconds to compute hull (after input): %2.4g\n", cpu);
+ }
+ if (qh->RERUN) {
+ if (!qh->PREmerge && !qh->MERGEexact)
+ qh_fprintf(qh, fp, 9334, " Percentage of runs with precision errors: %4.1f\n",
+ zzval_(Zretry)*100.0/qh->build_cnt); /* careful of order */
+ }else if (qh->JOGGLEmax < REALmax/2) {
+ if (zzval_(Zretry))
+ qh_fprintf(qh, fp, 9335, " After %d retries, input joggled by: %2.2g\n",
+ zzval_(Zretry), qh->JOGGLEmax);
+ else
+ qh_fprintf(qh, fp, 9336, " Input joggled by: %2.2g\n", qh->JOGGLEmax);
+ }
+ if (qh->totarea != 0.0)
+ qh_fprintf(qh, fp, 9337, " %s facet area: %2.8g\n",
+ zzval_(Ztotmerge) ? "Approximate" : "Total", qh->totarea);
+ if (qh->totvol != 0.0)
+ qh_fprintf(qh, fp, 9338, " %s volume: %2.8g\n",
+ zzval_(Ztotmerge) ? "Approximate" : "Total", qh->totvol);
+ if (qh->MERGING) {
+ qh_outerinner(qh, NULL, &outerplane, &innerplane);
+ if (outerplane > 2 * qh->DISTround) {
+ qh_fprintf(qh, fp, 9339, " Maximum distance of %spoint above facet: %2.2g",
+ (qh->QHULLfinished ? "" : "merged "), outerplane);
+ ratio= outerplane/(qh->ONEmerge + qh->DISTround);
+ /* don't report ratio if MINoutside is large */
+ if (ratio > 0.05 && 2* qh->ONEmerge > qh->MINoutside && qh->JOGGLEmax > REALmax/2)
+ qh_fprintf(qh, fp, 9340, " (%.1fx)\n", ratio);
+ else
+ qh_fprintf(qh, fp, 9341, "\n");
+ }
+ if (innerplane < -2 * qh->DISTround) {
+ qh_fprintf(qh, fp, 9342, " Maximum distance of %svertex below facet: %2.2g",
+ (qh->QHULLfinished ? "" : "merged "), innerplane);
+ ratio= -innerplane/(qh->ONEmerge+qh->DISTround);
+ if (ratio > 0.05 && qh->JOGGLEmax > REALmax/2)
+ qh_fprintf(qh, fp, 9343, " (%.1fx)\n", ratio);
+ else
+ qh_fprintf(qh, fp, 9344, "\n");
+ }
+ }
+ qh_fprintf(qh, fp, 9345, "\n");
+} /* printsummary */
+
+
diff --git a/xs/src/qhull/src/libqhull_r/libqhull_r.h b/xs/src/qhull/src/libqhull_r/libqhull_r.h
new file mode 100644
index 000000000..363e6da6a
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/libqhull_r.h
@@ -0,0 +1,1134 @@
+/*<html><pre> -<a href="qh-qhull_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ libqhull_r.h
+ user-level header file for using qhull.a library
+
+ see qh-qhull_r.htm, qhull_ra.h
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/libqhull_r.h#8 $$Change: 2079 $
+ $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+
+ includes function prototypes for libqhull_r.c, geom_r.c, global_r.c, io_r.c, user.c
+
+ use mem_r.h for mem_r.c
+ use qset_r.h for qset_r.c
+
+ see unix_r.c for an example of using libqhull_r.h
+
+ recompile qhull if you change this file
+*/
+
+#ifndef qhDEFlibqhull
+#define qhDEFlibqhull 1
+
+/*=========================== -included files ==============*/
+
+/* user_r.h first for QHULL_CRTDBG */
+#include "user_r.h" /* user definable constants (e.g., realT). */
+
+#include "mem_r.h" /* Needed for qhT in libqhull_r.h */
+#include "qset_r.h" /* Needed for QHULL_LIB_CHECK */
+/* include stat_r.h after defining boolT. statT needed for qhT in libqhull_r.h */
+
+#include <setjmp.h>
+#include <float.h>
+#include <time.h>
+#include <stdio.h>
+
+#ifndef __STDC__
+#ifndef __cplusplus
+#if !_MSC_VER
+#error Neither __STDC__ nor __cplusplus is defined. Please use strict ANSI C or C++ to compile
+#error Qhull. You may need to turn off compiler extensions in your project configuration. If
+#error your compiler is a standard C compiler, you can delete this warning from libqhull_r.h
+#endif
+#endif
+#endif
+
+/*============ constants and basic types ====================*/
+
+extern const char qh_version[]; /* defined in global_r.c */
+extern const char qh_version2[]; /* defined in global_r.c */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >--------------------------------</a><a name="coordT">-</a>
+
+ coordT
+ coordinates and coefficients are stored as realT (i.e., double)
+
+ notes:
+ Qhull works well if realT is 'float'. If so joggle (QJ) is not effective.
+
+ Could use 'float' for data and 'double' for calculations (realT vs. coordT)
+ This requires many type casts, and adjusted error bounds.
+ Also C compilers may do expressions in double anyway.
+*/
+#define coordT realT
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >--------------------------------</a><a name="pointT">-</a>
+
+ pointT
+ a point is an array of coordinates, usually qh.hull_dim
+ qh_pointid returns
+ qh_IDnone if point==0 or qh is undefined
+ qh_IDinterior for qh.interior_point
+ qh_IDunknown if point is neither in qh.first_point... nor qh.other_points
+
+ notes:
+ qh.STOPcone and qh.STOPpoint assume that qh_IDunknown==-1 (other negative numbers indicate points)
+ qh_IDunknown is also returned by getid_() for unknown facet, ridge, or vertex
+*/
+#define pointT coordT
+typedef enum
+{
+ qh_IDnone = -3, qh_IDinterior = -2, qh_IDunknown = -1
+}
+qh_pointT;
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >--------------------------------</a><a name="flagT">-</a>
+
+ flagT
+ Boolean flag as a bit
+*/
+#define flagT unsigned int
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >--------------------------------</a><a name="boolT">-</a>
+
+ boolT
+ boolean value, either True or False
+
+ notes:
+ needed for portability
+ Use qh_False/qh_True as synonyms
+*/
+#define boolT unsigned int
+#ifdef False
+#undef False
+#endif
+#ifdef True
+#undef True
+#endif
+#define False 0
+#define True 1
+#define qh_False 0
+#define qh_True 1
+
+#include "stat_r.h" /* needs boolT */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >--------------------------------</a><a name="CENTERtype">-</a>
+
+ qh_CENTER
+ to distinguish facet->center
+*/
+typedef enum
+{
+ qh_ASnone = 0, /* If not MERGING and not VORONOI */
+ qh_ASvoronoi, /* Set by qh_clearcenters on qh_prepare_output, or if not MERGING and VORONOI */
+ qh_AScentrum /* If MERGING (assumed during merging) */
+}
+qh_CENTER;
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >--------------------------------</a><a name="qh_PRINT">-</a>
+
+ qh_PRINT
+ output formats for printing (qh.PRINTout).
+ 'Fa' 'FV' 'Fc' 'FC'
+
+
+ notes:
+ some of these names are similar to qhT names. The similar names are only
+ used in switch statements in qh_printbegin() etc.
+*/
+typedef enum {qh_PRINTnone= 0,
+ qh_PRINTarea, qh_PRINTaverage, /* 'Fa' 'FV' 'Fc' 'FC' */
+ qh_PRINTcoplanars, qh_PRINTcentrums,
+ qh_PRINTfacets, qh_PRINTfacets_xridge, /* 'f' 'FF' 'G' 'FI' 'Fi' 'Fn' */
+ qh_PRINTgeom, qh_PRINTids, qh_PRINTinner, qh_PRINTneighbors,
+ qh_PRINTnormals, qh_PRINTouter, qh_PRINTmaple, /* 'n' 'Fo' 'i' 'm' 'Fm' 'FM', 'o' */
+ qh_PRINTincidences, qh_PRINTmathematica, qh_PRINTmerges, qh_PRINToff,
+ qh_PRINToptions, qh_PRINTpointintersect, /* 'FO' 'Fp' 'FP' 'p' 'FQ' 'FS' */
+ qh_PRINTpointnearest, qh_PRINTpoints, qh_PRINTqhull, qh_PRINTsize,
+ qh_PRINTsummary, qh_PRINTtriangles, /* 'Fs' 'Ft' 'Fv' 'FN' 'Fx' */
+ qh_PRINTvertices, qh_PRINTvneighbors, qh_PRINTextremes,
+ qh_PRINTEND} qh_PRINT;
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >--------------------------------</a><a name="qh_ALL">-</a>
+
+ qh_ALL
+ argument flag for selecting everything
+*/
+#define qh_ALL True
+#define qh_NOupper True /* argument for qh_findbest */
+#define qh_IScheckmax True /* argument for qh_findbesthorizon */
+#define qh_ISnewfacets True /* argument for qh_findbest */
+#define qh_RESETvisible True /* argument for qh_resetlists */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >--------------------------------</a><a name="qh_ERR">-</a>
+
+ qh_ERR
+ Qhull exit codes, for indicating errors
+ See: MSG_ERROR and MSG_WARNING [user.h]
+*/
+#define qh_ERRnone 0 /* no error occurred during qhull */
+#define qh_ERRinput 1 /* input inconsistency */
+#define qh_ERRsingular 2 /* singular input data */
+#define qh_ERRprec 3 /* precision error */
+#define qh_ERRmem 4 /* insufficient memory, matches mem_r.h */
+#define qh_ERRqhull 5 /* internal error detected, matches mem_r.h */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+>--------------------------------</a><a name="qh_FILEstderr">-</a>
+
+qh_FILEstderr
+Fake stderr to distinguish error output from normal output
+For C++ interface. Must redefine qh_fprintf_qhull
+*/
+#define qh_FILEstderr ((FILE*)1)
+
+/* ============ -structures- ====================
+ each of the following structures is defined by a typedef
+ all realT and coordT fields occur at the beginning of a structure
+ (otherwise space may be wasted due to alignment)
+ define all flags together and pack into 32-bit number
+
+ DEFqhT and DEFsetT are likewise defined in
+ mem_r.h, qset_r.h, and stat_r.h.
+
+*/
+
+typedef struct vertexT vertexT;
+typedef struct ridgeT ridgeT;
+typedef struct facetT facetT;
+
+#ifndef DEFqhT
+#define DEFqhT 1
+typedef struct qhT qhT; /* defined below */
+#endif
+
+#ifndef DEFsetT
+#define DEFsetT 1
+typedef struct setT setT; /* defined in qset_r.h */
+#endif
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="facetT">-</a>
+
+ facetT
+ defines a facet
+
+ notes:
+ qhull() generates the hull as a list of facets.
+
+ topological information:
+ f.previous,next doubly-linked list of facets
+ f.vertices set of vertices
+ f.ridges set of ridges
+ f.neighbors set of neighbors
+ f.toporient True if facet has top-orientation (else bottom)
+
+ geometric information:
+ f.offset,normal hyperplane equation
+ f.maxoutside offset to outer plane -- all points inside
+ f.center centrum for testing convexity or Voronoi center for output
+ f.simplicial True if facet is simplicial
+ f.flipped True if facet does not include qh.interior_point
+
+ for constructing hull:
+ f.visible True if facet on list of visible facets (will be deleted)
+ f.newfacet True if facet on list of newly created facets
+ f.coplanarset set of points coplanar with this facet
+ (includes near-inside points for later testing)
+ f.outsideset set of points outside of this facet
+ f.furthestdist distance to furthest point of outside set
+ f.visitid marks visited facets during a loop
+ f.replace replacement facet for to-be-deleted, visible facets
+ f.samecycle,newcycle cycle of facets for merging into horizon facet
+
+ see below for other flags and fields
+*/
+struct facetT {
+#if !qh_COMPUTEfurthest
+ coordT furthestdist;/* distance to furthest point of outsideset */
+#endif
+#if qh_MAXoutside
+ coordT maxoutside; /* max computed distance of point to facet
+ Before QHULLfinished this is an approximation
+ since maxdist not always set for mergefacet
+ Actual outer plane is +DISTround and
+ computed outer plane is +2*DISTround */
+#endif
+ coordT offset; /* exact offset of hyperplane from origin */
+ coordT *normal; /* normal of hyperplane, hull_dim coefficients */
+ /* if ->tricoplanar, shared with a neighbor */
+ union { /* in order of testing */
+ realT area; /* area of facet, only in io_r.c if ->isarea */
+ facetT *replace; /* replacement facet if ->visible and NEWfacets
+ is NULL only if qh_mergedegen_redundant or interior */
+ facetT *samecycle; /* cycle of facets from the same visible/horizon intersection,
+ if ->newfacet */
+ facetT *newcycle; /* in horizon facet, current samecycle of new facets */
+ facetT *trivisible; /* visible facet for ->tricoplanar facets during qh_triangulate() */
+ facetT *triowner; /* owner facet for ->tricoplanar, !isarea facets w/ ->keepcentrum */
+ }f;
+ coordT *center; /* set according to qh.CENTERtype */
+ /* qh_ASnone: no center (not MERGING) */
+ /* qh_AScentrum: centrum for testing convexity (qh_getcentrum) */
+ /* assumed qh_AScentrum while merging */
+ /* qh_ASvoronoi: Voronoi center (qh_facetcenter) */
+ /* after constructing the hull, it may be changed (qh_clearcenter) */
+ /* if tricoplanar and !keepcentrum, shared with a neighbor */
+ facetT *previous; /* previous facet in the facet_list */
+ facetT *next; /* next facet in the facet_list */
+ setT *vertices; /* vertices for this facet, inverse sorted by ID
+ if simplicial, 1st vertex was apex/furthest */
+ setT *ridges; /* explicit ridges for nonsimplicial facets.
+ for simplicial facets, neighbors define the ridges */
+ setT *neighbors; /* neighbors of the facet. If simplicial, the kth
+ neighbor is opposite the kth vertex, and the first
+ neighbor is the horizon facet for the first vertex*/
+ setT *outsideset; /* set of points outside this facet
+ if non-empty, last point is furthest
+ if NARROWhull, includes coplanars for partitioning*/
+ setT *coplanarset; /* set of points coplanar with this facet
+ > qh.min_vertex and <= facet->max_outside
+ a point is assigned to the furthest facet
+ if non-empty, last point is furthest away */
+ unsigned visitid; /* visit_id, for visiting all neighbors,
+ all uses are independent */
+ unsigned id; /* unique identifier from qh.facet_id */
+ unsigned nummerge:9; /* number of merges */
+#define qh_MAXnummerge 511 /* 2^9-1, 32 flags total, see "flags:" in io_r.c */
+ flagT tricoplanar:1; /* True if TRIangulate and simplicial and coplanar with a neighbor */
+ /* all tricoplanars share the same apex */
+ /* all tricoplanars share the same ->center, ->normal, ->offset, ->maxoutside */
+ /* ->keepcentrum is true for the owner. It has the ->coplanareset */
+ /* if ->degenerate, does not span facet (one logical ridge) */
+ /* during qh_triangulate, f.trivisible points to original facet */
+ flagT newfacet:1; /* True if facet on qh.newfacet_list (new or merged) */
+ flagT visible:1; /* True if visible facet (will be deleted) */
+ flagT toporient:1; /* True if created with top orientation
+ after merging, use ridge orientation */
+ flagT simplicial:1;/* True if simplicial facet, ->ridges may be implicit */
+ flagT seen:1; /* used to perform operations only once, like visitid */
+ flagT seen2:1; /* used to perform operations only once, like visitid */
+ flagT flipped:1; /* True if facet is flipped */
+ flagT upperdelaunay:1; /* True if facet is upper envelope of Delaunay triangulation */
+ flagT notfurthest:1; /* True if last point of outsideset is not furthest*/
+
+/*-------- flags primarily for output ---------*/
+ flagT good:1; /* True if a facet marked good for output */
+ flagT isarea:1; /* True if facet->f.area is defined */
+
+/*-------- flags for merging ------------------*/
+ flagT dupridge:1; /* True if duplicate ridge in facet */
+ flagT mergeridge:1; /* True if facet or neighbor contains a qh_MERGEridge
+ ->normal defined (also defined for mergeridge2) */
+ flagT mergeridge2:1; /* True if neighbor contains a qh_MERGEridge (qhT *qh, mark_dupridges */
+ flagT coplanar:1; /* True if horizon facet is coplanar at last use */
+ flagT mergehorizon:1; /* True if will merge into horizon (->coplanar) */
+ flagT cycledone:1;/* True if mergecycle_all already done */
+ flagT tested:1; /* True if facet convexity has been tested (false after merge */
+ flagT keepcentrum:1; /* True if keep old centrum after a merge, or marks owner for ->tricoplanar */
+ flagT newmerge:1; /* True if facet is newly merged for reducevertices */
+ flagT degenerate:1; /* True if facet is degenerate (degen_mergeset or ->tricoplanar) */
+ flagT redundant:1; /* True if facet is redundant (degen_mergeset) */
+};
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="ridgeT">-</a>
+
+ ridgeT
+ defines a ridge
+
+ notes:
+ a ridge is hull_dim-1 simplex between two neighboring facets. If the
+ facets are non-simplicial, there may be more than one ridge between
+ two facets. E.G. a 4-d hypercube has two triangles between each pair
+ of neighboring facets.
+
+ topological information:
+ vertices a set of vertices
+ top,bottom neighboring facets with orientation
+
+ geometric information:
+ tested True if ridge is clearly convex
+ nonconvex True if ridge is non-convex
+*/
+struct ridgeT {
+ setT *vertices; /* vertices belonging to this ridge, inverse sorted by ID
+ NULL if a degen ridge (matchsame) */
+ facetT *top; /* top facet this ridge is part of */
+ facetT *bottom; /* bottom facet this ridge is part of */
+ unsigned id; /* unique identifier. Same size as vertex_id and ridge_id */
+ flagT seen:1; /* used to perform operations only once */
+ flagT tested:1; /* True when ridge is tested for convexity */
+ flagT nonconvex:1; /* True if getmergeset detected a non-convex neighbor
+ only one ridge between neighbors may have nonconvex */
+};
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="vertexT">-</a>
+
+ vertexT
+ defines a vertex
+
+ topological information:
+ next,previous doubly-linked list of all vertices
+ neighbors set of adjacent facets (only if qh.VERTEXneighbors)
+
+ geometric information:
+ point array of DIM3 coordinates
+*/
+struct vertexT {
+ vertexT *next; /* next vertex in vertex_list */
+ vertexT *previous; /* previous vertex in vertex_list */
+ pointT *point; /* hull_dim coordinates (coordT) */
+ setT *neighbors; /* neighboring facets of vertex, qh_vertexneighbors()
+ inits in io_r.c or after first merge */
+ unsigned id; /* unique identifier. Same size as qh.vertex_id and qh.ridge_id */
+ unsigned visitid; /* for use with qh.vertex_visit, size must match */
+ flagT seen:1; /* used to perform operations only once */
+ flagT seen2:1; /* another seen flag */
+ flagT delridge:1; /* vertex was part of a deleted ridge */
+ flagT deleted:1; /* true if vertex on qh.del_vertices */
+ flagT newlist:1; /* true if vertex on qh.newvertex_list */
+};
+
+/*======= -global variables -qh ============================*/
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >--------------------------------</a><a name="qh">-</a>
+
+ qhT
+ All global variables for qhull are in qhT. It includes qhmemT, qhstatT, and rbox globals
+
+ This version of Qhull is reentrant, but it is not thread-safe.
+
+ Do not run separate threads on the same instance of qhT.
+
+ QHULL_LIB_CHECK checks that a program and the corresponding
+ qhull library were built with the same type of header files.
+*/
+
+#define QHULL_NON_REENTRANT 0
+#define QHULL_QH_POINTER 1
+#define QHULL_REENTRANT 2
+
+#define QHULL_LIB_TYPE QHULL_REENTRANT
+
+#define QHULL_LIB_CHECK qh_lib_check(QHULL_LIB_TYPE, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), sizeof(setT), sizeof(qhmemT));
+#define QHULL_LIB_CHECK_RBOX qh_lib_check(QHULL_LIB_TYPE, sizeof(qhT), sizeof(vertexT), sizeof(ridgeT), sizeof(facetT), 0, 0);
+
+struct qhT {
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >--------------------------------</a><a name="qh-const">-</a>
+
+ qh constants
+ configuration flags and constants for Qhull
+
+ notes:
+ The user configures Qhull by defining flags. They are
+ copied into qh by qh_setflags(). qh-quick_r.htm#options defines the flags.
+*/
+ boolT ALLpoints; /* true 'Qs' if search all points for initial simplex */
+ boolT ANGLEmerge; /* true 'Qa' if sort potential merges by angle */
+ boolT APPROXhull; /* true 'Wn' if MINoutside set */
+ realT MINoutside; /* 'Wn' min. distance for an outside point */
+ boolT ANNOTATEoutput; /* true 'Ta' if annotate output with message codes */
+ boolT ATinfinity; /* true 'Qz' if point num_points-1 is "at-infinity"
+ for improving precision in Delaunay triangulations */
+ boolT AVOIDold; /* true 'Q4' if avoid old->new merges */
+ boolT BESToutside; /* true 'Qf' if partition points into best outsideset */
+ boolT CDDinput; /* true 'Pc' if input uses CDD format (1.0/offset first) */
+ boolT CDDoutput; /* true 'PC' if print normals in CDD format (offset first) */
+ boolT CHECKfrequently; /* true 'Tc' if checking frequently */
+ realT premerge_cos; /* 'A-n' cos_max when pre merging */
+ realT postmerge_cos; /* 'An' cos_max when post merging */
+ boolT DELAUNAY; /* true 'd' if computing DELAUNAY triangulation */
+ boolT DOintersections; /* true 'Gh' if print hyperplane intersections */
+ int DROPdim; /* drops dim 'GDn' for 4-d -> 3-d output */
+ boolT FORCEoutput; /* true 'Po' if forcing output despite degeneracies */
+ int GOODpoint; /* 1+n for 'QGn', good facet if visible/not(-) from point n*/
+ pointT *GOODpointp; /* the actual point */
+ boolT GOODthreshold; /* true if qh.lower_threshold/upper_threshold defined
+ false if qh.SPLITthreshold */
+ int GOODvertex; /* 1+n, good facet if vertex for point n */
+ pointT *GOODvertexp; /* the actual point */
+ boolT HALFspace; /* true 'Hn,n,n' if halfspace intersection */
+ boolT ISqhullQh; /* Set by Qhull.cpp on initialization */
+ int IStracing; /* trace execution, 0=none, 1=least, 4=most, -1=events */
+ int KEEParea; /* 'PAn' number of largest facets to keep */
+ boolT KEEPcoplanar; /* true 'Qc' if keeping nearest facet for coplanar points */
+ boolT KEEPinside; /* true 'Qi' if keeping nearest facet for inside points
+ set automatically if 'd Qc' */
+ int KEEPmerge; /* 'PMn' number of facets to keep with most merges */
+ realT KEEPminArea; /* 'PFn' minimum facet area to keep */
+ realT MAXcoplanar; /* 'Un' max distance below a facet to be coplanar*/
+ boolT MERGEexact; /* true 'Qx' if exact merges (coplanar, degen, dupridge, flipped) */
+ boolT MERGEindependent; /* true 'Q2' if merging independent sets */
+ boolT MERGING; /* true if exact-, pre- or post-merging, with angle and centrum tests */
+ realT premerge_centrum; /* 'C-n' centrum_radius when pre merging. Default is round-off */
+ realT postmerge_centrum; /* 'Cn' centrum_radius when post merging. Default is round-off */
+ boolT MERGEvertices; /* true 'Q3' if merging redundant vertices */
+ realT MINvisible; /* 'Vn' min. distance for a facet to be visible */
+ boolT NOnarrow; /* true 'Q10' if no special processing for narrow distributions */
+ boolT NOnearinside; /* true 'Q8' if ignore near-inside points when partitioning */
+ boolT NOpremerge; /* true 'Q0' if no defaults for C-0 or Qx */
+ boolT NOwide; /* true 'Q12' if no error on wide merge due to duplicate ridge */
+ boolT ONLYgood; /* true 'Qg' if process points with good visible or horizon facets */
+ boolT ONLYmax; /* true 'Qm' if only process points that increase max_outside */
+ boolT PICKfurthest; /* true 'Q9' if process furthest of furthest points*/
+ boolT POSTmerge; /* true if merging after buildhull (Cn or An) */
+ boolT PREmerge; /* true if merging during buildhull (C-n or A-n) */
+ /* NOTE: some of these names are similar to qh_PRINT names */
+ boolT PRINTcentrums; /* true 'Gc' if printing centrums */
+ boolT PRINTcoplanar; /* true 'Gp' if printing coplanar points */
+ int PRINTdim; /* print dimension for Geomview output */
+ boolT PRINTdots; /* true 'Ga' if printing all points as dots */
+ boolT PRINTgood; /* true 'Pg' if printing good facets */
+ boolT PRINTinner; /* true 'Gi' if printing inner planes */
+ boolT PRINTneighbors; /* true 'PG' if printing neighbors of good facets */
+ boolT PRINTnoplanes; /* true 'Gn' if printing no planes */
+ boolT PRINToptions1st; /* true 'FO' if printing options to stderr */
+ boolT PRINTouter; /* true 'Go' if printing outer planes */
+ boolT PRINTprecision; /* false 'Pp' if not reporting precision problems */
+ qh_PRINT PRINTout[qh_PRINTEND]; /* list of output formats to print */
+ boolT PRINTridges; /* true 'Gr' if print ridges */
+ boolT PRINTspheres; /* true 'Gv' if print vertices as spheres */
+ boolT PRINTstatistics; /* true 'Ts' if printing statistics to stderr */
+ boolT PRINTsummary; /* true 's' if printing summary to stderr */
+ boolT PRINTtransparent; /* true 'Gt' if print transparent outer ridges */
+ boolT PROJECTdelaunay; /* true if DELAUNAY, no readpoints() and
+ need projectinput() for Delaunay in qh_init_B */
+ int PROJECTinput; /* number of projected dimensions 'bn:0Bn:0' */
+ boolT QUICKhelp; /* true if quick help message for degen input */
+ boolT RANDOMdist; /* true if randomly change distplane and setfacetplane */
+ realT RANDOMfactor; /* maximum random perturbation */
+ realT RANDOMa; /* qh_randomfactor is randr * RANDOMa + RANDOMb */
+ realT RANDOMb;
+ boolT RANDOMoutside; /* true if select a random outside point */
+ int REPORTfreq; /* buildtracing reports every n facets */
+ int REPORTfreq2; /* tracemerging reports every REPORTfreq/2 facets */
+ int RERUN; /* 'TRn' rerun qhull n times (qh.build_cnt) */
+ int ROTATErandom; /* 'QRn' seed, 0 time, >= rotate input */
+ boolT SCALEinput; /* true 'Qbk' if scaling input */
+ boolT SCALElast; /* true 'Qbb' if scale last coord to max prev coord */
+ boolT SETroundoff; /* true 'E' if qh.DISTround is predefined */
+ boolT SKIPcheckmax; /* true 'Q5' if skip qh_check_maxout */
+ boolT SKIPconvex; /* true 'Q6' if skip convexity testing during pre-merge */
+ boolT SPLITthresholds; /* true if upper_/lower_threshold defines a region
+ used only for printing (!for qh.ONLYgood) */
+ int STOPcone; /* 'TCn' 1+n for stopping after cone for point n */
+ /* also used by qh_build_withresart for err exit*/
+ int STOPpoint; /* 'TVn' 'TV-n' 1+n for stopping after/before(-)
+ adding point n */
+ int TESTpoints; /* 'QTn' num of test points after qh.num_points. Test points always coplanar. */
+ boolT TESTvneighbors; /* true 'Qv' if test vertex neighbors at end */
+ int TRACElevel; /* 'Tn' conditional IStracing level */
+ int TRACElastrun; /* qh.TRACElevel applies to last qh.RERUN */
+ int TRACEpoint; /* 'TPn' start tracing when point n is a vertex */
+ realT TRACEdist; /* 'TWn' start tracing when merge distance too big */
+ int TRACEmerge; /* 'TMn' start tracing before this merge */
+ boolT TRIangulate; /* true 'Qt' if triangulate non-simplicial facets */
+ boolT TRInormals; /* true 'Q11' if triangulate duplicates ->normal and ->center (sets Qt) */
+ boolT UPPERdelaunay; /* true 'Qu' if computing furthest-site Delaunay */
+ boolT USEstdout; /* true 'Tz' if using stdout instead of stderr */
+ boolT VERIFYoutput; /* true 'Tv' if verify output at end of qhull */
+ boolT VIRTUALmemory; /* true 'Q7' if depth-first processing in buildhull */
+ boolT VORONOI; /* true 'v' if computing Voronoi diagram */
+
+ /*--------input constants ---------*/
+ realT AREAfactor; /* 1/(hull_dim-1)! for converting det's to area */
+ boolT DOcheckmax; /* true if calling qh_check_maxout (qhT *qh, qh_initqhull_globals) */
+ char *feasible_string; /* feasible point 'Hn,n,n' for halfspace intersection */
+ coordT *feasible_point; /* as coordinates, both malloc'd */
+ boolT GETarea; /* true 'Fa', 'FA', 'FS', 'PAn', 'PFn' if compute facet area/Voronoi volume in io_r.c */
+ boolT KEEPnearinside; /* true if near-inside points in coplanarset */
+ int hull_dim; /* dimension of hull, set by initbuffers */
+ int input_dim; /* dimension of input, set by initbuffers */
+ int num_points; /* number of input points */
+ pointT *first_point; /* array of input points, see POINTSmalloc */
+ boolT POINTSmalloc; /* true if qh.first_point/num_points allocated */
+ pointT *input_points; /* copy of original qh.first_point for input points for qh_joggleinput */
+ boolT input_malloc; /* true if qh.input_points malloc'd */
+ char qhull_command[256];/* command line that invoked this program */
+ int qhull_commandsiz2; /* size of qhull_command at qh_clear_outputflags */
+ char rbox_command[256]; /* command line that produced the input points */
+ char qhull_options[512];/* descriptive list of options */
+ int qhull_optionlen; /* length of last line */
+ int qhull_optionsiz; /* size of qhull_options at qh_build_withrestart */
+ int qhull_optionsiz2; /* size of qhull_options at qh_clear_outputflags */
+ int run_id; /* non-zero, random identifier for this instance of qhull */
+ boolT VERTEXneighbors; /* true if maintaining vertex neighbors */
+ boolT ZEROcentrum; /* true if 'C-0' or 'C-0 Qx'. sets ZEROall_ok */
+ realT *upper_threshold; /* don't print if facet->normal[k]>=upper_threshold[k]
+ must set either GOODthreshold or SPLITthreshold
+ if Delaunay, default is 0.0 for upper envelope */
+ realT *lower_threshold; /* don't print if facet->normal[k] <=lower_threshold[k] */
+ realT *upper_bound; /* scale point[k] to new upper bound */
+ realT *lower_bound; /* scale point[k] to new lower bound
+ project if both upper_ and lower_bound == 0 */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >--------------------------------</a><a name="qh-prec">-</a>
+
+ qh precision constants
+ precision constants for Qhull
+
+ notes:
+ qh_detroundoff(qh) computes the maximum roundoff error for distance
+ and other computations. It also sets default values for the
+ qh constants above.
+*/
+ realT ANGLEround; /* max round off error for angles */
+ realT centrum_radius; /* max centrum radius for convexity (roundoff added) */
+ realT cos_max; /* max cosine for convexity (roundoff added) */
+ realT DISTround; /* max round off error for distances, 'E' overrides qh_distround() */
+ realT MAXabs_coord; /* max absolute coordinate */
+ realT MAXlastcoord; /* max last coordinate for qh_scalelast */
+ realT MAXsumcoord; /* max sum of coordinates */
+ realT MAXwidth; /* max rectilinear width of point coordinates */
+ realT MINdenom_1; /* min. abs. value for 1/x */
+ realT MINdenom; /* use divzero if denominator < MINdenom */
+ realT MINdenom_1_2; /* min. abs. val for 1/x that allows normalization */
+ realT MINdenom_2; /* use divzero if denominator < MINdenom_2 */
+ realT MINlastcoord; /* min. last coordinate for qh_scalelast */
+ boolT NARROWhull; /* set in qh_initialhull if angle < qh_MAXnarrow */
+ realT *NEARzero; /* hull_dim array for near zero in gausselim */
+ realT NEARinside; /* keep points for qh_check_maxout if close to facet */
+ realT ONEmerge; /* max distance for merging simplicial facets */
+ realT outside_err; /* application's epsilon for coplanar points
+ qh_check_bestdist() qh_check_points() reports error if point outside */
+ realT WIDEfacet; /* size of wide facet for skipping ridge in
+ area computation and locking centrum */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >--------------------------------</a><a name="qh-codetern">-</a>
+
+ qh internal constants
+ internal constants for Qhull
+*/
+ char qhull[sizeof("qhull")]; /* "qhull" for checking ownership while debugging */
+ jmp_buf errexit; /* exit label for qh_errexit, defined by setjmp() and NOerrexit */
+ char jmpXtra[40]; /* extra bytes in case jmp_buf is defined wrong by compiler */
+ jmp_buf restartexit; /* restart label for qh_errexit, defined by setjmp() and ALLOWrestart */
+ char jmpXtra2[40]; /* extra bytes in case jmp_buf is defined wrong by compiler*/
+ FILE *fin; /* pointer to input file, init by qh_initqhull_start */
+ FILE *fout; /* pointer to output file */
+ FILE *ferr; /* pointer to error file */
+ pointT *interior_point; /* center point of the initial simplex*/
+ int normal_size; /* size in bytes for facet normals and point coords*/
+ int center_size; /* size in bytes for Voronoi centers */
+ int TEMPsize; /* size for small, temporary sets (in quick mem) */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >--------------------------------</a><a name="qh-lists">-</a>
+
+ qh facet and vertex lists
+ defines lists of facets, new facets, visible facets, vertices, and
+ new vertices. Includes counts, next ids, and trace ids.
+ see:
+ qh_resetlists()
+*/
+ facetT *facet_list; /* first facet */
+ facetT *facet_tail; /* end of facet_list (dummy facet) */
+ facetT *facet_next; /* next facet for buildhull()
+ previous facets do not have outside sets
+ NARROWhull: previous facets may have coplanar outside sets for qh_outcoplanar */
+ facetT *newfacet_list; /* list of new facets to end of facet_list */
+ facetT *visible_list; /* list of visible facets preceding newfacet_list,
+ facet->visible set */
+ int num_visible; /* current number of visible facets */
+ unsigned tracefacet_id; /* set at init, then can print whenever */
+ facetT *tracefacet; /* set in newfacet/mergefacet, undone in delfacet*/
+ unsigned tracevertex_id; /* set at buildtracing, can print whenever */
+ vertexT *tracevertex; /* set in newvertex, undone in delvertex*/
+ vertexT *vertex_list; /* list of all vertices, to vertex_tail */
+ vertexT *vertex_tail; /* end of vertex_list (dummy vertex) */
+ vertexT *newvertex_list; /* list of vertices in newfacet_list, to vertex_tail
+ all vertices have 'newlist' set */
+ int num_facets; /* number of facets in facet_list
+ includes visible faces (num_visible) */
+ int num_vertices; /* number of vertices in facet_list */
+ int num_outside; /* number of points in outsidesets (for tracing and RANDOMoutside)
+ includes coplanar outsideset points for NARROWhull/qh_outcoplanar() */
+ int num_good; /* number of good facets (after findgood_all) */
+ unsigned facet_id; /* ID of next, new facet from newfacet() */
+ unsigned ridge_id; /* ID of next, new ridge from newridge() */
+ unsigned vertex_id; /* ID of next, new vertex from newvertex() */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >--------------------------------</a><a name="qh-var">-</a>
+
+ qh global variables
+ defines minimum and maximum distances, next visit ids, several flags,
+ and other global variables.
+ initialize in qh_initbuild or qh_maxmin if used in qh_buildhull
+*/
+ unsigned long hulltime; /* ignore time to set up input and randomize */
+ /* use unsigned to avoid wrap-around errors */
+ boolT ALLOWrestart; /* true if qh_precision can use qh.restartexit */
+ int build_cnt; /* number of calls to qh_initbuild */
+ qh_CENTER CENTERtype; /* current type of facet->center, qh_CENTER */
+ int furthest_id; /* pointid of furthest point, for tracing */
+ facetT *GOODclosest; /* closest facet to GOODthreshold in qh_findgood */
+ boolT hasAreaVolume; /* true if totarea, totvol was defined by qh_getarea */
+ boolT hasTriangulation; /* true if triangulation created by qh_triangulate */
+ realT JOGGLEmax; /* set 'QJn' if randomly joggle input */
+ boolT maxoutdone; /* set qh_check_maxout(), cleared by qh_addpoint() */
+ realT max_outside; /* maximum distance from a point to a facet,
+ before roundoff, not simplicial vertices
+ actual outer plane is +DISTround and
+ computed outer plane is +2*DISTround */
+ realT max_vertex; /* maximum distance (>0) from vertex to a facet,
+ before roundoff, due to a merge */
+ realT min_vertex; /* minimum distance (<0) from vertex to a facet,
+ before roundoff, due to a merge
+ if qh.JOGGLEmax, qh_makenewplanes sets it
+ recomputed if qh.DOcheckmax, default -qh.DISTround */
+ boolT NEWfacets; /* true while visible facets invalid due to new or merge
+ from makecone/attachnewfacets to deletevisible */
+ boolT findbestnew; /* true if partitioning calls qh_findbestnew */
+ boolT findbest_notsharp; /* true if new facets are at least 90 degrees */
+ boolT NOerrexit; /* true if qh.errexit is not available, cleared after setjmp */
+ realT PRINTcradius; /* radius for printing centrums */
+ realT PRINTradius; /* radius for printing vertex spheres and points */
+ boolT POSTmerging; /* true when post merging */
+ int printoutvar; /* temporary variable for qh_printbegin, etc. */
+ int printoutnum; /* number of facets printed */
+ boolT QHULLfinished; /* True after qhull() is finished */
+ realT totarea; /* 'FA': total facet area computed by qh_getarea, hasAreaVolume */
+ realT totvol; /* 'FA': total volume computed by qh_getarea, hasAreaVolume */
+ unsigned int visit_id; /* unique ID for searching neighborhoods, */
+ unsigned int vertex_visit; /* unique ID for searching vertices, reset with qh_buildtracing */
+ boolT ZEROall_ok; /* True if qh_checkzero always succeeds */
+ boolT WAScoplanar; /* True if qh_partitioncoplanar (qhT *qh, qh_check_maxout) */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >--------------------------------</a><a name="qh-set">-</a>
+
+ qh global sets
+ defines sets for merging, initial simplex, hashing, extra input points,
+ and deleted vertices
+*/
+ setT *facet_mergeset; /* temporary set of merges to be done */
+ setT *degen_mergeset; /* temporary set of degenerate and redundant merges */
+ setT *hash_table; /* hash table for matching ridges in qh_matchfacets
+ size is setsize() */
+ setT *other_points; /* additional points */
+ setT *del_vertices; /* vertices to partition and delete with visible
+ facets. Have deleted set for checkfacet */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >--------------------------------</a><a name="qh-buf">-</a>
+
+ qh global buffers
+ defines buffers for maxtrix operations, input, and error messages
+*/
+ coordT *gm_matrix; /* (dim+1)Xdim matrix for geom_r.c */
+ coordT **gm_row; /* array of gm_matrix rows */
+ char* line; /* malloc'd input line of maxline+1 chars */
+ int maxline;
+ coordT *half_space; /* malloc'd input array for halfspace (qh.normal_size+coordT) */
+ coordT *temp_malloc; /* malloc'd input array for points */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >--------------------------------</a><a name="qh-static">-</a>
+
+ qh static variables
+ defines static variables for individual functions
+
+ notes:
+ do not use 'static' within a function. Multiple instances of qhull
+ may exist.
+
+ do not assume zero initialization, 'QPn' may cause a restart
+*/
+ boolT ERREXITcalled; /* true during qh_errexit (qhT *qh, prevents duplicate calls */
+ boolT firstcentrum; /* for qh_printcentrum */
+ boolT old_randomdist; /* save RANDOMdist flag during io, tracing, or statistics */
+ setT *coplanarfacetset; /* set of coplanar facets for searching qh_findbesthorizon() */
+ realT last_low; /* qh_scalelast parameters for qh_setdelaunay */
+ realT last_high;
+ realT last_newhigh;
+ unsigned lastreport; /* for qh_buildtracing */
+ int mergereport; /* for qh_tracemerging */
+ setT *old_tempstack; /* for saving qh->qhmem.tempstack in save_qhull */
+ int ridgeoutnum; /* number of ridges for 4OFF output (qh_printbegin,etc) */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >--------------------------------</a><a name="qh-const">-</a>
+
+ qh memory management, rbox globals, and statistics
+
+ Replaces global data structures defined for libqhull
+*/
+ int last_random; /* Last random number from qh_rand (random_r.c) */
+ jmp_buf rbox_errexit; /* errexit from rboxlib_r.c, defined by qh_rboxpoints() only */
+ char jmpXtra3[40]; /* extra bytes in case jmp_buf is defined wrong by compiler */
+ int rbox_isinteger;
+ double rbox_out_offset;
+ void * cpp_object; /* C++ pointer. Currently used by RboxPoints.qh_fprintf_rbox */
+
+ /* Last, otherwise zero'd by qh_initqhull_start2 (global_r.c */
+ qhmemT qhmem; /* Qhull managed memory (mem_r.h) */
+ /* After qhmem because its size depends on the number of statistics */
+ qhstatT qhstat; /* Qhull statistics (stat_r.h) */
+};
+
+/*=========== -macros- =========================*/
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="otherfacet_">-</a>
+
+ otherfacet_(ridge, facet)
+ return neighboring facet for a ridge in facet
+*/
+#define otherfacet_(ridge, facet) \
+ (((ridge)->top == (facet)) ? (ridge)->bottom : (ridge)->top)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="getid_">-</a>
+
+ getid_(p)
+ return int ID for facet, ridge, or vertex
+ return qh_IDunknown(-1) if NULL
+*/
+#define getid_(p) ((p) ? (int)((p)->id) : qh_IDunknown)
+
+/*============== FORALL macros ===================*/
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FORALLfacets">-</a>
+
+ FORALLfacets { ... }
+ assign 'facet' to each facet in qh.facet_list
+
+ notes:
+ uses 'facetT *facet;'
+ assumes last facet is a sentinel
+ assumes qh defined
+
+ see:
+ FORALLfacet_( facetlist )
+*/
+#define FORALLfacets for (facet=qh->facet_list;facet && facet->next;facet=facet->next)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FORALLpoints">-</a>
+
+ FORALLpoints { ... }
+ assign 'point' to each point in qh.first_point, qh.num_points
+
+ notes:
+ assumes qh defined
+
+ declare:
+ coordT *point, *pointtemp;
+*/
+#define FORALLpoints FORALLpoint_(qh, qh->first_point, qh->num_points)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FORALLpoint_">-</a>
+
+ FORALLpoint_( qh, points, num) { ... }
+ assign 'point' to each point in points array of num points
+
+ declare:
+ coordT *point, *pointtemp;
+*/
+#define FORALLpoint_(qh, points, num) for (point= (points), \
+ pointtemp= (points)+qh->hull_dim*(num); point < pointtemp; point += qh->hull_dim)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FORALLvertices">-</a>
+
+ FORALLvertices { ... }
+ assign 'vertex' to each vertex in qh.vertex_list
+
+ declare:
+ vertexT *vertex;
+
+ notes:
+ assumes qh.vertex_list terminated with a sentinel
+ assumes qh defined
+*/
+#define FORALLvertices for (vertex=qh->vertex_list;vertex && vertex->next;vertex= vertex->next)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHfacet_">-</a>
+
+ FOREACHfacet_( facets ) { ... }
+ assign 'facet' to each facet in facets
+
+ declare:
+ facetT *facet, **facetp;
+
+ see:
+ <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHfacet_(facets) FOREACHsetelement_(facetT, facets, facet)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHneighbor_">-</a>
+
+ FOREACHneighbor_( facet ) { ... }
+ assign 'neighbor' to each neighbor in facet->neighbors
+
+ FOREACHneighbor_( vertex ) { ... }
+ assign 'neighbor' to each neighbor in vertex->neighbors
+
+ declare:
+ facetT *neighbor, **neighborp;
+
+ see:
+ <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHneighbor_(facet) FOREACHsetelement_(facetT, facet->neighbors, neighbor)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHpoint_">-</a>
+
+ FOREACHpoint_( points ) { ... }
+ assign 'point' to each point in points set
+
+ declare:
+ pointT *point, **pointp;
+
+ see:
+ <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHpoint_(points) FOREACHsetelement_(pointT, points, point)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHridge_">-</a>
+
+ FOREACHridge_( ridges ) { ... }
+ assign 'ridge' to each ridge in ridges set
+
+ declare:
+ ridgeT *ridge, **ridgep;
+
+ see:
+ <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHridge_(ridges) FOREACHsetelement_(ridgeT, ridges, ridge)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHvertex_">-</a>
+
+ FOREACHvertex_( vertices ) { ... }
+ assign 'vertex' to each vertex in vertices set
+
+ declare:
+ vertexT *vertex, **vertexp;
+
+ see:
+ <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHvertex_(vertices) FOREACHsetelement_(vertexT, vertices,vertex)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHfacet_i_">-</a>
+
+ FOREACHfacet_i_( qh, facets ) { ... }
+ assign 'facet' and 'facet_i' for each facet in facets set
+
+ declare:
+ facetT *facet;
+ int facet_n, facet_i;
+
+ see:
+ <a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+*/
+#define FOREACHfacet_i_(qh, facets) FOREACHsetelement_i_(qh, facetT, facets, facet)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHneighbor_i_">-</a>
+
+ FOREACHneighbor_i_( qh, facet ) { ... }
+ assign 'neighbor' and 'neighbor_i' for each neighbor in facet->neighbors
+
+ FOREACHneighbor_i_( qh, vertex ) { ... }
+ assign 'neighbor' and 'neighbor_i' for each neighbor in vertex->neighbors
+
+ declare:
+ facetT *neighbor;
+ int neighbor_n, neighbor_i;
+
+ see:
+ <a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+*/
+#define FOREACHneighbor_i_(qh, facet) FOREACHsetelement_i_(qh, facetT, facet->neighbors, neighbor)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHpoint_i_">-</a>
+
+ FOREACHpoint_i_( qh, points ) { ... }
+ assign 'point' and 'point_i' for each point in points set
+
+ declare:
+ pointT *point;
+ int point_n, point_i;
+
+ see:
+ <a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+*/
+#define FOREACHpoint_i_(qh, points) FOREACHsetelement_i_(qh, pointT, points, point)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHridge_i_">-</a>
+
+ FOREACHridge_i_( qh, ridges ) { ... }
+ assign 'ridge' and 'ridge_i' for each ridge in ridges set
+
+ declare:
+ ridgeT *ridge;
+ int ridge_n, ridge_i;
+
+ see:
+ <a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+*/
+#define FOREACHridge_i_(qh, ridges) FOREACHsetelement_i_(qh, ridgeT, ridges, ridge)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHvertex_i_">-</a>
+
+ FOREACHvertex_i_( qh, vertices ) { ... }
+ assign 'vertex' and 'vertex_i' for each vertex in vertices set
+
+ declare:
+ vertexT *vertex;
+ int vertex_n, vertex_i;
+
+ see:
+ <a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+*/
+#define FOREACHvertex_i_(qh, vertices) FOREACHsetelement_i_(qh, vertexT, vertices,vertex)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/********* -libqhull_r.c prototypes (duplicated from qhull_ra.h) **********************/
+
+void qh_qhull(qhT *qh);
+boolT qh_addpoint(qhT *qh, pointT *furthest, facetT *facet, boolT checkdist);
+void qh_printsummary(qhT *qh, FILE *fp);
+
+/********* -user.c prototypes (alphabetical) **********************/
+
+void qh_errexit(qhT *qh, int exitcode, facetT *facet, ridgeT *ridge);
+void qh_errprint(qhT *qh, const char* string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex);
+int qh_new_qhull(qhT *qh, int dim, int numpoints, coordT *points, boolT ismalloc,
+ char *qhull_cmd, FILE *outfile, FILE *errfile);
+void qh_printfacetlist(qhT *qh, facetT *facetlist, setT *facets, boolT printall);
+void qh_printhelp_degenerate(qhT *qh, FILE *fp);
+void qh_printhelp_narrowhull(qhT *qh, FILE *fp, realT minangle);
+void qh_printhelp_singular(qhT *qh, FILE *fp);
+void qh_user_memsizes(qhT *qh);
+
+/********* -usermem_r.c prototypes (alphabetical) **********************/
+void qh_exit(int exitcode);
+void qh_fprintf_stderr(int msgcode, const char *fmt, ... );
+void qh_free(void *mem);
+void *qh_malloc(size_t size);
+
+/********* -userprintf_r.c and userprintf_rbox_r.c prototypes **********************/
+void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
+void qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
+
+/***** -geom_r.c/geom2_r.c/random_r.c prototypes (duplicated from geom_r.h, random_r.h) ****************/
+
+facetT *qh_findbest(qhT *qh, pointT *point, facetT *startfacet,
+ boolT bestoutside, boolT newfacets, boolT noupper,
+ realT *dist, boolT *isoutside, int *numpart);
+facetT *qh_findbestnew(qhT *qh, pointT *point, facetT *startfacet,
+ realT *dist, boolT bestoutside, boolT *isoutside, int *numpart);
+boolT qh_gram_schmidt(qhT *qh, int dim, realT **rows);
+void qh_outerinner(qhT *qh, facetT *facet, realT *outerplane, realT *innerplane);
+void qh_printsummary(qhT *qh, FILE *fp);
+void qh_projectinput(qhT *qh);
+void qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **row);
+void qh_rotateinput(qhT *qh, realT **rows);
+void qh_scaleinput(qhT *qh);
+void qh_setdelaunay(qhT *qh, int dim, int count, pointT *points);
+coordT *qh_sethalfspace_all(qhT *qh, int dim, int count, coordT *halfspaces, pointT *feasible);
+
+/***** -global_r.c prototypes (alphabetical) ***********************/
+
+unsigned long qh_clock(qhT *qh);
+void qh_checkflags(qhT *qh, char *command, char *hiddenflags);
+void qh_clear_outputflags(qhT *qh);
+void qh_freebuffers(qhT *qh);
+void qh_freeqhull(qhT *qh, boolT allmem);
+void qh_init_A(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile, int argc, char *argv[]);
+void qh_init_B(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
+void qh_init_qhull_command(qhT *qh, int argc, char *argv[]);
+void qh_initbuffers(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
+void qh_initflags(qhT *qh, char *command);
+void qh_initqhull_buffers(qhT *qh);
+void qh_initqhull_globals(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
+void qh_initqhull_mem(qhT *qh);
+void qh_initqhull_outputflags(qhT *qh);
+void qh_initqhull_start(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile);
+void qh_initqhull_start2(qhT *qh, FILE *infile, FILE *outfile, FILE *errfile);
+void qh_initthresholds(qhT *qh, char *command);
+void qh_lib_check(int qhullLibraryType, int qhTsize, int vertexTsize, int ridgeTsize, int facetTsize, int setTsize, int qhmemTsize);
+void qh_option(qhT *qh, const char *option, int *i, realT *r);
+void qh_zero(qhT *qh, FILE *errfile);
+
+/***** -io_r.c prototypes (duplicated from io_r.h) ***********************/
+
+void qh_dfacet(qhT *qh, unsigned id);
+void qh_dvertex(qhT *qh, unsigned id);
+void qh_printneighborhood(qhT *qh, FILE *fp, qh_PRINT format, facetT *facetA, facetT *facetB, boolT printall);
+void qh_produce_output(qhT *qh);
+coordT *qh_readpoints(qhT *qh, int *numpoints, int *dimension, boolT *ismalloc);
+
+
+/********* -mem_r.c prototypes (duplicated from mem_r.h) **********************/
+
+void qh_meminit(qhT *qh, FILE *ferr);
+void qh_memfreeshort(qhT *qh, int *curlong, int *totlong);
+
+/********* -poly_r.c/poly2_r.c prototypes (duplicated from poly_r.h) **********************/
+
+void qh_check_output(qhT *qh);
+void qh_check_points(qhT *qh);
+setT *qh_facetvertices(qhT *qh, facetT *facetlist, setT *facets, boolT allfacets);
+facetT *qh_findbestfacet(qhT *qh, pointT *point, boolT bestoutside,
+ realT *bestdist, boolT *isoutside);
+vertexT *qh_nearvertex(qhT *qh, facetT *facet, pointT *point, realT *bestdistp);
+pointT *qh_point(qhT *qh, int id);
+setT *qh_pointfacet(qhT *qh /*qh.facet_list*/);
+int qh_pointid(qhT *qh, pointT *point);
+setT *qh_pointvertex(qhT *qh /*qh.facet_list*/);
+void qh_setvoronoi_all(qhT *qh);
+void qh_triangulate(qhT *qh /*qh.facet_list*/);
+
+/********* -rboxpoints_r.c prototypes **********************/
+int qh_rboxpoints(qhT *qh, char* rbox_command);
+void qh_errexit_rbox(qhT *qh, int exitcode);
+
+/********* -stat_r.c prototypes (duplicated from stat_r.h) **********************/
+
+void qh_collectstatistics(qhT *qh);
+void qh_printallstatistics(qhT *qh, FILE *fp, const char *string);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* qhDEFlibqhull */
diff --git a/xs/src/qhull/src/libqhull_r/libqhull_r.pro b/xs/src/qhull/src/libqhull_r/libqhull_r.pro
new file mode 100644
index 000000000..6b8db44b7
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/libqhull_r.pro
@@ -0,0 +1,67 @@
+# -------------------------------------------------
+# libqhull_r.pro -- Qt project for Qhull shared library
+#
+# It uses reentrant Qhull
+# -------------------------------------------------
+
+include(../qhull-warn.pri)
+
+DESTDIR = ../../lib
+DLLDESTDIR = ../../bin
+TEMPLATE = lib
+CONFIG += shared warn_on
+CONFIG -= qt
+
+build_pass:CONFIG(debug, debug|release):{
+ TARGET = qhull_rd
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release):{
+ TARGET = qhull_r
+ OBJECTS_DIR = Release
+}
+win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
+
+win32-msvc* : DEF_FILE += ../../src/libqhull_r/qhull_r-exports.def
+
+# libqhull_r/libqhull_r.pro and ../qhull-libqhull-src_r.pri have the same SOURCES and HEADERS
+
+SOURCES += ../libqhull_r/global_r.c
+SOURCES += ../libqhull_r/stat_r.c
+SOURCES += ../libqhull_r/geom2_r.c
+SOURCES += ../libqhull_r/poly2_r.c
+SOURCES += ../libqhull_r/merge_r.c
+SOURCES += ../libqhull_r/libqhull_r.c
+SOURCES += ../libqhull_r/geom_r.c
+SOURCES += ../libqhull_r/poly_r.c
+SOURCES += ../libqhull_r/qset_r.c
+SOURCES += ../libqhull_r/mem_r.c
+SOURCES += ../libqhull_r/random_r.c
+SOURCES += ../libqhull_r/usermem_r.c
+SOURCES += ../libqhull_r/userprintf_r.c
+SOURCES += ../libqhull_r/io_r.c
+SOURCES += ../libqhull_r/user_r.c
+SOURCES += ../libqhull_r/rboxlib_r.c
+SOURCES += ../libqhull_r/userprintf_rbox_r.c
+
+HEADERS += ../libqhull_r/geom_r.h
+HEADERS += ../libqhull_r/io_r.h
+HEADERS += ../libqhull_r/libqhull_r.h
+HEADERS += ../libqhull_r/mem_r.h
+HEADERS += ../libqhull_r/merge_r.h
+HEADERS += ../libqhull_r/poly_r.h
+HEADERS += ../libqhull_r/random_r.h
+HEADERS += ../libqhull_r/qhull_ra.h
+HEADERS += ../libqhull_r/qset_r.h
+HEADERS += ../libqhull_r/stat_r.h
+HEADERS += ../libqhull_r/user_r.h
+
+OTHER_FILES += qh-geom_r.htm
+OTHER_FILES += qh-globa_r.htm
+OTHER_FILES += qh-io_r.htm
+OTHER_FILES += qh-mem_r.htm
+OTHER_FILES += qh-merge_r.htm
+OTHER_FILES += qh-poly_r.htm
+OTHER_FILES += qh-qhull_r.htm
+OTHER_FILES += qh-set_r.htm
+OTHER_FILES += qh-stat_r.htm
+OTHER_FILES += qh-user_r.htm
diff --git a/xs/src/qhull/src/libqhull_r/mem_r.c b/xs/src/qhull/src/libqhull_r/mem_r.c
new file mode 100644
index 000000000..801a8c76a
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/mem_r.c
@@ -0,0 +1,562 @@
+/*<html><pre> -<a href="qh-mem_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ mem_r.c
+ memory management routines for qhull
+
+ See libqhull/mem_r.c for a standalone program.
+
+ To initialize memory:
+
+ qh_meminit(qh, stderr);
+ qh_meminitbuffers(qh, qh->IStracing, qh_MEMalign, 7, qh_MEMbufsize,qh_MEMinitbuf);
+ qh_memsize(qh, (int)sizeof(facetT));
+ qh_memsize(qh, (int)sizeof(facetT));
+ ...
+ qh_memsetup(qh);
+
+ To free up all memory buffers:
+ qh_memfreeshort(qh, &curlong, &totlong);
+
+ if qh_NOmem,
+ malloc/free is used instead of mem.c
+
+ notes:
+ uses Quickfit algorithm (freelists for commonly allocated sizes)
+ assumes small sizes for freelists (it discards the tail of memory buffers)
+
+ see:
+ qh-mem_r.htm and mem_r.h
+ global_r.c (qh_initbuffers) for an example of using mem_r.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/mem_r.c#5 $$Change: 2065 $
+ $DateTime: 2016/01/18 13:51:04 $$Author: bbarber $
+*/
+
+#include "libqhull_r.h" /* includes user_r.h and mem_r.h */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef qh_NOmem
+
+/*============= internal functions ==============*/
+
+static int qh_intcompare(const void *i, const void *j);
+
+/*========== functions in alphabetical order ======== */
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >-------------------------------</a><a name="intcompare">-</a>
+
+ qh_intcompare( i, j )
+ used by qsort and bsearch to compare two integers
+*/
+static int qh_intcompare(const void *i, const void *j) {
+ return(*((const int *)i) - *((const int *)j));
+} /* intcompare */
+
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >--------------------------------</a><a name="memalloc">-</a>
+
+ qh_memalloc( qh, insize )
+ returns object of insize bytes
+ qhmem is the global memory structure
+
+ returns:
+ pointer to allocated memory
+ errors if insufficient memory
+
+ notes:
+ use explicit type conversion to avoid type warnings on some compilers
+ actual object may be larger than insize
+ use qh_memalloc_() for inline code for quick allocations
+ logs allocations if 'T5'
+ caller is responsible for freeing the memory.
+ short memory is freed on shutdown by qh_memfreeshort unless qh_NOmem
+
+ design:
+ if size < qh->qhmem.LASTsize
+ if qh->qhmem.freelists[size] non-empty
+ return first object on freelist
+ else
+ round up request to size of qh->qhmem.freelists[size]
+ allocate new allocation buffer if necessary
+ allocate object from allocation buffer
+ else
+ allocate object with qh_malloc() in user.c
+*/
+void *qh_memalloc(qhT *qh, int insize) {
+ void **freelistp, *newbuffer;
+ int idx, size, n;
+ int outsize, bufsize;
+ void *object;
+
+ if (insize<0) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6235, "qhull error (qh_memalloc): negative request size (%d). Did int overflow due to high-D?\n", insize); /* WARN64 */
+ qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
+ }
+ if (insize>=0 && insize <= qh->qhmem.LASTsize) {
+ idx= qh->qhmem.indextable[insize];
+ outsize= qh->qhmem.sizetable[idx];
+ qh->qhmem.totshort += outsize;
+ freelistp= qh->qhmem.freelists+idx;
+ if ((object= *freelistp)) {
+ qh->qhmem.cntquick++;
+ qh->qhmem.totfree -= outsize;
+ *freelistp= *((void **)*freelistp); /* replace freelist with next object */
+#ifdef qh_TRACEshort
+ n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
+ if (qh->qhmem.IStracing >= 5)
+ qh_fprintf(qh, qh->qhmem.ferr, 8141, "qh_mem %p n %8d alloc quick: %d bytes (tot %d cnt %d)\n", object, n, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
+#endif
+ return(object);
+ }else {
+ qh->qhmem.cntshort++;
+ if (outsize > qh->qhmem.freesize) {
+ qh->qhmem.totdropped += qh->qhmem.freesize;
+ if (!qh->qhmem.curbuffer)
+ bufsize= qh->qhmem.BUFinit;
+ else
+ bufsize= qh->qhmem.BUFsize;
+ if (!(newbuffer= qh_malloc((size_t)bufsize))) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6080, "qhull error (qh_memalloc): insufficient memory to allocate short memory buffer (%d bytes)\n", bufsize);
+ qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
+ }
+ *((void **)newbuffer)= qh->qhmem.curbuffer; /* prepend newbuffer to curbuffer
+ list. newbuffer!=0 by QH6080 */
+ qh->qhmem.curbuffer= newbuffer;
+ size= (sizeof(void **) + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
+ qh->qhmem.freemem= (void *)((char *)newbuffer+size);
+ qh->qhmem.freesize= bufsize - size;
+ qh->qhmem.totbuffer += bufsize - size; /* easier to check */
+ /* Periodically test totbuffer. It matches at beginning and exit of every call */
+ n = qh->qhmem.totshort + qh->qhmem.totfree + qh->qhmem.totdropped + qh->qhmem.freesize - outsize;
+ if (qh->qhmem.totbuffer != n) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6212, "qh_memalloc internal error: short totbuffer %d != totshort+totfree... %d\n", qh->qhmem.totbuffer, n);
+ qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
+ }
+ }
+ object= qh->qhmem.freemem;
+ qh->qhmem.freemem= (void *)((char *)qh->qhmem.freemem + outsize);
+ qh->qhmem.freesize -= outsize;
+ qh->qhmem.totunused += outsize - insize;
+#ifdef qh_TRACEshort
+ n= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
+ if (qh->qhmem.IStracing >= 5)
+ qh_fprintf(qh, qh->qhmem.ferr, 8140, "qh_mem %p n %8d alloc short: %d bytes (tot %d cnt %d)\n", object, n, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
+#endif
+ return object;
+ }
+ }else { /* long allocation */
+ if (!qh->qhmem.indextable) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6081, "qhull internal error (qh_memalloc): qhmem has not been initialized.\n");
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ outsize= insize;
+ qh->qhmem.cntlong++;
+ qh->qhmem.totlong += outsize;
+ if (qh->qhmem.maxlong < qh->qhmem.totlong)
+ qh->qhmem.maxlong= qh->qhmem.totlong;
+ if (!(object= qh_malloc((size_t)outsize))) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6082, "qhull error (qh_memalloc): insufficient memory to allocate %d bytes\n", outsize);
+ qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
+ }
+ if (qh->qhmem.IStracing >= 5)
+ qh_fprintf(qh, qh->qhmem.ferr, 8057, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, outsize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
+ }
+ return(object);
+} /* memalloc */
+
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >--------------------------------</a><a name="memcheck">-</a>
+
+ qh_memcheck(qh)
+*/
+void qh_memcheck(qhT *qh) {
+ int i, count, totfree= 0;
+ void *object;
+
+ if (!qh) {
+ qh_fprintf_stderr(6243, "qh_memcheck(qh) error: qh is 0. It does not point to a qhT");
+ qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
+ }
+ if (qh->qhmem.ferr == 0 || qh->qhmem.IStracing < 0 || qh->qhmem.IStracing > 10 || (((qh->qhmem.ALIGNmask+1) & qh->qhmem.ALIGNmask) != 0)) {
+ qh_fprintf_stderr(6244, "qh_memcheck error: either qh->qhmem is overwritten or qh->qhmem is not initialized. Call qh_mem_new() or qh_new_qhull() before calling qh_mem routines. ferr 0x%x IsTracing %d ALIGNmask 0x%x", qh->qhmem.ferr, qh->qhmem.IStracing, qh->qhmem.ALIGNmask);
+ qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
+ }
+ if (qh->qhmem.IStracing != 0)
+ qh_fprintf(qh, qh->qhmem.ferr, 8143, "qh_memcheck: check size of freelists on qh->qhmem\nqh_memcheck: A segmentation fault indicates an overwrite of qh->qhmem\n");
+ for (i=0; i < qh->qhmem.TABLEsize; i++) {
+ count=0;
+ for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
+ count++;
+ totfree += qh->qhmem.sizetable[i] * count;
+ }
+ if (totfree != qh->qhmem.totfree) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6211, "Qhull internal error (qh_memcheck): totfree %d not equal to freelist total %d\n", qh->qhmem.totfree, totfree);
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ if (qh->qhmem.IStracing != 0)
+ qh_fprintf(qh, qh->qhmem.ferr, 8144, "qh_memcheck: total size of freelists totfree is the same as qh->qhmem.totfree\n", totfree);
+} /* memcheck */
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >--------------------------------</a><a name="memfree">-</a>
+
+ qh_memfree(qh, object, insize )
+ free up an object of size bytes
+ size is insize from qh_memalloc
+
+ notes:
+ object may be NULL
+ type checking warns if using (void **)object
+ use qh_memfree_() for quick free's of small objects
+
+ design:
+ if size <= qh->qhmem.LASTsize
+ append object to corresponding freelist
+ else
+ call qh_free(object)
+*/
+void qh_memfree(qhT *qh, void *object, int insize) {
+ void **freelistp;
+ int idx, outsize;
+
+ if (!object)
+ return;
+ if (insize <= qh->qhmem.LASTsize) {
+ qh->qhmem.freeshort++;
+ idx= qh->qhmem.indextable[insize];
+ outsize= qh->qhmem.sizetable[idx];
+ qh->qhmem.totfree += outsize;
+ qh->qhmem.totshort -= outsize;
+ freelistp= qh->qhmem.freelists + idx;
+ *((void **)object)= *freelistp;
+ *freelistp= object;
+#ifdef qh_TRACEshort
+ idx= qh->qhmem.cntshort+qh->qhmem.cntquick+qh->qhmem.freeshort;
+ if (qh->qhmem.IStracing >= 5)
+ qh_fprintf(qh, qh->qhmem.ferr, 8142, "qh_mem %p n %8d free short: %d bytes (tot %d cnt %d)\n", object, idx, outsize, qh->qhmem.totshort, qh->qhmem.cntshort+qh->qhmem.cntquick-qh->qhmem.freeshort);
+#endif
+ }else {
+ qh->qhmem.freelong++;
+ qh->qhmem.totlong -= insize;
+ if (qh->qhmem.IStracing >= 5)
+ qh_fprintf(qh, qh->qhmem.ferr, 8058, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
+ qh_free(object);
+ }
+} /* memfree */
+
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >-------------------------------</a><a name="memfreeshort">-</a>
+
+ qh_memfreeshort(qh, curlong, totlong )
+ frees up all short and qhmem memory allocations
+
+ returns:
+ number and size of current long allocations
+
+ notes:
+ if qh_NOmem (qh_malloc() for all allocations),
+ short objects (e.g., facetT) are not recovered.
+ use qh_freeqhull(qh, qh_ALL) instead.
+
+ see:
+ qh_freeqhull(qh, allMem)
+ qh_memtotal(qh, curlong, totlong, curshort, totshort, maxlong, totbuffer);
+*/
+void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
+ void *buffer, *nextbuffer;
+ FILE *ferr;
+
+ *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
+ *totlong= qh->qhmem.totlong;
+ for (buffer= qh->qhmem.curbuffer; buffer; buffer= nextbuffer) {
+ nextbuffer= *((void **) buffer);
+ qh_free(buffer);
+ }
+ qh->qhmem.curbuffer= NULL;
+ if (qh->qhmem.LASTsize) {
+ qh_free(qh->qhmem.indextable);
+ qh_free(qh->qhmem.freelists);
+ qh_free(qh->qhmem.sizetable);
+ }
+ ferr= qh->qhmem.ferr;
+ memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
+ qh->qhmem.ferr= ferr;
+} /* memfreeshort */
+
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >--------------------------------</a><a name="meminit">-</a>
+
+ qh_meminit(qh, ferr )
+ initialize qhmem and test sizeof( void*)
+ Does not throw errors. qh_exit on failure
+*/
+void qh_meminit(qhT *qh, FILE *ferr) {
+
+ memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
+ if (ferr)
+ qh->qhmem.ferr= ferr;
+ else
+ qh->qhmem.ferr= stderr;
+ if (sizeof(void*) < sizeof(int)) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6083, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d. qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
+ qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
+ }
+ if (sizeof(void*) > sizeof(ptr_intT)) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6084, "qhull internal error (qh_meminit): sizeof(void*) %d > sizeof(ptr_intT) %d. Change ptr_intT in mem.h to 'long long'\n", (int)sizeof(void*), (int)sizeof(ptr_intT));
+ qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
+ }
+ qh_memcheck(qh);
+} /* meminit */
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >-------------------------------</a><a name="meminitbuffers">-</a>
+
+ qh_meminitbuffers(qh, tracelevel, alignment, numsizes, bufsize, bufinit )
+ initialize qhmem
+ if tracelevel >= 5, trace memory allocations
+ alignment= desired address alignment for memory allocations
+ numsizes= number of freelists
+ bufsize= size of additional memory buffers for short allocations
+ bufinit= size of initial memory buffer for short allocations
+*/
+void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
+
+ qh->qhmem.IStracing= tracelevel;
+ qh->qhmem.NUMsizes= numsizes;
+ qh->qhmem.BUFsize= bufsize;
+ qh->qhmem.BUFinit= bufinit;
+ qh->qhmem.ALIGNmask= alignment-1;
+ if (qh->qhmem.ALIGNmask & ~qh->qhmem.ALIGNmask) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6085, "qhull internal error (qh_meminit): memory alignment %d is not a power of 2\n", alignment);
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ qh->qhmem.sizetable= (int *) calloc((size_t)numsizes, sizeof(int));
+ qh->qhmem.freelists= (void **) calloc((size_t)numsizes, sizeof(void *));
+ if (!qh->qhmem.sizetable || !qh->qhmem.freelists) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6086, "qhull error (qh_meminit): insufficient memory\n");
+ qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
+ }
+ if (qh->qhmem.IStracing >= 1)
+ qh_fprintf(qh, qh->qhmem.ferr, 8059, "qh_meminitbuffers: memory initialized with alignment %d\n", alignment);
+} /* meminitbuffers */
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >-------------------------------</a><a name="memsetup">-</a>
+
+ qh_memsetup(qh)
+ set up memory after running memsize()
+*/
+void qh_memsetup(qhT *qh) {
+ int k,i;
+
+ qsort(qh->qhmem.sizetable, (size_t)qh->qhmem.TABLEsize, sizeof(int), qh_intcompare);
+ qh->qhmem.LASTsize= qh->qhmem.sizetable[qh->qhmem.TABLEsize-1];
+ if(qh->qhmem.LASTsize >= qh->qhmem.BUFsize || qh->qhmem.LASTsize >= qh->qhmem.BUFinit) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6087, "qhull error (qh_memsetup): largest mem size %d is >= buffer size %d or initial buffer size %d\n",
+ qh->qhmem.LASTsize, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
+ qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
+ }
+ if (!(qh->qhmem.indextable= (int *)qh_malloc((qh->qhmem.LASTsize+1) * sizeof(int)))) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6088, "qhull error (qh_memsetup): insufficient memory\n");
+ qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
+ }
+ for (k=qh->qhmem.LASTsize+1; k--; )
+ qh->qhmem.indextable[k]= k;
+ i= 0;
+ for (k=0; k <= qh->qhmem.LASTsize; k++) {
+ if (qh->qhmem.indextable[k] <= qh->qhmem.sizetable[i])
+ qh->qhmem.indextable[k]= i;
+ else
+ qh->qhmem.indextable[k]= ++i;
+ }
+} /* memsetup */
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >-------------------------------</a><a name="memsize">-</a>
+
+ qh_memsize(qh, size )
+ define a free list for this size
+*/
+void qh_memsize(qhT *qh, int size) {
+ int k;
+
+ if(qh->qhmem.LASTsize) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6089, "qhull error (qh_memsize): called after qhmem_setup\n");
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ size= (size + qh->qhmem.ALIGNmask) & ~qh->qhmem.ALIGNmask;
+ for (k=qh->qhmem.TABLEsize; k--; ) {
+ if (qh->qhmem.sizetable[k] == size)
+ return;
+ }
+ if (qh->qhmem.TABLEsize < qh->qhmem.NUMsizes)
+ qh->qhmem.sizetable[qh->qhmem.TABLEsize++]= size;
+ else
+ qh_fprintf(qh, qh->qhmem.ferr, 7060, "qhull warning (memsize): free list table has room for only %d sizes\n", qh->qhmem.NUMsizes);
+} /* memsize */
+
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >-------------------------------</a><a name="memstatistics">-</a>
+
+ qh_memstatistics(qh, fp )
+ print out memory statistics
+
+ Verifies that qh->qhmem.totfree == sum of freelists
+*/
+void qh_memstatistics(qhT *qh, FILE *fp) {
+ int i;
+ int count;
+ void *object;
+
+ qh_memcheck(qh);
+ qh_fprintf(qh, fp, 9278, "\nmemory statistics:\n\
+%7d quick allocations\n\
+%7d short allocations\n\
+%7d long allocations\n\
+%7d short frees\n\
+%7d long frees\n\
+%7d bytes of short memory in use\n\
+%7d bytes of short memory in freelists\n\
+%7d bytes of dropped short memory\n\
+%7d bytes of unused short memory (estimated)\n\
+%7d bytes of long memory allocated (max, except for input)\n\
+%7d bytes of long memory in use (in %d pieces)\n\
+%7d bytes of short memory buffers (minus links)\n\
+%7d bytes per short memory buffer (initially %d bytes)\n",
+ qh->qhmem.cntquick, qh->qhmem.cntshort, qh->qhmem.cntlong,
+ qh->qhmem.freeshort, qh->qhmem.freelong,
+ qh->qhmem.totshort, qh->qhmem.totfree,
+ qh->qhmem.totdropped + qh->qhmem.freesize, qh->qhmem.totunused,
+ qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong,
+ qh->qhmem.totbuffer, qh->qhmem.BUFsize, qh->qhmem.BUFinit);
+ if (qh->qhmem.cntlarger) {
+ qh_fprintf(qh, fp, 9279, "%7d calls to qh_setlarger\n%7.2g average copy size\n",
+ qh->qhmem.cntlarger, ((float)qh->qhmem.totlarger)/(float)qh->qhmem.cntlarger);
+ qh_fprintf(qh, fp, 9280, " freelists(bytes->count):");
+ }
+ for (i=0; i < qh->qhmem.TABLEsize; i++) {
+ count=0;
+ for (object= qh->qhmem.freelists[i]; object; object= *((void **)object))
+ count++;
+ qh_fprintf(qh, fp, 9281, " %d->%d", qh->qhmem.sizetable[i], count);
+ }
+ qh_fprintf(qh, fp, 9282, "\n\n");
+} /* memstatistics */
+
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >-------------------------------</a><a name="NOmem">-</a>
+
+ qh_NOmem
+ turn off quick-fit memory allocation
+
+ notes:
+ uses qh_malloc() and qh_free() instead
+*/
+#else /* qh_NOmem */
+
+void *qh_memalloc(qhT *qh, int insize) {
+ void *object;
+
+ if (!(object= qh_malloc((size_t)insize))) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6090, "qhull error (qh_memalloc): insufficient memory\n");
+ qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
+ }
+ qh->qhmem.cntlong++;
+ qh->qhmem.totlong += insize;
+ if (qh->qhmem.maxlong < qh->qhmem.totlong)
+ qh->qhmem.maxlong= qh->qhmem.totlong;
+ if (qh->qhmem.IStracing >= 5)
+ qh_fprintf(qh, qh->qhmem.ferr, 8060, "qh_mem %p n %8d alloc long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
+ return object;
+}
+
+void qh_memfree(qhT *qh, void *object, int insize) {
+
+ if (!object)
+ return;
+ qh_free(object);
+ qh->qhmem.freelong++;
+ qh->qhmem.totlong -= insize;
+ if (qh->qhmem.IStracing >= 5)
+ qh_fprintf(qh, qh->qhmem.ferr, 8061, "qh_mem %p n %8d free long: %d bytes (tot %d cnt %d)\n", object, qh->qhmem.cntlong+qh->qhmem.freelong, insize, qh->qhmem.totlong, qh->qhmem.cntlong-qh->qhmem.freelong);
+}
+
+void qh_memfreeshort(qhT *qh, int *curlong, int *totlong) {
+ *totlong= qh->qhmem.totlong;
+ *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
+ memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
+}
+
+void qh_meminit(qhT *qh, FILE *ferr) {
+
+ memset((char *)&qh->qhmem, 0, sizeof(qh->qhmem)); /* every field is 0, FALSE, NULL */
+ if (ferr)
+ qh->qhmem.ferr= ferr;
+ else
+ qh->qhmem.ferr= stderr;
+ if (sizeof(void*) < sizeof(int)) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6091, "qhull internal error (qh_meminit): sizeof(void*) %d < sizeof(int) %d. qset.c will not work\n", (int)sizeof(void*), (int)sizeof(int));
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+}
+
+void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes, int bufsize, int bufinit) {
+
+ qh->qhmem.IStracing= tracelevel;
+}
+
+void qh_memsetup(qhT *qh) {
+
+}
+
+void qh_memsize(qhT *qh, int size) {
+
+}
+
+void qh_memstatistics(qhT *qh, FILE *fp) {
+
+ qh_fprintf(qh, fp, 9409, "\nmemory statistics:\n\
+%7d long allocations\n\
+%7d long frees\n\
+%7d bytes of long memory allocated (max, except for input)\n\
+%7d bytes of long memory in use (in %d pieces)\n",
+ qh->qhmem.cntlong,
+ qh->qhmem.freelong,
+ qh->qhmem.maxlong, qh->qhmem.totlong, qh->qhmem.cntlong - qh->qhmem.freelong);
+}
+
+#endif /* qh_NOmem */
+
+/*-<a href="qh-mem_r.htm#TOC"
+>-------------------------------</a><a name="memtotlong">-</a>
+
+ qh_memtotal(qh, totlong, curlong, totshort, curshort, maxlong, totbuffer )
+ Return the total, allocated long and short memory
+
+ returns:
+ Returns the total current bytes of long and short allocations
+ Returns the current count of long and short allocations
+ Returns the maximum long memory and total short buffer (minus one link per buffer)
+ Does not error (for deprecated UsingLibQhull.cpp (libqhullpcpp))
+*/
+void qh_memtotal(qhT *qh, int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer) {
+ *totlong= qh->qhmem.totlong;
+ *curlong= qh->qhmem.cntlong - qh->qhmem.freelong;
+ *totshort= qh->qhmem.totshort;
+ *curshort= qh->qhmem.cntshort + qh->qhmem.cntquick - qh->qhmem.freeshort;
+ *maxlong= qh->qhmem.maxlong;
+ *totbuffer= qh->qhmem.totbuffer;
+} /* memtotlong */
+
diff --git a/xs/src/qhull/src/libqhull_r/mem_r.h b/xs/src/qhull/src/libqhull_r/mem_r.h
new file mode 100644
index 000000000..25b551333
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/mem_r.h
@@ -0,0 +1,234 @@
+/*<html><pre> -<a href="qh-mem_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ mem_r.h
+ prototypes for memory management functions
+
+ see qh-mem_r.htm, mem_r.c and qset_r.h
+
+ for error handling, writes message and calls
+ qh_errexit(qhT *qh, qhmem_ERRmem, NULL, NULL) if insufficient memory
+ and
+ qh_errexit(qhT *qh, qhmem_ERRqhull, NULL, NULL) otherwise
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/mem_r.h#4 $$Change: 2079 $
+ $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+*/
+
+#ifndef qhDEFmem
+#define qhDEFmem 1
+
+#include <stdio.h>
+
+#ifndef DEFsetT
+#define DEFsetT 1
+typedef struct setT setT; /* defined in qset_r.h */
+#endif
+
+#ifndef DEFqhT
+#define DEFqhT 1
+typedef struct qhT qhT; /* defined in libqhull_r.h */
+#endif
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >-------------------------------</a><a name="NOmem">-</a>
+
+ qh_NOmem
+ turn off quick-fit memory allocation
+
+ notes:
+ mem_r.c implements Quickfit memory allocation for about 20% time
+ savings. If it fails on your machine, try to locate the
+ problem, and send the answer to qhull@qhull.org. If this can
+ not be done, define qh_NOmem to use malloc/free instead.
+
+ #define qh_NOmem
+*/
+
+/*-<a href="qh-mem_r.htm#TOC"
+>-------------------------------</a><a name="TRACEshort">-</a>
+
+qh_TRACEshort
+Trace short and quick memory allocations at T5
+
+*/
+#define qh_TRACEshort
+
+/*-------------------------------------------
+ to avoid bus errors, memory allocation must consider alignment requirements.
+ malloc() automatically takes care of alignment. Since mem_r.c manages
+ its own memory, we need to explicitly specify alignment in
+ qh_meminitbuffers().
+
+ A safe choice is sizeof(double). sizeof(float) may be used if doubles
+ do not occur in data structures and pointers are the same size. Be careful
+ of machines (e.g., DEC Alpha) with large pointers. If gcc is available,
+ use __alignof__(double) or fmax_(__alignof__(float), __alignof__(void *)).
+
+ see <a href="user.h#MEMalign">qh_MEMalign</a> in user.h for qhull's alignment
+*/
+
+#define qhmem_ERRmem 4 /* matches qh_ERRmem in libqhull_r.h */
+#define qhmem_ERRqhull 5 /* matches qh_ERRqhull in libqhull_r.h */
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >--------------------------------</a><a name="ptr_intT">-</a>
+
+ ptr_intT
+ for casting a void * to an integer-type that holds a pointer
+ Used for integer expressions (e.g., computing qh_gethash() in poly_r.c)
+
+ notes:
+ WARN64 -- these notes indicate 64-bit issues
+ On 64-bit machines, a pointer may be larger than an 'int'.
+ qh_meminit()/mem_r.c checks that 'ptr_intT' holds a 'void*'
+ ptr_intT is typically a signed value, but not necessarily so
+ size_t is typically unsigned, but should match the parameter type
+ Qhull uses int instead of size_t except for system calls such as malloc, qsort, qh_malloc, etc.
+ This matches Qt convention and is easier to work with.
+*/
+#if (defined(__MINGW64__)) && defined(_WIN64)
+typedef long long ptr_intT;
+#elif (_MSC_VER) && defined(_WIN64)
+typedef long long ptr_intT;
+#else
+typedef long ptr_intT;
+#endif
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >--------------------------------</a><a name="qhmemT">-</a>
+
+ qhmemT
+ global memory structure for mem_r.c
+
+ notes:
+ users should ignore qhmem except for writing extensions
+ qhmem is allocated in mem_r.c
+
+ qhmem could be swapable like qh and qhstat, but then
+ multiple qh's and qhmem's would need to keep in synch.
+ A swapable qhmem would also waste memory buffers. As long
+ as memory operations are atomic, there is no problem with
+ multiple qh structures being active at the same time.
+ If you need separate address spaces, you can swap the
+ contents of qh->qhmem.
+*/
+typedef struct qhmemT qhmemT;
+
+/* Update qhmem in mem_r.c if add or remove fields */
+struct qhmemT { /* global memory management variables */
+ int BUFsize; /* size of memory allocation buffer */
+ int BUFinit; /* initial size of memory allocation buffer */
+ int TABLEsize; /* actual number of sizes in free list table */
+ int NUMsizes; /* maximum number of sizes in free list table */
+ int LASTsize; /* last size in free list table */
+ int ALIGNmask; /* worst-case alignment, must be 2^n-1 */
+ void **freelists; /* free list table, linked by offset 0 */
+ int *sizetable; /* size of each freelist */
+ int *indextable; /* size->index table */
+ void *curbuffer; /* current buffer, linked by offset 0 */
+ void *freemem; /* free memory in curbuffer */
+ int freesize; /* size of freemem in bytes */
+ setT *tempstack; /* stack of temporary memory, managed by users */
+ FILE *ferr; /* file for reporting errors when 'qh' may be undefined */
+ int IStracing; /* =5 if tracing memory allocations */
+ int cntquick; /* count of quick allocations */
+ /* Note: removing statistics doesn't effect speed */
+ int cntshort; /* count of short allocations */
+ int cntlong; /* count of long allocations */
+ int freeshort; /* count of short memfrees */
+ int freelong; /* count of long memfrees */
+ int totbuffer; /* total short memory buffers minus buffer links */
+ int totdropped; /* total dropped memory at end of short memory buffers (e.g., freesize) */
+ int totfree; /* total size of free, short memory on freelists */
+ int totlong; /* total size of long memory in use */
+ int maxlong; /* maximum totlong */
+ int totshort; /* total size of short memory in use */
+ int totunused; /* total unused short memory (estimated, short size - request size of first allocations) */
+ int cntlarger; /* count of setlarger's */
+ int totlarger; /* total copied by setlarger */
+};
+
+
+/*==================== -macros ====================*/
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >--------------------------------</a><a name="memalloc_">-</a>
+
+ qh_memalloc_(qh, insize, freelistp, object, type)
+ returns object of size bytes
+ assumes size<=qh->qhmem.LASTsize and void **freelistp is a temp
+*/
+
+#if defined qh_NOmem
+#define qh_memalloc_(qh, insize, freelistp, object, type) {\
+ object= (type*)qh_memalloc(qh, insize); }
+#elif defined qh_TRACEshort
+#define qh_memalloc_(qh, insize, freelistp, object, type) {\
+ freelistp= NULL; /* Avoid warnings */ \
+ object= (type*)qh_memalloc(qh, insize); }
+#else /* !qh_NOmem */
+
+#define qh_memalloc_(qh, insize, freelistp, object, type) {\
+ freelistp= qh->qhmem.freelists + qh->qhmem.indextable[insize];\
+ if ((object= (type*)*freelistp)) {\
+ qh->qhmem.totshort += qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
+ qh->qhmem.totfree -= qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
+ qh->qhmem.cntquick++; \
+ *freelistp= *((void **)*freelistp);\
+ }else object= (type*)qh_memalloc(qh, insize);}
+#endif
+
+/*-<a href="qh-mem_r.htm#TOC"
+ >--------------------------------</a><a name="memfree_">-</a>
+
+ qh_memfree_(qh, object, insize, freelistp)
+ free up an object
+
+ notes:
+ object may be NULL
+ assumes size<=qh->qhmem.LASTsize and void **freelistp is a temp
+*/
+#if defined qh_NOmem
+#define qh_memfree_(qh, object, insize, freelistp) {\
+ qh_memfree(qh, object, insize); }
+#elif defined qh_TRACEshort
+#define qh_memfree_(qh, object, insize, freelistp) {\
+ freelistp= NULL; /* Avoid warnings */ \
+ qh_memfree(qh, object, insize); }
+#else /* !qh_NOmem */
+
+#define qh_memfree_(qh, object, insize, freelistp) {\
+ if (object) { \
+ qh->qhmem.freeshort++;\
+ freelistp= qh->qhmem.freelists + qh->qhmem.indextable[insize];\
+ qh->qhmem.totshort -= qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
+ qh->qhmem.totfree += qh->qhmem.sizetable[qh->qhmem.indextable[insize]]; \
+ *((void **)object)= *freelistp;\
+ *freelistp= object;}}
+#endif
+
+/*=============== prototypes in alphabetical order ============*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *qh_memalloc(qhT *qh, int insize);
+void qh_memcheck(qhT *qh);
+void qh_memfree(qhT *qh, void *object, int insize);
+void qh_memfreeshort(qhT *qh, int *curlong, int *totlong);
+void qh_meminit(qhT *qh, FILE *ferr);
+void qh_meminitbuffers(qhT *qh, int tracelevel, int alignment, int numsizes,
+ int bufsize, int bufinit);
+void qh_memsetup(qhT *qh);
+void qh_memsize(qhT *qh, int size);
+void qh_memstatistics(qhT *qh, FILE *fp);
+void qh_memtotal(qhT *qh, int *totlong, int *curlong, int *totshort, int *curshort, int *maxlong, int *totbuffer);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* qhDEFmem */
diff --git a/xs/src/qhull/src/libqhull_r/merge_r.c b/xs/src/qhull/src/libqhull_r/merge_r.c
new file mode 100644
index 000000000..e5823de8d
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/merge_r.c
@@ -0,0 +1,3627 @@
+/*<html><pre> -<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ merge_r.c
+ merges non-convex facets
+
+ see qh-merge_r.htm and merge_r.h
+
+ other modules call qh_premerge() and qh_postmerge()
+
+ the user may call qh_postmerge() to perform additional merges.
+
+ To remove deleted facets and vertices (qhull() in libqhull_r.c):
+ qh_partitionvisible(qh, !qh_ALL, &numoutside); // visible_list, newfacet_list
+ qh_deletevisible(); // qh.visible_list
+ qh_resetlists(qh, False, qh_RESETvisible); // qh.visible_list newvertex_list newfacet_list
+
+ assumes qh.CENTERtype= centrum
+
+ merges occur in qh_mergefacet and in qh_mergecycle
+ vertex->neighbors not set until the first merge occurs
+
+ Copyright (c) 1993-2015 C.B. Barber.
+ $Id: //main/2015/qhull/src/libqhull_r/merge_r.c#5 $$Change: 2064 $
+ $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
+*/
+
+#include "qhull_ra.h"
+
+#ifndef qh_NOmerge
+
+/*===== functions(alphabetical after premerge and postmerge) ======*/
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="premerge">-</a>
+
+ qh_premerge(qh, apex, maxcentrum )
+ pre-merge nonconvex facets in qh.newfacet_list for apex
+ maxcentrum defines coplanar and concave (qh_test_appendmerge)
+
+ returns:
+ deleted facets added to qh.visible_list with facet->visible set
+
+ notes:
+ uses globals, qh.MERGEexact, qh.PREmerge
+
+ design:
+ mark duplicate ridges in qh.newfacet_list
+ merge facet cycles in qh.newfacet_list
+ merge duplicate ridges and concave facets in qh.newfacet_list
+ check merged facet cycles for degenerate and redundant facets
+ merge degenerate and redundant facets
+ collect coplanar and concave facets
+ merge concave, coplanar, degenerate, and redundant facets
+*/
+void qh_premerge(qhT *qh, vertexT *apex, realT maxcentrum, realT maxangle) {
+ boolT othermerge= False;
+ facetT *newfacet;
+
+ if (qh->ZEROcentrum && qh_checkzero(qh, !qh_ALL))
+ return;
+ trace2((qh, qh->ferr, 2008, "qh_premerge: premerge centrum %2.2g angle %2.2g for apex v%d facetlist f%d\n",
+ maxcentrum, maxangle, apex->id, getid_(qh->newfacet_list)));
+ if (qh->IStracing >= 4 && qh->num_facets < 50)
+ qh_printlists(qh);
+ qh->centrum_radius= maxcentrum;
+ qh->cos_max= maxangle;
+ qh->degen_mergeset= qh_settemp(qh, qh->TEMPsize);
+ qh->facet_mergeset= qh_settemp(qh, qh->TEMPsize);
+ if (qh->hull_dim >=3) {
+ qh_mark_dupridges(qh, qh->newfacet_list); /* facet_mergeset */
+ qh_mergecycle_all(qh, qh->newfacet_list, &othermerge);
+ qh_forcedmerges(qh, &othermerge /* qh->facet_mergeset */);
+ FORALLnew_facets { /* test samecycle merges */
+ if (!newfacet->simplicial && !newfacet->mergeridge)
+ qh_degen_redundant_neighbors(qh, newfacet, NULL);
+ }
+ if (qh_merge_degenredundant(qh))
+ othermerge= True;
+ }else /* qh->hull_dim == 2 */
+ qh_mergecycle_all(qh, qh->newfacet_list, &othermerge);
+ qh_flippedmerges(qh, qh->newfacet_list, &othermerge);
+ if (!qh->MERGEexact || zzval_(Ztotmerge)) {
+ zinc_(Zpremergetot);
+ qh->POSTmerging= False;
+ qh_getmergeset_initial(qh, qh->newfacet_list);
+ qh_all_merges(qh, othermerge, False);
+ }
+ qh_settempfree(qh, &qh->facet_mergeset);
+ qh_settempfree(qh, &qh->degen_mergeset);
+} /* premerge */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="postmerge">-</a>
+
+ qh_postmerge(qh, reason, maxcentrum, maxangle, vneighbors )
+ post-merge nonconvex facets as defined by maxcentrum and maxangle
+ 'reason' is for reporting progress
+ if vneighbors,
+ calls qh_test_vneighbors at end of qh_all_merge
+ if firstmerge,
+ calls qh_reducevertices before qh_getmergeset
+
+ returns:
+ if first call (qh.visible_list != qh.facet_list),
+ builds qh.facet_newlist, qh.newvertex_list
+ deleted facets added to qh.visible_list with facet->visible
+ qh.visible_list == qh.facet_list
+
+ notes:
+
+
+ design:
+ if first call
+ set qh.visible_list and qh.newfacet_list to qh.facet_list
+ add all facets to qh.newfacet_list
+ mark non-simplicial facets, facet->newmerge
+ set qh.newvertext_list to qh.vertex_list
+ add all vertices to qh.newvertex_list
+ if a pre-merge occured
+ set vertex->delridge {will retest the ridge}
+ if qh.MERGEexact
+ call qh_reducevertices()
+ if no pre-merging
+ merge flipped facets
+ determine non-convex facets
+ merge all non-convex facets
+*/
+void qh_postmerge(qhT *qh, const char *reason, realT maxcentrum, realT maxangle,
+ boolT vneighbors) {
+ facetT *newfacet;
+ boolT othermerges= False;
+ vertexT *vertex;
+
+ if (qh->REPORTfreq || qh->IStracing) {
+ qh_buildtracing(qh, NULL, NULL);
+ qh_printsummary(qh, qh->ferr);
+ if (qh->PRINTstatistics)
+ qh_printallstatistics(qh, qh->ferr, "reason");
+ qh_fprintf(qh, qh->ferr, 8062, "\n%s with 'C%.2g' and 'A%.2g'\n",
+ reason, maxcentrum, maxangle);
+ }
+ trace2((qh, qh->ferr, 2009, "qh_postmerge: postmerge. test vneighbors? %d\n",
+ vneighbors));
+ qh->centrum_radius= maxcentrum;
+ qh->cos_max= maxangle;
+ qh->POSTmerging= True;
+ qh->degen_mergeset= qh_settemp(qh, qh->TEMPsize);
+ qh->facet_mergeset= qh_settemp(qh, qh->TEMPsize);
+ if (qh->visible_list != qh->facet_list) { /* first call */
+ qh->NEWfacets= True;
+ qh->visible_list= qh->newfacet_list= qh->facet_list;
+ FORALLnew_facets {
+ newfacet->newfacet= True;
+ if (!newfacet->simplicial)
+ newfacet->newmerge= True;
+ zinc_(Zpostfacets);
+ }
+ qh->newvertex_list= qh->vertex_list;
+ FORALLvertices
+ vertex->newlist= True;
+ if (qh->VERTEXneighbors) { /* a merge has occurred */
+ FORALLvertices
+ vertex->delridge= True; /* test for redundant, needed? */
+ if (qh->MERGEexact) {
+ if (qh->hull_dim <= qh_DIMreduceBuild)
+ qh_reducevertices(qh); /* was skipped during pre-merging */
+ }
+ }
+ if (!qh->PREmerge && !qh->MERGEexact)
+ qh_flippedmerges(qh, qh->newfacet_list, &othermerges);
+ }
+ qh_getmergeset_initial(qh, qh->newfacet_list);
+ qh_all_merges(qh, False, vneighbors);
+ qh_settempfree(qh, &qh->facet_mergeset);
+ qh_settempfree(qh, &qh->degen_mergeset);
+} /* post_merge */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="all_merges">-</a>
+
+ qh_all_merges(qh, othermerge, vneighbors )
+ merge all non-convex facets
+
+ set othermerge if already merged facets (for qh_reducevertices)
+ if vneighbors
+ tests vertex neighbors for convexity at end
+ qh.facet_mergeset lists the non-convex ridges in qh_newfacet_list
+ qh.degen_mergeset is defined
+ if qh.MERGEexact && !qh.POSTmerging,
+ does not merge coplanar facets
+
+ returns:
+ deleted facets added to qh.visible_list with facet->visible
+ deleted vertices added qh.delvertex_list with vertex->delvertex
+
+ notes:
+ unless !qh.MERGEindependent,
+ merges facets in independent sets
+ uses qh.newfacet_list as argument since merges call qh_removefacet()
+
+ design:
+ while merges occur
+ for each merge in qh.facet_mergeset
+ unless one of the facets was already merged in this pass
+ merge the facets
+ test merged facets for additional merges
+ add merges to qh.facet_mergeset
+ if vertices record neighboring facets
+ rename redundant vertices
+ update qh.facet_mergeset
+ if vneighbors ??
+ tests vertex neighbors for convexity at end
+*/
+void qh_all_merges(qhT *qh, boolT othermerge, boolT vneighbors) {
+ facetT *facet1, *facet2;
+ mergeT *merge;
+ boolT wasmerge= True, isreduce;
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+ vertexT *vertex;
+ mergeType mergetype;
+ int numcoplanar=0, numconcave=0, numdegenredun= 0, numnewmerges= 0;
+
+ trace2((qh, qh->ferr, 2010, "qh_all_merges: starting to merge facets beginning from f%d\n",
+ getid_(qh->newfacet_list)));
+ while (True) {
+ wasmerge= False;
+ while (qh_setsize(qh, qh->facet_mergeset)) {
+ while ((merge= (mergeT*)qh_setdellast(qh->facet_mergeset))) {
+ facet1= merge->facet1;
+ facet2= merge->facet2;
+ mergetype= merge->type;
+ qh_memfree_(qh, merge, (int)sizeof(mergeT), freelistp);
+ if (facet1->visible || facet2->visible) /*deleted facet*/
+ continue;
+ if ((facet1->newfacet && !facet1->tested)
+ || (facet2->newfacet && !facet2->tested)) {
+ if (qh->MERGEindependent && mergetype <= MRGanglecoplanar)
+ continue; /* perform independent sets of merges */
+ }
+ qh_merge_nonconvex(qh, facet1, facet2, mergetype);
+ numdegenredun += qh_merge_degenredundant(qh);
+ numnewmerges++;
+ wasmerge= True;
+ if (mergetype == MRGconcave)
+ numconcave++;
+ else /* MRGcoplanar or MRGanglecoplanar */
+ numcoplanar++;
+ } /* while setdellast */
+ if (qh->POSTmerging && qh->hull_dim <= qh_DIMreduceBuild
+ && numnewmerges > qh_MAXnewmerges) {
+ numnewmerges= 0;
+ qh_reducevertices(qh); /* otherwise large post merges too slow */
+ }
+ qh_getmergeset(qh, qh->newfacet_list); /* facet_mergeset */
+ } /* while mergeset */
+ if (qh->VERTEXneighbors) {
+ isreduce= False;
+ if (qh->hull_dim >=4 && qh->POSTmerging) {
+ FORALLvertices
+ vertex->delridge= True;
+ isreduce= True;
+ }
+ if ((wasmerge || othermerge) && (!qh->MERGEexact || qh->POSTmerging)
+ && qh->hull_dim <= qh_DIMreduceBuild) {
+ othermerge= False;
+ isreduce= True;
+ }
+ if (isreduce) {
+ if (qh_reducevertices(qh)) {
+ qh_getmergeset(qh, qh->newfacet_list); /* facet_mergeset */
+ continue;
+ }
+ }
+ }
+ if (vneighbors && qh_test_vneighbors(qh /* qh->newfacet_list */))
+ continue;
+ break;
+ } /* while (True) */
+ if (qh->CHECKfrequently && !qh->MERGEexact) {
+ qh->old_randomdist= qh->RANDOMdist;
+ qh->RANDOMdist= False;
+ qh_checkconvex(qh, qh->newfacet_list, qh_ALGORITHMfault);
+ /* qh_checkconnect(qh); [this is slow and it changes the facet order] */
+ qh->RANDOMdist= qh->old_randomdist;
+ }
+ trace1((qh, qh->ferr, 1009, "qh_all_merges: merged %d coplanar facets %d concave facets and %d degen or redundant facets.\n",
+ numcoplanar, numconcave, numdegenredun));
+ if (qh->IStracing >= 4 && qh->num_facets < 50)
+ qh_printlists(qh);
+} /* all_merges */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="appendmergeset">-</a>
+
+ qh_appendmergeset(qh, facet, neighbor, mergetype, angle )
+ appends an entry to qh.facet_mergeset or qh.degen_mergeset
+
+ angle ignored if NULL or !qh.ANGLEmerge
+
+ returns:
+ merge appended to facet_mergeset or degen_mergeset
+ sets ->degenerate or ->redundant if degen_mergeset
+
+ see:
+ qh_test_appendmerge()
+
+ design:
+ allocate merge entry
+ if regular merge
+ append to qh.facet_mergeset
+ else if degenerate merge and qh.facet_mergeset is all degenerate
+ append to qh.degen_mergeset
+ else if degenerate merge
+ prepend to qh.degen_mergeset
+ else if redundant merge
+ append to qh.degen_mergeset
+*/
+void qh_appendmergeset(qhT *qh, facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle) {
+ mergeT *merge, *lastmerge;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+
+ if (facet->redundant)
+ return;
+ if (facet->degenerate && mergetype == MRGdegen)
+ return;
+ qh_memalloc_(qh, (int)sizeof(mergeT), freelistp, merge, mergeT);
+ merge->facet1= facet;
+ merge->facet2= neighbor;
+ merge->type= mergetype;
+ if (angle && qh->ANGLEmerge)
+ merge->angle= *angle;
+ if (mergetype < MRGdegen)
+ qh_setappend(qh, &(qh->facet_mergeset), merge);
+ else if (mergetype == MRGdegen) {
+ facet->degenerate= True;
+ if (!(lastmerge= (mergeT*)qh_setlast(qh->degen_mergeset))
+ || lastmerge->type == MRGdegen)
+ qh_setappend(qh, &(qh->degen_mergeset), merge);
+ else
+ qh_setaddnth(qh, &(qh->degen_mergeset), 0, merge);
+ }else if (mergetype == MRGredundant) {
+ facet->redundant= True;
+ qh_setappend(qh, &(qh->degen_mergeset), merge);
+ }else /* mergetype == MRGmirror */ {
+ if (facet->redundant || neighbor->redundant) {
+ qh_fprintf(qh, qh->ferr, 6092, "qhull error (qh_appendmergeset): facet f%d or f%d is already a mirrored facet\n",
+ facet->id, neighbor->id);
+ qh_errexit2(qh, qh_ERRqhull, facet, neighbor);
+ }
+ if (!qh_setequal(facet->vertices, neighbor->vertices)) {
+ qh_fprintf(qh, qh->ferr, 6093, "qhull error (qh_appendmergeset): mirrored facets f%d and f%d do not have the same vertices\n",
+ facet->id, neighbor->id);
+ qh_errexit2(qh, qh_ERRqhull, facet, neighbor);
+ }
+ facet->redundant= True;
+ neighbor->redundant= True;
+ qh_setappend(qh, &(qh->degen_mergeset), merge);
+ }
+} /* appendmergeset */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="basevertices">-</a>
+
+ qh_basevertices(qh, samecycle )
+ return temporary set of base vertices for samecycle
+ samecycle is first facet in the cycle
+ assumes apex is SETfirst_( samecycle->vertices )
+
+ returns:
+ vertices(settemp)
+ all ->seen are cleared
+
+ notes:
+ uses qh_vertex_visit;
+
+ design:
+ for each facet in samecycle
+ for each unseen vertex in facet->vertices
+ append to result
+*/
+setT *qh_basevertices(qhT *qh, facetT *samecycle) {
+ facetT *same;
+ vertexT *apex, *vertex, **vertexp;
+ setT *vertices= qh_settemp(qh, qh->TEMPsize);
+
+ apex= SETfirstt_(samecycle->vertices, vertexT);
+ apex->visitid= ++qh->vertex_visit;
+ FORALLsame_cycle_(samecycle) {
+ if (same->mergeridge)
+ continue;
+ FOREACHvertex_(same->vertices) {
+ if (vertex->visitid != qh->vertex_visit) {
+ qh_setappend(qh, &vertices, vertex);
+ vertex->visitid= qh->vertex_visit;
+ vertex->seen= False;
+ }
+ }
+ }
+ trace4((qh, qh->ferr, 4019, "qh_basevertices: found %d vertices\n",
+ qh_setsize(qh, vertices)));
+ return vertices;
+} /* basevertices */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="checkconnect">-</a>
+
+ qh_checkconnect(qh)
+ check that new facets are connected
+ new facets are on qh.newfacet_list
+
+ notes:
+ this is slow and it changes the order of the facets
+ uses qh.visit_id
+
+ design:
+ move first new facet to end of qh.facet_list
+ for all newly appended facets
+ append unvisited neighbors to end of qh.facet_list
+ for all new facets
+ report error if unvisited
+*/
+void qh_checkconnect(qhT *qh /* qh->newfacet_list */) {
+ facetT *facet, *newfacet, *errfacet= NULL, *neighbor, **neighborp;
+
+ facet= qh->newfacet_list;
+ qh_removefacet(qh, facet);
+ qh_appendfacet(qh, facet);
+ facet->visitid= ++qh->visit_id;
+ FORALLfacet_(facet) {
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid != qh->visit_id) {
+ qh_removefacet(qh, neighbor);
+ qh_appendfacet(qh, neighbor);
+ neighbor->visitid= qh->visit_id;
+ }
+ }
+ }
+ FORALLnew_facets {
+ if (newfacet->visitid == qh->visit_id)
+ break;
+ qh_fprintf(qh, qh->ferr, 6094, "qhull error: f%d is not attached to the new facets\n",
+ newfacet->id);
+ errfacet= newfacet;
+ }
+ if (errfacet)
+ qh_errexit(qh, qh_ERRqhull, errfacet, NULL);
+} /* checkconnect */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="checkzero">-</a>
+
+ qh_checkzero(qh, testall )
+ check that facets are clearly convex for qh.DISTround with qh.MERGEexact
+
+ if testall,
+ test all facets for qh.MERGEexact post-merging
+ else
+ test qh.newfacet_list
+
+ if qh.MERGEexact,
+ allows coplanar ridges
+ skips convexity test while qh.ZEROall_ok
+
+ returns:
+ True if all facets !flipped, !dupridge, normal
+ if all horizon facets are simplicial
+ if all vertices are clearly below neighbor
+ if all opposite vertices of horizon are below
+ clears qh.ZEROall_ok if any problems or coplanar facets
+
+ notes:
+ uses qh.vertex_visit
+ horizon facets may define multiple new facets
+
+ design:
+ for all facets in qh.newfacet_list or qh.facet_list
+ check for flagged faults (flipped, etc.)
+ for all facets in qh.newfacet_list or qh.facet_list
+ for each neighbor of facet
+ skip horizon facets for qh.newfacet_list
+ test the opposite vertex
+ if qh.newfacet_list
+ test the other vertices in the facet's horizon facet
+*/
+boolT qh_checkzero(qhT *qh, boolT testall) {
+ facetT *facet, *neighbor, **neighborp;
+ facetT *horizon, *facetlist;
+ int neighbor_i;
+ vertexT *vertex, **vertexp;
+ realT dist;
+
+ if (testall)
+ facetlist= qh->facet_list;
+ else {
+ facetlist= qh->newfacet_list;
+ FORALLfacet_(facetlist) {
+ horizon= SETfirstt_(facet->neighbors, facetT);
+ if (!horizon->simplicial)
+ goto LABELproblem;
+ if (facet->flipped || facet->dupridge || !facet->normal)
+ goto LABELproblem;
+ }
+ if (qh->MERGEexact && qh->ZEROall_ok) {
+ trace2((qh, qh->ferr, 2011, "qh_checkzero: skip convexity check until first pre-merge\n"));
+ return True;
+ }
+ }
+ FORALLfacet_(facetlist) {
+ qh->vertex_visit++;
+ neighbor_i= 0;
+ horizon= NULL;
+ FOREACHneighbor_(facet) {
+ if (!neighbor_i && !testall) {
+ horizon= neighbor;
+ neighbor_i++;
+ continue; /* horizon facet tested in qh_findhorizon */
+ }
+ vertex= SETelemt_(facet->vertices, neighbor_i++, vertexT);
+ vertex->visitid= qh->vertex_visit;
+ zzinc_(Zdistzero);
+ qh_distplane(qh, vertex->point, neighbor, &dist);
+ if (dist >= -qh->DISTround) {
+ qh->ZEROall_ok= False;
+ if (!qh->MERGEexact || testall || dist > qh->DISTround)
+ goto LABELnonconvex;
+ }
+ }
+ if (!testall && horizon) {
+ FOREACHvertex_(horizon->vertices) {
+ if (vertex->visitid != qh->vertex_visit) {
+ zzinc_(Zdistzero);
+ qh_distplane(qh, vertex->point, facet, &dist);
+ if (dist >= -qh->DISTround) {
+ qh->ZEROall_ok= False;
+ if (!qh->MERGEexact || dist > qh->DISTround)
+ goto LABELnonconvex;
+ }
+ break;
+ }
+ }
+ }
+ }
+ trace2((qh, qh->ferr, 2012, "qh_checkzero: testall %d, facets are %s\n", testall,
+ (qh->MERGEexact && !testall) ?
+ "not concave, flipped, or duplicate ridged" : "clearly convex"));
+ return True;
+
+ LABELproblem:
+ qh->ZEROall_ok= False;
+ trace2((qh, qh->ferr, 2013, "qh_checkzero: facet f%d needs pre-merging\n",
+ facet->id));
+ return False;
+
+ LABELnonconvex:
+ trace2((qh, qh->ferr, 2014, "qh_checkzero: facet f%d and f%d are not clearly convex. v%d dist %.2g\n",
+ facet->id, neighbor->id, vertex->id, dist));
+ return False;
+} /* checkzero */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="compareangle">-</a>
+
+ qh_compareangle(angle1, angle2 )
+ used by qsort() to order merges by angle
+*/
+int qh_compareangle(const void *p1, const void *p2) {
+ const mergeT *a= *((mergeT *const*)p1), *b= *((mergeT *const*)p2);
+
+ return((a->angle > b->angle) ? 1 : -1);
+} /* compareangle */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="comparemerge">-</a>
+
+ qh_comparemerge(merge1, merge2 )
+ used by qsort() to order merges
+*/
+int qh_comparemerge(const void *p1, const void *p2) {
+ const mergeT *a= *((mergeT *const*)p1), *b= *((mergeT *const*)p2);
+
+ return(a->type - b->type);
+} /* comparemerge */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="comparevisit">-</a>
+
+ qh_comparevisit(vertex1, vertex2 )
+ used by qsort() to order vertices by their visitid
+*/
+int qh_comparevisit(const void *p1, const void *p2) {
+ const vertexT *a= *((vertexT *const*)p1), *b= *((vertexT *const*)p2);
+
+ return(a->visitid - b->visitid);
+} /* comparevisit */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="copynonconvex">-</a>
+
+ qh_copynonconvex(qh, atridge )
+ set non-convex flag on other ridges (if any) between same neighbors
+
+ notes:
+ may be faster if use smaller ridge set
+
+ design:
+ for each ridge of atridge's top facet
+ if ridge shares the same neighbor
+ set nonconvex flag
+*/
+void qh_copynonconvex(qhT *qh, ridgeT *atridge) {
+ facetT *facet, *otherfacet;
+ ridgeT *ridge, **ridgep;
+
+ facet= atridge->top;
+ otherfacet= atridge->bottom;
+ FOREACHridge_(facet->ridges) {
+ if (otherfacet == otherfacet_(ridge, facet) && ridge != atridge) {
+ ridge->nonconvex= True;
+ trace4((qh, qh->ferr, 4020, "qh_copynonconvex: moved nonconvex flag from r%d to r%d\n",
+ atridge->id, ridge->id));
+ break;
+ }
+ }
+} /* copynonconvex */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="degen_redundant_facet">-</a>
+
+ qh_degen_redundant_facet(qh, facet )
+ check facet for degen. or redundancy
+
+ notes:
+ bumps vertex_visit
+ called if a facet was redundant but no longer is (qh_merge_degenredundant)
+ qh_appendmergeset() only appends first reference to facet (i.e., redundant)
+
+ see:
+ qh_degen_redundant_neighbors()
+
+ design:
+ test for redundant neighbor
+ test for degenerate facet
+*/
+void qh_degen_redundant_facet(qhT *qh, facetT *facet) {
+ vertexT *vertex, **vertexp;
+ facetT *neighbor, **neighborp;
+
+ trace4((qh, qh->ferr, 4021, "qh_degen_redundant_facet: test facet f%d for degen/redundant\n",
+ facet->id));
+ FOREACHneighbor_(facet) {
+ qh->vertex_visit++;
+ FOREACHvertex_(neighbor->vertices)
+ vertex->visitid= qh->vertex_visit;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->visitid != qh->vertex_visit)
+ break;
+ }
+ if (!vertex) {
+ qh_appendmergeset(qh, facet, neighbor, MRGredundant, NULL);
+ trace2((qh, qh->ferr, 2015, "qh_degen_redundant_facet: f%d is contained in f%d. merge\n", facet->id, neighbor->id));
+ return;
+ }
+ }
+ if (qh_setsize(qh, facet->neighbors) < qh->hull_dim) {
+ qh_appendmergeset(qh, facet, facet, MRGdegen, NULL);
+ trace2((qh, qh->ferr, 2016, "qh_degen_redundant_neighbors: f%d is degenerate.\n", facet->id));
+ }
+} /* degen_redundant_facet */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="degen_redundant_neighbors">-</a>
+
+ qh_degen_redundant_neighbors(qh, facet, delfacet, )
+ append degenerate and redundant neighbors to facet_mergeset
+ if delfacet,
+ only checks neighbors of both delfacet and facet
+ also checks current facet for degeneracy
+
+ notes:
+ bumps vertex_visit
+ called for each qh_mergefacet() and qh_mergecycle()
+ merge and statistics occur in merge_nonconvex
+ qh_appendmergeset() only appends first reference to facet (i.e., redundant)
+ it appends redundant facets after degenerate ones
+
+ a degenerate facet has fewer than hull_dim neighbors
+ a redundant facet's vertices is a subset of its neighbor's vertices
+ tests for redundant merges first (appendmergeset is nop for others)
+ in a merge, only needs to test neighbors of merged facet
+
+ see:
+ qh_merge_degenredundant() and qh_degen_redundant_facet()
+
+ design:
+ test for degenerate facet
+ test for redundant neighbor
+ test for degenerate neighbor
+*/
+void qh_degen_redundant_neighbors(qhT *qh, facetT *facet, facetT *delfacet) {
+ vertexT *vertex, **vertexp;
+ facetT *neighbor, **neighborp;
+ int size;
+
+ trace4((qh, qh->ferr, 4022, "qh_degen_redundant_neighbors: test neighbors of f%d with delfacet f%d\n",
+ facet->id, getid_(delfacet)));
+ if ((size= qh_setsize(qh, facet->neighbors)) < qh->hull_dim) {
+ qh_appendmergeset(qh, facet, facet, MRGdegen, NULL);
+ trace2((qh, qh->ferr, 2017, "qh_degen_redundant_neighbors: f%d is degenerate with %d neighbors.\n", facet->id, size));
+ }
+ if (!delfacet)
+ delfacet= facet;
+ qh->vertex_visit++;
+ FOREACHvertex_(facet->vertices)
+ vertex->visitid= qh->vertex_visit;
+ FOREACHneighbor_(delfacet) {
+ /* uses early out instead of checking vertex count */
+ if (neighbor == facet)
+ continue;
+ FOREACHvertex_(neighbor->vertices) {
+ if (vertex->visitid != qh->vertex_visit)
+ break;
+ }
+ if (!vertex) {
+ qh_appendmergeset(qh, neighbor, facet, MRGredundant, NULL);
+ trace2((qh, qh->ferr, 2018, "qh_degen_redundant_neighbors: f%d is contained in f%d. merge\n", neighbor->id, facet->id));
+ }
+ }
+ FOREACHneighbor_(delfacet) { /* redundant merges occur first */
+ if (neighbor == facet)
+ continue;
+ if ((size= qh_setsize(qh, neighbor->neighbors)) < qh->hull_dim) {
+ qh_appendmergeset(qh, neighbor, neighbor, MRGdegen, NULL);
+ trace2((qh, qh->ferr, 2019, "qh_degen_redundant_neighbors: f%d is degenerate with %d neighbors. Neighbor of f%d.\n", neighbor->id, size, facet->id));
+ }
+ }
+} /* degen_redundant_neighbors */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="find_newvertex">-</a>
+
+ qh_find_newvertex(qh, oldvertex, vertices, ridges )
+ locate new vertex for renaming old vertex
+ vertices is a set of possible new vertices
+ vertices sorted by number of deleted ridges
+
+ returns:
+ newvertex or NULL
+ each ridge includes both vertex and oldvertex
+ vertices sorted by number of deleted ridges
+
+ notes:
+ modifies vertex->visitid
+ new vertex is in one of the ridges
+ renaming will not cause a duplicate ridge
+ renaming will minimize the number of deleted ridges
+ newvertex may not be adjacent in the dual (though unlikely)
+
+ design:
+ for each vertex in vertices
+ set vertex->visitid to number of references in ridges
+ remove unvisited vertices
+ set qh.vertex_visit above all possible values
+ sort vertices by number of references in ridges
+ add each ridge to qh.hash_table
+ for each vertex in vertices
+ look for a vertex that would not cause a duplicate ridge after a rename
+*/
+vertexT *qh_find_newvertex(qhT *qh, vertexT *oldvertex, setT *vertices, setT *ridges) {
+ vertexT *vertex, **vertexp;
+ setT *newridges;
+ ridgeT *ridge, **ridgep;
+ int size, hashsize;
+ int hash;
+
+#ifndef qh_NOtrace
+ if (qh->IStracing >= 4) {
+ qh_fprintf(qh, qh->ferr, 8063, "qh_find_newvertex: find new vertex for v%d from ",
+ oldvertex->id);
+ FOREACHvertex_(vertices)
+ qh_fprintf(qh, qh->ferr, 8064, "v%d ", vertex->id);
+ FOREACHridge_(ridges)
+ qh_fprintf(qh, qh->ferr, 8065, "r%d ", ridge->id);
+ qh_fprintf(qh, qh->ferr, 8066, "\n");
+ }
+#endif
+ FOREACHvertex_(vertices)
+ vertex->visitid= 0;
+ FOREACHridge_(ridges) {
+ FOREACHvertex_(ridge->vertices)
+ vertex->visitid++;
+ }
+ FOREACHvertex_(vertices) {
+ if (!vertex->visitid) {
+ qh_setdelnth(qh, vertices, SETindex_(vertices,vertex));
+ vertexp--; /* repeat since deleted this vertex */
+ }
+ }
+ qh->vertex_visit += (unsigned int)qh_setsize(qh, ridges);
+ if (!qh_setsize(qh, vertices)) {
+ trace4((qh, qh->ferr, 4023, "qh_find_newvertex: vertices not in ridges for v%d\n",
+ oldvertex->id));
+ return NULL;
+ }
+ qsort(SETaddr_(vertices, vertexT), (size_t)qh_setsize(qh, vertices),
+ sizeof(vertexT *), qh_comparevisit);
+ /* can now use qh->vertex_visit */
+ if (qh->PRINTstatistics) {
+ size= qh_setsize(qh, vertices);
+ zinc_(Zintersect);
+ zadd_(Zintersecttot, size);
+ zmax_(Zintersectmax, size);
+ }
+ hashsize= qh_newhashtable(qh, qh_setsize(qh, ridges));
+ FOREACHridge_(ridges)
+ qh_hashridge(qh, qh->hash_table, hashsize, ridge, oldvertex);
+ FOREACHvertex_(vertices) {
+ newridges= qh_vertexridges(qh, vertex);
+ FOREACHridge_(newridges) {
+ if (qh_hashridge_find(qh, qh->hash_table, hashsize, ridge, vertex, oldvertex, &hash)) {
+ zinc_(Zdupridge);
+ break;
+ }
+ }
+ qh_settempfree(qh, &newridges);
+ if (!ridge)
+ break; /* found a rename */
+ }
+ if (vertex) {
+ /* counted in qh_renamevertex */
+ trace2((qh, qh->ferr, 2020, "qh_find_newvertex: found v%d for old v%d from %d vertices and %d ridges.\n",
+ vertex->id, oldvertex->id, qh_setsize(qh, vertices), qh_setsize(qh, ridges)));
+ }else {
+ zinc_(Zfindfail);
+ trace0((qh, qh->ferr, 14, "qh_find_newvertex: no vertex for renaming v%d(all duplicated ridges) during p%d\n",
+ oldvertex->id, qh->furthest_id));
+ }
+ qh_setfree(qh, &qh->hash_table);
+ return vertex;
+} /* find_newvertex */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="findbest_test">-</a>
+
+ qh_findbest_test(qh, testcentrum, facet, neighbor, bestfacet, dist, mindist, maxdist )
+ test neighbor of facet for qh_findbestneighbor()
+ if testcentrum,
+ tests centrum (assumes it is defined)
+ else
+ tests vertices
+
+ returns:
+ if a better facet (i.e., vertices/centrum of facet closer to neighbor)
+ updates bestfacet, dist, mindist, and maxdist
+*/
+void qh_findbest_test(qhT *qh, boolT testcentrum, facetT *facet, facetT *neighbor,
+ facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp) {
+ realT dist, mindist, maxdist;
+
+ if (testcentrum) {
+ zzinc_(Zbestdist);
+ qh_distplane(qh, facet->center, neighbor, &dist);
+ dist *= qh->hull_dim; /* estimate furthest vertex */
+ if (dist < 0) {
+ maxdist= 0;
+ mindist= dist;
+ dist= -dist;
+ }else {
+ mindist= 0;
+ maxdist= dist;
+ }
+ }else
+ dist= qh_getdistance(qh, facet, neighbor, &mindist, &maxdist);
+ if (dist < *distp) {
+ *bestfacet= neighbor;
+ *mindistp= mindist;
+ *maxdistp= maxdist;
+ *distp= dist;
+ }
+} /* findbest_test */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="findbestneighbor">-</a>
+
+ qh_findbestneighbor(qh, facet, dist, mindist, maxdist )
+ finds best neighbor (least dist) of a facet for merging
+
+ returns:
+ returns min and max distances and their max absolute value
+
+ notes:
+ error if qh_ASvoronoi
+ avoids merging old into new
+ assumes ridge->nonconvex only set on one ridge between a pair of facets
+ could use an early out predicate but not worth it
+
+ design:
+ if a large facet
+ will test centrum
+ else
+ will test vertices
+ if a large facet
+ test nonconvex neighbors for best merge
+ else
+ test all neighbors for the best merge
+ if testing centrum
+ get distance information
+*/
+facetT *qh_findbestneighbor(qhT *qh, facetT *facet, realT *distp, realT *mindistp, realT *maxdistp) {
+ facetT *neighbor, **neighborp, *bestfacet= NULL;
+ ridgeT *ridge, **ridgep;
+ boolT nonconvex= True, testcentrum= False;
+ int size= qh_setsize(qh, facet->vertices);
+
+ if(qh->CENTERtype==qh_ASvoronoi){
+ qh_fprintf(qh, qh->ferr, 6272, "qhull error: cannot call qh_findbestneighor for f%d while qh.CENTERtype is qh_ASvoronoi\n", facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ *distp= REALmax;
+ if (size > qh_BESTcentrum2 * qh->hull_dim + qh_BESTcentrum) {
+ testcentrum= True;
+ zinc_(Zbestcentrum);
+ if (!facet->center)
+ facet->center= qh_getcentrum(qh, facet);
+ }
+ if (size > qh->hull_dim + qh_BESTnonconvex) {
+ FOREACHridge_(facet->ridges) {
+ if (ridge->nonconvex) {
+ neighbor= otherfacet_(ridge, facet);
+ qh_findbest_test(qh, testcentrum, facet, neighbor,
+ &bestfacet, distp, mindistp, maxdistp);
+ }
+ }
+ }
+ if (!bestfacet) {
+ nonconvex= False;
+ FOREACHneighbor_(facet)
+ qh_findbest_test(qh, testcentrum, facet, neighbor,
+ &bestfacet, distp, mindistp, maxdistp);
+ }
+ if (!bestfacet) {
+ qh_fprintf(qh, qh->ferr, 6095, "qhull internal error (qh_findbestneighbor): no neighbors for f%d\n", facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ if (testcentrum)
+ qh_getdistance(qh, facet, bestfacet, mindistp, maxdistp);
+ trace3((qh, qh->ferr, 3002, "qh_findbestneighbor: f%d is best neighbor for f%d testcentrum? %d nonconvex? %d dist %2.2g min %2.2g max %2.2g\n",
+ bestfacet->id, facet->id, testcentrum, nonconvex, *distp, *mindistp, *maxdistp));
+ return(bestfacet);
+} /* findbestneighbor */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="flippedmerges">-</a>
+
+ qh_flippedmerges(qh, facetlist, wasmerge )
+ merge flipped facets into best neighbor
+ assumes qh.facet_mergeset at top of temporary stack
+
+ returns:
+ no flipped facets on facetlist
+ sets wasmerge if merge occurred
+ degen/redundant merges passed through
+
+ notes:
+ othermerges not needed since qh.facet_mergeset is empty before & after
+ keep it in case of change
+
+ design:
+ append flipped facets to qh.facetmergeset
+ for each flipped merge
+ find best neighbor
+ merge facet into neighbor
+ merge degenerate and redundant facets
+ remove flipped merges from qh.facet_mergeset
+*/
+void qh_flippedmerges(qhT *qh, facetT *facetlist, boolT *wasmerge) {
+ facetT *facet, *neighbor, *facet1;
+ realT dist, mindist, maxdist;
+ mergeT *merge, **mergep;
+ setT *othermerges;
+ int nummerge=0;
+
+ trace4((qh, qh->ferr, 4024, "qh_flippedmerges: begin\n"));
+ FORALLfacet_(facetlist) {
+ if (facet->flipped && !facet->visible)
+ qh_appendmergeset(qh, facet, facet, MRGflip, NULL);
+ }
+ othermerges= qh_settemppop(qh); /* was facet_mergeset */
+ qh->facet_mergeset= qh_settemp(qh, qh->TEMPsize);
+ qh_settemppush(qh, othermerges);
+ FOREACHmerge_(othermerges) {
+ facet1= merge->facet1;
+ if (merge->type != MRGflip || facet1->visible)
+ continue;
+ if (qh->TRACEmerge-1 == zzval_(Ztotmerge))
+ qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
+ neighbor= qh_findbestneighbor(qh, facet1, &dist, &mindist, &maxdist);
+ trace0((qh, qh->ferr, 15, "qh_flippedmerges: merge flipped f%d into f%d dist %2.2g during p%d\n",
+ facet1->id, neighbor->id, dist, qh->furthest_id));
+ qh_mergefacet(qh, facet1, neighbor, &mindist, &maxdist, !qh_MERGEapex);
+ nummerge++;
+ if (qh->PRINTstatistics) {
+ zinc_(Zflipped);
+ wadd_(Wflippedtot, dist);
+ wmax_(Wflippedmax, dist);
+ }
+ qh_merge_degenredundant(qh);
+ }
+ FOREACHmerge_(othermerges) {
+ if (merge->facet1->visible || merge->facet2->visible)
+ qh_memfree(qh, merge, (int)sizeof(mergeT));
+ else
+ qh_setappend(qh, &qh->facet_mergeset, merge);
+ }
+ qh_settempfree(qh, &othermerges);
+ if (nummerge)
+ *wasmerge= True;
+ trace1((qh, qh->ferr, 1010, "qh_flippedmerges: merged %d flipped facets into a good neighbor\n", nummerge));
+} /* flippedmerges */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="forcedmerges">-</a>
+
+ qh_forcedmerges(qh, wasmerge )
+ merge duplicated ridges
+
+ returns:
+ removes all duplicate ridges on facet_mergeset
+ wasmerge set if merge
+ qh.facet_mergeset may include non-forced merges(none for now)
+ qh.degen_mergeset includes degen/redun merges
+
+ notes:
+ duplicate ridges occur when the horizon is pinched,
+ i.e. a subridge occurs in more than two horizon ridges.
+ could rename vertices that pinch the horizon
+ assumes qh_merge_degenredundant() has not be called
+ othermerges isn't needed since facet_mergeset is empty afterwards
+ keep it in case of change
+
+ design:
+ for each duplicate ridge
+ find current facets by chasing f.replace links
+ check for wide merge due to duplicate ridge
+ determine best direction for facet
+ merge one facet into the other
+ remove duplicate ridges from qh.facet_mergeset
+*/
+void qh_forcedmerges(qhT *qh, boolT *wasmerge) {
+ facetT *facet1, *facet2;
+ mergeT *merge, **mergep;
+ realT dist1, dist2, mindist1, mindist2, maxdist1, maxdist2;
+ setT *othermerges;
+ int nummerge=0, numflip=0;
+
+ if (qh->TRACEmerge-1 == zzval_(Ztotmerge))
+ qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
+ trace4((qh, qh->ferr, 4025, "qh_forcedmerges: begin\n"));
+ othermerges= qh_settemppop(qh); /* was facet_mergeset */
+ qh->facet_mergeset= qh_settemp(qh, qh->TEMPsize);
+ qh_settemppush(qh, othermerges);
+ FOREACHmerge_(othermerges) {
+ if (merge->type != MRGridge)
+ continue;
+ if (qh->TRACEmerge-1 == zzval_(Ztotmerge))
+ qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
+ facet1= merge->facet1;
+ facet2= merge->facet2;
+ while (facet1->visible) /* must exist, no qh_merge_degenredunant */
+ facet1= facet1->f.replace; /* previously merged facet */
+ while (facet2->visible)
+ facet2= facet2->f.replace; /* previously merged facet */
+ if (facet1 == facet2)
+ continue;
+ if (!qh_setin(facet2->neighbors, facet1)) {
+ qh_fprintf(qh, qh->ferr, 6096, "qhull internal error (qh_forcedmerges): f%d and f%d had a duplicate ridge but as f%d and f%d they are no longer neighbors\n",
+ merge->facet1->id, merge->facet2->id, facet1->id, facet2->id);
+ qh_errexit2(qh, qh_ERRqhull, facet1, facet2);
+ }
+ dist1= qh_getdistance(qh, facet1, facet2, &mindist1, &maxdist1);
+ dist2= qh_getdistance(qh, facet2, facet1, &mindist2, &maxdist2);
+ qh_check_dupridge(qh, facet1, dist1, facet2, dist2);
+ if (dist1 < dist2)
+ qh_mergefacet(qh, facet1, facet2, &mindist1, &maxdist1, !qh_MERGEapex);
+ else {
+ qh_mergefacet(qh, facet2, facet1, &mindist2, &maxdist2, !qh_MERGEapex);
+ dist1= dist2;
+ facet1= facet2;
+ }
+ if (facet1->flipped) {
+ zinc_(Zmergeflipdup);
+ numflip++;
+ }else
+ nummerge++;
+ if (qh->PRINTstatistics) {
+ zinc_(Zduplicate);
+ wadd_(Wduplicatetot, dist1);
+ wmax_(Wduplicatemax, dist1);
+ }
+ }
+ FOREACHmerge_(othermerges) {
+ if (merge->type == MRGridge)
+ qh_memfree(qh, merge, (int)sizeof(mergeT));
+ else
+ qh_setappend(qh, &qh->facet_mergeset, merge);
+ }
+ qh_settempfree(qh, &othermerges);
+ if (nummerge)
+ *wasmerge= True;
+ trace1((qh, qh->ferr, 1011, "qh_forcedmerges: merged %d facets and %d flipped facets across duplicated ridges\n",
+ nummerge, numflip));
+} /* forcedmerges */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="getmergeset">-</a>
+
+ qh_getmergeset(qh, facetlist )
+ determines nonconvex facets on facetlist
+ tests !tested ridges and nonconvex ridges of !tested facets
+
+ returns:
+ returns sorted qh.facet_mergeset of facet-neighbor pairs to be merged
+ all ridges tested
+
+ notes:
+ assumes no nonconvex ridges with both facets tested
+ uses facet->tested/ridge->tested to prevent duplicate tests
+ can not limit tests to modified ridges since the centrum changed
+ uses qh.visit_id
+
+ see:
+ qh_getmergeset_initial()
+
+ design:
+ for each facet on facetlist
+ for each ridge of facet
+ if untested ridge
+ test ridge for convexity
+ if non-convex
+ append ridge to qh.facet_mergeset
+ sort qh.facet_mergeset by angle
+*/
+void qh_getmergeset(qhT *qh, facetT *facetlist) {
+ facetT *facet, *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+ int nummerges;
+
+ nummerges= qh_setsize(qh, qh->facet_mergeset);
+ trace4((qh, qh->ferr, 4026, "qh_getmergeset: started.\n"));
+ qh->visit_id++;
+ FORALLfacet_(facetlist) {
+ if (facet->tested)
+ continue;
+ facet->visitid= qh->visit_id;
+ facet->tested= True; /* must be non-simplicial due to merge */
+ FOREACHneighbor_(facet)
+ neighbor->seen= False;
+ FOREACHridge_(facet->ridges) {
+ if (ridge->tested && !ridge->nonconvex)
+ continue;
+ /* if tested & nonconvex, need to append merge */
+ neighbor= otherfacet_(ridge, facet);
+ if (neighbor->seen) {
+ ridge->tested= True;
+ ridge->nonconvex= False;
+ }else if (neighbor->visitid != qh->visit_id) {
+ ridge->tested= True;
+ ridge->nonconvex= False;
+ neighbor->seen= True; /* only one ridge is marked nonconvex */
+ if (qh_test_appendmerge(qh, facet, neighbor))
+ ridge->nonconvex= True;
+ }
+ }
+ }
+ nummerges= qh_setsize(qh, qh->facet_mergeset);
+ if (qh->ANGLEmerge)
+ qsort(SETaddr_(qh->facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_compareangle);
+ else
+ qsort(SETaddr_(qh->facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_comparemerge);
+ if (qh->POSTmerging) {
+ zadd_(Zmergesettot2, nummerges);
+ }else {
+ zadd_(Zmergesettot, nummerges);
+ zmax_(Zmergesetmax, nummerges);
+ }
+ trace2((qh, qh->ferr, 2021, "qh_getmergeset: %d merges found\n", nummerges));
+} /* getmergeset */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="getmergeset_initial">-</a>
+
+ qh_getmergeset_initial(qh, facetlist )
+ determine initial qh.facet_mergeset for facets
+ tests all facet/neighbor pairs on facetlist
+
+ returns:
+ sorted qh.facet_mergeset with nonconvex ridges
+ sets facet->tested, ridge->tested, and ridge->nonconvex
+
+ notes:
+ uses visit_id, assumes ridge->nonconvex is False
+
+ see:
+ qh_getmergeset()
+
+ design:
+ for each facet on facetlist
+ for each untested neighbor of facet
+ test facet and neighbor for convexity
+ if non-convex
+ append merge to qh.facet_mergeset
+ mark one of the ridges as nonconvex
+ sort qh.facet_mergeset by angle
+*/
+void qh_getmergeset_initial(qhT *qh, facetT *facetlist) {
+ facetT *facet, *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+ int nummerges;
+
+ qh->visit_id++;
+ FORALLfacet_(facetlist) {
+ facet->visitid= qh->visit_id;
+ facet->tested= True;
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid != qh->visit_id) {
+ if (qh_test_appendmerge(qh, facet, neighbor)) {
+ FOREACHridge_(neighbor->ridges) {
+ if (facet == otherfacet_(ridge, neighbor)) {
+ ridge->nonconvex= True;
+ break; /* only one ridge is marked nonconvex */
+ }
+ }
+ }
+ }
+ }
+ FOREACHridge_(facet->ridges)
+ ridge->tested= True;
+ }
+ nummerges= qh_setsize(qh, qh->facet_mergeset);
+ if (qh->ANGLEmerge)
+ qsort(SETaddr_(qh->facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_compareangle);
+ else
+ qsort(SETaddr_(qh->facet_mergeset, mergeT), (size_t)nummerges, sizeof(mergeT *), qh_comparemerge);
+ if (qh->POSTmerging) {
+ zadd_(Zmergeinittot2, nummerges);
+ }else {
+ zadd_(Zmergeinittot, nummerges);
+ zmax_(Zmergeinitmax, nummerges);
+ }
+ trace2((qh, qh->ferr, 2022, "qh_getmergeset_initial: %d merges found\n", nummerges));
+} /* getmergeset_initial */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="hashridge">-</a>
+
+ qh_hashridge(qh, hashtable, hashsize, ridge, oldvertex )
+ add ridge to hashtable without oldvertex
+
+ notes:
+ assumes hashtable is large enough
+
+ design:
+ determine hash value for ridge without oldvertex
+ find next empty slot for ridge
+*/
+void qh_hashridge(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex) {
+ int hash;
+ ridgeT *ridgeA;
+
+ hash= qh_gethash(qh, hashsize, ridge->vertices, qh->hull_dim-1, 0, oldvertex);
+ while (True) {
+ if (!(ridgeA= SETelemt_(hashtable, hash, ridgeT))) {
+ SETelem_(hashtable, hash)= ridge;
+ break;
+ }else if (ridgeA == ridge)
+ break;
+ if (++hash == hashsize)
+ hash= 0;
+ }
+} /* hashridge */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="hashridge_find">-</a>
+
+ qh_hashridge_find(qh, hashtable, hashsize, ridge, vertex, oldvertex, hashslot )
+ returns matching ridge without oldvertex in hashtable
+ for ridge without vertex
+ if oldvertex is NULL
+ matches with any one skip
+
+ returns:
+ matching ridge or NULL
+ if no match,
+ if ridge already in table
+ hashslot= -1
+ else
+ hashslot= next NULL index
+
+ notes:
+ assumes hashtable is large enough
+ can't match ridge to itself
+
+ design:
+ get hash value for ridge without vertex
+ for each hashslot
+ return match if ridge matches ridgeA without oldvertex
+*/
+ridgeT *qh_hashridge_find(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge,
+ vertexT *vertex, vertexT *oldvertex, int *hashslot) {
+ int hash;
+ ridgeT *ridgeA;
+
+ *hashslot= 0;
+ zinc_(Zhashridge);
+ hash= qh_gethash(qh, hashsize, ridge->vertices, qh->hull_dim-1, 0, vertex);
+ while ((ridgeA= SETelemt_(hashtable, hash, ridgeT))) {
+ if (ridgeA == ridge)
+ *hashslot= -1;
+ else {
+ zinc_(Zhashridgetest);
+ if (qh_setequal_except(ridge->vertices, vertex, ridgeA->vertices, oldvertex))
+ return ridgeA;
+ }
+ if (++hash == hashsize)
+ hash= 0;
+ }
+ if (!*hashslot)
+ *hashslot= hash;
+ return NULL;
+} /* hashridge_find */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="makeridges">-</a>
+
+ qh_makeridges(qh, facet )
+ creates explicit ridges between simplicial facets
+
+ returns:
+ facet with ridges and without qh_MERGEridge
+ ->simplicial is False
+
+ notes:
+ allows qh_MERGEridge flag
+ uses existing ridges
+ duplicate neighbors ok if ridges already exist (qh_mergecycle_ridges)
+
+ see:
+ qh_mergecycle_ridges()
+
+ design:
+ look for qh_MERGEridge neighbors
+ mark neighbors that already have ridges
+ for each unprocessed neighbor of facet
+ create a ridge for neighbor and facet
+ if any qh_MERGEridge neighbors
+ delete qh_MERGEridge flags (already handled by qh_mark_dupridges)
+*/
+void qh_makeridges(qhT *qh, facetT *facet) {
+ facetT *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+ int neighbor_i, neighbor_n;
+ boolT toporient, mergeridge= False;
+
+ if (!facet->simplicial)
+ return;
+ trace4((qh, qh->ferr, 4027, "qh_makeridges: make ridges for f%d\n", facet->id));
+ facet->simplicial= False;
+ FOREACHneighbor_(facet) {
+ if (neighbor == qh_MERGEridge)
+ mergeridge= True;
+ else
+ neighbor->seen= False;
+ }
+ FOREACHridge_(facet->ridges)
+ otherfacet_(ridge, facet)->seen= True;
+ FOREACHneighbor_i_(qh, facet) {
+ if (neighbor == qh_MERGEridge)
+ continue; /* fixed by qh_mark_dupridges */
+ else if (!neighbor->seen) { /* no current ridges */
+ ridge= qh_newridge(qh);
+ ridge->vertices= qh_setnew_delnthsorted(qh, facet->vertices, qh->hull_dim,
+ neighbor_i, 0);
+ toporient= facet->toporient ^ (neighbor_i & 0x1);
+ if (toporient) {
+ ridge->top= facet;
+ ridge->bottom= neighbor;
+ }else {
+ ridge->top= neighbor;
+ ridge->bottom= facet;
+ }
+#if 0 /* this also works */
+ flip= (facet->toporient ^ neighbor->toporient)^(skip1 & 0x1) ^ (skip2 & 0x1);
+ if (facet->toporient ^ (skip1 & 0x1) ^ flip) {
+ ridge->top= neighbor;
+ ridge->bottom= facet;
+ }else {
+ ridge->top= facet;
+ ridge->bottom= neighbor;
+ }
+#endif
+ qh_setappend(qh, &(facet->ridges), ridge);
+ qh_setappend(qh, &(neighbor->ridges), ridge);
+ }
+ }
+ if (mergeridge) {
+ while (qh_setdel(facet->neighbors, qh_MERGEridge))
+ ; /* delete each one */
+ }
+} /* makeridges */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mark_dupridges">-</a>
+
+ qh_mark_dupridges(qh, facetlist )
+ add duplicated ridges to qh.facet_mergeset
+ facet->dupridge is true
+
+ returns:
+ duplicate ridges on qh.facet_mergeset
+ ->mergeridge/->mergeridge2 set
+ duplicate ridges marked by qh_MERGEridge and both sides facet->dupridge
+ no MERGEridges in neighbor sets
+
+ notes:
+ duplicate ridges occur when the horizon is pinched,
+ i.e. a subridge occurs in more than two horizon ridges.
+ could rename vertices that pinch the horizon (thus removing subridge)
+ uses qh.visit_id
+
+ design:
+ for all facets on facetlist
+ if facet contains a duplicate ridge
+ for each neighbor of facet
+ if neighbor marked qh_MERGEridge (one side of the merge)
+ set facet->mergeridge
+ else
+ if neighbor contains a duplicate ridge
+ and the back link is qh_MERGEridge
+ append duplicate ridge to qh.facet_mergeset
+ for each duplicate ridge
+ make ridge sets in preparation for merging
+ remove qh_MERGEridge from neighbor set
+ for each duplicate ridge
+ restore the missing neighbor from the neighbor set that was qh_MERGEridge
+ add the missing ridge for this neighbor
+*/
+void qh_mark_dupridges(qhT *qh, facetT *facetlist) {
+ facetT *facet, *neighbor, **neighborp;
+ int nummerge=0;
+ mergeT *merge, **mergep;
+
+
+ trace4((qh, qh->ferr, 4028, "qh_mark_dupridges: identify duplicate ridges\n"));
+ FORALLfacet_(facetlist) {
+ if (facet->dupridge) {
+ FOREACHneighbor_(facet) {
+ if (neighbor == qh_MERGEridge) {
+ facet->mergeridge= True;
+ continue;
+ }
+ if (neighbor->dupridge
+ && !qh_setin(neighbor->neighbors, facet)) { /* qh_MERGEridge */
+ qh_appendmergeset(qh, facet, neighbor, MRGridge, NULL);
+ facet->mergeridge2= True;
+ facet->mergeridge= True;
+ nummerge++;
+ }
+ }
+ }
+ }
+ if (!nummerge)
+ return;
+ FORALLfacet_(facetlist) { /* gets rid of qh_MERGEridge */
+ if (facet->mergeridge && !facet->mergeridge2)
+ qh_makeridges(qh, facet);
+ }
+ FOREACHmerge_(qh->facet_mergeset) { /* restore the missing neighbors */
+ if (merge->type == MRGridge) {
+ qh_setappend(qh, &merge->facet2->neighbors, merge->facet1);
+ qh_makeridges(qh, merge->facet1); /* and the missing ridges */
+ }
+ }
+ trace1((qh, qh->ferr, 1012, "qh_mark_dupridges: found %d duplicated ridges\n",
+ nummerge));
+} /* mark_dupridges */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="maydropneighbor">-</a>
+
+ qh_maydropneighbor(qh, facet )
+ drop neighbor relationship if no ridge between facet and neighbor
+
+ returns:
+ neighbor sets updated
+ appends degenerate facets to qh.facet_mergeset
+
+ notes:
+ won't cause redundant facets since vertex inclusion is the same
+ may drop vertex and neighbor if no ridge
+ uses qh.visit_id
+
+ design:
+ visit all neighbors with ridges
+ for each unvisited neighbor of facet
+ delete neighbor and facet from the neighbor sets
+ if neighbor becomes degenerate
+ append neighbor to qh.degen_mergeset
+ if facet is degenerate
+ append facet to qh.degen_mergeset
+*/
+void qh_maydropneighbor(qhT *qh, facetT *facet) {
+ ridgeT *ridge, **ridgep;
+ realT angledegen= qh_ANGLEdegen;
+ facetT *neighbor, **neighborp;
+
+ qh->visit_id++;
+ trace4((qh, qh->ferr, 4029, "qh_maydropneighbor: test f%d for no ridges to a neighbor\n",
+ facet->id));
+ FOREACHridge_(facet->ridges) {
+ ridge->top->visitid= qh->visit_id;
+ ridge->bottom->visitid= qh->visit_id;
+ }
+ FOREACHneighbor_(facet) {
+ if (neighbor->visitid != qh->visit_id) {
+ trace0((qh, qh->ferr, 17, "qh_maydropneighbor: facets f%d and f%d are no longer neighbors during p%d\n",
+ facet->id, neighbor->id, qh->furthest_id));
+ zinc_(Zdropneighbor);
+ qh_setdel(facet->neighbors, neighbor);
+ neighborp--; /* repeat, deleted a neighbor */
+ qh_setdel(neighbor->neighbors, facet);
+ if (qh_setsize(qh, neighbor->neighbors) < qh->hull_dim) {
+ zinc_(Zdropdegen);
+ qh_appendmergeset(qh, neighbor, neighbor, MRGdegen, &angledegen);
+ trace2((qh, qh->ferr, 2023, "qh_maydropneighbors: f%d is degenerate.\n", neighbor->id));
+ }
+ }
+ }
+ if (qh_setsize(qh, facet->neighbors) < qh->hull_dim) {
+ zinc_(Zdropdegen);
+ qh_appendmergeset(qh, facet, facet, MRGdegen, &angledegen);
+ trace2((qh, qh->ferr, 2024, "qh_maydropneighbors: f%d is degenerate.\n", facet->id));
+ }
+} /* maydropneighbor */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="merge_degenredundant">-</a>
+
+ qh_merge_degenredundant(qh)
+ merge all degenerate and redundant facets
+ qh.degen_mergeset contains merges from qh_degen_redundant_neighbors()
+
+ returns:
+ number of merges performed
+ resets facet->degenerate/redundant
+ if deleted (visible) facet has no neighbors
+ sets ->f.replace to NULL
+
+ notes:
+ redundant merges happen before degenerate ones
+ merging and renaming vertices can result in degen/redundant facets
+
+ design:
+ for each merge on qh.degen_mergeset
+ if redundant merge
+ if non-redundant facet merged into redundant facet
+ recheck facet for redundancy
+ else
+ merge redundant facet into other facet
+*/
+int qh_merge_degenredundant(qhT *qh) {
+ int size;
+ mergeT *merge;
+ facetT *bestneighbor, *facet1, *facet2;
+ realT dist, mindist, maxdist;
+ vertexT *vertex, **vertexp;
+ int nummerges= 0;
+ mergeType mergetype;
+
+ while ((merge= (mergeT*)qh_setdellast(qh->degen_mergeset))) {
+ facet1= merge->facet1;
+ facet2= merge->facet2;
+ mergetype= merge->type;
+ qh_memfree(qh, merge, (int)sizeof(mergeT));
+ if (facet1->visible)
+ continue;
+ facet1->degenerate= False;
+ facet1->redundant= False;
+ if (qh->TRACEmerge-1 == zzval_(Ztotmerge))
+ qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
+ if (mergetype == MRGredundant) {
+ zinc_(Zneighbor);
+ while (facet2->visible) {
+ if (!facet2->f.replace) {
+ qh_fprintf(qh, qh->ferr, 6097, "qhull internal error (qh_merge_degenredunant): f%d redundant but f%d has no replacement\n",
+ facet1->id, facet2->id);
+ qh_errexit2(qh, qh_ERRqhull, facet1, facet2);
+ }
+ facet2= facet2->f.replace;
+ }
+ if (facet1 == facet2) {
+ qh_degen_redundant_facet(qh, facet1); /* in case of others */
+ continue;
+ }
+ trace2((qh, qh->ferr, 2025, "qh_merge_degenredundant: facet f%d is contained in f%d, will merge\n",
+ facet1->id, facet2->id));
+ qh_mergefacet(qh, facet1, facet2, NULL, NULL, !qh_MERGEapex);
+ /* merge distance is already accounted for */
+ nummerges++;
+ }else { /* mergetype == MRGdegen, other merges may have fixed */
+ if (!(size= qh_setsize(qh, facet1->neighbors))) {
+ zinc_(Zdelfacetdup);
+ trace2((qh, qh->ferr, 2026, "qh_merge_degenredundant: facet f%d has no neighbors. Deleted\n", facet1->id));
+ qh_willdelete(qh, facet1, NULL);
+ FOREACHvertex_(facet1->vertices) {
+ qh_setdel(vertex->neighbors, facet1);
+ if (!SETfirst_(vertex->neighbors)) {
+ zinc_(Zdegenvertex);
+ trace2((qh, qh->ferr, 2027, "qh_merge_degenredundant: deleted v%d because f%d has no neighbors\n",
+ vertex->id, facet1->id));
+ vertex->deleted= True;
+ qh_setappend(qh, &qh->del_vertices, vertex);
+ }
+ }
+ nummerges++;
+ }else if (size < qh->hull_dim) {
+ bestneighbor= qh_findbestneighbor(qh, facet1, &dist, &mindist, &maxdist);
+ trace2((qh, qh->ferr, 2028, "qh_merge_degenredundant: facet f%d has %d neighbors, merge into f%d dist %2.2g\n",
+ facet1->id, size, bestneighbor->id, dist));
+ qh_mergefacet(qh, facet1, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
+ nummerges++;
+ if (qh->PRINTstatistics) {
+ zinc_(Zdegen);
+ wadd_(Wdegentot, dist);
+ wmax_(Wdegenmax, dist);
+ }
+ } /* else, another merge fixed the degeneracy and redundancy tested */
+ }
+ }
+ return nummerges;
+} /* merge_degenredundant */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="merge_nonconvex">-</a>
+
+ qh_merge_nonconvex(qh, facet1, facet2, mergetype )
+ remove non-convex ridge between facet1 into facet2
+ mergetype gives why the facet's are non-convex
+
+ returns:
+ merges one of the facets into the best neighbor
+
+ design:
+ if one of the facets is a new facet
+ prefer merging new facet into old facet
+ find best neighbors for both facets
+ merge the nearest facet into its best neighbor
+ update the statistics
+*/
+void qh_merge_nonconvex(qhT *qh, facetT *facet1, facetT *facet2, mergeType mergetype) {
+ facetT *bestfacet, *bestneighbor, *neighbor;
+ realT dist, dist2, mindist, mindist2, maxdist, maxdist2;
+
+ if (qh->TRACEmerge-1 == zzval_(Ztotmerge))
+ qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
+ trace3((qh, qh->ferr, 3003, "qh_merge_nonconvex: merge #%d for f%d and f%d type %d\n",
+ zzval_(Ztotmerge) + 1, facet1->id, facet2->id, mergetype));
+ /* concave or coplanar */
+ if (!facet1->newfacet) {
+ bestfacet= facet2; /* avoid merging old facet if new is ok */
+ facet2= facet1;
+ facet1= bestfacet;
+ }else
+ bestfacet= facet1;
+ bestneighbor= qh_findbestneighbor(qh, bestfacet, &dist, &mindist, &maxdist);
+ neighbor= qh_findbestneighbor(qh, facet2, &dist2, &mindist2, &maxdist2);
+ if (dist < dist2) {
+ qh_mergefacet(qh, bestfacet, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
+ }else if (qh->AVOIDold && !facet2->newfacet
+ && ((mindist >= -qh->MAXcoplanar && maxdist <= qh->max_outside)
+ || dist * 1.5 < dist2)) {
+ zinc_(Zavoidold);
+ wadd_(Wavoidoldtot, dist);
+ wmax_(Wavoidoldmax, dist);
+ trace2((qh, qh->ferr, 2029, "qh_merge_nonconvex: avoid merging old facet f%d dist %2.2g. Use f%d dist %2.2g instead\n",
+ facet2->id, dist2, facet1->id, dist2));
+ qh_mergefacet(qh, bestfacet, bestneighbor, &mindist, &maxdist, !qh_MERGEapex);
+ }else {
+ qh_mergefacet(qh, facet2, neighbor, &mindist2, &maxdist2, !qh_MERGEapex);
+ dist= dist2;
+ }
+ if (qh->PRINTstatistics) {
+ if (mergetype == MRGanglecoplanar) {
+ zinc_(Zacoplanar);
+ wadd_(Wacoplanartot, dist);
+ wmax_(Wacoplanarmax, dist);
+ }else if (mergetype == MRGconcave) {
+ zinc_(Zconcave);
+ wadd_(Wconcavetot, dist);
+ wmax_(Wconcavemax, dist);
+ }else { /* MRGcoplanar */
+ zinc_(Zcoplanar);
+ wadd_(Wcoplanartot, dist);
+ wmax_(Wcoplanarmax, dist);
+ }
+ }
+} /* merge_nonconvex */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergecycle">-</a>
+
+ qh_mergecycle(qh, samecycle, newfacet )
+ merge a cycle of facets starting at samecycle into a newfacet
+ newfacet is a horizon facet with ->normal
+ samecycle facets are simplicial from an apex
+
+ returns:
+ initializes vertex neighbors on first merge
+ samecycle deleted (placed on qh.visible_list)
+ newfacet at end of qh.facet_list
+ deleted vertices on qh.del_vertices
+
+ see:
+ qh_mergefacet()
+ called by qh_mergecycle_all() for multiple, same cycle facets
+
+ design:
+ make vertex neighbors if necessary
+ make ridges for newfacet
+ merge neighbor sets of samecycle into newfacet
+ merge ridges of samecycle into newfacet
+ merge vertex neighbors of samecycle into newfacet
+ make apex of samecycle the apex of newfacet
+ if newfacet wasn't a new facet
+ add its vertices to qh.newvertex_list
+ delete samecycle facets a make newfacet a newfacet
+*/
+void qh_mergecycle(qhT *qh, facetT *samecycle, facetT *newfacet) {
+ int traceonce= False, tracerestore= 0;
+ vertexT *apex;
+#ifndef qh_NOtrace
+ facetT *same;
+#endif
+
+ if (newfacet->tricoplanar) {
+ if (!qh->TRInormals) {
+ qh_fprintf(qh, qh->ferr, 6224, "Qhull internal error (qh_mergecycle): does not work for tricoplanar facets. Use option 'Q11'\n");
+ qh_errexit(qh, qh_ERRqhull, newfacet, NULL);
+ }
+ newfacet->tricoplanar= False;
+ newfacet->keepcentrum= False;
+ }
+ if (!qh->VERTEXneighbors)
+ qh_vertexneighbors(qh);
+ zzinc_(Ztotmerge);
+ if (qh->REPORTfreq2 && qh->POSTmerging) {
+ if (zzval_(Ztotmerge) > qh->mergereport + qh->REPORTfreq2)
+ qh_tracemerging(qh);
+ }
+#ifndef qh_NOtrace
+ if (qh->TRACEmerge == zzval_(Ztotmerge))
+ qh->qhmem.IStracing= qh->IStracing= qh->TRACElevel;
+ trace2((qh, qh->ferr, 2030, "qh_mergecycle: merge #%d for facets from cycle f%d into coplanar horizon f%d\n",
+ zzval_(Ztotmerge), samecycle->id, newfacet->id));
+ if (newfacet == qh->tracefacet) {
+ tracerestore= qh->IStracing;
+ qh->IStracing= 4;
+ qh_fprintf(qh, qh->ferr, 8068, "qh_mergecycle: ========= trace merge %d of samecycle %d into trace f%d, furthest is p%d\n",
+ zzval_(Ztotmerge), samecycle->id, newfacet->id, qh->furthest_id);
+ traceonce= True;
+ }
+ if (qh->IStracing >=4) {
+ qh_fprintf(qh, qh->ferr, 8069, " same cycle:");
+ FORALLsame_cycle_(samecycle)
+ qh_fprintf(qh, qh->ferr, 8070, " f%d", same->id);
+ qh_fprintf(qh, qh->ferr, 8071, "\n");
+ }
+ if (qh->IStracing >=4)
+ qh_errprint(qh, "MERGING CYCLE", samecycle, newfacet, NULL, NULL);
+#endif /* !qh_NOtrace */
+ apex= SETfirstt_(samecycle->vertices, vertexT);
+ qh_makeridges(qh, newfacet);
+ qh_mergecycle_neighbors(qh, samecycle, newfacet);
+ qh_mergecycle_ridges(qh, samecycle, newfacet);
+ qh_mergecycle_vneighbors(qh, samecycle, newfacet);
+ if (SETfirstt_(newfacet->vertices, vertexT) != apex)
+ qh_setaddnth(qh, &newfacet->vertices, 0, apex); /* apex has last id */
+ if (!newfacet->newfacet)
+ qh_newvertices(qh, newfacet->vertices);
+ qh_mergecycle_facets(qh, samecycle, newfacet);
+ qh_tracemerge(qh, samecycle, newfacet);
+ /* check for degen_redundant_neighbors after qh_forcedmerges() */
+ if (traceonce) {
+ qh_fprintf(qh, qh->ferr, 8072, "qh_mergecycle: end of trace facet\n");
+ qh->IStracing= tracerestore;
+ }
+} /* mergecycle */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergecycle_all">-</a>
+
+ qh_mergecycle_all(qh, facetlist, wasmerge )
+ merge all samecycles of coplanar facets into horizon
+ don't merge facets with ->mergeridge (these already have ->normal)
+ all facets are simplicial from apex
+ all facet->cycledone == False
+
+ returns:
+ all newfacets merged into coplanar horizon facets
+ deleted vertices on qh.del_vertices
+ sets wasmerge if any merge
+
+ see:
+ calls qh_mergecycle for multiple, same cycle facets
+
+ design:
+ for each facet on facetlist
+ skip facets with duplicate ridges and normals
+ check that facet is in a samecycle (->mergehorizon)
+ if facet only member of samecycle
+ sets vertex->delridge for all vertices except apex
+ merge facet into horizon
+ else
+ mark all facets in samecycle
+ remove facets with duplicate ridges from samecycle
+ merge samecycle into horizon (deletes facets from facetlist)
+*/
+void qh_mergecycle_all(qhT *qh, facetT *facetlist, boolT *wasmerge) {
+ facetT *facet, *same, *prev, *horizon;
+ facetT *samecycle= NULL, *nextfacet, *nextsame;
+ vertexT *apex, *vertex, **vertexp;
+ int cycles=0, total=0, facets, nummerge;
+
+ trace2((qh, qh->ferr, 2031, "qh_mergecycle_all: begin\n"));
+ for (facet= facetlist; facet && (nextfacet= facet->next); facet= nextfacet) {
+ if (facet->normal)
+ continue;
+ if (!facet->mergehorizon) {
+ qh_fprintf(qh, qh->ferr, 6225, "Qhull internal error (qh_mergecycle_all): f%d without normal\n", facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ horizon= SETfirstt_(facet->neighbors, facetT);
+ if (facet->f.samecycle == facet) {
+ zinc_(Zonehorizon);
+ /* merge distance done in qh_findhorizon */
+ apex= SETfirstt_(facet->vertices, vertexT);
+ FOREACHvertex_(facet->vertices) {
+ if (vertex != apex)
+ vertex->delridge= True;
+ }
+ horizon->f.newcycle= NULL;
+ qh_mergefacet(qh, facet, horizon, NULL, NULL, qh_MERGEapex);
+ }else {
+ samecycle= facet;
+ facets= 0;
+ prev= facet;
+ for (same= facet->f.samecycle; same; /* FORALLsame_cycle_(facet) */
+ same= (same == facet ? NULL :nextsame)) { /* ends at facet */
+ nextsame= same->f.samecycle;
+ if (same->cycledone || same->visible)
+ qh_infiniteloop(qh, same);
+ same->cycledone= True;
+ if (same->normal) {
+ prev->f.samecycle= same->f.samecycle; /* unlink ->mergeridge */
+ same->f.samecycle= NULL;
+ }else {
+ prev= same;
+ facets++;
+ }
+ }
+ while (nextfacet && nextfacet->cycledone) /* will delete samecycle */
+ nextfacet= nextfacet->next;
+ horizon->f.newcycle= NULL;
+ qh_mergecycle(qh, samecycle, horizon);
+ nummerge= horizon->nummerge + facets;
+ if (nummerge > qh_MAXnummerge)
+ horizon->nummerge= qh_MAXnummerge;
+ else
+ horizon->nummerge= (short unsigned int)nummerge;
+ zzinc_(Zcyclehorizon);
+ total += facets;
+ zzadd_(Zcyclefacettot, facets);
+ zmax_(Zcyclefacetmax, facets);
+ }
+ cycles++;
+ }
+ if (cycles)
+ *wasmerge= True;
+ trace1((qh, qh->ferr, 1013, "qh_mergecycle_all: merged %d same cycles or facets into coplanar horizons\n", cycles));
+} /* mergecycle_all */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergecycle_facets">-</a>
+
+ qh_mergecycle_facets(qh, samecycle, newfacet )
+ finish merge of samecycle into newfacet
+
+ returns:
+ samecycle prepended to visible_list for later deletion and partitioning
+ each facet->f.replace == newfacet
+
+ newfacet moved to end of qh.facet_list
+ makes newfacet a newfacet (get's facet1->id if it was old)
+ sets newfacet->newmerge
+ clears newfacet->center (unless merging into a large facet)
+ clears newfacet->tested and ridge->tested for facet1
+
+ adds neighboring facets to facet_mergeset if redundant or degenerate
+
+ design:
+ make newfacet a new facet and set its flags
+ move samecycle facets to qh.visible_list for later deletion
+ unless newfacet is large
+ remove its centrum
+*/
+void qh_mergecycle_facets(qhT *qh, facetT *samecycle, facetT *newfacet) {
+ facetT *same, *next;
+
+ trace4((qh, qh->ferr, 4030, "qh_mergecycle_facets: make newfacet new and samecycle deleted\n"));
+ qh_removefacet(qh, newfacet); /* append as a newfacet to end of qh->facet_list */
+ qh_appendfacet(qh, newfacet);
+ newfacet->newfacet= True;
+ newfacet->simplicial= False;
+ newfacet->newmerge= True;
+
+ for (same= samecycle->f.samecycle; same; same= (same == samecycle ? NULL : next)) {
+ next= same->f.samecycle; /* reused by willdelete */
+ qh_willdelete(qh, same, newfacet);
+ }
+ if (newfacet->center
+ && qh_setsize(qh, newfacet->vertices) <= qh->hull_dim + qh_MAXnewcentrum) {
+ qh_memfree(qh, newfacet->center, qh->normal_size);
+ newfacet->center= NULL;
+ }
+ trace3((qh, qh->ferr, 3004, "qh_mergecycle_facets: merged facets from cycle f%d into f%d\n",
+ samecycle->id, newfacet->id));
+} /* mergecycle_facets */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergecycle_neighbors">-</a>
+
+ qh_mergecycle_neighbors(qh, samecycle, newfacet )
+ add neighbors for samecycle facets to newfacet
+
+ returns:
+ newfacet with updated neighbors and vice-versa
+ newfacet has ridges
+ all neighbors of newfacet marked with qh.visit_id
+ samecycle facets marked with qh.visit_id-1
+ ridges updated for simplicial neighbors of samecycle with a ridge
+
+ notes:
+ assumes newfacet not in samecycle
+ usually, samecycle facets are new, simplicial facets without internal ridges
+ not so if horizon facet is coplanar to two different samecycles
+
+ see:
+ qh_mergeneighbors()
+
+ design:
+ check samecycle
+ delete neighbors from newfacet that are also in samecycle
+ for each neighbor of a facet in samecycle
+ if neighbor is simplicial
+ if first visit
+ move the neighbor relation to newfacet
+ update facet links for its ridges
+ else
+ make ridges for neighbor
+ remove samecycle reference
+ else
+ update neighbor sets
+*/
+void qh_mergecycle_neighbors(qhT *qh, facetT *samecycle, facetT *newfacet) {
+ facetT *same, *neighbor, **neighborp;
+ int delneighbors= 0, newneighbors= 0;
+ unsigned int samevisitid;
+ ridgeT *ridge, **ridgep;
+
+ samevisitid= ++qh->visit_id;
+ FORALLsame_cycle_(samecycle) {
+ if (same->visitid == samevisitid || same->visible)
+ qh_infiniteloop(qh, samecycle);
+ same->visitid= samevisitid;
+ }
+ newfacet->visitid= ++qh->visit_id;
+ trace4((qh, qh->ferr, 4031, "qh_mergecycle_neighbors: delete shared neighbors from newfacet\n"));
+ FOREACHneighbor_(newfacet) {
+ if (neighbor->visitid == samevisitid) {
+ SETref_(neighbor)= NULL; /* samecycle neighbors deleted */
+ delneighbors++;
+ }else
+ neighbor->visitid= qh->visit_id;
+ }
+ qh_setcompact(qh, newfacet->neighbors);
+
+ trace4((qh, qh->ferr, 4032, "qh_mergecycle_neighbors: update neighbors\n"));
+ FORALLsame_cycle_(samecycle) {
+ FOREACHneighbor_(same) {
+ if (neighbor->visitid == samevisitid)
+ continue;
+ if (neighbor->simplicial) {
+ if (neighbor->visitid != qh->visit_id) {
+ qh_setappend(qh, &newfacet->neighbors, neighbor);
+ qh_setreplace(qh, neighbor->neighbors, same, newfacet);
+ newneighbors++;
+ neighbor->visitid= qh->visit_id;
+ FOREACHridge_(neighbor->ridges) { /* update ridge in case of qh_makeridges */
+ if (ridge->top == same) {
+ ridge->top= newfacet;
+ break;
+ }else if (ridge->bottom == same) {
+ ridge->bottom= newfacet;
+ break;
+ }
+ }
+ }else {
+ qh_makeridges(qh, neighbor);
+ qh_setdel(neighbor->neighbors, same);
+ /* same can't be horizon facet for neighbor */
+ }
+ }else { /* non-simplicial neighbor */
+ qh_setdel(neighbor->neighbors, same);
+ if (neighbor->visitid != qh->visit_id) {
+ qh_setappend(qh, &neighbor->neighbors, newfacet);
+ qh_setappend(qh, &newfacet->neighbors, neighbor);
+ neighbor->visitid= qh->visit_id;
+ newneighbors++;
+ }
+ }
+ }
+ }
+ trace2((qh, qh->ferr, 2032, "qh_mergecycle_neighbors: deleted %d neighbors and added %d\n",
+ delneighbors, newneighbors));
+} /* mergecycle_neighbors */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergecycle_ridges">-</a>
+
+ qh_mergecycle_ridges(qh, samecycle, newfacet )
+ add ridges/neighbors for facets in samecycle to newfacet
+ all new/old neighbors of newfacet marked with qh.visit_id
+ facets in samecycle marked with qh.visit_id-1
+ newfacet marked with qh.visit_id
+
+ returns:
+ newfacet has merged ridges
+
+ notes:
+ ridge already updated for simplicial neighbors of samecycle with a ridge
+
+ see:
+ qh_mergeridges()
+ qh_makeridges()
+
+ design:
+ remove ridges between newfacet and samecycle
+ for each facet in samecycle
+ for each ridge in facet
+ update facet pointers in ridge
+ skip ridges processed in qh_mergecycle_neighors
+ free ridges between newfacet and samecycle
+ free ridges between facets of samecycle (on 2nd visit)
+ append remaining ridges to newfacet
+ if simpilicial facet
+ for each neighbor of facet
+ if simplicial facet
+ and not samecycle facet or newfacet
+ make ridge between neighbor and newfacet
+*/
+void qh_mergecycle_ridges(qhT *qh, facetT *samecycle, facetT *newfacet) {
+ facetT *same, *neighbor= NULL;
+ int numold=0, numnew=0;
+ int neighbor_i, neighbor_n;
+ unsigned int samevisitid;
+ ridgeT *ridge, **ridgep;
+ boolT toporient;
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+
+ trace4((qh, qh->ferr, 4033, "qh_mergecycle_ridges: delete shared ridges from newfacet\n"));
+ samevisitid= qh->visit_id -1;
+ FOREACHridge_(newfacet->ridges) {
+ neighbor= otherfacet_(ridge, newfacet);
+ if (neighbor->visitid == samevisitid)
+ SETref_(ridge)= NULL; /* ridge free'd below */
+ }
+ qh_setcompact(qh, newfacet->ridges);
+
+ trace4((qh, qh->ferr, 4034, "qh_mergecycle_ridges: add ridges to newfacet\n"));
+ FORALLsame_cycle_(samecycle) {
+ FOREACHridge_(same->ridges) {
+ if (ridge->top == same) {
+ ridge->top= newfacet;
+ neighbor= ridge->bottom;
+ }else if (ridge->bottom == same) {
+ ridge->bottom= newfacet;
+ neighbor= ridge->top;
+ }else if (ridge->top == newfacet || ridge->bottom == newfacet) {
+ qh_setappend(qh, &newfacet->ridges, ridge);
+ numold++; /* already set by qh_mergecycle_neighbors */
+ continue;
+ }else {
+ qh_fprintf(qh, qh->ferr, 6098, "qhull internal error (qh_mergecycle_ridges): bad ridge r%d\n", ridge->id);
+ qh_errexit(qh, qh_ERRqhull, NULL, ridge);
+ }
+ if (neighbor == newfacet) {
+ qh_setfree(qh, &(ridge->vertices));
+ qh_memfree_(qh, ridge, (int)sizeof(ridgeT), freelistp);
+ numold++;
+ }else if (neighbor->visitid == samevisitid) {
+ qh_setdel(neighbor->ridges, ridge);
+ qh_setfree(qh, &(ridge->vertices));
+ qh_memfree_(qh, ridge, (int)sizeof(ridgeT), freelistp);
+ numold++;
+ }else {
+ qh_setappend(qh, &newfacet->ridges, ridge);
+ numold++;
+ }
+ }
+ if (same->ridges)
+ qh_settruncate(qh, same->ridges, 0);
+ if (!same->simplicial)
+ continue;
+ FOREACHneighbor_i_(qh, same) { /* note: !newfact->simplicial */
+ if (neighbor->visitid != samevisitid && neighbor->simplicial) {
+ ridge= qh_newridge(qh);
+ ridge->vertices= qh_setnew_delnthsorted(qh, same->vertices, qh->hull_dim,
+ neighbor_i, 0);
+ toporient= same->toporient ^ (neighbor_i & 0x1);
+ if (toporient) {
+ ridge->top= newfacet;
+ ridge->bottom= neighbor;
+ }else {
+ ridge->top= neighbor;
+ ridge->bottom= newfacet;
+ }
+ qh_setappend(qh, &(newfacet->ridges), ridge);
+ qh_setappend(qh, &(neighbor->ridges), ridge);
+ numnew++;
+ }
+ }
+ }
+
+ trace2((qh, qh->ferr, 2033, "qh_mergecycle_ridges: found %d old ridges and %d new ones\n",
+ numold, numnew));
+} /* mergecycle_ridges */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergecycle_vneighbors">-</a>
+
+ qh_mergecycle_vneighbors(qh, samecycle, newfacet )
+ create vertex neighbors for newfacet from vertices of facets in samecycle
+ samecycle marked with visitid == qh.visit_id - 1
+
+ returns:
+ newfacet vertices with updated neighbors
+ marks newfacet with qh.visit_id-1
+ deletes vertices that are merged away
+ sets delridge on all vertices (faster here than in mergecycle_ridges)
+
+ see:
+ qh_mergevertex_neighbors()
+
+ design:
+ for each vertex of samecycle facet
+ set vertex->delridge
+ delete samecycle facets from vertex neighbors
+ append newfacet to vertex neighbors
+ if vertex only in newfacet
+ delete it from newfacet
+ add it to qh.del_vertices for later deletion
+*/
+void qh_mergecycle_vneighbors(qhT *qh, facetT *samecycle, facetT *newfacet) {
+ facetT *neighbor, **neighborp;
+ unsigned int mergeid;
+ vertexT *vertex, **vertexp, *apex;
+ setT *vertices;
+
+ trace4((qh, qh->ferr, 4035, "qh_mergecycle_vneighbors: update vertex neighbors for newfacet\n"));
+ mergeid= qh->visit_id - 1;
+ newfacet->visitid= mergeid;
+ vertices= qh_basevertices(qh, samecycle); /* temp */
+ apex= SETfirstt_(samecycle->vertices, vertexT);
+ qh_setappend(qh, &vertices, apex);
+ FOREACHvertex_(vertices) {
+ vertex->delridge= True;
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid == mergeid)
+ SETref_(neighbor)= NULL;
+ }
+ qh_setcompact(qh, vertex->neighbors);
+ qh_setappend(qh, &vertex->neighbors, newfacet);
+ if (!SETsecond_(vertex->neighbors)) {
+ zinc_(Zcyclevertex);
+ trace2((qh, qh->ferr, 2034, "qh_mergecycle_vneighbors: deleted v%d when merging cycle f%d into f%d\n",
+ vertex->id, samecycle->id, newfacet->id));
+ qh_setdelsorted(newfacet->vertices, vertex);
+ vertex->deleted= True;
+ qh_setappend(qh, &qh->del_vertices, vertex);
+ }
+ }
+ qh_settempfree(qh, &vertices);
+ trace3((qh, qh->ferr, 3005, "qh_mergecycle_vneighbors: merged vertices from cycle f%d into f%d\n",
+ samecycle->id, newfacet->id));
+} /* mergecycle_vneighbors */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergefacet">-</a>
+
+ qh_mergefacet(qh, facet1, facet2, mindist, maxdist, mergeapex )
+ merges facet1 into facet2
+ mergeapex==qh_MERGEapex if merging new facet into coplanar horizon
+
+ returns:
+ qh.max_outside and qh.min_vertex updated
+ initializes vertex neighbors on first merge
+
+ returns:
+ facet2 contains facet1's vertices, neighbors, and ridges
+ facet2 moved to end of qh.facet_list
+ makes facet2 a newfacet
+ sets facet2->newmerge set
+ clears facet2->center (unless merging into a large facet)
+ clears facet2->tested and ridge->tested for facet1
+
+ facet1 prepended to visible_list for later deletion and partitioning
+ facet1->f.replace == facet2
+
+ adds neighboring facets to facet_mergeset if redundant or degenerate
+
+ notes:
+ mindist/maxdist may be NULL (only if both NULL)
+ traces merge if fmax_(maxdist,-mindist) > TRACEdist
+
+ see:
+ qh_mergecycle()
+
+ design:
+ trace merge and check for degenerate simplex
+ make ridges for both facets
+ update qh.max_outside, qh.max_vertex, qh.min_vertex
+ update facet2->maxoutside and keepcentrum
+ update facet2->nummerge
+ update tested flags for facet2
+ if facet1 is simplicial
+ merge facet1 into facet2
+ else
+ merge facet1's neighbors into facet2
+ merge facet1's ridges into facet2
+ merge facet1's vertices into facet2
+ merge facet1's vertex neighbors into facet2
+ add facet2's vertices to qh.new_vertexlist
+ unless qh_MERGEapex
+ test facet2 for degenerate or redundant neighbors
+ move facet1 to qh.visible_list for later deletion
+ move facet2 to end of qh.newfacet_list
+*/
+void qh_mergefacet(qhT *qh, facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex) {
+ boolT traceonce= False;
+ vertexT *vertex, **vertexp;
+ int tracerestore=0, nummerge;
+
+ if (facet1->tricoplanar || facet2->tricoplanar) {
+ if (!qh->TRInormals) {
+ qh_fprintf(qh, qh->ferr, 6226, "Qhull internal error (qh_mergefacet): does not work for tricoplanar facets. Use option 'Q11'\n");
+ qh_errexit2(qh, qh_ERRqhull, facet1, facet2);
+ }
+ if (facet2->tricoplanar) {
+ facet2->tricoplanar= False;
+ facet2->keepcentrum= False;
+ }
+ }
+ zzinc_(Ztotmerge);
+ if (qh->REPORTfreq2 && qh->POSTmerging) {
+ if (zzval_(Ztotmerge) > qh->mergereport + qh->REPORTfreq2)
+ qh_tracemerging(qh);
+ }
+#ifndef qh_NOtrace
+ if (qh->build_cnt >= qh->RERUN) {
+ if (mindist && (-*mindist > qh->TRACEdist || *maxdist > qh->TRACEdist)) {
+ tracerestore= 0;
+ qh->IStracing= qh->TRACElevel;
+ traceonce= True;
+ qh_fprintf(qh, qh->ferr, 8075, "qh_mergefacet: ========= trace wide merge #%d(%2.2g) for f%d into f%d, last point was p%d\n", zzval_(Ztotmerge),
+ fmax_(-*mindist, *maxdist), facet1->id, facet2->id, qh->furthest_id);
+ }else if (facet1 == qh->tracefacet || facet2 == qh->tracefacet) {
+ tracerestore= qh->IStracing;
+ qh->IStracing= 4;
+ traceonce= True;
+ qh_fprintf(qh, qh->ferr, 8076, "qh_mergefacet: ========= trace merge #%d involving f%d, furthest is p%d\n",
+ zzval_(Ztotmerge), qh->tracefacet_id, qh->furthest_id);
+ }
+ }
+ if (qh->IStracing >= 2) {
+ realT mergemin= -2;
+ realT mergemax= -2;
+
+ if (mindist) {
+ mergemin= *mindist;
+ mergemax= *maxdist;
+ }
+ qh_fprintf(qh, qh->ferr, 8077, "qh_mergefacet: #%d merge f%d into f%d, mindist= %2.2g, maxdist= %2.2g\n",
+ zzval_(Ztotmerge), facet1->id, facet2->id, mergemin, mergemax);
+ }
+#endif /* !qh_NOtrace */
+ if (facet1 == facet2 || facet1->visible || facet2->visible) {
+ qh_fprintf(qh, qh->ferr, 6099, "qhull internal error (qh_mergefacet): either f%d and f%d are the same or one is a visible facet\n",
+ facet1->id, facet2->id);
+ qh_errexit2(qh, qh_ERRqhull, facet1, facet2);
+ }
+ if (qh->num_facets - qh->num_visible <= qh->hull_dim + 1) {
+ qh_fprintf(qh, qh->ferr, 6227, "\n\
+qhull precision error: Only %d facets remain. Can not merge another\n\
+pair. The input is too degenerate or the convexity constraints are\n\
+too strong.\n", qh->hull_dim+1);
+ if (qh->hull_dim >= 5 && !qh->MERGEexact)
+ qh_fprintf(qh, qh->ferr, 8079, "Option 'Qx' may avoid this problem.\n");
+ qh_errexit(qh, qh_ERRprec, NULL, NULL);
+ }
+ if (!qh->VERTEXneighbors)
+ qh_vertexneighbors(qh);
+ qh_makeridges(qh, facet1);
+ qh_makeridges(qh, facet2);
+ if (qh->IStracing >=4)
+ qh_errprint(qh, "MERGING", facet1, facet2, NULL, NULL);
+ if (mindist) {
+ maximize_(qh->max_outside, *maxdist);
+ maximize_(qh->max_vertex, *maxdist);
+#if qh_MAXoutside
+ maximize_(facet2->maxoutside, *maxdist);
+#endif
+ minimize_(qh->min_vertex, *mindist);
+ if (!facet2->keepcentrum
+ && (*maxdist > qh->WIDEfacet || *mindist < -qh->WIDEfacet)) {
+ facet2->keepcentrum= True;
+ zinc_(Zwidefacet);
+ }
+ }
+ nummerge= facet1->nummerge + facet2->nummerge + 1;
+ if (nummerge >= qh_MAXnummerge)
+ facet2->nummerge= qh_MAXnummerge;
+ else
+ facet2->nummerge= (short unsigned int)nummerge;
+ facet2->newmerge= True;
+ facet2->dupridge= False;
+ qh_updatetested(qh, facet1, facet2);
+ if (qh->hull_dim > 2 && qh_setsize(qh, facet1->vertices) == qh->hull_dim)
+ qh_mergesimplex(qh, facet1, facet2, mergeapex);
+ else {
+ qh->vertex_visit++;
+ FOREACHvertex_(facet2->vertices)
+ vertex->visitid= qh->vertex_visit;
+ if (qh->hull_dim == 2)
+ qh_mergefacet2d(qh, facet1, facet2);
+ else {
+ qh_mergeneighbors(qh, facet1, facet2);
+ qh_mergevertices(qh, facet1->vertices, &facet2->vertices);
+ }
+ qh_mergeridges(qh, facet1, facet2);
+ qh_mergevertex_neighbors(qh, facet1, facet2);
+ if (!facet2->newfacet)
+ qh_newvertices(qh, facet2->vertices);
+ }
+ if (!mergeapex)
+ qh_degen_redundant_neighbors(qh, facet2, facet1);
+ if (facet2->coplanar || !facet2->newfacet) {
+ zinc_(Zmergeintohorizon);
+ }else if (!facet1->newfacet && facet2->newfacet) {
+ zinc_(Zmergehorizon);
+ }else {
+ zinc_(Zmergenew);
+ }
+ qh_willdelete(qh, facet1, facet2);
+ qh_removefacet(qh, facet2); /* append as a newfacet to end of qh->facet_list */
+ qh_appendfacet(qh, facet2);
+ facet2->newfacet= True;
+ facet2->tested= False;
+ qh_tracemerge(qh, facet1, facet2);
+ if (traceonce) {
+ qh_fprintf(qh, qh->ferr, 8080, "qh_mergefacet: end of wide tracing\n");
+ qh->IStracing= tracerestore;
+ }
+} /* mergefacet */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergefacet2d">-</a>
+
+ qh_mergefacet2d(qh, facet1, facet2 )
+ in 2d, merges neighbors and vertices of facet1 into facet2
+
+ returns:
+ build ridges for neighbors if necessary
+ facet2 looks like a simplicial facet except for centrum, ridges
+ neighbors are opposite the corresponding vertex
+ maintains orientation of facet2
+
+ notes:
+ qh_mergefacet() retains non-simplicial structures
+ they are not needed in 2d, but later routines may use them
+ preserves qh.vertex_visit for qh_mergevertex_neighbors()
+
+ design:
+ get vertices and neighbors
+ determine new vertices and neighbors
+ set new vertices and neighbors and adjust orientation
+ make ridges for new neighbor if needed
+*/
+void qh_mergefacet2d(qhT *qh, facetT *facet1, facetT *facet2) {
+ vertexT *vertex1A, *vertex1B, *vertex2A, *vertex2B, *vertexA, *vertexB;
+ facetT *neighbor1A, *neighbor1B, *neighbor2A, *neighbor2B, *neighborA, *neighborB;
+
+ vertex1A= SETfirstt_(facet1->vertices, vertexT);
+ vertex1B= SETsecondt_(facet1->vertices, vertexT);
+ vertex2A= SETfirstt_(facet2->vertices, vertexT);
+ vertex2B= SETsecondt_(facet2->vertices, vertexT);
+ neighbor1A= SETfirstt_(facet1->neighbors, facetT);
+ neighbor1B= SETsecondt_(facet1->neighbors, facetT);
+ neighbor2A= SETfirstt_(facet2->neighbors, facetT);
+ neighbor2B= SETsecondt_(facet2->neighbors, facetT);
+ if (vertex1A == vertex2A) {
+ vertexA= vertex1B;
+ vertexB= vertex2B;
+ neighborA= neighbor2A;
+ neighborB= neighbor1A;
+ }else if (vertex1A == vertex2B) {
+ vertexA= vertex1B;
+ vertexB= vertex2A;
+ neighborA= neighbor2B;
+ neighborB= neighbor1A;
+ }else if (vertex1B == vertex2A) {
+ vertexA= vertex1A;
+ vertexB= vertex2B;
+ neighborA= neighbor2A;
+ neighborB= neighbor1B;
+ }else { /* 1B == 2B */
+ vertexA= vertex1A;
+ vertexB= vertex2A;
+ neighborA= neighbor2B;
+ neighborB= neighbor1B;
+ }
+ /* vertexB always from facet2, neighborB always from facet1 */
+ if (vertexA->id > vertexB->id) {
+ SETfirst_(facet2->vertices)= vertexA;
+ SETsecond_(facet2->vertices)= vertexB;
+ if (vertexB == vertex2A)
+ facet2->toporient= !facet2->toporient;
+ SETfirst_(facet2->neighbors)= neighborA;
+ SETsecond_(facet2->neighbors)= neighborB;
+ }else {
+ SETfirst_(facet2->vertices)= vertexB;
+ SETsecond_(facet2->vertices)= vertexA;
+ if (vertexB == vertex2B)
+ facet2->toporient= !facet2->toporient;
+ SETfirst_(facet2->neighbors)= neighborB;
+ SETsecond_(facet2->neighbors)= neighborA;
+ }
+ qh_makeridges(qh, neighborB);
+ qh_setreplace(qh, neighborB->neighbors, facet1, facet2);
+ trace4((qh, qh->ferr, 4036, "qh_mergefacet2d: merged v%d and neighbor f%d of f%d into f%d\n",
+ vertexA->id, neighborB->id, facet1->id, facet2->id));
+} /* mergefacet2d */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergeneighbors">-</a>
+
+ qh_mergeneighbors(qh, facet1, facet2 )
+ merges the neighbors of facet1 into facet2
+
+ see:
+ qh_mergecycle_neighbors()
+
+ design:
+ for each neighbor of facet1
+ if neighbor is also a neighbor of facet2
+ if neighbor is simpilicial
+ make ridges for later deletion as a degenerate facet
+ update its neighbor set
+ else
+ move the neighbor relation to facet2
+ remove the neighbor relation for facet1 and facet2
+*/
+void qh_mergeneighbors(qhT *qh, facetT *facet1, facetT *facet2) {
+ facetT *neighbor, **neighborp;
+
+ trace4((qh, qh->ferr, 4037, "qh_mergeneighbors: merge neighbors of f%d and f%d\n",
+ facet1->id, facet2->id));
+ qh->visit_id++;
+ FOREACHneighbor_(facet2) {
+ neighbor->visitid= qh->visit_id;
+ }
+ FOREACHneighbor_(facet1) {
+ if (neighbor->visitid == qh->visit_id) {
+ if (neighbor->simplicial) /* is degen, needs ridges */
+ qh_makeridges(qh, neighbor);
+ if (SETfirstt_(neighbor->neighbors, facetT) != facet1) /*keep newfacet->horizon*/
+ qh_setdel(neighbor->neighbors, facet1);
+ else {
+ qh_setdel(neighbor->neighbors, facet2);
+ qh_setreplace(qh, neighbor->neighbors, facet1, facet2);
+ }
+ }else if (neighbor != facet2) {
+ qh_setappend(qh, &(facet2->neighbors), neighbor);
+ qh_setreplace(qh, neighbor->neighbors, facet1, facet2);
+ }
+ }
+ qh_setdel(facet1->neighbors, facet2); /* here for makeridges */
+ qh_setdel(facet2->neighbors, facet1);
+} /* mergeneighbors */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergeridges">-</a>
+
+ qh_mergeridges(qh, facet1, facet2 )
+ merges the ridge set of facet1 into facet2
+
+ returns:
+ may delete all ridges for a vertex
+ sets vertex->delridge on deleted ridges
+
+ see:
+ qh_mergecycle_ridges()
+
+ design:
+ delete ridges between facet1 and facet2
+ mark (delridge) vertices on these ridges for later testing
+ for each remaining ridge
+ rename facet1 to facet2
+*/
+void qh_mergeridges(qhT *qh, facetT *facet1, facetT *facet2) {
+ ridgeT *ridge, **ridgep;
+ vertexT *vertex, **vertexp;
+
+ trace4((qh, qh->ferr, 4038, "qh_mergeridges: merge ridges of f%d and f%d\n",
+ facet1->id, facet2->id));
+ FOREACHridge_(facet2->ridges) {
+ if ((ridge->top == facet1) || (ridge->bottom == facet1)) {
+ FOREACHvertex_(ridge->vertices)
+ vertex->delridge= True;
+ qh_delridge(qh, ridge); /* expensive in high-d, could rebuild */
+ ridgep--; /*repeat*/
+ }
+ }
+ FOREACHridge_(facet1->ridges) {
+ if (ridge->top == facet1)
+ ridge->top= facet2;
+ else
+ ridge->bottom= facet2;
+ qh_setappend(qh, &(facet2->ridges), ridge);
+ }
+} /* mergeridges */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergesimplex">-</a>
+
+ qh_mergesimplex(qh, facet1, facet2, mergeapex )
+ merge simplicial facet1 into facet2
+ mergeapex==qh_MERGEapex if merging samecycle into horizon facet
+ vertex id is latest (most recently created)
+ facet1 may be contained in facet2
+ ridges exist for both facets
+
+ returns:
+ facet2 with updated vertices, ridges, neighbors
+ updated neighbors for facet1's vertices
+ facet1 not deleted
+ sets vertex->delridge on deleted ridges
+
+ notes:
+ special case code since this is the most common merge
+ called from qh_mergefacet()
+
+ design:
+ if qh_MERGEapex
+ add vertices of facet2 to qh.new_vertexlist if necessary
+ add apex to facet2
+ else
+ for each ridge between facet1 and facet2
+ set vertex->delridge
+ determine the apex for facet1 (i.e., vertex to be merged)
+ unless apex already in facet2
+ insert apex into vertices for facet2
+ add vertices of facet2 to qh.new_vertexlist if necessary
+ add apex to qh.new_vertexlist if necessary
+ for each vertex of facet1
+ if apex
+ rename facet1 to facet2 in its vertex neighbors
+ else
+ delete facet1 from vertex neighors
+ if only in facet2
+ add vertex to qh.del_vertices for later deletion
+ for each ridge of facet1
+ delete ridges between facet1 and facet2
+ append other ridges to facet2 after renaming facet to facet2
+*/
+void qh_mergesimplex(qhT *qh, facetT *facet1, facetT *facet2, boolT mergeapex) {
+ vertexT *vertex, **vertexp, *apex;
+ ridgeT *ridge, **ridgep;
+ boolT issubset= False;
+ int vertex_i= -1, vertex_n;
+ facetT *neighbor, **neighborp, *otherfacet;
+
+ if (mergeapex) {
+ if (!facet2->newfacet)
+ qh_newvertices(qh, facet2->vertices); /* apex is new */
+ apex= SETfirstt_(facet1->vertices, vertexT);
+ if (SETfirstt_(facet2->vertices, vertexT) != apex)
+ qh_setaddnth(qh, &facet2->vertices, 0, apex); /* apex has last id */
+ else
+ issubset= True;
+ }else {
+ zinc_(Zmergesimplex);
+ FOREACHvertex_(facet1->vertices)
+ vertex->seen= False;
+ FOREACHridge_(facet1->ridges) {
+ if (otherfacet_(ridge, facet1) == facet2) {
+ FOREACHvertex_(ridge->vertices) {
+ vertex->seen= True;
+ vertex->delridge= True;
+ }
+ break;
+ }
+ }
+ FOREACHvertex_(facet1->vertices) {
+ if (!vertex->seen)
+ break; /* must occur */
+ }
+ apex= vertex;
+ trace4((qh, qh->ferr, 4039, "qh_mergesimplex: merge apex v%d of f%d into facet f%d\n",
+ apex->id, facet1->id, facet2->id));
+ FOREACHvertex_i_(qh, facet2->vertices) {
+ if (vertex->id < apex->id) {
+ break;
+ }else if (vertex->id == apex->id) {
+ issubset= True;
+ break;
+ }
+ }
+ if (!issubset)
+ qh_setaddnth(qh, &facet2->vertices, vertex_i, apex);
+ if (!facet2->newfacet)
+ qh_newvertices(qh, facet2->vertices);
+ else if (!apex->newlist) {
+ qh_removevertex(qh, apex);
+ qh_appendvertex(qh, apex);
+ }
+ }
+ trace4((qh, qh->ferr, 4040, "qh_mergesimplex: update vertex neighbors of f%d\n",
+ facet1->id));
+ FOREACHvertex_(facet1->vertices) {
+ if (vertex == apex && !issubset)
+ qh_setreplace(qh, vertex->neighbors, facet1, facet2);
+ else {
+ qh_setdel(vertex->neighbors, facet1);
+ if (!SETsecond_(vertex->neighbors))
+ qh_mergevertex_del(qh, vertex, facet1, facet2);
+ }
+ }
+ trace4((qh, qh->ferr, 4041, "qh_mergesimplex: merge ridges and neighbors of f%d into f%d\n",
+ facet1->id, facet2->id));
+ qh->visit_id++;
+ FOREACHneighbor_(facet2)
+ neighbor->visitid= qh->visit_id;
+ FOREACHridge_(facet1->ridges) {
+ otherfacet= otherfacet_(ridge, facet1);
+ if (otherfacet == facet2) {
+ qh_setdel(facet2->ridges, ridge);
+ qh_setfree(qh, &(ridge->vertices));
+ qh_memfree(qh, ridge, (int)sizeof(ridgeT));
+ qh_setdel(facet2->neighbors, facet1);
+ }else {
+ qh_setappend(qh, &facet2->ridges, ridge);
+ if (otherfacet->visitid != qh->visit_id) {
+ qh_setappend(qh, &facet2->neighbors, otherfacet);
+ qh_setreplace(qh, otherfacet->neighbors, facet1, facet2);
+ otherfacet->visitid= qh->visit_id;
+ }else {
+ if (otherfacet->simplicial) /* is degen, needs ridges */
+ qh_makeridges(qh, otherfacet);
+ if (SETfirstt_(otherfacet->neighbors, facetT) != facet1)
+ qh_setdel(otherfacet->neighbors, facet1);
+ else { /*keep newfacet->neighbors->horizon*/
+ qh_setdel(otherfacet->neighbors, facet2);
+ qh_setreplace(qh, otherfacet->neighbors, facet1, facet2);
+ }
+ }
+ if (ridge->top == facet1) /* wait until after qh_makeridges */
+ ridge->top= facet2;
+ else
+ ridge->bottom= facet2;
+ }
+ }
+ SETfirst_(facet1->ridges)= NULL; /* it will be deleted */
+ trace3((qh, qh->ferr, 3006, "qh_mergesimplex: merged simplex f%d apex v%d into facet f%d\n",
+ facet1->id, getid_(apex), facet2->id));
+} /* mergesimplex */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergevertex_del">-</a>
+
+ qh_mergevertex_del(qh, vertex, facet1, facet2 )
+ delete a vertex because of merging facet1 into facet2
+
+ returns:
+ deletes vertex from facet2
+ adds vertex to qh.del_vertices for later deletion
+*/
+void qh_mergevertex_del(qhT *qh, vertexT *vertex, facetT *facet1, facetT *facet2) {
+
+ zinc_(Zmergevertex);
+ trace2((qh, qh->ferr, 2035, "qh_mergevertex_del: deleted v%d when merging f%d into f%d\n",
+ vertex->id, facet1->id, facet2->id));
+ qh_setdelsorted(facet2->vertices, vertex);
+ vertex->deleted= True;
+ qh_setappend(qh, &qh->del_vertices, vertex);
+} /* mergevertex_del */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergevertex_neighbors">-</a>
+
+ qh_mergevertex_neighbors(qh, facet1, facet2 )
+ merge the vertex neighbors of facet1 to facet2
+
+ returns:
+ if vertex is current qh.vertex_visit
+ deletes facet1 from vertex->neighbors
+ else
+ renames facet1 to facet2 in vertex->neighbors
+ deletes vertices if only one neighbor
+
+ notes:
+ assumes vertex neighbor sets are good
+*/
+void qh_mergevertex_neighbors(qhT *qh, facetT *facet1, facetT *facet2) {
+ vertexT *vertex, **vertexp;
+
+ trace4((qh, qh->ferr, 4042, "qh_mergevertex_neighbors: merge vertex neighbors of f%d and f%d\n",
+ facet1->id, facet2->id));
+ if (qh->tracevertex) {
+ qh_fprintf(qh, qh->ferr, 8081, "qh_mergevertex_neighbors: of f%d and f%d at furthest p%d f0= %p\n",
+ facet1->id, facet2->id, qh->furthest_id, qh->tracevertex->neighbors->e[0].p);
+ qh_errprint(qh, "TRACE", NULL, NULL, NULL, qh->tracevertex);
+ }
+ FOREACHvertex_(facet1->vertices) {
+ if (vertex->visitid != qh->vertex_visit)
+ qh_setreplace(qh, vertex->neighbors, facet1, facet2);
+ else {
+ qh_setdel(vertex->neighbors, facet1);
+ if (!SETsecond_(vertex->neighbors))
+ qh_mergevertex_del(qh, vertex, facet1, facet2);
+ }
+ }
+ if (qh->tracevertex)
+ qh_errprint(qh, "TRACE", NULL, NULL, NULL, qh->tracevertex);
+} /* mergevertex_neighbors */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="mergevertices">-</a>
+
+ qh_mergevertices(qh, vertices1, vertices2 )
+ merges the vertex set of facet1 into facet2
+
+ returns:
+ replaces vertices2 with merged set
+ preserves vertex_visit for qh_mergevertex_neighbors
+ updates qh.newvertex_list
+
+ design:
+ create a merged set of both vertices (in inverse id order)
+*/
+void qh_mergevertices(qhT *qh, setT *vertices1, setT **vertices2) {
+ int newsize= qh_setsize(qh, vertices1)+qh_setsize(qh, *vertices2) - qh->hull_dim + 1;
+ setT *mergedvertices;
+ vertexT *vertex, **vertexp, **vertex2= SETaddr_(*vertices2, vertexT);
+
+ mergedvertices= qh_settemp(qh, newsize);
+ FOREACHvertex_(vertices1) {
+ if (!*vertex2 || vertex->id > (*vertex2)->id)
+ qh_setappend(qh, &mergedvertices, vertex);
+ else {
+ while (*vertex2 && (*vertex2)->id > vertex->id)
+ qh_setappend(qh, &mergedvertices, *vertex2++);
+ if (!*vertex2 || (*vertex2)->id < vertex->id)
+ qh_setappend(qh, &mergedvertices, vertex);
+ else
+ qh_setappend(qh, &mergedvertices, *vertex2++);
+ }
+ }
+ while (*vertex2)
+ qh_setappend(qh, &mergedvertices, *vertex2++);
+ if (newsize < qh_setsize(qh, mergedvertices)) {
+ qh_fprintf(qh, qh->ferr, 6100, "qhull internal error (qh_mergevertices): facets did not share a ridge\n");
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ qh_setfree(qh, vertices2);
+ *vertices2= mergedvertices;
+ qh_settemppop(qh);
+} /* mergevertices */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="neighbor_intersections">-</a>
+
+ qh_neighbor_intersections(qh, vertex )
+ return intersection of all vertices in vertex->neighbors except for vertex
+
+ returns:
+ returns temporary set of vertices
+ does not include vertex
+ NULL if a neighbor is simplicial
+ NULL if empty set
+
+ notes:
+ used for renaming vertices
+
+ design:
+ initialize the intersection set with vertices of the first two neighbors
+ delete vertex from the intersection
+ for each remaining neighbor
+ intersect its vertex set with the intersection set
+ return NULL if empty
+ return the intersection set
+*/
+setT *qh_neighbor_intersections(qhT *qh, vertexT *vertex) {
+ facetT *neighbor, **neighborp, *neighborA, *neighborB;
+ setT *intersect;
+ int neighbor_i, neighbor_n;
+
+ FOREACHneighbor_(vertex) {
+ if (neighbor->simplicial)
+ return NULL;
+ }
+ neighborA= SETfirstt_(vertex->neighbors, facetT);
+ neighborB= SETsecondt_(vertex->neighbors, facetT);
+ zinc_(Zintersectnum);
+ if (!neighborA)
+ return NULL;
+ if (!neighborB)
+ intersect= qh_setcopy(qh, neighborA->vertices, 0);
+ else
+ intersect= qh_vertexintersect_new(qh, neighborA->vertices, neighborB->vertices);
+ qh_settemppush(qh, intersect);
+ qh_setdelsorted(intersect, vertex);
+ FOREACHneighbor_i_(qh, vertex) {
+ if (neighbor_i >= 2) {
+ zinc_(Zintersectnum);
+ qh_vertexintersect(qh, &intersect, neighbor->vertices);
+ if (!SETfirst_(intersect)) {
+ zinc_(Zintersectfail);
+ qh_settempfree(qh, &intersect);
+ return NULL;
+ }
+ }
+ }
+ trace3((qh, qh->ferr, 3007, "qh_neighbor_intersections: %d vertices in neighbor intersection of v%d\n",
+ qh_setsize(qh, intersect), vertex->id));
+ return intersect;
+} /* neighbor_intersections */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="newvertices">-</a>
+
+ qh_newvertices(qh, vertices )
+ add vertices to end of qh.vertex_list (marks as new vertices)
+
+ returns:
+ vertices on qh.newvertex_list
+ vertex->newlist set
+*/
+void qh_newvertices(qhT *qh, setT *vertices) {
+ vertexT *vertex, **vertexp;
+
+ FOREACHvertex_(vertices) {
+ if (!vertex->newlist) {
+ qh_removevertex(qh, vertex);
+ qh_appendvertex(qh, vertex);
+ }
+ }
+} /* newvertices */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="reducevertices">-</a>
+
+ qh_reducevertices(qh)
+ reduce extra vertices, shared vertices, and redundant vertices
+ facet->newmerge is set if merged since last call
+ if !qh.MERGEvertices, only removes extra vertices
+
+ returns:
+ True if also merged degen_redundant facets
+ vertices are renamed if possible
+ clears facet->newmerge and vertex->delridge
+
+ notes:
+ ignored if 2-d
+
+ design:
+ merge any degenerate or redundant facets
+ for each newly merged facet
+ remove extra vertices
+ if qh.MERGEvertices
+ for each newly merged facet
+ for each vertex
+ if vertex was on a deleted ridge
+ rename vertex if it is shared
+ remove delridge flag from new vertices
+*/
+boolT qh_reducevertices(qhT *qh) {
+ int numshare=0, numrename= 0;
+ boolT degenredun= False;
+ facetT *newfacet;
+ vertexT *vertex, **vertexp;
+
+ if (qh->hull_dim == 2)
+ return False;
+ if (qh_merge_degenredundant(qh))
+ degenredun= True;
+ LABELrestart:
+ FORALLnew_facets {
+ if (newfacet->newmerge) {
+ if (!qh->MERGEvertices)
+ newfacet->newmerge= False;
+ qh_remove_extravertices(qh, newfacet);
+ }
+ }
+ if (!qh->MERGEvertices)
+ return False;
+ FORALLnew_facets {
+ if (newfacet->newmerge) {
+ newfacet->newmerge= False;
+ FOREACHvertex_(newfacet->vertices) {
+ if (vertex->delridge) {
+ if (qh_rename_sharedvertex(qh, vertex, newfacet)) {
+ numshare++;
+ vertexp--; /* repeat since deleted vertex */
+ }
+ }
+ }
+ }
+ }
+ FORALLvertex_(qh->newvertex_list) {
+ if (vertex->delridge && !vertex->deleted) {
+ vertex->delridge= False;
+ if (qh->hull_dim >= 4 && qh_redundant_vertex(qh, vertex)) {
+ numrename++;
+ if (qh_merge_degenredundant(qh)) {
+ degenredun= True;
+ goto LABELrestart;
+ }
+ }
+ }
+ }
+ trace1((qh, qh->ferr, 1014, "qh_reducevertices: renamed %d shared vertices and %d redundant vertices. Degen? %d\n",
+ numshare, numrename, degenredun));
+ return degenredun;
+} /* reducevertices */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="redundant_vertex">-</a>
+
+ qh_redundant_vertex(qh, vertex )
+ detect and rename a redundant vertex
+ vertices have full vertex->neighbors
+
+ returns:
+ returns true if find a redundant vertex
+ deletes vertex(vertex->deleted)
+
+ notes:
+ only needed if vertex->delridge and hull_dim >= 4
+ may add degenerate facets to qh.facet_mergeset
+ doesn't change vertex->neighbors or create redundant facets
+
+ design:
+ intersect vertices of all facet neighbors of vertex
+ determine ridges for these vertices
+ if find a new vertex for vertex amoung these ridges and vertices
+ rename vertex to the new vertex
+*/
+vertexT *qh_redundant_vertex(qhT *qh, vertexT *vertex) {
+ vertexT *newvertex= NULL;
+ setT *vertices, *ridges;
+
+ trace3((qh, qh->ferr, 3008, "qh_redundant_vertex: check if v%d can be renamed\n", vertex->id));
+ if ((vertices= qh_neighbor_intersections(qh, vertex))) {
+ ridges= qh_vertexridges(qh, vertex);
+ if ((newvertex= qh_find_newvertex(qh, vertex, vertices, ridges)))
+ qh_renamevertex(qh, vertex, newvertex, ridges, NULL, NULL);
+ qh_settempfree(qh, &ridges);
+ qh_settempfree(qh, &vertices);
+ }
+ return newvertex;
+} /* redundant_vertex */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="remove_extravertices">-</a>
+
+ qh_remove_extravertices(qh, facet )
+ remove extra vertices from non-simplicial facets
+
+ returns:
+ returns True if it finds them
+
+ design:
+ for each vertex in facet
+ if vertex not in a ridge (i.e., no longer used)
+ delete vertex from facet
+ delete facet from vertice's neighbors
+ unless vertex in another facet
+ add vertex to qh.del_vertices for later deletion
+*/
+boolT qh_remove_extravertices(qhT *qh, facetT *facet) {
+ ridgeT *ridge, **ridgep;
+ vertexT *vertex, **vertexp;
+ boolT foundrem= False;
+
+ trace4((qh, qh->ferr, 4043, "qh_remove_extravertices: test f%d for extra vertices\n",
+ facet->id));
+ FOREACHvertex_(facet->vertices)
+ vertex->seen= False;
+ FOREACHridge_(facet->ridges) {
+ FOREACHvertex_(ridge->vertices)
+ vertex->seen= True;
+ }
+ FOREACHvertex_(facet->vertices) {
+ if (!vertex->seen) {
+ foundrem= True;
+ zinc_(Zremvertex);
+ qh_setdelsorted(facet->vertices, vertex);
+ qh_setdel(vertex->neighbors, facet);
+ if (!qh_setsize(qh, vertex->neighbors)) {
+ vertex->deleted= True;
+ qh_setappend(qh, &qh->del_vertices, vertex);
+ zinc_(Zremvertexdel);
+ trace2((qh, qh->ferr, 2036, "qh_remove_extravertices: v%d deleted because it's lost all ridges\n", vertex->id));
+ }else
+ trace3((qh, qh->ferr, 3009, "qh_remove_extravertices: v%d removed from f%d because it's lost all ridges\n", vertex->id, facet->id));
+ vertexp--; /*repeat*/
+ }
+ }
+ return foundrem;
+} /* remove_extravertices */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="rename_sharedvertex">-</a>
+
+ qh_rename_sharedvertex(qh, vertex, facet )
+ detect and rename if shared vertex in facet
+ vertices have full ->neighbors
+
+ returns:
+ newvertex or NULL
+ the vertex may still exist in other facets (i.e., a neighbor was pinched)
+ does not change facet->neighbors
+ updates vertex->neighbors
+
+ notes:
+ a shared vertex for a facet is only in ridges to one neighbor
+ this may undo a pinched facet
+
+ it does not catch pinches involving multiple facets. These appear
+ to be difficult to detect, since an exhaustive search is too expensive.
+
+ design:
+ if vertex only has two neighbors
+ determine the ridges that contain the vertex
+ determine the vertices shared by both neighbors
+ if can find a new vertex in this set
+ rename the vertex to the new vertex
+*/
+vertexT *qh_rename_sharedvertex(qhT *qh, vertexT *vertex, facetT *facet) {
+ facetT *neighbor, **neighborp, *neighborA= NULL;
+ setT *vertices, *ridges;
+ vertexT *newvertex;
+
+ if (qh_setsize(qh, vertex->neighbors) == 2) {
+ neighborA= SETfirstt_(vertex->neighbors, facetT);
+ if (neighborA == facet)
+ neighborA= SETsecondt_(vertex->neighbors, facetT);
+ }else if (qh->hull_dim == 3)
+ return NULL;
+ else {
+ qh->visit_id++;
+ FOREACHneighbor_(facet)
+ neighbor->visitid= qh->visit_id;
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visitid == qh->visit_id) {
+ if (neighborA)
+ return NULL;
+ neighborA= neighbor;
+ }
+ }
+ if (!neighborA) {
+ qh_fprintf(qh, qh->ferr, 6101, "qhull internal error (qh_rename_sharedvertex): v%d's neighbors not in f%d\n",
+ vertex->id, facet->id);
+ qh_errprint(qh, "ERRONEOUS", facet, NULL, NULL, vertex);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ }
+ /* the vertex is shared by facet and neighborA */
+ ridges= qh_settemp(qh, qh->TEMPsize);
+ neighborA->visitid= ++qh->visit_id;
+ qh_vertexridges_facet(qh, vertex, facet, &ridges);
+ trace2((qh, qh->ferr, 2037, "qh_rename_sharedvertex: p%d(v%d) is shared by f%d(%d ridges) and f%d\n",
+ qh_pointid(qh, vertex->point), vertex->id, facet->id, qh_setsize(qh, ridges), neighborA->id));
+ zinc_(Zintersectnum);
+ vertices= qh_vertexintersect_new(qh, facet->vertices, neighborA->vertices);
+ qh_setdel(vertices, vertex);
+ qh_settemppush(qh, vertices);
+ if ((newvertex= qh_find_newvertex(qh, vertex, vertices, ridges)))
+ qh_renamevertex(qh, vertex, newvertex, ridges, facet, neighborA);
+ qh_settempfree(qh, &vertices);
+ qh_settempfree(qh, &ridges);
+ return newvertex;
+} /* rename_sharedvertex */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="renameridgevertex">-</a>
+
+ qh_renameridgevertex(qh, ridge, oldvertex, newvertex )
+ renames oldvertex as newvertex in ridge
+
+ returns:
+
+ design:
+ delete oldvertex from ridge
+ if newvertex already in ridge
+ copy ridge->noconvex to another ridge if possible
+ delete the ridge
+ else
+ insert newvertex into the ridge
+ adjust the ridge's orientation
+*/
+void qh_renameridgevertex(qhT *qh, ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex) {
+ int nth= 0, oldnth;
+ facetT *temp;
+ vertexT *vertex, **vertexp;
+
+ oldnth= qh_setindex(ridge->vertices, oldvertex);
+ qh_setdelnthsorted(qh, ridge->vertices, oldnth);
+ FOREACHvertex_(ridge->vertices) {
+ if (vertex == newvertex) {
+ zinc_(Zdelridge);
+ if (ridge->nonconvex) /* only one ridge has nonconvex set */
+ qh_copynonconvex(qh, ridge);
+ trace2((qh, qh->ferr, 2038, "qh_renameridgevertex: ridge r%d deleted. It contained both v%d and v%d\n",
+ ridge->id, oldvertex->id, newvertex->id));
+ qh_delridge(qh, ridge);
+ return;
+ }
+ if (vertex->id < newvertex->id)
+ break;
+ nth++;
+ }
+ qh_setaddnth(qh, &ridge->vertices, nth, newvertex);
+ if (abs(oldnth - nth)%2) {
+ trace3((qh, qh->ferr, 3010, "qh_renameridgevertex: swapped the top and bottom of ridge r%d\n",
+ ridge->id));
+ temp= ridge->top;
+ ridge->top= ridge->bottom;
+ ridge->bottom= temp;
+ }
+} /* renameridgevertex */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="renamevertex">-</a>
+
+ qh_renamevertex(qh, oldvertex, newvertex, ridges, oldfacet, neighborA )
+ renames oldvertex as newvertex in ridges
+ gives oldfacet/neighborA if oldvertex is shared between two facets
+
+ returns:
+ oldvertex may still exist afterwards
+
+
+ notes:
+ can not change neighbors of newvertex (since it's a subset)
+
+ design:
+ for each ridge in ridges
+ rename oldvertex to newvertex and delete degenerate ridges
+ if oldfacet not defined
+ for each neighbor of oldvertex
+ delete oldvertex from neighbor's vertices
+ remove extra vertices from neighbor
+ add oldvertex to qh.del_vertices
+ else if oldvertex only between oldfacet and neighborA
+ delete oldvertex from oldfacet and neighborA
+ add oldvertex to qh.del_vertices
+ else oldvertex is in oldfacet and neighborA and other facets (i.e., pinched)
+ delete oldvertex from oldfacet
+ delete oldfacet from oldvertice's neighbors
+ remove extra vertices (e.g., oldvertex) from neighborA
+*/
+void qh_renamevertex(qhT *qh, vertexT *oldvertex, vertexT *newvertex, setT *ridges, facetT *oldfacet, facetT *neighborA) {
+ facetT *neighbor, **neighborp;
+ ridgeT *ridge, **ridgep;
+ boolT istrace= False;
+
+ if (qh->IStracing >= 2 || oldvertex->id == qh->tracevertex_id ||
+ newvertex->id == qh->tracevertex_id)
+ istrace= True;
+ FOREACHridge_(ridges)
+ qh_renameridgevertex(qh, ridge, oldvertex, newvertex);
+ if (!oldfacet) {
+ zinc_(Zrenameall);
+ if (istrace)
+ qh_fprintf(qh, qh->ferr, 8082, "qh_renamevertex: renamed v%d to v%d in several facets\n",
+ oldvertex->id, newvertex->id);
+ FOREACHneighbor_(oldvertex) {
+ qh_maydropneighbor(qh, neighbor);
+ qh_setdelsorted(neighbor->vertices, oldvertex);
+ if (qh_remove_extravertices(qh, neighbor))
+ neighborp--; /* neighbor may be deleted */
+ }
+ if (!oldvertex->deleted) {
+ oldvertex->deleted= True;
+ qh_setappend(qh, &qh->del_vertices, oldvertex);
+ }
+ }else if (qh_setsize(qh, oldvertex->neighbors) == 2) {
+ zinc_(Zrenameshare);
+ if (istrace)
+ qh_fprintf(qh, qh->ferr, 8083, "qh_renamevertex: renamed v%d to v%d in oldfacet f%d\n",
+ oldvertex->id, newvertex->id, oldfacet->id);
+ FOREACHneighbor_(oldvertex)
+ qh_setdelsorted(neighbor->vertices, oldvertex);
+ oldvertex->deleted= True;
+ qh_setappend(qh, &qh->del_vertices, oldvertex);
+ }else {
+ zinc_(Zrenamepinch);
+ if (istrace || qh->IStracing)
+ qh_fprintf(qh, qh->ferr, 8084, "qh_renamevertex: renamed pinched v%d to v%d between f%d and f%d\n",
+ oldvertex->id, newvertex->id, oldfacet->id, neighborA->id);
+ qh_setdelsorted(oldfacet->vertices, oldvertex);
+ qh_setdel(oldvertex->neighbors, oldfacet);
+ qh_remove_extravertices(qh, neighborA);
+ }
+} /* renamevertex */
+
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="test_appendmerge">-</a>
+
+ qh_test_appendmerge(qh, facet, neighbor )
+ tests facet/neighbor for convexity
+ appends to mergeset if non-convex
+ if pre-merging,
+ nop if qh.SKIPconvex, or qh.MERGEexact and coplanar
+
+ returns:
+ true if appends facet/neighbor to mergeset
+ sets facet->center as needed
+ does not change facet->seen
+
+ design:
+ if qh.cos_max is defined
+ if the angle between facet normals is too shallow
+ append an angle-coplanar merge to qh.mergeset
+ return True
+ make facet's centrum if needed
+ if facet's centrum is above the neighbor
+ set isconcave
+ else
+ if facet's centrum is not below the neighbor
+ set iscoplanar
+ make neighbor's centrum if needed
+ if neighbor's centrum is above the facet
+ set isconcave
+ else if neighbor's centrum is not below the facet
+ set iscoplanar
+ if isconcave or iscoplanar
+ get angle if needed
+ append concave or coplanar merge to qh.mergeset
+*/
+boolT qh_test_appendmerge(qhT *qh, facetT *facet, facetT *neighbor) {
+ realT dist, dist2= -REALmax, angle= -REALmax;
+ boolT isconcave= False, iscoplanar= False, okangle= False;
+
+ if (qh->SKIPconvex && !qh->POSTmerging)
+ return False;
+ if ((!qh->MERGEexact || qh->POSTmerging) && qh->cos_max < REALmax/2) {
+ angle= qh_getangle(qh, facet->normal, neighbor->normal);
+ zinc_(Zangletests);
+ if (angle > qh->cos_max) {
+ zinc_(Zcoplanarangle);
+ qh_appendmergeset(qh, facet, neighbor, MRGanglecoplanar, &angle);
+ trace2((qh, qh->ferr, 2039, "qh_test_appendmerge: coplanar angle %4.4g between f%d and f%d\n",
+ angle, facet->id, neighbor->id));
+ return True;
+ }else
+ okangle= True;
+ }
+ if (!facet->center)
+ facet->center= qh_getcentrum(qh, facet);
+ zzinc_(Zcentrumtests);
+ qh_distplane(qh, facet->center, neighbor, &dist);
+ if (dist > qh->centrum_radius)
+ isconcave= True;
+ else {
+ if (dist > -qh->centrum_radius)
+ iscoplanar= True;
+ if (!neighbor->center)
+ neighbor->center= qh_getcentrum(qh, neighbor);
+ zzinc_(Zcentrumtests);
+ qh_distplane(qh, neighbor->center, facet, &dist2);
+ if (dist2 > qh->centrum_radius)
+ isconcave= True;
+ else if (!iscoplanar && dist2 > -qh->centrum_radius)
+ iscoplanar= True;
+ }
+ if (!isconcave && (!iscoplanar || (qh->MERGEexact && !qh->POSTmerging)))
+ return False;
+ if (!okangle && qh->ANGLEmerge) {
+ angle= qh_getangle(qh, facet->normal, neighbor->normal);
+ zinc_(Zangletests);
+ }
+ if (isconcave) {
+ zinc_(Zconcaveridge);
+ if (qh->ANGLEmerge)
+ angle += qh_ANGLEconcave + 0.5;
+ qh_appendmergeset(qh, facet, neighbor, MRGconcave, &angle);
+ trace0((qh, qh->ferr, 18, "qh_test_appendmerge: concave f%d to f%d dist %4.4g and reverse dist %4.4g angle %4.4g during p%d\n",
+ facet->id, neighbor->id, dist, dist2, angle, qh->furthest_id));
+ }else /* iscoplanar */ {
+ zinc_(Zcoplanarcentrum);
+ qh_appendmergeset(qh, facet, neighbor, MRGcoplanar, &angle);
+ trace2((qh, qh->ferr, 2040, "qh_test_appendmerge: coplanar f%d to f%d dist %4.4g, reverse dist %4.4g angle %4.4g\n",
+ facet->id, neighbor->id, dist, dist2, angle));
+ }
+ return True;
+} /* test_appendmerge */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="test_vneighbors">-</a>
+
+ qh_test_vneighbors(qh)
+ test vertex neighbors for convexity
+ tests all facets on qh.newfacet_list
+
+ returns:
+ true if non-convex vneighbors appended to qh.facet_mergeset
+ initializes vertex neighbors if needed
+
+ notes:
+ assumes all facet neighbors have been tested
+ this can be expensive
+ this does not guarantee that a centrum is below all facets
+ but it is unlikely
+ uses qh.visit_id
+
+ design:
+ build vertex neighbors if necessary
+ for all new facets
+ for all vertices
+ for each unvisited facet neighbor of the vertex
+ test new facet and neighbor for convexity
+*/
+boolT qh_test_vneighbors(qhT *qh /* qh->newfacet_list */) {
+ facetT *newfacet, *neighbor, **neighborp;
+ vertexT *vertex, **vertexp;
+ int nummerges= 0;
+
+ trace1((qh, qh->ferr, 1015, "qh_test_vneighbors: testing vertex neighbors for convexity\n"));
+ if (!qh->VERTEXneighbors)
+ qh_vertexneighbors(qh);
+ FORALLnew_facets
+ newfacet->seen= False;
+ FORALLnew_facets {
+ newfacet->seen= True;
+ newfacet->visitid= qh->visit_id++;
+ FOREACHneighbor_(newfacet)
+ newfacet->visitid= qh->visit_id;
+ FOREACHvertex_(newfacet->vertices) {
+ FOREACHneighbor_(vertex) {
+ if (neighbor->seen || neighbor->visitid == qh->visit_id)
+ continue;
+ if (qh_test_appendmerge(qh, newfacet, neighbor))
+ nummerges++;
+ }
+ }
+ }
+ zadd_(Ztestvneighbor, nummerges);
+ trace1((qh, qh->ferr, 1016, "qh_test_vneighbors: found %d non-convex, vertex neighbors\n",
+ nummerges));
+ return (nummerges > 0);
+} /* test_vneighbors */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="tracemerge">-</a>
+
+ qh_tracemerge(qh, facet1, facet2 )
+ print trace message after merge
+*/
+void qh_tracemerge(qhT *qh, facetT *facet1, facetT *facet2) {
+ boolT waserror= False;
+
+#ifndef qh_NOtrace
+ if (qh->IStracing >= 4)
+ qh_errprint(qh, "MERGED", facet2, NULL, NULL, NULL);
+ if (facet2 == qh->tracefacet || (qh->tracevertex && qh->tracevertex->newlist)) {
+ qh_fprintf(qh, qh->ferr, 8085, "qh_tracemerge: trace facet and vertex after merge of f%d and f%d, furthest p%d\n", facet1->id, facet2->id, qh->furthest_id);
+ if (facet2 != qh->tracefacet)
+ qh_errprint(qh, "TRACE", qh->tracefacet,
+ (qh->tracevertex && qh->tracevertex->neighbors) ?
+ SETfirstt_(qh->tracevertex->neighbors, facetT) : NULL,
+ NULL, qh->tracevertex);
+ }
+ if (qh->tracevertex) {
+ if (qh->tracevertex->deleted)
+ qh_fprintf(qh, qh->ferr, 8086, "qh_tracemerge: trace vertex deleted at furthest p%d\n",
+ qh->furthest_id);
+ else
+ qh_checkvertex(qh, qh->tracevertex);
+ }
+ if (qh->tracefacet) {
+ qh_checkfacet(qh, qh->tracefacet, True, &waserror);
+ if (waserror)
+ qh_errexit(qh, qh_ERRqhull, qh->tracefacet, NULL);
+ }
+#endif /* !qh_NOtrace */
+ if (qh->CHECKfrequently || qh->IStracing >= 4) { /* can't check polygon here */
+ qh_checkfacet(qh, facet2, True, &waserror);
+ if (waserror)
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+} /* tracemerge */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="tracemerging">-</a>
+
+ qh_tracemerging(qh)
+ print trace message during POSTmerging
+
+ returns:
+ updates qh.mergereport
+
+ notes:
+ called from qh_mergecycle() and qh_mergefacet()
+
+ see:
+ qh_buildtracing()
+*/
+void qh_tracemerging(qhT *qh) {
+ realT cpu;
+ int total;
+ time_t timedata;
+ struct tm *tp;
+
+ qh->mergereport= zzval_(Ztotmerge);
+ time(&timedata);
+ tp= localtime(&timedata);
+ cpu= qh_CPUclock;
+ cpu /= qh_SECticks;
+ total= zzval_(Ztotmerge) - zzval_(Zcyclehorizon) + zzval_(Zcyclefacettot);
+ qh_fprintf(qh, qh->ferr, 8087, "\n\
+At %d:%d:%d & %2.5g CPU secs, qhull has merged %d facets. The hull\n\
+ contains %d facets and %d vertices.\n",
+ tp->tm_hour, tp->tm_min, tp->tm_sec, cpu,
+ total, qh->num_facets - qh->num_visible,
+ qh->num_vertices-qh_setsize(qh, qh->del_vertices));
+} /* tracemerging */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="updatetested">-</a>
+
+ qh_updatetested(qh, facet1, facet2 )
+ clear facet2->tested and facet1->ridge->tested for merge
+
+ returns:
+ deletes facet2->center unless it's already large
+ if so, clears facet2->ridge->tested
+
+ design:
+ clear facet2->tested
+ clear ridge->tested for facet1's ridges
+ if facet2 has a centrum
+ if facet2 is large
+ set facet2->keepcentrum
+ else if facet2 has 3 vertices due to many merges, or not large and post merging
+ clear facet2->keepcentrum
+ unless facet2->keepcentrum
+ clear facet2->center to recompute centrum later
+ clear ridge->tested for facet2's ridges
+*/
+void qh_updatetested(qhT *qh, facetT *facet1, facetT *facet2) {
+ ridgeT *ridge, **ridgep;
+ int size;
+
+ facet2->tested= False;
+ FOREACHridge_(facet1->ridges)
+ ridge->tested= False;
+ if (!facet2->center)
+ return;
+ size= qh_setsize(qh, facet2->vertices);
+ if (!facet2->keepcentrum) {
+ if (size > qh->hull_dim + qh_MAXnewcentrum) {
+ facet2->keepcentrum= True;
+ zinc_(Zwidevertices);
+ }
+ }else if (size <= qh->hull_dim + qh_MAXnewcentrum) {
+ /* center and keepcentrum was set */
+ if (size == qh->hull_dim || qh->POSTmerging)
+ facet2->keepcentrum= False; /* if many merges need to recompute centrum */
+ }
+ if (!facet2->keepcentrum) {
+ qh_memfree(qh, facet2->center, qh->normal_size);
+ facet2->center= NULL;
+ FOREACHridge_(facet2->ridges)
+ ridge->tested= False;
+ }
+} /* updatetested */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="vertexridges">-</a>
+
+ qh_vertexridges(qh, vertex )
+ return temporary set of ridges adjacent to a vertex
+ vertex->neighbors defined
+
+ ntoes:
+ uses qh.visit_id
+ does not include implicit ridges for simplicial facets
+
+ design:
+ for each neighbor of vertex
+ add ridges that include the vertex to ridges
+*/
+setT *qh_vertexridges(qhT *qh, vertexT *vertex) {
+ facetT *neighbor, **neighborp;
+ setT *ridges= qh_settemp(qh, qh->TEMPsize);
+ int size;
+
+ qh->visit_id++;
+ FOREACHneighbor_(vertex)
+ neighbor->visitid= qh->visit_id;
+ FOREACHneighbor_(vertex) {
+ if (*neighborp) /* no new ridges in last neighbor */
+ qh_vertexridges_facet(qh, vertex, neighbor, &ridges);
+ }
+ if (qh->PRINTstatistics || qh->IStracing) {
+ size= qh_setsize(qh, ridges);
+ zinc_(Zvertexridge);
+ zadd_(Zvertexridgetot, size);
+ zmax_(Zvertexridgemax, size);
+ trace3((qh, qh->ferr, 3011, "qh_vertexridges: found %d ridges for v%d\n",
+ size, vertex->id));
+ }
+ return ridges;
+} /* vertexridges */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="vertexridges_facet">-</a>
+
+ qh_vertexridges_facet(qh, vertex, facet, ridges )
+ add adjacent ridges for vertex in facet
+ neighbor->visitid==qh.visit_id if it hasn't been visited
+
+ returns:
+ ridges updated
+ sets facet->visitid to qh.visit_id-1
+
+ design:
+ for each ridge of facet
+ if ridge of visited neighbor (i.e., unprocessed)
+ if vertex in ridge
+ append ridge to vertex
+ mark facet processed
+*/
+void qh_vertexridges_facet(qhT *qh, vertexT *vertex, facetT *facet, setT **ridges) {
+ ridgeT *ridge, **ridgep;
+ facetT *neighbor;
+
+ FOREACHridge_(facet->ridges) {
+ neighbor= otherfacet_(ridge, facet);
+ if (neighbor->visitid == qh->visit_id
+ && qh_setin(ridge->vertices, vertex))
+ qh_setappend(qh, ridges, ridge);
+ }
+ facet->visitid= qh->visit_id-1;
+} /* vertexridges_facet */
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >-------------------------------</a><a name="willdelete">-</a>
+
+ qh_willdelete(qh, facet, replace )
+ moves facet to visible list
+ sets facet->f.replace to replace (may be NULL)
+
+ returns:
+ bumps qh.num_visible
+*/
+void qh_willdelete(qhT *qh, facetT *facet, facetT *replace) {
+
+ qh_removefacet(qh, facet);
+ qh_prependfacet(qh, facet, &qh->visible_list);
+ qh->num_visible++;
+ facet->visible= True;
+ facet->f.replace= replace;
+} /* willdelete */
+
+#else /* qh_NOmerge */
+void qh_premerge(qhT *qh, vertexT *apex, realT maxcentrum, realT maxangle) {
+}
+void qh_postmerge(qhT *qh, const char *reason, realT maxcentrum, realT maxangle,
+ boolT vneighbors) {
+}
+boolT qh_checkzero(qhT *qh, boolT testall) {
+ }
+#endif /* qh_NOmerge */
+
diff --git a/xs/src/qhull/src/libqhull_r/merge_r.h b/xs/src/qhull/src/libqhull_r/merge_r.h
new file mode 100644
index 000000000..30a51815d
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/merge_r.h
@@ -0,0 +1,186 @@
+/*<html><pre> -<a href="qh-merge_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ merge_r.h
+ header file for merge_r.c
+
+ see qh-merge_r.htm and merge_r.c
+
+ Copyright (c) 1993-2015 C.B. Barber.
+ $Id: //main/2015/qhull/src/libqhull_r/merge_r.h#3 $$Change: 2079 $
+ $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+*/
+
+#ifndef qhDEFmerge
+#define qhDEFmerge 1
+
+#include "libqhull_r.h"
+
+
+/*============ -constants- ==============*/
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >--------------------------------</a><a name="qh_ANGLEredundant">-</a>
+
+ qh_ANGLEredundant
+ indicates redundant merge in mergeT->angle
+*/
+#define qh_ANGLEredundant 6.0
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >--------------------------------</a><a name="qh_ANGLEdegen">-</a>
+
+ qh_ANGLEdegen
+ indicates degenerate facet in mergeT->angle
+*/
+#define qh_ANGLEdegen 5.0
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >--------------------------------</a><a name="qh_ANGLEconcave">-</a>
+
+ qh_ANGLEconcave
+ offset to indicate concave facets in mergeT->angle
+
+ notes:
+ concave facets are assigned the range of [2,4] in mergeT->angle
+ roundoff error may make the angle less than 2
+*/
+#define qh_ANGLEconcave 1.5
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >--------------------------------</a><a name="MRG">-</a>
+
+ MRG... (mergeType)
+ indicates the type of a merge (mergeT->type)
+*/
+typedef enum { /* in sort order for facet_mergeset */
+ MRGnone= 0,
+ MRGcoplanar, /* centrum coplanar */
+ MRGanglecoplanar, /* angle coplanar */
+ /* could detect half concave ridges */
+ MRGconcave, /* concave ridge */
+ MRGflip, /* flipped facet. facet1 == facet2 */
+ MRGridge, /* duplicate ridge (qh_MERGEridge) */
+ /* degen and redundant go onto degen_mergeset */
+ MRGdegen, /* degenerate facet (!enough neighbors) facet1 == facet2 */
+ MRGredundant, /* redundant facet (vertex subset) */
+ /* merge_degenredundant assumes degen < redundant */
+ MRGmirror, /* mirror facet from qh_triangulate */
+ ENDmrg
+} mergeType;
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >--------------------------------</a><a name="qh_MERGEapex">-</a>
+
+ qh_MERGEapex
+ flag for qh_mergefacet() to indicate an apex merge
+*/
+#define qh_MERGEapex True
+
+/*============ -structures- ====================*/
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >--------------------------------</a><a name="mergeT">-</a>
+
+ mergeT
+ structure used to merge facets
+*/
+
+typedef struct mergeT mergeT;
+struct mergeT { /* initialize in qh_appendmergeset */
+ realT angle; /* angle between normals of facet1 and facet2 */
+ facetT *facet1; /* will merge facet1 into facet2 */
+ facetT *facet2;
+ mergeType type;
+};
+
+
+/*=========== -macros- =========================*/
+
+/*-<a href="qh-merge_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHmerge_">-</a>
+
+ FOREACHmerge_( merges ) {...}
+ assign 'merge' to each merge in merges
+
+ notes:
+ uses 'mergeT *merge, **mergep;'
+ if qh_mergefacet(),
+ restart since qh.facet_mergeset may change
+ see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHmerge_( merges ) FOREACHsetelement_(mergeT, merges, merge)
+
+/*============ prototypes in alphabetical order after pre/postmerge =======*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void qh_premerge(qhT *qh, vertexT *apex, realT maxcentrum, realT maxangle);
+void qh_postmerge(qhT *qh, const char *reason, realT maxcentrum, realT maxangle,
+ boolT vneighbors);
+void qh_all_merges(qhT *qh, boolT othermerge, boolT vneighbors);
+void qh_appendmergeset(qhT *qh, facetT *facet, facetT *neighbor, mergeType mergetype, realT *angle);
+setT *qh_basevertices(qhT *qh, facetT *samecycle);
+void qh_checkconnect(qhT *qh /* qh.new_facets */);
+boolT qh_checkzero(qhT *qh, boolT testall);
+int qh_compareangle(const void *p1, const void *p2);
+int qh_comparemerge(const void *p1, const void *p2);
+int qh_comparevisit(const void *p1, const void *p2);
+void qh_copynonconvex(qhT *qh, ridgeT *atridge);
+void qh_degen_redundant_facet(qhT *qh, facetT *facet);
+void qh_degen_redundant_neighbors(qhT *qh, facetT *facet, facetT *delfacet);
+vertexT *qh_find_newvertex(qhT *qh, vertexT *oldvertex, setT *vertices, setT *ridges);
+void qh_findbest_test(qhT *qh, boolT testcentrum, facetT *facet, facetT *neighbor,
+ facetT **bestfacet, realT *distp, realT *mindistp, realT *maxdistp);
+facetT *qh_findbestneighbor(qhT *qh, facetT *facet, realT *distp, realT *mindistp, realT *maxdistp);
+void qh_flippedmerges(qhT *qh, facetT *facetlist, boolT *wasmerge);
+void qh_forcedmerges(qhT *qh, boolT *wasmerge);
+void qh_getmergeset(qhT *qh, facetT *facetlist);
+void qh_getmergeset_initial(qhT *qh, facetT *facetlist);
+void qh_hashridge(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge, vertexT *oldvertex);
+ridgeT *qh_hashridge_find(qhT *qh, setT *hashtable, int hashsize, ridgeT *ridge,
+ vertexT *vertex, vertexT *oldvertex, int *hashslot);
+void qh_makeridges(qhT *qh, facetT *facet);
+void qh_mark_dupridges(qhT *qh, facetT *facetlist);
+void qh_maydropneighbor(qhT *qh, facetT *facet);
+int qh_merge_degenredundant(qhT *qh);
+void qh_merge_nonconvex(qhT *qh, facetT *facet1, facetT *facet2, mergeType mergetype);
+void qh_mergecycle(qhT *qh, facetT *samecycle, facetT *newfacet);
+void qh_mergecycle_all(qhT *qh, facetT *facetlist, boolT *wasmerge);
+void qh_mergecycle_facets(qhT *qh, facetT *samecycle, facetT *newfacet);
+void qh_mergecycle_neighbors(qhT *qh, facetT *samecycle, facetT *newfacet);
+void qh_mergecycle_ridges(qhT *qh, facetT *samecycle, facetT *newfacet);
+void qh_mergecycle_vneighbors(qhT *qh, facetT *samecycle, facetT *newfacet);
+void qh_mergefacet(qhT *qh, facetT *facet1, facetT *facet2, realT *mindist, realT *maxdist, boolT mergeapex);
+void qh_mergefacet2d(qhT *qh, facetT *facet1, facetT *facet2);
+void qh_mergeneighbors(qhT *qh, facetT *facet1, facetT *facet2);
+void qh_mergeridges(qhT *qh, facetT *facet1, facetT *facet2);
+void qh_mergesimplex(qhT *qh, facetT *facet1, facetT *facet2, boolT mergeapex);
+void qh_mergevertex_del(qhT *qh, vertexT *vertex, facetT *facet1, facetT *facet2);
+void qh_mergevertex_neighbors(qhT *qh, facetT *facet1, facetT *facet2);
+void qh_mergevertices(qhT *qh, setT *vertices1, setT **vertices);
+setT *qh_neighbor_intersections(qhT *qh, vertexT *vertex);
+void qh_newvertices(qhT *qh, setT *vertices);
+boolT qh_reducevertices(qhT *qh);
+vertexT *qh_redundant_vertex(qhT *qh, vertexT *vertex);
+boolT qh_remove_extravertices(qhT *qh, facetT *facet);
+vertexT *qh_rename_sharedvertex(qhT *qh, vertexT *vertex, facetT *facet);
+void qh_renameridgevertex(qhT *qh, ridgeT *ridge, vertexT *oldvertex, vertexT *newvertex);
+void qh_renamevertex(qhT *qh, vertexT *oldvertex, vertexT *newvertex, setT *ridges,
+ facetT *oldfacet, facetT *neighborA);
+boolT qh_test_appendmerge(qhT *qh, facetT *facet, facetT *neighbor);
+boolT qh_test_vneighbors(qhT *qh /* qh.newfacet_list */);
+void qh_tracemerge(qhT *qh, facetT *facet1, facetT *facet2);
+void qh_tracemerging(qhT *qh);
+void qh_updatetested(qhT *qh, facetT *facet1, facetT *facet2);
+setT *qh_vertexridges(qhT *qh, vertexT *vertex);
+void qh_vertexridges_facet(qhT *qh, vertexT *vertex, facetT *facet, setT **ridges);
+void qh_willdelete(qhT *qh, facetT *facet, facetT *replace);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* qhDEFmerge */
diff --git a/xs/src/qhull/src/libqhull_r/poly2_r.c b/xs/src/qhull/src/libqhull_r/poly2_r.c
new file mode 100644
index 000000000..b8ae9af9f
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/poly2_r.c
@@ -0,0 +1,3222 @@
+/*<html><pre> -<a href="qh-poly_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ poly2_r.c
+ implements polygons and simplicies
+
+ see qh-poly_r.htm, poly_r.h and libqhull_r.h
+
+ frequently used code is in poly_r.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/poly2_r.c#10 $$Change: 2069 $
+ $DateTime: 2016/01/18 22:05:03 $$Author: bbarber $
+*/
+
+#include "qhull_ra.h"
+
+/*======== functions in alphabetical order ==========*/
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="addhash">-</a>
+
+ qh_addhash( newelem, hashtable, hashsize, hash )
+ add newelem to linear hash table at hash if not already there
+*/
+void qh_addhash(void *newelem, setT *hashtable, int hashsize, int hash) {
+ int scan;
+ void *elem;
+
+ for (scan= (int)hash; (elem= SETelem_(hashtable, scan));
+ scan= (++scan >= hashsize ? 0 : scan)) {
+ if (elem == newelem)
+ break;
+ }
+ /* loop terminates because qh_HASHfactor >= 1.1 by qh_initbuffers */
+ if (!elem)
+ SETelem_(hashtable, scan)= newelem;
+} /* addhash */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="check_bestdist">-</a>
+
+ qh_check_bestdist(qh)
+ check that all points are within max_outside of the nearest facet
+ if qh.ONLYgood,
+ ignores !good facets
+
+ see:
+ qh_check_maxout(), qh_outerinner()
+
+ notes:
+ only called from qh_check_points()
+ seldom used since qh.MERGING is almost always set
+ if notverified>0 at end of routine
+ some points were well inside the hull. If the hull contains
+ a lens-shaped component, these points were not verified. Use
+ options 'Qi Tv' to verify all points. (Exhaustive check also verifies)
+
+ design:
+ determine facet for each point (if any)
+ for each point
+ start with the assigned facet or with the first facet
+ find the best facet for the point and check all coplanar facets
+ error if point is outside of facet
+*/
+void qh_check_bestdist(qhT *qh) {
+ boolT waserror= False, unassigned;
+ facetT *facet, *bestfacet, *errfacet1= NULL, *errfacet2= NULL;
+ facetT *facetlist;
+ realT dist, maxoutside, maxdist= -REALmax;
+ pointT *point;
+ int numpart= 0, facet_i, facet_n, notgood= 0, notverified= 0;
+ setT *facets;
+
+ trace1((qh, qh->ferr, 1020, "qh_check_bestdist: check points below nearest facet. Facet_list f%d\n",
+ qh->facet_list->id));
+ maxoutside= qh_maxouter(qh);
+ maxoutside += qh->DISTround;
+ /* one more qh.DISTround for check computation */
+ trace1((qh, qh->ferr, 1021, "qh_check_bestdist: check that all points are within %2.2g of best facet\n", maxoutside));
+ facets= qh_pointfacet(qh /*qh.facet_list*/);
+ if (!qh_QUICKhelp && qh->PRINTprecision)
+ qh_fprintf(qh, qh->ferr, 8091, "\n\
+qhull output completed. Verifying that %d points are\n\
+below %2.2g of the nearest %sfacet.\n",
+ qh_setsize(qh, facets), maxoutside, (qh->ONLYgood ? "good " : ""));
+ FOREACHfacet_i_(qh, facets) { /* for each point with facet assignment */
+ if (facet)
+ unassigned= False;
+ else {
+ unassigned= True;
+ facet= qh->facet_list;
+ }
+ point= qh_point(qh, facet_i);
+ if (point == qh->GOODpointp)
+ continue;
+ qh_distplane(qh, point, facet, &dist);
+ numpart++;
+ bestfacet= qh_findbesthorizon(qh, !qh_IScheckmax, point, facet, qh_NOupper, &dist, &numpart);
+ /* occurs after statistics reported */
+ maximize_(maxdist, dist);
+ if (dist > maxoutside) {
+ if (qh->ONLYgood && !bestfacet->good
+ && !((bestfacet= qh_findgooddist(qh, point, bestfacet, &dist, &facetlist))
+ && dist > maxoutside))
+ notgood++;
+ else {
+ waserror= True;
+ qh_fprintf(qh, qh->ferr, 6109, "qhull precision error: point p%d is outside facet f%d, distance= %6.8g maxoutside= %6.8g\n",
+ facet_i, bestfacet->id, dist, maxoutside);
+ if (errfacet1 != bestfacet) {
+ errfacet2= errfacet1;
+ errfacet1= bestfacet;
+ }
+ }
+ }else if (unassigned && dist < -qh->MAXcoplanar)
+ notverified++;
+ }
+ qh_settempfree(qh, &facets);
+ if (notverified && !qh->DELAUNAY && !qh_QUICKhelp && qh->PRINTprecision)
+ qh_fprintf(qh, qh->ferr, 8092, "\n%d points were well inside the hull. If the hull contains\n\
+a lens-shaped component, these points were not verified. Use\n\
+options 'Qci Tv' to verify all points.\n", notverified);
+ if (maxdist > qh->outside_err) {
+ qh_fprintf(qh, qh->ferr, 6110, "qhull precision error (qh_check_bestdist): a coplanar point is %6.2g from convex hull. The maximum value(qh.outside_err) is %6.2g\n",
+ maxdist, qh->outside_err);
+ qh_errexit2(qh, qh_ERRprec, errfacet1, errfacet2);
+ }else if (waserror && qh->outside_err > REALmax/2)
+ qh_errexit2(qh, qh_ERRprec, errfacet1, errfacet2);
+ /* else if waserror, the error was logged to qh.ferr but does not effect the output */
+ trace0((qh, qh->ferr, 20, "qh_check_bestdist: max distance outside %2.2g\n", maxdist));
+} /* check_bestdist */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="check_dupridge">-</a>
+
+ qh_check_dupridge(qh, facet1, dist1, facet2, dist2)
+ Check duplicate ridge between facet1 and facet2 for wide merge
+ dist1 is the maximum distance of facet1's vertices to facet2
+ dist2 is the maximum distance of facet2's vertices to facet1
+
+ Returns
+ Level 1 log of the duplicate ridge with the minimum distance between vertices
+ Throws error if the merge will increase the maximum facet width by qh_WIDEduplicate (100x)
+
+ called from:
+ qh_forcedmerges()
+*/
+#ifndef qh_NOmerge
+void qh_check_dupridge(qhT *qh, facetT *facet1, realT dist1, facetT *facet2, realT dist2) {
+ vertexT *vertex, **vertexp, *vertexA, **vertexAp;
+ realT dist, innerplane, mergedist, outerplane, prevdist, ratio;
+ realT minvertex= REALmax;
+
+ mergedist= fmin_(dist1, dist2);
+ qh_outerinner(qh, NULL, &outerplane, &innerplane); /* ratio from qh_printsummary */
+ prevdist= fmax_(outerplane, innerplane);
+ maximize_(prevdist, qh->ONEmerge + qh->DISTround);
+ maximize_(prevdist, qh->MINoutside + qh->DISTround);
+ ratio= mergedist/prevdist;
+ FOREACHvertex_(facet1->vertices) { /* The duplicate ridge is between facet1 and facet2, so either facet can be tested */
+ FOREACHvertexA_(facet1->vertices) {
+ if (vertex > vertexA){ /* Test each pair once */
+ dist= qh_pointdist(vertex->point, vertexA->point, qh->hull_dim);
+ minimize_(minvertex, dist);
+ }
+ }
+ }
+ trace0((qh, qh->ferr, 16, "qh_check_dupridge: duplicate ridge between f%d and f%d due to nearly-coincident vertices (%2.2g), dist %2.2g, reverse dist %2.2g, ratio %2.2g while processing p%d\n",
+ facet1->id, facet2->id, minvertex, dist1, dist2, ratio, qh->furthest_id));
+ if (ratio > qh_WIDEduplicate) {
+ qh_fprintf(qh, qh->ferr, 6271, "qhull precision error (qh_check_dupridge): wide merge (%.0f times wider) due to duplicate ridge with nearly coincident points (%2.2g) between f%d and f%d, merge dist %2.2g, while processing p%d\n- Ignore error with option 'Q12'\n- To be fixed in a later version of Qhull\n",
+ ratio, minvertex, facet1->id, facet2->id, mergedist, qh->furthest_id);
+ if (qh->DELAUNAY)
+ qh_fprintf(qh, qh->ferr, 8145, "- A bounding box for the input sites may alleviate this error.\n");
+ if(minvertex > qh_WIDEduplicate*prevdist)
+ qh_fprintf(qh, qh->ferr, 8146, "- Vertex distance %2.2g is greater than %d times maximum distance %2.2g\n Please report to bradb@shore.net with steps to reproduce and all output\n",
+ minvertex, qh_WIDEduplicate, prevdist);
+ if (!qh->NOwide)
+ qh_errexit2(qh, qh_ERRqhull, facet1, facet2);
+ }
+} /* check_dupridge */
+#endif
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="check_maxout">-</a>
+
+ qh_check_maxout(qh)
+ updates qh.max_outside by checking all points against bestfacet
+ if qh.ONLYgood, ignores !good facets
+
+ returns:
+ updates facet->maxoutside via qh_findbesthorizon()
+ sets qh.maxoutdone
+ if printing qh.min_vertex (qh_outerinner),
+ it is updated to the current vertices
+ removes inside/coplanar points from coplanarset as needed
+
+ notes:
+ defines coplanar as min_vertex instead of MAXcoplanar
+ may not need to check near-inside points because of qh.MAXcoplanar
+ and qh.KEEPnearinside (before it was -DISTround)
+
+ see also:
+ qh_check_bestdist()
+
+ design:
+ if qh.min_vertex is needed
+ for all neighbors of all vertices
+ test distance from vertex to neighbor
+ determine facet for each point (if any)
+ for each point with an assigned facet
+ find the best facet for the point and check all coplanar facets
+ (updates outer planes)
+ remove near-inside points from coplanar sets
+*/
+#ifndef qh_NOmerge
+void qh_check_maxout(qhT *qh) {
+ facetT *facet, *bestfacet, *neighbor, **neighborp, *facetlist;
+ realT dist, maxoutside, minvertex, old_maxoutside;
+ pointT *point;
+ int numpart= 0, facet_i, facet_n, notgood= 0;
+ setT *facets, *vertices;
+ vertexT *vertex;
+
+ trace1((qh, qh->ferr, 1022, "qh_check_maxout: check and update maxoutside for each facet.\n"));
+ maxoutside= minvertex= 0;
+ if (qh->VERTEXneighbors
+ && (qh->PRINTsummary || qh->KEEPinside || qh->KEEPcoplanar
+ || qh->TRACElevel || qh->PRINTstatistics
+ || qh->PRINTout[0] == qh_PRINTsummary || qh->PRINTout[0] == qh_PRINTnone)) {
+ trace1((qh, qh->ferr, 1023, "qh_check_maxout: determine actual maxoutside and minvertex\n"));
+ vertices= qh_pointvertex(qh /*qh.facet_list*/);
+ FORALLvertices {
+ FOREACHneighbor_(vertex) {
+ zinc_(Zdistvertex); /* distance also computed by main loop below */
+ qh_distplane(qh, vertex->point, neighbor, &dist);
+ minimize_(minvertex, dist);
+ if (-dist > qh->TRACEdist || dist > qh->TRACEdist
+ || neighbor == qh->tracefacet || vertex == qh->tracevertex)
+ qh_fprintf(qh, qh->ferr, 8093, "qh_check_maxout: p%d(v%d) is %.2g from f%d\n",
+ qh_pointid(qh, vertex->point), vertex->id, dist, neighbor->id);
+ }
+ }
+ if (qh->MERGING) {
+ wmin_(Wminvertex, qh->min_vertex);
+ }
+ qh->min_vertex= minvertex;
+ qh_settempfree(qh, &vertices);
+ }
+ facets= qh_pointfacet(qh /*qh.facet_list*/);
+ do {
+ old_maxoutside= fmax_(qh->max_outside, maxoutside);
+ FOREACHfacet_i_(qh, facets) { /* for each point with facet assignment */
+ if (facet) {
+ point= qh_point(qh, facet_i);
+ if (point == qh->GOODpointp)
+ continue;
+ zzinc_(Ztotcheck);
+ qh_distplane(qh, point, facet, &dist);
+ numpart++;
+ bestfacet= qh_findbesthorizon(qh, qh_IScheckmax, point, facet, !qh_NOupper, &dist, &numpart);
+ if (bestfacet && dist > maxoutside) {
+ if (qh->ONLYgood && !bestfacet->good
+ && !((bestfacet= qh_findgooddist(qh, point, bestfacet, &dist, &facetlist))
+ && dist > maxoutside))
+ notgood++;
+ else
+ maxoutside= dist;
+ }
+ if (dist > qh->TRACEdist || (bestfacet && bestfacet == qh->tracefacet))
+ qh_fprintf(qh, qh->ferr, 8094, "qh_check_maxout: p%d is %.2g above f%d\n",
+ qh_pointid(qh, point), dist, (bestfacet ? bestfacet->id : UINT_MAX));
+ }
+ }
+ }while
+ (maxoutside > 2*old_maxoutside);
+ /* if qh.maxoutside increases substantially, qh_SEARCHdist is not valid
+ e.g., RBOX 5000 s Z1 G1e-13 t1001200614 | qhull */
+ zzadd_(Zcheckpart, numpart);
+ qh_settempfree(qh, &facets);
+ wval_(Wmaxout)= maxoutside - qh->max_outside;
+ wmax_(Wmaxoutside, qh->max_outside);
+ qh->max_outside= maxoutside;
+ qh_nearcoplanar(qh /*qh.facet_list*/);
+ qh->maxoutdone= True;
+ trace1((qh, qh->ferr, 1024, "qh_check_maxout: maxoutside %2.2g, min_vertex %2.2g, outside of not good %d\n",
+ maxoutside, qh->min_vertex, notgood));
+} /* check_maxout */
+#else /* qh_NOmerge */
+void qh_check_maxout(qhT *qh) {
+}
+#endif
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="check_output">-</a>
+
+ qh_check_output(qh)
+ performs the checks at the end of qhull algorithm
+ Maybe called after voronoi output. Will recompute otherwise centrums are Voronoi centers instead
+*/
+void qh_check_output(qhT *qh) {
+ int i;
+
+ if (qh->STOPcone)
+ return;
+ if (qh->VERIFYoutput | qh->IStracing | qh->CHECKfrequently) {
+ qh_checkpolygon(qh, qh->facet_list);
+ qh_checkflipped_all(qh, qh->facet_list);
+ qh_checkconvex(qh, qh->facet_list, qh_ALGORITHMfault);
+ }else if (!qh->MERGING && qh_newstats(qh, qh->qhstat.precision, &i)) {
+ qh_checkflipped_all(qh, qh->facet_list);
+ qh_checkconvex(qh, qh->facet_list, qh_ALGORITHMfault);
+ }
+} /* check_output */
+
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="check_point">-</a>
+
+ qh_check_point(qh, point, facet, maxoutside, maxdist, errfacet1, errfacet2 )
+ check that point is less than maxoutside from facet
+*/
+void qh_check_point(qhT *qh, pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2) {
+ realT dist;
+
+ /* occurs after statistics reported */
+ qh_distplane(qh, point, facet, &dist);
+ if (dist > *maxoutside) {
+ if (*errfacet1 != facet) {
+ *errfacet2= *errfacet1;
+ *errfacet1= facet;
+ }
+ qh_fprintf(qh, qh->ferr, 6111, "qhull precision error: point p%d is outside facet f%d, distance= %6.8g maxoutside= %6.8g\n",
+ qh_pointid(qh, point), facet->id, dist, *maxoutside);
+ }
+ maximize_(*maxdist, dist);
+} /* qh_check_point */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="check_points">-</a>
+
+ qh_check_points(qh)
+ checks that all points are inside all facets
+
+ notes:
+ if many points and qh_check_maxout not called (i.e., !qh.MERGING),
+ calls qh_findbesthorizon (seldom done).
+ ignores flipped facets
+ maxoutside includes 2 qh.DISTrounds
+ one qh.DISTround for the computed distances in qh_check_points
+ qh_printafacet and qh_printsummary needs only one qh.DISTround
+ the computation for qh.VERIFYdirect does not account for qh.other_points
+
+ design:
+ if many points
+ use qh_check_bestdist()
+ else
+ for all facets
+ for all points
+ check that point is inside facet
+*/
+void qh_check_points(qhT *qh) {
+ facetT *facet, *errfacet1= NULL, *errfacet2= NULL;
+ realT total, maxoutside, maxdist= -REALmax;
+ pointT *point, **pointp, *pointtemp;
+ boolT testouter;
+
+ maxoutside= qh_maxouter(qh);
+ maxoutside += qh->DISTround;
+ /* one more qh.DISTround for check computation */
+ trace1((qh, qh->ferr, 1025, "qh_check_points: check all points below %2.2g of all facet planes\n",
+ maxoutside));
+ if (qh->num_good) /* miss counts other_points and !good facets */
+ total= (float)qh->num_good * (float)qh->num_points;
+ else
+ total= (float)qh->num_facets * (float)qh->num_points;
+ if (total >= qh_VERIFYdirect && !qh->maxoutdone) {
+ if (!qh_QUICKhelp && qh->SKIPcheckmax && qh->MERGING)
+ qh_fprintf(qh, qh->ferr, 7075, "qhull input warning: merging without checking outer planes('Q5' or 'Po').\n\
+Verify may report that a point is outside of a facet.\n");
+ qh_check_bestdist(qh);
+ }else {
+ if (qh_MAXoutside && qh->maxoutdone)
+ testouter= True;
+ else
+ testouter= False;
+ if (!qh_QUICKhelp) {
+ if (qh->MERGEexact)
+ qh_fprintf(qh, qh->ferr, 7076, "qhull input warning: exact merge ('Qx'). Verify may report that a point\n\
+is outside of a facet. See qh-optq.htm#Qx\n");
+ else if (qh->SKIPcheckmax || qh->NOnearinside)
+ qh_fprintf(qh, qh->ferr, 7077, "qhull input warning: no outer plane check ('Q5') or no processing of\n\
+near-inside points ('Q8'). Verify may report that a point is outside\n\
+of a facet.\n");
+ }
+ if (qh->PRINTprecision) {
+ if (testouter)
+ qh_fprintf(qh, qh->ferr, 8098, "\n\
+Output completed. Verifying that all points are below outer planes of\n\
+all %sfacets. Will make %2.0f distance computations.\n",
+ (qh->ONLYgood ? "good " : ""), total);
+ else
+ qh_fprintf(qh, qh->ferr, 8099, "\n\
+Output completed. Verifying that all points are below %2.2g of\n\
+all %sfacets. Will make %2.0f distance computations.\n",
+ maxoutside, (qh->ONLYgood ? "good " : ""), total);
+ }
+ FORALLfacets {
+ if (!facet->good && qh->ONLYgood)
+ continue;
+ if (facet->flipped)
+ continue;
+ if (!facet->normal) {
+ qh_fprintf(qh, qh->ferr, 7061, "qhull warning (qh_check_points): missing normal for facet f%d\n", facet->id);
+ continue;
+ }
+ if (testouter) {
+#if qh_MAXoutside
+ maxoutside= facet->maxoutside + 2* qh->DISTround;
+ /* one DISTround to actual point and another to computed point */
+#endif
+ }
+ FORALLpoints {
+ if (point != qh->GOODpointp)
+ qh_check_point(qh, point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2);
+ }
+ FOREACHpoint_(qh->other_points) {
+ if (point != qh->GOODpointp)
+ qh_check_point(qh, point, facet, &maxoutside, &maxdist, &errfacet1, &errfacet2);
+ }
+ }
+ if (maxdist > qh->outside_err) {
+ qh_fprintf(qh, qh->ferr, 6112, "qhull precision error (qh_check_points): a coplanar point is %6.2g from convex hull. The maximum value(qh.outside_err) is %6.2g\n",
+ maxdist, qh->outside_err );
+ qh_errexit2(qh, qh_ERRprec, errfacet1, errfacet2 );
+ }else if (errfacet1 && qh->outside_err > REALmax/2)
+ qh_errexit2(qh, qh_ERRprec, errfacet1, errfacet2 );
+ /* else if errfacet1, the error was logged to qh.ferr but does not effect the output */
+ trace0((qh, qh->ferr, 21, "qh_check_points: max distance outside %2.2g\n", maxdist));
+ }
+} /* check_points */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="checkconvex">-</a>
+
+ qh_checkconvex(qh, facetlist, fault )
+ check that each ridge in facetlist is convex
+ fault = qh_DATAfault if reporting errors
+ = qh_ALGORITHMfault otherwise
+
+ returns:
+ counts Zconcaveridges and Zcoplanarridges
+ errors if concaveridge or if merging an coplanar ridge
+
+ note:
+ if not merging,
+ tests vertices for neighboring simplicial facets
+ else if ZEROcentrum,
+ tests vertices for neighboring simplicial facets
+ else
+ tests centrums of neighboring facets
+
+ design:
+ for all facets
+ report flipped facets
+ if ZEROcentrum and simplicial neighbors
+ test vertices for neighboring simplicial facets
+ else
+ test centrum against all neighbors
+*/
+void qh_checkconvex(qhT *qh, facetT *facetlist, int fault) {
+ facetT *facet, *neighbor, **neighborp, *errfacet1=NULL, *errfacet2=NULL;
+ vertexT *vertex;
+ realT dist;
+ pointT *centrum;
+ boolT waserror= False, centrum_warning= False, tempcentrum= False, allsimplicial;
+ int neighbor_i;
+
+ trace1((qh, qh->ferr, 1026, "qh_checkconvex: check all ridges are convex\n"));
+ if (!qh->RERUN) {
+ zzval_(Zconcaveridges)= 0;
+ zzval_(Zcoplanarridges)= 0;
+ }
+ FORALLfacet_(facetlist) {
+ if (facet->flipped) {
+ qh_precision(qh, "flipped facet");
+ qh_fprintf(qh, qh->ferr, 6113, "qhull precision error: f%d is flipped(interior point is outside)\n",
+ facet->id);
+ errfacet1= facet;
+ waserror= True;
+ continue;
+ }
+ if (qh->MERGING && (!qh->ZEROcentrum || !facet->simplicial || facet->tricoplanar))
+ allsimplicial= False;
+ else {
+ allsimplicial= True;
+ neighbor_i= 0;
+ FOREACHneighbor_(facet) {
+ vertex= SETelemt_(facet->vertices, neighbor_i++, vertexT);
+ if (!neighbor->simplicial || neighbor->tricoplanar) {
+ allsimplicial= False;
+ continue;
+ }
+ qh_distplane(qh, vertex->point, neighbor, &dist);
+ if (dist > -qh->DISTround) {
+ if (fault == qh_DATAfault) {
+ qh_precision(qh, "coplanar or concave ridge");
+ qh_fprintf(qh, qh->ferr, 6114, "qhull precision error: initial simplex is not convex. Distance=%.2g\n", dist);
+ qh_errexit(qh, qh_ERRsingular, NULL, NULL);
+ }
+ if (dist > qh->DISTround) {
+ zzinc_(Zconcaveridges);
+ qh_precision(qh, "concave ridge");
+ qh_fprintf(qh, qh->ferr, 6115, "qhull precision error: f%d is concave to f%d, since p%d(v%d) is %6.4g above\n",
+ facet->id, neighbor->id, qh_pointid(qh, vertex->point), vertex->id, dist);
+ errfacet1= facet;
+ errfacet2= neighbor;
+ waserror= True;
+ }else if (qh->ZEROcentrum) {
+ if (dist > 0) { /* qh_checkzero checks that dist < - qh->DISTround */
+ zzinc_(Zcoplanarridges);
+ qh_precision(qh, "coplanar ridge");
+ qh_fprintf(qh, qh->ferr, 6116, "qhull precision error: f%d is clearly not convex to f%d, since p%d(v%d) is %6.4g above\n",
+ facet->id, neighbor->id, qh_pointid(qh, vertex->point), vertex->id, dist);
+ errfacet1= facet;
+ errfacet2= neighbor;
+ waserror= True;
+ }
+ }else {
+ zzinc_(Zcoplanarridges);
+ qh_precision(qh, "coplanar ridge");
+ trace0((qh, qh->ferr, 22, "qhull precision error: f%d may be coplanar to f%d, since p%d(v%d) is within %6.4g during p%d\n",
+ facet->id, neighbor->id, qh_pointid(qh, vertex->point), vertex->id, dist, qh->furthest_id));
+ }
+ }
+ }
+ }
+ if (!allsimplicial) {
+ if (qh->CENTERtype == qh_AScentrum) {
+ if (!facet->center)
+ facet->center= qh_getcentrum(qh, facet);
+ centrum= facet->center;
+ }else {
+ if (!centrum_warning && (!facet->simplicial || facet->tricoplanar)) {
+ centrum_warning= True;
+ qh_fprintf(qh, qh->ferr, 7062, "qhull warning: recomputing centrums for convexity test. This may lead to false, precision errors.\n");
+ }
+ centrum= qh_getcentrum(qh, facet);
+ tempcentrum= True;
+ }
+ FOREACHneighbor_(facet) {
+ if (qh->ZEROcentrum && facet->simplicial && neighbor->simplicial)
+ continue;
+ if (facet->tricoplanar || neighbor->tricoplanar)
+ continue;
+ zzinc_(Zdistconvex);
+ qh_distplane(qh, centrum, neighbor, &dist);
+ if (dist > qh->DISTround) {
+ zzinc_(Zconcaveridges);
+ qh_precision(qh, "concave ridge");
+ qh_fprintf(qh, qh->ferr, 6117, "qhull precision error: f%d is concave to f%d. Centrum of f%d is %6.4g above f%d\n",
+ facet->id, neighbor->id, facet->id, dist, neighbor->id);
+ errfacet1= facet;
+ errfacet2= neighbor;
+ waserror= True;
+ }else if (dist >= 0.0) { /* if arithmetic always rounds the same,
+ can test against centrum radius instead */
+ zzinc_(Zcoplanarridges);
+ qh_precision(qh, "coplanar ridge");
+ qh_fprintf(qh, qh->ferr, 6118, "qhull precision error: f%d is coplanar or concave to f%d. Centrum of f%d is %6.4g above f%d\n",
+ facet->id, neighbor->id, facet->id, dist, neighbor->id);
+ errfacet1= facet;
+ errfacet2= neighbor;
+ waserror= True;
+ }
+ }
+ if (tempcentrum)
+ qh_memfree(qh, centrum, qh->normal_size);
+ }
+ }
+ if (waserror && !qh->FORCEoutput)
+ qh_errexit2(qh, qh_ERRprec, errfacet1, errfacet2);
+} /* checkconvex */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="checkfacet">-</a>
+
+ qh_checkfacet(qh, facet, newmerge, waserror )
+ checks for consistency errors in facet
+ newmerge set if from merge_r.c
+
+ returns:
+ sets waserror if any error occurs
+
+ checks:
+ vertex ids are inverse sorted
+ unless newmerge, at least hull_dim neighbors and vertices (exactly if simplicial)
+ if non-simplicial, at least as many ridges as neighbors
+ neighbors are not duplicated
+ ridges are not duplicated
+ in 3-d, ridges=verticies
+ (qh.hull_dim-1) ridge vertices
+ neighbors are reciprocated
+ ridge neighbors are facet neighbors and a ridge for every neighbor
+ simplicial neighbors match facetintersect
+ vertex intersection matches vertices of common ridges
+ vertex neighbors and facet vertices agree
+ all ridges have distinct vertex sets
+
+ notes:
+ uses neighbor->seen
+
+ design:
+ check sets
+ check vertices
+ check sizes of neighbors and vertices
+ check for qh_MERGEridge and qh_DUPLICATEridge flags
+ check neighbor set
+ check ridge set
+ check ridges, neighbors, and vertices
+*/
+void qh_checkfacet(qhT *qh, facetT *facet, boolT newmerge, boolT *waserrorp) {
+ facetT *neighbor, **neighborp, *errother=NULL;
+ ridgeT *ridge, **ridgep, *errridge= NULL, *ridge2;
+ vertexT *vertex, **vertexp;
+ unsigned previousid= INT_MAX;
+ int numneighbors, numvertices, numridges=0, numRvertices=0;
+ boolT waserror= False;
+ int skipA, skipB, ridge_i, ridge_n, i;
+ setT *intersection;
+
+ if (facet->visible) {
+ qh_fprintf(qh, qh->ferr, 6119, "qhull internal error (qh_checkfacet): facet f%d is on the visible_list\n",
+ facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ if (!facet->normal) {
+ qh_fprintf(qh, qh->ferr, 6120, "qhull internal error (qh_checkfacet): facet f%d does not have a normal\n",
+ facet->id);
+ waserror= True;
+ }
+ qh_setcheck(qh, facet->vertices, "vertices for f", facet->id);
+ qh_setcheck(qh, facet->ridges, "ridges for f", facet->id);
+ qh_setcheck(qh, facet->outsideset, "outsideset for f", facet->id);
+ qh_setcheck(qh, facet->coplanarset, "coplanarset for f", facet->id);
+ qh_setcheck(qh, facet->neighbors, "neighbors for f", facet->id);
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->deleted) {
+ qh_fprintf(qh, qh->ferr, 6121, "qhull internal error (qh_checkfacet): deleted vertex v%d in f%d\n", vertex->id, facet->id);
+ qh_errprint(qh, "ERRONEOUS", NULL, NULL, NULL, vertex);
+ waserror= True;
+ }
+ if (vertex->id >= previousid) {
+ qh_fprintf(qh, qh->ferr, 6122, "qhull internal error (qh_checkfacet): vertices of f%d are not in descending id order at v%d\n", facet->id, vertex->id);
+ waserror= True;
+ break;
+ }
+ previousid= vertex->id;
+ }
+ numneighbors= qh_setsize(qh, facet->neighbors);
+ numvertices= qh_setsize(qh, facet->vertices);
+ numridges= qh_setsize(qh, facet->ridges);
+ if (facet->simplicial) {
+ if (numvertices+numneighbors != 2*qh->hull_dim
+ && !facet->degenerate && !facet->redundant) {
+ qh_fprintf(qh, qh->ferr, 6123, "qhull internal error (qh_checkfacet): for simplicial facet f%d, #vertices %d + #neighbors %d != 2*qh->hull_dim\n",
+ facet->id, numvertices, numneighbors);
+ qh_setprint(qh, qh->ferr, "", facet->neighbors);
+ waserror= True;
+ }
+ }else { /* non-simplicial */
+ if (!newmerge
+ &&(numvertices < qh->hull_dim || numneighbors < qh->hull_dim)
+ && !facet->degenerate && !facet->redundant) {
+ qh_fprintf(qh, qh->ferr, 6124, "qhull internal error (qh_checkfacet): for facet f%d, #vertices %d or #neighbors %d < qh->hull_dim\n",
+ facet->id, numvertices, numneighbors);
+ waserror= True;
+ }
+ /* in 3-d, can get a vertex twice in an edge list, e.g., RBOX 1000 s W1e-13 t995849315 D2 | QHULL d Tc Tv TP624 TW1e-13 T4 */
+ if (numridges < numneighbors
+ ||(qh->hull_dim == 3 && numvertices > numridges && !qh->NEWfacets)
+ ||(qh->hull_dim == 2 && numridges + numvertices + numneighbors != 6)) {
+ if (!facet->degenerate && !facet->redundant) {
+ qh_fprintf(qh, qh->ferr, 6125, "qhull internal error (qh_checkfacet): for facet f%d, #ridges %d < #neighbors %d or(3-d) > #vertices %d or(2-d) not all 2\n",
+ facet->id, numridges, numneighbors, numvertices);
+ waserror= True;
+ }
+ }
+ }
+ FOREACHneighbor_(facet) {
+ if (neighbor == qh_MERGEridge || neighbor == qh_DUPLICATEridge) {
+ qh_fprintf(qh, qh->ferr, 6126, "qhull internal error (qh_checkfacet): facet f%d still has a MERGE or DUP neighbor\n", facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ neighbor->seen= True;
+ }
+ FOREACHneighbor_(facet) {
+ if (!qh_setin(neighbor->neighbors, facet)) {
+ qh_fprintf(qh, qh->ferr, 6127, "qhull internal error (qh_checkfacet): facet f%d has neighbor f%d, but f%d does not have neighbor f%d\n",
+ facet->id, neighbor->id, neighbor->id, facet->id);
+ errother= neighbor;
+ waserror= True;
+ }
+ if (!neighbor->seen) {
+ qh_fprintf(qh, qh->ferr, 6128, "qhull internal error (qh_checkfacet): facet f%d has a duplicate neighbor f%d\n",
+ facet->id, neighbor->id);
+ errother= neighbor;
+ waserror= True;
+ }
+ neighbor->seen= False;
+ }
+ FOREACHridge_(facet->ridges) {
+ qh_setcheck(qh, ridge->vertices, "vertices for r", ridge->id);
+ ridge->seen= False;
+ }
+ FOREACHridge_(facet->ridges) {
+ if (ridge->seen) {
+ qh_fprintf(qh, qh->ferr, 6129, "qhull internal error (qh_checkfacet): facet f%d has a duplicate ridge r%d\n",
+ facet->id, ridge->id);
+ errridge= ridge;
+ waserror= True;
+ }
+ ridge->seen= True;
+ numRvertices= qh_setsize(qh, ridge->vertices);
+ if (numRvertices != qh->hull_dim - 1) {
+ qh_fprintf(qh, qh->ferr, 6130, "qhull internal error (qh_checkfacet): ridge between f%d and f%d has %d vertices\n",
+ ridge->top->id, ridge->bottom->id, numRvertices);
+ errridge= ridge;
+ waserror= True;
+ }
+ neighbor= otherfacet_(ridge, facet);
+ neighbor->seen= True;
+ if (!qh_setin(facet->neighbors, neighbor)) {
+ qh_fprintf(qh, qh->ferr, 6131, "qhull internal error (qh_checkfacet): for facet f%d, neighbor f%d of ridge r%d not in facet\n",
+ facet->id, neighbor->id, ridge->id);
+ errridge= ridge;
+ waserror= True;
+ }
+ }
+ if (!facet->simplicial) {
+ FOREACHneighbor_(facet) {
+ if (!neighbor->seen) {
+ qh_fprintf(qh, qh->ferr, 6132, "qhull internal error (qh_checkfacet): facet f%d does not have a ridge for neighbor f%d\n",
+ facet->id, neighbor->id);
+ errother= neighbor;
+ waserror= True;
+ }
+ intersection= qh_vertexintersect_new(qh, facet->vertices, neighbor->vertices);
+ qh_settemppush(qh, intersection);
+ FOREACHvertex_(facet->vertices) {
+ vertex->seen= False;
+ vertex->seen2= False;
+ }
+ FOREACHvertex_(intersection)
+ vertex->seen= True;
+ FOREACHridge_(facet->ridges) {
+ if (neighbor != otherfacet_(ridge, facet))
+ continue;
+ FOREACHvertex_(ridge->vertices) {
+ if (!vertex->seen) {
+ qh_fprintf(qh, qh->ferr, 6133, "qhull internal error (qh_checkfacet): vertex v%d in r%d not in f%d intersect f%d\n",
+ vertex->id, ridge->id, facet->id, neighbor->id);
+ qh_errexit(qh, qh_ERRqhull, facet, ridge);
+ }
+ vertex->seen2= True;
+ }
+ }
+ if (!newmerge) {
+ FOREACHvertex_(intersection) {
+ if (!vertex->seen2) {
+ if (qh->IStracing >=3 || !qh->MERGING) {
+ qh_fprintf(qh, qh->ferr, 6134, "qhull precision error (qh_checkfacet): vertex v%d in f%d intersect f%d but\n\
+ not in a ridge. This is ok under merging. Last point was p%d\n",
+ vertex->id, facet->id, neighbor->id, qh->furthest_id);
+ if (!qh->FORCEoutput && !qh->MERGING) {
+ qh_errprint(qh, "ERRONEOUS", facet, neighbor, NULL, vertex);
+ if (!qh->MERGING)
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ }
+ }
+ }
+ }
+ qh_settempfree(qh, &intersection);
+ }
+ }else { /* simplicial */
+ FOREACHneighbor_(facet) {
+ if (neighbor->simplicial) {
+ skipA= SETindex_(facet->neighbors, neighbor);
+ skipB= qh_setindex(neighbor->neighbors, facet);
+ if (skipA<0 || skipB<0 || !qh_setequal_skip(facet->vertices, skipA, neighbor->vertices, skipB)) {
+ qh_fprintf(qh, qh->ferr, 6135, "qhull internal error (qh_checkfacet): facet f%d skip %d and neighbor f%d skip %d do not match \n",
+ facet->id, skipA, neighbor->id, skipB);
+ errother= neighbor;
+ waserror= True;
+ }
+ }
+ }
+ }
+ if (qh->hull_dim < 5 && (qh->IStracing > 2 || qh->CHECKfrequently)) {
+ FOREACHridge_i_(qh, facet->ridges) { /* expensive */
+ for (i=ridge_i+1; i < ridge_n; i++) {
+ ridge2= SETelemt_(facet->ridges, i, ridgeT);
+ if (qh_setequal(ridge->vertices, ridge2->vertices)) {
+ qh_fprintf(qh, qh->ferr, 6227, "Qhull internal error (qh_checkfacet): ridges r%d and r%d have the same vertices\n",
+ ridge->id, ridge2->id);
+ errridge= ridge;
+ waserror= True;
+ }
+ }
+ }
+ }
+ if (waserror) {
+ qh_errprint(qh, "ERRONEOUS", facet, errother, errridge, NULL);
+ *waserrorp= True;
+ }
+} /* checkfacet */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="checkflipped_all">-</a>
+
+ qh_checkflipped_all(qh, facetlist )
+ checks orientation of facets in list against interior point
+*/
+void qh_checkflipped_all(qhT *qh, facetT *facetlist) {
+ facetT *facet;
+ boolT waserror= False;
+ realT dist;
+
+ if (facetlist == qh->facet_list)
+ zzval_(Zflippedfacets)= 0;
+ FORALLfacet_(facetlist) {
+ if (facet->normal && !qh_checkflipped(qh, facet, &dist, !qh_ALL)) {
+ qh_fprintf(qh, qh->ferr, 6136, "qhull precision error: facet f%d is flipped, distance= %6.12g\n",
+ facet->id, dist);
+ if (!qh->FORCEoutput) {
+ qh_errprint(qh, "ERRONEOUS", facet, NULL, NULL, NULL);
+ waserror= True;
+ }
+ }
+ }
+ if (waserror) {
+ qh_fprintf(qh, qh->ferr, 8101, "\n\
+A flipped facet occurs when its distance to the interior point is\n\
+greater than %2.2g, the maximum roundoff error.\n", -qh->DISTround);
+ qh_errexit(qh, qh_ERRprec, NULL, NULL);
+ }
+} /* checkflipped_all */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="checkpolygon">-</a>
+
+ qh_checkpolygon(qh, facetlist )
+ checks the correctness of the structure
+
+ notes:
+ call with either qh.facet_list or qh.newfacet_list
+ checks num_facets and num_vertices if qh.facet_list
+
+ design:
+ for each facet
+ checks facet and outside set
+ initializes vertexlist
+ for each facet
+ checks vertex set
+ if checking all facets(qh.facetlist)
+ check facet count
+ if qh.VERTEXneighbors
+ check vertex neighbors and count
+ check vertex count
+*/
+void qh_checkpolygon(qhT *qh, facetT *facetlist) {
+ facetT *facet;
+ vertexT *vertex, **vertexp, *vertexlist;
+ int numfacets= 0, numvertices= 0, numridges= 0;
+ int totvneighbors= 0, totvertices= 0;
+ boolT waserror= False, nextseen= False, visibleseen= False;
+
+ trace1((qh, qh->ferr, 1027, "qh_checkpolygon: check all facets from f%d\n", facetlist->id));
+ if (facetlist != qh->facet_list || qh->ONLYgood)
+ nextseen= True;
+ FORALLfacet_(facetlist) {
+ if (facet == qh->visible_list)
+ visibleseen= True;
+ if (!facet->visible) {
+ if (!nextseen) {
+ if (facet == qh->facet_next)
+ nextseen= True;
+ else if (qh_setsize(qh, facet->outsideset)) {
+ if (!qh->NARROWhull
+#if !qh_COMPUTEfurthest
+ || facet->furthestdist >= qh->MINoutside
+#endif
+ ) {
+ qh_fprintf(qh, qh->ferr, 6137, "qhull internal error (qh_checkpolygon): f%d has outside points before qh->facet_next\n",
+ facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ }
+ }
+ numfacets++;
+ qh_checkfacet(qh, facet, False, &waserror);
+ }
+ }
+ if (qh->visible_list && !visibleseen && facetlist == qh->facet_list) {
+ qh_fprintf(qh, qh->ferr, 6138, "qhull internal error (qh_checkpolygon): visible list f%d no longer on facet list\n", qh->visible_list->id);
+ qh_printlists(qh);
+ qh_errexit(qh, qh_ERRqhull, qh->visible_list, NULL);
+ }
+ if (facetlist == qh->facet_list)
+ vertexlist= qh->vertex_list;
+ else if (facetlist == qh->newfacet_list)
+ vertexlist= qh->newvertex_list;
+ else
+ vertexlist= NULL;
+ FORALLvertex_(vertexlist) {
+ vertex->seen= False;
+ vertex->visitid= 0;
+ }
+ FORALLfacet_(facetlist) {
+ if (facet->visible)
+ continue;
+ if (facet->simplicial)
+ numridges += qh->hull_dim;
+ else
+ numridges += qh_setsize(qh, facet->ridges);
+ FOREACHvertex_(facet->vertices) {
+ vertex->visitid++;
+ if (!vertex->seen) {
+ vertex->seen= True;
+ numvertices++;
+ if (qh_pointid(qh, vertex->point) == qh_IDunknown) {
+ qh_fprintf(qh, qh->ferr, 6139, "qhull internal error (qh_checkpolygon): unknown point %p for vertex v%d first_point %p\n",
+ vertex->point, vertex->id, qh->first_point);
+ waserror= True;
+ }
+ }
+ }
+ }
+ qh->vertex_visit += (unsigned int)numfacets;
+ if (facetlist == qh->facet_list) {
+ if (numfacets != qh->num_facets - qh->num_visible) {
+ qh_fprintf(qh, qh->ferr, 6140, "qhull internal error (qh_checkpolygon): actual number of facets is %d, cumulative facet count is %d - %d visible facets\n",
+ numfacets, qh->num_facets, qh->num_visible);
+ waserror= True;
+ }
+ qh->vertex_visit++;
+ if (qh->VERTEXneighbors) {
+ FORALLvertices {
+ qh_setcheck(qh, vertex->neighbors, "neighbors for v", vertex->id);
+ if (vertex->deleted)
+ continue;
+ totvneighbors += qh_setsize(qh, vertex->neighbors);
+ }
+ FORALLfacet_(facetlist)
+ totvertices += qh_setsize(qh, facet->vertices);
+ if (totvneighbors != totvertices) {
+ qh_fprintf(qh, qh->ferr, 6141, "qhull internal error (qh_checkpolygon): vertex neighbors inconsistent. Totvneighbors %d, totvertices %d\n",
+ totvneighbors, totvertices);
+ waserror= True;
+ }
+ }
+ if (numvertices != qh->num_vertices - qh_setsize(qh, qh->del_vertices)) {
+ qh_fprintf(qh, qh->ferr, 6142, "qhull internal error (qh_checkpolygon): actual number of vertices is %d, cumulative vertex count is %d\n",
+ numvertices, qh->num_vertices - qh_setsize(qh, qh->del_vertices));
+ waserror= True;
+ }
+ if (qh->hull_dim == 2 && numvertices != numfacets) {
+ qh_fprintf(qh, qh->ferr, 6143, "qhull internal error (qh_checkpolygon): #vertices %d != #facets %d\n",
+ numvertices, numfacets);
+ waserror= True;
+ }
+ if (qh->hull_dim == 3 && numvertices + numfacets - numridges/2 != 2) {
+ qh_fprintf(qh, qh->ferr, 7063, "qhull warning: #vertices %d + #facets %d - #edges %d != 2\n\
+ A vertex appears twice in a edge list. May occur during merging.",
+ numvertices, numfacets, numridges/2);
+ /* occurs if lots of merging and a vertex ends up twice in an edge list. e.g., RBOX 1000 s W1e-13 t995849315 D2 | QHULL d Tc Tv */
+ }
+ }
+ if (waserror)
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+} /* checkpolygon */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="checkvertex">-</a>
+
+ qh_checkvertex(qh, vertex )
+ check vertex for consistency
+ checks vertex->neighbors
+
+ notes:
+ neighbors checked efficiently in checkpolygon
+*/
+void qh_checkvertex(qhT *qh, vertexT *vertex) {
+ boolT waserror= False;
+ facetT *neighbor, **neighborp, *errfacet=NULL;
+
+ if (qh_pointid(qh, vertex->point) == qh_IDunknown) {
+ qh_fprintf(qh, qh->ferr, 6144, "qhull internal error (qh_checkvertex): unknown point id %p\n", vertex->point);
+ waserror= True;
+ }
+ if (vertex->id >= qh->vertex_id) {
+ qh_fprintf(qh, qh->ferr, 6145, "qhull internal error (qh_checkvertex): unknown vertex id %d\n", vertex->id);
+ waserror= True;
+ }
+ if (!waserror && !vertex->deleted) {
+ if (qh_setsize(qh, vertex->neighbors)) {
+ FOREACHneighbor_(vertex) {
+ if (!qh_setin(neighbor->vertices, vertex)) {
+ qh_fprintf(qh, qh->ferr, 6146, "qhull internal error (qh_checkvertex): neighbor f%d does not contain v%d\n", neighbor->id, vertex->id);
+ errfacet= neighbor;
+ waserror= True;
+ }
+ }
+ }
+ }
+ if (waserror) {
+ qh_errprint(qh, "ERRONEOUS", NULL, NULL, NULL, vertex);
+ qh_errexit(qh, qh_ERRqhull, errfacet, NULL);
+ }
+} /* checkvertex */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="clearcenters">-</a>
+
+ qh_clearcenters(qh, type )
+ clear old data from facet->center
+
+ notes:
+ sets new centertype
+ nop if CENTERtype is the same
+*/
+void qh_clearcenters(qhT *qh, qh_CENTER type) {
+ facetT *facet;
+
+ if (qh->CENTERtype != type) {
+ FORALLfacets {
+ if (facet->tricoplanar && !facet->keepcentrum)
+ facet->center= NULL; /* center is owned by the ->keepcentrum facet */
+ else if (qh->CENTERtype == qh_ASvoronoi){
+ if (facet->center) {
+ qh_memfree(qh, facet->center, qh->center_size);
+ facet->center= NULL;
+ }
+ }else /* qh->CENTERtype == qh_AScentrum */ {
+ if (facet->center) {
+ qh_memfree(qh, facet->center, qh->normal_size);
+ facet->center= NULL;
+ }
+ }
+ }
+ qh->CENTERtype= type;
+ }
+ trace2((qh, qh->ferr, 2043, "qh_clearcenters: switched to center type %d\n", type));
+} /* clearcenters */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="createsimplex">-</a>
+
+ qh_createsimplex(qh, vertices )
+ creates a simplex from a set of vertices
+
+ returns:
+ initializes qh.facet_list to the simplex
+ initializes qh.newfacet_list, .facet_tail
+ initializes qh.vertex_list, .newvertex_list, .vertex_tail
+
+ design:
+ initializes lists
+ for each vertex
+ create a new facet
+ for each new facet
+ create its neighbor set
+*/
+void qh_createsimplex(qhT *qh, setT *vertices) {
+ facetT *facet= NULL, *newfacet;
+ boolT toporient= True;
+ int vertex_i, vertex_n, nth;
+ setT *newfacets= qh_settemp(qh, qh->hull_dim+1);
+ vertexT *vertex;
+
+ qh->facet_list= qh->newfacet_list= qh->facet_tail= qh_newfacet(qh);
+ qh->num_facets= qh->num_vertices= qh->num_visible= 0;
+ qh->vertex_list= qh->newvertex_list= qh->vertex_tail= qh_newvertex(qh, NULL);
+ FOREACHvertex_i_(qh, vertices) {
+ newfacet= qh_newfacet(qh);
+ newfacet->vertices= qh_setnew_delnthsorted(qh, vertices, vertex_n,
+ vertex_i, 0);
+ newfacet->toporient= (unsigned char)toporient;
+ qh_appendfacet(qh, newfacet);
+ newfacet->newfacet= True;
+ qh_appendvertex(qh, vertex);
+ qh_setappend(qh, &newfacets, newfacet);
+ toporient ^= True;
+ }
+ FORALLnew_facets {
+ nth= 0;
+ FORALLfacet_(qh->newfacet_list) {
+ if (facet != newfacet)
+ SETelem_(newfacet->neighbors, nth++)= facet;
+ }
+ qh_settruncate(qh, newfacet->neighbors, qh->hull_dim);
+ }
+ qh_settempfree(qh, &newfacets);
+ trace1((qh, qh->ferr, 1028, "qh_createsimplex: created simplex\n"));
+} /* createsimplex */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="delridge">-</a>
+
+ qh_delridge(qh, ridge )
+ deletes ridge from data structures it belongs to
+ frees up its memory
+
+ notes:
+ in merge_r.c, caller sets vertex->delridge for each vertex
+ ridges also freed in qh_freeqhull
+*/
+void qh_delridge(qhT *qh, ridgeT *ridge) {
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+
+ qh_setdel(ridge->top->ridges, ridge);
+ qh_setdel(ridge->bottom->ridges, ridge);
+ qh_setfree(qh, &(ridge->vertices));
+ qh_memfree_(qh, ridge, (int)sizeof(ridgeT), freelistp);
+} /* delridge */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="delvertex">-</a>
+
+ qh_delvertex(qh, vertex )
+ deletes a vertex and frees its memory
+
+ notes:
+ assumes vertex->adjacencies have been updated if needed
+ unlinks from vertex_list
+*/
+void qh_delvertex(qhT *qh, vertexT *vertex) {
+
+ if (vertex == qh->tracevertex)
+ qh->tracevertex= NULL;
+ qh_removevertex(qh, vertex);
+ qh_setfree(qh, &vertex->neighbors);
+ qh_memfree(qh, vertex, (int)sizeof(vertexT));
+} /* delvertex */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="facet3vertex">-</a>
+
+ qh_facet3vertex(qh, )
+ return temporary set of 3-d vertices in qh_ORIENTclock order
+
+ design:
+ if simplicial facet
+ build set from facet->vertices with facet->toporient
+ else
+ for each ridge in order
+ build set from ridge's vertices
+*/
+setT *qh_facet3vertex(qhT *qh, facetT *facet) {
+ ridgeT *ridge, *firstridge;
+ vertexT *vertex;
+ int cntvertices, cntprojected=0;
+ setT *vertices;
+
+ cntvertices= qh_setsize(qh, facet->vertices);
+ vertices= qh_settemp(qh, cntvertices);
+ if (facet->simplicial) {
+ if (cntvertices != 3) {
+ qh_fprintf(qh, qh->ferr, 6147, "qhull internal error (qh_facet3vertex): only %d vertices for simplicial facet f%d\n",
+ cntvertices, facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ qh_setappend(qh, &vertices, SETfirst_(facet->vertices));
+ if (facet->toporient ^ qh_ORIENTclock)
+ qh_setappend(qh, &vertices, SETsecond_(facet->vertices));
+ else
+ qh_setaddnth(qh, &vertices, 0, SETsecond_(facet->vertices));
+ qh_setappend(qh, &vertices, SETelem_(facet->vertices, 2));
+ }else {
+ ridge= firstridge= SETfirstt_(facet->ridges, ridgeT); /* no infinite */
+ while ((ridge= qh_nextridge3d(ridge, facet, &vertex))) {
+ qh_setappend(qh, &vertices, vertex);
+ if (++cntprojected > cntvertices || ridge == firstridge)
+ break;
+ }
+ if (!ridge || cntprojected != cntvertices) {
+ qh_fprintf(qh, qh->ferr, 6148, "qhull internal error (qh_facet3vertex): ridges for facet %d don't match up. got at least %d\n",
+ facet->id, cntprojected);
+ qh_errexit(qh, qh_ERRqhull, facet, ridge);
+ }
+ }
+ return vertices;
+} /* facet3vertex */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="findbestfacet">-</a>
+
+ qh_findbestfacet(qh, point, bestoutside, bestdist, isoutside )
+ find facet that is furthest below a point
+
+ for Delaunay triangulations,
+ Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
+ Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates.
+
+ returns:
+ if bestoutside is set (e.g., qh_ALL)
+ returns best facet that is not upperdelaunay
+ if Delaunay and inside, point is outside circumsphere of bestfacet
+ else
+ returns first facet below point
+ if point is inside, returns nearest, !upperdelaunay facet
+ distance to facet
+ isoutside set if outside of facet
+
+ notes:
+ For tricoplanar facets, this finds one of the tricoplanar facets closest
+ to the point. For Delaunay triangulations, the point may be inside a
+ different tricoplanar facet. See <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
+
+ If inside, qh_findbestfacet performs an exhaustive search
+ this may be too conservative. Sometimes it is clearly required.
+
+ qh_findbestfacet is not used by qhull.
+ uses qh.visit_id and qh.coplanarset
+
+ see:
+ <a href="geom_r.c#findbest">qh_findbest</a>
+*/
+facetT *qh_findbestfacet(qhT *qh, pointT *point, boolT bestoutside,
+ realT *bestdist, boolT *isoutside) {
+ facetT *bestfacet= NULL;
+ int numpart, totpart= 0;
+
+ bestfacet= qh_findbest(qh, point, qh->facet_list,
+ bestoutside, !qh_ISnewfacets, bestoutside /* qh_NOupper */,
+ bestdist, isoutside, &totpart);
+ if (*bestdist < -qh->DISTround) {
+ bestfacet= qh_findfacet_all(qh, point, bestdist, isoutside, &numpart);
+ totpart += numpart;
+ if ((isoutside && *isoutside && bestoutside)
+ || (isoutside && !*isoutside && bestfacet->upperdelaunay)) {
+ bestfacet= qh_findbest(qh, point, bestfacet,
+ bestoutside, False, bestoutside,
+ bestdist, isoutside, &totpart);
+ totpart += numpart;
+ }
+ }
+ trace3((qh, qh->ferr, 3014, "qh_findbestfacet: f%d dist %2.2g isoutside %d totpart %d\n",
+ bestfacet->id, *bestdist, (isoutside ? *isoutside : UINT_MAX), totpart));
+ return bestfacet;
+} /* findbestfacet */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="findbestlower">-</a>
+
+ qh_findbestlower(qh, facet, point, bestdist, numpart )
+ returns best non-upper, non-flipped neighbor of facet for point
+ if needed, searches vertex neighbors
+
+ returns:
+ returns bestdist and updates numpart
+
+ notes:
+ if Delaunay and inside, point is outside of circumsphere of bestfacet
+ called by qh_findbest() for points above an upperdelaunay facet
+
+*/
+facetT *qh_findbestlower(qhT *qh, facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart) {
+ facetT *neighbor, **neighborp, *bestfacet= NULL;
+ realT bestdist= -REALmax/2 /* avoid underflow */;
+ realT dist;
+ vertexT *vertex;
+ boolT isoutside= False; /* not used */
+
+ zinc_(Zbestlower);
+ FOREACHneighbor_(upperfacet) {
+ if (neighbor->upperdelaunay || neighbor->flipped)
+ continue;
+ (*numpart)++;
+ qh_distplane(qh, point, neighbor, &dist);
+ if (dist > bestdist) {
+ bestfacet= neighbor;
+ bestdist= dist;
+ }
+ }
+ if (!bestfacet) {
+ zinc_(Zbestlowerv);
+ /* rarely called, numpart does not count nearvertex computations */
+ vertex= qh_nearvertex(qh, upperfacet, point, &dist);
+ qh_vertexneighbors(qh);
+ FOREACHneighbor_(vertex) {
+ if (neighbor->upperdelaunay || neighbor->flipped)
+ continue;
+ (*numpart)++;
+ qh_distplane(qh, point, neighbor, &dist);
+ if (dist > bestdist) {
+ bestfacet= neighbor;
+ bestdist= dist;
+ }
+ }
+ }
+ if (!bestfacet) {
+ zinc_(Zbestlowerall); /* invoked once per point in outsideset */
+ zmax_(Zbestloweralln, qh->num_facets);
+ /* [dec'15] Previously reported as QH6228 */
+ trace3((qh, qh->ferr, 3025, "qh_findbestlower: all neighbors of facet %d are flipped or upper Delaunay. Search all facets\n",
+ upperfacet->id));
+ /* rarely called */
+ bestfacet= qh_findfacet_all(qh, point, &bestdist, &isoutside, numpart);
+ }
+ *bestdistp= bestdist;
+ trace3((qh, qh->ferr, 3015, "qh_findbestlower: f%d dist %2.2g for f%d p%d\n",
+ bestfacet->id, bestdist, upperfacet->id, qh_pointid(qh, point)));
+ return bestfacet;
+} /* findbestlower */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="findfacet_all">-</a>
+
+ qh_findfacet_all(qh, point, bestdist, isoutside, numpart )
+ exhaustive search for facet below a point
+
+ for Delaunay triangulations,
+ Use qh_setdelaunay() to lift point to paraboloid and scale by 'Qbb' if needed
+ Do not use options 'Qbk', 'QBk', or 'QbB' since they scale the coordinates.
+
+ returns:
+ returns first facet below point
+ if point is inside,
+ returns nearest facet
+ distance to facet
+ isoutside if point is outside of the hull
+ number of distance tests
+
+ notes:
+ primarily for library users, rarely used by Qhull
+*/
+facetT *qh_findfacet_all(qhT *qh, pointT *point, realT *bestdist, boolT *isoutside,
+ int *numpart) {
+ facetT *bestfacet= NULL, *facet;
+ realT dist;
+ int totpart= 0;
+
+ *bestdist= -REALmax;
+ *isoutside= False;
+ FORALLfacets {
+ if (facet->flipped || !facet->normal)
+ continue;
+ totpart++;
+ qh_distplane(qh, point, facet, &dist);
+ if (dist > *bestdist) {
+ *bestdist= dist;
+ bestfacet= facet;
+ if (dist > qh->MINoutside) {
+ *isoutside= True;
+ break;
+ }
+ }
+ }
+ *numpart= totpart;
+ trace3((qh, qh->ferr, 3016, "qh_findfacet_all: f%d dist %2.2g isoutside %d totpart %d\n",
+ getid_(bestfacet), *bestdist, *isoutside, totpart));
+ return bestfacet;
+} /* findfacet_all */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="findgood">-</a>
+
+ qh_findgood(qh, facetlist, goodhorizon )
+ identify good facets for qh.PRINTgood
+ if qh.GOODvertex>0
+ facet includes point as vertex
+ if !match, returns goodhorizon
+ inactive if qh.MERGING
+ if qh.GOODpoint
+ facet is visible or coplanar (>0) or not visible (<0)
+ if qh.GOODthreshold
+ facet->normal matches threshold
+ if !goodhorizon and !match,
+ selects facet with closest angle
+ sets GOODclosest
+
+ returns:
+ number of new, good facets found
+ determines facet->good
+ may update qh.GOODclosest
+
+ notes:
+ qh_findgood_all further reduces the good region
+
+ design:
+ count good facets
+ mark good facets for qh.GOODpoint
+ mark good facets for qh.GOODthreshold
+ if necessary
+ update qh.GOODclosest
+*/
+int qh_findgood(qhT *qh, facetT *facetlist, int goodhorizon) {
+ facetT *facet, *bestfacet= NULL;
+ realT angle, bestangle= REALmax, dist;
+ int numgood=0;
+
+ FORALLfacet_(facetlist) {
+ if (facet->good)
+ numgood++;
+ }
+ if (qh->GOODvertex>0 && !qh->MERGING) {
+ FORALLfacet_(facetlist) {
+ if (!qh_isvertex(qh->GOODvertexp, facet->vertices)) {
+ facet->good= False;
+ numgood--;
+ }
+ }
+ }
+ if (qh->GOODpoint && numgood) {
+ FORALLfacet_(facetlist) {
+ if (facet->good && facet->normal) {
+ zinc_(Zdistgood);
+ qh_distplane(qh, qh->GOODpointp, facet, &dist);
+ if ((qh->GOODpoint > 0) ^ (dist > 0.0)) {
+ facet->good= False;
+ numgood--;
+ }
+ }
+ }
+ }
+ if (qh->GOODthreshold && (numgood || goodhorizon || qh->GOODclosest)) {
+ FORALLfacet_(facetlist) {
+ if (facet->good && facet->normal) {
+ if (!qh_inthresholds(qh, facet->normal, &angle)) {
+ facet->good= False;
+ numgood--;
+ if (angle < bestangle) {
+ bestangle= angle;
+ bestfacet= facet;
+ }
+ }
+ }
+ }
+ if (!numgood && (!goodhorizon || qh->GOODclosest)) {
+ if (qh->GOODclosest) {
+ if (qh->GOODclosest->visible)
+ qh->GOODclosest= NULL;
+ else {
+ qh_inthresholds(qh, qh->GOODclosest->normal, &angle);
+ if (angle < bestangle)
+ bestfacet= qh->GOODclosest;
+ }
+ }
+ if (bestfacet && bestfacet != qh->GOODclosest) {
+ if (qh->GOODclosest)
+ qh->GOODclosest->good= False;
+ qh->GOODclosest= bestfacet;
+ bestfacet->good= True;
+ numgood++;
+ trace2((qh, qh->ferr, 2044, "qh_findgood: f%d is closest(%2.2g) to thresholds\n",
+ bestfacet->id, bestangle));
+ return numgood;
+ }
+ }else if (qh->GOODclosest) { /* numgood > 0 */
+ qh->GOODclosest->good= False;
+ qh->GOODclosest= NULL;
+ }
+ }
+ zadd_(Zgoodfacet, numgood);
+ trace2((qh, qh->ferr, 2045, "qh_findgood: found %d good facets with %d good horizon\n",
+ numgood, goodhorizon));
+ if (!numgood && qh->GOODvertex>0 && !qh->MERGING)
+ return goodhorizon;
+ return numgood;
+} /* findgood */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="findgood_all">-</a>
+
+ qh_findgood_all(qh, facetlist )
+ apply other constraints for good facets (used by qh.PRINTgood)
+ if qh.GOODvertex
+ facet includes (>0) or doesn't include (<0) point as vertex
+ if last good facet and ONLYgood, prints warning and continues
+ if qh.SPLITthresholds
+ facet->normal matches threshold, or if none, the closest one
+ calls qh_findgood
+ nop if good not used
+
+ returns:
+ clears facet->good if not good
+ sets qh.num_good
+
+ notes:
+ this is like qh_findgood but more restrictive
+
+ design:
+ uses qh_findgood to mark good facets
+ marks facets for qh.GOODvertex
+ marks facets for qh.SPLITthreholds
+*/
+void qh_findgood_all(qhT *qh, facetT *facetlist) {
+ facetT *facet, *bestfacet=NULL;
+ realT angle, bestangle= REALmax;
+ int numgood=0, startgood;
+
+ if (!qh->GOODvertex && !qh->GOODthreshold && !qh->GOODpoint
+ && !qh->SPLITthresholds)
+ return;
+ if (!qh->ONLYgood)
+ qh_findgood(qh, qh->facet_list, 0);
+ FORALLfacet_(facetlist) {
+ if (facet->good)
+ numgood++;
+ }
+ if (qh->GOODvertex <0 || (qh->GOODvertex > 0 && qh->MERGING)) {
+ FORALLfacet_(facetlist) {
+ if (facet->good && ((qh->GOODvertex > 0) ^ !!qh_isvertex(qh->GOODvertexp, facet->vertices))) {
+ if (!--numgood) {
+ if (qh->ONLYgood) {
+ qh_fprintf(qh, qh->ferr, 7064, "qhull warning: good vertex p%d does not match last good facet f%d. Ignored.\n",
+ qh_pointid(qh, qh->GOODvertexp), facet->id);
+ return;
+ }else if (qh->GOODvertex > 0)
+ qh_fprintf(qh, qh->ferr, 7065, "qhull warning: point p%d is not a vertex('QV%d').\n",
+ qh->GOODvertex-1, qh->GOODvertex-1);
+ else
+ qh_fprintf(qh, qh->ferr, 7066, "qhull warning: point p%d is a vertex for every facet('QV-%d').\n",
+ -qh->GOODvertex - 1, -qh->GOODvertex - 1);
+ }
+ facet->good= False;
+ }
+ }
+ }
+ startgood= numgood;
+ if (qh->SPLITthresholds) {
+ FORALLfacet_(facetlist) {
+ if (facet->good) {
+ if (!qh_inthresholds(qh, facet->normal, &angle)) {
+ facet->good= False;
+ numgood--;
+ if (angle < bestangle) {
+ bestangle= angle;
+ bestfacet= facet;
+ }
+ }
+ }
+ }
+ if (!numgood && bestfacet) {
+ bestfacet->good= True;
+ numgood++;
+ trace0((qh, qh->ferr, 23, "qh_findgood_all: f%d is closest(%2.2g) to thresholds\n",
+ bestfacet->id, bestangle));
+ return;
+ }
+ }
+ qh->num_good= numgood;
+ trace0((qh, qh->ferr, 24, "qh_findgood_all: %d good facets remain out of %d facets\n",
+ numgood, startgood));
+} /* findgood_all */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="furthestnext">-</a>
+
+ qh_furthestnext()
+ set qh.facet_next to facet with furthest of all furthest points
+ searches all facets on qh.facet_list
+
+ notes:
+ this may help avoid precision problems
+*/
+void qh_furthestnext(qhT *qh /* qh->facet_list */) {
+ facetT *facet, *bestfacet= NULL;
+ realT dist, bestdist= -REALmax;
+
+ FORALLfacets {
+ if (facet->outsideset) {
+#if qh_COMPUTEfurthest
+ pointT *furthest;
+ furthest= (pointT*)qh_setlast(facet->outsideset);
+ zinc_(Zcomputefurthest);
+ qh_distplane(qh, furthest, facet, &dist);
+#else
+ dist= facet->furthestdist;
+#endif
+ if (dist > bestdist) {
+ bestfacet= facet;
+ bestdist= dist;
+ }
+ }
+ }
+ if (bestfacet) {
+ qh_removefacet(qh, bestfacet);
+ qh_prependfacet(qh, bestfacet, &qh->facet_next);
+ trace1((qh, qh->ferr, 1029, "qh_furthestnext: made f%d next facet(dist %.2g)\n",
+ bestfacet->id, bestdist));
+ }
+} /* furthestnext */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="furthestout">-</a>
+
+ qh_furthestout(qh, facet )
+ make furthest outside point the last point of outsideset
+
+ returns:
+ updates facet->outsideset
+ clears facet->notfurthest
+ sets facet->furthestdist
+
+ design:
+ determine best point of outsideset
+ make it the last point of outsideset
+*/
+void qh_furthestout(qhT *qh, facetT *facet) {
+ pointT *point, **pointp, *bestpoint= NULL;
+ realT dist, bestdist= -REALmax;
+
+ FOREACHpoint_(facet->outsideset) {
+ qh_distplane(qh, point, facet, &dist);
+ zinc_(Zcomputefurthest);
+ if (dist > bestdist) {
+ bestpoint= point;
+ bestdist= dist;
+ }
+ }
+ if (bestpoint) {
+ qh_setdel(facet->outsideset, point);
+ qh_setappend(qh, &facet->outsideset, point);
+#if !qh_COMPUTEfurthest
+ facet->furthestdist= bestdist;
+#endif
+ }
+ facet->notfurthest= False;
+ trace3((qh, qh->ferr, 3017, "qh_furthestout: p%d is furthest outside point of f%d\n",
+ qh_pointid(qh, point), facet->id));
+} /* furthestout */
+
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="infiniteloop">-</a>
+
+ qh_infiniteloop(qh, facet )
+ report infinite loop error due to facet
+*/
+void qh_infiniteloop(qhT *qh, facetT *facet) {
+
+ qh_fprintf(qh, qh->ferr, 6149, "qhull internal error (qh_infiniteloop): potential infinite loop detected\n");
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+} /* qh_infiniteloop */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="initbuild">-</a>
+
+ qh_initbuild()
+ initialize hull and outside sets with point array
+ qh.FIRSTpoint/qh.NUMpoints is point array
+ if qh.GOODpoint
+ adds qh.GOODpoint to initial hull
+
+ returns:
+ qh_facetlist with initial hull
+ points partioned into outside sets, coplanar sets, or inside
+ initializes qh.GOODpointp, qh.GOODvertexp,
+
+ design:
+ initialize global variables used during qh_buildhull
+ determine precision constants and points with max/min coordinate values
+ if qh.SCALElast, scale last coordinate(for 'd')
+ build initial simplex
+ partition input points into facets of initial simplex
+ set up lists
+ if qh.ONLYgood
+ check consistency
+ add qh.GOODvertex if defined
+*/
+void qh_initbuild(qhT *qh) {
+ setT *maxpoints, *vertices;
+ facetT *facet;
+ int i, numpart;
+ realT dist;
+ boolT isoutside;
+
+ qh->furthest_id= qh_IDunknown;
+ qh->lastreport= 0;
+ qh->facet_id= qh->vertex_id= qh->ridge_id= 0;
+ qh->visit_id= qh->vertex_visit= 0;
+ qh->maxoutdone= False;
+
+ if (qh->GOODpoint > 0)
+ qh->GOODpointp= qh_point(qh, qh->GOODpoint-1);
+ else if (qh->GOODpoint < 0)
+ qh->GOODpointp= qh_point(qh, -qh->GOODpoint-1);
+ if (qh->GOODvertex > 0)
+ qh->GOODvertexp= qh_point(qh, qh->GOODvertex-1);
+ else if (qh->GOODvertex < 0)
+ qh->GOODvertexp= qh_point(qh, -qh->GOODvertex-1);
+ if ((qh->GOODpoint
+ && (qh->GOODpointp < qh->first_point /* also catches !GOODpointp */
+ || qh->GOODpointp > qh_point(qh, qh->num_points-1)))
+ || (qh->GOODvertex
+ && (qh->GOODvertexp < qh->first_point /* also catches !GOODvertexp */
+ || qh->GOODvertexp > qh_point(qh, qh->num_points-1)))) {
+ qh_fprintf(qh, qh->ferr, 6150, "qhull input error: either QGn or QVn point is > p%d\n",
+ qh->num_points-1);
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ maxpoints= qh_maxmin(qh, qh->first_point, qh->num_points, qh->hull_dim);
+ if (qh->SCALElast)
+ qh_scalelast(qh, qh->first_point, qh->num_points, qh->hull_dim,
+ qh->MINlastcoord, qh->MAXlastcoord, qh->MAXwidth);
+ qh_detroundoff(qh);
+ if (qh->DELAUNAY && qh->upper_threshold[qh->hull_dim-1] > REALmax/2
+ && qh->lower_threshold[qh->hull_dim-1] < -REALmax/2) {
+ for (i=qh_PRINTEND; i--; ) {
+ if (qh->PRINTout[i] == qh_PRINTgeom && qh->DROPdim < 0
+ && !qh->GOODthreshold && !qh->SPLITthresholds)
+ break; /* in this case, don't set upper_threshold */
+ }
+ if (i < 0) {
+ if (qh->UPPERdelaunay) { /* matches qh.upperdelaunay in qh_setfacetplane */
+ qh->lower_threshold[qh->hull_dim-1]= qh->ANGLEround * qh_ZEROdelaunay;
+ qh->GOODthreshold= True;
+ }else {
+ qh->upper_threshold[qh->hull_dim-1]= -qh->ANGLEround * qh_ZEROdelaunay;
+ if (!qh->GOODthreshold)
+ qh->SPLITthresholds= True; /* build upper-convex hull even if Qg */
+ /* qh_initqhull_globals errors if Qg without Pdk/etc. */
+ }
+ }
+ }
+ vertices= qh_initialvertices(qh, qh->hull_dim, maxpoints, qh->first_point, qh->num_points);
+ qh_initialhull(qh, vertices); /* initial qh->facet_list */
+ qh_partitionall(qh, vertices, qh->first_point, qh->num_points);
+ if (qh->PRINToptions1st || qh->TRACElevel || qh->IStracing) {
+ if (qh->TRACElevel || qh->IStracing)
+ qh_fprintf(qh, qh->ferr, 8103, "\nTrace level %d for %s | %s\n",
+ qh->IStracing ? qh->IStracing : qh->TRACElevel, qh->rbox_command, qh->qhull_command);
+ qh_fprintf(qh, qh->ferr, 8104, "Options selected for Qhull %s:\n%s\n", qh_version, qh->qhull_options);
+ }
+ qh_resetlists(qh, False, qh_RESETvisible /*qh.visible_list newvertex_list newfacet_list */);
+ qh->facet_next= qh->facet_list;
+ qh_furthestnext(qh /* qh->facet_list */);
+ if (qh->PREmerge) {
+ qh->cos_max= qh->premerge_cos;
+ qh->centrum_radius= qh->premerge_centrum;
+ }
+ if (qh->ONLYgood) {
+ if (qh->GOODvertex > 0 && qh->MERGING) {
+ qh_fprintf(qh, qh->ferr, 6151, "qhull input error: 'Qg QVn' (only good vertex) does not work with merging.\nUse 'QJ' to joggle the input or 'Q0' to turn off merging.\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (!(qh->GOODthreshold || qh->GOODpoint
+ || (!qh->MERGEexact && !qh->PREmerge && qh->GOODvertexp))) {
+ qh_fprintf(qh, qh->ferr, 6152, "qhull input error: 'Qg' (ONLYgood) needs a good threshold('Pd0D0'), a\n\
+good point(QGn or QG-n), or a good vertex with 'QJ' or 'Q0' (QVn).\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (qh->GOODvertex > 0 && !qh->MERGING /* matches qh_partitionall */
+ && !qh_isvertex(qh->GOODvertexp, vertices)) {
+ facet= qh_findbestnew(qh, qh->GOODvertexp, qh->facet_list,
+ &dist, !qh_ALL, &isoutside, &numpart);
+ zadd_(Zdistgood, numpart);
+ if (!isoutside) {
+ qh_fprintf(qh, qh->ferr, 6153, "qhull input error: point for QV%d is inside initial simplex. It can not be made a vertex.\n",
+ qh_pointid(qh, qh->GOODvertexp));
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ if (!qh_addpoint(qh, qh->GOODvertexp, facet, False)) {
+ qh_settempfree(qh, &vertices);
+ qh_settempfree(qh, &maxpoints);
+ return;
+ }
+ }
+ qh_findgood(qh, qh->facet_list, 0);
+ }
+ qh_settempfree(qh, &vertices);
+ qh_settempfree(qh, &maxpoints);
+ trace1((qh, qh->ferr, 1030, "qh_initbuild: initial hull created and points partitioned\n"));
+} /* initbuild */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="initialhull">-</a>
+
+ qh_initialhull(qh, vertices )
+ constructs the initial hull as a DIM3 simplex of vertices
+
+ design:
+ creates a simplex (initializes lists)
+ determines orientation of simplex
+ sets hyperplanes for facets
+ doubles checks orientation (in case of axis-parallel facets with Gaussian elimination)
+ checks for flipped facets and qh.NARROWhull
+ checks the result
+*/
+void qh_initialhull(qhT *qh, setT *vertices) {
+ facetT *facet, *firstfacet, *neighbor, **neighborp;
+ realT dist, angle, minangle= REALmax;
+#ifndef qh_NOtrace
+ int k;
+#endif
+
+ qh_createsimplex(qh, vertices); /* qh->facet_list */
+ qh_resetlists(qh, False, qh_RESETvisible);
+ qh->facet_next= qh->facet_list; /* advance facet when processed */
+ qh->interior_point= qh_getcenter(qh, vertices);
+ firstfacet= qh->facet_list;
+ qh_setfacetplane(qh, firstfacet);
+ zinc_(Znumvisibility); /* needs to be in printsummary */
+ qh_distplane(qh, qh->interior_point, firstfacet, &dist);
+ if (dist > 0) {
+ FORALLfacets
+ facet->toporient ^= (unsigned char)True;
+ }
+ FORALLfacets
+ qh_setfacetplane(qh, facet);
+ FORALLfacets {
+ if (!qh_checkflipped(qh, facet, NULL, qh_ALL)) {/* due to axis-parallel facet */
+ trace1((qh, qh->ferr, 1031, "qh_initialhull: initial orientation incorrect. Correct all facets\n"));
+ facet->flipped= False;
+ FORALLfacets {
+ facet->toporient ^= (unsigned char)True;
+ qh_orientoutside(qh, facet);
+ }
+ break;
+ }
+ }
+ FORALLfacets {
+ if (!qh_checkflipped(qh, facet, NULL, !qh_ALL)) { /* can happen with 'R0.1' */
+ if (qh->DELAUNAY && ! qh->ATinfinity) {
+ if (qh->UPPERdelaunay)
+ qh_fprintf(qh, qh->ferr, 6240, "Qhull precision error: Initial simplex is cocircular or cospherical. Option 'Qs' searches all points. Can not compute the upper Delaunay triangulation or upper Voronoi diagram of cocircular/cospherical points.\n");
+ else
+ qh_fprintf(qh, qh->ferr, 6239, "Qhull precision error: Initial simplex is cocircular or cospherical. Use option 'Qz' for the Delaunay triangulation or Voronoi diagram of cocircular/cospherical points. Option 'Qz' adds a point \"at infinity\". Use option 'Qs' to search all points for the initial simplex.\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ qh_precision(qh, "initial simplex is flat");
+ qh_fprintf(qh, qh->ferr, 6154, "Qhull precision error: Initial simplex is flat (facet %d is coplanar with the interior point)\n",
+ facet->id);
+ qh_errexit(qh, qh_ERRsingular, NULL, NULL); /* calls qh_printhelp_singular */
+ }
+ FOREACHneighbor_(facet) {
+ angle= qh_getangle(qh, facet->normal, neighbor->normal);
+ minimize_( minangle, angle);
+ }
+ }
+ if (minangle < qh_MAXnarrow && !qh->NOnarrow) {
+ realT diff= 1.0 + minangle;
+
+ qh->NARROWhull= True;
+ qh_option(qh, "_narrow-hull", NULL, &diff);
+ if (minangle < qh_WARNnarrow && !qh->RERUN && qh->PRINTprecision)
+ qh_printhelp_narrowhull(qh, qh->ferr, minangle);
+ }
+ zzval_(Zprocessed)= qh->hull_dim+1;
+ qh_checkpolygon(qh, qh->facet_list);
+ qh_checkconvex(qh, qh->facet_list, qh_DATAfault);
+#ifndef qh_NOtrace
+ if (qh->IStracing >= 1) {
+ qh_fprintf(qh, qh->ferr, 8105, "qh_initialhull: simplex constructed, interior point:");
+ for (k=0; k < qh->hull_dim; k++)
+ qh_fprintf(qh, qh->ferr, 8106, " %6.4g", qh->interior_point[k]);
+ qh_fprintf(qh, qh->ferr, 8107, "\n");
+ }
+#endif
+} /* initialhull */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="initialvertices">-</a>
+
+ qh_initialvertices(qh, dim, maxpoints, points, numpoints )
+ determines a non-singular set of initial vertices
+ maxpoints may include duplicate points
+
+ returns:
+ temporary set of dim+1 vertices in descending order by vertex id
+ if qh.RANDOMoutside && !qh.ALLpoints
+ picks random points
+ if dim >= qh_INITIALmax,
+ uses min/max x and max points with non-zero determinants
+
+ notes:
+ unless qh.ALLpoints,
+ uses maxpoints as long as determinate is non-zero
+*/
+setT *qh_initialvertices(qhT *qh, int dim, setT *maxpoints, pointT *points, int numpoints) {
+ pointT *point, **pointp;
+ setT *vertices, *simplex, *tested;
+ realT randr;
+ int idx, point_i, point_n, k;
+ boolT nearzero= False;
+
+ vertices= qh_settemp(qh, dim + 1);
+ simplex= qh_settemp(qh, dim+1);
+ if (qh->ALLpoints)
+ qh_maxsimplex(qh, dim, NULL, points, numpoints, &simplex);
+ else if (qh->RANDOMoutside) {
+ while (qh_setsize(qh, simplex) != dim+1) {
+ randr= qh_RANDOMint;
+ randr= randr/(qh_RANDOMmax+1);
+ idx= (int)floor(qh->num_points * randr);
+ while (qh_setin(simplex, qh_point(qh, idx))) {
+ idx++; /* in case qh_RANDOMint always returns the same value */
+ idx= idx < qh->num_points ? idx : 0;
+ }
+ qh_setappend(qh, &simplex, qh_point(qh, idx));
+ }
+ }else if (qh->hull_dim >= qh_INITIALmax) {
+ tested= qh_settemp(qh, dim+1);
+ qh_setappend(qh, &simplex, SETfirst_(maxpoints)); /* max and min X coord */
+ qh_setappend(qh, &simplex, SETsecond_(maxpoints));
+ qh_maxsimplex(qh, fmin_(qh_INITIALsearch, dim), maxpoints, points, numpoints, &simplex);
+ k= qh_setsize(qh, simplex);
+ FOREACHpoint_i_(qh, maxpoints) {
+ if (point_i & 0x1) { /* first pick up max. coord. points */
+ if (!qh_setin(simplex, point) && !qh_setin(tested, point)){
+ qh_detsimplex(qh, point, simplex, k, &nearzero);
+ if (nearzero)
+ qh_setappend(qh, &tested, point);
+ else {
+ qh_setappend(qh, &simplex, point);
+ if (++k == dim) /* use search for last point */
+ break;
+ }
+ }
+ }
+ }
+ while (k != dim && (point= (pointT*)qh_setdellast(maxpoints))) {
+ if (!qh_setin(simplex, point) && !qh_setin(tested, point)){
+ qh_detsimplex(qh, point, simplex, k, &nearzero);
+ if (nearzero)
+ qh_setappend(qh, &tested, point);
+ else {
+ qh_setappend(qh, &simplex, point);
+ k++;
+ }
+ }
+ }
+ idx= 0;
+ while (k != dim && (point= qh_point(qh, idx++))) {
+ if (!qh_setin(simplex, point) && !qh_setin(tested, point)){
+ qh_detsimplex(qh, point, simplex, k, &nearzero);
+ if (!nearzero){
+ qh_setappend(qh, &simplex, point);
+ k++;
+ }
+ }
+ }
+ qh_settempfree(qh, &tested);
+ qh_maxsimplex(qh, dim, maxpoints, points, numpoints, &simplex);
+ }else
+ qh_maxsimplex(qh, dim, maxpoints, points, numpoints, &simplex);
+ FOREACHpoint_(simplex)
+ qh_setaddnth(qh, &vertices, 0, qh_newvertex(qh, point)); /* descending order */
+ qh_settempfree(qh, &simplex);
+ return vertices;
+} /* initialvertices */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="isvertex">-</a>
+
+ qh_isvertex( point, vertices )
+ returns vertex if point is in vertex set, else returns NULL
+
+ notes:
+ for qh.GOODvertex
+*/
+vertexT *qh_isvertex(pointT *point, setT *vertices) {
+ vertexT *vertex, **vertexp;
+
+ FOREACHvertex_(vertices) {
+ if (vertex->point == point)
+ return vertex;
+ }
+ return NULL;
+} /* isvertex */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="makenewfacets">-</a>
+
+ qh_makenewfacets(qh, point )
+ make new facets from point and qh.visible_list
+
+ returns:
+ qh.newfacet_list= list of new facets with hyperplanes and ->newfacet
+ qh.newvertex_list= list of vertices in new facets with ->newlist set
+
+ if (qh.ONLYgood)
+ newfacets reference horizon facets, but not vice versa
+ ridges reference non-simplicial horizon ridges, but not vice versa
+ does not change existing facets
+ else
+ sets qh.NEWfacets
+ new facets attached to horizon facets and ridges
+ for visible facets,
+ visible->r.replace is corresponding new facet
+
+ see also:
+ qh_makenewplanes() -- make hyperplanes for facets
+ qh_attachnewfacets() -- attachnewfacets if not done here(qh->ONLYgood)
+ qh_matchnewfacets() -- match up neighbors
+ qh_updatevertices() -- update vertex neighbors and delvertices
+ qh_deletevisible() -- delete visible facets
+ qh_checkpolygon() --check the result
+ qh_triangulate() -- triangulate a non-simplicial facet
+
+ design:
+ for each visible facet
+ make new facets to its horizon facets
+ update its f.replace
+ clear its neighbor set
+*/
+vertexT *qh_makenewfacets(qhT *qh, pointT *point /*visible_list*/) {
+ facetT *visible, *newfacet= NULL, *newfacet2= NULL, *neighbor, **neighborp;
+ vertexT *apex;
+ int numnew=0;
+
+ qh->newfacet_list= qh->facet_tail;
+ qh->newvertex_list= qh->vertex_tail;
+ apex= qh_newvertex(qh, point);
+ qh_appendvertex(qh, apex);
+ qh->visit_id++;
+ if (!qh->ONLYgood)
+ qh->NEWfacets= True;
+ FORALLvisible_facets {
+ FOREACHneighbor_(visible)
+ neighbor->seen= False;
+ if (visible->ridges) {
+ visible->visitid= qh->visit_id;
+ newfacet2= qh_makenew_nonsimplicial(qh, visible, apex, &numnew);
+ }
+ if (visible->simplicial)
+ newfacet= qh_makenew_simplicial(qh, visible, apex, &numnew);
+ if (!qh->ONLYgood) {
+ if (newfacet2) /* newfacet is null if all ridges defined */
+ newfacet= newfacet2;
+ if (newfacet)
+ visible->f.replace= newfacet;
+ else
+ zinc_(Zinsidevisible);
+ SETfirst_(visible->neighbors)= NULL;
+ }
+ }
+ trace1((qh, qh->ferr, 1032, "qh_makenewfacets: created %d new facets from point p%d to horizon\n",
+ numnew, qh_pointid(qh, point)));
+ if (qh->IStracing >= 4)
+ qh_printfacetlist(qh, qh->newfacet_list, NULL, qh_ALL);
+ return apex;
+} /* makenewfacets */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="matchduplicates">-</a>
+
+ qh_matchduplicates(qh, atfacet, atskip, hashsize, hashcount )
+ match duplicate ridges in qh.hash_table for atfacet/atskip
+ duplicates marked with ->dupridge and qh_DUPLICATEridge
+
+ returns:
+ picks match with worst merge (min distance apart)
+ updates hashcount
+
+ see also:
+ qh_matchneighbor
+
+ notes:
+
+ design:
+ compute hash value for atfacet and atskip
+ repeat twice -- once to make best matches, once to match the rest
+ for each possible facet in qh.hash_table
+ if it is a matching facet and pass 2
+ make match
+ unless tricoplanar, mark match for merging (qh_MERGEridge)
+ [e.g., tricoplanar RBOX s 1000 t993602376 | QHULL C-1e-3 d Qbb FA Qt]
+ if it is a matching facet and pass 1
+ test if this is a better match
+ if pass 1,
+ make best match (it will not be merged)
+*/
+#ifndef qh_NOmerge
+void qh_matchduplicates(qhT *qh, facetT *atfacet, int atskip, int hashsize, int *hashcount) {
+ boolT same, ismatch;
+ int hash, scan;
+ facetT *facet, *newfacet, *maxmatch= NULL, *maxmatch2= NULL, *nextfacet;
+ int skip, newskip, nextskip= 0, maxskip= 0, maxskip2= 0, makematch;
+ realT maxdist= -REALmax, mindist, dist2, low, high;
+
+ hash= qh_gethash(qh, hashsize, atfacet->vertices, qh->hull_dim, 1,
+ SETelem_(atfacet->vertices, atskip));
+ trace2((qh, qh->ferr, 2046, "qh_matchduplicates: find duplicate matches for f%d skip %d hash %d hashcount %d\n",
+ atfacet->id, atskip, hash, *hashcount));
+ for (makematch= 0; makematch < 2; makematch++) {
+ qh->visit_id++;
+ for (newfacet= atfacet, newskip= atskip; newfacet; newfacet= nextfacet, newskip= nextskip) {
+ zinc_(Zhashlookup);
+ nextfacet= NULL;
+ newfacet->visitid= qh->visit_id;
+ for (scan= hash; (facet= SETelemt_(qh->hash_table, scan, facetT));
+ scan= (++scan >= hashsize ? 0 : scan)) {
+ if (!facet->dupridge || facet->visitid == qh->visit_id)
+ continue;
+ zinc_(Zhashtests);
+ if (qh_matchvertices(qh, 1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) {
+ ismatch= (same == (boolT)(newfacet->toporient ^ facet->toporient));
+ if (SETelemt_(facet->neighbors, skip, facetT) != qh_DUPLICATEridge) {
+ if (!makematch) {
+ qh_fprintf(qh, qh->ferr, 6155, "qhull internal error (qh_matchduplicates): missing dupridge at f%d skip %d for new f%d skip %d hash %d\n",
+ facet->id, skip, newfacet->id, newskip, hash);
+ qh_errexit2(qh, qh_ERRqhull, facet, newfacet);
+ }
+ }else if (ismatch && makematch) {
+ if (SETelemt_(newfacet->neighbors, newskip, facetT) == qh_DUPLICATEridge) {
+ SETelem_(facet->neighbors, skip)= newfacet;
+ if (newfacet->tricoplanar)
+ SETelem_(newfacet->neighbors, newskip)= facet;
+ else
+ SETelem_(newfacet->neighbors, newskip)= qh_MERGEridge;
+ *hashcount -= 2; /* removed two unmatched facets */
+ trace4((qh, qh->ferr, 4059, "qh_matchduplicates: duplicate f%d skip %d matched with new f%d skip %d merge\n",
+ facet->id, skip, newfacet->id, newskip));
+ }
+ }else if (ismatch) {
+ mindist= qh_getdistance(qh, facet, newfacet, &low, &high);
+ dist2= qh_getdistance(qh, newfacet, facet, &low, &high);
+ minimize_(mindist, dist2);
+ if (mindist > maxdist) {
+ maxdist= mindist;
+ maxmatch= facet;
+ maxskip= skip;
+ maxmatch2= newfacet;
+ maxskip2= newskip;
+ }
+ trace3((qh, qh->ferr, 3018, "qh_matchduplicates: duplicate f%d skip %d new f%d skip %d at dist %2.2g, max is now f%d f%d\n",
+ facet->id, skip, newfacet->id, newskip, mindist,
+ maxmatch->id, maxmatch2->id));
+ }else { /* !ismatch */
+ nextfacet= facet;
+ nextskip= skip;
+ }
+ }
+ if (makematch && !facet
+ && SETelemt_(facet->neighbors, skip, facetT) == qh_DUPLICATEridge) {
+ qh_fprintf(qh, qh->ferr, 6156, "qhull internal error (qh_matchduplicates): no MERGEridge match for duplicate f%d skip %d at hash %d\n",
+ newfacet->id, newskip, hash);
+ qh_errexit(qh, qh_ERRqhull, newfacet, NULL);
+ }
+ }
+ } /* end of for each new facet at hash */
+ if (!makematch) {
+ if (!maxmatch) {
+ qh_fprintf(qh, qh->ferr, 6157, "qhull internal error (qh_matchduplicates): no maximum match at duplicate f%d skip %d at hash %d\n",
+ atfacet->id, atskip, hash);
+ qh_errexit(qh, qh_ERRqhull, atfacet, NULL);
+ }
+ SETelem_(maxmatch->neighbors, maxskip)= maxmatch2; /* maxmatch!=0 by QH6157 */
+ SETelem_(maxmatch2->neighbors, maxskip2)= maxmatch;
+ *hashcount -= 2; /* removed two unmatched facets */
+ zzinc_(Zmultiridge);
+ trace0((qh, qh->ferr, 25, "qh_matchduplicates: duplicate f%d skip %d matched with new f%d skip %d keep\n",
+ maxmatch->id, maxskip, maxmatch2->id, maxskip2));
+ qh_precision(qh, "ridge with multiple neighbors");
+ if (qh->IStracing >= 4)
+ qh_errprint(qh, "DUPLICATED/MATCH", maxmatch, maxmatch2, NULL, NULL);
+ }
+ }
+} /* matchduplicates */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="nearcoplanar">-</a>
+
+ qh_nearcoplanar()
+ for all facets, remove near-inside points from facet->coplanarset</li>
+ coplanar points defined by innerplane from qh_outerinner()
+
+ returns:
+ if qh->KEEPcoplanar && !qh->KEEPinside
+ facet->coplanarset only contains coplanar points
+ if qh.JOGGLEmax
+ drops inner plane by another qh.JOGGLEmax diagonal since a
+ vertex could shift out while a coplanar point shifts in
+
+ notes:
+ used for qh.PREmerge and qh.JOGGLEmax
+ must agree with computation of qh.NEARcoplanar in qh_detroundoff(qh)
+ design:
+ if not keeping coplanar or inside points
+ free all coplanar sets
+ else if not keeping both coplanar and inside points
+ remove !coplanar or !inside points from coplanar sets
+*/
+void qh_nearcoplanar(qhT *qh /* qh.facet_list */) {
+ facetT *facet;
+ pointT *point, **pointp;
+ int numpart;
+ realT dist, innerplane;
+
+ if (!qh->KEEPcoplanar && !qh->KEEPinside) {
+ FORALLfacets {
+ if (facet->coplanarset)
+ qh_setfree(qh, &facet->coplanarset);
+ }
+ }else if (!qh->KEEPcoplanar || !qh->KEEPinside) {
+ qh_outerinner(qh, NULL, NULL, &innerplane);
+ if (qh->JOGGLEmax < REALmax/2)
+ innerplane -= qh->JOGGLEmax * sqrt((realT)qh->hull_dim);
+ numpart= 0;
+ FORALLfacets {
+ if (facet->coplanarset) {
+ FOREACHpoint_(facet->coplanarset) {
+ numpart++;
+ qh_distplane(qh, point, facet, &dist);
+ if (dist < innerplane) {
+ if (!qh->KEEPinside)
+ SETref_(point)= NULL;
+ }else if (!qh->KEEPcoplanar)
+ SETref_(point)= NULL;
+ }
+ qh_setcompact(qh, facet->coplanarset);
+ }
+ }
+ zzadd_(Zcheckpart, numpart);
+ }
+} /* nearcoplanar */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="nearvertex">-</a>
+
+ qh_nearvertex(qh, facet, point, bestdist )
+ return nearest vertex in facet to point
+
+ returns:
+ vertex and its distance
+
+ notes:
+ if qh.DELAUNAY
+ distance is measured in the input set
+ searches neighboring tricoplanar facets (requires vertexneighbors)
+ Slow implementation. Recomputes vertex set for each point.
+ The vertex set could be stored in the qh.keepcentrum facet.
+*/
+vertexT *qh_nearvertex(qhT *qh, facetT *facet, pointT *point, realT *bestdistp) {
+ realT bestdist= REALmax, dist;
+ vertexT *bestvertex= NULL, *vertex, **vertexp, *apex;
+ coordT *center;
+ facetT *neighbor, **neighborp;
+ setT *vertices;
+ int dim= qh->hull_dim;
+
+ if (qh->DELAUNAY)
+ dim--;
+ if (facet->tricoplanar) {
+ if (!qh->VERTEXneighbors || !facet->center) {
+ qh_fprintf(qh, qh->ferr, 6158, "qhull internal error (qh_nearvertex): qh.VERTEXneighbors and facet->center required for tricoplanar facets\n");
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ vertices= qh_settemp(qh, qh->TEMPsize);
+ apex= SETfirstt_(facet->vertices, vertexT);
+ center= facet->center;
+ FOREACHneighbor_(apex) {
+ if (neighbor->center == center) {
+ FOREACHvertex_(neighbor->vertices)
+ qh_setappend(qh, &vertices, vertex);
+ }
+ }
+ }else
+ vertices= facet->vertices;
+ FOREACHvertex_(vertices) {
+ dist= qh_pointdist(vertex->point, point, -dim);
+ if (dist < bestdist) {
+ bestdist= dist;
+ bestvertex= vertex;
+ }
+ }
+ if (facet->tricoplanar)
+ qh_settempfree(qh, &vertices);
+ *bestdistp= sqrt(bestdist);
+ if (!bestvertex) {
+ qh_fprintf(qh, qh->ferr, 6261, "qhull internal error (qh_nearvertex): did not find bestvertex for f%d p%d\n", facet->id, qh_pointid(qh, point));
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ trace3((qh, qh->ferr, 3019, "qh_nearvertex: v%d dist %2.2g for f%d p%d\n",
+ bestvertex->id, *bestdistp, facet->id, qh_pointid(qh, point))); /* bestvertex!=0 by QH2161 */
+ return bestvertex;
+} /* nearvertex */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="newhashtable">-</a>
+
+ qh_newhashtable(qh, newsize )
+ returns size of qh.hash_table of at least newsize slots
+
+ notes:
+ assumes qh.hash_table is NULL
+ qh_HASHfactor determines the number of extra slots
+ size is not divisible by 2, 3, or 5
+*/
+int qh_newhashtable(qhT *qh, int newsize) {
+ int size;
+
+ size= ((newsize+1)*qh_HASHfactor) | 0x1; /* odd number */
+ while (True) {
+ if (newsize<0 || size<0) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6236, "qhull error (qh_newhashtable): negative request (%d) or size (%d). Did int overflow due to high-D?\n", newsize, size); /* WARN64 */
+ qh_errexit(qh, qhmem_ERRmem, NULL, NULL);
+ }
+ if ((size%3) && (size%5))
+ break;
+ size += 2;
+ /* loop terminates because there is an infinite number of primes */
+ }
+ qh->hash_table= qh_setnew(qh, size);
+ qh_setzero(qh, qh->hash_table, 0, size);
+ return size;
+} /* newhashtable */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="newvertex">-</a>
+
+ qh_newvertex(qh, point )
+ returns a new vertex for point
+*/
+vertexT *qh_newvertex(qhT *qh, pointT *point) {
+ vertexT *vertex;
+
+ zinc_(Ztotvertices);
+ vertex= (vertexT *)qh_memalloc(qh, (int)sizeof(vertexT));
+ memset((char *) vertex, (size_t)0, sizeof(vertexT));
+ if (qh->vertex_id == UINT_MAX) {
+ qh_memfree(qh, vertex, (int)sizeof(vertexT));
+ qh_fprintf(qh, qh->ferr, 6159, "qhull error: more than 2^32 vertices. vertexT.id field overflows. Vertices would not be sorted correctly.\n");
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ if (qh->vertex_id == qh->tracevertex_id)
+ qh->tracevertex= vertex;
+ vertex->id= qh->vertex_id++;
+ vertex->point= point;
+ trace4((qh, qh->ferr, 4060, "qh_newvertex: vertex p%d(v%d) created\n", qh_pointid(qh, vertex->point),
+ vertex->id));
+ return(vertex);
+} /* newvertex */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="nextridge3d">-</a>
+
+ qh_nextridge3d( atridge, facet, vertex )
+ return next ridge and vertex for a 3d facet
+ returns NULL on error
+ [for QhullFacet::nextRidge3d] Does not call qh_errexit nor access qhT.
+
+ notes:
+ in qh_ORIENTclock order
+ this is a O(n^2) implementation to trace all ridges
+ be sure to stop on any 2nd visit
+ same as QhullRidge::nextRidge3d
+ does not use qhT or qh_errexit [QhullFacet.cpp]
+
+ design:
+ for each ridge
+ exit if it is the ridge after atridge
+*/
+ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp) {
+ vertexT *atvertex, *vertex, *othervertex;
+ ridgeT *ridge, **ridgep;
+
+ if ((atridge->top == facet) ^ qh_ORIENTclock)
+ atvertex= SETsecondt_(atridge->vertices, vertexT);
+ else
+ atvertex= SETfirstt_(atridge->vertices, vertexT);
+ FOREACHridge_(facet->ridges) {
+ if (ridge == atridge)
+ continue;
+ if ((ridge->top == facet) ^ qh_ORIENTclock) {
+ othervertex= SETsecondt_(ridge->vertices, vertexT);
+ vertex= SETfirstt_(ridge->vertices, vertexT);
+ }else {
+ vertex= SETsecondt_(ridge->vertices, vertexT);
+ othervertex= SETfirstt_(ridge->vertices, vertexT);
+ }
+ if (vertex == atvertex) {
+ if (vertexp)
+ *vertexp= othervertex;
+ return ridge;
+ }
+ }
+ return NULL;
+} /* nextridge3d */
+#else /* qh_NOmerge */
+void qh_matchduplicates(qhT *qh, facetT *atfacet, int atskip, int hashsize, int *hashcount) {
+}
+ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp) {
+
+ return NULL;
+}
+#endif /* qh_NOmerge */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="outcoplanar">-</a>
+
+ qh_outcoplanar()
+ move points from all facets' outsidesets to their coplanarsets
+
+ notes:
+ for post-processing under qh.NARROWhull
+
+ design:
+ for each facet
+ for each outside point for facet
+ partition point into coplanar set
+*/
+void qh_outcoplanar(qhT *qh /* facet_list */) {
+ pointT *point, **pointp;
+ facetT *facet;
+ realT dist;
+
+ trace1((qh, qh->ferr, 1033, "qh_outcoplanar: move outsideset to coplanarset for qh->NARROWhull\n"));
+ FORALLfacets {
+ FOREACHpoint_(facet->outsideset) {
+ qh->num_outside--;
+ if (qh->KEEPcoplanar || qh->KEEPnearinside) {
+ qh_distplane(qh, point, facet, &dist);
+ zinc_(Zpartition);
+ qh_partitioncoplanar(qh, point, facet, &dist);
+ }
+ }
+ qh_setfree(qh, &facet->outsideset);
+ }
+} /* outcoplanar */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="point">-</a>
+
+ qh_point(qh, id )
+ return point for a point id, or NULL if unknown
+
+ alternative code:
+ return((pointT *)((unsigned long)qh.first_point
+ + (unsigned long)((id)*qh.normal_size)));
+*/
+pointT *qh_point(qhT *qh, int id) {
+
+ if (id < 0)
+ return NULL;
+ if (id < qh->num_points)
+ return qh->first_point + id * qh->hull_dim;
+ id -= qh->num_points;
+ if (id < qh_setsize(qh, qh->other_points))
+ return SETelemt_(qh->other_points, id, pointT);
+ return NULL;
+} /* point */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="point_add">-</a>
+
+ qh_point_add(qh, set, point, elem )
+ stores elem at set[point.id]
+
+ returns:
+ access function for qh_pointfacet and qh_pointvertex
+
+ notes:
+ checks point.id
+*/
+void qh_point_add(qhT *qh, setT *set, pointT *point, void *elem) {
+ int id, size;
+
+ SETreturnsize_(set, size);
+ if ((id= qh_pointid(qh, point)) < 0)
+ qh_fprintf(qh, qh->ferr, 7067, "qhull internal warning (point_add): unknown point %p id %d\n",
+ point, id);
+ else if (id >= size) {
+ qh_fprintf(qh, qh->ferr, 6160, "qhull internal errror(point_add): point p%d is out of bounds(%d)\n",
+ id, size);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }else
+ SETelem_(set, id)= elem;
+} /* point_add */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="pointfacet">-</a>
+
+ qh_pointfacet()
+ return temporary set of facet for each point
+ the set is indexed by point id
+
+ notes:
+ vertices assigned to one of the facets
+ coplanarset assigned to the facet
+ outside set assigned to the facet
+ NULL if no facet for point (inside)
+ includes qh.GOODpointp
+
+ access:
+ FOREACHfacet_i_(qh, facets) { ... }
+ SETelem_(facets, i)
+
+ design:
+ for each facet
+ add each vertex
+ add each coplanar point
+ add each outside point
+*/
+setT *qh_pointfacet(qhT *qh /*qh.facet_list*/) {
+ int numpoints= qh->num_points + qh_setsize(qh, qh->other_points);
+ setT *facets;
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+ pointT *point, **pointp;
+
+ facets= qh_settemp(qh, numpoints);
+ qh_setzero(qh, facets, 0, numpoints);
+ qh->vertex_visit++;
+ FORALLfacets {
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->visitid != qh->vertex_visit) {
+ vertex->visitid= qh->vertex_visit;
+ qh_point_add(qh, facets, vertex->point, facet);
+ }
+ }
+ FOREACHpoint_(facet->coplanarset)
+ qh_point_add(qh, facets, point, facet);
+ FOREACHpoint_(facet->outsideset)
+ qh_point_add(qh, facets, point, facet);
+ }
+ return facets;
+} /* pointfacet */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="pointvertex">-</a>
+
+ qh_pointvertex(qh, )
+ return temporary set of vertices indexed by point id
+ entry is NULL if no vertex for a point
+ this will include qh.GOODpointp
+
+ access:
+ FOREACHvertex_i_(qh, vertices) { ... }
+ SETelem_(vertices, i)
+*/
+setT *qh_pointvertex(qhT *qh /*qh.facet_list*/) {
+ int numpoints= qh->num_points + qh_setsize(qh, qh->other_points);
+ setT *vertices;
+ vertexT *vertex;
+
+ vertices= qh_settemp(qh, numpoints);
+ qh_setzero(qh, vertices, 0, numpoints);
+ FORALLvertices
+ qh_point_add(qh, vertices, vertex->point, vertex);
+ return vertices;
+} /* pointvertex */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="prependfacet">-</a>
+
+ qh_prependfacet(qh, facet, facetlist )
+ prepend facet to the start of a facetlist
+
+ returns:
+ increments qh.numfacets
+ updates facetlist, qh.facet_list, facet_next
+
+ notes:
+ be careful of prepending since it can lose a pointer.
+ e.g., can lose _next by deleting and then prepending before _next
+*/
+void qh_prependfacet(qhT *qh, facetT *facet, facetT **facetlist) {
+ facetT *prevfacet, *list;
+
+
+ trace4((qh, qh->ferr, 4061, "qh_prependfacet: prepend f%d before f%d\n",
+ facet->id, getid_(*facetlist)));
+ if (!*facetlist)
+ (*facetlist)= qh->facet_tail;
+ list= *facetlist;
+ prevfacet= list->previous;
+ facet->previous= prevfacet;
+ if (prevfacet)
+ prevfacet->next= facet;
+ list->previous= facet;
+ facet->next= *facetlist;
+ if (qh->facet_list == list) /* this may change *facetlist */
+ qh->facet_list= facet;
+ if (qh->facet_next == list)
+ qh->facet_next= facet;
+ *facetlist= facet;
+ qh->num_facets++;
+} /* prependfacet */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="printhashtable">-</a>
+
+ qh_printhashtable(qh, fp )
+ print hash table to fp
+
+ notes:
+ not in I/O to avoid bringing io_r.c in
+
+ design:
+ for each hash entry
+ if defined
+ if unmatched or will merge (NULL, qh_MERGEridge, qh_DUPLICATEridge)
+ print entry and neighbors
+*/
+void qh_printhashtable(qhT *qh, FILE *fp) {
+ facetT *facet, *neighbor;
+ int id, facet_i, facet_n, neighbor_i= 0, neighbor_n= 0;
+ vertexT *vertex, **vertexp;
+
+ FOREACHfacet_i_(qh, qh->hash_table) {
+ if (facet) {
+ FOREACHneighbor_i_(qh, facet) {
+ if (!neighbor || neighbor == qh_MERGEridge || neighbor == qh_DUPLICATEridge)
+ break;
+ }
+ if (neighbor_i == neighbor_n)
+ continue;
+ qh_fprintf(qh, fp, 9283, "hash %d f%d ", facet_i, facet->id);
+ FOREACHvertex_(facet->vertices)
+ qh_fprintf(qh, fp, 9284, "v%d ", vertex->id);
+ qh_fprintf(qh, fp, 9285, "\n neighbors:");
+ FOREACHneighbor_i_(qh, facet) {
+ if (neighbor == qh_MERGEridge)
+ id= -3;
+ else if (neighbor == qh_DUPLICATEridge)
+ id= -2;
+ else
+ id= getid_(neighbor);
+ qh_fprintf(qh, fp, 9286, " %d", id);
+ }
+ qh_fprintf(qh, fp, 9287, "\n");
+ }
+ }
+} /* printhashtable */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="printlists">-</a>
+
+ qh_printlists(qh, fp )
+ print out facet and vertex list for debugging (without 'f/v' tags)
+*/
+void qh_printlists(qhT *qh) {
+ facetT *facet;
+ vertexT *vertex;
+ int count= 0;
+
+ qh_fprintf(qh, qh->ferr, 8108, "qh_printlists: facets:");
+ FORALLfacets {
+ if (++count % 100 == 0)
+ qh_fprintf(qh, qh->ferr, 8109, "\n ");
+ qh_fprintf(qh, qh->ferr, 8110, " %d", facet->id);
+ }
+ qh_fprintf(qh, qh->ferr, 8111, "\n new facets %d visible facets %d next facet for qh_addpoint %d\n vertices(new %d):",
+ getid_(qh->newfacet_list), getid_(qh->visible_list), getid_(qh->facet_next),
+ getid_(qh->newvertex_list));
+ count = 0;
+ FORALLvertices {
+ if (++count % 100 == 0)
+ qh_fprintf(qh, qh->ferr, 8112, "\n ");
+ qh_fprintf(qh, qh->ferr, 8113, " %d", vertex->id);
+ }
+ qh_fprintf(qh, qh->ferr, 8114, "\n");
+} /* printlists */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="resetlists">-</a>
+
+ qh_resetlists(qh, stats, qh_RESETvisible )
+ reset newvertex_list, newfacet_list, visible_list
+ if stats,
+ maintains statistics
+
+ returns:
+ visible_list is empty if qh_deletevisible was called
+*/
+void qh_resetlists(qhT *qh, boolT stats, boolT resetVisible /*qh.newvertex_list newfacet_list visible_list*/) {
+ vertexT *vertex;
+ facetT *newfacet, *visible;
+ int totnew=0, totver=0;
+
+ if (stats) {
+ FORALLvertex_(qh->newvertex_list)
+ totver++;
+ FORALLnew_facets
+ totnew++;
+ zadd_(Zvisvertextot, totver);
+ zmax_(Zvisvertexmax, totver);
+ zadd_(Znewfacettot, totnew);
+ zmax_(Znewfacetmax, totnew);
+ }
+ FORALLvertex_(qh->newvertex_list)
+ vertex->newlist= False;
+ qh->newvertex_list= NULL;
+ FORALLnew_facets
+ newfacet->newfacet= False;
+ qh->newfacet_list= NULL;
+ if (resetVisible) {
+ FORALLvisible_facets {
+ visible->f.replace= NULL;
+ visible->visible= False;
+ }
+ qh->num_visible= 0;
+ }
+ qh->visible_list= NULL; /* may still have visible facets via qh_triangulate */
+ qh->NEWfacets= False;
+} /* resetlists */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="setvoronoi_all">-</a>
+
+ qh_setvoronoi_all(qh)
+ compute Voronoi centers for all facets
+ includes upperDelaunay facets if qh.UPPERdelaunay ('Qu')
+
+ returns:
+ facet->center is the Voronoi center
+
+ notes:
+ this is unused/untested code
+ please email bradb@shore.net if this works ok for you
+
+ use:
+ FORALLvertices {...} to locate the vertex for a point.
+ FOREACHneighbor_(vertex) {...} to visit the Voronoi centers for a Voronoi cell.
+*/
+void qh_setvoronoi_all(qhT *qh) {
+ facetT *facet;
+
+ qh_clearcenters(qh, qh_ASvoronoi);
+ qh_vertexneighbors(qh);
+
+ FORALLfacets {
+ if (!facet->normal || !facet->upperdelaunay || qh->UPPERdelaunay) {
+ if (!facet->center)
+ facet->center= qh_facetcenter(qh, facet->vertices);
+ }
+ }
+} /* setvoronoi_all */
+
+#ifndef qh_NOmerge
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="triangulate">-</a>
+
+ qh_triangulate()
+ triangulate non-simplicial facets on qh.facet_list,
+ if qh->VORONOI, sets Voronoi centers of non-simplicial facets
+ nop if hasTriangulation
+
+ returns:
+ all facets simplicial
+ each tricoplanar facet has ->f.triowner == owner of ->center,normal,etc.
+
+ notes:
+ call after qh_check_output since may switch to Voronoi centers
+ Output may overwrite ->f.triowner with ->f.area
+*/
+void qh_triangulate(qhT *qh /*qh.facet_list*/) {
+ facetT *facet, *nextfacet, *owner;
+ int onlygood= qh->ONLYgood;
+ facetT *neighbor, *visible= NULL, *facet1, *facet2, *new_facet_list= NULL;
+ facetT *orig_neighbor= NULL, *otherfacet;
+ vertexT *new_vertex_list= NULL;
+ mergeT *merge;
+ mergeType mergetype;
+ int neighbor_i, neighbor_n;
+
+ if (qh->hasTriangulation)
+ return;
+ trace1((qh, qh->ferr, 1034, "qh_triangulate: triangulate non-simplicial facets\n"));
+ if (qh->hull_dim == 2)
+ return;
+ if (qh->VORONOI) { /* otherwise lose Voronoi centers [could rebuild vertex set from tricoplanar] */
+ qh_clearcenters(qh, qh_ASvoronoi);
+ qh_vertexneighbors(qh);
+ }
+ qh->ONLYgood= False; /* for makenew_nonsimplicial */
+ qh->visit_id++;
+ qh->NEWfacets= True;
+ qh->degen_mergeset= qh_settemp(qh, qh->TEMPsize);
+ qh->newvertex_list= qh->vertex_tail;
+ for (facet= qh->facet_list; facet && facet->next; facet= nextfacet) { /* non-simplicial facets moved to end */
+ nextfacet= facet->next;
+ if (facet->visible || facet->simplicial)
+ continue;
+ /* triangulate all non-simplicial facets, otherwise merging does not work, e.g., RBOX c P-0.1 P+0.1 P+0.1 D3 | QHULL d Qt Tv */
+ if (!new_facet_list)
+ new_facet_list= facet; /* will be moved to end */
+ qh_triangulate_facet(qh, facet, &new_vertex_list);
+ }
+ trace2((qh, qh->ferr, 2047, "qh_triangulate: delete null facets from f%d -- apex same as second vertex\n", getid_(new_facet_list)));
+ for (facet= new_facet_list; facet && facet->next; facet= nextfacet) { /* null facets moved to end */
+ nextfacet= facet->next;
+ if (facet->visible)
+ continue;
+ if (facet->ridges) {
+ if (qh_setsize(qh, facet->ridges) > 0) {
+ qh_fprintf(qh, qh->ferr, 6161, "qhull error (qh_triangulate): ridges still defined for f%d\n", facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ qh_setfree(qh, &facet->ridges);
+ }
+ if (SETfirst_(facet->vertices) == SETsecond_(facet->vertices)) {
+ zinc_(Ztrinull);
+ qh_triangulate_null(qh, facet);
+ }
+ }
+ trace2((qh, qh->ferr, 2048, "qh_triangulate: delete %d or more mirror facets -- same vertices and neighbors\n", qh_setsize(qh, qh->degen_mergeset)));
+ qh->visible_list= qh->facet_tail;
+ while ((merge= (mergeT*)qh_setdellast(qh->degen_mergeset))) {
+ facet1= merge->facet1;
+ facet2= merge->facet2;
+ mergetype= merge->type;
+ qh_memfree(qh, merge, (int)sizeof(mergeT));
+ if (mergetype == MRGmirror) {
+ zinc_(Ztrimirror);
+ qh_triangulate_mirror(qh, facet1, facet2);
+ }
+ }
+ qh_settempfree(qh, &qh->degen_mergeset);
+ trace2((qh, qh->ferr, 2049, "qh_triangulate: update neighbor lists for vertices from v%d\n", getid_(new_vertex_list)));
+ qh->newvertex_list= new_vertex_list; /* all vertices of new facets */
+ qh->visible_list= NULL;
+ qh_updatevertices(qh /*qh.newvertex_list, empty newfacet_list and visible_list*/);
+ qh_resetlists(qh, False, !qh_RESETvisible /*qh.newvertex_list, empty newfacet_list and visible_list*/);
+
+ trace2((qh, qh->ferr, 2050, "qh_triangulate: identify degenerate tricoplanar facets from f%d\n", getid_(new_facet_list)));
+ trace2((qh, qh->ferr, 2051, "qh_triangulate: and replace facet->f.triowner with tricoplanar facets that own center, normal, etc.\n"));
+ FORALLfacet_(new_facet_list) {
+ if (facet->tricoplanar && !facet->visible) {
+ FOREACHneighbor_i_(qh, facet) {
+ if (neighbor_i == 0) { /* first iteration */
+ if (neighbor->tricoplanar)
+ orig_neighbor= neighbor->f.triowner;
+ else
+ orig_neighbor= neighbor;
+ }else {
+ if (neighbor->tricoplanar)
+ otherfacet= neighbor->f.triowner;
+ else
+ otherfacet= neighbor;
+ if (orig_neighbor == otherfacet) {
+ zinc_(Ztridegen);
+ facet->degenerate= True;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ trace2((qh, qh->ferr, 2052, "qh_triangulate: delete visible facets -- non-simplicial, null, and mirrored facets\n"));
+ owner= NULL;
+ visible= NULL;
+ for (facet= new_facet_list; facet && facet->next; facet= nextfacet) { /* may delete facet */
+ nextfacet= facet->next;
+ if (facet->visible) {
+ if (facet->tricoplanar) { /* a null or mirrored facet */
+ qh_delfacet(qh, facet);
+ qh->num_visible--;
+ }else { /* a non-simplicial facet followed by its tricoplanars */
+ if (visible && !owner) {
+ /* RBOX 200 s D5 t1001471447 | QHULL Qt C-0.01 Qx Qc Tv Qt -- f4483 had 6 vertices/neighbors and 8 ridges */
+ trace2((qh, qh->ferr, 2053, "qh_triangulate: all tricoplanar facets degenerate for non-simplicial facet f%d\n",
+ visible->id));
+ qh_delfacet(qh, visible);
+ qh->num_visible--;
+ }
+ visible= facet;
+ owner= NULL;
+ }
+ }else if (facet->tricoplanar) {
+ if (facet->f.triowner != visible || visible==NULL) {
+ qh_fprintf(qh, qh->ferr, 6162, "qhull error (qh_triangulate): tricoplanar facet f%d not owned by its visible, non-simplicial facet f%d\n", facet->id, getid_(visible));
+ qh_errexit2(qh, qh_ERRqhull, facet, visible);
+ }
+ if (owner)
+ facet->f.triowner= owner;
+ else if (!facet->degenerate) {
+ owner= facet;
+ nextfacet= visible->next; /* rescan tricoplanar facets with owner, visible!=0 by QH6162 */
+ facet->keepcentrum= True; /* one facet owns ->normal, etc. */
+ facet->coplanarset= visible->coplanarset;
+ facet->outsideset= visible->outsideset;
+ visible->coplanarset= NULL;
+ visible->outsideset= NULL;
+ if (!qh->TRInormals) { /* center and normal copied to tricoplanar facets */
+ visible->center= NULL;
+ visible->normal= NULL;
+ }
+ qh_delfacet(qh, visible);
+ qh->num_visible--;
+ }
+ }
+ }
+ if (visible && !owner) {
+ trace2((qh, qh->ferr, 2054, "qh_triangulate: all tricoplanar facets degenerate for last non-simplicial facet f%d\n",
+ visible->id));
+ qh_delfacet(qh, visible);
+ qh->num_visible--;
+ }
+ qh->NEWfacets= False;
+ qh->ONLYgood= onlygood; /* restore value */
+ if (qh->CHECKfrequently)
+ qh_checkpolygon(qh, qh->facet_list);
+ qh->hasTriangulation= True;
+} /* triangulate */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="triangulate_facet">-</a>
+
+ qh_triangulate_facet(qh, facetA, &firstVertex )
+ triangulate a non-simplicial facet
+ if qh.CENTERtype=qh_ASvoronoi, sets its Voronoi center
+ returns:
+ qh.newfacet_list == simplicial facets
+ facet->tricoplanar set and ->keepcentrum false
+ facet->degenerate set if duplicated apex
+ facet->f.trivisible set to facetA
+ facet->center copied from facetA (created if qh_ASvoronoi)
+ qh_eachvoronoi, qh_detvridge, qh_detvridge3 assume centers copied
+ facet->normal,offset,maxoutside copied from facetA
+
+ notes:
+ only called by qh_triangulate
+ qh_makenew_nonsimplicial uses neighbor->seen for the same
+ if qh.TRInormals, newfacet->normal will need qh_free
+ if qh.TRInormals and qh_AScentrum, newfacet->center will need qh_free
+ keepcentrum is also set on Zwidefacet in qh_mergefacet
+ freed by qh_clearcenters
+
+ see also:
+ qh_addpoint() -- add a point
+ qh_makenewfacets() -- construct a cone of facets for a new vertex
+
+ design:
+ if qh_ASvoronoi,
+ compute Voronoi center (facet->center)
+ select first vertex (highest ID to preserve ID ordering of ->vertices)
+ triangulate from vertex to ridges
+ copy facet->center, normal, offset
+ update vertex neighbors
+*/
+void qh_triangulate_facet(qhT *qh, facetT *facetA, vertexT **first_vertex) {
+ facetT *newfacet;
+ facetT *neighbor, **neighborp;
+ vertexT *apex;
+ int numnew=0;
+
+ trace3((qh, qh->ferr, 3020, "qh_triangulate_facet: triangulate facet f%d\n", facetA->id));
+
+ if (qh->IStracing >= 4)
+ qh_printfacet(qh, qh->ferr, facetA);
+ FOREACHneighbor_(facetA) {
+ neighbor->seen= False;
+ neighbor->coplanar= False;
+ }
+ if (qh->CENTERtype == qh_ASvoronoi && !facetA->center /* matches upperdelaunay in qh_setfacetplane() */
+ && fabs_(facetA->normal[qh->hull_dim -1]) >= qh->ANGLEround * qh_ZEROdelaunay) {
+ facetA->center= qh_facetcenter(qh, facetA->vertices);
+ }
+ qh_willdelete(qh, facetA, NULL);
+ qh->newfacet_list= qh->facet_tail;
+ facetA->visitid= qh->visit_id;
+ apex= SETfirstt_(facetA->vertices, vertexT);
+ qh_makenew_nonsimplicial(qh, facetA, apex, &numnew);
+ SETfirst_(facetA->neighbors)= NULL;
+ FORALLnew_facets {
+ newfacet->tricoplanar= True;
+ newfacet->f.trivisible= facetA;
+ newfacet->degenerate= False;
+ newfacet->upperdelaunay= facetA->upperdelaunay;
+ newfacet->good= facetA->good;
+ if (qh->TRInormals) { /* 'Q11' triangulate duplicates ->normal and ->center */
+ newfacet->keepcentrum= True;
+ if(facetA->normal){
+ newfacet->normal= qh_memalloc(qh, qh->normal_size);
+ memcpy((char *)newfacet->normal, facetA->normal, qh->normal_size);
+ }
+ if (qh->CENTERtype == qh_AScentrum)
+ newfacet->center= qh_getcentrum(qh, newfacet);
+ else if (qh->CENTERtype == qh_ASvoronoi && facetA->center){
+ newfacet->center= qh_memalloc(qh, qh->center_size);
+ memcpy((char *)newfacet->center, facetA->center, qh->center_size);
+ }
+ }else {
+ newfacet->keepcentrum= False;
+ /* one facet will have keepcentrum=True at end of qh_triangulate */
+ newfacet->normal= facetA->normal;
+ newfacet->center= facetA->center;
+ }
+ newfacet->offset= facetA->offset;
+#if qh_MAXoutside
+ newfacet->maxoutside= facetA->maxoutside;
+#endif
+ }
+ qh_matchnewfacets(qh /*qh.newfacet_list*/);
+ zinc_(Ztricoplanar);
+ zadd_(Ztricoplanartot, numnew);
+ zmax_(Ztricoplanarmax, numnew);
+ qh->visible_list= NULL;
+ if (!(*first_vertex))
+ (*first_vertex)= qh->newvertex_list;
+ qh->newvertex_list= NULL;
+ qh_updatevertices(qh /*qh.newfacet_list, qh.empty visible_list and qh.newvertex_list*/);
+ qh_resetlists(qh, False, !qh_RESETvisible /*qh.newfacet_list, qh.empty visible_list and qh.newvertex_list*/);
+} /* triangulate_facet */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="triangulate_link">-</a>
+
+ qh_triangulate_link(qh, oldfacetA, facetA, oldfacetB, facetB)
+ relink facetA to facetB via oldfacets
+ returns:
+ adds mirror facets to qh->degen_mergeset (4-d and up only)
+ design:
+ if they are already neighbors, the opposing neighbors become MRGmirror facets
+*/
+void qh_triangulate_link(qhT *qh, facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB) {
+ int errmirror= False;
+
+ trace3((qh, qh->ferr, 3021, "qh_triangulate_link: relink old facets f%d and f%d between neighbors f%d and f%d\n",
+ oldfacetA->id, oldfacetB->id, facetA->id, facetB->id));
+ if (qh_setin(facetA->neighbors, facetB)) {
+ if (!qh_setin(facetB->neighbors, facetA))
+ errmirror= True;
+ else
+ qh_appendmergeset(qh, facetA, facetB, MRGmirror, NULL);
+ }else if (qh_setin(facetB->neighbors, facetA))
+ errmirror= True;
+ if (errmirror) {
+ qh_fprintf(qh, qh->ferr, 6163, "qhull error (qh_triangulate_link): mirror facets f%d and f%d do not match for old facets f%d and f%d\n",
+ facetA->id, facetB->id, oldfacetA->id, oldfacetB->id);
+ qh_errexit2(qh, qh_ERRqhull, facetA, facetB);
+ }
+ qh_setreplace(qh, facetB->neighbors, oldfacetB, facetA);
+ qh_setreplace(qh, facetA->neighbors, oldfacetA, facetB);
+} /* triangulate_link */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="triangulate_mirror">-</a>
+
+ qh_triangulate_mirror(qh, facetA, facetB)
+ delete mirrored facets from qh_triangulate_null() and qh_triangulate_mirror
+ a mirrored facet shares the same vertices of a logical ridge
+ design:
+ since a null facet duplicates the first two vertices, the opposing neighbors absorb the null facet
+ if they are already neighbors, the opposing neighbors become MRGmirror facets
+*/
+void qh_triangulate_mirror(qhT *qh, facetT *facetA, facetT *facetB) {
+ facetT *neighbor, *neighborB;
+ int neighbor_i, neighbor_n;
+
+ trace3((qh, qh->ferr, 3022, "qh_triangulate_mirror: delete mirrored facets f%d and f%d\n",
+ facetA->id, facetB->id));
+ FOREACHneighbor_i_(qh, facetA) {
+ neighborB= SETelemt_(facetB->neighbors, neighbor_i, facetT);
+ if (neighbor == neighborB)
+ continue; /* occurs twice */
+ qh_triangulate_link(qh, facetA, neighbor, facetB, neighborB);
+ }
+ qh_willdelete(qh, facetA, NULL);
+ qh_willdelete(qh, facetB, NULL);
+} /* triangulate_mirror */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="triangulate_null">-</a>
+
+ qh_triangulate_null(qh, facetA)
+ remove null facetA from qh_triangulate_facet()
+ a null facet has vertex #1 (apex) == vertex #2
+ returns:
+ adds facetA to ->visible for deletion after qh_updatevertices
+ qh->degen_mergeset contains mirror facets (4-d and up only)
+ design:
+ since a null facet duplicates the first two vertices, the opposing neighbors absorb the null facet
+ if they are already neighbors, the opposing neighbors become MRGmirror facets
+*/
+void qh_triangulate_null(qhT *qh, facetT *facetA) {
+ facetT *neighbor, *otherfacet;
+
+ trace3((qh, qh->ferr, 3023, "qh_triangulate_null: delete null facet f%d\n", facetA->id));
+ neighbor= SETfirstt_(facetA->neighbors, facetT);
+ otherfacet= SETsecondt_(facetA->neighbors, facetT);
+ qh_triangulate_link(qh, facetA, neighbor, facetA, otherfacet);
+ qh_willdelete(qh, facetA, NULL);
+} /* triangulate_null */
+
+#else /* qh_NOmerge */
+void qh_triangulate(qhT *qh) {
+}
+#endif /* qh_NOmerge */
+
+ /*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="vertexintersect">-</a>
+
+ qh_vertexintersect(qh, vertexsetA, vertexsetB )
+ intersects two vertex sets (inverse id ordered)
+ vertexsetA is a temporary set at the top of qh->qhmem.tempstack
+
+ returns:
+ replaces vertexsetA with the intersection
+
+ notes:
+ could overwrite vertexsetA if currently too slow
+*/
+void qh_vertexintersect(qhT *qh, setT **vertexsetA,setT *vertexsetB) {
+ setT *intersection;
+
+ intersection= qh_vertexintersect_new(qh, *vertexsetA, vertexsetB);
+ qh_settempfree(qh, vertexsetA);
+ *vertexsetA= intersection;
+ qh_settemppush(qh, intersection);
+} /* vertexintersect */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="vertexintersect_new">-</a>
+
+ qh_vertexintersect_new(qh, )
+ intersects two vertex sets (inverse id ordered)
+
+ returns:
+ a new set
+*/
+setT *qh_vertexintersect_new(qhT *qh, setT *vertexsetA,setT *vertexsetB) {
+ setT *intersection= qh_setnew(qh, qh->hull_dim - 1);
+ vertexT **vertexA= SETaddr_(vertexsetA, vertexT);
+ vertexT **vertexB= SETaddr_(vertexsetB, vertexT);
+
+ while (*vertexA && *vertexB) {
+ if (*vertexA == *vertexB) {
+ qh_setappend(qh, &intersection, *vertexA);
+ vertexA++; vertexB++;
+ }else {
+ if ((*vertexA)->id > (*vertexB)->id)
+ vertexA++;
+ else
+ vertexB++;
+ }
+ }
+ return intersection;
+} /* vertexintersect_new */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="vertexneighbors">-</a>
+
+ qh_vertexneighbors(qh)
+ for each vertex in qh.facet_list,
+ determine its neighboring facets
+
+ returns:
+ sets qh.VERTEXneighbors
+ nop if qh.VERTEXneighbors already set
+ qh_addpoint() will maintain them
+
+ notes:
+ assumes all vertex->neighbors are NULL
+
+ design:
+ for each facet
+ for each vertex
+ append facet to vertex->neighbors
+*/
+void qh_vertexneighbors(qhT *qh /*qh.facet_list*/) {
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+
+ if (qh->VERTEXneighbors)
+ return;
+ trace1((qh, qh->ferr, 1035, "qh_vertexneighbors: determining neighboring facets for each vertex\n"));
+ qh->vertex_visit++;
+ FORALLfacets {
+ if (facet->visible)
+ continue;
+ FOREACHvertex_(facet->vertices) {
+ if (vertex->visitid != qh->vertex_visit) {
+ vertex->visitid= qh->vertex_visit;
+ vertex->neighbors= qh_setnew(qh, qh->hull_dim);
+ }
+ qh_setappend(qh, &vertex->neighbors, facet);
+ }
+ }
+ qh->VERTEXneighbors= True;
+} /* vertexneighbors */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="vertexsubset">-</a>
+
+ qh_vertexsubset( vertexsetA, vertexsetB )
+ returns True if vertexsetA is a subset of vertexsetB
+ assumes vertexsets are sorted
+
+ note:
+ empty set is a subset of any other set
+*/
+boolT qh_vertexsubset(setT *vertexsetA, setT *vertexsetB) {
+ vertexT **vertexA= (vertexT **) SETaddr_(vertexsetA, vertexT);
+ vertexT **vertexB= (vertexT **) SETaddr_(vertexsetB, vertexT);
+
+ while (True) {
+ if (!*vertexA)
+ return True;
+ if (!*vertexB)
+ return False;
+ if ((*vertexA)->id > (*vertexB)->id)
+ return False;
+ if (*vertexA == *vertexB)
+ vertexA++;
+ vertexB++;
+ }
+ return False; /* avoid warnings */
+} /* vertexsubset */
diff --git a/xs/src/qhull/src/libqhull_r/poly_r.c b/xs/src/qhull/src/libqhull_r/poly_r.c
new file mode 100644
index 000000000..e5b479743
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/poly_r.c
@@ -0,0 +1,1205 @@
+/*<html><pre> -<a href="qh-poly_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ poly_r.c
+ implements polygons and simplices
+
+ see qh-poly_r.htm, poly_r.h and libqhull_r.h
+
+ infrequent code is in poly2_r.c
+ (all but top 50 and their callers 12/3/95)
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/poly_r.c#3 $$Change: 2064 $
+ $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
+*/
+
+#include "qhull_ra.h"
+
+/*======== functions in alphabetical order ==========*/
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="appendfacet">-</a>
+
+ qh_appendfacet(qh, facet )
+ appends facet to end of qh.facet_list,
+
+ returns:
+ updates qh.newfacet_list, facet_next, facet_list
+ increments qh.numfacets
+
+ notes:
+ assumes qh.facet_list/facet_tail is defined (createsimplex)
+
+ see:
+ qh_removefacet()
+
+*/
+void qh_appendfacet(qhT *qh, facetT *facet) {
+ facetT *tail= qh->facet_tail;
+
+ if (tail == qh->newfacet_list)
+ qh->newfacet_list= facet;
+ if (tail == qh->facet_next)
+ qh->facet_next= facet;
+ facet->previous= tail->previous;
+ facet->next= tail;
+ if (tail->previous)
+ tail->previous->next= facet;
+ else
+ qh->facet_list= facet;
+ tail->previous= facet;
+ qh->num_facets++;
+ trace4((qh, qh->ferr, 4044, "qh_appendfacet: append f%d to facet_list\n", facet->id));
+} /* appendfacet */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="appendvertex">-</a>
+
+ qh_appendvertex(qh, vertex )
+ appends vertex to end of qh.vertex_list,
+
+ returns:
+ sets vertex->newlist
+ updates qh.vertex_list, newvertex_list
+ increments qh.num_vertices
+
+ notes:
+ assumes qh.vertex_list/vertex_tail is defined (createsimplex)
+
+*/
+void qh_appendvertex(qhT *qh, vertexT *vertex) {
+ vertexT *tail= qh->vertex_tail;
+
+ if (tail == qh->newvertex_list)
+ qh->newvertex_list= vertex;
+ vertex->newlist= True;
+ vertex->previous= tail->previous;
+ vertex->next= tail;
+ if (tail->previous)
+ tail->previous->next= vertex;
+ else
+ qh->vertex_list= vertex;
+ tail->previous= vertex;
+ qh->num_vertices++;
+ trace4((qh, qh->ferr, 4045, "qh_appendvertex: append v%d to vertex_list\n", vertex->id));
+} /* appendvertex */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="attachnewfacets">-</a>
+
+ qh_attachnewfacets(qh, )
+ attach horizon facets to new facets in qh.newfacet_list
+ newfacets have neighbor and ridge links to horizon but not vice versa
+ only needed for qh.ONLYgood
+
+ returns:
+ set qh.NEWfacets
+ horizon facets linked to new facets
+ ridges changed from visible facets to new facets
+ simplicial ridges deleted
+ qh.visible_list, no ridges valid
+ facet->f.replace is a newfacet (if any)
+
+ design:
+ delete interior ridges and neighbor sets by
+ for each visible, non-simplicial facet
+ for each ridge
+ if last visit or if neighbor is simplicial
+ if horizon neighbor
+ delete ridge for horizon's ridge set
+ delete ridge
+ erase neighbor set
+ attach horizon facets and new facets by
+ for all new facets
+ if corresponding horizon facet is simplicial
+ locate corresponding visible facet {may be more than one}
+ link visible facet to new facet
+ replace visible facet with new facet in horizon
+ else it's non-simplicial
+ for all visible neighbors of the horizon facet
+ link visible neighbor to new facet
+ delete visible neighbor from horizon facet
+ append new facet to horizon's neighbors
+ the first ridge of the new facet is the horizon ridge
+ link the new facet into the horizon ridge
+*/
+void qh_attachnewfacets(qhT *qh /* qh.visible_list, newfacet_list */) {
+ facetT *newfacet= NULL, *neighbor, **neighborp, *horizon, *visible;
+ ridgeT *ridge, **ridgep;
+
+ qh->NEWfacets= True;
+ trace3((qh, qh->ferr, 3012, "qh_attachnewfacets: delete interior ridges\n"));
+ qh->visit_id++;
+ FORALLvisible_facets {
+ visible->visitid= qh->visit_id;
+ if (visible->ridges) {
+ FOREACHridge_(visible->ridges) {
+ neighbor= otherfacet_(ridge, visible);
+ if (neighbor->visitid == qh->visit_id
+ || (!neighbor->visible && neighbor->simplicial)) {
+ if (!neighbor->visible) /* delete ridge for simplicial horizon */
+ qh_setdel(neighbor->ridges, ridge);
+ qh_setfree(qh, &(ridge->vertices)); /* delete on 2nd visit */
+ qh_memfree(qh, ridge, (int)sizeof(ridgeT));
+ }
+ }
+ SETfirst_(visible->ridges)= NULL;
+ }
+ SETfirst_(visible->neighbors)= NULL;
+ }
+ trace1((qh, qh->ferr, 1017, "qh_attachnewfacets: attach horizon facets to new facets\n"));
+ FORALLnew_facets {
+ horizon= SETfirstt_(newfacet->neighbors, facetT);
+ if (horizon->simplicial) {
+ visible= NULL;
+ FOREACHneighbor_(horizon) { /* may have more than one horizon ridge */
+ if (neighbor->visible) {
+ if (visible) {
+ if (qh_setequal_skip(newfacet->vertices, 0, horizon->vertices,
+ SETindex_(horizon->neighbors, neighbor))) {
+ visible= neighbor;
+ break;
+ }
+ }else
+ visible= neighbor;
+ }
+ }
+ if (visible) {
+ visible->f.replace= newfacet;
+ qh_setreplace(qh, horizon->neighbors, visible, newfacet);
+ }else {
+ qh_fprintf(qh, qh->ferr, 6102, "qhull internal error (qh_attachnewfacets): couldn't find visible facet for horizon f%d of newfacet f%d\n",
+ horizon->id, newfacet->id);
+ qh_errexit2(qh, qh_ERRqhull, horizon, newfacet);
+ }
+ }else { /* non-simplicial, with a ridge for newfacet */
+ FOREACHneighbor_(horizon) { /* may hold for many new facets */
+ if (neighbor->visible) {
+ neighbor->f.replace= newfacet;
+ qh_setdelnth(qh, horizon->neighbors,
+ SETindex_(horizon->neighbors, neighbor));
+ neighborp--; /* repeat */
+ }
+ }
+ qh_setappend(qh, &horizon->neighbors, newfacet);
+ ridge= SETfirstt_(newfacet->ridges, ridgeT);
+ if (ridge->top == horizon)
+ ridge->bottom= newfacet;
+ else
+ ridge->top= newfacet;
+ }
+ } /* newfacets */
+ if (qh->PRINTstatistics) {
+ FORALLvisible_facets {
+ if (!visible->f.replace)
+ zinc_(Zinsidevisible);
+ }
+ }
+} /* attachnewfacets */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="checkflipped">-</a>
+
+ qh_checkflipped(qh, facet, dist, allerror )
+ checks facet orientation to interior point
+
+ if allerror set,
+ tests against qh.DISTround
+ else
+ tests against 0 since tested against DISTround before
+
+ returns:
+ False if it flipped orientation (sets facet->flipped)
+ distance if non-NULL
+*/
+boolT qh_checkflipped(qhT *qh, facetT *facet, realT *distp, boolT allerror) {
+ realT dist;
+
+ if (facet->flipped && !distp)
+ return False;
+ zzinc_(Zdistcheck);
+ qh_distplane(qh, qh->interior_point, facet, &dist);
+ if (distp)
+ *distp= dist;
+ if ((allerror && dist > -qh->DISTround)|| (!allerror && dist >= 0.0)) {
+ facet->flipped= True;
+ zzinc_(Zflippedfacets);
+ trace0((qh, qh->ferr, 19, "qh_checkflipped: facet f%d is flipped, distance= %6.12g during p%d\n",
+ facet->id, dist, qh->furthest_id));
+ qh_precision(qh, "flipped facet");
+ return False;
+ }
+ return True;
+} /* checkflipped */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="delfacet">-</a>
+
+ qh_delfacet(qh, facet )
+ removes facet from facet_list and frees up its memory
+
+ notes:
+ assumes vertices and ridges already freed
+*/
+void qh_delfacet(qhT *qh, facetT *facet) {
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+
+ trace4((qh, qh->ferr, 4046, "qh_delfacet: delete f%d\n", facet->id));
+ if (facet == qh->tracefacet)
+ qh->tracefacet= NULL;
+ if (facet == qh->GOODclosest)
+ qh->GOODclosest= NULL;
+ qh_removefacet(qh, facet);
+ if (!facet->tricoplanar || facet->keepcentrum) {
+ qh_memfree_(qh, facet->normal, qh->normal_size, freelistp);
+ if (qh->CENTERtype == qh_ASvoronoi) { /* braces for macro calls */
+ qh_memfree_(qh, facet->center, qh->center_size, freelistp);
+ }else /* AScentrum */ {
+ qh_memfree_(qh, facet->center, qh->normal_size, freelistp);
+ }
+ }
+ qh_setfree(qh, &(facet->neighbors));
+ if (facet->ridges)
+ qh_setfree(qh, &(facet->ridges));
+ qh_setfree(qh, &(facet->vertices));
+ if (facet->outsideset)
+ qh_setfree(qh, &(facet->outsideset));
+ if (facet->coplanarset)
+ qh_setfree(qh, &(facet->coplanarset));
+ qh_memfree_(qh, facet, (int)sizeof(facetT), freelistp);
+} /* delfacet */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="deletevisible">-</a>
+
+ qh_deletevisible()
+ delete visible facets and vertices
+
+ returns:
+ deletes each facet and removes from facetlist
+ at exit, qh.visible_list empty (== qh.newfacet_list)
+
+ notes:
+ ridges already deleted
+ horizon facets do not reference facets on qh.visible_list
+ new facets in qh.newfacet_list
+ uses qh.visit_id;
+*/
+void qh_deletevisible(qhT *qh /*qh.visible_list*/) {
+ facetT *visible, *nextfacet;
+ vertexT *vertex, **vertexp;
+ int numvisible= 0, numdel= qh_setsize(qh, qh->del_vertices);
+
+ trace1((qh, qh->ferr, 1018, "qh_deletevisible: delete %d visible facets and %d vertices\n",
+ qh->num_visible, numdel));
+ for (visible= qh->visible_list; visible && visible->visible;
+ visible= nextfacet) { /* deleting current */
+ nextfacet= visible->next;
+ numvisible++;
+ qh_delfacet(qh, visible);
+ }
+ if (numvisible != qh->num_visible) {
+ qh_fprintf(qh, qh->ferr, 6103, "qhull internal error (qh_deletevisible): qh->num_visible %d is not number of visible facets %d\n",
+ qh->num_visible, numvisible);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+ qh->num_visible= 0;
+ zadd_(Zvisfacettot, numvisible);
+ zmax_(Zvisfacetmax, numvisible);
+ zzadd_(Zdelvertextot, numdel);
+ zmax_(Zdelvertexmax, numdel);
+ FOREACHvertex_(qh->del_vertices)
+ qh_delvertex(qh, vertex);
+ qh_settruncate(qh, qh->del_vertices, 0);
+} /* deletevisible */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="facetintersect">-</a>
+
+ qh_facetintersect(qh, facetA, facetB, skipa, skipB, prepend )
+ return vertices for intersection of two simplicial facets
+ may include 1 prepended entry (if more, need to settemppush)
+
+ returns:
+ returns set of qh.hull_dim-1 + prepend vertices
+ returns skipped index for each test and checks for exactly one
+
+ notes:
+ does not need settemp since set in quick memory
+
+ see also:
+ qh_vertexintersect and qh_vertexintersect_new
+ use qh_setnew_delnthsorted to get nth ridge (no skip information)
+
+ design:
+ locate skipped vertex by scanning facet A's neighbors
+ locate skipped vertex by scanning facet B's neighbors
+ intersect the vertex sets
+*/
+setT *qh_facetintersect(qhT *qh, facetT *facetA, facetT *facetB,
+ int *skipA,int *skipB, int prepend) {
+ setT *intersect;
+ int dim= qh->hull_dim, i, j;
+ facetT **neighborsA, **neighborsB;
+
+ neighborsA= SETaddr_(facetA->neighbors, facetT);
+ neighborsB= SETaddr_(facetB->neighbors, facetT);
+ i= j= 0;
+ if (facetB == *neighborsA++)
+ *skipA= 0;
+ else if (facetB == *neighborsA++)
+ *skipA= 1;
+ else if (facetB == *neighborsA++)
+ *skipA= 2;
+ else {
+ for (i=3; i < dim; i++) {
+ if (facetB == *neighborsA++) {
+ *skipA= i;
+ break;
+ }
+ }
+ }
+ if (facetA == *neighborsB++)
+ *skipB= 0;
+ else if (facetA == *neighborsB++)
+ *skipB= 1;
+ else if (facetA == *neighborsB++)
+ *skipB= 2;
+ else {
+ for (j=3; j < dim; j++) {
+ if (facetA == *neighborsB++) {
+ *skipB= j;
+ break;
+ }
+ }
+ }
+ if (i >= dim || j >= dim) {
+ qh_fprintf(qh, qh->ferr, 6104, "qhull internal error (qh_facetintersect): f%d or f%d not in others neighbors\n",
+ facetA->id, facetB->id);
+ qh_errexit2(qh, qh_ERRqhull, facetA, facetB);
+ }
+ intersect= qh_setnew_delnthsorted(qh, facetA->vertices, qh->hull_dim, *skipA, prepend);
+ trace4((qh, qh->ferr, 4047, "qh_facetintersect: f%d skip %d matches f%d skip %d\n",
+ facetA->id, *skipA, facetB->id, *skipB));
+ return(intersect);
+} /* facetintersect */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="gethash">-</a>
+
+ qh_gethash(qh, hashsize, set, size, firstindex, skipelem )
+ return hashvalue for a set with firstindex and skipelem
+
+ notes:
+ returned hash is in [0,hashsize)
+ assumes at least firstindex+1 elements
+ assumes skipelem is NULL, in set, or part of hash
+
+ hashes memory addresses which may change over different runs of the same data
+ using sum for hash does badly in high d
+*/
+int qh_gethash(qhT *qh, int hashsize, setT *set, int size, int firstindex, void *skipelem) {
+ void **elemp= SETelemaddr_(set, firstindex, void);
+ ptr_intT hash = 0, elem;
+ unsigned result;
+ int i;
+#ifdef _MSC_VER /* Microsoft Visual C++ -- warn about 64-bit issues */
+#pragma warning( push) /* WARN64 -- ptr_intT holds a 64-bit pointer */
+#pragma warning( disable : 4311) /* 'type cast': pointer truncation from 'void*' to 'ptr_intT' */
+#endif
+
+ switch (size-firstindex) {
+ case 1:
+ hash= (ptr_intT)(*elemp) - (ptr_intT) skipelem;
+ break;
+ case 2:
+ hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] - (ptr_intT) skipelem;
+ break;
+ case 3:
+ hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
+ - (ptr_intT) skipelem;
+ break;
+ case 4:
+ hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
+ + (ptr_intT)elemp[3] - (ptr_intT) skipelem;
+ break;
+ case 5:
+ hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
+ + (ptr_intT)elemp[3] + (ptr_intT)elemp[4] - (ptr_intT) skipelem;
+ break;
+ case 6:
+ hash= (ptr_intT)(*elemp) + (ptr_intT)elemp[1] + (ptr_intT)elemp[2]
+ + (ptr_intT)elemp[3] + (ptr_intT)elemp[4]+ (ptr_intT)elemp[5]
+ - (ptr_intT) skipelem;
+ break;
+ default:
+ hash= 0;
+ i= 3;
+ do { /* this is about 10% in 10-d */
+ if ((elem= (ptr_intT)*elemp++) != (ptr_intT)skipelem) {
+ hash ^= (elem << i) + (elem >> (32-i));
+ i += 3;
+ if (i >= 32)
+ i -= 32;
+ }
+ }while (*elemp);
+ break;
+ }
+ if (hashsize<0) {
+ qh_fprintf(qh, qh->ferr, 6202, "qhull internal error: negative hashsize %d passed to qh_gethash [poly.c]\n", hashsize);
+ qh_errexit2(qh, qh_ERRqhull, NULL, NULL);
+ }
+ result= (unsigned)hash;
+ result %= (unsigned)hashsize;
+ /* result= 0; for debugging */
+ return result;
+#ifdef _MSC_VER
+#pragma warning( pop)
+#endif
+} /* gethash */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="makenewfacet">-</a>
+
+ qh_makenewfacet(qh, vertices, toporient, horizon )
+ creates a toporient? facet from vertices
+
+ returns:
+ returns newfacet
+ adds newfacet to qh.facet_list
+ newfacet->vertices= vertices
+ if horizon
+ newfacet->neighbor= horizon, but not vice versa
+ newvertex_list updated with vertices
+*/
+facetT *qh_makenewfacet(qhT *qh, setT *vertices, boolT toporient,facetT *horizon) {
+ facetT *newfacet;
+ vertexT *vertex, **vertexp;
+
+ FOREACHvertex_(vertices) {
+ if (!vertex->newlist) {
+ qh_removevertex(qh, vertex);
+ qh_appendvertex(qh, vertex);
+ }
+ }
+ newfacet= qh_newfacet(qh);
+ newfacet->vertices= vertices;
+ newfacet->toporient= (unsigned char)toporient;
+ if (horizon)
+ qh_setappend(qh, &(newfacet->neighbors), horizon);
+ qh_appendfacet(qh, newfacet);
+ return(newfacet);
+} /* makenewfacet */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="makenewplanes">-</a>
+
+ qh_makenewplanes()
+ make new hyperplanes for facets on qh.newfacet_list
+
+ returns:
+ all facets have hyperplanes or are marked for merging
+ doesn't create hyperplane if horizon is coplanar (will merge)
+ updates qh.min_vertex if qh.JOGGLEmax
+
+ notes:
+ facet->f.samecycle is defined for facet->mergehorizon facets
+*/
+void qh_makenewplanes(qhT *qh /* qh.newfacet_list */) {
+ facetT *newfacet;
+
+ FORALLnew_facets {
+ if (!newfacet->mergehorizon)
+ qh_setfacetplane(qh, newfacet);
+ }
+ if (qh->JOGGLEmax < REALmax/2)
+ minimize_(qh->min_vertex, -wwval_(Wnewvertexmax));
+} /* makenewplanes */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="makenew_nonsimplicial">-</a>
+
+ qh_makenew_nonsimplicial(qh, visible, apex, numnew )
+ make new facets for ridges of a visible facet
+
+ returns:
+ first newfacet, bumps numnew as needed
+ attaches new facets if !qh.ONLYgood
+ marks ridge neighbors for simplicial visible
+ if (qh.ONLYgood)
+ ridges on newfacet, horizon, and visible
+ else
+ ridge and neighbors between newfacet and horizon
+ visible facet's ridges are deleted
+
+ notes:
+ qh.visit_id if visible has already been processed
+ sets neighbor->seen for building f.samecycle
+ assumes all 'seen' flags initially false
+
+ design:
+ for each ridge of visible facet
+ get neighbor of visible facet
+ if neighbor was already processed
+ delete the ridge (will delete all visible facets later)
+ if neighbor is a horizon facet
+ create a new facet
+ if neighbor coplanar
+ adds newfacet to f.samecycle for later merging
+ else
+ updates neighbor's neighbor set
+ (checks for non-simplicial facet with multiple ridges to visible facet)
+ updates neighbor's ridge set
+ (checks for simplicial neighbor to non-simplicial visible facet)
+ (deletes ridge if neighbor is simplicial)
+
+*/
+#ifndef qh_NOmerge
+facetT *qh_makenew_nonsimplicial(qhT *qh, facetT *visible, vertexT *apex, int *numnew) {
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+ ridgeT *ridge, **ridgep;
+ facetT *neighbor, *newfacet= NULL, *samecycle;
+ setT *vertices;
+ boolT toporient;
+ int ridgeid;
+
+ FOREACHridge_(visible->ridges) {
+ ridgeid= ridge->id;
+ neighbor= otherfacet_(ridge, visible);
+ if (neighbor->visible) {
+ if (!qh->ONLYgood) {
+ if (neighbor->visitid == qh->visit_id) {
+ qh_setfree(qh, &(ridge->vertices)); /* delete on 2nd visit */
+ qh_memfree_(qh, ridge, (int)sizeof(ridgeT), freelistp);
+ }
+ }
+ }else { /* neighbor is an horizon facet */
+ toporient= (ridge->top == visible);
+ vertices= qh_setnew(qh, qh->hull_dim); /* makes sure this is quick */
+ qh_setappend(qh, &vertices, apex);
+ qh_setappend_set(qh, &vertices, ridge->vertices);
+ newfacet= qh_makenewfacet(qh, vertices, toporient, neighbor);
+ (*numnew)++;
+ if (neighbor->coplanar) {
+ newfacet->mergehorizon= True;
+ if (!neighbor->seen) {
+ newfacet->f.samecycle= newfacet;
+ neighbor->f.newcycle= newfacet;
+ }else {
+ samecycle= neighbor->f.newcycle;
+ newfacet->f.samecycle= samecycle->f.samecycle;
+ samecycle->f.samecycle= newfacet;
+ }
+ }
+ if (qh->ONLYgood) {
+ if (!neighbor->simplicial)
+ qh_setappend(qh, &(newfacet->ridges), ridge);
+ }else { /* qh_attachnewfacets */
+ if (neighbor->seen) {
+ if (neighbor->simplicial) {
+ qh_fprintf(qh, qh->ferr, 6105, "qhull internal error (qh_makenew_nonsimplicial): simplicial f%d sharing two ridges with f%d\n",
+ neighbor->id, visible->id);
+ qh_errexit2(qh, qh_ERRqhull, neighbor, visible);
+ }
+ qh_setappend(qh, &(neighbor->neighbors), newfacet);
+ }else
+ qh_setreplace(qh, neighbor->neighbors, visible, newfacet);
+ if (neighbor->simplicial) {
+ qh_setdel(neighbor->ridges, ridge);
+ qh_setfree(qh, &(ridge->vertices));
+ qh_memfree(qh, ridge, (int)sizeof(ridgeT));
+ }else {
+ qh_setappend(qh, &(newfacet->ridges), ridge);
+ if (toporient)
+ ridge->top= newfacet;
+ else
+ ridge->bottom= newfacet;
+ }
+ trace4((qh, qh->ferr, 4048, "qh_makenew_nonsimplicial: created facet f%d from v%d and r%d of horizon f%d\n",
+ newfacet->id, apex->id, ridgeid, neighbor->id));
+ }
+ }
+ neighbor->seen= True;
+ } /* for each ridge */
+ if (!qh->ONLYgood)
+ SETfirst_(visible->ridges)= NULL;
+ return newfacet;
+} /* makenew_nonsimplicial */
+#else /* qh_NOmerge */
+facetT *qh_makenew_nonsimplicial(qhT *qh, facetT *visible, vertexT *apex, int *numnew) {
+ return NULL;
+}
+#endif /* qh_NOmerge */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="makenew_simplicial">-</a>
+
+ qh_makenew_simplicial(qh, visible, apex, numnew )
+ make new facets for simplicial visible facet and apex
+
+ returns:
+ attaches new facets if (!qh.ONLYgood)
+ neighbors between newfacet and horizon
+
+ notes:
+ nop if neighbor->seen or neighbor->visible(see qh_makenew_nonsimplicial)
+
+ design:
+ locate neighboring horizon facet for visible facet
+ determine vertices and orientation
+ create new facet
+ if coplanar,
+ add new facet to f.samecycle
+ update horizon facet's neighbor list
+*/
+facetT *qh_makenew_simplicial(qhT *qh, facetT *visible, vertexT *apex, int *numnew) {
+ facetT *neighbor, **neighborp, *newfacet= NULL;
+ setT *vertices;
+ boolT flip, toporient;
+ int horizonskip= 0, visibleskip= 0;
+
+ FOREACHneighbor_(visible) {
+ if (!neighbor->seen && !neighbor->visible) {
+ vertices= qh_facetintersect(qh, neighbor,visible, &horizonskip, &visibleskip, 1);
+ SETfirst_(vertices)= apex;
+ flip= ((horizonskip & 0x1) ^ (visibleskip & 0x1));
+ if (neighbor->toporient)
+ toporient= horizonskip & 0x1;
+ else
+ toporient= (horizonskip & 0x1) ^ 0x1;
+ newfacet= qh_makenewfacet(qh, vertices, toporient, neighbor);
+ (*numnew)++;
+ if (neighbor->coplanar && (qh->PREmerge || qh->MERGEexact)) {
+#ifndef qh_NOmerge
+ newfacet->f.samecycle= newfacet;
+ newfacet->mergehorizon= True;
+#endif
+ }
+ if (!qh->ONLYgood)
+ SETelem_(neighbor->neighbors, horizonskip)= newfacet;
+ trace4((qh, qh->ferr, 4049, "qh_makenew_simplicial: create facet f%d top %d from v%d and horizon f%d skip %d top %d and visible f%d skip %d, flip? %d\n",
+ newfacet->id, toporient, apex->id, neighbor->id, horizonskip,
+ neighbor->toporient, visible->id, visibleskip, flip));
+ }
+ }
+ return newfacet;
+} /* makenew_simplicial */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="matchneighbor">-</a>
+
+ qh_matchneighbor(qh, newfacet, newskip, hashsize, hashcount )
+ either match subridge of newfacet with neighbor or add to hash_table
+
+ returns:
+ duplicate ridges are unmatched and marked by qh_DUPLICATEridge
+
+ notes:
+ ridge is newfacet->vertices w/o newskip vertex
+ do not allocate memory (need to free hash_table cleanly)
+ uses linear hash chains
+
+ see also:
+ qh_matchduplicates
+
+ design:
+ for each possible matching facet in qh.hash_table
+ if vertices match
+ set ismatch, if facets have opposite orientation
+ if ismatch and matching facet doesn't have a match
+ match the facets by updating their neighbor sets
+ else
+ indicate a duplicate ridge
+ set facet hyperplane for later testing
+ add facet to hashtable
+ unless the other facet was already a duplicate ridge
+ mark both facets with a duplicate ridge
+ add other facet (if defined) to hash table
+*/
+void qh_matchneighbor(qhT *qh, facetT *newfacet, int newskip, int hashsize, int *hashcount) {
+ boolT newfound= False; /* True, if new facet is already in hash chain */
+ boolT same, ismatch;
+ int hash, scan;
+ facetT *facet, *matchfacet;
+ int skip, matchskip;
+
+ hash= qh_gethash(qh, hashsize, newfacet->vertices, qh->hull_dim, 1,
+ SETelem_(newfacet->vertices, newskip));
+ trace4((qh, qh->ferr, 4050, "qh_matchneighbor: newfacet f%d skip %d hash %d hashcount %d\n",
+ newfacet->id, newskip, hash, *hashcount));
+ zinc_(Zhashlookup);
+ for (scan= hash; (facet= SETelemt_(qh->hash_table, scan, facetT));
+ scan= (++scan >= hashsize ? 0 : scan)) {
+ if (facet == newfacet) {
+ newfound= True;
+ continue;
+ }
+ zinc_(Zhashtests);
+ if (qh_matchvertices(qh, 1, newfacet->vertices, newskip, facet->vertices, &skip, &same)) {
+ if (SETelem_(newfacet->vertices, newskip) ==
+ SETelem_(facet->vertices, skip)) {
+ qh_precision(qh, "two facets with the same vertices");
+ qh_fprintf(qh, qh->ferr, 6106, "qhull precision error: Vertex sets are the same for f%d and f%d. Can not force output.\n",
+ facet->id, newfacet->id);
+ qh_errexit2(qh, qh_ERRprec, facet, newfacet);
+ }
+ ismatch= (same == (boolT)((newfacet->toporient ^ facet->toporient)));
+ matchfacet= SETelemt_(facet->neighbors, skip, facetT);
+ if (ismatch && !matchfacet) {
+ SETelem_(facet->neighbors, skip)= newfacet;
+ SETelem_(newfacet->neighbors, newskip)= facet;
+ (*hashcount)--;
+ trace4((qh, qh->ferr, 4051, "qh_matchneighbor: f%d skip %d matched with new f%d skip %d\n",
+ facet->id, skip, newfacet->id, newskip));
+ return;
+ }
+ if (!qh->PREmerge && !qh->MERGEexact) {
+ qh_precision(qh, "a ridge with more than two neighbors");
+ qh_fprintf(qh, qh->ferr, 6107, "qhull precision error: facets f%d, f%d and f%d meet at a ridge with more than 2 neighbors. Can not continue.\n",
+ facet->id, newfacet->id, getid_(matchfacet));
+ qh_errexit2(qh, qh_ERRprec, facet, newfacet);
+ }
+ SETelem_(newfacet->neighbors, newskip)= qh_DUPLICATEridge;
+ newfacet->dupridge= True;
+ if (!newfacet->normal)
+ qh_setfacetplane(qh, newfacet);
+ qh_addhash(newfacet, qh->hash_table, hashsize, hash);
+ (*hashcount)++;
+ if (!facet->normal)
+ qh_setfacetplane(qh, facet);
+ if (matchfacet != qh_DUPLICATEridge) {
+ SETelem_(facet->neighbors, skip)= qh_DUPLICATEridge;
+ facet->dupridge= True;
+ if (!facet->normal)
+ qh_setfacetplane(qh, facet);
+ if (matchfacet) {
+ matchskip= qh_setindex(matchfacet->neighbors, facet);
+ if (matchskip<0) {
+ qh_fprintf(qh, qh->ferr, 6260, "qhull internal error (qh_matchneighbor): matchfacet f%d is in f%d neighbors but not vice versa. Can not continue.\n",
+ matchfacet->id, facet->id);
+ qh_errexit2(qh, qh_ERRqhull, matchfacet, facet);
+ }
+ SETelem_(matchfacet->neighbors, matchskip)= qh_DUPLICATEridge; /* matchskip>=0 by QH6260 */
+ matchfacet->dupridge= True;
+ if (!matchfacet->normal)
+ qh_setfacetplane(qh, matchfacet);
+ qh_addhash(matchfacet, qh->hash_table, hashsize, hash);
+ *hashcount += 2;
+ }
+ }
+ trace4((qh, qh->ferr, 4052, "qh_matchneighbor: new f%d skip %d duplicates ridge for f%d skip %d matching f%d ismatch %d at hash %d\n",
+ newfacet->id, newskip, facet->id, skip,
+ (matchfacet == qh_DUPLICATEridge ? -2 : getid_(matchfacet)),
+ ismatch, hash));
+ return; /* end of duplicate ridge */
+ }
+ }
+ if (!newfound)
+ SETelem_(qh->hash_table, scan)= newfacet; /* same as qh_addhash */
+ (*hashcount)++;
+ trace4((qh, qh->ferr, 4053, "qh_matchneighbor: no match for f%d skip %d at hash %d\n",
+ newfacet->id, newskip, hash));
+} /* matchneighbor */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="matchnewfacets">-</a>
+
+ qh_matchnewfacets()
+ match newfacets in qh.newfacet_list to their newfacet neighbors
+
+ returns:
+ qh.newfacet_list with full neighbor sets
+ get vertices with nth neighbor by deleting nth vertex
+ if qh.PREmerge/MERGEexact or qh.FORCEoutput
+ sets facet->flippped if flipped normal (also prevents point partitioning)
+ if duplicate ridges and qh.PREmerge/MERGEexact
+ sets facet->dupridge
+ missing neighbor links identifies extra ridges to be merging (qh_MERGEridge)
+
+ notes:
+ newfacets already have neighbor[0] (horizon facet)
+ assumes qh.hash_table is NULL
+ vertex->neighbors has not been updated yet
+ do not allocate memory after qh.hash_table (need to free it cleanly)
+
+ design:
+ delete neighbor sets for all new facets
+ initialize a hash table
+ for all new facets
+ match facet with neighbors
+ if unmatched facets (due to duplicate ridges)
+ for each new facet with a duplicate ridge
+ match it with a facet
+ check for flipped facets
+*/
+void qh_matchnewfacets(qhT *qh /* qh.newfacet_list */) {
+ int numnew=0, hashcount=0, newskip;
+ facetT *newfacet, *neighbor;
+ int dim= qh->hull_dim, hashsize, neighbor_i, neighbor_n;
+ setT *neighbors;
+#ifndef qh_NOtrace
+ int facet_i, facet_n, numfree= 0;
+ facetT *facet;
+#endif
+
+ trace1((qh, qh->ferr, 1019, "qh_matchnewfacets: match neighbors for new facets.\n"));
+ FORALLnew_facets {
+ numnew++;
+ { /* inline qh_setzero(qh, newfacet->neighbors, 1, qh->hull_dim); */
+ neighbors= newfacet->neighbors;
+ neighbors->e[neighbors->maxsize].i= dim+1; /*may be overwritten*/
+ memset((char *)SETelemaddr_(neighbors, 1, void), 0, dim * SETelemsize);
+ }
+ }
+
+ qh_newhashtable(qh, numnew*(qh->hull_dim-1)); /* twice what is normally needed,
+ but every ridge could be DUPLICATEridge */
+ hashsize= qh_setsize(qh, qh->hash_table);
+ FORALLnew_facets {
+ for (newskip=1; newskip<qh->hull_dim; newskip++) /* furthest/horizon already matched */
+ /* hashsize>0 because hull_dim>1 and numnew>0 */
+ qh_matchneighbor(qh, newfacet, newskip, hashsize, &hashcount);
+#if 0 /* use the following to trap hashcount errors */
+ {
+ int count= 0, k;
+ facetT *facet, *neighbor;
+
+ count= 0;
+ FORALLfacet_(qh->newfacet_list) { /* newfacet already in use */
+ for (k=1; k < qh->hull_dim; k++) {
+ neighbor= SETelemt_(facet->neighbors, k, facetT);
+ if (!neighbor || neighbor == qh_DUPLICATEridge)
+ count++;
+ }
+ if (facet == newfacet)
+ break;
+ }
+ if (count != hashcount) {
+ qh_fprintf(qh, qh->ferr, 8088, "qh_matchnewfacets: after adding facet %d, hashcount %d != count %d\n",
+ newfacet->id, hashcount, count);
+ qh_errexit(qh, qh_ERRqhull, newfacet, NULL);
+ }
+ }
+#endif /* end of trap code */
+ }
+ if (hashcount) {
+ FORALLnew_facets {
+ if (newfacet->dupridge) {
+ FOREACHneighbor_i_(qh, newfacet) {
+ if (neighbor == qh_DUPLICATEridge) {
+ qh_matchduplicates(qh, newfacet, neighbor_i, hashsize, &hashcount);
+ /* this may report MERGEfacet */
+ }
+ }
+ }
+ }
+ }
+ if (hashcount) {
+ qh_fprintf(qh, qh->ferr, 6108, "qhull internal error (qh_matchnewfacets): %d neighbors did not match up\n",
+ hashcount);
+ qh_printhashtable(qh, qh->ferr);
+ qh_errexit(qh, qh_ERRqhull, NULL, NULL);
+ }
+#ifndef qh_NOtrace
+ if (qh->IStracing >= 2) {
+ FOREACHfacet_i_(qh, qh->hash_table) {
+ if (!facet)
+ numfree++;
+ }
+ qh_fprintf(qh, qh->ferr, 8089, "qh_matchnewfacets: %d new facets, %d unused hash entries . hashsize %d\n",
+ numnew, numfree, qh_setsize(qh, qh->hash_table));
+ }
+#endif /* !qh_NOtrace */
+ qh_setfree(qh, &qh->hash_table);
+ if (qh->PREmerge || qh->MERGEexact) {
+ if (qh->IStracing >= 4)
+ qh_printfacetlist(qh, qh->newfacet_list, NULL, qh_ALL);
+ FORALLnew_facets {
+ if (newfacet->normal)
+ qh_checkflipped(qh, newfacet, NULL, qh_ALL);
+ }
+ }else if (qh->FORCEoutput)
+ qh_checkflipped_all(qh, qh->newfacet_list); /* prints warnings for flipped */
+} /* matchnewfacets */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="matchvertices">-</a>
+
+ qh_matchvertices(qh, firstindex, verticesA, skipA, verticesB, skipB, same )
+ tests whether vertices match with a single skip
+ starts match at firstindex since all new facets have a common vertex
+
+ returns:
+ true if matched vertices
+ skip index for each set
+ sets same iff vertices have the same orientation
+
+ notes:
+ assumes skipA is in A and both sets are the same size
+
+ design:
+ set up pointers
+ scan both sets checking for a match
+ test orientation
+*/
+boolT qh_matchvertices(qhT *qh, int firstindex, setT *verticesA, int skipA,
+ setT *verticesB, int *skipB, boolT *same) {
+ vertexT **elemAp, **elemBp, **skipBp=NULL, **skipAp;
+
+ elemAp= SETelemaddr_(verticesA, firstindex, vertexT);
+ elemBp= SETelemaddr_(verticesB, firstindex, vertexT);
+ skipAp= SETelemaddr_(verticesA, skipA, vertexT);
+ do if (elemAp != skipAp) {
+ while (*elemAp != *elemBp++) {
+ if (skipBp)
+ return False;
+ skipBp= elemBp; /* one extra like FOREACH */
+ }
+ }while (*(++elemAp));
+ if (!skipBp)
+ skipBp= ++elemBp;
+ *skipB= SETindex_(verticesB, skipB); /* i.e., skipBp - verticesB */
+ *same= !((skipA & 0x1) ^ (*skipB & 0x1)); /* result is 0 or 1 */
+ trace4((qh, qh->ferr, 4054, "qh_matchvertices: matched by skip %d(v%d) and skip %d(v%d) same? %d\n",
+ skipA, (*skipAp)->id, *skipB, (*(skipBp-1))->id, *same));
+ return(True);
+} /* matchvertices */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="newfacet">-</a>
+
+ qh_newfacet(qh)
+ return a new facet
+
+ returns:
+ all fields initialized or cleared (NULL)
+ preallocates neighbors set
+*/
+facetT *qh_newfacet(qhT *qh) {
+ facetT *facet;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+
+ qh_memalloc_(qh, (int)sizeof(facetT), freelistp, facet, facetT);
+ memset((char *)facet, (size_t)0, sizeof(facetT));
+ if (qh->facet_id == qh->tracefacet_id)
+ qh->tracefacet= facet;
+ facet->id= qh->facet_id++;
+ facet->neighbors= qh_setnew(qh, qh->hull_dim);
+#if !qh_COMPUTEfurthest
+ facet->furthestdist= 0.0;
+#endif
+#if qh_MAXoutside
+ if (qh->FORCEoutput && qh->APPROXhull)
+ facet->maxoutside= qh->MINoutside;
+ else
+ facet->maxoutside= qh->DISTround;
+#endif
+ facet->simplicial= True;
+ facet->good= True;
+ facet->newfacet= True;
+ trace4((qh, qh->ferr, 4055, "qh_newfacet: created facet f%d\n", facet->id));
+ return(facet);
+} /* newfacet */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="newridge">-</a>
+
+ qh_newridge()
+ return a new ridge
+*/
+ridgeT *qh_newridge(qhT *qh) {
+ ridgeT *ridge;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+
+ qh_memalloc_(qh, (int)sizeof(ridgeT), freelistp, ridge, ridgeT);
+ memset((char *)ridge, (size_t)0, sizeof(ridgeT));
+ zinc_(Ztotridges);
+ if (qh->ridge_id == UINT_MAX) {
+ qh_fprintf(qh, qh->ferr, 7074, "\
+qhull warning: more than 2^32 ridges. Qhull results are OK. Since the ridge ID wraps around to 0, two ridges may have the same identifier.\n");
+ }
+ ridge->id= qh->ridge_id++;
+ trace4((qh, qh->ferr, 4056, "qh_newridge: created ridge r%d\n", ridge->id));
+ return(ridge);
+} /* newridge */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="pointid">-</a>
+
+ qh_pointid(qh, point )
+ return id for a point,
+ returns qh_IDnone(-3) if null, qh_IDinterior(-2) if interior, or qh_IDunknown(-1) if not known
+
+ alternative code if point is in qh.first_point...
+ unsigned long id;
+ id= ((unsigned long)point - (unsigned long)qh.first_point)/qh.normal_size;
+
+ notes:
+ Valid points are non-negative
+ WARN64 -- id truncated to 32-bits, at most 2G points
+ NOerrors returned (QhullPoint::id)
+ if point not in point array
+ the code does a comparison of unrelated pointers.
+*/
+int qh_pointid(qhT *qh, pointT *point) {
+ ptr_intT offset, id;
+
+ if (!point || !qh)
+ return qh_IDnone;
+ else if (point == qh->interior_point)
+ return qh_IDinterior;
+ else if (point >= qh->first_point
+ && point < qh->first_point + qh->num_points * qh->hull_dim) {
+ offset= (ptr_intT)(point - qh->first_point);
+ id= offset / qh->hull_dim;
+ }else if ((id= qh_setindex(qh->other_points, point)) != -1)
+ id += qh->num_points;
+ else
+ return qh_IDunknown;
+ return (int)id;
+} /* pointid */
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="removefacet">-</a>
+
+ qh_removefacet(qh, facet )
+ unlinks facet from qh.facet_list,
+
+ returns:
+ updates qh.facet_list .newfacet_list .facet_next visible_list
+ decrements qh.num_facets
+
+ see:
+ qh_appendfacet
+*/
+void qh_removefacet(qhT *qh, facetT *facet) {
+ facetT *next= facet->next, *previous= facet->previous;
+
+ if (facet == qh->newfacet_list)
+ qh->newfacet_list= next;
+ if (facet == qh->facet_next)
+ qh->facet_next= next;
+ if (facet == qh->visible_list)
+ qh->visible_list= next;
+ if (previous) {
+ previous->next= next;
+ next->previous= previous;
+ }else { /* 1st facet in qh->facet_list */
+ qh->facet_list= next;
+ qh->facet_list->previous= NULL;
+ }
+ qh->num_facets--;
+ trace4((qh, qh->ferr, 4057, "qh_removefacet: remove f%d from facet_list\n", facet->id));
+} /* removefacet */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="removevertex">-</a>
+
+ qh_removevertex(qh, vertex )
+ unlinks vertex from qh.vertex_list,
+
+ returns:
+ updates qh.vertex_list .newvertex_list
+ decrements qh.num_vertices
+*/
+void qh_removevertex(qhT *qh, vertexT *vertex) {
+ vertexT *next= vertex->next, *previous= vertex->previous;
+
+ if (vertex == qh->newvertex_list)
+ qh->newvertex_list= next;
+ if (previous) {
+ previous->next= next;
+ next->previous= previous;
+ }else { /* 1st vertex in qh->vertex_list */
+ qh->vertex_list= vertex->next;
+ qh->vertex_list->previous= NULL;
+ }
+ qh->num_vertices--;
+ trace4((qh, qh->ferr, 4058, "qh_removevertex: remove v%d from vertex_list\n", vertex->id));
+} /* removevertex */
+
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >-------------------------------</a><a name="updatevertices">-</a>
+
+ qh_updatevertices()
+ update vertex neighbors and delete interior vertices
+
+ returns:
+ if qh.VERTEXneighbors, updates neighbors for each vertex
+ if qh.newvertex_list,
+ removes visible neighbors from vertex neighbors
+ if qh.newfacet_list
+ adds new facets to vertex neighbors
+ if qh.visible_list
+ interior vertices added to qh.del_vertices for later partitioning
+
+ design:
+ if qh.VERTEXneighbors
+ deletes references to visible facets from vertex neighbors
+ appends new facets to the neighbor list for each vertex
+ checks all vertices of visible facets
+ removes visible facets from neighbor lists
+ marks unused vertices for deletion
+*/
+void qh_updatevertices(qhT *qh /*qh.newvertex_list, newfacet_list, visible_list*/) {
+ facetT *newfacet= NULL, *neighbor, **neighborp, *visible;
+ vertexT *vertex, **vertexp;
+
+ trace3((qh, qh->ferr, 3013, "qh_updatevertices: delete interior vertices and update vertex->neighbors\n"));
+ if (qh->VERTEXneighbors) {
+ FORALLvertex_(qh->newvertex_list) {
+ FOREACHneighbor_(vertex) {
+ if (neighbor->visible)
+ SETref_(neighbor)= NULL;
+ }
+ qh_setcompact(qh, vertex->neighbors);
+ }
+ FORALLnew_facets {
+ FOREACHvertex_(newfacet->vertices)
+ qh_setappend(qh, &vertex->neighbors, newfacet);
+ }
+ FORALLvisible_facets {
+ FOREACHvertex_(visible->vertices) {
+ if (!vertex->newlist && !vertex->deleted) {
+ FOREACHneighbor_(vertex) { /* this can happen under merging */
+ if (!neighbor->visible)
+ break;
+ }
+ if (neighbor)
+ qh_setdel(vertex->neighbors, visible);
+ else {
+ vertex->deleted= True;
+ qh_setappend(qh, &qh->del_vertices, vertex);
+ trace2((qh, qh->ferr, 2041, "qh_updatevertices: delete vertex p%d(v%d) in f%d\n",
+ qh_pointid(qh, vertex->point), vertex->id, visible->id));
+ }
+ }
+ }
+ }
+ }else { /* !VERTEXneighbors */
+ FORALLvisible_facets {
+ FOREACHvertex_(visible->vertices) {
+ if (!vertex->newlist && !vertex->deleted) {
+ vertex->deleted= True;
+ qh_setappend(qh, &qh->del_vertices, vertex);
+ trace2((qh, qh->ferr, 2042, "qh_updatevertices: delete vertex p%d(v%d) in f%d\n",
+ qh_pointid(qh, vertex->point), vertex->id, visible->id));
+ }
+ }
+ }
+ }
+} /* updatevertices */
+
+
+
diff --git a/xs/src/qhull/src/libqhull_r/poly_r.h b/xs/src/qhull/src/libqhull_r/poly_r.h
new file mode 100644
index 000000000..c71511bd6
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/poly_r.h
@@ -0,0 +1,303 @@
+/*<html><pre> -<a href="qh-poly_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ poly_r.h
+ header file for poly_r.c and poly2_r.c
+
+ see qh-poly_r.htm, libqhull_r.h and poly_r.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/poly_r.h#5 $$Change: 2079 $
+ $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+*/
+
+#ifndef qhDEFpoly
+#define qhDEFpoly 1
+
+#include "libqhull_r.h"
+
+/*=============== constants ========================== */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >--------------------------------</a><a name="ALGORITHMfault">-</a>
+
+ ALGORITHMfault
+ use as argument to checkconvex() to report errors during buildhull
+*/
+#define qh_ALGORITHMfault 0
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="DATAfault">-</a>
+
+ DATAfault
+ use as argument to checkconvex() to report errors during initialhull
+*/
+#define qh_DATAfault 1
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="DUPLICATEridge">-</a>
+
+ DUPLICATEridge
+ special value for facet->neighbor to indicate a duplicate ridge
+
+ notes:
+ set by matchneighbor, used by matchmatch and mark_dupridge
+*/
+#define qh_DUPLICATEridge (facetT *)1L
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="MERGEridge">-</a>
+
+ MERGEridge flag in facet
+ special value for facet->neighbor to indicate a merged ridge
+
+ notes:
+ set by matchneighbor, used by matchmatch and mark_dupridge
+*/
+#define qh_MERGEridge (facetT *)2L
+
+
+/*============ -structures- ====================*/
+
+/*=========== -macros- =========================*/
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FORALLfacet_">-</a>
+
+ FORALLfacet_( facetlist ) { ... }
+ assign 'facet' to each facet in facetlist
+
+ notes:
+ uses 'facetT *facet;'
+ assumes last facet is a sentinel
+
+ see:
+ FORALLfacets
+*/
+#define FORALLfacet_( facetlist ) if (facetlist ) for ( facet=( facetlist ); facet && facet->next; facet= facet->next )
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FORALLnew_facets">-</a>
+
+ FORALLnew_facets { ... }
+ assign 'newfacet' to each facet in qh.newfacet_list
+
+ notes:
+ uses 'facetT *newfacet;'
+ at exit, newfacet==NULL
+*/
+#define FORALLnew_facets for ( newfacet=qh->newfacet_list;newfacet && newfacet->next;newfacet=newfacet->next )
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FORALLvertex_">-</a>
+
+ FORALLvertex_( vertexlist ) { ... }
+ assign 'vertex' to each vertex in vertexlist
+
+ notes:
+ uses 'vertexT *vertex;'
+ at exit, vertex==NULL
+*/
+#define FORALLvertex_( vertexlist ) for (vertex=( vertexlist );vertex && vertex->next;vertex= vertex->next )
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FORALLvisible_facets">-</a>
+
+ FORALLvisible_facets { ... }
+ assign 'visible' to each visible facet in qh.visible_list
+
+ notes:
+ uses 'vacetT *visible;'
+ at exit, visible==NULL
+*/
+#define FORALLvisible_facets for (visible=qh->visible_list; visible && visible->visible; visible= visible->next)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FORALLsame_">-</a>
+
+ FORALLsame_( newfacet ) { ... }
+ assign 'same' to each facet in newfacet->f.samecycle
+
+ notes:
+ uses 'facetT *same;'
+ stops when it returns to newfacet
+*/
+#define FORALLsame_(newfacet) for (same= newfacet->f.samecycle; same != newfacet; same= same->f.samecycle)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FORALLsame_cycle_">-</a>
+
+ FORALLsame_cycle_( newfacet ) { ... }
+ assign 'same' to each facet in newfacet->f.samecycle
+
+ notes:
+ uses 'facetT *same;'
+ at exit, same == NULL
+*/
+#define FORALLsame_cycle_(newfacet) \
+ for (same= newfacet->f.samecycle; \
+ same; same= (same == newfacet ? NULL : same->f.samecycle))
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHneighborA_">-</a>
+
+ FOREACHneighborA_( facet ) { ... }
+ assign 'neighborA' to each neighbor in facet->neighbors
+
+ FOREACHneighborA_( vertex ) { ... }
+ assign 'neighborA' to each neighbor in vertex->neighbors
+
+ declare:
+ facetT *neighborA, **neighborAp;
+
+ see:
+ <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHneighborA_(facet) FOREACHsetelement_(facetT, facet->neighbors, neighborA)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHvisible_">-</a>
+
+ FOREACHvisible_( facets ) { ... }
+ assign 'visible' to each facet in facets
+
+ notes:
+ uses 'facetT *facet, *facetp;'
+ see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHvisible_(facets) FOREACHsetelement_(facetT, facets, visible)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHnewfacet_">-</a>
+
+ FOREACHnewfacet_( facets ) { ... }
+ assign 'newfacet' to each facet in facets
+
+ notes:
+ uses 'facetT *newfacet, *newfacetp;'
+ see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHnewfacet_(facets) FOREACHsetelement_(facetT, facets, newfacet)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHvertexA_">-</a>
+
+ FOREACHvertexA_( vertices ) { ... }
+ assign 'vertexA' to each vertex in vertices
+
+ notes:
+ uses 'vertexT *vertexA, *vertexAp;'
+ see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHvertexA_(vertices) FOREACHsetelement_(vertexT, vertices, vertexA)
+
+/*-<a href="qh-poly_r.htm#TOC"
+ >--------------------------------</a><a name="FOREACHvertexreverse12_">-</a>
+
+ FOREACHvertexreverse12_( vertices ) { ... }
+ assign 'vertex' to each vertex in vertices
+ reverse order of first two vertices
+
+ notes:
+ uses 'vertexT *vertex, *vertexp;'
+ see <a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+*/
+#define FOREACHvertexreverse12_(vertices) FOREACHsetelementreverse12_(vertexT, vertices, vertex)
+
+
+/*=============== prototypes poly_r.c in alphabetical order ================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void qh_appendfacet(qhT *qh, facetT *facet);
+void qh_appendvertex(qhT *qh, vertexT *vertex);
+void qh_attachnewfacets(qhT *qh /* qh.visible_list, qh.newfacet_list */);
+boolT qh_checkflipped(qhT *qh, facetT *facet, realT *dist, boolT allerror);
+void qh_delfacet(qhT *qh, facetT *facet);
+void qh_deletevisible(qhT *qh /* qh.visible_list, qh.horizon_list */);
+setT *qh_facetintersect(qhT *qh, facetT *facetA, facetT *facetB, int *skipAp,int *skipBp, int extra);
+int qh_gethash(qhT *qh, int hashsize, setT *set, int size, int firstindex, void *skipelem);
+facetT *qh_makenewfacet(qhT *qh, setT *vertices, boolT toporient, facetT *facet);
+void qh_makenewplanes(qhT *qh /* qh.newfacet_list */);
+facetT *qh_makenew_nonsimplicial(qhT *qh, facetT *visible, vertexT *apex, int *numnew);
+facetT *qh_makenew_simplicial(qhT *qh, facetT *visible, vertexT *apex, int *numnew);
+void qh_matchneighbor(qhT *qh, facetT *newfacet, int newskip, int hashsize,
+ int *hashcount);
+void qh_matchnewfacets(qhT *qh);
+boolT qh_matchvertices(qhT *qh, int firstindex, setT *verticesA, int skipA,
+ setT *verticesB, int *skipB, boolT *same);
+facetT *qh_newfacet(qhT *qh);
+ridgeT *qh_newridge(qhT *qh);
+int qh_pointid(qhT *qh, pointT *point);
+void qh_removefacet(qhT *qh, facetT *facet);
+void qh_removevertex(qhT *qh, vertexT *vertex);
+void qh_updatevertices(qhT *qh);
+
+
+/*========== -prototypes poly2_r.c in alphabetical order ===========*/
+
+void qh_addhash(void *newelem, setT *hashtable, int hashsize, int hash);
+void qh_check_bestdist(qhT *qh);
+void qh_check_dupridge(qhT *qh, facetT *facet1, realT dist1, facetT *facet2, realT dist2);
+void qh_check_maxout(qhT *qh);
+void qh_check_output(qhT *qh);
+void qh_check_point(qhT *qh, pointT *point, facetT *facet, realT *maxoutside, realT *maxdist, facetT **errfacet1, facetT **errfacet2);
+void qh_check_points(qhT *qh);
+void qh_checkconvex(qhT *qh, facetT *facetlist, int fault);
+void qh_checkfacet(qhT *qh, facetT *facet, boolT newmerge, boolT *waserrorp);
+void qh_checkflipped_all(qhT *qh, facetT *facetlist);
+void qh_checkpolygon(qhT *qh, facetT *facetlist);
+void qh_checkvertex(qhT *qh, vertexT *vertex);
+void qh_clearcenters(qhT *qh, qh_CENTER type);
+void qh_createsimplex(qhT *qh, setT *vertices);
+void qh_delridge(qhT *qh, ridgeT *ridge);
+void qh_delvertex(qhT *qh, vertexT *vertex);
+setT *qh_facet3vertex(qhT *qh, facetT *facet);
+facetT *qh_findbestfacet(qhT *qh, pointT *point, boolT bestoutside,
+ realT *bestdist, boolT *isoutside);
+facetT *qh_findbestlower(qhT *qh, facetT *upperfacet, pointT *point, realT *bestdistp, int *numpart);
+facetT *qh_findfacet_all(qhT *qh, pointT *point, realT *bestdist, boolT *isoutside,
+ int *numpart);
+int qh_findgood(qhT *qh, facetT *facetlist, int goodhorizon);
+void qh_findgood_all(qhT *qh, facetT *facetlist);
+void qh_furthestnext(qhT *qh /* qh.facet_list */);
+void qh_furthestout(qhT *qh, facetT *facet);
+void qh_infiniteloop(qhT *qh, facetT *facet);
+void qh_initbuild(qhT *qh);
+void qh_initialhull(qhT *qh, setT *vertices);
+setT *qh_initialvertices(qhT *qh, int dim, setT *maxpoints, pointT *points, int numpoints);
+vertexT *qh_isvertex(pointT *point, setT *vertices);
+vertexT *qh_makenewfacets(qhT *qh, pointT *point /*horizon_list, visible_list*/);
+void qh_matchduplicates(qhT *qh, facetT *atfacet, int atskip, int hashsize, int *hashcount);
+void qh_nearcoplanar(qhT *qh /* qh.facet_list */);
+vertexT *qh_nearvertex(qhT *qh, facetT *facet, pointT *point, realT *bestdistp);
+int qh_newhashtable(qhT *qh, int newsize);
+vertexT *qh_newvertex(qhT *qh, pointT *point);
+ridgeT *qh_nextridge3d(ridgeT *atridge, facetT *facet, vertexT **vertexp);
+void qh_outcoplanar(qhT *qh /* qh.facet_list */);
+pointT *qh_point(qhT *qh, int id);
+void qh_point_add(qhT *qh, setT *set, pointT *point, void *elem);
+setT *qh_pointfacet(qhT *qh /*qh.facet_list*/);
+setT *qh_pointvertex(qhT *qh /*qh.facet_list*/);
+void qh_prependfacet(qhT *qh, facetT *facet, facetT **facetlist);
+void qh_printhashtable(qhT *qh, FILE *fp);
+void qh_printlists(qhT *qh);
+void qh_resetlists(qhT *qh, boolT stats, boolT resetVisible /*qh.newvertex_list qh.newfacet_list qh.visible_list*/);
+void qh_setvoronoi_all(qhT *qh);
+void qh_triangulate(qhT *qh /*qh.facet_list*/);
+void qh_triangulate_facet(qhT *qh, facetT *facetA, vertexT **first_vertex);
+void qh_triangulate_link(qhT *qh, facetT *oldfacetA, facetT *facetA, facetT *oldfacetB, facetT *facetB);
+void qh_triangulate_mirror(qhT *qh, facetT *facetA, facetT *facetB);
+void qh_triangulate_null(qhT *qh, facetT *facetA);
+void qh_vertexintersect(qhT *qh, setT **vertexsetA,setT *vertexsetB);
+setT *qh_vertexintersect_new(qhT *qh, setT *vertexsetA,setT *vertexsetB);
+void qh_vertexneighbors(qhT *qh /*qh.facet_list*/);
+boolT qh_vertexsubset(setT *vertexsetA, setT *vertexsetB);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* qhDEFpoly */
diff --git a/xs/src/qhull/src/libqhull_r/qh-geom_r.htm b/xs/src/qhull/src/libqhull_r/qh-geom_r.htm
new file mode 100644
index 000000000..eeefc0c75
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qh-geom_r.htm
@@ -0,0 +1,295 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>geom_r.c, geom2_r.c -- geometric and floating point routines</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm#TOC">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+
+<hr>
+<!-- Main text of document. -->
+
+<h2>geom_r.c, geom2_r.c, random_r.c -- geometric and floating point routines</h2>
+<blockquote>
+<p>Geometrically, a vertex is a point with <em>d</em> coordinates
+and a facet is a halfspace. A <em>halfspace</em> is defined by an
+oriented hyperplane through the facet's vertices. A <em>hyperplane</em>
+is defined by <em>d</em> normalized coefficients and an offset. A
+point is <em>above</em> a facet if its distance to the facet is
+positive.</p>
+
+<p>Qhull uses floating point coordinates for input points,
+vertices, halfspace equations, centrums, and an interior point.</p>
+
+<p>Qhull may be configured for single precision or double
+precision floating point arithmetic (see <a href="user_r.h#realT">realT</a>
+). </p>
+
+<p>Each floating point operation may incur round-off error (see
+<a href="qh-merge_r.htm#TOC">Merge</a>). The maximum error for distance
+computations is determined at initialization. The roundoff error
+in halfspace computation is accounted for by computing the
+distance from vertices to the halfspace. </p>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <b>Geom</b>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a> &#149;
+<a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a> &#149;
+<a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a> &#149;
+<a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a> &#149;
+<a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a> </p>
+
+<h3>Index to <a href="geom_r.c">geom_r.c</a>,
+<a href="geom2_r.c">geom2_r.c</a>, <a href="geom_r.h">geom_r.h</a>,
+<a href="random_r.c">random_r.c</a>, <a href="random_r.h">random_r.h</a>
+</h3>
+
+<ul>
+<li><a href="#gtype">geometric data types and constants</a> </li>
+<li><a href="#gmacro">mathematical macros</a>
+</li>
+<li><a href="#gmath">mathematical functions</a> </li>
+<li><a href="#gcomp">computational geometry functions</a> </li>
+<li><a href="#gpoint">point array functions</a> </li>
+<li><a href="#gfacet">geometric facet functions</a> </li>
+<li><a href="#ground">geometric roundoff functions</a></li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gtype">geometric data types
+and constants</a></h3>
+
+<ul>
+<li><a href="libqhull_r.h#coordT">coordT</a> coordinates and
+coefficients are stored as realT</li>
+<li><a href="libqhull_r.h#pointT">pointT</a> a point is an array
+of <tt>DIM3</tt> coordinates </li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gmacro">mathematical macros</a></h3>
+
+<ul>
+<li><a href="geom_r.h#fabs_">fabs_</a> returns the absolute
+value of a </li>
+<li><a href="geom_r.h#fmax_">fmax_</a> returns the maximum
+value of a and b </li>
+<li><a href="geom_r.h#fmin_">fmin_</a> returns the minimum
+value of a and b </li>
+<li><a href="geom_r.h#maximize_">maximize_</a> maximize a value
+</li>
+<li><a href="geom_r.h#minimize_">minimize_</a> minimize a value
+</li>
+<li><a href="geom_r.h#det2_">det2_</a> compute a 2-d
+determinate </li>
+<li><a href="geom_r.h#det3_">det3_</a> compute a 3-d
+determinate </li>
+<li><a href="geom_r.h#dX">dX, dY, dZ</a> compute the difference
+between two coordinates </li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gmath">mathematical functions</a></h3>
+
+<ul>
+<li><a href="geom_r.c#backnormal">qh_backnormal</a> solve for
+normal using back substitution </li>
+<li><a href="geom2_r.c#crossproduct">qh_crossproduct</a>
+compute the cross product of two 3-d vectors </li>
+<li><a href="geom2_r.c#determinant">qh_determinant</a> compute
+the determinant of a square matrix </li>
+<li><a href="geom_r.c#gausselim">qh_gausselim</a> Gaussian
+elimination with partial pivoting </li>
+<li><a href="geom2_r.c#gram_schmidt">qh_gram_schmidt</a>
+implements Gram-Schmidt orthogonalization by rows </li>
+<li><a href="geom2_r.c#maxabsval">qh_maxabsval</a> return max
+absolute value of a vector </li>
+<li><a href="geom2_r.c#minabsval">qh_minabsval</a> return min
+absolute value of a dim vector </li>
+<li><a href="geom2_r.c#mindiff">qh_mindiff</a> return index of
+min absolute difference of two vectors </li>
+<li><a href="geom_r.c#normalize">qh_normalize</a> normalize a
+vector </li>
+<li><a href="geom_r.c#normalize2">qh_normalize2</a> normalize a
+vector and report if too small </li>
+<li><a href="geom2_r.c#printmatrix">qh_printmatrix</a> print
+matrix given by row vectors </li>
+<li><a href="random_r.c#rand">qh_rand/srand</a> generate random
+numbers </li>
+<li><a href="random_r.c#randomfactor">qh_randomfactor</a> return
+a random factor near 1.0 </li>
+<li><a href="random_r.c#randommatrix">qh_randommatrix</a>
+generate a random dimXdim matrix in range (-1,1) </li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gcomp">computational geometry functions</a></h3>
+
+<ul>
+<li><a href="geom2_r.c#detsimplex">qh_detsimplex</a> compute
+determinate of a simplex of points </li>
+<li><a href="io_r.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
+<li><a href="geom2_r.c#distnorm">qh_distnorm</a> compute
+distance from point to hyperplane as defined by normal and offset</li>
+<li><a href="geom2_r.c#facetarea_simplex">qh_facetarea_simplex</a>
+return area of a simplex</li>
+<li><a href="geom_r.c#getangle">qh_getangle</a> return cosine
+of angle (i.e., dot product) </li>
+<li><a href="geom_r.c#getcenter">qh_getcenter</a> return
+arithmetic center for a set of vertices </li>
+<li><a href="geom2_r.c#pointdist">qh_pointdist</a> return
+distance between two points </li>
+<li><a href="geom2_r.c#rotatepoints">qh_rotatepoints</a> rotate
+numpoints points by a row matrix </li>
+<li><a href="geom2_r.c#sethalfspace">qh_sethalfspace</a> set
+coords to dual of halfspace relative to an interior point </li>
+<li><a href="geom_r.c#sethyperplane_det">qh_sethyperplane_det</a>
+return hyperplane for oriented simplex using determinates
+</li>
+<li><a href="geom_r.c#sethyperplane_gauss">qh_sethyperplane_gauss</a>
+return hyperplane for oriented simplex using Gaussian
+elimination </li>
+<li><a href="geom2_r.c#voronoi_center">qh_voronoi_center</a>
+return Voronoi center for a set of points </li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gpoint">point array functions</a></h3>
+<ul>
+<li><a href="geom2_r.c#copypoints">qh_copypoints</a> return
+malloc'd copy of points</li>
+<li><a href="geom2_r.c#joggleinput">qh_joggleinput</a> joggle
+input points by qh.JOGGLEmax </li>
+<li><a href="geom2_r.c#maxmin">qh_maxmin</a> return max/min
+points for each dimension</li>
+<li><a href="geom2_r.c#maxsimplex">qh_maxsimplex</a> determines
+maximum simplex for a set of points </li>
+<li><a href="geom2_r.c#printpoints">qh_printpoints</a> print ids for a
+set of points </li>
+<li><a href="geom2_r.c#projectinput">qh_projectinput</a> project
+input using qh DELAUNAY and qh low_bound/high_bound </li>
+<li><a href="geom2_r.c#projectpoints">qh_projectpoints</a>
+project points along one or more dimensions </li>
+<li><a href="geom2_r.c#rotateinput">qh_rotateinput</a> rotate
+input points using row matrix </li>
+<li><a href="geom2_r.c#scaleinput">qh_scaleinput</a> scale
+input points using qh low_bound/high_bound </li>
+<li><a href="geom2_r.c#scalelast">qh_scalelast</a> scale last
+coordinate to [0,m] for Delaunay triangulations </li>
+<li><a href="geom2_r.c#scalepoints">qh_scalepoints</a> scale
+points to new lowbound and highbound </li>
+<li><a href="geom2_r.c#setdelaunay">qh_setdelaunay</a> project
+points to paraboloid for Delaunay triangulation </li>
+<li><a href="geom2_r.c#sethalfspace_all">qh_sethalfspace_all</a>
+generate dual for halfspace intersection with interior
+point </li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="gfacet">geometric facet functions</a></h3>
+<ul>
+<li><a href="geom_r.c#distplane">qh_distplane</a> return
+distance from point to facet </li>
+<li><a href="geom2_r.c#facetarea">qh_facetarea</a> return area
+of a facet </li>
+<li><a href="geom2_r.c#facetcenter">qh_facetcenter</a> return
+Voronoi center for a facet's vertices </li>
+<li><a href="geom_r.c#findbest">qh_findbest</a> find visible
+facet or best facet for a point </li>
+<li><a href="geom_r.c#findbesthorizon">qh_findbesthorizon</a>
+update best new facet with horizon facets</li>
+<li><a href="geom_r.c#findbestnew">qh_findbestnew</a> find best
+new facet for point </li>
+<li><a href="geom2_r.c#getarea">qh_getarea</a> get area of all
+facets in facetlist, collect statistics </li>
+<li><a href="geom_r.c#getcentrum">qh_getcentrum</a> return
+centrum for a facet </li>
+<li><a href="geom_r.c#getdistance">qh_getdistance</a> returns
+the max and min distance of a facet's vertices to a
+neighboring facet</li>
+<li><a href="geom2_r.c#findgooddist">qh_findgooddist</a> find
+best good facet visible for point from facet </li>
+<li><a href="geom2_r.c#inthresholds">qh_inthresholds</a> return
+True if facet normal within 'Pdn' and 'PDn'</li>
+<li><a href="geom2_r.c#orientoutside">qh_orientoutside</a>
+orient facet so that <tt>qh.interior_point</tt> is inside</li>
+<li><a href="geom_r.c#projectpoint">qh_projectpoint</a> project
+point onto a facet </li>
+<li><a href="geom_r.c#setfacetplane">qh_setfacetplane</a> sets
+the hyperplane for a facet </li>
+<li><a href="geom2_r.c#sharpnewfacets">qh_sharpnewfacets</a> true
+if new facets contains a sharp corner</li>
+</ul>
+
+<h3><a href="qh-geom_r.htm#TOC">&#187;</a><a name="ground">geometric roundoff functions</a></h3>
+<ul>
+<li><a href="geom2_r.c#detjoggle">qh_detjoggle</a> determine
+default joggle for points and distance roundoff error</li>
+<li><a href="geom2_r.c#detroundoff">qh_detroundoff</a>
+determine maximum roundoff error and other precision constants</li>
+<li><a href="geom2_r.c#distround">qh_distround</a> compute
+maximum roundoff error due to a distance computation to a
+normalized hyperplane</li>
+<li><a href="geom2_r.c#divzero">qh_divzero</a> divide by a
+number that is nearly zero </li>
+<li><a href="geom2_r.c#maxouter">qh_maxouter</a> return maximum outer
+plane</li>
+<li><a href="geom2_r.c#outerinner">qh_outerinner</a> return actual
+outer and inner planes
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+
+
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull_r/qh-globa_r.htm b/xs/src/qhull/src/libqhull_r/qh-globa_r.htm
new file mode 100644
index 000000000..45437a059
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qh-globa_r.htm
@@ -0,0 +1,163 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>global_r.c -- global variables and their functions</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+
+<hr>
+<!-- Main text of document. -->
+
+<h2>global_r.c -- global variables and their functions</h2>
+<blockquote>
+<p>Qhull uses a data structure, <tt>qhT</tt>, to store
+globally defined constants, lists, sets, and variables. It is passed as the
+first argument to most functions.
+</p>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <b>Global</b> &#149;
+<a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a> &#149;
+<a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a> &#149;
+<a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a> &#149;
+<a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a> </p>
+
+<h3>Index to <a href="global_r.c">global_r.c</a> and
+<a href="libqhull_r.h">libqhull_r.h</a></h3>
+
+<ul>
+<li><a href="#ovar">Qhull's global variables</a> </li>
+<li><a href="#ofunc">Global variable and initialization
+routines</a> </li>
+</ul>
+
+<h3><a href="qh-globa_r.htm#TOC">&#187;</a><a name="ovar">Qhull's global
+variables</a></h3>
+
+<ul>
+<li><a href=global_r.c#qh_version>qh_version</a> version string
+<li><a href="libqhull_r.h#qh">qh</a> all global variables for
+qhull are in <tt>qh,qhmem</tt>, and <tt>qhstat</tt></li>
+<li><a href="libqhull_r.h#qh">QHULL_LIB_CHECK</a> Check for compatible library</li>
+<li><a href="libqhull_r.h#qh-const">qh constants</a> configuration
+flags and constants for Qhull </li>
+<li><a href="libqhull_r.h#qh-prec">qh precision constants</a>
+precision constants for Qhull </li>
+<li><a href="libqhull_r.h#qh-codetern">qh internal constants</a>
+internal constants for Qhull </li>
+<li><a href="libqhull_r.h#qh-lists">qh facet and vertex lists</a>
+lists of facets and vertices </li>
+<li><a href="libqhull_r.h#qh-var">qh global variables</a> minimum
+and maximum distances, next visit ids, several flags, and
+other global variables. </li>
+<li><a href="libqhull_r.h#qh-set">qh global sets</a> global sets
+for merging, hashing, input, etc. </li>
+<li><a href="libqhull_r.h#qh-buf">qh global buffers</a> buffers
+for matrix operations and input </li>
+<li><a href="libqhull_r.h#qh-static">qh static variables</a>
+static variables for individual functions </li>
+</ul>
+
+<h3><a href="qh-globa_r.htm#TOC">&#187;</a><a name="ofunc">Global variable and
+initialization routines</a></h3>
+
+<ul>
+<li><a href="global_r.c#appendprint">qh_appendprint</a> append
+output format to <tt>qh.PRINTout</tt> </li>
+<li><a href="global_r.c#freebuffers">qh_freebuffers</a> free
+global memory buffers </li>
+<li><a href="global_r.c#freeqhull">qh_freeqhull</a> free memory
+used by qhull </li>
+<li><a href="global_r.c#init_A">qh_init_A</a> called before
+error handling initialized </li>
+<li><a href="global_r.c#init_B">qh_init_B</a> called after
+points are defined </li>
+<li><a href="global_r.c#init_qhull_command">qh_init_qhull_command</a>
+build <tt>qh.qhull_command</tt> from <tt>argc/argv</tt></li>
+<li><a href="global_r.c#initflags">qh_initflags</a> set flags
+and constants from command line </li>
+<li><a href="global_r.c#initqhull_buffers">qh_initqhull_buffers</a>
+initialize global memory buffers </li>
+<li><a href="global_r.c#initqhull_globals">qh_initqhull_globals</a>
+initialize global variables </li>
+<li><a href="global_r.c#initqhull_mem">qh_initqhull_mem</a>
+initialize Qhull memory management </li>
+<li><a href="global_r.c#initqhull_start">qh_initqhull_start</a>
+allocate qh_qh and call qh_initqhull_start2()
+<li><a href="global_r.c#initqhull_start2">qh_initqhull_start2</a>
+initialize default values at Qhull startup </li>
+<li><a href="global_r.c#initthresholds">qh_initthresholds</a>
+initialize 'Pdn' and 'PDn' thresholds </li>
+<li><a href="global_r.c#lib_check">qh_lib_check</a> check for compatible Qhull library. Invoked by QHULL_LIB_CHECK at start of each program.</li>
+<li><a href="global_r.c#option">qh_option</a> append option
+description to <tt>qh.global_options</tt> </li>
+<li><a href="global_r.c#restore_qhull">qh_restore_qhull</a>
+restores a previously saved qhull </li>
+<li><a href="global_r.c#save_qhull">qh_save_qhull</a> saves
+qhull for a later qh_restore_qhull() </li>
+<li><a href="global_r.c#strtol">qh_strtol</a> duplicates
+strtod() and strtol() </li>
+<li><a href="global_r.c#zero">qh_zero</a> zeroes qhT before first use</li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull_r/qh-io_r.htm b/xs/src/qhull/src/libqhull_r/qh-io_r.htm
new file mode 100644
index 000000000..8a8a96300
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qh-io_r.htm
@@ -0,0 +1,305 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>io_r.c -- input and output operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+<hr>
+
+<h2>io_r.c -- input and output operations</h2>
+<blockquote>
+
+<p>Qhull provides a wide range of input
+and output options. To organize the code, most output formats use
+the same driver: </p>
+
+<pre>
+ qh_printbegin( fp, format, facetlist, facets, printall );
+
+ FORALLfacet_( facetlist )
+ qh_printafacet( fp, format, facet, printall );
+
+ FOREACHfacet_( facets )
+ qh_printafacet( fp, format, facet, printall );
+
+ qh_printend( fp, format );
+</pre>
+
+<p>Note the 'printall' flag. It selects whether or not
+qh_skipfacet() is tested. </p>
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a> <a name="TOC">&#149;</a>
+<a href="qh-globa_r.htm#TOC">Global</a> &#149; <b>Io</b> &#149;
+<a href="qh-mem_r.htm#TOC">Mem</a> &#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149;
+<a href="qh-poly_r.htm#TOC">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149;
+<a href="qh-set_r.htm#TOC">Set</a> &#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149;
+<a href="qh-user_r.htm#TOC">User</a> </p>
+
+<h3>Index to <a href="io_r.c">io_r.c</a> and <a href="io_r.h">io_r.h</a></h3>
+
+<ul>
+<li><a href="#iconst">io_r.h constants and types</a> </li>
+<li><a href="#ilevel">User level functions</a> </li>
+<li><a href="#iprint">Print functions for all output formats</a></li>
+<li><a href="#itext">Text output functions</a> </li>
+<li><a href="#iutil">Text utility functions</a></li>
+<li><a href="#igeom">Geomview output functions</a> </li>
+<li><a href="#iview">Geomview utility functions</a></li>
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iconst">io_r.h constants and types</a></h3>
+
+<ul>
+<li><a href="io_r.h#qh_MAXfirst">qh_MAXfirst</a> maximum length
+of first two lines of stdin </li>
+<li><a href="io_r.h#qh_WHITESPACE">qh_WHITESPACE</a> possible
+values of white space </li>
+<li><a href="io_r.h#printvridgeT">printvridgeT</a> function to
+print results of qh_printvdiagram or qh_eachvoronoi</li>
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="ilevel">User level functions</a></h3>
+
+<ul>
+<li><a href="io_r.c#copyfilename">qh_copyfilename</a>
+copy filename identified by qh_skipfilename
+<li><a href="io_r.c#eachvoronoi_all">qh_eachvoronoi_all</a>
+visit each Voronoi ridge of the Voronoi diagram
+<li><a href="io_r.c#prepare_output">qh_prepare_output</a>
+prepare Qhull for output (called by qh_produce_output())
+<li><a href="io_r.c#printhelp_degenerate">qh_printhelp_degenerate</a>
+prints descriptive message for precision error </li>
+<li><a href="io_r.c#printhelp_singular">qh_printhelp_singular</a>
+print help message for singular data </li>
+<li><a href="libqhull_r.c#printsummary">qh_printsummary</a> print
+summary ('s')</li>
+<li><a href="io_r.c#produce_output">qh_produce_output</a>
+prints out the result of qhull()</li>
+<li><a href="io_r.c#produce_output">qh_produce_output2</a>
+prints out the result of qhull() without calling qh_prepare_output()</li>
+<li><a href="io_r.c#readfeasible">qh_readfeasible</a> read
+interior point from remainder and qh fin ('H')</li>
+<li><a href="io_r.c#readpoints">qh_readpoints</a> read input
+points </li>
+<li><a href="io_r.c#setfeasible">qh_setfeasible</a> set
+interior point from qh feasible_string ('Hn,n,n')</li>
+<li><a href="io_r.c#skipfilename">qh_skipfilename</a>
+skip filename in string
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iprint">Print functions for all
+output formats</a></h3>
+
+<ul>
+<li><a href="io_r.c#countfacets">qh_countfacets</a> count good
+facets for printing and set visitid </li>
+<li><a href="io_r.c#markkeep">qh_markkeep</a> mark good facets
+that meet qh.KEEParea ('PAn'), qh.KEEPmerge ('PMn'), and qh.KEEPminArea ('PFn')</li>
+<li><a href="io_r.c#order_vertexneighbors">qh_order_vertexneighbors</a>
+order neighbors for a 3-d vertex by adjacency ('i', 'o')</li>
+<li><a href="io_r.c#printafacet">qh_printafacet</a> print facet
+in an output format </li>
+<li><a href="io_r.c#printbegin">qh_printbegin</a> print header
+for an output format </li>
+<li><a href="io_r.c#printend">qh_printend</a> print trailer for
+an output format </li>
+<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
+print facets in a facetlist</li>
+<li><a href="io_r.c#printfacets">qh_printfacets</a> print
+facetlist and/or facet set in an output format </li>
+<li><a href="io_r.c#printneighborhood">qh_printneighborhood</a>
+print neighborhood of one or two facets ('Po')</li>
+<li><a href="io_r.c#produce_output">qh_produce_output</a>
+print the results of qh_qhull() </li>
+<li><a href="io_r.c#skipfacet">qh_skipfacet</a> True if not
+printing this facet ('Pdk:n', 'QVn', 'QGn')</li>
+<li><a href="io_r.c#facetvertices">qh_facetvertices</a> return
+vertices in a set of facets ('p')</li>
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="itext">Text output functions</a></h3>
+<ul>
+<li><a href="io_r.c#eachvoronoi">qh_eachvoronoi</a>
+print or visit each Voronoi ridge for an input site of the Voronoi diagram
+<li><a href="io_r.c#printextremes">qh_printextremes</a> print
+extreme points by point ID (vertices of convex hull) ('Fx')</li>
+<li><a href="io_r.c#printextremes_2d">qh_printextremes_2d</a> print
+2-d extreme points by point ID ('Fx')</li>
+<li><a href="io_r.c#printextremes_d">qh_printextremes_d</a> print
+extreme points of input sites for Delaunay triangulations ('Fx')</li>
+<li><a href="io_r.c#printfacet">qh_printfacet</a> print all
+fields of a facet ('f')</li>
+<li><a href="io_r.c#printfacet2math">qh_printfacet2math</a> print
+2-d Maple or Mathematica output for a facet ('FM' or 'm')</li>
+<li><a href="io_r.c#printfacet3math">qh_printfacet3math</a>
+print 3-d Maple or Mathematica facet ('FM' or 'm')</li>
+<li><a href="io_r.c#printfacet3vertex">qh_printfacet3vertex</a>
+print vertices for a 3-d facet ('i', 'o')</li>
+<li><a href="io_r.c#printfacetheader">qh_printfacetheader</a>
+prints header fields of a facet ('f')</li>
+<li><a href="io_r.c#printfacetNvertex_nonsimplicial">qh_printfacetNvertex_nonsimplicial</a>
+print vertices for an N-d non-simplicial facet ('i', 'Ft')</li>
+<li><a href="io_r.c#printfacetNvertex_simplicial">qh_printfacetNvertex_simplicial</a>
+print vertices for an N-d simplicial facet ('i', 'o', 'Ft')</li>
+<li><a href="io_r.c#printfacetridges">qh_printfacetridges</a>
+prints ridges of a facet ('f')</li>
+<li><a href="io_r.c#printpoints_out">qh_printpoints_out</a> prints
+vertices for facets by their point coordinates ('p')</li>
+<li><a href="io_r.c#printridge">qh_printridge</a> print all
+fields for a ridge ('f')</li>
+<li><a href="io_r.c#printvdiagram">qh_printvdiagram</a> print
+voronoi diagram as Voronoi vertices for each input pair</li>
+<li><a href="io_r.c#printvertex">qh_printvertex</a> print all
+fields for a vertex ('f')</li>
+<li><a href="io_r.c#printvertexlist">qh_printvertexlist</a>
+print vertices used by a list or set of facets ('f')</li>
+<li><a href="io_r.c#printvertices">qh_printvertices</a> print a
+set of vertices ('f')</li>
+<li><a href="io_r.c#printvneighbors">qh_printvneighbors</a>
+print vertex neighbors of vertices ('FN')</li>
+<li><a href="io_r.c#printvoronoi">qh_printvoronoi</a> print
+voronoi diagram in 'o' or 'G' format</li>
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iutil">Text utility functions</a></h3>
+<ul>
+<li><a href="io_r.c#dfacet">dfacet</a> print facet by ID </li>
+<li><a href="io_r.c#dvertex">dvertex</a> print vertex by ID </li>
+<li><a href="io_r.c#compare_facetarea">qh_compare_facetarea</a>
+used by qsort() to order facets by area </li>
+<li><a href="io_r.c#compare_facetmerge">qh_compare_facetmerge</a>
+used by qsort() to order facets by number of merges </li>
+<li><a href="io_r.c#compare_facetvisit">qh_compare_facetvisit</a>
+used by qsort() to order facets by visit ID or ID </li>
+<li><a href="io_r.c#compare_vertexpoint">qh_compare_vertexpoint</a>
+used by qsort() to order vertices by point ID </li>
+<li><a href="io_r.c#detvnorm">qh_detvnorm</a> determine normal for Voronoi ridge </li>
+<li><a href="io_r.c#detvridge">qh_detvridge</a> determine Voronoi
+ridge for an input site
+<li><a href="io_r.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
+ridge for an input site
+<li><a href="io_r.c#facet2point">qh_facet2point</a> return two
+projected temporary vertices for a 2-d facet ('m', 'G')</li>
+<li><a href="io_r.c#markvoronoi">qh_markvoronoi</a> mark Voronoi
+vertices for printing
+<li><a href="io_r.c#printcenter">qh_printcenter</a> print
+facet-&gt;center as centrum or Voronoi center ('Ft', 'v p', 'FC', 'f') </li>
+<li><a href="io_r.c#printpoint">qh_printpoint</a>, qh_printpointid, print
+coordinates of a point ('p', 'o', 'Fp', 'G', 'f')</li>
+<li><a href="io_r.c#printpoint3">qh_printpoint3</a> prints 2-d,
+3-d, or 4-d point as 3-d coordinates ('G')</li>
+<li><a href="io_r.c#printvdiagram2">qh_printvdiagram2</a> print
+voronoi diagram for each ridge of each vertex from qh_markvoronoi</li>
+<li><a href="io_r.c#printvnorm">qh_printvnorm</a> print
+separating plane of the Voronoi diagram for a pair of input sites</li>
+<li><a href="io_r.c#printvridge">qh_printvridge</a> print
+ridge of the Voronoi diagram for a pair of input sites</li>
+<li><a href="io_r.c#projectdim3">qh_projectdim3</a> project 2-d
+3-d or 4-d point to a 3-d point ('G')</li>
+</ul>
+
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="igeom">Geomview output functions</a></h3>
+<ul>
+<li><a href="io_r.c#printfacet2geom">qh_printfacet2geom</a>
+print facet as a 2-d VECT object </li>
+<li><a href="io_r.c#printfacet2geom_points">qh_printfacet2geom_points</a>
+print points as a 2-d VECT object with offset </li>
+<li><a href="io_r.c#printfacet3geom_nonsimplicial">qh_printfacet3geom_nonsimplicial</a>
+print Geomview OFF for a 3-d nonsimplicial facet. </li>
+<li><a href="io_r.c#printfacet3geom_points">qh_printfacet3geom_points</a>
+prints a 3-d facet as OFF Geomview object. </li>
+<li><a href="io_r.c#printfacet3geom_simplicial">qh_printfacet3geom_simplicial</a>
+print Geomview OFF for a 3-d simplicial facet. </li>
+<li><a href="io_r.c#printfacet4geom_nonsimplicial">qh_printfacet4geom_nonsimplicial</a>
+print Geomview 4OFF file for a 4d nonsimplicial facet </li>
+<li><a href="io_r.c#printfacet4geom_simplicial">qh_printfacet4geom_simplicial</a>
+print Geomview 4OFF file for a 4d simplicial facet </li>
+<li><a href="io_r.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
+print hyperplane intersection as OFF or 4OFF </li>
+<li><a href="io_r.c#printvoronoi">qh_printvoronoi</a> print
+voronoi diagram in 'o' or 'G' format</li>
+</ul>
+<h3><a href="qh-io_r.htm#TOC">&#187;</a><a name="iview">Geomview utility functions</a></h3>
+<ul>
+<li><a href="io_r.c#geomplanes">qh_geomplanes</a>
+ return outer and inner planes for Geomview</li>
+<li><a href="io_r.c#printcentrum">qh_printcentrum</a> print
+centrum for a facet in OOGL format </li>
+<li><a href="io_r.c#printend4geom">qh_printend4geom</a> helper
+function for qh_printbegin/printend </li>
+<li><a href="io_r.c#printhyperplaneintersection">qh_printhyperplaneintersection</a>
+print Geomview OFF or 4OFF for the intersection of two
+hyperplanes in 3-d or 4-d </li>
+<li><a href="io_r.c#printline3geom">qh_printline3geom</a> prints a
+line as a VECT </li>
+<li><a href="io_r.c#printpointvect">qh_printpointvect</a>
+prints a 2-d or 3-d point as 3-d VECT's </li>
+<li><a href="io_r.c#printpointvect2">qh_printpointvect2</a>
+prints a 2-d or 3-d point as 2 3-d VECT's </li>
+<li><a href="io_r.c#printspheres">qh_printspheres</a> prints 3-d
+vertices as OFF spheres </li>
+</ul>
+<p>
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull_r/qh-mem_r.htm b/xs/src/qhull/src/libqhull_r/qh-mem_r.htm
new file mode 100644
index 000000000..db59119cb
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qh-mem_r.htm
@@ -0,0 +1,145 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>mem_r.c -- memory operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+<hr>
+
+<h2>mem_r.c -- memory operations</h2>
+<blockquote>
+<p>Qhull uses quick-fit memory allocation. It maintains a
+set of free lists for a variety of small allocations. A
+small request returns a block from the best fitting free
+list. If the free list is empty, Qhull allocates a block
+from a reserved buffer. </p>
+<p>Use 'T5' to trace memory allocations.</p>
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a> &#149;
+<a href="qh-io_r.htm#TOC">Io</a> &#149; <b>Mem</b>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="mem_r.c">mem_r.c</a> and
+<a href="mem_r.h">mem_r.h</a></h3>
+<ul>
+<li><a href="#etype">mem_r.h data types</a> </li>
+<li><a href="#emacro">mem_r.h macros</a> </li>
+<li><a href="#efunc">User level functions</a> </li>
+</ul>
+<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="etype">mem_r.h data types and constants</a></h3>
+<ul>
+<li><a href="mem_r.h#ptr_intT">ptr_intT</a> for casting
+a void* to an integer-type </li>
+<li><a href="mem_r.h#qhmemT">qhmemT</a> global memory
+structure for mem_r.c </li>
+<li><a href="mem_r.h#NOmem">qh_NOmem</a> disable memory allocation</li>
+</ul>
+<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="emacro">mem_r.h macros</a></h3>
+<ul>
+<li><a href="mem_r.h#memalloc_">qh_memalloc_</a>
+allocate memory</li>
+<li><a href="mem_r.h#memfree_">qh_memfree_</a> free
+memory</li>
+</ul>
+<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="efunc">User level
+functions</a></h3>
+<ul>
+<li><a href="mem_r.c#memalloc">qh_memalloc</a> allocate
+memory </li>
+<li><a href="mem_r.c#memcheck">qh_memcheck</a>
+quick check of memory for internal consistency</li>
+<li><a href="mem_r.c#memfree">qh_memfree</a> free
+memory </li>
+<li><a href="mem_r.c#meminit">qh_meminit</a> initialize
+memory </li>
+<li><a href="mem_r.c#memstatistics">qh_memstatistics</a>
+print memory statistics </li>
+<li><a href="mem_r.c#meminit">qh_memtotlong</a> return total, allocated long memory</li>
+<li><a href="mem_r.c#NOmem">qh_NOmem</a> allocation routines with malloc() and free()
+</ul>
+
+<h3><a href="qh-mem_r.htm#TOC">&#187;</a><a name="m">Initialization and
+termination functions</a></h3>
+<ul>
+<li><a href="mem_r.c#intcompare">qh_intcompare</a> used by
+qsort and bsearch to compare two integers </li>
+<li><a href="mem_r.c#memfreeshort">qh_memfreeshort</a>
+frees up all short and qhmem memory allocations </li>
+<li><a href="mem_r.c#meminit">qh_meminit</a> initialize
+memory </li>
+<li><a href="mem_r.c#meminitbuffers">qh_meminitbuffers</a>
+initialize qhmem </li>
+<li><a href="mem_r.c#memsetup">qh_memsetup</a> set up
+memory after running memsize() </li>
+<li><a href="mem_r.c#memsize">qh_memsize</a> define a free
+list for this size </li>
+<li><a href="mem_r.c#memstatistics">qh_memstatistics</a>
+print out memory statistics </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull_r/qh-merge_r.htm b/xs/src/qhull/src/libqhull_r/qh-merge_r.htm
new file mode 100644
index 000000000..63e5135be
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qh-merge_r.htm
@@ -0,0 +1,366 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>merge_r.c -- facet merge operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+<hr>
+
+<h2>merge_r.c -- facet merge operations</h2>
+<blockquote>
+<p>Qhull handles precision problems by merged facets or joggled input.
+Except for redundant vertices, it corrects a problem by
+merging two facets. When done, all facets are clearly
+convex. See <a href="../../html/qh-impre.htm">Imprecision in Qhull</a>
+for further information. </p>
+<p>Users may joggle the input ('<a href="../../html/qh-optq.htm#QJn">QJn</a>')
+instead of merging facets. </p>
+<p>Qhull detects and corrects the following problems: </p>
+<ul>
+<li><b>More than two facets meeting at a ridge. </b>When
+Qhull creates facets, it creates an even number
+of facets for each ridge. A convex hull always
+has two facets for each ridge. More than two
+facets may be created if non-adjacent facets
+share a vertex. This is called a <em>duplicate
+ridge</em>. In 2-d, a duplicate ridge would
+create a loop of facets. </li>
+</ul>
+<ul>
+<li><b>A facet contained in another facet. </b>Facet
+merging may leave all vertices of one facet as a
+subset of the vertices of another facet. This is
+called a <em>redundant facet</em>. </li>
+</ul>
+<ul>
+<li><b>A facet with fewer than three neighbors. </b>Facet
+merging may leave a facet with one or two
+neighbors. This is called a <em>degenerate facet</em>.
+</li>
+</ul>
+<ul>
+<li><b>A facet with flipped orientation. </b>A
+facet's hyperplane may define a halfspace that
+does not include the interior point.This is
+called a <em>flipped facet</em>. </li>
+</ul>
+<ul>
+<li><strong>A coplanar horizon facet.</strong> A
+newly processed point may be coplanar with an
+horizon facet. Qhull creates a new facet without
+a hyperplane. It links new facets for the same
+horizon facet together. This is called a <em>samecycle</em>.
+The new facet or samecycle is merged into the
+horizon facet. </li>
+</ul>
+<ul>
+<li><b>Concave facets. </b>A facet's centrum may be
+above a neighboring facet. If so, the facets meet
+at a concave angle. </li>
+</ul>
+<ul>
+<li><b>Coplanar facets. </b>A facet's centrum may be
+coplanar with a neighboring facet (i.e., it is
+neither clearly below nor clearly above the
+facet's hyperplane). Qhull removes coplanar
+facets in independent sets sorted by angle.</li>
+</ul>
+<ul>
+<li><b>Redundant vertex. </b>A vertex may have fewer
+than three neighboring facets. If so, it is
+redundant and may be renamed to an adjacent
+vertex without changing the topological
+structure.This is called a <em>redundant vertex</em>.
+</li>
+</ul>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <b>Merge</b> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="merge_r.c">merge_r.c</a> and
+<a href="merge_r.h">merge_r.h</a></h3>
+<ul>
+<li><a href="#mtype">merge_r.h data types, macros, and
+global sets</a> </li>
+<li><a href="#mconst">merge_r.h constants</a> </li>
+</ul>
+<ul>
+<li><a href="#mtop">top-level merge functions</a> </li>
+<li><a href="#mset">functions for identifying merges</a></li>
+<li><a href="#mbest">functions for determining the
+best merge</a> </li>
+<li><a href="#mmerge">functions for merging facets</a>
+</li>
+<li><a href="#mcycle">functions for merging a cycle
+of facets</a> </li>
+<li><a href="#mrename">functions for renaming a
+vertex</a> </li>
+<li><a href="#mvertex">functions for identifying
+vertices for renaming</a> </li>
+<li><a href="#mcheck">functions for check and trace</a> </li>
+</ul>
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mtype">merge_r.h data
+types, macros, and global sets</a></h3>
+<ul>
+<li><a href="merge_r.h#mergeT">mergeT</a> structure to
+identify a merge of two facets</li>
+<li><a href="merge_r.h#FOREACHmerge_">FOREACHmerge_</a>
+assign 'merge' to each merge in merges </li>
+<li><a href="libqhull_r.h#qh-set">qh global sets</a>
+qh.facet_mergeset contains non-convex merges
+while qh.degen_mergeset contains degenerate and
+redundant facets</li>
+</ul>
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mconst">merge_r.h
+constants</a></h3>
+<ul>
+<li><a href="libqhull_r.h#qh-prec">qh precision constants</a>
+precision constants for Qhull </li>
+<li><a href="merge_r.h#MRG">MRG...</a> indicates the
+type of a merge (mergeT-&gt;type)</li>
+<li><a href="merge_r.h#qh_ANGLEredundant">qh_ANGLEredundant</a>
+indicates redundant merge in mergeT-&gt;angle </li>
+<li><a href="merge_r.h#qh_ANGLEdegen">qh_ANGLEdegen</a>
+indicates degenerate facet in mergeT-&gt;angle </li>
+<li><a href="merge_r.h#qh_ANGLEconcave">qh_ANGLEconcave</a>
+offset to indicate concave facets in
+mergeT-&gt;angle </li>
+<li><a href="merge_r.h#qh_MERGEapex">qh_MERGEapex</a>
+flag for qh_mergefacet() to indicate an apex
+merge </li>
+</ul>
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mtop">top-level merge
+functions</a></h3>
+<ul>
+<li><a href="merge_r.c#all_merges">qh_all_merges</a>
+merge all non-convex facets </li>
+<li><a href="merge_r.c#checkzero">qh_checkzero</a>
+check that facets are clearly convex </li>
+<li><a href="merge_r.c#flippedmerges">qh_flippedmerges</a>
+merge flipped facets into best neighbor </li>
+<li><a href="merge_r.c#forcedmerges">qh_forcedmerges</a>
+merge all duplicate ridges </li>
+<li><a href="merge_r.c#merge_degenredundant">qh_merge_degenredundant</a>
+merge degenerate and redundant facets </li>
+<li><a href="merge_r.c#merge_nonconvex">qh_merge_nonconvex</a>
+merge a non-convex ridge </li>
+<li><a href="merge_r.c#premerge">qh_premerge</a>
+pre-merge non-convex facets </li>
+<li><a href="merge_r.c#postmerge">qh_postmerge</a>
+post-merge nonconvex facets as defined by
+maxcentrum/maxangle </li>
+</ul>
+
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mset">functions for
+identifying merges</a></h3>
+<ul>
+<li><a href="merge_r.c#appendmergeset">qh_appendmergeset</a>
+appends an entry to qh.facet_mergeset</li>
+<li><a href="merge_r.c#compareangle">qh_compareangle</a>
+used by qsort() to order merges </li>
+<li><a href="merge_r.c#comparemerge">qh_comparemerge</a>
+used by qsort() to order merges </li>
+<li><a href="merge_r.c#degen_redundant_facet">qh_degen_redundant_facet</a>
+check for a degenerate and redundant facet</li>
+<li><a href="merge_r.c#degen_redundant_neighbors">qh_degen_redundant_neighbors</a>
+append degenerate and redundant neighbors to
+qh.degen_mergeset </li>
+<li><a href="merge_r.c#getmergeset_initial">qh_getmergeset_initial</a>
+build initial qh.facet_mergeset </li>
+<li><a href="merge_r.c#getmergeset">qh_getmergeset</a>
+update qh.facet_mergeset </li>
+<li><a href="merge_r.c#mark_dupridges">qh_mark_dupridges</a>
+add duplicated ridges to qh.facet_mergeset</li>
+<li><a href="merge_r.c#maydropneighbor">qh_maydropneighbor</a>
+drop neighbor relationship if no ridge between
+facet and neighbor </li>
+<li><a href="merge_r.c#test_appendmerge">qh_test_appendmerge</a>
+test a pair of facets for convexity and append to
+qh.facet_mergeset if non-convex </li>
+<li><a href="merge_r.c#test_vneighbors">qh_test_vneighbors</a>
+test vertex neighbors for convexity </li>
+</ul>
+
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mbest">functions for
+determining the best merge</a></h3>
+<ul>
+<li><a href="merge_r.c#findbest_test">qh_findbest_test</a>
+test neighbor for best merge </li>
+<li><a href="merge_r.c#findbestneighbor">qh_findbestneighbor</a>
+finds best neighbor of a facet for merging (i.e.,
+closest hyperplane) </li>
+</ul>
+
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mmerge">functions for
+merging facets</a></h3>
+<ul>
+<li><a href="merge_r.c#copynonconvex">qh_copynonconvex</a>
+copy non-convex flag to another ridge for the
+same neighbor </li>
+<li><a href="merge_r.c#makeridges">qh_makeridges</a>
+creates explicit ridges between simplicial facets
+</li>
+<li><a href="merge_r.c#mergefacet">qh_mergefacet</a>
+merges one facet into another facet</li>
+<li><a href="merge_r.c#mergeneighbors">qh_mergeneighbors</a>
+merges the neighbors of two facets </li>
+<li><a href="merge_r.c#mergeridges">qh_mergeridges</a>
+merges the ridge sets of two facets </li>
+<li><a href="merge_r.c#mergesimplex">qh_mergesimplex</a>
+merge a simplicial facet into another simplicial
+facet </li>
+<li><a href="merge_r.c#mergevertex_del">qh_mergevertex_del</a>
+delete a vertex due to merging one facet into
+another facet </li>
+<li><a href="merge_r.c#mergevertex_neighbors">qh_mergevertex_neighbors</a>
+merge the vertex neighbors of two facets </li>
+<li><a href="merge_r.c#mergevertices">qh_mergevertices</a>
+merge the vertex sets of two facets </li>
+<li><a href="merge_r.c#newvertices">qh_newvertices</a>
+register all vertices as new vertices </li>
+<li><a href="merge_r.c#updatetested">qh_updatetested</a>
+clear tested flags and centrums involved in a
+merge </li>
+<li><a href="merge_r.c#willdelete">qh_willdelete</a>
+moves facet to qh.visible_list; sets replacement
+or NULL </li>
+</ul>
+
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mcycle">functions for
+merging a cycle of facets</a></h3>
+<p>If a point is coplanar with an horizon facet, the
+corresponding new facets are linked together (a <em>samecycle</em>)
+for merging.</p>
+<ul>
+<li><a href="merge_r.c#basevertices">qh_basevertices</a>
+return temporary set of base vertices for a
+samecycle </li>
+<li><a href="merge_r.c#mergecycle">qh_mergecycle</a>
+merge a samecycle into a horizon facet </li>
+<li><a href="merge_r.c#mergecycle_all">qh_mergecycle_all</a>
+merge all samecycles into horizon facets</li>
+<li><a href="merge_r.c#mergecycle_facets">qh_mergecycle_facets</a>
+finish merge of samecycle </li>
+<li><a href="merge_r.c#mergecycle_neighbors">qh_mergecycle_neighbors</a>
+merge neighbor sets for samecycle </li>
+<li><a href="merge_r.c#mergecycle_ridges">qh_mergecycle_ridges</a>
+merge ridge sets for samecycle </li>
+<li><a href="merge_r.c#mergecycle_vneighbors">qh_mergecycle_vneighbors</a>
+merge vertex neighbor sets for samecycle </li>
+</ul>
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mrename">functions
+for renaming a vertex</a></h3>
+<ul>
+<li><a href="merge_r.c#comparevisit">qh_comparevisit</a>
+used by qsort() to order vertices by visitid</li>
+<li><a href="merge_r.c#reducevertices">qh_reducevertices</a>
+reduce vertex sets </li>
+<li><a href="merge_r.c#redundant_vertex">qh_redundant_vertex</a>
+returns true if detect and rename redundant
+vertex </li>
+<li><a href="merge_r.c#rename_sharedvertex">qh_rename_sharedvertex</a>
+detect and rename a shared vertex </li>
+<li><a href="merge_r.c#renameridgevertex">qh_renameridgevertex</a>
+rename oldvertex to newvertex in a ridge </li>
+<li><a href="merge_r.c#renamevertex">qh_renamevertex</a>
+rename oldvertex to newvertex in ridges </li>
+<li><a href="merge_r.c#remove_extravertices">qh_remove_extravertices</a>
+remove extra vertices in non-simplicial facets </li>
+</ul>
+
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mvertex">functions
+for identifying vertices for renaming</a></h3>
+<ul>
+<li><a href="merge_r.c#find_newvertex">qh_find_newvertex</a>
+locate new vertex for renaming old vertex </li>
+<li><a href="merge_r.c#hashridge">qh_hashridge</a> add
+ridge to hashtable </li>
+<li><a href="merge_r.c#hashridge_find">qh_hashridge_find</a>
+returns matching ridge in hashtable</li>
+<li><a href="merge_r.c#neighbor_intersections">qh_neighbor_intersections</a>
+return intersection of vertex sets for
+neighboring facets </li>
+<li><a href="merge_r.c#vertexridges">qh_vertexridges</a>
+return temporary set of ridges adjacent to a
+vertex </li>
+<li><a href="merge_r.c#vertexridges_facet">qh_vertexridges_facet</a>
+add adjacent ridges for a vertex in facet </li>
+</ul>
+
+<h3><a href="qh-merge_r.htm#TOC">&#187;</a><a name="mcheck">functions for check and
+trace</a></h3>
+<ul>
+<li><a href="merge_r.c#checkconnect">qh_checkconnect</a>
+check that new facets are connected </li>
+<li><a href="merge_r.c#tracemerge">qh_tracemerge</a>
+print trace message after merge </li>
+<li><a href="merge_r.c#tracemerging">qh_tracemerging</a>
+print trace message during post-merging </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull_r/qh-poly_r.htm b/xs/src/qhull/src/libqhull_r/qh-poly_r.htm
new file mode 100644
index 000000000..c5b6f2f83
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qh-poly_r.htm
@@ -0,0 +1,485 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>poly_r.c, poly2_r.c -- polyhedron operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+<hr>
+
+<h2>poly_r.c, poly2_r.c -- polyhedron operations</h2>
+<blockquote>
+
+<p>Qhull uses dimension-free terminology. Qhull builds a
+polyhedron in dimension <em>d. </em>A <em>polyhedron</em> is a
+simplicial complex of faces with geometric information for the
+top and bottom-level faces. A (<em>d-1</em>)-face is a <em>facet</em>,
+a (<em>d-2</em>)-face is a <em>ridge</em>, and a <em>0</em>-face
+is a <em>vertex</em>. For example in 3-d, a facet is a polygon
+and a ridge is an edge. A facet is built from a ridge (the <em>base</em>)
+and a vertex (the <em>apex</em>). See
+<a href="../../html/index.htm#structure">Qhull's data structures</a>.</p>
+
+<p>Qhull's primary data structure is a polyhedron. A
+polyhedron is a list of facets. Each facet has a set of
+neighboring facets and a set of vertices. Each facet has a
+hyperplane. For example, a tetrahedron has four facets.
+If its vertices are <em>a, b, c, d</em>, and its facets
+are <em>1, 2, 3, 4,</em> the tetrahedron is </p>
+<blockquote>
+<ul>
+<li>facet 1 <ul>
+ <li>vertices: b c d </li>
+ <li>neighbors: 2 3 4 </li>
+</ul>
+</li>
+<li>facet 2 <ul>
+ <li>vertices: a c d </li>
+ <li>neighbors: 1 3 4 </li>
+</ul>
+</li>
+<li>facet 3 <ul>
+ <li>vertices: a b d </li>
+ <li>neighbors: 1 2 4 </li>
+</ul>
+</li>
+<li>facet 4 <ul>
+ <li>vertices: a b c </li>
+ <li>neighbors: 1 2 3 </li>
+</ul>
+</li>
+</ul>
+</blockquote>
+<p>A facet may be simplicial or non-simplicial. In 3-d, a
+<i>simplicial facet</i> has three vertices and three
+neighbors. A <i>nonsimplicial facet</i> has more than
+three vertices and more than three neighbors. A
+nonsimplicial facet has a set of ridges and a centrum. </p>
+<p>
+A simplicial facet has an orientation. An <i>orientation</i>
+is either <i>top</i> or <i>bottom</i>.
+The flag, <tt>facet-&gt;toporient,</tt>
+defines the orientation of the facet's vertices. For example in 3-d,
+'top' is left-handed orientation (i.e., the vertex order follows the direction
+of the left-hand fingers when the thumb is pointing away from the center).
+Except for axis-parallel facets in 5-d and higher, topological orientation
+determines the geometric orientation of the facet's hyperplane.
+
+<p>A nonsimplicial facet is due to merging two or more
+facets. The facet's ridge set determine a simplicial
+decomposition of the facet. Each ridge is a 1-face (i.e.,
+it has two vertices and two neighboring facets). The
+orientation of a ridge is determined by the order of the
+neighboring facets. The flag, <tt>facet-&gt;toporient,</tt>is
+ignored. </p>
+<p>A nonsimplicial facet has a centrum for testing
+convexity. A <i>centrum</i> is a point on the facet's
+hyperplane that is near the center of the facet. Except
+for large facets, it is the arithmetic average of the
+facet's vertices. </p>
+<p>A nonsimplicial facet is an approximation that is
+defined by offsets from the facet's hyperplane. When
+Qhull finishes, the <i>outer plane</i> is above all
+points while the <i>inner plane</i> is below the facet's
+vertices. This guarantees that any exact convex hull
+passes between the inner and outer planes. The outer
+plane is defined by <tt>facet-&gt;maxoutside</tt> while
+the inner plane is computed from the facet's vertices.</p>
+
+<p>Qhull 3.1 includes triangulation of non-simplicial facets
+('<a href="../../html/qh-optq.htm#Qt">Qt</a>').
+These facets,
+called <i>tricoplanar</i>, share the same normal. centrum, and Voronoi center.
+One facet (keepcentrum) owns these data structures.
+While tricoplanar facets are more accurate than the simplicial facets from
+joggled input, they
+may have zero area or flipped orientation.
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <b>Poly</b>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="poly_r.c">poly_r.c</a>,
+<a href="poly2_r.c">poly2_r.c</a>, <a href="poly_r.h">poly_r.h</a>,
+and <a href="libqhull_r.h">libqhull_r.h</a></h3>
+<ul>
+<li><a href="#ptype">Data types and global
+lists for polyhedrons</a> </li>
+<li><a href="#pconst">poly_r.h constants</a> </li>
+<li><a href="#pgall">Global FORALL macros</a> </li>
+<li><a href="#pall">FORALL macros</a> </li>
+<li><a href="#peach">FOREACH macros</a> </li>
+<li><a href="#pieach">Indexed FOREACH macros</a> </li>
+<li><a href="#pmacro">Other macros for polyhedrons</a><p>&nbsp;</li>
+<li><a href="#plist">Facetlist functions</a> </li>
+<li><a href="#pfacet">Facet functions</a> </li>
+<li><a href="#pvertex">Vertex, ridge, and point
+functions</a> </li>
+<li><a href="#phash">Hashtable functions</a> </li>
+<li><a href="#pnew">Allocation and deallocation
+functions</a> </li>
+<li><a href="#pcheck">Check functions</a> </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="ptype">Data
+types and global lists for polyhedrons</a></h3>
+<ul>
+<li><a href="libqhull_r.h#facetT">facetT</a> defines a
+facet </li>
+<li><a href="libqhull_r.h#ridgeT">ridgeT</a> defines a
+ridge </li>
+<li><a href="libqhull_r.h#vertexT">vertexT</a> defines a
+vertex </li>
+<li><a href="libqhull_r.h#qh-lists">qh facet and vertex
+lists</a> lists of facets and vertices </li>
+<li><a href="libqhull_r.h#qh-set">qh global sets</a>
+global sets for merging, hashing, input, etc. </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pconst">poly_r.h constants</a></h3>
+<ul>
+<li><a href="poly_r.h#ALGORITHMfault">ALGORITHMfault</a>
+flag to not report errors in qh_checkconvex() </li>
+<li><a href="poly_r.h#DATAfault">DATAfault</a> flag to
+report errors in qh_checkconvex() </li>
+<li><a href="poly_r.h#DUPLICATEridge">DUPLICATEridge</a>
+special value for facet-&gt;neighbor to indicate
+a duplicate ridge </li>
+<li><a href="poly_r.h#MERGEridge">MERGEridge</a>
+special value for facet-&gt;neighbor to indicate
+a merged ridge </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pgall">Global FORALL
+macros</a></h3>
+<ul>
+<li><a href="libqhull_r.h#FORALLfacets">FORALLfacets</a>
+assign 'facet' to each facet in qh.facet_list </li>
+<li><a href="poly_r.h#FORALLnew_facets">FORALLnew_facets</a>
+assign 'facet' to each facet in qh.newfacet_list </li>
+<li><a href="poly_r.h#FORALLvisible_facets">FORALLvisible_facets</a>
+assign 'visible' to each visible facet in
+qh.visible_list </li>
+<li><a href="libqhull_r.h#FORALLpoints">FORALLpoints</a>
+assign 'point' to each point in qh.first_point,
+qh.num_points </li>
+<li><a href="libqhull_r.h#FORALLvertices">FORALLvertices</a>
+assign 'vertex' to each vertex in qh.vertex_list </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pall">FORALL macros</a></h3>
+<ul>
+<li><a href="poly_r.h#FORALLfacet_">FORALLfacet_</a>
+assign 'facet' to each facet in facetlist </li>
+<li><a href="libqhull_r.h#FORALLpoint_">FORALLpoint_</a>
+assign 'point' to each point in points array</li>
+<li><a href="poly_r.h#FORALLsame_">FORALLsame_</a>
+assign 'same' to each facet in samecycle</li>
+<li><a href="poly_r.h#FORALLsame_cycle_">FORALLsame_cycle_</a>
+assign 'same' to each facet in samecycle</li>
+<li><a href="poly_r.h#FORALLvertex_">FORALLvertex_</a>
+assign 'vertex' to each vertex in vertexlist </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="peach">FOREACH macros</a></h3>
+<ul>
+<li><a href="libqhull_r.h#FOREACHfacet_">FOREACHfacet_</a>
+assign 'facet' to each facet in facets </li>
+<li><a href="libqhull_r.h#FOREACHneighbor_">FOREACHneighbor_</a>
+assign 'neighbor' to each facet in
+facet-&gt;neighbors or vertex-&gt;neighbors</li>
+<li><a href="poly_r.h#FOREACHnewfacet_">FOREACHnewfacet_</a>
+assign 'newfacet' to each facet in facet set </li>
+<li><a href="libqhull_r.h#FOREACHpoint_">FOREACHpoint_</a>
+assign 'point' to each point in points set </li>
+<li><a href="libqhull_r.h#FOREACHridge_">FOREACHridge_</a>
+assign 'ridge' to each ridge in ridge set </li>
+<li><a href="libqhull_r.h#FOREACHvertex_">FOREACHvertex_</a>
+assign 'vertex' to each vertex in vertex set </li>
+<li><a href="poly_r.h#FOREACHvertexA_">FOREACHvertexA_</a>
+assign 'vertexA' to each vertex in vertex set</li>
+<li><a href="poly_r.h#FOREACHvisible_">FOREACHvisible_</a>
+assign 'visible' to each facet in facet set </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pieach">Indexed
+FOREACH macros</a></h3>
+<ul>
+<li><a href="libqhull_r.h#FOREACHfacet_i_">FOREACHfacet_i_</a>
+assign 'facet' and 'facet_i' to each facet in
+facet set </li>
+<li><a href="libqhull_r.h#FOREACHneighbor_i_">FOREACHneighbor_i_</a>
+assign 'neighbor' and 'neighbor_i' to each facet
+in facet-&gt;neighbors or vertex-&gt;neighbors</li>
+<li><a href="libqhull_r.h#FOREACHpoint_i_">FOREACHpoint_i_</a>
+assign 'point' and 'point_i' to each point in
+points set </li>
+<li><a href="libqhull_r.h#FOREACHridge_i_">FOREACHridge_i_</a>
+assign 'ridge' and 'ridge_i' to each ridge in
+ridges set </li>
+<li><a href="libqhull_r.h#FOREACHvertex_i_">FOREACHvertex_i_</a>
+assign 'vertex' and 'vertex_i' to each vertex in
+vertices set </li>
+<li><a href="poly_r.h#FOREACHvertexreverse12_">FOREACHvertexreverse12_</a>
+assign 'vertex' to each vertex in vertex set;
+reverse the order of first two vertices </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pmacro">Other macros for polyhedrons</a></h3>
+<ul>
+<li><a href="libqhull_r.h#getid_">getid_</a> return ID for
+a facet, ridge, or vertex </li>
+<li><a href="libqhull_r.h#otherfacet_">otherfacet_</a>
+return neighboring facet for a ridge in a facet </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="plist">Facetlist
+functions</a></h3>
+<ul>
+<li><a href="poly_r.c#appendfacet">qh_appendfacet</a>
+appends facet to end of qh.facet_list</li>
+<li><a href="poly_r.c#attachnewfacets">qh_attachnewfacets</a>
+attach new facets in qh.newfacet_list to the
+horizon </li>
+<li><a href="poly2_r.c#findgood">qh_findgood</a>
+identify good facets for qh.PRINTgood </li>
+<li><a href="poly2_r.c#findgood_all">qh_findgood_all</a>
+identify more good facets for qh.PRINTgood </li>
+<li><a href="poly2_r.c#furthestnext">qh_furthestnext</a>
+move facet with furthest of furthest points to
+facet_next </li>
+<li><a href="poly2_r.c#initialhull">qh_initialhull</a>
+construct the initial hull as a simplex of
+vertices </li>
+<li><a href="poly2_r.c#nearcoplanar">qh_nearcoplanar</a>
+ remove near-inside points from coplanar sets</li>
+<li><a href="poly2_r.c#prependfacet">qh_prependfacet</a>
+prepends facet to start of facetlist </li>
+<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
+print facets in a facetlist</li>
+<li><a href="poly2_r.c#printlists">qh_printlists</a>
+print out facet list for debugging </li>
+<li><a href="poly_r.c#removefacet">qh_removefacet</a>
+unlinks facet from qh.facet_list</li>
+<li><a href="poly2_r.c#resetlists">qh_resetlists</a>
+reset qh.newvertex_list, qh.newfacet_list, and
+qh.visible_list </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pfacet">Facet
+functions</a></h3>
+<ul>
+<li><a href="poly2_r.c#createsimplex">qh_createsimplex</a>
+create a simplex of facets from a set of vertices
+</li>
+<li><a href="poly2_r.c#findbestlower">qh_findbestlower</a> find best
+non-upper, non-flipped facet for point at upperfacet</li>
+<li><a href="poly2_r.c#furthestout">qh_furthestout</a>
+make furthest outside point the last point of a
+facet's outside set </li>
+<li><a href="poly_r.c#makenew_nonsimplicial">qh_makenew_nonsimplicial</a>
+make new facets from ridges of visible facets </li>
+<li><a href="poly_r.c#makenew_simplicial">qh_makenew_simplicial</a>
+make new facets for horizon neighbors </li>
+<li><a href="poly_r.c#makenewfacet">qh_makenewfacet</a>
+create a facet from vertices and apex </li>
+<li><a href="poly2_r.c#makenewfacets">qh_makenewfacets</a>
+make new facets from vertex, horizon facets, and
+visible facets </li>
+<li><a href="poly_r.c#makenewplanes">qh_makenewplanes</a>
+make new hyperplanes for facets </li>
+<li><a href="poly2_r.c#outcoplanar">qh_outcoplanar</a>
+move points from outside set to coplanar set </li>
+<li><a href="poly2_r.c#setvoronoi_all">qh_setvoronoi_all</a>
+compute Voronoi centers for all facets </li>
+<li><a href="poly2_r.c#triangulate">qh_triangulate</a>
+triangulate non-simplicial facets</li>
+<li><a href="poly2_r.c#triangulate_facet">qh_triangulate_facet</a>
+triangulate a non-simplicial facet</li>
+<li><a href="poly2_r.c#triangulate_link">qh_triangulate_link</a>
+link facets together from qh_triangulate</li>
+<li><a href="poly2_r.c#triangulate_mirror">qh_triangulate_mirror</a>
+delete mirrored facets from qh_triangulate</li>
+<li><a href="poly2_r.c#triangulate_null">qh_triangulate_null</a>
+delete null facet from qh_triangulate</li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pvertex">Vertex,
+ridge, and point functions</a></h3>
+<ul>
+<li><a href="poly_r.c#appendvertex">qh_appendvertex</a>
+append vertex to end of qh.vertex_list, </li>
+<li><a href="io_r.c#detvridge">qh_detvridge</a> determine Voronoi
+ridge for an input site
+<li><a href="io_r.c#detvridge3">qh_detvridge3</a> determine 3-d Voronoi
+ridge for an input site
+<li><a href="poly2_r.c#facet3vertex">qh_facet3vertex</a>
+return an oriented vertex set for a 3-d facet </li>
+<li><a href="poly_r.c#facetintersect">qh_facetintersect</a>
+return intersection of simplicial facets </li>
+<li><a href="poly2_r.c#initialvertices">qh_initialvertices</a>
+return non-singular set of initial vertices </li>
+<li><a href="poly2_r.c#isvertex">qh_isvertex</a> true
+if point is in a vertex set </li>
+<li><a href="poly2_r.c#nearvertex">qh_nearvertex</a>
+return nearest vertex to point </li>
+<li><a href="poly2_r.c#nextridge3d">qh_nextridge3d</a>
+iterate over each ridge and vertex for a 3-d
+facet </li>
+<li><a href="poly2_r.c#point">qh_point</a> return point
+for a point ID </li>
+<li><a href="poly2_r.c#pointfacet">qh_pointfacet</a>
+return temporary set of facets indexed by point
+ID </li>
+<li><a href="poly_r.c#pointid">qh_pointid</a> return ID
+for a point</li>
+<li><a href="poly2_r.c#pointvertex">qh_pointvertex</a>
+return temporary set of vertices indexed by point
+ID </li>
+<li><a href="poly_r.c#removevertex">qh_removevertex</a>
+unlink vertex from qh.vertex_list, </li>
+<li><a href="poly_r.c#updatevertices">qh_updatevertices</a>
+update vertex neighbors and delete interior
+vertices </li>
+<li><a href="poly2_r.c#vertexintersect">qh_vertexintersect</a>
+intersect two vertex sets </li>
+<li><a href="poly2_r.c#vertexintersect_new">qh_vertexintersect_new</a>
+return intersection of two vertex sets </li>
+<li><a href="poly2_r.c#vertexneighbors">qh_vertexneighbors</a>
+for each vertex in hull, determine facet
+neighbors </li>
+<li><a href="poly2_r.c#vertexsubset">qh_vertexsubset</a>
+returns True if vertexsetA is a subset of
+vertexsetB </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="phash">Hashtable functions</a></h3>
+<ul>
+<li><a href="poly2_r.c#addhash">qh_addhash</a> add hash
+element to linear hash table</li>
+<li><a href="poly_r.c#gethash">qh_gethash</a> return
+hash value for a set</li>
+<li><a href="poly2_r.c#matchduplicates">qh_matchduplicates</a>
+match duplicate ridges in hash table </li>
+<li><a href="poly_r.c#matchneighbor">qh_matchneighbor</a>
+try to match subridge of new facet with a
+neighbor </li>
+<li><a href="poly_r.c#matchnewfacets">qh_matchnewfacets</a>
+match new facets with their new facet neighbors </li>
+<li><a href="poly_r.c#matchvertices">qh_matchvertices</a>
+tests whether a facet and hash entry match at a
+ridge </li>
+<li><a href="poly2_r.c#newhashtable">qh_newhashtable</a>
+allocate a new qh_r.hash_table </li>
+<li><a href="poly2_r.c#printhashtable">qh_printhashtable</a>
+print hash table </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pnew">Allocation and
+deallocation functions</a></h3>
+<ul>
+<li><a href="poly2_r.c#clearcenters">qh_clearcenters</a>
+clear old data from facet-&gt;center </li>
+<li><a href="poly_r.c#deletevisible">qh_deletevisible</a>
+delete visible facets and vertices </li>
+<li><a href="poly_r.c#delfacet">qh_delfacet</a> free up
+the memory occupied by a facet </li>
+<li><a href="poly2_r.c#delridge">qh_delridge</a> delete
+ridge</li>
+<li><a href="poly2_r.c#delvertex">qh_delvertex</a>
+delete vertex </li>
+<li><a href="poly_r.c#newfacet">qh_newfacet</a> create
+and allocate space for a facet </li>
+<li><a href="poly_r.c#newridge">qh_newridge</a> create
+and allocate space for a ridge </li>
+<li><a href="poly2_r.c#newvertex">qh_newvertex</a>
+create and allocate space for a vertex </li>
+</ul>
+<h3><a href="qh-poly_r.htm#TOC">&#187;</a><a name="pcheck">Check
+functions</a></h3>
+<ul>
+<li><a href="poly2_r.c#check_bestdist">qh_check_bestdist</a>
+check that points are not outside of facets </li>
+<li><a href="poly2_r.c#check_dupridge">qh_check_dupridge</a>
+check duplicate ridge between facet1 and facet2 for wide merge </li>
+<li><a href="poly2_r.c#check_maxout">qh_check_maxout</a>
+updates qh.max_outside and checks all points
+against bestfacet </li>
+<li><a href="poly2_r.c#check_output">qh_check_output</a>
+check topological and geometric output</li>
+<li><a href="poly2_r.c#check_point">qh_check_point</a>
+check that point is not outside of facet </li>
+<li><a href="poly2_r.c#check_points">qh_check_points</a>
+check that all points are inside all facets </li>
+<li><a href="poly2_r.c#checkconvex">qh_checkconvex</a>
+check that each ridge in facetlist is convex </li>
+<li><a href="poly2_r.c#checkfacet">qh_checkfacet</a>
+check for consistency errors in facet </li>
+<li><a href="poly_r.c#checkflipped">qh_checkflipped</a>
+check facet orientation to the interior point </li>
+<li><a href="poly2_r.c#checkflipped_all">qh_checkflipped_all</a>
+check facet orientation for a facet list </li>
+<li><a href="poly2_r.c#checkpolygon">qh_checkpolygon</a>
+check topological structure </li>
+<li><a href="poly2_r.c#checkvertex">qh_checkvertex</a>
+check vertex for consistency </li>
+<li><a href="poly2_r.c#infiniteloop">qh_infiniteloop</a>
+report error for a loop of facets </li>
+<li><a href="poly2_r.c#printlists">qh_printlists</a>
+print out facet list for debugging </li>
+</ul>
+
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull_r/qh-qhull_r.htm b/xs/src/qhull/src/libqhull_r/qh-qhull_r.htm
new file mode 100644
index 000000000..25d5e4972
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qh-qhull_r.htm
@@ -0,0 +1,279 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>libqhull_r.c -- top-level functions and basic data types</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+<hr>
+
+<h2>libqhull_r.c -- top-level functions and basic data types</h2>
+<blockquote>
+<p>Qhull implements the Quickhull algorithm for computing
+the convex hull. The Quickhull algorithm combines two
+well-known algorithms: the 2-d quickhull algorithm and
+the n-d beneath-beyond algorithm. See
+<a href="../../html/index.htm#description">Description of Qhull</a>. </p>
+<p>This section provides an index to the top-level
+functions and base data types. The top-level header file, <tt>libqhull_r.h</tt>,
+contains prototypes for these functions.</p>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <b>Qhull</b> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="libqhull_r.c">libqhull_r.c</a>,
+<a href="libqhull_r.h">libqhull_r.h</a>, and
+<a href="../qhull/unix_r.c">unix_r.c</a></h3>
+<ul>
+<li><a href="#qtype">libqhull_r.h and unix_r.c data types and
+constants</a> </li>
+<li><a href="#qmacro">libqhull_r.h other macros</a> </li>
+<li><a href="#qfunc">Quickhull routines in call order</a> </li>
+<li><a href="#qinit">Top-level routines for initializing and terminating Qhull</a></li>
+<li><a href="#qin">Top-level routines for reading and modifying the input</a></li>
+<li><a href="#qcall">Top-level routines for calling Qhull</a></li>
+<li><a href="#qout">Top-level routines for returning results</a></li>
+<li><a href="#qtest">Top-level routines for testing and debugging</a></li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qtype">libqhull_r.h and unix_r.c
+data types and constants</a></h3>
+<ul>
+<li><a href="libqhull_r.h#flagT">flagT</a> Boolean flag as
+a bit </li>
+<li><a href="libqhull_r.h#boolT">boolT</a> boolean value,
+either True or False </li>
+<li><a href="libqhull_r.h#CENTERtype">CENTERtype</a> to
+distinguish facet-&gt;center </li>
+<li><a href="libqhull_r.h#qh_PRINT">qh_PRINT</a> output
+formats for printing (qh.PRINTout) </li>
+<li><a href="libqhull_r.h#qh_ALL">qh_ALL</a> argument flag
+for selecting everything </li>
+<li><a href="libqhull_r.h#qh_ERR">qh_ERR</a> Qhull exit
+codes for indicating errors </li>
+<li><a href="libqhull_r.h#qh_FILEstderr">qh_FILEstderr</a> Fake stderr
+to distinguish error output from normal output [C++ only]</li>
+<li><a href="../qhull/unix_r.c#prompt">qh_prompt</a> version and long prompt for Qhull</li>
+<li><a href="../qhull/unix_r.c#prompt2">qh_prompt2</a> synopsis for Qhull</li>
+<li><a href="../qhull/unix_r.c#prompt3">qh_prompt3</a> concise prompt for Qhull</li>
+<li><a href="global_r.c#qh_version">qh_version</a> version stamp</li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qmacro">libqhull_r.h other
+macros</a></h3>
+<ul>
+<li><a href="qhull_ra.h#traceN">traceN</a> print trace
+message if <em>qh.IStracing &gt;= N</em>. </li>
+<li><a href="qhull_ra.h#QHULL_UNUSED">QHULL_UNUSED</a> declare an
+ unused variable to avoid warnings. </li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qfunc">Quickhull
+routines in call order</a></h3>
+<ul>
+<li><a href="../qhull/unix_r.c#main">main</a> processes the
+command line, calls qhull() to do the work, and
+exits </li>
+<li><a href="libqhull_r.c#qhull">qh_qhull</a> construct
+the convex hull of a set of points </li>
+<li><a href="libqhull_r.c#build_withrestart">qh_build_withrestart</a>
+allow restarts while calling qh_buildhull</li>
+<li><a href="poly2_r.c#initbuild">qh_initbuild</a>
+initialize hull and outside sets with point array</li>
+<li><a href="libqhull_r.c#partitionall">qh_partitionall</a>
+partition all points into outside sets </li>
+<li><a href="libqhull_r.c#buildhull">qh_buildhull</a>
+construct a convex hull by adding points one at a
+time </li>
+<li><a href="libqhull_r.c#nextfurthest">qh_nextfurthest</a>
+return next furthest point for processing </li>
+<li><a href="libqhull_r.c#buildtracing">qh_buildtracing</a>
+trace an iteration of buildhull </li>
+<li><a href="libqhull_r.c#addpoint">qh_addpoint</a> add a
+point to the convex hull </li>
+<li><a href="libqhull_r.c#findhorizon">qh_findhorizon</a>
+find the horizon and visible facets for a point </li>
+<li><a href="libqhull_r.c#partitionvisible">qh_partitionvisible</a>
+partition points from facets in qh.visible_list
+to facets in qh.newfacet_list </li>
+<li><a href="libqhull_r.c#partitionpoint">qh_partitionpoint</a>
+partition a point as inside, coplanar with, or
+outside a facet </li>
+<li><a href="libqhull_r.c#partitioncoplanar">qh_partitioncoplanar</a>
+partition coplanar point into a facet </li>
+<li><a href="libqhull_r.c#precision">qh_precision</a> restart on precision errors if not merging and if 'QJn'</li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qinit">Top-level routines for initializing and terminating Qhull (in other modules)</a></h3>
+<ul>
+<li><a href="global_r.c#freebuild">qh_freebuild</a>
+free memory used by qh_initbuild and qh_buildhull
+</li>
+<li><a href="global_r.c#checkflags">qh_checkflags</a>
+check flags for multiple frontends to qhull
+<li><a href="global_r.c#freeqhull">qh_freeqhull</a>
+free memory used by qhull </li>
+<li><a href="global_r.c#init_A">qh_init_A</a> called
+before error handling initialized </li>
+<li><a href="global_r.c#init_B">qh_init_B</a> called
+after points are defined </li>
+<li><a href="global_r.c#initflags">qh_initflags</a> set
+flags and constants from command line </li>
+<li><a href="rboxlib_r.c#rboxpoints">qh_rboxpoints</a>
+generate points for qhull </li>
+<li><a href="global_r.c#restore_qhull">qh_restore_qhull</a>
+restores a saved qhull </li>
+<li><a href="global_r.c#save_qhull">qh_save_qhull</a>
+saves qhull for later restoring </li>
+<li><a href="user_r.c#user_memsizes">qh_user_memsizes</a>
+define additional quick allocation sizes
+</li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qin">Top-level routines for reading and modifying the input (in other modules)</a></h3>
+<ul>
+<li><a href="geom2_r.c#gram_schmidt">qh_gram_schmidt</a>
+implements Gram-Schmidt orthogonalization by rows </li>
+<li><a href="geom2_r.c#projectinput">qh_projectinput</a>
+project input along one or more dimensions +
+Delaunay projection </li>
+<li><a href="geom2_r.c#randommatrix">qh_randommatrix</a>
+generate a random dimXdim matrix in range (-1,1) </li>
+<li><a href="io_r.c#readpoints">qh_readpoints</a> read
+points from input </li>
+<li><a href="geom2_r.c#rotateinput">qh_rotateinput</a> rotate
+input points using row matrix </li>
+<li><a href="geom2_r.c#scaleinput">qh_scaleinput</a> scale
+input points using qh low_bound/high_bound </li>
+<li><a href="geom2_r.c#setdelaunay">qh_setdelaunay</a> project
+points to paraboloid for Delaunay triangulation </li>
+<li><a href="geom2_r.c#sethalfspace_all">qh_sethalfspace_all</a>
+generate dual for halfspace intersection with interior
+point </li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qcall">Top-level routines for calling Qhull (in other modules)</a></h3>
+<ul>
+<li><a href="libqhull_r.c#addpoint">qh_addpoint</a> add
+point to convex hull </li>
+<li><a href="poly2_r.c#findbestfacet">qh_findbestfacet</a>
+find facet that is furthest below a point </li>
+<li><a href="poly2_r.c#findfacet_all">qh_findfacet_all</a>
+exhaustive search for facet below a point </li>
+<li><a href="libqhull_r.c#qhull">qh_qhull</a> construct
+the convex hull of a set of points </li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qout">Top-level routines for returning results (in other modules)</a></h3>
+<ul>
+<li><a href="stat_r.c#collectstatistics">qh_collectstatistics</a>
+collect statistics for qh.facet_list </li>
+<li><a href="poly2_r.c#nearvertex">qh_nearvertex</a>
+return nearest vertex to point </li>
+<li><a href="poly2_r.c#point">qh_point</a> return point
+for a point ID </li>
+<li><a href="poly2_r.c#pointfacet">qh_pointfacet</a>
+return temporary set of facets indexed by point
+ID </li>
+<li><a href="poly_r.c#pointid">qh_pointid</a> return ID
+for a point</li>
+<li><a href="poly2_r.c#pointvertex">qh_pointvertex</a>
+return vertices (if any) for all points</li>
+<li><a href="stat_r.c#printallstatistics">qh_printallstatistics</a>
+print all statistics </li>
+<li><a href="io_r.c#printneighborhood">qh_printneighborhood</a>
+print neighborhood of one or two facets </li>
+<li><a href="libqhull_r.c#printsummary">qh_printsummary</a>
+print summary </li>
+<li><a href="io_r.c#produce_output">qh_produce_output</a>
+print the results of qh_qhull() </li>
+<li><a href="poly2_r.c#setvoronoi_all">qh_setvoronoi_all</a>
+compute Voronoi centers for all facets </li>
+</ul>
+
+<h3><a href="qh-qhull_r.htm#TOC">&#187;</a><a name="qtest">Top-level routines for testing and debugging (in other modules)</a></h3>
+<ul>
+<li><a href="io_r.c#dfacet">dfacet</a> print facet by
+ID from debugger </li>
+<li><a href="io_r.c#dvertex">dvertex</a> print vertex
+by ID from debugger </li>
+<li><a href="poly2_r.c#check_output">qh_check_output</a>
+check output </li>
+<li><a href="poly2_r.c#check_points">qh_check_points</a>
+verify that all points are inside the convex hull
+</li>
+<li><a href="user_r.c#errexit">qh_errexit</a> report
+error with a facet and a ridge</li>
+<li><a href="libqhull_r.c#errexit2">qh_errexit2</a> report
+error with two facets </li>
+<li><a href="user_r.c#errprint">qh_errprint</a> print
+erroneous facets, ridge, and vertex </li>
+<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
+print all fields for a list of facets </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull_r/qh-set_r.htm b/xs/src/qhull/src/libqhull_r/qh-set_r.htm
new file mode 100644
index 000000000..cf8ab63af
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qh-set_r.htm
@@ -0,0 +1,308 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>qset_r.c -- set data type and operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+<hr>
+
+<h2>qset_r.c -- set data type and operations</h2>
+<blockquote>
+<p>Qhull's data structures are constructed from sets. The
+functions and macros in qset_r.c construct, iterate, and
+modify these sets. They are the most frequently called
+functions in Qhull. For this reason, efficiency is the
+primary concern. </p>
+<p>In Qhull, a <i>set</i> is represented by an unordered
+array of pointers with a maximum size and a NULL
+terminator (<a href="qset_r.h#setT">setT</a>).
+Most sets correspond to mathematical sets
+(i.e., the pointers are unique). Some sets are sorted to
+enforce uniqueness. Some sets are ordered. For example,
+the order of vertices in a ridge determine the ridge's
+orientation. If you reverse the order of adjacent
+vertices, the orientation reverses. Some sets are not
+mathematical sets. They may be indexed as an array and
+they may include NULL pointers. </p>
+<p>The most common operation on a set is to iterate its
+members. This is done with a 'FOREACH...' macro. Each set
+has a custom macro. For example, 'FOREACHvertex_'
+iterates over a set of vertices. Each vertex is assigned
+to the variable 'vertex' from the pointer 'vertexp'. </p>
+<p>Most sets are constructed by appending elements to the
+set. The last element of a set is either NULL or the
+index of the terminating NULL for a partially full set.
+If a set is full, appending an element copies the set to
+a larger array. </p>
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a> &#149;
+<a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a> &#149;
+<a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <b>Set</b>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="qset_r.c">qset_r.c</a> and
+<a href="qset_r.h">qset_r.h</a></h3>
+<ul>
+<li><a href="#stype">Data types and constants</a> </li>
+<li><a href="#seach">FOREACH macros</a> </li>
+<li><a href="#saccess">access and size macros</a> </li>
+<li><a href="#sint">internal macros</a> </li>
+<li><a href="#saddr">address macros</a><p>&nbsp;</li>
+
+<li><a href="#snew">Allocation and deallocation functions</a> </li>
+<li><a href="#spred">Access and predicate functions</a>
+</li>
+<li><a href="#sadd">Add functions</a> </li>
+<li><a href="#scheck">Check and print functions</a></li>
+<li><a href="#scopy">Copy, compact, and zero functions</a></li>
+<li><a href="#sdel">Delete functions</a> </li>
+<li><a href="#stemp">Temporary set functions</a> </li>
+</ul>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="stype">Data types and
+constants</a></h3>
+<ul>
+<li><a href="qset_r.h#SETelemsize">SETelemsize</a> size
+of a set element in bytes </li>
+<li><a href="qset_r.h#setT">setT</a> a set with a
+maximum size and a current size</li>
+<li><a href="libqhull_r.h#qh-set">qh global sets</a>
+global sets for temporary sets, etc. </li>
+</ul>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="seach">FOREACH macros</a></h3>
+<ul>
+<li><a href="qset_r.h#FOREACHelem_">FOREACHelem_</a>
+assign 'elem' to each element in a set </li>
+<li><a href="qset_r.h#FOREACHset_">FOREACHset_</a>
+assign 'set' to each set in a set of sets </li>
+<li><a href="qset_r.h#FOREACHsetelement_">FOREACHsetelement_</a>
+define a FOREACH iterator </li>
+<li><a href="qset_r.h#FOREACHsetelement_i_">FOREACHsetelement_i_</a>
+define an indexed FOREACH iterator </li>
+<li><a href="qset_r.h#FOREACHsetelementreverse_">FOREACHsetelementreverse_</a>
+define a reversed FOREACH iterator </li>
+<li><a href="qset_r.h#FOREACHsetelementreverse12_">FOREACHsetelementreverse12_</a>
+define a FOREACH iterator with e[1] and e[0]
+reversed </li>
+</ul>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="saccess">Access and
+size macros</a></h3>
+<ul>
+<li><a href="qset_r.h#SETelem_">SETelem_</a> return the
+n'th element of set </li>
+<li><a href="qset_r.h#SETelemt_">SETelemt_</a> return
+the n'th element of set as a type</li>
+<li><a href="qset_r.h#SETempty_">SETempty_</a> return
+true (1) if set is empty </li>
+<li><a href="qset_r.h#SETfirst_">SETfirst_</a> return
+first element of set </li>
+<li><a href="qset_r.h#SETfirstt_">SETfirstt_</a> return
+first element of set as a type</li>
+<li><a href="qset_r.h#SETindex_">SETindex_</a> return
+index of elem in set </li>
+<li><a href="qset_r.h#SETreturnsize_">SETreturnsize_</a>
+return size of a set (normally use <a href="qset_r.c#setsize">qh_setsize</a>) </li>
+<li><a href="qset_r.h#SETsecond_">SETsecond_</a> return
+second element of set </li>
+<li><a href="qset_r.h#SETsecondt_">SETsecondt_</a>
+return second element of set as a type</li>
+<li><a href="qset_r.h#SETtruncate_">SETtruncate_</a>
+truncate set to size, i.e., qh_settruncate()</li>
+</ul>
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="sint">Internal macros</a></h3>
+<ul>
+<li><a href="qset_r.c#SETsizeaddr_">SETsizeaddr_</a>
+return pointer to end element of a set (indicates
+current size) </li>
+</ul>
+
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="saddr">address macros</a></h3>
+<ul>
+<li><a href="qset_r.h#SETaddr_">SETaddr_</a> return
+address of a set's elements </li>
+<li><a href="qset_r.h#SETelemaddr_">SETelemaddr_</a>
+return address of the n'th element of a set </li>
+<li><a href="qset_r.h#SETref_">SETref_</a> l_r.h.s. for
+modifying the current element in a FOREACH
+iteration </li>
+</ul>
+
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="snew">Allocation and
+deallocation functions</a></h3>
+<ul>
+<li><a href="qset_r.c#setfree">qh_setfree</a> free the
+space occupied by a set </li>
+<li><a href="qset_r.c#setfree2">qh_setfree2</a> free a
+set and its elements </li>
+<li><a href="qset_r.c#setfreelong">qh_setfreelong</a>
+free a set only if it is in long memory </li>
+<li><a href="qset_r.c#setnew">qh_setnew</a> create a new
+set </li>
+</ul>
+
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="spred">Access and
+predicate functions </a></h3>
+<ul>
+<li><a href="qset_r.c#setendpointer">qh_setendpointer</a> return
+pointer to NULL terminator of a set</li>
+<li><a href="qset_r.c#setequal">qh_setequal</a> return 1
+if two sorted sets are equal </li>
+<li><a href="qset_r.c#setequal_except">qh_setequal_except</a>
+return 1 if two sorted sets are equal except for
+an element </li>
+<li><a href="qset_r.c#setequal_skip">qh_setequal_skip</a>
+return 1 if two sorted sets are equal except for
+a pair of skipped elements </li>
+<li><a href="qset_r.c#setequal_skip">qh_setequal_skip</a>
+return 1 if two sorted sets are equal except for
+a pair of skipped elements </li>
+<li><a href="qset_r.c#setin">qh_setin</a> return 1 if an
+element is in a set </li>
+<li><a href="qset_r.c#setindex">qh_setindex</a> return
+the index of an element in a set </li>
+<li><a href="qset_r.c#setlast">qh_setlast</a> return
+last element of a set</li>
+<li><a href="qset_r.c#setsize">qh_setsize</a> returns
+the size of a set </li>
+</ul>
+
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="sadd">Add functions</a></h3>
+<ul>
+<li><a href="qset_r.c#setaddnth">qh_setaddnth</a> add a
+element as n'th element of sorted or unsorted set
+</li>
+<li><a href="qset_r.c#setaddsorted">qh_setaddsorted</a>
+add an element to a sorted set </li>
+<li><a href="qset_r.c#setappend">qh_setappend</a> append
+an element to a set </li>
+<li><a href="qset_r.c#setappend_set">qh_setappend_set</a>
+append a set of elements to a set </li>
+<li><a href="qset_r.c#setappend2ndlast">qh_setappend2ndlast</a>
+add an element as the next to the last element in
+a set </li>
+<li><a href="qset_r.c#setlarger">qh_setlarger</a> return
+a larger set with the same elements</li>
+<li><a href="qset_r.c#setreplace">qh_setreplace</a>
+replace one element with another in a set</li>
+<li><a href="qset_r.c#setunique">qh_setunique</a> add an
+element if it is not already in a set </li>
+</ul>
+
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="scheck">Check and print functions</a></h3>
+<ul>
+<li><a href="qset_r.c#setcheck">qh_setcheck</a> check a
+set for validity </li>
+<li><a href="qset_r.c#setprint">qh_setprint</a> print a
+set's elements to fp </li>
+</ul>
+
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="scopy">Copy, compact, and zero functions</a></h3>
+<ul>
+<li><a href="qset_r.c#setcompact">qh_setcompact</a>
+compact NULLs from an unsorted set </li>
+<li><a href="qset_r.c#setcopy">qh_setcopy</a> make a
+copy of a sorted or unsorted set </li>
+<li><a href="qset_r.c#setduplicate">qh_setduplicate</a>
+duplicate a set and its elements </li>
+<li><a href="qset_r.c#settruncate">qh_settruncate</a>
+truncate a set to size elements </li>
+<li><a href="qset_r.c#setzero">qh_setzero</a> zero the
+remainder of a set </li>
+</ul>
+
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="sdel">Delete functions</a></h3>
+<ul>
+<li><a href="qset_r.c#setdel">qh_setdel</a> delete an
+element from an unsorted set. </li>
+<li><a href="qset_r.c#setdellast">qh_setdellast</a>
+delete and return last element from a set</li>
+<li><a href="qset_r.c#setdelnth">qh_setdelnth</a> delete
+and return nth element from an unsorted set </li>
+<li><a href="qset_r.c#setdelnthsorted">qh_setdelnthsorted</a>
+delete and return nth element from a sorted set </li>
+<li><a href="qset_r.c#setdelsorted">qh_setdelsorted</a>
+delete an element from a sorted set </li>
+<li><a href="qset_r.c#setnew_delnthsorted">qh_setnew_delnthsorted</a>
+create a sorted set not containing the nth
+element </li>
+</ul>
+
+<h3><a href="qh-set_r.htm#TOC">&#187;</a><a name="stemp">Temporary set functions</a></h3>
+<ul>
+<li><a href="qset_r.c#settemp">qh_settemp</a> return a
+temporary set and append it qhmem.tempstack</li>
+<li><a href="qset_r.c#settempfree">qh_settempfree</a>
+free and pop a set from qhmem.tempstack</li>
+<li><a href="qset_r.c#settempfree_all">qh_settempfree_all</a>
+free all sets in qhmem.tempstack </li>
+<li><a href="qset_r.c#settemppop">qh_settemppop</a> pop
+a set from qhmem.tempstack (makes it permanent) </li>
+<li><a href="qset_r.c#settemppush">qh_settemppush</a>
+push a set unto qhmem.tempstack (makes it
+temporary) </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull_r/qh-stat_r.htm b/xs/src/qhull/src/libqhull_r/qh-stat_r.htm
new file mode 100644
index 000000000..ea9d7fc56
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qh-stat_r.htm
@@ -0,0 +1,161 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>stat_r.c -- statistical operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <a href="qh-user_r.htm">User</a>
+</p>
+<hr>
+
+<h2>stat_r.c -- statistical operations</h2>
+<blockquote>
+<p>Qhull records many statistics. These functions and
+macros make it inexpensive to add a statistic.
+<p>As with Qhull's global variables, the statistics data structure is
+accessed by a macro, 'qhstat'. If qh_QHpointer is defined, the macro
+is 'qh_qhstat->', otherwise the macro is 'qh_qhstat.'.
+Statistics
+may be turned off in user_r.h. If so, all but the 'zz'
+statistics are ignored.</p>
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <b>Stat</b> &#149; <a href="qh-user_r.htm#TOC">User</a>
+</p>
+<h3>Index to <a href="stat_r.c">stat_r.c</a> and
+<a href="stat_r.h">stat_r.h</a></h3>
+<ul>
+<li><a href="#ttype">stat_r.h types</a> </li>
+<li><a href="#tconst">stat_r.h constants</a> </li>
+<li><a href="#tmacro">stat_r.h macros</a> </li>
+<li><a href="#tfunc">stat_r.c functions</a> </li>
+</ul>
+
+<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="ttype">stat_r.h types</a></h3>
+<ul>
+<li><a href="stat_r.h#intrealT">intrealT</a> union of
+integer and real</li>
+<li><a href="stat_r.h#qhstat">qhstat</a> global data
+structure for statistics </li>
+</ul>
+<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="tconst">stat_r.h
+constants</a></h3>
+<ul>
+<li><a href="stat_r.h#KEEPstatistics">qh_KEEPstatistics</a> 0 turns off most statistics</li>
+<li><a href="stat_r.h#statistics">Z..., W...</a> integer (Z) and real (W) statistics
+</li>
+<li><a href="stat_r.h#ZZstat">ZZstat</a> Z.../W... statistics that
+remain defined if qh_KEEPstatistics=0
+</li>
+<li><a href="stat_r.h#ztype">ztype</a> zdoc, zinc, etc.
+for definining statistics </li>
+</ul>
+<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="tmacro">stat_r.h macros</a></h3>
+<ul>
+<li><a href="stat_r.h#MAYdebugx">MAYdebugx</a> called
+frequently for error trapping </li>
+<li><a href="stat_r.h#zadd_">zadd_/wadd_</a> add value
+to an integer or real statistic </li>
+<li><a href="stat_r.h#zdef_">zdef_</a> define a
+statistic </li>
+<li><a href="stat_r.h#zinc_">zinc_</a> increment an
+integer statistic </li>
+<li><a href="stat_r.h#zmax_">zmax_/wmax_</a> update
+integer or real maximum statistic </li>
+<li><a href="stat_r.h#zmin_">zmin_/wmin_</a> update
+integer or real minimum statistic </li>
+<li><a href="stat_r.h#zval_">zval_/wval_</a> set or
+return value of a statistic </li>
+</ul>
+
+<h3><a href="qh-stat_r.htm#TOC">&#187;</a><a name="tfunc">stat_r.c
+functions</a></h3>
+<ul>
+<li><a href="stat_r.c#allstatA">qh_allstatA</a> define
+statistics in groups of 20 </li>
+<li><a href="stat_r.c#allstatistics">qh_allstatistics</a>
+reset printed flag for all statistics </li>
+<li><a href="stat_r.c#collectstatistics">qh_collectstatistics</a>
+collect statistics for qh.facet_list </li>
+<li><a href="stat_r.c#initstatistics">qh_initstatistics</a>
+allocate and initialize statistics </li>
+<li><a href="stat_r.c#newstats">qh_newstats</a> returns
+True if statistics for zdoc </li>
+<li><a href="stat_r.c#nostatistic">qh_nostatistic</a>
+true if no statistic to print </li>
+<li><a href="stat_r.c#printallstatistics">qh_printallstatistics</a>
+print all statistics </li>
+<li><a href="stat_r.c#printstatistics">qh_printstatistics</a>
+print statistics to a file </li>
+<li><a href="stat_r.c#printstatlevel">qh_printstatlevel</a>
+print level information for a statistic </li>
+<li><a href="stat_r.c#printstats">qh_printstats</a>
+print statistics for a zdoc group </li>
+<li><a href="stat_r.c#stddev">qh_stddev</a> compute the
+standard deviation and average from statistics </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull_r/qh-user_r.htm b/xs/src/qhull/src/libqhull_r/qh-user_r.htm
new file mode 100644
index 000000000..909fec656
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qh-user_r.htm
@@ -0,0 +1,271 @@
+<!-- Do not edit with Front Page, it adds too many spaces -->
+<html>
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<title>user_r.c -- user-definable operations</title>
+</head>
+
+<body>
+<!-- Navigation links -->
+<p><a name="TOP"><b>Up:</b></a> <a
+href="http://www.qhull.org">Home page</a> for Qhull<br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual</a>: Table of Contents <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a><br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149; <a href="qh-globa_r.htm">Global</a>
+&#149; <a href="qh-io_r.htm">Io</a> &#149; <a href="qh-mem_r.htm">Mem</a>
+&#149; <a href="qh-merge_r.htm">Merge</a> &#149; <a href="qh-poly_r.htm">Poly</a>
+&#149; <a href="qh-qhull_r.htm">Qhull</a> &#149; <a href="qh-set_r.htm">Set</a>
+&#149; <a href="qh-stat_r.htm">Stat</a> &#149; <a href="qh-user_r.htm#TOC">User</a>
+</p>
+<hr>
+<h2>user_r.c -- user-definable operations</h2>
+<blockquote>
+<p>This section contains functions and constants that the
+user may want to change. </p>
+
+</blockquote>
+<p><b>Copyright &copy; 1995-2015 C.B. Barber</b></p>
+<hr>
+<p><a href="#TOP">&#187;</a> <a href="qh-geom_r.htm#TOC">Geom</a>
+<a name="TOC">&#149;</a> <a href="qh-globa_r.htm#TOC">Global</a>
+&#149; <a href="qh-io_r.htm#TOC">Io</a> &#149; <a href="qh-mem_r.htm#TOC">Mem</a>
+&#149; <a href="qh-merge_r.htm#TOC">Merge</a> &#149; <a href="qh-poly_r.htm#TOC">Poly</a>
+&#149; <a href="qh-qhull_r.htm#TOC">Qhull</a> &#149; <a href="qh-set_r.htm#TOC">Set</a>
+&#149; <a href="qh-stat_r.htm#TOC">Stat</a> &#149; <b>User</b>
+</p>
+<h3>Index to <a href="user_r.c">user_r.c</a>, <a href="usermem_r.c">usermem_r.c</a>, <a href="userprintf_r.c">userprintf_r.c</a>, <a href="userprintf_rbox_r.c">userprintf_rbox_r.c</a> and
+<a href="user_r.h">user_r.h</a></h3>
+<ul>
+<li><a href="#qulllib">qhull library constants</a></li>
+<li><a href="#utype">user_r.h data types and
+configuration macros</a> </li>
+<li><a href="#ujoggle">joggle constants</a></li>
+<li><a href="#uperform">performance related constants</a></li>
+<li><a href="#umemory">memory constants</a></li>
+<li><a href="#ucond">conditional compilation</a></li>
+<li><a href="#umerge">merge constants</a> </li>
+<li><a href="#ufunc">user_r.c functions</a> </li>
+<li><a href="#u2func">usermem_r.c functions</a> </li>
+<li><a href="#u3func">userprintf_r.c functions</a> </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="qulllib">Qhull library constants</a></h3>
+<ul>
+<li><a href="user_r.h#filenamelen">FILENAMElen</a> -- max length of TI or TO filename </li>
+<li><a href="user_r.h#msgcode">msgcode</a> -- unique message codes for qh_fprintf </li>
+<li><a href="user_r.h#qh_OPTIONline">qh_OPTIONline</a> -- max length of option line ('FO')</li>
+</ul>
+
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="utype">user_r.h data
+types and configuration macros</a></h3>
+<ul>
+<li><a href="user_r.h#realT">realT, qh_REAL...</a> size
+of floating point numbers </li>
+<li><a href="user_r.h#countT">countT, COUNTmax</a> size
+of counts and identifiers, typically 'int' or 'long long' </li>
+<li><a href="user_r.h#CPUclock">qh_CPUclock</a> clock()
+function for reporting the total time spent by
+Qhull </li>
+<li><a href="user_r.h#RANDOM">qh_RANDOM...</a> random
+number generator </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="udef">definition constants</a></h3>
+<ul>
+<li><a href="user_r.h#DEFAULTbox">qh_DEFAULTbox</a>
+define default box size for rbox, 'Qbb', and 'QbB' (Geomview expects 0.5) </li>
+<li><a href="user_r.h#INFINITE">qh_INFINITE</a> on
+output, indicates Voronoi center at infinity </li>
+<li><a href="user_r.h#ORIENTclock">qh_ORIENTclock</a>
+define convention for orienting facets</li>
+<li><a href="user_r.h#ZEROdelaunay">qh_ZEROdelaunay</a>
+define facets that are ignored in Delaunay triangulations</li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="ujoggle">joggle constants</a></h3>
+<ul>
+<li><a href="user_r.h#JOGGLEagain">qh_JOGGLEagain</a>
+how often to retry before using qh_JOGGLEmaxincrease
+again </li>
+<li><a href="user_r.h#JOGGLEdefault">qh_JOGGLEdefault</a>
+default value for qh.JOGGLEmax for 'QP' </li>
+<li><a href="user_r.h#JOGGLEincrease">qh_JOGGLEincrease</a>
+factor to increase qh.JOGGLEmax on retrys for
+'QPn' </li>
+<li><a href="user_r.h#JOGGLEmaxincrease">qh_JOGGLEmaxincrease</a> max
+for increasing qh.JOGGLEmax relative to
+qh.MAXwidth </li>
+<li><a href="user_r.h#JOGGLEretry">qh_JOGGLEmaxretry</a>
+report error if this many retries </li>
+<li><a href="user_r.h#JOGGLEretry">qh_JOGGLEretry</a>
+how often to retry before using qh_JOGGLEmax </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="uperform">performance
+related constants</a></h3>
+<ul>
+<li><a href="user_r.h#HASHfactor">qh_HASHfactor</a>
+total/used hash slots </li>
+<li><a href="user_r.h#INITIALmax">qh_INITIALmax</a> if
+dim &gt;= qh_INITIALmax, use min/max coordinate
+points for initial simplex </li>
+<li><a href="user_r.h#INITIALsearch">qh_INITIALsearch</a>
+if qh.INITIALmax, search points up to this
+dimension </li>
+<li><a href="user_r.h#NOtrace">qh_NOtrace</a> disallow
+tracing </li>
+<li><a href="user_r.h#VERIFYdirect">qh_VERIFYdirect</a>
+'Tv' verifies all <em>points X facets</em> if op
+count is smaller </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="umemory">memory constants</a></h3>
+<ul>
+<li><a href="user_r.h#MEMalign">qh_MEMalign</a> memory
+alignment for qh_meminitbuffers() in global_r.c </li>
+<li><a href="user_r.h#MEMbufsize">qh_MEMbufsize</a>
+size of additional memory buffers </li>
+<li><a href="user_r.h#MEMinitbuf">qh_MEMinitbuf</a>
+size of initial memory buffer </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="ucond">conditional compilation</a></h3>
+<ul>
+<li><a href="user_r.h#compiler">compiler</a> defined symbols,
+e.g., _STDC_ and _cplusplus
+
+<li><a href="user_r.h#COMPUTEfurthest">qh_COMPUTEfurthest</a>
+ compute furthest distance to an outside point instead of storing it with the facet
+<li><a href="user_r.h#KEEPstatistics">qh_KEEPstatistics</a>
+ enable statistic gathering and reporting with option 'Ts'
+<li><a href="user_r.h#MAXoutside">qh_MAXoutside</a>
+record outer plane for each facet
+<li><a href="user_r.h#NOmerge">qh_NOmerge</a>
+disable facet merging
+<li><a href="user_r.h#NOtrace">qh_NOtrace</a>
+disable tracing with option 'T4'
+<li><a href="user_r.h#QHpointer">qh_QHpointer</a>
+access global data with pointer or static structure
+<li><a href="user_r.h#QUICKhelp">qh_QUICKhelp</a>
+use abbreviated help messages, e.g., for degenerate inputs
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="umerge">merge
+constants</a></h3>
+<ul>
+<li><a href="user_r.h#BESTcentrum">qh_BESTcentrum</a>
+when does qh_findbestneighbor() test centrums? </li>
+<li><a href="user_r.h#BESTnonconvex">qh_BESTnonconvex</a>
+when does qh_findbestneighbor() test nonconvex
+ridges only? </li>
+<li><a href="user_r.h#COPLANARratio">qh_COPLANARratio</a>
+what is qh.MINvisible? </li>
+<li><a href="user_r.h#DIMreduceBuild">qh_DIMreduceBuild</a>
+max dimension for vertex reduction </li>
+<li><a href="user_r.h#DIMmergeVertex">qh_DIMmergeVertex</a>
+max dimension for vertex merging </li>
+<li><a href="user_r.h#DISToutside">qh_DISToutside</a>
+when is a point clearly outside of a facet for qh_findbestnew and qh_partitionall</li>
+<li><a href="user_r.h#MAXnarrow">qh_MAXnarrow</a> max.
+cosine for qh.NARROWhull </li>
+<li><a href="user_r.h#MAXnewcentrum">qh_MAXnewcentrum</a>
+when does qh_reducevertices_centrum() reset the
+centrum? </li>
+<li><a href="user_r.h#MAXnewmerges">qh_MAXnewmerges</a>
+when does qh_merge_nonconvex() call
+qh_reducevertices_centrums? </li>
+<li><a href="user_r.h#RATIOnearinside">qh_RATIOnearinside</a>
+ratio for retaining inside points for
+qh_check_maxout() </li>
+<li><a href="user_r.h#SEARCHdist">qh_SEARCHdist</a>
+when is facet coplanar with the best facet for qh_findbesthorizon</li>
+<li><a href="user_r.h#USEfindbestnew">qh_USEfindbestnew</a>
+when to use qh_findbestnew for qh_partitionpoint()</li>
+<li><a href="user_r.h#WARNnarrow">qh_WARNnarrow</a>
+max. cosine to warn about qh.NARROWhull </li>
+<li><a href="user_r.h#WIDEcoplanar">qh_WIDEcoplanar</a>
+what is a wide facet? </li>
+<li><a href="user_r.h#WIDEduplicate">qh_WIDEduplicate</a>
+what is a wide ratio on merging duplicate ridges? </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="ufunc">user_r.c
+functions</a></h3>
+<ul>
+<li><a href="user_r.c#qhull_template">Qhull template</a> for calling qh_new_qhull from your program</li>
+<li><a href="user_r.c#errexit">qh_errexit</a> report
+error and exit qhull()</li>
+<li><a href="user_r.c#errprint">qh_errprint</a> print
+information about facets and ridges </li>
+<li><a href="user_r.c#new_qhull">qh_new_qhull</a> call qhull on an array
+of points</li>
+<li><a href="user_r.c#printfacetlist">qh_printfacetlist</a>
+print all fields of all facets </li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="u2func">usermem_r.c
+functions</a></h3>
+<ul>
+<li><a href="usermem_r.c#qh_exit">qh_exit</a> exit program, same as exit(). May be redefined as throw "QH10003.." by libqhullcpp/usermem_r-cpp.cpp</li>
+<li><a href="usermem_r.c#qh_fprintf_stderr">qh_fprintf_stderr</a> print to stderr when qh->ferr is not defined.</li>
+<li><a href="usermem_r.c#qh_free">qh_free</a> free memory, same as free().</li>
+<li><a href="usermem_r.c#qh_malloc">qh_malloc</a> allocate memory, same as malloc()</li>
+</ul>
+
+<h3><a href="qh-user_r.htm#TOC">&#187;</a><a name="u3func">userprintf_r.c
+ and userprintf_rbox,c functions</a></h3>
+<ul>
+<li><a href="userprintf_r.c#qh_fprintf">qh_fprintf</a> print
+information from Qhull, sames as fprintf(). </li>
+<li><a href="userprintf_rbox_r.c#qh_fprintf_rbox">qh_fprintf_rbox</a> print
+information from Rbox, sames as fprintf(). </li>
+</ul>
+
+<p><!-- Navigation links --> </p>
+<hr>
+<p><b>Up:</b>
+<a href="http://www.qhull.org">Home page for
+Qhull</a> <br>
+<b>Up:</b> <a href="../../html/index.htm#TOC">Qhull manual: Table of Contents</a> <br>
+<b>Up:</b> <a href="../../html/qh-quick.htm#programs">Programs</a>
+&#149; <a href="../../html/qh-quick.htm#options">Options</a>
+&#149; <a href="../../html/qh-opto.htm#output">Output</a>
+&#149; <a href="../../html/qh-optf.htm#format">Formats</a>
+&#149; <a href="../../html/qh-optg.htm#geomview">Geomview</a>
+&#149; <a href="../../html/qh-optp.htm#print">Print</a>
+&#149; <a href="../../html/qh-optq.htm#qhull">Qhull</a>
+&#149; <a href="../../html/qh-optc.htm#prec">Precision</a>
+&#149; <a href="../../html/qh-optt.htm#trace">Trace</a>
+&#149; <a href="index.htm">Functions</a><br>
+<b>Up:</b> <a href="../../html/qh-code.htm#TOC">Qhull code: Table of Contents</a> <br>
+<b>To:</b> <a href="index.htm">Qhull functions</a>, macros, and data structures<br>
+<b>To:</b> <a href="qh-geom_r.htm">Geom</a> &#149;
+<a href="qh-globa_r.htm">Global</a> &#149; <a href="qh-io_r.htm">Io</a>
+&#149; <a href="qh-mem_r.htm">Mem</a> &#149; <a href="qh-merge_r.htm">Merge</a>
+&#149; <a href="qh-poly_r.htm">Poly</a> &#149; <a href="qh-qhull_r.htm#TOC">Qhull</a>
+&#149; <a href="qh-set_r.htm">Set</a> &#149; <a href="qh-stat_r.htm">Stat</a>
+&#149; <a href="qh-user_r.htm">User</a><br>
+</p>
+<p><!-- GC common information --> </p>
+<hr>
+<p><a href="http://www.geom.uiuc.edu/"><img
+src="../../html/qh--geom.gif" align="middle" width="40" height="40"></a><i>The
+Geometry Center Home Page </i></p>
+<p>Comments to: <a href=mailto:qhull@qhull.org>qhull@qhull.org</a>
+</a><br>
+Created: May 2, 1997 --- <!-- hhmts start --> Last modified: see top <!-- hhmts end --> </p>
+</body>
+</html>
diff --git a/xs/src/qhull/src/libqhull_r/qhull_r-exports.def b/xs/src/qhull/src/libqhull_r/qhull_r-exports.def
new file mode 100644
index 000000000..325d57c3b
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qhull_r-exports.def
@@ -0,0 +1,404 @@
+; qhull_r-exports.def -- msvc module-definition file
+;
+; Generated from depends.exe by cut-and-paste of exported symbols by mingw gcc
+; [jan'14] 391 symbols
+; Same as ../libqhullp/qhull-exports.def without DATA items (reentrant)
+;
+; $Id: //main/2015/qhull/src/libqhull_r/qhull_r-exports.def#3 $$Change: 2047 $
+; $DateTime: 2016/01/04 22:03:18 $$Author: bbarber $
+;
+; Define qhull_VERSION in CMakeLists.txt, Makefile, qhull-exports.def, qhull_p-exports.def, qhull_r-exports.def, and qhull-warn.pri
+VERSION 7.0
+EXPORTS
+qh_addhash
+qh_addpoint
+qh_all_merges
+qh_allstatA
+qh_allstatB
+qh_allstatC
+qh_allstatD
+qh_allstatE
+qh_allstatE2
+qh_allstatF
+qh_allstatG
+qh_allstatH
+qh_allstatI
+qh_allstatistics
+qh_appendfacet
+qh_appendmergeset
+qh_appendprint
+qh_appendvertex
+qh_argv_to_command
+qh_argv_to_command_size
+qh_attachnewfacets
+qh_backnormal
+qh_basevertices
+qh_build_withrestart
+qh_buildhull
+qh_buildtracing
+qh_check_bestdist
+qh_check_dupridge
+qh_check_maxout
+qh_check_output
+qh_check_point
+qh_check_points
+qh_checkconnect
+qh_checkconvex
+qh_checkfacet
+qh_checkflags
+qh_checkflipped
+qh_checkflipped_all
+qh_checkpolygon
+qh_checkvertex
+qh_checkzero
+qh_clear_outputflags
+qh_clearcenters
+qh_clock
+qh_collectstatistics
+qh_compare_facetarea
+qh_compare_facetmerge
+qh_compare_facetvisit
+qh_compareangle
+qh_comparemerge
+qh_comparevisit
+qh_copyfilename
+qh_copynonconvex
+qh_copypoints
+qh_countfacets
+qh_createsimplex
+qh_crossproduct
+qh_degen_redundant_facet
+qh_degen_redundant_neighbors
+qh_deletevisible
+qh_delfacet
+qh_delridge
+qh_delvertex
+qh_determinant
+qh_detjoggle
+qh_detroundoff
+qh_detsimplex
+qh_detvnorm
+qh_detvridge
+qh_detvridge3
+qh_dfacet
+qh_distnorm
+qh_distplane
+qh_distround
+qh_divzero
+qh_dvertex
+qh_eachvoronoi
+qh_eachvoronoi_all
+qh_errexit
+qh_errexit2
+qh_errexit_rbox
+qh_errprint
+qh_exit
+qh_facet2point
+qh_facet3vertex
+qh_facetarea
+qh_facetarea_simplex
+qh_facetcenter
+qh_facetintersect
+qh_facetvertices
+qh_find_newvertex
+qh_findbest
+qh_findbest_test
+qh_findbestfacet
+qh_findbesthorizon
+qh_findbestlower
+qh_findbestneighbor
+qh_findbestnew
+qh_findfacet_all
+qh_findgood
+qh_findgood_all
+qh_findgooddist
+qh_findhorizon
+qh_flippedmerges
+qh_forcedmerges
+qh_fprintf
+qh_fprintf_rbox
+qh_fprintf_stderr
+qh_free
+qh_freebuffers
+qh_freebuild
+qh_freeqhull
+qh_furthestnext
+qh_furthestout
+qh_gausselim
+qh_geomplanes
+qh_getangle
+qh_getarea
+qh_getcenter
+qh_getcentrum
+qh_getdistance
+qh_gethash
+qh_getmergeset
+qh_getmergeset_initial
+qh_gram_schmidt
+qh_hashridge
+qh_hashridge_find
+qh_infiniteloop
+qh_init_A
+qh_init_B
+qh_init_qhull_command
+qh_initbuild
+qh_initflags
+qh_initialhull
+qh_initialvertices
+qh_initqhull_buffers
+qh_initqhull_globals
+qh_initqhull_mem
+qh_initqhull_outputflags
+qh_initqhull_start
+qh_initqhull_start2
+qh_initstatistics
+qh_initthresholds
+qh_inthresholds
+qh_isvertex
+qh_joggleinput
+qh_lib_check
+qh_makenew_nonsimplicial
+qh_makenew_simplicial
+qh_makenewfacet
+qh_makenewfacets
+qh_makenewplanes
+qh_makeridges
+qh_malloc
+qh_mark_dupridges
+qh_markkeep
+qh_markvoronoi
+qh_matchduplicates
+qh_matchneighbor
+qh_matchnewfacets
+qh_matchvertices
+qh_maxabsval
+qh_maxmin
+qh_maxouter
+qh_maxsimplex
+qh_maydropneighbor
+qh_memalloc
+qh_memfree
+qh_memfreeshort
+qh_meminit
+qh_meminitbuffers
+qh_memsetup
+qh_memsize
+qh_memstatistics
+qh_memtotal
+qh_merge_degenredundant
+qh_merge_nonconvex
+qh_mergecycle
+qh_mergecycle_all
+qh_mergecycle_facets
+qh_mergecycle_neighbors
+qh_mergecycle_ridges
+qh_mergecycle_vneighbors
+qh_mergefacet
+qh_mergefacet2d
+qh_mergeneighbors
+qh_mergeridges
+qh_mergesimplex
+qh_mergevertex_del
+qh_mergevertex_neighbors
+qh_mergevertices
+qh_minabsval
+qh_mindiff
+qh_nearcoplanar
+qh_nearvertex
+qh_neighbor_intersections
+qh_new_qhull
+qh_newfacet
+qh_newhashtable
+qh_newridge
+qh_newstats
+qh_newvertex
+qh_newvertices
+qh_nextfurthest
+qh_nextridge3d
+qh_normalize
+qh_normalize2
+qh_nostatistic
+qh_option
+qh_order_vertexneighbors
+qh_orientoutside
+qh_out1
+qh_out2n
+qh_out3n
+qh_outcoplanar
+qh_outerinner
+qh_partitionall
+qh_partitioncoplanar
+qh_partitionpoint
+qh_partitionvisible
+qh_point
+qh_point_add
+qh_pointdist
+qh_pointfacet
+qh_pointid
+qh_pointvertex
+qh_postmerge
+qh_precision
+qh_premerge
+qh_prepare_output
+qh_prependfacet
+qh_printafacet
+qh_printallstatistics
+qh_printbegin
+qh_printcenter
+qh_printcentrum
+qh_printend
+qh_printend4geom
+qh_printextremes
+qh_printextremes_2d
+qh_printextremes_d
+qh_printfacet
+qh_printfacet2geom
+qh_printfacet2geom_points
+qh_printfacet2math
+qh_printfacet3geom_nonsimplicial
+qh_printfacet3geom_points
+qh_printfacet3geom_simplicial
+qh_printfacet3math
+qh_printfacet3vertex
+qh_printfacet4geom_nonsimplicial
+qh_printfacet4geom_simplicial
+qh_printfacetNvertex_nonsimplicial
+qh_printfacetNvertex_simplicial
+qh_printfacetheader
+qh_printfacetlist
+qh_printfacetridges
+qh_printfacets
+qh_printhashtable
+qh_printhelp_degenerate
+qh_printhelp_narrowhull
+qh_printhelp_singular
+qh_printhyperplaneintersection
+qh_printline3geom
+qh_printlists
+qh_printmatrix
+qh_printneighborhood
+qh_printpoint
+qh_printpoint3
+qh_printpointid
+qh_printpoints
+qh_printpoints_out
+qh_printpointvect
+qh_printpointvect2
+qh_printridge
+qh_printspheres
+qh_printstatistics
+qh_printstatlevel
+qh_printstats
+qh_printsummary
+qh_printvdiagram
+qh_printvdiagram2
+qh_printvertex
+qh_printvertexlist
+qh_printvertices
+qh_printvneighbors
+qh_printvnorm
+qh_printvoronoi
+qh_printvridge
+qh_produce_output
+qh_produce_output2
+qh_projectdim3
+qh_projectinput
+qh_projectpoint
+qh_projectpoints
+qh_qhull
+qh_rand
+qh_randomfactor
+qh_randommatrix
+qh_rboxpoints
+qh_readfeasible
+qh_readpoints
+qh_reducevertices
+qh_redundant_vertex
+qh_remove_extravertices
+qh_removefacet
+qh_removevertex
+qh_rename_sharedvertex
+qh_renameridgevertex
+qh_renamevertex
+qh_resetlists
+qh_rotateinput
+qh_rotatepoints
+qh_roundi
+qh_scaleinput
+qh_scalelast
+qh_scalepoints
+qh_setaddnth
+qh_setaddsorted
+qh_setappend
+qh_setappend2ndlast
+qh_setappend_set
+qh_setcheck
+qh_setcompact
+qh_setcopy
+qh_setdel
+qh_setdelaunay
+qh_setdellast
+qh_setdelnth
+qh_setdelnthsorted
+qh_setdelsorted
+qh_setduplicate
+qh_setequal
+qh_setequal_except
+qh_setequal_skip
+qh_setfacetplane
+qh_setfeasible
+qh_setfree
+qh_setfree2
+qh_setfreelong
+qh_sethalfspace
+qh_sethalfspace_all
+qh_sethyperplane_det
+qh_sethyperplane_gauss
+qh_setin
+qh_setindex
+qh_setlarger
+qh_setlast
+qh_setnew
+qh_setnew_delnthsorted
+qh_setprint
+qh_setreplace
+qh_setsize
+qh_settemp
+qh_settempfree
+qh_settempfree_all
+qh_settemppop
+qh_settemppush
+qh_settruncate
+qh_setunique
+qh_setvoronoi_all
+qh_setzero
+qh_sharpnewfacets
+qh_skipfacet
+qh_skipfilename
+qh_srand
+qh_stddev
+qh_strtod
+qh_strtol
+qh_test_appendmerge
+qh_test_vneighbors
+qh_tracemerge
+qh_tracemerging
+qh_triangulate
+qh_triangulate_facet
+qh_triangulate_link
+qh_triangulate_mirror
+qh_triangulate_null
+qh_updatetested
+qh_updatevertices
+qh_user_memsizes
+qh_version
+qh_version2
+qh_vertexintersect
+qh_vertexintersect_new
+qh_vertexneighbors
+qh_vertexridges
+qh_vertexridges_facet
+qh_vertexsubset
+qh_voronoi_center
+qh_willdelete
+qh_zero
diff --git a/xs/src/qhull/src/libqhull_r/qhull_ra.h b/xs/src/qhull/src/libqhull_r/qhull_ra.h
new file mode 100644
index 000000000..5c5bd8779
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qhull_ra.h
@@ -0,0 +1,158 @@
+/*<html><pre> -<a href="qh-qhull_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qhull_ra.h
+ all header files for compiling qhull with reentrant code
+ included before C++ headers for user_r.h:QHULL_CRTDBG
+
+ see qh-qhull.htm
+
+ see libqhull_r.h for user-level definitions
+
+ see user_r.h for user-definable constants
+
+ defines internal functions for libqhull_r.c global_r.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/qhull_ra.h#6 $$Change: 2079 $
+ $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+
+ Notes: grep for ((" and (" to catch fprintf("lkasdjf");
+ full parens around (x?y:z)
+ use '#include "libqhull_r/qhull_ra.h"' to avoid name clashes
+*/
+
+#ifndef qhDEFqhulla
+#define qhDEFqhulla 1
+
+#include "libqhull_r.h" /* Includes user_r.h and data types */
+
+#include "stat_r.h"
+#include "random_r.h"
+#include "mem_r.h"
+#include "qset_r.h"
+#include "geom_r.h"
+#include "merge_r.h"
+#include "poly_r.h"
+#include "io_r.h"
+
+#include <setjmp.h>
+#include <string.h>
+#include <math.h>
+#include <float.h> /* some compilers will not need float.h */
+#include <limits.h>
+#include <time.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+/*** uncomment here and qset_r.c
+ if string.h does not define memcpy()
+#include <memory.h>
+*/
+
+#if qh_CLOCKtype == 2 /* defined in user_r.h from libqhull_r.h */
+#include <sys/types.h>
+#include <sys/times.h>
+#include <unistd.h>
+#endif
+
+#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
+#pragma warning( disable : 4100) /* unreferenced formal parameter */
+#pragma warning( disable : 4127) /* conditional expression is constant */
+#pragma warning( disable : 4706) /* assignment within conditional function */
+#pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
+#endif
+
+/* ======= -macros- =========== */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >--------------------------------</a><a name="traceN">-</a>
+
+ traceN((qh, qh->ferr, 0Nnnn, "format\n", vars));
+ calls qh_fprintf if qh.IStracing >= N
+
+ Add debugging traps to the end of qh_fprintf
+
+ notes:
+ removing tracing reduces code size but doesn't change execution speed
+*/
+#ifndef qh_NOtrace
+#define trace0(args) {if (qh->IStracing) qh_fprintf args;}
+#define trace1(args) {if (qh->IStracing >= 1) qh_fprintf args;}
+#define trace2(args) {if (qh->IStracing >= 2) qh_fprintf args;}
+#define trace3(args) {if (qh->IStracing >= 3) qh_fprintf args;}
+#define trace4(args) {if (qh->IStracing >= 4) qh_fprintf args;}
+#define trace5(args) {if (qh->IStracing >= 5) qh_fprintf args;}
+#else /* qh_NOtrace */
+#define trace0(args) {}
+#define trace1(args) {}
+#define trace2(args) {}
+#define trace3(args) {}
+#define trace4(args) {}
+#define trace5(args) {}
+#endif /* qh_NOtrace */
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >--------------------------------</a><a name="QHULL_UNUSED">-</a>
+
+ Define an unused variable to avoid compiler warnings
+
+ Derived from Qt's corelib/global/qglobal.h
+
+*/
+
+#if defined(__cplusplus) && defined(__INTEL_COMPILER) && !defined(QHULL_OS_WIN)
+template <typename T>
+inline void qhullUnused(T &x) { (void)x; }
+# define QHULL_UNUSED(x) qhullUnused(x);
+#else
+# define QHULL_UNUSED(x) (void)x;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***** -libqhull_r.c prototypes (alphabetical after qhull) ********************/
+
+void qh_qhull(qhT *qh);
+boolT qh_addpoint(qhT *qh, pointT *furthest, facetT *facet, boolT checkdist);
+void qh_buildhull(qhT *qh);
+void qh_buildtracing(qhT *qh, pointT *furthest, facetT *facet);
+void qh_build_withrestart(qhT *qh);
+void qh_errexit2(qhT *qh, int exitcode, facetT *facet, facetT *otherfacet);
+void qh_findhorizon(qhT *qh, pointT *point, facetT *facet, int *goodvisible,int *goodhorizon);
+pointT *qh_nextfurthest(qhT *qh, facetT **visible);
+void qh_partitionall(qhT *qh, setT *vertices, pointT *points,int npoints);
+void qh_partitioncoplanar(qhT *qh, pointT *point, facetT *facet, realT *dist);
+void qh_partitionpoint(qhT *qh, pointT *point, facetT *facet);
+void qh_partitionvisible(qhT *qh, boolT allpoints, int *numpoints);
+void qh_precision(qhT *qh, const char *reason);
+void qh_printsummary(qhT *qh, FILE *fp);
+
+/***** -global_r.c internal prototypes (alphabetical) ***********************/
+
+void qh_appendprint(qhT *qh, qh_PRINT format);
+void qh_freebuild(qhT *qh, boolT allmem);
+void qh_freebuffers(qhT *qh);
+void qh_initbuffers(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
+
+/***** -stat_r.c internal prototypes (alphabetical) ***********************/
+
+void qh_allstatA(qhT *qh);
+void qh_allstatB(qhT *qh);
+void qh_allstatC(qhT *qh);
+void qh_allstatD(qhT *qh);
+void qh_allstatE(qhT *qh);
+void qh_allstatE2(qhT *qh);
+void qh_allstatF(qhT *qh);
+void qh_allstatG(qhT *qh);
+void qh_allstatH(qhT *qh);
+void qh_freebuffers(qhT *qh);
+void qh_initbuffers(qhT *qh, coordT *points, int numpoints, int dim, boolT ismalloc);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* qhDEFqhulla */
diff --git a/xs/src/qhull/src/libqhull_r/qset_r.c b/xs/src/qhull/src/libqhull_r/qset_r.c
new file mode 100644
index 000000000..15cd3c0e2
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qset_r.c
@@ -0,0 +1,1340 @@
+/*<html><pre> -<a href="qh-set_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qset_r.c
+ implements set manipulations needed for quickhull
+
+ see qh-set_r.htm and qset_r.h
+
+ Be careful of strict aliasing (two pointers of different types
+ that reference the same location). The last slot of a set is
+ either the actual size of the set plus 1, or the NULL terminator
+ of the set (i.e., setelemT).
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/qset_r.c#3 $$Change: 2062 $
+ $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+*/
+
+#include "libqhull_r.h" /* for qhT and QHULL_CRTDBG */
+#include "qset_r.h"
+#include "mem_r.h"
+#include <stdio.h>
+#include <string.h>
+/*** uncomment here and qhull_ra.h
+ if string.h does not define memcpy()
+#include <memory.h>
+*/
+
+#ifndef qhDEFlibqhull
+typedef struct ridgeT ridgeT;
+typedef struct facetT facetT;
+void qh_errexit(qhT *qh, int exitcode, facetT *, ridgeT *);
+void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
+# ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
+# pragma warning( disable : 4127) /* conditional expression is constant */
+# pragma warning( disable : 4706) /* assignment within conditional function */
+# endif
+#endif
+
+/*=============== internal macros ===========================*/
+
+/*============ functions in alphabetical order ===================*/
+
+/*-<a href="qh-set_r.htm#TOC"
+ >--------------------------------<a name="setaddnth">-</a>
+
+ qh_setaddnth(qh, setp, nth, newelem)
+ adds newelem as n'th element of sorted or unsorted *setp
+
+ notes:
+ *setp and newelem must be defined
+ *setp may be a temp set
+ nth=0 is first element
+ errors if nth is out of bounds
+
+ design:
+ expand *setp if empty or full
+ move tail of *setp up one
+ insert newelem
+*/
+void qh_setaddnth(qhT *qh, setT **setp, int nth, void *newelem) {
+ int oldsize, i;
+ setelemT *sizep; /* avoid strict aliasing */
+ setelemT *oldp, *newp;
+
+ if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
+ qh_setlarger(qh, setp);
+ sizep= SETsizeaddr_(*setp);
+ }
+ oldsize= sizep->i - 1;
+ if (nth < 0 || nth > oldsize) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6171, "qhull internal error (qh_setaddnth): nth %d is out-of-bounds for set:\n", nth);
+ qh_setprint(qh, qh->qhmem.ferr, "", *setp);
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ sizep->i++;
+ oldp= (setelemT *)SETelemaddr_(*setp, oldsize, void); /* NULL */
+ newp= oldp+1;
+ for (i=oldsize-nth+1; i--; ) /* move at least NULL */
+ (newp--)->p= (oldp--)->p; /* may overwrite *sizep */
+ newp->p= newelem;
+} /* setaddnth */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >--------------------------------<a name="setaddsorted">-</a>
+
+ setaddsorted( setp, newelem )
+ adds an newelem into sorted *setp
+
+ notes:
+ *setp and newelem must be defined
+ *setp may be a temp set
+ nop if newelem already in set
+
+ design:
+ find newelem's position in *setp
+ insert newelem
+*/
+void qh_setaddsorted(qhT *qh, setT **setp, void *newelem) {
+ int newindex=0;
+ void *elem, **elemp;
+
+ FOREACHelem_(*setp) { /* could use binary search instead */
+ if (elem < newelem)
+ newindex++;
+ else if (elem == newelem)
+ return;
+ else
+ break;
+ }
+ qh_setaddnth(qh, setp, newindex, newelem);
+} /* setaddsorted */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setappend">-</a>
+
+ qh_setappend(qh, setp, newelem)
+ append newelem to *setp
+
+ notes:
+ *setp may be a temp set
+ *setp and newelem may be NULL
+
+ design:
+ expand *setp if empty or full
+ append newelem to *setp
+
+*/
+void qh_setappend(qhT *qh, setT **setp, void *newelem) {
+ setelemT *sizep; /* Avoid strict aliasing. Writing to *endp may overwrite *sizep */
+ setelemT *endp;
+ int count;
+
+ if (!newelem)
+ return;
+ if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
+ qh_setlarger(qh, setp);
+ sizep= SETsizeaddr_(*setp);
+ }
+ count= (sizep->i)++ - 1;
+ endp= (setelemT *)SETelemaddr_(*setp, count, void);
+ (endp++)->p= newelem;
+ endp->p= NULL;
+} /* setappend */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setappend_set">-</a>
+
+ qh_setappend_set(qh, setp, setA)
+ appends setA to *setp
+
+ notes:
+ *setp can not be a temp set
+ *setp and setA may be NULL
+
+ design:
+ setup for copy
+ expand *setp if it is too small
+ append all elements of setA to *setp
+*/
+void qh_setappend_set(qhT *qh, setT **setp, setT *setA) {
+ int sizeA, size;
+ setT *oldset;
+ setelemT *sizep;
+
+ if (!setA)
+ return;
+ SETreturnsize_(setA, sizeA);
+ if (!*setp)
+ *setp= qh_setnew(qh, sizeA);
+ sizep= SETsizeaddr_(*setp);
+ if (!(size= sizep->i))
+ size= (*setp)->maxsize;
+ else
+ size--;
+ if (size + sizeA > (*setp)->maxsize) {
+ oldset= *setp;
+ *setp= qh_setcopy(qh, oldset, sizeA);
+ qh_setfree(qh, &oldset);
+ sizep= SETsizeaddr_(*setp);
+ }
+ if (sizeA > 0) {
+ sizep->i= size+sizeA+1; /* memcpy may overwrite */
+ memcpy((char *)&((*setp)->e[size].p), (char *)&(setA->e[0].p), (size_t)(sizeA+1) * SETelemsize);
+ }
+} /* setappend_set */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setappend2ndlast">-</a>
+
+ qh_setappend2ndlast(qh, setp, newelem )
+ makes newelem the next to the last element in *setp
+
+ notes:
+ *setp must have at least one element
+ newelem must be defined
+ *setp may be a temp set
+
+ design:
+ expand *setp if empty or full
+ move last element of *setp up one
+ insert newelem
+*/
+void qh_setappend2ndlast(qhT *qh, setT **setp, void *newelem) {
+ setelemT *sizep; /* Avoid strict aliasing. Writing to *endp may overwrite *sizep */
+ setelemT *endp, *lastp;
+ int count;
+
+ if (!*setp || (sizep= SETsizeaddr_(*setp))->i==0) {
+ qh_setlarger(qh, setp);
+ sizep= SETsizeaddr_(*setp);
+ }
+ count= (sizep->i)++ - 1;
+ endp= (setelemT *)SETelemaddr_(*setp, count, void); /* NULL */
+ lastp= endp-1;
+ *(endp++)= *lastp;
+ endp->p= NULL; /* may overwrite *sizep */
+ lastp->p= newelem;
+} /* setappend2ndlast */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setcheck">-</a>
+
+ qh_setcheck(qh, set, typename, id )
+ check set for validity
+ report errors with typename and id
+
+ design:
+ checks that maxsize, actual size, and NULL terminator agree
+*/
+void qh_setcheck(qhT *qh, setT *set, const char *tname, unsigned id) {
+ int maxsize, size;
+ int waserr= 0;
+
+ if (!set)
+ return;
+ SETreturnsize_(set, size);
+ maxsize= set->maxsize;
+ if (size > maxsize || !maxsize) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6172, "qhull internal error (qh_setcheck): actual size %d of %s%d is greater than max size %d\n",
+ size, tname, id, maxsize);
+ waserr= 1;
+ }else if (set->e[size].p) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6173, "qhull internal error (qh_setcheck): %s%d(size %d max %d) is not null terminated.\n",
+ tname, id, size-1, maxsize);
+ waserr= 1;
+ }
+ if (waserr) {
+ qh_setprint(qh, qh->qhmem.ferr, "ERRONEOUS", set);
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+} /* setcheck */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setcompact">-</a>
+
+ qh_setcompact(qh, set )
+ remove internal NULLs from an unsorted set
+
+ returns:
+ updated set
+
+ notes:
+ set may be NULL
+ it would be faster to swap tail of set into holes, like qh_setdel
+
+ design:
+ setup pointers into set
+ skip NULLs while copying elements to start of set
+ update the actual size
+*/
+void qh_setcompact(qhT *qh, setT *set) {
+ int size;
+ void **destp, **elemp, **endp, **firstp;
+
+ if (!set)
+ return;
+ SETreturnsize_(set, size);
+ destp= elemp= firstp= SETaddr_(set, void);
+ endp= destp + size;
+ while (1) {
+ if (!(*destp++ = *elemp++)) {
+ destp--;
+ if (elemp > endp)
+ break;
+ }
+ }
+ qh_settruncate(qh, set, (int)(destp-firstp)); /* WARN64 */
+} /* setcompact */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setcopy">-</a>
+
+ qh_setcopy(qh, set, extra )
+ make a copy of a sorted or unsorted set with extra slots
+
+ returns:
+ new set
+
+ design:
+ create a newset with extra slots
+ copy the elements to the newset
+
+*/
+setT *qh_setcopy(qhT *qh, setT *set, int extra) {
+ setT *newset;
+ int size;
+
+ if (extra < 0)
+ extra= 0;
+ SETreturnsize_(set, size);
+ newset= qh_setnew(qh, size+extra);
+ SETsizeaddr_(newset)->i= size+1; /* memcpy may overwrite */
+ memcpy((char *)&(newset->e[0].p), (char *)&(set->e[0].p), (size_t)(size+1) * SETelemsize);
+ return(newset);
+} /* setcopy */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setdel">-</a>
+
+ qh_setdel(set, oldelem )
+ delete oldelem from an unsorted set
+
+ returns:
+ returns oldelem if found
+ returns NULL otherwise
+
+ notes:
+ set may be NULL
+ oldelem must not be NULL;
+ only deletes one copy of oldelem in set
+
+ design:
+ locate oldelem
+ update actual size if it was full
+ move the last element to the oldelem's location
+*/
+void *qh_setdel(setT *set, void *oldelem) {
+ setelemT *sizep;
+ setelemT *elemp;
+ setelemT *lastp;
+
+ if (!set)
+ return NULL;
+ elemp= (setelemT *)SETaddr_(set, void);
+ while (elemp->p != oldelem && elemp->p)
+ elemp++;
+ if (elemp->p) {
+ sizep= SETsizeaddr_(set);
+ if (!(sizep->i)--) /* if was a full set */
+ sizep->i= set->maxsize; /* *sizep= (maxsize-1)+ 1 */
+ lastp= (setelemT *)SETelemaddr_(set, sizep->i-1, void);
+ elemp->p= lastp->p; /* may overwrite itself */
+ lastp->p= NULL;
+ return oldelem;
+ }
+ return NULL;
+} /* setdel */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setdellast">-</a>
+
+ qh_setdellast(set)
+ return last element of set or NULL
+
+ notes:
+ deletes element from set
+ set may be NULL
+
+ design:
+ return NULL if empty
+ if full set
+ delete last element and set actual size
+ else
+ delete last element and update actual size
+*/
+void *qh_setdellast(setT *set) {
+ int setsize; /* actually, actual_size + 1 */
+ int maxsize;
+ setelemT *sizep;
+ void *returnvalue;
+
+ if (!set || !(set->e[0].p))
+ return NULL;
+ sizep= SETsizeaddr_(set);
+ if ((setsize= sizep->i)) {
+ returnvalue= set->e[setsize - 2].p;
+ set->e[setsize - 2].p= NULL;
+ sizep->i--;
+ }else {
+ maxsize= set->maxsize;
+ returnvalue= set->e[maxsize - 1].p;
+ set->e[maxsize - 1].p= NULL;
+ sizep->i= maxsize;
+ }
+ return returnvalue;
+} /* setdellast */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setdelnth">-</a>
+
+ qh_setdelnth(qh, set, nth )
+ deletes nth element from unsorted set
+ 0 is first element
+
+ returns:
+ returns the element (needs type conversion)
+
+ notes:
+ errors if nth invalid
+
+ design:
+ setup points and check nth
+ delete nth element and overwrite with last element
+*/
+void *qh_setdelnth(qhT *qh, setT *set, int nth) {
+ void *elem;
+ setelemT *sizep;
+ setelemT *elemp, *lastp;
+
+ sizep= SETsizeaddr_(set);
+ if ((sizep->i--)==0) /* if was a full set */
+ sizep->i= set->maxsize; /* *sizep= (maxsize-1)+ 1 */
+ if (nth < 0 || nth >= sizep->i) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6174, "qhull internal error (qh_setdelnth): nth %d is out-of-bounds for set:\n", nth);
+ qh_setprint(qh, qh->qhmem.ferr, "", set);
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ elemp= (setelemT *)SETelemaddr_(set, nth, void); /* nth valid by QH6174 */
+ lastp= (setelemT *)SETelemaddr_(set, sizep->i-1, void);
+ elem= elemp->p;
+ elemp->p= lastp->p; /* may overwrite itself */
+ lastp->p= NULL;
+ return elem;
+} /* setdelnth */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setdelnthsorted">-</a>
+
+ qh_setdelnthsorted(qh, set, nth )
+ deletes nth element from sorted set
+
+ returns:
+ returns the element (use type conversion)
+
+ notes:
+ errors if nth invalid
+
+ see also:
+ setnew_delnthsorted
+
+ design:
+ setup points and check nth
+ copy remaining elements down one
+ update actual size
+*/
+void *qh_setdelnthsorted(qhT *qh, setT *set, int nth) {
+ void *elem;
+ setelemT *sizep;
+ setelemT *newp, *oldp;
+
+ sizep= SETsizeaddr_(set);
+ if (nth < 0 || (sizep->i && nth >= sizep->i-1) || nth >= set->maxsize) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6175, "qhull internal error (qh_setdelnthsorted): nth %d is out-of-bounds for set:\n", nth);
+ qh_setprint(qh, qh->qhmem.ferr, "", set);
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ newp= (setelemT *)SETelemaddr_(set, nth, void);
+ elem= newp->p;
+ oldp= newp+1;
+ while (((newp++)->p= (oldp++)->p))
+ ; /* copy remaining elements and NULL */
+ if ((sizep->i--)==0) /* if was a full set */
+ sizep->i= set->maxsize; /* *sizep= (max size-1)+ 1 */
+ return elem;
+} /* setdelnthsorted */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setdelsorted">-</a>
+
+ qh_setdelsorted(set, oldelem )
+ deletes oldelem from sorted set
+
+ returns:
+ returns oldelem if it was deleted
+
+ notes:
+ set may be NULL
+
+ design:
+ locate oldelem in set
+ copy remaining elements down one
+ update actual size
+*/
+void *qh_setdelsorted(setT *set, void *oldelem) {
+ setelemT *sizep;
+ setelemT *newp, *oldp;
+
+ if (!set)
+ return NULL;
+ newp= (setelemT *)SETaddr_(set, void);
+ while(newp->p != oldelem && newp->p)
+ newp++;
+ if (newp->p) {
+ oldp= newp+1;
+ while (((newp++)->p= (oldp++)->p))
+ ; /* copy remaining elements */
+ sizep= SETsizeaddr_(set);
+ if ((sizep->i--)==0) /* if was a full set */
+ sizep->i= set->maxsize; /* *sizep= (max size-1)+ 1 */
+ return oldelem;
+ }
+ return NULL;
+} /* setdelsorted */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setduplicate">-</a>
+
+ qh_setduplicate(qh, set, elemsize )
+ duplicate a set of elemsize elements
+
+ notes:
+ use setcopy if retaining old elements
+
+ design:
+ create a new set
+ for each elem of the old set
+ create a newelem
+ append newelem to newset
+*/
+setT *qh_setduplicate(qhT *qh, setT *set, int elemsize) {
+ void *elem, **elemp, *newElem;
+ setT *newSet;
+ int size;
+
+ if (!(size= qh_setsize(qh, set)))
+ return NULL;
+ newSet= qh_setnew(qh, size);
+ FOREACHelem_(set) {
+ newElem= qh_memalloc(qh, elemsize);
+ memcpy(newElem, elem, (size_t)elemsize);
+ qh_setappend(qh, &newSet, newElem);
+ }
+ return newSet;
+} /* setduplicate */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setendpointer">-</a>
+
+ qh_setendpointer( set )
+ Returns pointer to NULL terminator of a set's elements
+ set can not be NULL
+
+*/
+void **qh_setendpointer(setT *set) {
+
+ setelemT *sizep= SETsizeaddr_(set);
+ int n= sizep->i;
+ return (n ? &set->e[n-1].p : &sizep->p);
+} /* qh_setendpointer */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setequal">-</a>
+
+ qh_setequal( setA, setB )
+ returns 1 if two sorted sets are equal, otherwise returns 0
+
+ notes:
+ either set may be NULL
+
+ design:
+ check size of each set
+ setup pointers
+ compare elements of each set
+*/
+int qh_setequal(setT *setA, setT *setB) {
+ void **elemAp, **elemBp;
+ int sizeA= 0, sizeB= 0;
+
+ if (setA) {
+ SETreturnsize_(setA, sizeA);
+ }
+ if (setB) {
+ SETreturnsize_(setB, sizeB);
+ }
+ if (sizeA != sizeB)
+ return 0;
+ if (!sizeA)
+ return 1;
+ elemAp= SETaddr_(setA, void);
+ elemBp= SETaddr_(setB, void);
+ if (!memcmp((char *)elemAp, (char *)elemBp, sizeA*SETelemsize))
+ return 1;
+ return 0;
+} /* setequal */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setequal_except">-</a>
+
+ qh_setequal_except( setA, skipelemA, setB, skipelemB )
+ returns 1 if sorted setA and setB are equal except for skipelemA & B
+
+ returns:
+ false if either skipelemA or skipelemB are missing
+
+ notes:
+ neither set may be NULL
+
+ if skipelemB is NULL,
+ can skip any one element of setB
+
+ design:
+ setup pointers
+ search for skipelemA, skipelemB, and mismatches
+ check results
+*/
+int qh_setequal_except(setT *setA, void *skipelemA, setT *setB, void *skipelemB) {
+ void **elemA, **elemB;
+ int skip=0;
+
+ elemA= SETaddr_(setA, void);
+ elemB= SETaddr_(setB, void);
+ while (1) {
+ if (*elemA == skipelemA) {
+ skip++;
+ elemA++;
+ }
+ if (skipelemB) {
+ if (*elemB == skipelemB) {
+ skip++;
+ elemB++;
+ }
+ }else if (*elemA != *elemB) {
+ skip++;
+ if (!(skipelemB= *elemB++))
+ return 0;
+ }
+ if (!*elemA)
+ break;
+ if (*elemA++ != *elemB++)
+ return 0;
+ }
+ if (skip != 2 || *elemB)
+ return 0;
+ return 1;
+} /* setequal_except */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setequal_skip">-</a>
+
+ qh_setequal_skip( setA, skipA, setB, skipB )
+ returns 1 if sorted setA and setB are equal except for elements skipA & B
+
+ returns:
+ false if different size
+
+ notes:
+ neither set may be NULL
+
+ design:
+ setup pointers
+ search for mismatches while skipping skipA and skipB
+*/
+int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB) {
+ void **elemA, **elemB, **skipAp, **skipBp;
+
+ elemA= SETaddr_(setA, void);
+ elemB= SETaddr_(setB, void);
+ skipAp= SETelemaddr_(setA, skipA, void);
+ skipBp= SETelemaddr_(setB, skipB, void);
+ while (1) {
+ if (elemA == skipAp)
+ elemA++;
+ if (elemB == skipBp)
+ elemB++;
+ if (!*elemA)
+ break;
+ if (*elemA++ != *elemB++)
+ return 0;
+ }
+ if (*elemB)
+ return 0;
+ return 1;
+} /* setequal_skip */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setfree">-</a>
+
+ qh_setfree(qh, setp )
+ frees the space occupied by a sorted or unsorted set
+
+ returns:
+ sets setp to NULL
+
+ notes:
+ set may be NULL
+
+ design:
+ free array
+ free set
+*/
+void qh_setfree(qhT *qh, setT **setp) {
+ int size;
+ void **freelistp; /* used if !qh_NOmem by qh_memfree_() */
+
+ if (*setp) {
+ size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize;
+ if (size <= qh->qhmem.LASTsize) {
+ qh_memfree_(qh, *setp, size, freelistp);
+ }else
+ qh_memfree(qh, *setp, size);
+ *setp= NULL;
+ }
+} /* setfree */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setfree2">-</a>
+
+ qh_setfree2(qh, setp, elemsize )
+ frees the space occupied by a set and its elements
+
+ notes:
+ set may be NULL
+
+ design:
+ free each element
+ free set
+*/
+void qh_setfree2(qhT *qh, setT **setp, int elemsize) {
+ void *elem, **elemp;
+
+ FOREACHelem_(*setp)
+ qh_memfree(qh, elem, elemsize);
+ qh_setfree(qh, setp);
+} /* setfree2 */
+
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setfreelong">-</a>
+
+ qh_setfreelong(qh, setp )
+ frees a set only if it's in long memory
+
+ returns:
+ sets setp to NULL if it is freed
+
+ notes:
+ set may be NULL
+
+ design:
+ if set is large
+ free it
+*/
+void qh_setfreelong(qhT *qh, setT **setp) {
+ int size;
+
+ if (*setp) {
+ size= sizeof(setT) + ((*setp)->maxsize)*SETelemsize;
+ if (size > qh->qhmem.LASTsize) {
+ qh_memfree(qh, *setp, size);
+ *setp= NULL;
+ }
+ }
+} /* setfreelong */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setin">-</a>
+
+ qh_setin(set, setelem )
+ returns 1 if setelem is in a set, 0 otherwise
+
+ notes:
+ set may be NULL or unsorted
+
+ design:
+ scans set for setelem
+*/
+int qh_setin(setT *set, void *setelem) {
+ void *elem, **elemp;
+
+ FOREACHelem_(set) {
+ if (elem == setelem)
+ return 1;
+ }
+ return 0;
+} /* setin */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setindex">-</a>
+
+ qh_setindex(set, atelem )
+ returns the index of atelem in set.
+ returns -1, if not in set or maxsize wrong
+
+ notes:
+ set may be NULL and may contain nulls.
+ NOerrors returned (qh_pointid, QhullPoint::id)
+
+ design:
+ checks maxsize
+ scans set for atelem
+*/
+int qh_setindex(setT *set, void *atelem) {
+ void **elem;
+ int size, i;
+
+ if (!set)
+ return -1;
+ SETreturnsize_(set, size);
+ if (size > set->maxsize)
+ return -1;
+ elem= SETaddr_(set, void);
+ for (i=0; i < size; i++) {
+ if (*elem++ == atelem)
+ return i;
+ }
+ return -1;
+} /* setindex */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setlarger">-</a>
+
+ qh_setlarger(qh, oldsetp )
+ returns a larger set that contains all elements of *oldsetp
+
+ notes:
+ the set is at least twice as large
+ if temp set, updates qh->qhmem.tempstack
+
+ design:
+ creates a new set
+ copies the old set to the new set
+ updates pointers in tempstack
+ deletes the old set
+*/
+void qh_setlarger(qhT *qh, setT **oldsetp) {
+ int size= 1;
+ setT *newset, *set, **setp, *oldset;
+ setelemT *sizep;
+ setelemT *newp, *oldp;
+
+ if (*oldsetp) {
+ oldset= *oldsetp;
+ SETreturnsize_(oldset, size);
+ qh->qhmem.cntlarger++;
+ qh->qhmem.totlarger += size+1;
+ newset= qh_setnew(qh, 2 * size);
+ oldp= (setelemT *)SETaddr_(oldset, void);
+ newp= (setelemT *)SETaddr_(newset, void);
+ memcpy((char *)newp, (char *)oldp, (size_t)(size+1) * SETelemsize);
+ sizep= SETsizeaddr_(newset);
+ sizep->i= size+1;
+ FOREACHset_((setT *)qh->qhmem.tempstack) {
+ if (set == oldset)
+ *(setp-1)= newset;
+ }
+ qh_setfree(qh, oldsetp);
+ }else
+ newset= qh_setnew(qh, 3);
+ *oldsetp= newset;
+} /* setlarger */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setlast">-</a>
+
+ qh_setlast( set )
+ return last element of set or NULL (use type conversion)
+
+ notes:
+ set may be NULL
+
+ design:
+ return last element
+*/
+void *qh_setlast(setT *set) {
+ int size;
+
+ if (set) {
+ size= SETsizeaddr_(set)->i;
+ if (!size)
+ return SETelem_(set, set->maxsize - 1);
+ else if (size > 1)
+ return SETelem_(set, size - 2);
+ }
+ return NULL;
+} /* setlast */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setnew">-</a>
+
+ qh_setnew(qh, setsize )
+ creates and allocates space for a set
+
+ notes:
+ setsize means the number of elements (!including the NULL terminator)
+ use qh_settemp/qh_setfreetemp if set is temporary
+
+ design:
+ allocate memory for set
+ roundup memory if small set
+ initialize as empty set
+*/
+setT *qh_setnew(qhT *qh, int setsize) {
+ setT *set;
+ int sizereceived; /* used if !qh_NOmem */
+ int size;
+ void **freelistp; /* used if !qh_NOmem by qh_memalloc_() */
+
+ if (!setsize)
+ setsize++;
+ size= sizeof(setT) + setsize * SETelemsize;
+ if (size>0 && size <= qh->qhmem.LASTsize) {
+ qh_memalloc_(qh, size, freelistp, set, setT);
+#ifndef qh_NOmem
+ sizereceived= qh->qhmem.sizetable[ qh->qhmem.indextable[size]];
+ if (sizereceived > size)
+ setsize += (sizereceived - size)/SETelemsize;
+#endif
+ }else
+ set= (setT*)qh_memalloc(qh, size);
+ set->maxsize= setsize;
+ set->e[setsize].i= 1;
+ set->e[0].p= NULL;
+ return(set);
+} /* setnew */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setnew_delnthsorted">-</a>
+
+ qh_setnew_delnthsorted(qh, set, size, nth, prepend )
+ creates a sorted set not containing nth element
+ if prepend, the first prepend elements are undefined
+
+ notes:
+ set must be defined
+ checks nth
+ see also: setdelnthsorted
+
+ design:
+ create new set
+ setup pointers and allocate room for prepend'ed entries
+ append head of old set to new set
+ append tail of old set to new set
+*/
+setT *qh_setnew_delnthsorted(qhT *qh, setT *set, int size, int nth, int prepend) {
+ setT *newset;
+ void **oldp, **newp;
+ int tailsize= size - nth -1, newsize;
+
+ if (tailsize < 0) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6176, "qhull internal error (qh_setnew_delnthsorted): nth %d is out-of-bounds for set:\n", nth);
+ qh_setprint(qh, qh->qhmem.ferr, "", set);
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ newsize= size-1 + prepend;
+ newset= qh_setnew(qh, newsize);
+ newset->e[newset->maxsize].i= newsize+1; /* may be overwritten */
+ oldp= SETaddr_(set, void);
+ newp= SETaddr_(newset, void) + prepend;
+ switch (nth) {
+ case 0:
+ break;
+ case 1:
+ *(newp++)= *oldp++;
+ break;
+ case 2:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ case 3:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ case 4:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ default:
+ memcpy((char *)newp, (char *)oldp, (size_t)nth * SETelemsize);
+ newp += nth;
+ oldp += nth;
+ break;
+ }
+ oldp++;
+ switch (tailsize) {
+ case 0:
+ break;
+ case 1:
+ *(newp++)= *oldp++;
+ break;
+ case 2:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ case 3:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ case 4:
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ *(newp++)= *oldp++;
+ break;
+ default:
+ memcpy((char *)newp, (char *)oldp, (size_t)tailsize * SETelemsize);
+ newp += tailsize;
+ }
+ *newp= NULL;
+ return(newset);
+} /* setnew_delnthsorted */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setprint">-</a>
+
+ qh_setprint(qh, fp, string, set )
+ print set elements to fp with identifying string
+
+ notes:
+ never errors
+*/
+void qh_setprint(qhT *qh, FILE *fp, const char* string, setT *set) {
+ int size, k;
+
+ if (!set)
+ qh_fprintf(qh, fp, 9346, "%s set is null\n", string);
+ else {
+ SETreturnsize_(set, size);
+ qh_fprintf(qh, fp, 9347, "%s set=%p maxsize=%d size=%d elems=",
+ string, set, set->maxsize, size);
+ if (size > set->maxsize)
+ size= set->maxsize+1;
+ for (k=0; k < size; k++)
+ qh_fprintf(qh, fp, 9348, " %p", set->e[k].p);
+ qh_fprintf(qh, fp, 9349, "\n");
+ }
+} /* setprint */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setreplace">-</a>
+
+ qh_setreplace(qh, set, oldelem, newelem )
+ replaces oldelem in set with newelem
+
+ notes:
+ errors if oldelem not in the set
+ newelem may be NULL, but it turns the set into an indexed set (no FOREACH)
+
+ design:
+ find oldelem
+ replace with newelem
+*/
+void qh_setreplace(qhT *qh, setT *set, void *oldelem, void *newelem) {
+ void **elemp;
+
+ elemp= SETaddr_(set, void);
+ while (*elemp != oldelem && *elemp)
+ elemp++;
+ if (*elemp)
+ *elemp= newelem;
+ else {
+ qh_fprintf(qh, qh->qhmem.ferr, 6177, "qhull internal error (qh_setreplace): elem %p not found in set\n",
+ oldelem);
+ qh_setprint(qh, qh->qhmem.ferr, "", set);
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+} /* setreplace */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setsize">-</a>
+
+ qh_setsize(qh, set )
+ returns the size of a set
+
+ notes:
+ errors if set's maxsize is incorrect
+ same as SETreturnsize_(set)
+ same code for qh_setsize [qset_r.c] and QhullSetBase::count
+
+ design:
+ determine actual size of set from maxsize
+*/
+int qh_setsize(qhT *qh, setT *set) {
+ int size;
+ setelemT *sizep;
+
+ if (!set)
+ return(0);
+ sizep= SETsizeaddr_(set);
+ if ((size= sizep->i)) {
+ size--;
+ if (size > set->maxsize) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6178, "qhull internal error (qh_setsize): current set size %d is greater than maximum size %d\n",
+ size, set->maxsize);
+ qh_setprint(qh, qh->qhmem.ferr, "set: ", set);
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ }else
+ size= set->maxsize;
+ return size;
+} /* setsize */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="settemp">-</a>
+
+ qh_settemp(qh, setsize )
+ return a stacked, temporary set of upto setsize elements
+
+ notes:
+ use settempfree or settempfree_all to release from qh->qhmem.tempstack
+ see also qh_setnew
+
+ design:
+ allocate set
+ append to qh->qhmem.tempstack
+
+*/
+setT *qh_settemp(qhT *qh, int setsize) {
+ setT *newset;
+
+ newset= qh_setnew(qh, setsize);
+ qh_setappend(qh, &qh->qhmem.tempstack, newset);
+ if (qh->qhmem.IStracing >= 5)
+ qh_fprintf(qh, qh->qhmem.ferr, 8123, "qh_settemp: temp set %p of %d elements, depth %d\n",
+ newset, newset->maxsize, qh_setsize(qh, qh->qhmem.tempstack));
+ return newset;
+} /* settemp */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="settempfree">-</a>
+
+ qh_settempfree(qh, set )
+ free temporary set at top of qh->qhmem.tempstack
+
+ notes:
+ nop if set is NULL
+ errors if set not from previous qh_settemp
+
+ to locate errors:
+ use 'T2' to find source and then find mis-matching qh_settemp
+
+ design:
+ check top of qh->qhmem.tempstack
+ free it
+*/
+void qh_settempfree(qhT *qh, setT **set) {
+ setT *stackedset;
+
+ if (!*set)
+ return;
+ stackedset= qh_settemppop(qh);
+ if (stackedset != *set) {
+ qh_settemppush(qh, stackedset);
+ qh_fprintf(qh, qh->qhmem.ferr, 6179, "qhull internal error (qh_settempfree): set %p(size %d) was not last temporary allocated(depth %d, set %p, size %d)\n",
+ *set, qh_setsize(qh, *set), qh_setsize(qh, qh->qhmem.tempstack)+1,
+ stackedset, qh_setsize(qh, stackedset));
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ qh_setfree(qh, set);
+} /* settempfree */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="settempfree_all">-</a>
+
+ qh_settempfree_all(qh)
+ free all temporary sets in qh->qhmem.tempstack
+
+ design:
+ for each set in tempstack
+ free set
+ free qh->qhmem.tempstack
+*/
+void qh_settempfree_all(qhT *qh) {
+ setT *set, **setp;
+
+ FOREACHset_(qh->qhmem.tempstack)
+ qh_setfree(qh, &set);
+ qh_setfree(qh, &qh->qhmem.tempstack);
+} /* settempfree_all */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="settemppop">-</a>
+
+ qh_settemppop(qh)
+ pop and return temporary set from qh->qhmem.tempstack
+
+ notes:
+ the returned set is permanent
+
+ design:
+ pop and check top of qh->qhmem.tempstack
+*/
+setT *qh_settemppop(qhT *qh) {
+ setT *stackedset;
+
+ stackedset= (setT*)qh_setdellast(qh->qhmem.tempstack);
+ if (!stackedset) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6180, "qhull internal error (qh_settemppop): pop from empty temporary stack\n");
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ if (qh->qhmem.IStracing >= 5)
+ qh_fprintf(qh, qh->qhmem.ferr, 8124, "qh_settemppop: depth %d temp set %p of %d elements\n",
+ qh_setsize(qh, qh->qhmem.tempstack)+1, stackedset, qh_setsize(qh, stackedset));
+ return stackedset;
+} /* settemppop */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="settemppush">-</a>
+
+ qh_settemppush(qh, set )
+ push temporary set unto qh->qhmem.tempstack (makes it temporary)
+
+ notes:
+ duplicates settemp() for tracing
+
+ design:
+ append set to tempstack
+*/
+void qh_settemppush(qhT *qh, setT *set) {
+ if (!set) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6267, "qhull error (qh_settemppush): can not push a NULL temp\n");
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ qh_setappend(qh, &qh->qhmem.tempstack, set);
+ if (qh->qhmem.IStracing >= 5)
+ qh_fprintf(qh, qh->qhmem.ferr, 8125, "qh_settemppush: depth %d temp set %p of %d elements\n",
+ qh_setsize(qh, qh->qhmem.tempstack), set, qh_setsize(qh, set));
+} /* settemppush */
+
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="settruncate">-</a>
+
+ qh_settruncate(qh, set, size )
+ truncate set to size elements
+
+ notes:
+ set must be defined
+
+ see:
+ SETtruncate_
+
+ design:
+ check size
+ update actual size of set
+*/
+void qh_settruncate(qhT *qh, setT *set, int size) {
+
+ if (size < 0 || size > set->maxsize) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6181, "qhull internal error (qh_settruncate): size %d out of bounds for set:\n", size);
+ qh_setprint(qh, qh->qhmem.ferr, "", set);
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ set->e[set->maxsize].i= size+1; /* maybe overwritten */
+ set->e[size].p= NULL;
+} /* settruncate */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setunique">-</a>
+
+ qh_setunique(qh, set, elem )
+ add elem to unsorted set unless it is already in set
+
+ notes:
+ returns 1 if it is appended
+
+ design:
+ if elem not in set
+ append elem to set
+*/
+int qh_setunique(qhT *qh, setT **set, void *elem) {
+
+ if (!qh_setin(*set, elem)) {
+ qh_setappend(qh, set, elem);
+ return 1;
+ }
+ return 0;
+} /* setunique */
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="setzero">-</a>
+
+ qh_setzero(qh, set, index, size )
+ zero elements from index on
+ set actual size of set to size
+
+ notes:
+ set must be defined
+ the set becomes an indexed set (can not use FOREACH...)
+
+ see also:
+ qh_settruncate
+
+ design:
+ check index and size
+ update actual size
+ zero elements starting at e[index]
+*/
+void qh_setzero(qhT *qh, setT *set, int idx, int size) {
+ int count;
+
+ if (idx < 0 || idx >= size || size > set->maxsize) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6182, "qhull internal error (qh_setzero): index %d or size %d out of bounds for set:\n", idx, size);
+ qh_setprint(qh, qh->qhmem.ferr, "", set);
+ qh_errexit(qh, qhmem_ERRqhull, NULL, NULL);
+ }
+ set->e[set->maxsize].i= size+1; /* may be overwritten */
+ count= size - idx + 1; /* +1 for NULL terminator */
+ memset((char *)SETelemaddr_(set, idx, void), 0, (size_t)count * SETelemsize);
+} /* setzero */
+
+
diff --git a/xs/src/qhull/src/libqhull_r/qset_r.h b/xs/src/qhull/src/libqhull_r/qset_r.h
new file mode 100644
index 000000000..7ba199d6f
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/qset_r.h
@@ -0,0 +1,502 @@
+/*<html><pre> -<a href="qh-set_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qset_r.h
+ header file for qset_r.c that implements set
+
+ see qh-set_r.htm and qset_r.c
+
+ only uses mem_r.c, malloc/free
+
+ for error handling, writes message and calls
+ qh_errexit(qhT *qh, qhmem_ERRqhull, NULL, NULL);
+
+ set operations satisfy the following properties:
+ - sets have a max size, the actual size (if different) is stored at the end
+ - every set is NULL terminated
+ - sets may be sorted or unsorted, the caller must distinguish this
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/qset_r.h#4 $$Change: 2079 $
+ $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+*/
+
+#ifndef qhDEFset
+#define qhDEFset 1
+
+#include <stdio.h>
+
+/*================= -structures- ===============*/
+
+#ifndef DEFsetT
+#define DEFsetT 1
+typedef struct setT setT; /* a set is a sorted or unsorted array of pointers */
+#endif
+
+#ifndef DEFqhT
+#define DEFqhT 1
+typedef struct qhT qhT; /* defined in libqhull_r.h */
+#endif
+
+/* [jan'15] Decided not to use countT. Most sets are small. The code uses signed tests */
+
+/*-<a href="qh-set_r.htm#TOC"
+>----------------------------------------</a><a name="setT">-</a>
+
+setT
+ a set or list of pointers with maximum size and actual size.
+
+variations:
+ unsorted, unique -- a list of unique pointers with NULL terminator
+ user guarantees uniqueness
+ sorted -- a sorted list of unique pointers with NULL terminator
+ qset_r.c guarantees uniqueness
+ unsorted -- a list of pointers terminated with NULL
+ indexed -- an array of pointers with NULL elements
+
+structure for set of n elements:
+
+ --------------
+ | maxsize
+ --------------
+ | e[0] - a pointer, may be NULL for indexed sets
+ --------------
+ | e[1]
+
+ --------------
+ | ...
+ --------------
+ | e[n-1]
+ --------------
+ | e[n] = NULL
+ --------------
+ | ...
+ --------------
+ | e[maxsize] - n+1 or NULL (determines actual size of set)
+ --------------
+
+*/
+
+/*-- setelemT -- internal type to allow both pointers and indices
+*/
+typedef union setelemT setelemT;
+union setelemT {
+ void *p;
+ int i; /* integer used for e[maxSize] */
+};
+
+struct setT {
+ int maxsize; /* maximum number of elements (except NULL) */
+ setelemT e[1]; /* array of pointers, tail is NULL */
+ /* last slot (unless NULL) is actual size+1
+ e[maxsize]==NULL or e[e[maxsize]-1]==NULL */
+ /* this may generate a warning since e[] contains
+ maxsize elements */
+};
+
+/*=========== -constants- =========================*/
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-----------------------------------</a><a name="SETelemsize">-</a>
+
+ SETelemsize
+ size of a set element in bytes
+*/
+#define SETelemsize ((int)sizeof(setelemT))
+
+
+/*=========== -macros- =========================*/
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-----------------------------------</a><a name="FOREACHsetelement_">-</a>
+
+ FOREACHsetelement_(type, set, variable)
+ define FOREACH iterator
+
+ declare:
+ assumes *variable and **variablep are declared
+ no space in "variable)" [DEC Alpha cc compiler]
+
+ each iteration:
+ variable is set element
+ variablep is one beyond variable.
+
+ to repeat an element:
+ variablep--; / *repeat* /
+
+ at exit:
+ variable is NULL at end of loop
+
+ example:
+ #define FOREACHfacet_( facets ) FOREACHsetelement_( facetT, facets, facet )
+
+ notes:
+ use FOREACHsetelement_i_() if need index or include NULLs
+
+ WARNING:
+ nested loops can't use the same variable (define another FOREACH)
+
+ needs braces if nested inside another FOREACH
+ this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
+*/
+#define FOREACHsetelement_(type, set, variable) \
+ if (((variable= NULL), set)) for (\
+ variable##p= (type **)&((set)->e[0].p); \
+ (variable= *variable##p++);)
+
+/*-<a href="qh-set_r.htm#TOC"
+ >----------------------------------------</a><a name="FOREACHsetelement_i_">-</a>
+
+ FOREACHsetelement_i_(qh, type, set, variable)
+ define indexed FOREACH iterator
+
+ declare:
+ type *variable, variable_n, variable_i;
+
+ each iteration:
+ variable is set element, may be NULL
+ variable_i is index, variable_n is qh_setsize()
+
+ to repeat an element:
+ variable_i--; variable_n-- repeats for deleted element
+
+ at exit:
+ variable==NULL and variable_i==variable_n
+
+ example:
+ #define FOREACHfacet_i_( qh, facets ) FOREACHsetelement_i_( qh, facetT, facets, facet )
+
+ WARNING:
+ nested loops can't use the same variable (define another FOREACH)
+
+ needs braces if nested inside another FOREACH
+ this includes intervening blocks, e.g. FOREACH...{ if () FOREACH...} )
+*/
+#define FOREACHsetelement_i_(qh, type, set, variable) \
+ if (((variable= NULL), set)) for (\
+ variable##_i= 0, variable= (type *)((set)->e[0].p), \
+ variable##_n= qh_setsize(qh, set);\
+ variable##_i < variable##_n;\
+ variable= (type *)((set)->e[++variable##_i].p) )
+
+/*-<a href="qh-set_r.htm#TOC"
+ >--------------------------------------</a><a name="FOREACHsetelementreverse_">-</a>
+
+ FOREACHsetelementreverse_(qh, type, set, variable)-
+ define FOREACH iterator in reverse order
+
+ declare:
+ assumes *variable and **variablep are declared
+ also declare 'int variabletemp'
+
+ each iteration:
+ variable is set element
+
+ to repeat an element:
+ variabletemp++; / *repeat* /
+
+ at exit:
+ variable is NULL
+
+ example:
+ #define FOREACHvertexreverse_( vertices ) FOREACHsetelementreverse_( vertexT, vertices, vertex )
+
+ notes:
+ use FOREACHsetelementreverse12_() to reverse first two elements
+ WARNING: needs braces if nested inside another FOREACH
+*/
+#define FOREACHsetelementreverse_(qh, type, set, variable) \
+ if (((variable= NULL), set)) for (\
+ variable##temp= qh_setsize(qh, set)-1, variable= qh_setlast(qh, set);\
+ variable; variable= \
+ ((--variable##temp >= 0) ? SETelemt_(set, variable##temp, type) : NULL))
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-----------------------------------</a><a name="FOREACHsetelementreverse12_">-</a>
+
+ FOREACHsetelementreverse12_(type, set, variable)-
+ define FOREACH iterator with e[1] and e[0] reversed
+
+ declare:
+ assumes *variable and **variablep are declared
+
+ each iteration:
+ variable is set element
+ variablep is one after variable.
+
+ to repeat an element:
+ variablep--; / *repeat* /
+
+ at exit:
+ variable is NULL at end of loop
+
+ example
+ #define FOREACHvertexreverse12_( vertices ) FOREACHsetelementreverse12_( vertexT, vertices, vertex )
+
+ notes:
+ WARNING: needs braces if nested inside another FOREACH
+*/
+#define FOREACHsetelementreverse12_(type, set, variable) \
+ if (((variable= NULL), set)) for (\
+ variable##p= (type **)&((set)->e[1].p); \
+ (variable= *variable##p); \
+ variable##p == ((type **)&((set)->e[0].p))?variable##p += 2: \
+ (variable##p == ((type **)&((set)->e[1].p))?variable##p--:variable##p++))
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-----------------------------------</a><a name="FOREACHelem_">-</a>
+
+ FOREACHelem_( set )-
+ iterate elements in a set
+
+ declare:
+ void *elem, *elemp;
+
+ each iteration:
+ elem is set element
+ elemp is one beyond
+
+ to repeat an element:
+ elemp--; / *repeat* /
+
+ at exit:
+ elem == NULL at end of loop
+
+ example:
+ FOREACHelem_(set) {
+
+ notes:
+ WARNING: needs braces if nested inside another FOREACH
+*/
+#define FOREACHelem_(set) FOREACHsetelement_(void, set, elem)
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-----------------------------------</a><a name="FOREACHset_">-</a>
+
+ FOREACHset_( set )-
+ iterate a set of sets
+
+ declare:
+ setT *set, **setp;
+
+ each iteration:
+ set is set element
+ setp is one beyond
+
+ to repeat an element:
+ setp--; / *repeat* /
+
+ at exit:
+ set == NULL at end of loop
+
+ example
+ FOREACHset_(sets) {
+
+ notes:
+ WARNING: needs braces if nested inside another FOREACH
+*/
+#define FOREACHset_(sets) FOREACHsetelement_(setT, sets, set)
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-----------------------------------------</a><a name="SETindex_">-</a>
+
+ SETindex_( set, elem )
+ return index of elem in set
+
+ notes:
+ for use with FOREACH iteration
+ WARN64 -- Maximum set size is 2G
+
+ example:
+ i= SETindex_(ridges, ridge)
+*/
+#define SETindex_(set, elem) ((int)((void **)elem##p - (void **)&(set)->e[1].p))
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETref_">-</a>
+
+ SETref_( elem )
+ l.h.s. for modifying the current element in a FOREACH iteration
+
+ example:
+ SETref_(ridge)= anotherridge;
+*/
+#define SETref_(elem) (elem##p[-1])
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETelem_">-</a>
+
+ SETelem_(set, n)
+ return the n'th element of set
+
+ notes:
+ assumes that n is valid [0..size] and that set is defined
+ use SETelemt_() for type cast
+*/
+#define SETelem_(set, n) ((set)->e[n].p)
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETelemt_">-</a>
+
+ SETelemt_(set, n, type)
+ return the n'th element of set as a type
+
+ notes:
+ assumes that n is valid [0..size] and that set is defined
+*/
+#define SETelemt_(set, n, type) ((type*)((set)->e[n].p))
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETelemaddr_">-</a>
+
+ SETelemaddr_(set, n, type)
+ return address of the n'th element of a set
+
+ notes:
+ assumes that n is valid [0..size] and set is defined
+*/
+#define SETelemaddr_(set, n, type) ((type **)(&((set)->e[n].p)))
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETfirst_">-</a>
+
+ SETfirst_(set)
+ return first element of set
+
+*/
+#define SETfirst_(set) ((set)->e[0].p)
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETfirstt_">-</a>
+
+ SETfirstt_(set, type)
+ return first element of set as a type
+
+*/
+#define SETfirstt_(set, type) ((type*)((set)->e[0].p))
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETsecond_">-</a>
+
+ SETsecond_(set)
+ return second element of set
+
+*/
+#define SETsecond_(set) ((set)->e[1].p)
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETsecondt_">-</a>
+
+ SETsecondt_(set, type)
+ return second element of set as a type
+*/
+#define SETsecondt_(set, type) ((type*)((set)->e[1].p))
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETaddr_">-</a>
+
+ SETaddr_(set, type)
+ return address of set's elements
+*/
+#define SETaddr_(set,type) ((type **)(&((set)->e[0].p)))
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETreturnsize_">-</a>
+
+ SETreturnsize_(set, size)
+ return size of a set
+
+ notes:
+ set must be defined
+ use qh_setsize(qhT *qh, set) unless speed is critical
+*/
+#define SETreturnsize_(set, size) (((size)= ((set)->e[(set)->maxsize].i))?(--(size)):((size)= (set)->maxsize))
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETempty_">-</a>
+
+ SETempty_(set)
+ return true(1) if set is empty
+
+ notes:
+ set may be NULL
+*/
+#define SETempty_(set) (!set || (SETfirst_(set) ? 0 : 1))
+
+/*-<a href="qh-set_r.htm#TOC"
+ >-------------------------------<a name="SETsizeaddr_">-</a>
+
+ SETsizeaddr_(set)
+ return pointer to 'actual size+1' of set (set CANNOT be NULL!!)
+ Its type is setelemT* for strict aliasing
+ All SETelemaddr_ must be cast to setelemT
+
+
+ notes:
+ *SETsizeaddr==NULL or e[*SETsizeaddr-1].p==NULL
+*/
+#define SETsizeaddr_(set) (&((set)->e[(set)->maxsize]))
+
+/*-<a href="qh-set_r.htm#TOC"
+ >---------------------------------------</a><a name="SETtruncate_">-</a>
+
+ SETtruncate_(set, size)
+ truncate set to size
+
+ see:
+ qh_settruncate()
+
+*/
+#define SETtruncate_(set, size) {set->e[set->maxsize].i= size+1; /* maybe overwritten */ \
+ set->e[size].p= NULL;}
+
+/*======= prototypes in alphabetical order ============*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void qh_setaddsorted(qhT *qh, setT **setp, void *elem);
+void qh_setaddnth(qhT *qh, setT **setp, int nth, void *newelem);
+void qh_setappend(qhT *qh, setT **setp, void *elem);
+void qh_setappend_set(qhT *qh, setT **setp, setT *setA);
+void qh_setappend2ndlast(qhT *qh, setT **setp, void *elem);
+void qh_setcheck(qhT *qh, setT *set, const char *tname, unsigned id);
+void qh_setcompact(qhT *qh, setT *set);
+setT *qh_setcopy(qhT *qh, setT *set, int extra);
+void *qh_setdel(setT *set, void *elem);
+void *qh_setdellast(setT *set);
+void *qh_setdelnth(qhT *qh, setT *set, int nth);
+void *qh_setdelnthsorted(qhT *qh, setT *set, int nth);
+void *qh_setdelsorted(setT *set, void *newelem);
+setT *qh_setduplicate(qhT *qh, setT *set, int elemsize);
+void **qh_setendpointer(setT *set);
+int qh_setequal(setT *setA, setT *setB);
+int qh_setequal_except(setT *setA, void *skipelemA, setT *setB, void *skipelemB);
+int qh_setequal_skip(setT *setA, int skipA, setT *setB, int skipB);
+void qh_setfree(qhT *qh, setT **set);
+void qh_setfree2(qhT *qh, setT **setp, int elemsize);
+void qh_setfreelong(qhT *qh, setT **set);
+int qh_setin(setT *set, void *setelem);
+int qh_setindex(setT *set, void *setelem);
+void qh_setlarger(qhT *qh, setT **setp);
+void *qh_setlast(setT *set);
+setT *qh_setnew(qhT *qh, int size);
+setT *qh_setnew_delnthsorted(qhT *qh, setT *set, int size, int nth, int prepend);
+void qh_setprint(qhT *qh, FILE *fp, const char* string, setT *set);
+void qh_setreplace(qhT *qh, setT *set, void *oldelem, void *newelem);
+int qh_setsize(qhT *qh, setT *set);
+setT *qh_settemp(qhT *qh, int setsize);
+void qh_settempfree(qhT *qh, setT **set);
+void qh_settempfree_all(qhT *qh);
+setT *qh_settemppop(qhT *qh);
+void qh_settemppush(qhT *qh, setT *set);
+void qh_settruncate(qhT *qh, setT *set, int size);
+int qh_setunique(qhT *qh, setT **set, void *elem);
+void qh_setzero(qhT *qh, setT *set, int idx, int size);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* qhDEFset */
diff --git a/xs/src/qhull/src/libqhull_r/random_r.c b/xs/src/qhull/src/libqhull_r/random_r.c
new file mode 100644
index 000000000..1fefb51c3
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/random_r.c
@@ -0,0 +1,247 @@
+/*<html><pre> -<a href="index_r.htm#TOC"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ random_r.c and utilities
+ Park & Miller's minimimal standard random number generator
+ argc/argv conversion
+
+ Used by rbox. Do not use 'qh'
+*/
+
+#include "libqhull_r.h"
+#include "random_r.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
+#pragma warning( disable : 4706) /* assignment within conditional function */
+#pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
+#endif
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="argv_to_command">-</a>
+
+ qh_argv_to_command(argc, argv, command, max_size )
+
+ build command from argc/argv
+ max_size is at least
+
+ returns:
+ a space-delimited string of options (just as typed)
+ returns false if max_size is too short
+
+ notes:
+ silently removes
+ makes option string easy to input and output
+ matches qh_argv_to_command_size()
+
+ argc may be 0
+*/
+int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
+ int i, remaining;
+ char *s;
+ *command= '\0'; /* max_size > 0 */
+
+ if (argc) {
+ if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
+ || (s= strrchr( argv[0], '/')))
+ s++;
+ else
+ s= argv[0];
+ if ((int)strlen(s) < max_size) /* WARN64 */
+ strcpy(command, s);
+ else
+ goto error_argv;
+ if ((s= strstr(command, ".EXE"))
+ || (s= strstr(command, ".exe")))
+ *s= '\0';
+ }
+ for (i=1; i < argc; i++) {
+ s= argv[i];
+ remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2; /* WARN64 */
+ if (!*s || strchr(s, ' ')) {
+ char *t= command + strlen(command);
+ remaining -= 2;
+ if (remaining < 0) {
+ goto error_argv;
+ }
+ *t++= ' ';
+ *t++= '"';
+ while (*s) {
+ if (*s == '"') {
+ if (--remaining < 0)
+ goto error_argv;
+ *t++= '\\';
+ }
+ *t++= *s++;
+ }
+ *t++= '"';
+ *t= '\0';
+ }else if (remaining < 0) {
+ goto error_argv;
+ }else
+ strcat(command, " ");
+ strcat(command, s);
+ }
+ return 1;
+
+error_argv:
+ return 0;
+} /* argv_to_command */
+
+/*-<a href="qh-globa_r.htm#TOC"
+>-------------------------------</a><a name="argv_to_command_size">-</a>
+
+qh_argv_to_command_size(argc, argv )
+
+ return size to allocate for qh_argv_to_command()
+
+notes:
+ argc may be 0
+ actual size is usually shorter
+*/
+int qh_argv_to_command_size(int argc, char *argv[]) {
+ unsigned int count= 1; /* null-terminator if argc==0 */
+ int i;
+ char *s;
+
+ for (i=0; i<argc; i++){
+ count += (int)strlen(argv[i]) + 1; /* WARN64 */
+ if (i>0 && strchr(argv[i], ' ')) {
+ count += 2; /* quote delimiters */
+ for (s=argv[i]; *s; s++) {
+ if (*s == '"') {
+ count++;
+ }
+ }
+ }
+ }
+ return count;
+} /* argv_to_command_size */
+
+/*-<a href="qh-geom_r.htm#TOC"
+ >-------------------------------</a><a name="rand">-</a>
+
+ qh_rand()
+ qh_srand(qh, seed )
+ generate pseudo-random number between 1 and 2^31 -2
+
+ notes:
+ For qhull and rbox, called from qh_RANDOMint(),etc. [user.h]
+
+ From Park & Miller's minimal standard random number generator
+ Communications of the ACM, 31:1192-1201, 1988.
+ Does not use 0 or 2^31 -1
+ this is silently enforced by qh_srand()
+ Can make 'Rn' much faster by moving qh_rand to qh_distplane
+*/
+
+/* Global variables and constants */
+
+#define qh_rand_a 16807
+#define qh_rand_m 2147483647
+#define qh_rand_q 127773 /* m div a */
+#define qh_rand_r 2836 /* m mod a */
+
+int qh_rand(qhT *qh) {
+ int lo, hi, test;
+ int seed = qh->last_random;
+
+ hi = seed / qh_rand_q; /* seed div q */
+ lo = seed % qh_rand_q; /* seed mod q */
+ test = qh_rand_a * lo - qh_rand_r * hi;
+ if (test > 0)
+ seed= test;
+ else
+ seed= test + qh_rand_m;
+ qh->last_random= seed;
+ /* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax; for testing */
+ /* seed = qh_RANDOMmax; for testing */
+ return seed;
+} /* rand */
+
+void qh_srand(qhT *qh, int seed) {
+ if (seed < 1)
+ qh->last_random= 1;
+ else if (seed >= qh_rand_m)
+ qh->last_random= qh_rand_m - 1;
+ else
+ qh->last_random= seed;
+} /* qh_srand */
+
+/*-<a href="qh-geom_r.htm#TOC"
+>-------------------------------</a><a name="randomfactor">-</a>
+
+qh_randomfactor(qh, scale, offset )
+ return a random factor r * scale + offset
+
+notes:
+ qh.RANDOMa/b are defined in global_r.c
+ qh_RANDOMint requires 'qh'
+*/
+realT qh_randomfactor(qhT *qh, realT scale, realT offset) {
+ realT randr;
+
+ randr= qh_RANDOMint;
+ return randr * scale + offset;
+} /* randomfactor */
+
+/*-<a href="qh-geom_r.htm#TOC"
+>-------------------------------</a><a name="randommatrix">-</a>
+
+qh_randommatrix(qh, buffer, dim, rows )
+ generate a random dim X dim matrix in range [-1,1]
+ assumes buffer is [dim+1, dim]
+
+ returns:
+ sets buffer to random numbers
+ sets rows to rows of buffer
+ sets row[dim] as scratch row
+
+ notes:
+ qh_RANDOMint requires 'qh'
+*/
+void qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **rows) {
+ int i, k;
+ realT **rowi, *coord, realr;
+
+ coord= buffer;
+ rowi= rows;
+ for (i=0; i < dim; i++) {
+ *(rowi++)= coord;
+ for (k=0; k < dim; k++) {
+ realr= qh_RANDOMint;
+ *(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
+ }
+ }
+ *rowi= coord;
+} /* randommatrix */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="strtol">-</a>
+
+ qh_strtol( s, endp) qh_strtod( s, endp)
+ internal versions of strtol() and strtod()
+ does not skip trailing spaces
+ notes:
+ some implementations of strtol()/strtod() skip trailing spaces
+*/
+double qh_strtod(const char *s, char **endp) {
+ double result;
+
+ result= strtod(s, endp);
+ if (s < (*endp) && (*endp)[-1] == ' ')
+ (*endp)--;
+ return result;
+} /* strtod */
+
+int qh_strtol(const char *s, char **endp) {
+ int result;
+
+ result= (int) strtol(s, endp, 10); /* WARN64 */
+ if (s< (*endp) && (*endp)[-1] == ' ')
+ (*endp)--;
+ return result;
+} /* strtol */
diff --git a/xs/src/qhull/src/libqhull_r/random_r.h b/xs/src/qhull/src/libqhull_r/random_r.h
new file mode 100644
index 000000000..dc884b33c
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/random_r.h
@@ -0,0 +1,41 @@
+/*<html><pre> -<a href="qh-geom_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ random.h
+ header file for random and utility routines
+
+ see qh-geom_r.htm and random_r.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/random_r.h#4 $$Change: 2079 $
+ $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+*/
+
+#ifndef qhDEFrandom
+#define qhDEFrandom 1
+
+#include "libqhull_r.h"
+
+/*============= prototypes in alphabetical order ======= */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int qh_argv_to_command(int argc, char *argv[], char* command, int max_size);
+int qh_argv_to_command_size(int argc, char *argv[]);
+int qh_rand(qhT *qh);
+void qh_srand(qhT *qh, int seed);
+realT qh_randomfactor(qhT *qh, realT scale, realT offset);
+void qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **row);
+int qh_strtol(const char *s, char **endp);
+double qh_strtod(const char *s, char **endp);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* qhDEFrandom */
+
+
+
diff --git a/xs/src/qhull/src/libqhull_r/rboxlib_r.c b/xs/src/qhull/src/libqhull_r/rboxlib_r.c
new file mode 100644
index 000000000..6c0c7e35e
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/rboxlib_r.c
@@ -0,0 +1,842 @@
+/*<html><pre> -<a href="index_r.htm#TOC"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ rboxlib_r.c
+ Generate input points
+
+ notes:
+ For documentation, see prompt[] of rbox_r.c
+ 50 points generated for 'rbox D4'
+
+ WARNING:
+ incorrect range if qh_RANDOMmax is defined wrong (user_r.h)
+*/
+
+#include "libqhull_r.h" /* First for user_r.h */
+#include "random_r.h"
+
+#include <ctype.h>
+#include <limits.h>
+#include <math.h>
+#include <setjmp.h>
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef _MSC_VER /* Microsoft Visual C++ */
+#pragma warning( disable : 4706) /* assignment within conditional expression. */
+#pragma warning( disable : 4996) /* this function (strncat,sprintf,strcpy) or variable may be unsafe. */
+#endif
+
+#define MAXdim 200
+#define PI 3.1415926535897932384
+
+/* ------------------------------ prototypes ----------------*/
+int qh_roundi(qhT *qh, double a);
+void qh_out1(qhT *qh, double a);
+void qh_out2n(qhT *qh, double a, double b);
+void qh_out3n(qhT *qh, double a, double b, double c);
+void qh_outcoord(qhT *qh, int iscdd, double *coord, int dim);
+void qh_outcoincident(qhT *qh, int coincidentpoints, double radius, int iscdd, double *coord, int dim);
+
+void qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
+void qh_free(void *mem);
+void *qh_malloc(size_t size);
+int qh_rand(qhT *qh);
+void qh_srand(qhT *qh, int seed);
+
+/*-<a href="qh-qhull_r.htm#TOC"
+ >-------------------------------</a><a name="rboxpoints">-</a>
+
+ qh_rboxpoints(qh, rbox_command )
+ Generate points to qh->fout according to rbox options
+ Report errors on qh->ferr
+
+ returns:
+ 0 (qh_ERRnone) on success
+ 1 (qh_ERRinput) on input error
+ 4 (qh_ERRmem) on memory error
+ 5 (qh_ERRqhull) on internal error
+
+ notes:
+ To avoid using stdio, redefine qh_malloc, qh_free, and qh_fprintf_rbox (user_r.c)
+
+ design:
+ Straight line code (consider defining a struct and functions):
+
+ Parse arguments into variables
+ Determine the number of points
+ Generate the points
+*/
+int qh_rboxpoints(qhT *qh, char* rbox_command) {
+ int i,j,k;
+ int gendim;
+ int coincidentcount=0, coincidenttotal=0, coincidentpoints=0;
+ int cubesize, diamondsize, seed=0, count, apex;
+ int dim=3 , numpoints= 0, totpoints, addpoints=0;
+ int issphere=0, isaxis=0, iscdd= 0, islens= 0, isregular=0, iswidth=0, addcube=0;
+ int isgap=0, isspiral=0, NOcommand= 0, adddiamond=0;
+ int israndom=0, istime=0;
+ int isbox=0, issimplex=0, issimplex2=0, ismesh=0;
+ double width=0.0, gap=0.0, radius=0.0, coincidentradius=0.0;
+ double coord[MAXdim], offset, meshm=3.0, meshn=4.0, meshr=5.0;
+ double *coordp, *simplex= NULL, *simplexp;
+ int nthroot, mult[MAXdim];
+ double norm, factor, randr, rangap, lensangle= 0, lensbase= 1;
+ double anglediff, angle, x, y, cube= 0.0, diamond= 0.0;
+ double box= qh_DEFAULTbox; /* scale all numbers before output */
+ double randmax= qh_RANDOMmax;
+ char command[200], seedbuf[200];
+ char *s= command, *t, *first_point= NULL;
+ time_t timedata;
+ int exitcode;
+
+ exitcode= setjmp(qh->rbox_errexit);
+ if (exitcode) {
+ /* same code for error exit and normal return, qh->NOerrexit is set */
+ if (simplex)
+ qh_free(simplex);
+ return exitcode;
+ }
+
+ *command= '\0';
+ strncat(command, rbox_command, sizeof(command)-strlen(command)-1);
+
+ while (*s && !isspace(*s)) /* skip program name */
+ s++;
+ while (*s) {
+ while (*s && isspace(*s))
+ s++;
+ if (*s == '-')
+ s++;
+ if (!*s)
+ break;
+ if (isdigit(*s)) {
+ numpoints= qh_strtol(s, &s);
+ continue;
+ }
+ /* ============= read flags =============== */
+ switch (*s++) {
+ case 'c':
+ addcube= 1;
+ t= s;
+ while (isspace(*t))
+ t++;
+ if (*t == 'G')
+ cube= qh_strtod(++t, &s);
+ break;
+ case 'd':
+ adddiamond= 1;
+ t= s;
+ while (isspace(*t))
+ t++;
+ if (*t == 'G')
+ diamond= qh_strtod(++t, &s);
+ break;
+ case 'h':
+ iscdd= 1;
+ break;
+ case 'l':
+ isspiral= 1;
+ break;
+ case 'n':
+ NOcommand= 1;
+ break;
+ case 'r':
+ isregular= 1;
+ break;
+ case 's':
+ issphere= 1;
+ break;
+ case 't':
+ istime= 1;
+ if (isdigit(*s)) {
+ seed= qh_strtol(s, &s);
+ israndom= 0;
+ }else
+ israndom= 1;
+ break;
+ case 'x':
+ issimplex= 1;
+ break;
+ case 'y':
+ issimplex2= 1;
+ break;
+ case 'z':
+ qh->rbox_isinteger= 1;
+ break;
+ case 'B':
+ box= qh_strtod(s, &s);
+ isbox= 1;
+ break;
+ case 'C':
+ if (*s)
+ coincidentpoints= qh_strtol(s, &s);
+ if (*s == ',') {
+ ++s;
+ coincidentradius= qh_strtod(s, &s);
+ }
+ if (*s == ',') {
+ ++s;
+ coincidenttotal= qh_strtol(s, &s);
+ }
+ if (*s && !isspace(*s)) {
+ qh_fprintf_rbox(qh, qh->ferr, 7080, "rbox error: arguments for 'Cn,r,m' are not 'int', 'float', and 'int'. Remaining string is '%s'\n", s);
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ if (coincidentpoints==0){
+ qh_fprintf_rbox(qh, qh->ferr, 6268, "rbox error: missing arguments for 'Cn,r,m' where n is the number of coincident points, r is the radius (default 0.0), and m is the number of points\n");
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ if (coincidentpoints<0 || coincidenttotal<0 || coincidentradius<0.0){
+ qh_fprintf_rbox(qh, qh->ferr, 6269, "rbox error: negative arguments for 'Cn,m,r' where n (%d) is the number of coincident points, m (%d) is the number of points, and r (%.2g) is the radius (default 0.0)\n", coincidentpoints, coincidenttotal, coincidentradius);
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ break;
+ case 'D':
+ dim= qh_strtol(s, &s);
+ if (dim < 1
+ || dim > MAXdim) {
+ qh_fprintf_rbox(qh, qh->ferr, 6189, "rbox error: dimension, D%d, out of bounds (>=%d or <=0)", dim, MAXdim);
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ break;
+ case 'G':
+ if (isdigit(*s))
+ gap= qh_strtod(s, &s);
+ else
+ gap= 0.5;
+ isgap= 1;
+ break;
+ case 'L':
+ if (isdigit(*s))
+ radius= qh_strtod(s, &s);
+ else
+ radius= 10;
+ islens= 1;
+ break;
+ case 'M':
+ ismesh= 1;
+ if (*s)
+ meshn= qh_strtod(s, &s);
+ if (*s == ',') {
+ ++s;
+ meshm= qh_strtod(s, &s);
+ }else
+ meshm= 0.0;
+ if (*s == ',') {
+ ++s;
+ meshr= qh_strtod(s, &s);
+ }else
+ meshr= sqrt(meshn*meshn + meshm*meshm);
+ if (*s && !isspace(*s)) {
+ qh_fprintf_rbox(qh, qh->ferr, 7069, "rbox warning: assuming 'M3,4,5' since mesh args are not integers or reals\n");
+ meshn= 3.0, meshm=4.0, meshr=5.0;
+ }
+ break;
+ case 'O':
+ qh->rbox_out_offset= qh_strtod(s, &s);
+ break;
+ case 'P':
+ if (!first_point)
+ first_point= s-1;
+ addpoints++;
+ while (*s && !isspace(*s)) /* read points later */
+ s++;
+ break;
+ case 'W':
+ width= qh_strtod(s, &s);
+ iswidth= 1;
+ break;
+ case 'Z':
+ if (isdigit(*s))
+ radius= qh_strtod(s, &s);
+ else
+ radius= 1.0;
+ isaxis= 1;
+ break;
+ default:
+ qh_fprintf_rbox(qh, qh->ferr, 7070, "rbox error: unknown flag at %s.\nExecute 'rbox' without arguments for documentation.\n", s);
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ if (*s && !isspace(*s)) {
+ qh_fprintf_rbox(qh, qh->ferr, 7071, "rbox error: missing space between flags at %s.\n", s);
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ }
+
+ /* ============= defaults, constants, and sizes =============== */
+ if (qh->rbox_isinteger && !isbox)
+ box= qh_DEFAULTzbox;
+ if (addcube) {
+ cubesize= (int)floor(ldexp(1.0,dim)+0.5);
+ if (cube == 0.0)
+ cube= box;
+ }else
+ cubesize= 0;
+ if (adddiamond) {
+ diamondsize= 2*dim;
+ if (diamond == 0.0)
+ diamond= box;
+ }else
+ diamondsize= 0;
+ if (islens) {
+ if (isaxis) {
+ qh_fprintf_rbox(qh, qh->ferr, 6190, "rbox error: can not combine 'Ln' with 'Zn'\n");
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ if (radius <= 1.0) {
+ qh_fprintf_rbox(qh, qh->ferr, 6191, "rbox error: lens radius %.2g should be greater than 1.0\n",
+ radius);
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ lensangle= asin(1.0/radius);
+ lensbase= radius * cos(lensangle);
+ }
+
+ if (!numpoints) {
+ if (issimplex2)
+ ; /* ok */
+ else if (isregular + issimplex + islens + issphere + isaxis + isspiral + iswidth + ismesh) {
+ qh_fprintf_rbox(qh, qh->ferr, 6192, "rbox error: missing count\n");
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }else if (adddiamond + addcube + addpoints)
+ ; /* ok */
+ else {
+ numpoints= 50; /* ./rbox D4 is the test case */
+ issphere= 1;
+ }
+ }
+ if ((issimplex + islens + isspiral + ismesh > 1)
+ || (issimplex + issphere + isspiral + ismesh > 1)) {
+ qh_fprintf_rbox(qh, qh->ferr, 6193, "rbox error: can only specify one of 'l', 's', 'x', 'Ln', or 'Mn,m,r' ('Ln s' is ok).\n");
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ if (coincidentpoints>0 && (numpoints == 0 || coincidenttotal > numpoints)) {
+ qh_fprintf_rbox(qh, qh->ferr, 6270, "rbox error: 'Cn,r,m' requested n coincident points for each of m points. Either there is no points or m (%d) is greater than the number of points (%d).\n", coincidenttotal, numpoints);
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ if (coincidenttotal == 0)
+ coincidenttotal= numpoints;
+
+ /* ============= print header with total points =============== */
+ if (issimplex || ismesh)
+ totpoints= numpoints;
+ else if (issimplex2)
+ totpoints= numpoints+dim+1;
+ else if (isregular) {
+ totpoints= numpoints;
+ if (dim == 2) {
+ if (islens)
+ totpoints += numpoints - 2;
+ }else if (dim == 3) {
+ if (islens)
+ totpoints += 2 * numpoints;
+ else if (isgap)
+ totpoints += 1 + numpoints;
+ else
+ totpoints += 2;
+ }
+ }else
+ totpoints= numpoints + isaxis;
+ totpoints += cubesize + diamondsize + addpoints;
+ totpoints += coincidentpoints*coincidenttotal;
+
+ /* ============= seed randoms =============== */
+ if (istime == 0) {
+ for (s=command; *s; s++) {
+ if (issimplex2 && *s == 'y') /* make 'y' same seed as 'x' */
+ i= 'x';
+ else
+ i= *s;
+ seed= 11*seed + i;
+ }
+ }else if (israndom) {
+ seed= (int)time(&timedata);
+ sprintf(seedbuf, " t%d", seed); /* appends an extra t, not worth removing */
+ strncat(command, seedbuf, sizeof(command)-strlen(command)-1);
+ t= strstr(command, " t ");
+ if (t)
+ strcpy(t+1, t+3); /* remove " t " */
+ } /* else, seed explicitly set to n */
+ qh_RANDOMseed_(qh, seed);
+
+ /* ============= print header =============== */
+
+ if (iscdd)
+ qh_fprintf_rbox(qh, qh->fout, 9391, "%s\nbegin\n %d %d %s\n",
+ NOcommand ? "" : command,
+ totpoints, dim+1,
+ qh->rbox_isinteger ? "integer" : "real");
+ else if (NOcommand)
+ qh_fprintf_rbox(qh, qh->fout, 9392, "%d\n%d\n", dim, totpoints);
+ else
+ /* qh_fprintf_rbox special cases 9393 to append 'command' to the RboxPoints.comment() */
+ qh_fprintf_rbox(qh, qh->fout, 9393, "%d %s\n%d\n", dim, command, totpoints);
+
+ /* ============= explicit points =============== */
+ if ((s= first_point)) {
+ while (s && *s) { /* 'P' */
+ count= 0;
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ while (*++s) {
+ qh_out1(qh, qh_strtod(s, &s));
+ count++;
+ if (isspace(*s) || !*s)
+ break;
+ if (*s != ',') {
+ qh_fprintf_rbox(qh, qh->ferr, 6194, "rbox error: missing comma after coordinate in %s\n\n", s);
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ }
+ if (count < dim) {
+ for (k=dim-count; k--; )
+ qh_out1(qh, 0.0);
+ }else if (count > dim) {
+ qh_fprintf_rbox(qh, qh->ferr, 6195, "rbox error: %d coordinates instead of %d coordinates in %s\n\n",
+ count, dim, s);
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ qh_fprintf_rbox(qh, qh->fout, 9394, "\n");
+ while ((s= strchr(s, 'P'))) {
+ if (isspace(s[-1]))
+ break;
+ }
+ }
+ }
+
+ /* ============= simplex distribution =============== */
+ if (issimplex+issimplex2) {
+ if (!(simplex= (double*)qh_malloc( dim * (dim+1) * sizeof(double)))) {
+ qh_fprintf_rbox(qh, qh->ferr, 6196, "rbox error: insufficient memory for simplex\n");
+ qh_errexit_rbox(qh, qh_ERRmem); /* qh_ERRmem */
+ }
+ simplexp= simplex;
+ if (isregular) {
+ for (i=0; i<dim; i++) {
+ for (k=0; k<dim; k++)
+ *(simplexp++)= i==k ? 1.0 : 0.0;
+ }
+ for (k=0; k<dim; k++)
+ *(simplexp++)= -1.0;
+ }else {
+ for (i=0; i<dim+1; i++) {
+ for (k=0; k<dim; k++) {
+ randr= qh_RANDOMint;
+ *(simplexp++)= 2.0 * randr/randmax - 1.0;
+ }
+ }
+ }
+ if (issimplex2) {
+ simplexp= simplex;
+ for (i=0; i<dim+1; i++) {
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ for (k=0; k<dim; k++)
+ qh_out1(qh, *(simplexp++) * box);
+ qh_fprintf_rbox(qh, qh->fout, 9395, "\n");
+ }
+ }
+ for (j=0; j<numpoints; j++) {
+ if (iswidth)
+ apex= qh_RANDOMint % (dim+1);
+ else
+ apex= -1;
+ for (k=0; k<dim; k++)
+ coord[k]= 0.0;
+ norm= 0.0;
+ for (i=0; i<dim+1; i++) {
+ randr= qh_RANDOMint;
+ factor= randr/randmax;
+ if (i == apex)
+ factor *= width;
+ norm += factor;
+ for (k=0; k<dim; k++) {
+ simplexp= simplex + i*dim + k;
+ coord[k] += factor * (*simplexp);
+ }
+ }
+ for (k=0; k<dim; k++)
+ coord[k] *= box/norm;
+ qh_outcoord(qh, iscdd, coord, dim);
+ if(coincidentcount++ < coincidenttotal)
+ qh_outcoincident(qh, coincidentpoints, coincidentradius, iscdd, coord, dim);
+ }
+ isregular= 0; /* continue with isbox */
+ numpoints= 0;
+ }
+
+ /* ============= mesh distribution =============== */
+ if (ismesh) {
+ nthroot= (int)(pow((double)numpoints, 1.0/dim) + 0.99999);
+ for (k=dim; k--; )
+ mult[k]= 0;
+ for (i=0; i < numpoints; i++) {
+ coordp= coord;
+ for (k=0; k < dim; k++) {
+ if (k == 0)
+ *(coordp++)= mult[0] * meshn + mult[1] * (-meshm);
+ else if (k == 1)
+ *(coordp++)= mult[0] * meshm + mult[1] * meshn;
+ else
+ *(coordp++)= mult[k] * meshr;
+ }
+ qh_outcoord(qh, iscdd, coord, dim);
+ if(coincidentcount++ < coincidenttotal)
+ qh_outcoincident(qh, coincidentpoints, coincidentradius, iscdd, coord, dim);
+ for (k=0; k < dim; k++) {
+ if (++mult[k] < nthroot)
+ break;
+ mult[k]= 0;
+ }
+ }
+ }
+ /* ============= regular points for 's' =============== */
+ else if (isregular && !islens) {
+ if (dim != 2 && dim != 3) {
+ qh_free(simplex);
+ qh_fprintf_rbox(qh, qh->ferr, 6197, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ if (!isaxis || radius == 0.0) {
+ isaxis= 1;
+ radius= 1.0;
+ }
+ if (dim == 3) {
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ qh_out3n(qh, 0.0, 0.0, -box);
+ if (!isgap) {
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ qh_out3n(qh, 0.0, 0.0, box);
+ }
+ }
+ angle= 0.0;
+ anglediff= 2.0 * PI/numpoints;
+ for (i=0; i < numpoints; i++) {
+ angle += anglediff;
+ x= radius * cos(angle);
+ y= radius * sin(angle);
+ if (dim == 2) {
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ qh_out2n(qh, x*box, y*box);
+ }else {
+ norm= sqrt(1.0 + x*x + y*y);
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ qh_out3n(qh, box*x/norm, box*y/norm, box/norm);
+ if (isgap) {
+ x *= 1-gap;
+ y *= 1-gap;
+ norm= sqrt(1.0 + x*x + y*y);
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ qh_out3n(qh, box*x/norm, box*y/norm, box/norm);
+ }
+ }
+ }
+ }
+ /* ============= regular points for 'r Ln D2' =============== */
+ else if (isregular && islens && dim == 2) {
+ double cos_0;
+
+ angle= lensangle;
+ anglediff= 2 * lensangle/(numpoints - 1);
+ cos_0= cos(lensangle);
+ for (i=0; i < numpoints; i++, angle -= anglediff) {
+ x= radius * sin(angle);
+ y= radius * (cos(angle) - cos_0);
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ qh_out2n(qh, x*box, y*box);
+ if (i != 0 && i != numpoints - 1) {
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ qh_out2n(qh, x*box, -y*box);
+ }
+ }
+ }
+ /* ============= regular points for 'r Ln D3' =============== */
+ else if (isregular && islens && dim != 2) {
+ if (dim != 3) {
+ qh_free(simplex);
+ qh_fprintf_rbox(qh, qh->ferr, 6198, "rbox error: regular points can be used only in 2-d and 3-d\n\n");
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ angle= 0.0;
+ anglediff= 2* PI/numpoints;
+ if (!isgap) {
+ isgap= 1;
+ gap= 0.5;
+ }
+ offset= sqrt(radius * radius - (1-gap)*(1-gap)) - lensbase;
+ for (i=0; i < numpoints; i++, angle += anglediff) {
+ x= cos(angle);
+ y= sin(angle);
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ qh_out3n(qh, box*x, box*y, 0.0);
+ x *= 1-gap;
+ y *= 1-gap;
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ qh_out3n(qh, box*x, box*y, box * offset);
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ qh_out3n(qh, box*x, box*y, -box * offset);
+ }
+ }
+ /* ============= apex of 'Zn' distribution + gendim =============== */
+ else {
+ if (isaxis) {
+ gendim= dim-1;
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ for (j=0; j < gendim; j++)
+ qh_out1(qh, 0.0);
+ qh_out1(qh, -box);
+ qh_fprintf_rbox(qh, qh->fout, 9398, "\n");
+ }else if (islens)
+ gendim= dim-1;
+ else
+ gendim= dim;
+ /* ============= generate random point in unit cube =============== */
+ for (i=0; i < numpoints; i++) {
+ norm= 0.0;
+ for (j=0; j < gendim; j++) {
+ randr= qh_RANDOMint;
+ coord[j]= 2.0 * randr/randmax - 1.0;
+ norm += coord[j] * coord[j];
+ }
+ norm= sqrt(norm);
+ /* ============= dim-1 point of 'Zn' distribution ========== */
+ if (isaxis) {
+ if (!isgap) {
+ isgap= 1;
+ gap= 1.0;
+ }
+ randr= qh_RANDOMint;
+ rangap= 1.0 - gap * randr/randmax;
+ factor= radius * rangap / norm;
+ for (j=0; j<gendim; j++)
+ coord[j]= factor * coord[j];
+ /* ============= dim-1 point of 'Ln s' distribution =========== */
+ }else if (islens && issphere) {
+ if (!isgap) {
+ isgap= 1;
+ gap= 1.0;
+ }
+ randr= qh_RANDOMint;
+ rangap= 1.0 - gap * randr/randmax;
+ factor= rangap / norm;
+ for (j=0; j<gendim; j++)
+ coord[j]= factor * coord[j];
+ /* ============= dim-1 point of 'Ln' distribution ========== */
+ }else if (islens && !issphere) {
+ if (!isgap) {
+ isgap= 1;
+ gap= 1.0;
+ }
+ j= qh_RANDOMint % gendim;
+ if (coord[j] < 0)
+ coord[j]= -1.0 - coord[j] * gap;
+ else
+ coord[j]= 1.0 - coord[j] * gap;
+ /* ============= point of 'l' distribution =============== */
+ }else if (isspiral) {
+ if (dim != 3) {
+ qh_free(simplex);
+ qh_fprintf_rbox(qh, qh->ferr, 6199, "rbox error: spiral distribution is available only in 3d\n\n");
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ coord[0]= cos(2*PI*i/(numpoints - 1));
+ coord[1]= sin(2*PI*i/(numpoints - 1));
+ coord[2]= 2.0*(double)i/(double)(numpoints-1) - 1.0;
+ /* ============= point of 's' distribution =============== */
+ }else if (issphere) {
+ factor= 1.0/norm;
+ if (iswidth) {
+ randr= qh_RANDOMint;
+ factor *= 1.0 - width * randr/randmax;
+ }
+ for (j=0; j<dim; j++)
+ coord[j]= factor * coord[j];
+ }
+ /* ============= project 'Zn s' point in to sphere =============== */
+ if (isaxis && issphere) {
+ coord[dim-1]= 1.0;
+ norm= 1.0;
+ for (j=0; j<gendim; j++)
+ norm += coord[j] * coord[j];
+ norm= sqrt(norm);
+ for (j=0; j<dim; j++)
+ coord[j]= coord[j] / norm;
+ if (iswidth) {
+ randr= qh_RANDOMint;
+ coord[dim-1] *= 1 - width * randr/randmax;
+ }
+ /* ============= project 'Zn' point onto cube =============== */
+ }else if (isaxis && !issphere) { /* not very interesting */
+ randr= qh_RANDOMint;
+ coord[dim-1]= 2.0 * randr/randmax - 1.0;
+ /* ============= project 'Ln' point out to sphere =============== */
+ }else if (islens) {
+ coord[dim-1]= lensbase;
+ for (j=0, norm= 0; j<dim; j++)
+ norm += coord[j] * coord[j];
+ norm= sqrt(norm);
+ for (j=0; j<dim; j++)
+ coord[j]= coord[j] * radius/ norm;
+ coord[dim-1] -= lensbase;
+ if (iswidth) {
+ randr= qh_RANDOMint;
+ coord[dim-1] *= 1 - width * randr/randmax;
+ }
+ if (qh_RANDOMint > randmax/2)
+ coord[dim-1]= -coord[dim-1];
+ /* ============= project 'Wn' point toward boundary =============== */
+ }else if (iswidth && !issphere) {
+ j= qh_RANDOMint % gendim;
+ if (coord[j] < 0)
+ coord[j]= -1.0 - coord[j] * width;
+ else
+ coord[j]= 1.0 - coord[j] * width;
+ }
+ /* ============= scale point to box =============== */
+ for (k=0; k<dim; k++)
+ coord[k]= coord[k] * box;
+
+ /* ============= write output =============== */
+ qh_outcoord(qh, iscdd, coord, dim);
+ if(coincidentcount++ < coincidenttotal)
+ qh_outcoincident(qh, coincidentpoints, coincidentradius, iscdd, coord, dim);
+ }
+ }
+
+ /* ============= write cube vertices =============== */
+ if (addcube) {
+ for (j=0; j<cubesize; j++) {
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ for (k=dim-1; k>=0; k--) {
+ if (j & ( 1 << k))
+ qh_out1(qh, cube);
+ else
+ qh_out1(qh, -cube);
+ }
+ qh_fprintf_rbox(qh, qh->fout, 9400, "\n");
+ }
+ }
+
+ /* ============= write diamond vertices =============== */
+ if (adddiamond) {
+ for (j=0; j<diamondsize; j++) {
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ for (k=dim-1; k>=0; k--) {
+ if (j/2 != k)
+ qh_out1(qh, 0.0);
+ else if (j & 0x1)
+ qh_out1(qh, diamond);
+ else
+ qh_out1(qh, -diamond);
+ }
+ qh_fprintf_rbox(qh, qh->fout, 9401, "\n");
+ }
+ }
+
+ if (iscdd)
+ qh_fprintf_rbox(qh, qh->fout, 9402, "end\nhull\n");
+
+ /* same code for error exit and normal return */
+ qh_free(simplex);
+ return qh_ERRnone;
+} /* rboxpoints */
+
+/*------------------------------------------------
+outxxx - output functions for qh_rboxpoints
+*/
+int qh_roundi(qhT *qh, double a) {
+ if (a < 0.0) {
+ if (a - 0.5 < INT_MIN) {
+ qh_fprintf_rbox(qh, qh->ferr, 6200, "rbox input error: negative coordinate %2.2g is too large. Reduce 'Bn'\n", a);
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ return (int)(a - 0.5);
+ }else {
+ if (a + 0.5 > INT_MAX) {
+ qh_fprintf_rbox(qh, qh->ferr, 6201, "rbox input error: coordinate %2.2g is too large. Reduce 'Bn'\n", a);
+ qh_errexit_rbox(qh, qh_ERRinput);
+ }
+ return (int)(a + 0.5);
+ }
+} /* qh_roundi */
+
+void qh_out1(qhT *qh, double a) {
+
+ if (qh->rbox_isinteger)
+ qh_fprintf_rbox(qh, qh->fout, 9403, "%d ", qh_roundi(qh, a+qh->rbox_out_offset));
+ else
+ qh_fprintf_rbox(qh, qh->fout, 9404, qh_REAL_1, a+qh->rbox_out_offset);
+} /* qh_out1 */
+
+void qh_out2n(qhT *qh, double a, double b) {
+
+ if (qh->rbox_isinteger)
+ qh_fprintf_rbox(qh, qh->fout, 9405, "%d %d\n", qh_roundi(qh, a+qh->rbox_out_offset), qh_roundi(qh, b+qh->rbox_out_offset));
+ else
+ qh_fprintf_rbox(qh, qh->fout, 9406, qh_REAL_2n, a+qh->rbox_out_offset, b+qh->rbox_out_offset);
+} /* qh_out2n */
+
+void qh_out3n(qhT *qh, double a, double b, double c) {
+
+ if (qh->rbox_isinteger)
+ qh_fprintf_rbox(qh, qh->fout, 9407, "%d %d %d\n", qh_roundi(qh, a+qh->rbox_out_offset), qh_roundi(qh, b+qh->rbox_out_offset), qh_roundi(qh, c+qh->rbox_out_offset));
+ else
+ qh_fprintf_rbox(qh, qh->fout, 9408, qh_REAL_3n, a+qh->rbox_out_offset, b+qh->rbox_out_offset, c+qh->rbox_out_offset);
+} /* qh_out3n */
+
+void qh_outcoord(qhT *qh, int iscdd, double *coord, int dim) {
+ double *p= coord;
+ int k;
+
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ for (k=0; k < dim; k++)
+ qh_out1(qh, *(p++));
+ qh_fprintf_rbox(qh, qh->fout, 9396, "\n");
+} /* qh_outcoord */
+
+void qh_outcoincident(qhT *qh, int coincidentpoints, double radius, int iscdd, double *coord, int dim) {
+ double *p;
+ double randr, delta;
+ int i,k;
+ double randmax= qh_RANDOMmax;
+
+ for (i= 0; i<coincidentpoints; i++) {
+ p= coord;
+ if (iscdd)
+ qh_out1(qh, 1.0);
+ for (k=0; k < dim; k++) {
+ randr= qh_RANDOMint;
+ delta= 2.0 * randr/randmax - 1.0; /* -1..+1 */
+ delta *= radius;
+ qh_out1(qh, *(p++) + delta);
+ }
+ qh_fprintf_rbox(qh, qh->fout, 9410, "\n");
+ }
+} /* qh_outcoincident */
+
+/*------------------------------------------------
+ Only called from qh_rboxpoints or qh_fprintf_rbox
+ qh_fprintf_rbox is only called from qh_rboxpoints
+*/
+void qh_errexit_rbox(qhT *qh, int exitcode)
+{
+ longjmp(qh->rbox_errexit, exitcode);
+} /* qh_errexit_rbox */
+
diff --git a/xs/src/qhull/src/libqhull_r/stat_r.c b/xs/src/qhull/src/libqhull_r/stat_r.c
new file mode 100644
index 000000000..0f3ff0d3d
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/stat_r.c
@@ -0,0 +1,682 @@
+/*<html><pre> -<a href="qh-stat_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ stat_r.c
+ contains all statistics that are collected for qhull
+
+ see qh-stat_r.htm and stat_r.h
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/stat_r.c#5 $$Change: 2062 $
+ $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+*/
+
+#include "qhull_ra.h"
+
+/*========== functions in alphabetic order ================*/
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="allstatA">-</a>
+
+ qh_allstatA()
+ define statistics in groups of 20
+
+ notes:
+ (otherwise, 'gcc -O2' uses too much memory)
+ uses qhstat.next
+*/
+void qh_allstatA(qhT *qh) {
+
+ /* zdef_(type,name,doc,average) */
+ zzdef_(zdoc, Zdoc2, "precision statistics", -1);
+ zdef_(zinc, Znewvertex, NULL, -1);
+ zdef_(wadd, Wnewvertex, "ave. distance of a new vertex to a facet(!0s)", Znewvertex);
+ zzdef_(wmax, Wnewvertexmax, "max. distance of a new vertex to a facet", -1);
+ zdef_(wmax, Wvertexmax, "max. distance of an output vertex to a facet", -1);
+ zdef_(wmin, Wvertexmin, "min. distance of an output vertex to a facet", -1);
+ zdef_(wmin, Wmindenom, "min. denominator in hyperplane computation", -1);
+
+ qh->qhstat.precision= qh->qhstat.next; /* call qh_precision for each of these */
+ zzdef_(zdoc, Zdoc3, "precision problems (corrected unless 'Q0' or an error)", -1);
+ zzdef_(zinc, Zcoplanarridges, "coplanar half ridges in output", -1);
+ zzdef_(zinc, Zconcaveridges, "concave half ridges in output", -1);
+ zzdef_(zinc, Zflippedfacets, "flipped facets", -1);
+ zzdef_(zinc, Zcoplanarhorizon, "coplanar horizon facets for new vertices", -1);
+ zzdef_(zinc, Zcoplanarpart, "coplanar points during partitioning", -1);
+ zzdef_(zinc, Zminnorm, "degenerate hyperplanes recomputed with gaussian elimination", -1);
+ zzdef_(zinc, Znearlysingular, "nearly singular or axis-parallel hyperplanes", -1);
+ zzdef_(zinc, Zback0, "zero divisors during back substitute", -1);
+ zzdef_(zinc, Zgauss0, "zero divisors during gaussian elimination", -1);
+ zzdef_(zinc, Zmultiridge, "ridges with multiple neighbors", -1);
+}
+void qh_allstatB(qhT *qh) {
+ zzdef_(zdoc, Zdoc1, "summary information", -1);
+ zdef_(zinc, Zvertices, "number of vertices in output", -1);
+ zdef_(zinc, Znumfacets, "number of facets in output", -1);
+ zdef_(zinc, Znonsimplicial, "number of non-simplicial facets in output", -1);
+ zdef_(zinc, Znowsimplicial, "number of simplicial facets that were merged", -1);
+ zdef_(zinc, Znumridges, "number of ridges in output", -1);
+ zdef_(zadd, Znumridges, "average number of ridges per facet", Znumfacets);
+ zdef_(zmax, Zmaxridges, "maximum number of ridges", -1);
+ zdef_(zadd, Znumneighbors, "average number of neighbors per facet", Znumfacets);
+ zdef_(zmax, Zmaxneighbors, "maximum number of neighbors", -1);
+ zdef_(zadd, Znumvertices, "average number of vertices per facet", Znumfacets);
+ zdef_(zmax, Zmaxvertices, "maximum number of vertices", -1);
+ zdef_(zadd, Znumvneighbors, "average number of neighbors per vertex", Zvertices);
+ zdef_(zmax, Zmaxvneighbors, "maximum number of neighbors", -1);
+ zdef_(wadd, Wcpu, "cpu seconds for qhull after input", -1);
+ zdef_(zinc, Ztotvertices, "vertices created altogether", -1);
+ zzdef_(zinc, Zsetplane, "facets created altogether", -1);
+ zdef_(zinc, Ztotridges, "ridges created altogether", -1);
+ zdef_(zinc, Zpostfacets, "facets before post merge", -1);
+ zdef_(zadd, Znummergetot, "average merges per facet(at most 511)", Znumfacets);
+ zdef_(zmax, Znummergemax, " maximum merges for a facet(at most 511)", -1);
+ zdef_(zinc, Zangle, NULL, -1);
+ zdef_(wadd, Wangle, "average angle(cosine) of facet normals for all ridges", Zangle);
+ zdef_(wmax, Wanglemax, " maximum angle(cosine) of facet normals across a ridge", -1);
+ zdef_(wmin, Wanglemin, " minimum angle(cosine) of facet normals across a ridge", -1);
+ zdef_(wadd, Wareatot, "total area of facets", -1);
+ zdef_(wmax, Wareamax, " maximum facet area", -1);
+ zdef_(wmin, Wareamin, " minimum facet area", -1);
+}
+void qh_allstatC(qhT *qh) {
+ zdef_(zdoc, Zdoc9, "build hull statistics", -1);
+ zzdef_(zinc, Zprocessed, "points processed", -1);
+ zzdef_(zinc, Zretry, "retries due to precision problems", -1);
+ zdef_(wmax, Wretrymax, " max. random joggle", -1);
+ zdef_(zmax, Zmaxvertex, "max. vertices at any one time", -1);
+ zdef_(zinc, Ztotvisible, "ave. visible facets per iteration", Zprocessed);
+ zdef_(zinc, Zinsidevisible, " ave. visible facets without an horizon neighbor", Zprocessed);
+ zdef_(zadd, Zvisfacettot, " ave. facets deleted per iteration", Zprocessed);
+ zdef_(zmax, Zvisfacetmax, " maximum", -1);
+ zdef_(zadd, Zvisvertextot, "ave. visible vertices per iteration", Zprocessed);
+ zdef_(zmax, Zvisvertexmax, " maximum", -1);
+ zdef_(zinc, Ztothorizon, "ave. horizon facets per iteration", Zprocessed);
+ zdef_(zadd, Znewfacettot, "ave. new or merged facets per iteration", Zprocessed);
+ zdef_(zmax, Znewfacetmax, " maximum(includes initial simplex)", -1);
+ zdef_(wadd, Wnewbalance, "average new facet balance", Zprocessed);
+ zdef_(wadd, Wnewbalance2, " standard deviation", -1);
+ zdef_(wadd, Wpbalance, "average partition balance", Zpbalance);
+ zdef_(wadd, Wpbalance2, " standard deviation", -1);
+ zdef_(zinc, Zpbalance, " number of trials", -1);
+ zdef_(zinc, Zsearchpoints, "searches of all points for initial simplex", -1);
+ zdef_(zinc, Zdetsimplex, "determinants computed(area & initial hull)", -1);
+ zdef_(zinc, Znoarea, "determinants not computed because vertex too low", -1);
+ zdef_(zinc, Znotmax, "points ignored(!above max_outside)", -1);
+ zdef_(zinc, Znotgood, "points ignored(!above a good facet)", -1);
+ zdef_(zinc, Znotgoodnew, "points ignored(didn't create a good new facet)", -1);
+ zdef_(zinc, Zgoodfacet, "good facets found", -1);
+ zzdef_(zinc, Znumvisibility, "distance tests for facet visibility", -1);
+ zdef_(zinc, Zdistvertex, "distance tests to report minimum vertex", -1);
+ zzdef_(zinc, Ztotcheck, "points checked for facets' outer planes", -1);
+ zzdef_(zinc, Zcheckpart, " ave. distance tests per check", Ztotcheck);
+}
+void qh_allstatD(qhT *qh) {
+ zdef_(zinc, Zvisit, "resets of visit_id", -1);
+ zdef_(zinc, Zvvisit, " resets of vertex_visit", -1);
+ zdef_(zmax, Zvisit2max, " max visit_id/2", -1);
+ zdef_(zmax, Zvvisit2max, " max vertex_visit/2", -1);
+
+ zdef_(zdoc, Zdoc4, "partitioning statistics(see previous for outer planes)", -1);
+ zzdef_(zadd, Zdelvertextot, "total vertices deleted", -1);
+ zdef_(zmax, Zdelvertexmax, " maximum vertices deleted per iteration", -1);
+ zdef_(zinc, Zfindbest, "calls to findbest", -1);
+ zdef_(zadd, Zfindbesttot, " ave. facets tested", Zfindbest);
+ zdef_(zmax, Zfindbestmax, " max. facets tested", -1);
+ zdef_(zadd, Zfindcoplanar, " ave. coplanar search", Zfindbest);
+ zdef_(zinc, Zfindnew, "calls to findbestnew", -1);
+ zdef_(zadd, Zfindnewtot, " ave. facets tested", Zfindnew);
+ zdef_(zmax, Zfindnewmax, " max. facets tested", -1);
+ zdef_(zinc, Zfindnewjump, " ave. clearly better", Zfindnew);
+ zdef_(zinc, Zfindnewsharp, " calls due to qh_sharpnewfacets", -1);
+ zdef_(zinc, Zfindhorizon, "calls to findhorizon", -1);
+ zdef_(zadd, Zfindhorizontot, " ave. facets tested", Zfindhorizon);
+ zdef_(zmax, Zfindhorizonmax, " max. facets tested", -1);
+ zdef_(zinc, Zfindjump, " ave. clearly better", Zfindhorizon);
+ zdef_(zinc, Zparthorizon, " horizon facets better than bestfacet", -1);
+ zdef_(zinc, Zpartangle, "angle tests for repartitioned coplanar points", -1);
+ zdef_(zinc, Zpartflip, " repartitioned coplanar points for flipped orientation", -1);
+}
+void qh_allstatE(qhT *qh) {
+ zdef_(zinc, Zpartinside, "inside points", -1);
+ zdef_(zinc, Zpartnear, " inside points kept with a facet", -1);
+ zdef_(zinc, Zcoplanarinside, " inside points that were coplanar with a facet", -1);
+ zdef_(zinc, Zbestlower, "calls to findbestlower", -1);
+ zdef_(zinc, Zbestlowerv, " with search of vertex neighbors", -1);
+ zdef_(zinc, Zbestlowerall, " with rare search of all facets", -1);
+ zdef_(zmax, Zbestloweralln, " facets per search of all facets", -1);
+ zdef_(wadd, Wmaxout, "difference in max_outside at final check", -1);
+ zzdef_(zinc, Zpartitionall, "distance tests for initial partition", -1);
+ zdef_(zinc, Ztotpartition, "partitions of a point", -1);
+ zzdef_(zinc, Zpartition, "distance tests for partitioning", -1);
+ zzdef_(zinc, Zdistcheck, "distance tests for checking flipped facets", -1);
+ zzdef_(zinc, Zdistconvex, "distance tests for checking convexity", -1);
+ zdef_(zinc, Zdistgood, "distance tests for checking good point", -1);
+ zdef_(zinc, Zdistio, "distance tests for output", -1);
+ zdef_(zinc, Zdiststat, "distance tests for statistics", -1);
+ zdef_(zinc, Zdistplane, "total number of distance tests", -1);
+ zdef_(zinc, Ztotpartcoplanar, "partitions of coplanar points or deleted vertices", -1);
+ zzdef_(zinc, Zpartcoplanar, " distance tests for these partitions", -1);
+ zdef_(zinc, Zcomputefurthest, "distance tests for computing furthest", -1);
+}
+void qh_allstatE2(qhT *qh) {
+ zdef_(zdoc, Zdoc5, "statistics for matching ridges", -1);
+ zdef_(zinc, Zhashlookup, "total lookups for matching ridges of new facets", -1);
+ zdef_(zinc, Zhashtests, "average number of tests to match a ridge", Zhashlookup);
+ zdef_(zinc, Zhashridge, "total lookups of subridges(duplicates and boundary)", -1);
+ zdef_(zinc, Zhashridgetest, "average number of tests per subridge", Zhashridge);
+ zdef_(zinc, Zdupsame, "duplicated ridges in same merge cycle", -1);
+ zdef_(zinc, Zdupflip, "duplicated ridges with flipped facets", -1);
+
+ zdef_(zdoc, Zdoc6, "statistics for determining merges", -1);
+ zdef_(zinc, Zangletests, "angles computed for ridge convexity", -1);
+ zdef_(zinc, Zbestcentrum, "best merges used centrum instead of vertices",-1);
+ zzdef_(zinc, Zbestdist, "distance tests for best merge", -1);
+ zzdef_(zinc, Zcentrumtests, "distance tests for centrum convexity", -1);
+ zzdef_(zinc, Zdistzero, "distance tests for checking simplicial convexity", -1);
+ zdef_(zinc, Zcoplanarangle, "coplanar angles in getmergeset", -1);
+ zdef_(zinc, Zcoplanarcentrum, "coplanar centrums in getmergeset", -1);
+ zdef_(zinc, Zconcaveridge, "concave ridges in getmergeset", -1);
+}
+void qh_allstatF(qhT *qh) {
+ zdef_(zdoc, Zdoc7, "statistics for merging", -1);
+ zdef_(zinc, Zpremergetot, "merge iterations", -1);
+ zdef_(zadd, Zmergeinittot, "ave. initial non-convex ridges per iteration", Zpremergetot);
+ zdef_(zadd, Zmergeinitmax, " maximum", -1);
+ zdef_(zadd, Zmergesettot, " ave. additional non-convex ridges per iteration", Zpremergetot);
+ zdef_(zadd, Zmergesetmax, " maximum additional in one pass", -1);
+ zdef_(zadd, Zmergeinittot2, "initial non-convex ridges for post merging", -1);
+ zdef_(zadd, Zmergesettot2, " additional non-convex ridges", -1);
+ zdef_(wmax, Wmaxoutside, "max distance of vertex or coplanar point above facet(w/roundoff)", -1);
+ zdef_(wmin, Wminvertex, "max distance of merged vertex below facet(or roundoff)", -1);
+ zdef_(zinc, Zwidefacet, "centrums frozen due to a wide merge", -1);
+ zdef_(zinc, Zwidevertices, "centrums frozen due to extra vertices", -1);
+ zzdef_(zinc, Ztotmerge, "total number of facets or cycles of facets merged", -1);
+ zdef_(zinc, Zmergesimplex, "merged a simplex", -1);
+ zdef_(zinc, Zonehorizon, "simplices merged into coplanar horizon", -1);
+ zzdef_(zinc, Zcyclehorizon, "cycles of facets merged into coplanar horizon", -1);
+ zzdef_(zadd, Zcyclefacettot, " ave. facets per cycle", Zcyclehorizon);
+ zdef_(zmax, Zcyclefacetmax, " max. facets", -1);
+ zdef_(zinc, Zmergeintohorizon, "new facets merged into horizon", -1);
+ zdef_(zinc, Zmergenew, "new facets merged", -1);
+ zdef_(zinc, Zmergehorizon, "horizon facets merged into new facets", -1);
+ zdef_(zinc, Zmergevertex, "vertices deleted by merging", -1);
+ zdef_(zinc, Zcyclevertex, "vertices deleted by merging into coplanar horizon", -1);
+ zdef_(zinc, Zdegenvertex, "vertices deleted by degenerate facet", -1);
+ zdef_(zinc, Zmergeflipdup, "merges due to flipped facets in duplicated ridge", -1);
+ zdef_(zinc, Zneighbor, "merges due to redundant neighbors", -1);
+ zdef_(zadd, Ztestvneighbor, "non-convex vertex neighbors", -1);
+}
+void qh_allstatG(qhT *qh) {
+ zdef_(zinc, Zacoplanar, "merges due to angle coplanar facets", -1);
+ zdef_(wadd, Wacoplanartot, " average merge distance", Zacoplanar);
+ zdef_(wmax, Wacoplanarmax, " maximum merge distance", -1);
+ zdef_(zinc, Zcoplanar, "merges due to coplanar facets", -1);
+ zdef_(wadd, Wcoplanartot, " average merge distance", Zcoplanar);
+ zdef_(wmax, Wcoplanarmax, " maximum merge distance", -1);
+ zdef_(zinc, Zconcave, "merges due to concave facets", -1);
+ zdef_(wadd, Wconcavetot, " average merge distance", Zconcave);
+ zdef_(wmax, Wconcavemax, " maximum merge distance", -1);
+ zdef_(zinc, Zavoidold, "coplanar/concave merges due to avoiding old merge", -1);
+ zdef_(wadd, Wavoidoldtot, " average merge distance", Zavoidold);
+ zdef_(wmax, Wavoidoldmax, " maximum merge distance", -1);
+ zdef_(zinc, Zdegen, "merges due to degenerate facets", -1);
+ zdef_(wadd, Wdegentot, " average merge distance", Zdegen);
+ zdef_(wmax, Wdegenmax, " maximum merge distance", -1);
+ zdef_(zinc, Zflipped, "merges due to removing flipped facets", -1);
+ zdef_(wadd, Wflippedtot, " average merge distance", Zflipped);
+ zdef_(wmax, Wflippedmax, " maximum merge distance", -1);
+ zdef_(zinc, Zduplicate, "merges due to duplicated ridges", -1);
+ zdef_(wadd, Wduplicatetot, " average merge distance", Zduplicate);
+ zdef_(wmax, Wduplicatemax, " maximum merge distance", -1);
+}
+void qh_allstatH(qhT *qh) {
+ zdef_(zdoc, Zdoc8, "renamed vertex statistics", -1);
+ zdef_(zinc, Zrenameshare, "renamed vertices shared by two facets", -1);
+ zdef_(zinc, Zrenamepinch, "renamed vertices in a pinched facet", -1);
+ zdef_(zinc, Zrenameall, "renamed vertices shared by multiple facets", -1);
+ zdef_(zinc, Zfindfail, "rename failures due to duplicated ridges", -1);
+ zdef_(zinc, Zdupridge, " duplicate ridges detected", -1);
+ zdef_(zinc, Zdelridge, "deleted ridges due to renamed vertices", -1);
+ zdef_(zinc, Zdropneighbor, "dropped neighbors due to renamed vertices", -1);
+ zdef_(zinc, Zdropdegen, "degenerate facets due to dropped neighbors", -1);
+ zdef_(zinc, Zdelfacetdup, " facets deleted because of no neighbors", -1);
+ zdef_(zinc, Zremvertex, "vertices removed from facets due to no ridges", -1);
+ zdef_(zinc, Zremvertexdel, " deleted", -1);
+ zdef_(zinc, Zintersectnum, "vertex intersections for locating redundant vertices", -1);
+ zdef_(zinc, Zintersectfail, "intersections failed to find a redundant vertex", -1);
+ zdef_(zinc, Zintersect, "intersections found redundant vertices", -1);
+ zdef_(zadd, Zintersecttot, " ave. number found per vertex", Zintersect);
+ zdef_(zmax, Zintersectmax, " max. found for a vertex", -1);
+ zdef_(zinc, Zvertexridge, NULL, -1);
+ zdef_(zadd, Zvertexridgetot, " ave. number of ridges per tested vertex", Zvertexridge);
+ zdef_(zmax, Zvertexridgemax, " max. number of ridges per tested vertex", -1);
+
+ zdef_(zdoc, Zdoc10, "memory usage statistics(in bytes)", -1);
+ zdef_(zadd, Zmemfacets, "for facets and their normals, neighbor and vertex sets", -1);
+ zdef_(zadd, Zmemvertices, "for vertices and their neighbor sets", -1);
+ zdef_(zadd, Zmempoints, "for input points, outside and coplanar sets, and qhT",-1);
+ zdef_(zadd, Zmemridges, "for ridges and their vertex sets", -1);
+} /* allstat */
+
+void qh_allstatI(qhT *qh) {
+ qh->qhstat.vridges= qh->qhstat.next;
+ zzdef_(zdoc, Zdoc11, "Voronoi ridge statistics", -1);
+ zzdef_(zinc, Zridge, "non-simplicial Voronoi vertices for all ridges", -1);
+ zzdef_(wadd, Wridge, " ave. distance to ridge", Zridge);
+ zzdef_(wmax, Wridgemax, " max. distance to ridge", -1);
+ zzdef_(zinc, Zridgemid, "bounded ridges", -1);
+ zzdef_(wadd, Wridgemid, " ave. distance of midpoint to ridge", Zridgemid);
+ zzdef_(wmax, Wridgemidmax, " max. distance of midpoint to ridge", -1);
+ zzdef_(zinc, Zridgeok, "bounded ridges with ok normal", -1);
+ zzdef_(wadd, Wridgeok, " ave. angle to ridge", Zridgeok);
+ zzdef_(wmax, Wridgeokmax, " max. angle to ridge", -1);
+ zzdef_(zinc, Zridge0, "bounded ridges with near-zero normal", -1);
+ zzdef_(wadd, Wridge0, " ave. angle to ridge", Zridge0);
+ zzdef_(wmax, Wridge0max, " max. angle to ridge", -1);
+
+ zdef_(zdoc, Zdoc12, "Triangulation statistics(Qt)", -1);
+ zdef_(zinc, Ztricoplanar, "non-simplicial facets triangulated", -1);
+ zdef_(zadd, Ztricoplanartot, " ave. new facets created(may be deleted)", Ztricoplanar);
+ zdef_(zmax, Ztricoplanarmax, " max. new facets created", -1);
+ zdef_(zinc, Ztrinull, "null new facets deleted(duplicated vertex)", -1);
+ zdef_(zinc, Ztrimirror, "mirrored pairs of new facets deleted(same vertices)", -1);
+ zdef_(zinc, Ztridegen, "degenerate new facets in output(same ridge)", -1);
+} /* allstat */
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="allstatistics">-</a>
+
+ qh_allstatistics()
+ reset printed flag for all statistics
+*/
+void qh_allstatistics(qhT *qh) {
+ int i;
+
+ for(i=ZEND; i--; )
+ qh->qhstat.printed[i]= False;
+} /* allstatistics */
+
+#if qh_KEEPstatistics
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="collectstatistics">-</a>
+
+ qh_collectstatistics()
+ collect statistics for qh.facet_list
+
+*/
+void qh_collectstatistics(qhT *qh) {
+ facetT *facet, *neighbor, **neighborp;
+ vertexT *vertex, **vertexp;
+ realT dotproduct, dist;
+ int sizneighbors, sizridges, sizvertices, i;
+
+ qh->old_randomdist= qh->RANDOMdist;
+ qh->RANDOMdist= False;
+ zval_(Zmempoints)= qh->num_points * qh->normal_size + sizeof(qhT);
+ zval_(Zmemfacets)= 0;
+ zval_(Zmemridges)= 0;
+ zval_(Zmemvertices)= 0;
+ zval_(Zangle)= 0;
+ wval_(Wangle)= 0.0;
+ zval_(Znumridges)= 0;
+ zval_(Znumfacets)= 0;
+ zval_(Znumneighbors)= 0;
+ zval_(Znumvertices)= 0;
+ zval_(Znumvneighbors)= 0;
+ zval_(Znummergetot)= 0;
+ zval_(Znummergemax)= 0;
+ zval_(Zvertices)= qh->num_vertices - qh_setsize(qh, qh->del_vertices);
+ if (qh->MERGING || qh->APPROXhull || qh->JOGGLEmax < REALmax/2)
+ wmax_(Wmaxoutside, qh->max_outside);
+ if (qh->MERGING)
+ wmin_(Wminvertex, qh->min_vertex);
+ FORALLfacets
+ facet->seen= False;
+ if (qh->DELAUNAY) {
+ FORALLfacets {
+ if (facet->upperdelaunay != qh->UPPERdelaunay)
+ facet->seen= True; /* remove from angle statistics */
+ }
+ }
+ FORALLfacets {
+ if (facet->visible && qh->NEWfacets)
+ continue;
+ sizvertices= qh_setsize(qh, facet->vertices);
+ sizneighbors= qh_setsize(qh, facet->neighbors);
+ sizridges= qh_setsize(qh, facet->ridges);
+ zinc_(Znumfacets);
+ zadd_(Znumvertices, sizvertices);
+ zmax_(Zmaxvertices, sizvertices);
+ zadd_(Znumneighbors, sizneighbors);
+ zmax_(Zmaxneighbors, sizneighbors);
+ zadd_(Znummergetot, facet->nummerge);
+ i= facet->nummerge; /* avoid warnings */
+ zmax_(Znummergemax, i);
+ if (!facet->simplicial) {
+ if (sizvertices == qh->hull_dim) {
+ zinc_(Znowsimplicial);
+ }else {
+ zinc_(Znonsimplicial);
+ }
+ }
+ if (sizridges) {
+ zadd_(Znumridges, sizridges);
+ zmax_(Zmaxridges, sizridges);
+ }
+ zadd_(Zmemfacets, sizeof(facetT) + qh->normal_size + 2*sizeof(setT)
+ + SETelemsize * (sizneighbors + sizvertices));
+ if (facet->ridges) {
+ zadd_(Zmemridges,
+ sizeof(setT) + SETelemsize * sizridges + sizridges *
+ (sizeof(ridgeT) + sizeof(setT) + SETelemsize * (qh->hull_dim-1))/2);
+ }
+ if (facet->outsideset)
+ zadd_(Zmempoints, sizeof(setT) + SETelemsize * qh_setsize(qh, facet->outsideset));
+ if (facet->coplanarset)
+ zadd_(Zmempoints, sizeof(setT) + SETelemsize * qh_setsize(qh, facet->coplanarset));
+ if (facet->seen) /* Delaunay upper envelope */
+ continue;
+ facet->seen= True;
+ FOREACHneighbor_(facet) {
+ if (neighbor == qh_DUPLICATEridge || neighbor == qh_MERGEridge
+ || neighbor->seen || !facet->normal || !neighbor->normal)
+ continue;
+ dotproduct= qh_getangle(qh, facet->normal, neighbor->normal);
+ zinc_(Zangle);
+ wadd_(Wangle, dotproduct);
+ wmax_(Wanglemax, dotproduct)
+ wmin_(Wanglemin, dotproduct)
+ }
+ if (facet->normal) {
+ FOREACHvertex_(facet->vertices) {
+ zinc_(Zdiststat);
+ qh_distplane(qh, vertex->point, facet, &dist);
+ wmax_(Wvertexmax, dist);
+ wmin_(Wvertexmin, dist);
+ }
+ }
+ }
+ FORALLvertices {
+ if (vertex->deleted)
+ continue;
+ zadd_(Zmemvertices, sizeof(vertexT));
+ if (vertex->neighbors) {
+ sizneighbors= qh_setsize(qh, vertex->neighbors);
+ zadd_(Znumvneighbors, sizneighbors);
+ zmax_(Zmaxvneighbors, sizneighbors);
+ zadd_(Zmemvertices, sizeof(vertexT) + SETelemsize * sizneighbors);
+ }
+ }
+ qh->RANDOMdist= qh->old_randomdist;
+} /* collectstatistics */
+#endif /* qh_KEEPstatistics */
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="initstatistics">-</a>
+
+ qh_initstatistics(qh)
+ initialize statistics
+
+ notes:
+ NOerrors -- qh_initstatistics can not use qh_errexit(), qh_fprintf, or qh.ferr
+ On first call, only qhmem.ferr is defined. qh_memalloc is not setup.
+ Also invoked by QhullQh().
+*/
+void qh_initstatistics(qhT *qh) {
+ int i;
+ realT realx;
+ int intx;
+
+ qh->qhstat.next= 0;
+ qh_allstatA(qh);
+ qh_allstatB(qh);
+ qh_allstatC(qh);
+ qh_allstatD(qh);
+ qh_allstatE(qh);
+ qh_allstatE2(qh);
+ qh_allstatF(qh);
+ qh_allstatG(qh);
+ qh_allstatH(qh);
+ qh_allstatI(qh);
+ if (qh->qhstat.next > (int)sizeof(qh->qhstat.id)) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6184, "qhull error (qh_initstatistics): increase size of qhstat.id[].\n\
+ qhstat.next %d should be <= sizeof(qh->qhstat.id) %d\n", qh->qhstat.next, (int)sizeof(qh->qhstat.id));
+#if 0 /* for locating error, Znumridges should be duplicated */
+ for(i=0; i < ZEND; i++) {
+ int j;
+ for(j=i+1; j < ZEND; j++) {
+ if (qh->qhstat.id[i] == qh->qhstat.id[j]) {
+ qh_fprintf(qh, qh->qhmem.ferr, 6185, "qhull error (qh_initstatistics): duplicated statistic %d at indices %d and %d\n",
+ qh->qhstat.id[i], i, j);
+ }
+ }
+ }
+#endif
+ qh_exit(qh_ERRqhull); /* can not use qh_errexit() */
+ }
+ qh->qhstat.init[zinc].i= 0;
+ qh->qhstat.init[zadd].i= 0;
+ qh->qhstat.init[zmin].i= INT_MAX;
+ qh->qhstat.init[zmax].i= INT_MIN;
+ qh->qhstat.init[wadd].r= 0;
+ qh->qhstat.init[wmin].r= REALmax;
+ qh->qhstat.init[wmax].r= -REALmax;
+ for(i=0; i < ZEND; i++) {
+ if (qh->qhstat.type[i] > ZTYPEreal) {
+ realx= qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].r;
+ qh->qhstat.stats[i].r= realx;
+ }else if (qh->qhstat.type[i] != zdoc) {
+ intx= qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].i;
+ qh->qhstat.stats[i].i= intx;
+ }
+ }
+} /* initstatistics */
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="newstats">-</a>
+
+ qh_newstats(qh, )
+ returns True if statistics for zdoc
+
+ returns:
+ next zdoc
+*/
+boolT qh_newstats(qhT *qh, int idx, int *nextindex) {
+ boolT isnew= False;
+ int start, i;
+
+ if (qh->qhstat.type[qh->qhstat.id[idx]] == zdoc)
+ start= idx+1;
+ else
+ start= idx;
+ for(i= start; i < qh->qhstat.next && qh->qhstat.type[qh->qhstat.id[i]] != zdoc; i++) {
+ if (!qh_nostatistic(qh, qh->qhstat.id[i]) && !qh->qhstat.printed[qh->qhstat.id[i]])
+ isnew= True;
+ }
+ *nextindex= i;
+ return isnew;
+} /* newstats */
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="nostatistic">-</a>
+
+ qh_nostatistic(qh, index )
+ true if no statistic to print
+*/
+boolT qh_nostatistic(qhT *qh, int i) {
+
+ if ((qh->qhstat.type[i] > ZTYPEreal
+ &&qh->qhstat.stats[i].r == qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].r)
+ || (qh->qhstat.type[i] < ZTYPEreal
+ &&qh->qhstat.stats[i].i == qh->qhstat.init[(unsigned char)(qh->qhstat.type[i])].i))
+ return True;
+ return False;
+} /* nostatistic */
+
+#if qh_KEEPstatistics
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="printallstatistics">-</a>
+
+ qh_printallstatistics(qh, fp, string )
+ print all statistics with header 'string'
+*/
+void qh_printallstatistics(qhT *qh, FILE *fp, const char *string) {
+
+ qh_allstatistics(qh);
+ qh_collectstatistics(qh);
+ qh_printstatistics(qh, fp, string);
+ qh_memstatistics(qh, fp);
+}
+
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="printstatistics">-</a>
+
+ qh_printstatistics(qh, fp, string )
+ print statistics to a file with header 'string'
+ skips statistics with qhstat.printed[] (reset with qh_allstatistics)
+
+ see:
+ qh_printallstatistics()
+*/
+void qh_printstatistics(qhT *qh, FILE *fp, const char *string) {
+ int i, k;
+ realT ave;
+
+ if (qh->num_points != qh->num_vertices) {
+ wval_(Wpbalance)= 0;
+ wval_(Wpbalance2)= 0;
+ }else
+ wval_(Wpbalance2)= qh_stddev(zval_(Zpbalance), wval_(Wpbalance),
+ wval_(Wpbalance2), &ave);
+ wval_(Wnewbalance2)= qh_stddev(zval_(Zprocessed), wval_(Wnewbalance),
+ wval_(Wnewbalance2), &ave);
+ qh_fprintf(qh, fp, 9350, "\n\
+%s\n\
+ qhull invoked by: %s | %s\n%s with options:\n%s\n", string, qh->rbox_command,
+ qh->qhull_command, qh_version, qh->qhull_options);
+ qh_fprintf(qh, fp, 9351, "\nprecision constants:\n\
+ %6.2g max. abs. coordinate in the (transformed) input('Qbd:n')\n\
+ %6.2g max. roundoff error for distance computation('En')\n\
+ %6.2g max. roundoff error for angle computations\n\
+ %6.2g min. distance for outside points ('Wn')\n\
+ %6.2g min. distance for visible facets ('Vn')\n\
+ %6.2g max. distance for coplanar facets ('Un')\n\
+ %6.2g max. facet width for recomputing centrum and area\n\
+",
+ qh->MAXabs_coord, qh->DISTround, qh->ANGLEround, qh->MINoutside,
+ qh->MINvisible, qh->MAXcoplanar, qh->WIDEfacet);
+ if (qh->KEEPnearinside)
+ qh_fprintf(qh, fp, 9352, "\
+ %6.2g max. distance for near-inside points\n", qh->NEARinside);
+ if (qh->premerge_cos < REALmax/2) qh_fprintf(qh, fp, 9353, "\
+ %6.2g max. cosine for pre-merge angle\n", qh->premerge_cos);
+ if (qh->PREmerge) qh_fprintf(qh, fp, 9354, "\
+ %6.2g radius of pre-merge centrum\n", qh->premerge_centrum);
+ if (qh->postmerge_cos < REALmax/2) qh_fprintf(qh, fp, 9355, "\
+ %6.2g max. cosine for post-merge angle\n", qh->postmerge_cos);
+ if (qh->POSTmerge) qh_fprintf(qh, fp, 9356, "\
+ %6.2g radius of post-merge centrum\n", qh->postmerge_centrum);
+ qh_fprintf(qh, fp, 9357, "\
+ %6.2g max. distance for merging two simplicial facets\n\
+ %6.2g max. roundoff error for arithmetic operations\n\
+ %6.2g min. denominator for divisions\n\
+ zero diagonal for Gauss: ", qh->ONEmerge, REALepsilon, qh->MINdenom);
+ for(k=0; k < qh->hull_dim; k++)
+ qh_fprintf(qh, fp, 9358, "%6.2e ", qh->NEARzero[k]);
+ qh_fprintf(qh, fp, 9359, "\n\n");
+ for(i=0 ; i < qh->qhstat.next; )
+ qh_printstats(qh, fp, i, &i);
+} /* printstatistics */
+#endif /* qh_KEEPstatistics */
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="printstatlevel">-</a>
+
+ qh_printstatlevel(qh, fp, id )
+ print level information for a statistic
+
+ notes:
+ nop if id >= ZEND, printed, or same as initial value
+*/
+void qh_printstatlevel(qhT *qh, FILE *fp, int id) {
+#define NULLfield " "
+
+ if (id >= ZEND || qh->qhstat.printed[id])
+ return;
+ if (qh->qhstat.type[id] == zdoc) {
+ qh_fprintf(qh, fp, 9360, "%s\n", qh->qhstat.doc[id]);
+ return;
+ }
+ if (qh_nostatistic(qh, id) || !qh->qhstat.doc[id])
+ return;
+ qh->qhstat.printed[id]= True;
+ if (qh->qhstat.count[id] != -1
+ && qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i == 0)
+ qh_fprintf(qh, fp, 9361, " *0 cnt*");
+ else if (qh->qhstat.type[id] >= ZTYPEreal && qh->qhstat.count[id] == -1)
+ qh_fprintf(qh, fp, 9362, "%7.2g", qh->qhstat.stats[id].r);
+ else if (qh->qhstat.type[id] >= ZTYPEreal && qh->qhstat.count[id] != -1)
+ qh_fprintf(qh, fp, 9363, "%7.2g", qh->qhstat.stats[id].r/ qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i);
+ else if (qh->qhstat.type[id] < ZTYPEreal && qh->qhstat.count[id] == -1)
+ qh_fprintf(qh, fp, 9364, "%7d", qh->qhstat.stats[id].i);
+ else if (qh->qhstat.type[id] < ZTYPEreal && qh->qhstat.count[id] != -1)
+ qh_fprintf(qh, fp, 9365, "%7.3g", (realT) qh->qhstat.stats[id].i / qh->qhstat.stats[(unsigned char)(qh->qhstat.count[id])].i);
+ qh_fprintf(qh, fp, 9366, " %s\n", qh->qhstat.doc[id]);
+} /* printstatlevel */
+
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="printstats">-</a>
+
+ qh_printstats(qh, fp, index, nextindex )
+ print statistics for a zdoc group
+
+ returns:
+ next zdoc if non-null
+*/
+void qh_printstats(qhT *qh, FILE *fp, int idx, int *nextindex) {
+ int j, nexti;
+
+ if (qh_newstats(qh, idx, &nexti)) {
+ qh_fprintf(qh, fp, 9367, "\n");
+ for (j=idx; j<nexti; j++)
+ qh_printstatlevel(qh, fp, qh->qhstat.id[j]);
+ }
+ if (nextindex)
+ *nextindex= nexti;
+} /* printstats */
+
+#if qh_KEEPstatistics
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="stddev">-</a>
+
+ qh_stddev(num, tot, tot2, ave )
+ compute the standard deviation and average from statistics
+
+ tot2 is the sum of the squares
+ notes:
+ computes r.m.s.:
+ (x-ave)^2
+ == x^2 - 2x tot/num + (tot/num)^2
+ == tot2 - 2 tot tot/num + tot tot/num
+ == tot2 - tot ave
+*/
+realT qh_stddev(int num, realT tot, realT tot2, realT *ave) {
+ realT stddev;
+
+ *ave= tot/num;
+ stddev= sqrt(tot2/num - *ave * *ave);
+ return stddev;
+} /* stddev */
+
+#endif /* qh_KEEPstatistics */
+
+#if !qh_KEEPstatistics
+void qh_collectstatistics(qhT *qh) {}
+void qh_printallstatistics(qhT *qh, FILE *fp, char *string) {};
+void qh_printstatistics(qhT *qh, FILE *fp, char *string) {}
+#endif
+
diff --git a/xs/src/qhull/src/libqhull_r/stat_r.h b/xs/src/qhull/src/libqhull_r/stat_r.h
new file mode 100644
index 000000000..75e7d1057
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/stat_r.h
@@ -0,0 +1,533 @@
+/*<html><pre> -<a href="qh-stat_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ stat_r.h
+ contains all statistics that are collected for qhull
+
+ see qh-stat_r.htm and stat_r.c
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/libqhull_r/stat_r.h#5 $$Change: 2079 $
+ $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+
+ recompile qhull if you change this file
+
+ Integer statistics are Z* while real statistics are W*.
+
+ define MAYdebugx to call a routine at every statistic event
+
+*/
+
+#ifndef qhDEFstat
+#define qhDEFstat 1
+
+/* Depends on realT. Do not include libqhull_r to avoid circular dependency */
+
+#ifndef DEFqhT
+#define DEFqhT 1
+typedef struct qhT qhT; /* Defined by libqhull_r.h */
+#endif
+
+#ifndef DEFqhstatT
+#define DEFqhstatT 1
+typedef struct qhstatT qhstatT; /* Defined here */
+#endif
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="KEEPstatistics">-</a>
+
+ qh_KEEPstatistics
+ 0 turns off statistic gathering (except zzdef/zzinc/zzadd/zzval/wwval)
+*/
+#ifndef qh_KEEPstatistics
+#define qh_KEEPstatistics 1
+#endif
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="statistics">-</a>
+
+ Zxxx for integers, Wxxx for reals
+
+ notes:
+ be sure that all statistics are defined in stat_r.c
+ otherwise initialization may core dump
+ can pick up all statistics by:
+ grep '[zw].*_[(][ZW]' *.c >z.x
+ remove trailers with query">-</a>
+ remove leaders with query-replace-regexp [ ^I]+ (
+*/
+#if qh_KEEPstatistics
+enum qh_statistics { /* alphabetical after Z/W */
+ Zacoplanar,
+ Wacoplanarmax,
+ Wacoplanartot,
+ Zangle,
+ Wangle,
+ Wanglemax,
+ Wanglemin,
+ Zangletests,
+ Wareatot,
+ Wareamax,
+ Wareamin,
+ Zavoidold,
+ Wavoidoldmax,
+ Wavoidoldtot,
+ Zback0,
+ Zbestcentrum,
+ Zbestdist,
+ Zbestlower,
+ Zbestlowerall,
+ Zbestloweralln,
+ Zbestlowerv,
+ Zcentrumtests,
+ Zcheckpart,
+ Zcomputefurthest,
+ Zconcave,
+ Wconcavemax,
+ Wconcavetot,
+ Zconcaveridges,
+ Zconcaveridge,
+ Zcoplanar,
+ Wcoplanarmax,
+ Wcoplanartot,
+ Zcoplanarangle,
+ Zcoplanarcentrum,
+ Zcoplanarhorizon,
+ Zcoplanarinside,
+ Zcoplanarpart,
+ Zcoplanarridges,
+ Wcpu,
+ Zcyclefacetmax,
+ Zcyclefacettot,
+ Zcyclehorizon,
+ Zcyclevertex,
+ Zdegen,
+ Wdegenmax,
+ Wdegentot,
+ Zdegenvertex,
+ Zdelfacetdup,
+ Zdelridge,
+ Zdelvertextot,
+ Zdelvertexmax,
+ Zdetsimplex,
+ Zdistcheck,
+ Zdistconvex,
+ Zdistgood,
+ Zdistio,
+ Zdistplane,
+ Zdiststat,
+ Zdistvertex,
+ Zdistzero,
+ Zdoc1,
+ Zdoc2,
+ Zdoc3,
+ Zdoc4,
+ Zdoc5,
+ Zdoc6,
+ Zdoc7,
+ Zdoc8,
+ Zdoc9,
+ Zdoc10,
+ Zdoc11,
+ Zdoc12,
+ Zdropdegen,
+ Zdropneighbor,
+ Zdupflip,
+ Zduplicate,
+ Wduplicatemax,
+ Wduplicatetot,
+ Zdupridge,
+ Zdupsame,
+ Zflipped,
+ Wflippedmax,
+ Wflippedtot,
+ Zflippedfacets,
+ Zfindbest,
+ Zfindbestmax,
+ Zfindbesttot,
+ Zfindcoplanar,
+ Zfindfail,
+ Zfindhorizon,
+ Zfindhorizonmax,
+ Zfindhorizontot,
+ Zfindjump,
+ Zfindnew,
+ Zfindnewmax,
+ Zfindnewtot,
+ Zfindnewjump,
+ Zfindnewsharp,
+ Zgauss0,
+ Zgoodfacet,
+ Zhashlookup,
+ Zhashridge,
+ Zhashridgetest,
+ Zhashtests,
+ Zinsidevisible,
+ Zintersect,
+ Zintersectfail,
+ Zintersectmax,
+ Zintersectnum,
+ Zintersecttot,
+ Zmaxneighbors,
+ Wmaxout,
+ Wmaxoutside,
+ Zmaxridges,
+ Zmaxvertex,
+ Zmaxvertices,
+ Zmaxvneighbors,
+ Zmemfacets,
+ Zmempoints,
+ Zmemridges,
+ Zmemvertices,
+ Zmergeflipdup,
+ Zmergehorizon,
+ Zmergeinittot,
+ Zmergeinitmax,
+ Zmergeinittot2,
+ Zmergeintohorizon,
+ Zmergenew,
+ Zmergesettot,
+ Zmergesetmax,
+ Zmergesettot2,
+ Zmergesimplex,
+ Zmergevertex,
+ Wmindenom,
+ Wminvertex,
+ Zminnorm,
+ Zmultiridge,
+ Znearlysingular,
+ Zneighbor,
+ Wnewbalance,
+ Wnewbalance2,
+ Znewfacettot,
+ Znewfacetmax,
+ Znewvertex,
+ Wnewvertex,
+ Wnewvertexmax,
+ Znoarea,
+ Znonsimplicial,
+ Znowsimplicial,
+ Znotgood,
+ Znotgoodnew,
+ Znotmax,
+ Znumfacets,
+ Znummergemax,
+ Znummergetot,
+ Znumneighbors,
+ Znumridges,
+ Znumvertices,
+ Znumvisibility,
+ Znumvneighbors,
+ Zonehorizon,
+ Zpartangle,
+ Zpartcoplanar,
+ Zpartflip,
+ Zparthorizon,
+ Zpartinside,
+ Zpartition,
+ Zpartitionall,
+ Zpartnear,
+ Zpbalance,
+ Wpbalance,
+ Wpbalance2,
+ Zpostfacets,
+ Zpremergetot,
+ Zprocessed,
+ Zremvertex,
+ Zremvertexdel,
+ Zrenameall,
+ Zrenamepinch,
+ Zrenameshare,
+ Zretry,
+ Wretrymax,
+ Zridge,
+ Wridge,
+ Wridgemax,
+ Zridge0,
+ Wridge0,
+ Wridge0max,
+ Zridgemid,
+ Wridgemid,
+ Wridgemidmax,
+ Zridgeok,
+ Wridgeok,
+ Wridgeokmax,
+ Zsearchpoints,
+ Zsetplane,
+ Ztestvneighbor,
+ Ztotcheck,
+ Ztothorizon,
+ Ztotmerge,
+ Ztotpartcoplanar,
+ Ztotpartition,
+ Ztotridges,
+ Ztotvertices,
+ Ztotvisible,
+ Ztricoplanar,
+ Ztricoplanarmax,
+ Ztricoplanartot,
+ Ztridegen,
+ Ztrimirror,
+ Ztrinull,
+ Wvertexmax,
+ Wvertexmin,
+ Zvertexridge,
+ Zvertexridgetot,
+ Zvertexridgemax,
+ Zvertices,
+ Zvisfacettot,
+ Zvisfacetmax,
+ Zvisit,
+ Zvisit2max,
+ Zvisvertextot,
+ Zvisvertexmax,
+ Zvvisit,
+ Zvvisit2max,
+ Zwidefacet,
+ Zwidevertices,
+ ZEND};
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="ZZstat">-</a>
+
+ Zxxx/Wxxx statistics that remain defined if qh_KEEPstatistics=0
+
+ notes:
+ be sure to use zzdef, zzinc, etc. with these statistics (no double checking!)
+*/
+#else
+enum qh_statistics { /* for zzdef etc. macros */
+ Zback0,
+ Zbestdist,
+ Zcentrumtests,
+ Zcheckpart,
+ Zconcaveridges,
+ Zcoplanarhorizon,
+ Zcoplanarpart,
+ Zcoplanarridges,
+ Zcyclefacettot,
+ Zcyclehorizon,
+ Zdelvertextot,
+ Zdistcheck,
+ Zdistconvex,
+ Zdistzero,
+ Zdoc1,
+ Zdoc2,
+ Zdoc3,
+ Zdoc11,
+ Zflippedfacets,
+ Zgauss0,
+ Zminnorm,
+ Zmultiridge,
+ Znearlysingular,
+ Wnewvertexmax,
+ Znumvisibility,
+ Zpartcoplanar,
+ Zpartition,
+ Zpartitionall,
+ Zprocessed,
+ Zretry,
+ Zridge,
+ Wridge,
+ Wridgemax,
+ Zridge0,
+ Wridge0,
+ Wridge0max,
+ Zridgemid,
+ Wridgemid,
+ Wridgemidmax,
+ Zridgeok,
+ Wridgeok,
+ Wridgeokmax,
+ Zsetplane,
+ Ztotcheck,
+ Ztotmerge,
+ ZEND};
+#endif
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >-------------------------------</a><a name="ztype">-</a>
+
+ ztype
+ the type of a statistic sets its initial value.
+
+ notes:
+ The type should be the same as the macro for collecting the statistic
+*/
+enum ztypes {zdoc,zinc,zadd,zmax,zmin,ZTYPEreal,wadd,wmax,wmin,ZTYPEend};
+
+/*========== macros and constants =============*/
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >--------------------------------</a><a name="MAYdebugx">-</a>
+
+ MAYdebugx
+ define as maydebug() to be called frequently for error trapping
+*/
+#define MAYdebugx
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >--------------------------------</a><a name="zdef_">-</a>
+
+ zzdef_, zdef_( type, name, doc, -1)
+ define a statistic (assumes 'qhstat.next= 0;')
+
+ zdef_( type, name, doc, count)
+ define an averaged statistic
+ printed as name/count
+*/
+#define zzdef_(stype,name,string,cnt) qh->qhstat.id[qh->qhstat.next++]=name; \
+ qh->qhstat.doc[name]= string; qh->qhstat.count[name]= cnt; qh->qhstat.type[name]= stype
+#if qh_KEEPstatistics
+#define zdef_(stype,name,string,cnt) qh->qhstat.id[qh->qhstat.next++]=name; \
+ qh->qhstat.doc[name]= string; qh->qhstat.count[name]= cnt; qh->qhstat.type[name]= stype
+#else
+#define zdef_(type,name,doc,count)
+#endif
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >--------------------------------</a><a name="zinc_">-</a>
+
+ zzinc_( name ), zinc_( name)
+ increment an integer statistic
+*/
+#define zzinc_(id) {MAYdebugx; qh->qhstat.stats[id].i++;}
+#if qh_KEEPstatistics
+#define zinc_(id) {MAYdebugx; qh->qhstat.stats[id].i++;}
+#else
+#define zinc_(id) {}
+#endif
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >--------------------------------</a><a name="zadd_">-</a>
+
+ zzadd_( name, value ), zadd_( name, value ), wadd_( name, value )
+ add value to an integer or real statistic
+*/
+#define zzadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].i += (val);}
+#define wwadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].r += (val);}
+#if qh_KEEPstatistics
+#define zadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].i += (val);}
+#define wadd_(id, val) {MAYdebugx; qh->qhstat.stats[id].r += (val);}
+#else
+#define zadd_(id, val) {}
+#define wadd_(id, val) {}
+#endif
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >--------------------------------</a><a name="zval_">-</a>
+
+ zzval_( name ), zval_( name ), wwval_( name )
+ set or return value of a statistic
+*/
+#define zzval_(id) ((qh->qhstat.stats[id]).i)
+#define wwval_(id) ((qh->qhstat.stats[id]).r)
+#if qh_KEEPstatistics
+#define zval_(id) ((qh->qhstat.stats[id]).i)
+#define wval_(id) ((qh->qhstat.stats[id]).r)
+#else
+#define zval_(id) qh->qhstat.tempi
+#define wval_(id) qh->qhstat.tempr
+#endif
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >--------------------------------</a><a name="zmax_">-</a>
+
+ zmax_( id, val ), wmax_( id, value )
+ maximize id with val
+*/
+#define wwmax_(id, val) {MAYdebugx; maximize_(qh->qhstat.stats[id].r,(val));}
+#if qh_KEEPstatistics
+#define zmax_(id, val) {MAYdebugx; maximize_(qh->qhstat.stats[id].i,(val));}
+#define wmax_(id, val) {MAYdebugx; maximize_(qh->qhstat.stats[id].r,(val));}
+#else
+#define zmax_(id, val) {}
+#define wmax_(id, val) {}
+#endif
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >--------------------------------</a><a name="zmin_">-</a>
+
+ zmin_( id, val ), wmin_( id, value )
+ minimize id with val
+*/
+#if qh_KEEPstatistics
+#define zmin_(id, val) {MAYdebugx; minimize_(qh->qhstat.stats[id].i,(val));}
+#define wmin_(id, val) {MAYdebugx; minimize_(qh->qhstat.stats[id].r,(val));}
+#else
+#define zmin_(id, val) {}
+#define wmin_(id, val) {}
+#endif
+
+/*================== stat_r.h types ==============*/
+
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >--------------------------------</a><a name="intrealT">-</a>
+
+ intrealT
+ union of integer and real, used for statistics
+*/
+typedef union intrealT intrealT; /* union of int and realT */
+union intrealT {
+ int i;
+ realT r;
+};
+
+/*-<a href="qh-stat_r.htm#TOC"
+ >--------------------------------</a><a name="qhstat">-</a>
+
+ qhstat
+ Data structure for statistics, similar to qh and qhrbox
+
+ Allocated as part of qhT (libqhull_r.h)
+*/
+
+struct qhstatT {
+ intrealT stats[ZEND]; /* integer and real statistics */
+ unsigned char id[ZEND+10]; /* id's in print order */
+ const char *doc[ZEND]; /* array of documentation strings */
+ short int count[ZEND]; /* -1 if none, else index of count to use */
+ char type[ZEND]; /* type, see ztypes above */
+ char printed[ZEND]; /* true, if statistic has been printed */
+ intrealT init[ZTYPEend]; /* initial values by types, set initstatistics */
+
+ int next; /* next index for zdef_ */
+ int precision; /* index for precision problems */
+ int vridges; /* index for Voronoi ridges */
+ int tempi;
+ realT tempr;
+};
+
+/*========== function prototypes ===========*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void qh_allstatA(qhT *qh);
+void qh_allstatB(qhT *qh);
+void qh_allstatC(qhT *qh);
+void qh_allstatD(qhT *qh);
+void qh_allstatE(qhT *qh);
+void qh_allstatE2(qhT *qh);
+void qh_allstatF(qhT *qh);
+void qh_allstatG(qhT *qh);
+void qh_allstatH(qhT *qh);
+void qh_allstatI(qhT *qh);
+void qh_allstatistics(qhT *qh);
+void qh_collectstatistics(qhT *qh);
+void qh_initstatistics(qhT *qh);
+boolT qh_newstats(qhT *qh, int idx, int *nextindex);
+boolT qh_nostatistic(qhT *qh, int i);
+void qh_printallstatistics(qhT *qh, FILE *fp, const char *string);
+void qh_printstatistics(qhT *qh, FILE *fp, const char *string);
+void qh_printstatlevel(qhT *qh, FILE *fp, int id);
+void qh_printstats(qhT *qh, FILE *fp, int idx, int *nextindex);
+realT qh_stddev(int num, realT tot, realT tot2, realT *ave);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* qhDEFstat */
diff --git a/xs/src/qhull/src/libqhull_r/user_r.c b/xs/src/qhull/src/libqhull_r/user_r.c
new file mode 100644
index 000000000..bf7ed1d8d
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/user_r.c
@@ -0,0 +1,527 @@
+/*<html><pre> -<a href="qh-user_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ user.c
+ user redefinable functions
+
+ see user2_r.c for qh_fprintf, qh_malloc, qh_free
+
+ see README.txt see COPYING.txt for copyright information.
+
+ see libqhull_r.h for data structures, macros, and user-callable functions.
+
+ see user_eg.c, user_eg2.c, and unix.c for examples.
+
+ see user.h for user-definable constants
+
+ use qh_NOmem in mem_r.h to turn off memory management
+ use qh_NOmerge in user.h to turn off facet merging
+ set qh_KEEPstatistics in user.h to 0 to turn off statistics
+
+ This is unsupported software. You're welcome to make changes,
+ but you're on your own if something goes wrong. Use 'Tc' to
+ check frequently. Usually qhull will report an error if
+ a data structure becomes inconsistent. If so, it also reports
+ the last point added to the hull, e.g., 102. You can then trace
+ the execution of qhull with "T4P102".
+
+ Please report any errors that you fix to qhull@qhull.org
+
+ Qhull-template is a template for calling qhull from within your application
+
+ if you recompile and load this module, then user.o will not be loaded
+ from qhull.a
+
+ you can add additional quick allocation sizes in qh_user_memsizes
+
+ if the other functions here are redefined to not use qh_print...,
+ then io.o will not be loaded from qhull.a. See user_eg_r.c for an
+ example. We recommend keeping io.o for the extra debugging
+ information it supplies.
+*/
+
+#include "qhull_ra.h"
+
+#include <stdarg.h>
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="qhull_template">-</a>
+
+ Qhull-template
+ Template for calling qhull from inside your program
+
+ returns:
+ exit code(see qh_ERR... in libqhull_r.h)
+ all memory freed
+
+ notes:
+ This can be called any number of times.
+
+*/
+#if 0
+{
+ int dim; /* dimension of points */
+ int numpoints; /* number of points */
+ coordT *points; /* array of coordinates for each point */
+ boolT ismalloc; /* True if qhull should free points in qh_freeqhull() or reallocation */
+ char flags[]= "qhull Tv"; /* option flags for qhull, see qh_opt.htm */
+ FILE *outfile= stdout; /* output from qh_produce_output(qh)
+ use NULL to skip qh_produce_output(qh) */
+ FILE *errfile= stderr; /* error messages from qhull code */
+ int exitcode; /* 0 if no error from qhull */
+ facetT *facet; /* set by FORALLfacets */
+ int curlong, totlong; /* memory remaining after qh_memfreeshort */
+
+ qhT qh_qh; /* Qhull's data structure. First argument of most calls */
+ qhT *qh= &qh_qh; /* Alternatively -- qhT *qh= (qhT*)malloc(sizeof(qhT)) */
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ qh_zero(qh, errfile);
+
+ /* initialize dim, numpoints, points[], ismalloc here */
+ exitcode= qh_new_qhull(qh, dim, numpoints, points, ismalloc,
+ flags, outfile, errfile);
+ if (!exitcode) { /* if no error */
+ /* 'qh->facet_list' contains the convex hull */
+ FORALLfacets {
+ /* ... your code ... */
+ }
+ }
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf(qh, errfile, 7068, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n", totlong, curlong);
+}
+#endif
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="new_qhull">-</a>
+
+ qh_new_qhull(qh, dim, numpoints, points, ismalloc, qhull_cmd, outfile, errfile )
+ Run qhull and return results in qh.
+ Returns exitcode (0 if no errors).
+ Before first call, either call qh_zero(qh, errfile), or set qh to all zero.
+
+ notes:
+ do not modify points until finished with results.
+ The qhull data structure contains pointers into the points array.
+ do not call qhull functions before qh_new_qhull().
+ The qhull data structure is not initialized until qh_new_qhull().
+ do not call qh_init_A (global_r.c)
+
+ Default errfile is stderr, outfile may be null
+ qhull_cmd must start with "qhull "
+ projects points to a new point array for Delaunay triangulations ('d' and 'v')
+ transforms points into a new point array for halfspace intersection ('H')
+
+ see:
+ Qhull-template at the beginning of this file.
+ An example of using qh_new_qhull is user_eg_r.c
+*/
+int qh_new_qhull(qhT *qh, int dim, int numpoints, coordT *points, boolT ismalloc,
+ char *qhull_cmd, FILE *outfile, FILE *errfile) {
+ /* gcc may issue a "might be clobbered" warning for dim, points, and ismalloc [-Wclobbered].
+ These parameters are not referenced after a longjmp() and hence not clobbered.
+ See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
+ int exitcode, hulldim;
+ boolT new_ismalloc;
+ coordT *new_points;
+
+ if(!errfile){
+ errfile= stderr;
+ }
+ if (!qh->qhmem.ferr) {
+ qh_meminit(qh, errfile);
+ } else {
+ qh_memcheck(qh);
+ }
+ if (strncmp(qhull_cmd, "qhull ", (size_t)6)) {
+ qh_fprintf(qh, errfile, 6186, "qhull error (qh_new_qhull): start qhull_cmd argument with \"qhull \"\n");
+ return qh_ERRinput;
+ }
+ qh_initqhull_start(qh, NULL, outfile, errfile);
+ trace1((qh, qh->ferr, 1044, "qh_new_qhull: build new Qhull for %d %d-d points with %s\n", numpoints, dim, qhull_cmd));
+ exitcode = setjmp(qh->errexit);
+ if (!exitcode)
+ {
+ qh->NOerrexit = False;
+ qh_initflags(qh, qhull_cmd);
+ if (qh->DELAUNAY)
+ qh->PROJECTdelaunay= True;
+ if (qh->HALFspace) {
+ /* points is an array of halfspaces,
+ the last coordinate of each halfspace is its offset */
+ hulldim= dim-1;
+ qh_setfeasible(qh, hulldim);
+ new_points= qh_sethalfspace_all(qh, dim, numpoints, points, qh->feasible_point);
+ new_ismalloc= True;
+ if (ismalloc)
+ qh_free(points);
+ }else {
+ hulldim= dim;
+ new_points= points;
+ new_ismalloc= ismalloc;
+ }
+ qh_init_B(qh, new_points, numpoints, hulldim, new_ismalloc);
+ qh_qhull(qh);
+ qh_check_output(qh);
+ if (outfile) {
+ qh_produce_output(qh);
+ }else {
+ qh_prepare_output(qh);
+ }
+ if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ }
+ qh->NOerrexit = True;
+ return exitcode;
+} /* new_qhull */
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="errexit">-</a>
+
+ qh_errexit(qh, exitcode, facet, ridge )
+ report and exit from an error
+ report facet and ridge if non-NULL
+ reports useful information such as last point processed
+ set qh.FORCEoutput to print neighborhood of facet
+
+ see:
+ qh_errexit2() in libqhull_r.c for printing 2 facets
+
+ design:
+ check for error within error processing
+ compute qh.hulltime
+ print facet and ridge (if any)
+ report commandString, options, qh.furthest_id
+ print summary and statistics (including precision statistics)
+ if qh_ERRsingular
+ print help text for singular data set
+ exit program via long jump (if defined) or exit()
+*/
+void qh_errexit(qhT *qh, int exitcode, facetT *facet, ridgeT *ridge) {
+
+ if (qh->ERREXITcalled) {
+ qh_fprintf(qh, qh->ferr, 8126, "\nqhull error while processing previous error. Exit program\n");
+ qh_exit(qh_ERRqhull);
+ }
+ qh->ERREXITcalled= True;
+ if (!qh->QHULLfinished)
+ qh->hulltime= qh_CPUclock - qh->hulltime;
+ qh_errprint(qh, "ERRONEOUS", facet, NULL, ridge, NULL);
+ qh_fprintf(qh, qh->ferr, 8127, "\nWhile executing: %s | %s\n", qh->rbox_command, qh->qhull_command);
+ qh_fprintf(qh, qh->ferr, 8128, "Options selected for Qhull %s:\n%s\n", qh_version, qh->qhull_options);
+ if (qh->furthest_id >= 0) {
+ qh_fprintf(qh, qh->ferr, 8129, "Last point added to hull was p%d.", qh->furthest_id);
+ if (zzval_(Ztotmerge))
+ qh_fprintf(qh, qh->ferr, 8130, " Last merge was #%d.", zzval_(Ztotmerge));
+ if (qh->QHULLfinished)
+ qh_fprintf(qh, qh->ferr, 8131, "\nQhull has finished constructing the hull.");
+ else if (qh->POSTmerging)
+ qh_fprintf(qh, qh->ferr, 8132, "\nQhull has started post-merging.");
+ qh_fprintf(qh, qh->ferr, 8133, "\n");
+ }
+ if (qh->FORCEoutput && (qh->QHULLfinished || (!facet && !ridge)))
+ qh_produce_output(qh);
+ else if (exitcode != qh_ERRinput) {
+ if (exitcode != qh_ERRsingular && zzval_(Zsetplane) > qh->hull_dim+1) {
+ qh_fprintf(qh, qh->ferr, 8134, "\nAt error exit:\n");
+ qh_printsummary(qh, qh->ferr);
+ if (qh->PRINTstatistics) {
+ qh_collectstatistics(qh);
+ qh_printstatistics(qh, qh->ferr, "at error exit");
+ qh_memstatistics(qh, qh->ferr);
+ }
+ }
+ if (qh->PRINTprecision)
+ qh_printstats(qh, qh->ferr, qh->qhstat.precision, NULL);
+ }
+ if (!exitcode)
+ exitcode= qh_ERRqhull;
+ else if (exitcode == qh_ERRsingular)
+ qh_printhelp_singular(qh, qh->ferr);
+ else if (exitcode == qh_ERRprec && !qh->PREmerge)
+ qh_printhelp_degenerate(qh, qh->ferr);
+ if (qh->NOerrexit) {
+ qh_fprintf(qh, qh->ferr, 6187, "qhull error while ending program, or qh->NOerrexit not cleared after setjmp(). Exit program with error.\n");
+ qh_exit(qh_ERRqhull);
+ }
+ qh->ERREXITcalled= False;
+ qh->NOerrexit= True;
+ qh->ALLOWrestart= False; /* longjmp will undo qh_build_withrestart */
+ longjmp(qh->errexit, exitcode);
+} /* errexit */
+
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="errprint">-</a>
+
+ qh_errprint(qh, fp, string, atfacet, otherfacet, atridge, atvertex )
+ prints out the information of facets and ridges to fp
+ also prints neighbors and geomview output
+
+ notes:
+ except for string, any parameter may be NULL
+*/
+void qh_errprint(qhT *qh, const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
+ int i;
+
+ if (atfacet) {
+ qh_fprintf(qh, qh->ferr, 8135, "%s FACET:\n", string);
+ qh_printfacet(qh, qh->ferr, atfacet);
+ }
+ if (otherfacet) {
+ qh_fprintf(qh, qh->ferr, 8136, "%s OTHER FACET:\n", string);
+ qh_printfacet(qh, qh->ferr, otherfacet);
+ }
+ if (atridge) {
+ qh_fprintf(qh, qh->ferr, 8137, "%s RIDGE:\n", string);
+ qh_printridge(qh, qh->ferr, atridge);
+ if (atridge->top && atridge->top != atfacet && atridge->top != otherfacet)
+ qh_printfacet(qh, qh->ferr, atridge->top);
+ if (atridge->bottom
+ && atridge->bottom != atfacet && atridge->bottom != otherfacet)
+ qh_printfacet(qh, qh->ferr, atridge->bottom);
+ if (!atfacet)
+ atfacet= atridge->top;
+ if (!otherfacet)
+ otherfacet= otherfacet_(atridge, atfacet);
+ }
+ if (atvertex) {
+ qh_fprintf(qh, qh->ferr, 8138, "%s VERTEX:\n", string);
+ qh_printvertex(qh, qh->ferr, atvertex);
+ }
+ if (qh->fout && qh->FORCEoutput && atfacet && !qh->QHULLfinished && !qh->IStracing) {
+ qh_fprintf(qh, qh->ferr, 8139, "ERRONEOUS and NEIGHBORING FACETS to output\n");
+ for (i=0; i < qh_PRINTEND; i++) /* use fout for geomview output */
+ qh_printneighborhood(qh, qh->fout, qh->PRINTout[i], atfacet, otherfacet,
+ !qh_ALL);
+ }
+} /* errprint */
+
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="printfacetlist">-</a>
+
+ qh_printfacetlist(qh, fp, facetlist, facets, printall )
+ print all fields for a facet list and/or set of facets to fp
+ if !printall,
+ only prints good facets
+
+ notes:
+ also prints all vertices
+*/
+void qh_printfacetlist(qhT *qh, facetT *facetlist, setT *facets, boolT printall) {
+ facetT *facet, **facetp;
+
+ qh_printbegin(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);
+ FORALLfacet_(facetlist)
+ qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall);
+ FOREACHfacet_(facets)
+ qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall);
+ qh_printend(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);
+} /* printfacetlist */
+
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printhelp_degenerate">-</a>
+
+ qh_printhelp_degenerate(qh, fp )
+ prints descriptive message for precision error
+
+ notes:
+ no message if qh_QUICKhelp
+*/
+void qh_printhelp_degenerate(qhT *qh, FILE *fp) {
+
+ if (qh->MERGEexact || qh->PREmerge || qh->JOGGLEmax < REALmax/2)
+ qh_fprintf(qh, fp, 9368, "\n\
+A Qhull error has occurred. Qhull should have corrected the above\n\
+precision error. Please send the input and all of the output to\n\
+qhull_bug@qhull.org\n");
+ else if (!qh_QUICKhelp) {
+ qh_fprintf(qh, fp, 9369, "\n\
+Precision problems were detected during construction of the convex hull.\n\
+This occurs because convex hull algorithms assume that calculations are\n\
+exact, but floating-point arithmetic has roundoff errors.\n\
+\n\
+To correct for precision problems, do not use 'Q0'. By default, Qhull\n\
+selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',\n\
+Qhull joggles the input to prevent precision problems. See \"Imprecision\n\
+in Qhull\" (qh-impre.htm).\n\
+\n\
+If you use 'Q0', the output may include\n\
+coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,\n\
+Qhull may produce a ridge with four neighbors or two facets with the same \n\
+vertices. Qhull reports these events when they occur. It stops when a\n\
+concave ridge, flipped facet, or duplicate facet occurs.\n");
+#if REALfloat
+ qh_fprintf(qh, fp, 9370, "\
+\n\
+Qhull is currently using single precision arithmetic. The following\n\
+will probably remove the precision problems:\n\
+ - recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
+#endif
+ if (qh->DELAUNAY && !qh->SCALElast && qh->MAXabs_coord > 1e4)
+ qh_fprintf(qh, fp, 9371, "\
+\n\
+When computing the Delaunay triangulation of coordinates > 1.0,\n\
+ - use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n");
+ if (qh->DELAUNAY && !qh->ATinfinity)
+ qh_fprintf(qh, fp, 9372, "\
+When computing the Delaunay triangulation:\n\
+ - use 'Qz' to add a point at-infinity. This reduces precision problems.\n");
+
+ qh_fprintf(qh, fp, 9373, "\
+\n\
+If you need triangular output:\n\
+ - use option 'Qt' to triangulate the output\n\
+ - use option 'QJ' to joggle the input points and remove precision errors\n\
+ - use option 'Ft'. It triangulates non-simplicial facets with added points.\n\
+\n\
+If you must use 'Q0',\n\
+try one or more of the following options. They can not guarantee an output.\n\
+ - use 'QbB' to scale the input to a cube.\n\
+ - use 'Po' to produce output and prevent partitioning for flipped facets\n\
+ - use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\
+ - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
+ - options 'Qf', 'Qbb', and 'QR0' may also help\n",
+ qh->DISTround);
+ qh_fprintf(qh, fp, 9374, "\
+\n\
+To guarantee simplicial output:\n\
+ - use option 'Qt' to triangulate the output\n\
+ - use option 'QJ' to joggle the input points and remove precision errors\n\
+ - use option 'Ft' to triangulate the output by adding points\n\
+ - use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\
+");
+ }
+} /* printhelp_degenerate */
+
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="printhelp_narrowhull">-</a>
+
+ qh_printhelp_narrowhull(qh, minangle )
+ Warn about a narrow hull
+
+ notes:
+ Alternatively, reduce qh_WARNnarrow in user.h
+
+*/
+void qh_printhelp_narrowhull(qhT *qh, FILE *fp, realT minangle) {
+
+ qh_fprintf(qh, fp, 9375, "qhull precision warning: \n\
+The initial hull is narrow (cosine of min. angle is %.16f).\n\
+Is the input lower dimensional (e.g., on a plane in 3-d)? Qhull may\n\
+produce a wide facet. Options 'QbB' (scale to unit box) or 'Qbb' (scale\n\
+last coordinate) may remove this warning. Use 'Pp' to skip this warning.\n\
+See 'Limitations' in qh-impre.htm.\n",
+ -minangle); /* convert from angle between normals to angle between facets */
+} /* printhelp_narrowhull */
+
+/*-<a href="qh-io_r.htm#TOC"
+ >-------------------------------</a><a name="printhelp_singular">-</a>
+
+ qh_printhelp_singular(qh, fp )
+ prints descriptive message for singular input
+*/
+void qh_printhelp_singular(qhT *qh, FILE *fp) {
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+ realT min, max, *coord, dist;
+ int i,k;
+
+ qh_fprintf(qh, fp, 9376, "\n\
+The input to qhull appears to be less than %d dimensional, or a\n\
+computation has overflowed.\n\n\
+Qhull could not construct a clearly convex simplex from points:\n",
+ qh->hull_dim);
+ qh_printvertexlist(qh, fp, "", qh->facet_list, NULL, qh_ALL);
+ if (!qh_QUICKhelp)
+ qh_fprintf(qh, fp, 9377, "\n\
+The center point is coplanar with a facet, or a vertex is coplanar\n\
+with a neighboring facet. The maximum round off error for\n\
+computing distances is %2.2g. The center point, facets and distances\n\
+to the center point are as follows:\n\n", qh->DISTround);
+ qh_printpointid(qh, fp, "center point", qh->hull_dim, qh->interior_point, qh_IDunknown);
+ qh_fprintf(qh, fp, 9378, "\n");
+ FORALLfacets {
+ qh_fprintf(qh, fp, 9379, "facet");
+ FOREACHvertex_(facet->vertices)
+ qh_fprintf(qh, fp, 9380, " p%d", qh_pointid(qh, vertex->point));
+ zinc_(Zdistio);
+ qh_distplane(qh, qh->interior_point, facet, &dist);
+ qh_fprintf(qh, fp, 9381, " distance= %4.2g\n", dist);
+ }
+ if (!qh_QUICKhelp) {
+ if (qh->HALFspace)
+ qh_fprintf(qh, fp, 9382, "\n\
+These points are the dual of the given halfspaces. They indicate that\n\
+the intersection is degenerate.\n");
+ qh_fprintf(qh, fp, 9383,"\n\
+These points either have a maximum or minimum x-coordinate, or\n\
+they maximize the determinant for k coordinates. Trial points\n\
+are first selected from points that maximize a coordinate.\n");
+ if (qh->hull_dim >= qh_INITIALmax)
+ qh_fprintf(qh, fp, 9384, "\n\
+Because of the high dimension, the min x-coordinate and max-coordinate\n\
+points are used if the determinant is non-zero. Option 'Qs' will\n\
+do a better, though much slower, job. Instead of 'Qs', you can change\n\
+the points by randomly rotating the input with 'QR0'.\n");
+ }
+ qh_fprintf(qh, fp, 9385, "\nThe min and max coordinates for each dimension are:\n");
+ for (k=0; k < qh->hull_dim; k++) {
+ min= REALmax;
+ max= -REALmin;
+ for (i=qh->num_points, coord= qh->first_point+k; i--; coord += qh->hull_dim) {
+ maximize_(max, *coord);
+ minimize_(min, *coord);
+ }
+ qh_fprintf(qh, fp, 9386, " %d: %8.4g %8.4g difference= %4.4g\n", k, min, max, max-min);
+ }
+ if (!qh_QUICKhelp) {
+ qh_fprintf(qh, fp, 9387, "\n\
+If the input should be full dimensional, you have several options that\n\
+may determine an initial simplex:\n\
+ - use 'QJ' to joggle the input and make it full dimensional\n\
+ - use 'QbB' to scale the points to the unit cube\n\
+ - use 'QR0' to randomly rotate the input for different maximum points\n\
+ - use 'Qs' to search all points for the initial simplex\n\
+ - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
+ - trace execution with 'T3' to see the determinant for each point.\n",
+ qh->DISTround);
+#if REALfloat
+ qh_fprintf(qh, fp, 9388, "\
+ - recompile qhull for realT precision(#define REALfloat 0 in libqhull_r.h).\n");
+#endif
+ qh_fprintf(qh, fp, 9389, "\n\
+If the input is lower dimensional:\n\
+ - use 'QJ' to joggle the input and make it full dimensional\n\
+ - use 'Qbk:0Bk:0' to delete coordinate k from the input. You should\n\
+ pick the coordinate with the least range. The hull will have the\n\
+ correct topology.\n\
+ - determine the flat containing the points, rotate the points\n\
+ into a coordinate plane, and delete the other coordinates.\n\
+ - add one or more points to make the input full dimensional.\n\
+");
+ }
+} /* printhelp_singular */
+
+/*-<a href="qh-globa_r.htm#TOC"
+ >-------------------------------</a><a name="user_memsizes">-</a>
+
+ qh_user_memsizes(qh)
+ allocate up to 10 additional, quick allocation sizes
+
+ notes:
+ increase maximum number of allocations in qh_initqhull_mem()
+*/
+void qh_user_memsizes(qhT *qh) {
+
+ QHULL_UNUSED(qh)
+ /* qh_memsize(qh, size); */
+} /* user_memsizes */
+
+
diff --git a/xs/src/qhull/src/libqhull_r/user_r.h b/xs/src/qhull/src/libqhull_r/user_r.h
new file mode 100644
index 000000000..7cca65a80
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/user_r.h
@@ -0,0 +1,882 @@
+/*<html><pre> -<a href="qh-user_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ user.h
+ user redefinable constants
+
+ for each source file, user_r.h is included first
+
+ see qh-user_r.htm. see COPYING for copyright information.
+
+ See user_r.c for sample code.
+
+ before reading any code, review libqhull_r.h for data structure definitions
+
+Sections:
+ ============= qhull library constants ======================
+ ============= data types and configuration macros ==========
+ ============= performance related constants ================
+ ============= memory constants =============================
+ ============= joggle constants =============================
+ ============= conditional compilation ======================
+ ============= -merge constants- ============================
+
+Code flags --
+ NOerrors -- the code does not call qh_errexit()
+ WARN64 -- the code may be incompatible with 64-bit pointers
+
+*/
+
+#include <time.h>
+
+#ifndef qhDEFuser
+#define qhDEFuser 1
+
+/* Derived from Qt's corelib/global/qglobal.h */
+#if !defined(SAG_COM) && !defined(__CYGWIN__) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
+# define QHULL_OS_WIN
+#elif defined(__MWERKS__) && defined(__INTEL__) /* Metrowerks discontinued before the release of Intel Macs */
+# define QHULL_OS_WIN
+#endif
+
+/*============================================================*/
+/*============= qhull library constants ======================*/
+/*============================================================*/
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="filenamelen">-</a>
+
+ FILENAMElen -- max length for TI and TO filenames
+
+*/
+
+#define qh_FILENAMElen 500
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="msgcode">-</a>
+
+ msgcode -- Unique message codes for qh_fprintf
+
+ If add new messages, assign these values and increment in user.h and user_r.h
+ See QhullError.h for 10000 errors.
+
+ def counters = [27, 1048, 2059, 3026, 4068, 5003,
+ 6273, 7081, 8147, 9411, 10000, 11029]
+
+ See: qh_ERR* [libqhull_r.h]
+*/
+
+#define MSG_TRACE0 0
+#define MSG_TRACE1 1000
+#define MSG_TRACE2 2000
+#define MSG_TRACE3 3000
+#define MSG_TRACE4 4000
+#define MSG_TRACE5 5000
+#define MSG_ERROR 6000 /* errors written to qh.ferr */
+#define MSG_WARNING 7000
+#define MSG_STDERR 8000 /* log messages Written to qh.ferr */
+#define MSG_OUTPUT 9000
+#define MSG_QHULL_ERROR 10000 /* errors thrown by QhullError.cpp (QHULLlastError is in QhullError.h) */
+#define MSG_FIXUP 11000 /* FIXUP QH11... */
+#define MSG_MAXLEN 3000 /* qh_printhelp_degenerate() in user.c */
+
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="qh_OPTIONline">-</a>
+
+ qh_OPTIONline -- max length of an option line 'FO'
+*/
+#define qh_OPTIONline 80
+
+/*============================================================*/
+/*============= data types and configuration macros ==========*/
+/*============================================================*/
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="realT">-</a>
+
+ realT
+ set the size of floating point numbers
+
+ qh_REALdigits
+ maximimum number of significant digits
+
+ qh_REAL_1, qh_REAL_2n, qh_REAL_3n
+ format strings for printf
+
+ qh_REALmax, qh_REALmin
+ maximum and minimum (near zero) values
+
+ qh_REALepsilon
+ machine roundoff. Maximum roundoff error for addition and multiplication.
+
+ notes:
+ Select whether to store floating point numbers in single precision (float)
+ or double precision (double).
+
+ Use 'float' to save about 8% in time and 25% in space. This is particularly
+ helpful if high-d where convex hulls are space limited. Using 'float' also
+ reduces the printed size of Qhull's output since numbers have 8 digits of
+ precision.
+
+ Use 'double' when greater arithmetic precision is needed. This is needed
+ for Delaunay triangulations and Voronoi diagrams when you are not merging
+ facets.
+
+ If 'double' gives insufficient precision, your data probably includes
+ degeneracies. If so you should use facet merging (done by default)
+ or exact arithmetic (see imprecision section of manual, qh-impre.htm).
+ You may also use option 'Po' to force output despite precision errors.
+
+ You may use 'long double', but many format statements need to be changed
+ and you may need a 'long double' square root routine. S. Grundmann
+ (sg@eeiwzb.et.tu-dresden.de) has done this. He reports that the code runs
+ much slower with little gain in precision.
+
+ WARNING: on some machines, int f(){realT a= REALmax;return (a == REALmax);}
+ returns False. Use (a > REALmax/2) instead of (a == REALmax).
+
+ REALfloat = 1 all numbers are 'float' type
+ = 0 all numbers are 'double' type
+*/
+#define REALfloat 1
+
+#if (REALfloat == 1)
+#define realT float
+#define REALmax FLT_MAX
+#define REALmin FLT_MIN
+#define REALepsilon FLT_EPSILON
+#define qh_REALdigits 8 /* maximum number of significant digits */
+#define qh_REAL_1 "%6.8g "
+#define qh_REAL_2n "%6.8g %6.8g\n"
+#define qh_REAL_3n "%6.8g %6.8g %6.8g\n"
+
+#elif (REALfloat == 0)
+#define realT double
+#define REALmax DBL_MAX
+#define REALmin DBL_MIN
+#define REALepsilon DBL_EPSILON
+#define qh_REALdigits 16 /* maximum number of significant digits */
+#define qh_REAL_1 "%6.16g "
+#define qh_REAL_2n "%6.16g %6.16g\n"
+#define qh_REAL_3n "%6.16g %6.16g %6.16g\n"
+
+#else
+#error unknown float option
+#endif
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="countT">-</a>
+
+ countT
+ The type for counts and identifiers (e.g., the number of points, vertex identifiers)
+ Currently used by C++ code-only. Decided against using it for setT because most sets are small.
+
+ Defined as 'int' for C-code compatibility and QH11026
+
+ FIXUP QH11026 countT may be defined as a unsigned value, but several code issues need to be solved first. See countT in Changes.txt
+*/
+
+#ifndef DEFcountT
+#define DEFcountT 1
+typedef int countT;
+#endif
+#define COUNTmax 0x7fffffff
+
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="CPUclock">-</a>
+
+ qh_CPUclock
+ define the clock() function for reporting the total time spent by Qhull
+ returns CPU ticks as a 'long int'
+ qh_CPUclock is only used for reporting the total time spent by Qhull
+
+ qh_SECticks
+ the number of clock ticks per second
+
+ notes:
+ looks for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or assumes microseconds
+ to define a custom clock, set qh_CLOCKtype to 0
+
+ if your system does not use clock() to return CPU ticks, replace
+ qh_CPUclock with the corresponding function. It is converted
+ to 'unsigned long' to prevent wrap-around during long runs. By default,
+ <time.h> defines clock_t as 'long'
+
+ Set qh_CLOCKtype to
+
+ 1 for CLOCKS_PER_SEC, CLOCKS_PER_SECOND, or microsecond
+ Note: may fail if more than 1 hour elapsed time
+
+ 2 use qh_clock() with POSIX times() (see global_r.c)
+*/
+#define qh_CLOCKtype 1 /* change to the desired number */
+
+#if (qh_CLOCKtype == 1)
+
+#if defined(CLOCKS_PER_SECOND)
+#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
+#define qh_SECticks CLOCKS_PER_SECOND
+
+#elif defined(CLOCKS_PER_SEC)
+#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
+#define qh_SECticks CLOCKS_PER_SEC
+
+#elif defined(CLK_TCK)
+#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
+#define qh_SECticks CLK_TCK
+
+#else
+#define qh_CPUclock ((unsigned long)clock()) /* return CPU clock */
+#define qh_SECticks 1E6
+#endif
+
+#elif (qh_CLOCKtype == 2)
+#define qh_CPUclock qh_clock() /* return CPU clock */
+#define qh_SECticks 100
+
+#else /* qh_CLOCKtype == ? */
+#error unknown clock option
+#endif
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="RANDOM">-</a>
+
+ qh_RANDOMtype, qh_RANDOMmax, qh_RANDOMseed
+ define random number generator
+
+ qh_RANDOMint generates a random integer between 0 and qh_RANDOMmax.
+ qh_RANDOMseed sets the random number seed for qh_RANDOMint
+
+ Set qh_RANDOMtype (default 5) to:
+ 1 for random() with 31 bits (UCB)
+ 2 for rand() with RAND_MAX or 15 bits (system 5)
+ 3 for rand() with 31 bits (Sun)
+ 4 for lrand48() with 31 bits (Solaris)
+ 5 for qh_rand(qh) with 31 bits (included with Qhull, requires 'qh')
+
+ notes:
+ Random numbers are used by rbox to generate point sets. Random
+ numbers are used by Qhull to rotate the input ('QRn' option),
+ simulate a randomized algorithm ('Qr' option), and to simulate
+ roundoff errors ('Rn' option).
+
+ Random number generators differ between systems. Most systems provide
+ rand() but the period varies. The period of rand() is not critical
+ since qhull does not normally use random numbers.
+
+ The default generator is Park & Miller's minimal standard random
+ number generator [CACM 31:1195 '88]. It is included with Qhull.
+
+ If qh_RANDOMmax is wrong, qhull will report a warning and Geomview
+ output will likely be invisible.
+*/
+#define qh_RANDOMtype 5 /* *** change to the desired number *** */
+
+#if (qh_RANDOMtype == 1)
+#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, random()/MAX */
+#define qh_RANDOMint random()
+#define qh_RANDOMseed_(qh, seed) srandom(seed);
+
+#elif (qh_RANDOMtype == 2)
+#ifdef RAND_MAX
+#define qh_RANDOMmax ((realT)RAND_MAX)
+#else
+#define qh_RANDOMmax ((realT)32767) /* 15 bits (System 5) */
+#endif
+#define qh_RANDOMint rand()
+#define qh_RANDOMseed_(qh, seed) srand((unsigned)seed);
+
+#elif (qh_RANDOMtype == 3)
+#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, Sun */
+#define qh_RANDOMint rand()
+#define qh_RANDOMseed_(qh, seed) srand((unsigned)seed);
+
+#elif (qh_RANDOMtype == 4)
+#define qh_RANDOMmax ((realT)0x7fffffffUL) /* 31 bits, lrand38()/MAX */
+#define qh_RANDOMint lrand48()
+#define qh_RANDOMseed_(qh, seed) srand48(seed);
+
+#elif (qh_RANDOMtype == 5) /* 'qh' is an implicit parameter */
+#define qh_RANDOMmax ((realT)2147483646UL) /* 31 bits, qh_rand/MAX */
+#define qh_RANDOMint qh_rand(qh)
+#define qh_RANDOMseed_(qh, seed) qh_srand(qh, seed);
+/* unlike rand(), never returns 0 */
+
+#else
+#error: unknown random option
+#endif
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="ORIENTclock">-</a>
+
+ qh_ORIENTclock
+ 0 for inward pointing normals by Geomview convention
+*/
+#define qh_ORIENTclock 0
+
+
+/*============================================================*/
+/*============= joggle constants =============================*/
+/*============================================================*/
+
+/*-<a href="qh-user_r.htm#TOC"
+>--------------------------------</a><a name="JOGGLEdefault">-</a>
+
+qh_JOGGLEdefault
+default qh.JOGGLEmax is qh.DISTround * qh_JOGGLEdefault
+
+notes:
+rbox s r 100 | qhull QJ1e-15 QR0 generates 90% faults at distround 7e-16
+rbox s r 100 | qhull QJ1e-14 QR0 generates 70% faults
+rbox s r 100 | qhull QJ1e-13 QR0 generates 35% faults
+rbox s r 100 | qhull QJ1e-12 QR0 generates 8% faults
+rbox s r 100 | qhull QJ1e-11 QR0 generates 1% faults
+rbox s r 100 | qhull QJ1e-10 QR0 generates 0% faults
+rbox 1000 W0 | qhull QJ1e-12 QR0 generates 86% faults
+rbox 1000 W0 | qhull QJ1e-11 QR0 generates 20% faults
+rbox 1000 W0 | qhull QJ1e-10 QR0 generates 2% faults
+the later have about 20 points per facet, each of which may interfere
+
+pick a value large enough to avoid retries on most inputs
+*/
+#define qh_JOGGLEdefault 30000.0
+
+/*-<a href="qh-user_r.htm#TOC"
+>--------------------------------</a><a name="JOGGLEincrease">-</a>
+
+qh_JOGGLEincrease
+factor to increase qh.JOGGLEmax on qh_JOGGLEretry or qh_JOGGLEagain
+*/
+#define qh_JOGGLEincrease 10.0
+
+/*-<a href="qh-user_r.htm#TOC"
+>--------------------------------</a><a name="JOGGLEretry">-</a>
+
+qh_JOGGLEretry
+if ZZretry = qh_JOGGLEretry, increase qh.JOGGLEmax
+
+notes:
+try twice at the original value in case of bad luck the first time
+*/
+#define qh_JOGGLEretry 2
+
+/*-<a href="qh-user_r.htm#TOC"
+>--------------------------------</a><a name="JOGGLEagain">-</a>
+
+qh_JOGGLEagain
+every following qh_JOGGLEagain, increase qh.JOGGLEmax
+
+notes:
+1 is OK since it's already failed qh_JOGGLEretry times
+*/
+#define qh_JOGGLEagain 1
+
+/*-<a href="qh-user_r.htm#TOC"
+>--------------------------------</a><a name="JOGGLEmaxincrease">-</a>
+
+qh_JOGGLEmaxincrease
+maximum qh.JOGGLEmax due to qh_JOGGLEincrease
+relative to qh.MAXwidth
+
+notes:
+qh.joggleinput will retry at this value until qh_JOGGLEmaxretry
+*/
+#define qh_JOGGLEmaxincrease 1e-2
+
+/*-<a href="qh-user_r.htm#TOC"
+>--------------------------------</a><a name="JOGGLEmaxretry">-</a>
+
+qh_JOGGLEmaxretry
+stop after qh_JOGGLEmaxretry attempts
+*/
+#define qh_JOGGLEmaxretry 100
+
+/*============================================================*/
+/*============= performance related constants ================*/
+/*============================================================*/
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="HASHfactor">-</a>
+
+ qh_HASHfactor
+ total hash slots / used hash slots. Must be at least 1.1.
+
+ notes:
+ =2 for at worst 50% occupancy for qh.hash_table and normally 25% occupancy
+*/
+#define qh_HASHfactor 2
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="VERIFYdirect">-</a>
+
+ qh_VERIFYdirect
+ with 'Tv' verify all points against all facets if op count is smaller
+
+ notes:
+ if greater, calls qh_check_bestdist() instead
+*/
+#define qh_VERIFYdirect 1000000
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="INITIALsearch">-</a>
+
+ qh_INITIALsearch
+ if qh_INITIALmax, search points up to this dimension
+*/
+#define qh_INITIALsearch 6
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="INITIALmax">-</a>
+
+ qh_INITIALmax
+ if dim >= qh_INITIALmax, use min/max coordinate points for initial simplex
+
+ notes:
+ from points with non-zero determinants
+ use option 'Qs' to override (much slower)
+*/
+#define qh_INITIALmax 8
+
+/*============================================================*/
+/*============= memory constants =============================*/
+/*============================================================*/
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="MEMalign">-</a>
+
+ qh_MEMalign
+ memory alignment for qh_meminitbuffers() in global_r.c
+
+ notes:
+ to avoid bus errors, memory allocation must consider alignment requirements.
+ malloc() automatically takes care of alignment. Since mem_r.c manages
+ its own memory, we need to explicitly specify alignment in
+ qh_meminitbuffers().
+
+ A safe choice is sizeof(double). sizeof(float) may be used if doubles
+ do not occur in data structures and pointers are the same size. Be careful
+ of machines (e.g., DEC Alpha) with large pointers.
+
+ If using gcc, best alignment is [fmax_() is defined in geom_r.h]
+ #define qh_MEMalign fmax_(__alignof__(realT),__alignof__(void *))
+*/
+#define qh_MEMalign ((int)(fmax_(sizeof(realT), sizeof(void *))))
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="MEMbufsize">-</a>
+
+ qh_MEMbufsize
+ size of additional memory buffers
+
+ notes:
+ used for qh_meminitbuffers() in global_r.c
+*/
+#define qh_MEMbufsize 0x10000 /* allocate 64K memory buffers */
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="MEMinitbuf">-</a>
+
+ qh_MEMinitbuf
+ size of initial memory buffer
+
+ notes:
+ use for qh_meminitbuffers() in global_r.c
+*/
+#define qh_MEMinitbuf 0x20000 /* initially allocate 128K buffer */
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="INFINITE">-</a>
+
+ qh_INFINITE
+ on output, indicates Voronoi center at infinity
+*/
+#define qh_INFINITE -10.101
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="DEFAULTbox">-</a>
+
+ qh_DEFAULTbox
+ default box size (Geomview expects 0.5)
+
+ qh_DEFAULTbox
+ default box size for integer coorindate (rbox only)
+*/
+#define qh_DEFAULTbox 0.5
+#define qh_DEFAULTzbox 1e6
+
+/*============================================================*/
+/*============= conditional compilation ======================*/
+/*============================================================*/
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="compiler">-</a>
+
+ __cplusplus
+ defined by C++ compilers
+
+ __MSC_VER
+ defined by Microsoft Visual C++
+
+ __MWERKS__ && __INTEL__
+ defined by Metrowerks when compiling for Windows (not Intel-based Macintosh)
+
+ __MWERKS__ && __POWERPC__
+ defined by Metrowerks when compiling for PowerPC-based Macintosh
+
+ __STDC__
+ defined for strict ANSI C
+*/
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="COMPUTEfurthest">-</a>
+
+ qh_COMPUTEfurthest
+ compute furthest distance to an outside point instead of storing it with the facet
+ =1 to compute furthest
+
+ notes:
+ computing furthest saves memory but costs time
+ about 40% more distance tests for partitioning
+ removes facet->furthestdist
+*/
+#define qh_COMPUTEfurthest 0
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="KEEPstatistics">-</a>
+
+ qh_KEEPstatistics
+ =0 removes most of statistic gathering and reporting
+
+ notes:
+ if 0, code size is reduced by about 4%.
+*/
+#define qh_KEEPstatistics 1
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="MAXoutside">-</a>
+
+ qh_MAXoutside
+ record outer plane for each facet
+ =1 to record facet->maxoutside
+
+ notes:
+ this takes a realT per facet and slightly slows down qhull
+ it produces better outer planes for geomview output
+*/
+#define qh_MAXoutside 1
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="NOmerge">-</a>
+
+ qh_NOmerge
+ disables facet merging if defined
+
+ notes:
+ This saves about 10% space.
+
+ Unless 'Q0'
+ qh_NOmerge sets 'QJ' to avoid precision errors
+
+ #define qh_NOmerge
+
+ see:
+ <a href="mem_r.h#NOmem">qh_NOmem</a> in mem_r.c
+
+ see user_r.c/user_eg.c for removing io_r.o
+*/
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="NOtrace">-</a>
+
+ qh_NOtrace
+ no tracing if defined
+
+ notes:
+ This saves about 5% space.
+
+ #define qh_NOtrace
+*/
+
+#if 0 /* sample code */
+ exitcode= qh_new_qhull(qhT *qh, dim, numpoints, points, ismalloc,
+ flags, outfile, errfile);
+ qh_freeqhull(qhT *qh, !qh_ALL); /* frees long memory used by second call */
+ qh_memfreeshort(qhT *qh, &curlong, &totlong); /* frees short memory and memory allocator */
+#endif
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="QUICKhelp">-</a>
+
+ qh_QUICKhelp
+ =1 to use abbreviated help messages, e.g., for degenerate inputs
+*/
+#define qh_QUICKhelp 0
+
+/*============================================================*/
+/*============= -merge constants- ============================*/
+/*============================================================*/
+/*
+ These constants effect facet merging. You probably will not need
+ to modify them. They effect the performance of facet merging.
+*/
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="DIMmergeVertex">-</a>
+
+ qh_DIMmergeVertex
+ max dimension for vertex merging (it is not effective in high-d)
+*/
+#define qh_DIMmergeVertex 6
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="DIMreduceBuild">-</a>
+
+ qh_DIMreduceBuild
+ max dimension for vertex reduction during build (slow in high-d)
+*/
+#define qh_DIMreduceBuild 5
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="BESTcentrum">-</a>
+
+ qh_BESTcentrum
+ if > 2*dim+n vertices, qh_findbestneighbor() tests centrums (faster)
+ else, qh_findbestneighbor() tests all vertices (much better merges)
+
+ qh_BESTcentrum2
+ if qh_BESTcentrum2 * DIM3 + BESTcentrum < #vertices tests centrums
+*/
+#define qh_BESTcentrum 20
+#define qh_BESTcentrum2 2
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="BESTnonconvex">-</a>
+
+ qh_BESTnonconvex
+ if > dim+n neighbors, qh_findbestneighbor() tests nonconvex ridges.
+
+ notes:
+ It is needed because qh_findbestneighbor is slow for large facets
+*/
+#define qh_BESTnonconvex 15
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="MAXnewmerges">-</a>
+
+ qh_MAXnewmerges
+ if >n newmerges, qh_merge_nonconvex() calls qh_reducevertices_centrums.
+
+ notes:
+ It is needed because postmerge can merge many facets at once
+*/
+#define qh_MAXnewmerges 2
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="MAXnewcentrum">-</a>
+
+ qh_MAXnewcentrum
+ if <= dim+n vertices (n approximates the number of merges),
+ reset the centrum in qh_updatetested() and qh_mergecycle_facets()
+
+ notes:
+ needed to reduce cost and because centrums may move too much if
+ many vertices in high-d
+*/
+#define qh_MAXnewcentrum 5
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="COPLANARratio">-</a>
+
+ qh_COPLANARratio
+ for 3-d+ merging, qh.MINvisible is n*premerge_centrum
+
+ notes:
+ for non-merging, it's DISTround
+*/
+#define qh_COPLANARratio 3
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="DISToutside">-</a>
+
+ qh_DISToutside
+ When is a point clearly outside of a facet?
+ Stops search in qh_findbestnew or qh_partitionall
+ qh_findbest uses qh.MINoutside since since it is only called if no merges.
+
+ notes:
+ 'Qf' always searches for best facet
+ if !qh.MERGING, same as qh.MINoutside.
+ if qh_USEfindbestnew, increase value since neighboring facets may be ill-behaved
+ [Note: Zdelvertextot occurs normally with interior points]
+ RBOX 1000 s Z1 G1e-13 t1001188774 | QHULL Tv
+ When there is a sharp edge, need to move points to a
+ clearly good facet; otherwise may be lost in another partitioning.
+ if too big then O(n^2) behavior for partitioning in cone
+ if very small then important points not processed
+ Needed in qh_partitionall for
+ RBOX 1000 s Z1 G1e-13 t1001032651 | QHULL Tv
+ Needed in qh_findbestnew for many instances of
+ RBOX 1000 s Z1 G1e-13 t | QHULL Tv
+
+ See:
+ qh_DISToutside -- when is a point clearly outside of a facet
+ qh_SEARCHdist -- when is facet coplanar with the best facet?
+ qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
+*/
+#define qh_DISToutside ((qh_USEfindbestnew ? 2 : 1) * \
+ fmax_((qh->MERGING ? 2 : 1)*qh->MINoutside, qh->max_outside))
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="RATIOnearinside">-</a>
+
+ qh_RATIOnearinside
+ ratio of qh.NEARinside to qh.ONEmerge for retaining inside points for
+ qh_check_maxout().
+
+ notes:
+ This is overkill since do not know the correct value.
+ It effects whether 'Qc' reports all coplanar points
+ Not used for 'd' since non-extreme points are coplanar
+*/
+#define qh_RATIOnearinside 5
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="SEARCHdist">-</a>
+
+ qh_SEARCHdist
+ When is a facet coplanar with the best facet?
+ qh_findbesthorizon: all coplanar facets of the best facet need to be searched.
+
+ See:
+ qh_DISToutside -- when is a point clearly outside of a facet
+ qh_SEARCHdist -- when is facet coplanar with the best facet?
+ qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
+*/
+#define qh_SEARCHdist ((qh_USEfindbestnew ? 2 : 1) * \
+ (qh->max_outside + 2 * qh->DISTround + fmax_( qh->MINvisible, qh->MAXcoplanar)));
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="USEfindbestnew">-</a>
+
+ qh_USEfindbestnew
+ Always use qh_findbestnew for qh_partitionpoint, otherwise use
+ qh_findbestnew if merged new facet or sharpnewfacets.
+
+ See:
+ qh_DISToutside -- when is a point clearly outside of a facet
+ qh_SEARCHdist -- when is facet coplanar with the best facet?
+ qh_USEfindbestnew -- when to use qh_findbestnew for qh_partitionpoint()
+*/
+#define qh_USEfindbestnew (zzval_(Ztotmerge) > 50)
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="WIDEcoplanar">-</a>
+
+ qh_WIDEcoplanar
+ n*MAXcoplanar or n*MINvisible for a WIDEfacet
+
+ if vertex is further than qh.WIDEfacet from the hyperplane
+ then its ridges are not counted in computing the area, and
+ the facet's centrum is frozen.
+
+ notes:
+ qh.WIDEfacet= max(qh.MAXoutside,qh_WIDEcoplanar*qh.MAXcoplanar,
+ qh_WIDEcoplanar * qh.MINvisible);
+*/
+#define qh_WIDEcoplanar 6
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="WIDEduplicate">-</a>
+
+ qh_WIDEduplicate
+ Merge ratio for errexit from qh_forcedmerges due to duplicate ridge
+ Override with option Q12 no-wide-duplicate
+
+ Notes:
+ Merging a duplicate ridge can lead to very wide facets.
+ A future release of qhull will avoid duplicate ridges by removing duplicate sub-ridges from the horizon
+*/
+#define qh_WIDEduplicate 100
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="MAXnarrow">-</a>
+
+ qh_MAXnarrow
+ max. cosine in initial hull that sets qh.NARROWhull
+
+ notes:
+ If qh.NARROWhull, the initial partition does not make
+ coplanar points. If narrow, a coplanar point can be
+ coplanar to two facets of opposite orientations and
+ distant from the exact convex hull.
+
+ Conservative estimate. Don't actually see problems until it is -1.0
+*/
+#define qh_MAXnarrow -0.99999999
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="WARNnarrow">-</a>
+
+ qh_WARNnarrow
+ max. cosine in initial hull to warn about qh.NARROWhull
+
+ notes:
+ this is a conservative estimate.
+ Don't actually see problems until it is -1.0. See qh-impre.htm
+*/
+#define qh_WARNnarrow -0.999999999999999
+
+/*-<a href="qh-user_r.htm#TOC"
+ >--------------------------------</a><a name="ZEROdelaunay">-</a>
+
+ qh_ZEROdelaunay
+ a zero Delaunay facet occurs for input sites coplanar with their convex hull
+ the last normal coefficient of a zero Delaunay facet is within
+ qh_ZEROdelaunay * qh.ANGLEround of 0
+
+ notes:
+ qh_ZEROdelaunay does not allow for joggled input ('QJ').
+
+ You can avoid zero Delaunay facets by surrounding the input with a box.
+
+ Use option 'PDk:-n' to explicitly define zero Delaunay facets
+ k= dimension of input sites (e.g., 3 for 3-d Delaunay triangulation)
+ n= the cutoff for zero Delaunay facets (e.g., 'PD3:-1e-12')
+*/
+#define qh_ZEROdelaunay 2
+
+/*============================================================*/
+/*============= Microsoft DevStudio ==========================*/
+/*============================================================*/
+
+/*
+ Finding Memory Leaks Using the CRT Library
+ https://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.100).aspx
+
+ Reports enabled in qh_lib_check for Debug window and stderr
+
+ From 2005=>msvcr80d, 2010=>msvcr100d, 2012=>msvcr110d
+
+ Watch: {,,msvcr80d.dll}_crtBreakAlloc Value from {n} in the leak report
+ _CrtSetBreakAlloc(689); // qh_lib_check() [global_r.c]
+
+ Examples
+ http://free-cad.sourceforge.net/SrcDocu/d2/d7f/MemDebug_8cpp_source.html
+ https://github.com/illlust/Game/blob/master/library/MemoryLeak.cpp
+*/
+#if 0 /* off (0) by default for QHULL_CRTDBG */
+#define QHULL_CRTDBG
+#endif
+
+#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG)
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+#endif
+
+#endif /* qh_DEFuser */
+
+
+
diff --git a/xs/src/qhull/src/libqhull_r/usermem_r.c b/xs/src/qhull/src/libqhull_r/usermem_r.c
new file mode 100644
index 000000000..3297b0318
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/usermem_r.c
@@ -0,0 +1,94 @@
+/*<html><pre> -<a href="qh-user_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ usermem_r.c
+ qh_exit(), qh_free(), and qh_malloc()
+
+ See README.txt.
+
+ If you redefine one of these functions you must redefine all of them.
+ If you recompile and load this file, then usermem.o will not be loaded
+ from qhull.a or qhull.lib
+
+ See libqhull_r.h for data structures, macros, and user-callable functions.
+ See user_r.c for qhull-related, redefinable functions
+ see user_r.h for user-definable constants
+ See userprintf_r.c for qh_fprintf and userprintf_rbox_r.c for qh_fprintf_rbox
+
+ Please report any errors that you fix to qhull@qhull.org
+*/
+
+#include "libqhull_r.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="qh_exit">-</a>
+
+ qh_exit( exitcode )
+ exit program
+
+ notes:
+ qh_exit() is called when qh_errexit() and longjmp() are not available.
+
+ This is the only use of exit() in Qhull
+ To replace qh_exit with 'throw', see libqhullcpp/usermem_r-cpp.cpp
+*/
+void qh_exit(int exitcode) {
+ exit(exitcode);
+} /* exit */
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="qh_fprintf_stderr">-</a>
+
+ qh_fprintf_stderr( msgcode, format, list of args )
+ fprintf to stderr with msgcode (non-zero)
+
+ notes:
+ qh_fprintf_stderr() is called when qh->ferr is not defined, usually due to an initialization error
+
+ It is typically followed by qh_errexit().
+
+ Redefine this function to avoid using stderr
+
+ Use qh_fprintf [userprintf_r.c] for normal printing
+*/
+void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
+ va_list args;
+
+ va_start(args, fmt);
+ if(msgcode)
+ fprintf(stderr, "QH%.4d ", msgcode);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+} /* fprintf_stderr */
+
+/*-<a href="qh-user_r.htm#TOC"
+>-------------------------------</a><a name="qh_free">-</a>
+
+ qh_free(qhT *qh, mem )
+ free memory
+
+ notes:
+ same as free()
+ No calls to qh_errexit()
+*/
+void qh_free(void *mem) {
+ free(mem);
+} /* free */
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="qh_malloc">-</a>
+
+ qh_malloc( mem )
+ allocate memory
+
+ notes:
+ same as malloc()
+*/
+void *qh_malloc(size_t size) {
+ return malloc(size);
+} /* malloc */
+
+
diff --git a/xs/src/qhull/src/libqhull_r/userprintf_r.c b/xs/src/qhull/src/libqhull_r/userprintf_r.c
new file mode 100644
index 000000000..6004491a1
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/userprintf_r.c
@@ -0,0 +1,65 @@
+/*<html><pre> -<a href="qh-user_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ userprintf_r.c
+ qh_fprintf()
+
+ see README.txt see COPYING.txt for copyright information.
+
+ If you recompile and load this file, then userprintf_r.o will not be loaded
+ from qhull.a or qhull.lib
+
+ See libqhull_r.h for data structures, macros, and user-callable functions.
+ See user_r.c for qhull-related, redefinable functions
+ see user_r.h for user-definable constants
+ See usermem_r.c for qh_exit(), qh_free(), and qh_malloc()
+ see Qhull.cpp and RboxPoints.cpp for examples.
+
+ Please report any errors that you fix to qhull@qhull.org
+*/
+
+#include "libqhull_r.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="qh_fprintf">-</a>
+
+ qh_fprintf(qh, fp, msgcode, format, list of args )
+ print arguments to *fp according to format
+ Use qh_fprintf_rbox() for rboxlib_r.c
+
+ notes:
+ same as fprintf()
+ fgets() is not trapped like fprintf()
+ exit qh_fprintf via qh_errexit()
+ may be called for errors in qh_initstatistics and qh_meminit
+*/
+
+void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
+ va_list args;
+
+ if (!fp) {
+ if(!qh){
+ qh_fprintf_stderr(6241, "userprintf_r.c: fp and qh not defined for qh_fprintf '%s'", fmt);
+ qh_exit(qhmem_ERRqhull); /* can not use qh_errexit() */
+ }
+ /* could use qh->qhmem.ferr, but probably better to be cautious */
+ qh_fprintf_stderr(6232, "Qhull internal error (userprintf_r.c): fp is 0. Wrong qh_fprintf called.\n");
+ qh_errexit(qh, 6232, NULL, NULL);
+ }
+ va_start(args, fmt);
+ if (qh && qh->ANNOTATEoutput) {
+ fprintf(fp, "[QH%.4d]", msgcode);
+ }else if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR ) {
+ fprintf(fp, "QH%.4d ", msgcode);
+ }
+ vfprintf(fp, fmt, args);
+ va_end(args);
+
+ /* Place debugging traps here. Use with option 'Tn' */
+
+} /* qh_fprintf */
+
diff --git a/xs/src/qhull/src/libqhull_r/userprintf_rbox_r.c b/xs/src/qhull/src/libqhull_r/userprintf_rbox_r.c
new file mode 100644
index 000000000..1e721a22a
--- /dev/null
+++ b/xs/src/qhull/src/libqhull_r/userprintf_rbox_r.c
@@ -0,0 +1,53 @@
+/*<html><pre> -<a href="qh-user_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ userprintf_rbox_r.c
+ qh_fprintf_rbox()
+
+ see README.txt see COPYING.txt for copyright information.
+
+ If you recompile and load this file, then userprintf_rbox_r.o will not be loaded
+ from qhull.a or qhull.lib
+
+ See libqhull_r.h for data structures, macros, and user-callable functions.
+ See user_r.c for qhull-related, redefinable functions
+ see user_r.h for user-definable constants
+ See usermem_r.c for qh_exit(), qh_free(), and qh_malloc()
+ see Qhull.cpp and RboxPoints.cpp for examples.
+
+ Please report any errors that you fix to qhull@qhull.org
+*/
+
+#include "libqhull_r.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="qh_fprintf_rbox">-</a>
+
+ qh_fprintf_rbox(qh, fp, msgcode, format, list of args )
+ print arguments to *fp according to format
+ Use qh_fprintf_rbox() for rboxlib_r.c
+
+ notes:
+ same as fprintf()
+ fgets() is not trapped like fprintf()
+ exit qh_fprintf_rbox via qh_errexit_rbox()
+*/
+
+void qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
+ va_list args;
+
+ if (!fp) {
+ qh_fprintf_stderr(6231, "Qhull internal error (userprintf_rbox_r.c): fp is 0. Wrong qh_fprintf_rbox called.\n");
+ qh_errexit_rbox(qh, 6231);
+ }
+ if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR)
+ fprintf(fp, "QH%.4d ", msgcode);
+ va_start(args, fmt);
+ vfprintf(fp, fmt, args);
+ va_end(args);
+} /* qh_fprintf_rbox */
+
diff --git a/xs/src/qhull/src/libqhullcpp/Coordinates.cpp b/xs/src/qhull/src/libqhullcpp/Coordinates.cpp
new file mode 100644
index 000000000..806b438ab
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/Coordinates.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/Coordinates.cpp#4 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#include "libqhullcpp/Coordinates.h"
+
+#include "libqhullcpp/functionObjects.h"
+#include "libqhullcpp/QhullError.h"
+
+#include <iostream>
+#include <iterator>
+#include <algorithm>
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#endif
+
+namespace orgQhull {
+
+#//! Coordinates -- vector of coordT (normally double)
+
+#//!\name Constructor
+
+#//!\name Element access
+
+// Inefficient without result-value-optimization or implicitly shared object
+Coordinates Coordinates::
+mid(countT idx, countT length) const
+{
+ countT newLength= length;
+ if(length<0 || idx+length > count()){
+ newLength= count()-idx;
+ }
+ Coordinates result;
+ if(newLength>0){
+ std::copy(begin()+idx, begin()+(idx+newLength), std::back_inserter(result));
+ }
+ return result;
+}//mid
+
+coordT Coordinates::
+value(countT idx, const coordT &defaultValue) const
+{
+ return ((idx < 0 || idx >= count()) ? defaultValue : (*this)[idx]);
+}//value
+
+#//!\name GetSet
+
+Coordinates Coordinates::
+operator+(const Coordinates &other) const
+{
+ Coordinates result(*this);
+ std::copy(other.begin(), other.end(), std::back_inserter(result));
+ return result;
+}//operator+
+
+Coordinates & Coordinates::
+operator+=(const Coordinates &other)
+{
+ if(&other==this){
+ Coordinates clone(other);
+ std::copy(clone.begin(), clone.end(), std::back_inserter(*this));
+ }else{
+ std::copy(other.begin(), other.end(), std::back_inserter(*this));
+ }
+ return *this;
+}//operator+=
+
+#//!\name Read-write
+
+void Coordinates::
+append(int pointDimension, coordT *c)
+{
+ if(c){
+ coordT *p= c;
+ for(int i= 0; i<pointDimension; ++i){
+ coordinate_array.push_back(*p++);
+ }
+ }
+}//append dim coordT
+
+coordT Coordinates::
+takeAt(countT idx)
+{
+ coordT c= at(idx);
+ erase(begin()+idx);
+ return c;
+}//takeAt
+
+coordT Coordinates::
+takeLast()
+{
+ coordT c= last();
+ removeLast();
+ return c;
+}//takeLast
+
+void Coordinates::
+swap(countT idx, countT other)
+{
+ coordT c= at(idx);
+ at(idx)= at(other);
+ at(other)= c;
+}//swap
+
+#//!\name Search
+
+bool Coordinates::
+contains(const coordT &t) const
+{
+ CoordinatesIterator i(*this);
+ return i.findNext(t);
+}//contains
+
+countT Coordinates::
+count(const coordT &t) const
+{
+ CoordinatesIterator i(*this);
+ countT result= 0;
+ while(i.findNext(t)){
+ ++result;
+ }
+ return result;
+}//count
+
+countT Coordinates::
+indexOf(const coordT &t, countT from) const
+{
+ if(from<0){
+ from += count();
+ if(from<0){
+ from= 0;
+ }
+ }
+ if(from<count()){
+ const_iterator i= begin()+from;
+ while(i!=constEnd()){
+ if(*i==t){
+ return (static_cast<countT>(i-begin())); // WARN64 coordinate index
+ }
+ ++i;
+ }
+ }
+ return -1;
+}//indexOf
+
+countT Coordinates::
+lastIndexOf(const coordT &t, countT from) const
+{
+ if(from<0){
+ from += count();
+ }else if(from>=count()){
+ from= count()-1;
+ }
+ if(from>=0){
+ const_iterator i= begin()+from+1;
+ while(i-- != constBegin()){
+ if(*i==t){
+ return (static_cast<countT>(i-begin())); // WARN64 coordinate index
+ }
+ }
+ }
+ return -1;
+}//lastIndexOf
+
+void Coordinates::
+removeAll(const coordT &t)
+{
+ MutableCoordinatesIterator i(*this);
+ while(i.findNext(t)){
+ i.remove();
+ }
+}//removeAll
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+using std::endl;
+using std::istream;
+using std::ostream;
+using std::string;
+using std::ws;
+using orgQhull::Coordinates;
+
+ostream &
+operator<<(ostream &os, const Coordinates &cs)
+{
+ Coordinates::const_iterator c= cs.begin();
+ for(countT i=cs.count(); i--; ){
+ os << *c++ << " ";
+ }
+ return os;
+}//operator<<
+
diff --git a/xs/src/qhull/src/libqhullcpp/Coordinates.h b/xs/src/qhull/src/libqhullcpp/Coordinates.h
new file mode 100644
index 000000000..df8bd1138
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/Coordinates.h
@@ -0,0 +1,303 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/Coordinates.h#6 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHCOORDINATES_H
+#define QHCOORDINATES_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullIterator.h"
+
+#include <cstddef> // ptrdiff_t, size_t
+#include <ostream>
+// Requires STL vector class. Can use with another vector class such as QList.
+#include <vector>
+
+namespace orgQhull {
+
+#//!\name Defined here
+ //! An std::vector of point coordinates independent of dimension
+ //! Used by PointCoordinates for RboxPoints and by Qhull for feasiblePoint
+ //! A QhullPoint refers to previously allocated coordinates
+ class Coordinates;
+ class MutableCoordinatesIterator;
+
+class Coordinates {
+
+private:
+#//!\name Fields
+ std::vector<coordT> coordinate_array;
+
+public:
+#//!\name Subtypes
+
+ class const_iterator;
+ class iterator;
+ typedef iterator Iterator;
+ typedef const_iterator ConstIterator;
+
+ typedef coordT value_type;
+ typedef const value_type *const_pointer;
+ typedef const value_type & const_reference;
+ typedef value_type * pointer;
+ typedef value_type & reference;
+ typedef ptrdiff_t difference_type;
+ typedef countT size_type;
+
+#//!\name Construct
+ Coordinates() {};
+ explicit Coordinates(const std::vector<coordT> &other) : coordinate_array(other) {}
+ Coordinates(const Coordinates &other) : coordinate_array(other.coordinate_array) {}
+ Coordinates & operator=(const Coordinates &other) { coordinate_array= other.coordinate_array; return *this; }
+ Coordinates & operator=(const std::vector<coordT> &other) { coordinate_array= other; return *this; }
+ ~Coordinates() {}
+
+#//!\name Conversion
+
+#ifndef QHULL_NO_STL
+ std::vector<coordT> toStdVector() const { return coordinate_array; }
+#endif //QHULL_NO_STL
+#ifdef QHULL_USES_QT
+ QList<coordT> toQList() const;
+#endif //QHULL_USES_QT
+
+#//!\name GetSet
+ countT count() const { return static_cast<countT>(size()); }
+ coordT * data() { return isEmpty() ? 0 : &at(0); }
+ const coordT * data() const { return const_cast<const pointT*>(isEmpty() ? 0 : &at(0)); }
+ bool isEmpty() const { return coordinate_array.empty(); }
+ bool operator==(const Coordinates &other) const { return coordinate_array==other.coordinate_array; }
+ bool operator!=(const Coordinates &other) const { return coordinate_array!=other.coordinate_array; }
+ size_t size() const { return coordinate_array.size(); }
+
+#//!\name Element access
+ coordT & at(countT idx) { return coordinate_array.at(idx); }
+ const coordT & at(countT idx) const { return coordinate_array.at(idx); }
+ coordT & back() { return coordinate_array.back(); }
+ const coordT & back() const { return coordinate_array.back(); }
+ coordT & first() { return front(); }
+ const coordT & first() const { return front(); }
+ coordT & front() { return coordinate_array.front(); }
+ const coordT & front() const { return coordinate_array.front(); }
+ coordT & last() { return back(); }
+ const coordT & last() const { return back(); }
+ Coordinates mid(countT idx, countT length= -1) const; //!<\todo countT -1 indicates
+ coordT & operator[](countT idx) { return coordinate_array.operator[](idx); }
+ const coordT & operator[](countT idx) const { return coordinate_array.operator[](idx); }
+ coordT value(countT idx, const coordT &defaultValue) const;
+
+#//!\name Iterator
+ iterator begin() { return iterator(coordinate_array.begin()); }
+ const_iterator begin() const { return const_iterator(coordinate_array.begin()); }
+ const_iterator constBegin() const { return begin(); }
+ const_iterator constEnd() const { return end(); }
+ iterator end() { return iterator(coordinate_array.end()); }
+ const_iterator end() const { return const_iterator(coordinate_array.end()); }
+
+#//!\name GetSet
+ Coordinates operator+(const Coordinates &other) const;
+
+#//!\name Modify
+ void append(int pointDimension, coordT *c);
+ void append(const coordT &c) { push_back(c); }
+ void clear() { coordinate_array.clear(); }
+ iterator erase(iterator idx) { return iterator(coordinate_array.erase(idx.base())); }
+ iterator erase(iterator beginIterator, iterator endIterator) { return iterator(coordinate_array.erase(beginIterator.base(), endIterator.base())); }
+ void insert(countT before, const coordT &c) { insert(begin()+before, c); }
+ iterator insert(iterator before, const coordT &c) { return iterator(coordinate_array.insert(before.base(), c)); }
+ void move(countT from, countT to) { insert(to, takeAt(from)); }
+ Coordinates & operator+=(const Coordinates &other);
+ Coordinates & operator+=(const coordT &c) { append(c); return *this; }
+ Coordinates & operator<<(const Coordinates &other) { return *this += other; }
+ Coordinates & operator<<(const coordT &c) { return *this += c; }
+ void pop_back() { coordinate_array.pop_back(); }
+ void pop_front() { removeFirst(); }
+ void prepend(const coordT &c) { insert(begin(), c); }
+ void push_back(const coordT &c) { coordinate_array.push_back(c); }
+ void push_front(const coordT &c) { insert(begin(), c); }
+ //removeAll below
+ void removeAt(countT idx) { erase(begin()+idx); }
+ void removeFirst() { erase(begin()); }
+ void removeLast() { erase(--end()); }
+ void replace(countT idx, const coordT &c) { (*this)[idx]= c; }
+ void reserve(countT i) { coordinate_array.reserve(i); }
+ void swap(countT idx, countT other);
+ coordT takeAt(countT idx);
+ coordT takeFirst() { return takeAt(0); }
+ coordT takeLast();
+
+#//!\name Search
+ bool contains(const coordT &t) const;
+ countT count(const coordT &t) const;
+ countT indexOf(const coordT &t, countT from = 0) const;
+ countT lastIndexOf(const coordT &t, countT from = -1) const;
+ void removeAll(const coordT &t);
+
+#//!\name Coordinates::iterator -- from QhullPoints, forwarding to coordinate_array
+ // before const_iterator for conversion with comparison operators
+ // Reviewed corelib/tools/qlist.h and corelib/tools/qvector.h w/o QT_STRICT_ITERATORS
+ class iterator {
+
+ private:
+ std::vector<coordT>::iterator i;
+ friend class const_iterator;
+
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef coordT value_type;
+ typedef value_type *pointer;
+ typedef value_type &reference;
+ typedef ptrdiff_t difference_type;
+
+ iterator() {}
+ iterator(const iterator &other) { i= other.i; }
+ explicit iterator(const std::vector<coordT>::iterator &vi) { i= vi; }
+ iterator & operator=(const iterator &other) { i= other.i; return *this; }
+ std::vector<coordT>::iterator &base() { return i; }
+ coordT & operator*() const { return *i; }
+ // No operator->() when the base type is double
+ coordT & operator[](countT idx) const { return i[idx]; }
+
+ bool operator==(const iterator &other) const { return i==other.i; }
+ bool operator!=(const iterator &other) const { return i!=other.i; }
+ bool operator<(const iterator &other) const { return i<other.i; }
+ bool operator<=(const iterator &other) const { return i<=other.i; }
+ bool operator>(const iterator &other) const { return i>other.i; }
+ bool operator>=(const iterator &other) const { return i>=other.i; }
+ // reinterpret_cast to break circular dependency
+ bool operator==(const Coordinates::const_iterator &other) const { return *this==reinterpret_cast<const iterator &>(other); }
+ bool operator!=(const Coordinates::const_iterator &other) const { return *this!=reinterpret_cast<const iterator &>(other); }
+ bool operator<(const Coordinates::const_iterator &other) const { return *this<reinterpret_cast<const iterator &>(other); }
+ bool operator<=(const Coordinates::const_iterator &other) const { return *this<=reinterpret_cast<const iterator &>(other); }
+ bool operator>(const Coordinates::const_iterator &other) const { return *this>reinterpret_cast<const iterator &>(other); }
+ bool operator>=(const Coordinates::const_iterator &other) const { return *this>=reinterpret_cast<const iterator &>(other); }
+
+ iterator & operator++() { ++i; return *this; }
+ iterator operator++(int) { return iterator(i++); }
+ iterator & operator--() { --i; return *this; }
+ iterator operator--(int) { return iterator(i--); }
+ iterator & operator+=(countT idx) { i += idx; return *this; }
+ iterator & operator-=(countT idx) { i -= idx; return *this; }
+ iterator operator+(countT idx) const { return iterator(i+idx); }
+ iterator operator-(countT idx) const { return iterator(i-idx); }
+ difference_type operator-(iterator other) const { return i-other.i; }
+ };//Coordinates::iterator
+
+#//!\name Coordinates::const_iterator
+ class const_iterator {
+
+ private:
+ std::vector<coordT>::const_iterator i;
+
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef coordT value_type;
+ typedef const value_type *pointer;
+ typedef const value_type &reference;
+ typedef ptrdiff_t difference_type;
+
+ const_iterator() {}
+ const_iterator(const const_iterator &other) { i= other.i; }
+ const_iterator(const iterator &o) : i(o.i) {}
+ explicit const_iterator(const std::vector<coordT>::const_iterator &vi) { i= vi; }
+ const_iterator &operator=(const const_iterator &other) { i= other.i; return *this; }
+ const coordT & operator*() const { return *i; }
+ // No operator->() when the base type is double
+ const coordT & operator[](countT idx) const { return i[idx]; }
+
+ bool operator==(const const_iterator &other) const { return i==other.i; }
+ bool operator!=(const const_iterator &other) const { return i!=other.i; }
+ bool operator<(const const_iterator &other) const { return i<other.i; }
+ bool operator<=(const const_iterator &other) const { return i<=other.i; }
+ bool operator>(const const_iterator &other) const { return i>other.i; }
+ bool operator>=(const const_iterator &other) const { return i>=other.i; }
+
+ const_iterator & operator++() { ++i; return *this; }
+ const_iterator operator++(int) { return const_iterator(i++); }
+ const_iterator & operator--() { --i; return *this; }
+ const_iterator operator--(int) { return const_iterator(i--); }
+ const_iterator & operator+=(countT idx) { i += idx; return *this; }
+ const_iterator & operator-=(countT idx) { i -= idx; return *this; }
+ const_iterator operator+(countT idx) const { return const_iterator(i+idx); }
+ const_iterator operator-(countT idx) const { return const_iterator(i-idx); }
+ difference_type operator-(const_iterator other) const { return i-other.i; }
+ };//Coordinates::const_iterator
+
+};//Coordinates
+
+//class CoordinatesIterator
+//QHULL_DECLARE_SEQUENTIAL_ITERATOR(Coordinates, coordT)
+
+class CoordinatesIterator
+{
+ typedef Coordinates::const_iterator const_iterator;
+
+private:
+ const Coordinates * c;
+ const_iterator i;
+
+public:
+ CoordinatesIterator(const Coordinates &container): c(&container), i(c->constBegin()) {}
+ CoordinatesIterator &operator=(const Coordinates &container) { c= &container; i= c->constBegin(); return *this; }
+ ~CoordinatesIterator() {}
+
+ bool findNext(const coordT &t) { while (i != c->constEnd()) if(*i++ == t){ return true;} return false; }
+ bool findPrevious(const coordT &t) { while (i != c->constBegin())if (*(--i) == t){ return true;} return false; }
+ bool hasNext() const { return i != c->constEnd(); }
+ bool hasPrevious() const { return i != c->constBegin(); }
+ const coordT & next() { return *i++; }
+ const coordT & previous() { return *--i; }
+ const coordT & peekNext() const { return *i; }
+ const coordT & peekPrevious() const { const_iterator p= i; return *--p; }
+ void toFront() { i= c->constBegin(); }
+ void toBack() { i= c->constEnd(); }
+};//CoordinatesIterator
+
+//class MutableCoordinatesIterator
+//QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Coordinates, coordT)
+class MutableCoordinatesIterator
+{
+ typedef Coordinates::iterator iterator;
+ typedef Coordinates::const_iterator const_iterator;
+
+private:
+ Coordinates * c;
+ iterator i;
+ iterator n;
+ bool item_exists() const { return const_iterator(n) != c->constEnd(); }
+
+public:
+ MutableCoordinatesIterator(Coordinates &container) : c(&container) { i= c->begin(); n= c->end(); }
+ MutableCoordinatesIterator &operator=(Coordinates &container) { c= &container; i= c->begin(); n= c->end(); return *this; }
+ ~MutableCoordinatesIterator() {}
+
+ bool findNext(const coordT &t) { while(c->constEnd()!=const_iterator(n= i)){ if(*i++==t){ return true;}} return false; }
+ bool findPrevious(const coordT &t) { while(c->constBegin()!=const_iterator(i)){ if(*(n= --i)== t){ return true;}} n= c->end(); return false; }
+ bool hasNext() const { return (c->constEnd()!=const_iterator(i)); }
+ bool hasPrevious() const { return (c->constBegin()!=const_iterator(i)); }
+ void insert(const coordT &t) { n= i= c->insert(i, t); ++i; }
+ coordT & next() { n= i++; return *n; }
+ coordT & peekNext() const { return *i; }
+ coordT & peekPrevious() const { iterator p= i; return *--p; }
+ coordT & previous() { n= --i; return *n; }
+ void remove() { if(c->constEnd()!=const_iterator(n)){ i= c->erase(n); n= c->end();} }
+ void setValue(const coordT &t) const { if(c->constEnd()!=const_iterator(n)){ *n= t;} }
+ void toFront() { i= c->begin(); n= c->end(); }
+ void toBack() { i= c->end(); n= i; }
+ coordT & value() { QHULL_ASSERT(item_exists()); return *n; }
+ const coordT & value() const { QHULL_ASSERT(item_exists()); return *n; }
+};//MutableCoordinatesIterator
+
+
+}//namespace orgQhull
+
+#//!\name Global
+
+std::ostream &operator<<(std::ostream &os, const orgQhull::Coordinates &c);
+
+#endif // QHCOORDINATES_H
diff --git a/xs/src/qhull/src/libqhullcpp/PointCoordinates.cpp b/xs/src/qhull/src/libqhullcpp/PointCoordinates.cpp
new file mode 100644
index 000000000..a5b71e901
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/PointCoordinates.cpp
@@ -0,0 +1,348 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/PointCoordinates.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#include "libqhullcpp/PointCoordinates.h"
+
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullPoint.h"
+
+#include <iterator>
+#include <iostream>
+
+using std::istream;
+using std::string;
+using std::ws;
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
+#endif
+
+namespace orgQhull {
+
+#//! PointCoordinates -- vector of PointCoordinates
+
+#//!\name Constructors
+
+PointCoordinates::
+PointCoordinates()
+: QhullPoints()
+, point_coordinates()
+, describe_points()
+{
+}
+
+PointCoordinates::
+PointCoordinates(const std::string &aComment)
+: QhullPoints()
+, point_coordinates()
+, describe_points(aComment)
+{
+}
+
+PointCoordinates::
+PointCoordinates(int pointDimension, const std::string &aComment)
+: QhullPoints()
+, point_coordinates()
+, describe_points(aComment)
+{
+ setDimension(pointDimension);
+}
+
+//! Qhull and QhullQh constructors are the same
+PointCoordinates::
+PointCoordinates(const Qhull &q)
+: QhullPoints(q)
+, point_coordinates()
+, describe_points()
+{
+}
+
+PointCoordinates::
+PointCoordinates(const Qhull &q, const std::string &aComment)
+: QhullPoints(q)
+, point_coordinates()
+, describe_points(aComment)
+{
+}
+
+PointCoordinates::
+PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment)
+: QhullPoints(q)
+, point_coordinates()
+, describe_points(aComment)
+{
+ setDimension(pointDimension);
+}
+
+PointCoordinates::
+PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
+: QhullPoints(q)
+, point_coordinates()
+, describe_points(aComment)
+{
+ setDimension(pointDimension);
+ append(coordinatesCount, c);
+}
+
+PointCoordinates::
+PointCoordinates(QhullQh *qqh)
+: QhullPoints(qqh)
+, point_coordinates()
+, describe_points()
+{
+}
+
+PointCoordinates::
+PointCoordinates(QhullQh *qqh, const std::string &aComment)
+: QhullPoints(qqh)
+, point_coordinates()
+, describe_points(aComment)
+{
+}
+
+PointCoordinates::
+PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment)
+: QhullPoints(qqh)
+, point_coordinates()
+, describe_points(aComment)
+{
+ setDimension(pointDimension);
+}
+
+PointCoordinates::
+PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c)
+: QhullPoints(qqh)
+, point_coordinates()
+, describe_points(aComment)
+{
+ setDimension(pointDimension);
+ append(coordinatesCount, c);
+}
+
+PointCoordinates::
+PointCoordinates(const PointCoordinates &other)
+: QhullPoints(other)
+, point_coordinates(other.point_coordinates)
+, describe_points(other.describe_points)
+{
+ makeValid(); // Update point_first and point_end
+}
+
+PointCoordinates & PointCoordinates::
+operator=(const PointCoordinates &other)
+{
+ QhullPoints::operator=(other);
+ point_coordinates= other.point_coordinates;
+ describe_points= other.describe_points;
+ makeValid(); // Update point_first and point_end
+ return *this;
+}//operator=
+
+PointCoordinates::
+~PointCoordinates()
+{ }
+
+#//!\name GetSet
+
+void PointCoordinates::
+checkValid() const
+{
+ if(getCoordinates().data()!=data()
+ || getCoordinates().count()!=coordinateCount()){
+ throw QhullError(10060, "Qhull error: first point (%x) is not PointCoordinates.data() or count (%d) is not PointCoordinates.count (%d)", coordinateCount(), getCoordinates().count(), 0.0, data());
+ }
+}//checkValid
+
+void PointCoordinates::
+setDimension(int i)
+{
+ if(i<0){
+ throw QhullError(10062, "Qhull error: can not set PointCoordinates dimension to %d", i);
+ }
+ int currentDimension=QhullPoints::dimension();
+ if(currentDimension!=0 && i!=currentDimension){
+ throw QhullError(10063, "Qhull error: can not change PointCoordinates dimension (from %d to %d)", currentDimension, i);
+ }
+ QhullPoints::setDimension(i);
+}//setDimension
+
+#//!\name Foreach
+
+Coordinates::ConstIterator PointCoordinates::
+beginCoordinates(countT pointIndex) const
+{
+ return point_coordinates.begin()+indexOffset(pointIndex);
+}
+
+Coordinates::Iterator PointCoordinates::
+beginCoordinates(countT pointIndex)
+{
+ return point_coordinates.begin()+indexOffset(pointIndex);
+}
+
+#//!\name Methods
+
+void PointCoordinates::
+append(countT coordinatesCount, const coordT *c)
+{
+ if(coordinatesCount<=0){
+ return;
+ }
+ if(includesCoordinates(c)){
+ throw QhullError(10065, "Qhull error: can not append a subset of PointCoordinates to itself. The coordinates for point %d may move.", indexOf(c, QhullError::NOthrow));
+ }
+ reserveCoordinates(coordinatesCount);
+ std::copy(c, c+coordinatesCount, std::back_inserter(point_coordinates));
+ makeValid();
+}//append coordT
+
+void PointCoordinates::
+append(const PointCoordinates &other)
+{
+ setDimension(other.dimension());
+ append(other.coordinateCount(), other.data());
+}//append PointCoordinates
+
+void PointCoordinates::
+append(const QhullPoint &p)
+{
+ setDimension(p.dimension());
+ append(p.dimension(), p.coordinates());
+}//append QhullPoint
+
+void PointCoordinates::
+appendComment(const std::string &s){
+ if(char c= s[0] && describe_points.empty()){
+ if(c=='-' || isdigit(c)){
+ throw QhullError(10028, "Qhull argument error: comments can not start with a number or minus, %s", 0, 0, 0.0, s.c_str());
+ }
+ }
+ describe_points += s;
+}//appendComment
+
+//! Read PointCoordinates from istream. First two numbers are dimension and count. A non-digit starts a rboxCommand.
+//! Overwrites describe_points. See qh_readpoints [io.c]
+void PointCoordinates::
+appendPoints(istream &in)
+{
+ int inDimension;
+ countT inCount;
+ in >> ws >> inDimension >> ws;
+ if(!in.good()){
+ in.clear();
+ string remainder;
+ getline(in, remainder);
+ throw QhullError(10005, "Qhull error: input did not start with dimension or count -- %s", 0, 0, 0, remainder.c_str());
+ }
+ char c= (char)in.peek();
+ if(c!='-' && !isdigit(c)){ // Comments start with a non-digit
+ getline(in, describe_points);
+ in >> ws;
+ }
+ in >> inCount >> ws;
+ if(!in.good()){
+ in.clear();
+ string remainder;
+ getline(in, remainder);
+ throw QhullError(10009, "Qhull error: input did not start with dimension and count -- %d %s", inDimension, 0, 0, remainder.c_str());
+ }
+ c= (char)in.peek();
+ if(c!='-' && !isdigit(c)){ // Comments start with a non-digit
+ getline(in, describe_points);
+ in >> ws;
+ }
+ if(inCount<inDimension){ // Count may precede dimension
+ std::swap(inCount, inDimension);
+ }
+ setDimension(inDimension);
+ reserveCoordinates(inCount*inDimension);
+ countT coordinatesCount= 0;
+ while(!in.eof()){
+ realT p;
+ in >> p >> ws;
+ if(in.fail()){
+ in.clear();
+ string remainder;
+ getline(in, remainder);
+ throw QhullError(10008, "Qhull error: failed to read coordinate %d of point %d\n %s", coordinatesCount % inDimension, coordinatesCount/inDimension, 0, remainder.c_str());
+ }else{
+ point_coordinates.push_back(p);
+ coordinatesCount++;
+ }
+ }
+ if(coordinatesCount != inCount*inDimension){
+ if(coordinatesCount%inDimension==0){
+ throw QhullError(10006, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates", int(inCount), inDimension, 0.0, int(coordinatesCount/inDimension));
+ }else{
+ throw QhullError(10012, "Qhull error: expected %d %d-d PointCoordinates but read %i PointCoordinates plus %f extra coordinates", inCount, inDimension, float(coordinatesCount%inDimension), coordinatesCount/inDimension);
+ }
+ }
+ makeValid();
+}//appendPoints istream
+
+PointCoordinates PointCoordinates::
+operator+(const PointCoordinates &other) const
+{
+ PointCoordinates pc= *this;
+ pc << other;
+ return pc;
+}//operator+
+
+void PointCoordinates::
+reserveCoordinates(countT newCoordinates)
+{
+ // vector::reserve is not const
+ point_coordinates.reserve((countT)point_coordinates.size()+newCoordinates); // WARN64
+ makeValid();
+}//reserveCoordinates
+
+#//!\name Helpers
+
+countT PointCoordinates::
+indexOffset(countT i) const {
+ countT n= i*dimension();
+ countT coordinatesCount= point_coordinates.count();
+ if(i<0 || n>coordinatesCount){
+ throw QhullError(10061, "Qhull error: point_coordinates is too short (%d) for point %d", coordinatesCount, i);
+ }
+ return n;
+}
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+using std::endl;
+using std::ostream;
+
+using orgQhull::Coordinates;
+using orgQhull::PointCoordinates;
+
+ostream&
+operator<<(ostream &os, const PointCoordinates &p)
+{
+ p.checkValid();
+ countT count= p.count();
+ int dimension= p.dimension();
+ string comment= p.comment();
+ if(comment.empty()){
+ os << dimension << endl;
+ }else{
+ os << dimension << " " << comment << endl;
+ }
+ os << count << endl;
+ Coordinates::ConstIterator c= p.beginCoordinates();
+ for(countT i=0; i<count; i++){
+ for(int j=0; j<dimension; j++){
+ os << *c++ << " ";
+ }
+ os << endl;
+ }
+ return os;
+}//operator<<
+
diff --git a/xs/src/qhull/src/libqhullcpp/PointCoordinates.h b/xs/src/qhull/src/libqhullcpp/PointCoordinates.h
new file mode 100644
index 000000000..4c63cdfca
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/PointCoordinates.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/PointCoordinates.h#4 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHPOINTCOORDINATES_H
+#define QHPOINTCOORDINATES_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullPoints.h"
+#include "libqhullcpp/Coordinates.h"
+
+#include <ostream>
+#include <string>
+
+#ifndef QHULL_NO_STL
+#include <vector>
+#endif
+
+namespace orgQhull {
+
+#//!\name Defined here
+ //! QhullPoints with Coordinates and description
+ //! Inherited by RboxPoints
+ class PointCoordinates;
+
+class PointCoordinates : public QhullPoints {
+
+private:
+#//!\name Fields
+ Coordinates point_coordinates; //! std::vector of point coordinates
+ //! may have extraCoordinates()
+ std::string describe_points; //! Comment describing PointCoordinates
+
+public:
+#//!\name Construct
+ //! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
+ //! If Qhull/QhullQh is not initialized, then dimension()==0 PointCoordinates();
+ PointCoordinates();
+ explicit PointCoordinates(const std::string &aComment);
+ PointCoordinates(int pointDimension, const std::string &aComment);
+ //! Qhull/QhullQh used for dimension() and QhullPoint equality
+ explicit PointCoordinates(const Qhull &q);
+ PointCoordinates(const Qhull &q, const std::string &aComment);
+ PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment);
+ PointCoordinates(const Qhull &q, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c); // may be invalid
+ //! Use append() and appendPoints() for Coordinates and vector<coordT>
+ explicit PointCoordinates(QhullQh *qqh);
+ PointCoordinates(QhullQh *qqh, const std::string &aComment);
+ PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment);
+ PointCoordinates(QhullQh *qqh, int pointDimension, const std::string &aComment, countT coordinatesCount, const coordT *c); // may be invalid
+ //! Use append() and appendPoints() for Coordinates and vector<coordT>
+ PointCoordinates(const PointCoordinates &other);
+ PointCoordinates & operator=(const PointCoordinates &other);
+ ~PointCoordinates();
+
+#//!\name Convert
+ //! QhullPoints coordinates, constData, data, count, size
+#ifndef QHULL_NO_STL
+ void append(const std::vector<coordT> &otherCoordinates) { if(!otherCoordinates.empty()){ append((int)otherCoordinates.size(), &otherCoordinates[0]); } }
+ std::vector<coordT> toStdVector() const { return point_coordinates.toStdVector(); }
+#endif //QHULL_NO_STL
+#ifdef QHULL_USES_QT
+ void append(const QList<coordT> &pointCoordinates) { if(!pointCoordinates.isEmpty()){ append(pointCoordinates.count(), &pointCoordinates[0]); } }
+ QList<coordT> toQList() const { return point_coordinates.toQList(); }
+#endif //QHULL_USES_QT
+
+#//!\name GetSet
+ //! See QhullPoints for coordinates, coordinateCount, dimension, empty, isEmpty, ==, !=
+ void checkValid() const;
+ std::string comment() const { return describe_points; }
+ void makeValid() { defineAs(point_coordinates.count(), point_coordinates.data()); }
+ const Coordinates & getCoordinates() const { return point_coordinates; }
+ void setComment(const std::string &s) { describe_points= s; }
+ void setDimension(int i);
+
+private:
+ //! disable QhullPoints.defineAs()
+ void defineAs(countT coordinatesCount, coordT *c) { QhullPoints::defineAs(coordinatesCount, c); }
+public:
+
+#//!\name ElementAccess
+ //! See QhullPoints for at, back, first, front, last, mid, [], value
+
+#//!\name Foreach
+ //! See QhullPoints for begin, constBegin, end
+ Coordinates::ConstIterator beginCoordinates() const { return point_coordinates.begin(); }
+ Coordinates::Iterator beginCoordinates() { return point_coordinates.begin(); }
+ Coordinates::ConstIterator beginCoordinates(countT pointIndex) const;
+ Coordinates::Iterator beginCoordinates(countT pointIndex);
+ Coordinates::ConstIterator endCoordinates() const { return point_coordinates.end(); }
+ Coordinates::Iterator endCoordinates() { return point_coordinates.end(); }
+
+#//!\name Search
+ //! See QhullPoints for contains, count, indexOf, lastIndexOf
+
+#//!\name GetSet
+ PointCoordinates operator+(const PointCoordinates &other) const;
+
+#//!\name Modify
+ //FIXUP QH11001: Add clear() and other modify operators from Coordinates.h. Include QhullPoint::operator=()
+ void append(countT coordinatesCount, const coordT *c); //! Dimension previously defined
+ void append(const coordT &c) { append(1, &c); } //! Dimension previously defined
+ void append(const QhullPoint &p);
+ //! See convert for std::vector and QList
+ void append(const Coordinates &c) { append(c.count(), c.data()); }
+ void append(const PointCoordinates &other);
+ void appendComment(const std::string &s);
+ void appendPoints(std::istream &in);
+ PointCoordinates & operator+=(const PointCoordinates &other) { append(other); return *this; }
+ PointCoordinates & operator+=(const coordT &c) { append(c); return *this; }
+ PointCoordinates & operator+=(const QhullPoint &p) { append(p); return *this; }
+ PointCoordinates & operator<<(const PointCoordinates &other) { return *this += other; }
+ PointCoordinates & operator<<(const coordT &c) { return *this += c; }
+ PointCoordinates & operator<<(const QhullPoint &p) { return *this += p; }
+ // reserve() is non-const
+ void reserveCoordinates(countT newCoordinates);
+
+#//!\name Helpers
+private:
+ int indexOffset(int i) const;
+
+};//PointCoordinates
+
+// No references to QhullPoint. Prevents use of QHULL_DECLARE_SEQUENTIAL_ITERATOR(PointCoordinates, QhullPoint)
+class PointCoordinatesIterator
+{
+ typedef PointCoordinates::const_iterator const_iterator;
+
+private:
+ const PointCoordinates *c;
+ const_iterator i;
+
+public:
+ PointCoordinatesIterator(const PointCoordinates &container) : c(&container), i(c->constBegin()) {}
+ PointCoordinatesIterator &operator=(const PointCoordinates &container) { c = &container; i = c->constBegin(); return *this; }
+
+ void toFront() { i = c->constBegin(); }
+ void toBack() { i = c->constEnd(); }
+ bool hasNext() const { return i != c->constEnd(); }
+ const QhullPoint next() { return *i++; }
+ const QhullPoint peekNext() const { return *i; }
+ bool hasPrevious() const { return i != c->constBegin(); }
+ const QhullPoint previous() { return *--i; }
+ const QhullPoint peekPrevious() const { const_iterator p = i; return *--p; }
+ bool findNext(const QhullPoint &t) { while(i != c->constEnd()){ if (*i++ == t) return true;} return false; }
+ bool findPrevious(const QhullPoint &t) { while(i != c->constBegin()){ if (*(--i) == t) return true;} return false; }
+};//CoordinatesIterator
+
+// FIXUP QH11002: Add MutablePointCoordinatesIterator after adding modify operators
+\
+}//namespace orgQhull
+
+#//!\name Global
+
+std::ostream & operator<<(std::ostream &os, const orgQhull::PointCoordinates &p);
+
+#endif // QHPOINTCOORDINATES_H
diff --git a/xs/src/qhull/src/libqhullcpp/Qhull.cpp b/xs/src/qhull/src/libqhullcpp/Qhull.cpp
new file mode 100644
index 000000000..7124a15cd
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/Qhull.cpp
@@ -0,0 +1,352 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/Qhull.cpp#4 $$Change: 2078 $
+** $DateTime: 2016/02/07 16:53:56 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! Qhull -- invoke qhull from C++
+#//! Compile libqhull_r and Qhull together due to use of setjmp/longjmp()
+
+#include "libqhullcpp/Qhull.h"
+
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/QhullQh.h"
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/QhullFacetList.h"
+
+#include <iostream>
+
+using std::cerr;
+using std::string;
+using std::vector;
+using std::ostream;
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
+#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
+#endif
+
+namespace orgQhull {
+
+#//!\name Global variables
+
+const char s_unsupported_options[]=" Fd TI ";
+const char s_not_output_options[]= " Fd TI A C d E H P Qb QbB Qbb Qc Qf Qg Qi Qm QJ Qr QR Qs Qt Qv Qx Qz Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 Q10 Q11 R Tc TC TM TP TR Tv TV TW U v V W ";
+
+#//!\name Constructor, destructor, etc.
+Qhull::
+Qhull()
+: qh_qh(0)
+, origin_point()
+, run_called(false)
+, feasible_point()
+{
+ allocateQhullQh();
+}//Qhull
+
+//! Invokes Qhull on rboxPoints
+//! Same as runQhull()
+//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
+//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
+Qhull::
+Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
+: qh_qh(0)
+, origin_point()
+, run_called(false)
+, feasible_point()
+{
+ allocateQhullQh();
+ runQhull(rboxPoints, qhullCommand2);
+}//Qhull rbox
+
+//! Invokes Qhull on a set of input points
+//! Same as runQhull()
+//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
+Qhull::
+Qhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2)
+: qh_qh(0)
+, origin_point()
+, run_called(false)
+, feasible_point()
+{
+ allocateQhullQh();
+ runQhull(inputComment2, pointDimension, pointCount, pointCoordinates, qhullCommand2);
+}//Qhull points
+
+void Qhull::
+allocateQhullQh()
+{
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ qh_qh= new QhullQh;
+ void *p= qh_qh;
+ void *p2= static_cast<qhT *>(qh_qh);
+ char *s= static_cast<char *>(p);
+ char *s2= static_cast<char *>(p2);
+ if(s!=s2){
+ throw QhullError(10074, "Qhull error: QhullQh at a different address than base type QhT (%d bytes). Please report compiler to qhull.org", int(s2-s));
+ }
+}//allocateQhullQh
+
+Qhull::
+~Qhull() throw()
+{
+ // Except for cerr, does not throw errors
+ if(qh_qh->hasQhullMessage()){
+ cerr<< "\nQhull output at end\n"; //FIXUP QH11005: where should error and log messages go on ~Qhull?
+ cerr<< qh_qh->qhullMessage();
+ qh_qh->clearQhullMessage();
+ }
+ delete qh_qh;
+ qh_qh= 0;
+}//~Qhull
+
+#//!\name GetSet
+
+void Qhull::
+checkIfQhullInitialized()
+{
+ if(!initialized()){ // qh_initqhull_buffers() not called
+ throw QhullError(10023, "Qhull error: checkIfQhullInitialized failed. Call runQhull() first.");
+ }
+}//checkIfQhullInitialized
+
+//! Return feasiblePoint for halfspace intersection
+//! If called before runQhull(), then it returns the value from setFeasiblePoint. qh.feasible_string overrides this value if it is defined.
+Coordinates Qhull::
+feasiblePoint() const
+{
+ Coordinates result;
+ if(qh_qh->feasible_point){
+ result.append(qh_qh->hull_dim, qh_qh->feasible_point);
+ }else{
+ result= feasible_point;
+ }
+ return result;
+}//feasiblePoint
+
+//! Return origin point for qh.input_dim
+QhullPoint Qhull::
+inputOrigin()
+{
+ QhullPoint result= origin();
+ result.setDimension(qh_qh->input_dim);
+ return result;
+}//inputOrigin
+
+#//!\name GetValue
+
+double Qhull::
+area(){
+ checkIfQhullInitialized();
+ if(!qh_qh->hasAreaVolume){
+ QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
+ qh_getarea(qh_qh, qh_qh->facet_list);
+ }
+ qh_qh->NOerrexit= true;
+ qh_qh->maybeThrowQhullMessage(QH_TRY_status);
+ }
+ return qh_qh->totarea;
+}//area
+
+double Qhull::
+volume(){
+ checkIfQhullInitialized();
+ if(!qh_qh->hasAreaVolume){
+ QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
+ qh_getarea(qh_qh, qh_qh->facet_list);
+ }
+ qh_qh->NOerrexit= true;
+ qh_qh->maybeThrowQhullMessage(QH_TRY_status);
+ }
+ return qh_qh->totvol;
+}//volume
+
+#//!\name Foreach
+
+//! Define QhullVertex::neighborFacets().
+//! Automatically called if merging facets or computing the Voronoi diagram.
+//! Noop if called multiple times.
+void Qhull::
+defineVertexNeighborFacets(){
+ checkIfQhullInitialized();
+ if(!qh_qh->hasAreaVolume){
+ QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
+ qh_vertexneighbors(qh_qh);
+ }
+ qh_qh->NOerrexit= true;
+ qh_qh->maybeThrowQhullMessage(QH_TRY_status);
+ }
+}//defineVertexNeighborFacets
+
+QhullFacetList Qhull::
+facetList() const{
+ return QhullFacetList(beginFacet(), endFacet());
+}//facetList
+
+QhullPoints Qhull::
+points() const
+{
+ return QhullPoints(qh_qh, qh_qh->hull_dim, qh_qh->num_points*qh_qh->hull_dim, qh_qh->first_point);
+}//points
+
+QhullPointSet Qhull::
+otherPoints() const
+{
+ return QhullPointSet(qh_qh, qh_qh->other_points);
+}//otherPoints
+
+//! Return vertices of the convex hull.
+QhullVertexList Qhull::
+vertexList() const{
+ return QhullVertexList(beginVertex(), endVertex());
+}//vertexList
+
+#//!\name Methods
+
+void Qhull::
+outputQhull()
+{
+ checkIfQhullInitialized();
+ QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
+ qh_produce_output2(qh_qh);
+ }
+ qh_qh->NOerrexit= true;
+ qh_qh->maybeThrowQhullMessage(QH_TRY_status);
+}//outputQhull
+
+void Qhull::
+outputQhull(const char *outputflags)
+{
+ checkIfQhullInitialized();
+ string cmd(" "); // qh_checkflags skips first word
+ cmd += outputflags;
+ char *command= const_cast<char*>(cmd.c_str());
+ QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
+ qh_clear_outputflags(qh_qh);
+ char *s = qh_qh->qhull_command + strlen(qh_qh->qhull_command) + 1; //space
+ strncat(qh_qh->qhull_command, command, sizeof(qh_qh->qhull_command)-strlen(qh_qh->qhull_command)-1);
+ qh_checkflags(qh_qh, command, const_cast<char *>(s_not_output_options));
+ qh_initflags(qh_qh, s);
+ qh_initqhull_outputflags(qh_qh);
+ if(qh_qh->KEEPminArea < REALmax/2
+ || (0 != qh_qh->KEEParea + qh_qh->KEEPmerge + qh_qh->GOODvertex
+ + qh_qh->GOODthreshold + qh_qh->GOODpoint + qh_qh->SPLITthresholds)){
+ facetT *facet;
+ qh_qh->ONLYgood= False;
+ FORALLfacet_(qh_qh->facet_list) {
+ facet->good= True;
+ }
+ qh_prepare_output(qh_qh);
+ }
+ qh_produce_output2(qh_qh);
+ if(qh_qh->VERIFYoutput && !qh_qh->STOPpoint && !qh_qh->STOPcone){
+ qh_check_points(qh_qh);
+ }
+ }
+ qh_qh->NOerrexit= true;
+ qh_qh->maybeThrowQhullMessage(QH_TRY_status);
+}//outputQhull
+
+//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
+void Qhull::
+runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2)
+{
+ runQhull(rboxPoints.comment().c_str(), rboxPoints.dimension(), rboxPoints.count(), &*rboxPoints.coordinates(), qhullCommand2);
+}//runQhull, RboxPoints
+
+//! pointCoordinates is a array of points, input sites ('d' or 'v'), or halfspaces with offset last ('H')
+//! Derived from qh_new_qhull [user.c]
+//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
+//! For qhull commands, see http://www.qhull.org/html/qhull.htm or html/qhull.htm
+void Qhull::
+runQhull(const char *inputComment, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand)
+{
+ /* gcc may issue a "might be clobbered" warning for pointDimension and pointCoordinates [-Wclobbered].
+ These parameters are not referenced after a longjmp() and hence not clobbered.
+ See http://stackoverflow.com/questions/7721854/what-sense-do-these-clobbered-variable-warnings-make */
+ if(run_called){
+ throw QhullError(10027, "Qhull error: runQhull called twice. Only one call allowed.");
+ }
+ run_called= true;
+ string s("qhull ");
+ s += qhullCommand;
+ char *command= const_cast<char*>(s.c_str());
+ /************* Expansion of QH_TRY_ for debugging
+ int QH_TRY_status;
+ if(qh_qh->NOerrexit){
+ qh_qh->NOerrexit= False;
+ QH_TRY_status= setjmp(qh_qh->errexit);
+ }else{
+ QH_TRY_status= QH_TRY_ERROR;
+ }
+ if(!QH_TRY_status){
+ *************/
+ QH_TRY_(qh_qh){ // no object creation -- destructors are skipped on longjmp()
+ qh_checkflags(qh_qh, command, const_cast<char *>(s_unsupported_options));
+ qh_initflags(qh_qh, command);
+ *qh_qh->rbox_command= '\0';
+ strncat( qh_qh->rbox_command, inputComment, sizeof(qh_qh->rbox_command)-1);
+ if(qh_qh->DELAUNAY){
+ qh_qh->PROJECTdelaunay= True; // qh_init_B() calls qh_projectinput()
+ }
+ pointT *newPoints= const_cast<pointT*>(pointCoordinates);
+ int newDimension= pointDimension;
+ int newIsMalloc= False;
+ if(qh_qh->HALFspace){
+ --newDimension;
+ initializeFeasiblePoint(newDimension);
+ newPoints= qh_sethalfspace_all(qh_qh, pointDimension, pointCount, newPoints, qh_qh->feasible_point);
+ newIsMalloc= True;
+ }
+ qh_init_B(qh_qh, newPoints, pointCount, newDimension, newIsMalloc);
+ qh_qhull(qh_qh);
+ qh_check_output(qh_qh);
+ qh_prepare_output(qh_qh);
+ if(qh_qh->VERIFYoutput && !qh_qh->STOPpoint && !qh_qh->STOPcone){
+ qh_check_points(qh_qh);
+ }
+ }
+ qh_qh->NOerrexit= true;
+ for(int k= qh_qh->hull_dim; k--; ){ // Do not move into QH_TRY block. It may throw an error
+ origin_point << 0.0;
+ }
+ qh_qh->maybeThrowQhullMessage(QH_TRY_status);
+}//runQhull
+
+#//!\name Helpers -- be careful of allocating C++ objects due to setjmp/longjmp() error handling by qh_... routines
+
+//! initialize qh.feasible_point for half-space intersection
+//! Sets from qh.feasible_string if available, otherwise from Qhull::feasible_point
+//! called only once from runQhull(), otherwise it leaks memory (the same as qh_setFeasible)
+void Qhull::
+initializeFeasiblePoint(int hulldim)
+{
+ if(qh_qh->feasible_string){
+ qh_setfeasible(qh_qh, hulldim);
+ }else{
+ if(feasible_point.isEmpty()){
+ qh_fprintf(qh_qh, qh_qh->ferr, 6209, "qhull error: missing feasible point for halfspace intersection. Use option 'Hn,n' or Qhull::setFeasiblePoint before runQhull()\n");
+ qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
+ }
+ if(feasible_point.size()!=(size_t)hulldim){
+ qh_fprintf(qh_qh, qh_qh->ferr, 6210, "qhull error: dimension of feasiblePoint should be %d. It is %u", hulldim, feasible_point.size());
+ qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
+ }
+ if (!(qh_qh->feasible_point= (coordT*)qh_malloc(hulldim * sizeof(coordT)))) {
+ qh_fprintf(qh_qh, qh_qh->ferr, 6202, "qhull error: insufficient memory for feasible point\n");
+ qh_errexit(qh_qh, qh_ERRmem, NULL, NULL);
+ }
+ coordT *t= qh_qh->feasible_point;
+ // No qh_... routines after here -- longjmp() ignores destructor
+ for(Coordinates::ConstIterator p=feasible_point.begin(); p<feasible_point.end(); p++){
+ *t++= *p;
+ }
+ }
+}//initializeFeasiblePoint
+
+}//namespace orgQhull
+
diff --git a/xs/src/qhull/src/libqhullcpp/Qhull.h b/xs/src/qhull/src/libqhullcpp/Qhull.h
new file mode 100644
index 000000000..e3ad9d8e1
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/Qhull.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/Qhull.h#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLCPP_H
+#define QHULLCPP_H
+
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/QhullVertex.h"
+#include "libqhullcpp/QhullFacet.h"
+
+namespace orgQhull {
+
+/***
+ Compile qhullcpp and libqhull with the same compiler. setjmp() and longjmp() must be the same.
+
+ #define QHULL_NO_STL
+ Do not supply conversions to STL
+ Coordinates.h requires <vector>. It could be rewritten for another vector class such as QList
+ #define QHULL_USES_QT
+ Supply conversions to QT
+ qhulltest requires QT. It is defined in RoadTest.h
+
+ #define QHULL_ASSERT
+ Defined by QhullError.h
+ It invokes assert()
+*/
+
+#//!\name Used here
+ class QhullFacetList;
+ class QhullPoints;
+ class QhullQh;
+ class RboxPoints;
+
+#//!\name Defined here
+ class Qhull;
+
+//! Interface to Qhull from C++
+class Qhull {
+
+private:
+#//!\name Members and friends
+ QhullQh * qh_qh; //! qhT for this instance
+ Coordinates origin_point; //! origin for qh_qh->hull_dim. Set by runQhull()
+ bool run_called; //! True at start of runQhull. Errors if call again.
+ Coordinates feasible_point; //! feasible point for half-space intersection (alternative to qh.feasible_string for qh.feasible_point)
+
+public:
+#//!\name Constructors
+ Qhull(); //!< call runQhull() next
+ Qhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
+ Qhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2);
+ ~Qhull() throw();
+private: //! Disable copy constructor and assignment. Qhull owns QhullQh.
+ Qhull(const Qhull &);
+ Qhull & operator=(const Qhull &);
+
+private:
+ void allocateQhullQh();
+
+public:
+
+#//!\name GetSet
+ void checkIfQhullInitialized();
+ int dimension() const { return qh_qh->input_dim; } //!< Dimension of input and result
+ void disableOutputStream() { qh_qh->disableOutputStream(); }
+ void enableOutputStream() { qh_qh->enableOutputStream(); }
+ countT facetCount() const { return qh_qh->num_facets; }
+ Coordinates feasiblePoint() const;
+ int hullDimension() const { return qh_qh->hull_dim; } //!< Dimension of the computed hull
+ bool hasOutputStream() const { return qh_qh->hasOutputStream(); }
+ bool initialized() const { return (qh_qh->hull_dim>0); }
+ const char * inputComment() const { return qh_qh->rbox_command; }
+ QhullPoint inputOrigin();
+ //! non-const due to QhullPoint
+ QhullPoint origin() { QHULL_ASSERT(initialized()); return QhullPoint(qh_qh, origin_point.data()); }
+ QhullQh * qh() const { return qh_qh; };
+ const char * qhullCommand() const { return qh_qh->qhull_command; }
+ const char * rboxCommand() const { return qh_qh->rbox_command; }
+ int rotateRandom() const { return qh_qh->ROTATErandom; } //!< Return QRn for repeating QR0 runs
+ void setFeasiblePoint(const Coordinates &c) { feasible_point= c; } //!< Sets qh.feasible_point via initializeFeasiblePoint
+ countT vertexCount() const { return qh_qh->num_vertices; }
+
+#//!\name Delegated to QhullQh
+ double angleEpsilon() const { return qh_qh->angleEpsilon(); } //!< Epsilon for hyperplane angle equality
+ void appendQhullMessage(const std::string &s) { qh_qh->appendQhullMessage(s); }
+ void clearQhullMessage() { qh_qh->clearQhullMessage(); }
+ double distanceEpsilon() const { return qh_qh->distanceEpsilon(); } //!< Epsilon for distance to hyperplane
+ double factorEpsilon() const { return qh_qh->factorEpsilon(); } //!< Factor for angleEpsilon and distanceEpsilon
+ std::string qhullMessage() const { return qh_qh->qhullMessage(); }
+ bool hasQhullMessage() const { return qh_qh->hasQhullMessage(); }
+ int qhullStatus() const { return qh_qh->qhullStatus(); }
+ void setErrorStream(std::ostream *os) { qh_qh->setErrorStream(os); }
+ void setFactorEpsilon(double a) { qh_qh->setFactorEpsilon(a); }
+ void setOutputStream(std::ostream *os) { qh_qh->setOutputStream(os); }
+
+#//!\name ForEach
+ QhullFacet beginFacet() const { return QhullFacet(qh_qh, qh_qh->facet_list); }
+ QhullVertex beginVertex() const { return QhullVertex(qh_qh, qh_qh->vertex_list); }
+ void defineVertexNeighborFacets(); //!< Automatically called if merging facets or Voronoi diagram
+ QhullFacet endFacet() const { return QhullFacet(qh_qh, qh_qh->facet_tail); }
+ QhullVertex endVertex() const { return QhullVertex(qh_qh, qh_qh->vertex_tail); }
+ QhullFacetList facetList() const;
+ QhullFacet firstFacet() const { return beginFacet(); }
+ QhullVertex firstVertex() const { return beginVertex(); }
+ QhullPoints points() const;
+ QhullPointSet otherPoints() const;
+ //! Same as points().coordinates()
+ coordT * pointCoordinateBegin() const { return qh_qh->first_point; }
+ coordT * pointCoordinateEnd() const { return qh_qh->first_point + qh_qh->num_points*qh_qh->hull_dim; }
+ QhullVertexList vertexList() const;
+
+#//!\name Methods
+ double area();
+ void outputQhull();
+ void outputQhull(const char * outputflags);
+ void runQhull(const RboxPoints &rboxPoints, const char *qhullCommand2);
+ void runQhull(const char *inputComment2, int pointDimension, int pointCount, const realT *pointCoordinates, const char *qhullCommand2);
+ double volume();
+
+#//!\name Helpers
+private:
+ void initializeFeasiblePoint(int hulldim);
+};//Qhull
+
+}//namespace orgQhull
+
+#endif // QHULLCPP_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullError.h b/xs/src/qhull/src/libqhullcpp/QhullError.h
new file mode 100644
index 000000000..08d50aa0f
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullError.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullError.h#2 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLERROR_H
+#define QHULLERROR_H
+
+#include "libqhullcpp/RoadError.h"
+// No dependencies on libqhull
+
+#ifndef QHULL_ASSERT
+#define QHULL_ASSERT assert
+#include <assert.h>
+#endif
+
+namespace orgQhull {
+
+#//!\name Defined here
+ //! QhullError -- std::exception class for Qhull
+ class QhullError;
+
+class QhullError : public RoadError {
+
+public:
+#//!\name Constants
+ enum {
+ QHULLfirstError= 10000, //MSG_QHULL_ERROR in Qhull's user.h
+ QHULLlastError= 10078,
+ NOthrow= 1 //! For flag to indexOf()
+ };
+
+#//!\name Constructors
+ // default constructors
+ QhullError() : RoadError() {};
+ QhullError(const QhullError &other) : RoadError(other) {}
+ QhullError(int code, const std::string &message) : RoadError(code, message) {};
+ QhullError(int code, const char *fmt) : RoadError(code, fmt) {};
+ QhullError(int code, const char *fmt, int d) : RoadError(code, fmt, d) {};
+ QhullError(int code, const char *fmt, int d, int d2) : RoadError(code, fmt, d, d2) {};
+ QhullError(int code, const char *fmt, int d, int d2, float f) : RoadError(code, fmt, d, d2, f) {};
+ QhullError(int code, const char *fmt, int d, int d2, float f, const char *s) : RoadError(code, fmt, d, d2, f, s) {};
+ QhullError(int code, const char *fmt, int d, int d2, float f, const void *x) : RoadError(code, fmt, d, d2, f, x) {};
+ QhullError(int code, const char *fmt, int d, int d2, float f, int i) : RoadError(code, fmt, d, d2, f, i) {};
+ QhullError(int code, const char *fmt, int d, int d2, float f, long long i) : RoadError(code, fmt, d, d2, f, i) {};
+ QhullError(int code, const char *fmt, int d, int d2, float f, double e) : RoadError(code, fmt, d, d2, f, e) {};
+ QhullError &operator=(const QhullError &other) { this->RoadError::operator=(other); return *this; }
+ ~QhullError() throw() {}
+
+};//class QhullError
+
+
+}//namespace orgQhull
+
+#//!\name Global
+
+inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullError &e) { return os << e.what(); }
+
+#endif // QHULLERROR_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullFacet.cpp b/xs/src/qhull/src/libqhullcpp/QhullFacet.cpp
new file mode 100644
index 000000000..40d3828a4
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullFacet.cpp
@@ -0,0 +1,519 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacet.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! QhullFacet -- Qhull's facet structure, facetT, as a C++ class
+
+#include "libqhullcpp/QhullFacet.h"
+
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/QhullSet.h"
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/QhullPointSet.h"
+#include "libqhullcpp/QhullRidge.h"
+#include "libqhullcpp/QhullFacetSet.h"
+#include "libqhullcpp/QhullVertex.h"
+
+#include <ostream>
+
+using std::endl;
+using std::ostream;
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
+#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
+#endif
+
+namespace orgQhull {
+
+#//!\name Class objects
+facetT QhullFacet::
+s_empty_facet= {0,0,0,0,{0},
+ 0,0,0,0,0,
+ 0,0,0,0,0,
+ 0,0,0,0,0,
+ 0,0,0,0,0,
+ 0,0,0,0,0,
+ 0,0,0,0,0,
+ 0,0,0,0};
+
+#//!\name Constructors
+
+QhullFacet::
+QhullFacet(const Qhull &q)
+: qh_facet(&s_empty_facet)
+, qh_qh(q.qh())
+{
+}
+
+QhullFacet::
+QhullFacet(const Qhull &q, facetT *f)
+: qh_facet(f ? f : &s_empty_facet)
+, qh_qh(q.qh())
+{
+}
+
+#//!\name GetSet
+
+//! Return voronoi center or facet centrum. Derived from qh_printcenter [io_r.c]
+//! if printFormat=qh_PRINTtriangles and qh.DELAUNAY, returns centrum of a Delaunay facet
+//! Sets center if needed
+//! Code duplicated for PrintCenter and getCenter
+//! Returns QhullPoint() if none or qh_INFINITE
+QhullPoint QhullFacet::
+getCenter(qh_PRINT printFormat)
+{
+ if(!qh_qh){
+ // returns QhullPoint()
+ }else if(qh_qh->CENTERtype==qh_ASvoronoi){
+ if(!qh_facet->normal || !qh_facet->upperdelaunay || !qh_qh->ATinfinity){
+ if(!qh_facet->center){
+ QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
+ qh_facet->center= qh_facetcenter(qh_qh, qh_facet->vertices);
+ }
+ qh_qh->NOerrexit= true;
+ qh_qh->maybeThrowQhullMessage(QH_TRY_status);
+ }
+ return QhullPoint(qh_qh, qh_qh->hull_dim-1, qh_facet->center);
+ }
+ }else if(qh_qh->CENTERtype==qh_AScentrum){
+ volatile int numCoords= qh_qh->hull_dim;
+ if(printFormat==qh_PRINTtriangles && qh_qh->DELAUNAY){
+ numCoords--;
+ }
+ if(!qh_facet->center){
+ QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
+ qh_facet->center= qh_getcentrum(qh_qh, getFacetT());
+ }
+ qh_qh->NOerrexit= true;
+ qh_qh->maybeThrowQhullMessage(QH_TRY_status);
+ }
+ return QhullPoint(qh_qh, numCoords, qh_facet->center);
+ }
+ return QhullPoint();
+ }//getCenter
+
+//! Return innerplane clearly below the vertices
+//! from io_r.c[qh_PRINTinner]
+QhullHyperplane QhullFacet::
+innerplane() const{
+ QhullHyperplane h;
+ if(qh_qh){
+ realT inner;
+ // Does not error, TRY_QHULL_ not needed
+ qh_outerinner(qh_qh, const_cast<facetT *>(getFacetT()), NULL, &inner);
+ h= hyperplane();
+ h.setOffset(h.offset()-inner); //inner is negative
+ }
+ return h;
+}//innerplane
+
+//! Return outerplane clearly above all points
+//! from io_r.c[qh_PRINTouter]
+QhullHyperplane QhullFacet::
+outerplane() const{
+ QhullHyperplane h;
+ if(qh_qh){
+ realT outer;
+ // Does not error, TRY_QHULL_ not needed
+ qh_outerinner(qh_qh, const_cast<facetT *>(getFacetT()), &outer, NULL);
+ h= hyperplane();
+ h.setOffset(h.offset()-outer); //outer is positive
+ }
+ return h;
+}//outerplane
+
+//! Set by qh_triangulate for option 'Qt'.
+//! Errors if tricoplanar and facetArea() or qh_getarea() called first.
+QhullFacet QhullFacet::
+tricoplanarOwner() const
+{
+ if(qh_facet->tricoplanar){
+ if(qh_facet->isarea){
+ throw QhullError(10018, "Qhull error: facetArea() or qh_getarea() previously called. triCoplanarOwner() is not available.");
+ }
+ return QhullFacet(qh_qh, qh_facet->f.triowner);
+ }
+ return QhullFacet(qh_qh);
+}//tricoplanarOwner
+
+QhullPoint QhullFacet::
+voronoiVertex()
+{
+ if(qh_qh && qh_qh->CENTERtype!=qh_ASvoronoi){
+ throw QhullError(10052, "Error: QhullFacet.voronoiVertex() requires option 'v' (qh_ASvoronoi)");
+ }
+ return getCenter();
+}//voronoiVertex
+
+#//!\name Value
+
+//! Disables tricoplanarOwner()
+double QhullFacet::
+facetArea()
+{
+ if(qh_qh && !qh_facet->isarea){
+ QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
+ qh_facet->f.area= qh_facetarea(qh_qh, qh_facet);
+ qh_facet->isarea= True;
+ }
+ qh_qh->NOerrexit= true;
+ qh_qh->maybeThrowQhullMessage(QH_TRY_status);
+ }
+ return qh_facet->f.area;
+}//facetArea
+
+#//!\name Foreach
+
+QhullPointSet QhullFacet::
+coplanarPoints() const
+{
+ return QhullPointSet(qh_qh, qh_facet->coplanarset);
+}//coplanarPoints
+
+QhullFacetSet QhullFacet::
+neighborFacets() const
+{
+ return QhullFacetSet(qh_qh, qh_facet->neighbors);
+}//neighborFacets
+
+QhullPointSet QhullFacet::
+outsidePoints() const
+{
+ return QhullPointSet(qh_qh, qh_facet->outsideset);
+}//outsidePoints
+
+QhullRidgeSet QhullFacet::
+ridges() const
+{
+ return QhullRidgeSet(qh_qh, qh_facet->ridges);
+}//ridges
+
+QhullVertexSet QhullFacet::
+vertices() const
+{
+ return QhullVertexSet(qh_qh, qh_facet->vertices);
+}//vertices
+
+}//namespace orgQhull
+
+#//!\name operator<<
+
+using std::ostream;
+
+using orgQhull::QhullFacet;
+using orgQhull::QhullFacetSet;
+using orgQhull::QhullPoint;
+using orgQhull::QhullPointSet;
+using orgQhull::QhullRidge;
+using orgQhull::QhullRidgeSet;
+using orgQhull::QhullSetBase;
+using orgQhull::QhullVertexSet;
+
+ostream &
+operator<<(ostream &os, const QhullFacet::PrintFacet &pr)
+{
+ os << pr.message;
+ QhullFacet f= *pr.facet;
+ if(f.getFacetT()==0){ // Special values from set iterator
+ os << " NULLfacet" << endl;
+ return os;
+ }
+ if(f.getFacetT()==qh_MERGEridge){
+ os << " MERGEridge" << endl;
+ return os;
+ }
+ if(f.getFacetT()==qh_DUPLICATEridge){
+ os << " DUPLICATEridge" << endl;
+ return os;
+ }
+ os << f.printHeader();
+ if(!f.ridges().isEmpty()){
+ os << f.printRidges();
+ }
+ return os;
+}//operator<< PrintFacet
+
+//! Print Voronoi center or facet centrum to stream. Same as qh_printcenter [_r.]
+//! Code duplicated for PrintCenter and getCenter
+//! Sets center if needed
+ostream &
+operator<<(ostream &os, const QhullFacet::PrintCenter &pr)
+{
+ facetT *f= pr.facet->getFacetT();
+ if(pr.facet->qh()->CENTERtype!=qh_ASvoronoi && pr.facet->qh()->CENTERtype!=qh_AScentrum){
+ return os;
+ }
+ if (pr.message){
+ os << pr.message;
+ }
+ int numCoords;
+ if(pr.facet->qh()->CENTERtype==qh_ASvoronoi){
+ numCoords= pr.facet->qh()->hull_dim-1;
+ if(!f->normal || !f->upperdelaunay || !pr.facet->qh()->ATinfinity){
+ if(!f->center){
+ f->center= qh_facetcenter(pr.facet->qh(), f->vertices);
+ }
+ for(int k=0; k<numCoords; k++){
+ os << f->center[k] << " "; // FIXUP QH11010 qh_REAL_1
+ }
+ }else{
+ for(int k=0; k<numCoords; k++){
+ os << qh_INFINITE << " "; // FIXUP QH11010 qh_REAL_1
+ }
+ }
+ }else{ // qh CENTERtype==qh_AScentrum
+ numCoords= pr.facet->qh()->hull_dim;
+ if(pr.print_format==qh_PRINTtriangles && pr.facet->qh()->DELAUNAY){
+ numCoords--;
+ }
+ if(!f->center){
+ f->center= qh_getcentrum(pr.facet->qh(), f);
+ }
+ for(int k=0; k<numCoords; k++){
+ os << f->center[k] << " "; // FIXUP QH11010 qh_REAL_1
+ }
+ }
+ if(pr.print_format==qh_PRINTgeom && numCoords==2){
+ os << " 0";
+ }
+ os << endl;
+ return os;
+}//operator<< PrintCenter
+
+//! Print flags for facet to stream. Space prefix. From qh_printfacetheader [io_r.c]
+ostream &
+operator<<(ostream &os, const QhullFacet::PrintFlags &p)
+{
+ const facetT *f= p.facet->getFacetT();
+ if(p.message){
+ os << p.message;
+ }
+
+ os << (p.facet->isTopOrient() ? " top" : " bottom");
+ if(p.facet->isSimplicial()){
+ os << " simplicial";
+ }
+ if(p.facet->isTriCoplanar()){
+ os << " tricoplanar";
+ }
+ if(p.facet->isUpperDelaunay()){
+ os << " upperDelaunay";
+ }
+ if(f->visible){
+ os << " visible";
+ }
+ if(f->newfacet){
+ os << " new";
+ }
+ if(f->tested){
+ os << " tested";
+ }
+ if(!f->good){
+ os << " notG";
+ }
+ if(f->seen){
+ os << " seen";
+ }
+ if(f->coplanar){
+ os << " coplanar";
+ }
+ if(f->mergehorizon){
+ os << " mergehorizon";
+ }
+ if(f->keepcentrum){
+ os << " keepcentrum";
+ }
+ if(f->dupridge){
+ os << " dupridge";
+ }
+ if(f->mergeridge && !f->mergeridge2){
+ os << " mergeridge1";
+ }
+ if(f->mergeridge2){
+ os << " mergeridge2";
+ }
+ if(f->newmerge){
+ os << " newmerge";
+ }
+ if(f->flipped){
+ os << " flipped";
+ }
+ if(f->notfurthest){
+ os << " notfurthest";
+ }
+ if(f->degenerate){
+ os << " degenerate";
+ }
+ if(f->redundant){
+ os << " redundant";
+ }
+ os << endl;
+ return os;
+}//operator<< PrintFlags
+
+//! Print header for facet to stream. Space prefix. From qh_printfacetheader [io_r.c]
+ostream &
+operator<<(ostream &os, const QhullFacet::PrintHeader &pr)
+{
+ QhullFacet facet= *pr.facet;
+ facetT *f= facet.getFacetT();
+ os << "- f" << facet.id() << endl;
+ os << facet.printFlags(" - flags:");
+ if(f->isarea){
+ os << " - area: " << f->f.area << endl; //FIXUP QH11010 2.2g
+ }else if(pr.facet->qh()->NEWfacets && f->visible && f->f.replace){
+ os << " - replacement: f" << f->f.replace->id << endl;
+ }else if(f->newfacet){
+ if(f->f.samecycle && f->f.samecycle != f){
+ os << " - shares same visible/horizon as f" << f->f.samecycle->id << endl;
+ }
+ }else if(f->tricoplanar /* !isarea */){
+ if(f->f.triowner){
+ os << " - owner of normal & centrum is facet f" << f->f.triowner->id << endl;
+ }
+ }else if(f->f.newcycle){
+ os << " - was horizon to f" << f->f.newcycle->id << endl;
+ }
+ if(f->nummerge){
+ os << " - merges: " << f->nummerge << endl;
+ }
+ os << facet.hyperplane().print(" - normal: ", "\n - offset: "); // FIXUP QH11010 %10.7g
+ if(pr.facet->qh()->CENTERtype==qh_ASvoronoi || f->center){
+ os << facet.printCenter(qh_PRINTfacets, " - center: ");
+ }
+#if qh_MAXoutside
+ if(f->maxoutside > pr.facet->qh()->DISTround){
+ os << " - maxoutside: " << f->maxoutside << endl; //FIXUP QH11010 %10.7g
+ }
+#endif
+ QhullPointSet ps= facet.outsidePoints();
+ if(!ps.isEmpty()){
+ QhullPoint furthest= ps.last();
+ if (ps.size() < 6) {
+ os << " - outside set(furthest p" << furthest.id() << "):" << endl;
+ for(QhullPointSet::iterator i=ps.begin(); i!=ps.end(); ++i){
+ QhullPoint p= *i;
+ os << p.print(" ");
+ }
+ }else if(ps.size()<21){
+ os << ps.print(" - outside set:");
+ }else{
+ os << " - outside set: " << ps.size() << " points.";
+ os << furthest.print(" Furthest");
+ }
+#if !qh_COMPUTEfurthest
+ os << " - furthest distance= " << f->furthestdist << endl; //FIXUP QH11010 %2.2g
+#endif
+ }
+ QhullPointSet cs= facet.coplanarPoints();
+ if(!cs.isEmpty()){
+ QhullPoint furthest= cs.last();
+ if (cs.size() < 6) {
+ os << " - coplanar set(furthest p" << furthest.id() << "):" << endl;
+ for(QhullPointSet::iterator i=cs.begin(); i!=cs.end(); ++i){
+ QhullPoint p= *i;
+ os << p.print(" ");
+ }
+ }else if(cs.size()<21){
+ os << cs.print(" - coplanar set:");
+ }else{
+ os << " - coplanar set: " << cs.size() << " points.";
+ os << furthest.print(" Furthest");
+ }
+ // FIXUP QH11027 Can/should zinc_(Zdistio) be called from C++ interface
+ double d= facet.distance(furthest);
+ os << " furthest distance= " << d << endl; //FIXUP QH11010 %2.2g
+ }
+ QhullVertexSet vs= facet.vertices();
+ if(!vs.isEmpty()){
+ os << vs.print(" - vertices:");
+ }
+ QhullFacetSet fs= facet.neighborFacets();
+ fs.selectAll();
+ if(!fs.isEmpty()){
+ os << fs.printIdentifiers(" - neighboring facets:");
+ }
+ return os;
+}//operator<< PrintHeader
+
+
+//! Print ridges of facet to stream. Same as qh_printfacetridges [io_r.c]
+ostream &
+operator<<(ostream &os, const QhullFacet::PrintRidges &pr)
+{
+ const QhullFacet facet= *pr.facet;
+ facetT *f= facet.getFacetT();
+ QhullRidgeSet rs= facet.ridges();
+ if(!rs.isEmpty()){
+ if(f->visible && pr.facet->qh()->NEWfacets){
+ os << " - ridges(ids may be garbage):";
+ for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
+ QhullRidge r= *i;
+ os << " r" << r.id();
+ }
+ os << endl;
+ }else{
+ os << " - ridges:" << endl;
+ }
+
+ // Keep track of printed ridges
+ for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
+ QhullRidge r= *i;
+ r.getRidgeT()->seen= false;
+ }
+ int ridgeCount= 0;
+ if(facet.dimension()==3){
+ for(QhullRidge r= rs.first(); !r.getRidgeT()->seen; r= r.nextRidge3d(facet)){
+ r.getRidgeT()->seen= true;
+ os << r.print("");
+ ++ridgeCount;
+ if(!r.hasNextRidge3d(facet)){
+ break;
+ }
+ }
+ }else {
+ QhullFacetSet ns(facet.neighborFacets());
+ for(QhullFacetSet::iterator i=ns.begin(); i!=ns.end(); ++i){
+ QhullFacet neighbor= *i;
+ QhullRidgeSet nrs(neighbor.ridges());
+ for(QhullRidgeSet::iterator j=nrs.begin(); j!=nrs.end(); ++j){
+ QhullRidge r= *j;
+ if(r.otherFacet(neighbor)==facet){
+ r.getRidgeT()->seen= true;
+ os << r.print("");
+ ridgeCount++;
+ }
+ }
+ }
+ }
+ if(ridgeCount!=rs.count()){
+ os << " - all ridges:";
+ for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
+ QhullRidge r= *i;
+ os << " r" << r.id();
+ }
+ os << endl;
+ }
+ for(QhullRidgeSet::iterator i=rs.begin(); i!=rs.end(); ++i){
+ QhullRidge r= *i;
+ if(!r.getRidgeT()->seen){
+ os << r.print("");
+ }
+ }
+ }
+ return os;
+}//operator<< PrintRidges
+
+// "No conversion" error if defined inline
+ostream &
+operator<<(ostream &os, QhullFacet &f)
+{
+ os << f.print("");
+ return os;
+}//<< QhullFacet
diff --git a/xs/src/qhull/src/libqhullcpp/QhullFacet.h b/xs/src/qhull/src/libqhullcpp/QhullFacet.h
new file mode 100644
index 000000000..ae4f008fd
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullFacet.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacet.h#4 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLFACET_H
+#define QHULLFACET_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullHyperplane.h"
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/QhullSet.h"
+#include "libqhullcpp/QhullPointSet.h"
+
+#include <ostream>
+
+namespace orgQhull {
+
+#//!\name Used here
+ class Coordinates;
+ class Qhull;
+ class QhullFacetSet;
+ class QhullRidge;
+ class QhullVertex;
+ class QhullVertexSet;
+
+#//!\name Defined here
+ class QhullFacet;
+ typedef QhullSet<QhullRidge> QhullRidgeSet;
+
+//! A QhullFacet is the C++ equivalent to Qhull's facetT*
+class QhullFacet {
+
+#//!\name Defined here
+public:
+ typedef facetT * base_type; // for QhullVertexSet
+
+private:
+#//!\name Fields -- no additions (QhullFacetSet of facetT*)
+ facetT * qh_facet; //!< Corresponding facetT, may be 0 for corner cases (e.g., *facetSet.end()==0) and tricoplanarOwner()
+ QhullQh * qh_qh; //!< QhullQh/qhT for facetT, may be 0
+
+#//!\name Class objects
+ static facetT s_empty_facet; // needed for shallow copy
+
+public:
+#//!\name Constructors
+ QhullFacet() : qh_facet(&s_empty_facet), qh_qh(0) {}
+ explicit QhullFacet(const Qhull &q);
+ QhullFacet(const Qhull &q, facetT *f);
+ explicit QhullFacet(QhullQh *qqh) : qh_facet(&s_empty_facet), qh_qh(qqh) {}
+ QhullFacet(QhullQh *qqh, facetT *f) : qh_facet(f ? f : &s_empty_facet), qh_qh(qqh) {}
+ // Creates an alias. Does not copy QhullFacet. Needed for return by value and parameter passing
+ QhullFacet(const QhullFacet &other) : qh_facet(other.qh_facet ? other.qh_facet : &s_empty_facet), qh_qh(other.qh_qh) {}
+ // Creates an alias. Does not copy QhullFacet. Needed for vector<QhullFacet>
+ QhullFacet & operator=(const QhullFacet &other) { qh_facet= other.qh_facet ? other.qh_facet : &s_empty_facet; qh_qh= other.qh_qh; return *this; }
+ ~QhullFacet() {}
+
+
+#//!\name GetSet
+ int dimension() const { return (qh_qh ? qh_qh->hull_dim : 0); }
+ QhullPoint getCenter() { return getCenter(qh_PRINTpoints); }
+ QhullPoint getCenter(qh_PRINT printFormat);
+ facetT * getBaseT() const { return getFacetT(); } //!< For QhullSet<QhullFacet>
+ // Do not define facetT(). It conflicts with return type facetT*
+ facetT * getFacetT() const { return qh_facet; }
+ QhullHyperplane hyperplane() const { return QhullHyperplane(qh_qh, dimension(), qh_facet->normal, qh_facet->offset); }
+ countT id() const { return (qh_facet ? qh_facet->id : (int)qh_IDunknown); }
+ QhullHyperplane innerplane() const;
+ bool isValid() const { return qh_qh && qh_facet && qh_facet != &s_empty_facet; }
+ bool isGood() const { return qh_facet && qh_facet->good; }
+ bool isSimplicial() const { return qh_facet && qh_facet->simplicial; }
+ bool isTopOrient() const { return qh_facet && qh_facet->toporient; }
+ bool isTriCoplanar() const { return qh_facet && qh_facet->tricoplanar; }
+ bool isUpperDelaunay() const { return qh_facet && qh_facet->upperdelaunay; }
+ QhullFacet next() const { return QhullFacet(qh_qh, qh_facet->next); }
+ bool operator==(const QhullFacet &other) const { return qh_facet==other.qh_facet; }
+ bool operator!=(const QhullFacet &other) const { return !operator==(other); }
+ QhullHyperplane outerplane() const;
+ QhullFacet previous() const { return QhullFacet(qh_qh, qh_facet->previous); }
+ QhullQh * qh() const { return qh_qh; }
+ QhullFacet tricoplanarOwner() const;
+ QhullPoint voronoiVertex();
+
+#//!\name value
+ //! Undefined if c.size() != dimension()
+ double distance(const Coordinates &c) const { return distance(c.data()); }
+ double distance(const pointT *p) const { return distance(QhullPoint(qh_qh, const_cast<coordT *>(p))); }
+ double distance(const QhullPoint &p) const { return hyperplane().distance(p); }
+ double facetArea();
+
+#//!\name foreach
+ // Can not inline. Otherwise circular reference
+ QhullPointSet coplanarPoints() const;
+ QhullFacetSet neighborFacets() const;
+ QhullPointSet outsidePoints() const;
+ QhullRidgeSet ridges() const;
+ QhullVertexSet vertices() const;
+
+#//!\name IO
+ struct PrintCenter{
+ QhullFacet * facet; // non-const due to facet.center()
+ const char * message;
+ qh_PRINT print_format;
+ PrintCenter(QhullFacet &f, qh_PRINT printFormat, const char * s) : facet(&f), message(s), print_format(printFormat){}
+ };//PrintCenter
+ PrintCenter printCenter(qh_PRINT printFormat, const char *message) { return PrintCenter(*this, printFormat, message); }
+
+ struct PrintFacet{
+ QhullFacet * facet; // non-const due to f->center()
+ const char * message;
+ explicit PrintFacet(QhullFacet &f, const char * s) : facet(&f), message(s) {}
+ };//PrintFacet
+ PrintFacet print(const char *message) { return PrintFacet(*this, message); }
+
+ struct PrintFlags{
+ const QhullFacet *facet;
+ const char * message;
+ PrintFlags(const QhullFacet &f, const char *s) : facet(&f), message(s) {}
+ };//PrintFlags
+ PrintFlags printFlags(const char *message) const { return PrintFlags(*this, message); }
+
+ struct PrintHeader{
+ QhullFacet * facet; // non-const due to f->center()
+ PrintHeader(QhullFacet &f) : facet(&f) {}
+ };//PrintHeader
+ PrintHeader printHeader() { return PrintHeader(*this); }
+
+ struct PrintRidges{
+ const QhullFacet *facet;
+ PrintRidges(QhullFacet &f) : facet(&f) {}
+ };//PrintRidges
+ PrintRidges printRidges() { return PrintRidges(*this); }
+
+};//class QhullFacet
+
+}//namespace orgQhull
+
+#//!\name Global
+
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintFacet &pr);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintCenter &pr);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintFlags &pr);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintHeader &pr);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacet::PrintRidges &pr);
+std::ostream &operator<<(std::ostream &os, orgQhull::QhullFacet &f); // non-const due to qh_getcenter()
+
+#endif // QHULLFACET_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullFacetList.cpp b/xs/src/qhull/src/libqhullcpp/QhullFacetList.cpp
new file mode 100644
index 000000000..9e6ddfe9e
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullFacetList.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetList.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! QhullFacetList -- Qhull's linked facets, as a C++ class
+
+#include "libqhullcpp/QhullFacetList.h"
+
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/QhullRidge.h"
+#include "libqhullcpp/QhullVertex.h"
+
+using std::string;
+using std::vector;
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
+#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
+#endif
+
+namespace orgQhull {
+
+#//!\name Constructors
+
+QhullFacetList::
+QhullFacetList(const Qhull &q, facetT *b, facetT *e )
+: QhullLinkedList<QhullFacet>(QhullFacet(q, b), QhullFacet(q, e))
+, select_all(false)
+{
+}
+
+#//!\name Conversions
+
+// See qt_qhull.cpp for QList conversions
+
+#ifndef QHULL_NO_STL
+std::vector<QhullFacet> QhullFacetList::
+toStdVector() const
+{
+ QhullLinkedListIterator<QhullFacet> i(*this);
+ std::vector<QhullFacet> vs;
+ while(i.hasNext()){
+ QhullFacet f= i.next();
+ if(isSelectAll() || f.isGood()){
+ vs.push_back(f);
+ }
+ }
+ return vs;
+}//toStdVector
+#endif //QHULL_NO_STL
+
+#ifndef QHULL_NO_STL
+//! Same as PrintVertices
+std::vector<QhullVertex> QhullFacetList::
+vertices_toStdVector() const
+{
+ std::vector<QhullVertex> vs;
+ QhullVertexSet qvs(qh(), first().getFacetT(), 0, isSelectAll());
+
+ for(QhullVertexSet::iterator i=qvs.begin(); i!=qvs.end(); ++i){
+ vs.push_back(*i);
+ }
+ return vs;
+}//vertices_toStdVector
+#endif //QHULL_NO_STL
+
+#//!\name GetSet
+
+bool QhullFacetList::
+contains(const QhullFacet &facet) const
+{
+ if(isSelectAll()){
+ return QhullLinkedList<QhullFacet>::contains(facet);
+ }
+ for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
+ QhullFacet f= *i;
+ if(f==facet && f.isGood()){
+ return true;
+ }
+ }
+ return false;
+}//contains
+
+int QhullFacetList::
+count() const
+{
+ if(isSelectAll()){
+ return QhullLinkedList<QhullFacet>::count();
+ }
+ int counter= 0;
+ for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
+ if((*i).isGood()){
+ counter++;
+ }
+ }
+ return counter;
+}//count
+
+int QhullFacetList::
+count(const QhullFacet &facet) const
+{
+ if(isSelectAll()){
+ return QhullLinkedList<QhullFacet>::count(facet);
+ }
+ int counter= 0;
+ for(QhullFacetList::const_iterator i=begin(); i != end(); ++i){
+ QhullFacet f= *i;
+ if(f==facet && f.isGood()){
+ counter++;
+ }
+ }
+ return counter;
+}//count
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+using std::endl;
+using std::ostream;
+using orgQhull::QhullFacet;
+using orgQhull::QhullFacetList;
+using orgQhull::QhullVertex;
+using orgQhull::QhullVertexSet;
+
+ostream &
+operator<<(ostream &os, const QhullFacetList::PrintFacetList &pr)
+{
+ os << pr.print_message;
+ QhullFacetList fs= *pr.facet_list;
+ os << "Vertices for " << fs.count() << " facets" << endl;
+ os << fs.printVertices();
+ os << fs.printFacets();
+ return os;
+}//operator<<
+
+//! Print facet list to stream. From qh_printafacet [io_r.c]
+ostream &
+operator<<(ostream &os, const QhullFacetList::PrintFacets &pr)
+{
+ for(QhullFacetList::const_iterator i= pr.facet_list->begin(); i != pr.facet_list->end(); ++i){
+ QhullFacet f= *i;
+ if(pr.facet_list->isSelectAll() || f.isGood()){
+ os << f.print("");
+ }
+ }
+ return os;
+}//printFacets
+
+//! Print vertices of good faces in facet list to stream. From qh_printvertexlist [io_r.c]
+//! Same as vertices_toStdVector
+ostream &
+operator<<(ostream &os, const QhullFacetList::PrintVertices &pr)
+{
+ QhullVertexSet vs(pr.facet_list->qh(), pr.facet_list->first().getFacetT(), NULL, pr.facet_list->isSelectAll());
+ for(QhullVertexSet::iterator i=vs.begin(); i!=vs.end(); ++i){
+ QhullVertex v= *i;
+ os << v.print("");
+ }
+ return os;
+}//printVertices
+
+std::ostream &
+operator<<(ostream &os, const QhullFacetList &fs)
+{
+ os << fs.printFacets();
+ return os;
+}//QhullFacetList
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullFacetList.h b/xs/src/qhull/src/libqhullcpp/QhullFacetList.h
new file mode 100644
index 000000000..e61e56840
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullFacetList.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetList.h#2 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLFACETLIST_H
+#define QHULLFACETLIST_H
+
+#include "libqhullcpp/QhullLinkedList.h"
+#include "libqhullcpp/QhullFacet.h"
+
+#include <ostream>
+
+#ifndef QHULL_NO_STL
+#include <vector>
+#endif
+
+namespace orgQhull {
+
+#//!\name Used here
+ class Qhull;
+ class QhullFacet;
+ class QhullQh;
+
+#//!\name Defined here
+ //! QhullFacetList -- List of QhullFacet/facetT, as a C++ class.
+ //!\see QhullFacetSet.h
+ class QhullFacetList;
+ //! QhullFacetListIterator -- if(f.isGood()){ ... }
+ typedef QhullLinkedListIterator<QhullFacet> QhullFacetListIterator;
+
+class QhullFacetList : public QhullLinkedList<QhullFacet> {
+
+#//!\name Fields
+private:
+ bool select_all; //! True if include bad facets. Default is false.
+
+#//!\name Constructors
+public:
+ QhullFacetList(const Qhull &q, facetT *b, facetT *e);
+ QhullFacetList(QhullQh *qqh, facetT *b, facetT *e);
+ QhullFacetList(QhullFacet b, QhullFacet e) : QhullLinkedList<QhullFacet>(b, e), select_all(false) {}
+ //Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
+ QhullFacetList(const QhullFacetList &other) : QhullLinkedList<QhullFacet>(*other.begin(), *other.end()), select_all(other.select_all) {}
+ QhullFacetList & operator=(const QhullFacetList &other) { QhullLinkedList<QhullFacet>::operator =(other); select_all= other.select_all; return *this; }
+ ~QhullFacetList() {}
+
+private: //!Disable default constructor. See QhullLinkedList
+ QhullFacetList();
+public:
+
+#//!\name Conversion
+#ifndef QHULL_NO_STL
+ std::vector<QhullFacet> toStdVector() const;
+ std::vector<QhullVertex> vertices_toStdVector() const;
+#endif //QHULL_NO_STL
+#ifdef QHULL_USES_QT
+ QList<QhullFacet> toQList() const;
+ QList<QhullVertex> vertices_toQList() const;
+#endif //QHULL_USES_QT
+
+#//!\name GetSet
+ //! Filtered by facet.isGood(). May be 0 when !isEmpty().
+ countT count() const;
+ bool contains(const QhullFacet &f) const;
+ countT count(const QhullFacet &f) const;
+ bool isSelectAll() const { return select_all; }
+ QhullQh * qh() const { return first().qh(); }
+ void selectAll() { select_all= true; }
+ void selectGood() { select_all= false; }
+ //!< operator==() does not depend on isGood()
+
+#//!\name IO
+ struct PrintFacetList{
+ const QhullFacetList *facet_list;
+ const char * print_message; //!< non-null message
+ PrintFacetList(const QhullFacetList &fl, const char *message) : facet_list(&fl), print_message(message) {}
+ };//PrintFacetList
+ PrintFacetList print(const char *message) const { return PrintFacetList(*this, message); }
+
+ struct PrintFacets{
+ const QhullFacetList *facet_list;
+ PrintFacets(const QhullFacetList &fl) : facet_list(&fl) {}
+ };//PrintFacets
+ PrintFacets printFacets() const { return PrintFacets(*this); }
+
+ struct PrintVertices{
+ const QhullFacetList *facet_list;
+ PrintVertices(const QhullFacetList &fl) : facet_list(&fl) {}
+ };//PrintVertices
+ PrintVertices printVertices() const { return PrintVertices(*this); }
+};//class QhullFacetList
+
+}//namespace orgQhull
+
+#//!\name == Global namespace =========================================
+
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintFacetList &p);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintFacets &p);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList::PrintVertices &p);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetList &fs);
+
+#endif // QHULLFACETLIST_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullFacetSet.cpp b/xs/src/qhull/src/libqhullcpp/QhullFacetSet.cpp
new file mode 100644
index 000000000..d30c21e26
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullFacetSet.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetSet.cpp#2 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! QhullFacetSet -- Qhull's linked facets, as a C++ class
+
+#include "libqhullcpp/QhullFacetSet.h"
+
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/QhullRidge.h"
+#include "libqhullcpp/QhullVertex.h"
+
+#ifndef QHULL_NO_STL
+using std::vector;
+#endif
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
+#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
+#endif
+
+namespace orgQhull {
+
+#//!\name Conversions
+
+// See qt-qhull.cpp for QList conversions
+
+#ifndef QHULL_NO_STL
+std::vector<QhullFacet> QhullFacetSet::
+toStdVector() const
+{
+ QhullSetIterator<QhullFacet> i(*this);
+ std::vector<QhullFacet> vs;
+ while(i.hasNext()){
+ QhullFacet f= i.next();
+ if(isSelectAll() || f.isGood()){
+ vs.push_back(f);
+ }
+ }
+ return vs;
+}//toStdVector
+#endif //QHULL_NO_STL
+
+#//!\name GetSet
+
+bool QhullFacetSet::
+contains(const QhullFacet &facet) const
+{
+ if(isSelectAll()){
+ return QhullSet<QhullFacet>::contains(facet);
+ }
+ for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
+ QhullFacet f= *i;
+ if(f==facet && f.isGood()){
+ return true;
+ }
+ }
+ return false;
+}//contains
+
+int QhullFacetSet::
+count() const
+{
+ if(isSelectAll()){
+ return QhullSet<QhullFacet>::count();
+ }
+ int counter= 0;
+ for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
+ QhullFacet f= *i;
+ if(f.isGood()){
+ counter++;
+ }
+ }
+ return counter;
+}//count
+
+int QhullFacetSet::
+count(const QhullFacet &facet) const
+{
+ if(isSelectAll()){
+ return QhullSet<QhullFacet>::count(facet);
+ }
+ int counter= 0;
+ for(QhullFacetSet::const_iterator i=begin(); i != end(); ++i){
+ QhullFacet f= *i;
+ if(f==facet && f.isGood()){
+ counter++;
+ }
+ }
+ return counter;
+}//count
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+using std::endl;
+using std::ostream;
+using orgQhull::QhullFacet;
+using orgQhull::QhullFacetSet;
+
+ostream &
+operator<<(ostream &os, const QhullFacetSet &fs)
+{
+ os << fs.print("");
+ return os;
+}//<<QhullFacetSet
+
+ostream &
+
+operator<<(ostream &os, const QhullFacetSet::PrintFacetSet &pr)
+{
+ os << pr.print_message;
+ QhullFacetSet fs= *pr.facet_set;
+ for(QhullFacetSet::iterator i=fs.begin(); i != fs.end(); ++i){
+ QhullFacet f= *i;
+ if(fs.isSelectAll() || f.isGood()){
+ os << f;
+ }
+ }
+ return os;
+}//<< QhullFacetSet::PrintFacetSet
+
+//! Print facet identifiers to stream. Space prefix. From qh_printfacetheader [io_r.c]
+ostream &
+operator<<(ostream &os, const QhullFacetSet::PrintIdentifiers &p)
+{
+ os << p.print_message;
+ for(QhullFacetSet::const_iterator i=p.facet_set->begin(); i!=p.facet_set->end(); ++i){
+ const QhullFacet f= *i;
+ if(f.getFacetT()==qh_MERGEridge){
+ os << " MERGE";
+ }else if(f.getFacetT()==qh_DUPLICATEridge){
+ os << " DUP";
+ }else if(p.facet_set->isSelectAll() || f.isGood()){
+ os << " f" << f.id();
+ }
+ }
+ os << endl;
+ return os;
+}//<<QhullFacetSet::PrintIdentifiers
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullFacetSet.h b/xs/src/qhull/src/libqhullcpp/QhullFacetSet.h
new file mode 100644
index 000000000..ee3208559
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullFacetSet.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullFacetSet.h#2 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLFACETSET_H
+#define QHULLFACETSET_H
+
+#include "libqhullcpp/QhullSet.h"
+#include "libqhullcpp/QhullFacet.h"
+
+#include <ostream>
+
+namespace orgQhull {
+
+#//!\name Used here
+ class Qhull;
+
+#//!\name Defined here
+ //! QhullFacetSet -- a set of Qhull facets, as a C++ class. See QhullFacetList.h
+ class QhullFacetSet;
+ typedef QhullSetIterator<QhullFacet> QhullFacetSetIterator;
+
+class QhullFacetSet : public QhullSet<QhullFacet> {
+
+#//!\name Defined here
+public:
+ typedef facetT * base_type; // for QhullVertexSet
+
+private:
+#//!\name Fields
+ bool select_all; //! True if include bad facets. Default is false.
+
+public:
+#//!\name Constructor
+ //Conversion from setT* is not type-safe. Implicit conversion for void* to T
+ QhullFacetSet(const Qhull &q, setT *s) : QhullSet<QhullFacet>(q, s), select_all(false) {}
+ QhullFacetSet(QhullQh *qqh, setT *s) : QhullSet<QhullFacet>(qqh, s), select_all(false) {}
+ //!Copy constructor copies pointers but not contents. Needed for return by value and parameter passing.
+ QhullFacetSet(const QhullFacetSet &other) : QhullSet<QhullFacet>(other), select_all(other.select_all) {}
+ //!Assignment copies pointers but not contents.
+ QhullFacetSet & operator=(const QhullFacetSet &other) { QhullSet<QhullFacet>::operator=(other); select_all= other.select_all; return *this; }
+
+private:
+ //!Disable default constructor. See QhullSetBase
+ QhullFacetSet();
+public:
+
+#//!\name Conversion
+#ifndef QHULL_NO_STL
+ std::vector<QhullFacet> toStdVector() const;
+#endif //QHULL_NO_STL
+#ifdef QHULL_USES_QT
+ QList<QhullFacet> toQList() const;
+#endif //QHULL_USES_QT
+
+#//!\name GetSet
+ //! Filtered by facet.isGood(). May be 0 when !isEmpty().
+ countT count() const;
+ bool contains(const QhullFacet &f) const;
+ countT count(const QhullFacet &f) const;
+ bool isSelectAll() const { return select_all; }
+ //! operator==() does not depend on isGood()
+ void selectAll() { select_all= true; }
+ void selectGood() { select_all= false; }
+
+#//!\name IO
+ // Not same as QhullFacetList#IO. A QhullFacetSet is a component of a QhullFacetList.
+
+ struct PrintFacetSet{
+ const QhullFacetSet *facet_set;
+ const char * print_message; //!< non-null message
+ PrintFacetSet(const char *message, const QhullFacetSet *s) : facet_set(s), print_message(message) {}
+ };//PrintFacetSet
+ const PrintFacetSet print(const char *message) const { return PrintFacetSet(message, this); }
+
+ struct PrintIdentifiers{
+ const QhullFacetSet *facet_set;
+ const char * print_message; //!< non-null message
+ PrintIdentifiers(const char *message, const QhullFacetSet *s) : facet_set(s), print_message(message) {}
+ };//PrintIdentifiers
+ PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
+
+};//class QhullFacetSet
+
+}//namespace orgQhull
+
+#//!\name == Global namespace =========================================
+
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet &fs);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet::PrintFacetSet &pr);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullFacetSet::PrintIdentifiers &p);
+
+#endif // QHULLFACETSET_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullHyperplane.cpp b/xs/src/qhull/src/libqhullcpp/QhullHyperplane.cpp
new file mode 100644
index 000000000..ed5cc4bae
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullHyperplane.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullHyperplane.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#include "libqhullcpp/QhullHyperplane.h"
+
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/QhullPoint.h"
+
+#include <iostream>
+
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#endif
+
+namespace orgQhull {
+
+#//!\name Constructors
+
+QhullHyperplane::
+QhullHyperplane(const Qhull &q)
+: hyperplane_coordinates(0)
+, qh_qh(q.qh())
+, hyperplane_offset(0.0)
+, hyperplane_dimension(0)
+{
+}
+
+QhullHyperplane::
+QhullHyperplane(const Qhull &q, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset)
+: hyperplane_coordinates(c)
+, qh_qh(q.qh())
+, hyperplane_offset(hyperplaneOffset)
+, hyperplane_dimension(hyperplaneDimension)
+{
+}
+
+#//!\name Conversions
+
+// See qt-qhull.cpp for QList conversions
+
+#ifndef QHULL_NO_STL
+std::vector<coordT> QhullHyperplane::
+toStdVector() const
+{
+ QhullHyperplaneIterator i(*this);
+ std::vector<coordT> fs;
+ while(i.hasNext()){
+ fs.push_back(i.next());
+ }
+ fs.push_back(hyperplane_offset);
+ return fs;
+}//toStdVector
+#endif //QHULL_NO_STL
+
+#//!\name GetSet
+
+//! Return true if equal
+//! If qh_qh defined, tests qh.distanceEpsilon and qh.angleEpsilon
+//! otherwise, tests equal coordinates and offset
+bool QhullHyperplane::
+operator==(const QhullHyperplane &other) const
+{
+ if(hyperplane_dimension!=other.hyperplane_dimension || !hyperplane_coordinates || !other.hyperplane_coordinates){
+ return false;
+ }
+ double d= fabs(hyperplane_offset-other.hyperplane_offset);
+ if(d > (qh_qh ? qh_qh->distanceEpsilon() : 0.0)){
+ return false;
+ }
+ double angle= hyperplaneAngle(other);
+
+ double a= fabs(angle-1.0);
+ if(a > (qh_qh ? qh_qh->angleEpsilon() : 0.0)){
+ return false;
+ }
+ return true;
+}//operator==
+
+#//!\name Methods
+
+//! Return distance from point to hyperplane.
+//! If greater than zero, the point is above the facet (i.e., outside).
+// qh_distplane [geom_r.c], QhullFacet::distance, and QhullHyperplane::distance are copies
+// Does not support RANDOMdist or logging
+double QhullHyperplane::
+distance(const QhullPoint &p) const
+{
+ const coordT *point= p.coordinates();
+ int dim= p.dimension();
+ QHULL_ASSERT(dim==dimension());
+ const coordT *normal= coordinates();
+ double dist;
+
+ switch (dim){
+ case 2:
+ dist= offset() + point[0] * normal[0] + point[1] * normal[1];
+ break;
+ case 3:
+ dist= offset() + point[0] * normal[0] + point[1] * normal[1] + point[2] * normal[2];
+ break;
+ case 4:
+ dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3];
+ break;
+ case 5:
+ dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4];
+ break;
+ case 6:
+ dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5];
+ break;
+ case 7:
+ dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6];
+ break;
+ case 8:
+ dist= offset()+point[0]*normal[0]+point[1]*normal[1]+point[2]*normal[2]+point[3]*normal[3]+point[4]*normal[4]+point[5]*normal[5]+point[6]*normal[6]+point[7]*normal[7];
+ break;
+ default:
+ dist= offset();
+ for (int k=dim; k--; )
+ dist += *point++ * *normal++;
+ break;
+ }
+ return dist;
+}//distance
+
+double QhullHyperplane::
+hyperplaneAngle(const QhullHyperplane &other) const
+{
+ volatile realT result= 0.0;
+ QH_TRY_(qh_qh){ // no object creation -- destructors skipped on longjmp()
+ result= qh_getangle(qh_qh, hyperplane_coordinates, other.hyperplane_coordinates);
+ }
+ qh_qh->NOerrexit= true;
+ qh_qh->maybeThrowQhullMessage(QH_TRY_status);
+ return result;
+}//hyperplaneAngle
+
+double QhullHyperplane::
+norm() const {
+ double d= 0.0;
+ const coordT *c= coordinates();
+ for (int k=dimension(); k--; ){
+ d += *c * *c;
+ ++c;
+ }
+ return sqrt(d);
+}//norm
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+using std::ostream;
+using orgQhull::QhullHyperplane;
+
+#//!\name GetSet<<
+
+ostream &
+operator<<(ostream &os, const QhullHyperplane &p)
+{
+ os << p.print("");
+ return os;
+}
+
+ostream &
+operator<<(ostream &os, const QhullHyperplane::PrintHyperplane &pr)
+{
+ os << pr.print_message;
+ QhullHyperplane p= *pr.hyperplane;
+ const realT *c= p.coordinates();
+ for(int k=p.dimension(); k--; ){
+ realT r= *c++;
+ if(pr.print_message){
+ os << " " << r; // FIXUP QH11010 %8.4g
+ }else{
+ os << " " << r; // FIXUP QH11010 qh_REAL_1
+ }
+ }
+ os << pr.hyperplane_offset_message << " " << p.offset();
+ os << std::endl;
+ return os;
+}//PrintHyperplane
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullHyperplane.h b/xs/src/qhull/src/libqhullcpp/QhullHyperplane.h
new file mode 100644
index 000000000..2868ce5c9
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullHyperplane.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullHyperplane.h#4 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHHYPERPLANE_H
+#define QHHYPERPLANE_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullIterator.h"
+#include "libqhullcpp/QhullQh.h"
+
+#include <ostream>
+
+namespace orgQhull {
+
+#//!\name Used here
+ class Qhull;
+ class QhullPoint;
+
+#//!\name Defined here
+ //! QhullHyperplane as an offset, dimension, and pointer to coordinates
+ class QhullHyperplane;
+ //! Java-style iterator for QhullHyperplane coordinates
+ class QhullHyperplaneIterator;
+
+class QhullHyperplane { // Similar to QhullPoint
+public:
+#//!\name Subtypes
+ typedef const coordT * iterator;
+ typedef const coordT * const_iterator;
+ typedef QhullHyperplane::iterator Iterator;
+ typedef QhullHyperplane::const_iterator ConstIterator;
+
+private:
+#//!\name Fields
+ coordT * hyperplane_coordinates; //!< Normal to hyperplane. facetT.normal is normalized to 1.0
+ QhullQh * qh_qh; //!< qhT for distanceEpsilon() in operator==
+ coordT hyperplane_offset; //!< Distance from hyperplane to origin
+ int hyperplane_dimension; //!< Dimension of hyperplane
+
+#//!\name Construct
+public:
+ QhullHyperplane() : hyperplane_coordinates(0), qh_qh(0), hyperplane_offset(0.0), hyperplane_dimension(0) {}
+ explicit QhullHyperplane(const Qhull &q);
+ QhullHyperplane(const Qhull &q, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset);
+ explicit QhullHyperplane(QhullQh *qqh) : hyperplane_coordinates(0), qh_qh(qqh), hyperplane_offset(0.0), hyperplane_dimension(0) {}
+ QhullHyperplane(QhullQh *qqh, int hyperplaneDimension, coordT *c, coordT hyperplaneOffset) : hyperplane_coordinates(c), qh_qh(qqh), hyperplane_offset(hyperplaneOffset), hyperplane_dimension(hyperplaneDimension) {}
+ // Creates an alias. Does not copy the hyperplane's coordinates. Needed for return by value and parameter passing.
+ QhullHyperplane(const QhullHyperplane &other) : hyperplane_coordinates(other.hyperplane_coordinates), qh_qh(other.qh_qh), hyperplane_offset(other.hyperplane_offset), hyperplane_dimension(other.hyperplane_dimension) {}
+ // Creates an alias. Does not copy the hyperplane's coordinates. Needed for vector<QhullHyperplane>
+ QhullHyperplane & operator=(const QhullHyperplane &other) { hyperplane_coordinates= other.hyperplane_coordinates; qh_qh= other.qh_qh; hyperplane_offset= other.hyperplane_offset; hyperplane_dimension= other.hyperplane_dimension; return *this; }
+ ~QhullHyperplane() {}
+
+#//!\name Conversions --
+//! Includes offset at end
+#ifndef QHULL_NO_STL
+ std::vector<coordT> toStdVector() const;
+#endif //QHULL_NO_STL
+#ifdef QHULL_USES_QT
+ QList<coordT> toQList() const;
+#endif //QHULL_USES_QT
+
+#//!\name GetSet
+public:
+ const coordT * coordinates() const { return hyperplane_coordinates; }
+ coordT * coordinates() { return hyperplane_coordinates; }
+ void defineAs(int hyperplaneDimension, coordT *c, coordT hyperplaneOffset) { QHULL_ASSERT(hyperplaneDimension>=0); hyperplane_coordinates= c; hyperplane_dimension= hyperplaneDimension; hyperplane_offset= hyperplaneOffset; }
+ //! Creates an alias to other using the same qh_qh
+ void defineAs(QhullHyperplane &other) { hyperplane_coordinates= other.coordinates(); hyperplane_dimension= other.dimension(); hyperplane_offset= other.offset(); }
+ int dimension() const { return hyperplane_dimension; }
+ bool isValid() const { return hyperplane_coordinates!=0 && hyperplane_dimension>0; }
+ coordT offset() const { return hyperplane_offset; }
+ bool operator==(const QhullHyperplane &other) const;
+ bool operator!=(const QhullHyperplane &other) const { return !operator==(other); }
+ const coordT & operator[](int idx) const { QHULL_ASSERT(idx>=0 && idx<hyperplane_dimension); return *(hyperplane_coordinates+idx); }
+ coordT & operator[](int idx) { QHULL_ASSERT(idx>=0 && idx<hyperplane_dimension); return *(hyperplane_coordinates+idx); }
+ void setCoordinates(coordT *c) { hyperplane_coordinates= c; }
+ void setDimension(int hyperplaneDimension) { hyperplane_dimension= hyperplaneDimension; }
+ void setOffset(coordT hyperplaneOffset) { hyperplane_offset= hyperplaneOffset; }
+
+#//!\name iterator
+ iterator begin() { return hyperplane_coordinates; }
+ const_iterator begin() const { return hyperplane_coordinates; }
+ const_iterator constBegin() const { return hyperplane_coordinates; }
+ const_iterator constEnd() const { return hyperplane_coordinates+hyperplane_dimension; }
+ int count() { return hyperplane_dimension; }
+ iterator end() { return hyperplane_coordinates+hyperplane_dimension; }
+ const_iterator end() const { return hyperplane_coordinates+hyperplane_dimension; }
+ size_t size() { return (size_t)hyperplane_dimension; }
+
+#//!\name Methods
+ double distance(const QhullPoint &p) const;
+ double hyperplaneAngle(const QhullHyperplane &other) const;
+ double norm() const;
+
+#//!\name IO
+ struct PrintHyperplane{
+ const QhullHyperplane *hyperplane;
+ const char * print_message; //!< non-null message
+ const char * hyperplane_offset_message; //!< non-null message
+ PrintHyperplane(const char *message, const char *offsetMessage, const QhullHyperplane &p) : hyperplane(&p), print_message(message), hyperplane_offset_message(offsetMessage) {}
+ };//PrintHyperplane
+ PrintHyperplane print(const char *message) const { return PrintHyperplane(message, "", *this); }
+ PrintHyperplane print(const char *message, const char *offsetMessage) const { return PrintHyperplane(message, offsetMessage, *this); }
+
+};//QhullHyperplane
+
+QHULL_DECLARE_SEQUENTIAL_ITERATOR(QhullHyperplane, coordT)
+
+}//namespace orgQhull
+
+#//!\name Global
+
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane::PrintHyperplane &pr);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullHyperplane &p);
+
+#endif // QHHYPERPLANE_H
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullIterator.h b/xs/src/qhull/src/libqhullcpp/QhullIterator.h
new file mode 100644
index 000000000..ec60496bf
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullIterator.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullIterator.h#4 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLITERATOR_H
+#define QHULLITERATOR_H
+
+#include "libqhull_r/qhull_ra.h"
+
+#include <assert.h>
+#include <iterator>
+#include <string>
+#include <vector>
+
+namespace orgQhull {
+
+#//!\name Defined here
+ //! Only QHULL_DECLARE_SEQUENTIAL_ITERATOR is used in libqhullcpp. The others need further development
+ //! QHULL_DECLARE_SEQUENTIAL_ITERATOR(C) -- Declare a Java-style iterator
+ //! QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) -- Declare a mutable Java-style iterator
+ //! QHULL_DECLARE_SET_ITERATOR(C) -- Declare a set iterator
+ //! QHULL_DECLARE_MUTABLE_SET_ITERATOR(C) -- Declare a mutable set iterator
+ //! Derived from Qt/core/tools/qiterator.h and qset_r.h/FOREACHsetelement_()
+
+// Stores C* as done in Mutable... Assumes the container is not deleted.
+// C::const_iterator is an STL-style iterator that returns T&
+#define QHULL_DECLARE_SEQUENTIAL_ITERATOR(C, T) \
+ \
+ class C##Iterator \
+ { \
+ typedef C::const_iterator const_iterator; \
+ const C *c; \
+ const_iterator i; \
+ public: \
+ inline C##Iterator(const C &container) \
+ : c(&container), i(c->constBegin()) {} \
+ inline C##Iterator &operator=(const C &container) \
+ { c = &container; i = c->constBegin(); return *this; } \
+ inline void toFront() { i = c->constBegin(); } \
+ inline void toBack() { i = c->constEnd(); } \
+ inline bool hasNext() const { return i != c->constEnd(); } \
+ inline const T &next() { return *i++; } \
+ inline const T &peekNext() const { return *i; } \
+ inline bool hasPrevious() const { return i != c->constBegin(); } \
+ inline const T &previous() { return *--i; } \
+ inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \
+ inline bool findNext(const T &t) \
+ { while (i != c->constEnd()) if (*i++ == t) return true; return false; } \
+ inline bool findPrevious(const T &t) \
+ { while (i != c->constBegin()) if (*(--i) == t) return true; \
+ return false; } \
+ };//C##Iterator
+
+// Remove setShareable() from Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR
+// Uses QHULL_ASSERT (assert.h)
+// Duplicated in MutablePointIterator without insert or remove
+// Not used in libqhullcpp. See Coordinates.h
+#define QHULL_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C, T) \
+ class Mutable##C##Iterator \
+ { \
+ typedef C::iterator iterator; \
+ typedef C::const_iterator const_iterator; \
+ C *c; \
+ iterator i, n; \
+ inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
+ public: \
+ inline Mutable##C##Iterator(C &container) \
+ : c(&container) \
+ { i = c->begin(); n = c->end(); } \
+ inline ~Mutable##C##Iterator() \
+ {} \
+ inline Mutable##C##Iterator &operator=(C &container) \
+ { c = &container; \
+ i = c->begin(); n = c->end(); return *this; } \
+ inline void toFront() { i = c->begin(); n = c->end(); } \
+ inline void toBack() { i = c->end(); n = i; } \
+ inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
+ inline T &next() { n = i++; return *n; } \
+ inline T &peekNext() const { return *i; } \
+ inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
+ inline T &previous() { n = --i; return *n; } \
+ inline T &peekPrevious() const { iterator p = i; return *--p; } \
+ inline void remove() \
+ { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \
+ inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; } \
+ inline T &value() { QHULL_ASSERT(item_exists()); return *n; } \
+ inline const T &value() const { QHULL_ASSERT(item_exists()); return *n; } \
+ inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \
+ inline bool findNext(const T &t) \
+ { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \
+ inline bool findPrevious(const T &t) \
+ { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \
+ n = c->end(); return false; } \
+ };//Mutable##C##Iterator
+
+// Not used in libqhullcpp.
+#define QHULL_DECLARE_SET_ITERATOR(C) \
+\
+ template <class T> \
+ class Qhull##C##Iterator \
+ { \
+ typedef typename Qhull##C<T>::const_iterator const_iterator; \
+ Qhull##C<T> c; \
+ const_iterator i; \
+ public: \
+ inline Qhull##C##Iterator(const Qhull##C<T> &container) \
+ : c(container), i(c.constBegin()) {} \
+ inline Qhull##C##Iterator &operator=(const Qhull##C<T> &container) \
+ { c = container; i = c.constBegin(); return *this; } \
+ inline void toFront() { i = c.constBegin(); } \
+ inline void toBack() { i = c.constEnd(); } \
+ inline bool hasNext() const { return i != c.constEnd(); } \
+ inline const T &next() { return *i++; } \
+ inline const T &peekNext() const { return *i; } \
+ inline bool hasPrevious() const { return i != c.constBegin(); } \
+ inline const T &previous() { return *--i; } \
+ inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \
+ inline bool findNext(const T &t) \
+ { while (i != c.constEnd()) if (*i++ == t) return true; return false; } \
+ inline bool findPrevious(const T &t) \
+ { while (i != c.constBegin()) if (*(--i) == t) return true; \
+ return false; } \
+ };//Qhull##C##Iterator
+
+// Not used in libqhullcpp.
+#define QHULL_DECLARE_MUTABLE_SET_ITERATOR(C) \
+\
+template <class T> \
+class QhullMutable##C##Iterator \
+{ \
+ typedef typename Qhull##C::iterator iterator; \
+ typedef typename Qhull##C::const_iterator const_iterator; \
+ Qhull##C *c; \
+ iterator i, n; \
+ inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
+public: \
+ inline Mutable##C##Iterator(Qhull##C &container) \
+ : c(&container) \
+ { c->setSharable(false); i = c->begin(); n = c->end(); } \
+ inline ~Mutable##C##Iterator() \
+ { c->setSharable(true); } \
+ inline Mutable##C##Iterator &operator=(Qhull##C &container) \
+ { c->setSharable(true); c = &container; c->setSharable(false); \
+ i = c->begin(); n = c->end(); return *this; } \
+ inline void toFront() { i = c->begin(); n = c->end(); } \
+ inline void toBack() { i = c->end(); n = i; } \
+ inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
+ inline T &next() { n = i++; return *n; } \
+ inline T &peekNext() const { return *i; } \
+ inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
+ inline T &previous() { n = --i; return *n; } \
+ inline T &peekPrevious() const { iterator p = i; return *--p; } \
+ inline void remove() \
+ { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \
+ inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; } \
+ inline T &value() { Q_ASSERT(item_exists()); return *n; } \
+ inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
+ inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \
+ inline bool findNext(const T &t) \
+ { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \
+ inline bool findPrevious(const T &t) \
+ { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \
+ n = c->end(); return false; } \
+};//QhullMutable##C##Iterator
+
+}//namespace orgQhull
+
+#endif // QHULLITERATOR_H
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullLinkedList.h b/xs/src/qhull/src/libqhullcpp/QhullLinkedList.h
new file mode 100644
index 000000000..d4caf52c1
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullLinkedList.h
@@ -0,0 +1,388 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullLinkedList.h#7 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLLINKEDLIST_H
+#define QHULLLINKEDLIST_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullError.h"
+
+#include <cstddef> // ptrdiff_t, size_t
+
+#ifdef QHULL_USES_QT
+#include <QtCore/QList>
+#endif
+
+#ifndef QHULL_NO_STL
+#include <algorithm>
+#include <iterator>
+#include <vector>
+#endif
+
+namespace orgQhull {
+
+#//!\name Defined here
+ //! QhullLinkedList<T> -- A linked list modeled on QLinkedList.
+ //! T is an opaque type with T(B *b), b=t.getBaseT(), t=t.next(), and t=t.prev(). The end node is a sentinel.
+ //! QhullQh/qhT owns the contents.
+ //! QhullLinkedList does not define erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList()
+ //! Derived from Qt/core/tools/qlinkedlist.h and libqhull_r.h/FORALLfacets_()
+ //! QhullLinkedList<T>::const_iterator -- STL-style iterator
+ //! QhullLinkedList<T>::iterator -- STL-style iterator
+ //! QhullLinkedListIterator<T> -- Java-style iterator
+ //! Derived from Qt/core/tools/qiterator.h
+ //! Works with Qt's foreach keyword [Qt/src/corelib/global/qglobal.h]
+
+template <typename T>
+class QhullLinkedList
+{
+#//!\name Defined here
+public:
+ class const_iterator;
+ class iterator;
+ typedef const_iterator ConstIterator;
+ typedef iterator Iterator;
+ typedef ptrdiff_t difference_type;
+ typedef countT size_type;
+ typedef T value_type;
+ typedef const value_type *const_pointer;
+ typedef const value_type &const_reference;
+ typedef value_type *pointer;
+ typedef value_type &reference;
+
+#//!\name Fields
+private:
+ T begin_node;
+ T end_node; //! Sentinel node at end of list
+
+#//!\name Constructors
+public:
+ QhullLinkedList<T>(T b, T e) : begin_node(b), end_node(e) {}
+ //! Copy constructor copies begin_node and end_node, but not the list elements. Needed for return by value and parameter passing.
+ QhullLinkedList<T>(const QhullLinkedList<T> &other) : begin_node(other.begin_node), end_node(other.end_node) {}
+ //! Copy assignment copies begin_node and end_node, but not the list elements.
+ QhullLinkedList<T> & operator=(const QhullLinkedList<T> &other) { begin_node= other.begin_node; end_node= other.end_node; return *this; }
+ ~QhullLinkedList<T>() {}
+
+private:
+ //!disabled since a sentinel must be allocated as the private type
+ QhullLinkedList<T>() {}
+
+public:
+
+#//!\name Conversions
+#ifndef QHULL_NO_STL
+ std::vector<T> toStdVector() const;
+#endif
+#ifdef QHULL_USES_QT
+ QList<T> toQList() const;
+#endif
+
+#//!\name GetSet
+ countT count() const;
+ //count(t) under #//!\name Search
+ bool isEmpty() const { return (begin_node==end_node); }
+ bool operator==(const QhullLinkedList<T> &o) const;
+ bool operator!=(const QhullLinkedList<T> &o) const { return !operator==(o); }
+ size_t size() const { return count(); }
+
+#//!\name Element access
+ //! For back() and last(), return T instead of T& (T is computed)
+ const T back() const { return last(); }
+ T back() { return last(); }
+ const T & first() const { QHULL_ASSERT(!isEmpty()); return begin_node; }
+ T & first() { QHULL_ASSERT(!isEmpty()); return begin_node; }
+ const T & front() const { return first(); }
+ T & front() { return first(); }
+ const T last() const { QHULL_ASSERT(!isEmpty()); return *--end(); }
+ T last() { QHULL_ASSERT(!isEmpty()); return *--end(); }
+
+#//!\name Modify -- Allocation of opaque types not implemented.
+
+#//!\name Search
+ bool contains(const T &t) const;
+ countT count(const T &t) const;
+
+#//!\name Iterator
+ iterator begin() { return begin_node; }
+ const_iterator begin() const { return begin_node; }
+ const_iterator constBegin() const { return begin_node; }
+ const_iterator constEnd() const { return end_node; }
+ iterator end() { return end_node; }
+ const_iterator end() const { return end_node; }
+
+ class iterator {
+
+ private:
+ T i;
+ friend class const_iterator;
+
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef T value_type;
+ typedef value_type *pointer;
+ typedef value_type &reference;
+ typedef ptrdiff_t difference_type;
+
+ iterator() : i() {}
+ iterator(const T &t) : i(t) {} //!< Automatic conversion to iterator
+ iterator(const iterator &o) : i(o.i) {}
+ iterator & operator=(const iterator &o) { i= o.i; return *this; }
+
+ const T & operator*() const { return i; }
+ T & operator*() { return i; }
+ // Do not define operator[]
+ const T * operator->() const { return &i; }
+ T * operator->() { return &i; }
+ bool operator==(const iterator &o) const { return i == o.i; }
+ bool operator!=(const iterator &o) const { return !operator==(o); }
+ bool operator==(const const_iterator &o) const { return i==reinterpret_cast<const iterator &>(o).i; }
+ bool operator!=(const const_iterator &o) const { return !operator==(o); }
+ iterator & operator++() { i= i.next(); return *this; }
+ iterator operator++(int) { iterator o= i; i= i.next(); return o; }
+ iterator & operator--() { i= i.previous(); return *this; }
+ iterator operator--(int) { iterator o= i; i= i.previous(); return o; }
+ iterator operator+(int j) const;
+ iterator operator-(int j) const { return operator+(-j); }
+ iterator & operator+=(int j) { return (*this= *this + j); }
+ iterator & operator-=(int j) { return (*this= *this - j); }
+ };//QhullLinkedList::iterator
+
+ class const_iterator {
+
+ private:
+ T i;
+
+ public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef T value_type;
+ typedef const value_type *pointer;
+ typedef const value_type &reference;
+ typedef ptrdiff_t difference_type;
+
+ const_iterator() : i() {}
+ const_iterator(const T &t) : i(t) {} //!< Automatic conversion to const_iterator
+ const_iterator(const iterator &o) : i(o.i) {}
+ const_iterator(const const_iterator &o) : i(o.i) {}
+ const_iterator &operator=(const const_iterator &o) { i= o.i; return *this; }
+
+ const T & operator*() const { return i; }
+ const T * operator->() const { return i; }
+ bool operator==(const const_iterator &o) const { return i == o.i; }
+ bool operator!=(const const_iterator &o) const { return !operator==(o); }
+ // No comparisons or iterator diff
+ const_iterator &operator++() { i= i.next(); return *this; }
+ const_iterator operator++(int) { const_iterator o= i; i= i.next(); return o; }
+ const_iterator &operator--() { i= i.previous(); return *this; }
+ const_iterator operator--(int) { const_iterator o= i; i= i.previous(); return o; }
+ const_iterator operator+(int j) const;
+ const_iterator operator-(int j) const { return operator+(-j); }
+ const_iterator &operator+=(int j) { return (*this= *this + j); }
+ const_iterator &operator-=(int j) { return (*this= *this - j); }
+ };//QhullLinkedList::const_iterator
+
+};//QhullLinkedList
+
+template <typename T>
+class QhullLinkedListIterator // FIXUP QH11016 define QhullMutableLinkedListIterator
+{
+ typedef typename QhullLinkedList<T>::const_iterator const_iterator;
+ const QhullLinkedList<T> *c;
+ const_iterator i;
+
+public:
+ QhullLinkedListIterator(const QhullLinkedList<T> &container) : c(&container), i(c->constBegin()) {}
+ QhullLinkedListIterator & operator=(const QhullLinkedList<T> &container) { c= &container; i= c->constBegin(); return *this; }
+ bool findNext(const T &t);
+ bool findPrevious(const T &t);
+ bool hasNext() const { return i != c->constEnd(); }
+ bool hasPrevious() const { return i != c->constBegin(); }
+ T next() { return *i++; }
+ T peekNext() const { return *i; }
+ T peekPrevious() const { const_iterator p= i; return *--p; }
+ T previous() { return *--i; }
+ void toFront() { i= c->constBegin(); }
+ void toBack() { i= c->constEnd(); }
+};//QhullLinkedListIterator
+
+#//!\name == Definitions =========================================
+
+#//!\name Conversion
+
+#ifndef QHULL_NO_STL
+template <typename T>
+std::vector<T> QhullLinkedList<T>::
+toStdVector() const
+{
+ std::vector<T> tmp;
+ std::copy(constBegin(), constEnd(), std::back_inserter(tmp));
+ return tmp;
+}//toStdVector
+#endif
+
+#ifdef QHULL_USES_QT
+template <typename T>
+QList<T> QhullLinkedList<T>::
+toQList() const
+{
+ QhullLinkedListIterator<T> i(*this);
+ QList<T> ls;
+ while(i.hasNext()){
+ ls.append(i.next());
+ }
+ return ls;
+}//toQList
+#endif
+
+#//!\name GetSet
+
+template <typename T>
+countT QhullLinkedList<T>::
+count() const
+{
+ const_iterator i= begin_node;
+ countT c= 0;
+ while(i != end_node){
+ c++;
+ i++;
+ }
+ return c;
+}//count
+
+#//!\name Search
+
+template <typename T>
+bool QhullLinkedList<T>::
+contains(const T &t) const
+{
+ const_iterator i= begin_node;
+ while(i != end_node){
+ if(i==t){
+ return true;
+ }
+ i++;
+ }
+ return false;
+}//contains
+
+template <typename T>
+countT QhullLinkedList<T>::
+count(const T &t) const
+{
+ const_iterator i= begin_node;
+ countT c= 0;
+ while(i != end_node){
+ if(i==t){
+ c++;
+ }
+ i++;
+ }
+ return c;
+}//count
+
+template <typename T>
+bool QhullLinkedList<T>::
+operator==(const QhullLinkedList<T> &l) const
+{
+ if(begin_node==l.begin_node){
+ return (end_node==l.end_node);
+ }
+ T i= begin_node;
+ T il= l.begin_node;
+ while(i != end_node){
+ if(i != il){
+ return false;
+ }
+ i= static_cast<T>(i.next());
+ il= static_cast<T>(il.next());
+ }
+ if(il != l.end_node){
+ return false;
+ }
+ return true;
+}//operator==
+
+#//!\name Iterator
+
+template <typename T>
+typename QhullLinkedList<T>::iterator QhullLinkedList<T>::iterator::
+operator+(int j) const
+{
+ T n= i;
+ if(j>0){
+ while(j--){
+ n= n.next();
+ }
+ }else{
+ while(j++){
+ n= n.previous();
+ }
+ }
+ return iterator(n);
+}//operator+
+
+template <typename T>
+typename QhullLinkedList<T>::const_iterator QhullLinkedList<T>::const_iterator::
+operator+(int j) const
+{
+ T n= i;
+ if(j>0){
+ while(j--){
+ n= n.next();
+ }
+ }else{
+ while(j++){
+ n= n.previous();
+ }
+ }
+ return const_iterator(n);
+}//operator+
+
+#//!\name QhullLinkedListIterator
+
+template <typename T>
+bool QhullLinkedListIterator<T>::
+findNext(const T &t)
+{
+ while(i != c->constEnd()){
+ if (*i++ == t){
+ return true;
+ }
+ }
+ return false;
+}//findNext
+
+template <typename T>
+bool QhullLinkedListIterator<T>::
+findPrevious(const T &t)
+{
+ while(i!=c->constBegin()){
+ if(*(--i)==t){
+ return true;
+ }
+ }
+ return false;
+}//findNext
+
+}//namespace orgQhull
+
+#//!\name Global
+
+template <typename T>
+std::ostream &
+operator<<(std::ostream &os, const orgQhull::QhullLinkedList<T> &qs)
+{
+ typename orgQhull::QhullLinkedList<T>::const_iterator i;
+ for(i= qs.begin(); i != qs.end(); ++i){
+ os << *i;
+ }
+ return os;
+}//operator<<
+
+#endif // QHULLLINKEDLIST_H
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullPoint.cpp b/xs/src/qhull/src/libqhullcpp/QhullPoint.cpp
new file mode 100644
index 000000000..f5e912460
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullPoint.cpp
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullPoint.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#include "libqhullcpp/QhullPoint.h"
+
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/Qhull.h"
+
+#include <iostream>
+#include <algorithm>
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#endif
+
+namespace orgQhull {
+
+#//!\name Constructors
+
+
+QhullPoint::
+QhullPoint(const Qhull &q)
+: point_coordinates(0)
+, qh_qh(q.qh())
+, point_dimension(q.hullDimension())
+{
+}//QhullPoint
+
+QhullPoint::
+QhullPoint(const Qhull &q, coordT *c)
+: point_coordinates(c)
+, qh_qh(q.qh())
+, point_dimension(q.hullDimension())
+{
+ QHULL_ASSERT(q.hullDimension()>0);
+}//QhullPoint dim, coordT
+
+QhullPoint::
+QhullPoint(const Qhull &q, int pointDimension, coordT *c)
+: point_coordinates(c)
+, qh_qh(q.qh())
+, point_dimension(pointDimension)
+{
+}//QhullPoint dim, coordT
+
+//! QhullPoint of Coordinates with point_dimension==c.count()
+QhullPoint::
+QhullPoint(const Qhull &q, Coordinates &c)
+: point_coordinates(c.data())
+, qh_qh(q.qh())
+, point_dimension(c.count())
+{
+}//QhullPoint Coordinates
+
+#//!\name Conversions
+
+// See qt-qhull.cpp for QList conversion
+
+#ifndef QHULL_NO_STL
+std::vector<coordT> QhullPoint::
+toStdVector() const
+{
+ QhullPointIterator i(*this);
+ std::vector<coordT> vs;
+ while(i.hasNext()){
+ vs.push_back(i.next());
+ }
+ return vs;
+}//toStdVector
+#endif //QHULL_NO_STL
+
+#//!\name GetSet
+
+//! QhullPoint is equal if it has the same address and dimension
+//! If !qh_qh, returns true if dimension and coordinates are equal
+//! If qh_qh, returns true if the distance between points is less than qh_qh->distanceEpsilon()
+//!\todo Compares distance with distance-to-hyperplane (distanceEpsilon). Is that correct?
+bool QhullPoint::
+operator==(const QhullPoint &other) const
+{
+ if(point_dimension!=other.point_dimension){
+ return false;
+ }
+ const coordT *c= point_coordinates;
+ const coordT *c2= other.point_coordinates;
+ if(c==c2){
+ return true;
+ }
+ if(!c || !c2){
+ return false;
+ }
+ if(!qh_qh || qh_qh->hull_dim==0){
+ for(int k= point_dimension; k--; ){
+ if(*c++ != *c2++){
+ return false;
+ }
+ }
+ return true;
+ }
+ double dist2= 0.0;
+ for(int k= point_dimension; k--; ){
+ double diff= *c++ - *c2++;
+ dist2 += diff*diff;
+ }
+ dist2= sqrt(dist2);
+ return (dist2 < qh_qh->distanceEpsilon());
+}//operator==
+
+#//!\name Methods
+
+//! Return distance between two points.
+double QhullPoint::
+distance(const QhullPoint &p) const
+{
+ const coordT *c= point_coordinates;
+ const coordT *c2= p.point_coordinates;
+ int dim= point_dimension;
+ if(dim!=p.point_dimension){
+ throw QhullError(10075, "QhullPoint error: Expecting dimension %d for distance(). Got %d", dim, p.point_dimension);
+ }
+ if(!c || !c2){
+ throw QhullError(10076, "QhullPoint error: Cannot compute distance() for undefined point");
+ }
+ double dist;
+
+ switch(dim){
+ case 2:
+ dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]);
+ break;
+ case 3:
+ dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]);
+ break;
+ case 4:
+ dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]);
+ break;
+ case 5:
+ dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]);
+ break;
+ case 6:
+ dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]);
+ break;
+ case 7:
+ dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]) + (c[6]-c2[6])*(c[6]-c2[6]);
+ break;
+ case 8:
+ dist= (c[0]-c2[0])*(c[0]-c2[0]) + (c[1]-c2[1])*(c[1]-c2[1]) + (c[2]-c2[2])*(c[2]-c2[2]) + (c[3]-c2[3])*(c[3]-c2[3]) + (c[4]-c2[4])*(c[4]-c2[4]) + (c[5]-c2[5])*(c[5]-c2[5]) + (c[6]-c2[6])*(c[6]-c2[6]) + (c[7]-c2[7])*(c[7]-c2[7]);
+ break;
+ default:
+ dist= 0.0;
+ for(int k=dim; k--; ){
+ dist += (*c - *c2) * (*c - *c2);
+ ++c;
+ ++c2;
+ }
+ break;
+ }
+ return sqrt(dist);
+}//distance
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+using std::ostream;
+using orgQhull::QhullPoint;
+
+//! Same as qh_printpointid [io.c]
+ostream &
+operator<<(ostream &os, const QhullPoint::PrintPoint &pr)
+{
+ QhullPoint p= *pr.point;
+ countT i= p.id();
+ if(pr.point_message){
+ if(*pr.point_message){
+ os << pr.point_message << " ";
+ }
+ if(pr.with_identifier && (i!=qh_IDunknown) && (i!=qh_IDnone)){
+ os << "p" << i << ": ";
+ }
+ }
+ const realT *c= p.coordinates();
+ for(int k=p.dimension(); k--; ){
+ realT r= *c++;
+ if(pr.point_message){
+ os << " " << r; // FIXUP QH11010 %8.4g
+ }else{
+ os << " " << r; // FIXUP QH11010 qh_REAL_1
+ }
+ }
+ os << std::endl;
+ return os;
+}//printPoint
+
+ostream &
+operator<<(ostream &os, const QhullPoint &p)
+{
+ os << p.print("");
+ return os;
+}//operator<<
diff --git a/xs/src/qhull/src/libqhullcpp/QhullPoint.h b/xs/src/qhull/src/libqhullcpp/QhullPoint.h
new file mode 100644
index 000000000..17f94ab36
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullPoint.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullPoint.h#4 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHPOINT_H
+#define QHPOINT_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullIterator.h"
+#include "libqhullcpp/QhullQh.h"
+#include "libqhullcpp/Coordinates.h"
+
+#include <ostream>
+
+namespace orgQhull {
+
+#//!\name Defined here
+ class QhullPoint; //!< QhullPoint as a pointer and dimension to shared memory
+ class QhullPointIterator; //!< Java-style iterator for QhullPoint coordinates
+
+#//!\name Used here
+ class Qhull;
+
+//! A QhullPoint is a dimension and an array of coordinates.
+//! With Qhull/QhullQh, a QhullPoint has an identifier. Point equality is relative to qh.distanceEpsilon
+class QhullPoint {
+
+#//!\name Iterators
+public:
+ typedef coordT * base_type; // for QhullPointSet
+ typedef const coordT * iterator;
+ typedef const coordT * const_iterator;
+ typedef QhullPoint::iterator Iterator;
+ typedef QhullPoint::const_iterator ConstIterator;
+
+#//!\name Fields
+protected: // For QhullPoints::iterator, QhullPoints::const_iterator
+ coordT * point_coordinates; //!< Pointer to first coordinate, 0 if undefined
+ QhullQh * qh_qh; //!< qhT for this instance of Qhull. 0 if undefined.
+ //!< operator==() returns true if points within sqrt(qh_qh->distanceEpsilon())
+ //!< If !qh_qh, id() is -3, and operator==() requires equal coordinates
+ int point_dimension; //!< Default dimension is qh_qh->hull_dim
+public:
+
+#//!\name Constructors
+ //! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
+ //! If Qhull/QhullQh is not initialized, then QhullPoint.dimension() is zero unless explicitly set
+ //! Cannot define QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh)
+ QhullPoint() : point_coordinates(0), qh_qh(0), point_dimension(0) {}
+ QhullPoint(int pointDimension, coordT *c) : point_coordinates(c), qh_qh(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>0); }
+ explicit QhullPoint(const Qhull &q);
+ QhullPoint(const Qhull &q, coordT *c);
+ QhullPoint(const Qhull &q, Coordinates &c);
+ QhullPoint(const Qhull &q, int pointDimension, coordT *c);
+ explicit QhullPoint(QhullQh *qqh) : point_coordinates(0), qh_qh(qqh), point_dimension(qqh->hull_dim) {}
+ QhullPoint(QhullQh *qqh, coordT *c) : point_coordinates(c), qh_qh(qqh), point_dimension(qqh->hull_dim) { QHULL_ASSERT(qqh->hull_dim>0); }
+ QhullPoint(QhullQh *qqh, Coordinates &c) : point_coordinates(c.data()), qh_qh(qqh), point_dimension(c.count()) {}
+ QhullPoint(QhullQh *qqh, int pointDimension, coordT *c) : point_coordinates(c), qh_qh(qqh), point_dimension(pointDimension) {}
+ //! Creates an alias. Does not make a deep copy of the point. Needed for return by value and parameter passing.
+ QhullPoint(const QhullPoint &other) : point_coordinates(other.point_coordinates), qh_qh(other.qh_qh), point_dimension(other.point_dimension) {}
+ //! Creates an alias. Does not make a deep copy of the point. Needed for vector<QhullPoint>
+ QhullPoint & operator=(const QhullPoint &other) { point_coordinates= other.point_coordinates; qh_qh= other.qh_qh; point_dimension= other.point_dimension; return *this; }
+ ~QhullPoint() {}
+
+
+#//!\name Conversions
+
+#ifndef QHULL_NO_STL
+ std::vector<coordT> toStdVector() const;
+#endif //QHULL_NO_STL
+#ifdef QHULL_USES_QT
+ QList<coordT> toQList() const;
+#endif //QHULL_USES_QT
+
+#//!\name GetSet
+public:
+ const coordT * coordinates() const { return point_coordinates; } //!< 0 if undefined
+ coordT * coordinates() { return point_coordinates; } //!< 0 if undefined
+ void defineAs(coordT *c) { QHULL_ASSERT(point_dimension>0); point_coordinates= c; }
+ void defineAs(int pointDimension, coordT *c) { QHULL_ASSERT(pointDimension>=0); point_coordinates= c; point_dimension= pointDimension; }
+ void defineAs(QhullPoint &other) { point_coordinates= other.point_coordinates; qh_qh= other.qh_qh; point_dimension= other.point_dimension; }
+ int dimension() const { return point_dimension; }
+ coordT * getBaseT() const { return point_coordinates; } // for QhullPointSet
+ countT id() const { return qh_pointid(qh_qh, point_coordinates); } // NOerrors
+ bool isValid() const { return (point_coordinates!=0 && point_dimension>0); };
+ bool operator==(const QhullPoint &other) const;
+ bool operator!=(const QhullPoint &other) const { return ! operator==(other); }
+ const coordT & operator[](int idx) const { QHULL_ASSERT(point_coordinates!=0 && idx>=0 && idx<point_dimension); return *(point_coordinates+idx); } //!< 0 to hull_dim-1
+ coordT & operator[](int idx) { QHULL_ASSERT(point_coordinates!=0 && idx>=0 && idx<point_dimension); return *(point_coordinates+idx); } //!< 0 to hull_dim-1
+ QhullQh * qh() { return qh_qh; }
+ void setCoordinates(coordT *c) { point_coordinates= c; }
+ void setDimension(int pointDimension) { point_dimension= pointDimension; }
+
+#//!\name foreach
+ iterator begin() { return point_coordinates; }
+ const_iterator begin() const { return point_coordinates; }
+ const_iterator constBegin() const { return point_coordinates; }
+ const_iterator constEnd() const { return (point_coordinates ? point_coordinates+point_dimension : 0); }
+ int count() { return (point_coordinates ? point_dimension : 0); }
+ iterator end() { return (point_coordinates ? point_coordinates+point_dimension : 0); }
+ const_iterator end() const { return (point_coordinates ? point_coordinates+point_dimension : 0); }
+ size_t size() { return (size_t)(point_coordinates ? point_dimension : 0); }
+
+#//!\name Methods
+ void advancePoint(countT idx) { if(point_coordinates) { point_coordinates += idx*point_dimension; } }
+ double distance(const QhullPoint &p) const;
+
+#//!\name IO
+
+ struct PrintPoint{
+ const QhullPoint *point;
+ const char * point_message;
+ bool with_identifier;
+ PrintPoint(const char *message, bool withIdentifier, const QhullPoint &p) : point(&p), point_message(message), with_identifier(withIdentifier) {}
+ };//PrintPoint
+ PrintPoint print(const char *message) const { return PrintPoint(message, false, *this); }
+ PrintPoint printWithIdentifier(const char *message) const { return PrintPoint(message, true, *this); }
+
+};//QhullPoint
+
+QHULL_DECLARE_SEQUENTIAL_ITERATOR(QhullPoint, coordT)
+
+}//namespace orgQhull
+
+#//!\name Global
+
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint::PrintPoint &pr);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPoint &p);
+
+#endif // QHPOINT_H
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullPointSet.cpp b/xs/src/qhull/src/libqhullcpp/QhullPointSet.cpp
new file mode 100644
index 000000000..561fd6c76
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullPointSet.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullPointSet.cpp#2 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#include "libqhullcpp/QhullPointSet.h"
+
+#include <iostream>
+#include <algorithm>
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#endif
+
+namespace orgQhull {
+
+// Implemented via QhullSet.h
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+using std::endl;
+using std::ostream;
+using orgQhull::QhullPoint;
+using orgQhull::QhullPointSet;
+using orgQhull::QhullPointSetIterator;
+
+ostream &
+operator<<(ostream &os, const QhullPointSet::PrintIdentifiers &pr)
+{
+ os << pr.print_message;
+ const QhullPointSet s= *pr.point_set;
+ QhullPointSetIterator i(s);
+ while(i.hasNext()){
+ if(i.hasPrevious()){
+ os << " ";
+ }
+ const QhullPoint point= i.next();
+ countT id= point.id();
+ os << "p" << id;
+
+ }
+ os << endl;
+ return os;
+}//PrintIdentifiers
+
+ostream &
+operator<<(ostream &os, const QhullPointSet::PrintPointSet &pr)
+{
+ os << pr.print_message;
+ const QhullPointSet s= *pr.point_set;
+ for(QhullPointSet::const_iterator i=s.begin(); i != s.end(); ++i){
+ const QhullPoint point= *i;
+ os << point;
+ }
+ return os;
+}//printPointSet
+
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullPointSet.h b/xs/src/qhull/src/libqhullcpp/QhullPointSet.h
new file mode 100644
index 000000000..8562e170e
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullPointSet.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullPointSet.h#4 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLPOINTSET_H
+#define QHULLPOINTSET_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullSet.h"
+#include "libqhullcpp/QhullPoint.h"
+
+#include <ostream>
+
+namespace orgQhull {
+
+#//!\name Used here
+ class Qhull;
+ class QhullPoint;
+
+#//!\name Defined here
+ //! QhullPointSet -- a set of coordinate pointers with input dimension
+ // with const_iterator and iterator
+ class QhullPointSet;
+
+class QhullPointSet : public QhullSet<QhullPoint> {
+
+private:
+#//!\name Fields
+ // no fields
+public:
+
+#//!\name Construct
+ QhullPointSet(const Qhull &q, setT *s) : QhullSet<QhullPoint>(q, s) {}
+ //Conversion from setT* is not type-safe. Implicit conversion for void* to T
+ QhullPointSet(QhullQh *qqh, setT *s) : QhullSet<QhullPoint>(qqh, s) {}
+ //Copy constructor copies pointer but not contents. Needed for return by value and parameter passing.
+ QhullPointSet(const QhullPointSet &other) : QhullSet<QhullPoint>(other) {}
+ //!Assignment copies pointers but not contents.
+ QhullPointSet & operator=(const QhullPointSet &other) { QhullSet<QhullPoint>::operator=(other); return *this; }
+ ~QhullPointSet() {}
+
+ //!Default constructor disabled.
+private:
+ QhullPointSet();
+public:
+
+#//!\name IO
+ struct PrintIdentifiers{
+ const QhullPointSet *point_set;
+ const char * print_message; //!< non-null message
+ PrintIdentifiers(const char *message, const QhullPointSet *s) : point_set(s), print_message(message) {}
+ };//PrintIdentifiers
+ PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
+
+ struct PrintPointSet{
+ const QhullPointSet *point_set;
+ const char * print_message; //!< non-null message
+ PrintPointSet(const char *message, const QhullPointSet &s) : point_set(&s), print_message(message) {}
+ };//PrintPointSet
+ PrintPointSet print(const char *message) const { return PrintPointSet(message, *this); }
+
+};//QhullPointSet
+
+typedef QhullSetIterator<QhullPoint> QhullPointSetIterator;
+
+}//namespace orgQhull
+
+#//!\name Global
+
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPointSet::PrintIdentifiers &pr);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullPointSet::PrintPointSet &pr);
+
+#endif // QHULLPOINTSET_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullPoints.cpp b/xs/src/qhull/src/libqhullcpp/QhullPoints.cpp
new file mode 100644
index 000000000..2320b5007
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullPoints.cpp
@@ -0,0 +1,320 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullPoints.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#include "libqhullcpp/QhullPoints.h"
+
+#include "libqhullcpp/Qhull.h"
+
+#include <iostream>
+
+#ifndef QHULL_NO_STL
+#include <vector>
+#endif
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#endif
+
+namespace orgQhull {
+
+#//!\name Constructors
+
+QhullPoints::
+QhullPoints(const Qhull &q)
+: point_first(0)
+, point_end(0)
+, qh_qh(q.qh())
+, point_dimension(q.hullDimension())
+{
+}//QhullPoints Qhull
+
+QhullPoints::
+QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c)
+: point_first(c)
+, point_end(c+coordinateCount2)
+, qh_qh(q.qh())
+, point_dimension(q.hullDimension())
+{
+ QHULL_ASSERT(q.hullDimension());
+ QHULL_ASSERT(coordinateCount2>=0);
+}//QhullPoints Qhull dim
+
+QhullPoints::
+QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c)
+: point_first(c)
+, point_end(c+coordinateCount2)
+, qh_qh(q.qh())
+, point_dimension(pointDimension)
+{
+ QHULL_ASSERT(pointDimension>=0);
+ QHULL_ASSERT(coordinateCount2>=0);
+}//QhullPoints Qhull dim coordT
+
+QhullPoints::
+QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c)
+: point_first(c)
+, point_end(c+coordinateCount2)
+, qh_qh(qqh)
+, point_dimension(pointDimension)
+{
+ QHULL_ASSERT(pointDimension>=0);
+ QHULL_ASSERT(coordinateCount2>=0);
+}//QhullPoints QhullQh dim coordT
+
+#//!\name Conversions
+// See qt-qhull.cpp for QList conversion
+
+#ifndef QHULL_NO_STL
+std::vector<QhullPoint> QhullPoints::
+toStdVector() const
+{
+ QhullPointsIterator i(*this);
+ std::vector<QhullPoint> vs;
+ while(i.hasNext()){
+ vs.push_back(i.next());
+ }
+ return vs;
+}//toStdVector
+#endif //QHULL_NO_STL
+
+#//!\name GetSet
+
+countT QhullPoints::
+extraCoordinatesCount() const
+{
+ if(point_dimension>0){
+ return (countT)((point_end-point_first)%(size_t)point_dimension);
+ }
+ return 0;
+}//extraCoordinatesCount
+
+//! QhullPoints is equal if the same address, or if the coordinates are identical
+//! Use QhullPoint.operator==() for DISTround equality
+bool QhullPoints::
+operator==(const QhullPoints &other) const
+{
+ if((point_end-point_first) != (other.point_end-other.point_first)){
+ return false;
+ }
+ if(point_dimension!=other.point_dimension){
+ return false;
+ }
+ if(point_first==other.point_first){
+ return true;
+ }
+ if(!qh_qh || qh_qh->hull_dim==0){
+ const coordT *c= point_first;
+ const coordT *c2= other.point_first;
+ while(c<point_end){
+ if(*c++!=*c2++){
+ return false;
+ }
+ }
+ }else{
+ const_iterator i= begin();
+ const_iterator i2= other.begin();
+ while(i<end()){
+ if(*i++!=*i2++){
+ return false;
+ }
+ }
+ }
+ return true;
+}//operator==
+
+//! Reset QhullPoints to QhullQh and its hullDimension()
+//! Does not free up old qh_qh
+void QhullPoints::
+resetQhullQh(QhullQh *qqh)
+{
+ qh_qh= qqh;
+ point_dimension= (qqh ? qqh->hull_dim : 0);
+ point_first= 0;
+ point_end= 0;
+}//resetQhullQh
+
+QhullPoint QhullPoints::
+value(countT idx) const
+{
+ QhullPoint p(qh_qh);
+ if(idx>=0 && idx<count()){
+ p.defineAs(point_dimension, point_first+idx*point_dimension);
+ }
+ return p;
+}//value
+
+QhullPoint QhullPoints::
+value(countT idx, QhullPoint &defaultValue) const
+{
+ QhullPoint p(qh_qh);
+ if(idx>=0 && idx<count()){
+ p.defineAs(point_dimension, point_first+idx*point_dimension);
+ }else{
+ p.defineAs(defaultValue);
+ }
+ return p;
+}//value
+
+#//!\name Methods
+
+bool QhullPoints::
+contains(const QhullPoint &t) const
+{
+ const_iterator i= begin();
+ while(i != end()){
+ if(*i==t){
+ return true;
+ }
+ i++;
+ }
+ return false;
+}//contains
+
+countT QhullPoints::
+count(const QhullPoint &t) const
+{
+ countT n= 0;
+ const_iterator i= begin();
+ while(i != end()){
+ if(*i==t){
+ ++n;
+ }
+ i++;
+ }
+ return n;
+}//count
+
+countT QhullPoints::
+indexOf(const coordT *pointCoordinates) const
+{
+ if(!includesCoordinates(pointCoordinates) || point_dimension==0){
+ return -1;
+ }
+ size_t offset= pointCoordinates-point_first;
+ countT idx= (countT)(offset/(size_t)point_dimension);
+ countT extra= (countT)(offset%(size_t)point_dimension);
+ if(extra!=0){
+ throw QhullError(10066, "Qhull error: coordinates %x are not at point boundary (extra %d at index %d)", extra, idx, 0.0, pointCoordinates);
+ }
+ return idx;
+}//indexOf coordT
+
+countT QhullPoints::
+indexOf(const coordT *pointCoordinates, int noThrow) const
+{
+ size_t extra= 0;
+ if(noThrow){
+ if(!includesCoordinates(pointCoordinates) || point_dimension==0){
+ return -1;
+ }
+ extra= (pointCoordinates-point_first)%(size_t)point_dimension;
+ }
+ return indexOf(pointCoordinates-extra);
+}//indexOf coordT noThrow
+
+countT QhullPoints::
+indexOf(const QhullPoint &t) const
+{
+ countT j=0;
+ const_iterator i= begin();
+ while(i!=end()){
+ if(*i==t){
+ return j;
+ }
+ ++i;
+ ++j;
+ }
+ return -1;
+}//indexOf
+
+countT QhullPoints::
+lastIndexOf(const QhullPoint &t) const
+{
+ countT j= count();
+ const_iterator i= end();
+ while(i != begin()){
+ --i;
+ --j;
+ if(*i==t){
+ return j;
+ }
+ }
+ return -1;
+}//lastIndexOf
+
+QhullPoints QhullPoints::
+mid(countT idx, countT length) const
+{
+ countT n= count();
+ if(idx<0 || idx>=n){
+ n= 0;
+ }else if(length<0 || idx+length>=n){
+ n -= idx;
+ }else{
+ n -= idx+length;
+ }
+ return QhullPoints(qh_qh, point_dimension, n*point_dimension, point_first+idx*point_dimension);
+}//mid
+
+#//!\name QhullPointsIterator
+
+bool QhullPointsIterator::
+findNext(const QhullPoint &p)
+{
+ while(i!=ps->constEnd()){
+ if(*i++ == p){
+ return true;
+ }
+ }
+ return false;
+}//findNext
+
+bool QhullPointsIterator::
+findPrevious(const QhullPoint &p)
+{
+ while(i!=ps->constBegin()){
+ if(*--i == p){
+ return true;
+ }
+ }
+ return false;
+}//findPrevious
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+using std::ostream;
+using orgQhull::QhullPoint;
+using orgQhull::QhullPoints;
+using orgQhull::QhullPointsIterator;
+
+ostream &
+operator<<(ostream &os, const QhullPoints &p)
+{
+ QhullPointsIterator i(p);
+ while(i.hasNext()){
+ os << i.next();
+ }
+ return os;
+}//operator<<QhullPoints
+
+ostream &
+operator<<(ostream &os, const QhullPoints::PrintPoints &pr)
+{
+ os << pr.point_message;
+ QhullPoints ps= *pr.points;
+ for(QhullPoints::iterator i=ps.begin(); i!=ps.end(); ++i){
+ QhullPoint p= *i;
+ if(pr.with_identifier){
+ os << p.printWithIdentifier("");
+ }else{
+ os << p.print("");
+ }
+ }
+ return os;
+}//<<PrintPoints
diff --git a/xs/src/qhull/src/libqhullcpp/QhullPoints.h b/xs/src/qhull/src/libqhullcpp/QhullPoints.h
new file mode 100644
index 000000000..ce169a159
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullPoints.h
@@ -0,0 +1,266 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullPoints.h#5 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLPOINTS_H
+#define QHULLPOINTS_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullPoint.h"
+
+#include <cstddef> // ptrdiff_t, size_t
+#include <ostream>
+
+namespace orgQhull {
+
+#//!\name Defined here
+ class QhullPoints; //!< One or more points Coordinate pointers with dimension and iterators
+ class QhullPointsIterator; //!< Java-style iterator
+
+//! QhullPoints are an array of QhullPoint as pointers into an array of coordinates.
+//! For Qhull/QhullQh, QhullPoints must use hull_dim. Can change QhullPoint to input_dim if needed for Delaunay input site
+class QhullPoints {
+
+private:
+#//!\name Fields
+ coordT * point_first; //!< First coordinate of an array of points of point_dimension
+ coordT * point_end; //!< End of point coordinates (end>=first). Trailing coordinates ignored
+ QhullQh * qh_qh; //!< Maybe initialized NULL to allow ownership by RboxPoints
+ //!< qh_qh used for QhullPoint() and qh_qh->hull_dim in constructor
+ int point_dimension; //!< Dimension, >=0
+
+public:
+#//!\name Subtypes
+ class const_iterator;
+ class iterator;
+ typedef QhullPoints::const_iterator ConstIterator;
+ typedef QhullPoints::iterator Iterator;
+
+#//!\name Construct
+ //! QhullPoint, PointCoordinates, and QhullPoints have similar constructors
+ //! If Qhull/QhullQh is not initialized, then QhullPoints.dimension() is zero unless explicitly set
+ //! Cannot define QhullPoints(int pointDimension) since it is ambiguous with QhullPoints(QhullQh *qqh)
+ QhullPoints() : point_first(0), point_end(0), qh_qh(0), point_dimension(0) { }
+ QhullPoints(int pointDimension, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(0), point_dimension(pointDimension) { QHULL_ASSERT(pointDimension>=0); }
+ explicit QhullPoints(const Qhull &q);
+ QhullPoints(const Qhull &q, countT coordinateCount2, coordT *c);
+ QhullPoints(const Qhull &q, int pointDimension, countT coordinateCount2, coordT *c);
+ explicit QhullPoints(QhullQh *qqh) : point_first(0), point_end(0), qh_qh(qqh), point_dimension(qqh ? qqh->hull_dim : 0) { }
+ QhullPoints(QhullQh *qqh, countT coordinateCount2, coordT *c) : point_first(c), point_end(c+coordinateCount2), qh_qh(qqh), point_dimension(qqh ? qqh->hull_dim : 0) { QHULL_ASSERT(qqh && qqh->hull_dim>0); }
+ QhullPoints(QhullQh *qqh, int pointDimension, countT coordinateCount2, coordT *c);
+ //! Copy constructor copies pointers but not contents. Needed for return by value and parameter passing.
+ QhullPoints(const QhullPoints &other) : point_first(other.point_first), point_end(other.point_end), qh_qh(other.qh_qh), point_dimension(other.point_dimension) {}
+ QhullPoints & operator=(const QhullPoints &other) { point_first= other.point_first; point_end= other.point_end; qh_qh= other.qh_qh; point_dimension= other.point_dimension; return *this; }
+ ~QhullPoints() {}
+
+public:
+
+#//!\name Conversion
+
+#ifndef QHULL_NO_STL
+ std::vector<QhullPoint> toStdVector() const;
+#endif //QHULL_NO_STL
+#ifdef QHULL_USES_QT
+ QList<QhullPoint> toQList() const;
+#endif //QHULL_USES_QT
+
+#//!\name GetSet
+ // Constructs QhullPoint. Cannot return reference.
+ const QhullPoint at(countT idx) const { /* point_first==0 caught by point_end assert */ coordT *p= point_first+idx*point_dimension; QHULL_ASSERT(p<point_end); return QhullPoint(qh_qh, point_dimension, p); }
+ // Constructs QhullPoint. Cannot return reference.
+ const QhullPoint back() const { return last(); }
+ QhullPoint back() { return last(); }
+ ConstIterator begin() const { return ConstIterator(*this); }
+ Iterator begin() { return Iterator(*this); }
+ ConstIterator constBegin() const { return ConstIterator(*this); }
+ const coordT * constData() const { return point_first; }
+ ConstIterator constEnd() const { return ConstIterator(qh_qh, point_dimension, point_end); }
+ coordT * coordinates() const { return point_first; }
+ countT coordinateCount() const { return (countT)(point_end-point_first); } // WARN64
+ countT count() const { return (countT)size(); } // WARN64
+ const coordT * data() const { return point_first; }
+ coordT * data() { return point_first; }
+ void defineAs(int pointDimension, countT coordinatesCount, coordT *c) { QHULL_ASSERT(pointDimension>=0 && coordinatesCount>=0 && c!=0); point_first= c; point_end= c+coordinatesCount; point_dimension= pointDimension; }
+ void defineAs(countT coordinatesCount, coordT *c) { QHULL_ASSERT((point_dimension>0 && coordinatesCount>=0 && c!=0) || (c==0 && coordinatesCount==0)); point_first= c; point_end= c+coordinatesCount; }
+ void defineAs(const QhullPoints &other) { point_first= other.point_first; point_end= other.point_end; qh_qh= other.qh_qh; point_dimension= other.point_dimension; }
+ int dimension() const { return point_dimension; }
+ ConstIterator end() const { return ConstIterator(qh_qh, point_dimension, point_end); }
+ Iterator end() { return Iterator(qh_qh, point_dimension, point_end); }
+ coordT * extraCoordinates() const { return extraCoordinatesCount() ? (point_end-extraCoordinatesCount()) : 0; }
+ countT extraCoordinatesCount() const; // WARN64
+ // Constructs QhullPoint. Cannot return reference.
+ const QhullPoint first() const { return QhullPoint(qh_qh, point_dimension, point_first); }
+ QhullPoint first() { return QhullPoint(qh_qh, point_dimension, point_first); }
+ // Constructs QhullPoint. Cannot return reference.
+ const QhullPoint front() const { return first(); }
+ QhullPoint front() { return first(); }
+ bool includesCoordinates(const coordT *c) const { return c>=point_first && c<point_end; }
+ bool isEmpty() const { return (point_end==point_first || point_dimension==0); }
+ // Constructs QhullPoint. Cannot return reference.
+ const QhullPoint last() const { QHULL_ASSERT(point_first!=0); return QhullPoint(qh_qh, point_dimension, point_end - point_dimension); }
+ QhullPoint last() { QHULL_ASSERT(point_first!=0); return QhullPoint(qh_qh, point_dimension, point_end - point_dimension); }
+ bool operator==(const QhullPoints &other) const;
+ bool operator!=(const QhullPoints &other) const { return ! operator==(other); }
+ QhullPoint operator[](countT idx) const { return at(idx); }
+ QhullQh * qh() const { return qh_qh; }
+ void resetQhullQh(QhullQh *qqh);
+ void setDimension(int d) { point_dimension= d; }
+ size_t size() const { return point_dimension ? (point_end-point_first)/point_dimension : 0; }
+ QhullPoint value(countT idx) const;
+ QhullPoint value(countT idx, QhullPoint &defaultValue) const;
+
+#//!\name Methods
+ bool contains(const QhullPoint &t) const;
+ countT count(const QhullPoint &t) const;
+ countT indexOf(const coordT *pointCoordinates) const;
+ countT indexOf(const coordT *pointCoordinates, int noThrow) const;
+ countT indexOf(const QhullPoint &t) const;
+ countT lastIndexOf(const QhullPoint &t) const;
+ //! Returns a subset of the points, not a copy
+ QhullPoints mid(countT idx, countT length= -1) const;
+
+#//!\name QhullPoints::iterator
+ // Modeled on qlist.h w/o QT_STRICT_ITERATORS
+ // before const_iterator for conversion with comparison operators
+ // See: QhullSet.h
+ class iterator : public QhullPoint {
+
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef QhullPoint value_type;
+ typedef value_type * pointer;
+ typedef value_type & reference;
+ typedef ptrdiff_t difference_type;
+
+ explicit iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {}
+ iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
+ iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {}
+ iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {}
+ iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {}
+ iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {}
+ iterator(const iterator &other): QhullPoint(*other) {}
+ iterator & operator=(const iterator &other) { defineAs( const_cast<iterator &>(other)); return *this; }
+
+ // Need 'const QhullPoint' to maintain const
+ const QhullPoint & operator*() const { return *this; }
+ QhullPoint & operator*() { return *this; }
+ const QhullPoint * operator->() const { return this; }
+ QhullPoint * operator->() { return this; }
+ // value instead of reference since advancePoint() modifies self
+ QhullPoint operator[](countT idx) const { QhullPoint result= *this; result.advancePoint(idx); return result; }
+ bool operator==(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates==o.point_coordinates && point_dimension==o.point_dimension); }
+ bool operator!=(const iterator &o) const { return !operator==(o); }
+ bool operator<(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates < o.point_coordinates; }
+ bool operator<=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates <= o.point_coordinates; }
+ bool operator>(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates > o.point_coordinates; }
+ bool operator>=(const iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates >= o.point_coordinates; }
+ // reinterpret_cast to break circular dependency
+ bool operator==(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return (point_coordinates==reinterpret_cast<const iterator &>(o).point_coordinates && point_dimension==reinterpret_cast<const iterator &>(o).point_dimension); }
+ bool operator!=(const QhullPoints::const_iterator &o) const { return !operator==(reinterpret_cast<const iterator &>(o)); }
+ bool operator<(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates < reinterpret_cast<const iterator &>(o).point_coordinates; }
+ bool operator<=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates <= reinterpret_cast<const iterator &>(o).point_coordinates; }
+ bool operator>(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates > reinterpret_cast<const iterator &>(o).point_coordinates; }
+ bool operator>=(const QhullPoints::const_iterator &o) const { QHULL_ASSERT(qh_qh==reinterpret_cast<const iterator &>(o).qh_qh); return point_coordinates >= reinterpret_cast<const iterator &>(o).point_coordinates; }
+ iterator & operator++() { advancePoint(1); return *this; }
+ iterator operator++(int) { iterator n= *this; operator++(); return iterator(n); }
+ iterator & operator--() { advancePoint(-1); return *this; }
+ iterator operator--(int) { iterator n= *this; operator--(); return iterator(n); }
+ iterator & operator+=(countT idx) { advancePoint(idx); return *this; }
+ iterator & operator-=(countT idx) { advancePoint(-idx); return *this; }
+ iterator operator+(countT idx) const { iterator n= *this; n.advancePoint(idx); return n; }
+ iterator operator-(countT idx) const { iterator n= *this; n.advancePoint(-idx); return n; }
+ difference_type operator-(iterator o) const { QHULL_ASSERT(qh_qh==o.qh_qh && point_dimension==o.point_dimension); return (point_dimension ? (point_coordinates-o.point_coordinates)/point_dimension : 0); }
+ };//QhullPoints::iterator
+
+#//!\name QhullPoints::const_iterator
+ //!\todo FIXUP QH11018 const_iterator same as iterator. SHould have a common definition
+ class const_iterator : public QhullPoint {
+
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef QhullPoint value_type;
+ typedef const value_type * pointer;
+ typedef const value_type & reference;
+ typedef ptrdiff_t difference_type;
+
+ const_iterator(const QhullPoints::iterator &o) : QhullPoint(*o) {}
+ explicit const_iterator(const QhullPoints &ps) : QhullPoint(ps.qh(), ps.dimension(), ps.coordinates()) {}
+ const_iterator(const int pointDimension, coordT *c): QhullPoint(pointDimension, c) {}
+ const_iterator(const Qhull &q, coordT *c): QhullPoint(q, c) {}
+ const_iterator(const Qhull &q, int pointDimension, coordT *c): QhullPoint(q, pointDimension, c) {}
+ const_iterator(QhullQh *qqh, coordT *c): QhullPoint(qqh, c) {}
+ const_iterator(QhullQh *qqh, int pointDimension, coordT *c): QhullPoint(qqh, pointDimension, c) {}
+ const_iterator(const const_iterator &o) : QhullPoint(*o) {}
+ const_iterator &operator=(const const_iterator &o) { defineAs(const_cast<const_iterator &>(o)); return *this; }
+
+ // value/non-const since advancePoint(1), etc. modifies self
+ const QhullPoint & operator*() const { return *this; }
+ const QhullPoint * operator->() const { return this; }
+ // value instead of reference since advancePoint() modifies self
+ const QhullPoint operator[](countT idx) const { QhullPoint n= *this; n.advancePoint(idx); return n; }
+ bool operator==(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return (point_coordinates==o.point_coordinates && point_dimension==o.point_dimension); }
+ bool operator!=(const const_iterator &o) const { return ! operator==(o); }
+ bool operator<(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates < o.point_coordinates; }
+ bool operator<=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates <= o.point_coordinates; }
+ bool operator>(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates > o.point_coordinates; }
+ bool operator>=(const const_iterator &o) const { QHULL_ASSERT(qh_qh==o.qh_qh); return point_coordinates >= o.point_coordinates; }
+ const_iterator &operator++() { advancePoint(1); return *this; }
+ const_iterator operator++(int) { const_iterator n= *this; operator++(); return const_iterator(n); }
+ const_iterator &operator--() { advancePoint(-1); return *this; }
+ const_iterator operator--(int) { const_iterator n= *this; operator--(); return const_iterator(n); }
+ const_iterator &operator+=(countT idx) { advancePoint(idx); return *this; }
+ const_iterator &operator-=(countT idx) { advancePoint(-idx); return *this; }
+ const_iterator operator+(countT idx) const { const_iterator n= *this; n.advancePoint(idx); return n; }
+ const_iterator operator-(countT idx) const { const_iterator n= *this; n.advancePoint(-idx); return n; }
+ difference_type operator-(const_iterator o) const { QHULL_ASSERT(qh_qh==o.qh_qh && point_dimension==o.point_dimension); return (point_dimension ? (point_coordinates-o.point_coordinates)/point_dimension : 0); }
+ };//QhullPoints::const_iterator
+
+#//!\name IO
+ struct PrintPoints{
+ const QhullPoints *points;
+ const char * point_message;
+ bool with_identifier;
+ PrintPoints(const char *message, bool withIdentifier, const QhullPoints &ps) : points(&ps), point_message(message), with_identifier(withIdentifier) {}
+ };//PrintPoints
+ PrintPoints print(const char *message) const { return PrintPoints(message, false, *this); }
+ PrintPoints printWithIdentifier(const char *message) const { return PrintPoints(message, true, *this); }
+};//QhullPoints
+
+// Instead of QHULL_DECLARE_SEQUENTIAL_ITERATOR because next(),etc would return a reference to a temporary
+class QhullPointsIterator
+{
+ typedef QhullPoints::const_iterator const_iterator;
+
+#//!\name Fields
+private:
+ const QhullPoints *ps;
+ const_iterator i;
+
+public:
+ QhullPointsIterator(const QhullPoints &other) : ps(&other), i(ps->constBegin()) {}
+ QhullPointsIterator &operator=(const QhullPoints &other) { ps = &other; i = ps->constBegin(); return *this; }
+
+ bool findNext(const QhullPoint &t);
+ bool findPrevious(const QhullPoint &t);
+ bool hasNext() const { return i != ps->constEnd(); }
+ bool hasPrevious() const { return i != ps->constBegin(); }
+ QhullPoint next() { return *i++; }
+ QhullPoint peekNext() const { return *i; }
+ QhullPoint peekPrevious() const { const_iterator p = i; return *--p; }
+ QhullPoint previous() { return *--i; }
+ void toBack() { i = ps->constEnd(); }
+ void toFront() { i = ps->constBegin(); }
+};//QhullPointsIterator
+
+}//namespace orgQhull
+
+#//!\name Global
+
+std::ostream & operator<<(std::ostream &os, const orgQhull::QhullPoints &p);
+std::ostream & operator<<(std::ostream &os, const orgQhull::QhullPoints::PrintPoints &pr);
+
+#endif // QHULLPOINTS_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullQh.cpp b/xs/src/qhull/src/libqhullcpp/QhullQh.cpp
new file mode 100644
index 000000000..363533700
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullQh.cpp
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullQh.cpp#5 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! QhullQh -- Qhull's global data structure, qhT, as a C++ class
+
+
+#include "libqhullcpp/QhullQh.h"
+
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullStat.h"
+
+#include <sstream>
+#include <iostream>
+
+#include <stdarg.h>
+
+using std::cerr;
+using std::string;
+using std::vector;
+using std::ostream;
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
+#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
+#endif
+
+namespace orgQhull {
+
+#//!\name Global variables
+const double QhullQh::
+default_factor_epsilon= 1.0;
+
+#//!\name Constructor, destructor, etc.
+
+//! Derived from qh_new_qhull[user.c]
+QhullQh::
+QhullQh()
+: qhull_status(qh_ERRnone)
+, qhull_message()
+, error_stream(0)
+, output_stream(0)
+, factor_epsilon(QhullQh::default_factor_epsilon)
+, use_output_stream(false)
+{
+ // NOerrors: TRY_QHULL_ not needed since these routines do not call qh_errexit()
+ qh_meminit(this, NULL);
+ qh_initstatistics(this);
+ qh_initqhull_start2(this, NULL, NULL, qh_FILEstderr); // Initialize qhT
+ this->ISqhullQh= True;
+}//QhullQh
+
+QhullQh::
+~QhullQh()
+{
+ checkAndFreeQhullMemory();
+}//~QhullQh
+
+#//!\name Methods
+
+//! Check memory for internal consistency
+//! Free global memory used by qh_initbuild and qh_buildhull
+//! Zero the qhT data structure, except for memory (qhmemT) and statistics (qhstatT)
+//! Check and free short memory (e.g., facetT)
+//! Zero the qhmemT data structure
+void QhullQh::
+checkAndFreeQhullMemory()
+{
+#ifdef qh_NOmem
+ qh_freeqhull(this, qh_ALL);
+#else
+ qh_memcheck(this);
+ qh_freeqhull(this, !qh_ALL);
+ countT curlong;
+ countT totlong;
+ qh_memfreeshort(this, &curlong, &totlong);
+ if (curlong || totlong)
+ throw QhullError(10026, "Qhull error: qhull did not free %d bytes of long memory (%d pieces).", totlong, curlong);
+#endif
+}//checkAndFreeQhullMemory
+
+#//!\name Messaging
+
+void QhullQh::
+appendQhullMessage(const string &s)
+{
+ if(output_stream && use_output_stream && this->USEstdout){
+ *output_stream << s;
+ }else if(error_stream){
+ *error_stream << s;
+ }else{
+ qhull_message += s;
+ }
+}//appendQhullMessage
+
+//! clearQhullMessage does not throw errors (~Qhull)
+void QhullQh::
+clearQhullMessage()
+{
+ qhull_status= qh_ERRnone;
+ qhull_message.clear();
+ RoadError::clearGlobalLog();
+}//clearQhullMessage
+
+//! hasQhullMessage does not throw errors (~Qhull)
+bool QhullQh::
+hasQhullMessage() const
+{
+ return (!qhull_message.empty() || qhull_status!=qh_ERRnone);
+ //FIXUP QH11006 -- inconsistent usage with Rbox. hasRboxMessage just tests rbox_status. No appendRboxMessage()
+}
+
+void QhullQh::
+maybeThrowQhullMessage(int exitCode)
+{
+ if(!NOerrexit){
+ if(qhull_message.size()>0){
+ qhull_message.append("\n");
+ }
+ if(exitCode || qhull_status==qh_ERRnone){
+ qhull_status= 10073;
+ }else{
+ qhull_message.append("QH10073: ");
+ }
+ qhull_message.append("Cannot call maybeThrowQhullMessage() from QH_TRY_(). Or missing 'qh->NOerrexit=true;' after QH_TRY_(){...}.");
+ }
+ if(qhull_status==qh_ERRnone){
+ qhull_status= exitCode;
+ }
+ if(qhull_status!=qh_ERRnone){
+ QhullError e(qhull_status, qhull_message);
+ clearQhullMessage();
+ throw e; // FIXUP QH11007: copy constructor is expensive if logging
+ }
+}//maybeThrowQhullMessage
+
+void QhullQh::
+maybeThrowQhullMessage(int exitCode, int noThrow) throw()
+{
+ QHULL_UNUSED(noThrow);
+
+ if(qhull_status==qh_ERRnone){
+ qhull_status= exitCode;
+ }
+ if(qhull_status!=qh_ERRnone){
+ QhullError e(qhull_status, qhull_message);
+ e.logErrorLastResort();
+ }
+}//maybeThrowQhullMessage
+
+//! qhullMessage does not throw errors (~Qhull)
+std::string QhullQh::
+qhullMessage() const
+{
+ if(qhull_message.empty() && qhull_status!=qh_ERRnone){
+ return "qhull: no message for error. Check cerr or error stream\n";
+ }else{
+ return qhull_message;
+ }
+}//qhullMessage
+
+int QhullQh::
+qhullStatus() const
+{
+ return qhull_status;
+}//qhullStatus
+
+void QhullQh::
+setErrorStream(ostream *os)
+{
+ error_stream= os;
+}//setErrorStream
+
+//! Updates use_output_stream
+void QhullQh::
+setOutputStream(ostream *os)
+{
+ output_stream= os;
+ use_output_stream= (os!=0);
+}//setOutputStream
+
+}//namespace orgQhull
+
+/*-<a href="qh_qh-user.htm#TOC"
+ >-------------------------------</a><a name="qh_fprintf">-</a>
+
+ qh_fprintf(qhT *qh, fp, msgcode, format, list of args )
+ replaces qh_fprintf() in userprintf_r.c
+
+notes:
+ only called from libqhull
+ same as fprintf() and RboxPoints.qh_fprintf_rbox()
+ fgets() is not trapped like fprintf()
+ Do not throw errors from here. Use qh_errexit;
+*/
+extern "C"
+void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... ) {
+ va_list args;
+
+ using namespace orgQhull;
+
+ if(!qh->ISqhullQh){
+ qh_fprintf_stderr(10025, "Qhull error: qh_fprintf called from a Qhull instance without QhullQh defined\n");
+ qh_exit(10025);
+ }
+ QhullQh *qhullQh= static_cast<QhullQh *>(qh);
+ va_start(args, fmt);
+ if(msgcode<MSG_OUTPUT || fp == qh_FILEstderr){
+ if(msgcode>=MSG_ERROR && msgcode<MSG_WARNING){
+ if(qhullQh->qhull_status<MSG_ERROR || qhullQh->qhull_status>=MSG_WARNING){
+ qhullQh->qhull_status= msgcode;
+ }
+ }
+ char newMessage[MSG_MAXLEN];
+ // RoadError will add the message tag
+ vsnprintf(newMessage, sizeof(newMessage), fmt, args);
+ qhullQh->appendQhullMessage(newMessage);
+ va_end(args);
+ return;
+ }
+ if(qhullQh->output_stream && qhullQh->use_output_stream){
+ char newMessage[MSG_MAXLEN];
+ vsnprintf(newMessage, sizeof(newMessage), fmt, args);
+ *qhullQh->output_stream << newMessage;
+ va_end(args);
+ return;
+ }
+ // FIXUP QH11008: how do users trap messages and handle input? A callback?
+ char newMessage[MSG_MAXLEN];
+ vsnprintf(newMessage, sizeof(newMessage), fmt, args);
+ qhullQh->appendQhullMessage(newMessage);
+ va_end(args);
+} /* qh_fprintf */
diff --git a/xs/src/qhull/src/libqhullcpp/QhullQh.h b/xs/src/qhull/src/libqhullcpp/QhullQh.h
new file mode 100644
index 000000000..c3b277ff0
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullQh.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullQh.h#2 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLQH_H
+#define QHULLQH_H
+
+#include "libqhull_r/qhull_ra.h"
+
+#include <string>
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#pragma warning( disable : 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
+/* setjmp should not be implemented with 'catch' */
+#endif
+
+//! Use QH_TRY_ or QH_TRY_NOTHROW_ to call a libqhull_r routine that may invoke qh_errexit()
+//! QH_TRY_(qh){...} qh->NOerrexit=true;
+//! No object creation -- longjmp() skips object destructors
+//! To test for error when done -- qh->maybeThrowQhullMessage(QH_TRY_status);
+//! Use the same compiler for QH_TRY_, libqhullcpp, and libqhull_r. setjmp() is not portable between compilers.
+
+#define QH_TRY_ERROR 10071
+
+#define QH_TRY_(qh) \
+ int QH_TRY_status; \
+ if(qh->NOerrexit){ \
+ qh->NOerrexit= False; \
+ QH_TRY_status= setjmp(qh->errexit); \
+ }else{ \
+ throw QhullError(QH_TRY_ERROR, "Cannot invoke QH_TRY_() from inside a QH_TRY_. Or missing 'qh->NOerrexit=true' after previously called QH_TRY_(qh){...}"); \
+ } \
+ if(!QH_TRY_status)
+
+#define QH_TRY_NO_THROW_(qh) \
+ int QH_TRY_status; \
+ if(qh->NOerrexit){ \
+ qh->NOerrexit= False; \
+ QH_TRY_status= setjmp(qh->errexit); \
+ }else{ \
+ QH_TRY_status= QH_TRY_ERROR; \
+ } \
+ if(!QH_TRY_status)
+
+namespace orgQhull {
+
+#//!\name Defined here
+ //! QhullQh -- Qhull's global data structure, qhT, as a C++ class
+ class QhullQh;
+
+//! POD type equivalent to qhT. No virtual members
+class QhullQh : public qhT {
+
+#//!\name Constants
+
+#//!\name Fields
+private:
+ int qhull_status; //!< qh_ERRnone if valid
+ std::string qhull_message; //!< Returned messages from libqhull_r
+ std::ostream * error_stream; //!< overrides errorMessage, use appendQhullMessage()
+ std::ostream * output_stream; //!< send output to stream
+ double factor_epsilon; //!< Factor to increase ANGLEround and DISTround for hyperplane equality
+ bool use_output_stream; //!< True if using output_stream
+
+ friend void ::qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
+
+ static const double default_factor_epsilon; //!< Default factor_epsilon is 1.0, never updated
+
+#//!\name Constructors
+public:
+ QhullQh();
+ ~QhullQh();
+private:
+ //!disable copy constructor and assignment
+ QhullQh(const QhullQh &);
+ QhullQh & operator=(const QhullQh &);
+public:
+
+#//!\name GetSet
+ double factorEpsilon() const { return factor_epsilon; }
+ void setFactorEpsilon(double a) { factor_epsilon= a; }
+ void disableOutputStream() { use_output_stream= false; }
+ void enableOutputStream() { use_output_stream= true; }
+
+#//!\name Messaging
+ void appendQhullMessage(const std::string &s);
+ void clearQhullMessage();
+ std::string qhullMessage() const;
+ bool hasOutputStream() const { return use_output_stream; }
+ bool hasQhullMessage() const;
+ void maybeThrowQhullMessage(int exitCode);
+ void maybeThrowQhullMessage(int exitCode, int noThrow) throw();
+ int qhullStatus() const;
+ void setErrorStream(std::ostream *os);
+ void setOutputStream(std::ostream *os);
+
+#//!\name Methods
+ double angleEpsilon() const { return this->ANGLEround*factor_epsilon; } //!< Epsilon for hyperplane angle equality
+ void checkAndFreeQhullMemory();
+ double distanceEpsilon() const { return this->DISTround*factor_epsilon; } //!< Epsilon for distance to hyperplane
+
+};//class QhullQh
+
+}//namespace orgQhull
+
+#endif // QHULLQH_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullRidge.cpp b/xs/src/qhull/src/libqhullcpp/QhullRidge.cpp
new file mode 100644
index 000000000..7a0181280
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullRidge.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullRidge.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! QhullRidge -- Qhull's ridge structure, ridgeT, as a C++ class
+
+#include "libqhullcpp/QhullRidge.h"
+
+#include "libqhullcpp/QhullSets.h"
+#include "libqhullcpp/QhullVertex.h"
+#include "libqhullcpp/Qhull.h"
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
+#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
+#endif
+
+namespace orgQhull {
+
+#//!\name Class objects
+ridgeT QhullRidge::
+s_empty_ridge= {0,0,0,0,0,
+ 0,0};
+
+#//!\name Constructors
+
+QhullRidge::QhullRidge(const Qhull &q)
+: qh_ridge(&s_empty_ridge)
+, qh_qh(q.qh())
+{
+}//Default
+
+QhullRidge::QhullRidge(const Qhull &q, ridgeT *r)
+: qh_ridge(r ? r : &s_empty_ridge)
+, qh_qh(q.qh())
+{
+}//ridgeT
+
+#//!\name foreach
+
+//! Return True if nextRidge3d
+//! Simplicial facets may have incomplete ridgeSets
+//! Does not use qh_errexit()
+bool QhullRidge::
+hasNextRidge3d(const QhullFacet &f) const
+{
+ if(!qh_qh){
+ return false;
+ }
+ vertexT *v= 0;
+ // Does not call qh_errexit(), TRY_QHULL_ not needed
+ ridgeT *ridge= qh_nextridge3d(getRidgeT(), f.getFacetT(), &v);
+ return (ridge!=0);
+}//hasNextRidge3d
+
+//! Return next ridge and optional vertex for a 3d facet and ridge
+//! Does not use qh_errexit()
+QhullRidge QhullRidge::
+nextRidge3d(const QhullFacet &f, QhullVertex *nextVertex) const
+{
+ vertexT *v= 0;
+ ridgeT *ridge= 0;
+ if(qh_qh){
+ // Does not call qh_errexit(), TRY_QHULL_ not needed
+ ridge= qh_nextridge3d(getRidgeT(), f.getFacetT(), &v);
+ if(!ridge){
+ throw QhullError(10030, "Qhull error nextRidge3d: missing next ridge for facet %d ridge %d. Does facet contain ridge?", f.id(), id());
+ }
+ }
+ if(nextVertex!=0){
+ *nextVertex= QhullVertex(qh_qh, v);
+ }
+ return QhullRidge(qh_qh, ridge);
+}//nextRidge3d
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+using std::endl;
+using std::ostream;
+using orgQhull::QhullRidge;
+using orgQhull::QhullVertex;
+
+ostream &
+operator<<(ostream &os, const QhullRidge &r)
+{
+ os << r.print("");
+ return os;
+}//<< QhullRidge
+
+//! Duplicate of qh_printridge [io_r.c]
+ostream &
+operator<<(ostream &os, const QhullRidge::PrintRidge &pr)
+{
+ if(*pr.print_message){
+ os << pr.print_message << " ";
+ }else{
+ os << " - ";
+ }
+ QhullRidge r= *pr.ridge;
+ os << "r" << r.id();
+ if(r.getRidgeT()->tested){
+ os << " tested";
+ }
+ if(r.getRidgeT()->nonconvex){
+ os << " nonconvex";
+ }
+ os << endl;
+ os << r.vertices().print(" vertices:");
+ if(r.getRidgeT()->top && r.getRidgeT()->bottom){
+ os << " between f" << r.topFacet().id() << " and f" << r.bottomFacet().id() << endl;
+ }else if(r.getRidgeT()->top){
+ os << " top f" << r.topFacet().id() << endl;
+ }else if(r.getRidgeT()->bottom){
+ os << " bottom f" << r.bottomFacet().id() << endl;
+ }
+
+ return os;
+}//<< PrintRidge
diff --git a/xs/src/qhull/src/libqhullcpp/QhullRidge.h b/xs/src/qhull/src/libqhullcpp/QhullRidge.h
new file mode 100644
index 000000000..924340fb0
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullRidge.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullRidge.h#4 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLRIDGE_H
+#define QHULLRIDGE_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullSet.h"
+#include "libqhullcpp/QhullVertex.h"
+#include "libqhullcpp/QhullVertexSet.h"
+#include "libqhullcpp/QhullFacet.h"
+
+#include <ostream>
+
+namespace orgQhull {
+
+#//!\name Used here
+ class Qhull;
+ class QhullVertex;
+ class QhullVertexSet;
+ class QhullFacet;
+
+#//!\name Defined here
+ //! QhullRidge -- Qhull's ridge structure, ridgeT [libqhull.h], as a C++ class
+ class QhullRidge;
+ typedef QhullSet<QhullRidge> QhullRidgeSet;
+ typedef QhullSetIterator<QhullRidge> QhullRidgeSetIterator;
+ // see QhullSets.h for QhullRidgeSet and QhullRidgeSetIterator -- avoids circular references
+
+/************************
+a ridge is hull_dim-1 simplex between two neighboring facets. If the
+facets are non-simplicial, there may be more than one ridge between
+two facets. E.G. a 4-d hypercube has two triangles between each pair
+of neighboring facets.
+
+topological information:
+ vertices a set of vertices
+ top,bottom neighboring facets with orientation
+
+geometric information:
+ tested True if ridge is clearly convex
+ nonconvex True if ridge is non-convex
+*/
+
+class QhullRidge {
+
+#//!\name Defined here
+public:
+ typedef ridgeT * base_type; // for QhullRidgeSet
+
+#//!\name Fields
+private:
+ ridgeT * qh_ridge; //!< Corresponding ridgeT, never 0
+ QhullQh * qh_qh; //!< QhullQh/qhT for ridgeT, may be 0
+
+#//!\name Class objects
+ static ridgeT s_empty_ridge;
+
+public:
+#//!\name Constants
+
+#//!\name Constructors
+ QhullRidge() : qh_ridge(&s_empty_ridge), qh_qh(0) {}
+ explicit QhullRidge(const Qhull &q);
+ QhullRidge(const Qhull &q, ridgeT *r);
+ explicit QhullRidge(QhullQh *qqh) : qh_ridge(&s_empty_ridge), qh_qh(qqh) {}
+ QhullRidge(QhullQh *qqh, ridgeT *r) : qh_ridge(r ? r : &s_empty_ridge), qh_qh(qqh) {}
+ // Creates an alias. Does not copy QhullRidge. Needed for return by value and parameter passing
+ QhullRidge(const QhullRidge &other) : qh_ridge(other.qh_ridge), qh_qh(other.qh_qh) {}
+ // Creates an alias. Does not copy QhullRidge. Needed for vector<QhullRidge>
+ QhullRidge & operator=(const QhullRidge &other) { qh_ridge= other.qh_ridge; qh_qh= other.qh_qh; return *this; }
+ ~QhullRidge() {}
+
+#//!\name GetSet
+ QhullFacet bottomFacet() const { return QhullFacet(qh_qh, qh_ridge->bottom); }
+ int dimension() const { return ((qh_qh && qh_qh->hull_dim) ? qh_qh->hull_dim-1 : 0); }
+ ridgeT * getBaseT() const { return getRidgeT(); } //!< For QhullSet<QhullRidge>
+ ridgeT * getRidgeT() const { return qh_ridge; }
+ countT id() const { return qh_ridge->id; }
+ bool isValid() const { return (qh_qh && qh_ridge != &s_empty_ridge); }
+ bool operator==(const QhullRidge &other) const { return qh_ridge==other.qh_ridge; }
+ bool operator!=(const QhullRidge &other) const { return !operator==(other); }
+ QhullFacet otherFacet(const QhullFacet &f) const { return QhullFacet(qh_qh, (qh_ridge->top==f.getFacetT() ? qh_ridge->bottom : qh_ridge->top)); }
+ QhullFacet topFacet() const { return QhullFacet(qh_qh, qh_ridge->top); }
+
+#//!\name foreach
+ bool hasNextRidge3d(const QhullFacet &f) const;
+ QhullRidge nextRidge3d(const QhullFacet &f) const { return nextRidge3d(f, 0); }
+ QhullRidge nextRidge3d(const QhullFacet &f, QhullVertex *nextVertex) const;
+ QhullVertexSet vertices() const { return QhullVertexSet(qh_qh, qh_ridge->vertices); }
+
+#//!\name IO
+
+ struct PrintRidge{
+ const QhullRidge *ridge;
+ const char * print_message; //!< non-null message
+ PrintRidge(const char *message, const QhullRidge &r) : ridge(&r), print_message(message) {}
+ };//PrintRidge
+ PrintRidge print(const char* message) const { return PrintRidge(message, *this); }
+};//class QhullRidge
+
+}//namespace orgQhull
+
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullRidge &r);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullRidge::PrintRidge &pr);
+
+#endif // QHULLRIDGE_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullSet.cpp b/xs/src/qhull/src/libqhullcpp/QhullSet.cpp
new file mode 100644
index 000000000..dfdc3c51f
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullSet.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullSet.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! QhullSet -- Qhull's set structure, setT, as a C++ class
+
+#include "libqhullcpp/QhullSet.h"
+
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/QhullError.h"
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#endif
+
+namespace orgQhull {
+
+#//!\name Class objects
+
+setT QhullSetBase::
+s_empty_set;
+
+#//!\name Constructors
+
+QhullSetBase::
+QhullSetBase(const Qhull &q, setT *s)
+: qh_set(s ? s : &s_empty_set)
+, qh_qh(q.qh())
+{
+}
+
+#//!\name Class methods
+
+// Same code for qh_setsize [qset_r.c] and QhullSetBase::count [static]
+countT QhullSetBase::
+count(const setT *set)
+{
+ countT size;
+ const setelemT *sizep;
+
+ if (!set){
+ return(0);
+ }
+ sizep= SETsizeaddr_(set);
+ if ((size= sizep->i)) {
+ size--;
+ if (size > set->maxsize) {
+ // FIXUP QH11022 How to add additional output to a error? -- qh_setprint(qhmem.ferr, "set: ", set);
+ throw QhullError(10032, "QhullSet internal error: current set size %d is greater than maximum size %d\n",
+ size, set->maxsize);
+ }
+ }else{
+ size= set->maxsize;
+ }
+ return size;
+}//count
+
+}//namespace orgQhull
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullSet.h b/xs/src/qhull/src/libqhullcpp/QhullSet.h
new file mode 100644
index 000000000..afb6b51d9
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullSet.h
@@ -0,0 +1,462 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullSet.h#6 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QhullSet_H
+#define QhullSet_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullQh.h"
+
+#include <cstddef> // ptrdiff_t, size_t
+
+#ifndef QHULL_NO_STL
+#include <vector>
+#endif
+
+#ifdef QHULL_USES_QT
+ #include <QtCore/QList>
+#endif
+
+namespace orgQhull {
+
+#//!\name Used here
+ class Qhull;
+
+#//!\name Defined here
+ class QhullSetBase; //! Base class for QhullSet<T>
+ //! QhullSet<T> defined below
+ //! QhullSetIterator<T> defined below
+ //! \see QhullPointSet, QhullLinkedList<T>
+
+//! QhullSetBase is a wrapper for Qhull's setT of void* pointers
+//! \see libqhull_r/qset.h
+class QhullSetBase {
+
+private:
+#//!\name Fields --
+ setT * qh_set;
+ QhullQh * qh_qh; //! Provides access to setT memory allocator
+
+#//!\name Class objects
+ static setT s_empty_set; //! Used if setT* is NULL
+
+public:
+#//!\name Constructors
+ QhullSetBase(const Qhull &q, setT *s);
+ QhullSetBase(QhullQh *qqh, setT *s) : qh_set(s ? s : &s_empty_set), qh_qh(qqh) {}
+ //! Copy constructor copies the pointer but not the set. Needed for return by value and parameter passing.
+ QhullSetBase(const QhullSetBase &other) : qh_set(other.qh_set), qh_qh(other.qh_qh) {}
+ QhullSetBase & operator=(const QhullSetBase &other) { qh_set= other.qh_set; qh_qh= other.qh_qh; return *this; }
+ ~QhullSetBase() {}
+
+private:
+ //!disabled since memory allocation for QhullSet not defined
+ QhullSetBase() {}
+public:
+
+#//!\name GetSet
+ countT count() const { return QhullSetBase::count(qh_set); }
+ void defineAs(setT *s) { qh_set= s ? s : &s_empty_set; } //!< Not type-safe since setT may contain any type
+ void forceEmpty() { qh_set= &s_empty_set; }
+ setT * getSetT() const { return qh_set; }
+ bool isEmpty() const { return SETempty_(qh_set); }
+ QhullQh * qh() const { return qh_qh; }
+ setT ** referenceSetT() { return &qh_set; }
+ size_t size() const { return QhullSetBase::count(qh_set); }
+
+#//!\name Element
+protected:
+ void ** beginPointer() const { return &qh_set->e[0].p; }
+ void ** elementPointer(countT idx) const { QHULL_ASSERT(idx>=0 && idx<qh_set->maxsize); return &SETelem_(qh_set, idx); }
+ //! Always points to 0
+ void ** endPointer() const { return qh_setendpointer(qh_set); }
+
+#//!\name Class methods
+public:
+ static countT count(const setT *set);
+ //s may be null
+ static bool isEmpty(const setT *s) { return SETempty_(s); }
+};//QhullSetBase
+
+
+//! QhullSet<T> -- A read-only wrapper to Qhull's collection class, setT.
+//! QhullSet is similar to STL's <vector> and Qt's QVector
+//! QhullSet is unrelated to STL and Qt's set and map types (e.g., QSet and QMap)
+//! T is a Qhull type that defines 'base_type' and getBaseT() (e.g., QhullFacet with base_type 'facetT *'
+//! A QhullSet does not own its contents -- erase(), clear(), removeFirst(), removeLast(), pop_back(), pop_front(), fromStdList() not defined
+//! QhullSetIterator is faster than STL-style iterator/const_iterator
+//! Qhull's FOREACHelement_() [qset_r.h] maybe more efficient than QhullSet. It uses a NULL terminator instead of an end pointer. STL requires an end pointer.
+//! Derived from QhullLinkedList.h and Qt/core/tools/qlist.h w/o QT_STRICT_ITERATORS
+template <typename T>
+class QhullSet : public QhullSetBase {
+
+private:
+#//!\name Fields -- see QhullSetBase
+
+#//!\name Class objects
+ static setT s_empty_set; //! Workaround for no setT allocator. Used if setT* is NULL
+
+public:
+#//!\name Defined here
+ class iterator;
+ class const_iterator;
+ typedef typename QhullSet<T>::iterator Iterator;
+ typedef typename QhullSet<T>::const_iterator ConstIterator;
+
+#//!\name Constructors
+ QhullSet<T>(const Qhull &q, setT *s) : QhullSetBase(q, s) { }
+ QhullSet<T>(QhullQh *qqh, setT *s) : QhullSetBase(qqh, s) { }
+ //Conversion from setT* is not type-safe. Implicit conversion for void* to T
+ //Copy constructor copies pointer but not contents. Needed for return by value.
+ QhullSet<T>(const QhullSet<T> &other) : QhullSetBase(other) {}
+ QhullSet<T> & operator=(const QhullSet<T> &other) { QhullSetBase::operator=(other); return *this; }
+ ~QhullSet<T>() {}
+
+private:
+ //!Disable default constructor. See QhullSetBase
+ QhullSet<T>();
+public:
+
+#//!\name Conversion
+
+#ifndef QHULL_NO_STL
+ std::vector<T> toStdVector() const;
+#endif
+#ifdef QHULL_USES_QT
+ QList<typename T> toQList() const;
+#endif
+
+#//!\name GetSet -- see QhullSetBase for count(), empty(), isEmpty(), size()
+ using QhullSetBase::count;
+ using QhullSetBase::isEmpty;
+ // operator== defined for QhullSets of the same type
+ bool operator==(const QhullSet<T> &other) const { return qh_setequal(getSetT(), other.getSetT()); }
+ bool operator!=(const QhullSet<T> &other) const { return !operator==(other); }
+
+#//!\name Element access
+ // Constructs T. Cannot return reference.
+ const T at(countT idx) const { return operator[](idx); }
+ // Constructs T. Cannot return reference.
+ const T back() const { return last(); }
+ T back() { return last(); }
+ //! end element is NULL
+ const typename T::base_type * constData() const { return reinterpret_cast<const typename T::base_type *>(beginPointer()); }
+ typename T::base_type * data() { return reinterpret_cast<typename T::base_type *>(beginPointer()); }
+ const typename T::base_type *data() const { return reinterpret_cast<const typename T::base_type *>(beginPointer()); }
+ typename T::base_type * endData() { return reinterpret_cast<typename T::base_type *>(endPointer()); }
+ const typename T::base_type * endData() const { return reinterpret_cast<const typename T::base_type *>(endPointer()); }
+ // Constructs T. Cannot return reference.
+ const T first() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
+ T first() { QHULL_ASSERT(!isEmpty()); return T(qh(), *data()); }
+ // Constructs T. Cannot return reference.
+ const T front() const { return first(); }
+ T front() { return first(); }
+ // Constructs T. Cannot return reference.
+ const T last() const { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
+ T last() { QHULL_ASSERT(!isEmpty()); return T(qh(), *(endData()-1)); }
+ // mid() not available. No setT constructor
+ // Constructs T. Cannot return reference.
+ const T operator[](countT idx) const { const typename T::base_type *p= reinterpret_cast<typename T::base_type *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
+ T operator[](countT idx) { typename T::base_type *p= reinterpret_cast<typename T::base_type *>(elementPointer(idx)); QHULL_ASSERT(idx>=0 && p < endData()); return T(qh(), *p); }
+ const T second() const { return operator[](1); }
+ T second() { return operator[](1); }
+ T value(countT idx) const;
+ T value(countT idx, const T &defaultValue) const;
+
+#//!\name Read-write -- Not available, no setT constructor
+
+#//!\name iterator
+ iterator begin() { return iterator(qh(), reinterpret_cast<typename T::base_type *>(beginPointer())); }
+ const_iterator begin() const { return const_iterator(qh(), data()); }
+ const_iterator constBegin() const { return const_iterator(qh(), data()); }
+ const_iterator constEnd() const { return const_iterator(qh(), endData()); }
+ iterator end() { return iterator(qh(), endData()); }
+ const_iterator end() const { return const_iterator(qh(), endData()); }
+
+#//!\name Search
+ bool contains(const T &t) const;
+ countT count(const T &t) const;
+ countT indexOf(const T &t) const { /* no qh_qh */ return qh_setindex(getSetT(), t.getBaseT()); }
+ countT lastIndexOf(const T &t) const;
+
+ // before const_iterator for conversion with comparison operators
+ class iterator {
+ friend class const_iterator;
+ private:
+ typename T::base_type * i; // e.g., facetT**, first for debugger
+ QhullQh * qh_qh;
+
+ public:
+ typedef ptrdiff_t difference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef T value_type;
+
+ iterator(QhullQh *qqh, typename T::base_type *p) : i(p), qh_qh(qqh) {}
+ iterator(const iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
+ iterator & operator=(const iterator &o) { i= o.i; qh_qh= o.qh_qh; return *this; }
+
+ // Constructs T. Cannot return reference.
+ T operator*() const { return T(qh_qh, *i); }
+ //operator->() n/a, value-type
+ // Constructs T. Cannot return reference.
+ T operator[](countT idx) const { return T(qh_qh, *(i+idx)); } //!< No error checking
+ bool operator==(const iterator &o) const { return i == o.i; }
+ bool operator!=(const iterator &o) const { return !operator==(o); }
+ bool operator==(const const_iterator &o) const { return (i==reinterpret_cast<const iterator &>(o).i); }
+ bool operator!=(const const_iterator &o) const { return !operator==(o); }
+
+ //! Assumes same point set
+ countT operator-(const iterator &o) const { return (countT)(i-o.i); } //WARN64
+ bool operator>(const iterator &o) const { return i>o.i; }
+ bool operator<=(const iterator &o) const { return !operator>(o); }
+ bool operator<(const iterator &o) const { return i<o.i; }
+ bool operator>=(const iterator &o) const { return !operator<(o); }
+ bool operator>(const const_iterator &o) const { return (i > reinterpret_cast<const iterator &>(o).i); }
+ bool operator<=(const const_iterator &o) const { return !operator>(o); }
+ bool operator<(const const_iterator &o) const { return (i < reinterpret_cast<const iterator &>(o).i); }
+ bool operator>=(const const_iterator &o) const { return !operator<(o); }
+
+ //! No error checking
+ iterator & operator++() { ++i; return *this; }
+ iterator operator++(int) { iterator o= *this; ++i; return o; }
+ iterator & operator--() { --i; return *this; }
+ iterator operator--(int) { iterator o= *this; --i; return o; }
+ iterator operator+(countT j) const { return iterator(qh_qh, i+j); }
+ iterator operator-(countT j) const { return operator+(-j); }
+ iterator & operator+=(countT j) { i += j; return *this; }
+ iterator & operator-=(countT j) { i -= j; return *this; }
+ };//QhullPointSet::iterator
+
+ class const_iterator {
+ private:
+ const typename T::base_type * i; // e.g., const facetT**, first for debugger
+ QhullQh * qh_qh;
+
+ public:
+ typedef ptrdiff_t difference_type;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef T value_type;
+
+ const_iterator(QhullQh *qqh, const typename T::base_type * p) : i(p), qh_qh(qqh) {}
+ const_iterator(const const_iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
+ const_iterator(const iterator &o) : i(o.i), qh_qh(o.qh_qh) {}
+ const_iterator &operator=(const const_iterator &o) { i= o.i; qh_qh= o.qh_qh; return *this; }
+
+ // Constructs T. Cannot return reference. Retaining 'const T' return type for consistency with QList/QVector
+ const T operator*() const { return T(qh_qh, *i); }
+ const T operator[](countT idx) const { return T(qh_qh, *(i+idx)); } //!< No error checking
+ //operator->() n/a, value-type
+ bool operator==(const const_iterator &o) const { return i == o.i; }
+ bool operator!=(const const_iterator &o) const { return !operator==(o); }
+
+ //! Assumes same point set
+ countT operator-(const const_iterator &o) { return (countT)(i-o.i); } //WARN64
+ bool operator>(const const_iterator &o) const { return i>o.i; }
+ bool operator<=(const const_iterator &o) const { return !operator>(o); }
+ bool operator<(const const_iterator &o) const { return i<o.i; }
+ bool operator>=(const const_iterator &o) const { return !operator<(o); }
+
+ //!< No error checking
+ const_iterator &operator++() { ++i; return *this; }
+ const_iterator operator++(int) { const_iterator o= *this; ++i; return o; }
+ const_iterator &operator--() { --i; return *this; }
+ const_iterator operator--(int) { const_iterator o= *this; --i; return o; }
+ const_iterator operator+(int j) const { return const_iterator(qh_qh, i+j); }
+ const_iterator operator-(int j) const { return operator+(-j); }
+ const_iterator &operator+=(int j) { i += j; return *this; }
+ const_iterator &operator-=(int j) { i -= j; return *this; }
+ };//QhullPointSet::const_iterator
+
+};//class QhullSet
+
+
+//! Faster then interator/const_iterator due to T::base_type
+template <typename T>
+class QhullSetIterator {
+
+#//!\name Subtypes
+ typedef typename QhullSet<T>::const_iterator const_iterator;
+
+private:
+#//!\name Fields
+ const typename T::base_type * i; // e.g., facetT**, first for debugger
+ const typename T::base_type * begin_i; // must be initialized after i
+ const typename T::base_type * end_i;
+ QhullQh * qh_qh;
+
+public:
+#//!\name Constructors
+ QhullSetIterator<T>(const QhullSet<T> &s) : i(s.data()), begin_i(i), end_i(s.endData()), qh_qh(s.qh()) {}
+ QhullSetIterator<T>(const QhullSetIterator<T> &o) : i(o.i), begin_i(o.begin_i), end_i(o.end_i), qh_qh(o.qh_qh) {}
+ QhullSetIterator<T> &operator=(const QhullSetIterator<T> &o) { i= o.i; begin_i= o.begin_i; end_i= o.end_i; qh_qh= o.qh_qh; return *this; }
+
+#//!\name ReadOnly
+ countT countRemaining() { return (countT)(end_i-i); } // WARN64
+
+#//!\name Search
+ bool findNext(const T &t);
+ bool findPrevious(const T &t);
+
+#//!\name Foreach
+ bool hasNext() const { return i != end_i; }
+ bool hasPrevious() const { return i != begin_i; }
+ T next() { return T(qh_qh, *i++); }
+ T peekNext() const { return T(qh_qh, *i); }
+ T peekPrevious() const { const typename T::base_type *p = i; return T(qh_qh, *--p); }
+ T previous() { return T(qh_qh, *--i); }
+ void toBack() { i = end_i; }
+ void toFront() { i = begin_i; }
+};//class QhullSetIterator
+
+#//!\name == Definitions =========================================
+
+#//!\name Conversions
+
+// See qt-qhull.cpp for QList conversion
+
+#ifndef QHULL_NO_STL
+template <typename T>
+std::vector<T> QhullSet<T>::
+toStdVector() const
+{
+ typename QhullSet<T>::const_iterator i = begin();
+ typename QhullSet<T>::const_iterator e = end();
+ std::vector<T> vs;
+ while(i!=e){
+ vs.push_back(*i++);
+ }
+ return vs;
+}//toStdVector
+#endif //QHULL_NO_STL
+
+#ifdef QHULL_USES_QT
+template <typename T>
+QList<T> QhullSet<T>::
+toQList() const
+{
+ QhullSet<T>::const_iterator i= begin();
+ QhullSet<T>::const_iterator e= end();
+ QList<T> vs;
+ while(i!=e){
+ vs.append(*i++);
+ }
+ return vs;
+}//toQList
+#endif
+
+#//!\name Element
+
+template <typename T>
+T QhullSet<T>::
+value(countT idx) const
+{
+ // Avoid call to qh_setsize() and assert in elementPointer()
+ const typename T::base_type *p= reinterpret_cast<const typename T::base_type *>(&SETelem_(getSetT(), idx));
+ return (idx>=0 && p<endData()) ? T(qh(), *p) : T(qh());
+}//value
+
+template <typename T>
+T QhullSet<T>::
+value(countT idx, const T &defaultValue) const
+{
+ // Avoid call to qh_setsize() and assert in elementPointer()
+ const typename T::base_type *p= reinterpret_cast<const typename T::base_type *>(&SETelem_(getSetT(), idx));
+ return (idx>=0 && p<endData() ? T(qh(), *p) : defaultValue);
+}//value
+
+#//!\name Search
+
+template <typename T>
+bool QhullSet<T>::
+contains(const T &t) const
+{
+ setT *s= getSetT();
+ void *p= t.getBaseT(); // contains() is not inline for better error reporting
+ int result= qh_setin(s, p);
+ return result!=0;
+}//contains
+
+template <typename T>
+countT QhullSet<T>::
+count(const T &t) const
+{
+ countT n= 0;
+ const typename T::base_type *i= data();
+ const typename T::base_type *e= endData();
+ typename T::base_type p= t.getBaseT();
+ while(i<e){
+ if(*i==p){
+ n++;
+ }
+ i++;
+ }
+ return n;
+}//count
+
+template <typename T>
+countT QhullSet<T>::
+lastIndexOf(const T &t) const
+{
+ const typename T::base_type *b= data();
+ const typename T::base_type *i= endData();
+ typename T::base_type p= t.getBaseT();
+ while(--i>=b){
+ if(*i==p){
+ break;
+ }
+ }
+ return (countT)(i-b); // WARN64
+}//lastIndexOf
+
+#//!\name QhullSetIterator
+
+template <typename T>
+bool QhullSetIterator<T>::
+findNext(const T &t)
+{
+ typename T::base_type p= t.getBaseT();
+ while(i!=end_i){
+ if(*(++i)==p){
+ return true;
+ }
+ }
+ return false;
+}//findNext
+
+template <typename T>
+bool QhullSetIterator<T>::
+findPrevious(const T &t)
+{
+ typename T::base_type p= t.getBaseT();
+ while(i!=begin_i){
+ if(*(--i)==p){
+ return true;
+ }
+ }
+ return false;
+}//findPrevious
+
+}//namespace orgQhull
+
+
+#//!\name == Global namespace =========================================
+
+template <typename T>
+std::ostream &
+operator<<(std::ostream &os, const orgQhull::QhullSet<T> &qs)
+{
+ const typename T::base_type *i= qs.data();
+ const typename T::base_type *e= qs.endData();
+ while(i!=e){
+ os << T(qs.qh(), *i++);
+ }
+ return os;
+}//operator<<
+
+#endif // QhullSet_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullSets.h b/xs/src/qhull/src/libqhullcpp/QhullSets.h
new file mode 100644
index 000000000..d0f200cbc
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullSets.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullSets.h#2 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLSETS_H
+#define QHULLSETS_H
+
+#include "libqhullcpp/QhullSet.h"
+
+namespace orgQhull {
+
+ //See: QhullFacetSet.h
+ //See: QhullPointSet.h
+ //See: QhullVertexSet.h
+
+ // Avoid circular references between QhullFacet, QhullRidge, and QhullVertex
+ class QhullRidge;
+ typedef QhullSet<QhullRidge> QhullRidgeSet;
+ typedef QhullSetIterator<QhullRidge> QhullRidgeSetIterator;
+
+}//namespace orgQhull
+
+#endif // QHULLSETS_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullStat.cpp b/xs/src/qhull/src/libqhullcpp/QhullStat.cpp
new file mode 100644
index 000000000..c4fe6c491
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullStat.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullStat.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! QhullStat -- Qhull's global data structure, statT, as a C++ class
+
+#include "libqhullcpp/QhullStat.h"
+
+#include "libqhullcpp/QhullError.h"
+
+#include <sstream>
+#include <iostream>
+
+using std::cerr;
+using std::string;
+using std::vector;
+using std::ostream;
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#endif
+
+namespace orgQhull {
+
+#//!\name Constructor, destructor, etc.
+
+//! If qh_QHpointer==0, invoke with placement new on qh_stat;
+QhullStat::
+QhullStat()
+{
+}//QhullStat
+
+QhullStat::
+~QhullStat()
+{
+}//~QhullStat
+
+}//namespace orgQhull
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullStat.h b/xs/src/qhull/src/libqhullcpp/QhullStat.h
new file mode 100644
index 000000000..54bde8fc7
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullStat.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullStat.h#2 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLSTAT_H
+#define QHULLSTAT_H
+
+#include "libqhull_r/qhull_ra.h"
+
+#include <string>
+#include <vector>
+
+namespace orgQhull {
+
+#//!\name defined here
+ //! QhullStat -- Qhull's statistics, qhstatT, as a C++ class
+ //! Statistics defined with zzdef_() control Qhull's behavior, summarize its result, and report precision problems.
+ class QhullStat;
+
+class QhullStat : public qhstatT {
+
+private:
+#//!\name Fields (empty) -- POD type equivalent to qhstatT. No data or virtual members
+
+public:
+#//!\name Constants
+
+#//!\name class methods
+
+#//!\name constructor, assignment, destructor, invariant
+ QhullStat();
+ ~QhullStat();
+
+private:
+ //!disable copy constructor and assignment
+ QhullStat(const QhullStat &);
+ QhullStat & operator=(const QhullStat &);
+public:
+
+#//!\name Access
+};//class QhullStat
+
+}//namespace orgQhull
+
+#endif // QHULLSTAT_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullVertex.cpp b/xs/src/qhull/src/libqhullcpp/QhullVertex.cpp
new file mode 100644
index 000000000..fd7aef089
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullVertex.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullVertex.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! QhullVertex -- Qhull's vertex structure, vertexT, as a C++ class
+
+#include "libqhullcpp/QhullVertex.h"
+
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/QhullFacetSet.h"
+#include "libqhullcpp/QhullFacet.h"
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#pragma warning( disable : 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
+#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
+#endif
+
+namespace orgQhull {
+
+#//!\name Class objects
+vertexT QhullVertex::
+s_empty_vertex= {0,0,0,0,0,
+ 0,0,0,0,0,
+ 0};
+
+#//!\name Constructors
+
+QhullVertex::QhullVertex(const Qhull &q)
+: qh_vertex(&s_empty_vertex)
+, qh_qh(q.qh())
+{
+}//Default
+
+QhullVertex::QhullVertex(const Qhull &q, vertexT *v)
+: qh_vertex(v ? v : &s_empty_vertex)
+, qh_qh(q.qh())
+{
+}//vertexT
+
+#//!\name foreach
+
+//! Return neighboring facets for a vertex
+//! If neither merging nor Voronoi diagram, requires Qhull::defineVertexNeighborFacets() beforehand.
+QhullFacetSet QhullVertex::
+neighborFacets() const
+{
+ if(!neighborFacetsDefined()){
+ throw QhullError(10034, "Qhull error: neighboring facets of vertex %d not defined. Please call Qhull::defineVertexNeighborFacets() beforehand.", id());
+ }
+ return QhullFacetSet(qh_qh, qh_vertex->neighbors);
+}//neighborFacets
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+using std::endl;
+using std::ostream;
+using std::string;
+using std::vector;
+using orgQhull::QhullPoint;
+using orgQhull::QhullFacet;
+using orgQhull::QhullFacetSet;
+using orgQhull::QhullFacetSetIterator;
+using orgQhull::QhullVertex;
+
+//! Duplicate of qh_printvertex [io_r.c]
+ostream &
+operator<<(ostream &os, const QhullVertex::PrintVertex &pr)
+{
+ QhullVertex v= *pr.vertex;
+ QhullPoint p= v.point();
+ if(*pr.print_message){
+ os << pr.print_message << " ";
+ }else{
+ os << "- ";
+ }
+ os << "p" << p.id() << " (v" << v.id() << "): ";
+ const realT *c= p.coordinates();
+ for(int k= p.dimension(); k--; ){
+ os << " " << *c++; // FIXUP QH11010 %5.2g
+ }
+ if(v.getVertexT()->deleted){
+ os << " deleted";
+ }
+ if(v.getVertexT()->delridge){
+ os << " ridgedeleted";
+ }
+ os << endl;
+ if(v.neighborFacetsDefined()){
+ QhullFacetSetIterator i= v.neighborFacets();
+ if(i.hasNext()){
+ os << " neighborFacets:";
+ countT count= 0;
+ while(i.hasNext()){
+ if(++count % 100 == 0){
+ os << endl << " ";
+ }
+ QhullFacet f= i.next();
+ os << " f" << f.id();
+ }
+ os << endl;
+ }
+ }
+ return os;
+}//<< PrintVertex
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullVertex.h b/xs/src/qhull/src/libqhullcpp/QhullVertex.h
new file mode 100644
index 000000000..0137766db
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullVertex.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullVertex.h#4 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLVERTEX_H
+#define QHULLVERTEX_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/QhullLinkedList.h"
+#include "libqhullcpp/QhullSet.h"
+
+#include <ostream>
+
+namespace orgQhull {
+
+#//!\name Used here
+ class QhullFacetSet;
+
+#//!\name Defined here
+ //! QhullVertex -- Qhull's vertex structure, vertexT [libqhull_r.h], as a C++ class
+ class QhullVertex;
+ typedef QhullLinkedList<QhullVertex> QhullVertexList;
+ typedef QhullLinkedListIterator<QhullVertex> QhullVertexListIterator;
+
+
+/*********************
+ topological information:
+ next,previous doubly-linked list of all vertices
+ neighborFacets set of adjacent facets (only if qh.VERTEXneighbors)
+
+ geometric information:
+ point array of DIM coordinates
+*/
+
+class QhullVertex {
+
+#//!\name Defined here
+public:
+ typedef vertexT * base_type; // for QhullVertexSet
+
+private:
+#//!\name Fields
+ vertexT * qh_vertex; //!< Corresponding vertexT, never 0
+ QhullQh * qh_qh; //!< QhullQh/qhT for vertexT, may be 0
+
+#//!\name Class objects
+ static vertexT s_empty_vertex; // needed for shallow copy
+
+public:
+#//!\name Constants
+
+#//!\name Constructors
+ QhullVertex() : qh_vertex(&s_empty_vertex), qh_qh(0) {}
+ explicit QhullVertex(const Qhull &q);
+ QhullVertex(const Qhull &q, vertexT *v);
+ explicit QhullVertex(QhullQh *qqh) : qh_vertex(&s_empty_vertex), qh_qh(qqh) {}
+ QhullVertex(QhullQh *qqh, vertexT *v) : qh_vertex(v ? v : &s_empty_vertex), qh_qh(qqh) {}
+ // Creates an alias. Does not copy QhullVertex. Needed for return by value and parameter passing
+ QhullVertex(const QhullVertex &other) : qh_vertex(other.qh_vertex), qh_qh(other.qh_qh) {}
+ // Creates an alias. Does not copy QhullVertex. Needed for vector<QhullVertex>
+ QhullVertex & operator=(const QhullVertex &other) { qh_vertex= other.qh_vertex; qh_qh= other.qh_qh; return *this; }
+ ~QhullVertex() {}
+
+#//!\name GetSet
+ int dimension() const { return (qh_qh ? qh_qh->hull_dim : 0); }
+ vertexT * getBaseT() const { return getVertexT(); } //!< For QhullSet<QhullVertex>
+ vertexT * getVertexT() const { return qh_vertex; }
+ countT id() const { return qh_vertex->id; }
+ bool isValid() const { return (qh_qh && qh_vertex != &s_empty_vertex); }
+ //! True if defineVertexNeighborFacets() already called. Auotomatically set for facet merging, Voronoi diagrams
+ bool neighborFacetsDefined() const { return qh_vertex->neighbors != 0; }
+ QhullVertex next() const { return QhullVertex(qh_qh, qh_vertex->next); }
+ bool operator==(const QhullVertex &other) const { return qh_vertex==other.qh_vertex; }
+ bool operator!=(const QhullVertex &other) const { return !operator==(other); }
+ QhullPoint point() const { return QhullPoint(qh_qh, qh_vertex->point); }
+ QhullVertex previous() const { return QhullVertex(qh_qh, qh_vertex->previous); }
+ QhullQh * qh() const { return qh_qh; }
+
+#//!\name foreach
+ //See also QhullVertexList
+ QhullFacetSet neighborFacets() const;
+
+#//!\name IO
+ struct PrintVertex{
+ const QhullVertex *vertex;
+ const char * print_message; //!< non-null message
+ PrintVertex(const char *message, const QhullVertex &v) : vertex(&v), print_message(message) {}
+ };//PrintVertex
+ PrintVertex print(const char *message) const { return PrintVertex(message, *this); }
+};//class QhullVertex
+
+}//namespace orgQhull
+
+#//!\name GLobal
+
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertex::PrintVertex &pr);
+inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertex &v) { os << v.print(""); return os; }
+
+#endif // QHULLVERTEX_H
diff --git a/xs/src/qhull/src/libqhullcpp/QhullVertexSet.cpp b/xs/src/qhull/src/libqhullcpp/QhullVertexSet.cpp
new file mode 100644
index 000000000..00ba62d19
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullVertexSet.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullVertexSet.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! QhullVertexSet -- Qhull's linked Vertexs, as a C++ class
+
+#include "libqhullcpp/QhullVertexSet.h"
+
+#include "libqhullcpp/QhullVertex.h"
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/QhullRidge.h"
+#include "libqhullcpp/QhullVertex.h"
+#include "libqhullcpp/Qhull.h"
+
+using std::string;
+using std::vector;
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#pragma warning( disable : 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
+ /* setjmp should not be implemented with 'catch' */
+#endif
+
+namespace orgQhull {
+
+QhullVertexSet::
+QhullVertexSet(const Qhull &q, facetT *facetlist, setT *facetset, bool allfacets)
+: QhullSet<QhullVertex>(q.qh(), 0)
+, qhsettemp_defined(false)
+{
+ QH_TRY_(q.qh()){ // no object creation -- destructors skipped on longjmp()
+ setT *vertices= qh_facetvertices(q.qh(), facetlist, facetset, allfacets);
+ defineAs(vertices);
+ qhsettemp_defined= true;
+ }
+ q.qh()->NOerrexit= true;
+ q.qh()->maybeThrowQhullMessage(QH_TRY_status);
+}//QhullVertexSet facetlist facetset
+
+//! Return tempory QhullVertexSet of vertices for a list and/or a set of facets
+//! Sets qhsettemp_defined (disallows copy constructor and assignment to prevent double-free)
+QhullVertexSet::
+QhullVertexSet(QhullQh *qqh, facetT *facetlist, setT *facetset, bool allfacets)
+: QhullSet<QhullVertex>(qqh, 0)
+, qhsettemp_defined(false)
+{
+ QH_TRY_(qh()){ // no object creation -- destructors skipped on longjmp()
+ setT *vertices= qh_facetvertices(qh(), facetlist, facetset, allfacets);
+ defineAs(vertices);
+ qhsettemp_defined= true;
+ }
+ qh()->NOerrexit= true;
+ qh()->maybeThrowQhullMessage(QH_TRY_status);
+}//QhullVertexSet facetlist facetset
+
+//! Copy constructor for argument passing and returning a result
+//! Only copies a pointer to the set.
+//! Throws an error if qhsettemp_defined, otherwise have a double-free
+//!\todo Convert QhullVertexSet to a shared pointer with reference counting
+QhullVertexSet::
+QhullVertexSet(const QhullVertexSet &other)
+: QhullSet<QhullVertex>(other)
+, qhsettemp_defined(false)
+{
+ if(other.qhsettemp_defined){
+ throw QhullError(10077, "QhullVertexSet: Cannot use copy constructor since qhsettemp_defined (e.g., QhullVertexSet for a set and/or list of QhFacet). Contains %d vertices", other.count());
+ }
+}//copy constructor
+
+//! Copy assignment only copies a pointer to the set.
+//! Throws an error if qhsettemp_defined, otherwise have a double-free
+QhullVertexSet & QhullVertexSet::
+operator=(const QhullVertexSet &other)
+{
+ QhullSet<QhullVertex>::operator=(other);
+ qhsettemp_defined= false;
+ if(other.qhsettemp_defined){
+ throw QhullError(10078, "QhullVertexSet: Cannot use copy constructor since qhsettemp_defined (e.g., QhullVertexSet for a set and/or list of QhFacet). Contains %d vertices", other.count());
+ }
+ return *this;
+}//assignment
+
+void QhullVertexSet::
+freeQhSetTemp()
+{
+ if(qhsettemp_defined){
+ qhsettemp_defined= false;
+ QH_TRY_(qh()){ // no object creation -- destructors skipped on longjmp()
+ qh_settempfree(qh(), referenceSetT()); // errors if not top of tempstack or if qhmem corrupted
+ }
+ qh()->NOerrexit= true;
+ qh()->maybeThrowQhullMessage(QH_TRY_status, QhullError::NOthrow);
+ }
+}//freeQhSetTemp
+
+QhullVertexSet::
+~QhullVertexSet()
+{
+ freeQhSetTemp();
+}//~QhullVertexSet
+
+//FIXUP -- Move conditional, QhullVertexSet code to QhullVertexSet.cpp
+#ifndef QHULL_NO_STL
+std::vector<QhullVertex> QhullVertexSet::
+toStdVector() const
+{
+ QhullSetIterator<QhullVertex> i(*this);
+ std::vector<QhullVertex> vs;
+ while(i.hasNext()){
+ QhullVertex v= i.next();
+ vs.push_back(v);
+ }
+ return vs;
+}//toStdVector
+#endif //QHULL_NO_STL
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+using std::endl;
+using std::ostream;
+using orgQhull::QhullPoint;
+using orgQhull::QhullVertex;
+using orgQhull::QhullVertexSet;
+using orgQhull::QhullVertexSetIterator;
+
+//! Print Vertex identifiers to stream. Space prefix. From qh_printVertexheader [io_r.c]
+ostream &
+operator<<(ostream &os, const QhullVertexSet::PrintIdentifiers &pr)
+{
+ os << pr.print_message;
+ for(QhullVertexSet::const_iterator i= pr.vertex_set->begin(); i!=pr.vertex_set->end(); ++i){
+ const QhullVertex v= *i;
+ os << " v" << v.id();
+ }
+ os << endl;
+ return os;
+}//<<QhullVertexSet::PrintIdentifiers
+
+//! Duplicate of printvertices [io_r.c]
+ostream &
+operator<<(ostream &os, const QhullVertexSet::PrintVertexSet &pr){
+
+ os << pr.print_message;
+ const QhullVertexSet *vs= pr.vertex_set;
+ QhullVertexSetIterator i= *vs;
+ while(i.hasNext()){
+ const QhullVertex v= i.next();
+ const QhullPoint p= v.point();
+ os << " p" << p.id() << "(v" << v.id() << ")";
+ }
+ os << endl;
+
+ return os;
+}//<< PrintVertexSet
+
+
diff --git a/xs/src/qhull/src/libqhullcpp/QhullVertexSet.h b/xs/src/qhull/src/libqhullcpp/QhullVertexSet.h
new file mode 100644
index 000000000..a3a11c124
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/QhullVertexSet.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/QhullVertexSet.h#2 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHULLVERTEXSET_H
+#define QHULLVERTEXSET_H
+
+#include "libqhullcpp/QhullSet.h"
+#include "libqhullcpp/QhullVertex.h"
+
+#include <ostream>
+
+namespace orgQhull {
+
+#//!\name Used here
+
+#//!\name Defined here
+ //! QhullVertexSet -- a set of Qhull Vertices, as a C++ class.
+ //! See Qhull
+ class QhullVertexSet;
+ typedef QhullSetIterator<QhullVertex> QhullVertexSetIterator;
+
+class QhullVertexSet : public QhullSet<QhullVertex> {
+
+private:
+#//!\name Fields
+ bool qhsettemp_defined; //! Set was allocated with qh_settemp()
+
+public:
+#//!\name Constructor
+ QhullVertexSet(const Qhull &q, setT *s) : QhullSet<QhullVertex>(q, s), qhsettemp_defined(false) {}
+ QhullVertexSet(const Qhull &q, facetT *facetlist, setT *facetset, bool allfacets);
+ //Conversion from setT* is not type-safe. Implicit conversion for void* to T
+ QhullVertexSet(QhullQh *qqh, setT *s) : QhullSet<QhullVertex>(qqh, s), qhsettemp_defined(false) {}
+ QhullVertexSet(QhullQh *qqh, facetT *facetlist, setT *facetset, bool allfacets);
+ //Copy constructor and assignment copies pointer but not contents. Throws error if qhsettemp_defined. Needed for return by value.
+ QhullVertexSet(const QhullVertexSet &other);
+ QhullVertexSet & operator=(const QhullVertexSet &other);
+ ~QhullVertexSet();
+
+private: //!Default constructor disabled. Will implement allocation later
+ QhullVertexSet();
+public:
+
+#//!\name Destructor
+ void freeQhSetTemp();
+
+#//!\name Conversion
+#ifndef QHULL_NO_STL
+ std::vector<QhullVertex> toStdVector() const;
+#endif //QHULL_NO_STL
+#ifdef QHULL_USES_QT
+ QList<QhullVertex> toQList() const;
+#endif //QHULL_USES_QT
+
+#//!\name IO
+ struct PrintVertexSet{
+ const QhullVertexSet *vertex_set;
+ const char * print_message; //!< non-null message
+
+ PrintVertexSet(const char *message, const QhullVertexSet *s) : vertex_set(s), print_message(message) {}
+ };//PrintVertexSet
+ const PrintVertexSet print(const char *message) const { return PrintVertexSet(message, this); }
+
+ struct PrintIdentifiers{
+ const QhullVertexSet *vertex_set;
+ const char * print_message; //!< non-null message
+ PrintIdentifiers(const char *message, const QhullVertexSet *s) : vertex_set(s), print_message(message) {}
+ };//PrintIdentifiers
+ PrintIdentifiers printIdentifiers(const char *message) const { return PrintIdentifiers(message, this); }
+
+};//class QhullVertexSet
+
+}//namespace orgQhull
+
+#//!\name Global
+
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet::PrintVertexSet &pr);
+std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet::PrintIdentifiers &p);
+inline std::ostream &operator<<(std::ostream &os, const orgQhull::QhullVertexSet &vs) { os << vs.print(""); return os; }
+
+#endif // QHULLVERTEXSET_H
diff --git a/xs/src/qhull/src/libqhullcpp/RboxPoints.cpp b/xs/src/qhull/src/libqhullcpp/RboxPoints.cpp
new file mode 100644
index 000000000..d7acd9fce
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/RboxPoints.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/RboxPoints.cpp#3 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#include "libqhullcpp/RboxPoints.h"
+
+#include "libqhullcpp/QhullError.h"
+
+#include <iostream>
+
+using std::cerr;
+using std::endl;
+using std::istream;
+using std::ostream;
+using std::ostringstream;
+using std::string;
+using std::vector;
+using std::ws;
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#pragma warning( disable : 4996) // function was declared deprecated(strcpy, localtime, etc.)
+#endif
+
+namespace orgQhull {
+
+#//! RboxPoints -- generate random PointCoordinates for qhull (rbox)
+
+
+#//!\name Constructors
+RboxPoints::
+RboxPoints()
+: PointCoordinates("rbox")
+, rbox_new_count(0)
+, rbox_status(qh_ERRnone)
+, rbox_message()
+{
+ allocateQhullQh();
+}
+
+//! Allocate and generate points according to rboxCommand
+//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
+//! Same as appendPoints()
+RboxPoints::
+RboxPoints(const char *rboxCommand)
+: PointCoordinates("rbox")
+, rbox_new_count(0)
+, rbox_status(qh_ERRnone)
+, rbox_message()
+{
+ allocateQhullQh();
+ // rbox arguments added to comment() via qh_rboxpoints > qh_fprintf_rbox
+ appendPoints(rboxCommand);
+}
+
+RboxPoints::
+~RboxPoints()
+{
+ delete qh();
+ resetQhullQh(0);
+}
+
+// RboxPoints and qh_rboxpoints has several fields in qhT (rbox_errexit..cpp_object)
+// It shares last_random with qh_rand and qh_srand
+// The other fields are unused
+void RboxPoints::
+allocateQhullQh()
+{
+ QHULL_LIB_CHECK /* Check for compatible library */
+ resetQhullQh(new QhullQh);
+}//allocateQhullQh
+
+#//!\name Messaging
+
+void RboxPoints::
+clearRboxMessage()
+{
+ rbox_status= qh_ERRnone;
+ rbox_message.clear();
+}//clearRboxMessage
+
+std::string RboxPoints::
+rboxMessage() const
+{
+ if(rbox_status!=qh_ERRnone){
+ return rbox_message;
+ }
+ if(isEmpty()){
+ return "rbox warning: no points generated\n";
+ }
+ return "rbox: OK\n";
+}//rboxMessage
+
+int RboxPoints::
+rboxStatus() const
+{
+ return rbox_status;
+}
+
+bool RboxPoints::
+hasRboxMessage() const
+{
+ return (rbox_status!=qh_ERRnone);
+}
+
+#//!\name Methods
+
+//! Appends points as defined by rboxCommand
+//! Appends rboxCommand to comment
+//! For rbox commands, see http://www.qhull.org/html/rbox.htm or html/rbox.htm
+void RboxPoints::
+appendPoints(const char *rboxCommand)
+{
+ string s("rbox ");
+ s += rboxCommand;
+ char *command= const_cast<char*>(s.c_str());
+ if(qh()->cpp_object){
+ throw QhullError(10001, "Qhull error: conflicting user of cpp_object for RboxPoints::appendPoints() or corrupted qh_qh");
+ }
+ if(extraCoordinatesCount()!=0){
+ throw QhullError(10067, "Qhull error: Extra coordinates (%d) prior to calling RboxPoints::appendPoints. Was %s", extraCoordinatesCount(), 0, 0.0, comment().c_str());
+ }
+ countT previousCount= count();
+ qh()->cpp_object= this; // for qh_fprintf_rbox()
+ int status= qh_rboxpoints(qh(), command);
+ qh()->cpp_object= 0;
+ if(rbox_status==qh_ERRnone){
+ rbox_status= status;
+ }
+ if(rbox_status!=qh_ERRnone){
+ throw QhullError(rbox_status, rbox_message);
+ }
+ if(extraCoordinatesCount()!=0){
+ throw QhullError(10002, "Qhull error: extra coordinates (%d) for PointCoordinates (%x)", extraCoordinatesCount(), 0, 0.0, coordinates());
+ }
+ if(previousCount+newCount()!=count()){
+ throw QhullError(10068, "Qhull error: rbox specified %d points but got %d points for command '%s'", newCount(), count()-previousCount, 0.0, comment().c_str());
+ }
+}//appendPoints
+
+}//namespace orgQhull
+
+#//!\name Global functions
+
+/*-<a href="qh-user.htm#TOC"
+>-------------------------------</a><a name="qh_fprintf_rbox">-</a>
+
+ qh_fprintf_rbox(qh, fp, msgcode, format, list of args )
+ fp is ignored (replaces qh_fprintf_rbox() in userprintf_rbox.c)
+ cpp_object == RboxPoints
+
+notes:
+ only called from qh_rboxpoints()
+ same as fprintf() and Qhull.qh_fprintf()
+ fgets() is not trapped like fprintf()
+ Do not throw errors from here. Use qh_errexit_rbox;
+ A similar technique can be used for qh_fprintf to capture all of its output
+*/
+extern "C"
+void qh_fprintf_rbox(qhT *qh, FILE*, int msgcode, const char *fmt, ... ) {
+ va_list args;
+
+ using namespace orgQhull;
+
+ if(!qh->cpp_object){
+ qh_errexit_rbox(qh, 10072);
+ }
+ RboxPoints *out= reinterpret_cast<RboxPoints *>(qh->cpp_object);
+ va_start(args, fmt);
+ if(msgcode<MSG_OUTPUT){
+ char newMessage[MSG_MAXLEN];
+ // RoadError provides the message tag
+ vsnprintf(newMessage, sizeof(newMessage), fmt, args);
+ out->rbox_message += newMessage;
+ if(out->rbox_status<MSG_ERROR || out->rbox_status>=MSG_STDERR){
+ out->rbox_status= msgcode;
+ }
+ va_end(args);
+ return;
+ }
+ switch(msgcode){
+ case 9391:
+ case 9392:
+ out->rbox_message += "RboxPoints error: options 'h', 'n' not supported.\n";
+ qh_errexit_rbox(qh, 10010);
+ /* never returns */
+ case 9393: // FIXUP QH11026 countT vs. int
+ {
+ int dimension= va_arg(args, int);
+ string command(va_arg(args, char*));
+ countT count= va_arg(args, countT);
+ out->setDimension(dimension);
+ out->appendComment(" \"");
+ out->appendComment(command.substr(command.find(' ')+1));
+ out->appendComment("\"");
+ out->setNewCount(count);
+ out->reservePoints();
+ }
+ break;
+ case 9407:
+ *out << va_arg(args, int);
+ // fall through
+ case 9405:
+ *out << va_arg(args, int);
+ // fall through
+ case 9403:
+ *out << va_arg(args, int);
+ break;
+ case 9408:
+ *out << va_arg(args, double);
+ // fall through
+ case 9406:
+ *out << va_arg(args, double);
+ // fall through
+ case 9404:
+ *out << va_arg(args, double);
+ break;
+ }
+ va_end(args);
+} /* qh_fprintf_rbox */
+
diff --git a/xs/src/qhull/src/libqhullcpp/RboxPoints.h b/xs/src/qhull/src/libqhullcpp/RboxPoints.h
new file mode 100644
index 000000000..e8ec72b14
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/RboxPoints.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/RboxPoints.h#4 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef RBOXPOINTS_H
+#define RBOXPOINTS_H
+
+#include "libqhull_r/qhull_ra.h"
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/PointCoordinates.h"
+
+#include <stdarg.h>
+#include <string>
+#include <vector>
+#include <istream>
+#include <ostream>
+#include <sstream>
+
+namespace orgQhull {
+
+#//!\name Defined here
+ //! RboxPoints -- generate random PointCoordinates for Qhull
+ class RboxPoints;
+
+class RboxPoints : public PointCoordinates {
+
+private:
+#//!\name Fields and friends
+ //! PointCoordinates.qh() is owned by RboxPoints
+ countT rbox_new_count; //! Number of points for PointCoordinates
+ int rbox_status; //! error status from rboxpoints. qh_ERRnone if none.
+ std::string rbox_message; //! stderr from rboxpoints
+
+ // '::' is required for friend references
+ friend void ::qh_fprintf_rbox(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... );
+
+public:
+#//!\name Construct
+ RboxPoints();
+ explicit RboxPoints(const char *rboxCommand);
+ ~RboxPoints();
+private: // Disable copy constructor and assignment. RboxPoints owns QhullQh.
+ RboxPoints(const RboxPoints &);
+ RboxPoints &operator=(const RboxPoints &);
+private:
+ void allocateQhullQh();
+
+public:
+#//!\name GetSet
+ void clearRboxMessage();
+ countT newCount() const { return rbox_new_count; }
+ std::string rboxMessage() const;
+ int rboxStatus() const;
+ bool hasRboxMessage() const;
+ void setNewCount(countT pointCount) { QHULL_ASSERT(pointCount>=0); rbox_new_count= pointCount; }
+
+#//!\name Modify
+ void appendPoints(const char* rboxCommand);
+ using PointCoordinates::appendPoints;
+ void reservePoints() { reserveCoordinates((count()+newCount())*dimension()); }
+};//class RboxPoints
+
+}//namespace orgQhull
+
+#endif // RBOXPOINTS_H
diff --git a/xs/src/qhull/src/libqhullcpp/RoadError.cpp b/xs/src/qhull/src/libqhullcpp/RoadError.cpp
new file mode 100644
index 000000000..1d41ec1bc
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/RoadError.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/RoadError.cpp#2 $$Change: 2066 $
+** $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! RoadError -- All exceptions thrown by Qhull are RoadErrors
+#//! Do not throw RoadError's from destructors. Use e.logError() instead.
+
+#include "libqhullcpp/RoadError.h"
+
+#include <string>
+#include <sstream>
+#include <iostream>
+
+using std::cerr;
+using std::cout;
+using std::string;
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#endif
+
+namespace orgQhull {
+
+#//!\name Class fields
+
+//! Identifies error messages from Qhull and Road for web searches.
+//! See QhullError.h#QHULLlastError and user.h#MSG_ERROR
+const char * RoadError::
+ROADtag= "QH";
+
+std::ostringstream RoadError::
+global_log;
+
+#//!\name Constructor
+
+RoadError::
+RoadError()
+: error_code(0)
+, log_event()
+, error_message()
+{ }
+
+RoadError::
+RoadError(const RoadError &other)
+: error_code(other.error_code)
+, log_event(other.log_event)
+, error_message(other.error_message)
+{
+}//copy construct
+
+RoadError::
+RoadError(int code, const std::string &message)
+: error_code(code)
+, log_event(message.c_str())
+, error_message(log_event.toString(ROADtag, error_code))
+{
+ log_event.cstr_1= error_message.c_str(); // overwrites initial value
+}
+
+RoadError::
+RoadError(int code, const char *fmt)
+: error_code(code)
+, log_event(fmt)
+, error_message()
+{ }
+
+RoadError::
+RoadError(int code, const char *fmt, int d)
+: error_code(code)
+, log_event(fmt, d)
+, error_message()
+{ }
+
+RoadError::
+RoadError(int code, const char *fmt, int d, int d2)
+: error_code(code)
+, log_event(fmt, d, d2)
+, error_message()
+{ }
+
+RoadError::
+RoadError(int code, const char *fmt, int d, int d2, float f)
+: error_code(code)
+, log_event(fmt, d, d2, f)
+, error_message()
+{ }
+
+RoadError::
+RoadError(int code, const char *fmt, int d, int d2, float f, const char *s)
+: error_code(code)
+, log_event(fmt, d, d2, f, s)
+, error_message(log_event.toString(ROADtag, code)) // char * may go out of scope
+{ }
+
+RoadError::
+RoadError(int code, const char *fmt, int d, int d2, float f, const void *x)
+: error_code(code)
+, log_event(fmt, d, d2, f, x)
+, error_message()
+{ }
+
+RoadError::
+RoadError(int code, const char *fmt, int d, int d2, float f, int i)
+: error_code(code)
+, log_event(fmt, d, d2, f, i)
+, error_message()
+{ }
+
+RoadError::
+RoadError(int code, const char *fmt, int d, int d2, float f, long long i)
+: error_code(code)
+, log_event(fmt, d, d2, f, i)
+, error_message()
+{ }
+
+RoadError::
+RoadError(int code, const char *fmt, int d, int d2, float f, double e)
+: error_code(code)
+, log_event(fmt, d, d2, f, e)
+, error_message()
+{ }
+
+RoadError & RoadError::
+operator=(const RoadError &other)
+{
+ error_code= other.error_code;
+ error_message= other.error_message;
+ log_event= other.log_event;
+ return *this;
+}//operator=
+
+#//!\name Virtual
+const char * RoadError::
+what() const throw()
+{
+ if(error_message.empty()){
+ error_message= log_event.toString(ROADtag, error_code);
+ }
+ return error_message.c_str();
+}//what
+
+#//!\name Updates
+
+//! Log error instead of throwing it.
+//! Not reentrant, so avoid using it if possible
+//!\todo Redesign with a thread-local stream or a reentrant ostringstream
+void RoadError::
+logErrorLastResort() const
+{
+ global_log << what() << endl;
+}//logError
+
+
+}//namespace orgQhull
+
diff --git a/xs/src/qhull/src/libqhullcpp/RoadError.h b/xs/src/qhull/src/libqhullcpp/RoadError.h
new file mode 100644
index 000000000..1c9f6cdd5
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/RoadError.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/RoadError.h#4 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef ROADERROR_H
+#define ROADERROR_H
+
+#include "libqhull_r/user_r.h" /* for QHULL_CRTDBG */
+#include "libqhullcpp/RoadLogEvent.h"
+
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+
+using std::endl;
+
+namespace orgQhull {
+
+#//!\name Defined here
+ //! RoadError -- Report and log errors
+ //! See discussion in Saylan, G., "Practical C++ error handling in hybrid environments," Dr. Dobb's Journal, p. 50-55, March 2007.
+ //! He uses an auto_ptr to track a stringstream. It constructs a string on the fly. RoadError uses the copy constructor to transform RoadLogEvent into a string
+ class RoadError;
+
+class RoadError : public std::exception {
+
+private:
+#//!\name Fields
+ int error_code; //! Non-zero code (not logged), maybe returned as program status
+ RoadLogEvent log_event; //! Format string w/ arguments
+ mutable std::string error_message; //! Formated error message. Must be after log_event.
+
+#//!\name Class fields
+ static const char * ROADtag;
+ static std::ostringstream global_log; //!< May be replaced with any ostream object
+ //!< Not reentrant -- only used by RoadError::logErrorLastResort()
+
+public:
+#//!\name Constants
+
+#//!\name Constructors
+ RoadError();
+ RoadError(const RoadError &other); //! Called on throw, generates error_message
+ RoadError(int code, const std::string &message);
+ RoadError(int code, const char *fmt);
+ RoadError(int code, const char *fmt, int d);
+ RoadError(int code, const char *fmt, int d, int d2);
+ RoadError(int code, const char *fmt, int d, int d2, float f);
+ RoadError(int code, const char *fmt, int d, int d2, float f, const char *s);
+ RoadError(int code, const char *fmt, int d, int d2, float f, const void *x);
+ RoadError(int code, const char *fmt, int d, int d2, float f, int i);
+ RoadError(int code, const char *fmt, int d, int d2, float f, long long i);
+ RoadError(int code, const char *fmt, int d, int d2, float f, double e);
+
+ RoadError & operator=(const RoadError &other);
+ ~RoadError() throw() {};
+
+#//!\name Class methods
+
+ static void clearGlobalLog() { global_log.seekp(0); }
+ static bool emptyGlobalLog() { return global_log.tellp()<=0; }
+ static const char *stringGlobalLog() { return global_log.str().c_str(); }
+
+#//!\name Virtual
+ virtual const char *what() const throw();
+
+#//!\name GetSet
+ bool isValid() const { return log_event.isValid(); }
+ int errorCode() const { return error_code; };
+ // FIXUP QH11021 should RoadError provide errorMessage(). Currently what()
+ RoadLogEvent roadLogEvent() const { return log_event; };
+
+#//!\name Update
+ void logErrorLastResort() const;
+};//class RoadError
+
+}//namespace orgQhull
+
+#//!\name Global
+
+inline std::ostream & operator<<(std::ostream &os, const orgQhull::RoadError &e) { return os << e.what(); }
+
+#endif // ROADERROR_H
diff --git a/xs/src/qhull/src/libqhullcpp/RoadLogEvent.cpp b/xs/src/qhull/src/libqhullcpp/RoadLogEvent.cpp
new file mode 100644
index 000000000..9a9cf5960
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/RoadLogEvent.cpp
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/RoadLogEvent.cpp#3 $$Change: 2066 $
+** $Date: 2016/01/18 $$Author: bbarber $
+**
+****************************************************************************/
+
+#//! RoadLogEvent -- All exceptions thrown by Qhull are RoadErrors
+
+#include "libqhullcpp/RoadLogEvent.h"
+
+#include <string>
+#include <sstream>
+#include <iostream>
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::string;
+
+#ifdef _MSC_VER // Microsoft Visual C++ -- warning level 4
+#endif
+
+namespace orgQhull {
+
+#//!\name Conversion
+string RoadLogEvent::
+toString(const char *tag, int code) const
+{
+ ostringstream os;
+ if(tag && code){
+ os << tag << code;
+ if(format_string){
+ os << " ";
+ }
+ }
+ if(!format_string){
+ return os.str();
+ }
+ const char *s= format_string;
+ int dCount= 0; // Count of %d
+ int fCount= 0; // Count of %f
+ char extraCode= '\0';
+ while(*s){
+ if(*s!='%'){
+ os << *s++;
+ }else{
+ char c= *++s;
+ s++;
+ switch(c){
+ case 'd':
+ if(++dCount>2){
+ os << " ERROR_three_%d_in_format ";
+ }else if(dCount==2){
+ os << int_2;
+ }else{
+ os << int_1;
+ }
+ break;
+ case 'e':
+ if(firstExtraCode(os, c, &extraCode)){
+ os << double_1;
+ }
+ break;
+ case 'f':
+ if(++fCount>1){
+ os << " ERROR_two_%f_in_format ";
+ }else{
+ os << float_1;
+ }
+ break;
+ case 'i':
+ if(firstExtraCode(os, c, &extraCode)){
+ os << int64_1;
+ }
+ break;
+ case 's':
+ if(firstExtraCode(os, c, &extraCode)){
+ os << cstr_1;
+ }
+ break;
+ case 'u':
+ if(firstExtraCode(os, c, &extraCode)){
+ os << "0x" << std::hex << int64_1 << std::dec;
+ }
+ break;
+ case 'x':
+ if(firstExtraCode(os, c, &extraCode)){
+ os << void_1;
+ }
+ break;
+ case '%':
+ os << c;
+ break;
+ default:
+ os << " ERROR_%" << c << "_not_defined_in_format";
+ break;
+ }
+ }
+ }
+ if(s[-1]!='\n'){
+ os << endl;
+ }
+ return os.str();
+}//toString
+
+#//!\name Class helpers (static)
+
+//! True if this char is the first extra code
+bool RoadLogEvent::
+firstExtraCode(std::ostream &os, char c, char *extraCode){
+ if(*extraCode){
+ os << " ERROR_%" << *extraCode << "_and_%" << c << "_in_format ";
+ return false;
+ }
+ *extraCode= c;
+ return true;
+}//firstExtraCode
+
+}//namespace orgQhull
+
diff --git a/xs/src/qhull/src/libqhullcpp/RoadLogEvent.h b/xs/src/qhull/src/libqhullcpp/RoadLogEvent.h
new file mode 100644
index 000000000..7c4cfba0d
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/RoadLogEvent.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/RoadLogEvent.h#1 $$Change: 1981 $
+** $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef ROADLOGEVENT_H
+#define ROADLOGEVENT_H
+
+#include <ostream>
+#include <stdexcept>
+#include <string>
+
+namespace orgQhull {
+
+#//!\name Defined here
+ //! RoadLogEvent -- Record an event for the RoadLog
+ struct RoadLogEvent;
+
+struct RoadLogEvent {
+
+public:
+#//!\name Fields
+ const char * format_string; //! Format string (a literal with format codes, for logging)
+ int int_1; //! Integer argument (%d, for logging)
+ int int_2; //! Integer argument (%d, for logging)
+ float float_1; //! Float argument (%f, for logging)
+ union { //! One additional argument (for logging)
+ const char *cstr_1; //! Cstr argument (%s) -- type checked at construct-time
+ const void *void_1; //! Void* argument (%x) -- Use upper-case codes for object types
+ long long int64_1; //! signed int64 (%i). Ambiguous if unsigned is also defined.
+ double double_1; //! Double argument (%e)
+ };
+
+#//!\name Constants
+
+#//!\name Constructors
+ RoadLogEvent() : format_string(0), int_1(0), int_2(0), float_1(0), int64_1(0) {};
+ explicit RoadLogEvent(const char *fmt) : format_string(fmt), int_1(0), int_2(0), float_1(0), int64_1(0) {};
+ RoadLogEvent(const char *fmt, int d) : format_string(fmt), int_1(d), int_2(0), float_1(0), int64_1(0) {};
+ RoadLogEvent(const char *fmt, int d, int d2) : format_string(fmt), int_1(d), int_2(d2), float_1(0), int64_1(0) {};
+ RoadLogEvent(const char *fmt, int d, int d2, float f) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(0) {};
+ RoadLogEvent(const char *fmt, int d, int d2, float f, const char *s) : format_string(fmt), int_1(d), int_2(d2), float_1(f), cstr_1(s) {};
+ RoadLogEvent(const char *fmt, int d, int d2, float f, const void *x) : format_string(fmt), int_1(d), int_2(d2), float_1(f), void_1(x) {};
+ RoadLogEvent(const char *fmt, int d, int d2, float f, int i) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(i) {};
+ RoadLogEvent(const char *fmt, int d, int d2, float f, long long i) : format_string(fmt), int_1(d), int_2(d2), float_1(f), int64_1(i) {};
+ RoadLogEvent(const char *fmt, int d, int d2, float f, double g) : format_string(fmt), int_1(d), int_2(d2), float_1(f), double_1(g) {};
+ ~RoadLogEvent() {};
+ //! Default copy constructor and assignment
+
+#//!\name GetSet
+ bool isValid() const { return format_string!=0; }
+ int int1() const { return int_1; };
+ int int2() const { return int_2; };
+ float float1() const { return float_1; };
+ const char * format() const { return format_string; };
+ const char * cstr1() const { return cstr_1; };
+ const void * void1() const { return void_1; };
+ long long int64() const { return int64_1; };
+ double double1() const { return double_1; };
+
+#//!\name Conversion
+
+ std::string toString(const char* tag, int code) const;
+
+private:
+#//!\name Class helpers
+ static bool firstExtraCode(std::ostream &os, char c, char *extraCode);
+
+
+};//class RoadLogEvent
+
+}//namespace orgQhull
+
+#endif // ROADLOGEVENT_H
diff --git a/xs/src/qhull/src/libqhullcpp/functionObjects.h b/xs/src/qhull/src/libqhullcpp/functionObjects.h
new file mode 100644
index 000000000..3645c0713
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/functionObjects.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/functionObjects.h#1 $$Change: 1981 $
+** $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef QHFUNCTIONOBJECTS_H
+#define QHFUNCTIONOBJECTS_H
+
+#include <stdlib.h>
+#include <math.h>
+
+namespace orgQhull {
+
+#//!\name Defined here
+
+ //! Sum of absolute values of the elements in a container
+ class AbsoluteSumOf;
+ //! Sum of the elements in a container
+ class SumOf;
+ //! Sum of squares of the elements in a container
+ class SumSquaresOf;
+
+#//!\name Class
+
+//! Absolute sum of the elements in a container
+class AbsoluteSumOf
+{
+private:
+ double sum;
+public:
+ inline AbsoluteSumOf() : sum(0.0) {}
+ inline void operator()(double v) { sum += fabs(v); }
+ inline operator double() { return sum; }
+};//AbsoluteSumOf
+
+//! Sum of the elements in a container
+class SumOf
+{
+private:
+ double sum;
+public:
+ inline SumOf() : sum(0.0) {}
+ inline void operator()(double v) { sum += v; }
+ inline operator double() { return sum; }
+};//SumOf
+
+
+//! Sum of squares of the elements in a container
+class SumSquaresOf
+{
+private:
+ double sum;
+public:
+ inline SumSquaresOf() : sum(0.0) {}
+ inline void operator()(double v) { sum += v*v; }
+ inline operator double() { return sum; }
+};//SumSquaresOf
+
+
+}//orgQhull
+
+
+#endif //QHFUNCTIONOBJECTS_H
+
diff --git a/xs/src/qhull/src/libqhullcpp/libqhullcpp.pro b/xs/src/qhull/src/libqhullcpp/libqhullcpp.pro
new file mode 100644
index 000000000..89b967bef
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/libqhullcpp.pro
@@ -0,0 +1,71 @@
+# -------------------------------------------------
+# libqhullcpp.pro -- Qt project for Qhull cpp shared library
+#
+# It uses reentrant Qhull
+# -------------------------------------------------
+
+include(../qhull-warn.pri)
+
+DESTDIR = ../../lib
+TEMPLATE = lib
+# Do not create libqhullcpp as a shared library. Qhull C++ classes may change layout and size.
+CONFIG += staticlib warn_on
+CONFIG -= qt rtti
+build_pass:CONFIG(debug, debug|release):{
+ TARGET = qhullcpp_d
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release):{
+ TARGET = qhullcpp
+ OBJECTS_DIR = Release
+}
+MOC_DIR = moc
+
+INCLUDEPATH += ../../src
+INCLUDEPATH += $$PWD # for MOC_DIR
+
+CONFIG += qhull_warn_shadow qhull_warn_conversion
+
+SOURCES += ../libqhullcpp/Coordinates.cpp
+SOURCES += ../libqhullcpp/PointCoordinates.cpp
+SOURCES += ../libqhullcpp/Qhull.cpp
+SOURCES += ../libqhullcpp/QhullFacet.cpp
+SOURCES += ../libqhullcpp/QhullFacetList.cpp
+SOURCES += ../libqhullcpp/QhullFacetSet.cpp
+SOURCES += ../libqhullcpp/QhullHyperplane.cpp
+SOURCES += ../libqhullcpp/QhullPoint.cpp
+SOURCES += ../libqhullcpp/QhullPoints.cpp
+SOURCES += ../libqhullcpp/QhullPointSet.cpp
+SOURCES += ../libqhullcpp/QhullQh.cpp
+SOURCES += ../libqhullcpp/QhullRidge.cpp
+SOURCES += ../libqhullcpp/QhullSet.cpp
+SOURCES += ../libqhullcpp/QhullStat.cpp
+SOURCES += ../libqhullcpp/QhullVertex.cpp
+SOURCES += ../libqhullcpp/QhullVertexSet.cpp
+SOURCES += ../libqhullcpp/RboxPoints.cpp
+SOURCES += ../libqhullcpp/RoadError.cpp
+SOURCES += ../libqhullcpp/RoadLogEvent.cpp
+
+HEADERS += ../libqhullcpp/Coordinates.h
+HEADERS += ../libqhullcpp/functionObjects.h
+HEADERS += ../libqhullcpp/PointCoordinates.h
+HEADERS += ../libqhullcpp/Qhull.h
+HEADERS += ../libqhullcpp/QhullError.h
+HEADERS += ../libqhullcpp/QhullFacet.h
+HEADERS += ../libqhullcpp/QhullFacetList.h
+HEADERS += ../libqhullcpp/QhullFacetSet.h
+HEADERS += ../libqhullcpp/QhullHyperplane.h
+HEADERS += ../libqhullcpp/QhullIterator.h
+HEADERS += ../libqhullcpp/QhullLinkedList.h
+HEADERS += ../libqhullcpp/QhullPoint.h
+HEADERS += ../libqhullcpp/QhullPoints.h
+HEADERS += ../libqhullcpp/QhullPointSet.h
+HEADERS += ../libqhullcpp/QhullQh.h
+HEADERS += ../libqhullcpp/QhullRidge.h
+HEADERS += ../libqhullcpp/QhullSet.h
+HEADERS += ../libqhullcpp/QhullSets.h
+HEADERS += ../libqhullcpp/QhullStat.h
+HEADERS += ../libqhullcpp/QhullVertex.h
+HEADERS += ../libqhullcpp/QhullVertexSet.h
+HEADERS += ../libqhullcpp/RboxPoints.h
+HEADERS += ../libqhullcpp/RoadError.h
+HEADERS += ../libqhullcpp/RoadLogEvent.h
diff --git a/xs/src/qhull/src/libqhullcpp/qt-qhull.cpp b/xs/src/qhull/src/libqhullcpp/qt-qhull.cpp
new file mode 100644
index 000000000..895f591a8
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/qt-qhull.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/libqhullcpp/qt-qhull.cpp#1 $$Change: 1981 $
+** $DateTime: 2015/09/28 20:26:32 $$Author: bbarber $
+**
+****************************************************************************/
+
+#include <QList>
+#include "qhulltest/RoadTest.h"
+
+#ifndef QHULL_USES_QT
+#define QHULL_USES_QT 1
+#endif
+
+#include "Coordinates.h"
+#include "QhullFacetList.h"
+#include "QhullFacetSet.h"
+#include "QhullHyperplane.h"
+#include "QhullPoint.h"
+#include "QhullPoints.h"
+#include "QhullPointSet.h"
+#include "QhullVertex.h"
+#include "QhullVertexSet.h"
+
+namespace orgQhull {
+
+#//!\name Conversions
+
+QList<coordT> Coordinates::
+toQList() const
+{
+ CoordinatesIterator i(*this);
+ QList<coordT> cs;
+ while(i.hasNext()){
+ cs.append(i.next());
+ }
+ return cs;
+}//toQList
+
+QList<QhullFacet> QhullFacetList::
+toQList() const
+{
+ QhullLinkedListIterator<QhullFacet> i(*this);
+ QList<QhullFacet> vs;
+ while(i.hasNext()){
+ QhullFacet f= i.next();
+ if(isSelectAll() || f.isGood()){
+ vs.append(f);
+ }
+ }
+ return vs;
+}//toQList
+
+//! Same as PrintVertices
+QList<QhullVertex> QhullFacetList::
+vertices_toQList() const
+{
+ QList<QhullVertex> vs;
+ QhullVertexSet qvs(qh(), first().getFacetT(), NULL, isSelectAll());
+ for(QhullVertexSet::iterator i=qvs.begin(); i!=qvs.end(); ++i){
+ vs.push_back(*i);
+ }
+ return vs;
+}//vertices_toQList
+
+QList<QhullFacet> QhullFacetSet::
+toQList() const
+{
+ QhullSetIterator<QhullFacet> i(*this);
+ QList<QhullFacet> vs;
+ while(i.hasNext()){
+ QhullFacet f= i.next();
+ if(isSelectAll() || f.isGood()){
+ vs.append(f);
+ }
+ }
+ return vs;
+}//toQList
+
+#ifdef QHULL_USES_QT
+QList<coordT> QhullHyperplane::
+toQList() const
+{
+ QhullHyperplaneIterator i(*this);
+ QList<coordT> fs;
+ while(i.hasNext()){
+ fs.append(i.next());
+ }
+ fs.append(hyperplane_offset);
+ return fs;
+}//toQList
+#endif //QHULL_USES_QT
+
+QList<coordT> QhullPoint::
+toQList() const
+{
+ QhullPointIterator i(*this);
+ QList<coordT> vs;
+ while(i.hasNext()){
+ vs.append(i.next());
+ }
+ return vs;
+}//toQList
+
+QList<QhullPoint> QhullPoints::
+toQList() const
+{
+ QhullPointsIterator i(*this);
+ QList<QhullPoint> vs;
+ while(i.hasNext()){
+ vs.append(i.next());
+ }
+ return vs;
+}//toQList
+
+/******
+QList<QhullPoint> QhullPointSet::
+toQList() const
+{
+ QhullPointSetIterator i(*this);
+ QList<QhullPoint> vs;
+ while(i.hasNext()){
+ vs.append(i.next());
+ }
+ return vs;
+}//toQList
+*/
+}//orgQhull
+
diff --git a/xs/src/qhull/src/libqhullcpp/usermem_r-cpp.cpp b/xs/src/qhull/src/libqhullcpp/usermem_r-cpp.cpp
new file mode 100644
index 000000000..bb9534d09
--- /dev/null
+++ b/xs/src/qhull/src/libqhullcpp/usermem_r-cpp.cpp
@@ -0,0 +1,93 @@
+/*<html><pre> -<a href="qh-user_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ usermem_r-cpp.cpp
+
+ Redefine qh_exit() as 'throw std::runtime_error("QH10003 ...")'
+
+ This file is not included in the Qhull builds.
+
+ qhull_r calls qh_exit() when qh_errexit() is not available. For example,
+ it calls qh_exit() if you linked the wrong qhull library.
+
+ The C++ interface avoids most of the calls to qh_exit().
+
+ If needed, include usermem_r-cpp.o before libqhullstatic_r.a. You may need to
+ override duplicate symbol errors (e.g. /FORCE:MULTIPLE for DevStudio). It
+ may produce a warning about throwing an error from C code.
+*/
+
+extern "C" {
+ void qh_exit(int exitcode);
+}
+
+#include <stdexcept>
+#include <stdlib.h>
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="qh_exit">-</a>
+
+ qh_exit( exitcode )
+ exit program
+
+ notes:
+ same as exit()
+*/
+void qh_exit(int exitcode) {
+ exitcode= exitcode;
+ throw std::runtime_error("QH10003 Qhull error. See stderr or errfile.");
+} /* exit */
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="qh_fprintf_stderr">-</a>
+
+ qh_fprintf_stderr( msgcode, format, list of args )
+ fprintf to stderr with msgcode (non-zero)
+
+ notes:
+ qh_fprintf_stderr() is called when qh->ferr is not defined, usually due to an initialization error
+
+ It is typically followed by qh_errexit().
+
+ Redefine this function to avoid using stderr
+
+ Use qh_fprintf [userprintf_r.c] for normal printing
+*/
+void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
+ va_list args;
+
+ va_start(args, fmt);
+ if(msgcode)
+ fprintf(stderr, "QH%.4d ", msgcode);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+} /* fprintf_stderr */
+
+/*-<a href="qh-user_r.htm#TOC"
+>-------------------------------</a><a name="qh_free">-</a>
+
+ qh_free(qhT *qh, mem )
+ free memory
+
+ notes:
+ same as free()
+ No calls to qh_errexit()
+*/
+void qh_free(void *mem) {
+ free(mem);
+} /* free */
+
+/*-<a href="qh-user_r.htm#TOC"
+ >-------------------------------</a><a name="qh_malloc">-</a>
+
+ qh_malloc( mem )
+ allocate memory
+
+ notes:
+ same as malloc()
+*/
+void *qh_malloc(size_t size) {
+ return malloc(size);
+} /* malloc */
+
+
diff --git a/xs/src/qhull/src/libqhullstatic/libqhullstatic.pro b/xs/src/qhull/src/libqhullstatic/libqhullstatic.pro
new file mode 100644
index 000000000..1a516db73
--- /dev/null
+++ b/xs/src/qhull/src/libqhullstatic/libqhullstatic.pro
@@ -0,0 +1,19 @@
+# -------------------------------------------------
+# libqhullstatic.pro -- Qt project for Qhull static library
+# Built with qh_QHpointer=0. See libqhullp.pro
+# -------------------------------------------------
+
+include(../qhull-warn.pri)
+include(../qhull-libqhull-src.pri)
+
+DESTDIR = ../../lib
+TEMPLATE = lib
+CONFIG += staticlib warn_on
+CONFIG -= qt
+build_pass:CONFIG(debug, debug|release):{
+ TARGET = qhullstatic_d
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release):{
+ TARGET = qhullstatic
+ OBJECTS_DIR = Release
+}
diff --git a/xs/src/qhull/src/libqhullstatic_r/libqhullstatic_r.pro b/xs/src/qhull/src/libqhullstatic_r/libqhullstatic_r.pro
new file mode 100644
index 000000000..2f5bf4d07
--- /dev/null
+++ b/xs/src/qhull/src/libqhullstatic_r/libqhullstatic_r.pro
@@ -0,0 +1,21 @@
+# -------------------------------------------------
+# libqhullstatic_r.pro -- Qt project for Qhull static library
+#
+# It uses reeentrant Qhull
+# -------------------------------------------------
+
+include(../qhull-warn.pri)
+
+DESTDIR = ../../lib
+TEMPLATE = lib
+CONFIG += staticlib warn_on
+CONFIG -= qt
+build_pass:CONFIG(debug, debug|release):{
+ TARGET = qhullstatic_rd
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release):{
+ TARGET = qhullstatic_r
+ OBJECTS_DIR = Release
+}
+
+include(../qhull-libqhull-src_r.pri)
diff --git a/xs/src/qhull/src/qconvex/qconvex.c b/xs/src/qhull/src/qconvex/qconvex.c
new file mode 100644
index 000000000..41bd666da
--- /dev/null
+++ b/xs/src/qhull/src/qconvex/qconvex.c
@@ -0,0 +1,326 @@
+/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qconvex.c
+ compute convex hulls using qhull
+
+ see unix.c for full interface
+
+ Copyright (c) 1993-2015, The Geometry Center
+*/
+
+#include "libqhull/libqhull.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#if __cplusplus
+extern "C" {
+ int isatty(int);
+}
+
+#elif _MSC_VER
+#include <io.h>
+#define isatty _isatty
+/* int _isatty(int); */
+
+#else
+int isatty(int); /* returns 1 if stdin is a tty
+ if "Undefined symbol" this can be deleted along with call in main() */
+#endif
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt">-</a>
+
+ qh_prompt
+ long prompt for qconvex
+
+ notes:
+ restricted version of libqhull.c
+
+ see:
+ concise prompt below
+*/
+
+/* duplicated in qconvex.htm */
+char hidden_options[]=" d v H Qbb Qf Qg Qm Qr Qu Qv Qx Qz TR E V Fp Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
+
+char qh_prompta[]= "\n\
+qconvex- compute the convex hull\n\
+ http://www.qhull.org %s\n\
+\n\
+input (stdin):\n\
+ first lines: dimension and number of points (or vice-versa).\n\
+ other lines: point coordinates, best if one point per line\n\
+ comments: start with a non-numeric character\n\
+\n\
+options:\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Qc - keep coplanar points with nearest facet\n\
+ Qi - keep interior points with nearest facet\n\
+\n\
+Qhull control options:\n\
+ Qbk:n - scale coord k so that low bound is n\n\
+ QBk:n - scale coord k so that upper bound is n (QBk is %2.2g)\n\
+ QbB - scale input to unit cube centered at the origin\n\
+ Qbk:0Bk:0 - remove k-th coordinate from input\n\
+ QJn - randomly joggle input in range [-n,n]\n\
+ QRn - random rotation (n=seed, n=0 time, n=-1 time/no rotate)\n\
+%s%s%s%s"; /* split up qh_prompt for Visual C++ */
+char qh_promptb[]= "\
+ Qs - search all points for the initial simplex\n\
+ QGn - good facet if visible from point n, -n for not visible\n\
+ QVn - good facet if it includes point n, -n if not\n\
+\n\
+";
+char qh_promptc[]= "\
+Trace options:\n\
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
+ Tc - check frequently during execution\n\
+ Ts - print statistics\n\
+ Tv - verify result: structure, convexity, and point inclusion\n\
+ Tz - send all output to stdout\n\
+ TFn - report summary when n or more facets created\n\
+ TI file - input data from file, no spaces or single quotes\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+ TPn - turn on tracing when point n added to hull\n\
+ TMn - turn on tracing at merge n\n\
+ TWn - trace merge facets when width > n\n\
+ TVn - stop qhull after adding point n, -n for before (see TCn)\n\
+ TCn - stop qhull after building cone for point n (see TVn)\n\
+\n\
+Precision options:\n\
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex\n\
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex\n\
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
+ Rn - randomly perturb computations by a factor of [1-n,1+n]\n\
+ Un - max distance below plane for a new, coplanar point\n\
+ Wn - min facet width for outside point (before roundoff)\n\
+\n\
+Output formats (may be combined; if none, produces a summary to stdout):\n\
+ f - facet dump\n\
+ G - Geomview output (see below)\n\
+ i - vertices incident to each facet\n\
+ m - Mathematica output (2-d and 3-d)\n\
+ n - normals with offsets\n\
+ o - OFF file format (dim, points and facets; Voronoi regions)\n\
+ p - point coordinates \n\
+ s - summary (stderr)\n\
+\n\
+";
+char qh_promptd[]= "\
+More formats:\n\
+ Fa - area for each facet\n\
+ FA - compute total area and volume for option 's'\n\
+ Fc - count plus coplanar points for each facet\n\
+ use 'Qc' (default) for coplanar and 'Qi' for interior\n\
+ FC - centrum for each facet\n\
+ Fd - use cdd format for input (homogeneous with offset first)\n\
+ FD - use cdd format for numeric output (offset first)\n\
+ FF - facet dump without ridges\n\
+ Fi - inner plane for each facet\n\
+ FI - ID for each facet\n\
+ Fm - merge count for each facet (511 max)\n\
+ Fn - count plus neighboring facets for each facet\n\
+ FN - count plus neighboring facets for each point\n\
+ Fo - outer plane (or max_outside) for each facet\n\
+ FO - options and precision constants\n\
+ FP - nearest vertex for each coplanar point\n\
+ FQ - command used for qconvex\n\
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
+ for output: #vertices, #facets,\n\
+ #coplanar points, #non-simplicial facets\n\
+ #real (2), max outer plane, min vertex\n\
+ FS - sizes: #int (0) \n\
+ #real (2) tot area, tot volume\n\
+ Ft - triangulation with centrums for non-simplicial facets (OFF format)\n\
+ Fv - count plus vertices for each facet\n\
+ FV - average of vertices (a feasible point for 'H')\n\
+ Fx - extreme points (in order for 2-d)\n\
+\n\
+";
+char qh_prompte[]= "\
+Geomview output (2-d, 3-d, and 4-d)\n\
+ Ga - all points as dots\n\
+ Gp - coplanar points and vertices as radii\n\
+ Gv - vertices as spheres\n\
+ Gi - inner planes only\n\
+ Gn - no planes\n\
+ Go - outer planes only\n\
+ Gc - centrums\n\
+ Gh - hyperplane intersections\n\
+ Gr - ridges\n\
+ GDn - drop dimension n in 3-d and 4-d output\n\
+\n\
+Print options:\n\
+ PAn - keep n largest facets by area\n\
+ Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
+ PDk:n - drop facet if normal[k] >= n\n\
+ Pg - print good facets (needs 'QGn' or 'QVn')\n\
+ PFn - keep facets whose area is at least n\n\
+ PG - print neighbors of good facets\n\
+ PMn - keep n facets with most merges\n\
+ Po - force output. If error, output neighborhood of facet\n\
+ Pp - do not report precision problems\n\
+\n\
+ . - list of all options\n\
+ - - one line descriptions of all options\n\
+ -V - version\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt2">-</a>
+
+ qh_prompt2
+ synopsis for qhull
+*/
+char qh_prompt2[]= "\n\
+qconvex- compute the convex hull. Qhull %s\n\
+ input (stdin): dimension, number of points, point coordinates\n\
+ comments start with a non-numeric character\n\
+\n\
+options (qconvex.htm):\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Tv - verify result: structure, convexity, and point inclusion\n\
+ . - concise list of all options\n\
+ - - one-line description of all options\n\
+ -V - version\n\
+\n\
+output options (subset):\n\
+ s - summary of results (default)\n\
+ i - vertices incident to each facet\n\
+ n - normals with offsets\n\
+ p - vertex coordinates (includes coplanar points if 'Qc')\n\
+ Fx - extreme points (convex hull vertices)\n\
+ FA - report total area and volume\n\
+ FS - compute total area and volume\n\
+ o - OFF format (dim, n, points, facets)\n\
+ G - Geomview output (2-d, 3-d, and 4-d)\n\
+ m - Mathematica output (2-d and 3-d)\n\
+ QVn - print facets that include point n, -n if not\n\
+ TO file- output results to file, may be enclosed in single quotes\n\
+\n\
+examples:\n\
+ rbox c D2 | qconvex s n rbox c D2 | qconvex i\n\
+ rbox c D2 | qconvex o rbox 1000 s | qconvex s Tv FA\n\
+ rbox c d D2 | qconvex s Qc Fx rbox y 1000 W0 | qconvex s n\n\
+ rbox y 1000 W0 | qconvex s QJ rbox d G1 D12 | qconvex QR0 FA Pp\n\
+ rbox c D7 | qconvex FA TF1000\n\
+\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt3">-</a>
+
+ qh_prompt3
+ concise prompt for qhull
+*/
+char qh_prompt3[]= "\n\
+Qhull %s.\n\
+Except for 'F.' and 'PG', upper-case options take an argument.\n\
+\n\
+ incidences mathematica normals OFF_format points\n\
+ summary facet_dump\n\
+\n\
+ Farea FArea_total Fcoplanars FCentrums Fd_cdd_in\n\
+ FD_cdd_out FFacet_xridge Finner FIDs Fmerges\n\
+ Fneighbors FNeigh_vertex Fouter FOptions FPoint_near\n\
+ FQhull Fsummary FSize Fvertices FVertex_ave\n\
+ Fxtremes FMaple\n\
+\n\
+ Gvertices Gpoints Gall_points Gno_planes Ginner\n\
+ Gcentrums Ghyperplanes Gridges Gouter GDrop_dim\n\
+\n\
+ PArea_keep Pdrop d0:0D0 PFacet_area_keep Pgood PGood_neighbors\n\
+ PMerge_keep Poutput_forced Pprecision_not\n\
+\n\
+ QbBound 0:0.5 QbB_scale_box Qcoplanar QGood_point Qinterior\n\
+ QJoggle Qrandom QRotate Qsearch_1st Qtriangulate\n\
+ QVertex_good\n\
+\n\
+ T4_trace Tcheck_often Tstatistics Tverify Tz_stdout\n\
+ TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file\n\
+ TWide_trace TVertex_stop TCone_stop\n\
+\n\
+ Angle_max Centrum_size Random_dist Ucoplanar_max Wide_outside\n\
+";
+
+/*-<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="main">-</a>
+
+ main( argc, argv )
+ processes the command line, calls qhull() to do the work, and exits
+
+ design:
+ initializes data structures
+ reads points
+ finishes initialization
+ computes convex hull and other structures
+ checks the result
+ writes the output
+ frees memory
+*/
+int main(int argc, char *argv[]) {
+ int curlong, totlong; /* used !qh_NOmem */
+ int exitcode, numpoints, dim;
+ coordT *points;
+ boolT ismalloc;
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ if ((argc == 1) && isatty( 0 /*stdin*/)) {
+ fprintf(stdout, qh_prompt2, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompta, qh_version, qh_DEFAULTbox,
+ qh_promptb, qh_promptc, qh_promptd, qh_prompte);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '.' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompt3, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
+ fprintf(stdout, "%s\n", qh_version2);
+ exit(qh_ERRnone);
+ }
+ qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
+ exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
+ if (!exitcode) {
+ qh NOerrexit = False;
+ qh_checkflags(qh qhull_command, hidden_options);
+ qh_initflags(qh qhull_command);
+ points= qh_readpoints(&numpoints, &dim, &ismalloc);
+ if (dim >= 5) {
+ qh_option("Qxact_merge", NULL, NULL);
+ qh MERGEexact= True; /* 'Qx' always */
+ }
+ qh_init_B(points, numpoints, dim, ismalloc);
+ qh_qhull();
+ qh_check_output();
+ qh_produce_output();
+ if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ exitcode= qh_ERRnone;
+ }
+ qh NOerrexit= True; /* no more setjmp */
+#ifdef qh_NOmem
+ qh_freeqhull(qh_ALL);
+#else
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
+ totlong, curlong);
+#endif
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/qconvex/qconvex.pro b/xs/src/qhull/src/qconvex/qconvex.pro
new file mode 100644
index 000000000..1bf631bff
--- /dev/null
+++ b/xs/src/qhull/src/qconvex/qconvex.pro
@@ -0,0 +1,9 @@
+# -------------------------------------------------
+# qconvex.pro -- Qt project file for qconvex.exe
+# -------------------------------------------------
+
+include(../qhull-app-c.pri)
+
+TARGET = qconvex
+
+SOURCES += qconvex.c
diff --git a/xs/src/qhull/src/qconvex/qconvex_r.c b/xs/src/qhull/src/qconvex/qconvex_r.c
new file mode 100644
index 000000000..abf68ce37
--- /dev/null
+++ b/xs/src/qhull/src/qconvex/qconvex_r.c
@@ -0,0 +1,328 @@
+/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qconvex.c
+ compute convex hulls using qhull
+
+ see unix.c for full interface
+
+ Copyright (c) 1993-2015, The Geometry Center
+*/
+
+#include "libqhull_r/libqhull_r.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#if __cplusplus
+extern "C" {
+ int isatty(int);
+}
+
+#elif _MSC_VER
+#include <io.h>
+#define isatty _isatty
+/* int _isatty(int); */
+
+#else
+int isatty(int); /* returns 1 if stdin is a tty
+ if "Undefined symbol" this can be deleted along with call in main() */
+#endif
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt">-</a>
+
+ qh_prompt
+ long prompt for qconvex
+
+ notes:
+ restricted version of libqhull.c
+
+ see:
+ concise prompt below
+*/
+
+/* duplicated in qconvex.htm */
+char hidden_options[]=" d v H Qbb Qf Qg Qm Qr Qu Qv Qx Qz TR E V Fp Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
+
+char qh_prompta[]= "\n\
+qconvex- compute the convex hull\n\
+ http://www.qhull.org %s\n\
+\n\
+input (stdin):\n\
+ first lines: dimension and number of points (or vice-versa).\n\
+ other lines: point coordinates, best if one point per line\n\
+ comments: start with a non-numeric character\n\
+\n\
+options:\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Qc - keep coplanar points with nearest facet\n\
+ Qi - keep interior points with nearest facet\n\
+\n\
+Qhull control options:\n\
+ Qbk:n - scale coord k so that low bound is n\n\
+ QBk:n - scale coord k so that upper bound is n (QBk is %2.2g)\n\
+ QbB - scale input to unit cube centered at the origin\n\
+ Qbk:0Bk:0 - remove k-th coordinate from input\n\
+ QJn - randomly joggle input in range [-n,n]\n\
+ QRn - random rotation (n=seed, n=0 time, n=-1 time/no rotate)\n\
+%s%s%s%s"; /* split up qh_prompt for Visual C++ */
+char qh_promptb[]= "\
+ Qs - search all points for the initial simplex\n\
+ QGn - good facet if visible from point n, -n for not visible\n\
+ QVn - good facet if it includes point n, -n if not\n\
+\n\
+";
+char qh_promptc[]= "\
+Trace options:\n\
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
+ Tc - check frequently during execution\n\
+ Ts - print statistics\n\
+ Tv - verify result: structure, convexity, and point inclusion\n\
+ Tz - send all output to stdout\n\
+ TFn - report summary when n or more facets created\n\
+ TI file - input data from file, no spaces or single quotes\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+ TPn - turn on tracing when point n added to hull\n\
+ TMn - turn on tracing at merge n\n\
+ TWn - trace merge facets when width > n\n\
+ TVn - stop qhull after adding point n, -n for before (see TCn)\n\
+ TCn - stop qhull after building cone for point n (see TVn)\n\
+\n\
+Precision options:\n\
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex\n\
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex\n\
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
+ Rn - randomly perturb computations by a factor of [1-n,1+n]\n\
+ Un - max distance below plane for a new, coplanar point\n\
+ Wn - min facet width for outside point (before roundoff)\n\
+\n\
+Output formats (may be combined; if none, produces a summary to stdout):\n\
+ f - facet dump\n\
+ G - Geomview output (see below)\n\
+ i - vertices incident to each facet\n\
+ m - Mathematica output (2-d and 3-d)\n\
+ n - normals with offsets\n\
+ o - OFF file format (dim, points and facets; Voronoi regions)\n\
+ p - point coordinates \n\
+ s - summary (stderr)\n\
+\n\
+";
+char qh_promptd[]= "\
+More formats:\n\
+ Fa - area for each facet\n\
+ FA - compute total area and volume for option 's'\n\
+ Fc - count plus coplanar points for each facet\n\
+ use 'Qc' (default) for coplanar and 'Qi' for interior\n\
+ FC - centrum for each facet\n\
+ Fd - use cdd format for input (homogeneous with offset first)\n\
+ FD - use cdd format for numeric output (offset first)\n\
+ FF - facet dump without ridges\n\
+ Fi - inner plane for each facet\n\
+ FI - ID for each facet\n\
+ Fm - merge count for each facet (511 max)\n\
+ Fn - count plus neighboring facets for each facet\n\
+ FN - count plus neighboring facets for each point\n\
+ Fo - outer plane (or max_outside) for each facet\n\
+ FO - options and precision constants\n\
+ FP - nearest vertex for each coplanar point\n\
+ FQ - command used for qconvex\n\
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
+ for output: #vertices, #facets,\n\
+ #coplanar points, #non-simplicial facets\n\
+ #real (2), max outer plane, min vertex\n\
+ FS - sizes: #int (0) \n\
+ #real (2) tot area, tot volume\n\
+ Ft - triangulation with centrums for non-simplicial facets (OFF format)\n\
+ Fv - count plus vertices for each facet\n\
+ FV - average of vertices (a feasible point for 'H')\n\
+ Fx - extreme points (in order for 2-d)\n\
+\n\
+";
+char qh_prompte[]= "\
+Geomview output (2-d, 3-d, and 4-d)\n\
+ Ga - all points as dots\n\
+ Gp - coplanar points and vertices as radii\n\
+ Gv - vertices as spheres\n\
+ Gi - inner planes only\n\
+ Gn - no planes\n\
+ Go - outer planes only\n\
+ Gc - centrums\n\
+ Gh - hyperplane intersections\n\
+ Gr - ridges\n\
+ GDn - drop dimension n in 3-d and 4-d output\n\
+\n\
+Print options:\n\
+ PAn - keep n largest facets by area\n\
+ Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
+ PDk:n - drop facet if normal[k] >= n\n\
+ Pg - print good facets (needs 'QGn' or 'QVn')\n\
+ PFn - keep facets whose area is at least n\n\
+ PG - print neighbors of good facets\n\
+ PMn - keep n facets with most merges\n\
+ Po - force output. If error, output neighborhood of facet\n\
+ Pp - do not report precision problems\n\
+\n\
+ . - list of all options\n\
+ - - one line descriptions of all options\n\
+ -V - version\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt2">-</a>
+
+ qh_prompt2
+ synopsis for qhull
+*/
+char qh_prompt2[]= "\n\
+qconvex- compute the convex hull. Qhull %s\n\
+ input (stdin): dimension, number of points, point coordinates\n\
+ comments start with a non-numeric character\n\
+\n\
+options (qconvex.htm):\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Tv - verify result: structure, convexity, and point inclusion\n\
+ . - concise list of all options\n\
+ - - one-line description of all options\n\
+ -V - version\n\
+\n\
+output options (subset):\n\
+ s - summary of results (default)\n\
+ i - vertices incident to each facet\n\
+ n - normals with offsets\n\
+ p - vertex coordinates (includes coplanar points if 'Qc')\n\
+ Fx - extreme points (convex hull vertices)\n\
+ FA - report total area and volume\n\
+ FS - compute total area and volume\n\
+ o - OFF format (dim, n, points, facets)\n\
+ G - Geomview output (2-d, 3-d, and 4-d)\n\
+ m - Mathematica output (2-d and 3-d)\n\
+ QVn - print facets that include point n, -n if not\n\
+ TO file- output results to file, may be enclosed in single quotes\n\
+\n\
+examples:\n\
+ rbox c D2 | qconvex s n rbox c D2 | qconvex i\n\
+ rbox c D2 | qconvex o rbox 1000 s | qconvex s Tv FA\n\
+ rbox c d D2 | qconvex s Qc Fx rbox y 1000 W0 | qconvex s n\n\
+ rbox y 1000 W0 | qconvex s QJ rbox d G1 D12 | qconvex QR0 FA Pp\n\
+ rbox c D7 | qconvex FA TF1000\n\
+\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt3">-</a>
+
+ qh_prompt3
+ concise prompt for qhull
+*/
+char qh_prompt3[]= "\n\
+Qhull %s.\n\
+Except for 'F.' and 'PG', upper-case options take an argument.\n\
+\n\
+ incidences mathematica normals OFF_format points\n\
+ summary facet_dump\n\
+\n\
+ Farea FArea_total Fcoplanars FCentrums Fd_cdd_in\n\
+ FD_cdd_out FFacet_xridge Finner FIDs Fmerges\n\
+ Fneighbors FNeigh_vertex Fouter FOptions FPoint_near\n\
+ FQhull Fsummary FSize Fvertices FVertex_ave\n\
+ Fxtremes FMaple\n\
+\n\
+ Gvertices Gpoints Gall_points Gno_planes Ginner\n\
+ Gcentrums Ghyperplanes Gridges Gouter GDrop_dim\n\
+\n\
+ PArea_keep Pdrop d0:0D0 PFacet_area_keep Pgood PGood_neighbors\n\
+ PMerge_keep Poutput_forced Pprecision_not\n\
+\n\
+ QbBound 0:0.5 QbB_scale_box Qcoplanar QGood_point Qinterior\n\
+ QJoggle Qrandom QRotate Qsearch_1st Qtriangulate\n\
+ QVertex_good\n\
+\n\
+ T4_trace Tcheck_often Tstatistics Tverify Tz_stdout\n\
+ TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file\n\
+ TWide_trace TVertex_stop TCone_stop\n\
+\n\
+ Angle_max Centrum_size Random_dist Ucoplanar_max Wide_outside\n\
+";
+
+/*-<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="main">-</a>
+
+ main( argc, argv )
+ processes the command line, calls qhull() to do the work, and exits
+
+ design:
+ initializes data structures
+ reads points
+ finishes initialization
+ computes convex hull and other structures
+ checks the result
+ writes the output
+ frees memory
+*/
+int main(int argc, char *argv[]) {
+ int curlong, totlong; /* used !qh_NOmem */
+ int exitcode, numpoints, dim;
+ coordT *points;
+ boolT ismalloc;
+ qhT qh_qh;
+ qhT *qh= &qh_qh;
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ if ((argc == 1) && isatty( 0 /*stdin*/)) {
+ fprintf(stdout, qh_prompt2, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompta, qh_version, qh_DEFAULTbox,
+ qh_promptb, qh_promptc, qh_promptd, qh_prompte);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '.' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompt3, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
+ fprintf(stdout, "%s\n", qh_version2);
+ exit(qh_ERRnone);
+ }
+ qh_init_A(qh, stdin, stdout, stderr, argc, argv); /* sets qh->qhull_command */
+ exitcode= setjmp(qh->errexit); /* simple statement for CRAY J916 */
+ if (!exitcode) {
+ qh->NOerrexit = False;
+ qh_checkflags(qh, qh->qhull_command, hidden_options);
+ qh_initflags(qh, qh->qhull_command);
+ points= qh_readpoints(qh, &numpoints, &dim, &ismalloc);
+ if (dim >= 5) {
+ qh_option(qh, "Qxact_merge", NULL, NULL);
+ qh->MERGEexact= True; /* 'Qx' always */
+ }
+ qh_init_B(qh, points, numpoints, dim, ismalloc);
+ qh_qhull(qh);
+ qh_check_output(qh);
+ qh_produce_output(qh);
+ if (qh->VERIFYoutput && !qh->FORCEoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ exitcode= qh_ERRnone;
+ }
+ qh->NOerrexit= True; /* no more setjmp */
+#ifdef qh_NOmem
+ qh_freeqhull(qh, qh_ALL);
+#else
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
+ totlong, curlong);
+#endif
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/qdelaunay/qdelaun.c b/xs/src/qhull/src/qdelaunay/qdelaun.c
new file mode 100644
index 000000000..9011d9fcc
--- /dev/null
+++ b/xs/src/qhull/src/qdelaunay/qdelaun.c
@@ -0,0 +1,315 @@
+/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qdelaun.c
+ compute Delaunay triangulations and furthest-point Delaunay
+ triangulations using qhull
+
+ see unix.c for full interface
+
+ Copyright (c) 1993-2015, The Geometry Center
+*/
+
+#include "libqhull/libqhull.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#if __cplusplus
+extern "C" {
+ int isatty(int);
+}
+
+#elif _MSC_VER
+#include <io.h>
+#define isatty _isatty
+/* int _isatty(int); */
+
+#else
+int isatty(int); /* returns 1 if stdin is a tty
+ if "Undefined symbol" this can be deleted along with call in main() */
+#endif
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt">-</a>
+
+ qh_prompt
+ long prompt for qhull
+
+ notes:
+ restricted version of libqhull.c
+
+ see:
+ concise prompt below
+*/
+
+/* duplicated in qdelau_f.htm and qdelaun.htm */
+char hidden_options[]=" d n v H U Qb QB Qc Qf Qg Qi Qm Qr QR Qv Qx TR E V FC Fi Fo Ft Fp FV Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
+
+char qh_prompta[]= "\n\
+qdelaunay- compute the Delaunay triangulation\n\
+ http://www.qhull.org %s\n\
+\n\
+input (stdin):\n\
+ first lines: dimension and number of points (or vice-versa).\n\
+ other lines: point coordinates, best if one point per line\n\
+ comments: start with a non-numeric character\n\
+\n\
+options:\n\
+ Qu - compute furthest-site Delaunay triangulation\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+\n\
+Qhull control options:\n\
+ QJn - randomly joggle input in range [-n,n]\n\
+%s%s%s%s"; /* split up qh_prompt for Visual C++ */
+char qh_promptb[]= "\
+ Qs - search all points for the initial simplex\n\
+ Qz - add point-at-infinity to Delaunay triangulation\n\
+ QGn - print Delaunay region if visible from point n, -n if not\n\
+ QVn - print Delaunay regions that include point n, -n if not\n\
+\n\
+";
+char qh_promptc[]= "\
+Trace options:\n\
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
+ Tc - check frequently during execution\n\
+ Ts - print statistics\n\
+ Tv - verify result: structure, convexity, and in-circle test\n\
+ Tz - send all output to stdout\n\
+ TFn - report summary when n or more facets created\n\
+ TI file - input data from file, no spaces or single quotes\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+ TPn - turn on tracing when point n added to hull\n\
+ TMn - turn on tracing at merge n\n\
+ TWn - trace merge facets when width > n\n\
+ TVn - stop qhull after adding point n, -n for before (see TCn)\n\
+ TCn - stop qhull after building cone for point n (see TVn)\n\
+\n\
+Precision options:\n\
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex\n\
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex\n\
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
+ Rn - randomly perturb computations by a factor of [1-n,1+n]\n\
+ Wn - min facet width for outside point (before roundoff)\n\
+\n\
+Output formats (may be combined; if none, produces a summary to stdout):\n\
+ f - facet dump\n\
+ G - Geomview output (see below)\n\
+ i - vertices incident to each Delaunay region\n\
+ m - Mathematica output (2-d only, lifted to a paraboloid)\n\
+ o - OFF format (dim, points, and facets as a paraboloid)\n\
+ p - point coordinates (lifted to a paraboloid)\n\
+ s - summary (stderr)\n\
+\n\
+";
+char qh_promptd[]= "\
+More formats:\n\
+ Fa - area for each Delaunay region\n\
+ FA - compute total area for option 's'\n\
+ Fc - count plus coincident points for each Delaunay region\n\
+ Fd - use cdd format for input (homogeneous with offset first)\n\
+ FD - use cdd format for numeric output (offset first)\n\
+ FF - facet dump without ridges\n\
+ FI - ID of each Delaunay region\n\
+ Fm - merge count for each Delaunay region (511 max)\n\
+ FM - Maple output (2-d only, lifted to a paraboloid)\n\
+ Fn - count plus neighboring region for each Delaunay region\n\
+ FN - count plus neighboring region for each point\n\
+ FO - options and precision constants\n\
+ FP - nearest point and distance for each coincident point\n\
+ FQ - command used for qdelaunay\n\
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
+ for output: #vertices, #Delaunay regions,\n\
+ #coincident points, #non-simplicial regions\n\
+ #real (2), max outer plane, min vertex\n\
+ FS - sizes: #int (0)\n\
+ #real (2), tot area, 0\n\
+ Fv - count plus vertices for each Delaunay region\n\
+ Fx - extreme points of Delaunay triangulation (on convex hull)\n\
+\n\
+";
+char qh_prompte[]= "\
+Geomview options (2-d and 3-d)\n\
+ Ga - all points as dots\n\
+ Gp - coplanar points and vertices as radii\n\
+ Gv - vertices as spheres\n\
+ Gi - inner planes only\n\
+ Gn - no planes\n\
+ Go - outer planes only\n\
+ Gc - centrums\n\
+ Gh - hyperplane intersections\n\
+ Gr - ridges\n\
+ GDn - drop dimension n in 3-d and 4-d output\n\
+ Gt - transparent outer ridges to view 3-d Delaunay\n\
+\n\
+Print options:\n\
+ PAn - keep n largest Delaunay regions by area\n\
+ Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
+ PDk:n - drop facet if normal[k] >= n\n\
+ Pg - print good Delaunay regions (needs 'QGn' or 'QVn')\n\
+ PFn - keep Delaunay regions whose area is at least n\n\
+ PG - print neighbors of good regions (needs 'QGn' or 'QVn')\n\
+ PMn - keep n Delaunay regions with most merges\n\
+ Po - force output. If error, output neighborhood of facet\n\
+ Pp - do not report precision problems\n\
+\n\
+ . - list of all options\n\
+ - - one line descriptions of all options\n\
+ -V - version\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt2">-</a>
+
+ qh_prompt2
+ synopsis for qhull
+*/
+char qh_prompt2[]= "\n\
+qdelaunay- compute the Delaunay triangulation. Qhull %s\n\
+ input (stdin): dimension, number of points, point coordinates\n\
+ comments start with a non-numeric character\n\
+\n\
+options (qdelaun.htm):\n\
+ Qu - furthest-site Delaunay triangulation\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Tv - verify result: structure, convexity, and in-circle test\n\
+ . - concise list of all options\n\
+ - - one-line description of all options\n\
+ -V - version\n\
+\n\
+output options (subset):\n\
+ s - summary of results (default)\n\
+ i - vertices incident to each Delaunay region\n\
+ Fx - extreme points (vertices of the convex hull)\n\
+ o - OFF format (shows the points lifted to a paraboloid)\n\
+ G - Geomview output (2-d and 3-d points lifted to a paraboloid)\n\
+ m - Mathematica output (2-d inputs lifted to a paraboloid)\n\
+ QVn - print Delaunay regions that include point n, -n if not\n\
+ TO file- output results to file, may be enclosed in single quotes\n\
+\n\
+examples:\n\
+ rbox c P0 D2 | qdelaunay s o rbox c P0 D2 | qdelaunay i\n\
+ rbox c P0 D2 | qdelaunay Fv rbox c P0 D2 | qdelaunay s Qu Fv\n\
+ rbox c G1 d D2 | qdelaunay s i rbox c G1 d D2 | qdelaunay Qt\n\
+ rbox M3,4 z 100 D2 | qdelaunay s rbox M3,4 z 100 D2 | qdelaunay s Qt\n\
+\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt3">-</a>
+
+ qh_prompt3
+ concise prompt for qhull
+*/
+char qh_prompt3[]= "\n\
+Qhull %s.\n\
+Except for 'F.' and 'PG', upper-case options take an argument.\n\
+\n\
+ incidences mathematica OFF_format points_lifted summary\n\
+ facet_dump\n\
+\n\
+ Farea FArea_total Fcoincident Fd_cdd_in FD_cdd_out\n\
+ FF_dump_xridge FIDs Fmerges Fneighbors FNeigh_vertex\n\
+ FOptions FPoint_near FQdelaun Fsummary FSize\n\
+ Fvertices Fxtremes FMaple\n\
+\n\
+ Gvertices Gpoints Gall_points Gno_planes Ginner\n\
+ Gcentrums Ghyperplanes Gridges Gouter GDrop_dim\n\
+ Gtransparent\n\
+\n\
+ PArea_keep Pdrop d0:0D0 Pgood PFacet_area_keep\n\
+ PGood_neighbors PMerge_keep Poutput_forced Pprecision_not\n\
+\n\
+ QGood_point QJoggle Qsearch_1st Qtriangulate QupperDelaunay\n\
+ QVertex_good Qzinfinite\n\
+\n\
+ T4_trace Tcheck_often Tstatistics Tverify Tz_stdout\n\
+ TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file\n\
+ TWide_trace TVertex_stop TCone_stop\n\
+\n\
+ Angle_max Centrum_size Random_dist Wide_outside\n\
+";
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="main">-</a>
+
+ main( argc, argv )
+ processes the command line, calls qhull() to do the work, and exits
+
+ design:
+ initializes data structures
+ reads points
+ finishes initialization
+ computes convex hull and other structures
+ checks the result
+ writes the output
+ frees memory
+*/
+int main(int argc, char *argv[]) {
+ int curlong, totlong; /* used !qh_NOmem */
+ int exitcode, numpoints, dim;
+ coordT *points;
+ boolT ismalloc;
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ if ((argc == 1) && isatty( 0 /*stdin*/)) {
+ fprintf(stdout, qh_prompt2, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompta, qh_version,
+ qh_promptb, qh_promptc, qh_promptd, qh_prompte);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '.' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompt3, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
+ fprintf(stdout, "%s\n", qh_version2);
+ exit(qh_ERRnone);
+ }
+ qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
+ exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
+ if (!exitcode) {
+ qh NOerrexit = False;
+ qh_option("delaunay Qbbound-last", NULL, NULL);
+ qh DELAUNAY= True; /* 'd' */
+ qh SCALElast= True; /* 'Qbb' */
+ qh KEEPcoplanar= True; /* 'Qc', to keep coplanars in 'p' */
+ qh_checkflags(qh qhull_command, hidden_options);
+ qh_initflags(qh qhull_command);
+ points= qh_readpoints(&numpoints, &dim, &ismalloc);
+ if (dim >= 5) {
+ qh_option("Qxact_merge", NULL, NULL);
+ qh MERGEexact= True; /* 'Qx' always */
+ }
+ qh_init_B(points, numpoints, dim, ismalloc);
+ qh_qhull();
+ qh_check_output();
+ qh_produce_output();
+ if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ exitcode= qh_ERRnone;
+ }
+ qh NOerrexit= True; /* no more setjmp */
+#ifdef qh_NOmem
+ qh_freeqhull(qh_ALL);
+#else
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
+ totlong, curlong);
+#endif
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/qdelaunay/qdelaun_r.c b/xs/src/qhull/src/qdelaunay/qdelaun_r.c
new file mode 100644
index 000000000..0854b8bb9
--- /dev/null
+++ b/xs/src/qhull/src/qdelaunay/qdelaun_r.c
@@ -0,0 +1,317 @@
+/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qdelaun.c
+ compute Delaunay triangulations and furthest-point Delaunay
+ triangulations using qhull
+
+ see unix.c for full interface
+
+ Copyright (c) 1993-2015, The Geometry Center
+*/
+
+#include "libqhull_r/libqhull_r.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#if __cplusplus
+extern "C" {
+ int isatty(int);
+}
+
+#elif _MSC_VER
+#include <io.h>
+#define isatty _isatty
+/* int _isatty(int); */
+
+#else
+int isatty(int); /* returns 1 if stdin is a tty
+ if "Undefined symbol" this can be deleted along with call in main() */
+#endif
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt">-</a>
+
+ qh_prompt
+ long prompt for qhull
+
+ notes:
+ restricted version of libqhull.c
+
+ see:
+ concise prompt below
+*/
+
+/* duplicated in qdelau_f.htm and qdelaun.htm */
+char hidden_options[]=" d n v H U Qb QB Qc Qf Qg Qi Qm Qr QR Qv Qx TR E V FC Fi Fo Ft Fp FV Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
+
+char qh_prompta[]= "\n\
+qdelaunay- compute the Delaunay triangulation\n\
+ http://www.qhull.org %s\n\
+\n\
+input (stdin):\n\
+ first lines: dimension and number of points (or vice-versa).\n\
+ other lines: point coordinates, best if one point per line\n\
+ comments: start with a non-numeric character\n\
+\n\
+options:\n\
+ Qu - compute furthest-site Delaunay triangulation\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+\n\
+Qhull control options:\n\
+ QJn - randomly joggle input in range [-n,n]\n\
+%s%s%s%s"; /* split up qh_prompt for Visual C++ */
+char qh_promptb[]= "\
+ Qs - search all points for the initial simplex\n\
+ Qz - add point-at-infinity to Delaunay triangulation\n\
+ QGn - print Delaunay region if visible from point n, -n if not\n\
+ QVn - print Delaunay regions that include point n, -n if not\n\
+\n\
+";
+char qh_promptc[]= "\
+Trace options:\n\
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
+ Tc - check frequently during execution\n\
+ Ts - print statistics\n\
+ Tv - verify result: structure, convexity, and in-circle test\n\
+ Tz - send all output to stdout\n\
+ TFn - report summary when n or more facets created\n\
+ TI file - input data from file, no spaces or single quotes\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+ TPn - turn on tracing when point n added to hull\n\
+ TMn - turn on tracing at merge n\n\
+ TWn - trace merge facets when width > n\n\
+ TVn - stop qhull after adding point n, -n for before (see TCn)\n\
+ TCn - stop qhull after building cone for point n (see TVn)\n\
+\n\
+Precision options:\n\
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex\n\
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex\n\
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
+ Rn - randomly perturb computations by a factor of [1-n,1+n]\n\
+ Wn - min facet width for outside point (before roundoff)\n\
+\n\
+Output formats (may be combined; if none, produces a summary to stdout):\n\
+ f - facet dump\n\
+ G - Geomview output (see below)\n\
+ i - vertices incident to each Delaunay region\n\
+ m - Mathematica output (2-d only, lifted to a paraboloid)\n\
+ o - OFF format (dim, points, and facets as a paraboloid)\n\
+ p - point coordinates (lifted to a paraboloid)\n\
+ s - summary (stderr)\n\
+\n\
+";
+char qh_promptd[]= "\
+More formats:\n\
+ Fa - area for each Delaunay region\n\
+ FA - compute total area for option 's'\n\
+ Fc - count plus coincident points for each Delaunay region\n\
+ Fd - use cdd format for input (homogeneous with offset first)\n\
+ FD - use cdd format for numeric output (offset first)\n\
+ FF - facet dump without ridges\n\
+ FI - ID of each Delaunay region\n\
+ Fm - merge count for each Delaunay region (511 max)\n\
+ FM - Maple output (2-d only, lifted to a paraboloid)\n\
+ Fn - count plus neighboring region for each Delaunay region\n\
+ FN - count plus neighboring region for each point\n\
+ FO - options and precision constants\n\
+ FP - nearest point and distance for each coincident point\n\
+ FQ - command used for qdelaunay\n\
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
+ for output: #vertices, #Delaunay regions,\n\
+ #coincident points, #non-simplicial regions\n\
+ #real (2), max outer plane, min vertex\n\
+ FS - sizes: #int (0)\n\
+ #real (2), tot area, 0\n\
+ Fv - count plus vertices for each Delaunay region\n\
+ Fx - extreme points of Delaunay triangulation (on convex hull)\n\
+\n\
+";
+char qh_prompte[]= "\
+Geomview options (2-d and 3-d)\n\
+ Ga - all points as dots\n\
+ Gp - coplanar points and vertices as radii\n\
+ Gv - vertices as spheres\n\
+ Gi - inner planes only\n\
+ Gn - no planes\n\
+ Go - outer planes only\n\
+ Gc - centrums\n\
+ Gh - hyperplane intersections\n\
+ Gr - ridges\n\
+ GDn - drop dimension n in 3-d and 4-d output\n\
+ Gt - transparent outer ridges to view 3-d Delaunay\n\
+\n\
+Print options:\n\
+ PAn - keep n largest Delaunay regions by area\n\
+ Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
+ PDk:n - drop facet if normal[k] >= n\n\
+ Pg - print good Delaunay regions (needs 'QGn' or 'QVn')\n\
+ PFn - keep Delaunay regions whose area is at least n\n\
+ PG - print neighbors of good regions (needs 'QGn' or 'QVn')\n\
+ PMn - keep n Delaunay regions with most merges\n\
+ Po - force output. If error, output neighborhood of facet\n\
+ Pp - do not report precision problems\n\
+\n\
+ . - list of all options\n\
+ - - one line descriptions of all options\n\
+ -V - version\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt2">-</a>
+
+ qh_prompt2
+ synopsis for qhull
+*/
+char qh_prompt2[]= "\n\
+qdelaunay- compute the Delaunay triangulation. Qhull %s\n\
+ input (stdin): dimension, number of points, point coordinates\n\
+ comments start with a non-numeric character\n\
+\n\
+options (qdelaun.htm):\n\
+ Qu - furthest-site Delaunay triangulation\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Tv - verify result: structure, convexity, and in-circle test\n\
+ . - concise list of all options\n\
+ - - one-line description of all options\n\
+ -V - version\n\
+\n\
+output options (subset):\n\
+ s - summary of results (default)\n\
+ i - vertices incident to each Delaunay region\n\
+ Fx - extreme points (vertices of the convex hull)\n\
+ o - OFF format (shows the points lifted to a paraboloid)\n\
+ G - Geomview output (2-d and 3-d points lifted to a paraboloid)\n\
+ m - Mathematica output (2-d inputs lifted to a paraboloid)\n\
+ QVn - print Delaunay regions that include point n, -n if not\n\
+ TO file- output results to file, may be enclosed in single quotes\n\
+\n\
+examples:\n\
+ rbox c P0 D2 | qdelaunay s o rbox c P0 D2 | qdelaunay i\n\
+ rbox c P0 D2 | qdelaunay Fv rbox c P0 D2 | qdelaunay s Qu Fv\n\
+ rbox c G1 d D2 | qdelaunay s i rbox c G1 d D2 | qdelaunay Qt\n\
+ rbox M3,4 z 100 D2 | qdelaunay s rbox M3,4 z 100 D2 | qdelaunay s Qt\n\
+\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt3">-</a>
+
+ qh_prompt3
+ concise prompt for qhull
+*/
+char qh_prompt3[]= "\n\
+Qhull %s.\n\
+Except for 'F.' and 'PG', upper-case options take an argument.\n\
+\n\
+ incidences mathematica OFF_format points_lifted summary\n\
+ facet_dump\n\
+\n\
+ Farea FArea_total Fcoincident Fd_cdd_in FD_cdd_out\n\
+ FF_dump_xridge FIDs Fmerges Fneighbors FNeigh_vertex\n\
+ FOptions FPoint_near FQdelaun Fsummary FSize\n\
+ Fvertices Fxtremes FMaple\n\
+\n\
+ Gvertices Gpoints Gall_points Gno_planes Ginner\n\
+ Gcentrums Ghyperplanes Gridges Gouter GDrop_dim\n\
+ Gtransparent\n\
+\n\
+ PArea_keep Pdrop d0:0D0 Pgood PFacet_area_keep\n\
+ PGood_neighbors PMerge_keep Poutput_forced Pprecision_not\n\
+\n\
+ QGood_point QJoggle Qsearch_1st Qtriangulate QupperDelaunay\n\
+ QVertex_good Qzinfinite\n\
+\n\
+ T4_trace Tcheck_often Tstatistics Tverify Tz_stdout\n\
+ TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file\n\
+ TWide_trace TVertex_stop TCone_stop\n\
+\n\
+ Angle_max Centrum_size Random_dist Wide_outside\n\
+";
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="main">-</a>
+
+ main( argc, argv )
+ processes the command line, calls qhull() to do the work, and exits
+
+ design:
+ initializes data structures
+ reads points
+ finishes initialization
+ computes convex hull and other structures
+ checks the result
+ writes the output
+ frees memory
+*/
+int main(int argc, char *argv[]) {
+ int curlong, totlong; /* used !qh_NOmem */
+ int exitcode, numpoints, dim;
+ coordT *points;
+ boolT ismalloc;
+ qhT qh_qh;
+ qhT *qh= &qh_qh;
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ if ((argc == 1) && isatty( 0 /*stdin*/)) {
+ fprintf(stdout, qh_prompt2, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompta, qh_version,
+ qh_promptb, qh_promptc, qh_promptd, qh_prompte);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '.' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompt3, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
+ fprintf(stdout, "%s\n", qh_version2);
+ exit(qh_ERRnone);
+ }
+ qh_init_A(qh, stdin, stdout, stderr, argc, argv); /* sets qh->qhull_command */
+ exitcode= setjmp(qh->errexit); /* simple statement for CRAY J916 */
+ if (!exitcode) {
+ qh->NOerrexit = False;
+ qh_option(qh, "delaunay Qbbound-last", NULL, NULL);
+ qh->DELAUNAY= True; /* 'd' */
+ qh->SCALElast= True; /* 'Qbb' */
+ qh->KEEPcoplanar= True; /* 'Qc', to keep coplanars in 'p' */
+ qh_checkflags(qh, qh->qhull_command, hidden_options);
+ qh_initflags(qh, qh->qhull_command);
+ points= qh_readpoints(qh, &numpoints, &dim, &ismalloc);
+ if (dim >= 5) {
+ qh_option(qh, "Qxact_merge", NULL, NULL);
+ qh->MERGEexact= True; /* 'Qx' always */
+ }
+ qh_init_B(qh, points, numpoints, dim, ismalloc);
+ qh_qhull(qh);
+ qh_check_output(qh);
+ qh_produce_output(qh);
+ if (qh->VERIFYoutput && !qh->FORCEoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ exitcode= qh_ERRnone;
+ }
+ qh->NOerrexit= True; /* no more setjmp */
+#ifdef qh_NOmem
+ qh_freeqhull(qh, qh_ALL);
+#else
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
+ totlong, curlong);
+#endif
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/qdelaunay/qdelaunay.pro b/xs/src/qhull/src/qdelaunay/qdelaunay.pro
new file mode 100644
index 000000000..138ac0589
--- /dev/null
+++ b/xs/src/qhull/src/qdelaunay/qdelaunay.pro
@@ -0,0 +1,9 @@
+# -------------------------------------------------
+# qdelaunay.pro -- Qt project file for qvoronoi.exe
+# -------------------------------------------------
+
+include(../qhull-app-c.pri)
+
+TARGET = qdelaunay
+
+SOURCES += qdelaun.c
diff --git a/xs/src/qhull/src/qhalf/qhalf.c b/xs/src/qhull/src/qhalf/qhalf.c
new file mode 100644
index 000000000..4a5889ed7
--- /dev/null
+++ b/xs/src/qhull/src/qhalf/qhalf.c
@@ -0,0 +1,316 @@
+/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qhalf.c
+ compute the intersection of halfspaces about a point
+
+ see unix.c for full interface
+
+ Copyright (c) 1993-2015, The Geometry Center
+*/
+
+#include "libqhull/libqhull.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#if __cplusplus
+extern "C" {
+ int isatty(int);
+}
+
+#elif _MSC_VER
+#include <io.h>
+#define isatty _isatty
+/* int _isatty(int); */
+
+#else
+int isatty(int); /* returns 1 if stdin is a tty
+ if "Undefined symbol" this can be deleted along with call in main() */
+#endif
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt">-</a>
+
+ qh_prompt
+ long prompt for qhull
+
+ notes:
+ restricted version of libqhull.c
+
+ see:
+ concise prompt below
+*/
+
+/* duplicated in qhalf.htm */
+char hidden_options[]=" d n v Qbb QbB Qf Qg Qm Qr QR Qv Qx Qz TR E V Fa FA FC FD FS Ft FV Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
+
+char qh_prompta[]= "\n\
+qhalf- compute the intersection of halfspaces about a point\n\
+ http://www.qhull.org %s\n\
+\n\
+input (stdin):\n\
+ optional interior point: dimension, 1, coordinates\n\
+ first lines: dimension+1 and number of halfspaces\n\
+ other lines: halfspace coefficients followed by offset\n\
+ comments: start with a non-numeric character\n\
+\n\
+options:\n\
+ Hn,n - specify coordinates of interior point\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Qc - keep coplanar halfspaces\n\
+ Qi - keep other redundant halfspaces\n\
+\n\
+Qhull control options:\n\
+ QJn - randomly joggle input in range [-n,n]\n\
+%s%s%s%s"; /* split up qh_prompt for Visual C++ */
+char qh_promptb[]= "\
+ Qbk:0Bk:0 - remove k-th coordinate from input\n\
+ Qs - search all halfspaces for the initial simplex\n\
+ QGn - print intersection if visible to halfspace n, -n for not\n\
+ QVn - print intersections for halfspace n, -n if not\n\
+\n\
+";
+char qh_promptc[]= "\
+Trace options:\n\
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
+ Tc - check frequently during execution\n\
+ Ts - print statistics\n\
+ Tv - verify result: structure, convexity, and redundancy\n\
+ Tz - send all output to stdout\n\
+ TFn - report summary when n or more facets created\n\
+ TI file - input data from file, no spaces or single quotes\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+ TPn - turn on tracing when halfspace n added to intersection\n\
+ TMn - turn on tracing at merge n\n\
+ TWn - trace merge facets when width > n\n\
+ TVn - stop qhull after adding halfspace n, -n for before (see TCn)\n\
+ TCn - stop qhull after building cone for halfspace n (see TVn)\n\
+\n\
+Precision options:\n\
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex\n\
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex\n\
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
+ Rn - randomly perturb computations by a factor of [1-n,1+n]\n\
+ Un - max distance below plane for a new, coplanar halfspace\n\
+ Wn - min facet width for outside halfspace (before roundoff)\n\
+\n\
+Output formats (may be combined; if none, produces a summary to stdout):\n\
+ f - facet dump\n\
+ G - Geomview output (dual convex hull)\n\
+ i - non-redundant halfspaces incident to each intersection\n\
+ m - Mathematica output (dual convex hull)\n\
+ o - OFF format (dual convex hull: dimension, points, and facets)\n\
+ p - vertex coordinates of dual convex hull (coplanars if 'Qc' or 'Qi')\n\
+ s - summary (stderr)\n\
+\n\
+";
+char qh_promptd[]= "\
+More formats:\n\
+ Fc - count plus redundant halfspaces for each intersection\n\
+ - Qc (default) for coplanar and Qi for other redundant\n\
+ Fd - use cdd format for input (homogeneous with offset first)\n\
+ FF - facet dump without ridges\n\
+ FI - ID of each intersection\n\
+ Fm - merge count for each intersection (511 max)\n\
+ FM - Maple output (dual convex hull)\n\
+ Fn - count plus neighboring intersections for each intersection\n\
+ FN - count plus intersections for each non-redundant halfspace\n\
+ FO - options and precision constants\n\
+ Fp - dim, count, and intersection coordinates\n\
+ FP - nearest halfspace and distance for each redundant halfspace\n\
+ FQ - command used for qhalf\n\
+ Fs - summary: #int (8), dim, #halfspaces, #non-redundant, #intersections\n\
+ for output: #non-redundant, #intersections, #coplanar\n\
+ halfspaces, #non-simplicial intersections\n\
+ #real (2), max outer plane, min vertex\n\
+ Fv - count plus non-redundant halfspaces for each intersection\n\
+ Fx - non-redundant halfspaces\n\
+\n\
+";
+char qh_prompte[]= "\
+Geomview output (2-d, 3-d and 4-d; dual convex hull)\n\
+ Ga - all points (i.e., transformed halfspaces) as dots\n\
+ Gp - coplanar points and vertices as radii\n\
+ Gv - vertices (i.e., non-redundant halfspaces) as spheres\n\
+ Gi - inner planes (i.e., halfspace intersections) only\n\
+ Gn - no planes\n\
+ Go - outer planes only\n\
+ Gc - centrums\n\
+ Gh - hyperplane intersections\n\
+ Gr - ridges\n\
+ GDn - drop dimension n in 3-d and 4-d output\n\
+\n\
+Print options:\n\
+ PAn - keep n largest facets (i.e., intersections) by area\n\
+ Pdk:n- drop facet if normal[k] <= n (default 0.0)\n\
+ PDk:n- drop facet if normal[k] >= n\n\
+ Pg - print good facets (needs 'QGn' or 'QVn')\n\
+ PFn - keep facets whose area is at least n\n\
+ PG - print neighbors of good facets\n\
+ PMn - keep n facets with most merges\n\
+ Po - force output. If error, output neighborhood of facet\n\
+ Pp - do not report precision problems\n\
+\n\
+ . - list of all options\n\
+ - - one line descriptions of all options\n\
+ -V - version\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt2">-</a>
+
+ qh_prompt2
+ synopsis for qhull
+*/
+char qh_prompt2[]= "\n\
+qhalf- halfspace intersection about a point. Qhull %s\n\
+ input (stdin): [dim, 1, interior point], dim+1, n, coefficients+offset\n\
+ comments start with a non-numeric character\n\
+\n\
+options (qhalf.htm):\n\
+ Hn,n - specify coordinates of interior point\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Tv - verify result: structure, convexity, and redundancy\n\
+ . - concise list of all options\n\
+ - - one-line description of all options\n\
+ -V - version\n\
+\n\
+output options (subset):\n\
+ s - summary of results (default)\n\
+ Fp - intersection coordinates\n\
+ Fv - non-redundant halfspaces incident to each intersection\n\
+ Fx - non-redundant halfspaces\n\
+ o - OFF file format (dual convex hull)\n\
+ G - Geomview output (dual convex hull)\n\
+ m - Mathematica output (dual convex hull)\n\
+ QVn - print intersections for halfspace n, -n if not\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+\n\
+examples:\n\
+ rbox d | qconvex FQ n | qhalf s H0,0,0 Fp\n\
+ rbox c | qconvex FQ FV n | qhalf s i\n\
+ rbox c | qconvex FQ FV n | qhalf s o\n\
+\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt3">-</a>
+
+ qh_prompt3
+ concise prompt for qhull
+*/
+char qh_prompt3[]= "\n\
+Qhull %s.\n\
+Except for 'F.' and 'PG', upper_case options take an argument.\n\
+\n\
+ incidences Geomview mathematica OFF_format point_dual\n\
+ summary facet_dump\n\
+\n\
+ Fc_redundant Fd_cdd_in FF_dump_xridge FIDs Fmerges\n\
+ Fneighbors FN_intersect FOptions Fp_coordinates FP_nearest\n\
+ FQhalf Fsummary Fv_halfspace FMaple Fx_non_redundant\n\
+\n\
+ Gvertices Gpoints Gall_points Gno_planes Ginner\n\
+ Gcentrums Ghyperplanes Gridges Gouter GDrop_dim\n\
+\n\
+ PArea_keep Pdrop d0:0D0 Pgood PFacet_area_keep\n\
+ PGood_neighbors PMerge_keep Poutput_forced Pprecision_not\n\
+\n\
+ Qbk:0Bk:0_drop Qcoplanar QG_half_good Qi_redundant QJoggle\n\
+ Qsearch_1st Qtriangulate QVertex_good\n\
+\n\
+ T4_trace Tcheck_often Tstatistics Tverify Tz_stdout\n\
+ TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file\n\
+ TWide_trace TVertex_stop TCone_stop\n\
+\n\
+ Angle_max Centrum_size Random_dist Ucoplanar_max Wide_outside\n\
+";
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="main">-</a>
+
+ main( argc, argv )
+ processes the command line, calls qhull() to do the work, and exits
+
+ design:
+ initializes data structures
+ reads points
+ finishes initialization
+ computes convex hull and other structures
+ checks the result
+ writes the output
+ frees memory
+*/
+int main(int argc, char *argv[]) {
+ int curlong, totlong; /* used !qh_NOmem */
+ int exitcode, numpoints, dim;
+ coordT *points;
+ boolT ismalloc;
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ if ((argc == 1) && isatty( 0 /*stdin*/)) {
+ fprintf(stdout, qh_prompt2, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompta, qh_version,
+ qh_promptb, qh_promptc, qh_promptd, qh_prompte);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '.' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompt3, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
+ fprintf(stdout, "%s\n", qh_version2);
+ exit(qh_ERRnone);
+ }
+ qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
+ exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
+ if (!exitcode) {
+ qh NOerrexit = False;
+ qh_option("Halfspace", NULL, NULL);
+ qh HALFspace= True; /* 'H' */
+ qh_checkflags(qh qhull_command, hidden_options);
+ qh_initflags(qh qhull_command);
+ if (qh SCALEinput) {
+ fprintf(qh ferr, "\
+qhull error: options 'Qbk:n' and 'QBk:n' are not used with qhalf.\n\
+ Use 'Qbk:0Bk:0 to drop dimension k.\n");
+ qh_errexit(qh_ERRinput, NULL, NULL);
+ }
+ points= qh_readpoints(&numpoints, &dim, &ismalloc);
+ if (dim >= 5) {
+ qh_option("Qxact_merge", NULL, NULL);
+ qh MERGEexact= True; /* 'Qx' always */
+ }
+ qh_init_B(points, numpoints, dim, ismalloc);
+ qh_qhull();
+ qh_check_output();
+ qh_produce_output();
+ if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ exitcode= qh_ERRnone;
+ }
+ qh NOerrexit= True; /* no more setjmp */
+#ifdef qh_NOmem
+ qh_freeqhull(qh_ALL);
+#else
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
+ totlong, curlong);
+#endif
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/qhalf/qhalf.pro b/xs/src/qhull/src/qhalf/qhalf.pro
new file mode 100644
index 000000000..ebad38789
--- /dev/null
+++ b/xs/src/qhull/src/qhalf/qhalf.pro
@@ -0,0 +1,9 @@
+# -------------------------------------------------
+# qhalf.pro -- Qt project file for qconvex.exe
+# -------------------------------------------------
+
+include(../qhull-app-c.pri)
+
+TARGET = qhalf
+
+SOURCES += qhalf.c
diff --git a/xs/src/qhull/src/qhalf/qhalf_r.c b/xs/src/qhull/src/qhalf/qhalf_r.c
new file mode 100644
index 000000000..c49d777f9
--- /dev/null
+++ b/xs/src/qhull/src/qhalf/qhalf_r.c
@@ -0,0 +1,318 @@
+/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qhalf.c
+ compute the intersection of halfspaces about a point
+
+ see unix.c for full interface
+
+ Copyright (c) 1993-2015, The Geometry Center
+*/
+
+#include "libqhull_r/libqhull_r.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#if __cplusplus
+extern "C" {
+ int isatty(int);
+}
+
+#elif _MSC_VER
+#include <io.h>
+#define isatty _isatty
+/* int _isatty(int); */
+
+#else
+int isatty(int); /* returns 1 if stdin is a tty
+ if "Undefined symbol" this can be deleted along with call in main() */
+#endif
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt">-</a>
+
+ qh_prompt
+ long prompt for qhull
+
+ notes:
+ restricted version of libqhull.c
+
+ see:
+ concise prompt below
+*/
+
+/* duplicated in qhalf.htm */
+char hidden_options[]=" d n v Qbb QbB Qf Qg Qm Qr QR Qv Qx Qz TR E V Fa FA FC FD FS Ft FV Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
+
+char qh_prompta[]= "\n\
+qhalf- compute the intersection of halfspaces about a point\n\
+ http://www.qhull.org %s\n\
+\n\
+input (stdin):\n\
+ optional interior point: dimension, 1, coordinates\n\
+ first lines: dimension+1 and number of halfspaces\n\
+ other lines: halfspace coefficients followed by offset\n\
+ comments: start with a non-numeric character\n\
+\n\
+options:\n\
+ Hn,n - specify coordinates of interior point\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Qc - keep coplanar halfspaces\n\
+ Qi - keep other redundant halfspaces\n\
+\n\
+Qhull control options:\n\
+ QJn - randomly joggle input in range [-n,n]\n\
+%s%s%s%s"; /* split up qh_prompt for Visual C++ */
+char qh_promptb[]= "\
+ Qbk:0Bk:0 - remove k-th coordinate from input\n\
+ Qs - search all halfspaces for the initial simplex\n\
+ QGn - print intersection if visible to halfspace n, -n for not\n\
+ QVn - print intersections for halfspace n, -n if not\n\
+\n\
+";
+char qh_promptc[]= "\
+Trace options:\n\
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
+ Tc - check frequently during execution\n\
+ Ts - print statistics\n\
+ Tv - verify result: structure, convexity, and redundancy\n\
+ Tz - send all output to stdout\n\
+ TFn - report summary when n or more facets created\n\
+ TI file - input data from file, no spaces or single quotes\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+ TPn - turn on tracing when halfspace n added to intersection\n\
+ TMn - turn on tracing at merge n\n\
+ TWn - trace merge facets when width > n\n\
+ TVn - stop qhull after adding halfspace n, -n for before (see TCn)\n\
+ TCn - stop qhull after building cone for halfspace n (see TVn)\n\
+\n\
+Precision options:\n\
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex\n\
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex\n\
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
+ Rn - randomly perturb computations by a factor of [1-n,1+n]\n\
+ Un - max distance below plane for a new, coplanar halfspace\n\
+ Wn - min facet width for outside halfspace (before roundoff)\n\
+\n\
+Output formats (may be combined; if none, produces a summary to stdout):\n\
+ f - facet dump\n\
+ G - Geomview output (dual convex hull)\n\
+ i - non-redundant halfspaces incident to each intersection\n\
+ m - Mathematica output (dual convex hull)\n\
+ o - OFF format (dual convex hull: dimension, points, and facets)\n\
+ p - vertex coordinates of dual convex hull (coplanars if 'Qc' or 'Qi')\n\
+ s - summary (stderr)\n\
+\n\
+";
+char qh_promptd[]= "\
+More formats:\n\
+ Fc - count plus redundant halfspaces for each intersection\n\
+ - Qc (default) for coplanar and Qi for other redundant\n\
+ Fd - use cdd format for input (homogeneous with offset first)\n\
+ FF - facet dump without ridges\n\
+ FI - ID of each intersection\n\
+ Fm - merge count for each intersection (511 max)\n\
+ FM - Maple output (dual convex hull)\n\
+ Fn - count plus neighboring intersections for each intersection\n\
+ FN - count plus intersections for each non-redundant halfspace\n\
+ FO - options and precision constants\n\
+ Fp - dim, count, and intersection coordinates\n\
+ FP - nearest halfspace and distance for each redundant halfspace\n\
+ FQ - command used for qhalf\n\
+ Fs - summary: #int (8), dim, #halfspaces, #non-redundant, #intersections\n\
+ for output: #non-redundant, #intersections, #coplanar\n\
+ halfspaces, #non-simplicial intersections\n\
+ #real (2), max outer plane, min vertex\n\
+ Fv - count plus non-redundant halfspaces for each intersection\n\
+ Fx - non-redundant halfspaces\n\
+\n\
+";
+char qh_prompte[]= "\
+Geomview output (2-d, 3-d and 4-d; dual convex hull)\n\
+ Ga - all points (i.e., transformed halfspaces) as dots\n\
+ Gp - coplanar points and vertices as radii\n\
+ Gv - vertices (i.e., non-redundant halfspaces) as spheres\n\
+ Gi - inner planes (i.e., halfspace intersections) only\n\
+ Gn - no planes\n\
+ Go - outer planes only\n\
+ Gc - centrums\n\
+ Gh - hyperplane intersections\n\
+ Gr - ridges\n\
+ GDn - drop dimension n in 3-d and 4-d output\n\
+\n\
+Print options:\n\
+ PAn - keep n largest facets (i.e., intersections) by area\n\
+ Pdk:n- drop facet if normal[k] <= n (default 0.0)\n\
+ PDk:n- drop facet if normal[k] >= n\n\
+ Pg - print good facets (needs 'QGn' or 'QVn')\n\
+ PFn - keep facets whose area is at least n\n\
+ PG - print neighbors of good facets\n\
+ PMn - keep n facets with most merges\n\
+ Po - force output. If error, output neighborhood of facet\n\
+ Pp - do not report precision problems\n\
+\n\
+ . - list of all options\n\
+ - - one line descriptions of all options\n\
+ -V - version\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt2">-</a>
+
+ qh_prompt2
+ synopsis for qhull
+*/
+char qh_prompt2[]= "\n\
+qhalf- halfspace intersection about a point. Qhull %s\n\
+ input (stdin): [dim, 1, interior point], dim+1, n, coefficients+offset\n\
+ comments start with a non-numeric character\n\
+\n\
+options (qhalf.htm):\n\
+ Hn,n - specify coordinates of interior point\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Tv - verify result: structure, convexity, and redundancy\n\
+ . - concise list of all options\n\
+ - - one-line description of all options\n\
+ -V - version\n\
+\n\
+output options (subset):\n\
+ s - summary of results (default)\n\
+ Fp - intersection coordinates\n\
+ Fv - non-redundant halfspaces incident to each intersection\n\
+ Fx - non-redundant halfspaces\n\
+ o - OFF file format (dual convex hull)\n\
+ G - Geomview output (dual convex hull)\n\
+ m - Mathematica output (dual convex hull)\n\
+ QVn - print intersections for halfspace n, -n if not\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+\n\
+examples:\n\
+ rbox d | qconvex FQ n | qhalf s H0,0,0 Fp\n\
+ rbox c | qconvex FQ FV n | qhalf s i\n\
+ rbox c | qconvex FQ FV n | qhalf s o\n\
+\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt3">-</a>
+
+ qh_prompt3
+ concise prompt for qhull
+*/
+char qh_prompt3[]= "\n\
+Qhull %s.\n\
+Except for 'F.' and 'PG', upper_case options take an argument.\n\
+\n\
+ incidences Geomview mathematica OFF_format point_dual\n\
+ summary facet_dump\n\
+\n\
+ Fc_redundant Fd_cdd_in FF_dump_xridge FIDs Fmerges\n\
+ Fneighbors FN_intersect FOptions Fp_coordinates FP_nearest\n\
+ FQhalf Fsummary Fv_halfspace FMaple Fx_non_redundant\n\
+\n\
+ Gvertices Gpoints Gall_points Gno_planes Ginner\n\
+ Gcentrums Ghyperplanes Gridges Gouter GDrop_dim\n\
+\n\
+ PArea_keep Pdrop d0:0D0 Pgood PFacet_area_keep\n\
+ PGood_neighbors PMerge_keep Poutput_forced Pprecision_not\n\
+\n\
+ Qbk:0Bk:0_drop Qcoplanar QG_half_good Qi_redundant QJoggle\n\
+ Qsearch_1st Qtriangulate QVertex_good\n\
+\n\
+ T4_trace Tcheck_often Tstatistics Tverify Tz_stdout\n\
+ TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file\n\
+ TWide_trace TVertex_stop TCone_stop\n\
+\n\
+ Angle_max Centrum_size Random_dist Ucoplanar_max Wide_outside\n\
+";
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="main">-</a>
+
+ main( argc, argv )
+ processes the command line, calls qhull() to do the work, and exits
+
+ design:
+ initializes data structures
+ reads points
+ finishes initialization
+ computes convex hull and other structures
+ checks the result
+ writes the output
+ frees memory
+*/
+int main(int argc, char *argv[]) {
+ int curlong, totlong; /* used !qh_NOmem */
+ int exitcode, numpoints, dim;
+ coordT *points;
+ boolT ismalloc;
+ qhT qh_qh;
+ qhT *qh= &qh_qh;
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ if ((argc == 1) && isatty( 0 /*stdin*/)) {
+ fprintf(stdout, qh_prompt2, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompta, qh_version,
+ qh_promptb, qh_promptc, qh_promptd, qh_prompte);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '.' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompt3, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
+ fprintf(stdout, "%s\n", qh_version2);
+ exit(qh_ERRnone);
+ }
+ qh_init_A(qh, stdin, stdout, stderr, argc, argv); /* sets qh->qhull_command */
+ exitcode= setjmp(qh->errexit); /* simple statement for CRAY J916 */
+ if (!exitcode) {
+ qh->NOerrexit = False;
+ qh_option(qh, "Halfspace", NULL, NULL);
+ qh->HALFspace= True; /* 'H' */
+ qh_checkflags(qh, qh->qhull_command, hidden_options);
+ qh_initflags(qh, qh->qhull_command);
+ if (qh->SCALEinput) {
+ fprintf(qh->ferr, "\
+qhull error: options 'Qbk:n' and 'QBk:n' are not used with qhalf.\n\
+ Use 'Qbk:0Bk:0 to drop dimension k.\n");
+ qh_errexit(qh, qh_ERRinput, NULL, NULL);
+ }
+ points= qh_readpoints(qh, &numpoints, &dim, &ismalloc);
+ if (dim >= 5) {
+ qh_option(qh, "Qxact_merge", NULL, NULL);
+ qh->MERGEexact= True; /* 'Qx' always */
+ }
+ qh_init_B(qh, points, numpoints, dim, ismalloc);
+ qh_qhull(qh);
+ qh_check_output(qh);
+ qh_produce_output(qh);
+ if (qh->VERIFYoutput && !qh->FORCEoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ exitcode= qh_ERRnone;
+ }
+ qh->NOerrexit= True; /* no more setjmp */
+#ifdef qh_NOmem
+ qh_freeqhull(qh, qh_ALL);
+#else
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
+ totlong, curlong);
+#endif
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/qhull-all.pro b/xs/src/qhull/src/qhull-all.pro
new file mode 100644
index 000000000..1d3a0ac6f
--- /dev/null
+++ b/xs/src/qhull/src/qhull-all.pro
@@ -0,0 +1,94 @@
+# -------------------------------------------------
+# qhull-all.pro -- Qt project to build executables and static libraries
+#
+# To build with Qt on mingw
+# Download Qt SDK, install Perl
+# /c/qt/2010.05/qt> ./configure -static -platform win32-g++ -fast -no-qt3support
+#
+# To build DevStudio sln and proj files (Qhull ships with cmake derived files)
+# qmake is in Qt's bin directory
+# mkdir -p build && cd build && qmake -tp vc -r ../src/qhull-all.pro
+# Additional Library Directories -- C:\qt\Qt5.2.0\5.2.0\msvc2012_64\lib
+# libqhullcpp and libqhullstatic refered to $(QTDIR) but apparently didn't retrieve (should be %QTDIR%?)
+# libqhull_r also needs ..\..\lib
+# Need to change build/x64/Debug/*.lib to lib/ (or copy libs by hand, each time)
+# Additional Build Dependencies
+# See README.txt -- Need to add Build Dependencies, disable rtti, rename targets to qhull.dll, qhull6_p.dll and qhull6_pd.dll
+# -------------------------------------------------
+
+TEMPLATE = subdirs
+CONFIG += ordered
+
+SUBDIRS += libqhull_r #shared library with reentrant code
+SUBDIRS += libqhullstatic #static library
+SUBDIRS += libqhullstatic_r #static library with reentrant code
+SUBDIRS += libqhullcpp #static library for C++ interface with libqhullstatic_r
+
+SUBDIRS += qhull #qhull program linked to libqhullstatic_r
+SUBDIRS += rbox
+SUBDIRS += qconvex #qhull programs linked to libqhullstatic
+SUBDIRS += qdelaunay
+SUBDIRS += qhalf
+SUBDIRS += qvoronoi
+
+SUBDIRS += user_eg #user programs linked to libqhull_r
+SUBDIRS += user_eg2
+SUBDIRS += user_eg3 #user program with libqhullcpp and libqhullstatic_r
+
+SUBDIRS += qhulltest #C++ test program with Qt, libqhullcpp, and libqhullstatic_r
+SUBDIRS += testqset #test program for qset.c with mem.c
+SUBDIRS += testqset_r #test program for qset_r.c with mem_r.c
+ #See eg/q_test for qhull tests
+
+OTHER_FILES += Changes.txt
+OTHER_FILES += CMakeLists.txt
+OTHER_FILES += Make-config.sh
+OTHER_FILES += ../Announce.txt
+OTHER_FILES += ../CMakeLists.txt
+OTHER_FILES += ../COPYING.txt
+OTHER_FILES += ../File_id.diz
+OTHER_FILES += ../index.htm
+OTHER_FILES += ../Makefile
+OTHER_FILES += ../README.txt
+OTHER_FILES += ../REGISTER.txt
+OTHER_FILES += ../eg/q_eg
+OTHER_FILES += ../eg/q_egtest
+OTHER_FILES += ../eg/q_test
+OTHER_FILES += ../html/index.htm
+OTHER_FILES += ../html/qconvex.htm
+OTHER_FILES += ../html/qdelau_f.htm
+OTHER_FILES += ../html/qdelaun.htm
+OTHER_FILES += ../html/qhalf.htm
+OTHER_FILES += ../html/qh-code.htm
+OTHER_FILES += ../html/qh-eg.htm
+OTHER_FILES += ../html/qh-faq.htm
+OTHER_FILES += ../html/qh-get.htm
+OTHER_FILES += ../html/qh-impre.htm
+OTHER_FILES += ../html/qh-optc.htm
+OTHER_FILES += ../html/qh-optf.htm
+OTHER_FILES += ../html/qh-optg.htm
+OTHER_FILES += ../html/qh-opto.htm
+OTHER_FILES += ../html/qh-optp.htm
+OTHER_FILES += ../html/qh-optq.htm
+OTHER_FILES += ../html/qh-optt.htm
+OTHER_FILES += ../html/qh-quick.htm
+OTHER_FILES += ../html/qhull.htm
+OTHER_FILES += ../html/qhull.man
+OTHER_FILES += ../html/qhull.txt
+OTHER_FILES += ../html/qhull-cpp.xml
+OTHER_FILES += ../html/qvoron_f.htm
+OTHER_FILES += ../html/qvoronoi.htm
+OTHER_FILES += ../html/rbox.htm
+OTHER_FILES += ../html/rbox.man
+OTHER_FILES += ../html/rbox.txt
+OTHER_FILES += ../src/libqhull/Makefile
+OTHER_FILES += ../src/libqhull_r/Makefile
+OTHER_FILES += ../src/libqhull_r/qhull_r-exports.def
+OTHER_FILES += ../src/qconvex/qconvex_r.c
+OTHER_FILES += ../src/qdelaunay/qdelaun_r.c
+OTHER_FILES += ../src/qhalf/qhalf_r.c
+OTHER_FILES += ../src/qhull/rbox_r.c
+OTHER_FILES += ../src/qvoronoi/qvoronoi_r.c
+OTHER_FILES += ../src/qhull/unix.c
+OTHER_FILES += ../src/user_eg/user_eg.c
+OTHER_FILES += ../src/user_eg2/user_eg2.c
diff --git a/xs/src/qhull/src/qhull-app-c.pri b/xs/src/qhull/src/qhull-app-c.pri
new file mode 100644
index 000000000..05e5a00f2
--- /dev/null
+++ b/xs/src/qhull/src/qhull-app-c.pri
@@ -0,0 +1,24 @@
+# -------------------------------------------------
+# qhull-app-c.pri -- Qt include project for C qhull applications linked to libqhull
+# -------------------------------------------------
+
+include(qhull-warn.pri)
+
+DESTDIR = ../../bin
+TEMPLATE = app
+CONFIG += console warn_on
+CONFIG -= qt
+
+LIBS += -L../../lib
+build_pass:CONFIG(debug, debug|release){
+ LIBS += -lqhullstatic_d
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release){
+ LIBS += -lqhullstatic
+ OBJECTS_DIR = Release
+}
+win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
+
+INCLUDEPATH += ..
+CONFIG += qhull_warn_conversion
+
diff --git a/xs/src/qhull/src/qhull-app-c_r.pri b/xs/src/qhull/src/qhull-app-c_r.pri
new file mode 100644
index 000000000..9c2ef5600
--- /dev/null
+++ b/xs/src/qhull/src/qhull-app-c_r.pri
@@ -0,0 +1,26 @@
+# -------------------------------------------------
+# qhull-app-c_r.pri -- Qt include project for C qhull applications linked to qhullstatic_r
+#
+# It uses reentrant Qhull
+# -------------------------------------------------
+
+include(qhull-warn.pri)
+
+DESTDIR = ../../bin
+TEMPLATE = app
+CONFIG += console warn_on
+CONFIG -= qt
+
+LIBS += -L../../lib
+build_pass:CONFIG(debug, debug|release){
+ LIBS += -lqhullstatic_rd
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release){
+ LIBS += -lqhullstatic_r
+ OBJECTS_DIR = Release
+}
+win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
+
+INCLUDEPATH += ..
+CONFIG += qhull_warn_conversion
+
diff --git a/xs/src/qhull/src/qhull-app-cpp.pri b/xs/src/qhull/src/qhull-app-cpp.pri
new file mode 100644
index 000000000..a6f17d8ec
--- /dev/null
+++ b/xs/src/qhull/src/qhull-app-cpp.pri
@@ -0,0 +1,23 @@
+# -------------------------------------------------
+# qhull-app-cpp.pri -- Qt include project for qhull as C++ classes
+# -------------------------------------------------
+
+include(qhull-warn.pri)
+
+DESTDIR = ../../bin
+TEMPLATE = app
+CONFIG += console warn_on
+CONFIG -= rtti
+LIBS += -L../../lib
+build_pass:CONFIG(debug, debug|release){
+ LIBS += -lqhullcpp_d
+ LIBS += -lqhullstatic_rd # Must be last, otherwise qh_fprintf,etc. are loaded from here instead of qhullcpp-d.lib
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release){
+ LIBS += -lqhullcpp
+ LIBS += -lqhullstatic_r # Must be last, otherwise qh_fprintf,etc. are loaded from here instead of qhullcpp.lib
+ OBJECTS_DIR = Release
+}
+win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
+
+INCLUDEPATH += ../../src # "libqhull_r/qhull_a.h"
diff --git a/xs/src/qhull/src/qhull-app-shared.pri b/xs/src/qhull/src/qhull-app-shared.pri
new file mode 100644
index 000000000..1f4026a6a
--- /dev/null
+++ b/xs/src/qhull/src/qhull-app-shared.pri
@@ -0,0 +1,27 @@
+# -------------------------------------------------
+# qhull-app-shared.pri -- Deprecated Qt include project for C qhull applications linked with libqhull (shared library)
+# -------------------------------------------------
+
+include(qhull-warn.pri)
+
+DESTDIR = ../../bin
+TEMPLATE = app
+CONFIG += console warn_on
+CONFIG -= qt
+
+LIBS += -L../../lib
+build_pass:CONFIG(debug, debug|release){
+ LIBS += -lqhull_d
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release){
+ LIBS += -lqhull
+ OBJECTS_DIR = Release
+}
+win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
+
+win32-msvc* : DEFINES += qh_dllimport # libqhull/user.h
+
+INCLUDEPATH += ../libqhull
+CONFIG += qhull_warn_conversion
+
+
diff --git a/xs/src/qhull/src/qhull-app-shared_r.pri b/xs/src/qhull/src/qhull-app-shared_r.pri
new file mode 100644
index 000000000..e55c1a65f
--- /dev/null
+++ b/xs/src/qhull/src/qhull-app-shared_r.pri
@@ -0,0 +1,29 @@
+# -------------------------------------------------
+# qhull-app-shared_r.pri -- Qt include project for C qhull applications linked with libqhull_r (shared library)
+#
+# It uses reentrant Qhull
+# -------------------------------------------------
+
+include(qhull-warn.pri)
+
+DESTDIR = ../../bin
+TEMPLATE = app
+CONFIG += console warn_on
+CONFIG -= qt
+
+LIBS += -L../../lib
+build_pass:CONFIG(debug, debug|release){
+ LIBS += -lqhull_rd
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release){
+ LIBS += -lqhull_r
+ OBJECTS_DIR = Release
+}
+win32-msvc* : QMAKE_LFLAGS += /INCREMENTAL:NO
+
+win32-msvc* : DEFINES += qh_dllimport # libqhull_r/user.h
+
+INCLUDEPATH += ..
+CONFIG += qhull_warn_conversion
+
+
diff --git a/xs/src/qhull/src/qhull-libqhull-src.pri b/xs/src/qhull/src/qhull-libqhull-src.pri
new file mode 100644
index 000000000..e7aff3f78
--- /dev/null
+++ b/xs/src/qhull/src/qhull-libqhull-src.pri
@@ -0,0 +1,39 @@
+# -------------------------------------------------
+# qhull-libqhull-src.pri -- Qt include project for libqhull sources and headers
+# libqhull.pro, libqhullp.pro, and libqhulldll.pro are the same for SOURCES and HEADERS
+# -------------------------------------------------
+
+# Order object files by frequency of execution. Small files at end.
+# Current directory is caller
+
+# libqhull/libqhull.pro and ../qhull-libqhull-src.pri have the same SOURCES and HEADERS
+SOURCES += ../libqhull/global.c
+SOURCES += ../libqhull/stat.c
+SOURCES += ../libqhull/geom2.c
+SOURCES += ../libqhull/poly2.c
+SOURCES += ../libqhull/merge.c
+SOURCES += ../libqhull/libqhull.c
+SOURCES += ../libqhull/geom.c
+SOURCES += ../libqhull/poly.c
+SOURCES += ../libqhull/qset.c
+SOURCES += ../libqhull/mem.c
+SOURCES += ../libqhull/random.c
+SOURCES += ../libqhull/usermem.c
+SOURCES += ../libqhull/userprintf.c
+SOURCES += ../libqhull/io.c
+SOURCES += ../libqhull/user.c
+SOURCES += ../libqhull/rboxlib.c
+SOURCES += ../libqhull/userprintf_rbox.c
+
+# [2014] qmake locates the headers in the shadow build directory not the src directory
+HEADERS += ../libqhull/geom.h
+HEADERS += ../libqhull/io.h
+HEADERS += ../libqhull/libqhull.h
+HEADERS += ../libqhull/mem.h
+HEADERS += ../libqhull/merge.h
+HEADERS += ../libqhull/poly.h
+HEADERS += ../libqhull/random.h
+HEADERS += ../libqhull/qhull_a.h
+HEADERS += ../libqhull/qset.h
+HEADERS += ../libqhull/stat.h
+HEADERS += ../libqhull/user.h
diff --git a/xs/src/qhull/src/qhull-libqhull-src_r.pri b/xs/src/qhull/src/qhull-libqhull-src_r.pri
new file mode 100644
index 000000000..3b53291b1
--- /dev/null
+++ b/xs/src/qhull/src/qhull-libqhull-src_r.pri
@@ -0,0 +1,39 @@
+# -------------------------------------------------
+# qhull-libqhull-src_r.pri -- Qt include project for libqhull_r sources and headers
+#
+# It uses reentrant Qhull
+# -------------------------------------------------
+
+# Order object files by frequency of execution. Small files at end.
+# Current directory is caller
+
+# libqhull_r/libqhull_r.pro and ../qhull-libqhull-src_r.pri have the same SOURCES and HEADERS
+SOURCES += ../libqhull_r/global_r.c
+SOURCES += ../libqhull_r/stat_r.c
+SOURCES += ../libqhull_r/geom2_r.c
+SOURCES += ../libqhull_r/poly2_r.c
+SOURCES += ../libqhull_r/merge_r.c
+SOURCES += ../libqhull_r/libqhull_r.c
+SOURCES += ../libqhull_r/geom_r.c
+SOURCES += ../libqhull_r/poly_r.c
+SOURCES += ../libqhull_r/qset_r.c
+SOURCES += ../libqhull_r/mem_r.c
+SOURCES += ../libqhull_r/random_r.c
+SOURCES += ../libqhull_r/usermem_r.c
+SOURCES += ../libqhull_r/userprintf_r.c
+SOURCES += ../libqhull_r/io_r.c
+SOURCES += ../libqhull_r/user_r.c
+SOURCES += ../libqhull_r/rboxlib_r.c
+SOURCES += ../libqhull_r/userprintf_rbox_r.c
+
+HEADERS += ../libqhull_r/geom_r.h
+HEADERS += ../libqhull_r/io_r.h
+HEADERS += ../libqhull_r/libqhull_r.h
+HEADERS += ../libqhull_r/mem_r.h
+HEADERS += ../libqhull_r/merge_r.h
+HEADERS += ../libqhull_r/poly_r.h
+HEADERS += ../libqhull_r/random_r.h
+HEADERS += ../libqhull_r/qhull_ra.h
+HEADERS += ../libqhull_r/qset_r.h
+HEADERS += ../libqhull_r/stat_r.h
+HEADERS += ../libqhull_r/user_r.h
diff --git a/xs/src/qhull/src/qhull-warn.pri b/xs/src/qhull/src/qhull-warn.pri
new file mode 100644
index 000000000..7d0e7fa2f
--- /dev/null
+++ b/xs/src/qhull/src/qhull-warn.pri
@@ -0,0 +1,57 @@
+# -------------------------------------------------
+# qhull-warn.pri -- Qt project warnings for warn_on
+# CONFIG += qhull_warn_all # Qhull compiles with all warnings except for qhull_warn_shadow and qhull_warn_conversion
+# CONFIG += qhull_warn_conversion # Warn in Qt and Qhull about conversion errors
+# CONFIG += qhull_warn_error # Turn warnings into errors
+# CONFIG += qhull_warn_shadow # Warn in Qt about shadowing of functions and fields
+# -------------------------------------------------
+
+# [apr'11] VERSION works erratically for msvc builds
+# VERSION = 7.2.0
+qhull_SOVERSION = 7
+
+# Uncomment to report warnings as errors
+#CONFIG += qhull_warn_error
+
+*g++{
+ qhull_warn_error{
+ QMAKE_CFLAGS_WARN_ON += -Werror
+ QMAKE_CXXFLAGS_WARN_ON += -Werror
+ }
+
+ QMAKE_CFLAGS_WARN_ON += -Wcast-qual -Wextra -Wshadow -Wwrite-strings
+
+ QMAKE_CXXFLAGS_WARN_ON += -Wcast-qual -Wextra -Wwrite-strings
+ QMAKE_CXXFLAGS_WARN_ON += -Wno-sign-conversion
+
+ qhull_warn_shadow{
+ QMAKE_CXXFLAGS_WARN_ON += -Wshadow # Shadowing occurs in Qt, e.g., nested foreach
+ }
+
+ qhull_warn_conversion{
+ QMAKE_CFLAGS_WARN_ON += -Wno-sign-conversion # libqhullstatic has many size_t vs. int warnings
+ QMAKE_CFLAGS_WARN_ON += -Wconversion # libqhullstatic has no workaround for bit-field conversions
+ QMAKE_CXXFLAGS_WARN_ON += -Wconversion # Qt has conversion errors for qbitarray and qpalette
+ }
+
+ qhull_warn_all{
+ QMAKE_CFLAGS_WARN_ON += -Waddress -Warray-bounds -Wchar-subscripts -Wclobbered -Wcomment -Wempty-body
+ QMAKE_CFLAGS_WARN_ON += -Wformat -Wignored-qualifiers -Wimplicit-function-declaration -Wimplicit-int
+ QMAKE_CFLAGS_WARN_ON += -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-parameter-type
+ QMAKE_CFLAGS_WARN_ON += -Wnonnull -Wold-style-declaration -Woverride-init -Wparentheses
+ QMAKE_CFLAGS_WARN_ON += -Wpointer-sign -Wreturn-type -Wsequence-point -Wsign-compare
+ QMAKE_CFLAGS_WARN_ON += -Wsign-compare -Wstrict-aliasing -Wstrict-overflow=1 -Wswitch
+ QMAKE_CFLAGS_WARN_ON += -Wtrigraphs -Wtype-limits -Wuninitialized -Wuninitialized
+ QMAKE_CFLAGS_WARN_ON += -Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-parameter
+ QMAKE_CFLAGS_WARN_ON += -Wunused-value -Wunused-variable -Wvolatile-register-var
+
+ QMAKE_CXXFLAGS_WARN_ON += -Waddress -Warray-bounds -Wc++0x-compat -Wchar-subscripts
+ QMAKE_CXXFLAGS_WARN_ON += -Wclobbered -Wcomment -Wempty-body -Wenum-compare
+ QMAKE_CXXFLAGS_WARN_ON += -Wformat -Wignored-qualifiers -Wmain -Wmissing-braces
+ QMAKE_CXXFLAGS_WARN_ON += -Wmissing-field-initializers -Wparentheses -Wreorder -Wreturn-type
+ QMAKE_CXXFLAGS_WARN_ON += -Wsequence-point -Wsign-compare -Wsign-compare -Wstrict-aliasing
+ QMAKE_CXXFLAGS_WARN_ON += -Wstrict-overflow=1 -Wswitch -Wtrigraphs -Wtype-limits
+ QMAKE_CXXFLAGS_WARN_ON += -Wuninitialized -Wunknown-pragmas -Wunused-function -Wunused-label
+ QMAKE_CXXFLAGS_WARN_ON += -Wunused-parameter -Wunused-value -Wunused-variable -Wvolatile-register-var
+ }
+}
diff --git a/xs/src/qhull/src/qhull/qhull.pro b/xs/src/qhull/src/qhull/qhull.pro
new file mode 100644
index 000000000..839372856
--- /dev/null
+++ b/xs/src/qhull/src/qhull/qhull.pro
@@ -0,0 +1,9 @@
+# -------------------------------------------------
+# qhull.pro -- Qt project file for qhull.exe with libqhullstatic_r
+# -------------------------------------------------
+
+include(../qhull-app-c_r.pri)
+
+TARGET = qhull
+
+SOURCES += unix_r.c
diff --git a/xs/src/qhull/src/qhull/unix.c b/xs/src/qhull/src/qhull/unix.c
new file mode 100644
index 000000000..892a819c3
--- /dev/null
+++ b/xs/src/qhull/src/qhull/unix.c
@@ -0,0 +1,372 @@
+/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ unix.c
+ command line interface to qhull
+ includes SIOUX interface for Macintoshes
+
+ see qh-qhull.htm
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/qhull/unix.c#4 $$Change: 2066 $
+ $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+*/
+
+#include "libqhull/libqhull.h"
+#include "libqhull/qset.h"
+
+#include <ctype.h>
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if __cplusplus
+extern "C" {
+ int isatty(int);
+}
+
+#elif _MSC_VER
+#include <io.h>
+#define isatty _isatty
+/* int _isatty(int); */
+
+#else
+int isatty(int); /* returns 1 if stdin is a tty
+ if "Undefined symbol" this can be deleted along with call in main() */
+#endif
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt">-</a>
+
+ qh_prompt
+ long prompt for qhull
+
+ see:
+ concise prompt below
+*/
+char qh_prompta[]= "\n\
+qhull- compute convex hulls and related structures.\n\
+ http://www.qhull.org %s\n\
+\n\
+input (stdin):\n\
+ first lines: dimension and number of points (or vice-versa).\n\
+ other lines: point coordinates, best if one point per line\n\
+ comments: start with a non-numeric character\n\
+ halfspaces: use dim plus one and put offset after coefficients.\n\
+ May be preceded by a single interior point ('H').\n\
+\n\
+options:\n\
+ d - Delaunay triangulation by lifting points to a paraboloid\n\
+ d Qu - furthest-site Delaunay triangulation (upper convex hull)\n\
+ v - Voronoi diagram (dual of the Delaunay triangulation)\n\
+ v Qu - furthest-site Voronoi diagram\n\
+ Hn,n,... - halfspace intersection about point [n,n,0,...]\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Qc - keep coplanar points with nearest facet\n\
+ Qi - keep interior points with nearest facet\n\
+\n\
+Qhull control options:\n\
+ Qbk:n - scale coord k so that low bound is n\n\
+ QBk:n - scale coord k so that upper bound is n (QBk is %2.2g)\n\
+ QbB - scale input to unit cube centered at the origin\n\
+ Qbb - scale last coordinate to [0,m] for Delaunay triangulations\n\
+ Qbk:0Bk:0 - remove k-th coordinate from input\n\
+ QJn - randomly joggle input in range [-n,n]\n\
+ QRn - random rotation (n=seed, n=0 time, n=-1 time/no rotate)\n\
+%s%s%s%s"; /* split up qh_prompt for Visual C++ */
+char qh_promptb[]= "\
+ Qf - partition point to furthest outside facet\n\
+ Qg - only build good facets (needs 'QGn', 'QVn', or 'PdD')\n\
+ Qm - only process points that would increase max_outside\n\
+ Qr - process random outside points instead of furthest ones\n\
+ Qs - search all points for the initial simplex\n\
+ Qu - for 'd' or 'v', compute upper hull without point at-infinity\n\
+ returns furthest-site Delaunay triangulation\n\
+ Qv - test vertex neighbors for convexity\n\
+ Qx - exact pre-merges (skips coplanar and angle-coplanar facets)\n\
+ Qz - add point-at-infinity to Delaunay triangulation\n\
+ QGn - good facet if visible from point n, -n for not visible\n\
+ QVn - good facet if it includes point n, -n if not\n\
+ Q0 - turn off default premerge with 'C-0'/'Qx'\n\
+ Q1 - sort merges by type instead of angle\n\
+ Q2 - merge all non-convex at once instead of independent sets\n\
+ Q3 - do not merge redundant vertices\n\
+ Q4 - avoid old->new merges\n\
+ Q5 - do not correct outer planes at end of qhull\n\
+ Q6 - do not pre-merge concave or coplanar facets\n\
+ Q7 - depth-first processing instead of breadth-first\n\
+ Q8 - do not process near-inside points\n\
+ Q9 - process furthest of furthest points\n\
+ Q10 - no special processing for narrow distributions\n\
+ Q11 - copy normals and recompute centrums for tricoplanar facets\n\
+ Q12 - no error on wide merge due to duplicate ridge\n\
+\n\
+";
+char qh_promptc[]= "\
+Topts- Trace options:\n\
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
+ Ta - annotate output with message codes\n\
+ Tc - check frequently during execution\n\
+ Ts - print statistics\n\
+ Tv - verify result: structure, convexity, and point inclusion\n\
+ Tz - send all output to stdout\n\
+ TFn - report summary when n or more facets created\n\
+ TI file - input data from file, no spaces or single quotes\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+ TPn - turn on tracing when point n added to hull\n\
+ TMn - turn on tracing at merge n\n\
+ TWn - trace merge facets when width > n\n\
+ TRn - rerun qhull n times. Use with 'QJn'\n\
+ TVn - stop qhull after adding point n, -n for before (see TCn)\n\
+ TCn - stop qhull after building cone for point n (see TVn)\n\
+\n\
+Precision options:\n\
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex\n\
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex\n\
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
+ En - max roundoff error for distance computation\n\
+ Rn - randomly perturb computations by a factor of [1-n,1+n]\n\
+ Vn - min distance above plane for a visible facet (default 3C-n or En)\n\
+ Un - max distance below plane for a new, coplanar point (default Vn)\n\
+ Wn - min facet width for outside point (before roundoff, default 2Vn)\n\
+\n\
+Output formats (may be combined; if none, produces a summary to stdout):\n\
+ f - facet dump\n\
+ G - Geomview output (see below)\n\
+ i - vertices incident to each facet\n\
+ m - Mathematica output (2-d and 3-d)\n\
+ o - OFF format (dim, points and facets; Voronoi regions)\n\
+ n - normals with offsets\n\
+ p - vertex coordinates or Voronoi vertices (coplanar points if 'Qc')\n\
+ s - summary (stderr)\n\
+\n\
+";
+char qh_promptd[]= "\
+More formats:\n\
+ Fa - area for each facet\n\
+ FA - compute total area and volume for option 's'\n\
+ Fc - count plus coplanar points for each facet\n\
+ use 'Qc' (default) for coplanar and 'Qi' for interior\n\
+ FC - centrum or Voronoi center for each facet\n\
+ Fd - use cdd format for input (homogeneous with offset first)\n\
+ FD - use cdd format for numeric output (offset first)\n\
+ FF - facet dump without ridges\n\
+ Fi - inner plane for each facet\n\
+ for 'v', separating hyperplanes for bounded Voronoi regions\n\
+ FI - ID of each facet\n\
+ Fm - merge count for each facet (511 max)\n\
+ FM - Maple output (2-d and 3-d)\n\
+ Fn - count plus neighboring facets for each facet\n\
+ FN - count plus neighboring facets for each point\n\
+ Fo - outer plane (or max_outside) for each facet\n\
+ for 'v', separating hyperplanes for unbounded Voronoi regions\n\
+ FO - options and precision constants\n\
+ Fp - dim, count, and intersection coordinates (halfspace only)\n\
+ FP - nearest vertex and distance for each coplanar point\n\
+ FQ - command used for qhull\n\
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
+ output: #vertices, #facets, #coplanars, #nonsimplicial\n\
+ #real (2), max outer plane, min vertex\n\
+ FS - sizes: #int (0)\n\
+ #real (2) tot area, tot volume\n\
+ Ft - triangulation with centrums for non-simplicial facets (OFF format)\n\
+ Fv - count plus vertices for each facet\n\
+ for 'v', Voronoi diagram as Voronoi vertices for pairs of sites\n\
+ FV - average of vertices (a feasible point for 'H')\n\
+ Fx - extreme points (in order for 2-d)\n\
+\n\
+";
+char qh_prompte[]= "\
+Geomview options (2-d, 3-d, and 4-d; 2-d Voronoi)\n\
+ Ga - all points as dots\n\
+ Gp - coplanar points and vertices as radii\n\
+ Gv - vertices as spheres\n\
+ Gi - inner planes only\n\
+ Gn - no planes\n\
+ Go - outer planes only\n\
+ Gc - centrums\n\
+ Gh - hyperplane intersections\n\
+ Gr - ridges\n\
+ GDn - drop dimension n in 3-d and 4-d output\n\
+ Gt - for 3-d 'd', transparent outer ridges\n\
+\n\
+Print options:\n\
+ PAn - keep n largest facets by area\n\
+ Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
+ PDk:n - drop facet if normal[k] >= n\n\
+ Pg - print good facets (needs 'QGn' or 'QVn')\n\
+ PFn - keep facets whose area is at least n\n\
+ PG - print neighbors of good facets\n\
+ PMn - keep n facets with most merges\n\
+ Po - force output. If error, output neighborhood of facet\n\
+ Pp - do not report precision problems\n\
+\n\
+ . - list of all options\n\
+ - - one line descriptions of all options\n\
+ -V - version\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt2">-</a>
+
+ qh_prompt2
+ synopsis for qhull
+*/
+char qh_prompt2[]= "\n\
+qhull- compute convex hulls and related structures. Qhull %s\n\
+ input (stdin): dimension, n, point coordinates\n\
+ comments start with a non-numeric character\n\
+ halfspace: use dim+1 and put offsets after coefficients\n\
+\n\
+options (qh-quick.htm):\n\
+ d - Delaunay triangulation by lifting points to a paraboloid\n\
+ d Qu - furthest-site Delaunay triangulation (upper convex hull)\n\
+ v - Voronoi diagram as the dual of the Delaunay triangulation\n\
+ v Qu - furthest-site Voronoi diagram\n\
+ H1,1 - Halfspace intersection about [1,1,0,...] via polar duality\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Tv - verify result: structure, convexity, and point inclusion\n\
+ . - concise list of all options\n\
+ - - one-line description of each option\n\
+ -V - version\n\
+\n\
+Output options (subset):\n\
+ s - summary of results (default)\n\
+ i - vertices incident to each facet\n\
+ n - normals with offsets\n\
+ p - vertex coordinates (if 'Qc', includes coplanar points)\n\
+ if 'v', Voronoi vertices\n\
+ Fp - halfspace intersections\n\
+ Fx - extreme points (convex hull vertices)\n\
+ FA - compute total area and volume\n\
+ o - OFF format (if 'v', outputs Voronoi regions)\n\
+ G - Geomview output (2-d, 3-d and 4-d)\n\
+ m - Mathematica output (2-d and 3-d)\n\
+ QVn - print facets that include point n, -n if not\n\
+ TO file- output results to file, may be enclosed in single quotes\n\
+\n\
+examples:\n\
+ rbox D4 | qhull Tv rbox 1000 s | qhull Tv s FA\n\
+ rbox 10 D2 | qhull d QJ s i TO result rbox 10 D2 | qhull v Qbb Qt p\n\
+ rbox 10 D2 | qhull d Qu QJ m rbox 10 D2 | qhull v Qu QJ o\n\
+ rbox c d D2 | qhull Qc s f Fx | more rbox c | qhull FV n | qhull H Fp\n\
+ rbox d D12 | qhull QR0 FA rbox c D7 | qhull FA TF1000\n\
+ rbox y 1000 W0 | qhull rbox c | qhull n\n\
+\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt3">-</a>
+
+ qh_prompt3
+ concise prompt for qhull
+*/
+char qh_prompt3[]= "\n\
+Qhull %s.\n\
+Except for 'F.' and 'PG', upper-case options take an argument.\n\
+\n\
+ delaunay voronoi Geomview Halfspace facet_dump\n\
+ incidences mathematica normals OFF_format points\n\
+ summary\n\
+\n\
+ Farea FArea-total Fcoplanars FCentrums Fd-cdd-in\n\
+ FD-cdd-out FF-dump-xridge Finner FIDs Fmerges\n\
+ Fneighbors FNeigh-vertex Fouter FOptions Fpoint-intersect\n\
+ FPoint_near FQhull Fsummary FSize Ftriangles\n\
+ Fvertices Fvoronoi FVertex-ave Fxtremes FMaple\n\
+\n\
+ Gvertices Gpoints Gall_points Gno_planes Ginner\n\
+ Gcentrums Ghyperplanes Gridges Gouter GDrop_dim\n\
+ Gtransparent\n\
+\n\
+ PArea-keep Pdrop d0:0D0 Pgood PFacet_area_keep\n\
+ PGood_neighbors PMerge-keep Poutput_forced Pprecision_not\n\
+\n\
+ QbBound 0:0.5 Qbk:0Bk:0_drop QbB-scale-box Qbb-scale-last Qcoplanar\n\
+ Qfurthest Qgood_only QGood_point Qinterior Qmax_out\n\
+ QJoggle Qrandom QRotate Qsearch_1st Qtriangulate\n\
+ QupperDelaunay QVertex_good Qvneighbors Qxact_merge Qzinfinite\n\
+\n\
+ Q0_no_premerge Q1_no_angle Q2_no_independ Q3_no_redundant Q4_no_old\n\
+ Q5_no_check_out Q6_no_concave Q7_depth_first Q8_no_near_in Q9_pick_furthest\n\
+ Q10_no_narrow Q11_trinormals Q12_no_wide_dup\n\
+\n\
+ T4_trace Tannotate Tcheck_often Tstatistics Tverify\n\
+ Tz_stdout TFacet_log TInput_file TPoint_trace TMerge_trace\n\
+ TOutput_file TRerun TWide_trace TVertex_stop TCone_stop\n\
+\n\
+ Angle_max Centrum_size Error_round Random_dist Visible_min\n\
+ Ucoplanar_max Wide_outside\n\
+";
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="main">-</a>
+
+ main( argc, argv )
+ processes the command line, calls qhull() to do the work, and exits
+
+ design:
+ initializes data structures
+ reads points
+ finishes initialization
+ computes convex hull and other structures
+ checks the result
+ writes the output
+ frees memory
+*/
+int main(int argc, char *argv[]) {
+ int curlong, totlong; /* used !qh_NOmem */
+ int exitcode, numpoints, dim;
+ coordT *points;
+ boolT ismalloc;
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ if ((argc == 1) && isatty( 0 /*stdin*/)) {
+ fprintf(stdout, qh_prompt2, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompta, qh_version, qh_DEFAULTbox,
+ qh_promptb, qh_promptc, qh_promptd, qh_prompte);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '.' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompt3, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
+ fprintf(stdout, "%s\n", qh_version2);
+ exit(qh_ERRnone);
+ }
+ qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
+ exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
+ if (!exitcode) {
+ qh_initflags(qh qhull_command);
+ points= qh_readpoints(&numpoints, &dim, &ismalloc);
+ qh_init_B(points, numpoints, dim, ismalloc);
+ qh_qhull();
+ qh_check_output();
+ qh_produce_output();
+ if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ exitcode= qh_ERRnone;
+ }
+ qh NOerrexit= True; /* no more setjmp */
+#ifdef qh_NOmem
+ qh_freeqhull( qh_ALL);
+#else
+ qh_freeqhull( !qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
+ totlong, curlong);
+#endif
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/qhull/unix_r.c b/xs/src/qhull/src/qhull/unix_r.c
new file mode 100644
index 000000000..3f999f7fa
--- /dev/null
+++ b/xs/src/qhull/src/qhull/unix_r.c
@@ -0,0 +1,374 @@
+/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ unix.c
+ command line interface to qhull
+ includes SIOUX interface for Macintoshes
+
+ see qh-qhull.htm
+
+ Copyright (c) 1993-2015 The Geometry Center.
+ $Id: //main/2015/qhull/src/qhull/unix_r.c#6 $$Change: 2066 $
+ $DateTime: 2016/01/18 19:29:17 $$Author: bbarber $
+*/
+
+#include "libqhull_r/libqhull_r.h"
+
+#include <ctype.h>
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if __cplusplus
+extern "C" {
+ int isatty(int);
+}
+
+#elif _MSC_VER
+#include <io.h>
+#define isatty _isatty
+/* int _isatty(int); */
+
+#else
+int isatty(int); /* returns 1 if stdin is a tty
+ if "Undefined symbol" this can be deleted along with call in main() */
+#endif
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt">-</a>
+
+ qh_prompt
+ long prompt for qhull
+
+ see:
+ concise prompt below
+*/
+char qh_prompta[]= "\n\
+qhull- compute convex hulls and related structures.\n\
+ http://www.qhull.org %s\n\
+\n\
+input (stdin):\n\
+ first lines: dimension and number of points (or vice-versa).\n\
+ other lines: point coordinates, best if one point per line\n\
+ comments: start with a non-numeric character\n\
+ halfspaces: use dim plus one and put offset after coefficients.\n\
+ May be preceded by a single interior point ('H').\n\
+\n\
+options:\n\
+ d - Delaunay triangulation by lifting points to a paraboloid\n\
+ d Qu - furthest-site Delaunay triangulation (upper convex hull)\n\
+ v - Voronoi diagram (dual of the Delaunay triangulation)\n\
+ v Qu - furthest-site Voronoi diagram\n\
+ Hn,n,... - halfspace intersection about point [n,n,0,...]\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Qc - keep coplanar points with nearest facet\n\
+ Qi - keep interior points with nearest facet\n\
+\n\
+Qhull control options:\n\
+ Qbk:n - scale coord k so that low bound is n\n\
+ QBk:n - scale coord k so that upper bound is n (QBk is %2.2g)\n\
+ QbB - scale input to unit cube centered at the origin\n\
+ Qbb - scale last coordinate to [0,m] for Delaunay triangulations\n\
+ Qbk:0Bk:0 - remove k-th coordinate from input\n\
+ QJn - randomly joggle input in range [-n,n]\n\
+ QRn - random rotation (n=seed, n=0 time, n=-1 time/no rotate)\n\
+%s%s%s%s"; /* split up qh_prompt for Visual C++ */
+char qh_promptb[]= "\
+ Qf - partition point to furthest outside facet\n\
+ Qg - only build good facets (needs 'QGn', 'QVn', or 'PdD')\n\
+ Qm - only process points that would increase max_outside\n\
+ Qr - process random outside points instead of furthest ones\n\
+ Qs - search all points for the initial simplex\n\
+ Qu - for 'd' or 'v', compute upper hull without point at-infinity\n\
+ returns furthest-site Delaunay triangulation\n\
+ Qv - test vertex neighbors for convexity\n\
+ Qx - exact pre-merges (skips coplanar and angle-coplanar facets)\n\
+ Qz - add point-at-infinity to Delaunay triangulation\n\
+ QGn - good facet if visible from point n, -n for not visible\n\
+ QVn - good facet if it includes point n, -n if not\n\
+ Q0 - turn off default premerge with 'C-0'/'Qx'\n\
+ Q1 - sort merges by type instead of angle\n\
+ Q2 - merge all non-convex at once instead of independent sets\n\
+ Q3 - do not merge redundant vertices\n\
+ Q4 - avoid old->new merges\n\
+ Q5 - do not correct outer planes at end of qhull\n\
+ Q6 - do not pre-merge concave or coplanar facets\n\
+ Q7 - depth-first processing instead of breadth-first\n\
+ Q8 - do not process near-inside points\n\
+ Q9 - process furthest of furthest points\n\
+ Q10 - no special processing for narrow distributions\n\
+ Q11 - copy normals and recompute centrums for tricoplanar facets\n\
+ Q12 - no error on wide merge due to duplicate ridge\n\
+\n\
+";
+char qh_promptc[]= "\
+Topts- Trace options:\n\
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
+ Ta - annotate output with message codes\n\
+ Tc - check frequently during execution\n\
+ Ts - print statistics\n\
+ Tv - verify result: structure, convexity, and point inclusion\n\
+ Tz - send all output to stdout\n\
+ TFn - report summary when n or more facets created\n\
+ TI file - input data from file, no spaces or single quotes\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+ TPn - turn on tracing when point n added to hull\n\
+ TMn - turn on tracing at merge n\n\
+ TWn - trace merge facets when width > n\n\
+ TRn - rerun qhull n times. Use with 'QJn'\n\
+ TVn - stop qhull after adding point n, -n for before (see TCn)\n\
+ TCn - stop qhull after building cone for point n (see TVn)\n\
+\n\
+Precision options:\n\
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex\n\
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex\n\
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
+ En - max roundoff error for distance computation\n\
+ Rn - randomly perturb computations by a factor of [1-n,1+n]\n\
+ Vn - min distance above plane for a visible facet (default 3C-n or En)\n\
+ Un - max distance below plane for a new, coplanar point (default Vn)\n\
+ Wn - min facet width for outside point (before roundoff, default 2Vn)\n\
+\n\
+Output formats (may be combined; if none, produces a summary to stdout):\n\
+ f - facet dump\n\
+ G - Geomview output (see below)\n\
+ i - vertices incident to each facet\n\
+ m - Mathematica output (2-d and 3-d)\n\
+ o - OFF format (dim, points and facets; Voronoi regions)\n\
+ n - normals with offsets\n\
+ p - vertex coordinates or Voronoi vertices (coplanar points if 'Qc')\n\
+ s - summary (stderr)\n\
+\n\
+";
+char qh_promptd[]= "\
+More formats:\n\
+ Fa - area for each facet\n\
+ FA - compute total area and volume for option 's'\n\
+ Fc - count plus coplanar points for each facet\n\
+ use 'Qc' (default) for coplanar and 'Qi' for interior\n\
+ FC - centrum or Voronoi center for each facet\n\
+ Fd - use cdd format for input (homogeneous with offset first)\n\
+ FD - use cdd format for numeric output (offset first)\n\
+ FF - facet dump without ridges\n\
+ Fi - inner plane for each facet\n\
+ for 'v', separating hyperplanes for bounded Voronoi regions\n\
+ FI - ID of each facet\n\
+ Fm - merge count for each facet (511 max)\n\
+ FM - Maple output (2-d and 3-d)\n\
+ Fn - count plus neighboring facets for each facet\n\
+ FN - count plus neighboring facets for each point\n\
+ Fo - outer plane (or max_outside) for each facet\n\
+ for 'v', separating hyperplanes for unbounded Voronoi regions\n\
+ FO - options and precision constants\n\
+ Fp - dim, count, and intersection coordinates (halfspace only)\n\
+ FP - nearest vertex and distance for each coplanar point\n\
+ FQ - command used for qhull\n\
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
+ output: #vertices, #facets, #coplanars, #nonsimplicial\n\
+ #real (2), max outer plane, min vertex\n\
+ FS - sizes: #int (0)\n\
+ #real (2) tot area, tot volume\n\
+ Ft - triangulation with centrums for non-simplicial facets (OFF format)\n\
+ Fv - count plus vertices for each facet\n\
+ for 'v', Voronoi diagram as Voronoi vertices for pairs of sites\n\
+ FV - average of vertices (a feasible point for 'H')\n\
+ Fx - extreme points (in order for 2-d)\n\
+\n\
+";
+char qh_prompte[]= "\
+Geomview options (2-d, 3-d, and 4-d; 2-d Voronoi)\n\
+ Ga - all points as dots\n\
+ Gp - coplanar points and vertices as radii\n\
+ Gv - vertices as spheres\n\
+ Gi - inner planes only\n\
+ Gn - no planes\n\
+ Go - outer planes only\n\
+ Gc - centrums\n\
+ Gh - hyperplane intersections\n\
+ Gr - ridges\n\
+ GDn - drop dimension n in 3-d and 4-d output\n\
+ Gt - for 3-d 'd', transparent outer ridges\n\
+\n\
+Print options:\n\
+ PAn - keep n largest facets by area\n\
+ Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
+ PDk:n - drop facet if normal[k] >= n\n\
+ Pg - print good facets (needs 'QGn' or 'QVn')\n\
+ PFn - keep facets whose area is at least n\n\
+ PG - print neighbors of good facets\n\
+ PMn - keep n facets with most merges\n\
+ Po - force output. If error, output neighborhood of facet\n\
+ Pp - do not report precision problems\n\
+\n\
+ . - list of all options\n\
+ - - one line descriptions of all options\n\
+ -V - version\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt2">-</a>
+
+ qh_prompt2
+ synopsis for qhull
+*/
+char qh_prompt2[]= "\n\
+qhull- compute convex hulls and related structures. Qhull %s\n\
+ input (stdin): dimension, n, point coordinates\n\
+ comments start with a non-numeric character\n\
+ halfspace: use dim+1 and put offsets after coefficients\n\
+\n\
+options (qh-quick.htm):\n\
+ d - Delaunay triangulation by lifting points to a paraboloid\n\
+ d Qu - furthest-site Delaunay triangulation (upper convex hull)\n\
+ v - Voronoi diagram as the dual of the Delaunay triangulation\n\
+ v Qu - furthest-site Voronoi diagram\n\
+ H1,1 - Halfspace intersection about [1,1,0,...] via polar duality\n\
+ Qt - triangulated output\n\
+ QJ - joggled input instead of merged facets\n\
+ Tv - verify result: structure, convexity, and point inclusion\n\
+ . - concise list of all options\n\
+ - - one-line description of each option\n\
+ -V - version\n\
+\n\
+Output options (subset):\n\
+ s - summary of results (default)\n\
+ i - vertices incident to each facet\n\
+ n - normals with offsets\n\
+ p - vertex coordinates (if 'Qc', includes coplanar points)\n\
+ if 'v', Voronoi vertices\n\
+ Fp - halfspace intersections\n\
+ Fx - extreme points (convex hull vertices)\n\
+ FA - compute total area and volume\n\
+ o - OFF format (if 'v', outputs Voronoi regions)\n\
+ G - Geomview output (2-d, 3-d and 4-d)\n\
+ m - Mathematica output (2-d and 3-d)\n\
+ QVn - print facets that include point n, -n if not\n\
+ TO file- output results to file, may be enclosed in single quotes\n\
+\n\
+examples:\n\
+ rbox D4 | qhull Tv rbox 1000 s | qhull Tv s FA\n\
+ rbox 10 D2 | qhull d QJ s i TO result rbox 10 D2 | qhull v Qbb Qt p\n\
+ rbox 10 D2 | qhull d Qu QJ m rbox 10 D2 | qhull v Qu QJ o\n\
+ rbox c d D2 | qhull Qc s f Fx | more rbox c | qhull FV n | qhull H Fp\n\
+ rbox d D12 | qhull QR0 FA rbox c D7 | qhull FA TF1000\n\
+ rbox y 1000 W0 | qhull rbox c | qhull n\n\
+\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt3">-</a>
+
+ qh_prompt3
+ concise prompt for qhull
+*/
+char qh_prompt3[]= "\n\
+Qhull %s.\n\
+Except for 'F.' and 'PG', upper-case options take an argument.\n\
+\n\
+ delaunay voronoi Geomview Halfspace facet_dump\n\
+ incidences mathematica normals OFF_format points\n\
+ summary\n\
+\n\
+ Farea FArea-total Fcoplanars FCentrums Fd-cdd-in\n\
+ FD-cdd-out FF-dump-xridge Finner FIDs Fmerges\n\
+ Fneighbors FNeigh-vertex Fouter FOptions Fpoint-intersect\n\
+ FPoint_near FQhull Fsummary FSize Ftriangles\n\
+ Fvertices Fvoronoi FVertex-ave Fxtremes FMaple\n\
+\n\
+ Gvertices Gpoints Gall_points Gno_planes Ginner\n\
+ Gcentrums Ghyperplanes Gridges Gouter GDrop_dim\n\
+ Gtransparent\n\
+\n\
+ PArea-keep Pdrop d0:0D0 Pgood PFacet_area_keep\n\
+ PGood_neighbors PMerge-keep Poutput_forced Pprecision_not\n\
+\n\
+ QbBound 0:0.5 Qbk:0Bk:0_drop QbB-scale-box Qbb-scale-last Qcoplanar\n\
+ Qfurthest Qgood_only QGood_point Qinterior Qmax_out\n\
+ QJoggle Qrandom QRotate Qsearch_1st Qtriangulate\n\
+ QupperDelaunay QVertex_good Qvneighbors Qxact_merge Qzinfinite\n\
+\n\
+ Q0_no_premerge Q1_no_angle Q2_no_independ Q3_no_redundant Q4_no_old\n\
+ Q5_no_check_out Q6_no_concave Q7_depth_first Q8_no_near_in Q9_pick_furthest\n\
+ Q10_no_narrow Q11_trinormals Q12_no_wide_dup\n\
+\n\
+ T4_trace Tannotate Tcheck_often Tstatistics Tverify\n\
+ Tz_stdout TFacet_log TInput_file TPoint_trace TMerge_trace\n\
+ TOutput_file TRerun TWide_trace TVertex_stop TCone_stop\n\
+\n\
+ Angle_max Centrum_size Error_round Random_dist Visible_min\n\
+ Ucoplanar_max Wide_outside\n\
+";
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="main">-</a>
+
+ main( argc, argv )
+ processes the command line, calls qhull() to do the work, and exits
+
+ design:
+ initializes data structures
+ reads points
+ finishes initialization
+ computes convex hull and other structures
+ checks the result
+ writes the output
+ frees memory
+*/
+int main(int argc, char *argv[]) {
+ int curlong, totlong; /* used !qh_NOmem */
+ int exitcode, numpoints, dim;
+ coordT *points;
+ boolT ismalloc;
+ qhT qh_qh;
+ qhT *qh= &qh_qh;
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ if ((argc == 1) && isatty( 0 /*stdin*/)) {
+ fprintf(stdout, qh_prompt2, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompta, qh_version, qh_DEFAULTbox,
+ qh_promptb, qh_promptc, qh_promptd, qh_prompte);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '.' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompt3, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
+ fprintf(stdout, "%s\n", qh_version2);
+ exit(qh_ERRnone);
+ }
+ qh_init_A(qh, stdin, stdout, stderr, argc, argv); /* sets qh->qhull_command */
+ exitcode= setjmp(qh->errexit); /* simple statement for CRAY J916 */
+ if (!exitcode) {
+ qh->NOerrexit = False;
+ qh_initflags(qh, qh->qhull_command);
+ points= qh_readpoints(qh, &numpoints, &dim, &ismalloc);
+ qh_init_B(qh, points, numpoints, dim, ismalloc);
+ qh_qhull(qh);
+ qh_check_output(qh);
+ qh_produce_output(qh);
+ if (qh->VERIFYoutput && !qh->FORCEoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ exitcode= qh_ERRnone;
+ }
+ qh->NOerrexit= True; /* no more setjmp */
+#ifdef qh_NOmem
+ qh_freeqhull(qh, qh_ALL);
+#else
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
+ totlong, curlong);
+#endif
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/qhulltest/Coordinates_test.cpp b/xs/src/qhull/src/qhulltest/Coordinates_test.cpp
new file mode 100644
index 000000000..3e8658a5b
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/Coordinates_test.cpp
@@ -0,0 +1,539 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/Coordinates_test.cpp#2 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "qhulltest/RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/Coordinates.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/Qhull.h"
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::ostream;
+using std::string;
+
+namespace orgQhull {
+
+class Coordinates_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void t_construct();
+ void t_convert();
+ void t_element();
+ void t_readonly();
+ void t_operator();
+ void t_const_iterator();
+ void t_iterator();
+ void t_coord_iterator();
+ void t_mutable_coord_iterator();
+ void t_readwrite();
+ void t_search();
+ void t_io();
+};//Coordinates_test
+
+void
+add_Coordinates_test()
+{
+ new Coordinates_test(); // RoadTest::s_testcases
+}
+
+void Coordinates_test::
+t_construct()
+{
+ Coordinates c;
+ QCOMPARE(c.size(), 0U);
+ QVERIFY(c.isEmpty());
+ c << 1.0;
+ QCOMPARE(c.count(), 1);
+ Coordinates c2(c);
+ c2 << 2.0;
+ QCOMPARE(c2.count(), 2);
+ Coordinates c3;
+ c3 = c2;
+ QCOMPARE(c3.count(), 2);
+ QCOMPARE(c3[0]+c3[1], 3.0);
+ QVERIFY(c2==c3);
+ std::vector<coordT> vc;
+ vc.push_back(3.0);
+ vc.push_back(4.0);
+ Coordinates c4(vc);
+ QCOMPARE(c4[0]+c4[1], 7.0);
+ Coordinates c5(c3);
+ QVERIFY(c5==c3);
+ c5= vc;
+ QVERIFY(c5!=c3);
+ QVERIFY(c5==c4);
+}//t_construct
+
+void Coordinates_test::
+t_convert()
+{
+ Coordinates c;
+ c << 1.0 << 3.0;
+ QCOMPARE(c.data()[1], 3.0);
+ coordT *c2= c.data();
+ const coordT *c3= c.data();
+ QCOMPARE(c2, c3);
+ std::vector<coordT> vc= c.toStdVector();
+ QCOMPARE((size_t)vc.size(), c.size());
+ for(int k= (int)vc.size(); k--; ){
+ QCOMPARE(vc[k], c[k]);
+ }
+ QList<coordT> qc= c.toQList();
+ QCOMPARE(qc.count(), c.count());
+ for(int k= qc.count(); k--; ){
+ QCOMPARE(qc[k], c[k]);
+ }
+ Coordinates c4;
+ c4= std::vector<double>(2, 0.0);
+ QCOMPARE(c4.back(), 0.0);
+ Coordinates c5(std::vector<double>(2, 0.0));
+ QCOMPARE(c4.size(), c5.size());
+ QVERIFY(c4==c5);
+}//t_convert
+
+void Coordinates_test::
+t_element()
+{
+ Coordinates c;
+ c << 1.0 << -2.0;
+ c.at(1)= -3;
+ QCOMPARE(c.at(1), -3.0);
+ QCOMPARE(c.back(), -3.0);
+ QCOMPARE(c.front(), 1.0);
+ c[1]= -2.0;
+ QCOMPARE(c[1],-2.0);
+ QCOMPARE(c.first(), 1.0);
+ c.first()= 2.0;
+ QCOMPARE(c.first(), 2.0);
+ QCOMPARE(c.last(), -2.0);
+ c.last()= 0.0;
+ QCOMPARE(c.first()+c.last(), 2.0);
+ coordT *c4= &c.first();
+ const coordT *c5= &c.first();
+ QCOMPARE(c4, c5);
+ coordT *c6= &c.last();
+ const coordT *c7= &c.last();
+ QCOMPARE(c6, c7);
+ Coordinates c2= c.mid(1);
+ QCOMPARE(c2.count(), 1);
+ c << 3.0;
+ Coordinates c3= c.mid(1,1);
+ QCOMPARE(c2, c3);
+ QCOMPARE(c3.value(-1, -1.0), -1.0);
+ QCOMPARE(c3.value(3, 4.0), 4.0);
+ QCOMPARE(c.value(2, 4.0), 3.0);
+}//t_element
+
+void Coordinates_test::
+t_readonly()
+{
+ Coordinates c;
+ QCOMPARE(c.size(), 0u);
+ QCOMPARE(c.count(), 0);
+ QVERIFY(c.isEmpty());
+ c << 1.0 << -2.0;
+ QCOMPARE(c.size(), 2u);
+ QCOMPARE(c.count(), 2);
+ QVERIFY(!c.isEmpty());
+}//t_readonly
+
+void Coordinates_test::
+t_operator()
+{
+ Coordinates c;
+ Coordinates c2(c);
+ QVERIFY(c==c2);
+ QVERIFY(!(c!=c2));
+ c << 1.0;
+ QVERIFY(!(c==c2));
+ QVERIFY(c!=c2);
+ c2 << 1.0;
+ QVERIFY(c==c2);
+ QVERIFY(!(c!=c2));
+ c[0]= 0.0;
+ QVERIFY(c!=c2);
+ Coordinates c3= c+c2;
+ QCOMPARE(c3.count(), 2);
+ QCOMPARE(c3[0], 0.0);
+ QCOMPARE(c3[1], 1.0);
+ c3 += c3;
+ QCOMPARE(c3.count(), 4);
+ QCOMPARE(c3[2], 0.0);
+ QCOMPARE(c3[3], 1.0);
+ c3 += c2;
+ QCOMPARE(c3[4], 1.0);
+ c3 += 5.0;
+ QCOMPARE(c3.count(), 6);
+ QCOMPARE(c3[5], 5.0);
+ // << checked above
+}//t_operator
+
+void Coordinates_test::
+t_const_iterator()
+{
+ Coordinates c;
+ QCOMPARE(c.begin(), c.end());
+ // begin and end checked elsewhere
+ c << 1.0 << 3.0;
+ Coordinates::const_iterator i= c.begin();
+ QCOMPARE(*i, 1.0);
+ QCOMPARE(i[1], 3.0);
+ // i[1]= -3.0; // compiler error
+ // operator-> is not applicable to double
+ QCOMPARE(*i++, 1.0);
+ QCOMPARE(*i, 3.0);
+ QCOMPARE(*i--, 3.0);
+ QCOMPARE(*i, 1.0);
+ QCOMPARE(*(i+1), 3.0);
+ QCOMPARE(*++i, 3.0);
+ QCOMPARE(*(i-1), 1.0);
+ QCOMPARE(*--i, 1.0);
+ QVERIFY(i==c.begin());
+ QVERIFY(i==c.constBegin());
+ QVERIFY(i!=c.end());
+ QVERIFY(i!=c.constEnd());
+ QVERIFY(i<c.end());
+ QVERIFY(i>=c.begin());
+ QVERIFY(i+1<=c.end());
+ QVERIFY(i+1>c.begin());
+ Coordinates::iterator i2= c.begin();
+ Coordinates::const_iterator i3(i2);
+ QCOMPARE(*i3, 1.0);
+ QCOMPARE(i3[1], 3.0);
+}//t_const_iterator
+
+void Coordinates_test::
+t_iterator()
+{
+ Coordinates c;
+ QCOMPARE(c.begin(), c.end());
+ // begin and end checked elsewhere
+ c << 1.0 << 3.0;
+ Coordinates::iterator i= c.begin();
+ QCOMPARE(*i, 1.0);
+ QCOMPARE(i[1], 3.0);
+ *i= -1.0;
+ QCOMPARE(*i, -1.0);
+ i[1]= -3.0;
+ QCOMPARE(i[1], -3.0);
+ *i= 1.0;
+ // operator-> is not applicable to double
+ QCOMPARE(*i++, 1.0);
+ QCOMPARE(*i, -3.0);
+ *i= 3.0;
+ QCOMPARE(*i--, 3.0);
+ QCOMPARE(*i, 1.0);
+ QCOMPARE(*(i+1), 3.0);
+ QCOMPARE(*++i, 3.0);
+ QCOMPARE(*(i-1), 1.0);
+ QCOMPARE(*--i, 1.0);
+ QVERIFY(i==c.begin());
+ QVERIFY(i==c.constBegin());
+ QVERIFY(i!=c.end());
+ QVERIFY(i!=c.constEnd());
+ QVERIFY(i<c.end());
+ QVERIFY(i>=c.begin());
+ QVERIFY(i+1<=c.end());
+ QVERIFY(i+1>c.begin());
+}//t_iterator
+
+void Coordinates_test::
+t_coord_iterator()
+{
+ Coordinates c;
+ c << 1.0 << 3.0;
+ CoordinatesIterator i(c);
+ CoordinatesIterator i2= c;
+ QVERIFY(i.findNext(1.0));
+ QVERIFY(!i.findNext(2.0));
+ QVERIFY(!i.findNext(3.0));
+ QVERIFY(i.findPrevious(3.0));
+ QVERIFY(!i.findPrevious(2.0));
+ QVERIFY(!i.findPrevious(1.0));
+ QVERIFY(i2.findNext(3.0));
+ QVERIFY(i2.findPrevious(3.0));
+ QVERIFY(i2.findNext(3.0));
+ QVERIFY(i2.findPrevious(1.0));
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i.toBack();
+ i2.toFront();
+ QVERIFY(!i.hasNext());
+ QVERIFY(i.hasPrevious());
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ Coordinates c2;
+ i2= c2;
+ QVERIFY(!i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ i2.toBack();
+ QVERIFY(!i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ QCOMPARE(i.peekPrevious(), 3.0);
+ QCOMPARE(i.previous(), 3.0);
+ QCOMPARE(i.previous(), 1.0);
+ QVERIFY(!i.hasPrevious());
+ QCOMPARE(i.peekNext(), 1.0);
+ // i.peekNext()= 1.0; // compiler error
+ QCOMPARE(i.next(), 1.0);
+ QCOMPARE(i.peekNext(), 3.0);
+ QCOMPARE(i.next(), 3.0);
+ QVERIFY(!i.hasNext());
+ i.toFront();
+ QCOMPARE(i.next(), 1.0);
+}//t_coord_iterator
+
+void Coordinates_test::
+t_mutable_coord_iterator()
+{
+ // Same tests as CoordinatesIterator
+ Coordinates c;
+ c << 1.0 << 3.0;
+ MutableCoordinatesIterator i(c);
+ MutableCoordinatesIterator i2= c;
+ QVERIFY(i.findNext(1.0));
+ QVERIFY(!i.findNext(2.0));
+ QVERIFY(!i.findNext(3.0));
+ QVERIFY(i.findPrevious(3.0));
+ QVERIFY(!i.findPrevious(2.0));
+ QVERIFY(!i.findPrevious(1.0));
+ QVERIFY(i2.findNext(3.0));
+ QVERIFY(i2.findPrevious(3.0));
+ QVERIFY(i2.findNext(3.0));
+ QVERIFY(i2.findPrevious(1.0));
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i.toBack();
+ i2.toFront();
+ QVERIFY(!i.hasNext());
+ QVERIFY(i.hasPrevious());
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ Coordinates c2;
+ i2= c2;
+ QVERIFY(!i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ i2.toBack();
+ QVERIFY(!i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ QCOMPARE(i.peekPrevious(), 3.0);
+ QCOMPARE(i.peekPrevious(), 3.0);
+ QCOMPARE(i.previous(), 3.0);
+ QCOMPARE(i.previous(), 1.0);
+ QVERIFY(!i.hasPrevious());
+ QCOMPARE(i.peekNext(), 1.0);
+ QCOMPARE(i.next(), 1.0);
+ QCOMPARE(i.peekNext(), 3.0);
+ QCOMPARE(i.next(), 3.0);
+ QVERIFY(!i.hasNext());
+ i.toFront();
+ QCOMPARE(i.next(), 1.0);
+
+ // Mutable tests
+ i.toFront();
+ i.peekNext()= -1.0;
+ QCOMPARE(i.peekNext(), -1.0);
+ QCOMPARE((i.next()= 1.0), 1.0);
+ QCOMPARE(i.peekPrevious(), 1.0);
+ i.remove();
+ QCOMPARE(c.count(), 1);
+ i.remove();
+ QCOMPARE(c.count(), 1);
+ QCOMPARE(i.peekNext(), 3.0);
+ i.insert(1.0);
+ i.insert(2.0);
+ QCOMPARE(c.count(), 3);
+ QCOMPARE(i.peekNext(), 3.0);
+ QCOMPARE(i.peekPrevious(), 2.0);
+ i.peekPrevious()= -2.0;
+ QCOMPARE(i.peekPrevious(), -2.0);
+ QCOMPARE((i.previous()= 2.0), 2.0);
+ QCOMPARE(i.peekNext(), 2.0);
+ i.toBack();
+ i.remove();
+ QCOMPARE(c.count(), 3); // unchanged
+ i.toFront();
+ i.remove();
+ QCOMPARE(c.count(), 3); // unchanged
+ QCOMPARE(i.peekNext(), 1.0);
+ i.remove();
+ QCOMPARE(c.count(), 3); // unchanged
+ i.insert(0.0);
+ QCOMPARE(c.count(), 4);
+ QCOMPARE(i.value(), 0.0);
+ QCOMPARE(i.peekPrevious(), 0.0);
+ i.setValue(-10.0);
+ QCOMPARE(c.count(), 4); // unchanged
+ QCOMPARE(i.peekNext(), 1.0);
+ QCOMPARE(i.peekPrevious(), -10.0);
+ i.findNext(1.0);
+ i.setValue(-1.0);
+ QCOMPARE(i.peekPrevious(), -1.0);
+ i.setValue(1.0);
+ QCOMPARE(i.peekPrevious(), 1.0);
+ QCOMPARE(i.value(), 1.0);
+ i.findPrevious(1.0);
+ i.setValue(-1.0);
+ QCOMPARE(i.peekNext(), -1.0);
+ i.toBack();
+ QCOMPARE(i.previous(), 3.0);
+ i.setValue(-3.0);
+ QCOMPARE(i.peekNext(), -3.0);
+ double d= i.value();
+ QCOMPARE(d, -3.0);
+ QCOMPARE(i.previous(), 2.0);
+}//t_mutable_coord_iterator
+
+void Coordinates_test::
+t_readwrite()
+{
+ Coordinates c;
+ c.clear();
+ QCOMPARE(c.count(), 0);
+ c << 1.0 << 3.0;
+ c.clear();
+ QCOMPARE(c.count(), 0);
+ coordT c2[4]= { 0.0, 1.0, 2.0, 3.0};
+ c.append(4, c2);
+ QCOMPARE(c.count(), 4);
+ QCOMPARE(c[0], 0.0);
+ QCOMPARE(c[1], 1.0);
+ QCOMPARE(c[3], 3.0);
+ c.clear();
+ c << 1.0 << 3.0;
+ c.erase(c.begin(), c.end());
+ QCOMPARE(c.count(), 0);
+ c << 1.0 << 0.0;
+ Coordinates::iterator i= c.erase(c.begin());
+ QCOMPARE(*i, 0.0);
+ i= c.insert(c.end(), 1.0);
+ QCOMPARE(*i, 1.0);
+ QCOMPARE(c.count(), 2);
+ c.pop_back();
+ QCOMPARE(c.count(), 1); // 0
+ QCOMPARE(c[0], 0.0);
+ c.push_back(2.0);
+ QCOMPARE(c.count(), 2);
+ c.append(3.0);
+ QCOMPARE(c.count(), 3); // 0, 2, 3
+ QCOMPARE(c[2], 3.0);
+ c.insert(0, 4.0);
+ QCOMPARE(c[0], 4.0);
+ QCOMPARE(c[3], 3.0);
+ c.insert(c.count(), 5.0);
+ QCOMPARE(c.count(), 5); // 4, 0, 2, 3, 5
+ QCOMPARE(c[4], 5.0);
+ c.move(4, 0);
+ QCOMPARE(c.count(), 5); // 5, 4, 0, 2, 3
+ QCOMPARE(c[0], 5.0);
+ c.pop_front();
+ QCOMPARE(c.count(), 4);
+ QCOMPARE(c[0], 4.0);
+ c.prepend(6.0);
+ QCOMPARE(c.count(), 5); // 6, 4, 0, 2, 3
+ QCOMPARE(c[0], 6.0);
+ c.push_front(7.0);
+ QCOMPARE(c.count(), 6);
+ QCOMPARE(c[0], 7.0);
+ c.removeAt(1);
+ QCOMPARE(c.count(), 5); // 7, 4, 0, 2, 3
+ QCOMPARE(c[1], 4.0);
+ c.removeFirst();
+ QCOMPARE(c.count(), 4); // 4, 0, 2, 3
+ QCOMPARE(c[0], 4.0);
+ c.removeLast();
+ QCOMPARE(c.count(), 3);
+ QCOMPARE(c.last(), 2.0);
+ c.replace(2, 8.0);
+ QCOMPARE(c.count(), 3); // 4, 0, 8
+ QCOMPARE(c[2], 8.0);
+ c.swap(0, 2);
+ QCOMPARE(c[2], 4.0);
+ double d= c.takeAt(2);
+ QCOMPARE(c.count(), 2); // 8, 0
+ QCOMPARE(d, 4.0);
+ double d2= c.takeFirst();
+ QCOMPARE(c.count(), 1); // 0
+ QCOMPARE(d2, 8.0);
+ double d3= c.takeLast();
+ QVERIFY(c.isEmpty()); \
+ QCOMPARE(d3, 0.0);
+}//t_readwrite
+
+void Coordinates_test::
+t_search()
+{
+ Coordinates c;
+ c << 1.0 << 3.0 << 1.0;
+ QVERIFY(c.contains(1.0));
+ QVERIFY(c.contains(3.0));
+ QVERIFY(!c.contains(0.0));
+ QCOMPARE(c.count(1.0), 2);
+ QCOMPARE(c.count(3.0), 1);
+ QCOMPARE(c.count(0.0), 0);
+ QCOMPARE(c.indexOf(1.0), 0);
+ QCOMPARE(c.indexOf(3.0), 1);
+ QCOMPARE(c.indexOf(1.0, -1), 2);
+ QCOMPARE(c.indexOf(3.0, -1), -1);
+ QCOMPARE(c.indexOf(3.0, -2), 1);
+ QCOMPARE(c.indexOf(1.0, -3), 0);
+ QCOMPARE(c.indexOf(1.0, -4), 0);
+ QCOMPARE(c.indexOf(1.0, 1), 2);
+ QCOMPARE(c.indexOf(3.0, 2), -1);
+ QCOMPARE(c.indexOf(1.0, 2), 2);
+ QCOMPARE(c.indexOf(1.0, 3), -1);
+ QCOMPARE(c.indexOf(1.0, 4), -1);
+ QCOMPARE(c.lastIndexOf(1.0), 2);
+ QCOMPARE(c.lastIndexOf(3.0), 1);
+ QCOMPARE(c.lastIndexOf(1.0, -1), 2);
+ QCOMPARE(c.lastIndexOf(3.0, -1), 1);
+ QCOMPARE(c.lastIndexOf(3.0, -2), 1);
+ QCOMPARE(c.lastIndexOf(1.0, -3), 0);
+ QCOMPARE(c.lastIndexOf(1.0, -4), -1);
+ QCOMPARE(c.lastIndexOf(1.0, 1), 0);
+ QCOMPARE(c.lastIndexOf(3.0, 2), 1);
+ QCOMPARE(c.lastIndexOf(1.0, 2), 2);
+ QCOMPARE(c.lastIndexOf(1.0, 3), 2);
+ QCOMPARE(c.lastIndexOf(1.0, 4), 2);
+ c.removeAll(3.0);
+ QCOMPARE(c.count(), 2);
+ c.removeAll(4.0);
+ QCOMPARE(c.count(), 2);
+ c.removeAll(1.0);
+ QCOMPARE(c.count(), 0);
+ c.removeAll(4.0);
+ QCOMPARE(c.count(), 0);
+}//t_search
+
+void Coordinates_test::
+t_io()
+{
+ Coordinates c;
+ c << 1.0 << 2.0 << 3.0;
+ ostringstream os;
+ os << "Coordinates 1-2-3\n" << c;
+ cout << os.str();
+ QString s= QString::fromStdString(os.str());
+ QCOMPARE(s.count("2"), 2);
+}//t_io
+
+}//orgQhull
+
+#include "moc/Coordinates_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/PointCoordinates_test.cpp b/xs/src/qhull/src/qhulltest/PointCoordinates_test.cpp
new file mode 100644
index 000000000..09285954d
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/PointCoordinates_test.cpp
@@ -0,0 +1,478 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/PointCoordinates_test.cpp#2 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "qhulltest/RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/PointCoordinates.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/Qhull.h"
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::ostream;
+using std::string;
+using std::stringstream;
+
+namespace orgQhull {
+
+class PointCoordinates_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void t_construct_q();
+ void t_construct_qh();
+ void t_convert();
+ void t_getset();
+ void t_element();
+ void t_foreach();
+ void t_search();
+ void t_modify();
+ void t_append_points();
+ void t_coord_iterator();
+ void t_io();
+};//PointCoordinates_test
+
+void
+add_PointCoordinates_test()
+{
+ new PointCoordinates_test(); // RoadTest::s_testcases
+}
+
+void PointCoordinates_test::
+t_construct_q()
+{
+ Qhull q;
+ PointCoordinates pc(q);
+ QCOMPARE(pc.size(), 0U);
+ QCOMPARE(pc.coordinateCount(), 0);
+ QCOMPARE(pc.dimension(), 0);
+ QCOMPARE(pc.coordinates(), (coordT *)0);
+ QVERIFY(pc.isEmpty());
+ pc.checkValid();
+ PointCoordinates pc7(q, 2, "test explicit dimension");
+ QCOMPARE(pc7.dimension(), 2);
+ QCOMPARE(pc7.count(), 0);
+ QVERIFY(pc7.isEmpty());
+ QCOMPARE(pc7.comment(), std::string("test explicit dimension"));
+ pc7.checkValid();
+ PointCoordinates pc2(q, "Test pc2");
+ QCOMPARE(pc2.count(), 0);
+ QVERIFY(pc2.isEmpty());
+ QCOMPARE(pc2.comment(), std::string("Test pc2"));
+ pc2.checkValid();
+ PointCoordinates pc3(q, 3, "Test 3-d pc3");
+ QCOMPARE(pc3.dimension(), 3);
+ QVERIFY(pc3.isEmpty());
+ pc3.checkValid();
+ coordT c[]= { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
+ PointCoordinates pc4(q, 2, "Test 2-d pc4", 6, c);
+ QCOMPARE(pc4.dimension(), 2);
+ QCOMPARE(pc4.count(), 3);
+ QCOMPARE(pc4.size(), 3u);
+ QVERIFY(!pc4.isEmpty());
+ pc4.checkValid();
+ QhullPoint p= pc4[2];
+ QCOMPARE(p[1], 5.0);
+ // QhullPoint refers to PointCoordinates
+ p[1] += 1.0;
+ QCOMPARE(pc4[2][1], 6.0);
+ PointCoordinates pc5(q, 4, "Test 4-d pc5 with insufficient coordinates", 6, c);
+ QCOMPARE(pc5.dimension(), 4);
+ QCOMPARE(pc5.count(), 1);
+ QCOMPARE(pc5.extraCoordinatesCount(), 2);
+ QCOMPARE(pc5.extraCoordinates()[1], 5.0);
+ QVERIFY(!pc5.isEmpty());;
+ std::vector<coordT> vc;
+ vc.push_back(3.0);
+ vc.push_back(4.0);
+ vc.push_back(5.0);
+ vc.push_back(6.0);
+ vc.push_back(7.0);
+ vc.push_back(9.0);
+ pc5.append(2, &vc[3]); // Copy of vc[]
+ pc5.checkValid();
+ QhullPoint p5(q, 4, &vc[1]);
+ QCOMPARE(pc5[1], p5);
+ PointCoordinates pc6(pc5); // Makes copy of point_coordinates
+ QCOMPARE(pc6[1], p5);
+ QVERIFY(pc6==pc5);
+ QhullPoint p6= pc5[1]; // Refers to pc5.coordinates
+ pc5[1][0] += 1.0;
+ QCOMPARE(pc5[1], p6);
+ QVERIFY(pc5[1]!=p5);
+ QVERIFY(pc6!=pc5);
+ pc6= pc5;
+ QVERIFY(pc6==pc5);
+ PointCoordinates pc8(q);
+ pc6= pc8;
+ QVERIFY(pc6!=pc5);
+ QVERIFY(pc6.isEmpty());
+}//t_construct_q
+
+void PointCoordinates_test::
+t_construct_qh()
+{
+ QhullQh qh;
+ PointCoordinates pc(&qh);
+ QCOMPARE(pc.size(), 0U);
+ QCOMPARE(pc.coordinateCount(), 0);
+ QCOMPARE(pc.dimension(), 0);
+ QCOMPARE(pc.coordinates(), (coordT *)0);
+ QVERIFY(pc.isEmpty());
+ pc.checkValid();
+ PointCoordinates pc7(&qh, 2, "test explicit dimension");
+ QCOMPARE(pc7.dimension(), 2);
+ QCOMPARE(pc7.count(), 0);
+ QVERIFY(pc7.isEmpty());
+ QCOMPARE(pc7.comment(), std::string("test explicit dimension"));
+ pc7.checkValid();
+ PointCoordinates pc2(&qh, "Test pc2");
+ QCOMPARE(pc2.count(), 0);
+ QVERIFY(pc2.isEmpty());
+ QCOMPARE(pc2.comment(), std::string("Test pc2"));
+ pc2.checkValid();
+ PointCoordinates pc3(&qh, 3, "Test 3-d pc3");
+ QCOMPARE(pc3.dimension(), 3);
+ QVERIFY(pc3.isEmpty());
+ pc3.checkValid();
+ coordT c[]= { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
+ PointCoordinates pc4(&qh, 2, "Test 2-d pc4", 6, c);
+ QCOMPARE(pc4.dimension(), 2);
+ QCOMPARE(pc4.count(), 3);
+ QCOMPARE(pc4.size(), 3u);
+ QVERIFY(!pc4.isEmpty());
+ pc4.checkValid();
+ QhullPoint p= pc4[2];
+ QCOMPARE(p[1], 5.0);
+ // QhullPoint refers to PointCoordinates
+ p[1] += 1.0;
+ QCOMPARE(pc4[2][1], 6.0);
+ PointCoordinates pc5(&qh, 4, "Test 4-d pc5 with insufficient coordinates", 6, c);
+ QCOMPARE(pc5.dimension(), 4);
+ QCOMPARE(pc5.count(), 1);
+ QCOMPARE(pc5.extraCoordinatesCount(), 2);
+ QCOMPARE(pc5.extraCoordinates()[1], 5.0);
+ QVERIFY(!pc5.isEmpty());;
+ std::vector<coordT> vc;
+ vc.push_back(3.0);
+ vc.push_back(4.0);
+ vc.push_back(5.0);
+ vc.push_back(6.0);
+ vc.push_back(7.0);
+ vc.push_back(9.0);
+ pc5.append(2, &vc[3]); // Copy of vc[]
+ pc5.checkValid();
+ QhullPoint p5(&qh, 4, &vc[1]);
+ QCOMPARE(pc5[1], p5);
+ PointCoordinates pc6(pc5); // Makes copy of point_coordinates
+ QCOMPARE(pc6[1], p5);
+ QVERIFY(pc6==pc5);
+ QhullPoint p6= pc5[1]; // Refers to pc5.coordinates
+ pc5[1][0] += 1.0;
+ QCOMPARE(pc5[1], p6);
+ QVERIFY(pc5[1]!=p5);
+ QVERIFY(pc6!=pc5);
+ pc6= pc5;
+ QVERIFY(pc6==pc5);
+ PointCoordinates pc8(&qh);
+ pc6= pc8;
+ QVERIFY(pc6!=pc5);
+ QVERIFY(pc6.isEmpty());
+}//t_construct_qh
+
+void PointCoordinates_test::
+t_convert()
+{
+ Qhull q;
+ //defineAs tested above
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ PointCoordinates ps(q, 3, "two 3-d points", 6, c);
+ QCOMPARE(ps.dimension(), 3);
+ QCOMPARE(ps.size(), 2u);
+ const coordT *c2= ps.constData();
+ QVERIFY(c!=c2);
+ QCOMPARE(c[0], c2[0]);
+ const coordT *c3= ps.data();
+ QCOMPARE(c3, c2);
+ coordT *c4= ps.data();
+ QCOMPARE(c4, c2);
+ std::vector<coordT> vs= ps.toStdVector();
+ QCOMPARE(vs.size(), 6u);
+ QCOMPARE(vs[5], 5.0);
+ QList<coordT> qs= ps.toQList();
+ QCOMPARE(qs.size(), 6);
+ QCOMPARE(qs[5], 5.0);
+}//t_convert
+
+void PointCoordinates_test::
+t_getset()
+{
+ // See t_construct() for test of coordinates, coordinateCount, dimension, empty, isEmpty, ==, !=
+ // See t_construct() for test of checkValid, comment, setDimension
+ Qhull q;
+ PointCoordinates pc(q, "Coordinates c");
+ pc.setComment("New comment");
+ QCOMPARE(pc.comment(), std::string("New comment"));
+ pc.checkValid();
+ pc.makeValid(); // A no-op
+ pc.checkValid();
+ Coordinates cs= pc.getCoordinates();
+ QVERIFY(cs.isEmpty());
+ PointCoordinates pc2(pc);
+ pc.setDimension(3);
+ QVERIFY(pc2!=pc);
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ pc.append(6, c);
+ pc.checkValid();
+ pc.makeValid(); // A no-op
+ QhullPoint p= pc[0];
+ QCOMPARE(p[2], 2.0);
+ try{
+ pc.setDimension(2);
+ QFAIL("setDimension(2) did not fail for 3-d.");
+ }catch (const std::exception &e) {
+ const char *s= e.what();
+ cout << "INFO : Caught " << s;
+ }
+}//t_getset
+
+void PointCoordinates_test::
+t_element()
+{
+ Qhull q;
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ PointCoordinates pc(q, 2, "2-d points", 6, c);
+ QhullPoint p= pc.at(0);
+ QCOMPARE(p, pc[0]);
+ QCOMPARE(p, pc.first());
+ QCOMPARE(p, pc.value(0));
+ p= pc.back();
+ QCOMPARE(p, pc[2]);
+ QCOMPARE(p, pc.last());
+ QCOMPARE(p, pc.value(2));
+ QhullPoints ps= pc.mid(1, 2);
+ QCOMPARE(ps[1], p);
+}//t_element
+
+void PointCoordinates_test::
+t_foreach()
+{
+ Qhull q;
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ PointCoordinates pc(q, 2, "2-d points", 6, c);
+ QhullPoints::Iterator i= pc.begin();
+ QhullPoint p= pc[0];
+ QCOMPARE(*i, p);
+ QCOMPARE((*i)[0], 0.0);
+ QhullPoint p3= pc[2];
+ i= pc.end();
+ QCOMPARE(i[-1], p3);
+ const PointCoordinates pc2(q, 2, "2-d points", 6, c);
+ QhullPoints::ConstIterator i2= pc.begin();
+ const QhullPoint p0= pc2[0];
+ QCOMPARE(*i2, p0);
+ QCOMPARE((*i2)[0], 0.0);
+ QhullPoints::ConstIterator i3= i2;
+ QCOMPARE(i3, i2);
+ QCOMPARE((*i3)[0], 0.0);
+ i3= pc.constEnd();
+ --i3;
+ QhullPoint p2= pc2[2];
+ QCOMPARE(*i3, p2);
+ i= pc.end();
+ QVERIFY(i-1==i3);
+ i2= pc2.end();
+ QVERIFY(i2-1!=i3);
+ QCOMPARE(*(i2-1), *i3);
+ foreach(QhullPoint p3, pc){ //Qt only
+ QVERIFY(p3[0]>=0.0);
+ QVERIFY(p3[0]<=5.0);
+ }
+ Coordinates::ConstIterator i4= pc.beginCoordinates();
+ QCOMPARE(*i4, 0.0);
+ Coordinates::Iterator i5= pc.beginCoordinates();
+ QCOMPARE(*i5, 0.0);
+ i4= pc.beginCoordinates(1);
+ QCOMPARE(*i4, 2.0);
+ i5= pc.beginCoordinates(1);
+ QCOMPARE(*i5, 2.0);
+ i4= pc.endCoordinates();
+ QCOMPARE(*--i4, 5.0);
+ i5= pc.endCoordinates();
+ QCOMPARE(*--i5, 5.0);
+}//t_foreach
+
+void PointCoordinates_test::
+t_search()
+{
+ Qhull q;
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ PointCoordinates pc(q, 2, "2-d points", 6, c);
+ QhullPoint p0= pc[0];
+ QhullPoint p2= pc[2];
+ QVERIFY(pc.contains(p0));
+ QVERIFY(pc.contains(p2));
+ QCOMPARE(pc.count(p0), 1);
+ QCOMPARE(pc.indexOf(p2), 2);
+ QCOMPARE(pc.lastIndexOf(p0), 0);
+}//t_search
+
+void PointCoordinates_test::
+t_modify()
+{
+ Qhull q;
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ PointCoordinates pc(q, 2, "2-d points", 6, c);
+ coordT c3[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ PointCoordinates pc5(q, 2, "test explicit dimension");
+ pc5.append(6, c3); // 0-5
+ QVERIFY(pc5==pc);
+ PointCoordinates pc2(q, 2, "2-d");
+ coordT c2[]= {6.0, 7.0, 8.0, 9.0, 10.0, 11.0};
+ pc2.append(6, c2);
+ QCOMPARE(pc2.count(), 3);
+ pc2.append(14.0);
+ QCOMPARE(pc2.count(), 3);
+ QCOMPARE(pc2.extraCoordinatesCount(), 1);
+ pc2.append(15.0); // 6-11, 14,15
+ QCOMPARE(pc2.count(), 4);
+ QCOMPARE(pc2.extraCoordinatesCount(), 0);
+ QhullPoint p(pc[0]);
+ pc2.append(p); // 6-11, 14,15, 0,1
+ QCOMPARE(pc2.count(), 5);
+ QCOMPARE(pc2.extraCoordinatesCount(), 0);
+ QCOMPARE(pc2.lastIndexOf(p), 4);
+ pc.append(pc2); // Invalidates p
+ QCOMPARE(pc.count(), 8); // 0-11, 14,15, 0,1
+ QCOMPARE(pc.extraCoordinatesCount(), 0);
+ QCOMPARE(pc.lastIndexOf(pc[0]), 7);
+ pc.appendComment(" operators");
+ QCOMPARE(pc.comment(), std::string("2-d points operators"));
+ pc.checkValid();
+ // see t_append_points for appendPoints
+ PointCoordinates pc3= pc+pc2;
+ pc3.checkValid();
+ QCOMPARE(pc3.count(), 13);
+ QCOMPARE(pc3[6][0], 14.0);
+ QCOMPARE(pc3[8][0], 6.0);
+ pc3 += pc;
+ QCOMPARE(pc3.count(), 21);
+ QCOMPARE(pc3[14][0], 2.0);
+ pc3 += 12.0;
+ pc3 += 14.0;
+ QCOMPARE(pc3.count(), 22);
+ QCOMPARE(pc3.last()[0], 12.0);
+ // QhullPoint p3= pc3.first(); // += throws error because append may move the data
+ QhullPoint p3= pc2.first();
+ pc3 += p3;
+ QCOMPARE(pc3.count(), 23);
+ QCOMPARE(pc3.last()[0], 6.0);
+ pc3 << pc;
+ QCOMPARE(pc3.count(), 31);
+ QCOMPARE(pc3.last()[0], 0.0);
+ pc3 << 12.0 << 14.0;
+ QCOMPARE(pc3.count(), 32);
+ QCOMPARE(pc3.last()[0], 12.0);
+ PointCoordinates pc4(pc3);
+ pc4.reserveCoordinates(100);
+ QVERIFY(pc3==pc4);
+}//t_modify
+
+void PointCoordinates_test::
+t_append_points()
+{
+ Qhull q;
+ PointCoordinates pc(q, 2, "stringstream");
+ stringstream s("2 3 1 2 3 4 5 6");
+ pc.appendPoints(s);
+ QCOMPARE(pc.count(), 3);
+}//t_append_points
+
+void PointCoordinates_test::
+t_coord_iterator()
+{
+ Qhull q;
+ PointCoordinates c(q, 2, "2-d");
+ c << 0.0 << 1.0 << 2.0 << 3.0 << 4.0 << 5.0;
+ PointCoordinatesIterator i(c);
+ QhullPoint p0(c[0]);
+ QhullPoint p1(c[1]);
+ QhullPoint p2(c[2]);
+ coordT c2[] = {-1.0, -2.0};
+ QhullPoint p3(q, 2, c2);
+ PointCoordinatesIterator i2= c;
+ QVERIFY(i.findNext(p1));
+ QVERIFY(!i.findNext(p1));
+ QVERIFY(!i.findNext(p2));
+ QVERIFY(!i.findNext(p3));
+ QVERIFY(i.findPrevious(p2));
+ QVERIFY(!i.findPrevious(p2));
+ QVERIFY(!i.findPrevious(p0));
+ QVERIFY(!i.findPrevious(p3));
+ QVERIFY(i2.findNext(p2));
+ QVERIFY(i2.findPrevious(p0));
+ QVERIFY(i2.findNext(p1));
+ QVERIFY(i2.findPrevious(p0));
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i.toBack();
+ i2.toFront();
+ QVERIFY(!i.hasNext());
+ QVERIFY(i.hasPrevious());
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ PointCoordinates c3(q);
+ PointCoordinatesIterator i3= c3;
+ QVERIFY(!i3.hasNext());
+ QVERIFY(!i3.hasPrevious());
+ i3.toBack();
+ QVERIFY(!i3.hasNext());
+ QVERIFY(!i3.hasPrevious());
+ QCOMPARE(i.peekPrevious(), p2);
+ QCOMPARE(i.previous(), p2);
+ QCOMPARE(i.previous(), p1);
+ QCOMPARE(i.previous(), p0);
+ QVERIFY(!i.hasPrevious());
+ QCOMPARE(i.peekNext(), p0);
+ // i.peekNext()= 1.0; // compiler error
+ QCOMPARE(i.next(), p0);
+ QCOMPARE(i.peekNext(), p1);
+ QCOMPARE(i.next(), p1);
+ QCOMPARE(i.next(), p2);
+ QVERIFY(!i.hasNext());
+ i.toFront();
+ QCOMPARE(i.next(), p0);
+}//t_coord_iterator
+
+void PointCoordinates_test::
+t_io()
+{
+ Qhull q;
+ PointCoordinates c(q);
+ ostringstream os;
+ os << "PointCoordinates 0-d\n" << c;
+ c.setDimension(2);
+ c << 1.0 << 2.0 << 3.0 << 1.0 << 2.0 << 3.0;
+ os << "PointCoordinates 1,2 3,1 2,3\n" << c;
+ cout << os.str();
+ QString s= QString::fromStdString(os.str());
+ QCOMPARE(s.count("0"), 3);
+ QCOMPARE(s.count("2"), 5);
+}//t_io
+
+}//orgQhull
+
+#include "moc/PointCoordinates_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullFacetList_test.cpp b/xs/src/qhull/src/qhulltest/QhullFacetList_test.cpp
new file mode 100644
index 000000000..5a09d01da
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullFacetList_test.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullFacetList_test.cpp#3 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "qhulltest/RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/QhullFacetList.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/QhullVertex.h"
+#include "libqhullcpp/QhullVertexSet.h"
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/RboxPoints.h"
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::ostream;
+using std::string;
+
+namespace orgQhull {
+
+class QhullFacetList_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_construct_qh();
+ void t_construct_q();
+ void t_convert();
+ void t_readonly();
+ void t_foreach();
+ void t_io();
+};//QhullFacetList_test
+
+void
+add_QhullFacetList_test()
+{
+ new QhullFacetList_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void QhullFacetList_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void QhullFacetList_test::
+t_construct_qh()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullFacetList fs2= q.facetList();
+ QVERIFY(!fs2.isEmpty());
+ QCOMPARE(fs2.count(),6);
+ QhullFacetList fs3(q.endFacet(), q.endFacet());
+ QVERIFY(fs3.isEmpty());
+ QhullFacetList fs4(q.endFacet().previous(), q.endFacet());
+ QCOMPARE(fs4.count(), 1);
+ QhullFacetList fs5(q.beginFacet(), q.endFacet());
+ QCOMPARE(fs2.count(), fs5.count());
+ QVERIFY(fs2==fs5);
+ QhullFacetList fs6= fs2; // copy constructor
+ QVERIFY(fs6==fs2);
+ std::vector<QhullFacet> fv= fs2.toStdVector();
+ QCOMPARE(fv.size(), 6u);
+}//t_construct_qh
+
+void QhullFacetList_test::
+t_construct_q()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullFacetList fs2= q.facetList();
+ QVERIFY(!fs2.isEmpty());
+ QCOMPARE(fs2.count(),6);
+ QhullFacetList fs3(q.endFacet(), q.endFacet());
+ QVERIFY(fs3.isEmpty());
+ QhullFacetList fs4(q.endFacet().previous(), q.endFacet());
+ QCOMPARE(fs4.count(), 1);
+ QhullFacetList fs5(q.beginFacet(), q.endFacet());
+ QCOMPARE(fs2.count(), fs5.count());
+ QVERIFY(fs2==fs5);
+ QhullFacetList fs6= fs2; // copy constructor
+ QVERIFY(fs6==fs2);
+ std::vector<QhullFacet> fv= fs2.toStdVector();
+ QCOMPARE(fv.size(), 6u);
+}//t_construct_q
+
+void QhullFacetList_test::
+t_convert()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0 QV2"); // rotated unit cube
+ QhullFacetList fs2= q.facetList();
+ QVERIFY(!fs2.isSelectAll());
+ QVERIFY(!fs2.isEmpty());
+ QCOMPARE(fs2.count(),3);
+ std::vector<QhullFacet> fv= fs2.toStdVector();
+ QCOMPARE(fv.size(), 3u);
+ QList<QhullFacet> fv2= fs2.toQList();
+ QCOMPARE(fv2.size(), 3);
+ std::vector<QhullVertex> fv5= fs2.vertices_toStdVector();
+ QCOMPARE(fv5.size(), 7u);
+ QList<QhullVertex> fv6= fs2.vertices_toQList();
+ QCOMPARE(fv6.size(), 7);
+ fs2.selectAll();
+ QVERIFY(fs2.isSelectAll());
+ std::vector<QhullFacet> fv3= fs2.toStdVector();
+ QCOMPARE(fv3.size(), 6u);
+ QList<QhullFacet> fv4= fs2.toQList();
+ QCOMPARE(fv4.size(), 6);
+ std::vector<QhullVertex> fv7= fs2.vertices_toStdVector();
+ QCOMPARE(fv7.size(), 8u);
+ QList<QhullVertex> fv8= fs2.vertices_toQList();
+ QCOMPARE(fv8.size(), 8);
+}//t_convert
+
+//! Spot check properties and read-only. See QhullLinkedList_test
+void QhullFacetList_test::
+t_readonly()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QV0"); // good facets are adjacent to point 0
+ QhullFacetList fs= q.facetList();
+ QVERIFY(!fs.isSelectAll());
+ QCOMPARE(fs.count(), 3);
+ QCOMPARE(fs.first(), q.firstFacet());
+ fs.selectAll();
+ QVERIFY(fs.isSelectAll());
+ QCOMPARE(fs.count(), 6);
+ fs.selectGood();
+ QVERIFY(!fs.isSelectAll());
+ QCOMPARE(fs.count(), 3);
+ fs.selectAll();
+ QVERIFY(fs.isSelectAll());
+ QCOMPARE(fs.count(), 6);
+ QhullFacet f= fs.first();
+ QhullFacet f2= fs.last();
+ fs.selectAll();
+ QVERIFY(fs.contains(f));
+ QVERIFY(fs.contains(f2));
+ QVERIFY(f.isGood());
+ QVERIFY(!f2.isGood());
+ fs.selectGood();
+ QVERIFY(fs.contains(f));
+ QVERIFY(!fs.contains(f2));
+}//t_readonly
+
+void QhullFacetList_test::
+t_foreach()
+{
+ RboxPoints rcube("c");
+ // Spot check predicates and accessors. See QhullLinkedList_test
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullFacetList fs= q.facetList();
+ QVERIFY(fs.contains(q.firstFacet()));
+ QhullFacet f= q.firstFacet().next();
+ QVERIFY(fs.contains(f));
+ QCOMPARE(fs.first(), *fs.begin());
+ QCOMPARE(*(fs.end()-1), fs.last());
+ QCOMPARE(fs.first(), q.firstFacet());
+ QCOMPARE(*fs.begin(), q.beginFacet());
+ QCOMPARE(*fs.end(), q.endFacet());
+}//t_foreach
+
+void QhullFacetList_test::
+t_io()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0 QV0"); // good facets are adjacent to point 0
+ QhullFacetList fs= q.facetList();
+ ostringstream os;
+ os << fs.print("Show all of FacetList\n");
+ os << "\nFacets only\n" << fs;
+ os << "\nVertices only\n" << fs.printVertices();
+ cout << os.str();
+ QString facets= QString::fromStdString(os.str());
+ QCOMPARE(facets.count("(v"), 2*7+12*3*2);
+ QCOMPARE(facets.count(QRegExp("f\\d")), 2*3*7 + 13*3*2);
+ }
+}//t_io
+
+}//orgQhull
+
+#include "moc/QhullFacetList_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullFacetSet_test.cpp b/xs/src/qhull/src/qhulltest/QhullFacetSet_test.cpp
new file mode 100644
index 000000000..a7fe123a2
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullFacetSet_test.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullFacetSet_test.cpp#3 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "qhulltest/RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/QhullFacetSet.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/RboxPoints.h"
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::ostream;
+using std::string;
+
+namespace orgQhull {
+
+class QhullFacetSet_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_construct();
+ void t_convert();
+ void t_readonly();
+ void t_foreach();
+ void t_io();
+};//QhullFacetSet_test
+
+void
+add_QhullFacetSet_test()
+{
+ new QhullFacetSet_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void QhullFacetSet_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void QhullFacetSet_test::
+t_construct()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullFacet f= q.firstFacet();
+ QhullFacetSet fs2= f.neighborFacets();
+ QVERIFY(!fs2.isEmpty());
+ QCOMPARE(fs2.count(),4);
+ QhullFacetSet fs4= fs2; // copy constructor
+ QVERIFY(fs4==fs2);
+ QhullFacetSet fs3(q, q.qh()->facet_mergeset);
+ QVERIFY(fs3.isEmpty());
+}//t_construct
+
+void QhullFacetSet_test::
+t_convert()
+{
+ RboxPoints rcube("c");
+ Qhull q2(rcube,"QR0 QV2"); // rotated unit cube
+ QhullFacet f2= q2.firstFacet();
+ QhullFacetSet fs2= f2.neighborFacets();
+ QVERIFY(!fs2.isSelectAll());
+ QCOMPARE(fs2.count(),2);
+ std::vector<QhullFacet> fv= fs2.toStdVector();
+ QCOMPARE(fv.size(), 2u);
+ QList<QhullFacet> fv2= fs2.toQList();
+ QCOMPARE(fv2.size(), 2);
+ fs2.selectAll();
+ QVERIFY(fs2.isSelectAll());
+ std::vector<QhullFacet> fv3= fs2.toStdVector();
+ QCOMPARE(fv3.size(), 4u);
+ QList<QhullFacet> fv4= fs2.toQList();
+ QCOMPARE(fv4.size(), 4);
+}//t_convert
+
+//! Spot check properties and read-only. See QhullSet_test
+void QhullFacetSet_test::
+t_readonly()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QV0"); // good facets are adjacent to point 0
+ QhullFacetSet fs= q.firstFacet().neighborFacets();
+ QVERIFY(!fs.isSelectAll());
+ QCOMPARE(fs.count(), 2);
+ fs.selectAll();
+ QVERIFY(fs.isSelectAll());
+ QCOMPARE(fs.count(), 4);
+ fs.selectGood();
+ QVERIFY(!fs.isSelectAll());
+ QCOMPARE(fs.count(), 2);
+ QhullFacet f= fs.first();
+ QhullFacet f2= fs.last();
+ fs.selectAll();
+ QVERIFY(fs.contains(f));
+ QVERIFY(fs.contains(f2));
+ QVERIFY(f.isGood());
+ QVERIFY(!f2.isGood());
+ fs.selectGood();
+ QVERIFY(fs.contains(f));
+ QVERIFY(!fs.contains(f2));
+}//t_readonly
+
+void QhullFacetSet_test::
+t_foreach()
+{
+ RboxPoints rcube("c");
+ // Spot check predicates and accessors. See QhullLinkedList_test
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullFacetSet fs= q.firstFacet().neighborFacets();
+ QVERIFY(!fs.contains(q.firstFacet()));
+ QVERIFY(fs.contains(fs.first()));
+ QhullFacet f= q.firstFacet().next();
+ if(!fs.contains(f)){ // check if 'f' is the facet opposite firstFacet()
+ f= f.next();
+ }
+ QVERIFY(fs.contains(f));
+ QCOMPARE(fs.first(), *fs.begin());
+ QCOMPARE(*(fs.end()-1), fs.last());
+}//t_foreach
+
+void QhullFacetSet_test::
+t_io()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0 QV0"); // good facets are adjacent to point 0
+ QhullFacetSet fs= q.firstFacet().neighborFacets();
+ ostringstream os;
+ os << fs.print("Neighbors of first facet with point 0");
+ os << fs.printIdentifiers("\nFacet identifiers: ");
+ cout << os.str();
+ QString facets= QString::fromStdString(os.str());
+ QCOMPARE(facets.count(QRegExp(" f[0-9]")), 2+13*2);
+ }
+}//t_io
+
+}//orgQhull
+
+#include "moc/QhullFacetSet_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullFacet_test.cpp b/xs/src/qhull/src/qhulltest/QhullFacet_test.cpp
new file mode 100644
index 000000000..271f63753
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullFacet_test.cpp
@@ -0,0 +1,283 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullFacet_test.cpp#4 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "qhulltest/RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/Coordinates.h"
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/QhullFacetList.h"
+#include "libqhullcpp/QhullFacetSet.h"
+#include "libqhullcpp/QhullPointSet.h"
+#include "libqhullcpp/QhullRidge.h"
+#include "libqhullcpp/Qhull.h"
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::ostream;
+using std::string;
+
+namespace orgQhull {
+
+class QhullFacet_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_construct_qh();
+ void t_constructConvert();
+ void t_getSet();
+ void t_value();
+ void t_foreach();
+ void t_io();
+};//QhullFacet_test
+
+void
+add_QhullFacet_test()
+{
+ new QhullFacet_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void QhullFacet_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void QhullFacet_test::
+t_construct_qh()
+{
+ // Qhull.runQhull() constructs QhullFacets as facetT
+ QhullQh qh;
+ QhullFacet f(&qh);
+ QVERIFY(!f.isValid());
+ QCOMPARE(f.dimension(),0);
+}//t_construct_qh
+
+void QhullFacet_test::
+t_constructConvert()
+{
+ // Qhull.runQhull() constructs QhullFacets as facetT
+ Qhull q2;
+ QhullFacet f(q2);
+ QVERIFY(!f.isValid());
+ QCOMPARE(f.dimension(),0);
+ RboxPoints rcube("c");
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullFacet f2(q.beginFacet());
+ QCOMPARE(f2.dimension(),3);
+ f= f2; // copy assignment
+ QVERIFY(f.isValid());
+ QCOMPARE(f.dimension(),3);
+ QhullFacet f5= f2;
+ QVERIFY(f5==f2);
+ QVERIFY(f5==f);
+ QhullFacet f3(q, f2.getFacetT());
+ QCOMPARE(f,f3);
+ QhullFacet f4(q, f2.getBaseT());
+ QCOMPARE(f,f4);
+}//t_constructConvert
+
+void QhullFacet_test::
+t_getSet()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ cout << " rbox c | qhull Qt QR0 QR" << q.rotateRandom() << " distanceEpsilon " << q.distanceEpsilon() << endl;
+ QCOMPARE(q.facetCount(), 12);
+ QCOMPARE(q.vertexCount(), 8);
+ QhullFacetListIterator i(q.facetList());
+ while(i.hasNext()){
+ const QhullFacet f= i.next();
+ cout << f.id() << endl;
+ QCOMPARE(f.dimension(),3);
+ QVERIFY(f.id()>0 && f.id()<=39);
+ QVERIFY(f.isValid());
+ if(i.hasNext()){
+ QCOMPARE(f.next(), i.peekNext());
+ QVERIFY(f.next()!=f);
+ }
+ QVERIFY(i.hasPrevious());
+ QCOMPARE(f, i.peekPrevious());
+ }
+
+ // test tricoplanarOwner
+ QhullFacet facet = q.beginFacet();
+ QhullFacet tricoplanarOwner = facet.tricoplanarOwner();
+ int tricoplanarCount= 0;
+ i.toFront();
+ while(i.hasNext()){
+ const QhullFacet f= i.next();
+ if(f.tricoplanarOwner()==tricoplanarOwner){
+ tricoplanarCount++;
+ }
+ }
+ QCOMPARE(tricoplanarCount, 2);
+ int tricoplanarCount2= 0;
+ foreach (QhullFacet f, q.facetList()){ // Qt only
+ QhullHyperplane h= f.hyperplane();
+ cout << "Hyperplane: " << h;
+ QCOMPARE(h.count(), 3);
+ QCOMPARE(h.offset(), -0.5);
+ double n= h.norm();
+ QCOMPARE(n, 1.0);
+ QhullHyperplane hi= f.innerplane();
+ QCOMPARE(hi.count(), 3);
+ double innerOffset= hi.offset()+0.5;
+ cout << "InnerPlane: " << hi << " innerOffset+0.5 " << innerOffset << endl;
+ QVERIFY(innerOffset >= 0.0-(2*q.distanceEpsilon())); // A guessed epsilon. It needs to account for roundoff due to rotation of the vertices
+ QhullHyperplane ho= f.outerplane();
+ QCOMPARE(ho.count(), 3);
+ double outerOffset= ho.offset()+0.5;
+ cout << "OuterPlane: " << ho << " outerOffset+0.5 " << outerOffset << endl;
+ QVERIFY(outerOffset <= 0.0+(2*q.distanceEpsilon())); // A guessed epsilon. It needs to account for roundoff due to rotation of the vertices
+ QVERIFY(outerOffset-innerOffset < 1e-7);
+ for(int k= 0; k<3; k++){
+ QVERIFY(ho[k]==hi[k]);
+ QVERIFY(ho[k]==h[k]);
+ }
+ QhullPoint center= f.getCenter();
+ cout << "Center: " << center;
+ double d= f.distance(center);
+ QVERIFY(d < innerOffset-outerOffset);
+ QhullPoint center2= f.getCenter(qh_PRINTcentrums);
+ QCOMPARE(center, center2);
+ if(f.tricoplanarOwner()==tricoplanarOwner){
+ tricoplanarCount2++;
+ }
+ cout << endl;
+ }
+ QCOMPARE(tricoplanarCount2, 2);
+ Qhull q2(rcube,"d Qz Qt QR0"); // 3-d triangulation of Delaunay triangulation (the cube)
+ cout << " rbox c | qhull d Qz Qt QR0 QR" << q2.rotateRandom() << " distanceEpsilon " << q2.distanceEpsilon() << endl;
+ QhullFacet f2= q2.firstFacet();
+ QhullPoint center3= f2.getCenter(qh_PRINTtriangles);
+ QCOMPARE(center3.dimension(), 3);
+ QhullPoint center4= f2.getCenter();
+ QCOMPARE(center4.dimension(), 4);
+ for(int k= 0; k<3; k++){
+ QVERIFY(center4[k]==center3[k]);
+ }
+ Qhull q3(rcube,"v Qz QR0"); // Voronoi diagram of a cube (one vertex)
+ cout << " rbox c | qhull v Qz QR0 QR" << q3.rotateRandom() << " distanceEpsilon " << q3.distanceEpsilon() << endl;
+
+ q3.setFactorEpsilon(400); // Voronoi vertices are not necessarily within distance episilon
+ QhullPoint origin= q3.inputOrigin();
+ int voronoiCount= 0;
+ foreach(QhullFacet f, q3.facetList()){ //Qt only
+ if(f.isGood()){
+ ++voronoiCount;
+ QhullPoint p= f.voronoiVertex();
+ cout << p.print("Voronoi vertex: ")
+ << " Is it within " << q3.factorEpsilon() << " * distanceEpsilon (" << q3.distanceEpsilon() << ") of the origin?" << endl;
+ QCOMPARE(p, origin);
+ }
+ }
+ QCOMPARE(voronoiCount, 1);
+ }
+}//t_getSet
+
+void QhullFacet_test::
+t_value()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube, "");
+ coordT c[]= {0.0, 0.0, 0.0};
+ foreach (QhullFacet f, q.facetList()){ // Qt only
+ double d= f.distance(q.origin());
+ QCOMPARE(d, -0.5);
+ double d0= f.distance(c);
+ QCOMPARE(d0, -0.5);
+ double facetArea= f.facetArea();
+ QCOMPARE(facetArea, 1.0);
+ #if qh_MAXoutside
+ double maxoutside= f.getFacetT()->maxoutside;
+ QVERIFY(maxoutside<1e-7);
+ #endif
+ }
+ }
+}//t_value
+
+void QhullFacet_test::
+t_foreach()
+{
+ RboxPoints rcube("c W0 300"); // cube plus 300 points on its surface
+ {
+ Qhull q(rcube, "QR0 Qc"); // keep coplanars, thick facet, and rotate the cube
+ int coplanarCount= 0;
+ foreach(const QhullFacet f, q.facetList()){
+ QhullPointSet coplanars= f.coplanarPoints();
+ coplanarCount += coplanars.count();
+ QhullFacetSet neighbors= f.neighborFacets();
+ QCOMPARE(neighbors.count(), 4);
+ QhullPointSet outsides= f.outsidePoints();
+ QCOMPARE(outsides.count(), 0);
+ QhullRidgeSet ridges= f.ridges();
+ QCOMPARE(ridges.count(), 4);
+ QhullVertexSet vertices= f.vertices();
+ QCOMPARE(vertices.count(), 4);
+ int ridgeCount= 0;
+ QhullRidge r= ridges.first();
+ for(int r0= r.id(); ridgeCount==0 || r.id()!=r0; r= r.nextRidge3d(f)){
+ ++ridgeCount;
+ if(!r.hasNextRidge3d(f)){
+ QFAIL("Unexpected simplicial facet. They only have ridges to non-simplicial neighbors.");
+ }
+ }
+ QCOMPARE(ridgeCount, 4);
+ }
+ QCOMPARE(coplanarCount, 300);
+ }
+}//t_foreach
+
+void QhullFacet_test::
+t_io()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube, "");
+ QhullFacet f= q.beginFacet();
+ cout << f;
+ ostringstream os;
+ os << f.print("\nWith a message\n");
+ os << "\nPrint header for the same facet\n";
+ os << f.printHeader();
+ os << "\nPrint each component\n";
+ os << f.printFlags(" - flags:");
+ os << f.printCenter(qh_PRINTfacets, " - center: ");
+ os << f.printRidges();
+ cout << os.str();
+ ostringstream os2;
+ os2 << f;
+ QString facetString2= QString::fromStdString(os2.str());
+ facetString2.replace(QRegExp("\\s\\s+"), " ");
+ ostringstream os3;
+ q.qh()->setOutputStream(&os3);
+ q.outputQhull("f");
+ QString facetsString= QString::fromStdString(os3.str());
+ QString facetString3= facetsString.mid(facetsString.indexOf("- f1\n"));
+ facetString3= facetString3.left(facetString3.indexOf("\n- f")+1);
+ facetString3.replace(QRegExp("\\s\\s+"), " ");
+ QCOMPARE(facetString2, facetString3);
+ }
+}//t_io
+
+// toQhullFacet is static_cast only
+
+}//orgQhull
+
+#include "moc/QhullFacet_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullHyperplane_test.cpp b/xs/src/qhull/src/qhulltest/QhullHyperplane_test.cpp
new file mode 100644
index 000000000..d016989a9
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullHyperplane_test.cpp
@@ -0,0 +1,429 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullHyperplane_test.cpp#4 $$Change: 2064 $
+** $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "qhulltest/RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/QhullHyperplane.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/QhullFacetList.h"
+#include "libqhullcpp/QhullFacetSet.h"
+#include "libqhullcpp/Qhull.h"
+
+#include <numeric>
+#include <vector>
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::ostream;
+using std::string;
+
+namespace orgQhull {
+
+class QhullHyperplane_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_construct();
+ void t_construct_qh();
+ void t_convert();
+ void t_readonly();
+ void t_define();
+ void t_value();
+ void t_operator();
+ void t_iterator();
+ void t_const_iterator();
+ void t_qhullHyperplane_iterator();
+ void t_io();
+};//QhullHyperplane_test
+
+void
+add_QhullHyperplane_test()
+{
+ new QhullHyperplane_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void QhullHyperplane_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void QhullHyperplane_test::
+t_construct()
+{
+ QhullHyperplane h4;
+ QVERIFY(!h4.isValid());
+ QCOMPARE(h4.dimension(), 0);
+ // Qhull.runQhull() constructs QhullFacets as facetT
+ RboxPoints rcube("c");
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullHyperplane h(q);
+ QVERIFY(!h.isValid());
+ QCOMPARE(h.dimension(), 0);
+ QCOMPARE(h.coordinates(),static_cast<double *>(0));
+ QhullFacet f= q.firstFacet();
+ QhullHyperplane h2(f.hyperplane());
+ QVERIFY(h2.isValid());
+ QCOMPARE(h2.dimension(), 3);
+ h= h2;
+ QCOMPARE(h, h2);
+ QhullHyperplane h3(q, h2.dimension(), h2.coordinates(), h2.offset());
+ QCOMPARE(h2, h3);
+ QhullHyperplane h5= h2; // copy constructor
+ QVERIFY(h5==h2);
+}//t_construct
+
+void QhullHyperplane_test::
+t_construct_qh()
+{
+ // Qhull.runQhull() constructs QhullFacets as facetT
+ RboxPoints rcube("c");
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullFacet f= q.firstFacet();
+ QhullHyperplane h2(f.hyperplane());
+ QVERIFY(h2.isValid());
+ QCOMPARE(h2.dimension(), 3);
+ // h= h2; // copy assignment disabled, ambiguous
+ QhullHyperplane h3(q.qh(), h2.dimension(), h2.coordinates(), h2.offset());
+ QCOMPARE(h2, h3);
+ QhullHyperplane h5= h2; // copy constructor
+ QVERIFY(h5==h2);
+}//t_construct_qh
+
+void QhullHyperplane_test::
+t_convert()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullHyperplane h= q.firstFacet().hyperplane();
+ std::vector<double> fs= h.toStdVector();
+ QCOMPARE(fs.size(), 4u);
+ double offset= fs.back();
+ fs.pop_back();
+ QCOMPARE(offset, -0.5);
+
+ double squareNorm= inner_product(fs.begin(), fs.end(), fs.begin(), 0.0);
+ QCOMPARE(squareNorm, 1.0);
+ QList<double> qs= h.toQList();
+ QCOMPARE(qs.size(), 4);
+ double offset2= qs.takeLast();
+ QCOMPARE(offset2, -0.5);
+ double squareNorm2= std::inner_product(qs.begin(), qs.end(), qs.begin(), 0.0);
+ QCOMPARE(squareNorm2, 1.0);
+}//t_convert
+
+void QhullHyperplane_test::
+t_readonly()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullFacetList fs= q.facetList();
+ QhullFacetListIterator i(fs);
+ while(i.hasNext()){
+ QhullFacet f= i.next();
+ QhullHyperplane h= f.hyperplane();
+ int id= f.id();
+ cout << "h" << id << endl;
+ QVERIFY(h.isValid());
+ QCOMPARE(h.dimension(),3);
+ const coordT *c= h.coordinates();
+ coordT *c2= h.coordinates();
+ QCOMPARE(c, c2);
+ const coordT *c3= h.begin();
+ QCOMPARE(c, c3);
+ QCOMPARE(h.offset(), -0.5);
+ int j= h.end()-h.begin();
+ QCOMPARE(j, 3);
+ double squareNorm= std::inner_product(h.begin(), h.end(), h.begin(), 0.0);
+ QCOMPARE(squareNorm, 1.0);
+ }
+ QhullHyperplane h2= fs.first().hyperplane();
+ QhullHyperplane h3= fs.last().hyperplane();
+ QVERIFY(h2!=h3);
+ QVERIFY(h3.coordinates()!=h2.coordinates());
+ }
+}//t_readonly
+
+void QhullHyperplane_test::
+t_define()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullFacetList fs= q.facetList();
+ QhullHyperplane h= fs.first().hyperplane();
+ QhullHyperplane h2= h;
+ QVERIFY(h==h2);
+ QhullHyperplane h3= fs.last().hyperplane();
+ QVERIFY(h2!=h3);
+
+ QhullHyperplane h4= h3;
+ h4.defineAs(h2);
+ QVERIFY(h2==h4);
+ QhullHyperplane p5= h3;
+ p5.defineAs(h2.dimension(), h2.coordinates(), h2.offset());
+ QVERIFY(h2==p5);
+ QhullHyperplane h6= h3;
+ h6.setCoordinates(h2.coordinates());
+ QCOMPARE(h2.coordinates(), h6.coordinates());
+ h6.setOffset(h2.offset());
+ QCOMPARE(h2.offset(), h6.offset());
+ QVERIFY(h2==h6);
+ h6.setDimension(2);
+ QCOMPARE(h6.dimension(), 2);
+ QVERIFY(h2!=h6);
+ }
+}//t_define
+
+void QhullHyperplane_test::
+t_value()
+{
+ RboxPoints rcube("c G1");
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullFacet f= q.firstFacet();
+ QhullFacet f2= f.neighborFacets().at(0);
+ const QhullHyperplane h= f.hyperplane();
+ const QhullHyperplane h2= f2.hyperplane(); // At right angles
+ double dist= h.distance(q.origin());
+ QCOMPARE(dist, -1.0);
+ double norm= h.norm();
+ QCOMPARE(norm, 1.0);
+ double angle= h.hyperplaneAngle(h2);
+ cout << "angle " << angle << endl;
+ QCOMPARE(angle+1.0, 1.0); // qFuzzyCompare does not work for 0.0
+ QVERIFY(h==h);
+ QVERIFY(h!=h2);
+}//t_value
+
+void QhullHyperplane_test::
+t_operator()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ const QhullHyperplane h= q.firstFacet().hyperplane();
+ //operator== and operator!= tested elsewhere
+ const coordT *c= h.coordinates();
+ for(int k=h.dimension(); k--; ){
+ QCOMPARE(c[k], h[k]);
+ }
+ //h[0]= 10.0; // compiler error, const
+ QhullHyperplane h2= q.firstFacet().hyperplane();
+ h2[0]= 10.0; // Overwrites Hyperplane coordinate!
+ QCOMPARE(h2[0], 10.0);
+}//t_operator
+
+void QhullHyperplane_test::
+t_iterator()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullHyperplane h= q.firstFacet().hyperplane();
+ QCOMPARE(h.count(), 3);
+ QCOMPARE(h.size(), 3u);
+ QhullHyperplane::Iterator i= h.begin();
+ QhullHyperplane::iterator i2= h.begin();
+ QVERIFY(i==i2);
+ QVERIFY(i>=i2);
+ QVERIFY(i<=i2);
+ i= h.begin();
+ QVERIFY(i==i2);
+ i2= h.end();
+ QVERIFY(i!=i2);
+ double d3= *i;
+ i2--;
+ double d2= *i2;
+ QCOMPARE(d3, h[0]);
+ QCOMPARE(d2, h[2]);
+ QhullHyperplane::Iterator i3(i2);
+ QCOMPARE(*i2, *i3);
+
+ (i3= i)++;
+ QCOMPARE((*i3), h[1]);
+ QVERIFY(i==i);
+ QVERIFY(i!=i2);
+ QVERIFY(i<i2);
+ QVERIFY(i<=i2);
+ QVERIFY(i2>i);
+ QVERIFY(i2>=i);
+
+ QhullHyperplane::ConstIterator i4= h.begin();
+ QVERIFY(i==i4); // iterator COMP const_iterator
+ QVERIFY(i<=i4);
+ QVERIFY(i>=i4);
+ QVERIFY(i4==i); // const_iterator COMP iterator
+ QVERIFY(i4<=i);
+ QVERIFY(i4>=i);
+ QVERIFY(i>=i4);
+ QVERIFY(i4<=i);
+ QVERIFY(i2!=i4);
+ QVERIFY(i2>i4);
+ QVERIFY(i2>=i4);
+ QVERIFY(i4!=i2);
+ QVERIFY(i4<i2);
+ QVERIFY(i4<=i2);
+ ++i4;
+ QVERIFY(i<i4);
+ QVERIFY(i<=i4);
+ QVERIFY(i4>i);
+ QVERIFY(i4>=i);
+
+ i= h.begin();
+ i2= h.begin();
+ QCOMPARE(i, i2++);
+ QCOMPARE(*i2, h[1]);
+ QCOMPARE(++i, i2);
+ QCOMPARE(i, i2--);
+ QCOMPARE(i2, h.begin());
+ QCOMPARE(--i, i2);
+ QCOMPARE(i2 += 3, h.end());
+ QCOMPARE(i2 -= 3, h.begin());
+ QCOMPARE(i2+0, h.begin());
+ QCOMPARE(i2+3, h.end());
+ i2 += 3;
+ i= i2-0;
+ QCOMPARE(i, i2);
+ i= i2-3;
+ QCOMPARE(i, h.begin());
+ QCOMPARE(i2-i, 3);
+
+ //h.begin end tested above
+
+ // QhullHyperplane is const-only
+ }
+}//t_iterator
+
+void QhullHyperplane_test::
+t_const_iterator()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullHyperplane h= q.firstFacet().hyperplane();
+ QhullHyperplane::ConstIterator i= h.begin();
+ QhullHyperplane::const_iterator i2= h.begin();
+ QVERIFY(i==i2);
+ QVERIFY(i>=i2);
+ QVERIFY(i<=i2);
+ i= h.begin();
+ QVERIFY(i==i2);
+ i2= h.end();
+ QVERIFY(i!=i2);
+ double d3= *i;
+ i2--;
+ double d2= *i2;
+ QCOMPARE(d3, h[0]);
+ QCOMPARE(d2, h[2]);
+ QhullHyperplane::ConstIterator i3(i2);
+ QCOMPARE(*i2, *i3);
+
+ (i3= i)++;
+ QCOMPARE((*i3), h[1]);
+ QVERIFY(i==i);
+ QVERIFY(i!=i2);
+ QVERIFY(i<i2);
+ QVERIFY(i<=i2);
+ QVERIFY(i2>i);
+ QVERIFY(i2>=i);
+
+ // See t_iterator for const_iterator COMP iterator
+
+ i= h.begin();
+ i2= h.constBegin();
+ QCOMPARE(i, i2++);
+ QCOMPARE(*i2, h[1]);
+ QCOMPARE(++i, i2);
+ QCOMPARE(i, i2--);
+ QCOMPARE(i2, h.constBegin());
+ QCOMPARE(--i, i2);
+ QCOMPARE(i2+=3, h.constEnd());
+ QCOMPARE(i2-=3, h.constBegin());
+ QCOMPARE(i2+0, h.constBegin());
+ QCOMPARE(i2+3, h.constEnd());
+ i2 += 3;
+ i= i2-0;
+ QCOMPARE(i, i2);
+ i= i2-3;
+ QCOMPARE(i, h.constBegin());
+ QCOMPARE(i2-i, 3);
+
+ // QhullHyperplane is const-only
+ }
+}//t_const_iterator
+
+void QhullHyperplane_test::
+t_qhullHyperplane_iterator()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullHyperplane h = q.firstFacet().hyperplane();
+ QhullHyperplaneIterator i2(h);
+ QCOMPARE(h.dimension(), 3);
+ QhullHyperplaneIterator i= h;
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i2.toBack();
+ i.toFront();
+ QVERIFY(!i2.hasNext());
+ QVERIFY(i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+
+ // i at front, i2 at end/back, 3 coordinates
+ QCOMPARE(i.peekNext(), h[0]);
+ QCOMPARE(i2.peekPrevious(), h[2]);
+ QCOMPARE(i2.previous(), h[2]);
+ QCOMPARE(i2.previous(), h[1]);
+ QCOMPARE(i2.previous(), h[0]);
+ QVERIFY(!i2.hasPrevious());
+ QCOMPARE(i.peekNext(), h[0]);
+ // i.peekNext()= 1.0; // compiler error, i is const
+ QCOMPARE(i.next(), h[0]);
+ QCOMPARE(i.peekNext(), h[1]);
+ QCOMPARE(i.next(), h[1]);
+ QCOMPARE(i.next(), h[2]);
+ QVERIFY(!i.hasNext());
+ i.toFront();
+ QCOMPARE(i.next(), h[0]);
+}//t_qhullHyperplane_iterator
+
+void QhullHyperplane_test::
+t_io()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube, "");
+ QhullHyperplane h= q.firstFacet().hyperplane();
+ ostringstream os;
+ os << "Hyperplane:\n";
+ os << h;
+ os << h.print("message");
+ os << h.print(" and a message ", " offset ");
+ cout << os.str();
+ QString s= QString::fromStdString(os.str());
+ QCOMPARE(s.count("1"), 3);
+ // QCOMPARE(s.count(QRegExp("f\\d")), 3*7 + 13*3*2);
+ }
+}//t_io
+
+
+}//orgQhull
+
+#include "moc/QhullHyperplane_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullLinkedList_test.cpp b/xs/src/qhull/src/qhulltest/QhullLinkedList_test.cpp
new file mode 100644
index 000000000..e0cde4050
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullLinkedList_test.cpp
@@ -0,0 +1,330 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullLinkedList_test.cpp#3 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <QtCore/QList>
+#include "qhulltest/RoadTest.h"
+
+#include "libqhullcpp/QhullLinkedList.h"
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/QhullVertex.h"
+#include "libqhullcpp/RboxPoints.h"
+
+namespace orgQhull {
+
+class QhullLinkedList_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_construct();
+ void t_convert();
+ void t_element();
+ void t_search();
+ void t_iterator();
+ void t_const_iterator();
+ void t_QhullLinkedList_iterator();
+ void t_io();
+};//QhullLinkedList_test
+
+void
+add_QhullLinkedList_test()
+{
+ new QhullLinkedList_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void QhullLinkedList_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void QhullLinkedList_test::
+t_construct()
+{
+ // QhullLinkedList vs; //private (compiler error). No memory allocation
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QCOMPARE(q.facetCount(), 12);
+ QhullVertexList vs = QhullVertexList(q.beginVertex(), q.endVertex());
+ QCOMPARE(vs.count(), 8);
+ QCOMPARE(vs.size(), 8u);
+ QVERIFY(!vs.isEmpty());
+ QhullVertexList vs2 = q.vertexList();
+ QCOMPARE(vs2.count(), 8);
+ QCOMPARE(vs2.size(),8u);
+ QVERIFY(!vs2.isEmpty());
+ QVERIFY(vs==vs2);
+ // vs= vs2; // disabled. Would not copy the vertices
+ QhullVertexList vs3= vs2; // copy constructor
+ QVERIFY(vs3==vs2);
+ }
+}//t_construct
+
+void QhullLinkedList_test::
+t_convert()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QCOMPARE(q.facetCount(), 12);
+ QhullVertexList vs = q.vertexList();
+ QCOMPARE(vs.size(), 8u);
+ QVERIFY(!vs.isEmpty());
+ std::vector<QhullVertex> vs2= vs.toStdVector();
+ QCOMPARE(vs2.size(), vs.size());
+ QhullVertexList::Iterator i= vs.begin();
+ for(int k= 0; k<(int)vs2.size(); k++){
+ QCOMPARE(vs2[k], *i++);
+ }
+ QList<QhullVertex> vs3= vs.toQList();
+ QCOMPARE(vs3.count(), vs.count());
+ i= vs.begin();
+ for(int k= 0; k<vs3.count(); k++){
+ QCOMPARE(vs3[k], *i++);
+ }
+ QhullVertexList vs4(q.endVertex(), q.endVertex());
+ QVERIFY(vs4.isEmpty());
+ QVERIFY(vs==vs);
+ QVERIFY(vs4==vs4);
+ QVERIFY(vs!=vs4);
+ }
+}//t_convert
+
+//ReadOnly tested by t_convert
+
+void QhullLinkedList_test::
+t_element()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullVertexList vs = q.vertexList();
+ QhullVertex v= vs.first();
+ QCOMPARE(v.previous(), QhullVertex(NULL));
+ QCOMPARE(vs.front(), vs.first());
+ QhullVertex v2= vs.last();
+ QCOMPARE(v2.next().next(), QhullVertex(NULL)); // sentinel has NULL next
+ QCOMPARE(vs.back(), v2);
+ QCOMPARE(vs.back(), vs.last());
+}//t_element
+
+void QhullLinkedList_test::
+t_search()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullVertexList vs = q.vertexList();
+ QhullVertex v(q);
+ QVERIFY(!vs.contains(v));
+ QCOMPARE(vs.count(v), 0);
+ QhullVertex v2= *vs.begin();
+ QhullVertex v3= vs.last();
+ QVERIFY(vs.contains(v2));
+ QCOMPARE(vs.count(v2), 1);
+ QVERIFY(vs.contains(v3));
+ QCOMPARE(vs.count(v3), 1);
+}//t_search
+
+void QhullLinkedList_test::
+t_iterator()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullVertexList vs = q.vertexList();
+ QhullVertexList::Iterator i= vs.begin();
+ QhullVertexList::iterator i2= vs.begin();
+ QVERIFY(i==i2);
+ // No comparisons
+ i= vs.begin();
+ QVERIFY(i==i2);
+ i2= vs.end();
+ QVERIFY(i!=i2);
+ QhullVertex v3(*i);
+ i2--;
+ QhullVertex v8= *i2;
+ QhullVertex v= vs.first();
+ QhullVertex v2= v.next();
+ QCOMPARE(v3.id(), v.id());
+ QCOMPARE(v8.id(), vs.last().id());
+ QhullVertexList::Iterator i3(i2);
+ QCOMPARE(*i2, *i3);
+
+ (i3= i)++;
+ QCOMPARE((*i3).id(), v2.id());
+ QVERIFY(i==i);
+ QVERIFY(i!=i2);
+
+ QhullVertexList::ConstIterator i4= vs.begin();
+ QVERIFY(i==i4); // iterator COMP const_iterator
+ QVERIFY(i4==i); // const_iterator COMP iterator
+ QVERIFY(i2!=i4);
+ QVERIFY(i4!=i2);
+ ++i4;
+
+ i= vs.begin();
+ i2= vs.begin();
+ QCOMPARE(i, i2++);
+ QCOMPARE(*i2, v2);
+ QCOMPARE(++i, i2);
+ QCOMPARE(i, i2--);
+ QCOMPARE(i2, vs.begin());
+ QCOMPARE(--i, i2);
+ QCOMPARE(i2 += 8, vs.end());
+ QCOMPARE(i2 -= 8, vs.begin());
+ QCOMPARE(i2+0, vs.begin());
+ QCOMPARE(i2+8, vs.end());
+ i2 += 8;
+ i= i2-0;
+ QCOMPARE(i, i2);
+ i= i2-8;
+ QCOMPARE(i, vs.begin());
+
+ //vs.begin end tested above
+
+ // QhullVertexList is const-only
+ }
+}//t_iterator
+
+void QhullLinkedList_test::
+t_const_iterator()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullVertexList vs = q.vertexList();
+ QhullVertexList::ConstIterator i= vs.begin();
+ QhullVertexList::const_iterator i2= vs.begin();
+ QVERIFY(i==i2);
+ i= vs.begin();
+ QVERIFY(i==i2);
+ i2= vs.end();
+ QVERIFY(i!=i2);
+ QhullVertex v3(*i);
+ i2--;
+ QhullVertex v8= *i2;
+ QhullVertex v= vs.first();
+ QhullVertex v2= v.next();
+ QCOMPARE(v3.id(), v.id());
+ QCOMPARE(v8.id(), vs.last().id());
+ QhullVertexList::ConstIterator i3(i2);
+ QCOMPARE(*i2, *i3);
+
+ (i3= i)++;
+ QCOMPARE((*i3).id(), v2.id());
+ QVERIFY(i==i);
+ QVERIFY(i!=i2);
+
+ // See t_iterator for const_iterator COMP iterator
+
+ i= vs.begin();
+ i2= vs.constBegin();
+ QCOMPARE(i, i2++);
+ QCOMPARE(*i2, v2);
+ QCOMPARE(++i, i2);
+ QCOMPARE(i, i2--);
+ QCOMPARE(i2, vs.constBegin());
+ QCOMPARE(--i, i2);
+ QCOMPARE(i2 += 8, vs.constEnd());
+ QCOMPARE(i2 -= 8, vs.constBegin());
+ QCOMPARE(i2+0, vs.constBegin());
+ QCOMPARE(i2+8, vs.constEnd());
+ i2 += 8;
+ i= i2-0;
+ QCOMPARE(i, i2);
+ i= i2-8;
+ QCOMPARE(i, vs.constBegin());
+
+ // QhullVertexList is const-only
+ }
+}//t_const_iterator
+
+void QhullLinkedList_test::
+t_QhullLinkedList_iterator()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullVertexList vs(q.endVertex(), q.endVertex());
+ QhullVertexListIterator i= vs;
+ QCOMPARE(vs.count(), 0);
+ QVERIFY(!i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i.toBack();
+ QVERIFY(!i.hasNext());
+ QVERIFY(!i.hasPrevious());
+
+ QhullVertexList vs2 = q.vertexList();
+ QhullVertexListIterator i2(vs2);
+ QCOMPARE(vs2.count(), 8);
+ i= vs2;
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i2.toBack();
+ i.toFront();
+ QVERIFY(!i2.hasNext());
+ QVERIFY(i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+
+ // i at front, i2 at end/back, 4 neighbors
+ QhullVertexList vs3 = q.vertexList(); // same as vs2
+ QhullVertex v3(vs3.first());
+ QhullVertex v4= vs3.first();
+ QCOMPARE(v3, v4);
+ QVERIFY(v3==v4);
+ QhullVertex v5(v4.next());
+ QVERIFY(v4!=v5);
+ QhullVertex v6(v5.next());
+ QhullVertex v7(v6.next());
+ QhullVertex v8(vs3.last());
+ QCOMPARE(i2.peekPrevious(), v8);
+ i2.previous();
+ i2.previous();
+ i2.previous();
+ i2.previous();
+ QCOMPARE(i2.previous(), v7);
+ QCOMPARE(i2.previous(), v6);
+ QCOMPARE(i2.previous(), v5);
+ QCOMPARE(i2.previous(), v4);
+ QVERIFY(!i2.hasPrevious());
+ QCOMPARE(i.peekNext(), v4);
+ // i.peekNext()= 1.0; // compiler error
+ QCOMPARE(i.next(), v4);
+ QCOMPARE(i.peekNext(), v5);
+ QCOMPARE(i.next(), v5);
+ QCOMPARE(i.next(), v6);
+ QCOMPARE(i.next(), v7);
+ i.next();
+ i.next();
+ i.next();
+ QCOMPARE(i.next(), v8);
+ QVERIFY(!i.hasNext());
+ i.toFront();
+ QCOMPARE(i.next(), v4);
+}//t_QhullLinkedList_iterator
+
+void QhullLinkedList_test::
+t_io()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullVertexList vs(q.endVertex(), q.endVertex());
+ std::cout << "INFO: empty QhullVertextList" << vs << std::endl;
+ QhullVertexList vs2= q.vertexList();
+ std::cout << "INFO: " << vs2 << std::endl;
+}//t_io
+
+}//namespace orgQhull
+
+#include "moc/QhullLinkedList_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullPointSet_test.cpp b/xs/src/qhull/src/qhulltest/QhullPointSet_test.cpp
new file mode 100644
index 000000000..ff633a518
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullPointSet_test.cpp
@@ -0,0 +1,378 @@
+/****************************************************************************
+**
+** Copyright (p) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullPointSet_test.cpp#3 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled header
+#include <iostream>
+#include "RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/QhullPointSet.h"
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/QhullFacetList.h"
+#include "libqhullcpp/Qhull.h"
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+
+namespace orgQhull {
+
+class QhullPointSet_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_construct();
+ void t_convert();
+ void t_element();
+ void t_iterator();
+ void t_const_iterator();
+ void t_search();
+ void t_pointset_iterator();
+ void t_io();
+};//QhullPointSet_test
+
+void
+add_QhullPointSet_test()
+{
+ new QhullPointSet_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void QhullPointSet_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void QhullPointSet_test::
+t_construct()
+{
+ // Default constructor is disallowed (i.e., private)
+ RboxPoints rcube("c W0 1000");
+ Qhull q(rcube,"Qc"); // cube with 1000 coplanar points
+ int coplanarCount= 0;
+ foreach(QhullFacet f, q.facetList()){
+ QhullPointSet ps(q, f.getFacetT()->outsideset);
+ QVERIFY(ps.isEmpty());
+ QCOMPARE(ps.count(), 0);
+ QCOMPARE(ps.size(), 0u);
+ QhullPointSet ps2(q.qh(), f.getFacetT()->coplanarset);
+ QVERIFY(!ps2.isEmpty());
+ coplanarCount += ps2.count();
+ QCOMPARE(ps2.count(), (int)ps2.size());
+ QhullPointSet ps3(ps2);
+ QVERIFY(!ps3.isEmpty());
+ QCOMPARE(ps3.count(), ps2.count());
+ QVERIFY(ps3==ps2);
+ QVERIFY(ps3!=ps);
+ QhullPointSet ps4= ps3;
+ QVERIFY(ps4==ps2);
+ }
+ QCOMPARE(coplanarCount, 1000);
+}//t_construct
+
+void QhullPointSet_test::
+t_convert()
+{
+ RboxPoints rcube("c W0 1000");
+ Qhull q(rcube,"Qc"); // cube with 1000 coplanar points
+ QhullFacet f= q.firstFacet();
+ QhullPointSet ps= f.coplanarPoints();
+ QVERIFY(ps.count()>=1); // Sometimes no coplanar points
+ std::vector<QhullPoint> vs= ps.toStdVector();
+ QCOMPARE(vs.size(), ps.size());
+ QhullPoint p= ps[0];
+ QhullPoint p2= vs[0];
+ QCOMPARE(p, p2);
+ QList<QhullPoint> qs= ps.toQList();
+ QCOMPARE(qs.size(), static_cast<int>(ps.size()));
+ QhullPoint p3= qs[0];
+ QCOMPARE(p3, p);
+}//t_convert
+
+// readonly tested in t_construct
+// empty, isEmpty, ==, !=, size
+
+void QhullPointSet_test::
+t_element()
+{
+ RboxPoints rcube("c W0 1000");
+ Qhull q(rcube,"Qc"); // cube with 1000 coplanar points
+ QhullFacet f= q.firstFacet();
+ QhullPointSet ps= f.coplanarPoints();
+ QVERIFY(ps.count()>=3); // Sometimes no coplanar points
+ QhullPoint p= ps[0];
+ QCOMPARE(p, ps[0]);
+ QhullPoint p2= ps[ps.count()-1];
+ QCOMPARE(ps.at(1), ps[1]);
+ QCOMPARE(ps.second(), ps[1]);
+ QCOMPARE(ps.first(), p);
+ QCOMPARE(ps.front(), ps.first());
+ QCOMPARE(ps.last(), p2);
+ QCOMPARE(ps.back(), ps.last());
+ QhullPoint p8(q);
+ QCOMPARE(ps.value(2), ps[2]);
+ QCOMPARE(ps.value(-1), p8);
+ QCOMPARE(ps.value(ps.count()), p8);
+ QCOMPARE(ps.value(ps.count(), p), p);
+ QVERIFY(ps.value(1, p)!=p);
+ QhullPointSet ps8= f.coplanarPoints();
+ QhullPointSet::Iterator i= ps8.begin();
+ foreach(QhullPoint p9, ps){ // Qt only
+ QCOMPARE(p9.dimension(), 3);
+ QCOMPARE(p9, *i++);
+ }
+}//t_element
+
+void QhullPointSet_test::
+t_iterator()
+{
+ RboxPoints rcube("c W0 1000");
+ Qhull q(rcube,"Qc"); // cube with 1000 coplanar points
+ QhullFacet f= q.firstFacet();
+ QhullPointSet ps= f.coplanarPoints();
+ QVERIFY(ps.count()>=3); // Sometimes no coplanar points
+ QhullPointSet::Iterator i= ps.begin();
+ QhullPointSet::iterator i2= ps.begin();
+ QVERIFY(i==i2);
+ QVERIFY(i>=i2);
+ QVERIFY(i<=i2);
+ i= ps.begin();
+ QVERIFY(i==i2);
+ i2= ps.end();
+ QVERIFY(i!=i2);
+ QhullPoint p= *i;
+ QCOMPARE(p.dimension(), q.dimension());
+ QCOMPARE(p, ps[0]);
+ i2--;
+ QhullPoint p2= *i2;
+ QCOMPARE(p2.dimension(), q.dimension());
+ QCOMPARE(p2, ps.last());
+ QhullPointSet::Iterator i5(i2);
+ QCOMPARE(*i2, *i5);
+ QhullPointSet::Iterator i3= i+1;
+ QVERIFY(i!=i3);
+ QCOMPARE(i[1], *i3);
+ (i3= i)++;
+ QCOMPARE((*i3)[0], ps[1][0]);
+ QCOMPARE((*i3).dimension(), 3);
+
+ QVERIFY(i==i);
+ QVERIFY(i!=i3);
+ QVERIFY(i<i3);
+ QVERIFY(i<=i3);
+ QVERIFY(i3>i);
+ QVERIFY(i3>=i);
+
+ QhullPointSet::ConstIterator i4= ps.begin();
+ QVERIFY(i==i4); // iterator COMP const_iterator
+ QVERIFY(i<=i4);
+ QVERIFY(i>=i4);
+ QVERIFY(i4==i); // const_iterator COMP iterator
+ QVERIFY(i4<=i);
+ QVERIFY(i4>=i);
+ QVERIFY(i>=i4);
+ QVERIFY(i4<=i);
+ QVERIFY(i2!=i4);
+ QVERIFY(i2>i4);
+ QVERIFY(i2>=i4);
+ QVERIFY(i4!=i2);
+ QVERIFY(i4<i2);
+ QVERIFY(i4<=i2);
+ ++i4;
+ QVERIFY(i!=i4); // iterator COMP const_iterator
+ QVERIFY(i<i4);
+ QVERIFY(i<=i4);
+ QVERIFY(i4>i);
+ QVERIFY(i4>=i);
+ i4= ps.constBegin();
+ QVERIFY(i==i4); // iterator COMP const_iterator
+ QCOMPARE(i4+ps.count(), ps.constEnd());
+
+ i= ps.begin();
+ i2= ps.begin();
+ QCOMPARE(i, i2++);
+ QCOMPARE(*i2, ps[1]);
+ QCOMPARE(++i, i2);
+ QCOMPARE(i, i2--);
+ QCOMPARE(i2, ps.begin());
+ QCOMPARE(--i, i2);
+ QCOMPARE(i2+=ps.count(), ps.end());
+ QCOMPARE(i2-=ps.count(), ps.begin());
+ QCOMPARE(i2+0, ps.begin());
+ QCOMPARE(i2+ps.count(), ps.end());
+ i2 += ps.count();
+ i= i2-0;
+ QCOMPARE(i, i2);
+ i= i2-ps.count();
+ QCOMPARE(i, ps.begin());
+ QCOMPARE(i2-i, ps.count());
+
+ //ps.begin end tested above
+
+ // QhullPointSet is const-only
+}//t_iterator
+
+void QhullPointSet_test::
+t_const_iterator()
+{
+ RboxPoints rcube("c W0 1000");
+ Qhull q(rcube,"Qc"); // cube with 1000 coplanar points
+ QhullFacet f= q.firstFacet();
+ QhullPointSet ps= f.coplanarPoints();
+ QVERIFY(ps.count()>=3); // Sometimes no coplanar points
+ QhullPointSet::ConstIterator i= ps.begin();
+ QhullPointSet::const_iterator i2= ps.begin();
+ QVERIFY(i==i2);
+ QVERIFY(i>=i2);
+ QVERIFY(i<=i2);
+
+ // See t_iterator for const_iterator COMP iterator
+
+ i= ps.begin();
+ QVERIFY(i==i2);
+ i2= ps.end();
+ QVERIFY(i!=i2);
+ QhullPoint p= *i; // QhullPoint is the base class for QhullPointSet::iterator
+ QCOMPARE(p.dimension(), q.dimension());
+ QCOMPARE(p, ps[0]);
+ i2--;
+ QhullPoint p2= *i2;
+ QCOMPARE(p2.dimension(), q.dimension());
+ QCOMPARE(p2, ps.last());
+ QhullPointSet::ConstIterator i5(i2);
+ QCOMPARE(*i2, *i5);
+
+
+ QhullPointSet::ConstIterator i3= i+1;
+ QVERIFY(i!=i3);
+ QCOMPARE(i[1], *i3);
+
+ QVERIFY(i==i);
+ QVERIFY(i!=i3);
+ QVERIFY(i<i3);
+ QVERIFY(i<=i3);
+ QVERIFY(i3>i);
+ QVERIFY(i3>=i);
+
+ // QhullPointSet is const-only
+}//t_const_iterator
+
+
+void QhullPointSet_test::
+t_search()
+{
+ RboxPoints rcube("c W0 1000");
+ Qhull q(rcube,"Qc"); // cube with 1000 coplanar points
+ QhullFacet f= q.firstFacet();
+ QhullPointSet ps= f.coplanarPoints();
+ QVERIFY(ps.count()>=3); // Sometimes no coplanar points
+ QhullPoint p= ps.first();
+ QhullPoint p2= ps.last();
+ QVERIFY(ps.contains(p));
+ QVERIFY(ps.contains(p2));
+ QVERIFY(p!=p2);
+ QhullPoint p3= ps[2];
+ QVERIFY(ps.contains(p3));
+ QVERIFY(p!=p3);
+ QCOMPARE(ps.indexOf(p), 0);
+ QCOMPARE(ps.indexOf(p2), ps.count()-1);
+ QCOMPARE(ps.indexOf(p3), 2);
+ QhullPoint p4(q);
+ QCOMPARE(ps.indexOf(p4), -1);
+ QCOMPARE(ps.lastIndexOf(p), 0);
+ QCOMPARE(ps.lastIndexOf(p2), ps.count()-1);
+ QCOMPARE(ps.lastIndexOf(p3), 2);
+ QCOMPARE(ps.lastIndexOf(p4), -1);
+}//t_search
+
+void QhullPointSet_test::
+t_pointset_iterator()
+{
+ RboxPoints rcube("c W0 1000");
+ Qhull q(rcube,"Qc"); // cube with 1000 coplanar points
+ QhullFacet f= q.firstFacet();
+ QhullPointSet ps2= f.outsidePoints();
+ QVERIFY(ps2.count()==0); // No outside points after constructing the convex hull
+ QhullPointSetIterator i2= ps2;
+ QCOMPARE(i2.countRemaining(), 0);
+ QVERIFY(!i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ i2.toBack();
+ QVERIFY(!i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+
+ QhullPointSet ps= f.coplanarPoints();
+ QVERIFY(ps.count()>=3); // Sometimes no coplanar points
+ QhullPointSetIterator i(ps);
+ i2= ps;
+ QCOMPARE(i2.countRemaining(), ps.count());
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i2.toBack();
+ QCOMPARE(i2.countRemaining(), 0);
+ i.toFront();
+ QCOMPARE(i.countRemaining(), ps.count());
+ QCOMPARE(i2.countRemaining(), 0);
+ QVERIFY(!i2.hasNext());
+ QVERIFY(i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+
+ QhullPoint p= ps[0];
+ QhullPoint p2(ps[0]);
+ QCOMPARE(p, p2);
+ QVERIFY(p==p2);
+ QhullPoint p3(ps.last());
+ // p2[0]= 0.0;
+ QVERIFY(p==p2);
+ QCOMPARE(i2.peekPrevious(), p3);
+ QCOMPARE(i2.previous(), p3);
+ QCOMPARE(i2.previous(), ps[ps.count()-2]);
+ QVERIFY(i2.hasPrevious());
+ QCOMPARE(i.peekNext(), p);
+ // i.peekNext()= 1.0; // compiler error
+ QCOMPARE(i.next(), p);
+ QCOMPARE(i.countRemaining(), ps.count()-1);
+ QhullPoint p4= i.peekNext();
+ QVERIFY(p4!=p3);
+ QCOMPARE(i.next(), p4);
+ QVERIFY(i.hasNext());
+ i.toFront();
+ QCOMPARE(i.next(), p);
+}//t_pointset_iterator
+
+void QhullPointSet_test::
+t_io()
+{
+ ostringstream os;
+ RboxPoints rcube("c W0 120");
+ Qhull q(rcube,"Qc"); // cube with 100 coplanar points
+ QhullFacet f= q.firstFacet();
+ QhullPointSet ps= f.coplanarPoints();
+ QVERIFY(ps.count()>=3); // Sometimes no coplanar points
+ os << "QhullPointSet from coplanarPoints\n" << ps << endl;
+ os << ps.print("\nWith message\n");
+ os << ps.printIdentifiers("\nCoplanar points: ");
+ os << "\nAs a point set:\n";
+ os << ps;
+ cout << os.str();
+ QString s= QString::fromStdString(os.str());
+ QCOMPARE(s.count(" 0.5\n"), 3*ps.count());
+ QCOMPARE(s.count("p"), ps.count()+4);
+}//t_io
+
+}//orgQhull
+
+#include "moc/QhullPointSet_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullPoint_test.cpp b/xs/src/qhull/src/qhulltest/QhullPoint_test.cpp
new file mode 100644
index 000000000..1528086a1
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullPoint_test.cpp
@@ -0,0 +1,437 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullPoint_test.cpp#3 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/Coordinates.h"
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/QhullPoint.h"
+#include "libqhullcpp/Qhull.h"
+
+#include <numeric>
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::ostream;
+using std::string;
+
+namespace orgQhull {
+
+class QhullPoint_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_construct();
+ void t_convert();
+ void t_readonly();
+ void t_define();
+ void t_operator();
+ void t_iterator();
+ void t_const_iterator();
+ void t_qhullpoint_iterator();
+ void t_method();
+ void t_io();
+};//QhullPoint_test
+
+void
+add_QhullPoint_test()
+{
+ new QhullPoint_test(); // RoadTest::s_testcases
+}
+
+//Executed after each test
+void QhullPoint_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void QhullPoint_test::
+t_construct()
+{
+ QhullPoint p12;
+ QVERIFY(!p12.isValid());
+ QCOMPARE(p12.coordinates(), (coordT *)0);
+ QCOMPARE(p12.dimension(), 0);
+ QCOMPARE(p12.qh(), (QhullQh *)0);
+ QCOMPARE(p12.id(), -3);
+ QCOMPARE(p12.begin(), p12.end());
+ QCOMPARE(p12.constBegin(), p12.constEnd());
+
+ RboxPoints rcube("c");
+ Qhull q(rcube, "Qt QR0"); // triangulation of rotated unit cube
+ QhullPoint p(q);
+ QVERIFY(!p.isValid());
+ QCOMPARE(p.dimension(),3);
+ QCOMPARE(p.coordinates(),static_cast<double *>(0));
+ QhullPoint p7(q.qh());
+ QCOMPARE(p, p7);
+
+ // copy constructor and copy assignment
+ QhullVertex v2(q.beginVertex());
+ QhullPoint p2(v2.point());
+ QVERIFY(p2.isValid());
+ QCOMPARE(p2.dimension(),3);
+ QVERIFY(p2!=p12);
+ p= p2;
+ QCOMPARE(p, p2);
+
+ QhullPoint p3(q, p2.dimension(), p2.coordinates());
+ QCOMPARE(p3, p2);
+ QhullPoint p8(q, p2.coordinates()); // Qhull defines dimension
+ QCOMPARE(p8, p2);
+ QhullPoint p9(q.qh(), p2.dimension(), p2.coordinates());
+ QCOMPARE(p9, p2);
+ QhullPoint p10(q.qh(), p2.coordinates()); // Qhull defines dimension
+ QCOMPARE(p10, p2);
+
+ Coordinates c;
+ c << 0.0 << 0.0 << 0.0;
+ QhullPoint p6(q, c);
+ QCOMPARE(p6, q.origin());
+ QhullPoint p11(q.qh(), c);
+ QCOMPARE(p11, q.origin());
+
+ QhullPoint p5= p2; // copy constructor
+ QVERIFY(p5==p2);
+}//t_construct
+
+void QhullPoint_test::
+t_convert()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullVertex v= q.firstVertex();
+ QhullPoint p= v.point();
+ std::vector<double> vs= p.toStdVector();
+ QCOMPARE(vs.size(), 3u);
+ for(int k=3; k--; ){
+ QCOMPARE(vs[k], p[k]);
+ }
+ QList<double> qs= p.toQList();
+ QCOMPARE(qs.size(), 3);
+ for(int k=3; k--; ){
+ QCOMPARE(qs[k], p[k]);
+ }
+}//t_convert
+
+void QhullPoint_test::
+t_readonly()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullVertexList vs= q.vertexList();
+ cout << "Point ids in 'rbox c'\n";
+ QhullVertexListIterator i(vs);
+ while(i.hasNext()){
+ QhullPoint p= i.next().point();
+ int id= p.id();
+ cout << "p" << id << endl;
+ QVERIFY(p.isValid());
+ QCOMPARE(p.dimension(),3);
+ QCOMPARE(id, p.id());
+ QVERIFY(p.id()>=0 && p.id()<9);
+ const coordT *c= p.coordinates();
+ coordT *c2= p.coordinates();
+ QCOMPARE(c, c2);
+ QCOMPARE(p.dimension(), 3);
+ QCOMPARE(q.qh(), p.qh());
+ }
+ QhullPoint p2= vs.first().point();
+ QhullPoint p3= vs.last().point();
+ QVERIFY(p2!=p3);
+ QVERIFY(p3.coordinates()!=p2.coordinates());
+ }
+}//t_readonly
+
+void QhullPoint_test::
+t_define()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullVertexList vs= q.vertexList();
+ QhullPoint p= vs.first().point();
+ QhullPoint p2= p;
+ QVERIFY(p==p2);
+ QhullPoint p3= vs.last().point();
+ QVERIFY(p2!=p3);
+ int idx= (p3.coordinates()-p2.coordinates())/p2.dimension();
+ QVERIFY(idx>-8 && idx<8);
+ p2.advancePoint(idx);
+ QVERIFY(p2==p3);
+ p2.advancePoint(-idx);
+ QVERIFY(p2==p);
+ p2.advancePoint(0);
+ QVERIFY(p2==p);
+
+ QhullPoint p4= p3;
+ QVERIFY(p4==p3);
+ p4.defineAs(p2);
+ QVERIFY(p2==p4);
+ QhullPoint p5= p3;
+ p5.defineAs(p2.dimension(), p2.coordinates());
+ QVERIFY(p2==p5);
+ QhullPoint p6= p3;
+ p6.setCoordinates(p2.coordinates());
+ QCOMPARE(p2.coordinates(), p6.coordinates());
+ QVERIFY(p2==p6);
+ p6.setDimension(2);
+ QCOMPARE(p6.dimension(), 2);
+ QVERIFY(p2!=p6);
+ }
+}//t_define
+
+void QhullPoint_test::
+t_operator()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ const QhullPoint p= q.firstVertex().point();
+ //operator== and operator!= tested elsewhere
+ const coordT *c= p.coordinates();
+ for(int k=p.dimension(); k--; ){
+ QCOMPARE(c[k], p[k]);
+ }
+ //p[0]= 10.0; // compiler error, const
+ QhullPoint p2= q.firstVertex().point();
+ p2[0]= 10.0; // Overwrites point coordinate
+ QCOMPARE(p2[0], 10.0);
+}//t_operator
+
+void QhullPoint_test::
+t_iterator()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullPoint p2(q);
+ QCOMPARE(p2.begin(), p2.end());
+
+ QhullPoint p= q.firstVertex().point();
+ QhullPoint::Iterator i= p.begin();
+ QhullPoint::iterator i2= p.begin();
+ QVERIFY(i==i2);
+ QVERIFY(i>=i2);
+ QVERIFY(i<=i2);
+ i= p.begin();
+ QVERIFY(i==i2);
+ i2= p.end();
+ QVERIFY(i!=i2);
+ double d3= *i;
+ i2--;
+ double d2= *i2;
+ QCOMPARE(d3, p[0]);
+ QCOMPARE(d2, p[2]);
+ QhullPoint::Iterator i3(i2);
+ QCOMPARE(*i2, *i3);
+
+ (i3= i)++;
+ QCOMPARE((*i3), p[1]);
+ QVERIFY(i==i);
+ QVERIFY(i!=i2);
+ QVERIFY(i<i2);
+ QVERIFY(i<=i2);
+ QVERIFY(i2>i);
+ QVERIFY(i2>=i);
+
+ QhullPoint::ConstIterator i4= p.begin();
+ QVERIFY(i==i4); // iterator COMP const_iterator
+ QVERIFY(i<=i4);
+ QVERIFY(i>=i4);
+ QVERIFY(i4==i); // const_iterator COMP iterator
+ QVERIFY(i4<=i);
+ QVERIFY(i4>=i);
+ QVERIFY(i>=i4);
+ QVERIFY(i4<=i);
+ QVERIFY(i2!=i4);
+ QVERIFY(i2>i4);
+ QVERIFY(i2>=i4);
+ QVERIFY(i4!=i2);
+ QVERIFY(i4<i2);
+ QVERIFY(i4<=i2);
+ ++i4;
+ QVERIFY(i<i4);
+ QVERIFY(i<=i4);
+ QVERIFY(i4>i);
+ QVERIFY(i4>=i);
+
+ i= p.begin();
+ i2= p.begin();
+ QCOMPARE(i, i2++);
+ QCOMPARE(*i2, p[1]);
+ QCOMPARE(++i, i2);
+ QCOMPARE(i, i2--);
+ QCOMPARE(i2, p.begin());
+ QCOMPARE(--i, i2);
+ QCOMPARE(i2 += 3, p.end());
+ QCOMPARE(i2 -= 3, p.begin());
+ QCOMPARE(i2+0, p.begin());
+ QCOMPARE(i2+3, p.end());
+ i2 += 3;
+ i= i2-0;
+ QCOMPARE(i, i2);
+ i= i2-3;
+ QCOMPARE(i, p.begin());
+ QCOMPARE(i2-i, 3);
+
+ //p.begin end tested above
+
+ // QhullPoint is const-only
+ }
+}//t_iterator
+
+void QhullPoint_test::
+t_const_iterator()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullPoint p= q.firstVertex().point();
+ QhullPoint::ConstIterator i= p.begin();
+ QhullPoint::const_iterator i2= p.begin();
+ QVERIFY(i==i2);
+ QVERIFY(i>=i2);
+ QVERIFY(i<=i2);
+ i= p.begin();
+ QVERIFY(i==i2);
+ i2= p.end();
+ QVERIFY(i!=i2);
+ double d3= *i;
+ i2--;
+ double d2= *i2;
+ QCOMPARE(d3, p[0]);
+ QCOMPARE(d2, p[2]);
+ QhullPoint::ConstIterator i3(i2);
+ QCOMPARE(*i2, *i3);
+
+ (i3= i)++;
+ QCOMPARE((*i3), p[1]);
+ QVERIFY(i==i);
+ QVERIFY(i!=i2);
+ QVERIFY(i<i2);
+ QVERIFY(i<=i2);
+ QVERIFY(i2>i);
+ QVERIFY(i2>=i);
+
+ // See t_iterator for const_iterator COMP iterator
+
+ i= p.begin();
+ i2= p.constBegin();
+ QCOMPARE(i, i2++);
+ QCOMPARE(*i2, p[1]);
+ QCOMPARE(++i, i2);
+ QCOMPARE(i, i2--);
+ QCOMPARE(i2, p.constBegin());
+ QCOMPARE(--i, i2);
+ QCOMPARE(i2+=3, p.constEnd());
+ QCOMPARE(i2-=3, p.constBegin());
+ QCOMPARE(i2+0, p.constBegin());
+ QCOMPARE(i2+3, p.constEnd());
+ i2 += 3;
+ i= i2-0;
+ QCOMPARE(i, i2);
+ i= i2-3;
+ QCOMPARE(i, p.constBegin());
+ QCOMPARE(i2-i, 3);
+
+ // QhullPoint is const-only
+ }
+}//t_const_iterator
+
+void QhullPoint_test::
+t_qhullpoint_iterator()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+
+ QhullPoint p2(q);
+ QhullPointIterator i= p2;
+ QCOMPARE(p2.dimension(), 3);
+ QVERIFY(!i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i.toBack();
+ QVERIFY(!i.hasNext());
+ QVERIFY(!i.hasPrevious());
+
+ QhullPoint p = q.firstVertex().point();
+ QhullPointIterator i2(p);
+ QCOMPARE(p.dimension(), 3);
+ i= p;
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i2.toBack();
+ i.toFront();
+ QVERIFY(!i2.hasNext());
+ QVERIFY(i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+
+ // i at front, i2 at end/back, 3 coordinates
+ QCOMPARE(i.peekNext(), p[0]);
+ QCOMPARE(i2.peekPrevious(), p[2]);
+ QCOMPARE(i2.previous(), p[2]);
+ QCOMPARE(i2.previous(), p[1]);
+ QCOMPARE(i2.previous(), p[0]);
+ QVERIFY(!i2.hasPrevious());
+ QCOMPARE(i.peekNext(), p[0]);
+ // i.peekNext()= 1.0; // compiler error, i is const
+ QCOMPARE(i.next(), p[0]);
+ QCOMPARE(i.peekNext(), p[1]);
+ QCOMPARE(i.next(), p[1]);
+ QCOMPARE(i.next(), p[2]);
+ QVERIFY(!i.hasNext());
+ i.toFront();
+ QCOMPARE(i.next(), p[0]);
+}//t_qhullpoint_iterator
+
+void QhullPoint_test::
+t_method()
+{
+ // advancePoint tested above
+ RboxPoints rcube("c");
+ Qhull q(rcube, "");
+ QhullPoint p = q.firstVertex().point();
+ double dist= p.distance(q.origin());
+ QCOMPARE(dist, sqrt(double(2.0+1.0))/2); // half diagonal of unit cube
+}//t_qhullpoint_iterator
+
+void QhullPoint_test::
+t_io()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube, "");
+ QhullPoint p= q.beginVertex().point();
+ ostringstream os;
+ os << "Point:\n";
+ os << p;
+ os << "Point w/ print:\n";
+ os << p.print(" message ");
+ os << p.printWithIdentifier(" Point with id and a message ");
+ cout << os.str();
+ QString s= QString::fromStdString(os.str());
+ QCOMPARE(s.count("p"), 2);
+ }
+}//t_io
+
+}//orgQhull
+
+#include "moc/QhullPoint_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullPoints_test.cpp b/xs/src/qhull/src/qhulltest/QhullPoints_test.cpp
new file mode 100644
index 000000000..c2d8347e2
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullPoints_test.cpp
@@ -0,0 +1,561 @@
+/****************************************************************************
+**
+** Copyright (p) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullPoints_test.cpp#3 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled header
+#include <iostream>
+#include "qhulltest/RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/QhullPoints.h"
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/Qhull.h"
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+
+namespace orgQhull {
+
+class QhullPoints_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_construct_q();
+ void t_construct_qh();
+ void t_convert();
+ void t_getset();
+ void t_element();
+ void t_iterator();
+ void t_const_iterator();
+ void t_search();
+ void t_points_iterator();
+ void t_io();
+};//QhullPoints_test
+
+void
+add_QhullPoints_test()
+{
+ new QhullPoints_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void QhullPoints_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void QhullPoints_test::
+t_construct_q()
+{
+ Qhull q;
+ QhullPoints ps(q);
+ QCOMPARE(ps.dimension(), 0);
+ QVERIFY(ps.isEmpty());
+ QCOMPARE(ps.count(), 0);
+ QCOMPARE(ps.size(), 0u);
+ QCOMPARE(ps.coordinateCount(), 0);
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ QhullPoints ps2(q);
+ ps2.defineAs(2, 6, c);
+ QCOMPARE(ps2.dimension(), 2);
+ QVERIFY(!ps2.isEmpty());
+ QCOMPARE(ps2.count(), 3);
+ QCOMPARE(ps2.size(), 3u);
+ QCOMPARE(ps2.coordinates(), c);
+ QhullPoints ps3(q, 2, 6, c);
+ QCOMPARE(ps3.dimension(), 2);
+ QVERIFY(!ps3.isEmpty());
+ QCOMPARE(ps3.coordinates(), ps2.coordinates());
+ QVERIFY(ps3==ps2);
+ QVERIFY(ps3!=ps);
+ QhullPoints ps4= ps3;
+ QVERIFY(ps4==ps3);
+ // ps4= ps3; //compiler error
+ QhullPoints ps5(ps4);
+ QVERIFY(ps5==ps4);
+ QVERIFY(!(ps5!=ps4));
+ coordT c2[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ QhullPoints ps6(q, 2, 6, c2);
+ QVERIFY(ps6==ps2);
+
+ RboxPoints rbox("c D2");
+ Qhull q2(rbox, "");
+ QhullPoints ps8(q2);
+ QCOMPARE(ps8.dimension(), 2);
+ QCOMPARE(ps8.count(), 0);
+ QCOMPARE(ps8.size(), 0u);
+ QCOMPARE(ps8.coordinateCount(), 0);
+ coordT c3[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ QhullPoints ps9(q2, 6, c3);
+ QCOMPARE(ps9.dimension(), 2);
+ QCOMPARE(ps9.coordinateCount(), 6);
+ QCOMPARE(ps9.count(), 3);
+ QCOMPARE(ps9.coordinates(), c3);
+ QCOMPARE(ps9, ps2); // DISTround
+ c3[1]= 1.0+1e-17;
+ QCOMPARE(ps9, ps2); // DISTround
+ c3[1]= 1.0+1e-15;
+ QVERIFY(ps9!=ps2); // DISTround
+
+ ps9.defineAs(6, c2);
+ QCOMPARE(ps9.dimension(), 2);
+ QCOMPARE(ps9.coordinateCount(), 6);
+ QCOMPARE(ps9.count(), 3);
+ QCOMPARE(ps9.coordinates(), c2);
+}//t_construct_q
+
+void QhullPoints_test::
+t_construct_qh()
+{
+ Qhull q;
+ QhullQh *qh= q.qh();
+ QhullPoints ps(qh);
+ QCOMPARE(ps.dimension(), 0);
+ QVERIFY(ps.isEmpty());
+ QCOMPARE(ps.count(), 0);
+ QCOMPARE(ps.size(), 0u);
+ QCOMPARE(ps.coordinateCount(), 0);
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ QhullPoints ps2(qh);
+ ps2.defineAs(2, 6, c);
+ QCOMPARE(ps2.dimension(), 2);
+ QVERIFY(!ps2.isEmpty());
+ QCOMPARE(ps2.count(), 3);
+ QCOMPARE(ps2.size(), 3u);
+ QCOMPARE(ps2.coordinates(), c);
+ QhullPoints ps3(qh, 2, 6, c);
+ QCOMPARE(ps3.dimension(), 2);
+ QVERIFY(!ps3.isEmpty());
+ QCOMPARE(ps3.coordinates(), ps2.coordinates());
+ QVERIFY(ps3==ps2);
+ QVERIFY(ps3!=ps);
+ QhullPoints ps4= ps3;
+ QVERIFY(ps4==ps3);
+ // ps4= ps3; //compiler error
+ QhullPoints ps5(ps4);
+ QVERIFY(ps5==ps4);
+ QVERIFY(!(ps5!=ps4));
+ coordT c2[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ QhullPoints ps6(qh, 2, 6, c2);
+ QVERIFY(ps6==ps2);
+
+ RboxPoints rbox("c D2");
+ Qhull q2(rbox, "");
+ QhullPoints ps8(q2.qh());
+ QCOMPARE(ps8.dimension(), 2);
+ QCOMPARE(ps8.count(), 0);
+ QCOMPARE(ps8.size(), 0u);
+ QCOMPARE(ps8.coordinateCount(), 0);
+ coordT c3[]= {10.0, 11.0, 12.0, 13.0, 14.0, 15.0};
+ QhullPoints ps9(q2.qh(), 6, c3);
+ QCOMPARE(ps9.dimension(), 2);
+ QCOMPARE(ps9.coordinateCount(), 6);
+ QCOMPARE(ps9.count(), 3);
+ QCOMPARE(ps9.coordinates(), c3);
+ ps9.defineAs(6, c2);
+ QCOMPARE(ps9.dimension(), 2);
+ QCOMPARE(ps9.coordinateCount(), 6);
+ QCOMPARE(ps9.count(), 3);
+ QCOMPARE(ps9.coordinates(), c2);
+}//t_construct_qh
+
+void QhullPoints_test::
+t_convert()
+{
+ Qhull q;
+ //defineAs tested above
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ QhullPoints ps(q, 3, 6, c);
+ QCOMPARE(ps.dimension(), 3);
+ QCOMPARE(ps.size(), 2u);
+ const coordT *c2= ps.constData();
+ QCOMPARE(c, c2);
+ const coordT *c3= ps.data();
+ QCOMPARE(c, c3);
+ coordT *c4= ps.data();
+ QCOMPARE(c, c4);
+ std::vector<QhullPoint> vs= ps.toStdVector();
+ QCOMPARE(vs.size(), 2u);
+ QhullPoint p= vs[1];
+ QCOMPARE(p[2], 5.0);
+ QList<QhullPoint> qs= ps.toQList();
+ QCOMPARE(qs.size(), 2);
+ QhullPoint p2= qs[1];
+ QCOMPARE(p2[2], 5.0);
+}//t_convert
+
+void QhullPoints_test::
+t_getset()
+{
+ Qhull q;
+ //See t_construct for coordinates, count, defineAs, dimension, isempty, ==, !=, size
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ QhullPoints ps(q, 3, 6, c);
+ QhullPoints ps2(q, 3, 6, c);
+ QCOMPARE(ps2.dimension(), 3);
+ QCOMPARE(ps2.coordinates(), c);
+ QCOMPARE(ps2.count(), 2);
+ QCOMPARE(ps2.coordinateCount(), 6);
+ coordT c2[]= {-1.0, -2.0, -3.0, -4.0, -5.0, -6.0};
+ ps2.defineAs(6, c2);
+ QCOMPARE(ps2.coordinates(), c2);
+ QCOMPARE(ps2.count(), 2);
+ QCOMPARE(ps2.size(), 2u);
+ QCOMPARE(ps2.dimension(), 3);
+ QVERIFY(!ps2.isEmpty());
+ QVERIFY(ps!=ps2);
+ // ps2= ps; // assignment not available, compiler error
+ ps2.defineAs(ps);
+ QVERIFY(ps==ps2);
+ ps2.setDimension(2);
+ QCOMPARE(ps2.dimension(), 2);
+ QCOMPARE(ps2.coordinates(), c);
+ QVERIFY(!ps2.isEmpty());
+ QCOMPARE(ps2.count(), 3);
+ QCOMPARE(ps2.size(), 3u);
+ QVERIFY(ps!=ps2);
+ QhullPoints ps3(ps2);
+ ps3.setDimension(3);
+ ps3.defineAs(5, c2);
+ QCOMPARE(ps3.count(), 1);
+ QCOMPARE(ps3.extraCoordinatesCount(), 2);
+ QCOMPARE(ps3.extraCoordinates()[0], -4.0);
+ QVERIFY(ps3.includesCoordinates(ps3.data()));
+ QVERIFY(ps3.includesCoordinates(ps3.data()+ps3.count()-1));
+ QVERIFY(!ps3.includesCoordinates(ps3.data()-1));
+ QVERIFY(!ps3.includesCoordinates(ps3.data()+ps3.coordinateCount()));
+}//t_getset
+
+
+void QhullPoints_test::
+t_element()
+{
+ Qhull q;
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ QhullPoints ps(q, 2, 6, c);
+ QCOMPARE(ps.count(), 3);
+ QhullPoint p(q, 2, c);
+ QCOMPARE(ps[0], p);
+ QCOMPARE(ps.at(1), ps[1]);
+ QCOMPARE(ps.first(), p);
+ QCOMPARE(ps.front(), ps.first());
+ QCOMPARE(ps.last(), ps.at(2));
+ QCOMPARE(ps.back(), ps.last());
+ QhullPoints ps2= ps.mid(2);
+ QCOMPARE(ps2.count(), 1);
+ QhullPoints ps3= ps.mid(3);
+ QVERIFY(ps3.isEmpty());
+ QhullPoints ps4= ps.mid(10);
+ QVERIFY(ps4.isEmpty());
+ QhullPoints ps5= ps.mid(-1);
+ QVERIFY(ps5.isEmpty());
+ QhullPoints ps6= ps.mid(1, 1);
+ QCOMPARE(ps6.count(), 1);
+ QCOMPARE(ps6[0], ps[1]);
+ QhullPoints ps7= ps.mid(1, 10);
+ QCOMPARE(ps7.count(), 2);
+ QCOMPARE(ps7[1], ps[2]);
+ QhullPoint p8(q);
+ QCOMPARE(ps.value(2), ps[2]);
+ QCOMPARE(ps.value(-1), p8);
+ QCOMPARE(ps.value(3), p8);
+ QCOMPARE(ps.value(3, p), p);
+ QVERIFY(ps.value(1, p)!=p);
+ foreach(QhullPoint p9, ps){ // Qt only
+ QCOMPARE(p9.dimension(), 2);
+ QVERIFY(p9[0]==0.0 || p9[0]==2.0 || p9[0]==4.0);
+ }
+}//t_element
+
+void QhullPoints_test::
+t_iterator()
+{
+ Qhull q;
+ coordT c[]= {0.0, 1.0, 2.0};
+ QhullPoints ps(q, 1, 3, c);
+ QCOMPARE(ps.dimension(), 1);
+ QhullPoints::Iterator i(ps);
+ QhullPoints::iterator i2= ps.begin();
+ QVERIFY(i==i2);
+ QVERIFY(i>=i2);
+ QVERIFY(i<=i2);
+ i= ps.begin();
+ QVERIFY(i==i2);
+ i2= ps.end();
+ QVERIFY(i!=i2);
+ QhullPoint p(i); // QhullPoint is the base class for QhullPoints::iterator
+ QCOMPARE(p.dimension(), ps.dimension());
+ QCOMPARE(p.coordinates(), ps.coordinates());
+ i2--;
+ QhullPoint p2= *i2;
+ QCOMPARE(p[0], 0.0);
+ QCOMPARE(p2[0], 2.0);
+ QhullPoints::Iterator i5(i2);
+ QCOMPARE(*i2, *i5);
+ coordT c3[]= {0.0, -1.0, -2.0};
+ QhullPoints::Iterator i3(q, 1, c3);
+ QVERIFY(i!=i3);
+ QCOMPARE(*i, *i3);
+
+ (i3= i)++;
+ QCOMPARE((*i3)[0], 1.0);
+ QCOMPARE(i3->dimension(), 1);
+ QCOMPARE(i3[0][0], 1.0);
+ QCOMPARE(i3[0], ps[1]);
+
+ QVERIFY(i==i);
+ QVERIFY(i!=i2);
+ QVERIFY(i<i2);
+ QVERIFY(i<=i2);
+ QVERIFY(i2>i);
+ QVERIFY(i2>=i);
+
+ QhullPoints::ConstIterator i4(q, 1, c);
+ QVERIFY(i==i4); // iterator COMP const_iterator
+ QVERIFY(i<=i4);
+ QVERIFY(i>=i4);
+ QVERIFY(i4==i); // const_iterator COMP iterator
+ QVERIFY(i4<=i);
+ QVERIFY(i4>=i);
+ QVERIFY(i>=i4);
+ QVERIFY(i4<=i);
+ QVERIFY(i2!=i4);
+ QVERIFY(i2>i4);
+ QVERIFY(i2>=i4);
+ QVERIFY(i4!=i2);
+ QVERIFY(i4<i2);
+ QVERIFY(i4<=i2);
+ ++i4;
+ QVERIFY(i<i4);
+ QVERIFY(i<=i4);
+ QVERIFY(i4>i);
+ QVERIFY(i4>=i);
+
+ i= ps.begin();
+ i2= ps.begin();
+ QCOMPARE(i, i2++);
+ QCOMPARE(*i2, ps[1]);
+ QCOMPARE(++i, i2);
+ QCOMPARE(i, i2--);
+ QCOMPARE(i2, ps.begin());
+ QCOMPARE(--i, i2);
+ QCOMPARE(i2+=3, ps.end());
+ QCOMPARE(i2-=3, ps.begin());
+ QCOMPARE(i2+0, ps.begin());
+ QCOMPARE(i2+3, ps.end());
+ i2 += 3;
+ i= i2-0;
+ QCOMPARE(i, i2);
+ i= i2-3;
+ QCOMPARE(i, ps.begin());
+ QCOMPARE(i2-i, 3);
+
+ //ps.begin end tested above
+
+ // QhullPoints is const-only
+}//t_iterator
+
+void QhullPoints_test::
+t_const_iterator()
+{
+ Qhull q;
+ coordT c[]= {0.0, 1.0, 2.0};
+ const QhullPoints ps(q, 1, 3, c);
+ QhullPoints::ConstIterator i(ps);
+ QhullPoints::const_iterator i2= ps.begin();
+ QVERIFY(i==i2);
+ QVERIFY(i>=i2);
+ QVERIFY(i<=i2);
+ i= ps.begin();
+ QVERIFY(i==i2);
+ i2= ps.end();
+ QVERIFY(i!=i2);
+ QhullPoint p(i);
+ QCOMPARE(p.dimension(), ps.dimension());
+ QCOMPARE(p.coordinates(), ps.coordinates());
+ i2--;
+ QhullPoint p2= *i2;
+ QCOMPARE(p[0], 0.0);
+ QCOMPARE(p2[0], 2.0);
+ QhullPoints::ConstIterator i5(i2);
+ QCOMPARE(*i2, *i5);
+ coordT c3[]= {0.0, -1.0, -2.0};
+ QhullPoints::ConstIterator i3(q, 1, c3);
+ QVERIFY(i!=i3);
+ QCOMPARE(*i, *i3);
+
+ (i3= i)++;
+ QCOMPARE((*i3)[0], 1.0);
+ QCOMPARE(i3->dimension(), 1);
+ QCOMPARE(i3[0][0], 1.0);
+ QCOMPARE(i3[0][0], 1.0);
+ QCOMPARE(i3[0], ps[1]);
+
+ QVERIFY(i==i);
+ QVERIFY(i!=i2);
+ QVERIFY(i<i2);
+ QVERIFY(i<=i2);
+ QVERIFY(i2>i);
+ QVERIFY(i2>=i);
+
+ // See t_iterator for const_iterator COMP iterator
+
+ i= ps.begin();
+ i2= ps.constBegin();
+ QCOMPARE(i, i2++);
+ QCOMPARE(*i2, ps[1]);
+ QCOMPARE(++i, i2);
+ QCOMPARE(i, i2--);
+ QCOMPARE(i2, ps.constBegin());
+ QCOMPARE(--i, i2);
+ QCOMPARE(i2+=3, ps.constEnd());
+ QCOMPARE(i2-=3, ps.constBegin());
+ QCOMPARE(i2+0, ps.constBegin());
+ QCOMPARE(i2+3, ps.constEnd());
+ i2 += 3;
+ i= i2-0;
+ QCOMPARE(i, i2);
+ i= i2-3;
+ QCOMPARE(i, ps.constBegin());
+ QCOMPARE(i2-i, 3);
+
+ // QhullPoints is const-only
+}//t_const_iterator
+
+
+void QhullPoints_test::
+t_search()
+{
+ Qhull q;
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 0, 1};
+ QhullPoints ps(q, 2, 8, c); //2-d array of 4 points
+ QhullPoint p= ps.first();
+ QhullPoint p2= ps.last();
+ QVERIFY(ps.contains(p));
+ QVERIFY(ps.contains(p2));
+ QVERIFY(p==p2);
+ QhullPoint p5= ps[2];
+ QVERIFY(p!=p5);
+ QVERIFY(ps.contains(p5));
+ coordT c2[]= {0.0, 1.0, 2.0, 3.0};
+ QhullPoint p3(q, 2, c2); //2-d point
+ QVERIFY(ps.contains(p3));
+ QhullPoint p4(q, 3, c2); //3-d point
+ QVERIFY(!ps.contains(p4));
+ p4.defineAs(2, c); //2-d point
+ QVERIFY(ps.contains(p4));
+ p4.defineAs(2, c+1); //2-d point
+ QVERIFY(!ps.contains(p4));
+ QhullPoint p6(q, 2, c2+2); //2-d point
+ QCOMPARE(ps.count(p), 2);
+ QCOMPARE(ps.count(p2), 2);
+ QCOMPARE(ps.count(p3), 2);
+ QCOMPARE(ps.count(p4), 0);
+ QCOMPARE(ps.count(p6), 1);
+ QCOMPARE(ps.indexOf(&ps[0][0]), 0);
+ //QCOMPARE(ps.indexOf(ps.end()), -1); //ps.end() is a QhullPoint which may match
+ QCOMPARE(ps.indexOf(0), -1);
+ QCOMPARE(ps.indexOf(&ps[3][0]), 3);
+ QCOMPARE(ps.indexOf(&ps[3][1], QhullError::NOthrow), 3);
+ QCOMPARE(ps.indexOf(ps.data()+ps.coordinateCount(), QhullError::NOthrow), -1);
+ QCOMPARE(ps.indexOf(p), 0);
+ QCOMPARE(ps.indexOf(p2), 0);
+ QCOMPARE(ps.indexOf(p3), 0);
+ QCOMPARE(ps.indexOf(p4), -1);
+ QCOMPARE(ps.indexOf(p5), 2);
+ QCOMPARE(ps.indexOf(p6), 1);
+ QCOMPARE(ps.lastIndexOf(p), 3);
+ QCOMPARE(ps.lastIndexOf(p4), -1);
+ QCOMPARE(ps.lastIndexOf(p6), 1);
+ QhullPoints ps3(q);
+ QCOMPARE(ps3.indexOf(ps3.data()), -1);
+ QCOMPARE(ps3.indexOf(ps3.data()+1, QhullError::NOthrow), -1);
+ QCOMPARE(ps3.indexOf(p), -1);
+ QCOMPARE(ps3.lastIndexOf(p), -1);
+ QhullPoints ps4(q, 2, 0, c);
+ QCOMPARE(ps4.indexOf(p), -1);
+ QCOMPARE(ps4.lastIndexOf(p), -1);
+}//t_search
+
+void QhullPoints_test::
+t_points_iterator()
+{
+ Qhull q;
+ coordT c2[]= {0.0};
+ QhullPoints ps2(q, 0, 0, c2); // 0-dimensional
+ QhullPointsIterator i2= ps2;
+ QVERIFY(!i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ i2.toBack();
+ QVERIFY(!i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ QhullPoints ps(q, 3, 6, c); // 3-dimensional
+ QhullPointsIterator i(ps);
+ i2= ps;
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i2.toBack();
+ i.toFront();
+ QVERIFY(!i2.hasNext());
+ QVERIFY(i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+
+ QhullPoint p= ps[0];
+ QhullPoint p2(ps[0]);
+ QCOMPARE(p, p2);
+ QVERIFY(p==p2);
+ QhullPoint p3(ps[1]);
+ // p2[0]= 0.0;
+ QVERIFY(p==p2);
+ QCOMPARE(i2.peekPrevious(), p3);
+ QCOMPARE(i2.previous(), p3);
+ QCOMPARE(i2.previous(), p);
+ QVERIFY(!i2.hasPrevious());
+ QCOMPARE(i.peekNext(), p);
+ // i.peekNext()= 1.0; // compiler error
+ QCOMPARE(i.next(), p);
+ QCOMPARE(i.peekNext(), p3);
+ QCOMPARE(i.next(), p3);
+ QVERIFY(!i.hasNext());
+ i.toFront();
+ QCOMPARE(i.next(), p);
+}//t_points_iterator
+
+void QhullPoints_test::
+t_io()
+{
+ Qhull q;
+ QhullPoints ps(q);
+ ostringstream os;
+ os << "Empty QhullPoints\n" << ps << endl;
+ coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
+ QhullPoints ps2(q, 3, 6, c); // 3-dimensional explicit
+ os << "QhullPoints from c[]\n" << ps2 << endl;
+
+ RboxPoints rcube("c");
+ Qhull q2(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullPoints ps3= q2.points();
+ os << "QhullPoints\n" << ps3;
+ os << ps3.print("message\n");
+ os << ps3.printWithIdentifier("w/ identifiers\n");
+ cout << os.str();
+ QString s= QString::fromStdString(os.str());
+ QCOMPARE(s.count("p"), 8+1);
+}//t_io
+
+}//orgQhull
+
+#include "moc/QhullPoints_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullRidge_test.cpp b/xs/src/qhull/src/qhulltest/QhullRidge_test.cpp
new file mode 100644
index 000000000..420a7f06d
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullRidge_test.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullRidge_test.cpp#3 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/QhullRidge.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/Qhull.h"
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::ostream;
+using std::string;
+
+namespace orgQhull {
+
+class QhullRidge_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_construct();
+ void t_getSet();
+ void t_foreach();
+ void t_io();
+};//QhullRidge_test
+
+void
+add_QhullRidge_test()
+{
+ new QhullRidge_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void QhullRidge_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void QhullRidge_test::
+t_construct()
+{
+ // Qhull.runQhull() constructs QhullFacets as facetT
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // triangulation of rotated unit cube
+ QhullRidge r(q);
+ QVERIFY(!r.isValid());
+ QCOMPARE(r.dimension(),2);
+ QhullFacet f(q.firstFacet());
+ QhullRidgeSet rs(f.ridges());
+ QVERIFY(!rs.isEmpty()); // Simplicial facets do not have ridges()
+ QhullRidge r2(rs.first());
+ QCOMPARE(r2.dimension(), 2); // One dimension lower than the facet
+ r= r2;
+ QVERIFY(r.isValid());
+ QCOMPARE(r.dimension(), 2);
+ QhullRidge r3(q, r2.getRidgeT());
+ QCOMPARE(r,r3);
+ QhullRidge r4(q, r2.getBaseT());
+ QCOMPARE(r,r4);
+ QhullRidge r5= r2; // copy constructor
+ QVERIFY(r5==r2);
+ QVERIFY(r5==r);
+}//t_construct
+
+void QhullRidge_test::
+t_getSet()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0"); // triangulation of rotated unit cube
+ QCOMPARE(q.facetCount(), 6);
+ QCOMPARE(q.vertexCount(), 8);
+ QhullFacet f(q.firstFacet());
+ QhullRidgeSet rs= f.ridges();
+ QhullRidgeSetIterator i(rs);
+ while(i.hasNext()){
+ const QhullRidge r= i.next();
+ cout << r.id() << endl;
+ QVERIFY(r.bottomFacet()!=r.topFacet());
+ QCOMPARE(r.dimension(), 2); // Ridge one-dimension less than facet
+ QVERIFY(r.id()>=0 && r.id()<9*27);
+ QVERIFY(r.isValid());
+ QVERIFY(r==r);
+ QVERIFY(r==i.peekPrevious());
+ QCOMPARE(r.otherFacet(r.bottomFacet()),r.topFacet());
+ QCOMPARE(r.otherFacet(r.topFacet()),r.bottomFacet());
+ }
+ }
+}//t_getSet
+
+void QhullRidge_test::
+t_foreach()
+{
+ RboxPoints rcube("c"); // cube
+ {
+ Qhull q(rcube, "QR0"); // rotated cube
+ QhullFacet f(q.firstFacet());
+ foreach (const QhullRidge &r, f.ridges()){ // Qt only
+ QhullVertexSet vs= r.vertices();
+ QCOMPARE(vs.count(), 2);
+ foreach (const QhullVertex &v, vs){ // Qt only
+ QVERIFY(f.vertices().contains(v));
+ }
+ }
+ QhullRidgeSet rs= f.ridges();
+ QhullRidge r= rs.first();
+ QhullRidge r2= r;
+ QList<QhullVertex> vs;
+ int count= 0;
+ while(!count || r2!=r){
+ ++count;
+ QhullVertex v(q);
+ QVERIFY2(r2.hasNextRidge3d(f),"A cube should only have non-simplicial facets.");
+ QhullRidge r3= r2.nextRidge3d(f, &v);
+ QVERIFY(!vs.contains(v));
+ vs << v;
+ r2= r2.nextRidge3d(f);
+ QCOMPARE(r3, r2);
+ }
+ QCOMPARE(vs.count(), rs.count());
+ QCOMPARE(count, rs.count());
+ }
+}//t_foreach
+
+void QhullRidge_test::
+t_io()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube, "");
+ QhullFacet f(q.firstFacet());
+ QhullRidgeSet rs= f.ridges();
+ QhullRidge r= rs.first();
+ ostringstream os;
+ os << "Ridges\n" << rs << "Ridge\n" << r;
+ os << r.print("\nRidge with message");
+ cout << os.str();
+ QString s= QString::fromStdString(os.str());
+ QCOMPARE(s.count(" r"), 6);
+ }
+}//t_io
+
+}//orgQhull
+
+#include "moc/QhullRidge_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullSet_test.cpp b/xs/src/qhull/src/qhulltest/QhullSet_test.cpp
new file mode 100644
index 000000000..87fcf4acf
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullSet_test.cpp
@@ -0,0 +1,434 @@
+/****************************************************************************
+**
+** Copyright (c) 2009-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullSet_test.cpp#3 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/QhullRidge.h"
+#include "libqhullcpp/QhullFacetSet.h"
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/RboxPoints.h"
+
+#include <QtCore/QList>
+
+using std::cout;
+using std::endl;
+
+namespace orgQhull {
+
+class QhullSet_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_qhullsetbase();
+ void t_convert();
+ void t_element();
+ void t_search();
+ void t_iterator();
+ void t_const_iterator();
+ void t_qhullset_iterator();
+ void t_io();
+};//QhullSet_test
+
+void
+add_QhullSet_test()
+{
+ new QhullSet_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void QhullSet_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+// Test QhullFacetSet and QhullSet.
+// Use QhullRidgeSet to test methods overloaded by QhullFacetSet
+
+void QhullSet_test::
+t_qhullsetbase()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0"); // triangulation of rotated unit cube
+ // Fake an empty set. Default constructor not defined. No memory allocation.
+ QhullFacet f4 = q.beginFacet();
+ QhullFacetSet fs = f4.neighborFacets();
+ fs.defineAs(q.qh()->other_points); // Force an empty set
+ QVERIFY(fs.isEmpty());
+ QCOMPARE(fs.count(), 0);
+ QCOMPARE(fs.size(), 0u);
+ QCOMPARE(fs.begin(), fs.end()); // beginPointer(), endPointer()
+ QVERIFY(QhullSetBase::isEmpty(fs.getSetT()));
+
+ QhullRidgeSet rs = f4.ridges();
+ QVERIFY(!rs.isEmpty());
+ QCOMPARE(rs.count(), 4);
+ QCOMPARE(rs.size(), 4u);
+ QVERIFY(rs.begin()!=rs.end());
+ QVERIFY(!QhullSetBase::isEmpty(rs.getSetT()));
+ QhullRidgeSet rs2= rs; // copy constructor
+ // rs= rs2; // disabled. Would not copy ridges
+ QCOMPARE(rs2, rs);
+
+ QCOMPARE(q.facetCount(), 6);
+ QhullFacet f = q.beginFacet();
+ QhullFacetSet fs2 = f.neighborFacets();
+ QCOMPARE(fs2.count(), 4);
+ QCOMPARE(fs2.size(), 4u);
+ QVERIFY(!fs2.isEmpty());
+ QVERIFY(!QhullSetBase::isEmpty(fs2.getSetT()));
+ QVERIFY(fs!=fs2);
+ setT *s= fs2.getSetT();
+ fs.defineAs(s);
+ QVERIFY(fs==fs2);
+ QCOMPARE(fs[1], fs2[1]); // elementPointer
+ QhullFacetSet fs3(fs2);
+ QVERIFY(fs3==fs);
+ // fs= fs2; // disabled. Would not copy facets
+ QhullFacetSet fs4= fs2; // copy constructor
+ QVERIFY(fs4==fs2);
+ }
+}//t_qhullsetbase
+
+// constructors tested by t_qhullsetbase
+
+void QhullSet_test::
+t_convert()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullFacet f= q.firstFacet();
+ f= f.next();
+ QhullRidgeSet rs= f.ridges();
+ QCOMPARE(rs.count(),4);
+ std::vector<QhullRidge> rv= rs.toStdVector();
+ QCOMPARE(rv.size(), 4u);
+ QList<QhullRidge> rv2= rs.toQList();
+ QCOMPARE(rv2.size(), 4);
+ std::vector<QhullRidge>::iterator i= rv.begin();
+ foreach(QhullRidge r, rv2){ // Qt only
+ QhullRidge r2= *i++;
+ QCOMPARE(r, r2);
+ }
+
+ Qhull q2(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QCOMPARE(q2.facetCount(), 12);
+ QhullFacet f2 = q2.beginFacet();
+ QhullFacetSet fs = f2.neighborFacets();
+ QCOMPARE(fs.size(), 3U);
+ std::vector<QhullFacet> vs= fs.toStdVector();
+ QCOMPARE(vs.size(), fs.size());
+ for(int k= fs.count(); k--; ){
+ QCOMPARE(vs[k], fs[k]);
+ }
+ QList<QhullFacet> qv= fs.toQList();
+ QCOMPARE(qv.count(), fs.count());
+ for(int k= fs.count(); k--; ){
+ QCOMPARE(qv[k], fs[k]);
+ }
+ }
+}//t_convert
+
+//ReadOnly (count, isEmpty) tested by t_convert
+// operator== tested by t_search
+
+void QhullSet_test::
+t_element()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullFacet f = q.beginFacet();
+ QhullFacetSet fs = f.neighborFacets();
+
+ QCOMPARE(fs.at(1), fs[1]);
+ QCOMPARE(fs.first(), fs[0]);
+ QCOMPARE(fs.front(), fs.first());
+ QCOMPARE(fs.last(), fs.at(3));
+ QCOMPARE(fs.back(), fs.last());
+ facetT **d = fs.data();
+ facetT * const *d2= fs.data();
+ facetT * const *d3= fs.constData();
+ QVERIFY(d==d2);
+ QVERIFY(d2==d3);
+ QCOMPARE(QhullFacet(q, *d), fs.first());
+ QhullFacetSet::iterator i(q.qh(), d+4);
+ QCOMPARE(i, fs.end());
+ QCOMPARE(d[4], static_cast<facetT *>(0));
+ QhullFacet f4(q, d[4]);
+ QVERIFY(!f4.isValid());
+ QCOMPARE(fs.second(), fs[1]);
+ const QhullFacet f2= fs.second();
+ QVERIFY(f2==fs[1]);
+ const QhullFacet f3= fs[1];
+ QCOMPARE(f2, f3);
+
+ QCOMPARE(fs.value(2), fs[2]);
+ QCOMPARE(fs.value(-1), QhullFacet());
+ QCOMPARE(fs.value(10), QhullFacet());
+ QCOMPARE(fs.value(2, f), fs[2]);
+ QCOMPARE(fs.value(4, f), f);
+ // mid() not available (read-only)
+}//t_element
+
+void QhullSet_test::
+t_search()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullFacet f = q.beginFacet();
+ QhullFacetSet fs = f.neighborFacets();
+ QhullFacet f2= *fs.begin();
+ QhullFacet f3= fs.last();
+ QVERIFY(fs.contains(f2));
+ QVERIFY(fs.contains(f3));
+ QVERIFY(!fs.contains(f));
+
+ QhullFacetSet fs2= f2.neighborFacets();
+ QVERIFY(fs==fs);
+ QVERIFY(fs!=fs2);
+ QCOMPARE(fs.count(f2), 1);
+ QCOMPARE(fs.count(f3), 1);
+ QCOMPARE(fs.count(f), 0);
+ QCOMPARE(fs.indexOf(f2), 0);
+ QCOMPARE(fs.indexOf(f3), 3);
+ QCOMPARE(fs.indexOf(f), -1);
+ QCOMPARE(fs.lastIndexOf(f2), 0);
+ QCOMPARE(fs.lastIndexOf(f3), 3);
+ QCOMPARE(fs.lastIndexOf(f), -1);
+}//t_search
+
+void QhullSet_test::
+t_iterator()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullFacet f = q.beginFacet();
+ QhullFacetSet fs = f.neighborFacets();
+ QhullFacetSet::Iterator i= fs.begin();
+ QhullFacetSet::iterator i2= fs.begin();
+ QVERIFY(i==i2);
+ QVERIFY(i>=i2);
+ QVERIFY(i<=i2);
+ i= fs.begin();
+ QVERIFY(i==i2);
+ i2= fs.end();
+ QVERIFY(i!=i2);
+ QhullFacet f3(*i);
+ i2--;
+ QhullFacet f2= *i2;
+ QCOMPARE(f3.id(), fs[0].id());
+ QCOMPARE(f2.id(), fs[3].id());
+ QhullFacetSet::Iterator i3(i2);
+ QCOMPARE(*i2, *i3);
+
+ (i3= i)++;
+ QCOMPARE((*i3).id(), fs[1].id());
+ QVERIFY(i==i);
+ QVERIFY(i!=i2);
+ QVERIFY(i<i2);
+ QVERIFY(i<=i2);
+ QVERIFY(i2>i);
+ QVERIFY(i2>=i);
+
+ QhullFacetSet::ConstIterator i4= fs.begin();
+ QVERIFY(i==i4); // iterator COMP const_iterator
+ QVERIFY(i<=i4);
+ QVERIFY(i>=i4);
+ QVERIFY(i4==i); // const_iterator COMP iterator
+ QVERIFY(i4<=i);
+ QVERIFY(i4>=i);
+ QVERIFY(i>=i4);
+ QVERIFY(i4<=i);
+ QVERIFY(i2!=i4);
+ QVERIFY(i2>i4);
+ QVERIFY(i2>=i4);
+ QVERIFY(i4!=i2);
+ QVERIFY(i4<i2);
+ QVERIFY(i4<=i2);
+ ++i4;
+ QVERIFY(i<i4);
+ QVERIFY(i<=i4);
+ QVERIFY(i4>i);
+ QVERIFY(i4>=i);
+
+ i= fs.begin();
+ i2= fs.begin();
+ QCOMPARE(i, i2++);
+ QCOMPARE(*i2, fs[1]);
+ QCOMPARE(++i, i2);
+ QCOMPARE(i, i2--);
+ QCOMPARE(i2, fs.begin());
+ QCOMPARE(--i, i2);
+ QCOMPARE(i2 += 4, fs.end());
+ QCOMPARE(i2 -= 4, fs.begin());
+ QCOMPARE(i2+0, fs.begin());
+ QCOMPARE(i2+4, fs.end());
+ i2 += 4;
+ i= i2-0;
+ QCOMPARE(i, i2);
+ i= i2-4;
+ QCOMPARE(i, fs.begin());
+ QCOMPARE(i2-i, 4);
+
+ //fs.begin end tested above
+
+ // QhullFacetSet is const-only
+ }
+}//t_iterator
+
+void QhullSet_test::
+t_const_iterator()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ QhullFacet f = q.beginFacet();
+ QhullFacetSet fs = f.neighborFacets();
+ QhullFacetSet::ConstIterator i= fs.begin();
+ QhullFacetSet::const_iterator i2= fs.begin();
+ QVERIFY(i==i2);
+ QVERIFY(i>=i2);
+ QVERIFY(i<=i2);
+ i= fs.begin();
+ QVERIFY(i==i2);
+ i2= fs.end();
+ QVERIFY(i!=i2);
+ QhullFacet f3(*i);
+ i2--;
+ QhullFacet f2= *i2;
+ QCOMPARE(f3.id(), fs[0].id());
+ QCOMPARE(f2.id(), fs[3].id());
+ QhullFacetSet::ConstIterator i3(i2);
+ QCOMPARE(*i2, *i3);
+
+ (i3= i)++;
+ QCOMPARE((*i3).id(), fs[1].id());
+ QVERIFY(i==i);
+ QVERIFY(i!=i2);
+ QVERIFY(i<i2);
+ QVERIFY(i<=i2);
+ QVERIFY(i2>i);
+ QVERIFY(i2>=i);
+
+ // See t_iterator for const_iterator COMP iterator
+
+ i= fs.begin();
+ i2= fs.constBegin();
+ QCOMPARE(i, i2++);
+ QCOMPARE(*i2, fs[1]);
+ QCOMPARE(++i, i2);
+ QCOMPARE(i, i2--);
+ QCOMPARE(i2, fs.constBegin());
+ QCOMPARE(--i, i2);
+ QCOMPARE(i2+=4, fs.constEnd());
+ QCOMPARE(i2-=4, fs.constBegin());
+ QCOMPARE(i2+0, fs.constBegin());
+ QCOMPARE(i2+4, fs.constEnd());
+ i2 += 4;
+ i= i2-0;
+ QCOMPARE(i, i2);
+ i= i2-4;
+ QCOMPARE(i, fs.constBegin());
+ QCOMPARE(i2-i, 4);
+
+ // QhullFacetSet is const-only
+ }
+}//t_const_iterator
+
+void QhullSet_test::
+t_qhullset_iterator()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ // Fake an empty set. Default constructor not defined. No memory allocation.
+ QhullFacet f = q.beginFacet();
+ QhullFacetSet fs = f.neighborFacets();
+ fs.defineAs(q.qh()->other_points);
+ QhullFacetSetIterator i(fs);
+ QCOMPARE(fs.count(), 0);
+ QVERIFY(!i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i.toBack();
+ QVERIFY(!i.hasNext());
+ QVERIFY(!i.hasPrevious());
+
+ QhullFacet f2 = q.beginFacet();
+ QhullFacetSet fs2 = f2.neighborFacets();
+ QhullFacetSetIterator i2(fs2);
+ QCOMPARE(fs2.count(), 4);
+ i= fs2;
+ QVERIFY(i2.hasNext());
+ QVERIFY(!i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+ i2.toBack();
+ i.toFront();
+ QVERIFY(!i2.hasNext());
+ QVERIFY(i2.hasPrevious());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+
+ // i at front, i2 at end/back, 4 neighbors
+ QhullFacetSet fs3 = f2.neighborFacets(); // same as fs2
+ QhullFacet f3(fs2[0]);
+ QhullFacet f4= fs3[0];
+ QCOMPARE(f3, f4);
+ QVERIFY(f3==f4);
+ QhullFacet f5(fs3[1]);
+ QVERIFY(f4!=f5);
+ QhullFacet f6(fs3[2]);
+ QhullFacet f7(fs3[3]);
+ QCOMPARE(i2.peekPrevious(), f7);
+ QCOMPARE(i2.previous(), f7);
+ QCOMPARE(i2.previous(), f6);
+ QCOMPARE(i2.previous(), f5);
+ QCOMPARE(i2.previous(), f4);
+ QVERIFY(!i2.hasPrevious());
+ QCOMPARE(i.peekNext(), f4);
+ // i.peekNext()= 1.0; // compiler error
+ QCOMPARE(i.next(), f4);
+ QCOMPARE(i.peekNext(), f5);
+ QCOMPARE(i.next(), f5);
+ QCOMPARE(i.next(), f6);
+ QCOMPARE(i.next(), f7);
+ QVERIFY(!i.hasNext());
+ i.toFront();
+ QCOMPARE(i.next(), f4);
+}//t_qhullset_iterator
+
+void QhullSet_test::
+t_io()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ // Fake an empty set. Default constructor not defined. No memory allocation.
+ QhullFacet f= q.beginFacet();
+ QhullFacetSet fs= f.neighborFacets();
+ fs.defineAs(q.qh()->other_points);
+ cout << "INFO: empty set" << fs << std::endl;
+ QhullFacet f2= q.beginFacet();
+ QhullFacetSet fs2= f2.neighborFacets();
+ cout << "INFO: Neighboring facets\n";
+ cout << fs2 << std::endl;
+
+ QhullRidgeSet rs= f.ridges();
+ cout << "INFO: Ridges for a facet\n";
+ cout << rs << std::endl;
+}//t_io
+
+}//namespace orgQhull
+
+#include "moc/QhullSet_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullVertexSet_test.cpp b/xs/src/qhull/src/qhulltest/QhullVertexSet_test.cpp
new file mode 100644
index 000000000..41caacd29
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullVertexSet_test.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullVertexSet_test.cpp#3 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "qhulltest/RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/QhullVertexSet.h"
+#include "libqhullcpp/QhullVertex.h"
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/RboxPoints.h"
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::ostream;
+using std::string;
+
+namespace orgQhull {
+
+class QhullVertexSet_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_construct();
+ void t_convert();
+ void t_readonly();
+ void t_foreach();
+ void t_io();
+};//QhullVertexSet_test
+
+void
+add_QhullVertexSet_test()
+{
+ new QhullVertexSet_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void QhullVertexSet_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void QhullVertexSet_test::
+t_construct()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ cout << "INFO : Cube rotated by QR" << q.rotateRandom() << std::endl;
+ QhullFacet f= q.firstFacet();
+ QhullVertexSet vs= f.vertices();
+ QVERIFY(!vs.isEmpty());
+ QCOMPARE(vs.count(),4);
+ QhullVertexSet vs4= vs; // copy constructor
+ QVERIFY(vs4==vs);
+ QhullVertexSet vs3(q, q.qh()->del_vertices);
+ QVERIFY(vs3.isEmpty());
+}//t_construct
+
+void QhullVertexSet_test::
+t_convert()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QR0 QV2"); // rotated unit cube with "good" facets adjacent to point 0
+ cout << "INFO : Cube rotated by QR" << q.rotateRandom() << std::endl;
+ QhullFacet f= q.firstFacet();
+ QhullVertexSet vs2= f.vertices();
+ QCOMPARE(vs2.count(),4);
+ std::vector<QhullVertex> fv= vs2.toStdVector();
+ QCOMPARE(fv.size(), 4u);
+ QList<QhullVertex> fv2= vs2.toQList();
+ QCOMPARE(fv2.size(), 4);
+ std::vector<QhullVertex> fv3= vs2.toStdVector();
+ QCOMPARE(fv3.size(), 4u);
+ QList<QhullVertex> fv4= vs2.toQList();
+ QCOMPARE(fv4.size(), 4);
+}//t_convert
+
+//! Spot check properties and read-only. See QhullSet_test
+void QhullVertexSet_test::
+t_readonly()
+{
+ RboxPoints rcube("c");
+ Qhull q(rcube,"QV0"); // good facets are adjacent to point 0
+ QhullVertexSet vs= q.firstFacet().vertices();
+ QCOMPARE(vs.count(), 4);
+ QCOMPARE(vs.count(), 4);
+ QhullVertex v= vs.first();
+ QhullVertex v2= vs.last();
+ QVERIFY(vs.contains(v));
+ QVERIFY(vs.contains(v2));
+}//t_readonly
+
+void QhullVertexSet_test::
+t_foreach()
+{
+ RboxPoints rcube("c");
+ // Spot check predicates and accessors. See QhullLinkedList_test
+ Qhull q(rcube,"QR0"); // rotated unit cube
+ cout << "INFO : Cube rotated by QR" << q.rotateRandom() << std::endl;
+ QhullVertexSet vs= q.firstFacet().vertices();
+ QVERIFY(vs.contains(vs.first()));
+ QVERIFY(vs.contains(vs.last()));
+ QCOMPARE(vs.first(), *vs.begin());
+ QCOMPARE(*(vs.end()-1), vs.last());
+}//t_foreach
+
+void QhullVertexSet_test::
+t_io()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"QR0 QV0"); // good facets are adjacent to point 0
+ cout << "INFO : Cube rotated by QR" << q.rotateRandom() << std::endl;
+ QhullVertexSet vs= q.firstFacet().vertices();
+ ostringstream os;
+ os << vs.print("Vertices of first facet with point 0");
+ os << vs.printIdentifiers("\nVertex identifiers: ");
+ cout<< os.str();
+ QString vertices= QString::fromStdString(os.str());
+ QCOMPARE(vertices.count(QRegExp(" v[0-9]")), 4);
+ }
+}//t_io
+
+#ifdef QHULL_USES_QT
+QList<QhullVertex> QhullVertexSet::
+toQList() const
+{
+ QhullSetIterator<QhullVertex> i(*this);
+ QList<QhullVertex> vs;
+ while(i.hasNext()){
+ QhullVertex v= i.next();
+ vs.append(v);
+ }
+ return vs;
+}//toQList
+#endif //QHULL_USES_QT
+
+}//orgQhull
+
+#include "moc/QhullVertexSet_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/QhullVertex_test.cpp b/xs/src/qhull/src/qhulltest/QhullVertex_test.cpp
new file mode 100644
index 000000000..fb6ec9640
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/QhullVertex_test.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/QhullVertex_test.cpp#3 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/QhullVertex.h"
+#include "libqhullcpp/Coordinates.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/QhullFacetSet.h"
+#include "libqhullcpp/QhullVertexSet.h"
+#include "libqhullcpp/Qhull.h"
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::ostream;
+using std::string;
+
+namespace orgQhull {
+
+class QhullVertex_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_constructConvert();
+ void t_getSet();
+ void t_foreach();
+ void t_io();
+};//QhullVertex_test
+
+void
+add_QhullVertex_test()
+{
+ new QhullVertex_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void QhullVertex_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void QhullVertex_test::
+t_constructConvert()
+{
+ QhullVertex v6;
+ QVERIFY(!v6.isValid());
+ QCOMPARE(v6.dimension(),0);
+ // Qhull.runQhull() constructs QhullFacets as facetT
+ RboxPoints rcube("c");
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QhullVertex v(q);
+ QVERIFY(!v.isValid());
+ QCOMPARE(v.dimension(),3);
+ QhullVertex v2(q.beginVertex());
+ QCOMPARE(v2.dimension(),3);
+ v= v2; // copy assignment
+ QVERIFY(v.isValid());
+ QCOMPARE(v.dimension(),3);
+ QhullVertex v5= v2; // copy constructor
+ QVERIFY(v5==v2);
+ QVERIFY(v5==v);
+ QhullVertex v3(q, v2.getVertexT());
+ QCOMPARE(v,v3);
+ QhullVertex v4(q, v2.getBaseT());
+ QCOMPARE(v,v4);
+}//t_constructConvert
+
+void QhullVertex_test::
+t_getSet()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
+ QCOMPARE(q.facetCount(), 12);
+ QCOMPARE(q.vertexCount(), 8);
+
+ // Also spot-test QhullVertexList. See QhullLinkedList_test.cpp
+ QhullVertexList vs= q.vertexList();
+ QhullVertexListIterator i(vs);
+ while(i.hasNext()){
+ const QhullVertex v= i.next();
+ cout << v.id() << endl;
+ QCOMPARE(v.dimension(),3);
+ QVERIFY(v.id()>=0 && v.id()<9);
+ QVERIFY(v.isValid());
+ if(i.hasNext()){
+ QCOMPARE(v.next(), i.peekNext());
+ QVERIFY(v.next()!=v);
+ QVERIFY(v.next().previous()==v);
+ }
+ QVERIFY(i.hasPrevious());
+ QCOMPARE(v, i.peekPrevious());
+ }
+
+ // test point()
+ foreach (QhullVertex v, q.vertexList()){ // Qt only
+ QhullPoint p= v.point();
+ int j= p.id();
+ cout << "Point " << j << ":\n" << p << endl;
+ QVERIFY(j>=0 && j<8);
+ }
+ }
+}//t_getSet
+
+void QhullVertex_test::
+t_foreach()
+{
+ RboxPoints rcube("c W0 300"); // 300 points on surface of cube
+ {
+ Qhull q(rcube, "QR0 Qc"); // keep coplanars, thick facet, and rotate the cube
+ foreach (QhullVertex v, q.vertexList()){ // Qt only
+ QhullFacetSet fs= v.neighborFacets();
+ QCOMPARE(fs.count(), 3);
+ foreach (QhullFacet f, fs){ // Qt only
+ QVERIFY(f.vertices().contains(v));
+ }
+ }
+ }
+}//t_foreach
+
+void QhullVertex_test::
+t_io()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q(rcube, "");
+ QhullVertex v= q.beginVertex();
+ ostringstream os;
+ os << "Vertex and vertices:\n";
+ os << v;
+ QhullVertexSet vs= q.firstFacet().vertices();
+ os << vs;
+ os << "\nVertex and vertices with message:\n";
+ os << v.print("Vertex");
+ os << vs.print("\nVertices:");
+ cout << os.str();
+ QString s= QString::fromStdString(os.str());
+ QCOMPARE(s.count("(v"), 10);
+ QCOMPARE(s.count(": f"), 2);
+ }
+ RboxPoints r10("10 D3"); // Without QhullVertex::facetNeighbors
+ {
+ Qhull q(r10, "");
+ QhullVertex v= q.beginVertex();
+ ostringstream os;
+ os << "\nTry again with simplicial facets. No neighboring facets listed for vertices.\n";
+ os << "Vertex and vertices:\n";
+ os << v;
+ q.defineVertexNeighborFacets();
+ os << "This time with neighborFacets() defined for all vertices:\n";
+ os << v;
+ cout << os.str();
+ QString s= QString::fromStdString(os.str());
+ QCOMPARE(s.count(": f"), 1);
+
+ Qhull q2(r10, "v"); // Voronoi diagram
+ QhullVertex v2= q2.beginVertex();
+ ostringstream os2;
+ os2 << "\nTry again with Voronoi diagram of simplicial facets. Neighboring facets automatically defined for vertices.\n";
+ os2 << "Vertex and vertices:\n";
+ os2 << v2;
+ cout << os2.str();
+ QString s2= QString::fromStdString(os2.str());
+ QCOMPARE(s2.count(": f"), 1);
+ }
+}//t_io
+
+}//orgQhull
+
+#include "moc/QhullVertex_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/Qhull_test.cpp b/xs/src/qhull/src/qhulltest/Qhull_test.cpp
new file mode 100644
index 000000000..cc3918a05
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/Qhull_test.cpp
@@ -0,0 +1,360 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/Qhull_test.cpp#4 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "qhulltest/RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/Qhull.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/QhullFacetList.h"
+
+using std::cout;
+using std::endl;
+using std::string;
+
+namespace orgQhull {
+
+//! Test C++ interface to Qhull
+//! See eg/q_test for tests of Qhull commands
+class Qhull_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void cleanup();
+ void t_construct();
+ void t_attribute();
+ void t_message();
+ void t_getSet();
+ void t_getQh();
+ void t_getValue();
+ void t_foreach();
+ void t_modify();
+};//Qhull_test
+
+void
+add_Qhull_test()
+{
+ new Qhull_test(); // RoadTest::s_testcases
+}
+
+//Executed after each testcase
+void Qhull_test::
+cleanup()
+{
+ RoadTest::cleanup();
+}
+
+void Qhull_test::
+t_construct()
+{
+ {
+ Qhull q;
+ QCOMPARE(q.dimension(),0);
+ QVERIFY(q.qh()!=0);
+ QCOMPARE(QString(q.qhullCommand()),QString(""));
+ QCOMPARE(QString(q.rboxCommand()),QString(""));
+ try{
+ QCOMPARE(q.area(),0.0);
+ QFAIL("area() did not fail.");
+ }catch (const std::exception &e) {
+ cout << "INFO : Caught " << e.what();
+ }
+ }
+ {
+ RboxPoints rbox("10000");
+ Qhull q(rbox, "QR0"); // Random points in a randomly rotated cube.
+ QCOMPARE(q.dimension(),3);
+ QVERIFY(q.volume() < 1.0);
+ QVERIFY(q.volume() > 0.99);
+ }
+ {
+ double points[] = {
+ 0, 0,
+ 1, 0,
+ 1, 1
+ };
+ Qhull q("triangle", 2, 3, points, "");
+ QCOMPARE(q.dimension(),2);
+ QCOMPARE(q.facetCount(),3);
+ QCOMPARE(q.vertexCount(),3);
+ QCOMPARE(q.dimension(),2);
+ QCOMPARE(q.area(), 2.0+sqrt(2.0)); // length of boundary
+ QCOMPARE(q.volume(), 0.5); // the 2-d area
+ }
+}//t_construct
+
+void Qhull_test::
+t_attribute()
+{
+ RboxPoints rcube("c");
+ {
+ double normals[] = {
+ 0, -1, -0.5,
+ -1, 0, -0.5,
+ 1, 0, -0.5,
+ 0, 1, -0.5
+ };
+ Qhull q;
+ Coordinates feasible;
+ feasible << 0.0 << 0.0;
+ q.setFeasiblePoint(feasible);
+ Coordinates c(std::vector<double>(2, 0.0));
+ QVERIFY(q.feasiblePoint()==c);
+ q.setOutputStream(&cout);
+ q.runQhull("normals of square", 3, 4, normals, "H"); // halfspace intersect
+ QVERIFY(q.feasiblePoint()==c); // from qh.feasible_point after runQhull()
+ QCOMPARE(q.facetList().count(), 4); // Vertices of square
+ cout << "Expecting summary of halfspace intersection\n";
+ q.outputQhull();
+ q.qh()->disableOutputStream(); // Same as q.disableOutputStream()
+ cout << "Expecting no output from qh_fprintf() in Qhull.cpp\n";
+ q.outputQhull();
+ }
+}//t_attribute
+
+//! No QhullMessage for errors outside of qhull
+void Qhull_test::
+t_message()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q;
+ QCOMPARE(q.qhullMessage(), string(""));
+ QCOMPARE(q.qhullStatus(), qh_ERRnone);
+ QVERIFY(!q.hasQhullMessage());
+ try{
+ q.runQhull(rcube, "Fd");
+ QFAIL("runQhull Fd did not fail.");
+ }catch (const std::exception &e) {
+ const char *s= e.what();
+ cout << "INFO : Caught " << s;
+ QCOMPARE(QString::fromStdString(s).left(6), QString("QH6029"));
+ // FIXUP QH11025 -- review decision to clearQhullMessage at QhullError() // Cleared when copied to QhullError
+ QVERIFY(!q.hasQhullMessage());
+ // QCOMPARE(q.qhullMessage(), QString::fromStdString(s).remove(0, 7));
+ // QCOMPARE(q.qhullStatus(), 6029);
+ q.clearQhullMessage();
+ QVERIFY(!q.hasQhullMessage());
+ }
+ q.appendQhullMessage("Append 1");
+ QVERIFY(q.hasQhullMessage());
+ QCOMPARE(QString::fromStdString(q.qhullMessage()), QString("Append 1"));
+ q.appendQhullMessage("\nAppend 2\n");
+ QCOMPARE(QString::fromStdString(q.qhullMessage()), QString("Append 1\nAppend 2\n"));
+ q.clearQhullMessage();
+ QVERIFY(!q.hasQhullMessage());
+ QCOMPARE(QString::fromStdString(q.qhullMessage()), QString(""));
+ }
+ {
+ cout << "INFO : Error stream without output stream\n";
+ Qhull q;
+ q.setErrorStream(&cout);
+ q.setOutputStream(0);
+ try{
+ q.runQhull(rcube, "Fd");
+ QFAIL("runQhull Fd did not fail.");
+ }catch (const QhullError &e) {
+ cout << "INFO : Caught " << e;
+ QCOMPARE(e.errorCode(), 6029);
+ }
+ //FIXUP QH11025 Qhullmessage cleared when QhullError thrown. Switched to e
+ //QVERIFY(q.hasQhullMessage());
+ //QCOMPARE(QString::fromStdString(q.qhullMessage()).left(6), QString("QH6029"));
+ q.clearQhullMessage();
+ QVERIFY(!q.hasQhullMessage());
+ }
+ {
+ cout << "INFO : Error output sent to output stream without error stream\n";
+ Qhull q;
+ q.setErrorStream(0);
+ q.setOutputStream(&cout);
+ try{
+ q.runQhull(rcube, "Tz H0");
+ QFAIL("runQhull TZ did not fail.");
+ }catch (const std::exception &e) {
+ const char *s= e.what();
+ cout << "INFO : Caught " << s;
+ QCOMPARE(QString::fromLatin1(s).left(6), QString("QH6023"));
+ }
+ //FIXUP QH11025 Qhullmessage cleared when QhullError thrown. Switched to e
+ //QVERIFY(q.hasQhullMessage());
+ //QCOMPARE(QString::fromStdString(q.qhullMessage()).left(17), QString("qhull: no message"));
+ //QCOMPARE(q.qhullStatus(), 6023);
+ q.clearQhullMessage();
+ QVERIFY(!q.hasQhullMessage());
+ }
+ {
+ cout << "INFO : No error stream or output stream\n";
+ Qhull q;
+ q.setErrorStream(0);
+ q.setOutputStream(0);
+ try{
+ q.runQhull(rcube, "Fd");
+ QFAIL("outputQhull did not fail.");
+ }catch (const std::exception &e) {
+ const char *s= e.what();
+ cout << "INFO : Caught " << s;
+ QCOMPARE(QString::fromLatin1(s).left(6), QString("QH6029"));
+ }
+ //FIXUP QH11025 Qhullmessage cleared when QhullError thrown. Switched to e
+ //QVERIFY(q.hasQhullMessage());
+ //QCOMPARE(QString::fromStdString(q.qhullMessage()).left(9), QString("qhull err"));
+ //QCOMPARE(q.qhullStatus(), 6029);
+ q.clearQhullMessage();
+ QVERIFY(!q.hasQhullMessage());
+ }
+}//t_message
+
+void Qhull_test::
+t_getSet()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q;
+ QVERIFY(!q.initialized());
+ q.runQhull(rcube, "s");
+ QVERIFY(q.initialized());
+ QCOMPARE(q.dimension(), 3);
+ QhullPoint p= q.origin();
+ QCOMPARE(p.dimension(), 3);
+ QCOMPARE(p[0]+p[1]+p[2], 0.0);
+ q.setErrorStream(&cout);
+ q.outputQhull();
+ }
+ {
+ Qhull q;
+ q.runQhull(rcube, "");
+ q.setOutputStream(&cout);
+ q.outputQhull();
+ }
+}//t_getSet
+
+void Qhull_test::
+t_getQh()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q;
+ q.runQhull(rcube, "s");
+ QCOMPARE(QString(q.qhullCommand()), QString("qhull s"));
+ QCOMPARE(QString(q.rboxCommand()), QString("rbox \"c\""));
+ QCOMPARE(q.facetCount(), 6);
+ QCOMPARE(q.vertexCount(), 8);
+ // Sample fields from Qhull's qhT [libqhull.h]
+ QCOMPARE(q.qh()->ALLpoints, 0u);
+ QCOMPARE(q.qh()->GOODpoint, 0);
+ QCOMPARE(q.qh()->IStracing, 0);
+ QCOMPARE(q.qh()->MAXcoplanar+1.0, 1.0); // fuzzy compare
+ QCOMPARE(q.qh()->MERGING, 1u);
+ QCOMPARE(q.qh()->input_dim, 3);
+ QCOMPARE(QString(q.qh()->qhull_options).left(8), QString(" run-id"));
+ QCOMPARE(q.qh()->num_facets, 6);
+ QCOMPARE(q.qh()->hasTriangulation, 0u);
+ QCOMPARE(q.qh()->max_outside - q.qh()->min_vertex + 1.0, 1.0); // fuzzy compare
+ QCOMPARE(*q.qh()->gm_matrix+1.0, 1.0); // fuzzy compare
+ }
+}//t_getQh
+
+void Qhull_test::
+t_getValue()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q;
+ q.runQhull(rcube, "");
+ QCOMPARE(q.area(), 6.0);
+ QCOMPARE(q.volume(), 1.0);
+ }
+}//t_getValue
+
+void Qhull_test::
+t_foreach()
+{
+ RboxPoints rcube("c");
+ {
+ Qhull q;
+ QCOMPARE(q.beginFacet(),q.endFacet());
+ QCOMPARE(q.beginVertex(),q.endVertex());
+ q.runQhull(rcube, "");
+ QCOMPARE(q.facetList().count(), 6);
+
+ // defineVertexNeighborFacets() tested in QhullVertex_test::t_io()
+
+ QhullFacetList facets(q.beginFacet(), q.endFacet());
+ QCOMPARE(facets.count(), 6);
+ QCOMPARE(q.firstFacet(), q.beginFacet());
+ QhullVertexList vertices(q.beginVertex(), q.endVertex());
+ QCOMPARE(vertices.count(), 8);
+ QCOMPARE(q.firstVertex(), q.beginVertex());
+ QhullPoints ps= q.points();
+ QCOMPARE(ps.count(), 8);
+ QhullPointSet ps2= q.otherPoints();
+ QCOMPARE(ps2.count(), 0);
+ // ps2= q.otherPoints(); //disabled, would not copy the points
+ QCOMPARE(q.facetCount(), 6);
+ QCOMPARE(q.vertexCount(), 8);
+ coordT *c= q.pointCoordinateBegin(); // of q.points()
+ QVERIFY(*c==0.5 || *c==-0.5);
+ coordT *c3= q.pointCoordinateEnd();
+ QVERIFY(c3[-1]==0.5 || c3[-1]==-0.5);
+ QCOMPARE(c3-c, 8*3);
+ QCOMPARE(q.vertexList().count(), 8);
+ }
+}//t_foreach
+
+void Qhull_test::
+t_modify()
+{
+ //addPoint() tested in t_foreach
+ RboxPoints diamond("d");
+ Qhull q(diamond, "o");
+ q.setOutputStream(&cout);
+ cout << "Expecting vertexList and facetList of a 3-d diamond.\n";
+ q.outputQhull();
+ cout << "Expecting normals of a 3-d diamond.\n";
+ q.outputQhull("n");
+ // runQhull tested in t_attribute(), t_message(), etc.
+}//t_modify
+
+}//orgQhull
+
+// Redefine Qhull's usermem_r.c in order to report erroneous calls to qh_exit
+void qh_exit(int exitcode) {
+ cout << "FAIL! : Qhull called qh_exit(). Qhull's error handling not available.\n.. See the corresponding Qhull:qhull_message or setErrorStream().\n";
+ exit(exitcode);
+}
+void qh_fprintf_stderr(int msgcode, const char *fmt, ... ) {
+ va_list args;
+
+ va_start(args, fmt);
+ if(msgcode)
+ fprintf(stderr, "QH%.4d ", msgcode);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+} /* fprintf_stderr */
+void qh_free(void *mem) {
+ free(mem);
+}
+void *qh_malloc(size_t size) {
+ return malloc(size);
+}
+
+#if 0
+template<> char * QTest::
+toString(const std::string &s)
+{
+ QByteArray ba = s.c_str();
+ return qstrdup(ba.data());
+}
+#endif
+
+#include "moc/Qhull_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/RboxPoints_test.cpp b/xs/src/qhull/src/qhulltest/RboxPoints_test.cpp
new file mode 100644
index 000000000..4f4ea984f
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/RboxPoints_test.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (c) 2006-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/RboxPoints_test.cpp#2 $$Change: 2062 $
+** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/QhullError.h"
+
+using std::cout;
+using std::endl;
+using std::ostringstream;
+using std::string;
+using std::stringstream;
+
+namespace orgQhull {
+
+//! Test C++ interface to Rbox
+//! See eg/q_test for tests of rbox commands
+class RboxPoints_test : public RoadTest
+{
+ Q_OBJECT
+
+#//!\name Test slots
+private slots:
+ void t_construct();
+ void t_error();
+ void t_test();
+ void t_getSet();
+ void t_foreach();
+ void t_change();
+ void t_ostream();
+};
+
+void
+add_RboxPoints_test()
+{
+ new RboxPoints_test(); // RoadTest::s_testcases
+}
+
+void RboxPoints_test::
+t_construct()
+{
+ RboxPoints rp;
+ QCOMPARE(rp.dimension(), 0);
+ QCOMPARE(rp.count(), 0);
+ QVERIFY(QString::fromStdString(rp.comment()) != QString(""));
+ QVERIFY(rp.isEmpty());
+ QVERIFY(!rp.hasRboxMessage());
+ QCOMPARE(rp.rboxStatus(), qh_ERRnone);
+ QCOMPARE(QString::fromStdString(rp.rboxMessage()), QString("rbox warning: no points generated\n"));
+
+ RboxPoints rp2("c"); // 3-d cube
+ QCOMPARE(rp2.dimension(), 3);
+ QCOMPARE(rp2.count(), 8);
+ QCOMPARE(QString::fromStdString(rp2.comment()), QString("rbox \"c\""));
+ QVERIFY(!rp2.isEmpty());
+ QVERIFY(!rp2.hasRboxMessage());
+ QCOMPARE(rp2.rboxStatus(), qh_ERRnone);
+ QCOMPARE(QString::fromStdString(rp2.rboxMessage()), QString("rbox: OK\n"));
+}//t_construct
+
+void RboxPoints_test::
+t_error()
+{
+ RboxPoints rp;
+ try{
+ rp.appendPoints("D0 c");
+ QFAIL("'D0 c' did not fail.");
+ }catch (const std::exception &e) {
+ const char *s= e.what();
+ cout << "INFO : Caught " << s;
+ QCOMPARE(QString(s).left(6), QString("QH6189"));
+ QVERIFY(rp.hasRboxMessage());
+ QCOMPARE(QString::fromStdString(rp.rboxMessage()).left(8), QString("rbox err"));
+ QCOMPARE(rp.rboxStatus(), 6189);
+ rp.clearRboxMessage();
+ QVERIFY(!rp.hasRboxMessage());
+ }
+ try{
+ RboxPoints rp2;
+ rp2.setDimension(-1);
+ QFAIL("setDimension(-1) did not fail.");
+ }catch (const RoadError &e) {
+ const char *s= e.what();
+ cout << "INFO : Caught " << s;
+ QCOMPARE(QString(s).left(7), QString("QH10062"));
+ QCOMPARE(e.errorCode(), 10062);
+ QCOMPARE(QString::fromStdString(e.what()), QString(s));
+ RoadLogEvent logEvent= e.roadLogEvent();
+ QCOMPARE(logEvent.int1(), -1);
+ }
+}//t_error
+
+void RboxPoints_test::
+t_test()
+{
+ // isEmpty -- t_construct
+}//t_test
+
+void RboxPoints_test::
+t_getSet()
+{
+ // comment -- t_construct
+ // count -- t_construct
+ // dimension -- t_construct
+
+ RboxPoints rp;
+ QCOMPARE(rp.dimension(), 0);
+ rp.setDimension(2);
+ QCOMPARE(rp.dimension(), 2);
+ try{
+ rp.setDimension(102);
+ QFAIL("setDimension(102) did not fail.");
+ }catch (const std::exception &e) {
+ cout << "INFO : Caught " << e.what();
+ }
+ QCOMPARE(rp.newCount(), 0);
+ rp.appendPoints("D2 P1 P2");
+ QCOMPARE(rp.count(), 2);
+ QCOMPARE(rp.newCount(), 2); // From previous appendPoints();
+ PointCoordinates pc(rp.qh(), 2, "Test qh() and <<");
+ pc << 1.0 << 0.0 << 2.0 << 0.0;
+ QCOMPARE(pc.dimension(), 2);
+ QCOMPARE(pc.count(), 2);
+ QVERIFY(rp==pc);
+ rp.setNewCount(10); // Normally only used by appendPoints for rbox processing
+ QCOMPARE(rp.newCount(), 10);
+ rp.reservePoints();
+ QVERIFY(rp==pc);
+}//t_getSet
+
+void RboxPoints_test::
+t_foreach()
+{
+ RboxPoints rp("c");
+ Coordinates::ConstIterator cci= rp.beginCoordinates();
+ orgQhull::Coordinates::Iterator ci= rp.beginCoordinates();
+ QCOMPARE(*cci, -0.5);
+ QCOMPARE(*ci, *cci);
+ int i=1;
+ while(++cci<rp.endCoordinates()){
+ QVERIFY(++ci<rp.endCoordinates());
+ QCOMPARE(*cci, *ci);
+ i++;
+ }
+ QVERIFY(++ci==rp.endCoordinates());
+ QCOMPARE(i, 8*3);
+ orgQhull::Coordinates::Iterator ci4= rp.beginCoordinates(4);
+ QCOMPARE(rp.endCoordinates()-ci4, 4*3);
+ orgQhull::Coordinates::ConstIterator cci4= rp.beginCoordinates(4);
+ orgQhull::Coordinates::ConstIterator cci5= rp.endCoordinates();
+ QCOMPARE(cci5-cci4, 4*3);
+}//t_foreach
+
+void RboxPoints_test::
+t_change()
+{
+ RboxPoints rp("c D2");
+ stringstream s;
+ s << "4 count" << endl;
+ s << "2 dimension" << endl;
+ s << "1 2 3 4 5 6 7 8" << endl;
+ rp.appendPoints(s);
+ QCOMPARE(rp.count(), 8);
+ orgQhull::Coordinates::Iterator ci= rp.beginCoordinates(7);
+ QCOMPARE(*ci, 7.0);
+ try{
+ stringstream s2;
+ s2 << "4 count" << endl;
+ s2 << "2 dimension" << endl;
+ s2 << "1 2 3 4 5 6 7 " << endl;
+ rp.appendPoints(s2);
+ QFAIL("incomplete appendPoints() did not fail.");
+ }catch (const std::exception &e) {
+ cout << "INFO : Caught " << e.what();
+ }
+ RboxPoints rp2;
+ rp2.append(rp);
+ QCOMPARE(rp2.count(), 8);
+ orgQhull::Coordinates::ConstIterator cci2= rp2.beginCoordinates(6);
+ QCOMPARE(*(cci2+1), 6.0);
+ rp2.appendPoints("D2 10 P0");
+ QCOMPARE(rp2.count(), 19);
+ orgQhull::Coordinates::ConstIterator cie= rp2.beginCoordinates(8);
+ QCOMPARE(*cie, 0.0);
+ RboxPoints rp3;
+ coordT points[] = { 0, 1,1,0,1,1,0,0};
+ rp3.setDimension(2);
+ rp3.append(8,points);
+ QCOMPARE(rp3.count(), 4);
+ orgQhull::Coordinates::Iterator ci3= rp3.beginCoordinates(3);
+ QCOMPARE(*ci3, 0.0);
+}//t_change
+
+void RboxPoints_test::
+t_ostream()
+{
+ RboxPoints rp("c D2");
+ ostringstream oss;
+ oss << rp;
+ string s= oss.str();
+ QString qs= QString::fromStdString(s);
+ QCOMPARE(qs.count("-0.5"), 4);
+}//t_ostream
+
+}//orgQhull
+
+#include "moc/RboxPoints_test.moc"
diff --git a/xs/src/qhull/src/qhulltest/RoadTest.cpp b/xs/src/qhull/src/qhulltest/RoadTest.cpp
new file mode 100644
index 000000000..05c87f3de
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/RoadTest.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/RoadTest.cpp#2 $$Change: 2062 $
+** $Date: 2016/01/17 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include <iostream>
+#include "RoadTest.h" // QT_VERSION
+
+#include <stdexcept>
+
+using std::cout;
+using std::endl;
+
+namespace orgQhull {
+
+#//!\name class variable
+
+QList<RoadTest*> RoadTest::
+s_testcases;
+
+int RoadTest::
+s_test_count= 0;
+
+int RoadTest::
+s_test_fail= 0;
+
+QStringList RoadTest::
+s_failed_tests;
+
+#//!\name Slot
+
+//! Executed after each test
+void RoadTest::
+cleanup()
+{
+ s_test_count++;
+ if(QTest::currentTestFailed()){
+ recordFailedTest();
+ }
+}//cleanup
+
+#//!\name Helper
+
+void RoadTest::
+recordFailedTest()
+{
+ s_test_fail++;
+ QString className= metaObject()->className();
+ s_failed_tests << className + "::" + QTest::currentTestFunction();
+}
+
+#//!\name class function
+
+void RoadTest::
+deleteTests()
+{
+ foreach(RoadTest *testcase, s_testcases){
+ delete testcase;
+ }
+ s_failed_tests.clear();
+}
+
+int RoadTest::
+runTests(QStringList arguments)
+{
+ int result= 0; // assume success
+
+ foreach(RoadTest *testcase, s_testcases){
+ try{
+ result += QTest::qExec(testcase, arguments);
+ }catch(const std::exception &e){
+ cout << "FAIL! : Threw error ";
+ cout << e.what() << endl;
+ s_test_count++;
+ testcase->recordFailedTest();
+ // Qt 4.5.2 OK. In Qt 4.3.3, qtestcase did not clear currentTestObject
+ }
+ }
+ if(s_test_fail){
+ cout << "Failed " << s_test_fail << " of " << s_test_count << " tests.\n";
+ cout << s_failed_tests.join("\n").toLocal8Bit().constData() << std::endl;
+ }else{
+ cout << "Passed " << s_test_count << " tests.\n";
+ }
+ return result;
+}//runTests
+
+}//orgQhull
+
+#include "moc/moc_RoadTest.cpp"
diff --git a/xs/src/qhull/src/qhulltest/RoadTest.h b/xs/src/qhull/src/qhulltest/RoadTest.h
new file mode 100644
index 000000000..adfe0bf8c
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/RoadTest.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/RoadTest.h#2 $$Change: 2062 $
+** $Date: 2016/01/17 $$Author: bbarber $
+**
+****************************************************************************/
+
+#ifndef ROADTEST_H
+#define ROADTEST_H
+
+//pre-compiled with RoadTest.h
+#include <QObject> // Qt C++ Framework
+#include <QtTest/QtTest>
+
+#define QHULL_USES_QT 1
+
+namespace orgQhull {
+
+#//!\name Defined here
+
+ //! RoadTest -- Generic test for Qt's QTest
+ class RoadTest;
+ //! TESTadd_(t) -- Add a RoadTest
+
+/** Test Name objects using Qt's QTestLib
+
+Template:
+
+class Name_test : public RoadTest
+{
+ Q_OBJECT
+#//!\name Test slot
+private slots:
+ void t_name();
+ //Executed before any test
+ void initTestCase();
+ void init(); // Each test
+ //Executed after each test
+ void cleanup(); //RoadTest::cleanup();
+ // Executed after last test
+ void cleanupTestCase();
+};
+
+void
+add_Name_test()
+{
+ new Name_test(); // RoadTest::s_testcases
+}
+
+Send additional output to cout
+*/
+
+class RoadTest : public QObject
+{
+ Q_OBJECT
+
+#//!\name Class globals
+protected:
+ static QList<RoadTest *>
+ s_testcases; ///! List of testcases to execute. Initialized via add_...()
+ static int s_test_count; ///! Total number of tests executed
+ static int s_test_fail; ///! Number of failed tests
+ static QStringList s_failed_tests; ///! List of failed tests
+
+#//!\name Test slots
+public slots:
+ void cleanup();
+
+public:
+#//!\name Constructors, etc.
+ RoadTest() { s_testcases.append(this); }
+ virtual ~RoadTest() {} // Derived from QObject
+
+#//!\name Helper
+ void recordFailedTest();
+
+
+#//!\name Class functions
+ static void deleteTests();
+ static int runTests(QStringList arguments);
+
+};//RoadTest
+
+#define TESTadd_(t) extern void t(); t();
+
+
+}//orgQhull
+
+namespace QTest{
+
+template<>
+inline char *
+toString(const std::string &s)
+{
+ return qstrdup(s.c_str());
+}
+
+}//namespace QTest
+
+#endif //ROADTEST_H
+
diff --git a/xs/src/qhull/src/qhulltest/qhulltest.cpp b/xs/src/qhull/src/qhulltest/qhulltest.cpp
new file mode 100644
index 000000000..5bfe16e9c
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/qhulltest.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
+** $Id: //main/2015/qhull/src/qhulltest/qhulltest.cpp#5 $$Change: 2079 $
+** $DateTime: 2016/02/07 17:43:34 $$Author: bbarber $
+**
+****************************************************************************/
+
+//pre-compiled headers
+#include "libqhull_r/user_r.h"
+
+#include <iostream>
+#include "RoadTest.h" // QT_VERSION
+
+#include "libqhullcpp/RoadError.h"
+#include "libqhull_r/qhull_ra.h"
+
+#include <sstream>
+#include <stdexcept>
+#include <string>
+
+using std::cout;
+using std::endl;
+
+namespace orgQhull {
+
+void addQhullTests(QStringList &args)
+{
+ TESTadd_(add_Qhull_test);
+
+ if(args.contains("--all")){
+ args.removeAll("--all");
+ // up-to-date
+ TESTadd_(add_Coordinates_test);
+ TESTadd_(add_PointCoordinates_test);
+ TESTadd_(add_QhullFacet_test);
+ TESTadd_(add_QhullFacetList_test);
+ TESTadd_(add_QhullFacetSet_test);
+ TESTadd_(add_QhullHyperplane_test);
+ TESTadd_(add_QhullLinkedList_test);
+ TESTadd_(add_QhullPoint_test);
+ TESTadd_(add_QhullPoints_test);
+ TESTadd_(add_QhullPointSet_test);
+ TESTadd_(add_QhullRidge_test);
+ TESTadd_(add_QhullSet_test);
+ TESTadd_(add_QhullVertex_test);
+ TESTadd_(add_QhullVertexSet_test);
+ TESTadd_(add_RboxPoints_test);
+ // qhullStat
+ TESTadd_(add_Qhull_test);
+ }//--all
+}//addQhullTests
+
+int main(int argc, char *argv[])
+{
+
+ QCoreApplication app(argc, argv);
+ QStringList args= app.arguments();
+ bool isAll= args.contains("--all");
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ addQhullTests(args);
+ int status=1010;
+ try{
+ status= RoadTest::runTests(args);
+ }catch(const std::exception &e){
+ cout << "FAIL! : runTests() did not catch error\n";
+ cout << e.what() << endl;
+ if(!RoadError::emptyGlobalLog()){
+ cout << RoadError::stringGlobalLog() << endl;
+ RoadError::clearGlobalLog();
+ }
+ }
+ if(!RoadError::emptyGlobalLog()){
+ cout << RoadError::stringGlobalLog() << endl;
+ RoadError::clearGlobalLog();
+ }
+ if(isAll){
+ cout << "Finished test of libqhullcpp. Test libqhull_r with eg/q_test after building libqhull_r/Makefile" << endl;
+ }else{
+ cout << "Finished test of one class. Test all classes with 'qhulltest --all'" << endl;
+ }
+ RoadTest::deleteTests();
+ return status;
+}
+
+}//orgQhull
+
+int main(int argc, char *argv[])
+{
+ return orgQhull::main(argc, argv); // Needs RoadTest:: for TESTadd_() linkage
+}
+
diff --git a/xs/src/qhull/src/qhulltest/qhulltest.pro b/xs/src/qhull/src/qhulltest/qhulltest.pro
new file mode 100644
index 000000000..0da34d375
--- /dev/null
+++ b/xs/src/qhull/src/qhulltest/qhulltest.pro
@@ -0,0 +1,36 @@
+# -------------------------------------------------
+# qhulltest.pro -- Qt project for qhulltest.exe (QTestLib)
+# cd $qh/build/qhulltest && qmake -tp vc -r ../../src/qhulltest/qhulltest.pro
+# -------------------------------------------------
+
+include(../qhull-app-cpp.pri)
+
+TARGET = qhulltest
+QT += testlib
+MOC_DIR = moc
+INCLUDEPATH += .. # for MOC_DIR
+
+PRECOMPILED_HEADER = RoadTest.h
+
+HEADERS += RoadTest.h
+
+SOURCES += ../libqhullcpp/qt-qhull.cpp
+SOURCES += Coordinates_test.cpp
+SOURCES += PointCoordinates_test.cpp
+SOURCES += Qhull_test.cpp
+SOURCES += QhullFacet_test.cpp
+SOURCES += QhullFacetList_test.cpp
+SOURCES += QhullFacetSet_test.cpp
+SOURCES += QhullHyperplane_test.cpp
+SOURCES += QhullLinkedList_test.cpp
+SOURCES += QhullPoint_test.cpp
+SOURCES += QhullPoints_test.cpp
+SOURCES += QhullPointSet_test.cpp
+SOURCES += QhullRidge_test.cpp
+SOURCES += QhullSet_test.cpp
+SOURCES += qhulltest.cpp
+SOURCES += QhullVertex_test.cpp
+SOURCES += QhullVertexSet_test.cpp
+SOURCES += RboxPoints_test.cpp
+SOURCES += RoadTest.cpp
+
diff --git a/xs/src/qhull/src/qvoronoi/qvoronoi.c b/xs/src/qhull/src/qvoronoi/qvoronoi.c
new file mode 100644
index 000000000..b93d23711
--- /dev/null
+++ b/xs/src/qhull/src/qvoronoi/qvoronoi.c
@@ -0,0 +1,303 @@
+/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qvoronoi.c
+ compute Voronoi diagrams and furthest-point Voronoi
+ diagrams using qhull
+
+ see unix.c for full interface
+
+ Copyright (c) 1993-2015, The Geometry Center
+*/
+
+#include "libqhull/libqhull.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#if __cplusplus
+extern "C" {
+ int isatty(int);
+}
+
+#elif _MSC_VER
+#include <io.h>
+#define isatty _isatty
+/* int _isatty(int); */
+
+#else
+int isatty(int); /* returns 1 if stdin is a tty
+ if "Undefined symbol" this can be deleted along with call in main() */
+#endif
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt">-</a>
+
+ qh_prompt
+ long prompt for qhull
+
+ notes:
+ restricted version of libqhull.c
+
+ see:
+ concise prompt below
+*/
+
+/* duplicated in qvoron_f.htm and qvoronoi.htm
+ QJ and Qt are deprecated, but allowed for backwards compatibility
+*/
+char hidden_options[]=" d n m v H U Qb QB Qc Qf Qg Qi Qm Qr QR Qv Qx TR E V Fa FA FC Fp FS Ft FV Pv Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
+
+char qh_prompta[]= "\n\
+qvoronoi- compute the Voronoi diagram\n\
+ http://www.qhull.org %s\n\
+\n\
+input (stdin):\n\
+ first lines: dimension and number of points (or vice-versa).\n\
+ other lines: point coordinates, best if one point per line\n\
+ comments: start with a non-numeric character\n\
+\n\
+options:\n\
+ Qu - compute furthest-site Voronoi diagram\n\
+\n\
+Qhull control options:\n\
+ Qz - add point-at-infinity to Voronoi diagram\n\
+%s%s%s%s"; /* split up qh_prompt for Visual C++ */
+char qh_promptb[]= "\
+ Qs - search all points for the initial simplex\n\
+ QGn - Voronoi vertices if visible from point n, -n if not\n\
+ QVn - Voronoi vertices for input point n, -n if not\n\
+\n\
+";
+char qh_promptc[]= "\
+Trace options:\n\
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
+ Tc - check frequently during execution\n\
+ Ts - statistics\n\
+ Tv - verify result: structure, convexity, and in-circle test\n\
+ Tz - send all output to stdout\n\
+ TFn - report summary when n or more facets created\n\
+ TI file - input data from file, no spaces or single quotes\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+ TPn - turn on tracing when point n added to hull\n\
+ TMn - turn on tracing at merge n\n\
+ TWn - trace merge facets when width > n\n\
+ TVn - stop qhull after adding point n, -n for before (see TCn)\n\
+ TCn - stop qhull after building cone for point n (see TVn)\n\
+\n\
+Precision options:\n\
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex\n\
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex\n\
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
+ Rn - randomly perturb computations by a factor of [1-n,1+n]\n\
+ Wn - min facet width for non-coincident point (before roundoff)\n\
+\n\
+Output formats (may be combined; if none, produces a summary to stdout):\n\
+ s - summary to stderr\n\
+ p - Voronoi vertices\n\
+ o - OFF format (dim, Voronoi vertices, and Voronoi regions)\n\
+ i - Delaunay regions (use 'Pp' to avoid warning)\n\
+ f - facet dump\n\
+\n\
+";
+char qh_promptd[]= "\
+More formats:\n\
+ Fc - count plus coincident points (by Voronoi vertex)\n\
+ Fd - use cdd format for input (homogeneous with offset first)\n\
+ FD - use cdd format for output (offset first)\n\
+ FF - facet dump without ridges\n\
+ Fi - separating hyperplanes for bounded Voronoi regions\n\
+ FI - ID for each Voronoi vertex\n\
+ Fm - merge count for each Voronoi vertex (511 max)\n\
+ Fn - count plus neighboring Voronoi vertices for each Voronoi vertex\n\
+ FN - count and Voronoi vertices for each Voronoi region\n\
+ Fo - separating hyperplanes for unbounded Voronoi regions\n\
+ FO - options and precision constants\n\
+ FP - nearest point and distance for each coincident point\n\
+ FQ - command used for qvoronoi\n\
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
+ for output: #Voronoi regions, #Voronoi vertices,\n\
+ #coincident points, #non-simplicial regions\n\
+ #real (2), max outer plane and min vertex\n\
+ Fv - Voronoi diagram as Voronoi vertices between adjacent input sites\n\
+ Fx - extreme points of Delaunay triangulation (on convex hull)\n\
+\n\
+";
+char qh_prompte[]= "\
+Geomview options (2-d only)\n\
+ Ga - all points as dots\n\
+ Gp - coplanar points and vertices as radii\n\
+ Gv - vertices as spheres\n\
+ Gi - inner planes only\n\
+ Gn - no planes\n\
+ Go - outer planes only\n\
+ Gc - centrums\n\
+ Gh - hyperplane intersections\n\
+ Gr - ridges\n\
+ GDn - drop dimension n in 3-d and 4-d output\n\
+\n\
+Print options:\n\
+ PAn - keep n largest Voronoi vertices by 'area'\n\
+ Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
+ PDk:n - drop facet if normal[k] >= n\n\
+ Pg - print good Voronoi vertices (needs 'QGn' or 'QVn')\n\
+ PFn - keep Voronoi vertices whose 'area' is at least n\n\
+ PG - print neighbors of good Voronoi vertices\n\
+ PMn - keep n Voronoi vertices with most merges\n\
+ Po - force output. If error, output neighborhood of facet\n\
+ Pp - do not report precision problems\n\
+\n\
+ . - list of all options\n\
+ - - one line descriptions of all options\n\
+ -V - version\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt2">-</a>
+
+ qh_prompt2
+ synopsis for qhull
+*/
+char qh_prompt2[]= "\n\
+qvoronoi- compute the Voronoi diagram. Qhull %s\n\
+ input (stdin): dimension, number of points, point coordinates\n\
+ comments start with a non-numeric character\n\
+\n\
+options (qvoronoi.htm):\n\
+ Qu - compute furthest-site Voronoi diagram\n\
+ Tv - verify result: structure, convexity, and in-circle test\n\
+ . - concise list of all options\n\
+ - - one-line description of all options\n\
+ -V - version\n\
+\n\
+output options (subset):\n\
+ s - summary of results (default)\n\
+ p - Voronoi vertices\n\
+ o - OFF file format (dim, Voronoi vertices, and Voronoi regions)\n\
+ FN - count and Voronoi vertices for each Voronoi region\n\
+ Fv - Voronoi diagram as Voronoi vertices between adjacent input sites\n\
+ Fi - separating hyperplanes for bounded regions, 'Fo' for unbounded\n\
+ G - Geomview output (2-d only)\n\
+ QVn - Voronoi vertices for input point n, -n if not\n\
+ TO file- output results to file, may be enclosed in single quotes\n\
+\n\
+examples:\n\
+rbox c P0 D2 | qvoronoi s o rbox c P0 D2 | qvoronoi Fi\n\
+rbox c P0 D2 | qvoronoi Fo rbox c P0 D2 | qvoronoi Fv\n\
+rbox c P0 D2 | qvoronoi s Qu Fv rbox c P0 D2 | qvoronoi Qu Fo\n\
+rbox c G1 d D2 | qvoronoi s p rbox c P0 D2 | qvoronoi s Fv QV0\n\
+\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt3">-</a>
+
+ qh_prompt3
+ concise prompt for qhull
+*/
+char qh_prompt3[]= "\n\
+Qhull %s.\n\
+Except for 'F.' and 'PG', upper-case options take an argument.\n\
+\n\
+ OFF_format p_vertices i_delaunay summary facet_dump\n\
+\n\
+ Fcoincident Fd_cdd_in FD_cdd_out FF-dump-xridge Fi_bounded\n\
+ Fxtremes Fmerges Fneighbors FNeigh_region FOptions\n\
+ Fo_unbounded FPoint_near FQvoronoi Fsummary Fvoronoi\n\
+ FIDs\n\
+\n\
+ Gvertices Gpoints Gall_points Gno_planes Ginner\n\
+ Gcentrums Ghyperplanes Gridges Gouter GDrop_dim\n\
+\n\
+ PArea_keep Pdrop d0:0D0 Pgood PFacet_area_keep\n\
+ PGood_neighbors PMerge_keep Poutput_forced Pprecision_not\n\
+\n\
+ QG_vertex_good Qsearch_1st Qupper_voronoi QV_point_good Qzinfinite\n\
+ T4_trace Tcheck_often Tstatistics Tverify Tz_stdout\n\
+ TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file\n\
+ TWide_trace TVertex_stop TCone_stop\n\
+\n\
+ Angle_max Centrum_size Random_dist Wide_outside\n\
+";
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="main">-</a>
+
+ main( argc, argv )
+ processes the command line, calls qhull() to do the work, and exits
+
+ design:
+ initializes data structures
+ reads points
+ finishes initialization
+ computes convex hull and other structures
+ checks the result
+ writes the output
+ frees memory
+*/
+int main(int argc, char *argv[]) {
+ int curlong, totlong; /* used !qh_NOmem */
+ int exitcode, numpoints, dim;
+ coordT *points;
+ boolT ismalloc;
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ if ((argc == 1) && isatty( 0 /*stdin*/)) {
+ fprintf(stdout, qh_prompt2, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompta, qh_version,
+ qh_promptb, qh_promptc, qh_promptd, qh_prompte);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '.' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompt3, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
+ fprintf(stdout, "%s\n", qh_version2);
+ exit(qh_ERRnone);
+ }
+ qh_init_A(stdin, stdout, stderr, argc, argv); /* sets qh qhull_command */
+ exitcode= setjmp(qh errexit); /* simple statement for CRAY J916 */
+ if (!exitcode) {
+ qh NOerrexit= False;
+ qh_option("voronoi _bbound-last _coplanar-keep", NULL, NULL);
+ qh DELAUNAY= True; /* 'v' */
+ qh VORONOI= True;
+ qh SCALElast= True; /* 'Qbb' */
+ qh_checkflags(qh qhull_command, hidden_options);
+ qh_initflags(qh qhull_command);
+ points= qh_readpoints(&numpoints, &dim, &ismalloc);
+ if (dim >= 5) {
+ qh_option("_merge-exact", NULL, NULL);
+ qh MERGEexact= True; /* 'Qx' always */
+ }
+ qh_init_B(points, numpoints, dim, ismalloc);
+ qh_qhull();
+ qh_check_output();
+ qh_produce_output();
+ if (qh VERIFYoutput && !qh FORCEoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ exitcode= qh_ERRnone;
+ }
+ qh NOerrexit= True; /* no more setjmp */
+#ifdef qh_NOmem
+ qh_freeqhull(qh_ALL);
+#else
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
+ totlong, curlong);
+#endif
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/qvoronoi/qvoronoi.pro b/xs/src/qhull/src/qvoronoi/qvoronoi.pro
new file mode 100644
index 000000000..4646c8447
--- /dev/null
+++ b/xs/src/qhull/src/qvoronoi/qvoronoi.pro
@@ -0,0 +1,9 @@
+# -------------------------------------------------
+# qvoronoi.pro -- Qt project file for qvoronoi.exe
+# -------------------------------------------------
+
+include(../qhull-app-c.pri)
+
+TARGET = qvoronoi
+
+SOURCES += qvoronoi.c
diff --git a/xs/src/qhull/src/qvoronoi/qvoronoi_r.c b/xs/src/qhull/src/qvoronoi/qvoronoi_r.c
new file mode 100644
index 000000000..6323c8b49
--- /dev/null
+++ b/xs/src/qhull/src/qvoronoi/qvoronoi_r.c
@@ -0,0 +1,305 @@
+/*<html><pre> -<a href="../libqhull/qh-qhull.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ qvoronoi.c
+ compute Voronoi diagrams and furthest-point Voronoi
+ diagrams using qhull
+
+ see unix.c for full interface
+
+ Copyright (c) 1993-2015, The Geometry Center
+*/
+
+#include "libqhull_r/libqhull_r.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#if __cplusplus
+extern "C" {
+ int isatty(int);
+}
+
+#elif _MSC_VER
+#include <io.h>
+#define isatty _isatty
+/* int _isatty(int); */
+
+#else
+int isatty(int); /* returns 1 if stdin is a tty
+ if "Undefined symbol" this can be deleted along with call in main() */
+#endif
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt">-</a>
+
+ qh_prompt
+ long prompt for qhull
+
+ notes:
+ restricted version of libqhull.c
+
+ see:
+ concise prompt below
+*/
+
+/* duplicated in qvoron_f.htm and qvoronoi.htm
+ QJ and Qt are deprecated, but allowed for backwards compatibility
+*/
+char hidden_options[]=" d n m v H U Qb QB Qc Qf Qg Qi Qm Qr QR Qv Qx TR E V Fa FA FC Fp FS Ft FV Pv Gt Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 ";
+
+char qh_prompta[]= "\n\
+qvoronoi- compute the Voronoi diagram\n\
+ http://www.qhull.org %s\n\
+\n\
+input (stdin):\n\
+ first lines: dimension and number of points (or vice-versa).\n\
+ other lines: point coordinates, best if one point per line\n\
+ comments: start with a non-numeric character\n\
+\n\
+options:\n\
+ Qu - compute furthest-site Voronoi diagram\n\
+\n\
+Qhull control options:\n\
+ Qz - add point-at-infinity to Voronoi diagram\n\
+%s%s%s%s"; /* split up qh_prompt for Visual C++ */
+char qh_promptb[]= "\
+ Qs - search all points for the initial simplex\n\
+ QGn - Voronoi vertices if visible from point n, -n if not\n\
+ QVn - Voronoi vertices for input point n, -n if not\n\
+\n\
+";
+char qh_promptc[]= "\
+Trace options:\n\
+ T4 - trace at level n, 4=all, 5=mem/gauss, -1= events\n\
+ Tc - check frequently during execution\n\
+ Ts - statistics\n\
+ Tv - verify result: structure, convexity, and in-circle test\n\
+ Tz - send all output to stdout\n\
+ TFn - report summary when n or more facets created\n\
+ TI file - input data from file, no spaces or single quotes\n\
+ TO file - output results to file, may be enclosed in single quotes\n\
+ TPn - turn on tracing when point n added to hull\n\
+ TMn - turn on tracing at merge n\n\
+ TWn - trace merge facets when width > n\n\
+ TVn - stop qhull after adding point n, -n for before (see TCn)\n\
+ TCn - stop qhull after building cone for point n (see TVn)\n\
+\n\
+Precision options:\n\
+ Cn - radius of centrum (roundoff added). Merge facets if non-convex\n\
+ An - cosine of maximum angle. Merge facets if cosine > n or non-convex\n\
+ C-0 roundoff, A-0.99/C-0.01 pre-merge, A0.99/C0.01 post-merge\n\
+ Rn - randomly perturb computations by a factor of [1-n,1+n]\n\
+ Wn - min facet width for non-coincident point (before roundoff)\n\
+\n\
+Output formats (may be combined; if none, produces a summary to stdout):\n\
+ s - summary to stderr\n\
+ p - Voronoi vertices\n\
+ o - OFF format (dim, Voronoi vertices, and Voronoi regions)\n\
+ i - Delaunay regions (use 'Pp' to avoid warning)\n\
+ f - facet dump\n\
+\n\
+";
+char qh_promptd[]= "\
+More formats:\n\
+ Fc - count plus coincident points (by Voronoi vertex)\n\
+ Fd - use cdd format for input (homogeneous with offset first)\n\
+ FD - use cdd format for output (offset first)\n\
+ FF - facet dump without ridges\n\
+ Fi - separating hyperplanes for bounded Voronoi regions\n\
+ FI - ID for each Voronoi vertex\n\
+ Fm - merge count for each Voronoi vertex (511 max)\n\
+ Fn - count plus neighboring Voronoi vertices for each Voronoi vertex\n\
+ FN - count and Voronoi vertices for each Voronoi region\n\
+ Fo - separating hyperplanes for unbounded Voronoi regions\n\
+ FO - options and precision constants\n\
+ FP - nearest point and distance for each coincident point\n\
+ FQ - command used for qvoronoi\n\
+ Fs - summary: #int (8), dimension, #points, tot vertices, tot facets,\n\
+ for output: #Voronoi regions, #Voronoi vertices,\n\
+ #coincident points, #non-simplicial regions\n\
+ #real (2), max outer plane and min vertex\n\
+ Fv - Voronoi diagram as Voronoi vertices between adjacent input sites\n\
+ Fx - extreme points of Delaunay triangulation (on convex hull)\n\
+\n\
+";
+char qh_prompte[]= "\
+Geomview options (2-d only)\n\
+ Ga - all points as dots\n\
+ Gp - coplanar points and vertices as radii\n\
+ Gv - vertices as spheres\n\
+ Gi - inner planes only\n\
+ Gn - no planes\n\
+ Go - outer planes only\n\
+ Gc - centrums\n\
+ Gh - hyperplane intersections\n\
+ Gr - ridges\n\
+ GDn - drop dimension n in 3-d and 4-d output\n\
+\n\
+Print options:\n\
+ PAn - keep n largest Voronoi vertices by 'area'\n\
+ Pdk:n - drop facet if normal[k] <= n (default 0.0)\n\
+ PDk:n - drop facet if normal[k] >= n\n\
+ Pg - print good Voronoi vertices (needs 'QGn' or 'QVn')\n\
+ PFn - keep Voronoi vertices whose 'area' is at least n\n\
+ PG - print neighbors of good Voronoi vertices\n\
+ PMn - keep n Voronoi vertices with most merges\n\
+ Po - force output. If error, output neighborhood of facet\n\
+ Pp - do not report precision problems\n\
+\n\
+ . - list of all options\n\
+ - - one line descriptions of all options\n\
+ -V - version\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt2">-</a>
+
+ qh_prompt2
+ synopsis for qhull
+*/
+char qh_prompt2[]= "\n\
+qvoronoi- compute the Voronoi diagram. Qhull %s\n\
+ input (stdin): dimension, number of points, point coordinates\n\
+ comments start with a non-numeric character\n\
+\n\
+options (qvoronoi.htm):\n\
+ Qu - compute furthest-site Voronoi diagram\n\
+ Tv - verify result: structure, convexity, and in-circle test\n\
+ . - concise list of all options\n\
+ - - one-line description of all options\n\
+ -V - version\n\
+\n\
+output options (subset):\n\
+ s - summary of results (default)\n\
+ p - Voronoi vertices\n\
+ o - OFF file format (dim, Voronoi vertices, and Voronoi regions)\n\
+ FN - count and Voronoi vertices for each Voronoi region\n\
+ Fv - Voronoi diagram as Voronoi vertices between adjacent input sites\n\
+ Fi - separating hyperplanes for bounded regions, 'Fo' for unbounded\n\
+ G - Geomview output (2-d only)\n\
+ QVn - Voronoi vertices for input point n, -n if not\n\
+ TO file- output results to file, may be enclosed in single quotes\n\
+\n\
+examples:\n\
+rbox c P0 D2 | qvoronoi s o rbox c P0 D2 | qvoronoi Fi\n\
+rbox c P0 D2 | qvoronoi Fo rbox c P0 D2 | qvoronoi Fv\n\
+rbox c P0 D2 | qvoronoi s Qu Fv rbox c P0 D2 | qvoronoi Qu Fo\n\
+rbox c G1 d D2 | qvoronoi s p rbox c P0 D2 | qvoronoi s Fv QV0\n\
+\n\
+";
+/* for opts, don't assign 'e' or 'E' to a flag (already used for exponent) */
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="prompt3">-</a>
+
+ qh_prompt3
+ concise prompt for qhull
+*/
+char qh_prompt3[]= "\n\
+Qhull %s.\n\
+Except for 'F.' and 'PG', upper-case options take an argument.\n\
+\n\
+ OFF_format p_vertices i_delaunay summary facet_dump\n\
+\n\
+ Fcoincident Fd_cdd_in FD_cdd_out FF-dump-xridge Fi_bounded\n\
+ Fxtremes Fmerges Fneighbors FNeigh_region FOptions\n\
+ Fo_unbounded FPoint_near FQvoronoi Fsummary Fvoronoi\n\
+ FIDs\n\
+\n\
+ Gvertices Gpoints Gall_points Gno_planes Ginner\n\
+ Gcentrums Ghyperplanes Gridges Gouter GDrop_dim\n\
+\n\
+ PArea_keep Pdrop d0:0D0 Pgood PFacet_area_keep\n\
+ PGood_neighbors PMerge_keep Poutput_forced Pprecision_not\n\
+\n\
+ QG_vertex_good Qsearch_1st Qupper_voronoi QV_point_good Qzinfinite\n\
+ T4_trace Tcheck_often Tstatistics Tverify Tz_stdout\n\
+ TFacet_log TInput_file TPoint_trace TMerge_trace TOutput_file\n\
+ TWide_trace TVertex_stop TCone_stop\n\
+\n\
+ Angle_max Centrum_size Random_dist Wide_outside\n\
+";
+
+/*-<a href="../libqhull/qh-qhull.htm#TOC"
+ >-------------------------------</a><a name="main">-</a>
+
+ main( argc, argv )
+ processes the command line, calls qhull() to do the work, and exits
+
+ design:
+ initializes data structures
+ reads points
+ finishes initialization
+ computes convex hull and other structures
+ checks the result
+ writes the output
+ frees memory
+*/
+int main(int argc, char *argv[]) {
+ int curlong, totlong; /* used !qh_NOmem */
+ int exitcode, numpoints, dim;
+ coordT *points;
+ boolT ismalloc;
+ qhT qh_qh;
+ qhT *qh= &qh_qh;
+
+ QHULL_LIB_CHECK /* Check for compatible library */
+
+ if ((argc == 1) && isatty( 0 /*stdin*/)) {
+ fprintf(stdout, qh_prompt2, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompta, qh_version,
+ qh_promptb, qh_promptc, qh_promptd, qh_prompte);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '.' && !*(argv[1]+1)) {
+ fprintf(stdout, qh_prompt3, qh_version);
+ exit(qh_ERRnone);
+ }
+ if (argc > 1 && *argv[1] == '-' && *(argv[1]+1)=='V') {
+ fprintf(stdout, "%s\n", qh_version2);
+ exit(qh_ERRnone);
+ }
+ qh_init_A(qh, stdin, stdout, stderr, argc, argv); /* sets qh->qhull_command */
+ exitcode= setjmp(qh->errexit); /* simple statement for CRAY J916 */
+ if (!exitcode) {
+ qh->NOerrexit = False;
+ qh_option(qh, "voronoi _bbound-last _coplanar-keep", NULL, NULL);
+ qh->DELAUNAY= True; /* 'v' */
+ qh->VORONOI= True;
+ qh->SCALElast= True; /* 'Qbb' */
+ qh_checkflags(qh, qh->qhull_command, hidden_options);
+ qh_initflags(qh, qh->qhull_command);
+ points= qh_readpoints(qh, &numpoints, &dim, &ismalloc);
+ if (dim >= 5) {
+ qh_option(qh, "_merge-exact", NULL, NULL);
+ qh->MERGEexact= True; /* 'Qx' always */
+ }
+ qh_init_B(qh, points, numpoints, dim, ismalloc);
+ qh_qhull(qh);
+ qh_check_output(qh);
+ qh_produce_output(qh);
+ if (qh->VERIFYoutput && !qh->FORCEoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ exitcode= qh_ERRnone;
+ }
+ qh->NOerrexit= True; /* no more setjmp */
+#ifdef qh_NOmem
+ qh_freeqhull(qh, qh_ALL);
+#else
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
+ if (curlong || totlong)
+ qh_fprintf_stderr(6263, "qhull internal warning (main): did not free %d bytes of long memory(%d pieces)\n",
+ totlong, curlong);
+#endif
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/rbox/rbox.c b/xs/src/qhull/src/rbox/rbox.c
new file mode 100644
index 000000000..d7c51b1aa
--- /dev/null
+++ b/xs/src/qhull/src/rbox/rbox.c
@@ -0,0 +1,88 @@
+/*<html><pre> -<a href="../libqhull/index.htm#TOC"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ rbox.c
+ rbox program for generating input points for qhull.
+
+ notes:
+ 50 points generated for 'rbox D4'
+
+*/
+
+#include "libqhull/libqhull.h"
+#include "libqhull/random.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
+#pragma warning( disable : 4706) /* assignment within conditional function */
+#endif
+
+char prompt[]= "\n\
+-rbox- generate various point distributions. Default is random in cube.\n\
+\n\
+args (any order, space separated): Version: 2016/01/18\n\
+ 3000 number of random points in cube, lens, spiral, sphere or grid\n\
+ D3 dimension 3-d\n\
+ c add a unit cube to the output ('c G2.0' sets size)\n\
+ d add a unit diamond to the output ('d G2.0' sets size)\n\
+ l generate a regular 3-d spiral\n\
+ r generate a regular polygon, ('r s Z1 G0.1' makes a cone)\n\
+ s generate cospherical points\n\
+ x generate random points in simplex, may use 'r' or 'Wn'\n\
+ y same as 'x', plus simplex\n\
+ Cn,r,m add n nearly coincident points within radius r of m points\n\
+ Pn,m,r add point [n,m,r] first, pads with 0, maybe repeated\n\
+\n\
+ Ln lens distribution of radius n. Also 's', 'r', 'G', 'W'.\n\
+ Mn,m,r lattice(Mesh) rotated by [n,-m,0], [m,n,0], [0,0,r], ...\n\
+ '27 M1,0,1' is {0,1,2} x {0,1,2} x {0,1,2}. Try 'M3,4 z'.\n\
+ W0.1 random distribution within 0.1 of the cube's or sphere's surface\n\
+ Z0.5 s random points in a 0.5 disk projected to a sphere\n\
+ Z0.5 s G0.6 same as Z0.5 within a 0.6 gap\n\
+\n\
+ Bn bounding box coordinates, default %2.2g\n\
+ h output as homogeneous coordinates for cdd\n\
+ n remove command line from the first line of output\n\
+ On offset coordinates by n\n\
+ t use time as the random number seed(default is command line)\n\
+ tn use n as the random number seed\n\
+ z print integer coordinates, default 'Bn' is %2.2g\n\
+";
+
+/*--------------------------------------------
+-rbox- main procedure of rbox application
+*/
+int main(int argc, char **argv) {
+ char *command;
+ int command_size;
+ int return_status;
+
+ QHULL_LIB_CHECK_RBOX
+
+ if (argc == 1) {
+ printf(prompt, qh_DEFAULTbox, qh_DEFAULTzbox);
+ return 1;
+ }
+ if (argc == 2 && strcmp(argv[1], "D4")==0)
+ qh_fprintf_stderr(0, "\nStarting the rbox smoketest for qhull. An immediate failure indicates\nthat non-reentrant rbox was linked to reentrant routines. An immediate\nfailure of qhull may indicate that qhull was linked to the wrong\nqhull library. Also try 'rbox D4 | qhull T1'\n");
+
+ command_size= qh_argv_to_command_size(argc, argv);
+ if ((command= (char *)qh_malloc((size_t)command_size))) {
+ if (!qh_argv_to_command(argc, argv, command, command_size)) {
+ qh_fprintf_stderr(6264, "rbox internal error: allocated insufficient memory (%d) for arguments\n", command_size);
+ return_status= qh_ERRinput;
+ }else{
+ return_status= qh_rboxpoints(stdout, stderr, command);
+ }
+ qh_free(command);
+ }else {
+ qh_fprintf_stderr(6265, "rbox error: insufficient memory for %d bytes\n", command_size);
+ return_status= qh_ERRmem;
+ }
+ return return_status;
+}/*main*/
+
diff --git a/xs/src/qhull/src/rbox/rbox.pro b/xs/src/qhull/src/rbox/rbox.pro
new file mode 100644
index 000000000..6c21bdb6d
--- /dev/null
+++ b/xs/src/qhull/src/rbox/rbox.pro
@@ -0,0 +1,9 @@
+# -------------------------------------------------
+# rbox.pro -- Qt project for rbox.exe with libqhullstatic
+# -------------------------------------------------
+
+include(../qhull-app-c.pri)
+
+TARGET = rbox
+
+SOURCES += rbox.c
diff --git a/xs/src/qhull/src/rbox/rbox_r.c b/xs/src/qhull/src/rbox/rbox_r.c
new file mode 100644
index 000000000..6ec74d914
--- /dev/null
+++ b/xs/src/qhull/src/rbox/rbox_r.c
@@ -0,0 +1,78 @@
+
+/*<html><pre> -<a href="../libqhull/index.htm#TOC"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ rbox.c
+ rbox program for generating input points for qhull.
+
+ notes:
+ 50 points generated for 'rbox D4'
+
+*/
+
+#include "libqhull_r/libqhull_r.h"
+#include "libqhull/random_r.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
+#pragma warning( disable : 4706) /* assignment within conditional function */
+#endif
+
+char prompt[]= "\n\
+-rbox- generate various point distributions. Default is random in cube.\n\
+\n\
+args (any order, space separated): Version: 2016/01/18 r\n\
+ 3000 number of random points in cube, lens, spiral, sphere or grid\n\
+ D3 dimension 3-d\n\
+ c add a unit cube to the output ('c G2.0' sets size)\n\
+ d add a unit diamond to the output ('d G2.0' sets size)\n\
+ l generate a regular 3-d spiral\n\
+ r generate a regular polygon, ('r s Z1 G0.1' makes a cone)\n\
+ s generate cospherical points\n\
+ x generate random points in simplex, may use 'r' or 'Wn'\n\
+ y same as 'x', plus simplex\n\
+ Cn,r,m add n nearly coincident points within radius r of m points\n\
+ Pn,m,r add point [n,m,r] first, pads with 0, maybe repeated\n\
+\n\
+ Ln lens distribution of radius n. Also 's', 'r', 'G', 'W'.\n\
+ Mn,m,r lattice(Mesh) rotated by [n,-m,0], [m,n,0], [0,0,r], ...\n\
+ '27 M1,0,1' is {0,1,2} x {0,1,2} x {0,1,2}. Try 'M3,4 z'.\n\
+ W0.1 random distribution within 0.1 of the cube's or sphere's surface\n\
+ Z0.5 s random points in a 0.5 disk projected to a sphere\n\
+ Z0.5 s G0.6 same as Z0.5 within a 0.6 gap\n\
+\n\
+ Bn bounding box coordinates, default %2.2g\n\
+ h output as homogeneous coordinates for cdd\n\
+ n remove command line from the first line of output\n\
+ On offset coordinates by n\n\
+ t use time as the random number seed(default is command line)\n\
+ tn use n as the random number seed\n\
+ z print integer coordinates, default 'Bn' is %2.2g\n\
+";
+
+/*--------------------------------------------
+-rbox- main procedure of rbox application
+*/
+int main(int argc, char **argv) {
+ int return_status;
+ qhT qh_qh;
+ qhT *qh= &qh_qh;
+
+ QHULL_LIB_CHECK_RBOX
+
+ if (argc == 1) {
+ printf(prompt, qh_DEFAULTbox, qh_DEFAULTzbox);
+ return 1;
+ }
+ if (argc == 2 && strcmp(argv[1], "D4")==0)
+ qh_fprintf_stderr(0, "\nStarting the rbox smoketest for qhull. An immediate failure indicates\nthat reentrant rbox was linked to non-reentrant routines. An immediate\nfailure of qhull may indicate that qhull was linked to the wrong\nqhull library. Also try 'rbox D4 | qhull T1'\n");
+
+ qh_init_A(qh, stdin, stdout, stderr, argc, argv); /*no qh_errexit, sets qh->qhull_command */
+ return_status= qh_rboxpoints(qh, qh->qhull_command); /* Traps its own errors, qh_errexit_rbox() */
+ return return_status;
+}/*main*/
+
diff --git a/xs/src/qhull/src/testqset/testqset.c b/xs/src/qhull/src/testqset/testqset.c
new file mode 100644
index 000000000..61057eef9
--- /dev/null
+++ b/xs/src/qhull/src/testqset/testqset.c
@@ -0,0 +1,891 @@
+/*<html><pre> -<a href="../libqhull/index.htm#TOC"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ testset.c -- test qset.c and its use of mem.c
+
+ The test sets are pointers to int. Normally a set is a pointer to a type (e.g., facetT, ridgeT, etc.).
+ For consistency in notation, an "int" is typedef'd to i2T
+
+Functions and macros from qset.h. Counts occurrences in this test. Does not correspond to thoroughness.
+ qh_setaddsorted -- 4 tests
+ qh_setaddnth -- 1 test
+ qh_setappend -- 7 tests
+ qh_setappend_set -- 1 test
+ qh_setappend2ndlast -- 1 test
+ qh_setcheck -- lots of tests
+ qh_setcompact -- 7 tests
+ qh_setcopy -- 3 tests
+ qh_setdel -- 1 tests
+ qh_setdellast -- 1 tests
+ qh_setdelnth -- 2 tests
+ qh_setdelnthsorted -- 2 tests
+ qh_setdelsorted -- 1 test
+ qh_setduplicate -- not testable here
+ qh_setequal -- 4 tests
+ qh_setequal_except -- 2 tests
+ qh_setequal_skip -- 2 tests
+ qh_setfree -- 11+ tests
+ qh_setfree2 -- not testable here
+ qh_setfreelong -- 2 tests
+ qh_setin -- 3 tests
+ qh_setindex -- 4 tests
+ qh_setlarger -- 1 test
+ qh_setlast -- 2 tests
+ qh_setnew -- 6 tests
+ qh_setnew_delnthsorted
+ qh_setprint -- tested elsewhere
+ qh_setreplace -- 1 test
+ qh_setsize -- 9+ tests
+ qh_settemp -- 2 tests
+ qh_settempfree -- 1 test
+ qh_settempfree_all -- 1 test
+ qh_settemppop -- 1 test
+ qh_settemppush -- 1 test
+ qh_settruncate -- 3 tests
+ qh_setunique -- 3 tests
+ qh_setzero -- 1 test
+ FOREACHint_ -- 2 test
+ FOREACHint4_
+ FOREACHint_i_ -- 1 test
+ FOREACHintreverse_
+ FOREACHintreverse12_
+ FOREACHsetelement_ -- 1 test
+ FOREACHsetelement_i_ -- 1 test
+ FOREACHsetelementreverse_ -- 1 test
+ FOREACHsetelementreverse12_ -- 1 test
+ SETelem_ -- 3 tests
+ SETelemaddr_ -- 2 tests
+ SETelemt_ -- not tested (generic)
+ SETempty_ -- 1 test
+ SETfirst_ -- 4 tests
+ SETfirstt_ -- 2 tests
+ SETindex_ -- 2 tests
+ SETref_ -- 2 tests
+ SETreturnsize_ -- 2 tests
+ SETsecond_ -- 1 test
+ SETsecondt_ -- 2 tests
+ SETtruncate_ -- 2 tests
+
+ Copyright (c) 2012-2015 C.B. Barber. All rights reserved.
+ $Id: //main/2015/qhull/src/testqset/testqset.c#4 $$Change: 2062 $
+ $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
+*/
+
+#include "libqhull/user.h" /* QHULL_CRTDBG */
+#include "libqhull/qset.h"
+#include "libqhull/mem.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef int i2T;
+#define MAXerrorCount 100 /* quit after n errors */
+
+#define FOREACHint_( ints ) FOREACHsetelement_( i2T, ints, i2)
+#define FOREACHint4_( ints ) FOREACHsetelement_( i2T, ints, i4)
+#define FOREACHint_i_( ints ) FOREACHsetelement_i_( i2T, ints, i2)
+#define FOREACHintreverse_( ints ) FOREACHsetelementreverse_( i2T, ints, i2)
+#define FOREACHintreverse12_( ints ) FOREACHsetelementreverse12_( i2T, ints, i2)
+
+enum {
+ MAXint= 0x7fffffff,
+};
+
+char prompt[]= "testqset N [M] [T5] -- Test qset.c and mem.c\n\
+ \n\
+ If this test fails then qhull will not work.\n\
+ \n\
+ Test qsets of 0..N integers with a check every M iterations (default ~log10)\n\
+ Additional checking and logging if M is 1\n\
+ \n\
+ T5 turns on memory logging (qset does not log)\n\
+ \n\
+ For example:\n\
+ testqset 10000\n\
+";
+
+int error_count= 0; /* Global error_count. checkSetContents() keeps its own error count. It exits on too many errors */
+
+/* Macros normally defined in geom.h */
+#define fmax_( a,b ) ( ( a ) < ( b ) ? ( b ) : ( a ) )
+
+/* Macros normally defined in user.h */
+
+#define realT double
+#define qh_MEMalign ((int)(fmax_(sizeof(realT), sizeof(void *))))
+#define qh_MEMbufsize 0x10000 /* allocate 64K memory buffers */
+#define qh_MEMinitbuf 0x20000 /* initially allocate 128K buffer */
+
+/* Macros normally defined in QhullSet.h */
+
+
+/* Functions normally defined in user.h for usermem.c */
+
+void qh_exit(int exitcode);
+void qh_fprintf_stderr(int msgcode, const char *fmt, ... );
+void qh_free(void *mem);
+void *qh_malloc(size_t size);
+
+/* Normally defined in user.c */
+
+void qh_errexit(int exitcode, void *f, void *r)
+{
+ (void)f; /* unused */
+ (void)r; /* unused */
+ qh_exit(exitcode);
+}
+
+/* Normally defined in userprintf.c */
+
+void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... )
+{
+ static int needs_cr= 0; /* True if qh_fprintf needs a CR */
+
+ size_t fmtlen= strlen(fmt);
+ va_list args;
+
+ if (!fp) {
+ /* Do not use qh_fprintf_stderr. This is a standalone program */
+ fprintf(stderr, "QH6232 qh_fprintf: fp not defined for '%s'", fmt);
+ qh_errexit(6232, NULL, NULL);
+ }
+ if(fmtlen>0){
+ if(fmt[fmtlen-1]=='\n'){
+ if(needs_cr && fmtlen>1){
+ fprintf(fp, "\n");
+ }
+ needs_cr= 0;
+ }else{
+ needs_cr= 1;
+ }
+ }
+ if(msgcode>=6000 && msgcode<7000){
+ fprintf(fp, "Error TQ%d ", msgcode);
+ }
+ va_start(args, fmt);
+ vfprintf(fp, fmt, args);
+ va_end(args);
+}
+
+/* Defined below in order of use */
+int main(int argc, char **argv);
+void readOptions(int argc, char **argv, const char *promptstr, int *numInts, int *checkEvery, int *traceLevel);
+void setupMemory(int tracelevel, int numInts, int **intarray);
+
+void testSetappendSettruncate(int numInts, int *intarray, int checkEvery);
+void testSetdelSetadd(int numInts, int *intarray, int checkEvery);
+void testSetappendSet(int numInts, int *intarray, int checkEvery);
+void testSetcompactCopy(int numInts, int *intarray, int checkEvery);
+void testSetequalInEtc(int numInts, int *intarray, int checkEvery);
+void testSettemp(int numInts, int *intarray, int checkEvery);
+void testSetlastEtc(int numInts, int *intarray, int checkEvery);
+void testSetdelsortedEtc(int numInts, int *intarray, int checkEvery);
+
+int log_i(setT *set, const char *s, int i, int numInts, int checkEvery);
+void checkSetContents(const char *name, setT *set, int count, int rangeA, int rangeB, int rangeC);
+
+int main(int argc, char **argv) {
+ int *intarray= NULL;
+ int numInts;
+ int checkEvery= MAXint;
+ int curlong, totlong;
+ int traceLevel= 4; /* 4 normally, no tracing since qset does not log. 5 for memory tracing */
+
+#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG) /* user.h */
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) );
+ _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
+ _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
+#endif
+
+ readOptions(argc, argv, prompt, &numInts, &checkEvery, &traceLevel);
+ setupMemory(traceLevel, numInts, &intarray);
+
+ testSetappendSettruncate(numInts, intarray, checkEvery);
+ testSetdelSetadd(numInts, intarray, checkEvery);
+ testSetappendSet(numInts, intarray, checkEvery);
+ testSetcompactCopy(numInts, intarray, checkEvery);
+ testSetequalInEtc(numInts, intarray, checkEvery);
+ testSettemp(numInts, intarray, checkEvery);
+ testSetlastEtc(numInts, intarray, checkEvery);
+ testSetdelsortedEtc(numInts, intarray, checkEvery);
+ printf("\n\nNot testing qh_setduplicate and qh_setfree2.\n These routines use heap-allocated set contents. See qhull tests.\n");
+
+ qh_memstatistics(stdout);
+ qh_memfreeshort(&curlong, &totlong);
+ if (curlong || totlong){
+ qh_fprintf(stderr, 8043, "qh_memfreeshort: did not free %d bytes of long memory(%d pieces)\n", totlong, curlong);
+ error_count++;
+ }
+ if(error_count){
+ qh_fprintf(stderr, 8012, "testqset: %d errors\n\n", error_count);
+ exit(1);
+ }else{
+ printf("testqset: OK\n\n");
+ }
+ return 0;
+}/*main*/
+
+void readOptions(int argc, char **argv, const char *promptstr, int *numInts, int *checkEvery, int *traceLevel)
+{
+ long numIntsArg;
+ long checkEveryArg;
+ char *endp;
+ int isTracing= 0;
+
+ if (argc < 2 || argc > 4) {
+ printf("%s", promptstr);
+ exit(0);
+ }
+ numIntsArg= strtol(argv[1], &endp, 10);
+ if(numIntsArg<1){
+ qh_fprintf(stderr, 6301, "First argument should be 1 or greater. Got '%s'\n", argv[1]);
+ exit(1);
+ }
+ if(numIntsArg>MAXint){
+ qh_fprintf(stderr, 6302, "qset does not currently support 64-bit ints. Maximum count is %d\n", MAXint);
+ exit(1);
+ }
+ *numInts= (int)numIntsArg;
+
+ if(argc==3 && argv[2][0]=='T' && argv[2][1]=='5' ){
+ isTracing= 1;
+ *traceLevel= 5;
+ }
+ if(argc==4 || (argc==3 && !isTracing)){
+ checkEveryArg= strtol(argv[2], &endp, 10);
+ if(checkEveryArg<1){
+ qh_fprintf(stderr, 6321, "checkEvery argument should be 1 or greater. Got '%s'\n", argv[2]);
+ exit(1);
+ }
+ if(checkEveryArg>MAXint){
+ qh_fprintf(stderr, 6322, "qset does not currently support 64-bit ints. Maximum checkEvery is %d\n", MAXint);
+ exit(1);
+ }
+ if(argc==4){
+ if(argv[3][0]=='T' && argv[3][1]=='5' ){
+ isTracing= 1;
+ *traceLevel= 5;
+ }else{
+ qh_fprintf(stderr, 6242, "Optional third argument must be 'T5'. Got '%s'\n", argv[3]);
+ exit(1);
+ }
+ }
+ *checkEvery= (int)checkEveryArg;
+ }
+}/*readOptions*/
+
+void setupMemory(int tracelevel, int numInts, int **intarray)
+{
+ int i;
+ if(numInts<0 || numInts*(int)sizeof(int)<0){
+ qh_fprintf(stderr, 6303, "qset does not currently support 64-bit ints. Integer overflow\n");
+ exit(1);
+ }
+ *intarray= qh_malloc(numInts * sizeof(int));
+ if(!*intarray){
+ qh_fprintf(stderr, 6304, "Failed to allocate %d bytes of memory\n", numInts * sizeof(int));
+ exit(1);
+ }
+ for(i= 0; i<numInts; i++){
+ (*intarray)[i] =i;
+ }
+
+ qh_meminit(stderr);
+ qh_meminitbuffers(tracelevel, qh_MEMalign, 4 /*sizes*/, qh_MEMbufsize,qh_MEMinitbuf);
+ qh_memsize(10);
+ qh_memsize(20);
+ qh_memsize(30);
+ qh_memsize(40);
+ qh_memsetup();
+
+ qh_fprintf(stderr, 8001, "SETelemsize is %d bytes for pointer-to-int\n", SETelemsize);
+}/*setupMemmory*/
+
+void testSetappendSettruncate(int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= qh_setnew(4);
+ int i, isCheck;
+
+ qh_fprintf(stderr, 8002, "\n\nTesting qh_setappend 0..%d. Test", numInts-1);
+ for(i= 0; i<numInts; i++){
+ isCheck= log_i(ints, "i", i, numInts, checkEvery);
+ qh_setappend(&ints, intarray+i);
+ if(isCheck){
+ checkSetContents("qh_setappend", ints, i+1, 0, -1, -1);
+ }
+ }
+
+ qh_fprintf(stderr, 8014, "\n\nTesting qh_settruncate %d and 0. Test", numInts/2);
+ if(numInts>=2){
+ isCheck= log_i(ints, "n", numInts/2, numInts, checkEvery);
+ qh_settruncate(ints, numInts/2);
+ checkSetContents("qh_settruncate by half", ints, numInts/2, 0, -1, -1);
+ }
+ isCheck= log_i(ints, "n", 0, numInts, checkEvery);
+ qh_settruncate(ints, 0);
+ checkSetContents("qh_settruncate", ints, 0, -1, -1, -1);
+
+ qh_fprintf(stderr, 8003, "\n\nTesting qh_setappend2ndlast 0,0..%d. Test 0", numInts-1);
+ qh_setfree(&ints);
+ ints= qh_setnew(4);
+ qh_setappend(&ints, intarray+0);
+ for(i= 0; i<numInts; i++){
+ isCheck= log_i(ints, "i", i, numInts, checkEvery);
+ qh_setappend2ndlast(&ints, intarray+i);
+ if(isCheck){
+ checkSetContents("qh_setappend2ndlast", ints, i+2, 0, 0, -1);
+ }
+ }
+ qh_fprintf(stderr, 8015, "\n\nTesting SETtruncate_ %d and 0. Test", numInts/2);
+ if(numInts>=2){
+ isCheck= log_i(ints, "n", numInts/2, numInts, checkEvery);
+ SETtruncate_(ints, numInts/2);
+ checkSetContents("SETtruncate_ by half", ints, numInts/2, 0, -1, -1);
+ }
+ isCheck= log_i(ints, "n", 0, numInts, checkEvery);
+ SETtruncate_(ints, 0);
+ checkSetContents("SETtruncate_", ints, 0, -1, -1, -1);
+
+ qh_setfree(&ints);
+}/*testSetappendSettruncate*/
+
+void testSetdelSetadd(int numInts, int *intarray, int checkEvery)
+{
+ setT *ints=qh_setnew(1);
+ int i,j,isCheck;
+
+ qh_fprintf(stderr, 8003, "\n\nTesting qh_setdelnthsorted and qh_setaddnth 1..%d. Test", numInts-1);
+ for(j=1; j<numInts; j++){ /* size 0 not valid */
+ if(log_i(ints, "j", j, numInts, MAXint)){
+ for(i= qh_setsize(ints); i<j; i++){
+ qh_setappend(&ints, intarray+i);
+ }
+ checkSetContents("qh_setappend", ints, j, 0, -1, -1);
+ for(i= 0; i<j && i<100; i++){ /* otherwise too slow */
+ isCheck= log_i(ints, "", i, numInts, checkEvery);
+ (void)isCheck; /* unused */
+ qh_setdelnthsorted(ints, i);
+ qh_setaddnth(&ints, i, intarray+i);
+ if(checkEvery==1){
+ checkSetContents("qh_setdelnthsorted qh_setaddnth", ints, j, 0, -1, -1);
+ }
+ }
+ checkSetContents("qh_setdelnthsorted qh_setaddnth 2", ints, j, 0, -1, -1);
+ }
+ }
+ qh_setfree(&ints);
+}/*testSetdelSetadd*/
+
+void testSetappendSet(int numInts, int *intarray, int checkEvery)
+{
+ setT *ints=qh_setnew(1);
+ setT *ints2;
+ int i,j,k;
+
+ qh_fprintf(stderr, 8016, "\n\nTesting qh_setappend_set 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(ints, "j", j, numInts, numInts)){
+ for(i= qh_setsize(ints); i<j; i++){
+ qh_setappend(&ints, intarray+i);
+ }
+ if(checkEvery==1){
+ checkSetContents("qh_setappend", ints, j, 0, -1, -1);
+ }
+ ints2= qh_setnew(j==0 ? 0 : j-1); /* One less than needed */
+ for(i= 0; i<=j && i<=20; i++){ /* otherwise too slow */
+ if(log_i(ints, "", i, numInts, numInts)){
+ for(k= qh_setsize(ints2); k<i; k++){
+ qh_setappend(&ints2, intarray+k);
+ }
+ if(checkEvery==1){
+ checkSetContents("qh_setappend 2", ints2, i, 0, -1, -1);
+ }
+ qh_setappend_set(&ints, ints2);
+ checkSetContents("qh_setappend_set", ints, i+j, 0, (j==0 ? -1 : 0), -1);
+ qh_settruncate(ints, j);
+ if(checkEvery==1){
+ checkSetContents("qh_settruncate", ints, j, 0, -1, -1);
+ }
+ }
+ }
+ qh_setfree(&ints2);
+ }
+ }
+ qh_setfree(&ints);
+}/*testSetappendSet*/
+
+void testSetcompactCopy(int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= qh_setnew(20);
+ setT *ints2= NULL;
+ int i,j,k;
+
+ qh_fprintf(stderr, 8017, "\n\nTesting qh_setcompact and qh_setcopy 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(ints, "j", j, numInts, checkEvery)){
+ for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */
+ for(k= 0; k<i%7; k++){
+ qh_setappend(&ints, NULL);
+ }
+ qh_setappend(&ints, intarray+i);
+ }
+ qh_setfree(&ints2);
+ ints2= qh_setcopy(ints, 0);
+ qh_setcompact(ints);
+ qh_setcompact(ints2);
+ checkSetContents("qh_setcompact", ints, j, 0, 0, -1);
+ checkSetContents("qh_setcompact", ints2, j, 0, 0, -1);
+ qh_setcompact(ints);
+ checkSetContents("qh_setcompact", ints, j, 0, 0, -1);
+ }
+ }
+ qh_setfree(&ints);
+ qh_setfree(&ints2);
+}/*testSetcompactCopy*/
+
+void testSetdelsortedEtc(int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= qh_setnew(1);
+ setT *ints2= NULL;
+ int i,j;
+
+ qh_fprintf(stderr, 8018, "\n\nTesting qh_setdel*, qh_setaddsorted, and 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(ints, "j", j, numInts, checkEvery)){
+ for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */
+ qh_setaddsorted(&ints, intarray+i);
+ }
+ checkSetContents("qh_setaddsorted", ints, j, 0, 0, -1);
+ if(j>3){
+ qh_setdelsorted(ints, intarray+i/2);
+ checkSetContents("qh_setdelsorted", ints, j-1, 0, i/2+1, -1);
+ qh_setaddsorted(&ints, intarray+i/2);
+ checkSetContents("qh_setaddsorted i/2", ints, j, 0, 0, -1);
+ }
+ qh_setdellast(ints);
+ checkSetContents("qh_setdellast", ints, (j ? j-1 : 0), 0, -1, -1);
+ if(j>0){
+ qh_setaddsorted(&ints, intarray+j-1);
+ checkSetContents("qh_setaddsorted j-1", ints, j, 0, -1, -1);
+ }
+ if(j>4){
+ qh_setdelnthsorted(ints, i/2);
+ if (checkEvery==1)
+ checkSetContents("qh_setdelnthsorted", ints, j-1, 0, i/2+1, -1);
+ /* test qh_setdelnth and move-to-front */
+ qh_setdelsorted(ints, intarray+i/2+1);
+ checkSetContents("qh_setdelsorted 2", ints, j-2, 0, i/2+2, -1);
+ qh_setaddsorted(&ints, intarray+i/2+1);
+ if (checkEvery==1)
+ checkSetContents("qh_setaddsorted i/2+1", ints, j-1, 0, i/2+1, -1);
+ qh_setaddsorted(&ints, intarray+i/2);
+ checkSetContents("qh_setaddsorted i/2 again", ints, j, 0, -1, -1);
+ }
+ qh_setfree(&ints2);
+ ints2= qh_setcopy(ints, 0);
+ qh_setcompact(ints);
+ qh_setcompact(ints2);
+ checkSetContents("qh_setcompact", ints, j, 0, 0, -1);
+ checkSetContents("qh_setcompact 2", ints2, j, 0, 0, -1);
+ qh_setcompact(ints);
+ checkSetContents("qh_setcompact 3", ints, j, 0, 0, -1);
+ qh_setfree(&ints2);
+ }
+ }
+ qh_setfreelong(&ints);
+ if(ints){
+ qh_setfree(&ints); /* Was quick memory */
+ }
+}/*testSetdelsortedEtc*/
+
+void testSetequalInEtc(int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= NULL;
+ setT *ints2= NULL;
+ setT *ints3= NULL;
+ int i,j,n;
+
+ qh_fprintf(stderr, 8019, "\n\nTesting qh_setequal*, qh_setin*, qh_setdel, qh_setdelnth, and qh_setlarger 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(ints, "j", j, numInts, checkEvery)){
+ n= qh_setsize(ints);
+ qh_setlarger(&ints);
+ checkSetContents("qh_setlarger", ints, n, 0, -1, -1);
+ for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */
+ qh_setappend(&ints, intarray+i);
+ }
+ checkSetContents("qh_setappend", ints, j, 0, -1, -1);
+ if(!qh_setequal(ints, ints)){
+ qh_fprintf(stderr, 6300, "testSetequalInEtc: set not equal to itself at length %d\n", j);
+ error_count++;
+ }
+ if(j==0 && !qh_setequal(ints, ints2)){
+ qh_fprintf(stderr, 6323, "testSetequalInEtc: empty set not equal to null set\n");
+ error_count++;
+ }
+ if(j>0){
+ if(qh_setequal(ints, ints2)){
+ qh_fprintf(stderr, 6324, "testSetequalInEtc: non-empty set equal to empty set\n", j);
+ error_count++;
+ }
+ qh_setfree(&ints3);
+ ints3= qh_setcopy(ints, 0);
+ checkSetContents("qh_setreplace", ints3, j, 0, -1, -1);
+ qh_setreplace(ints3, intarray+j/2, intarray+j/2+1);
+ if(j==1){
+ checkSetContents("qh_setreplace 2", ints3, j, j/2+1, -1, -1);
+ }else if(j==2){
+ checkSetContents("qh_setreplace 3", ints3, j, 0, j/2+1, -1);
+ }else{
+ checkSetContents("qh_setreplace 3", ints3, j, 0, j/2+1, j/2+1);
+ }
+ if(qh_setequal(ints, ints3)){
+ qh_fprintf(stderr, 6325, "testSetequalInEtc: modified set equal to original set at %d/2\n", j);
+ error_count++;
+ }
+ if(!qh_setequal_except(ints, intarray+j/2, ints3, intarray+j/2+1)){
+ qh_fprintf(stderr, 6326, "qh_setequal_except: modified set not equal to original set except modified\n", j);
+ error_count++;
+ }
+ if(qh_setequal_except(ints, intarray+j/2, ints3, intarray)){
+ qh_fprintf(stderr, 6327, "qh_setequal_except: modified set equal to original set with wrong excepts\n", j);
+ error_count++;
+ }
+ if(!qh_setequal_skip(ints, j/2, ints3, j/2)){
+ qh_fprintf(stderr, 6328, "qh_setequal_skip: modified set not equal to original set except modified\n", j);
+ error_count++;
+ }
+ if(j>2 && qh_setequal_skip(ints, j/2, ints3, 0)){
+ qh_fprintf(stderr, 6329, "qh_setequal_skip: modified set equal to original set with wrong excepts\n", j);
+ error_count++;
+ }
+ if(intarray+j/2+1!=qh_setdel(ints3, intarray+j/2+1)){
+ qh_fprintf(stderr, 6330, "qh_setdel: failed to find added element\n", j);
+ error_count++;
+ }
+ checkSetContents("qh_setdel", ints3, j-1, 0, j-1, (j==1 ? -1 : j/2+1)); /* swaps last element with deleted element */
+ if(j>3){
+ qh_setdelnth(ints3, j/2); /* Delete at the same location as the original replace, for only one out-of-order element */
+ checkSetContents("qh_setdelnth", ints3, j-2, 0, j-2, (j==2 ? -1 : j/2+1));
+ }
+ if(qh_setin(ints3, intarray+j/2)){
+ qh_fprintf(stderr, 6331, "qh_setin: found deleted element\n");
+ error_count++;
+ }
+ if(j>4 && !qh_setin(ints3, intarray+1)){
+ qh_fprintf(stderr, 6332, "qh_setin: did not find second element\n");
+ error_count++;
+ }
+ if(j>4 && !qh_setin(ints3, intarray+j-2)){
+ qh_fprintf(stderr, 6333, "qh_setin: did not find last element\n");
+ error_count++;
+ }
+ if(-1!=qh_setindex(ints2, intarray)){
+ qh_fprintf(stderr, 6334, "qh_setindex: found element in empty set\n");
+ error_count++;
+ }
+ if(-1!=qh_setindex(ints3, intarray+j/2)){
+ qh_fprintf(stderr, 6335, "qh_setindex: found deleted element in set\n");
+ error_count++;
+ }
+ if(0!=qh_setindex(ints, intarray)){
+ qh_fprintf(stderr, 6336, "qh_setindex: did not find first in set\n");
+ error_count++;
+ }
+ if(j-1!=qh_setindex(ints, intarray+j-1)){
+ qh_fprintf(stderr, 6337, "qh_setindex: did not find last in set\n");
+ error_count++;
+ }
+ }
+ qh_setfree(&ints2);
+ }
+ }
+ qh_setfree(&ints3);
+ qh_setfreelong(&ints);
+ if(ints){
+ qh_setfree(&ints); /* Was quick memory */
+ }
+}/*testSetequalInEtc*/
+
+
+void testSetlastEtc(int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= NULL;
+ setT *ints2= NULL;
+ int i,j,prepend;
+
+ qh_fprintf(stderr, 8020, "\n\nTesting qh_setlast, qh_setnew_delnthsorted, qh_setunique, and qh_setzero 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(ints, "j", j, numInts, checkEvery)){
+ for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */
+ if(!qh_setunique(&ints, intarray+i)){
+ qh_fprintf(stderr, 6340, "qh_setunique: not able to append next element %d\n", i);
+ error_count++;
+ }
+ if(checkEvery==1){
+ checkSetContents("qh_setunique", ints, i+1, 0, -1, -1);
+ }
+ if(qh_setunique(&ints, intarray+i)){
+ qh_fprintf(stderr, 6341, "qh_setunique: appended next element twice %d\n", i);
+ error_count++;
+ }
+ if(qh_setunique(&ints, intarray+i/2)){
+ qh_fprintf(stderr, 6346, "qh_setunique: appended middle element twice %d/2\n", i);
+ error_count++;
+ }
+ }
+ checkSetContents("qh_setunique 2", ints, j, 0, -1, -1);
+ if(j==0 && NULL!=qh_setlast(ints)){
+ qh_fprintf(stderr, 6339, "qh_setlast: returned last element of empty set\n");
+ error_count++;
+ }
+ if(j>0){
+ if(intarray+j-1!=qh_setlast(ints)){
+ qh_fprintf(stderr, 6338, "qh_setlast: wrong last element\n");
+ error_count++;
+ }
+ prepend= (j<100 ? j/4 : 0);
+ ints2= qh_setnew_delnthsorted(ints, qh_setsize(ints), j/2, prepend);
+ if(qh_setsize(ints2)!=j+prepend-1){
+ qh_fprintf(stderr, 6345, "qh_setnew_delnthsorted: Expecting %d elements, got %d\n", j+prepend-1, qh_setsize(ints2));
+ error_count++;
+ }
+ /* Define prepended elements. Otherwise qh_setdelnthsorted may fail */
+ for(i= 0; i<prepend; i++){
+ void **p= &SETelem_(ints2, i);
+ *p= intarray+0;
+ }
+ for(i= 0; i<prepend; i++){
+ qh_setdelnthsorted(ints2, 0); /* delete undefined prefix */
+ }
+ checkSetContents("qh_setnew_delnthsorted", ints2, j-1, 0, j/2+1, -1);
+ if(j>2){
+ qh_setzero(ints2, j/2, j-1); /* max size may be j-1 */
+ if(qh_setsize(ints2)!=j-1){
+ qh_fprintf(stderr, 6342, "qh_setzero: Expecting %d elements, got %d\n", j, qh_setsize(ints2));
+ error_count++;
+ }
+ qh_setcompact(ints2);
+ checkSetContents("qh_setzero", ints2, j/2, 0, -1, -1);
+ }
+ }
+ qh_setfree(&ints2);
+ }
+ }
+ qh_setfreelong(&ints);
+ if(ints){
+ qh_setfree(&ints); /* Was quick memory */
+ }
+}/*testSetlastEtc*/
+
+void testSettemp(int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= NULL;
+ setT *ints2= NULL;
+ setT *ints3= NULL;
+ int i,j;
+
+ qh_fprintf(stderr, 8021, "\n\nTesting qh_settemp* 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(ints, "j", j, numInts, checkEvery)){
+ if(j<20){
+ for(i=0; i<j; i++){
+ ints2= qh_settemp(j);
+ }
+ qh_settempfree_all();
+ }
+ for(i= qh_setsize(ints); i<j; i++){ /* Test i<j to test the empty set */
+ qh_setappend(&ints, intarray+i);
+ }
+ ints2= qh_settemp(j);
+ if(j>0){
+ qh_settemppush(ints);
+ ints3= qh_settemppop();
+ if(ints!=ints3){
+ qh_fprintf(stderr, 6343, "qh_settemppop: didn't pop the push\n");
+ error_count++;
+ }
+ }
+ qh_settempfree(&ints2);
+ }
+ }
+ qh_setfreelong(&ints);
+ if(ints){
+ qh_setfree(&ints); /* Was quick memory */
+ }
+}/*testSettemp*/
+
+/* Check that a set contains count elements
+ Ranges are consecutive (e.g., 1,2,3,...) starting with first, mid, and last
+ Use -1 for missing ranges
+ Returns -1 if should check results
+*/
+int log_i(setT *set, const char *s, int i, int numInts, int checkEvery)
+{
+ int j= i;
+ int scale= 1;
+ int e= 0;
+ int *i2, **i2p;
+
+ if(*s || checkEvery==1){
+ if(i<10){
+ qh_fprintf(stderr, 8004, " %s%d", s, i);
+ }else{
+ if(i==11 && checkEvery==1){
+ qh_fprintf(stderr, 8005, "\nResults after 10: ");
+ FOREACHint_(set){
+ qh_fprintf(stderr, 8006, " %d", *i2);
+ }
+ qh_fprintf(stderr, 8007, " Continue");
+ }
+ while((j= j/10)>=1){
+ scale *= 10;
+ e++;
+ }
+ if(i==numInts-1){
+ qh_fprintf(stderr, 8008, " %s%d", s, i);
+ }else if(i==scale){
+ if(i<=1000){
+ qh_fprintf(stderr, 8010, " %s%d", s, i);
+ }else{
+ qh_fprintf(stderr, 8009, " %s1e%d", s, e);
+ }
+ }
+ }
+ }
+ if(i<1000 || i%checkEvery==0 || i== scale || i==numInts-1){
+ return 1;
+ }
+ return 0;
+}/*log_i*/
+
+/* Check that a set contains count elements
+ Ranges are consecutive (e.g., 1,2,3,...) starting with first, mid, and last
+ Use -1 for missing ranges
+*/
+void checkSetContents(const char *name, setT *set, int count, int rangeA, int rangeB, int rangeC)
+{
+
+ i2T *i2, **i2p;
+ int i2_i, i2_n;
+ int prev= -1; /* avoid warning */
+ int i;
+ int first= -3;
+ int second= -3;
+ int rangeCount=1;
+ int actualSize= 0;
+
+ qh_setcheck(set, name, 0);
+ if(set){
+ SETreturnsize_(set, actualSize); /* normally used only when speed is critical */
+ if(*qh_setendpointer(set)!=NULL){
+ qh_fprintf(stderr, 6344, "%s: qh_setendpointer(), 0x%x, is not NULL terminator of set 0x%x", name, qh_setendpointer(set), set);
+ error_count++;
+ }
+ }
+ if(actualSize!=qh_setsize(set)){
+ qh_fprintf(stderr, 6305, "%s: SETreturnsize_() returned %d while qh_setsize() returns %d\n", name, actualSize, qh_setsize(set));
+ error_count++;
+ }else if(actualSize!=count){
+ qh_fprintf(stderr, 6306, "%s: Expecting %d elements for set. Got %d elements\n", name, count, actualSize);
+ error_count++;
+ }
+ if(SETempty_(set)){
+ if(count!=0){
+ qh_fprintf(stderr, 6307, "%s: Got empty set instead of count %d, rangeA %d, rangeB %d, rangeC %d\n", name, count, rangeA, rangeB, rangeC);
+ error_count++;
+ }
+ }else{
+ /* Must be first, otherwise trips msvc 8 */
+ i2T **p= SETaddr_(set, i2T);
+ if(*p!=SETfirstt_(set, i2T)){
+ qh_fprintf(stderr, 6309, "%s: SETaddr_(set, i2t) [%p] is not the same as SETfirst_(set) [%p]\n", name, SETaddr_(set, i2T), SETfirst_(set));
+ error_count++;
+ }
+ first= *(int *)SETfirst_(set);
+ if(SETfirst_(set)!=SETfirstt_(set, i2T)){
+ qh_fprintf(stderr, 6308, "%s: SETfirst_(set) [%p] is not the same as SETfirstt_(set, i2T [%p]\n", name, SETfirst_(set), SETfirstt_(set, i2T));
+ error_count++;
+ }
+ if(qh_setsize(set)>1){
+ second= *(int *)SETsecond_(set);
+ if(SETsecond_(set)!=SETsecondt_(set, i2T)){
+ qh_fprintf(stderr, 6310, "%s: SETsecond_(set) [%p] is not the same as SETsecondt_(set, i2T) [%p]\n", name, SETsecond_(set), SETsecondt_(set, i2T));
+ error_count++;
+ }
+ }
+ }
+ /* Test first run of ints in set*/
+ i= 0;
+ FOREACHint_(set){
+ if(i2!=SETfirst_(set) && *i2!=prev+1){
+ break;
+ }
+ prev= *i2;
+ if(SETindex_(set, i2)!=i){
+ qh_fprintf(stderr, 6311, "%s: Expecting SETIndex_(set, pointer-to-%d) to be %d. Got %d\n", name, *i2, i, SETindex_(set, i2));
+ error_count++;;
+ }
+ if(i2!=SETref_(i2)){
+ qh_fprintf(stderr, 6312, "%s: SETref_(i2) [%p] does not point to i2 (the %d'th element)\n", name, SETref_(i2), i);
+ error_count++;;
+ }
+ i++;
+ }
+ FOREACHint_i_(set){
+ /* Must be first conditional, otherwise it trips up msvc 8 */
+ i2T **p= SETelemaddr_(set, i2_i, i2T);
+ if(i2!=*p){
+ qh_fprintf(stderr, 6320, "%s: SETelemaddr_(set, %d, i2T) [%p] does not point to i2\n", name, i2_i, SETelemaddr_(set, i2_i, int));
+ error_count++;;
+ }
+ if(i2_i==0){
+ if(first!=*i2){
+ qh_fprintf(stderr, 6314, "%s: First element is %d instead of SETfirst %d\n", name, *i2, first);
+ error_count++;;
+ }
+ if(rangeA!=*i2){
+ qh_fprintf(stderr, 6315, "%s: starts with %d instead of rangeA %d\n", name, *i2, rangeA);
+ error_count++;;
+ }
+ prev= rangeA;
+ }else{
+ if(i2_i==1 && second!=*i2){
+ qh_fprintf(stderr, 6316, "%s: Second element is %d instead of SETsecond %d\n", name, *i2, second);
+ error_count++;;
+ }
+ if(prev+1==*i2){
+ prev++;
+ }else{
+ if(*i2==rangeB){
+ prev= rangeB;
+ rangeB= -1;
+ rangeCount++;
+ }else if(rangeB==-1 && *i2==rangeC){
+ prev= rangeC;
+ rangeC= -1;
+ rangeCount++;
+ }else{
+ prev++;
+ qh_fprintf(stderr, 6317, "%s: Expecting %d'th element to be %d. Got %d\n", name, i2_i, prev, *i2);
+ error_count++;
+ }
+ }
+ }
+ if(i2!=SETelem_(set, i2_i)){
+ qh_fprintf(stderr, 6318, "%s: SETelem_(set, %d) [%p] is not i2 [%p] (the %d'th element)\n", name, i2_i, SETelem_(set, i2_i), i2, i2_i);
+ error_count++;;
+ }
+ if(SETelemt_(set, i2_i, i2T)!=SETelem_(set, i2_i)){ /* Normally SETelemt_ is used for generic sets */
+ qh_fprintf(stderr, 6319, "%s: SETelemt_(set, %d, i2T) [%p] is not SETelem_(set, %d) [%p] (the %d'th element)\n", name, i2_i, SETelemt_(set, i2_i, int), i2_i, SETelem_(set, i2_i), i2_i);
+ error_count++;;
+ }
+ }
+ if(error_count>=MAXerrorCount){
+ qh_fprintf(stderr, 8011, "testqset: Stop testing after %d errors\n", error_count);
+ exit(1);
+ }
+}/*checkSetContents*/
+
diff --git a/xs/src/qhull/src/testqset/testqset.pro b/xs/src/qhull/src/testqset/testqset.pro
new file mode 100644
index 000000000..3f69048aa
--- /dev/null
+++ b/xs/src/qhull/src/testqset/testqset.pro
@@ -0,0 +1,30 @@
+# -------------------------------------------------
+# testqset.pro -- Qt project file for testqset.exe
+# -------------------------------------------------
+
+include(../qhull-warn.pri)
+
+TARGET = testqset
+
+DESTDIR = ../../bin
+TEMPLATE = app
+CONFIG += console warn_on
+CONFIG -= qt
+CONFIG += qhull_warn_conversion
+
+build_pass:CONFIG(debug, debug|release){
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release){
+ OBJECTS_DIR = Release
+}
+
+INCLUDEPATH += ..
+
+SOURCES += testqset.c
+SOURCES += ../libqhull/qset.c
+SOURCES += ../libqhull/mem.c
+SOURCES += ../libqhull/usermem.c
+
+HEADERS += ../libqhull/mem.h
+HEADERS += ../libqhull/qset.h
+
diff --git a/xs/src/qhull/src/testqset_r/testqset_r.c b/xs/src/qhull/src/testqset_r/testqset_r.c
new file mode 100644
index 000000000..9a6d496e4
--- /dev/null
+++ b/xs/src/qhull/src/testqset_r/testqset_r.c
@@ -0,0 +1,890 @@
+/*<html><pre> -<a href="../libqhull/index.htm#TOC"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ testset.c -- test qset.c and its use of mem.c
+
+ The test sets are pointers to int. Normally a set is a pointer to a type (e.g., facetT, ridgeT, etc.).
+ For consistency in notation, an "int" is typedef'd to i2T
+
+Functions and macros from qset.h. Counts occurrences in this test. Does not correspond to thoroughness.
+ qh_setaddsorted -- 4 tests
+ qh_setaddnth -- 1 test
+ qh_setappend -- 7 tests
+ qh_setappend_set -- 1 test
+ qh_setappend2ndlast -- 1 test
+ qh_setcheck -- lots of tests
+ qh_setcompact -- 7 tests
+ qh_setcopy -- 3 tests
+ qh_setdel -- 1 tests
+ qh_setdellast -- 1 tests
+ qh_setdelnth -- 2 tests
+ qh_setdelnthsorted -- 2 tests
+ qh_setdelsorted -- 1 test
+ qh_setduplicate -- not testable here
+ qh_setequal -- 4 tests
+ qh_setequal_except -- 2 tests
+ qh_setequal_skip -- 2 tests
+ qh_setfree -- 11+ tests
+ qh_setfree2 -- not testable here
+ qh_setfreelong -- 2 tests
+ qh_setin -- 3 tests
+ qh_setindex -- 4 tests
+ qh_setlarger -- 1 test
+ qh_setlast -- 2 tests
+ qh_setnew -- 6 tests
+ qh_setnew_delnthsorted
+ qh_setprint -- tested elsewhere
+ qh_setreplace -- 1 test
+ qh_setsize -- 9+ tests
+ qh_settemp -- 2 tests
+ qh_settempfree -- 1 test
+ qh_settempfree_all -- 1 test
+ qh_settemppop -- 1 test
+ qh_settemppush -- 1 test
+ qh_settruncate -- 3 tests
+ qh_setunique -- 3 tests
+ qh_setzero -- 1 test
+ FOREACHint_ -- 2 test
+ FOREACHint4_
+ FOREACHint_i_ -- 1 test
+ FOREACHintreverse_
+ FOREACHintreverse12_
+ FOREACHsetelement_ -- 1 test
+ FOREACHsetelement_i_ -- 1 test
+ FOREACHsetelementreverse_ -- 1 test
+ FOREACHsetelementreverse12_ -- 1 test
+ SETelem_ -- 3 tests
+ SETelemaddr_ -- 2 tests
+ SETelemt_ -- not tested (generic)
+ SETempty_ -- 1 test
+ SETfirst_ -- 4 tests
+ SETfirstt_ -- 2 tests
+ SETindex_ -- 2 tests
+ SETref_ -- 2 tests
+ SETreturnsize_ -- 2 tests
+ SETsecond_ -- 1 test
+ SETsecondt_ -- 2 tests
+ SETtruncate_ -- 2 tests
+
+ Copyright (c) 2012-2015 C.B. Barber. All rights reserved.
+ $Id: //main/2015/qhull/src/testqset_r/testqset_r.c#5 $$Change: 2064 $
+ $DateTime: 2016/01/18 12:36:08 $$Author: bbarber $
+*/
+
+#include "libqhull_r/user_r.h" /* QHULL_CRTDBG */
+#include "libqhull_r/qset_r.h"
+#include "libqhull_r/mem_r.h"
+#include "libqhull_r/libqhull_r.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef int i2T;
+#define MAXerrorCount 100 /* quit after n errors */
+
+#define FOREACHint_( ints ) FOREACHsetelement_( i2T, ints, i2)
+#define FOREACHint4_( ints ) FOREACHsetelement_( i2T, ints, i4)
+#define FOREACHint_i_( qh, ints ) FOREACHsetelement_i_( qh, i2T, ints, i2)
+#define FOREACHintreverse_( qh, ints ) FOREACHsetelementreverse_( qh, i2T, ints, i2)
+#define FOREACHintreverse12_( ints ) FOREACHsetelementreverse12_( i2T, ints, i2)
+
+enum {
+ MAXint= 0x7fffffff,
+};
+
+char prompt[]= "testqset_r N [M] [T5] -- Test reentrant qset_r.c and mem_r.c\n\
+ \n\
+ If this test fails then reentrant Qhull will not work.\n\
+ \n\
+ Test qsets of 0..N integers with a check every M iterations (default ~log10)\n\
+ Additional checking and logging if M is 1\n\
+ \n\
+ T5 turns on memory logging (qset does not log)\n\
+ \n\
+ For example:\n\
+ testqset_r 10000\n\
+";
+
+int error_count= 0; /* Global error_count. checkSetContents(qh) keeps its own error count. It exits on too many errors */
+
+/* Macros normally defined in geom.h */
+#define fmax_( a,b ) ( ( a ) < ( b ) ? ( b ) : ( a ) )
+
+/* Macros normally defined in QhullSet.h */
+
+/* Functions normally defined in user_r.h for usermem_r.c */
+
+void qh_exit(int exitcode);
+void qh_fprintf_stderr(int msgcode, const char *fmt, ... );
+void qh_free(void *mem);
+void *qh_malloc(size_t size);
+
+/* Normally defined in user_r.c */
+
+void qh_errexit(qhT *qh, int exitcode, facetT *f, ridgeT *r)
+{
+ (void)f; /* unused */
+ (void)r; /* unused */
+ (void)qh; /* unused */
+ qh_exit(exitcode);
+}
+
+/* Normally defined in userprintf.c */
+
+void qh_fprintf(qhT *qh, FILE *fp, int msgcode, const char *fmt, ... )
+{
+ static int needs_cr= 0; /* True if qh_fprintf needs a CR. testqset_r is not itself reentrant */
+
+ size_t fmtlen= strlen(fmt);
+ va_list args;
+
+ if (!fp) {
+ /* Do not use qh_fprintf_stderr. This is a standalone program */
+ if(!qh)
+ fprintf(stderr, "QH6241 qh_fprintf: fp and qh not defined for '%s'", fmt);
+ else
+ fprintf(stderr, "QH6232 qh_fprintf: fp is 0. Was wrong qh_fprintf called for '%s'", fmt);
+ qh_errexit(qh, 6232, NULL, NULL);
+ }
+ if(fmtlen>0){
+ if(fmt[fmtlen-1]=='\n'){
+ if(needs_cr && fmtlen>1){
+ fprintf(fp, "\n");
+ }
+ needs_cr= 0;
+ }else{
+ needs_cr= 1;
+ }
+ }
+ if(msgcode>=6000 && msgcode<7000){
+ fprintf(fp, "Error TQ%d ", msgcode);
+ }
+ va_start(args, fmt);
+ vfprintf(fp, fmt, args);
+ va_end(args);
+}
+
+/* Defined below in order of use */
+int main(int argc, char **argv);
+void readOptions(qhT *qh, int argc, char **argv, const char *promptstr, int *numInts, int *checkEvery, int *traceLevel);
+void setupMemory(qhT *qh, int tracelevel, int numInts, int **intarray);
+
+void testSetappendSettruncate(qhT *qh, int numInts, int *intarray, int checkEvery);
+void testSetdelSetadd(qhT *qh, int numInts, int *intarray, int checkEvery);
+void testSetappendSet(qhT *qh, int numInts, int *intarray, int checkEvery);
+void testSetcompactCopy(qhT *qh, int numInts, int *intarray, int checkEvery);
+void testSetequalInEtc(qhT *qh, int numInts, int *intarray, int checkEvery);
+void testSettemp(qhT *qh, int numInts, int *intarray, int checkEvery);
+void testSetlastEtc(qhT *qh, int numInts, int *intarray, int checkEvery);
+void testSetdelsortedEtc(qhT *qh, int numInts, int *intarray, int checkEvery);
+
+int log_i(qhT *qh, setT *set, const char *s, int i, int numInts, int checkEvery);
+void checkSetContents(qhT *qh, const char *name, setT *set, int count, int rangeA, int rangeB, int rangeC);
+
+int main(int argc, char **argv) {
+ int *intarray= NULL;
+ int numInts;
+ int checkEvery= MAXint;
+ int curlong, totlong;
+ int traceLevel= 4; /* 4 normally, no tracing since qset does not log. Option 'T5' for memory tracing */
+ qhT qh_qh;
+ qhT *qh= &qh_qh;
+
+#if defined(_MSC_VER) && defined(_DEBUG) && defined(QHULL_CRTDBG) /* user_r.h */
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) );
+ _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG );
+ _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
+#endif
+
+ readOptions(qh, argc, argv, prompt, &numInts, &checkEvery, &traceLevel);
+ setupMemory(qh, traceLevel, numInts, &intarray);
+
+ testSetappendSettruncate(qh, numInts, intarray, checkEvery);
+ testSetdelSetadd(qh, numInts, intarray, checkEvery);
+ testSetappendSet(qh, numInts, intarray, checkEvery);
+ testSetcompactCopy(qh, numInts, intarray, checkEvery);
+ testSetequalInEtc(qh, numInts, intarray, checkEvery);
+ testSettemp(qh, numInts, intarray, checkEvery);
+ testSetlastEtc(qh, numInts, intarray, checkEvery);
+ testSetdelsortedEtc(qh, numInts, intarray, checkEvery);
+ printf("\n\nNot testing qh_setduplicate and qh_setfree2.\n These routines use heap-allocated set contents. See qhull tests.\n");
+
+ qh_memstatistics(qh, stdout);
+ qh_memfreeshort(qh, &curlong, &totlong);
+ if (curlong || totlong){
+ qh_fprintf(qh, stderr, 8043, "qh_memfreeshort: did not free %d bytes of long memory(%d pieces)\n", totlong, curlong);
+ error_count++;
+ }
+ if(error_count){
+ qh_fprintf(qh, stderr, 8012, "testqset: %d errors\n\n", error_count);
+ exit(1);
+ }else{
+ printf("testqset_r: OK\n\n");
+ }
+ return 0;
+}/*main*/
+
+void readOptions(qhT *qh, int argc, char **argv, const char *promptstr, int *numInts, int *checkEvery, int *traceLevel)
+{
+ long numIntsArg;
+ long checkEveryArg;
+ char *endp;
+ int isTracing= 0;
+
+ if (argc < 2 || argc > 4) {
+ printf("%s", promptstr);
+ exit(0);
+ }
+ numIntsArg= strtol(argv[1], &endp, 10);
+ if(numIntsArg<1){
+ qh_fprintf(qh, stderr, 6301, "First argument should be 1 or greater. Got '%s'\n", argv[1]);
+ exit(1);
+ }
+ if(numIntsArg>MAXint){
+ qh_fprintf(qh, stderr, 6302, "qset does not currently support 64-bit ints. Maximum count is %d\n", MAXint);
+ exit(1);
+ }
+ *numInts= (int)numIntsArg;
+
+ if(argc==3 && argv[2][0]=='T' && argv[2][1]=='5' ){
+ isTracing= 1;
+ *traceLevel= 5;
+ }
+ if(argc==4 || (argc==3 && !isTracing)){
+ checkEveryArg= strtol(argv[2], &endp, 10);
+ if(checkEveryArg<1){
+ qh_fprintf(qh, stderr, 6321, "checkEvery argument should be 1 or greater. Got '%s'\n", argv[2]);
+ exit(1);
+ }
+ if(checkEveryArg>MAXint){
+ qh_fprintf(qh, stderr, 6322, "qset does not currently support 64-bit ints. Maximum checkEvery is %d\n", MAXint);
+ exit(1);
+ }
+ if(argc==4){
+ if(argv[3][0]=='T' && argv[3][1]=='5' ){
+ isTracing= 1;
+ *traceLevel= 5;
+ }else{
+ qh_fprintf(qh, stderr, 6242, "Optional third argument must be 'T5'. Got '%s'\n", argv[3]);
+ exit(1);
+ }
+ }
+ *checkEvery= (int)checkEveryArg;
+ }
+}/*readOptions*/
+
+void setupMemory(qhT *qh, int tracelevel, int numInts, int **intarray)
+{
+ int i;
+ if(numInts<0 || numInts*(int)sizeof(int)<0){
+ qh_fprintf(qh, stderr, 6303, "qset does not currently support 64-bit ints. Integer overflow\n");
+ exit(1);
+ }
+ *intarray= qh_malloc(numInts * sizeof(int));
+ if(!*intarray){
+ qh_fprintf(qh, stderr, 6304, "Failed to allocate %d bytes of memory\n", numInts * sizeof(int));
+ exit(1);
+ }
+ for(i= 0; i<numInts; i++){
+ (*intarray)[i] =i;
+ }
+
+ qh_meminit(qh, stderr);
+ qh_meminitbuffers(qh, tracelevel, qh_MEMalign, 4 /*sizes*/, qh_MEMbufsize, qh_MEMinitbuf);
+ qh_memsize(qh, 10);
+ qh_memsize(qh, 20);
+ qh_memsize(qh, 30);
+ qh_memsize(qh, 40);
+ qh_memsetup(qh);
+
+ qh_fprintf(qh, stderr, 8001, "SETelemsize is %d bytes for pointer-to-int\n", SETelemsize);
+}/*setupMemmory*/
+
+void testSetappendSettruncate(qhT *qh, int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= qh_setnew(qh, 4);
+ int i, isCheck;
+
+ qh_fprintf(qh, stderr, 8002, "\n\nTesting qh_setappend 0..%d. Test", numInts-1);
+ for(i= 0; i<numInts; i++){
+ isCheck= log_i(qh, ints, "i", i, numInts, checkEvery);
+ qh_setappend(qh, &ints, intarray+i);
+ if(isCheck){
+ checkSetContents(qh, "qh_setappend", ints, i+1, 0, -1, -1);
+ }
+ }
+
+ qh_fprintf(qh, stderr, 8014, "\n\nTesting qh_settruncate %d and 0. Test", numInts/2);
+ if(numInts>=2){
+ isCheck= log_i(qh, ints, "n", numInts/2, numInts, checkEvery);
+ qh_settruncate(qh, ints, numInts/2);
+ checkSetContents(qh, "qh_settruncate by half", ints, numInts/2, 0, -1, -1);
+ }
+ isCheck= log_i(qh, ints, "n", 0, numInts, checkEvery);
+ qh_settruncate(qh, ints, 0);
+ checkSetContents(qh, "qh_settruncate", ints, 0, -1, -1, -1);
+
+ qh_fprintf(qh, stderr, 8003, "\n\nTesting qh_setappend2ndlast 0,0..%d. Test 0", numInts-1);
+ qh_setfree(qh, &ints);
+ ints= qh_setnew(qh, 4);
+ qh_setappend(qh, &ints, intarray+0);
+ for(i= 0; i<numInts; i++){
+ isCheck= log_i(qh, ints, "i", i, numInts, checkEvery);
+ qh_setappend2ndlast(qh, &ints, intarray+i);
+ if(isCheck){
+ checkSetContents(qh, "qh_setappend2ndlast", ints, i+2, 0, 0, -1);
+ }
+ }
+ qh_fprintf(qh, stderr, 8015, "\n\nTesting SETtruncate_ %d and 0. Test", numInts/2);
+ if(numInts>=2){
+ isCheck= log_i(qh, ints, "n", numInts/2, numInts, checkEvery);
+ SETtruncate_(ints, numInts/2);
+ checkSetContents(qh, "SETtruncate_ by half", ints, numInts/2, 0, -1, -1);
+ }
+ isCheck= log_i(qh, ints, "n", 0, numInts, checkEvery);
+ SETtruncate_(ints, 0);
+ checkSetContents(qh, "SETtruncate_", ints, 0, -1, -1, -1);
+
+ qh_setfree(qh, &ints);
+}/*testSetappendSettruncate*/
+
+void testSetdelSetadd(qhT *qh, int numInts, int *intarray, int checkEvery)
+{
+ setT *ints=qh_setnew(qh, 1);
+ int i,j,isCheck;
+
+ qh_fprintf(qh, stderr, 8003, "\n\nTesting qh_setdelnthsorted and qh_setaddnth 1..%d. Test", numInts-1);
+ for(j=1; j<numInts; j++){ /* size 0 not valid */
+ if(log_i(qh, ints, "j", j, numInts, MAXint)){
+ for(i= qh_setsize(qh, ints); i<j; i++){
+ qh_setappend(qh, &ints, intarray+i);
+ }
+ checkSetContents(qh, "qh_setappend", ints, j, 0, -1, -1);
+ for(i= 0; i<j && i<100; i++){ /* otherwise too slow */
+ isCheck= log_i(qh, ints, "", i, numInts, checkEvery);
+ (void)isCheck; /* unused */
+ qh_setdelnthsorted(qh, ints, i);
+ qh_setaddnth(qh, &ints, i, intarray+i);
+ if(checkEvery==1){
+ checkSetContents(qh, "qh_setdelnthsorted qh_setaddnth", ints, j, 0, -1, -1);
+ }
+ }
+ checkSetContents(qh, "qh_setdelnthsorted qh_setaddnth 2", ints, j, 0, -1, -1);
+ }
+ }
+ qh_setfree(qh, &ints);
+}/*testSetdelSetadd*/
+
+void testSetappendSet(qhT *qh, int numInts, int *intarray, int checkEvery)
+{
+ setT *ints=qh_setnew(qh, 1);
+ setT *ints2;
+ int i,j,k;
+
+ qh_fprintf(qh, stderr, 8016, "\n\nTesting qh_setappend_set 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(qh, ints, "j", j, numInts, numInts)){
+ for(i= qh_setsize(qh, ints); i<j; i++){
+ qh_setappend(qh, &ints, intarray+i);
+ }
+ if(checkEvery==1){
+ checkSetContents(qh, "qh_setappend", ints, j, 0, -1, -1);
+ }
+ ints2= qh_setnew(qh, j==0 ? 0 : j-1); /* One less than needed */
+ for(i= 0; i<=j && i<=20; i++){ /* otherwise too slow */
+ if(log_i(qh, ints, "", i, numInts, numInts)){
+ for(k= qh_setsize(qh, ints2); k<i; k++){
+ qh_setappend(qh, &ints2, intarray+k);
+ }
+ if(checkEvery==1){
+ checkSetContents(qh, "qh_setappend 2", ints2, i, 0, -1, -1);
+ }
+ qh_setappend_set(qh, &ints, ints2);
+ checkSetContents(qh, "qh_setappend_set", ints, i+j, 0, (j==0 ? -1 : 0), -1);
+ qh_settruncate(qh, ints, j);
+ if(checkEvery==1){
+ checkSetContents(qh, "qh_settruncate", ints, j, 0, -1, -1);
+ }
+ }
+ }
+ qh_setfree(qh, &ints2);
+ }
+ }
+ qh_setfree(qh, &ints);
+}/*testSetappendSet*/
+
+void testSetcompactCopy(qhT *qh, int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= qh_setnew(qh, 20);
+ setT *ints2= NULL;
+ int i,j,k;
+
+ qh_fprintf(qh, stderr, 8017, "\n\nTesting qh_setcompact and qh_setcopy 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(qh, ints, "j", j, numInts, checkEvery)){
+ for(i= qh_setsize(qh, ints); i<j; i++){ /* Test i<j to test the empty set */
+ for(k= 0; k<i%7; k++){
+ qh_setappend(qh, &ints, NULL);
+ }
+ qh_setappend(qh, &ints, intarray+i);
+ }
+ qh_setfree(qh, &ints2);
+ ints2= qh_setcopy(qh, ints, 0);
+ qh_setcompact(qh, ints);
+ qh_setcompact(qh, ints2);
+ checkSetContents(qh, "qh_setcompact", ints, j, 0, 0, -1);
+ checkSetContents(qh, "qh_setcompact", ints2, j, 0, 0, -1);
+ qh_setcompact(qh, ints);
+ checkSetContents(qh, "qh_setcompact", ints, j, 0, 0, -1);
+ }
+ }
+ qh_setfree(qh, &ints);
+ qh_setfree(qh, &ints2);
+}/*testSetcompactCopy*/
+
+void testSetdelsortedEtc(qhT *qh, int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= qh_setnew(qh, 1);
+ setT *ints2= NULL;
+ int i,j;
+
+ qh_fprintf(qh, stderr, 8018, "\n\nTesting qh_setdel*, qh_setaddsorted, and 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(qh, ints, "j", j, numInts, checkEvery)){
+ for(i= qh_setsize(qh, ints); i<j; i++){ /* Test i<j to test the empty set */
+ qh_setaddsorted(qh, &ints, intarray+i);
+ }
+ checkSetContents(qh, "qh_setaddsorted", ints, j, 0, 0, -1);
+ if(j>3){
+ qh_setdelsorted(ints, intarray+i/2);
+ checkSetContents(qh, "qh_setdelsorted", ints, j-1, 0, i/2+1, -1);
+ qh_setaddsorted(qh, &ints, intarray+i/2);
+ checkSetContents(qh, "qh_setaddsorted i/2", ints, j, 0, 0, -1);
+ }
+ qh_setdellast(ints);
+ checkSetContents(qh, "qh_setdellast", ints, (j ? j-1 : 0), 0, -1, -1);
+ if(j>0){
+ qh_setaddsorted(qh, &ints, intarray+j-1);
+ checkSetContents(qh, "qh_setaddsorted j-1", ints, j, 0, -1, -1);
+ }
+ if(j>4){
+ qh_setdelnthsorted(qh, ints, i/2);
+ if (checkEvery==1)
+ checkSetContents(qh, "qh_setdelnthsorted", ints, j-1, 0, i/2+1, -1);
+ /* test qh_setdelnth and move-to-front */
+ qh_setdelsorted(ints, intarray+i/2+1);
+ checkSetContents(qh, "qh_setdelsorted 2", ints, j-2, 0, i/2+2, -1);
+ qh_setaddsorted(qh, &ints, intarray+i/2+1);
+ if (checkEvery==1)
+ checkSetContents(qh, "qh_setaddsorted i/2+1", ints, j-1, 0, i/2+1, -1);
+ qh_setaddsorted(qh, &ints, intarray+i/2);
+ checkSetContents(qh, "qh_setaddsorted i/2 again", ints, j, 0, -1, -1);
+ }
+ qh_setfree(qh, &ints2);
+ ints2= qh_setcopy(qh, ints, 0);
+ qh_setcompact(qh, ints);
+ qh_setcompact(qh, ints2);
+ checkSetContents(qh, "qh_setcompact", ints, j, 0, 0, -1);
+ checkSetContents(qh, "qh_setcompact 2", ints2, j, 0, 0, -1);
+ qh_setcompact(qh, ints);
+ checkSetContents(qh, "qh_setcompact 3", ints, j, 0, 0, -1);
+ qh_setfree(qh, &ints2);
+ }
+ }
+ qh_setfreelong(qh, &ints);
+ if(ints){
+ qh_setfree(qh, &ints); /* Was quick memory */
+ }
+}/*testSetdelsortedEtc*/
+
+void testSetequalInEtc(qhT *qh, int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= NULL;
+ setT *ints2= NULL;
+ setT *ints3= NULL;
+ int i,j,n;
+
+ qh_fprintf(qh, stderr, 8019, "\n\nTesting qh_setequal*, qh_setin*, qh_setdel, qh_setdelnth, and qh_setlarger 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(qh, ints, "j", j, numInts, checkEvery)){
+ n= qh_setsize(qh, ints);
+ qh_setlarger(qh, &ints);
+ checkSetContents(qh, "qh_setlarger", ints, n, 0, -1, -1);
+ for(i= qh_setsize(qh, ints); i<j; i++){ /* Test i<j to test the empty set */
+ qh_setappend(qh, &ints, intarray+i);
+ }
+ checkSetContents(qh, "qh_setappend", ints, j, 0, -1, -1);
+ if(!qh_setequal(ints, ints)){
+ qh_fprintf(qh, stderr, 6300, "testSetequalInEtc: set not equal to itself at length %d\n", j);
+ error_count++;
+ }
+ if(j==0 && !qh_setequal(ints, ints2)){
+ qh_fprintf(qh, stderr, 6323, "testSetequalInEtc: empty set not equal to null set\n");
+ error_count++;
+ }
+ if(j>0){
+ if(qh_setequal(ints, ints2)){
+ qh_fprintf(qh, stderr, 6324, "testSetequalInEtc: non-empty set equal to empty set\n", j);
+ error_count++;
+ }
+ qh_setfree(qh, &ints3);
+ ints3= qh_setcopy(qh, ints, 0);
+ checkSetContents(qh, "qh_setreplace", ints3, j, 0, -1, -1);
+ qh_setreplace(qh, ints3, intarray+j/2, intarray+j/2+1);
+ if(j==1){
+ checkSetContents(qh, "qh_setreplace 2", ints3, j, j/2+1, -1, -1);
+ }else if(j==2){
+ checkSetContents(qh, "qh_setreplace 3", ints3, j, 0, j/2+1, -1);
+ }else{
+ checkSetContents(qh, "qh_setreplace 3", ints3, j, 0, j/2+1, j/2+1);
+ }
+ if(qh_setequal(ints, ints3)){
+ qh_fprintf(qh, stderr, 6325, "testSetequalInEtc: modified set equal to original set at %d/2\n", j);
+ error_count++;
+ }
+ if(!qh_setequal_except(ints, intarray+j/2, ints3, intarray+j/2+1)){
+ qh_fprintf(qh, stderr, 6326, "qh_setequal_except: modified set not equal to original set except modified\n", j);
+ error_count++;
+ }
+ if(qh_setequal_except(ints, intarray+j/2, ints3, intarray)){
+ qh_fprintf(qh, stderr, 6327, "qh_setequal_except: modified set equal to original set with wrong excepts\n", j);
+ error_count++;
+ }
+ if(!qh_setequal_skip(ints, j/2, ints3, j/2)){
+ qh_fprintf(qh, stderr, 6328, "qh_setequal_skip: modified set not equal to original set except modified\n", j);
+ error_count++;
+ }
+ if(j>2 && qh_setequal_skip(ints, j/2, ints3, 0)){
+ qh_fprintf(qh, stderr, 6329, "qh_setequal_skip: modified set equal to original set with wrong excepts\n", j);
+ error_count++;
+ }
+ if(intarray+j/2+1!=qh_setdel(ints3, intarray+j/2+1)){
+ qh_fprintf(qh, stderr, 6330, "qh_setdel: failed to find added element\n", j);
+ error_count++;
+ }
+ checkSetContents(qh, "qh_setdel", ints3, j-1, 0, j-1, (j==1 ? -1 : j/2+1)); /* swaps last element with deleted element */
+ if(j>3){
+ qh_setdelnth(qh, ints3, j/2); /* Delete at the same location as the original replace, for only one out-of-order element */
+ checkSetContents(qh, "qh_setdelnth", ints3, j-2, 0, j-2, (j==2 ? -1 : j/2+1));
+ }
+ if(qh_setin(ints3, intarray+j/2)){
+ qh_fprintf(qh, stderr, 6331, "qh_setin: found deleted element\n");
+ error_count++;
+ }
+ if(j>4 && !qh_setin(ints3, intarray+1)){
+ qh_fprintf(qh, stderr, 6332, "qh_setin: did not find second element\n");
+ error_count++;
+ }
+ if(j>4 && !qh_setin(ints3, intarray+j-2)){
+ qh_fprintf(qh, stderr, 6333, "qh_setin: did not find last element\n");
+ error_count++;
+ }
+ if(-1!=qh_setindex(ints2, intarray)){
+ qh_fprintf(qh, stderr, 6334, "qh_setindex: found element in empty set\n");
+ error_count++;
+ }
+ if(-1!=qh_setindex(ints3, intarray+j/2)){
+ qh_fprintf(qh, stderr, 6335, "qh_setindex: found deleted element in set\n");
+ error_count++;
+ }
+ if(0!=qh_setindex(ints, intarray)){
+ qh_fprintf(qh, stderr, 6336, "qh_setindex: did not find first in set\n");
+ error_count++;
+ }
+ if(j-1!=qh_setindex(ints, intarray+j-1)){
+ qh_fprintf(qh, stderr, 6337, "qh_setindex: did not find last in set\n");
+ error_count++;
+ }
+ }
+ qh_setfree(qh, &ints2);
+ }
+ }
+ qh_setfree(qh, &ints3);
+ qh_setfreelong(qh, &ints);
+ if(ints){
+ qh_setfree(qh, &ints); /* Was quick memory */
+ }
+}/*testSetequalInEtc*/
+
+
+void testSetlastEtc(qhT *qh, int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= NULL;
+ setT *ints2= NULL;
+ int i,j,prepend;
+
+ qh_fprintf(qh, stderr, 8020, "\n\nTesting qh_setlast, qh_setnew_delnthsorted, qh_setunique, and qh_setzero 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(qh, ints, "j", j, numInts, checkEvery)){
+ for(i= qh_setsize(qh, ints); i<j; i++){ /* Test i<j to test the empty set */
+ if(!qh_setunique(qh, &ints, intarray+i)){
+ qh_fprintf(qh, stderr, 6340, "qh_setunique: not able to append next element %d\n", i);
+ error_count++;
+ }
+ if(checkEvery==1){
+ checkSetContents(qh, "qh_setunique", ints, i+1, 0, -1, -1);
+ }
+ if(qh_setunique(qh, &ints, intarray+i)){
+ qh_fprintf(qh, stderr, 6341, "qh_setunique: appended next element twice %d\n", i);
+ error_count++;
+ }
+ if(qh_setunique(qh, &ints, intarray+i/2)){
+ qh_fprintf(qh, stderr, 6346, "qh_setunique: appended middle element twice %d/2\n", i);
+ error_count++;
+ }
+ }
+ checkSetContents(qh, "qh_setunique 2", ints, j, 0, -1, -1);
+ if(j==0 && NULL!=qh_setlast(ints)){
+ qh_fprintf(qh, stderr, 6339, "qh_setlast: returned last element of empty set\n");
+ error_count++;
+ }
+ if(j>0){
+ if(intarray+j-1!=qh_setlast(ints)){
+ qh_fprintf(qh, stderr, 6338, "qh_setlast: wrong last element\n");
+ error_count++;
+ }
+ prepend= (j<100 ? j/4 : 0);
+ ints2= qh_setnew_delnthsorted(qh, ints, qh_setsize(qh, ints), j/2, prepend);
+ if(qh_setsize(qh, ints2)!=j+prepend-1){
+ qh_fprintf(qh, stderr, 6345, "qh_setnew_delnthsorted: Expecting %d elements, got %d\n", j+prepend-1, qh_setsize(qh, ints2));
+ error_count++;
+ }
+ /* Define prepended elements. Otherwise qh_setdelnthsorted may fail */
+ for(i= 0; i<prepend; i++){
+ void **p= &SETelem_(ints2, i);
+ *p= intarray+0;
+ }
+ for(i= 0; i<prepend; i++){
+ qh_setdelnthsorted(qh, ints2, 0); /* delete undefined prefix */
+ }
+ checkSetContents(qh, "qh_setnew_delnthsorted", ints2, j-1, 0, j/2+1, -1);
+ if(j>2){
+ qh_setzero(qh, ints2, j/2, j-1); /* max size may be j-1 */
+ if(qh_setsize(qh, ints2)!=j-1){
+ qh_fprintf(qh, stderr, 6342, "qh_setzero: Expecting %d elements, got %d\n", j, qh_setsize(qh, ints2));
+ error_count++;
+ }
+ qh_setcompact(qh, ints2);
+ checkSetContents(qh, "qh_setzero", ints2, j/2, 0, -1, -1);
+ }
+ }
+ qh_setfree(qh, &ints2);
+ }
+ }
+ qh_setfreelong(qh, &ints);
+ if(ints){
+ qh_setfree(qh, &ints); /* Was quick memory */
+ }
+}/*testSetlastEtc*/
+
+void testSettemp(qhT *qh, int numInts, int *intarray, int checkEvery)
+{
+ setT *ints= NULL;
+ setT *ints2= NULL;
+ setT *ints3= NULL;
+ int i,j;
+
+ qh_fprintf(qh, stderr, 8021, "\n\nTesting qh_settemp* 0..%d. Test", numInts-1);
+ for(j=0; j<numInts; j++){
+ if(log_i(qh, ints, "j", j, numInts, checkEvery)){
+ if(j<20){
+ for(i=0; i<j; i++){
+ ints2= qh_settemp(qh, j);
+ }
+ qh_settempfree_all(qh);
+ }
+ for(i= qh_setsize(qh, ints); i<j; i++){ /* Test i<j to test the empty set */
+ qh_setappend(qh, &ints, intarray+i);
+ }
+ ints2= qh_settemp(qh, j);
+ if(j>0){
+ qh_settemppush(qh, ints);
+ ints3= qh_settemppop(qh);
+ if(ints!=ints3){
+ qh_fprintf(qh, stderr, 6343, "qh_settemppop: didn't pop the push\n");
+ error_count++;
+ }
+ }
+ qh_settempfree(qh, &ints2);
+ }
+ }
+ qh_setfreelong(qh, &ints);
+ if(ints){
+ qh_setfree(qh, &ints); /* Was quick memory */
+ }
+}/*testSettemp*/
+
+/* Check that a set contains count elements
+ Ranges are consecutive (e.g., 1,2,3,...) starting with first, mid, and last
+ Use -1 for missing ranges
+ Returns -1 if should check results
+*/
+int log_i(qhT *qh, setT *set, const char *s, int i, int numInts, int checkEvery)
+{
+ int j= i;
+ int scale= 1;
+ int e= 0;
+ int *i2, **i2p;
+
+ if(*s || checkEvery==1){
+ if(i<10){
+ qh_fprintf(qh, stderr, 8004, " %s%d", s, i);
+ }else{
+ if(i==11 && checkEvery==1){
+ qh_fprintf(qh, stderr, 8005, "\nResults after 10: ");
+ FOREACHint_(set){
+ qh_fprintf(qh, stderr, 8006, " %d", *i2);
+ }
+ qh_fprintf(qh, stderr, 8007, " Continue");
+ }
+ while((j= j/10)>=1){
+ scale *= 10;
+ e++;
+ }
+ if(i==numInts-1){
+ qh_fprintf(qh, stderr, 8008, " %s%d", s, i);
+ }else if(i==scale){
+ if(i<=1000){
+ qh_fprintf(qh, stderr, 8010, " %s%d", s, i);
+ }else{
+ qh_fprintf(qh, stderr, 8009, " %s1e%d", s, e);
+ }
+ }
+ }
+ }
+ if(i<1000 || i%checkEvery==0 || i== scale || i==numInts-1){
+ return 1;
+ }
+ return 0;
+}/*log_i*/
+
+/* Check that a set contains count elements
+ Ranges are consecutive (e.g., 1,2,3,...) starting with first, mid, and last
+ Use -1 for missing ranges
+*/
+void checkSetContents(qhT *qh, const char *name, setT *set, int count, int rangeA, int rangeB, int rangeC)
+{
+
+ i2T *i2, **i2p;
+ int i2_i, i2_n;
+ int prev= -1; /* avoid warning */
+ int i;
+ int first= -3;
+ int second= -3;
+ int rangeCount=1;
+ int actualSize= 0;
+
+ qh_setcheck(qh, set, name, 0);
+ if(set){
+ SETreturnsize_(set, actualSize); /* normally used only when speed is critical */
+ if(*qh_setendpointer(set)!=NULL){
+ qh_fprintf(qh, stderr, 6344, "%s: qh_setendpointer(set), 0x%x, is not NULL terminator of set 0x%x", name, qh_setendpointer(set), set);
+ error_count++;
+ }
+ }
+ if(actualSize!=qh_setsize(qh, set)){
+ qh_fprintf(qh, stderr, 6305, "%s: SETreturnsize_(qh) returned %d while qh_setsize(qh) returns %d\n", name, actualSize, qh_setsize(qh, set));
+ error_count++;
+ }else if(actualSize!=count){
+ qh_fprintf(qh, stderr, 6306, "%s: Expecting %d elements for set. Got %d elements\n", name, count, actualSize);
+ error_count++;
+ }
+ if(SETempty_(set)){
+ if(count!=0){
+ qh_fprintf(qh, stderr, 6307, "%s: Got empty set instead of count %d, rangeA %d, rangeB %d, rangeC %d\n", name, count, rangeA, rangeB, rangeC);
+ error_count++;
+ }
+ }else{
+ /* Must be first, otherwise trips msvc 8 */
+ i2T **p= SETaddr_(set, i2T);
+ if(*p!=SETfirstt_(set, i2T)){
+ qh_fprintf(qh, stderr, 6309, "%s: SETaddr_(set, i2t) [%p] is not the same as SETfirst_(set) [%p]\n", name, SETaddr_(set, i2T), SETfirst_(set));
+ error_count++;
+ }
+ first= *(int *)SETfirst_(set);
+ if(SETfirst_(set)!=SETfirstt_(set, i2T)){
+ qh_fprintf(qh, stderr, 6308, "%s: SETfirst_(set) [%p] is not the same as SETfirstt_(set, i2T [%p]\n", name, SETfirst_(set), SETfirstt_(set, i2T));
+ error_count++;
+ }
+ if(qh_setsize(qh, set)>1){
+ second= *(int *)SETsecond_(set);
+ if(SETsecond_(set)!=SETsecondt_(set, i2T)){
+ qh_fprintf(qh, stderr, 6310, "%s: SETsecond_(set) [%p] is not the same as SETsecondt_(set, i2T) [%p]\n", name, SETsecond_(set), SETsecondt_(set, i2T));
+ error_count++;
+ }
+ }
+ }
+ /* Test first run of ints in set*/
+ i= 0;
+ FOREACHint_(set){
+ if(i2!=SETfirst_(set) && *i2!=prev+1){
+ break;
+ }
+ prev= *i2;
+ if(SETindex_(set, i2)!=i){
+ qh_fprintf(qh, stderr, 6311, "%s: Expecting SETindex_(set, pointer-to-%d) to be %d. Got %d\n", name, *i2, i, SETindex_(set, i2));
+ error_count++;;
+ }
+ if(i2!=SETref_(i2)){
+ qh_fprintf(qh, stderr, 6312, "%s: SETref_(i2) [%p] does not point to i2 (the %d'th element)\n", name, SETref_(i2), i);
+ error_count++;;
+ }
+ i++;
+ }
+ FOREACHint_i_(qh, set){
+ /* Must be first conditional, otherwise it trips up msvc 8 */
+ i2T **p= SETelemaddr_(set, i2_i, i2T);
+ if(i2!=*p){
+ qh_fprintf(qh, stderr, 6320, "%s: SETelemaddr_(set, %d, i2T) [%p] does not point to i2\n", name, i2_i, SETelemaddr_(set, i2_i, int));
+ error_count++;;
+ }
+ if(i2_i==0){
+ if(first!=*i2){
+ qh_fprintf(qh, stderr, 6314, "%s: First element is %d instead of SETfirst %d\n", name, *i2, first);
+ error_count++;;
+ }
+ if(rangeA!=*i2){
+ qh_fprintf(qh, stderr, 6315, "%s: starts with %d instead of rangeA %d\n", name, *i2, rangeA);
+ error_count++;;
+ }
+ prev= rangeA;
+ }else{
+ if(i2_i==1 && second!=*i2){
+ qh_fprintf(qh, stderr, 6316, "%s: Second element is %d instead of SETsecond %d\n", name, *i2, second);
+ error_count++;;
+ }
+ if(prev+1==*i2){
+ prev++;
+ }else{
+ if(*i2==rangeB){
+ prev= rangeB;
+ rangeB= -1;
+ rangeCount++;
+ }else if(rangeB==-1 && *i2==rangeC){
+ prev= rangeC;
+ rangeC= -1;
+ rangeCount++;
+ }else{
+ prev++;
+ qh_fprintf(qh, stderr, 6317, "%s: Expecting %d'th element to be %d. Got %d\n", name, i2_i, prev, *i2);
+ error_count++;
+ }
+ }
+ }
+ if(i2!=SETelem_(set, i2_i)){
+ qh_fprintf(qh, stderr, 6318, "%s: SETelem_(set, %d) [%p] is not i2 [%p] (the %d'th element)\n", name, i2_i, SETelem_(set, i2_i), i2, i2_i);
+ error_count++;;
+ }
+ if(SETelemt_(set, i2_i, i2T)!=SETelem_(set, i2_i)){ /* Normally SETelemt_ is used for generic sets */
+ qh_fprintf(qh, stderr, 6319, "%s: SETelemt_(set, %d, i2T) [%p] is not SETelem_(set, %d) [%p] (the %d'th element)\n", name, i2_i, SETelemt_(set, i2_i, int), i2_i, SETelem_(set, i2_i), i2_i);
+ error_count++;;
+ }
+ }
+ if(error_count>=MAXerrorCount){
+ qh_fprintf(qh, stderr, 8011, "testqset: Stop testing after %d errors\n", error_count);
+ exit(1);
+ }
+}/*checkSetContents*/
+
diff --git a/xs/src/qhull/src/testqset_r/testqset_r.pro b/xs/src/qhull/src/testqset_r/testqset_r.pro
new file mode 100644
index 000000000..951e0624e
--- /dev/null
+++ b/xs/src/qhull/src/testqset_r/testqset_r.pro
@@ -0,0 +1,30 @@
+# -------------------------------------------------
+# testqset_r.pro -- Qt project file for testqset_r.exe
+# -------------------------------------------------
+
+include(../qhull-warn.pri)
+
+TARGET = testqset_r
+
+DESTDIR = ../../bin
+TEMPLATE = app
+CONFIG += console warn_on
+CONFIG -= qt
+CONFIG += qhull_warn_conversion
+
+build_pass:CONFIG(debug, debug|release){
+ OBJECTS_DIR = Debug
+}else:build_pass:CONFIG(release, debug|release){
+ OBJECTS_DIR = Release
+}
+
+INCLUDEPATH += ..
+
+SOURCES += testqset_r.c
+SOURCES += ../libqhull_r/qset_r.c
+SOURCES += ../libqhull_r/mem_r.c
+SOURCES += ../libqhull_r/usermem_r.c
+
+HEADERS += ../libqhull_r/mem_r.h
+HEADERS += ../libqhull_r/qset_r.h
+
diff --git a/xs/src/qhull/src/user_eg/user_eg.c b/xs/src/qhull/src/user_eg/user_eg.c
new file mode 100644
index 000000000..9c5fee51b
--- /dev/null
+++ b/xs/src/qhull/src/user_eg/user_eg.c
@@ -0,0 +1,330 @@
+/*<html><pre> -<a href="../libqhull/qh-user.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ user_eg.c
+ sample code for calling qhull() from an application
+
+ call with:
+
+ user_eg "cube/diamond options" "delaunay options" "halfspace options"
+
+ for example:
+
+ user_eg # return summaries
+
+ user_eg "n" "o" "Fp" # return normals, OFF, points
+
+ user_eg "n Qt" "o" "Fp" # triangulated cube
+
+ user_eg "QR0 p" "QR0 v p" "QR0 Fp" # rotate input and return points
+ # 'v' returns Voronoi
+ # transform is rotated for halfspaces
+
+ main() makes three runs of qhull.
+
+ 1) compute the convex hull of a cube
+
+ 2a) compute the Delaunay triangulation of random points
+
+ 2b) find the Delaunay triangle closest to a point.
+
+ 3) compute the halfspace intersection of a diamond
+
+ notes:
+
+ For another example, see main() in unix.c and user_eg2.c.
+ These examples, call qh_qhull() directly. They allow
+ tighter control on the code loaded with Qhull.
+
+ For a C++ example, see user_eg3/user_eg3_r.cpp
+
+ Summaries are sent to stderr if other output formats are used
+
+ compiled by 'make bin/user_eg'
+
+ see libqhull.h for data structures, macros, and user-callable functions.
+*/
+
+#define qh_QHimport
+#include "libqhull/qhull_a.h"
+
+/*-------------------------------------------------
+-internal function prototypes
+*/
+void print_summary(void);
+void makecube(coordT *points, int numpoints, int dim);
+void makeDelaunay(coordT *points, int numpoints, int dim, int seed);
+void findDelaunay(int dim);
+void makehalf(coordT *points, int numpoints, int dim);
+
+/*-------------------------------------------------
+-print_summary()
+*/
+void print_summary(void) {
+ facetT *facet;
+ int k;
+
+ printf("\n%d vertices and %d facets with normals:\n",
+ qh num_vertices, qh num_facets);
+ FORALLfacets {
+ for (k=0; k < qh hull_dim; k++)
+ printf("%6.2g ", facet->normal[k]);
+ printf("\n");
+ }
+}
+
+/*--------------------------------------------------
+-makecube- set points to vertices of cube
+ points is numpoints X dim
+*/
+void makecube(coordT *points, int numpoints, int dim) {
+ int j,k;
+ coordT *point;
+
+ for (j=0; j<numpoints; j++) {
+ point= points + j*dim;
+ for (k=dim; k--; ) {
+ if (j & ( 1 << k))
+ point[k]= 1.0;
+ else
+ point[k]= -1.0;
+ }
+ }
+} /*.makecube.*/
+
+/*--------------------------------------------------
+-makeDelaunay- set points for dim Delaunay triangulation of random points
+ points is numpoints X dim.
+notes:
+ makeDelaunay() in user_eg2.c uses qh_setdelaunay() to project points in place.
+*/
+void makeDelaunay(coordT *points, int numpoints, int dim, int seed) {
+ int j,k;
+ coordT *point, realr;
+
+ printf("seed: %d\n", seed);
+ qh_RANDOMseed_( seed);
+ for (j=0; j<numpoints; j++) {
+ point= points + j*dim;
+ for (k= 0; k < dim; k++) {
+ realr= qh_RANDOMint;
+ point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
+ }
+ }
+} /*.makeDelaunay.*/
+
+/*--------------------------------------------------
+-findDelaunay- find Delaunay triangle for [0.5,0.5,...]
+ assumes dim < 100
+notes:
+ calls qh_setdelaunay() to project the point to a parabaloid
+warning:
+ This is not implemented for tricoplanar facets ('Qt'),
+ See <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
+*/
+void findDelaunay(int dim) {
+ int k;
+ coordT point[ 100];
+ boolT isoutside;
+ realT bestdist;
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+
+ for (k= 0; k < dim; k++)
+ point[k]= 0.5;
+ qh_setdelaunay(dim+1, 1, point);
+ facet= qh_findbestfacet(point, qh_ALL, &bestdist, &isoutside);
+ if (facet->tricoplanar) {
+ fprintf(stderr, "findDelaunay: not implemented for triangulated, non-simplicial Delaunay regions (tricoplanar facet, f%d).\n",
+ facet->id);
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ FOREACHvertex_(facet->vertices) {
+ for (k=0; k < dim; k++)
+ printf("%5.2f ", vertex->point[k]);
+ printf("\n");
+ }
+} /*.findDelaunay.*/
+
+/*--------------------------------------------------
+-makehalf- set points to halfspaces for a (dim)-dimensional diamond
+ points is numpoints X dim+1
+
+ each halfspace consists of dim coefficients followed by an offset
+*/
+void makehalf(coordT *points, int numpoints, int dim) {
+ int j,k;
+ coordT *point;
+
+ for (j=0; j<numpoints; j++) {
+ point= points + j*(dim+1);
+ point[dim]= -1.0; /* offset */
+ for (k=dim; k--; ) {
+ if (j & ( 1 << k))
+ point[k]= 1.0;
+ else
+ point[k]= -1.0;
+ }
+ }
+} /*.makehalf.*/
+
+#define DIM 3 /* dimension of points, must be < 31 for SIZEcube */
+#define SIZEcube (1<<DIM)
+#define SIZEdiamond (2*DIM)
+#define TOTpoints (SIZEcube + SIZEdiamond)
+
+/*--------------------------------------------------
+-main- derived from Qhull-template in user.c
+
+ see program header
+
+ this contains three runs of Qhull for convex hull, Delaunay
+ triangulation or Voronoi vertices, and halfspace intersection
+
+*/
+int main(int argc, char *argv[]) {
+ int dim= DIM; /* dimension of points */
+ int numpoints; /* number of points */
+ coordT points[(DIM+1)*TOTpoints]; /* array of coordinates for each point */
+ coordT *rows[TOTpoints];
+ boolT ismalloc= False; /* True if qhull should free points in qh_freeqhull() or reallocation */
+ char flags[250]; /* option flags for qhull, see qh-quick.htm */
+ FILE *outfile= stdout; /* output from qh_produce_output()
+ use NULL to skip qh_produce_output() */
+ FILE *errfile= stderr; /* error messages from qhull code */
+ int exitcode; /* 0 if no error from qhull */
+ facetT *facet; /* set by FORALLfacets */
+ int curlong, totlong; /* memory remaining after qh_memfreeshort */
+ int i;
+
+ QHULL_LIB_CHECK
+
+ printf("This is the output from user_eg.c\n\n\
+It shows how qhull() may be called from an application using the qhull\n\
+shared library. user_eg is not part of qhull itself. If it appears\n\
+accidently, please remove user_eg.c from your project. If it fails\n\
+immediately, user_eg.c was incorrectly linked to the reentrant library.\n\
+Also try 'user_eg T1 2>&1'\n\n");
+
+#if qh_QHpointer /* see user.h */
+ if (qh_qh){
+ printf("QH6233: Qhull link error. The global variable qh_qh was not initialized\n\
+to NULL by global.c. Please compile user_eg.c with -Dqh_QHpointer_dllimport\n\
+as well as -Dqh_QHpointer, or use libqhullstatic, or use a different tool chain.\n\n");
+ return -1;
+ }
+#endif
+
+ /*
+ Run 1: convex hull
+ */
+ printf( "\ncompute convex hull of cube after rotating input\n");
+ sprintf(flags, "qhull s Tcv %s", argc >= 2 ? argv[1] : "");
+ numpoints= SIZEcube;
+ makecube(points, numpoints, DIM);
+ for (i=numpoints; i--; )
+ rows[i]= points+dim*i;
+ qh_printmatrix(outfile, "input", rows, numpoints, dim);
+ exitcode= qh_new_qhull(dim, numpoints, points, ismalloc,
+ flags, outfile, errfile);
+ if (!exitcode) { /* if no error */
+ /* 'qh facet_list' contains the convex hull */
+ print_summary();
+ FORALLfacets {
+ /* ... your code ... */
+ }
+ }
+ qh_freeqhull(!qh_ALL); /* free long memory */
+ qh_memfreeshort(&curlong, &totlong); /* free short memory and memory allocator */
+ if (curlong || totlong)
+ fprintf(errfile, "qhull internal warning (user_eg, #1): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
+
+ /*
+ Run 2: Delaunay triangulation
+ */
+
+ printf( "\ncompute %d-d Delaunay triangulation\n", dim);
+ sprintf(flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
+ numpoints= SIZEcube;
+ makeDelaunay(points, numpoints, dim, (int)time(NULL));
+ for (i=numpoints; i--; )
+ rows[i]= points+dim*i;
+ qh_printmatrix(outfile, "input", rows, numpoints, dim);
+ exitcode= qh_new_qhull(dim, numpoints, points, ismalloc,
+ flags, outfile, errfile);
+ if (!exitcode) { /* if no error */
+ /* 'qh facet_list' contains the convex hull */
+ /* If you want a Voronoi diagram ('v') and do not request output (i.e., outfile=NULL),
+ call qh_setvoronoi_all() after qh_new_qhull(). */
+ print_summary();
+ FORALLfacets {
+ /* ... your code ... */
+ }
+ printf( "\nfind %d-d Delaunay triangle closest to [0.5, 0.5, ...]\n", dim);
+ exitcode= setjmp(qh errexit);
+ if (!exitcode) {
+ /* Trap Qhull errors in findDelaunay(). Without the setjmp(), Qhull
+ will exit() after reporting an error */
+ qh NOerrexit= False;
+ findDelaunay(DIM);
+ }
+ qh NOerrexit= True;
+ }
+#if qh_QHpointer /* see user.h */
+ {
+ qhT *oldqhA, *oldqhB;
+ coordT pointsB[DIM*TOTpoints]; /* array of coordinates for each point */
+
+ printf( "\nsave first triangulation and compute a new triangulation\n");
+ oldqhA= qh_save_qhull();
+ sprintf(flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
+ numpoints= SIZEcube;
+ makeDelaunay(pointsB, numpoints, dim, (int)time(NULL)+1);
+ for (i=numpoints; i--; )
+ rows[i]= pointsB+dim*i;
+ qh_printmatrix(outfile, "input", rows, numpoints, dim);
+ exitcode= qh_new_qhull(dim, numpoints, pointsB, ismalloc,
+ flags, outfile, errfile);
+ if (!exitcode)
+ print_summary();
+ printf( "\nsave second triangulation and restore first one\n");
+ oldqhB= qh_save_qhull();
+ qh_restore_qhull(&oldqhA);
+ print_summary();
+ printf( "\nfree first triangulation and restore second one.\n");
+ qh_freeqhull(qh_ALL); /* free short and long memory used by first call */
+ /* do not use qh_memfreeshort */
+ qh_restore_qhull(&oldqhB);
+ print_summary();
+ }
+#endif
+ qh_freeqhull(!qh_ALL); /* free long memory */
+ qh_memfreeshort(&curlong, &totlong); /* free short memory and memory allocator */
+ if (curlong || totlong)
+ fprintf(errfile, "qhull internal warning (user_eg, #2): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
+
+ /*
+ Run 3: halfspace intersection about the origin
+ */
+ printf( "\ncompute halfspace intersection about the origin for a diamond\n");
+ sprintf(flags, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "Fp");
+ numpoints= SIZEcube;
+ makehalf(points, numpoints, dim);
+ for (i=numpoints; i--; )
+ rows[i]= points+(dim+1)*i;
+ qh_printmatrix(outfile, "input as halfspace coefficients + offsets", rows, numpoints, dim+1);
+ /* use qh_sethalfspace_all to transform the halfspaces yourself.
+ If so, set 'qh feasible_point and do not use option 'Hn,...' [it would retransform the halfspaces]
+ */
+ exitcode= qh_new_qhull(dim+1, numpoints, points, ismalloc,
+ flags, outfile, errfile);
+ if (!exitcode)
+ print_summary();
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
+ if (curlong || totlong) /* could also check previous runs */
+ fprintf(stderr, "qhull internal warning (user_eg, #3): did not free %d bytes of long memory (%d pieces)\n",
+ totlong, curlong);
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/user_eg/user_eg.pro b/xs/src/qhull/src/user_eg/user_eg.pro
new file mode 100644
index 000000000..9dda01009
--- /dev/null
+++ b/xs/src/qhull/src/user_eg/user_eg.pro
@@ -0,0 +1,11 @@
+# -------------------------------------------------
+# user_eg.pro -- Qt project for Qhull demonstration using shared Qhull library
+#
+# It uses reentrant Qhull
+# -------------------------------------------------
+
+include(../qhull-app-shared_r.pri)
+
+TARGET = user_eg
+
+SOURCES += user_eg_r.c
diff --git a/xs/src/qhull/src/user_eg/user_eg_r.c b/xs/src/qhull/src/user_eg/user_eg_r.c
new file mode 100644
index 000000000..21b0ccf4e
--- /dev/null
+++ b/xs/src/qhull/src/user_eg/user_eg_r.c
@@ -0,0 +1,326 @@
+/*<html><pre> -<a href="../libqhull_r/qh-user_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ user_eg_r.c
+ sample code for calling qhull() from an application. Uses reentrant libqhull_r
+
+ call with:
+
+ user_eg "cube/diamond options" "delaunay options" "halfspace options"
+
+ for example:
+
+ user_eg # return summaries
+
+ user_eg "n" "o" "Fp" # return normals, OFF, points
+
+ user_eg "n Qt" "o" "Fp" # triangulated cube
+
+ user_eg "QR0 p" "QR0 v p" "QR0 Fp" # rotate input and return points
+ # 'v' returns Voronoi
+ # transform is rotated for halfspaces
+
+ main() makes three runs of qhull.
+
+ 1) compute the convex hull of a cube
+
+ 2a) compute the Delaunay triangulation of random points
+
+ 2b) find the Delaunay triangle closest to a point.
+
+ 3) compute the halfspace intersection of a diamond
+
+ notes:
+
+ For another example, see main() in unix_r.c and user_eg2_r.c.
+ These examples, call qh_qhull() directly. They allow
+ tighter control on the code loaded with Qhull.
+
+ For a C++ example, see user_eg3/user_eg3_r.cpp
+
+ Summaries are sent to stderr if other output formats are used
+
+ compiled by 'make bin/user_eg'
+
+ see libqhull.h for data structures, macros, and user-callable functions.
+*/
+
+#define qh_QHimport
+#include "libqhull_r/qhull_ra.h"
+
+/*-------------------------------------------------
+-internal function prototypes
+*/
+void print_summary(qhT *qh);
+void makecube(coordT *points, int numpoints, int dim);
+void makeDelaunay(qhT *qh, coordT *points, int numpoints, int dim, int seed);
+void findDelaunay(qhT *qh, int dim);
+void makehalf(coordT *points, int numpoints, int dim);
+
+/*-------------------------------------------------
+-print_summary(qh)
+*/
+void print_summary(qhT *qh) {
+ facetT *facet;
+ int k;
+
+ printf("\n%d vertices and %d facets with normals:\n",
+ qh->num_vertices, qh->num_facets);
+ FORALLfacets {
+ for (k=0; k < qh->hull_dim; k++)
+ printf("%6.2g ", facet->normal[k]);
+ printf("\n");
+ }
+}
+
+/*--------------------------------------------------
+-makecube- set points to vertices of cube
+ points is numpoints X dim
+*/
+void makecube(coordT *points, int numpoints, int dim) {
+ int j,k;
+ coordT *point;
+
+ for (j=0; j<numpoints; j++) {
+ point= points + j*dim;
+ for (k=dim; k--; ) {
+ if (j & ( 1 << k))
+ point[k]= 1.0;
+ else
+ point[k]= -1.0;
+ }
+ }
+} /*.makecube.*/
+
+/*--------------------------------------------------
+-makeDelaunay- set points for dim Delaunay triangulation of random points
+ points is numpoints X dim.
+notes:
+ makeDelaunay() in user_eg2.c uses qh_setdelaunay() to project points in place.
+*/
+void makeDelaunay(qhT *qh, coordT *points, int numpoints, int dim, int seed) {
+ int j,k;
+ coordT *point, realr;
+
+ printf("seed: %d\n", seed);
+ qh_RANDOMseed_(qh, seed);
+ for (j=0; j<numpoints; j++) {
+ point= points + j*dim;
+ for (k= 0; k < dim; k++) {
+ realr= qh_RANDOMint;
+ point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
+ }
+ }
+} /*.makeDelaunay.*/
+
+/*--------------------------------------------------
+-findDelaunay- find Delaunay triangle for [0.5,0.5,...]
+ assumes dim < 100
+notes:
+ calls qh_setdelaunay() to project the point to a parabaloid
+warning:
+ This is not implemented for tricoplanar facets ('Qt'),
+ See <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
+*/
+void findDelaunay(qhT *qh, int dim) {
+ int k;
+ coordT point[ 100];
+ boolT isoutside;
+ realT bestdist;
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+
+ for (k= 0; k < dim; k++)
+ point[k]= 0.5;
+ qh_setdelaunay(qh, dim+1, 1, point);
+ facet= qh_findbestfacet(qh, point, qh_ALL, &bestdist, &isoutside);
+ if (facet->tricoplanar) {
+ fprintf(stderr, "findDelaunay: not implemented for triangulated, non-simplicial Delaunay regions (tricoplanar facet, f%d).\n",
+ facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ FOREACHvertex_(facet->vertices) {
+ for (k=0; k < dim; k++)
+ printf("%5.2f ", vertex->point[k]);
+ printf("\n");
+ }
+} /*.findDelaunay.*/
+
+/*--------------------------------------------------
+-makehalf- set points to halfspaces for a (dim)-dimensional diamond
+ points is numpoints X dim+1
+
+ each halfspace consists of dim coefficients followed by an offset
+*/
+void makehalf(coordT *points, int numpoints, int dim) {
+ int j,k;
+ coordT *point;
+
+ for (j=0; j<numpoints; j++) {
+ point= points + j*(dim+1);
+ point[dim]= -1.0; /* offset */
+ for (k=dim; k--; ) {
+ if (j & ( 1 << k))
+ point[k]= 1.0;
+ else
+ point[k]= -1.0;
+ }
+ }
+} /*.makehalf.*/
+
+#define DIM 3 /* dimension of points, must be < 31 for SIZEcube */
+#define SIZEcube (1<<DIM)
+#define SIZEdiamond (2*DIM)
+#define TOTpoints (SIZEcube + SIZEdiamond)
+
+/*--------------------------------------------------
+-main- derived from Qhull-template in user.c
+
+ see program header
+
+ this contains three runs of Qhull for convex hull, Delaunay
+ triangulation or Voronoi vertices, and halfspace intersection
+
+*/
+int main(int argc, char *argv[]) {
+ int dim= DIM; /* dimension of points */
+ int numpoints; /* number of points */
+ coordT points[(DIM+1)*TOTpoints]; /* array of coordinates for each point */
+ coordT *rows[TOTpoints];
+ boolT ismalloc= False; /* True if qhull should free points in qh_freeqhull() or reallocation */
+ char flags[250]; /* option flags for qhull, see qh-quick.htm */
+ FILE *outfile= stdout; /* output from qh_produce_output()
+ use NULL to skip qh_produce_output() */
+ FILE *errfile= stderr; /* error messages from qhull code */
+ int exitcode; /* 0 if no error from qhull */
+ facetT *facet; /* set by FORALLfacets */
+ int curlong, totlong; /* memory remaining after qh_memfreeshort */
+ int i;
+
+ qhT qh_qh; /* Qhull's data structure. First argument of most calls */
+ qhT *qh= &qh_qh;
+
+ QHULL_LIB_CHECK
+
+ qh_zero(qh, errfile);
+
+ printf("This is the output from user_eg_r.c\n\n\
+It shows how qhull() may be called from an application using the qhull\n\
+reentrant library. user_eg is not part of qhull itself. If it appears\n\
+accidently, please remove user_eg_r.c from your project. If it fails\n\
+immediately, user_eg_r.c was incorrectly linked to the non-reentrant library.\n\
+Also try 'user_eg T1 2>&1'\n\n");
+
+ /*
+ Run 1: convex hull
+ */
+ printf( "\ncompute convex hull of cube after rotating input\n");
+ sprintf(flags, "qhull s Tcv %s", argc >= 2 ? argv[1] : "");
+ numpoints= SIZEcube;
+ makecube(points, numpoints, DIM);
+ for (i=numpoints; i--; )
+ rows[i]= points+dim*i;
+ qh_printmatrix(qh, outfile, "input", rows, numpoints, dim);
+ exitcode= qh_new_qhull(qh, dim, numpoints, points, ismalloc,
+ flags, outfile, errfile);
+ if (!exitcode) { /* if no error */
+ /* 'qh->facet_list' contains the convex hull */
+ print_summary(qh);
+ FORALLfacets {
+ /* ... your code ... */
+ }
+ }
+ qh_freeqhull(qh, !qh_ALL); /* free long memory */
+ qh_memfreeshort(qh, &curlong, &totlong); /* free short memory and memory allocator */
+ if (curlong || totlong)
+ fprintf(errfile, "qhull internal warning (user_eg, #1): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
+
+ /*
+ Run 2: Delaunay triangulation, reusing the previous qh/qh_qh
+ */
+
+ printf( "\ncompute %d-d Delaunay triangulation\n", dim);
+ sprintf(flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
+ numpoints= SIZEcube;
+ makeDelaunay(qh, points, numpoints, dim, (int)time(NULL));
+ for (i=numpoints; i--; )
+ rows[i]= points+dim*i;
+ qh_printmatrix(qh, outfile, "input", rows, numpoints, dim);
+ exitcode= qh_new_qhull(qh, dim, numpoints, points, ismalloc,
+ flags, outfile, errfile);
+ if (!exitcode) { /* if no error */
+ /* 'qh->facet_list' contains the convex hull */
+ /* If you want a Voronoi diagram ('v') and do not request output (i.e., outfile=NULL),
+ call qh_setvoronoi_all() after qh_new_qhull(). */
+ print_summary(qh);
+ FORALLfacets {
+ /* ... your code ... */
+ }
+ printf( "\nfind %d-d Delaunay triangle closest to [0.5, 0.5, ...]\n", dim);
+ exitcode= setjmp(qh->errexit);
+ if (!exitcode) {
+ /* Trap Qhull errors in findDelaunay(). Without the setjmp(), Qhull
+ will exit() after reporting an error */
+ qh->NOerrexit= False;
+ findDelaunay(qh, DIM);
+ }
+ qh->NOerrexit= True;
+ }
+ {
+ coordT pointsB[DIM*TOTpoints]; /* array of coordinates for each point */
+
+ qhT qh_qhB; /* Create a new instance of Qhull (qhB) */
+ qhT *qhB= &qh_qhB;
+ qh_zero(qhB, errfile);
+
+ printf( "\nCompute a new triangulation as a separate instance of Qhull\n");
+ sprintf(flags, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
+ numpoints= SIZEcube;
+ makeDelaunay(qhB, pointsB, numpoints, dim, (int)time(NULL)+1);
+ for (i=numpoints; i--; )
+ rows[i]= pointsB+dim*i;
+ qh_printmatrix(qhB, outfile, "input", rows, numpoints, dim);
+ exitcode= qh_new_qhull(qhB, dim, numpoints, pointsB, ismalloc,
+ flags, outfile, errfile);
+ if (!exitcode)
+ print_summary(qhB);
+ printf( "\nFree memory allocated by the new instance of Qhull, and redisplay the old results.\n");
+ qh_freeqhull(qhB, !qh_ALL); /* free long memory */
+ qh_memfreeshort(qhB, &curlong, &totlong); /* free short memory and memory allocator */
+ if (curlong || totlong)
+ fprintf(errfile, "qhull internal warning (user_eg, #4): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
+
+ printf( "\n\n");
+ print_summary(qh); /* The other instance is unchanged */
+ /* Exiting the block frees qh_qhB */
+ }
+ qh_freeqhull(qh, !qh_ALL); /* free long memory */
+ qh_memfreeshort(qh, &curlong, &totlong); /* free short memory and memory allocator */
+ if (curlong || totlong)
+ fprintf(errfile, "qhull internal warning (user_eg, #2): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
+
+ /*
+ Run 3: halfspace intersection about the origin
+ */
+ printf( "\ncompute halfspace intersection about the origin for a diamond\n");
+ sprintf(flags, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "Fp");
+ numpoints= SIZEcube;
+ makehalf(points, numpoints, dim);
+ for (i=numpoints; i--; )
+ rows[i]= points+(dim+1)*i;
+ qh_printmatrix(qh, outfile, "input as halfspace coefficients + offsets", rows, numpoints, dim+1);
+ /* use qh_sethalfspace_all to transform the halfspaces yourself.
+ If so, set 'qh->feasible_point and do not use option 'Hn,...' [it would retransform the halfspaces]
+ */
+ exitcode= qh_new_qhull(qh, dim+1, numpoints, points, ismalloc,
+ flags, outfile, errfile);
+ if (!exitcode)
+ print_summary(qh);
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
+ if (curlong || totlong) /* could also check previous runs */
+ fprintf(stderr, "qhull internal warning (user_eg, #3): did not free %d bytes of long memory (%d pieces)\n",
+ totlong, curlong);
+ return exitcode;
+} /* main */
+
diff --git a/xs/src/qhull/src/user_eg2/user_eg2.c b/xs/src/qhull/src/user_eg2/user_eg2.c
new file mode 100644
index 000000000..a455f025d
--- /dev/null
+++ b/xs/src/qhull/src/user_eg2/user_eg2.c
@@ -0,0 +1,746 @@
+/*<html><pre> -<a href="../libqhull/qh-user.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ user_eg2.c
+
+ sample code for calling qhull() from an application.
+
+ See user_eg.c for a simpler method using qh_new_qhull().
+ The method used here and in unix.c gives you additional
+ control over Qhull.
+
+ See user_eg3/user_eg3_r.cpp for a C++ example
+
+ call with:
+
+ user_eg2 "triangulated cube/diamond options" "delaunay options" "halfspace options"
+
+ for example:
+
+ user_eg2 # return summaries
+
+ user_eg2 "n" "o" "Fp" # return normals, OFF, points
+
+ user_eg2 "QR0 p" "QR0 v p" "QR0 Fp" # rotate input and return points
+ # 'v' returns Voronoi
+ # transform is rotated for halfspaces
+
+ main() makes three runs of qhull.
+
+ 1) compute the convex hull of a cube, and incrementally add a diamond
+
+ 2a) compute the Delaunay triangulation of random points, and add points.
+
+ 2b) find the Delaunay triangle closest to a point.
+
+ 3) compute the halfspace intersection of a diamond, and add a cube
+
+ notes:
+
+ summaries are sent to stderr if other output formats are used
+
+ derived from unix.c and compiled by 'make bin/user_eg2'
+
+ see libqhull.h for data structures, macros, and user-callable functions.
+
+ If you want to control all output to stdio and input to stdin,
+ set the #if below to "1" and delete all lines that contain "io.c".
+ This prevents the loading of io.o. Qhull will
+ still write to 'qh ferr' (stderr) for error reporting and tracing.
+
+ Defining #if 1, also prevents user.o from being loaded.
+*/
+
+#include "libqhull/qhull_a.h"
+
+/*-------------------------------------------------
+-internal function prototypes
+*/
+void print_summary(void);
+void makecube(coordT *points, int numpoints, int dim);
+void adddiamond(coordT *points, int numpoints, int numnew, int dim);
+void makeDelaunay(coordT *points, int numpoints, int dim);
+void addDelaunay(coordT *points, int numpoints, int numnew, int dim);
+void findDelaunay(int dim);
+void makehalf(coordT *points, int numpoints, int dim);
+void addhalf(coordT *points, int numpoints, int numnew, int dim, coordT *feasible);
+
+/*-------------------------------------------------
+-print_summary()
+*/
+void print_summary(void) {
+ facetT *facet;
+ int k;
+
+ printf("\n%d vertices and %d facets with normals:\n",
+ qh num_vertices, qh num_facets);
+ FORALLfacets {
+ for (k=0; k < qh hull_dim; k++)
+ printf("%6.2g ", facet->normal[k]);
+ printf("\n");
+ }
+}
+
+/*--------------------------------------------------
+-makecube- set points to vertices of cube
+ points is numpoints X dim
+*/
+void makecube(coordT *points, int numpoints, int dim) {
+ int j,k;
+ coordT *point;
+
+ for (j=0; j<numpoints; j++) {
+ point= points + j*dim;
+ for (k=dim; k--; ) {
+ if (j & ( 1 << k))
+ point[k]= 1.0;
+ else
+ point[k]= -1.0;
+ }
+ }
+} /*.makecube.*/
+
+/*--------------------------------------------------
+-adddiamond- add diamond to convex hull
+ points is numpoints+numnew X dim.
+
+notes:
+ qh_addpoint() does not make a copy of the point coordinates.
+
+ For inside points and some outside points, qh_findbestfacet performs
+ an exhaustive search for a visible facet. Algorithms that retain
+ previously constructed hulls should be faster for on-line construction
+ of the convex hull.
+*/
+void adddiamond(coordT *points, int numpoints, int numnew, int dim) {
+ int j,k;
+ coordT *point;
+ facetT *facet;
+ boolT isoutside;
+ realT bestdist;
+
+ for (j= 0; j < numnew ; j++) {
+ point= points + (numpoints+j)*dim;
+ if (points == qh first_point) /* in case of 'QRn' */
+ qh num_points= numpoints+j+1;
+ /* qh.num_points sets the size of the points array. You may
+ allocate the points elsewhere. If so, qh_addpoint records
+ the point's address in qh other_points
+ */
+ for (k=dim; k--; ) {
+ if (j/2 == k)
+ point[k]= (j & 1) ? 2.0 : -2.0;
+ else
+ point[k]= 0.0;
+ }
+ facet= qh_findbestfacet(point, !qh_ALL, &bestdist, &isoutside);
+ if (isoutside) {
+ if (!qh_addpoint(point, facet, False))
+ break; /* user requested an early exit with 'TVn' or 'TCn' */
+ }
+ printf("%d vertices and %d facets\n",
+ qh num_vertices, qh num_facets);
+ /* qh_produce_output(); */
+ }
+ if (qh DOcheckmax)
+ qh_check_maxout();
+ else if (qh KEEPnearinside)
+ qh_nearcoplanar();
+} /*.adddiamond.*/
+
+/*--------------------------------------------------
+-makeDelaunay- set points for dim-1 Delaunay triangulation of random points
+ points is numpoints X dim. Each point is projected to a paraboloid.
+*/
+void makeDelaunay(coordT *points, int numpoints, int dim) {
+ int j,k, seed;
+ coordT *point, realr;
+
+ seed= (int)time(NULL); /* time_t to int */
+ printf("seed: %d\n", seed);
+ qh_RANDOMseed_( seed);
+ for (j=0; j<numpoints; j++) {
+ point= points + j*dim;
+ for (k= 0; k < dim-1; k++) {
+ realr= qh_RANDOMint;
+ point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
+ }
+ }
+ qh_setdelaunay(dim, numpoints, points);
+} /*.makeDelaunay.*/
+
+/*--------------------------------------------------
+-addDelaunay- add points to dim-1 Delaunay triangulation
+ points is numpoints+numnew X dim. Each point is projected to a paraboloid.
+notes:
+ qh_addpoint() does not make a copy of the point coordinates.
+
+ Since qh_addpoint() is not given a visible facet, it performs a directed
+ search of all facets. Algorithms that retain previously
+ constructed hulls may be faster.
+*/
+void addDelaunay(coordT *points, int numpoints, int numnew, int dim) {
+ int j,k;
+ coordT *point, realr;
+ facetT *facet;
+ realT bestdist;
+ boolT isoutside;
+
+ for (j= 0; j < numnew ; j++) {
+ point= points + (numpoints+j)*dim;
+ if (points == qh first_point) /* in case of 'QRn' */
+ qh num_points= numpoints+j+1;
+ /* qh.num_points sets the size of the points array. You may
+ allocate the point elsewhere. If so, qh_addpoint records
+ the point's address in qh other_points
+ */
+ for (k= 0; k < dim-1; k++) {
+ realr= qh_RANDOMint;
+ point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
+ }
+ qh_setdelaunay(dim, 1, point);
+ facet= qh_findbestfacet(point, !qh_ALL, &bestdist, &isoutside);
+ if (isoutside) {
+ if (!qh_addpoint(point, facet, False))
+ break; /* user requested an early exit with 'TVn' or 'TCn' */
+ }
+ qh_printpoint(stdout, "added point", point);
+ printf("%d points, %d extra points, %d vertices, and %d facets in total\n",
+ qh num_points, qh_setsize(qh other_points),
+ qh num_vertices, qh num_facets);
+
+ /* qh_produce_output(); */
+ }
+ if (qh DOcheckmax)
+ qh_check_maxout();
+ else if (qh KEEPnearinside)
+ qh_nearcoplanar();
+} /*.addDelaunay.*/
+
+/*--------------------------------------------------
+-findDelaunay- find Delaunay triangle for [0.5,0.5,...]
+ assumes dim < 100
+notes:
+ calls qh_setdelaunay() to project the point to a parabaloid
+warning:
+ This is not implemented for tricoplanar facets ('Qt'),
+ See <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
+*/
+void findDelaunay(int dim) {
+ int k;
+ coordT point[ 100];
+ boolT isoutside;
+ realT bestdist;
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+
+ for (k= 0; k < dim-1; k++)
+ point[k]= 0.5;
+ qh_setdelaunay(dim, 1, point);
+ facet= qh_findbestfacet(point, qh_ALL, &bestdist, &isoutside);
+ if (facet->tricoplanar) {
+ fprintf(stderr, "findDelaunay: not implemented for triangulated, non-simplicial Delaunay regions (tricoplanar facet, f%d).\n",
+ facet->id);
+ qh_errexit(qh_ERRqhull, facet, NULL);
+ }
+ FOREACHvertex_(facet->vertices) {
+ for (k=0; k < dim-1; k++)
+ printf("%5.2f ", vertex->point[k]);
+ printf("\n");
+ }
+} /*.findDelaunay.*/
+
+/*--------------------------------------------------
+-makehalf- set points to halfspaces for a (dim)-d diamond
+ points is numpoints X dim+1
+
+ each halfspace consists of dim coefficients followed by an offset
+*/
+void makehalf(coordT *points, int numpoints, int dim) {
+ int j,k;
+ coordT *point;
+
+ for (j=0; j<numpoints; j++) {
+ point= points + j*(dim+1);
+ point[dim]= -1.0; /* offset */
+ for (k=dim; k--; ) {
+ if (j & ( 1 << k))
+ point[k]= 1.0;
+ else
+ point[k]= -1.0;
+ }
+ }
+} /*.makehalf.*/
+
+/*--------------------------------------------------
+-addhalf- add halfspaces for a (dim)-d cube to the intersection
+ points is numpoints+numnew X dim+1
+notes:
+ assumes dim < 100.
+
+ For makehalf(), points is the initial set of halfspaces with offsets.
+ It is transformed by qh_sethalfspace_all into a
+ (dim)-d set of newpoints. Qhull computed the convex hull of newpoints -
+ this is equivalent to the halfspace intersection of the
+ orginal halfspaces.
+
+ For addhalf(), the remainder of points stores the transforms of
+ the added halfspaces. Qhull computes the convex hull of newpoints
+ and the added points. qh_addpoint() does not make a copy of these points.
+
+ Since halfspace intersection is equivalent to a convex hull,
+ qh_findbestfacet may perform an exhaustive search
+ for a visible facet. Algorithms that retain previously constructed
+ intersections should be faster for on-line construction.
+*/
+void addhalf(coordT *points, int numpoints, int numnew, int dim, coordT *feasible) {
+ int j,k;
+ coordT *point, normal[100], offset, *next;
+ facetT *facet;
+ boolT isoutside;
+ realT bestdist;
+
+ for (j= 0; j < numnew ; j++) {
+ offset= -1.0;
+ for (k=dim; k--; ) {
+ if (j/2 == k) {
+ normal[k]= sqrt((coordT)dim); /* to normalize as in makehalf */
+ if (j & 1)
+ normal[k]= -normal[k];
+ }else
+ normal[k]= 0.0;
+ }
+ point= points + (numpoints+j)* (dim+1); /* does not use point[dim] */
+ qh_sethalfspace(dim, point, &next, normal, &offset, feasible);
+ facet= qh_findbestfacet(point, !qh_ALL, &bestdist, &isoutside);
+ if (isoutside) {
+ if (!qh_addpoint(point, facet, False))
+ break; /* user requested an early exit with 'TVn' or 'TCn' */
+ }
+ qh_printpoint(stdout, "added offset -1 and normal", normal);
+ printf("%d points, %d extra points, %d vertices, and %d facets in total\n",
+ qh num_points, qh_setsize(qh other_points),
+ qh num_vertices, qh num_facets);
+ /* qh_produce_output(); */
+ }
+ if (qh DOcheckmax)
+ qh_check_maxout();
+ else if (qh KEEPnearinside)
+ qh_nearcoplanar();
+} /*.addhalf.*/
+
+#define DIM 3 /* dimension of points, must be < 31 for SIZEcube */
+#define SIZEcube (1<<DIM)
+#define SIZEdiamond (2*DIM)
+#define TOTpoints (SIZEcube + SIZEdiamond)
+
+/*--------------------------------------------------
+-main- derived from unix.c
+
+ see program header
+
+ this contains three runs of Qhull for convex hull, Delaunay
+ triangulation or Voronoi vertices, and halfspace intersection
+
+*/
+int main(int argc, char *argv[]) {
+ boolT ismalloc;
+ int curlong, totlong, exitcode;
+ char options [2000];
+
+ QHULL_LIB_CHECK
+
+ printf("This is the output from user_eg2.c\n\n\
+It shows how qhull() may be called from an application in the same way as\n\
+qconvex. It is not part of qhull itself. If it appears accidently,\n\
+please remove user_eg2.c from your project.\n\n");
+
+#if qh_QHpointer /* see user.h */
+ if (qh_qh){
+ printf("QH6237: Qhull link error. The global variable qh_qh was not initialized\n\
+ to NULL by global.c. Please compile user_eg2.c with -Dqh_QHpointer_dllimport\n\
+ as well as -Dqh_QHpointer, or use libqhullstatic, or use a different tool chain.\n\n");
+ return -1;
+ }
+#endif
+
+
+ ismalloc= False; /* True if qh_freeqhull should 'free(array)' */
+ /*
+ Run 1: convex hull
+ */
+ qh_init_A(stdin, stdout, stderr, 0, NULL);
+ exitcode= setjmp(qh errexit);
+ if (!exitcode) {
+ coordT array[TOTpoints][DIM];
+
+ strcat(qh rbox_command, "user_eg cube");
+ sprintf(options, "qhull s Tcv Q11 %s ", argc >= 2 ? argv[1] : "");
+ qh_initflags(options);
+ printf( "\ncompute triangulated convex hull of cube after rotating input\n");
+ makecube(array[0], SIZEcube, DIM);
+ qh_init_B(array[0], SIZEcube, DIM, ismalloc);
+ qh_qhull();
+ qh_check_output();
+ qh_triangulate(); /* requires option 'Q11' if want to add points */
+ print_summary();
+ if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ printf( "\nadd points in a diamond\n");
+ adddiamond(array[0], SIZEcube, SIZEdiamond, DIM);
+ qh_check_output();
+ print_summary();
+ qh_produce_output(); /* delete this line to help avoid io.c */
+ if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ }
+ qh NOerrexit= True;
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
+ if (curlong || totlong)
+ fprintf(stderr, "qhull warning (user_eg, run 1): did not free %d bytes of long memory (%d pieces)\n",
+ totlong, curlong);
+
+ /*
+ Run 2: Delaunay triangulation
+ */
+ qh_init_A(stdin, stdout, stderr, 0, NULL);
+ exitcode= setjmp(qh errexit);
+ if (!exitcode) {
+ coordT array[TOTpoints][DIM];
+
+ strcat(qh rbox_command, "user_eg Delaunay");
+ sprintf(options, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
+ qh_initflags(options);
+ printf( "\ncompute %d-d Delaunay triangulation\n", DIM-1);
+ makeDelaunay(array[0], SIZEcube, DIM);
+ /* Instead of makeDelaunay with qh_setdelaunay, you may
+ produce a 2-d array of points, set DIM to 2, and set
+ qh PROJECTdelaunay to True. qh_init_B will call
+ qh_projectinput to project the points to the paraboloid
+ and add a point "at-infinity".
+ */
+ qh_init_B(array[0], SIZEcube, DIM, ismalloc);
+ qh_qhull();
+ /* If you want Voronoi ('v') without qh_produce_output(), call
+ qh_setvoronoi_all() after qh_qhull() */
+ qh_check_output();
+ print_summary();
+ qh_produce_output(); /* delete this line to help avoid io.c */
+ if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ printf( "\nadd points to triangulation\n");
+ addDelaunay(array[0], SIZEcube, SIZEdiamond, DIM);
+ qh_check_output();
+ qh_produce_output(); /* delete this line to help avoid io.c */
+ if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ printf( "\nfind Delaunay triangle closest to [0.5, 0.5, ...]\n");
+ findDelaunay(DIM);
+ }
+ qh NOerrexit= True;
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
+ if (curlong || totlong)
+ fprintf(stderr, "qhull warning (user_eg, run 2): did not free %d bytes of long memory (%d pieces)\n",
+ totlong, curlong);
+
+ /*
+ Run 3: halfspace intersection
+ */
+ qh_init_A(stdin, stdout, stderr, 0, NULL);
+ exitcode= setjmp(qh errexit);
+ if (!exitcode) {
+ coordT array[TOTpoints][DIM+1]; /* +1 for halfspace offset */
+ pointT *points;
+
+ strcat(qh rbox_command, "user_eg halfspaces");
+ sprintf(options, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "");
+ qh_initflags(options);
+ printf( "\ncompute halfspace intersection about the origin for a diamond\n");
+ makehalf(array[0], SIZEcube, DIM);
+ qh_setfeasible(DIM); /* from io.c, sets qh feasible_point from 'Hn,n' */
+ /* you may malloc and set qh feasible_point directly. It is only used for
+ option 'Fp' */
+ points= qh_sethalfspace_all( DIM+1, SIZEcube, array[0], qh feasible_point);
+ qh_init_B(points, SIZEcube, DIM, True); /* qh_freeqhull frees points */
+ qh_qhull();
+ qh_check_output();
+ qh_produce_output(); /* delete this line to help avoid io.c */
+ if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ printf( "\nadd halfspaces for cube to intersection\n");
+ addhalf(array[0], SIZEcube, SIZEdiamond, DIM, qh feasible_point);
+ qh_check_output();
+ qh_produce_output(); /* delete this line to help avoid io.c */
+ if (qh VERIFYoutput && !qh STOPpoint && !qh STOPcone)
+ qh_check_points();
+ }
+ qh NOerrexit= True;
+ qh NOerrexit= True;
+ qh_freeqhull(!qh_ALL);
+ qh_memfreeshort(&curlong, &totlong);
+ if (curlong || totlong)
+ fprintf(stderr, "qhull warning (user_eg, run 3): did not free %d bytes of long memory (%d pieces)\n",
+ totlong, curlong);
+ return exitcode;
+} /* main */
+
+#if 1 /* use 1 to prevent loading of io.o and user.o */
+/*-------------------------------------------
+-errexit- return exitcode to system after an error
+ assumes exitcode non-zero
+ prints useful information
+ see qh_errexit2() in libqhull.c for 2 facets
+*/
+void qh_errexit(int exitcode, facetT *facet, ridgeT *ridge) {
+ QHULL_UNUSED(facet);
+ QHULL_UNUSED(ridge);
+
+ if (qh ERREXITcalled) {
+ fprintf(qh ferr, "qhull error while processing previous error. Exit program\n");
+ exit(1);
+ }
+ qh ERREXITcalled= True;
+ if (!qh QHULLfinished)
+ qh hulltime= (unsigned)clock() - qh hulltime;
+ fprintf(qh ferr, "\nWhile executing: %s | %s\n", qh rbox_command, qh qhull_command);
+ fprintf(qh ferr, "Options selected:\n%s\n", qh qhull_options);
+ if (qh furthest_id >= 0) {
+ fprintf(qh ferr, "\nLast point added to hull was p%d", qh furthest_id);
+ if (zzval_(Ztotmerge))
+ fprintf(qh ferr, " Last merge was #%d.", zzval_(Ztotmerge));
+ if (qh QHULLfinished)
+ fprintf(qh ferr, "\nQhull has finished constructing the hull.");
+ else if (qh POSTmerging)
+ fprintf(qh ferr, "\nQhull has started post-merging");
+ fprintf(qh ferr, "\n\n");
+ }
+ if (qh NOerrexit) {
+ fprintf(qh ferr, "qhull error while ending program. Exit program\n");
+ exit(1);
+ }
+ if (!exitcode)
+ exitcode= qh_ERRqhull;
+ qh NOerrexit= True;
+ longjmp(qh errexit, exitcode);
+} /* errexit */
+
+
+/*-------------------------------------------
+-errprint- prints out the information of the erroneous object
+ any parameter may be NULL, also prints neighbors and geomview output
+*/
+void qh_errprint(const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
+
+ fprintf(qh ferr, "%s facets f%d f%d ridge r%d vertex v%d\n",
+ string, getid_(atfacet), getid_(otherfacet), getid_(atridge),
+ getid_(atvertex));
+} /* errprint */
+
+
+void qh_printfacetlist(facetT *facetlist, setT *facets, boolT printall) {
+ facetT *facet, **facetp;
+
+ /* remove these calls to help avoid io.c */
+ qh_printbegin(qh ferr, qh_PRINTfacets, facetlist, facets, printall);/*io.c*/
+ FORALLfacet_(facetlist) /*io.c*/
+ qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall); /*io.c*/
+ FOREACHfacet_(facets) /*io.c*/
+ qh_printafacet(qh ferr, qh_PRINTfacets, facet, printall); /*io.c*/
+ qh_printend(qh ferr, qh_PRINTfacets, facetlist, facets, printall); /*io.c*/
+
+ FORALLfacet_(facetlist)
+ fprintf( qh ferr, "facet f%d\n", facet->id);
+} /* printfacetlist */
+
+/* qh_printhelp_degenerate( fp )
+ prints descriptive message for precision error
+
+ notes:
+ no message if qh_QUICKhelp
+*/
+void qh_printhelp_degenerate(FILE *fp) {
+
+ if (qh MERGEexact || qh PREmerge || qh JOGGLEmax < REALmax/2)
+ qh_fprintf(fp, 9368, "\n\
+A Qhull error has occurred. Qhull should have corrected the above\n\
+precision error. Please send the input and all of the output to\n\
+qhull_bug@qhull.org\n");
+ else if (!qh_QUICKhelp) {
+ qh_fprintf(fp, 9369, "\n\
+Precision problems were detected during construction of the convex hull.\n\
+This occurs because convex hull algorithms assume that calculations are\n\
+exact, but floating-point arithmetic has roundoff errors.\n\
+\n\
+To correct for precision problems, do not use 'Q0'. By default, Qhull\n\
+selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',\n\
+Qhull joggles the input to prevent precision problems. See \"Imprecision\n\
+in Qhull\" (qh-impre.htm).\n\
+\n\
+If you use 'Q0', the output may include\n\
+coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,\n\
+Qhull may produce a ridge with four neighbors or two facets with the same \n\
+vertices. Qhull reports these events when they occur. It stops when a\n\
+concave ridge, flipped facet, or duplicate facet occurs.\n");
+#if REALfloat
+ qh_fprintf(fp, 9370, "\
+\n\
+Qhull is currently using single precision arithmetic. The following\n\
+will probably remove the precision problems:\n\
+ - recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
+#endif
+ if (qh DELAUNAY && !qh SCALElast && qh MAXabs_coord > 1e4)
+ qh_fprintf(fp, 9371, "\
+\n\
+When computing the Delaunay triangulation of coordinates > 1.0,\n\
+ - use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n");
+ if (qh DELAUNAY && !qh ATinfinity)
+ qh_fprintf(fp, 9372, "\
+When computing the Delaunay triangulation:\n\
+ - use 'Qz' to add a point at-infinity. This reduces precision problems.\n");
+
+ qh_fprintf(fp, 9373, "\
+\n\
+If you need triangular output:\n\
+ - use option 'Qt' to triangulate the output\n\
+ - use option 'QJ' to joggle the input points and remove precision errors\n\
+ - use option 'Ft'. It triangulates non-simplicial facets with added points.\n\
+\n\
+If you must use 'Q0',\n\
+try one or more of the following options. They can not guarantee an output.\n\
+ - use 'QbB' to scale the input to a cube.\n\
+ - use 'Po' to produce output and prevent partitioning for flipped facets\n\
+ - use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\
+ - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
+ - options 'Qf', 'Qbb', and 'QR0' may also help\n",
+ qh DISTround);
+ qh_fprintf(fp, 9374, "\
+\n\
+To guarantee simplicial output:\n\
+ - use option 'Qt' to triangulate the output\n\
+ - use option 'QJ' to joggle the input points and remove precision errors\n\
+ - use option 'Ft' to triangulate the output by adding points\n\
+ - use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\
+");
+ }
+} /* printhelp_degenerate */
+
+
+/* qh_printhelp_narrowhull( minangle )
+ Warn about a narrow hull
+
+ notes:
+ Alternatively, reduce qh_WARNnarrow in user.h
+
+*/
+void qh_printhelp_narrowhull(FILE *fp, realT minangle) {
+
+ qh_fprintf(fp, 9375, "qhull precision warning: \n\
+The initial hull is narrow (cosine of min. angle is %.16f).\n\
+A coplanar point may lead to a wide facet. Options 'QbB' (scale to unit box)\n\
+or 'Qbb' (scale last coordinate) may remove this warning. Use 'Pp' to skip\n\
+this warning. See 'Limitations' in qh-impre.htm.\n",
+ -minangle); /* convert from angle between normals to angle between facets */
+} /* printhelp_narrowhull */
+
+/* qh_printhelp_singular
+ prints descriptive message for singular input
+*/
+void qh_printhelp_singular(FILE *fp) {
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+ realT min, max, *coord, dist;
+ int i,k;
+
+ qh_fprintf(fp, 9376, "\n\
+The input to qhull appears to be less than %d dimensional, or a\n\
+computation has overflowed.\n\n\
+Qhull could not construct a clearly convex simplex from points:\n",
+ qh hull_dim);
+ qh_printvertexlist(fp, "", qh facet_list, NULL, qh_ALL);
+ if (!qh_QUICKhelp)
+ qh_fprintf(fp, 9377, "\n\
+The center point is coplanar with a facet, or a vertex is coplanar\n\
+with a neighboring facet. The maximum round off error for\n\
+computing distances is %2.2g. The center point, facets and distances\n\
+to the center point are as follows:\n\n", qh DISTround);
+ qh_printpointid(fp, "center point", qh hull_dim, qh interior_point, -1);
+ qh_fprintf(fp, 9378, "\n");
+ FORALLfacets {
+ qh_fprintf(fp, 9379, "facet");
+ FOREACHvertex_(facet->vertices)
+ qh_fprintf(fp, 9380, " p%d", qh_pointid(vertex->point));
+ zinc_(Zdistio);
+ qh_distplane(qh interior_point, facet, &dist);
+ qh_fprintf(fp, 9381, " distance= %4.2g\n", dist);
+ }
+ if (!qh_QUICKhelp) {
+ if (qh HALFspace)
+ qh_fprintf(fp, 9382, "\n\
+These points are the dual of the given halfspaces. They indicate that\n\
+the intersection is degenerate.\n");
+ qh_fprintf(fp, 9383,"\n\
+These points either have a maximum or minimum x-coordinate, or\n\
+they maximize the determinant for k coordinates. Trial points\n\
+are first selected from points that maximize a coordinate.\n");
+ if (qh hull_dim >= qh_INITIALmax)
+ qh_fprintf(fp, 9384, "\n\
+Because of the high dimension, the min x-coordinate and max-coordinate\n\
+points are used if the determinant is non-zero. Option 'Qs' will\n\
+do a better, though much slower, job. Instead of 'Qs', you can change\n\
+the points by randomly rotating the input with 'QR0'.\n");
+ }
+ qh_fprintf(fp, 9385, "\nThe min and max coordinates for each dimension are:\n");
+ for (k=0; k < qh hull_dim; k++) {
+ min= REALmax;
+ max= -REALmin;
+ for (i=qh num_points, coord= qh first_point+k; i--; coord += qh hull_dim) {
+ maximize_(max, *coord);
+ minimize_(min, *coord);
+ }
+ qh_fprintf(fp, 9386, " %d: %8.4g %8.4g difference= %4.4g\n", k, min, max, max-min);
+ }
+ if (!qh_QUICKhelp) {
+ qh_fprintf(fp, 9387, "\n\
+If the input should be full dimensional, you have several options that\n\
+may determine an initial simplex:\n\
+ - use 'QJ' to joggle the input and make it full dimensional\n\
+ - use 'QbB' to scale the points to the unit cube\n\
+ - use 'QR0' to randomly rotate the input for different maximum points\n\
+ - use 'Qs' to search all points for the initial simplex\n\
+ - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
+ - trace execution with 'T3' to see the determinant for each point.\n",
+ qh DISTround);
+#if REALfloat
+ qh_fprintf(fp, 9388, "\
+ - recompile qhull for realT precision(#define REALfloat 0 in libqhull.h).\n");
+#endif
+ qh_fprintf(fp, 9389, "\n\
+If the input is lower dimensional:\n\
+ - use 'QJ' to joggle the input and make it full dimensional\n\
+ - use 'Qbk:0Bk:0' to delete coordinate k from the input. You should\n\
+ pick the coordinate with the least range. The hull will have the\n\
+ correct topology.\n\
+ - determine the flat containing the points, rotate the points\n\
+ into a coordinate plane, and delete the other coordinates.\n\
+ - add one or more points to make the input full dimensional.\n\
+");
+ if (qh DELAUNAY && !qh ATinfinity)
+ qh_fprintf(fp, 9390, "\n\n\
+This is a Delaunay triangulation and the input is co-circular or co-spherical:\n\
+ - use 'Qz' to add a point \"at infinity\" (i.e., above the paraboloid)\n\
+ - or use 'QJ' to joggle the input and avoid co-circular data\n");
+ }
+} /* printhelp_singular */
+
+
+/*-----------------------------------------
+-user_memsizes- allocate up to 10 additional, quick allocation sizes
+*/
+void qh_user_memsizes(void) {
+
+ /* qh_memsize(size); */
+} /* user_memsizes */
+
+#endif
diff --git a/xs/src/qhull/src/user_eg2/user_eg2.pro b/xs/src/qhull/src/user_eg2/user_eg2.pro
new file mode 100644
index 000000000..c841bfe13
--- /dev/null
+++ b/xs/src/qhull/src/user_eg2/user_eg2.pro
@@ -0,0 +1,11 @@
+# -------------------------------------------------
+# user_eg2.pro -- Qt project for Qhull demonstration using the static Qhull library
+#
+# It uses reentrant Qhull
+# -------------------------------------------------
+
+include(../qhull-app-c_r.pri)
+
+TARGET = user_eg2
+
+SOURCES += user_eg2_r.c
diff --git a/xs/src/qhull/src/user_eg2/user_eg2_r.c b/xs/src/qhull/src/user_eg2/user_eg2_r.c
new file mode 100644
index 000000000..2f8b4e6c7
--- /dev/null
+++ b/xs/src/qhull/src/user_eg2/user_eg2_r.c
@@ -0,0 +1,742 @@
+/*<html><pre> -<a href="../libqhull_r/qh-user_r.htm"
+ >-------------------------------</a><a name="TOP">-</a>
+
+ user_eg2_r.c
+
+ sample code for calling qhull() from an application.
+
+ See user_eg_r.c for a simpler method using qh_new_qhull().
+ The method used here and in unix_r.c gives you additional
+ control over Qhull.
+
+ See user_eg3/user_eg3_r.cpp for a C++ example
+
+ call with:
+
+ user_eg2 "triangulated cube/diamond options" "delaunay options" "halfspace options"
+
+ for example:
+
+ user_eg2 # return summaries
+
+ user_eg2 "n" "o" "Fp" # return normals, OFF, points
+
+ user_eg2 "QR0 p" "QR0 v p" "QR0 Fp" # rotate input and return points
+ # 'v' returns Voronoi
+ # transform is rotated for halfspaces
+
+ main() makes three runs of qhull.
+
+ 1) compute the convex hull of a cube, and incrementally add a diamond
+
+ 2a) compute the Delaunay triangulation of random points, and add points.
+
+ 2b) find the Delaunay triangle closest to a point.
+
+ 3) compute the halfspace intersection of a diamond, and add a cube
+
+ notes:
+
+ summaries are sent to stderr if other output formats are used
+
+ derived from unix.c and compiled by 'make bin/user_eg2'
+
+ see libqhull.h for data structures, macros, and user-callable functions.
+
+ If you want to control all output to stdio and input to stdin,
+ set the #if below to "1" and delete all lines that contain "io.c".
+ This prevents the loading of io.o. Qhull will
+ still write to 'qh->ferr' (stderr) for error reporting and tracing.
+
+ Defining #if 1, also prevents user.o from being loaded.
+*/
+
+#include "libqhull_r/qhull_ra.h"
+
+/*-------------------------------------------------
+-internal function prototypes
+*/
+void print_summary(qhT *qh);
+void makecube(coordT *points, int numpoints, int dim);
+void adddiamond(qhT *qh, coordT *points, int numpoints, int numnew, int dim);
+void makeDelaunay(qhT *qh, coordT *points, int numpoints, int dim);
+void addDelaunay(qhT *qh, coordT *points, int numpoints, int numnew, int dim);
+void findDelaunay(qhT *qh, int dim);
+void makehalf(coordT *points, int numpoints, int dim);
+void addhalf(qhT *qh, coordT *points, int numpoints, int numnew, int dim, coordT *feasible);
+
+/*-------------------------------------------------
+-print_summary(qh)
+*/
+void print_summary(qhT *qh) {
+ facetT *facet;
+ int k;
+
+ printf("\n%d vertices and %d facets with normals:\n",
+ qh->num_vertices, qh->num_facets);
+ FORALLfacets {
+ for (k=0; k < qh->hull_dim; k++)
+ printf("%6.2g ", facet->normal[k]);
+ printf("\n");
+ }
+}
+
+/*--------------------------------------------------
+-makecube- set points to vertices of cube
+ points is numpoints X dim
+*/
+void makecube(coordT *points, int numpoints, int dim) {
+ int j,k;
+ coordT *point;
+
+ for (j=0; j<numpoints; j++) {
+ point= points + j*dim;
+ for (k=dim; k--; ) {
+ if (j & ( 1 << k))
+ point[k]= 1.0;
+ else
+ point[k]= -1.0;
+ }
+ }
+} /*.makecube.*/
+
+/*--------------------------------------------------
+-adddiamond- add diamond to convex hull
+ points is numpoints+numnew X dim.
+
+notes:
+ qh_addpoint() does not make a copy of the point coordinates.
+
+ For inside points and some outside points, qh_findbestfacet performs
+ an exhaustive search for a visible facet. Algorithms that retain
+ previously constructed hulls should be faster for on-line construction
+ of the convex hull.
+*/
+void adddiamond(qhT *qh, coordT *points, int numpoints, int numnew, int dim) {
+ int j,k;
+ coordT *point;
+ facetT *facet;
+ boolT isoutside;
+ realT bestdist;
+
+ for (j= 0; j < numnew ; j++) {
+ point= points + (numpoints+j)*dim;
+ if (points == qh->first_point) /* in case of 'QRn' */
+ qh->num_points= numpoints+j+1;
+ /* qh.num_points sets the size of the points array. You may
+ allocate the points elsewhere. If so, qh_addpoint records
+ the point's address in qh->other_points
+ */
+ for (k=dim; k--; ) {
+ if (j/2 == k)
+ point[k]= (j & 1) ? 2.0 : -2.0;
+ else
+ point[k]= 0.0;
+ }
+ facet= qh_findbestfacet(qh, point, !qh_ALL, &bestdist, &isoutside);
+ if (isoutside) {
+ if (!qh_addpoint(qh, point, facet, False))
+ break; /* user requested an early exit with 'TVn' or 'TCn' */
+ }
+ printf("%d vertices and %d facets\n",
+ qh->num_vertices, qh->num_facets);
+ /* qh_produce_output(); */
+ }
+ if (qh->DOcheckmax)
+ qh_check_maxout(qh);
+ else if (qh->KEEPnearinside)
+ qh_nearcoplanar(qh);
+} /*.adddiamond.*/
+
+/*--------------------------------------------------
+-makeDelaunay- set points for dim-1 Delaunay triangulation of random points
+ points is numpoints X dim. Each point is projected to a paraboloid.
+*/
+void makeDelaunay(qhT *qh, coordT *points, int numpoints, int dim) {
+ int j,k, seed;
+ coordT *point, realr;
+
+ seed= (int)time(NULL); /* time_t to int */
+ printf("seed: %d\n", seed);
+ qh_RANDOMseed_(qh, seed);
+ for (j=0; j<numpoints; j++) {
+ point= points + j*dim;
+ for (k= 0; k < dim-1; k++) {
+ realr= qh_RANDOMint;
+ point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
+ }
+ }
+ qh_setdelaunay(qh, dim, numpoints, points);
+} /*.makeDelaunay.*/
+
+/*--------------------------------------------------
+-addDelaunay- add points to dim-1 Delaunay triangulation
+ points is numpoints+numnew X dim. Each point is projected to a paraboloid.
+notes:
+ qh_addpoint() does not make a copy of the point coordinates.
+
+ Since qh_addpoint() is not given a visible facet, it performs a directed
+ search of all facets. Algorithms that retain previously
+ constructed hulls may be faster.
+*/
+void addDelaunay(qhT *qh, coordT *points, int numpoints, int numnew, int dim) {
+ int j,k;
+ coordT *point, realr;
+ facetT *facet;
+ realT bestdist;
+ boolT isoutside;
+
+ for (j= 0; j < numnew ; j++) {
+ point= points + (numpoints+j)*dim;
+ if (points == qh->first_point) /* in case of 'QRn' */
+ qh->num_points= numpoints+j+1;
+ /* qh.num_points sets the size of the points array. You may
+ allocate the point elsewhere. If so, qh_addpoint records
+ the point's address in qh->other_points
+ */
+ for (k= 0; k < dim-1; k++) {
+ realr= qh_RANDOMint;
+ point[k]= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
+ }
+ qh_setdelaunay(qh, dim, 1, point);
+ facet= qh_findbestfacet(qh, point, !qh_ALL, &bestdist, &isoutside);
+ if (isoutside) {
+ if (!qh_addpoint(qh, point, facet, False))
+ break; /* user requested an early exit with 'TVn' or 'TCn' */
+ }
+ qh_printpoint(qh, stdout, "added point", point);
+ printf("%d points, %d extra points, %d vertices, and %d facets in total\n",
+ qh->num_points, qh_setsize(qh, qh->other_points),
+ qh->num_vertices, qh->num_facets);
+
+ /* qh_produce_output(qh); */
+ }
+ if (qh->DOcheckmax)
+ qh_check_maxout(qh);
+ else if (qh->KEEPnearinside)
+ qh_nearcoplanar(qh);
+} /*.addDelaunay.*/
+
+/*--------------------------------------------------
+-findDelaunay- find Delaunay triangle for [0.5,0.5,...]
+ assumes dim < 100
+notes:
+ calls qh_setdelaunay() to project the point to a parabaloid
+warning:
+ This is not implemented for tricoplanar facets ('Qt'),
+ See <a href="../html/qh-code.htm#findfacet">locate a facet with qh_findbestfacet()</a>
+*/
+void findDelaunay(qhT *qh, int dim) {
+ int k;
+ coordT point[ 100];
+ boolT isoutside;
+ realT bestdist;
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+
+ for (k= 0; k < dim-1; k++)
+ point[k]= 0.5;
+ qh_setdelaunay(qh, dim, 1, point);
+ facet= qh_findbestfacet(qh, point, qh_ALL, &bestdist, &isoutside);
+ if (facet->tricoplanar) {
+ fprintf(stderr, "findDelaunay: not implemented for triangulated, non-simplicial Delaunay regions (tricoplanar facet, f%d).\n",
+ facet->id);
+ qh_errexit(qh, qh_ERRqhull, facet, NULL);
+ }
+ FOREACHvertex_(facet->vertices) {
+ for (k=0; k < dim-1; k++)
+ printf("%5.2f ", vertex->point[k]);
+ printf("\n");
+ }
+} /*.findDelaunay.*/
+
+/*--------------------------------------------------
+-makehalf- set points to halfspaces for a (dim)-d diamond
+ points is numpoints X dim+1
+
+ each halfspace consists of dim coefficients followed by an offset
+*/
+void makehalf(coordT *points, int numpoints, int dim) {
+ int j,k;
+ coordT *point;
+
+ for (j=0; j<numpoints; j++) {
+ point= points + j*(dim+1);
+ point[dim]= -1.0; /* offset */
+ for (k=dim; k--; ) {
+ if (j & ( 1 << k))
+ point[k]= 1.0;
+ else
+ point[k]= -1.0;
+ }
+ }
+} /*.makehalf.*/
+
+/*--------------------------------------------------
+-addhalf- add halfspaces for a (dim)-d cube to the intersection
+ points is numpoints+numnew X dim+1
+notes:
+ assumes dim < 100.
+
+ For makehalf(), points is the initial set of halfspaces with offsets.
+ It is transformed by qh_sethalfspace_all into a
+ (dim)-d set of newpoints. Qhull computed the convex hull of newpoints -
+ this is equivalent to the halfspace intersection of the
+ orginal halfspaces.
+
+ For addhalf(), the remainder of points stores the transforms of
+ the added halfspaces. Qhull computes the convex hull of newpoints
+ and the added points. qh_addpoint() does not make a copy of these points.
+
+ Since halfspace intersection is equivalent to a convex hull,
+ qh_findbestfacet may perform an exhaustive search
+ for a visible facet. Algorithms that retain previously constructed
+ intersections should be faster for on-line construction.
+*/
+void addhalf(qhT *qh, coordT *points, int numpoints, int numnew, int dim, coordT *feasible) {
+ int j,k;
+ coordT *point, normal[100], offset, *next;
+ facetT *facet;
+ boolT isoutside;
+ realT bestdist;
+
+ for (j= 0; j < numnew ; j++) {
+ offset= -1.0;
+ for (k=dim; k--; ) {
+ if (j/2 == k) {
+ normal[k]= sqrt((coordT)dim); /* to normalize as in makehalf */
+ if (j & 1)
+ normal[k]= -normal[k];
+ }else
+ normal[k]= 0.0;
+ }
+ point= points + (numpoints+j)* (dim+1); /* does not use point[dim] */
+ qh_sethalfspace(qh, dim, point, &next, normal, &offset, feasible);
+ facet= qh_findbestfacet(qh, point, !qh_ALL, &bestdist, &isoutside);
+ if (isoutside) {
+ if (!qh_addpoint(qh, point, facet, False))
+ break; /* user requested an early exit with 'TVn' or 'TCn' */
+ }
+ qh_printpoint(qh, stdout, "added offset -1 and normal", normal);
+ printf("%d points, %d extra points, %d vertices, and %d facets in total\n",
+ qh->num_points, qh_setsize(qh, qh->other_points),
+ qh->num_vertices, qh->num_facets);
+ /* qh_produce_output(qh); */
+ }
+ if (qh->DOcheckmax)
+ qh_check_maxout(qh);
+ else if (qh->KEEPnearinside)
+ qh_nearcoplanar(qh);
+} /*.addhalf.*/
+
+#define DIM 3 /* dimension of points, must be < 31 for SIZEcube */
+#define SIZEcube (1<<DIM)
+#define SIZEdiamond (2*DIM)
+#define TOTpoints (SIZEcube + SIZEdiamond)
+
+/*--------------------------------------------------
+-main- Similar to unix.c, the main program for qhull
+
+ see program header
+
+ this contains three runs of Qhull for convex hull, Delaunay
+ triangulation or Voronoi vertices, and halfspace intersection
+
+*/
+int main(int argc, char *argv[]) {
+ boolT ismalloc;
+ int curlong, totlong, exitcode;
+ char options [2000];
+ qhT qh_qh;
+ qhT *qh= &qh_qh; /* Alternatively -- qhT *qh= (qhT*)malloc(sizeof(qhT)) */
+
+ QHULL_LIB_CHECK
+
+ printf("This is the output from user_eg2_r.c\n\n\
+It shows how qhull() may be called from an application using qhull's\n\
+static, reentrant library. user_eg2 is not part of qhull itself. If it\n\
+appears accidently, please remove user_eg2_r.c from your project. If it fails\n\
+immediately, user_eg2_r.c was incorrectly linked to the non-reentrant library.\n\
+Also try 'user_eg2 T1 2>&1'\n\n");
+
+ ismalloc= False; /* True if qh_freeqhull should 'free(array)' */
+ /*
+ Run 1: convex hull
+ */
+ qh_init_A(qh, stdin, stdout, stderr, 0, NULL);
+ exitcode= setjmp(qh->errexit);
+ if (!exitcode) {
+ coordT array[TOTpoints][DIM];
+
+ qh->NOerrexit= False;
+ strcat(qh->rbox_command, "user_eg2 cube example");
+ sprintf(options, "qhull s Tcv Q11 %s ", argc >= 2 ? argv[1] : "");
+ qh_initflags(qh, options);
+ printf( "\ncompute triangulated convex hull of cube after rotating input\n");
+ makecube(array[0], SIZEcube, DIM);
+ qh_init_B(qh, array[0], SIZEcube, DIM, ismalloc);
+ qh_qhull(qh);
+ qh_check_output(qh);
+ qh_triangulate(qh); /* requires option 'Q11' if want to add points */
+ print_summary(qh);
+ if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ printf( "\nadd points in a diamond\n");
+ adddiamond(qh, array[0], SIZEcube, SIZEdiamond, DIM);
+ qh_check_output(qh);
+ print_summary(qh);
+ qh_produce_output(qh); /* delete this line to help avoid io.c */
+ if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ }
+ qh->NOerrexit= True;
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
+ if (curlong || totlong)
+ fprintf(stderr, "qhull warning (user_eg2, run 1): did not free %d bytes of long memory (%d pieces)\n",
+ totlong, curlong);
+ /*
+ Run 2: Delaunay triangulation
+ */
+ qh_init_A(qh, stdin, stdout, stderr, 0, NULL);
+ exitcode= setjmp(qh->errexit);
+ if (!exitcode) {
+ coordT array[TOTpoints][DIM];
+
+ qh->NOerrexit= False;
+ strcat(qh->rbox_command, "user_eg2 Delaunay example");
+ sprintf(options, "qhull s d Tcv %s", argc >= 3 ? argv[2] : "");
+ qh_initflags(qh, options);
+ printf( "\ncompute %d-d Delaunay triangulation\n", DIM-1);
+ makeDelaunay(qh, array[0], SIZEcube, DIM);
+ /* Instead of makeDelaunay with qh_setdelaunay, you may
+ produce a 2-d array of points, set DIM to 2, and set
+ qh->PROJECTdelaunay to True. qh_init_B will call
+ qh_projectinput to project the points to the paraboloid
+ and add a point "at-infinity".
+ */
+ qh_init_B(qh, array[0], SIZEcube, DIM, ismalloc);
+ qh_qhull(qh);
+ /* If you want Voronoi ('v') without qh_produce_output(), call
+ qh_setvoronoi_all() after qh_qhull() */
+ qh_check_output(qh);
+ print_summary(qh);
+ qh_produce_output(qh); /* delete this line to help avoid io.c */
+ if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ printf( "\nadd points to triangulation\n");
+ addDelaunay(qh, array[0], SIZEcube, SIZEdiamond, DIM);
+ qh_check_output(qh);
+ qh_produce_output(qh); /* delete this line to help avoid io.c */
+ if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ printf( "\nfind Delaunay triangle closest to [0.5, 0.5, ...]\n");
+ findDelaunay(qh, DIM);
+ }
+ qh->NOerrexit= True;
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
+ if (curlong || totlong)
+ fprintf(stderr, "qhull warning (user_eg2, run 2): did not free %d bytes of long memory (%d pieces)\n",
+ totlong, curlong);
+ /*
+ Run 3: halfspace intersection
+ */
+ qh_init_A(qh, stdin, stdout, stderr, 0, NULL);
+ exitcode= setjmp(qh->errexit);
+ if (!exitcode) {
+ coordT array[TOTpoints][DIM+1]; /* +1 for halfspace offset */
+ pointT *points;
+
+ qh->NOerrexit= False;
+ strcat(qh->rbox_command, "user_eg2 halfspace example");
+ sprintf(options, "qhull H0 s Tcv %s", argc >= 4 ? argv[3] : "");
+ qh_initflags(qh, options);
+ printf( "\ncompute halfspace intersection about the origin for a diamond\n");
+ makehalf(array[0], SIZEcube, DIM);
+ qh_setfeasible(qh, DIM); /* from io.c, sets qh->feasible_point from 'Hn,n' */
+ /* you may malloc and set qh->feasible_point directly. It is only used for
+ option 'Fp' */
+ points= qh_sethalfspace_all(qh, DIM+1, SIZEcube, array[0], qh->feasible_point);
+ qh_init_B(qh, points, SIZEcube, DIM, True); /* qh_freeqhull frees points */
+ qh_qhull(qh);
+ qh_check_output(qh);
+ qh_produce_output(qh); /* delete this line to help avoid io.c */
+ if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ printf( "\nadd halfspaces for cube to intersection\n");
+ addhalf(qh, array[0], SIZEcube, SIZEdiamond, DIM, qh->feasible_point);
+ qh_check_output(qh);
+ qh_produce_output(qh); /* delete this line to help avoid io.c */
+ if (qh->VERIFYoutput && !qh->STOPpoint && !qh->STOPcone)
+ qh_check_points(qh);
+ }
+ qh->NOerrexit= True;
+ qh->NOerrexit= True;
+ qh_freeqhull(qh, !qh_ALL);
+ qh_memfreeshort(qh, &curlong, &totlong);
+ if (curlong || totlong)
+ fprintf(stderr, "qhull warning (user_eg2, run 3): did not free %d bytes of long memory (%d pieces)\n",
+ totlong, curlong);
+ return exitcode;
+} /* main */
+
+#if 1 /* use 1 to prevent loading of io.o and user.o */
+/*-------------------------------------------
+-errexit- return exitcode to system after an error
+ assumes exitcode non-zero
+ prints useful information
+ see qh_errexit2() in libqhull.c for 2 facets
+*/
+void qh_errexit(qhT *qh, int exitcode, facetT *facet, ridgeT *ridge) {
+ QHULL_UNUSED(facet);
+ QHULL_UNUSED(ridge);
+
+ if (qh->ERREXITcalled) {
+ fprintf(qh->ferr, "qhull error while processing previous error. Exit program\n");
+ exit(1);
+ }
+ qh->ERREXITcalled= True;
+ if (!qh->QHULLfinished)
+ qh->hulltime= (unsigned)clock() - qh->hulltime;
+ fprintf(qh->ferr, "\nWhile executing: %s | %s\n", qh->rbox_command, qh->qhull_command);
+ fprintf(qh->ferr, "Options selected:\n%s\n", qh->qhull_options);
+ if (qh->furthest_id >= 0) {
+ fprintf(qh->ferr, "\nLast point added to hull was p%d", qh->furthest_id);
+ if (zzval_(Ztotmerge))
+ fprintf(qh->ferr, " Last merge was #%d.", zzval_(Ztotmerge));
+ if (qh->QHULLfinished)
+ fprintf(qh->ferr, "\nQhull has finished constructing the hull.");
+ else if (qh->POSTmerging)
+ fprintf(qh->ferr, "\nQhull has started post-merging");
+ fprintf(qh->ferr, "\n\n");
+ }
+ if (qh->NOerrexit) {
+ fprintf(qh->ferr, "qhull error while ending program. Exit program\n");
+ exit(1);
+ }
+ if (!exitcode)
+ exitcode= qh_ERRqhull;
+ qh->NOerrexit= True;
+ longjmp(qh->errexit, exitcode);
+} /* errexit */
+
+
+/*-------------------------------------------
+-errprint- prints out the information of the erroneous object
+ any parameter may be NULL, also prints neighbors and geomview output
+*/
+void qh_errprint(qhT *qh, const char *string, facetT *atfacet, facetT *otherfacet, ridgeT *atridge, vertexT *atvertex) {
+
+ fprintf(qh->ferr, "%s facets f%d f%d ridge r%d vertex v%d\n",
+ string, getid_(atfacet), getid_(otherfacet), getid_(atridge),
+ getid_(atvertex));
+} /* errprint */
+
+
+void qh_printfacetlist(qhT *qh, facetT *facetlist, setT *facets, boolT printall) {
+ facetT *facet, **facetp;
+
+ /* remove these calls to help avoid io.c */
+ qh_printbegin(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall);/*io.c*/
+ FORALLfacet_(facetlist) /*io.c*/
+ qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall); /*io.c*/
+ FOREACHfacet_(facets) /*io.c*/
+ qh_printafacet(qh, qh->ferr, qh_PRINTfacets, facet, printall); /*io.c*/
+ qh_printend(qh, qh->ferr, qh_PRINTfacets, facetlist, facets, printall); /*io.c*/
+
+ FORALLfacet_(facetlist)
+ fprintf( qh->ferr, "facet f%d\n", facet->id);
+} /* printfacetlist */
+
+/* qh_printhelp_degenerate( fp )
+ prints descriptive message for precision error
+
+ notes:
+ no message if qh_QUICKhelp
+*/
+void qh_printhelp_degenerate(qhT *qh, FILE *fp) {
+
+ if (qh->MERGEexact || qh->PREmerge || qh->JOGGLEmax < REALmax/2)
+ qh_fprintf(qh, fp, 9368, "\n\
+A Qhull error has occurred. Qhull should have corrected the above\n\
+precision error. Please send the input and all of the output to\n\
+qhull_bug@qhull.org\n");
+ else if (!qh_QUICKhelp) {
+ qh_fprintf(qh, fp, 9369, "\n\
+Precision problems were detected during construction of the convex hull.\n\
+This occurs because convex hull algorithms assume that calculations are\n\
+exact, but floating-point arithmetic has roundoff errors.\n\
+\n\
+To correct for precision problems, do not use 'Q0'. By default, Qhull\n\
+selects 'C-0' or 'Qx' and merges non-convex facets. With option 'QJ',\n\
+Qhull joggles the input to prevent precision problems. See \"Imprecision\n\
+in Qhull\" (qh-impre.htm).\n\
+\n\
+If you use 'Q0', the output may include\n\
+coplanar ridges, concave ridges, and flipped facets. In 4-d and higher,\n\
+Qhull may produce a ridge with four neighbors or two facets with the same \n\
+vertices. Qhull reports these events when they occur. It stops when a\n\
+concave ridge, flipped facet, or duplicate facet occurs.\n");
+#if REALfloat
+ qh_fprintf(qh, fp, 9370, "\
+\n\
+Qhull is currently using single precision arithmetic. The following\n\
+will probably remove the precision problems:\n\
+ - recompile qhull for realT precision(#define REALfloat 0 in user.h).\n");
+#endif
+ if (qh->DELAUNAY && !qh->SCALElast && qh->MAXabs_coord > 1e4)
+ qh_fprintf(qh, fp, 9371, "\
+\n\
+When computing the Delaunay triangulation of coordinates > 1.0,\n\
+ - use 'Qbb' to scale the last coordinate to [0,m] (max previous coordinate)\n");
+ if (qh->DELAUNAY && !qh->ATinfinity)
+ qh_fprintf(qh, fp, 9372, "\
+When computing the Delaunay triangulation:\n\
+ - use 'Qz' to add a point at-infinity. This reduces precision problems.\n");
+
+ qh_fprintf(qh, fp, 9373, "\
+\n\
+If you need triangular output:\n\
+ - use option 'Qt' to triangulate the output\n\
+ - use option 'QJ' to joggle the input points and remove precision errors\n\
+ - use option 'Ft'. It triangulates non-simplicial facets with added points.\n\
+\n\
+If you must use 'Q0',\n\
+try one or more of the following options. They can not guarantee an output.\n\
+ - use 'QbB' to scale the input to a cube.\n\
+ - use 'Po' to produce output and prevent partitioning for flipped facets\n\
+ - use 'V0' to set min. distance to visible facet as 0 instead of roundoff\n\
+ - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
+ - options 'Qf', 'Qbb', and 'QR0' may also help\n",
+ qh->DISTround);
+ qh_fprintf(qh, fp, 9374, "\
+\n\
+To guarantee simplicial output:\n\
+ - use option 'Qt' to triangulate the output\n\
+ - use option 'QJ' to joggle the input points and remove precision errors\n\
+ - use option 'Ft' to triangulate the output by adding points\n\
+ - use exact arithmetic (see \"Imprecision in Qhull\", qh-impre.htm)\n\
+");
+ }
+} /* printhelp_degenerate */
+
+
+/* qh_printhelp_narrowhull( minangle )
+ Warn about a narrow hull
+
+ notes:
+ Alternatively, reduce qh_WARNnarrow in user.h
+
+*/
+void qh_printhelp_narrowhull(qhT *qh, FILE *fp, realT minangle) {
+
+ qh_fprintf(qh, fp, 9375, "qhull precision warning: \n\
+The initial hull is narrow (cosine of min. angle is %.16f).\n\
+A coplanar point may lead to a wide facet. Options 'QbB' (scale to unit box)\n\
+or 'Qbb' (scale last coordinate) may remove this warning. Use 'Pp' to skip\n\
+this warning. See 'Limitations' in qh-impre.htm.\n",
+ -minangle); /* convert from angle between normals to angle between facets */
+} /* printhelp_narrowhull */
+
+/* qh_printhelp_singular
+ prints descriptive message for singular input
+*/
+void qh_printhelp_singular(qhT *qh, FILE *fp) {
+ facetT *facet;
+ vertexT *vertex, **vertexp;
+ realT min, max, *coord, dist;
+ int i,k;
+
+ qh_fprintf(qh, fp, 9376, "\n\
+The input to qhull appears to be less than %d dimensional, or a\n\
+computation has overflowed.\n\n\
+Qhull could not construct a clearly convex simplex from points:\n",
+ qh->hull_dim);
+ qh_printvertexlist(qh, fp, "", qh->facet_list, NULL, qh_ALL);
+ if (!qh_QUICKhelp)
+ qh_fprintf(qh, fp, 9377, "\n\
+The center point is coplanar with a facet, or a vertex is coplanar\n\
+with a neighboring facet. The maximum round off error for\n\
+computing distances is %2.2g. The center point, facets and distances\n\
+to the center point are as follows:\n\n", qh->DISTround);
+ qh_printpointid(qh, fp, "center point", qh->hull_dim, qh->interior_point, -1);
+ qh_fprintf(qh, fp, 9378, "\n");
+ FORALLfacets {
+ qh_fprintf(qh, fp, 9379, "facet");
+ FOREACHvertex_(facet->vertices)
+ qh_fprintf(qh, fp, 9380, " p%d", qh_pointid(qh, vertex->point));
+ zinc_(Zdistio);
+ qh_distplane(qh, qh->interior_point, facet, &dist);
+ qh_fprintf(qh, fp, 9381, " distance= %4.2g\n", dist);
+ }
+ if (!qh_QUICKhelp) {
+ if (qh->HALFspace)
+ qh_fprintf(qh, fp, 9382, "\n\
+These points are the dual of the given halfspaces. They indicate that\n\
+the intersection is degenerate.\n");
+ qh_fprintf(qh, fp, 9383,"\n\
+These points either have a maximum or minimum x-coordinate, or\n\
+they maximize the determinant for k coordinates. Trial points\n\
+are first selected from points that maximize a coordinate.\n");
+ if (qh->hull_dim >= qh_INITIALmax)
+ qh_fprintf(qh, fp, 9384, "\n\
+Because of the high dimension, the min x-coordinate and max-coordinate\n\
+points are used if the determinant is non-zero. Option 'Qs' will\n\
+do a better, though much slower, job. Instead of 'Qs', you can change\n\
+the points by randomly rotating the input with 'QR0'.\n");
+ }
+ qh_fprintf(qh, fp, 9385, "\nThe min and max coordinates for each dimension are:\n");
+ for (k=0; k < qh->hull_dim; k++) {
+ min= REALmax;
+ max= -REALmin;
+ for (i=qh->num_points, coord= qh->first_point+k; i--; coord += qh->hull_dim) {
+ maximize_(max, *coord);
+ minimize_(min, *coord);
+ }
+ qh_fprintf(qh, fp, 9386, " %d: %8.4g %8.4g difference= %4.4g\n", k, min, max, max-min);
+ }
+ if (!qh_QUICKhelp) {
+ qh_fprintf(qh, fp, 9387, "\n\
+If the input should be full dimensional, you have several options that\n\
+may determine an initial simplex:\n\
+ - use 'QJ' to joggle the input and make it full dimensional\n\
+ - use 'QbB' to scale the points to the unit cube\n\
+ - use 'QR0' to randomly rotate the input for different maximum points\n\
+ - use 'Qs' to search all points for the initial simplex\n\
+ - use 'En' to specify a maximum roundoff error less than %2.2g.\n\
+ - trace execution with 'T3' to see the determinant for each point.\n",
+ qh->DISTround);
+#if REALfloat
+ qh_fprintf(qh, fp, 9388, "\
+ - recompile qhull for realT precision(#define REALfloat 0 in libqhull.h).\n");
+#endif
+ qh_fprintf(qh, fp, 9389, "\n\
+If the input is lower dimensional:\n\
+ - use 'QJ' to joggle the input and make it full dimensional\n\
+ - use 'Qbk:0Bk:0' to delete coordinate k from the input. You should\n\
+ pick the coordinate with the least range. The hull will have the\n\
+ correct topology.\n\
+ - determine the flat containing the points, rotate the points\n\
+ into a coordinate plane, and delete the other coordinates.\n\
+ - add one or more points to make the input full dimensional.\n\
+");
+ if (qh->DELAUNAY && !qh->ATinfinity)
+ qh_fprintf(qh, fp, 9390, "\n\n\
+This is a Delaunay triangulation and the input is co-circular or co-spherical:\n\
+ - use 'Qz' to add a point \"at infinity\" (i.e., above the paraboloid)\n\
+ - or use 'QJ' to joggle the input and avoid co-circular data\n");
+ }
+} /* printhelp_singular */
+
+
+/*-----------------------------------------
+-user_memsizes- allocate up to 10 additional, quick allocation sizes
+*/
+void qh_user_memsizes(qhT *qh) {
+
+ QHULL_UNUSED(qh);
+ /* qh_memsize(qh, size); */
+} /* user_memsizes */
+
+#endif
diff --git a/xs/src/qhull/src/user_eg3/user_eg3.pro b/xs/src/qhull/src/user_eg3/user_eg3.pro
new file mode 100644
index 000000000..35372fbf9
--- /dev/null
+++ b/xs/src/qhull/src/user_eg3/user_eg3.pro
@@ -0,0 +1,12 @@
+# -------------------------------------------------
+# user_eg3.pro -- Qt project for cpp demonstration user_eg3.exe
+#
+# The C++ interface requires reentrant Qhull.
+# -------------------------------------------------
+
+include(../qhull-app-cpp.pri)
+
+TARGET = user_eg3
+CONFIG -= qt
+
+SOURCES += user_eg3_r.cpp
diff --git a/xs/src/qhull/src/user_eg3/user_eg3_r.cpp b/xs/src/qhull/src/user_eg3/user_eg3_r.cpp
new file mode 100644
index 000000000..5257872ab
--- /dev/null
+++ b/xs/src/qhull/src/user_eg3/user_eg3_r.cpp
@@ -0,0 +1,162 @@
+#//! user_eg3_r.cpp -- Invoke rbox and qhull from C++
+
+#include "libqhullcpp/RboxPoints.h"
+#include "libqhullcpp/QhullError.h"
+#include "libqhullcpp/QhullQh.h"
+#include "libqhullcpp/QhullFacet.h"
+#include "libqhullcpp/QhullFacetList.h"
+#include "libqhullcpp/QhullLinkedList.h"
+#include "libqhullcpp/QhullVertex.h"
+#include "libqhullcpp/Qhull.h"
+
+#include <cstdio> /* for printf() of help message */
+#include <ostream>
+#include <stdexcept>
+
+using std::cerr;
+using std::cin;
+using std::cout;
+using std::endl;
+
+using orgQhull::Qhull;
+using orgQhull::QhullError;
+using orgQhull::QhullFacet;
+using orgQhull::QhullFacetList;
+using orgQhull::QhullQh;
+using orgQhull::RboxPoints;
+using orgQhull::QhullVertex;
+using orgQhull::QhullVertexSet;
+
+int main(int argc, char **argv);
+int user_eg3(int argc, char **argv);
+
+char prompt[]= "\n\
+user_eg3 -- demonstrate calling rbox and qhull from C++.\n\
+\n\
+user_eg3 is statically linked to reentrant qhull. If user_eg3\n\
+fails immediately, it is probably linked to the non-reentrant qhull.\n\
+Try 'user_eg3 rbox qhull \"T1\"'\n\
+\n\
+ eg-100 Run the example in qh-code.htm\n\
+ rbox \"200 D4\" ... Generate points from rbox\n\
+ qhull \"d p\" ... Run qhull and produce output\n\
+ qhull-cout \"o\" ... Run qhull and produce output to cout\n\
+ qhull \"T1\" ... Run qhull with level-1 trace to cerr\n\
+ facets Print facets when done\n\
+\n\
+For example\n\
+ user_eg3 rbox qhull\n\
+ user_eg3 rbox qhull d\n\
+ user_eg3 rbox \"10 D2\" \"2 D2\" qhull \"s p\" facets\n\
+\n\
+";
+
+
+/*--------------------------------------------
+-user_eg3- main procedure of user_eg3 application
+*/
+int main(int argc, char **argv) {
+
+ QHULL_LIB_CHECK
+
+ if(argc==1){
+ cout << prompt;
+ return 1;
+ }
+ try{
+ return user_eg3(argc, argv);
+ }catch(QhullError &e){
+ cerr << e.what() << std::endl;
+ return e.errorCode();
+ }
+}//main
+
+int user_eg3(int argc, char **argv)
+{
+ if(strcmp(argv[1], "eg-100")==0){
+ RboxPoints rbox("100");
+ Qhull q(rbox, "");
+ QhullFacetList facets= q.facetList();
+ cout << facets;
+ return 0;
+ }
+ bool printFacets= false;
+ RboxPoints rbox;
+ Qhull qhull;
+ int readingRbox= 0;
+ int readingQhull= 0;
+ for(int i=1; i<argc; i++){
+ if(strcmp(argv[i], "rbox")==0){
+ if(readingRbox!=0 || readingQhull!=0){
+ cerr << "user_eg3 -- \"rbox\" must be first" << endl;
+ return 1;
+ }
+ readingRbox++;
+ }else if(strcmp(argv[i], "qhull")==0
+ || strcmp(argv[i], "qhull-cout")==0){
+ if(readingQhull){
+ cerr << "user_eg3 -- only one \"qhull\" or \"qhull-cout\" allowed." << endl;
+ return 1;
+ }
+ if(strcmp(argv[i], "qhull-cout")==0){
+ qhull.setOutputStream(&cout);
+ }
+ if(rbox.isEmpty()){
+ if(readingRbox){
+ rbox.appendPoints("10 D2");
+ }else{
+ cerr << "Enter dimension count coordinates. End with ^Z (Windows) or ^D (Unix).\n";
+ rbox.appendPoints(cin);
+ }
+ }
+ readingQhull++;
+ readingRbox= 0;
+ }else if(strcmp(argv[i], "facets")==0){
+ printFacets= true;
+ }else if(readingRbox){
+ readingRbox++;
+ cerr << "rbox " << argv[i] << endl;
+ rbox.appendPoints(argv[i]);
+ if(rbox.hasRboxMessage()){
+ cerr << "user_eg3 " << argv[i] << " -- " << rbox.rboxMessage();
+ return rbox.rboxStatus();
+ }
+ }else if(readingQhull){
+ if(readingQhull==1){
+ qhull.runQhull(rbox, argv[i]);
+ qhull.outputQhull();
+ }else{
+ qhull.outputQhull(argv[i]);
+ }
+ readingQhull++;
+ if(qhull.hasQhullMessage()){
+ cerr << "\nResults of " << argv[i] << "\n" << qhull.qhullMessage();
+ qhull.clearQhullMessage();
+ }
+ }else{
+ cerr << "user_eg3 error: Expecting qhull, qhull-cout, or rbox. Got " << argv[i] << endl;
+ return 1;
+ }
+ }//foreach argv
+ if(readingRbox){
+ cout << rbox;
+ return 0;
+ }
+ if(readingQhull==1){ // e.g., rbox 10 qhull
+ qhull.runQhull(rbox, "");
+ qhull.outputQhull();
+ if(qhull.hasQhullMessage()){
+ cerr << "\nResults of qhull\n" << qhull.qhullMessage();
+ qhull.clearQhullMessage();
+ }
+ }
+ if(qhull.hasOutputStream()){
+ return 0;
+ }
+ if(printFacets){
+ QhullFacetList facets= qhull.facetList();
+ cout << "\nFacets created by Qhull::runQhull()\n" << facets;
+ }
+ return 0;
+}//user_eg3
+
diff --git a/xs/src/semver/semver.c b/xs/src/semver/semver.c
new file mode 100644
index 000000000..527738644
--- /dev/null
+++ b/xs/src/semver/semver.c
@@ -0,0 +1,640 @@
+/*
+ * semver.c
+ *
+ * Copyright (c) 2015-2017 Tomas Aparicio
+ * MIT licensed
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "semver.h"
+
+#define SLICE_SIZE 50
+#define DELIMITER "."
+#define PR_DELIMITER "-"
+#define MT_DELIMITER "+"
+#define NUMBERS "0123456789"
+#define ALPHA "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define DELIMITERS DELIMITER PR_DELIMITER MT_DELIMITER
+#define VALID_CHARS NUMBERS ALPHA DELIMITERS
+
+static const size_t MAX_SIZE = sizeof(char) * 255;
+static const int MAX_SAFE_INT = (unsigned int) -1 >> 1;
+
+/**
+ * Define comparison operators, storing the
+ * ASCII code per each symbol in hexadecimal notation.
+ */
+
+enum operators {
+ SYMBOL_GT = 0x3e,
+ SYMBOL_LT = 0x3c,
+ SYMBOL_EQ = 0x3d,
+ SYMBOL_TF = 0x7e,
+ SYMBOL_CF = 0x5e
+};
+
+/**
+ * Private helpers
+ */
+
+/*
+ * Remove [begin:len-begin] from str by moving len data from begin+len to begin.
+ * If len is negative cut out to the end of the string.
+ */
+static int
+strcut (char *str, int begin, int len) {
+ size_t l;
+ l = strlen(str);
+
+ if((int)l < 0 || (int)l > MAX_SAFE_INT) return -1;
+
+ if (len < 0) len = l - begin + 1;
+ if (begin + len > (int)l) len = l - begin;
+ memmove(str + begin, str + begin + len, l - len + 1 - begin);
+
+ return len;
+}
+
+static int
+contains (const char c, const char *matrix, size_t len) {
+ size_t x;
+ for (x = 0; x < len; x++)
+ if ((char) matrix[x] == c) return 1;
+ return 0;
+}
+
+static int
+has_valid_chars (const char *str, const char *matrix) {
+ size_t i, len, mlen;
+ len = strlen(str);
+ mlen = strlen(matrix);
+
+ for (i = 0; i < len; i++)
+ if (contains(str[i], matrix, mlen) == 0)
+ return 0;
+
+ return 1;
+}
+
+static int
+binary_comparison (int x, int y) {
+ if (x == y) return 0;
+ if (x > y) return 1;
+ return -1;
+}
+
+static int
+parse_int (const char *s) {
+ int valid, num;
+ valid = has_valid_chars(s, NUMBERS);
+ if (valid == 0) return -1;
+
+ num = strtol(s, NULL, 10);
+ if (num > MAX_SAFE_INT) return -1;
+
+ return num;
+}
+
+/*
+ * Return a string allocated on the heap with the content from sep to end and
+ * terminate buf at sep.
+ */
+static char *
+parse_slice (char *buf, char sep) {
+ char *pr, *part;
+ int plen;
+
+ /* Find separator in buf */
+ pr = strchr(buf, sep);
+ if (pr == NULL) return NULL;
+ /* Length from separator to end of buf */
+ plen = strlen(pr);
+
+ /* Copy from buf into new string */
+ part = calloc(plen + 1, sizeof(*part));
+ if (part == NULL) return NULL;
+ memcpy(part, pr + 1, plen);
+ /* Null terminate new string */
+ part[plen] = '\0';
+
+ /* Terminate buf where separator was */
+ *pr = '\0';
+
+ return part;
+}
+
+/**
+ * Parses a string as semver expression.
+ *
+ * Returns:
+ *
+ * `0` - Parsed successfully
+ * `-1` - In case of error
+ */
+
+int
+semver_parse (const char *str, semver_t *ver) {
+ int valid, res;
+ size_t len;
+ char *buf;
+ valid = semver_is_valid(str);
+ if (!valid) return -1;
+
+ len = strlen(str);
+ buf = calloc(len + 1, sizeof(*buf));
+ if (buf == NULL) return -1;
+ strcpy(buf, str);
+
+ ver->metadata = parse_slice(buf, MT_DELIMITER[0]);
+ ver->prerelease = parse_slice(buf, PR_DELIMITER[0]);
+
+ res = semver_parse_version(buf, ver);
+ free(buf);
+#if DEBUG > 0
+ printf("[debug] semver.c %s = %d.%d.%d, %s %s\n", str, ver->major, ver->minor, ver->patch, ver->prerelease, ver->metadata);
+#endif
+ return res;
+}
+
+/**
+ * Parses a given string as semver expression.
+ *
+ * Returns:
+ *
+ * `0` - Parsed successfully
+ * `-1` - Parse error or invalid
+ */
+
+int
+semver_parse_version (const char *str, semver_t *ver) {
+ size_t len;
+ int index, value;
+ char *slice, *next, *endptr;
+ slice = (char *) str;
+ index = 0;
+
+ // non mandatory
+ ver->patch = 0;
+
+ while (slice != NULL && index++ < 4) {
+ next = strchr(slice, DELIMITER[0]);
+ if (next == NULL)
+ len = strlen(slice);
+ else
+ len = next - slice;
+ if (len > SLICE_SIZE) return -1;
+
+ /* Cast to integer and store */
+ value = strtol(slice, &endptr, 10);
+ if (endptr != next && *endptr != '\0') return -1;
+
+ switch (index) {
+ case 1: ver->major = value; break;
+ case 2: ver->minor = value; break;
+ case 3: ver->patch = value; break;
+ }
+
+ /* Continue with the next slice */
+ if (next == NULL)
+ slice = NULL;
+ else
+ slice = next + 1;
+ }
+
+ // Major and minor versions are mandatory, patch version is not mandatory.
+ return (index == 2 || index == 3) ? 0 : -1;
+}
+
+static int
+compare_prerelease (char *x, char *y) {
+ char *lastx, *lasty, *xptr, *yptr, *endptr;
+ int xlen, ylen, xisnum, yisnum, xnum, ynum;
+ int xn, yn, min, res;
+ if (x == NULL && y == NULL) return 0;
+ if (y == NULL && x) return -1;
+ if (x == NULL && y) return 1;
+
+ lastx = x;
+ lasty = y;
+ xlen = strlen(x);
+ ylen = strlen(y);
+
+ while (1) {
+ if ((xptr = strchr(lastx, DELIMITER[0])) == NULL)
+ xptr = x + xlen;
+ if ((yptr = strchr(lasty, DELIMITER[0])) == NULL)
+ yptr = y + ylen;
+
+ xnum = strtol(lastx, &endptr, 10);
+ xisnum = endptr == xptr ? 1 : 0;
+ ynum = strtol(lasty, &endptr, 10);
+ yisnum = endptr == yptr ? 1 : 0;
+
+ if (xisnum && !yisnum) return -1;
+ if (!xisnum && yisnum) return 1;
+
+ if (xisnum && yisnum) {
+ /* Numerical comparison */
+ if (xnum != ynum) return xnum < ynum ? -1 : 1;
+ } else {
+ /* String comparison */
+ xn = xptr - lastx;
+ yn = yptr - lasty;
+ min = xn < yn ? xn : yn;
+ if ((res = strncmp(lastx, lasty, min))) return res < 0 ? -1 : 1;
+ if (xn != yn) return xn < yn ? -1 : 1;
+ }
+
+ lastx = xptr + 1;
+ lasty = yptr + 1;
+ if (lastx == x + xlen + 1 && lasty == y + ylen + 1) break;
+ if (lastx == x + xlen + 1) return -1;
+ if (lasty == y + ylen + 1) return 1;
+ }
+
+ return 0;
+}
+
+int
+semver_compare_prerelease (semver_t x, semver_t y) {
+ return compare_prerelease(x.prerelease, y.prerelease);
+}
+
+/**
+ * Performs a major, minor and patch binary comparison (x, y).
+ * This function is mostly used internally
+ *
+ * Returns:
+ *
+ * `0` - If versiona are equal
+ * `1` - If x is higher than y
+ * `-1` - If x is lower than y
+ */
+
+int
+semver_compare_version (semver_t x, semver_t y) {
+ int res;
+
+ if ((res = binary_comparison(x.major, y.major)) == 0) {
+ if ((res = binary_comparison(x.minor, y.minor)) == 0) {
+ return binary_comparison(x.patch, y.patch);
+ }
+ }
+
+ return res;
+}
+
+/**
+ * Compare two semantic versions (x, y).
+ *
+ * Returns:
+ * - `1` if x is higher than y
+ * - `0` if x is equal to y
+ * - `-1` if x is lower than y
+ */
+
+int
+semver_compare (semver_t x, semver_t y) {
+ int res;
+
+ if ((res = semver_compare_version(x, y)) == 0) {
+ return semver_compare_prerelease(x, y);
+ }
+
+ return res;
+}
+
+/**
+ * Performs a `greater than` comparison
+ */
+
+int
+semver_gt (semver_t x, semver_t y) {
+ return semver_compare(x, y) == 1;
+}
+
+/**
+ * Performs a `lower than` comparison
+ */
+
+int
+semver_lt (semver_t x, semver_t y) {
+ return semver_compare(x, y) == -1;
+}
+
+/**
+ * Performs a `equality` comparison
+ */
+
+int
+semver_eq (semver_t x, semver_t y) {
+ return semver_compare(x, y) == 0;
+}
+
+/**
+ * Performs a `non equal to` comparison
+ */
+
+int
+semver_neq (semver_t x, semver_t y) {
+ return semver_compare(x, y) != 0;
+}
+
+/**
+ * Performs a `greater than or equal` comparison
+ */
+
+int
+semver_gte (semver_t x, semver_t y) {
+ return semver_compare(x, y) >= 0;
+}
+
+/**
+ * Performs a `lower than or equal` comparison
+ */
+
+int
+semver_lte (semver_t x, semver_t y) {
+ return semver_compare(x, y) <= 0;
+}
+
+/**
+ * Checks if version `x` can be satisfied by `y`
+ * performing a comparison with caret operator.
+ *
+ * See: https://docs.npmjs.com/misc/semver#caret-ranges-1-2-3-0-2-5-0-0-4
+ *
+ * Returns:
+ *
+ * `1` - Can be satisfied
+ * `0` - Cannot be satisfied
+ */
+
+int
+semver_satisfies_caret (semver_t x, semver_t y) {
+ if (x.major == y.major) {
+ if (x.major == 0) {
+ return x.minor >= y.minor;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * Checks if version `x` can be satisfied by `y`
+ * performing a comparison with tilde operator.
+ *
+ * See: https://docs.npmjs.com/misc/semver#tilde-ranges-1-2-3-1-2-1
+ *
+ * Returns:
+ *
+ * `1` - Can be satisfied
+ * `0` - Cannot be satisfied
+ */
+
+int
+semver_satisfies_patch (semver_t x, semver_t y) {
+ return x.major == y.major
+ && x.minor == y.minor;
+}
+
+/**
+ * Checks if both versions can be satisfied
+ * based on the given comparison operator.
+ *
+ * Allowed operators:
+ *
+ * - `=` - Equality
+ * - `>=` - Higher or equal to
+ * - `<=` - Lower or equal to
+ * - `<` - Lower than
+ * - `>` - Higher than
+ * - `^` - Caret comparison (see https://docs.npmjs.com/misc/semver#caret-ranges-1-2-3-0-2-5-0-0-4)
+ * - `~` - Tilde comparison (see https://docs.npmjs.com/misc/semver#tilde-ranges-1-2-3-1-2-1)
+ *
+ * Returns:
+ *
+ * `1` - Can be satisfied
+ * `0` - Cannot be satisfied
+ */
+
+int
+semver_satisfies (semver_t x, semver_t y, const char *op) {
+ int first, second;
+ /* Extract the comparison operator */
+ first = op[0];
+ second = op[1];
+
+ /* Caret operator */
+ if (first == SYMBOL_CF)
+ return semver_satisfies_caret(x, y);
+
+ /* Tilde operator */
+ if (first == SYMBOL_TF)
+ return semver_satisfies_patch(x, y);
+
+ /* Strict equality */
+ if (first == SYMBOL_EQ)
+ return semver_eq(x, y);
+
+ /* Greater than or equal comparison */
+ if (first == SYMBOL_GT) {
+ if (second == SYMBOL_EQ) {
+ return semver_gte(x, y);
+ }
+ return semver_gt(x, y);
+ }
+
+ /* Lower than or equal comparison */
+ if (first == SYMBOL_LT) {
+ if (second == SYMBOL_EQ) {
+ return semver_lte(x, y);
+ }
+ return semver_lt(x, y);
+ }
+
+ return 0;
+}
+
+/**
+ * Free heep allocated memory of a given semver.
+ * This is just a convenient function that you
+ * should call when you're done.
+ */
+
+void
+semver_free (semver_t *x) {
+ if (x->metadata) {
+ free(x->metadata);
+ x->metadata = NULL;
+ }
+ if (x->prerelease) {
+ free(x->prerelease);
+ x->prerelease = NULL;
+ }
+}
+
+/**
+ * Renders
+ */
+
+static void
+concat_num (char * str, int x, char * sep) {
+ char buf[SLICE_SIZE] = {0};
+ if (sep == NULL) sprintf(buf, "%d", x);
+ else sprintf(buf, "%s%d", sep, x);
+ strcat(str, buf);
+}
+
+static void
+concat_char (char * str, char * x, char * sep) {
+ char buf[SLICE_SIZE] = {0};
+ sprintf(buf, "%s%s", sep, x);
+ strcat(str, buf);
+}
+
+/**
+ * Render a given semver as string
+ */
+
+void
+semver_render (semver_t *x, char *dest) {
+ if (x->major) concat_num(dest, x->major, NULL);
+ if (x->minor) concat_num(dest, x->minor, DELIMITER);
+ if (x->patch) concat_num(dest, x->patch, DELIMITER);
+ if (x->prerelease) concat_char(dest, x->prerelease, PR_DELIMITER);
+ if (x->metadata) concat_char(dest, x->metadata, MT_DELIMITER);
+}
+
+/**
+ * Version bump helpers
+ */
+
+void
+semver_bump (semver_t *x) {
+ x->major++;
+}
+
+void
+semver_bump_minor (semver_t *x) {
+ x->minor++;
+}
+
+void
+semver_bump_patch (semver_t *x) {
+ x->patch++;
+}
+
+/**
+ * Helpers
+ */
+
+static int
+has_valid_length (const char *s) {
+ return strlen(s) <= MAX_SIZE;
+}
+
+/**
+ * Checks if a given semver string is valid
+ *
+ * Returns:
+ *
+ * `1` - Valid expression
+ * `0` - Invalid
+ */
+
+int
+semver_is_valid (const char *s) {
+ return has_valid_length(s)
+ && has_valid_chars(s, VALID_CHARS);
+}
+
+/**
+ * Removes non-valid characters in the given string.
+ *
+ * Returns:
+ *
+ * `0` - Valid
+ * `-1` - Invalid input
+ */
+
+int
+semver_clean (char *s) {
+ size_t i, len, mlen;
+ int res;
+ if (has_valid_length(s) == 0) return -1;
+
+ len = strlen(s);
+ mlen = strlen(VALID_CHARS);
+
+ for (i = 0; i < len; i++) {
+ if (contains(s[i], VALID_CHARS, mlen) == 0) {
+ res = strcut(s, i, 1);
+ if(res == -1) return -1;
+ --len; --i;
+ }
+ }
+
+ return 0;
+}
+
+static int
+char_to_int (const char * str) {
+ int buf;
+ size_t i,len, mlen;
+ buf = 0;
+ len = strlen(str);
+ mlen = strlen(VALID_CHARS);
+
+ for (i = 0; i < len; i++)
+ if (contains(str[i], VALID_CHARS, mlen))
+ buf += (int) str[i];
+
+ return buf;
+}
+
+/**
+ * Render a given semver as numeric value.
+ * Useful for ordering and filtering.
+ */
+
+int
+semver_numeric (semver_t *x) {
+ int num;
+ char buf[SLICE_SIZE * 3];
+ memset(&buf, 0, SLICE_SIZE * 3);
+
+ if (x->major) concat_num(buf, x->major, NULL);
+ if (x->minor) concat_num(buf, x->minor, NULL);
+ if (x->patch) concat_num(buf, x->patch, NULL);
+
+ num = parse_int(buf);
+ if(num == -1) return -1;
+
+ if (x->prerelease) num += char_to_int(x->prerelease);
+ if (x->metadata) num += char_to_int(x->metadata);
+
+ return num;
+}
+
+char *semver_strdup(const char *src) {
+ if (src == NULL) return NULL;
+ size_t len = strlen(src) + 1;
+ char *res = malloc(len);
+ return res != NULL ? (char *) memcpy(res, src, len) : NULL;
+}
+
+semver_t
+semver_copy(const semver_t *ver) {
+ semver_t res = *ver;
+ if (ver->metadata != NULL) {
+ res.metadata = strdup(ver->metadata);
+ }
+ if (ver->prerelease != NULL) {
+ res.prerelease = strdup(ver->prerelease);
+ }
+ return res;
+}
diff --git a/xs/src/semver/semver.h b/xs/src/semver/semver.h
new file mode 100644
index 000000000..01a15fc43
--- /dev/null
+++ b/xs/src/semver/semver.h
@@ -0,0 +1,111 @@
+/*
+ * semver.h
+ *
+ * Copyright (c) 2015-2017 Tomas Aparicio
+ * MIT licensed
+ */
+
+#ifndef __SEMVER_H
+#define __SEMVER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SEMVER_VERSION
+#define SEMVER_VERSION "0.2.0"
+#endif
+
+/**
+ * semver_t struct
+ */
+
+typedef struct semver_version_s {
+ int major;
+ int minor;
+ int patch;
+ char * metadata;
+ char * prerelease;
+} semver_t;
+
+/**
+ * Set prototypes
+ */
+
+int
+semver_satisfies (semver_t x, semver_t y, const char *op);
+
+int
+semver_satisfies_caret (semver_t x, semver_t y);
+
+int
+semver_satisfies_patch (semver_t x, semver_t y);
+
+int
+semver_compare (semver_t x, semver_t y);
+
+int
+semver_compare_version (semver_t x, semver_t y);
+
+int
+semver_compare_prerelease (semver_t x, semver_t y);
+
+int
+semver_gt (semver_t x, semver_t y);
+
+int
+semver_gte (semver_t x, semver_t y);
+
+int
+semver_lt (semver_t x, semver_t y);
+
+int
+semver_lte (semver_t x, semver_t y);
+
+int
+semver_eq (semver_t x, semver_t y);
+
+int
+semver_neq (semver_t x, semver_t y);
+
+int
+semver_parse (const char *str, semver_t *ver);
+
+int
+semver_parse_version (const char *str, semver_t *ver);
+
+void
+semver_render (semver_t *x, char *dest);
+
+int
+semver_numeric (semver_t *x);
+
+void
+semver_bump (semver_t *x);
+
+void
+semver_bump_minor (semver_t *x);
+
+void
+semver_bump_patch (semver_t *x);
+
+void
+semver_free (semver_t *x);
+
+int
+semver_is_valid (const char *s);
+
+int
+semver_clean (char *s);
+
+char *
+semver_strdup(const char *src);
+
+semver_t
+semver_copy(const semver_t *ver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/xs/src/slic3r/AppController.cpp b/xs/src/slic3r/AppController.cpp
new file mode 100644
index 000000000..faecf9ecd
--- /dev/null
+++ b/xs/src/slic3r/AppController.cpp
@@ -0,0 +1,502 @@
+#include "AppController.hpp"
+
+#include <future>
+#include <chrono>
+#include <sstream>
+#include <cstdarg>
+#include <thread>
+#include <unordered_map>
+
+#include <slic3r/GUI/GUI.hpp>
+#include <ModelArrange.hpp>
+#include <slic3r/GUI/PresetBundle.hpp>
+
+#include <PrintConfig.hpp>
+#include <Print.hpp>
+#include <PrintExport.hpp>
+#include <Geometry.hpp>
+#include <Model.hpp>
+#include <Utils.hpp>
+#include <SLABasePool.hpp>
+
+namespace Slic3r {
+
+class AppControllerBoilerplate::PriData {
+public:
+ std::mutex m;
+ std::thread::id ui_thread;
+
+ inline explicit PriData(std::thread::id uit): ui_thread(uit) {}
+};
+
+AppControllerBoilerplate::AppControllerBoilerplate()
+ :pri_data_(new PriData(std::this_thread::get_id())) {}
+
+AppControllerBoilerplate::~AppControllerBoilerplate() {
+ pri_data_.reset();
+}
+
+bool AppControllerBoilerplate::is_main_thread() const
+{
+ return pri_data_->ui_thread == std::this_thread::get_id();
+}
+
+namespace GUI {
+PresetBundle* get_preset_bundle();
+}
+
+static const PrintObjectStep STEP_SLICE = posSlice;
+static const PrintObjectStep STEP_PERIMETERS = posPerimeters;
+static const PrintObjectStep STEP_PREPARE_INFILL = posPrepareInfill;
+static const PrintObjectStep STEP_INFILL = posInfill;
+static const PrintObjectStep STEP_SUPPORTMATERIAL = posSupportMaterial;
+static const PrintStep STEP_SKIRT = psSkirt;
+static const PrintStep STEP_BRIM = psBrim;
+static const PrintStep STEP_WIPE_TOWER = psWipeTower;
+
+AppControllerBoilerplate::ProgresIndicatorPtr
+AppControllerBoilerplate::global_progress_indicator() {
+ ProgresIndicatorPtr ret;
+
+ pri_data_->m.lock();
+ ret = global_progressind_;
+ pri_data_->m.unlock();
+
+ return ret;
+}
+
+void AppControllerBoilerplate::global_progress_indicator(
+ AppControllerBoilerplate::ProgresIndicatorPtr gpri)
+{
+ pri_data_->m.lock();
+ global_progressind_ = gpri;
+ pri_data_->m.unlock();
+}
+
+#if 0
+void PrintController::make_skirt()
+{
+ assert(print_ != nullptr);
+
+ // prerequisites
+ for(auto obj : print_->objects()) make_perimeters(obj);
+ for(auto obj : print_->objects()) infill(obj);
+ for(auto obj : print_->objects()) gen_support_material(obj);
+
+ if(!print_->state.is_done(STEP_SKIRT)) {
+ print_->state.set_started(STEP_SKIRT);
+ print_->skirt.clear();
+ if(print_->has_skirt()) print_->_make_skirt();
+
+ print_->state.set_done(STEP_SKIRT);
+ }
+}
+
+void PrintController::make_brim()
+{
+ assert(print_ != nullptr);
+
+ // prerequisites
+ for(auto obj : print_->objects()) make_perimeters(obj);
+ for(auto obj : print_->objects()) infill(obj);
+ for(auto obj : print_->objects()) gen_support_material(obj);
+ make_skirt();
+
+ if(!print_->state.is_done(STEP_BRIM)) {
+ print_->state.set_started(STEP_BRIM);
+
+ // since this method must be idempotent, we clear brim paths *before*
+ // checking whether we need to generate them
+ print_->brim.clear();
+
+ if(print_->config.brim_width > 0) print_->_make_brim();
+
+ print_->state.set_done(STEP_BRIM);
+ }
+}
+
+void PrintController::make_wipe_tower()
+{
+ assert(print_ != nullptr);
+
+ // prerequisites
+ for(auto obj : print_->objects()) make_perimeters(obj);
+ for(auto obj : print_->objects()) infill(obj);
+ for(auto obj : print_->objects()) gen_support_material(obj);
+ make_skirt();
+ make_brim();
+
+ if(!print_->state.is_done(STEP_WIPE_TOWER)) {
+ print_->state.set_started(STEP_WIPE_TOWER);
+
+ // since this method must be idempotent, we clear brim paths *before*
+ // checking whether we need to generate them
+ print_->brim.clear();
+
+ if(print_->has_wipe_tower()) print_->_make_wipe_tower();
+
+ print_->state.set_done(STEP_WIPE_TOWER);
+ }
+}
+
+void PrintController::slice(PrintObject *pobj)
+{
+ assert(pobj != nullptr && print_ != nullptr);
+
+ if(pobj->state.is_done(STEP_SLICE)) return;
+
+ pobj->state.set_started(STEP_SLICE);
+
+ pobj->_slice();
+
+ auto msg = pobj->_fix_slicing_errors();
+ if(!msg.empty()) report_issue(IssueType::WARN, msg);
+
+ // simplify slices if required
+ if (print_->config.resolution)
+ pobj->_simplify_slices(scale_(print_->config.resolution));
+
+
+ if(pobj->layers.empty())
+ report_issue(IssueType::ERR,
+ _(L("No layers were detected. You might want to repair your "
+ "STL file(s) or check their size or thickness and retry"))
+ );
+
+ pobj->state.set_done(STEP_SLICE);
+}
+
+void PrintController::make_perimeters(PrintObject *pobj)
+{
+ assert(pobj != nullptr);
+
+ slice(pobj);
+
+ if (!pobj->state.is_done(STEP_PERIMETERS)) {
+ pobj->_make_perimeters();
+ }
+}
+
+void PrintController::infill(PrintObject *pobj)
+{
+ assert(pobj != nullptr);
+
+ make_perimeters(pobj);
+
+ if (!pobj->state.is_done(STEP_PREPARE_INFILL)) {
+ pobj->state.set_started(STEP_PREPARE_INFILL);
+
+ pobj->_prepare_infill();
+
+ pobj->state.set_done(STEP_PREPARE_INFILL);
+ }
+
+ pobj->_infill();
+}
+
+void PrintController::gen_support_material(PrintObject *pobj)
+{
+ assert(pobj != nullptr);
+
+ // prerequisites
+ slice(pobj);
+
+ if(!pobj->state.is_done(STEP_SUPPORTMATERIAL)) {
+ pobj->state.set_started(STEP_SUPPORTMATERIAL);
+
+ pobj->clear_support_layers();
+
+ if((pobj->config.support_material || pobj->config.raft_layers > 0)
+ && pobj->layers.size() > 1) {
+ pobj->_generate_support_material();
+ }
+
+ pobj->state.set_done(STEP_SUPPORTMATERIAL);
+ }
+}
+
+PrintController::PngExportData
+PrintController::query_png_export_data(const DynamicPrintConfig& conf)
+{
+ PngExportData ret;
+
+ auto zippath = query_destination_path("Output zip file", "*.zip", "out");
+
+ ret.zippath = zippath;
+
+ ret.width_mm = conf.opt_float("display_width");
+ ret.height_mm = conf.opt_float("display_height");
+
+ ret.width_px = conf.opt_int("display_pixels_x");
+ ret.height_px = conf.opt_int("display_pixels_y");
+
+ auto opt_corr = conf.opt<ConfigOptionFloats>("printer_correction");
+
+ if(opt_corr) {
+ ret.corr_x = opt_corr->values[0];
+ ret.corr_y = opt_corr->values[1];
+ ret.corr_z = opt_corr->values[2];
+ }
+
+ ret.exp_time_first_s = conf.opt_float("initial_exposure_time");
+ ret.exp_time_s = conf.opt_float("exposure_time");
+
+ return ret;
+}
+
+void PrintController::slice(AppControllerBoilerplate::ProgresIndicatorPtr pri)
+{
+ auto st = pri->state();
+
+ Slic3r::trace(3, "Starting the slicing process.");
+
+ pri->update(st+20, _(L("Generating perimeters")));
+ for(auto obj : print_->objects()) make_perimeters(obj);
+
+ pri->update(st+60, _(L("Infilling layers")));
+ for(auto obj : print_->objects()) infill(obj);
+
+ pri->update(st+70, _(L("Generating support material")));
+ for(auto obj : print_->objects()) gen_support_material(obj);
+
+ pri->message_fmt(_(L("Weight: %.1fg, Cost: %.1f")),
+ print_->total_weight, print_->total_cost);
+ pri->state(st+85);
+
+
+ pri->update(st+88, _(L("Generating skirt")));
+ make_skirt();
+
+
+ pri->update(st+90, _(L("Generating brim")));
+ make_brim();
+
+ pri->update(st+95, _(L("Generating wipe tower")));
+ make_wipe_tower();
+
+ pri->update(st+100, _(L("Done")));
+
+ // time to make some statistics..
+
+ Slic3r::trace(3, _(L("Slicing process finished.")));
+}
+
+void PrintController::slice()
+{
+ auto pri = global_progress_indicator();
+ if(!pri) pri = create_progress_indicator(100, L("Slicing"));
+ slice(pri);
+}
+
+void PrintController::slice_to_png()
+{
+ using Pointf3 = Vec3d;
+
+ auto presetbundle = GUI::get_preset_bundle();
+
+ assert(presetbundle);
+
+ auto pt = presetbundle->printers.get_selected_preset().printer_technology();
+ if(pt != ptSLA) {
+ report_issue(IssueType::ERR, _("Printer technology is not SLA!"),
+ _("Error"));
+ return;
+ }
+
+ auto conf = presetbundle->full_config();
+ conf.validate();
+
+ auto exd = query_png_export_data(conf);
+ if(exd.zippath.empty()) return;
+
+ try {
+ print_->apply_config(conf);
+ print_->validate();
+ } catch(std::exception& e) {
+ report_issue(IssueType::ERR, e.what(), "Error");
+ return;
+ }
+
+ // TODO: copy the model and work with the copy only
+ bool correction = false;
+ if(exd.corr_x != 1.0 || exd.corr_y != 1.0 || exd.corr_z != 1.0) {
+ correction = true;
+ print_->invalidate_all_steps();
+
+ for(auto po : print_->objects()) {
+ po->model_object()->scale(
+ Pointf3(exd.corr_x, exd.corr_y, exd.corr_z)
+ );
+ po->model_object()->invalidate_bounding_box();
+ po->reload_model_instances();
+ po->invalidate_all_steps();
+ }
+ }
+
+ // Turn back the correction scaling on the model.
+ auto scale_back = [this, correction, exd]() {
+ if(correction) { // scale the model back
+ print_->invalidate_all_steps();
+ for(auto po : print_->objects()) {
+ po->model_object()->scale(
+ Pointf3(1.0/exd.corr_x, 1.0/exd.corr_y, 1.0/exd.corr_z)
+ );
+ po->model_object()->invalidate_bounding_box();
+ po->reload_model_instances();
+ po->invalidate_all_steps();
+ }
+ }
+ };
+
+ auto print_bb = print_->bounding_box();
+ Vec2d punsc = unscale(print_bb.size());
+
+ // If the print does not fit into the print area we should cry about it.
+ if(px(punsc) > exd.width_mm || py(punsc) > exd.height_mm) {
+ std::stringstream ss;
+
+ ss << _(L("Print will not fit and will be truncated!")) << "\n"
+ << _(L("Width needed: ")) << px(punsc) << " mm\n"
+ << _(L("Height needed: ")) << py(punsc) << " mm\n";
+
+ if(!report_issue(IssueType::WARN_Q, ss.str(), _(L("Warning")))) {
+ scale_back();
+ return;
+ }
+ }
+
+// std::async(supports_asynch()? std::launch::async : std::launch::deferred,
+// [this, exd, scale_back]()
+// {
+
+ auto pri = create_progress_indicator(
+ 200, _(L("Slicing to zipped png files...")));
+
+ try {
+ pri->update(0, _(L("Slicing...")));
+ slice(pri);
+ } catch (std::exception& e) {
+ pri->cancel();
+ report_issue(IssueType::ERR, e.what(), _(L("Exception occured")));
+ scale_back();
+ return;
+ }
+
+ auto pbak = print_->progressindicator;
+ print_->progressindicator = pri;
+
+ try {
+ print_to<FilePrinterFormat::PNG>( *print_, exd.zippath,
+ exd.width_mm, exd.height_mm,
+ exd.width_px, exd.height_px,
+ exd.exp_time_s, exd.exp_time_first_s);
+
+ } catch (std::exception& e) {
+ pri->cancel();
+ report_issue(IssueType::ERR, e.what(), _(L("Exception occured")));
+ }
+
+ print_->progressindicator = pbak;
+ scale_back();
+
+// });
+}
+
+const PrintConfig &PrintController::config() const
+{
+ return print_->config;
+}
+#endif
+
+void ProgressIndicator::message_fmt(
+ const string &fmtstr, ...) {
+ std::stringstream ss;
+ va_list args;
+ va_start(args, fmtstr);
+
+ auto fmt = fmtstr.begin();
+
+ while (*fmt != '\0') {
+ if (*fmt == 'd') {
+ int i = va_arg(args, int);
+ ss << i << '\n';
+ } else if (*fmt == 'c') {
+ // note automatic conversion to integral type
+ int c = va_arg(args, int);
+ ss << static_cast<char>(c) << '\n';
+ } else if (*fmt == 'f') {
+ double d = va_arg(args, double);
+ ss << d << '\n';
+ }
+ ++fmt;
+ }
+
+ va_end(args);
+ message(ss.str());
+}
+
+void AppController::arrange_model()
+{
+ using Coord = libnest2d::TCoord<libnest2d::PointImpl>;
+
+ unsigned count = 0;
+ for(auto obj : model_->objects) count += obj->instances.size();
+
+ auto pind = global_progress_indicator();
+
+ float pmax = 1.0;
+
+ if(pind) {
+ pmax = pind->max();
+
+ // Set the range of the progress to the object count
+ pind->max(count);
+
+ pind->on_cancel([](){
+ std::cout << "Cannot be cancelled!" << std::endl;
+ });
+ }
+
+ auto dist = print_ctl()->config().min_object_distance();
+
+ // Create the arranger config
+ auto min_obj_distance = static_cast<Coord>(dist/SCALING_FACTOR);
+
+ auto& bedpoints = print_ctl()->config().bed_shape.values;
+ Polyline bed; bed.points.reserve(bedpoints.size());
+ for(auto& v : bedpoints)
+ bed.append(Point::new_scale(v(0), v(1)));
+
+ if(pind) pind->update(0, _(L("Arranging objects...")));
+
+ try {
+ arr::BedShapeHint hint;
+ // TODO: from Sasha from GUI
+ hint.type = arr::BedShapeType::WHO_KNOWS;
+
+ arr::arrange(*model_,
+ min_obj_distance,
+ bed,
+ hint,
+ false, // create many piles not just one pile
+ [pind, count](unsigned rem) {
+ if(pind)
+ pind->update(count - rem, _(L("Arranging objects...")));
+ });
+ } catch(std::exception& e) {
+ std::cerr << e.what() << std::endl;
+ report_issue(IssueType::ERR,
+ _(L("Could not arrange model objects! "
+ "Some geometries may be invalid.")),
+ _(L("Exception occurred")));
+ }
+
+ // Restore previous max value
+ if(pind) {
+ pind->max(pmax);
+ pind->update(0, _(L("Arranging done.")));
+ pind->on_cancel(/*remove cancel function*/);
+ }
+}
+
+}
diff --git a/xs/src/slic3r/AppController.hpp b/xs/src/slic3r/AppController.hpp
new file mode 100644
index 000000000..b9af3bbd9
--- /dev/null
+++ b/xs/src/slic3r/AppController.hpp
@@ -0,0 +1,303 @@
+#ifndef APPCONTROLLER_HPP
+#define APPCONTROLLER_HPP
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <atomic>
+#include <iostream>
+
+#include "ProgressIndicator.hpp"
+
+namespace Slic3r {
+
+class Model;
+class Print;
+class PrintObject;
+class PrintConfig;
+class ProgressStatusBar;
+
+/**
+ * @brief A boilerplate class for creating application logic. It should provide
+ * features as issue reporting and progress indication, etc...
+ *
+ * The lower lever UI independent classes can be manipulated with a subclass
+ * of this controller class. We can also catch any exceptions that lower level
+ * methods could throw and display appropriate errors and warnings.
+ *
+ * Note that the outer and the inner interface of this class is free from any
+ * UI toolkit dependencies. We can implement it with any UI framework or make it
+ * a cli client.
+ */
+class AppControllerBoilerplate {
+public:
+
+ /// A Progress indicator object smart pointer
+ using ProgresIndicatorPtr = std::shared_ptr<ProgressIndicator>;
+
+private:
+ class PriData; // Some structure to store progress indication data
+
+ // Pimpl data for thread safe progress indication features
+ std::unique_ptr<PriData> pri_data_;
+
+public:
+
+ AppControllerBoilerplate();
+ ~AppControllerBoilerplate();
+
+ using Path = string;
+ using PathList = std::vector<Path>;
+
+ /// Common runtime issue types
+ enum class IssueType {
+ INFO,
+ WARN,
+ WARN_Q, // Warning with a question to continue
+ ERR,
+ FATAL
+ };
+
+ /**
+ * @brief Query some paths from the user.
+ *
+ * It should display a file chooser dialog in case of a UI application.
+ * @param title Title of a possible query dialog.
+ * @param extensions Recognized file extensions.
+ * @return Returns a list of paths choosed by the user.
+ */
+ PathList query_destination_paths(
+ const string& title,
+ const std::string& extensions) const;
+
+ /**
+ * @brief Same as query_destination_paths but works for directories only.
+ */
+ PathList query_destination_dirs(
+ const string& title) const;
+
+ /**
+ * @brief Same as query_destination_paths but returns only one path.
+ */
+ Path query_destination_path(
+ const string& title,
+ const std::string& extensions,
+ const std::string& hint = "") const;
+
+ /**
+ * @brief Report an issue to the user be it fatal or recoverable.
+ *
+ * In a UI app this should display some message dialog.
+ *
+ * @param issuetype The type of the runtime issue.
+ * @param description A somewhat longer description of the issue.
+ * @param brief A very brief description. Can be used for message dialog
+ * title.
+ */
+ bool report_issue(IssueType issuetype,
+ const string& description,
+ const string& brief);
+
+ bool report_issue(IssueType issuetype,
+ const string& description);
+
+ /**
+ * @brief Return the global progress indicator for the current controller.
+ * Can be empty as well.
+ *
+ * Only one thread should use the global indicator at a time.
+ */
+ ProgresIndicatorPtr global_progress_indicator();
+
+ void global_progress_indicator(ProgresIndicatorPtr gpri);
+
+ /**
+ * @brief A predicate telling the caller whether it is the thread that
+ * created the AppConroller object itself. This probably means that the
+ * execution is in the UI thread. Otherwise it returns false meaning that
+ * some worker thread called this function.
+ * @return Return true for the same caller thread that created this
+ * object and false for every other.
+ */
+ bool is_main_thread() const;
+
+ /**
+ * @brief The frontend supports asynch execution.
+ *
+ * A Graphic UI will support this, a CLI may not. This can be used in
+ * subclass methods to decide whether to start threads for block free UI.
+ *
+ * Note that even a progress indicator's update called regularly can solve
+ * the blocking UI problem in some cases even when an event loop is present.
+ * This is how wxWidgets gauge work but creating a separate thread will make
+ * the UI even more fluent.
+ *
+ * @return true if a job or method can be executed asynchronously, false
+ * otherwise.
+ */
+ bool supports_asynch() const;
+
+ void process_events();
+
+protected:
+
+ /**
+ * @brief Create a new progress indicator and return a smart pointer to it.
+ * @param statenum The number of states for the given procedure.
+ * @param title The title of the procedure.
+ * @param firstmsg The message for the first subtask to be displayed.
+ * @return Smart pointer to the created object.
+ */
+ ProgresIndicatorPtr create_progress_indicator(
+ unsigned statenum,
+ const string& title,
+ const string& firstmsg) const;
+
+ ProgresIndicatorPtr create_progress_indicator(
+ unsigned statenum,
+ const string& title) const;
+
+ // This is a global progress indicator placeholder. In the Slic3r UI it can
+ // contain the progress indicator on the statusbar.
+ ProgresIndicatorPtr global_progressind_;
+};
+
+#if 0
+/**
+ * @brief Implementation of the printing logic.
+ */
+class PrintController: public AppControllerBoilerplate {
+ Print *print_ = nullptr;
+protected:
+
+ void make_skirt();
+ void make_brim();
+ void make_wipe_tower();
+
+ void make_perimeters(PrintObject *pobj);
+ void infill(PrintObject *pobj);
+ void gen_support_material(PrintObject *pobj);
+
+ // Data structure with the png export input data
+ struct PngExportData {
+ std::string zippath; // output zip file
+ unsigned long width_px = 1440; // resolution - rows
+ unsigned long height_px = 2560; // resolution columns
+ double width_mm = 68.0, height_mm = 120.0; // dimensions in mm
+ double exp_time_first_s = 35.0; // first exposure time
+ double exp_time_s = 8.0; // global exposure time
+ double corr_x = 1.0; // offsetting in x
+ double corr_y = 1.0; // offsetting in y
+ double corr_z = 1.0; // offsetting in y
+ };
+
+ // Should display a dialog with the input fields for printing to png
+ PngExportData query_png_export_data(const DynamicPrintConfig&);
+
+ // The previous export data, to pre-populate the dialog
+ PngExportData prev_expdata_;
+
+ /**
+ * @brief Slice one pront object.
+ * @param pobj The print object.
+ */
+ void slice(PrintObject *pobj);
+
+ void slice(ProgresIndicatorPtr pri);
+
+public:
+
+ // Must be public for perl to use it
+ explicit inline PrintController(Print *print): print_(print) {}
+
+ PrintController(const PrintController&) = delete;
+ PrintController(PrintController&&) = delete;
+
+ using Ptr = std::unique_ptr<PrintController>;
+
+ inline static Ptr create(Print *print) {
+ return PrintController::Ptr( new PrintController(print) );
+ }
+
+ /**
+ * @brief Slice the loaded print scene.
+ */
+ void slice();
+
+ /**
+ * @brief Slice the print into zipped png files.
+ */
+ void slice_to_png();
+
+ const PrintConfig& config() const;
+};
+#else
+class PrintController: public AppControllerBoilerplate {
+public:
+ using Ptr = std::unique_ptr<PrintController>;
+ explicit inline PrintController(Print *print){}
+ inline static Ptr create(Print *print) {
+ return PrintController::Ptr( new PrintController(print) );
+ }
+ void slice() {}
+ void slice_to_png() {}
+ const PrintConfig& config() const { static PrintConfig cfg; return cfg; }
+};
+#endif
+
+/**
+ * @brief Top level controller.
+ */
+class AppController: public AppControllerBoilerplate {
+ Model *model_ = nullptr;
+ PrintController::Ptr printctl;
+public:
+
+ /**
+ * @brief Get the print controller object.
+ *
+ * @return Return a raw pointer instead of a smart one for perl to be able
+ * to use this function and access the print controller.
+ */
+ PrintController * print_ctl() { return printctl.get(); }
+
+ /**
+ * @brief Set a model object.
+ *
+ * @param model A raw pointer to the model object. This can be used from
+ * perl.
+ */
+ void set_model(Model *model) { model_ = model; }
+
+ /**
+ * @brief Set the print object from perl.
+ *
+ * This will create a print controller that will then be accessible from
+ * perl.
+ * @param print A print object which can be a perl-ish extension as well.
+ */
+ void set_print(Print *print) {
+ printctl = PrintController::create(print);
+ }
+
+ /**
+ * @brief Set up a global progress indicator.
+ *
+ * In perl we have a progress indicating status bar on the bottom of the
+ * window which is defined and created in perl. We can pass the ID-s of the
+ * gauge and the statusbar id and make a wrapper implementation of the
+ * IProgressIndicator interface so we can use this GUI widget from C++.
+ *
+ * This function should be called from perl.
+ *
+ * @param gauge_id The ID of the gague widget of the status bar.
+ * @param statusbar_id The ID of the status bar.
+ */
+ void set_global_progress_indicator(ProgressStatusBar *prs);
+
+ void arrange_model();
+};
+
+}
+
+#endif // APPCONTROLLER_HPP
diff --git a/xs/src/slic3r/AppControllerWx.cpp b/xs/src/slic3r/AppControllerWx.cpp
new file mode 100644
index 000000000..39192e7d3
--- /dev/null
+++ b/xs/src/slic3r/AppControllerWx.cpp
@@ -0,0 +1,302 @@
+#include "AppController.hpp"
+
+#include <thread>
+#include <future>
+
+#include <slic3r/GUI/GUI.hpp>
+#include <slic3r/GUI/ProgressStatusBar.hpp>
+
+#include <wx/app.h>
+#include <wx/filedlg.h>
+#include <wx/msgdlg.h>
+#include <wx/progdlg.h>
+#include <wx/gauge.h>
+#include <wx/statusbr.h>
+#include <wx/event.h>
+
+// This source file implements the UI dependent methods of the AppControllers.
+// It will be clear what is needed to be reimplemented in case of a UI framework
+// change or a CLI client creation. In this particular case we use wxWidgets to
+// implement everything.
+
+namespace Slic3r {
+
+bool AppControllerBoilerplate::supports_asynch() const
+{
+ return true;
+}
+
+void AppControllerBoilerplate::process_events()
+{
+ wxSafeYield();
+}
+
+AppControllerBoilerplate::PathList
+AppControllerBoilerplate::query_destination_paths(
+ const string &title,
+ const std::string &extensions) const
+{
+
+ wxFileDialog dlg(wxTheApp->GetTopWindow(), title );
+ dlg.SetWildcard(extensions);
+
+ dlg.ShowModal();
+
+ wxArrayString paths;
+ dlg.GetPaths(paths);
+
+ PathList ret(paths.size(), "");
+ for(auto& p : paths) ret.push_back(p.ToStdString());
+
+ return ret;
+}
+
+AppControllerBoilerplate::Path
+AppControllerBoilerplate::query_destination_path(
+ const string &title,
+ const std::string &extensions,
+ const std::string& hint) const
+{
+ wxFileDialog dlg(wxTheApp->GetTopWindow(), title );
+ dlg.SetWildcard(extensions);
+
+ dlg.SetFilename(hint);
+
+ Path ret;
+
+ if(dlg.ShowModal() == wxID_OK) {
+ ret = Path(dlg.GetPath());
+ }
+
+ return ret;
+}
+
+bool AppControllerBoilerplate::report_issue(IssueType issuetype,
+ const string &description,
+ const string &brief)
+{
+ auto icon = wxICON_INFORMATION;
+ auto style = wxOK|wxCENTRE;
+ switch(issuetype) {
+ case IssueType::INFO: break;
+ case IssueType::WARN: icon = wxICON_WARNING; break;
+ case IssueType::WARN_Q: icon = wxICON_WARNING; style |= wxCANCEL; break;
+ case IssueType::ERR:
+ case IssueType::FATAL: icon = wxICON_ERROR;
+ }
+
+ auto ret = wxMessageBox(description, brief, icon | style);
+ return ret != wxCANCEL;
+}
+
+bool AppControllerBoilerplate::report_issue(
+ AppControllerBoilerplate::IssueType issuetype,
+ const string &description)
+{
+ return report_issue(issuetype, description, string());
+}
+
+wxDEFINE_EVENT(PROGRESS_STATUS_UPDATE_EVENT, wxCommandEvent);
+
+namespace {
+
+/*
+ * A simple thread safe progress dialog implementation that can be used from
+ * the main thread as well.
+ */
+class GuiProgressIndicator:
+ public ProgressIndicator, public wxEvtHandler {
+
+ wxProgressDialog gauge_;
+ using Base = ProgressIndicator;
+ wxString message_;
+ int range_; wxString title_;
+ bool is_asynch_ = false;
+
+ const int id_ = wxWindow::NewControlId();
+
+ // status update handler
+ void _state( wxCommandEvent& evt) {
+ unsigned st = evt.GetInt();
+ message_ = evt.GetString();
+ _state(st);
+ }
+
+ // Status update implementation
+ void _state( unsigned st) {
+ if(!gauge_.IsShown()) gauge_.ShowModal();
+ Base::state(st);
+ gauge_.Update(static_cast<int>(st), message_);
+ }
+
+public:
+
+ /// Setting whether it will be used from the UI thread or some worker thread
+ inline void asynch(bool is) { is_asynch_ = is; }
+
+ /// Get the mode of parallel operation.
+ inline bool asynch() const { return is_asynch_; }
+
+ inline GuiProgressIndicator(int range, const string& title,
+ const string& firstmsg) :
+ gauge_(title, firstmsg, range, wxTheApp->GetTopWindow(),
+ wxPD_APP_MODAL | wxPD_AUTO_HIDE),
+ message_(firstmsg),
+ range_(range), title_(title)
+ {
+ Base::max(static_cast<float>(range));
+ Base::states(static_cast<unsigned>(range));
+
+ Bind(PROGRESS_STATUS_UPDATE_EVENT,
+ &GuiProgressIndicator::_state,
+ this, id_);
+ }
+
+ virtual void cancel() override {
+ update(max(), "Abort");
+ ProgressIndicator::cancel();
+ }
+
+ virtual void state(float val) override {
+ state(static_cast<unsigned>(val));
+ }
+
+ void state(unsigned st) {
+ // send status update event
+ if(is_asynch_) {
+ auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
+ evt->SetInt(st);
+ evt->SetString(message_);
+ wxQueueEvent(this, evt);
+ } else _state(st);
+ }
+
+ virtual void message(const string & msg) override {
+ message_ = msg;
+ }
+
+ virtual void messageFmt(const string& fmt, ...) {
+ va_list arglist;
+ va_start(arglist, fmt);
+ message_ = wxString::Format(wxString(fmt), arglist);
+ va_end(arglist);
+ }
+
+ virtual void title(const string & title) override {
+ title_ = title;
+ }
+};
+}
+
+AppControllerBoilerplate::ProgresIndicatorPtr
+AppControllerBoilerplate::create_progress_indicator(
+ unsigned statenum, const string& title, const string& firstmsg) const
+{
+ auto pri =
+ std::make_shared<GuiProgressIndicator>(statenum, title, firstmsg);
+
+ // We set up the mode of operation depending of the creator thread's
+ // identity
+ pri->asynch(!is_main_thread());
+
+ return pri;
+}
+
+AppControllerBoilerplate::ProgresIndicatorPtr
+AppControllerBoilerplate::create_progress_indicator(unsigned statenum,
+ const string &title) const
+{
+ return create_progress_indicator(statenum, title, string());
+}
+
+namespace {
+
+class Wrapper: public ProgressIndicator, public wxEvtHandler {
+ ProgressStatusBar *sbar_;
+ using Base = ProgressIndicator;
+ std::string message_;
+ AppControllerBoilerplate& ctl_;
+
+ void showProgress(bool show = true) {
+ sbar_->show_progress(show);
+ }
+
+ void _state(unsigned st) {
+ if( st <= ProgressIndicator::max() ) {
+ Base::state(st);
+ sbar_->set_status_text(message_);
+ sbar_->set_progress(st);
+ }
+ }
+
+ // status update handler
+ void _state( wxCommandEvent& evt) {
+ unsigned st = evt.GetInt(); _state(st);
+ }
+
+ const int id_ = wxWindow::NewControlId();
+
+public:
+
+ inline Wrapper(ProgressStatusBar *sbar,
+ AppControllerBoilerplate& ctl):
+ sbar_(sbar), ctl_(ctl)
+ {
+ Base::max(static_cast<float>(sbar_->get_range()));
+ Base::states(static_cast<unsigned>(sbar_->get_range()));
+
+ Bind(PROGRESS_STATUS_UPDATE_EVENT,
+ &Wrapper::_state,
+ this, id_);
+ }
+
+ virtual void state(float val) override {
+ state(unsigned(val));
+ }
+
+ virtual void max(float val) override {
+ if(val > 1.0) {
+ sbar_->set_range(static_cast<int>(val));
+ ProgressIndicator::max(val);
+ }
+ }
+
+ void state(unsigned st) {
+ if(!ctl_.is_main_thread()) {
+ auto evt = new wxCommandEvent(PROGRESS_STATUS_UPDATE_EVENT, id_);
+ evt->SetInt(st);
+ wxQueueEvent(this, evt);
+ } else {
+ _state(st);
+ }
+ }
+
+ virtual void message(const string & msg) override {
+ message_ = msg;
+ }
+
+ virtual void message_fmt(const string& fmt, ...) override {
+ va_list arglist;
+ va_start(arglist, fmt);
+ message_ = wxString::Format(fmt, arglist);
+ va_end(arglist);
+ }
+
+ virtual void title(const string & /*title*/) override {}
+
+ virtual void on_cancel(CancelFn fn) override {
+ sbar_->set_cancel_callback(fn);
+ Base::on_cancel(fn);
+ }
+
+};
+}
+
+void AppController::set_global_progress_indicator(ProgressStatusBar *prsb)
+{
+ if(prsb) {
+ global_progress_indicator(std::make_shared<Wrapper>(prsb, *this));
+ }
+}
+
+}
diff --git a/xs/src/slic3r/Config/Snapshot.cpp b/xs/src/slic3r/Config/Snapshot.cpp
new file mode 100644
index 000000000..704fbcfa1
--- /dev/null
+++ b/xs/src/slic3r/Config/Snapshot.cpp
@@ -0,0 +1,532 @@
+#include "Snapshot.hpp"
+#include "../GUI/AppConfig.hpp"
+#include "../GUI/PresetBundle.hpp"
+#include "../Utils/Time.hpp"
+
+#include <time.h>
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/trim.hpp>
+#include <boost/nowide/cstdio.hpp>
+#include <boost/nowide/fstream.hpp>
+#include <boost/property_tree/ini_parser.hpp>
+#include <boost/property_tree/ptree.hpp>
+
+#include "../../libslic3r/libslic3r.h"
+#include "../../libslic3r/Config.hpp"
+#include "../../libslic3r/FileParserError.hpp"
+#include "../../libslic3r/Utils.hpp"
+
+#define SLIC3R_SNAPSHOTS_DIR "snapshots"
+#define SLIC3R_SNAPSHOT_FILE "snapshot.ini"
+
+namespace Slic3r {
+namespace GUI {
+namespace Config {
+
+void Snapshot::clear()
+{
+ this->id.clear();
+ this->time_captured = 0;
+ this->slic3r_version_captured = Semver::invalid();
+ this->comment.clear();
+ this->reason = SNAPSHOT_UNKNOWN;
+ this->print.clear();
+ this->filaments.clear();
+ this->printer.clear();
+}
+
+void Snapshot::load_ini(const std::string &path)
+{
+ this->clear();
+
+ auto throw_on_parse_error = [&path](const std::string &msg) {
+ throw file_parser_error(std::string("Failed loading the snapshot file. Reason: ") + msg, path);
+ };
+
+ // Load the snapshot.ini file.
+ boost::property_tree::ptree tree;
+ try {
+ boost::nowide::ifstream ifs(path);
+ boost::property_tree::read_ini(ifs, tree);
+ } catch (const std::ifstream::failure &err) {
+ throw file_parser_error(std::string("The snapshot file cannot be loaded. Reason: ") + err.what(), path);
+ } catch (const std::runtime_error &err) {
+ throw_on_parse_error(err.what());
+ }
+
+ // Parse snapshot.ini
+ std::string group_name_vendor = "Vendor:";
+ std::string key_filament = "filament";
+ std::string key_prefix_model = "model_";
+ for (auto &section : tree) {
+ if (section.first == "snapshot") {
+ // Parse the common section.
+ for (auto &kvp : section.second) {
+ if (kvp.first == "id")
+ this->id = kvp.second.data();
+ else if (kvp.first == "time_captured") {
+ this->time_captured = Slic3r::Utils::parse_time_ISO8601Z(kvp.second.data());
+ if (this->time_captured == (time_t)-1)
+ throw_on_parse_error("invalid timestamp");
+ } else if (kvp.first == "slic3r_version_captured") {
+ auto semver = Semver::parse(kvp.second.data());
+ if (! semver)
+ throw_on_parse_error("invalid slic3r_version_captured semver");
+ this->slic3r_version_captured = *semver;
+ } else if (kvp.first == "comment") {
+ this->comment = kvp.second.data();
+ } else if (kvp.first == "reason") {
+ std::string rsn = kvp.second.data();
+ if (rsn == "upgrade")
+ this->reason = SNAPSHOT_UPGRADE;
+ else if (rsn == "downgrade")
+ this->reason = SNAPSHOT_DOWNGRADE;
+ else if (rsn == "before_rollback")
+ this->reason = SNAPSHOT_BEFORE_ROLLBACK;
+ else if (rsn == "user")
+ this->reason = SNAPSHOT_USER;
+ else
+ this->reason = SNAPSHOT_UNKNOWN;
+ }
+ }
+ } else if (section.first == "presets") {
+ // Load the names of the active presets.
+ for (auto &kvp : section.second) {
+ if (kvp.first == "print") {
+ this->print = kvp.second.data();
+ } else if (boost::starts_with(kvp.first, "filament")) {
+ int idx = 0;
+ if (kvp.first == "filament" || sscanf(kvp.first.c_str(), "filament_%d", &idx) == 1) {
+ if (int(this->filaments.size()) <= idx)
+ this->filaments.resize(idx + 1, std::string());
+ this->filaments[idx] = kvp.second.data();
+ }
+ } else if (kvp.first == "printer") {
+ this->printer = kvp.second.data();
+ }
+ }
+ } else if (boost::starts_with(section.first, group_name_vendor) && section.first.size() > group_name_vendor.size()) {
+ // Vendor specific section.
+ VendorConfig vc;
+ vc.name = section.first.substr(group_name_vendor.size());
+ for (auto &kvp : section.second) {
+ if (kvp.first == "version" || kvp.first == "min_slic3r_version" || kvp.first == "max_slic3r_version") {
+ // Version of the vendor specific config bundle bundled with this snapshot.
+ auto semver = Semver::parse(kvp.second.data());
+ if (! semver)
+ throw_on_parse_error("invalid " + kvp.first + " format for " + section.first);
+ if (kvp.first == "version")
+ vc.version.config_version = *semver;
+ else if (kvp.first == "min_slic3r_version")
+ vc.version.min_slic3r_version = *semver;
+ else
+ vc.version.max_slic3r_version = *semver;
+ } else if (boost::starts_with(kvp.first, key_prefix_model) && kvp.first.size() > key_prefix_model.size()) {
+ // Parse the printer variants installed for the current model.
+ auto &set_variants = vc.models_variants_installed[kvp.first.substr(key_prefix_model.size())];
+ std::vector<std::string> variants;
+ if (unescape_strings_cstyle(kvp.second.data(), variants))
+ for (auto &variant : variants)
+ set_variants.insert(std::move(variant));
+ }
+ }
+ this->vendor_configs.emplace_back(std::move(vc));
+ }
+ }
+ // Sort the vendors lexicographically.
+ std::sort(this->vendor_configs.begin(), this->vendor_configs.begin(),
+ [](const VendorConfig &cfg1, const VendorConfig &cfg2) { return cfg1.name < cfg2.name; });
+}
+
+static std::string reason_string(const Snapshot::Reason reason)
+{
+ switch (reason) {
+ case Snapshot::SNAPSHOT_UPGRADE:
+ return "upgrade";
+ case Snapshot::SNAPSHOT_DOWNGRADE:
+ return "downgrade";
+ case Snapshot::SNAPSHOT_BEFORE_ROLLBACK:
+ return "before_rollback";
+ case Snapshot::SNAPSHOT_USER:
+ return "user";
+ case Snapshot::SNAPSHOT_UNKNOWN:
+ default:
+ return "unknown";
+ }
+}
+
+void Snapshot::save_ini(const std::string &path)
+{
+ boost::nowide::ofstream c;
+ c.open(path, std::ios::out | std::ios::trunc);
+ c << "# " << Slic3r::header_slic3r_generated() << std::endl;
+
+ // Export the common "snapshot".
+ c << std::endl << "[snapshot]" << std::endl;
+ c << "id = " << this->id << std::endl;
+ c << "time_captured = " << Slic3r::Utils::format_time_ISO8601Z(this->time_captured) << std::endl;
+ c << "slic3r_version_captured = " << this->slic3r_version_captured.to_string() << std::endl;
+ c << "comment = " << this->comment << std::endl;
+ c << "reason = " << reason_string(this->reason) << std::endl;
+
+ // Export the active presets at the time of the snapshot.
+ c << std::endl << "[presets]" << std::endl;
+ c << "print = " << this->print << std::endl;
+ c << "filament = " << this->filaments.front() << std::endl;
+ for (size_t i = 1; i < this->filaments.size(); ++ i)
+ c << "filament_" << std::to_string(i) << " = " << this->filaments[i] << std::endl;
+ c << "printer = " << this->printer << std::endl;
+
+ // Export the vendor configs.
+ for (const VendorConfig &vc : this->vendor_configs) {
+ c << std::endl << "[Vendor:" << vc.name << "]" << std::endl;
+ c << "version = " << vc.version.config_version.to_string() << std::endl;
+ c << "min_slic3r_version = " << vc.version.min_slic3r_version.to_string() << std::endl;
+ c << "max_slic3r_version = " << vc.version.max_slic3r_version.to_string() << std::endl;
+ // Export installed printer models and their variants.
+ for (const auto &model : vc.models_variants_installed) {
+ if (model.second.size() == 0)
+ continue;
+ const std::vector<std::string> variants(model.second.begin(), model.second.end());
+ const auto escaped = escape_strings_cstyle(variants);
+ c << "model_" << model.first << " = " << escaped << std::endl;
+ }
+ }
+ c.close();
+}
+
+void Snapshot::export_selections(AppConfig &config) const
+{
+ assert(filaments.size() >= 1);
+ config.clear_section("presets");
+ config.set("presets", "print", print);
+ config.set("presets", "filament", filaments.front());
+ for (int i = 1; i < filaments.size(); ++i) {
+ char name[64];
+ sprintf(name, "filament_%d", i);
+ config.set("presets", name, filaments[i]);
+ }
+ config.set("presets", "printer", printer);
+}
+
+void Snapshot::export_vendor_configs(AppConfig &config) const
+{
+ std::map<std::string, std::map<std::string, std::set<std::string>>> vendors;
+ for (const VendorConfig &vc : vendor_configs)
+ vendors[vc.name] = vc.models_variants_installed;
+ config.set_vendors(std::move(vendors));
+}
+
+// Perform a deep compare of the active print / filament / printer / vendor directories.
+// Return true if the content of the current print / filament / printer / vendor directories
+// matches the state stored in this snapshot.
+bool Snapshot::equal_to_active(const AppConfig &app_config) const
+{
+ // 1) Check, whether this snapshot contains the same set of active vendors, printer models and variants
+ // as app_config.
+ {
+ std::set<std::string> matched;
+ for (const VendorConfig &vc : this->vendor_configs) {
+ auto it_vendor_models_variants = app_config.vendors().find(vc.name);
+ if (it_vendor_models_variants == app_config.vendors().end() ||
+ it_vendor_models_variants->second != vc.models_variants_installed)
+ // There are more vendors enabled in the snapshot than currently installed.
+ return false;
+ matched.insert(vc.name);
+ }
+ for (const std::pair<std::string, std::map<std::string, std::set<std::string>>> &v : app_config.vendors())
+ if (matched.find(v.first) == matched.end() && ! v.second.empty())
+ // There are more vendors currently installed than enabled in the snapshot.
+ return false;
+ }
+
+ // 2) Check, whether this snapshot references the same set of ini files as the current state.
+ boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir());
+ boost::filesystem::path snapshot_dir = boost::filesystem::path(Slic3r::data_dir()) / SLIC3R_SNAPSHOTS_DIR / this->id;
+ for (const char *subdir : { "print", "filament", "printer", "vendor" }) {
+ boost::filesystem::path path1 = data_dir / subdir;
+ boost::filesystem::path path2 = snapshot_dir / subdir;
+ std::vector<std::string> files1, files2;
+ for (auto &dir_entry : boost::filesystem::directory_iterator(path1))
+ if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini"))
+ files1.emplace_back(dir_entry.path().filename().string());
+ for (auto &dir_entry : boost::filesystem::directory_iterator(path2))
+ if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini"))
+ files2.emplace_back(dir_entry.path().filename().string());
+ std::sort(files1.begin(), files1.end());
+ std::sort(files2.begin(), files2.end());
+ if (files1 != files2)
+ return false;
+ for (const std::string &filename : files1) {
+ FILE *f1 = boost::nowide::fopen((path1 / filename).string().c_str(), "rb");
+ FILE *f2 = boost::nowide::fopen((path2 / filename).string().c_str(), "rb");
+ bool same = true;
+ if (f1 && f2) {
+ char buf1[4096];
+ char buf2[4096];
+ do {
+ size_t r1 = fread(buf1, 1, 4096, f1);
+ size_t r2 = fread(buf2, 1, 4096, f2);
+ if (r1 != r2 || memcmp(buf1, buf2, r1)) {
+ same = false;
+ break;
+ }
+ } while (! feof(f1) || ! feof(f2));
+ } else
+ same = false;
+ if (f1)
+ fclose(f1);
+ if (f2)
+ fclose(f2);
+ if (! same)
+ return false;
+ }
+ }
+ return true;
+}
+
+size_t SnapshotDB::load_db()
+{
+ boost::filesystem::path snapshots_dir = SnapshotDB::create_db_dir();
+
+ m_snapshots.clear();
+
+ // Walk over the snapshot directories and load their index.
+ std::string errors_cummulative;
+ for (auto &dir_entry : boost::filesystem::directory_iterator(snapshots_dir))
+ if (boost::filesystem::is_directory(dir_entry.status())) {
+ // Try to read "snapshot.ini".
+ boost::filesystem::path path_ini = dir_entry.path() / SLIC3R_SNAPSHOT_FILE;
+ Snapshot snapshot;
+ try {
+ snapshot.load_ini(path_ini.string());
+ } catch (const std::runtime_error &err) {
+ errors_cummulative += err.what();
+ errors_cummulative += "\n";
+ continue;
+ }
+ // Check that the name of the snapshot directory matches the snapshot id stored in the snapshot.ini file.
+ if (dir_entry.path().filename().string() != snapshot.id) {
+ errors_cummulative += std::string("Snapshot ID ") + snapshot.id + " does not match the snapshot directory " + dir_entry.path().filename().string() + "\n";
+ continue;
+ }
+ m_snapshots.emplace_back(std::move(snapshot));
+ }
+ // Sort the snapshots by their date/time.
+ std::sort(m_snapshots.begin(), m_snapshots.end(), [](const Snapshot &s1, const Snapshot &s2) { return s1.time_captured < s2.time_captured; });
+ if (! errors_cummulative.empty())
+ throw std::runtime_error(errors_cummulative);
+ return m_snapshots.size();
+}
+
+void SnapshotDB::update_slic3r_versions(std::vector<Index> &index_db)
+{
+ for (Snapshot &snapshot : m_snapshots) {
+ for (Snapshot::VendorConfig &vendor_config : snapshot.vendor_configs) {
+ auto it = std::find_if(index_db.begin(), index_db.end(), [&vendor_config](const Index &idx) { return idx.vendor() == vendor_config.name; });
+ if (it != index_db.end()) {
+ Index::const_iterator it_version = it->find(vendor_config.version.config_version);
+ if (it_version != it->end()) {
+ vendor_config.version.min_slic3r_version = it_version->min_slic3r_version;
+ vendor_config.version.max_slic3r_version = it_version->max_slic3r_version;
+ }
+ }
+ }
+ }
+}
+
+static void copy_config_dir_single_level(const boost::filesystem::path &path_src, const boost::filesystem::path &path_dst)
+{
+ if (! boost::filesystem::is_directory(path_dst) &&
+ ! boost::filesystem::create_directory(path_dst))
+ throw std::runtime_error(std::string("Slic3r was unable to create a directory at ") + path_dst.string());
+
+ for (auto &dir_entry : boost::filesystem::directory_iterator(path_src))
+ if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini"))
+ boost::filesystem::copy_file(dir_entry.path(), path_dst / dir_entry.path().filename(), boost::filesystem::copy_option::overwrite_if_exists);
+}
+
+static void delete_existing_ini_files(const boost::filesystem::path &path)
+{
+ if (! boost::filesystem::is_directory(path))
+ return;
+ for (auto &dir_entry : boost::filesystem::directory_iterator(path))
+ if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini"))
+ boost::filesystem::remove(dir_entry.path());
+}
+
+const Snapshot& SnapshotDB::take_snapshot(const AppConfig &app_config, Snapshot::Reason reason, const std::string &comment)
+{
+ boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir());
+ boost::filesystem::path snapshot_db_dir = SnapshotDB::create_db_dir();
+
+ // 1) Prepare the snapshot structure.
+ Snapshot snapshot;
+ // Snapshot header.
+ snapshot.time_captured = Slic3r::Utils::get_current_time_utc();
+ snapshot.id = Slic3r::Utils::format_time_ISO8601Z(snapshot.time_captured);
+ snapshot.slic3r_version_captured = *Semver::parse(SLIC3R_VERSION); // XXX: have Semver Slic3r version
+ snapshot.comment = comment;
+ snapshot.reason = reason;
+ // Active presets at the time of the snapshot.
+ snapshot.print = app_config.get("presets", "print");
+ snapshot.filaments.emplace_back(app_config.get("presets", "filament"));
+ snapshot.printer = app_config.get("presets", "printer");
+ for (unsigned int i = 1; i < 1000; ++ i) {
+ char name[64];
+ sprintf(name, "filament_%d", i);
+ if (! app_config.has("presets", name))
+ break;
+ snapshot.filaments.emplace_back(app_config.get("presets", name));
+ }
+ // Vendor specific config bundles and installed printers.
+ for (const std::pair<std::string, std::map<std::string, std::set<std::string>>> &vendor : app_config.vendors()) {
+ Snapshot::VendorConfig cfg;
+ cfg.name = vendor.first;
+ cfg.models_variants_installed = vendor.second;
+ for (auto it = cfg.models_variants_installed.begin(); it != cfg.models_variants_installed.end();)
+ if (it->second.empty())
+ cfg.models_variants_installed.erase(it ++);
+ else
+ ++ it;
+ // Read the active config bundle, parse the config version.
+ PresetBundle bundle;
+ bundle.load_configbundle((data_dir / "vendor" / (cfg.name + ".ini")).string(), PresetBundle::LOAD_CFGBUNDLE_VENDOR_ONLY);
+ for (const VendorProfile &vp : bundle.vendors)
+ if (vp.id == cfg.name)
+ cfg.version.config_version = vp.config_version;
+ // Fill-in the min/max slic3r version from the config index, if possible.
+ try {
+ // Load the config index for the vendor.
+ Index index;
+ index.load(data_dir / "vendor" / (cfg.name + ".idx"));
+ auto it = index.find(cfg.version.config_version);
+ if (it != index.end()) {
+ cfg.version.min_slic3r_version = it->min_slic3r_version;
+ cfg.version.max_slic3r_version = it->max_slic3r_version;
+ }
+ } catch (const std::runtime_error &err) {
+ }
+ snapshot.vendor_configs.emplace_back(std::move(cfg));
+ }
+
+ boost::filesystem::path snapshot_dir = snapshot_db_dir / snapshot.id;
+ boost::filesystem::create_directory(snapshot_dir);
+
+ // Backup the presets.
+ for (const char *subdir : { "print", "filament", "printer", "vendor" })
+ copy_config_dir_single_level(data_dir / subdir, snapshot_dir / subdir);
+ snapshot.save_ini((snapshot_dir / "snapshot.ini").string());
+ assert(m_snapshots.empty() || m_snapshots.back().time_captured <= snapshot.time_captured);
+ m_snapshots.emplace_back(std::move(snapshot));
+ return m_snapshots.back();
+}
+
+const Snapshot& SnapshotDB::restore_snapshot(const std::string &id, AppConfig &app_config)
+{
+ for (const Snapshot &snapshot : m_snapshots)
+ if (snapshot.id == id) {
+ this->restore_snapshot(snapshot, app_config);
+ return snapshot;
+ }
+ throw std::runtime_error(std::string("Snapshot with id " + id + " was not found."));
+}
+
+void SnapshotDB::restore_snapshot(const Snapshot &snapshot, AppConfig &app_config)
+{
+ boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir());
+ boost::filesystem::path snapshot_db_dir = SnapshotDB::create_db_dir();
+ boost::filesystem::path snapshot_dir = snapshot_db_dir / snapshot.id;
+ // Remove existing ini files and restore the ini files from the snapshot.
+ for (const char *subdir : { "print", "filament", "printer", "vendor" }) {
+ delete_existing_ini_files(data_dir / subdir);
+ copy_config_dir_single_level(snapshot_dir / subdir, data_dir / subdir);
+ }
+ // Update AppConfig with the selections of the print / filament / printer profiles
+ // and about the installed printer types and variants.
+ snapshot.export_selections(app_config);
+ snapshot.export_vendor_configs(app_config);
+}
+
+bool SnapshotDB::is_on_snapshot(AppConfig &app_config) const
+{
+ // Is the "on_snapshot" configuration value set?
+ std::string on_snapshot = app_config.get("on_snapshot");
+ if (on_snapshot.empty())
+ // No, we are not on a snapshot.
+ return false;
+ // Is the "on_snapshot" equal to the current configuration state?
+ auto it_snapshot = this->snapshot(on_snapshot);
+ if (it_snapshot != this->end() && it_snapshot->equal_to_active(app_config))
+ // Yes, we are on the snapshot.
+ return true;
+ // No, we are no more on a snapshot. Reset the state.
+ app_config.set("on_snapshot", "");
+ return false;
+}
+
+SnapshotDB::const_iterator SnapshotDB::snapshot_with_vendor_preset(const std::string &vendor_name, const Semver &config_version)
+{
+ auto it_found = m_snapshots.end();
+ Snapshot::VendorConfig key;
+ key.name = vendor_name;
+ for (auto it = m_snapshots.begin(); it != m_snapshots.end(); ++ it) {
+ const Snapshot &snapshot = *it;
+ auto it_vendor_config = std::lower_bound(snapshot.vendor_configs.begin(), snapshot.vendor_configs.end(),
+ key, [](const Snapshot::VendorConfig &cfg1, const Snapshot::VendorConfig &cfg2) { return cfg1.name < cfg2.name; });
+ if (it_vendor_config != snapshot.vendor_configs.end() && it_vendor_config->name == vendor_name &&
+ config_version == it_vendor_config->version.config_version) {
+ // Vendor config found with the correct version.
+ // Save it, but continue searching, as we want the newest snapshot.
+ it_found = it;
+ }
+ }
+ return it_found;
+}
+
+SnapshotDB::const_iterator SnapshotDB::snapshot(const std::string &id) const
+{
+ for (const_iterator it = m_snapshots.begin(); it != m_snapshots.end(); ++ it)
+ if (it->id == id)
+ return it;
+ return m_snapshots.end();
+}
+
+boost::filesystem::path SnapshotDB::create_db_dir()
+{
+ boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir());
+ boost::filesystem::path snapshots_dir = data_dir / SLIC3R_SNAPSHOTS_DIR;
+ for (const boost::filesystem::path &path : { data_dir, snapshots_dir }) {
+ boost::filesystem::path subdir = path;
+ subdir.make_preferred();
+ if (! boost::filesystem::is_directory(subdir) &&
+ ! boost::filesystem::create_directory(subdir))
+ throw std::runtime_error(std::string("Slic3r was unable to create a directory at ") + subdir.string());
+ }
+ return snapshots_dir;
+}
+
+SnapshotDB& SnapshotDB::singleton()
+{
+ static SnapshotDB instance;
+ static bool loaded = false;
+ if (! loaded) {
+ try {
+ loaded = true;
+ // Load the snapshot database.
+ instance.load_db();
+ // Load the vendor specific configuration indices.
+ std::vector<Index> index_db = Index::load_db();
+ // Update the min / max slic3r versions compatible with the configurations stored inside the snapshots
+ // based on the min / max slic3r versions defined by the vendor specific config indices.
+ instance.update_slic3r_versions(index_db);
+ } catch (std::exception &ex) {
+ }
+ }
+ return instance;
+}
+
+} // namespace Config
+} // namespace GUI
+} // namespace Slic3r
diff --git a/xs/src/slic3r/Config/Snapshot.hpp b/xs/src/slic3r/Config/Snapshot.hpp
new file mode 100644
index 000000000..a916dfe92
--- /dev/null
+++ b/xs/src/slic3r/Config/Snapshot.hpp
@@ -0,0 +1,129 @@
+#ifndef slic3r_GUI_Snapshot_
+#define slic3r_GUI_Snapshot_
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <boost/filesystem.hpp>
+
+#include "Version.hpp"
+#include "../Utils/Semver.hpp"
+
+namespace Slic3r {
+
+class AppConfig;
+
+namespace GUI {
+namespace Config {
+
+class Index;
+
+// A snapshot contains:
+// Slic3r.ini
+// vendor/
+// print/
+// filament/
+// printer/
+class Snapshot
+{
+public:
+ enum Reason {
+ SNAPSHOT_UNKNOWN,
+ SNAPSHOT_UPGRADE,
+ SNAPSHOT_DOWNGRADE,
+ SNAPSHOT_BEFORE_ROLLBACK,
+ SNAPSHOT_USER,
+ };
+
+ Snapshot() { clear(); }
+
+ void clear();
+ void load_ini(const std::string &path);
+ void save_ini(const std::string &path);
+
+ // Export the print / filament / printer selections to be activated into the AppConfig.
+ void export_selections(AppConfig &config) const;
+ void export_vendor_configs(AppConfig &config) const;
+
+ // Perform a deep compare of the active print / filament / printer / vendor directories.
+ // Return true if the content of the current print / filament / printer / vendor directories
+ // matches the state stored in this snapshot.
+ bool equal_to_active(const AppConfig &app_config) const;
+
+ // ID of a snapshot should equal to the name of the snapshot directory.
+ // The ID contains the date/time, reason and comment to be human readable.
+ std::string id;
+ std::time_t time_captured;
+ // Which Slic3r version captured this snapshot?
+ Semver slic3r_version_captured = Semver::invalid();
+ // Comment entered by the user at the start of the snapshot capture.
+ std::string comment;
+ Reason reason;
+
+ std::string format_reason() const;
+
+ // Active presets at the time of the snapshot.
+ std::string print;
+ std::vector<std::string> filaments;
+ std::string printer;
+
+ // Annotation of the vendor configuration stored in the snapshot.
+ // This information is displayed to the user and used to decide compatibility
+ // of the configuration stored in the snapshot with the running Slic3r version.
+ struct VendorConfig {
+ // Name of the vendor contained in this snapshot.
+ std::string name;
+ // Version of the vendor config contained in this snapshot, along with compatibility data.
+ Version version;
+ // Which printer models of this vendor were installed, and which variants of the models?
+ std::map<std::string, std::set<std::string>> models_variants_installed;
+ };
+ // List of vendor configs contained in this snapshot, sorted lexicographically.
+ std::vector<VendorConfig> vendor_configs;
+};
+
+class SnapshotDB
+{
+public:
+ // Initialize the SnapshotDB singleton instance. Load the database if it has not been loaded yet.
+ static SnapshotDB& singleton();
+
+ typedef std::vector<Snapshot>::const_iterator const_iterator;
+
+ // Load the snapshot database from the snapshots directory.
+ // If the snapshot directory or its parent does not exist yet, it will be created.
+ // Returns a number of snapshots loaded.
+ size_t load_db();
+ void update_slic3r_versions(std::vector<Index> &index_db);
+
+ // Create a snapshot directory, copy the vendor config bundles, user print/filament/printer profiles,
+ // create an index.
+ const Snapshot& take_snapshot(const AppConfig &app_config, Snapshot::Reason reason, const std::string &comment = "");
+ const Snapshot& restore_snapshot(const std::string &id, AppConfig &app_config);
+ void restore_snapshot(const Snapshot &snapshot, AppConfig &app_config);
+ // Test whether the AppConfig's on_snapshot variable points to an existing snapshot, and the existing snapshot
+ // matches the current state. If it does not match the current state, the AppConfig's "on_snapshot" ID is reset.
+ bool is_on_snapshot(AppConfig &app_config) const;
+ // Finds the newest snapshot, which contains a config bundle for vendor_name with config_version.
+ const_iterator snapshot_with_vendor_preset(const std::string &vendor_name, const Semver &config_version);
+
+ const_iterator begin() const { return m_snapshots.begin(); }
+ const_iterator end() const { return m_snapshots.end(); }
+ const_iterator snapshot(const std::string &id) const;
+ const std::vector<Snapshot>& snapshots() const { return m_snapshots; }
+
+private:
+ // Create the snapshots directory if it does not exist yet.
+ static boost::filesystem::path create_db_dir();
+
+ // Snapshots are sorted by their date/time, oldest first.
+ std::vector<Snapshot> m_snapshots;
+};
+
+} // namespace Config
+} // namespace GUI
+} // namespace Slic3r
+
+#endif /* slic3r_GUI_Snapshot_ */
diff --git a/xs/src/slic3r/Config/Version.cpp b/xs/src/slic3r/Config/Version.cpp
new file mode 100644
index 000000000..a85322eca
--- /dev/null
+++ b/xs/src/slic3r/Config/Version.cpp
@@ -0,0 +1,319 @@
+#include "Version.hpp"
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/algorithm/string/trim.hpp>
+#include <boost/nowide/fstream.hpp>
+
+#include "../../libslic3r/libslic3r.h"
+#include "../../libslic3r/Config.hpp"
+#include "../../libslic3r/FileParserError.hpp"
+#include "../../libslic3r/Utils.hpp"
+
+namespace Slic3r {
+namespace GUI {
+namespace Config {
+
+static const Semver s_current_slic3r_semver(SLIC3R_VERSION);
+
+// Optimized lexicographic compare of two pre-release versions, ignoring the numeric suffix.
+static int compare_prerelease(const char *p1, const char *p2)
+{
+ for (;;) {
+ char c1 = *p1 ++;
+ char c2 = *p2 ++;
+ bool a1 = std::isalpha(c1) && c1 != 0;
+ bool a2 = std::isalpha(c2) && c2 != 0;
+ if (a1) {
+ if (a2) {
+ if (c1 != c2)
+ return (c1 < c2) ? -1 : 1;
+ } else
+ return 1;
+ } else {
+ if (a2)
+ return -1;
+ else
+ return 0;
+ }
+ }
+ // This shall never happen.
+ return 0;
+}
+
+bool Version::is_slic3r_supported(const Semver &slic3r_version) const
+{
+ if (! slic3r_version.in_range(min_slic3r_version, max_slic3r_version))
+ return false;
+ // Now verify, whether the configuration pre-release status is compatible with the Slic3r's pre-release status.
+ // Alpha Slic3r will happily load any configuration, while beta Slic3r will ignore alpha configurations etc.
+ const char *prerelease_slic3r = slic3r_version.prerelease();
+ const char *prerelease_config = this->config_version.prerelease();
+ if (prerelease_config == nullptr)
+ // Released config is always supported.
+ return true;
+ else if (prerelease_slic3r == nullptr)
+ // Released slic3r only supports released configs.
+ return false;
+ // Compare the pre-release status of Slic3r against the config.
+ // If the prerelease status of slic3r is lexicographically lower or equal
+ // to the prerelease status of the config, accept it.
+ return compare_prerelease(prerelease_slic3r, prerelease_config) != 1;
+}
+
+bool Version::is_current_slic3r_supported() const
+{
+ return this->is_slic3r_supported(s_current_slic3r_semver);
+}
+
+#if 0
+//TODO: This test should be moved to a unit test, once we have C++ unit tests in place.
+static int version_test()
+{
+ Version v;
+ v.config_version = *Semver::parse("1.1.2");
+ v.min_slic3r_version = *Semver::parse("1.38.0");
+ v.max_slic3r_version = Semver::inf();
+ assert(v.is_slic3r_supported(*Semver::parse("1.38.0")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.38.0-alpha")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.37.0-alpha")));
+ // Test the prerelease status.
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-rc2")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0")));
+ v.config_version = *Semver::parse("1.1.2-alpha");
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha1")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0-beta")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0-rc2")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0")));
+ v.config_version = *Semver::parse("1.1.2-alpha1");
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha1")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0-beta")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0-rc2")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0")));
+ v.config_version = *Semver::parse("1.1.2-beta");
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0-rc")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0-rc2")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0")));
+ v.config_version = *Semver::parse("1.1.2-rc");
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-rc")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-rc2")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0")));
+ v.config_version = *Semver::parse("1.1.2-rc2");
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-alpha1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-beta1")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-rc")));
+ assert(v.is_slic3r_supported(*Semver::parse("1.39.0-rc2")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.39.0")));
+ // Test the upper boundary.
+ v.config_version = *Semver::parse("1.1.2");
+ v.max_slic3r_version = *Semver::parse("1.39.3-beta1");
+ assert(v.is_slic3r_supported(*Semver::parse("1.38.0")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.38.0-alpha")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.38.0-alpha1")));
+ assert(! v.is_slic3r_supported(*Semver::parse("1.37.0-alpha")));
+ return 0;
+}
+static int version_test_run = version_test();
+#endif
+
+inline char* left_trim(char *c)
+{
+ for (; *c == ' ' || *c == '\t'; ++ c);
+ return c;
+}
+
+inline char* right_trim(char *start)
+{
+ char *end = start + strlen(start) - 1;
+ for (; end >= start && (*end == ' ' || *end == '\t'); -- end);
+ *(++ end) = 0;
+ return end;
+}
+
+inline std::string unquote_value(char *value, char *end, const std::string &path, int idx_line)
+{
+ std::string svalue;
+ if (value == end) {
+ // Empty string is a valid string.
+ } else if (*value == '"') {
+ if (++ value > -- end || *end != '"')
+ throw file_parser_error("String not enquoted correctly", path, idx_line);
+ *end = 0;
+ if (! unescape_string_cstyle(value, svalue))
+ throw file_parser_error("Invalid escape sequence inside a quoted string", path, idx_line);
+ } else
+ svalue.assign(value, end);
+ return svalue;
+}
+
+inline std::string unquote_version_comment(char *value, char *end, const std::string &path, int idx_line)
+{
+ std::string svalue;
+ if (value == end) {
+ // Empty string is a valid string.
+ } else if (*value == '"') {
+ if (++ value > -- end || *end != '"')
+ throw file_parser_error("Version comment not enquoted correctly", path, idx_line);
+ *end = 0;
+ if (! unescape_string_cstyle(value, svalue))
+ throw file_parser_error("Invalid escape sequence inside a quoted version comment", path, idx_line);
+ } else
+ svalue.assign(value, end);
+ return svalue;
+}
+
+size_t Index::load(const boost::filesystem::path &path)
+{
+ m_configs.clear();
+ m_vendor = path.stem().string();
+
+ boost::nowide::ifstream ifs(path.string());
+ std::string line;
+ size_t idx_line = 0;
+ Version ver;
+ while (std::getline(ifs, line)) {
+ ++ idx_line;
+ // Skip the initial white spaces.
+ char *key = left_trim(const_cast<char*>(line.data()));
+ if (*key == '#')
+ // Skip a comment line.
+ continue;
+ // Right trim the line.
+ char *end = right_trim(key);
+ if (key == end)
+ // Skip an empty line.
+ continue;
+ // Keyword may only contain alphanumeric characters. Semantic version may in addition contain "+.-".
+ char *key_end = key;
+ bool maybe_semver = true;
+ for (; *key_end != 0; ++ key_end) {
+ if (std::isalnum(*key_end) || strchr("+.-", *key_end) != nullptr) {
+ // It may be a semver.
+ } else if (*key_end == '_') {
+ // Cannot be a semver, but it may be a key.
+ maybe_semver = false;
+ } else
+ // End of semver or keyword.
+ break;
+ }
+ if (*key_end != 0 && *key_end != ' ' && *key_end != '\t' && *key_end != '=')
+ throw file_parser_error("Invalid keyword or semantic version", path, idx_line);
+ char *value = left_trim(key_end);
+ bool key_value_pair = *value == '=';
+ if (key_value_pair)
+ value = left_trim(value + 1);
+ *key_end = 0;
+ boost::optional<Semver> semver;
+ if (maybe_semver)
+ semver = Semver::parse(key);
+ if (key_value_pair) {
+ if (semver)
+ throw file_parser_error("Key cannot be a semantic version", path, idx_line);\
+ // Verify validity of the key / value pair.
+ std::string svalue = unquote_value(value, end, path.string(), idx_line);
+ if (strcmp(key, "min_slic3r_version") == 0 || strcmp(key, "max_slic3r_version") == 0) {
+ if (! svalue.empty())
+ semver = Semver::parse(svalue);
+ if (! semver)
+ throw file_parser_error(std::string(key) + " must referece a valid semantic version", path, idx_line);
+ if (strcmp(key, "min_slic3r_version") == 0)
+ ver.min_slic3r_version = *semver;
+ else
+ ver.max_slic3r_version = *semver;
+ } else {
+ // Ignore unknown keys, as there may come new keys in the future.
+ }
+ continue;
+ }
+ if (! semver)
+ throw file_parser_error("Invalid semantic version", path, idx_line);
+ ver.config_version = *semver;
+ ver.comment = (end <= key_end) ? "" : unquote_version_comment(value, end, path.string(), idx_line);
+ m_configs.emplace_back(ver);
+ }
+
+ // Sort the configs by their version.
+ std::sort(m_configs.begin(), m_configs.end(), [](const Version &v1, const Version &v2) { return v1.config_version < v2.config_version; });
+ return m_configs.size();
+}
+
+Semver Index::version() const
+{
+ Semver ver = Semver::zero();
+ for (const Version &cv : m_configs)
+ if (cv.config_version >= ver)
+ ver = cv.config_version;
+ return ver;
+}
+
+Index::const_iterator Index::find(const Semver &ver) const
+{
+ Version key;
+ key.config_version = ver;
+ auto it = std::lower_bound(m_configs.begin(), m_configs.end(), key,
+ [](const Version &v1, const Version &v2) { return v1.config_version < v2.config_version; });
+ return (it == m_configs.end() || it->config_version == ver) ? it : m_configs.end();
+}
+
+Index::const_iterator Index::recommended() const
+{
+ int idx = -1;
+ const_iterator highest = this->end();
+ for (const_iterator it = this->begin(); it != this->end(); ++ it)
+ if (it->is_current_slic3r_supported() &&
+ (highest == this->end() || highest->config_version < it->config_version))
+ highest = it;
+ return highest;
+}
+
+std::vector<Index> Index::load_db()
+{
+ boost::filesystem::path cache_dir = boost::filesystem::path(Slic3r::data_dir()) / "cache";
+
+ std::vector<Index> index_db;
+ std::string errors_cummulative;
+ for (auto &dir_entry : boost::filesystem::directory_iterator(cache_dir))
+ if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".idx")) {
+ Index idx;
+ try {
+ idx.load(dir_entry.path());
+ } catch (const std::runtime_error &err) {
+ errors_cummulative += err.what();
+ errors_cummulative += "\n";
+ continue;
+ }
+ index_db.emplace_back(std::move(idx));
+ }
+
+ if (! errors_cummulative.empty())
+ throw std::runtime_error(errors_cummulative);
+ return index_db;
+}
+
+} // namespace Config
+} // namespace GUI
+} // namespace Slic3r
diff --git a/xs/src/slic3r/Config/Version.hpp b/xs/src/slic3r/Config/Version.hpp
new file mode 100644
index 000000000..acb0ae460
--- /dev/null
+++ b/xs/src/slic3r/Config/Version.hpp
@@ -0,0 +1,88 @@
+#ifndef slic3r_GUI_ConfigIndex_
+#define slic3r_GUI_ConfigIndex_
+
+#include <string>
+#include <vector>
+
+#include <boost/filesystem.hpp>
+
+#include "../../libslic3r/FileParserError.hpp"
+#include "../Utils/Semver.hpp"
+
+namespace Slic3r {
+namespace GUI {
+namespace Config {
+
+// Configuration bundle version.
+struct Version
+{
+ // Version of this config.
+ Semver config_version = Semver::invalid();
+ // Minimum Slic3r version, for which this config is applicable.
+ Semver min_slic3r_version = Semver::zero();
+ // Maximum Slic3r version, for which this config is recommended.
+ // Slic3r should read older configuration and upgrade to a newer format,
+ // but likely there has been a better configuration published, using the new features.
+ Semver max_slic3r_version = Semver::inf();
+ // Single comment line.
+ std::string comment;
+
+ bool is_slic3r_supported(const Semver &slicer_version) const;
+ bool is_current_slic3r_supported() const;
+};
+
+// Index of vendor specific config bundle versions and Slic3r compatibilities.
+// The index is being downloaded from the internet, also an initial version of the index
+// is contained in the Slic3r installation.
+//
+// The index has a simple format:
+//
+// min_sic3r_version =
+// max_slic3r_version =
+// config_version "comment"
+// config_version "comment"
+// ...
+// min_slic3r_version =
+// max_slic3r_version =
+// config_version comment
+// config_version comment
+// ...
+//
+// The min_slic3r_version, max_slic3r_version keys are applied to the config versions below,
+// empty slic3r version means an open interval.
+class Index
+{
+public:
+ typedef std::vector<Version>::const_iterator const_iterator;
+ // Read a config index file in the simple format described in the Index class comment.
+ // Throws Slic3r::file_parser_error and the standard std file access exceptions.
+ size_t load(const boost::filesystem::path &path);
+
+ const std::string& vendor() const { return m_vendor; }
+ // Returns version of the index as the highest version of all the configs.
+ // If there is no config, Semver::zero() is returned.
+ Semver version() const;
+
+ const_iterator begin() const { return m_configs.begin(); }
+ const_iterator end() const { return m_configs.end(); }
+ const_iterator find(const Semver &ver) const;
+ const std::vector<Version>& configs() const { return m_configs; }
+ // Finds a recommended config to be installed for the current Slic3r version.
+ // Returns configs().end() if such version does not exist in the index. This shall never happen
+ // if the index is valid.
+ const_iterator recommended() const;
+
+ // Load all vendor specific indices.
+ // Throws Slic3r::file_parser_error and the standard std file access exceptions.
+ static std::vector<Index> load_db();
+
+private:
+ std::string m_vendor;
+ std::vector<Version> m_configs;
+};
+
+} // namespace Config
+} // namespace GUI
+} // namespace Slic3r
+
+#endif /* slic3r_GUI_ConfigIndex_ */
diff --git a/xs/src/slic3r/GUI/2DBed.cpp b/xs/src/slic3r/GUI/2DBed.cpp
index c5d68400d..e19f839cd 100644
--- a/xs/src/slic3r/GUI/2DBed.cpp
+++ b/xs/src/slic3r/GUI/2DBed.cpp
@@ -1,4 +1,4 @@
-#include "2DBed.hpp";
+#include "2DBed.hpp"
#include <wx/dcbuffer.h>
#include "BoundingBox.hpp"
@@ -32,17 +32,17 @@ void Bed_2D::repaint()
cw--;
ch--;
- auto cbb = BoundingBoxf(Pointf(0, 0),Pointf(cw, ch));
+ auto cbb = BoundingBoxf(Vec2d(0, 0),Vec2d(cw, ch));
// leave space for origin point
- cbb.min.translate(4, 0);
- cbb.max.translate(-4, -4);
+ cbb.min(0) += 4;
+ cbb.max -= Vec2d(4., 4.);
// leave space for origin label
- cbb.max.translate(0, -13);
+ cbb.max(1) -= 13;
// read new size
- cw = cbb.size().x;
- ch = cbb.size().y;
+ cw = cbb.size()(0);
+ ch = cbb.size()(1);
auto ccenter = cbb.center();
@@ -50,113 +50,110 @@ void Bed_2D::repaint()
auto bed_shape = m_bed_shape;
auto bed_polygon = Polygon::new_scale(m_bed_shape);
auto bb = BoundingBoxf(m_bed_shape);
- bb.merge(Pointf(0, 0)); // origin needs to be in the visible area
- auto bw = bb.size().x;
- auto bh = bb.size().y;
+ bb.merge(Vec2d(0, 0)); // origin needs to be in the visible area
+ auto bw = bb.size()(0);
+ auto bh = bb.size()(1);
auto bcenter = bb.center();
// calculate the scaling factor for fitting bed shape in canvas area
auto sfactor = std::min(cw/bw, ch/bh);
- auto shift = Pointf(
- ccenter.x - bcenter.x * sfactor,
- ccenter.y - bcenter.y * sfactor
+ auto shift = Vec2d(
+ ccenter(0) - bcenter(0) * sfactor,
+ ccenter(1) - bcenter(1) * sfactor
);
m_scale_factor = sfactor;
- m_shift = Pointf(shift.x + cbb.min.x,
- shift.y - (cbb.max.y - GetSize().GetHeight()));
+ m_shift = Vec2d(shift(0) + cbb.min(0),
+ shift(1) - (cbb.max(1) - GetSize().GetHeight()));
// draw bed fill
- dc.SetBrush(*new wxBrush(*new wxColour(255, 255, 255), wxSOLID));
+ dc.SetBrush(wxBrush(wxColour(255, 255, 255), wxSOLID));
wxPointList pt_list;
for (auto pt: m_bed_shape)
{
Point pt_pix = to_pixels(pt);
- pt_list.push_back(new wxPoint(pt_pix.x, pt_pix.y));
+ pt_list.push_back(new wxPoint(pt_pix(0), pt_pix(1)));
}
dc.DrawPolygon(&pt_list, 0, 0);
// draw grid
auto step = 10; // 1cm grid
Polylines polylines;
- for (auto x = bb.min.x - fmod(bb.min.x, step) + step; x < bb.max.x; x += step) {
- Polyline pl = Polyline::new_scale({ Pointf(x, bb.min.y), Pointf(x, bb.max.y) });
- polylines.push_back(pl);
+ for (auto x = bb.min(0) - fmod(bb.min(0), step) + step; x < bb.max(0); x += step) {
+ polylines.push_back(Polyline::new_scale({ Vec2d(x, bb.min(1)), Vec2d(x, bb.max(1)) }));
}
- for (auto y = bb.min.y - fmod(bb.min.y, step) + step; y < bb.max.y; y += step) {
- polylines.push_back(Polyline::new_scale({ Pointf(bb.min.x, y), Pointf(bb.max.x, y) }));
+ for (auto y = bb.min(1) - fmod(bb.min(1), step) + step; y < bb.max(1); y += step) {
+ polylines.push_back(Polyline::new_scale({ Vec2d(bb.min(0), y), Vec2d(bb.max(0), y) }));
}
polylines = intersection_pl(polylines, bed_polygon);
- dc.SetPen(*new wxPen(*new wxColour(230, 230, 230), 1, wxSOLID));
+ dc.SetPen(wxPen(wxColour(230, 230, 230), 1, wxSOLID));
for (auto pl : polylines)
{
for (size_t i = 0; i < pl.points.size()-1; i++){
- Point pt1 = to_pixels(Pointf::new_unscale(pl.points[i]));
- Point pt2 = to_pixels(Pointf::new_unscale(pl.points[i+1]));
- dc.DrawLine(pt1.x, pt1.y, pt2.x, pt2.y);
+ Point pt1 = to_pixels(unscale(pl.points[i]));
+ Point pt2 = to_pixels(unscale(pl.points[i+1]));
+ dc.DrawLine(pt1(0), pt1(1), pt2(0), pt2(1));
}
}
// draw bed contour
- dc.SetPen(*new wxPen(*new wxColour(0, 0, 0), 1, wxSOLID));
- dc.SetBrush(*new wxBrush(*new wxColour(0, 0, 0), wxTRANSPARENT));
+ dc.SetPen(wxPen(wxColour(0, 0, 0), 1, wxSOLID));
+ dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxTRANSPARENT));
dc.DrawPolygon(&pt_list, 0, 0);
- auto origin_px = to_pixels(Pointf(0, 0));
+ auto origin_px = to_pixels(Vec2d(0, 0));
// draw axes
auto axes_len = 50;
auto arrow_len = 6;
auto arrow_angle = Geometry::deg2rad(45.0);
- dc.SetPen(*new wxPen(*new wxColour(255, 0, 0), 2, wxSOLID)); // red
- auto x_end = Pointf(origin_px.x + axes_len, origin_px.y);
- dc.DrawLine(wxPoint(origin_px.x, origin_px.y), wxPoint(x_end.x, x_end.y));
+ dc.SetPen(wxPen(wxColour(255, 0, 0), 2, wxSOLID)); // red
+ auto x_end = Vec2d(origin_px(0) + axes_len, origin_px(1));
+ dc.DrawLine(wxPoint(origin_px(0), origin_px(1)), wxPoint(x_end(0), x_end(1)));
for (auto angle : { -arrow_angle, arrow_angle }){
- auto end = x_end;
- end.translate(-arrow_len, 0);
- end.rotate(angle, x_end);
- dc.DrawLine(wxPoint(x_end.x, x_end.y), wxPoint(end.x, end.y));
+ auto end = Eigen::Translation2d(x_end) * Eigen::Rotation2Dd(angle) * Eigen::Translation2d(- x_end) * Eigen::Vector2d(x_end(0) - arrow_len, x_end(1));
+ dc.DrawLine(wxPoint(x_end(0), x_end(1)), wxPoint(end(0), end(1)));
}
- dc.SetPen(*new wxPen(*new wxColour(0, 255, 0), 2, wxSOLID)); // green
- auto y_end = Pointf(origin_px.x, origin_px.y - axes_len);
- dc.DrawLine(wxPoint(origin_px.x, origin_px.y), wxPoint(y_end.x, y_end.y));
+ dc.SetPen(wxPen(wxColour(0, 255, 0), 2, wxSOLID)); // green
+ auto y_end = Vec2d(origin_px(0), origin_px(1) - axes_len);
+ dc.DrawLine(wxPoint(origin_px(0), origin_px(1)), wxPoint(y_end(0), y_end(1)));
for (auto angle : { -arrow_angle, arrow_angle }) {
- auto end = y_end;
- end.translate(0, +arrow_len);
- end.rotate(angle, y_end);
- dc.DrawLine(wxPoint(y_end.x, y_end.y), wxPoint(end.x, end.y));
+ auto end = Eigen::Translation2d(y_end) * Eigen::Rotation2Dd(angle) * Eigen::Translation2d(- y_end) * Eigen::Vector2d(y_end(0), y_end(1) + arrow_len);
+ dc.DrawLine(wxPoint(y_end(0), y_end(1)), wxPoint(end(0), end(1)));
}
// draw origin
- dc.SetPen(*new wxPen(*new wxColour(0, 0, 0), 1, wxSOLID));
- dc.SetBrush(*new wxBrush(*new wxColour(0, 0, 0), wxSOLID));
- dc.DrawCircle(origin_px.x, origin_px.y, 3);
-
- dc.SetTextForeground(*new wxColour(0, 0, 0));
- dc.SetFont(*new wxFont(10, wxDEFAULT, wxNORMAL, wxNORMAL));
- dc.DrawText("(0,0)", origin_px.x + 1, origin_px.y + 2);
+ dc.SetPen(wxPen(wxColour(0, 0, 0), 1, wxSOLID));
+ dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxSOLID));
+ dc.DrawCircle(origin_px(0), origin_px(1), 3);
+
+ static const auto origin_label = wxString("(0,0)");
+ dc.SetTextForeground(wxColour(0, 0, 0));
+ dc.SetFont(wxFont(10, wxDEFAULT, wxNORMAL, wxNORMAL));
+ auto extent = dc.GetTextExtent(origin_label);
+ const auto origin_label_x = origin_px(0) <= cw / 2 ? origin_px(0) + 1 : origin_px(0) - 1 - extent.GetWidth();
+ const auto origin_label_y = origin_px(1) <= ch / 2 ? origin_px(1) + 1 : origin_px(1) - 1 - extent.GetHeight();
+ dc.DrawText(origin_label, origin_label_x, origin_label_y);
// draw current position
- if (m_pos!= Pointf(0, 0)) {
+ if (m_pos!= Vec2d(0, 0)) {
auto pos_px = to_pixels(m_pos);
- dc.SetPen(*new wxPen(*new wxColour(200, 0, 0), 2, wxSOLID));
- dc.SetBrush(*new wxBrush(*new wxColour(200, 0, 0), wxTRANSPARENT));
- dc.DrawCircle(pos_px.x, pos_px.y, 5);
+ dc.SetPen(wxPen(wxColour(200, 0, 0), 2, wxSOLID));
+ dc.SetBrush(wxBrush(wxColour(200, 0, 0), wxTRANSPARENT));
+ dc.DrawCircle(pos_px(0), pos_px(1), 5);
- dc.DrawLine(pos_px.x - 15, pos_px.y, pos_px.x + 15, pos_px.y);
- dc.DrawLine(pos_px.x, pos_px.y - 15, pos_px.x, pos_px.y + 15);
+ dc.DrawLine(pos_px(0) - 15, pos_px(1), pos_px(0) + 15, pos_px(1));
+ dc.DrawLine(pos_px(0), pos_px(1) - 15, pos_px(0), pos_px(1) + 15);
}
m_painted = true;
}
// convert G - code coordinates into pixels
-Point Bed_2D::to_pixels(Pointf point){
- auto p = Pointf(point);
- p.scale(m_scale_factor);
- p.translate(m_shift);
- return Point(p.x, GetSize().GetHeight() - p.y);
+Point Bed_2D::to_pixels(Vec2d point){
+ auto p = point * m_scale_factor + m_shift;
+ return Point(p(0), GetSize().GetHeight() - p(1));
}
void Bed_2D::mouse_event(wxMouseEvent event){
@@ -164,7 +161,7 @@ void Bed_2D::mouse_event(wxMouseEvent event){
if (!m_painted) return;
auto pos = event.GetPosition();
- auto point = to_units(Point(pos.x, pos.y));
+ auto point = to_units(Point(pos.x, pos.y));
if (event.LeftDown() || event.Dragging()) {
if (m_on_move)
m_on_move(point) ;
@@ -173,14 +170,11 @@ void Bed_2D::mouse_event(wxMouseEvent event){
}
// convert pixels into G - code coordinates
-Pointf Bed_2D::to_units(Point point){
- auto p = Pointf(point.x, GetSize().GetHeight() - point.y);
- p.translate(m_shift.negative());
- p.scale(1 / m_scale_factor);
- return p;
+Vec2d Bed_2D::to_units(Point point){
+ return (Vec2d(point(0), GetSize().GetHeight() - point(1)) - m_shift) * (1. / m_scale_factor);
}
-void Bed_2D::set_pos(Pointf pos){
+void Bed_2D::set_pos(Vec2d pos){
m_pos = pos;
Refresh();
}
diff --git a/xs/src/slic3r/GUI/2DBed.hpp b/xs/src/slic3r/GUI/2DBed.hpp
index 859417efb..d7a7f4260 100644
--- a/xs/src/slic3r/GUI/2DBed.hpp
+++ b/xs/src/slic3r/GUI/2DBed.hpp
@@ -1,3 +1,6 @@
+#ifndef slic3r_2DBed_hpp_
+#define slic3r_2DBed_hpp_
+
#include <wx/wx.h>
#include "Config.hpp"
@@ -6,27 +9,29 @@ namespace GUI {
class Bed_2D : public wxPanel
{
- bool m_user_drawn_background = false;
+ bool m_user_drawn_background = true;
bool m_painted = false;
bool m_interactive = false;
double m_scale_factor;
- Pointf m_shift;
- Pointf m_pos;
- std::function<void(Pointf)> m_on_move = nullptr;
+ Vec2d m_shift = Vec2d::Zero();
+ Vec2d m_pos = Vec2d::Zero();
+ std::function<void(Vec2d)> m_on_move = nullptr;
- Point to_pixels(Pointf point);
- Pointf to_units(Point point);
+ Point to_pixels(Vec2d point);
+ Vec2d to_units(Point point);
void repaint();
void mouse_event(wxMouseEvent event);
- void set_pos(Pointf pos);
+ void set_pos(Vec2d pos);
public:
Bed_2D(wxWindow* parent)
{
Create(parent, wxID_ANY, wxDefaultPosition, wxSize(250, -1), wxTAB_TRAVERSAL);
// m_user_drawn_background = $^O ne 'darwin';
- m_user_drawn_background = true;
+#ifdef __APPLE__
+ m_user_drawn_background = false;
+#endif /*__APPLE__*/
Bind(wxEVT_PAINT, ([this](wxPaintEvent e) { repaint(); }));
// EVT_ERASE_BACKGROUND($self, sub{}) if $self->{user_drawn_background};
// Bind(EVT_MOUSE_EVENTS, ([this](wxMouseEvent event){/*mouse_event()*/; }));
@@ -36,10 +41,12 @@ public:
}
~Bed_2D(){}
- std::vector<Pointf> m_bed_shape;
+ std::vector<Vec2d> m_bed_shape;
};
} // GUI
} // Slic3r
+
+#endif /* slic3r_2DBed_hpp_ */
diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp
index 356d27b96..a488bfcde 100644
--- a/xs/src/slic3r/GUI/3DScene.cpp
+++ b/xs/src/slic3r/GUI/3DScene.cpp
@@ -2,13 +2,13 @@
#include "3DScene.hpp"
-#include "../../libslic3r/libslic3r.h"
#include "../../libslic3r/ExtrusionEntity.hpp"
#include "../../libslic3r/ExtrusionEntityCollection.hpp"
#include "../../libslic3r/Geometry.hpp"
#include "../../libslic3r/GCode/PreviewData.hpp"
#include "../../libslic3r/Print.hpp"
#include "../../libslic3r/Slicing.hpp"
+#include "../../slic3r/GUI/PresetBundle.hpp"
#include "GCode/Analyzer.hpp"
#include <stdio.h>
@@ -22,10 +22,7 @@
#include <tbb/parallel_for.h>
#include <tbb/spin_mutex.h>
-#include <wx/bitmap.h>
-#include <wx/dcmemory.h>
-#include <wx/image.h>
-#include <wx/settings.h>
+#include <Eigen/Dense>
#include "GUI.hpp"
@@ -42,7 +39,7 @@ void GLIndexedVertexArray::load_mesh_flat_shading(const TriangleMesh &mesh)
for (int i = 0; i < mesh.stl.stats.number_of_facets; ++ i) {
const stl_facet &facet = mesh.stl.facet_start[i];
for (int j = 0; j < 3; ++ j)
- this->push_geometry(facet.vertex[j].x, facet.vertex[j].y, facet.vertex[j].z, facet.normal.x, facet.normal.y, facet.normal.z);
+ this->push_geometry(facet.vertex[j](0), facet.vertex[j](1), facet.vertex[j](2), facet.normal(0), facet.normal(1), facet.normal(2));
}
}
@@ -58,7 +55,7 @@ void GLIndexedVertexArray::load_mesh_full_shading(const TriangleMesh &mesh)
for (int i = 0; i < mesh.stl.stats.number_of_facets; ++i) {
const stl_facet &facet = mesh.stl.facet_start[i];
for (int j = 0; j < 3; ++j)
- this->push_geometry(facet.vertex[j].x, facet.vertex[j].y, facet.vertex[j].z, facet.normal.x, facet.normal.y, facet.normal.z);
+ this->push_geometry(facet.vertex[j](0), facet.vertex[j](1), facet.vertex[j](2), facet.normal(0), facet.normal(1), facet.normal(2));
this->push_triangle(vertices_count, vertices_count + 1, vertices_count + 2);
vertices_count += 3;
@@ -194,8 +191,40 @@ void GLIndexedVertexArray::render(
const float GLVolume::SELECTED_COLOR[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
const float GLVolume::HOVER_COLOR[4] = { 0.4f, 0.9f, 0.1f, 1.0f };
-const float GLVolume::OUTSIDE_COLOR[4] = { 0.75f, 0.0f, 0.75f, 1.0f };
-const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 1.0f, 0.0f, 1.0f, 1.0f };
+const float GLVolume::OUTSIDE_COLOR[4] = { 0.0f, 0.38f, 0.8f, 1.0f };
+const float GLVolume::SELECTED_OUTSIDE_COLOR[4] = { 0.19f, 0.58f, 1.0f, 1.0f };
+
+GLVolume::GLVolume(float r, float g, float b, float a)
+ : m_offset(Vec3d::Zero())
+ , m_rotation(0.0)
+ , m_scaling_factor(1.0)
+ , m_world_matrix(Transform3f::Identity())
+ , m_world_matrix_dirty(true)
+ , m_transformed_bounding_box_dirty(true)
+ , m_transformed_convex_hull_bounding_box_dirty(true)
+ , m_convex_hull(nullptr)
+ , composite_id(-1)
+ , select_group_id(-1)
+ , drag_group_id(-1)
+ , extruder_id(0)
+ , selected(false)
+ , is_active(true)
+ , zoom_to_volumes(true)
+ , shader_outside_printer_detection_enabled(false)
+ , is_outside(false)
+ , hover(false)
+ , is_modifier(false)
+ , is_wipe_tower(false)
+ , is_extrusion_path(false)
+ , tverts_range(0, size_t(-1))
+ , qverts_range(0, size_t(-1))
+{
+ color[0] = r;
+ color[1] = g;
+ color[2] = b;
+ color[3] = a;
+ set_render_color(r, g, b, a);
+}
void GLVolume::set_render_color(float r, float g, float b, float a)
{
@@ -217,20 +246,120 @@ void GLVolume::set_render_color(const float* rgba, unsigned int size)
void GLVolume::set_render_color()
{
if (selected)
- {
- if (is_outside)
- set_render_color(SELECTED_OUTSIDE_COLOR, 4);
- else
- set_render_color(SELECTED_COLOR, 4);
- }
+ set_render_color(is_outside ? SELECTED_OUTSIDE_COLOR : SELECTED_COLOR, 4);
else if (hover)
set_render_color(HOVER_COLOR, 4);
- else if (is_outside)
+ else if (is_outside && shader_outside_printer_detection_enabled)
set_render_color(OUTSIDE_COLOR, 4);
else
set_render_color(color, 4);
}
+double GLVolume::get_rotation()
+{
+ return m_rotation;
+}
+
+void GLVolume::set_rotation(double rotation)
+{
+ if (m_rotation != rotation)
+ {
+ m_rotation = rotation;
+ m_world_matrix_dirty = true;
+ m_transformed_bounding_box_dirty = true;
+ m_transformed_convex_hull_bounding_box_dirty = true;
+ }
+}
+
+const Vec3d& GLVolume::get_offset() const
+{
+ return m_offset;
+}
+
+void GLVolume::set_offset(const Vec3d& offset)
+{
+ if (m_offset != offset)
+ {
+ m_offset = offset;
+ m_world_matrix_dirty = true;
+ m_transformed_bounding_box_dirty = true;
+ m_transformed_convex_hull_bounding_box_dirty = true;
+ }
+}
+
+void GLVolume::set_scaling_factor(double factor)
+{
+ if (m_scaling_factor != factor)
+ {
+ m_scaling_factor = factor;
+ m_world_matrix_dirty = true;
+ m_transformed_bounding_box_dirty = true;
+ m_transformed_convex_hull_bounding_box_dirty = true;
+ }
+}
+
+void GLVolume::set_convex_hull(const TriangleMesh& convex_hull)
+{
+ m_convex_hull = &convex_hull;
+}
+
+void GLVolume::set_select_group_id(const std::string& select_by)
+{
+ if (select_by == "object")
+ select_group_id = object_idx() * 1000000;
+ else if (select_by == "volume")
+ select_group_id = object_idx() * 1000000 + volume_idx() * 1000;
+ else if (select_by == "instance")
+ select_group_id = composite_id;
+}
+
+void GLVolume::set_drag_group_id(const std::string& drag_by)
+{
+ if (drag_by == "object")
+ drag_group_id = object_idx() * 1000;
+ else if (drag_by == "instance")
+ drag_group_id = object_idx() * 1000 + instance_idx();
+}
+
+const Transform3f& GLVolume::world_matrix() const
+{
+ if (m_world_matrix_dirty)
+ {
+ m_world_matrix = Transform3f::Identity();
+ m_world_matrix.translate(m_offset.cast<float>());
+ m_world_matrix.rotate(Eigen::AngleAxisf((float)m_rotation, Vec3f::UnitZ()));
+ m_world_matrix.scale((float)m_scaling_factor);
+ m_world_matrix_dirty = false;
+ }
+ return m_world_matrix;
+}
+
+const BoundingBoxf3& GLVolume::transformed_bounding_box() const
+{
+ if (m_transformed_bounding_box_dirty)
+ {
+ m_transformed_bounding_box = bounding_box.transformed(world_matrix().cast<double>());
+ m_transformed_bounding_box_dirty = false;
+ }
+
+ return m_transformed_bounding_box;
+}
+
+const BoundingBoxf3& GLVolume::transformed_convex_hull_bounding_box() const
+{
+ if (m_transformed_convex_hull_bounding_box_dirty)
+ {
+ if ((m_convex_hull != nullptr) && (m_convex_hull->stl.stats.number_of_facets > 0))
+ m_transformed_convex_hull_bounding_box = m_convex_hull->transformed_bounding_box(world_matrix().cast<double>());
+ else
+ m_transformed_convex_hull_bounding_box = bounding_box.transformed(world_matrix().cast<double>());
+
+ m_transformed_convex_hull_bounding_box_dirty = false;
+ }
+
+ return m_transformed_convex_hull_bounding_box;
+}
+
void GLVolume::set_range(double min_z, double max_z)
{
this->qverts_range.first = 0;
@@ -271,14 +400,16 @@ void GLVolume::render() const
if (!is_active)
return;
- glCullFace(GL_BACK);
- glPushMatrix();
- glTranslated(this->origin.x, this->origin.y, this->origin.z);
+ ::glCullFace(GL_BACK);
+ ::glPushMatrix();
+ ::glTranslated(m_offset(0), m_offset(1), m_offset(2));
+ ::glRotated(m_rotation * 180.0 / (double)PI, 0.0, 0.0, 1.0);
+ ::glScaled(m_scaling_factor, m_scaling_factor, m_scaling_factor);
if (this->indexed_vertex_array.indexed())
this->indexed_vertex_array.render(this->tverts_range, this->qverts_range);
else
this->indexed_vertex_array.render();
- glPopMatrix();
+ ::glPopMatrix();
}
void GLVolume::render_using_layer_height() const
@@ -296,6 +427,7 @@ void GLVolume::render_using_layer_height() const
GLint z_texture_row_to_normalized_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_texture_row_to_normalized") : -1;
GLint z_cursor_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_cursor") : -1;
GLint z_cursor_band_width_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_cursor_band_width") : -1;
+ GLint world_matrix_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "volume_world_matrix") : -1;
if (z_to_texture_row_id >= 0)
glUniform1f(z_to_texture_row_id, (GLfloat)layer_height_texture_z_to_row_id());
@@ -304,19 +436,25 @@ void GLVolume::render_using_layer_height() const
glUniform1f(z_texture_row_to_normalized_id, (GLfloat)(1.0f / layer_height_texture_height()));
if (z_cursor_id >= 0)
- glUniform1f(z_cursor_id, (GLfloat)(bounding_box.max.z * layer_height_texture_data.z_cursor_relative));
+ glUniform1f(z_cursor_id, (GLfloat)(layer_height_texture_data.print_object->model_object()->bounding_box().max(2) * layer_height_texture_data.z_cursor_relative));
if (z_cursor_band_width_id >= 0)
glUniform1f(z_cursor_band_width_id, (GLfloat)layer_height_texture_data.edit_band_width);
- unsigned int w = layer_height_texture_width();
- unsigned int h = layer_height_texture_height();
+ if (world_matrix_id >= 0)
+ ::glUniformMatrix4fv(world_matrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data());
+
+ GLsizei w = (GLsizei)layer_height_texture_width();
+ GLsizei h = (GLsizei)layer_height_texture_height();
+ GLsizei half_w = w / 2;
+ GLsizei half_h = h / 2;
+ ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, layer_height_texture_data.texture_id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, w / 2, h / 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, layer_height_texture_data_ptr_level0());
- glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, w / 2, h / 2, GL_RGBA, GL_UNSIGNED_BYTE, layer_height_texture_data_ptr_level1());
+ glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, layer_height_texture_data_ptr_level1());
render();
@@ -326,15 +464,142 @@ void GLVolume::render_using_layer_height() const
glUseProgram(current_program_id);
}
-void GLVolume::generate_layer_height_texture(PrintObject *print_object, bool force)
+void GLVolume::render_VBOs(int color_id, int detection_id, int worldmatrix_id) const
{
- GLTexture *tex = this->layer_height_texture.get();
- if (tex == nullptr)
+ if (!is_active)
+ return;
+
+ if (!indexed_vertex_array.vertices_and_normals_interleaved_VBO_id)
+ return;
+
+ if (layer_height_texture_data.can_use())
+ {
+ ::glDisableClientState(GL_VERTEX_ARRAY);
+ ::glDisableClientState(GL_NORMAL_ARRAY);
+ render_using_layer_height();
+ ::glEnableClientState(GL_VERTEX_ARRAY);
+ ::glEnableClientState(GL_NORMAL_ARRAY);
+ return;
+ }
+
+ GLsizei n_triangles = GLsizei(std::min(indexed_vertex_array.triangle_indices_size, tverts_range.second - tverts_range.first));
+ GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first));
+ if (n_triangles + n_quads == 0)
+ {
+ ::glDisableClientState(GL_VERTEX_ARRAY);
+ ::glDisableClientState(GL_NORMAL_ARRAY);
+
+ if (color_id >= 0)
+ {
+ float color[4];
+ ::memcpy((void*)color, (const void*)render_color, 4 * sizeof(float));
+ ::glUniform4fv(color_id, 1, (const GLfloat*)color);
+ }
+ else
+ ::glColor4f(render_color[0], render_color[1], render_color[2], render_color[3]);
+
+ if (detection_id != -1)
+ ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0);
+
+ if (worldmatrix_id != -1)
+ ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data());
+
+ render();
+
+ ::glEnableClientState(GL_VERTEX_ARRAY);
+ ::glEnableClientState(GL_NORMAL_ARRAY);
+
+ return;
+ }
+
+ if (color_id >= 0)
+ ::glUniform4fv(color_id, 1, (const GLfloat*)render_color);
+ else
+ ::glColor4f(render_color[0], render_color[1], render_color[2], render_color[3]);
+
+ if (detection_id != -1)
+ ::glUniform1i(detection_id, shader_outside_printer_detection_enabled ? 1 : 0);
+
+ if (worldmatrix_id != -1)
+ ::glUniformMatrix4fv(worldmatrix_id, 1, GL_FALSE, (const GLfloat*)world_matrix().data());
+
+ ::glBindBuffer(GL_ARRAY_BUFFER, indexed_vertex_array.vertices_and_normals_interleaved_VBO_id);
+ ::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
+ ::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr);
+
+ ::glPushMatrix();
+ ::glTranslated(m_offset(0), m_offset(1), m_offset(2));
+ ::glRotated(m_rotation * 180.0 / (double)PI, 0.0, 0.0, 1.0);
+ ::glScaled(m_scaling_factor, m_scaling_factor, m_scaling_factor);
+
+ if (n_triangles > 0)
+ {
+ ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.triangle_indices_VBO_id);
+ ::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(tverts_range.first * 4));
+ }
+ if (n_quads > 0)
+ {
+ ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexed_vertex_array.quad_indices_VBO_id);
+ ::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(qverts_range.first * 4));
+ }
+
+ ::glPopMatrix();
+}
+
+void GLVolume::render_legacy() const
+{
+ assert(!indexed_vertex_array.vertices_and_normals_interleaved_VBO_id);
+ if (!is_active)
+ return;
+
+ GLsizei n_triangles = GLsizei(std::min(indexed_vertex_array.triangle_indices_size, tverts_range.second - tverts_range.first));
+ GLsizei n_quads = GLsizei(std::min(indexed_vertex_array.quad_indices_size, qverts_range.second - qverts_range.first));
+ if (n_triangles + n_quads == 0)
+ {
+ ::glDisableClientState(GL_VERTEX_ARRAY);
+ ::glDisableClientState(GL_NORMAL_ARRAY);
+
+ ::glColor4f(render_color[0], render_color[1], render_color[2], render_color[3]);
+ render();
+
+ ::glEnableClientState(GL_VERTEX_ARRAY);
+ ::glEnableClientState(GL_NORMAL_ARRAY);
+
+ return;
+ }
+
+ ::glColor4f(render_color[0], render_color[1], render_color[2], render_color[3]);
+ ::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data() + 3);
+ ::glNormalPointer(GL_FLOAT, 6 * sizeof(float), indexed_vertex_array.vertices_and_normals_interleaved.data());
+
+ ::glPushMatrix();
+ ::glTranslated(m_offset(0), m_offset(1), m_offset(2));
+ ::glRotated(m_rotation * 180.0 / (double)PI, 0.0, 0.0, 1.0);
+ ::glScaled(m_scaling_factor, m_scaling_factor, m_scaling_factor);
+
+ if (n_triangles > 0)
+ ::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, indexed_vertex_array.triangle_indices.data() + tverts_range.first);
+
+ if (n_quads > 0)
+ ::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, indexed_vertex_array.quad_indices.data() + qverts_range.first);
+
+ ::glPopMatrix();
+}
+
+double GLVolume::layer_height_texture_z_to_row_id() const
+{
+ return (this->layer_height_texture.get() == nullptr) ? 0.0 : double(this->layer_height_texture->cells - 1) / (double(this->layer_height_texture->width) * this->layer_height_texture_data.print_object->model_object()->bounding_box().max(2));
+}
+
+void GLVolume::generate_layer_height_texture(const PrintObject *print_object, bool force)
+{
+ LayersTexture *tex = this->layer_height_texture.get();
+ if (tex == nullptr)
// No layer_height_texture is assigned to this GLVolume, therefore the layer height texture cannot be filled.
return;
// Always try to update the layer height profile.
- bool update = print_object->update_layer_height_profile(print_object->model_object()->layer_height_profile) || force;
+ bool update = print_object->update_layer_height_profile(const_cast<ModelObject*>(print_object->model_object())->layer_height_profile) || force;
// Update if the layer height profile was changed, or when the texture is not valid.
if (! update && ! tex->data.empty() && tex->cells > 0)
// Texture is valid, don't update.
@@ -376,15 +641,23 @@ std::vector<int> GLVolumeCollection::load_object(
};
// Object will have a single common layer height texture for all volumes.
- std::shared_ptr<GLTexture> layer_height_texture = std::make_shared<GLTexture>();
-
+ std::shared_ptr<LayersTexture> layer_height_texture = std::make_shared<LayersTexture>();
+
std::vector<int> volumes_idx;
for (int volume_idx = 0; volume_idx < int(model_object->volumes.size()); ++ volume_idx) {
const ModelVolume *model_volume = model_object->volumes[volume_idx];
+
+ int extruder_id = -1;
+ if (!model_volume->modifier)
+ {
+ extruder_id = model_volume->config.has("extruder") ? model_volume->config.option("extruder")->getInt() : 0;
+ if (extruder_id == 0)
+ extruder_id = model_object->config.has("extruder") ? model_object->config.option("extruder")->getInt() : 0;
+ }
+
for (int instance_idx : instance_idxs) {
const ModelInstance *instance = model_object->instances[instance_idx];
TriangleMesh mesh = model_volume->mesh;
- instance->transform_mesh(&mesh);
volumes_idx.push_back(int(this->volumes.size()));
float color[4];
memcpy(color, colors[((color_by == "volume") ? volume_idx : obj_idx) % 4], sizeof(float) * 3);
@@ -400,18 +673,20 @@ std::vector<int> GLVolumeCollection::load_object(
v.bounding_box = v.indexed_vertex_array.bounding_box();
v.indexed_vertex_array.finalize_geometry(use_VBOs);
v.composite_id = obj_idx * 1000000 + volume_idx * 1000 + instance_idx;
- if (select_by == "object")
- v.select_group_id = obj_idx * 1000000;
- else if (select_by == "volume")
- v.select_group_id = obj_idx * 1000000 + volume_idx * 1000;
- else if (select_by == "instance")
- v.select_group_id = v.composite_id;
- if (drag_by == "object")
- v.drag_group_id = obj_idx * 1000;
- else if (drag_by == "instance")
- v.drag_group_id = obj_idx * 1000 + instance_idx;
- if (! model_volume->modifier)
+ v.set_select_group_id(select_by);
+ v.set_drag_group_id(drag_by);
+ if (!model_volume->modifier)
+ {
+ v.set_convex_hull(model_volume->get_convex_hull());
v.layer_height_texture = layer_height_texture;
+ if (extruder_id != -1)
+ v.extruder_id = extruder_id;
+ }
+ v.is_modifier = model_volume->modifier;
+ v.shader_outside_printer_detection_enabled = !model_volume->modifier;
+ v.set_offset(Vec3d(instance->offset(0), instance->offset(1), 0.0));
+ v.set_rotation(instance->rotation);
+ v.set_scaling_factor(instance->scaling_factor);
}
}
@@ -420,24 +695,76 @@ std::vector<int> GLVolumeCollection::load_object(
int GLVolumeCollection::load_wipe_tower_preview(
- int obj_idx, float pos_x, float pos_y, float width, float depth, float height, bool use_VBOs)
+ int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width)
{
- float color[4] = { 1.0f, 1.0f, 0.0f, 0.5f };
+ if (depth < 0.01f)
+ return int(this->volumes.size() - 1);
+ if (height == 0.0f)
+ height = 0.1f;
+ Point origin_of_rotation(0.f, 0.f);
+ TriangleMesh mesh;
+ float color[4] = { 0.5f, 0.5f, 0.0f, 1.f };
+
+ // In case we don't know precise dimensions of the wipe tower yet, we'll draw the box with different color with one side jagged:
+ if (size_unknown) {
+ color[0] = 0.9f;
+ color[1] = 0.6f;
+
+ depth = std::max(depth, 10.f); // Too narrow tower would interfere with the teeth. The estimate is not precise anyway.
+ float min_width = 30.f;
+ // We'll now create the box with jagged edge. y-coordinates of the pre-generated model are shifted so that the front
+ // edge has y=0 and centerline of the back edge has y=depth:
+ Pointf3s points;
+ std::vector<Vec3crd> facets;
+ float out_points_idx[][3] = {{0, -depth, 0}, {0, 0, 0}, {38.453, 0, 0}, {61.547, 0, 0}, {100, 0, 0}, {100, -depth, 0}, {55.7735, -10, 0}, {44.2265, 10, 0},
+ {38.453, 0, 1}, {0, 0, 1}, {0, -depth, 1}, {100, -depth, 1}, {100, 0, 1}, {61.547, 0, 1}, {55.7735, -10, 1}, {44.2265, 10, 1}};
+ int out_facets_idx[][3] = {{0, 1, 2}, {3, 4, 5}, {6, 5, 0}, {3, 5, 6}, {6, 2, 7}, {6, 0, 2}, {8, 9, 10}, {11, 12, 13}, {10, 11, 14}, {14, 11, 13}, {15, 8, 14},
+ {8, 10, 14}, {3, 12, 4}, {3, 13, 12}, {6, 13, 3}, {6, 14, 13}, {7, 14, 6}, {7, 15, 14}, {2, 15, 7}, {2, 8, 15}, {1, 8, 2}, {1, 9, 8},
+ {0, 9, 1}, {0, 10, 9}, {5, 10, 0}, {5, 11, 10}, {4, 11, 5}, {4, 12, 11}};
+ for (int i=0;i<16;++i)
+ points.push_back(Vec3d(out_points_idx[i][0] / (100.f/min_width), out_points_idx[i][1] + depth, out_points_idx[i][2]));
+ for (int i=0;i<28;++i)
+ facets.push_back(Vec3crd(out_facets_idx[i][0], out_facets_idx[i][1], out_facets_idx[i][2]));
+ TriangleMesh tooth_mesh(points, facets);
+
+ // We have the mesh ready. It has one tooth and width of min_width. We will now append several of these together until we are close to
+ // the required width of the block. Than we can scale it precisely.
+ size_t n = std::max(1, int(width/min_width)); // How many shall be merged?
+ for (size_t i=0;i<n;++i) {
+ mesh.merge(tooth_mesh);
+ tooth_mesh.translate(min_width, 0.f, 0.f);
+ }
+
+ mesh.scale(Vec3d(width/(n*min_width), 1.f, height)); // Scaling to proper width
+ }
+ else
+ mesh = make_cube(width, depth, height);
+
+ // We'll make another mesh to show the brim (fixed layer height):
+ TriangleMesh brim_mesh = make_cube(width+2.f*brim_width, depth+2.f*brim_width, 0.2f);
+ brim_mesh.translate(-brim_width, -brim_width, 0.f);
+ mesh.merge(brim_mesh);
+
+ mesh.rotate(rotation_angle, &origin_of_rotation); // rotates the box according to the config rotation setting
+
this->volumes.emplace_back(new GLVolume(color));
GLVolume &v = *this->volumes.back();
- auto mesh = make_cube(width, depth, height);
+
if (use_VBOs)
v.indexed_vertex_array.load_mesh_full_shading(mesh);
else
v.indexed_vertex_array.load_mesh_flat_shading(mesh);
- v.origin = Pointf3(pos_x, pos_y, 0.);
+ v.set_offset(Vec3d(pos_x, pos_y, 0.0));
+
// finalize_geometry() clears the vertex arrays, therefore the bounding box has to be computed before finalize_geometry().
v.bounding_box = v.indexed_vertex_array.bounding_box();
v.indexed_vertex_array.finalize_geometry(use_VBOs);
v.composite_id = obj_idx * 1000000;
v.select_group_id = obj_idx * 1000000;
v.drag_group_id = obj_idx * 1000;
+ v.is_wipe_tower = true;
+ v.shader_outside_printer_detection_enabled = ! size_unknown;
return int(this->volumes.size() - 1);
}
@@ -455,102 +782,23 @@ void GLVolumeCollection::render_VBOs() const
GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1;
GLint print_box_min_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.min") : -1;
GLint print_box_max_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.max") : -1;
- GLint print_box_origin_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_origin") : -1;
+ GLint print_box_detection_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_detection") : -1;
+ GLint print_box_worldmatrix_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.volume_world_matrix") : -1;
- for (GLVolume *volume : this->volumes) {
- if (!volume->is_active)
- continue;
+ if (print_box_min_id != -1)
+ ::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min);
- if (!volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id)
- continue;
+ if (print_box_max_id != -1)
+ ::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max);
+ for (GLVolume *volume : this->volumes)
+ {
if (volume->layer_height_texture_data.can_use())
- {
- ::glDisableClientState(GL_VERTEX_ARRAY);
- ::glDisableClientState(GL_NORMAL_ARRAY);
volume->generate_layer_height_texture(volume->layer_height_texture_data.print_object, false);
- volume->render_using_layer_height();
- ::glEnableClientState(GL_VERTEX_ARRAY);
- ::glEnableClientState(GL_NORMAL_ARRAY);
- continue;
- }
-
- volume->set_render_color();
-
- GLsizei n_triangles = GLsizei(std::min(volume->indexed_vertex_array.triangle_indices_size, volume->tverts_range.second - volume->tverts_range.first));
- GLsizei n_quads = GLsizei(std::min(volume->indexed_vertex_array.quad_indices_size, volume->qverts_range.second - volume->qverts_range.first));
- if (n_triangles + n_quads == 0)
- {
- ::glDisableClientState(GL_VERTEX_ARRAY);
- ::glDisableClientState(GL_NORMAL_ARRAY);
-
- if (color_id >= 0)
- {
- float color[4];
- ::memcpy((void*)color, (const void*)volume->render_color, 4 * sizeof(float));
- ::glUniform4fv(color_id, 1, (const GLfloat*)color);
- }
- else
- ::glColor4f(volume->render_color[0], volume->render_color[1], volume->render_color[2], volume->render_color[3]);
-
- if (print_box_min_id != -1)
- ::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min);
-
- if (print_box_max_id != -1)
- ::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max);
-
- if (print_box_origin_id != -1)
- {
- float origin[4] = { (float)volume->origin.x, (float)volume->origin.y, (float)volume->origin.z, volume->outside_printer_detection_enabled ? 1.0f : 0.0f };
- ::glUniform4fv(print_box_origin_id, 1, (const GLfloat*)origin);
- }
-
- volume->render();
-
- ::glEnableClientState(GL_VERTEX_ARRAY);
- ::glEnableClientState(GL_NORMAL_ARRAY);
-
- continue;
- }
-
- if (color_id >= 0)
- ::glUniform4fv(color_id, 1, (const GLfloat*)volume->render_color);
else
- ::glColor4f(volume->render_color[0], volume->render_color[1], volume->render_color[2], volume->render_color[3]);
-
- if (print_box_min_id != -1)
- ::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min);
+ volume->set_render_color();
- if (print_box_max_id != -1)
- ::glUniform3fv(print_box_max_id, 1, (const GLfloat*)print_box_max);
-
- if (print_box_origin_id != -1)
- {
- float origin[4] = { (float)volume->origin.x, (float)volume->origin.y, (float)volume->origin.z, volume->outside_printer_detection_enabled ? 1.0f : 0.0f };
- ::glUniform4fv(print_box_origin_id, 1, (const GLfloat*)origin);
- }
-
- ::glBindBuffer(GL_ARRAY_BUFFER, volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id);
- ::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
- ::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr);
-
- bool has_offset = (volume->origin.x != 0) || (volume->origin.y != 0) || (volume->origin.z != 0);
- if (has_offset) {
- ::glPushMatrix();
- ::glTranslated(volume->origin.x, volume->origin.y, volume->origin.z);
- }
-
- if (n_triangles > 0) {
- ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.triangle_indices_VBO_id);
- ::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(volume->tverts_range.first * 4));
- }
- if (n_quads > 0) {
- ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.quad_indices_VBO_id);
- ::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(volume->qverts_range.first * 4));
- }
-
- if (has_offset)
- ::glPopMatrix();
+ volume->render_VBOs(color_id, print_box_detection_id, print_box_worldmatrix_id);
}
::glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -571,43 +819,10 @@ void GLVolumeCollection::render_legacy() const
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
- for (GLVolume *volume : this->volumes) {
- assert(! volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id);
- if (!volume->is_active)
- continue;
-
+ for (GLVolume *volume : this->volumes)
+ {
volume->set_render_color();
-
- GLsizei n_triangles = GLsizei(std::min(volume->indexed_vertex_array.triangle_indices_size, volume->tverts_range.second - volume->tverts_range.first));
- GLsizei n_quads = GLsizei(std::min(volume->indexed_vertex_array.quad_indices_size, volume->qverts_range.second - volume->qverts_range.first));
- if (n_triangles + n_quads == 0)
- {
- ::glDisableClientState(GL_VERTEX_ARRAY);
- ::glDisableClientState(GL_NORMAL_ARRAY);
-
- ::glColor4f(volume->render_color[0], volume->render_color[1], volume->render_color[2], volume->render_color[3]);
- volume->render();
-
- ::glEnableClientState(GL_VERTEX_ARRAY);
- ::glEnableClientState(GL_NORMAL_ARRAY);
-
- continue;
- }
-
- glColor4f(volume->render_color[0], volume->render_color[1], volume->render_color[2], volume->render_color[3]);
- glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), volume->indexed_vertex_array.vertices_and_normals_interleaved.data() + 3);
- glNormalPointer(GL_FLOAT, 6 * sizeof(float), volume->indexed_vertex_array.vertices_and_normals_interleaved.data());
- bool has_offset = volume->origin.x != 0 || volume->origin.y != 0 || volume->origin.z != 0;
- if (has_offset) {
- glPushMatrix();
- glTranslated(volume->origin.x, volume->origin.y, volume->origin.z);
- }
- if (n_triangles > 0)
- glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, volume->indexed_vertex_array.triangle_indices.data() + volume->tverts_range.first);
- if (n_quads > 0)
- glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, volume->indexed_vertex_array.quad_indices.data() + volume->qverts_range.first);
- if (has_offset)
- glPopMatrix();
+ volume->render_legacy();
}
glDisableClientState(GL_VERTEX_ARRAY);
@@ -616,41 +831,174 @@ void GLVolumeCollection::render_legacy() const
glDisable(GL_BLEND);
}
-void GLVolumeCollection::update_outside_state(const DynamicPrintConfig* config, bool all_inside)
+bool GLVolumeCollection::check_outside_state(const DynamicPrintConfig* config, ModelInstance::EPrintVolumeState* out_state)
{
if (config == nullptr)
- return;
+ return false;
const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(config->option("bed_shape"));
if (opt == nullptr)
- return;
+ return false;
BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
- BoundingBoxf3 print_volume(Pointf3(unscale(bed_box_2D.min.x), unscale(bed_box_2D.min.y), 0.0), Pointf3(unscale(bed_box_2D.max.x), unscale(bed_box_2D.max.y), config->opt_float("max_print_height")));
+ BoundingBoxf3 print_volume(Vec3d(unscale<double>(bed_box_2D.min(0)), unscale<double>(bed_box_2D.min(1)), 0.0), Vec3d(unscale<double>(bed_box_2D.max(0)), unscale<double>(bed_box_2D.max(1)), config->opt_float("max_print_height")));
+ // Allow the objects to protrude below the print bed
+ print_volume.min(2) = -1e10;
+
+ ModelInstance::EPrintVolumeState state = ModelInstance::PVS_Inside;
+ bool all_contained = true;
for (GLVolume* volume : this->volumes)
{
- if (all_inside)
+ if ((volume != nullptr) && !volume->is_modifier && (!volume->is_wipe_tower || (volume->is_wipe_tower && volume->shader_outside_printer_detection_enabled)))
{
+ const BoundingBoxf3& bb = volume->transformed_convex_hull_bounding_box();
+ bool contained = print_volume.contains(bb);
+ all_contained &= contained;
+
+ volume->is_outside = !contained;
+
+ if ((state == ModelInstance::PVS_Inside) && volume->is_outside)
+ state = ModelInstance::PVS_Fully_Outside;
+
+ if ((state == ModelInstance::PVS_Fully_Outside) && volume->is_outside && print_volume.intersects(bb))
+ state = ModelInstance::PVS_Partly_Outside;
+ }
+ }
+
+ if (out_state != nullptr)
+ *out_state = state;
+
+ return all_contained;
+}
+
+void GLVolumeCollection::reset_outside_state()
+{
+ for (GLVolume* volume : this->volumes)
+ {
+ if (volume != nullptr)
volume->is_outside = false;
- continue;
+ }
+}
+
+void GLVolumeCollection::update_colors_by_extruder(const DynamicPrintConfig* config)
+{
+ static const float inv_255 = 1.0f / 255.0f;
+
+ struct Color
+ {
+ std::string text;
+ unsigned char rgb[3];
+
+ Color()
+ : text("")
+ {
+ rgb[0] = 255;
+ rgb[1] = 255;
+ rgb[2] = 255;
+ }
+
+ void set(const std::string& text, unsigned char* rgb)
+ {
+ this->text = text;
+ ::memcpy((void*)this->rgb, (const void*)rgb, 3 * sizeof(unsigned char));
}
+ };
- volume->is_outside = !print_volume.contains(volume->transformed_bounding_box());
+ if (config == nullptr)
+ return;
+
+ const ConfigOptionStrings* extruders_opt = dynamic_cast<const ConfigOptionStrings*>(config->option("extruder_colour"));
+ if (extruders_opt == nullptr)
+ return;
+
+ const ConfigOptionStrings* filamemts_opt = dynamic_cast<const ConfigOptionStrings*>(config->option("filament_colour"));
+ if (filamemts_opt == nullptr)
+ return;
+
+ unsigned int colors_count = std::max((unsigned int)extruders_opt->values.size(), (unsigned int)filamemts_opt->values.size());
+ if (colors_count == 0)
+ return;
+
+ std::vector<Color> colors(colors_count);
+
+ unsigned char rgb[3];
+ for (unsigned int i = 0; i < colors_count; ++i)
+ {
+ const std::string& txt_color = config->opt_string("extruder_colour", i);
+ if (PresetBundle::parse_color(txt_color, rgb))
+ {
+ colors[i].set(txt_color, rgb);
+ }
+ else
+ {
+ const std::string& txt_color = config->opt_string("filament_colour", i);
+ if (PresetBundle::parse_color(txt_color, rgb))
+ colors[i].set(txt_color, rgb);
+ }
+ }
+
+ for (GLVolume* volume : volumes)
+ {
+ if ((volume == nullptr) || volume->is_modifier || volume->is_wipe_tower)
+ continue;
+
+ int extruder_id = volume->extruder_id - 1;
+ if ((extruder_id < 0) || ((unsigned int)colors.size() <= extruder_id))
+ extruder_id = 0;
+
+ const Color& color = colors[extruder_id];
+ if (!color.text.empty())
+ {
+ for (int i = 0; i < 3; ++i)
+ {
+ volume->color[i] = (float)color.rgb[i] * inv_255;
+ }
+ }
}
}
-std::vector<double> GLVolumeCollection::get_current_print_zs() const
+void GLVolumeCollection::set_select_by(const std::string& select_by)
{
- std::vector<double> print_zs;
+ for (GLVolume *vol : this->volumes)
+ {
+ if (vol != nullptr)
+ vol->set_select_group_id(select_by);
+ }
+}
+void GLVolumeCollection::set_drag_by(const std::string& drag_by)
+{
for (GLVolume *vol : this->volumes)
{
- for (coordf_t z : vol->print_zs)
- print_zs.emplace_back((double)round(z * 100000.0f) / 100000.0f);
+ if (vol != nullptr)
+ vol->set_drag_group_id(drag_by);
}
+}
- sort_remove_duplicates(print_zs);
+std::vector<double> GLVolumeCollection::get_current_print_zs(bool active_only) const
+{
+ // Collect layer top positions of all volumes.
+ std::vector<double> print_zs;
+ for (GLVolume *vol : this->volumes)
+ {
+ if (!active_only || vol->is_active)
+ append(print_zs, vol->print_zs);
+ }
+ std::sort(print_zs.begin(), print_zs.end());
+
+ // Replace intervals of layers with similar top positions with their average value.
+ int n = int(print_zs.size());
+ int k = 0;
+ for (int i = 0; i < n;) {
+ int j = i + 1;
+ coordf_t zmax = print_zs[i] + EPSILON;
+ for (; j < n && print_zs[j] <= zmax; ++ j) ;
+ print_zs[k ++] = (j > i + 1) ? (0.5 * (print_zs[i] + print_zs[j - 1])) : print_zs[i];
+ i = j;
+ }
+ if (k < n)
+ print_zs.erase(print_zs.begin() + k, print_zs.end());
return print_zs;
}
@@ -673,47 +1021,53 @@ static void thick_lines_to_indexed_vertex_array(
#define TOP 2
#define BOTTOM 3
- Line prev_line;
// right, left, top, bottom
int idx_prev[4] = { -1, -1, -1, -1 };
double bottom_z_prev = 0.;
- Pointf b1_prev;
- Pointf b2_prev;
- Vectorf v_prev;
+ Vec2d b1_prev(Vec2d::Zero());
+ Vec2d v_prev(Vec2d::Zero());
int idx_initial[4] = { -1, -1, -1, -1 };
double width_initial = 0.;
+ double bottom_z_initial = 0.0;
// loop once more in case of closed loops
size_t lines_end = closed ? (lines.size() + 1) : lines.size();
for (size_t ii = 0; ii < lines_end; ++ ii) {
size_t i = (ii == lines.size()) ? 0 : ii;
const Line &line = lines[i];
- double len = unscale(line.length());
+ double len = unscale<double>(line.length());
+ double inv_len = 1.0 / len;
double bottom_z = top_z - heights[i];
- double middle_z = (top_z + bottom_z) / 2.;
+ double middle_z = 0.5 * (top_z + bottom_z);
double width = widths[i];
-
- Vectorf v = Vectorf::new_unscale(line.vector());
- v.scale(1. / len);
-
- Pointf a = Pointf::new_unscale(line.a);
- Pointf b = Pointf::new_unscale(line.b);
- Pointf a1 = a;
- Pointf a2 = a;
- Pointf b1 = b;
- Pointf b2 = b;
+
+ bool is_first = (ii == 0);
+ bool is_last = (ii == lines_end - 1);
+ bool is_closing = closed && is_last;
+
+ Vec2d v = unscale(line.vector());
+ v *= inv_len;
+
+ Vec2d a = unscale(line.a);
+ Vec2d b = unscale(line.b);
+ Vec2d a1 = a;
+ Vec2d a2 = a;
+ Vec2d b1 = b;
+ Vec2d b2 = b;
{
- double dist = width / 2.; // scaled
- a1.translate(+dist*v.y, -dist*v.x);
- a2.translate(-dist*v.y, +dist*v.x);
- b1.translate(+dist*v.y, -dist*v.x);
- b2.translate(-dist*v.y, +dist*v.x);
+ double dist = 0.5 * width; // scaled
+ double dx = dist * v(0);
+ double dy = dist * v(1);
+ a1 += Vec2d(+dy, -dx);
+ a2 += Vec2d(-dy, +dx);
+ b1 += Vec2d(+dy, -dx);
+ b2 += Vec2d(-dy, +dx);
}
// calculate new XY normals
Vector n = line.normal();
- Vectorf3 xy_right_normal = Vectorf3::new_unscale(n.x, n.y, 0);
- xy_right_normal.scale(1.f / len);
+ Vec3d xy_right_normal = unscale(n(0), n(1), 0);
+ xy_right_normal *= inv_len;
int idx_a[4];
int idx_b[4];
@@ -722,72 +1076,92 @@ static void thick_lines_to_indexed_vertex_array(
bool bottom_z_different = bottom_z_prev != bottom_z;
bottom_z_prev = bottom_z;
+ if (!is_first && bottom_z_different)
+ {
+ // Found a change of the layer thickness -> Add a cap at the end of the previous segment.
+ volume.push_quad(idx_b[BOTTOM], idx_b[LEFT], idx_b[TOP], idx_b[RIGHT]);
+ }
+
// Share top / bottom vertices if possible.
- if (ii == 0) {
- idx_a[TOP] = idx_last ++;
- volume.push_geometry(a.x, a.y, top_z , 0., 0., 1.);
+ if (is_first) {
+ idx_a[TOP] = idx_last++;
+ volume.push_geometry(a(0), a(1), top_z , 0., 0., 1.);
} else {
idx_a[TOP] = idx_prev[TOP];
}
- if (ii == 0 || bottom_z_different) {
+
+ if (is_first || bottom_z_different) {
// Start of the 1st line segment or a change of the layer thickness while maintaining the print_z.
idx_a[BOTTOM] = idx_last ++;
- volume.push_geometry(a.x, a.y, bottom_z, 0., 0., -1.);
+ volume.push_geometry(a(0), a(1), bottom_z, 0., 0., -1.);
idx_a[LEFT ] = idx_last ++;
- volume.push_geometry(a2.x, a2.y, middle_z, -xy_right_normal.x, -xy_right_normal.y, -xy_right_normal.z);
+ volume.push_geometry(a2(0), a2(1), middle_z, -xy_right_normal(0), -xy_right_normal(1), -xy_right_normal(2));
idx_a[RIGHT] = idx_last ++;
- volume.push_geometry(a1.x, a1.y, middle_z, xy_right_normal.x, xy_right_normal.y, xy_right_normal.z);
- } else {
+ volume.push_geometry(a1(0), a1(1), middle_z, xy_right_normal(0), xy_right_normal(1), xy_right_normal(2));
+ }
+ else {
idx_a[BOTTOM] = idx_prev[BOTTOM];
}
- if (ii == 0) {
+ if (is_first) {
// Start of the 1st line segment.
width_initial = width;
+ bottom_z_initial = bottom_z;
memcpy(idx_initial, idx_a, sizeof(int) * 4);
} else {
// Continuing a previous segment.
// Share left / right vertices if possible.
- double v_dot = dot(v_prev, v);
+ double v_dot = v_prev.dot(v);
bool sharp = v_dot < 0.707; // sin(45 degrees)
if (sharp) {
- // Allocate new left / right points for the start of this segment as these points will receive their own normals to indicate a sharp turn.
- idx_a[RIGHT] = idx_last ++;
- volume.push_geometry(a1.x, a1.y, middle_z, xy_right_normal.x, xy_right_normal.y, xy_right_normal.z);
- idx_a[LEFT ] = idx_last ++;
- volume.push_geometry(a2.x, a2.y, middle_z, -xy_right_normal.x, -xy_right_normal.y, -xy_right_normal.z);
+ if (!bottom_z_different)
+ {
+ // Allocate new left / right points for the start of this segment as these points will receive their own normals to indicate a sharp turn.
+ idx_a[RIGHT] = idx_last++;
+ volume.push_geometry(a1(0), a1(1), middle_z, xy_right_normal(0), xy_right_normal(1), xy_right_normal(2));
+ idx_a[LEFT] = idx_last++;
+ volume.push_geometry(a2(0), a2(1), middle_z, -xy_right_normal(0), -xy_right_normal(1), -xy_right_normal(2));
+ }
}
if (v_dot > 0.9) {
- // The two successive segments are nearly collinear.
- idx_a[LEFT ] = idx_prev[LEFT];
- idx_a[RIGHT] = idx_prev[RIGHT];
- } else if (! sharp) {
- // Create a sharp corner with an overshot and average the left / right normals.
- // At the crease angle of 45 degrees, the overshot at the corner will be less than (1-1/cos(PI/8)) = 8.2% over an arc.
- Pointf intersection;
- Geometry::ray_ray_intersection(b1_prev, v_prev, a1, v, intersection);
- a1 = intersection;
- a2 = 2. * a - intersection;
- assert(length(a1.vector_to(a)) < width);
- assert(length(a2.vector_to(a)) < width);
- float *n_left_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[LEFT ] * 6;
- float *p_left_prev = n_left_prev + 3;
- float *n_right_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[RIGHT] * 6;
- float *p_right_prev = n_right_prev + 3;
- p_left_prev [0] = float(a2.x);
- p_left_prev [1] = float(a2.y);
- p_right_prev[0] = float(a1.x);
- p_right_prev[1] = float(a1.y);
- xy_right_normal.x += n_right_prev[0];
- xy_right_normal.y += n_right_prev[1];
- xy_right_normal.scale(1. / length(xy_right_normal));
- n_left_prev [0] = float(-xy_right_normal.x);
- n_left_prev [1] = float(-xy_right_normal.y);
- n_right_prev[0] = float( xy_right_normal.x);
- n_right_prev[1] = float( xy_right_normal.y);
- idx_a[LEFT ] = idx_prev[LEFT ];
- idx_a[RIGHT] = idx_prev[RIGHT];
- } else if (cross(v_prev, v) > 0.) {
+ if (!bottom_z_different)
+ {
+ // The two successive segments are nearly collinear.
+ idx_a[LEFT ] = idx_prev[LEFT];
+ idx_a[RIGHT] = idx_prev[RIGHT];
+ }
+ }
+ else if (!sharp) {
+ if (!bottom_z_different)
+ {
+ // Create a sharp corner with an overshot and average the left / right normals.
+ // At the crease angle of 45 degrees, the overshot at the corner will be less than (1-1/cos(PI/8)) = 8.2% over an arc.
+ Vec2d intersection(Vec2d::Zero());
+ Geometry::ray_ray_intersection(b1_prev, v_prev, a1, v, intersection);
+ a1 = intersection;
+ a2 = 2. * a - intersection;
+ assert((a - a1).norm() < width);
+ assert((a - a2).norm() < width);
+ float *n_left_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[LEFT ] * 6;
+ float *p_left_prev = n_left_prev + 3;
+ float *n_right_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[RIGHT] * 6;
+ float *p_right_prev = n_right_prev + 3;
+ p_left_prev [0] = float(a2(0));
+ p_left_prev [1] = float(a2(1));
+ p_right_prev[0] = float(a1(0));
+ p_right_prev[1] = float(a1(1));
+ xy_right_normal(0) += n_right_prev[0];
+ xy_right_normal(1) += n_right_prev[1];
+ xy_right_normal *= 1. / xy_right_normal.norm();
+ n_left_prev [0] = float(-xy_right_normal(0));
+ n_left_prev [1] = float(-xy_right_normal(1));
+ n_right_prev[0] = float( xy_right_normal(0));
+ n_right_prev[1] = float( xy_right_normal(1));
+ idx_a[LEFT ] = idx_prev[LEFT ];
+ idx_a[RIGHT] = idx_prev[RIGHT];
+ }
+ }
+ else if (cross2(v_prev, v) > 0.) {
// Right turn. Fill in the right turn wedge.
volume.push_triangle(idx_prev[RIGHT], idx_a [RIGHT], idx_prev[TOP] );
volume.push_triangle(idx_prev[RIGHT], idx_prev[BOTTOM], idx_a [RIGHT] );
@@ -796,18 +1170,21 @@ static void thick_lines_to_indexed_vertex_array(
volume.push_triangle(idx_prev[LEFT], idx_prev[TOP], idx_a [LEFT] );
volume.push_triangle(idx_prev[LEFT], idx_a [LEFT], idx_prev[BOTTOM]);
}
- if (ii == lines.size()) {
- if (! sharp) {
- // Closing a loop with smooth transition. Unify the closing left / right vertices.
- memcpy(volume.vertices_and_normals_interleaved.data() + idx_initial[LEFT ] * 6, volume.vertices_and_normals_interleaved.data() + idx_prev[LEFT ] * 6, sizeof(float) * 6);
- memcpy(volume.vertices_and_normals_interleaved.data() + idx_initial[RIGHT] * 6, volume.vertices_and_normals_interleaved.data() + idx_prev[RIGHT] * 6, sizeof(float) * 6);
- volume.vertices_and_normals_interleaved.erase(volume.vertices_and_normals_interleaved.end() - 12, volume.vertices_and_normals_interleaved.end());
- // Replace the left / right vertex indices to point to the start of the loop.
- for (size_t u = volume.quad_indices.size() - 16; u < volume.quad_indices.size(); ++ u) {
- if (volume.quad_indices[u] == idx_prev[LEFT])
- volume.quad_indices[u] = idx_initial[LEFT];
- else if (volume.quad_indices[u] == idx_prev[RIGHT])
- volume.quad_indices[u] = idx_initial[RIGHT];
+ if (is_closing) {
+ if (!sharp) {
+ if (!bottom_z_different)
+ {
+ // Closing a loop with smooth transition. Unify the closing left / right vertices.
+ memcpy(volume.vertices_and_normals_interleaved.data() + idx_initial[LEFT ] * 6, volume.vertices_and_normals_interleaved.data() + idx_prev[LEFT ] * 6, sizeof(float) * 6);
+ memcpy(volume.vertices_and_normals_interleaved.data() + idx_initial[RIGHT] * 6, volume.vertices_and_normals_interleaved.data() + idx_prev[RIGHT] * 6, sizeof(float) * 6);
+ volume.vertices_and_normals_interleaved.erase(volume.vertices_and_normals_interleaved.end() - 12, volume.vertices_and_normals_interleaved.end());
+ // Replace the left / right vertex indices to point to the start of the loop.
+ for (size_t u = volume.quad_indices.size() - 16; u < volume.quad_indices.size(); ++ u) {
+ if (volume.quad_indices[u] == idx_prev[LEFT])
+ volume.quad_indices[u] = idx_initial[LEFT];
+ else if (volume.quad_indices[u] == idx_prev[RIGHT])
+ volume.quad_indices[u] = idx_initial[RIGHT];
+ }
}
}
// This is the last iteration, only required to solve the transition.
@@ -816,40 +1193,45 @@ static void thick_lines_to_indexed_vertex_array(
}
// Only new allocate top / bottom vertices, if not closing a loop.
- if (closed && ii + 1 == lines.size()) {
+ if (is_closing) {
idx_b[TOP] = idx_initial[TOP];
} else {
idx_b[TOP] = idx_last ++;
- volume.push_geometry(b.x, b.y, top_z , 0., 0., 1.);
+ volume.push_geometry(b(0), b(1), top_z , 0., 0., 1.);
}
- if (closed && ii + 1 == lines.size() && width == width_initial) {
+
+ if (is_closing && (width == width_initial) && (bottom_z == bottom_z_initial)) {
idx_b[BOTTOM] = idx_initial[BOTTOM];
} else {
idx_b[BOTTOM] = idx_last ++;
- volume.push_geometry(b.x, b.y, bottom_z, 0., 0., -1.);
+ volume.push_geometry(b(0), b(1), bottom_z, 0., 0., -1.);
}
// Generate new vertices for the end of this line segment.
idx_b[LEFT ] = idx_last ++;
- volume.push_geometry(b2.x, b2.y, middle_z, -xy_right_normal.x, -xy_right_normal.y, -xy_right_normal.z);
+ volume.push_geometry(b2(0), b2(1), middle_z, -xy_right_normal(0), -xy_right_normal(1), -xy_right_normal(2));
idx_b[RIGHT ] = idx_last ++;
- volume.push_geometry(b1.x, b1.y, middle_z, xy_right_normal.x, xy_right_normal.y, xy_right_normal.z);
+ volume.push_geometry(b1(0), b1(1), middle_z, xy_right_normal(0), xy_right_normal(1), xy_right_normal(2));
- prev_line = line;
memcpy(idx_prev, idx_b, 4 * sizeof(int));
bottom_z_prev = bottom_z;
b1_prev = b1;
- b2_prev = b2;
- v_prev = v;
+ v_prev = v;
+
+ if (bottom_z_different && (closed || (!is_first && !is_last)))
+ {
+ // Found a change of the layer thickness -> Add a cap at the beginning of this segment.
+ volume.push_quad(idx_a[BOTTOM], idx_a[RIGHT], idx_a[TOP], idx_a[LEFT]);
+ }
if (! closed) {
// Terminate open paths with caps.
- if (i == 0)
+ if (is_first)
volume.push_quad(idx_a[BOTTOM], idx_a[RIGHT], idx_a[TOP], idx_a[LEFT]);
// We don't use 'else' because both cases are true if we have only one line.
- if (i + 1 == lines.size())
+ if (is_last)
volume.push_quad(idx_b[BOTTOM], idx_b[LEFT], idx_b[TOP], idx_b[RIGHT]);
}
-
+
// Add quads for a straight hollow tube-like segment.
// bottom-right face
volume.push_quad(idx_a[BOTTOM], idx_b[BOTTOM], idx_b[RIGHT], idx_a[RIGHT]);
@@ -887,15 +1269,15 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
int idx_initial[4] = { -1, -1, -1, -1 };
int idx_prev[4] = { -1, -1, -1, -1 };
double z_prev = 0.0;
- Vectorf3 n_right_prev;
- Vectorf3 n_top_prev;
- Vectorf3 unit_v_prev;
+ Vec3d n_right_prev = Vec3d::Zero();
+ Vec3d n_top_prev = Vec3d::Zero();
+ Vec3d unit_v_prev = Vec3d::Zero();
double width_initial = 0.0;
// new vertices around the line endpoints
// left, right, top, bottom
- Pointf3 a[4];
- Pointf3 b[4];
+ Vec3d a[4] = { Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero() };
+ Vec3d b[4] = { Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero(), Vec3d::Zero() };
// loop once more in case of closed loops
size_t lines_end = closed ? (lines.size() + 1) : lines.size();
@@ -907,29 +1289,29 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
double height = heights[i];
double width = widths[i];
- Vectorf3 unit_v = normalize(Vectorf3::new_unscale(line.vector()));
+ Vec3d unit_v = unscale(line.vector()).normalized();
- Vectorf3 n_top;
- Vectorf3 n_right;
- Vectorf3 unit_positive_z(0.0, 0.0, 1.0);
+ Vec3d n_top = Vec3d::Zero();
+ Vec3d n_right = Vec3d::Zero();
+ Vec3d unit_positive_z(0.0, 0.0, 1.0);
- if ((line.a.x == line.b.x) && (line.a.y == line.b.y))
+ if ((line.a(0) == line.b(0)) && (line.a(1) == line.b(1)))
{
// vertical segment
- n_right = (line.a.z < line.b.z) ? Vectorf3(-1.0, 0.0, 0.0) : Vectorf3(1.0, 0.0, 0.0);
- n_top = Vectorf3(0.0, 1.0, 0.0);
+ n_right = (line.a(2) < line.b(2)) ? Vec3d(-1.0, 0.0, 0.0) : Vec3d(1.0, 0.0, 0.0);
+ n_top = Vec3d(0.0, 1.0, 0.0);
}
else
{
// generic segment
- n_right = normalize(cross(unit_v, unit_positive_z));
- n_top = normalize(cross(n_right, unit_v));
+ n_right = unit_v.cross(unit_positive_z).normalized();
+ n_top = n_right.cross(unit_v).normalized();
}
- Vectorf3 rl_displacement = 0.5 * width * n_right;
- Vectorf3 tb_displacement = 0.5 * height * n_top;
- Pointf3 l_a = Pointf3::new_unscale(line.a);
- Pointf3 l_b = Pointf3::new_unscale(line.b);
+ Vec3d rl_displacement = 0.5 * width * n_right;
+ Vec3d tb_displacement = 0.5 * height * n_top;
+ Vec3d l_a = unscale(line.a);
+ Vec3d l_b = unscale(line.b);
a[RIGHT] = l_a + rl_displacement;
a[LEFT] = l_a - rl_displacement;
@@ -940,15 +1322,15 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
b[TOP] = l_b + tb_displacement;
b[BOTTOM] = l_b - tb_displacement;
- Vectorf3 n_bottom = -n_top;
- Vectorf3 n_left = -n_right;
+ Vec3d n_bottom = -n_top;
+ Vec3d n_left = -n_right;
int idx_a[4];
int idx_b[4];
int idx_last = int(volume.vertices_and_normals_interleaved.size() / 6);
- bool z_different = (z_prev != l_a.z);
- z_prev = l_b.z;
+ bool z_different = (z_prev != l_a(2));
+ z_prev = l_b(2);
// Share top / bottom vertices if possible.
if (ii == 0)
@@ -982,9 +1364,9 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
{
// Continuing a previous segment.
// Share left / right vertices if possible.
- double v_dot = dot(unit_v_prev, unit_v);
+ double v_dot = unit_v_prev.dot(unit_v);
bool is_sharp = v_dot < 0.707; // sin(45 degrees)
- bool is_right_turn = dot(n_top_prev, cross(unit_v_prev, unit_v)) > 0.0;
+ bool is_right_turn = n_top_prev.dot(unit_v_prev.cross(unit_v)) > 0.0;
if (is_sharp)
{
@@ -1007,9 +1389,9 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
// At the crease angle of 45 degrees, the overshot at the corner will be less than (1-1/cos(PI/8)) = 8.2% over an arc.
// averages normals
- Vectorf3 average_n_right = normalize(0.5 * (n_right + n_right_prev));
- Vectorf3 average_n_left = -average_n_right;
- Vectorf3 average_rl_displacement = 0.5 * width * average_n_right;
+ Vec3d average_n_right = 0.5 * (n_right + n_right_prev).normalized();
+ Vec3d average_n_left = -average_n_right;
+ Vec3d average_rl_displacement = 0.5 * width * average_n_right;
// updates vertices around a
a[RIGHT] = l_a + average_rl_displacement;
@@ -1017,25 +1399,25 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
// updates previous line normals
float* normal_left_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[LEFT] * 6;
- normal_left_prev[0] = float(average_n_left.x);
- normal_left_prev[1] = float(average_n_left.y);
- normal_left_prev[2] = float(average_n_left.z);
+ normal_left_prev[0] = float(average_n_left(0));
+ normal_left_prev[1] = float(average_n_left(1));
+ normal_left_prev[2] = float(average_n_left(2));
float* normal_right_prev = volume.vertices_and_normals_interleaved.data() + idx_prev[RIGHT] * 6;
- normal_right_prev[0] = float(average_n_right.x);
- normal_right_prev[1] = float(average_n_right.y);
- normal_right_prev[2] = float(average_n_right.z);
+ normal_right_prev[0] = float(average_n_right(0));
+ normal_right_prev[1] = float(average_n_right(1));
+ normal_right_prev[2] = float(average_n_right(2));
// updates previous line's vertices around b
float* b_left_prev = normal_left_prev + 3;
- b_left_prev[0] = float(a[LEFT].x);
- b_left_prev[1] = float(a[LEFT].y);
- b_left_prev[2] = float(a[LEFT].z);
+ b_left_prev[0] = float(a[LEFT](0));
+ b_left_prev[1] = float(a[LEFT](1));
+ b_left_prev[2] = float(a[LEFT](2));
float* b_right_prev = normal_right_prev + 3;
- b_right_prev[0] = float(a[RIGHT].x);
- b_right_prev[1] = float(a[RIGHT].y);
- b_right_prev[2] = float(a[RIGHT].z);
+ b_right_prev[0] = float(a[RIGHT](0));
+ b_right_prev[1] = float(a[RIGHT](1));
+ b_right_prev[2] = float(a[RIGHT](2));
idx_a[LEFT] = idx_prev[LEFT];
idx_a[RIGHT] = idx_prev[RIGHT];
@@ -1132,14 +1514,14 @@ static void thick_lines_to_indexed_vertex_array(const Lines3& lines,
#undef BOTTOM
}
-static void point_to_indexed_vertex_array(const Point3& point,
+static void point_to_indexed_vertex_array(const Vec3crd& point,
double width,
double height,
GLIndexedVertexArray& volume)
{
// builds a double piramid, with vertices on the local axes, around the point
- Pointf3 center = Pointf3::new_unscale(point);
+ Vec3d center = unscale(point);
double scale_factor = 1.0;
double w = scale_factor * width;
@@ -1153,13 +1535,13 @@ static void point_to_indexed_vertex_array(const Point3& point,
idxs[i] = idx_last + i;
}
- Vectorf3 displacement_x(w, 0.0, 0.0);
- Vectorf3 displacement_y(0.0, w, 0.0);
- Vectorf3 displacement_z(0.0, 0.0, h);
+ Vec3d displacement_x(w, 0.0, 0.0);
+ Vec3d displacement_y(0.0, w, 0.0);
+ Vec3d displacement_z(0.0, 0.0, h);
- Vectorf3 unit_x(1.0, 0.0, 0.0);
- Vectorf3 unit_y(0.0, 1.0, 0.0);
- Vectorf3 unit_z(0.0, 0.0, 1.0);
+ Vec3d unit_x(1.0, 0.0, 0.0);
+ Vec3d unit_y(0.0, 1.0, 0.0);
+ Vec3d unit_z(0.0, 0.0, 1.0);
// vertices
volume.push_geometry(center - displacement_x, -unit_x); // idxs[0]
@@ -1182,8 +1564,8 @@ static void point_to_indexed_vertex_array(const Point3& point,
volume.push_triangle(idxs[0], idxs[3], idxs[4]);
}
-static void thick_lines_to_verts(
- const Lines &lines,
+void _3DScene::thick_lines_to_verts(
+ const Lines &lines,
const std::vector<double> &widths,
const std::vector<double> &heights,
bool closed,
@@ -1193,7 +1575,7 @@ static void thick_lines_to_verts(
thick_lines_to_indexed_vertex_array(lines, widths, heights, closed, top_z, volume.indexed_vertex_array);
}
-static void thick_lines_to_verts(const Lines3& lines,
+void _3DScene::thick_lines_to_verts(const Lines3& lines,
const std::vector<double>& widths,
const std::vector<double>& heights,
bool closed,
@@ -1202,7 +1584,7 @@ static void thick_lines_to_verts(const Lines3& lines,
thick_lines_to_indexed_vertex_array(lines, widths, heights, closed, volume.indexed_vertex_array);
}
-static void thick_point_to_verts(const Point3& point,
+static void thick_point_to_verts(const Vec3crd& point,
double width,
double height,
GLVolume& volume)
@@ -1211,7 +1593,7 @@ static void thick_point_to_verts(const Point3& point,
}
// Fill in the qverts and tverts with quads and triangles for the extrusion_path.
-static inline void extrusionentity_to_verts(const ExtrusionPath &extrusion_path, float print_z, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionPath &extrusion_path, float print_z, GLVolume &volume)
{
Lines lines = extrusion_path.polyline.lines();
std::vector<double> widths(lines.size(), extrusion_path.width);
@@ -1220,7 +1602,7 @@ static inline void extrusionentity_to_verts(const ExtrusionPath &extrusion_path,
}
// Fill in the qverts and tverts with quads and triangles for the extrusion_path.
-static inline void extrusionentity_to_verts(const ExtrusionPath &extrusion_path, float print_z, const Point &copy, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionPath &extrusion_path, float print_z, const Point &copy, GLVolume &volume)
{
Polyline polyline = extrusion_path.polyline;
polyline.remove_duplicate_points();
@@ -1232,7 +1614,7 @@ static inline void extrusionentity_to_verts(const ExtrusionPath &extrusion_path,
}
// Fill in the qverts and tverts with quads and triangles for the extrusion_loop.
-static inline void extrusionentity_to_verts(const ExtrusionLoop &extrusion_loop, float print_z, const Point &copy, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionLoop &extrusion_loop, float print_z, const Point &copy, GLVolume &volume)
{
Lines lines;
std::vector<double> widths;
@@ -1250,7 +1632,7 @@ static inline void extrusionentity_to_verts(const ExtrusionLoop &extrusion_loop,
}
// Fill in the qverts and tverts with quads and triangles for the extrusion_multi_path.
-static inline void extrusionentity_to_verts(const ExtrusionMultiPath &extrusion_multi_path, float print_z, const Point &copy, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionMultiPath &extrusion_multi_path, float print_z, const Point &copy, GLVolume &volume)
{
Lines lines;
std::vector<double> widths;
@@ -1267,15 +1649,13 @@ static inline void extrusionentity_to_verts(const ExtrusionMultiPath &extrusion_
thick_lines_to_verts(lines, widths, heights, false, print_z, volume);
}
-static void extrusionentity_to_verts(const ExtrusionEntity *extrusion_entity, float print_z, const Point &copy, GLVolume &volume);
-
-static inline void extrusionentity_to_verts(const ExtrusionEntityCollection &extrusion_entity_collection, float print_z, const Point &copy, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionEntityCollection &extrusion_entity_collection, float print_z, const Point &copy, GLVolume &volume)
{
for (const ExtrusionEntity *extrusion_entity : extrusion_entity_collection.entities)
extrusionentity_to_verts(extrusion_entity, print_z, copy, volume);
}
-static void extrusionentity_to_verts(const ExtrusionEntity *extrusion_entity, float print_z, const Point &copy, GLVolume &volume)
+void _3DScene::extrusionentity_to_verts(const ExtrusionEntity *extrusion_entity, float print_z, const Point &copy, GLVolume &volume)
{
if (extrusion_entity != nullptr) {
auto *extrusion_path = dynamic_cast<const ExtrusionPath*>(extrusion_entity);
@@ -1302,7 +1682,7 @@ static void extrusionentity_to_verts(const ExtrusionEntity *extrusion_entity, fl
}
}
-static void polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume)
+void _3DScene::polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume)
{
Lines3 lines = polyline.lines();
std::vector<double> widths(lines.size(), width);
@@ -1310,1280 +1690,498 @@ static void polyline3_to_verts(const Polyline3& polyline, double width, double h
thick_lines_to_verts(lines, widths, heights, false, volume);
}
-static void point3_to_verts(const Point3& point, double width, double height, GLVolume& volume)
+void _3DScene::point3_to_verts(const Vec3crd& point, double width, double height, GLVolume& volume)
{
thick_point_to_verts(point, width, height, volume);
}
-_3DScene::GCodePreviewVolumeIndex _3DScene::s_gcode_preview_volume_index;
-_3DScene::LegendTexture _3DScene::s_legend_texture;
-_3DScene::WarningTexture _3DScene::s_warning_texture;
+GUI::GLCanvas3DManager _3DScene::s_canvas_mgr;
-unsigned int _3DScene::TextureBase::finalize()
+void _3DScene::init_gl()
{
- if (!m_data.empty()) {
- // sends buffer to gpu
- ::glGenTextures(1, &m_tex_id);
- ::glBindTexture(GL_TEXTURE_2D, m_tex_id);
- ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_tex_width, (GLsizei)m_tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)m_data.data());
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
- ::glBindTexture(GL_TEXTURE_2D, 0);
- m_data.clear();
- }
- return (m_tex_width > 0 && m_tex_height > 0) ? m_tex_id : 0;
+ s_canvas_mgr.init_gl();
}
-void _3DScene::TextureBase::_destroy_texture()
+std::string _3DScene::get_gl_info(bool format_as_html, bool extensions)
{
- if (m_tex_id > 0)
- {
- ::glDeleteTextures(1, &m_tex_id);
- m_tex_id = 0;
- m_tex_height = 0;
- m_tex_width = 0;
- }
- m_data.clear();
+ return s_canvas_mgr.get_gl_info(format_as_html, extensions);
}
-
-const unsigned char _3DScene::WarningTexture::Background_Color[3] = { 9, 91, 134 };
-const unsigned char _3DScene::WarningTexture::Opacity = 255;
-
-// Generate a texture data, but don't load it into the GPU yet, as the GPU context may not yet be valid.
-bool _3DScene::WarningTexture::generate(const std::string& msg)
+bool _3DScene::use_VBOs()
{
- // Mark the texture as released, but don't release the texture from the GPU yet.
- m_tex_width = m_tex_height = 0;
- m_data.clear();
-
- if (msg.empty())
- return false;
-
- wxMemoryDC memDC;
- // select default font
- memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
-
- // calculates texture size
- wxCoord w, h;
- memDC.GetTextExtent(msg, &w, &h);
- m_tex_width = (unsigned int)w;
- m_tex_height = (unsigned int)h;
-
- // generates bitmap
- wxBitmap bitmap(m_tex_width, m_tex_height);
-
-#if defined(__APPLE__) || defined(_MSC_VER)
- bitmap.UseAlpha();
-#endif
-
- memDC.SelectObject(bitmap);
- memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2])));
- memDC.Clear();
-
- memDC.SetTextForeground(*wxWHITE);
-
- // draw message
- memDC.DrawText(msg, 0, 0);
-
- memDC.SelectObject(wxNullBitmap);
-
- // Convert the bitmap into a linear data ready to be loaded into the GPU.
- {
- wxImage image = bitmap.ConvertToImage();
- image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]);
-
- // prepare buffer
- m_data.assign(4 * m_tex_width * m_tex_height, 0);
- for (unsigned int h = 0; h < m_tex_height; ++h)
- {
- unsigned int hh = h * m_tex_width;
- unsigned char* px_ptr = m_data.data() + 4 * hh;
- for (unsigned int w = 0; w < m_tex_width; ++w)
- {
- *px_ptr++ = image.GetRed(w, h);
- *px_ptr++ = image.GetGreen(w, h);
- *px_ptr++ = image.GetBlue(w, h);
- *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity;
- }
- }
- }
- return true;
+ return s_canvas_mgr.use_VBOs();
}
-const unsigned char _3DScene::LegendTexture::Squares_Border_Color[3] = { 64, 64, 64 };
-const unsigned char _3DScene::LegendTexture::Background_Color[3] = { 9, 91, 134 };
-const unsigned char _3DScene::LegendTexture::Opacity = 255;
-
-// Generate a texture data, but don't load it into the GPU yet, as the GPU context may not yet be valid.
-bool _3DScene::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
+bool _3DScene::add_canvas(wxGLCanvas* canvas)
{
- // Mark the texture as released, but don't release the texture from the GPU yet.
- m_tex_width = m_tex_height = 0;
- m_data.clear();
-
- // collects items to render
- auto title = GUI::L_str(preview_data.get_legend_title());
- const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors);
-
- unsigned int items_count = (unsigned int)items.size();
- if (items_count == 0)
- // nothing to render, return
- return false;
-
- wxMemoryDC memDC;
- // select default font
- memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
-
- // calculates texture size
- wxCoord w, h;
- memDC.GetTextExtent(title, &w, &h);
- unsigned int title_width = (unsigned int)w;
- unsigned int title_height = (unsigned int)h;
-
- unsigned int max_text_width = 0;
- unsigned int max_text_height = 0;
- for (const GCodePreviewData::LegendItem& item : items)
- {
- memDC.GetTextExtent(GUI::from_u8(item.text), &w, &h);
- max_text_width = std::max(max_text_width, (unsigned int)w);
- max_text_height = std::max(max_text_height, (unsigned int)h);
- }
-
- m_tex_width = std::max(2 * Px_Border + title_width, 2 * (Px_Border + Px_Square_Contour) + Px_Square + Px_Text_Offset + max_text_width);
- m_tex_height = 2 * (Px_Border + Px_Square_Contour) + title_height + Px_Title_Offset + items_count * Px_Square;
- if (items_count > 1)
- m_tex_height += (items_count - 1) * Px_Square_Contour;
-
- // generates bitmap
- wxBitmap bitmap(m_tex_width, m_tex_height);
-
-#if defined(__APPLE__) || defined(_MSC_VER)
- bitmap.UseAlpha();
-#endif
-
- memDC.SelectObject(bitmap);
- memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2])));
- memDC.Clear();
-
- memDC.SetTextForeground(*wxWHITE);
-
- // draw title
- unsigned int title_x = Px_Border;
- unsigned int title_y = Px_Border;
- memDC.DrawText(title, title_x, title_y);
-
- // draw icons contours as background
- unsigned int squares_contour_x = Px_Border;
- unsigned int squares_contour_y = Px_Border + title_height + Px_Title_Offset;
- unsigned int squares_contour_width = Px_Square + 2 * Px_Square_Contour;
- unsigned int squares_contour_height = items_count * Px_Square + 2 * Px_Square_Contour;
- if (items_count > 1)
- squares_contour_height += (items_count - 1) * Px_Square_Contour;
-
- wxColour color(Squares_Border_Color[0], Squares_Border_Color[1], Squares_Border_Color[2]);
- wxPen pen(color);
- wxBrush brush(color);
- memDC.SetPen(pen);
- memDC.SetBrush(brush);
- memDC.DrawRectangle(wxRect(squares_contour_x, squares_contour_y, squares_contour_width, squares_contour_height));
-
- // draw items (colored icon + text)
- unsigned int icon_x = squares_contour_x + Px_Square_Contour;
- unsigned int icon_x_inner = icon_x + 1;
- unsigned int icon_y = squares_contour_y + Px_Square_Contour;
- unsigned int icon_y_step = Px_Square + Px_Square_Contour;
-
- unsigned int text_x = icon_x + Px_Square + Px_Text_Offset;
- unsigned int text_y_offset = (Px_Square - max_text_height) / 2;
-
- unsigned int px_inner_square = Px_Square - 2;
-
- for (const GCodePreviewData::LegendItem& item : items)
- {
- // draw darker icon perimeter
- const std::vector<unsigned char>& item_color_bytes = item.color.as_bytes();
- wxImage::HSVValue dark_hsv = wxImage::RGBtoHSV(wxImage::RGBValue(item_color_bytes[0], item_color_bytes[1], item_color_bytes[2]));
- dark_hsv.value *= 0.75;
- wxImage::RGBValue dark_rgb = wxImage::HSVtoRGB(dark_hsv);
- color.Set(dark_rgb.red, dark_rgb.green, dark_rgb.blue, item_color_bytes[3]);
- pen.SetColour(color);
- brush.SetColour(color);
- memDC.SetPen(pen);
- memDC.SetBrush(brush);
- memDC.DrawRectangle(wxRect(icon_x, icon_y, Px_Square, Px_Square));
-
- // draw icon interior
- color.Set(item_color_bytes[0], item_color_bytes[1], item_color_bytes[2], item_color_bytes[3]);
- pen.SetColour(color);
- brush.SetColour(color);
- memDC.SetPen(pen);
- memDC.SetBrush(brush);
- memDC.DrawRectangle(wxRect(icon_x_inner, icon_y + 1, px_inner_square, px_inner_square));
-
- // draw text
- memDC.DrawText(GUI::from_u8(item.text), text_x, icon_y + text_y_offset);
-
- // update y
- icon_y += icon_y_step;
- }
-
- memDC.SelectObject(wxNullBitmap);
-
- // Convert the bitmap into a linear data ready to be loaded into the GPU.
- {
- wxImage image = bitmap.ConvertToImage();
- image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]);
-
- // prepare buffer
- m_data.assign(4 * m_tex_width * m_tex_height, 0);
- for (unsigned int h = 0; h < m_tex_height; ++h)
- {
- unsigned int hh = h * m_tex_width;
- unsigned char* px_ptr = m_data.data() + 4 * hh;
- for (unsigned int w = 0; w < m_tex_width; ++w)
- {
- *px_ptr++ = image.GetRed(w, h);
- *px_ptr++ = image.GetGreen(w, h);
- *px_ptr++ = image.GetBlue(w, h);
- *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity;
- }
- }
- }
- return true;
+ return s_canvas_mgr.add(canvas);
}
-void _3DScene::_glew_init()
-{
- glewInit();
+bool _3DScene::remove_canvas(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.remove(canvas);
}
-static inline int hex_digit_to_int(const char c)
+void _3DScene::remove_all_canvases()
{
- return
- (c >= '0' && c <= '9') ? int(c - '0') :
- (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
- (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
+ s_canvas_mgr.remove_all();
}
-static inline std::vector<float> parse_colors(const std::vector<std::string> &scolors)
+bool _3DScene::init(wxGLCanvas* canvas)
{
- std::vector<float> output(scolors.size() * 4, 1.f);
- for (size_t i = 0; i < scolors.size(); ++ i) {
- const std::string &scolor = scolors[i];
- const char *c = scolor.data() + 1;
- if (scolor.size() == 7 && scolor.front() == '#') {
- for (size_t j = 0; j < 3; ++j) {
- int digit1 = hex_digit_to_int(*c ++);
- int digit2 = hex_digit_to_int(*c ++);
- if (digit1 == -1 || digit2 == -1)
- break;
- output[i * 4 + j] = float(digit1 * 16 + digit2) / 255.f;
- }
- }
- }
- return output;
+ return s_canvas_mgr.init(canvas);
}
-void _3DScene::load_gcode_preview(const Print* print, const GCodePreviewData* preview_data, GLVolumeCollection* volumes, const std::vector<std::string>& str_tool_colors, bool use_VBOs)
+void _3DScene::set_as_dirty(wxGLCanvas* canvas)
{
- if ((preview_data == nullptr) || (volumes == nullptr))
- return;
-
- if (volumes->empty())
- {
- std::vector<float> tool_colors = parse_colors(str_tool_colors);
-
- s_gcode_preview_volume_index.reset();
-
- _load_gcode_extrusion_paths(*preview_data, *volumes, tool_colors, use_VBOs);
- _load_gcode_travel_paths(*preview_data, *volumes, tool_colors, use_VBOs);
- _load_gcode_retractions(*preview_data, *volumes, use_VBOs);
- _load_gcode_unretractions(*preview_data, *volumes, use_VBOs);
-
- if (volumes->empty())
- reset_legend_texture();
- else
- {
- _generate_legend_texture(*preview_data, tool_colors);
- _load_shells(*print, *volumes, use_VBOs);
- }
- }
-
- _update_gcode_volumes_visibility(*preview_data, *volumes);
+ s_canvas_mgr.set_as_dirty(canvas);
}
-unsigned int _3DScene::get_legend_texture_width()
+unsigned int _3DScene::get_volumes_count(wxGLCanvas* canvas)
{
- return s_legend_texture.get_texture_width();
+ return s_canvas_mgr.get_volumes_count(canvas);
}
-unsigned int _3DScene::get_legend_texture_height()
+void _3DScene::reset_volumes(wxGLCanvas* canvas)
{
- return s_legend_texture.get_texture_height();
+ s_canvas_mgr.reset_volumes(canvas);
}
-void _3DScene::reset_legend_texture()
+void _3DScene::deselect_volumes(wxGLCanvas* canvas)
{
- s_legend_texture.reset_texture();
+ s_canvas_mgr.deselect_volumes(canvas);
}
-unsigned int _3DScene::finalize_legend_texture()
+void _3DScene::select_volume(wxGLCanvas* canvas, unsigned int id)
{
- return s_legend_texture.finalize();
+ s_canvas_mgr.select_volume(canvas, id);
}
-unsigned int _3DScene::get_warning_texture_width()
+void _3DScene::update_volumes_selection(wxGLCanvas* canvas, const std::vector<int>& selections)
{
- return s_warning_texture.get_texture_width();
+ s_canvas_mgr.update_volumes_selection(canvas, selections);
}
-unsigned int _3DScene::get_warning_texture_height()
+int _3DScene::check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config)
{
- return s_warning_texture.get_texture_height();
+ return s_canvas_mgr.check_volumes_outside_state(canvas, config);
}
-void _3DScene::generate_warning_texture(const std::string& msg)
+bool _3DScene::move_volume_up(wxGLCanvas* canvas, unsigned int id)
{
- s_warning_texture.generate(msg);
+ return s_canvas_mgr.move_volume_up(canvas, id);
}
-void _3DScene::reset_warning_texture()
+bool _3DScene::move_volume_down(wxGLCanvas* canvas, unsigned int id)
{
- s_warning_texture.reset_texture();
+ return s_canvas_mgr.move_volume_down(canvas, id);
}
-unsigned int _3DScene::finalize_warning_texture()
+void _3DScene::set_objects_selections(wxGLCanvas* canvas, const std::vector<int>& selections)
{
- return s_warning_texture.finalize();
+ s_canvas_mgr.set_objects_selections(canvas, selections);
}
-// Create 3D thick extrusion lines for a skirt and brim.
-// Adds a new Slic3r::GUI::3DScene::Volume to volumes.
-void _3DScene::_load_print_toolpaths(
- const Print *print,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors,
- bool use_VBOs)
+void _3DScene::set_config(wxGLCanvas* canvas, DynamicPrintConfig* config)
{
- // The skirt and brim steps should be marked as done, so their paths are valid.
- assert(print->is_step_done(psSkirt) && print->is_step_done(psBrim));
-
- if (!print->has_skirt() && print->config().brim_width.value == 0)
- return;
-
- const float color[] = { 0.5f, 1.0f, 0.5f, 1.f }; // greenish
-
- // number of skirt layers
- size_t total_layer_count = 0;
- for (const PrintObject *print_object : print->objects())
- total_layer_count = std::max(total_layer_count, print_object->total_layer_count());
- size_t skirt_height = print->has_infinite_skirt() ?
- total_layer_count :
- std::min<size_t>(print->config().skirt_height.value, total_layer_count);
- if (skirt_height == 0 && print->config().brim_width.value > 0)
- skirt_height = 1;
-
- // get first skirt_height layers (maybe this should be moved to a PrintObject method?)
- const PrintObject *object0 = print->objects().front();
- std::vector<float> print_zs;
- print_zs.reserve(skirt_height * 2);
- for (size_t i = 0; i < std::min(skirt_height, object0->layers().size()); ++ i)
- print_zs.push_back(float(object0->layers()[i]->print_z));
- //FIXME why there are support layers?
- for (size_t i = 0; i < std::min(skirt_height, object0->support_layers().size()); ++ i)
- print_zs.push_back(float(object0->support_layers()[i]->print_z));
- sort_remove_duplicates(print_zs);
- if (print_zs.size() > skirt_height)
- print_zs.erase(print_zs.begin() + skirt_height, print_zs.end());
-
- volumes->volumes.emplace_back(new GLVolume(color));
- GLVolume &volume = *volumes->volumes.back();
- for (size_t i = 0; i < skirt_height; ++ i) {
- volume.print_zs.push_back(print_zs[i]);
- volume.offsets.push_back(volume.indexed_vertex_array.quad_indices.size());
- volume.offsets.push_back(volume.indexed_vertex_array.triangle_indices.size());
- if (i == 0)
- extrusionentity_to_verts(print->brim(), print_zs[i], Point(0, 0), volume);
- extrusionentity_to_verts(print->skirt(), print_zs[i], Point(0, 0), volume);
- }
- volume.bounding_box = volume.indexed_vertex_array.bounding_box();
- volume.indexed_vertex_array.finalize_geometry(use_VBOs);
+ s_canvas_mgr.set_config(canvas, config);
}
-// Create 3D thick extrusion lines for object forming extrusions.
-// Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
-// one for perimeters, one for infill and one for supports.
-void _3DScene::_load_print_object_toolpaths(
- const PrintObject *print_object,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors_str,
- bool use_VBOs)
+void _3DScene::set_print(wxGLCanvas* canvas, Print* print)
{
- std::vector<float> tool_colors = parse_colors(tool_colors_str);
-
- struct Ctxt
- {
- const Points *shifted_copies;
- std::vector<const Layer*> layers;
- bool has_perimeters;
- bool has_infill;
- bool has_support;
- const std::vector<float>* tool_colors;
-
- // Number of vertices (each vertex is 6x4=24 bytes long)
- static const size_t alloc_size_max () { return 131072; } // 3.15MB
-// static const size_t alloc_size_max () { return 65536; } // 1.57MB
-// static const size_t alloc_size_max () { return 32768; } // 786kB
- static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
-
- static const float* color_perimeters () { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow
- static const float* color_infill () { static float color[4] = { 1.0f, 0.5f, 0.5f, 1.f }; return color; } // redish
- static const float* color_support () { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
-
- // For cloring by a tool, return a parsed color.
- bool color_by_tool() const { return tool_colors != nullptr; }
- size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; }
- const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
- int volume_idx(int extruder, int feature) const
- { return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(extruder - 1, 0)) : feature; }
- } ctxt;
-
- ctxt.shifted_copies = &print_object->_shifted_copies;
-
- // order layers by print_z
- ctxt.layers.reserve(print_object->layers().size() + print_object->support_layers().size());
- for (const Layer *layer : print_object->layers())
- ctxt.layers.push_back(layer);
- for (const Layer *layer : print_object->support_layers())
- ctxt.layers.push_back(layer);
- std::sort(ctxt.layers.begin(), ctxt.layers.end(), [](const Layer *l1, const Layer *l2) { return l1->print_z < l2->print_z; });
-
- // Maximum size of an allocation block: 32MB / sizeof(float)
- ctxt.has_perimeters = print_object->is_step_done(posPerimeters);
- ctxt.has_infill = print_object->is_step_done(posInfill);
- ctxt.has_support = print_object->is_step_done(posSupportMaterial);
- ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
-
- BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start";
-
- //FIXME Improve the heuristics for a grain size.
- size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1));
- tbb::spin_mutex new_volume_mutex;
- auto new_volume = [volumes, &new_volume_mutex](const float *color) -> GLVolume* {
- auto *volume = new GLVolume(color);
- new_volume_mutex.lock();
- volume->outside_printer_detection_enabled = false;
- volumes->volumes.emplace_back(volume);
- new_volume_mutex.unlock();
- return volume;
- };
- const size_t volumes_cnt_initial = volumes->volumes.size();
- std::vector<GLVolumeCollection> volumes_per_thread(ctxt.layers.size());
- tbb::parallel_for(
- tbb::blocked_range<size_t>(0, ctxt.layers.size(), grain_size),
- [&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
- std::vector<GLVolume*> vols;
- if (ctxt.color_by_tool()) {
- for (size_t i = 0; i < ctxt.number_tools(); ++ i)
- vols.emplace_back(new_volume(ctxt.color_tool(i)));
- } else
- vols = { new_volume(ctxt.color_perimeters()), new_volume(ctxt.color_infill()), new_volume(ctxt.color_support()) };
- for (GLVolume *vol : vols)
- vol->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
- for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
- const Layer *layer = ctxt.layers[idx_layer];
- for (size_t i = 0; i < vols.size(); ++ i) {
- GLVolume &vol = *vols[i];
- if (vol.print_zs.empty() || vol.print_zs.back() != layer->print_z) {
- vol.print_zs.push_back(layer->print_z);
- vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
- vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
- }
- }
- for (const Point &copy: *ctxt.shifted_copies) {
- for (const LayerRegion *layerm : layer->regions()) {
- if (ctxt.has_perimeters)
- extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
- *vols[ctxt.volume_idx(layerm->region()->config().perimeter_extruder.value, 0)]);
- if (ctxt.has_infill) {
- for (const ExtrusionEntity *ee : layerm->fills.entities) {
- // fill represents infill extrusions of a single island.
- const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
- if (! fill->entities.empty())
- extrusionentity_to_verts(*fill, float(layer->print_z), copy,
- *vols[ctxt.volume_idx(
- is_solid_infill(fill->entities.front()->role()) ?
- layerm->region()->config().solid_infill_extruder :
- layerm->region()->config().infill_extruder,
- 1)]);
- }
- }
- }
- if (ctxt.has_support) {
- const SupportLayer *support_layer = dynamic_cast<const SupportLayer*>(layer);
- if (support_layer) {
- for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
- extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy,
- *vols[ctxt.volume_idx(
- (extrusion_entity->role() == erSupportMaterial) ?
- support_layer->object()->config().support_material_extruder :
- support_layer->object()->config().support_material_interface_extruder,
- 2)]);
- }
- }
- }
- for (size_t i = 0; i < vols.size(); ++ i) {
- GLVolume &vol = *vols[i];
- if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
- // Store the vertex arrays and restart their containers,
- vols[i] = new_volume(vol.color);
- GLVolume &vol_new = *vols[i];
- // Assign the large pre-allocated buffers to the new GLVolume.
- vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
- // Copy the content back to the old GLVolume.
- vol.indexed_vertex_array = vol_new.indexed_vertex_array;
- // Finalize a bounding box of the old GLVolume.
- vol.bounding_box = vol.indexed_vertex_array.bounding_box();
- // Clear the buffers, but keep them pre-allocated.
- vol_new.indexed_vertex_array.clear();
- // Just make sure that clear did not clear the reserved memory.
- vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
- }
- }
- }
- for (GLVolume *vol : vols) {
- vol->bounding_box = vol->indexed_vertex_array.bounding_box();
- vol->indexed_vertex_array.shrink_to_fit();
- }
- });
-
- BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results";
- // Remove empty volumes from the newly added volumes.
- volumes->volumes.erase(
- std::remove_if(volumes->volumes.begin() + volumes_cnt_initial, volumes->volumes.end(),
- [](const GLVolume *volume) { return volume->empty(); }),
- volumes->volumes.end());
- for (size_t i = volumes_cnt_initial; i < volumes->volumes.size(); ++ i)
- volumes->volumes[i]->indexed_vertex_array.finalize_geometry(use_VBOs);
-
- BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end";
-}
-
-void _3DScene::_load_wipe_tower_toolpaths(
- const Print *print,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors_str,
- bool use_VBOs)
-{
- if (print->wipe_tower_data().tool_changes.empty())
- return;
-
- std::vector<float> tool_colors = parse_colors(tool_colors_str);
-
- struct Ctxt
- {
- const Print *print;
- const std::vector<float> *tool_colors;
-
- // Number of vertices (each vertex is 6x4=24 bytes long)
- static const size_t alloc_size_max () { return 131072; } // 3.15MB
- static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
-
- static const float* color_support () { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
-
- // For cloring by a tool, return a parsed color.
- bool color_by_tool() const { return tool_colors != nullptr; }
- size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; }
- const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
- int volume_idx(int tool, int feature) const
- { return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(tool, 0)) : feature; }
-
- const std::vector<WipeTower::ToolChangeResult>& tool_change(size_t idx) {
- return priming.empty() ?
- ((idx == print->wipe_tower_data().tool_changes.size()) ? final : print->wipe_tower_data().tool_changes[idx]) :
- ((idx == 0) ? priming : (idx == print->wipe_tower_data().tool_changes.size() + 1) ? final : print->wipe_tower_data().tool_changes[idx - 1]);
- }
- std::vector<WipeTower::ToolChangeResult> priming;
- std::vector<WipeTower::ToolChangeResult> final;
- } ctxt;
-
- ctxt.print = print;
- ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
- if (print->wipe_tower_data().priming != nullptr)
- ctxt.priming.emplace_back(*print->wipe_tower_data().priming);
- if (print->wipe_tower_data().final_purge)
- ctxt.final.emplace_back(*print->wipe_tower_data().final_purge);
-
- BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start";
-
- //FIXME Improve the heuristics for a grain size.
- size_t n_items = print->wipe_tower_data().tool_changes.size() + (ctxt.priming.empty() ? 0 : 1);
- size_t grain_size = std::max(n_items / 128, size_t(1));
- tbb::spin_mutex new_volume_mutex;
- auto new_volume = [volumes, &new_volume_mutex](const float *color) -> GLVolume* {
- auto *volume = new GLVolume(color);
- new_volume_mutex.lock();
- volume->outside_printer_detection_enabled = false;
- volumes->volumes.emplace_back(volume);
- new_volume_mutex.unlock();
- return volume;
- };
- const size_t volumes_cnt_initial = volumes->volumes.size();
- std::vector<GLVolumeCollection> volumes_per_thread(n_items);
- tbb::parallel_for(
- tbb::blocked_range<size_t>(0, n_items, grain_size),
- [&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
- // Bounding box of this slab of a wipe tower.
- std::vector<GLVolume*> vols;
- if (ctxt.color_by_tool()) {
- for (size_t i = 0; i < ctxt.number_tools(); ++ i)
- vols.emplace_back(new_volume(ctxt.color_tool(i)));
- } else
- vols = { new_volume(ctxt.color_support()) };
- for (GLVolume *volume : vols)
- volume->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
- for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
- const std::vector<WipeTower::ToolChangeResult> &layer = ctxt.tool_change(idx_layer);
- for (size_t i = 0; i < vols.size(); ++ i) {
- GLVolume &vol = *vols[i];
- if (vol.print_zs.empty() || vol.print_zs.back() != layer.front().print_z) {
- vol.print_zs.push_back(layer.front().print_z);
- vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
- vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
- }
- }
- for (const WipeTower::ToolChangeResult &extrusions : layer) {
- for (size_t i = 1; i < extrusions.extrusions.size();) {
- const WipeTower::Extrusion &e = extrusions.extrusions[i];
- if (e.width == 0.) {
- ++ i;
- continue;
- }
- size_t j = i + 1;
- if (ctxt.color_by_tool())
- for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].tool == e.tool && extrusions.extrusions[j].width > 0.f; ++ j) ;
- else
- for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].width > 0.f; ++ j) ;
- size_t n_lines = j - i;
- Lines lines;
- std::vector<double> widths;
- std::vector<double> heights;
- lines.reserve(n_lines);
- widths.reserve(n_lines);
- heights.assign(n_lines, extrusions.layer_height);
- for (; i < j; ++ i) {
- const WipeTower::Extrusion &e = extrusions.extrusions[i];
- assert(e.width > 0.f);
- const WipeTower::Extrusion &e_prev = *(&e - 1);
- lines.emplace_back(Point::new_scale(e_prev.pos.x, e_prev.pos.y), Point::new_scale(e.pos.x, e.pos.y));
- widths.emplace_back(e.width);
- }
- thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z,
- *vols[ctxt.volume_idx(e.tool, 0)]);
- }
- }
- }
- for (size_t i = 0; i < vols.size(); ++ i) {
- GLVolume &vol = *vols[i];
- if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
- // Store the vertex arrays and restart their containers,
- vols[i] = new_volume(vol.color);
- GLVolume &vol_new = *vols[i];
- // Assign the large pre-allocated buffers to the new GLVolume.
- vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
- // Copy the content back to the old GLVolume.
- vol.indexed_vertex_array = vol_new.indexed_vertex_array;
- // Finalize a bounding box of the old GLVolume.
- vol.bounding_box = vol.indexed_vertex_array.bounding_box();
- // Clear the buffers, but keep them pre-allocated.
- vol_new.indexed_vertex_array.clear();
- // Just make sure that clear did not clear the reserved memory.
- vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
- }
- }
- for (GLVolume *vol : vols) {
- vol->bounding_box = vol->indexed_vertex_array.bounding_box();
- vol->indexed_vertex_array.shrink_to_fit();
- }
- });
-
- BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results";
- // Remove empty volumes from the newly added volumes.
- volumes->volumes.erase(
- std::remove_if(volumes->volumes.begin() + volumes_cnt_initial, volumes->volumes.end(),
- [](const GLVolume *volume) { return volume->empty(); }),
- volumes->volumes.end());
- for (size_t i = volumes_cnt_initial; i < volumes->volumes.size(); ++ i)
- volumes->volumes[i]->indexed_vertex_array.finalize_geometry(use_VBOs);
-
- BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end";
+ s_canvas_mgr.set_print(canvas, print);
}
-void _3DScene::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors, bool use_VBOs)
+void _3DScene::set_model(wxGLCanvas* canvas, Model* model)
{
- // helper functions to select data in dependence of the extrusion view type
- struct Helper
- {
- static float path_filter(GCodePreviewData::Extrusion::EViewType type, const ExtrusionPath& path)
- {
- switch (type)
- {
- case GCodePreviewData::Extrusion::FeatureType:
- return (float)path.role();
- case GCodePreviewData::Extrusion::Height:
- return path.height;
- case GCodePreviewData::Extrusion::Width:
- return path.width;
- case GCodePreviewData::Extrusion::Feedrate:
- return path.feedrate;
- case GCodePreviewData::Extrusion::Tool:
- return (float)path.extruder_id;
- }
-
- return 0.0f;
- }
-
- static const GCodePreviewData::Color& path_color(const GCodePreviewData& data, const std::vector<float>& tool_colors, float value)
- {
- switch (data.extrusion.view_type)
- {
- case GCodePreviewData::Extrusion::FeatureType:
- return data.get_extrusion_role_color((ExtrusionRole)(int)value);
- case GCodePreviewData::Extrusion::Height:
- return data.get_extrusion_height_color(value);
- case GCodePreviewData::Extrusion::Width:
- return data.get_extrusion_width_color(value);
- case GCodePreviewData::Extrusion::Feedrate:
- return data.get_extrusion_feedrate_color(value);
- case GCodePreviewData::Extrusion::Tool:
- {
- static GCodePreviewData::Color color;
- ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + (unsigned int)value * 4), 4 * sizeof(float));
- return color;
- }
- }
+ s_canvas_mgr.set_model(canvas, model);
+}
- return GCodePreviewData::Color::Dummy;
- }
- };
+void _3DScene::set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape)
+{
+ s_canvas_mgr.set_bed_shape(canvas, shape);
+}
- // Helper structure for filters
- struct Filter
- {
- float value;
- ExtrusionRole role;
- GLVolume* volume;
-
- Filter(float value, ExtrusionRole role)
- : value(value)
- , role(role)
- , volume(nullptr)
- {
- }
+void _3DScene::set_auto_bed_shape(wxGLCanvas* canvas)
+{
+ s_canvas_mgr.set_auto_bed_shape(canvas);
+}
- bool operator == (const Filter& other) const
- {
- if (value != other.value)
- return false;
+BoundingBoxf3 _3DScene::get_volumes_bounding_box(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.get_volumes_bounding_box(canvas);
+}
- if (role != other.role)
- return false;
+void _3DScene::set_axes_length(wxGLCanvas* canvas, float length)
+{
+ s_canvas_mgr.set_axes_length(canvas, length);
+}
- return true;
- }
- };
+void _3DScene::set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons)
+{
+ s_canvas_mgr.set_cutting_plane(canvas, z, polygons);
+}
- typedef std::vector<Filter> FiltersList;
+void _3DScene::set_color_by(wxGLCanvas* canvas, const std::string& value)
+{
+ s_canvas_mgr.set_color_by(canvas, value);
+}
- size_t initial_volumes_count = volumes.volumes.size();
+void _3DScene::set_select_by(wxGLCanvas* canvas, const std::string& value)
+{
+ s_canvas_mgr.set_select_by(canvas, value);
+}
- // detects filters
- FiltersList filters;
- for (const GCodePreviewData::Extrusion::Layer& layer : preview_data.extrusion.layers)
- {
- for (const ExtrusionPath& path : layer.paths)
- {
- ExtrusionRole role = path.role();
- float path_filter = Helper::path_filter(preview_data.extrusion.view_type, path);
- if (std::find(filters.begin(), filters.end(), Filter(path_filter, role)) == filters.end())
- filters.emplace_back(path_filter, role);
- }
- }
+void _3DScene::set_drag_by(wxGLCanvas* canvas, const std::string& value)
+{
+ s_canvas_mgr.set_drag_by(canvas, value);
+}
- // nothing to render, return
- if (filters.empty())
- return;
+std::string _3DScene::get_select_by(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.get_select_by(canvas);
+}
- // creates a new volume for each filter
- for (Filter& filter : filters)
- {
- s_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Extrusion, (unsigned int)filter.role, (unsigned int)volumes.volumes.size());
+bool _3DScene::is_layers_editing_enabled(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.is_layers_editing_enabled(canvas);
+}
- GLVolume* volume = new GLVolume(Helper::path_color(preview_data, tool_colors, filter.value).rgba);
- if (volume != nullptr)
- {
- filter.volume = volume;
- volumes.volumes.emplace_back(volume);
- }
- else
- {
- // an error occourred - restore to previous state and return
- s_gcode_preview_volume_index.first_volumes.pop_back();
- if (initial_volumes_count != volumes.volumes.size())
- {
- std::vector<GLVolume*>::iterator begin = volumes.volumes.begin() + initial_volumes_count;
- std::vector<GLVolume*>::iterator end = volumes.volumes.end();
- for (std::vector<GLVolume*>::iterator it = begin; it < end; ++it)
- {
- GLVolume* volume = *it;
- delete volume;
- }
- volumes.volumes.erase(begin, end);
- return;
- }
- }
- }
+bool _3DScene::is_layers_editing_allowed(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.is_layers_editing_allowed(canvas);
+}
- // populates volumes
- for (const GCodePreviewData::Extrusion::Layer& layer : preview_data.extrusion.layers)
- {
- for (const ExtrusionPath& path : layer.paths)
- {
- float path_filter = Helper::path_filter(preview_data.extrusion.view_type, path);
- FiltersList::iterator filter = std::find(filters.begin(), filters.end(), Filter(path_filter, path.role()));
- if (filter != filters.end())
- {
- filter->volume->print_zs.push_back(layer.z);
- filter->volume->offsets.push_back(filter->volume->indexed_vertex_array.quad_indices.size());
- filter->volume->offsets.push_back(filter->volume->indexed_vertex_array.triangle_indices.size());
+bool _3DScene::is_shader_enabled(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.is_shader_enabled(canvas);
+}
- extrusionentity_to_verts(path, layer.z, *filter->volume);
- }
- }
- }
+bool _3DScene::is_reload_delayed(wxGLCanvas* canvas)
+{
+ return s_canvas_mgr.is_reload_delayed(canvas);
+}
- // finalize volumes and sends geometry to gpu
- if (volumes.volumes.size() > initial_volumes_count)
- {
- for (size_t i = initial_volumes_count; i < volumes.volumes.size(); ++i)
- {
- GLVolume* volume = volumes.volumes[i];
- volume->bounding_box = volume->indexed_vertex_array.bounding_box();
- volume->indexed_vertex_array.finalize_geometry(use_VBOs);
- }
- }
+void _3DScene::enable_layers_editing(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_layers_editing(canvas, enable);
}
-void _3DScene::_load_gcode_travel_paths(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors, bool use_VBOs)
+void _3DScene::enable_warning_texture(wxGLCanvas* canvas, bool enable)
{
- size_t initial_volumes_count = volumes.volumes.size();
- s_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Travel, 0, (unsigned int)initial_volumes_count);
+ s_canvas_mgr.enable_warning_texture(canvas, enable);
+}
- bool res = true;
- switch (preview_data.extrusion.view_type)
- {
- case GCodePreviewData::Extrusion::Feedrate:
- {
- res = _travel_paths_by_feedrate(preview_data, volumes);
- break;
- }
- case GCodePreviewData::Extrusion::Tool:
- {
- res = _travel_paths_by_tool(preview_data, volumes, tool_colors);
- break;
- }
- default:
- {
- res = _travel_paths_by_type(preview_data, volumes);
- break;
- }
- }
+void _3DScene::enable_legend_texture(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_legend_texture(canvas, enable);
+}
- if (!res)
- {
- // an error occourred - restore to previous state and return
- if (initial_volumes_count != volumes.volumes.size())
- {
- std::vector<GLVolume*>::iterator begin = volumes.volumes.begin() + initial_volumes_count;
- std::vector<GLVolume*>::iterator end = volumes.volumes.end();
- for (std::vector<GLVolume*>::iterator it = begin; it < end; ++it)
- {
- GLVolume* volume = *it;
- delete volume;
- }
- volumes.volumes.erase(begin, end);
- }
+void _3DScene::enable_picking(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_picking(canvas, enable);
+}
- return;
- }
+void _3DScene::enable_moving(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_moving(canvas, enable);
+}
- // finalize volumes and sends geometry to gpu
- if (volumes.volumes.size() > initial_volumes_count)
- {
- for (size_t i = initial_volumes_count; i < volumes.volumes.size(); ++i)
- {
- GLVolume* volume = volumes.volumes[i];
- volume->bounding_box = volume->indexed_vertex_array.bounding_box();
- volume->indexed_vertex_array.finalize_geometry(use_VBOs);
- }
- }
+void _3DScene::enable_gizmos(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_gizmos(canvas, enable);
}
-bool _3DScene::_travel_paths_by_type(const GCodePreviewData& preview_data, GLVolumeCollection& volumes)
+void _3DScene::enable_toolbar(wxGLCanvas* canvas, bool enable)
{
- // Helper structure for types
- struct Type
- {
- GCodePreviewData::Travel::EType value;
- GLVolume* volume;
+ s_canvas_mgr.enable_toolbar(canvas, enable);
+}
- explicit Type(GCodePreviewData::Travel::EType value)
- : value(value)
- , volume(nullptr)
- {
- }
+void _3DScene::enable_shader(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_shader(canvas, enable);
+}
- bool operator == (const Type& other) const
- {
- return value == other.value;
- }
- };
+void _3DScene::enable_force_zoom_to_bed(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_force_zoom_to_bed(canvas, enable);
+}
- typedef std::vector<Type> TypesList;
+void _3DScene::enable_dynamic_background(wxGLCanvas* canvas, bool enable)
+{
+ s_canvas_mgr.enable_dynamic_background(canvas, enable);
+}
- // colors travels by travel type
+void _3DScene::allow_multisample(wxGLCanvas* canvas, bool allow)
+{
+ s_canvas_mgr.allow_multisample(canvas, allow);
+}
- // detects types
- TypesList types;
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- if (std::find(types.begin(), types.end(), Type(polyline.type)) == types.end())
- types.emplace_back(polyline.type);
- }
+void _3DScene::enable_toolbar_item(wxGLCanvas* canvas, const std::string& name, bool enable)
+{
+ s_canvas_mgr.enable_toolbar_item(canvas, name, enable);
+}
- // nothing to render, return
- if (types.empty())
- return true;
+bool _3DScene::is_toolbar_item_pressed(wxGLCanvas* canvas, const std::string& name)
+{
+ return s_canvas_mgr.is_toolbar_item_pressed(canvas, name);
+}
- // creates a new volume for each type
- for (Type& type : types)
- {
- GLVolume* volume = new GLVolume(preview_data.travel.type_colors[type.value].rgba);
- if (volume == nullptr)
- return false;
- else
- {
- type.volume = volume;
- volumes.volumes.emplace_back(volume);
- }
- }
+void _3DScene::zoom_to_bed(wxGLCanvas* canvas)
+{
+ s_canvas_mgr.zoom_to_bed(canvas);
+}
- // populates volumes
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- TypesList::iterator type = std::find(types.begin(), types.end(), Type(polyline.type));
- if (type != types.end())
- {
- type->volume->print_zs.push_back(unscale(polyline.polyline.bounding_box().max.z));
- type->volume->offsets.push_back(type->volume->indexed_vertex_array.quad_indices.size());
- type->volume->offsets.push_back(type->volume->indexed_vertex_array.triangle_indices.size());
+void _3DScene::zoom_to_volumes(wxGLCanvas* canvas)
+{
+ s_canvas_mgr.zoom_to_volumes(canvas);
+}
- polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *type->volume);
- }
- }
+void _3DScene::select_view(wxGLCanvas* canvas, const std::string& direction)
+{
+ s_canvas_mgr.select_view(canvas, direction);
+}
- return true;
+void _3DScene::set_viewport_from_scene(wxGLCanvas* canvas, wxGLCanvas* other)
+{
+ s_canvas_mgr.set_viewport_from_scene(canvas, other);
}
-bool _3DScene::_travel_paths_by_feedrate(const GCodePreviewData& preview_data, GLVolumeCollection& volumes)
+void _3DScene::update_volumes_colors_by_extruder(wxGLCanvas* canvas)
{
- // Helper structure for feedrate
- struct Feedrate
- {
- float value;
- GLVolume* volume;
+ s_canvas_mgr.update_volumes_colors_by_extruder(canvas);
+}
- explicit Feedrate(float value)
- : value(value)
- , volume(nullptr)
- {
- }
+void _3DScene::update_gizmos_data(wxGLCanvas* canvas)
+{
+ s_canvas_mgr.update_gizmos_data(canvas);
+}
- bool operator == (const Feedrate& other) const
- {
- return value == other.value;
- }
- };
+void _3DScene::render(wxGLCanvas* canvas)
+{
+ s_canvas_mgr.render(canvas);
+}
- typedef std::vector<Feedrate> FeedratesList;
+std::vector<double> _3DScene::get_current_print_zs(wxGLCanvas* canvas, bool active_only)
+{
+ return s_canvas_mgr.get_current_print_zs(canvas, active_only);
+}
- // colors travels by feedrate
+void _3DScene::set_toolpaths_range(wxGLCanvas* canvas, double low, double high)
+{
+ s_canvas_mgr.set_toolpaths_range(canvas, low, high);
+}
- // detects feedrates
- FeedratesList feedrates;
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- if (std::find(feedrates.begin(), feedrates.end(), Feedrate(polyline.feedrate)) == feedrates.end())
- feedrates.emplace_back(polyline.feedrate);
- }
+void _3DScene::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_viewport_changed_callback(canvas, callback);
+}
- // nothing to render, return
- if (feedrates.empty())
- return true;
+void _3DScene::register_on_double_click_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_double_click_callback(canvas, callback);
+}
- // creates a new volume for each feedrate
- for (Feedrate& feedrate : feedrates)
- {
- GLVolume* volume = new GLVolume(preview_data.get_extrusion_feedrate_color(feedrate.value).rgba);
- if (volume == nullptr)
- return false;
- else
- {
- feedrate.volume = volume;
- volumes.volumes.emplace_back(volume);
- }
- }
+void _3DScene::register_on_right_click_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_right_click_callback(canvas, callback);
+}
- // populates volumes
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- FeedratesList::iterator feedrate = std::find(feedrates.begin(), feedrates.end(), Feedrate(polyline.feedrate));
- if (feedrate != feedrates.end())
- {
- feedrate->volume->print_zs.push_back(unscale(polyline.polyline.bounding_box().max.z));
- feedrate->volume->offsets.push_back(feedrate->volume->indexed_vertex_array.quad_indices.size());
- feedrate->volume->offsets.push_back(feedrate->volume->indexed_vertex_array.triangle_indices.size());
+void _3DScene::register_on_select_object_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_select_object_callback(canvas, callback);
+}
- polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *feedrate->volume);
- }
- }
+void _3DScene::register_on_model_update_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_model_update_callback(canvas, callback);
+}
- return true;
+void _3DScene::register_on_remove_object_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_remove_object_callback(canvas, callback);
}
-bool _3DScene::_travel_paths_by_tool(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors)
+void _3DScene::register_on_arrange_callback(wxGLCanvas* canvas, void* callback)
{
- // Helper structure for tool
- struct Tool
- {
- unsigned int value;
- GLVolume* volume;
+ s_canvas_mgr.register_on_arrange_callback(canvas, callback);
+}
- explicit Tool(unsigned int value)
- : value(value)
- , volume(nullptr)
- {
- }
+void _3DScene::register_on_rotate_object_left_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_rotate_object_left_callback(canvas, callback);
+}
- bool operator == (const Tool& other) const
- {
- return value == other.value;
- }
- };
+void _3DScene::register_on_rotate_object_right_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_rotate_object_right_callback(canvas, callback);
+}
- typedef std::vector<Tool> ToolsList;
+void _3DScene::register_on_scale_object_uniformly_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_scale_object_uniformly_callback(canvas, callback);
+}
- // colors travels by tool
+void _3DScene::register_on_increase_objects_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_increase_objects_callback(canvas, callback);
+}
- // detects tools
- ToolsList tools;
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- if (std::find(tools.begin(), tools.end(), Tool(polyline.extruder_id)) == tools.end())
- tools.emplace_back(polyline.extruder_id);
- }
+void _3DScene::register_on_decrease_objects_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_decrease_objects_callback(canvas, callback);
+}
- // nothing to render, return
- if (tools.empty())
- return true;
+void _3DScene::register_on_instance_moved_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_instance_moved_callback(canvas, callback);
+}
- // creates a new volume for each tool
- for (Tool& tool : tools)
- {
- GLVolume* volume = new GLVolume(tool_colors.data() + tool.value * 4);
- if (volume == nullptr)
- return false;
- else
- {
- tool.volume = volume;
- volumes.volumes.emplace_back(volume);
- }
- }
+void _3DScene::register_on_wipe_tower_moved_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_wipe_tower_moved_callback(canvas, callback);
+}
- // populates volumes
- for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
- {
- ToolsList::iterator tool = std::find(tools.begin(), tools.end(), Tool(polyline.extruder_id));
- if (tool != tools.end())
- {
- tool->volume->print_zs.push_back(unscale(polyline.polyline.bounding_box().max.z));
- tool->volume->offsets.push_back(tool->volume->indexed_vertex_array.quad_indices.size());
- tool->volume->offsets.push_back(tool->volume->indexed_vertex_array.triangle_indices.size());
+void _3DScene::register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_enable_action_buttons_callback(canvas, callback);
+}
- polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *tool->volume);
- }
- }
+void _3DScene::register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_gizmo_scale_uniformly_callback(canvas, callback);
+}
- return true;
+void _3DScene::register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_gizmo_rotate_callback(canvas, callback);
}
-void _3DScene::_load_gcode_retractions(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, bool use_VBOs)
+void _3DScene::register_on_gizmo_flatten_callback(wxGLCanvas* canvas, void* callback)
{
- s_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Retraction, 0, (unsigned int)volumes.volumes.size());
+ s_canvas_mgr.register_on_gizmo_flatten_callback(canvas, callback);
+}
- // nothing to render, return
- if (preview_data.retraction.positions.empty())
- return;
+void _3DScene::register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_on_update_geometry_info_callback(canvas, callback);
+}
- GLVolume* volume = new GLVolume(preview_data.retraction.color.rgba);
- if (volume != nullptr)
- {
- volumes.volumes.emplace_back(volume);
+void _3DScene::register_action_add_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_action_add_callback(canvas, callback);
+}
- for (const GCodePreviewData::Retraction::Position& position : preview_data.retraction.positions)
- {
- volume->print_zs.push_back(unscale(position.position.z));
- volume->offsets.push_back(volume->indexed_vertex_array.quad_indices.size());
- volume->offsets.push_back(volume->indexed_vertex_array.triangle_indices.size());
+void _3DScene::register_action_delete_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_action_delete_callback(canvas, callback);
+}
- point3_to_verts(position.position, position.width, position.height, *volume);
- }
+void _3DScene::register_action_deleteall_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_action_deleteall_callback(canvas, callback);
+}
- // finalize volumes and sends geometry to gpu
- volume->bounding_box = volume->indexed_vertex_array.bounding_box();
- volume->indexed_vertex_array.finalize_geometry(use_VBOs);
- }
+void _3DScene::register_action_arrange_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_action_arrange_callback(canvas, callback);
}
-void _3DScene::_load_gcode_unretractions(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, bool use_VBOs)
+void _3DScene::register_action_more_callback(wxGLCanvas* canvas, void* callback)
{
- s_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Unretraction, 0, (unsigned int)volumes.volumes.size());
+ s_canvas_mgr.register_action_more_callback(canvas, callback);
+}
- // nothing to render, return
- if (preview_data.unretraction.positions.empty())
- return;
+void _3DScene::register_action_fewer_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_action_fewer_callback(canvas, callback);
+}
- GLVolume* volume = new GLVolume(preview_data.unretraction.color.rgba);
- if (volume != nullptr)
- {
- volumes.volumes.emplace_back(volume);
+void _3DScene::register_action_split_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_action_split_callback(canvas, callback);
+}
- for (const GCodePreviewData::Retraction::Position& position : preview_data.unretraction.positions)
- {
- volume->print_zs.push_back(unscale(position.position.z));
- volume->offsets.push_back(volume->indexed_vertex_array.quad_indices.size());
- volume->offsets.push_back(volume->indexed_vertex_array.triangle_indices.size());
+void _3DScene::register_action_cut_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_action_cut_callback(canvas, callback);
+}
- point3_to_verts(position.position, position.width, position.height, *volume);
- }
+void _3DScene::register_action_settings_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_action_settings_callback(canvas, callback);
+}
- // finalize volumes and sends geometry to gpu
- volume->bounding_box = volume->indexed_vertex_array.bounding_box();
- volume->indexed_vertex_array.finalize_geometry(use_VBOs);
- }
+void _3DScene::register_action_layersediting_callback(wxGLCanvas* canvas, void* callback)
+{
+ s_canvas_mgr.register_action_layersediting_callback(canvas, callback);
}
-void _3DScene::_update_gcode_volumes_visibility(const GCodePreviewData& preview_data, GLVolumeCollection& volumes)
+void _3DScene::register_action_selectbyparts_callback(wxGLCanvas* canvas, void* callback)
{
- unsigned int size = (unsigned int)s_gcode_preview_volume_index.first_volumes.size();
- for (unsigned int i = 0; i < size; ++i)
- {
- std::vector<GLVolume*>::iterator begin = volumes.volumes.begin() + s_gcode_preview_volume_index.first_volumes[i].id;
- std::vector<GLVolume*>::iterator end = (i + 1 < size) ? volumes.volumes.begin() + s_gcode_preview_volume_index.first_volumes[i + 1].id : volumes.volumes.end();
+ s_canvas_mgr.register_action_selectbyparts_callback(canvas, callback);
+}
- for (std::vector<GLVolume*>::iterator it = begin; it != end; ++it)
- {
- GLVolume* volume = *it;
- volume->outside_printer_detection_enabled = false;
+static inline int hex_digit_to_int(const char c)
+{
+ return
+ (c >= '0' && c <= '9') ? int(c - '0') :
+ (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
+ (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
+}
- switch (s_gcode_preview_volume_index.first_volumes[i].type)
- {
- case GCodePreviewVolumeIndex::Extrusion:
- {
- if ((ExtrusionRole)s_gcode_preview_volume_index.first_volumes[i].flag == erCustom)
- volume->zoom_to_volumes = false;
-
- volume->is_active = preview_data.extrusion.is_role_flag_set((ExtrusionRole)s_gcode_preview_volume_index.first_volumes[i].flag);
- break;
- }
- case GCodePreviewVolumeIndex::Travel:
- {
- volume->is_active = preview_data.travel.is_visible;
- volume->zoom_to_volumes = false;
- break;
- }
- case GCodePreviewVolumeIndex::Retraction:
- {
- volume->is_active = preview_data.retraction.is_visible;
- volume->zoom_to_volumes = false;
- break;
- }
- case GCodePreviewVolumeIndex::Unretraction:
- {
- volume->is_active = preview_data.unretraction.is_visible;
- volume->zoom_to_volumes = false;
- break;
- }
- case GCodePreviewVolumeIndex::Shell:
- {
- volume->is_active = preview_data.shell.is_visible;
- volume->color[3] = 0.25f;
- volume->zoom_to_volumes = false;
- break;
- }
- default:
- {
- volume->is_active = false;
- volume->zoom_to_volumes = false;
+static inline std::vector<float> parse_colors(const std::vector<std::string> &scolors)
+{
+ std::vector<float> output(scolors.size() * 4, 1.f);
+ for (size_t i = 0; i < scolors.size(); ++ i) {
+ const std::string &scolor = scolors[i];
+ const char *c = scolor.data() + 1;
+ if (scolor.size() == 7 && scolor.front() == '#') {
+ for (size_t j = 0; j < 3; ++j) {
+ int digit1 = hex_digit_to_int(*c ++);
+ int digit2 = hex_digit_to_int(*c ++);
+ if (digit1 == -1 || digit2 == -1)
break;
- }
+ output[i * 4 + j] = float(digit1 * 16 + digit2) / 255.f;
}
}
}
+ return output;
}
-void _3DScene::_generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
+std::vector<int> _3DScene::load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector<int> instance_idxs)
{
- s_legend_texture.generate(preview_data, tool_colors);
+ return s_canvas_mgr.load_object(canvas, model_object, obj_idx, instance_idxs);
}
-void _3DScene::_load_shells(const Print& print, GLVolumeCollection& volumes, bool use_VBOs)
+std::vector<int> _3DScene::load_object(wxGLCanvas* canvas, const Model* model, int obj_idx)
{
- size_t initial_volumes_count = volumes.volumes.size();
- s_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Shell, 0, (unsigned int)initial_volumes_count);
-
- if (print.objects().empty())
- // nothing to render, return
- return;
-
- // adds objects' volumes
- unsigned int object_id = 0;
- for (PrintObject* obj : print.objects())
- {
- ModelObject* model_obj = obj->model_object();
+ return s_canvas_mgr.load_object(canvas, model, obj_idx);
+}
- std::vector<int> instance_ids(model_obj->instances.size());
- for (int i = 0; i < model_obj->instances.size(); ++i)
- {
- instance_ids[i] = i;
- }
+int _3DScene::get_first_volume_id(wxGLCanvas* canvas, int obj_idx)
+{
+ return s_canvas_mgr.get_first_volume_id(canvas, obj_idx);
+}
- for (ModelInstance* instance : model_obj->instances)
- {
- volumes.load_object(model_obj, object_id, instance_ids, "object", "object", "object", use_VBOs);
- }
+void _3DScene::reload_scene(wxGLCanvas* canvas, bool force)
+{
+ s_canvas_mgr.reload_scene(canvas, force);
+}
- ++object_id;
- }
+void _3DScene::load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors)
+{
+ s_canvas_mgr.load_gcode_preview(canvas, preview_data, str_tool_colors);
+}
- // adds wipe tower's volume
- coordf_t max_z = print.objects().front()->model_object()->get_model()->bounding_box().max.z;
- const PrintConfig& config = print.config();
- unsigned int extruders_count = config.nozzle_diameter.size();
- if ((extruders_count > 1) && config.single_extruder_multi_material && config.wipe_tower && !config.complete_objects)
- volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, config.wipe_tower_per_color_wipe * (extruders_count - 1), max_z, use_VBOs);
+void _3DScene::load_preview(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors)
+{
+ s_canvas_mgr.load_preview(canvas, str_tool_colors);
}
+void _3DScene::reset_legend_texture()
+{
+ s_canvas_mgr.reset_legend_texture();
}
+
+} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp
index 0fd31d8d6..b53fd8a23 100644
--- a/xs/src/slic3r/GUI/3DScene.hpp
+++ b/xs/src/slic3r/GUI/3DScene.hpp
@@ -6,8 +6,11 @@
#include "../../libslic3r/Line.hpp"
#include "../../libslic3r/TriangleMesh.hpp"
#include "../../libslic3r/Utils.hpp"
+#include "../../libslic3r/Model.hpp"
+#include "../../slic3r/GUI/GLCanvas3DManager.hpp"
class wxBitmap;
+class wxWindow;
namespace Slic3r {
@@ -17,6 +20,11 @@ class Model;
class ModelObject;
class GCodePreviewData;
class DynamicPrintConfig;
+class ExtrusionPath;
+class ExtrusionMultiPath;
+class ExtrusionLoop;
+class ExtrusionEntity;
+class ExtrusionEntityCollection;
// A container for interleaved arrays of 3D vertices and normals,
// possibly indexed by triangles and / or quads.
@@ -111,8 +119,8 @@ public:
push_geometry(float(x), float(y), float(z), float(nx), float(ny), float(nz));
}
- inline void push_geometry(const Pointf3& p, const Vectorf3& n) {
- push_geometry(p.x, p.y, p.z, n.x, n.y, n.z);
+ inline void push_geometry(const Vec3d& p, const Vec3d& n) {
+ push_geometry(p(0), p(1), p(2), n(0), n(1), n(2));
}
inline void push_triangle(int idx1, int idx2, int idx3) {
@@ -168,17 +176,17 @@ public:
BoundingBoxf3 bbox;
if (! this->vertices_and_normals_interleaved.empty()) {
bbox.defined = true;
- bbox.min.x = bbox.max.x = this->vertices_and_normals_interleaved[3];
- bbox.min.y = bbox.max.y = this->vertices_and_normals_interleaved[4];
- bbox.min.z = bbox.max.z = this->vertices_and_normals_interleaved[5];
+ bbox.min(0) = bbox.max(0) = this->vertices_and_normals_interleaved[3];
+ bbox.min(1) = bbox.max(1) = this->vertices_and_normals_interleaved[4];
+ bbox.min(2) = bbox.max(2) = this->vertices_and_normals_interleaved[5];
for (size_t i = 9; i < this->vertices_and_normals_interleaved.size(); i += 6) {
const float *verts = this->vertices_and_normals_interleaved.data() + i;
- bbox.min.x = std::min<coordf_t>(bbox.min.x, verts[0]);
- bbox.min.y = std::min<coordf_t>(bbox.min.y, verts[1]);
- bbox.min.z = std::min<coordf_t>(bbox.min.z, verts[2]);
- bbox.max.x = std::max<coordf_t>(bbox.max.x, verts[0]);
- bbox.max.y = std::max<coordf_t>(bbox.max.y, verts[1]);
- bbox.max.z = std::max<coordf_t>(bbox.max.z, verts[2]);
+ bbox.min(0) = std::min<coordf_t>(bbox.min(0), verts[0]);
+ bbox.min(1) = std::min<coordf_t>(bbox.min(1), verts[1]);
+ bbox.min(2) = std::min<coordf_t>(bbox.min(2), verts[2]);
+ bbox.max(0) = std::max<coordf_t>(bbox.max(0), verts[0]);
+ bbox.max(1) = std::max<coordf_t>(bbox.max(1), verts[1]);
+ bbox.max(2) = std::max<coordf_t>(bbox.max(2), verts[2]);
}
}
return bbox;
@@ -192,10 +200,10 @@ private:
}
};
-class GLTexture
+class LayersTexture
{
public:
- GLTexture() : width(0), height(0), levels(0), cells(0) {}
+ LayersTexture() : width(0), height(0), levels(0), cells(0) {}
// Texture data
std::vector<char> data;
@@ -217,7 +225,7 @@ class GLVolume {
// ID of the shader used to render with the layer height texture
unsigned int shader_id;
// The print object to update when generating the layer height texture
- PrintObject* print_object;
+ const PrintObject* print_object;
float z_cursor_relative;
float edit_band_width;
@@ -233,7 +241,7 @@ class GLVolume {
edit_band_width = 0.0f;
}
- bool can_use() { return (texture_id > 0) && (shader_id > 0) && (print_object != nullptr); }
+ bool can_use() const { return (texture_id > 0) && (shader_id > 0) && (print_object != nullptr); }
};
public:
@@ -242,41 +250,35 @@ public:
static const float OUTSIDE_COLOR[4];
static const float SELECTED_OUTSIDE_COLOR[4];
- GLVolume(float r = 1.f, float g = 1.f, float b = 1.f, float a = 1.f) :
- composite_id(-1),
- select_group_id(-1),
- drag_group_id(-1),
- selected(false),
- is_active(true),
- zoom_to_volumes(true),
- outside_printer_detection_enabled(true),
- is_outside(false),
- hover(false),
- tverts_range(0, size_t(-1)),
- qverts_range(0, size_t(-1))
- {
- color[0] = r;
- color[1] = g;
- color[2] = b;
- color[3] = a;
- set_render_color(r, g, b, a);
- }
+ GLVolume(float r = 1.f, float g = 1.f, float b = 1.f, float a = 1.f);
GLVolume(const float *rgba) : GLVolume(rgba[0], rgba[1], rgba[2], rgba[3]) {}
- std::vector<int> load_object(
- const ModelObject *model_object,
- const std::vector<int> &instance_idxs,
- const std::string &color_by,
- const std::string &select_by,
- const std::string &drag_by);
+private:
+ // Offset of the volume to be rendered.
+ Vec3d m_offset;
+ // Rotation around Z axis of the volume to be rendered.
+ double m_rotation;
+ // Scale factor of the volume to be rendered.
+ double m_scaling_factor;
+ // World matrix of the volume to be rendered.
+ mutable Transform3f m_world_matrix;
+ // Whether or not is needed to recalculate the world matrix.
+ mutable bool m_world_matrix_dirty;
+ // Bounding box of this volume, in unscaled coordinates.
+ mutable BoundingBoxf3 m_transformed_bounding_box;
+ // Whether or not is needed to recalculate the transformed bounding box.
+ mutable bool m_transformed_bounding_box_dirty;
+ // Pointer to convex hull of the original mesh, if any.
+ const TriangleMesh* m_convex_hull;
+ // Bounding box of this volume, in unscaled coordinates.
+ mutable BoundingBoxf3 m_transformed_convex_hull_bounding_box;
+ // Whether or not is needed to recalculate the transformed convex hull bounding box.
+ mutable bool m_transformed_convex_hull_bounding_box_dirty;
- int load_wipe_tower_preview(
- int obj_idx, float pos_x, float pos_y, float width, float depth, float height, bool use_VBOs);
+public:
// Bounding box of this volume, in unscaled coordinates.
BoundingBoxf3 bounding_box;
- // Offset of the volume to be rendered.
- Pointf3 origin;
// Color of the triangles / quads held by this volume.
float color[4];
// Color used to render this volume.
@@ -287,18 +289,26 @@ public:
int select_group_id;
// An ID for group dragging. It may be the same for all meshes of all object instances, or for just a single object instance.
int drag_group_id;
+ // An ID containing the extruder ID (used to select color).
+ int extruder_id;
// Is this object selected?
bool selected;
// Whether or not this volume is active for rendering
bool is_active;
// Whether or not to use this volume when applying zoom_to_volumes()
bool zoom_to_volumes;
- // Wheter or not this volume is enabled for outside print volume detection.
- bool outside_printer_detection_enabled;
+ // Wheter or not this volume is enabled for outside print volume detection in shader.
+ bool shader_outside_printer_detection_enabled;
// Wheter or not this volume is outside print volume.
bool is_outside;
// Boolean: Is mouse over this object?
bool hover;
+ // Wheter or not this volume has been generated from a modifier
+ bool is_modifier;
+ // Wheter or not this volume has been generated from the wipe tower
+ bool is_wipe_tower;
+ // Wheter or not this volume has been generated from an extrusion path
+ bool is_extrusion_path;
// Interleaved triangles & normals with indexed triangles & quads.
GLIndexedVertexArray indexed_vertex_array;
@@ -317,10 +327,26 @@ public:
// Sets render color in dependence of current state
void set_render_color();
+ double get_rotation();
+ void set_rotation(double rotation);
+
+ const Vec3d& get_offset() const;
+ void set_offset(const Vec3d& offset);
+
+ void set_scaling_factor(double factor);
+
+ void set_convex_hull(const TriangleMesh& convex_hull);
+
+ void set_select_group_id(const std::string& select_by);
+ void set_drag_group_id(const std::string& drag_by);
+
int object_idx() const { return this->composite_id / 1000000; }
int volume_idx() const { return (this->composite_id / 1000) % 1000; }
int instance_idx() const { return this->composite_id % 1000; }
- BoundingBoxf3 transformed_bounding_box() const { BoundingBoxf3 bb = this->bounding_box; bb.translate(this->origin); return bb; }
+
+ const Transform3f& world_matrix() const;
+ const BoundingBoxf3& transformed_bounding_box() const;
+ const BoundingBoxf3& transformed_convex_hull_bounding_box() const;
bool empty() const { return this->indexed_vertex_array.empty(); }
bool indexed() const { return this->indexed_vertex_array.indexed(); }
@@ -328,11 +354,14 @@ public:
void set_range(coordf_t low, coordf_t high);
void render() const;
void render_using_layer_height() const;
+ void render_VBOs(int color_id, int detection_id, int worldmatrix_id) const;
+ void render_legacy() const;
+
void finalize_geometry(bool use_VBOs) { this->indexed_vertex_array.finalize_geometry(use_VBOs); }
void release_geometry() { this->indexed_vertex_array.release_geometry(); }
/************************************************ Layer height texture ****************************************************/
- std::shared_ptr<GLTexture> layer_height_texture;
+ std::shared_ptr<LayersTexture> layer_height_texture;
// Data to render this volume using the layer height texture
LayerHeightTextureData layer_height_texture_data;
@@ -352,13 +381,10 @@ public:
return (layer_height_texture.get() == nullptr) ? 0 :
(void*)(layer_height_texture->data.data() + layer_height_texture->width * layer_height_texture->height * 4);
}
- double layer_height_texture_z_to_row_id() const {
- return (this->layer_height_texture.get() == nullptr) ? 0. :
- double(this->layer_height_texture->cells - 1) / (double(this->layer_height_texture->width) * bounding_box.max.z);
- }
- void generate_layer_height_texture(PrintObject *print_object, bool force);
+ double layer_height_texture_z_to_row_id() const;
+ void generate_layer_height_texture(const PrintObject *print_object, bool force);
- void set_layer_height_texture_data(unsigned int texture_id, unsigned int shader_id, PrintObject* print_object, float z_cursor_relative, float edit_band_width)
+ void set_layer_height_texture_data(unsigned int texture_id, unsigned int shader_id, const PrintObject* print_object, float z_cursor_relative, float edit_band_width)
{
layer_height_texture_data.texture_id = texture_id;
layer_height_texture_data.shader_id = shader_id;
@@ -392,7 +418,7 @@ public:
bool use_VBOs);
int load_wipe_tower_preview(
- int obj_idx, float pos_x, float pos_y, float width, float depth, float height, bool use_VBOs);
+ int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width);
// Render the volumes by OpenGL.
void render_VBOs() const;
@@ -416,10 +442,18 @@ public:
print_box_max[0] = max_x; print_box_max[1] = max_y; print_box_max[2] = max_z;
}
- void update_outside_state(const DynamicPrintConfig* config, bool all_inside);
+ // returns true if all the volumes are completely contained in the print volume
+ // returns the containment state in the given out_state, if non-null
+ bool check_outside_state(const DynamicPrintConfig* config, ModelInstance::EPrintVolumeState* out_state);
+ void reset_outside_state();
+
+ void update_colors_by_extruder(const DynamicPrintConfig* config);
+
+ void set_select_by(const std::string& select_by);
+ void set_drag_by(const std::string& drag_by);
// Returns a vector containing the sorted list of all the print_zs of the volumes contained in this collection
- std::vector<double> get_current_print_zs() const;
+ std::vector<double> get_current_print_zs(bool active_only) const;
private:
GLVolumeCollection(const GLVolumeCollection &other);
@@ -428,150 +462,139 @@ private:
class _3DScene
{
- struct GCodePreviewVolumeIndex
- {
- enum EType
- {
- Extrusion,
- Travel,
- Retraction,
- Unretraction,
- Shell,
- Num_Geometry_Types
- };
-
- struct FirstVolume
- {
- EType type;
- unsigned int flag;
- // Index of the first volume in a GLVolumeCollection.
- unsigned int id;
-
- FirstVolume(EType type, unsigned int flag, unsigned int id) : type(type), flag(flag), id(id) {}
- };
-
- std::vector<FirstVolume> first_volumes;
-
- void reset() { first_volumes.clear(); }
- };
-
- static GCodePreviewVolumeIndex s_gcode_preview_volume_index;
-
- class TextureBase
- {
- protected:
- unsigned int m_tex_id;
- unsigned int m_tex_width;
- unsigned int m_tex_height;
-
- // generate() fills in m_data with the pixels, while finalize() moves the data to the GPU before rendering.
- std::vector<unsigned char> m_data;
-
- public:
- TextureBase() : m_tex_id(0), m_tex_width(0), m_tex_height(0) {}
- virtual ~TextureBase() { _destroy_texture(); }
-
- // If not loaded, load the texture data into the GPU. Return a texture ID or 0 if the texture has zero size.
- unsigned int finalize();
-
- unsigned int get_texture_id() const { return m_tex_id; }
- unsigned int get_texture_width() const { return m_tex_width; }
- unsigned int get_texture_height() const { return m_tex_height; }
-
- void reset_texture() { _destroy_texture(); }
-
- private:
- void _destroy_texture();
- };
-
- class WarningTexture : public TextureBase
- {
- static const unsigned char Background_Color[3];
- static const unsigned char Opacity;
-
- public:
- WarningTexture() : TextureBase() {}
-
- // Generate a texture data, but don't load it into the GPU yet, as the glcontext may not be valid yet.
- bool generate(const std::string& msg);
- };
-
- class LegendTexture : public TextureBase
- {
- static const unsigned int Px_Title_Offset = 5;
- static const unsigned int Px_Text_Offset = 5;
- static const unsigned int Px_Square = 20;
- static const unsigned int Px_Square_Contour = 1;
- static const unsigned int Px_Border = Px_Square / 2;
- static const unsigned char Squares_Border_Color[3];
- static const unsigned char Background_Color[3];
- static const unsigned char Opacity;
-
- public:
- LegendTexture() : TextureBase() {}
-
- // Generate a texture data, but don't load it into the GPU yet, as the glcontext may not be valid yet.
- bool generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
- };
-
- static LegendTexture s_legend_texture;
- static WarningTexture s_warning_texture;
+ static GUI::GLCanvas3DManager s_canvas_mgr;
public:
- static void _glew_init();
-
- static void load_gcode_preview(const Print* print, const GCodePreviewData* preview_data, GLVolumeCollection* volumes, const std::vector<std::string>& str_tool_colors, bool use_VBOs);
-
- static unsigned int get_legend_texture_width();
- static unsigned int get_legend_texture_height();
+ static void init_gl();
+ static std::string get_gl_info(bool format_as_html, bool extensions);
+ static bool use_VBOs();
+
+ static bool add_canvas(wxGLCanvas* canvas);
+ static bool remove_canvas(wxGLCanvas* canvas);
+ static void remove_all_canvases();
+
+ static bool init(wxGLCanvas* canvas);
+
+ static void set_as_dirty(wxGLCanvas* canvas);
+
+ static unsigned int get_volumes_count(wxGLCanvas* canvas);
+ static void reset_volumes(wxGLCanvas* canvas);
+ static void deselect_volumes(wxGLCanvas* canvas);
+ static void select_volume(wxGLCanvas* canvas, unsigned int id);
+ static void update_volumes_selection(wxGLCanvas* canvas, const std::vector<int>& selections);
+ static int check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config);
+ static bool move_volume_up(wxGLCanvas* canvas, unsigned int id);
+ static bool move_volume_down(wxGLCanvas* canvas, unsigned int id);
+
+ static void set_objects_selections(wxGLCanvas* canvas, const std::vector<int>& selections);
+
+ static void set_config(wxGLCanvas* canvas, DynamicPrintConfig* config);
+ static void set_print(wxGLCanvas* canvas, Print* print);
+ static void set_model(wxGLCanvas* canvas, Model* model);
+
+ static void set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape);
+ static void set_auto_bed_shape(wxGLCanvas* canvas);
+
+ static BoundingBoxf3 get_volumes_bounding_box(wxGLCanvas* canvas);
+
+ static void set_axes_length(wxGLCanvas* canvas, float length);
+
+ static void set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons);
+
+ static void set_color_by(wxGLCanvas* canvas, const std::string& value);
+ static void set_select_by(wxGLCanvas* canvas, const std::string& value);
+ static void set_drag_by(wxGLCanvas* canvas, const std::string& value);
+
+ static std::string get_select_by(wxGLCanvas* canvas);
+
+ static bool is_layers_editing_enabled(wxGLCanvas* canvas);
+ static bool is_layers_editing_allowed(wxGLCanvas* canvas);
+ static bool is_shader_enabled(wxGLCanvas* canvas);
+
+ static bool is_reload_delayed(wxGLCanvas* canvas);
+
+ static void enable_layers_editing(wxGLCanvas* canvas, bool enable);
+ static void enable_warning_texture(wxGLCanvas* canvas, bool enable);
+ static void enable_legend_texture(wxGLCanvas* canvas, bool enable);
+ static void enable_picking(wxGLCanvas* canvas, bool enable);
+ static void enable_moving(wxGLCanvas* canvas, bool enable);
+ static void enable_gizmos(wxGLCanvas* canvas, bool enable);
+ static void enable_toolbar(wxGLCanvas* canvas, bool enable);
+ static void enable_shader(wxGLCanvas* canvas, bool enable);
+ static void enable_force_zoom_to_bed(wxGLCanvas* canvas, bool enable);
+ static void enable_dynamic_background(wxGLCanvas* canvas, bool enable);
+ static void allow_multisample(wxGLCanvas* canvas, bool allow);
+
+ static void enable_toolbar_item(wxGLCanvas* canvas, const std::string& name, bool enable);
+ static bool is_toolbar_item_pressed(wxGLCanvas* canvas, const std::string& name);
+
+ static void zoom_to_bed(wxGLCanvas* canvas);
+ static void zoom_to_volumes(wxGLCanvas* canvas);
+ static void select_view(wxGLCanvas* canvas, const std::string& direction);
+ static void set_viewport_from_scene(wxGLCanvas* canvas, wxGLCanvas* other);
+
+ static void update_volumes_colors_by_extruder(wxGLCanvas* canvas);
+ static void update_gizmos_data(wxGLCanvas* canvas);
+
+ static void render(wxGLCanvas* canvas);
+
+ static std::vector<double> get_current_print_zs(wxGLCanvas* canvas, bool active_only);
+ static void set_toolpaths_range(wxGLCanvas* canvas, double low, double high);
+
+ static void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_double_click_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_right_click_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_select_object_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_model_update_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_remove_object_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_arrange_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_rotate_object_left_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_rotate_object_right_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_scale_object_uniformly_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_increase_objects_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_decrease_objects_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_instance_moved_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_wipe_tower_moved_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_gizmo_flatten_callback(wxGLCanvas* canvas, void* callback);
+ static void register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback);
+
+ static void register_action_add_callback(wxGLCanvas* canvas, void* callback);
+ static void register_action_delete_callback(wxGLCanvas* canvas, void* callback);
+ static void register_action_deleteall_callback(wxGLCanvas* canvas, void* callback);
+ static void register_action_arrange_callback(wxGLCanvas* canvas, void* callback);
+ static void register_action_more_callback(wxGLCanvas* canvas, void* callback);
+ static void register_action_fewer_callback(wxGLCanvas* canvas, void* callback);
+ static void register_action_split_callback(wxGLCanvas* canvas, void* callback);
+ static void register_action_cut_callback(wxGLCanvas* canvas, void* callback);
+ static void register_action_settings_callback(wxGLCanvas* canvas, void* callback);
+ static void register_action_layersediting_callback(wxGLCanvas* canvas, void* callback);
+ static void register_action_selectbyparts_callback(wxGLCanvas* canvas, void* callback);
+
+ static std::vector<int> load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector<int> instance_idxs);
+ static std::vector<int> load_object(wxGLCanvas* canvas, const Model* model, int obj_idx);
+
+ static int get_first_volume_id(wxGLCanvas* canvas, int obj_idx);
+
+ static void reload_scene(wxGLCanvas* canvas, bool force);
+
+ static void load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors);
+ static void load_preview(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors);
static void reset_legend_texture();
- static unsigned int finalize_legend_texture();
-
- static unsigned int get_warning_texture_width();
- static unsigned int get_warning_texture_height();
-
- // generates a warning texture containing the given message
- static void generate_warning_texture(const std::string& msg);
- static void reset_warning_texture();
- static unsigned int finalize_warning_texture();
-
- static void _load_print_toolpaths(
- const Print *print,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors,
- bool use_VBOs);
-
- static void _load_print_object_toolpaths(
- const PrintObject *print_object,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors,
- bool use_VBOs);
-
- static void _load_wipe_tower_toolpaths(
- const Print *print,
- GLVolumeCollection *volumes,
- const std::vector<std::string> &tool_colors_str,
- bool use_VBOs);
-private:
- // generates gcode extrusion paths geometry
- static void _load_gcode_extrusion_paths(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors, bool use_VBOs);
- // generates gcode travel paths geometry
- static void _load_gcode_travel_paths(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors, bool use_VBOs);
- static bool _travel_paths_by_type(const GCodePreviewData& preview_data, GLVolumeCollection& volumes);
- static bool _travel_paths_by_feedrate(const GCodePreviewData& preview_data, GLVolumeCollection& volumes);
- static bool _travel_paths_by_tool(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, const std::vector<float>& tool_colors);
- // generates gcode retractions geometry
- static void _load_gcode_retractions(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, bool use_VBOs);
- // generates gcode unretractions geometry
- static void _load_gcode_unretractions(const GCodePreviewData& preview_data, GLVolumeCollection& volumes, bool use_VBOs);
- // sets gcode geometry visibility according to user selection
- static void _update_gcode_volumes_visibility(const GCodePreviewData& preview_data, GLVolumeCollection& volumes);
- // generates the legend texture in dependence of the current shown view type
- static void _generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
- // generates objects and wipe tower geometry
- static void _load_shells(const Print& print, GLVolumeCollection& volumes, bool use_VBOs);
+ static void thick_lines_to_verts(const Lines& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, double top_z, GLVolume& volume);
+ static void thick_lines_to_verts(const Lines3& lines, const std::vector<double>& widths, const std::vector<double>& heights, bool closed, GLVolume& volume);
+ static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, GLVolume& volume);
+ static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, const Point& copy, GLVolume& volume);
+ static void extrusionentity_to_verts(const ExtrusionLoop& extrusion_loop, float print_z, const Point& copy, GLVolume& volume);
+ static void extrusionentity_to_verts(const ExtrusionMultiPath& extrusion_multi_path, float print_z, const Point& copy, GLVolume& volume);
+ static void extrusionentity_to_verts(const ExtrusionEntityCollection& extrusion_entity_collection, float print_z, const Point& copy, GLVolume& volume);
+ static void extrusionentity_to_verts(const ExtrusionEntity* extrusion_entity, float print_z, const Point& copy, GLVolume& volume);
+ static void polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume);
+ static void point3_to_verts(const Vec3crd& point, double width, double height, GLVolume& volume);
};
}
diff --git a/xs/src/slic3r/GUI/AboutDialog.cpp b/xs/src/slic3r/GUI/AboutDialog.cpp
new file mode 100644
index 000000000..0fed8d175
--- /dev/null
+++ b/xs/src/slic3r/GUI/AboutDialog.cpp
@@ -0,0 +1,136 @@
+#include "AboutDialog.hpp"
+
+#include "../../libslic3r/Utils.hpp"
+
+namespace Slic3r {
+namespace GUI {
+
+AboutDialogLogo::AboutDialogLogo(wxWindow* parent)
+ : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize)
+{
+ this->SetBackgroundColour(*wxWHITE);
+ this->logo = wxBitmap(from_u8(Slic3r::var("Slic3r_192px.png")), wxBITMAP_TYPE_PNG);
+ this->SetMinSize(this->logo.GetSize());
+
+ this->Bind(wxEVT_PAINT, &AboutDialogLogo::onRepaint, this);
+}
+
+void AboutDialogLogo::onRepaint(wxEvent &event)
+{
+ wxPaintDC dc(this);
+ dc.SetBackgroundMode(wxTRANSPARENT);
+
+ wxSize size = this->GetSize();
+ int logo_w = this->logo.GetWidth();
+ int logo_h = this->logo.GetHeight();
+ dc.DrawBitmap(this->logo, (size.GetWidth() - logo_w)/2, (size.GetHeight() - logo_h)/2, true);
+
+ event.Skip();
+}
+
+AboutDialog::AboutDialog()
+ : wxDialog(NULL, wxID_ANY, _(L("About Slic3r")), wxDefaultPosition, wxDefaultSize, wxCAPTION)
+{
+ wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
+ SetBackgroundColour(bgr_clr);
+ wxBoxSizer* hsizer = new wxBoxSizer(wxHORIZONTAL);
+
+ auto main_sizer = new wxBoxSizer(wxVERTICAL);
+ main_sizer->Add(hsizer, 0, wxEXPAND | wxALL, 20);
+
+ // logo
+ wxBitmap logo_bmp = wxBitmap(from_u8(Slic3r::var("Slic3r_192px.png")), wxBITMAP_TYPE_PNG);
+ auto *logo = new wxStaticBitmap(this, wxID_ANY, std::move(logo_bmp));
+ hsizer->Add(logo, 1, wxALIGN_CENTRE_VERTICAL | wxEXPAND | wxTOP | wxBOTTOM, 35);
+
+ wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL);
+#ifdef __WXMSW__
+ int proportion = 2;
+#else
+ int proportion = 3;
+#endif
+ hsizer->Add(vsizer, proportion, wxEXPAND|wxLEFT, 20);
+
+ // title
+ {
+ wxStaticText* title = new wxStaticText(this, wxID_ANY, "Slic3r Prusa Edition", wxDefaultPosition, wxDefaultSize);
+ wxFont title_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ title_font.SetWeight(wxFONTWEIGHT_BOLD);
+ title_font.SetFamily(wxFONTFAMILY_ROMAN);
+ title_font.SetPointSize(24);
+ title->SetFont(title_font);
+ vsizer->Add(title, 0, wxALIGN_LEFT | wxTOP, 10);
+ }
+
+ // version
+ {
+ auto version_string = _(L("Version"))+ " " + std::string(SLIC3R_VERSION);
+ wxStaticText* version = new wxStaticText(this, wxID_ANY, version_string.c_str(), wxDefaultPosition, wxDefaultSize);
+ wxFont version_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ #ifdef __WXMSW__
+ version_font.SetPointSize(9);
+ #else
+ version_font.SetPointSize(11);
+ #endif
+ version->SetFont(version_font);
+ vsizer->Add(version, 0, wxALIGN_LEFT | wxBOTTOM, 10);
+ }
+
+ // text
+ wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO/*NEVER*/);
+ {
+ wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
+ auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
+ auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
+
+ const int fs = font.GetPointSize()-1;
+ int size[] = {fs,fs,fs,fs,fs,fs,fs};
+ html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
+ html->SetBorders(2);
+ const auto text = wxString::Format(
+ "<html>"
+ "<body bgcolor= %s link= %s>"
+ "<font color=%s>"
+ "Copyright &copy; 2016-2018 Prusa Research. <br />"
+ "Copyright &copy; 2011-2017 Alessandro Ranellucci. <br />"
+ "<a href=\"http://slic3r.org/\">Slic3r</a> is licensed under the "
+ "<a href=\"http://www.gnu.org/licenses/agpl-3.0.html\">GNU Affero General Public License, version 3</a>."
+ "<br /><br />"
+ "Contributions by Henrik Brix Andersen, Nicolas Dandrimont, Mark Hindess, Petr Ledvina, Joseph Lenox, Y. Sapir, Mike Sheldrake, Vojtech Bubnik and numerous others. "
+ "Manual by Gary Hodgson. Inspired by the RepRap community. <br />"
+ "Slic3r logo designed by Corey Daniels, <a href=\"http://www.famfamfam.com/lab/icons/silk/\">Silk Icon Set</a> designed by Mark James. "
+ "</font>"
+ "</body>"
+ "</html>", bgr_clr_str, text_clr_str, text_clr_str);
+ html->SetPage(text);
+ vsizer->Add(html, 1, wxEXPAND | wxBOTTOM, 10);
+ html->Bind(wxEVT_HTML_LINK_CLICKED, &AboutDialog::onLinkClicked, this);
+ }
+
+ wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE);
+ this->SetEscapeId(wxID_CLOSE);
+ this->Bind(wxEVT_BUTTON, &AboutDialog::onCloseDialog, this, wxID_CLOSE);
+ vsizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3);
+
+ this->Bind(wxEVT_LEFT_DOWN, &AboutDialog::onCloseDialog, this);
+ logo->Bind(wxEVT_LEFT_DOWN, &AboutDialog::onCloseDialog, this);
+
+ SetSizer(main_sizer);
+ main_sizer->SetSizeHints(this);
+}
+
+void AboutDialog::onLinkClicked(wxHtmlLinkEvent &event)
+{
+ wxLaunchDefaultBrowser(event.GetLinkInfo().GetHref());
+ event.Skip(false);
+}
+
+void AboutDialog::onCloseDialog(wxEvent &)
+{
+ this->EndModal(wxID_CLOSE);
+ this->Close();
+}
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/AboutDialog.hpp b/xs/src/slic3r/GUI/AboutDialog.hpp
new file mode 100644
index 000000000..01f7564c5
--- /dev/null
+++ b/xs/src/slic3r/GUI/AboutDialog.hpp
@@ -0,0 +1,36 @@
+#ifndef slic3r_GUI_AboutDialog_hpp_
+#define slic3r_GUI_AboutDialog_hpp_
+
+#include "GUI.hpp"
+
+#include <wx/wx.h>
+#include <wx/intl.h>
+#include <wx/html/htmlwin.h>
+
+namespace Slic3r {
+namespace GUI {
+
+class AboutDialogLogo : public wxPanel
+{
+public:
+ AboutDialogLogo(wxWindow* parent);
+
+private:
+ wxBitmap logo;
+ void onRepaint(wxEvent &event);
+};
+
+class AboutDialog : public wxDialog
+{
+public:
+ AboutDialog();
+
+private:
+ void onLinkClicked(wxHtmlLinkEvent &event);
+ void onCloseDialog(wxEvent &);
+};
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif
diff --git a/xs/src/slic3r/GUI/AppConfig.cpp b/xs/src/slic3r/GUI/AppConfig.cpp
index 99339e2f3..0f77b1953 100644
--- a/xs/src/slic3r/GUI/AppConfig.cpp
+++ b/xs/src/slic3r/GUI/AppConfig.cpp
@@ -1,5 +1,3 @@
-#include <GL/glew.h>
-
#include "../../libslic3r/libslic3r.h"
#include "../../libslic3r/Utils.hpp"
#include "AppConfig.hpp"
@@ -9,15 +7,22 @@
#include <string.h>
#include <utility>
#include <assert.h>
+#include <vector>
+#include <stdexcept>
#include <boost/filesystem.hpp>
#include <boost/nowide/cenv.hpp>
#include <boost/nowide/fstream.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/ptree.hpp>
+#include <boost/algorithm/string/predicate.hpp>
namespace Slic3r {
+static const std::string VENDOR_PREFIX = "vendor:";
+static const std::string MODEL_PREFIX = "model:";
+static const std::string VERSION_CHECK_URL = "https://raw.githubusercontent.com/prusa3d/Slic3r-settings/master/live/Slic3rPE.version";
+
void AppConfig::reset()
{
m_storage.clear();
@@ -42,13 +47,19 @@ void AppConfig::set_defaults()
set("no_defaults", "1");
if (get("show_incompatible_presets").empty())
set("show_incompatible_presets", "0");
- // Version check is enabled by default in the config, but it is not implemented yet.
+
if (get("version_check").empty())
set("version_check", "1");
+ if (get("preset_update").empty())
+ set("preset_update", "1");
+
// Use OpenGL 1.1 even if OpenGL 2.0 is available. This is mainly to support some buggy Intel HD Graphics drivers.
// https://github.com/prusa3d/Slic3r/issues/233
if (get("use_legacy_opengl").empty())
set("use_legacy_opengl", "0");
+
+ if (get("remember_output_path").empty())
+ set("remember_output_path", "1");
}
void AppConfig::load()
@@ -67,6 +78,19 @@ void AppConfig::load()
if (! data.empty())
// If there is a non-empty data, then it must be a top-level (without a section) config entry.
m_storage[""][section.first] = data;
+ } else if (boost::starts_with(section.first, VENDOR_PREFIX)) {
+ // This is a vendor section listing enabled model / variants
+ const auto vendor_name = section.first.substr(VENDOR_PREFIX.size());
+ auto &vendor = m_vendors[vendor_name];
+ for (const auto &kvp : section.second) {
+ if (! boost::starts_with(kvp.first, MODEL_PREFIX)) { continue; }
+ const auto model_name = kvp.first.substr(MODEL_PREFIX.size());
+ std::vector<std::string> variants;
+ if (! unescape_strings_cstyle(kvp.second.data(), variants)) { continue; }
+ for (const auto &variant : variants) {
+ vendor[model_name].insert(variant);
+ }
+ }
} else {
// This must be a section name. Read the entries of a section.
std::map<std::string, std::string> &storage = m_storage[section.first];
@@ -75,6 +99,17 @@ void AppConfig::load()
}
}
+ // Figure out if datadir has legacy presets
+ auto ini_ver = Semver::parse(get("version"));
+ m_legacy_datadir = false;
+ if (ini_ver) {
+ m_orig_version = *ini_ver;
+ // Make 1.40.0 alphas compare well
+ ini_ver->set_metadata(boost::none);
+ ini_ver->set_prerelease(boost::none);
+ m_legacy_datadir = ini_ver < Semver(1, 40, 0);
+ }
+
// Override missing or keys with their defaults.
this->set_defaults();
m_dirty = false;
@@ -96,10 +131,57 @@ void AppConfig::save()
for (const std::pair<std::string, std::string> &kvp : category.second)
c << kvp.first << " = " << kvp.second << std::endl;
}
+ // Write vendor sections
+ for (const auto &vendor : m_vendors) {
+ size_t size_sum = 0;
+ for (const auto &model : vendor.second) { size_sum += model.second.size(); }
+ if (size_sum == 0) { continue; }
+
+ c << std::endl << "[" << VENDOR_PREFIX << vendor.first << "]" << std::endl;
+
+ for (const auto &model : vendor.second) {
+ if (model.second.size() == 0) { continue; }
+ const std::vector<std::string> variants(model.second.begin(), model.second.end());
+ const auto escaped = escape_strings_cstyle(variants);
+ c << MODEL_PREFIX << model.first << " = " << escaped << std::endl;
+ }
+ }
c.close();
m_dirty = false;
}
+bool AppConfig::get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const
+{
+ const auto it_v = m_vendors.find(vendor);
+ if (it_v == m_vendors.end()) { return false; }
+ const auto it_m = it_v->second.find(model);
+ return it_m == it_v->second.end() ? false : it_m->second.find(variant) != it_m->second.end();
+}
+
+void AppConfig::set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable)
+{
+ if (enable) {
+ if (get_variant(vendor, model, variant)) { return; }
+ m_vendors[vendor][model].insert(variant);
+ } else {
+ auto it_v = m_vendors.find(vendor);
+ if (it_v == m_vendors.end()) { return; }
+ auto it_m = it_v->second.find(model);
+ if (it_m == it_v->second.end()) { return; }
+ auto it_var = it_m->second.find(variant);
+ if (it_var == it_m->second.end()) { return; }
+ it_m->second.erase(it_var);
+ }
+ // If we got here, there was an update
+ m_dirty = true;
+}
+
+void AppConfig::set_vendors(const AppConfig &from)
+{
+ m_vendors = from.m_vendors;
+ m_dirty = true;
+}
+
std::string AppConfig::get_last_dir() const
{
const auto it = m_storage.find("recent");
@@ -145,11 +227,29 @@ void AppConfig::update_last_output_dir(const std::string &dir)
this->set("", "last_output_path", dir);
}
+void AppConfig::reset_selections()
+{
+ auto it = m_storage.find("presets");
+ if (it != m_storage.end()) {
+ it->second.erase("print");
+ it->second.erase("filament");
+ it->second.erase("sla_material");
+ it->second.erase("printer");
+ m_dirty = true;
+ }
+}
+
std::string AppConfig::config_path()
{
return (boost::filesystem::path(Slic3r::data_dir()) / "slic3r.ini").make_preferred().string();
}
+std::string AppConfig::version_check_url() const
+{
+ auto from_settings = get("version_check_url");
+ return from_settings.empty() ? VERSION_CHECK_URL : from_settings;
+}
+
bool AppConfig::exists()
{
return boost::filesystem::exists(AppConfig::config_path());
diff --git a/xs/src/slic3r/GUI/AppConfig.hpp b/xs/src/slic3r/GUI/AppConfig.hpp
index c6d7766a4..b742176ed 100644
--- a/xs/src/slic3r/GUI/AppConfig.hpp
+++ b/xs/src/slic3r/GUI/AppConfig.hpp
@@ -1,15 +1,25 @@
#ifndef slic3r_AppConfig_hpp_
#define slic3r_AppConfig_hpp_
+#include <set>
#include <map>
#include <string>
+#include "libslic3r/Config.hpp"
+#include "slic3r/Utils/Semver.hpp"
+
namespace Slic3r {
class AppConfig
{
public:
- AppConfig() : m_dirty(false) { this->reset(); }
+ AppConfig() :
+ m_dirty(false),
+ m_orig_version(Semver::invalid()),
+ m_legacy_datadir(false)
+ {
+ this->reset();
+ }
// Clear and reset to defaults.
void reset();
@@ -65,6 +75,14 @@ public:
void clear_section(const std::string &section)
{ m_storage[section].clear(); }
+ typedef std::map<std::string, std::map<std::string, std::set<std::string>>> VendorMap;
+ bool get_variant(const std::string &vendor, const std::string &model, const std::string &variant) const;
+ void set_variant(const std::string &vendor, const std::string &model, const std::string &variant, bool enable);
+ void set_vendors(const AppConfig &from);
+ void set_vendors(const VendorMap &vendors) { m_vendors = vendors; m_dirty = true; }
+ void set_vendors(VendorMap &&vendors) { m_vendors = std::move(vendors); m_dirty = true; }
+ const VendorMap& vendors() const { return m_vendors; }
+
// return recent/skein_directory or recent/config_directory or empty string.
std::string get_last_dir() const;
void update_config_dir(const std::string &dir);
@@ -73,17 +91,40 @@ public:
std::string get_last_output_dir(const std::string &alt) const;
void update_last_output_dir(const std::string &dir);
+ // reset the current print / filament / printer selections, so that
+ // the PresetBundle::load_selections(const AppConfig &config) call will select
+ // the first non-default preset when called.
+ void reset_selections();
+
// Get the default config path from Slic3r::data_dir().
static std::string config_path();
+ // Returns true if the user's data directory comes from before Slic3r 1.40.0 (no updating)
+ bool legacy_datadir() const { return m_legacy_datadir; }
+ void set_legacy_datadir(bool value) { m_legacy_datadir = value; }
+
+ // Get the Slic3r version check url.
+ // This returns a hardcoded string unless it is overriden by "version_check_url" in the ini file.
+ std::string version_check_url() const;
+
+ // Returns the original Slic3r version found in the ini file before it was overwritten
+ // by the current version
+ Semver orig_version() const { return m_orig_version; }
+
// Does the config file exist?
static bool exists();
private:
// Map of section, name -> value
std::map<std::string, std::map<std::string, std::string>> m_storage;
+ // Map of enabled vendors / models / variants
+ VendorMap m_vendors;
// Has any value been modified since the config.ini has been last saved or loaded?
bool m_dirty;
+ // Original version found in the ini file before it was overwritten
+ Semver m_orig_version;
+ // Whether the existing version is before system profiles & configuration updating
+ bool m_legacy_datadir;
};
}; // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/xs/src/slic3r/GUI/BackgroundSlicingProcess.cpp
index 32cc07f15..47da3367c 100644
--- a/xs/src/slic3r/GUI/BackgroundSlicingProcess.cpp
+++ b/xs/src/slic3r/GUI/BackgroundSlicingProcess.cpp
@@ -1,11 +1,12 @@
#include "BackgroundSlicingProcess.hpp"
#include "GUI.hpp"
-#include "../../libslic3r/Print.hpp"
-
#include <wx/event.h>
#include <wx/panel.h>
+// Print now includes tbb, and tbb includes Windows. This breaks compilation of wxWidgets if included before wx.
+#include "../../libslic3r/Print.hpp"
+
//#undef NDEBUG
#include <cassert>
#include <stdexcept>
diff --git a/xs/src/slic3r/GUI/BedShapeDialog.cpp b/xs/src/slic3r/GUI/BedShapeDialog.cpp
index 51dbd6a27..e04f2b370 100644
--- a/xs/src/slic3r/GUI/BedShapeDialog.cpp
+++ b/xs/src/slic3r/GUI/BedShapeDialog.cpp
@@ -9,6 +9,8 @@
#include "Model.hpp"
#include "boost/nowide/iostream.hpp"
+#include <algorithm>
+
namespace Slic3r {
namespace GUI {
@@ -34,7 +36,7 @@ void BedShapeDialog::build_dialog(ConfigOptionPoints* default_pt)
void BedShapePanel::build_panel(ConfigOptionPoints* default_pt)
{
-// on_change(nullptr);
+// on_change(nullptr);
auto box = new wxStaticBox(this, wxID_ANY, _(L("Shape")));
auto sbsizer = new wxStaticBoxSizer(box, wxVERTICAL);
@@ -46,14 +48,14 @@ void BedShapePanel::build_panel(ConfigOptionPoints* default_pt)
auto optgroup = init_shape_options_page(_(L("Rectangular")));
ConfigOptionDef def;
def.type = coPoints;
- def.default_value = new ConfigOptionPoints{ Pointf(200, 200) };
+ def.default_value = new ConfigOptionPoints{ Vec2d(200, 200) };
def.label = L("Size");
def.tooltip = L("Size in X and Y of the rectangular plate.");
Option option(def, "rect_size");
optgroup->append_single_option_line(option);
def.type = coPoints;
- def.default_value = new ConfigOptionPoints{ Pointf(0, 0) };
+ def.default_value = new ConfigOptionPoints{ Vec2d(0, 0) };
def.label = L("Origin");
def.tooltip = L("Distance of the 0,0 G-code coordinate from the front left corner of the rectangle.");
option = Option(def, "rect_origin");
@@ -146,25 +148,22 @@ void BedShapePanel::set_shape(ConfigOptionPoints* points)
if (lines[0].parallel_to(lines[2]) && lines[1].parallel_to(lines[3])) {
// okay, it's a rectangle
// find origin
- // the || 0 hack prevents "-0" which might confuse the user
- int x_min, x_max, y_min, y_max;
- x_max = x_min = points->values[0].x;
- y_max = y_min = points->values[0].y;
- for (auto pt : points->values){
- if (x_min > pt.x) x_min = pt.x;
- if (x_max < pt.x) x_max = pt.x;
- if (y_min > pt.y) y_min = pt.y;
- if (y_max < pt.y) y_max = pt.y;
- }
- if (x_min < 0) x_min = 0;
- if (x_max < 0) x_max = 0;
- if (y_min < 0) y_min = 0;
- if (y_max < 0) y_max = 0;
- auto origin = new ConfigOptionPoints{ Pointf(-x_min, -y_min) };
+ coordf_t x_min, x_max, y_min, y_max;
+ x_max = x_min = points->values[0](0);
+ y_max = y_min = points->values[0](1);
+ for (auto pt : points->values)
+ {
+ x_min = std::min(x_min, pt(0));
+ x_max = std::max(x_max, pt(0));
+ y_min = std::min(y_min, pt(1));
+ y_max = std::max(y_max, pt(1));
+ }
+
+ auto origin = new ConfigOptionPoints{ Vec2d(-x_min, -y_min) };
m_shape_options_book->SetSelection(SHAPE_RECTANGULAR);
auto optgroup = m_optgroups[SHAPE_RECTANGULAR];
- optgroup->set_value("rect_size", new ConfigOptionPoints{ Pointf(x_max - x_min, y_max - y_min) });//[x_max - x_min, y_max - y_min]);
+ optgroup->set_value("rect_size", new ConfigOptionPoints{ Vec2d(x_max - x_min, y_max - y_min) });//[x_max - x_min, y_max - y_min]);
optgroup->set_value("rect_origin", origin);
update_shape();
return;
@@ -179,11 +178,12 @@ void BedShapePanel::set_shape(ConfigOptionPoints* points)
double avg_dist = 0;
for (auto pt: polygon.points)
{
- double distance = center.distance_to(pt);
+ double distance = (pt - center).cast<double>().norm();
vertex_distances.push_back(distance);
avg_dist += distance;
}
-
+
+ avg_dist /= vertex_distances.size();
bool defined_value = true;
for (auto el: vertex_distances)
{
@@ -195,7 +195,7 @@ void BedShapePanel::set_shape(ConfigOptionPoints* points)
// all vertices are equidistant to center
m_shape_options_book->SetSelection(SHAPE_CIRCULAR);
auto optgroup = m_optgroups[SHAPE_CIRCULAR];
- boost::any ret = wxNumberFormatter::ToString(unscale(avg_dist * 2), 0);
+ boost::any ret = wxNumberFormatter::ToString(unscale<double>(avg_dist * 2), 0);
optgroup->set_value("diameter", ret);
update_shape();
return;
@@ -206,8 +206,8 @@ void BedShapePanel::set_shape(ConfigOptionPoints* points)
// Invalid polygon.Revert to default bed dimensions.
m_shape_options_book->SetSelection(SHAPE_RECTANGULAR);
auto optgroup = m_optgroups[SHAPE_RECTANGULAR];
- optgroup->set_value("rect_size", new ConfigOptionPoints{ Pointf(200, 200) });
- optgroup->set_value("rect_origin", new ConfigOptionPoints{ Pointf(0, 0) });
+ optgroup->set_value("rect_size", new ConfigOptionPoints{ Vec2d(200, 200) });
+ optgroup->set_value("rect_origin", new ConfigOptionPoints{ Vec2d(0, 0) });
update_shape();
return;
}
@@ -230,19 +230,21 @@ void BedShapePanel::update_shape()
{
auto page_idx = m_shape_options_book->GetSelection();
if (page_idx == SHAPE_RECTANGULAR) {
- Pointf rect_size, rect_origin;
+ Vec2d rect_size(Vec2d::Zero());
+ Vec2d rect_origin(Vec2d::Zero());
try{
- rect_size = boost::any_cast<Pointf>(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_size")); }
+ rect_size = boost::any_cast<Vec2d>(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_size")); }
catch (const std::exception &e){
- return;}
+ return;
+ }
try{
- rect_origin = boost::any_cast<Pointf>(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_origin"));
+ rect_origin = boost::any_cast<Vec2d>(m_optgroups[SHAPE_RECTANGULAR]->get_value("rect_origin"));
}
catch (const std::exception &e){
return;}
- auto x = rect_size.x;
- auto y = rect_size.y;
+ auto x = rect_size(0);
+ auto y = rect_size(1);
// empty strings or '-' or other things
if (x == 0 || y == 0) return;
double x0 = 0.0;
@@ -250,17 +252,17 @@ void BedShapePanel::update_shape()
double x1 = x;
double y1 = y;
- auto dx = rect_origin.x;
- auto dy = rect_origin.y;
+ auto dx = rect_origin(0);
+ auto dy = rect_origin(1);
x0 -= dx;
x1 -= dx;
y0 -= dy;
y1 -= dy;
- m_canvas->m_bed_shape = { Pointf(x0, y0),
- Pointf(x1, y0),
- Pointf(x1, y1),
- Pointf(x0, y1)};
+ m_canvas->m_bed_shape = { Vec2d(x0, y0),
+ Vec2d(x1, y0),
+ Vec2d(x1, y1),
+ Vec2d(x0, y1)};
}
else if(page_idx == SHAPE_CIRCULAR) {
double diameter;
@@ -274,10 +276,10 @@ void BedShapePanel::update_shape()
auto r = diameter / 2;
auto twopi = 2 * PI;
auto edges = 60;
- std::vector<Pointf> points;
+ std::vector<Vec2d> points;
for (size_t i = 1; i <= 60; ++i){
auto angle = i * twopi / edges;
- points.push_back(Pointf(r*cos(angle), r*sin(angle)));
+ points.push_back(Vec2d(r*cos(angle), r*sin(angle)));
}
m_canvas->m_bed_shape = points;
}
@@ -330,9 +332,9 @@ void BedShapePanel::load_stl()
}
auto polygon = expolygons[0].contour;
- std::vector<Pointf> points;
+ std::vector<Vec2d> points;
for (auto pt : polygon.points)
- points.push_back(Pointf::new_unscale(pt));
+ points.push_back(unscale(pt));
m_canvas->m_bed_shape = points;
update_preview();
}
diff --git a/xs/src/slic3r/GUI/BedShapeDialog.hpp b/xs/src/slic3r/GUI/BedShapeDialog.hpp
index f4614c342..d8ba5a912 100644
--- a/xs/src/slic3r/GUI/BedShapeDialog.hpp
+++ b/xs/src/slic3r/GUI/BedShapeDialog.hpp
@@ -1,3 +1,5 @@
+#ifndef slic3r_BedShapeDialog_hpp_
+#define slic3r_BedShapeDialog_hpp_
// The bed shape dialog.
// The dialog opens from Print Settins tab->Bed Shape : Set...
@@ -32,7 +34,7 @@ public:
void load_stl();
// Returns the resulting bed shape polygon. This value will be stored to the ini file.
- std::vector<Pointf> GetValue() { return m_canvas->m_bed_shape; }
+ std::vector<Vec2d> GetValue() { return m_canvas->m_bed_shape; }
};
class BedShapeDialog : public wxDialog
@@ -44,8 +46,11 @@ public:
~BedShapeDialog(){ }
void build_dialog(ConfigOptionPoints* default_pt);
- std::vector<Pointf> GetValue() { return m_panel->GetValue(); }
+ std::vector<Vec2d> GetValue() { return m_panel->GetValue(); }
};
} // GUI
} // Slic3r
+
+
+#endif /* slic3r_BedShapeDialog_hpp_ */
diff --git a/xs/src/slic3r/GUI/BitmapCache.cpp b/xs/src/slic3r/GUI/BitmapCache.cpp
new file mode 100644
index 000000000..93853458e
--- /dev/null
+++ b/xs/src/slic3r/GUI/BitmapCache.cpp
@@ -0,0 +1,172 @@
+#include "BitmapCache.hpp"
+
+#if ! defined(WIN32) && ! defined(__APPLE__)
+#define BROKEN_ALPHA
+#endif
+
+#ifdef BROKEN_ALPHA
+ #include <wx/mstream.h>
+ #include <wx/rawbmp.h>
+#endif /* BROKEN_ALPHA */
+
+namespace Slic3r { namespace GUI {
+
+void BitmapCache::clear()
+{
+ for (std::pair<const std::string, wxBitmap*> &bitmap : m_map)
+ delete bitmap.second;
+}
+
+static wxBitmap wxImage_to_wxBitmap_with_alpha(wxImage &&image)
+{
+#ifdef BROKEN_ALPHA
+ wxMemoryOutputStream stream;
+ image.SaveFile(stream, wxBITMAP_TYPE_PNG);
+ wxStreamBuffer *buf = stream.GetOutputStreamBuffer();
+ return wxBitmap::NewFromPNGData(buf->GetBufferStart(), buf->GetBufferSize());
+#else
+ return wxBitmap(std::move(image));
+#endif
+}
+
+wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_t height)
+{
+ wxBitmap *bitmap = nullptr;
+ auto it = m_map.find(bitmap_key);
+ if (it == m_map.end()) {
+ bitmap = new wxBitmap(width, height);
+ m_map[bitmap_key] = bitmap;
+ } else {
+ bitmap = it->second;
+ if (bitmap->GetWidth() != width || bitmap->GetHeight() != height)
+ bitmap->Create(width, height);
+ }
+#ifndef BROKEN_ALPHA
+ bitmap->UseAlpha();
+#endif
+ return bitmap;
+}
+
+wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp)
+{
+ wxBitmap *bitmap = nullptr;
+ auto it = m_map.find(bitmap_key);
+ if (it == m_map.end()) {
+ bitmap = new wxBitmap(bmp);
+ m_map[bitmap_key] = bitmap;
+ } else {
+ bitmap = it->second;
+ *bitmap = bmp;
+ }
+ return bitmap;
+}
+
+wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp, const wxBitmap &bmp2)
+{
+ // Copying the wxBitmaps is cheap as the bitmap's content is reference counted.
+ const wxBitmap bmps[2] = { bmp, bmp2 };
+ return this->insert(bitmap_key, bmps, bmps + 2);
+}
+
+wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3)
+{
+ // Copying the wxBitmaps is cheap as the bitmap's content is reference counted.
+ const wxBitmap bmps[3] = { bmp, bmp2, bmp3 };
+ return this->insert(bitmap_key, bmps, bmps + 3);
+}
+
+wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *begin, const wxBitmap *end)
+{
+ size_t width = 0;
+ size_t height = 0;
+ for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
+ width += bmp->GetWidth();
+ height = std::max<size_t>(height, bmp->GetHeight());
+ }
+
+#ifdef BROKEN_ALPHA
+
+ wxImage image(width, height);
+ image.InitAlpha();
+ // Fill in with a white color.
+ memset(image.GetData(), 0x0ff, width * height * 3);
+ // Fill in with full transparency.
+ memset(image.GetAlpha(), 0, width * height);
+ size_t x = 0;
+ for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
+ if (bmp->GetWidth() > 0) {
+ if (bmp->GetDepth() == 32) {
+ wxAlphaPixelData data(*const_cast<wxBitmap*>(bmp));
+ data.UseAlpha();
+ if (data) {
+ for (int r = 0; r < bmp->GetHeight(); ++ r) {
+ wxAlphaPixelData::Iterator src(data);
+ src.Offset(data, 0, r);
+ unsigned char *dst_pixels = image.GetData() + (x + r * width) * 3;
+ unsigned char *dst_alpha = image.GetAlpha() + x + r * width;
+ for (int c = 0; c < bmp->GetWidth(); ++ c, ++ src) {
+ *dst_pixels ++ = src.Red();
+ *dst_pixels ++ = src.Green();
+ *dst_pixels ++ = src.Blue();
+ *dst_alpha ++ = src.Alpha();
+ }
+ }
+ }
+ } else if (bmp->GetDepth() == 24) {
+ wxNativePixelData data(*const_cast<wxBitmap*>(bmp));
+ if (data) {
+ for (int r = 0; r < bmp->GetHeight(); ++ r) {
+ wxNativePixelData::Iterator src(data);
+ src.Offset(data, 0, r);
+ unsigned char *dst_pixels = image.GetData() + (x + r * width) * 3;
+ unsigned char *dst_alpha = image.GetAlpha() + x + r * width;
+ for (int c = 0; c < bmp->GetWidth(); ++ c, ++ src) {
+ *dst_pixels ++ = src.Red();
+ *dst_pixels ++ = src.Green();
+ *dst_pixels ++ = src.Blue();
+ *dst_alpha ++ = wxALPHA_OPAQUE;
+ }
+ }
+ }
+ }
+ }
+ x += bmp->GetWidth();
+ }
+ return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image)));
+
+#else
+
+ wxBitmap *bitmap = this->insert(bitmap_key, width, height);
+ wxMemoryDC memDC;
+ memDC.SelectObject(*bitmap);
+ memDC.SetBackground(*wxTRANSPARENT_BRUSH);
+ memDC.Clear();
+ size_t x = 0;
+ for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
+ if (bmp->GetWidth() > 0)
+ memDC.DrawBitmap(*bmp, x, 0, true);
+ x += bmp->GetWidth();
+ }
+ memDC.SelectObject(wxNullBitmap);
+ return bitmap;
+
+#endif
+}
+
+wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency)
+{
+ wxImage image(width, height);
+ image.InitAlpha();
+ unsigned char* imgdata = image.GetData();
+ unsigned char* imgalpha = image.GetAlpha();
+ for (size_t i = 0; i < width * height; ++ i) {
+ *imgdata ++ = r;
+ *imgdata ++ = g;
+ *imgdata ++ = b;
+ *imgalpha ++ = transparency;
+ }
+ return wxImage_to_wxBitmap_with_alpha(std::move(image));
+}
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/BitmapCache.hpp b/xs/src/slic3r/GUI/BitmapCache.hpp
new file mode 100644
index 000000000..bec9a7ad2
--- /dev/null
+++ b/xs/src/slic3r/GUI/BitmapCache.hpp
@@ -0,0 +1,44 @@
+#ifndef SLIC3R_GUI_BITMAP_CACHE_HPP
+#define SLIC3R_GUI_BITMAP_CACHE_HPP
+
+#include <wx/wxprec.h>
+#ifndef WX_PRECOMP
+ #include <wx/wx.h>
+#endif
+
+#include "../../libslic3r/libslic3r.h"
+#include "../../libslic3r/Config.hpp"
+
+#include "GUI.hpp"
+
+namespace Slic3r { namespace GUI {
+
+class BitmapCache
+{
+public:
+ BitmapCache() {}
+ ~BitmapCache() { clear(); }
+ void clear();
+
+ wxBitmap* find(const std::string &name) { auto it = m_map.find(name); return (it == m_map.end()) ? nullptr : it->second; }
+ const wxBitmap* find(const std::string &name) const { return const_cast<BitmapCache*>(this)->find(name); }
+
+ wxBitmap* insert(const std::string &name, size_t width, size_t height);
+ wxBitmap* insert(const std::string &name, const wxBitmap &bmp);
+ wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2);
+ wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3);
+ wxBitmap* insert(const std::string &name, const std::vector<wxBitmap> &bmps) { return this->insert(name, &bmps.front(), &bmps.front() + bmps.size()); }
+ wxBitmap* insert(const std::string &name, const wxBitmap *begin, const wxBitmap *end);
+
+ static wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency);
+ static wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3]) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE); }
+ static wxBitmap mkclear(size_t width, size_t height) { return mksolid(width, height, 0, 0, 0, wxALPHA_TRANSPARENT); }
+
+private:
+ std::map<std::string, wxBitmap*> m_map;
+};
+
+} // GUI
+} // Slic3r
+
+#endif /* SLIC3R_GUI_BITMAP_CACHE_HPP */
diff --git a/xs/src/slic3r/GUI/BonjourDialog.cpp b/xs/src/slic3r/GUI/BonjourDialog.cpp
index 34fac9a91..11cfea642 100644
--- a/xs/src/slic3r/GUI/BonjourDialog.cpp
+++ b/xs/src/slic3r/GUI/BonjourDialog.cpp
@@ -191,7 +191,7 @@ void BonjourDialog::on_timer(wxTimerEvent &)
label->SetLabel(wxString::Format("%s %s", search_str, dots));
timer_state = (timer_state) % 3 + 1;
} else {
- label->SetLabel(wxString::Format("%s: %s", search_str, _(L("Finished."))));
+ label->SetLabel(wxString::Format("%s: %s", search_str, _(L("Finished"))+"."));
timer->Stop();
}
}
diff --git a/xs/src/slic3r/GUI/ButtonsDescription.cpp b/xs/src/slic3r/GUI/ButtonsDescription.cpp
new file mode 100644
index 000000000..5739fc90e
--- /dev/null
+++ b/xs/src/slic3r/GUI/ButtonsDescription.cpp
@@ -0,0 +1,84 @@
+#include "ButtonsDescription.hpp"
+#include <wx/sizer.h>
+#include <wx/stattext.h>
+#include <wx/statbmp.h>
+#include <wx/clrpicker.h>
+
+#include "GUI.hpp"
+
+namespace Slic3r {
+namespace GUI {
+
+ButtonsDescription::ButtonsDescription(wxWindow* parent, t_icon_descriptions* icon_descriptions) :
+ wxDialog(parent, wxID_ANY, _(L("Buttons And Text Colors Description")), wxDefaultPosition, wxDefaultSize),
+ m_icon_descriptions(icon_descriptions)
+{
+ auto grid_sizer = new wxFlexGridSizer(3, 20, 20);
+
+ auto main_sizer = new wxBoxSizer(wxVERTICAL);
+ main_sizer->Add(grid_sizer, 0, wxEXPAND | wxALL, 20);
+
+ // Icon description
+ for (auto pair : *m_icon_descriptions)
+ {
+ auto icon = new wxStaticBitmap(this, wxID_ANY, *pair.first);
+ grid_sizer->Add(icon, -1, wxALIGN_CENTRE_VERTICAL);
+
+ std::istringstream f(pair.second);
+ std::string s;
+ getline(f, s, ';');
+ auto description = new wxStaticText(this, wxID_ANY, _(s));
+ grid_sizer->Add(description, -1, wxALIGN_CENTRE_VERTICAL);
+ getline(f, s, ';');
+ description = new wxStaticText(this, wxID_ANY, _(s));
+ grid_sizer->Add(description, -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND);
+ }
+
+ // Text color description
+ auto sys_label = new wxStaticText(this, wxID_ANY, _(L("Value is the same as the system value")));
+ sys_label->SetForegroundColour(get_label_clr_sys());
+ auto sys_colour = new wxColourPickerCtrl(this, wxID_ANY, get_label_clr_sys());
+ sys_colour->Bind(wxEVT_COLOURPICKER_CHANGED, ([sys_colour, sys_label](wxCommandEvent e)
+ {
+ sys_label->SetForegroundColour(sys_colour->GetColour());
+ sys_label->Refresh();
+ }));
+ size_t t= 0;
+ while (t < 3){
+ grid_sizer->Add(new wxStaticText(this, wxID_ANY, ""), -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND);
+ ++t;
+ }
+ grid_sizer->Add(0, -1, wxALIGN_CENTRE_VERTICAL);
+ grid_sizer->Add(sys_colour, -1, wxALIGN_CENTRE_VERTICAL);
+ grid_sizer->Add(sys_label, -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND);
+
+ auto mod_label = new wxStaticText(this, wxID_ANY, _(L("Value was changed and is not equal to the system value or the last saved preset")));
+ mod_label->SetForegroundColour(get_label_clr_modified());
+ auto mod_colour = new wxColourPickerCtrl(this, wxID_ANY, get_label_clr_modified());
+ mod_colour->Bind(wxEVT_COLOURPICKER_CHANGED, ([mod_colour, mod_label](wxCommandEvent e)
+ {
+ mod_label->SetForegroundColour(mod_colour->GetColour());
+ mod_label->Refresh();
+ }));
+ grid_sizer->Add(0, -1, wxALIGN_CENTRE_VERTICAL);
+ grid_sizer->Add(mod_colour, -1, wxALIGN_CENTRE_VERTICAL);
+ grid_sizer->Add(mod_label, -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND);
+
+
+ auto buttons = CreateStdDialogButtonSizer(wxOK|wxCANCEL);
+ main_sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10);
+
+ wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this));
+ btn->Bind(wxEVT_BUTTON, [sys_colour, mod_colour, this](wxCommandEvent&) {
+ set_label_clr_sys(sys_colour->GetColour());
+ set_label_clr_modified(mod_colour->GetColour());
+ EndModal(wxID_OK);
+ });
+
+ SetSizer(main_sizer);
+ main_sizer->SetSizeHints(this);
+}
+
+} // GUI
+} // Slic3r
+
diff --git a/xs/src/slic3r/GUI/ButtonsDescription.hpp b/xs/src/slic3r/GUI/ButtonsDescription.hpp
new file mode 100644
index 000000000..4858eaaea
--- /dev/null
+++ b/xs/src/slic3r/GUI/ButtonsDescription.hpp
@@ -0,0 +1,27 @@
+#ifndef slic3r_ButtonsDescription_hpp
+#define slic3r_ButtonsDescription_hpp
+
+#include <wx/dialog.h>
+#include <vector>
+
+namespace Slic3r {
+namespace GUI {
+
+using t_icon_descriptions = std::vector<std::pair<wxBitmap*, std::string>>;
+
+class ButtonsDescription : public wxDialog
+{
+ t_icon_descriptions* m_icon_descriptions;
+public:
+ ButtonsDescription(wxWindow* parent, t_icon_descriptions* icon_descriptions);
+ ~ButtonsDescription(){}
+
+
+};
+
+} // GUI
+} // Slic3r
+
+
+#endif
+
diff --git a/xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp b/xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp
new file mode 100644
index 000000000..efcbf05bd
--- /dev/null
+++ b/xs/src/slic3r/GUI/ConfigSnapshotDialog.cpp
@@ -0,0 +1,140 @@
+#include "ConfigSnapshotDialog.hpp"
+
+#include "../Config/Snapshot.hpp"
+#include "../Utils/Time.hpp"
+
+#include "../../libslic3r/Utils.hpp"
+
+namespace Slic3r {
+namespace GUI {
+
+static wxString format_reason(const Config::Snapshot::Reason reason)
+{
+ switch (reason) {
+ case Config::Snapshot::SNAPSHOT_UPGRADE:
+ return wxString(_(L("Upgrade")));
+ case Config::Snapshot::SNAPSHOT_DOWNGRADE:
+ return wxString(_(L("Downgrade")));
+ case Config::Snapshot::SNAPSHOT_BEFORE_ROLLBACK:
+ return wxString(_(L("Before roll back")));
+ case Config::Snapshot::SNAPSHOT_USER:
+ return wxString(_(L("User")));
+ case Config::Snapshot::SNAPSHOT_UNKNOWN:
+ default:
+ return wxString(_(L("Unknown")));
+ }
+}
+
+static wxString generate_html_row(const Config::Snapshot &snapshot, bool row_even, bool snapshot_active)
+{
+ // Start by declaring a row with an alternating background color.
+ wxString text = "<tr bgcolor=\"";
+ text += snapshot_active ? "#B3FFCB" : (row_even ? "#FFFFFF" : "#D5D5D5");
+ text += "\">";
+ text += "<td>";
+ // Format the row header.
+ text += wxString("<font size=\"5\"><b>") + (snapshot_active ? _(L("Active: ")) : "") +
+ Utils::format_local_date_time(snapshot.time_captured) + ": " + format_reason(snapshot.reason);
+ if (! snapshot.comment.empty())
+ text += " (" + snapshot.comment + ")";
+ text += "</b></font><br>";
+ // End of row header.
+ text += _(L("slic3r version")) + ": " + snapshot.slic3r_version_captured.to_string() + "<br>";
+ text += _(L("print")) + ": " + snapshot.print + "<br>";
+ text += _(L("filaments")) + ": " + snapshot.filaments.front() + "<br>";
+ text += _(L("printer")) + ": " + snapshot.printer + "<br>";
+
+ bool compatible = true;
+ for (const Config::Snapshot::VendorConfig &vc : snapshot.vendor_configs) {
+ text += _(L("vendor")) + ": " + vc.name +", " + _(L("version")) + ": " + vc.version.config_version.to_string() +
+ ", " + _(L("min slic3r version")) + ": " + vc.version.min_slic3r_version.to_string();
+ if (vc.version.max_slic3r_version != Semver::inf())
+ text += ", " + _(L("max slic3r version")) + ": " + vc.version.max_slic3r_version.to_string();
+ text += "<br>";
+ for (const std::pair<std::string, std::set<std::string>> &model : vc.models_variants_installed) {
+ text += _(L("model")) + ": " + model.first + ", " + _(L("variants")) + ": ";
+ for (const std::string &variant : model.second) {
+ if (&variant != &*model.second.begin())
+ text += ", ";
+ text += variant;
+ }
+ text += "<br>";
+ }
+ if (! vc.version.is_current_slic3r_supported()) { compatible = false; }
+ }
+
+ if (! compatible) {
+ text += "<p align=\"right\">" + _(L("Incompatible with this Slic3r")) + "</p>";
+ }
+ else if (! snapshot_active)
+ text += "<p align=\"right\"><a href=\"" + snapshot.id + "\">" + _(L("Activate")) + "</a></p>";
+ text += "</td>";
+ text += "</tr>";
+ return text;
+}
+
+static wxString generate_html_page(const Config::SnapshotDB &snapshot_db, const wxString &on_snapshot)
+{
+ wxString text =
+ "<html>"
+ "<body bgcolor=\"#ffffff\" cellspacing=\"2\" cellpadding=\"0\" border=\"0\" link=\"#800000\">"
+ "<font color=\"#000000\">";
+ text += "<table style=\"width:100%\">";
+ for (size_t i_row = 0; i_row < snapshot_db.snapshots().size(); ++ i_row) {
+ const Config::Snapshot &snapshot = snapshot_db.snapshots()[snapshot_db.snapshots().size() - i_row - 1];
+ text += generate_html_row(snapshot, i_row & 1, snapshot.id == on_snapshot);
+ }
+ text +=
+ "</table>"
+ "</font>"
+ "</body>"
+ "</html>";
+ return text;
+}
+
+ConfigSnapshotDialog::ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db, const wxString &on_snapshot)
+ : wxDialog(NULL, wxID_ANY, _(L("Configuration Snapshots")), wxDefaultPosition, wxSize(600, 500), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX)
+{
+ this->SetBackgroundColour(*wxWHITE);
+
+ wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL);
+ this->SetSizer(vsizer);
+
+ // text
+ wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO);
+ {
+ wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ #ifdef __WXMSW__
+ int size[] = {8,8,8,8,11,11,11};
+ #else
+ int size[] = {11,11,11,11,14,14,14};
+ #endif
+ html->SetFonts(font.GetFaceName(), font.GetFaceName(), size);
+ html->SetBorders(2);
+ wxString text = generate_html_page(snapshot_db, on_snapshot);
+ html->SetPage(text);
+ vsizer->Add(html, 1, wxEXPAND | wxALIGN_LEFT | wxRIGHT | wxBOTTOM, 0);
+ html->Bind(wxEVT_HTML_LINK_CLICKED, &ConfigSnapshotDialog::onLinkClicked, this);
+ }
+
+ wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxCLOSE);
+ this->SetEscapeId(wxID_CLOSE);
+ this->Bind(wxEVT_BUTTON, &ConfigSnapshotDialog::onCloseDialog, this, wxID_CLOSE);
+ vsizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, 3);
+}
+
+void ConfigSnapshotDialog::onLinkClicked(wxHtmlLinkEvent &event)
+{
+ m_snapshot_to_activate = event.GetLinkInfo().GetHref();
+ this->EndModal(wxID_CLOSE);
+ this->Close();
+}
+
+void ConfigSnapshotDialog::onCloseDialog(wxEvent &)
+{
+ this->EndModal(wxID_CLOSE);
+ this->Close();
+}
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/ConfigSnapshotDialog.hpp b/xs/src/slic3r/GUI/ConfigSnapshotDialog.hpp
new file mode 100644
index 000000000..f43fb8ed1
--- /dev/null
+++ b/xs/src/slic3r/GUI/ConfigSnapshotDialog.hpp
@@ -0,0 +1,34 @@
+#ifndef slic3r_GUI_ConfigSnapshotDialog_hpp_
+#define slic3r_GUI_ConfigSnapshotDialog_hpp_
+
+#include "GUI.hpp"
+
+#include <wx/wx.h>
+#include <wx/intl.h>
+#include <wx/html/htmlwin.h>
+
+namespace Slic3r {
+namespace GUI {
+
+namespace Config {
+ class SnapshotDB;
+}
+
+class ConfigSnapshotDialog : public wxDialog
+{
+public:
+ ConfigSnapshotDialog(const Config::SnapshotDB &snapshot_db, const wxString &id);
+ const std::string& snapshot_to_activate() const { return m_snapshot_to_activate; }
+
+private:
+ void onLinkClicked(wxHtmlLinkEvent &event);
+ void onCloseDialog(wxEvent &);
+
+ // If set, it contains a snapshot ID to be restored after the dialog closes.
+ std::string m_snapshot_to_activate;
+};
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif /* slic3r_GUI_ConfigSnapshotDialog_hpp_ */
diff --git a/xs/src/slic3r/GUI/ConfigWizard.cpp b/xs/src/slic3r/GUI/ConfigWizard.cpp
new file mode 100644
index 000000000..9f736ded8
--- /dev/null
+++ b/xs/src/slic3r/GUI/ConfigWizard.cpp
@@ -0,0 +1,915 @@
+#include "ConfigWizard_private.hpp"
+
+#include <algorithm>
+#include <utility>
+#include <unordered_map>
+#include <boost/format.hpp>
+#include <boost/log/trivial.hpp>
+
+#include <wx/settings.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/dcclient.h>
+#include <wx/statbmp.h>
+#include <wx/checkbox.h>
+#include <wx/statline.h>
+
+#include "libslic3r/Utils.hpp"
+#include "PresetBundle.hpp"
+#include "GUI.hpp"
+#include "slic3r/Utils/PresetUpdater.hpp"
+
+
+namespace Slic3r {
+namespace GUI {
+
+
+// Printer model picker GUI control
+
+struct PrinterPickerEvent : public wxEvent
+{
+ std::string vendor_id;
+ std::string model_id;
+ std::string variant_name;
+ bool enable;
+
+ PrinterPickerEvent(wxEventType eventType, int winid, std::string vendor_id, std::string model_id, std::string variant_name, bool enable) :
+ wxEvent(winid, eventType),
+ vendor_id(std::move(vendor_id)),
+ model_id(std::move(model_id)),
+ variant_name(std::move(variant_name)),
+ enable(enable)
+ {}
+
+ virtual wxEvent *Clone() const
+ {
+ return new PrinterPickerEvent(*this);
+ }
+};
+
+wxDEFINE_EVENT(EVT_PRINTER_PICK, PrinterPickerEvent);
+
+PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, const AppConfig &appconfig_vendors) :
+ wxPanel(parent),
+ vendor_id(vendor.id),
+ variants_checked(0)
+{
+ const auto &models = vendor.models;
+
+ auto *sizer = new wxBoxSizer(wxVERTICAL);
+
+ auto *printer_grid = new wxFlexGridSizer(models.size(), 0, 20);
+ printer_grid->SetFlexibleDirection(wxVERTICAL | wxHORIZONTAL);
+ sizer->Add(printer_grid);
+
+ auto namefont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ namefont.SetWeight(wxFONTWEIGHT_BOLD);
+
+ // wxGrid appends widgets by rows, but we need to construct them in columns.
+ // These vectors are used to hold the elements so that they can be appended in the right order.
+ std::vector<wxStaticText*> titles;
+ std::vector<wxStaticBitmap*> bitmaps;
+ std::vector<wxPanel*> variants_panels;
+
+ for (const auto &model : models) {
+ auto bitmap_file = wxString::Format("printers/%s_%s.png", vendor.id, model.id);
+ wxBitmap bitmap(GUI::from_u8(Slic3r::var(bitmap_file.ToStdString())), wxBITMAP_TYPE_PNG);
+
+ auto *title = new wxStaticText(this, wxID_ANY, model.name, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+ title->SetFont(namefont);
+ title->Wrap(std::max((int)MODEL_MIN_WRAP, bitmap.GetWidth()));
+ titles.push_back(title);
+
+ auto *bitmap_widget = new wxStaticBitmap(this, wxID_ANY, bitmap);
+ bitmaps.push_back(bitmap_widget);
+
+ auto *variants_panel = new wxPanel(this);
+ auto *variants_sizer = new wxBoxSizer(wxVERTICAL);
+ variants_panel->SetSizer(variants_sizer);
+ const auto model_id = model.id;
+
+ bool default_variant = true; // Mark the first variant as default in the GUI
+ for (const auto &variant : model.variants) {
+ const auto label = wxString::Format("%s %s %s %s", variant.name, _(L("mm")), _(L("nozzle")),
+ (default_variant ? _(L("(default)")) : wxString()));
+ default_variant = false;
+ auto *cbox = new Checkbox(variants_panel, label, model_id, variant.name);
+ const size_t idx = cboxes.size();
+ cboxes.push_back(cbox);
+ bool enabled = appconfig_vendors.get_variant("PrusaResearch", model_id, variant.name);
+ variants_checked += enabled;
+ cbox->SetValue(enabled);
+ variants_sizer->Add(cbox, 0, wxBOTTOM, 3);
+ cbox->Bind(wxEVT_CHECKBOX, [this, idx](wxCommandEvent &event) {
+ if (idx >= this->cboxes.size()) { return; }
+ this->on_checkbox(this->cboxes[idx], event.IsChecked());
+ });
+ }
+
+ variants_panels.push_back(variants_panel);
+ }
+
+ for (auto title : titles) { printer_grid->Add(title, 0, wxBOTTOM, 3); }
+ for (auto bitmap : bitmaps) { printer_grid->Add(bitmap, 0, wxBOTTOM, 20); }
+ for (auto vp : variants_panels) { printer_grid->Add(vp); }
+
+ auto *all_none_sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto *sel_all = new wxButton(this, wxID_ANY, _(L("Select all")));
+ auto *sel_none = new wxButton(this, wxID_ANY, _(L("Select none")));
+ sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(true); });
+ sel_none->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(false); });
+ all_none_sizer->AddStretchSpacer();
+ all_none_sizer->Add(sel_all);
+ all_none_sizer->Add(sel_none);
+ sizer->AddStretchSpacer();
+ sizer->Add(all_none_sizer, 0, wxEXPAND);
+
+ SetSizer(sizer);
+}
+
+void PrinterPicker::select_all(bool select)
+{
+ for (const auto &cb : cboxes) {
+ if (cb->GetValue() != select) {
+ cb->SetValue(select);
+ on_checkbox(cb, select);
+ }
+ }
+}
+
+void PrinterPicker::select_one(size_t i, bool select)
+{
+ if (i < cboxes.size() && cboxes[i]->GetValue() != select) {
+ cboxes[i]->SetValue(select);
+ on_checkbox(cboxes[i], select);
+ }
+}
+
+void PrinterPicker::on_checkbox(const Checkbox *cbox, bool checked)
+{
+ variants_checked += checked ? 1 : -1;
+ PrinterPickerEvent evt(EVT_PRINTER_PICK, GetId(), vendor_id, cbox->model, cbox->variant, checked);
+ AddPendingEvent(evt);
+}
+
+
+// Wizard page base
+
+ConfigWizardPage::ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname) :
+ wxPanel(parent->p->hscroll),
+ parent(parent),
+ shortname(std::move(shortname)),
+ p_prev(nullptr),
+ p_next(nullptr)
+{
+ auto *sizer = new wxBoxSizer(wxVERTICAL);
+
+ auto *text = new wxStaticText(this, wxID_ANY, std::move(title), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+ auto font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ font.SetWeight(wxFONTWEIGHT_BOLD);
+ font.SetPointSize(14);
+ text->SetFont(font);
+ sizer->Add(text, 0, wxALIGN_LEFT, 0);
+ sizer->AddSpacer(10);
+
+ content = new wxBoxSizer(wxVERTICAL);
+ sizer->Add(content, 1);
+
+ SetSizer(sizer);
+
+ this->Hide();
+
+ Bind(wxEVT_SIZE, [this](wxSizeEvent &event) {
+ this->Layout();
+ event.Skip();
+ });
+}
+
+ConfigWizardPage::~ConfigWizardPage() {}
+
+ConfigWizardPage* ConfigWizardPage::chain(ConfigWizardPage *page)
+{
+ if (p_next != nullptr) { p_next->p_prev = nullptr; }
+ p_next = page;
+ if (page != nullptr) {
+ if (page->p_prev != nullptr) { page->p_prev->p_next = nullptr; }
+ page->p_prev = this;
+ }
+
+ return page;
+}
+
+void ConfigWizardPage::append_text(wxString text)
+{
+ auto *widget = new wxStaticText(this, wxID_ANY, text, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+ widget->Wrap(WRAP_WIDTH);
+ widget->SetMinSize(wxSize(WRAP_WIDTH, -1));
+ append(widget);
+}
+
+void ConfigWizardPage::append_spacer(int space)
+{
+ content->AddSpacer(space);
+}
+
+bool ConfigWizardPage::Show(bool show)
+{
+ if (extra_buttons() != nullptr) { extra_buttons()->Show(show); }
+ return wxPanel::Show(show);
+}
+
+void ConfigWizardPage::enable_next(bool enable) { parent->p->enable_next(enable); }
+
+
+// Wizard pages
+
+PageWelcome::PageWelcome(ConfigWizard *parent, bool check_first_variant) :
+ ConfigWizardPage(parent, wxString::Format(_(L("Welcome to the Slic3r %s")), ConfigWizard::name()), _(L("Welcome"))),
+ printer_picker(nullptr),
+ others_buttons(new wxPanel(parent)),
+ cbox_reset(nullptr)
+{
+ if (wizard_p()->run_reason == ConfigWizard::RR_DATA_EMPTY) {
+ wxString::Format(_(L("Run %s")), ConfigWizard::name());
+ append_text(wxString::Format(
+ _(L("Hello, welcome to Slic3r Prusa Edition! This %s helps you with the initial configuration; just a few settings and you will be ready to print.")),
+ ConfigWizard::name())
+ );
+ } else {
+ cbox_reset = new wxCheckBox(this, wxID_ANY, _(L("Remove user profiles - install from scratch (a snapshot will be taken beforehand)")));
+ append(cbox_reset);
+ }
+
+ const auto &vendors = wizard_p()->vendors;
+ const auto vendor_prusa = vendors.find("PrusaResearch");
+
+ if (vendor_prusa != vendors.cend()) {
+ AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors;
+
+ printer_picker = new PrinterPicker(this, vendor_prusa->second, appconfig_vendors);
+ if (check_first_variant) {
+ // Select the default (first) model/variant on the Prusa vendor
+ printer_picker->select_one(0, true);
+ }
+ printer_picker->Bind(EVT_PRINTER_PICK, [this, &appconfig_vendors](const PrinterPickerEvent &evt) {
+ appconfig_vendors.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable);
+ this->on_variant_checked();
+ });
+
+ append(printer_picker);
+ }
+
+ const size_t num_other_vendors = vendors.size() - (vendor_prusa != vendors.cend());
+ auto *sizer = new wxBoxSizer(wxHORIZONTAL);
+ auto *other_vendors = new wxButton(others_buttons, wxID_ANY, _(L("Other vendors")));
+ other_vendors->Enable(num_other_vendors > 0);
+ auto *custom_setup = new wxButton(others_buttons, wxID_ANY, _(L("Custom setup")));
+
+ sizer->Add(other_vendors);
+ sizer->AddSpacer(BTN_SPACING);
+ sizer->Add(custom_setup);
+
+ other_vendors->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->wizard_p()->on_other_vendors(); });
+ custom_setup->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->wizard_p()->on_custom_setup(); });
+
+ others_buttons->SetSizer(sizer);
+}
+
+void PageWelcome::on_page_set()
+{
+ chain(wizard_p()->page_update);
+ on_variant_checked();
+}
+
+void PageWelcome::on_variant_checked()
+{
+ enable_next(printer_picker != nullptr ? printer_picker->variants_checked > 0 : false);
+}
+
+PageUpdate::PageUpdate(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Automatic updates")), _(L("Updates"))),
+ version_check(true),
+ preset_update(true)
+{
+ const AppConfig *app_config = GUI::get_app_config();
+ auto boldfont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ boldfont.SetWeight(wxFONTWEIGHT_BOLD);
+
+ auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _(L("Check for application updates")));
+ box_slic3r->SetValue(app_config->get("version_check") == "1");
+ append(box_slic3r);
+ append_text(_(L("If enabled, Slic3r checks for new versions of Slic3r PE online. When a new version becomes available a notification is displayed at the next application startup (never during program usage). This is only a notification mechanisms, no automatic installation is done.")));
+
+ append_spacer(VERTICAL_SPACING);
+
+ auto *box_presets = new wxCheckBox(this, wxID_ANY, _(L("Update built-in Presets automatically")));
+ box_presets->SetValue(app_config->get("preset_update") == "1");
+ append(box_presets);
+ append_text(_(L("If enabled, Slic3r downloads updates of built-in system presets in the background. These updates are downloaded into a separate temporary location. When a new preset version becomes available it is offered at application startup.")));
+ const auto text_bold = _(L("Updates are never applied without user's consent and never overwrite user's customized settings."));
+ auto *label_bold = new wxStaticText(this, wxID_ANY, text_bold);
+ label_bold->SetFont(boldfont);
+ label_bold->Wrap(WRAP_WIDTH);
+ append(label_bold);
+ append_text(_(L("Additionally a backup snapshot of the whole configuration is created before an update is applied.")));
+
+ box_slic3r->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->version_check = event.IsChecked(); });
+ box_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->preset_update = event.IsChecked(); });
+}
+
+PageVendors::PageVendors(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Other Vendors")), _(L("Other Vendors")))
+{
+ append_text(_(L("Pick another vendor supported by Slic3r PE:")));
+
+ auto boldfont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ boldfont.SetWeight(wxFONTWEIGHT_BOLD);
+
+ AppConfig &appconfig_vendors = this->wizard_p()->appconfig_vendors;
+ wxArrayString choices_vendors;
+
+ for (const auto vendor_pair : wizard_p()->vendors) {
+ const auto &vendor = vendor_pair.second;
+ if (vendor.id == "PrusaResearch") { continue; }
+
+ auto *picker = new PrinterPicker(this, vendor, appconfig_vendors);
+ picker->Hide();
+ pickers.push_back(picker);
+ choices_vendors.Add(vendor.name);
+
+ picker->Bind(EVT_PRINTER_PICK, [this, &appconfig_vendors](const PrinterPickerEvent &evt) {
+ appconfig_vendors.set_variant(evt.vendor_id, evt.model_id, evt.variant_name, evt.enable);
+ this->on_variant_checked();
+ });
+ }
+
+ auto *vendor_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices_vendors);
+ if (choices_vendors.GetCount() > 0) {
+ vendor_picker->SetSelection(0);
+ on_vendor_pick(0);
+ }
+
+ vendor_picker->Bind(wxEVT_CHOICE, [this](wxCommandEvent &evt) {
+ this->on_vendor_pick(evt.GetInt());
+ });
+
+ append(vendor_picker);
+ for (PrinterPicker *picker : pickers) { this->append(picker); }
+}
+
+void PageVendors::on_page_set()
+{
+ on_variant_checked();
+}
+
+void PageVendors::on_vendor_pick(size_t i)
+{
+ for (PrinterPicker *picker : pickers) { picker->Hide(); }
+ if (i < pickers.size()) {
+ pickers[i]->Show();
+ wizard_p()->layout_fit();
+ }
+}
+
+void PageVendors::on_variant_checked()
+{
+ size_t variants_checked = 0;
+ for (const PrinterPicker *picker : pickers) { variants_checked += picker->variants_checked; }
+ enable_next(variants_checked > 0);
+}
+
+PageFirmware::PageFirmware(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Firmware Type")), _(L("Firmware"))),
+ gcode_opt(print_config_def.options["gcode_flavor"]),
+ gcode_picker(nullptr)
+{
+ append_text(_(L("Choose the type of firmware used by your printer.")));
+ append_text(gcode_opt.tooltip);
+
+ wxArrayString choices;
+ choices.Alloc(gcode_opt.enum_labels.size());
+ for (const auto &label : gcode_opt.enum_labels) {
+ choices.Add(label);
+ }
+
+ gcode_picker = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
+ const auto &enum_values = gcode_opt.enum_values;
+ auto needle = enum_values.cend();
+ if (gcode_opt.default_value != nullptr) {
+ needle = std::find(enum_values.cbegin(), enum_values.cend(), gcode_opt.default_value->serialize());
+ }
+ if (needle != enum_values.cend()) {
+ gcode_picker->SetSelection(needle - enum_values.cbegin());
+ } else {
+ gcode_picker->SetSelection(0);
+ }
+
+ append(gcode_picker);
+}
+
+void PageFirmware::apply_custom_config(DynamicPrintConfig &config)
+{
+ ConfigOptionEnum<GCodeFlavor> opt;
+
+ auto sel = gcode_picker->GetSelection();
+ if (sel != wxNOT_FOUND && opt.deserialize(gcode_picker->GetString(sel).ToStdString())) {
+ config.set_key_value("gcode_flavor", &opt);
+ }
+}
+
+PageBedShape::PageBedShape(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Bed Shape and Size")), _(L("Bed Shape"))),
+ shape_panel(new BedShapePanel(this))
+{
+ append_text(_(L("Set the shape of your printer's bed.")));
+
+ shape_panel->build_panel(wizard_p()->custom_config->option<ConfigOptionPoints>("bed_shape"));
+ append(shape_panel);
+}
+
+void PageBedShape::apply_custom_config(DynamicPrintConfig &config)
+{
+ const auto points(shape_panel->GetValue());
+ auto *opt = new ConfigOptionPoints(points);
+ config.set_key_value("bed_shape", opt);
+}
+
+PageDiameters::PageDiameters(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Filament and Nozzle Diameters")), _(L("Print Diameters"))),
+ spin_nozzle(new wxSpinCtrlDouble(this, wxID_ANY)),
+ spin_filam(new wxSpinCtrlDouble(this, wxID_ANY))
+{
+ spin_nozzle->SetDigits(2);
+ spin_nozzle->SetIncrement(0.1);
+ const auto &def_nozzle = print_config_def.options["nozzle_diameter"];
+ auto *default_nozzle = dynamic_cast<const ConfigOptionFloats*>(def_nozzle.default_value);
+ spin_nozzle->SetValue(default_nozzle != nullptr && default_nozzle->size() > 0 ? default_nozzle->get_at(0) : 0.5);
+
+ spin_filam->SetDigits(2);
+ spin_filam->SetIncrement(0.25);
+ const auto &def_filam = print_config_def.options["filament_diameter"];
+ auto *default_filam = dynamic_cast<const ConfigOptionFloats*>(def_filam.default_value);
+ spin_filam->SetValue(default_filam != nullptr && default_filam->size() > 0 ? default_filam->get_at(0) : 3.0);
+
+ append_text(_(L("Enter the diameter of your printer's hot end nozzle.")));
+
+ auto *sizer_nozzle = new wxFlexGridSizer(3, 5, 5);
+ auto *text_nozzle = new wxStaticText(this, wxID_ANY, _(L("Nozzle Diameter:")));
+ auto *unit_nozzle = new wxStaticText(this, wxID_ANY, _(L("mm")));
+ sizer_nozzle->AddGrowableCol(0, 1);
+ sizer_nozzle->Add(text_nozzle, 0, wxALIGN_CENTRE_VERTICAL);
+ sizer_nozzle->Add(spin_nozzle);
+ sizer_nozzle->Add(unit_nozzle, 0, wxALIGN_CENTRE_VERTICAL);
+ append(sizer_nozzle);
+
+ append_spacer(VERTICAL_SPACING);
+
+ append_text(_(L("Enter the diameter of your filament.")));
+ append_text(_(L("Good precision is required, so use a caliper and do multiple measurements along the filament, then compute the average.")));
+
+ auto *sizer_filam = new wxFlexGridSizer(3, 5, 5);
+ auto *text_filam = new wxStaticText(this, wxID_ANY, _(L("Filament Diameter:")));
+ auto *unit_filam = new wxStaticText(this, wxID_ANY, _(L("mm")));
+ sizer_filam->AddGrowableCol(0, 1);
+ sizer_filam->Add(text_filam, 0, wxALIGN_CENTRE_VERTICAL);
+ sizer_filam->Add(spin_filam);
+ sizer_filam->Add(unit_filam, 0, wxALIGN_CENTRE_VERTICAL);
+ append(sizer_filam);
+}
+
+void PageDiameters::apply_custom_config(DynamicPrintConfig &config)
+{
+ auto *opt_nozzle = new ConfigOptionFloats(1, spin_nozzle->GetValue());
+ config.set_key_value("nozzle_diameter", opt_nozzle);
+ auto *opt_filam = new ConfigOptionFloats(1, spin_filam->GetValue());
+ config.set_key_value("filament_diameter", opt_filam);
+}
+
+PageTemperatures::PageTemperatures(ConfigWizard *parent) :
+ ConfigWizardPage(parent, _(L("Extruder and Bed Temperatures")), _(L("Temperatures"))),
+ spin_extr(new wxSpinCtrlDouble(this, wxID_ANY)),
+ spin_bed(new wxSpinCtrlDouble(this, wxID_ANY))
+{
+ spin_extr->SetIncrement(5.0);
+ const auto &def_extr = print_config_def.options["temperature"];
+ spin_extr->SetRange(def_extr.min, def_extr.max);
+ auto *default_extr = dynamic_cast<const ConfigOptionInts*>(def_extr.default_value);
+ spin_extr->SetValue(default_extr != nullptr && default_extr->size() > 0 ? default_extr->get_at(0) : 200);
+
+ spin_bed->SetIncrement(5.0);
+ const auto &def_bed = print_config_def.options["bed_temperature"];
+ spin_bed->SetRange(def_bed.min, def_bed.max);
+ auto *default_bed = dynamic_cast<const ConfigOptionInts*>(def_bed.default_value);
+ spin_bed->SetValue(default_bed != nullptr && default_bed->size() > 0 ? default_bed->get_at(0) : 0);
+
+ append_text(_(L("Enter the temperature needed for extruding your filament.")));
+ append_text(_(L("A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS.")));
+
+ auto *sizer_extr = new wxFlexGridSizer(3, 5, 5);
+ auto *text_extr = new wxStaticText(this, wxID_ANY, _(L("Extrusion Temperature:")));
+ auto *unit_extr = new wxStaticText(this, wxID_ANY, _(L("°C")));
+ sizer_extr->AddGrowableCol(0, 1);
+ sizer_extr->Add(text_extr, 0, wxALIGN_CENTRE_VERTICAL);
+ sizer_extr->Add(spin_extr);
+ sizer_extr->Add(unit_extr, 0, wxALIGN_CENTRE_VERTICAL);
+ append(sizer_extr);
+
+ append_spacer(VERTICAL_SPACING);
+
+ append_text(_(L("Enter the bed temperature needed for getting your filament to stick to your heated bed.")));
+ append_text(_(L("A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have no heated bed.")));
+
+ auto *sizer_bed = new wxFlexGridSizer(3, 5, 5);
+ auto *text_bed = new wxStaticText(this, wxID_ANY, _(L("Bed Temperature:")));
+ auto *unit_bed = new wxStaticText(this, wxID_ANY, _(L("°C")));
+ sizer_bed->AddGrowableCol(0, 1);
+ sizer_bed->Add(text_bed, 0, wxALIGN_CENTRE_VERTICAL);
+ sizer_bed->Add(spin_bed);
+ sizer_bed->Add(unit_bed, 0, wxALIGN_CENTRE_VERTICAL);
+ append(sizer_bed);
+}
+
+void PageTemperatures::apply_custom_config(DynamicPrintConfig &config)
+{
+ auto *opt_extr = new ConfigOptionInts(1, spin_extr->GetValue());
+ config.set_key_value("temperature", opt_extr);
+ auto *opt_extr1st = new ConfigOptionInts(1, spin_extr->GetValue());
+ config.set_key_value("first_layer_temperature", opt_extr1st);
+ auto *opt_bed = new ConfigOptionInts(1, spin_bed->GetValue());
+ config.set_key_value("bed_temperature", opt_bed);
+ auto *opt_bed1st = new ConfigOptionInts(1, spin_bed->GetValue());
+ config.set_key_value("first_layer_bed_temperature", opt_bed1st);
+}
+
+
+// Index
+
+ConfigWizardIndex::ConfigWizardIndex(wxWindow *parent) :
+ wxPanel(parent),
+ bg(GUI::from_u8(Slic3r::var("Slic3r_192px_transparent.png")), wxBITMAP_TYPE_PNG),
+ bullet_black(GUI::from_u8(Slic3r::var("bullet_black.png")), wxBITMAP_TYPE_PNG),
+ bullet_blue(GUI::from_u8(Slic3r::var("bullet_blue.png")), wxBITMAP_TYPE_PNG),
+ bullet_white(GUI::from_u8(Slic3r::var("bullet_white.png")), wxBITMAP_TYPE_PNG)
+{
+ SetMinSize(bg.GetSize());
+
+ wxClientDC dc(this);
+ text_height = dc.GetCharHeight();
+
+ // Add logo bitmap.
+ // This could be done in on_paint() along with the index labels, but I've found it tricky
+ // to get the bitmap rendered well on all platforms with transparent background.
+ // In some cases it didn't work at all. And so wxStaticBitmap is used here instead,
+ // because it has all the platform quirks figured out.
+ auto *sizer = new wxBoxSizer(wxVERTICAL);
+ auto *logo = new wxStaticBitmap(this, wxID_ANY, bg);
+ sizer->AddStretchSpacer();
+ sizer->Add(logo);
+ SetSizer(sizer);
+
+ Bind(wxEVT_PAINT, &ConfigWizardIndex::on_paint, this);
+}
+
+void ConfigWizardIndex::load_items(ConfigWizardPage *firstpage)
+{
+ items.clear();
+ item_active = items.cend();
+
+ for (auto *page = firstpage; page != nullptr; page = page->page_next()) {
+ items.emplace_back(page->shortname);
+ }
+
+ Refresh();
+}
+
+void ConfigWizardIndex::set_active(ConfigWizardPage *page)
+{
+ item_active = std::find(items.cbegin(), items.cend(), page->shortname);
+ Refresh();
+}
+
+void ConfigWizardIndex::on_paint(wxPaintEvent & evt)
+{
+ enum {
+ MARGIN = 10,
+ SPACING = 5,
+ };
+
+ const auto size = GetClientSize();
+ if (size.GetHeight() == 0 || size.GetWidth() == 0) { return; }
+
+ wxPaintDC dc(this);
+
+ const auto bullet_w = bullet_black.GetSize().GetWidth();
+ const auto bullet_h = bullet_black.GetSize().GetHeight();
+ const int yoff_icon = bullet_h < text_height ? (text_height - bullet_h) / 2 : 0;
+ const int yoff_text = bullet_h > text_height ? (bullet_h - text_height) / 2 : 0;
+ const int yinc = std::max(bullet_h, text_height) + SPACING;
+
+ unsigned y = 0;
+ for (auto it = items.cbegin(); it != items.cend(); ++it) {
+ if (it < item_active) { dc.DrawBitmap(bullet_black, MARGIN, y + yoff_icon, false); }
+ if (it == item_active) { dc.DrawBitmap(bullet_blue, MARGIN, y + yoff_icon, false); }
+ if (it > item_active) { dc.DrawBitmap(bullet_white, MARGIN, y + yoff_icon, false); }
+ dc.DrawText(*it, MARGIN + bullet_w + SPACING, y + yoff_text);
+ y += yinc;
+ }
+}
+
+
+
+// priv
+
+static const std::unordered_map<std::string, std::pair<std::string, std::string>> legacy_preset_map {{
+ { "Original Prusa i3 MK2.ini", std::make_pair("MK2S", "0.4") },
+ { "Original Prusa i3 MK2 MM Single Mode.ini", std::make_pair("MK2SMM", "0.4") },
+ { "Original Prusa i3 MK2 MM Single Mode 0.6 nozzle.ini", std::make_pair("MK2SMM", "0.6") },
+ { "Original Prusa i3 MK2 MultiMaterial.ini", std::make_pair("MK2SMM", "0.4") },
+ { "Original Prusa i3 MK2 MultiMaterial 0.6 nozzle.ini", std::make_pair("MK2SMM", "0.6") },
+ { "Original Prusa i3 MK2 0.25 nozzle.ini", std::make_pair("MK2S", "0.25") },
+ { "Original Prusa i3 MK2 0.6 nozzle.ini", std::make_pair("MK2S", "0.6") },
+ { "Original Prusa i3 MK3.ini", std::make_pair("MK3", "0.4") },
+}};
+
+void ConfigWizard::priv::load_vendors()
+{
+ const auto vendor_dir = fs::path(Slic3r::data_dir()) / "vendor";
+ const auto rsrc_vendor_dir = fs::path(resources_dir()) / "profiles";
+
+ // Load vendors from the "vendors" directory in datadir
+ for (fs::directory_iterator it(vendor_dir); it != fs::directory_iterator(); ++it) {
+ if (it->path().extension() == ".ini") {
+ try {
+ auto vp = VendorProfile::from_ini(it->path());
+ vendors[vp.id] = std::move(vp);
+ }
+ catch (const std::exception& e) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % it->path() % e.what();
+ }
+
+ }
+ }
+
+ // Additionally load up vendors from the application resources directory, but only those not seen in the datadir
+ for (fs::directory_iterator it(rsrc_vendor_dir); it != fs::directory_iterator(); ++it) {
+ if (it->path().extension() == ".ini") {
+ const auto id = it->path().stem().string();
+ if (vendors.find(id) == vendors.end()) {
+ try {
+ auto vp = VendorProfile::from_ini(it->path());
+ vendors_rsrc[vp.id] = it->path().filename().string();
+ vendors[vp.id] = std::move(vp);
+ }
+ catch (const std::exception& e) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Error loading vendor bundle %1%: %2%") % it->path() % e.what();
+ }
+ }
+ }
+ }
+
+ // Load up the set of vendors / models / variants the user has had enabled up till now
+ const AppConfig *app_config = GUI::get_app_config();
+ if (! app_config->legacy_datadir()) {
+ appconfig_vendors.set_vendors(*app_config);
+ } else {
+ // In case of legacy datadir, try to guess the preference based on the printer preset files that are present
+ const auto printer_dir = fs::path(Slic3r::data_dir()) / "printer";
+ for (fs::directory_iterator it(printer_dir); it != fs::directory_iterator(); ++it) {
+ auto needle = legacy_preset_map.find(it->path().filename().string());
+ if (needle == legacy_preset_map.end()) { continue; }
+
+ const auto &model = needle->second.first;
+ const auto &variant = needle->second.second;
+ appconfig_vendors.set_variant("PrusaResearch", model, variant, true);
+ }
+ }
+}
+
+void ConfigWizard::priv::index_refresh()
+{
+ index->load_items(page_welcome);
+}
+
+void ConfigWizard::priv::add_page(ConfigWizardPage *page)
+{
+ hscroll_sizer->Add(page, 0, wxEXPAND);
+
+ auto *extra_buttons = page->extra_buttons();
+ if (extra_buttons != nullptr) {
+ btnsizer->Prepend(extra_buttons, 0);
+ }
+}
+
+void ConfigWizard::priv::set_page(ConfigWizardPage *page)
+{
+ if (page == nullptr) { return; }
+ if (page_current != nullptr) { page_current->Hide(); }
+ page_current = page;
+ enable_next(true);
+
+ page->on_page_set();
+ index->load_items(page_welcome);
+ index->set_active(page);
+ page->Show();
+
+ btn_prev->Enable(page->page_prev() != nullptr);
+ btn_next->Show(page->page_next() != nullptr);
+ btn_finish->Show(page->page_next() == nullptr);
+
+ layout_fit();
+}
+
+void ConfigWizard::priv::layout_fit()
+{
+ q->Layout();
+ q->Fit();
+}
+
+void ConfigWizard::priv::enable_next(bool enable)
+{
+ btn_next->Enable(enable);
+ btn_finish->Enable(enable);
+}
+
+void ConfigWizard::priv::on_other_vendors()
+{
+ page_welcome
+ ->chain(page_vendors)
+ ->chain(page_update);
+ set_page(page_vendors);
+}
+
+void ConfigWizard::priv::on_custom_setup()
+{
+ page_welcome->chain(page_firmware);
+ page_temps->chain(page_update);
+ set_page(page_firmware);
+}
+
+void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater)
+{
+ const bool is_custom_setup = page_welcome->page_next() == page_firmware;
+
+ if (! is_custom_setup) {
+ const auto enabled_vendors = appconfig_vendors.vendors();
+
+ // Install bundles from resources if needed:
+ std::vector<std::string> install_bundles;
+ for (const auto &vendor_rsrc : vendors_rsrc) {
+ const auto vendor = enabled_vendors.find(vendor_rsrc.first);
+ if (vendor == enabled_vendors.end()) { continue; }
+
+ size_t size_sum = 0;
+ for (const auto &model : vendor->second) { size_sum += model.second.size(); }
+ if (size_sum == 0) { continue; }
+
+ // This vendor needs to be installed
+ install_bundles.emplace_back(vendor_rsrc.second);
+ }
+
+ // Decide whether to create snapshot based on run_reason and the reset profile checkbox
+ bool snapshot = true;
+ switch (run_reason) {
+ case ConfigWizard::RR_DATA_EMPTY: snapshot = false; break;
+ case ConfigWizard::RR_DATA_LEGACY: snapshot = true; break;
+ case ConfigWizard::RR_DATA_INCOMPAT: snapshot = false; break; // In this case snapshot is done by PresetUpdater with the appropriate reason
+ case ConfigWizard::RR_USER: snapshot = page_welcome->reset_user_profile(); break;
+ }
+ if (install_bundles.size() > 0) {
+ // Install bundles from resources.
+ updater->install_bundles_rsrc(std::move(install_bundles), snapshot);
+ } else {
+ BOOST_LOG_TRIVIAL(info) << "No bundles need to be installed from resources";
+ }
+
+ if (page_welcome->reset_user_profile()) {
+ BOOST_LOG_TRIVIAL(info) << "Resetting user profiles...";
+ preset_bundle->reset(true);
+ }
+
+ app_config->set_vendors(appconfig_vendors);
+ app_config->set("version_check", page_update->version_check ? "1" : "0");
+ app_config->set("preset_update", page_update->preset_update ? "1" : "0");
+ app_config->reset_selections();
+ preset_bundle->load_presets(*app_config);
+ } else {
+ for (ConfigWizardPage *page = page_firmware; page != nullptr; page = page->page_next()) {
+ page->apply_custom_config(*custom_config);
+ }
+ preset_bundle->load_config("My Settings", *custom_config);
+ }
+ // Update the selections from the compatibilty.
+ preset_bundle->export_selections(*app_config);
+}
+
+// Public
+
+ConfigWizard::ConfigWizard(wxWindow *parent, RunReason reason) :
+ wxDialog(parent, wxID_ANY, name(), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
+ p(new priv(this))
+{
+ p->run_reason = reason;
+
+ p->load_vendors();
+ p->custom_config.reset(DynamicPrintConfig::new_from_defaults_keys({
+ "gcode_flavor", "bed_shape", "nozzle_diameter", "filament_diameter", "temperature", "bed_temperature",
+ }));
+
+ p->index = new ConfigWizardIndex(this);
+
+ auto *vsizer = new wxBoxSizer(wxVERTICAL);
+ auto *topsizer = new wxBoxSizer(wxHORIZONTAL);
+ auto *hline = new wxStaticLine(this);
+ p->btnsizer = new wxBoxSizer(wxHORIZONTAL);
+
+ // Initially we _do not_ SetScrollRate in order to figure out the overall width of the Wizard without scrolling.
+ // Later, we compare that to the size of the current screen and set minimum width based on that (see below).
+ p->hscroll = new wxScrolledWindow(this);
+ p->hscroll_sizer = new wxBoxSizer(wxHORIZONTAL);
+ p->hscroll->SetSizer(p->hscroll_sizer);
+
+ topsizer->Add(p->index, 0, wxEXPAND);
+ topsizer->AddSpacer(INDEX_MARGIN);
+ topsizer->Add(p->hscroll, 1, wxEXPAND);
+
+ p->btn_prev = new wxButton(this, wxID_NONE, _(L("< &Back")));
+ p->btn_next = new wxButton(this, wxID_NONE, _(L("&Next >")));
+ p->btn_finish = new wxButton(this, wxID_APPLY, _(L("&Finish")));
+ p->btn_cancel = new wxButton(this, wxID_CANCEL);
+ p->btnsizer->AddStretchSpacer();
+ p->btnsizer->Add(p->btn_prev, 0, wxLEFT, BTN_SPACING);
+ p->btnsizer->Add(p->btn_next, 0, wxLEFT, BTN_SPACING);
+ p->btnsizer->Add(p->btn_finish, 0, wxLEFT, BTN_SPACING);
+ p->btnsizer->Add(p->btn_cancel, 0, wxLEFT, BTN_SPACING);
+
+ p->add_page(p->page_welcome = new PageWelcome(this, reason == RR_DATA_EMPTY || reason == RR_DATA_LEGACY));
+ p->add_page(p->page_update = new PageUpdate(this));
+ p->add_page(p->page_vendors = new PageVendors(this));
+ p->add_page(p->page_firmware = new PageFirmware(this));
+ p->add_page(p->page_bed = new PageBedShape(this));
+ p->add_page(p->page_diams = new PageDiameters(this));
+ p->add_page(p->page_temps = new PageTemperatures(this));
+ p->index_refresh();
+
+ p->page_welcome->chain(p->page_update);
+ p->page_firmware
+ ->chain(p->page_bed)
+ ->chain(p->page_diams)
+ ->chain(p->page_temps);
+
+ vsizer->Add(topsizer, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
+ vsizer->Add(hline, 0, wxEXPAND);
+ vsizer->Add(p->btnsizer, 0, wxEXPAND | wxALL, DIALOG_MARGIN);
+
+ p->set_page(p->page_welcome);
+ SetSizer(vsizer);
+ SetSizerAndFit(vsizer);
+
+ // We can now enable scrolling on hscroll
+ p->hscroll->SetScrollRate(30, 30);
+ // Compare current ("ideal") wizard size with the size of the current screen.
+ // If the screen is smaller, resize wizrad to match, which will enable scrollbars.
+ auto wizard_size = GetSize();
+ unsigned width, height;
+ GUI::get_current_screen_size(width, height);
+ wizard_size.SetWidth(std::min(wizard_size.GetWidth(), (int)(width - 2 * DIALOG_MARGIN)));
+ wizard_size.SetHeight(std::min(wizard_size.GetHeight(), (int)(height - 2 * DIALOG_MARGIN)));
+ SetMinSize(wizard_size);
+ Fit();
+
+ p->btn_prev->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->go_prev(); });
+ p->btn_next->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->p->go_next(); });
+ p->btn_finish->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &evt) { this->EndModal(wxID_OK); });
+}
+
+ConfigWizard::~ConfigWizard() {}
+
+bool ConfigWizard::run(PresetBundle *preset_bundle, const PresetUpdater *updater)
+{
+ BOOST_LOG_TRIVIAL(info) << "Running ConfigWizard, reason: " << p->run_reason;
+ if (ShowModal() == wxID_OK) {
+ auto *app_config = GUI::get_app_config();
+ p->apply_config(app_config, preset_bundle, updater);
+ app_config->set_legacy_datadir(false);
+ BOOST_LOG_TRIVIAL(info) << "ConfigWizard applied";
+ return true;
+ } else {
+ BOOST_LOG_TRIVIAL(info) << "ConfigWizard cancelled";
+ return false;
+ }
+}
+
+
+const wxString& ConfigWizard::name()
+{
+ // A different naming convention is used for the Wizard on Windows vs. OSX & GTK.
+#if WIN32
+ static const wxString config_wizard_name = L("Configuration Wizard");
+#else
+ static const wxString config_wizard_name = L("Configuration Assistant");
+#endif
+ return config_wizard_name;
+}
+
+}
+}
diff --git a/xs/src/slic3r/GUI/ConfigWizard.hpp b/xs/src/slic3r/GUI/ConfigWizard.hpp
new file mode 100644
index 000000000..73fce7cd2
--- /dev/null
+++ b/xs/src/slic3r/GUI/ConfigWizard.hpp
@@ -0,0 +1,50 @@
+#ifndef slic3r_ConfigWizard_hpp_
+#define slic3r_ConfigWizard_hpp_
+
+#include <memory>
+
+#include <wx/dialog.h>
+
+namespace Slic3r {
+
+class PresetBundle;
+class PresetUpdater;
+
+namespace GUI {
+
+
+class ConfigWizard: public wxDialog
+{
+public:
+ // Why is the Wizard run
+ enum RunReason {
+ RR_DATA_EMPTY, // No or empty datadir
+ RR_DATA_LEGACY, // Pre-updating datadir
+ RR_DATA_INCOMPAT, // Incompatible datadir - Slic3r downgrade situation
+ RR_USER, // User requested the Wizard from the menus
+ };
+
+ ConfigWizard(wxWindow *parent, RunReason run_reason);
+ ConfigWizard(ConfigWizard &&) = delete;
+ ConfigWizard(const ConfigWizard &) = delete;
+ ConfigWizard &operator=(ConfigWizard &&) = delete;
+ ConfigWizard &operator=(const ConfigWizard &) = delete;
+ ~ConfigWizard();
+
+ // Run the Wizard. Return whether it was completed.
+ bool run(PresetBundle *preset_bundle, const PresetUpdater *updater);
+
+ static const wxString& name();
+private:
+ struct priv;
+ std::unique_ptr<priv> p;
+
+ friend class ConfigWizardPage;
+};
+
+
+
+}
+}
+
+#endif
diff --git a/xs/src/slic3r/GUI/ConfigWizard_private.hpp b/xs/src/slic3r/GUI/ConfigWizard_private.hpp
new file mode 100644
index 000000000..2c8f23cd3
--- /dev/null
+++ b/xs/src/slic3r/GUI/ConfigWizard_private.hpp
@@ -0,0 +1,241 @@
+#ifndef slic3r_ConfigWizard_private_hpp_
+#define slic3r_ConfigWizard_private_hpp_
+
+#include "ConfigWizard.hpp"
+
+#include <vector>
+#include <set>
+#include <unordered_map>
+#include <boost/filesystem.hpp>
+
+#include <wx/sizer.h>
+#include <wx/panel.h>
+#include <wx/button.h>
+#include <wx/choice.h>
+#include <wx/spinctrl.h>
+
+#include "libslic3r/PrintConfig.hpp"
+#include "slic3r/Utils/PresetUpdater.hpp"
+#include "AppConfig.hpp"
+#include "Preset.hpp"
+#include "BedShapeDialog.hpp"
+
+namespace fs = boost::filesystem;
+
+namespace Slic3r {
+namespace GUI {
+
+enum {
+ WRAP_WIDTH = 500,
+ MODEL_MIN_WRAP = 150,
+
+ DIALOG_MARGIN = 15,
+ INDEX_MARGIN = 40,
+ BTN_SPACING = 10,
+ INDENT_SPACING = 30,
+ VERTICAL_SPACING = 10,
+};
+
+struct PrinterPicker: wxPanel
+{
+ struct Checkbox : wxCheckBox
+ {
+ Checkbox(wxWindow *parent, const wxString &label, const std::string &model, const std::string &variant) :
+ wxCheckBox(parent, wxID_ANY, label),
+ model(model),
+ variant(variant)
+ {}
+
+ std::string model;
+ std::string variant;
+ };
+
+ const std::string vendor_id;
+ std::vector<Checkbox*> cboxes;
+ unsigned variants_checked;
+
+ PrinterPicker(wxWindow *parent, const VendorProfile &vendor, const AppConfig &appconfig_vendors);
+
+ void select_all(bool select);
+ void select_one(size_t i, bool select);
+ void on_checkbox(const Checkbox *cbox, bool checked);
+};
+
+struct ConfigWizardPage: wxPanel
+{
+ ConfigWizard *parent;
+ const wxString shortname;
+ wxBoxSizer *content;
+
+ ConfigWizardPage(ConfigWizard *parent, wxString title, wxString shortname);
+
+ virtual ~ConfigWizardPage();
+
+ ConfigWizardPage* page_prev() const { return p_prev; }
+ ConfigWizardPage* page_next() const { return p_next; }
+ ConfigWizardPage* chain(ConfigWizardPage *page);
+
+ template<class T>
+ void append(T *thing, int proportion = 0, int flag = wxEXPAND|wxTOP|wxBOTTOM, int border = 10)
+ {
+ content->Add(thing, proportion, flag, border);
+ }
+
+ void append_text(wxString text);
+ void append_spacer(int space);
+
+ ConfigWizard::priv *wizard_p() const { return parent->p.get(); }
+
+ virtual bool Show(bool show = true);
+ virtual bool Hide() { return Show(false); }
+ virtual wxPanel* extra_buttons() { return nullptr; }
+ virtual void on_page_set() {}
+ virtual void apply_custom_config(DynamicPrintConfig &config) {}
+
+ void enable_next(bool enable);
+private:
+ ConfigWizardPage *p_prev;
+ ConfigWizardPage *p_next;
+};
+
+struct PageWelcome: ConfigWizardPage
+{
+ PrinterPicker *printer_picker;
+ wxPanel *others_buttons;
+ wxCheckBox *cbox_reset;
+
+ PageWelcome(ConfigWizard *parent, bool check_first_variant);
+
+ virtual wxPanel* extra_buttons() { return others_buttons; }
+ virtual void on_page_set();
+
+ bool reset_user_profile() const { return cbox_reset != nullptr ? cbox_reset->GetValue() : false; }
+ void on_variant_checked();
+};
+
+struct PageUpdate: ConfigWizardPage
+{
+ bool version_check;
+ bool preset_update;
+
+ PageUpdate(ConfigWizard *parent);
+};
+
+struct PageVendors: ConfigWizardPage
+{
+ std::vector<PrinterPicker*> pickers;
+
+ PageVendors(ConfigWizard *parent);
+
+ virtual void on_page_set();
+
+ void on_vendor_pick(size_t i);
+ void on_variant_checked();
+};
+
+struct PageFirmware: ConfigWizardPage
+{
+ const ConfigOptionDef &gcode_opt;
+ wxChoice *gcode_picker;
+
+ PageFirmware(ConfigWizard *parent);
+ virtual void apply_custom_config(DynamicPrintConfig &config);
+};
+
+struct PageBedShape: ConfigWizardPage
+{
+ BedShapePanel *shape_panel;
+
+ PageBedShape(ConfigWizard *parent);
+ virtual void apply_custom_config(DynamicPrintConfig &config);
+};
+
+struct PageDiameters: ConfigWizardPage
+{
+ wxSpinCtrlDouble *spin_nozzle;
+ wxSpinCtrlDouble *spin_filam;
+
+ PageDiameters(ConfigWizard *parent);
+ virtual void apply_custom_config(DynamicPrintConfig &config);
+};
+
+struct PageTemperatures: ConfigWizardPage
+{
+ wxSpinCtrlDouble *spin_extr;
+ wxSpinCtrlDouble *spin_bed;
+
+ PageTemperatures(ConfigWizard *parent);
+ virtual void apply_custom_config(DynamicPrintConfig &config);
+};
+
+
+class ConfigWizardIndex: public wxPanel
+{
+public:
+ ConfigWizardIndex(wxWindow *parent);
+
+ void load_items(ConfigWizardPage *firstpage);
+ void set_active(ConfigWizardPage *page);
+private:
+ const wxBitmap bg;
+ const wxBitmap bullet_black;
+ const wxBitmap bullet_blue;
+ const wxBitmap bullet_white;
+ int text_height;
+
+ std::vector<wxString> items;
+ std::vector<wxString>::const_iterator item_active;
+
+ void on_paint(wxPaintEvent &evt);
+};
+
+struct ConfigWizard::priv
+{
+ ConfigWizard *q;
+ ConfigWizard::RunReason run_reason;
+ AppConfig appconfig_vendors;
+ std::unordered_map<std::string, VendorProfile> vendors;
+ std::unordered_map<std::string, std::string> vendors_rsrc;
+ std::unique_ptr<DynamicPrintConfig> custom_config;
+
+ wxScrolledWindow *hscroll = nullptr;
+ wxBoxSizer *hscroll_sizer = nullptr;
+ wxBoxSizer *btnsizer = nullptr;
+ ConfigWizardPage *page_current = nullptr;
+ ConfigWizardIndex *index = nullptr;
+ wxButton *btn_prev = nullptr;
+ wxButton *btn_next = nullptr;
+ wxButton *btn_finish = nullptr;
+ wxButton *btn_cancel = nullptr;
+
+ PageWelcome *page_welcome = nullptr;
+ PageUpdate *page_update = nullptr;
+ PageVendors *page_vendors = nullptr;
+ PageFirmware *page_firmware = nullptr;
+ PageBedShape *page_bed = nullptr;
+ PageDiameters *page_diams = nullptr;
+ PageTemperatures *page_temps = nullptr;
+
+ priv(ConfigWizard *q) : q(q) {}
+
+ void load_vendors();
+ void add_page(ConfigWizardPage *page);
+ void index_refresh();
+ void set_page(ConfigWizardPage *page);
+ void layout_fit();
+ void go_prev() { if (page_current != nullptr) { set_page(page_current->page_prev()); } }
+ void go_next() { if (page_current != nullptr) { set_page(page_current->page_next()); } }
+ void enable_next(bool enable);
+
+ void on_other_vendors();
+ void on_custom_setup();
+
+ void apply_config(AppConfig *app_config, PresetBundle *preset_bundle, const PresetUpdater *updater);
+};
+
+
+
+}
+}
+
+#endif
diff --git a/xs/src/slic3r/GUI/Field.cpp b/xs/src/slic3r/GUI/Field.cpp
index c2fc5e4e4..f143e8bc6 100644
--- a/xs/src/slic3r/GUI/Field.cpp
+++ b/xs/src/slic3r/GUI/Field.cpp
@@ -12,19 +12,54 @@ namespace Slic3r { namespace GUI {
wxString double_to_string(double const value)
{
- int precision = 10 * value - int(10 * value) == 0 ? 1 : 2;
- return value - int(value) == 0 ?
- wxString::Format(_T("%i"), int(value)) :
- wxNumberFormatter::ToString(value, precision, wxNumberFormatter::Style_None);
+ if (value - int(value) == 0)
+ return wxString::Format(_T("%i"), int(value));
+ else {
+ int precision = 4;
+ for (size_t p = 1; p < 4; p++)
+ {
+ double cur_val = pow(10, p)*value;
+ if (cur_val - int(cur_val) == 0) {
+ precision = p;
+ break;
+ }
+ }
+ return wxNumberFormatter::ToString(value, precision, wxNumberFormatter::Style_None);
+ }
}
void Field::PostInitialize(){
- m_Undo_btn = new wxButton(m_parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
- // use bouth of temporary_icons till don't have "undo_icon"
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
- if (wxMSW) m_Undo_btn->SetBackgroundColour(color);
- m_Undo_btn->SetBitmap(wxBitmap(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG));
+ m_Undo_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
+ m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
+ if (wxMSW) {
+ m_Undo_btn->SetBackgroundColour(color);
+ m_Undo_to_sys_btn->SetBackgroundColour(color);
+ }
m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_back_to_initial_value(); }));
+ m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_back_to_sys_value(); }));
+
+ //set default bitmap
+ wxBitmap bmp;
+ bmp.LoadFile(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG);
+ set_undo_bitmap(&bmp);
+ set_undo_to_sys_bitmap(&bmp);
+
+ switch (m_opt.type)
+ {
+ case coPercents:
+ case coFloats:
+ case coStrings:
+ case coBools:
+ case coInts: {
+ auto tag_pos = m_opt_id.find("#");
+ if (tag_pos != std::string::npos)
+ m_opt_idx = stoi(m_opt_id.substr(tag_pos + 1, m_opt_id.size()));
+ break;
+ }
+ default:
+ break;
+ }
BUILD();
}
@@ -45,36 +80,40 @@ namespace Slic3r { namespace GUI {
m_on_change(m_opt_id, get_value());
}
- void Field::on_back_to_initial_value()
- {
+ void Field::on_back_to_initial_value(){
if (m_back_to_initial_value != nullptr && m_is_modified_value)
m_back_to_initial_value(m_opt_id);
}
+ void Field::on_back_to_sys_value(){
+ if (m_back_to_sys_value != nullptr && m_is_nonsys_value)
+ m_back_to_sys_value(m_opt_id);
+ }
+
wxString Field::get_tooltip_text(const wxString& default_string)
{
wxString tooltip_text("");
- wxString tooltip = L_str(m_opt.tooltip);
+ wxString tooltip = _(m_opt.tooltip);
if (tooltip.length() > 0)
- tooltip_text = tooltip + "(" + _(L("default")) + ": " +
- (boost::iends_with(m_opt_id, "_gcode") ? "\n" : "") +
- default_string + ")";
+ tooltip_text = tooltip + "\n" + _(L("default value")) + "\t: " +
+ (boost::iends_with(m_opt_id, "_gcode") ? "\n" : "") + default_string +
+ (boost::iends_with(m_opt_id, "_gcode") ? "" : "\n") +
+ _(L("parameter name")) + "\t: " + m_opt_id;
return tooltip_text;
}
- bool Field::is_matched(std::string string, std::string pattern)
+ bool Field::is_matched(const std::string& string, const std::string& pattern)
{
std::regex regex_pattern(pattern, std::regex_constants::icase); // use ::icase to make the matching case insensitive like /i in perl
return std::regex_match(string, regex_pattern);
}
- boost::any Field::get_value_by_opt_type(wxString str)
+ void Field::get_value_by_opt_type(wxString& str)
{
- boost::any ret_val;
switch (m_opt.type){
case coInt:
- ret_val = wxAtoi(str);
+ m_value = wxAtoi(str);
break;
case coPercent:
case coPercents:
@@ -82,20 +121,39 @@ namespace Slic3r { namespace GUI {
case coFloat:{
if (m_opt.type == coPercent && str.Last() == '%')
str.RemoveLast();
+ else if (str.Last() == '%') {
+ wxString label = m_Label->GetLabel();
+ if (label.Last() == '\n') label.RemoveLast();
+ while (label.Last() == ' ') label.RemoveLast();
+ if (label.Last() == ':') label.RemoveLast();
+ show_error(m_parent, wxString::Format(_(L("%s doesn't support percentage")), label));
+ set_value(double_to_string(m_opt.min), true);
+ m_value = double(m_opt.min);
+ break;
+ }
double val;
- str.ToCDouble(&val);
- ret_val = val;
+ if(!str.ToCDouble(&val))
+ {
+ show_error(m_parent, _(L("Input value contains incorrect symbol(s).\nUse, please, only digits")));
+ set_value(double_to_string(val), true);
+ }
+ if (m_opt.min > val || val > m_opt.max)
+ {
+ show_error(m_parent, _(L("Input value is out of range")));
+ if (m_opt.min > val) val = m_opt.min;
+ if (val > m_opt.max) val = m_opt.max;
+ set_value(double_to_string(val), true);
+ }
+ m_value = val;
break; }
case coString:
case coStrings:
case coFloatOrPercent:
- ret_val = str.ToStdString();
+ m_value = str.ToStdString();
break;
default:
break;
}
-
- return ret_val;
}
void TextCtrl::BUILD() {
@@ -124,10 +182,10 @@ namespace Slic3r { namespace GUI {
case coFloat:
{
double val = m_opt.type == coFloats ?
- static_cast<const ConfigOptionFloats*>(m_opt.default_value)->get_at(0) :
+ static_cast<const ConfigOptionFloats*>(m_opt.default_value)->get_at(m_opt_idx) :
m_opt.type == coFloat ?
m_opt.default_value->getFloat() :
- static_cast<const ConfigOptionPercents*>(m_opt.default_value)->get_at(0);
+ static_cast<const ConfigOptionPercents*>(m_opt.default_value)->get_at(m_opt_idx);
text_value = double_to_string(val);
break;
}
@@ -137,10 +195,8 @@ namespace Slic3r { namespace GUI {
case coStrings:
{
const ConfigOptionStrings *vec = static_cast<const ConfigOptionStrings*>(m_opt.default_value);
- if (vec == nullptr || vec->empty()) break;
- if (vec->size() > 1)
- break;
- text_value = vec->values.at(0);
+ if (vec == nullptr || vec->empty()) break; //for the case of empty default value
+ text_value = vec->get_at(m_opt_idx);
break;
}
default:
@@ -156,32 +212,70 @@ namespace Slic3r { namespace GUI {
//! to allow the default handling
event.Skip();
//! eliminating the g-code pop up text description
- temp->GetToolTip()->Enable(false);
+ bool flag = false;
+#ifdef __WXGTK__
+ // I have no idea why, but on GTK flag works in other way
+ flag = true;
+#endif // __WXGTK__
+ temp->GetToolTip()->Enable(flag);
}), temp->GetId());
+#if !defined(__WXGTK__)
temp->Bind(wxEVT_KILL_FOCUS, ([this, temp](wxEvent& e)
{
- on_kill_focus(e);
+ e.Skip();// on_kill_focus(e);
temp->GetToolTip()->Enable(true);
}), temp->GetId());
+#endif // __WXGTK__
+
+ temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent& evt)
+ {
+#ifdef __WXGTK__
+ if (bChangedValueEvent)
+#endif //__WXGTK__
+ on_change_field();
+ }), temp->GetId());
- temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent) { on_change_field(); }), temp->GetId());
+#ifdef __WXGTK__
+ // to correct value updating on GTK we should:
+ // call on_change_field() on wxEVT_KEY_UP instead of wxEVT_TEXT
+ // and prevent value updating on wxEVT_KEY_DOWN
+ temp->Bind(wxEVT_KEY_DOWN, &TextCtrl::change_field_value, this);
+ temp->Bind(wxEVT_KEY_UP, &TextCtrl::change_field_value, this);
+#endif //__WXGTK__
+
+ // select all text using Ctrl+A
+ temp->Bind(wxEVT_CHAR, ([temp](wxKeyEvent& event)
+ {
+ if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL))
+ temp->SetSelection(-1, -1); //select all
+ event.Skip();
+ }));
// recast as a wxWindow to fit the calling convention
window = dynamic_cast<wxWindow*>(temp);
}
- boost::any TextCtrl::get_value()
+ boost::any& TextCtrl::get_value()
{
wxString ret_str = static_cast<wxTextCtrl*>(window)->GetValue();
- boost::any ret_val = get_value_by_opt_type(ret_str);
+ get_value_by_opt_type(ret_str);
- return ret_val;
+ return m_value;
}
void TextCtrl::enable() { dynamic_cast<wxTextCtrl*>(window)->Enable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(true); }
void TextCtrl::disable() { dynamic_cast<wxTextCtrl*>(window)->Disable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(false); }
+#ifdef __WXGTK__
+ void TextCtrl::change_field_value(wxEvent& event)
+ {
+ if (bChangedValueEvent = event.GetEventType()==wxEVT_KEY_UP)
+ on_change_field();
+ event.Skip();
+ };
+#endif //__WXGTK__
+
void CheckBox::BUILD() {
auto size = wxSize(wxDefaultSize);
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
@@ -189,7 +283,7 @@ void CheckBox::BUILD() {
bool check_value = m_opt.type == coBool ?
m_opt.default_value->getBool() : m_opt.type == coBools ?
- static_cast<ConfigOptionBools*>(m_opt.default_value)->values.at(0) :
+ static_cast<const ConfigOptionBools*>(m_opt.default_value)->get_at(m_opt_idx) :
false;
auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size);
@@ -204,15 +298,15 @@ void CheckBox::BUILD() {
window = dynamic_cast<wxWindow*>(temp);
}
-boost::any CheckBox::get_value()
+boost::any& CheckBox::get_value()
{
- boost::any ret_val;
+// boost::any m_value;
bool value = dynamic_cast<wxCheckBox*>(window)->GetValue();
if (m_opt.type == coBool)
- ret_val = static_cast<bool>(value);
+ m_value = static_cast<bool>(value);
else
- ret_val = static_cast<unsigned char>(value);
- return ret_val;
+ m_value = static_cast<unsigned char>(value);
+ return m_value;
}
int undef_spin_val = -9999; //! Probably, It's not necessary
@@ -245,16 +339,14 @@ void SpinCtrl::BUILD() {
break;
}
- const int min_val = m_opt_id == "standby_temperature_delta" ?
- -500 : m_opt.min > 0 ?
- m_opt.min : 0;
+ const int min_val = m_opt.min == INT_MIN ? 0: m_opt.min;
const int max_val = m_opt.max < 2147483647 ? m_opt.max : 2147483647;
auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size,
0, min_val, max_val, default_value);
- temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) { tmp_value = undef_spin_val; on_change_field(); }), temp->GetId());
- temp->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e) { tmp_value = undef_spin_val; on_kill_focus(e); }), temp->GetId());
+// temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) { tmp_value = undef_spin_val; on_change_field(); }), temp->GetId());
+// temp->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e) { tmp_value = undef_spin_val; on_kill_focus(e); }), temp->GetId());
temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent e)
{
// # On OSX / Cocoa, wxSpinCtrl::GetValue() doesn't return the new value
@@ -295,7 +387,7 @@ void Choice::BUILD() {
}
else{
for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels){
- const wxString& str = m_opt_id == "support" ? L_str(el) : el;
+ const wxString& str = _(el);//m_opt_id == "support" ? _(el) : el;
temp->Append(str);
}
set_selection();
@@ -348,7 +440,7 @@ void Choice::set_selection()
break;
}
case coStrings:{
- text_value = static_cast<const ConfigOptionStrings*>(m_opt.default_value)->values.at(0);
+ text_value = static_cast<const ConfigOptionStrings*>(m_opt.default_value)->get_at(m_opt_idx);
size_t idx = 0;
for (auto el : m_opt.enum_values)
@@ -365,7 +457,7 @@ void Choice::set_selection()
}
}
-void Choice::set_value(const std::string value, bool change_event) //! Redundant?
+void Choice::set_value(const std::string& value, bool change_event) //! Redundant?
{
m_disable_change_event = !change_event;
@@ -384,7 +476,7 @@ void Choice::set_value(const std::string value, bool change_event) //! Redundan
m_disable_change_event = false;
}
-void Choice::set_value(boost::any value, bool change_event)
+void Choice::set_value(const boost::any& value, bool change_event)
{
m_disable_change_event = !change_event;
@@ -392,6 +484,7 @@ void Choice::set_value(boost::any value, bool change_event)
case coInt:
case coFloat:
case coPercent:
+ case coString:
case coStrings:{
wxString text_value;
if (m_opt.type == coInt)
@@ -405,14 +498,39 @@ void Choice::set_value(boost::any value, bool change_event)
break;
++idx;
}
-// if (m_opt.type == coPercent) text_value += "%";
idx == m_opt.enum_values.size() ?
dynamic_cast<wxComboBox*>(window)->SetValue(text_value) :
dynamic_cast<wxComboBox*>(window)->SetSelection(idx);
break;
}
case coEnum:{
- dynamic_cast<wxComboBox*>(window)->SetSelection(boost::any_cast<int>(value));
+ int val = boost::any_cast<int>(value);
+ if (m_opt_id.compare("external_fill_pattern") == 0)
+ {
+ if (!m_opt.enum_values.empty()){
+ std::string key;
+ t_config_enum_values map_names = ConfigOptionEnum<InfillPattern>::get_enum_values();
+ for (auto it : map_names) {
+ if (val == it.second) {
+ key = it.first;
+ break;
+ }
+ }
+
+ size_t idx = 0;
+ for (auto el : m_opt.enum_values)
+ {
+ if (el.compare(key) == 0)
+ break;
+ ++idx;
+ }
+
+ val = idx == m_opt.enum_values.size() ? 0 : idx;
+ }
+ else
+ val = 0;
+ }
+ dynamic_cast<wxComboBox*>(window)->SetSelection(val);
break;
}
default:
@@ -423,7 +541,7 @@ void Choice::set_value(boost::any value, bool change_event)
}
//! it's needed for _update_serial_ports()
-void Choice::set_values(const std::vector<std::string> values)
+void Choice::set_values(const std::vector<std::string>& values)
{
if (values.empty())
return;
@@ -434,6 +552,7 @@ void Choice::set_values(const std::vector<std::string> values)
auto ww = dynamic_cast<wxComboBox*>(window);
auto value = ww->GetValue();
ww->Clear();
+ ww->Append("");
for (auto el : values)
ww->Append(wxString(el));
ww->SetValue(value);
@@ -441,16 +560,19 @@ void Choice::set_values(const std::vector<std::string> values)
m_disable_change_event = false;
}
-boost::any Choice::get_value()
+boost::any& Choice::get_value()
{
- boost::any ret_val;
+// boost::any m_value;
wxString ret_str = static_cast<wxComboBox*>(window)->GetValue();
- if (m_opt_id == "support")
- return ret_str;
+ // options from right panel
+ std::vector <std::string> right_panel_options{ "support", "scale_unit" };
+ for (auto rp_option: right_panel_options)
+ if (m_opt_id == rp_option)
+ return m_value = boost::any(ret_str);
if (m_opt.type != coEnum)
- ret_val = get_value_by_opt_type(ret_str);
+ /*m_value = */get_value_by_opt_type(ret_str);
else
{
int ret_enum = static_cast<wxComboBox*>(window)->GetSelection();
@@ -461,22 +583,24 @@ boost::any Choice::get_value()
t_config_enum_values map_names = ConfigOptionEnum<InfillPattern>::get_enum_values();
int value = map_names.at(key);
- ret_val = static_cast<InfillPattern>(value);
+ m_value = static_cast<InfillPattern>(value);
}
else
- ret_val = static_cast<InfillPattern>(0);
+ m_value = static_cast<InfillPattern>(0);
}
if (m_opt_id.compare("fill_pattern") == 0)
- ret_val = static_cast<InfillPattern>(ret_enum);
+ m_value = static_cast<InfillPattern>(ret_enum);
else if (m_opt_id.compare("gcode_flavor") == 0)
- ret_val = static_cast<GCodeFlavor>(ret_enum);
+ m_value = static_cast<GCodeFlavor>(ret_enum);
else if (m_opt_id.compare("support_material_pattern") == 0)
- ret_val = static_cast<SupportMaterialPattern>(ret_enum);
+ m_value = static_cast<SupportMaterialPattern>(ret_enum);
else if (m_opt_id.compare("seam_position") == 0)
- ret_val = static_cast<SeamPosition>(ret_enum);
+ m_value = static_cast<SeamPosition>(ret_enum);
+ else if (m_opt_id.compare("host_type") == 0)
+ m_value = static_cast<PrintHostType>(ret_enum);
}
- return ret_val;
+ return m_value;
}
void ColourPicker::BUILD()
@@ -485,7 +609,7 @@ void ColourPicker::BUILD()
if (m_opt.height >= 0) size.SetHeight(m_opt.height);
if (m_opt.width >= 0) size.SetWidth(m_opt.width);
- wxString clr(static_cast<ConfigOptionStrings*>(m_opt.default_value)->values.at(0));
+ wxString clr(static_cast<const ConfigOptionStrings*>(m_opt.default_value)->get_at(m_opt_idx));
auto temp = new wxColourPickerCtrl(m_parent, wxID_ANY, clr, wxDefaultPosition, size);
// // recast as a wxWindow to fit the calling convention
@@ -496,14 +620,14 @@ void ColourPicker::BUILD()
temp->SetToolTip(get_tooltip_text(clr));
}
-boost::any ColourPicker::get_value(){
- boost::any ret_val;
+boost::any& ColourPicker::get_value(){
+// boost::any m_value;
auto colour = static_cast<wxColourPickerCtrl*>(window)->GetColour();
auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), colour.Red(), colour.Green(), colour.Blue());
- ret_val = clr_str.ToStdString();
+ m_value = clr_str.ToStdString();
- return ret_val;
+ return m_value;
}
void PointCtrl::BUILD()
@@ -517,10 +641,10 @@ void PointCtrl::BUILD()
//
wxSize field_size(40, -1);
- auto default_pt = static_cast<ConfigOptionPoints*>(m_opt.default_value)->values.at(0);
- double val = default_pt.x;
+ auto default_pt = static_cast<const ConfigOptionPoints*>(m_opt.default_value)->values.at(0);
+ double val = default_pt(0);
wxString X = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None);
- val = default_pt.y;
+ val = default_pt(1);
wxString Y = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None);
x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size);
@@ -541,22 +665,22 @@ void PointCtrl::BUILD()
y_textctrl->SetToolTip(get_tooltip_text(X+", "+Y));
}
-void PointCtrl::set_value(const Pointf value, bool change_event)
+void PointCtrl::set_value(const Vec2d& value, bool change_event)
{
m_disable_change_event = !change_event;
- double val = value.x;
+ double val = value(0);
x_textctrl->SetValue(val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None));
- val = value.y;
+ val = value(1);
y_textctrl->SetValue(val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None));
m_disable_change_event = false;
}
-void PointCtrl::set_value(boost::any value, bool change_event)
+void PointCtrl::set_value(const boost::any& value, bool change_event)
{
- Pointf pt;
- Pointf *ptf = boost::any_cast<Pointf>(&value);
+ Vec2d pt(Vec2d::Zero());
+ const Vec2d *ptf = boost::any_cast<Vec2d>(&value);
if (!ptf)
{
ConfigOptionPoints* pts = boost::any_cast<ConfigOptionPoints*>(value);
@@ -564,35 +688,96 @@ void PointCtrl::set_value(boost::any value, bool change_event)
}
else
pt = *ptf;
-// try
-// {
-// pt = boost::any_cast<ConfigOptionPoints*>(value)->values.at(0);
-// }
-// catch (const std::exception &e)
-// {
-// try{
-// pt = boost::any_cast<Pointf>(value);
-// }
-// catch (const std::exception &e)
-// {
-// std::cerr << "Error! Can't cast PointCtrl value" << m_opt_id << "\n";
-// return;
-// }
-// }
set_value(pt, change_event);
}
-boost::any PointCtrl::get_value()
+boost::any& PointCtrl::get_value()
+{
+ double x, y;
+ x_textctrl->GetValue().ToDouble(&x);
+ y_textctrl->GetValue().ToDouble(&y);
+ return m_value = Vec2d(x, y);
+}
+
+void StaticText::BUILD()
+{
+ auto size = wxSize(wxDefaultSize);
+ if (m_opt.height >= 0) size.SetHeight(m_opt.height);
+ if (m_opt.width >= 0) size.SetWidth(m_opt.width);
+
+ wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value);
+ auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size);
+ temp->SetFont(bold_font());
+
+ // // recast as a wxWindow to fit the calling convention
+ window = dynamic_cast<wxWindow*>(temp);
+
+ temp->SetToolTip(get_tooltip_text(legend));
+}
+
+void SliderCtrl::BUILD()
+{
+ auto size = wxSize(wxDefaultSize);
+ if (m_opt.height >= 0) size.SetHeight(m_opt.height);
+ if (m_opt.width >= 0) size.SetWidth(m_opt.width);
+
+ auto temp = new wxBoxSizer(wxHORIZONTAL);
+
+ auto def_val = static_cast<const ConfigOptionInt*>(m_opt.default_value)->value;
+ auto min = m_opt.min == INT_MIN ? 0 : m_opt.min;
+ auto max = m_opt.max == INT_MAX ? 100 : m_opt.max;
+
+ m_slider = new wxSlider(m_parent, wxID_ANY, def_val * m_scale,
+ min * m_scale, max * m_scale,
+ wxDefaultPosition, size);
+ wxSize field_size(40, -1);
+
+ m_textctrl = new wxTextCtrl(m_parent, wxID_ANY, wxString::Format("%d", m_slider->GetValue()/m_scale),
+ wxDefaultPosition, field_size);
+
+ temp->Add(m_slider, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL, 0);
+ temp->Add(m_textctrl, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+ m_slider->Bind(wxEVT_SLIDER, ([this](wxCommandEvent e) {
+ if (!m_disable_change_event){
+ int val = boost::any_cast<int>(get_value());
+ m_textctrl->SetLabel(wxString::Format("%d", val));
+ on_change_field();
+ }
+ }), m_slider->GetId());
+
+ m_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) {
+ std::string value = e.GetString().utf8_str().data();
+ if (is_matched(value, "^-?\\d+(\\.\\d*)?$")){
+ m_disable_change_event = true;
+ m_slider->SetValue(stoi(value)*m_scale);
+ m_disable_change_event = false;
+ on_change_field();
+ }
+ }), m_textctrl->GetId());
+
+ m_sizer = dynamic_cast<wxSizer*>(temp);
+}
+
+void SliderCtrl::set_value(const boost::any& value, bool change_event)
{
- Pointf ret_point;
- double val;
- x_textctrl->GetValue().ToDouble(&val);
- ret_point.x = val;
- y_textctrl->GetValue().ToDouble(&val);
- ret_point.y = val;
- return ret_point;
+ m_disable_change_event = !change_event;
+
+ m_slider->SetValue(boost::any_cast<int>(value)*m_scale);
+ int val = boost::any_cast<int>(get_value());
+ m_textctrl->SetLabel(wxString::Format("%d", val));
+
+ m_disable_change_event = false;
}
+boost::any& SliderCtrl::get_value()
+{
+// int ret_val;
+// x_textctrl->GetValue().ToDouble(&val);
+ return m_value = int(m_slider->GetValue()/m_scale);
+}
+
+
} // GUI
} // Slic3r
diff --git a/xs/src/slic3r/GUI/Field.hpp b/xs/src/slic3r/GUI/Field.hpp
index 2ddb5d9f8..c38658e2b 100644
--- a/xs/src/slic3r/GUI/Field.hpp
+++ b/xs/src/slic3r/GUI/Field.hpp
@@ -31,11 +31,36 @@ namespace Slic3r { namespace GUI {
class Field;
using t_field = std::unique_ptr<Field>;
using t_kill_focus = std::function<void()>;
-using t_change = std::function<void(t_config_option_key, boost::any)>;
-using t_back_to_init = std::function<void(std::string)>;
+using t_change = std::function<void(t_config_option_key, const boost::any&)>;
+using t_back_to_init = std::function<void(const std::string&)>;
wxString double_to_string(double const value);
+class MyButton : public wxButton
+{
+ bool hidden = false; // never show button if it's hidden ones
+public:
+ MyButton() {}
+ MyButton(wxWindow* parent, wxWindowID id, const wxString& label = wxEmptyString,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize, long style = 0,
+ const wxValidator& validator = wxDefaultValidator,
+ const wxString& name = wxTextCtrlNameStr)
+ {
+ this->Create(parent, id, label, pos, size, style, validator, name);
+ }
+
+ // overridden from wxWindow base class
+ virtual bool
+ AcceptsFocusFromKeyboard() const { return false; }
+
+ virtual bool Show(bool show = true) override {
+ if (!show)
+ hidden = true;
+ return wxButton::Show(!hidden);
+ }
+};
+
class Field {
protected:
// factory function to defer and enforce creation of derived type.
@@ -52,6 +77,8 @@ protected:
void on_change_field();
/// Call the attached m_back_to_initial_value method.
void on_back_to_initial_value();
+ /// Call the attached m_back_to_sys_value method.
+ void on_back_to_sys_value();
public:
/// parent wx item, opportunity to refactor (probably not necessary - data duplication)
@@ -63,38 +90,40 @@ public:
/// Function object to store callback passed in from owning object.
t_change m_on_change {nullptr};
- /// Function object to store callback passed in from owning object.
+ /// Function object to store callback passed in from owning object.
t_back_to_init m_back_to_initial_value{ nullptr };
+ t_back_to_init m_back_to_sys_value{ nullptr };
// This is used to avoid recursive invocation of the field change/update by wxWidgets.
bool m_disable_change_event {false};
- // This is used to avoid recursive invocation of the field change/update by wxWidgets.
bool m_is_modified_value {false};
+ bool m_is_nonsys_value {true};
/// Copy of ConfigOption for deduction purposes
const ConfigOptionDef m_opt {ConfigOptionDef()};
const t_config_option_key m_opt_id;//! {""};
+ int m_opt_idx = 0;
/// Sets a value for this control.
/// subclasses should overload with a specific version
/// Postcondition: Method does not fire the on_change event.
- virtual void set_value(boost::any value, bool change_event) = 0;
+ virtual void set_value(const boost::any& value, bool change_event) = 0;
/// Gets a boost::any representing this control.
/// subclasses should overload with a specific version
- virtual boost::any get_value() = 0;
+ virtual boost::any& get_value() = 0;
virtual void enable() = 0;
virtual void disable() = 0;
- wxStaticText* m_Label = nullptr;
- wxButton* m_Undo_btn = nullptr;
-
- /// Fires the enable or disable function, based on the input.
+ /// Fires the enable or disable function, based on the input.
inline void toggle(bool en) { en ? enable() : disable(); }
virtual wxString get_tooltip_text(const wxString& default_string);
+ // set icon to "UndoToSystemValue" button according to an inheritance of preset
+// void set_nonsys_btn_icon(const wxBitmap& icon);
+
Field(const ConfigOptionDef& opt, const t_config_option_key& id) : m_opt(opt), m_opt_id(id) {};
Field(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : m_parent(parent), m_opt(opt), m_opt_id(id) {};
@@ -102,8 +131,8 @@ public:
virtual wxSizer* getSizer() { return nullptr; }
virtual wxWindow* getWindow() { return nullptr; }
- bool is_matched(std::string string, std::string pattern);
- boost::any get_value_by_opt_type(wxString str);
+ bool is_matched(const std::string& string, const std::string& pattern);
+ void get_value_by_opt_type(wxString& str);
/// Factory method for generating new derived classes.
template<class T>
@@ -113,6 +142,84 @@ public:
p->PostInitialize();
return std::move(p); //!p;
}
+
+ bool set_undo_bitmap(const wxBitmap *bmp) {
+ if (m_undo_bitmap != bmp) {
+ m_undo_bitmap = bmp;
+ m_Undo_btn->SetBitmap(*bmp);
+ return true;
+ }
+ return false;
+ }
+
+ bool set_undo_to_sys_bitmap(const wxBitmap *bmp) {
+ if (m_undo_to_sys_bitmap != bmp) {
+ m_undo_to_sys_bitmap = bmp;
+ m_Undo_to_sys_btn->SetBitmap(*bmp);
+ return true;
+ }
+ return false;
+ }
+
+ bool set_label_colour(const wxColour *clr) {
+ if (m_Label == nullptr) return false;
+ if (m_label_color != clr) {
+ m_label_color = clr;
+ m_Label->SetForegroundColour(*clr);
+ m_Label->Refresh(true);
+ }
+ return false;
+ }
+
+ bool set_label_colour_force(const wxColour *clr) {
+ if (m_Label == nullptr) return false;
+ m_Label->SetForegroundColour(*clr);
+ m_Label->Refresh(true);
+ return false;
+ }
+
+ bool set_undo_tooltip(const wxString *tip) {
+ if (m_undo_tooltip != tip) {
+ m_undo_tooltip = tip;
+ m_Undo_btn->SetToolTip(*tip);
+ return true;
+ }
+ return false;
+ }
+
+ bool set_undo_to_sys_tooltip(const wxString *tip) {
+ if (m_undo_to_sys_tooltip != tip) {
+ m_undo_to_sys_tooltip = tip;
+ m_Undo_to_sys_btn->SetToolTip(*tip);
+ return true;
+ }
+ return false;
+ }
+
+ void set_side_text_ptr(wxStaticText* side_text) {
+ m_side_text = side_text;
+ }
+
+protected:
+ MyButton* m_Undo_btn = nullptr;
+ // Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
+ const wxBitmap* m_undo_bitmap = nullptr;
+ const wxString* m_undo_tooltip = nullptr;
+ MyButton* m_Undo_to_sys_btn = nullptr;
+ // Bitmap and Tooltip text for m_Undo_to_sys_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
+ const wxBitmap* m_undo_to_sys_bitmap = nullptr;
+ const wxString* m_undo_to_sys_tooltip = nullptr;
+
+ wxStaticText* m_Label = nullptr;
+ // Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
+ const wxColour* m_label_color = nullptr;
+
+ wxStaticText* m_side_text = nullptr;
+
+ // current value
+ boost::any m_value;
+
+ friend class OptionsGroup;
};
/// Convenience function, accepts a const reference to t_field and checks to see whether
@@ -120,32 +227,37 @@ public:
inline bool is_bad_field(const t_field& obj) { return obj->getSizer() == nullptr && obj->getWindow() == nullptr; }
/// Covenience function to determine whether this field is a valid window field.
-inline bool is_window_field(const t_field& obj) { return !is_bad_field(obj) && obj->getWindow() != nullptr; }
+inline bool is_window_field(const t_field& obj) { return !is_bad_field(obj) && obj->getWindow() != nullptr && obj->getSizer() == nullptr; }
/// Covenience function to determine whether this field is a valid sizer field.
inline bool is_sizer_field(const t_field& obj) { return !is_bad_field(obj) && obj->getSizer() != nullptr; }
class TextCtrl : public Field {
using Field::Field;
+#ifdef __WXGTK__
+ bool bChangedValueEvent = true;
+ void change_field_value(wxEvent& event);
+#endif //__WXGTK__
public:
TextCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
TextCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
+ ~TextCtrl() {}
void BUILD();
wxWindow* window {nullptr};
- virtual void set_value(std::string value, bool change_event = false) {
+ virtual void set_value(const std::string& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxTextCtrl*>(window)->SetValue(wxString(value));
m_disable_change_event = false;
}
- virtual void set_value(boost::any value, bool change_event = false) {
+ virtual void set_value(const boost::any& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxTextCtrl*>(window)->SetValue(boost::any_cast<wxString>(value));
m_disable_change_event = false;
}
- boost::any get_value() override;
+ boost::any& get_value() override;
virtual void enable();
virtual void disable();
@@ -157,6 +269,7 @@ class CheckBox : public Field {
public:
CheckBox(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
CheckBox(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
+ ~CheckBox() {}
wxWindow* window{ nullptr };
void BUILD() override;
@@ -166,12 +279,12 @@ public:
dynamic_cast<wxCheckBox*>(window)->SetValue(value);
m_disable_change_event = false;
}
- void set_value(boost::any value, bool change_event = false) {
+ void set_value(const boost::any& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxCheckBox*>(window)->SetValue(boost::any_cast<bool>(value));
m_disable_change_event = false;
}
- boost::any get_value() override;
+ boost::any& get_value() override;
void enable() override { dynamic_cast<wxCheckBox*>(window)->Enable(); }
void disable() override { dynamic_cast<wxCheckBox*>(window)->Disable(); }
@@ -183,24 +296,27 @@ class SpinCtrl : public Field {
public:
SpinCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id), tmp_value(-9999) {}
SpinCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id), tmp_value(-9999) {}
+ ~SpinCtrl() {}
int tmp_value;
wxWindow* window{ nullptr };
void BUILD() override;
- void set_value(const std::string value, bool change_event = false) {
+ void set_value(const std::string& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxSpinCtrl*>(window)->SetValue(value);
m_disable_change_event = false;
}
- void set_value(boost::any value, bool change_event = false) {
+ void set_value(const boost::any& value, bool change_event = false) {
m_disable_change_event = !change_event;
- dynamic_cast<wxSpinCtrl*>(window)->SetValue(boost::any_cast<int>(value));
+ tmp_value = boost::any_cast<int>(value);
+ dynamic_cast<wxSpinCtrl*>(window)->SetValue(tmp_value);
m_disable_change_event = false;
}
- boost::any get_value() override {
- return boost::any(dynamic_cast<wxSpinCtrl*>(window)->GetValue());
+ boost::any& get_value() override {
+// return boost::any(tmp_value);
+ return m_value = tmp_value;
}
void enable() override { dynamic_cast<wxSpinCtrl*>(window)->Enable(); }
@@ -213,15 +329,16 @@ class Choice : public Field {
public:
Choice(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
Choice(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
+ ~Choice() {}
wxWindow* window{ nullptr };
void BUILD() override;
void set_selection();
- void set_value(const std::string value, bool change_event = false);
- void set_value(boost::any value, bool change_event = false);
- void set_values(const std::vector<std::string> values);
- boost::any get_value() override;
+ void set_value(const std::string& value, bool change_event = false);
+ void set_value(const boost::any& value, bool change_event = false);
+ void set_values(const std::vector<std::string> &values);
+ boost::any& get_value() override;
void enable() override { dynamic_cast<wxComboBox*>(window)->Enable(); };
void disable() override{ dynamic_cast<wxComboBox*>(window)->Disable(); };
@@ -233,22 +350,23 @@ class ColourPicker : public Field {
public:
ColourPicker(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
ColourPicker(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
+ ~ColourPicker() {}
wxWindow* window{ nullptr };
void BUILD() override;
- void set_value(const std::string value, bool change_event = false) {
+ void set_value(const std::string& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxColourPickerCtrl*>(window)->SetColour(value);
m_disable_change_event = false;
}
- void set_value(boost::any value, bool change_event = false) {
+ void set_value(const boost::any& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxColourPickerCtrl*>(window)->SetColour(boost::any_cast<wxString>(value));
m_disable_change_event = false;
}
- boost::any get_value() override;
+ boost::any& get_value() override;
void enable() override { dynamic_cast<wxColourPickerCtrl*>(window)->Enable(); };
void disable() override{ dynamic_cast<wxColourPickerCtrl*>(window)->Disable(); };
@@ -260,29 +378,89 @@ class PointCtrl : public Field {
public:
PointCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
PointCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
+ ~PointCtrl() {}
wxSizer* sizer{ nullptr };
- wxTextCtrl* x_textctrl;
- wxTextCtrl* y_textctrl;
+ wxTextCtrl* x_textctrl{ nullptr };
+ wxTextCtrl* y_textctrl{ nullptr };
void BUILD() override;
- void set_value(const Pointf value, bool change_event = false);
- void set_value(boost::any value, bool change_event = false);
- boost::any get_value() override;
+ void set_value(const Vec2d& value, bool change_event = false);
+ void set_value(const boost::any& value, bool change_event = false);
+ boost::any& get_value() override;
void enable() override {
x_textctrl->Enable();
- y_textctrl->Enable(); };
+ y_textctrl->Enable(); }
void disable() override{
x_textctrl->Disable();
- y_textctrl->Disable(); };
+ y_textctrl->Disable(); }
wxSizer* getSizer() override { return sizer; }
};
+class StaticText : public Field {
+ using Field::Field;
+public:
+ StaticText(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
+ StaticText(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
+ ~StaticText() {}
+
+ wxWindow* window{ nullptr };
+ void BUILD() override;
+
+ void set_value(const std::string& value, bool change_event = false) {
+ m_disable_change_event = !change_event;
+ dynamic_cast<wxStaticText*>(window)->SetLabel(value);
+ m_disable_change_event = false;
+ }
+ void set_value(const boost::any& value, bool change_event = false) {
+ m_disable_change_event = !change_event;
+ dynamic_cast<wxStaticText*>(window)->SetLabel(boost::any_cast<wxString>(value));
+ m_disable_change_event = false;
+ }
+
+ boost::any& get_value()override { return m_value; }
+
+ void enable() override { dynamic_cast<wxStaticText*>(window)->Enable(); };
+ void disable() override{ dynamic_cast<wxStaticText*>(window)->Disable(); };
+ wxWindow* getWindow() override { return window; }
+};
+
+class SliderCtrl : public Field {
+ using Field::Field;
+public:
+ SliderCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
+ SliderCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
+ ~SliderCtrl() {}
+
+ wxSizer* m_sizer{ nullptr };
+ wxTextCtrl* m_textctrl{ nullptr };
+ wxSlider* m_slider{ nullptr };
+
+ int m_scale = 10;
+
+ void BUILD() override;
+
+ void set_value(const int value, bool change_event = false);
+ void set_value(const boost::any& value, bool change_event = false);
+ boost::any& get_value() override;
+
+ void enable() override {
+ m_slider->Enable();
+ m_textctrl->Enable();
+ m_textctrl->SetEditable(true);
+ }
+ void disable() override{
+ m_slider->Disable();
+ m_textctrl->Disable();
+ m_textctrl->SetEditable(false);
+ }
+ wxSizer* getSizer() override { return m_sizer; }
+ wxWindow* getWindow() override { return dynamic_cast<wxWindow*>(m_slider); }
+};
-#endif
} // GUI
} // Slic3r
-
+#endif /* SLIC3R_GUI_FIELD_HPP */
diff --git a/xs/src/slic3r/GUI/FirmwareDialog.cpp b/xs/src/slic3r/GUI/FirmwareDialog.cpp
new file mode 100644
index 000000000..d0cd9f8cf
--- /dev/null
+++ b/xs/src/slic3r/GUI/FirmwareDialog.cpp
@@ -0,0 +1,839 @@
+#include <numeric>
+#include <algorithm>
+#include <thread>
+#include <condition_variable>
+#include <stdexcept>
+#include <boost/format.hpp>
+#include <boost/asio.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/log/trivial.hpp>
+#include <boost/optional.hpp>
+
+#include "libslic3r/Utils.hpp"
+#include "avrdude/avrdude-slic3r.hpp"
+#include "GUI.hpp"
+#include "MsgDialog.hpp"
+#include "../Utils/HexFile.hpp"
+#include "../Utils/Serial.hpp"
+
+// wx includes need to come after asio because of the WinSock.h problem
+#include "FirmwareDialog.hpp"
+
+#include <wx/app.h>
+#include <wx/event.h>
+#include <wx/sizer.h>
+#include <wx/settings.h>
+#include <wx/timer.h>
+#include <wx/panel.h>
+#include <wx/button.h>
+#include <wx/filepicker.h>
+#include <wx/textctrl.h>
+#include <wx/stattext.h>
+#include <wx/combobox.h>
+#include <wx/gauge.h>
+#include <wx/collpane.h>
+#include <wx/msgdlg.h>
+#include <wx/filefn.h>
+
+
+namespace fs = boost::filesystem;
+namespace asio = boost::asio;
+using boost::system::error_code;
+using boost::optional;
+
+
+namespace Slic3r {
+
+using Utils::HexFile;
+using Utils::SerialPortInfo;
+using Utils::Serial;
+
+
+// USB IDs used to perform device lookup
+enum {
+ USB_VID_PRUSA = 0x2c99,
+ USB_PID_MK2 = 1,
+ USB_PID_MK3 = 2,
+ USB_PID_MMU_BOOT = 3,
+ USB_PID_MMU_APP = 4,
+};
+
+// This enum discriminates the kind of information in EVT_AVRDUDE,
+// it's stored in the ExtraLong field of wxCommandEvent.
+enum AvrdudeEvent
+{
+ AE_MESSAGE,
+ AE_PROGRESS,
+ AE_STATUS,
+ AE_EXIT,
+};
+
+wxDECLARE_EVENT(EVT_AVRDUDE, wxCommandEvent);
+wxDEFINE_EVENT(EVT_AVRDUDE, wxCommandEvent);
+
+wxDECLARE_EVENT(EVT_ASYNC_DIALOG, wxCommandEvent);
+wxDEFINE_EVENT(EVT_ASYNC_DIALOG, wxCommandEvent);
+
+
+// Private
+
+struct FirmwareDialog::priv
+{
+ enum AvrDudeComplete
+ {
+ AC_NONE,
+ AC_SUCCESS,
+ AC_FAILURE,
+ AC_USER_CANCELLED,
+ };
+
+ FirmwareDialog *q; // PIMPL back pointer ("Q-Pointer")
+
+ // GUI elements
+ wxComboBox *port_picker;
+ wxStaticText *port_autodetect;
+ wxFilePickerCtrl *hex_picker;
+ wxStaticText *txt_status;
+ wxGauge *progressbar;
+ wxCollapsiblePane *spoiler;
+ wxTextCtrl *txt_stdout;
+ wxButton *btn_rescan;
+ wxButton *btn_close;
+ wxButton *btn_flash;
+ wxString btn_flash_label_ready;
+ wxString btn_flash_label_flashing;
+ wxString label_status_flashing;
+
+ wxTimer timer_pulse;
+
+ // Async modal dialog during flashing
+ std::mutex mutex;
+ int modal_response;
+ std::condition_variable response_cv;
+
+ // Data
+ std::vector<SerialPortInfo> ports;
+ optional<SerialPortInfo> port;
+ HexFile hex_file;
+
+ // This is a shared pointer holding the background AvrDude task
+ // also serves as a status indication (it is set _iff_ the background task is running, otherwise it is reset).
+ AvrDude::Ptr avrdude;
+ std::string avrdude_config;
+ unsigned progress_tasks_done;
+ unsigned progress_tasks_bar;
+ bool user_cancelled;
+ const bool extra_verbose; // For debugging
+
+ priv(FirmwareDialog *q) :
+ q(q),
+ btn_flash_label_ready(_(L("Flash!"))),
+ btn_flash_label_flashing(_(L("Cancel"))),
+ label_status_flashing(_(L("Flashing in progress. Please do not disconnect the printer!"))),
+ timer_pulse(q),
+ avrdude_config((fs::path(::Slic3r::resources_dir()) / "avrdude" / "avrdude.conf").string()),
+ progress_tasks_done(0),
+ progress_tasks_bar(0),
+ user_cancelled(false),
+ extra_verbose(false)
+ {}
+
+ void find_serial_ports();
+ void fit_no_shrink();
+ void set_txt_status(const wxString &label);
+ void flashing_start(unsigned tasks);
+ void flashing_done(AvrDudeComplete complete);
+ void enable_port_picker(bool enable);
+ void load_hex_file(const wxString &path);
+ void queue_status(wxString message);
+ void queue_error(const wxString &message);
+
+ bool ask_model_id_mismatch(const std::string &printer_model);
+ bool check_model_id();
+ void wait_for_mmu_bootloader(unsigned retries);
+ void mmu_reboot(const SerialPortInfo &port);
+ void lookup_port_mmu();
+ void prepare_common();
+ void prepare_mk2();
+ void prepare_mk3();
+ void prepare_mm_control();
+ void perform_upload();
+
+ void user_cancel();
+ void on_avrdude(const wxCommandEvent &evt);
+ void on_async_dialog(const wxCommandEvent &evt);
+ void ensure_joined();
+};
+
+void FirmwareDialog::priv::find_serial_ports()
+{
+ auto new_ports = Utils::scan_serial_ports_extended();
+ if (new_ports != this->ports) {
+ this->ports = new_ports;
+ port_picker->Clear();
+ for (const auto &port : this->ports)
+ port_picker->Append(wxString::FromUTF8(port.friendly_name.data()));
+ if (ports.size() > 0) {
+ int idx = port_picker->GetValue().IsEmpty() ? 0 : -1;
+ for (int i = 0; i < (int)this->ports.size(); ++ i)
+ if (this->ports[i].is_printer) {
+ idx = i;
+ break;
+ }
+ if (idx != -1)
+ port_picker->SetSelection(idx);
+ }
+ }
+}
+
+void FirmwareDialog::priv::fit_no_shrink()
+{
+ // Ensure content fits into window and window is not shrinked
+ const auto old_size = q->GetSize();
+ q->Layout();
+ q->Fit();
+ const auto new_size = q->GetSize();
+ const auto new_width = std::max(old_size.GetWidth(), new_size.GetWidth());
+ const auto new_height = std::max(old_size.GetHeight(), new_size.GetHeight());
+ q->SetSize(new_width, new_height);
+}
+
+void FirmwareDialog::priv::set_txt_status(const wxString &label)
+{
+ const auto width = txt_status->GetSize().GetWidth();
+ txt_status->SetLabel(label);
+ txt_status->Wrap(width);
+
+ fit_no_shrink();
+}
+
+void FirmwareDialog::priv::flashing_start(unsigned tasks)
+{
+ modal_response = wxID_NONE;
+ txt_stdout->Clear();
+ set_txt_status(label_status_flashing);
+ txt_status->SetForegroundColour(GUI::get_label_clr_modified());
+ port_picker->Disable();
+ btn_rescan->Disable();
+ hex_picker->Disable();
+ btn_close->Disable();
+ btn_flash->SetLabel(btn_flash_label_flashing);
+ progressbar->SetRange(200 * tasks); // See progress callback below
+ progressbar->SetValue(0);
+ progress_tasks_done = 0;
+ progress_tasks_bar = 0;
+ user_cancelled = false;
+ timer_pulse.Start(50);
+}
+
+void FirmwareDialog::priv::flashing_done(AvrDudeComplete complete)
+{
+ auto text_color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
+ port_picker->Enable();
+ btn_rescan->Enable();
+ hex_picker->Enable();
+ btn_close->Enable();
+ btn_flash->SetLabel(btn_flash_label_ready);
+ txt_status->SetForegroundColour(text_color);
+ timer_pulse.Stop();
+ progressbar->SetValue(progressbar->GetRange());
+
+ switch (complete) {
+ case AC_SUCCESS: set_txt_status(_(L("Flashing succeeded!"))); break;
+ case AC_FAILURE: set_txt_status(_(L("Flashing failed. Please see the avrdude log below."))); break;
+ case AC_USER_CANCELLED: set_txt_status(_(L("Flashing cancelled."))); break;
+ default: break;
+ }
+}
+
+void FirmwareDialog::priv::enable_port_picker(bool enable)
+{
+ port_picker->Show(enable);
+ btn_rescan->Show(enable);
+ port_autodetect->Show(! enable);
+ q->Layout();
+ fit_no_shrink();
+}
+
+void FirmwareDialog::priv::load_hex_file(const wxString &path)
+{
+ hex_file = HexFile(path.wx_str());
+ enable_port_picker(hex_file.device != HexFile::DEV_MM_CONTROL);
+}
+
+void FirmwareDialog::priv::queue_status(wxString message)
+{
+ auto evt = new wxCommandEvent(EVT_AVRDUDE, this->q->GetId());
+ evt->SetExtraLong(AE_STATUS);
+ evt->SetString(std::move(message));
+ wxQueueEvent(this->q, evt);
+}
+
+void FirmwareDialog::priv::queue_error(const wxString &message)
+{
+ auto evt = new wxCommandEvent(EVT_AVRDUDE, this->q->GetId());
+ evt->SetExtraLong(AE_STATUS);
+ evt->SetString(wxString::Format(_(L("Flashing failed: %s")), message));
+
+ wxQueueEvent(this->q, evt); avrdude->cancel();
+}
+
+bool FirmwareDialog::priv::ask_model_id_mismatch(const std::string &printer_model)
+{
+ // model_id in the hex file doesn't match what the printer repoted.
+ // Ask the user if it should be flashed anyway.
+
+ std::unique_lock<std::mutex> lock(mutex);
+
+ auto evt = new wxCommandEvent(EVT_ASYNC_DIALOG, this->q->GetId());
+ evt->SetString(wxString::Format(_(L(
+ "This firmware hex file does not match the printer model.\n"
+ "The hex file is intended for: %s\n"
+ "Printer reported: %s\n\n"
+ "Do you want to continue and flash this hex file anyway?\n"
+ "Please only continue if you are sure this is the right thing to do.")),
+ hex_file.model_id, printer_model
+ ));
+ wxQueueEvent(this->q, evt);
+
+ response_cv.wait(lock, [this]() { return this->modal_response != wxID_NONE; });
+
+ if (modal_response == wxID_YES) {
+ return true;
+ } else {
+ user_cancel();
+ return false;
+ }
+}
+
+bool FirmwareDialog::priv::check_model_id()
+{
+ // XXX: The implementation in Serial doesn't currently work reliably enough to be used.
+ // Therefore, regretably, so far the check cannot be used and we just return true here.
+ // TODO: Rewrite Serial using more platform-native code.
+ return true;
+
+ // if (hex_file.model_id.empty()) {
+ // // No data to check against, assume it's ok
+ // return true;
+ // }
+
+ // asio::io_service io;
+ // Serial serial(io, port->port, 115200);
+ // serial.printer_setup();
+
+ // enum {
+ // TIMEOUT = 2000,
+ // RETREIES = 5,
+ // };
+
+ // if (! serial.printer_ready_wait(RETREIES, TIMEOUT)) {
+ // queue_error(wxString::Format(_(L("Could not connect to the printer at %s")), port->port));
+ // return false;
+ // }
+
+ // std::string line;
+ // error_code ec;
+ // serial.printer_write_line("PRUSA Rev");
+ // while (serial.read_line(TIMEOUT, line, ec)) {
+ // if (ec) {
+ // queue_error(wxString::Format(_(L("Could not connect to the printer at %s")), port->port));
+ // return false;
+ // }
+
+ // if (line == "ok") { continue; }
+
+ // if (line == hex_file.model_id) {
+ // return true;
+ // } else {
+ // return ask_model_id_mismatch(line);
+ // }
+
+ // line.clear();
+ // }
+
+ // return false;
+}
+
+void FirmwareDialog::priv::wait_for_mmu_bootloader(unsigned retries)
+{
+ enum {
+ SLEEP_MS = 500,
+ };
+
+ for (unsigned i = 0; i < retries && !user_cancelled; i++) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_MS));
+
+ auto ports = Utils::scan_serial_ports_extended();
+ ports.erase(std::remove_if(ports.begin(), ports.end(), [=](const SerialPortInfo &port ) {
+ return port.id_vendor != USB_VID_PRUSA && port.id_product != USB_PID_MMU_BOOT;
+ }), ports.end());
+
+ if (ports.size() == 1) {
+ port = ports[0];
+ return;
+ } else if (ports.size() > 1) {
+ BOOST_LOG_TRIVIAL(error) << "Several VID/PID 0x2c99/3 devices found";
+ queue_error(_(L("Multiple Original Prusa i3 MMU 2.0 devices found. Please only connect one at a time for flashing.")));
+ return;
+ }
+ }
+}
+
+void FirmwareDialog::priv::mmu_reboot(const SerialPortInfo &port)
+{
+ asio::io_service io;
+ Serial serial(io, port.port, 1200);
+ std::this_thread::sleep_for(std::chrono::milliseconds(50));
+}
+
+void FirmwareDialog::priv::lookup_port_mmu()
+{
+ BOOST_LOG_TRIVIAL(info) << "Flashing MMU 2.0, looking for VID/PID 0x2c99/3 or 0x2c99/4 ...";
+
+ auto ports = Utils::scan_serial_ports_extended();
+ ports.erase(std::remove_if(ports.begin(), ports.end(), [=](const SerialPortInfo &port ) {
+ return port.id_vendor != USB_VID_PRUSA &&
+ port.id_product != USB_PID_MMU_BOOT &&
+ port.id_product != USB_PID_MMU_APP;
+ }), ports.end());
+
+ if (ports.size() == 0) {
+ BOOST_LOG_TRIVIAL(info) << "MMU 2.0 device not found, asking the user to press Reset and waiting for the device to show up ...";
+
+ queue_status(_(L(
+ "The Multi Material Control device was not found.\n"
+ "If the device is connected, please press the Reset button next to the USB connector ..."
+ )));
+
+ wait_for_mmu_bootloader(30);
+ } else if (ports.size() > 1) {
+ BOOST_LOG_TRIVIAL(error) << "Several VID/PID 0x2c99/3 devices found";
+ queue_error(_(L("Multiple Original Prusa i3 MMU 2.0 devices found. Please only connect one at a time for flashing.")));
+ } else {
+ if (ports[0].id_product == USB_PID_MMU_APP) {
+ // The device needs to be rebooted into the bootloader mode
+ BOOST_LOG_TRIVIAL(info) << boost::format("Found VID/PID 0x2c99/4 at `%1%`, rebooting the device ...") % ports[0].port;
+ mmu_reboot(ports[0]);
+ wait_for_mmu_bootloader(10);
+ } else {
+ port = ports[0];
+ }
+ }
+}
+
+void FirmwareDialog::priv::prepare_common()
+{
+ std::vector<std::string> args {{
+ extra_verbose ? "-vvvvv" : "-v",
+ "-p", "atmega2560",
+ // Using the "Wiring" mode to program Rambo or Einsy, using the STK500v2 protocol (not the STK500).
+ // The Prusa's avrdude is patched to never send semicolons inside the data packets, as the USB to serial chip
+ // is flashed with a buggy firmware.
+ "-c", "wiring",
+ "-P", port->port,
+ "-b", "115200", // TODO: Allow other rates? Ditto elsewhere.
+ "-D",
+ "-U", (boost::format("flash:w:0:%1%:i") % hex_file.path.string()).str(),
+ }};
+
+ BOOST_LOG_TRIVIAL(info) << "Invoking avrdude, arguments: "
+ << std::accumulate(std::next(args.begin()), args.end(), args[0], [](std::string a, const std::string &b) {
+ return a + ' ' + b;
+ });
+
+ avrdude->push_args(std::move(args));
+}
+
+void FirmwareDialog::priv::prepare_mk2()
+{
+ if (! port) { return; }
+
+ if (! check_model_id()) {
+ avrdude->cancel();
+ return;
+ }
+
+ prepare_common();
+}
+
+void FirmwareDialog::priv::prepare_mk3()
+{
+ if (! port) { return; }
+
+ if (! check_model_id()) {
+ avrdude->cancel();
+ return;
+ }
+
+ prepare_common();
+
+ // The hex file also contains another section with l10n data to be flashed into the external flash on MK3 (Einsy)
+ // This is done via another avrdude invocation, here we build arg list for that:
+ std::vector<std::string> args {{
+ extra_verbose ? "-vvvvv" : "-v",
+ "-p", "atmega2560",
+ // Using the "Arduino" mode to program Einsy's external flash with languages, using the STK500 protocol (not the STK500v2).
+ // The Prusa's avrdude is patched again to never send semicolons inside the data packets.
+ "-c", "arduino",
+ "-P", port->port,
+ "-b", "115200",
+ "-D",
+ "-u", // disable safe mode
+ "-U", (boost::format("flash:w:1:%1%:i") % hex_file.path.string()).str(),
+ }};
+
+ BOOST_LOG_TRIVIAL(info) << "Invoking avrdude for external flash flashing, arguments: "
+ << std::accumulate(std::next(args.begin()), args.end(), args[0], [](std::string a, const std::string &b) {
+ return a + ' ' + b;
+ });
+
+ avrdude->push_args(std::move(args));
+}
+
+void FirmwareDialog::priv::prepare_mm_control()
+{
+ port = boost::none;
+ lookup_port_mmu();
+ if (! port) {
+ queue_error(_(L("The device could not have been found")));
+ return;
+ }
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("Found VID/PID 0x2c99/3 at `%1%`, flashing ...") % port->port;
+ queue_status(label_status_flashing);
+
+ std::vector<std::string> args {{
+ extra_verbose ? "-vvvvv" : "-v",
+ "-p", "atmega32u4",
+ "-c", "avr109",
+ "-P", port->port,
+ "-b", "57600",
+ "-D",
+ "-U", (boost::format("flash:w:0:%1%:i") % hex_file.path.string()).str(),
+ }};
+
+ BOOST_LOG_TRIVIAL(info) << "Invoking avrdude, arguments: "
+ << std::accumulate(std::next(args.begin()), args.end(), args[0], [](std::string a, const std::string &b) {
+ return a + ' ' + b;
+ });
+
+ avrdude->push_args(std::move(args));
+}
+
+
+void FirmwareDialog::priv::perform_upload()
+{
+ auto filename = hex_picker->GetPath();
+ if (filename.IsEmpty()) { return; }
+
+ load_hex_file(filename); // Might already be loaded, but we want to make sure it's fresh
+
+ int selection = port_picker->GetSelection();
+ if (selection != wxNOT_FOUND) {
+ port = this->ports[selection];
+
+ // Verify whether the combo box list selection equals to the combo box edit value.
+ if (wxString::FromUTF8(port->friendly_name.data()) != port_picker->GetValue()) {
+ return;
+ }
+ }
+
+ const bool extra_verbose = false; // For debugging
+
+ flashing_start(hex_file.device == HexFile::DEV_MK3 ? 2 : 1);
+
+ // Init the avrdude object
+ AvrDude avrdude(avrdude_config);
+
+ // It is ok here to use the q-pointer to the FirmwareDialog
+ // because the dialog ensures it doesn't exit before the background thread is done.
+ auto q = this->q;
+
+ avrdude
+ .on_run([this](AvrDude::Ptr avrdude) {
+ this->avrdude = std::move(avrdude);
+
+ try {
+ switch (this->hex_file.device) {
+ case HexFile::DEV_MK3:
+ this->prepare_mk3();
+ break;
+
+ case HexFile::DEV_MM_CONTROL:
+ this->prepare_mm_control();
+ break;
+
+ default:
+ this->prepare_mk2();
+ break;
+ }
+ } catch (const std::exception &ex) {
+ queue_error(wxString::Format(_(L("Error accessing port at %s: %s")), port->port, ex.what()));
+ }
+ })
+ .on_message(std::move([q, extra_verbose](const char *msg, unsigned /* size */) {
+ if (extra_verbose) {
+ BOOST_LOG_TRIVIAL(debug) << "avrdude: " << msg;
+ }
+
+ auto evt = new wxCommandEvent(EVT_AVRDUDE, q->GetId());
+ auto wxmsg = wxString::FromUTF8(msg);
+ evt->SetExtraLong(AE_MESSAGE);
+ evt->SetString(std::move(wxmsg));
+ wxQueueEvent(q, evt);
+ }))
+ .on_progress(std::move([q](const char * /* task */, unsigned progress) {
+ auto evt = new wxCommandEvent(EVT_AVRDUDE, q->GetId());
+ evt->SetExtraLong(AE_PROGRESS);
+ evt->SetInt(progress);
+ wxQueueEvent(q, evt);
+ }))
+ .on_complete(std::move([this]() {
+ auto evt = new wxCommandEvent(EVT_AVRDUDE, this->q->GetId());
+ evt->SetExtraLong(AE_EXIT);
+ evt->SetInt(this->avrdude->exit_code());
+ wxQueueEvent(this->q, evt);
+ }))
+ .run();
+}
+
+void FirmwareDialog::priv::user_cancel()
+{
+ if (avrdude) {
+ user_cancelled = true;
+ avrdude->cancel();
+ }
+}
+
+void FirmwareDialog::priv::on_avrdude(const wxCommandEvent &evt)
+{
+ AvrDudeComplete complete_kind;
+
+ switch (evt.GetExtraLong()) {
+ case AE_MESSAGE:
+ txt_stdout->AppendText(evt.GetString());
+ break;
+
+ case AE_PROGRESS:
+ // We try to track overall progress here.
+ // Avrdude performs 3 tasks per one memory operation ("-U" arg),
+ // first of which is reading of status data (very short).
+ // We use the timer_pulse during the very first task to indicate intialization
+ // and then display overall progress during the latter tasks.
+
+ if (progress_tasks_done > 0) {
+ progressbar->SetValue(progress_tasks_bar + evt.GetInt());
+ }
+
+ if (evt.GetInt() == 100) {
+ timer_pulse.Stop();
+ if (progress_tasks_done % 3 != 0) {
+ progress_tasks_bar += 100;
+ }
+ progress_tasks_done++;
+ }
+
+ break;
+
+ case AE_EXIT:
+ BOOST_LOG_TRIVIAL(info) << "avrdude exit code: " << evt.GetInt();
+
+ // Figure out the exit state
+ if (user_cancelled) { complete_kind = AC_USER_CANCELLED; }
+ else if (avrdude->cancelled()) { complete_kind = AC_NONE; } // Ie. cancelled programatically
+ else { complete_kind = evt.GetInt() == 0 ? AC_SUCCESS : AC_FAILURE; }
+
+ flashing_done(complete_kind);
+ ensure_joined();
+ break;
+
+ case AE_STATUS:
+ set_txt_status(evt.GetString());
+ break;
+
+ default:
+ break;
+ }
+}
+
+void FirmwareDialog::priv::on_async_dialog(const wxCommandEvent &evt)
+{
+ wxMessageDialog dlg(this->q, evt.GetString(), wxMessageBoxCaptionStr, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ modal_response = dlg.ShowModal();
+ }
+ response_cv.notify_all();
+}
+
+void FirmwareDialog::priv::ensure_joined()
+{
+ // Make sure the background thread is collected and the AvrDude object reset
+ if (avrdude) { avrdude->join(); }
+ avrdude.reset();
+}
+
+
+// Public
+
+FirmwareDialog::FirmwareDialog(wxWindow *parent) :
+ wxDialog(parent, wxID_ANY, _(L("Firmware flasher")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
+ p(new priv(this))
+{
+ enum {
+ DIALOG_MARGIN = 15,
+ SPACING = 10,
+ MIN_WIDTH = 600,
+ MIN_HEIGHT = 200,
+ MIN_HEIGHT_EXPANDED = 500,
+ };
+
+ wxFont status_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ status_font.MakeBold();
+ wxFont mono_font(wxFontInfo().Family(wxFONTFAMILY_TELETYPE));
+ mono_font.MakeSmaller();
+
+ // Create GUI components and layout
+
+ auto *panel = new wxPanel(this);
+ wxBoxSizer *vsizer = new wxBoxSizer(wxVERTICAL);
+ panel->SetSizer(vsizer);
+
+ auto *label_hex_picker = new wxStaticText(panel, wxID_ANY, _(L("Firmware image:")));
+ p->hex_picker = new wxFilePickerCtrl(panel, wxID_ANY);
+
+ auto *label_port_picker = new wxStaticText(panel, wxID_ANY, _(L("Serial port:")));
+ p->port_picker = new wxComboBox(panel, wxID_ANY);
+ p->port_autodetect = new wxStaticText(panel, wxID_ANY, _(L("Autodetected")));
+ p->btn_rescan = new wxButton(panel, wxID_ANY, _(L("Rescan")));
+ auto *port_sizer = new wxBoxSizer(wxHORIZONTAL);
+ port_sizer->Add(p->port_picker, 1, wxEXPAND | wxRIGHT, SPACING);
+ port_sizer->Add(p->btn_rescan, 0);
+ port_sizer->Add(p->port_autodetect, 1, wxEXPAND);
+ p->enable_port_picker(true);
+
+ auto *label_progress = new wxStaticText(panel, wxID_ANY, _(L("Progress:")));
+ p->progressbar = new wxGauge(panel, wxID_ANY, 1, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL | wxGA_SMOOTH);
+
+ auto *label_status = new wxStaticText(panel, wxID_ANY, _(L("Status:")));
+ p->txt_status = new wxStaticText(panel, wxID_ANY, _(L("Ready")));
+ p->txt_status->SetFont(status_font);
+
+ auto *grid = new wxFlexGridSizer(2, SPACING, SPACING);
+ grid->AddGrowableCol(1);
+
+ grid->Add(label_hex_picker, 0, wxALIGN_CENTER_VERTICAL);
+ grid->Add(p->hex_picker, 0, wxEXPAND);
+
+ grid->Add(label_port_picker, 0, wxALIGN_CENTER_VERTICAL);
+ grid->Add(port_sizer, 0, wxEXPAND);
+
+ grid->Add(label_progress, 0, wxALIGN_CENTER_VERTICAL);
+ grid->Add(p->progressbar, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL);
+
+ grid->Add(label_status, 0, wxALIGN_CENTER_VERTICAL);
+ grid->Add(p->txt_status, 0, wxEXPAND);
+
+ vsizer->Add(grid, 0, wxEXPAND | wxTOP | wxBOTTOM, SPACING);
+
+ p->spoiler = new wxCollapsiblePane(panel, wxID_ANY, _(L("Advanced: avrdude output log")), wxDefaultPosition, wxDefaultSize, wxCP_DEFAULT_STYLE | wxCP_NO_TLW_RESIZE);
+ auto *spoiler_pane = p->spoiler->GetPane();
+ auto *spoiler_sizer = new wxBoxSizer(wxVERTICAL);
+ p->txt_stdout = new wxTextCtrl(spoiler_pane, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY);
+ p->txt_stdout->SetFont(mono_font);
+ spoiler_sizer->Add(p->txt_stdout, 1, wxEXPAND);
+ spoiler_pane->SetSizer(spoiler_sizer);
+ // The doc says proportion need to be 0 for wxCollapsiblePane.
+ // Experience says it needs to be 1, otherwise things won't get sized properly.
+ vsizer->Add(p->spoiler, 1, wxEXPAND | wxBOTTOM, SPACING);
+
+ p->btn_close = new wxButton(panel, wxID_CLOSE);
+ p->btn_flash = new wxButton(panel, wxID_ANY, p->btn_flash_label_ready);
+ p->btn_flash->Disable();
+ auto *bsizer = new wxBoxSizer(wxHORIZONTAL);
+ bsizer->Add(p->btn_close);
+ bsizer->AddStretchSpacer();
+ bsizer->Add(p->btn_flash);
+ vsizer->Add(bsizer, 0, wxEXPAND);
+
+ auto *topsizer = new wxBoxSizer(wxVERTICAL);
+ topsizer->Add(panel, 1, wxEXPAND | wxALL, DIALOG_MARGIN);
+ SetMinSize(wxSize(MIN_WIDTH, MIN_HEIGHT));
+ SetSizerAndFit(topsizer);
+ const auto size = GetSize();
+ SetSize(std::max(size.GetWidth(), static_cast<int>(MIN_WIDTH)), std::max(size.GetHeight(), static_cast<int>(MIN_HEIGHT)));
+ Layout();
+
+ // Bind events
+
+ p->hex_picker->Bind(wxEVT_FILEPICKER_CHANGED, [this](wxFileDirPickerEvent& evt) {
+ if (wxFileExists(evt.GetPath())) {
+ this->p->load_hex_file(evt.GetPath());
+ this->p->btn_flash->Enable();
+ }
+ });
+
+ p->spoiler->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, [this](wxCollapsiblePaneEvent &evt) {
+ if (evt.GetCollapsed()) {
+ this->SetMinSize(wxSize(MIN_WIDTH, MIN_HEIGHT));
+ const auto new_height = this->GetSize().GetHeight() - this->p->txt_stdout->GetSize().GetHeight();
+ this->SetSize(this->GetSize().GetWidth(), new_height);
+ } else {
+ this->SetMinSize(wxSize(MIN_WIDTH, MIN_HEIGHT_EXPANDED));
+ }
+
+ this->Layout();
+ this->p->fit_no_shrink();
+ });
+
+ p->btn_close->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { this->Close(); });
+ p->btn_rescan->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { this->p->find_serial_ports(); });
+
+ p->btn_flash->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
+ if (this->p->avrdude) {
+ // Flashing is in progress, ask the user if they're really sure about canceling it
+ wxMessageDialog dlg(this,
+ _(L("Are you sure you want to cancel firmware flashing?\nThis could leave your printer in an unusable state!")),
+ _(L("Confirmation")),
+ wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
+ if (dlg.ShowModal() == wxID_YES) {
+ this->p->set_txt_status(_(L("Cancelling...")));
+ this->p->user_cancel();
+ }
+ } else {
+ // Start a flashing task
+ this->p->perform_upload();
+ }
+ });
+
+ Bind(wxEVT_TIMER, [this](wxTimerEvent &evt) { this->p->progressbar->Pulse(); });
+
+ Bind(EVT_AVRDUDE, [this](wxCommandEvent &evt) { this->p->on_avrdude(evt); });
+ Bind(EVT_ASYNC_DIALOG, [this](wxCommandEvent &evt) { this->p->on_async_dialog(evt); });
+
+ Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &evt) {
+ if (this->p->avrdude) {
+ evt.Veto();
+ } else {
+ evt.Skip();
+ }
+ });
+
+ p->find_serial_ports();
+}
+
+FirmwareDialog::~FirmwareDialog()
+{
+ // Needed bacuse of forward defs
+}
+
+void FirmwareDialog::run(wxWindow *parent)
+{
+ FirmwareDialog dialog(parent);
+ dialog.ShowModal();
+}
+
+
+}
diff --git a/xs/src/slic3r/GUI/FirmwareDialog.hpp b/xs/src/slic3r/GUI/FirmwareDialog.hpp
new file mode 100644
index 000000000..ad048bf5d
--- /dev/null
+++ b/xs/src/slic3r/GUI/FirmwareDialog.hpp
@@ -0,0 +1,31 @@
+#ifndef slic3r_FirmwareDialog_hpp_
+#define slic3r_FirmwareDialog_hpp_
+
+#include <memory>
+
+#include <wx/dialog.h>
+
+
+namespace Slic3r {
+
+
+class FirmwareDialog: public wxDialog
+{
+public:
+ FirmwareDialog(wxWindow *parent);
+ FirmwareDialog(FirmwareDialog &&) = delete;
+ FirmwareDialog(const FirmwareDialog &) = delete;
+ FirmwareDialog &operator=(FirmwareDialog &&) = delete;
+ FirmwareDialog &operator=(const FirmwareDialog &) = delete;
+ ~FirmwareDialog();
+
+ static void run(wxWindow *parent);
+private:
+ struct priv;
+ std::unique_ptr<priv> p;
+};
+
+
+}
+
+#endif
diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp
new file mode 100644
index 000000000..eebaffc2a
--- /dev/null
+++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp
@@ -0,0 +1,5505 @@
+#include "GLCanvas3D.hpp"
+
+#include "../../admesh/stl.h"
+#include "../../libslic3r/libslic3r.h"
+#include "../../slic3r/GUI/3DScene.hpp"
+#include "../../slic3r/GUI/GLShader.hpp"
+#include "../../slic3r/GUI/GUI.hpp"
+#include "../../slic3r/GUI/PresetBundle.hpp"
+#include "../../slic3r/GUI/GLGizmo.hpp"
+#include "../../libslic3r/ClipperUtils.hpp"
+#include "../../libslic3r/PrintConfig.hpp"
+#include "../../libslic3r/GCode/PreviewData.hpp"
+
+#include <GL/glew.h>
+
+#include <wx/glcanvas.h>
+#include <wx/timer.h>
+#include <wx/bitmap.h>
+#include <wx/dcmemory.h>
+#include <wx/image.h>
+#include <wx/settings.h>
+
+#include "../../libslic3r/Print.hpp"
+
+#include <tbb/parallel_for.h>
+#include <tbb/spin_mutex.h>
+
+#include <boost/log/trivial.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+
+#include <iostream>
+#include <float.h>
+#include <algorithm>
+
+static const float TRACKBALLSIZE = 0.8f;
+static const float GIMBALL_LOCK_THETA_MAX = 180.0f;
+static const float GROUND_Z = -0.02f;
+
+// phi / theta angles to orient the camera.
+static const float VIEW_DEFAULT[2] = { 45.0f, 45.0f };
+static const float VIEW_LEFT[2] = { 90.0f, 90.0f };
+static const float VIEW_RIGHT[2] = { -90.0f, 90.0f };
+static const float VIEW_TOP[2] = { 0.0f, 0.0f };
+static const float VIEW_BOTTOM[2] = { 0.0f, 180.0f };
+static const float VIEW_FRONT[2] = { 0.0f, 90.0f };
+static const float VIEW_REAR[2] = { 180.0f, 90.0f };
+
+static const float VARIABLE_LAYER_THICKNESS_BAR_WIDTH = 70.0f;
+static const float VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT = 22.0f;
+
+static const float UNIT_MATRIX[] = { 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f };
+
+static const float DEFAULT_BG_COLOR[3] = { 10.0f / 255.0f, 98.0f / 255.0f, 144.0f / 255.0f };
+static const float ERROR_BG_COLOR[3] = { 144.0f / 255.0f, 49.0f / 255.0f, 10.0f / 255.0f };
+
+namespace Slic3r {
+namespace GUI {
+
+bool GeometryBuffer::set_from_triangles(const Polygons& triangles, float z, bool generate_tex_coords)
+{
+ m_vertices.clear();
+ m_tex_coords.clear();
+
+ unsigned int v_size = 9 * (unsigned int)triangles.size();
+ unsigned int t_size = 6 * (unsigned int)triangles.size();
+ if (v_size == 0)
+ return false;
+
+ m_vertices = std::vector<float>(v_size, 0.0f);
+ if (generate_tex_coords)
+ m_tex_coords = std::vector<float>(t_size, 0.0f);
+
+ float min_x = unscale<float>(triangles[0].points[0](0));
+ float min_y = unscale<float>(triangles[0].points[0](1));
+ float max_x = min_x;
+ float max_y = min_y;
+
+ unsigned int v_coord = 0;
+ unsigned int t_coord = 0;
+ for (const Polygon& t : triangles)
+ {
+ for (unsigned int v = 0; v < 3; ++v)
+ {
+ const Point& p = t.points[v];
+ float x = unscale<float>(p(0));
+ float y = unscale<float>(p(1));
+
+ m_vertices[v_coord++] = x;
+ m_vertices[v_coord++] = y;
+ m_vertices[v_coord++] = z;
+
+ if (generate_tex_coords)
+ {
+ m_tex_coords[t_coord++] = x;
+ m_tex_coords[t_coord++] = y;
+
+ min_x = std::min(min_x, x);
+ max_x = std::max(max_x, x);
+ min_y = std::min(min_y, y);
+ max_y = std::max(max_y, y);
+ }
+ }
+ }
+
+ if (generate_tex_coords)
+ {
+ float size_x = max_x - min_x;
+ float size_y = max_y - min_y;
+
+ if ((size_x != 0.0f) && (size_y != 0.0f))
+ {
+ float inv_size_x = 1.0f / size_x;
+ float inv_size_y = -1.0f / size_y;
+ for (unsigned int i = 0; i < m_tex_coords.size(); i += 2)
+ {
+ m_tex_coords[i] *= inv_size_x;
+ m_tex_coords[i + 1] *= inv_size_y;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool GeometryBuffer::set_from_lines(const Lines& lines, float z)
+{
+ m_vertices.clear();
+ m_tex_coords.clear();
+
+ unsigned int size = 6 * (unsigned int)lines.size();
+ if (size == 0)
+ return false;
+
+ m_vertices = std::vector<float>(size, 0.0f);
+
+ unsigned int coord = 0;
+ for (const Line& l : lines)
+ {
+ m_vertices[coord++] = unscale<float>(l.a(0));
+ m_vertices[coord++] = unscale<float>(l.a(1));
+ m_vertices[coord++] = z;
+ m_vertices[coord++] = unscale<float>(l.b(0));
+ m_vertices[coord++] = unscale<float>(l.b(1));
+ m_vertices[coord++] = z;
+ }
+
+ return true;
+}
+
+const float* GeometryBuffer::get_vertices() const
+{
+ return m_vertices.data();
+}
+
+const float* GeometryBuffer::get_tex_coords() const
+{
+ return m_tex_coords.data();
+}
+
+unsigned int GeometryBuffer::get_vertices_count() const
+{
+ return (unsigned int)m_vertices.size() / 3;
+}
+
+Size::Size()
+ : m_width(0)
+ , m_height(0)
+{
+}
+
+Size::Size(int width, int height)
+ : m_width(width)
+ , m_height(height)
+{
+}
+
+int Size::get_width() const
+{
+ return m_width;
+}
+
+void Size::set_width(int width)
+{
+ m_width = width;
+}
+
+int Size::get_height() const
+{
+ return m_height;
+}
+
+void Size::set_height(int height)
+{
+ m_height = height;
+}
+
+Rect::Rect()
+ : m_left(0.0f)
+ , m_top(0.0f)
+ , m_right(0.0f)
+ , m_bottom(0.0f)
+{
+}
+
+Rect::Rect(float left, float top, float right, float bottom)
+ : m_left(left)
+ , m_top(top)
+ , m_right(right)
+ , m_bottom(bottom)
+{
+}
+
+float Rect::get_left() const
+{
+ return m_left;
+}
+
+void Rect::set_left(float left)
+{
+ m_left = left;
+}
+
+float Rect::get_top() const
+{
+ return m_top;
+}
+
+void Rect::set_top(float top)
+{
+ m_top = top;
+}
+
+float Rect::get_right() const
+{
+ return m_right;
+}
+
+void Rect::set_right(float right)
+{
+ m_right = right;
+}
+
+float Rect::get_bottom() const
+{
+ return m_bottom;
+}
+
+void Rect::set_bottom(float bottom)
+{
+ m_bottom = bottom;
+}
+
+GLCanvas3D::Camera::Camera()
+ : type(Ortho)
+ , zoom(1.0f)
+ , phi(45.0f)
+// , distance(0.0f)
+ , target(0.0, 0.0, 0.0)
+ , m_theta(45.0f)
+{
+}
+
+std::string GLCanvas3D::Camera::get_type_as_string() const
+{
+ switch (type)
+ {
+ default:
+ case Unknown:
+ return "unknown";
+// case Perspective:
+// return "perspective";
+ case Ortho:
+ return "ortho";
+ };
+}
+
+float GLCanvas3D::Camera::get_theta() const
+{
+ return m_theta;
+}
+
+void GLCanvas3D::Camera::set_theta(float theta)
+{
+ m_theta = clamp(0.0f, GIMBALL_LOCK_THETA_MAX, theta);
+}
+
+GLCanvas3D::Bed::Bed()
+ : m_type(Custom)
+{
+}
+
+bool GLCanvas3D::Bed::is_prusa() const
+{
+ return (m_type == MK2) || (m_type == MK3);
+}
+
+bool GLCanvas3D::Bed::is_custom() const
+{
+ return m_type == Custom;
+}
+
+const Pointfs& GLCanvas3D::Bed::get_shape() const
+{
+ return m_shape;
+}
+
+bool GLCanvas3D::Bed::set_shape(const Pointfs& shape)
+{
+ EType new_type = _detect_type();
+ if (m_shape == shape && m_type == new_type)
+ // No change, no need to update the UI.
+ return false;
+ m_shape = shape;
+ m_type = new_type;
+
+ _calc_bounding_box();
+
+ ExPolygon poly;
+ for (const Vec2d& p : m_shape)
+ {
+ poly.contour.append(Point(scale_(p(0)), scale_(p(1))));
+ }
+
+ _calc_triangles(poly);
+
+ const BoundingBox& bed_bbox = poly.contour.bounding_box();
+ _calc_gridlines(poly, bed_bbox);
+
+ m_polygon = offset_ex(poly.contour, (float)bed_bbox.radius() * 1.7f, jtRound, scale_(0.5))[0].contour;
+ // Let the calee to update the UI.
+ return true;
+}
+
+const BoundingBoxf3& GLCanvas3D::Bed::get_bounding_box() const
+{
+ return m_bounding_box;
+}
+
+bool GLCanvas3D::Bed::contains(const Point& point) const
+{
+ return m_polygon.contains(point);
+}
+
+Point GLCanvas3D::Bed::point_projection(const Point& point) const
+{
+ return m_polygon.point_projection(point);
+}
+
+void GLCanvas3D::Bed::render(float theta) const
+{
+ switch (m_type)
+ {
+ case MK2:
+ {
+ _render_mk2(theta);
+ break;
+ }
+ case MK3:
+ {
+ _render_mk3(theta);
+ break;
+ }
+ default:
+ case Custom:
+ {
+ _render_custom();
+ break;
+ }
+ }
+}
+
+void GLCanvas3D::Bed::_calc_bounding_box()
+{
+ m_bounding_box = BoundingBoxf3();
+ for (const Vec2d& p : m_shape)
+ {
+ m_bounding_box.merge(Vec3d(p(0), p(1), 0.0));
+ }
+}
+
+void GLCanvas3D::Bed::_calc_triangles(const ExPolygon& poly)
+{
+ Polygons triangles;
+ poly.triangulate(&triangles);
+
+ if (!m_triangles.set_from_triangles(triangles, GROUND_Z, m_type != Custom))
+ printf("Unable to create bed triangles\n");
+}
+
+void GLCanvas3D::Bed::_calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox)
+{
+ Polylines axes_lines;
+ for (coord_t x = bed_bbox.min(0); x <= bed_bbox.max(0); x += scale_(10.0))
+ {
+ Polyline line;
+ line.append(Point(x, bed_bbox.min(1)));
+ line.append(Point(x, bed_bbox.max(1)));
+ axes_lines.push_back(line);
+ }
+ for (coord_t y = bed_bbox.min(1); y <= bed_bbox.max(1); y += scale_(10.0))
+ {
+ Polyline line;
+ line.append(Point(bed_bbox.min(0), y));
+ line.append(Point(bed_bbox.max(0), y));
+ axes_lines.push_back(line);
+ }
+
+ // clip with a slightly grown expolygon because our lines lay on the contours and may get erroneously clipped
+ Lines gridlines = to_lines(intersection_pl(axes_lines, offset(poly, SCALED_EPSILON)));
+
+ // append bed contours
+ Lines contour_lines = to_lines(poly);
+ std::copy(contour_lines.begin(), contour_lines.end(), std::back_inserter(gridlines));
+
+ if (!m_gridlines.set_from_lines(gridlines, GROUND_Z))
+ printf("Unable to create bed grid lines\n");
+}
+
+GLCanvas3D::Bed::EType GLCanvas3D::Bed::_detect_type() const
+{
+ EType type = Custom;
+
+ const PresetBundle* bundle = get_preset_bundle();
+ if (bundle != nullptr)
+ {
+ const Preset* curr = &bundle->printers.get_selected_preset();
+ while (curr != nullptr)
+ {
+ if (curr->config.has("bed_shape") && _are_equal(m_shape, dynamic_cast<const ConfigOptionPoints*>(curr->config.option("bed_shape"))->values))
+ {
+ if ((curr->vendor != nullptr) && (curr->vendor->name == "Prusa Research"))
+ {
+ if (boost::contains(curr->name, "MK2"))
+ {
+ type = MK2;
+ break;
+ }
+ else if (boost::contains(curr->name, "MK3"))
+ {
+ type = MK3;
+ break;
+ }
+ }
+ }
+
+ curr = bundle->printers.get_preset_parent(*curr);
+ }
+ }
+
+ return type;
+}
+
+void GLCanvas3D::Bed::_render_mk2(float theta) const
+{
+ std::string filename = resources_dir() + "/icons/bed/mk2_top.png";
+ if ((m_top_texture.get_id() == 0) || (m_top_texture.get_source() != filename))
+ {
+ if (!m_top_texture.load_from_file(filename, true))
+ {
+ _render_custom();
+ return;
+ }
+ }
+
+ filename = resources_dir() + "/icons/bed/mk2_bottom.png";
+ if ((m_bottom_texture.get_id() == 0) || (m_bottom_texture.get_source() != filename))
+ {
+ if (!m_bottom_texture.load_from_file(filename, true))
+ {
+ _render_custom();
+ return;
+ }
+ }
+
+ _render_prusa(theta);
+}
+
+void GLCanvas3D::Bed::_render_mk3(float theta) const
+{
+ std::string filename = resources_dir() + "/icons/bed/mk3_top.png";
+ if ((m_top_texture.get_id() == 0) || (m_top_texture.get_source() != filename))
+ {
+ if (!m_top_texture.load_from_file(filename, true))
+ {
+ _render_custom();
+ return;
+ }
+ }
+
+ filename = resources_dir() + "/icons/bed/mk3_bottom.png";
+ if ((m_bottom_texture.get_id() == 0) || (m_bottom_texture.get_source() != filename))
+ {
+ if (!m_bottom_texture.load_from_file(filename, true))
+ {
+ _render_custom();
+ return;
+ }
+ }
+
+ _render_prusa(theta);
+}
+
+void GLCanvas3D::Bed::_render_prusa(float theta) const
+{
+ unsigned int triangles_vcount = m_triangles.get_vertices_count();
+ if (triangles_vcount > 0)
+ {
+ ::glEnable(GL_DEPTH_TEST);
+ ::glDepthMask(GL_FALSE);
+
+ ::glEnable(GL_BLEND);
+ ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ ::glEnable(GL_TEXTURE_2D);
+ ::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ ::glEnableClientState(GL_VERTEX_ARRAY);
+ ::glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ if (theta > 90.0f)
+ ::glFrontFace(GL_CW);
+
+ ::glBindTexture(GL_TEXTURE_2D, (theta <= 90.0f) ? (GLuint)m_top_texture.get_id() : (GLuint)m_bottom_texture.get_id());
+ ::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_triangles.get_vertices());
+ ::glTexCoordPointer(2, GL_FLOAT, 0, (GLvoid*)m_triangles.get_tex_coords());
+ ::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount);
+
+ if (theta > 90.0f)
+ ::glFrontFace(GL_CCW);
+
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+ ::glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ ::glDisableClientState(GL_VERTEX_ARRAY);
+
+ ::glDisable(GL_TEXTURE_2D);
+
+ ::glDisable(GL_BLEND);
+ ::glDepthMask(GL_TRUE);
+ }
+}
+
+void GLCanvas3D::Bed::_render_custom() const
+{
+ m_top_texture.reset();
+ m_bottom_texture.reset();
+
+ unsigned int triangles_vcount = m_triangles.get_vertices_count();
+ if (triangles_vcount > 0)
+ {
+ ::glEnable(GL_LIGHTING);
+ ::glDisable(GL_DEPTH_TEST);
+
+ ::glEnable(GL_BLEND);
+ ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ ::glEnableClientState(GL_VERTEX_ARRAY);
+
+ ::glColor4f(0.8f, 0.6f, 0.5f, 0.4f);
+ ::glNormal3d(0.0f, 0.0f, 1.0f);
+ ::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_triangles.get_vertices());
+ ::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)triangles_vcount);
+
+ // draw grid
+ unsigned int gridlines_vcount = m_gridlines.get_vertices_count();
+
+ // we need depth test for grid, otherwise it would disappear when looking the object from below
+ ::glEnable(GL_DEPTH_TEST);
+ ::glLineWidth(3.0f);
+ ::glColor4f(0.2f, 0.2f, 0.2f, 0.4f);
+ ::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_gridlines.get_vertices());
+ ::glDrawArrays(GL_LINES, 0, (GLsizei)gridlines_vcount);
+
+ ::glDisableClientState(GL_VERTEX_ARRAY);
+
+ ::glDisable(GL_BLEND);
+ ::glDisable(GL_LIGHTING);
+ }
+}
+
+bool GLCanvas3D::Bed::_are_equal(const Pointfs& bed_1, const Pointfs& bed_2)
+{
+ if (bed_1.size() != bed_2.size())
+ return false;
+
+ for (unsigned int i = 0; i < (unsigned int)bed_1.size(); ++i)
+ {
+ if (bed_1[i] != bed_2[i])
+ return false;
+ }
+
+ return true;
+}
+
+GLCanvas3D::Axes::Axes()
+ : origin(0, 0, 0), length(0.0f)
+{
+}
+
+void GLCanvas3D::Axes::render(bool depth_test) const
+{
+ if (depth_test)
+ ::glEnable(GL_DEPTH_TEST);
+ else
+ ::glDisable(GL_DEPTH_TEST);
+
+ ::glLineWidth(2.0f);
+ ::glBegin(GL_LINES);
+ // draw line for x axis
+ ::glColor3f(1.0f, 0.0f, 0.0f);
+ ::glVertex3f((GLfloat)origin(0), (GLfloat)origin(1), (GLfloat)origin(2));
+ ::glVertex3f((GLfloat)origin(0) + length, (GLfloat)origin(1), (GLfloat)origin(2));
+ // draw line for y axis
+ ::glColor3f(0.0f, 1.0f, 0.0f);
+ ::glVertex3f((GLfloat)origin(0), (GLfloat)origin(1), (GLfloat)origin(2));
+ ::glVertex3f((GLfloat)origin(0), (GLfloat)origin(1) + length, (GLfloat)origin(2));
+ ::glEnd();
+ // draw line for Z axis
+ // (re-enable depth test so that axis is correctly shown when objects are behind it)
+ if (!depth_test)
+ ::glEnable(GL_DEPTH_TEST);
+
+ ::glBegin(GL_LINES);
+ ::glColor3f(0.0f, 0.0f, 1.0f);
+ ::glVertex3f((GLfloat)origin(0), (GLfloat)origin(1), (GLfloat)origin(2));
+ ::glVertex3f((GLfloat)origin(0), (GLfloat)origin(1), (GLfloat)origin(2) + length);
+ ::glEnd();
+}
+
+GLCanvas3D::CuttingPlane::CuttingPlane()
+ : m_z(-1.0f)
+{
+}
+
+bool GLCanvas3D::CuttingPlane::set(float z, const ExPolygons& polygons)
+{
+ m_z = z;
+
+ // grow slices in order to display them better
+ ExPolygons expolygons = offset_ex(polygons, scale_(0.1));
+ Lines lines = to_lines(expolygons);
+ return m_lines.set_from_lines(lines, m_z);
+}
+
+void GLCanvas3D::CuttingPlane::render(const BoundingBoxf3& bb) const
+{
+ _render_plane(bb);
+ _render_contour();
+}
+
+void GLCanvas3D::CuttingPlane::_render_plane(const BoundingBoxf3& bb) const
+{
+ if (m_z >= 0.0f)
+ {
+ ::glDisable(GL_CULL_FACE);
+ ::glEnable(GL_BLEND);
+ ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ float margin = 20.0f;
+ float min_x = bb.min(0) - margin;
+ float max_x = bb.max(0) + margin;
+ float min_y = bb.min(1) - margin;
+ float max_y = bb.max(1) + margin;
+
+ ::glBegin(GL_QUADS);
+ ::glColor4f(0.8f, 0.8f, 0.8f, 0.5f);
+ ::glVertex3f(min_x, min_y, m_z);
+ ::glVertex3f(max_x, min_y, m_z);
+ ::glVertex3f(max_x, max_y, m_z);
+ ::glVertex3f(min_x, max_y, m_z);
+ ::glEnd();
+
+ ::glEnable(GL_CULL_FACE);
+ ::glDisable(GL_BLEND);
+ }
+}
+
+void GLCanvas3D::CuttingPlane::_render_contour() const
+{
+ ::glEnableClientState(GL_VERTEX_ARRAY);
+
+ if (m_z >= 0.0f)
+ {
+ unsigned int lines_vcount = m_lines.get_vertices_count();
+
+ ::glLineWidth(2.0f);
+ ::glColor3f(0.0f, 0.0f, 0.0f);
+ ::glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)m_lines.get_vertices());
+ ::glDrawArrays(GL_LINES, 0, (GLsizei)lines_vcount);
+ }
+
+ ::glDisableClientState(GL_VERTEX_ARRAY);
+}
+
+GLCanvas3D::Shader::Shader()
+ : m_shader(nullptr)
+{
+}
+
+GLCanvas3D::Shader::~Shader()
+{
+ _reset();
+}
+
+bool GLCanvas3D::Shader::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename)
+{
+ if (is_initialized())
+ return true;
+
+ m_shader = new GLShader();
+ if (m_shader != nullptr)
+ {
+ if (!m_shader->load_from_file(fragment_shader_filename.c_str(), vertex_shader_filename.c_str()))
+ {
+ std::cout << "Compilaton of shader failed:" << std::endl;
+ std::cout << m_shader->last_error << std::endl;
+ _reset();
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool GLCanvas3D::Shader::is_initialized() const
+{
+ return (m_shader != nullptr);
+}
+
+bool GLCanvas3D::Shader::start_using() const
+{
+ if (is_initialized())
+ {
+ m_shader->enable();
+ return true;
+ }
+ else
+ return false;
+}
+
+void GLCanvas3D::Shader::stop_using() const
+{
+ if (m_shader != nullptr)
+ m_shader->disable();
+}
+
+void GLCanvas3D::Shader::set_uniform(const std::string& name, float value) const
+{
+ if (m_shader != nullptr)
+ m_shader->set_uniform(name.c_str(), value);
+}
+
+void GLCanvas3D::Shader::set_uniform(const std::string& name, const float* matrix) const
+{
+ if (m_shader != nullptr)
+ m_shader->set_uniform(name.c_str(), matrix);
+}
+
+const GLShader* GLCanvas3D::Shader::get_shader() const
+{
+ return m_shader;
+}
+
+void GLCanvas3D::Shader::_reset()
+{
+ if (m_shader != nullptr)
+ {
+ m_shader->release();
+ delete m_shader;
+ m_shader = nullptr;
+ }
+}
+
+GLCanvas3D::LayersEditing::LayersEditing()
+ : m_use_legacy_opengl(false)
+ , m_enabled(false)
+ , m_z_texture_id(0)
+ , state(Unknown)
+ , band_width(2.0f)
+ , strength(0.005f)
+ , last_object_id(-1)
+ , last_z(0.0f)
+ , last_action(0)
+{
+}
+
+GLCanvas3D::LayersEditing::~LayersEditing()
+{
+ if (m_z_texture_id != 0)
+ {
+ ::glDeleteTextures(1, &m_z_texture_id);
+ m_z_texture_id = 0;
+ }
+}
+
+bool GLCanvas3D::LayersEditing::init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename)
+{
+ if (!m_shader.init(vertex_shader_filename, fragment_shader_filename))
+ return false;
+
+ ::glGenTextures(1, (GLuint*)&m_z_texture_id);
+ ::glBindTexture(GL_TEXTURE_2D, m_z_texture_id);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+
+ return true;
+}
+
+bool GLCanvas3D::LayersEditing::is_allowed() const
+{
+ return !m_use_legacy_opengl && m_shader.is_initialized();
+}
+
+void GLCanvas3D::LayersEditing::set_use_legacy_opengl(bool use_legacy_opengl)
+{
+ m_use_legacy_opengl = use_legacy_opengl;
+}
+
+bool GLCanvas3D::LayersEditing::is_enabled() const
+{
+ return m_enabled;
+}
+
+void GLCanvas3D::LayersEditing::set_enabled(bool enabled)
+{
+ m_enabled = is_allowed() && enabled;
+}
+
+unsigned int GLCanvas3D::LayersEditing::get_z_texture_id() const
+{
+ return m_z_texture_id;
+}
+
+void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas, const PrintObject& print_object, const GLVolume& volume) const
+{
+ if (!m_enabled)
+ return;
+
+ const Rect& bar_rect = get_bar_rect_viewport(canvas);
+ const Rect& reset_rect = get_reset_rect_viewport(canvas);
+
+ ::glDisable(GL_DEPTH_TEST);
+
+ // The viewport and camera are set to complete view and glOrtho(-$x / 2, $x / 2, -$y / 2, $y / 2, -$depth, $depth),
+ // where x, y is the window size divided by $self->_zoom.
+ ::glPushMatrix();
+ ::glLoadIdentity();
+
+ _render_tooltip_texture(canvas, bar_rect, reset_rect);
+ _render_reset_texture(reset_rect);
+ _render_active_object_annotations(canvas, volume, print_object, bar_rect);
+ _render_profile(print_object, bar_rect);
+
+ // Revert the matrices.
+ ::glPopMatrix();
+
+ ::glEnable(GL_DEPTH_TEST);
+}
+
+int GLCanvas3D::LayersEditing::get_shader_program_id() const
+{
+ const GLShader* shader = m_shader.get_shader();
+ return (shader != nullptr) ? shader->shader_program_id : -1;
+}
+
+float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
+{
+ const Point& mouse_pos = canvas.get_local_mouse_position();
+ const Rect& rect = get_bar_rect_screen(canvas);
+ float x = (float)mouse_pos(0);
+ float y = (float)mouse_pos(1);
+ float t = rect.get_top();
+ float b = rect.get_bottom();
+
+ return ((rect.get_left() <= x) && (x <= rect.get_right()) && (t <= y) && (y <= b)) ?
+ // Inside the bar.
+ (b - y - 1.0f) / (b - t - 1.0f) :
+ // Outside the bar.
+ -1000.0f;
+}
+
+bool GLCanvas3D::LayersEditing::bar_rect_contains(const GLCanvas3D& canvas, float x, float y)
+{
+ const Rect& rect = get_bar_rect_screen(canvas);
+ return (rect.get_left() <= x) && (x <= rect.get_right()) && (rect.get_top() <= y) && (y <= rect.get_bottom());
+}
+
+bool GLCanvas3D::LayersEditing::reset_rect_contains(const GLCanvas3D& canvas, float x, float y)
+{
+ const Rect& rect = get_reset_rect_screen(canvas);
+ return (rect.get_left() <= x) && (x <= rect.get_right()) && (rect.get_top() <= y) && (y <= rect.get_bottom());
+}
+
+Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas)
+{
+ const Size& cnv_size = canvas.get_canvas_size();
+ float w = (float)cnv_size.get_width();
+ float h = (float)cnv_size.get_height();
+
+ return Rect(w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, 0.0f, w, h - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT);
+}
+
+Rect GLCanvas3D::LayersEditing::get_reset_rect_screen(const GLCanvas3D& canvas)
+{
+ const Size& cnv_size = canvas.get_canvas_size();
+ float w = (float)cnv_size.get_width();
+ float h = (float)cnv_size.get_height();
+
+ return Rect(w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, h - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT, w, h);
+}
+
+Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
+{
+ const Size& cnv_size = canvas.get_canvas_size();
+ float half_w = 0.5f * (float)cnv_size.get_width();
+ float half_h = 0.5f * (float)cnv_size.get_height();
+
+ float zoom = canvas.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+
+ return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom);
+}
+
+Rect GLCanvas3D::LayersEditing::get_reset_rect_viewport(const GLCanvas3D& canvas)
+{
+ const Size& cnv_size = canvas.get_canvas_size();
+ float half_w = 0.5f * (float)cnv_size.get_width();
+ float half_h = 0.5f * (float)cnv_size.get_height();
+
+ float zoom = canvas.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+
+ return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom);
+}
+
+
+bool GLCanvas3D::LayersEditing::_is_initialized() const
+{
+ return m_shader.is_initialized();
+}
+
+void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const
+{
+ if (m_tooltip_texture.get_id() == 0)
+ {
+ std::string filename = resources_dir() + "/icons/variable_layer_height_tooltip.png";
+ if (!m_tooltip_texture.load_from_file(filename, false))
+ return;
+ }
+
+ float zoom = canvas.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+ float gap = 10.0f * inv_zoom;
+
+ float bar_left = bar_rect.get_left();
+ float reset_bottom = reset_rect.get_bottom();
+
+ float l = bar_left - (float)m_tooltip_texture.get_width() * inv_zoom - gap;
+ float r = bar_left - gap;
+ float t = reset_bottom + (float)m_tooltip_texture.get_height() * inv_zoom + gap;
+ float b = reset_bottom + gap;
+
+ GLTexture::render_texture(m_tooltip_texture.get_id(), l, r, b, t);
+}
+
+void GLCanvas3D::LayersEditing::_render_reset_texture(const Rect& reset_rect) const
+{
+ if (m_reset_texture.get_id() == 0)
+ {
+ std::string filename = resources_dir() + "/icons/variable_layer_height_reset.png";
+ if (!m_reset_texture.load_from_file(filename, false))
+ return;
+ }
+
+ GLTexture::render_texture(m_reset_texture.get_id(), reset_rect.get_left(), reset_rect.get_right(), reset_rect.get_bottom(), reset_rect.get_top());
+}
+
+void GLCanvas3D::LayersEditing::_render_active_object_annotations(const GLCanvas3D& canvas, const GLVolume& volume, const PrintObject& print_object, const Rect& bar_rect) const
+{
+ float max_z = print_object.model_object()->bounding_box().max(2);
+
+ m_shader.start_using();
+
+ m_shader.set_uniform("z_to_texture_row", (float)volume.layer_height_texture_z_to_row_id());
+ m_shader.set_uniform("z_texture_row_to_normalized", 1.0f / (float)volume.layer_height_texture_height());
+ m_shader.set_uniform("z_cursor", max_z * get_cursor_z_relative(canvas));
+ m_shader.set_uniform("z_cursor_band_width", band_width);
+ // The shader requires the original model coordinates when rendering to the texture, so we pass it the unit matrix
+ m_shader.set_uniform("volume_world_matrix", UNIT_MATRIX);
+
+ GLsizei w = (GLsizei)volume.layer_height_texture_width();
+ GLsizei h = (GLsizei)volume.layer_height_texture_height();
+ GLsizei half_w = w / 2;
+ GLsizei half_h = h / 2;
+
+ ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ ::glBindTexture(GL_TEXTURE_2D, m_z_texture_id);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ ::glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, half_w, half_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ ::glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, volume.layer_height_texture_data_ptr_level0());
+ ::glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, half_w, half_h, GL_RGBA, GL_UNSIGNED_BYTE, volume.layer_height_texture_data_ptr_level1());
+
+ // Render the color bar
+ float l = bar_rect.get_left();
+ float r = bar_rect.get_right();
+ float t = bar_rect.get_top();
+ float b = bar_rect.get_bottom();
+
+ ::glBegin(GL_QUADS);
+ ::glVertex3f(l, b, 0.0f);
+ ::glVertex3f(r, b, 0.0f);
+ ::glVertex3f(r, t, max_z);
+ ::glVertex3f(l, t, max_z);
+ ::glEnd();
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+
+ m_shader.stop_using();
+}
+
+void GLCanvas3D::LayersEditing::_render_profile(const PrintObject& print_object, const Rect& bar_rect) const
+{
+ // FIXME show some kind of legend.
+
+ // Get a maximum layer height value.
+ // FIXME This is a duplicate code of Slicing.cpp.
+ double layer_height_max = DBL_MAX;
+ const PrintConfig& print_config = print_object.print()->config();
+ const std::vector<double>& nozzle_diameters = dynamic_cast<const ConfigOptionFloats*>(print_config.option("nozzle_diameter"))->values;
+ const std::vector<double>& layer_heights_min = dynamic_cast<const ConfigOptionFloats*>(print_config.option("min_layer_height"))->values;
+ const std::vector<double>& layer_heights_max = dynamic_cast<const ConfigOptionFloats*>(print_config.option("max_layer_height"))->values;
+ for (unsigned int i = 0; i < (unsigned int)nozzle_diameters.size(); ++i)
+ {
+ double lh_min = (layer_heights_min[i] == 0.0) ? 0.07 : std::max(0.01, layer_heights_min[i]);
+ double lh_max = (layer_heights_max[i] == 0.0) ? (0.75 * nozzle_diameters[i]) : layer_heights_max[i];
+ layer_height_max = std::min(layer_height_max, std::max(lh_min, lh_max));
+ }
+
+ // Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region.
+ layer_height_max *= 1.12;
+
+ double max_z = unscale<double>(print_object.size(2));
+ double layer_height = dynamic_cast<const ConfigOptionFloat*>(print_object.config().option("layer_height"))->value;
+ float l = bar_rect.get_left();
+ float w = bar_rect.get_right() - l;
+ float b = bar_rect.get_bottom();
+ float t = bar_rect.get_top();
+ float h = t - b;
+ float scale_x = w / (float)layer_height_max;
+ float scale_y = h / (float)max_z;
+ float x = l + (float)layer_height * scale_x;
+
+ // Baseline
+ ::glColor3f(0.0f, 0.0f, 0.0f);
+ ::glBegin(GL_LINE_STRIP);
+ ::glVertex2f(x, b);
+ ::glVertex2f(x, t);
+ ::glEnd();
+
+ // Curve
+ const ModelObject* model_object = print_object.model_object();
+ if (model_object->layer_height_profile_valid)
+ {
+ const std::vector<double>& profile = model_object->layer_height_profile;
+
+ ::glColor3f(0.0f, 0.0f, 1.0f);
+ ::glBegin(GL_LINE_STRIP);
+ for (unsigned int i = 0; i < profile.size(); i += 2)
+ {
+ ::glVertex2f(l + (float)profile[i + 1] * scale_x, b + (float)profile[i] * scale_y);
+ }
+ ::glEnd();
+ }
+}
+
+const Point GLCanvas3D::Mouse::Drag::Invalid_2D_Point(INT_MAX, INT_MAX);
+const Vec3d GLCanvas3D::Mouse::Drag::Invalid_3D_Point(DBL_MAX, DBL_MAX, DBL_MAX);
+
+GLCanvas3D::Mouse::Drag::Drag()
+ : start_position_2D(Invalid_2D_Point)
+ , start_position_3D(Invalid_3D_Point)
+ , volume_center_offset(0, 0, 0)
+ , move_with_shift(false)
+ , move_volume_idx(-1)
+ , gizmo_volume_idx(-1)
+{
+}
+
+GLCanvas3D::Mouse::Mouse()
+ : dragging(false)
+ , position(DBL_MAX, DBL_MAX)
+{
+}
+
+void GLCanvas3D::Mouse::set_start_position_2D_as_invalid()
+{
+ drag.start_position_2D = Drag::Invalid_2D_Point;
+}
+
+void GLCanvas3D::Mouse::set_start_position_3D_as_invalid()
+{
+ drag.start_position_3D = Drag::Invalid_3D_Point;
+}
+
+bool GLCanvas3D::Mouse::is_start_position_2D_defined() const
+{
+ return (drag.start_position_2D != Drag::Invalid_2D_Point);
+}
+
+bool GLCanvas3D::Mouse::is_start_position_3D_defined() const
+{
+ return (drag.start_position_3D != Drag::Invalid_3D_Point);
+}
+
+const float GLCanvas3D::Gizmos::OverlayTexturesScale = 0.75f;
+const float GLCanvas3D::Gizmos::OverlayOffsetX = 10.0f * OverlayTexturesScale;
+const float GLCanvas3D::Gizmos::OverlayGapY = 5.0f * OverlayTexturesScale;
+
+GLCanvas3D::Gizmos::Gizmos()
+ : m_enabled(false)
+ , m_current(Undefined)
+{
+}
+
+GLCanvas3D::Gizmos::~Gizmos()
+{
+ _reset();
+}
+
+bool GLCanvas3D::Gizmos::init(GLCanvas3D& parent)
+{
+ GLGizmoBase* gizmo = new GLGizmoMove3D(parent);
+ if (gizmo == nullptr)
+ return false;
+
+ if (!gizmo->init())
+ return false;
+
+ // temporary disable z grabber
+ gizmo->disable_grabber(2);
+
+ m_gizmos.insert(GizmosMap::value_type(Move, gizmo));
+
+ gizmo = new GLGizmoScale3D(parent);
+ if (gizmo == nullptr)
+ return false;
+
+ if (!gizmo->init())
+ return false;
+
+ // temporary disable x grabbers
+ gizmo->disable_grabber(0);
+ gizmo->disable_grabber(1);
+ // temporary disable y grabbers
+ gizmo->disable_grabber(2);
+ gizmo->disable_grabber(3);
+ // temporary disable z grabbers
+ gizmo->disable_grabber(4);
+ gizmo->disable_grabber(5);
+
+ m_gizmos.insert(GizmosMap::value_type(Scale, gizmo));
+
+ gizmo = new GLGizmoRotate3D(parent);
+ if (gizmo == nullptr)
+ {
+ _reset();
+ return false;
+ }
+
+ if (!gizmo->init())
+ {
+ _reset();
+ return false;
+ }
+
+ // temporary disable x and y grabbers
+ gizmo->disable_grabber(0);
+ gizmo->disable_grabber(1);
+
+ m_gizmos.insert(GizmosMap::value_type(Rotate, gizmo));
+
+ gizmo = new GLGizmoFlatten(parent);
+ if (gizmo == nullptr)
+ return false;
+
+ if (!gizmo->init()) {
+ _reset();
+ return false;
+ }
+
+ m_gizmos.insert(GizmosMap::value_type(Flatten, gizmo));
+
+
+ return true;
+}
+
+bool GLCanvas3D::Gizmos::is_enabled() const
+{
+ return m_enabled;
+}
+
+void GLCanvas3D::Gizmos::set_enabled(bool enable)
+{
+ m_enabled = enable;
+}
+
+void GLCanvas3D::Gizmos::update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos)
+{
+ if (!m_enabled)
+ return;
+
+ float cnv_h = (float)canvas.get_canvas_size().get_height();
+ float height = _get_total_overlay_height();
+ float top_y = 0.5f * (cnv_h - height);
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if (it->second == nullptr)
+ continue;
+
+ float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale;
+ float half_tex_size = 0.5f * tex_size;
+
+ // we currently use circular icons for gizmo, so we check the radius
+ if (it->second->get_state() != GLGizmoBase::On)
+ {
+ bool inside = (mouse_pos - Vec2d(OverlayOffsetX + half_tex_size, top_y + half_tex_size)).norm() < half_tex_size;
+ it->second->set_state(inside ? GLGizmoBase::Hover : GLGizmoBase::Off);
+ }
+ top_y += (tex_size + OverlayGapY);
+ }
+}
+
+void GLCanvas3D::Gizmos::update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos)
+{
+ if (!m_enabled)
+ return;
+
+ float cnv_h = (float)canvas.get_canvas_size().get_height();
+ float height = _get_total_overlay_height();
+ float top_y = 0.5f * (cnv_h - height);
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if (it->second == nullptr)
+ continue;
+
+ float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale;
+ float half_tex_size = 0.5f * tex_size;
+
+ // we currently use circular icons for gizmo, so we check the radius
+ if ((mouse_pos - Vec2d(OverlayOffsetX + half_tex_size, top_y + half_tex_size)).norm() < half_tex_size)
+ {
+ if ((it->second->get_state() == GLGizmoBase::On))
+ {
+ it->second->set_state(GLGizmoBase::Off);
+ m_current = Undefined;
+ }
+ else
+ {
+ it->second->set_state(GLGizmoBase::On);
+ m_current = it->first;
+ }
+ }
+ else
+ it->second->set_state(GLGizmoBase::Off);
+
+ top_y += (tex_size + OverlayGapY);
+ }
+}
+
+void GLCanvas3D::Gizmos::reset_all_states()
+{
+ if (!m_enabled)
+ return;
+
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if (it->second != nullptr)
+ {
+ it->second->set_state(GLGizmoBase::Off);
+ it->second->set_hover_id(-1);
+ }
+ }
+
+ m_current = Undefined;
+}
+
+void GLCanvas3D::Gizmos::set_hover_id(int id)
+{
+ if (!m_enabled)
+ return;
+
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if ((it->second != nullptr) && (it->second->get_state() == GLGizmoBase::On))
+ it->second->set_hover_id(id);
+ }
+}
+
+bool GLCanvas3D::Gizmos::overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const
+{
+ if (!m_enabled)
+ return false;
+
+ float cnv_h = (float)canvas.get_canvas_size().get_height();
+ float height = _get_total_overlay_height();
+ float top_y = 0.5f * (cnv_h - height);
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ if (it->second == nullptr)
+ continue;
+
+ float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale;
+ float half_tex_size = 0.5f * tex_size;
+
+ // we currently use circular icons for gizmo, so we check the radius
+ if ((mouse_pos - Vec2d(OverlayOffsetX + half_tex_size, top_y + half_tex_size)).norm() < half_tex_size)
+ return true;
+
+ top_y += (tex_size + OverlayGapY);
+ }
+
+ return false;
+}
+
+bool GLCanvas3D::Gizmos::grabber_contains_mouse() const
+{
+ if (!m_enabled)
+ return false;
+
+ GLGizmoBase* curr = _get_current();
+ return (curr != nullptr) ? (curr->get_hover_id() != -1) : false;
+}
+
+void GLCanvas3D::Gizmos::update(const Linef3& mouse_ray)
+{
+ if (!m_enabled)
+ return;
+
+ GLGizmoBase* curr = _get_current();
+ if (curr != nullptr)
+ curr->update(mouse_ray);
+}
+
+GLCanvas3D::Gizmos::EType GLCanvas3D::Gizmos::get_current_type() const
+{
+ return m_current;
+}
+
+bool GLCanvas3D::Gizmos::is_running() const
+{
+ if (!m_enabled)
+ return false;
+
+ GLGizmoBase* curr = _get_current();
+ return (curr != nullptr) ? (curr->get_state() == GLGizmoBase::On) : false;
+}
+
+bool GLCanvas3D::Gizmos::is_dragging() const
+{
+ GLGizmoBase* curr = _get_current();
+ return (curr != nullptr) ? curr->is_dragging() : false;
+}
+
+void GLCanvas3D::Gizmos::start_dragging(const BoundingBoxf3& box)
+{
+ GLGizmoBase* curr = _get_current();
+ if (curr != nullptr)
+ curr->start_dragging(box);
+}
+
+void GLCanvas3D::Gizmos::stop_dragging()
+{
+ GLGizmoBase* curr = _get_current();
+ if (curr != nullptr)
+ curr->stop_dragging();
+}
+
+Vec3d GLCanvas3D::Gizmos::get_position() const
+{
+ if (!m_enabled)
+ return Vec3d::Zero();
+
+ GizmosMap::const_iterator it = m_gizmos.find(Move);
+ return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoMove3D*>(it->second)->get_position() : Vec3d::Zero();
+}
+
+void GLCanvas3D::Gizmos::set_position(const Vec3d& position)
+{
+ if (!m_enabled)
+ return;
+
+ GizmosMap::const_iterator it = m_gizmos.find(Move);
+ if (it != m_gizmos.end())
+ reinterpret_cast<GLGizmoMove3D*>(it->second)->set_position(position);
+}
+
+float GLCanvas3D::Gizmos::get_scale() const
+{
+ if (!m_enabled)
+ return 1.0f;
+
+ GizmosMap::const_iterator it = m_gizmos.find(Scale);
+ return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoScale3D*>(it->second)->get_scale_x() : 1.0f;
+}
+
+void GLCanvas3D::Gizmos::set_scale(float scale)
+{
+ if (!m_enabled)
+ return;
+
+ GizmosMap::const_iterator it = m_gizmos.find(Scale);
+ if (it != m_gizmos.end())
+ reinterpret_cast<GLGizmoScale3D*>(it->second)->set_scale(scale);
+}
+
+float GLCanvas3D::Gizmos::get_angle_z() const
+{
+ if (!m_enabled)
+ return 0.0f;
+
+ GizmosMap::const_iterator it = m_gizmos.find(Rotate);
+ return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoRotate3D*>(it->second)->get_angle_z() : 0.0f;
+}
+
+void GLCanvas3D::Gizmos::set_angle_z(float angle_z)
+{
+ if (!m_enabled)
+ return;
+
+ GizmosMap::const_iterator it = m_gizmos.find(Rotate);
+ if (it != m_gizmos.end())
+ reinterpret_cast<GLGizmoRotate3D*>(it->second)->set_angle_z(angle_z);
+}
+
+Vec3d GLCanvas3D::Gizmos::get_flattening_normal() const
+{
+ if (!m_enabled)
+ return Vec3d::Zero();
+
+ GizmosMap::const_iterator it = m_gizmos.find(Flatten);
+ return (it != m_gizmos.end()) ? reinterpret_cast<GLGizmoFlatten*>(it->second)->get_flattening_normal() : Vec3d::Zero();
+}
+
+void GLCanvas3D::Gizmos::set_flattening_data(const ModelObject* model_object)
+{
+ if (!m_enabled)
+ return;
+
+ GizmosMap::const_iterator it = m_gizmos.find(Flatten);
+ if (it != m_gizmos.end())
+ reinterpret_cast<GLGizmoFlatten*>(it->second)->set_flattening_data(model_object);
+}
+
+void GLCanvas3D::Gizmos::render_current_gizmo(const BoundingBoxf3& box) const
+{
+ if (!m_enabled)
+ return;
+
+ ::glDisable(GL_DEPTH_TEST);
+
+ if (box.radius() > 0.0)
+ _render_current_gizmo(box);
+}
+
+void GLCanvas3D::Gizmos::render_current_gizmo_for_picking_pass(const BoundingBoxf3& box) const
+{
+ if (!m_enabled)
+ return;
+
+ GLGizmoBase* curr = _get_current();
+ if (curr != nullptr)
+ curr->render_for_picking(box);
+}
+
+void GLCanvas3D::Gizmos::render_overlay(const GLCanvas3D& canvas) const
+{
+ if (!m_enabled)
+ return;
+
+ ::glDisable(GL_DEPTH_TEST);
+
+ ::glPushMatrix();
+ ::glLoadIdentity();
+
+ _render_overlay(canvas);
+
+ ::glPopMatrix();
+}
+
+void GLCanvas3D::Gizmos::_reset()
+{
+ for (GizmosMap::value_type& gizmo : m_gizmos)
+ {
+ delete gizmo.second;
+ gizmo.second = nullptr;
+ }
+
+ m_gizmos.clear();
+}
+
+void GLCanvas3D::Gizmos::_render_overlay(const GLCanvas3D& canvas) const
+{
+ if (m_gizmos.empty())
+ return;
+
+ float cnv_w = (float)canvas.get_canvas_size().get_width();
+ float zoom = canvas.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+
+ float height = _get_total_overlay_height();
+ float top_x = (OverlayOffsetX - 0.5f * cnv_w) * inv_zoom;
+ float top_y = 0.5f * height * inv_zoom;
+ float scaled_gap_y = OverlayGapY * inv_zoom;
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ float tex_size = (float)it->second->get_textures_size() * OverlayTexturesScale * inv_zoom;
+ GLTexture::render_texture(it->second->get_texture_id(), top_x, top_x + tex_size, top_y - tex_size, top_y);
+ top_y -= (tex_size + scaled_gap_y);
+ }
+}
+
+void GLCanvas3D::Gizmos::_render_current_gizmo(const BoundingBoxf3& box) const
+{
+ GLGizmoBase* curr = _get_current();
+ if (curr != nullptr)
+ curr->render(box);
+}
+
+float GLCanvas3D::Gizmos::_get_total_overlay_height() const
+{
+ float height = 0.0f;
+
+ for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it)
+ {
+ height += (float)it->second->get_textures_size();
+ if (std::distance(it, m_gizmos.end()) > 1)
+ height += OverlayGapY;
+ }
+
+ return height;
+}
+
+const unsigned char GLCanvas3D::WarningTexture::Background_Color[3] = { 9, 91, 134 };
+const unsigned char GLCanvas3D::WarningTexture::Opacity = 255;
+
+GLCanvas3D::WarningTexture::WarningTexture()
+ : GUI::GLTexture()
+ , m_original_width(0)
+ , m_original_height(0)
+{
+}
+
+bool GLCanvas3D::WarningTexture::generate(const std::string& msg)
+{
+ reset();
+
+ if (msg.empty())
+ return false;
+
+ wxMemoryDC memDC;
+ // select default font
+ wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ font.MakeLarger();
+ font.MakeBold();
+ memDC.SetFont(font);
+
+ // calculates texture size
+ wxCoord w, h;
+ memDC.GetTextExtent(msg, &w, &h);
+
+ int pow_of_two_size = next_highest_power_of_2(std::max<unsigned int>(w, h));
+
+ m_original_width = (int)w;
+ m_original_height = (int)h;
+ m_width = pow_of_two_size;
+ m_height = pow_of_two_size;
+
+ // generates bitmap
+ wxBitmap bitmap(m_width, m_height);
+
+#if defined(__APPLE__) || defined(_MSC_VER)
+ bitmap.UseAlpha();
+#endif
+
+ memDC.SelectObject(bitmap);
+ memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2])));
+ memDC.Clear();
+
+ memDC.SetTextForeground(*wxWHITE);
+
+ // draw message
+ memDC.DrawText(msg, 0, 0);
+
+ memDC.SelectObject(wxNullBitmap);
+
+ // Convert the bitmap into a linear data ready to be loaded into the GPU.
+ wxImage image = bitmap.ConvertToImage();
+ image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]);
+
+ // prepare buffer
+ std::vector<unsigned char> data(4 * m_width * m_height, 0);
+ for (int h = 0; h < m_height; ++h)
+ {
+ int hh = h * m_width;
+ unsigned char* px_ptr = data.data() + 4 * hh;
+ for (int w = 0; w < m_width; ++w)
+ {
+ *px_ptr++ = image.GetRed(w, h);
+ *px_ptr++ = image.GetGreen(w, h);
+ *px_ptr++ = image.GetBlue(w, h);
+ *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity;
+ }
+ }
+
+ // sends buffer to gpu
+ ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ ::glGenTextures(1, &m_id);
+ ::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+
+ return true;
+}
+
+void GLCanvas3D::WarningTexture::render(const GLCanvas3D& canvas) const
+{
+ if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0))
+ {
+ ::glDisable(GL_DEPTH_TEST);
+ ::glPushMatrix();
+ ::glLoadIdentity();
+
+ const Size& cnv_size = canvas.get_canvas_size();
+ float zoom = canvas.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+ float left = (-0.5f * (float)m_original_width) * inv_zoom;
+ float top = (-0.5f * (float)cnv_size.get_height() + (float)m_original_height + 2.0f) * inv_zoom;
+ float right = left + (float)m_original_width * inv_zoom;
+ float bottom = top - (float)m_original_height * inv_zoom;
+
+ float uv_left = 0.0f;
+ float uv_top = 0.0f;
+ float uv_right = (float)m_original_width / (float)m_width;
+ float uv_bottom = (float)m_original_height / (float)m_height;
+
+ GLTexture::Quad_UVs uvs;
+ uvs.left_top = { uv_left, uv_top };
+ uvs.left_bottom = { uv_left, uv_bottom };
+ uvs.right_bottom = { uv_right, uv_bottom };
+ uvs.right_top = { uv_right, uv_top };
+
+ GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs);
+
+ ::glPopMatrix();
+ ::glEnable(GL_DEPTH_TEST);
+ }
+}
+
+const unsigned char GLCanvas3D::LegendTexture::Squares_Border_Color[3] = { 64, 64, 64 };
+const unsigned char GLCanvas3D::LegendTexture::Background_Color[3] = { 9, 91, 134 };
+const unsigned char GLCanvas3D::LegendTexture::Opacity = 255;
+
+GLCanvas3D::LegendTexture::LegendTexture()
+ : GUI::GLTexture()
+ , m_original_width(0)
+ , m_original_height(0)
+{
+}
+
+bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
+{
+ reset();
+
+ // collects items to render
+ auto title = _(preview_data.get_legend_title());
+ const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors);
+
+ unsigned int items_count = (unsigned int)items.size();
+ if (items_count == 0)
+ // nothing to render, return
+ return false;
+
+ wxMemoryDC memDC;
+ // select default font
+ memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
+
+ // calculates texture size
+ wxCoord w, h;
+ memDC.GetTextExtent(title, &w, &h);
+ int title_width = (int)w;
+ int title_height = (int)h;
+
+ int max_text_width = 0;
+ int max_text_height = 0;
+ for (const GCodePreviewData::LegendItem& item : items)
+ {
+ memDC.GetTextExtent(GUI::from_u8(item.text), &w, &h);
+ max_text_width = std::max(max_text_width, (int)w);
+ max_text_height = std::max(max_text_height, (int)h);
+ }
+
+ m_original_width = std::max(2 * Px_Border + title_width, 2 * (Px_Border + Px_Square_Contour) + Px_Square + Px_Text_Offset + max_text_width);
+ m_original_height = 2 * (Px_Border + Px_Square_Contour) + title_height + Px_Title_Offset + items_count * Px_Square;
+ if (items_count > 1)
+ m_original_height += (items_count - 1) * Px_Square_Contour;
+
+ int pow_of_two_size = next_highest_power_of_2(std::max(m_original_width, m_original_height));
+
+ m_width = pow_of_two_size;
+ m_height = pow_of_two_size;
+
+ // generates bitmap
+ wxBitmap bitmap(m_width, m_height);
+
+#if defined(__APPLE__) || defined(_MSC_VER)
+ bitmap.UseAlpha();
+#endif
+
+ memDC.SelectObject(bitmap);
+ memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2])));
+ memDC.Clear();
+
+ memDC.SetTextForeground(*wxWHITE);
+
+ // draw title
+ int title_x = Px_Border;
+ int title_y = Px_Border;
+ memDC.DrawText(title, title_x, title_y);
+
+ // draw icons contours as background
+ int squares_contour_x = Px_Border;
+ int squares_contour_y = Px_Border + title_height + Px_Title_Offset;
+ int squares_contour_width = Px_Square + 2 * Px_Square_Contour;
+ int squares_contour_height = items_count * Px_Square + 2 * Px_Square_Contour;
+ if (items_count > 1)
+ squares_contour_height += (items_count - 1) * Px_Square_Contour;
+
+ wxColour color(Squares_Border_Color[0], Squares_Border_Color[1], Squares_Border_Color[2]);
+ wxPen pen(color);
+ wxBrush brush(color);
+ memDC.SetPen(pen);
+ memDC.SetBrush(brush);
+ memDC.DrawRectangle(wxRect(squares_contour_x, squares_contour_y, squares_contour_width, squares_contour_height));
+
+ // draw items (colored icon + text)
+ int icon_x = squares_contour_x + Px_Square_Contour;
+ int icon_x_inner = icon_x + 1;
+ int icon_y = squares_contour_y + Px_Square_Contour;
+ int icon_y_step = Px_Square + Px_Square_Contour;
+
+ int text_x = icon_x + Px_Square + Px_Text_Offset;
+ int text_y_offset = (Px_Square - max_text_height) / 2;
+
+ int px_inner_square = Px_Square - 2;
+
+ for (const GCodePreviewData::LegendItem& item : items)
+ {
+ // draw darker icon perimeter
+ const std::vector<unsigned char>& item_color_bytes = item.color.as_bytes();
+ wxImage::HSVValue dark_hsv = wxImage::RGBtoHSV(wxImage::RGBValue(item_color_bytes[0], item_color_bytes[1], item_color_bytes[2]));
+ dark_hsv.value *= 0.75;
+ wxImage::RGBValue dark_rgb = wxImage::HSVtoRGB(dark_hsv);
+ color.Set(dark_rgb.red, dark_rgb.green, dark_rgb.blue, item_color_bytes[3]);
+ pen.SetColour(color);
+ brush.SetColour(color);
+ memDC.SetPen(pen);
+ memDC.SetBrush(brush);
+ memDC.DrawRectangle(wxRect(icon_x, icon_y, Px_Square, Px_Square));
+
+ // draw icon interior
+ color.Set(item_color_bytes[0], item_color_bytes[1], item_color_bytes[2], item_color_bytes[3]);
+ pen.SetColour(color);
+ brush.SetColour(color);
+ memDC.SetPen(pen);
+ memDC.SetBrush(brush);
+ memDC.DrawRectangle(wxRect(icon_x_inner, icon_y + 1, px_inner_square, px_inner_square));
+
+ // draw text
+ memDC.DrawText(GUI::from_u8(item.text), text_x, icon_y + text_y_offset);
+
+ // update y
+ icon_y += icon_y_step;
+ }
+
+ memDC.SelectObject(wxNullBitmap);
+
+ // Convert the bitmap into a linear data ready to be loaded into the GPU.
+ wxImage image = bitmap.ConvertToImage();
+ image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]);
+
+ // prepare buffer
+ std::vector<unsigned char> data(4 * m_width * m_height, 0);
+ for (int h = 0; h < m_height; ++h)
+ {
+ int hh = h * m_width;
+ unsigned char* px_ptr = data.data() + 4 * hh;
+ for (int w = 0; w < m_width; ++w)
+ {
+ *px_ptr++ = image.GetRed(w, h);
+ *px_ptr++ = image.GetGreen(w, h);
+ *px_ptr++ = image.GetBlue(w, h);
+ *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity;
+ }
+ }
+
+ // sends buffer to gpu
+ ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ ::glGenTextures(1, &m_id);
+ ::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+
+ return true;
+}
+
+void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const
+{
+ if ((m_id > 0) && (m_original_width > 0) && (m_original_height > 0) && (m_width > 0) && (m_height > 0))
+ {
+ ::glDisable(GL_DEPTH_TEST);
+ ::glPushMatrix();
+ ::glLoadIdentity();
+
+ const Size& cnv_size = canvas.get_canvas_size();
+ float zoom = canvas.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+ float left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom;
+ float top = (0.5f * (float)cnv_size.get_height()) * inv_zoom;
+ float right = left + (float)m_original_width * inv_zoom;
+ float bottom = top - (float)m_original_height * inv_zoom;
+
+ float uv_left = 0.0f;
+ float uv_top = 0.0f;
+ float uv_right = (float)m_original_width / (float)m_width;
+ float uv_bottom = (float)m_original_height / (float)m_height;
+
+ GLTexture::Quad_UVs uvs;
+ uvs.left_top = { uv_left, uv_top };
+ uvs.left_bottom = { uv_left, uv_bottom };
+ uvs.right_bottom = { uv_right, uv_bottom };
+ uvs.right_top = { uv_right, uv_top };
+
+ GLTexture::render_sub_texture(m_id, left, right, bottom, top, uvs);
+
+ ::glPopMatrix();
+ ::glEnable(GL_DEPTH_TEST);
+ }
+}
+
+GLGizmoBase* GLCanvas3D::Gizmos::_get_current() const
+{
+ GizmosMap::const_iterator it = m_gizmos.find(m_current);
+ return (it != m_gizmos.end()) ? it->second : nullptr;
+}
+
+GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
+ : m_canvas(canvas)
+ , m_context(nullptr)
+ , m_timer(nullptr)
+ , m_toolbar(*this)
+ , m_config(nullptr)
+ , m_print(nullptr)
+ , m_model(nullptr)
+ , m_dirty(true)
+ , m_initialized(false)
+ , m_use_VBOs(false)
+ , m_force_zoom_to_bed_enabled(false)
+ , m_apply_zoom_to_volumes_filter(false)
+ , m_hover_volume_id(-1)
+ , m_toolbar_action_running(false)
+ , m_warning_texture_enabled(false)
+ , m_legend_texture_enabled(false)
+ , m_picking_enabled(false)
+ , m_moving_enabled(false)
+ , m_shader_enabled(false)
+ , m_dynamic_background_enabled(false)
+ , m_multisample_allowed(false)
+ , m_color_by("volume")
+ , m_select_by("object")
+ , m_drag_by("instance")
+ , m_reload_delayed(false)
+{
+ if (m_canvas != nullptr)
+ {
+ m_context = new wxGLContext(m_canvas);
+ m_timer = new wxTimer(m_canvas);
+ }
+}
+
+GLCanvas3D::~GLCanvas3D()
+{
+ reset_volumes();
+
+ if (m_timer != nullptr)
+ {
+ delete m_timer;
+ m_timer = nullptr;
+ }
+
+ if (m_context != nullptr)
+ {
+ delete m_context;
+ m_context = nullptr;
+ }
+
+ _deregister_callbacks();
+}
+
+bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl)
+{
+ if (m_initialized)
+ return true;
+
+ if ((m_canvas == nullptr) || (m_context == nullptr))
+ return false;
+
+ ::glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ ::glClearDepth(1.0f);
+
+ ::glDepthFunc(GL_LESS);
+
+ ::glEnable(GL_DEPTH_TEST);
+ ::glEnable(GL_CULL_FACE);
+ ::glEnable(GL_BLEND);
+ ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ // Set antialiasing / multisampling
+ ::glDisable(GL_LINE_SMOOTH);
+ ::glDisable(GL_POLYGON_SMOOTH);
+
+ // ambient lighting
+ GLfloat ambient[4] = { 0.3f, 0.3f, 0.3f, 1.0f };
+ ::glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
+
+ ::glEnable(GL_LIGHT0);
+ ::glEnable(GL_LIGHT1);
+
+ // light from camera
+ GLfloat specular_cam[4] = { 0.3f, 0.3f, 0.3f, 1.0f };
+ ::glLightfv(GL_LIGHT1, GL_SPECULAR, specular_cam);
+ GLfloat diffuse_cam[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
+ ::glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse_cam);
+
+ // light from above
+ GLfloat specular_top[4] = { 0.2f, 0.2f, 0.2f, 1.0f };
+ ::glLightfv(GL_LIGHT0, GL_SPECULAR, specular_top);
+ GLfloat diffuse_top[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
+ ::glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_top);
+
+ // Enables Smooth Color Shading; try GL_FLAT for (lack of) fun.
+ ::glShadeModel(GL_SMOOTH);
+
+ // A handy trick -- have surface material mirror the color.
+ ::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
+ ::glEnable(GL_COLOR_MATERIAL);
+
+ if (m_multisample_allowed)
+ ::glEnable(GL_MULTISAMPLE);
+
+ if (useVBOs && !m_shader.init("gouraud.vs", "gouraud.fs"))
+ return false;
+
+ if (useVBOs && !m_layers_editing.init("variable_layer_height.vs", "variable_layer_height.fs"))
+ return false;
+
+ m_use_VBOs = useVBOs;
+ m_layers_editing.set_use_legacy_opengl(use_legacy_opengl);
+
+ // on linux the gl context is not valid until the canvas is not shown on screen
+ // we defer the geometry finalization of volumes until the first call to render()
+ if (!m_volumes.empty())
+ m_volumes.finalize_geometry(m_use_VBOs);
+
+ if (m_gizmos.is_enabled() && !m_gizmos.init(*this))
+ return false;
+
+ if (!_init_toolbar())
+ return false;
+
+ m_initialized = true;
+
+ return true;
+}
+
+bool GLCanvas3D::set_current()
+{
+ if ((m_canvas != nullptr) && (m_context != nullptr))
+ return m_canvas->SetCurrent(*m_context);
+
+ return false;
+}
+
+void GLCanvas3D::set_as_dirty()
+{
+ m_dirty = true;
+}
+
+unsigned int GLCanvas3D::get_volumes_count() const
+{
+ return (unsigned int)m_volumes.volumes.size();
+}
+
+void GLCanvas3D::reset_volumes()
+{
+ if (!m_volumes.empty())
+ {
+ // ensures this canvas is current
+ if (!set_current())
+ return;
+
+ m_volumes.release_geometry();
+ m_volumes.clear();
+ m_dirty = true;
+ }
+
+ enable_warning_texture(false);
+ _reset_warning_texture();
+}
+
+void GLCanvas3D::deselect_volumes()
+{
+ for (GLVolume* vol : m_volumes.volumes)
+ {
+ if (vol != nullptr)
+ vol->selected = false;
+ }
+}
+
+void GLCanvas3D::select_volume(unsigned int id)
+{
+ if (id < (unsigned int)m_volumes.volumes.size())
+ {
+ GLVolume* vol = m_volumes.volumes[id];
+ if (vol != nullptr)
+ vol->selected = true;
+ }
+}
+
+void GLCanvas3D::update_volumes_selection(const std::vector<int>& selections)
+{
+ if (m_model == nullptr)
+ return;
+
+ if (selections.empty())
+ return;
+
+ for (unsigned int obj_idx = 0; obj_idx < (unsigned int)m_model->objects.size(); ++obj_idx)
+ {
+ if ((selections[obj_idx] == 1) && (obj_idx < (unsigned int)m_objects_volumes_idxs.size()))
+ {
+ const std::vector<int>& volume_idxs = m_objects_volumes_idxs[obj_idx];
+ for (int v : volume_idxs)
+ {
+ select_volume(v);
+ }
+ }
+ }
+}
+
+int GLCanvas3D::check_volumes_outside_state(const DynamicPrintConfig* config) const
+{
+ ModelInstance::EPrintVolumeState state;
+ m_volumes.check_outside_state(config, &state);
+ return (int)state;
+}
+
+bool GLCanvas3D::move_volume_up(unsigned int id)
+{
+ if ((id > 0) && (id < (unsigned int)m_volumes.volumes.size()))
+ {
+ std::swap(m_volumes.volumes[id - 1], m_volumes.volumes[id]);
+ std::swap(m_volumes.volumes[id - 1]->composite_id, m_volumes.volumes[id]->composite_id);
+ std::swap(m_volumes.volumes[id - 1]->select_group_id, m_volumes.volumes[id]->select_group_id);
+ std::swap(m_volumes.volumes[id - 1]->drag_group_id, m_volumes.volumes[id]->drag_group_id);
+ return true;
+ }
+
+ return false;
+}
+
+bool GLCanvas3D::move_volume_down(unsigned int id)
+{
+ if ((id >= 0) && (id + 1 < (unsigned int)m_volumes.volumes.size()))
+ {
+ std::swap(m_volumes.volumes[id + 1], m_volumes.volumes[id]);
+ std::swap(m_volumes.volumes[id + 1]->composite_id, m_volumes.volumes[id]->composite_id);
+ std::swap(m_volumes.volumes[id + 1]->select_group_id, m_volumes.volumes[id]->select_group_id);
+ std::swap(m_volumes.volumes[id + 1]->drag_group_id, m_volumes.volumes[id]->drag_group_id);
+ return true;
+ }
+
+ return false;
+}
+
+void GLCanvas3D::set_objects_selections(const std::vector<int>& selections)
+{
+ m_objects_selections = selections;
+}
+
+void GLCanvas3D::set_config(DynamicPrintConfig* config)
+{
+ m_config = config;
+}
+
+void GLCanvas3D::set_print(Print* print)
+{
+ m_print = print;
+}
+
+void GLCanvas3D::set_model(Model* model)
+{
+ m_model = model;
+}
+
+void GLCanvas3D::set_bed_shape(const Pointfs& shape)
+{
+ bool new_shape = m_bed.set_shape(shape);
+
+ // Set the origin and size for painting of the coordinate system axes.
+ m_axes.origin = Vec3d(0.0, 0.0, (double)GROUND_Z);
+ set_axes_length(0.3f * (float)m_bed.get_bounding_box().max_size());
+
+ if (new_shape)
+ {
+ // forces the selection of the proper camera target
+ if (m_volumes.volumes.empty())
+ zoom_to_bed();
+ else
+ zoom_to_volumes();
+ }
+
+ m_dirty = true;
+}
+
+void GLCanvas3D::set_auto_bed_shape()
+{
+ // draw a default square bed around object center
+ const BoundingBoxf3& bbox = volumes_bounding_box();
+ double max_size = bbox.max_size();
+ const Vec3d center = bbox.center();
+
+ Pointfs bed_shape;
+ bed_shape.reserve(4);
+ bed_shape.emplace_back(center(0) - max_size, center(1) - max_size);
+ bed_shape.emplace_back(center(0) + max_size, center(1) - max_size);
+ bed_shape.emplace_back(center(0) + max_size, center(1) + max_size);
+ bed_shape.emplace_back(center(0) - max_size, center(1) + max_size);
+
+ set_bed_shape(bed_shape);
+
+ // Set the origin for painting of the coordinate system axes.
+ m_axes.origin = Vec3d(center(0), center(1), (double)GROUND_Z);
+}
+
+void GLCanvas3D::set_axes_length(float length)
+{
+ m_axes.length = length;
+}
+
+void GLCanvas3D::set_cutting_plane(float z, const ExPolygons& polygons)
+{
+ m_cutting_plane.set(z, polygons);
+}
+
+void GLCanvas3D::set_color_by(const std::string& value)
+{
+ m_color_by = value;
+}
+
+void GLCanvas3D::set_select_by(const std::string& value)
+{
+ m_select_by = value;
+ m_volumes.set_select_by(value);
+}
+
+void GLCanvas3D::set_drag_by(const std::string& value)
+{
+ m_drag_by = value;
+ m_volumes.set_drag_by(value);
+}
+
+const std::string& GLCanvas3D::get_select_by() const
+{
+ return m_select_by;
+}
+
+const std::string& GLCanvas3D::get_drag_by() const
+{
+ return m_drag_by;
+}
+
+float GLCanvas3D::get_camera_zoom() const
+{
+ return m_camera.zoom;
+}
+
+BoundingBoxf3 GLCanvas3D::volumes_bounding_box() const
+{
+ BoundingBoxf3 bb;
+ for (const GLVolume* volume : m_volumes.volumes)
+ {
+ if (!m_apply_zoom_to_volumes_filter || ((volume != nullptr) && volume->zoom_to_volumes))
+ bb.merge(volume->transformed_bounding_box());
+ }
+ return bb;
+}
+
+bool GLCanvas3D::is_layers_editing_enabled() const
+{
+ return m_layers_editing.is_enabled();
+}
+
+bool GLCanvas3D::is_layers_editing_allowed() const
+{
+ return m_layers_editing.is_allowed();
+}
+
+bool GLCanvas3D::is_shader_enabled() const
+{
+ return m_shader_enabled;
+}
+
+bool GLCanvas3D::is_reload_delayed() const
+{
+ return m_reload_delayed;
+}
+
+void GLCanvas3D::enable_layers_editing(bool enable)
+{
+ m_layers_editing.set_enabled(enable);
+}
+
+void GLCanvas3D::enable_warning_texture(bool enable)
+{
+ m_warning_texture_enabled = enable;
+}
+
+void GLCanvas3D::enable_legend_texture(bool enable)
+{
+ m_legend_texture_enabled = enable;
+}
+
+void GLCanvas3D::enable_picking(bool enable)
+{
+ m_picking_enabled = enable;
+}
+
+void GLCanvas3D::enable_moving(bool enable)
+{
+ m_moving_enabled = enable;
+}
+
+void GLCanvas3D::enable_gizmos(bool enable)
+{
+ m_gizmos.set_enabled(enable);
+}
+
+void GLCanvas3D::enable_toolbar(bool enable)
+{
+ m_toolbar.set_enabled(enable);
+}
+
+void GLCanvas3D::enable_shader(bool enable)
+{
+ m_shader_enabled = enable;
+}
+
+void GLCanvas3D::enable_force_zoom_to_bed(bool enable)
+{
+ m_force_zoom_to_bed_enabled = enable;
+}
+
+void GLCanvas3D::enable_dynamic_background(bool enable)
+{
+ m_dynamic_background_enabled = enable;
+}
+
+void GLCanvas3D::allow_multisample(bool allow)
+{
+ m_multisample_allowed = allow;
+}
+
+void GLCanvas3D::enable_toolbar_item(const std::string& name, bool enable)
+{
+ if (enable)
+ m_toolbar.enable_item(name);
+ else
+ m_toolbar.disable_item(name);
+}
+
+bool GLCanvas3D::is_toolbar_item_pressed(const std::string& name) const
+{
+ return m_toolbar.is_item_pressed(name);
+}
+
+void GLCanvas3D::zoom_to_bed()
+{
+ _zoom_to_bounding_box(m_bed.get_bounding_box());
+}
+
+void GLCanvas3D::zoom_to_volumes()
+{
+ m_apply_zoom_to_volumes_filter = true;
+ _zoom_to_bounding_box(volumes_bounding_box());
+ m_apply_zoom_to_volumes_filter = false;
+}
+
+void GLCanvas3D::select_view(const std::string& direction)
+{
+ const float* dir_vec = nullptr;
+
+ if (direction == "iso")
+ dir_vec = VIEW_DEFAULT;
+ else if (direction == "left")
+ dir_vec = VIEW_LEFT;
+ else if (direction == "right")
+ dir_vec = VIEW_RIGHT;
+ else if (direction == "top")
+ dir_vec = VIEW_TOP;
+ else if (direction == "bottom")
+ dir_vec = VIEW_BOTTOM;
+ else if (direction == "front")
+ dir_vec = VIEW_FRONT;
+ else if (direction == "rear")
+ dir_vec = VIEW_REAR;
+
+ if ((dir_vec != nullptr) && !empty(volumes_bounding_box()))
+ {
+ m_camera.phi = dir_vec[0];
+ m_camera.set_theta(dir_vec[1]);
+
+ m_on_viewport_changed_callback.call();
+
+ if (m_canvas != nullptr)
+ m_canvas->Refresh();
+ }
+}
+
+void GLCanvas3D::set_viewport_from_scene(const GLCanvas3D& other)
+{
+ m_camera.phi = other.m_camera.phi;
+ m_camera.set_theta(other.m_camera.get_theta());
+ m_camera.target = other.m_camera.target;
+ m_camera.zoom = other.m_camera.zoom;
+ m_dirty = true;
+}
+
+void GLCanvas3D::update_volumes_colors_by_extruder()
+{
+ if (m_config != nullptr)
+ m_volumes.update_colors_by_extruder(m_config);
+}
+
+void GLCanvas3D::update_gizmos_data()
+{
+ if (!m_gizmos.is_enabled())
+ return;
+
+ int id = _get_first_selected_object_id();
+ if ((id != -1) && (m_model != nullptr))
+ {
+ ModelObject* model_object = m_model->objects[id];
+ if (model_object != nullptr)
+ {
+ ModelInstance* model_instance = model_object->instances[0];
+ if (model_instance != nullptr)
+ {
+ m_gizmos.set_position(Vec3d(model_instance->offset(0), model_instance->offset(1), 0.0));
+ m_gizmos.set_scale(model_instance->scaling_factor);
+ m_gizmos.set_angle_z(model_instance->rotation);
+ m_gizmos.set_flattening_data(model_object);
+ }
+ }
+ }
+ else
+ {
+ m_gizmos.set_position(Vec3d::Zero());
+ m_gizmos.set_scale(1.0f);
+ m_gizmos.set_angle_z(0.0f);
+ m_gizmos.set_flattening_data(nullptr);
+ }
+}
+
+void GLCanvas3D::render()
+{
+ if (m_canvas == nullptr)
+ return;
+
+ if (!_is_shown_on_screen())
+ return;
+
+ // ensures this canvas is current and initialized
+ if (!set_current() || !_3DScene::init(m_canvas))
+ return;
+
+ if (m_force_zoom_to_bed_enabled)
+ _force_zoom_to_bed();
+
+ _camera_tranform();
+
+ GLfloat position_cam[4] = { 1.0f, 0.0f, 1.0f, 0.0f };
+ ::glLightfv(GL_LIGHT1, GL_POSITION, position_cam);
+ GLfloat position_top[4] = { -0.5f, -0.5f, 1.0f, 0.0f };
+ ::glLightfv(GL_LIGHT0, GL_POSITION, position_top);
+
+ float theta = m_camera.get_theta();
+ bool is_custom_bed = m_bed.is_custom();
+
+ // picking pass
+ _picking_pass();
+
+ // draw scene
+ _render_background();
+
+ if (is_custom_bed) // untextured bed needs to be rendered before objects
+ {
+ _render_bed(theta);
+ // disable depth testing so that axes are not covered by ground
+ _render_axes(false);
+ }
+ _render_objects();
+ if (!is_custom_bed) // textured bed needs to be rendered after objects
+ {
+ _render_axes(true);
+ _render_bed(theta);
+ }
+
+ _render_current_gizmo();
+ _render_cutting_plane();
+
+ // draw overlays
+ _render_gizmos_overlay();
+ _render_warning_texture();
+ _render_legend_texture();
+ _render_toolbar();
+ _render_layer_editing_overlay();
+
+ m_canvas->SwapBuffers();
+}
+
+std::vector<double> GLCanvas3D::get_current_print_zs(bool active_only) const
+{
+ return m_volumes.get_current_print_zs(active_only);
+}
+
+void GLCanvas3D::set_toolpaths_range(double low, double high)
+{
+ m_volumes.set_range(low, high);
+}
+
+std::vector<int> GLCanvas3D::load_object(const ModelObject& model_object, int obj_idx, std::vector<int> instance_idxs)
+{
+ if (instance_idxs.empty())
+ {
+ for (unsigned int i = 0; i < model_object.instances.size(); ++i)
+ {
+ instance_idxs.push_back(i);
+ }
+ }
+ return m_volumes.load_object(&model_object, obj_idx, instance_idxs, m_color_by, m_select_by, m_drag_by, m_use_VBOs && m_initialized);
+}
+
+std::vector<int> GLCanvas3D::load_object(const Model& model, int obj_idx)
+{
+ if ((0 <= obj_idx) && (obj_idx < (int)model.objects.size()))
+ {
+ const ModelObject* model_object = model.objects[obj_idx];
+ if (model_object != nullptr)
+ return load_object(*model_object, obj_idx, std::vector<int>());
+ }
+
+ return std::vector<int>();
+}
+
+int GLCanvas3D::get_first_volume_id(int obj_idx) const
+{
+ for (int i = 0; i < (int)m_volumes.volumes.size(); ++i)
+ {
+ if ((m_volumes.volumes[i] != nullptr) && (m_volumes.volumes[i]->object_idx() == obj_idx))
+ return i;
+ }
+
+ return -1;
+}
+
+void GLCanvas3D::reload_scene(bool force)
+{
+ if ((m_canvas == nullptr) || (m_config == nullptr) || (m_model == nullptr))
+ return;
+
+ reset_volumes();
+
+ // ensures this canvas is current
+ if (!set_current())
+ return;
+
+ set_bed_shape(dynamic_cast<const ConfigOptionPoints*>(m_config->option("bed_shape"))->values);
+
+ if (!m_canvas->IsShown() && !force)
+ {
+ m_reload_delayed = true;
+ return;
+ }
+
+ m_reload_delayed = false;
+
+ m_objects_volumes_idxs.clear();
+
+ for (unsigned int obj_idx = 0; obj_idx < (unsigned int)m_model->objects.size(); ++obj_idx)
+ {
+ m_objects_volumes_idxs.push_back(load_object(*m_model, obj_idx));
+ }
+
+ // 1st call to reset if no objects left
+ update_gizmos_data();
+ update_volumes_selection(m_objects_selections);
+ // 2nd call to restore selection, if any
+ if (!m_objects_selections.empty())
+ update_gizmos_data();
+
+ if (m_config->has("nozzle_diameter"))
+ {
+ // Should the wipe tower be visualized ?
+ unsigned int extruders_count = (unsigned int)dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"))->values.size();
+
+ bool semm = dynamic_cast<const ConfigOptionBool*>(m_config->option("single_extruder_multi_material"))->value;
+ bool wt = dynamic_cast<const ConfigOptionBool*>(m_config->option("wipe_tower"))->value;
+ bool co = dynamic_cast<const ConfigOptionBool*>(m_config->option("complete_objects"))->value;
+
+ if ((extruders_count > 1) && semm && wt && !co)
+ {
+ // Height of a print (Show at least a slab)
+ double height = std::max(m_model->bounding_box().max(2), 10.0);
+
+ float x = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_x"))->value;
+ float y = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_y"))->value;
+ float w = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_width"))->value;
+ float a = dynamic_cast<const ConfigOptionFloat*>(m_config->option("wipe_tower_rotation_angle"))->value;
+
+ float depth = m_print->get_wipe_tower_depth();
+ if (!m_print->is_step_done(psWipeTower))
+ depth = (900.f/w) * (float)(extruders_count - 1) ;
+
+ m_volumes.load_wipe_tower_preview(1000, x, y, w, depth, (float)height, a, m_use_VBOs && m_initialized, !m_print->is_step_done(psWipeTower),
+ m_print->config().nozzle_diameter.values[0] * 1.25f * 4.5f);
+ }
+ }
+
+ update_volumes_colors_by_extruder();
+
+ // checks for geometry outside the print volume to render it accordingly
+ if (!m_volumes.empty())
+ {
+ ModelInstance::EPrintVolumeState state;
+ bool contained = m_volumes.check_outside_state(m_config, &state);
+
+ if (!contained)
+ {
+ enable_warning_texture(true);
+ _generate_warning_texture(L("Detected object outside print volume"));
+ m_on_enable_action_buttons_callback.call(state == ModelInstance::PVS_Fully_Outside);
+ }
+ else
+ {
+ enable_warning_texture(false);
+ m_volumes.reset_outside_state();
+ _reset_warning_texture();
+ m_on_enable_action_buttons_callback.call(!m_model->objects.empty());
+ }
+ }
+ else
+ {
+ enable_warning_texture(false);
+ _reset_warning_texture();
+ m_on_enable_action_buttons_callback.call(false);
+ }
+}
+
+void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors)
+{
+ if ((m_canvas != nullptr) && (m_print != nullptr))
+ {
+ // ensures that this canvas is current
+ if (!set_current())
+ return;
+
+ if (m_volumes.empty())
+ {
+ std::vector<float> tool_colors = _parse_colors(str_tool_colors);
+
+ m_gcode_preview_volume_index.reset();
+
+ _load_gcode_extrusion_paths(preview_data, tool_colors);
+ _load_gcode_travel_paths(preview_data, tool_colors);
+ _load_gcode_retractions(preview_data);
+ _load_gcode_unretractions(preview_data);
+
+ if (m_volumes.empty())
+ reset_legend_texture();
+ else
+ {
+ _generate_legend_texture(preview_data, tool_colors);
+
+ // removes empty volumes
+ m_volumes.volumes.erase(std::remove_if(m_volumes.volumes.begin(), m_volumes.volumes.end(),
+ [](const GLVolume* volume) { return volume->print_zs.empty(); }), m_volumes.volumes.end());
+
+ _load_shells();
+ }
+ _update_toolpath_volumes_outside_state();
+ }
+
+ _update_gcode_volumes_visibility(preview_data);
+ _show_warning_texture_if_needed();
+ }
+}
+
+void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors)
+{
+ if (m_print == nullptr)
+ return;
+
+ _load_print_toolpaths();
+ _load_wipe_tower_toolpaths(str_tool_colors);
+ for (const PrintObject* object : m_print->objects())
+ {
+ if (object != nullptr)
+ _load_print_object_toolpaths(*object, str_tool_colors);
+ }
+
+ for (GLVolume* volume : m_volumes.volumes)
+ {
+ volume->is_extrusion_path = true;
+ }
+
+ _update_toolpath_volumes_outside_state();
+ _show_warning_texture_if_needed();
+ reset_legend_texture();
+}
+
+void GLCanvas3D::register_on_viewport_changed_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_viewport_changed_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_double_click_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_double_click_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_right_click_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_right_click_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_select_object_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_select_object_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_model_update_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_model_update_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_remove_object_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_remove_object_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_arrange_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_arrange_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_rotate_object_left_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_rotate_object_left_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_rotate_object_right_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_rotate_object_right_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_scale_object_uniformly_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_scale_object_uniformly_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_increase_objects_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_increase_objects_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_decrease_objects_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_decrease_objects_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_instance_moved_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_instance_moved_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_wipe_tower_moved_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_wipe_tower_moved_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_enable_action_buttons_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_enable_action_buttons_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_gizmo_scale_uniformly_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_gizmo_scale_uniformly_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_gizmo_rotate_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_gizmo_rotate_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_gizmo_flatten_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_gizmo_flatten_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_on_update_geometry_info_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_on_update_geometry_info_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_action_add_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_action_add_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_action_delete_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_action_delete_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_action_deleteall_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_action_deleteall_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_action_arrange_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_action_arrange_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_action_more_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_action_more_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_action_fewer_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_action_fewer_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_action_split_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_action_split_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_action_cut_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_action_cut_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_action_settings_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_action_settings_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_action_layersediting_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_action_layersediting_callback.register_callback(callback);
+}
+
+void GLCanvas3D::register_action_selectbyparts_callback(void* callback)
+{
+ if (callback != nullptr)
+ m_action_selectbyparts_callback.register_callback(callback);
+}
+
+void GLCanvas3D::bind_event_handlers()
+{
+ if (m_canvas != nullptr)
+ {
+ m_canvas->Bind(wxEVT_SIZE, &GLCanvas3D::on_size, this);
+ m_canvas->Bind(wxEVT_IDLE, &GLCanvas3D::on_idle, this);
+ m_canvas->Bind(wxEVT_CHAR, &GLCanvas3D::on_char, this);
+ m_canvas->Bind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this);
+ m_canvas->Bind(wxEVT_TIMER, &GLCanvas3D::on_timer, this);
+ m_canvas->Bind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_LEFT_UP, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_MIDDLE_DOWN, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_MIDDLE_UP, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_RIGHT_DOWN, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_RIGHT_UP, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_MOTION, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_ENTER_WINDOW, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_LEAVE_WINDOW, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_LEFT_DCLICK, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_MIDDLE_DCLICK, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this);
+ m_canvas->Bind(wxEVT_PAINT, &GLCanvas3D::on_paint, this);
+ m_canvas->Bind(wxEVT_KEY_DOWN, &GLCanvas3D::on_key_down, this);
+ }
+}
+
+void GLCanvas3D::unbind_event_handlers()
+{
+ if (m_canvas != nullptr)
+ {
+ m_canvas->Unbind(wxEVT_SIZE, &GLCanvas3D::on_size, this);
+ m_canvas->Unbind(wxEVT_IDLE, &GLCanvas3D::on_idle, this);
+ m_canvas->Unbind(wxEVT_CHAR, &GLCanvas3D::on_char, this);
+ m_canvas->Unbind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this);
+ m_canvas->Unbind(wxEVT_TIMER, &GLCanvas3D::on_timer, this);
+ m_canvas->Unbind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_LEFT_UP, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_MIDDLE_DOWN, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_MIDDLE_UP, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_RIGHT_DOWN, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_RIGHT_UP, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_MOTION, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_ENTER_WINDOW, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_LEAVE_WINDOW, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_LEFT_DCLICK, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_MIDDLE_DCLICK, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this);
+ m_canvas->Unbind(wxEVT_PAINT, &GLCanvas3D::on_paint, this);
+ m_canvas->Unbind(wxEVT_KEY_DOWN, &GLCanvas3D::on_key_down, this);
+ }
+}
+
+void GLCanvas3D::on_size(wxSizeEvent& evt)
+{
+ m_dirty = true;
+}
+
+void GLCanvas3D::on_idle(wxIdleEvent& evt)
+{
+ if (!m_dirty)
+ return;
+
+ _refresh_if_shown_on_screen();
+}
+
+void GLCanvas3D::on_char(wxKeyEvent& evt)
+{
+ if (evt.HasModifiers())
+ evt.Skip();
+ else
+ {
+ int keyCode = evt.GetKeyCode();
+ switch (keyCode - 48)
+ {
+ // numerical input
+ case 0: { select_view("iso"); break; }
+ case 1: { select_view("top"); break; }
+ case 2: { select_view("bottom"); break; }
+ case 3: { select_view("front"); break; }
+ case 4: { select_view("rear"); break; }
+ case 5: { select_view("left"); break; }
+ case 6: { select_view("right"); break; }
+ default:
+ {
+ // text input
+ switch (keyCode)
+ {
+ // key +
+ case 43: { m_on_increase_objects_callback.call(); break; }
+ // key -
+ case 45: { m_on_decrease_objects_callback.call(); break; }
+ // key A/a
+ case 65:
+ case 97: { m_on_arrange_callback.call(); break; }
+ // key B/b
+ case 66:
+ case 98: { zoom_to_bed(); break; }
+ // key L/l
+ case 76:
+ case 108: { m_on_rotate_object_left_callback.call(); break; }
+ // key R/r
+ case 82:
+ case 114: { m_on_rotate_object_right_callback.call(); break; }
+ // key S/s
+ case 83:
+ case 115: { m_on_scale_object_uniformly_callback.call(); break; }
+ // key Z/z
+ case 90:
+ case 122: { zoom_to_volumes(); break; }
+ default:
+ {
+ evt.Skip();
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt)
+{
+ // Ignore the wheel events if the middle button is pressed.
+ if (evt.MiddleIsDown())
+ return;
+
+ // Performs layers editing updates, if enabled
+ if (is_layers_editing_enabled())
+ {
+ int object_idx_selected = _get_first_selected_object_id();
+ if (object_idx_selected != -1)
+ {
+ // A volume is selected. Test, whether hovering over a layer thickness bar.
+ if (m_layers_editing.bar_rect_contains(*this, (float)evt.GetX(), (float)evt.GetY()))
+ {
+ // Adjust the width of the selection.
+ m_layers_editing.band_width = std::max(std::min(m_layers_editing.band_width * (1.0f + 0.1f * (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta()), 10.0f), 1.5f);
+ if (m_canvas != nullptr)
+ m_canvas->Refresh();
+
+ return;
+ }
+ }
+ }
+
+ // Calculate the zoom delta and apply it to the current zoom factor
+ float zoom = (float)evt.GetWheelRotation() / (float)evt.GetWheelDelta();
+ zoom = std::max(std::min(zoom, 4.0f), -4.0f) / 10.0f;
+ zoom = get_camera_zoom() / (1.0f - zoom);
+
+ // Don't allow to zoom too far outside the scene.
+ float zoom_min = _get_zoom_to_bounding_box_factor(_max_bounding_box());
+ if (zoom_min > 0.0f)
+ zoom = std::max(zoom, zoom_min * 0.8f);
+
+ m_camera.zoom = zoom;
+ m_on_viewport_changed_callback.call();
+
+ _refresh_if_shown_on_screen();
+}
+
+void GLCanvas3D::on_timer(wxTimerEvent& evt)
+{
+ if (m_layers_editing.state != LayersEditing::Editing)
+ return;
+
+ _perform_layer_editing_action();
+}
+
+void GLCanvas3D::on_mouse(wxMouseEvent& evt)
+{
+ Point pos(evt.GetX(), evt.GetY());
+
+ int selected_object_idx = _get_first_selected_object_id();
+ int layer_editing_object_idx = is_layers_editing_enabled() ? selected_object_idx : -1;
+ m_layers_editing.last_object_id = layer_editing_object_idx;
+ bool gizmos_overlay_contains_mouse = m_gizmos.overlay_contains_mouse(*this, m_mouse.position);
+ int toolbar_contains_mouse = m_toolbar.contains_mouse(m_mouse.position);
+
+ if (evt.Entering())
+ {
+#if defined(__WXMSW__) || defined(__linux__)
+ // On Windows and Linux needs focus in order to catch key events
+ if (m_canvas != nullptr)
+ m_canvas->SetFocus();
+
+ m_mouse.set_start_position_2D_as_invalid();
+#endif
+ }
+ else if (evt.Leaving())
+ {
+ // to remove hover on objects when the mouse goes out of this canvas
+ m_mouse.position = Vec2d(-1.0, -1.0);
+ m_dirty = true;
+ }
+ else if (evt.LeftDClick() && (m_hover_volume_id != -1) && !gizmos_overlay_contains_mouse && (toolbar_contains_mouse == -1))
+ m_on_double_click_callback.call();
+ else if (evt.LeftDClick() && (toolbar_contains_mouse != -1))
+ {
+ m_toolbar_action_running = true;
+ m_toolbar.do_action((unsigned int)toolbar_contains_mouse);
+ }
+ else if (evt.LeftDown() || evt.RightDown())
+ {
+ // If user pressed left or right button we first check whether this happened
+ // on a volume or not.
+ int volume_idx = m_hover_volume_id;
+ m_layers_editing.state = LayersEditing::Unknown;
+ if ((layer_editing_object_idx != -1) && m_layers_editing.bar_rect_contains(*this, pos(0), pos(1)))
+ {
+ // A volume is selected and the mouse is inside the layer thickness bar.
+ // Start editing the layer height.
+ m_layers_editing.state = LayersEditing::Editing;
+ _perform_layer_editing_action(&evt);
+ }
+ else if ((layer_editing_object_idx != -1) && m_layers_editing.reset_rect_contains(*this, pos(0), pos(1)))
+ {
+ if (evt.LeftDown())
+ {
+ // A volume is selected and the mouse is inside the reset button.
+ // The PrintObject::adjust_layer_height_profile() call adjusts the profile of its associated ModelObject, it does not modify the profile of the PrintObject itself,
+ // therefore it is safe to call it while the background processing is running.
+ const_cast<PrintObject*>(m_print->get_object(layer_editing_object_idx))->reset_layer_height_profile();
+ // Index 2 means no editing, just wait for mouse up event.
+ m_layers_editing.state = LayersEditing::Completed;
+
+ m_dirty = true;
+ }
+ }
+ else if ((selected_object_idx != -1) && gizmos_overlay_contains_mouse)
+ {
+ update_gizmos_data();
+ m_gizmos.update_on_off_state(*this, m_mouse.position);
+ m_dirty = true;
+ }
+ else if ((selected_object_idx != -1) && m_gizmos.grabber_contains_mouse())
+ {
+ update_gizmos_data();
+ m_gizmos.start_dragging(_selected_volumes_bounding_box());
+ m_mouse.drag.gizmo_volume_idx = _get_first_selected_volume_id(selected_object_idx);
+
+ if (m_gizmos.get_current_type() == Gizmos::Flatten) {
+ // Rotate the object so the normal points downward:
+ Vec3d normal = m_gizmos.get_flattening_normal();
+ if (normal(0) != 0.0 || normal(1) != 0.0 || normal(2) != 0.0) {
+ Vec3d axis = normal(2) > 0.999 ? Vec3d::UnitX() : normal.cross(-Vec3d::UnitZ()).normalized();
+ float angle = acos(clamp(-1.0, 1.0, -normal(2)));
+ m_on_gizmo_flatten_callback.call(angle, (float)axis(0), (float)axis(1), (float)axis(2));
+ }
+ }
+
+ m_dirty = true;
+ }
+ else if (toolbar_contains_mouse != -1)
+ {
+ m_toolbar_action_running = true;
+ m_toolbar.do_action((unsigned int)toolbar_contains_mouse);
+ }
+ else
+ {
+ // Select volume in this 3D canvas.
+ // Don't deselect a volume if layer editing is enabled. We want the object to stay selected
+ // during the scene manipulation.
+
+ if (m_picking_enabled && ((volume_idx != -1) || !is_layers_editing_enabled()))
+ {
+ if (volume_idx != -1)
+ {
+ deselect_volumes();
+ select_volume(volume_idx);
+ int group_id = m_volumes.volumes[volume_idx]->select_group_id;
+ if (group_id != -1)
+ {
+ for (GLVolume* vol : m_volumes.volumes)
+ {
+ if ((vol != nullptr) && (vol->select_group_id == group_id))
+ vol->selected = true;
+ }
+ }
+
+ update_gizmos_data();
+ m_dirty = true;
+ }
+ }
+
+ // propagate event through callback
+ if (m_picking_enabled && (volume_idx != -1))
+ _on_select(volume_idx, selected_object_idx);
+
+ if (volume_idx != -1)
+ {
+ if (evt.LeftDown() && m_moving_enabled)
+ {
+ // The mouse_to_3d gets the Z coordinate from the Z buffer at the screen coordinate pos x, y,
+ // an converts the screen space coordinate to unscaled object space.
+ Vec3d pos3d = (volume_idx == -1) ? Vec3d(DBL_MAX, DBL_MAX, DBL_MAX) : _mouse_to_3d(pos);
+
+ // Only accept the initial position, if it is inside the volume bounding box.
+ BoundingBoxf3 volume_bbox = m_volumes.volumes[volume_idx]->transformed_bounding_box();
+ volume_bbox.offset(1.0);
+ if (volume_bbox.contains(pos3d))
+ {
+ // The dragging operation is initiated.
+ m_mouse.drag.move_with_shift = evt.ShiftDown();
+ m_mouse.drag.move_volume_idx = volume_idx;
+ m_mouse.drag.start_position_3D = pos3d;
+ // Remember the shift to to the object center.The object center will later be used
+ // to limit the object placement close to the bed.
+ m_mouse.drag.volume_center_offset = volume_bbox.center() - pos3d;
+ }
+ }
+ else if (evt.RightDown())
+ {
+ // forces a frame render to ensure that m_hover_volume_id is updated even when the user right clicks while
+ // the context menu is already shown, ensuring it to disappear if the mouse is outside any volume
+ m_mouse.position = Vec2d((double)pos(0), (double)pos(1));
+ render();
+ if (m_hover_volume_id != -1)
+ {
+ // if right clicking on volume, propagate event through callback (shows context menu)
+ if (m_volumes.volumes[volume_idx]->hover)
+ m_on_right_click_callback.call(pos(0), pos(1));
+ }
+ }
+ }
+ }
+ }
+ else if (evt.Dragging() && evt.LeftIsDown() && !gizmos_overlay_contains_mouse && (m_layers_editing.state == LayersEditing::Unknown) && (m_mouse.drag.move_volume_idx != -1))
+ {
+ m_mouse.dragging = true;
+
+ // Get new position at the same Z of the initial click point.
+ float z0 = 0.0f;
+ float z1 = 1.0f;
+ Vec3d cur_pos = Linef3(_mouse_to_3d(pos, &z0), _mouse_to_3d(pos, &z1)).intersect_plane(m_mouse.drag.start_position_3D(2));
+
+ // Clip the new position, so the object center remains close to the bed.
+ cur_pos += m_mouse.drag.volume_center_offset;
+ Point cur_pos2(scale_(cur_pos(0)), scale_(cur_pos(1)));
+ if (!m_bed.contains(cur_pos2))
+ {
+ Point ip = m_bed.point_projection(cur_pos2);
+ cur_pos(0) = unscale<double>(ip(0));
+ cur_pos(1) = unscale<double>(ip(1));
+ }
+ cur_pos -= m_mouse.drag.volume_center_offset;
+
+ // Calculate the translation vector.
+ Vec3d vector = cur_pos - m_mouse.drag.start_position_3D;
+ // Get the volume being dragged.
+ GLVolume* volume = m_volumes.volumes[m_mouse.drag.move_volume_idx];
+ // Get all volumes belonging to the same group, if any.
+ std::vector<GLVolume*> volumes;
+ int group_id = m_mouse.drag.move_with_shift ? volume->select_group_id : volume->drag_group_id;
+ if (group_id == -1)
+ volumes.push_back(volume);
+ else
+ {
+ for (GLVolume* v : m_volumes.volumes)
+ {
+ if (v != nullptr)
+ {
+ if ((m_mouse.drag.move_with_shift && (v->select_group_id == group_id)) || (!m_mouse.drag.move_with_shift && (v->drag_group_id == group_id)))
+ volumes.push_back(v);
+ }
+ }
+ }
+
+ // Apply new temporary volume origin and ignore Z.
+ for (GLVolume* v : volumes)
+ {
+ v->set_offset(v->get_offset() + Vec3d(vector(0), vector(1), 0.0));
+ }
+
+ update_position_values(volume->get_offset());
+ m_mouse.drag.start_position_3D = cur_pos;
+
+ m_dirty = true;
+ }
+ else if (evt.Dragging() && m_gizmos.is_dragging())
+ {
+ if (!m_canvas->HasCapture())
+ m_canvas->CaptureMouse();
+
+ m_mouse.dragging = true;
+ m_gizmos.update(mouse_ray(pos));
+
+ std::vector<GLVolume*> volumes;
+ if (m_mouse.drag.gizmo_volume_idx != -1)
+ {
+ GLVolume* volume = m_volumes.volumes[m_mouse.drag.gizmo_volume_idx];
+ // Get all volumes belonging to the same group, if any.
+ if (volume->select_group_id == -1)
+ volumes.push_back(volume);
+ else
+ {
+ for (GLVolume* v : m_volumes.volumes)
+ {
+ if ((v != nullptr) && (v->select_group_id == volume->select_group_id))
+ volumes.push_back(v);
+ }
+ }
+ }
+
+ switch (m_gizmos.get_current_type())
+ {
+ case Gizmos::Move:
+ {
+ // Apply new temporary offset
+ GLVolume* volume = m_volumes.volumes[m_mouse.drag.gizmo_volume_idx];
+ Vec3d offset = m_gizmos.get_position() - volume->get_offset();
+ for (GLVolume* v : volumes)
+ {
+ v->set_offset(v->get_offset() + offset);
+ }
+ update_position_values(volume->get_offset());
+ break;
+ }
+ case Gizmos::Scale:
+ {
+ // Apply new temporary scale factor
+ float scale_factor = m_gizmos.get_scale();
+ for (GLVolume* v : volumes)
+ {
+ v->set_scaling_factor((double)scale_factor);
+ }
+ update_scale_values((double)scale_factor);
+ break;
+ }
+ case Gizmos::Rotate:
+ {
+ // Apply new temporary angle_z
+ float angle_z = m_gizmos.get_angle_z();
+ for (GLVolume* v : volumes)
+ {
+ v->set_rotation((double)angle_z);
+ }
+ update_rotation_value((double)angle_z, Z);
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (!volumes.empty())
+ {
+ BoundingBoxf3 bb;
+ for (const GLVolume* volume : volumes)
+ {
+ bb.merge(volume->transformed_bounding_box());
+ }
+ const Vec3d& size = bb.size();
+ m_on_update_geometry_info_callback.call(size(0), size(1), size(2), m_gizmos.get_scale());
+ }
+
+ m_dirty = true;
+ }
+ else if (evt.Dragging() && !gizmos_overlay_contains_mouse)
+ {
+ m_mouse.dragging = true;
+
+ if ((m_layers_editing.state != LayersEditing::Unknown) && (layer_editing_object_idx != -1))
+ {
+ if (m_layers_editing.state == LayersEditing::Editing)
+ _perform_layer_editing_action(&evt);
+ }
+ else if (evt.LeftIsDown())
+ {
+ // if dragging over blank area with left button, rotate
+ if (m_mouse.is_start_position_3D_defined())
+ {
+ const Vec3d& orig = m_mouse.drag.start_position_3D;
+ m_camera.phi += (((float)pos(0) - (float)orig(0)) * TRACKBALLSIZE);
+ m_camera.set_theta(m_camera.get_theta() - ((float)pos(1) - (float)orig(1)) * TRACKBALLSIZE);
+
+ m_on_viewport_changed_callback.call();
+
+ m_dirty = true;
+ }
+ m_mouse.drag.start_position_3D = Vec3d((double)pos(0), (double)pos(1), 0.0);
+ }
+ else if (evt.MiddleIsDown() || evt.RightIsDown())
+ {
+ // If dragging over blank area with right button, pan.
+ if (m_mouse.is_start_position_2D_defined())
+ {
+ // get point in model space at Z = 0
+ float z = 0.0f;
+ const Vec3d& cur_pos = _mouse_to_3d(pos, &z);
+ Vec3d orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z);
+ m_camera.target += orig - cur_pos;
+
+ m_on_viewport_changed_callback.call();
+
+ m_dirty = true;
+ }
+
+ m_mouse.drag.start_position_2D = pos;
+ }
+ }
+ else if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp())
+ {
+ if (m_layers_editing.state != LayersEditing::Unknown)
+ {
+ m_layers_editing.state = LayersEditing::Unknown;
+ _stop_timer();
+
+ if (layer_editing_object_idx != -1)
+ m_on_model_update_callback.call();
+ }
+ else if ((m_mouse.drag.move_volume_idx != -1) && m_mouse.dragging)
+ {
+ // get all volumes belonging to the same group, if any
+ std::vector<int> volume_idxs;
+ int vol_id = m_mouse.drag.move_volume_idx;
+ int group_id = m_mouse.drag.move_with_shift ? m_volumes.volumes[vol_id]->select_group_id : m_volumes.volumes[vol_id]->drag_group_id;
+ if (group_id == -1)
+ volume_idxs.push_back(vol_id);
+ else
+ {
+ for (int i = 0; i < (int)m_volumes.volumes.size(); ++i)
+ {
+ if ((m_mouse.drag.move_with_shift && (m_volumes.volumes[i]->select_group_id == group_id)) || (m_volumes.volumes[i]->drag_group_id == group_id))
+ volume_idxs.push_back(i);
+ }
+ }
+
+ _on_move(volume_idxs);
+
+ // force re-selection of the wipe tower, if needed
+ if ((volume_idxs.size() == 1) && m_volumes.volumes[volume_idxs[0]]->is_wipe_tower)
+ select_volume(volume_idxs[0]);
+ }
+ else if (evt.LeftUp() && !m_mouse.dragging && (m_hover_volume_id == -1) && !gizmos_overlay_contains_mouse && !m_gizmos.is_dragging() && !is_layers_editing_enabled())
+ {
+ // deselect and propagate event through callback
+ if (m_picking_enabled && !m_toolbar_action_running)
+ {
+ deselect_volumes();
+ _on_select(-1, -1);
+ update_gizmos_data();
+ }
+ }
+ else if (evt.LeftUp() && m_gizmos.is_dragging())
+ {
+ switch (m_gizmos.get_current_type())
+ {
+ case Gizmos::Move:
+ {
+ // get all volumes belonging to the same group, if any
+ std::vector<int> volume_idxs;
+ int vol_id = m_mouse.drag.gizmo_volume_idx;
+ int group_id = m_volumes.volumes[vol_id]->select_group_id;
+ if (group_id == -1)
+ volume_idxs.push_back(vol_id);
+ else
+ {
+ for (int i = 0; i < (int)m_volumes.volumes.size(); ++i)
+ {
+ if (m_volumes.volumes[i]->select_group_id == group_id)
+ volume_idxs.push_back(i);
+ }
+ }
+
+ _on_move(volume_idxs);
+
+ break;
+ }
+ case Gizmos::Scale:
+ {
+ m_on_gizmo_scale_uniformly_callback.call((double)m_gizmos.get_scale());
+ break;
+ }
+ case Gizmos::Rotate:
+ {
+ m_on_gizmo_rotate_callback.call((double)m_gizmos.get_angle_z());
+ break;
+ }
+ default:
+ break;
+ }
+ m_gizmos.stop_dragging();
+ Slic3r::GUI::update_settings_value();
+ }
+
+ m_mouse.drag.move_volume_idx = -1;
+ m_mouse.drag.gizmo_volume_idx = -1;
+ m_mouse.set_start_position_3D_as_invalid();
+ m_mouse.set_start_position_2D_as_invalid();
+ m_mouse.dragging = false;
+ m_toolbar_action_running = false;
+ m_dirty = true;
+
+ if (m_canvas->HasCapture())
+ m_canvas->ReleaseMouse();
+ }
+ else if (evt.Moving())
+ {
+ m_mouse.position = Vec2d((double)pos(0), (double)pos(1));
+ // Only refresh if picking is enabled, in that case the objects may get highlighted if the mouse cursor hovers over.
+ if (m_picking_enabled)
+ m_dirty = true;
+ }
+ else
+ evt.Skip();
+}
+
+void GLCanvas3D::on_paint(wxPaintEvent& evt)
+{
+ render();
+}
+
+void GLCanvas3D::on_key_down(wxKeyEvent& evt)
+{
+ if (evt.HasModifiers())
+ evt.Skip();
+ else
+ {
+ int key = evt.GetKeyCode();
+ if (key == WXK_DELETE)
+ m_on_remove_object_callback.call();
+ else
+ {
+#ifdef __WXOSX__
+ if (key == WXK_BACK)
+ m_on_remove_object_callback.call();
+#endif
+ evt.Skip();
+ }
+ }
+}
+
+Size GLCanvas3D::get_canvas_size() const
+{
+ int w = 0;
+ int h = 0;
+
+ if (m_canvas != nullptr)
+ m_canvas->GetSize(&w, &h);
+
+ return Size(w, h);
+}
+
+Point GLCanvas3D::get_local_mouse_position() const
+{
+ if (m_canvas == nullptr)
+ return Point();
+
+ wxPoint mouse_pos = m_canvas->ScreenToClient(wxGetMousePosition());
+ return Point(mouse_pos.x, mouse_pos.y);
+}
+
+void GLCanvas3D::reset_legend_texture()
+{
+ if (!set_current())
+ return;
+
+ m_legend_texture.reset();
+}
+
+void GLCanvas3D::set_tooltip(const std::string& tooltip)
+{
+ if (m_canvas != nullptr)
+ m_canvas->SetToolTip(tooltip);
+}
+
+bool GLCanvas3D::_is_shown_on_screen() const
+{
+ return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false;
+}
+
+void GLCanvas3D::_force_zoom_to_bed()
+{
+ zoom_to_bed();
+ m_force_zoom_to_bed_enabled = false;
+}
+
+bool GLCanvas3D::_init_toolbar()
+{
+ if (!m_toolbar.is_enabled())
+ return true;
+
+ if (!m_toolbar.init("toolbar.png", 36, 1, 1))
+ {
+ // unable to init the toolbar texture, disable it
+ m_toolbar.set_enabled(false);
+ return true;
+ }
+
+// m_toolbar.set_layout_type(GLToolbar::Layout::Vertical);
+ m_toolbar.set_layout_type(GLToolbar::Layout::Horizontal);
+ m_toolbar.set_separator_size(5);
+ m_toolbar.set_gap_size(2);
+
+ GLToolbarItem::Data item;
+
+ item.name = "add";
+ item.tooltip = GUI::L_str("Add...");
+ item.sprite_id = 0;
+ item.is_toggable = false;
+ item.action_callback = &m_action_add_callback;
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ item.name = "delete";
+ item.tooltip = GUI::L_str("Delete");
+ item.sprite_id = 1;
+ item.is_toggable = false;
+ item.action_callback = &m_action_delete_callback;
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ item.name = "deleteall";
+ item.tooltip = GUI::L_str("Delete all");
+ item.sprite_id = 2;
+ item.is_toggable = false;
+ item.action_callback = &m_action_deleteall_callback;
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ item.name = "arrange";
+ item.tooltip = GUI::L_str("Arrange");
+ item.sprite_id = 3;
+ item.is_toggable = false;
+ item.action_callback = &m_action_arrange_callback;
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ if (!m_toolbar.add_separator())
+ return false;
+
+ item.name = "more";
+ item.tooltip = GUI::L_str("Add instance");
+ item.sprite_id = 4;
+ item.is_toggable = false;
+ item.action_callback = &m_action_more_callback;
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ item.name = "fewer";
+ item.tooltip = GUI::L_str("Remove instance");
+ item.sprite_id = 5;
+ item.is_toggable = false;
+ item.action_callback = &m_action_fewer_callback;
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ if (!m_toolbar.add_separator())
+ return false;
+
+ item.name = "split";
+ item.tooltip = GUI::L_str("Split");
+ item.sprite_id = 6;
+ item.is_toggable = false;
+ item.action_callback = &m_action_split_callback;
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ item.name = "cut";
+ item.tooltip = GUI::L_str("Cut...");
+ item.sprite_id = 7;
+ item.is_toggable = false;
+ item.action_callback = &m_action_cut_callback;
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ if (!m_toolbar.add_separator())
+ return false;
+
+ item.name = "settings";
+ item.tooltip = GUI::L_str("Settings...");
+ item.sprite_id = 8;
+ item.is_toggable = false;
+ item.action_callback = &m_action_settings_callback;
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ item.name = "layersediting";
+ item.tooltip = GUI::L_str("Layers editing");
+ item.sprite_id = 9;
+ item.is_toggable = true;
+ item.action_callback = &m_action_layersediting_callback;
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ if (!m_toolbar.add_separator())
+ return false;
+
+ item.name = "selectbyparts";
+ item.tooltip = GUI::L_str("Select by parts");
+ item.sprite_id = 10;
+ item.is_toggable = true;
+ item.action_callback = &m_action_selectbyparts_callback;
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ enable_toolbar_item("add", true);
+
+ return true;
+}
+
+void GLCanvas3D::_resize(unsigned int w, unsigned int h)
+{
+ if ((m_canvas == nullptr) && (m_context == nullptr))
+ return;
+
+ // ensures that this canvas is current
+ set_current();
+ ::glViewport(0, 0, w, h);
+
+ ::glMatrixMode(GL_PROJECTION);
+ ::glLoadIdentity();
+
+ const BoundingBoxf3& bbox = _max_bounding_box();
+
+ switch (m_camera.type)
+ {
+ case Camera::Ortho:
+ {
+ float w2 = w;
+ float h2 = h;
+ float two_zoom = 2.0f * get_camera_zoom();
+ if (two_zoom != 0.0f)
+ {
+ float inv_two_zoom = 1.0f / two_zoom;
+ w2 *= inv_two_zoom;
+ h2 *= inv_two_zoom;
+ }
+
+ // FIXME: calculate a tighter value for depth will improve z-fighting
+ float depth = 5.0f * (float)bbox.max_size();
+ ::glOrtho(-w2, w2, -h2, h2, -depth, depth);
+
+ break;
+ }
+// case Camera::Perspective:
+// {
+// float bbox_r = (float)bbox.radius();
+// float fov = PI * 45.0f / 180.0f;
+// float fov_tan = tan(0.5f * fov);
+// float cam_distance = 0.5f * bbox_r / fov_tan;
+// m_camera.distance = cam_distance;
+//
+// float nr = cam_distance - bbox_r * 1.1f;
+// float fr = cam_distance + bbox_r * 1.1f;
+// if (nr < 1.0f)
+// nr = 1.0f;
+//
+// if (fr < nr + 1.0f)
+// fr = nr + 1.0f;
+//
+// float h2 = fov_tan * nr;
+// float w2 = h2 * w / h;
+// ::glFrustum(-w2, w2, -h2, h2, nr, fr);
+//
+// break;
+// }
+ default:
+ {
+ throw std::runtime_error("Invalid camera type.");
+ break;
+ }
+ }
+
+ ::glMatrixMode(GL_MODELVIEW);
+
+ m_dirty = false;
+}
+
+BoundingBoxf3 GLCanvas3D::_max_bounding_box() const
+{
+ BoundingBoxf3 bb = m_bed.get_bounding_box();
+ bb.merge(volumes_bounding_box());
+ return bb;
+}
+
+BoundingBoxf3 GLCanvas3D::_selected_volumes_bounding_box() const
+{
+ BoundingBoxf3 bb;
+
+ std::vector<const GLVolume*> selected_volumes;
+ for (const GLVolume* volume : m_volumes.volumes)
+ {
+ if ((volume != nullptr) && !volume->is_wipe_tower && volume->selected)
+ selected_volumes.push_back(volume);
+ }
+
+ bool use_drag_group_id = selected_volumes.size() > 1;
+ if (use_drag_group_id)
+ {
+ int drag_group_id = selected_volumes[0]->drag_group_id;
+ for (const GLVolume* volume : selected_volumes)
+ {
+ if (drag_group_id != volume->drag_group_id)
+ {
+ use_drag_group_id = false;
+ break;
+ }
+ }
+ }
+
+ if (use_drag_group_id)
+ {
+ for (const GLVolume* volume : selected_volumes)
+ {
+ bb.merge(volume->bounding_box);
+ }
+
+ bb = bb.transformed(selected_volumes[0]->world_matrix().cast<double>());
+ }
+ else
+ {
+ for (const GLVolume* volume : selected_volumes)
+ {
+ bb.merge(volume->transformed_bounding_box());
+ }
+ }
+
+ return bb;
+}
+
+void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox)
+{
+ // Calculate the zoom factor needed to adjust viewport to bounding box.
+ float zoom = _get_zoom_to_bounding_box_factor(bbox);
+ if (zoom > 0.0f)
+ {
+ m_camera.zoom = zoom;
+ // center view around bounding box center
+ m_camera.target = bbox.center();
+
+ m_on_viewport_changed_callback.call();
+
+ _refresh_if_shown_on_screen();
+ }
+}
+
+float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const
+{
+ float max_bb_size = bbox.max_size();
+ if (max_bb_size == 0.0f)
+ return -1.0f;
+
+ // project the bbox vertices on a plane perpendicular to the camera forward axis
+ // then calculates the vertices coordinate on this plane along the camera xy axes
+
+ // we need the view matrix, we let opengl calculate it (same as done in render())
+ _camera_tranform();
+
+ // get the view matrix back from opengl
+ GLfloat matrix[16];
+ ::glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
+
+ // camera axes
+ Vec3d right((double)matrix[0], (double)matrix[4], (double)matrix[8]);
+ Vec3d up((double)matrix[1], (double)matrix[5], (double)matrix[9]);
+ Vec3d forward((double)matrix[2], (double)matrix[6], (double)matrix[10]);
+
+ Vec3d bb_min = bbox.min;
+ Vec3d bb_max = bbox.max;
+ Vec3d bb_center = bbox.center();
+
+ // bbox vertices in world space
+ std::vector<Vec3d> vertices;
+ vertices.reserve(8);
+ vertices.push_back(bb_min);
+ vertices.emplace_back(bb_max(0), bb_min(1), bb_min(2));
+ vertices.emplace_back(bb_max(0), bb_max(1), bb_min(2));
+ vertices.emplace_back(bb_min(0), bb_max(1), bb_min(2));
+ vertices.emplace_back(bb_min(0), bb_min(1), bb_max(2));
+ vertices.emplace_back(bb_max(0), bb_min(1), bb_max(2));
+ vertices.push_back(bb_max);
+ vertices.emplace_back(bb_min(0), bb_max(1), bb_max(2));
+
+ double max_x = 0.0;
+ double max_y = 0.0;
+
+ // margin factor to give some empty space around the bbox
+ double margin_factor = 1.25;
+
+ for (const Vec3d v : vertices)
+ {
+ // project vertex on the plane perpendicular to camera forward axis
+ Vec3d pos(v(0) - bb_center(0), v(1) - bb_center(1), v(2) - bb_center(2));
+ Vec3d proj_on_plane = pos - pos.dot(forward) * forward;
+
+ // calculates vertex coordinate along camera xy axes
+ double x_on_plane = proj_on_plane.dot(right);
+ double y_on_plane = proj_on_plane.dot(up);
+
+ max_x = std::max(max_x, margin_factor * std::abs(x_on_plane));
+ max_y = std::max(max_y, margin_factor * std::abs(y_on_plane));
+ }
+
+ if ((max_x == 0.0) || (max_y == 0.0))
+ return -1.0f;
+
+ max_x *= 2.0;
+ max_y *= 2.0;
+
+ const Size& cnv_size = get_canvas_size();
+ return (float)std::min((double)cnv_size.get_width() / max_x, (double)cnv_size.get_height() / max_y);
+}
+
+void GLCanvas3D::_deregister_callbacks()
+{
+ m_on_viewport_changed_callback.deregister_callback();
+ m_on_double_click_callback.deregister_callback();
+ m_on_right_click_callback.deregister_callback();
+ m_on_select_object_callback.deregister_callback();
+ m_on_model_update_callback.deregister_callback();
+ m_on_remove_object_callback.deregister_callback();
+ m_on_arrange_callback.deregister_callback();
+ m_on_rotate_object_left_callback.deregister_callback();
+ m_on_rotate_object_right_callback.deregister_callback();
+ m_on_scale_object_uniformly_callback.deregister_callback();
+ m_on_increase_objects_callback.deregister_callback();
+ m_on_decrease_objects_callback.deregister_callback();
+ m_on_instance_moved_callback.deregister_callback();
+ m_on_wipe_tower_moved_callback.deregister_callback();
+ m_on_enable_action_buttons_callback.deregister_callback();
+ m_on_gizmo_scale_uniformly_callback.deregister_callback();
+ m_on_gizmo_rotate_callback.deregister_callback();
+ m_on_gizmo_flatten_callback.deregister_callback();
+ m_on_update_geometry_info_callback.deregister_callback();
+
+ m_action_add_callback.deregister_callback();
+ m_action_delete_callback.deregister_callback();
+ m_action_deleteall_callback.deregister_callback();
+ m_action_arrange_callback.deregister_callback();
+ m_action_more_callback.deregister_callback();
+ m_action_fewer_callback.deregister_callback();
+ m_action_split_callback.deregister_callback();
+ m_action_cut_callback.deregister_callback();
+ m_action_settings_callback.deregister_callback();
+ m_action_layersediting_callback.deregister_callback();
+ m_action_selectbyparts_callback.deregister_callback();
+}
+
+void GLCanvas3D::_mark_volumes_for_layer_height() const
+{
+ if (m_print == nullptr)
+ return;
+
+ for (GLVolume* vol : m_volumes.volumes)
+ {
+ int object_id = int(vol->select_group_id / 1000000);
+ int shader_id = m_layers_editing.get_shader_program_id();
+
+ if (is_layers_editing_enabled() && (shader_id != -1) && vol->selected &&
+ vol->has_layer_height_texture() && (object_id < (int)m_print->objects().size()))
+ {
+ vol->set_layer_height_texture_data(m_layers_editing.get_z_texture_id(), shader_id,
+ m_print->get_object(object_id), _get_layers_editing_cursor_z_relative(), m_layers_editing.band_width);
+ }
+ else
+ vol->reset_layer_height_texture_data();
+ }
+}
+
+void GLCanvas3D::_refresh_if_shown_on_screen()
+{
+ if (_is_shown_on_screen())
+ {
+ const Size& cnv_size = get_canvas_size();
+ _resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height());
+ if (m_canvas != nullptr)
+ m_canvas->Refresh();
+ }
+}
+
+void GLCanvas3D::_camera_tranform() const
+{
+ ::glMatrixMode(GL_MODELVIEW);
+ ::glLoadIdentity();
+
+ ::glRotatef(-m_camera.get_theta(), 1.0f, 0.0f, 0.0f); // pitch
+ ::glRotatef(m_camera.phi, 0.0f, 0.0f, 1.0f); // yaw
+
+ Vec3d neg_target = - m_camera.target;
+ ::glTranslatef((GLfloat)neg_target(0), (GLfloat)neg_target(1), (GLfloat)neg_target(2));
+}
+
+void GLCanvas3D::_picking_pass() const
+{
+ const Vec2d& pos = m_mouse.position;
+
+ if (m_picking_enabled && !m_mouse.dragging && (pos != Vec2d(DBL_MAX, DBL_MAX)))
+ {
+ // Render the object for picking.
+ // FIXME This cannot possibly work in a multi - sampled context as the color gets mangled by the anti - aliasing.
+ // Better to use software ray - casting on a bounding - box hierarchy.
+
+ if (m_multisample_allowed)
+ ::glDisable(GL_MULTISAMPLE);
+
+ ::glDisable(GL_BLEND);
+ ::glEnable(GL_DEPTH_TEST);
+
+ ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ _render_volumes(true);
+ m_gizmos.render_current_gizmo_for_picking_pass(_selected_volumes_bounding_box());
+
+ if (m_multisample_allowed)
+ ::glEnable(GL_MULTISAMPLE);
+
+ int volume_id = -1;
+ for (GLVolume* vol : m_volumes.volumes)
+ {
+ vol->hover = false;
+ }
+
+ GLubyte color[4] = { 0, 0, 0, 0 };
+ const Size& cnv_size = get_canvas_size();
+ bool inside = (0 <= pos(0)) && (pos(0) < cnv_size.get_width()) && (0 <= pos(1)) && (pos(1) < cnv_size.get_height());
+ if (inside)
+ {
+ ::glReadPixels(pos(0), cnv_size.get_height() - pos(1) - 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color);
+ volume_id = color[0] + color[1] * 256 + color[2] * 256 * 256;
+ }
+
+ if ((0 <= volume_id) && (volume_id < (int)m_volumes.volumes.size()))
+ {
+ m_hover_volume_id = volume_id;
+ m_volumes.volumes[volume_id]->hover = true;
+ int group_id = m_volumes.volumes[volume_id]->select_group_id;
+ if (group_id != -1)
+ {
+ for (GLVolume* vol : m_volumes.volumes)
+ {
+ if (vol->select_group_id == group_id)
+ vol->hover = true;
+ }
+ }
+ m_gizmos.set_hover_id(-1);
+ }
+ else
+ {
+ m_hover_volume_id = -1;
+ m_gizmos.set_hover_id(inside ? (254 - (int)color[2]) : -1);
+ }
+
+ // updates gizmos overlay
+ if (_get_first_selected_object_id() != -1)
+ m_gizmos.update_hover_state(*this, pos);
+ else
+ m_gizmos.reset_all_states();
+
+ m_toolbar.update_hover_state(pos);
+ }
+}
+
+void GLCanvas3D::_render_background() const
+{
+ ::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ ::glPushMatrix();
+ ::glLoadIdentity();
+ ::glMatrixMode(GL_PROJECTION);
+ ::glPushMatrix();
+ ::glLoadIdentity();
+
+ // Draws a bluish bottom to top gradient over the complete screen.
+ ::glDisable(GL_DEPTH_TEST);
+
+ ::glBegin(GL_QUADS);
+ ::glColor3f(0.0f, 0.0f, 0.0f);
+ ::glVertex2f(-1.0f, -1.0f);
+ ::glVertex2f(1.0f, -1.0f);
+
+ if (m_dynamic_background_enabled && _is_any_volume_outside())
+ ::glColor3f(ERROR_BG_COLOR[0], ERROR_BG_COLOR[1], ERROR_BG_COLOR[2]);
+ else
+ ::glColor3f(DEFAULT_BG_COLOR[0], DEFAULT_BG_COLOR[1], DEFAULT_BG_COLOR[2]);
+
+ ::glVertex2f(1.0f, 1.0f);
+ ::glVertex2f(-1.0f, 1.0f);
+ ::glEnd();
+
+ ::glEnable(GL_DEPTH_TEST);
+
+ ::glPopMatrix();
+ ::glMatrixMode(GL_MODELVIEW);
+ ::glPopMatrix();
+}
+
+void GLCanvas3D::_render_bed(float theta) const
+{
+ m_bed.render(theta);
+}
+
+void GLCanvas3D::_render_axes(bool depth_test) const
+{
+ m_axes.render(depth_test);
+}
+
+void GLCanvas3D::_render_objects() const
+{
+ if (m_volumes.empty())
+ return;
+
+ ::glEnable(GL_LIGHTING);
+ ::glEnable(GL_DEPTH_TEST);
+
+ if (!m_shader_enabled)
+ _render_volumes(false);
+ else if (m_use_VBOs)
+ {
+ if (m_picking_enabled)
+ {
+ _mark_volumes_for_layer_height();
+
+ if (m_config != nullptr)
+ {
+ const BoundingBoxf3& bed_bb = m_bed.get_bounding_box();
+ m_volumes.set_print_box((float)bed_bb.min(0), (float)bed_bb.min(1), 0.0f, (float)bed_bb.max(0), (float)bed_bb.max(1), (float)m_config->opt_float("max_print_height"));
+ m_volumes.check_outside_state(m_config, nullptr);
+ }
+ // do not cull backfaces to show broken geometry, if any
+ ::glDisable(GL_CULL_FACE);
+ }
+
+ m_shader.start_using();
+ m_volumes.render_VBOs();
+ m_shader.stop_using();
+
+ if (m_picking_enabled)
+ ::glEnable(GL_CULL_FACE);
+ }
+ else
+ {
+ // do not cull backfaces to show broken geometry, if any
+ if (m_picking_enabled)
+ ::glDisable(GL_CULL_FACE);
+
+ m_volumes.render_legacy();
+
+ if (m_picking_enabled)
+ ::glEnable(GL_CULL_FACE);
+ }
+
+ ::glDisable(GL_LIGHTING);
+}
+
+void GLCanvas3D::_render_cutting_plane() const
+{
+ m_cutting_plane.render(volumes_bounding_box());
+}
+
+void GLCanvas3D::_render_warning_texture() const
+{
+ if (!m_warning_texture_enabled)
+ return;
+
+ m_warning_texture.render(*this);
+}
+
+void GLCanvas3D::_render_legend_texture() const
+{
+ if (!m_legend_texture_enabled)
+ return;
+
+ m_legend_texture.render(*this);
+}
+
+void GLCanvas3D::_render_layer_editing_overlay() const
+{
+ if (m_print == nullptr)
+ return;
+
+ GLVolume* volume = nullptr;
+
+ for (GLVolume* vol : m_volumes.volumes)
+ {
+ if ((vol != nullptr) && vol->selected && vol->has_layer_height_texture())
+ {
+ volume = vol;
+ break;
+ }
+ }
+
+ if (volume == nullptr)
+ return;
+
+ // If the active object was not allocated at the Print, go away.This should only be a momentary case between an object addition / deletion
+ // and an update by Platter::async_apply_config.
+ int object_idx = int(volume->select_group_id / 1000000);
+ if ((int)m_print->objects().size() < object_idx)
+ return;
+
+ const PrintObject* print_object = m_print->get_object(object_idx);
+ if (print_object == nullptr)
+ return;
+
+ m_layers_editing.render(*this, *print_object, *volume);
+}
+
+void GLCanvas3D::_render_volumes(bool fake_colors) const
+{
+ static const GLfloat INV_255 = 1.0f / 255.0f;
+
+ if (!fake_colors)
+ ::glEnable(GL_LIGHTING);
+
+ // do not cull backfaces to show broken geometry, if any
+ ::glDisable(GL_CULL_FACE);
+
+ ::glEnable(GL_BLEND);
+ ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ ::glEnableClientState(GL_VERTEX_ARRAY);
+ ::glEnableClientState(GL_NORMAL_ARRAY);
+
+ unsigned int volume_id = 0;
+ for (GLVolume* vol : m_volumes.volumes)
+ {
+ if (fake_colors)
+ {
+ // Object picking mode. Render the object with a color encoding the object index.
+ unsigned int r = (volume_id & 0x000000FF) >> 0;
+ unsigned int g = (volume_id & 0x0000FF00) >> 8;
+ unsigned int b = (volume_id & 0x00FF0000) >> 16;
+ ::glColor3f((GLfloat)r * INV_255, (GLfloat)g * INV_255, (GLfloat)b * INV_255);
+ }
+ else
+ {
+ vol->set_render_color();
+ ::glColor4f(vol->render_color[0], vol->render_color[1], vol->render_color[2], vol->render_color[3]);
+ }
+
+ vol->render();
+ ++volume_id;
+ }
+
+ ::glDisableClientState(GL_NORMAL_ARRAY);
+ ::glDisableClientState(GL_VERTEX_ARRAY);
+ ::glDisable(GL_BLEND);
+
+ ::glEnable(GL_CULL_FACE);
+
+ if (!fake_colors)
+ ::glDisable(GL_LIGHTING);
+}
+
+void GLCanvas3D::_render_current_gizmo() const
+{
+ m_gizmos.render_current_gizmo(_selected_volumes_bounding_box());
+}
+
+void GLCanvas3D::_render_gizmos_overlay() const
+{
+ m_gizmos.render_overlay(*this);
+}
+
+void GLCanvas3D::_render_toolbar() const
+{
+ _resize_toolbar();
+ m_toolbar.render();
+}
+
+float GLCanvas3D::_get_layers_editing_cursor_z_relative() const
+{
+ return m_layers_editing.get_cursor_z_relative(*this);
+}
+
+void GLCanvas3D::_perform_layer_editing_action(wxMouseEvent* evt)
+{
+ int object_idx_selected = m_layers_editing.last_object_id;
+ if (object_idx_selected == -1)
+ return;
+
+ if (m_print == nullptr)
+ return;
+
+ const PrintObject* selected_obj = m_print->get_object(object_idx_selected);
+ if (selected_obj == nullptr)
+ return;
+
+ // A volume is selected. Test, whether hovering over a layer thickness bar.
+ if (evt != nullptr)
+ {
+ const Rect& rect = LayersEditing::get_bar_rect_screen(*this);
+ float b = rect.get_bottom();
+ m_layers_editing.last_z = unscale<double>(selected_obj->size(2)) * (b - evt->GetY() - 1.0f) / (b - rect.get_top());
+ m_layers_editing.last_action = evt->ShiftDown() ? (evt->RightIsDown() ? 3 : 2) : (evt->RightIsDown() ? 0 : 1);
+ }
+
+ // Mark the volume as modified, so Print will pick its layer height profile ? Where to mark it ?
+ // Start a timer to refresh the print ? schedule_background_process() ?
+ // The PrintObject::adjust_layer_height_profile() call adjusts the profile of its associated ModelObject, it does not modify the profile of the PrintObject itself,
+ // therefore it is safe to call it while the background processing is running.
+ const_cast<PrintObject*>(selected_obj)->adjust_layer_height_profile(m_layers_editing.last_z, m_layers_editing.strength, m_layers_editing.band_width, m_layers_editing.last_action);
+
+ // searches the id of the first volume of the selected object
+ int volume_idx = 0;
+ for (int i = 0; i < object_idx_selected; ++i)
+ {
+ const PrintObject* obj = m_print->get_object(i);
+ if (obj != nullptr)
+ {
+ for (int j = 0; j < (int)obj->region_volumes.size(); ++j)
+ {
+ volume_idx += (int)obj->region_volumes[j].size();
+ }
+ }
+ }
+
+ m_volumes.volumes[volume_idx]->generate_layer_height_texture(selected_obj, 1);
+ _refresh_if_shown_on_screen();
+
+ // Automatic action on mouse down with the same coordinate.
+ _start_timer();
+}
+
+Vec3d GLCanvas3D::_mouse_to_3d(const Point& mouse_pos, float* z)
+{
+ if (m_canvas == nullptr)
+ return Vec3d(DBL_MAX, DBL_MAX, DBL_MAX);
+
+ _camera_tranform();
+
+ GLint viewport[4];
+ ::glGetIntegerv(GL_VIEWPORT, viewport);
+ GLdouble modelview_matrix[16];
+ ::glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix);
+ GLdouble projection_matrix[16];
+ ::glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix);
+
+ GLint y = viewport[3] - (GLint)mouse_pos(1);
+ GLfloat mouse_z;
+ if (z == nullptr)
+ ::glReadPixels((GLint)mouse_pos(0), y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, (void*)&mouse_z);
+ else
+ mouse_z = *z;
+
+ GLdouble out_x, out_y, out_z;
+ ::gluUnProject((GLdouble)mouse_pos(0), (GLdouble)y, (GLdouble)mouse_z, modelview_matrix, projection_matrix, viewport, &out_x, &out_y, &out_z);
+ return Vec3d((double)out_x, (double)out_y, (double)out_z);
+}
+
+Vec3d GLCanvas3D::_mouse_to_bed_3d(const Point& mouse_pos)
+{
+ return mouse_ray(mouse_pos).intersect_plane(0.0);
+}
+
+Linef3 GLCanvas3D::mouse_ray(const Point& mouse_pos)
+{
+ float z0 = 0.0f;
+ float z1 = 1.0f;
+ return Linef3(_mouse_to_3d(mouse_pos, &z0), _mouse_to_3d(mouse_pos, &z1));
+}
+
+void GLCanvas3D::_start_timer()
+{
+ if (m_timer != nullptr)
+ m_timer->Start(100, wxTIMER_CONTINUOUS);
+}
+
+void GLCanvas3D::_stop_timer()
+{
+ if (m_timer != nullptr)
+ m_timer->Stop();
+}
+
+int GLCanvas3D::_get_first_selected_object_id() const
+{
+ if (m_print != nullptr)
+ {
+ int objects_count = (int)m_print->objects().size();
+
+ for (const GLVolume* vol : m_volumes.volumes)
+ {
+ if ((vol != nullptr) && vol->selected)
+ {
+ int object_id = vol->select_group_id / 1000000;
+ // Objects with object_id >= 1000 have a specific meaning, for example the wipe tower proxy.
+ if (object_id < 10000)
+ return (object_id >= objects_count) ? -1 : object_id;
+ }
+ }
+ }
+ return -1;
+}
+
+int GLCanvas3D::_get_first_selected_volume_id(int object_id) const
+{
+ int volume_id = -1;
+
+ for (const GLVolume* vol : m_volumes.volumes)
+ {
+ ++volume_id;
+ if ((vol != nullptr) && vol->selected && (object_id == vol->select_group_id / 1000000))
+ return volume_id;
+ }
+
+ return -1;
+}
+
+void GLCanvas3D::_load_print_toolpaths()
+{
+ // ensures this canvas is current
+ if (!set_current())
+ return;
+
+ if (m_print == nullptr)
+ return;
+
+ if (!m_print->is_step_done(psSkirt) || !m_print->is_step_done(psBrim))
+ return;
+
+ if (!m_print->has_skirt() && (m_print->config().brim_width.value == 0))
+ return;
+
+ const float color[] = { 0.5f, 1.0f, 0.5f, 1.0f }; // greenish
+
+ // number of skirt layers
+ size_t total_layer_count = 0;
+ for (const PrintObject* print_object : m_print->objects())
+ {
+ total_layer_count = std::max(total_layer_count, print_object->total_layer_count());
+ }
+ size_t skirt_height = m_print->has_infinite_skirt() ? total_layer_count : std::min<size_t>(m_print->config().skirt_height.value, total_layer_count);
+ if ((skirt_height == 0) && (m_print->config().brim_width.value > 0))
+ skirt_height = 1;
+
+ // get first skirt_height layers (maybe this should be moved to a PrintObject method?)
+ const PrintObject* object0 = m_print->objects().front();
+ std::vector<float> print_zs;
+ print_zs.reserve(skirt_height * 2);
+ for (size_t i = 0; i < std::min(skirt_height, object0->layers().size()); ++i)
+ {
+ print_zs.push_back(float(object0->layers()[i]->print_z));
+ }
+ //FIXME why there are support layers?
+ for (size_t i = 0; i < std::min(skirt_height, object0->support_layers().size()); ++i)
+ {
+ print_zs.push_back(float(object0->support_layers()[i]->print_z));
+ }
+ sort_remove_duplicates(print_zs);
+ if (print_zs.size() > skirt_height)
+ print_zs.erase(print_zs.begin() + skirt_height, print_zs.end());
+
+ m_volumes.volumes.emplace_back(new GLVolume(color));
+ GLVolume& volume = *m_volumes.volumes.back();
+ for (size_t i = 0; i < skirt_height; ++i) {
+ volume.print_zs.push_back(print_zs[i]);
+ volume.offsets.push_back(volume.indexed_vertex_array.quad_indices.size());
+ volume.offsets.push_back(volume.indexed_vertex_array.triangle_indices.size());
+ if (i == 0)
+ _3DScene::extrusionentity_to_verts(m_print->brim(), print_zs[i], Point(0, 0), volume);
+
+ _3DScene::extrusionentity_to_verts(m_print->skirt(), print_zs[i], Point(0, 0), volume);
+ }
+ volume.bounding_box = volume.indexed_vertex_array.bounding_box();
+ volume.indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
+}
+
+void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors)
+{
+ std::vector<float> tool_colors = _parse_colors(str_tool_colors);
+
+ struct Ctxt
+ {
+ const Points *shifted_copies;
+ std::vector<const Layer*> layers;
+ bool has_perimeters;
+ bool has_infill;
+ bool has_support;
+ const std::vector<float>* tool_colors;
+
+ // Number of vertices (each vertex is 6x4=24 bytes long)
+ static const size_t alloc_size_max() { return 131072; } // 3.15MB
+ // static const size_t alloc_size_max () { return 65536; } // 1.57MB
+ // static const size_t alloc_size_max () { return 32768; } // 786kB
+ static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
+
+ static const float* color_perimeters() { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow
+ static const float* color_infill() { static float color[4] = { 1.0f, 0.5f, 0.5f, 1.f }; return color; } // redish
+ static const float* color_support() { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
+
+ // For cloring by a tool, return a parsed color.
+ bool color_by_tool() const { return tool_colors != nullptr; }
+ size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; }
+ const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
+ int volume_idx(int extruder, int feature) const
+ {
+ return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(extruder - 1, 0)) : feature;
+ }
+ } ctxt;
+
+ ctxt.shifted_copies = &print_object.copies();
+
+ // order layers by print_z
+ ctxt.layers.reserve(print_object.layers().size() + print_object.support_layers().size());
+ for (const Layer *layer : print_object.layers())
+ ctxt.layers.push_back(layer);
+ for (const Layer *layer : print_object.support_layers())
+ ctxt.layers.push_back(layer);
+ std::sort(ctxt.layers.begin(), ctxt.layers.end(), [](const Layer *l1, const Layer *l2) { return l1->print_z < l2->print_z; });
+
+ // Maximum size of an allocation block: 32MB / sizeof(float)
+ ctxt.has_perimeters = print_object.is_step_done(posPerimeters);
+ ctxt.has_infill = print_object.is_step_done(posInfill);
+ ctxt.has_support = print_object.is_step_done(posSupportMaterial);
+ ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start";
+
+ //FIXME Improve the heuristics for a grain size.
+ size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1));
+ tbb::spin_mutex new_volume_mutex;
+ auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* {
+ auto *volume = new GLVolume(color);
+ new_volume_mutex.lock();
+ m_volumes.volumes.emplace_back(volume);
+ new_volume_mutex.unlock();
+ return volume;
+ };
+ const size_t volumes_cnt_initial = m_volumes.volumes.size();
+ std::vector<GLVolumeCollection> volumes_per_thread(ctxt.layers.size());
+ tbb::parallel_for(
+ tbb::blocked_range<size_t>(0, ctxt.layers.size(), grain_size),
+ [&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
+ std::vector<GLVolume*> vols;
+ if (ctxt.color_by_tool()) {
+ for (size_t i = 0; i < ctxt.number_tools(); ++i)
+ vols.emplace_back(new_volume(ctxt.color_tool(i)));
+ }
+ else
+ vols = { new_volume(ctxt.color_perimeters()), new_volume(ctxt.color_infill()), new_volume(ctxt.color_support()) };
+ for (GLVolume *vol : vols)
+ vol->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+ for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) {
+ const Layer *layer = ctxt.layers[idx_layer];
+ for (size_t i = 0; i < vols.size(); ++i) {
+ GLVolume &vol = *vols[i];
+ if (vol.print_zs.empty() || vol.print_zs.back() != layer->print_z) {
+ vol.print_zs.push_back(layer->print_z);
+ vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
+ vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
+ }
+ }
+ for (const Point &copy : *ctxt.shifted_copies) {
+ for (const LayerRegion *layerm : layer->regions()) {
+ if (ctxt.has_perimeters)
+ _3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
+ *vols[ctxt.volume_idx(layerm->region()->config().perimeter_extruder.value, 0)]);
+ if (ctxt.has_infill) {
+ for (const ExtrusionEntity *ee : layerm->fills.entities) {
+ // fill represents infill extrusions of a single island.
+ const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
+ if (!fill->entities.empty())
+ _3DScene::extrusionentity_to_verts(*fill, float(layer->print_z), copy,
+ *vols[ctxt.volume_idx(
+ is_solid_infill(fill->entities.front()->role()) ?
+ layerm->region()->config().solid_infill_extruder :
+ layerm->region()->config().infill_extruder,
+ 1)]);
+ }
+ }
+ }
+ if (ctxt.has_support) {
+ const SupportLayer *support_layer = dynamic_cast<const SupportLayer*>(layer);
+ if (support_layer) {
+ for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
+ _3DScene::extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy,
+ *vols[ctxt.volume_idx(
+ (extrusion_entity->role() == erSupportMaterial) ?
+ support_layer->object()->config().support_material_extruder :
+ support_layer->object()->config().support_material_interface_extruder,
+ 2)]);
+ }
+ }
+ }
+ for (size_t i = 0; i < vols.size(); ++i) {
+ GLVolume &vol = *vols[i];
+ if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
+ // Store the vertex arrays and restart their containers,
+ vols[i] = new_volume(vol.color);
+ GLVolume &vol_new = *vols[i];
+ // Assign the large pre-allocated buffers to the new GLVolume.
+ vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
+ // Copy the content back to the old GLVolume.
+ vol.indexed_vertex_array = vol_new.indexed_vertex_array;
+ // Finalize a bounding box of the old GLVolume.
+ vol.bounding_box = vol.indexed_vertex_array.bounding_box();
+ // Clear the buffers, but keep them pre-allocated.
+ vol_new.indexed_vertex_array.clear();
+ // Just make sure that clear did not clear the reserved memory.
+ vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+ }
+ }
+ }
+ for (GLVolume *vol : vols) {
+ vol->bounding_box = vol->indexed_vertex_array.bounding_box();
+ vol->indexed_vertex_array.shrink_to_fit();
+ }
+ });
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results";
+ // Remove empty volumes from the newly added volumes.
+ m_volumes.volumes.erase(
+ std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(),
+ [](const GLVolume *volume) { return volume->empty(); }),
+ m_volumes.volumes.end());
+ for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i)
+ m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end";
+}
+
+void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors)
+{
+ if ((m_print == nullptr) || m_print->wipe_tower_data().tool_changes.empty())
+ return;
+
+ if (!m_print->is_step_done(psWipeTower))
+ return;
+
+ std::vector<float> tool_colors = _parse_colors(str_tool_colors);
+
+ struct Ctxt
+ {
+ const Print *print;
+ const std::vector<float> *tool_colors;
+ WipeTower::xy wipe_tower_pos;
+ float wipe_tower_angle;
+
+ // Number of vertices (each vertex is 6x4=24 bytes long)
+ static const size_t alloc_size_max() { return 131072; } // 3.15MB
+ static const size_t alloc_size_reserve() { return alloc_size_max() * 2; }
+
+ static const float* color_support() { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
+
+ // For cloring by a tool, return a parsed color.
+ bool color_by_tool() const { return tool_colors != nullptr; }
+ size_t number_tools() const { return this->color_by_tool() ? tool_colors->size() / 4 : 0; }
+ const float* color_tool(size_t tool) const { return tool_colors->data() + tool * 4; }
+ int volume_idx(int tool, int feature) const
+ {
+ return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(tool, 0)) : feature;
+ }
+
+ const std::vector<WipeTower::ToolChangeResult>& tool_change(size_t idx) {
+ const auto &tool_changes = print->wipe_tower_data().tool_changes;
+ return priming.empty() ?
+ ((idx == tool_changes.size()) ? final : tool_changes[idx]) :
+ ((idx == 0) ? priming : (idx == tool_changes.size() + 1) ? final : tool_changes[idx - 1]);
+ }
+ std::vector<WipeTower::ToolChangeResult> priming;
+ std::vector<WipeTower::ToolChangeResult> final;
+ } ctxt;
+
+ ctxt.print = m_print;
+ ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
+ if (m_print->wipe_tower_data().priming && m_print->config().single_extruder_multi_material_priming)
+ ctxt.priming.emplace_back(*m_print->wipe_tower_data().priming.get());
+ if (m_print->wipe_tower_data().final_purge)
+ ctxt.final.emplace_back(*m_print->wipe_tower_data().final_purge.get());
+
+ ctxt.wipe_tower_angle = ctxt.print->config().wipe_tower_rotation_angle.value/180.f * PI;
+ ctxt.wipe_tower_pos = WipeTower::xy(ctxt.print->config().wipe_tower_x.value, ctxt.print->config().wipe_tower_y.value);
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - start";
+
+ //FIXME Improve the heuristics for a grain size.
+ size_t n_items = m_print->wipe_tower_data().tool_changes.size() + (ctxt.priming.empty() ? 0 : 1);
+ size_t grain_size = std::max(n_items / 128, size_t(1));
+ tbb::spin_mutex new_volume_mutex;
+ auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* {
+ auto *volume = new GLVolume(color);
+ new_volume_mutex.lock();
+ m_volumes.volumes.emplace_back(volume);
+ new_volume_mutex.unlock();
+ return volume;
+ };
+ const size_t volumes_cnt_initial = m_volumes.volumes.size();
+ std::vector<GLVolumeCollection> volumes_per_thread(n_items);
+ tbb::parallel_for(
+ tbb::blocked_range<size_t>(0, n_items, grain_size),
+ [&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
+ // Bounding box of this slab of a wipe tower.
+ std::vector<GLVolume*> vols;
+ if (ctxt.color_by_tool()) {
+ for (size_t i = 0; i < ctxt.number_tools(); ++i)
+ vols.emplace_back(new_volume(ctxt.color_tool(i)));
+ }
+ else
+ vols = { new_volume(ctxt.color_support()) };
+ for (GLVolume *volume : vols)
+ volume->indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+ for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) {
+ const std::vector<WipeTower::ToolChangeResult> &layer = ctxt.tool_change(idx_layer);
+ for (size_t i = 0; i < vols.size(); ++i) {
+ GLVolume &vol = *vols[i];
+ if (vol.print_zs.empty() || vol.print_zs.back() != layer.front().print_z) {
+ vol.print_zs.push_back(layer.front().print_z);
+ vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size());
+ vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size());
+ }
+ }
+ for (const WipeTower::ToolChangeResult &extrusions : layer) {
+ for (size_t i = 1; i < extrusions.extrusions.size();) {
+ const WipeTower::Extrusion &e = extrusions.extrusions[i];
+ if (e.width == 0.) {
+ ++i;
+ continue;
+ }
+ size_t j = i + 1;
+ if (ctxt.color_by_tool())
+ for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].tool == e.tool && extrusions.extrusions[j].width > 0.f; ++j);
+ else
+ for (; j < extrusions.extrusions.size() && extrusions.extrusions[j].width > 0.f; ++j);
+ size_t n_lines = j - i;
+ Lines lines;
+ std::vector<double> widths;
+ std::vector<double> heights;
+ lines.reserve(n_lines);
+ widths.reserve(n_lines);
+ heights.assign(n_lines, extrusions.layer_height);
+ WipeTower::Extrusion e_prev = extrusions.extrusions[i-1];
+
+ if (!extrusions.priming) { // wipe tower extrusions describe the wipe tower at the origin with no rotation
+ e_prev.pos.rotate(ctxt.wipe_tower_angle);
+ e_prev.pos.translate(ctxt.wipe_tower_pos);
+ }
+
+ for (; i < j; ++i) {
+ WipeTower::Extrusion e = extrusions.extrusions[i];
+ assert(e.width > 0.f);
+ if (!extrusions.priming) {
+ e.pos.rotate(ctxt.wipe_tower_angle);
+ e.pos.translate(ctxt.wipe_tower_pos);
+ }
+
+ lines.emplace_back(Point::new_scale(e_prev.pos.x, e_prev.pos.y), Point::new_scale(e.pos.x, e.pos.y));
+ widths.emplace_back(e.width);
+
+ e_prev = e;
+ }
+ _3DScene::thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z,
+ *vols[ctxt.volume_idx(e.tool, 0)]);
+ }
+ }
+ }
+ for (size_t i = 0; i < vols.size(); ++i) {
+ GLVolume &vol = *vols[i];
+ if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() / 6 > ctxt.alloc_size_max()) {
+ // Store the vertex arrays and restart their containers,
+ vols[i] = new_volume(vol.color);
+ GLVolume &vol_new = *vols[i];
+ // Assign the large pre-allocated buffers to the new GLVolume.
+ vol_new.indexed_vertex_array = std::move(vol.indexed_vertex_array);
+ // Copy the content back to the old GLVolume.
+ vol.indexed_vertex_array = vol_new.indexed_vertex_array;
+ // Finalize a bounding box of the old GLVolume.
+ vol.bounding_box = vol.indexed_vertex_array.bounding_box();
+ // Clear the buffers, but keep them pre-allocated.
+ vol_new.indexed_vertex_array.clear();
+ // Just make sure that clear did not clear the reserved memory.
+ vol_new.indexed_vertex_array.reserve(ctxt.alloc_size_reserve());
+ }
+ }
+ for (GLVolume *vol : vols) {
+ vol->bounding_box = vol->indexed_vertex_array.bounding_box();
+ vol->indexed_vertex_array.shrink_to_fit();
+ }
+ });
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results";
+ // Remove empty volumes from the newly added volumes.
+ m_volumes.volumes.erase(
+ std::remove_if(m_volumes.volumes.begin() + volumes_cnt_initial, m_volumes.volumes.end(),
+ [](const GLVolume *volume) { return volume->empty(); }),
+ m_volumes.volumes.end());
+ for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i)
+ m_volumes.volumes[i]->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
+
+ BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end";
+}
+
+static inline int hex_digit_to_int(const char c)
+{
+ return
+ (c >= '0' && c <= '9') ? int(c - '0') :
+ (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
+ (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
+}
+
+void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
+{
+ // helper functions to select data in dependence of the extrusion view type
+ struct Helper
+ {
+ static float path_filter(GCodePreviewData::Extrusion::EViewType type, const ExtrusionPath& path)
+ {
+ switch (type)
+ {
+ case GCodePreviewData::Extrusion::FeatureType:
+ return (float)path.role();
+ case GCodePreviewData::Extrusion::Height:
+ return path.height;
+ case GCodePreviewData::Extrusion::Width:
+ return path.width;
+ case GCodePreviewData::Extrusion::Feedrate:
+ return path.feedrate;
+ case GCodePreviewData::Extrusion::VolumetricRate:
+ return path.feedrate * (float)path.mm3_per_mm;
+ case GCodePreviewData::Extrusion::Tool:
+ return (float)path.extruder_id;
+ default:
+ return 0.0f;
+ }
+
+ return 0.0f;
+ }
+
+ static GCodePreviewData::Color path_color(const GCodePreviewData& data, const std::vector<float>& tool_colors, float value)
+ {
+ switch (data.extrusion.view_type)
+ {
+ case GCodePreviewData::Extrusion::FeatureType:
+ return data.get_extrusion_role_color((ExtrusionRole)(int)value);
+ case GCodePreviewData::Extrusion::Height:
+ return data.get_height_color(value);
+ case GCodePreviewData::Extrusion::Width:
+ return data.get_width_color(value);
+ case GCodePreviewData::Extrusion::Feedrate:
+ return data.get_feedrate_color(value);
+ case GCodePreviewData::Extrusion::VolumetricRate:
+ return data.get_volumetric_rate_color(value);
+ case GCodePreviewData::Extrusion::Tool:
+ {
+ GCodePreviewData::Color color;
+ ::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + (unsigned int)value * 4), 4 * sizeof(float));
+ return color;
+ }
+ default:
+ return GCodePreviewData::Color::Dummy;
+ }
+
+ return GCodePreviewData::Color::Dummy;
+ }
+ };
+
+ // Helper structure for filters
+ struct Filter
+ {
+ float value;
+ ExtrusionRole role;
+ GLVolume* volume;
+
+ Filter(float value, ExtrusionRole role)
+ : value(value)
+ , role(role)
+ , volume(nullptr)
+ {
+ }
+
+ bool operator == (const Filter& other) const
+ {
+ if (value != other.value)
+ return false;
+
+ if (role != other.role)
+ return false;
+
+ return true;
+ }
+ };
+
+ typedef std::vector<Filter> FiltersList;
+ size_t initial_volumes_count = m_volumes.volumes.size();
+
+ // detects filters
+ FiltersList filters;
+ for (const GCodePreviewData::Extrusion::Layer& layer : preview_data.extrusion.layers)
+ {
+ for (const ExtrusionPath& path : layer.paths)
+ {
+ ExtrusionRole role = path.role();
+ float path_filter = Helper::path_filter(preview_data.extrusion.view_type, path);
+ if (std::find(filters.begin(), filters.end(), Filter(path_filter, role)) == filters.end())
+ filters.emplace_back(path_filter, role);
+ }
+ }
+
+ // nothing to render, return
+ if (filters.empty())
+ return;
+
+ // creates a new volume for each filter
+ for (Filter& filter : filters)
+ {
+ m_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Extrusion, (unsigned int)filter.role, (unsigned int)m_volumes.volumes.size());
+ GLVolume* volume = new GLVolume(Helper::path_color(preview_data, tool_colors, filter.value).rgba);
+ if (volume != nullptr)
+ {
+ filter.volume = volume;
+ volume->is_extrusion_path = true;
+ m_volumes.volumes.emplace_back(volume);
+ }
+ else
+ {
+ // an error occourred - restore to previous state and return
+ m_gcode_preview_volume_index.first_volumes.pop_back();
+ if (initial_volumes_count != m_volumes.volumes.size())
+ {
+ std::vector<GLVolume*>::iterator begin = m_volumes.volumes.begin() + initial_volumes_count;
+ std::vector<GLVolume*>::iterator end = m_volumes.volumes.end();
+ for (std::vector<GLVolume*>::iterator it = begin; it < end; ++it)
+ {
+ GLVolume* volume = *it;
+ delete volume;
+ }
+ m_volumes.volumes.erase(begin, end);
+ return;
+ }
+ }
+ }
+
+ // populates volumes
+ for (const GCodePreviewData::Extrusion::Layer& layer : preview_data.extrusion.layers)
+ {
+ for (const ExtrusionPath& path : layer.paths)
+ {
+ float path_filter = Helper::path_filter(preview_data.extrusion.view_type, path);
+ FiltersList::iterator filter = std::find(filters.begin(), filters.end(), Filter(path_filter, path.role()));
+ if (filter != filters.end())
+ {
+ filter->volume->print_zs.push_back(layer.z);
+ filter->volume->offsets.push_back(filter->volume->indexed_vertex_array.quad_indices.size());
+ filter->volume->offsets.push_back(filter->volume->indexed_vertex_array.triangle_indices.size());
+
+ _3DScene::extrusionentity_to_verts(path, layer.z, *filter->volume);
+ }
+ }
+ }
+
+ // finalize volumes and sends geometry to gpu
+ if (m_volumes.volumes.size() > initial_volumes_count)
+ {
+ for (size_t i = initial_volumes_count; i < m_volumes.volumes.size(); ++i)
+ {
+ GLVolume* volume = m_volumes.volumes[i];
+ volume->bounding_box = volume->indexed_vertex_array.bounding_box();
+ volume->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
+ }
+ }
+}
+
+void GLCanvas3D::_load_gcode_travel_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
+{
+ size_t initial_volumes_count = m_volumes.volumes.size();
+ m_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Travel, 0, (unsigned int)initial_volumes_count);
+
+ bool res = true;
+ switch (preview_data.extrusion.view_type)
+ {
+ case GCodePreviewData::Extrusion::Feedrate:
+ {
+ res = _travel_paths_by_feedrate(preview_data);
+ break;
+ }
+ case GCodePreviewData::Extrusion::Tool:
+ {
+ res = _travel_paths_by_tool(preview_data, tool_colors);
+ break;
+ }
+ default:
+ {
+ res = _travel_paths_by_type(preview_data);
+ break;
+ }
+ }
+
+ if (!res)
+ {
+ // an error occourred - restore to previous state and return
+ if (initial_volumes_count != m_volumes.volumes.size())
+ {
+ std::vector<GLVolume*>::iterator begin = m_volumes.volumes.begin() + initial_volumes_count;
+ std::vector<GLVolume*>::iterator end = m_volumes.volumes.end();
+ for (std::vector<GLVolume*>::iterator it = begin; it < end; ++it)
+ {
+ GLVolume* volume = *it;
+ delete volume;
+ }
+ m_volumes.volumes.erase(begin, end);
+ }
+
+ return;
+ }
+
+ // finalize volumes and sends geometry to gpu
+ if (m_volumes.volumes.size() > initial_volumes_count)
+ {
+ for (size_t i = initial_volumes_count; i < m_volumes.volumes.size(); ++i)
+ {
+ GLVolume* volume = m_volumes.volumes[i];
+ volume->bounding_box = volume->indexed_vertex_array.bounding_box();
+ volume->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
+ }
+ }
+}
+
+bool GLCanvas3D::_travel_paths_by_type(const GCodePreviewData& preview_data)
+{
+ // Helper structure for types
+ struct Type
+ {
+ GCodePreviewData::Travel::EType value;
+ GLVolume* volume;
+
+ explicit Type(GCodePreviewData::Travel::EType value)
+ : value(value)
+ , volume(nullptr)
+ {
+ }
+
+ bool operator == (const Type& other) const
+ {
+ return value == other.value;
+ }
+ };
+
+ typedef std::vector<Type> TypesList;
+
+ // colors travels by travel type
+
+ // detects types
+ TypesList types;
+ for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
+ {
+ if (std::find(types.begin(), types.end(), Type(polyline.type)) == types.end())
+ types.emplace_back(polyline.type);
+ }
+
+ // nothing to render, return
+ if (types.empty())
+ return true;
+
+ // creates a new volume for each type
+ for (Type& type : types)
+ {
+ GLVolume* volume = new GLVolume(preview_data.travel.type_colors[type.value].rgba);
+ if (volume == nullptr)
+ return false;
+ else
+ {
+ type.volume = volume;
+ m_volumes.volumes.emplace_back(volume);
+ }
+ }
+
+ // populates volumes
+ for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
+ {
+ TypesList::iterator type = std::find(types.begin(), types.end(), Type(polyline.type));
+ if (type != types.end())
+ {
+ type->volume->print_zs.push_back(unscale<double>(polyline.polyline.bounding_box().min(2)));
+ type->volume->offsets.push_back(type->volume->indexed_vertex_array.quad_indices.size());
+ type->volume->offsets.push_back(type->volume->indexed_vertex_array.triangle_indices.size());
+
+ _3DScene::polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *type->volume);
+ }
+ }
+
+ return true;
+}
+
+bool GLCanvas3D::_travel_paths_by_feedrate(const GCodePreviewData& preview_data)
+{
+ // Helper structure for feedrate
+ struct Feedrate
+ {
+ float value;
+ GLVolume* volume;
+
+ explicit Feedrate(float value)
+ : value(value)
+ , volume(nullptr)
+ {
+ }
+
+ bool operator == (const Feedrate& other) const
+ {
+ return value == other.value;
+ }
+ };
+
+ typedef std::vector<Feedrate> FeedratesList;
+
+ // colors travels by feedrate
+
+ // detects feedrates
+ FeedratesList feedrates;
+ for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
+ {
+ if (std::find(feedrates.begin(), feedrates.end(), Feedrate(polyline.feedrate)) == feedrates.end())
+ feedrates.emplace_back(polyline.feedrate);
+ }
+
+ // nothing to render, return
+ if (feedrates.empty())
+ return true;
+
+ // creates a new volume for each feedrate
+ for (Feedrate& feedrate : feedrates)
+ {
+ GLVolume* volume = new GLVolume(preview_data.get_feedrate_color(feedrate.value).rgba);
+ if (volume == nullptr)
+ return false;
+ else
+ {
+ feedrate.volume = volume;
+ m_volumes.volumes.emplace_back(volume);
+ }
+ }
+
+ // populates volumes
+ for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
+ {
+ FeedratesList::iterator feedrate = std::find(feedrates.begin(), feedrates.end(), Feedrate(polyline.feedrate));
+ if (feedrate != feedrates.end())
+ {
+ feedrate->volume->print_zs.push_back(unscale<double>(polyline.polyline.bounding_box().min(2)));
+ feedrate->volume->offsets.push_back(feedrate->volume->indexed_vertex_array.quad_indices.size());
+ feedrate->volume->offsets.push_back(feedrate->volume->indexed_vertex_array.triangle_indices.size());
+
+ _3DScene::polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *feedrate->volume);
+ }
+ }
+
+ return true;
+}
+
+bool GLCanvas3D::_travel_paths_by_tool(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
+{
+ // Helper structure for tool
+ struct Tool
+ {
+ unsigned int value;
+ GLVolume* volume;
+
+ explicit Tool(unsigned int value)
+ : value(value)
+ , volume(nullptr)
+ {
+ }
+
+ bool operator == (const Tool& other) const
+ {
+ return value == other.value;
+ }
+ };
+
+ typedef std::vector<Tool> ToolsList;
+
+ // colors travels by tool
+
+ // detects tools
+ ToolsList tools;
+ for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
+ {
+ if (std::find(tools.begin(), tools.end(), Tool(polyline.extruder_id)) == tools.end())
+ tools.emplace_back(polyline.extruder_id);
+ }
+
+ // nothing to render, return
+ if (tools.empty())
+ return true;
+
+ // creates a new volume for each tool
+ for (Tool& tool : tools)
+ {
+ GLVolume* volume = new GLVolume(tool_colors.data() + tool.value * 4);
+ if (volume == nullptr)
+ return false;
+ else
+ {
+ tool.volume = volume;
+ m_volumes.volumes.emplace_back(volume);
+ }
+ }
+
+ // populates volumes
+ for (const GCodePreviewData::Travel::Polyline& polyline : preview_data.travel.polylines)
+ {
+ ToolsList::iterator tool = std::find(tools.begin(), tools.end(), Tool(polyline.extruder_id));
+ if (tool != tools.end())
+ {
+ tool->volume->print_zs.push_back(unscale<double>(polyline.polyline.bounding_box().min(2)));
+ tool->volume->offsets.push_back(tool->volume->indexed_vertex_array.quad_indices.size());
+ tool->volume->offsets.push_back(tool->volume->indexed_vertex_array.triangle_indices.size());
+
+ _3DScene::polyline3_to_verts(polyline.polyline, preview_data.travel.width, preview_data.travel.height, *tool->volume);
+ }
+ }
+
+ return true;
+}
+
+void GLCanvas3D::_load_gcode_retractions(const GCodePreviewData& preview_data)
+{
+ m_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Retraction, 0, (unsigned int)m_volumes.volumes.size());
+
+ // nothing to render, return
+ if (preview_data.retraction.positions.empty())
+ return;
+
+ GLVolume* volume = new GLVolume(preview_data.retraction.color.rgba);
+ if (volume != nullptr)
+ {
+ m_volumes.volumes.emplace_back(volume);
+
+ GCodePreviewData::Retraction::PositionsList copy(preview_data.retraction.positions);
+ std::sort(copy.begin(), copy.end(), [](const GCodePreviewData::Retraction::Position& p1, const GCodePreviewData::Retraction::Position& p2){ return p1.position(2) < p2.position(2); });
+
+ for (const GCodePreviewData::Retraction::Position& position : copy)
+ {
+ volume->print_zs.push_back(unscale<double>(position.position(2)));
+ volume->offsets.push_back(volume->indexed_vertex_array.quad_indices.size());
+ volume->offsets.push_back(volume->indexed_vertex_array.triangle_indices.size());
+
+ _3DScene::point3_to_verts(position.position, position.width, position.height, *volume);
+ }
+
+ // finalize volumes and sends geometry to gpu
+ volume->bounding_box = volume->indexed_vertex_array.bounding_box();
+ volume->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
+ }
+}
+
+void GLCanvas3D::_load_gcode_unretractions(const GCodePreviewData& preview_data)
+{
+ m_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Unretraction, 0, (unsigned int)m_volumes.volumes.size());
+
+ // nothing to render, return
+ if (preview_data.unretraction.positions.empty())
+ return;
+
+ GLVolume* volume = new GLVolume(preview_data.unretraction.color.rgba);
+ if (volume != nullptr)
+ {
+ m_volumes.volumes.emplace_back(volume);
+
+ GCodePreviewData::Retraction::PositionsList copy(preview_data.unretraction.positions);
+ std::sort(copy.begin(), copy.end(), [](const GCodePreviewData::Retraction::Position& p1, const GCodePreviewData::Retraction::Position& p2){ return p1.position(2) < p2.position(2); });
+
+ for (const GCodePreviewData::Retraction::Position& position : copy)
+ {
+ volume->print_zs.push_back(unscale<double>(position.position(2)));
+ volume->offsets.push_back(volume->indexed_vertex_array.quad_indices.size());
+ volume->offsets.push_back(volume->indexed_vertex_array.triangle_indices.size());
+
+ _3DScene::point3_to_verts(position.position, position.width, position.height, *volume);
+ }
+
+ // finalize volumes and sends geometry to gpu
+ volume->bounding_box = volume->indexed_vertex_array.bounding_box();
+ volume->indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
+ }
+}
+
+void GLCanvas3D::_load_shells()
+{
+ size_t initial_volumes_count = m_volumes.volumes.size();
+ m_gcode_preview_volume_index.first_volumes.emplace_back(GCodePreviewVolumeIndex::Shell, 0, (unsigned int)initial_volumes_count);
+
+ if (m_print->objects().empty())
+ // nothing to render, return
+ return;
+
+ // adds objects' volumes
+ unsigned int object_id = 0;
+ for (PrintObject* obj : m_print->objects())
+ {
+ ModelObject* model_obj = obj->model_object();
+
+ std::vector<int> instance_ids(model_obj->instances.size());
+ for (int i = 0; i < (int)model_obj->instances.size(); ++i)
+ {
+ instance_ids[i] = i;
+ }
+
+ m_volumes.load_object(model_obj, object_id, instance_ids, "object", "object", "object", m_use_VBOs && m_initialized);
+
+ ++object_id;
+ }
+
+ // adds wipe tower's volume
+ double max_z = m_print->objects()[0]->model_object()->get_model()->bounding_box().max(2);
+ const PrintConfig& config = m_print->config();
+ unsigned int extruders_count = config.nozzle_diameter.size();
+ if ((extruders_count > 1) && config.single_extruder_multi_material && config.wipe_tower && !config.complete_objects) {
+ float depth = m_print->get_wipe_tower_depth();
+ if (!m_print->is_step_done(psWipeTower))
+ depth = (900.f/config.wipe_tower_width) * (float)(extruders_count - 1) ;
+ m_volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
+ m_use_VBOs && m_initialized, !m_print->is_step_done(psWipeTower), m_print->config().nozzle_diameter.values[0] * 1.25f * 4.5f);
+ }
+}
+
+void GLCanvas3D::_update_gcode_volumes_visibility(const GCodePreviewData& preview_data)
+{
+ unsigned int size = (unsigned int)m_gcode_preview_volume_index.first_volumes.size();
+ for (unsigned int i = 0; i < size; ++i)
+ {
+ std::vector<GLVolume*>::iterator begin = m_volumes.volumes.begin() + m_gcode_preview_volume_index.first_volumes[i].id;
+ std::vector<GLVolume*>::iterator end = (i + 1 < size) ? m_volumes.volumes.begin() + m_gcode_preview_volume_index.first_volumes[i + 1].id : m_volumes.volumes.end();
+
+ for (std::vector<GLVolume*>::iterator it = begin; it != end; ++it)
+ {
+ GLVolume* volume = *it;
+
+ switch (m_gcode_preview_volume_index.first_volumes[i].type)
+ {
+ case GCodePreviewVolumeIndex::Extrusion:
+ {
+ if ((ExtrusionRole)m_gcode_preview_volume_index.first_volumes[i].flag == erCustom)
+ volume->zoom_to_volumes = false;
+
+ volume->is_active = preview_data.extrusion.is_role_flag_set((ExtrusionRole)m_gcode_preview_volume_index.first_volumes[i].flag);
+ break;
+ }
+ case GCodePreviewVolumeIndex::Travel:
+ {
+ volume->is_active = preview_data.travel.is_visible;
+ volume->zoom_to_volumes = false;
+ break;
+ }
+ case GCodePreviewVolumeIndex::Retraction:
+ {
+ volume->is_active = preview_data.retraction.is_visible;
+ volume->zoom_to_volumes = false;
+ break;
+ }
+ case GCodePreviewVolumeIndex::Unretraction:
+ {
+ volume->is_active = preview_data.unretraction.is_visible;
+ volume->zoom_to_volumes = false;
+ break;
+ }
+ case GCodePreviewVolumeIndex::Shell:
+ {
+ volume->is_active = preview_data.shell.is_visible;
+ volume->color[3] = 0.25f;
+ volume->zoom_to_volumes = false;
+ break;
+ }
+ default:
+ {
+ volume->is_active = false;
+ volume->zoom_to_volumes = false;
+ break;
+ }
+ }
+ }
+ }
+}
+
+void GLCanvas3D::_update_toolpath_volumes_outside_state()
+{
+ // tolerance to avoid false detection at bed edges
+ static const double tolerance_x = 0.05;
+ static const double tolerance_y = 0.05;
+
+ BoundingBoxf3 print_volume;
+ if (m_config != nullptr)
+ {
+ const ConfigOptionPoints* opt = dynamic_cast<const ConfigOptionPoints*>(m_config->option("bed_shape"));
+ if (opt != nullptr)
+ {
+ BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values));
+ print_volume = BoundingBoxf3(Vec3d(unscale<double>(bed_box_2D.min(0)) - tolerance_x, unscale<double>(bed_box_2D.min(1)) - tolerance_y, 0.0), Vec3d(unscale<double>(bed_box_2D.max(0)) + tolerance_x, unscale<double>(bed_box_2D.max(1)) + tolerance_y, m_config->opt_float("max_print_height")));
+ // Allow the objects to protrude below the print bed
+ print_volume.min(2) = -1e10;
+ }
+ }
+
+ for (GLVolume* volume : m_volumes.volumes)
+ {
+ volume->is_outside = ((print_volume.radius() > 0.0) && volume->is_extrusion_path) ? !print_volume.contains(volume->bounding_box) : false;
+ }
+}
+
+void GLCanvas3D::_show_warning_texture_if_needed()
+{
+ if (_is_any_volume_outside())
+ {
+ enable_warning_texture(true);
+ _generate_warning_texture(L("Detected toolpath outside print volume"));
+ }
+ else
+ {
+ enable_warning_texture(false);
+ _reset_warning_texture();
+ }
+}
+
+void GLCanvas3D::_on_move(const std::vector<int>& volume_idxs)
+{
+ if (m_model == nullptr)
+ return;
+
+ std::set<std::string> done; // prevent moving instances twice
+ bool object_moved = false;
+ Vec3d wipe_tower_origin = Vec3d::Zero();
+ for (int volume_idx : volume_idxs)
+ {
+ GLVolume* volume = m_volumes.volumes[volume_idx];
+ int obj_idx = volume->object_idx();
+ int instance_idx = volume->instance_idx();
+
+ // prevent moving instances twice
+ char done_id[64];
+ ::sprintf(done_id, "%d_%d", obj_idx, instance_idx);
+ if (done.find(done_id) != done.end())
+ continue;
+
+ done.insert(done_id);
+
+ if (obj_idx < 1000)
+ {
+ // Move a regular object.
+ ModelObject* model_object = m_model->objects[obj_idx];
+ if (model_object != nullptr)
+ {
+ const Vec3d& offset = volume->get_offset();
+ model_object->instances[instance_idx]->offset = Vec2d(offset(0), offset(1));
+ model_object->invalidate_bounding_box();
+ update_position_values();
+ object_moved = true;
+ }
+ }
+ else if (obj_idx == 1000)
+ // Move a wipe tower proxy.
+ wipe_tower_origin = volume->get_offset();
+ }
+
+ if (object_moved)
+ m_on_instance_moved_callback.call();
+
+ if (wipe_tower_origin != Vec3d::Zero())
+ m_on_wipe_tower_moved_callback.call(wipe_tower_origin(0), wipe_tower_origin(1));
+}
+
+void GLCanvas3D::_on_select(int volume_idx, int object_idx)
+{
+ int vol_id = -1;
+ int obj_id = -1;
+
+ if ((volume_idx != -1) && (volume_idx < (int)m_volumes.volumes.size()))
+ {
+ if (m_select_by == "volume")
+ {
+ if (m_volumes.volumes[volume_idx]->object_idx() != object_idx)
+ {
+ set_select_by("object");
+ obj_id = m_volumes.volumes[volume_idx]->object_idx();
+ vol_id = -1;
+ }
+ else
+ {
+ obj_id = object_idx;
+ vol_id = m_volumes.volumes[volume_idx]->volume_idx();
+ }
+ }
+ else if (m_select_by == "object")
+ {
+ obj_id = m_volumes.volumes[volume_idx]->object_idx();
+ vol_id = -1;
+ }
+ }
+
+ m_on_select_object_callback.call(obj_id, vol_id);
+}
+
+std::vector<float> GLCanvas3D::_parse_colors(const std::vector<std::string>& colors)
+{
+ static const float INV_255 = 1.0f / 255.0f;
+
+ std::vector<float> output(colors.size() * 4, 1.0f);
+ for (size_t i = 0; i < colors.size(); ++i)
+ {
+ const std::string& color = colors[i];
+ const char* c = color.data() + 1;
+ if ((color.size() == 7) && (color.front() == '#'))
+ {
+ for (size_t j = 0; j < 3; ++j)
+ {
+ int digit1 = hex_digit_to_int(*c++);
+ int digit2 = hex_digit_to_int(*c++);
+ if ((digit1 == -1) || (digit2 == -1))
+ break;
+
+ output[i * 4 + j] = float(digit1 * 16 + digit2) * INV_255;
+ }
+ }
+ }
+ return output;
+}
+
+void GLCanvas3D::_generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
+{
+ if (!set_current())
+ return;
+
+ m_legend_texture.generate(preview_data, tool_colors);
+}
+
+void GLCanvas3D::_generate_warning_texture(const std::string& msg)
+{
+ if (!set_current())
+ return;
+
+ m_warning_texture.generate(msg);
+}
+
+void GLCanvas3D::_reset_warning_texture()
+{
+ if (!set_current())
+ return;
+
+ m_warning_texture.reset();
+}
+
+bool GLCanvas3D::_is_any_volume_outside() const
+{
+ for (const GLVolume* volume : m_volumes.volumes)
+ {
+ if ((volume != nullptr) && volume->is_outside)
+ return true;
+ }
+
+ return false;
+}
+
+void GLCanvas3D::_resize_toolbar() const
+{
+ Size cnv_size = get_canvas_size();
+ float zoom = get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+
+ switch (m_toolbar.get_layout_type())
+ {
+ default:
+ case GLToolbar::Layout::Horizontal:
+ {
+ // centers the toolbar on the top edge of the 3d scene
+ unsigned int toolbar_width = m_toolbar.get_width();
+ float top = (0.5f * (float)cnv_size.get_height() - 2.0f) * inv_zoom;
+ float left = -0.5f * (float)toolbar_width * inv_zoom;
+ m_toolbar.set_position(top, left);
+ break;
+ }
+ case GLToolbar::Layout::Vertical:
+ {
+ // centers the toolbar on the right edge of the 3d scene
+ unsigned int toolbar_width = m_toolbar.get_width();
+ unsigned int toolbar_height = m_toolbar.get_height();
+ float top = 0.5f * (float)toolbar_height * inv_zoom;
+ float left = (0.5f * (float)cnv_size.get_width() - toolbar_width - 2.0f) * inv_zoom;
+ m_toolbar.set_position(top, left);
+ break;
+ }
+ }
+}
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp
new file mode 100644
index 000000000..a200e7fdb
--- /dev/null
+++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp
@@ -0,0 +1,766 @@
+#ifndef slic3r_GLCanvas3D_hpp_
+#define slic3r_GLCanvas3D_hpp_
+
+#include "../../slic3r/GUI/3DScene.hpp"
+#include "../../slic3r/GUI/GLToolbar.hpp"
+
+class wxTimer;
+class wxSizeEvent;
+class wxIdleEvent;
+class wxKeyEvent;
+class wxMouseEvent;
+class wxTimerEvent;
+class wxPaintEvent;
+
+namespace Slic3r {
+
+class GLShader;
+class ExPolygon;
+
+namespace GUI {
+
+class GLGizmoBase;
+
+class GeometryBuffer
+{
+ std::vector<float> m_vertices;
+ std::vector<float> m_tex_coords;
+
+public:
+ bool set_from_triangles(const Polygons& triangles, float z, bool generate_tex_coords);
+ bool set_from_lines(const Lines& lines, float z);
+
+ const float* get_vertices() const;
+ const float* get_tex_coords() const;
+
+ unsigned int get_vertices_count() const;
+};
+
+class Size
+{
+ int m_width;
+ int m_height;
+
+public:
+ Size();
+ Size(int width, int height);
+
+ int get_width() const;
+ void set_width(int width);
+
+ int get_height() const;
+ void set_height(int height);
+};
+
+class Rect
+{
+ float m_left;
+ float m_top;
+ float m_right;
+ float m_bottom;
+
+public:
+ Rect();
+ Rect(float left, float top, float right, float bottom);
+
+ float get_left() const;
+ void set_left(float left);
+
+ float get_top() const;
+ void set_top(float top);
+
+ float get_right() const;
+ void set_right(float right);
+
+ float get_bottom() const;
+ void set_bottom(float bottom);
+};
+
+class GLCanvas3D
+{
+ struct GCodePreviewVolumeIndex
+ {
+ enum EType
+ {
+ Extrusion,
+ Travel,
+ Retraction,
+ Unretraction,
+ Shell,
+ Num_Geometry_Types
+ };
+
+ struct FirstVolume
+ {
+ EType type;
+ unsigned int flag;
+ // Index of the first volume in a GLVolumeCollection.
+ unsigned int id;
+
+ FirstVolume(EType type, unsigned int flag, unsigned int id) : type(type), flag(flag), id(id) {}
+ };
+
+ std::vector<FirstVolume> first_volumes;
+
+ void reset() { first_volumes.clear(); }
+ };
+
+public:
+ struct Camera
+ {
+ enum EType : unsigned char
+ {
+ Unknown,
+// Perspective,
+ Ortho,
+ Num_types
+ };
+
+ EType type;
+ float zoom;
+ float phi;
+// float distance;
+ Vec3d target;
+
+ private:
+ float m_theta;
+
+ public:
+ Camera();
+
+ std::string get_type_as_string() const;
+
+ float get_theta() const;
+ void set_theta(float theta);
+ };
+
+ class Bed
+ {
+ public:
+ enum EType : unsigned char
+ {
+ MK2,
+ MK3,
+ Custom,
+ Num_Types
+ };
+
+ private:
+ EType m_type;
+ Pointfs m_shape;
+ BoundingBoxf3 m_bounding_box;
+ Polygon m_polygon;
+ GeometryBuffer m_triangles;
+ GeometryBuffer m_gridlines;
+ mutable GLTexture m_top_texture;
+ mutable GLTexture m_bottom_texture;
+
+ public:
+ Bed();
+
+ bool is_prusa() const;
+ bool is_custom() const;
+
+ const Pointfs& get_shape() const;
+ // Return true if the bed shape changed, so the calee will update the UI.
+ bool set_shape(const Pointfs& shape);
+
+ const BoundingBoxf3& get_bounding_box() const;
+ bool contains(const Point& point) const;
+ Point point_projection(const Point& point) const;
+
+ void render(float theta) const;
+
+ private:
+ void _calc_bounding_box();
+ void _calc_triangles(const ExPolygon& poly);
+ void _calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox);
+ EType _detect_type() const;
+ void _render_mk2(float theta) const;
+ void _render_mk3(float theta) const;
+ void _render_prusa(float theta) const;
+ void _render_custom() const;
+ static bool _are_equal(const Pointfs& bed_1, const Pointfs& bed_2);
+ };
+
+ struct Axes
+ {
+ Vec3d origin;
+ float length;
+
+ Axes();
+
+ void render(bool depth_test) const;
+ };
+
+ class CuttingPlane
+ {
+ float m_z;
+ GeometryBuffer m_lines;
+
+ public:
+ CuttingPlane();
+
+ bool set(float z, const ExPolygons& polygons);
+
+ void render(const BoundingBoxf3& bb) const;
+
+ private:
+ void _render_plane(const BoundingBoxf3& bb) const;
+ void _render_contour() const;
+ };
+
+ class Shader
+ {
+ GLShader* m_shader;
+
+ public:
+ Shader();
+ ~Shader();
+
+ bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename);
+
+ bool is_initialized() const;
+
+ bool start_using() const;
+ void stop_using() const;
+
+ void set_uniform(const std::string& name, float value) const;
+ void set_uniform(const std::string& name, const float* matrix) const;
+
+ const GLShader* get_shader() const;
+
+ private:
+ void _reset();
+ };
+
+ class LayersEditing
+ {
+ public:
+ enum EState : unsigned char
+ {
+ Unknown,
+ Editing,
+ Completed,
+ Num_States
+ };
+
+ private:
+ bool m_use_legacy_opengl;
+ bool m_enabled;
+ Shader m_shader;
+ unsigned int m_z_texture_id;
+ mutable GLTexture m_tooltip_texture;
+ mutable GLTexture m_reset_texture;
+
+ public:
+ EState state;
+ float band_width;
+ float strength;
+ int last_object_id;
+ float last_z;
+ unsigned int last_action;
+
+ LayersEditing();
+ ~LayersEditing();
+
+ bool init(const std::string& vertex_shader_filename, const std::string& fragment_shader_filename);
+
+ bool is_allowed() const;
+ void set_use_legacy_opengl(bool use_legacy_opengl);
+
+ bool is_enabled() const;
+ void set_enabled(bool enabled);
+
+ unsigned int get_z_texture_id() const;
+
+ void render(const GLCanvas3D& canvas, const PrintObject& print_object, const GLVolume& volume) const;
+
+ int get_shader_program_id() const;
+
+ static float get_cursor_z_relative(const GLCanvas3D& canvas);
+ static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y);
+ static bool reset_rect_contains(const GLCanvas3D& canvas, float x, float y);
+ static Rect get_bar_rect_screen(const GLCanvas3D& canvas);
+ static Rect get_reset_rect_screen(const GLCanvas3D& canvas);
+ static Rect get_bar_rect_viewport(const GLCanvas3D& canvas);
+ static Rect get_reset_rect_viewport(const GLCanvas3D& canvas);
+
+ private:
+ bool _is_initialized() const;
+ void _render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const;
+ void _render_reset_texture(const Rect& reset_rect) const;
+ void _render_active_object_annotations(const GLCanvas3D& canvas, const GLVolume& volume, const PrintObject& print_object, const Rect& bar_rect) const;
+ void _render_profile(const PrintObject& print_object, const Rect& bar_rect) const;
+ };
+
+ struct Mouse
+ {
+ struct Drag
+ {
+ static const Point Invalid_2D_Point;
+ static const Vec3d Invalid_3D_Point;
+
+ Point start_position_2D;
+ Vec3d start_position_3D;
+ Vec3d volume_center_offset;
+
+ bool move_with_shift;
+ int move_volume_idx;
+ int gizmo_volume_idx;
+
+ public:
+ Drag();
+ };
+
+ bool dragging;
+ Vec2d position;
+ Drag drag;
+
+ Mouse();
+
+ void set_start_position_2D_as_invalid();
+ void set_start_position_3D_as_invalid();
+
+ bool is_start_position_2D_defined() const;
+ bool is_start_position_3D_defined() const;
+ };
+
+ class Gizmos
+ {
+ static const float OverlayTexturesScale;
+ static const float OverlayOffsetX;
+ static const float OverlayGapY;
+
+ public:
+ enum EType : unsigned char
+ {
+ Undefined,
+ Move,
+ Scale,
+ Rotate,
+ Flatten,
+ Num_Types
+ };
+
+ private:
+ bool m_enabled;
+ typedef std::map<EType, GLGizmoBase*> GizmosMap;
+ GizmosMap m_gizmos;
+ EType m_current;
+
+ public:
+ Gizmos();
+ ~Gizmos();
+
+ bool init(GLCanvas3D& parent);
+
+ bool is_enabled() const;
+ void set_enabled(bool enable);
+
+ void update_hover_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos);
+ void update_on_off_state(const GLCanvas3D& canvas, const Vec2d& mouse_pos);
+ void reset_all_states();
+
+ void set_hover_id(int id);
+
+ bool overlay_contains_mouse(const GLCanvas3D& canvas, const Vec2d& mouse_pos) const;
+ bool grabber_contains_mouse() const;
+ void update(const Linef3& mouse_ray);
+
+ EType get_current_type() const;
+
+ bool is_running() const;
+
+ bool is_dragging() const;
+ void start_dragging(const BoundingBoxf3& box);
+ void stop_dragging();
+
+ Vec3d get_position() const;
+ void set_position(const Vec3d& position);
+
+ float get_scale() const;
+ void set_scale(float scale);
+
+ float get_angle_z() const;
+ void set_angle_z(float angle_z);
+
+ void set_flattening_data(const ModelObject* model_object);
+ Vec3d get_flattening_normal() const;
+
+ void render_current_gizmo(const BoundingBoxf3& box) const;
+
+ void render_current_gizmo_for_picking_pass(const BoundingBoxf3& box) const;
+ void render_overlay(const GLCanvas3D& canvas) const;
+
+ private:
+ void _reset();
+
+ void _render_overlay(const GLCanvas3D& canvas) const;
+ void _render_current_gizmo(const BoundingBoxf3& box) const;
+
+ float _get_total_overlay_height() const;
+ GLGizmoBase* _get_current() const;
+ };
+
+ class WarningTexture : public GUI::GLTexture
+ {
+ static const unsigned char Background_Color[3];
+ static const unsigned char Opacity;
+
+ int m_original_width;
+ int m_original_height;
+
+ public:
+ WarningTexture();
+
+ bool generate(const std::string& msg);
+
+ void render(const GLCanvas3D& canvas) const;
+ };
+
+ class LegendTexture : public GUI::GLTexture
+ {
+ static const int Px_Title_Offset = 5;
+ static const int Px_Text_Offset = 5;
+ static const int Px_Square = 20;
+ static const int Px_Square_Contour = 1;
+ static const int Px_Border = Px_Square / 2;
+ static const unsigned char Squares_Border_Color[3];
+ static const unsigned char Background_Color[3];
+ static const unsigned char Opacity;
+
+ int m_original_width;
+ int m_original_height;
+
+ public:
+ LegendTexture();
+
+ bool generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
+
+ void render(const GLCanvas3D& canvas) const;
+ };
+
+private:
+ wxGLCanvas* m_canvas;
+ wxGLContext* m_context;
+ LegendTexture m_legend_texture;
+ WarningTexture m_warning_texture;
+ wxTimer* m_timer;
+ Camera m_camera;
+ Bed m_bed;
+ Axes m_axes;
+ CuttingPlane m_cutting_plane;
+ LayersEditing m_layers_editing;
+ Shader m_shader;
+ Mouse m_mouse;
+ mutable Gizmos m_gizmos;
+ mutable GLToolbar m_toolbar;
+
+ mutable GLVolumeCollection m_volumes;
+ DynamicPrintConfig* m_config;
+ Print* m_print;
+ Model* m_model;
+
+ bool m_dirty;
+ bool m_initialized;
+ bool m_use_VBOs;
+ bool m_force_zoom_to_bed_enabled;
+ bool m_apply_zoom_to_volumes_filter;
+ mutable int m_hover_volume_id;
+ bool m_toolbar_action_running;
+ bool m_warning_texture_enabled;
+ bool m_legend_texture_enabled;
+ bool m_picking_enabled;
+ bool m_moving_enabled;
+ bool m_shader_enabled;
+ bool m_dynamic_background_enabled;
+ bool m_multisample_allowed;
+
+ std::string m_color_by;
+ std::string m_select_by;
+ std::string m_drag_by;
+
+ bool m_reload_delayed;
+ std::vector<std::vector<int>> m_objects_volumes_idxs;
+ std::vector<int> m_objects_selections;
+
+ GCodePreviewVolumeIndex m_gcode_preview_volume_index;
+
+ PerlCallback m_on_viewport_changed_callback;
+ PerlCallback m_on_double_click_callback;
+ PerlCallback m_on_right_click_callback;
+ PerlCallback m_on_select_object_callback;
+ PerlCallback m_on_model_update_callback;
+ PerlCallback m_on_remove_object_callback;
+ PerlCallback m_on_arrange_callback;
+ PerlCallback m_on_rotate_object_left_callback;
+ PerlCallback m_on_rotate_object_right_callback;
+ PerlCallback m_on_scale_object_uniformly_callback;
+ PerlCallback m_on_increase_objects_callback;
+ PerlCallback m_on_decrease_objects_callback;
+ PerlCallback m_on_instance_moved_callback;
+ PerlCallback m_on_wipe_tower_moved_callback;
+ PerlCallback m_on_enable_action_buttons_callback;
+ PerlCallback m_on_gizmo_scale_uniformly_callback;
+ PerlCallback m_on_gizmo_rotate_callback;
+ PerlCallback m_on_gizmo_flatten_callback;
+ PerlCallback m_on_update_geometry_info_callback;
+
+ PerlCallback m_action_add_callback;
+ PerlCallback m_action_delete_callback;
+ PerlCallback m_action_deleteall_callback;
+ PerlCallback m_action_arrange_callback;
+ PerlCallback m_action_more_callback;
+ PerlCallback m_action_fewer_callback;
+ PerlCallback m_action_split_callback;
+ PerlCallback m_action_cut_callback;
+ PerlCallback m_action_settings_callback;
+ PerlCallback m_action_layersediting_callback;
+ PerlCallback m_action_selectbyparts_callback;
+
+public:
+ GLCanvas3D(wxGLCanvas* canvas);
+ ~GLCanvas3D();
+
+ bool init(bool useVBOs, bool use_legacy_opengl);
+
+ bool set_current();
+
+ void set_as_dirty();
+
+ unsigned int get_volumes_count() const;
+ void reset_volumes();
+ void deselect_volumes();
+ void select_volume(unsigned int id);
+ void update_volumes_selection(const std::vector<int>& selections);
+ int check_volumes_outside_state(const DynamicPrintConfig* config) const;
+ bool move_volume_up(unsigned int id);
+ bool move_volume_down(unsigned int id);
+
+ void set_objects_selections(const std::vector<int>& selections);
+
+ void set_config(DynamicPrintConfig* config);
+ void set_print(Print* print);
+ void set_model(Model* model);
+
+ // Set the bed shape to a single closed 2D polygon(array of two element arrays),
+ // triangulate the bed and store the triangles into m_bed.m_triangles,
+ // fills the m_bed.m_grid_lines and sets m_bed.m_origin.
+ // Sets m_bed.m_polygon to limit the object placement.
+ void set_bed_shape(const Pointfs& shape);
+ // Used by ObjectCutDialog and ObjectPartsPanel to generate a rectangular ground plane to support the scene objects.
+ void set_auto_bed_shape();
+
+ void set_axes_length(float length);
+
+ void set_cutting_plane(float z, const ExPolygons& polygons);
+
+ void set_color_by(const std::string& value);
+ void set_select_by(const std::string& value);
+ void set_drag_by(const std::string& value);
+
+ const std::string& get_select_by() const;
+ const std::string& get_drag_by() const;
+
+ float get_camera_zoom() const;
+
+ BoundingBoxf3 volumes_bounding_box() const;
+
+ bool is_layers_editing_enabled() const;
+ bool is_layers_editing_allowed() const;
+ bool is_shader_enabled() const;
+
+ bool is_reload_delayed() const;
+
+ void enable_layers_editing(bool enable);
+ void enable_warning_texture(bool enable);
+ void enable_legend_texture(bool enable);
+ void enable_picking(bool enable);
+ void enable_moving(bool enable);
+ void enable_gizmos(bool enable);
+ void enable_toolbar(bool enable);
+ void enable_shader(bool enable);
+ void enable_force_zoom_to_bed(bool enable);
+ void enable_dynamic_background(bool enable);
+ void allow_multisample(bool allow);
+
+ void enable_toolbar_item(const std::string& name, bool enable);
+ bool is_toolbar_item_pressed(const std::string& name) const;
+
+ void zoom_to_bed();
+ void zoom_to_volumes();
+ void select_view(const std::string& direction);
+ void set_viewport_from_scene(const GLCanvas3D& other);
+
+ void update_volumes_colors_by_extruder();
+ void update_gizmos_data();
+
+ void render();
+
+ std::vector<double> get_current_print_zs(bool active_only) const;
+ void set_toolpaths_range(double low, double high);
+
+ std::vector<int> load_object(const ModelObject& model_object, int obj_idx, std::vector<int> instance_idxs);
+ std::vector<int> load_object(const Model& model, int obj_idx);
+
+ int get_first_volume_id(int obj_idx) const;
+
+ void reload_scene(bool force);
+
+ void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors);
+ void load_preview(const std::vector<std::string>& str_tool_colors);
+
+ void register_on_viewport_changed_callback(void* callback);
+ void register_on_double_click_callback(void* callback);
+ void register_on_right_click_callback(void* callback);
+ void register_on_select_object_callback(void* callback);
+ void register_on_model_update_callback(void* callback);
+ void register_on_remove_object_callback(void* callback);
+ void register_on_arrange_callback(void* callback);
+ void register_on_rotate_object_left_callback(void* callback);
+ void register_on_rotate_object_right_callback(void* callback);
+ void register_on_scale_object_uniformly_callback(void* callback);
+ void register_on_increase_objects_callback(void* callback);
+ void register_on_decrease_objects_callback(void* callback);
+ void register_on_instance_moved_callback(void* callback);
+ void register_on_wipe_tower_moved_callback(void* callback);
+ void register_on_enable_action_buttons_callback(void* callback);
+ void register_on_gizmo_scale_uniformly_callback(void* callback);
+ void register_on_gizmo_rotate_callback(void* callback);
+ void register_on_gizmo_flatten_callback(void* callback);
+ void register_on_update_geometry_info_callback(void* callback);
+
+ void register_action_add_callback(void* callback);
+ void register_action_delete_callback(void* callback);
+ void register_action_deleteall_callback(void* callback);
+ void register_action_arrange_callback(void* callback);
+ void register_action_more_callback(void* callback);
+ void register_action_fewer_callback(void* callback);
+ void register_action_split_callback(void* callback);
+ void register_action_cut_callback(void* callback);
+ void register_action_settings_callback(void* callback);
+ void register_action_layersediting_callback(void* callback);
+ void register_action_selectbyparts_callback(void* callback);
+
+ void bind_event_handlers();
+ void unbind_event_handlers();
+
+ void on_size(wxSizeEvent& evt);
+ void on_idle(wxIdleEvent& evt);
+ void on_char(wxKeyEvent& evt);
+ void on_mouse_wheel(wxMouseEvent& evt);
+ void on_timer(wxTimerEvent& evt);
+ void on_mouse(wxMouseEvent& evt);
+ void on_paint(wxPaintEvent& evt);
+ void on_key_down(wxKeyEvent& evt);
+
+ Size get_canvas_size() const;
+ Point get_local_mouse_position() const;
+
+ void reset_legend_texture();
+
+ void set_tooltip(const std::string& tooltip);
+
+private:
+ bool _is_shown_on_screen() const;
+ void _force_zoom_to_bed();
+
+ bool _init_toolbar();
+
+ void _resize(unsigned int w, unsigned int h);
+
+ BoundingBoxf3 _max_bounding_box() const;
+ BoundingBoxf3 _selected_volumes_bounding_box() const;
+
+ void _zoom_to_bounding_box(const BoundingBoxf3& bbox);
+ float _get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const;
+
+ void _deregister_callbacks();
+
+ void _mark_volumes_for_layer_height() const;
+ void _refresh_if_shown_on_screen();
+
+ void _camera_tranform() const;
+ void _picking_pass() const;
+ void _render_background() const;
+ void _render_bed(float theta) const;
+ void _render_axes(bool depth_test) const;
+ void _render_objects() const;
+ void _render_cutting_plane() const;
+ void _render_warning_texture() const;
+ void _render_legend_texture() const;
+ void _render_layer_editing_overlay() const;
+ void _render_volumes(bool fake_colors) const;
+ void _render_current_gizmo() const;
+ void _render_gizmos_overlay() const;
+ void _render_toolbar() const;
+
+ float _get_layers_editing_cursor_z_relative() const;
+ void _perform_layer_editing_action(wxMouseEvent* evt = nullptr);
+
+ // Convert the screen space coordinate to an object space coordinate.
+ // If the Z screen space coordinate is not provided, a depth buffer value is substituted.
+ Vec3d _mouse_to_3d(const Point& mouse_pos, float* z = nullptr);
+
+ // Convert the screen space coordinate to world coordinate on the bed.
+ Vec3d _mouse_to_bed_3d(const Point& mouse_pos);
+
+ // Returns the view ray line, in world coordinate, at the given mouse position.
+ Linef3 mouse_ray(const Point& mouse_pos);
+
+ void _start_timer();
+ void _stop_timer();
+
+ int _get_first_selected_object_id() const;
+ int _get_first_selected_volume_id(int object_id) const;
+
+ // Create 3D thick extrusion lines for a skirt and brim.
+ // Adds a new Slic3r::GUI::3DScene::Volume to volumes.
+ void _load_print_toolpaths();
+ // Create 3D thick extrusion lines for object forming extrusions.
+ // Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
+ // one for perimeters, one for infill and one for supports.
+ void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors);
+ // Create 3D thick extrusion lines for wipe tower extrusions
+ void _load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors);
+
+ // generates gcode extrusion paths geometry
+ void _load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
+ // generates gcode travel paths geometry
+ void _load_gcode_travel_paths(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
+ bool _travel_paths_by_type(const GCodePreviewData& preview_data);
+ bool _travel_paths_by_feedrate(const GCodePreviewData& preview_data);
+ bool _travel_paths_by_tool(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
+ // generates gcode retractions geometry
+ void _load_gcode_retractions(const GCodePreviewData& preview_data);
+ // generates gcode unretractions geometry
+ void _load_gcode_unretractions(const GCodePreviewData& preview_data);
+ // generates objects and wipe tower geometry
+ void _load_shells();
+ // sets gcode geometry visibility according to user selection
+ void _update_gcode_volumes_visibility(const GCodePreviewData& preview_data);
+ void _update_toolpath_volumes_outside_state();
+ void _show_warning_texture_if_needed();
+
+ void _on_move(const std::vector<int>& volume_idxs);
+ void _on_select(int volume_idx, int object_idx);
+
+ // generates the legend texture in dependence of the current shown view type
+ void _generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors);
+
+ // generates a warning texture containing the given message
+ void _generate_warning_texture(const std::string& msg);
+ void _reset_warning_texture();
+
+ bool _is_any_volume_outside() const;
+
+ void _resize_toolbar() const;
+
+ static std::vector<float> _parse_colors(const std::vector<std::string>& colors);
+};
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif // slic3r_GLCanvas3D_hpp_
diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp
new file mode 100644
index 000000000..3445d4b65
--- /dev/null
+++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp
@@ -0,0 +1,813 @@
+#include "GLCanvas3DManager.hpp"
+#include "../../slic3r/GUI/GUI.hpp"
+#include "../../slic3r/GUI/AppConfig.hpp"
+#include "../../slic3r/GUI/GLCanvas3D.hpp"
+
+#include <GL/glew.h>
+
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
+#include <wx/glcanvas.h>
+#include <wx/timer.h>
+
+#include <vector>
+#include <string>
+#include <iostream>
+
+namespace Slic3r {
+namespace GUI {
+
+GLCanvas3DManager::GLInfo::GLInfo()
+ : version("")
+ , glsl_version("")
+ , vendor("")
+ , renderer("")
+{
+}
+
+void GLCanvas3DManager::GLInfo::detect()
+{
+ const char* data = (const char*)::glGetString(GL_VERSION);
+ if (data != nullptr)
+ version = data;
+
+ data = (const char*)::glGetString(GL_SHADING_LANGUAGE_VERSION);
+ if (data != nullptr)
+ glsl_version = data;
+
+ data = (const char*)::glGetString(GL_VENDOR);
+ if (data != nullptr)
+ vendor = data;
+
+ data = (const char*)::glGetString(GL_RENDERER);
+ if (data != nullptr)
+ renderer = data;
+}
+
+bool GLCanvas3DManager::GLInfo::is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const
+{
+ std::vector<std::string> tokens;
+ boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on);
+
+ if (tokens.empty())
+ return false;
+
+ std::vector<std::string> numbers;
+ boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on);
+
+ unsigned int gl_major = 0;
+ unsigned int gl_minor = 0;
+
+ if (numbers.size() > 0)
+ gl_major = ::atoi(numbers[0].c_str());
+
+ if (numbers.size() > 1)
+ gl_minor = ::atoi(numbers[1].c_str());
+
+ if (gl_major < major)
+ return false;
+ else if (gl_major > major)
+ return true;
+ else
+ return gl_minor >= minor;
+}
+
+std::string GLCanvas3DManager::GLInfo::to_string(bool format_as_html, bool extensions) const
+{
+ std::stringstream out;
+
+ std::string h2_start = format_as_html ? "<b>" : "";
+ std::string h2_end = format_as_html ? "</b>" : "";
+ std::string b_start = format_as_html ? "<b>" : "";
+ std::string b_end = format_as_html ? "</b>" : "";
+ std::string line_end = format_as_html ? "<br>" : "\n";
+
+ out << h2_start << "OpenGL installation" << h2_end << line_end;
+ out << b_start << "GL version: " << b_end << (version.empty() ? "N/A" : version) << line_end;
+ out << b_start << "Vendor: " << b_end << (vendor.empty() ? "N/A" : vendor) << line_end;
+ out << b_start << "Renderer: " << b_end << (renderer.empty() ? "N/A" : renderer) << line_end;
+ out << b_start << "GLSL version: " << b_end << (glsl_version.empty() ? "N/A" : glsl_version) << line_end;
+
+ if (extensions)
+ {
+ std::vector<std::string> extensions_list;
+ std::string extensions_str = (const char*)::glGetString(GL_EXTENSIONS);
+ boost::split(extensions_list, extensions_str, boost::is_any_of(" "), boost::token_compress_off);
+
+ if (!extensions_list.empty())
+ {
+ out << h2_start << "Installed extensions:" << h2_end << line_end;
+
+ std::sort(extensions_list.begin(), extensions_list.end());
+ for (const std::string& ext : extensions_list)
+ {
+ out << ext << line_end;
+ }
+ }
+ }
+
+ return out.str();
+}
+
+GLCanvas3DManager::GLCanvas3DManager()
+ : m_current(nullptr)
+ , m_gl_initialized(false)
+ , m_use_legacy_opengl(false)
+ , m_use_VBOs(false)
+{
+}
+
+bool GLCanvas3DManager::add(wxGLCanvas* canvas)
+{
+ if (canvas == nullptr)
+ return false;
+
+ if (_get_canvas(canvas) != m_canvases.end())
+ return false;
+
+ GLCanvas3D* canvas3D = new GLCanvas3D(canvas);
+ if (canvas3D == nullptr)
+ return false;
+
+ canvas3D->bind_event_handlers();
+ m_canvases.insert(CanvasesMap::value_type(canvas, canvas3D));
+
+ return true;
+}
+
+bool GLCanvas3DManager::remove(wxGLCanvas* canvas)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it == m_canvases.end())
+ return false;
+
+ it->second->unbind_event_handlers();
+ delete it->second;
+ m_canvases.erase(it);
+
+ return true;
+}
+
+void GLCanvas3DManager::remove_all()
+{
+ for (CanvasesMap::value_type& item : m_canvases)
+ {
+ item.second->unbind_event_handlers();
+ delete item.second;
+ }
+ m_canvases.clear();
+}
+
+unsigned int GLCanvas3DManager::count() const
+{
+ return (unsigned int)m_canvases.size();
+}
+
+void GLCanvas3DManager::init_gl()
+{
+ if (!m_gl_initialized)
+ {
+ glewInit();
+ m_gl_info.detect();
+ const AppConfig* config = GUI::get_app_config();
+ m_use_legacy_opengl = (config == nullptr) || (config->get("use_legacy_opengl") == "1");
+ m_use_VBOs = !m_use_legacy_opengl && m_gl_info.is_version_greater_or_equal_to(2, 0);
+ m_gl_initialized = true;
+ }
+}
+
+std::string GLCanvas3DManager::get_gl_info(bool format_as_html, bool extensions) const
+{
+ return m_gl_info.to_string(format_as_html, extensions);
+}
+
+bool GLCanvas3DManager::use_VBOs() const
+{
+ return m_use_VBOs;
+}
+
+bool GLCanvas3DManager::init(wxGLCanvas* canvas)
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ return (it->second != nullptr) ? _init(*it->second) : false;
+ else
+ return false;
+}
+
+void GLCanvas3DManager::set_as_dirty(wxGLCanvas* canvas)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_as_dirty();
+}
+
+unsigned int GLCanvas3DManager::get_volumes_count(wxGLCanvas* canvas) const
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->get_volumes_count() : 0;
+}
+
+void GLCanvas3DManager::reset_volumes(wxGLCanvas* canvas)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->reset_volumes();
+}
+
+void GLCanvas3DManager::deselect_volumes(wxGLCanvas* canvas)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->deselect_volumes();
+}
+
+void GLCanvas3DManager::select_volume(wxGLCanvas* canvas, unsigned int id)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->select_volume(id);
+}
+
+void GLCanvas3DManager::update_volumes_selection(wxGLCanvas* canvas, const std::vector<int>& selections)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->update_volumes_selection(selections);
+}
+
+int GLCanvas3DManager::check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->check_volumes_outside_state(config) : false;
+}
+
+bool GLCanvas3DManager::move_volume_up(wxGLCanvas* canvas, unsigned int id)
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->move_volume_up(id) : false;
+}
+
+bool GLCanvas3DManager::move_volume_down(wxGLCanvas* canvas, unsigned int id)
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->move_volume_down(id) : false;
+}
+
+void GLCanvas3DManager::set_objects_selections(wxGLCanvas* canvas, const std::vector<int>& selections)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_objects_selections(selections);
+}
+
+void GLCanvas3DManager::set_config(wxGLCanvas* canvas, DynamicPrintConfig* config)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_config(config);
+}
+
+void GLCanvas3DManager::set_print(wxGLCanvas* canvas, Print* print)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_print(print);
+}
+
+void GLCanvas3DManager::set_model(wxGLCanvas* canvas, Model* model)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_model(model);
+}
+
+void GLCanvas3DManager::set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_bed_shape(shape);
+}
+
+void GLCanvas3DManager::set_auto_bed_shape(wxGLCanvas* canvas)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_auto_bed_shape();
+}
+
+BoundingBoxf3 GLCanvas3DManager::get_volumes_bounding_box(wxGLCanvas* canvas)
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->volumes_bounding_box() : BoundingBoxf3();
+}
+
+void GLCanvas3DManager::set_axes_length(wxGLCanvas* canvas, float length)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_axes_length(length);
+}
+
+void GLCanvas3DManager::set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_cutting_plane(z, polygons);
+}
+
+void GLCanvas3DManager::set_color_by(wxGLCanvas* canvas, const std::string& value)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_color_by(value);
+}
+
+void GLCanvas3DManager::set_select_by(wxGLCanvas* canvas, const std::string& value)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_select_by(value);
+}
+
+void GLCanvas3DManager::set_drag_by(wxGLCanvas* canvas, const std::string& value)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_drag_by(value);
+}
+
+std::string GLCanvas3DManager::get_select_by(wxGLCanvas* canvas) const
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->get_select_by() : "";
+}
+
+bool GLCanvas3DManager::is_layers_editing_enabled(wxGLCanvas* canvas) const
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->is_layers_editing_enabled() : false;
+}
+
+bool GLCanvas3DManager::is_layers_editing_allowed(wxGLCanvas* canvas) const
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->is_layers_editing_allowed() : false;
+}
+
+bool GLCanvas3DManager::is_shader_enabled(wxGLCanvas* canvas) const
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->is_shader_enabled() : false;
+}
+
+bool GLCanvas3DManager::is_reload_delayed(wxGLCanvas* canvas) const
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->is_reload_delayed() : false;
+}
+
+void GLCanvas3DManager::enable_layers_editing(wxGLCanvas* canvas, bool enable)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->enable_layers_editing(enable);
+}
+
+void GLCanvas3DManager::enable_warning_texture(wxGLCanvas* canvas, bool enable)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->enable_warning_texture(enable);
+}
+
+void GLCanvas3DManager::enable_legend_texture(wxGLCanvas* canvas, bool enable)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->enable_legend_texture(enable);
+}
+
+void GLCanvas3DManager::enable_picking(wxGLCanvas* canvas, bool enable)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->enable_picking(enable);
+}
+
+void GLCanvas3DManager::enable_moving(wxGLCanvas* canvas, bool enable)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->enable_moving(enable);
+}
+
+void GLCanvas3DManager::enable_gizmos(wxGLCanvas* canvas, bool enable)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->enable_gizmos(enable);
+}
+
+void GLCanvas3DManager::enable_toolbar(wxGLCanvas* canvas, bool enable)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->enable_toolbar(enable);
+}
+
+void GLCanvas3DManager::enable_shader(wxGLCanvas* canvas, bool enable)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->enable_shader(enable);
+}
+
+void GLCanvas3DManager::enable_force_zoom_to_bed(wxGLCanvas* canvas, bool enable)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->enable_force_zoom_to_bed(enable);
+}
+
+void GLCanvas3DManager::enable_dynamic_background(wxGLCanvas* canvas, bool enable)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->enable_dynamic_background(enable);
+}
+
+void GLCanvas3DManager::allow_multisample(wxGLCanvas* canvas, bool allow)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->allow_multisample(allow);
+}
+
+void GLCanvas3DManager::enable_toolbar_item(wxGLCanvas* canvas, const std::string& name, bool enable)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->enable_toolbar_item(name, enable);
+}
+
+bool GLCanvas3DManager::is_toolbar_item_pressed(wxGLCanvas* canvas, const std::string& name) const
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->is_toolbar_item_pressed(name) : false;
+}
+
+void GLCanvas3DManager::zoom_to_bed(wxGLCanvas* canvas)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->zoom_to_bed();
+}
+
+void GLCanvas3DManager::zoom_to_volumes(wxGLCanvas* canvas)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->zoom_to_volumes();
+}
+
+void GLCanvas3DManager::select_view(wxGLCanvas* canvas, const std::string& direction)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->select_view(direction);
+}
+
+void GLCanvas3DManager::set_viewport_from_scene(wxGLCanvas* canvas, wxGLCanvas* other)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ {
+ CanvasesMap::iterator other_it = _get_canvas(other);
+ if (other_it != m_canvases.end())
+ it->second->set_viewport_from_scene(*other_it->second);
+ }
+}
+
+void GLCanvas3DManager::update_volumes_colors_by_extruder(wxGLCanvas* canvas)
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->update_volumes_colors_by_extruder();
+}
+
+void GLCanvas3DManager::update_gizmos_data(wxGLCanvas* canvas)
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->update_gizmos_data();
+}
+
+void GLCanvas3DManager::render(wxGLCanvas* canvas) const
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->render();
+}
+
+std::vector<double> GLCanvas3DManager::get_current_print_zs(wxGLCanvas* canvas, bool active_only) const
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->get_current_print_zs(active_only) : std::vector<double>();
+}
+
+void GLCanvas3DManager::set_toolpaths_range(wxGLCanvas* canvas, double low, double high)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->set_toolpaths_range(low, high);
+}
+
+std::vector<int> GLCanvas3DManager::load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector<int> instance_idxs)
+{
+ if (model_object == nullptr)
+ return std::vector<int>();
+
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->load_object(*model_object, obj_idx, instance_idxs) : std::vector<int>();
+}
+
+std::vector<int> GLCanvas3DManager::load_object(wxGLCanvas* canvas, const Model* model, int obj_idx)
+{
+ if (model == nullptr)
+ return std::vector<int>();
+
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->load_object(*model, obj_idx) : std::vector<int>();
+}
+
+int GLCanvas3DManager::get_first_volume_id(wxGLCanvas* canvas, int obj_idx) const
+{
+ CanvasesMap::const_iterator it = _get_canvas(canvas);
+ return (it != m_canvases.end()) ? it->second->get_first_volume_id(obj_idx) : -1;
+}
+
+void GLCanvas3DManager::reload_scene(wxGLCanvas* canvas, bool force)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->reload_scene(force);
+}
+
+void GLCanvas3DManager::load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors)
+{
+ if (preview_data == nullptr)
+ return;
+
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->load_gcode_preview(*preview_data, str_tool_colors);
+}
+
+void GLCanvas3DManager::load_preview(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->load_preview(str_tool_colors);
+}
+
+void GLCanvas3DManager::reset_legend_texture()
+{
+ for (CanvasesMap::value_type& canvas : m_canvases)
+ {
+ if (canvas.second != nullptr)
+ canvas.second->reset_legend_texture();
+ }
+}
+
+void GLCanvas3DManager::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_viewport_changed_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_double_click_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_double_click_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_right_click_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_right_click_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_select_object_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_select_object_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_model_update_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_model_update_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_remove_object_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_remove_object_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_arrange_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_arrange_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_rotate_object_left_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_rotate_object_left_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_rotate_object_right_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_rotate_object_right_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_scale_object_uniformly_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_scale_object_uniformly_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_increase_objects_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_increase_objects_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_decrease_objects_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_decrease_objects_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_instance_moved_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_instance_moved_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_wipe_tower_moved_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_wipe_tower_moved_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_enable_action_buttons_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_gizmo_scale_uniformly_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_gizmo_rotate_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_gizmo_flatten_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_gizmo_flatten_callback(callback);
+}
+
+void GLCanvas3DManager::register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_on_update_geometry_info_callback(callback);
+}
+
+void GLCanvas3DManager::register_action_add_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_action_add_callback(callback);
+}
+
+void GLCanvas3DManager::register_action_delete_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_action_delete_callback(callback);
+}
+
+void GLCanvas3DManager::register_action_deleteall_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_action_deleteall_callback(callback);
+}
+
+void GLCanvas3DManager::register_action_arrange_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_action_arrange_callback(callback);
+}
+
+void GLCanvas3DManager::register_action_more_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_action_more_callback(callback);
+}
+
+void GLCanvas3DManager::register_action_fewer_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_action_fewer_callback(callback);
+}
+
+void GLCanvas3DManager::register_action_split_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_action_split_callback(callback);
+}
+
+void GLCanvas3DManager::register_action_cut_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_action_cut_callback(callback);
+}
+
+void GLCanvas3DManager::register_action_settings_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_action_settings_callback(callback);
+}
+
+void GLCanvas3DManager::register_action_layersediting_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_action_layersediting_callback(callback);
+}
+
+void GLCanvas3DManager::register_action_selectbyparts_callback(wxGLCanvas* canvas, void* callback)
+{
+ CanvasesMap::iterator it = _get_canvas(canvas);
+ if (it != m_canvases.end())
+ it->second->register_action_selectbyparts_callback(callback);
+}
+
+GLCanvas3DManager::CanvasesMap::iterator GLCanvas3DManager::_get_canvas(wxGLCanvas* canvas)
+{
+ return (canvas == nullptr) ? m_canvases.end() : m_canvases.find(canvas);
+}
+
+GLCanvas3DManager::CanvasesMap::const_iterator GLCanvas3DManager::_get_canvas(wxGLCanvas* canvas) const
+{
+ return (canvas == nullptr) ? m_canvases.end() : m_canvases.find(canvas);
+}
+
+bool GLCanvas3DManager::_init(GLCanvas3D& canvas)
+{
+ if (!m_gl_initialized)
+ init_gl();
+
+ return canvas.init(m_use_VBOs, m_use_legacy_opengl);
+}
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp
new file mode 100644
index 000000000..b808c022e
--- /dev/null
+++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp
@@ -0,0 +1,191 @@
+#ifndef slic3r_GLCanvas3DManager_hpp_
+#define slic3r_GLCanvas3DManager_hpp_
+
+#include "../../libslic3r/BoundingBox.hpp"
+
+#include <map>
+#include <vector>
+
+class wxGLCanvas;
+class wxGLContext;
+
+namespace Slic3r {
+
+class DynamicPrintConfig;
+class Print;
+class Model;
+class ExPolygon;
+typedef std::vector<ExPolygon> ExPolygons;
+class ModelObject;
+class PrintObject;
+class GCodePreviewData;
+
+namespace GUI {
+
+class GLCanvas3D;
+
+class GLCanvas3DManager
+{
+ struct GLInfo
+ {
+ std::string version;
+ std::string glsl_version;
+ std::string vendor;
+ std::string renderer;
+
+ GLInfo();
+
+ void detect();
+ bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const;
+
+ std::string to_string(bool format_as_html, bool extensions) const;
+ };
+
+ typedef std::map<wxGLCanvas*, GLCanvas3D*> CanvasesMap;
+
+ CanvasesMap m_canvases;
+ wxGLCanvas* m_current;
+ GLInfo m_gl_info;
+ bool m_gl_initialized;
+ bool m_use_legacy_opengl;
+ bool m_use_VBOs;
+
+public:
+ GLCanvas3DManager();
+
+ bool add(wxGLCanvas* canvas);
+ bool remove(wxGLCanvas* canvas);
+
+ void remove_all();
+
+ unsigned int count() const;
+
+ void init_gl();
+ std::string get_gl_info(bool format_as_html, bool extensions) const;
+
+ bool use_VBOs() const;
+ bool layer_editing_allowed() const;
+
+ bool init(wxGLCanvas* canvas);
+
+ void set_as_dirty(wxGLCanvas* canvas);
+
+ unsigned int get_volumes_count(wxGLCanvas* canvas) const;
+ void reset_volumes(wxGLCanvas* canvas);
+ void deselect_volumes(wxGLCanvas* canvas);
+ void select_volume(wxGLCanvas* canvas, unsigned int id);
+ void update_volumes_selection(wxGLCanvas* canvas, const std::vector<int>& selections);
+ int check_volumes_outside_state(wxGLCanvas* canvas, const DynamicPrintConfig* config) const;
+ bool move_volume_up(wxGLCanvas* canvas, unsigned int id);
+ bool move_volume_down(wxGLCanvas* canvas, unsigned int id);
+
+ void set_objects_selections(wxGLCanvas* canvas, const std::vector<int>& selections);
+
+ void set_config(wxGLCanvas* canvas, DynamicPrintConfig* config);
+ void set_print(wxGLCanvas* canvas, Print* print);
+ void set_model(wxGLCanvas* canvas, Model* model);
+
+ void set_bed_shape(wxGLCanvas* canvas, const Pointfs& shape);
+ void set_auto_bed_shape(wxGLCanvas* canvas);
+
+ BoundingBoxf3 get_volumes_bounding_box(wxGLCanvas* canvas);
+
+ void set_axes_length(wxGLCanvas* canvas, float length);
+
+ void set_cutting_plane(wxGLCanvas* canvas, float z, const ExPolygons& polygons);
+
+ void set_color_by(wxGLCanvas* canvas, const std::string& value);
+ void set_select_by(wxGLCanvas* canvas, const std::string& value);
+ void set_drag_by(wxGLCanvas* canvas, const std::string& value);
+
+ std::string get_select_by(wxGLCanvas* canvas) const;
+
+ bool is_layers_editing_enabled(wxGLCanvas* canvas) const;
+ bool is_layers_editing_allowed(wxGLCanvas* canvas) const;
+ bool is_shader_enabled(wxGLCanvas* canvas) const;
+
+ bool is_reload_delayed(wxGLCanvas* canvas) const;
+
+ void enable_layers_editing(wxGLCanvas* canvas, bool enable);
+ void enable_warning_texture(wxGLCanvas* canvas, bool enable);
+ void enable_legend_texture(wxGLCanvas* canvas, bool enable);
+ void enable_picking(wxGLCanvas* canvas, bool enable);
+ void enable_moving(wxGLCanvas* canvas, bool enable);
+ void enable_gizmos(wxGLCanvas* canvas, bool enable);
+ void enable_toolbar(wxGLCanvas* canvas, bool enable);
+ void enable_shader(wxGLCanvas* canvas, bool enable);
+ void enable_force_zoom_to_bed(wxGLCanvas* canvas, bool enable);
+ void enable_dynamic_background(wxGLCanvas* canvas, bool enable);
+ void allow_multisample(wxGLCanvas* canvas, bool allow);
+
+ void enable_toolbar_item(wxGLCanvas* canvas, const std::string& name, bool enable);
+ bool is_toolbar_item_pressed(wxGLCanvas* canvas, const std::string& name) const;
+
+ void zoom_to_bed(wxGLCanvas* canvas);
+ void zoom_to_volumes(wxGLCanvas* canvas);
+ void select_view(wxGLCanvas* canvas, const std::string& direction);
+ void set_viewport_from_scene(wxGLCanvas* canvas, wxGLCanvas* other);
+
+ void update_volumes_colors_by_extruder(wxGLCanvas* canvas);
+ void update_gizmos_data(wxGLCanvas* canvas);
+
+ void render(wxGLCanvas* canvas) const;
+
+ std::vector<double> get_current_print_zs(wxGLCanvas* canvas, bool active_only) const;
+ void set_toolpaths_range(wxGLCanvas* canvas, double low, double high);
+
+ std::vector<int> load_object(wxGLCanvas* canvas, const ModelObject* model_object, int obj_idx, std::vector<int> instance_idxs);
+ std::vector<int> load_object(wxGLCanvas* canvas, const Model* model, int obj_idx);
+
+ int get_first_volume_id(wxGLCanvas* canvas, int obj_idx) const;
+
+ void reload_scene(wxGLCanvas* canvas, bool force);
+
+ void load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector<std::string>& str_tool_colors);
+ void load_preview(wxGLCanvas* canvas, const std::vector<std::string>& str_tool_colors);
+
+ void reset_legend_texture();
+
+ void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_double_click_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_right_click_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_select_object_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_model_update_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_remove_object_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_arrange_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_rotate_object_left_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_rotate_object_right_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_scale_object_uniformly_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_increase_objects_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_decrease_objects_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_instance_moved_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_wipe_tower_moved_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_enable_action_buttons_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_gizmo_scale_uniformly_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_gizmo_rotate_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_gizmo_flatten_callback(wxGLCanvas* canvas, void* callback);
+ void register_on_update_geometry_info_callback(wxGLCanvas* canvas, void* callback);
+
+ void register_action_add_callback(wxGLCanvas* canvas, void* callback);
+ void register_action_delete_callback(wxGLCanvas* canvas, void* callback);
+ void register_action_deleteall_callback(wxGLCanvas* canvas, void* callback);
+ void register_action_arrange_callback(wxGLCanvas* canvas, void* callback);
+ void register_action_more_callback(wxGLCanvas* canvas, void* callback);
+ void register_action_fewer_callback(wxGLCanvas* canvas, void* callback);
+ void register_action_split_callback(wxGLCanvas* canvas, void* callback);
+ void register_action_cut_callback(wxGLCanvas* canvas, void* callback);
+ void register_action_settings_callback(wxGLCanvas* canvas, void* callback);
+ void register_action_layersediting_callback(wxGLCanvas* canvas, void* callback);
+ void register_action_selectbyparts_callback(wxGLCanvas* canvas, void* callback);
+
+private:
+ CanvasesMap::iterator _get_canvas(wxGLCanvas* canvas);
+ CanvasesMap::const_iterator _get_canvas(wxGLCanvas* canvas) const;
+
+ bool _init(GLCanvas3D& canvas);
+};
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif // slic3r_GLCanvas3DManager_hpp_
diff --git a/xs/src/slic3r/GUI/GLGizmo.cpp b/xs/src/slic3r/GUI/GLGizmo.cpp
new file mode 100644
index 000000000..4aa5ab32f
--- /dev/null
+++ b/xs/src/slic3r/GUI/GLGizmo.cpp
@@ -0,0 +1,1476 @@
+#include "GLGizmo.hpp"
+
+#include "../../libslic3r/Utils.hpp"
+#include "../../slic3r/GUI/GLCanvas3D.hpp"
+
+#include <Eigen/Dense>
+#include "../../libslic3r/Geometry.hpp"
+
+#include <GL/glew.h>
+
+#include <iostream>
+#include <numeric>
+
+static const float DEFAULT_BASE_COLOR[3] = { 0.625f, 0.625f, 0.625f };
+static const float DEFAULT_DRAG_COLOR[3] = { 1.0f, 1.0f, 1.0f };
+static const float DEFAULT_HIGHLIGHT_COLOR[3] = { 1.0f, 0.38f, 0.0f };
+
+static const float AXES_COLOR[3][3] = { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
+
+namespace Slic3r {
+namespace GUI {
+
+ // returns the intersection of the given ray with the plane parallel to plane XY and passing through the given center
+ // coordinates are local to the plane
+ Vec3d intersection_on_plane_xy(const Linef3& ray, const Vec3d& center)
+ {
+ Transform3d m = Transform3d::Identity();
+ m.translate(-center);
+ Vec2d mouse_pos_2d = to_2d(transform(ray, m).intersect_plane(0.0));
+ return Vec3d(mouse_pos_2d(0), mouse_pos_2d(1), 0.0);
+ }
+
+ // returns the intersection of the given ray with the plane parallel to plane XZ and passing through the given center
+ // coordinates are local to the plane
+ Vec3d intersection_on_plane_xz(const Linef3& ray, const Vec3d& center)
+ {
+ Transform3d m = Transform3d::Identity();
+ m.rotate(Eigen::AngleAxisd(-0.5 * (double)PI, Vec3d::UnitX()));
+ m.translate(-center);
+ Vec2d mouse_pos_2d = to_2d(transform(ray, m).intersect_plane(0.0));
+ return Vec3d(mouse_pos_2d(0), 0.0, mouse_pos_2d(1));
+ }
+
+ // returns the intersection of the given ray with the plane parallel to plane YZ and passing through the given center
+ // coordinates are local to the plane
+ Vec3d intersection_on_plane_yz(const Linef3& ray, const Vec3d& center)
+ {
+ Transform3d m = Transform3d::Identity();
+ m.rotate(Eigen::AngleAxisd(-0.5f * (double)PI, Vec3d::UnitY()));
+ m.translate(-center);
+ Vec2d mouse_pos_2d = to_2d(transform(ray, m).intersect_plane(0.0));
+
+ return Vec3d(0.0, mouse_pos_2d(1), -mouse_pos_2d(0));
+ }
+
+ // return an index:
+ // 0 for plane XY
+ // 1 for plane XZ
+ // 2 for plane YZ
+ // which indicates which plane is best suited for intersecting the given unit vector
+ // giving precedence to the plane with the given index
+ unsigned int select_best_plane(const Vec3d& unit_vector, unsigned int preferred_plane)
+ {
+ unsigned int ret = preferred_plane;
+
+ // 1st checks if the given vector is not parallel to the given preferred plane
+ double dot_to_normal = 0.0;
+ switch (ret)
+ {
+ case 0: // plane xy
+ {
+ dot_to_normal = std::abs(unit_vector.dot(Vec3d::UnitZ()));
+ break;
+ }
+ case 1: // plane xz
+ {
+ dot_to_normal = std::abs(unit_vector.dot(-Vec3d::UnitY()));
+ break;
+ }
+ case 2: // plane yz
+ {
+ dot_to_normal = std::abs(unit_vector.dot(Vec3d::UnitX()));
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ // if almost parallel, select the plane whose normal direction is closest to the given vector direction,
+ // otherwise return the given preferred plane index
+ if (dot_to_normal < 0.1)
+ {
+ typedef std::map<double, unsigned int> ProjsMap;
+ ProjsMap projs_map;
+ projs_map.insert(ProjsMap::value_type(std::abs(unit_vector.dot(Vec3d::UnitZ())), 0)); // plane xy
+ projs_map.insert(ProjsMap::value_type(std::abs(unit_vector.dot(-Vec3d::UnitY())), 1)); // plane xz
+ projs_map.insert(ProjsMap::value_type(std::abs(unit_vector.dot(Vec3d::UnitX())), 2)); // plane yz
+ ret = projs_map.rbegin()->second;
+ }
+
+ return ret;
+ }
+
+ const float GLGizmoBase::Grabber::HalfSize = 2.0f;
+const float GLGizmoBase::Grabber::DraggingScaleFactor = 1.25f;
+
+GLGizmoBase::Grabber::Grabber()
+ : center(Vec3d::Zero())
+ , angles(Vec3d::Zero())
+ , dragging(false)
+ , enabled(true)
+{
+ color[0] = 1.0f;
+ color[1] = 1.0f;
+ color[2] = 1.0f;
+}
+
+void GLGizmoBase::Grabber::render(bool hover) const
+{
+ float render_color[3];
+ if (hover)
+ {
+ render_color[0] = 1.0f - color[0];
+ render_color[1] = 1.0f - color[1];
+ render_color[2] = 1.0f - color[2];
+ }
+ else
+ ::memcpy((void*)render_color, (const void*)color, 3 * sizeof(float));
+
+ render(render_color, true);
+}
+
+void GLGizmoBase::Grabber::render(const float* render_color, bool use_lighting) const
+{
+ float half_size = dragging ? HalfSize * DraggingScaleFactor : HalfSize;
+ if (use_lighting)
+ ::glEnable(GL_LIGHTING);
+
+ ::glColor3f((GLfloat)render_color[0], (GLfloat)render_color[1], (GLfloat)render_color[2]);
+
+ ::glPushMatrix();
+ ::glTranslatef((GLfloat)center(0), (GLfloat)center(1), (GLfloat)center(2));
+
+ float rad_to_deg = 180.0f / (GLfloat)PI;
+ ::glRotatef((GLfloat)angles(0) * rad_to_deg, 1.0f, 0.0f, 0.0f);
+ ::glRotatef((GLfloat)angles(1) * rad_to_deg, 0.0f, 1.0f, 0.0f);
+ ::glRotatef((GLfloat)angles(2) * rad_to_deg, 0.0f, 0.0f, 1.0f);
+
+ // face min x
+ ::glPushMatrix();
+ ::glTranslatef(-(GLfloat)half_size, 0.0f, 0.0f);
+ ::glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);
+ render_face(half_size);
+ ::glPopMatrix();
+
+ // face max x
+ ::glPushMatrix();
+ ::glTranslatef((GLfloat)half_size, 0.0f, 0.0f);
+ ::glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
+ render_face(half_size);
+ ::glPopMatrix();
+
+ // face min y
+ ::glPushMatrix();
+ ::glTranslatef(0.0f, -(GLfloat)half_size, 0.0f);
+ ::glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
+ render_face(half_size);
+ ::glPopMatrix();
+
+ // face max y
+ ::glPushMatrix();
+ ::glTranslatef(0.0f, (GLfloat)half_size, 0.0f);
+ ::glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
+ render_face(half_size);
+ ::glPopMatrix();
+
+ // face min z
+ ::glPushMatrix();
+ ::glTranslatef(0.0f, 0.0f, -(GLfloat)half_size);
+ ::glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
+ render_face(half_size);
+ ::glPopMatrix();
+
+ // face max z
+ ::glPushMatrix();
+ ::glTranslatef(0.0f, 0.0f, (GLfloat)half_size);
+ render_face(half_size);
+ ::glPopMatrix();
+
+ ::glPopMatrix();
+
+ if (use_lighting)
+ ::glDisable(GL_LIGHTING);
+}
+
+void GLGizmoBase::Grabber::render_face(float half_size) const
+{
+ ::glBegin(GL_TRIANGLES);
+ ::glNormal3f(0.0f, 0.0f, 1.0f);
+ ::glVertex3f(-(GLfloat)half_size, -(GLfloat)half_size, 0.0f);
+ ::glVertex3f((GLfloat)half_size, -(GLfloat)half_size, 0.0f);
+ ::glVertex3f((GLfloat)half_size, (GLfloat)half_size, 0.0f);
+ ::glVertex3f((GLfloat)half_size, (GLfloat)half_size, 0.0f);
+ ::glVertex3f(-(GLfloat)half_size, (GLfloat)half_size, 0.0f);
+ ::glVertex3f(-(GLfloat)half_size, -(GLfloat)half_size, 0.0f);
+ ::glEnd();
+}
+
+GLGizmoBase::GLGizmoBase(GLCanvas3D& parent)
+ : m_parent(parent)
+ , m_group_id(-1)
+ , m_state(Off)
+ , m_hover_id(-1)
+ , m_dragging(false)
+{
+ ::memcpy((void*)m_base_color, (const void*)DEFAULT_BASE_COLOR, 3 * sizeof(float));
+ ::memcpy((void*)m_drag_color, (const void*)DEFAULT_DRAG_COLOR, 3 * sizeof(float));
+ ::memcpy((void*)m_highlight_color, (const void*)DEFAULT_HIGHLIGHT_COLOR, 3 * sizeof(float));
+}
+
+void GLGizmoBase::set_hover_id(int id)
+{
+ if (m_grabbers.empty() || (id < (int)m_grabbers.size()))
+ {
+ m_hover_id = id;
+ on_set_hover_id();
+ }
+}
+
+void GLGizmoBase::set_highlight_color(const float* color)
+{
+ if (color != nullptr)
+ ::memcpy((void*)m_highlight_color, (const void*)color, 3 * sizeof(float));
+}
+
+void GLGizmoBase::enable_grabber(unsigned int id)
+{
+ if ((0 <= id) && (id < (unsigned int)m_grabbers.size()))
+ m_grabbers[id].enabled = true;
+
+ on_enable_grabber(id);
+}
+
+void GLGizmoBase::disable_grabber(unsigned int id)
+{
+ if ((0 <= id) && (id < (unsigned int)m_grabbers.size()))
+ m_grabbers[id].enabled = false;
+
+ on_disable_grabber(id);
+}
+
+void GLGizmoBase::start_dragging(const BoundingBoxf3& box)
+{
+ m_dragging = true;
+
+ for (int i = 0; i < (int)m_grabbers.size(); ++i)
+ {
+ m_grabbers[i].dragging = (m_hover_id == i);
+ }
+
+ on_start_dragging(box);
+}
+
+void GLGizmoBase::stop_dragging()
+{
+ m_dragging = false;
+ set_tooltip("");
+
+ for (int i = 0; i < (int)m_grabbers.size(); ++i)
+ {
+ m_grabbers[i].dragging = false;
+ }
+
+ on_stop_dragging();
+}
+
+void GLGizmoBase::update(const Linef3& mouse_ray)
+{
+ if (m_hover_id != -1)
+ on_update(mouse_ray);
+}
+
+float GLGizmoBase::picking_color_component(unsigned int id) const
+{
+ int color = 254 - (int)id;
+ if (m_group_id > -1)
+ color -= m_group_id;
+
+ return (float)color / 255.0f;
+}
+
+void GLGizmoBase::render_grabbers() const
+{
+ for (int i = 0; i < (int)m_grabbers.size(); ++i)
+ {
+ if (m_grabbers[i].enabled)
+ m_grabbers[i].render(m_hover_id == i);
+ }
+}
+
+void GLGizmoBase::render_grabbers_for_picking() const
+{
+ for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i)
+ {
+ if (m_grabbers[i].enabled)
+ {
+ m_grabbers[i].color[0] = 1.0f;
+ m_grabbers[i].color[1] = 1.0f;
+ m_grabbers[i].color[2] = picking_color_component(i);
+ m_grabbers[i].render_for_picking();
+ }
+ }
+}
+
+void GLGizmoBase::set_tooltip(const std::string& tooltip) const
+{
+ m_parent.set_tooltip(tooltip);
+}
+
+std::string GLGizmoBase::format(float value, unsigned int decimals) const
+{
+ char buf[1024];
+ ::sprintf(buf, "%.*f", decimals, value);
+ return buf;
+}
+
+const float GLGizmoRotate::Offset = 5.0f;
+const unsigned int GLGizmoRotate::CircleResolution = 64;
+const unsigned int GLGizmoRotate::AngleResolution = 64;
+const unsigned int GLGizmoRotate::ScaleStepsCount = 72;
+const float GLGizmoRotate::ScaleStepRad = 2.0f * (float)PI / GLGizmoRotate::ScaleStepsCount;
+const unsigned int GLGizmoRotate::ScaleLongEvery = 2;
+const float GLGizmoRotate::ScaleLongTooth = 2.0f;
+const float GLGizmoRotate::ScaleShortTooth = 1.0f;
+const unsigned int GLGizmoRotate::SnapRegionsCount = 8;
+const float GLGizmoRotate::GrabberOffset = 5.0f;
+
+GLGizmoRotate::GLGizmoRotate(GLCanvas3D& parent, GLGizmoRotate::Axis axis)
+ : GLGizmoBase(parent)
+ , m_axis(axis)
+ , m_angle(0.0)
+ , m_center(0.0, 0.0, 0.0)
+ , m_radius(0.0f)
+{
+}
+
+void GLGizmoRotate::set_angle(double angle)
+{
+ if (std::abs(angle - 2.0 * (double)PI) < EPSILON)
+ angle = 0.0;
+
+ m_angle = angle;
+}
+
+bool GLGizmoRotate::on_init()
+{
+ m_grabbers.push_back(Grabber());
+ return true;
+}
+
+void GLGizmoRotate::on_start_dragging(const BoundingBoxf3& box)
+{
+ m_center = box.center();
+ m_radius = Offset + box.radius();
+}
+
+void GLGizmoRotate::on_update(const Linef3& mouse_ray)
+{
+ Vec2d mouse_pos = to_2d(mouse_position_in_local_plane(mouse_ray));
+
+ Vec2d orig_dir = Vec2d::UnitX();
+ Vec2d new_dir = mouse_pos.normalized();
+
+ double theta = ::acos(clamp(-1.0, 1.0, new_dir.dot(orig_dir)));
+ if (cross2(orig_dir, new_dir) < 0.0)
+ theta = 2.0 * (double)PI - theta;
+
+ double len = mouse_pos.norm();
+
+ // snap to snap region
+ double in_radius = (double)m_radius / 3.0;
+ double out_radius = 2.0 * (double)in_radius;
+ if ((in_radius <= len) && (len <= out_radius))
+ {
+ double step = 2.0 * (double)PI / (double)SnapRegionsCount;
+ theta = step * (double)std::round(theta / step);
+ }
+ else
+ {
+ // snap to scale
+ in_radius = (double)m_radius;
+ out_radius = in_radius + (double)ScaleLongTooth;
+ if ((in_radius <= len) && (len <= out_radius))
+ {
+ double step = 2.0 * (double)PI / (double)ScaleStepsCount;
+ theta = step * (double)std::round(theta / step);
+ }
+ }
+
+ if (theta == 2.0 * (double)PI)
+ theta = 0.0;
+
+ m_angle = theta;
+}
+
+void GLGizmoRotate::on_render(const BoundingBoxf3& box) const
+{
+ if (!m_grabbers[0].enabled)
+ return;
+
+ if (m_dragging)
+ set_tooltip(format(m_angle * 180.0f / (float)PI, 4));
+ else
+ {
+ m_center = box.center();
+ m_radius = Offset + box.radius();
+ }
+
+ ::glEnable(GL_DEPTH_TEST);
+
+ ::glPushMatrix();
+ transform_to_local();
+
+ ::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f);
+ ::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color);
+
+ render_circle();
+
+ if (m_hover_id != -1)
+ {
+ render_scale();
+ render_snap_radii();
+ render_reference_radius();
+ }
+
+ ::glColor3fv(m_highlight_color);
+
+ if (m_hover_id != -1)
+ render_angle();
+
+ render_grabber();
+
+ ::glPopMatrix();
+}
+
+void GLGizmoRotate::on_render_for_picking(const BoundingBoxf3& box) const
+{
+ ::glDisable(GL_DEPTH_TEST);
+
+ ::glPushMatrix();
+
+ transform_to_local();
+ render_grabbers_for_picking();
+
+ ::glPopMatrix();
+}
+
+void GLGizmoRotate::render_circle() const
+{
+ ::glBegin(GL_LINE_LOOP);
+ for (unsigned int i = 0; i < ScaleStepsCount; ++i)
+ {
+ float angle = (float)i * ScaleStepRad;
+ float x = ::cos(angle) * m_radius;
+ float y = ::sin(angle) * m_radius;
+ float z = 0.0f;
+ ::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
+ }
+ ::glEnd();
+}
+
+void GLGizmoRotate::render_scale() const
+{
+ float out_radius_long = m_radius + ScaleLongTooth;
+ float out_radius_short = m_radius + ScaleShortTooth;
+
+ ::glBegin(GL_LINES);
+ for (unsigned int i = 0; i < ScaleStepsCount; ++i)
+ {
+ float angle = (float)i * ScaleStepRad;
+ float cosa = ::cos(angle);
+ float sina = ::sin(angle);
+ float in_x = cosa * m_radius;
+ float in_y = sina * m_radius;
+ float in_z = 0.0f;
+ float out_x = (i % ScaleLongEvery == 0) ? cosa * out_radius_long : cosa * out_radius_short;
+ float out_y = (i % ScaleLongEvery == 0) ? sina * out_radius_long : sina * out_radius_short;
+ float out_z = 0.0f;
+ ::glVertex3f((GLfloat)in_x, (GLfloat)in_y, (GLfloat)in_z);
+ ::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z);
+ }
+ ::glEnd();
+}
+
+void GLGizmoRotate::render_snap_radii() const
+{
+ float step = 2.0f * (float)PI / (float)SnapRegionsCount;
+
+ float in_radius = m_radius / 3.0f;
+ float out_radius = 2.0f * in_radius;
+
+ ::glBegin(GL_LINES);
+ for (unsigned int i = 0; i < SnapRegionsCount; ++i)
+ {
+ float angle = (float)i * step;
+ float cosa = ::cos(angle);
+ float sina = ::sin(angle);
+ float in_x = cosa * in_radius;
+ float in_y = sina * in_radius;
+ float in_z = 0.0f;
+ float out_x = cosa * out_radius;
+ float out_y = sina * out_radius;
+ float out_z = 0.0f;
+ ::glVertex3f((GLfloat)in_x, (GLfloat)in_y, (GLfloat)in_z);
+ ::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z);
+ }
+ ::glEnd();
+}
+
+void GLGizmoRotate::render_reference_radius() const
+{
+ ::glBegin(GL_LINES);
+ ::glVertex3f(0.0f, 0.0f, 0.0f);
+ ::glVertex3f((GLfloat)(m_radius + GrabberOffset), 0.0f, 0.0f);
+ ::glEnd();
+}
+
+void GLGizmoRotate::render_angle() const
+{
+ float step_angle = (float)m_angle / AngleResolution;
+ float ex_radius = m_radius + GrabberOffset;
+
+ ::glBegin(GL_LINE_STRIP);
+ for (unsigned int i = 0; i <= AngleResolution; ++i)
+ {
+ float angle = (float)i * step_angle;
+ float x = ::cos(angle) * ex_radius;
+ float y = ::sin(angle) * ex_radius;
+ float z = 0.0f;
+ ::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
+ }
+ ::glEnd();
+}
+
+void GLGizmoRotate::render_grabber() const
+{
+ double grabber_radius = (double)(m_radius + GrabberOffset);
+ m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0);
+ m_grabbers[0].angles(2) = m_angle;
+
+ ::glColor3fv((m_hover_id != -1) ? m_drag_color : m_highlight_color);
+
+ ::glBegin(GL_LINES);
+ ::glVertex3f(0.0f, 0.0f, 0.0f);
+ ::glVertex3f((GLfloat)m_grabbers[0].center(0), (GLfloat)m_grabbers[0].center(1), (GLfloat)m_grabbers[0].center(2));
+ ::glEnd();
+
+ ::memcpy((void*)m_grabbers[0].color, (const void*)m_highlight_color, 3 * sizeof(float));
+ render_grabbers();
+}
+
+void GLGizmoRotate::transform_to_local() const
+{
+ ::glTranslatef((GLfloat)m_center(0), (GLfloat)m_center(1), (GLfloat)m_center(2));
+
+ switch (m_axis)
+ {
+ case X:
+ {
+ ::glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
+ ::glRotatef(90.0f, 0.0f, 0.0f, 1.0f);
+ break;
+ }
+ case Y:
+ {
+ ::glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
+ ::glRotatef(180.0f, 0.0f, 0.0f, 1.0f);
+ break;
+ }
+ default:
+ case Z:
+ {
+ // no rotation
+ break;
+ }
+ }
+}
+
+Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray) const
+{
+ double half_pi = 0.5 * (double)PI;
+
+ Transform3d m = Transform3d::Identity();
+
+ switch (m_axis)
+ {
+ case X:
+ {
+ m.rotate(Eigen::AngleAxisd(-half_pi, Vec3d::UnitZ()));
+ m.rotate(Eigen::AngleAxisd(-half_pi, Vec3d::UnitY()));
+ break;
+ }
+ case Y:
+ {
+ m.rotate(Eigen::AngleAxisd(-(double)PI, Vec3d::UnitZ()));
+ m.rotate(Eigen::AngleAxisd(half_pi, Vec3d::UnitX()));
+ break;
+ }
+ default:
+ case Z:
+ {
+ // no rotation applied
+ break;
+ }
+ }
+
+ m.translate(-m_center);
+
+ return transform(mouse_ray, m).intersect_plane(0.0);
+}
+
+GLGizmoRotate3D::GLGizmoRotate3D(GLCanvas3D& parent)
+ : GLGizmoBase(parent)
+{
+ m_gizmos.emplace_back(parent, GLGizmoRotate::X);
+ m_gizmos.emplace_back(parent, GLGizmoRotate::Y);
+ m_gizmos.emplace_back(parent, GLGizmoRotate::Z);
+
+ for (unsigned int i = 0; i < 3; ++i)
+ {
+ m_gizmos[i].set_group_id(i);
+ }
+}
+
+bool GLGizmoRotate3D::on_init()
+{
+ for (GLGizmoRotate& g : m_gizmos)
+ {
+ if (!g.init())
+ return false;
+ }
+
+ for (unsigned int i = 0; i < 3; ++i)
+ {
+ m_gizmos[i].set_highlight_color(AXES_COLOR[i]);
+ }
+
+ std::string path = resources_dir() + "/icons/overlay/";
+
+ std::string filename = path + "rotate_off.png";
+ if (!m_textures[Off].load_from_file(filename, false))
+ return false;
+
+ filename = path + "rotate_hover.png";
+ if (!m_textures[Hover].load_from_file(filename, false))
+ return false;
+
+ filename = path + "rotate_on.png";
+ if (!m_textures[On].load_from_file(filename, false))
+ return false;
+
+ return true;
+}
+
+void GLGizmoRotate3D::on_start_dragging(const BoundingBoxf3& box)
+{
+ if ((0 <= m_hover_id) && (m_hover_id < 3))
+ m_gizmos[m_hover_id].start_dragging(box);
+}
+
+void GLGizmoRotate3D::on_stop_dragging()
+{
+ if ((0 <= m_hover_id) && (m_hover_id < 3))
+ m_gizmos[m_hover_id].stop_dragging();
+}
+
+void GLGizmoRotate3D::on_render(const BoundingBoxf3& box) const
+{
+ if ((m_hover_id == -1) || (m_hover_id == 0))
+ m_gizmos[X].render(box);
+
+ if ((m_hover_id == -1) || (m_hover_id == 1))
+ m_gizmos[Y].render(box);
+
+ if ((m_hover_id == -1) || (m_hover_id == 2))
+ m_gizmos[Z].render(box);
+}
+
+const float GLGizmoScale3D::Offset = 5.0f;
+
+GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent)
+ : GLGizmoBase(parent)
+ , m_scale(Vec3d::Ones())
+ , m_starting_scale(Vec3d::Ones())
+ , m_show_starting_box(false)
+{
+}
+
+bool GLGizmoScale3D::on_init()
+{
+ std::string path = resources_dir() + "/icons/overlay/";
+
+ std::string filename = path + "scale_off.png";
+ if (!m_textures[Off].load_from_file(filename, false))
+ return false;
+
+ filename = path + "scale_hover.png";
+ if (!m_textures[Hover].load_from_file(filename, false))
+ return false;
+
+ filename = path + "scale_on.png";
+ if (!m_textures[On].load_from_file(filename, false))
+ return false;
+
+ for (int i = 0; i < 10; ++i)
+ {
+ m_grabbers.push_back(Grabber());
+ }
+
+ double half_pi = 0.5 * (double)PI;
+
+ // x axis
+ m_grabbers[0].angles(1) = half_pi;
+ m_grabbers[1].angles(1) = half_pi;
+
+ // y axis
+ m_grabbers[2].angles(0) = half_pi;
+ m_grabbers[3].angles(0) = half_pi;
+
+ return true;
+}
+
+void GLGizmoScale3D::on_start_dragging(const BoundingBoxf3& box)
+{
+ if (m_hover_id != -1)
+ {
+ m_starting_drag_position = m_grabbers[m_hover_id].center;
+ m_show_starting_box = true;
+ m_starting_box = box;
+ }
+}
+
+void GLGizmoScale3D::on_update(const Linef3& mouse_ray)
+{
+ if ((m_hover_id == 0) || (m_hover_id == 1))
+ do_scale_x(mouse_ray);
+ else if ((m_hover_id == 2) || (m_hover_id == 3))
+ do_scale_y(mouse_ray);
+ else if ((m_hover_id == 4) || (m_hover_id == 5))
+ do_scale_z(mouse_ray);
+ else if (m_hover_id >= 6)
+ do_scale_uniform(mouse_ray);
+}
+
+void GLGizmoScale3D::on_render(const BoundingBoxf3& box) const
+{
+ if (m_grabbers[0].dragging || m_grabbers[1].dragging)
+ set_tooltip("X: " + format(100.0f * m_scale(0), 4) + "%");
+ else if (m_grabbers[2].dragging || m_grabbers[3].dragging)
+ set_tooltip("Y: " + format(100.0f * m_scale(1), 4) + "%");
+ else if (m_grabbers[4].dragging || m_grabbers[5].dragging)
+ set_tooltip("Z: " + format(100.0f * m_scale(2), 4) + "%");
+ else if (m_grabbers[6].dragging || m_grabbers[7].dragging || m_grabbers[8].dragging || m_grabbers[9].dragging)
+ {
+ std::string tooltip = "X: " + format(100.0f * m_scale(0), 4) + "%\n";
+ tooltip += "Y: " + format(100.0f * m_scale(1), 4) + "%\n";
+ tooltip += "Z: " + format(100.0f * m_scale(2), 4) + "%";
+ set_tooltip(tooltip);
+ }
+
+ ::glEnable(GL_DEPTH_TEST);
+
+ Vec3d offset_vec = (double)Offset * Vec3d::Ones();
+
+ m_box = BoundingBoxf3(box.min - offset_vec, box.max + offset_vec);
+ const Vec3d& center = m_box.center();
+
+ // x axis
+ m_grabbers[0].center = Vec3d(m_box.min(0), center(1), center(2));
+ m_grabbers[1].center = Vec3d(m_box.max(0), center(1), center(2));
+ ::memcpy((void*)m_grabbers[0].color, (const void*)&AXES_COLOR[0], 3 * sizeof(float));
+ ::memcpy((void*)m_grabbers[1].color, (const void*)&AXES_COLOR[0], 3 * sizeof(float));
+
+ // y axis
+ m_grabbers[2].center = Vec3d(center(0), m_box.min(1), center(2));
+ m_grabbers[3].center = Vec3d(center(0), m_box.max(1), center(2));
+ ::memcpy((void*)m_grabbers[2].color, (const void*)&AXES_COLOR[1], 3 * sizeof(float));
+ ::memcpy((void*)m_grabbers[3].color, (const void*)&AXES_COLOR[1], 3 * sizeof(float));
+
+ // z axis
+ m_grabbers[4].center = Vec3d(center(0), center(1), m_box.min(2));
+ m_grabbers[5].center = Vec3d(center(0), center(1), m_box.max(2));
+ ::memcpy((void*)m_grabbers[4].color, (const void*)&AXES_COLOR[2], 3 * sizeof(float));
+ ::memcpy((void*)m_grabbers[5].color, (const void*)&AXES_COLOR[2], 3 * sizeof(float));
+
+ // uniform
+ m_grabbers[6].center = Vec3d(m_box.min(0), m_box.min(1), m_box.min(2));
+ m_grabbers[7].center = Vec3d(m_box.max(0), m_box.min(1), m_box.min(2));
+ m_grabbers[8].center = Vec3d(m_box.max(0), m_box.max(1), m_box.min(2));
+ m_grabbers[9].center = Vec3d(m_box.min(0), m_box.max(1), m_box.min(2));
+ for (int i = 6; i < 10; ++i)
+ {
+ ::memcpy((void*)m_grabbers[i].color, (const void*)m_highlight_color, 3 * sizeof(float));
+ }
+
+ ::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f);
+
+ if (m_hover_id == -1)
+ {
+ // draw box
+ ::glColor3fv(m_base_color);
+ render_box(m_box);
+ // draw connections
+ if (m_grabbers[0].enabled && m_grabbers[1].enabled)
+ {
+ ::glColor3fv(m_grabbers[0].color);
+ render_grabbers_connection(0, 1);
+ }
+ if (m_grabbers[2].enabled && m_grabbers[3].enabled)
+ {
+ ::glColor3fv(m_grabbers[2].color);
+ render_grabbers_connection(2, 3);
+ }
+ if (m_grabbers[4].enabled && m_grabbers[5].enabled)
+ {
+ ::glColor3fv(m_grabbers[4].color);
+ render_grabbers_connection(4, 5);
+ }
+ // draw grabbers
+ render_grabbers();
+ }
+ else if ((m_hover_id == 0) || (m_hover_id == 1))
+ {
+ // draw starting box
+ if (m_show_starting_box)
+ {
+ ::glColor3fv(m_base_color);
+ render_box(m_starting_box);
+ }
+ // draw current box
+ ::glColor3fv(m_drag_color);
+ render_box(m_box);
+ // draw connection
+ ::glColor3fv(m_grabbers[0].color);
+ render_grabbers_connection(0, 1);
+ // draw grabbers
+ m_grabbers[0].render(true);
+ m_grabbers[1].render(true);
+ }
+ else if ((m_hover_id == 2) || (m_hover_id == 3))
+ {
+ // draw starting box
+ if (m_show_starting_box)
+ {
+ ::glColor3fv(m_base_color);
+ render_box(m_starting_box);
+ }
+ // draw current box
+ ::glColor3fv(m_drag_color);
+ render_box(m_box);
+ // draw connection
+ ::glColor3fv(m_grabbers[2].color);
+ render_grabbers_connection(2, 3);
+ // draw grabbers
+ m_grabbers[2].render(true);
+ m_grabbers[3].render(true);
+ }
+ else if ((m_hover_id == 4) || (m_hover_id == 5))
+ {
+ // draw starting box
+ if (m_show_starting_box)
+ {
+ ::glColor3fv(m_base_color);
+ render_box(m_starting_box);
+ }
+ // draw current box
+ ::glColor3fv(m_drag_color);
+ render_box(m_box);
+ // draw connection
+ ::glColor3fv(m_grabbers[4].color);
+ render_grabbers_connection(4, 5);
+ // draw grabbers
+ m_grabbers[4].render(true);
+ m_grabbers[5].render(true);
+ }
+ else if (m_hover_id >= 6)
+ {
+ // draw starting box
+ if (m_show_starting_box)
+ {
+ ::glColor3fv(m_base_color);
+ render_box(m_starting_box);
+ }
+ // draw current box
+ ::glColor3fv(m_drag_color);
+ render_box(m_box);
+ // draw grabbers
+ for (int i = 6; i < 10; ++i)
+ {
+ m_grabbers[i].render(true);
+ }
+ }
+}
+
+void GLGizmoScale3D::on_render_for_picking(const BoundingBoxf3& box) const
+{
+ ::glDisable(GL_DEPTH_TEST);
+
+ render_grabbers_for_picking();
+}
+
+void GLGizmoScale3D::render_box(const BoundingBoxf3& box) const
+{
+ // bottom face
+ ::glBegin(GL_LINE_LOOP);
+ ::glVertex3f((GLfloat)box.min(0), (GLfloat)box.min(1), (GLfloat)box.min(2));
+ ::glVertex3f((GLfloat)box.min(0), (GLfloat)box.max(1), (GLfloat)box.min(2));
+ ::glVertex3f((GLfloat)box.max(0), (GLfloat)box.max(1), (GLfloat)box.min(2));
+ ::glVertex3f((GLfloat)box.max(0), (GLfloat)box.min(1), (GLfloat)box.min(2));
+ ::glEnd();
+
+ // top face
+ ::glBegin(GL_LINE_LOOP);
+ ::glVertex3f((GLfloat)box.min(0), (GLfloat)box.min(1), (GLfloat)box.max(2));
+ ::glVertex3f((GLfloat)box.min(0), (GLfloat)box.max(1), (GLfloat)box.max(2));
+ ::glVertex3f((GLfloat)box.max(0), (GLfloat)box.max(1), (GLfloat)box.max(2));
+ ::glVertex3f((GLfloat)box.max(0), (GLfloat)box.min(1), (GLfloat)box.max(2));
+ ::glEnd();
+
+ // vertical edges
+ ::glBegin(GL_LINES);
+ ::glVertex3f((GLfloat)box.min(0), (GLfloat)box.min(1), (GLfloat)box.min(2)); ::glVertex3f((GLfloat)box.min(0), (GLfloat)box.min(1), (GLfloat)box.max(2));
+ ::glVertex3f((GLfloat)box.min(0), (GLfloat)box.max(1), (GLfloat)box.min(2)); ::glVertex3f((GLfloat)box.min(0), (GLfloat)box.max(1), (GLfloat)box.max(2));
+ ::glVertex3f((GLfloat)box.max(0), (GLfloat)box.max(1), (GLfloat)box.min(2)); ::glVertex3f((GLfloat)box.max(0), (GLfloat)box.max(1), (GLfloat)box.max(2));
+ ::glVertex3f((GLfloat)box.max(0), (GLfloat)box.min(1), (GLfloat)box.min(2)); ::glVertex3f((GLfloat)box.max(0), (GLfloat)box.min(1), (GLfloat)box.max(2));
+ ::glEnd();
+}
+
+void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int id_2) const
+{
+ unsigned int grabbers_count = (unsigned int)m_grabbers.size();
+ if ((id_1 < grabbers_count) && (id_2 < grabbers_count))
+ {
+ ::glBegin(GL_LINES);
+ ::glVertex3f((GLfloat)m_grabbers[id_1].center(0), (GLfloat)m_grabbers[id_1].center(1), (GLfloat)m_grabbers[id_1].center(2));
+ ::glVertex3f((GLfloat)m_grabbers[id_2].center(0), (GLfloat)m_grabbers[id_2].center(1), (GLfloat)m_grabbers[id_2].center(2));
+ ::glEnd();
+ }
+}
+
+void GLGizmoScale3D::do_scale_x(const Linef3& mouse_ray)
+{
+ double ratio = calc_ratio(1, mouse_ray, m_starting_box.center());
+
+ if (ratio > 0.0)
+ m_scale(0) = m_starting_scale(0) * ratio;
+}
+
+void GLGizmoScale3D::do_scale_y(const Linef3& mouse_ray)
+{
+ double ratio = calc_ratio(2, mouse_ray, m_starting_box.center());
+
+ if (ratio > 0.0)
+ m_scale(0) = m_starting_scale(1) * ratio; // << this is temporary
+// m_scale(1) = m_starting_scale(1) * ratio;
+}
+
+void GLGizmoScale3D::do_scale_z(const Linef3& mouse_ray)
+{
+ double ratio = calc_ratio(1, mouse_ray, m_starting_box.center());
+
+ if (ratio > 0.0)
+ m_scale(0) = m_starting_scale(2) * ratio; // << this is temporary
+// m_scale(2) = m_starting_scale(2) * ratio;
+}
+
+void GLGizmoScale3D::do_scale_uniform(const Linef3& mouse_ray)
+{
+ Vec3d center = m_starting_box.center();
+ center(2) = m_box.min(2);
+ double ratio = calc_ratio(0, mouse_ray, center);
+
+ if (ratio > 0.0)
+ m_scale = m_starting_scale * ratio;
+}
+
+double GLGizmoScale3D::calc_ratio(unsigned int preferred_plane_id, const Linef3& mouse_ray, const Vec3d& center) const
+{
+ double ratio = 0.0;
+
+ Vec3d starting_vec = m_starting_drag_position - center;
+ double len_starting_vec = starting_vec.norm();
+ if (len_starting_vec == 0.0)
+ return ratio;
+
+ Vec3d starting_vec_dir = starting_vec.normalized();
+ Vec3d mouse_dir = mouse_ray.unit_vector();
+
+ unsigned int plane_id = select_best_plane(mouse_dir, preferred_plane_id);
+ // ratio is given by the projection of the calculated intersection on the starting vector divided by the starting vector length
+ switch (plane_id)
+ {
+ case 0:
+ {
+ ratio = starting_vec_dir.dot(intersection_on_plane_xy(mouse_ray, center)) / len_starting_vec;
+ break;
+ }
+ case 1:
+ {
+ ratio = starting_vec_dir.dot(intersection_on_plane_xz(mouse_ray, center)) / len_starting_vec;
+ break;
+ }
+ case 2:
+ {
+ ratio = starting_vec_dir.dot(intersection_on_plane_yz(mouse_ray, center)) / len_starting_vec;
+ break;
+ }
+ }
+
+ return ratio;
+}
+
+const double GLGizmoMove3D::Offset = 10.0;
+
+GLGizmoMove3D::GLGizmoMove3D(GLCanvas3D& parent)
+ : GLGizmoBase(parent)
+ , m_position(Vec3d::Zero())
+ , m_starting_drag_position(Vec3d::Zero())
+ , m_starting_box_center(Vec3d::Zero())
+{
+}
+
+bool GLGizmoMove3D::on_init()
+{
+ std::string path = resources_dir() + "/icons/overlay/";
+
+ std::string filename = path + "move_off.png";
+ if (!m_textures[Off].load_from_file(filename, false))
+ return false;
+
+ filename = path + "move_hover.png";
+ if (!m_textures[Hover].load_from_file(filename, false))
+ return false;
+
+ filename = path + "move_on.png";
+ if (!m_textures[On].load_from_file(filename, false))
+ return false;
+
+ for (int i = 0; i < 3; ++i)
+ {
+ m_grabbers.push_back(Grabber());
+ }
+
+ return true;
+}
+
+void GLGizmoMove3D::on_start_dragging(const BoundingBoxf3& box)
+{
+ if (m_hover_id != -1)
+ {
+ m_starting_drag_position = m_grabbers[m_hover_id].center;
+ m_starting_box_center = box.center();
+ }
+}
+
+void GLGizmoMove3D::on_update(const Linef3& mouse_ray)
+{
+ if (m_hover_id == 0)
+ m_position(0) = 2.0 * m_starting_box_center(0) + calc_displacement(1, mouse_ray) - m_starting_drag_position(0);
+ else if (m_hover_id == 1)
+ m_position(1) = 2.0 * m_starting_box_center(1) + calc_displacement(2, mouse_ray) - m_starting_drag_position(1);
+ else if (m_hover_id == 2)
+ m_position(2) = 2.0 * m_starting_box_center(2) + calc_displacement(1, mouse_ray) - m_starting_drag_position(2);
+}
+
+void GLGizmoMove3D::on_render(const BoundingBoxf3& box) const
+{
+ if (m_grabbers[0].dragging)
+ set_tooltip("X: " + format(m_position(0), 2));
+ else if (m_grabbers[1].dragging)
+ set_tooltip("Y: " + format(m_position(1), 2));
+ else if (m_grabbers[2].dragging)
+ set_tooltip("Z: " + format(m_position(2), 2));
+
+ ::glEnable(GL_DEPTH_TEST);
+
+ const Vec3d& center = box.center();
+
+ // x axis
+ m_grabbers[0].center = Vec3d(box.max(0) + Offset, center(1), center(2));
+ ::memcpy((void*)m_grabbers[0].color, (const void*)&AXES_COLOR[0], 3 * sizeof(float));
+
+ // y axis
+ m_grabbers[1].center = Vec3d(center(0), box.max(1) + Offset, center(2));
+ ::memcpy((void*)m_grabbers[1].color, (const void*)&AXES_COLOR[1], 3 * sizeof(float));
+
+ // z axis
+ m_grabbers[2].center = Vec3d(center(0), center(1), box.max(2) + Offset);
+ ::memcpy((void*)m_grabbers[2].color, (const void*)&AXES_COLOR[2], 3 * sizeof(float));
+
+ ::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f);
+
+ if (m_hover_id == -1)
+ {
+ // draw axes
+ for (unsigned int i = 0; i < 3; ++i)
+ {
+ if (m_grabbers[i].enabled)
+ {
+ ::glColor3fv(AXES_COLOR[i]);
+ ::glBegin(GL_LINES);
+ ::glVertex3f(center(0), center(1), center(2));
+ ::glVertex3f((GLfloat)m_grabbers[i].center(0), (GLfloat)m_grabbers[i].center(1), (GLfloat)m_grabbers[i].center(2));
+ ::glEnd();
+ }
+ }
+
+ // draw grabbers
+ render_grabbers();
+ }
+ else
+ {
+ // draw axis
+ ::glColor3fv(AXES_COLOR[m_hover_id]);
+ ::glBegin(GL_LINES);
+ ::glVertex3f(center(0), center(1), center(2));
+ ::glVertex3f((GLfloat)m_grabbers[m_hover_id].center(0), (GLfloat)m_grabbers[m_hover_id].center(1), (GLfloat)m_grabbers[m_hover_id].center(2));
+ ::glEnd();
+
+ // draw grabber
+ m_grabbers[m_hover_id].render(true);
+ }
+}
+
+void GLGizmoMove3D::on_render_for_picking(const BoundingBoxf3& box) const
+{
+ ::glDisable(GL_DEPTH_TEST);
+
+ render_grabbers_for_picking();
+}
+
+double GLGizmoMove3D::calc_displacement(unsigned int preferred_plane_id, const Linef3& mouse_ray) const
+{
+ double displacement = 0.0;
+
+ Vec3d starting_vec = m_starting_drag_position - m_starting_box_center;
+ double len_starting_vec = starting_vec.norm();
+ if (len_starting_vec == 0.0)
+ return displacement;
+
+ Vec3d starting_vec_dir = starting_vec.normalized();
+ Vec3d mouse_dir = mouse_ray.unit_vector();
+
+ unsigned int plane_id = select_best_plane(mouse_dir, preferred_plane_id);
+
+ switch (plane_id)
+ {
+ case 0:
+ {
+ displacement = starting_vec_dir.dot(intersection_on_plane_xy(mouse_ray, m_starting_box_center));
+ break;
+ }
+ case 1:
+ {
+ displacement = starting_vec_dir.dot(intersection_on_plane_xz(mouse_ray, m_starting_box_center));
+ break;
+ }
+ case 2:
+ {
+ displacement = starting_vec_dir.dot(intersection_on_plane_yz(mouse_ray, m_starting_box_center));
+ break;
+ }
+ }
+
+ return displacement;
+}
+
+GLGizmoFlatten::GLGizmoFlatten(GLCanvas3D& parent)
+ : GLGizmoBase(parent)
+ , m_normal(Vec3d::Zero())
+ , m_starting_center(Vec3d::Zero())
+{
+}
+
+bool GLGizmoFlatten::on_init()
+{
+ std::string path = resources_dir() + "/icons/overlay/";
+
+ std::string filename = path + "layflat_off.png";
+ if (!m_textures[Off].load_from_file(filename, false))
+ return false;
+
+ filename = path + "layflat_hover.png";
+ if (!m_textures[Hover].load_from_file(filename, false))
+ return false;
+
+ filename = path + "layflat_on.png";
+ if (!m_textures[On].load_from_file(filename, false))
+ return false;
+
+ return true;
+}
+
+void GLGizmoFlatten::on_start_dragging(const BoundingBoxf3& box)
+{
+ if (m_hover_id != -1)
+ {
+ m_normal = m_planes[m_hover_id].normal;
+ m_starting_center = box.center();
+ }
+}
+
+void GLGizmoFlatten::on_render(const BoundingBoxf3& box) const
+{
+ // the dragged_offset is a vector measuring where was the object moved
+ // with the gizmo being on. This is reset in set_flattening_data and
+ // does not work correctly when there are multiple copies.
+ Vec3d dragged_offset(Vec3d::Zero());
+ if (m_dragging)
+ dragged_offset = box.center() - m_starting_center;
+
+ ::glEnable(GL_BLEND);
+ ::glEnable(GL_DEPTH_TEST);
+
+ for (int i=0; i<(int)m_planes.size(); ++i) {
+ if (i == m_hover_id)
+ ::glColor4f(0.9f, 0.9f, 0.9f, 0.75f);
+ else
+ ::glColor4f(0.9f, 0.9f, 0.9f, 0.5f);
+
+ for (Vec2d offset : m_instances_positions) {
+ offset += to_2d(dragged_offset);
+ ::glPushMatrix();
+ ::glTranslatef((GLfloat)offset(0), (GLfloat)offset(1), 0.0f);
+ ::glBegin(GL_POLYGON);
+ for (const Vec3d& vertex : m_planes[i].vertices)
+ ::glVertex3f((GLfloat)vertex(0), (GLfloat)vertex(1), (GLfloat)vertex(2));
+ ::glEnd();
+ ::glPopMatrix();
+ }
+ }
+
+ ::glDisable(GL_BLEND);
+}
+
+void GLGizmoFlatten::on_render_for_picking(const BoundingBoxf3& box) const
+{
+ ::glEnable(GL_DEPTH_TEST);
+
+ for (unsigned int i = 0; i < m_planes.size(); ++i)
+ {
+ ::glColor3f(1.0f, 1.0f, picking_color_component(i));
+ for (const Vec2d& offset : m_instances_positions) {
+ ::glPushMatrix();
+ ::glTranslatef((GLfloat)offset(0), (GLfloat)offset(1), 0.0f);
+ ::glBegin(GL_POLYGON);
+ for (const Vec3d& vertex : m_planes[i].vertices)
+ ::glVertex3f((GLfloat)vertex(0), (GLfloat)vertex(1), (GLfloat)vertex(2));
+ ::glEnd();
+ ::glPopMatrix();
+ }
+ }
+}
+
+void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object)
+{
+ m_model_object = model_object;
+
+ // ...and save the updated positions of the object instances:
+ if (m_model_object && !m_model_object->instances.empty()) {
+ m_instances_positions.clear();
+ for (const auto* instance : m_model_object->instances)
+ m_instances_positions.emplace_back(instance->offset);
+ }
+
+ if (is_plane_update_necessary())
+ update_planes();
+}
+
+void GLGizmoFlatten::update_planes()
+{
+ TriangleMesh ch;
+ for (const ModelVolume* vol : m_model_object->volumes)
+ ch.merge(vol->get_convex_hull());
+ ch = ch.convex_hull_3d();
+ ch.scale(m_model_object->instances.front()->scaling_factor);
+ ch.rotate_z(m_model_object->instances.front()->rotation);
+
+ m_planes.clear();
+
+ // Now we'll go through all the facets and append Points of facets sharing the same normal:
+ const int num_of_facets = ch.stl.stats.number_of_facets;
+ std::vector<int> facet_queue(num_of_facets, 0);
+ std::vector<bool> facet_visited(num_of_facets, false);
+ int facet_queue_cnt = 0;
+ const stl_normal* normal_ptr = nullptr;
+ while (1) {
+ // Find next unvisited triangle:
+ int facet_idx = 0;
+ for (; facet_idx < num_of_facets; ++ facet_idx)
+ if (!facet_visited[facet_idx]) {
+ facet_queue[facet_queue_cnt ++] = facet_idx;
+ facet_visited[facet_idx] = true;
+ normal_ptr = &ch.stl.facet_start[facet_idx].normal;
+ m_planes.emplace_back();
+ break;
+ }
+ if (facet_idx == num_of_facets)
+ break; // Everything was visited already
+
+ while (facet_queue_cnt > 0) {
+ int facet_idx = facet_queue[-- facet_queue_cnt];
+ const stl_normal& this_normal = ch.stl.facet_start[facet_idx].normal;
+ if (std::abs(this_normal(0) - (*normal_ptr)(0)) < 0.001 && std::abs(this_normal(1) - (*normal_ptr)(1)) < 0.001 && std::abs(this_normal(2) - (*normal_ptr)(2)) < 0.001) {
+ stl_vertex* first_vertex = ch.stl.facet_start[facet_idx].vertex;
+ for (int j=0; j<3; ++j)
+ m_planes.back().vertices.emplace_back(first_vertex[j](0), first_vertex[j](1), first_vertex[j](2));
+
+ facet_visited[facet_idx] = true;
+ for (int j = 0; j < 3; ++ j) {
+ int neighbor_idx = ch.stl.neighbors_start[facet_idx].neighbor[j];
+ if (! facet_visited[neighbor_idx])
+ facet_queue[facet_queue_cnt ++] = neighbor_idx;
+ }
+ }
+ }
+ m_planes.back().normal = Vec3d((double)(*normal_ptr)(0), (double)(*normal_ptr)(1), (double)(*normal_ptr)(2));
+
+ // if this is a just a very small triangle, remove it to speed up further calculations (it would be rejected anyway):
+ if (m_planes.back().vertices.size() == 3 &&
+ (m_planes.back().vertices[0] - m_planes.back().vertices[1]).norm() < 1.f
+ || (m_planes.back().vertices[0] - m_planes.back().vertices[2]).norm() < 1.f)
+ m_planes.pop_back();
+ }
+
+ // Now we'll go through all the polygons, transform the points into xy plane to process them:
+ for (unsigned int polygon_id=0; polygon_id < m_planes.size(); ++polygon_id) {
+ Pointf3s& polygon = m_planes[polygon_id].vertices;
+ const Vec3d& normal = m_planes[polygon_id].normal;
+
+ // We are going to rotate about z and y to flatten the plane
+ float angle_z = 0.f;
+ float angle_y = 0.f;
+ if (std::abs(normal(1)) > 0.001)
+ angle_z = -atan2(normal(1), normal(0)); // angle to rotate so that normal ends up in xz-plane
+ if (std::abs(normal(0)*cos(angle_z) - normal(1)*sin(angle_z)) > 0.001)
+ angle_y = -atan2(normal(0)*cos(angle_z) - normal(1)*sin(angle_z), normal(2)); // angle to rotate to make normal point upwards
+ else {
+ // In case it already was in z-direction, we must ensure it is not the wrong way:
+ angle_y = normal(2) > 0.f ? 0.f : -PI;
+ }
+
+ // Rotate all points to the xy plane:
+ Transform3d m = Transform3d::Identity();
+ m.rotate(Eigen::AngleAxisd((double)angle_y, Vec3d::UnitY()));
+ m.rotate(Eigen::AngleAxisd((double)angle_z, Vec3d::UnitZ()));
+ polygon = transform(polygon, m);
+
+ polygon = Slic3r::Geometry::convex_hull(polygon); // To remove the inner points
+
+ // We will calculate area of the polygon and discard ones that are too small
+ // The limit is more forgiving in case the normal is in the direction of the coordinate axes
+ const float minimal_area = (std::abs(normal(0)) > 0.999f || std::abs(normal(1)) > 0.999f || std::abs(normal(2)) > 0.999f) ? 1.f : 20.f;
+ float& area = m_planes[polygon_id].area;
+ area = 0.f;
+ for (unsigned int i = 0; i < polygon.size(); i++) // Shoelace formula
+ area += polygon[i](0)*polygon[i + 1 < polygon.size() ? i + 1 : 0](1) - polygon[i + 1 < polygon.size() ? i + 1 : 0](0)*polygon[i](1);
+ area = std::abs(area / 2.f);
+ if (area < minimal_area) {
+ m_planes.erase(m_planes.begin()+(polygon_id--));
+ continue;
+ }
+
+ // We will shrink the polygon a little bit so it does not touch the object edges:
+ Vec3d centroid = std::accumulate(polygon.begin(), polygon.end(), Vec3d(0.0, 0.0, 0.0));
+ centroid /= (double)polygon.size();
+ for (auto& vertex : polygon)
+ vertex = 0.9f*vertex + 0.1f*centroid;
+
+ // Polygon is now simple and convex, we'll round the corners to make them look nicer.
+ // The algorithm takes a vertex, calculates middles of respective sides and moves the vertex
+ // towards their average (controlled by 'aggressivity'). This is repeated k times.
+ // In next iterations, the neighbours are not always taken at the middle (to increase the
+ // rounding effect at the corners, where we need it most).
+ const unsigned int k = 10; // number of iterations
+ const float aggressivity = 0.2f; // agressivity
+ const unsigned int N = polygon.size();
+ std::vector<std::pair<unsigned int, unsigned int>> neighbours;
+ if (k != 0) {
+ Pointf3s points_out(2*k*N); // vector long enough to store the future vertices
+ for (unsigned int j=0; j<N; ++j) {
+ points_out[j*2*k] = polygon[j];
+ neighbours.push_back(std::make_pair((int)(j*2*k-k) < 0 ? (N-1)*2*k+k : j*2*k-k, j*2*k+k));
+ }
+
+ for (unsigned int i=0; i<k; ++i) {
+ // Calculate middle of each edge so that neighbours points to something useful:
+ for (unsigned int j=0; j<N; ++j)
+ if (i==0)
+ points_out[j*2*k+k] = 0.5f * (points_out[j*2*k] + points_out[j==N-1 ? 0 : (j+1)*2*k]);
+ else {
+ float r = 0.2+0.3/(k-1)*i; // the neighbours are not always taken in the middle
+ points_out[neighbours[j].first] = r*points_out[j*2*k] + (1-r) * points_out[neighbours[j].first-1];
+ points_out[neighbours[j].second] = r*points_out[j*2*k] + (1-r) * points_out[neighbours[j].second+1];
+ }
+ // Now we have a triangle and valid neighbours, we can do an iteration:
+ for (unsigned int j=0; j<N; ++j)
+ points_out[2*k*j] = (1-aggressivity) * points_out[2*k*j] +
+ aggressivity*0.5f*(points_out[neighbours[j].first] + points_out[neighbours[j].second]);
+
+ for (auto& n : neighbours) {
+ ++n.first;
+ --n.second;
+ }
+ }
+ polygon = points_out; // replace the coarse polygon with the smooth one that we just created
+ }
+
+ // Transform back to 3D;
+ for (auto& b : polygon) {
+ b(2) += 0.1f; // raise a bit above the object surface to avoid flickering
+ }
+
+ m = m.inverse();
+ polygon = transform(polygon, m);
+ }
+
+ // We'll sort the planes by area and only keep the 254 largest ones (because of the picking pass limitations):
+ std::sort(m_planes.rbegin(), m_planes.rend(), [](const PlaneData& a, const PlaneData& b) { return a.area < b.area; });
+ m_planes.resize(std::min((int)m_planes.size(), 254));
+
+ // Planes are finished - let's save what we calculated it from:
+ m_source_data.bounding_boxes.clear();
+ for (const auto& vol : m_model_object->volumes)
+ m_source_data.bounding_boxes.push_back(vol->get_convex_hull().bounding_box());
+ m_source_data.scaling_factor = m_model_object->instances.front()->scaling_factor;
+ m_source_data.rotation = m_model_object->instances.front()->rotation;
+ const float* first_vertex = m_model_object->volumes.front()->get_convex_hull().first_vertex();
+ m_source_data.mesh_first_point = Vec3d((double)first_vertex[0], (double)first_vertex[1], (double)first_vertex[2]);
+}
+
+// Check if the bounding boxes of each volume's convex hull is the same as before
+// and that scaling and rotation has not changed. In that case we don't have to recalculate it.
+bool GLGizmoFlatten::is_plane_update_necessary() const
+{
+ if (m_state != On || !m_model_object || m_model_object->instances.empty())
+ return false;
+
+ if (m_model_object->volumes.size() != m_source_data.bounding_boxes.size()
+ || m_model_object->instances.front()->scaling_factor != m_source_data.scaling_factor
+ || m_model_object->instances.front()->rotation != m_source_data.rotation)
+ return true;
+
+ // now compare the bounding boxes:
+ for (unsigned int i=0; i<m_model_object->volumes.size(); ++i)
+ if (m_model_object->volumes[i]->get_convex_hull().bounding_box() != m_source_data.bounding_boxes[i])
+ return true;
+
+ const float* first_vertex = m_model_object->volumes.front()->get_convex_hull().first_vertex();
+ Vec3d first_point((double)first_vertex[0], (double)first_vertex[1], (double)first_vertex[2]);
+ if (first_point != m_source_data.mesh_first_point)
+ return true;
+
+ return false;
+}
+
+Vec3d GLGizmoFlatten::get_flattening_normal() const {
+ Vec3d normal = m_model_object->instances.front()->world_matrix(true).matrix().block(0, 0, 3, 3).inverse() * m_normal;
+ m_normal = Vec3d::Zero();
+ return normal.normalized();
+}
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/GLGizmo.hpp b/xs/src/slic3r/GUI/GLGizmo.hpp
new file mode 100644
index 000000000..8760b1c7d
--- /dev/null
+++ b/xs/src/slic3r/GUI/GLGizmo.hpp
@@ -0,0 +1,359 @@
+#ifndef slic3r_GLGizmo_hpp_
+#define slic3r_GLGizmo_hpp_
+
+#include "../../slic3r/GUI/GLTexture.hpp"
+#include "../../libslic3r/Point.hpp"
+#include "../../libslic3r/BoundingBox.hpp"
+
+#include <vector>
+
+namespace Slic3r {
+
+class BoundingBoxf3;
+class Linef3;
+class ModelObject;
+
+namespace GUI {
+
+class GLCanvas3D;
+
+class GLGizmoBase
+{
+protected:
+ struct Grabber
+ {
+ static const float HalfSize;
+ static const float DraggingScaleFactor;
+
+ Vec3d center;
+ Vec3d angles;
+ float color[3];
+ bool enabled;
+ bool dragging;
+
+ Grabber();
+
+ void render(bool hover) const;
+ void render_for_picking() const { render(color, false); }
+
+ private:
+ void render(const float* render_color, bool use_lighting) const;
+ void render_face(float half_size) const;
+ };
+
+public:
+ enum EState
+ {
+ Off,
+ Hover,
+ On,
+ Num_States
+ };
+
+protected:
+ GLCanvas3D& m_parent;
+
+ int m_group_id;
+ EState m_state;
+ // textures are assumed to be square and all with the same size in pixels, no internal check is done
+ GLTexture m_textures[Num_States];
+ int m_hover_id;
+ bool m_dragging;
+ float m_base_color[3];
+ float m_drag_color[3];
+ float m_highlight_color[3];
+ mutable std::vector<Grabber> m_grabbers;
+
+public:
+ explicit GLGizmoBase(GLCanvas3D& parent);
+ virtual ~GLGizmoBase() {}
+
+ bool init() { return on_init(); }
+
+ int get_group_id() const { return m_group_id; }
+ void set_group_id(int id) { m_group_id = id; }
+
+ EState get_state() const { return m_state; }
+ void set_state(EState state) { m_state = state; on_set_state(); }
+
+ unsigned int get_texture_id() const { return m_textures[m_state].get_id(); }
+ int get_textures_size() const { return m_textures[Off].get_width(); }
+
+ int get_hover_id() const { return m_hover_id; }
+ void set_hover_id(int id);
+
+ void set_highlight_color(const float* color);
+
+ void enable_grabber(unsigned int id);
+ void disable_grabber(unsigned int id);
+
+ void start_dragging(const BoundingBoxf3& box);
+ void stop_dragging();
+ bool is_dragging() const { return m_dragging; }
+
+ void update(const Linef3& mouse_ray);
+
+ void render(const BoundingBoxf3& box) const { on_render(box); }
+ void render_for_picking(const BoundingBoxf3& box) const { on_render_for_picking(box); }
+
+protected:
+ virtual bool on_init() = 0;
+ virtual void on_set_state() {}
+ virtual void on_set_hover_id() {}
+ virtual void on_enable_grabber(unsigned int id) {}
+ virtual void on_disable_grabber(unsigned int id) {}
+ virtual void on_start_dragging(const BoundingBoxf3& box) {}
+ virtual void on_stop_dragging() {}
+ virtual void on_update(const Linef3& mouse_ray) = 0;
+ virtual void on_render(const BoundingBoxf3& box) const = 0;
+ virtual void on_render_for_picking(const BoundingBoxf3& box) const = 0;
+
+ float picking_color_component(unsigned int id) const;
+ void render_grabbers() const;
+ void render_grabbers_for_picking() const;
+
+ void set_tooltip(const std::string& tooltip) const;
+ std::string format(float value, unsigned int decimals) const;
+};
+
+class GLGizmoRotate : public GLGizmoBase
+{
+ static const float Offset;
+ static const unsigned int CircleResolution;
+ static const unsigned int AngleResolution;
+ static const unsigned int ScaleStepsCount;
+ static const float ScaleStepRad;
+ static const unsigned int ScaleLongEvery;
+ static const float ScaleLongTooth;
+ static const float ScaleShortTooth;
+ static const unsigned int SnapRegionsCount;
+ static const float GrabberOffset;
+
+public:
+ enum Axis : unsigned char
+ {
+ X,
+ Y,
+ Z
+ };
+
+private:
+ Axis m_axis;
+ double m_angle;
+
+ mutable Vec3d m_center;
+ mutable float m_radius;
+
+public:
+ GLGizmoRotate(GLCanvas3D& parent, Axis axis);
+
+ double get_angle() const { return m_angle; }
+ void set_angle(double angle);
+
+protected:
+ virtual bool on_init();
+ virtual void on_start_dragging(const BoundingBoxf3& box);
+ virtual void on_update(const Linef3& mouse_ray);
+ virtual void on_render(const BoundingBoxf3& box) const;
+ virtual void on_render_for_picking(const BoundingBoxf3& box) const;
+
+private:
+ void render_circle() const;
+ void render_scale() const;
+ void render_snap_radii() const;
+ void render_reference_radius() const;
+ void render_angle() const;
+ void render_grabber() const;
+
+ void transform_to_local() const;
+ // returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate
+ Vec3d mouse_position_in_local_plane(const Linef3& mouse_ray) const;
+};
+
+class GLGizmoRotate3D : public GLGizmoBase
+{
+ std::vector<GLGizmoRotate> m_gizmos;
+
+public:
+ explicit GLGizmoRotate3D(GLCanvas3D& parent);
+
+ double get_angle_x() const { return m_gizmos[X].get_angle(); }
+ void set_angle_x(double angle) { m_gizmos[X].set_angle(angle); }
+
+ double get_angle_y() const { return m_gizmos[Y].get_angle(); }
+ void set_angle_y(double angle) { m_gizmos[Y].set_angle(angle); }
+
+ double get_angle_z() const { return m_gizmos[Z].get_angle(); }
+ void set_angle_z(double angle) { m_gizmos[Z].set_angle(angle); }
+
+protected:
+ virtual bool on_init();
+ virtual void on_set_state()
+ {
+ for (GLGizmoRotate& g : m_gizmos)
+ {
+ g.set_state(m_state);
+ }
+ }
+ virtual void on_set_hover_id()
+ {
+ for (unsigned int i = 0; i < 3; ++i)
+ {
+ m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1);
+ }
+ }
+ virtual void on_enable_grabber(unsigned int id)
+ {
+ if ((0 <= id) && (id < 3))
+ m_gizmos[id].enable_grabber(0);
+ }
+ virtual void on_disable_grabber(unsigned int id)
+ {
+ if ((0 <= id) && (id < 3))
+ m_gizmos[id].disable_grabber(0);
+ }
+ virtual void on_start_dragging(const BoundingBoxf3& box);
+ virtual void on_stop_dragging();
+ virtual void on_update(const Linef3& mouse_ray)
+ {
+ for (GLGizmoRotate& g : m_gizmos)
+ {
+ g.update(mouse_ray);
+ }
+ }
+ virtual void on_render(const BoundingBoxf3& box) const;
+ virtual void on_render_for_picking(const BoundingBoxf3& box) const
+ {
+ for (const GLGizmoRotate& g : m_gizmos)
+ {
+ g.render_for_picking(box);
+ }
+ }
+};
+
+class GLGizmoScale3D : public GLGizmoBase
+{
+ static const float Offset;
+
+ mutable BoundingBoxf3 m_box;
+
+ Vec3d m_scale;
+
+ Vec3d m_starting_scale;
+ Vec3d m_starting_drag_position;
+ bool m_show_starting_box;
+ BoundingBoxf3 m_starting_box;
+
+public:
+ explicit GLGizmoScale3D(GLCanvas3D& parent);
+
+ double get_scale_x() const { return m_scale(0); }
+ void set_scale_x(double scale) { m_starting_scale(0) = scale; }
+
+ double get_scale_y() const { return m_scale(1); }
+ void set_scale_y(double scale) { m_starting_scale(1) = scale; }
+
+ double get_scale_z() const { return m_scale(2); }
+ void set_scale_z(double scale) { m_starting_scale(2) = scale; }
+
+ void set_scale(double scale) { m_starting_scale = scale * Vec3d::Ones(); }
+
+protected:
+ virtual bool on_init();
+ virtual void on_start_dragging(const BoundingBoxf3& box);
+ virtual void on_stop_dragging() { m_show_starting_box = false; }
+ virtual void on_update(const Linef3& mouse_ray);
+ virtual void on_render(const BoundingBoxf3& box) const;
+ virtual void on_render_for_picking(const BoundingBoxf3& box) const;
+
+private:
+ void render_box(const BoundingBoxf3& box) const;
+ void render_grabbers_connection(unsigned int id_1, unsigned int id_2) const;
+
+ void do_scale_x(const Linef3& mouse_ray);
+ void do_scale_y(const Linef3& mouse_ray);
+ void do_scale_z(const Linef3& mouse_ray);
+ void do_scale_uniform(const Linef3& mouse_ray);
+
+ double calc_ratio(unsigned int preferred_plane_id, const Linef3& mouse_ray, const Vec3d& center) const;
+};
+
+class GLGizmoMove3D : public GLGizmoBase
+{
+ static const double Offset;
+
+ Vec3d m_position;
+ Vec3d m_starting_drag_position;
+ Vec3d m_starting_box_center;
+
+public:
+ explicit GLGizmoMove3D(GLCanvas3D& parent);
+
+ const Vec3d& get_position() const { return m_position; }
+ void set_position(const Vec3d& position) { m_position = position; }
+
+protected:
+ virtual bool on_init();
+ virtual void on_start_dragging(const BoundingBoxf3& box);
+ virtual void on_update(const Linef3& mouse_ray);
+ virtual void on_render(const BoundingBoxf3& box) const;
+ virtual void on_render_for_picking(const BoundingBoxf3& box) const;
+
+private:
+ double calc_displacement(unsigned int preferred_plane_id, const Linef3& mouse_ray) const;
+};
+
+class GLGizmoFlatten : public GLGizmoBase
+{
+// This gizmo does not use grabbers. The m_hover_id relates to polygon managed by the class itself.
+
+private:
+ mutable Vec3d m_normal;
+
+ struct PlaneData {
+ std::vector<Vec3d> vertices;
+ Vec3d normal;
+ float area;
+ };
+ struct SourceDataSummary {
+ std::vector<BoundingBoxf3> bounding_boxes; // bounding boxes of convex hulls of individual volumes
+ float scaling_factor;
+ float rotation;
+ Vec3d mesh_first_point;
+ };
+
+ // This holds information to decide whether recalculation is necessary:
+ SourceDataSummary m_source_data;
+
+ std::vector<PlaneData> m_planes;
+ std::vector<Vec2d> m_instances_positions;
+ Vec3d m_starting_center;
+ const ModelObject* m_model_object = nullptr;
+
+ void update_planes();
+ bool is_plane_update_necessary() const;
+
+public:
+ explicit GLGizmoFlatten(GLCanvas3D& parent);
+
+ void set_flattening_data(const ModelObject* model_object);
+ Vec3d get_flattening_normal() const;
+
+protected:
+ virtual bool on_init();
+ virtual void on_start_dragging(const BoundingBoxf3& box);
+ virtual void on_update(const Linef3& mouse_ray) {}
+ virtual void on_render(const BoundingBoxf3& box) const;
+ virtual void on_render_for_picking(const BoundingBoxf3& box) const;
+ virtual void on_set_state()
+ {
+ if (m_state == On && is_plane_update_necessary())
+ update_planes();
+ }
+};
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif // slic3r_GLGizmo_hpp_
+
diff --git a/xs/src/slic3r/GUI/GLShader.cpp b/xs/src/slic3r/GUI/GLShader.cpp
index ce9a80f05..e2995f7c3 100644
--- a/xs/src/slic3r/GUI/GLShader.cpp
+++ b/xs/src/slic3r/GUI/GLShader.cpp
@@ -2,6 +2,9 @@
#include "GLShader.hpp"
+#include "../../libslic3r/Utils.hpp"
+#include <boost/nowide/fstream.hpp>
+
#include <string>
#include <utility>
#include <assert.h>
@@ -22,7 +25,7 @@ inline std::string gl_get_string_safe(GLenum param)
return std::string(value ? value : "N/A");
}
-bool GLShader::load(const char *fragment_shader, const char *vertex_shader)
+bool GLShader::load_from_text(const char *fragment_shader, const char *vertex_shader)
{
std::string gl_version = gl_get_string_safe(GL_VERSION);
int major = atoi(gl_version.c_str());
@@ -123,6 +126,41 @@ bool GLShader::load(const char *fragment_shader, const char *vertex_shader)
return true;
}
+bool GLShader::load_from_file(const char* fragment_shader_filename, const char* vertex_shader_filename)
+{
+ const std::string& path = resources_dir() + "/shaders/";
+
+ boost::nowide::ifstream vs(path + std::string(vertex_shader_filename), boost::nowide::ifstream::binary);
+ if (!vs.good())
+ return false;
+
+ vs.seekg(0, vs.end);
+ int file_length = vs.tellg();
+ vs.seekg(0, vs.beg);
+ std::string vertex_shader(file_length, '\0');
+ vs.read(const_cast<char*>(vertex_shader.data()), file_length);
+ if (!vs.good())
+ return false;
+
+ vs.close();
+
+ boost::nowide::ifstream fs(path + std::string(fragment_shader_filename), boost::nowide::ifstream::binary);
+ if (!fs.good())
+ return false;
+
+ fs.seekg(0, fs.end);
+ file_length = fs.tellg();
+ fs.seekg(0, fs.beg);
+ std::string fragment_shader(file_length, '\0');
+ fs.read(const_cast<char*>(fragment_shader.data()), file_length);
+ if (!fs.good())
+ return false;
+
+ fs.close();
+
+ return load_from_text(fragment_shader.c_str(), vertex_shader.c_str());
+}
+
void GLShader::release()
{
if (this->shader_program_id) {
@@ -176,6 +214,17 @@ bool GLShader::set_uniform(const char *name, float value) const
return false;
}
+bool GLShader::set_uniform(const char* name, const float* matrix) const
+{
+ int id = get_uniform_location(name);
+ if (id >= 0)
+ {
+ ::glUniformMatrix4fv(id, 1, GL_FALSE, (const GLfloat*)matrix);
+ return true;
+ }
+ return false;
+}
+
/*
# Set shader vector
sub SetVector
diff --git a/xs/src/slic3r/GUI/GLShader.hpp b/xs/src/slic3r/GUI/GLShader.hpp
index d91463f19..803b2f154 100644
--- a/xs/src/slic3r/GUI/GLShader.hpp
+++ b/xs/src/slic3r/GUI/GLShader.hpp
@@ -16,13 +16,16 @@ public:
{}
~GLShader();
- bool load(const char *fragment_shader, const char *vertex_shader);
+ bool load_from_text(const char *fragment_shader, const char *vertex_shader);
+ bool load_from_file(const char* fragment_shader_filename, const char* vertex_shader_filename);
+
void release();
int get_attrib_location(const char *name) const;
int get_uniform_location(const char *name) const;
bool set_uniform(const char *name, float value) const;
+ bool set_uniform(const char* name, const float* matrix) const;
void enable() const;
void disable() const;
diff --git a/xs/src/slic3r/GUI/GLTexture.cpp b/xs/src/slic3r/GUI/GLTexture.cpp
new file mode 100644
index 000000000..235e3d93b
--- /dev/null
+++ b/xs/src/slic3r/GUI/GLTexture.cpp
@@ -0,0 +1,199 @@
+#include "GLTexture.hpp"
+
+#include <GL/glew.h>
+
+#include <wx/image.h>
+
+#include <boost/filesystem.hpp>
+
+#include <vector>
+#include <algorithm>
+
+namespace Slic3r {
+namespace GUI {
+
+GLTexture::Quad_UVs GLTexture::FullTextureUVs = { { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f }, { 0.0f, 0.0f } };
+
+GLTexture::GLTexture()
+ : m_id(0)
+ , m_width(0)
+ , m_height(0)
+ , m_source("")
+{
+}
+
+GLTexture::~GLTexture()
+{
+ reset();
+}
+
+bool GLTexture::load_from_file(const std::string& filename, bool generate_mipmaps)
+{
+ reset();
+
+ if (!boost::filesystem::exists(filename))
+ return false;
+
+ // Load a PNG with an alpha channel.
+ wxImage image;
+ if (!image.LoadFile(filename, wxBITMAP_TYPE_PNG))
+ {
+ reset();
+ return false;
+ }
+
+ m_width = image.GetWidth();
+ m_height = image.GetHeight();
+ int n_pixels = m_width * m_height;
+
+ if (n_pixels <= 0)
+ {
+ reset();
+ return false;
+ }
+
+ // Get RGB & alpha raw data from wxImage, pack them into an array.
+ unsigned char* img_rgb = image.GetData();
+ if (img_rgb == nullptr)
+ {
+ reset();
+ return false;
+ }
+
+ unsigned char* img_alpha = image.GetAlpha();
+
+ std::vector<unsigned char> data(n_pixels * 4, 0);
+ for (int i = 0; i < n_pixels; ++i)
+ {
+ int data_id = i * 4;
+ int img_id = i * 3;
+ data[data_id + 0] = img_rgb[img_id + 0];
+ data[data_id + 1] = img_rgb[img_id + 1];
+ data[data_id + 2] = img_rgb[img_id + 2];
+ data[data_id + 3] = (img_alpha != nullptr) ? img_alpha[i] : 255;
+ }
+
+ // sends data to gpu
+ ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ ::glGenTextures(1, &m_id);
+ ::glBindTexture(GL_TEXTURE_2D, m_id);
+ ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
+ if (generate_mipmaps)
+ {
+ // we manually generate mipmaps because glGenerateMipmap() function is not reliable on all graphics cards
+ unsigned int levels_count = _generate_mipmaps(image);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1 + levels_count);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ }
+ else
+ {
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
+ }
+ ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+
+ m_source = filename;
+ return true;
+}
+
+void GLTexture::reset()
+{
+ if (m_id != 0)
+ ::glDeleteTextures(1, &m_id);
+
+ m_id = 0;
+ m_width = 0;
+ m_height = 0;
+ m_source = "";
+}
+
+unsigned int GLTexture::get_id() const
+{
+ return m_id;
+}
+
+int GLTexture::get_width() const
+{
+ return m_width;
+}
+
+int GLTexture::get_height() const
+{
+ return m_height;
+}
+
+const std::string& GLTexture::get_source() const
+{
+ return m_source;
+}
+
+void GLTexture::render_texture(unsigned int tex_id, float left, float right, float bottom, float top)
+{
+ render_sub_texture(tex_id, left, right, bottom, top, FullTextureUVs);
+}
+
+void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right, float bottom, float top, const GLTexture::Quad_UVs& uvs)
+{
+ ::glEnable(GL_BLEND);
+ ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ ::glEnable(GL_TEXTURE_2D);
+ ::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ ::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id);
+
+ ::glBegin(GL_QUADS);
+ ::glTexCoord2f(uvs.left_bottom.u, uvs.left_bottom.v); ::glVertex2f(left, bottom);
+ ::glTexCoord2f(uvs.right_bottom.u, uvs.right_bottom.v); ::glVertex2f(right, bottom);
+ ::glTexCoord2f(uvs.right_top.u, uvs.right_top.v); ::glVertex2f(right, top);
+ ::glTexCoord2f(uvs.left_top.u, uvs.left_top.v); ::glVertex2f(left, top);
+ ::glEnd();
+
+ ::glBindTexture(GL_TEXTURE_2D, 0);
+
+ ::glDisable(GL_TEXTURE_2D);
+ ::glDisable(GL_BLEND);
+}
+
+unsigned int GLTexture::_generate_mipmaps(wxImage& image)
+{
+ int w = image.GetWidth();
+ int h = image.GetHeight();
+ GLint level = 0;
+ std::vector<unsigned char> data(w * h * 4, 0);
+
+ while ((w > 1) || (h > 1))
+ {
+ ++level;
+
+ w = std::max(w / 2, 1);
+ h = std::max(h / 2, 1);
+
+ int n_pixels = w * h;
+
+ image = image.ResampleBicubic(w, h);
+
+ unsigned char* img_rgb = image.GetData();
+ unsigned char* img_alpha = image.GetAlpha();
+
+ data.resize(n_pixels * 4);
+ for (int i = 0; i < n_pixels; ++i)
+ {
+ int data_id = i * 4;
+ int img_id = i * 3;
+ data[data_id + 0] = img_rgb[img_id + 0];
+ data[data_id + 1] = img_rgb[img_id + 1];
+ data[data_id + 2] = img_rgb[img_id + 2];
+ data[data_id + 3] = (img_alpha != nullptr) ? img_alpha[i] : 255;
+ }
+
+ ::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data());
+ }
+
+ return (unsigned int)level;
+}
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/GLTexture.hpp b/xs/src/slic3r/GUI/GLTexture.hpp
new file mode 100644
index 000000000..e027bd152
--- /dev/null
+++ b/xs/src/slic3r/GUI/GLTexture.hpp
@@ -0,0 +1,60 @@
+#ifndef slic3r_GLTexture_hpp_
+#define slic3r_GLTexture_hpp_
+
+#include <string>
+
+class wxImage;
+
+namespace Slic3r {
+namespace GUI {
+
+ class GLTexture
+ {
+ public:
+ struct UV
+ {
+ float u;
+ float v;
+ };
+
+ struct Quad_UVs
+ {
+ UV left_bottom;
+ UV right_bottom;
+ UV right_top;
+ UV left_top;
+ };
+
+ static Quad_UVs FullTextureUVs;
+
+ protected:
+ unsigned int m_id;
+ int m_width;
+ int m_height;
+ std::string m_source;
+
+ public:
+ GLTexture();
+ virtual ~GLTexture();
+
+ bool load_from_file(const std::string& filename, bool generate_mipmaps);
+ void reset();
+
+ unsigned int get_id() const;
+ int get_width() const;
+ int get_height() const;
+
+ const std::string& get_source() const;
+
+ static void render_texture(unsigned int tex_id, float left, float right, float bottom, float top);
+ static void render_sub_texture(unsigned int tex_id, float left, float right, float bottom, float top, const Quad_UVs& uvs);
+
+ protected:
+ unsigned int _generate_mipmaps(wxImage& image);
+ };
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif // slic3r_GLTexture_hpp_
+
diff --git a/xs/src/slic3r/GUI/GLToolbar.cpp b/xs/src/slic3r/GUI/GLToolbar.cpp
new file mode 100644
index 000000000..388868b12
--- /dev/null
+++ b/xs/src/slic3r/GUI/GLToolbar.cpp
@@ -0,0 +1,722 @@
+#include "../../libslic3r/Point.hpp"
+#include "GLToolbar.hpp"
+
+#include "../../libslic3r/libslic3r.h"
+#include "../../slic3r/GUI/GLCanvas3D.hpp"
+
+#include <GL/glew.h>
+
+#include <wx/bitmap.h>
+#include <wx/dcmemory.h>
+#include <wx/settings.h>
+
+namespace Slic3r {
+namespace GUI {
+
+GLToolbarItem::Data::Data()
+ : name("")
+ , tooltip("")
+ , sprite_id(-1)
+ , is_toggable(false)
+ , action_callback(nullptr)
+{
+}
+
+GLToolbarItem::GLToolbarItem(GLToolbarItem::EType type, const GLToolbarItem::Data& data)
+ : m_type(type)
+ , m_state(Disabled)
+ , m_data(data)
+{
+}
+
+GLToolbarItem::EState GLToolbarItem::get_state() const
+{
+ return m_state;
+}
+
+void GLToolbarItem::set_state(GLToolbarItem::EState state)
+{
+ m_state = state;
+}
+
+const std::string& GLToolbarItem::get_name() const
+{
+ return m_data.name;
+}
+
+const std::string& GLToolbarItem::get_tooltip() const
+{
+ return m_data.tooltip;
+}
+
+void GLToolbarItem::do_action()
+{
+ if (m_data.action_callback != nullptr)
+ m_data.action_callback->call();
+}
+
+bool GLToolbarItem::is_enabled() const
+{
+ return m_state != Disabled;
+}
+
+bool GLToolbarItem::is_hovered() const
+{
+ return (m_state == Hover) || (m_state == HoverPressed);
+}
+
+bool GLToolbarItem::is_pressed() const
+{
+ return (m_state == Pressed) || (m_state == HoverPressed);
+}
+
+bool GLToolbarItem::is_toggable() const
+{
+ return m_data.is_toggable;
+}
+
+bool GLToolbarItem::is_separator() const
+{
+ return m_type == Separator;
+}
+
+void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const
+{
+ GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(texture_size, border_size, icon_size, gap_size));
+}
+
+GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const
+{
+ GLTexture::Quad_UVs uvs;
+
+ float inv_texture_size = (texture_size != 0) ? 1.0f / (float)texture_size : 0.0f;
+
+ float scaled_icon_size = (float)icon_size * inv_texture_size;
+ float scaled_border_size = (float)border_size * inv_texture_size;
+ float scaled_gap_size = (float)gap_size * inv_texture_size;
+ float stride = scaled_icon_size + scaled_gap_size;
+
+ float left = scaled_border_size + (float)m_state * stride;
+ float right = left + scaled_icon_size;
+ float top = scaled_border_size + (float)m_data.sprite_id * stride;
+ float bottom = top + scaled_icon_size;
+
+ uvs.left_top = { left, top };
+ uvs.left_bottom = { left, bottom };
+ uvs.right_bottom = { right, bottom };
+ uvs.right_top = { right, top };
+
+ return uvs;
+}
+
+GLToolbar::ItemsIconsTexture::ItemsIconsTexture()
+ : items_icon_size(0)
+ , items_icon_border_size(0)
+ , items_icon_gap_size(0)
+{
+}
+
+GLToolbar::Layout::Layout()
+ : type(Horizontal)
+ , top(0.0f)
+ , left(0.0f)
+ , separator_size(0.0f)
+ , gap_size(0.0f)
+{
+}
+
+GLToolbar::GLToolbar(GLCanvas3D& parent)
+ : m_parent(parent)
+ , m_enabled(false)
+{
+}
+
+bool GLToolbar::init(const std::string& icons_texture_filename, unsigned int items_icon_size, unsigned int items_icon_border_size, unsigned int items_icon_gap_size)
+{
+ std::string path = resources_dir() + "/icons/";
+ bool res = !icons_texture_filename.empty() && m_icons_texture.texture.load_from_file(path + icons_texture_filename, false);
+ if (res)
+ {
+ m_icons_texture.items_icon_size = items_icon_size;
+ m_icons_texture.items_icon_border_size = items_icon_border_size;
+ m_icons_texture.items_icon_gap_size = items_icon_gap_size;
+ }
+
+ return res;
+}
+
+GLToolbar::Layout::Type GLToolbar::get_layout_type() const
+{
+ return m_layout.type;
+}
+
+void GLToolbar::set_layout_type(GLToolbar::Layout::Type type)
+{
+ m_layout.type = type;
+}
+
+void GLToolbar::set_position(float top, float left)
+{
+ m_layout.top = top;
+ m_layout.left = left;
+}
+
+void GLToolbar::set_separator_size(float size)
+{
+ m_layout.separator_size = size;
+}
+
+void GLToolbar::set_gap_size(float size)
+{
+ m_layout.gap_size = size;
+}
+
+bool GLToolbar::is_enabled() const
+{
+ return m_enabled;
+}
+
+void GLToolbar::set_enabled(bool enable)
+{
+ m_enabled = true;
+}
+
+bool GLToolbar::add_item(const GLToolbarItem::Data& data)
+{
+ GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Action, data);
+ if (item == nullptr)
+ return false;
+
+ m_items.push_back(item);
+ return true;
+}
+
+bool GLToolbar::add_separator()
+{
+ GLToolbarItem::Data data;
+ GLToolbarItem* item = new GLToolbarItem(GLToolbarItem::Separator, data);
+ if (item == nullptr)
+ return false;
+
+ m_items.push_back(item);
+ return true;
+}
+
+float GLToolbar::get_width() const
+{
+ switch (m_layout.type)
+ {
+ default:
+ case Layout::Horizontal:
+ {
+ return get_width_horizontal();
+ }
+ case Layout::Vertical:
+ {
+ return get_width_vertical();
+ }
+ }
+}
+
+float GLToolbar::get_height() const
+{
+ switch (m_layout.type)
+ {
+ default:
+ case Layout::Horizontal:
+ {
+ return get_height_horizontal();
+ }
+ case Layout::Vertical:
+ {
+ return get_height_vertical();
+ }
+ }
+}
+
+void GLToolbar::enable_item(const std::string& name)
+{
+ for (GLToolbarItem* item : m_items)
+ {
+ if ((item->get_name() == name) && (item->get_state() == GLToolbarItem::Disabled))
+ {
+ item->set_state(GLToolbarItem::Normal);
+ return;
+ }
+ }
+}
+
+void GLToolbar::disable_item(const std::string& name)
+{
+ for (GLToolbarItem* item : m_items)
+ {
+ if (item->get_name() == name)
+ {
+ item->set_state(GLToolbarItem::Disabled);
+ return;
+ }
+ }
+}
+
+bool GLToolbar::is_item_pressed(const std::string& name) const
+{
+ for (GLToolbarItem* item : m_items)
+ {
+ if (item->get_name() == name)
+ return item->is_pressed();
+ }
+
+ return false;
+}
+
+void GLToolbar::update_hover_state(const Vec2d& mouse_pos)
+{
+ if (!m_enabled)
+ return;
+
+ switch (m_layout.type)
+ {
+ default:
+ case Layout::Horizontal:
+ {
+ update_hover_state_horizontal(mouse_pos);
+ break;
+ }
+ case Layout::Vertical:
+ {
+ update_hover_state_vertical(mouse_pos);
+ break;
+ }
+ }
+}
+
+int GLToolbar::contains_mouse(const Vec2d& mouse_pos) const
+{
+ if (!m_enabled)
+ return -1;
+
+ switch (m_layout.type)
+ {
+ default:
+ case Layout::Horizontal:
+ {
+ return contains_mouse_horizontal(mouse_pos);
+ }
+ case Layout::Vertical:
+ {
+ return contains_mouse_vertical(mouse_pos);
+ }
+ }
+}
+
+void GLToolbar::do_action(unsigned int item_id)
+{
+ if (item_id < (unsigned int)m_items.size())
+ {
+ GLToolbarItem* item = m_items[item_id];
+ if ((item != nullptr) && !item->is_separator() && item->is_hovered())
+ {
+ if (item->is_toggable())
+ {
+ GLToolbarItem::EState state = item->get_state();
+ if (state == GLToolbarItem::Hover)
+ item->set_state(GLToolbarItem::HoverPressed);
+ else if (state == GLToolbarItem::HoverPressed)
+ item->set_state(GLToolbarItem::Hover);
+
+ m_parent.render();
+ item->do_action();
+ }
+ else
+ {
+ item->set_state(GLToolbarItem::HoverPressed);
+ m_parent.render();
+ item->do_action();
+ if (item->get_state() != GLToolbarItem::Disabled)
+ {
+ // the item may get disabled during the action, if not, set it back to hover state
+ item->set_state(GLToolbarItem::Hover);
+ m_parent.render();
+ }
+ }
+ }
+ }
+}
+
+void GLToolbar::render() const
+{
+ if (!m_enabled || m_items.empty())
+ return;
+
+ ::glDisable(GL_DEPTH_TEST);
+
+ ::glPushMatrix();
+ ::glLoadIdentity();
+
+ switch (m_layout.type)
+ {
+ default:
+ case Layout::Horizontal:
+ {
+ render_horizontal();
+ break;
+ }
+ case Layout::Vertical:
+ {
+ render_vertical();
+ break;
+ }
+ }
+
+ ::glPopMatrix();
+}
+
+float GLToolbar::get_width_horizontal() const
+{
+ return get_main_size();
+}
+
+float GLToolbar::get_width_vertical() const
+{
+ return m_icons_texture.items_icon_size;
+}
+
+float GLToolbar::get_height_horizontal() const
+{
+ return m_icons_texture.items_icon_size;
+}
+
+float GLToolbar::get_height_vertical() const
+{
+ return get_main_size();
+}
+
+float GLToolbar::get_main_size() const
+{
+ float size = 0.0f;
+ for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i)
+ {
+ if (m_items[i]->is_separator())
+ size += m_layout.separator_size;
+ else
+ size += (float)m_icons_texture.items_icon_size;
+ }
+
+ if (m_items.size() > 1)
+ size += ((float)m_items.size() - 1.0f) * m_layout.gap_size;
+
+ return size;
+}
+
+void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos)
+{
+ float zoom = m_parent.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+
+ Size cnv_size = m_parent.get_canvas_size();
+ Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
+
+ float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
+ float scaled_separator_size = m_layout.separator_size * inv_zoom;
+ float scaled_gap_size = m_layout.gap_size * inv_zoom;
+
+ float separator_stride = scaled_separator_size + scaled_gap_size;
+ float icon_stride = scaled_icons_size + scaled_gap_size;
+
+ float left = m_layout.left;
+ float top = m_layout.top;
+
+ std::string tooltip = "";
+
+ for (GLToolbarItem* item : m_items)
+ {
+ if (item->is_separator())
+ left += separator_stride;
+ else
+ {
+ float right = left + scaled_icons_size;
+ float bottom = top - scaled_icons_size;
+
+ GLToolbarItem::EState state = item->get_state();
+ bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top);
+
+ switch (state)
+ {
+ case GLToolbarItem::Normal:
+ {
+ if (inside)
+ item->set_state(GLToolbarItem::Hover);
+
+ break;
+ }
+ case GLToolbarItem::Hover:
+ {
+ if (inside)
+ tooltip = item->get_tooltip();
+ else
+ item->set_state(GLToolbarItem::Normal);
+
+ break;
+ }
+ case GLToolbarItem::Pressed:
+ {
+ if (inside)
+ item->set_state(GLToolbarItem::HoverPressed);
+
+ break;
+ }
+ case GLToolbarItem::HoverPressed:
+ {
+ if (inside)
+ tooltip = item->get_tooltip();
+ else
+ item->set_state(GLToolbarItem::Pressed);
+
+ break;
+ }
+ default:
+ case GLToolbarItem::Disabled:
+ {
+ break;
+ }
+ }
+
+ left += icon_stride;
+ }
+ }
+
+ m_parent.set_tooltip(tooltip);
+}
+
+void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos)
+{
+ float zoom = m_parent.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+
+ Size cnv_size = m_parent.get_canvas_size();
+ Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
+
+ float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
+ float scaled_separator_size = m_layout.separator_size * inv_zoom;
+ float scaled_gap_size = m_layout.gap_size * inv_zoom;
+
+ float separator_stride = scaled_separator_size + scaled_gap_size;
+ float icon_stride = scaled_icons_size + scaled_gap_size;
+
+ float left = m_layout.left;
+ float top = m_layout.top;
+
+ std::string tooltip = "";
+
+ for (GLToolbarItem* item : m_items)
+ {
+ if (item->is_separator())
+ top -= separator_stride;
+ else
+ {
+ float right = left + scaled_icons_size;
+ float bottom = top - scaled_icons_size;
+
+ GLToolbarItem::EState state = item->get_state();
+ bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top);
+
+ switch (state)
+ {
+ case GLToolbarItem::Normal:
+ {
+ if (inside)
+ item->set_state(GLToolbarItem::Hover);
+
+ break;
+ }
+ case GLToolbarItem::Hover:
+ {
+ if (inside)
+ tooltip = item->get_tooltip();
+ else
+ item->set_state(GLToolbarItem::Normal);
+
+ break;
+ }
+ case GLToolbarItem::Pressed:
+ {
+ if (inside)
+ item->set_state(GLToolbarItem::HoverPressed);
+
+ break;
+ }
+ case GLToolbarItem::HoverPressed:
+ {
+ if (inside)
+ tooltip = item->get_tooltip();
+ else
+ item->set_state(GLToolbarItem::Pressed);
+
+ break;
+ }
+ default:
+ case GLToolbarItem::Disabled:
+ {
+ break;
+ }
+ }
+
+ top -= icon_stride;
+ }
+ }
+
+ m_parent.set_tooltip(tooltip);
+}
+
+int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos) const
+{
+ float zoom = m_parent.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+
+ Size cnv_size = m_parent.get_canvas_size();
+ Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
+
+ float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
+ float scaled_separator_size = m_layout.separator_size * inv_zoom;
+ float scaled_gap_size = m_layout.gap_size * inv_zoom;
+
+ float separator_stride = scaled_separator_size + scaled_gap_size;
+ float icon_stride = scaled_icons_size + scaled_gap_size;
+
+ float left = m_layout.left;
+ float top = m_layout.top;
+
+ int id = -1;
+
+ for (GLToolbarItem* item : m_items)
+ {
+ ++id;
+
+ if (item->is_separator())
+ left += separator_stride;
+ else
+ {
+ float right = left + scaled_icons_size;
+ float bottom = top - scaled_icons_size;
+
+ if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
+ return id;
+
+ left += icon_stride;
+ }
+ }
+
+ return -1;
+}
+
+int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos) const
+{
+ float zoom = m_parent.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+
+ Size cnv_size = m_parent.get_canvas_size();
+ Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
+
+ float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
+ float scaled_separator_size = m_layout.separator_size * inv_zoom;
+ float scaled_gap_size = m_layout.gap_size * inv_zoom;
+
+ float separator_stride = scaled_separator_size + scaled_gap_size;
+ float icon_stride = scaled_icons_size + scaled_gap_size;
+
+ float left = m_layout.left;
+ float top = m_layout.top;
+
+ int id = -1;
+
+ for (GLToolbarItem* item : m_items)
+ {
+ ++id;
+
+ if (item->is_separator())
+ top -= separator_stride;
+ else
+ {
+ float right = left + scaled_icons_size;
+ float bottom = top - scaled_icons_size;
+
+ if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
+ return id;
+
+ top -= icon_stride;
+ }
+ }
+
+ return -1;
+}
+
+void GLToolbar::render_horizontal() const
+{
+ unsigned int tex_id = m_icons_texture.texture.get_id();
+ int tex_size = m_icons_texture.texture.get_width();
+
+ if ((tex_id == 0) || (tex_size <= 0))
+ return;
+
+ float zoom = m_parent.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+
+ float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
+ float scaled_separator_size = m_layout.separator_size * inv_zoom;
+ float scaled_gap_size = m_layout.gap_size * inv_zoom;
+
+ float separator_stride = scaled_separator_size + scaled_gap_size;
+ float icon_stride = scaled_icons_size + scaled_gap_size;
+
+ float left = m_layout.left;
+ float top = m_layout.top;
+
+ // renders icons
+ for (const GLToolbarItem* item : m_items)
+ {
+ if (item->is_separator())
+ left += separator_stride;
+ else
+ {
+ item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_size, m_icons_texture.items_icon_border_size, m_icons_texture.items_icon_size, m_icons_texture.items_icon_gap_size);
+ left += icon_stride;
+ }
+ }
+}
+
+void GLToolbar::render_vertical() const
+{
+ unsigned int tex_id = m_icons_texture.texture.get_id();
+ int tex_size = m_icons_texture.texture.get_width();
+
+ if ((tex_id == 0) || (tex_size <= 0))
+ return;
+
+ float zoom = m_parent.get_camera_zoom();
+ float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+
+ float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
+ float scaled_separator_size = m_layout.separator_size * inv_zoom;
+ float scaled_gap_size = m_layout.gap_size * inv_zoom;
+
+ float separator_stride = scaled_separator_size + scaled_gap_size;
+ float icon_stride = scaled_icons_size + scaled_gap_size;
+
+ float left = m_layout.left;
+ float top = m_layout.top;
+
+ // renders icons
+ for (const GLToolbarItem* item : m_items)
+ {
+ if (item->is_separator())
+ top -= separator_stride;
+ else
+ {
+ item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_size, m_icons_texture.items_icon_border_size, m_icons_texture.items_icon_size, m_icons_texture.items_icon_gap_size);
+ top -= icon_stride;
+ }
+ }
+}
+
+} // namespace GUI
+} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/GLToolbar.hpp b/xs/src/slic3r/GUI/GLToolbar.hpp
new file mode 100644
index 000000000..c1501b10c
--- /dev/null
+++ b/xs/src/slic3r/GUI/GLToolbar.hpp
@@ -0,0 +1,175 @@
+#ifndef slic3r_GLToolbar_hpp_
+#define slic3r_GLToolbar_hpp_
+
+#include "../../slic3r/GUI/GLTexture.hpp"
+#include "../../libslic3r/Utils.hpp"
+
+#include <string>
+#include <vector>
+
+namespace Slic3r {
+namespace GUI {
+
+class GLCanvas3D;
+
+class GLToolbarItem
+{
+public:
+ enum EType : unsigned char
+ {
+ Action,
+ Separator,
+ Num_Types
+ };
+
+ enum EState : unsigned char
+ {
+ Normal,
+ Pressed,
+ Disabled,
+ Hover,
+ HoverPressed,
+ Num_States
+ };
+
+ struct Data
+ {
+ std::string name;
+ std::string tooltip;
+ unsigned int sprite_id;
+ bool is_toggable;
+ PerlCallback* action_callback;
+
+ Data();
+ };
+
+private:
+ EType m_type;
+ EState m_state;
+ Data m_data;
+
+public:
+ GLToolbarItem(EType type, const Data& data);
+
+ EState get_state() const;
+ void set_state(EState state);
+
+ const std::string& get_name() const;
+ const std::string& get_tooltip() const;
+
+ void do_action();
+
+ bool is_enabled() const;
+ bool is_hovered() const;
+ bool is_pressed() const;
+
+ bool is_toggable() const;
+ bool is_separator() const;
+
+ void render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const;
+
+private:
+ GLTexture::Quad_UVs get_uvs(unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const;
+};
+
+class GLToolbar
+{
+public:
+ // items icon textures are assumed to be square and all with the same size in pixels, no internal check is done
+ // icons are layed-out into the texture starting from the top-left corner in the same order as enum GLToolbarItem::EState
+ // from left to right
+ struct ItemsIconsTexture
+ {
+ GLTexture texture;
+ // size of the square icons, in pixels
+ unsigned int items_icon_size;
+ // distance from the border, in pixels
+ unsigned int items_icon_border_size;
+ // distance between two adjacent icons (to avoid filtering artifacts), in pixels
+ unsigned int items_icon_gap_size;
+
+ ItemsIconsTexture();
+ };
+
+ struct Layout
+ {
+ enum Type : unsigned char
+ {
+ Horizontal,
+ Vertical,
+ Num_Types
+ };
+
+ Type type;
+ float top;
+ float left;
+ float separator_size;
+ float gap_size;
+
+ Layout();
+ };
+
+private:
+ typedef std::vector<GLToolbarItem*> ItemsList;
+
+ GLCanvas3D& m_parent;
+ bool m_enabled;
+ ItemsIconsTexture m_icons_texture;
+ Layout m_layout;
+
+ ItemsList m_items;
+
+public:
+ explicit GLToolbar(GLCanvas3D& parent);
+
+ bool init(const std::string& icons_texture_filename, unsigned int items_icon_size, unsigned int items_icon_border_size, unsigned int items_icon_gap_size);
+
+ Layout::Type get_layout_type() const;
+ void set_layout_type(Layout::Type type);
+
+ void set_position(float top, float left);
+ void set_separator_size(float size);
+ void set_gap_size(float size);
+
+ bool is_enabled() const;
+ void set_enabled(bool enable);
+
+ bool add_item(const GLToolbarItem::Data& data);
+ bool add_separator();
+
+ float get_width() const;
+ float get_height() const;
+
+ void enable_item(const std::string& name);
+ void disable_item(const std::string& name);
+
+ bool is_item_pressed(const std::string& name) const;
+
+ void update_hover_state(const Vec2d& mouse_pos);
+
+ // returns the id of the item under the given mouse position or -1 if none
+ int contains_mouse(const Vec2d& mouse_pos) const;
+
+ void do_action(unsigned int item_id);
+
+ void render() const;
+
+private:
+ float get_width_horizontal() const;
+ float get_width_vertical() const;
+ float get_height_horizontal() const;
+ float get_height_vertical() const;
+ float get_main_size() const;
+ void update_hover_state_horizontal(const Vec2d& mouse_pos);
+ void update_hover_state_vertical(const Vec2d& mouse_pos);
+ int contains_mouse_horizontal(const Vec2d& mouse_pos) const;
+ int contains_mouse_vertical(const Vec2d& mouse_pos) const;
+
+ void render_horizontal() const;
+ void render_vertical() const;
+};
+
+} // namespace GUI
+} // namespace Slic3r
+
+#endif // slic3r_GLToolbar_hpp_
diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp
index 270a5d198..dda2cb953 100644
--- a/xs/src/slic3r/GUI/GUI.cpp
+++ b/xs/src/slic3r/GUI/GUI.cpp
@@ -1,12 +1,11 @@
#include "GUI.hpp"
+#include "WipeTowerDialog.hpp"
#include <assert.h>
+#include <cmath>
-#include <boost/algorithm/string/predicate.hpp>
-#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/algorithm/string/split.hpp>
-#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
#if __APPLE__
@@ -23,7 +22,6 @@
#undef max
#endif
#include "boost/nowide/convert.hpp"
-#pragma comment(lib, "user32.lib")
#endif
#include <wx/app.h>
@@ -37,15 +35,35 @@
#include <wx/sizer.h>
#include <wx/combo.h>
#include <wx/window.h>
+#include <wx/msgdlg.h>
+#include <wx/settings.h>
+#include <wx/display.h>
+#include <wx/collpane.h>
+#include <wx/wupdlock.h>
#include "wxExtensions.hpp"
#include "Tab.hpp"
#include "TabIface.hpp"
+#include "AboutDialog.hpp"
#include "AppConfig.hpp"
+#include "ConfigSnapshotDialog.hpp"
#include "Utils.hpp"
+#include "MsgDialog.hpp"
+#include "ConfigWizard.hpp"
#include "Preferences.hpp"
#include "PresetBundle.hpp"
+#include "UpdateDialogs.hpp"
+#include "FirmwareDialog.hpp"
+#include "GUI_ObjectParts.hpp"
+
+#include "../Utils/PresetUpdater.hpp"
+#include "../Config/Snapshot.hpp"
+
+#include "3DScene.hpp"
+#include "libslic3r/I18N.hpp"
+#include "Model.hpp"
+#include "LambdaObjectDialog.hpp"
#include "../../libslic3r/Print.hpp"
@@ -76,83 +94,6 @@ void enable_screensaver()
#endif
}
-std::vector<std::string> scan_serial_ports()
-{
- std::vector<std::string> out;
-#ifdef _WIN32
- // 1) Open the registry key SERIALCOM.
- HKEY hKey;
- LONG lRes = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_READ, &hKey);
- assert(lRes == ERROR_SUCCESS);
- if (lRes == ERROR_SUCCESS) {
- // 2) Get number of values of SERIALCOM key.
- DWORD cValues; // number of values for key
- {
- TCHAR achKey[255]; // buffer for subkey name
- DWORD cbName; // size of name string
- TCHAR achClass[MAX_PATH] = TEXT(""); // buffer for class name
- DWORD cchClassName = MAX_PATH; // size of class string
- DWORD cSubKeys=0; // number of subkeys
- DWORD cbMaxSubKey; // longest subkey size
- DWORD cchMaxClass; // longest class string
- DWORD cchMaxValue; // longest value name
- DWORD cbMaxValueData; // longest value data
- DWORD cbSecurityDescriptor; // size of security descriptor
- FILETIME ftLastWriteTime; // last write time
- // Get the class name and the value count.
- lRes = RegQueryInfoKey(
- hKey, // key handle
- achClass, // buffer for class name
- &cchClassName, // size of class string
- NULL, // reserved
- &cSubKeys, // number of subkeys
- &cbMaxSubKey, // longest subkey size
- &cchMaxClass, // longest class string
- &cValues, // number of values for this key
- &cchMaxValue, // longest value name
- &cbMaxValueData, // longest value data
- &cbSecurityDescriptor, // security descriptor
- &ftLastWriteTime); // last write time
- assert(lRes == ERROR_SUCCESS);
- }
- // 3) Read the SERIALCOM values.
- {
- DWORD dwIndex = 0;
- for (int i = 0; i < cValues; ++ i, ++ dwIndex) {
- wchar_t valueName[2048];
- DWORD valNameLen = 2048;
- DWORD dataType;
- wchar_t data[2048];
- DWORD dataSize = 4096;
- lRes = ::RegEnumValueW(hKey, dwIndex, valueName, &valNameLen, nullptr, &dataType, (BYTE*)&data, &dataSize);
- if (lRes == ERROR_SUCCESS && dataType == REG_SZ && valueName[0] != 0)
- out.emplace_back(boost::nowide::narrow(data));
- }
- }
- ::RegCloseKey(hKey);
- }
-#else
- // UNIX and OS X
- std::initializer_list<const char*> prefixes { "ttyUSB" , "ttyACM", "tty.", "cu.", "rfcomm" };
- for (auto &dir_entry : boost::filesystem::directory_iterator(boost::filesystem::path("/dev"))) {
- std::string name = dir_entry.path().filename().string();
- for (const char *prefix : prefixes) {
- if (boost::starts_with(name, prefix)) {
- out.emplace_back(dir_entry.path().string());
- break;
- }
- }
- }
-#endif
-
- out.erase(std::remove_if(out.begin(), out.end(),
- [](const std::string &key){
- return boost::starts_with(key, "Bluetooth") || boost::starts_with(key, "FireFly");
- }),
- out.end());
- return out;
-}
-
bool debugged()
{
#ifdef _WIN32
@@ -177,17 +118,86 @@ wxNotebook *g_wxTabPanel = nullptr;
wxPanel *g_wxPlater = nullptr;
AppConfig *g_AppConfig = nullptr;
PresetBundle *g_PresetBundle= nullptr;
+PresetUpdater *g_PresetUpdater = nullptr;
+_3DScene *g_3DScene = nullptr;
+wxColour g_color_label_modified;
+wxColour g_color_label_sys;
+wxColour g_color_label_default;
std::vector<Tab *> g_tabs_list;
wxLocale* g_wxLocale;
-std::shared_ptr<ConfigOptionsGroup> m_optgroup;
-double m_brim_width = 0.0;
+wxFont g_small_font;
+wxFont g_bold_font;
+
+std::vector <std::shared_ptr<ConfigOptionsGroup>> m_optgroups;
+double m_brim_width = 0.0;
+size_t m_label_width = 100;
+wxButton* g_wiping_dialog_button = nullptr;
+
+//showed/hided controls according to the view mode
+wxWindow *g_right_panel = nullptr;
+wxBoxSizer *g_frequently_changed_parameters_sizer = nullptr;
+wxBoxSizer *g_expert_mode_part_sizer = nullptr;
+wxBoxSizer *g_scrolled_window_sizer = nullptr;
+wxBoxSizer *g_object_list_sizer = nullptr;
+wxButton *g_btn_export_gcode = nullptr;
+wxButton *g_btn_export_stl = nullptr;
+wxButton *g_btn_reslice = nullptr;
+wxButton *g_btn_print = nullptr;
+wxButton *g_btn_send_gcode = nullptr;
+wxStaticBitmap *g_manifold_warning_icon = nullptr;
+bool g_show_print_info = false;
+bool g_show_manifold_warning_icon = false;
+
+static void init_label_colours()
+{
+ auto luma = get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+ if (luma >= 128) {
+ g_color_label_modified = wxColour(252, 77, 1);
+ g_color_label_sys = wxColour(26, 132, 57);
+ } else {
+ g_color_label_modified = wxColour(253, 111, 40);
+ g_color_label_sys = wxColour(115, 220, 103);
+ }
+ g_color_label_default = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
+}
+
+void update_label_colours_from_appconfig()
+{
+ if (g_AppConfig->has("label_clr_sys")){
+ auto str = g_AppConfig->get("label_clr_sys");
+ if (str != "")
+ g_color_label_sys = wxColour(str);
+ }
+
+ if (g_AppConfig->has("label_clr_modified")){
+ auto str = g_AppConfig->get("label_clr_modified");
+ if (str != "")
+ g_color_label_modified = wxColour(str);
+ }
+}
+
+static void init_fonts()
+{
+ g_small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+ g_bold_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold();
+#ifdef __WXMAC__
+ g_small_font.SetPointSize(11);
+ g_bold_font.SetPointSize(13);
+#endif /*__WXMAC__*/
+}
+
+static std::string libslic3r_translate_callback(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)).utf8_str().data(); }
void set_wxapp(wxApp *app)
{
g_wxApp = app;
+ // Let the libslic3r know the callback, which will translate messages on demand.
+ Slic3r::I18N::set_translate_callback(libslic3r_translate_callback);
+ init_label_colours();
+ init_fonts();
}
void set_main_frame(wxFrame *main_frame)
@@ -195,6 +205,8 @@ void set_main_frame(wxFrame *main_frame)
g_wxMainFrame = main_frame;
}
+wxFrame* get_main_frame() { return g_wxMainFrame; }
+
void set_tab_panel(wxNotebook *tab_panel)
{
g_wxTabPanel = tab_panel;
@@ -215,6 +227,49 @@ void set_preset_bundle(PresetBundle *preset_bundle)
g_PresetBundle = preset_bundle;
}
+void set_preset_updater(PresetUpdater *updater)
+{
+ g_PresetUpdater = updater;
+}
+
+void set_3DScene(_3DScene *scene)
+{
+ g_3DScene = scene;
+}
+
+void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_parameters_sizer,
+ wxBoxSizer *expert_mode_part_sizer, wxBoxSizer *scrolled_window_sizer,
+ wxButton *btn_export_gcode,
+ wxButton *btn_export_stl, wxButton *btn_reslice,
+ wxButton *btn_print, wxButton *btn_send_gcode,
+ wxStaticBitmap *manifold_warning_icon)
+{
+ g_right_panel = parent;
+ g_frequently_changed_parameters_sizer = frequently_changed_parameters_sizer;
+ g_expert_mode_part_sizer = expert_mode_part_sizer;
+ g_scrolled_window_sizer = scrolled_window_sizer;
+ g_btn_export_gcode = btn_export_gcode;
+ g_btn_export_stl = btn_export_stl;
+ g_btn_reslice = btn_reslice;
+ g_btn_print = btn_print;
+ g_btn_send_gcode = btn_send_gcode;
+ g_manifold_warning_icon = manifold_warning_icon;
+}
+
+void set_show_print_info(bool show)
+{
+ g_show_print_info = show;
+}
+
+void set_show_manifold_warning_icon(bool show)
+{
+ g_show_manifold_warning_icon = show;
+}
+
+void set_objects_list_sizer(wxBoxSizer *objects_list_sizer){
+ g_object_list_sizer = objects_list_sizer;
+}
+
std::vector<Tab *>& get_tabs_list()
{
return g_tabs_list;
@@ -259,6 +314,7 @@ bool select_language(wxArrayString & names,
g_wxLocale->AddCatalogLookupPathPrefix(wxPathOnly(localization_dir()));
g_wxLocale->AddCatalog(g_wxApp->GetAppName());
wxSetlocale(LC_NUMERIC, "C");
+ Preset::update_suffix_modified();
return true;
}
return false;
@@ -266,28 +322,25 @@ bool select_language(wxArrayString & names,
bool load_language()
{
- long language;
- if (!g_AppConfig->has("translation_language"))
- language = wxLANGUAGE_UNKNOWN;
- else {
- auto str_language = g_AppConfig->get("translation_language");
- language = str_language != "" ? stol(str_language) : wxLANGUAGE_UNKNOWN;
- }
+ wxString language = wxEmptyString;
+ if (g_AppConfig->has("translation_language"))
+ language = g_AppConfig->get("translation_language");
- if (language == wxLANGUAGE_UNKNOWN)
+ if (language.IsEmpty())
return false;
wxArrayString names;
wxArrayLong identifiers;
get_installed_languages(names, identifiers);
for (size_t i = 0; i < identifiers.Count(); i++)
{
- if (identifiers[i] == language)
+ if (wxLocale::GetLanguageCanonicalName(identifiers[i]) == language)
{
g_wxLocale = new wxLocale;
g_wxLocale->Init(identifiers[i]);
g_wxLocale->AddCatalogLookupPathPrefix(wxPathOnly(localization_dir()));
g_wxLocale->AddCatalog(g_wxApp->GetAppName());
wxSetlocale(LC_NUMERIC, "C");
+ Preset::update_suffix_modified();
return true;
}
}
@@ -296,12 +349,11 @@ bool load_language()
void save_language()
{
- long language = wxLANGUAGE_UNKNOWN;
- if (g_wxLocale) {
- language = g_wxLocale->GetLanguage();
- }
- std::string str_language = std::to_string(language);
- g_AppConfig->set("translation_language", str_language);
+ wxString language = wxEmptyString;
+ if (g_wxLocale)
+ language = g_wxLocale->GetCanonicalName();
+
+ g_AppConfig->set("translation_language", language.ToStdString());
g_AppConfig->save();
}
@@ -338,26 +390,210 @@ void get_installed_languages(wxArrayString & names,
}
}
-void add_debug_menu(wxMenuBar *menu, int event_language_change)
+enum ConfigMenuIDs {
+ ConfigMenuWizard,
+ ConfigMenuSnapshots,
+ ConfigMenuTakeSnapshot,
+ ConfigMenuUpdate,
+ ConfigMenuPreferences,
+ ConfigMenuModeSimple,
+ ConfigMenuModeExpert,
+ ConfigMenuLanguage,
+ ConfigMenuFlashFirmware,
+ ConfigMenuCnt,
+};
+
+ConfigMenuIDs get_view_mode()
+{
+ if (!g_AppConfig->has("view_mode"))
+ return ConfigMenuModeSimple;
+
+ const auto mode = g_AppConfig->get("view_mode");
+ return mode == "expert" ? ConfigMenuModeExpert : ConfigMenuModeSimple;
+}
+
+static wxString dots("…", wxConvUTF8);
+
+void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_language_change)
{
-//#if 0
auto local_menu = new wxMenu();
- local_menu->Append(wxWindow::NewControlId(1), _(L("Change Application Language")));
- local_menu->Bind(wxEVT_MENU, [event_language_change](wxEvent&){
- wxArrayString names;
- wxArrayLong identifiers;
- get_installed_languages(names, identifiers);
- if (select_language(names, identifiers)){
- save_language();
- show_info(g_wxTabPanel, _(L("Application will be restarted")), _(L("Attention!")));
- if (event_language_change > 0) {
- wxCommandEvent event(event_language_change);
- g_wxApp->ProcessEvent(event);
+ wxWindowID config_id_base = wxWindow::NewControlId((int)ConfigMenuCnt);
+
+ const auto config_wizard_name = _(ConfigWizard::name().wx_str());
+ const auto config_wizard_tooltip = wxString::Format(_(L("Run %s")), config_wizard_name);
+ // Cmd+, is standard on OS X - what about other operating systems?
+ local_menu->Append(config_id_base + ConfigMenuWizard, config_wizard_name + dots, config_wizard_tooltip);
+ local_menu->Append(config_id_base + ConfigMenuSnapshots, _(L("Configuration Snapshots"))+dots, _(L("Inspect / activate configuration snapshots")));
+ local_menu->Append(config_id_base + ConfigMenuTakeSnapshot, _(L("Take Configuration Snapshot")), _(L("Capture a configuration snapshot")));
+// local_menu->Append(config_id_base + ConfigMenuUpdate, _(L("Check for updates")), _(L("Check for configuration updates")));
+ local_menu->AppendSeparator();
+ local_menu->Append(config_id_base + ConfigMenuPreferences, _(L("Preferences"))+dots+"\tCtrl+,", _(L("Application preferences")));
+ local_menu->AppendSeparator();
+ auto mode_menu = new wxMenu();
+ mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _(L("&Simple")), _(L("Simple View Mode")));
+ mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeExpert, _(L("&Expert")), _(L("Expert View Mode")));
+ mode_menu->Check(config_id_base + get_view_mode(), true);
+ local_menu->AppendSubMenu(mode_menu, _(L("&Mode")), _(L("Slic3r View Mode")));
+ local_menu->AppendSeparator();
+ local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application Language")));
+ local_menu->AppendSeparator();
+ local_menu->Append(config_id_base + ConfigMenuFlashFirmware, _(L("Flash printer firmware")), _(L("Upload a firmware image into an Arduino based printer")));
+ // TODO: for when we're able to flash dictionaries
+ // local_menu->Append(config_id_base + FirmwareMenuDict, _(L("Flash language file")), _(L("Upload a language dictionary file into a Prusa printer")));
+
+ local_menu->Bind(wxEVT_MENU, [config_id_base, event_language_change, event_preferences_changed](wxEvent &event){
+ switch (event.GetId() - config_id_base) {
+ case ConfigMenuWizard:
+ config_wizard(ConfigWizard::RR_USER);
+ break;
+ case ConfigMenuTakeSnapshot:
+ // Take a configuration snapshot.
+ if (check_unsaved_changes()) {
+ wxTextEntryDialog dlg(nullptr, _(L("Taking configuration snapshot")), _(L("Snapshot name")));
+ if (dlg.ShowModal() == wxID_OK)
+ g_AppConfig->set("on_snapshot",
+ Slic3r::GUI::Config::SnapshotDB::singleton().take_snapshot(
+ *g_AppConfig, Slic3r::GUI::Config::Snapshot::SNAPSHOT_USER, dlg.GetValue().ToUTF8().data()).id);
}
+ break;
+ case ConfigMenuSnapshots:
+ if (check_unsaved_changes()) {
+ std::string on_snapshot;
+ if (Config::SnapshotDB::singleton().is_on_snapshot(*g_AppConfig))
+ on_snapshot = g_AppConfig->get("on_snapshot");
+ ConfigSnapshotDialog dlg(Slic3r::GUI::Config::SnapshotDB::singleton(), on_snapshot);
+ dlg.ShowModal();
+ if (! dlg.snapshot_to_activate().empty()) {
+ if (! Config::SnapshotDB::singleton().is_on_snapshot(*g_AppConfig))
+ Config::SnapshotDB::singleton().take_snapshot(*g_AppConfig, Config::Snapshot::SNAPSHOT_BEFORE_ROLLBACK);
+ g_AppConfig->set("on_snapshot",
+ Config::SnapshotDB::singleton().restore_snapshot(dlg.snapshot_to_activate(), *g_AppConfig).id);
+ g_PresetBundle->load_presets(*g_AppConfig);
+ // Load the currently selected preset into the GUI, update the preset selection box.
+ load_current_presets();
+ }
+ }
+ break;
+ case ConfigMenuPreferences:
+ {
+ PreferencesDialog dlg(g_wxMainFrame, event_preferences_changed);
+ dlg.ShowModal();
+ break;
+ }
+ case ConfigMenuLanguage:
+ {
+ wxArrayString names;
+ wxArrayLong identifiers;
+ get_installed_languages(names, identifiers);
+ if (select_language(names, identifiers)) {
+ save_language();
+ show_info(g_wxTabPanel, _(L("Application will be restarted")), _(L("Attention!")));
+ if (event_language_change > 0) {
+ _3DScene::remove_all_canvases();// remove all canvas before recreate GUI
+ wxCommandEvent event(event_language_change);
+ g_wxApp->ProcessEvent(event);
+ }
+ }
+ break;
+ }
+ case ConfigMenuFlashFirmware:
+ FirmwareDialog::run(g_wxMainFrame);
+ break;
+ default:
+ break;
}
});
- menu->Append(local_menu, _(L("&Localization")));
-//#endif
+ mode_menu->Bind(wxEVT_MENU, [config_id_base](wxEvent& event) {
+ std::string mode = event.GetId() - config_id_base == ConfigMenuModeExpert ?
+ "expert" : "simple";
+ g_AppConfig->set("view_mode", mode);
+ g_AppConfig->save();
+ update_mode();
+ });
+ menu->Append(local_menu, _(L("&Configuration")));
+}
+
+void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change)
+{
+ add_config_menu(menu, event_preferences_changed, event_language_change);
+}
+
+void open_model(wxWindow *parent, wxArrayString& input_files){
+ t_file_wild_card vec_FILE_WILDCARDS = get_file_wild_card();
+ std::vector<std::string> file_types = { "known", "stl", "obj", "amf", "3mf", "prusa" };
+ wxString MODEL_WILDCARD;
+ for (auto file_type : file_types)
+ MODEL_WILDCARD += vec_FILE_WILDCARDS.at(file_type) + "|";
+
+ auto dlg_title = _(L("Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):"));
+ auto dialog = new wxFileDialog(parent /*? parent : GetTopWindow(g_wxMainFrame)*/, dlg_title,
+ g_AppConfig->get_last_dir(), "",
+ MODEL_WILDCARD, wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST);
+ if (dialog->ShowModal() != wxID_OK) {
+ dialog->Destroy();
+ return ;
+ }
+
+ dialog->GetPaths(input_files);
+ dialog->Destroy();
+}
+
+// This is called when closing the application, when loading a config file or when starting the config wizard
+// to notify the user whether he is aware that some preset changes will be lost.
+bool check_unsaved_changes()
+{
+ std::string dirty;
+ for (Tab *tab : g_tabs_list)
+ if (tab->current_preset_is_dirty())
+ if (dirty.empty())
+ dirty = tab->name();
+ else
+ dirty += std::string(", ") + tab->name();
+ if (dirty.empty())
+ // No changes, the application may close or reload presets.
+ return true;
+ // Ask the user.
+ auto dialog = new wxMessageDialog(g_wxMainFrame,
+ _(L("You have unsaved changes ")) + dirty + _(L(". Discard changes and continue anyway?")),
+ _(L("Unsaved Presets")),
+ wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT);
+ return dialog->ShowModal() == wxID_YES;
+}
+
+bool config_wizard_startup(bool app_config_exists)
+{
+ if (! app_config_exists || g_PresetBundle->printers.size() <= 1) {
+ config_wizard(ConfigWizard::RR_DATA_EMPTY);
+ return true;
+ } else if (g_AppConfig->legacy_datadir()) {
+ // Looks like user has legacy pre-vendorbundle data directory,
+ // explain what this is and run the wizard
+
+ MsgDataLegacy dlg;
+ dlg.ShowModal();
+
+ config_wizard(ConfigWizard::RR_DATA_LEGACY);
+ return true;
+ }
+ return false;
+}
+
+void config_wizard(int reason)
+{
+ // Exit wizard if there are unsaved changes and the user cancels the action.
+ if (! check_unsaved_changes())
+ return;
+
+ try {
+ ConfigWizard wizard(nullptr, static_cast<ConfigWizard::RunReason>(reason));
+ wizard.run(g_PresetBundle, g_PresetUpdater);
+ }
+ catch (const std::exception &e) {
+ show_error(nullptr, e.what());
+ }
+
+ // Load the currently selected preset into the GUI, update the preset selection box.
+ load_current_presets();
}
void open_preferences_dialog(int event_preferences)
@@ -368,20 +604,34 @@ void open_preferences_dialog(int event_preferences)
void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed)
{
- add_created_tab(new TabPrint (g_wxTabPanel, no_controller));
- add_created_tab(new TabFilament (g_wxTabPanel, no_controller));
- add_created_tab(new TabPrinter (g_wxTabPanel, no_controller));
- for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++ i) {
- Tab *tab = dynamic_cast<Tab*>(g_wxTabPanel->GetPage(i));
- if (! tab)
- continue;
- tab->set_event_value_change(wxEventType(event_value_change));
- tab->set_event_presets_changed(wxEventType(event_presets_changed));
- }
+ update_label_colours_from_appconfig();
+ add_created_tab(new TabPrint (g_wxTabPanel, no_controller), event_value_change, event_presets_changed);
+ add_created_tab(new TabFilament (g_wxTabPanel, no_controller), event_value_change, event_presets_changed);
+ add_created_tab(new TabSLAMaterial (g_wxTabPanel, no_controller), event_value_change, event_presets_changed);
+ add_created_tab(new TabPrinter (g_wxTabPanel, no_controller), event_value_change, event_presets_changed);
+}
+
+std::vector<PresetTab> preset_tabs = {
+ { "print", nullptr, ptFFF },
+ { "filament", nullptr, ptFFF },
+ { "sla_material", nullptr, ptSLA }
+};
+const std::vector<PresetTab>& get_preset_tabs() {
+ return preset_tabs;
+}
+
+Tab* get_tab(const std::string& name)
+{
+ std::vector<PresetTab>::iterator it = std::find_if(preset_tabs.begin(), preset_tabs.end(),
+ [name](PresetTab& tab){ return name == tab.name; });
+ return it != preset_tabs.end() ? it->panel : nullptr;
}
TabIface* get_preset_tab_iface(char *name)
{
+ Tab* tab = get_tab(name);
+ if (tab) return new TabIface(tab);
+
for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++ i) {
Tab *tab = dynamic_cast<Tab*>(g_wxTabPanel->GetPage(i));
if (! tab)
@@ -394,7 +644,7 @@ TabIface* get_preset_tab_iface(char *name)
}
// opt_index = 0, by the reason of zero-index in ConfigOptionVector by default (in case only one element)
-void change_opt_value(DynamicPrintConfig& config, t_config_option_key opt_key, boost::any value, int opt_index /*= 0*/)
+void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/)
{
try{
switch (config.def()->get(opt_key)->type){
@@ -430,14 +680,20 @@ void change_opt_value(DynamicPrintConfig& config, t_config_option_key opt_key, b
config.set_key_value(opt_key, new ConfigOptionString(boost::any_cast<std::string>(value)));
break;
case coStrings:{
- if (opt_key.compare("compatible_printers") == 0 ||
- config.def()->get(opt_key)->gui_flags.compare("serialized") == 0){
- config.option<ConfigOptionStrings>(opt_key)->values.resize(0);
- std::vector<std::string> values = boost::any_cast<std::vector<std::string>>(value);
- if (values.size() == 1 && values[0] == "")
+ if (opt_key.compare("compatible_printers") == 0) {
+ config.option<ConfigOptionStrings>(opt_key)->values =
+ boost::any_cast<std::vector<std::string>>(value);
+ }
+ else if (config.def()->get(opt_key)->gui_flags.compare("serialized") == 0){
+ std::string str = boost::any_cast<std::string>(value);
+ if (str.back() == ';') str.pop_back();
+ // Split a string to multiple strings by a semi - colon.This is the old way of storing multi - string values.
+ // Currently used for the post_process config value only.
+ std::vector<std::string> values;
+ boost::split(values, str, boost::is_any_of(";"));
+ if (values.size() == 1 && values[0] == "")
break;
- for (auto el : values)
- config.option<ConfigOptionStrings>(opt_key)->values.push_back(el);
+ config.option<ConfigOptionStrings>(opt_key)->values = values;
}
else{
ConfigOptionStrings* vec_new = new ConfigOptionStrings{ boost::any_cast<std::string>(value) };
@@ -470,10 +726,16 @@ void change_opt_value(DynamicPrintConfig& config, t_config_option_key opt_key, b
config.set_key_value(opt_key, new ConfigOptionEnum<SupportMaterialPattern>(boost::any_cast<SupportMaterialPattern>(value)));
else if (opt_key.compare("seam_position") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<SeamPosition>(boost::any_cast<SeamPosition>(value)));
+ else if (opt_key.compare("host_type") == 0)
+ config.set_key_value(opt_key, new ConfigOptionEnum<PrintHostType>(boost::any_cast<PrintHostType>(value)));
}
break;
case coPoints:{
- ConfigOptionPoints* vec_new = new ConfigOptionPoints{ boost::any_cast<Pointf>(value) };
+ if (opt_key.compare("bed_shape") == 0){
+ config.option<ConfigOptionPoints>(opt_key)->values = boost::any_cast<std::vector<Vec2d>>(value);
+ break;
+ }
+ ConfigOptionPoints* vec_new = new ConfigOptionPoints{ boost::any_cast<Vec2d>(value) };
config.option<ConfigOptionPoints>(opt_key)->set_at(vec_new, opt_index, 0);
}
break;
@@ -489,30 +751,57 @@ void change_opt_value(DynamicPrintConfig& config, t_config_option_key opt_key, b
}
}
-void add_created_tab(Tab* panel)
+void add_created_tab(Tab* panel, int event_value_change, int event_presets_changed)
{
panel->create_preset_tab(g_PresetBundle);
// Load the currently selected preset into the GUI, update the preset selection box.
panel->load_current_preset();
- g_wxTabPanel->AddPage(panel, panel->title());
+
+ panel->set_event_value_change(wxEventType(event_value_change));
+ panel->set_event_presets_changed(wxEventType(event_presets_changed));
+
+ const wxString& tab_name = panel->GetName();
+ bool add_panel = true;
+
+ auto it = std::find_if( preset_tabs.begin(), preset_tabs.end(),
+ [tab_name](PresetTab& tab){return tab.name == tab_name; });
+ if (it != preset_tabs.end()) {
+ it->panel = panel;
+ add_panel = it->technology == g_PresetBundle->printers.get_edited_preset().printer_technology();
+ }
+
+ if (add_panel)
+ g_wxTabPanel->AddPage(panel, panel->title());
+}
+
+void load_current_presets()
+{
+ for (Tab *tab : g_tabs_list) {
+ tab->load_current_preset();
+ }
+}
+
+void show_error(wxWindow* parent, const wxString& message) {
+ ErrorDialog msg(parent, message);
+ msg.ShowModal();
}
-void show_error(wxWindow* parent, wxString message){
- auto msg_wingow = new wxMessageDialog(parent, message, _(L("Error")), wxOK | wxICON_ERROR);
- msg_wingow->ShowModal();
+void show_error_id(int id, const std::string& message) {
+ auto *parent = id != 0 ? wxWindow::FindWindowById(id) : nullptr;
+ show_error(parent, wxString::FromUTF8(message.data()));
}
-void show_info(wxWindow* parent, wxString message, wxString title){
- auto msg_wingow = new wxMessageDialog(parent, message, title.empty() ? _(L("Notice")) : title, wxOK | wxICON_INFORMATION);
- msg_wingow->ShowModal();
+void show_info(wxWindow* parent, const wxString& message, const wxString& title){
+ wxMessageDialog msg_wingow(parent, message, title.empty() ? _(L("Notice")) : title, wxOK | wxICON_INFORMATION);
+ msg_wingow.ShowModal();
}
-void warning_catcher(wxWindow* parent, wxString message){
- if (message == _(L("GLUquadricObjPtr | Attempt to free unreferenced scalar")) )
+void warning_catcher(wxWindow* parent, const wxString& message){
+ if (message == "GLUquadricObjPtr | " + _(L("Attempt to free unreferenced scalar")) )
return;
- auto msg = new wxMessageDialog(parent, message, _(L("Warning")), wxOK | wxICON_WARNING);
- msg->ShowModal();
+ wxMessageDialog msg(parent, message, _(L("Warning")), wxOK | wxICON_WARNING);
+ msg.ShowModal();
}
// Assign a Lambda to the print object to emit a wxWidgets Command with the provided ID
@@ -531,9 +820,70 @@ wxApp* get_app(){
return g_wxApp;
}
-wxColour* get_modified_label_clr()
+PresetBundle* get_preset_bundle()
{
- return new wxColour(253, 88, 0);
+ return g_PresetBundle;
+}
+
+const wxColour& get_label_clr_modified() {
+ return g_color_label_modified;
+}
+
+const wxColour& get_label_clr_sys() {
+ return g_color_label_sys;
+}
+
+void set_label_clr_modified(const wxColour& clr) {
+ g_color_label_modified = clr;
+ auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue());
+ std::string str = clr_str.ToStdString();
+ g_AppConfig->set("label_clr_modified", str);
+ g_AppConfig->save();
+}
+
+void set_label_clr_sys(const wxColour& clr) {
+ g_color_label_sys = clr;
+ auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue());
+ std::string str = clr_str.ToStdString();
+ g_AppConfig->set("label_clr_sys", str);
+ g_AppConfig->save();
+}
+
+const wxFont& small_font(){
+ return g_small_font;
+}
+
+const wxFont& bold_font(){
+ return g_bold_font;
+}
+
+const wxColour& get_label_clr_default() {
+ return g_color_label_default;
+}
+
+unsigned get_colour_approx_luma(const wxColour &colour)
+{
+ double r = colour.Red();
+ double g = colour.Green();
+ double b = colour.Blue();
+
+ return std::round(std::sqrt(
+ r * r * .241 +
+ g * g * .691 +
+ b * b * .068
+ ));
+}
+
+wxWindow* get_right_panel(){
+ return g_right_panel;
+}
+
+wxNotebook * get_tab_panel() {
+ return g_wxTabPanel;
+}
+
+const size_t& label_width(){
+ return m_label_width;
}
void create_combochecklist(wxComboCtrl* comboCtrl, std::string text, std::string items, bool initial_value)
@@ -604,14 +954,37 @@ wxString from_u8(const std::string &str)
return wxString::FromUTF8(str.c_str());
}
+void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer,
+ Model &model,
+ int event_object_selection_changed,
+ int event_object_settings_changed,
+ int event_remove_object,
+ int event_update_scene)
+{
+ set_event_object_selection_changed(event_object_selection_changed);
+ set_event_object_settings_changed(event_object_settings_changed);
+ set_event_remove_object(event_remove_object);
+ set_event_update_scene(event_update_scene);
+ set_objects_from_model(model);
+ init_mesh_icons();
+
+// wxWindowUpdateLocker noUpdates(parent);
+
+// add_objects_list(parent, sizer);
+
+// add_collapsible_panes(parent, sizer);
+}
void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer)
{
DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config;
- m_optgroup = std::make_shared<ConfigOptionsGroup>(parent, "", config);
+ std::shared_ptr<ConfigOptionsGroup> optgroup = std::make_shared<ConfigOptionsGroup>(parent, "", config);
const wxArrayInt& ar = preset_sizer->GetColWidths();
- m_optgroup->label_width = ar.IsEmpty() ? 100 : ar.front();
- m_optgroup->m_on_change = [config](t_config_option_key opt_key, boost::any value){
+ m_label_width = ar.IsEmpty() ? 100 : ar.front()-4;
+ optgroup->label_width = m_label_width;
+
+ //Frequently changed parameters
+ optgroup->m_on_change = [config](t_config_option_key opt_key, boost::any value){
TabPrint* tab_print = nullptr;
for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) {
Tab *tab = dynamic_cast<Tab*>(g_wxTabPanel->GetPage(i));
@@ -626,7 +999,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl
return;
if (opt_key == "fill_density"){
- value = m_optgroup->get_config_value(*config, opt_key);
+ value = m_optgroups[ogFrequentlyChangingParameters]->get_config_value(*config, opt_key);
tab_print->set_value(opt_key, value);
tab_print->update();
}
@@ -649,14 +1022,14 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl
}
else{ //(opt_key == "support")
const wxString& selection = boost::any_cast<wxString>(value);
-
+
auto support_material = selection == _("None") ? false : true;
new_conf.set_key_value("support_material", new ConfigOptionBool(support_material));
if (selection == _("Everywhere"))
new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(false));
else if (selection == _("Support on build plate only"))
- new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(true));
+ new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(true));
}
tab_print->load_config(new_conf);
}
@@ -664,11 +1037,10 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl
tab_print->update_dirty();
};
- const int width = 250;
- Option option = m_optgroup->get_option("fill_density");
+ Option option = optgroup->get_option("fill_density");
option.opt.sidetext = "";
- option.opt.width = width;
- m_optgroup->append_single_option_line(option);
+ option.opt.full_width = true;
+ optgroup->append_single_option_line(option);
ConfigOptionDef def;
@@ -686,8 +1058,8 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl
"Everywhere";
def.default_value = new ConfigOptionStrings { selection };
option = Option(def, "support");
- option.opt.width = width;
- m_optgroup->append_single_option_line(option);
+ option.opt.full_width = true;
+ optgroup->append_single_option_line(option);
m_brim_width = config->opt_float("brim_width");
def.label = L("Brim");
@@ -696,14 +1068,244 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl
def.gui_type = "";
def.default_value = new ConfigOptionBool{ m_brim_width > 0.0 ? true : false };
option = Option(def, "brim");
- m_optgroup->append_single_option_line(option);
+ optgroup->append_single_option_line(option);
+
+
+ Line line = { "", "" };
+ line.widget = [config](wxWindow* parent){
+ g_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
+ auto sizer = new wxBoxSizer(wxHORIZONTAL);
+ sizer->Add(g_wiping_dialog_button);
+ g_wiping_dialog_button->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent& e)
+ {
+ auto &config = g_PresetBundle->project_config;
+ const std::vector<double> &init_matrix = (config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values;
+ const std::vector<double> &init_extruders = (config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values;
- sizer->Add(m_optgroup->sizer, 0, wxEXPAND | wxBOTTOM | wxBottom, 1);
+ WipingDialog dlg(parent,cast<float>(init_matrix),cast<float>(init_extruders));
+
+ if (dlg.ShowModal() == wxID_OK) {
+ std::vector<float> matrix = dlg.get_matrix();
+ std::vector<float> extruders = dlg.get_extruders();
+ (config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values = std::vector<double>(matrix.begin(),matrix.end());
+ (config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values = std::vector<double>(extruders.begin(),extruders.end());
+ g_on_request_update_callback.call();
+ }
+ }));
+ return sizer;
+ };
+ optgroup->append_line(line);
+
+ sizer->Add(optgroup->sizer, 0, wxEXPAND | wxBOTTOM, 2);
+
+ m_optgroups.push_back(optgroup);// ogFrequentlyChangingParameters
+
+ // Object List
+ add_objects_list(parent, sizer);
+
+ // Frequently Object Settings
+ add_object_settings(parent, sizer);
+}
+
+void show_frequently_changed_parameters(bool show)
+{
+ g_frequently_changed_parameters_sizer->Show(show);
+ if (!show) return;
+
+ for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) {
+ Tab *tab = dynamic_cast<Tab*>(g_wxTabPanel->GetPage(i));
+ if (!tab)
+ continue;
+ tab->update_wiping_button_visibility();
+ break;
+ }
}
-ConfigOptionsGroup* get_optgroup()
+void show_buttons(bool show)
{
- return m_optgroup.get();
+ g_btn_export_stl->Show(show);
+ g_btn_reslice->Show(show);
+ for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) {
+ TabPrinter *tab = dynamic_cast<TabPrinter*>(g_wxTabPanel->GetPage(i));
+ if (!tab)
+ continue;
+ if (g_PresetBundle->printers.get_selected_preset().printer_technology() == ptFFF) {
+ g_btn_print->Show(show && !tab->m_config->opt_string("serial_port").empty());
+ g_btn_send_gcode->Show(show && !tab->m_config->opt_string("print_host").empty());
+ }
+ break;
+ }
+}
+
+void show_info_sizer(bool show)
+{
+ g_scrolled_window_sizer->Show(static_cast<size_t>(0), show);
+ g_scrolled_window_sizer->Show(1, show && g_show_print_info);
+ g_manifold_warning_icon->Show(show && g_show_manifold_warning_icon);
+}
+
+void show_object_name(bool show)
+{
+ wxGridSizer* grid_sizer = get_optgroup(ogFrequentlyObjectSettings)->get_grid_sizer();
+ grid_sizer->Show(static_cast<size_t>(0), show);
+ grid_sizer->Show(static_cast<size_t>(1), show);
+}
+
+void update_mode()
+{
+ wxWindowUpdateLocker noUpdates(g_right_panel);
+
+ // TODO There is a not the best place of it!
+ //*** Update style of the "Export G-code" button****
+ if (g_btn_export_gcode->GetFont() != bold_font()){
+ g_btn_export_gcode->SetBackgroundColour(wxColour(252, 77, 1));
+ g_btn_export_gcode->SetFont(bold_font());
+ }
+ // ***********************************
+
+ ConfigMenuIDs mode = get_view_mode();
+
+// show_frequently_changed_parameters(mode >= ConfigMenuModeRegular);
+// g_expert_mode_part_sizer->Show(mode == ConfigMenuModeExpert);
+ g_object_list_sizer->Show(mode == ConfigMenuModeExpert);
+ show_info_sizer(mode == ConfigMenuModeExpert);
+ show_buttons(mode == ConfigMenuModeExpert);
+ show_object_name(mode == ConfigMenuModeSimple);
+
+ // TODO There is a not the best place of it!
+ // *** Update showing of the collpane_settings
+// show_collpane_settings(mode == ConfigMenuModeExpert);
+ // *************************
+ g_right_panel->Layout();
+ g_right_panel->GetParent()->GetParent()->Layout();
+}
+
+bool is_expert_mode(){
+ return get_view_mode() == ConfigMenuModeExpert;
+}
+
+ConfigOptionsGroup* get_optgroup(size_t i)
+{
+ return m_optgroups[i].get();
+}
+
+std::vector <std::shared_ptr<ConfigOptionsGroup>>& get_optgroups() {
+ return m_optgroups;
+}
+
+wxButton* get_wiping_dialog_button()
+{
+ return g_wiping_dialog_button;
+}
+
+wxWindow* export_option_creator(wxWindow* parent)
+{
+ wxPanel* panel = new wxPanel(parent, -1);
+ wxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
+ wxCheckBox* cbox = new wxCheckBox(panel, wxID_HIGHEST + 1, L("Export print config"));
+ cbox->SetValue(true);
+ sizer->AddSpacer(5);
+ sizer->Add(cbox, 0, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 5);
+ panel->SetSizer(sizer);
+ sizer->SetSizeHints(panel);
+ return panel;
+}
+
+void add_export_option(wxFileDialog* dlg, const std::string& format)
+{
+ if ((dlg != nullptr) && (format == "AMF") || (format == "3MF"))
+ {
+ if (dlg->SupportsExtraControl())
+ dlg->SetExtraControlCreator(export_option_creator);
+ }
+}
+
+int get_export_option(wxFileDialog* dlg)
+{
+ if (dlg != nullptr)
+ {
+ wxWindow* wnd = dlg->GetExtraControl();
+ if (wnd != nullptr)
+ {
+ wxPanel* panel = dynamic_cast<wxPanel*>(wnd);
+ if (panel != nullptr)
+ {
+ wxWindow* child = panel->FindWindow(wxID_HIGHEST + 1);
+ if (child != nullptr)
+ {
+ wxCheckBox* cbox = dynamic_cast<wxCheckBox*>(child);
+ if (cbox != nullptr)
+ return cbox->IsChecked() ? 1 : 0;
+ }
+ }
+ }
+ }
+
+ return 0;
+
+}
+
+void get_current_screen_size(unsigned &width, unsigned &height)
+{
+ wxDisplay display(wxDisplay::GetFromWindow(g_wxMainFrame));
+ const auto disp_size = display.GetClientArea();
+ width = disp_size.GetWidth();
+ height = disp_size.GetHeight();
+}
+
+void about()
+{
+ AboutDialog dlg;
+ dlg.ShowModal();
+ dlg.Destroy();
+}
+
+void desktop_open_datadir_folder()
+{
+ // Execute command to open a file explorer, platform dependent.
+ // FIXME: The const_casts aren't needed in wxWidgets 3.1, remove them when we upgrade.
+
+ const auto path = data_dir();
+#ifdef _WIN32
+ const auto widepath = wxString::FromUTF8(path.data());
+ const wchar_t *argv[] = { L"explorer", widepath.GetData(), nullptr };
+ ::wxExecute(const_cast<wchar_t**>(argv), wxEXEC_ASYNC, nullptr);
+#elif __APPLE__
+ const char *argv[] = { "open", path.data(), nullptr };
+ ::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr);
+#else
+ const char *argv[] = { "xdg-open", path.data(), nullptr };
+
+ // Check if we're running in an AppImage container, if so, we need to remove AppImage's env vars,
+ // because they may mess up the environment expected by the file manager.
+ // Mostly this is about LD_LIBRARY_PATH, but we remove a few more too for good measure.
+ if (wxGetEnv("APPIMAGE", nullptr)) {
+ // We're running from AppImage
+ wxEnvVariableHashMap env_vars;
+ wxGetEnvMap(&env_vars);
+
+ env_vars.erase("APPIMAGE");
+ env_vars.erase("APPDIR");
+ env_vars.erase("LD_LIBRARY_PATH");
+ env_vars.erase("LD_PRELOAD");
+ env_vars.erase("UNION_PRELOAD");
+
+ wxExecuteEnv exec_env;
+ exec_env.env = std::move(env_vars);
+
+ wxString owd;
+ if (wxGetEnv("OWD", &owd)) {
+ // This is the original work directory from which the AppImage image was run,
+ // set it as CWD for the child process:
+ exec_env.cwd = std::move(owd);
+ }
+
+ ::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr, &exec_env);
+ } else {
+ // Looks like we're NOT running from AppImage, we'll make no changes to the environment.
+ ::wxExecute(const_cast<char**>(argv), wxEXEC_ASYNC, nullptr, nullptr);
+ }
+#endif
}
} }
diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp
index 506454e56..1f5805bb6 100644
--- a/xs/src/slic3r/GUI/GUI.hpp
+++ b/xs/src/slic3r/GUI/GUI.hpp
@@ -3,12 +3,16 @@
#include <string>
#include <vector>
-#include "Config.hpp"
+#include "PrintConfig.hpp"
+#include "../../libslic3r/Utils.hpp"
+#include "GUI_ObjectParts.hpp"
+
+#include <wx/intl.h>
+#include <wx/string.h>
class wxApp;
class wxWindow;
class wxFrame;
-class wxWindow;
class wxMenuBar;
class wxNotebook;
class wxPanel;
@@ -19,6 +23,10 @@ class wxArrayLong;
class wxColour;
class wxBoxSizer;
class wxFlexGridSizer;
+class wxButton;
+class wxFileDialog;
+class wxStaticBitmap;
+class wxFont;
namespace Slic3r {
@@ -26,8 +34,19 @@ class PresetBundle;
class PresetCollection;
class Print;
class AppConfig;
+class PresetUpdater;
class DynamicPrintConfig;
class TabIface;
+class _3DScene;
+
+#define _(s) Slic3r::GUI::I18N::translate((s))
+
+namespace GUI { namespace I18N {
+ inline wxString translate(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)); }
+ inline wxString translate(const wchar_t *s) { return wxGetTranslation(s); }
+ inline wxString translate(const std::string &s) { return wxGetTranslation(wxString(s.c_str(), wxConvUTF8)); }
+ inline wxString translate(const std::wstring &s) { return wxGetTranslation(s.c_str()); }
+} }
// !!! If you needed to translate some wxString,
// !!! please use _(L(string))
@@ -52,22 +71,28 @@ typedef std::map<std::string, std::string> t_file_wild_card;
inline t_file_wild_card& get_file_wild_card() {
static t_file_wild_card FILE_WILDCARDS;
if (FILE_WILDCARDS.empty()){
- FILE_WILDCARDS["known"] = "Known files (*.stl, *.obj, *.amf, *.xml, *.prusa)|*.stl;*.STL;*.obj;*.OBJ;*.amf;*.AMF;*.xml;*.XML;*.prusa;*.PRUSA";
- FILE_WILDCARDS["stl"] = "STL files (*.stl)|*.stl;*.STL";
- FILE_WILDCARDS["obj"] = "OBJ files (*.obj)|*.obj;*.OBJ";
- FILE_WILDCARDS["amf"] = "AMF files (*.amf)|*.zip.amf;*.amf;*.AMF;*.xml;*.XML";
- FILE_WILDCARDS["3mf"] = "3MF files (*.3mf)|*.3mf;*.3MF;";
- FILE_WILDCARDS["prusa"] = "Prusa Control files (*.prusa)|*.prusa;*.PRUSA";
- FILE_WILDCARDS["ini"] = "INI files *.ini|*.ini;*.INI";
+ FILE_WILDCARDS["known"] = "Known files (*.stl, *.obj, *.amf, *.xml, *.prusa)|*.stl;*.STL;*.obj;*.OBJ;*.amf;*.AMF;*.xml;*.XML;*.prusa;*.PRUSA";
+ FILE_WILDCARDS["stl"] = "STL files (*.stl)|*.stl;*.STL";
+ FILE_WILDCARDS["obj"] = "OBJ files (*.obj)|*.obj;*.OBJ";
+ FILE_WILDCARDS["amf"] = "AMF files (*.amf)|*.zip.amf;*.amf;*.AMF;*.xml;*.XML";
+ FILE_WILDCARDS["3mf"] = "3MF files (*.3mf)|*.3mf;*.3MF;";
+ FILE_WILDCARDS["prusa"] = "Prusa Control files (*.prusa)|*.prusa;*.PRUSA";
+ FILE_WILDCARDS["ini"] = "INI files *.ini|*.ini;*.INI";
FILE_WILDCARDS["gcode"] = "G-code files (*.gcode, *.gco, *.g, *.ngc)|*.gcode;*.GCODE;*.gco;*.GCO;*.g;*.G;*.ngc;*.NGC";
- FILE_WILDCARDS["svg"] = "SVG files *.svg|*.svg;*.SVG";
+ FILE_WILDCARDS["svg"] = "SVG files *.svg|*.svg;*.SVG";
}
return FILE_WILDCARDS;
}
+struct PresetTab {
+ std::string name;
+ Tab* panel;
+ PrinterTechnology technology;
+};
+
+
void disable_screensaver();
void enable_screensaver();
-std::vector<std::string> scan_serial_ports();
bool debugged();
void break_to_debugger();
@@ -78,28 +103,80 @@ void set_tab_panel(wxNotebook *tab_panel);
void set_plater(wxPanel *plater);
void set_app_config(AppConfig *app_config);
void set_preset_bundle(PresetBundle *preset_bundle);
-
-AppConfig* get_app_config();
-wxApp* get_app();
-wxColour* get_modified_label_clr();
-
-void add_debug_menu(wxMenuBar *menu, int event_language_change);
+void set_preset_updater(PresetUpdater *updater);
+void set_3DScene(_3DScene *scene);
+void set_objects_from_perl( wxWindow* parent,
+ wxBoxSizer *frequently_changed_parameters_sizer,
+ wxBoxSizer *expert_mode_part_sizer,
+ wxBoxSizer *scrolled_window_sizer,
+ wxButton *btn_export_gcode,
+ wxButton *btn_export_stl,
+ wxButton *btn_reslice,
+ wxButton *btn_print,
+ wxButton *btn_send_gcode,
+ wxStaticBitmap *manifold_warning_icon);
+void set_show_print_info(bool show);
+void set_show_manifold_warning_icon(bool show);
+void set_objects_list_sizer(wxBoxSizer *objects_list_sizer);
+
+AppConfig* get_app_config();
+wxApp* get_app();
+PresetBundle* get_preset_bundle();
+wxFrame* get_main_frame();
+wxNotebook * get_tab_panel();
+wxNotebook* get_tab_panel();
+
+const wxColour& get_label_clr_modified();
+const wxColour& get_label_clr_sys();
+const wxColour& get_label_clr_default();
+unsigned get_colour_approx_luma(const wxColour &colour);
+void set_label_clr_modified(const wxColour& clr);
+void set_label_clr_sys(const wxColour& clr);
+
+const wxFont& small_font();
+const wxFont& bold_font();
+
+void open_model(wxWindow *parent, wxArrayString& input_files);
+
+wxWindow* get_right_panel();
+const size_t& label_width();
+
+Tab* get_tab(const std::string& name);
+const std::vector<PresetTab>& get_preset_tabs();
+
+extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change);
+
+// This is called when closing the application, when loading a config file or when starting the config wizard
+// to notify the user whether he is aware that some preset changes will be lost.
+extern bool check_unsaved_changes();
+
+// Checks if configuration wizard needs to run, calls config_wizard if so.
+// Returns whether the Wizard ran.
+extern bool config_wizard_startup(bool app_config_exists);
+
+// Opens the configuration wizard, returns true if wizard is finished & accepted.
+// The run_reason argument is actually ConfigWizard::RunReason, but int is used here because of Perl.
+extern void config_wizard(int run_reason);
// Create "Preferences" dialog after selecting menu "Preferences" in Perl part
-void open_preferences_dialog(int event_preferences);
+extern void open_preferences_dialog(int event_preferences);
// Create a new preset tab (print, filament and printer),
void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed);
TabIface* get_preset_tab_iface(char *name);
// add it at the end of the tab panel.
-void add_created_tab(Tab* panel);
+void add_created_tab(Tab* panel, int event_value_change, int event_presets_changed);
// Change option value in config
-void change_opt_value(DynamicPrintConfig& config, t_config_option_key opt_key, boost::any value, int opt_index = 0);
+void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index = 0);
+
+// Update UI / Tabs to reflect changes in the currently loaded presets
+void load_current_presets();
-void show_error(wxWindow* parent, wxString message);
-void show_info(wxWindow* parent, wxString message, wxString title);
-void warning_catcher(wxWindow* parent, wxString message);
+void show_error(wxWindow* parent, const wxString& message);
+void show_error_id(int id, const std::string& message); // For Perl
+void show_info(wxWindow* parent, const wxString& message, const wxString& title);
+void warning_catcher(wxWindow* parent, const wxString& message);
// Assign a Lambda to the print object to emit a wxWidgets Command with the provided ID
// to deliver a progress status message.
@@ -113,6 +190,8 @@ void save_language();
void get_installed_languages(wxArrayString & names, wxArrayLong & identifiers);
// select language from the list of installed languages
bool select_language(wxArrayString & names, wxArrayLong & identifiers);
+// update right panel of the Plater according to view mode
+void update_mode();
std::vector<Tab *>& get_tabs_list();
bool checked_tab(Tab* tab);
@@ -132,12 +211,36 @@ wxString L_str(const std::string &str);
// Return wxString from std::string in UTF8
wxString from_u8(const std::string &str);
-
+void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer,
+ Model &model,
+ int event_object_selection_changed,
+ int event_object_settings_changed,
+ int event_remove_object,
+ int event_update_scene);
void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer);
-
-ConfigOptionsGroup* get_optgroup();
-
-}
-}
+// Update view mode according to selected menu
+void update_mode();
+bool is_expert_mode();
+
+// Callback to trigger a configuration update timer on the Plater.
+static PerlCallback g_on_request_update_callback;
+
+ConfigOptionsGroup* get_optgroup(size_t i);
+std::vector <std::shared_ptr<ConfigOptionsGroup>>& get_optgroups();
+wxButton* get_wiping_dialog_button();
+
+void add_export_option(wxFileDialog* dlg, const std::string& format);
+int get_export_option(wxFileDialog* dlg);
+
+// Returns the dimensions of the screen on which the main frame is displayed
+void get_current_screen_size(unsigned &width, unsigned &height);
+
+// Display an About dialog
+extern void about();
+// Ask the destop to open the datadir using the default file explorer.
+extern void desktop_open_datadir_folder();
+
+} // namespace GUI
+} // namespace Slic3r
#endif
diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp
new file mode 100644
index 000000000..af57db8ed
--- /dev/null
+++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp
@@ -0,0 +1,1723 @@
+#include "GUI.hpp"
+#include "OptionsGroup.hpp"
+#include "PresetBundle.hpp"
+#include "GUI_ObjectParts.hpp"
+#include "Model.hpp"
+#include "wxExtensions.hpp"
+#include "LambdaObjectDialog.hpp"
+#include "../../libslic3r/Utils.hpp"
+
+#include <wx/msgdlg.h>
+#include <boost/filesystem.hpp>
+#include <boost/algorithm/string.hpp>
+#include "Geometry.hpp"
+#include "slic3r/Utils/FixModelByWin10.hpp"
+
+namespace Slic3r
+{
+namespace GUI
+{
+wxSizer *m_sizer_object_buttons = nullptr;
+wxSizer *m_sizer_part_buttons = nullptr;
+wxSizer *m_sizer_object_movers = nullptr;
+wxDataViewCtrl *m_objects_ctrl = nullptr;
+PrusaObjectDataViewModel *m_objects_model = nullptr;
+wxCollapsiblePane *m_collpane_settings = nullptr;
+
+wxIcon m_icon_modifiermesh;
+wxIcon m_icon_solidmesh;
+wxIcon m_icon_manifold_warning;
+wxBitmap m_bmp_cog;
+wxBitmap m_bmp_split;
+
+wxSlider* m_mover_x = nullptr;
+wxSlider* m_mover_y = nullptr;
+wxSlider* m_mover_z = nullptr;
+wxButton* m_btn_move_up = nullptr;
+wxButton* m_btn_move_down = nullptr;
+Vec3d m_move_options;
+Vec3d m_last_coords;
+int m_selected_object_id = -1;
+
+bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select()
+ // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler
+ // calls this method again and again and again
+bool g_is_percent_scale = false; // It indicates if scale unit is percentage
+bool g_is_uniform_scale = false; // It indicates if scale is uniform
+ModelObjectPtrs* m_objects;
+std::shared_ptr<DynamicPrintConfig*> m_config;
+std::shared_ptr<DynamicPrintConfig> m_default_config;
+wxBoxSizer* m_option_sizer = nullptr;
+
+// option groups for settings
+std::vector <std::shared_ptr<ConfigOptionsGroup>> m_og_settings;
+
+int m_event_object_selection_changed = 0;
+int m_event_object_settings_changed = 0;
+int m_event_remove_object = 0;
+int m_event_update_scene = 0;
+
+bool m_parts_changed = false;
+bool m_part_settings_changed = false;
+
+#ifdef __WXOSX__
+ wxString g_selected_extruder = "";
+#endif //__WXOSX__
+
+// typedef std::map<std::string, std::string> t_category_icon;
+typedef std::map<std::string, wxBitmap> t_category_icon;
+inline t_category_icon& get_category_icon() {
+ static t_category_icon CATEGORY_ICON;
+ if (CATEGORY_ICON.empty()){
+ CATEGORY_ICON[L("Layers and Perimeters")] = wxBitmap(from_u8(Slic3r::var("layers.png")), wxBITMAP_TYPE_PNG);
+ CATEGORY_ICON[L("Infill")] = wxBitmap(from_u8(Slic3r::var("infill.png")), wxBITMAP_TYPE_PNG);
+ CATEGORY_ICON[L("Support material")] = wxBitmap(from_u8(Slic3r::var("building.png")), wxBITMAP_TYPE_PNG);
+ CATEGORY_ICON[L("Speed")] = wxBitmap(from_u8(Slic3r::var("time.png")), wxBITMAP_TYPE_PNG);
+ CATEGORY_ICON[L("Extruders")] = wxBitmap(from_u8(Slic3r::var("funnel.png")), wxBITMAP_TYPE_PNG);
+ CATEGORY_ICON[L("Extrusion Width")] = wxBitmap(from_u8(Slic3r::var("funnel.png")), wxBITMAP_TYPE_PNG);
+// CATEGORY_ICON[L("Skirt and brim")] = wxBitmap(from_u8(Slic3r::var("box.png")), wxBITMAP_TYPE_PNG);
+// CATEGORY_ICON[L("Speed > Acceleration")] = wxBitmap(from_u8(Slic3r::var("time.png")), wxBITMAP_TYPE_PNG);
+ CATEGORY_ICON[L("Advanced")] = wxBitmap(from_u8(Slic3r::var("wand.png")), wxBITMAP_TYPE_PNG);
+ }
+ return CATEGORY_ICON;
+}
+
+std::vector<std::string> get_options(const bool is_part)
+{
+ PrintRegionConfig reg_config;
+ auto options = reg_config.keys();
+ if (!is_part) {
+ PrintObjectConfig obj_config;
+ std::vector<std::string> obj_options = obj_config.keys();
+ options.insert(options.end(), obj_options.begin(), obj_options.end());
+ }
+ return options;
+}
+
+// category -> vector ( option ; label )
+typedef std::map< std::string, std::vector< std::pair<std::string, std::string> > > settings_menu_hierarchy;
+void get_options_menu(settings_menu_hierarchy& settings_menu, bool is_part)
+{
+ auto options = get_options(is_part);
+
+ auto extruders_cnt = get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA ? 1 :
+ get_preset_bundle()->printers.get_edited_preset().config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
+
+ DynamicPrintConfig config;
+ for (auto& option : options)
+ {
+ auto const opt = config.def()->get(option);
+ auto category = opt->category;
+ if (category.empty() ||
+ (category == "Extruders" && extruders_cnt == 1)) continue;
+
+ std::pair<std::string, std::string> option_label(option, opt->label);
+ std::vector< std::pair<std::string, std::string> > new_category;
+ auto& cat_opt_label = settings_menu.find(category) == settings_menu.end() ? new_category : settings_menu.at(category);
+ cat_opt_label.push_back(option_label);
+ if (cat_opt_label.size() == 1)
+ settings_menu[category] = cat_opt_label;
+ }
+}
+
+void set_event_object_selection_changed(const int& event){
+ m_event_object_selection_changed = event;
+}
+void set_event_object_settings_changed(const int& event){
+ m_event_object_settings_changed = event;
+}
+void set_event_remove_object(const int& event){
+ m_event_remove_object = event;
+}
+void set_event_update_scene(const int& event){
+ m_event_update_scene = event;
+}
+
+void set_objects_from_model(Model &model) {
+ m_objects = &(model.objects);
+}
+
+void init_mesh_icons(){
+ m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG);
+ m_icon_solidmesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG);
+
+ // init icon for manifold warning
+ m_icon_manifold_warning = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG);
+
+ // init bitmap for "Split to sub-objects" context menu
+ m_bmp_split = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("split.png")), wxBITMAP_TYPE_PNG);
+
+ // init bitmap for "Add Settings" context menu
+ m_bmp_cog = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG);
+}
+
+bool is_parts_changed(){return m_parts_changed;}
+bool is_part_settings_changed(){ return m_part_settings_changed; }
+
+static wxString dots("…", wxConvUTF8);
+
+void set_tooltip_for_item(const wxPoint& pt)
+{
+ wxDataViewItem item;
+ wxDataViewColumn* col;
+ m_objects_ctrl->HitTest(pt, item, col);
+ if (!item) return;
+
+ if (col->GetTitle() == " ")
+ m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings")));
+ else if (col->GetTitle() == _("Name") &&
+ m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) {
+ int obj_idx = m_objects_model->GetIdByItem(item);
+ auto& stats = (*m_objects)[obj_idx]->volumes[0]->mesh.stl.stats;
+ int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
+ stats.facets_added + stats.facets_reversed + stats.backwards_edges;
+
+ wxString tooltip = wxString::Format(_(L("Auto-repaired (%d errors):\n")), errors);
+
+ std::map<std::string, int> error_msg;
+ error_msg[L("degenerate facets")] = stats.degenerate_facets;
+ error_msg[L("edges fixed")] = stats.edges_fixed;
+ error_msg[L("facets removed")] = stats.facets_removed;
+ error_msg[L("facets added")] = stats.facets_added;
+ error_msg[L("facets reversed")] = stats.facets_reversed;
+ error_msg[L("backwards edges")] = stats.backwards_edges;
+
+ for (auto error : error_msg)
+ {
+ if (error.second > 0)
+ tooltip += wxString::Format(_("\t%d %s\n"), error.second, error.first);
+ }
+// OR
+// tooltip += wxString::Format(_(L("%d degenerate facets, %d edges fixed, %d facets removed, "
+// "%d facets added, %d facets reversed, %d backwards edges")),
+// stats.degenerate_facets, stats.edges_fixed, stats.facets_removed,
+// stats.facets_added, stats.facets_reversed, stats.backwards_edges);
+
+ if (is_windows10())
+ tooltip += _(L("Right button click the icon to fix STL through Netfabb"));
+
+ m_objects_ctrl->GetMainWindow()->SetToolTip(tooltip);
+ }
+ else
+ m_objects_ctrl->GetMainWindow()->SetToolTip(""); // hide tooltip
+}
+
+wxPoint get_mouse_position_in_control() {
+ const wxPoint& pt = wxGetMousePosition();
+ wxWindow* win = m_objects_ctrl->GetMainWindow();
+ return wxPoint(pt.x - win->GetScreenPosition().x,
+ pt.y - win->GetScreenPosition().y);
+}
+
+bool is_mouse_position_in_control(wxPoint& pt) {
+ pt = get_mouse_position_in_control();
+ const wxSize& cz = m_objects_ctrl->GetSize();
+ if (pt.x > 0 && pt.x < cz.x &&
+ pt.y > 0 && pt.y < cz.y)
+ return true;
+ return false;
+}
+
+wxDataViewColumn* object_ctrl_create_extruder_column(int extruders_count)
+{
+ wxArrayString choices;
+ choices.Add("default");
+ for (int i = 1; i <= extruders_count; ++i)
+ choices.Add(wxString::Format("%d", i));
+ wxDataViewChoiceRenderer *c =
+ new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_CENTER_HORIZONTAL);
+ wxDataViewColumn* column = new wxDataViewColumn(_(L("Extruder")), c, 2, 60, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE);
+ return column;
+}
+
+void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz)
+{
+ m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize);
+ m_objects_ctrl->SetInitialSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects
+
+ objects_sz = new wxBoxSizer(wxVERTICAL);
+ objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT, 20);
+
+ m_objects_model = new PrusaObjectDataViewModel;
+ m_objects_ctrl->AssociateModel(m_objects_model);
+#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE
+ m_objects_ctrl->EnableDragSource(wxDF_UNICODETEXT);
+ m_objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT);
+#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE
+
+ // column 0(Icon+Text) of the view control:
+ m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 200,
+ wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE);
+
+ // column 1 of the view control:
+ m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 45,
+ wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE);
+
+ // column 2 of the view control:
+ m_objects_ctrl->AppendColumn(object_ctrl_create_extruder_column(4));
+
+ // column 3 of the view control:
+ m_objects_ctrl->AppendBitmapColumn(" ", 3, wxDATAVIEW_CELL_INERT, 25,
+ wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE);
+}
+
+// ****** from GUI.cpp
+wxBoxSizer* create_objects_list(wxWindow *win)
+{
+ wxBoxSizer* objects_sz;
+ // create control
+ create_objects_ctrl(win, objects_sz);
+
+ // describe control behavior
+ m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) {
+ object_ctrl_selection_changed();
+#ifndef __WXMSW__
+ set_tooltip_for_item(get_mouse_position_in_control());
+#endif //__WXMSW__
+ });
+
+ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxDataViewEvent& event) {
+ object_ctrl_context_menu();
+ event.Skip();
+ });
+
+ m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) { object_ctrl_key_event(event); }); // doesn't work on OSX
+
+#ifdef __WXMSW__
+ // Extruder value changed
+ m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { update_extruder_in_config(event.GetString()); });
+
+ m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) {
+ set_tooltip_for_item(event.GetPosition());
+ event.Skip();
+ });
+#else
+ // equivalent to wxEVT_CHOICE on __WXMSW__
+ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) { object_ctrl_item_value_change(event); });
+#endif //__WXMSW__
+
+ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, [](wxDataViewEvent& e) {on_begin_drag(e);});
+ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, [](wxDataViewEvent& e) {on_drop_possible(e); });
+ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_DROP, [](wxDataViewEvent& e) {on_drop(e);});
+ return objects_sz;
+}
+
+wxBoxSizer* create_edit_object_buttons(wxWindow* win)
+{
+ auto sizer = new wxBoxSizer(wxVERTICAL);
+
+ auto btn_load_part = new wxButton(win, wxID_ANY, /*Load */"part" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/);
+ auto btn_load_modifier = new wxButton(win, wxID_ANY, /*Load */"modifier" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/);
+ auto btn_load_lambda_modifier = new wxButton(win, wxID_ANY, /*Load */"generic" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/);
+ auto btn_delete = new wxButton(win, wxID_ANY, "Delete"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/);
+ auto btn_split = new wxButton(win, wxID_ANY, "Split"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/);
+ m_btn_move_up = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT);
+ m_btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT);
+
+ //*** button's functions
+ btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) {
+ on_btn_load(win);
+ });
+
+ btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) {
+ on_btn_load(win, true);
+ });
+
+ btn_load_lambda_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) {
+ on_btn_load(win, true, true);
+ });
+
+ btn_delete ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_del(); });
+ btn_split ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_split(true); });
+ m_btn_move_up ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_move_up(); });
+ m_btn_move_down ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_move_down(); });
+ //***
+
+ m_btn_move_up->SetMinSize(wxSize(20, -1));
+ m_btn_move_down->SetMinSize(wxSize(20, -1));
+ btn_load_part->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG));
+ btn_load_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG));
+ btn_load_lambda_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG));
+ btn_delete->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_delete.png")), wxBITMAP_TYPE_PNG));
+ btn_split->SetBitmap(wxBitmap(from_u8(Slic3r::var("shape_ungroup.png")), wxBITMAP_TYPE_PNG));
+ m_btn_move_up->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_up.png")), wxBITMAP_TYPE_PNG));
+ m_btn_move_down->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_down.png")), wxBITMAP_TYPE_PNG));
+
+ m_sizer_object_buttons = new wxGridSizer(1, 3, 0, 0);
+ m_sizer_object_buttons->Add(btn_load_part, 0, wxEXPAND);
+ m_sizer_object_buttons->Add(btn_load_modifier, 0, wxEXPAND);
+ m_sizer_object_buttons->Add(btn_load_lambda_modifier, 0, wxEXPAND);
+ m_sizer_object_buttons->Show(false);
+
+ m_sizer_part_buttons = new wxGridSizer(1, 3, 0, 0);
+ m_sizer_part_buttons->Add(btn_delete, 0, wxEXPAND);
+ m_sizer_part_buttons->Add(btn_split, 0, wxEXPAND);
+ {
+ auto up_down_sizer = new wxGridSizer(1, 2, 0, 0);
+ up_down_sizer->Add(m_btn_move_up, 1, wxEXPAND);
+ up_down_sizer->Add(m_btn_move_down, 1, wxEXPAND);
+ m_sizer_part_buttons->Add(up_down_sizer, 0, wxEXPAND);
+ }
+ m_sizer_part_buttons->Show(false);
+
+ btn_load_part->SetFont(Slic3r::GUI::small_font());
+ btn_load_modifier->SetFont(Slic3r::GUI::small_font());
+ btn_load_lambda_modifier->SetFont(Slic3r::GUI::small_font());
+ btn_delete->SetFont(Slic3r::GUI::small_font());
+ btn_split->SetFont(Slic3r::GUI::small_font());
+ m_btn_move_up->SetFont(Slic3r::GUI::small_font());
+ m_btn_move_down->SetFont(Slic3r::GUI::small_font());
+
+ sizer->Add(m_sizer_object_buttons, 0, wxEXPAND | wxLEFT, 20);
+ sizer->Add(m_sizer_part_buttons, 0, wxEXPAND | wxLEFT, 20);
+ return sizer;
+}
+
+void update_after_moving()
+{
+ auto item = m_objects_ctrl->GetSelection();
+ if (!item || m_selected_object_id<0)
+ return;
+
+ auto volume_id = m_objects_model->GetVolumeIdByItem(item);
+ if (volume_id < 0)
+ return;
+
+ Vec3d m = m_move_options;
+ Vec3d l = m_last_coords;
+
+ auto d = Vec3d(m(0) - l(0), m(1) - l(1), m(2) - l(2));
+ auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id];
+ volume->mesh.translate(d(0), d(1), d(2));
+ m_last_coords = m;
+
+ m_parts_changed = true;
+ parts_changed(m_selected_object_id);
+}
+
+wxSizer* object_movers(wxWindow *win)
+{
+// DynamicPrintConfig* config = &get_preset_bundle()->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume
+ std::shared_ptr<ConfigOptionsGroup> optgroup = std::make_shared<ConfigOptionsGroup>(win, "Move"/*, config*/);
+ optgroup->label_width = 20;
+ optgroup->m_on_change = [](t_config_option_key opt_key, boost::any value){
+ int val = boost::any_cast<int>(value);
+ bool update = false;
+ if (opt_key == "x" && m_move_options(0) != val){
+ update = true;
+ m_move_options(0) = val;
+ }
+ else if (opt_key == "y" && m_move_options(1) != val){
+ update = true;
+ m_move_options(1) = val;
+ }
+ else if (opt_key == "z" && m_move_options(2) != val){
+ update = true;
+ m_move_options(2) = val;
+ }
+ if (update) update_after_moving();
+ };
+
+ ConfigOptionDef def;
+ def.label = L("X");
+ def.type = coInt;
+ def.gui_type = "slider";
+ def.default_value = new ConfigOptionInt(0);
+
+ Option option = Option(def, "x");
+ option.opt.full_width = true;
+ optgroup->append_single_option_line(option);
+ m_mover_x = dynamic_cast<wxSlider*>(optgroup->get_field("x")->getWindow());
+
+ def.label = L("Y");
+ option = Option(def, "y");
+ optgroup->append_single_option_line(option);
+ m_mover_y = dynamic_cast<wxSlider*>(optgroup->get_field("y")->getWindow());
+
+ def.label = L("Z");
+ option = Option(def, "z");
+ optgroup->append_single_option_line(option);
+ m_mover_z = dynamic_cast<wxSlider*>(optgroup->get_field("z")->getWindow());
+
+ get_optgroups().push_back(optgroup); // ogObjectMovers
+
+ m_sizer_object_movers = optgroup->sizer;
+ m_sizer_object_movers->Show(false);
+
+ m_move_options = Vec3d(0, 0, 0);
+ m_last_coords = Vec3d(0, 0, 0);
+
+ return optgroup->sizer;
+}
+
+wxBoxSizer* content_settings(wxWindow *win)
+{
+ DynamicPrintConfig* config = &get_preset_bundle()->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume
+ std::shared_ptr<ConfigOptionsGroup> optgroup = std::make_shared<ConfigOptionsGroup>(win, "Extruders", config);
+ optgroup->label_width = label_width();
+
+ Option option = optgroup->get_option("extruder");
+ option.opt.default_value = new ConfigOptionInt(1);
+ optgroup->append_single_option_line(option);
+
+ get_optgroups().push_back(optgroup); // ogObjectSettings
+
+ auto sizer = new wxBoxSizer(wxVERTICAL);
+ sizer->Add(create_edit_object_buttons(win), 0, wxEXPAND, 0); // *** Edit Object Buttons***
+
+ sizer->Add(optgroup->sizer, 1, wxEXPAND | wxLEFT, 20);
+
+ auto add_btn = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
+ if (wxMSW) add_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+ add_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG));
+ sizer->Add(add_btn, 0, wxALIGN_LEFT | wxLEFT, 20);
+
+ sizer->Add(object_movers(win), 0, wxEXPAND | wxLEFT, 20);
+
+ return sizer;
+}
+
+void add_objects_list(wxWindow* parent, wxBoxSizer* sizer)
+{
+ const auto ol_sizer = create_objects_list(parent);
+ sizer->Add(ol_sizer, 1, wxEXPAND | wxTOP, 20);
+ set_objects_list_sizer(ol_sizer);
+}
+
+Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value = 0)
+{
+ Line line = { _(option_name), "" };
+ if (option_name == "Scale") {
+ line.near_label_widget = [](wxWindow* parent) {
+ auto btn = new PrusaLockButton(parent, wxID_ANY);
+ btn->Bind(wxEVT_BUTTON, [btn](wxCommandEvent &event){
+ event.Skip();
+ wxTheApp->CallAfter([btn]() { set_uniform_scaling(btn->IsLocked()); });
+ });
+ return btn;
+ };
+ }
+
+ ConfigOptionDef def;
+ def.type = coInt;
+ def.default_value = new ConfigOptionInt(def_value);
+ def.width = 55;
+
+ if (option_name == "Rotation")
+ def.min = -360;
+
+ const std::string lower_name = boost::algorithm::to_lower_copy(option_name);
+
+ std::vector<std::string> axes{ "x", "y", "z" };
+ for (auto axis : axes) {
+ if (axis == "z" && option_name != "Scale")
+ def.sidetext = sidetext;
+ Option option = Option(def, lower_name + "_" + axis);
+ option.opt.full_width = true;
+ line.append_option(option);
+ }
+
+ if (option_name == "Scale")
+ {
+ def.width = 45;
+ def.type = coStrings;
+ def.gui_type = "select_open";
+ def.enum_labels.push_back(L("%"));
+ def.enum_labels.push_back(L("mm"));
+ def.default_value = new ConfigOptionStrings{ "mm" };
+
+ const Option option = Option(def, lower_name + "_unit");
+ line.append_option(option);
+ }
+
+ return line;
+}
+
+void add_object_settings(wxWindow* parent, wxBoxSizer* sizer)
+{
+ auto optgroup = std::make_shared<ConfigOptionsGroup>(parent, _(L("Object Settings")));
+ optgroup->label_width = 100;
+ optgroup->set_grid_vgap(5);
+
+ optgroup->m_on_change = [](t_config_option_key opt_key, boost::any value){
+ if (opt_key == "scale_unit"){
+ const wxString& selection = boost::any_cast<wxString>(value);
+ std::vector<std::string> axes{ "x", "y", "z" };
+ for (auto axis : axes) {
+ std::string key = "scale_" + axis;
+ get_optgroup(ogFrequentlyObjectSettings)->set_side_text(key, selection);
+ }
+
+ g_is_percent_scale = selection == _("%");
+ update_scale_values();
+ }
+ };
+
+ ConfigOptionDef def;
+
+ // Objects(sub-objects) name
+ def.label = L("Name");
+// def.type = coString;
+ def.gui_type = "legend";
+ def.tooltip = L("Object name");
+ def.full_width = true;
+ def.default_value = new ConfigOptionString{ " " };
+ optgroup->append_single_option_line(Option(def, "object_name"));
+
+
+ // Legend for object modification
+ auto line = Line{ "", "" };
+ def.label = "";
+ def.type = coString;
+ def.width = 55;
+
+ std::vector<std::string> axes{ "x", "y", "z" };
+ for (const auto axis : axes) {
+ const auto label = boost::algorithm::to_upper_copy(axis);
+ def.default_value = new ConfigOptionString{ " "+label };
+ Option option = Option(def, axis + "_axis_legend");
+ line.append_option(option);
+ }
+ optgroup->append_line(line);
+
+
+ // Settings table
+ optgroup->append_line(add_og_to_object_settings(L("Position"), L("mm")));
+ optgroup->append_line(add_og_to_object_settings(L("Rotation"), "°"));
+ optgroup->append_line(add_og_to_object_settings(L("Scale"), "mm"));
+
+
+ def.label = L("Place on bed");
+ def.type = coBool;
+ def.tooltip = L("Automatic placing of models on printing bed in Y axis");
+ def.gui_type = "";
+ def.sidetext = "";
+ def.default_value = new ConfigOptionBool{ false };
+ optgroup->append_single_option_line(Option(def, "place_on_bed"));
+
+ m_option_sizer = new wxBoxSizer(wxVERTICAL);
+ optgroup->sizer->Add(m_option_sizer, 1, wxEXPAND | wxLEFT, 5);
+
+ sizer->Add(optgroup->sizer, 0, wxEXPAND | wxLEFT | wxTOP, 20);
+
+ optgroup->disable();
+
+ get_optgroups().push_back(optgroup); // ogFrequentlyObjectSettings
+}
+
+
+// add Collapsible Pane to sizer
+wxCollapsiblePane* add_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, const wxString& name, std::function<wxSizer *(wxWindow *)> content_function)
+{
+#ifdef __WXMSW__
+ auto *collpane = new PrusaCollapsiblePaneMSW(parent, wxID_ANY, name);
+#else
+ auto *collpane = new PrusaCollapsiblePane/*wxCollapsiblePane*/(parent, wxID_ANY, name);
+#endif // __WXMSW__
+ // add the pane with a zero proportion value to the sizer which contains it
+ sizer_parent->Add(collpane, 0, wxGROW | wxALL, 0);
+
+ wxWindow *win = collpane->GetPane();
+
+ wxSizer *sizer = content_function(win);
+
+ wxSizer *sizer_pane = new wxBoxSizer(wxVERTICAL);
+ sizer_pane->Add(sizer, 1, wxGROW | wxEXPAND | wxBOTTOM, 2);
+ win->SetSizer(sizer_pane);
+ // sizer_pane->SetSizeHints(win);
+ return collpane;
+}
+
+void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer)
+{
+ // *** Objects List ***
+ auto collpane = add_collapsible_pane(parent, sizer, "Objects List:", create_objects_list);
+ collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([collpane](wxCommandEvent& e){
+ // wxWindowUpdateLocker noUpdates(g_right_panel);
+ if (collpane->IsCollapsed()) {
+ m_sizer_object_buttons->Show(false);
+ m_sizer_part_buttons->Show(false);
+ m_sizer_object_movers->Show(false);
+ if (!m_objects_ctrl->HasSelection())
+ m_collpane_settings->Show(false);
+ }
+ }));
+
+ // *** Object/Part Settings ***
+ m_collpane_settings = add_collapsible_pane(parent, sizer, "Object Settings", content_settings);
+}
+
+void show_collpane_settings(bool expert_mode)
+{
+ m_collpane_settings->Show(expert_mode && !m_objects_model->IsEmpty());
+}
+
+void add_object_to_list(const std::string &name, ModelObject* model_object)
+{
+ wxString item_name = name;
+ auto item = m_objects_model->Add(item_name, model_object->instances.size());
+ m_objects_ctrl->Select(item);
+
+ // Add error icon if detected auto-repaire
+ auto stats = model_object->volumes[0]->mesh.stl.stats;
+ int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed +
+ stats.facets_added + stats.facets_reversed + stats.backwards_edges;
+ if (errors > 0) {
+ const wxDataViewIconText data(item_name, m_icon_manifold_warning);
+ wxVariant variant;
+ variant << data;
+ m_objects_model->SetValue(variant, item, 0);
+ }
+
+ if (model_object->volumes.size() > 1) {
+ for (auto id = 0; id < model_object->volumes.size(); id++)
+ m_objects_model->AddChild(item,
+ model_object->volumes[id]->name,
+ m_icon_solidmesh,
+ model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value,
+ false);
+ m_objects_ctrl->Expand(item);
+ }
+
+#ifndef __WXOSX__
+ object_ctrl_selection_changed();
+#endif //__WXMSW__
+}
+
+void delete_object_from_list()
+{
+ auto item = m_objects_ctrl->GetSelection();
+ if (!item || m_objects_model->GetParent(item) != wxDataViewItem(0))
+ return;
+// m_objects_ctrl->Select(m_objects_model->Delete(item));
+ m_objects_model->Delete(item);
+
+ part_selection_changed();
+
+// if (m_objects_model->IsEmpty())
+// m_collpane_settings->Show(false);
+}
+
+void delete_all_objects_from_list()
+{
+ m_objects_model->DeleteAll();
+
+ part_selection_changed();
+// m_collpane_settings->Show(false);
+}
+
+void set_object_count(int idx, int count)
+{
+ m_objects_model->SetValue(wxString::Format("%d", count), idx, 1);
+ m_objects_ctrl->Refresh();
+}
+
+void unselect_objects()
+{
+ if (!m_objects_ctrl->GetSelection())
+ return;
+
+ g_prevent_list_events = true;
+ m_objects_ctrl->UnselectAll();
+ part_selection_changed();
+ g_prevent_list_events = false;
+}
+
+void select_current_object(int idx)
+{
+ g_prevent_list_events = true;
+ m_objects_ctrl->UnselectAll();
+ if (idx < 0) {
+ g_prevent_list_events = false;
+ return;
+ }
+ m_objects_ctrl->Select(m_objects_model->GetItemById(idx));
+ part_selection_changed();
+ g_prevent_list_events = false;
+}
+
+void remove()
+{
+ auto item = m_objects_ctrl->GetSelection();
+ if (!item)
+ return;
+
+ if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
+ if (m_event_remove_object > 0) {
+ wxCommandEvent event(m_event_remove_object);
+ get_main_frame()->ProcessWindowEvent(event);
+ }
+// delete_object_from_list();
+ }
+ else
+ on_btn_del();
+}
+
+void object_ctrl_selection_changed()
+{
+ if (g_prevent_list_events) return;
+
+ part_selection_changed();
+
+ if (m_event_object_selection_changed > 0) {
+ wxCommandEvent event(m_event_object_selection_changed);
+ event.SetInt(int(m_objects_model->GetParent(m_objects_ctrl->GetSelection()) != wxDataViewItem(0)));
+ event.SetId(m_selected_object_id);
+ get_main_frame()->ProcessWindowEvent(event);
+ }
+
+#ifdef __WXOSX__
+ update_extruder_in_config(g_selected_extruder);
+#endif //__WXOSX__
+}
+
+void object_ctrl_context_menu()
+{
+ wxDataViewItem item;
+ wxDataViewColumn* col;
+ printf("object_ctrl_context_menu\n");
+ const wxPoint pt = get_mouse_position_in_control();
+ printf("mouse_position_in_control: x = %d, y = %d\n", pt.x, pt.y);
+ m_objects_ctrl->HitTest(pt, item, col);
+ if (!item)
+#ifdef __WXOSX__ // #ys_FIXME temporary workaround for OSX
+ // after Yosemite OS X version, HitTest return undefined item
+ item = m_objects_ctrl->GetSelection();
+ if (item)
+ show_context_menu();
+ else
+ printf("undefined item\n");
+ return;
+#else
+ return;
+#endif // __WXOSX__
+ printf("item exists\n");
+ const wxString title = col->GetTitle();
+ printf("title = *%s*\n", title.data().AsChar());
+
+ if (title == " ")
+ show_context_menu();
+// #ys_FIXME
+// else if (title == _("Name") && pt.x >15 &&
+// m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData())
+// {
+// if (is_windows10())
+// fix_through_netfabb();
+// }
+#ifndef __WXMSW__
+ m_objects_ctrl->GetMainWindow()->SetToolTip(""); // hide tooltip
+#endif //__WXMSW__
+}
+
+void object_ctrl_key_event(wxKeyEvent& event)
+{
+ if (event.GetKeyCode() == WXK_TAB)
+ m_objects_ctrl->Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward);
+ else if (event.GetKeyCode() == WXK_DELETE
+#ifdef __WXOSX__
+ || event.GetKeyCode() == WXK_BACK
+#endif //__WXOSX__
+ ){
+ printf("WXK_BACK\n");
+ remove();
+ }
+ else
+ event.Skip();
+}
+
+void object_ctrl_item_value_change(wxDataViewEvent& event)
+{
+ if (event.GetColumn() == 2)
+ {
+ wxVariant variant;
+ m_objects_model->GetValue(variant, event.GetItem(), 2);
+#ifdef __WXOSX__
+ g_selected_extruder = variant.GetString();
+#else // --> for Linux
+ update_extruder_in_config(variant.GetString());
+#endif //__WXOSX__
+ }
+}
+
+//update_optgroup
+void update_settings_list()
+{
+#ifdef __WXGTK__
+ auto parent = get_optgroup(ogFrequentlyObjectSettings)->get_parent();
+#else
+ auto parent = get_optgroup(ogFrequentlyObjectSettings)->parent();
+#endif /* __WXGTK__ */
+
+// There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/Slic3r/issues/898 and https://github.com/prusa3d/Slic3r/issues/952.
+// The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason,
+// we will Thaw the UI prematurely on Linux. This means destroing the no_updates object prematurely.
+#ifdef __linux__
+ std::unique_ptr<wxWindowUpdateLocker> no_updates(new wxWindowUpdateLocker(parent));
+#else
+ wxWindowUpdateLocker noUpdates(parent);
+#endif
+
+ m_option_sizer->Clear(true);
+
+ if (m_config)
+ {
+ auto extra_column = [](wxWindow* parent, const Line& line)
+ {
+ auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line
+
+ auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("erase.png")), wxBITMAP_TYPE_PNG),
+ wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
+ btn->Bind(wxEVT_BUTTON, [opt_key](wxEvent &event){
+ (*m_config)->erase(opt_key);
+ wxTheApp->CallAfter([]() { update_settings_list(); });
+ });
+ return btn;
+ };
+
+ std::map<std::string, std::vector<std::string>> cat_options;
+ auto opt_keys = (*m_config)->keys();
+ if (opt_keys.size() == 1 && opt_keys[0] == "extruder")
+ return;
+
+ auto extruders_cnt = get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA ? 1 :
+ get_preset_bundle()->printers.get_edited_preset().config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
+
+ for (auto& opt_key : opt_keys) {
+ auto category = (*m_config)->def()->get(opt_key)->category;
+ if (category.empty() ||
+ (category == "Extruders" && extruders_cnt==1)) continue;
+
+ std::vector< std::string > new_category;
+
+ auto& cat_opt = cat_options.find(category) == cat_options.end() ? new_category : cat_options.at(category);
+ cat_opt.push_back(opt_key);
+ if (cat_opt.size() == 1)
+ cat_options[category] = cat_opt;
+ }
+
+
+ m_og_settings.resize(0);
+ for (auto& cat : cat_options) {
+ if (cat.second.size() == 1 && cat.second[0] == "extruder")
+ continue;
+
+ auto optgroup = std::make_shared<ConfigOptionsGroup>(parent, cat.first, *m_config, false, ogDEFAULT, extra_column);
+ optgroup->label_width = 100;
+ optgroup->sidetext_width = 70;
+
+ for (auto& opt : cat.second)
+ {
+ if (opt == "extruder")
+ continue;
+ Option option = optgroup->get_option(opt);
+ option.opt.width = 70;
+ optgroup->append_single_option_line(option);
+ }
+ optgroup->reload_config();
+ m_option_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0);
+ m_og_settings.push_back(optgroup);
+ }
+ }
+
+#ifdef __linux__
+ no_updates.reset(nullptr);
+#endif
+
+ /*get_right_panel()*/parent->Layout();
+ get_right_panel()->GetParent()->GetParent()->Layout();
+}
+
+void get_settings_choice(wxMenu *menu, int id, bool is_part)
+{
+ auto category_name = menu->GetLabel(id);
+
+ wxArrayString names;
+ wxArrayInt selections;
+
+ settings_menu_hierarchy settings_menu;
+ get_options_menu(settings_menu, is_part);
+ std::vector< std::pair<std::string, std::string> > *settings_list = nullptr;
+
+ auto opt_keys = (*m_config)->keys();
+
+ for (auto& cat : settings_menu)
+ {
+ if (_(cat.first) == category_name) {
+ int sel = 0;
+ for (auto& pair : cat.second) {
+ names.Add(_(pair.second));
+ if (find(opt_keys.begin(), opt_keys.end(), pair.first) != opt_keys.end())
+ selections.Add(sel);
+ sel++;
+ }
+ settings_list = &cat.second;
+ break;
+ }
+ }
+
+ if (!settings_list)
+ return;
+
+ if (wxGetMultipleChoices(selections, _(L("Select showing settings")), category_name, names) ==0 )
+ return;
+
+ std::vector <std::string> selected_options;
+ for (auto sel : selections)
+ selected_options.push_back((*settings_list)[sel].first);
+
+ for (auto& setting:(*settings_list) )
+ {
+ auto& opt_key = setting.first;
+ if (find(opt_keys.begin(), opt_keys.end(), opt_key) != opt_keys.end() &&
+ find(selected_options.begin(), selected_options.end(), opt_key) == selected_options.end())
+ (*m_config)->erase(opt_key);
+
+ if(find(opt_keys.begin(), opt_keys.end(), opt_key) == opt_keys.end() &&
+ find(selected_options.begin(), selected_options.end(), opt_key) != selected_options.end())
+ (*m_config)->set_key_value(opt_key, m_default_config.get()->option(opt_key)->clone());
+ }
+
+ update_settings_list();
+}
+
+bool cur_item_hase_children()
+{
+ wxDataViewItemArray children;
+ if (m_objects_model->GetChildren(m_objects_ctrl->GetSelection(), children) > 0)
+ return true;
+ return false;
+}
+
+wxMenuItem* menu_item_split(wxMenu* menu, int id) {
+ auto menu_item = new wxMenuItem(menu, id, _(L("Split to parts")));
+ menu_item->SetBitmap(m_bmp_split);
+ return menu_item;
+}
+
+wxMenuItem* menu_item_settings(wxMenu* menu, int id) {
+ auto menu_item = new wxMenuItem(menu, id, _(L("Add settings")));
+ menu_item->SetBitmap(m_bmp_cog);
+
+ auto sub_menu = create_add_settings_popupmenu(false);
+ menu_item->SetSubMenu(sub_menu);
+ return menu_item;
+}
+
+wxMenu *create_add_part_popupmenu()
+{
+ wxMenu *menu = new wxMenu;
+ std::vector<std::string> menu_items = { L("Add part"), L("Add modifier"), L("Add generic") };
+
+ wxWindowID config_id_base = wxWindow::NewControlId(menu_items.size()+2);
+
+ int i = 0;
+ for (auto& item : menu_items) {
+ auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item));
+ menu_item->SetBitmap(i == 0 ? m_icon_solidmesh : m_icon_modifiermesh);
+ menu->Append(menu_item);
+ i++;
+ }
+
+ menu->AppendSeparator();
+ auto menu_item = menu_item_split(menu, config_id_base + i);
+ menu->Append(menu_item);
+ menu_item->Enable(!cur_item_hase_children());
+
+ menu->AppendSeparator();
+ // Append settings popupmenu
+ menu->Append(menu_item_settings(menu, config_id_base + i + 1));
+
+ wxWindow* win = get_tab_panel()->GetPage(0);
+
+ menu->Bind(wxEVT_MENU, [config_id_base, win, menu](wxEvent &event){
+ switch (event.GetId() - config_id_base) {
+ case 0:
+ on_btn_load(win);
+ break;
+ case 1:
+ on_btn_load(win, true);
+ break;
+ case 2:
+ on_btn_load(win, true, true);
+ break;
+ case 3:
+ on_btn_split(false);
+ break;
+ default:{
+ get_settings_choice(menu, event.GetId(), false);
+ break;}
+ }
+ });
+
+ return menu;
+}
+
+wxMenu *create_part_settings_popupmenu()
+{
+ wxMenu *menu = new wxMenu;
+ wxWindowID config_id_base = wxWindow::NewControlId(2);
+
+ menu->Append(menu_item_split(menu, config_id_base));
+
+ menu->AppendSeparator();
+ // Append settings popupmenu
+ menu->Append(menu_item_settings(menu, config_id_base + 1));
+
+ menu->Bind(wxEVT_MENU, [config_id_base, menu](wxEvent &event){
+ switch (event.GetId() - config_id_base) {
+ case 0:
+ on_btn_split(true);
+ break;
+ default:{
+ get_settings_choice(menu, event.GetId(), true);
+ break; }
+ }
+ });
+
+ return menu;
+}
+
+wxMenu *create_add_settings_popupmenu(bool is_part)
+{
+ wxMenu *menu = new wxMenu;
+
+ auto categories = get_category_icon();
+
+ settings_menu_hierarchy settings_menu;
+ get_options_menu(settings_menu, is_part);
+
+ for (auto cat : settings_menu)
+ {
+ auto menu_item = new wxMenuItem(menu, wxID_ANY, _(cat.first));
+ menu_item->SetBitmap(categories.find(cat.first) == categories.end() ?
+ wxNullBitmap : categories.at(cat.first));
+ menu->Append(menu_item);
+ }
+
+ menu->Bind(wxEVT_MENU, [menu](wxEvent &event) {
+ get_settings_choice(menu, event.GetId(), true);
+ });
+
+ return menu;
+}
+
+void show_context_menu()
+{
+ auto item = m_objects_ctrl->GetSelection();
+ if (item)
+ {
+ if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
+ auto menu = create_add_part_popupmenu();
+ get_tab_panel()->GetPage(0)->PopupMenu(menu);
+ }
+ else {
+ auto menu = create_part_settings_popupmenu();
+ get_tab_panel()->GetPage(0)->PopupMenu(menu);
+ }
+ }
+}
+
+// ******
+
+void load_part( wxWindow* parent, ModelObject* model_object,
+ wxArrayString& part_names, const bool is_modifier)
+{
+ wxArrayString input_files;
+ open_model(parent, input_files);
+ for (int i = 0; i < input_files.size(); ++i) {
+ std::string input_file = input_files.Item(i).ToStdString();
+
+ Model model;
+ try {
+ model = Model::read_from_file(input_file);
+ }
+ catch (std::exception &e) {
+ auto msg = _(L("Error! ")) + input_file + " : " + e.what() + ".";
+ show_error(parent, msg);
+ exit(1);
+ }
+
+ for ( auto object : model.objects) {
+ for (auto volume : object->volumes) {
+ auto new_volume = model_object->add_volume(*volume);
+ new_volume->modifier = is_modifier;
+ boost::filesystem::path(input_file).filename().string();
+ new_volume->name = boost::filesystem::path(input_file).filename().string();
+
+ part_names.Add(new_volume->name);
+
+ // apply the same translation we applied to the object
+ new_volume->mesh.translate( model_object->origin_translation(0),
+ model_object->origin_translation(1),
+ model_object->origin_translation(2) );
+ // set a default extruder value, since user can't add it manually
+ new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
+
+ m_parts_changed = true;
+ }
+ }
+ }
+}
+
+void load_lambda( wxWindow* parent, ModelObject* model_object,
+ wxArrayString& part_names, const bool is_modifier)
+{
+ auto dlg = new LambdaObjectDialog(parent);
+ if (dlg->ShowModal() == wxID_CANCEL) {
+ return;
+ }
+
+ std::string name = "lambda-";
+ TriangleMesh mesh;
+
+ auto params = dlg->ObjectParameters();
+ switch (params.type)
+ {
+ case LambdaTypeBox:{
+ mesh = make_cube(params.dim[0], params.dim[1], params.dim[2]);
+ name += "Box";
+ break;}
+ case LambdaTypeCylinder:{
+ mesh = make_cylinder(params.cyl_r, params.cyl_h);
+ name += "Cylinder";
+ break;}
+ case LambdaTypeSphere:{
+ mesh = make_sphere(params.sph_rho);
+ name += "Sphere";
+ break;}
+ case LambdaTypeSlab:{
+ const auto& size = model_object->bounding_box().size();
+ mesh = make_cube(size(0)*1.5, size(1)*1.5, params.slab_h);
+ // box sets the base coordinate at 0, 0, move to center of plate and move it up to initial_z
+ mesh.translate(-size(0)*1.5 / 2.0, -size(1)*1.5 / 2.0, params.slab_z);
+ name += "Slab";
+ break; }
+ default:
+ break;
+ }
+ mesh.repair();
+
+ auto new_volume = model_object->add_volume(mesh);
+ new_volume->modifier = is_modifier;
+ new_volume->name = name;
+ // set a default extruder value, since user can't add it manually
+ new_volume->config.set_key_value("extruder", new ConfigOptionInt(0));
+
+ part_names.Add(name);
+
+ m_parts_changed = true;
+}
+
+void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/* = false*/)
+{
+ auto item = m_objects_ctrl->GetSelection();
+ if (!item)
+ return;
+ int obj_idx = -1;
+ if (m_objects_model->GetParent(item) == wxDataViewItem(0))
+ obj_idx = m_objects_model->GetIdByItem(item);
+ else
+ return;
+
+ if (obj_idx < 0) return;
+ wxArrayString part_names;
+ if (is_lambda)
+ load_lambda(parent, (*m_objects)[obj_idx], part_names, is_modifier);
+ else
+ load_part(parent, (*m_objects)[obj_idx], part_names, is_modifier);
+
+ parts_changed(obj_idx);
+
+ for (int i = 0; i < part_names.size(); ++i)
+ m_objects_ctrl->Select( m_objects_model->AddChild(item, part_names.Item(i),
+ is_modifier ? m_icon_modifiermesh : m_icon_solidmesh));
+// part_selection_changed();
+#ifdef __WXMSW__
+ object_ctrl_selection_changed();
+#endif //__WXMSW__
+}
+
+void on_btn_del()
+{
+ auto item = m_objects_ctrl->GetSelection();
+ if (!item) return;
+
+ auto volume_id = m_objects_model->GetVolumeIdByItem(item);
+ if (volume_id < 0)
+ return;
+ auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id];
+
+ // if user is deleting the last solid part, throw error
+ int solid_cnt = 0;
+ for (auto vol : (*m_objects)[m_selected_object_id]->volumes)
+ if (!vol->modifier)
+ ++solid_cnt;
+ if (!volume->modifier && solid_cnt == 1) {
+ Slic3r::GUI::show_error(nullptr, _(L("You can't delete the last solid part from this object.")));
+ return;
+ }
+
+ (*m_objects)[m_selected_object_id]->delete_volume(volume_id);
+ m_parts_changed = true;
+
+ parts_changed(m_selected_object_id);
+
+ m_objects_ctrl->Select(m_objects_model->Delete(item));
+ part_selection_changed();
+// #ifdef __WXMSW__
+// object_ctrl_selection_changed();
+// #endif //__WXMSW__
+}
+
+void on_btn_split(const bool split_part)
+{
+ auto item = m_objects_ctrl->GetSelection();
+ if (!item || m_selected_object_id<0)
+ return;
+ auto volume_id = m_objects_model->GetVolumeIdByItem(item);
+ ModelVolume* volume;
+ if (volume_id < 0) {
+ if (split_part) return;
+ else
+ volume = (*m_objects)[m_selected_object_id]->volumes[0]; }
+ else
+ volume = (*m_objects)[m_selected_object_id]->volumes[volume_id];
+ DynamicPrintConfig& config = get_preset_bundle()->printers.get_edited_preset().config;
+ auto nozzle_dmrs_cnt = config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
+ auto split_rez = volume->split(nozzle_dmrs_cnt);
+ if (split_rez == 1) {
+ wxMessageBox(_(L("The selected object couldn't be split because it contains only one part.")));
+ return;
+ }
+
+ auto model_object = (*m_objects)[m_selected_object_id];
+
+ if (split_part) {
+ auto parent = m_objects_model->GetParent(item);
+ m_objects_model->DeleteChildren(parent);
+
+ for (auto id = 0; id < model_object->volumes.size(); id++)
+ m_objects_model->AddChild(parent, model_object->volumes[id]->name,
+ model_object->volumes[id]->modifier ? m_icon_modifiermesh : m_icon_solidmesh,
+ model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value,
+ false);
+
+ m_objects_ctrl->Expand(parent);
+ }
+ else {
+ for (auto id = 0; id < model_object->volumes.size(); id++)
+ m_objects_model->AddChild(item, model_object->volumes[id]->name,
+ m_icon_solidmesh,
+ model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value,
+ false);
+ m_objects_ctrl->Expand(item);
+ }
+}
+
+void on_btn_move_up(){
+ auto item = m_objects_ctrl->GetSelection();
+ if (!item)
+ return;
+ auto volume_id = m_objects_model->GetVolumeIdByItem(item);
+ if (volume_id < 0)
+ return;
+ auto& volumes = (*m_objects)[m_selected_object_id]->volumes;
+ if (0 < volume_id && volume_id < volumes.size()) {
+ std::swap(volumes[volume_id - 1], volumes[volume_id]);
+ m_parts_changed = true;
+ m_objects_ctrl->Select(m_objects_model->MoveChildUp(item));
+ part_selection_changed();
+// #ifdef __WXMSW__
+// object_ctrl_selection_changed();
+// #endif //__WXMSW__
+ }
+}
+
+void on_btn_move_down(){
+ auto item = m_objects_ctrl->GetSelection();
+ if (!item)
+ return;
+ auto volume_id = m_objects_model->GetVolumeIdByItem(item);
+ if (volume_id < 0)
+ return;
+ auto& volumes = (*m_objects)[m_selected_object_id]->volumes;
+ if (0 <= volume_id && volume_id+1 < volumes.size()) {
+ std::swap(volumes[volume_id + 1], volumes[volume_id]);
+ m_parts_changed = true;
+ m_objects_ctrl->Select(m_objects_model->MoveChildDown(item));
+ part_selection_changed();
+// #ifdef __WXMSW__
+// object_ctrl_selection_changed();
+// #endif //__WXMSW__
+ }
+}
+
+void parts_changed(int obj_idx)
+{
+ if (m_event_object_settings_changed <= 0) return;
+
+ wxCommandEvent e(m_event_object_settings_changed);
+ auto event_str = wxString::Format("%d %d %d", obj_idx,
+ is_parts_changed() ? 1 : 0,
+ is_part_settings_changed() ? 1 : 0);
+ e.SetString(event_str);
+ get_main_frame()->ProcessWindowEvent(e);
+}
+
+void update_settings_value()
+{
+ auto og = get_optgroup(ogFrequentlyObjectSettings);
+ if (m_selected_object_id < 0 || m_objects->size() <= m_selected_object_id) {
+ og->set_value("position_x", 0);
+ og->set_value("position_y", 0);
+ og->set_value("position_z", 0);
+ og->set_value("scale_x", 0);
+ og->set_value("scale_y", 0);
+ og->set_value("scale_z", 0);
+ og->set_value("rotation_x", 0);
+ og->set_value("rotation_y", 0);
+ og->set_value("rotation_z", 0);
+ og->disable();
+ return;
+ }
+ g_is_percent_scale = boost::any_cast<wxString>(og->get_value("scale_unit")) == _("%");
+ update_position_values();
+ update_scale_values();
+ update_rotation_values();
+ og->enable();
+}
+
+void part_selection_changed()
+{
+ auto item = m_objects_ctrl->GetSelection();
+ int obj_idx = -1;
+ auto og = get_optgroup(ogFrequentlyObjectSettings);
+ if (item)
+ {
+ bool is_part = false;
+ if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
+ obj_idx = m_objects_model->GetIdByItem(item);
+ og->set_name(" " + _(L("Object Settings")) + " ");
+ m_config = std::make_shared<DynamicPrintConfig*>(&(*m_objects)[obj_idx]->config);
+ }
+ else {
+ auto parent = m_objects_model->GetParent(item);
+ // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene
+ obj_idx = m_objects_model->GetIdByItem(parent);
+ og->set_name(" " + _(L("Part Settings")) + " ");
+ is_part = true;
+ auto volume_id = m_objects_model->GetVolumeIdByItem(item);
+ m_config = std::make_shared<DynamicPrintConfig*>(&(*m_objects)[obj_idx]->volumes[volume_id]->config);
+ }
+
+ auto config = m_config;
+ og->set_value("object_name", m_objects_model->GetName(item));
+ m_default_config = std::make_shared<DynamicPrintConfig>(*DynamicPrintConfig::new_from_defaults_keys(get_options(is_part)));
+ }
+ else {
+ wxString empty_str = wxEmptyString;
+ og->set_value("object_name", empty_str);
+ m_config = nullptr;
+ }
+
+ update_settings_list();
+
+ m_selected_object_id = obj_idx;
+
+ update_settings_value();
+
+/* wxWindowUpdateLocker noUpdates(get_right_panel());
+
+ m_move_options = Point3(0, 0, 0);
+ m_last_coords = Point3(0, 0, 0);
+ // reset move sliders
+ std::vector<std::string> opt_keys = {"x", "y", "z"};
+ auto og = get_optgroup(ogObjectMovers);
+ for (auto opt_key: opt_keys)
+ og->set_value(opt_key, int(0));
+
+// if (!item || m_selected_object_id < 0){
+ if (m_selected_object_id < 0){
+ m_sizer_object_buttons->Show(false);
+ m_sizer_part_buttons->Show(false);
+ m_sizer_object_movers->Show(false);
+ m_collpane_settings->Show(false);
+ return;
+ }
+
+ m_collpane_settings->Show(true);
+
+ auto volume_id = m_objects_model->GetVolumeIdByItem(item);
+ if (volume_id < 0){
+ m_sizer_object_buttons->Show(true);
+ m_sizer_part_buttons->Show(false);
+ m_sizer_object_movers->Show(false);
+ m_collpane_settings->SetLabelText(_(L("Object Settings")) + ":");
+
+// elsif($itemData->{type} eq 'object') {
+// # select nothing in 3D preview
+//
+// # attach object config to settings panel
+// $self->{optgroup_movers}->disable;
+// $self->{staticbox}->SetLabel('Object Settings');
+// @opt_keys = (map @{$_->get_keys}, Slic3r::Config::PrintObject->new, Slic3r::Config::PrintRegion->new);
+// $config = $self->{model_object}->config;
+// }
+
+ return;
+ }
+
+ m_collpane_settings->SetLabelText(_(L("Part Settings")) + ":");
+
+ m_sizer_object_buttons->Show(false);
+ m_sizer_part_buttons->Show(true);
+ m_sizer_object_movers->Show(true);
+
+ auto bb_size = m_objects[m_selected_object_id]->bounding_box().size();
+ int scale = 10; //??
+
+ m_mover_x->SetMin(-bb_size.x * 4 * scale);
+ m_mover_x->SetMax(bb_size.x * 4 * scale);
+
+ m_mover_y->SetMin(-bb_size.y * 4 * scale);
+ m_mover_y->SetMax(bb_size.y * 4 * scale);
+
+ m_mover_z->SetMin(-bb_size.z * 4 * scale);
+ m_mover_z->SetMax(bb_size.z * 4 * scale);
+
+
+
+// my ($config, @opt_keys);
+ m_btn_move_up->Enable(volume_id > 0);
+ m_btn_move_down->Enable(volume_id + 1 < m_objects[m_selected_object_id]->volumes.size());
+
+ // attach volume config to settings panel
+ auto volume = m_objects[m_selected_object_id]->volumes[volume_id];
+
+ if (volume->modifier)
+ og->enable();
+ else
+ og->disable();
+
+// auto config = volume->config;
+
+ // get default values
+// @opt_keys = @{Slic3r::Config::PrintRegion->new->get_keys};
+// }
+/*
+ # get default values
+ my $default_config = Slic3r::Config::new_from_defaults_keys(\@opt_keys);
+
+ # append default extruder
+ push @opt_keys, 'extruder';
+ $default_config->set('extruder', 0);
+ $config->set_ifndef('extruder', 0);
+ $self->{settings_panel}->set_default_config($default_config);
+ $self->{settings_panel}->set_config($config);
+ $self->{settings_panel}->set_opt_keys(\@opt_keys);
+ $self->{settings_panel}->set_fixed_options([qw(extruder)]);
+ $self->{settings_panel}->enable;
+ }
+ */
+}
+
+void set_extruder_column_hidden(bool hide)
+{
+ m_objects_ctrl->GetColumn(2)->SetHidden(hide);
+}
+
+void update_extruder_in_config(const wxString& selection)
+{
+ if (!m_config || selection.empty())
+ return;
+
+ int extruder = selection.size() > 1 ? 0 : atoi(selection.c_str());
+ (*m_config)->set_key_value("extruder", new ConfigOptionInt(extruder));
+
+ if (m_event_update_scene > 0) {
+ wxCommandEvent e(m_event_update_scene);
+ get_main_frame()->ProcessWindowEvent(e);
+ }
+}
+
+void update_scale_values()
+{
+ auto og = get_optgroup(ogFrequentlyObjectSettings);
+ auto instance = (*m_objects)[m_selected_object_id]->instances.front();
+ auto size = (*m_objects)[m_selected_object_id]->instance_bounding_box(0).size();
+
+ if (g_is_percent_scale) {
+ auto scale = instance->scaling_factor * 100.0;
+ og->set_value("scale_x", int(scale));
+ og->set_value("scale_y", int(scale));
+ og->set_value("scale_z", int(scale));
+ }
+ else {
+ og->set_value("scale_x", int(instance->scaling_factor * size(0) + 0.5));
+ og->set_value("scale_y", int(instance->scaling_factor * size(1) + 0.5));
+ og->set_value("scale_z", int(instance->scaling_factor * size(2) + 0.5));
+ }
+}
+
+void update_position_values()
+{
+ auto og = get_optgroup(ogFrequentlyObjectSettings);
+ auto instance = (*m_objects)[m_selected_object_id]->instances.front();
+
+ og->set_value("position_x", int(instance->offset(0)));
+ og->set_value("position_y", int(instance->offset(1)));
+ og->set_value("position_z", 0);
+}
+
+void update_position_values(const Vec3d& position)
+{
+ auto og = get_optgroup(ogFrequentlyObjectSettings);
+
+ og->set_value("position_x", int(position(0)));
+ og->set_value("position_y", int(position(1)));
+ og->set_value("position_z", int(position(2)));
+}
+
+void update_scale_values(double scaling_factor)
+{
+ auto og = get_optgroup(ogFrequentlyObjectSettings);
+
+ // this is temporary
+ // to be able to update the values as size
+ // we need to store somewhere the original size
+ // or have it passed as parameter
+ if (!g_is_percent_scale)
+ og->set_value("scale_unit", _("%"));
+
+ auto scale = scaling_factor * 100.0;
+ og->set_value("scale_x", int(scale));
+ og->set_value("scale_y", int(scale));
+ og->set_value("scale_z", int(scale));
+}
+
+void update_rotation_values()
+{
+ auto og = get_optgroup(ogFrequentlyObjectSettings);
+ auto instance = (*m_objects)[m_selected_object_id]->instances.front();
+ og->set_value("rotation_x", 0);
+ og->set_value("rotation_y", 0);
+ og->set_value("rotation_z", int(Geometry::rad2deg(instance->rotation)));
+}
+
+void update_rotation_value(double angle, Axis axis)
+{
+ auto og = get_optgroup(ogFrequentlyObjectSettings);
+
+ std::string axis_str;
+ switch (axis)
+ {
+ case X:
+ {
+ axis_str = "rotation_x";
+ break;
+ }
+ case Y:
+ {
+ axis_str = "rotation_y";
+ break;
+ }
+ case Z:
+ {
+ axis_str = "rotation_z";
+ break;
+ }
+ }
+
+ og->set_value(axis_str, int(Geometry::rad2deg(angle)));
+}
+
+void set_uniform_scaling(const bool uniform_scale)
+{
+ g_is_uniform_scale = uniform_scale;
+}
+
+void on_begin_drag(wxDataViewEvent &event)
+{
+ wxDataViewItem item(event.GetItem());
+
+ // only allow drags for item, not containers
+ if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
+ event.Veto();
+ return;
+ }
+
+ /* Under MSW or OSX, DnD moves an item to the place of another selected item
+ * But under GTK, DnD moves an item between another two items.
+ * And as a result - call EVT_CHANGE_SELECTION to unselect all items.
+ * To prevent such behavior use g_prevent_list_events
+ **/
+ g_prevent_list_events = true;//it's needed for GTK
+
+ wxTextDataObject *obj = new wxTextDataObject;
+ obj->SetText(wxString::Format("%d", m_objects_model->GetVolumeIdByItem(item)));
+ event.SetDataObject(obj);
+ event.SetDragFlags(/*wxDrag_AllowMove*/wxDrag_DefaultMove); // allows both copy and move;
+}
+
+void on_drop_possible(wxDataViewEvent &event)
+{
+ wxDataViewItem item(event.GetItem());
+
+ // only allow drags for item or background, not containers
+ if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0) ||
+ event.GetDataFormat() != wxDF_UNICODETEXT)
+ event.Veto();
+}
+
+void on_drop(wxDataViewEvent &event)
+{
+ wxDataViewItem item(event.GetItem());
+
+ // only allow drops for item, not containers
+ if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0) ||
+ event.GetDataFormat() != wxDF_UNICODETEXT) {
+ event.Veto();
+ return;
+ }
+
+ wxTextDataObject obj;
+ obj.SetData(wxDF_UNICODETEXT, event.GetDataSize(), event.GetDataBuffer());
+
+ int from_volume_id = std::stoi(obj.GetText().ToStdString());
+ int to_volume_id = m_objects_model->GetVolumeIdByItem(item);
+
+#ifdef __WXGTK__
+ /* Under GTK, DnD moves an item between another two items.
+ * And event.GetItem() return item, which is under "insertion line"
+ * So, if we move item down we should to decrease the to_volume_id value
+ **/
+ if (to_volume_id > from_volume_id) to_volume_id--;
+#endif // __WXGTK__
+
+ m_objects_ctrl->Select(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id,
+ m_objects_model->GetParent(item)));
+
+ auto& volumes = (*m_objects)[m_selected_object_id]->volumes;
+ auto delta = to_volume_id < from_volume_id ? -1 : 1;
+ int cnt = 0;
+ for (int id = from_volume_id; cnt < abs(from_volume_id - to_volume_id); id+=delta, cnt++)
+ std::swap(volumes[id], volumes[id +delta]);
+
+ g_prevent_list_events = false;
+}
+
+void update_objects_list_extruder_column(int extruders_count)
+{
+ if (get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA)
+ extruders_count = 1;
+
+ // delete old 3rd column
+ m_objects_ctrl->DeleteColumn(m_objects_ctrl->GetColumn(2));
+ // insert new created 3rd column
+ m_objects_ctrl->InsertColumn(2, object_ctrl_create_extruder_column(extruders_count));
+ // set show/hide for this column
+ set_extruder_column_hidden(extruders_count <= 1);
+}
+
+} //namespace GUI
+} //namespace Slic3r \ No newline at end of file
diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp
new file mode 100644
index 000000000..8a1499e03
--- /dev/null
+++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp
@@ -0,0 +1,131 @@
+#ifndef slic3r_GUI_ObjectParts_hpp_
+#define slic3r_GUI_ObjectParts_hpp_
+
+class wxWindow;
+class wxSizer;
+class wxBoxSizer;
+class wxString;
+class wxArrayString;
+class wxMenu;
+class wxDataViewEvent;
+class wxKeyEvent;
+class wxControl;
+
+namespace Slic3r {
+class ModelObject;
+class Model;
+
+namespace GUI {
+
+enum ogGroup{
+ ogFrequentlyChangingParameters,
+ ogFrequentlyObjectSettings,
+ ogCurrentSettings
+// ogObjectSettings,
+// ogObjectMovers,
+// ogPartSettings
+};
+
+enum LambdaTypeIDs{
+ LambdaTypeBox,
+ LambdaTypeCylinder,
+ LambdaTypeSphere,
+ LambdaTypeSlab
+};
+
+struct OBJECT_PARAMETERS
+{
+ LambdaTypeIDs type = LambdaTypeBox;
+ double dim[3];// = { 1.0, 1.0, 1.0 };
+ int cyl_r = 1;
+ int cyl_h = 1;
+ double sph_rho = 1.0;
+ double slab_h = 1.0;
+ double slab_z = 0.0;
+};
+
+void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer);
+void add_objects_list(wxWindow* parent, wxBoxSizer* sizer);
+void add_object_settings(wxWindow* parent, wxBoxSizer* sizer);
+void show_collpane_settings(bool expert_mode);
+
+wxMenu *create_add_settings_popupmenu(bool is_part);
+wxMenu *create_add_part_popupmenu();
+wxMenu *create_part_settings_popupmenu();
+
+// Add object to the list
+//void add_object(const std::string &name);
+void add_object_to_list(const std::string &name, ModelObject* model_object);
+// Delete object from the list
+void delete_object_from_list();
+// Delete all objects from the list
+void delete_all_objects_from_list();
+// Set count of object on c++ side
+void set_object_count(int idx, int count);
+// Unselect all objects in the list on c++ side
+void unselect_objects();
+// Select current object in the list on c++ side
+void select_current_object(int idx);
+// Remove objects/sub-object from the list
+void remove();
+
+//void create_double_slider(wxWindow* parent, wxControl* slider);
+
+void object_ctrl_selection_changed();
+void object_ctrl_context_menu();
+void object_ctrl_key_event(wxKeyEvent& event);
+void object_ctrl_item_value_change(wxDataViewEvent& event);
+void show_context_menu();
+
+void init_mesh_icons();
+void set_event_object_selection_changed(const int& event);
+void set_event_object_settings_changed(const int& event);
+void set_event_remove_object(const int& event);
+void set_event_update_scene(const int& event);
+void set_objects_from_model(Model &model);
+
+bool is_parts_changed();
+bool is_part_settings_changed();
+
+void load_part( wxWindow* parent, ModelObject* model_object,
+ wxArrayString& part_names, const bool is_modifier);
+
+void load_lambda(wxWindow* parent, ModelObject* model_object,
+ wxArrayString& part_names, const bool is_modifier);
+
+void on_btn_load(wxWindow* parent, bool is_modifier = false, bool is_lambda = false);
+void on_btn_del();
+void on_btn_split(const bool split_part);
+void on_btn_move_up();
+void on_btn_move_down();
+
+void parts_changed(int obj_idx);
+void part_selection_changed();
+
+void update_settings_value();
+// show/hide "Extruder" column for Objects List
+void set_extruder_column_hidden(bool hide);
+// update extruder in current config
+void update_extruder_in_config(const wxString& selection);
+// update position values displacements or "gizmos"
+void update_position_values();
+void update_position_values(const Vec3d& position);
+// update scale values after scale unit changing or "gizmos"
+void update_scale_values();
+void update_scale_values(double scaling_factor);
+// update rotation values object selection changing
+void update_rotation_values();
+// update rotation value after "gizmos"
+void update_rotation_value(double angle, Axis axis);
+void set_uniform_scaling(const bool uniform_scale);
+
+void on_begin_drag(wxDataViewEvent &event);
+void on_drop_possible(wxDataViewEvent &event);
+void on_drop(wxDataViewEvent &event);
+
+// update extruder column for objects_ctrl according to extruders count
+void update_objects_list_extruder_column(int extruders_count);
+
+} //namespace GUI
+} //namespace Slic3r
+#endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file
diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.cpp b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp
new file mode 100644
index 000000000..7543821c0
--- /dev/null
+++ b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp
@@ -0,0 +1,176 @@
+#include "LambdaObjectDialog.hpp"
+
+#include <wx/window.h>
+#include <wx/button.h>
+#include "OptionsGroup.hpp"
+
+namespace Slic3r
+{
+namespace GUI
+{
+static wxString dots("…", wxConvUTF8);
+
+LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent)
+{
+ Create(parent, wxID_ANY, _(L("Lambda Object")),
+ wxDefaultPosition, wxDefaultSize,
+ wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
+
+ // instead of double dim[3] = { 1.0, 1.0, 1.0 };
+ object_parameters.dim[0] = 1.0;
+ object_parameters.dim[1] = 1.0;
+ object_parameters.dim[2] = 1.0;
+
+ sizer = new wxBoxSizer(wxVERTICAL);
+
+ // modificator options
+ m_modificator_options_book = new wxChoicebook( this, wxID_ANY, wxDefaultPosition,
+ wxDefaultSize, wxCHB_TOP);
+ sizer->Add(m_modificator_options_book, 1, wxEXPAND| wxALL, 10);
+
+ auto optgroup = init_modificator_options_page(_(L("Box")));
+ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
+ int opt_id = opt_key == "l" ? 0 :
+ opt_key == "w" ? 1 :
+ opt_key == "h" ? 2 : -1;
+ if (opt_id < 0) return;
+ object_parameters.dim[opt_id] = boost::any_cast<double>(value);
+ };
+
+ ConfigOptionDef def;
+ def.width = 70;
+ def.type = coFloat;
+ def.default_value = new ConfigOptionFloat{ 1.0 };
+ def.label = L("L");
+ Option option(def, "l");
+ optgroup->append_single_option_line(option);
+
+ def.label = L("W");
+ option = Option(def, "w");
+ optgroup->append_single_option_line(option);
+
+ def.label = L("H");
+ option = Option(def, "h");
+ optgroup->append_single_option_line(option);
+
+ optgroup = init_modificator_options_page(_(L("Cylinder")));
+ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
+ int val = boost::any_cast<int>(value);
+ if (opt_key == "cyl_r")
+ object_parameters.cyl_r = val;
+ else if (opt_key == "cyl_h")
+ object_parameters.cyl_h = val;
+ else return;
+ };
+
+ def.type = coInt;
+ def.default_value = new ConfigOptionInt{ 1 };
+ def.label = L("Radius");
+ option = Option(def, "cyl_r");
+ optgroup->append_single_option_line(option);
+
+ def.label = L("Height");
+ option = Option(def, "cyl_h");
+ optgroup->append_single_option_line(option);
+
+ optgroup = init_modificator_options_page(_(L("Sphere")));
+ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
+ if (opt_key == "sph_rho")
+ object_parameters.sph_rho = boost::any_cast<double>(value);
+ else return;
+ };
+
+ def.type = coFloat;
+ def.default_value = new ConfigOptionFloat{ 1.0 };
+ def.label = L("Rho");
+ option = Option(def, "sph_rho");
+ optgroup->append_single_option_line(option);
+
+ optgroup = init_modificator_options_page(_(L("Slab")));
+ optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
+ double val = boost::any_cast<double>(value);
+ if (opt_key == "slab_z")
+ object_parameters.slab_z = val;
+ else if (opt_key == "slab_h")
+ object_parameters.slab_h = val;
+ else return;
+ };
+
+ def.label = L("H");
+ option = Option(def, "slab_h");
+ optgroup->append_single_option_line(option);
+
+ def.label = L("Initial Z");
+ option = Option(def, "slab_z");
+ optgroup->append_single_option_line(option);
+
+ Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent e)
+ {
+ auto page_idx = m_modificator_options_book->GetSelection();
+ if (page_idx < 0) return;
+ switch (page_idx)
+ {
+ case 0:
+ object_parameters.type = LambdaTypeBox;
+ break;
+ case 1:
+ object_parameters.type = LambdaTypeCylinder;
+ break;
+ case 2:
+ object_parameters.type = LambdaTypeSphere;
+ break;
+ case 3:
+ object_parameters.type = LambdaTypeSlab;
+ break;
+ default:
+ break;
+ }
+ }));
+
+
+ auto button_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
+
+ wxButton* btn_OK = static_cast<wxButton*>(FindWindowById(wxID_OK, this));
+ btn_OK->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
+ // validate user input
+ if (!CanClose())return;
+ EndModal(wxID_OK);
+ Destroy();
+ });
+
+ wxButton* btn_CANCEL = static_cast<wxButton*>(FindWindowById(wxID_CANCEL, this));
+ btn_CANCEL->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
+ // validate user input
+ if (!CanClose())return;
+ EndModal(wxID_CANCEL);
+ Destroy();
+ });
+
+ sizer->Add(button_sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10);
+
+ SetSizer(sizer);
+ sizer->Fit(this);
+ sizer->SetSizeHints(this);
+}
+
+// Called from the constructor.
+// Create a panel for a rectangular / circular / custom bed shape.
+ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(wxString title){
+
+ auto panel = new wxPanel(m_modificator_options_book);
+
+ ConfigOptionsGroupShp optgroup;
+ optgroup = std::make_shared<ConfigOptionsGroup>(panel, _(L("Add")) + " " +title + " " +dots);
+ optgroup->label_width = 100;
+
+ m_optgroups.push_back(optgroup);
+
+ panel->SetSizerAndFit(optgroup->sizer);
+ m_modificator_options_book->AddPage(panel, title);
+
+ return optgroup;
+}
+
+
+} //namespace GUI
+} //namespace Slic3r
diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.hpp b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp
new file mode 100644
index 000000000..a70c12449
--- /dev/null
+++ b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp
@@ -0,0 +1,35 @@
+#ifndef slic3r_LambdaObjectDialog_hpp_
+#define slic3r_LambdaObjectDialog_hpp_
+
+#include "GUI.hpp"
+
+#include <wx/dialog.h>
+#include <wx/sizer.h>
+#include <wx/choicebk.h>
+
+namespace Slic3r
+{
+namespace GUI
+{
+using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
+class LambdaObjectDialog : public wxDialog
+{
+ wxChoicebook* m_modificator_options_book;
+ std::vector <ConfigOptionsGroupShp> m_optgroups;
+public:
+ LambdaObjectDialog(wxWindow* parent);
+ ~LambdaObjectDialog(){}
+
+ bool CanClose() { return true; } // ???
+ OBJECT_PARAMETERS& ObjectParameters(){ return object_parameters; }
+
+ ConfigOptionsGroupShp init_modificator_options_page(wxString title);
+
+ // Note whether the window was already closed, so a pending update is not executed.
+ bool m_already_closed = false;
+ OBJECT_PARAMETERS object_parameters;
+ wxBoxSizer* sizer = nullptr;
+};
+} //namespace GUI
+} //namespace Slic3r
+#endif //slic3r_LambdaObjectDialog_hpp_
diff --git a/xs/src/slic3r/GUI/MsgDialog.cpp b/xs/src/slic3r/GUI/MsgDialog.cpp
new file mode 100644
index 000000000..58679ed9e
--- /dev/null
+++ b/xs/src/slic3r/GUI/MsgDialog.cpp
@@ -0,0 +1,88 @@
+#include "MsgDialog.hpp"
+
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/stattext.h>
+#include <wx/button.h>
+#include <wx/statbmp.h>
+#include <wx/scrolwin.h>
+
+#include "libslic3r/libslic3r.h"
+#include "libslic3r/Utils.hpp"
+#include "GUI.hpp"
+#include "ConfigWizard.hpp"
+
+namespace Slic3r {
+namespace GUI {
+
+
+MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id) :
+ MsgDialog(parent, title, headline, wxBitmap(from_u8(Slic3r::var("Slic3r_192px.png")), wxBITMAP_TYPE_PNG), button_id)
+{}
+
+MsgDialog::MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxBitmap bitmap, wxWindowID button_id) :
+ wxDialog(parent, wxID_ANY, title),
+ boldfont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)),
+ content_sizer(new wxBoxSizer(wxVERTICAL)),
+ btn_sizer(new wxBoxSizer(wxHORIZONTAL))
+{
+ boldfont.SetWeight(wxFONTWEIGHT_BOLD);
+
+ auto *topsizer = new wxBoxSizer(wxHORIZONTAL);
+ auto *rightsizer = new wxBoxSizer(wxVERTICAL);
+
+ auto *headtext = new wxStaticText(this, wxID_ANY, headline);
+ headtext->SetFont(boldfont);
+ headtext->Wrap(CONTENT_WIDTH);
+ rightsizer->Add(headtext);
+ rightsizer->AddSpacer(VERT_SPACING);
+
+ rightsizer->Add(content_sizer, 1, wxEXPAND);
+
+ if (button_id != wxID_NONE) {
+ auto *button = new wxButton(this, button_id);
+ button->SetFocus();
+ btn_sizer->Add(button);
+ }
+
+ rightsizer->Add(btn_sizer, 0, wxALIGN_CENTRE_HORIZONTAL);
+
+ auto *logo = new wxStaticBitmap(this, wxID_ANY, std::move(bitmap));
+
+ topsizer->Add(logo, 0, wxALL, BORDER);
+ topsizer->Add(rightsizer, 1, wxALL | wxEXPAND, BORDER);
+
+ SetSizerAndFit(topsizer);
+}
+
+MsgDialog::~MsgDialog() {}
+
+
+// ErrorDialog
+
+ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg) :
+ MsgDialog(parent, _(L("Slic3r error")), _(L("Slic3r has encountered an error")), wxBitmap(from_u8(Slic3r::var("Slic3r_192px_grayscale.png")), wxBITMAP_TYPE_PNG))
+{
+ auto *panel = new wxScrolledWindow(this);
+ auto *p_sizer = new wxBoxSizer(wxVERTICAL);
+ panel->SetSizer(p_sizer);
+
+ auto *text = new wxStaticText(panel, wxID_ANY, msg);
+ text->Wrap(CONTENT_WIDTH);
+ p_sizer->Add(text, 1, wxEXPAND);
+
+ panel->SetMinSize(wxSize(CONTENT_WIDTH, 0));
+ panel->SetScrollRate(0, 5);
+
+ content_sizer->Add(panel, 1, wxEXPAND);
+
+ SetMaxSize(wxSize(-1, CONTENT_MAX_HEIGHT));
+ Fit();
+}
+
+ErrorDialog::~ErrorDialog() {}
+
+
+
+}
+}
diff --git a/xs/src/slic3r/GUI/MsgDialog.hpp b/xs/src/slic3r/GUI/MsgDialog.hpp
new file mode 100644
index 000000000..ca349eb5c
--- /dev/null
+++ b/xs/src/slic3r/GUI/MsgDialog.hpp
@@ -0,0 +1,67 @@
+#ifndef slic3r_MsgDialog_hpp_
+#define slic3r_MsgDialog_hpp_
+
+#include <string>
+#include <unordered_map>
+
+#include <wx/dialog.h>
+#include <wx/font.h>
+#include <wx/bitmap.h>
+
+#include "slic3r/Utils/Semver.hpp"
+
+class wxBoxSizer;
+class wxCheckBox;
+
+namespace Slic3r {
+
+namespace GUI {
+
+
+// A message / query dialog with a bitmap on the left and any content on the right
+// with buttons underneath.
+struct MsgDialog : wxDialog
+{
+ MsgDialog(MsgDialog &&) = delete;
+ MsgDialog(const MsgDialog &) = delete;
+ MsgDialog &operator=(MsgDialog &&) = delete;
+ MsgDialog &operator=(const MsgDialog &) = delete;
+ virtual ~MsgDialog();
+
+ // TODO: refactor with CreateStdDialogButtonSizer usage
+
+protected:
+ enum {
+ CONTENT_WIDTH = 500,
+ CONTENT_MAX_HEIGHT = 600,
+ BORDER = 30,
+ VERT_SPACING = 15,
+ HORIZ_SPACING = 5,
+ };
+
+ // button_id is an id of a button that can be added by default, use wxID_NONE to disable
+ MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id = wxID_OK);
+ MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxBitmap bitmap, wxWindowID button_id = wxID_OK);
+
+ wxFont boldfont;
+ wxBoxSizer *content_sizer;
+ wxBoxSizer *btn_sizer;
+};
+
+
+// Generic error dialog, used for displaying exceptions
+struct ErrorDialog : MsgDialog
+{
+ ErrorDialog(wxWindow *parent, const wxString &msg);
+ ErrorDialog(ErrorDialog &&) = delete;
+ ErrorDialog(const ErrorDialog &) = delete;
+ ErrorDialog &operator=(ErrorDialog &&) = delete;
+ ErrorDialog &operator=(const ErrorDialog &) = delete;
+ virtual ~ErrorDialog();
+};
+
+
+}
+}
+
+#endif
diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp
index 892d0332a..81d02a4cd 100644
--- a/xs/src/slic3r/GUI/OptionsGroup.cpp
+++ b/xs/src/slic3r/GUI/OptionsGroup.cpp
@@ -22,15 +22,18 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
// is the normal type.
if (opt.gui_type.compare("select") == 0) {
} else if (opt.gui_type.compare("select_open") == 0) {
- m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(m_parent, opt, id)));
+ m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(parent(), opt, id)));
} else if (opt.gui_type.compare("color") == 0) {
- m_fields.emplace(id, STDMOVE(ColourPicker::Create<ColourPicker>(m_parent, opt, id)));
+ m_fields.emplace(id, STDMOVE(ColourPicker::Create<ColourPicker>(parent(), opt, id)));
} else if (opt.gui_type.compare("f_enum_open") == 0 ||
opt.gui_type.compare("i_enum_open") == 0 ||
opt.gui_type.compare("i_enum_closed") == 0) {
- m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(m_parent, opt, id)));
+ m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(parent(), opt, id)));
} else if (opt.gui_type.compare("slider") == 0) {
+ m_fields.emplace(id, STDMOVE(SliderCtrl::Create<SliderCtrl>(parent(), opt, id)));
} else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl
+ } else if (opt.gui_type.compare("legend") == 0) { // StaticText
+ m_fields.emplace(id, STDMOVE(StaticText::Create<StaticText>(parent(), opt, id)));
} else {
switch (opt.type) {
case coFloatOrPercent:
@@ -40,21 +43,21 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
case coPercents:
case coString:
case coStrings:
- m_fields.emplace(id, STDMOVE(TextCtrl::Create<TextCtrl>(m_parent, opt, id)));
+ m_fields.emplace(id, STDMOVE(TextCtrl::Create<TextCtrl>(parent(), opt, id)));
break;
case coBool:
case coBools:
- m_fields.emplace(id, STDMOVE(CheckBox::Create<CheckBox>(m_parent, opt, id)));
+ m_fields.emplace(id, STDMOVE(CheckBox::Create<CheckBox>(parent(), opt, id)));
break;
case coInt:
case coInts:
- m_fields.emplace(id, STDMOVE(SpinCtrl::Create<SpinCtrl>(m_parent, opt, id)));
+ m_fields.emplace(id, STDMOVE(SpinCtrl::Create<SpinCtrl>(parent(), opt, id)));
break;
case coEnum:
- m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(m_parent, opt, id)));
+ m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(parent(), opt, id)));
break;
case coPoints:
- m_fields.emplace(id, STDMOVE(PointCtrl::Create<PointCtrl>(m_parent, opt, id)));
+ m_fields.emplace(id, STDMOVE(PointCtrl::Create<PointCtrl>(parent(), opt, id)));
break;
case coNone: break;
default:
@@ -82,13 +85,28 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
if (!m_disabled)
this->back_to_initial_value(opt_id);
};
- if (!m_is_tab_opt) field->m_Undo_btn->Hide();
+ field->m_back_to_sys_value = [this](std::string opt_id){
+ if (!this->m_disabled)
+ this->back_to_sys_value(opt_id);
+ };
// assign function objects for callbacks, etc.
return field;
}
-void OptionsGroup::append_line(const Line& line) {
+void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field)
+{
+ if (!m_show_modified_btns) {
+ field->m_Undo_btn->Hide();
+ field->m_Undo_to_sys_btn->Hide();
+ return;
+ }
+
+ sizer->Add(field->m_Undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL);
+ sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL);
+}
+
+void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* = nullptr*/) {
//! if (line.sizer != nullptr || (line.widget != nullptr && line.full_width > 0)){
if ( (line.sizer != nullptr || line.widget != nullptr) && line.full_width){
if (line.sizer != nullptr) {
@@ -109,27 +127,72 @@ void OptionsGroup::append_line(const Line& line) {
if (option_set.size() == 1 && label_width == 0 && option_set.front().opt.full_width &&
option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr &&
line.get_extra_widgets().size() == 0) {
+ wxSizer* tmp_sizer;
+#ifdef __WXGTK__
+ tmp_sizer = new wxBoxSizer(wxVERTICAL);
+ m_panel->SetSizer(tmp_sizer);
+ m_panel->Layout();
+#else
+ tmp_sizer = sizer;
+#endif /* __WXGTK__ */
+
const auto& option = option_set.front();
const auto& field = build_field(option);
- sizer->Add(field->m_Undo_btn);
+ auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
+ add_undo_buttuns_to_sizer(btn_sizer, field);
+ tmp_sizer->Add(btn_sizer, 0, wxEXPAND | wxALL, 0);
if (is_window_field(field))
- sizer->Add(field->getWindow(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
+ tmp_sizer->Add(field->getWindow(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
if (is_sizer_field(field))
- sizer->Add(field->getSizer(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
+ tmp_sizer->Add(field->getSizer(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5);
return;
}
auto grid_sizer = m_grid_sizer;
+#ifdef __WXGTK__
+ m_panel->SetSizer(m_grid_sizer);
+ m_panel->Layout();
+#endif /* __WXGTK__ */
+
+ // if we have an extra column, build it
+ if (extra_column) {
+ if (extra_column) {
+ grid_sizer->Add(extra_column(parent(), line), 0, wxALIGN_CENTER_VERTICAL, 0);
+ }
+ else {
+ // if the callback provides no sizer for the extra cell, put a spacer
+ grid_sizer->AddSpacer(1);
+ }
+ }
+
// Build a label if we have it
wxStaticText* label=nullptr;
if (label_width != 0) {
+ long label_style = staticbox ? 0 : wxALIGN_RIGHT;
+#ifdef __WXGTK__
+ // workaround for correct text align of the StaticBox on Linux
+ // flags wxALIGN_RIGHT and wxALIGN_CENTRE don't work when Ellipsize flags are _not_ given.
+ // Text is properly aligned only when Ellipsize is checked.
+ label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END;
+#endif /* __WXGTK__ */
label = new wxStaticText(parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ":"),
- wxDefaultPosition, wxSize(label_width, -1));
+ wxDefaultPosition, wxSize(label_width, -1), label_style);
label->SetFont(label_font);
label->Wrap(label_width); // avoid a Linux/GTK bug
- grid_sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL,0);
+ if (!line.near_label_widget)
+ grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) |
+ (m_flag == ogSIDE_OPTIONS_VERTICAL ? wxTOP : wxALIGN_CENTER_VERTICAL), 5);
+ else {
+ // If we're here, we have some widget near the label
+ // so we need a horizontal sizer to arrange these things
+ auto sizer = new wxBoxSizer(wxHORIZONTAL);
+ grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
+ sizer->Add(line.near_label_widget(parent()), 0, wxRIGHT, 7);
+ sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) |
+ (m_flag == ogSIDE_OPTIONS_VERTICAL ? wxTOP : wxALIGN_CENTER_VERTICAL), 5);
+ }
if (line.label_tooltip.compare("") != 0)
label->SetToolTip(line.label_tooltip);
}
@@ -137,67 +200,82 @@ void OptionsGroup::append_line(const Line& line) {
// If there's a widget, build it and add the result to the sizer.
if (line.widget != nullptr) {
auto wgt = line.widget(parent());
- grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, wxOSX ? 0 : 5);
+ // If widget doesn't have label, don't use border
+ grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, (wxOSX || line.label.IsEmpty()) ? 0 : 5);
+ if (colored_Label != nullptr) *colored_Label = label;
return;
}
- // if we have a single option with no sidetext just add it directly to the grid sizer
- auto sizer = new wxBoxSizer(wxHORIZONTAL);
- grid_sizer->Add(sizer, 0, wxEXPAND | wxALL, 0);
+ // If we're here, we have more than one option or a single option with sidetext
+ // so we need a horizontal sizer to arrange these things
+ auto sizer = new wxBoxSizer(m_flag == ogSIDE_OPTIONS_VERTICAL ? wxVERTICAL : wxHORIZONTAL);
+ grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
+ // If we have a single option with no sidetext just add it directly to the grid sizer
if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 &&
option_set.front().side_widget == nullptr && line.get_extra_widgets().size() == 0) {
const auto& option = option_set.front();
const auto& field = build_field(option, label);
- sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL);
+ add_undo_buttuns_to_sizer(sizer, field);
if (is_window_field(field))
- sizer->Add(field->getWindow(), 0, (option.opt.full_width ? wxEXPAND : 0) |
- wxBOTTOM | wxTOP | wxALIGN_CENTER_VERTICAL, wxOSX ? 0 : 2);
+ sizer->Add(field->getWindow(), option.opt.full_width ? 1 : 0, (option.opt.full_width ? wxEXPAND : 0) |
+ wxBOTTOM | wxTOP | wxALIGN_CENTER_VERTICAL, (wxOSX||!staticbox) ? 0 : 2);
if (is_sizer_field(field))
- sizer->Add(field->getSizer(), 0, (option.opt.full_width ? wxEXPAND : 0) | wxALIGN_CENTER_VERTICAL, 0);
+ sizer->Add(field->getSizer(), 1, (option.opt.full_width ? wxEXPAND : 0) | wxALIGN_CENTER_VERTICAL, 0);
return;
}
- // if we're here, we have more than one option or a single option with sidetext
- // so we need a horizontal sizer to arrange these things
- for (auto opt : option_set) {
+ for (auto opt : option_set) {
ConfigOptionDef option = opt.opt;
+ wxSizer* sizer_tmp;
+ if (m_flag == ogSIDE_OPTIONS_VERTICAL){
+ auto sz = new wxFlexGridSizer(1, 3, 2, 2);
+ sz->RemoveGrowableCol(2);
+ sizer_tmp = sz;
+ }
+ else
+ sizer_tmp = sizer;
// add label if any
if (option.label != "") {
- wxString str_label = L_str(option.label);
+ wxString str_label = _(option.label);
//! To correct translation by context have to use wxGETTEXT_IN_CONTEXT macro from wxWidget 3.1.1
// wxString str_label = (option.label == "Top" || option.label == "Bottom") ?
// wxGETTEXT_IN_CONTEXT("Layers", wxString(option.label.c_str()):
// L_str(option.label);
label = new wxStaticText(parent(), wxID_ANY, str_label + ":", wxDefaultPosition, wxDefaultSize);
label->SetFont(label_font);
- sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL, 0);
+ sizer_tmp->Add(label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 0);
}
// add field
const Option& opt_ref = opt;
auto& field = build_field(opt_ref, label);
- sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL, 0);
+ add_undo_buttuns_to_sizer(sizer_tmp, field);
is_sizer_field(field) ?
- sizer->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) :
- sizer->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0);
+ sizer_tmp->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) :
+ sizer_tmp->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0);
// add sidetext if any
if (option.sidetext != "") {
- auto sidetext = new wxStaticText(parent(), wxID_ANY, L_str(option.sidetext), wxDefaultPosition, wxDefaultSize);
+ auto sidetext = new wxStaticText( parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition,
+ wxSize(sidetext_width, -1)/*wxDefaultSize*/, wxALIGN_LEFT);
sidetext->SetFont(sidetext_font);
- sizer->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);
+ sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, m_flag == ogSIDE_OPTIONS_VERTICAL ? 0 : 4);
+ field->set_side_text_ptr(sidetext);
}
// add side widget if any
if (opt.side_widget != nullptr) {
- sizer->Add(opt.side_widget(parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification
+ sizer_tmp->Add(opt.side_widget(parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification
}
- if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back())
+ if (opt.opt_id != option_set.back().opt_id && m_flag != ogSIDE_OPTIONS_VERTICAL) //! istead of (opt != option_set.back())
{
- sizer->AddSpacer(6);
+ sizer_tmp->AddSpacer(6);
}
+
+ if (m_flag == ogSIDE_OPTIONS_VERTICAL)
+ sizer->Add(sizer_tmp, 0, wxALIGN_RIGHT|wxALL, 0);
}
// add extra sizers if any
for (auto extra_widget : line.get_extra_widgets()) {
@@ -206,22 +284,22 @@ void OptionsGroup::append_line(const Line& line) {
}
Line OptionsGroup::create_single_option_line(const Option& option) const {
- Line retval{ L_str(option.opt.label), L_str(option.opt.tooltip) };
+ Line retval{ _(option.opt.label), _(option.opt.tooltip) };
Option tmp(option);
tmp.opt.label = std::string("");
retval.append_option(tmp);
return retval;
}
-void OptionsGroup::on_change_OG(t_config_option_key id, /*config_value*/boost::any value) {
+void OptionsGroup::on_change_OG(const t_config_option_key& opt_id, const boost::any& value) {
if (m_on_change != nullptr)
- m_on_change(id, value);
+ m_on_change(opt_id, value);
}
-Option ConfigOptionsGroup::get_option(const std::string opt_key, int opt_index /*= -1*/)
+Option ConfigOptionsGroup::get_option(const std::string& opt_key, int opt_index /*= -1*/)
{
if (!m_config->has(opt_key)) {
- std::cerr << "No " << opt_key << " in ConfigOptionsGroup config.";
+ std::cerr << "No " << opt_key << " in ConfigOptionsGroup config.\n";
}
std::string opt_id = opt_index == -1 ? opt_key : opt_key + "#" + std::to_string(opt_index);
@@ -231,7 +309,7 @@ Option ConfigOptionsGroup::get_option(const std::string opt_key, int opt_index /
return Option(*m_config->def()->get(opt_key), opt_id);
}
-void ConfigOptionsGroup::on_change_OG(t_config_option_key opt_id, boost::any value)
+void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const boost::any& value)
{
if (!m_opt_map.empty())
{
@@ -254,16 +332,7 @@ void ConfigOptionsGroup::on_change_OG(t_config_option_key opt_id, boost::any val
if (opt_index != -1){
// die "Can't set serialized option indexed value" ;
}
- // # Split a string to multiple strings by a semi - colon.This is the old way of storing multi - string values.
- // # Currently used for the post_process config value only.
- // my @values = split / ; / , $field_value;
- // $self->config->set($opt_key, \@values);
- std::string str = boost::any_cast<std::string>(value);
- if (str.back() == ';')
- str.pop_back();
- std::vector<std::string> values;
- boost::split(values, str, boost::is_any_of(";"));
- change_opt_value(*m_config, opt_key, values);
+ change_opt_value(*m_config, opt_key, value);
}
else {
if (opt_index == -1) {
@@ -283,11 +352,24 @@ void ConfigOptionsGroup::on_change_OG(t_config_option_key opt_id, boost::any val
OptionsGroup::on_change_OG(opt_id, value); //!? Why doing this
}
-void ConfigOptionsGroup::back_to_initial_value(const std::string opt_key)
+void ConfigOptionsGroup::back_to_initial_value(const std::string& opt_key)
{
if (m_get_initial_config == nullptr)
return;
- DynamicPrintConfig config = m_get_initial_config();
+ back_to_config_value(m_get_initial_config(), opt_key);
+}
+
+void ConfigOptionsGroup::back_to_sys_value(const std::string& opt_key)
+{
+ if (m_get_sys_config == nullptr)
+ return;
+ if (!have_sys_config())
+ return;
+ back_to_config_value(m_get_sys_config(), opt_key);
+}
+
+void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, const std::string& opt_key)
+{
boost::any value;
if (opt_key == "extruders_count"){
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
@@ -300,15 +382,18 @@ void ConfigOptionsGroup::back_to_initial_value(const std::string opt_key)
int opt_index = m_opt_map.at(opt_id).second;
value = get_config_value(config, opt_short_key, opt_index);
}
- else
+ else{
value = get_config_value(config, opt_key);
+ change_opt_value(*m_config, opt_key, value);
+ return;
+ }
set_value(opt_key, value);
on_change_OG(opt_key, get_value(opt_key));
}
void ConfigOptionsGroup::reload_config(){
- for (std::map< std::string, std::pair<std::string, int> >::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) {
+ for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) {
auto opt_id = it->first;
std::string opt_key = m_opt_map.at(opt_id).first;
int opt_index = m_opt_map.at(opt_id).second;
@@ -318,7 +403,7 @@ void ConfigOptionsGroup::reload_config(){
}
-boost::any ConfigOptionsGroup::config_value(std::string opt_key, int opt_index, bool deserialize){
+boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize){
if (deserialize) {
// Want to edit a vector value(currently only multi - strings) in a single edit box.
@@ -335,7 +420,7 @@ boost::any ConfigOptionsGroup::config_value(std::string opt_key, int opt_index,
}
}
-boost::any ConfigOptionsGroup::get_config_value(DynamicPrintConfig& config, std::string opt_key, int opt_index/* = -1*/)
+boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index /*= -1*/)
{
size_t idx = opt_index == -1 ? 0 : opt_index;
@@ -375,12 +460,17 @@ boost::any ConfigOptionsGroup::get_config_value(DynamicPrintConfig& config, std:
ret = static_cast<wxString>(config.opt_string(opt_key));
break;
case coStrings:
+ if (opt_key.compare("compatible_printers") == 0){
+ ret = config.option<ConfigOptionStrings>(opt_key)->values;
+ break;
+ }
if (config.option<ConfigOptionStrings>(opt_key)->values.empty())
ret = text_value;
else if (opt->gui_flags.compare("serialized") == 0){
std::vector<std::string> values = config.option<ConfigOptionStrings>(opt_key)->values;
- for (auto el : values)
- text_value += el + ";";
+ if (!values.empty() && values[0].compare("") != 0)
+ for (auto el : values)
+ text_value += el + ";";
ret = text_value;
}
else
@@ -409,12 +499,19 @@ boost::any ConfigOptionsGroup::get_config_value(DynamicPrintConfig& config, std:
else if (opt_key.compare("support_material_pattern") == 0){
ret = static_cast<int>(config.option<ConfigOptionEnum<SupportMaterialPattern>>(opt_key)->value);
}
- else if (opt_key.compare("seam_position") == 0)
+ else if (opt_key.compare("seam_position") == 0){
ret = static_cast<int>(config.option<ConfigOptionEnum<SeamPosition>>(opt_key)->value);
+ }
+ else if (opt_key.compare("host_type") == 0){
+ ret = static_cast<int>(config.option<ConfigOptionEnum<PrintHostType>>(opt_key)->value);
+ }
}
break;
case coPoints:
- ret = config.option<ConfigOptionPoints>(opt_key)->get_at(idx);
+ if (opt_key.compare("bed_shape") == 0)
+ ret = config.option<ConfigOptionPoints>(opt_key)->values;
+ else
+ ret = config.option<ConfigOptionPoints>(opt_key)->get_at(idx);
break;
case coNone:
default:
@@ -423,12 +520,12 @@ boost::any ConfigOptionsGroup::get_config_value(DynamicPrintConfig& config, std:
return ret;
}
-Field* ConfigOptionsGroup::get_fieldc(t_config_option_key opt_key, int opt_index){
+Field* ConfigOptionsGroup::get_fieldc(const t_config_option_key& opt_key, int opt_index){
Field* field = get_field(opt_key);
if (field != nullptr)
return field;
std::string opt_id = "";
- for (std::map< std::string, std::pair<std::string, int> >::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) {
+ for (t_opt_map::iterator it = m_opt_map.begin(); it != m_opt_map.end(); ++it) {
if (opt_key == m_opt_map.at(it->first).first && opt_index == m_opt_map.at(it->first).second){
opt_id = it->first;
break;
@@ -437,10 +534,10 @@ Field* ConfigOptionsGroup::get_fieldc(t_config_option_key opt_key, int opt_index
return opt_id.empty() ? nullptr : get_field(opt_id);
}
-void ogStaticText::SetText(wxString value)
+void ogStaticText::SetText(const wxString& value, bool wrap/* = true*/)
{
SetLabel(value);
- Wrap(400);
+ if (wrap) Wrap(400);
GetParent()->Layout();
}
diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp
index aa0563866..5a18803a6 100644
--- a/xs/src/slic3r/GUI/OptionsGroup.hpp
+++ b/xs/src/slic3r/GUI/OptionsGroup.hpp
@@ -1,3 +1,6 @@
+#ifndef slic3r_OptionsGroup_hpp_
+#define slic3r_OptionsGroup_hpp_
+
#include <wx/wx.h>
#include <wx/stattext.h>
#include <wx/settings.h>
@@ -23,9 +26,13 @@
namespace Slic3r { namespace GUI {
+enum ogDrawFlag{
+ ogDEFAULT,
+ ogSIDE_OPTIONS_VERTICAL
+};
+
/// Widget type describes a function object that returns a wxWindow (our widget) and accepts a wxWidget (parent window).
using widget_t = std::function<wxSizer*(wxWindow*)>;//!std::function<wxWindow*(wxWindow*)>;
-using column_t = std::function<wxSizer*(const Line&)>;
//auto default_label_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT); //GetSystemColour
//auto modified_label_clr = *new wxColour(254, 189, 101);
@@ -50,6 +57,7 @@ public:
size_t full_width {0};
wxSizer* sizer {nullptr};
widget_t widget {nullptr};
+ std::function<wxWindow*(wxWindow*)> near_label_widget{ nullptr };
void append_option(const Option& option) {
m_options.push_back(option);
@@ -68,9 +76,13 @@ private:
std::vector<widget_t> m_extra_widgets;//! {std::vector<widget_t>()};
};
+using column_t = std::function<wxWindow*(wxWindow* parent, const Line&)>;//std::function<wxSizer*(const Line&)>;
+
using t_optionfield_map = std::map<t_config_option_key, t_field>;
+using t_opt_map = std::map< std::string, std::pair<std::string, int> >;
class OptionsGroup {
+ wxStaticBox* stb;
public:
const bool staticbox {true};
const wxString title {wxString("")};
@@ -79,30 +91,44 @@ public:
column_t extra_column {nullptr};
t_change m_on_change {nullptr};
std::function<DynamicPrintConfig()> m_get_initial_config{ nullptr };
+ std::function<DynamicPrintConfig()> m_get_sys_config{ nullptr };
+ std::function<bool()> have_sys_config{ nullptr };
wxFont sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
wxFont label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) };
+ int sidetext_width{ -1 };
/// Returns a copy of the pointer of the parent wxWindow.
/// Accessor function is because users are not allowed to change the parent
/// but defining it as const means a lot of const_casts to deal with wx functions.
- inline wxWindow* parent() const { return m_parent; }
+ inline wxWindow* parent() const {
+#ifdef __WXGTK__
+ return m_panel;
+#else
+ return m_parent;
+#endif /* __WXGTK__ */
+ }
+#ifdef __WXGTK__
+ wxWindow* get_parent() const {
+ return m_parent;
+ }
+#endif /* __WXGTK__ */
- void append_line(const Line& line);
+ void append_line(const Line& line, wxStaticText** colored_Label = nullptr);
Line create_single_option_line(const Option& option) const;
void append_single_option_line(const Option& option) { append_line(create_single_option_line(option)); }
// return a non-owning pointer reference
- inline Field* get_field(t_config_option_key id) const{
+ inline Field* get_field(const t_config_option_key& id) const{
if (m_fields.find(id) == m_fields.end()) return nullptr;
return m_fields.at(id).get();
}
- bool set_value(t_config_option_key id, boost::any value, bool change_event = false) {
+ bool set_value(const t_config_option_key& id, const boost::any& value, bool change_event = false) {
if (m_fields.find(id) == m_fields.end()) return false;
m_fields.at(id)->set_value(value, change_event);
return true;
}
- boost::any get_value(t_config_option_key id) {
+ boost::any get_value(const t_config_option_key& id) {
boost::any out;
if (m_fields.find(id) == m_fields.end()) ;
else
@@ -110,22 +136,51 @@ public:
return out;
}
+ bool set_side_text(const t_config_option_key& opt_key, const wxString& side_text) {
+ if (m_fields.find(opt_key) == m_fields.end()) return false;
+ auto st = m_fields.at(opt_key)->m_side_text;
+ if (!st) return false;
+ st->SetLabel(side_text);
+ return true;
+ }
+
+ void set_name(const wxString& new_name) {
+ stb->SetLabel(new_name);
+ }
+
inline void enable() { for (auto& field : m_fields) field.second->enable(); }
inline void disable() { for (auto& field : m_fields) field.second->disable(); }
+ void set_flag(ogDrawFlag flag) { m_flag = flag; }
+ void set_grid_vgap(int gap) { m_grid_sizer->SetVGap(gap); }
- OptionsGroup(wxWindow* _parent, wxString title, bool is_tab_opt=false) :
- m_parent(_parent), title(title), m_is_tab_opt(is_tab_opt), staticbox(title!="") {
- sizer = (staticbox ? new wxStaticBoxSizer(new wxStaticBox(_parent, wxID_ANY, title), wxVERTICAL) : new wxBoxSizer(wxVERTICAL));
+ void set_show_modified_btns_val(bool show) {
+ m_show_modified_btns = show;
+ }
+
+ OptionsGroup( wxWindow* _parent, const wxString& title, bool is_tab_opt = false,
+ ogDrawFlag flag = ogDEFAULT, column_t extra_clmn = nullptr) :
+ m_parent(_parent), title(title), m_show_modified_btns(is_tab_opt),
+ staticbox(title!=""), m_flag(flag), extra_column(extra_clmn){
+ stb = new wxStaticBox(_parent, wxID_ANY, title);
+ stb->SetFont(bold_font());
+ sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL));
auto num_columns = 1U;
if (label_width != 0) num_columns++;
if (extra_column != nullptr) num_columns++;
- m_grid_sizer = new wxFlexGridSizer(0, num_columns, 0,0);
- static_cast<wxFlexGridSizer*>(m_grid_sizer)->SetFlexibleDirection(wxHORIZONTAL);
+ m_grid_sizer = new wxFlexGridSizer(0, num_columns, 1,0);
+ static_cast<wxFlexGridSizer*>(m_grid_sizer)->SetFlexibleDirection(wxBOTH/*wxHORIZONTAL*/);
static_cast<wxFlexGridSizer*>(m_grid_sizer)->AddGrowableCol(label_width != 0);
-
- sizer->Add(m_grid_sizer, 0, wxEXPAND | wxALL, wxOSX ? 0: 5);
+#ifdef __WXGTK__
+ m_panel = new wxPanel( _parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
+ sizer->Fit(m_panel);
+ sizer->Add(m_panel, 0, wxEXPAND | wxALL, wxOSX||!staticbox ? 0: 5);
+#else
+ sizer->Add(m_grid_sizer, 0, wxEXPAND | wxALL, wxOSX||!staticbox ? 0: 5);
+#endif /* __WXGTK__ */
}
+ wxGridSizer* get_grid_sizer(){ return m_grid_sizer; }
+
protected:
std::map<t_config_option_key, Option> m_options;
wxWindow* m_parent {nullptr};
@@ -137,7 +192,16 @@ protected:
bool m_disabled {false};
wxGridSizer* m_grid_sizer {nullptr};
// "true" if option is created in preset tabs
- bool m_is_tab_opt{ false };
+ bool m_show_modified_btns{ false };
+
+ ogDrawFlag m_flag{ ogDEFAULT };
+
+ // This panel is needed for correct showing of the ToolTips for Button, StaticText and CheckBox
+ // Tooltips on GTK doesn't work inside wxStaticBoxSizer unless you insert a panel
+ // inside it before you insert the other controls.
+#ifdef __WXGTK__
+ wxPanel* m_panel {nullptr};
+#endif /* __WXGTK__ */
/// Generate a wxSizer or wxWindow from a configuration option
/// Precondition: opt resolves to a known ConfigOption
@@ -145,24 +209,27 @@ protected:
const t_field& build_field(const t_config_option_key& id, const ConfigOptionDef& opt, wxStaticText* label = nullptr);
const t_field& build_field(const t_config_option_key& id, wxStaticText* label = nullptr);
const t_field& build_field(const Option& opt, wxStaticText* label = nullptr);
+ void add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field);
virtual void on_kill_focus (){};
- virtual void on_change_OG(t_config_option_key opt_id, boost::any value);
- virtual void back_to_initial_value(const std::string opt_key){};
+ virtual void on_change_OG(const t_config_option_key& opt_id, const boost::any& value);
+ virtual void back_to_initial_value(const std::string& opt_key){}
+ virtual void back_to_sys_value(const std::string& opt_key){}
};
class ConfigOptionsGroup: public OptionsGroup {
public:
- ConfigOptionsGroup(wxWindow* parent, wxString title, DynamicPrintConfig* _config = nullptr, bool is_tab_opt = false) :
- OptionsGroup(parent, title, is_tab_opt), m_config(_config) {}
+ ConfigOptionsGroup( wxWindow* parent, const wxString& title, DynamicPrintConfig* _config = nullptr,
+ bool is_tab_opt = false, ogDrawFlag flag = ogDEFAULT, column_t extra_clmn = nullptr) :
+ OptionsGroup(parent, title, is_tab_opt, flag, extra_clmn), m_config(_config) {}
/// reference to libslic3r config, non-owning pointer (?).
DynamicPrintConfig* m_config {nullptr};
bool m_full_labels {0};
- std::map< std::string, std::pair<std::string, int> > m_opt_map;
+ t_opt_map m_opt_map;
- Option get_option(const std::string opt_key, int opt_index = -1);
- Line create_single_option_line(const std::string title, int idx = -1) /*const*/{
+ Option get_option(const std::string& opt_key, int opt_index = -1);
+ Line create_single_option_line(const std::string& title, int idx = -1) /*const*/{
Option option = get_option(title, idx);
return OptionsGroup::create_single_option_line(option);
}
@@ -175,14 +242,16 @@ public:
append_single_option_line(option);
}
- void on_change_OG(t_config_option_key opt_id, boost::any value) override;
- void back_to_initial_value(const std::string opt_key) override;
+ void on_change_OG(const t_config_option_key& opt_id, const boost::any& value) override;
+ void back_to_initial_value(const std::string& opt_key) override;
+ void back_to_sys_value(const std::string& opt_key) override;
+ void back_to_config_value(const DynamicPrintConfig& config, const std::string& opt_key);
void on_kill_focus() override{ reload_config();}
void reload_config();
- boost::any config_value(std::string opt_key, int opt_index, bool deserialize);
+ boost::any config_value(const std::string& opt_key, int opt_index, bool deserialize);
// return option value from config
- boost::any get_config_value(DynamicPrintConfig& config, std::string opt_key, int opt_index = -1);
- Field* get_fieldc(t_config_option_key opt_key, int opt_index);
+ boost::any get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index = -1);
+ Field* get_fieldc(const t_config_option_key& opt_key, int opt_index);
};
// Static text shown among the options.
@@ -192,7 +261,9 @@ public:
ogStaticText(wxWindow* parent, const char *text) : wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize){}
~ogStaticText(){}
- void SetText(wxString value);
+ void SetText(const wxString& value, bool wrap = true);
};
}}
+
+#endif /* slic3r_OptionsGroup_hpp_ */
diff --git a/xs/src/slic3r/GUI/Preferences.cpp b/xs/src/slic3r/GUI/Preferences.cpp
index 0009b17ec..2500afa13 100644
--- a/xs/src/slic3r/GUI/Preferences.cpp
+++ b/xs/src/slic3r/GUI/Preferences.cpp
@@ -5,15 +5,22 @@
namespace Slic3r {
namespace GUI {
+PreferencesDialog::PreferencesDialog(wxWindow* parent, int event_preferences) :
+ wxDialog(parent, wxID_ANY, _(L("Preferences")), wxDefaultPosition, wxDefaultSize),
+ m_event_preferences(event_preferences) {
+ build();
+ }
+
void PreferencesDialog::build()
{
auto app_config = get_app_config();
m_optgroup = std::make_shared<ConfigOptionsGroup>(this, _(L("General")));
- m_optgroup->label_width = 200;
+ m_optgroup->label_width = 400;
m_optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0";
};
+ // TODO
// $optgroup->append_single_option_line(Slic3r::GUI::OptionsGroup::Option->new(
// opt_id = > 'version_check',
// type = > 'bool',
@@ -28,8 +35,8 @@ void PreferencesDialog::build()
def.type = coBool;
def.tooltip = L("If this is enabled, Slic3r will prompt the last output directory "
"instead of the one containing the input files.");
- def.default_value = new ConfigOptionBool{ app_config->get("remember_output_path")[0] == '1' }; // 1;
- Option option(def, "remember_output_path");
+ def.default_value = new ConfigOptionBool{ app_config->has("remember_output_path") ? app_config->get("remember_output_path")[0] == '1' : true }; // 1;
+ Option option(def, "remember_output_path");
m_optgroup->append_single_option_line(option);
def.label = L("Auto-center parts");
@@ -48,6 +55,22 @@ void PreferencesDialog::build()
option = Option (def,"background_processing");
m_optgroup->append_single_option_line(option);
+ // Please keep in sync with ConfigWizard
+ def.label = L("Check for application updates");
+ def.type = coBool;
+ def.tooltip = L("If enabled, Slic3r checks for new versions of Slic3r PE online. When a new version becomes available a notification is displayed at the next application startup (never during program usage). This is only a notification mechanisms, no automatic installation is done.");
+ def.default_value = new ConfigOptionBool(app_config->get("version_check") == "1");
+ option = Option (def, "version_check");
+ m_optgroup->append_single_option_line(option);
+
+ // Please keep in sync with ConfigWizard
+ def.label = L("Update built-in Presets automatically");
+ def.type = coBool;
+ def.tooltip = L("If enabled, Slic3r downloads updates of built-in system presets in the background. These updates are downloaded into a separate temporary location. When a new preset version becomes available it is offered at application startup.");
+ def.default_value = new ConfigOptionBool(app_config->get("preset_update") == "1");
+ option = Option (def, "preset_update");
+ m_optgroup->append_single_option_line(option);
+
def.label = L("Disable USB/serial connection");
def.type = coBool;
def.tooltip = L("Disable communication with the printer over a serial / USB cable. "
diff --git a/xs/src/slic3r/GUI/Preferences.hpp b/xs/src/slic3r/GUI/Preferences.hpp
index c30e94d22..d01d78b70 100644
--- a/xs/src/slic3r/GUI/Preferences.hpp
+++ b/xs/src/slic3r/GUI/Preferences.hpp
@@ -1,3 +1,6 @@
+#ifndef slic3r_Preferences_hpp_
+#define slic3r_Preferences_hpp_
+
#include "GUI.hpp"
#include <wx/dialog.h>
@@ -14,8 +17,7 @@ class PreferencesDialog : public wxDialog
std::shared_ptr<ConfigOptionsGroup> m_optgroup;
int m_event_preferences;
public:
- PreferencesDialog(wxWindow* parent, int event_preferences) : wxDialog(parent, wxID_ANY, _(L("Preferences")),
- wxDefaultPosition, wxDefaultSize), m_event_preferences(event_preferences) { build(); }
+ PreferencesDialog(wxWindow* parent, int event_preferences);
~PreferencesDialog(){ }
void build();
@@ -25,3 +27,5 @@ public:
} // GUI
} // Slic3r
+
+#endif /* slic3r_Preferences_hpp_ */
diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp
index 59dcabb39..92912a3c4 100644
--- a/xs/src/slic3r/GUI/Preset.cpp
+++ b/xs/src/slic3r/GUI/Preset.cpp
@@ -2,9 +2,14 @@
#include <cassert>
#include "Preset.hpp"
+#include "AppConfig.hpp"
+#include "BitmapCache.hpp"
#include <fstream>
+#include <stdexcept>
+#include <boost/format.hpp>
#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/nowide/cenv.hpp>
@@ -13,6 +18,7 @@
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/locale.hpp>
+#include <boost/log/trivial.hpp>
#include <wx/image.h>
#include <wx/choice.h>
@@ -23,14 +29,16 @@
#include "../../libslic3r/Utils.hpp"
#include "../../libslic3r/PlaceholderParser.hpp"
+using boost::property_tree::ptree;
+
namespace Slic3r {
-ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree)
+ConfigFileType guess_config_file_type(const ptree &tree)
{
size_t app_config = 0;
size_t bundle = 0;
size_t config = 0;
- for (const boost::property_tree::ptree::value_type &v : tree) {
+ for (const ptree::value_type &v : tree) {
if (v.second.empty()) {
if (v.first == "background_processing" ||
v.first == "last_output_path" ||
@@ -58,12 +66,96 @@ ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree)
(bundle > config) ? CONFIG_FILE_TYPE_CONFIG_BUNDLE : CONFIG_FILE_TYPE_CONFIG;
}
+
+VendorProfile VendorProfile::from_ini(const boost::filesystem::path &path, bool load_all)
+{
+ ptree tree;
+ boost::filesystem::ifstream ifs(path);
+ boost::property_tree::read_ini(ifs, tree);
+ return VendorProfile::from_ini(tree, path, load_all);
+}
+
+VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem::path &path, bool load_all)
+{
+ static const std::string printer_model_key = "printer_model:";
+ const std::string id = path.stem().string();
+
+ if (! boost::filesystem::exists(path)) {
+ throw std::runtime_error((boost::format("Cannot load Vendor Config Bundle `%1%`: File not found: `%2%`.") % id % path).str());
+ }
+
+ VendorProfile res(id);
+
+ auto get_or_throw = [&](const ptree &tree, const std::string &key) -> ptree::const_assoc_iterator
+ {
+ auto res = tree.find(key);
+ if (res == tree.not_found()) {
+ throw std::runtime_error((boost::format("Vendor Config Bundle `%1%` is not valid: Missing secion or key: `%2%`.") % id % key).str());
+ }
+ return res;
+ };
+
+ const auto &vendor_section = get_or_throw(tree, "vendor")->second;
+ res.name = get_or_throw(vendor_section, "name")->second.data();
+
+ auto config_version_str = get_or_throw(vendor_section, "config_version")->second.data();
+ auto config_version = Semver::parse(config_version_str);
+ if (! config_version) {
+ throw std::runtime_error((boost::format("Vendor Config Bundle `%1%` is not valid: Cannot parse config_version: `%2%`.") % id % config_version_str).str());
+ } else {
+ res.config_version = std::move(*config_version);
+ }
+
+ auto config_update_url = vendor_section.find("config_update_url");
+ if (config_update_url != vendor_section.not_found()) {
+ res.config_update_url = config_update_url->second.data();
+ }
+
+ if (! load_all) {
+ return res;
+ }
+
+ for (auto &section : tree) {
+ if (boost::starts_with(section.first, printer_model_key)) {
+ VendorProfile::PrinterModel model;
+ model.id = section.first.substr(printer_model_key.size());
+ model.name = section.second.get<std::string>("name", model.id);
+ auto technology_field = section.second.get<std::string>("technology", "FFF");
+ if (! ConfigOptionEnum<PrinterTechnology>::from_string(technology_field, model.technology)) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: Invalid printer technology field: `%2%`") % id % technology_field;
+ model.technology = ptFFF;
+ }
+ section.second.get<std::string>("variants", "");
+ const auto variants_field = section.second.get<std::string>("variants", "");
+ std::vector<std::string> variants;
+ if (Slic3r::unescape_strings_cstyle(variants_field, variants)) {
+ for (const std::string &variant_name : variants) {
+ if (model.variant(variant_name) == nullptr)
+ model.variants.emplace_back(VendorProfile::PrinterVariant(variant_name));
+ }
+ } else {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: Malformed variants field: `%2%`") % id % variants_field;
+ }
+ if (! model.id.empty() && ! model.variants.empty())
+ res.models.push_back(std::move(model));
+ }
+ }
+
+ return res;
+}
+
+
// Suffix to be added to a modified preset name in the combo box.
static std::string g_suffix_modified = " (modified)";
const std::string& Preset::suffix_modified()
{
return g_suffix_modified;
}
+
+void Preset::update_suffix_modified()
+{
+ g_suffix_modified = (" (" + _(L("modified")) + ")").ToUTF8().data();
+}
// Remove an optional "(modified)" suffix from a name.
// This converts a UI name to a unique preset identifier.
std::string Preset::remove_suffix_modified(const std::string &name)
@@ -80,7 +172,7 @@ void Preset::set_num_extruders(DynamicPrintConfig &config, unsigned int num_extr
auto *opt = config.option(key, false);
assert(opt != nullptr);
assert(opt->is_vector());
- if (opt != nullptr && opt->is_vector())
+ if (opt != nullptr && opt->is_vector() && key != "default_filament_profile")
static_cast<ConfigOptionVectorBase*>(opt)->resize(num_extruders, defaults.option(key));
}
}
@@ -90,7 +182,7 @@ void Preset::normalize(DynamicPrintConfig &config)
{
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
if (nozzle_diameter != nullptr)
- // Loaded the Printer settings. Verify, that all extruder dependent values have enough values.
+ // Loaded the FFF Printer settings. Verify, that all extruder dependent values have enough values.
set_num_extruders(config, (unsigned int)nozzle_diameter->values.size());
if (config.option("filament_diameter") != nullptr) {
// This config contains single or multiple filament presets.
@@ -101,20 +193,25 @@ void Preset::normalize(DynamicPrintConfig &config)
if (key == "compatible_printers")
continue;
auto *opt = config.option(key, false);
- assert(opt != nullptr);
- assert(opt->is_vector());
+ /*assert(opt != nullptr);
+ assert(opt->is_vector());*/
if (opt != nullptr && opt->is_vector())
static_cast<ConfigOptionVectorBase*>(opt)->resize(n, defaults.option(key));
}
+ // The following keys are mandatory for the UI, but they are not part of FullPrintConfig, therefore they are handled separately.
+ for (const std::string &key : { "filament_settings_id" }) {
+ auto *opt = config.option(key, false);
+ assert(opt != nullptr);
+ assert(opt->type() == coStrings);
+ if (opt != nullptr && opt->type() == coStrings)
+ static_cast<ConfigOptionStrings*>(opt)->values.resize(n, std::string());
+ }
}
}
-// Load a config file, return a C++ class Slic3r::DynamicPrintConfig with $keys initialized from the config file.
-// In case of a "default" config item, return the default values.
-DynamicPrintConfig& Preset::load(const std::vector<std::string> &keys)
+DynamicPrintConfig& Preset::load(const std::vector<std::string> &keys, const StaticPrintConfig &defaults)
{
// Set the configuration from the defaults.
- Slic3r::FullPrintConfig defaults;
this->config.apply_only(defaults, keys.empty() ? defaults.keys() : keys);
if (! this->is_default) {
// Load the preset file, apply preset values on top of defaults.
@@ -144,12 +241,12 @@ std::string Preset::label() const
bool Preset::is_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config) const
{
- auto *condition = dynamic_cast<const ConfigOptionString*>(this->config.option("compatible_printers_condition"));
+ auto &condition = this->compatible_printers_condition();
auto *compatible_printers = dynamic_cast<const ConfigOptionStrings*>(this->config.option("compatible_printers"));
bool has_compatible_printers = compatible_printers != nullptr && ! compatible_printers->values.empty();
- if (! has_compatible_printers && condition != nullptr && ! condition->value.empty()) {
+ if (! has_compatible_printers && ! condition.empty()) {
try {
- return PlaceholderParser::evaluate_boolean_expression(condition->value, active_printer.config, extra_config);
+ return PlaceholderParser::evaluate_boolean_expression(condition, active_printer.config, extra_config);
} catch (const std::runtime_error &err) {
//FIXME in case of an error, return "compatible with everything".
printf("Preset::is_compatible_with_printer - parsing error of compatible_printers_condition %s:\n%s\n", active_printer.name.c_str(), err.what());
@@ -165,8 +262,9 @@ bool Preset::is_compatible_with_printer(const Preset &active_printer) const
{
DynamicPrintConfig config;
config.set_key_value("printer_preset", new ConfigOptionString(active_printer.name));
- config.set_key_value("num_extruders", new ConfigOptionInt(
- (int)static_cast<const ConfigOptionFloats*>(active_printer.config.option("nozzle_diameter"))->values.size()));
+ const ConfigOption *opt = active_printer.config.option("nozzle_diameter");
+ if (opt)
+ config.set_key_value("num_extruders", new ConfigOptionInt((int)static_cast<const ConfigOptionFloats*>(opt)->values.size()));
return this->is_compatible_with_printer(active_printer, &config);
}
@@ -175,6 +273,15 @@ bool Preset::update_compatible_with_printer(const Preset &active_printer, const
return this->is_compatible = is_compatible_with_printer(active_printer, extra_config);
}
+void Preset::set_visible_from_appconfig(const AppConfig &app_config)
+{
+ if (vendor == nullptr) { return; }
+ const std::string &model = config.opt_string("printer_model");
+ const std::string &variant = config.opt_string("printer_variant");
+ if (model.empty() || variant.empty()) { return; }
+ is_visible = app_config.get_variant(vendor->id, model, variant);
+}
+
const std::vector<std::string>& Preset::print_options()
{
static std::vector<std::string> s_opts {
@@ -199,8 +306,8 @@ const std::vector<std::string>& Preset::print_options()
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects",
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
- "wipe_tower_width", "wipe_tower_per_color_wipe",
- "compatible_printers", "compatible_printers_condition"
+ "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "single_extruder_multi_material_priming",
+ "compatible_printers", "compatible_printers_condition","inherits"
};
return s_opts;
}
@@ -208,12 +315,13 @@ const std::vector<std::string>& Preset::print_options()
const std::vector<std::string>& Preset::filament_options()
{
static std::vector<std::string> s_opts {
- "filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
- "extrusion_multiplier", "filament_density", "filament_cost", "temperature", "first_layer_temperature", "bed_temperature",
- "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed", "max_fan_speed", "bridge_fan_speed",
- "disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed", "start_filament_gcode",
- "end_filament_gcode",
- "compatible_printers", "compatible_printers_condition"
+ "filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
+ "extrusion_multiplier", "filament_density", "filament_cost", "filament_loading_speed", "filament_loading_speed_start", "filament_load_time",
+ "filament_unloading_speed", "filament_unloading_speed_start", "filament_unload_time", "filament_toolchange_delay", "filament_cooling_moves",
+ "filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower",
+ "temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed",
+ "max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed",
+ "start_filament_gcode", "end_filament_gcode","compatible_printers", "compatible_printers_condition", "inherits"
};
return s_opts;
}
@@ -223,16 +331,26 @@ const std::vector<std::string>& Preset::printer_options()
static std::vector<std::string> s_opts;
if (s_opts.empty()) {
s_opts = {
+ "printer_technology",
"bed_shape", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed",
- "octoprint_host", "octoprint_apikey", "octoprint_cafile", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
+ "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
+ "host_type", "print_host", "printhost_apikey", "printhost_cafile",
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
- "between_objects_gcode", "printer_notes", "max_print_height"
+ "between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
+ "cooling_tube_length", "parking_pos_retraction", "extra_loading_move", "max_print_height", "default_print_profile", "inherits",
+ "remaining_times", "silent_mode", "machine_max_acceleration_extruding", "machine_max_acceleration_retracting",
+ "machine_max_acceleration_x", "machine_max_acceleration_y", "machine_max_acceleration_z", "machine_max_acceleration_e",
+ "machine_max_feedrate_x", "machine_max_feedrate_y", "machine_max_feedrate_z", "machine_max_feedrate_e",
+ "machine_min_extruding_rate", "machine_min_travel_rate",
+ "machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e"
};
s_opts.insert(s_opts.end(), Preset::nozzle_options().begin(), Preset::nozzle_options().end());
}
return s_opts;
}
+// The following nozzle options of a printer profile will be adjusted to match the size
+// of the nozzle_diameter vector.
const std::vector<std::string>& Preset::nozzle_options()
{
// ConfigOptionFloats, ConfigOptionPercents, ConfigOptionBools, ConfigOptionStrings
@@ -240,20 +358,53 @@ const std::vector<std::string>& Preset::nozzle_options()
"nozzle_diameter", "min_layer_height", "max_layer_height", "extruder_offset",
"retract_length", "retract_lift", "retract_lift_above", "retract_lift_below", "retract_speed", "deretract_speed",
"retract_before_wipe", "retract_restart_extra", "retract_before_travel", "wipe",
- "retract_layer_change", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour"
+ "retract_layer_change", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour",
+ "default_filament_profile"
};
return s_opts;
}
-PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::string> &keys) :
+const std::vector<std::string>& Preset::sla_printer_options()
+{
+ static std::vector<std::string> s_opts;
+ if (s_opts.empty()) {
+ s_opts = {
+ "printer_technology",
+ "bed_shape", "max_print_height",
+ "display_width", "display_height", "display_pixels_x", "display_pixels_y",
+ "printer_correction",
+ "printer_notes",
+ "inherits"
+ };
+ }
+ return s_opts;
+}
+
+const std::vector<std::string>& Preset::sla_material_options()
+{
+ static std::vector<std::string> s_opts;
+ if (s_opts.empty()) {
+ s_opts = {
+ "layer_height", "initial_layer_height",
+ "exposure_time", "initial_exposure_time",
+ "material_correction_printing", "material_correction_curing",
+ "material_notes",
+ "compatible_printers",
+ "compatible_printers_condition", "inherits"
+ };
+ }
+ return s_opts;
+}
+
+PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name) :
m_type(type),
m_edited_preset(type, "", false),
m_idx_selected(0),
- m_bitmap_main_frame(new wxBitmap)
+ m_bitmap_main_frame(new wxBitmap),
+ m_bitmap_cache(new GUI::BitmapCache)
{
// Insert just the default preset.
- m_presets.emplace_back(Preset(type, "- default -", true));
- m_presets.front().load(keys);
+ this->add_default_preset(keys, defaults, default_name);
m_edited_preset.config.apply(m_presets.front().config);
}
@@ -261,30 +412,39 @@ PresetCollection::~PresetCollection()
{
delete m_bitmap_main_frame;
m_bitmap_main_frame = nullptr;
+ delete m_bitmap_cache;
+ m_bitmap_cache = nullptr;
}
void PresetCollection::reset(bool delete_files)
{
- if (m_presets.size() > 1) {
+ if (m_presets.size() > m_num_default_presets) {
if (delete_files) {
// Erase the preset files.
for (Preset &preset : m_presets)
- if (! preset.is_default && ! preset.is_external)
+ if (! preset.is_default && ! preset.is_external && ! preset.is_system)
boost::nowide::remove(preset.file.c_str());
}
// Don't use m_presets.resize() here as it requires a default constructor for Preset.
- m_presets.erase(m_presets.begin() + 1, m_presets.end());
+ m_presets.erase(m_presets.begin() + m_num_default_presets, m_presets.end());
this->select_preset(0);
}
}
+void PresetCollection::add_default_preset(const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &preset_name)
+{
+ // Insert just the default preset.
+ m_presets.emplace_back(Preset(this->type(), preset_name, true));
+ m_presets.back().load(keys, defaults);
+ ++ m_num_default_presets;
+}
+
// Load all presets found in dir_path.
// Throws an exception on error.
void PresetCollection::load_presets(const std::string &dir_path, const std::string &subdir)
{
boost::filesystem::path dir = boost::filesystem::canonical(boost::filesystem::path(dir_path) / subdir).make_preferred();
m_dir_path = dir.string();
- m_presets.erase(m_presets.begin()+1, m_presets.end());
t_config_option_keys keys = this->default_preset().config.keys();
std::string errors_cummulative;
for (auto &dir_entry : boost::filesystem::directory_iterator(dir))
@@ -292,17 +452,24 @@ void PresetCollection::load_presets(const std::string &dir_path, const std::stri
std::string name = dir_entry.path().filename().string();
// Remove the .ini suffix.
name.erase(name.size() - 4);
+ if (this->find_preset(name, false)) {
+ // This happens when there's is a preset (most likely legacy one) with the same name as a system preset
+ // that's already been loaded from a bundle.
+ BOOST_LOG_TRIVIAL(warning) << "Preset already present, not loading: " << name;
+ continue;
+ }
try {
Preset preset(m_type, name, false);
preset.file = dir_entry.path().string();
- preset.load(keys);
+ //FIXME One should initialize with SLAFullPrintConfig for the SLA profiles!
+ preset.load(keys, static_cast<const HostConfig&>(FullPrintConfig::defaults()));
m_presets.emplace_back(preset);
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
errors_cummulative += "\n";
}
}
- std::sort(m_presets.begin() + 1, m_presets.end());
+ std::sort(m_presets.begin() + m_num_default_presets, m_presets.end());
this->select_preset(first_visible_idx());
if (! errors_cummulative.empty())
throw std::runtime_error(errors_cummulative);
@@ -314,7 +481,90 @@ Preset& PresetCollection::load_preset(const std::string &path, const std::string
{
DynamicPrintConfig cfg(this->default_preset().config);
cfg.apply_only(config, cfg.keys(), true);
- return this->load_preset(path, name, std::move(cfg));
+ return this->load_preset(path, name, std::move(cfg), select);
+}
+
+static bool profile_print_params_same(const DynamicPrintConfig &cfg1, const DynamicPrintConfig &cfg2)
+{
+ t_config_option_keys diff = cfg1.diff(cfg2);
+ // Following keys are used by the UI, not by the slicing core, therefore they are not important
+ // when comparing profiles for equality. Ignore them.
+ for (const char *key : { "compatible_printers", "compatible_printers_condition", "inherits",
+ "print_settings_id", "filament_settings_id", "printer_settings_id",
+ "printer_model", "printer_variant", "default_print_profile", "default_filament_profile" })
+ diff.erase(std::remove(diff.begin(), diff.end(), key), diff.end());
+ // Preset with the same name as stored inside the config exists.
+ return diff.empty();
+}
+
+// Load a preset from an already parsed config file, insert it into the sorted sequence of presets
+// and select it, losing previous modifications.
+// In case
+Preset& PresetCollection::load_external_preset(
+ // Path to the profile source file (a G-code, an AMF or 3MF file, a config file)
+ const std::string &path,
+ // Name of the profile, derived from the source file name.
+ const std::string &name,
+ // Original name of the profile, extracted from the loaded config. Empty, if the name has not been stored.
+ const std::string &original_name,
+ // Config to initialize the preset from.
+ const DynamicPrintConfig &config,
+ // Select the preset after loading?
+ bool select)
+{
+ // Load the preset over a default preset, so that the missing fields are filled in from the default preset.
+ DynamicPrintConfig cfg(this->default_preset().config);
+ cfg.apply_only(config, cfg.keys(), true);
+ // Is there a preset already loaded with the name stored inside the config?
+ std::deque<Preset>::iterator it = this->find_preset_internal(original_name);
+ if (it != m_presets.end() && it->name == original_name && profile_print_params_same(it->config, cfg)) {
+ // The preset exists and it matches the values stored inside config.
+ if (select)
+ this->select_preset(it - m_presets.begin());
+ return *it;
+ }
+ // Update the "inherits" field.
+ std::string &inherits = Preset::inherits(cfg);
+ if (it != m_presets.end() && inherits.empty()) {
+ // There is a profile with the same name already loaded. Should we update the "inherits" field?
+ if (it->vendor == nullptr)
+ inherits = it->inherits();
+ else
+ inherits = it->name;
+ }
+ // The external preset does not match an internal preset, load the external preset.
+ std::string new_name;
+ for (size_t idx = 0;; ++ idx) {
+ std::string suffix;
+ if (original_name.empty()) {
+ if (idx > 0)
+ suffix = " (" + std::to_string(idx) + ")";
+ } else {
+ if (idx == 0)
+ suffix = " (" + original_name + ")";
+ else
+ suffix = " (" + original_name + "-" + std::to_string(idx) + ")";
+ }
+ new_name = name + suffix;
+ it = this->find_preset_internal(new_name);
+ if (it == m_presets.end() || it->name != new_name)
+ // Unique profile name. Insert a new profile.
+ break;
+ if (profile_print_params_same(it->config, cfg)) {
+ // The preset exists and it matches the values stored inside config.
+ if (select)
+ this->select_preset(it - m_presets.begin());
+ return *it;
+ }
+ // Form another profile name.
+ }
+ // Insert a new profile.
+ Preset &preset = this->load_preset(path, new_name, std::move(cfg), select);
+ preset.is_external = true;
+ if (&this->get_selected_preset() == &preset)
+ this->get_edited_preset().is_external = true;
+
+ return preset;
}
Preset& PresetCollection::load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select)
@@ -342,16 +592,32 @@ void PresetCollection::save_current_preset(const std::string &new_name)
if (it != m_presets.end() && it->name == new_name) {
// Preset with the same name found.
Preset &preset = *it;
- if (preset.is_default)
+ if (preset.is_default || preset.is_external || preset.is_system)
// Cannot overwrite the default preset.
return;
// Overwriting an existing preset.
preset.config = std::move(m_edited_preset.config);
} else {
// Creating a new preset.
- Preset &preset = *m_presets.insert(it, m_edited_preset);
+ Preset &preset = *m_presets.insert(it, m_edited_preset);
+ std::string &inherits = preset.inherits();
+ std::string old_name = preset.name;
preset.name = new_name;
preset.file = this->path_from_name(new_name);
+ preset.vendor = nullptr;
+ if (preset.is_system) {
+ // Inheriting from a system preset.
+ inherits = /* preset.vendor->name + "/" + */ old_name;
+ } else if (inherits.empty()) {
+ // Inheriting from a user preset. Link the new preset to the old preset.
+ // inherits = old_name;
+ } else {
+ // Inherited from a user preset. Just maintain the "inherited" flag,
+ // meaning it will inherit from either the system preset, or the inherited user preset.
+ }
+ preset.is_default = false;
+ preset.is_system = false;
+ preset.is_external = false;
}
// 2) Activate the saved preset.
this->select_preset_by_name(new_name, true);
@@ -364,7 +630,7 @@ void PresetCollection::delete_current_preset()
const Preset &selected = this->get_selected_preset();
if (selected.is_default)
return;
- if (! selected.is_external) {
+ if (! selected.is_external && ! selected.is_system) {
// Erase the preset file.
boost::nowide::remove(selected.file.c_str());
}
@@ -384,6 +650,29 @@ bool PresetCollection::load_bitmap_default(const std::string &file_name)
return m_bitmap_main_frame->LoadFile(wxString::FromUTF8(Slic3r::var(file_name).c_str()), wxBITMAP_TYPE_PNG);
}
+const Preset* PresetCollection::get_selected_preset_parent() const
+{
+ const std::string &inherits = this->get_edited_preset().inherits();
+ if (inherits.empty())
+ return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr;
+ const Preset* preset = this->find_preset(inherits, false);
+ return (preset == nullptr || preset->is_default || preset->is_external) ? nullptr : preset;
+}
+
+const Preset* PresetCollection::get_preset_parent(const Preset& child) const
+{
+ const std::string &inherits = child.inherits();
+ if (inherits.empty())
+// return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr;
+ return nullptr;
+ const Preset* preset = this->find_preset(inherits, false);
+ return (preset == nullptr/* || preset->is_default */|| preset->is_external) ? nullptr : preset;
+}
+
+const std::string& PresetCollection::get_suffix_modified() {
+ return g_suffix_modified;
+}
+
// Return a preset by its name. If the preset is active, a temporary copy is returned.
// If a preset is not found by its name, null is returned.
Preset* PresetCollection::find_preset(const std::string &name, bool first_visible_if_not_found)
@@ -398,8 +687,8 @@ Preset* PresetCollection::find_preset(const std::string &name, bool first_visibl
// Return index of the first visible preset. Certainly at least the '- default -' preset shall be visible.
size_t PresetCollection::first_visible_idx() const
{
- size_t idx = m_default_suppressed ? 1 : 0;
- for (; idx < m_presets.size(); ++ idx)
+ size_t idx = m_default_suppressed ? m_num_default_presets : 0;
+ for (; idx < this->m_presets.size(); ++ idx)
if (m_presets[idx].is_visible)
break;
if (idx == m_presets.size())
@@ -407,45 +696,32 @@ size_t PresetCollection::first_visible_idx() const
return idx;
}
-// Return index of the first compatible preset. Certainly at least the '- default -' preset shall be compatible.
-size_t PresetCollection::first_compatible_idx() const
-{
- size_t idx = m_default_suppressed ? 1 : 0;
- for (; idx < m_presets.size(); ++ idx)
- if (m_presets[idx].is_compatible)
- break;
- if (idx == m_presets.size())
- idx = 0;
- return idx;
-}
-
void PresetCollection::set_default_suppressed(bool default_suppressed)
{
if (m_default_suppressed != default_suppressed) {
m_default_suppressed = default_suppressed;
- m_presets.front().is_visible = ! default_suppressed || (m_presets.size() > 1 && m_idx_selected > 0);
+ m_presets.front().is_visible = ! default_suppressed || (m_presets.size() > m_num_default_presets && m_idx_selected > 0);
}
}
-void PresetCollection::update_compatible_with_printer(const Preset &active_printer, bool select_other_if_incompatible)
+size_t PresetCollection::update_compatible_with_printer_internal(const Preset &active_printer, bool unselect_if_incompatible)
{
DynamicPrintConfig config;
config.set_key_value("printer_preset", new ConfigOptionString(active_printer.name));
- config.set_key_value("num_extruders", new ConfigOptionInt(
- (int)static_cast<const ConfigOptionFloats*>(active_printer.config.option("nozzle_diameter"))->values.size()));
- for (size_t idx_preset = 1; idx_preset < m_presets.size(); ++ idx_preset) {
+ const ConfigOption *opt = active_printer.config.option("nozzle_diameter");
+ if (opt)
+ config.set_key_value("num_extruders", new ConfigOptionInt((int)static_cast<const ConfigOptionFloats*>(opt)->values.size()));
+ for (size_t idx_preset = m_num_default_presets; idx_preset < m_presets.size(); ++ idx_preset) {
bool selected = idx_preset == m_idx_selected;
Preset &preset_selected = m_presets[idx_preset];
Preset &preset_edited = selected ? m_edited_preset : preset_selected;
if (! preset_edited.update_compatible_with_printer(active_printer, &config) &&
- selected && select_other_if_incompatible)
+ selected && unselect_if_incompatible)
m_idx_selected = (size_t)-1;
if (selected)
preset_selected.is_compatible = preset_edited.is_compatible;
}
- if (m_idx_selected == (size_t)-1)
- // Find some other compatible preset, or the "-- default --" preset.
- this->select_preset(first_compatible_idx());
+ return m_idx_selected;
}
// Save the preset under a new name. If the name is different from the old one,
@@ -465,36 +741,131 @@ void PresetCollection::update_platter_ui(wxBitmapComboBox *ui)
// Otherwise fill in the list from scratch.
ui->Freeze();
ui->Clear();
- for (size_t i = m_presets.front().is_visible ? 0 : 1; i < m_presets.size(); ++ i) {
- const Preset &preset = m_presets[i];
+ size_t selected_preset_item = 0;
+
+ const Preset &selected_preset = this->get_selected_preset();
+ // Show wide icons if the currently selected preset is not compatible with the current printer,
+ // and draw a red flag in front of the selected preset.
+ bool wide_icons = !selected_preset.is_compatible && m_bitmap_incompatible != nullptr;
+
+ std::map<wxString, wxBitmap*> nonsys_presets;
+ wxString selected = "";
+ if (!this->m_presets.front().is_visible)
+ ui->Append("------- " +_(L("System presets")) + " -------", wxNullBitmap);
+ for (size_t i = this->m_presets.front().is_visible ? 0 : m_num_default_presets; i < this->m_presets.size(); ++i) {
+ const Preset &preset = this->m_presets[i];
if (! preset.is_visible || (! preset.is_compatible && i != m_idx_selected))
continue;
- const wxBitmap *bmp = (i == 0 || preset.is_compatible) ? m_bitmap_main_frame : m_bitmap_incompatible;
- ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
- (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
- if (i == m_idx_selected)
- ui->SetSelection(ui->GetCount() - 1);
- }
- ui->Thaw();
+ std::string bitmap_key = "";
+ // If the filament preset is not compatible and there is a "red flag" icon loaded, show it left
+ // to the filament color image.
+ if (wide_icons)
+ bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt";
+ bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst";
+ wxBitmap *bmp = m_bitmap_cache->find(bitmap_key);
+ if (bmp == nullptr) {
+ // Create the bitmap with color bars.
+ std::vector<wxBitmap> bmps;
+ if (wide_icons)
+ // Paint a red flag for incompatible presets.
+ bmps.emplace_back(preset.is_compatible ? m_bitmap_cache->mkclear(16, 16) : *m_bitmap_incompatible);
+ // Paint the color bars.
+ bmps.emplace_back(m_bitmap_cache->mkclear(4, 16));
+ bmps.emplace_back(*m_bitmap_main_frame);
+ // Paint a lock at the system presets.
+ bmps.emplace_back(m_bitmap_cache->mkclear(6, 16));
+ bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(16, 16));
+ bmp = m_bitmap_cache->insert(bitmap_key, bmps);
+ }
+
+ if (preset.is_default || preset.is_system){
+ ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
+ (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
+ if (i == m_idx_selected)
+ selected_preset_item = ui->GetCount() - 1;
+ }
+ else
+ {
+ nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), bmp/*preset.is_compatible*/);
+ if (i == m_idx_selected)
+ selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str());
+ }
+ if (i + 1 == m_num_default_presets)
+ ui->Append("------- " + _(L("System presets")) + " -------", wxNullBitmap);
+ }
+ if (!nonsys_presets.empty())
+ {
+ ui->Append("------- " + _(L("User presets")) + " -------", wxNullBitmap);
+ for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
+ ui->Append(it->first, *it->second);
+ if (it->first == selected)
+ selected_preset_item = ui->GetCount() - 1;
+ }
+ }
+
+ ui->SetSelection(selected_preset_item);
+ ui->SetToolTip(ui->GetString(selected_preset_item));
+ ui->Thaw();
}
-void PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible)
+size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible)
{
if (ui == nullptr)
- return;
+ return 0;
ui->Freeze();
ui->Clear();
- for (size_t i = m_presets.front().is_visible ? 0 : 1; i < m_presets.size(); ++ i) {
- const Preset &preset = m_presets[i];
+ size_t selected_preset_item = 0;
+
+ std::map<wxString, wxBitmap*> nonsys_presets;
+ wxString selected = "";
+ if (!this->m_presets.front().is_visible)
+ ui->Append("------- " + _(L("System presets")) + " -------", wxNullBitmap);
+ for (size_t i = this->m_presets.front().is_visible ? 0 : m_num_default_presets; i < this->m_presets.size(); ++i) {
+ const Preset &preset = this->m_presets[i];
if (! preset.is_visible || (! show_incompatible && ! preset.is_compatible && i != m_idx_selected))
continue;
- const wxBitmap *bmp = preset.is_compatible ? m_bitmap_compatible : m_bitmap_incompatible;
- ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
- (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
- if (i == m_idx_selected)
- ui->SetSelection(ui->GetCount() - 1);
+ std::string bitmap_key = "tab";
+ bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt";
+ bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst";
+ wxBitmap *bmp = m_bitmap_cache->find(bitmap_key);
+ if (bmp == nullptr) {
+ // Create the bitmap with color bars.
+ std::vector<wxBitmap> bmps;
+ const wxBitmap* tmp_bmp = preset.is_compatible ? m_bitmap_compatible : m_bitmap_incompatible;
+ bmps.emplace_back((tmp_bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *tmp_bmp);
+ // Paint a lock at the system presets.
+ bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(16, 16));
+ bmp = m_bitmap_cache->insert(bitmap_key, bmps);
+ }
+
+ if (preset.is_default || preset.is_system){
+ ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
+ (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
+ if (i == m_idx_selected)
+ selected_preset_item = ui->GetCount() - 1;
+ }
+ else
+ {
+ nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), bmp/*preset.is_compatible*/);
+ if (i == m_idx_selected)
+ selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str());
+ }
+ if (i + 1 == m_num_default_presets)
+ ui->Append("------- " + _(L("System presets")) + " -------", wxNullBitmap);
}
+ if (!nonsys_presets.empty())
+ {
+ ui->Append("------- " + _(L("User presets")) + " -------", wxNullBitmap);
+ for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
+ ui->Append(it->first, *it->second);
+ if (it->first == selected)
+ selected_preset_item = ui->GetCount() - 1;
+ }
+ }
+ ui->SetSelection(selected_preset_item);
+ ui->SetToolTip(ui->GetString(selected_preset_item));
ui->Thaw();
+ return selected_preset_item;
}
// Update a dirty floag of the current preset, update the labels of the UI component accordingly.
@@ -527,16 +898,21 @@ bool PresetCollection::update_dirty_ui(wxBitmapComboBox *ui)
return was_dirty != is_dirty;
}
-std::vector<std::string> PresetCollection::current_dirty_options() const
-{
- std::vector<std::string> changed = this->get_selected_preset().config.diff(this->get_edited_preset().config);
- // The "compatible_printers" option key is handled differently from the others:
- // It is not mandatory. If the key is missing, it means it is compatible with any printer.
- // If the key exists and it is empty, it means it is compatible with no printer.
- std::initializer_list<const char*> optional_keys { "compatible_printers", "compatible_printers_condition" };
- for (auto &opt_key : optional_keys) {
- if (this->get_selected_preset().config.has(opt_key) != this->get_edited_preset().config.has(opt_key))
- changed.emplace_back(opt_key);
+std::vector<std::string> PresetCollection::dirty_options(const Preset *edited, const Preset *reference, const bool deep_compare /*= false*/)
+{
+ std::vector<std::string> changed;
+ if (edited != nullptr && reference != nullptr) {
+ changed = deep_compare ?
+ reference->config.deep_diff(edited->config) :
+ reference->config.diff(edited->config);
+ // The "compatible_printers" option key is handled differently from the others:
+ // It is not mandatory. If the key is missing, it means it is compatible with any printer.
+ // If the key exists and it is empty, it means it is compatible with no printer.
+ std::initializer_list<const char*> optional_keys { "compatible_printers" };
+ for (auto &opt_key : optional_keys) {
+ if (reference->config.has(opt_key) != edited->config.has(opt_key))
+ changed.emplace_back(opt_key);
+ }
}
return changed;
}
@@ -561,12 +937,12 @@ bool PresetCollection::select_preset_by_name(const std::string &name_w_suffix, b
// 1) Try to find the preset by its name.
auto it = this->find_preset_internal(name);
size_t idx = 0;
- if (it != m_presets.end() && it->name == name)
- // Preset found by its name.
+ if (it != m_presets.end() && it->name == name && it->is_visible)
+ // Preset found by its name and it is visible.
idx = it - m_presets.begin();
else {
// Find the first visible preset.
- for (size_t i = m_default_suppressed ? 1 : 0; i < m_presets.size(); ++ i)
+ for (size_t i = m_default_suppressed ? m_num_default_presets : 0; i < m_presets.size(); ++ i)
if (m_presets[i].is_visible) {
idx = i;
break;
@@ -583,6 +959,46 @@ bool PresetCollection::select_preset_by_name(const std::string &name_w_suffix, b
return false;
}
+bool PresetCollection::select_preset_by_name_strict(const std::string &name)
+{
+ // 1) Try to find the preset by its name.
+ auto it = this->find_preset_internal(name);
+ size_t idx = (size_t)-1;
+ if (it != m_presets.end() && it->name == name && it->is_visible)
+ // Preset found by its name.
+ idx = it - m_presets.begin();
+ // 2) Select the new preset.
+ if (idx != (size_t)-1) {
+ this->select_preset(idx);
+ return true;
+ }
+ m_idx_selected = idx;
+ return false;
+}
+
+// Merge one vendor's presets with the other vendor's presets, report duplicates.
+std::vector<std::string> PresetCollection::merge_presets(PresetCollection &&other, const std::set<VendorProfile> &new_vendors)
+{
+ std::vector<std::string> duplicates;
+ for (Preset &preset : other.m_presets) {
+ if (preset.is_default || preset.is_external)
+ continue;
+ Preset key(m_type, preset.name);
+ auto it = std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key);
+ if (it == m_presets.end() || it->name != preset.name) {
+ if (preset.vendor != nullptr) {
+ // Re-assign a pointer to the vendor structure in the new PresetBundle.
+ auto it = new_vendors.find(*preset.vendor);
+ assert(it != new_vendors.end());
+ preset.vendor = &(*it);
+ }
+ this->m_presets.emplace(it, std::move(preset));
+ } else
+ duplicates.emplace_back(std::move(preset.name));
+ }
+ return duplicates;
+}
+
std::string PresetCollection::name() const
{
switch (this->type()) {
diff --git a/xs/src/slic3r/GUI/Preset.hpp b/xs/src/slic3r/GUI/Preset.hpp
index f5c138347..821d7dc54 100644
--- a/xs/src/slic3r/GUI/Preset.hpp
+++ b/xs/src/slic3r/GUI/Preset.hpp
@@ -3,8 +3,12 @@
#include <deque>
+#include <boost/filesystem/path.hpp>
+#include <boost/property_tree/ptree_fwd.hpp>
+
#include "../../libslic3r/libslic3r.h"
#include "../../libslic3r/PrintConfig.hpp"
+#include "slic3r/Utils/Semver.hpp"
class wxBitmap;
class wxChoice;
@@ -13,6 +17,13 @@ class wxItemContainer;
namespace Slic3r {
+class AppConfig;
+class PresetBundle;
+
+namespace GUI {
+ class BitmapCache;
+}
+
enum ConfigFileType
{
CONFIG_FILE_TYPE_UNKNOWN,
@@ -23,6 +34,48 @@ enum ConfigFileType
extern ConfigFileType guess_config_file_type(const boost::property_tree::ptree &tree);
+class VendorProfile
+{
+public:
+ std::string name;
+ std::string id;
+ Semver config_version;
+ std::string config_update_url;
+
+ struct PrinterVariant {
+ PrinterVariant() {}
+ PrinterVariant(const std::string &name) : name(name) {}
+ std::string name;
+ };
+
+ struct PrinterModel {
+ PrinterModel() {}
+ std::string id;
+ std::string name;
+ PrinterTechnology technology;
+ std::vector<PrinterVariant> variants;
+ PrinterVariant* variant(const std::string &name) {
+ for (auto &v : this->variants)
+ if (v.name == name)
+ return &v;
+ return nullptr;
+ }
+ const PrinterVariant* variant(const std::string &name) const { return const_cast<PrinterModel*>(this)->variant(name); }
+ };
+ std::vector<PrinterModel> models;
+
+ VendorProfile() {}
+ VendorProfile(std::string id) : id(std::move(id)) {}
+
+ static VendorProfile from_ini(const boost::filesystem::path &path, bool load_all=true);
+ static VendorProfile from_ini(const boost::property_tree::ptree &tree, const boost::filesystem::path &path, bool load_all=true);
+
+ size_t num_variants() const { size_t n = 0; for (auto &model : models) n += model.variants.size(); return n; }
+
+ bool operator< (const VendorProfile &rhs) const { return this->id < rhs.id; }
+ bool operator==(const VendorProfile &rhs) const { return this->id == rhs.id; }
+};
+
class Preset
{
public:
@@ -31,6 +84,7 @@ public:
TYPE_INVALID,
TYPE_PRINT,
TYPE_FILAMENT,
+ TYPE_SLA_MATERIAL,
TYPE_PRINTER,
};
@@ -44,7 +98,10 @@ public:
// External preset points to a configuration, which has been loaded but not imported
// into the Slic3r default configuration location.
bool is_external = false;
- // Preset is visible, if it is compatible with the active Printer.
+ // System preset is read-only.
+ bool is_system = false;
+ // Preset is visible, if it is associated with a printer model / variant that is enabled in the AppConfig
+ // or if it has no printer model / variant association.
// Also the "default" preset is only visible, if it is the only preset in the list.
bool is_visible = true;
// Has this preset been modified?
@@ -55,9 +112,11 @@ public:
// Name of the preset, usually derived form the file name.
std::string name;
// File name of the preset. This could be a Print / Filament / Printer preset,
- // or a Configuration file bundling the Print + Filament + Printer presets (in that case is_external will be true),
+ // or a Configuration file bundling the Print + Filament + Printer presets (in that case is_external and possibly is_system will be true),
// or it could be a G-code (again, is_external will be true).
std::string file;
+ // If this is a system profile, then there should be a vendor data available to display at the UI.
+ const VendorProfile *vendor = nullptr;
// Has this profile been loaded?
bool loaded = false;
@@ -66,8 +125,7 @@ public:
DynamicPrintConfig config;
// Load this profile for the following keys only.
- // Throws std::runtime_error in case the file cannot be read.
- DynamicPrintConfig& load(const std::vector<std::string> &keys);
+ DynamicPrintConfig& load(const std::vector<std::string> &keys, const StaticPrintConfig &defaults);
void save();
@@ -82,9 +140,26 @@ public:
bool is_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config) const;
bool is_compatible_with_printer(const Preset &active_printer) const;
+ // Returns the name of the preset, from which this preset inherits.
+ static std::string& inherits(DynamicPrintConfig &cfg) { return cfg.option<ConfigOptionString>("inherits", true)->value; }
+ std::string& inherits() { return Preset::inherits(this->config); }
+ const std::string& inherits() const { return Preset::inherits(const_cast<Preset*>(this)->config); }
+
+ // Returns the "compatible_printers_condition".
+ static std::string& compatible_printers_condition(DynamicPrintConfig &cfg) { return cfg.option<ConfigOptionString>("compatible_printers_condition", true)->value; }
+ std::string& compatible_printers_condition() { return Preset::compatible_printers_condition(this->config); }
+ const std::string& compatible_printers_condition() const { return Preset::compatible_printers_condition(const_cast<Preset*>(this)->config); }
+
+ static PrinterTechnology& printer_technology(DynamicPrintConfig &cfg) { return cfg.option<ConfigOptionEnum<PrinterTechnology>>("printer_technology", true)->value; }
+ PrinterTechnology& printer_technology() { return Preset::printer_technology(this->config); }
+ const PrinterTechnology& printer_technology() const { return Preset::printer_technology(const_cast<Preset*>(this)->config); }
+
// Mark this preset as compatible if it is compatible with active_printer.
bool update_compatible_with_printer(const Preset &active_printer, const DynamicPrintConfig *extra_config);
+ // Set is_visible according to application config
+ void set_visible_from_appconfig(const AppConfig &app_config);
+
// Resize the extruder specific fields, initialize them with the content of the 1st extruder.
void set_num_extruders(unsigned int n) { set_num_extruders(this->config, n); }
@@ -98,6 +173,11 @@ public:
// Nozzle options of the printer options.
static const std::vector<std::string>& nozzle_options();
+ static const std::vector<std::string>& sla_printer_options();
+ static const std::vector<std::string>& sla_material_options();
+
+ static void update_suffix_modified();
+
protected:
friend class PresetCollection;
friend class PresetBundle;
@@ -113,15 +193,25 @@ class PresetCollection
{
public:
// Initialize the PresetCollection with the "- default -" preset.
- PresetCollection(Preset::Type type, const std::vector<std::string> &keys);
+ PresetCollection(Preset::Type type, const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &default_name = "- default -");
~PresetCollection();
+ typedef std::deque<Preset>::iterator Iterator;
+ typedef std::deque<Preset>::const_iterator ConstIterator;
+ Iterator begin() { return m_presets.begin() + m_num_default_presets; }
+ ConstIterator begin() const { return m_presets.begin() + m_num_default_presets; }
+ Iterator end() { return m_presets.end(); }
+ ConstIterator end() const { return m_presets.end(); }
+
void reset(bool delete_files);
Preset::Type type() const { return m_type; }
std::string name() const;
const std::deque<Preset>& operator()() const { return m_presets; }
+ // Add default preset at the start of the collection, increment the m_default_preset counter.
+ void add_default_preset(const std::vector<std::string> &keys, const Slic3r::StaticPrintConfig &defaults, const std::string &preset_name);
+
// Load ini files of the particular type from the provided directory path.
void load_presets(const std::string &dir_path, const std::string &subdir);
@@ -130,6 +220,18 @@ public:
Preset& load_preset(const std::string &path, const std::string &name, const DynamicPrintConfig &config, bool select = true);
Preset& load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select = true);
+ Preset& load_external_preset(
+ // Path to the profile source file (a G-code, an AMF or 3MF file, a config file)
+ const std::string &path,
+ // Name of the profile, derived from the source file name.
+ const std::string &name,
+ // Original name of the profile, extracted from the loaded config. Empty, if the name has not been stored.
+ const std::string &original_name,
+ // Config to initialize the preset from.
+ const DynamicPrintConfig &config,
+ // Select the preset after loading?
+ bool select = true);
+
// Save the preset under a new name. If the name is different from the old one,
// a new preset is stored into the list of presets.
// All presets are marked as not modified and the new preset is activated.
@@ -144,6 +246,8 @@ public:
// Compatible & incompatible marks, to be placed at the wxBitmapComboBox items.
void set_bitmap_compatible (const wxBitmap *bmp) { m_bitmap_compatible = bmp; }
void set_bitmap_incompatible(const wxBitmap *bmp) { m_bitmap_incompatible = bmp; }
+ void set_bitmap_lock (const wxBitmap *bmp) { m_bitmap_lock = bmp; }
+ void set_bitmap_lock_open (const wxBitmap *bmp) { m_bitmap_lock_open = bmp; }
// Enable / disable the "- default -" preset.
void set_default_suppressed(bool default_suppressed);
@@ -155,10 +259,26 @@ public:
Preset& get_selected_preset() { return m_presets[m_idx_selected]; }
const Preset& get_selected_preset() const { return m_presets[m_idx_selected]; }
int get_selected_idx() const { return m_idx_selected; }
- // Return the selected preset including the user modifications.
+ // Returns the name of the selected preset, or an empty string if no preset is selected.
+ std::string get_selected_preset_name() const { return (m_idx_selected == -1) ? std::string() : this->get_selected_preset().name; }
+ // For the current edited preset, return the parent preset if there is one.
+ // If there is no parent preset, nullptr is returned.
+ // The parent preset may be a system preset or a user preset, which will be
+ // reflected by the UI.
+ const Preset* get_selected_preset_parent() const;
+ // get parent preset for some child preset
+ const Preset* get_preset_parent(const Preset& child) const;
+ // Return the selected preset including the user modifications.
Preset& get_edited_preset() { return m_edited_preset; }
const Preset& get_edited_preset() const { return m_edited_preset; }
+
+ // used to update preset_choice from Tab
+ const std::deque<Preset>& get_presets() { return m_presets; }
+ int get_idx_selected() { return m_idx_selected; }
+ static const std::string& get_suffix_modified();
+
// Return a preset possibly with modifications.
+ Preset& default_preset() { return m_presets.front(); }
const Preset& default_preset() const { return m_presets.front(); }
// Return a preset by an index. If the preset is active, a temporary copy is returned.
Preset& preset(size_t idx) { return (int(idx) == m_idx_selected) ? m_edited_preset : m_presets[idx]; }
@@ -172,31 +292,66 @@ public:
{ return const_cast<PresetCollection*>(this)->find_preset(name, first_visible_if_not_found); }
size_t first_visible_idx() const;
- size_t first_compatible_idx() const;
+ // Return index of the first compatible preset. Certainly at least the '- default -' preset shall be compatible.
+ // If one of the prefered_alternates is compatible, select it.
+ template<typename PreferedCondition>
+ size_t first_compatible_idx(PreferedCondition prefered_condition) const
+ {
+ size_t i = m_default_suppressed ? m_num_default_presets : 0;
+ size_t n = this->m_presets.size();
+ size_t i_compatible = n;
+ for (; i < n; ++ i)
+ if (m_presets[i].is_compatible) {
+ if (prefered_condition(m_presets[i].name))
+ return i;
+ if (i_compatible == n)
+ // Store the first compatible profile into i_compatible.
+ i_compatible = i;
+ }
+ return (i_compatible == n) ? 0 : i_compatible;
+ }
+ // Return index of the first compatible preset. Certainly at least the '- default -' preset shall be compatible.
+ size_t first_compatible_idx() const { return this->first_compatible_idx([](const std::string&){return true;}); }
+
// Return index of the first visible preset. Certainly at least the '- default -' preset shall be visible.
// Return the first visible preset. Certainly at least the '- default -' preset shall be visible.
Preset& first_visible() { return this->preset(this->first_visible_idx()); }
const Preset& first_visible() const { return this->preset(this->first_visible_idx()); }
Preset& first_compatible() { return this->preset(this->first_compatible_idx()); }
+ template<typename PreferedCondition>
+ Preset& first_compatible(PreferedCondition prefered_condition) { return this->preset(this->first_compatible_idx(prefered_condition)); }
const Preset& first_compatible() const { return this->preset(this->first_compatible_idx()); }
// Return number of presets including the "- default -" preset.
size_t size() const { return m_presets.size(); }
+ bool has_defaults_only() const { return m_presets.size() <= m_num_default_presets; }
// For Print / Filament presets, disable those, which are not compatible with the printer.
- void update_compatible_with_printer(const Preset &active_printer, bool select_other_if_incompatible);
+ template<typename PreferedCondition>
+ void update_compatible_with_printer(const Preset &active_printer, bool select_other_if_incompatible, PreferedCondition prefered_condition)
+ {
+ if (this->update_compatible_with_printer_internal(active_printer, select_other_if_incompatible) == (size_t)-1)
+ // Find some other compatible preset, or the "-- default --" preset.
+ this->select_preset(this->first_compatible_idx(prefered_condition));
+ }
+ void update_compatible_with_printer(const Preset &active_printer, bool select_other_if_incompatible)
+ { this->update_compatible_with_printer(active_printer, select_other_if_incompatible, [](const std::string&){return true;}); }
size_t num_visible() const { return std::count_if(m_presets.begin(), m_presets.end(), [](const Preset &preset){return preset.is_visible;}); }
// Compare the content of get_selected_preset() with get_edited_preset() configs, return true if they differ.
bool current_is_dirty() const { return ! this->current_dirty_options().empty(); }
// Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ.
- std::vector<std::string> current_dirty_options() const;
+ std::vector<std::string> current_dirty_options(const bool deep_compare = false) const
+ { return dirty_options(&this->get_edited_preset(), &this->get_selected_preset(), deep_compare); }
+ // Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ.
+ std::vector<std::string> current_different_from_parent_options(const bool deep_compare = false) const
+ { return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent(), deep_compare); }
// Update the choice UI from the list of presets.
// If show_incompatible, all presets are shown, otherwise only the compatible presets are shown.
// If an incompatible preset is selected, it is shown as well.
- void update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible);
+ size_t update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible);
// Update the choice UI from the list of presets.
// Only the compatible presets are shown.
// If an incompatible preset is selected, it is shown as well.
@@ -214,23 +369,44 @@ public:
// Generate a file path from a profile name. Add the ".ini" suffix if it is missing.
std::string path_from_name(const std::string &new_name) const;
+protected:
+ // Select a preset, if it exists. If it does not exist, select an invalid (-1) index.
+ // This is a temporary state, which shall be fixed immediately by the following step.
+ bool select_preset_by_name_strict(const std::string &name);
+
+ // Merge one vendor's presets with the other vendor's presets, report duplicates.
+ std::vector<std::string> merge_presets(PresetCollection &&other, const std::set<VendorProfile> &new_vendors);
+
private:
PresetCollection();
PresetCollection(const PresetCollection &other);
PresetCollection& operator=(const PresetCollection &other);
- // Find a preset in the sorted list of presets.
+ // Find a preset position in the sorted list of presets.
// The "-- default -- " preset is always the first, so it needs
// to be handled differently.
+ // If a preset does not exist, an iterator is returned indicating where to insert a preset with the same name.
std::deque<Preset>::iterator find_preset_internal(const std::string &name)
{
Preset key(m_type, name);
- auto it = std::lower_bound(m_presets.begin() + 1, m_presets.end(), key);
- return ((it == m_presets.end() || it->name != name) && m_presets.front().name == name) ? m_presets.begin() : it;
+ auto it = std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key);
+ if (it == m_presets.end() || it->name != name) {
+ // Preset has not been not found in the sorted list of non-default presets. Try the defaults.
+ for (size_t i = 0; i < m_num_default_presets; ++ i)
+ if (m_presets[i].name == name) {
+ it = m_presets.begin() + i;
+ break;
+ }
+ }
+ return it;
}
std::deque<Preset>::const_iterator find_preset_internal(const std::string &name) const
{ return const_cast<PresetCollection*>(this)->find_preset_internal(name); }
+ size_t update_compatible_with_printer_internal(const Preset &active_printer, bool unselect_if_incompatible);
+
+ static std::vector<std::string> dirty_options(const Preset *edited, const Preset *reference, const bool is_printer_type = false);
+
// Type of this PresetCollection: TYPE_PRINT, TYPE_FILAMENT or TYPE_PRINTER.
Preset::Type m_type;
// List of presets, starting with the "- default -" preset.
@@ -242,16 +418,25 @@ private:
// Selected preset.
int m_idx_selected;
// Is the "- default -" preset suppressed?
- bool m_default_suppressed = true;
+ bool m_default_suppressed = true;
+ size_t m_num_default_presets = 0;
// Compatible & incompatible marks, to be placed at the wxBitmapComboBox items of a Platter.
// These bitmaps are not owned by PresetCollection, but by a PresetBundle.
- const wxBitmap *m_bitmap_compatible = nullptr;
+ const wxBitmap *m_bitmap_compatible = nullptr;
const wxBitmap *m_bitmap_incompatible = nullptr;
+ const wxBitmap *m_bitmap_lock = nullptr;
+ const wxBitmap *m_bitmap_lock_open = nullptr;
// Marks placed at the wxBitmapComboBox of a MainFrame.
// These bitmaps are owned by PresetCollection.
wxBitmap *m_bitmap_main_frame;
// Path to the directory to store the config files into.
std::string m_dir_path;
+
+ // Caching color bitmaps for the filament combo box.
+ GUI::BitmapCache *m_bitmap_cache = nullptr;
+
+ // to access select_preset_by_name_strict()
+ friend class PresetBundle;
};
} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/PresetBundle.cpp b/xs/src/slic3r/GUI/PresetBundle.cpp
index bf79c6562..cd3924dd0 100644
--- a/xs/src/slic3r/GUI/PresetBundle.cpp
+++ b/xs/src/slic3r/GUI/PresetBundle.cpp
@@ -2,7 +2,9 @@
#include <cassert>
#include "PresetBundle.hpp"
+#include "BitmapCache.hpp"
+#include <algorithm>
#include <fstream>
#include <boost/filesystem.hpp>
#include <boost/algorithm/clamp.hpp>
@@ -32,69 +34,128 @@
namespace Slic3r {
+static std::vector<std::string> s_project_options {
+ "wiping_volumes_extruders",
+ "wiping_volumes_matrix"
+};
+
PresetBundle::PresetBundle() :
- prints(Preset::TYPE_PRINT, Preset::print_options()),
- filaments(Preset::TYPE_FILAMENT, Preset::filament_options()),
- printers(Preset::TYPE_PRINTER, Preset::printer_options()),
+ prints(Preset::TYPE_PRINT, Preset::print_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults())),
+ filaments(Preset::TYPE_FILAMENT, Preset::filament_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults())),
+ sla_materials(Preset::TYPE_SLA_MATERIAL, Preset::sla_material_options(), static_cast<const SLAMaterialConfig&>(SLAFullPrintConfig::defaults())),
+ printers(Preset::TYPE_PRINTER, Preset::printer_options(), static_cast<const HostConfig&>(FullPrintConfig::defaults()), "- default FFF -"),
m_bitmapCompatible(new wxBitmap),
- m_bitmapIncompatible(new wxBitmap)
+ m_bitmapIncompatible(new wxBitmap),
+ m_bitmapLock(new wxBitmap),
+ m_bitmapLockOpen(new wxBitmap),
+ m_bitmapCache(new GUI::BitmapCache)
{
if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr)
wxImage::AddHandler(new wxPNGHandler);
+ // The following keys are handled by the UI, they do not have a counterpart in any StaticPrintConfig derived classes,
+ // therefore they need to be handled differently. As they have no counterpart in StaticPrintConfig, they are not being
+ // initialized based on PrintConfigDef(), but to empty values (zeros, empty vectors, empty strings).
+ //
+ // "compatible_printers", "compatible_printers_condition", "inherits",
+ // "print_settings_id", "filament_settings_id", "printer_settings_id",
+ // "printer_vendor", "printer_model", "printer_variant", "default_print_profile", "default_filament_profile"
+
// Create the ID config keys, as they are not part of the Static print config classes.
- this->prints.preset(0).config.opt_string("print_settings_id", true);
- this->filaments.preset(0).config.opt_string("filament_settings_id", true);
- this->printers.preset(0).config.opt_string("print_settings_id", true);
- // Create the "compatible printers" keys, as they are not part of the Static print config classes.
- this->filaments.preset(0).config.optptr("compatible_printers", true);
- this->filaments.preset(0).config.optptr("compatible_printers_condition", true);
- this->prints.preset(0).config.optptr("compatible_printers", true);
- this->prints.preset(0).config.optptr("compatible_printers_condition", true);
-
- this->prints .load_bitmap_default("cog.png");
- this->filaments.load_bitmap_default("spool.png");
- this->printers .load_bitmap_default("printer_empty.png");
+ this->prints.default_preset().config.optptr("print_settings_id", true);
+ this->prints.default_preset().compatible_printers_condition();
+ this->prints.default_preset().inherits();
+
+ this->filaments.default_preset().config.option<ConfigOptionStrings>("filament_settings_id", true)->values = { "" };
+ this->filaments.default_preset().compatible_printers_condition();
+ this->filaments.default_preset().inherits();
+
+ this->sla_materials.default_preset().config.optptr("sla_material_settings_id", true);
+ this->sla_materials.default_preset().compatible_printers_condition();
+ this->sla_materials.default_preset().inherits();
+
+ this->printers.add_default_preset(Preset::sla_printer_options(), static_cast<const SLAMaterialConfig&>(SLAFullPrintConfig::defaults()), "- default SLA -");
+ this->printers.preset(1).printer_technology() = ptSLA;
+ for (size_t i = 0; i < 2; ++ i) {
+ Preset &preset = this->printers.preset(i);
+ preset.config.optptr("printer_settings_id", true);
+ preset.config.optptr("printer_vendor", true);
+ preset.config.optptr("printer_model", true);
+ preset.config.optptr("printer_variant", true);
+ preset.config.optptr("default_print_profile", true);
+ preset.config.option<ConfigOptionStrings>("default_filament_profile", true)->values = { "" };
+ preset.inherits();
+ }
+
+ // Load the default preset bitmaps.
+ this->prints .load_bitmap_default("cog.png");
+ this->filaments .load_bitmap_default("spool.png");
+ this->sla_materials.load_bitmap_default("package_green.png");
+ this->printers .load_bitmap_default("printer_empty.png");
this->load_compatible_bitmaps();
+
+ // Re-activate the default presets, so their "edited" preset copies will be updated with the additional configuration values above.
+ this->prints .select_preset(0);
+ this->filaments .select_preset(0);
+ this->sla_materials.select_preset(0);
+ this->printers .select_preset(0);
+
+ this->project_config.apply_only(FullPrintConfig::defaults(), s_project_options);
}
PresetBundle::~PresetBundle()
{
assert(m_bitmapCompatible != nullptr);
assert(m_bitmapIncompatible != nullptr);
+ assert(m_bitmapLock != nullptr);
+ assert(m_bitmapLockOpen != nullptr);
delete m_bitmapCompatible;
m_bitmapCompatible = nullptr;
delete m_bitmapIncompatible;
m_bitmapIncompatible = nullptr;
- for (std::pair<const std::string, wxBitmap*> &bitmap : m_mapColorToBitmap)
- delete bitmap.second;
+ delete m_bitmapLock;
+ m_bitmapLock = nullptr;
+ delete m_bitmapLockOpen;
+ m_bitmapLockOpen = nullptr;
+ delete m_bitmapCache;
+ m_bitmapCache = nullptr;
}
void PresetBundle::reset(bool delete_files)
{
// Clear the existing presets, delete their respective files.
- this->prints .reset(delete_files);
- this->filaments.reset(delete_files);
- this->printers .reset(delete_files);
+ this->vendors.clear();
+ this->prints .reset(delete_files);
+ this->filaments .reset(delete_files);
+ this->sla_materials.reset(delete_files);
+ this->printers .reset(delete_files);
this->filament_presets.clear();
- this->filament_presets.emplace_back(this->filaments.get_selected_preset().name);
+ this->filament_presets.emplace_back(this->filaments.get_selected_preset_name());
+ this->obsolete_presets.prints.clear();
+ this->obsolete_presets.filaments.clear();
+ this->obsolete_presets.sla_materials.clear();
+ this->obsolete_presets.printers.clear();
}
void PresetBundle::setup_directories()
{
boost::filesystem::path data_dir = boost::filesystem::path(Slic3r::data_dir());
std::initializer_list<boost::filesystem::path> paths = {
- data_dir,
+ data_dir,
+ data_dir / "vendor",
+ data_dir / "cache",
#ifdef SLIC3R_PROFILE_USE_PRESETS_SUBDIR
// Store the print/filament/printer presets into a "presets" directory.
data_dir / "presets",
data_dir / "presets" / "print",
data_dir / "presets" / "filament",
+ data_dir / "presets" / "sla_material",
data_dir / "presets" / "printer"
#else
// Store the print/filament/printer presets at the same location as the upstream Slic3r.
data_dir / "print",
data_dir / "filament",
+ data_dir / "sla_material",
data_dir / "printer"
#endif
};
@@ -107,10 +168,12 @@ void PresetBundle::setup_directories()
}
}
-void PresetBundle::load_presets()
+void PresetBundle::load_presets(const AppConfig &config)
{
- std::string errors_cummulative;
- const std::string dir_path = data_dir()
+ // First load the vendor specific system presets.
+ std::string errors_cummulative = this->load_system_presets();
+
+ const std::string dir_user_presets = data_dir()
#ifdef SLIC3R_PROFILE_USE_PRESETS_SUBDIR
// Store the print/filament/printer presets into a "presets" directory.
+ "/presets"
@@ -119,17 +182,22 @@ void PresetBundle::load_presets()
#endif
;
try {
- this->prints.load_presets(dir_path, "print");
+ this->prints.load_presets(dir_user_presets, "print");
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
try {
- this->filaments.load_presets(dir_path, "filament");
+ this->filaments.load_presets(dir_user_presets, "filament");
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
try {
- this->printers.load_presets(dir_path, "printer");
+ this->sla_materials.load_presets(dir_user_presets, "sla_material");
+ } catch (const std::runtime_error &err) {
+ errors_cummulative += err.what();
+ }
+ try {
+ this->printers.load_presets(dir_user_presets, "printer");
} catch (const std::runtime_error &err) {
errors_cummulative += err.what();
}
@@ -137,6 +205,72 @@ void PresetBundle::load_presets()
this->update_compatible_with_printer(false);
if (! errors_cummulative.empty())
throw std::runtime_error(errors_cummulative);
+
+ this->load_selections(config);
+}
+
+// Load system presets into this PresetBundle.
+// For each vendor, there will be a single PresetBundle loaded.
+std::string PresetBundle::load_system_presets()
+{
+ // Here the vendor specific read only Config Bundles are stored.
+ boost::filesystem::path dir = (boost::filesystem::path(data_dir()) / "vendor").make_preferred();
+ std::string errors_cummulative;
+ bool first = true;
+ for (auto &dir_entry : boost::filesystem::directory_iterator(dir))
+ if (boost::filesystem::is_regular_file(dir_entry.status()) && boost::algorithm::iends_with(dir_entry.path().filename().string(), ".ini")) {
+ std::string name = dir_entry.path().filename().string();
+ // Remove the .ini suffix.
+ name.erase(name.size() - 4);
+ try {
+ // Load the config bundle, flatten it.
+ if (first) {
+ // Reset this PresetBundle and load the first vendor config.
+ this->load_configbundle(dir_entry.path().string(), LOAD_CFGBNDLE_SYSTEM);
+ first = false;
+ } else {
+ // Load the other vendor configs, merge them with this PresetBundle.
+ // Report duplicate profiles.
+ PresetBundle other;
+ other.load_configbundle(dir_entry.path().string(), LOAD_CFGBNDLE_SYSTEM);
+ std::vector<std::string> duplicates = this->merge_presets(std::move(other));
+ if (! duplicates.empty()) {
+ errors_cummulative += "Vendor configuration file " + name + " contains the following presets with names used by other vendors: ";
+ for (size_t i = 0; i < duplicates.size(); ++ i) {
+ if (i > 0)
+ errors_cummulative += ", ";
+ errors_cummulative += duplicates[i];
+ }
+ }
+ }
+ } catch (const std::runtime_error &err) {
+ errors_cummulative += err.what();
+ errors_cummulative += "\n";
+ }
+ }
+ if (first) {
+ // No config bundle loaded, reset.
+ this->reset(false);
+ }
+ return errors_cummulative;
+}
+
+// Merge one vendor's presets with the other vendor's presets, report duplicates.
+std::vector<std::string> PresetBundle::merge_presets(PresetBundle &&other)
+{
+ this->vendors.insert(other.vendors.begin(), other.vendors.end());
+ std::vector<std::string> duplicate_prints = this->prints .merge_presets(std::move(other.prints), this->vendors);
+ std::vector<std::string> duplicate_filaments = this->filaments .merge_presets(std::move(other.filaments), this->vendors);
+ std::vector<std::string> duplicate_sla_materials = this->sla_materials.merge_presets(std::move(other.sla_materials), this->vendors);
+ std::vector<std::string> duplicate_printers = this->printers .merge_presets(std::move(other.printers), this->vendors);
+ append(this->obsolete_presets.prints, std::move(other.obsolete_presets.prints));
+ append(this->obsolete_presets.filaments, std::move(other.obsolete_presets.filaments));
+ append(this->obsolete_presets.sla_materials, std::move(other.obsolete_presets.sla_materials));
+ append(this->obsolete_presets.printers, std::move(other.obsolete_presets.printers));
+ append(duplicate_prints, std::move(duplicate_filaments));
+ append(duplicate_prints, std::move(duplicate_sla_materials));
+ append(duplicate_prints, std::move(duplicate_printers));
+ return duplicate_prints;
}
static inline std::string remove_ini_suffix(const std::string &name)
@@ -147,96 +281,178 @@ static inline std::string remove_ini_suffix(const std::string &name)
return out;
}
+// Set the "enabled" flag for printer vendors, printer models and printer variants
+// based on the user configuration.
+// If the "vendor" section is missing, enable all models and variants of the particular vendor.
+void PresetBundle::load_installed_printers(const AppConfig &config)
+{
+ for (auto &preset : printers) {
+ preset.set_visible_from_appconfig(config);
+ }
+}
+
// Load selections (current print, current filaments, current printer) from config.ini
-// This is done just once on application start up.
+// This is done on application start up or after updates are applied.
void PresetBundle::load_selections(const AppConfig &config)
{
- prints.select_preset_by_name(remove_ini_suffix(config.get("presets", "print")), true);
- filaments.select_preset_by_name(remove_ini_suffix(config.get("presets", "filament")), true);
- printers.select_preset_by_name(remove_ini_suffix(config.get("presets", "printer")), true);
- auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(printers.get_selected_preset().config.option("nozzle_diameter"));
- size_t num_extruders = nozzle_diameter->values.size();
- this->set_filament_preset(0, filaments.get_selected_preset().name);
- for (unsigned int i = 1; i < (unsigned int)num_extruders; ++ i) {
- char name[64];
- sprintf(name, "filament_%d", i);
- if (! config.has("presets", name))
- break;
- this->set_filament_preset(i, remove_ini_suffix(config.get("presets", name)));
+ // Update visibility of presets based on application vendor / model / variant configuration.
+ this->load_installed_printers(config);
+
+ // Parse the initial print / filament / printer profile names.
+ std::string initial_print_profile_name = remove_ini_suffix(config.get("presets", "print"));
+ std::string initial_filament_profile_name = remove_ini_suffix(config.get("presets", "filament"));
+ std::string initial_sla_material_profile_name = remove_ini_suffix(config.get("presets", "sla_material"));
+ std::string initial_printer_profile_name = remove_ini_suffix(config.get("presets", "printer"));
+
+ // Activate print / filament / printer profiles from the config.
+ // If the printer profile enumerated by the config are not visible, select an alternate preset.
+ // Do not select alternate profiles for the print / filament profiles as those presets
+ // will be selected by the following call of this->update_compatible_with_printer(true).
+ prints.select_preset_by_name_strict(initial_print_profile_name);
+ filaments.select_preset_by_name_strict(initial_filament_profile_name);
+ sla_materials.select_preset_by_name_strict(initial_sla_material_profile_name);
+ printers.select_preset_by_name(initial_printer_profile_name, true);
+
+ if (printers.get_selected_preset().printer_technology() == ptFFF){
+ // Load the names of the other filament profiles selected for a multi-material printer.
+ auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(printers.get_selected_preset().config.option("nozzle_diameter"));
+ size_t num_extruders = nozzle_diameter->values.size();
+ this->filament_presets = { initial_filament_profile_name };
+ for (unsigned int i = 1; i < (unsigned int)num_extruders; ++i) {
+ char name[64];
+ sprintf(name, "filament_%d", i);
+ if (!config.has("presets", name))
+ break;
+ this->filament_presets.emplace_back(remove_ini_suffix(config.get("presets", name)));
+ }
+ // Do not define the missing filaments, so that the update_compatible_with_printer() will use the preferred filaments.
+ this->filament_presets.resize(num_extruders, "");
}
+
// Update visibility of presets based on their compatibility with the active printer.
// Always try to select a compatible print and filament preset to the current printer preset,
// as the application may have been closed with an active "external" preset, which does not
// exist.
this->update_compatible_with_printer(true);
+ this->update_multi_material_filament_presets();
}
// Export selections (current print, current filaments, current printer) into config.ini
void PresetBundle::export_selections(AppConfig &config)
{
assert(filament_presets.size() >= 1);
- assert(filament_presets.size() > 1 || filaments.get_selected_preset().name == filament_presets.front());
+ assert(filament_presets.size() > 1 || filaments.get_selected_preset_name() == filament_presets.front());
config.clear_section("presets");
- config.set("presets", "print", prints.get_selected_preset().name);
- config.set("presets", "filament", filament_presets.front());
+ config.set("presets", "print", prints.get_selected_preset_name());
+ config.set("presets", "filament", filament_presets.front());
for (int i = 1; i < filament_presets.size(); ++i) {
char name[64];
sprintf(name, "filament_%d", i);
config.set("presets", name, filament_presets[i]);
}
- config.set("presets", "printer", printers.get_selected_preset().name);
+ config.set("presets", "sla_material", sla_materials.get_selected_preset_name());
+ config.set("presets", "printer", printers.get_selected_preset_name());
}
void PresetBundle::export_selections(PlaceholderParser &pp)
{
assert(filament_presets.size() >= 1);
- assert(filament_presets.size() > 1 || filaments.get_selected_preset().name == filament_presets.front());
- pp.set("print_preset", prints.get_selected_preset().name);
- pp.set("filament_preset", filament_presets);
- pp.set("printer_preset", printers.get_selected_preset().name);
+ assert(filament_presets.size() > 1 || filaments.get_selected_preset_name() == filament_presets.front());
+ switch (printers.get_edited_preset().printer_technology()) {
+ case ptFFF:
+ pp.set("print_preset", prints.get_selected_preset().name);
+ pp.set("filament_preset", filament_presets);
+ break;
+ case ptSLA:
+ pp.set("sla_material_preset", sla_materials.get_selected_preset().name);
+ break;
+ }
+ pp.set("printer_preset", printers.get_selected_preset().name);
}
bool PresetBundle::load_compatible_bitmaps()
{
const std::string path_bitmap_compatible = "flag-green-icon.png";
const std::string path_bitmap_incompatible = "flag-red-icon.png";
+ const std::string path_bitmap_lock = "sys_lock.png";//"lock.png";
+ const std::string path_bitmap_lock_open = "sys_unlock.png";//"lock_open.png";
bool loaded_compatible = m_bitmapCompatible ->LoadFile(
wxString::FromUTF8(Slic3r::var(path_bitmap_compatible).c_str()), wxBITMAP_TYPE_PNG);
bool loaded_incompatible = m_bitmapIncompatible->LoadFile(
wxString::FromUTF8(Slic3r::var(path_bitmap_incompatible).c_str()), wxBITMAP_TYPE_PNG);
+ bool loaded_lock = m_bitmapLock->LoadFile(
+ wxString::FromUTF8(Slic3r::var(path_bitmap_lock).c_str()), wxBITMAP_TYPE_PNG);
+ bool loaded_lock_open = m_bitmapLockOpen->LoadFile(
+ wxString::FromUTF8(Slic3r::var(path_bitmap_lock_open).c_str()), wxBITMAP_TYPE_PNG);
if (loaded_compatible) {
- prints .set_bitmap_compatible(m_bitmapCompatible);
- filaments.set_bitmap_compatible(m_bitmapCompatible);
+ prints .set_bitmap_compatible(m_bitmapCompatible);
+ filaments .set_bitmap_compatible(m_bitmapCompatible);
+ sla_materials.set_bitmap_compatible(m_bitmapCompatible);
// printers .set_bitmap_compatible(m_bitmapCompatible);
}
if (loaded_incompatible) {
- prints .set_bitmap_incompatible(m_bitmapIncompatible);
- filaments.set_bitmap_incompatible(m_bitmapIncompatible);
-// printers .set_bitmap_incompatible(m_bitmapIncompatible);
+ prints .set_bitmap_incompatible(m_bitmapIncompatible);
+ filaments .set_bitmap_incompatible(m_bitmapIncompatible);
+ sla_materials.set_bitmap_incompatible(m_bitmapIncompatible);
+// printers .set_bitmap_incompatible(m_bitmapIncompatible);
+ }
+ if (loaded_lock) {
+ prints .set_bitmap_lock(m_bitmapLock);
+ filaments .set_bitmap_lock(m_bitmapLock);
+ sla_materials.set_bitmap_lock(m_bitmapLock);
+ printers .set_bitmap_lock(m_bitmapLock);
}
- return loaded_compatible && loaded_incompatible;
+ if (loaded_lock_open) {
+ prints .set_bitmap_lock_open(m_bitmapLock);
+ filaments .set_bitmap_lock_open(m_bitmapLock);
+ sla_materials.set_bitmap_lock_open(m_bitmapLock);
+ printers .set_bitmap_lock_open(m_bitmapLock);
+ }
+ return loaded_compatible && loaded_incompatible && loaded_lock && loaded_lock_open;
}
DynamicPrintConfig PresetBundle::full_config() const
+{
+ return (this->printers.get_edited_preset().printer_technology() == ptFFF) ?
+ this->full_fff_config() :
+ this->full_sla_config();
+}
+
+DynamicPrintConfig PresetBundle::full_fff_config() const
{
DynamicPrintConfig out;
- out.apply(FullPrintConfig());
+ out.apply(FullPrintConfig::defaults());
out.apply(this->prints.get_edited_preset().config);
- out.apply(this->printers.get_edited_preset().config);
+ // Add the default filament preset to have the "filament_preset_id" defined.
+ out.apply(this->filaments.default_preset().config);
+ out.apply(this->printers.get_edited_preset().config);
+ out.apply(this->project_config);
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(out.option("nozzle_diameter"));
size_t num_extruders = nozzle_diameter->values.size();
+ // Collect the "compatible_printers_condition" and "inherits" values over all presets (print, filaments, printers) into a single vector.
+ std::vector<std::string> compatible_printers_condition;
+ std::vector<std::string> inherits;
+ compatible_printers_condition.emplace_back(this->prints.get_edited_preset().compatible_printers_condition());
+ inherits .emplace_back(this->prints.get_edited_preset().inherits());
if (num_extruders <= 1) {
out.apply(this->filaments.get_edited_preset().config);
+ compatible_printers_condition.emplace_back(this->filaments.get_edited_preset().compatible_printers_condition());
+ inherits .emplace_back(this->filaments.get_edited_preset().inherits());
} else {
// Retrieve filament presets and build a single config object for them.
// First collect the filament configurations based on the user selection of this->filament_presets.
+ // Here this->filaments.find_preset() and this->filaments.first_visible() return the edited copy of the preset if active.
std::vector<const DynamicPrintConfig*> filament_configs;
for (const std::string &filament_preset_name : this->filament_presets)
filament_configs.emplace_back(&this->filaments.find_preset(filament_preset_name, true)->config);
while (filament_configs.size() < num_extruders)
filament_configs.emplace_back(&this->filaments.first_visible().config);
+ for (const DynamicPrintConfig *cfg : filament_configs) {
+ compatible_printers_condition.emplace_back(Preset::compatible_printers_condition(*const_cast<DynamicPrintConfig*>(cfg)));
+ inherits .emplace_back(Preset::inherits(*const_cast<DynamicPrintConfig*>(cfg)));
+ }
// Option values to set a ConfigOptionVector from.
std::vector<const ConfigOption*> filament_opts(num_extruders, nullptr);
// loop through options and apply them to the resulting config.
@@ -259,7 +475,13 @@ DynamicPrintConfig PresetBundle::full_config() const
}
}
+ // Don't store the "compatible_printers_condition" for the printer profile, there is none.
+ inherits.emplace_back(this->printers.get_edited_preset().inherits());
+
+ // These two value types clash between the print and filament profiles. They should be renamed.
out.erase("compatible_printers");
+ out.erase("compatible_printers_condition");
+ out.erase("inherits");
static const char *keys[] = { "perimeter", "infill", "solid_infill", "support_material", "support_material_interface" };
for (size_t i = 0; i < sizeof(keys) / sizeof(keys[0]); ++ i) {
@@ -269,6 +491,67 @@ DynamicPrintConfig PresetBundle::full_config() const
opt->value = boost::algorithm::clamp<int>(opt->value, 0, int(num_extruders));
}
+ out.option<ConfigOptionString >("print_settings_id", true)->value = this->prints.get_selected_preset().name;
+ out.option<ConfigOptionStrings>("filament_settings_id", true)->values = this->filament_presets;
+ out.option<ConfigOptionString >("printer_settings_id", true)->value = this->printers.get_selected_preset().name;
+
+ // Serialize the collected "compatible_printers_condition" and "inherits" fields.
+ // There will be 1 + num_exturders fields for "inherits" and 2 + num_extruders for "compatible_printers_condition" stored.
+ // The vector will not be stored if all fields are empty strings.
+ auto add_if_some_non_empty = [&out](std::vector<std::string> &&values, const std::string &key) {
+ bool nonempty = false;
+ for (const std::string &v : values)
+ if (! v.empty()) {
+ nonempty = true;
+ break;
+ }
+ if (nonempty)
+ out.set_key_value(key, new ConfigOptionStrings(std::move(values)));
+ };
+ add_if_some_non_empty(std::move(compatible_printers_condition), "compatible_printers_condition_cummulative");
+ add_if_some_non_empty(std::move(inherits), "inherits_cummulative");
+ return out;
+}
+
+DynamicPrintConfig PresetBundle::full_sla_config() const
+{
+ DynamicPrintConfig out;
+ out.apply(SLAFullPrintConfig::defaults());
+ out.apply(this->sla_materials.get_edited_preset().config);
+ out.apply(this->printers.get_edited_preset().config);
+ // There are no project configuration values as of now, the project_config is reserved for FFF printers.
+// out.apply(this->project_config);
+
+ // Collect the "compatible_printers_condition" and "inherits" values over all presets (sla_materials, printers) into a single vector.
+ std::vector<std::string> compatible_printers_condition;
+ std::vector<std::string> inherits;
+ compatible_printers_condition.emplace_back(this->/*prints*/sla_materials.get_edited_preset().compatible_printers_condition());
+ inherits .emplace_back(this->/*prints*/sla_materials.get_edited_preset().inherits());
+ inherits .emplace_back(this->printers.get_edited_preset().inherits());
+
+ // These two value types clash between the print and filament profiles. They should be renamed.
+ out.erase("compatible_printers");
+ out.erase("compatible_printers_condition");
+ out.erase("inherits");
+
+ out.option<ConfigOptionString >("sla_material_settings_id", true)->value = this->sla_materials.get_selected_preset().name;
+ out.option<ConfigOptionString >("printer_settings_id", true)->value = this->printers.get_selected_preset().name;
+
+ // Serialize the collected "compatible_printers_condition" and "inherits" fields.
+ // There will be 1 + num_exturders fields for "inherits" and 2 + num_extruders for "compatible_printers_condition" stored.
+ // The vector will not be stored if all fields are empty strings.
+ auto add_if_some_non_empty = [&out](std::vector<std::string> &&values, const std::string &key) {
+ bool nonempty = false;
+ for (const std::string &v : values)
+ if (! v.empty()) {
+ nonempty = true;
+ break;
+ }
+ if (nonempty)
+ out.set_key_value(key, new ConfigOptionStrings(std::move(values)));
+ };
+ add_if_some_non_empty(std::move(compatible_printers_condition), "compatible_printers_condition_cummulative");
+ add_if_some_non_empty(std::move(inherits), "inherits_cummulative");
return out;
}
@@ -336,6 +619,8 @@ void PresetBundle::load_config_string(const char* str, const char* source_filena
// Load a config file from a boost property_tree. This is a private method called from load_config_file.
void PresetBundle::load_config_file_config(const std::string &name_or_path, bool is_external, DynamicPrintConfig &&config)
{
+ PrinterTechnology printer_technology = Preset::printer_technology(config);
+
// The "compatible_printers" field should not have been exported into a config.ini or a G-code anyway,
// but some of the alpha versions of Slic3r did.
{
@@ -347,6 +632,23 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
}
}
+ size_t num_extruders = (printer_technology == ptFFF) ?
+ std::min(config.option<ConfigOptionFloats>("nozzle_diameter" )->values.size(),
+ config.option<ConfigOptionFloats>("filament_diameter")->values.size()) :
+ 0;
+ // Make a copy of the "compatible_printers_condition_cummulative" and "inherits_cummulative" vectors, which
+ // accumulate values over all presets (print, filaments, printers).
+ // These values will be distributed into their particular presets when loading.
+ std::vector<std::string> compatible_printers_condition_values = std::move(config.option<ConfigOptionStrings>("compatible_printers_condition_cummulative", true)->values);
+ std::vector<std::string> inherits_values = std::move(config.option<ConfigOptionStrings>("inherits_cummulative", true)->values);
+ std::string &compatible_printers_condition = Preset::compatible_printers_condition(config);
+ std::string &inherits = Preset::inherits(config);
+ compatible_printers_condition_values.resize(num_extruders + 2, std::string());
+ inherits_values.resize(num_extruders + 2, std::string());
+ // The "default_filament_profile" will be later extracted into the printer profile.
+ if (printer_technology == ptFFF)
+ config.option<ConfigOptionStrings>("default_filament_profile", true)->values.resize(num_extruders, std::string());
+
// 1) Create a name from the file name.
// Keep the suffix (.ini, .gcode, .amf, .3mf etc) to differentiate it from the normal profiles.
std::string name = is_external ? boost::filesystem::path(name_or_path).filename().string() : name_or_path;
@@ -354,62 +656,82 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool
// 2) If the loading succeeded, split and load the config into print / filament / printer settings.
// First load the print and printer presets.
for (size_t i_group = 0; i_group < 2; ++ i_group) {
- PresetCollection &presets = (i_group == 0) ? this->prints : this->printers;
- Preset &preset = presets.load_preset(is_external ? name_or_path : presets.path_from_name(name), name, config);
- if (is_external)
- preset.is_external = true;
+ PresetCollection &presets = (i_group == 0) ? ((printer_technology == ptFFF) ? this->prints : this->sla_materials) : this->printers;
+ // Split the "compatible_printers_condition" and "inherits" values one by one from a single vector to the print & printer profiles.
+ size_t idx = (i_group == 0) ? 0 : num_extruders + 1;
+ inherits = inherits_values[idx];
+ compatible_printers_condition = compatible_printers_condition_values[idx];
+ if (is_external)
+ presets.load_external_preset(name_or_path, name,
+ config.opt_string((i_group == 0) ? ((printer_technology == ptFFF) ? "print_settings_id" : "sla_material_id") : "printer_settings_id", true),
+ config);
else
- preset.save();
+ presets.load_preset(presets.path_from_name(name), name, config).save();
}
- // 3) Now load the filaments. If there are multiple filament presets, split them and load them.
- auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("nozzle_diameter"));
- auto *filament_diameter = dynamic_cast<const ConfigOptionFloats*>(config.option("filament_diameter"));
- size_t num_extruders = std::min(nozzle_diameter->values.size(), filament_diameter->values.size());
- if (num_extruders <= 1) {
- Preset &preset = this->filaments.load_preset(
- is_external ? name_or_path : this->filaments.path_from_name(name), name, config);
- if (is_external)
- preset.is_external = true;
- else
- preset.save();
- this->filament_presets.clear();
- this->filament_presets.emplace_back(name);
- } else {
- // Split the filament presets, load each of them separately.
- std::vector<DynamicPrintConfig> configs(num_extruders, this->filaments.default_preset().config);
- // loop through options and scatter them into configs.
- for (const t_config_option_key &key : this->filaments.default_preset().config.keys()) {
- const ConfigOption *other_opt = config.option(key);
- if (other_opt == nullptr)
- continue;
- if (other_opt->is_scalar()) {
- for (size_t i = 0; i < configs.size(); ++ i)
- configs[i].option(key, false)->set(other_opt);
- } else if (key != "compatible_printers") {
- for (size_t i = 0; i < configs.size(); ++ i)
- static_cast<ConfigOptionVectorBase*>(configs[i].option(key, false))->set_at(other_opt, 0, i);
- }
- }
- // Load the configs into this->filaments and make them active.
- this->filament_presets.clear();
- for (size_t i = 0; i < configs.size(); ++ i) {
- char suffix[64];
- if (i == 0)
- suffix[0] = 0;
- else
- sprintf(suffix, " (%d)", i);
- std::string new_name = name + suffix;
- // Load all filament presets, but only select the first one in the preset dialog.
- Preset &preset = this->filaments.load_preset(
- is_external ? name_or_path : this->filaments.path_from_name(new_name),
- new_name, std::move(configs[i]), i == 0);
+ if (Preset::printer_technology(config) == ptFFF) {
+ // 3) Now load the filaments. If there are multiple filament presets, split them and load them.
+ auto old_filament_profile_names = config.option<ConfigOptionStrings>("filament_settings_id", true);
+ old_filament_profile_names->values.resize(num_extruders, std::string());
+
+ if (num_extruders <= 1) {
+ // Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets.
+ inherits = inherits_values[1];
+ compatible_printers_condition = compatible_printers_condition_values[1];
if (is_external)
- preset.is_external = true;
+ this->filaments.load_external_preset(name_or_path, name, old_filament_profile_names->values.front(), config);
else
- preset.save();
- this->filament_presets.emplace_back(new_name);
+ this->filaments.load_preset(this->filaments.path_from_name(name), name, config).save();
+ this->filament_presets.clear();
+ this->filament_presets.emplace_back(name);
+ } else {
+ // Split the filament presets, load each of them separately.
+ std::vector<DynamicPrintConfig> configs(num_extruders, this->filaments.default_preset().config);
+ // loop through options and scatter them into configs.
+ for (const t_config_option_key &key : this->filaments.default_preset().config.keys()) {
+ const ConfigOption *other_opt = config.option(key);
+ if (other_opt == nullptr)
+ continue;
+ if (other_opt->is_scalar()) {
+ for (size_t i = 0; i < configs.size(); ++ i)
+ configs[i].option(key, false)->set(other_opt);
+ } else if (key != "compatible_printers") {
+ for (size_t i = 0; i < configs.size(); ++ i)
+ static_cast<ConfigOptionVectorBase*>(configs[i].option(key, false))->set_at(other_opt, 0, i);
+ }
+ }
+ // Load the configs into this->filaments and make them active.
+ this->filament_presets.clear();
+ for (size_t i = 0; i < configs.size(); ++ i) {
+ DynamicPrintConfig &cfg = configs[i];
+ // Split the "compatible_printers_condition" and "inherits" from the cummulative vectors to separate filament presets.
+ cfg.opt_string("compatible_printers_condition", true) = compatible_printers_condition_values[i + 1];
+ cfg.opt_string("inherits", true) = inherits_values[i + 1];
+ // Load all filament presets, but only select the first one in the preset dialog.
+ Preset *loaded = nullptr;
+ if (is_external)
+ loaded = &this->filaments.load_external_preset(name_or_path, name,
+ (i < old_filament_profile_names->values.size()) ? old_filament_profile_names->values[i] : "",
+ std::move(cfg), i == 0);
+ else {
+ // Used by the config wizard when creating a custom setup.
+ // Therefore this block should only be called for a single extruder.
+ char suffix[64];
+ if (i == 0)
+ suffix[0] = 0;
+ else
+ sprintf(suffix, "%d", i);
+ std::string new_name = name + suffix;
+ loaded = &this->filaments.load_preset(this->filaments.path_from_name(new_name),
+ new_name, std::move(cfg), i == 0);
+ loaded->save();
+ }
+ this->filament_presets.emplace_back(loaded->name);
+ }
}
+
+ // 4) Load the project config values (the per extruder wipe matrix etc).
+ this->project_config.apply_only(config, s_project_options);
}
this->update_compatible_with_printer(false);
@@ -465,9 +787,10 @@ void PresetBundle::load_config_file_config_bundle(const std::string &path, const
collection_dst.load_preset(path, preset_name_dst, std::move(preset_src->config), activate).is_external = true;
return preset_name_dst;
};
- load_one(this->prints, tmp_bundle.prints, tmp_bundle.prints .get_selected_preset().name, true);
- load_one(this->filaments, tmp_bundle.filaments, tmp_bundle.filaments.get_selected_preset().name, true);
- load_one(this->printers, tmp_bundle.printers, tmp_bundle.printers .get_selected_preset().name, true);
+ load_one(this->prints, tmp_bundle.prints, tmp_bundle.prints .get_selected_preset().name, true);
+ load_one(this->filaments, tmp_bundle.filaments, tmp_bundle.filaments .get_selected_preset().name, true);
+ load_one(this->sla_materials, tmp_bundle.sla_materials, tmp_bundle.sla_materials.get_selected_preset().name, true);
+ load_one(this->printers, tmp_bundle.printers, tmp_bundle.printers .get_selected_preset().name, true);
this->update_multi_material_filament_presets();
for (size_t i = 1; i < std::min(tmp_bundle.filament_presets.size(), this->filament_presets.size()); ++ i)
this->filament_presets[i] = load_one(this->filaments, tmp_bundle.filaments, tmp_bundle.filament_presets[i], false);
@@ -591,6 +914,7 @@ static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree)
{
flatten_configbundle_hierarchy(tree, "print");
flatten_configbundle_hierarchy(tree, "filament");
+ flatten_configbundle_hierarchy(tree, "sla_material");
flatten_configbundle_hierarchy(tree, "printer");
}
@@ -598,7 +922,8 @@ static void flatten_configbundle_hierarchy(boost::property_tree::ptree &tree)
// of the local configuration directory.
size_t PresetBundle::load_configbundle(const std::string &path, unsigned int flags)
{
- if (flags & LOAD_CFGBNDLE_RESET_USER_PROFILE)
+ if (flags & (LOAD_CFGBNDLE_RESET_USER_PROFILE | LOAD_CFGBNDLE_SYSTEM))
+ // Reset this bundle, delete user profile files if LOAD_CFGBNDLE_SAVE.
this->reset(flags & LOAD_CFGBNDLE_SAVE);
// 1) Read the complete config file into a boost::property_tree.
@@ -606,15 +931,31 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
pt::ptree tree;
boost::nowide::ifstream ifs(path);
pt::read_ini(ifs, tree);
- // Flatten the config bundle by applying the inheritance rules. Internal profiles (with names starting with '*') are removed.
+
+ const VendorProfile *vendor_profile = nullptr;
+ if (flags & (LOAD_CFGBNDLE_SYSTEM | LOAD_CFGBUNDLE_VENDOR_ONLY)) {
+ auto vp = VendorProfile::from_ini(tree, path);
+ if (vp.num_variants() == 0)
+ return 0;
+ vendor_profile = &(*this->vendors.insert(vp).first);
+ }
+
+ if (flags & LOAD_CFGBUNDLE_VENDOR_ONLY) {
+ return 0;
+ }
+
+ // 1.5) Flatten the config bundle by applying the inheritance rules. Internal profiles (with names starting with '*') are removed.
flatten_configbundle_hierarchy(tree);
// 2) Parse the property_tree, extract the active preset names and the profiles, save them into local config files.
+ // Parse the obsolete preset names, to be deleted when upgrading from the old configuration structure.
std::vector<std::string> loaded_prints;
std::vector<std::string> loaded_filaments;
+ std::vector<std::string> loaded_sla_materials;
std::vector<std::string> loaded_printers;
std::string active_print;
std::vector<std::string> active_filaments;
+ std::string active_sla_material;
std::string active_printer;
size_t presets_loaded = 0;
for (const auto &section : tree) {
@@ -622,15 +963,19 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
std::vector<std::string> *loaded = nullptr;
std::string preset_name;
if (boost::starts_with(section.first, "print:")) {
- presets = &prints;
+ presets = &this->prints;
loaded = &loaded_prints;
preset_name = section.first.substr(6);
} else if (boost::starts_with(section.first, "filament:")) {
- presets = &filaments;
+ presets = &this->filaments;
loaded = &loaded_filaments;
preset_name = section.first.substr(9);
+ } else if (boost::starts_with(section.first, "sla_material:")) {
+ presets = &this->sla_materials;
+ loaded = &loaded_sla_materials;
+ preset_name = section.first.substr(9);
} else if (boost::starts_with(section.first, "printer:")) {
- presets = &printers;
+ presets = &this->printers;
loaded = &loaded_printers;
preset_name = section.first.substr(8);
} else if (section.first == "presets") {
@@ -645,10 +990,28 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
active_filaments.resize(idx + 1, std::string());
active_filaments[idx] = kvp.second.data();
}
+ } else if (kvp.first == "sla_material") {
+ active_sla_material = kvp.second.data();
} else if (kvp.first == "printer") {
active_printer = kvp.second.data();
}
}
+ } else if (section.first == "obsolete_presets") {
+ // Parse the names of obsolete presets. These presets will be deleted from user's
+ // profile directory on installation of this vendor preset.
+ for (auto &kvp : section.second) {
+ std::vector<std::string> *dst = nullptr;
+ if (kvp.first == "print")
+ dst = &this->obsolete_presets.prints;
+ else if (kvp.first == "filament")
+ dst = &this->obsolete_presets.filaments;
+ else if (kvp.first == "sla_material")
+ dst = &this->obsolete_presets.sla_materials;
+ else if (kvp.first == "printer")
+ dst = &this->obsolete_presets.printers;
+ if (dst)
+ unescape_strings_cstyle(kvp.second.data(), *dst);
+ }
} else if (section.first == "settings") {
// Load the settings.
for (auto &kvp : section.second) {
@@ -660,10 +1023,64 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
continue;
if (presets != nullptr) {
// Load the print, filament or printer preset.
- DynamicPrintConfig config(presets->default_preset().config);
+ const DynamicPrintConfig &default_config = presets->default_preset().config;
+ DynamicPrintConfig config(default_config);
for (auto &kvp : section.second)
config.set_deserialize(kvp.first, kvp.second.data());
Preset::normalize(config);
+ // Report configuration fields, which are misplaced into a wrong group.
+ std::string incorrect_keys;
+ size_t n_incorrect_keys = 0;
+ for (const std::string &key : config.keys())
+ if (! default_config.has(key)) {
+ if (incorrect_keys.empty())
+ incorrect_keys = key;
+ else {
+ incorrect_keys += ", ";
+ incorrect_keys += key;
+ }
+ config.erase(key);
+ ++ n_incorrect_keys;
+ }
+ if (! incorrect_keys.empty())
+ BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" <<
+ section.first << "\" contains the following incorrect keys: " << incorrect_keys << ", which were removed";
+ if ((flags & LOAD_CFGBNDLE_SYSTEM) && presets == &printers) {
+ // Filter out printer presets, which are not mentioned in the vendor profile.
+ // These presets are considered not installed.
+ auto printer_model = config.opt_string("printer_model");
+ if (printer_model.empty()) {
+ BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" <<
+ section.first << "\" defines no printer model, it will be ignored.";
+ continue;
+ }
+ auto printer_variant = config.opt_string("printer_variant");
+ if (printer_variant.empty()) {
+ BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" <<
+ section.first << "\" defines no printer variant, it will be ignored.";
+ continue;
+ }
+ auto it_model = std::find_if(vendor_profile->models.cbegin(), vendor_profile->models.cend(),
+ [&](const VendorProfile::PrinterModel &m) { return m.id == printer_model; }
+ );
+ if (it_model == vendor_profile->models.end()) {
+ BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" <<
+ section.first << "\" defines invalid printer model \"" << printer_model << "\", it will be ignored.";
+ continue;
+ }
+ auto it_variant = it_model->variant(printer_variant);
+ if (it_variant == nullptr) {
+ BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" <<
+ section.first << "\" defines invalid printer variant \"" << printer_variant << "\", it will be ignored.";
+ continue;
+ }
+ const Preset *preset_existing = presets->find_preset(section.first, false);
+ if (preset_existing != nullptr) {
+ BOOST_LOG_TRIVIAL(error) << "Error in a Vendor Config Bundle \"" << path << "\": The printer preset \"" <<
+ section.first << "\" has already been loaded from another Confing Bundle.";
+ continue;
+ }
+ }
// Decide a full path to this .ini file.
auto file_name = boost::algorithm::iends_with(preset_name, ".ini") ? preset_name : preset_name + ".ini";
auto file_path = (boost::filesystem::path(data_dir())
@@ -678,29 +1095,39 @@ size_t PresetBundle::load_configbundle(const std::string &path, unsigned int fla
Preset &loaded = presets->load_preset(file_path.string(), preset_name, std::move(config), false);
if (flags & LOAD_CFGBNDLE_SAVE)
loaded.save();
+ if (flags & LOAD_CFGBNDLE_SYSTEM) {
+ loaded.is_system = true;
+ loaded.vendor = vendor_profile;
+ }
++ presets_loaded;
}
}
// 3) Activate the presets.
- if (! active_print.empty())
- prints.select_preset_by_name(active_print, true);
- if (! active_printer.empty())
- printers.select_preset_by_name(active_printer, true);
- // Activate the first filament preset.
- if (! active_filaments.empty() && ! active_filaments.front().empty())
- filaments.select_preset_by_name(active_filaments.front(), true);
-
- this->update_multi_material_filament_presets();
- for (size_t i = 0; i < std::min(this->filament_presets.size(), active_filaments.size()); ++ i)
- this->filament_presets[i] = filaments.find_preset(active_filaments[i], true)->name;
+ if ((flags & LOAD_CFGBNDLE_SYSTEM) == 0) {
+ if (! active_print.empty())
+ prints.select_preset_by_name(active_print, true);
+ if (! active_sla_material.empty())
+ sla_materials.select_preset_by_name(active_sla_material, true);
+ if (! active_printer.empty())
+ printers.select_preset_by_name(active_printer, true);
+ // Activate the first filament preset.
+ if (! active_filaments.empty() && ! active_filaments.front().empty())
+ filaments.select_preset_by_name(active_filaments.front(), true);
+ this->update_multi_material_filament_presets();
+ for (size_t i = 0; i < std::min(this->filament_presets.size(), active_filaments.size()); ++ i)
+ this->filament_presets[i] = filaments.find_preset(active_filaments[i], true)->name;
+ this->update_compatible_with_printer(false);
+ }
- this->update_compatible_with_printer(false);
return presets_loaded;
}
void PresetBundle::update_multi_material_filament_presets()
{
+ if (printers.get_edited_preset().printer_technology() != ptFFF)
+ return;
+
// Verify and select the filament presets.
auto *nozzle_diameter = static_cast<const ConfigOptionFloats*>(printers.get_edited_preset().config.option("nozzle_diameter"));
size_t num_extruders = nozzle_diameter->values.size();
@@ -708,22 +1135,84 @@ void PresetBundle::update_multi_material_filament_presets()
for (size_t i = 0; i < std::min(this->filament_presets.size(), num_extruders); ++ i)
this->filament_presets[i] = this->filaments.find_preset(this->filament_presets[i], true)->name;
// Append the rest of filament presets.
-// if (this->filament_presets.size() < num_extruders)
- this->filament_presets.resize(num_extruders, this->filament_presets.empty() ? this->filaments.first_visible().name : this->filament_presets.back());
+ this->filament_presets.resize(num_extruders, this->filament_presets.empty() ? this->filaments.first_visible().name : this->filament_presets.back());
+
+ // Now verify if wiping_volumes_matrix has proper size (it is used to deduce number of extruders in wipe tower generator):
+ std::vector<double> old_matrix = this->project_config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values;
+ size_t old_number_of_extruders = int(sqrt(old_matrix.size())+EPSILON);
+ if (num_extruders != old_number_of_extruders) {
+ // First verify if purging volumes presets for each extruder matches number of extruders
+ std::vector<double>& extruders = this->project_config.option<ConfigOptionFloats>("wiping_volumes_extruders")->values;
+ while (extruders.size() < 2*num_extruders) {
+ extruders.push_back(extruders.size()>1 ? extruders[0] : 50.); // copy the values from the first extruder
+ extruders.push_back(extruders.size()>1 ? extruders[1] : 50.);
+ }
+ while (extruders.size() > 2*num_extruders) {
+ extruders.pop_back();
+ extruders.pop_back();
+ }
+
+ std::vector<double> new_matrix;
+ for (unsigned int i=0;i<num_extruders;++i)
+ for (unsigned int j=0;j<num_extruders;++j) {
+ // append the value for this pair from the old matrix (if it's there):
+ if (i<old_number_of_extruders && j<old_number_of_extruders)
+ new_matrix.push_back(old_matrix[i*old_number_of_extruders + j]);
+ else
+ new_matrix.push_back( i==j ? 0. : extruders[2*i]+extruders[2*j+1]); // so it matches new extruder volumes
+ }
+ this->project_config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values = new_matrix;
+ }
}
void PresetBundle::update_compatible_with_printer(bool select_other_if_incompatible)
{
- this->prints.update_compatible_with_printer(this->printers.get_edited_preset(), select_other_if_incompatible);
- this->filaments.update_compatible_with_printer(this->printers.get_edited_preset(), select_other_if_incompatible);
- if (select_other_if_incompatible) {
- // Verify validity of the current filament presets.
- for (std::string &filament_name : this->filament_presets) {
- Preset *preset = this->filaments.find_preset(filament_name, false);
- if (preset == nullptr || ! preset->is_compatible)
- filament_name = this->filaments.first_compatible().name;
+ const Preset &printer_preset = this->printers.get_edited_preset();
+
+ switch (printers.get_edited_preset().printer_technology()) {
+ case ptFFF:
+ {
+ const std::string &prefered_print_profile = printer_preset.config.opt_string("default_print_profile");
+ const std::vector<std::string> &prefered_filament_profiles = printer_preset.config.option<ConfigOptionStrings>("default_filament_profile")->values;
+ prefered_print_profile.empty() ?
+ this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
+ this->prints.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
+ [&prefered_print_profile](const std::string& profile_name){ return profile_name == prefered_print_profile; });
+ prefered_filament_profiles.empty() ?
+ this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
+ this->filaments.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
+ [&prefered_filament_profiles](const std::string& profile_name)
+ { return std::find(prefered_filament_profiles.begin(), prefered_filament_profiles.end(), profile_name) != prefered_filament_profiles.end(); });
+ if (select_other_if_incompatible) {
+ // Verify validity of the current filament presets.
+ this->filament_presets.front() = this->filaments.get_edited_preset().name;
+ for (size_t idx = 1; idx < this->filament_presets.size(); ++ idx) {
+ std::string &filament_name = this->filament_presets[idx];
+ Preset *preset = this->filaments.find_preset(filament_name, false);
+ if (preset == nullptr || ! preset->is_compatible) {
+ // Pick a compatible profile. If there are prefered_filament_profiles, use them.
+ if (prefered_filament_profiles.empty())
+ filament_name = this->filaments.first_compatible().name;
+ else {
+ const std::string &preferred = (idx < prefered_filament_profiles.size()) ?
+ prefered_filament_profiles[idx] : prefered_filament_profiles.front();
+ filament_name = this->filaments.first_compatible(
+ [&preferred](const std::string& profile_name){ return profile_name == preferred; }).name;
+ }
+ }
+ }
}
}
+ case ptSLA:
+ {
+ const std::string &prefered_print_profile = printer_preset.config.opt_string("default_print_profile");
+ const std::vector<std::string> &prefered_filament_profiles = printer_preset.config.option<ConfigOptionStrings>("default_filament_profile")->values;
+ prefered_print_profile.empty() ?
+ this->sla_materials.update_compatible_with_printer(printer_preset, select_other_if_incompatible) :
+ this->sla_materials.update_compatible_with_printer(printer_preset, select_other_if_incompatible,
+ [&prefered_print_profile](const std::string& profile_name){ return profile_name == prefered_print_profile; });
+ }
+ }
}
void PresetBundle::export_configbundle(const std::string &path) //, const DynamicPrintConfig &settings
@@ -750,6 +1239,7 @@ void PresetBundle::export_configbundle(const std::string &path) //, const Dynami
// Export the names of the active presets.
c << std::endl << "[presets]" << std::endl;
c << "print = " << this->prints.get_selected_preset().name << std::endl;
+ c << "sla_material = " << this->sla_materials.get_selected_preset().name << std::endl;
c << "printer = " << this->printers.get_selected_preset().name << std::endl;
for (size_t i = 0; i < this->filament_presets.size(); ++ i) {
char suffix[64];
@@ -775,6 +1265,9 @@ void PresetBundle::export_configbundle(const std::string &path) //, const Dynami
// an optional "(modified)" suffix will be removed from the filament name.
void PresetBundle::set_filament_preset(size_t idx, const std::string &name)
{
+ if (name.find_first_of("-------") == 0)
+ return;
+
if (idx >= filament_presets.size())
filament_presets.resize(idx + 1, filaments.default_preset().name);
filament_presets[idx] = Preset::remove_suffix_modified(name);
@@ -788,7 +1281,7 @@ static inline int hex_digit_to_int(const char c)
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
}
-static inline bool parse_color(const std::string &scolor, unsigned char *rgb_out)
+bool PresetBundle::parse_color(const std::string &scolor, unsigned char *rgb_out)
{
rgb_out[0] = rgb_out[1] = rgb_out[2] = 0;
if (scolor.size() != 7 || scolor.front() != '#')
@@ -806,7 +1299,7 @@ static inline bool parse_color(const std::string &scolor, unsigned char *rgb_out
void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitmapComboBox *ui)
{
- if (ui == nullptr)
+ if (ui == nullptr || this->printers.get_edited_preset().printer_technology() == ptSLA)
return;
unsigned char rgb[3];
@@ -818,12 +1311,17 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitma
// Fill in the list from scratch.
ui->Freeze();
ui->Clear();
+ size_t selected_preset_item = 0;
const Preset *selected_preset = this->filaments.find_preset(this->filament_presets[idx_extruder]);
// Show wide icons if the currently selected preset is not compatible with the current printer,
// and draw a red flag in front of the selected preset.
bool wide_icons = selected_preset != nullptr && ! selected_preset->is_compatible && m_bitmapIncompatible != nullptr;
assert(selected_preset != nullptr);
- for (int i = this->filaments().front().is_visible ? 0 : 1; i < int(this->filaments().size()); ++ i) {
+ std::map<wxString, wxBitmap*> nonsys_presets;
+ wxString selected_str = "";
+ if (!this->filaments().front().is_visible)
+ ui->Append("------- " + _(L("System presets")) + " -------", wxNullBitmap);
+ for (int i = this->filaments().front().is_visible ? 0 : 1; i < int(this->filaments().size()); ++i) {
const Preset &preset = this->filaments.preset(i);
bool selected = this->filament_presets[idx_extruder] == preset.name;
if (! preset.is_visible || (! preset.is_compatible && ! selected))
@@ -836,54 +1334,59 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitma
// If the filament preset is not compatible and there is a "red flag" icon loaded, show it left
// to the filament color image.
if (wide_icons)
- bitmap_key += preset.is_compatible ? "comp" : "notcomp";
- auto it = m_mapColorToBitmap.find(bitmap_key);
- wxBitmap *bitmap = (it == m_mapColorToBitmap.end()) ? nullptr : it->second;
+ bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt";
+ bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst";
+ if (preset.is_dirty)
+ bitmap_key += ",drty";
+ wxBitmap *bitmap = m_bitmapCache->find(bitmap_key);
if (bitmap == nullptr) {
// Create the bitmap with color bars.
- bitmap = new wxBitmap((wide_icons ? 16 : 0) + 24, 16);
-#if defined(__APPLE__) || defined(_MSC_VER)
- bitmap->UseAlpha();
-#endif
- wxMemoryDC memDC;
- memDC.SelectObject(*bitmap);
- memDC.SetBackground(*wxTRANSPARENT_BRUSH);
- memDC.Clear();
- if (wide_icons && ! preset.is_compatible)
- // Paint the red flag.
- memDC.DrawBitmap(*m_bitmapIncompatible, 0, 0, true);
+ std::vector<wxBitmap> bmps;
+ if (wide_icons)
+ // Paint a red flag for incompatible presets.
+ bmps.emplace_back(preset.is_compatible ? m_bitmapCache->mkclear(16, 16) : *m_bitmapIncompatible);
// Paint the color bars.
parse_color(filament_rgb, rgb);
- wxImage image(24, 16);
- image.InitAlpha();
- unsigned char* imgdata = image.GetData();
- unsigned char* imgalpha = image.GetAlpha();
- for (size_t i = 0; i < image.GetWidth() * image.GetHeight(); ++ i) {
- *imgdata ++ = rgb[0];
- *imgdata ++ = rgb[1];
- *imgdata ++ = rgb[2];
- *imgalpha ++ = wxALPHA_OPAQUE;
- }
+ bmps.emplace_back(m_bitmapCache->mksolid(single_bar ? 24 : 16, 16, rgb));
if (! single_bar) {
parse_color(extruder_rgb, rgb);
- imgdata = image.GetData();
- for (size_t r = 0; r < 16; ++ r) {
- imgdata = image.GetData() + r * image.GetWidth() * 3;
- for (size_t c = 0; c < 16; ++ c) {
- *imgdata ++ = rgb[0];
- *imgdata ++ = rgb[1];
- *imgdata ++ = rgb[2];
- }
- }
+ bmps.emplace_back(m_bitmapCache->mksolid(8, 16, rgb));
}
- memDC.DrawBitmap(wxBitmap(image), wide_icons ? 16 : 0, 0, true);
- memDC.SelectObject(wxNullBitmap);
- m_mapColorToBitmap[bitmap_key] = bitmap;
+ // Paint a lock at the system presets.
+ bmps.emplace_back(m_bitmapCache->mkclear(2, 16));
+ bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(16, 16));
+// (preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16));
+ bitmap = m_bitmapCache->insert(bitmap_key, bmps);
}
- ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), (bitmap == 0) ? wxNullBitmap : *bitmap);
- if (selected)
- ui->SetSelection(ui->GetCount() - 1);
+
+ if (preset.is_default || preset.is_system){
+ ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()),
+ (bitmap == 0) ? wxNullBitmap : *bitmap);
+ if (selected)
+ selected_preset_item = ui->GetCount() - 1;
+ }
+ else
+ {
+ nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()),
+ (bitmap == 0) ? &wxNullBitmap : bitmap);
+ if (selected)
+ selected_str = wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str());
+ }
+ if (preset.is_default)
+ ui->Append("------- " + _(L("System presets")) + " -------", wxNullBitmap);
}
+
+ if (!nonsys_presets.empty())
+ {
+ ui->Append("------- " + _(L("User presets")) + " -------", wxNullBitmap);
+ for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
+ ui->Append(it->first, *it->second);
+ if (it->first == selected_str)
+ selected_preset_item = ui->GetCount() - 1;
+ }
+ }
+ ui->SetSelection(selected_preset_item);
+ ui->SetToolTip(ui->GetString(selected_preset_item));
ui->Thaw();
}
@@ -891,6 +1394,7 @@ void PresetBundle::set_default_suppressed(bool default_suppressed)
{
prints.set_default_suppressed(default_suppressed);
filaments.set_default_suppressed(default_suppressed);
+ sla_materials.set_default_suppressed(default_suppressed);
printers.set_default_suppressed(default_suppressed);
}
diff --git a/xs/src/slic3r/GUI/PresetBundle.hpp b/xs/src/slic3r/GUI/PresetBundle.hpp
index e6aea206d..68ec534da 100644
--- a/xs/src/slic3r/GUI/PresetBundle.hpp
+++ b/xs/src/slic3r/GUI/PresetBundle.hpp
@@ -4,8 +4,15 @@
#include "AppConfig.hpp"
#include "Preset.hpp"
+#include <set>
+#include <boost/filesystem/path.hpp>
+
namespace Slic3r {
+namespace GUI {
+ class BitmapCache;
+};
+
class PlaceholderParser;
// Bundle of Print + Filament + Printer presets.
@@ -22,11 +29,10 @@ public:
void setup_directories();
// Load ini files of all types (print, filament, printer) from Slic3r::data_dir() / presets.
- void load_presets();
-
// Load selections (current print, current filaments, current printer) from config.ini
// This is done just once on application start up.
- void load_selections(const AppConfig &config);
+ void load_presets(const AppConfig &config);
+
// Export selections (current print, current filaments, current printer) into config.ini
void export_selections(AppConfig &config);
// Export selections (current print, current filaments, current printer) into a placeholder parser.
@@ -34,13 +40,31 @@ public:
PresetCollection prints;
PresetCollection filaments;
+ PresetCollection sla_materials;
PresetCollection printers;
// Filament preset names for a multi-extruder or multi-material print.
// extruders.size() should be the same as printers.get_edited_preset().config.nozzle_diameter.size()
std::vector<std::string> filament_presets;
+ // The project configuration values are kept separated from the print/filament/printer preset,
+ // they are being serialized / deserialized from / to the .amf, .3mf, .config, .gcode,
+ // and they are being used by slicing core.
+ DynamicPrintConfig project_config;
+
+ // There will be an entry for each system profile loaded,
+ // and the system profiles will point to the VendorProfile instances owned by PresetBundle::vendors.
+ std::set<VendorProfile> vendors;
+
+ struct ObsoletePresets {
+ std::vector<std::string> prints;
+ std::vector<std::string> filaments;
+ std::vector<std::string> sla_materials;
+ std::vector<std::string> printers;
+ };
+ ObsoletePresets obsolete_presets;
+
bool has_defauls_only() const
- { return prints.size() <= 1 && filaments.size() <= 1 && printers.size() <= 1; }
+ { return prints.has_defaults_only() && filaments.has_defaults_only() && printers.has_defaults_only(); }
DynamicPrintConfig full_config() const;
@@ -69,7 +93,10 @@ public:
// Save the profiles, which have been loaded.
LOAD_CFGBNDLE_SAVE = 1,
// Delete all old config profiles before loading.
- LOAD_CFGBNDLE_RESET_USER_PROFILE = 2
+ LOAD_CFGBNDLE_RESET_USER_PROFILE = 2,
+ // Load a system config bundle.
+ LOAD_CFGBNDLE_SYSTEM = 4,
+ LOAD_CFGBUNDLE_VENDOR_ONLY = 8,
};
// Load the config bundle, store it to the user profile directory by default.
size_t load_configbundle(const std::string &path, unsigned int flags = LOAD_CFGBNDLE_SAVE);
@@ -98,7 +125,22 @@ public:
// preset if the current print or filament preset is not compatible.
void update_compatible_with_printer(bool select_other_if_incompatible);
+ static bool parse_color(const std::string &scolor, unsigned char *rgb_out);
+
private:
+ std::string load_system_presets();
+ // Merge one vendor's presets with the other vendor's presets, report duplicates.
+ std::vector<std::string> merge_presets(PresetBundle &&other);
+
+ // Set the "enabled" flag for printer vendors, printer models and printer variants
+ // based on the user configuration.
+ // If the "vendor" section is missing, enable all models and variants of the particular vendor.
+ void load_installed_printers(const AppConfig &config);
+
+ // Load selections (current print, current filaments, current printer) from config.ini
+ // This is done just once on application start up.
+ void load_selections(const AppConfig &config);
+
// Load print, filament & printer presets from a config. If it is an external config, then the name is extracted from the external path.
// and the external config is just referenced, not stored into user profile directory.
// If it is not an external config, then the config will be stored into the user profile directory.
@@ -106,12 +148,19 @@ private:
void load_config_file_config_bundle(const std::string &path, const boost::property_tree::ptree &tree);
bool load_compatible_bitmaps();
+ DynamicPrintConfig full_fff_config() const;
+ DynamicPrintConfig full_sla_config() const;
+
// Indicator, that the preset is compatible with the selected printer.
wxBitmap *m_bitmapCompatible;
// Indicator, that the preset is NOT compatible with the selected printer.
wxBitmap *m_bitmapIncompatible;
- // Caching color bitmaps for the
- std::map<std::string, wxBitmap*> m_mapColorToBitmap;
+ // Indicator, that the preset is system and not modified.
+ wxBitmap *m_bitmapLock;
+ // Indicator, that the preset is system and user modified.
+ wxBitmap *m_bitmapLockOpen;
+ // Caching color bitmaps for the filament combo box.
+ GUI::BitmapCache *m_bitmapCache;
};
} // namespace Slic3r
diff --git a/xs/src/slic3r/GUI/ProgressStatusBar.cpp b/xs/src/slic3r/GUI/ProgressStatusBar.cpp
new file mode 100644
index 000000000..224ad8af5
--- /dev/null
+++ b/xs/src/slic3r/GUI/ProgressStatusBar.cpp
@@ -0,0 +1,151 @@
+#include "ProgressStatusBar.hpp"
+
+#include <wx/timer.h>
+#include <wx/gauge.h>
+#include <wx/button.h>
+#include <wx/statusbr.h>
+#include <wx/frame.h>
+#include "GUI.hpp"
+
+#include <iostream>
+
+namespace Slic3r {
+
+ProgressStatusBar::ProgressStatusBar(wxWindow *parent, int id):
+ self(new wxStatusBar(parent ? parent : GUI::get_main_frame(),
+ id == -1? wxID_ANY : id)),
+ timer_(new wxTimer(self)),
+ prog_ (new wxGauge(self,
+ wxGA_HORIZONTAL,
+ 100,
+ wxDefaultPosition,
+ wxDefaultSize)),
+ cancelbutton_(new wxButton(self,
+ -1,
+ "Cancel",
+ wxDefaultPosition,
+ wxDefaultSize))
+{
+ prog_->Hide();
+ cancelbutton_->Hide();
+
+ self->SetFieldsCount(3);
+ int w[] = {-1, 150, 155};
+ self->SetStatusWidths(3, w);
+
+ self->Bind(wxEVT_TIMER, [this](const wxTimerEvent&) {
+ if (prog_->IsShown()) timer_->Stop();
+ if(is_busy()) prog_->Pulse();
+ });
+
+ self->Bind(wxEVT_SIZE, [this](wxSizeEvent& event){
+ wxRect rect;
+ self->GetFieldRect(1, rect);
+ auto offset = 0;
+ cancelbutton_->Move(rect.GetX() + offset, rect.GetY() + offset);
+ cancelbutton_->SetSize(rect.GetWidth() - offset, rect.GetHeight());
+
+ self->GetFieldRect(2, rect);
+ prog_->Move(rect.GetX() + offset, rect.GetY() + offset);
+ prog_->SetSize(rect.GetWidth() - offset, rect.GetHeight());
+
+ event.Skip();
+ });
+
+ cancelbutton_->Bind(wxEVT_BUTTON, [this](const wxCommandEvent&) {
+ if(cancel_cb_) cancel_cb_();
+ cancelbutton_->Hide();
+ });
+}
+
+ProgressStatusBar::~ProgressStatusBar() {
+ if(timer_->IsRunning()) timer_->Stop();
+}
+
+int ProgressStatusBar::get_progress() const
+{
+ return prog_->GetValue();
+}
+
+void ProgressStatusBar::set_progress(int val)
+{
+ if(!prog_->IsShown()) show_progress(true);
+
+ if(val == prog_->GetRange()) {
+ prog_->SetValue(0);
+ show_progress(false);
+ } else {
+ prog_->SetValue(val);
+ }
+}
+
+int ProgressStatusBar::get_range() const
+{
+ return prog_->GetRange();
+}
+
+void ProgressStatusBar::set_range(int val)
+{
+ if(val != prog_->GetRange()) {
+ prog_->SetRange(val);
+ }
+}
+
+void ProgressStatusBar::show_progress(bool show)
+{
+ prog_->Show(show);
+ prog_->Pulse();
+}
+
+void ProgressStatusBar::start_busy(int rate)
+{
+ busy_ = true;
+ show_progress(true);
+ if (!timer_->IsRunning()) {
+ timer_->Start(rate);
+ }
+}
+
+void ProgressStatusBar::stop_busy()
+{
+ timer_->Stop();
+ show_progress(false);
+ prog_->SetValue(0);
+ busy_ = false;
+}
+
+void ProgressStatusBar::set_cancel_callback(ProgressStatusBar::CancelFn ccb) {
+ cancel_cb_ = ccb;
+ if(ccb) cancelbutton_->Show();
+ else cancelbutton_->Hide();
+}
+
+void ProgressStatusBar::run(int rate)
+{
+ if(!timer_->IsRunning()) {
+ timer_->Start(rate);
+ }
+}
+
+void ProgressStatusBar::embed(wxFrame *frame)
+{
+ wxFrame* mf = frame? frame : GUI::get_main_frame();
+ mf->SetStatusBar(self);
+}
+
+void ProgressStatusBar::set_status_text(const std::string& txt)
+{
+ self->SetStatusText(txt);
+}
+
+void ProgressStatusBar::show_cancel_button()
+{
+ cancelbutton_->Show();
+}
+
+void ProgressStatusBar::hide_cancel_button()
+{
+ cancelbutton_->Hide();
+}
+
+}
diff --git a/xs/src/slic3r/GUI/ProgressStatusBar.hpp b/xs/src/slic3r/GUI/ProgressStatusBar.hpp
new file mode 100644
index 000000000..a117cacfb
--- /dev/null
+++ b/xs/src/slic3r/GUI/ProgressStatusBar.hpp
@@ -0,0 +1,64 @@
+#ifndef PROGRESSSTATUSBAR_HPP
+#define PROGRESSSTATUSBAR_HPP
+
+#include <memory>
+#include <functional>
+
+class wxTimer;
+class wxGauge;
+class wxButton;
+class wxTimerEvent;
+class wxStatusBar;
+class wxWindow;
+class wxFrame;
+
+namespace Slic3r {
+
+/**
+ * @brief The ProgressStatusBar class is the widgets occupying the lower area
+ * of the Slicer main window. It consists of a message area to the left and a
+ * progress indication area to the right with an optional cancel button.
+ */
+class ProgressStatusBar {
+ wxStatusBar *self; // we cheat! It should be the base class but: perl!
+ wxTimer *timer_;
+ wxGauge *prog_;
+ wxButton *cancelbutton_;
+public:
+
+ /// Cancel callback function type
+ using CancelFn = std::function<void()>;
+
+ ProgressStatusBar(wxWindow *parent = nullptr, int id = -1);
+ ~ProgressStatusBar();
+
+ int get_progress() const;
+ void set_progress(int);
+ int get_range() const;
+ void set_range(int = 100);
+ void show_progress(bool);
+ void start_busy(int = 100);
+ void stop_busy();
+ inline bool is_busy() const { return busy_; }
+ void set_cancel_callback(CancelFn = CancelFn());
+ inline void remove_cancel_callback() { set_cancel_callback(); }
+ void run(int rate);
+ void embed(wxFrame *frame = nullptr);
+ void set_status_text(const std::string& txt);
+
+ // Temporary methods to satisfy Perl side
+ void show_cancel_button();
+ void hide_cancel_button();
+
+private:
+ bool busy_ = false;
+ CancelFn cancel_cb_;
+};
+
+namespace GUI {
+ using Slic3r::ProgressStatusBar;
+}
+
+}
+
+#endif // PROGRESSSTATUSBAR_HPP
diff --git a/xs/src/slic3r/GUI/RammingChart.cpp b/xs/src/slic3r/GUI/RammingChart.cpp
new file mode 100644
index 000000000..8954ff93b
--- /dev/null
+++ b/xs/src/slic3r/GUI/RammingChart.cpp
@@ -0,0 +1,279 @@
+#include <algorithm>
+#include <wx/dcbuffer.h>
+
+#include "RammingChart.hpp"
+#include "GUI.hpp"
+
+
+wxDEFINE_EVENT(EVT_WIPE_TOWER_CHART_CHANGED, wxCommandEvent);
+
+
+void Chart::draw() {
+ wxAutoBufferedPaintDC dc(this); // unbuffered DC caused flickering on win
+
+ dc.SetBrush(GetBackgroundColour());
+ dc.SetPen(GetBackgroundColour());
+ dc.DrawRectangle(GetClientRect()); // otherwise the background would end up black on windows
+
+ dc.SetPen(*wxBLACK_PEN);
+ dc.SetBrush(*wxWHITE_BRUSH);
+ dc.DrawRectangle(m_rect);
+
+ if (visible_area.m_width < 0.499) {
+ dc.DrawText(_(L("NO RAMMING AT ALL")),wxPoint(m_rect.GetLeft()+m_rect.GetWidth()/2-50,m_rect.GetBottom()-m_rect.GetHeight()/2));
+ return;
+ }
+
+
+ if (!m_line_to_draw.empty()) {
+ for (unsigned int i=0;i<m_line_to_draw.size()-2;++i) {
+ int color = 510*((m_rect.GetBottom()-(m_line_to_draw)[i])/double(m_rect.GetHeight()));
+ dc.SetPen( wxPen( wxColor(std::min(255,color),255-std::max(color-255,0),0), 1 ) );
+ dc.DrawLine(m_rect.GetLeft()+1+i,(m_line_to_draw)[i],m_rect.GetLeft()+1+i,m_rect.GetBottom());
+ }
+ dc.SetPen( wxPen( wxColor(0,0,0), 1 ) );
+ for (unsigned int i=0;i<m_line_to_draw.size()-2;++i) {
+ if (splines)
+ dc.DrawLine(m_rect.GetLeft()+i,(m_line_to_draw)[i],m_rect.GetLeft()+i+1,(m_line_to_draw)[i+1]);
+ else {
+ dc.DrawLine(m_rect.GetLeft()+i,(m_line_to_draw)[i],m_rect.GetLeft()+i+1,(m_line_to_draw)[i]);
+ dc.DrawLine(m_rect.GetLeft()+i+1,(m_line_to_draw)[i],m_rect.GetLeft()+i+1,(m_line_to_draw)[i+1]);
+ }
+ }
+ }
+
+ // draw draggable buttons
+ dc.SetBrush(*wxBLUE_BRUSH);
+ dc.SetPen( wxPen( wxColor(0,0,0), 1 ) );
+ for (auto& button : m_buttons)
+ //dc.DrawRectangle(math_to_screen(button.get_pos())-wxPoint(side/2.,side/2.), wxSize(side,side));
+ dc.DrawCircle(math_to_screen(button.get_pos()),side/2.);
+ //dc.DrawRectangle(math_to_screen(button.get_pos()-wxPoint2DDouble(0.125,0))-wxPoint(0,5),wxSize(50,10));
+
+ // draw x-axis:
+ float last_mark = -10000;
+ for (float math_x=int(visible_area.m_x*10)/10 ; math_x < (visible_area.m_x+visible_area.m_width) ; math_x+=0.1) {
+ int x = math_to_screen(wxPoint2DDouble(math_x,visible_area.m_y)).x;
+ int y = m_rect.GetBottom();
+ if (x-last_mark < 50) continue;
+ dc.DrawLine(x,y+3,x,y-3);
+ dc.DrawText(wxString().Format(wxT("%.1f"), math_x),wxPoint(x-10,y+7));
+ last_mark = x;
+ }
+
+ // draw y-axis:
+ last_mark=10000;
+ for (int math_y=visible_area.m_y ; math_y < (visible_area.m_y+visible_area.m_height) ; math_y+=1) {
+ int y = math_to_screen(wxPoint2DDouble(visible_area.m_x,math_y)).y;
+ int x = m_rect.GetLeft();
+ if (last_mark-y < 50) continue;
+ dc.DrawLine(x-3,y,x+3,y);
+ dc.DrawText(wxString()<<math_y,wxPoint(x-25,y-2/*7*/));
+ last_mark = y;
+ }
+
+ // axis labels:
+ wxString label = _(L("Time")) + " ("+_(L("s"))+")";
+ int text_width = 0;
+ int text_height = 0;
+ dc.GetTextExtent(label,&text_width,&text_height);
+ dc.DrawText(label,wxPoint(0.5*(m_rect.GetRight()+m_rect.GetLeft())-text_width/2.f, m_rect.GetBottom()+25));
+ label = _(L("Volumetric speed")) + " (" + _(L("mm")) + wxString("³/", wxConvUTF8) + _(L("s")) + ")";
+ dc.GetTextExtent(label,&text_width,&text_height);
+ dc.DrawRotatedText(label,wxPoint(0,0.5*(m_rect.GetBottom()+m_rect.GetTop())+text_width/2.f),90);
+}
+
+void Chart::mouse_right_button_clicked(wxMouseEvent& event) {
+ if (!manual_points_manipulation)
+ return;
+ wxPoint point = event.GetPosition();
+ int button_index = which_button_is_clicked(point);
+ if (button_index != -1 && m_buttons.size()>2) {
+ m_buttons.erase(m_buttons.begin()+button_index);
+ recalculate_line();
+ }
+}
+
+
+
+void Chart::mouse_clicked(wxMouseEvent& event) {
+ wxPoint point = event.GetPosition();
+ int button_index = which_button_is_clicked(point);
+ if ( button_index != -1) {
+ m_dragged = &m_buttons[button_index];
+ m_previous_mouse = point;
+ }
+}
+
+
+
+void Chart::mouse_moved(wxMouseEvent& event) {
+ if (!event.Dragging() || !m_dragged) return;
+ wxPoint pos = event.GetPosition();
+ wxRect rect = m_rect;
+ rect.Deflate(side/2.);
+ if (!(rect.Contains(pos))) { // the mouse left chart area
+ mouse_left_window(event);
+ return;
+ }
+ int delta_x = pos.x - m_previous_mouse.x;
+ int delta_y = pos.y - m_previous_mouse.y;
+ m_dragged->move(fixed_x?0:double(delta_x)/m_rect.GetWidth() * visible_area.m_width,-double(delta_y)/m_rect.GetHeight() * visible_area.m_height);
+ m_previous_mouse = pos;
+ recalculate_line();
+}
+
+
+
+void Chart::mouse_double_clicked(wxMouseEvent& event) {
+ if (!manual_points_manipulation)
+ return;
+ wxPoint point = event.GetPosition();
+ if (!m_rect.Contains(point)) // the click is outside the chart
+ return;
+ m_buttons.push_back(screen_to_math(point));
+ std::sort(m_buttons.begin(),m_buttons.end());
+ recalculate_line();
+ return;
+}
+
+
+
+
+void Chart::recalculate_line() {
+ std::vector<wxPoint> points;
+ for (auto& but : m_buttons) {
+ points.push_back(wxPoint(math_to_screen(but.get_pos())));
+ if (points.size()>1 && points.back().x==points[points.size()-2].x) points.pop_back();
+ if (points.size()>1 && points.back().x > m_rect.GetRight()) {
+ points.pop_back();
+ break;
+ }
+ }
+ std::sort(points.begin(),points.end(),[](wxPoint& a,wxPoint& b) { return a.x < b.x; });
+
+ m_line_to_draw.clear();
+ m_total_volume = 0.f;
+
+
+ // Cubic spline interpolation: see https://en.wikiversity.org/wiki/Cubic_Spline_Interpolation#Methods
+ const bool boundary_first_derivative = true; // true - first derivative is 0 at the leftmost and rightmost point
+ // false - second ---- || -------
+ const int N = points.size()-1; // last point can be accessed as N, we have N+1 total points
+ std::vector<float> diag(N+1);
+ std::vector<float> mu(N+1);
+ std::vector<float> lambda(N+1);
+ std::vector<float> h(N+1);
+ std::vector<float> rhs(N+1);
+
+ // let's fill in inner equations
+ for (int i=1;i<=N;++i) h[i] = points[i].x-points[i-1].x;
+ std::fill(diag.begin(),diag.end(),2.f);
+ for (int i=1;i<=N-1;++i) {
+ mu[i] = h[i]/(h[i]+h[i+1]);
+ lambda[i] = 1.f - mu[i];
+ rhs[i] = 6 * ( float(points[i+1].y-points[i].y )/(h[i+1]*(points[i+1].x-points[i-1].x)) -
+ float(points[i].y -points[i-1].y)/(h[i] *(points[i+1].x-points[i-1].x)) );
+ }
+
+ // now fill in the first and last equations, according to boundary conditions:
+ if (boundary_first_derivative) {
+ const float endpoints_derivative = 0;
+ lambda[0] = 1;
+ mu[N] = 1;
+ rhs[0] = (6.f/h[1]) * (float(points[0].y-points[1].y)/(points[0].x-points[1].x) - endpoints_derivative);
+ rhs[N] = (6.f/h[N]) * (endpoints_derivative - float(points[N-1].y-points[N].y)/(points[N-1].x-points[N].x));
+ }
+ else {
+ lambda[0] = 0;
+ mu[N] = 0;
+ rhs[0] = 0;
+ rhs[N] = 0;
+ }
+
+ // the trilinear system is ready to be solved:
+ for (int i=1;i<=N;++i) {
+ float multiple = mu[i]/diag[i-1]; // let's subtract proper multiple of above equation
+ diag[i]-= multiple * lambda[i-1];
+ rhs[i] -= multiple * rhs[i-1];
+ }
+ // now the back substitution (vector mu contains invalid values from now on):
+ rhs[N] = rhs[N]/diag[N];
+ for (int i=N-1;i>=0;--i)
+ rhs[i] = (rhs[i]-lambda[i]*rhs[i+1])/diag[i];
+
+
+
+
+ unsigned int i=1;
+ float y=0.f;
+ for (int x=m_rect.GetLeft(); x<=m_rect.GetRight() ; ++x) {
+ if (splines) {
+ if (i<points.size()-1 && points[i].x < x ) {
+ ++i;
+ }
+ if (points[0].x > x)
+ y = points[0].y;
+ else
+ if (points[N].x < x)
+ y = points[N].y;
+ else
+ y = (rhs[i-1]*pow(points[i].x-x,3)+rhs[i]*pow(x-points[i-1].x,3)) / (6*h[i]) +
+ (points[i-1].y-rhs[i-1]*h[i]*h[i]/6.f) * (points[i].x-x)/h[i] +
+ (points[i].y -rhs[i] *h[i]*h[i]/6.f) * (x-points[i-1].x)/h[i];
+ m_line_to_draw.push_back(y);
+ }
+ else {
+ float x_math = screen_to_math(wxPoint(x,0)).m_x;
+ if (i+2<=points.size() && m_buttons[i+1].get_pos().m_x-0.125 < x_math)
+ ++i;
+ m_line_to_draw.push_back(math_to_screen(wxPoint2DDouble(x_math,m_buttons[i].get_pos().m_y)).y);
+ }
+
+
+ m_line_to_draw.back() = std::max(m_line_to_draw.back(), m_rect.GetTop()-1);
+ m_line_to_draw.back() = std::min(m_line_to_draw.back(), m_rect.GetBottom()-1);
+ m_total_volume += (m_rect.GetBottom() - m_line_to_draw.back()) * (visible_area.m_width / m_rect.GetWidth()) * (visible_area.m_height / m_rect.GetHeight());
+ }
+
+ wxPostEvent(this->GetParent(), wxCommandEvent(EVT_WIPE_TOWER_CHART_CHANGED));
+ Refresh();
+}
+
+
+
+std::vector<float> Chart::get_ramming_speed(float sampling) const {
+ std::vector<float> speeds_out;
+
+ const int number_of_samples = std::round( visible_area.m_width / sampling);
+ if (number_of_samples>0) {
+ const int dx = (m_line_to_draw.size()-1) / number_of_samples;
+ for (int j=0;j<number_of_samples;++j) {
+ float left = screen_to_math(wxPoint(0,m_line_to_draw[j*dx])).m_y;
+ float right = screen_to_math(wxPoint(0,m_line_to_draw[(j+1)*dx])).m_y;
+ speeds_out.push_back((left+right)/2.f);
+ }
+ }
+ return speeds_out;
+}
+
+
+std::vector<std::pair<float,float>> Chart::get_buttons() const {
+ std::vector<std::pair<float, float>> buttons_out;
+ for (const auto& button : m_buttons)
+ buttons_out.push_back(std::make_pair(float(button.get_pos().m_x),float(button.get_pos().m_y)));
+ return buttons_out;
+}
+
+
+
+
+BEGIN_EVENT_TABLE(Chart, wxWindow)
+EVT_MOTION(Chart::mouse_moved)
+EVT_LEFT_DOWN(Chart::mouse_clicked)
+EVT_LEFT_UP(Chart::mouse_released)
+EVT_LEFT_DCLICK(Chart::mouse_double_clicked)
+EVT_RIGHT_DOWN(Chart::mouse_right_button_clicked)
+EVT_LEAVE_WINDOW(Chart::mouse_left_window)
+EVT_PAINT(Chart::paint_event)
+END_EVENT_TABLE()
diff --git a/xs/src/slic3r/GUI/RammingChart.hpp b/xs/src/slic3r/GUI/RammingChart.hpp
new file mode 100644
index 000000000..7d3b9a962
--- /dev/null
+++ b/xs/src/slic3r/GUI/RammingChart.hpp
@@ -0,0 +1,115 @@
+#ifndef RAMMING_CHART_H_
+#define RAMMING_CHART_H_
+
+#include <vector>
+#include <wx/wxprec.h>
+#ifndef WX_PRECOMP
+ #include <wx/wx.h>
+#endif
+
+wxDECLARE_EVENT(EVT_WIPE_TOWER_CHART_CHANGED, wxCommandEvent);
+
+
+class Chart : public wxWindow {
+
+public:
+ Chart(wxWindow* parent, wxRect rect,const std::vector<std::pair<float,float>>& initial_buttons,int ramming_speed_size, float sampling) :
+ wxWindow(parent,wxID_ANY,rect.GetTopLeft(),rect.GetSize())
+ {
+ SetBackgroundStyle(wxBG_STYLE_PAINT);
+ m_rect = wxRect(wxPoint(50,0),rect.GetSize()-wxSize(50,50));
+ visible_area = wxRect2DDouble(0.0, 0.0, sampling*ramming_speed_size, 20.);
+ m_buttons.clear();
+ if (initial_buttons.size()>0)
+ for (const auto& pair : initial_buttons)
+ m_buttons.push_back(wxPoint2DDouble(pair.first,pair.second));
+ recalculate_line();
+ }
+ void set_xy_range(float x,float y) {
+ x = int(x/0.5) * 0.5;
+ if (x>=0) visible_area.SetRight(x);
+ if (y>=0) visible_area.SetBottom(y);
+ recalculate_line();
+ }
+ float get_volume() const { return m_total_volume; }
+ float get_time() const { return visible_area.m_width; }
+
+ std::vector<float> get_ramming_speed(float sampling) const; //returns sampled ramming speed
+ std::vector<std::pair<float,float>> get_buttons() const; // returns buttons position
+
+ void draw();
+
+ void mouse_clicked(wxMouseEvent& event);
+ void mouse_right_button_clicked(wxMouseEvent& event);
+ void mouse_moved(wxMouseEvent& event);
+ void mouse_double_clicked(wxMouseEvent& event);
+ void mouse_left_window(wxMouseEvent&) { m_dragged = nullptr; }
+ void mouse_released(wxMouseEvent&) { m_dragged = nullptr; }
+ void paint_event(wxPaintEvent&) { draw(); }
+ DECLARE_EVENT_TABLE()
+
+
+
+private:
+ static const bool fixed_x = true;
+ static const bool splines = true;
+ static const bool manual_points_manipulation = false;
+ static const int side = 10; // side of draggable button
+
+ class ButtonToDrag {
+ public:
+ bool operator<(const ButtonToDrag& a) const { return m_pos.m_x < a.m_pos.m_x; }
+ ButtonToDrag(wxPoint2DDouble pos) : m_pos{pos} {};
+ wxPoint2DDouble get_pos() const { return m_pos; }
+ void move(double x,double y) { m_pos.m_x+=x; m_pos.m_y+=y; }
+ private:
+ wxPoint2DDouble m_pos; // position in math coordinates
+ };
+
+
+
+ wxPoint math_to_screen(const wxPoint2DDouble& math) const {
+ wxPoint screen;
+ screen.x = (math.m_x-visible_area.m_x) * (m_rect.GetWidth() / visible_area.m_width );
+ screen.y = (math.m_y-visible_area.m_y) * (m_rect.GetHeight() / visible_area.m_height );
+ screen.y *= -1;
+ screen += m_rect.GetLeftBottom();
+ return screen;
+ }
+ wxPoint2DDouble screen_to_math(const wxPoint& screen) const {
+ wxPoint2DDouble math = screen;
+ math -= m_rect.GetLeftBottom();
+ math.m_y *= -1;
+ math.m_x *= visible_area.m_width / m_rect.GetWidth(); // scales to [0;1]x[0,1]
+ math.m_y *= visible_area.m_height / m_rect.GetHeight();
+ return (math+visible_area.GetLeftTop());
+ }
+
+ int which_button_is_clicked(const wxPoint& point) const {
+ if (!m_rect.Contains(point))
+ return -1;
+ for (unsigned int i=0;i<m_buttons.size();++i) {
+ wxRect rect(math_to_screen(m_buttons[i].get_pos())-wxPoint(side/2.,side/2.),wxSize(side,side)); // bounding rectangle of this button
+ if ( rect.Contains(point) )
+ return i;
+ }
+ return (-1);
+ }
+
+
+ void recalculate_line();
+ void recalculate_volume();
+
+
+ wxRect m_rect; // rectangle on screen the chart is mapped into (screen coordinates)
+ wxPoint m_previous_mouse;
+ std::vector<ButtonToDrag> m_buttons;
+ std::vector<int> m_line_to_draw;
+ wxRect2DDouble visible_area;
+ ButtonToDrag* m_dragged = nullptr;
+ float m_total_volume = 0.f;
+
+};
+
+
+#endif // RAMMING_CHART_H_ \ No newline at end of file
diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp
index d0f9f0ce3..5daf2784d 100644
--- a/xs/src/slic3r/GUI/Tab.cpp
+++ b/xs/src/slic3r/GUI/Tab.cpp
@@ -3,9 +3,13 @@
#include "PresetBundle.hpp"
#include "PresetHints.hpp"
#include "../../libslic3r/Utils.hpp"
+
#include "slic3r/Utils/Http.hpp"
-#include "slic3r/Utils/OctoPrint.hpp"
+#include "slic3r/Utils/PrintHost.hpp"
+#include "slic3r/Utils/Serial.hpp"
#include "BonjourDialog.hpp"
+#include "WipeTowerDialog.hpp"
+#include "ButtonsDescription.hpp"
#include <wx/app.h>
#include <wx/button.h>
@@ -20,20 +24,42 @@
#include <wx/filedlg.h>
#include <boost/algorithm/string/predicate.hpp>
+#include "wxExtensions.hpp"
+#include <wx/wupdlock.h>
+
+#include <chrono>
namespace Slic3r {
namespace GUI {
+static wxString dots("…", wxConvUTF8);
+
// sub new
void Tab::create_preset_tab(PresetBundle *preset_bundle)
{
m_preset_bundle = preset_bundle;
// Vertical sizer to hold the choice menu and the rest of the page.
+#ifdef __WXOSX__
+ auto *main_sizer = new wxBoxSizer(wxVERTICAL);
+ main_sizer->SetSizeHints(this);
+ this->SetSizer(main_sizer);
+
+ // Create additional panel to Fit() it from OnActivate()
+ // It's needed for tooltip showing on OSX
+ m_tmp_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
+ auto panel = m_tmp_panel;
+ auto sizer = new wxBoxSizer(wxVERTICAL);
+ m_tmp_panel->SetSizer(sizer);
+ m_tmp_panel->Layout();
+
+ main_sizer->Add(m_tmp_panel, 1, wxEXPAND | wxALL, 0);
+#else
Tab *panel = this;
auto *sizer = new wxBoxSizer(wxVERTICAL);
sizer->SetSizeHints(panel);
panel->SetSizer(sizer);
+#endif //__WXOSX__
// preset chooser
m_presets_choice = new wxBitmapComboBox(panel, wxID_ANY, "", wxDefaultPosition, wxSize(270, -1), 0, 0,wxCB_READONLY);
@@ -50,15 +76,64 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle)
if (wxMSW) m_btn_delete_preset->SetBackgroundColour(color);
m_show_incompatible_presets = false;
- m_bmp_show_incompatible_presets = new wxBitmap(from_u8(Slic3r::var("flag-red-icon.png")), wxBITMAP_TYPE_PNG);
- m_bmp_hide_incompatible_presets = new wxBitmap(from_u8(Slic3r::var("flag-green-icon.png")), wxBITMAP_TYPE_PNG);
- m_btn_hide_incompatible_presets = new wxBitmapButton(panel, wxID_ANY, *m_bmp_hide_incompatible_presets, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
+ m_bmp_show_incompatible_presets.LoadFile(from_u8(Slic3r::var("flag-red-icon.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_hide_incompatible_presets.LoadFile(from_u8(Slic3r::var("flag-green-icon.png")), wxBITMAP_TYPE_PNG);
+ m_btn_hide_incompatible_presets = new wxBitmapButton(panel, wxID_ANY, m_bmp_hide_incompatible_presets, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);
if (wxMSW) m_btn_hide_incompatible_presets->SetBackgroundColour(color);
m_btn_save_preset->SetToolTip(_(L("Save current ")) + m_title);
m_btn_delete_preset->SetToolTip(_(L("Delete this preset")));
m_btn_delete_preset->Disable();
+ m_undo_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
+ m_undo_to_sys_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
+ m_question_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
+ if (wxMSW) {
+ m_undo_btn->SetBackgroundColour(color);
+ m_undo_to_sys_btn->SetBackgroundColour(color);
+ m_question_btn->SetBackgroundColour(color);
+ }
+
+ m_question_btn->SetToolTip(_(L("Hover the cursor over buttons to find more information \n"
+ "or click this button.")));
+
+ // Determine the theme color of OS (dark or light)
+ auto luma = get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+ // Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
+ m_bmp_value_lock .LoadFile(from_u8(var("sys_lock.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_value_unlock .LoadFile(from_u8(var(luma >= 128 ? "sys_unlock.png" : "sys_unlock_grey.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_non_system = &m_bmp_white_bullet;
+ // Bitmaps to be shown on the "Undo user changes" button next to each input field.
+ m_bmp_value_revert .LoadFile(from_u8(var(luma >= 128 ? "action_undo.png" : "action_undo_grey.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_white_bullet .LoadFile(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_question .LoadFile(from_u8(var("question_mark_01.png")), wxBITMAP_TYPE_PNG);
+
+ fill_icon_descriptions();
+ set_tooltips_text();
+
+ m_undo_btn->SetBitmap(m_bmp_white_bullet);
+ m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_roll_back_value(); }));
+ m_undo_to_sys_btn->SetBitmap(m_bmp_white_bullet);
+ m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_roll_back_value(true); }));
+ m_question_btn->SetBitmap(m_bmp_question);
+ m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent)
+ {
+ auto dlg = new ButtonsDescription(this, &m_icon_descriptions);
+ if (dlg->ShowModal() == wxID_OK){
+ // Colors for ui "decoration"
+ for (Tab *tab : get_tabs_list()){
+ tab->m_sys_label_clr = get_label_clr_sys();
+ tab->m_modified_label_clr = get_label_clr_modified();
+ tab->update_labels_colour();
+ }
+ }
+ }));
+
+ // Colors for ui "decoration"
+ m_sys_label_clr = get_label_clr_sys();
+ m_modified_label_clr = get_label_clr_modified();
+ m_default_text_clr = get_label_clr_default();
+
m_hsizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(m_hsizer, 0, wxBOTTOM, 3);
m_hsizer->Add(m_presets_choice, 1, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3);
@@ -68,6 +143,12 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle)
m_hsizer->Add(m_btn_delete_preset, 0, wxALIGN_CENTER_VERTICAL);
m_hsizer->AddSpacer(16);
m_hsizer->Add(m_btn_hide_incompatible_presets, 0, wxALIGN_CENTER_VERTICAL);
+ m_hsizer->AddSpacer(64);
+ m_hsizer->Add(m_undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL);
+ m_hsizer->Add(m_undo_btn, 0, wxALIGN_CENTER_VERTICAL);
+ m_hsizer->AddSpacer(32);
+ m_hsizer->Add(m_question_btn, 0, wxALIGN_CENTER_VERTICAL);
+// m_hsizer->Add(m_cc_presets_choice, 1, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3);
//Horizontal sizer to hold the tree and the selected page.
m_hsizer = new wxBoxSizer(wxHORIZONTAL);
@@ -98,10 +179,18 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle)
//! select_preset(m_presets_choice->GetStringSelection().ToStdString());
//! we doing next:
int selected_item = m_presets_choice->GetSelection();
+ if (m_selected_preset_item == selected_item && !m_presets->current_is_dirty())
+ return;
if (selected_item >= 0){
std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data();
+ if (selected_string.find("-------") == 0
+ /*selected_string == "------- System presets -------" ||
+ selected_string == "------- User presets -------"*/){
+ m_presets_choice->SetSelection(m_selected_preset_item);
+ return;
+ }
+ m_selected_preset_item = selected_item;
select_preset(selected_string);
- update_changed_ui();
}
}));
@@ -117,7 +206,15 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle)
update();
}
-PageShp Tab::add_options_page(wxString title, std::string icon, bool is_extruder_pages/* = false*/)
+void Tab::load_initial_data()
+{
+ m_config = &m_presets->get_edited_preset().config;
+ m_bmp_non_system = m_presets->get_selected_preset_parent() ? &m_bmp_value_unlock : &m_bmp_white_bullet;
+ m_ttg_non_system = m_presets->get_selected_preset_parent() ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns;
+ m_tt_non_system = m_presets->get_selected_preset_parent() ? &m_tt_value_unlock : &m_ttg_white_bullet_ns;
+}
+
+Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages /*= false*/)
{
// Index of icon in an icon list $self->{icons}.
auto icon_idx = 0;
@@ -132,96 +229,355 @@ PageShp Tab::add_options_page(wxString title, std::string icon, bool is_extruder
}
}
// Initialize the page.
- PageShp page(new Page(this, title, icon_idx));
+#ifdef __WXOSX__
+ auto panel = m_tmp_panel;
+#else
+ auto panel = this;
+#endif
+ PageShp page(new Page(panel, title, icon_idx));
page->SetScrollbars(1, 1, 1, 1);
page->Hide();
m_hsizer->Add(page.get(), 1, wxEXPAND | wxLEFT, 5);
- if (!is_extruder_pages)
+
+ if (!is_extruder_pages)
m_pages.push_back(page);
page->set_config(m_config);
return page;
}
-template<class T>
-void add_correct_opts_to_dirty_options(const std::string &opt_key, std::vector<std::string> *vec, TabPrinter *tab)
+void Tab::OnActivate()
{
- auto opt_init = static_cast<T*>(tab->m_presets->get_selected_preset().config.option(opt_key));
- auto opt_cur = static_cast<T*>(tab->m_config->option(opt_key));
- int opt_init_max_id = opt_init->values.size()-1;
- for (int i = 0; i < opt_cur->values.size(); i++)
+#ifdef __WXOSX__
+ wxWindowUpdateLocker noUpdates(this);
+
+ auto size = GetSizer()->GetSize();
+ m_tmp_panel->GetSizer()->SetMinSize(size.x + m_size_move, size.y);
+ Fit();
+ m_size_move *= -1;
+#endif // __WXOSX__
+}
+
+void Tab::update_labels_colour()
+{
+ Freeze();
+ //update options "decoration"
+ for (const auto opt : m_options_list)
{
- int init_id = i <= opt_init_max_id ? i : 0;
- if (opt_cur->values[i] != opt_init->values[init_id])
- vec->emplace_back(opt_key + "#" + std::to_string(i));
+ const wxColour *color = &m_sys_label_clr;
+
+ // value isn't equal to system value
+ if ((opt.second & osSystemValue) == 0){
+ // value is equal to last saved
+ if ((opt.second & osInitValue) != 0)
+ color = &m_default_text_clr;
+ // value is modified
+ else
+ color = &m_modified_label_clr;
+ }
+ if (opt.first == "bed_shape" || opt.first == "compatible_printers") {
+ if (m_colored_Label != nullptr) {
+ m_colored_Label->SetForegroundColour(*color);
+ m_colored_Label->Refresh(true);
+ }
+ continue;
+ }
+
+ Field* field = get_field(opt.first);
+ if (field == nullptr) continue;
+ field->set_label_colour_force(color);
+ }
+ Thaw();
+
+ auto cur_item = m_treectrl->GetFirstVisibleItem();
+ while (cur_item){
+ auto title = m_treectrl->GetItemText(cur_item);
+ for (auto page : m_pages)
+ {
+ if (page->title() != title)
+ continue;
+
+ const wxColor *clr = !page->m_is_nonsys_values ? &m_sys_label_clr :
+ page->m_is_modified_values ? &m_modified_label_clr :
+ &m_default_text_clr;
+
+ m_treectrl->SetItemTextColour(cur_item, *clr);
+ break;
+ }
+ cur_item = m_treectrl->GetNextVisible(cur_item);
}
}
// Update UI according to changes
void Tab::update_changed_ui()
{
- auto dirty_options = m_presets->current_dirty_options();
+ if (m_postpone_update_ui)
+ return;
- if (name() == "printer"){
- // Update dirty_options in case changes of Extruder's options
+ const bool deep_compare = (m_name == "printer" || m_name == "sla_material");
+ auto dirty_options = m_presets->current_dirty_options(deep_compare);
+ auto nonsys_options = m_presets->current_different_from_parent_options(deep_compare);
+ if (name() == "printer"){
TabPrinter* tab = static_cast<TabPrinter*>(this);
- std::vector<std::string> new_dirty;
- for (auto opt_key : dirty_options)
+ if (tab->m_initial_extruders_count != tab->m_extruders_count)
+ dirty_options.emplace_back("extruders_count");
+ if (tab->m_sys_extruders_count != tab->m_extruders_count)
+ nonsys_options.emplace_back("extruders_count");
+ }
+
+ for (auto& it : m_options_list)
+ it.second = m_opt_status_value;
+
+ for (auto opt_key : dirty_options) m_options_list[opt_key] &= ~osInitValue;
+ for (auto opt_key : nonsys_options) m_options_list[opt_key] &= ~osSystemValue;
+
+ Freeze();
+ //update options "decoration"
+ for (const auto opt : m_options_list)
+ {
+ bool is_nonsys_value = false;
+ bool is_modified_value = true;
+ const wxBitmap *sys_icon = &m_bmp_value_lock;
+ const wxBitmap *icon = &m_bmp_value_revert;
+
+ const wxColour *color = &m_sys_label_clr;
+
+ const wxString *sys_tt = &m_tt_value_lock;
+ const wxString *tt = &m_tt_value_revert;
+
+ // value isn't equal to system value
+ if ((opt.second & osSystemValue) == 0){
+ is_nonsys_value = true;
+ sys_icon = m_bmp_non_system;
+ sys_tt = m_tt_non_system;
+ // value is equal to last saved
+ if ((opt.second & osInitValue) != 0)
+ color = &m_default_text_clr;
+ // value is modified
+ else
+ color = &m_modified_label_clr;
+ }
+ if ((opt.second & osInitValue) != 0)
{
- switch (m_config->option(opt_key)->type())
- {
- case coInts: add_correct_opts_to_dirty_options<ConfigOptionInts >(opt_key, &new_dirty, tab); break;
- case coBools: add_correct_opts_to_dirty_options<ConfigOptionBools >(opt_key, &new_dirty, tab); break;
- case coFloats: add_correct_opts_to_dirty_options<ConfigOptionFloats >(opt_key, &new_dirty, tab); break;
- case coStrings: add_correct_opts_to_dirty_options<ConfigOptionStrings >(opt_key, &new_dirty, tab); break;
- case coPercents:add_correct_opts_to_dirty_options<ConfigOptionPercents >(opt_key, &new_dirty, tab); break;
- case coPoints: add_correct_opts_to_dirty_options<ConfigOptionPoints >(opt_key, &new_dirty, tab); break;
- default: new_dirty.emplace_back(opt_key); break;
+ is_modified_value = false;
+ icon = &m_bmp_white_bullet;
+ tt = &m_tt_white_bullet;
+ }
+ if (opt.first == "bed_shape" || opt.first == "compatible_printers") {
+ if (m_colored_Label != nullptr) {
+ m_colored_Label->SetForegroundColour(*color);
+ m_colored_Label->Refresh(true);
}
+ continue;
}
- dirty_options.resize(0);
- dirty_options = new_dirty;
- if (tab->m_initial_extruders_count != tab->m_extruders_count){
- dirty_options.emplace_back("extruders_count");
- }
+ Field* field = get_field(opt.first);
+ if (field == nullptr) continue;
+ field->m_is_nonsys_value = is_nonsys_value;
+ field->m_is_modified_value = is_modified_value;
+ field->set_undo_bitmap(icon);
+ field->set_undo_to_sys_bitmap(sys_icon);
+ field->set_undo_tooltip(tt);
+ field->set_undo_to_sys_tooltip(sys_tt);
+ field->set_label_colour(color);
}
+ Thaw();
- // Add new dirty options to m_dirty_options
- for (auto opt_key : dirty_options){
- Field* field = get_field(opt_key);
- if (field != nullptr && find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) == m_dirty_options.end()){
- if (field->m_Label != nullptr){
- field->m_Label->SetForegroundColour(*get_modified_label_clr());
- field->m_Label->Refresh(true);
- }
- field->m_Undo_btn->SetBitmap(wxBitmap(from_u8(wxMSW ? var("action_undo.png") : var("arrow_undo.png")), wxBITMAP_TYPE_PNG));
- field->m_is_modified_value = true;
+ wxTheApp->CallAfter([this]() {
+ update_changed_tree_ui();
+ });
+}
- m_dirty_options.push_back(opt_key);
+void Tab::init_options_list()
+{
+ if (!m_options_list.empty())
+ m_options_list.clear();
+
+ for (const auto opt_key : m_config->keys())
+ m_options_list.emplace(opt_key, m_opt_status_value);
+}
+
+template<class T>
+void add_correct_opts_to_options_list(const std::string &opt_key, std::map<std::string, int>& map, Tab *tab, const int& value)
+{
+ T *opt_cur = static_cast<T*>(tab->m_config->option(opt_key));
+ for (int i = 0; i < opt_cur->values.size(); i++)
+ map.emplace(opt_key + "#" + std::to_string(i), value);
+}
+
+void TabPrinter::init_options_list()
+{
+ if (!m_options_list.empty())
+ m_options_list.clear();
+
+ for (const auto opt_key : m_config->keys())
+ {
+ if (opt_key == "bed_shape"){
+ m_options_list.emplace(opt_key, m_opt_status_value);
+ continue;
+ }
+ switch (m_config->option(opt_key)->type())
+ {
+ case coInts: add_correct_opts_to_options_list<ConfigOptionInts >(opt_key, m_options_list, this, m_opt_status_value); break;
+ case coBools: add_correct_opts_to_options_list<ConfigOptionBools >(opt_key, m_options_list, this, m_opt_status_value); break;
+ case coFloats: add_correct_opts_to_options_list<ConfigOptionFloats >(opt_key, m_options_list, this, m_opt_status_value); break;
+ case coStrings: add_correct_opts_to_options_list<ConfigOptionStrings >(opt_key, m_options_list, this, m_opt_status_value); break;
+ case coPercents:add_correct_opts_to_options_list<ConfigOptionPercents >(opt_key, m_options_list, this, m_opt_status_value); break;
+ case coPoints: add_correct_opts_to_options_list<ConfigOptionPoints >(opt_key, m_options_list, this, m_opt_status_value); break;
+ default: m_options_list.emplace(opt_key, m_opt_status_value); break;
}
}
+ m_options_list.emplace("extruders_count", m_opt_status_value);
+}
- // Delete clear options from m_dirty_options
- for (auto i = 0; i < m_dirty_options.size(); ++i)
- {
- const std::string &opt_key = m_dirty_options[i];
- Field* field = get_field(opt_key);
- if (field != nullptr && find(dirty_options.begin(), dirty_options.end(), opt_key) == dirty_options.end())
+void TabSLAMaterial::init_options_list()
+{
+ if (!m_options_list.empty())
+ m_options_list.clear();
+
+ for (const auto opt_key : m_config->keys())
+ {
+ if (opt_key == "compatible_printers"){
+ m_options_list.emplace(opt_key, m_opt_status_value);
+ continue;
+ }
+ switch (m_config->option(opt_key)->type())
+ {
+ case coInts: add_correct_opts_to_options_list<ConfigOptionInts >(opt_key, m_options_list, this, m_opt_status_value); break;
+ case coBools: add_correct_opts_to_options_list<ConfigOptionBools >(opt_key, m_options_list, this, m_opt_status_value); break;
+ case coFloats: add_correct_opts_to_options_list<ConfigOptionFloats >(opt_key, m_options_list, this, m_opt_status_value); break;
+ case coStrings: add_correct_opts_to_options_list<ConfigOptionStrings >(opt_key, m_options_list, this, m_opt_status_value); break;
+ case coPercents:add_correct_opts_to_options_list<ConfigOptionPercents >(opt_key, m_options_list, this, m_opt_status_value); break;
+ case coPoints: add_correct_opts_to_options_list<ConfigOptionPoints >(opt_key, m_options_list, this, m_opt_status_value); break;
+ default: m_options_list.emplace(opt_key, m_opt_status_value); break;
+ }
+ }
+}
+
+void Tab::get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page)
+{
+ auto opt = m_options_list.find(opt_key);
+ if (sys_page) sys_page = (opt->second & osSystemValue) != 0;
+ if (!modified_page) modified_page = (opt->second & osInitValue) == 0;
+}
+
+void Tab::update_changed_tree_ui()
+{
+ auto cur_item = m_treectrl->GetFirstVisibleItem();
+ auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection());
+ while (cur_item){
+ auto title = m_treectrl->GetItemText(cur_item);
+ for (auto page : m_pages)
{
- field->m_Undo_btn->SetBitmap(wxBitmap(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG));
- if (field->m_Label != nullptr){
- field->m_Label->SetForegroundColour(wxSYS_COLOUR_WINDOWTEXT);
- field->m_Label->Refresh(true);
+ if (page->title() != title)
+ continue;
+ bool sys_page = true;
+ bool modified_page = false;
+ if (title == _("General")){
+ std::initializer_list<const char*> optional_keys{ "extruders_count", "bed_shape" };
+ for (auto &opt_key : optional_keys) {
+ get_sys_and_mod_flags(opt_key, sys_page, modified_page);
+ }
+ }
+ if (title == _("Dependencies")){
+ if (name() != "printer")
+ get_sys_and_mod_flags("compatible_printers", sys_page, modified_page);
+ else {
+ sys_page = m_presets->get_selected_preset_parent() ? true:false;
+ modified_page = false;
+ }
}
- field->m_is_modified_value = false;
- std::vector<std::string>::iterator itr = find(m_dirty_options.begin(), m_dirty_options.end(), opt_key);
- if (itr != m_dirty_options.end()){
- m_dirty_options.erase(itr);
- --i;
+ for (auto group : page->m_optgroups)
+ {
+ if (!sys_page && modified_page)
+ break;
+ for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) {
+ const std::string& opt_key = it->first;
+ get_sys_and_mod_flags(opt_key, sys_page, modified_page);
+ }
+ }
+
+ const wxColor *clr = sys_page ? &m_sys_label_clr :
+ modified_page ? &m_modified_label_clr :
+ &m_default_text_clr;
+
+ if (page->set_item_colour(clr))
+ m_treectrl->SetItemTextColour(cur_item, *clr);
+
+ page->m_is_nonsys_values = !sys_page;
+ page->m_is_modified_values = modified_page;
+
+ if (selection == title){
+ m_is_nonsys_values = page->m_is_nonsys_values;
+ m_is_modified_values = page->m_is_modified_values;
}
+ break;
}
+ auto next_item = m_treectrl->GetNextVisible(cur_item);
+ cur_item = next_item;
+ }
+ update_undo_buttons();
+}
+
+void Tab::update_undo_buttons()
+{
+ m_undo_btn->SetBitmap(m_is_modified_values ? m_bmp_value_revert : m_bmp_white_bullet);
+ m_undo_to_sys_btn->SetBitmap(m_is_nonsys_values ? *m_bmp_non_system : m_bmp_value_lock);
+
+ m_undo_btn->SetToolTip(m_is_modified_values ? m_ttg_value_revert : m_ttg_white_bullet);
+ m_undo_to_sys_btn->SetToolTip(m_is_nonsys_values ? *m_ttg_non_system : m_ttg_value_lock);
+}
+
+void Tab::on_roll_back_value(const bool to_sys /*= true*/)
+{
+ int os;
+ if (to_sys) {
+ if (!m_is_nonsys_values) return;
+ os = osSystemValue;
}
+ else {
+ if (!m_is_modified_values) return;
+ os = osInitValue;
+ }
+
+ m_postpone_update_ui = true;
+
+ auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection());
+ for (auto page : m_pages)
+ if (page->title() == selection) {
+ for (auto group : page->m_optgroups){
+ if (group->title == _("Capabilities")){
+ if ((m_options_list["extruders_count"] & os) == 0)
+ to_sys ? group->back_to_sys_value("extruders_count") : group->back_to_initial_value("extruders_count");
+ }
+ if (group->title == _("Size and coordinates")){
+ if ((m_options_list["bed_shape"] & os) == 0){
+ to_sys ? group->back_to_sys_value("bed_shape") : group->back_to_initial_value("bed_shape");
+ load_key_value("bed_shape", true/*some value*/, true);
+ }
+
+ }
+ if (group->title == _("Profile dependencies") && name() != "printer"){
+ if ((m_options_list["compatible_printers"] & os) == 0){
+ to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers");
+ load_key_value("compatible_printers", true/*some value*/, true);
+
+ bool is_empty = m_config->option<ConfigOptionStrings>("compatible_printers")->values.empty();
+ m_compatible_printers_checkbox->SetValue(is_empty);
+ is_empty ? m_compatible_printers_btn->Disable() : m_compatible_printers_btn->Enable();
+ }
+ }
+ for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) {
+ const std::string& opt_key = it->first;
+ if ((m_options_list[opt_key] & os) == 0)
+ to_sys ? group->back_to_sys_value(opt_key) : group->back_to_initial_value(opt_key);
+ }
+ }
+ break;
+ }
+
+ m_postpone_update_ui = false;
+ update_changed_ui();
}
// Update the combo box label of the selected preset based on its "dirty" state,
@@ -230,16 +586,19 @@ void Tab::update_dirty(){
m_presets->update_dirty_ui(m_presets_choice);
on_presets_changed();
update_changed_ui();
+// update_dirty_presets(m_cc_presets_choice);
}
void Tab::update_tab_ui()
{
- m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets);
+ m_selected_preset_item = m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets);
+// update_tab_presets(m_cc_presets_choice, m_show_incompatible_presets);
+// update_presetsctrl(m_presetctrl, m_show_incompatible_presets);
}
// Load a provied DynamicConfig into the tab, modifying the active preset.
// This could be used for example by setting a Wipe Tower position by interactive manipulation in the 3D view.
-void Tab::load_config(DynamicPrintConfig config)
+void Tab::load_config(const DynamicPrintConfig& config)
{
bool modified = 0;
for(auto opt_key : m_config->diff(config)) {
@@ -262,7 +621,7 @@ void Tab::reload_config(){
Thaw();
}
-Field* Tab::get_field(t_config_option_key opt_key, int opt_index/* = -1*/) const
+Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const
{
Field* field = nullptr;
for (auto page : m_pages){
@@ -276,7 +635,7 @@ Field* Tab::get_field(t_config_option_key opt_key, int opt_index/* = -1*/) const
// Set a key/value pair on this page. Return true if the value has been modified.
// Currently used for distributing extruders_count over preset pages of Slic3r::GUI::Tab::Printer
// after a preset is loaded.
-bool Tab::set_value(t_config_option_key opt_key, boost::any value){
+bool Tab::set_value(const t_config_option_key& opt_key, const boost::any& value){
bool changed = false;
for(auto page: m_pages) {
if (page->set_value(opt_key, value))
@@ -287,12 +646,15 @@ bool Tab::set_value(t_config_option_key opt_key, boost::any value){
// To be called by custom widgets, load a value into a config,
// update the preset selection boxes (the dirty flags)
-void Tab::load_key_value(std::string opt_key, boost::any value)
+// If value is saved before calling this function, put saved_value = true,
+// and value can be some random value because in this case it will not been used
+void Tab::load_key_value(const std::string& opt_key, const boost::any& value, bool saved_value /*= false*/)
{
- change_opt_value(*m_config, opt_key, value);
+ if (!saved_value) change_opt_value(*m_config, opt_key, value);
// Mark the print & filament enabled if they are compatible with the currently selected preset.
if (opt_key.compare("compatible_printers") == 0) {
- m_preset_bundle->update_compatible_with_printer(0);
+ // Don't select another profile if this profile happens to become incompatible.
+ m_preset_bundle->update_compatible_with_printer(false);
}
m_presets->update_dirty_ui(m_presets_choice);
on_presets_changed();
@@ -301,7 +663,7 @@ void Tab::load_key_value(std::string opt_key, boost::any value)
extern wxFrame *g_wxMainFrame;
-void Tab::on_value_change(std::string opt_key, boost::any value)
+void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
{
if (m_event_value_change > 0) {
wxCommandEvent event(m_event_value_change);
@@ -312,12 +674,21 @@ void Tab::on_value_change(std::string opt_key, boost::any value)
int val = boost::any_cast<size_t>(value);
event.SetInt(val);
}
+
+ if (opt_key == "printer_technology")
+ {
+ int val = boost::any_cast<PrinterTechnology>(value);
+ event.SetInt(val);
+ g_wxMainFrame->ProcessWindowEvent(event);
+ return;
+ }
+
g_wxMainFrame->ProcessWindowEvent(event);
}
if (opt_key == "fill_density")
{
- value = get_optgroup()->get_config_value(*m_config, opt_key);
- get_optgroup()->set_value(opt_key, value);
+ boost::any val = get_optgroup(ogFrequentlyChangingParameters)->get_config_value(*m_config, opt_key);
+ get_optgroup(ogFrequentlyChangingParameters)->set_value(opt_key, val);
}
if (opt_key == "support_material" || opt_key == "support_material_buildplate_only")
{
@@ -326,18 +697,34 @@ void Tab::on_value_change(std::string opt_key, boost::any value)
m_config->opt_bool("support_material_buildplate_only") ?
_("Support on build plate only") :
_("Everywhere");
- get_optgroup()->set_value("support", new_selection);
+ get_optgroup(ogFrequentlyChangingParameters)->set_value("support", new_selection);
}
if (opt_key == "brim_width")
{
bool val = m_config->opt_float("brim_width") > 0.0 ? true : false;
- get_optgroup()->set_value("brim", val);
+ get_optgroup(ogFrequentlyChangingParameters)->set_value("brim", val);
}
-
+ if (opt_key == "wipe_tower" || opt_key == "single_extruder_multi_material" || opt_key == "extruders_count" )
+ update_wiping_button_visibility();
+
update();
}
+// Show/hide the 'purging volumes' button
+void Tab::update_wiping_button_visibility() {
+ if (get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA)
+ return; // ys_FIXME
+ bool wipe_tower_enabled = dynamic_cast<ConfigOptionBool*>( (m_preset_bundle->prints.get_edited_preset().config ).option("wipe_tower"))->value;
+ bool multiple_extruders = dynamic_cast<ConfigOptionFloats*>((m_preset_bundle->printers.get_edited_preset().config).option("nozzle_diameter"))->values.size() > 1;
+ bool single_extruder_mm = dynamic_cast<ConfigOptionBool*>( (m_preset_bundle->printers.get_edited_preset().config).option("single_extruder_multi_material"))->value;
+
+ get_wiping_dialog_button()->Show(wipe_tower_enabled && multiple_extruders && single_extruder_mm);
+
+ (get_wiping_dialog_button()->GetParent())->Layout();
+}
+
+
// Call a callback to update the selection of presets on the platter:
// To update the content of the selection boxes,
// to update the filament colors of the selection boxes,
@@ -350,22 +737,70 @@ void Tab::on_presets_changed()
event.SetString(m_name);
g_wxMainFrame->ProcessWindowEvent(event);
}
+ update_preset_description_line();
+}
+
+void Tab::update_preset_description_line()
+{
+ const Preset* parent = m_presets->get_selected_preset_parent();
+ const Preset& preset = m_presets->get_edited_preset();
+
+ wxString description_line = preset.is_default ?
+ _(L("It's a default preset.")) : preset.is_system ?
+ _(L("It's a system preset.")) :
+ _(L("Current preset is inherited from ")) + (parent == nullptr ?
+ "default preset." :
+ ":\n\t" + parent->name);
+
+ if (preset.is_default || preset.is_system)
+ description_line += "\n\t" + _(L("It can't be deleted or modified. ")) +
+ "\n\t" + _(L("Any modifications should be saved as a new preset inherited from this one. ")) +
+ "\n\t" + _(L("To do that please specify a new name for the preset."));
+
+ if (parent && parent->vendor)
+ {
+ description_line += "\n\n" + _(L("Additional information:")) + "\n";
+ description_line += "\t" + _(L("vendor")) + ": " + (name()=="printer" ? "\n\t\t" : "") + parent->vendor->name +
+ ", ver: " + parent->vendor->config_version.to_string();
+ if (name() == "printer"){
+ const std::string &printer_model = preset.config.opt_string("printer_model");
+ const std::string &default_print_profile = preset.config.opt_string("default_print_profile");
+ const std::vector<std::string> &default_filament_profiles = preset.config.option<ConfigOptionStrings>("default_filament_profile")->values;
+ if (!printer_model.empty())
+ description_line += "\n\n\t" + _(L("printer model")) + ": \n\t\t" + printer_model;
+ if (!default_print_profile.empty())
+ description_line += "\n\n\t" + _(L("default print profile")) + ": \n\t\t" + default_print_profile;
+ if (!default_filament_profiles.empty())
+ {
+ description_line += "\n\n\t" + _(L("default filament profile")) + ": \n\t\t";
+ for (auto& profile : default_filament_profiles){
+ if (&profile != &*default_filament_profiles.begin())
+ description_line += ", ";
+ description_line += profile;
+ }
+ }
+ }
+ }
+
+ m_parent_preset_description_line->SetText(description_line, false);
}
void Tab::update_frequently_changed_parameters()
{
- boost::any value = get_optgroup()->get_config_value(*m_config, "fill_density");
- get_optgroup()->set_value("fill_density", value);
+ boost::any value = get_optgroup(ogFrequentlyChangingParameters)->get_config_value(*m_config, "fill_density");
+ get_optgroup(ogFrequentlyChangingParameters)->set_value("fill_density", value);
wxString new_selection = !m_config->opt_bool("support_material") ?
_("None") :
m_config->opt_bool("support_material_buildplate_only") ?
_("Support on build plate only") :
_("Everywhere");
- get_optgroup()->set_value("support", new_selection);
+ get_optgroup(ogFrequentlyChangingParameters)->set_value("support", new_selection);
bool val = m_config->opt_float("brim_width") > 0.0 ? true : false;
- get_optgroup()->set_value("brim", val);
+ get_optgroup(ogFrequentlyChangingParameters)->set_value("brim", val);
+
+ update_wiping_button_visibility();
}
void Tab::reload_compatible_printers_widget()
@@ -379,7 +814,7 @@ void Tab::reload_compatible_printers_widget()
void TabPrint::build()
{
m_presets = &m_preset_bundle->prints;
- m_config = &m_presets->get_edited_preset().config;
+ load_initial_data();
auto page = add_options_page(_(L("Layers and perimeters")), "layers.png");
auto optgroup = page->new_optgroup(_(L("Layer height")));
@@ -515,13 +950,15 @@ void TabPrint::build()
optgroup->append_single_option_line("wipe_tower_x");
optgroup->append_single_option_line("wipe_tower_y");
optgroup->append_single_option_line("wipe_tower_width");
- optgroup->append_single_option_line("wipe_tower_per_color_wipe");
+ optgroup->append_single_option_line("wipe_tower_rotation_angle");
+ optgroup->append_single_option_line("wipe_tower_bridging");
+ optgroup->append_single_option_line("single_extruder_multi_material_priming");
optgroup = page->new_optgroup(_(L("Advanced")));
optgroup->append_single_option_line("interface_shells");
page = add_options_page(_(L("Advanced")), "wrench.png");
- optgroup = page->new_optgroup(_(L("Extrusion width")), 180);
+ optgroup = page->new_optgroup(_(L("Extrusion width")));
optgroup->append_single_option_line("extrusion_width");
optgroup->append_single_option_line("first_layer_extrusion_width");
optgroup->append_single_option_line("perimeter_extrusion_width");
@@ -581,11 +1018,18 @@ void TabPrint::build()
line.widget = [this](wxWindow* parent){
return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
};
- optgroup->append_line(line);
+ optgroup->append_line(line, &m_colored_Label);
option = optgroup->get_option("compatible_printers_condition");
option.opt.full_width = true;
optgroup->append_single_option_line(option);
+
+ line = Line{ "", "" };
+ line.full_width = 1;
+ line.widget = [this](wxWindow* parent) {
+ return description_line_widget(parent, &m_parent_preset_description_line);
+ };
+ optgroup->append_line(line);
}
// Reload current config (aka presets->edited_preset->config) into the UI fields.
@@ -596,11 +1040,16 @@ void TabPrint::reload_config(){
void TabPrint::update()
{
+ if (get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA)
+ return; // ys_FIXME
+
Freeze();
+ double fill_density = m_config->option<ConfigOptionPercent>("fill_density")->value;
+
if (m_config->opt_bool("spiral_vase") &&
!(m_config->opt_int("perimeters") == 1 && m_config->opt_int("top_solid_layers") == 0 &&
- m_config->option<ConfigOptionPercent>("fill_density")->value == 0)) {
+ fill_density == 0)) {
wxString msg_text = _(L("The Spiral Vase mode requires:\n"
"- one perimeter\n"
"- no top solid layers\n"
@@ -617,34 +1066,13 @@ void TabPrint::update()
new_conf.set_key_value("support_material", new ConfigOptionBool(false));
new_conf.set_key_value("support_material_enforce_layers", new ConfigOptionInt(0));
new_conf.set_key_value("ensure_vertical_shell_thickness", new ConfigOptionBool(false));
+ fill_density = 0;
}
else {
new_conf.set_key_value("spiral_vase", new ConfigOptionBool(false));
}
load_config(new_conf);
- }
-
- auto first_layer_height = m_config->option<ConfigOptionFloatOrPercent>("first_layer_height")->value;
- auto layer_height = m_config->opt_float("layer_height");
- if (m_config->opt_bool("wipe_tower") &&
- (first_layer_height != 0.2 || layer_height < 0.15 || layer_height > 0.35)) {
- wxString msg_text = _(L("The Wipe Tower currently supports only:\n"
- "- first layer height 0.2mm\n"
- "- layer height from 0.15mm to 0.35mm\n"
- "\nShall I adjust those settings in order to enable the Wipe Tower?"));
- auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Wipe Tower")), wxICON_WARNING | wxYES | wxNO);
- DynamicPrintConfig new_conf = *m_config;
- if (dialog->ShowModal() == wxID_YES) {
- const auto &val = *m_config->option<ConfigOptionFloatOrPercent>("first_layer_height");
- auto percent = val.percent;
- new_conf.set_key_value("first_layer_height", new ConfigOptionFloatOrPercent(0.2, percent));
-
- if (m_config->opt_float("layer_height") < 0.15) new_conf.set_key_value("layer_height", new ConfigOptionFloat(0.15));
- if (m_config->opt_float("layer_height") > 0.35) new_conf.set_key_value("layer_height", new ConfigOptionFloat(0.35));
- }
- else
- new_conf.set_key_value("wipe_tower", new ConfigOptionBool(false));
- load_config(new_conf);
+ on_value_change("fill_density", fill_density);
}
if (m_config->opt_bool("wipe_tower") && m_config->opt_bool("support_material") &&
@@ -735,7 +1163,6 @@ void TabPrint::update()
"\nShall I switch to rectilinear fill pattern?"));
auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Infill")), wxICON_WARNING | wxYES | wxNO);
DynamicPrintConfig new_conf = *m_config;
- double fill_density;
if (dialog->ShowModal() == wxID_YES) {
new_conf.set_key_value("fill_pattern", new ConfigOptionEnum<InfillPattern>(ipRectilinear));
fill_density = 100;
@@ -750,53 +1177,40 @@ void TabPrint::update()
}
bool have_perimeters = m_config->opt_int("perimeters") > 0;
- std::vector<std::string> vec_enable = { "extra_perimeters", "ensure_vertical_shell_thickness", "thin_walls", "overhangs",
- "seam_position", "external_perimeters_first", "external_perimeter_extrusion_width",
- "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed" };
- for (auto el : vec_enable)
+ for (auto el : {"extra_perimeters", "ensure_vertical_shell_thickness", "thin_walls", "overhangs",
+ "seam_position", "external_perimeters_first", "external_perimeter_extrusion_width",
+ "perimeter_speed", "small_perimeter_speed", "external_perimeter_speed" })
get_field(el)->toggle(have_perimeters);
bool have_infill = m_config->option<ConfigOptionPercent>("fill_density")->value > 0;
- vec_enable.resize(0);
- vec_enable = { "fill_pattern", "infill_every_layers", "infill_only_where_needed",
- "solid_infill_every_layers", "solid_infill_below_area", "infill_extruder" };
// infill_extruder uses the same logic as in Print::extruders()
- for (auto el : vec_enable)
+ for (auto el : {"fill_pattern", "infill_every_layers", "infill_only_where_needed",
+ "solid_infill_every_layers", "solid_infill_below_area", "infill_extruder" })
get_field(el)->toggle(have_infill);
bool have_solid_infill = m_config->opt_int("top_solid_layers") > 0 || m_config->opt_int("bottom_solid_layers") > 0;
- vec_enable.resize(0);
- vec_enable = { "external_fill_pattern", "infill_first", "solid_infill_extruder",
- "solid_infill_extrusion_width", "solid_infill_speed" };
// solid_infill_extruder uses the same logic as in Print::extruders()
- for (auto el : vec_enable)
+ for (auto el : {"external_fill_pattern", "infill_first", "solid_infill_extruder",
+ "solid_infill_extrusion_width", "solid_infill_speed" })
get_field(el)->toggle(have_solid_infill);
- vec_enable.resize(0);
- vec_enable = { "fill_angle", "bridge_angle", "infill_extrusion_width",
- "infill_speed", "bridge_speed" };
- for (auto el : vec_enable)
+ for (auto el : {"fill_angle", "bridge_angle", "infill_extrusion_width",
+ "infill_speed", "bridge_speed" })
get_field(el)->toggle(have_infill || have_solid_infill);
get_field("gap_fill_speed")->toggle(have_perimeters && have_infill);
bool have_top_solid_infill = m_config->opt_int("top_solid_layers") > 0;
- vec_enable.resize(0);
- vec_enable = { "top_infill_extrusion_width", "top_solid_infill_speed" };
- for (auto el : vec_enable)
+ for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" })
get_field(el)->toggle(have_top_solid_infill);
bool have_default_acceleration = m_config->opt_float("default_acceleration") > 0;
- vec_enable.resize(0);
- vec_enable = { "perimeter_acceleration", "infill_acceleration",
- "bridge_acceleration", "first_layer_acceleration" };
- for (auto el : vec_enable)
+ for (auto el : {"perimeter_acceleration", "infill_acceleration",
+ "bridge_acceleration", "first_layer_acceleration" })
get_field(el)->toggle(have_default_acceleration);
bool have_skirt = m_config->opt_int("skirts") > 0 || m_config->opt_float("min_skirt_length") > 0;
- vec_enable.resize(0);
- vec_enable = { "skirt_distance", "skirt_height" };
- for (auto el : vec_enable)
+ for (auto el : { "skirt_distance", "skirt_height" })
get_field(el)->toggle(have_skirt);
bool have_brim = m_config->opt_float("brim_width") > 0;
@@ -807,18 +1221,14 @@ void TabPrint::update()
bool have_support_material = m_config->opt_bool("support_material") || have_raft;
bool have_support_interface = m_config->opt_int("support_material_interface_layers") > 0;
bool have_support_soluble = have_support_material && m_config->opt_float("support_material_contact_distance") == 0;
- vec_enable.resize(0);
- vec_enable = { "support_material_threshold", "support_material_pattern", "support_material_with_sheath",
+ for (auto el : {"support_material_threshold", "support_material_pattern", "support_material_with_sheath",
"support_material_spacing", "support_material_angle", "support_material_interface_layers",
"dont_support_bridges", "support_material_extrusion_width", "support_material_contact_distance",
- "support_material_xy_spacing" };
- for (auto el : vec_enable)
+ "support_material_xy_spacing" })
get_field(el)->toggle(have_support_material);
- vec_enable.resize(0);
- vec_enable = { "support_material_interface_spacing", "support_material_interface_extruder",
- "support_material_interface_speed", "support_material_interface_contact_loops" };
- for (auto el : vec_enable)
+ for (auto el : {"support_material_interface_spacing", "support_material_interface_extruder",
+ "support_material_interface_speed", "support_material_interface_contact_loops" })
get_field(el)->toggle(have_support_material && have_support_interface);
get_field("support_material_synchronize_layers")->toggle(have_support_soluble);
@@ -827,18 +1237,14 @@ void TabPrint::update()
get_field("support_material_speed")->toggle(have_support_material || have_brim || have_skirt);
bool have_sequential_printing = m_config->opt_bool("complete_objects");
- vec_enable.resize(0);
- vec_enable = { "extruder_clearance_radius", "extruder_clearance_height" };
- for (auto el : vec_enable)
+ for (auto el : { "extruder_clearance_radius", "extruder_clearance_height" })
get_field(el)->toggle(have_sequential_printing);
bool have_ooze_prevention = m_config->opt_bool("ooze_prevention");
get_field("standby_temperature_delta")->toggle(have_ooze_prevention);
bool have_wipe_tower = m_config->opt_bool("wipe_tower");
- vec_enable.resize(0);
- vec_enable = { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_per_color_wipe" };
- for (auto el : vec_enable)
+ for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging"})
get_field(el)->toggle(have_wipe_tower);
m_recommended_thin_wall_thickness_description_line->SetText(
@@ -851,12 +1257,13 @@ void TabPrint::OnActivate()
{
m_recommended_thin_wall_thickness_description_line->SetText(
from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle)));
+ Tab::OnActivate();
}
void TabFilament::build()
{
m_presets = &m_preset_bundle->filaments;
- m_config = &m_preset_bundle->filaments.get_edited_preset().config;
+ load_initial_data();
auto page = add_options_page(_(L("Filament")), "spool.png");
auto optgroup = page->new_optgroup(_(L("Filament")));
@@ -866,7 +1273,7 @@ void TabFilament::build()
optgroup->append_single_option_line("filament_density");
optgroup->append_single_option_line("filament_cost");
- optgroup = page->new_optgroup(_(L("Temperature ")) +" (\u00B0C)"); // degree sign
+ optgroup = page->new_optgroup(_(L("Temperature ")) + wxString("°C", wxConvUTF8));
Line line = { _(L("Extruder")), "" };
line.append_option(optgroup->get_option("first_layer_temperature"));
line.append_option(optgroup->get_option("temperature"));
@@ -918,7 +1325,37 @@ void TabFilament::build()
};
optgroup->append_line(line);
- page = add_options_page(_(L("Custom G-code")), "cog.png");
+ optgroup = page->new_optgroup(_(L("Toolchange parameters with single extruder MM printers")));
+ optgroup->append_single_option_line("filament_loading_speed_start");
+ optgroup->append_single_option_line("filament_loading_speed");
+ optgroup->append_single_option_line("filament_unloading_speed_start");
+ optgroup->append_single_option_line("filament_unloading_speed");
+ optgroup->append_single_option_line("filament_load_time");
+ optgroup->append_single_option_line("filament_unload_time");
+ optgroup->append_single_option_line("filament_toolchange_delay");
+ optgroup->append_single_option_line("filament_cooling_moves");
+ optgroup->append_single_option_line("filament_cooling_initial_speed");
+ optgroup->append_single_option_line("filament_cooling_final_speed");
+ optgroup->append_single_option_line("filament_minimal_purge_on_wipe_tower");
+
+ line = { _(L("Ramming")), "" };
+ line.widget = [this](wxWindow* parent){
+ auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
+ auto sizer = new wxBoxSizer(wxHORIZONTAL);
+ sizer->Add(ramming_dialog_btn);
+
+ ramming_dialog_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent& e)
+ {
+ RammingDialog dlg(this,(m_config->option<ConfigOptionStrings>("filament_ramming_parameters"))->get_at(0));
+ if (dlg.ShowModal() == wxID_OK)
+ (m_config->option<ConfigOptionStrings>("filament_ramming_parameters"))->get_at(0) = dlg.get_parameters();
+ }));
+ return sizer;
+ };
+ optgroup->append_line(line);
+
+
+ page = add_options_page(_(L("Custom G-code")), "cog.png");
optgroup = page->new_optgroup(_(L("Start G-code")), 0);
Option option = optgroup->get_option("start_filament_gcode");
option.opt.full_width = true;
@@ -945,11 +1382,18 @@ void TabFilament::build()
line.widget = [this](wxWindow* parent){
return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
};
- optgroup->append_line(line);
+ optgroup->append_line(line, &m_colored_Label);
option = optgroup->get_option("compatible_printers_condition");
option.opt.full_width = true;
optgroup->append_single_option_line(option);
+
+ line = Line{ "", "" };
+ line.full_width = 1;
+ line.widget = [this](wxWindow* parent) {
+ return description_line_widget(parent, &m_parent_preset_description_line);
+ };
+ optgroup->append_line(line);
}
// Reload current config (aka presets->edited_preset->config) into the UI fields.
@@ -960,6 +1404,10 @@ void TabFilament::reload_config(){
void TabFilament::update()
{
+ if (get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptSLA)
+ return; // ys_FIXME
+
+ Freeze();
wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset()));
m_cooling_description_line->SetText(text);
text = from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle));
@@ -968,19 +1416,18 @@ void TabFilament::update()
bool cooling = m_config->opt_bool("cooling", 0);
bool fan_always_on = cooling || m_config->opt_bool("fan_always_on", 0);
- std::vector<std::string> vec_enable = { "max_fan_speed", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed" };
- for (auto el : vec_enable)
+ for (auto el : { "max_fan_speed", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed" })
get_field(el)->toggle(cooling);
- vec_enable.resize(0);
- vec_enable = { "min_fan_speed", "disable_fan_first_layers" };
- for (auto el : vec_enable)
+ for (auto el : { "min_fan_speed", "disable_fan_first_layers" })
get_field(el)->toggle(fan_always_on);
+ Thaw();
}
void TabFilament::OnActivate()
{
m_volumetric_speed_description_line->SetText(from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle)));
+ Tab::OnActivate();
}
wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticText)
@@ -991,7 +1438,7 @@ wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticTex
(*StaticText)->SetFont(font);
auto sizer = new wxBoxSizer(wxHORIZONTAL);
- sizer->Add(*StaticText);
+ sizer->Add(*StaticText, 1, wxEXPAND|wxALL, 0);
return sizer;
}
@@ -1003,19 +1450,35 @@ bool Tab::current_preset_is_dirty()
void TabPrinter::build()
{
m_presets = &m_preset_bundle->printers;
- m_config = &m_preset_bundle->printers.get_edited_preset().config;
- auto default_config = m_preset_bundle->full_config();
+ load_initial_data();
+
+ m_printer_technology = m_presets->get_selected_preset().printer_technology();
+
+ m_presets->get_selected_preset().printer_technology() == ptSLA ? build_sla() : build_fff();
+
+// on_value_change("printer_technology", m_printer_technology); // to update show/hide preset ComboBoxes
+}
+
+void TabPrinter::build_fff()
+{
+ if (!m_pages.empty())
+ m_pages.resize(0);
+ // to avoid redundant memory allocation / deallocation during extruders count changing
+ m_pages.reserve(30);
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter"));
m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size();
+ const Preset* parent_preset = m_presets->get_selected_preset_parent();
+ m_sys_extruders_count = parent_preset == nullptr ? 0 :
+ static_cast<const ConfigOptionFloats*>(parent_preset->config.option("nozzle_diameter"))->values.size();
auto page = add_options_page(_(L("General")), "printer_empty.png");
auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
Line line{ _(L("Bed shape")), "" };
line.widget = [this](wxWindow* parent){
- auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+"\u2026", wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
- // btn->SetFont(Slic3r::GUI::small_font);
+ auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
+ btn->SetFont(Slic3r::GUI::small_font());
btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG));
auto sizer = new wxBoxSizer(wxHORIZONTAL);
@@ -1025,13 +1488,15 @@ void TabPrinter::build()
{
auto dlg = new BedShapeDialog(this);
dlg->build_dialog(m_config->option<ConfigOptionPoints>("bed_shape"));
- if (dlg->ShowModal() == wxID_OK)
+ if (dlg->ShowModal() == wxID_OK){
load_key_value("bed_shape", dlg->GetValue());
+ update_changed_ui();
+ }
}));
return sizer;
};
- optgroup->append_line(line);
+ optgroup->append_line(line, &m_colored_Label);
optgroup->append_single_option_line("max_print_height");
optgroup->append_single_option_line("z_offset");
@@ -1049,9 +1514,11 @@ void TabPrinter::build()
optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value){
size_t extruders_count = boost::any_cast<int>(optgroup->get_value("extruders_count"));
wxTheApp->CallAfter([this, opt_key, value, extruders_count](){
- if (opt_key.compare("extruders_count")==0) {
+ if (opt_key.compare("extruders_count")==0 || opt_key.compare("single_extruder_multi_material")==0) {
extruders_count_changed(extruders_count);
update_dirty();
+ if (opt_key.compare("single_extruder_multi_material")==0) // the single_extruder_multimaterial was added to force pages
+ on_value_change(opt_key, value); // rebuild - let's make sure the on_value_change is not skipped
}
else {
update_dirty();
@@ -1060,6 +1527,7 @@ void TabPrinter::build()
});
};
+
if (!m_no_controller)
{
optgroup = page->new_optgroup(_(L("USB/Serial connection")));
@@ -1078,13 +1546,13 @@ void TabPrinter::build()
auto serial_test = [this](wxWindow* parent){
auto btn = m_serial_test_btn = new wxButton(parent, wxID_ANY,
_(L("Test")), wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
-// btn->SetFont($Slic3r::GUI::small_font);
+ btn->SetFont(Slic3r::GUI::small_font());
btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("wrench.png")), wxBITMAP_TYPE_PNG));
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn);
btn->Bind(wxEVT_BUTTON, [this, parent](wxCommandEvent e){
- auto sender = new GCodeSender();
+ auto sender = Slic3r::make_unique<GCodeSender>();
auto res = sender->connect(
m_config->opt_string("serial_port"),
m_config->opt_int("serial_speed")
@@ -1105,10 +1573,12 @@ void TabPrinter::build()
optgroup->append_line(line);
}
- optgroup = page->new_optgroup(_(L("OctoPrint upload")));
+ optgroup = page->new_optgroup(_(L("Printer Host upload")));
+
+ optgroup->append_single_option_line("host_type");
- auto octoprint_host_browse = [this, optgroup] (wxWindow* parent) {
- auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+"\u2026", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
+ auto printhost_browse = [this, optgroup] (wxWindow* parent) {
+ auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("zoom.png")), wxBITMAP_TYPE_PNG));
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn);
@@ -1116,48 +1586,51 @@ void TabPrinter::build()
btn->Bind(wxEVT_BUTTON, [this, parent, optgroup](wxCommandEvent e) {
BonjourDialog dialog(parent);
if (dialog.show_and_lookup()) {
- optgroup->set_value("octoprint_host", std::move(dialog.get_selected()), true);
+ optgroup->set_value("print_host", std::move(dialog.get_selected()), true);
}
});
return sizer;
};
- auto octoprint_host_test = [this](wxWindow* parent) {
- auto btn = m_octoprint_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")),
+ auto print_host_test = [this](wxWindow* parent) {
+ auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")),
wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("wrench.png")), wxBITMAP_TYPE_PNG));
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn);
btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent e) {
- OctoPrint octoprint(m_config);
+ std::unique_ptr<PrintHost> host(PrintHost::get_print_host(m_config));
+ if (! host) {
+ const auto text = wxString::Format("%s",
+ _(L("Could not get a valid Printer Host reference")));
+ show_error(this, text);
+ return;
+ }
wxString msg;
- if (octoprint.test(msg)) {
- show_info(this, _(L("Connection to OctoPrint works correctly.")), _(L("Success!")));
+ if (host->test(msg)) {
+ show_info(this, host->get_test_ok_msg(), _(L("Success!")));
} else {
- const auto text = wxString::Format("%s: %s\n\n%s",
- _(L("Could not connect to OctoPrint")), msg, _(L("Note: OctoPrint version at least 1.1.0 is required."))
- );
- show_error(this, text);
+ show_error(this, host->get_test_failed_msg(msg));
}
});
return sizer;
};
- Line host_line = optgroup->create_single_option_line("octoprint_host");
- host_line.append_widget(octoprint_host_browse);
- host_line.append_widget(octoprint_host_test);
+ Line host_line = optgroup->create_single_option_line("print_host");
+ host_line.append_widget(printhost_browse);
+ host_line.append_widget(print_host_test);
optgroup->append_line(host_line);
- optgroup->append_single_option_line("octoprint_apikey");
+ optgroup->append_single_option_line("printhost_apikey");
if (Http::ca_file_supported()) {
- Line cafile_line = optgroup->create_single_option_line("octoprint_cafile");
+ Line cafile_line = optgroup->create_single_option_line("printhost_cafile");
- auto octoprint_cafile_browse = [this, optgroup] (wxWindow* parent) {
- auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+"\u2026", wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
+ auto printhost_cafile_browse = [this, optgroup] (wxWindow* parent) {
+ auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT);
btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("zoom.png")), wxBITMAP_TYPE_PNG));
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(btn);
@@ -1166,17 +1639,17 @@ void TabPrinter::build()
static const auto filemasks = _(L("Certificate files (*.crt, *.pem)|*.crt;*.pem|All files|*.*"));
wxFileDialog openFileDialog(this, _(L("Open CA certificate file")), "", "", filemasks, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (openFileDialog.ShowModal() != wxID_CANCEL) {
- optgroup->set_value("octoprint_cafile", std::move(openFileDialog.GetPath()), true);
+ optgroup->set_value("printhost_cafile", std::move(openFileDialog.GetPath()), true);
}
});
return sizer;
};
- cafile_line.append_widget(octoprint_cafile_browse);
+ cafile_line.append_widget(printhost_cafile_browse);
optgroup->append_line(cafile_line);
- auto octoprint_cafile_hint = [this, optgroup] (wxWindow* parent) {
+ auto printhost_cafile_hint = [this, optgroup] (wxWindow* parent) {
auto txt = new wxStaticText(parent, wxID_ANY,
_(L("HTTPS CA file is optional. It is only needed if you use HTTPS with a self-signed certificate.")));
auto sizer = new wxBoxSizer(wxHORIZONTAL);
@@ -1186,13 +1659,30 @@ void TabPrinter::build()
Line cafile_hint { "", "" };
cafile_hint.full_width = 1;
- cafile_hint.widget = std::move(octoprint_cafile_hint);
+ cafile_hint.widget = std::move(printhost_cafile_hint);
optgroup->append_line(cafile_hint);
}
optgroup = page->new_optgroup(_(L("Firmware")));
optgroup->append_single_option_line("gcode_flavor");
+ optgroup->append_single_option_line("silent_mode");
+ optgroup->append_single_option_line("remaining_times");
+
+ optgroup->m_on_change = [this, optgroup](t_config_option_key opt_key, boost::any value){
+ wxTheApp->CallAfter([this, opt_key, value](){
+ if (opt_key.compare("silent_mode") == 0) {
+ bool val = boost::any_cast<bool>(value);
+ if (m_use_silent_mode != val) {
+ m_rebuild_kinematics_page = true;
+ m_use_silent_mode = val;
+ }
+ }
+ build_extruder_pages();
+ update_dirty();
+ on_value_change(opt_key, value);
+ });
+ };
optgroup = page->new_optgroup(_(L("Advanced")));
optgroup->append_single_option_line("use_relative_e_distances");
@@ -1244,16 +1734,95 @@ void TabPrinter::build()
option.opt.height = 250;
optgroup->append_single_option_line(option);
+ page = add_options_page(_(L("Dependencies")), "wrench.png");
+ optgroup = page->new_optgroup(_(L("Profile dependencies")));
+ line = Line{ "", "" };
+ line.full_width = 1;
+ line.widget = [this](wxWindow* parent) {
+ return description_line_widget(parent, &m_parent_preset_description_line);
+ };
+ optgroup->append_line(line);
+
build_extruder_pages();
if (!m_no_controller)
update_serial_ports();
}
+void TabPrinter::build_sla()
+{
+ if (!m_pages.empty())
+ m_pages.resize(0);
+ auto page = add_options_page(_(L("General")), "printer_empty.png");
+ auto optgroup = page->new_optgroup(_(L("Size and coordinates")));
+
+ Line line{ _(L("Bed shape")), "" };
+ line.widget = [this](wxWindow* parent){
+ auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
+ // btn->SetFont(Slic3r::GUI::small_font);
+ btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG));
+
+ auto sizer = new wxBoxSizer(wxHORIZONTAL);
+ sizer->Add(btn);
+
+ btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent e)
+ {
+ auto dlg = new BedShapeDialog(this);
+ dlg->build_dialog(m_config->option<ConfigOptionPoints>("bed_shape"));
+ if (dlg->ShowModal() == wxID_OK){
+ load_key_value("bed_shape", dlg->GetValue());
+ update_changed_ui();
+ }
+ }));
+
+ return sizer;
+ };
+ optgroup->append_line(line, &m_colored_Label);
+ optgroup->append_single_option_line("max_print_height");
+
+ optgroup = page->new_optgroup(_(L("Display")));
+ optgroup->append_single_option_line("display_width");
+ optgroup->append_single_option_line("display_height");
+
+ auto option = optgroup->get_option("display_pixels_x");
+ line = { _(option.opt.full_label), "" };
+ line.append_option(option);
+ line.append_option(optgroup->get_option("display_pixels_y"));
+ optgroup->append_line(line);
+
+ optgroup = page->new_optgroup(_(L("Corrections")));
+ line = Line{ m_config->def()->get("printer_correction")->full_label, "" };
+ std::vector<std::string> axes{ "X", "Y", "Z" };
+ int id = 0;
+ for (auto& axis : axes) {
+ auto opt = optgroup->get_option("printer_correction", id);
+ opt.opt.label = axis;
+ line.append_option(opt);
+ ++id;
+ }
+ optgroup->append_line(line);
+
+ page = add_options_page(_(L("Notes")), "note.png");
+ optgroup = page->new_optgroup(_(L("Notes")), 0);
+ option = optgroup->get_option("printer_notes");
+ option.opt.full_width = true;
+ option.opt.height = 250;
+ optgroup->append_single_option_line(option);
+
+ page = add_options_page(_(L("Dependencies")), "wrench.png");
+ optgroup = page->new_optgroup(_(L("Profile dependencies")));
+ line = Line{ "", "" };
+ line.full_width = 1;
+ line.widget = [this](wxWindow* parent) {
+ return description_line_widget(parent, &m_parent_preset_description_line);
+ };
+ optgroup->append_line(line);
+}
+
void TabPrinter::update_serial_ports(){
Field *field = get_field("serial_port");
Choice *choice = static_cast<Choice *>(field);
- choice->set_values(scan_serial_ports());
+ choice->set_values(Utils::scan_serial_ports());
}
void TabPrinter::extruders_count_changed(size_t extruders_count){
@@ -1263,15 +1832,129 @@ void TabPrinter::extruders_count_changed(size_t extruders_count){
build_extruder_pages();
reload_config();
on_value_change("extruders_count", extruders_count);
+ update_objects_list_extruder_column(extruders_count);
+}
+
+void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key)
+{
+ auto option = optgroup->get_option(opt_key, 0);
+ auto line = Line{ option.opt.full_label, "" };
+ line.append_option(option);
+ if (m_use_silent_mode)
+ line.append_option(optgroup->get_option(opt_key, 1));
+ optgroup->append_line(line);
}
-void TabPrinter::build_extruder_pages(){
- for (auto extruder_idx = m_extruder_pages.size(); extruder_idx < m_extruders_count; ++extruder_idx){
+PageShp TabPrinter::build_kinematics_page()
+{
+ auto page = add_options_page(_(L("Machine limits")), "cog.png", true);
+
+ if (m_use_silent_mode) {
+ // Legend for OptionsGroups
+ auto optgroup = page->new_optgroup(_(L("")));
+ optgroup->set_show_modified_btns_val(false);
+ optgroup->label_width = 230;
+ auto line = Line{ "", "" };
+
+ ConfigOptionDef def;
+ def.type = coString;
+ def.width = 150;
+ def.gui_type = "legend";
+ def.tooltip = L("Values in this column are for Full Power mode");
+ def.default_value = new ConfigOptionString{ L("Full Power") };
+
+ auto option = Option(def, "full_power_legend");
+ line.append_option(option);
+
+ def.tooltip = L("Values in this column are for Silent mode");
+ def.default_value = new ConfigOptionString{ L("Silent") };
+ option = Option(def, "silent_legend");
+ line.append_option(option);
+
+ optgroup->append_line(line);
+ }
+
+ std::vector<std::string> axes{ "x", "y", "z", "e" };
+ auto optgroup = page->new_optgroup(_(L("Maximum feedrates")));
+ for (const std::string &axis : axes) {
+ append_option_line(optgroup, "machine_max_feedrate_" + axis);
+ }
+
+ optgroup = page->new_optgroup(_(L("Maximum accelerations")));
+ for (const std::string &axis : axes) {
+ append_option_line(optgroup, "machine_max_acceleration_" + axis);
+ }
+ append_option_line(optgroup, "machine_max_acceleration_extruding");
+ append_option_line(optgroup, "machine_max_acceleration_retracting");
+
+ optgroup = page->new_optgroup(_(L("Jerk limits")));
+ for (const std::string &axis : axes) {
+ append_option_line(optgroup, "machine_max_jerk_" + axis);
+ }
+
+ optgroup = page->new_optgroup(_(L("Minimum feedrates")));
+ append_option_line(optgroup, "machine_min_extruding_rate");
+ append_option_line(optgroup, "machine_min_travel_rate");
+
+ return page;
+}
+
+
+void TabPrinter::build_extruder_pages()
+{
+ size_t n_before_extruders = 2; // Count of pages before Extruder pages
+ bool is_marlin_flavor = m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value == gcfMarlin;
+
+ // Add/delete Kinematics page according to is_marlin_flavor
+ size_t existed_page = 0;
+ for (int i = n_before_extruders; i < m_pages.size(); ++i) // first make sure it's not there already
+ if (m_pages[i]->title().find(_(L("Machine limits"))) != std::string::npos) {
+ if (!is_marlin_flavor || m_rebuild_kinematics_page)
+ m_pages.erase(m_pages.begin() + i);
+ else
+ existed_page = i;
+ break;
+ }
+
+ if (existed_page < n_before_extruders && is_marlin_flavor){
+ auto page = build_kinematics_page();
+ m_pages.insert(m_pages.begin() + n_before_extruders, page);
+ }
+
+ if (is_marlin_flavor)
+ n_before_extruders++;
+ size_t n_after_single_extruder_MM = 2; // Count of pages after single_extruder_multi_material page
+
+ if (m_extruders_count_old == m_extruders_count ||
+ (m_has_single_extruder_MM_page && m_extruders_count == 1))
+ {
+ // if we have a single extruder MM setup, add a page with configuration options:
+ for (int i = 0; i < m_pages.size(); ++i) // first make sure it's not there already
+ if (m_pages[i]->title().find(_(L("Single extruder MM setup"))) != std::string::npos) {
+ m_pages.erase(m_pages.begin() + i);
+ break;
+ }
+ m_has_single_extruder_MM_page = false;
+ }
+ if (m_extruders_count > 1 && m_config->opt_bool("single_extruder_multi_material") && !m_has_single_extruder_MM_page) {
+ // create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves
+ auto page = add_options_page(_(L("Single extruder MM setup")), "printer_empty.png", true);
+ auto optgroup = page->new_optgroup(_(L("Single extruder multimaterial parameters")));
+ optgroup->append_single_option_line("cooling_tube_retraction");
+ optgroup->append_single_option_line("cooling_tube_length");
+ optgroup->append_single_option_line("parking_pos_retraction");
+ optgroup->append_single_option_line("extra_loading_move");
+ m_pages.insert(m_pages.end() - n_after_single_extruder_MM, page);
+ m_has_single_extruder_MM_page = true;
+ }
+
+
+ for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx){
//# build page
char buf[MIN_BUF_LENGTH_FOR_L];
sprintf(buf, _CHB(L("Extruder %d")), extruder_idx + 1);
auto page = add_options_page(from_u8(buf), "funnel.png", true);
- m_extruder_pages.push_back(page);
+ m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page);
auto optgroup = page->new_optgroup(_(L("Size")));
optgroup->append_single_option_line("nozzle_diameter", extruder_idx);
@@ -1309,18 +1992,11 @@ void TabPrinter::build_extruder_pages(){
}
// # remove extra pages
- if (m_extruders_count <= m_extruder_pages.size()) {
- m_extruder_pages.resize(m_extruders_count);
- }
+ if (m_extruders_count < m_extruders_count_old)
+ m_pages.erase( m_pages.begin() + n_before_extruders + m_extruders_count,
+ m_pages.begin() + n_before_extruders + m_extruders_count_old);
- // # rebuild page list
- PageShp page_note = m_pages.back();
- m_pages.pop_back();
- while (m_pages.back()->title().find(_(L("Extruder"))) != std::string::npos)
- m_pages.pop_back();
- for (auto page_extruder : m_extruder_pages)
- m_pages.push_back(page_extruder);
- m_pages.push_back(page_note);
+ m_extruders_count_old = m_extruders_count;
rebuild_page_tree();
}
@@ -1335,7 +2011,38 @@ void TabPrinter::on_preset_loaded()
extruders_count_changed(extruders_count);
}
-void TabPrinter::update(){
+void TabPrinter::update_pages()
+{
+ // update m_pages ONLY if printer technology is changed
+ if (m_presets->get_edited_preset().printer_technology() == m_printer_technology)
+ return;
+
+ // hide all old pages
+ for (auto& el : m_pages)
+ el.get()->Hide();
+
+ // set m_pages to m_pages_(technology before changing)
+ m_printer_technology == ptFFF ? m_pages.swap(m_pages_fff) : m_pages.swap(m_pages_sla);
+
+ // build Tab according to the technology, if it's not exist jet OR
+ // set m_pages_(technology after changing) to m_pages
+ if (m_presets->get_edited_preset().printer_technology() == ptFFF)
+ m_pages_fff.empty() ? build_fff() : m_pages.swap(m_pages_fff);
+ else
+ m_pages_sla.empty() ? build_sla() : m_pages.swap(m_pages_sla);
+
+ rebuild_page_tree(true);
+
+ on_value_change("printer_technology", m_presets->get_edited_preset().printer_technology()); // to update show/hide preset ComboBoxes
+}
+
+void TabPrinter::update()
+{
+ m_presets->get_edited_preset().printer_technology() == ptFFF ? update_fff() : update_sla();
+}
+
+void TabPrinter::update_fff()
+{
Freeze();
bool en;
@@ -1349,12 +2056,34 @@ void TabPrinter::update(){
m_serial_test_btn->Disable();
}
- m_octoprint_host_test_btn->Enable(!m_config->opt_string("octoprint_host").empty());
-
+ {
+ std::unique_ptr<PrintHost> host(PrintHost::get_print_host(m_config));
+ m_print_host_test_btn->Enable(!m_config->opt_string("print_host").empty() && host->can_test());
+ m_printhost_browse_btn->Enable(host->has_auto_discovery());
+ }
+
bool have_multiple_extruders = m_extruders_count > 1;
get_field("toolchange_gcode")->toggle(have_multiple_extruders);
get_field("single_extruder_multi_material")->toggle(have_multiple_extruders);
+ bool is_marlin_flavor = m_config->option<ConfigOptionEnum<GCodeFlavor>>("gcode_flavor")->value == gcfMarlin;
+
+ {
+ Field *sm = get_field("silent_mode");
+ if (! is_marlin_flavor)
+ // Disable silent mode for non-marlin firmwares.
+ get_field("silent_mode")->toggle(false);
+ if (is_marlin_flavor)
+ sm->enable();
+ else
+ sm->disable();
+ }
+
+ if (m_use_silent_mode != m_config->opt_bool("silent_mode")) {
+ m_rebuild_kinematics_page = true;
+ m_use_silent_mode = m_config->opt_bool("silent_mode");
+ }
+
for (size_t i = 0; i < m_extruders_count; ++i) {
bool have_retract_length = m_config->opt_float("retract_length", i) > 0;
@@ -1416,16 +2145,27 @@ void TabPrinter::update(){
Thaw();
}
+void TabPrinter::update_sla(){ ; }
+
// Initialize the UI from the current preset
void Tab::load_current_preset()
{
auto preset = m_presets->get_edited_preset();
- preset.is_default ? m_btn_delete_preset->Disable() : m_btn_delete_preset->Enable(true);
- update();
- // For the printer profile, generate the extruder pages.
- on_preset_loaded();
- // Reload preset pages with the new configuration values.
- reload_config();
+
+ (preset.is_default || preset.is_system) ? m_btn_delete_preset->Disable() : m_btn_delete_preset->Enable(true);
+
+ update();
+ // For the printer profile, generate the extruder pages.
+ if (preset.printer_technology() == ptFFF)
+ on_preset_loaded();
+ // Reload preset pages with the new configuration values.
+ reload_config();
+
+ m_bmp_non_system = m_presets->get_selected_preset_parent() ? &m_bmp_value_unlock : &m_bmp_white_bullet;
+ m_ttg_non_system = m_presets->get_selected_preset_parent() ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns;
+ m_tt_non_system = m_presets->get_selected_preset_parent() ? &m_tt_value_unlock : &m_ttg_white_bullet_ns;
+
+ m_undo_to_sys_btn->Enable(!preset.is_default);
// use CallAfter because some field triggers schedule on_change calls using CallAfter,
// and we don't want them to be called after this update_dirty() as they would mark the
@@ -1436,36 +2176,66 @@ void Tab::load_current_preset()
if (!checked_tab(this))
return;
update_tab_ui();
+
+ // update show/hide tabs
+ if (m_name == "printer"){
+ PrinterTechnology& printer_technology = m_presets->get_edited_preset().printer_technology();
+ if (printer_technology != static_cast<TabPrinter*>(this)->m_printer_technology)
+ {
+ for (auto& tab : get_preset_tabs()){
+ if (tab.technology != printer_technology)
+ {
+ int page_id = get_tab_panel()->FindPage(tab.panel);
+ get_tab_panel()->GetPage(page_id)->Show(false);
+ get_tab_panel()->RemovePage(page_id);
+ }
+ else
+ get_tab_panel()->InsertPage(get_tab_panel()->FindPage(this), tab.panel, tab.panel->title());
+ }
+
+ static_cast<TabPrinter*>(this)->m_printer_technology = printer_technology;
+ }
+ }
+
on_presets_changed();
if (name() == "print")
update_frequently_changed_parameters();
- if (m_name == "printer")
+ if (m_name == "printer"){
static_cast<TabPrinter*>(this)->m_initial_extruders_count = static_cast<TabPrinter*>(this)->m_extruders_count;
+ const Preset* parent_preset = m_presets->get_selected_preset_parent();
+ static_cast<TabPrinter*>(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 :
+ static_cast<const ConfigOptionFloats*>(parent_preset->config.option("nozzle_diameter"))->values.size();
+ }
+ m_opt_status_value = (m_presets->get_selected_preset_parent() ? osSystemValue : 0) | osInitValue;
+ init_options_list();
update_changed_ui();
});
}
//Regerenerate content of the page tree.
-void Tab::rebuild_page_tree()
+void Tab::rebuild_page_tree(bool tree_sel_change_event /*= false*/)
{
Freeze();
// get label of the currently selected item
auto selected = m_treectrl->GetItemText(m_treectrl->GetSelection());
auto rootItem = m_treectrl->GetRootItem();
- m_treectrl->DeleteChildren(rootItem);
+
auto have_selection = 0;
+ m_treectrl->DeleteChildren(rootItem);
for (auto p : m_pages)
{
auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID());
+ m_treectrl->SetItemTextColour(itemId, p->get_item_colour());
if (p->title() == selected) {
- m_disable_tree_sel_changed_event = 1;
+ if (!(p->title() == _(L("Machine limits")) || p->title() == _(L("Single extruder MM setup")))) // These Pages have to be updated inside OnTreeSelChange
+ m_disable_tree_sel_changed_event = !tree_sel_change_event;
m_treectrl->SelectItem(itemId);
- m_disable_tree_sel_changed_event = 0;
+ m_disable_tree_sel_changed_event = false;
have_selection = 1;
}
}
-
+
if (!have_selection) {
// this is triggered on first load, so we don't disable the sel change event
m_treectrl->SelectItem(m_treectrl->GetFirstVisibleItem());//! (treectrl->GetFirstChild(rootItem));
@@ -1478,46 +2248,51 @@ void Tab::rebuild_page_tree()
// If the current profile is modified, user is asked to save the changes.
void Tab::select_preset(std::string preset_name /*= ""*/)
{
- std::string name = preset_name;
- auto force = false;
- auto presets = m_presets;
// If no name is provided, select the "-- default --" preset.
- if (name.empty())
- name= presets->default_preset().name;
- auto current_dirty = presets->current_is_dirty();
- auto canceled = false;
- auto printer_tab = presets->name().compare("printer")==0;
+ if (preset_name.empty())
+ preset_name = m_presets->default_preset().name;
+ auto current_dirty = m_presets->current_is_dirty();
+ auto printer_tab = m_presets->name() == "printer";
+ auto canceled = false;
m_reload_dependent_tabs = {};
- if (!force && current_dirty && !may_discard_current_dirty_preset()) {
+ if (current_dirty && !may_discard_current_dirty_preset()) {
canceled = true;
- } else if(printer_tab) {
+ } else if (printer_tab) {
// Before switching the printer to a new one, verify, whether the currently active print and filament
// are compatible with the new printer.
// If they are not compatible and the current print or filament are dirty, let user decide
// whether to discard the changes or keep the current printer selection.
- auto new_printer_preset = presets->find_preset(name, true);
- auto print_presets = &m_preset_bundle->prints;
- bool print_preset_dirty = print_presets->current_is_dirty();
- bool print_preset_compatible = print_presets->get_edited_preset().is_compatible_with_printer(*new_printer_preset);
- canceled = !force && print_preset_dirty && !print_preset_compatible &&
- !may_discard_current_dirty_preset(print_presets, name);
- auto filament_presets = &m_preset_bundle->filaments;
- bool filament_preset_dirty = filament_presets->current_is_dirty();
- bool filament_preset_compatible = filament_presets->get_edited_preset().is_compatible_with_printer(*new_printer_preset);
- if (!canceled && !force) {
- canceled = filament_preset_dirty && !filament_preset_compatible &&
- !may_discard_current_dirty_preset(filament_presets, name);
+ //
+ // With the introduction of the SLA printer types, we need to support switching between
+ // the FFF and SLA printers.
+ const Preset &new_printer_preset = *m_presets->find_preset(preset_name, true);
+ PrinterTechnology old_printer_technology = m_presets->get_edited_preset().printer_technology();
+ PrinterTechnology new_printer_technology = new_printer_preset.printer_technology();
+ struct PresetUpdate {
+ std::string name;
+ PresetCollection *presets;
+ PrinterTechnology technology;
+ bool old_preset_dirty;
+ bool new_preset_compatible;
+ };
+ std::vector<PresetUpdate> updates = {
+ { "print", &m_preset_bundle->prints, ptFFF },
+ { "filament", &m_preset_bundle->filaments, ptFFF },
+ { "sla_material", &m_preset_bundle->sla_materials, ptSLA }
+ };
+ for (PresetUpdate &pu : updates) {
+ pu.old_preset_dirty = (old_printer_technology == pu.technology) && pu.presets->current_is_dirty();
+ pu.new_preset_compatible = (new_printer_technology == pu.technology) && pu.presets->get_edited_preset().is_compatible_with_printer(new_printer_preset);
+ if (! canceled)
+ canceled = pu.old_preset_dirty && ! pu.new_preset_compatible && ! may_discard_current_dirty_preset(pu.presets, preset_name);
}
- if (!canceled) {
- if (!print_preset_compatible) {
- // The preset will be switched to a different, compatible preset, or the '-- default --'.
- m_reload_dependent_tabs.push_back("print");
- if (print_preset_dirty) print_presets->discard_current_changes();
- }
- if (!filament_preset_compatible) {
+ if (! canceled) {
+ for (PresetUpdate &pu : updates) {
// The preset will be switched to a different, compatible preset, or the '-- default --'.
- m_reload_dependent_tabs.push_back("filament");
- if (filament_preset_dirty) filament_presets->discard_current_changes();
+ if (pu.technology == new_printer_technology)
+ m_reload_dependent_tabs.emplace_back(pu.name);
+ if (pu.old_preset_dirty)
+ pu.presets->discard_current_changes();
}
}
}
@@ -1526,24 +2301,25 @@ void Tab::select_preset(std::string preset_name /*= ""*/)
// Trigger the on_presets_changed event so that we also restore the previous value in the plater selector,
// if this action was initiated from the platter.
on_presets_changed();
- }
- else {
- if (current_dirty) presets->discard_current_changes() ;
- presets->select_preset_by_name(name, force);
+ } else {
+ if (current_dirty)
+ m_presets->discard_current_changes() ;
+ m_presets->select_preset_by_name(preset_name, false);
// Mark the print & filament enabled if they are compatible with the currently selected preset.
// The following method should not discard changes of current print or filament presets on change of a printer profile,
// if they are compatible with the current printer.
if (current_dirty || printer_tab)
m_preset_bundle->update_compatible_with_printer(true);
// Initialize the UI from the current preset.
+ if (printer_tab)
+ static_cast<TabPrinter*>(this)->update_pages();
load_current_preset();
}
-
}
// If the current preset is dirty, the user is asked whether the changes may be discarded.
// if the current preset was not dirty, or the user agreed to discard the changes, 1 is returned.
-bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr*/, std::string new_printer_name /*= ""*/)
+bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr*/, const std::string& new_printer_name /*= ""*/)
{
if (presets == nullptr) presets = m_presets;
// Display a dialog showing the dirty options in a human readable form.
@@ -1581,21 +2357,40 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr
void Tab::OnTreeSelChange(wxTreeEvent& event)
{
if (m_disable_tree_sel_changed_event) return;
+
+// There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/Slic3r/issues/898 and https://github.com/prusa3d/Slic3r/issues/952.
+// The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason,
+// we will Thaw the UI prematurely on Linux. This means destroing the no_updates object prematurely.
+#ifdef __linux__
+ std::unique_ptr<wxWindowUpdateLocker> no_updates(new wxWindowUpdateLocker(this));
+#else
+ wxWindowUpdateLocker noUpdates(this);
+#endif
+
Page* page = nullptr;
auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection());
for (auto p : m_pages)
if (p->title() == selection)
{
page = p.get();
+ m_is_nonsys_values = page->m_is_nonsys_values;
+ m_is_modified_values = page->m_is_modified_values;
break;
}
if (page == nullptr) return;
for (auto& el : m_pages)
el.get()->Hide();
+
+#ifdef __linux__
+ no_updates.reset(nullptr);
+#endif
+
page->Show();
m_hsizer->Layout();
Refresh();
+
+ update_undo_buttons();
}
void Tab::OnKeyDown(wxKeyEvent& event)
@@ -1631,7 +2426,7 @@ void Tab::save_preset(std::string name /*= ""*/)
std::vector<std::string> values;
for (size_t i = 0; i < m_presets->size(); ++i) {
const Preset &preset = m_presets->preset(i);
- if (preset.is_default || preset.is_external)
+ if (preset.is_default || preset.is_system || preset.is_external)
continue;
values.push_back(preset.name);
}
@@ -1645,6 +2440,15 @@ void Tab::save_preset(std::string name /*= ""*/)
show_error(this, _(L("The supplied name is empty. It can't be saved.")));
return;
}
+ const Preset *existing = m_presets->find_preset(name, false);
+ if (existing && (existing->is_default || existing->is_system)) {
+ show_error(this, _(L("Cannot overwrite a system profile.")));
+ return;
+ }
+ if (existing && (existing->is_external)) {
+ show_error(this, _(L("Cannot overwrite an external profile.")));
+ return;
+ }
}
// Save the preset into Slic3r::data_dir / presets / section_name / preset_name.ini
@@ -1655,6 +2459,12 @@ void Tab::save_preset(std::string name /*= ""*/)
update_tab_ui();
// Update the selection boxes at the platter.
on_presets_changed();
+ // If current profile is saved, "delete preset" button have to be enabled
+ m_btn_delete_preset->Enable(true);
+
+ if (m_name == "printer")
+ static_cast<TabPrinter*>(this)->m_initial_extruders_count = static_cast<TabPrinter*>(this)->m_extruders_count;
+ update_changed_ui();
}
// Called for a currently selected preset.
@@ -1690,7 +2500,7 @@ void Tab::toggle_show_hide_incompatible()
void Tab::update_show_hide_incompatible_button()
{
m_btn_hide_incompatible_presets->SetBitmap(m_show_incompatible_presets ?
- *m_bmp_show_incompatible_presets : *m_bmp_hide_incompatible_presets);
+ m_bmp_show_incompatible_presets : m_bmp_hide_incompatible_presets);
m_btn_hide_incompatible_presets->SetToolTip(m_show_incompatible_presets ?
"Both compatible an incompatible presets are shown. Click to hide presets not compatible with the current printer." :
"Only compatible presets are shown. Click to show both the presets compatible and not compatible with the current printer.");
@@ -1719,7 +2529,7 @@ void Tab::update_ui_from_settings()
wxSizer* Tab::compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox, wxButton** btn)
{
*checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All")));
- *btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+"\u2026", wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
+ *btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT);
(*btn)->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG));
@@ -1734,6 +2544,7 @@ wxSizer* Tab::compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox
if ((*checkbox)->GetValue())
load_key_value("compatible_printers", std::vector<std::string> {});
get_field("compatible_printers_condition")->toggle((*checkbox)->GetValue());
+ update_changed_ui();
}) );
(*btn)->Bind(wxEVT_BUTTON, ([this, parent, checkbox, btn](wxCommandEvent e)
@@ -1744,13 +2555,13 @@ wxSizer* Tab::compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox
for (size_t idx = 0; idx < printers->size(); ++idx)
{
Preset& preset = printers->preset(idx);
- if (!preset.is_default && !preset.is_external)
+ if (!preset.is_default && !preset.is_external && !preset.is_system)
presets.Add(preset.name);
}
- auto dlg = new wxMultiChoiceDialog(parent,
- _(L("Select the printers this profile is compatible with.")),
- _(L("Compatible printers")), presets);
+ wxMultiChoiceDialog dlg(parent,
+ _(L("Select the printers this profile is compatible with.")),
+ _(L("Compatible printers")), presets);
// # Collect and set indices of printers marked as compatible.
wxArrayInt selections;
auto *compatible_printers = dynamic_cast<const ConfigOptionStrings*>(m_config->option("compatible_printers"));
@@ -1762,12 +2573,12 @@ wxSizer* Tab::compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox
selections.Add(idx);
break;
}
- dlg->SetSelections(selections);
+ dlg.SetSelections(selections);
std::vector<std::string> value;
// Show the dialog.
- if (dlg->ShowModal() == wxID_OK) {
+ if (dlg.ShowModal() == wxID_OK) {
selections.Clear();
- selections = dlg->GetSelections();
+ selections = dlg.GetSelections();
for (auto idx : selections)
value.push_back(presets[idx].ToStdString());
if (value.empty()) {
@@ -1776,18 +2587,255 @@ wxSizer* Tab::compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox
}
// All printers have been made compatible with this preset.
load_key_value("compatible_printers", value);
+ update_changed_ui();
}
}));
return sizer;
}
+void Tab::update_presetsctrl(wxDataViewTreeCtrl* ui, bool show_incompatible)
+{
+ if (ui == nullptr)
+ return;
+ ui->Freeze();
+ ui->DeleteAllItems();
+ auto presets = m_presets->get_presets();
+ auto idx_selected = m_presets->get_idx_selected();
+ auto suffix_modified = m_presets->get_suffix_modified();
+ int icon_compatible = 0;
+ int icon_incompatible = 1;
+ int cnt_items = 0;
+
+ auto root_sys = ui->AppendContainer(wxDataViewItem(0), _(L("System presets")));
+ auto root_def = ui->AppendContainer(wxDataViewItem(0), _(L("Default presets")));
+
+ auto show_def = get_app_config()->get("no_defaults")[0] != '1';
+
+ for (size_t i = presets.front().is_visible ? 0 : 1; i < presets.size(); ++i) {
+ const Preset &preset = presets[i];
+ if (!preset.is_visible || (!show_incompatible && !preset.is_compatible && i != idx_selected))
+ continue;
+
+ auto preset_name = wxString::FromUTF8((preset.name + (preset.is_dirty ? suffix_modified : "")).c_str());
+
+ wxDataViewItem item;
+ if (preset.is_system)
+ item = ui->AppendItem(root_sys, preset_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ else if (show_def && preset.is_default)
+ item = ui->AppendItem(root_def, preset_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ else
+ {
+ auto parent = m_presets->get_preset_parent(preset);
+ if (parent == nullptr)
+ item = ui->AppendItem(root_def, preset_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ else
+ {
+ auto parent_name = parent->name;
+
+ wxDataViewTreeStoreContainerNode *node = ui->GetStore()->FindContainerNode(root_sys);
+ if (node)
+ {
+ wxDataViewTreeStoreNodeList::iterator iter;
+ for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); iter++)
+ {
+ wxDataViewTreeStoreNode* child = *iter;
+ auto child_item = child->GetItem();
+ auto item_text = ui->GetItemText(child_item);
+ if (item_text == parent_name)
+ {
+ auto added_child = ui->AppendItem(child->GetItem(), preset_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ if (!added_child){
+ ui->DeleteItem(child->GetItem());
+ auto new_parent = ui->AppendContainer(root_sys, parent_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ ui->AppendItem(new_parent, preset_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ cnt_items++;
+ if (i == idx_selected){
+ ui->Select(item);
+ m_cc_presets_choice->SetText(preset_name);
+ }
+ }
+ if (ui->GetStore()->GetChildCount(root_def) == 0)
+ ui->DeleteItem(root_def);
+
+ ui->Thaw();
+}
+
+void Tab::update_tab_presets(wxComboCtrl* ui, bool show_incompatible)
+{
+ if (ui == nullptr)
+ return;
+ ui->Freeze();
+ ui->Clear();
+ auto presets = m_presets->get_presets();
+ auto idx_selected = m_presets->get_idx_selected();
+ auto suffix_modified = m_presets->get_suffix_modified();
+ int icon_compatible = 0;
+ int icon_incompatible = 1;
+ int cnt_items = 0;
+
+ wxDataViewTreeCtrlComboPopup* popup = wxDynamicCast(m_cc_presets_choice->GetPopupControl(), wxDataViewTreeCtrlComboPopup);
+ if (popup != nullptr)
+ {
+ popup->DeleteAllItems();
+
+ auto root_sys = popup->AppendContainer(wxDataViewItem(0), _(L("System presets")));
+ auto root_def = popup->AppendContainer(wxDataViewItem(0), _(L("Default presets")));
+
+ auto show_def = get_app_config()->get("no_defaults")[0] != '1';
+
+ for (size_t i = presets.front().is_visible ? 0 : 1; i < presets.size(); ++i) {
+ const Preset &preset = presets[i];
+ if (!preset.is_visible || (!show_incompatible && !preset.is_compatible && i != idx_selected))
+ continue;
+
+ auto preset_name = wxString::FromUTF8((preset.name + (preset.is_dirty ? suffix_modified : "")).c_str());
+
+ wxDataViewItem item;
+ if (preset.is_system)
+ item = popup->AppendItem(root_sys, preset_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ else if (show_def && preset.is_default)
+ item = popup->AppendItem(root_def, preset_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ else
+ {
+ auto parent = m_presets->get_preset_parent(preset);
+ if (parent == nullptr)
+ item = popup->AppendItem(root_def, preset_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ else
+ {
+ auto parent_name = parent->name;
+
+ wxDataViewTreeStoreContainerNode *node = popup->GetStore()->FindContainerNode(root_sys);
+ if (node)
+ {
+ wxDataViewTreeStoreNodeList::iterator iter;
+ for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); iter++)
+ {
+ wxDataViewTreeStoreNode* child = *iter;
+ auto child_item = child->GetItem();
+ auto item_text = popup->GetItemText(child_item);
+ if (item_text == parent_name)
+ {
+ auto added_child = popup->AppendItem(child->GetItem(), preset_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ if (!added_child){
+ popup->DeleteItem(child->GetItem());
+ auto new_parent = popup->AppendContainer(root_sys, parent_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ popup->AppendItem(new_parent, preset_name,
+ preset.is_compatible ? icon_compatible : icon_incompatible);
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ cnt_items++;
+ if (i == idx_selected){
+ popup->Select(item);
+ m_cc_presets_choice->SetText(preset_name);
+ }
+ }
+ if (popup->GetStore()->GetChildCount(root_def) == 0)
+ popup->DeleteItem(root_def);
+ }
+ ui->Thaw();
+}
+
+void Tab::fill_icon_descriptions()
+{
+ m_icon_descriptions.push_back(t_icon_description(&m_bmp_value_lock, L("LOCKED LOCK;"
+ "indicates that the settings are the same as the system values for the current option group")));
+
+ m_icon_descriptions.push_back(t_icon_description(&m_bmp_value_unlock, L("UNLOCKED LOCK;"
+ "indicates that some settings were changed and are not equal to the system values for "
+ "the current option group.\n"
+ "Click the UNLOCKED LOCK icon to reset all settings for current option group to "
+ "the system values.")));
+
+ m_icon_descriptions.push_back(t_icon_description(&m_bmp_white_bullet, L("WHITE BULLET;"
+ "for the left button: \tindicates a non-system preset,\n"
+ "for the right button: \tindicates that the settings hasn't been modified.")));
+
+ m_icon_descriptions.push_back(t_icon_description(&m_bmp_value_revert, L("BACK ARROW;"
+ "indicates that the settings were changed and are not equal to the last saved preset for "
+ "the current option group.\n"
+ "Click the BACK ARROW icon to reset all settings for the current option group to "
+ "the last saved preset.")));
+}
+
+void Tab::set_tooltips_text()
+{
+// m_undo_to_sys_btn->SetToolTip(_(L( "LOCKED LOCK icon indicates that the settings are the same as the system values "
+// "for the current option group.\n"
+// "UNLOCKED LOCK icon indicates that some settings were changed and are not equal "
+// "to the system values for the current option group.\n"
+// "WHITE BULLET icon indicates a non system preset.\n\n"
+// "Click the UNLOCKED LOCK icon to reset all settings for current option group to "
+// "the system values.")));
+//
+// m_undo_btn->SetToolTip(_(L( "WHITE BULLET icon indicates that the settings are the same as in the last saved"
+// "preset for the current option group.\n"
+// "BACK ARROW icon indicates that the settings were changed and are not equal to "
+// "the last saved preset for the current option group.\n\n"
+// "Click the BACK ARROW icon to reset all settings for the current option group to "
+// "the last saved preset.")));
+
+ // --- Tooltip text for reset buttons (for whole options group)
+ // Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
+ m_ttg_value_lock = _(L("LOCKED LOCK icon indicates that the settings are the same as the system values "
+ "for the current option group"));
+ m_ttg_value_unlock = _(L("UNLOCKED LOCK icon indicates that some settings were changed and are not equal "
+ "to the system values for the current option group.\n"
+ "Click to reset all settings for current option group to the system values."));
+ m_ttg_white_bullet_ns = _(L("WHITE BULLET icon indicates a non system preset."));
+ m_ttg_non_system = &m_ttg_white_bullet_ns;
+ // Text to be shown on the "Undo user changes" button next to each input field.
+ m_ttg_white_bullet = _(L("WHITE BULLET icon indicates that the settings are the same as in the last saved "
+ "preset for the current option group."));
+ m_ttg_value_revert = _(L("BACK ARROW icon indicates that the settings were changed and are not equal to "
+ "the last saved preset for the current option group.\n"
+ "Click to reset all settings for the current option group to the last saved preset."));
+
+ // --- Tooltip text for reset buttons (for each option in group)
+ // Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
+ m_tt_value_lock = _(L("LOCKED LOCK icon indicates that the value is the same as the system value."));
+ m_tt_value_unlock = _(L("UNLOCKED LOCK icon indicates that the value was changed and is not equal "
+ "to the system value.\n"
+ "Click to reset current value to the system value."));
+ // m_tt_white_bullet_ns= _(L("WHITE BULLET icon indicates a non system preset."));
+ m_tt_non_system = &m_ttg_white_bullet_ns;
+ // Text to be shown on the "Undo user changes" button next to each input field.
+ m_tt_white_bullet = _(L("WHITE BULLET icon indicates that the value is the same as in the last saved preset."));
+ m_tt_value_revert = _(L("BACK ARROW icon indicates that the value was changed and is not equal to the last saved preset.\n"
+ "Click to reset current value to the last saved preset."));
+}
+
void Page::reload_config()
{
for (auto group : m_optgroups)
group->reload_config();
}
-Field* Page::get_field(t_config_option_key opt_key, int opt_index/* = -1*/) const
+Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const
{
Field* field = nullptr;
for (auto opt : m_optgroups){
@@ -1798,7 +2846,7 @@ Field* Page::get_field(t_config_option_key opt_key, int opt_index/* = -1*/) cons
return field;
}
-bool Page::set_value(t_config_option_key opt_key, boost::any value){
+bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value){
bool changed = false;
for(auto optgroup: m_optgroups) {
if (optgroup->set_value(opt_key, value))
@@ -1808,35 +2856,49 @@ bool Page::set_value(t_config_option_key opt_key, boost::any value){
}
// package Slic3r::GUI::Tab::Page;
-ConfigOptionsGroupShp Page::new_optgroup(wxString title, int noncommon_label_width /*= -1*/)
+ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_label_width /*= -1*/)
{
//! config_ have to be "right"
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(this, title, m_config, true);
if (noncommon_label_width >= 0)
optgroup->label_width = noncommon_label_width;
- optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){
+#ifdef __WXOSX__
+ auto tab = GetParent()->GetParent();
+#else
+ auto tab = GetParent();
+#endif
+ optgroup->m_on_change = [this, tab](t_config_option_key opt_key, boost::any value){
//! This function will be called from OptionGroup.
//! Using of CallAfter is redundant.
//! And in some cases it causes update() function to be recalled again
//! wxTheApp->CallAfter([this, opt_key, value]() {
- static_cast<Tab*>(GetParent())->update_dirty();
- static_cast<Tab*>(GetParent())->on_value_change(opt_key, value);
+ static_cast<Tab*>(tab)->update_dirty();
+ static_cast<Tab*>(tab)->on_value_change(opt_key, value);
//! });
};
- optgroup->m_get_initial_config = [this](){
- DynamicPrintConfig config = static_cast<Tab*>(GetParent())->m_presets->get_selected_preset().config;
+ optgroup->m_get_initial_config = [this, tab](){
+ DynamicPrintConfig config = static_cast<Tab*>(tab)->m_presets->get_selected_preset().config;
+ return config;
+ };
+
+ optgroup->m_get_sys_config = [this, tab](){
+ DynamicPrintConfig config = static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent()->config;
return config;
};
+ optgroup->have_sys_config = [this, tab](){
+ return static_cast<Tab*>(tab)->m_presets->get_selected_preset_parent() != nullptr;
+ };
+
vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10);
m_optgroups.push_back(optgroup);
return optgroup;
}
-void SavePresetWindow::build(wxString title, std::string default_name, std::vector<std::string> &values)
+void SavePresetWindow::build(const wxString& title, const std::string& default_name, std::vector<std::string> &values)
{
auto text = new wxStaticText(this, wxID_ANY, _(L("Save ")) + title + _(L(" as:")),
wxDefaultPosition, wxDefaultSize);
@@ -1865,14 +2927,25 @@ void SavePresetWindow::accept()
if (!m_chosen_name.empty()) {
const char* unusable_symbols = "<>:/\\|?*\"";
bool is_unusable_symbol = false;
+ bool is_unusable_postfix = false;
+ const std::string unusable_postfix = PresetCollection::get_suffix_modified();//"(modified)";
for (size_t i = 0; i < std::strlen(unusable_symbols); i++){
if (m_chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos){
is_unusable_symbol = true;
break;
}
}
+ if (m_chosen_name.find(unusable_postfix) != std::string::npos)
+ is_unusable_postfix = true;
+
if (is_unusable_symbol) {
- show_error(this, _(L("The supplied name is not valid; the following characters are not allowed:"))+" <>:/\\|?*\"");
+ show_error(this,_(L("The supplied name is not valid;")) + "\n" +
+ _(L("the following characters are not allowed:")) + " <>:/\\|?*\"");
+ }
+ else if (is_unusable_postfix){
+ show_error(this,_(L("The supplied name is not valid;")) + "\n" +
+ _(L("the following postfix are not allowed:")) + "\n\t" + //unusable_postfix);
+ wxString::FromUTF8(unusable_postfix.c_str()));
}
else if (m_chosen_name.compare("- default -") == 0) {
show_error(this, _(L("The supplied name is not available.")));
@@ -1883,5 +2956,71 @@ void SavePresetWindow::accept()
}
}
+void TabSLAMaterial::build()
+{
+ m_presets = &m_preset_bundle->sla_materials;
+ load_initial_data();
+
+ auto page = add_options_page(_(L("Material")), "package_green.png");
+
+ auto optgroup = page->new_optgroup(_(L("Layers")));
+ optgroup->append_single_option_line("layer_height");
+ optgroup->append_single_option_line("initial_layer_height");
+
+ optgroup = page->new_optgroup(_(L("Exposure")));
+ optgroup->append_single_option_line("exposure_time");
+ optgroup->append_single_option_line("initial_exposure_time");
+
+ optgroup = page->new_optgroup(_(L("Corrections")));
+ optgroup->label_width = 190;
+ std::vector<std::string> corrections = { "material_correction_printing", "material_correction_curing" };
+ std::vector<std::string> axes{ "X", "Y", "Z" };
+ for (auto& opt_key : corrections){
+ auto line = Line{ m_config->def()->get(opt_key)->full_label, "" };
+ int id = 0;
+ for (auto& axis : axes) {
+ auto opt = optgroup->get_option(opt_key, id);
+ opt.opt.label = axis;
+ opt.opt.width = 60;
+ line.append_option(opt);
+ ++id;
+ }
+ optgroup->append_line(line);
+ }
+
+ page = add_options_page(_(L("Notes")), "note.png");
+ optgroup = page->new_optgroup(_(L("Notes")), 0);
+ optgroup->label_width = 0;
+ Option option = optgroup->get_option("material_notes");
+ option.opt.full_width = true;
+ option.opt.height = 250;
+ optgroup->append_single_option_line(option);
+
+ page = add_options_page(_(L("Dependencies")), "wrench.png");
+ optgroup = page->new_optgroup(_(L("Profile dependencies")));
+ auto line = Line { _(L("Compatible printers")), "" };
+ line.widget = [this](wxWindow* parent){
+ return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
+ };
+ optgroup->append_line(line, &m_colored_Label);
+
+ option = optgroup->get_option("compatible_printers_condition");
+ option.opt.full_width = true;
+ optgroup->append_single_option_line(option);
+
+ line = Line{ "", "" };
+ line.full_width = 1;
+ line.widget = [this](wxWindow* parent) {
+ return description_line_widget(parent, &m_parent_preset_description_line);
+ };
+ optgroup->append_line(line);
+}
+
+void TabSLAMaterial::update()
+{
+ if (get_preset_bundle()->printers.get_selected_preset().printer_technology() == ptFFF)
+ return; // ys_FIXME
+}
+
} // GUI
} // Slic3r
diff --git a/xs/src/slic3r/GUI/Tab.hpp b/xs/src/slic3r/GUI/Tab.hpp
index 4f65f1475..a1214465e 100644
--- a/xs/src/slic3r/GUI/Tab.hpp
+++ b/xs/src/slic3r/GUI/Tab.hpp
@@ -1,3 +1,6 @@
+#ifndef slic3r_Tab_hpp_
+#define slic3r_Tab_hpp_
+
// The "Expert" tab at the right of the main tabbed window.
//
// This file implements following packages:
@@ -21,6 +24,7 @@
#include <wx/treectrl.h>
#include <wx/imaglist.h>
#include <wx/statbox.h>
+#include <wx/dataview.h>
#include <map>
#include <vector>
@@ -33,6 +37,9 @@
namespace Slic3r {
namespace GUI {
+typedef std::pair<wxBitmap*, std::string> t_icon_description;
+typedef std::vector<std::pair<wxBitmap*, std::string>> t_icon_descriptions;
+
// Single Tab page containing a{ vsizer } of{ optgroups }
// package Slic3r::GUI::Tab::Page;
using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>;
@@ -50,10 +57,14 @@ public:
{
Create(m_parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
m_vsizer = new wxBoxSizer(wxVERTICAL);
+ m_item_color = &get_label_clr_default();
SetSizer(m_vsizer);
}
~Page(){}
+ bool m_is_modified_values{ false };
+ bool m_is_nonsys_values{ true };
+
public:
std::vector <ConfigOptionsGroupShp> m_optgroups;
DynamicPrintConfig* m_config;
@@ -64,9 +75,25 @@ public:
size_t iconID() const { return m_iconID; }
void set_config(DynamicPrintConfig* config_in) { m_config = config_in; }
void reload_config();
- Field* get_field(t_config_option_key opt_key, int opt_index = -1) const;
- bool set_value(t_config_option_key opt_key, boost::any value);
- ConfigOptionsGroupShp new_optgroup(wxString title, int noncommon_label_width = -1);
+ Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
+ bool set_value(const t_config_option_key& opt_key, const boost::any& value);
+ ConfigOptionsGroupShp new_optgroup(const wxString& title, int noncommon_label_width = -1);
+
+ bool set_item_colour(const wxColour *clr) {
+ if (m_item_color != clr) {
+ m_item_color = clr;
+ return true;
+ }
+ return false;
+ }
+
+ const wxColour get_item_colour() {
+ return *m_item_color;
+ }
+
+protected:
+ // Color of TreeCtrlItem. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
+ const wxColour* m_item_color;
};
// Slic3r::GUI::Tab;
@@ -75,14 +102,16 @@ using PageShp = std::shared_ptr<Page>;
class Tab: public wxPanel
{
wxNotebook* m_parent;
+#ifdef __WXOSX__
+ wxPanel* m_tmp_panel;
+ int m_size_move = -1;
+#endif // __WXOSX__
protected:
std::string m_name;
const wxString m_title;
wxBitmapComboBox* m_presets_choice;
wxBitmapButton* m_btn_save_preset;
wxBitmapButton* m_btn_delete_preset;
- wxBitmap* m_bmp_show_incompatible_presets;
- wxBitmap* m_bmp_hide_incompatible_presets;
wxBitmapButton* m_btn_hide_incompatible_presets;
wxBoxSizer* m_hsizer;
wxBoxSizer* m_left_sizer;
@@ -90,35 +119,94 @@ protected:
wxImageList* m_icons;
wxCheckBox* m_compatible_printers_checkbox;
wxButton* m_compatible_printers_btn;
+ wxButton* m_undo_btn;
+ wxButton* m_undo_to_sys_btn;
+ wxButton* m_question_btn;
+ wxComboCtrl* m_cc_presets_choice;
+ wxDataViewTreeCtrl* m_presetctrl;
+ wxImageList* m_preset_icons;
+
+ // Cached bitmaps.
+ // A "flag" icon to be displayned next to the preset name in the Tab's combo box.
+ wxBitmap m_bmp_show_incompatible_presets;
+ wxBitmap m_bmp_hide_incompatible_presets;
+ // Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
+ wxBitmap m_bmp_value_lock;
+ wxBitmap m_bmp_value_unlock;
+ wxBitmap m_bmp_white_bullet;
+ // The following bitmap points to either m_bmp_value_unlock or m_bmp_white_bullet, depending on whether the current preset has a parent preset.
+ wxBitmap *m_bmp_non_system;
+ // Bitmaps to be shown on the "Undo user changes" button next to each input field.
+ wxBitmap m_bmp_value_revert;
+// wxBitmap m_bmp_value_unmodified;
+ wxBitmap m_bmp_question;
+
+ // Colors for ui "decoration"
+ wxColour m_sys_label_clr;
+ wxColour m_modified_label_clr;
+ wxColour m_default_text_clr;
+
+ // Tooltip text for reset buttons (for whole options group)
+ wxString m_ttg_value_lock;
+ wxString m_ttg_value_unlock;
+ wxString m_ttg_white_bullet_ns;
+ // The following text points to either m_ttg_value_unlock or m_ttg_white_bullet_ns, depending on whether the current preset has a parent preset.
+ wxString *m_ttg_non_system;
+ // Tooltip text to be shown on the "Undo user changes" button next to each input field.
+ wxString m_ttg_white_bullet;
+ wxString m_ttg_value_revert;
+
+ // Tooltip text for reset buttons (for each option in group)
+ wxString m_tt_value_lock;
+ wxString m_tt_value_unlock;
+ // The following text points to either m_tt_value_unlock or m_ttg_white_bullet_ns, depending on whether the current preset has a parent preset.
+ wxString *m_tt_non_system;
+ // Tooltip text to be shown on the "Undo user changes" button next to each input field.
+ wxString m_tt_white_bullet;
+ wxString m_tt_value_revert;
int m_icon_count;
- std::map<std::string, size_t> m_icon_index; // Map from an icon file name to its index in $self->{icons}.
- std::vector<PageShp> m_pages; // $self->{pages} = [];
+ std::map<std::string, size_t> m_icon_index; // Map from an icon file name to its index
+ std::vector<PageShp> m_pages;
bool m_disable_tree_sel_changed_event;
bool m_show_incompatible_presets;
bool m_no_controller;
std::vector<std::string> m_reload_dependent_tabs = {};
- std::vector<std::string> m_dirty_options = {};
+ enum OptStatus { osSystemValue = 1, osInitValue = 2 };
+ std::map<std::string, int> m_options_list;
+ int m_opt_status_value = 0;
+
+ t_icon_descriptions m_icon_descriptions = {};
// The two following two event IDs are generated at Plater.pm by calling Wx::NewEventType.
wxEventType m_event_value_change = 0;
wxEventType m_event_presets_changed = 0;
+ bool m_is_modified_values{ false };
+ bool m_is_nonsys_values{ true };
+ bool m_postpone_update_ui {false};
+
+ size_t m_selected_preset_item{ 0 };
+
public:
PresetBundle* m_preset_bundle;
bool m_show_btn_incompatible_presets = false;
PresetCollection* m_presets;
DynamicPrintConfig* m_config;
+ ogStaticText* m_parent_preset_description_line;
+ wxStaticText* m_colored_Label = nullptr;
public:
Tab() {}
- Tab(wxNotebook* parent, wxString title, const char* name, bool no_controller) :
+ Tab(wxNotebook* parent, const wxString& title, const char* name, bool no_controller) :
m_parent(parent), m_title(title), m_name(name), m_no_controller(no_controller) {
- Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
+ Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL, name);
get_tabs_list().push_back(this);
}
- ~Tab() { delete_tab_from_list(this); }
+ ~Tab(){
+ delete_tab_from_list(this);
+ }
wxWindow* parent() const { return m_parent; }
wxString title() const { return m_title; }
@@ -130,12 +218,13 @@ public:
void create_preset_tab(PresetBundle *preset_bundle);
void load_current_preset();
- void rebuild_page_tree();
+ void rebuild_page_tree(bool tree_sel_change_event = false);
void select_preset(std::string preset_name = "");
- bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, std::string new_printer_name = "");
+ bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, const std::string& new_printer_name = "");
wxSizer* compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox, wxButton** btn);
- void load_key_value(std::string opt_key, boost::any value);
+ void update_presetsctrl(wxDataViewTreeCtrl* ui, bool show_incompatible);
+ void load_key_value(const std::string& opt_key, const boost::any& value, bool saved_value = false);
void reload_compatible_printers_widget();
void OnTreeSelChange(wxTreeEvent& event);
@@ -146,34 +235,46 @@ public:
void toggle_show_hide_incompatible();
void update_show_hide_incompatible_button();
void update_ui_from_settings();
+ void update_labels_colour();
void update_changed_ui();
-
- PageShp add_options_page(wxString title, std::string icon, bool is_extruder_pages = false);
+ void get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page);
+ void update_changed_tree_ui();
+ void update_undo_buttons();
+
+ void on_roll_back_value(const bool to_sys = false);
+
+ PageShp add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages = false);
- virtual void OnActivate(){}
+ virtual void OnActivate();
virtual void on_preset_loaded(){}
virtual void build() = 0;
virtual void update() = 0;
+ virtual void init_options_list();
+ void load_initial_data();
void update_dirty();
void update_tab_ui();
- void load_config(DynamicPrintConfig config);
+ void load_config(const DynamicPrintConfig& config);
virtual void reload_config();
- Field* get_field(t_config_option_key opt_key, int opt_index = -1) const;
- bool set_value(t_config_option_key opt_key, boost::any value);
+ Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
+ bool set_value(const t_config_option_key& opt_key, const boost::any& value);
wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText);
bool current_preset_is_dirty();
+
DynamicPrintConfig* get_config() { return m_config; }
- PresetCollection* get_presets()
- {
- return m_presets;
- }
+ PresetCollection* get_presets() { return m_presets; }
std::vector<std::string> get_dependent_tabs() { return m_reload_dependent_tabs; }
+ size_t get_selected_preset_item() { return m_selected_preset_item; }
- void on_value_change(std::string opt_key, boost::any value);
+ void on_value_change(const std::string& opt_key, const boost::any& value);
+ void update_wiping_button_visibility();
protected:
void on_presets_changed();
+ void update_preset_description_line();
void update_frequently_changed_parameters();
+ void update_tab_presets(wxComboCtrl* ui, bool show_incompatible);
+ void fill_icon_descriptions();
+ void set_tooltips_text();
};
//Slic3r::GUI::Tab::Print;
@@ -214,24 +315,55 @@ public:
//Slic3r::GUI::Tab::Printer;
class TabPrinter : public Tab
{
+ bool m_has_single_extruder_MM_page = false;
+ bool m_use_silent_mode = false;
+ void append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key);
+ bool m_rebuild_kinematics_page = false;
+
+ std::vector<PageShp> m_pages_fff;
+ std::vector<PageShp> m_pages_sla;
public:
wxButton* m_serial_test_btn;
- wxButton* m_octoprint_host_test_btn;
+ wxButton* m_print_host_test_btn;
+ wxButton* m_printhost_browse_btn;
size_t m_extruders_count;
+ size_t m_extruders_count_old = 0;
size_t m_initial_extruders_count;
- std::vector<PageShp> m_extruder_pages;
+ size_t m_sys_extruders_count;
+
+ PrinterTechnology m_printer_technology = ptFFF;
TabPrinter() {}
TabPrinter(wxNotebook* parent, bool no_controller) : Tab(parent, _(L("Printer Settings")), "printer", no_controller) {}
~TabPrinter(){}
void build() override;
- void update() override;
+ void build_fff();
+ void build_sla();
+ void update() override;
+ void update_fff();
+ void update_sla();
+ void update_pages(); // update m_pages according to printer technology
void update_serial_ports();
void extruders_count_changed(size_t extruders_count);
+ PageShp build_kinematics_page();
void build_extruder_pages();
void on_preset_loaded() override;
+ void init_options_list() override;
+};
+
+class TabSLAMaterial : public Tab
+{
+public:
+ TabSLAMaterial() {}
+ TabSLAMaterial(wxNotebook* parent, bool no_controller) :
+ Tab(parent, _(L("SLA Material Settings")), "sla_material", no_controller) {}
+ ~TabSLAMaterial(){}
+
+ void build() override;
+ void update() override;
+ void init_options_list() override;
};
class SavePresetWindow :public wxDialog
@@ -243,10 +375,12 @@ public:
std::string m_chosen_name;
wxComboBox* m_combo;
- void build(wxString title, std::string default_name, std::vector<std::string> &values);
+ void build(const wxString& title, const std::string& default_name, std::vector<std::string> &values);
void accept();
std::string get_name() { return m_chosen_name; }
};
} // GUI
} // Slic3r
+
+#endif /* slic3r_Tab_hpp_ */
diff --git a/xs/src/slic3r/GUI/TabIface.cpp b/xs/src/slic3r/GUI/TabIface.cpp
index 4df0e72e5..29833322b 100644
--- a/xs/src/slic3r/GUI/TabIface.cpp
+++ b/xs/src/slic3r/GUI/TabIface.cpp
@@ -11,6 +11,7 @@ void TabIface::load_config(DynamicPrintConfig* config) { m_tab->load_config(*con
void TabIface::load_key_value(char* opt_key, char* value){ m_tab->load_key_value(opt_key, static_cast<std::string>(value)); }
bool TabIface::current_preset_is_dirty() { return m_tab->current_preset_is_dirty();}
void TabIface::OnActivate() { return m_tab->OnActivate();}
+size_t TabIface::get_selected_preset_item() { return m_tab->get_selected_preset_item(); }
std::string TabIface::title() { return m_tab->title().ToUTF8().data(); }
DynamicPrintConfig* TabIface::get_config() { return m_tab->get_config(); }
PresetCollection* TabIface::get_presets() { return m_tab!=nullptr ? m_tab->get_presets() : nullptr; }
diff --git a/xs/src/slic3r/GUI/TabIface.hpp b/xs/src/slic3r/GUI/TabIface.hpp
index 0325c855c..2f7f4e8e7 100644
--- a/xs/src/slic3r/GUI/TabIface.hpp
+++ b/xs/src/slic3r/GUI/TabIface.hpp
@@ -1,3 +1,6 @@
+#ifndef slic3r_TabIface_hpp_
+#define slic3r_TabIface_hpp_
+
#include <vector>
#include <string>
@@ -27,9 +30,12 @@ public:
DynamicPrintConfig* get_config();
PresetCollection* get_presets();
std::vector<std::string> get_dependent_tabs();
+ size_t get_selected_preset_item();
protected:
GUI::Tab *m_tab;
-};
+}; // namespace GUI
}; // namespace Slic3r
+
+#endif /* slic3r_TabIface_hpp_ */
diff --git a/xs/src/slic3r/GUI/UpdateDialogs.cpp b/xs/src/slic3r/GUI/UpdateDialogs.cpp
new file mode 100644
index 000000000..70d9c851c
--- /dev/null
+++ b/xs/src/slic3r/GUI/UpdateDialogs.cpp
@@ -0,0 +1,196 @@
+#include "UpdateDialogs.hpp"
+
+#include <wx/settings.h>
+#include <wx/sizer.h>
+#include <wx/event.h>
+#include <wx/stattext.h>
+#include <wx/button.h>
+#include <wx/hyperlink.h>
+#include <wx/statbmp.h>
+#include <wx/checkbox.h>
+
+#include "libslic3r/libslic3r.h"
+#include "libslic3r/Utils.hpp"
+#include "GUI.hpp"
+#include "ConfigWizard.hpp"
+
+namespace Slic3r {
+namespace GUI {
+
+
+static const std::string CONFIG_UPDATE_WIKI_URL("https://github.com/prusa3d/Slic3r/wiki/Slic3r-PE-1.40-configuration-update");
+
+
+// MsgUpdateSlic3r
+
+MsgUpdateSlic3r::MsgUpdateSlic3r(const Semver &ver_current, const Semver &ver_online) :
+ MsgDialog(nullptr, _(L("Update available")), _(L("New version of Slic3r PE is available"))),
+ ver_current(ver_current),
+ ver_online(ver_online)
+{
+ const auto url = wxString::Format("https://github.com/prusa3d/Slic3r/releases/tag/version_%s", ver_online.to_string());
+ auto *link = new wxHyperlinkCtrl(this, wxID_ANY, url, url);
+
+ auto *text = new wxStaticText(this, wxID_ANY, _(L("To download, follow the link below.")));
+ const auto link_width = link->GetSize().GetWidth();
+ text->Wrap(CONTENT_WIDTH > link_width ? CONTENT_WIDTH : link_width);
+ content_sizer->Add(text);
+ content_sizer->AddSpacer(VERT_SPACING);
+
+ auto *versions = new wxFlexGridSizer(2, 0, VERT_SPACING);
+ versions->Add(new wxStaticText(this, wxID_ANY, _(L("Current version:"))));
+ versions->Add(new wxStaticText(this, wxID_ANY, ver_current.to_string()));
+ versions->Add(new wxStaticText(this, wxID_ANY, _(L("New version:"))));
+ versions->Add(new wxStaticText(this, wxID_ANY, ver_online.to_string()));
+ content_sizer->Add(versions);
+ content_sizer->AddSpacer(VERT_SPACING);
+
+ content_sizer->Add(link);
+ content_sizer->AddSpacer(2*VERT_SPACING);
+
+ cbox = new wxCheckBox(this, wxID_ANY, _(L("Don't notify about new releases any more")));
+ content_sizer->Add(cbox);
+ content_sizer->AddSpacer(VERT_SPACING);
+
+ Fit();
+}
+
+MsgUpdateSlic3r::~MsgUpdateSlic3r() {}
+
+bool MsgUpdateSlic3r::disable_version_check() const
+{
+ return cbox->GetValue();
+}
+
+
+// MsgUpdateConfig
+
+MsgUpdateConfig::MsgUpdateConfig(const std::unordered_map<std::string, std::string> &updates) :
+ MsgDialog(nullptr, _(L("Configuration update")), _(L("Configuration update is available")), wxID_NONE)
+{
+ auto *text = new wxStaticText(this, wxID_ANY, _(L(
+ "Would you like to install it?\n\n"
+ "Note that a full configuration snapshot will be created first. It can then be restored at any time "
+ "should there be a problem with the new version.\n\n"
+ "Updated configuration bundles:"
+ )));
+ text->Wrap(CONTENT_WIDTH);
+ content_sizer->Add(text);
+ content_sizer->AddSpacer(VERT_SPACING);
+
+ auto *versions = new wxFlexGridSizer(2, 0, VERT_SPACING);
+ for (const auto &update : updates) {
+ auto *text_vendor = new wxStaticText(this, wxID_ANY, update.first);
+ text_vendor->SetFont(boldfont);
+ versions->Add(text_vendor);
+ versions->Add(new wxStaticText(this, wxID_ANY, update.second));
+ }
+
+ content_sizer->Add(versions);
+ content_sizer->AddSpacer(2*VERT_SPACING);
+
+ auto *btn_cancel = new wxButton(this, wxID_CANCEL);
+ btn_sizer->Add(btn_cancel);
+ btn_sizer->AddSpacer(HORIZ_SPACING);
+ auto *btn_ok = new wxButton(this, wxID_OK);
+ btn_sizer->Add(btn_ok);
+ btn_ok->SetFocus();
+
+ Fit();
+}
+
+MsgUpdateConfig::~MsgUpdateConfig() {}
+
+
+// MsgDataIncompatible
+
+MsgDataIncompatible::MsgDataIncompatible(const std::unordered_map<std::string, wxString> &incompats) :
+ MsgDialog(nullptr, _(L("Slic3r incompatibility")), _(L("Slic3r configuration is incompatible")), wxBitmap(from_u8(Slic3r::var("Slic3r_192px_grayscale.png")), wxBITMAP_TYPE_PNG), wxID_NONE)
+{
+ auto *text = new wxStaticText(this, wxID_ANY, _(L(
+ "This version of Slic3r PE is not compatible with currently installed configuration bundles.\n"
+ "This probably happened as a result of running an older Slic3r PE after using a newer one.\n\n"
+
+ "You may either exit Slic3r and try again with a newer version, or you may re-run the initial configuration. "
+ "Doing so will create a backup snapshot of the existing configuration before installing files compatible with this Slic3r.\n"
+ )));
+ text->Wrap(CONTENT_WIDTH);
+ content_sizer->Add(text);
+
+ auto *text2 = new wxStaticText(this, wxID_ANY, wxString::Format(_(L("This Slic3r PE version: %s")), SLIC3R_VERSION));
+ text2->Wrap(CONTENT_WIDTH);
+ content_sizer->Add(text2);
+ content_sizer->AddSpacer(VERT_SPACING);
+
+ auto *text3 = new wxStaticText(this, wxID_ANY, _(L("Incompatible bundles:")));
+ text3->Wrap(CONTENT_WIDTH);
+ content_sizer->Add(text3);
+ content_sizer->AddSpacer(VERT_SPACING);
+
+ auto *versions = new wxFlexGridSizer(2, 0, VERT_SPACING);
+ for (const auto &incompat : incompats) {
+ auto *text_vendor = new wxStaticText(this, wxID_ANY, incompat.first);
+ text_vendor->SetFont(boldfont);
+ versions->Add(text_vendor);
+ versions->Add(new wxStaticText(this, wxID_ANY, incompat.second));
+ }
+
+ content_sizer->Add(versions);
+ content_sizer->AddSpacer(2*VERT_SPACING);
+
+ auto *btn_exit = new wxButton(this, wxID_EXIT, _(L("Exit Slic3r")));
+ btn_sizer->Add(btn_exit);
+ btn_sizer->AddSpacer(HORIZ_SPACING);
+ auto *btn_reconf = new wxButton(this, wxID_REPLACE, _(L("Re-configure")));
+ btn_sizer->Add(btn_reconf);
+ btn_exit->SetFocus();
+
+ auto exiter = [this](const wxCommandEvent& evt) { this->EndModal(evt.GetId()); };
+ btn_exit->Bind(wxEVT_BUTTON, exiter);
+ btn_reconf->Bind(wxEVT_BUTTON, exiter);
+
+ Fit();
+}
+
+MsgDataIncompatible::~MsgDataIncompatible() {}
+
+
+// MsgDataLegacy
+
+MsgDataLegacy::MsgDataLegacy() :
+ MsgDialog(nullptr, _(L("Configuration update")), _(L("Configuration update")))
+{
+ auto *text = new wxStaticText(this, wxID_ANY, wxString::Format(
+ _(L(
+ "Slic3r PE now uses an updated configuration structure.\n\n"
+
+ "So called 'System presets' have been introduced, which hold the built-in default settings for various "
+ "printers. These System presets cannot be modified, instead, users now may create their "
+ "own presets inheriting settings from one of the System presets.\n"
+ "An inheriting preset may either inherit a particular value from its parent or override it with a customized value.\n\n"
+
+ "Please proceed with the %s that follows to set up the new presets "
+ "and to choose whether to enable automatic preset updates."
+ )),
+ ConfigWizard::name()
+ ));
+ text->Wrap(CONTENT_WIDTH);
+ content_sizer->Add(text);
+ content_sizer->AddSpacer(VERT_SPACING);
+
+ auto *text2 = new wxStaticText(this, wxID_ANY, _(L("For more information please visit our wiki page:")));
+ static const wxString url("https://github.com/prusa3d/Slic3r/wiki/Slic3r-PE-1.40-configuration-update");
+ // The wiki page name is intentionally not localized:
+ auto *link = new wxHyperlinkCtrl(this, wxID_ANY, "Slic3r PE 1.40 configuration update", CONFIG_UPDATE_WIKI_URL);
+ content_sizer->Add(text2);
+ content_sizer->Add(link);
+ content_sizer->AddSpacer(VERT_SPACING);
+
+ Fit();
+}
+
+MsgDataLegacy::~MsgDataLegacy() {}
+
+
+}
+}
diff --git a/xs/src/slic3r/GUI/UpdateDialogs.hpp b/xs/src/slic3r/GUI/UpdateDialogs.hpp
new file mode 100644
index 000000000..62548b98b
--- /dev/null
+++ b/xs/src/slic3r/GUI/UpdateDialogs.hpp
@@ -0,0 +1,81 @@
+#ifndef slic3r_UpdateDialogs_hpp_
+#define slic3r_UpdateDialogs_hpp_
+
+#include <string>
+#include <unordered_map>
+
+#include "slic3r/Utils/Semver.hpp"
+#include "MsgDialog.hpp"
+
+class wxBoxSizer;
+class wxCheckBox;
+
+namespace Slic3r {
+
+namespace GUI {
+
+
+// A confirmation dialog listing configuration updates
+class MsgUpdateSlic3r : public MsgDialog
+{
+public:
+ MsgUpdateSlic3r(const Semver &ver_current, const Semver &ver_online);
+ MsgUpdateSlic3r(MsgUpdateSlic3r &&) = delete;
+ MsgUpdateSlic3r(const MsgUpdateSlic3r &) = delete;
+ MsgUpdateSlic3r &operator=(MsgUpdateSlic3r &&) = delete;
+ MsgUpdateSlic3r &operator=(const MsgUpdateSlic3r &) = delete;
+ virtual ~MsgUpdateSlic3r();
+
+ // Tells whether the user checked the "don't bother me again" checkbox
+ bool disable_version_check() const;
+
+private:
+ const Semver &ver_current;
+ const Semver &ver_online;
+ wxCheckBox *cbox;
+};
+
+
+// Confirmation dialog informing about configuration update. Lists updated bundles & their versions.
+class MsgUpdateConfig : public MsgDialog
+{
+public:
+ // updates is a map of "vendor name" -> "version (comment)"
+ MsgUpdateConfig(const std::unordered_map<std::string, std::string> &updates);
+ MsgUpdateConfig(MsgUpdateConfig &&) = delete;
+ MsgUpdateConfig(const MsgUpdateConfig &) = delete;
+ MsgUpdateConfig &operator=(MsgUpdateConfig &&) = delete;
+ MsgUpdateConfig &operator=(const MsgUpdateConfig &) = delete;
+ ~MsgUpdateConfig();
+};
+
+// Informs about currently installed bundles not being compatible with the running Slic3r. Asks about action.
+class MsgDataIncompatible : public MsgDialog
+{
+public:
+ // incompats is a map of "vendor name" -> "version restrictions"
+ MsgDataIncompatible(const std::unordered_map<std::string, wxString> &incompats);
+ MsgDataIncompatible(MsgDataIncompatible &&) = delete;
+ MsgDataIncompatible(const MsgDataIncompatible &) = delete;
+ MsgDataIncompatible &operator=(MsgDataIncompatible &&) = delete;
+ MsgDataIncompatible &operator=(const MsgDataIncompatible &) = delete;
+ ~MsgDataIncompatible();
+};
+
+// Informs about a legacy data directory - an update from Slic3r PE < 1.40
+class MsgDataLegacy : public MsgDialog
+{
+public:
+ MsgDataLegacy();
+ MsgDataLegacy(MsgDataLegacy &&) = delete;
+ MsgDataLegacy(const MsgDataLegacy &) = delete;
+ MsgDataLegacy &operator=(MsgDataLegacy &&) = delete;
+ MsgDataLegacy &operator=(const MsgDataLegacy &) = delete;
+ ~MsgDataLegacy();
+};
+
+
+}
+}
+
+#endif
diff --git a/xs/src/slic3r/GUI/WipeTowerDialog.cpp b/xs/src/slic3r/GUI/WipeTowerDialog.cpp
new file mode 100644
index 000000000..eef4017c1
--- /dev/null
+++ b/xs/src/slic3r/GUI/WipeTowerDialog.cpp
@@ -0,0 +1,338 @@
+#include <algorithm>
+#include <sstream>
+#include "WipeTowerDialog.hpp"
+#include "GUI.hpp"
+
+#include <wx/sizer.h>
+
+RammingDialog::RammingDialog(wxWindow* parent,const std::string& parameters)
+: wxDialog(parent, wxID_ANY, _(L("Ramming customization")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE/* | wxRESIZE_BORDER*/)
+{
+ m_panel_ramming = new RammingPanel(this,parameters);
+
+ // Not found another way of getting the background colours of RammingDialog, RammingPanel and Chart correct than setting
+ // them all explicitely. Reading the parent colour yielded colour that didn't really match it, no wxSYS_COLOUR_... matched
+ // colour used for the dialog. Same issue (and "solution") here : https://forums.wxwidgets.org/viewtopic.php?f=1&t=39608
+ // Whoever can fix this, feel free to do so.
+ this-> SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK));
+ m_panel_ramming->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK));
+ m_panel_ramming->Show(true);
+ this->Show();
+
+ auto main_sizer = new wxBoxSizer(wxVERTICAL);
+ main_sizer->Add(m_panel_ramming, 1, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, 5);
+ main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_CENTER_HORIZONTAL | wxTOP | wxBOTTOM, 10);
+ SetSizer(main_sizer);
+ main_sizer->SetSizeHints(this);
+
+ this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) { EndModal(wxCANCEL); });
+
+ this->Bind(wxEVT_BUTTON,[this](wxCommandEvent&) {
+ m_output_data = m_panel_ramming->get_parameters();
+ EndModal(wxID_OK);
+ },wxID_OK);
+ this->Show();
+ wxMessageDialog(this,_(L("Ramming denotes the rapid extrusion just before a tool change in a single-extruder MM printer. Its purpose is to "
+ "properly shape the end of the unloaded filament so it does not prevent insertion of the new filament and can itself "
+ "be reinserted later. This phase is important and different materials can require different extrusion speeds to get "
+ "the good shape. For this reason, the extrusion rates during ramming are adjustable.\n\nThis is an expert-level "
+ "setting, incorrect adjustment will likely lead to jams, extruder wheel grinding into filament etc.")),_(L("Warning")),wxOK|wxICON_EXCLAMATION).ShowModal();
+}
+
+
+
+
+
+RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters)
+: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize/*,wxPoint(50,50), wxSize(800,350),wxBORDER_RAISED*/)
+{
+ auto sizer_chart = new wxBoxSizer(wxVERTICAL);
+ auto sizer_param = new wxBoxSizer(wxVERTICAL);
+
+ std::stringstream stream{ parameters };
+ stream >> m_ramming_line_width_multiplicator >> m_ramming_step_multiplicator;
+ int ramming_speed_size = 0;
+ float dummy = 0.f;
+ while (stream >> dummy)
+ ++ramming_speed_size;
+ stream.clear();
+ stream.get();
+
+ std::vector<std::pair<float, float>> buttons;
+ float x = 0.f;
+ float y = 0.f;
+ while (stream >> x >> y)
+ buttons.push_back(std::make_pair(x, y));
+
+ m_chart = new Chart(this, wxRect(10, 10, 480, 360), buttons, ramming_speed_size, 0.25f);
+ m_chart->SetBackgroundColour(parent->GetBackgroundColour()); // see comment in RammingDialog constructor
+ sizer_chart->Add(m_chart, 0, wxALL, 5);
+
+ m_widget_time = new wxSpinCtrlDouble(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(75, -1),wxSP_ARROW_KEYS,0.,5.0,3.,0.5);
+ m_widget_volume = new wxSpinCtrl(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(75, -1),wxSP_ARROW_KEYS,0,10000,0);
+ m_widget_ramming_line_width_multiplicator = new wxSpinCtrl(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(75, -1),wxSP_ARROW_KEYS,10,200,100);
+ m_widget_ramming_step_multiplicator = new wxSpinCtrl(this,wxID_ANY,wxEmptyString,wxDefaultPosition,wxSize(75, -1),wxSP_ARROW_KEYS,10,200,100);
+
+ auto gsizer_param = new wxFlexGridSizer(2, 5, 15);
+ gsizer_param->Add(new wxStaticText(this, wxID_ANY, wxString(_(L("Total ramming time")) + " (" + _(L("s")) + "):")), 0, wxALIGN_CENTER_VERTICAL);
+ gsizer_param->Add(m_widget_time);
+ gsizer_param->Add(new wxStaticText(this, wxID_ANY, wxString(_(L("Total rammed volume")) + " (" + _(L("mm")) + wxString("³):", wxConvUTF8))), 0, wxALIGN_CENTER_VERTICAL);
+ gsizer_param->Add(m_widget_volume);
+ gsizer_param->AddSpacer(20);
+ gsizer_param->AddSpacer(20);
+ gsizer_param->Add(new wxStaticText(this, wxID_ANY, wxString(_(L("Ramming line width")) + " (%):")), 0, wxALIGN_CENTER_VERTICAL);
+ gsizer_param->Add(m_widget_ramming_line_width_multiplicator);
+ gsizer_param->Add(new wxStaticText(this, wxID_ANY, wxString(_(L("Ramming line spacing")) + " (%):")), 0, wxALIGN_CENTER_VERTICAL);
+ gsizer_param->Add(m_widget_ramming_step_multiplicator);
+
+ sizer_param->Add(gsizer_param, 0, wxTOP, 100);
+
+ m_widget_time->SetValue(m_chart->get_time());
+ m_widget_time->SetDigits(2);
+ m_widget_volume->SetValue(m_chart->get_volume());
+ m_widget_volume->Disable();
+ m_widget_ramming_line_width_multiplicator->SetValue(m_ramming_line_width_multiplicator);
+ m_widget_ramming_step_multiplicator->SetValue(m_ramming_step_multiplicator);
+
+ m_widget_ramming_step_multiplicator->Bind(wxEVT_TEXT,[this](wxCommandEvent&) { line_parameters_changed(); });
+ m_widget_ramming_line_width_multiplicator->Bind(wxEVT_TEXT,[this](wxCommandEvent&) { line_parameters_changed(); });
+
+ auto sizer = new wxBoxSizer(wxHORIZONTAL);
+ sizer->Add(sizer_chart, 0, wxALL, 5);
+ sizer->Add(sizer_param, 0, wxALL, 10);
+
+ sizer->SetSizeHints(this);
+ SetSizer(sizer);
+
+ m_widget_time->Bind(wxEVT_TEXT,[this](wxCommandEvent&) {m_chart->set_xy_range(m_widget_time->GetValue(),-1);});
+ m_widget_time->Bind(wxEVT_CHAR,[](wxKeyEvent&){}); // do nothing - prevents the user to change the value
+ m_widget_volume->Bind(wxEVT_CHAR,[](wxKeyEvent&){}); // do nothing - prevents the user to change the value
+ Bind(EVT_WIPE_TOWER_CHART_CHANGED,[this](wxCommandEvent&) {m_widget_volume->SetValue(m_chart->get_volume()); m_widget_time->SetValue(m_chart->get_time());} );
+ Refresh(this);
+}
+
+void RammingPanel::line_parameters_changed() {
+ m_ramming_line_width_multiplicator = m_widget_ramming_line_width_multiplicator->GetValue();
+ m_ramming_step_multiplicator = m_widget_ramming_step_multiplicator->GetValue();
+}
+
+std::string RammingPanel::get_parameters()
+{
+ std::vector<float> speeds = m_chart->get_ramming_speed(0.25f);
+ std::vector<std::pair<float,float>> buttons = m_chart->get_buttons();
+ std::stringstream stream;
+ stream << m_ramming_line_width_multiplicator << " " << m_ramming_step_multiplicator;
+ for (const float& speed_value : speeds)
+ stream << " " << speed_value;
+ stream << "|";
+ for (const auto& button : buttons)
+ stream << " " << button.first << " " << button.second;
+ return stream.str();
+}
+
+
+#define ITEM_WIDTH 60
+// Parent dialog for purging volume adjustments - it fathers WipingPanel widget (that contains all controls) and a button to toggle simple/advanced mode:
+WipingDialog::WipingDialog(wxWindow* parent,const std::vector<float>& matrix, const std::vector<float>& extruders)
+: wxDialog(parent, wxID_ANY, _(L("Wipe tower - Purging volume adjustment")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE/* | wxRESIZE_BORDER*/)
+{
+ auto widget_button = new wxButton(this,wxID_ANY,"-",wxPoint(0,0),wxDefaultSize);
+ m_panel_wiping = new WipingPanel(this,matrix,extruders, widget_button);
+
+ auto main_sizer = new wxBoxSizer(wxVERTICAL);
+
+ // set min sizer width according to extruders count
+ const auto sizer_width = (int)((sqrt(matrix.size()) + 2.8)*ITEM_WIDTH);
+ main_sizer->SetMinSize(wxSize(sizer_width, -1));
+
+ main_sizer->Add(m_panel_wiping, 0, wxEXPAND | wxALL, 5);
+ main_sizer->Add(widget_button, 0, wxALIGN_CENTER_HORIZONTAL | wxCENTER | wxBOTTOM, 5);
+ main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10);
+ SetSizer(main_sizer);
+ main_sizer->SetSizeHints(this);
+
+ this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& e) { EndModal(wxCANCEL); });
+
+ this->Bind(wxEVT_BUTTON,[this](wxCommandEvent&) { // if OK button is clicked..
+ m_output_matrix = m_panel_wiping->read_matrix_values(); // ..query wiping panel and save returned values
+ m_output_extruders = m_panel_wiping->read_extruders_values(); // so they can be recovered later by calling get_...()
+ EndModal(wxID_OK);
+ },wxID_OK);
+
+ this->Show();
+}
+
+// This function allows to "play" with sizers parameters (like align or border)
+void WipingPanel::format_sizer(wxSizer* sizer, wxPanel* page, wxGridSizer* grid_sizer, const wxString& info, const wxString& table_title, int table_lshift/*=0*/)
+{
+ sizer->Add(new wxStaticText(page, wxID_ANY, info,wxDefaultPosition,wxSize(0,50)), 0, wxEXPAND | wxLEFT, 15);
+ auto table_sizer = new wxBoxSizer(wxVERTICAL);
+ sizer->Add(table_sizer, 0, wxALIGN_CENTER | wxCENTER, table_lshift);
+ table_sizer->Add(new wxStaticText(page, wxID_ANY, table_title), 0, wxALIGN_CENTER | wxTOP, 50);
+ table_sizer->Add(grid_sizer, 0, wxALIGN_CENTER | wxTOP, 10);
+}
+
+// This panel contains all control widgets for both simple and advanced mode (these reside in separate sizers)
+WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, wxButton* widget_button)
+: wxPanel(parent,wxID_ANY, wxDefaultPosition, wxDefaultSize/*,wxBORDER_RAISED*/)
+{
+ m_widget_button = widget_button; // pointer to the button in parent dialog
+ m_widget_button->Bind(wxEVT_BUTTON,[this](wxCommandEvent&){ toggle_advanced(true); });
+
+ m_number_of_extruders = (int)(sqrt(matrix.size())+0.001);
+
+ // Create two switched panels with their own sizers
+ m_sizer_simple = new wxBoxSizer(wxVERTICAL);
+ m_sizer_advanced = new wxBoxSizer(wxVERTICAL);
+ m_page_simple = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+ m_page_advanced = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+ m_page_simple->SetSizer(m_sizer_simple);
+ m_page_advanced->SetSizer(m_sizer_advanced);
+
+ auto gridsizer_simple = new wxGridSizer(3, 5, 10);
+ m_gridsizer_advanced = new wxGridSizer(m_number_of_extruders+1, 5, 1);
+
+ // First create controls for advanced mode and assign them to m_page_advanced:
+ for (unsigned int i = 0; i < m_number_of_extruders; ++i) {
+ edit_boxes.push_back(std::vector<wxTextCtrl*>(0));
+
+ for (unsigned int j = 0; j < m_number_of_extruders; ++j) {
+ edit_boxes.back().push_back(new wxTextCtrl(m_page_advanced, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH, -1)));
+ if (i == j)
+ edit_boxes[i][j]->Disable();
+ else
+ edit_boxes[i][j]->SetValue(wxString("") << int(matrix[m_number_of_extruders*j + i]));
+ }
+ }
+ m_gridsizer_advanced->Add(new wxStaticText(m_page_advanced, wxID_ANY, wxString("")));
+ for (unsigned int i = 0; i < m_number_of_extruders; ++i)
+ m_gridsizer_advanced->Add(new wxStaticText(m_page_advanced, wxID_ANY, wxString("") << i + 1), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ for (unsigned int i = 0; i < m_number_of_extruders; ++i) {
+ m_gridsizer_advanced->Add(new wxStaticText(m_page_advanced, wxID_ANY, wxString("") << i + 1), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ for (unsigned int j = 0; j < m_number_of_extruders; ++j)
+ m_gridsizer_advanced->Add(edit_boxes[j][i], 0);
+ }
+
+ // collect and format sizer
+ format_sizer(m_sizer_advanced, m_page_advanced, m_gridsizer_advanced,
+ _(L("Here you can adjust required purging volume (mm³) for any given pair of tools.")),
+ _(L("Extruder changed to")));
+
+ // Hide preview page before new page creating
+ // It allows to do that from a beginning of the main panel
+ m_page_advanced->Hide();
+
+ // Now the same for simple mode:
+ gridsizer_simple->Add(new wxStaticText(m_page_simple, wxID_ANY, wxString("")), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ gridsizer_simple->Add(new wxStaticText(m_page_simple, wxID_ANY, wxString(_(L("unloaded")))), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+ gridsizer_simple->Add(new wxStaticText(m_page_simple,wxID_ANY,wxString(_(L("loaded")))), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
+
+ for (unsigned int i=0;i<m_number_of_extruders;++i) {
+ m_old.push_back(new wxSpinCtrl(m_page_simple,wxID_ANY,wxEmptyString,wxDefaultPosition, wxSize(80, -1),wxSP_ARROW_KEYS|wxALIGN_RIGHT,0,300,extruders[2*i]));
+ m_new.push_back(new wxSpinCtrl(m_page_simple,wxID_ANY,wxEmptyString,wxDefaultPosition, wxSize(80, -1),wxSP_ARROW_KEYS|wxALIGN_RIGHT,0,300,extruders[2*i+1]));
+ gridsizer_simple->Add(new wxStaticText(m_page_simple, wxID_ANY, wxString(_(L("Tool #"))) << i + 1 << ": "), 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
+ gridsizer_simple->Add(m_old.back(),0);
+ gridsizer_simple->Add(m_new.back(),0);
+ }
+
+ // collect and format sizer
+ format_sizer(m_sizer_simple, m_page_simple, gridsizer_simple,
+ _(L("Total purging volume is calculated by summing two values below, depending on which tools are loaded/unloaded.")),
+ _(L("Volume to purge (mm³) when the filament is being")), 50);
+
+ m_sizer = new wxBoxSizer(wxVERTICAL);
+ m_sizer->Add(m_page_simple, 0, wxEXPAND | wxALL, 25);
+ m_sizer->Add(m_page_advanced, 0, wxEXPAND | wxALL, 25);
+
+ m_sizer->SetSizeHints(this);
+ SetSizer(m_sizer);
+
+ toggle_advanced(); // to show/hide what is appropriate
+
+ m_page_advanced->Bind(wxEVT_PAINT,[this](wxPaintEvent&) {
+ wxPaintDC dc(m_page_advanced);
+ int y_pos = 0.5 * (edit_boxes[0][0]->GetPosition().y + edit_boxes[0][edit_boxes.size()-1]->GetPosition().y + edit_boxes[0][edit_boxes.size()-1]->GetSize().y);
+ wxString label = _(L("From"));
+ int text_width = 0;
+ int text_height = 0;
+ dc.GetTextExtent(label,&text_width,&text_height);
+ int xpos = m_gridsizer_advanced->GetPosition().x;
+ dc.DrawRotatedText(label,xpos-text_height,y_pos + text_width/2.f,90);
+ });
+}
+
+
+
+
+// Reads values from the (advanced) wiping matrix:
+std::vector<float> WipingPanel::read_matrix_values() {
+ if (!m_advanced)
+ fill_in_matrix();
+ std::vector<float> output;
+ for (unsigned int i=0;i<m_number_of_extruders;++i) {
+ for (unsigned int j=0;j<m_number_of_extruders;++j) {
+ double val = 0.;
+ edit_boxes[j][i]->GetValue().ToDouble(&val);
+ output.push_back((float)val);
+ }
+ }
+ return output;
+}
+
+// Reads values from simple mode to save them for next time:
+std::vector<float> WipingPanel::read_extruders_values() {
+ std::vector<float> output;
+ for (unsigned int i=0;i<m_number_of_extruders;++i) {
+ output.push_back(m_old[i]->GetValue());
+ output.push_back(m_new[i]->GetValue());
+ }
+ return output;
+}
+
+// This updates the "advanced" matrix based on values from "simple" mode
+void WipingPanel::fill_in_matrix() {
+ for (unsigned i=0;i<m_number_of_extruders;++i) {
+ for (unsigned j=0;j<m_number_of_extruders;++j) {
+ if (i==j) continue;
+ edit_boxes[j][i]->SetValue(wxString("")<< (m_old[i]->GetValue() + m_new[j]->GetValue()));
+ }
+ }
+}
+
+
+
+// Function to check if simple and advanced settings are matching
+bool WipingPanel::advanced_matches_simple() {
+ for (unsigned i=0;i<m_number_of_extruders;++i) {
+ for (unsigned j=0;j<m_number_of_extruders;++j) {
+ if (i==j) continue;
+ if (edit_boxes[j][i]->GetValue() != (wxString("")<< (m_old[i]->GetValue() + m_new[j]->GetValue())))
+ return false;
+ }
+ }
+ return true;
+}
+
+
+// Switches the dialog from simple to advanced mode and vice versa
+void WipingPanel::toggle_advanced(bool user_action) {
+ if (m_advanced && !advanced_matches_simple() && user_action) {
+ if (wxMessageDialog(this,wxString(_(L("Switching to simple settings will discard changes done in the advanced mode!\n\nDo you want to proceed?"))),
+ wxString(_(L("Warning"))),wxYES_NO|wxICON_EXCLAMATION).ShowModal() != wxID_YES)
+ return;
+ }
+ if (user_action)
+ m_advanced = !m_advanced; // user demands a change -> toggle
+ else
+ m_advanced = !advanced_matches_simple(); // if called from constructor, show what is appropriate
+
+ (m_advanced ? m_page_advanced : m_page_simple)->Show();
+ (!m_advanced ? m_page_advanced : m_page_simple)->Hide();
+
+ m_widget_button->SetLabel(m_advanced ? _(L("Show simplified settings")) : _(L("Show advanced settings")));
+ if (m_advanced)
+ if (user_action) fill_in_matrix(); // otherwise keep values loaded from config
+
+ m_sizer->Layout();
+ Refresh();
+}
diff --git a/xs/src/slic3r/GUI/WipeTowerDialog.hpp b/xs/src/slic3r/GUI/WipeTowerDialog.hpp
new file mode 100644
index 000000000..d858062da
--- /dev/null
+++ b/xs/src/slic3r/GUI/WipeTowerDialog.hpp
@@ -0,0 +1,90 @@
+#ifndef _WIPE_TOWER_DIALOG_H_
+#define _WIPE_TOWER_DIALOG_H_
+
+#include <wx/spinctrl.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/checkbox.h>
+#include <wx/msgdlg.h>
+
+#include "RammingChart.hpp"
+
+
+class RammingPanel : public wxPanel {
+public:
+ RammingPanel(wxWindow* parent);
+ RammingPanel(wxWindow* parent,const std::string& data);
+ std::string get_parameters();
+
+private:
+ Chart* m_chart = nullptr;
+ wxSpinCtrl* m_widget_volume = nullptr;
+ wxSpinCtrl* m_widget_ramming_line_width_multiplicator = nullptr;
+ wxSpinCtrl* m_widget_ramming_step_multiplicator = nullptr;
+ wxSpinCtrlDouble* m_widget_time = nullptr;
+ int m_ramming_step_multiplicator;
+ int m_ramming_line_width_multiplicator;
+
+ void line_parameters_changed();
+};
+
+
+class RammingDialog : public wxDialog {
+public:
+ RammingDialog(wxWindow* parent,const std::string& parameters);
+ std::string get_parameters() { return m_output_data; }
+private:
+ RammingPanel* m_panel_ramming = nullptr;
+ std::string m_output_data;
+};
+
+
+
+
+
+
+
+class WipingPanel : public wxPanel {
+public:
+ WipingPanel(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, wxButton* widget_button);
+ std::vector<float> read_matrix_values();
+ std::vector<float> read_extruders_values();
+ void toggle_advanced(bool user_action = false);
+ void format_sizer(wxSizer* sizer, wxPanel* page, wxGridSizer* grid_sizer, const wxString& info, const wxString& table_title, int table_lshift=0);
+
+private:
+ void fill_in_matrix();
+ bool advanced_matches_simple();
+
+ std::vector<wxSpinCtrl*> m_old;
+ std::vector<wxSpinCtrl*> m_new;
+ std::vector<std::vector<wxTextCtrl*>> edit_boxes;
+ unsigned int m_number_of_extruders = 0;
+ bool m_advanced = false;
+ wxPanel* m_page_simple = nullptr;
+ wxPanel* m_page_advanced = nullptr;
+ wxBoxSizer* m_sizer = nullptr;
+ wxBoxSizer* m_sizer_simple = nullptr;
+ wxBoxSizer* m_sizer_advanced = nullptr;
+ wxGridSizer* m_gridsizer_advanced = nullptr;
+ wxButton* m_widget_button = nullptr;
+};
+
+
+
+
+
+class WipingDialog : public wxDialog {
+public:
+ WipingDialog(wxWindow* parent,const std::vector<float>& matrix, const std::vector<float>& extruders);
+ std::vector<float> get_matrix() const { return m_output_matrix; }
+ std::vector<float> get_extruders() const { return m_output_extruders; }
+
+
+private:
+ WipingPanel* m_panel_wiping = nullptr;
+ std::vector<float> m_output_matrix;
+ std::vector<float> m_output_extruders;
+};
+
+#endif // _WIPE_TOWER_DIALOG_H_ \ No newline at end of file
diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp
index 1ebd7979e..e646ed0ec 100644
--- a/xs/src/slic3r/GUI/wxExtensions.cpp
+++ b/xs/src/slic3r/GUI/wxExtensions.cpp
@@ -1,5 +1,13 @@
#include "wxExtensions.hpp"
+#include "GUI.hpp"
+#include "../../libslic3r/Utils.hpp"
+
+#include <wx/sizer.h>
+#include <wx/statline.h>
+#include <wx/dcclient.h>
+#include <wx/numformatter.h>
+
const unsigned int wxCheckListBoxComboPopup::DefaultWidth = 200;
const unsigned int wxCheckListBoxComboPopup::DefaultHeight = 200;
const unsigned int wxCheckListBoxComboPopup::DefaultItemHeight = 18;
@@ -82,15 +90,27 @@ void wxCheckListBoxComboPopup::OnCheckListBox(wxCommandEvent& evt)
{
// forwards the checklistbox event to the owner wxComboCtrl
- wxComboCtrl* cmb = GetComboCtrl();
- if (cmb != nullptr)
+ if (m_check_box_events_status == OnCheckListBoxFunction::FreeToProceed )
{
- wxCommandEvent event(wxEVT_CHECKLISTBOX, cmb->GetId());
- event.SetEventObject(cmb);
- cmb->ProcessWindowEvent(event);
+ wxComboCtrl* cmb = GetComboCtrl();
+ if (cmb != nullptr) {
+ wxCommandEvent event(wxEVT_CHECKLISTBOX, cmb->GetId());
+ event.SetEventObject(cmb);
+ cmb->ProcessWindowEvent(event);
+ }
}
evt.Skip();
+
+ #ifndef _WIN32 // events are sent differently on OSX+Linux vs Win (more description in header file)
+ if ( m_check_box_events_status == OnCheckListBoxFunction::RefuseToProceed )
+ // this happens if the event was resent by OnListBoxSelection - next call to OnListBoxSelection is due to user clicking the text, so the function should
+ // explicitly change the state on the checkbox
+ m_check_box_events_status = OnCheckListBoxFunction::WasRefusedLastTime;
+ else
+ // if the user clicked the checkbox square, this event was sent before OnListBoxSelection was called, so we don't want it to resend it
+ m_check_box_events_status = OnCheckListBoxFunction::RefuseToProceed;
+ #endif
}
void wxCheckListBoxComboPopup::OnListBoxSelection(wxCommandEvent& evt)
@@ -100,12 +120,1330 @@ void wxCheckListBoxComboPopup::OnListBoxSelection(wxCommandEvent& evt)
int selId = GetSelection();
if (selId != wxNOT_FOUND)
{
- Check((unsigned int)selId, !IsChecked((unsigned int)selId));
- SetSelection(wxNOT_FOUND);
+ #ifndef _WIN32
+ if (m_check_box_events_status == OnCheckListBoxFunction::RefuseToProceed)
+ #endif
+ Check((unsigned int)selId, !IsChecked((unsigned int)selId));
+ m_check_box_events_status = OnCheckListBoxFunction::FreeToProceed; // so the checkbox reacts to square-click the next time
+
+ SetSelection(wxNOT_FOUND);
wxCommandEvent event(wxEVT_CHECKLISTBOX, GetId());
event.SetInt(selId);
event.SetEventObject(this);
ProcessEvent(event);
}
}
+
+
+// *** wxDataViewTreeCtrlComboPopup ***
+
+const unsigned int wxDataViewTreeCtrlComboPopup::DefaultWidth = 270;
+const unsigned int wxDataViewTreeCtrlComboPopup::DefaultHeight = 200;
+const unsigned int wxDataViewTreeCtrlComboPopup::DefaultItemHeight = 22;
+
+bool wxDataViewTreeCtrlComboPopup::Create(wxWindow* parent)
+{
+ return wxDataViewTreeCtrl::Create(parent, wxID_ANY/*HIGHEST + 1*/, wxPoint(0, 0), wxDefaultSize/*wxSize(270, -1)*/, wxDV_NO_HEADER);
+}
+/*
+wxSize wxDataViewTreeCtrlComboPopup::GetAdjustedSize(int minWidth, int prefHeight, int maxHeight)
+{
+ // matches owner wxComboCtrl's width
+ // and sets height dinamically in dependence of contained items count
+ wxComboCtrl* cmb = GetComboCtrl();
+ if (cmb != nullptr)
+ {
+ wxSize size = GetComboCtrl()->GetSize();
+ if (m_cnt_open_items > 0)
+ size.SetHeight(m_cnt_open_items * DefaultItemHeight);
+ else
+ size.SetHeight(DefaultHeight);
+
+ return size;
+ }
+ else
+ return wxSize(DefaultWidth, DefaultHeight);
+}
+*/
+void wxDataViewTreeCtrlComboPopup::OnKeyEvent(wxKeyEvent& evt)
+{
+ // filters out all the keys which are not working properly
+ if (evt.GetKeyCode() == WXK_UP)
+ {
+ return;
+ }
+ else if (evt.GetKeyCode() == WXK_DOWN)
+ {
+ return;
+ }
+ else
+ {
+ evt.Skip();
+ return;
+ }
+}
+
+void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& evt)
+{
+ wxComboCtrl* cmb = GetComboCtrl();
+ auto selected = GetItemText(GetSelection());
+ cmb->SetText(selected);
+}
+
+// ----------------------------------------------------------------------------
+// *** PrusaCollapsiblePane ***
+// ----------------------------------------------------------------------------
+void PrusaCollapsiblePane::OnStateChange(const wxSize& sz)
+{
+#ifdef __WXOSX__
+ wxCollapsiblePane::OnStateChange(sz);
+#else
+ SetSize(sz);
+
+ if (this->HasFlag(wxCP_NO_TLW_RESIZE))
+ {
+ // the user asked to explicitly handle the resizing itself...
+ return;
+ }
+
+ auto top = GetParent(); //right_panel
+ if (!top)
+ return;
+
+ wxSizer *sizer = top->GetSizer();
+ if (!sizer)
+ return;
+
+ const wxSize newBestSize = sizer->ComputeFittingClientSize(top);
+ top->SetMinClientSize(newBestSize);
+
+ wxWindowUpdateLocker noUpdates_p(top->GetParent());
+ // we shouldn't attempt to resize a maximized window, whatever happens
+ // if (!top->IsMaximized())
+ // top->SetClientSize(newBestSize);
+ top->GetParent()->Layout();
+ top->Refresh();
+#endif //__WXOSX__
+}
+
+// ----------------------------------------------------------------------------
+// *** PrusaCollapsiblePaneMSW *** used only #ifdef __WXMSW__
+// ----------------------------------------------------------------------------
+#ifdef __WXMSW__
+bool PrusaCollapsiblePaneMSW::Create(wxWindow *parent, wxWindowID id, const wxString& label,
+ const wxPoint& pos, const wxSize& size, long style, const wxValidator& val, const wxString& name)
+{
+ if (!wxControl::Create(parent, id, pos, size, style, val, name))
+ return false;
+ m_pStaticLine = NULL;
+ m_strLabel = label;
+
+ // sizer containing the expand button and possibly a static line
+ m_sz = new wxBoxSizer(wxHORIZONTAL);
+
+ m_bmp_close.LoadFile(Slic3r::GUI::from_u8(Slic3r::var("disclosure_triangle_close.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_open.LoadFile(Slic3r::GUI::from_u8(Slic3r::var("disclosure_triangle_open.png")), wxBITMAP_TYPE_PNG);
+
+ m_pDisclosureTriangleButton = new wxButton(this, wxID_ANY, m_strLabel, wxPoint(0, 0),
+ wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
+ UpdateBtnBmp();
+ m_pDisclosureTriangleButton->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event)
+ {
+ if (event.GetEventObject() != m_pDisclosureTriangleButton)
+ {
+ event.Skip();
+ return;
+ }
+
+ Collapse(!IsCollapsed());
+
+ // this change was generated by the user - send the event
+ wxCollapsiblePaneEvent ev(this, GetId(), IsCollapsed());
+ GetEventHandler()->ProcessEvent(ev);
+ });
+
+ m_sz->Add(m_pDisclosureTriangleButton, 0, wxLEFT | wxTOP | wxBOTTOM, GetBorder());
+
+ // do not set sz as our sizers since we handle the pane window without using sizers
+ m_pPane = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
+ wxTAB_TRAVERSAL | wxNO_BORDER, wxT("wxCollapsiblePanePane"));
+
+ wxColour& clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
+ m_pDisclosureTriangleButton->SetBackgroundColour(clr);
+ this->SetBackgroundColour(clr);
+ m_pPane->SetBackgroundColour(clr);
+
+ // start as collapsed:
+ m_pPane->Hide();
+
+ return true;
+}
+
+void PrusaCollapsiblePaneMSW::UpdateBtnBmp()
+{
+ if (IsCollapsed())
+ m_pDisclosureTriangleButton->SetBitmap(m_bmp_close);
+ else{
+ m_pDisclosureTriangleButton->SetBitmap(m_bmp_open);
+ // To updating button bitmap it's needed to lost focus on this button, so
+ // we set focus to mainframe
+ //GetParent()->GetParent()->GetParent()->SetFocus();
+ //or to pane
+ GetPane()->SetFocus();
+ }
+ Layout();
+}
+
+void PrusaCollapsiblePaneMSW::SetLabel(const wxString &label)
+{
+ m_strLabel = label;
+ m_pDisclosureTriangleButton->SetLabel(m_strLabel);
+ Layout();
+}
+
+bool PrusaCollapsiblePaneMSW::Layout()
+{
+ if (!m_pDisclosureTriangleButton || !m_pPane || !m_sz)
+ return false; // we need to complete the creation first!
+
+ wxSize oursz(GetSize());
+
+ // move & resize the button and the static line
+ m_sz->SetDimension(0, 0, oursz.GetWidth(), m_sz->GetMinSize().GetHeight());
+ m_sz->Layout();
+
+ if (IsExpanded())
+ {
+ // move & resize the container window
+ int yoffset = m_sz->GetSize().GetHeight() + GetBorder();
+ m_pPane->SetSize(0, yoffset,
+ oursz.x, oursz.y - yoffset);
+
+ // this is very important to make the pane window layout show correctly
+ m_pPane->Layout();
+ }
+
+ return true;
+}
+
+void PrusaCollapsiblePaneMSW::Collapse(bool collapse)
+{
+ // optimization
+ if (IsCollapsed() == collapse)
+ return;
+
+ InvalidateBestSize();
+
+ // update our state
+ m_pPane->Show(!collapse);
+
+ // update button bitmap
+ UpdateBtnBmp();
+
+ OnStateChange(GetBestSize());
+}
+#endif //__WXMSW__
+
+// *****************************************************************************
+// ----------------------------------------------------------------------------
+// PrusaObjectDataViewModelNode
+// ----------------------------------------------------------------------------
+
+void PrusaObjectDataViewModelNode::set_object_action_icon() {
+ m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("add_object.png")), wxBITMAP_TYPE_PNG);
+}
+void PrusaObjectDataViewModelNode::set_part_action_icon() {
+ m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG);
+}
+
+// *****************************************************************************
+// ----------------------------------------------------------------------------
+// PrusaObjectDataViewModel
+// ----------------------------------------------------------------------------
+
+wxDataViewItem PrusaObjectDataViewModel::Add(const wxString &name)
+{
+ auto root = new PrusaObjectDataViewModelNode(name);
+ m_objects.push_back(root);
+ // notify control
+ wxDataViewItem child((void*)root);
+ wxDataViewItem parent((void*)NULL);
+ ItemAdded(parent, child);
+ return child;
+}
+
+wxDataViewItem PrusaObjectDataViewModel::Add(const wxString &name, const int instances_count/*, int scale*/)
+{
+ auto root = new PrusaObjectDataViewModelNode(name, instances_count);
+ m_objects.push_back(root);
+ // notify control
+ wxDataViewItem child((void*)root);
+ wxDataViewItem parent((void*)NULL);
+ ItemAdded(parent, child);
+ return child;
+}
+
+wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_item,
+ const wxString &name,
+ const wxIcon& icon,
+ const int extruder/* = 0*/,
+ const bool create_frst_child/* = true*/)
+{
+ PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID();
+ if (!root) return wxDataViewItem(0);
+
+ wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder);
+
+ if (root->GetChildren().Count() == 0 && create_frst_child)
+ {
+ auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG);
+ auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, extruder_str, 0);
+ root->Append(node);
+ // notify control
+ wxDataViewItem child((void*)node);
+ ItemAdded(parent_item, child);
+ }
+
+ auto volume_id = root->GetChildCount();
+ auto node = new PrusaObjectDataViewModelNode(root, name, icon, extruder_str, volume_id);
+ root->Append(node);
+ // notify control
+ wxDataViewItem child((void*)node);
+ ItemAdded(parent_item, child);
+ return child;
+}
+
+wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item)
+{
+ auto ret_item = wxDataViewItem(0);
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+ if (!node) // happens if item.IsOk()==false
+ return ret_item;
+
+ auto node_parent = node->GetParent();
+ wxDataViewItem parent(node_parent);
+
+ // first remove the node from the parent's array of children;
+ // NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_
+ // thus removing the node from it doesn't result in freeing it
+ if (node_parent){
+ auto id = node_parent->GetChildren().Index(node);
+ auto v_id = node->GetVolumeId();
+ node_parent->GetChildren().Remove(node);
+ if (id > 0){
+ if(id == node_parent->GetChildCount()) id--;
+ ret_item = wxDataViewItem(node_parent->GetChildren().Item(id));
+ }
+
+ //update volume_id value for remaining child-nodes
+ auto children = node_parent->GetChildren();
+ for (size_t i = 0; i < node_parent->GetChildCount(); i++)
+ {
+ auto volume_id = children[i]->GetVolumeId();
+ if (volume_id > v_id)
+ children[i]->SetVolumeId(volume_id-1);
+ }
+ }
+ else
+ {
+ auto it = find(m_objects.begin(), m_objects.end(), node);
+ auto id = it - m_objects.begin();
+ if (it != m_objects.end())
+ m_objects.erase(it);
+ if (id > 0){
+ if(id == m_objects.size()) id--;
+ ret_item = wxDataViewItem(m_objects[id]);
+ }
+ }
+ // free the node
+ delete node;
+
+ // set m_containet to FALSE if parent has no child
+ if (node_parent && node_parent->GetChildCount() == 0){
+#ifndef __WXGTK__
+ node_parent->m_container = false;
+#endif //__WXGTK__
+ ret_item = parent;
+ }
+
+ // notify control
+ ItemDeleted(parent, item);
+ return ret_item;
+}
+
+void PrusaObjectDataViewModel::DeleteAll()
+{
+ while (!m_objects.empty())
+ {
+ auto object = m_objects.back();
+// object->RemoveAllChildren();
+ Delete(wxDataViewItem(object));
+ }
+}
+
+void PrusaObjectDataViewModel::DeleteChildren(wxDataViewItem& parent)
+{
+ PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent.GetID();
+ if (!root) // happens if item.IsOk()==false
+ return;
+
+ // first remove the node from the parent's array of children;
+ // NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_
+ // thus removing the node from it doesn't result in freeing it
+ auto& children = root->GetChildren();
+ for (int id = root->GetChildCount() - 1; id >= 0; --id)
+ {
+ auto node = children[id];
+ auto item = wxDataViewItem(node);
+ children.RemoveAt(id);
+
+ // free the node
+ delete node;
+
+ // notify control
+ ItemDeleted(parent, item);
+ }
+
+ // set m_containet to FALSE if parent has no child
+#ifndef __WXGTK__
+ root->m_container = false;
+#endif //__WXGTK__
+}
+
+wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx)
+{
+ if (obj_idx >= m_objects.size())
+ {
+ printf("Error! Out of objects range.\n");
+ return wxDataViewItem(0);
+ }
+ return wxDataViewItem(m_objects[obj_idx]);
+}
+
+
+int PrusaObjectDataViewModel::GetIdByItem(wxDataViewItem& item)
+{
+ wxASSERT(item.IsOk());
+
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+ auto it = find(m_objects.begin(), m_objects.end(), node);
+ if (it == m_objects.end())
+ return -1;
+
+ return it - m_objects.begin();
+}
+
+int PrusaObjectDataViewModel::GetVolumeIdByItem(wxDataViewItem& item)
+{
+ wxASSERT(item.IsOk());
+
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+ if (!node) // happens if item.IsOk()==false
+ return -1;
+ return node->GetVolumeId();
+}
+
+wxString PrusaObjectDataViewModel::GetName(const wxDataViewItem &item) const
+{
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+ if (!node) // happens if item.IsOk()==false
+ return wxEmptyString;
+
+ return node->m_name;
+}
+
+wxString PrusaObjectDataViewModel::GetCopy(const wxDataViewItem &item) const
+{
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+ if (!node) // happens if item.IsOk()==false
+ return wxEmptyString;
+
+ return node->m_copy;
+}
+
+wxIcon& PrusaObjectDataViewModel::GetIcon(const wxDataViewItem &item) const
+{
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+ return node->m_icon;
+}
+
+void PrusaObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned int col) const
+{
+ wxASSERT(item.IsOk());
+
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+ switch (col)
+ {
+ case 0:{
+ const wxDataViewIconText data(node->m_name, node->m_icon);
+ variant << data;
+ break;}
+ case 1:
+ variant = node->m_copy;
+ break;
+ case 2:
+ variant = node->m_extruder;
+ break;
+ case 3:
+ variant << node->m_action_icon;
+ break;
+ default:
+ ;
+ }
+}
+
+bool PrusaObjectDataViewModel::SetValue(const wxVariant &variant, const wxDataViewItem &item, unsigned int col)
+{
+ wxASSERT(item.IsOk());
+
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+ return node->SetValue(variant, col);
+}
+
+bool PrusaObjectDataViewModel::SetValue(const wxVariant &variant, const int item_idx, unsigned int col)
+{
+ if (item_idx < 0 || item_idx >= m_objects.size())
+ return false;
+
+ return m_objects[item_idx]->SetValue(variant, col);
+}
+
+wxDataViewItem PrusaObjectDataViewModel::MoveChildUp(const wxDataViewItem &item)
+{
+ auto ret_item = wxDataViewItem(0);
+ wxASSERT(item.IsOk());
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+ if (!node) // happens if item.IsOk()==false
+ return ret_item;
+
+ auto node_parent = node->GetParent();
+ if (!node_parent) // If isn't part, but object
+ return ret_item;
+
+ auto volume_id = node->GetVolumeId();
+ if (0 < volume_id && volume_id < node_parent->GetChildCount()){
+ node_parent->SwapChildrens(volume_id - 1, volume_id);
+ ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id - 1));
+ ItemChanged(item);
+ ItemChanged(ret_item);
+ }
+ else
+ ret_item = wxDataViewItem(node_parent->GetNthChild(0));
+ return ret_item;
+}
+
+wxDataViewItem PrusaObjectDataViewModel::MoveChildDown(const wxDataViewItem &item)
+{
+ auto ret_item = wxDataViewItem(0);
+ wxASSERT(item.IsOk());
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+ if (!node) // happens if item.IsOk()==false
+ return ret_item;
+
+ auto node_parent = node->GetParent();
+ if (!node_parent) // If isn't part, but object
+ return ret_item;
+
+ auto volume_id = node->GetVolumeId();
+ if (0 <= volume_id && volume_id+1 < node_parent->GetChildCount()){
+ node_parent->SwapChildrens(volume_id + 1, volume_id);
+ ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id + 1));
+ ItemChanged(item);
+ ItemChanged(ret_item);
+ }
+ else
+ ret_item = wxDataViewItem(node_parent->GetNthChild(node_parent->GetChildCount()-1));
+ return ret_item;
+}
+
+wxDataViewItem PrusaObjectDataViewModel::ReorganizeChildren(int current_volume_id, int new_volume_id, const wxDataViewItem &parent)
+{
+ auto ret_item = wxDataViewItem(0);
+ if (current_volume_id == new_volume_id)
+ return ret_item;
+ wxASSERT(parent.IsOk());
+ PrusaObjectDataViewModelNode *node_parent = (PrusaObjectDataViewModelNode*)parent.GetID();
+ if (!node_parent) // happens if item.IsOk()==false
+ return ret_item;
+
+ PrusaObjectDataViewModelNode *deleted_node = node_parent->GetNthChild(current_volume_id);
+ node_parent->GetChildren().Remove(deleted_node);
+ ItemDeleted(parent, wxDataViewItem(deleted_node));
+ node_parent->Insert(deleted_node, new_volume_id);
+ ItemAdded(parent, wxDataViewItem(deleted_node));
+
+ //update volume_id value for child-nodes
+ auto children = node_parent->GetChildren();
+ int id_frst = current_volume_id < new_volume_id ? current_volume_id : new_volume_id;
+ int id_last = current_volume_id > new_volume_id ? current_volume_id : new_volume_id;
+ for (int id = id_frst; id <= id_last; ++id)
+ children[id]->SetVolumeId(id);
+
+ return wxDataViewItem(node_parent->GetNthChild(new_volume_id));
+}
+
+// bool MyObjectTreeModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const
+// {
+//
+// }
+
+wxDataViewItem PrusaObjectDataViewModel::GetParent(const wxDataViewItem &item) const
+{
+ // the invisible root node has no parent
+ if (!item.IsOk())
+ return wxDataViewItem(0);
+
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+
+ // objects nodes has no parent too
+ if (find(m_objects.begin(), m_objects.end(),node) != m_objects.end())
+ return wxDataViewItem(0);
+
+ return wxDataViewItem((void*)node->GetParent());
+}
+
+bool PrusaObjectDataViewModel::IsContainer(const wxDataViewItem &item) const
+{
+ // the invisible root node can have children
+ if (!item.IsOk())
+ return true;
+
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID();
+ return node->IsContainer();
+}
+
+unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const
+{
+ PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)parent.GetID();
+ if (!node)
+ {
+ for (auto object : m_objects)
+ array.Add(wxDataViewItem((void*)object));
+ return m_objects.size();
+ }
+
+ if (node->GetChildCount() == 0)
+ {
+ return 0;
+ }
+
+ unsigned int count = node->GetChildren().GetCount();
+ for (unsigned int pos = 0; pos < count; pos++)
+ {
+ PrusaObjectDataViewModelNode *child = node->GetChildren().Item(pos);
+ array.Add(wxDataViewItem((void*)child));
+ }
+
+ return count;
+}
+
+
+// ----------------------------------------------------------------------------
+// PrusaDoubleSlider
+// ----------------------------------------------------------------------------
+
+PrusaDoubleSlider::PrusaDoubleSlider(wxWindow *parent,
+ wxWindowID id,
+ int lowerValue,
+ int higherValue,
+ int minValue,
+ int maxValue,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxValidator& val,
+ const wxString& name) :
+ wxControl(parent, id, pos, size, wxWANTS_CHARS | wxBORDER_NONE),
+ m_lower_value(lowerValue), m_higher_value (higherValue),
+ m_min_value(minValue), m_max_value(maxValue),
+ m_style(style == wxSL_HORIZONTAL || style == wxSL_VERTICAL ? style: wxSL_HORIZONTAL)
+{
+#ifndef __WXOSX__ // SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX
+ SetDoubleBuffered(true);
+#endif //__WXOSX__
+
+ m_bmp_thumb_higher = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("right_half_circle.png")) :
+ Slic3r::GUI::from_u8(Slic3r::var("up_half_circle.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("left_half_circle.png")) :
+ Slic3r::GUI::from_u8(Slic3r::var("down_half_circle.png")), wxBITMAP_TYPE_PNG);
+ m_thumb_size = m_bmp_thumb_lower.GetSize();
+
+ m_bmp_add_tick_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_add_on.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_add_tick_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_add_off.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_del_tick_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_delete_on.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_del_tick_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_delete_off.png")), wxBITMAP_TYPE_PNG);
+ m_tick_icon_dim = m_bmp_add_tick_on.GetSize().x;
+
+ m_bmp_one_layer_lock_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_lock_on.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_one_layer_lock_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_lock_off.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_one_layer_unlock_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_unlock_on.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_one_layer_unlock_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_unlock_off.png")), wxBITMAP_TYPE_PNG);
+ m_lock_icon_dim = m_bmp_one_layer_lock_on.GetSize().x;
+
+ m_selection = ssUndef;
+
+ // slider events
+ Bind(wxEVT_PAINT, &PrusaDoubleSlider::OnPaint, this);
+ Bind(wxEVT_LEFT_DOWN, &PrusaDoubleSlider::OnLeftDown, this);
+ Bind(wxEVT_MOTION, &PrusaDoubleSlider::OnMotion, this);
+ Bind(wxEVT_LEFT_UP, &PrusaDoubleSlider::OnLeftUp, this);
+ Bind(wxEVT_MOUSEWHEEL, &PrusaDoubleSlider::OnWheel, this);
+ Bind(wxEVT_ENTER_WINDOW,&PrusaDoubleSlider::OnEnterWin, this);
+ Bind(wxEVT_LEAVE_WINDOW,&PrusaDoubleSlider::OnLeaveWin, this);
+ Bind(wxEVT_KEY_DOWN, &PrusaDoubleSlider::OnKeyDown, this);
+ Bind(wxEVT_KEY_UP, &PrusaDoubleSlider::OnKeyUp, this);
+ Bind(wxEVT_RIGHT_DOWN, &PrusaDoubleSlider::OnRightDown,this);
+ Bind(wxEVT_RIGHT_UP, &PrusaDoubleSlider::OnRightUp, this);
+
+ // control's view variables
+ SLIDER_MARGIN = 4 + (style == wxSL_HORIZONTAL ? m_bmp_thumb_higher.GetWidth() : m_bmp_thumb_higher.GetHeight());
+
+ DARK_ORANGE_PEN = wxPen(wxColour(253, 84, 2));
+ ORANGE_PEN = wxPen(wxColour(253, 126, 66));
+ LIGHT_ORANGE_PEN = wxPen(wxColour(254, 177, 139));
+
+ DARK_GREY_PEN = wxPen(wxColour(128, 128, 128));
+ GREY_PEN = wxPen(wxColour(164, 164, 164));
+ LIGHT_GREY_PEN = wxPen(wxColour(204, 204, 204));
+
+ line_pens = { &DARK_GREY_PEN, &GREY_PEN, &LIGHT_GREY_PEN };
+ segm_pens = { &DARK_ORANGE_PEN, &ORANGE_PEN, &LIGHT_ORANGE_PEN };
+}
+
+int PrusaDoubleSlider::GetActiveValue() const
+{
+ return m_selection == ssLower ?
+ m_lower_value : m_selection == ssHigher ?
+ m_higher_value : -1;
+}
+
+wxSize PrusaDoubleSlider::DoGetBestSize() const
+{
+ const wxSize size = wxControl::DoGetBestSize();
+ if (size.x > 1 && size.y > 1)
+ return size;
+ const int new_size = is_horizontal() ? 80 : 120;
+ return wxSize(new_size, new_size);
+}
+
+void PrusaDoubleSlider::SetLowerValue(const int lower_val)
+{
+ m_lower_value = lower_val;
+ Refresh();
+ Update();
+}
+
+void PrusaDoubleSlider::SetHigherValue(const int higher_val)
+{
+ m_higher_value = higher_val;
+ Refresh();
+ Update();
+}
+
+void PrusaDoubleSlider::SetMaxValue(const int max_value)
+{
+ m_max_value = max_value;
+ Refresh();
+ Update();
+}
+
+void PrusaDoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos)
+{
+ int width;
+ int height;
+ get_size(&width, &height);
+
+ wxCoord line_beg_x = is_horizontal() ? SLIDER_MARGIN : width*0.5 - 1;
+ wxCoord line_beg_y = is_horizontal() ? height*0.5 - 1 : SLIDER_MARGIN;
+ wxCoord line_end_x = is_horizontal() ? width - SLIDER_MARGIN + 1 : width*0.5 - 1;
+ wxCoord line_end_y = is_horizontal() ? height*0.5 - 1 : height - SLIDER_MARGIN + 1;
+
+ wxCoord segm_beg_x = is_horizontal() ? lower_pos : width*0.5 - 1;
+ wxCoord segm_beg_y = is_horizontal() ? height*0.5 - 1 : lower_pos-1;
+ wxCoord segm_end_x = is_horizontal() ? higher_pos : width*0.5 - 1;
+ wxCoord segm_end_y = is_horizontal() ? height*0.5 - 1 : higher_pos-1;
+
+ for (int id = 0; id < line_pens.size(); id++)
+ {
+ dc.SetPen(*line_pens[id]);
+ dc.DrawLine(line_beg_x, line_beg_y, line_end_x, line_end_y);
+ dc.SetPen(*segm_pens[id]);
+ dc.DrawLine(segm_beg_x, segm_beg_y, segm_end_x, segm_end_y);
+ if (is_horizontal())
+ line_beg_y = line_end_y = segm_beg_y = segm_end_y += 1;
+ else
+ line_beg_x = line_end_x = segm_beg_x = segm_end_x += 1;
+ }
+}
+
+double PrusaDoubleSlider::get_scroll_step()
+{
+ const wxSize sz = get_size();
+ const int& slider_len = m_style == wxSL_HORIZONTAL ? sz.x : sz.y;
+ return double(slider_len - SLIDER_MARGIN * 2) / (m_max_value - m_min_value);
+}
+
+// get position on the slider line from entered value
+wxCoord PrusaDoubleSlider::get_position_from_value(const int value)
+{
+ const double step = get_scroll_step();
+ const int val = is_horizontal() ? value : m_max_value - value;
+ return wxCoord(SLIDER_MARGIN + int(val*step + 0.5));
+}
+
+wxSize PrusaDoubleSlider::get_size()
+{
+ int w, h;
+ get_size(&w, &h);
+ return wxSize(w, h);
+}
+
+void PrusaDoubleSlider::get_size(int *w, int *h)
+{
+ GetSize(w, h);
+ is_horizontal() ? *w -= m_lock_icon_dim : *h -= m_lock_icon_dim;
+}
+
+void PrusaDoubleSlider::get_lower_and_higher_position(int& lower_pos, int& higher_pos)
+{
+ const double step = get_scroll_step();
+ if (is_horizontal()) {
+ lower_pos = SLIDER_MARGIN + int(m_lower_value*step + 0.5);
+ higher_pos = SLIDER_MARGIN + int(m_higher_value*step + 0.5);
+ }
+ else {
+ lower_pos = SLIDER_MARGIN + int((m_max_value - m_lower_value)*step + 0.5);
+ higher_pos = SLIDER_MARGIN + int((m_max_value - m_higher_value)*step + 0.5);
+ }
+}
+
+void PrusaDoubleSlider::draw_focus_rect()
+{
+ if (!m_is_focused)
+ return;
+ const wxSize sz = GetSize();
+ wxPaintDC dc(this);
+ const wxPen pen = wxPen(wxColour(128, 128, 10), 1, wxPENSTYLE_DOT);
+ dc.SetPen(pen);
+ dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxBRUSHSTYLE_TRANSPARENT));
+ dc.DrawRectangle(1, 1, sz.x - 2, sz.y - 2);
+}
+
+void PrusaDoubleSlider::render()
+{
+ SetBackgroundColour(GetParent()->GetBackgroundColour());
+ draw_focus_rect();
+
+ wxPaintDC dc(this);
+ wxFont font = dc.GetFont();
+ const wxFont smaller_font = font.Smaller();
+ dc.SetFont(smaller_font);
+
+ const wxCoord lower_pos = get_position_from_value(m_lower_value);
+ const wxCoord higher_pos = get_position_from_value(m_higher_value);
+
+ // draw line
+ draw_scroll_line(dc, lower_pos, higher_pos);
+
+// //lower slider:
+// draw_thumb(dc, lower_pos, ssLower);
+// //higher slider:
+// draw_thumb(dc, higher_pos, ssHigher);
+
+ // draw both sliders
+ draw_thumbs(dc, lower_pos, higher_pos);
+
+ //draw color print ticks
+ draw_ticks(dc);
+
+ //draw color print ticks
+ draw_one_layer_icon(dc);
+}
+
+void PrusaDoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end)
+{
+ const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
+ wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off : &m_bmp_add_tick_on;
+ if (m_ticks.find(tick) != m_ticks.end())
+ icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off : &m_bmp_del_tick_on;
+
+ wxCoord x_draw, y_draw;
+ is_horizontal() ? x_draw = pt_beg.x - 0.5*m_tick_icon_dim : y_draw = pt_beg.y - 0.5*m_tick_icon_dim;
+ if (m_selection == ssLower)
+ is_horizontal() ? y_draw = pt_end.y + 3 : x_draw = pt_beg.x - m_tick_icon_dim-2;
+ else
+ is_horizontal() ? y_draw = pt_beg.y - m_tick_icon_dim-2 : x_draw = pt_end.x + 3;
+
+ dc.DrawBitmap(*icon, x_draw, y_draw);
+
+ //update rect of the tick action icon
+ m_rect_tick_action = wxRect(x_draw, y_draw, m_tick_icon_dim, m_tick_icon_dim);
+}
+
+void PrusaDoubleSlider::draw_info_line_with_icon(wxDC& dc, const wxPoint& pos, const SelectedSlider selection)
+{
+ if (m_selection == selection) {
+ //draw info line
+ dc.SetPen(DARK_ORANGE_PEN);
+ const wxPoint pt_beg = is_horizontal() ? wxPoint(pos.x, pos.y - m_thumb_size.y) : wxPoint(pos.x - m_thumb_size.x, pos.y - 1);
+ const wxPoint pt_end = is_horizontal() ? wxPoint(pos.x, pos.y + m_thumb_size.y) : wxPoint(pos.x + m_thumb_size.x, pos.y - 1);
+ dc.DrawLine(pt_beg, pt_end);
+
+ //draw action icon
+ draw_action_icon(dc, pt_beg, pt_end);
+ }
+}
+
+wxString PrusaDoubleSlider::get_label(const SelectedSlider& selection) const
+{
+ const int value = selection == ssLower ? m_lower_value : m_higher_value;
+
+ if (m_label_koef == 1.0 && m_values.empty())
+ return wxString::Format("%d", value);
+
+ const wxString str = m_values.empty() ?
+ wxNumberFormatter::ToString(m_label_koef*value, 2, wxNumberFormatter::Style_None) :
+ wxNumberFormatter::ToString(m_values[value].second, 2, wxNumberFormatter::Style_None);
+ return wxString::Format("%s\n(%d)", str, m_values.empty() ? value : m_values[value].first);
+}
+
+void PrusaDoubleSlider::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const
+{
+ if (m_is_one_layer && selection != m_selection || !selection)
+ return;
+ wxCoord text_width, text_height;
+ const wxString label = get_label(selection);
+ dc.GetMultiLineTextExtent(label, &text_width, &text_height);
+ wxPoint text_pos;
+ if (selection ==ssLower)
+ text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + m_thumb_size.x) :
+ wxPoint(pos.x + m_thumb_size.x+1, pos.y - 0.5*text_height - 1);
+ else
+ text_pos = is_horizontal() ? wxPoint(pos.x - text_width - 1, pos.y - m_thumb_size.x - text_height) :
+ wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5*text_height + 1);
+ dc.DrawText(label, text_pos);
+}
+
+void PrusaDoubleSlider::draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection)
+{
+ wxCoord x_draw, y_draw;
+ if (selection == ssLower) {
+ if (is_horizontal()) {
+ x_draw = pos.x - m_thumb_size.x;
+ y_draw = pos.y - int(0.5*m_thumb_size.y);
+ }
+ else {
+ x_draw = pos.x - int(0.5*m_thumb_size.x);
+ y_draw = pos.y;
+ }
+ }
+ else{
+ if (is_horizontal()) {
+ x_draw = pos.x;
+ y_draw = pos.y - int(0.5*m_thumb_size.y);
+ }
+ else {
+ x_draw = pos.x - int(0.5*m_thumb_size.x);
+ y_draw = pos.y - m_thumb_size.y;
+ }
+ }
+ dc.DrawBitmap(selection == ssLower ? m_bmp_thumb_lower : m_bmp_thumb_higher, x_draw, y_draw);
+
+ // Update thumb rect
+ update_thumb_rect(x_draw, y_draw, selection);
+}
+
+void PrusaDoubleSlider::draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection)
+{
+ //calculate thumb position on slider line
+ int width, height;
+ get_size(&width, &height);
+ const wxPoint pos = is_horizontal() ? wxPoint(pos_coord, height*0.5) : wxPoint(0.5*width, pos_coord);
+
+ // Draw thumb
+ draw_thumb_item(dc, pos, selection);
+
+ // Draw info_line
+ draw_info_line_with_icon(dc, pos, selection);
+
+ // Draw thumb text
+ draw_thumb_text(dc, pos, selection);
+}
+
+void PrusaDoubleSlider::draw_thumbs(wxDC& dc, const wxCoord& lower_pos, const wxCoord& higher_pos)
+{
+ //calculate thumb position on slider line
+ int width, height;
+ get_size(&width, &height);
+ const wxPoint pos_l = is_horizontal() ? wxPoint(lower_pos, height*0.5) : wxPoint(0.5*width, lower_pos);
+ const wxPoint pos_h = is_horizontal() ? wxPoint(higher_pos, height*0.5) : wxPoint(0.5*width, higher_pos);
+
+ // Draw lower thumb
+ draw_thumb_item(dc, pos_l, ssLower);
+ // Draw lower info_line
+ draw_info_line_with_icon(dc, pos_l, ssLower);
+
+ // Draw higher thumb
+ draw_thumb_item(dc, pos_h, ssHigher);
+ // Draw higher info_line
+ draw_info_line_with_icon(dc, pos_h, ssHigher);
+ // Draw higher thumb text
+ draw_thumb_text(dc, pos_h, ssHigher);
+
+ // Draw lower thumb text
+ draw_thumb_text(dc, pos_l, ssLower);
+}
+
+void PrusaDoubleSlider::draw_ticks(wxDC& dc)
+{
+ dc.SetPen(DARK_GREY_PEN);
+ int height, width;
+ get_size(&width, &height);
+ const wxCoord mid = is_horizontal() ? 0.5*height : 0.5*width;
+ for (auto tick : m_ticks)
+ {
+ const wxCoord pos = get_position_from_value(tick);
+
+ is_horizontal() ? dc.DrawLine(pos, mid-14, pos, mid-9) :
+ dc.DrawLine(mid - 14, pos - 1, mid - 9, pos - 1);
+ is_horizontal() ? dc.DrawLine(pos, mid+14, pos, mid+9) :
+ dc.DrawLine(mid + 14, pos - 1, mid + 9, pos - 1);
+ }
+}
+
+void PrusaDoubleSlider::draw_one_layer_icon(wxDC& dc)
+{
+ wxBitmap* icon = m_is_one_layer ?
+ m_is_one_layer_icon_focesed ? &m_bmp_one_layer_lock_off : &m_bmp_one_layer_lock_on :
+ m_is_one_layer_icon_focesed ? &m_bmp_one_layer_unlock_off : &m_bmp_one_layer_unlock_on;
+
+ int width, height;
+ get_size(&width, &height);
+
+ wxCoord x_draw, y_draw;
+ is_horizontal() ? x_draw = width-2 : x_draw = 0.5*width - 0.5*m_lock_icon_dim;
+ is_horizontal() ? y_draw = 0.5*height - 0.5*m_lock_icon_dim : y_draw = height-2;
+
+ dc.DrawBitmap(*icon, x_draw, y_draw);
+
+ //update rect of the lock/unlock icon
+ m_rect_one_layer_icon = wxRect(x_draw, y_draw, m_lock_icon_dim, m_lock_icon_dim);
+}
+
+void PrusaDoubleSlider::update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection)
+{
+ const wxRect& rect = wxRect(begin_x, begin_y, m_thumb_size.x, m_thumb_size.y);
+ if (selection == ssLower)
+ m_rect_lower_thumb = rect;
+ else
+ m_rect_higher_thumb = rect;
+}
+
+int PrusaDoubleSlider::get_value_from_position(const wxCoord x, const wxCoord y)
+{
+ const int height = get_size().y;
+ const double step = get_scroll_step();
+
+ if (is_horizontal())
+ return int(double(x - SLIDER_MARGIN) / step + 0.5);
+ else
+ return int(m_min_value + double(height - SLIDER_MARGIN - y) / step + 0.5);
+}
+
+void PrusaDoubleSlider::detect_selected_slider(const wxPoint& pt, const bool is_mouse_wheel /*= false*/)
+{
+ if (is_mouse_wheel)
+ {
+ if (is_horizontal()) {
+ m_selection = pt.x <= m_rect_lower_thumb.GetRight() ? ssLower :
+ pt.x >= m_rect_higher_thumb.GetLeft() ? ssHigher : ssUndef;
+ }
+ else {
+ m_selection = pt.y >= m_rect_lower_thumb.GetTop() ? ssLower :
+ pt.y <= m_rect_higher_thumb.GetBottom() ? ssHigher : ssUndef;
+ }
+ return;
+ }
+
+ m_selection = is_point_in_rect(pt, m_rect_lower_thumb) ? ssLower :
+ is_point_in_rect(pt, m_rect_higher_thumb) ? ssHigher : ssUndef;
+}
+
+bool PrusaDoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect)
+{
+ if (rect.GetLeft() <= pt.x && pt.x <= rect.GetRight() &&
+ rect.GetTop() <= pt.y && pt.y <= rect.GetBottom())
+ return true;
+ return false;
+}
+
+void PrusaDoubleSlider::OnLeftDown(wxMouseEvent& event)
+{
+ this->CaptureMouse();
+ wxClientDC dc(this);
+ wxPoint pos = event.GetLogicalPosition(dc);
+ if (is_point_in_rect(pos, m_rect_tick_action)) {
+ action_tick(taOnIcon);
+ return;
+ }
+
+ m_is_left_down = true;
+ if (is_point_in_rect(pos, m_rect_one_layer_icon)){
+ m_is_one_layer = !m_is_one_layer;
+ m_selection == ssLower ? correct_lower_value() : correct_higher_value();
+ if (!m_selection) m_selection = ssHigher;
+ }
+ else
+ detect_selected_slider(pos);
+
+ Refresh();
+ Update();
+ event.Skip();
+}
+
+void PrusaDoubleSlider::correct_lower_value()
+{
+ if (m_lower_value < m_min_value)
+ m_lower_value = m_min_value;
+ else if (m_lower_value > m_max_value)
+ m_lower_value = m_max_value;
+
+ if (m_lower_value >= m_higher_value && m_lower_value <= m_max_value || m_is_one_layer)
+ m_higher_value = m_lower_value;
+}
+
+void PrusaDoubleSlider::correct_higher_value()
+{
+ if (m_higher_value > m_max_value)
+ m_higher_value = m_max_value;
+ else if (m_higher_value < m_min_value)
+ m_higher_value = m_min_value;
+
+ if (m_higher_value <= m_lower_value && m_higher_value >= m_min_value || m_is_one_layer)
+ m_lower_value = m_higher_value;
+}
+
+void PrusaDoubleSlider::OnMotion(wxMouseEvent& event)
+{
+ const wxClientDC dc(this);
+ const wxPoint pos = event.GetLogicalPosition(dc);
+ m_is_one_layer_icon_focesed = is_point_in_rect(pos, m_rect_one_layer_icon);
+ if (!m_is_left_down && !m_is_one_layer){
+ m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action);
+ }
+ else if (m_is_left_down || m_is_right_down){
+ if (m_selection == ssLower) {
+ m_lower_value = get_value_from_position(pos.x, pos.y);
+ correct_lower_value();
+ }
+ else if (m_selection == ssHigher) {
+ m_higher_value = get_value_from_position(pos.x, pos.y);
+ correct_higher_value();
+ }
+ }
+ Refresh();
+ Update();
+ event.Skip();
+}
+
+void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event)
+{
+ this->ReleaseMouse();
+ m_is_left_down = false;
+ Refresh();
+ Update();
+ event.Skip();
+
+ wxCommandEvent e(wxEVT_SCROLL_CHANGED);
+ e.SetEventObject(this);
+ ProcessWindowEvent(e);
+}
+
+void PrusaDoubleSlider::enter_window(wxMouseEvent& event, const bool enter)
+{
+ m_is_focused = enter;
+ Refresh();
+ Update();
+ event.Skip();
+}
+
+// "condition" have to be true for:
+// - value increase (if wxSL_VERTICAL)
+// - value decrease (if wxSL_HORIZONTAL)
+void PrusaDoubleSlider::move_current_thumb(const bool condition)
+{
+ m_is_one_layer = wxGetKeyState(WXK_CONTROL);
+ int delta = condition ? -1 : 1;
+ if (is_horizontal())
+ delta *= -1;
+
+ if (m_selection == ssLower) {
+ m_lower_value -= delta;
+ correct_lower_value();
+ }
+ else if (m_selection == ssHigher) {
+ m_higher_value -= delta;
+ correct_higher_value();
+ }
+ Refresh();
+ Update();
+
+ wxCommandEvent e(wxEVT_SCROLL_CHANGED);
+ e.SetEventObject(this);
+ ProcessWindowEvent(e);
+}
+
+void PrusaDoubleSlider::action_tick(const TicksAction action)
+{
+ if (m_selection == ssUndef)
+ return;
+
+ const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
+
+ if (action == taOnIcon && !m_ticks.insert(tick).second)
+ m_ticks.erase(tick);
+ else {
+ const auto it = m_ticks.find(tick);
+ if (it == m_ticks.end() && action == taAdd)
+ m_ticks.insert(tick);
+ else if (it != m_ticks.end() && action == taDel)
+ m_ticks.erase(tick);
+ else
+ return;
+ }
+
+ Refresh();
+ Update();
+}
+
+void PrusaDoubleSlider::OnWheel(wxMouseEvent& event)
+{
+ wxClientDC dc(this);
+ wxPoint pos = event.GetLogicalPosition(dc);
+ detect_selected_slider(pos, true);
+
+ if (m_selection == ssUndef)
+ return;
+
+ move_current_thumb(event.GetWheelRotation() > 0);
+}
+
+void PrusaDoubleSlider::OnKeyDown(wxKeyEvent &event)
+{
+ const int key = event.GetKeyCode();
+ if (key == '+' || key == WXK_NUMPAD_ADD)
+ action_tick(taAdd);
+ else if (key == '-' || key == 390 || key == WXK_DELETE || key == WXK_BACK)
+ action_tick(taDel);
+ else if (is_horizontal())
+ {
+ if (key == WXK_LEFT || key == WXK_RIGHT)
+ move_current_thumb(key == WXK_LEFT);
+ else if (key == WXK_UP || key == WXK_DOWN){
+ m_selection = key == WXK_UP ? ssHigher : ssLower;
+ Refresh();
+ }
+ }
+ else {
+ if (key == WXK_LEFT || key == WXK_RIGHT) {
+ m_selection = key == WXK_LEFT ? ssHigher : ssLower;
+ Refresh();
+ }
+ else if (key == WXK_UP || key == WXK_DOWN)
+ move_current_thumb(key == WXK_UP);
+ }
+}
+
+void PrusaDoubleSlider::OnKeyUp(wxKeyEvent &event)
+{
+ if (event.GetKeyCode() == WXK_CONTROL)
+ m_is_one_layer = false;
+ Refresh();
+ Update();
+ event.Skip();
+}
+
+void PrusaDoubleSlider::OnRightDown(wxMouseEvent& event)
+{
+ this->CaptureMouse();
+ const wxClientDC dc(this);
+ detect_selected_slider(event.GetLogicalPosition(dc));
+ if (!m_selection)
+ return;
+
+ if (m_selection == ssLower)
+ m_higher_value = m_lower_value;
+ else
+ m_lower_value = m_higher_value;
+
+ m_is_right_down = m_is_one_layer = true;
+
+ Refresh();
+ Update();
+ event.Skip();
+}
+
+void PrusaDoubleSlider::OnRightUp(wxMouseEvent& event)
+{
+ this->ReleaseMouse();
+ m_is_right_down = m_is_one_layer = false;
+
+ Refresh();
+ Update();
+ event.Skip();
+}
+
+
+// ----------------------------------------------------------------------------
+// PrusaLockButton
+// ----------------------------------------------------------------------------
+
+PrusaLockButton::PrusaLockButton( wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos /*= wxDefaultPosition*/,
+ const wxSize& size /*= wxDefaultSize*/):
+ wxButton(parent, id, wxEmptyString, pos, size, wxBU_EXACTFIT | wxNO_BORDER)
+{
+ m_bmp_lock_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_lock_on.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_lock_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_lock_off.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_unlock_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_unlock_on.png")), wxBITMAP_TYPE_PNG);
+ m_bmp_unlock_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_unlock_off.png")), wxBITMAP_TYPE_PNG);
+ m_lock_icon_dim = m_bmp_lock_on.GetSize().x;
+
+#ifdef __WXMSW__
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+#endif // __WXMSW__
+ SetBitmap(m_bmp_unlock_on);
+
+ //button events
+ Bind(wxEVT_BUTTON, &PrusaLockButton::OnButton, this);
+ Bind(wxEVT_ENTER_WINDOW, &PrusaLockButton::OnEnterBtn, this);
+ Bind(wxEVT_LEAVE_WINDOW, &PrusaLockButton::OnLeaveBtn, this);
+}
+
+void PrusaLockButton::OnButton(wxCommandEvent& event)
+{
+ m_is_pushed = !m_is_pushed;
+ enter_button(true);
+
+ event.Skip();
+}
+
+void PrusaLockButton::enter_button(const bool enter)
+{
+ wxBitmap* icon = m_is_pushed ?
+ enter ? &m_bmp_lock_off : &m_bmp_lock_on :
+ enter ? &m_bmp_unlock_off : &m_bmp_unlock_on;
+ SetBitmap(*icon);
+
+ Refresh();
+ Update();
+}
+
+// ************************************** EXPERIMENTS ***************************************
+
+// *****************************************************************************
+
+
+
diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp
index e61c17bbc..76e59f2eb 100644
--- a/xs/src/slic3r/GUI/wxExtensions.hpp
+++ b/xs/src/slic3r/GUI/wxExtensions.hpp
@@ -3,6 +3,15 @@
#include <wx/checklst.h>
#include <wx/combo.h>
+#include <wx/dataview.h>
+#include <wx/dc.h>
+#include <wx/collpane.h>
+#include <wx/wupdlock.h>
+#include <wx/button.h>
+#include <wx/slider.h>
+
+#include <vector>
+#include <set>
class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup
{
@@ -12,6 +21,21 @@ class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup
wxString m_text;
+ // Events sent on mouseclick are quite complex. Function OnListBoxSelection is supposed to pass the event to the checkbox, which works fine on
+ // Win. On OSX and Linux the events are generated differently - clicking on the checkbox square generates the event twice (and the square
+ // therefore seems not to respond).
+ // This enum is meant to save current state of affairs, i.e., if the event forwarding is ok to do or not. It is only used on Linux
+ // and OSX by some #ifdefs. It also stores information whether OnListBoxSelection is supposed to change the checkbox status,
+ // or if it changed status on its own already (which happens when the square is clicked). More comments in OnCheckListBox(...)
+ // There indeed is a better solution, maybe making a custom event used for the event passing to distinguish the original and passed message
+ // and blocking one of them on OSX and Linux. Feel free to refactor, but carefully test on all platforms.
+ enum class OnCheckListBoxFunction{
+ FreeToProceed,
+ RefuseToProceed,
+ WasRefusedLastTime
+ } m_check_box_events_status = OnCheckListBoxFunction::FreeToProceed;
+
+
public:
virtual bool Create(wxWindow* parent);
virtual wxWindow* GetControl();
@@ -25,4 +49,629 @@ public:
void OnListBoxSelection(wxCommandEvent& evt);
};
+
+// *** wxDataViewTreeCtrlComboBox ***
+
+class wxDataViewTreeCtrlComboPopup: public wxDataViewTreeCtrl, public wxComboPopup
+{
+ static const unsigned int DefaultWidth;
+ static const unsigned int DefaultHeight;
+ static const unsigned int DefaultItemHeight;
+
+ wxString m_text;
+ int m_cnt_open_items{0};
+
+public:
+ virtual bool Create(wxWindow* parent);
+ virtual wxWindow* GetControl() { return this; }
+ virtual void SetStringValue(const wxString& value) { m_text = value; }
+ virtual wxString GetStringValue() const { return m_text; }
+// virtual wxSize GetAdjustedSize(int minWidth, int prefHeight, int maxHeight);
+
+ virtual void OnKeyEvent(wxKeyEvent& evt);
+ void OnDataViewTreeCtrlSelection(wxCommandEvent& evt);
+ void SetItemsCnt(int cnt) { m_cnt_open_items = cnt; }
+};
+
+
+
+// *** PrusaCollapsiblePane ***
+// ----------------------------------------------------------------------------
+class PrusaCollapsiblePane : public wxCollapsiblePane
+{
+public:
+ PrusaCollapsiblePane() {}
+ PrusaCollapsiblePane(wxWindow *parent,
+ wxWindowID winid,
+ const wxString& label,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxCP_DEFAULT_STYLE,
+ const wxValidator& val = wxDefaultValidator,
+ const wxString& name = wxCollapsiblePaneNameStr)
+ {
+ Create(parent, winid, label, pos, size, style, val, name);
+ }
+ ~PrusaCollapsiblePane() {}
+
+ void OnStateChange(const wxSize& sz); //override/hide of OnStateChange from wxCollapsiblePane
+ virtual bool Show(bool show = true) override {
+ wxCollapsiblePane::Show(show);
+ OnStateChange(GetBestSize());
+ return true;
+ }
+};
+
+
+// *** PrusaCollapsiblePaneMSW *** used only #ifdef __WXMSW__
+// ----------------------------------------------------------------------------
+#ifdef __WXMSW__
+class PrusaCollapsiblePaneMSW : public PrusaCollapsiblePane//wxCollapsiblePane
+{
+ wxButton* m_pDisclosureTriangleButton = nullptr;
+ wxBitmap m_bmp_close;
+ wxBitmap m_bmp_open;
+public:
+ PrusaCollapsiblePaneMSW() {}
+ PrusaCollapsiblePaneMSW( wxWindow *parent,
+ wxWindowID winid,
+ const wxString& label,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxCP_DEFAULT_STYLE,
+ const wxValidator& val = wxDefaultValidator,
+ const wxString& name = wxCollapsiblePaneNameStr)
+ {
+ Create(parent, winid, label, pos, size, style, val, name);
+ }
+
+ ~PrusaCollapsiblePaneMSW() {}
+
+ bool Create(wxWindow *parent,
+ wxWindowID id,
+ const wxString& label,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxValidator& val,
+ const wxString& name);
+
+ void UpdateBtnBmp();
+ void SetLabel(const wxString &label) override;
+ bool Layout() override;
+ void Collapse(bool collapse) override;
+};
+#endif //__WXMSW__
+
+// *****************************************************************************
+// ----------------------------------------------------------------------------
+// PrusaObjectDataViewModelNode: a node inside PrusaObjectDataViewModel
+// ----------------------------------------------------------------------------
+
+class PrusaObjectDataViewModelNode;
+WX_DEFINE_ARRAY_PTR(PrusaObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray);
+
+class PrusaObjectDataViewModelNode
+{
+ PrusaObjectDataViewModelNode* m_parent;
+ MyObjectTreeModelNodePtrArray m_children;
+ wxIcon m_empty_icon;
+public:
+ PrusaObjectDataViewModelNode(const wxString &name, const int instances_count=1) {
+ m_parent = NULL;
+ m_name = name;
+ m_copy = wxString::Format("%d", instances_count);
+ m_type = "object";
+ m_volume_id = -1;
+#ifdef __WXGTK__
+ // it's necessary on GTK because of control have to know if this item will be container
+ // in another case you couldn't to add subitem for this item
+ // it will be produce "segmentation fault"
+ m_container = true;
+#endif //__WXGTK__
+ set_object_action_icon();
+ }
+
+ PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent,
+ const wxString& sub_obj_name,
+ const wxIcon& icon,
+ const wxString& extruder,
+ const int volume_id=-1) {
+ m_parent = parent;
+ m_name = sub_obj_name;
+ m_copy = wxEmptyString;
+ m_icon = icon;
+ m_type = "volume";
+ m_volume_id = volume_id;
+ m_extruder = extruder;
+ set_part_action_icon();
+ }
+
+ ~PrusaObjectDataViewModelNode()
+ {
+ // free all our children nodes
+ size_t count = m_children.GetCount();
+ for (size_t i = 0; i < count; i++)
+ {
+ PrusaObjectDataViewModelNode *child = m_children[i];
+ delete child;
+ }
+ }
+
+ wxString m_name;
+ wxIcon& m_icon = m_empty_icon;
+ wxString m_copy;
+ std::string m_type;
+ int m_volume_id;
+ bool m_container = false;
+ wxString m_extruder = "default";
+ wxBitmap m_action_icon;
+
+ bool IsContainer() const
+ {
+ return m_container;
+ }
+
+ PrusaObjectDataViewModelNode* GetParent()
+ {
+ return m_parent;
+ }
+ MyObjectTreeModelNodePtrArray& GetChildren()
+ {
+ return m_children;
+ }
+ PrusaObjectDataViewModelNode* GetNthChild(unsigned int n)
+ {
+ return m_children.Item(n);
+ }
+ void Insert(PrusaObjectDataViewModelNode* child, unsigned int n)
+ {
+ m_children.Insert(child, n);
+ }
+ void Append(PrusaObjectDataViewModelNode* child)
+ {
+ if (!m_container)
+ m_container = true;
+ m_children.Add(child);
+ }
+ void RemoveAllChildren()
+ {
+ if (GetChildCount() == 0)
+ return;
+ for (size_t id = GetChildCount() - 1; id >= 0; --id)
+ {
+ if (m_children.Item(id)->GetChildCount() > 0)
+ m_children[id]->RemoveAllChildren();
+ auto node = m_children[id];
+ m_children.RemoveAt(id);
+ delete node;
+ }
+ }
+
+ size_t GetChildCount() const
+ {
+ return m_children.GetCount();
+ }
+
+ bool SetValue(const wxVariant &variant, unsigned int col)
+ {
+ switch (col)
+ {
+ case 0:{
+ wxDataViewIconText data;
+ data << variant;
+ m_icon = data.GetIcon();
+ m_name = data.GetText();
+ return true;}
+ case 1:
+ m_copy = variant.GetString();
+ return true;
+ case 2:
+ m_extruder = variant.GetString();
+ return true;
+ case 3:
+ m_action_icon << variant;
+ return true;
+ default:
+ printf("MyObjectTreeModel::SetValue: wrong column");
+ }
+ return false;
+ }
+ void SetIcon(const wxIcon &icon)
+ {
+ m_icon = icon;
+ }
+
+ void SetType(const std::string& type){
+ m_type = type;
+ }
+ const std::string& GetType(){
+ return m_type;
+ }
+
+ void SetVolumeId(const int& volume_id){
+ m_volume_id = volume_id;
+ }
+ const int& GetVolumeId(){
+ return m_volume_id;
+ }
+
+ // use this function only for childrens
+ void AssignAllVal(PrusaObjectDataViewModelNode& from_node)
+ {
+ // ! Don't overwrite other values because of equality of this values for all children --
+ m_name = from_node.m_name;
+ m_icon = from_node.m_icon;
+ m_volume_id = from_node.m_volume_id;
+ m_extruder = from_node.m_extruder;
+ }
+
+ bool SwapChildrens(int frst_id, int scnd_id) {
+ if (GetChildCount() < 2 ||
+ frst_id < 0 || frst_id >= GetChildCount() ||
+ scnd_id < 0 || scnd_id >= GetChildCount())
+ return false;
+
+ PrusaObjectDataViewModelNode new_scnd = *GetNthChild(frst_id);
+ PrusaObjectDataViewModelNode new_frst = *GetNthChild(scnd_id);
+
+ new_scnd.m_volume_id = m_children.Item(scnd_id)->m_volume_id;
+ new_frst.m_volume_id = m_children.Item(frst_id)->m_volume_id;
+
+ m_children.Item(frst_id)->AssignAllVal(new_frst);
+ m_children.Item(scnd_id)->AssignAllVal(new_scnd);
+ return true;
+ }
+
+ // Set action icons for node
+ void set_object_action_icon();
+ void set_part_action_icon();
+};
+
+// ----------------------------------------------------------------------------
+// PrusaObjectDataViewModel
+// ----------------------------------------------------------------------------
+
+class PrusaObjectDataViewModel :public wxDataViewModel
+{
+ std::vector<PrusaObjectDataViewModelNode*> m_objects;
+public:
+ PrusaObjectDataViewModel(){}
+ ~PrusaObjectDataViewModel()
+ {
+ for (auto object : m_objects)
+ delete object;
+ }
+
+ wxDataViewItem Add(const wxString &name);
+ wxDataViewItem Add(const wxString &name, const int instances_count);
+ wxDataViewItem AddChild(const wxDataViewItem &parent_item,
+ const wxString &name,
+ const wxIcon& icon,
+ const int = 0,
+ const bool create_frst_child = true);
+ wxDataViewItem Delete(const wxDataViewItem &item);
+ void DeleteAll();
+ void DeleteChildren(wxDataViewItem& parent);
+ wxDataViewItem GetItemById(int obj_idx);
+ int GetIdByItem(wxDataViewItem& item);
+ int GetVolumeIdByItem(wxDataViewItem& item);
+ bool IsEmpty() { return m_objects.empty(); }
+
+ // helper method for wxLog
+
+ wxString GetName(const wxDataViewItem &item) const;
+ wxString GetCopy(const wxDataViewItem &item) const;
+ wxIcon& GetIcon(const wxDataViewItem &item) const;
+
+ // helper methods to change the model
+
+ virtual unsigned int GetColumnCount() const override { return 3;}
+ virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); }
+
+ virtual void GetValue(wxVariant &variant,
+ const wxDataViewItem &item, unsigned int col) const override;
+ virtual bool SetValue(const wxVariant &variant,
+ const wxDataViewItem &item, unsigned int col) override;
+ bool SetValue(const wxVariant &variant, const int item_idx, unsigned int col);
+
+ wxDataViewItem MoveChildUp(const wxDataViewItem &item);
+ wxDataViewItem MoveChildDown(const wxDataViewItem &item);
+ // For parent move child from cur_volume_id place to new_volume_id
+ // Remaining items will moved up/down accordingly
+ wxDataViewItem ReorganizeChildren(int cur_volume_id,
+ int new_volume_id,
+ const wxDataViewItem &parent);
+
+// virtual bool IsEnabled(const wxDataViewItem &item,
+// unsigned int col) const override;
+
+ virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override;
+ virtual bool IsContainer(const wxDataViewItem &item) const override;
+ virtual unsigned int GetChildren(const wxDataViewItem &parent,
+ wxDataViewItemArray &array) const override;
+
+ // Is the container just a header or an item with all columns
+ // In our case it is an item with all columns
+ virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; }
+};
+
+
+
+// ----------------------------------------------------------------------------
+// MyCustomRenderer
+// ----------------------------------------------------------------------------
+
+class MyCustomRenderer : public wxDataViewCustomRenderer
+{
+public:
+ // This renderer can be either activatable or editable, for demonstration
+ // purposes. In real programs, you should select whether the user should be
+ // able to activate or edit the cell and it doesn't make sense to switch
+ // between the two -- but this is just an example, so it doesn't stop us.
+ explicit MyCustomRenderer(wxDataViewCellMode mode)
+ : wxDataViewCustomRenderer("string", mode, wxALIGN_CENTER)
+ { }
+
+ virtual bool Render(wxRect rect, wxDC *dc, int state) override/*wxOVERRIDE*/
+ {
+ dc->SetBrush(*wxLIGHT_GREY_BRUSH);
+ dc->SetPen(*wxTRANSPARENT_PEN);
+
+ rect.Deflate(2);
+ dc->DrawRoundedRectangle(rect, 5);
+
+ RenderText(m_value,
+ 0, // no offset
+ wxRect(dc->GetTextExtent(m_value)).CentreIn(rect),
+ dc,
+ state);
+ return true;
+ }
+
+ virtual bool ActivateCell(const wxRect& WXUNUSED(cell),
+ wxDataViewModel *WXUNUSED(model),
+ const wxDataViewItem &WXUNUSED(item),
+ unsigned int WXUNUSED(col),
+ const wxMouseEvent *mouseEvent) override/*wxOVERRIDE*/
+ {
+ wxString position;
+ if (mouseEvent)
+ position = wxString::Format("via mouse at %d, %d", mouseEvent->m_x, mouseEvent->m_y);
+ else
+ position = "from keyboard";
+// wxLogMessage("MyCustomRenderer ActivateCell() %s", position);
+ return false;
+ }
+
+ virtual wxSize GetSize() const override/*wxOVERRIDE*/
+ {
+ return wxSize(60, 20);
+ }
+
+ virtual bool SetValue(const wxVariant &value) override/*wxOVERRIDE*/
+ {
+ m_value = value.GetString();
+ return true;
+ }
+
+ virtual bool GetValue(wxVariant &WXUNUSED(value)) const override/*wxOVERRIDE*/{ return true; }
+
+ virtual bool HasEditorCtrl() const override/*wxOVERRIDE*/{ return true; }
+
+ virtual wxWindow*
+ CreateEditorCtrl(wxWindow* parent,
+ wxRect labelRect,
+ const wxVariant& value) override/*wxOVERRIDE*/
+ {
+ wxTextCtrl* text = new wxTextCtrl(parent, wxID_ANY, value,
+ labelRect.GetPosition(),
+ labelRect.GetSize(),
+ wxTE_PROCESS_ENTER);
+ text->SetInsertionPointEnd();
+
+ return text;
+ }
+
+ virtual bool
+ GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& value) override/*wxOVERRIDE*/
+ {
+ wxTextCtrl* text = wxDynamicCast(ctrl, wxTextCtrl);
+ if (!text)
+ return false;
+
+ value = text->GetValue();
+
+ return true;
+ }
+
+private:
+ wxString m_value;
+};
+
+
+// ----------------------------------------------------------------------------
+// PrusaDoubleSlider
+// ----------------------------------------------------------------------------
+
+enum SelectedSlider {
+ ssUndef,
+ ssLower,
+ ssHigher
+};
+enum TicksAction{
+ taOnIcon,
+ taAdd,
+ taDel
+};
+class PrusaDoubleSlider : public wxControl
+{
+public:
+ PrusaDoubleSlider(
+ wxWindow *parent,
+ wxWindowID id,
+ int lowerValue,
+ int higherValue,
+ int minValue,
+ int maxValue,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxSL_HORIZONTAL,
+ const wxValidator& val = wxDefaultValidator,
+ const wxString& name = wxEmptyString);
+ ~PrusaDoubleSlider(){}
+
+ int GetLowerValue() const {
+ return m_lower_value;
+ }
+ int GetHigherValue() const {
+ return m_higher_value;
+ }
+ int GetActiveValue() const;
+ wxSize DoGetBestSize() const override;
+ void SetLowerValue(const int lower_val);
+ void SetHigherValue(const int higher_val);
+ void SetMaxValue(const int max_value);
+ void SetKoefForLabels(const double koef) {
+ m_label_koef = koef;
+ }
+ void SetSliderValues(const std::vector<std::pair<int, double>>& values) {
+ m_values = values;
+ }
+
+ void OnPaint(wxPaintEvent& ){ render();}
+ void OnLeftDown(wxMouseEvent& event);
+ void OnMotion(wxMouseEvent& event);
+ void OnLeftUp(wxMouseEvent& event);
+ void OnEnterWin(wxMouseEvent& event){ enter_window(event, true); }
+ void OnLeaveWin(wxMouseEvent& event){ enter_window(event, false); }
+ void OnWheel(wxMouseEvent& event);
+ void OnKeyDown(wxKeyEvent &event);
+ void OnKeyUp(wxKeyEvent &event);
+ void OnRightDown(wxMouseEvent& event);
+ void OnRightUp(wxMouseEvent& event);
+
+protected:
+
+ void render();
+ void draw_focus_rect();
+ void draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end);
+ void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos);
+ void draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection);
+ void draw_thumbs(wxDC& dc, const wxCoord& lower_pos, const wxCoord& higher_pos);
+ void draw_ticks(wxDC& dc);
+ void draw_one_layer_icon(wxDC& dc);
+ void draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection);
+ void draw_info_line_with_icon(wxDC& dc, const wxPoint& pos, SelectedSlider selection);
+ void draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const;
+
+ void update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection);
+ void detect_selected_slider(const wxPoint& pt, const bool is_mouse_wheel = false);
+ void correct_lower_value();
+ void correct_higher_value();
+ void move_current_thumb(const bool condition);
+ void action_tick(const TicksAction action);
+ void enter_window(wxMouseEvent& event, const bool enter);
+
+ bool is_point_in_rect(const wxPoint& pt, const wxRect& rect);
+ bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; }
+
+ double get_scroll_step();
+ wxString get_label(const SelectedSlider& selection) const;
+ void get_lower_and_higher_position(int& lower_pos, int& higher_pos);
+ int get_value_from_position(const wxCoord x, const wxCoord y);
+ wxCoord get_position_from_value(const int value);
+ wxSize get_size();
+ void get_size(int *w, int *h);
+
+private:
+ int m_min_value;
+ int m_max_value;
+ int m_lower_value;
+ int m_higher_value;
+ wxBitmap m_bmp_thumb_higher;
+ wxBitmap m_bmp_thumb_lower;
+ wxBitmap m_bmp_add_tick_on;
+ wxBitmap m_bmp_add_tick_off;
+ wxBitmap m_bmp_del_tick_on;
+ wxBitmap m_bmp_del_tick_off;
+ wxBitmap m_bmp_one_layer_lock_on;
+ wxBitmap m_bmp_one_layer_lock_off;
+ wxBitmap m_bmp_one_layer_unlock_on;
+ wxBitmap m_bmp_one_layer_unlock_off;
+ SelectedSlider m_selection;
+ bool m_is_left_down = false;
+ bool m_is_right_down = false;
+ bool m_is_one_layer = false;
+ bool m_is_focused = false;
+ bool m_is_action_icon_focesed = false;
+ bool m_is_one_layer_icon_focesed = false;
+
+ wxRect m_rect_lower_thumb;
+ wxRect m_rect_higher_thumb;
+ wxRect m_rect_tick_action;
+ wxRect m_rect_one_layer_icon;
+ wxSize m_thumb_size;
+ int m_tick_icon_dim;
+ int m_lock_icon_dim;
+ long m_style;
+ float m_label_koef = 1.0;
+
+// control's view variables
+ wxCoord SLIDER_MARGIN; // margin around slider
+
+ wxPen DARK_ORANGE_PEN;
+ wxPen ORANGE_PEN;
+ wxPen LIGHT_ORANGE_PEN;
+
+ wxPen DARK_GREY_PEN;
+ wxPen GREY_PEN;
+ wxPen LIGHT_GREY_PEN;
+
+ std::vector<wxPen*> line_pens;
+ std::vector<wxPen*> segm_pens;
+ std::set<int> m_ticks;
+ std::vector<std::pair<int,double>> m_values;
+};
+
+
+// ----------------------------------------------------------------------------
+// PrusaLockButton
+// ----------------------------------------------------------------------------
+
+class PrusaLockButton : public wxButton
+{
+public:
+ PrusaLockButton(
+ wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize);
+ ~PrusaLockButton(){}
+
+ void OnButton(wxCommandEvent& event);
+ void OnEnterBtn(wxMouseEvent& event){ enter_button(true); event.Skip(); }
+ void OnLeaveBtn(wxMouseEvent& event){ enter_button(false); event.Skip(); }
+
+ bool IsLocked() const { return m_is_pushed; }
+
+protected:
+ void enter_button(const bool enter);
+
+private:
+ bool m_is_pushed = false;
+
+ wxBitmap m_bmp_lock_on;
+ wxBitmap m_bmp_lock_off;
+ wxBitmap m_bmp_unlock_on;
+ wxBitmap m_bmp_unlock_off;
+
+ int m_lock_icon_dim;
+};
+
+
+// ******************************* EXPERIMENTS **********************************************
+// ******************************************************************************************
+
+
#endif // slic3r_GUI_wxExtensions_hpp_
diff --git a/xs/src/slic3r/ProgressIndicator.hpp b/xs/src/slic3r/ProgressIndicator.hpp
new file mode 100644
index 000000000..4a39e84ab
--- /dev/null
+++ b/xs/src/slic3r/ProgressIndicator.hpp
@@ -0,0 +1,71 @@
+#ifndef IPROGRESSINDICATOR_HPP
+#define IPROGRESSINDICATOR_HPP
+
+#include <string>
+#include <functional>
+#include "Strings.hpp"
+
+namespace Slic3r {
+
+/**
+ * @brief Generic progress indication interface.
+ */
+class ProgressIndicator {
+public:
+ using CancelFn = std::function<void(void)>; // Cancel function signature.
+
+private:
+ float state_ = .0f, max_ = 1.f, step_;
+ CancelFn cancelfunc_ = [](){};
+
+public:
+
+ inline virtual ~ProgressIndicator() {}
+
+ /// Get the maximum of the progress range.
+ float max() const { return max_; }
+
+ /// Get the current progress state
+ float state() const { return state_; }
+
+ /// Set the maximum of the progress range
+ virtual void max(float maxval) { max_ = maxval; }
+
+ /// Set the current state of the progress.
+ virtual void state(float val) { state_ = val; }
+
+ /**
+ * @brief Number of states int the progress. Can be used instead of giving a
+ * maximum value.
+ */
+ virtual void states(unsigned statenum) {
+ step_ = max_ / statenum;
+ }
+
+ /// Message shown on the next status update.
+ virtual void message(const string&) = 0;
+
+ /// Title of the operation.
+ virtual void title(const string&) = 0;
+
+ /// Formatted message for the next status update. Works just like sprintf.
+ virtual void message_fmt(const string& fmt, ...);
+
+ /// Set up a cancel callback for the operation if feasible.
+ virtual void on_cancel(CancelFn func = CancelFn()) { cancelfunc_ = func; }
+
+ /**
+ * Explicitly shut down the progress indicator and call the associated
+ * callback.
+ */
+ virtual void cancel() { cancelfunc_(); }
+
+ /// Convenience function to call message and status update in one function.
+ void update(float st, const string& msg) {
+ message(msg); state(st);
+ }
+};
+
+}
+
+#endif // IPROGRESSINDICATOR_HPP
diff --git a/xs/src/slic3r/Strings.hpp b/xs/src/slic3r/Strings.hpp
new file mode 100644
index 000000000..b267fe064
--- /dev/null
+++ b/xs/src/slic3r/Strings.hpp
@@ -0,0 +1,10 @@
+#ifndef STRINGS_HPP
+#define STRINGS_HPP
+
+#include "GUI/GUI.hpp"
+
+namespace Slic3r {
+using string = wxString;
+}
+
+#endif // STRINGS_HPP
diff --git a/xs/src/slic3r/Utils/Duet.cpp b/xs/src/slic3r/Utils/Duet.cpp
new file mode 100644
index 000000000..f25327161
--- /dev/null
+++ b/xs/src/slic3r/Utils/Duet.cpp
@@ -0,0 +1,279 @@
+#include "Duet.hpp"
+#include "PrintHostSendDialog.hpp"
+
+#include <algorithm>
+#include <ctime>
+#include <boost/filesystem/path.hpp>
+#include <boost/format.hpp>
+#include <boost/log/trivial.hpp>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+
+#include <wx/frame.h>
+#include <wx/event.h>
+#include <wx/progdlg.h>
+#include <wx/sizer.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/checkbox.h>
+
+#include "libslic3r/PrintConfig.hpp"
+#include "slic3r/GUI/GUI.hpp"
+#include "slic3r/GUI/MsgDialog.hpp"
+#include "Http.hpp"
+
+namespace fs = boost::filesystem;
+namespace pt = boost::property_tree;
+
+namespace Slic3r {
+
+Duet::Duet(DynamicPrintConfig *config) :
+ host(config->opt_string("print_host")),
+ password(config->opt_string("printhost_apikey"))
+{}
+
+Duet::~Duet() {}
+
+bool Duet::test(wxString &msg) const
+{
+ bool connected = connect(msg);
+ if (connected) {
+ disconnect();
+ }
+
+ return connected;
+}
+
+wxString Duet::get_test_ok_msg () const
+{
+ return wxString::Format("%s", _(L("Connection to Duet works correctly.")));
+}
+
+wxString Duet::get_test_failed_msg (wxString &msg) const
+{
+ return wxString::Format("%s: %s", _(L("Could not connect to Duet")), msg);
+}
+
+bool Duet::send_gcode(const std::string &filename) const
+{
+ enum { PROGRESS_RANGE = 1000 };
+
+ const auto errortitle = _(L("Error while uploading to the Duet"));
+ fs::path filepath(filename);
+
+ PrintHostSendDialog send_dialog(filepath.filename(), true);
+ if (send_dialog.ShowModal() != wxID_OK) { return false; }
+
+ const bool print = send_dialog.print();
+ const auto upload_filepath = send_dialog.filename();
+ const auto upload_filename = upload_filepath.filename();
+ const auto upload_parent_path = upload_filepath.parent_path();
+
+ wxProgressDialog progress_dialog(
+ _(L("Duet upload")),
+ _(L("Sending G-code file to Duet...")),
+ PROGRESS_RANGE, nullptr, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
+ progress_dialog.Pulse();
+
+ wxString connect_msg;
+ if (!connect(connect_msg)) {
+ auto errormsg = wxString::Format("%s: %s", errortitle, connect_msg);
+ GUI::show_error(&progress_dialog, std::move(errormsg));
+ return false;
+ }
+
+ bool res = true;
+
+ auto upload_cmd = get_upload_url(upload_filepath.string());
+ BOOST_LOG_TRIVIAL(info) << boost::format("Duet: Uploading file %1%, filename: %2%, path: %3%, print: %4%, command: %5%")
+ % filepath.string()
+ % upload_filename.string()
+ % upload_parent_path.string()
+ % print
+ % upload_cmd;
+
+ auto http = Http::post(std::move(upload_cmd));
+ http.set_post_body(filename)
+ .on_complete([&](std::string body, unsigned status) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: File uploaded: HTTP %1%: %2%") % status % body;
+ progress_dialog.Update(PROGRESS_RANGE);
+
+ int err_code = get_err_code_from_body(body);
+ if (err_code != 0) {
+ auto msg = format_error(body, L("Unknown error occured"), 0);
+ GUI::show_error(&progress_dialog, std::move(msg));
+ res = false;
+ } else if (print) {
+ wxString errormsg;
+ res = start_print(errormsg, upload_filepath.string());
+ if (!res) {
+ GUI::show_error(&progress_dialog, std::move(errormsg));
+ }
+ }
+ })
+ .on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body;
+ auto errormsg = wxString::Format("%s: %s", errortitle, format_error(body, error, status));
+ GUI::show_error(&progress_dialog, std::move(errormsg));
+ res = false;
+ })
+ .on_progress([&](Http::Progress progress, bool &cancel) {
+ if (cancel) {
+ // Upload was canceled
+ res = false;
+ } else if (progress.ultotal > 0) {
+ int value = PROGRESS_RANGE * progress.ulnow / progress.ultotal;
+ cancel = !progress_dialog.Update(std::min(value, PROGRESS_RANGE - 1)); // Cap the value to prevent premature dialog closing
+ } else {
+ cancel = !progress_dialog.Pulse();
+ }
+ })
+ .perform_sync();
+
+ disconnect();
+
+ return res;
+}
+
+bool Duet::has_auto_discovery() const
+{
+ return false;
+}
+
+bool Duet::can_test() const
+{
+ return true;
+}
+
+bool Duet::connect(wxString &msg) const
+{
+ bool res = false;
+ auto url = get_connect_url();
+
+ auto http = Http::get(std::move(url));
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error connecting: %1%, HTTP %2%, body: `%3%`") % error % status % body;
+ msg = format_error(body, error, status);
+ })
+ .on_complete([&](std::string body, unsigned) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: Got: %1%") % body;
+
+ int err_code = get_err_code_from_body(body);
+ switch (err_code) {
+ case 0:
+ res = true;
+ break;
+ case 1:
+ msg = format_error(body, L("Wrong password"), 0);
+ break;
+ case 2:
+ msg = format_error(body, L("Could not get resources to create a new connection"), 0);
+ break;
+ default:
+ msg = format_error(body, L("Unknown error occured"), 0);
+ break;
+ }
+
+ })
+ .perform_sync();
+
+ return res;
+}
+
+void Duet::disconnect() const
+{
+ auto url = (boost::format("%1%rr_disconnect")
+ % get_base_url()).str();
+
+ auto http = Http::get(std::move(url));
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ // we don't care about it, if disconnect is not working Duet will disconnect automatically after some time
+ BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error disconnecting: %1%, HTTP %2%, body: `%3%`") % error % status % body;
+ })
+ .perform_sync();
+}
+
+std::string Duet::get_upload_url(const std::string &filename) const
+{
+ return (boost::format("%1%rr_upload?name=0:/gcodes/%2%&%3%")
+ % get_base_url()
+ % Http::url_encode(filename)
+ % timestamp_str()).str();
+}
+
+std::string Duet::get_connect_url() const
+{
+ return (boost::format("%1%rr_connect?password=%2%&%3%")
+ % get_base_url()
+ % (password.empty() ? "reprap" : password)
+ % timestamp_str()).str();
+}
+
+std::string Duet::get_base_url() const
+{
+ if (host.find("http://") == 0 || host.find("https://") == 0) {
+ if (host.back() == '/') {
+ return host;
+ } else {
+ return (boost::format("%1%/") % host).str();
+ }
+ } else {
+ return (boost::format("http://%1%/") % host).str();
+ }
+}
+
+std::string Duet::timestamp_str() const
+{
+ enum { BUFFER_SIZE = 32 };
+
+ auto t = std::time(nullptr);
+ auto tm = *std::localtime(&t);
+
+ char buffer[BUFFER_SIZE];
+ std::strftime(buffer, BUFFER_SIZE, "time=%Y-%m-%dT%H:%M:%S", &tm);
+
+ return std::string(buffer);
+}
+
+wxString Duet::format_error(const std::string &body, const std::string &error, unsigned status)
+{
+ if (status != 0) {
+ auto wxbody = wxString::FromUTF8(body.data());
+ return wxString::Format("HTTP %u: %s", status, wxbody);
+ } else {
+ return wxString::FromUTF8(error.data());
+ }
+}
+
+bool Duet::start_print(wxString &msg, const std::string &filename) const
+{
+ bool res = false;
+
+ auto url = (boost::format("%1%rr_gcode?gcode=M32%%20\"%2%\"")
+ % get_base_url()
+ % Http::url_encode(filename)).str();
+
+ auto http = Http::get(std::move(url));
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Duet: Error starting print: %1%, HTTP %2%, body: `%3%`") % error % status % body;
+ msg = format_error(body, error, status);
+ })
+ .on_complete([&](std::string body, unsigned) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("Duet: Got: %1%") % body;
+ res = true;
+ })
+ .perform_sync();
+
+ return res;
+}
+
+int Duet::get_err_code_from_body(const std::string &body) const
+{
+ pt::ptree root;
+ std::istringstream iss (body); // wrap returned json to istringstream
+ pt::read_json(iss, root);
+
+ return root.get<int>("err", 0);
+}
+
+}
diff --git a/xs/src/slic3r/Utils/Duet.hpp b/xs/src/slic3r/Utils/Duet.hpp
new file mode 100644
index 000000000..bc210d7a4
--- /dev/null
+++ b/xs/src/slic3r/Utils/Duet.hpp
@@ -0,0 +1,47 @@
+#ifndef slic3r_Duet_hpp_
+#define slic3r_Duet_hpp_
+
+#include <string>
+#include <wx/string.h>
+
+#include "PrintHost.hpp"
+
+
+namespace Slic3r {
+
+
+class DynamicPrintConfig;
+class Http;
+
+class Duet : public PrintHost
+{
+public:
+ Duet(DynamicPrintConfig *config);
+ virtual ~Duet();
+
+ bool test(wxString &curl_msg) const;
+ wxString get_test_ok_msg () const;
+ wxString get_test_failed_msg (wxString &msg) const;
+ // Send gcode file to duet, filename is expected to be in UTF-8
+ bool send_gcode(const std::string &filename) const;
+ bool has_auto_discovery() const;
+ bool can_test() const;
+private:
+ std::string host;
+ std::string password;
+
+ std::string get_upload_url(const std::string &filename) const;
+ std::string get_connect_url() const;
+ std::string get_base_url() const;
+ std::string timestamp_str() const;
+ bool connect(wxString &msg) const;
+ void disconnect() const;
+ bool start_print(wxString &msg, const std::string &filename) const;
+ int get_err_code_from_body(const std::string &body) const;
+ static wxString format_error(const std::string &body, const std::string &error, unsigned status);
+};
+
+
+}
+
+#endif
diff --git a/xs/src/slic3r/Utils/FixModelByWin10.cpp b/xs/src/slic3r/Utils/FixModelByWin10.cpp
new file mode 100644
index 000000000..556035a5b
--- /dev/null
+++ b/xs/src/slic3r/Utils/FixModelByWin10.cpp
@@ -0,0 +1,402 @@
+#ifdef HAS_WIN10SDK
+
+#ifndef NOMINMAX
+# define NOMINMAX
+#endif
+
+#include "FixModelByWin10.hpp"
+
+#include <atomic>
+#include <chrono>
+#include <cstdint>
+#include <condition_variable>
+#include <exception>
+#include <string>
+#include <thread>
+
+#include <boost/filesystem.hpp>
+#include <boost/nowide/convert.hpp>
+#include <boost/nowide/cstdio.hpp>
+
+#include <roapi.h>
+// for ComPtr
+#include <wrl/client.h>
+// from C:/Program Files (x86)/Windows Kits/10/Include/10.0.17134.0/
+#include <winrt/robuffer.h>
+#include <winrt/windows.storage.provider.h>
+#include <winrt/windows.graphics.printing3d.h>
+
+#include "libslic3r/Model.hpp"
+#include "libslic3r/Print.hpp"
+#include "libslic3r/Format/3mf.hpp"
+#include "../GUI/GUI.hpp"
+#include "../GUI/PresetBundle.hpp"
+
+#include <wx/msgdlg.h>
+#include <wx/progdlg.h>
+
+extern "C"{
+ // from rapi.h
+ typedef HRESULT (__stdcall* FunctionRoInitialize)(int);
+ typedef HRESULT (__stdcall* FunctionRoUninitialize)();
+ typedef HRESULT (__stdcall* FunctionRoActivateInstance)(HSTRING activatableClassId, IInspectable **instance);
+ typedef HRESULT (__stdcall* FunctionRoGetActivationFactory)(HSTRING activatableClassId, REFIID iid, void **factory);
+ // from winstring.h
+ typedef HRESULT (__stdcall* FunctionWindowsCreateString)(LPCWSTR sourceString, UINT32 length, HSTRING *string);
+ typedef HRESULT (__stdcall* FunctionWindowsDelteString)(HSTRING string);
+}
+
+namespace Slic3r {
+
+HMODULE s_hRuntimeObjectLibrary = nullptr;
+FunctionRoInitialize s_RoInitialize = nullptr;
+FunctionRoUninitialize s_RoUninitialize = nullptr;
+FunctionRoActivateInstance s_RoActivateInstance = nullptr;
+FunctionRoGetActivationFactory s_RoGetActivationFactory = nullptr;
+FunctionWindowsCreateString s_WindowsCreateString = nullptr;
+FunctionWindowsDelteString s_WindowsDeleteString = nullptr;
+
+bool winrt_load_runtime_object_library()
+{
+ if (s_hRuntimeObjectLibrary == nullptr)
+ s_hRuntimeObjectLibrary = LoadLibrary(L"ComBase.dll");
+ if (s_hRuntimeObjectLibrary != nullptr) {
+ s_RoInitialize = (FunctionRoInitialize) GetProcAddress(s_hRuntimeObjectLibrary, "RoInitialize");
+ s_RoUninitialize = (FunctionRoUninitialize) GetProcAddress(s_hRuntimeObjectLibrary, "RoUninitialize");
+ s_RoActivateInstance = (FunctionRoActivateInstance) GetProcAddress(s_hRuntimeObjectLibrary, "RoActivateInstance");
+ s_RoGetActivationFactory = (FunctionRoGetActivationFactory) GetProcAddress(s_hRuntimeObjectLibrary, "RoGetActivationFactory");
+ s_WindowsCreateString = (FunctionWindowsCreateString) GetProcAddress(s_hRuntimeObjectLibrary, "WindowsCreateString");
+ s_WindowsDeleteString = (FunctionWindowsDelteString) GetProcAddress(s_hRuntimeObjectLibrary, "WindowsDeleteString");
+ }
+ return s_RoInitialize && s_RoUninitialize && s_RoActivateInstance && s_WindowsCreateString && s_WindowsDeleteString;
+}
+
+static HRESULT winrt_activate_instance(const std::wstring &class_name, IInspectable **pinst)
+{
+ HSTRING hClassName;
+ HRESULT hr = (*s_WindowsCreateString)(class_name.c_str(), class_name.size(), &hClassName);
+ if (S_OK != hr)
+ return hr;
+ hr = (*s_RoActivateInstance)(hClassName, pinst);
+ (*s_WindowsDeleteString)(hClassName);
+ return hr;
+}
+
+template<typename TYPE>
+static HRESULT winrt_activate_instance(const std::wstring &class_name, TYPE **pinst)
+{
+ IInspectable *pinspectable = nullptr;
+ HRESULT hr = winrt_activate_instance(class_name, &pinspectable);
+ if (S_OK != hr)
+ return hr;
+ hr = pinspectable->QueryInterface(__uuidof(TYPE), (void**)pinst);
+ pinspectable->Release();
+ return hr;
+}
+
+static HRESULT winrt_get_activation_factory(const std::wstring &class_name, REFIID iid, void **pinst)
+{
+ HSTRING hClassName;
+ HRESULT hr = (*s_WindowsCreateString)(class_name.c_str(), class_name.size(), &hClassName);
+ if (S_OK != hr)
+ return hr;
+ hr = (*s_RoGetActivationFactory)(hClassName, iid, pinst);
+ (*s_WindowsDeleteString)(hClassName);
+ return hr;
+}
+
+template<typename TYPE>
+static HRESULT winrt_get_activation_factory(const std::wstring &class_name, TYPE **pinst)
+{
+ return winrt_get_activation_factory(class_name, __uuidof(TYPE), reinterpret_cast<void**>(pinst));
+}
+
+// To be called often to test whether to cancel the operation.
+typedef std::function<void ()> ThrowOnCancelFn;
+
+template<typename T>
+static AsyncStatus winrt_async_await(const Microsoft::WRL::ComPtr<T> &asyncAction, ThrowOnCancelFn throw_on_cancel, int blocking_tick_ms = 100)
+{
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> asyncInfo;
+ asyncAction.As(&asyncInfo);
+ AsyncStatus status;
+ // Ugly blocking loop until the RepairAsync call finishes.
+//FIXME replace with a callback.
+// https://social.msdn.microsoft.com/Forums/en-US/a5038fb4-b7b7-4504-969d-c102faa389fb/trying-to-block-an-async-operation-and-wait-for-a-particular-time?forum=vclanguage
+ for (;;) {
+ asyncInfo->get_Status(&status);
+ if (status != AsyncStatus::Started)
+ return status;
+ throw_on_cancel();
+ ::Sleep(blocking_tick_ms);
+ }
+}
+
+static HRESULT winrt_open_file_stream(
+ const std::wstring &path,
+ ABI::Windows::Storage::FileAccessMode mode,
+ ABI::Windows::Storage::Streams::IRandomAccessStream **fileStream,
+ ThrowOnCancelFn throw_on_cancel)
+{
+ // Get the file factory.
+ Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFileStatics> fileFactory;
+ HRESULT hr = winrt_get_activation_factory(L"Windows.Storage.StorageFile", fileFactory.GetAddressOf());
+ if (FAILED(hr)) return hr;
+
+ // Open the file asynchronously.
+ HSTRING hstr_path;
+ hr = (*s_WindowsCreateString)(path.c_str(), path.size(), &hstr_path);
+ if (FAILED(hr)) return hr;
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Storage::StorageFile*>> fileOpenAsync;
+ hr = fileFactory->GetFileFromPathAsync(hstr_path, fileOpenAsync.GetAddressOf());
+ if (FAILED(hr)) return hr;
+ (*s_WindowsDeleteString)(hstr_path);
+
+ // Wait until the file gets open, get the actual file.
+ AsyncStatus status = winrt_async_await(fileOpenAsync, throw_on_cancel);
+ Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFile> storageFile;
+ if (status == AsyncStatus::Completed) {
+ hr = fileOpenAsync->GetResults(storageFile.GetAddressOf());
+ } else {
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> asyncInfo;
+ hr = fileOpenAsync.As(&asyncInfo);
+ if (FAILED(hr)) return hr;
+ HRESULT err;
+ hr = asyncInfo->get_ErrorCode(&err);
+ return FAILED(hr) ? hr : err;
+ }
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Storage::Streams::IRandomAccessStream*>> fileStreamAsync;
+ hr = storageFile->OpenAsync(mode, fileStreamAsync.GetAddressOf());
+ if (FAILED(hr)) return hr;
+
+ status = winrt_async_await(fileStreamAsync, throw_on_cancel);
+ if (status == AsyncStatus::Completed) {
+ hr = fileStreamAsync->GetResults(fileStream);
+ } else {
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncInfo> asyncInfo;
+ hr = fileStreamAsync.As(&asyncInfo);
+ if (FAILED(hr)) return hr;
+ HRESULT err;
+ hr = asyncInfo->get_ErrorCode(&err);
+ if (!FAILED(hr))
+ hr = err;
+ }
+ return hr;
+}
+
+bool is_windows10()
+{
+ HKEY hKey;
+ LONG lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey);
+ if (lRes == ERROR_SUCCESS) {
+ WCHAR szBuffer[512];
+ DWORD dwBufferSize = sizeof(szBuffer);
+ lRes = RegQueryValueExW(hKey, L"ProductName", 0, nullptr, (LPBYTE)szBuffer, &dwBufferSize);
+ if (lRes == ERROR_SUCCESS)
+ return wcsncmp(szBuffer, L"Windows 10", 10) == 0;
+ RegCloseKey(hKey);
+ }
+ return false;
+}
+
+// Progress function, to be called regularly to update the progress.
+typedef std::function<void (const char * /* message */, unsigned /* progress */)> ProgressFn;
+
+void fix_model_by_win10_sdk(const std::string &path_src, const std::string &path_dst, ProgressFn on_progress, ThrowOnCancelFn throw_on_cancel)
+{
+ if (! is_windows10())
+ throw std::runtime_error("fix_model_by_win10_sdk called on non Windows 10 system");
+
+ if (! winrt_load_runtime_object_library())
+ throw std::runtime_error("Failed to initialize the WinRT library.");
+
+ HRESULT hr = (*s_RoInitialize)(RO_INIT_MULTITHREADED);
+ {
+ on_progress(L("Exporting the source model"), 20);
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IRandomAccessStream> fileStream;
+ hr = winrt_open_file_stream(boost::nowide::widen(path_src), ABI::Windows::Storage::FileAccessMode::FileAccessMode_Read, fileStream.GetAddressOf(), throw_on_cancel);
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Graphics::Printing3D::IPrinting3D3MFPackage> printing3d3mfpackage;
+ hr = winrt_activate_instance(L"Windows.Graphics.Printing3D.Printing3D3MFPackage", printing3d3mfpackage.GetAddressOf());
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Graphics::Printing3D::Printing3DModel*>> modelAsync;
+ hr = printing3d3mfpackage->LoadModelFromPackageAsync(fileStream.Get(), modelAsync.GetAddressOf());
+
+ AsyncStatus status = winrt_async_await(modelAsync, throw_on_cancel);
+ Microsoft::WRL::ComPtr<ABI::Windows::Graphics::Printing3D::IPrinting3DModel> model;
+ if (status == AsyncStatus::Completed)
+ hr = modelAsync->GetResults(model.GetAddressOf());
+ else
+ throw std::runtime_error(L("Failed loading the input model."));
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Collections::IVector<ABI::Windows::Graphics::Printing3D::Printing3DMesh*>> meshes;
+ hr = model->get_Meshes(meshes.GetAddressOf());
+ unsigned num_meshes = 0;
+ hr = meshes->get_Size(&num_meshes);
+
+ on_progress(L("Repairing the model by the Netfabb service"), 40);
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncAction> repairAsync;
+ hr = model->RepairAsync(repairAsync.GetAddressOf());
+ status = winrt_async_await(repairAsync, throw_on_cancel);
+ if (status != AsyncStatus::Completed)
+ throw std::runtime_error(L("Mesh repair failed."));
+ repairAsync->GetResults();
+
+ on_progress(L("Loading the repaired model"), 60);
+
+ // Verify the number of meshes returned after the repair action.
+ meshes.Reset();
+ hr = model->get_Meshes(meshes.GetAddressOf());
+ hr = meshes->get_Size(&num_meshes);
+
+ // Save model to this class' Printing3D3MFPackage.
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncAction> saveToPackageAsync;
+ hr = printing3d3mfpackage->SaveModelToPackageAsync(model.Get(), saveToPackageAsync.GetAddressOf());
+ status = winrt_async_await(saveToPackageAsync, throw_on_cancel);
+ if (status != AsyncStatus::Completed)
+ throw std::runtime_error(L("Saving mesh into the 3MF container failed."));
+ hr = saveToPackageAsync->GetResults();
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Storage::Streams::IRandomAccessStream*>> generatorStreamAsync;
+ hr = printing3d3mfpackage->SaveAsync(generatorStreamAsync.GetAddressOf());
+ status = winrt_async_await(generatorStreamAsync, throw_on_cancel);
+ if (status != AsyncStatus::Completed)
+ throw std::runtime_error(L("Saving mesh into the 3MF container failed."));
+ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IRandomAccessStream> generatorStream;
+ hr = generatorStreamAsync->GetResults(generatorStream.GetAddressOf());
+
+ // Go to the beginning of the stream.
+ generatorStream->Seek(0);
+ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IInputStream> inputStream;
+ hr = generatorStream.As(&inputStream);
+
+ // Get the buffer factory.
+ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBufferFactory> bufferFactory;
+ hr = winrt_get_activation_factory(L"Windows.Storage.Streams.Buffer", bufferFactory.GetAddressOf());
+
+ // Open the destination file.
+ FILE *fout = boost::nowide::fopen(path_dst.c_str(), "wb");
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> buffer;
+ byte *buffer_ptr;
+ bufferFactory->Create(65536 * 2048, buffer.GetAddressOf());
+ {
+ Microsoft::WRL::ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess;
+ buffer.As(&bufferByteAccess);
+ hr = bufferByteAccess->Buffer(&buffer_ptr);
+ }
+ uint32_t length;
+ hr = buffer->get_Length(&length);
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer*, UINT32>> asyncRead;
+ for (;;) {
+ hr = inputStream->ReadAsync(buffer.Get(), 65536 * 2048, ABI::Windows::Storage::Streams::InputStreamOptions_ReadAhead, asyncRead.GetAddressOf());
+ status = winrt_async_await(asyncRead, throw_on_cancel);
+ if (status != AsyncStatus::Completed)
+ throw std::runtime_error(L("Saving mesh into the 3MF container failed."));
+ hr = buffer->get_Length(&length);
+ if (length == 0)
+ break;
+ fwrite(buffer_ptr, length, 1, fout);
+ }
+ fclose(fout);
+ // Here all the COM objects will be released through the ComPtr destructors.
+ }
+ (*s_RoUninitialize)();
+}
+
+class RepairCanceledException : public std::exception {
+public:
+ const char* what() const throw() { return "Model repair has been canceled"; }
+};
+
+void fix_model_by_win10_sdk_gui(const ModelObject &model_object, const Print &print, Model &result)
+{
+ std::mutex mutex;
+ std::condition_variable condition;
+ std::unique_lock<std::mutex> lock(mutex);
+ struct Progress {
+ std::string message;
+ int percent = 0;
+ bool updated = false;
+ } progress;
+ std::atomic<bool> canceled = false;
+ std::atomic<bool> finished = false;
+
+ // Open a progress dialog.
+ wxProgressDialog progress_dialog(
+ _(L("Model fixing")),
+ _(L("Exporting model...")),
+ 100, nullptr, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
+ // Executing the calculation in a background thread, so that the COM context could be created with its own threading model.
+ // (It seems like wxWidgets initialize the COM contex as single threaded and we need a multi-threaded context).
+ bool success = false;
+ auto on_progress = [&mutex, &condition, &progress](const char *msg, unsigned prcnt) {
+ std::lock_guard<std::mutex> lk(mutex);
+ progress.message = msg;
+ progress.percent = prcnt;
+ progress.updated = true;
+ condition.notify_all();
+ };
+ auto worker_thread = boost::thread([&model_object, &print, &result, on_progress, &success, &canceled, &finished]() {
+ try {
+ on_progress(L("Exporting the source model"), 0);
+ boost::filesystem::path path_src = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
+ path_src += ".3mf";
+ Model model;
+ model.add_object(model_object);
+ if (! Slic3r::store_3mf(path_src.string().c_str(), &model, const_cast<Print*>(&print), false)) {
+ boost::filesystem::remove(path_src);
+ throw std::runtime_error(L("Export of a temporary 3mf file failed"));
+ }
+ model.clear_objects();
+ model.clear_materials();
+ boost::filesystem::path path_dst = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
+ path_dst += ".3mf";
+ fix_model_by_win10_sdk(path_src.string().c_str(), path_dst.string(), on_progress,
+ [&canceled]() { if (canceled) throw RepairCanceledException(); });
+ boost::filesystem::remove(path_src);
+ PresetBundle bundle;
+ on_progress(L("Loading the repaired model"), 80);
+ bool loaded = Slic3r::load_3mf(path_dst.string().c_str(), &bundle, &result);
+ boost::filesystem::remove(path_dst);
+ if (! loaded)
+ throw std::runtime_error(L("Import of the repaired 3mf file failed"));
+ success = true;
+ finished = true;
+ on_progress(L("Model repair finished"), 100);
+ } catch (RepairCanceledException &ex) {
+ canceled = true;
+ finished = true;
+ on_progress(L("Model repair canceled"), 100);
+ } catch (std::exception &ex) {
+ success = false;
+ finished = true;
+ on_progress(ex.what(), 100);
+ }
+ });
+ while (! finished) {
+ condition.wait_for(lock, std::chrono::milliseconds(500), [&progress]{ return progress.updated; });
+ if (! progress_dialog.Update(progress.percent, _(progress.message)))
+ canceled = true;
+ progress.updated = false;
+ }
+
+ if (canceled) {
+ // Nothing to show.
+ } else if (success) {
+ wxMessageDialog dlg(nullptr, _(L("Model repaired successfully")), _(L("Model Repair by the Netfabb service")), wxICON_INFORMATION | wxOK_DEFAULT);
+ dlg.ShowModal();
+ } else {
+ wxMessageDialog dlg(nullptr, _(L("Model repair failed: \n")) + _(progress.message), _(L("Model Repair by the Netfabb service")), wxICON_ERROR | wxOK_DEFAULT);
+ dlg.ShowModal();
+ }
+ worker_thread.join();
+}
+
+} // namespace Slic3r
+
+#endif /* HAS_WIN10SDK */
diff --git a/xs/src/slic3r/Utils/FixModelByWin10.hpp b/xs/src/slic3r/Utils/FixModelByWin10.hpp
new file mode 100644
index 000000000..c148a6970
--- /dev/null
+++ b/xs/src/slic3r/Utils/FixModelByWin10.hpp
@@ -0,0 +1,26 @@
+#ifndef slic3r_GUI_Utils_FixModelByWin10_hpp_
+#define slic3r_GUI_Utils_FixModelByWin10_hpp_
+
+#include <string>
+
+namespace Slic3r {
+
+class Model;
+class ModelObject;
+class Print;
+
+#ifdef HAS_WIN10SDK
+
+extern bool is_windows10();
+extern void fix_model_by_win10_sdk_gui(const ModelObject &model_object, const Print &print, Model &result);
+
+#else /* HAS_WIN10SDK */
+
+inline bool is_windows10() { return false; }
+inline void fix_model_by_win10_sdk_gui(const ModelObject &, const Print &, Model &) {}
+
+#endif /* HAS_WIN10SDK */
+
+} // namespace Slic3r
+
+#endif /* slic3r_GUI_Utils_FixModelByWin10_hpp_ */
diff --git a/xs/src/slic3r/Utils/HexFile.cpp b/xs/src/slic3r/Utils/HexFile.cpp
new file mode 100644
index 000000000..282c647bd
--- /dev/null
+++ b/xs/src/slic3r/Utils/HexFile.cpp
@@ -0,0 +1,106 @@
+#include "HexFile.hpp"
+
+#include <sstream>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/ini_parser.hpp>
+
+namespace fs = boost::filesystem;
+namespace pt = boost::property_tree;
+
+
+namespace Slic3r {
+namespace Utils {
+
+
+static HexFile::DeviceKind parse_device_kind(const std::string &str)
+{
+ if (str == "mk2") { return HexFile::DEV_MK2; }
+ else if (str == "mk3") { return HexFile::DEV_MK3; }
+ else if (str == "mm-control") { return HexFile::DEV_MM_CONTROL; }
+ else { return HexFile::DEV_GENERIC; }
+}
+
+static size_t hex_num_sections(fs::ifstream &file)
+{
+ file.seekg(0);
+ if (! file.good()) {
+ return 0;
+ }
+
+ static const char *hex_terminator = ":00000001FF\r";
+ size_t res = 0;
+ std::string line;
+ while (getline(file, line, '\n').good()) {
+ // Account for LF vs CRLF
+ if (!line.empty() && line.back() != '\r') {
+ line.push_back('\r');
+ }
+
+ if (line == hex_terminator) {
+ res++;
+ }
+ }
+
+ return res;
+}
+
+HexFile::HexFile(fs::path path) :
+ path(std::move(path))
+{
+ fs::ifstream file(this->path);
+ if (! file.good()) {
+ return;
+ }
+
+ std::string line;
+ std::stringstream header_ini;
+ while (std::getline(file, line, '\n').good()) {
+ if (line.empty()) {
+ continue;
+ }
+
+ // Account for LF vs CRLF
+ if (!line.empty() && line.back() == '\r') {
+ line.pop_back();
+ }
+
+ if (line.front() == ';') {
+ line.front() = ' ';
+ header_ini << line << std::endl;
+ } else if (line.front() == ':') {
+ break;
+ }
+ }
+
+ pt::ptree ptree;
+ try {
+ pt::read_ini(header_ini, ptree);
+ } catch (std::exception &e) {
+ return;
+ }
+
+ bool has_device_meta = false;
+ const auto device = ptree.find("device");
+ if (device != ptree.not_found()) {
+ this->device = parse_device_kind(device->second.data());
+ has_device_meta = true;
+ }
+
+ const auto model_id = ptree.find("model_id");
+ if (model_id != ptree.not_found()) {
+ this->model_id = model_id->second.data();
+ }
+
+ if (! has_device_meta) {
+ // No device metadata, look at the number of 'sections'
+ if (hex_num_sections(file) == 2) {
+ // Looks like a pre-metadata l10n firmware for the MK3, assume that's the case
+ this->device = DEV_MK3;
+ }
+ }
+}
+
+
+}
+}
diff --git a/xs/src/slic3r/Utils/HexFile.hpp b/xs/src/slic3r/Utils/HexFile.hpp
new file mode 100644
index 000000000..1201d23a4
--- /dev/null
+++ b/xs/src/slic3r/Utils/HexFile.hpp
@@ -0,0 +1,33 @@
+#ifndef slic3r_Hex_hpp_
+#define slic3r_Hex_hpp_
+
+#include <string>
+#include <boost/filesystem/path.hpp>
+
+
+namespace Slic3r {
+namespace Utils {
+
+
+struct HexFile
+{
+ enum DeviceKind {
+ DEV_GENERIC,
+ DEV_MK2,
+ DEV_MK3,
+ DEV_MM_CONTROL,
+ };
+
+ boost::filesystem::path path;
+ DeviceKind device = DEV_GENERIC;
+ std::string model_id;
+
+ HexFile() {}
+ HexFile(boost::filesystem::path path);
+};
+
+
+}
+}
+
+#endif
diff --git a/xs/src/slic3r/Utils/Http.cpp b/xs/src/slic3r/Utils/Http.cpp
index de28904e2..9b67ceea8 100644
--- a/xs/src/slic3r/Utils/Http.cpp
+++ b/xs/src/slic3r/Utils/Http.cpp
@@ -3,13 +3,17 @@
#include <cstdlib>
#include <functional>
#include <thread>
-#include <tuple>
+#include <deque>
+#include <sstream>
+#include <boost/filesystem/fstream.hpp>
#include <boost/format.hpp>
#include <curl/curl.h>
#include "../../libslic3r/libslic3r.h"
+namespace fs = boost::filesystem;
+
namespace Slic3r {
@@ -34,18 +38,32 @@ struct Http::priv
::curl_httppost *form;
::curl_httppost *form_end;
::curl_slist *headerlist;
+ // Used for reading the body
std::string buffer;
+ // Used for storing file streams added as multipart form parts
+ // Using a deque here because unlike vector it doesn't ivalidate pointers on insertion
+ std::deque<fs::ifstream> form_files;
+ std::string postfields;
size_t limit;
+ bool cancel;
std::thread io_thread;
Http::CompleteFn completefn;
Http::ErrorFn errorfn;
+ Http::ProgressFn progressfn;
priv(const std::string &url);
~priv();
static bool ca_file_supported(::CURL *curl);
static size_t writecb(void *data, size_t size, size_t nmemb, void *userp);
+ static int xfercb(void *userp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
+ static int xfercb_legacy(void *userp, double dltotal, double dlnow, double ultotal, double ulnow);
+ static size_t form_file_read_cb(char *buffer, size_t size, size_t nitems, void *userp);
+
+ void form_add_file(const char *name, const fs::path &path, const char* filename);
+ void set_post_body(const fs::path &path);
+
std::string curl_error(CURLcode curlcode);
std::string body_size_error();
void http_perform();
@@ -55,7 +73,9 @@ Http::priv::priv(const std::string &url) :
curl(::curl_easy_init()),
form(nullptr),
form_end(nullptr),
- headerlist(nullptr)
+ headerlist(nullptr),
+ limit(0),
+ cancel(false)
{
if (curl == nullptr) {
throw std::runtime_error(std::string("Could not construct Curl object"));
@@ -112,6 +132,71 @@ size_t Http::priv::writecb(void *data, size_t size, size_t nmemb, void *userp)
return realsize;
}
+int Http::priv::xfercb(void *userp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
+{
+ auto self = static_cast<priv*>(userp);
+ bool cb_cancel = false;
+
+ if (self->progressfn) {
+ Progress progress(dltotal, dlnow, ultotal, ulnow);
+ self->progressfn(progress, cb_cancel);
+ }
+
+ return self->cancel || cb_cancel;
+}
+
+int Http::priv::xfercb_legacy(void *userp, double dltotal, double dlnow, double ultotal, double ulnow)
+{
+ return xfercb(userp, dltotal, dlnow, ultotal, ulnow);
+}
+
+size_t Http::priv::form_file_read_cb(char *buffer, size_t size, size_t nitems, void *userp)
+{
+ auto stream = reinterpret_cast<fs::ifstream*>(userp);
+
+ try {
+ stream->read(buffer, size * nitems);
+ } catch (...) {
+ return CURL_READFUNC_ABORT;
+ }
+
+ return stream->gcount();
+}
+
+void Http::priv::form_add_file(const char *name, const fs::path &path, const char* filename)
+{
+ // We can't use CURLFORM_FILECONTENT, because curl doesn't support Unicode filenames on Windows
+ // and so we use CURLFORM_STREAM with boost ifstream to read the file.
+
+ if (filename == nullptr) {
+ filename = path.string().c_str();
+ }
+
+ form_files.emplace_back(path, std::ios::in | std::ios::binary);
+ auto &stream = form_files.back();
+ stream.seekg(0, std::ios::end);
+ size_t size = stream.tellg();
+ stream.seekg(0);
+
+ if (filename != nullptr) {
+ ::curl_formadd(&form, &form_end,
+ CURLFORM_COPYNAME, name,
+ CURLFORM_FILENAME, filename,
+ CURLFORM_CONTENTTYPE, "application/octet-stream",
+ CURLFORM_STREAM, static_cast<void*>(&stream),
+ CURLFORM_CONTENTSLENGTH, static_cast<long>(size),
+ CURLFORM_END
+ );
+ }
+}
+
+void Http::priv::set_post_body(const fs::path &path)
+{
+ std::ifstream file(path.string());
+ std::string file_content { std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>() };
+ postfields = file_content;
+}
+
std::string Http::priv::curl_error(CURLcode curlcode)
{
return (boost::format("%1% (%2%)")
@@ -127,10 +212,20 @@ std::string Http::priv::body_size_error()
void Http::priv::http_perform()
{
- ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecb);
::curl_easy_setopt(curl, CURLOPT_WRITEDATA, static_cast<void*>(this));
+ ::curl_easy_setopt(curl, CURLOPT_READFUNCTION, form_file_read_cb);
+
+ ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
+#if LIBCURL_VERSION_MAJOR >= 7 && LIBCURL_VERSION_MINOR >= 32
+ ::curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xfercb);
+ ::curl_easy_setopt(curl, CURLOPT_XFERINFODATA, static_cast<void*>(this));
+ (void)xfercb_legacy; // prevent unused function warning
+#else
+ ::curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, xfercb);
+ ::curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, static_cast<void*>(this));
+#endif
#ifndef NDEBUG
::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
@@ -144,24 +239,38 @@ void Http::priv::http_perform()
::curl_easy_setopt(curl, CURLOPT_HTTPPOST, form);
}
+ if (!postfields.empty()) {
+ ::curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postfields.c_str());
+ ::curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, postfields.size());
+ }
+
CURLcode res = ::curl_easy_perform(curl);
- long http_status = 0;
- ::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status);
if (res != CURLE_OK) {
- std::string error;
- if (res == CURLE_WRITE_ERROR) {
- error = std::move(body_size_error());
+ if (res == CURLE_ABORTED_BY_CALLBACK) {
+ if (cancel) {
+ // The abort comes from the request being cancelled programatically
+ Progress dummyprogress(0, 0, 0, 0);
+ bool cancel = true;
+ if (progressfn) { progressfn(dummyprogress, cancel); }
+ } else {
+ // The abort comes from the CURLOPT_READFUNCTION callback, which means reading file failed
+ if (errorfn) { errorfn(std::move(buffer), "Error reading file for file upload", 0); }
+ }
+ }
+ else if (res == CURLE_WRITE_ERROR) {
+ if (errorfn) { errorfn(std::move(buffer), body_size_error(), 0); }
} else {
- error = std::move(curl_error(res));
+ if (errorfn) { errorfn(std::move(buffer), curl_error(res), 0); }
};
-
- if (errorfn) {
- errorfn(std::move(buffer), std::move(error), http_status);
- }
} else {
- if (completefn) {
- completefn(std::move(buffer), http_status);
+ long http_status = 0;
+ ::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_status);
+
+ if (http_status >= 400) {
+ if (errorfn) { errorfn(std::move(buffer), std::string(), http_status); }
+ } else {
+ if (completefn) { completefn(std::move(buffer), http_status); }
}
}
}
@@ -232,17 +341,21 @@ Http& Http::form_add(const std::string &name, const std::string &contents)
return *this;
}
-Http& Http::form_add_file(const std::string &name, const std::string &filename)
+Http& Http::form_add_file(const std::string &name, const fs::path &path)
{
- if (p) {
- ::curl_formadd(&p->form, &p->form_end,
- CURLFORM_COPYNAME, name.c_str(),
- CURLFORM_FILE, filename.c_str(),
- CURLFORM_CONTENTTYPE, "application/octet-stream",
- CURLFORM_END
- );
- }
+ if (p) { p->form_add_file(name.c_str(), path.c_str(), nullptr); }
+ return *this;
+}
+Http& Http::form_add_file(const std::string &name, const fs::path &path, const std::string &filename)
+{
+ if (p) { p->form_add_file(name.c_str(), path.c_str(), filename.c_str()); }
+ return *this;
+}
+
+Http& Http::set_post_body(const fs::path &path)
+{
+ if (p) { p->set_post_body(path);}
return *this;
}
@@ -258,6 +371,12 @@ Http& Http::on_error(ErrorFn fn)
return *this;
}
+Http& Http::on_progress(ProgressFn fn)
+{
+ if (p) { p->progressfn = std::move(fn); }
+ return *this;
+}
+
Http::Ptr Http::perform()
{
auto self = std::make_shared<Http>(std::move(*this));
@@ -277,6 +396,11 @@ void Http::perform_sync()
if (p) { p->http_perform(); }
}
+void Http::cancel()
+{
+ if (p) { p->cancel = true; }
+}
+
Http Http::get(std::string url)
{
return std::move(Http{std::move(url)});
@@ -297,5 +421,31 @@ bool Http::ca_file_supported()
return res;
}
+std::string Http::url_encode(const std::string &str)
+{
+ ::CURL *curl = ::curl_easy_init();
+ if (curl == nullptr) {
+ return str;
+ }
+ char *ce = ::curl_easy_escape(curl, str.c_str(), str.length());
+ std::string encoded = std::string(ce);
+
+ ::curl_free(ce);
+ ::curl_easy_cleanup(curl);
+
+ return encoded;
+}
+
+std::ostream& operator<<(std::ostream &os, const Http::Progress &progress)
+{
+ os << "Http::Progress("
+ << "dltotal = " << progress.dltotal
+ << ", dlnow = " << progress.dlnow
+ << ", ultotal = " << progress.ultotal
+ << ", ulnow = " << progress.ulnow
+ << ")";
+ return os;
+}
+
}
diff --git a/xs/src/slic3r/Utils/Http.hpp b/xs/src/slic3r/Utils/Http.hpp
index 6ac5fcce1..44580b7ea 100644
--- a/xs/src/slic3r/Utils/Http.hpp
+++ b/xs/src/slic3r/Utils/Http.hpp
@@ -4,6 +4,7 @@
#include <memory>
#include <string>
#include <functional>
+#include <boost/filesystem/path.hpp>
namespace Slic3r {
@@ -14,12 +15,38 @@ class Http : public std::enable_shared_from_this<Http> {
private:
struct priv;
public:
+ struct Progress
+ {
+ size_t dltotal; // Total bytes to download
+ size_t dlnow; // Bytes downloaded so far
+ size_t ultotal; // Total bytes to upload
+ size_t ulnow; // Bytes uploaded so far
+
+ Progress(size_t dltotal, size_t dlnow, size_t ultotal, size_t ulnow) :
+ dltotal(dltotal), dlnow(dlnow), ultotal(ultotal), ulnow(ulnow)
+ {}
+ };
+
typedef std::shared_ptr<Http> Ptr;
typedef std::function<void(std::string /* body */, unsigned /* http_status */)> CompleteFn;
+
+ // A HTTP request may fail at various stages of completeness (URL parsing, DNS lookup, TCP connection, ...).
+ // If the HTTP request could not be made or failed before completion, the `error` arg contains a description
+ // of the error and `http_status` is zero.
+ // If the HTTP request was completed but the response HTTP code is >= 400, `error` is empty and `http_status` contains the response code.
+ // In either case there may or may not be a body.
typedef std::function<void(std::string /* body */, std::string /* error */, unsigned /* http_status */)> ErrorFn;
+ // See the Progress struct above.
+ // Writing true to the `cancel` reference cancels the request in progress.
+ typedef std::function<void(Progress, bool& /* cancel */)> ProgressFn;
+
Http(Http &&other);
+ // Note: strings are expected to be UTF-8-encoded
+
+ // These are the primary constructors that create a HTTP object
+ // for a GET and a POST request respectively.
static Http get(std::string url);
static Http post(std::string url);
~Http();
@@ -28,26 +55,60 @@ public:
Http& operator=(const Http &) = delete;
Http& operator=(Http &&) = delete;
+ // Sets a maximum size of the data that can be received.
+ // A value of zero sets the default limit, which is is 5MB.
Http& size_limit(size_t sizeLimit);
+ // Sets a HTTP header field.
Http& header(std::string name, const std::string &value);
+ // Removes a header field.
Http& remove_header(std::string name);
+ // Sets a CA certificate file for usage with HTTPS. This is only supported on some backends,
+ // specifically, this is supported with OpenSSL and NOT supported with Windows and OS X native certificate store.
+ // See also ca_file_supported().
Http& ca_file(const std::string &filename);
+ // Add a HTTP multipart form field
Http& form_add(const std::string &name, const std::string &contents);
- Http& form_add_file(const std::string &name, const std::string &filename);
+ // Add a HTTP multipart form file data contents, `name` is the name of the part
+ Http& form_add_file(const std::string &name, const boost::filesystem::path &path);
+ // Same as above except also override the file's filename with a custom one
+ Http& form_add_file(const std::string &name, const boost::filesystem::path &path, const std::string &filename);
+ // Set the file contents as a POST request body.
+ // The data is used verbatim, it is not additionally encoded in any way.
+ // This can be used for hosts which do not support multipart requests.
+ Http& set_post_body(const boost::filesystem::path &path);
+
+ // Callback called on HTTP request complete
Http& on_complete(CompleteFn fn);
+ // Callback called on an error occuring at any stage of the requests: Url parsing, DNS lookup,
+ // TCP connection, HTTP transfer, and finally also when the response indicates an error (status >= 400).
+ // Therefore, a response body may or may not be present.
Http& on_error(ErrorFn fn);
+ // Callback called on data download/upload prorgess (called fairly frequently).
+ // See the `Progress` structure for description of the data passed.
+ // Writing a true-ish value into the cancel reference parameter cancels the request.
+ Http& on_progress(ProgressFn fn);
+ // Starts performing the request in a background thread
Ptr perform();
+ // Starts performing the request on the current thread
void perform_sync();
+ // Cancels a request in progress
+ void cancel();
+ // Tells whether current backend supports seting up a CA file using ca_file()
static bool ca_file_supported();
+
+ // converts the given string to an url_encoded_string
+ static std::string url_encode(const std::string &str);
private:
Http(const std::string &url);
std::unique_ptr<priv> p;
};
+std::ostream& operator<<(std::ostream &, const Http::Progress &);
+
}
diff --git a/xs/src/slic3r/Utils/OctoPrint.cpp b/xs/src/slic3r/Utils/OctoPrint.cpp
index 5bf51f470..db86d7697 100644
--- a/xs/src/slic3r/Utils/OctoPrint.cpp
+++ b/xs/src/slic3r/Utils/OctoPrint.cpp
@@ -1,74 +1,140 @@
#include "OctoPrint.hpp"
+#include "PrintHostSendDialog.hpp"
-#include <iostream>
+#include <algorithm>
#include <boost/format.hpp>
-
-#include <wx/frame.h>
-#include <wx/event.h>
+#include <boost/log/trivial.hpp>
#include "libslic3r/PrintConfig.hpp"
-#include "slic3r/GUI/GUI.hpp"
#include "Http.hpp"
+namespace fs = boost::filesystem;
-namespace Slic3r {
+namespace Slic3r {
OctoPrint::OctoPrint(DynamicPrintConfig *config) :
- host(config->opt_string("octoprint_host")),
- apikey(config->opt_string("octoprint_apikey")),
- cafile(config->opt_string("octoprint_cafile"))
+ host(config->opt_string("print_host")),
+ apikey(config->opt_string("printhost_apikey")),
+ cafile(config->opt_string("printhost_cafile"))
{}
+OctoPrint::~OctoPrint() {}
+
bool OctoPrint::test(wxString &msg) const
{
// Since the request is performed synchronously here,
// it is ok to refer to `msg` from within the closure
bool res = true;
+ auto url = make_url("api/version");
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("Octoprint: Get version at: %1%") % url;
- auto url = std::move(make_url("api/version"));
auto http = Http::get(std::move(url));
set_auth(http);
- http.on_error([&](std::string, std::string error, unsigned status) {
+ http.on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Octoprint: Error getting version: %1%, HTTP %2%, body: `%3%`") % error % status % body;
res = false;
- msg = format_error(error, status);
+ msg = format_error(body, error, status);
+ })
+ .on_complete([&](std::string body, unsigned) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("Octoprint: Got version: %1%") % body;
})
.perform_sync();
return res;
}
-void OctoPrint::send_gcode(int windowId, int completeEvt, int errorEvt, const std::string &filename, bool print) const
+wxString OctoPrint::get_test_ok_msg () const
{
- auto http = Http::post(std::move(make_url("api/files/local")));
+ return wxString::Format("%s", _(L("Connection to OctoPrint works correctly.")));
+}
+
+wxString OctoPrint::get_test_failed_msg (wxString &msg) const
+{
+ return wxString::Format("%s: %s\n\n%s",
+ _(L("Could not connect to OctoPrint")), msg, _(L("Note: OctoPrint version at least 1.1.0 is required.")));
+}
+
+bool OctoPrint::send_gcode(const std::string &filename) const
+{
+ enum { PROGRESS_RANGE = 1000 };
+
+ const auto errortitle = _(L("Error while uploading to the OctoPrint server"));
+ fs::path filepath(filename);
+
+ PrintHostSendDialog send_dialog(filepath.filename(), true);
+ if (send_dialog.ShowModal() != wxID_OK) { return false; }
+
+ const bool print = send_dialog.print();
+ const auto upload_filepath = send_dialog.filename();
+ const auto upload_filename = upload_filepath.filename();
+ const auto upload_parent_path = upload_filepath.parent_path();
+
+ wxProgressDialog progress_dialog(
+ _(L("OctoPrint upload")),
+ _(L("Sending G-code file to the OctoPrint server...")),
+ PROGRESS_RANGE, nullptr, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
+ progress_dialog.Pulse();
+
+ wxString test_msg;
+ if (!test(test_msg)) {
+ auto errormsg = wxString::Format("%s: %s", errortitle, test_msg);
+ GUI::show_error(&progress_dialog, std::move(errormsg));
+ return false;
+ }
+
+ bool res = true;
+
+ auto url = make_url("api/files/local");
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("Octoprint: Uploading file %1% at %2%, filename: %3%, path: %4%, print: %5%")
+ % filepath.string()
+ % url
+ % upload_filename.string()
+ % upload_parent_path.string()
+ % print;
+
+ auto http = Http::post(std::move(url));
set_auth(http);
http.form_add("print", print ? "true" : "false")
- .form_add_file("file", filename)
- .on_complete([=](std::string body, unsigned status) {
- wxWindow *window = wxWindow::FindWindowById(windowId);
- if (window == nullptr) { return; }
-
- wxCommandEvent* evt = new wxCommandEvent(completeEvt);
- evt->SetString(_(L("G-code file successfully uploaded to the OctoPrint server")));
- evt->SetInt(100);
- wxQueueEvent(window, evt);
+ .form_add("path", upload_parent_path.string())
+ .form_add_file("file", filename, upload_filename.string())
+ .on_complete([&](std::string body, unsigned status) {
+ BOOST_LOG_TRIVIAL(debug) << boost::format("Octoprint: File uploaded: HTTP %1%: %2%") % status % body;
+ progress_dialog.Update(PROGRESS_RANGE);
+ })
+ .on_error([&](std::string body, std::string error, unsigned status) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("Octoprint: Error uploading file: %1%, HTTP %2%, body: `%3%`") % error % status % body;
+ auto errormsg = wxString::Format("%s: %s", errortitle, format_error(body, error, status));
+ GUI::show_error(&progress_dialog, std::move(errormsg));
+ res = false;
})
- .on_error([=](std::string body, std::string error, unsigned status) {
- wxWindow *window = wxWindow::FindWindowById(windowId);
- if (window == nullptr) { return; }
-
- wxCommandEvent* evt_complete = new wxCommandEvent(completeEvt);
- evt_complete->SetInt(100);
- wxQueueEvent(window, evt_complete);
-
- wxCommandEvent* evt_error = new wxCommandEvent(errorEvt);
- evt_error->SetString(wxString::Format("%s: %s",
- _(L("Error while uploading to the OctoPrint server")),
- format_error(error, status)));
- wxQueueEvent(window, evt_error);
+ .on_progress([&](Http::Progress progress, bool &cancel) {
+ if (cancel) {
+ // Upload was canceled
+ res = false;
+ } else if (progress.ultotal > 0) {
+ int value = PROGRESS_RANGE * progress.ulnow / progress.ultotal;
+ cancel = !progress_dialog.Update(std::min(value, PROGRESS_RANGE - 1)); // Cap the value to prevent premature dialog closing
+ } else {
+ cancel = !progress_dialog.Pulse();
+ }
})
- .perform();
+ .perform_sync();
+
+ return res;
+}
+
+bool OctoPrint::has_auto_discovery() const
+{
+ return true;
+}
+
+bool OctoPrint::can_test() const
+{
+ return true;
}
void OctoPrint::set_auth(Http &http) const
@@ -84,24 +150,22 @@ std::string OctoPrint::make_url(const std::string &path) const
{
if (host.find("http://") == 0 || host.find("https://") == 0) {
if (host.back() == '/') {
- return std::move((boost::format("%1%%2%") % host % path).str());
+ return (boost::format("%1%%2%") % host % path).str();
} else {
- return std::move((boost::format("%1%/%2%") % host % path).str());
+ return (boost::format("%1%/%2%") % host % path).str();
}
} else {
- return std::move((boost::format("http://%1%/%2%") % host % path).str());
+ return (boost::format("http://%1%/%2%") % host % path).str();
}
}
-wxString OctoPrint::format_error(std::string error, unsigned status)
+wxString OctoPrint::format_error(const std::string &body, const std::string &error, unsigned status)
{
- const wxString wxerror = error;
-
if (status != 0) {
- return wxString::Format("HTTP %u: %s", status,
- (status == 401 ? _(L("Invalid API key")) : wxerror));
+ auto wxbody = wxString::FromUTF8(body.data());
+ return wxString::Format("HTTP %u: %s", status, wxbody);
} else {
- return std::move(wxerror);
+ return wxString::FromUTF8(error.data());
}
}
diff --git a/xs/src/slic3r/Utils/OctoPrint.hpp b/xs/src/slic3r/Utils/OctoPrint.hpp
index 1f544295c..f6c4d58c8 100644
--- a/xs/src/slic3r/Utils/OctoPrint.hpp
+++ b/xs/src/slic3r/Utils/OctoPrint.hpp
@@ -4,6 +4,8 @@
#include <string>
#include <wx/string.h>
+#include "PrintHost.hpp"
+
namespace Slic3r {
@@ -11,13 +13,19 @@ namespace Slic3r {
class DynamicPrintConfig;
class Http;
-class OctoPrint
+class OctoPrint : public PrintHost
{
public:
OctoPrint(DynamicPrintConfig *config);
+ virtual ~OctoPrint();
bool test(wxString &curl_msg) const;
- void send_gcode(int windowId, int completeEvt, int errorEvt, const std::string &filename, bool print = false) const;
+ wxString get_test_ok_msg () const;
+ wxString get_test_failed_msg (wxString &msg) const;
+ // Send gcode file to octoprint, filename is expected to be in UTF-8
+ bool send_gcode(const std::string &filename) const;
+ bool has_auto_discovery() const;
+ bool can_test() const;
private:
std::string host;
std::string apikey;
@@ -25,7 +33,7 @@ private:
void set_auth(Http &http) const;
std::string make_url(const std::string &path) const;
- static wxString format_error(std::string error, unsigned status);
+ static wxString format_error(const std::string &body, const std::string &error, unsigned status);
};
diff --git a/xs/src/slic3r/Utils/PresetUpdater.cpp b/xs/src/slic3r/Utils/PresetUpdater.cpp
new file mode 100644
index 000000000..2e423dc5e
--- /dev/null
+++ b/xs/src/slic3r/Utils/PresetUpdater.cpp
@@ -0,0 +1,633 @@
+#include "PresetUpdater.hpp"
+
+#include <algorithm>
+#include <thread>
+#include <unordered_map>
+#include <ostream>
+#include <stdexcept>
+#include <boost/format.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/log/trivial.hpp>
+
+#include <wx/app.h>
+#include <wx/event.h>
+#include <wx/msgdlg.h>
+
+#include "libslic3r/libslic3r.h"
+#include "libslic3r/Utils.hpp"
+#include "slic3r/GUI/GUI.hpp"
+#include "slic3r/GUI/PresetBundle.hpp"
+#include "slic3r/GUI/UpdateDialogs.hpp"
+#include "slic3r/GUI/ConfigWizard.hpp"
+#include "slic3r/Utils/Http.hpp"
+#include "slic3r/Config/Version.hpp"
+#include "slic3r/Config/Snapshot.hpp"
+
+namespace fs = boost::filesystem;
+using Slic3r::GUI::Config::Index;
+using Slic3r::GUI::Config::Version;
+using Slic3r::GUI::Config::Snapshot;
+using Slic3r::GUI::Config::SnapshotDB;
+
+
+namespace Slic3r {
+
+
+enum {
+ SLIC3R_VERSION_BODY_MAX = 256,
+};
+
+static const char *INDEX_FILENAME = "index.idx";
+static const char *TMP_EXTENSION = ".download";
+
+
+struct Update
+{
+ fs::path source;
+ fs::path target;
+ Version version;
+
+ Update(fs::path &&source, fs::path &&target, const Version &version) :
+ source(std::move(source)),
+ target(std::move(target)),
+ version(version)
+ {}
+
+ std::string name() const { return source.stem().string(); }
+
+ friend std::ostream& operator<<(std::ostream& os , const Update &self) {
+ os << "Update(" << self.source.string() << " -> " << self.target.string() << ')';
+ return os;
+ }
+};
+
+struct Incompat
+{
+ fs::path bundle;
+ Version version;
+
+ Incompat(fs::path &&bundle, const Version &version) :
+ bundle(std::move(bundle)),
+ version(version)
+ {}
+
+ std::string name() const { return bundle.stem().string(); }
+
+ friend std::ostream& operator<<(std::ostream& os , const Incompat &self) {
+ os << "Incompat(" << self.bundle.string() << ')';
+ return os;
+ }
+};
+
+struct Updates
+{
+ std::vector<Incompat> incompats;
+ std::vector<Update> updates;
+};
+
+
+struct PresetUpdater::priv
+{
+ int version_online_event;
+ std::vector<Index> index_db;
+
+ bool enabled_version_check;
+ bool enabled_config_update;
+ std::string version_check_url;
+ bool had_config_update;
+
+ fs::path cache_path;
+ fs::path rsrc_path;
+ fs::path vendor_path;
+
+ bool cancel;
+ std::thread thread;
+
+ priv(int version_online_event);
+
+ void set_download_prefs(AppConfig *app_config);
+ bool get_file(const std::string &url, const fs::path &target_path) const;
+ void prune_tmps() const;
+ void sync_version() const;
+ void sync_config(const std::set<VendorProfile> vendors) const;
+
+ void check_install_indices() const;
+ Updates get_config_updates() const;
+ void perform_updates(Updates &&updates, bool snapshot = true) const;
+
+ static void copy_file(const fs::path &from, const fs::path &to);
+};
+
+PresetUpdater::priv::priv(int version_online_event) :
+ version_online_event(version_online_event),
+ had_config_update(false),
+ cache_path(fs::path(Slic3r::data_dir()) / "cache"),
+ rsrc_path(fs::path(resources_dir()) / "profiles"),
+ vendor_path(fs::path(Slic3r::data_dir()) / "vendor"),
+ cancel(false)
+{
+ set_download_prefs(GUI::get_app_config());
+ check_install_indices();
+ index_db = std::move(Index::load_db());
+}
+
+// Pull relevant preferences from AppConfig
+void PresetUpdater::priv::set_download_prefs(AppConfig *app_config)
+{
+ enabled_version_check = app_config->get("version_check") == "1";
+ version_check_url = app_config->version_check_url();
+ enabled_config_update = app_config->get("preset_update") == "1" && !app_config->legacy_datadir();
+}
+
+// Downloads a file (http get operation). Cancels if the Updater is being destroyed.
+bool PresetUpdater::priv::get_file(const std::string &url, const fs::path &target_path) const
+{
+ bool res = false;
+ fs::path tmp_path = target_path;
+ tmp_path += (boost::format(".%1%%2%") % get_current_pid() % TMP_EXTENSION).str();
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("Get: `%1%`\n\t-> `%2%`\n\tvia tmp path `%3%`")
+ % url
+ % target_path.string()
+ % tmp_path.string();
+
+ Http::get(url)
+ .on_progress([this](Http::Progress, bool &cancel) {
+ if (cancel) { cancel = true; }
+ })
+ .on_error([&](std::string body, std::string error, unsigned http_status) {
+ (void)body;
+ BOOST_LOG_TRIVIAL(error) << boost::format("Error getting: `%1%`: HTTP %2%, %3%")
+ % url
+ % http_status
+ % error;
+ })
+ .on_complete([&](std::string body, unsigned /* http_status */) {
+ fs::fstream file(tmp_path, std::ios::out | std::ios::binary | std::ios::trunc);
+ file.write(body.c_str(), body.size());
+ file.close();
+ fs::rename(tmp_path, target_path);
+ res = true;
+ })
+ .perform_sync();
+
+ return res;
+}
+
+// Remove leftover paritally downloaded files, if any.
+void PresetUpdater::priv::prune_tmps() const
+{
+ for (fs::directory_iterator it(cache_path); it != fs::directory_iterator(); ++it) {
+ if (it->path().extension() == TMP_EXTENSION) {
+ BOOST_LOG_TRIVIAL(debug) << "Cache prune: " << it->path().string();
+ fs::remove(it->path());
+ }
+ }
+}
+
+// Get Slic3rPE version available online, save in AppConfig.
+void PresetUpdater::priv::sync_version() const
+{
+ if (! enabled_version_check) { return; }
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("Downloading Slic3rPE online version from: `%1%`") % version_check_url;
+
+ Http::get(version_check_url)
+ .size_limit(SLIC3R_VERSION_BODY_MAX)
+ .on_progress([this](Http::Progress, bool &cancel) {
+ cancel = this->cancel;
+ })
+ .on_error([&](std::string body, std::string error, unsigned http_status) {
+ (void)body;
+ BOOST_LOG_TRIVIAL(error) << boost::format("Error getting: `%1%`: HTTP %2%, %3%")
+ % version_check_url
+ % http_status
+ % error;
+ })
+ .on_complete([&](std::string body, unsigned /* http_status */) {
+ boost::trim(body);
+ BOOST_LOG_TRIVIAL(info) << boost::format("Got Slic3rPE online version: `%1%`. Sending to GUI thread...") % body;
+ wxCommandEvent* evt = new wxCommandEvent(version_online_event);
+ evt->SetString(body);
+ GUI::get_app()->QueueEvent(evt);
+ })
+ .perform_sync();
+}
+
+// Download vendor indices. Also download new bundles if an index indicates there's a new one available.
+// Both are saved in cache.
+void PresetUpdater::priv::sync_config(const std::set<VendorProfile> vendors) const
+{
+ BOOST_LOG_TRIVIAL(info) << "Syncing configuration cache";
+
+ if (!enabled_config_update) { return; }
+
+ // Donwload vendor preset bundles
+ for (const auto &index : index_db) {
+ if (cancel) { return; }
+
+ const auto vendor_it = vendors.find(VendorProfile(index.vendor()));
+ if (vendor_it == vendors.end()) {
+ BOOST_LOG_TRIVIAL(warning) << "No such vendor: " << index.vendor();
+ continue;
+ }
+
+ const VendorProfile &vendor = *vendor_it;
+ if (vendor.config_update_url.empty()) {
+ BOOST_LOG_TRIVIAL(info) << "Vendor has no config_update_url: " << vendor.name;
+ continue;
+ }
+
+ // Download a fresh index
+ BOOST_LOG_TRIVIAL(info) << "Downloading index for vendor: " << vendor.name;
+ const auto idx_url = vendor.config_update_url + "/" + INDEX_FILENAME;
+ const auto idx_path = cache_path / (vendor.id + ".idx");
+ if (! get_file(idx_url, idx_path)) { continue; }
+ if (cancel) { return; }
+
+ // Load the fresh index up
+ Index new_index;
+ new_index.load(idx_path);
+
+ // See if a there's a new version to download
+ const auto recommended_it = new_index.recommended();
+ if (recommended_it == new_index.end()) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("No recommended version for vendor: %1%, invalid index?") % vendor.name;
+ continue;
+ }
+ const auto recommended = recommended_it->config_version;
+
+ BOOST_LOG_TRIVIAL(debug) << boost::format("Got index for vendor: %1%: current version: %2%, recommended version: %3%")
+ % vendor.name
+ % vendor.config_version.to_string()
+ % recommended.to_string();
+
+ if (vendor.config_version >= recommended) { continue; }
+
+ // Download a fresh bundle
+ BOOST_LOG_TRIVIAL(info) << "Downloading new bundle for vendor: " << vendor.name;
+ const auto bundle_url = (boost::format("%1%/%2%.ini") % vendor.config_update_url % recommended.to_string()).str();
+ const auto bundle_path = cache_path / (vendor.id + ".ini");
+ if (! get_file(bundle_url, bundle_path)) { continue; }
+ if (cancel) { return; }
+ }
+}
+
+// Install indicies from resources. Only installs those that are either missing or older than in resources.
+void PresetUpdater::priv::check_install_indices() const
+{
+ BOOST_LOG_TRIVIAL(info) << "Checking if indices need to be installed from resources...";
+
+ for (fs::directory_iterator it(rsrc_path); it != fs::directory_iterator(); ++it) {
+ const auto &path = it->path();
+ if (path.extension() == ".idx") {
+ const auto path_in_cache = cache_path / path.filename();
+
+ if (! fs::exists(path_in_cache)) {
+ BOOST_LOG_TRIVIAL(info) << "Install index from resources: " << path.filename();
+ copy_file(path, path_in_cache);
+ } else {
+ Index idx_rsrc, idx_cache;
+ idx_rsrc.load(path);
+ idx_cache.load(path_in_cache);
+
+ if (idx_cache.version() < idx_rsrc.version()) {
+ BOOST_LOG_TRIVIAL(info) << "Update index from resources: " << path.filename();
+ copy_file(path, path_in_cache);
+ }
+ }
+ }
+ }
+}
+
+// Generates a list of bundle updates that are to be performed
+Updates PresetUpdater::priv::get_config_updates() const
+{
+ Updates updates;
+
+ BOOST_LOG_TRIVIAL(info) << "Checking for cached configuration updates...";
+
+ for (const auto idx : index_db) {
+ auto bundle_path = vendor_path / (idx.vendor() + ".ini");
+
+ if (! fs::exists(bundle_path)) {
+ BOOST_LOG_TRIVIAL(info) << "Bundle not present for index, skipping: " << idx.vendor();
+ continue;
+ }
+
+ // Perform a basic load and check the version
+ const auto vp = VendorProfile::from_ini(bundle_path, false);
+
+ const auto ver_current = idx.find(vp.config_version);
+ if (ver_current == idx.end()) {
+ auto message = (boost::format("Preset bundle `%1%` version not found in index: %2%") % idx.vendor() % vp.config_version.to_string()).str();
+ BOOST_LOG_TRIVIAL(error) << message;
+ throw std::runtime_error(message);
+ }
+
+ // Getting a recommended version from the latest index, wich may have been downloaded
+ // from the internet, or installed / updated from the installation resources.
+ const auto recommended = idx.recommended();
+ if (recommended == idx.end()) {
+ BOOST_LOG_TRIVIAL(error) << boost::format("No recommended version for vendor: %1%, invalid index?") % idx.vendor();
+ }
+
+ BOOST_LOG_TRIVIAL(debug) << boost::format("Vendor: %1%, version installed: %2%, version cached: %3%")
+ % vp.name
+ % ver_current->config_version.to_string()
+ % recommended->config_version.to_string();
+
+ if (! ver_current->is_current_slic3r_supported()) {
+ BOOST_LOG_TRIVIAL(warning) << "Current Slic3r incompatible with installed bundle: " << bundle_path.string();
+ updates.incompats.emplace_back(std::move(bundle_path), *ver_current);
+ } else if (recommended->config_version > ver_current->config_version) {
+ // Config bundle update situation
+
+ // Check if the update is already present in a snapshot
+ const auto recommended_snap = SnapshotDB::singleton().snapshot_with_vendor_preset(vp.name, recommended->config_version);
+ if (recommended_snap != SnapshotDB::singleton().end()) {
+ BOOST_LOG_TRIVIAL(info) << boost::format("Bundle update %1% %2% already found in snapshot %3%, skipping...")
+ % vp.name
+ % recommended->config_version.to_string()
+ % recommended_snap->id;
+ continue;
+ }
+
+ auto path_src = cache_path / (idx.vendor() + ".ini");
+ auto path_in_rsrc = rsrc_path / (idx.vendor() + ".ini");
+ if (! fs::exists(path_src)) {
+ if (! fs::exists(path_in_rsrc)) {
+ BOOST_LOG_TRIVIAL(warning) << boost::format("Index for vendor %1% indicates update, but bundle found in neither cache nor resources")
+ % idx.vendor();
+ continue;
+ } else {
+ path_src = std::move(path_in_rsrc);
+ path_in_rsrc.clear();
+ }
+ }
+
+ auto new_vp = VendorProfile::from_ini(path_src, false);
+ bool found = false;
+ if (new_vp.config_version == recommended->config_version) {
+ updates.updates.emplace_back(std::move(path_src), std::move(bundle_path), *recommended);
+ found = true;
+ } else if (! path_in_rsrc.empty() && fs::exists(path_in_rsrc)) {
+ new_vp = VendorProfile::from_ini(path_in_rsrc, false);
+ if (new_vp.config_version == recommended->config_version) {
+ updates.updates.emplace_back(std::move(path_in_rsrc), std::move(bundle_path), *recommended);
+ found = true;
+ }
+ }
+ if (! found)
+ BOOST_LOG_TRIVIAL(warning) << boost::format("Index for vendor %1% indicates update (%2%) but the new bundle was found neither in cache nor resources")
+ % idx.vendor()
+ % recommended->config_version.to_string();
+ }
+ }
+
+ return updates;
+}
+
+void PresetUpdater::priv::perform_updates(Updates &&updates, bool snapshot) const
+{
+ if (updates.incompats.size() > 0) {
+ if (snapshot) {
+ BOOST_LOG_TRIVIAL(info) << "Taking a snapshot...";
+ SnapshotDB::singleton().take_snapshot(*GUI::get_app_config(), Snapshot::SNAPSHOT_DOWNGRADE);
+ }
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("Deleting %1% incompatible bundles") % updates.incompats.size();
+
+ for (const auto &incompat : updates.incompats) {
+ BOOST_LOG_TRIVIAL(info) << '\t' << incompat;
+ fs::remove(incompat.bundle);
+ }
+ }
+ else if (updates.updates.size() > 0) {
+ if (snapshot) {
+ BOOST_LOG_TRIVIAL(info) << "Taking a snapshot...";
+ SnapshotDB::singleton().take_snapshot(*GUI::get_app_config(), Snapshot::SNAPSHOT_UPGRADE);
+ }
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("Performing %1% updates") % updates.updates.size();
+
+ for (const auto &update : updates.updates) {
+ BOOST_LOG_TRIVIAL(info) << '\t' << update;
+
+ copy_file(update.source, update.target);
+
+ PresetBundle bundle;
+ bundle.load_configbundle(update.target.string(), PresetBundle::LOAD_CFGBNDLE_SYSTEM);
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("Deleting %1% conflicting presets")
+ % (bundle.prints.size() + bundle.filaments.size() + bundle.printers.size());
+
+ auto preset_remover = [](const Preset &preset) {
+ BOOST_LOG_TRIVIAL(info) << '\t' << preset.file;
+ fs::remove(preset.file);
+ };
+
+ for (const auto &preset : bundle.prints) { preset_remover(preset); }
+ for (const auto &preset : bundle.filaments) { preset_remover(preset); }
+ for (const auto &preset : bundle.printers) { preset_remover(preset); }
+
+ // Also apply the `obsolete_presets` property, removing obsolete ini files
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("Deleting %1% obsolete presets")
+ % (bundle.obsolete_presets.prints.size() + bundle.obsolete_presets.filaments.size() + bundle.obsolete_presets.printers.size());
+
+ auto obsolete_remover = [](const char *subdir, const std::string &preset) {
+ auto path = fs::path(Slic3r::data_dir()) / subdir / preset;
+ path += ".ini";
+ BOOST_LOG_TRIVIAL(info) << '\t' << path.string();
+ fs::remove(path);
+ };
+
+ for (const auto &name : bundle.obsolete_presets.prints) { obsolete_remover("print", name); }
+ for (const auto &name : bundle.obsolete_presets.filaments) { obsolete_remover("filament", name); }
+ for (const auto &name : bundle.obsolete_presets.filaments) { obsolete_remover("sla_material", name); }
+ for (const auto &name : bundle.obsolete_presets.printers) { obsolete_remover("printer", name); }
+ }
+ }
+}
+
+void PresetUpdater::priv::copy_file(const fs::path &source, const fs::path &target)
+{
+ static const auto perms = fs::owner_read | fs::owner_write | fs::group_read | fs::others_read; // aka 644
+
+ // Make sure the file has correct permission both before and after we copy over it
+ if (fs::exists(target)) {
+ fs::permissions(target, perms);
+ }
+ fs::copy_file(source, target, fs::copy_option::overwrite_if_exists);
+ fs::permissions(target, perms);
+}
+
+
+PresetUpdater::PresetUpdater(int version_online_event) :
+ p(new priv(version_online_event))
+{}
+
+
+// Public
+
+PresetUpdater::~PresetUpdater()
+{
+ if (p && p->thread.joinable()) {
+ // This will stop transfers being done by the thread, if any.
+ // Cancelling takes some time, but should complete soon enough.
+ p->cancel = true;
+ p->thread.join();
+ }
+}
+
+void PresetUpdater::sync(PresetBundle *preset_bundle)
+{
+ p->set_download_prefs(GUI::get_app_config());
+ if (!p->enabled_version_check && !p->enabled_config_update) { return; }
+
+ // Copy the whole vendors data for use in the background thread
+ // Unfortunatelly as of C++11, it needs to be copied again
+ // into the closure (but perhaps the compiler can elide this).
+ std::set<VendorProfile> vendors = preset_bundle->vendors;
+
+ p->thread = std::move(std::thread([this, vendors]() {
+ this->p->prune_tmps();
+ this->p->sync_version();
+ this->p->sync_config(std::move(vendors));
+ }));
+}
+
+void PresetUpdater::slic3r_update_notify()
+{
+ if (! p->enabled_version_check) { return; }
+
+ if (p->had_config_update) {
+ BOOST_LOG_TRIVIAL(info) << "New Slic3r version available, but there was a configuration update, notification won't be displayed";
+ return;
+ }
+
+ auto* app_config = GUI::get_app_config();
+ const auto ver_slic3r = Semver::parse(SLIC3R_VERSION);
+ const auto ver_online_str = app_config->get("version_online");
+ const auto ver_online = Semver::parse(ver_online_str);
+ const auto ver_online_seen = Semver::parse(app_config->get("version_online_seen"));
+ if (! ver_slic3r) {
+ throw std::runtime_error("Could not parse Slic3r version string: " SLIC3R_VERSION);
+ }
+
+ if (ver_online) {
+ // Only display the notification if the version available online is newer AND if we haven't seen it before
+ if (*ver_online > *ver_slic3r && (! ver_online_seen || *ver_online_seen < *ver_online)) {
+ GUI::MsgUpdateSlic3r notification(*ver_slic3r, *ver_online);
+ notification.ShowModal();
+ if (notification.disable_version_check()) {
+ app_config->set("version_check", "0");
+ p->enabled_version_check = false;
+ }
+ }
+ app_config->set("version_online_seen", ver_online_str);
+ }
+}
+
+bool PresetUpdater::config_update() const
+{
+ if (! p->enabled_config_update) { return true; }
+
+ auto updates = p->get_config_updates();
+ if (updates.incompats.size() > 0) {
+ BOOST_LOG_TRIVIAL(info) << boost::format("%1% bundles incompatible. Asking for action...") % updates.incompats.size();
+
+ std::unordered_map<std::string, wxString> incompats_map;
+ for (const auto &incompat : updates.incompats) {
+ auto vendor = incompat.name();
+
+ const auto min_slic3r = incompat.version.min_slic3r_version;
+ const auto max_slic3r = incompat.version.max_slic3r_version;
+ wxString restrictions;
+ if (min_slic3r != Semver::zero() && max_slic3r != Semver::inf()) {
+ restrictions = wxString::Format(_(L("requires min. %s and max. %s")),
+ min_slic3r.to_string(),
+ max_slic3r.to_string()
+ );
+ } else if (min_slic3r != Semver::zero()) {
+ restrictions = wxString::Format(_(L("requires min. %s")), min_slic3r.to_string());
+ } else {
+ restrictions = wxString::Format(_(L("requires max. %s")), max_slic3r.to_string());
+ }
+
+ incompats_map.emplace(std::make_pair(std::move(vendor), std::move(restrictions)));
+ }
+
+ p->had_config_update = true; // This needs to be done before a dialog is shown because of OnIdle() + CallAfter() in Perl
+
+ GUI::MsgDataIncompatible dlg(std::move(incompats_map));
+ const auto res = dlg.ShowModal();
+ if (res == wxID_REPLACE) {
+ BOOST_LOG_TRIVIAL(info) << "User wants to re-configure...";
+ p->perform_updates(std::move(updates));
+ GUI::ConfigWizard wizard(nullptr, GUI::ConfigWizard::RR_DATA_INCOMPAT);
+ if (! wizard.run(GUI::get_preset_bundle(), this)) {
+ return false;
+ }
+ GUI::load_current_presets();
+ } else {
+ BOOST_LOG_TRIVIAL(info) << "User wants to exit Slic3r, bye...";
+ return false;
+ }
+ }
+ else if (updates.updates.size() > 0) {
+ BOOST_LOG_TRIVIAL(info) << boost::format("Update of %1% bundles available. Asking for confirmation ...") % updates.updates.size();
+
+ std::unordered_map<std::string, std::string> updates_map;
+ for (const auto &update : updates.updates) {
+ auto vendor = update.name();
+ auto ver_str = update.version.config_version.to_string();
+ if (! update.version.comment.empty()) {
+ ver_str += std::string(" (") + update.version.comment + ")";
+ }
+ updates_map.emplace(std::make_pair(std::move(vendor), std::move(ver_str)));
+ }
+
+ p->had_config_update = true; // Ditto, see above
+
+ GUI::MsgUpdateConfig dlg(std::move(updates_map));
+
+ const auto res = dlg.ShowModal();
+ if (res == wxID_OK) {
+ BOOST_LOG_TRIVIAL(debug) << "User agreed to perform the update";
+ p->perform_updates(std::move(updates));
+
+ // Reload global configuration
+ auto *app_config = GUI::get_app_config();
+ GUI::get_preset_bundle()->load_presets(*app_config);
+ GUI::load_current_presets();
+ } else {
+ BOOST_LOG_TRIVIAL(info) << "User refused the update";
+ }
+ } else {
+ BOOST_LOG_TRIVIAL(info) << "No configuration updates available.";
+ }
+
+ return true;
+}
+
+void PresetUpdater::install_bundles_rsrc(std::vector<std::string> bundles, bool snapshot) const
+{
+ Updates updates;
+
+ BOOST_LOG_TRIVIAL(info) << boost::format("Installing %1% bundles from resources ...") % bundles.size();
+
+ for (const auto &bundle : bundles) {
+ auto path_in_rsrc = p->rsrc_path / bundle;
+ auto path_in_vendors = p->vendor_path / bundle;
+ updates.updates.emplace_back(std::move(path_in_rsrc), std::move(path_in_vendors), Version());
+ }
+
+ p->perform_updates(std::move(updates), snapshot);
+}
+
+
+}
diff --git a/xs/src/slic3r/Utils/PresetUpdater.hpp b/xs/src/slic3r/Utils/PresetUpdater.hpp
new file mode 100644
index 000000000..6a53cca81
--- /dev/null
+++ b/xs/src/slic3r/Utils/PresetUpdater.hpp
@@ -0,0 +1,42 @@
+#ifndef slic3r_PresetUpdate_hpp_
+#define slic3r_PresetUpdate_hpp_
+
+#include <memory>
+#include <vector>
+
+namespace Slic3r {
+
+
+class AppConfig;
+class PresetBundle;
+
+class PresetUpdater
+{
+public:
+ PresetUpdater(int version_online_event);
+ PresetUpdater(PresetUpdater &&) = delete;
+ PresetUpdater(const PresetUpdater &) = delete;
+ PresetUpdater &operator=(PresetUpdater &&) = delete;
+ PresetUpdater &operator=(const PresetUpdater &) = delete;
+ ~PresetUpdater();
+
+ // If either version check or config updating is enabled, get the appropriate data in the background and cache it.
+ void sync(PresetBundle *preset_bundle);
+
+ // If version check is enabled, check if chaced online slic3r version is newer, notify if so.
+ void slic3r_update_notify();
+
+ // If updating is enabled, check if updates are available in cache, if so, ask about installation.
+ // A false return value implies Slic3r should exit due to incompatibility of configuration.
+ bool config_update() const;
+
+ // "Update" a list of bundles from resources (behaves like an online update).
+ void install_bundles_rsrc(std::vector<std::string> bundles, bool snapshot = true) const;
+private:
+ struct priv;
+ std::unique_ptr<priv> p;
+};
+
+
+}
+#endif
diff --git a/xs/src/slic3r/Utils/PrintHost.cpp b/xs/src/slic3r/Utils/PrintHost.cpp
new file mode 100644
index 000000000..dd72bae40
--- /dev/null
+++ b/xs/src/slic3r/Utils/PrintHost.cpp
@@ -0,0 +1,23 @@
+#include "OctoPrint.hpp"
+#include "Duet.hpp"
+
+#include "libslic3r/PrintConfig.hpp"
+
+namespace Slic3r {
+
+
+PrintHost::~PrintHost() {}
+
+PrintHost* PrintHost::get_print_host(DynamicPrintConfig *config)
+{
+ PrintHostType kind = config->option<ConfigOptionEnum<PrintHostType>>("host_type")->value;
+ if (kind == htOctoPrint) {
+ return new OctoPrint(config);
+ } else if (kind == htDuet) {
+ return new Duet(config);
+ }
+ return nullptr;
+}
+
+
+}
diff --git a/xs/src/slic3r/Utils/PrintHost.hpp b/xs/src/slic3r/Utils/PrintHost.hpp
new file mode 100644
index 000000000..bc828ea46
--- /dev/null
+++ b/xs/src/slic3r/Utils/PrintHost.hpp
@@ -0,0 +1,35 @@
+#ifndef slic3r_PrintHost_hpp_
+#define slic3r_PrintHost_hpp_
+
+#include <memory>
+#include <string>
+#include <wx/string.h>
+
+
+namespace Slic3r {
+
+
+class DynamicPrintConfig;
+
+class PrintHost
+{
+public:
+ virtual ~PrintHost();
+
+ virtual bool test(wxString &curl_msg) const = 0;
+ virtual wxString get_test_ok_msg () const = 0;
+ virtual wxString get_test_failed_msg (wxString &msg) const = 0;
+ // Send gcode file to print host, filename is expected to be in UTF-8
+ virtual bool send_gcode(const std::string &filename) const = 0;
+ virtual bool has_auto_discovery() const = 0;
+ virtual bool can_test() const = 0;
+
+ static PrintHost* get_print_host(DynamicPrintConfig *config);
+};
+
+
+
+
+}
+
+#endif
diff --git a/xs/src/slic3r/Utils/PrintHostSendDialog.cpp b/xs/src/slic3r/Utils/PrintHostSendDialog.cpp
new file mode 100644
index 000000000..c5d441f87
--- /dev/null
+++ b/xs/src/slic3r/Utils/PrintHostSendDialog.cpp
@@ -0,0 +1,52 @@
+#include "PrintHostSendDialog.hpp"
+
+#include <wx/frame.h>
+#include <wx/event.h>
+#include <wx/progdlg.h>
+#include <wx/sizer.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/checkbox.h>
+
+#include "slic3r/GUI/GUI.hpp"
+#include "slic3r/GUI/MsgDialog.hpp"
+
+
+namespace fs = boost::filesystem;
+
+namespace Slic3r {
+
+PrintHostSendDialog::PrintHostSendDialog(const fs::path &path, bool can_start_print) :
+ MsgDialog(nullptr, _(L("Send G-Code to printer host")), _(L("Upload to Printer Host with the following filename:")), wxID_NONE),
+ txt_filename(new wxTextCtrl(this, wxID_ANY, path.filename().wstring())),
+ box_print(new wxCheckBox(this, wxID_ANY, _(L("Start printing after upload")))),
+ can_start_print(can_start_print)
+{
+ auto *label_dir_hint = new wxStaticText(this, wxID_ANY, _(L("Use forward slashes ( / ) as a directory separator if needed.")));
+ label_dir_hint->Wrap(CONTENT_WIDTH);
+
+ content_sizer->Add(txt_filename, 0, wxEXPAND);
+ content_sizer->Add(label_dir_hint);
+ content_sizer->AddSpacer(VERT_SPACING);
+ content_sizer->Add(box_print, 0, wxBOTTOM, 2*VERT_SPACING);
+
+ btn_sizer->Add(CreateStdDialogButtonSizer(wxOK | wxCANCEL));
+
+ txt_filename->SetFocus();
+ wxString stem(path.stem().wstring());
+ txt_filename->SetSelection(0, stem.Length());
+
+ box_print->Enable(can_start_print);
+
+ Fit();
+}
+
+fs::path PrintHostSendDialog::filename() const
+{
+ return fs::path(txt_filename->GetValue().wx_str());
+}
+
+bool PrintHostSendDialog::print() const
+{
+ return box_print->GetValue(); }
+}
diff --git a/xs/src/slic3r/Utils/PrintHostSendDialog.hpp b/xs/src/slic3r/Utils/PrintHostSendDialog.hpp
new file mode 100644
index 000000000..dc4a8d6f7
--- /dev/null
+++ b/xs/src/slic3r/Utils/PrintHostSendDialog.hpp
@@ -0,0 +1,38 @@
+#ifndef slic3r_PrintHostSendDialog_hpp_
+#define slic3r_PrintHostSendDialog_hpp_
+
+#include <string>
+
+#include <boost/filesystem/path.hpp>
+
+#include <wx/string.h>
+#include <wx/frame.h>
+#include <wx/event.h>
+#include <wx/progdlg.h>
+#include <wx/sizer.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/checkbox.h>
+
+#include "slic3r/GUI/GUI.hpp"
+#include "slic3r/GUI/MsgDialog.hpp"
+
+
+namespace Slic3r {
+
+class PrintHostSendDialog : public GUI::MsgDialog
+{
+private:
+ wxTextCtrl *txt_filename;
+ wxCheckBox *box_print;
+ bool can_start_print;
+
+public:
+ PrintHostSendDialog(const boost::filesystem::path &path, bool can_start_print);
+ boost::filesystem::path filename() const;
+ bool print() const;
+};
+
+}
+
+#endif
diff --git a/xs/src/slic3r/Utils/Semver.hpp b/xs/src/slic3r/Utils/Semver.hpp
new file mode 100644
index 000000000..736f9b891
--- /dev/null
+++ b/xs/src/slic3r/Utils/Semver.hpp
@@ -0,0 +1,151 @@
+#ifndef slic3r_Semver_hpp_
+#define slic3r_Semver_hpp_
+
+#include <string>
+#include <cstring>
+#include <ostream>
+#include <stdexcept>
+#include <boost/optional.hpp>
+#include <boost/format.hpp>
+
+#include "semver/semver.h"
+
+namespace Slic3r {
+
+
+class Semver
+{
+public:
+ struct Major { const int i; Major(int i) : i(i) {} };
+ struct Minor { const int i; Minor(int i) : i(i) {} };
+ struct Patch { const int i; Patch(int i) : i(i) {} };
+
+ Semver() : ver(semver_zero()) {}
+
+ Semver(int major, int minor, int patch,
+ boost::optional<const std::string&> metadata = boost::none,
+ boost::optional<const std::string&> prerelease = boost::none)
+ : ver(semver_zero())
+ {
+ ver.major = major;
+ ver.minor = minor;
+ ver.patch = patch;
+ set_metadata(metadata);
+ set_prerelease(prerelease);
+ }
+
+ Semver(const std::string &str) : ver(semver_zero())
+ {
+ auto parsed = parse(str);
+ if (! parsed) {
+ throw std::runtime_error(std::string("Could not parse version string: ") + str);
+ }
+ ver = parsed->ver;
+ parsed->ver = semver_zero();
+ }
+
+ static boost::optional<Semver> parse(const std::string &str)
+ {
+ semver_t ver = semver_zero();
+ if (::semver_parse(str.c_str(), &ver) == 0) {
+ return Semver(ver);
+ } else {
+ return boost::none;
+ }
+ }
+
+ static const Semver zero() { return Semver(semver_zero()); }
+
+ static const Semver inf()
+ {
+ static semver_t ver = { std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), nullptr, nullptr };
+ return Semver(ver);
+ }
+
+ static const Semver invalid()
+ {
+ static semver_t ver = { -1, 0, 0, nullptr, nullptr };
+ return Semver(ver);
+ }
+
+ Semver(Semver &&other) : ver(other.ver) { other.ver = semver_zero(); }
+ Semver(const Semver &other) : ver(::semver_copy(&other.ver)) {}
+
+ Semver &operator=(Semver &&other)
+ {
+ ::semver_free(&ver);
+ ver = other.ver;
+ other.ver = semver_zero();
+ return *this;
+ }
+
+ Semver &operator=(const Semver &other)
+ {
+ ::semver_free(&ver);
+ ver = ::semver_copy(&other.ver);
+ return *this;
+ }
+
+ ~Semver() { ::semver_free(&ver); }
+
+ // const accessors
+ int maj() const { return ver.major; }
+ int min() const { return ver.minor; }
+ int patch() const { return ver.patch; }
+ const char* prerelease() const { return ver.prerelease; }
+ const char* metadata() const { return ver.metadata; }
+
+ // Setters
+ void set_maj(int maj) { ver.major = maj; }
+ void set_min(int min) { ver.minor = min; }
+ void set_patch(int patch) { ver.patch = patch; }
+ void set_metadata(boost::optional<const std::string&> meta) { ver.metadata = meta ? strdup(*meta) : nullptr; }
+ void set_prerelease(boost::optional<const std::string&> pre) { ver.prerelease = pre ? strdup(*pre) : nullptr; }
+
+ // Comparison
+ bool operator<(const Semver &b) const { return ::semver_compare(ver, b.ver) == -1; }
+ bool operator<=(const Semver &b) const { return ::semver_compare(ver, b.ver) <= 0; }
+ bool operator==(const Semver &b) const { return ::semver_compare(ver, b.ver) == 0; }
+ bool operator!=(const Semver &b) const { return ::semver_compare(ver, b.ver) != 0; }
+ bool operator>=(const Semver &b) const { return ::semver_compare(ver, b.ver) >= 0; }
+ bool operator>(const Semver &b) const { return ::semver_compare(ver, b.ver) == 1; }
+ // We're using '&' instead of the '~' operator here as '~' is unary-only:
+ // Satisfies patch if Major and minor are equal.
+ bool operator&(const Semver &b) const { return ::semver_satisfies_patch(ver, b.ver); }
+ bool operator^(const Semver &b) const { return ::semver_satisfies_caret(ver, b.ver); }
+ bool in_range(const Semver &low, const Semver &high) const { return low <= *this && *this <= high; }
+
+ // Conversion
+ std::string to_string() const {
+ auto res = (boost::format("%1%.%2%.%3%") % ver.major % ver.minor % ver.patch).str();
+ if (ver.prerelease != nullptr) { res += '-'; res += ver.prerelease; }
+ if (ver.metadata != nullptr) { res += '+'; res += ver.metadata; }
+ return res;
+ }
+
+ // Arithmetics
+ Semver& operator+=(const Major &b) { ver.major += b.i; return *this; }
+ Semver& operator+=(const Minor &b) { ver.minor += b.i; return *this; }
+ Semver& operator+=(const Patch &b) { ver.patch += b.i; return *this; }
+ Semver& operator-=(const Major &b) { ver.major -= b.i; return *this; }
+ Semver& operator-=(const Minor &b) { ver.minor -= b.i; return *this; }
+ Semver& operator-=(const Patch &b) { ver.patch -= b.i; return *this; }
+ Semver operator+(const Major &b) const { Semver res(*this); return res += b; }
+ Semver operator+(const Minor &b) const { Semver res(*this); return res += b; }
+ Semver operator+(const Patch &b) const { Semver res(*this); return res += b; }
+ Semver operator-(const Major &b) const { Semver res(*this); return res -= b; }
+ Semver operator-(const Minor &b) const { Semver res(*this); return res -= b; }
+ Semver operator-(const Patch &b) const { Semver res(*this); return res -= b; }
+
+private:
+ semver_t ver;
+
+ Semver(semver_t ver) : ver(ver) {}
+
+ static semver_t semver_zero() { return { 0, 0, 0, nullptr, nullptr }; }
+ static char * strdup(const std::string &str) { return ::semver_strdup(const_cast<char*>(str.c_str())); }
+};
+
+
+}
+#endif
diff --git a/xs/src/slic3r/Utils/Serial.cpp b/xs/src/slic3r/Utils/Serial.cpp
new file mode 100644
index 000000000..183119b44
--- /dev/null
+++ b/xs/src/slic3r/Utils/Serial.cpp
@@ -0,0 +1,490 @@
+#include "Serial.hpp"
+
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <chrono>
+#include <thread>
+#include <fstream>
+#include <stdexcept>
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/format.hpp>
+#include <boost/optional.hpp>
+
+#if _WIN32
+ #include <Windows.h>
+ #include <Setupapi.h>
+ #include <initguid.h>
+ #include <devguid.h>
+ #include <regex>
+ // Undefine min/max macros incompatible with the standard library
+ // For example, std::numeric_limits<std::streamsize>::max()
+ // produces some weird errors
+ #ifdef min
+ #undef min
+ #endif
+ #ifdef max
+ #undef max
+ #endif
+ #include "boost/nowide/convert.hpp"
+ #pragma comment(lib, "user32.lib")
+#elif __APPLE__
+ #include <CoreFoundation/CoreFoundation.h>
+ #include <CoreFoundation/CFString.h>
+ #include <IOKit/IOKitLib.h>
+ #include <IOKit/serial/IOSerialKeys.h>
+ #include <IOKit/serial/ioss.h>
+ #include <sys/syslimits.h>
+#endif
+
+#ifndef _WIN32
+ #include <sys/ioctl.h>
+ #include <sys/time.h>
+ #include <sys/unistd.h>
+ #include <sys/select.h>
+#endif
+
+#if defined(__APPLE__) || defined(__OpenBSD__)
+ #include <termios.h>
+#elif defined __linux__
+ #include <fcntl.h>
+ #include <asm-generic/ioctls.h>
+#endif
+
+using boost::optional;
+
+
+namespace Slic3r {
+namespace Utils {
+
+static bool looks_like_printer(const std::string &friendly_name)
+{
+ return friendly_name.find("Original Prusa") != std::string::npos;
+}
+
+#if _WIN32
+void parse_hardware_id(const std::string &hardware_id, SerialPortInfo &spi)
+{
+ unsigned vid, pid;
+ std::regex pattern("USB\\\\.*VID_([[:xdigit:]]+)&PID_([[:xdigit:]]+).*");
+ std::smatch matches;
+ if (std::regex_match(hardware_id, matches, pattern)) {
+ try {
+ vid = std::stoul(matches[1].str(), 0, 16);
+ pid = std::stoul(matches[2].str(), 0, 16);
+ spi.id_vendor = vid;
+ spi.id_product = pid;
+ }
+ catch (...) {}
+ }
+}
+#endif
+
+#ifdef __linux__
+optional<std::string> sysfs_tty_prop(const std::string &tty_dev, const std::string &name)
+{
+ const auto prop_path = (boost::format("/sys/class/tty/%1%/device/../%2%") % tty_dev % name).str();
+ std::ifstream file(prop_path);
+ std::string res;
+
+ std::getline(file, res);
+ if (file.good()) { return res; }
+ else { return boost::none; }
+}
+
+optional<unsigned long> sysfs_tty_prop_hex(const std::string &tty_dev, const std::string &name)
+{
+ auto prop = sysfs_tty_prop(tty_dev, name);
+ if (!prop) { return boost::none; }
+
+ try { return std::stoul(*prop, 0, 16); }
+ catch (...) { return boost::none; }
+}
+#endif
+
+std::vector<SerialPortInfo> scan_serial_ports_extended()
+{
+ std::vector<SerialPortInfo> output;
+
+#ifdef _WIN32
+ SP_DEVINFO_DATA devInfoData = { 0 };
+ devInfoData.cbSize = sizeof(devInfoData);
+ // Get the tree containing the info for the ports.
+ HDEVINFO hDeviceInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_PORTS, 0, nullptr, DIGCF_PRESENT);
+ if (hDeviceInfo != INVALID_HANDLE_VALUE) {
+ // Iterate over all the devices in the tree.
+ for (int nDevice = 0; SetupDiEnumDeviceInfo(hDeviceInfo, nDevice, &devInfoData); ++ nDevice) {
+ SerialPortInfo port_info;
+ // Get the registry key which stores the ports settings.
+ HKEY hDeviceKey = SetupDiOpenDevRegKey(hDeviceInfo, &devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
+ if (hDeviceKey) {
+ // Read in the name of the port.
+ wchar_t pszPortName[4096];
+ DWORD dwSize = sizeof(pszPortName);
+ DWORD dwType = 0;
+ if (RegQueryValueEx(hDeviceKey, L"PortName", NULL, &dwType, (LPBYTE)pszPortName, &dwSize) == ERROR_SUCCESS)
+ port_info.port = boost::nowide::narrow(pszPortName);
+ RegCloseKey(hDeviceKey);
+ if (port_info.port.empty())
+ continue;
+ }
+
+ // Find the size required to hold the device info.
+ DWORD regDataType;
+ DWORD reqSize = 0;
+ SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_HARDWAREID, nullptr, nullptr, 0, &reqSize);
+ std::vector<wchar_t> hardware_id(reqSize > 1 ? reqSize : 1);
+ // Now store it in a buffer.
+ if (! SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_HARDWAREID, &regDataType, (BYTE*)hardware_id.data(), reqSize, nullptr))
+ continue;
+ parse_hardware_id(boost::nowide::narrow(hardware_id.data()), port_info);
+
+ // Find the size required to hold the friendly name.
+ reqSize = 0;
+ SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, nullptr, 0, &reqSize);
+ std::vector<wchar_t> friendly_name;
+ friendly_name.reserve(reqSize > 1 ? reqSize : 1);
+ // Now store it in a buffer.
+ if (! SetupDiGetDeviceRegistryProperty(hDeviceInfo, &devInfoData, SPDRP_FRIENDLYNAME, nullptr, (BYTE*)friendly_name.data(), reqSize, nullptr)) {
+ port_info.friendly_name = port_info.port;
+ } else {
+ port_info.friendly_name = boost::nowide::narrow(friendly_name.data());
+ port_info.is_printer = looks_like_printer(port_info.friendly_name);
+ }
+ output.emplace_back(std::move(port_info));
+ }
+ }
+#elif __APPLE__
+ // inspired by https://sigrok.org/wiki/Libserialport
+ CFMutableDictionaryRef classes = IOServiceMatching(kIOSerialBSDServiceValue);
+ if (classes != 0) {
+ io_iterator_t iter;
+ if (IOServiceGetMatchingServices(kIOMasterPortDefault, classes, &iter) == KERN_SUCCESS) {
+ io_object_t port;
+ while ((port = IOIteratorNext(iter)) != 0) {
+ CFTypeRef cf_property = IORegistryEntryCreateCFProperty(port, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
+ if (cf_property) {
+ char path[PATH_MAX];
+ Boolean result = CFStringGetCString((CFStringRef)cf_property, path, sizeof(path), kCFStringEncodingUTF8);
+ CFRelease(cf_property);
+ if (result) {
+ SerialPortInfo port_info;
+ port_info.port = path;
+
+ // Attempt to read out the device friendly name
+ if ((cf_property = IORegistryEntrySearchCFProperty(port, kIOServicePlane,
+ CFSTR("USB Interface Name"), kCFAllocatorDefault,
+ kIORegistryIterateRecursively | kIORegistryIterateParents)) ||
+ (cf_property = IORegistryEntrySearchCFProperty(port, kIOServicePlane,
+ CFSTR("USB Product Name"), kCFAllocatorDefault,
+ kIORegistryIterateRecursively | kIORegistryIterateParents)) ||
+ (cf_property = IORegistryEntrySearchCFProperty(port, kIOServicePlane,
+ CFSTR("Product Name"), kCFAllocatorDefault,
+ kIORegistryIterateRecursively | kIORegistryIterateParents)) ||
+ (cf_property = IORegistryEntryCreateCFProperty(port,
+ CFSTR(kIOTTYDeviceKey), kCFAllocatorDefault, 0))) {
+ // Description limited to 127 char, anything longer would not be user friendly anyway.
+ char description[128];
+ if (CFStringGetCString((CFStringRef)cf_property, description, sizeof(description), kCFStringEncodingUTF8)) {
+ port_info.friendly_name = std::string(description) + " (" + port_info.port + ")";
+ port_info.is_printer = looks_like_printer(port_info.friendly_name);
+ }
+ CFRelease(cf_property);
+ }
+ if (port_info.friendly_name.empty())
+ port_info.friendly_name = port_info.port;
+
+ // Attempt to read out the VID & PID
+ int vid, pid;
+ auto cf_vendor = IORegistryEntrySearchCFProperty(port, kIOServicePlane, CFSTR("idVendor"),
+ kCFAllocatorDefault, kIORegistryIterateRecursively | kIORegistryIterateParents);
+ auto cf_product = IORegistryEntrySearchCFProperty(port, kIOServicePlane, CFSTR("idProduct"),
+ kCFAllocatorDefault, kIORegistryIterateRecursively | kIORegistryIterateParents);
+ if (cf_vendor && cf_product) {
+ if (CFNumberGetValue((CFNumberRef)cf_vendor, kCFNumberIntType, &vid) &&
+ CFNumberGetValue((CFNumberRef)cf_product, kCFNumberIntType, &pid)) {
+ port_info.id_vendor = vid;
+ port_info.id_product = pid;
+ }
+ }
+ if (cf_vendor) { CFRelease(cf_vendor); }
+ if (cf_product) { CFRelease(cf_product); }
+
+ output.emplace_back(std::move(port_info));
+ }
+ }
+ IOObjectRelease(port);
+ }
+ }
+ }
+#else
+ // UNIX / Linux
+ std::initializer_list<const char*> prefixes { "ttyUSB" , "ttyACM", "tty.", "cu.", "rfcomm" };
+ for (auto &dir_entry : boost::filesystem::directory_iterator(boost::filesystem::path("/dev"))) {
+ std::string name = dir_entry.path().filename().string();
+ for (const char *prefix : prefixes) {
+ if (boost::starts_with(name, prefix)) {
+ const auto path = dir_entry.path().string();
+ SerialPortInfo spi;
+ spi.port = path;
+#ifdef __linux__
+ auto friendly_name = sysfs_tty_prop(name, "product");
+ spi.friendly_name = friendly_name ? (boost::format("%1% (%2%)") % *friendly_name % path).str() : path;
+ auto vid = sysfs_tty_prop_hex(name, "idVendor");
+ auto pid = sysfs_tty_prop_hex(name, "idProduct");
+ if (vid && pid) {
+ spi.id_vendor = *vid;
+ spi.id_product = *pid;
+ }
+#else
+ spi.friendly_name = path;
+#endif
+ output.emplace_back(std::move(spi));
+ break;
+ }
+ }
+ }
+#endif
+
+ output.erase(std::remove_if(output.begin(), output.end(),
+ [](const SerialPortInfo &info) {
+ return boost::starts_with(info.port, "Bluetooth") || boost::starts_with(info.port, "FireFly");
+ }),
+ output.end());
+ return output;
+}
+
+std::vector<std::string> scan_serial_ports()
+{
+ std::vector<SerialPortInfo> ports = scan_serial_ports_extended();
+ std::vector<std::string> output;
+ output.reserve(ports.size());
+ for (const SerialPortInfo &spi : ports)
+ output.emplace_back(std::move(spi.port));
+ return output;
+}
+
+
+
+// Class Serial
+
+namespace asio = boost::asio;
+using boost::system::error_code;
+
+Serial::Serial(asio::io_service& io_service) :
+ asio::serial_port(io_service)
+{}
+
+Serial::Serial(asio::io_service& io_service, const std::string &name, unsigned baud_rate) :
+ asio::serial_port(io_service, name)
+{
+ set_baud_rate(baud_rate);
+}
+
+Serial::~Serial() {}
+
+void Serial::set_baud_rate(unsigned baud_rate)
+{
+ try {
+ // This does not support speeds > 115200
+ set_option(boost::asio::serial_port_base::baud_rate(baud_rate));
+ } catch (boost::system::system_error &) {
+ auto handle = native_handle();
+
+ auto handle_errno = [](int retval) {
+ if (retval != 0) {
+ throw std::runtime_error(
+ (boost::format("Could not set baud rate: %1%") % strerror(errno)).str()
+ );
+ }
+ };
+
+#if __APPLE__
+ termios ios;
+ handle_errno(::tcgetattr(handle, &ios));
+ handle_errno(::cfsetspeed(&ios, baud_rate));
+ speed_t newSpeed = baud_rate;
+ handle_errno(::ioctl(handle, IOSSIOSPEED, &newSpeed));
+ handle_errno(::tcsetattr(handle, TCSANOW, &ios));
+#elif __linux
+
+ /* The following definitions are kindly borrowed from:
+ /usr/include/asm-generic/termbits.h
+ Unfortunately we cannot just include that one because
+ it would redefine the "struct termios" already defined
+ the <termios.h> already included by Boost.ASIO. */
+#define K_NCCS 19
+ struct termios2 {
+ tcflag_t c_iflag;
+ tcflag_t c_oflag;
+ tcflag_t c_cflag;
+ tcflag_t c_lflag;
+ cc_t c_line;
+ cc_t c_cc[K_NCCS];
+ speed_t c_ispeed;
+ speed_t c_ospeed;
+ };
+#define BOTHER CBAUDEX
+
+ termios2 ios;
+ handle_errno(::ioctl(handle, TCGETS2, &ios));
+ ios.c_ispeed = ios.c_ospeed = baud_rate;
+ ios.c_cflag &= ~CBAUD;
+ ios.c_cflag |= BOTHER | CLOCAL | CREAD;
+ ios.c_cc[VMIN] = 1; // Minimum of characters to read, prevents eof errors when 0 bytes are read
+ ios.c_cc[VTIME] = 1;
+ handle_errno(::ioctl(handle, TCSETS2, &ios));
+
+#elif __OpenBSD__
+ struct termios ios;
+ handle_errno(::tcgetattr(handle, &ios));
+ handle_errno(::cfsetspeed(&ios, baud_rate));
+ handle_errno(::tcsetattr(handle, TCSAFLUSH, &ios));
+#else
+ throw std::runtime_error("Custom baud rates are not currently supported on this OS");
+#endif
+ }
+}
+
+void Serial::set_DTR(bool on)
+{
+ auto handle = native_handle();
+#if defined(_WIN32) && !defined(__SYMBIAN32__)
+ if (! EscapeCommFunction(handle, on ? SETDTR : CLRDTR)) {
+ throw std::runtime_error("Could not set serial port DTR");
+ }
+#else
+ int status;
+ if (::ioctl(handle, TIOCMGET, &status) == 0) {
+ on ? status |= TIOCM_DTR : status &= ~TIOCM_DTR;
+ if (::ioctl(handle, TIOCMSET, &status) == 0) {
+ return;
+ }
+ }
+
+ throw std::runtime_error(
+ (boost::format("Could not set serial port DTR: %1%") % strerror(errno)).str()
+ );
+#endif
+}
+
+void Serial::reset_line_num()
+{
+ // See https://github.com/MarlinFirmware/Marlin/wiki/M110
+ write_string("M110 N0\n");
+ m_line_num = 0;
+}
+
+bool Serial::read_line(unsigned timeout, std::string &line, error_code &ec)
+{
+ auto &io_service = get_io_service();
+ asio::deadline_timer timer(io_service);
+ char c = 0;
+ bool fail = false;
+
+ while (true) {
+ io_service.reset();
+
+ asio::async_read(*this, boost::asio::buffer(&c, 1), [&](const error_code &read_ec, size_t size) {
+ if (ec || size == 0) {
+ fail = true;
+ ec = read_ec; // FIXME: only if operation not aborted
+ }
+ timer.cancel(); // FIXME: ditto
+ });
+
+ if (timeout > 0) {
+ timer.expires_from_now(boost::posix_time::milliseconds(timeout));
+ timer.async_wait([&](const error_code &ec) {
+ // Ignore timer aborts
+ if (!ec) {
+ fail = true;
+ this->cancel();
+ }
+ });
+ }
+
+ io_service.run();
+
+ if (fail) {
+ return false;
+ } else if (c != '\n') {
+ line += c;
+ } else {
+ return true;
+ }
+ }
+}
+
+void Serial::printer_setup()
+{
+ printer_reset();
+ write_string("\r\r\r\r\r\r\r\r\r\r"); // Gets rid of line noise, if any
+}
+
+size_t Serial::write_string(const std::string &str)
+{
+ // TODO: might be wise to timeout here as well
+ return asio::write(*this, asio::buffer(str));
+}
+
+bool Serial::printer_ready_wait(unsigned retries, unsigned timeout)
+{
+ std::string line;
+ error_code ec;
+
+ for (; retries > 0; retries--) {
+ reset_line_num();
+
+ while (read_line(timeout, line, ec)) {
+ if (line == "ok") {
+ return true;
+ }
+ line.clear();
+ }
+
+ line.clear();
+ }
+
+ return false;
+}
+
+size_t Serial::printer_write_line(const std::string &line, unsigned line_num)
+{
+ const auto formatted_line = Utils::Serial::printer_format_line(line, line_num);
+ return write_string(formatted_line);
+}
+
+size_t Serial::printer_write_line(const std::string &line)
+{
+ m_line_num++;
+ return printer_write_line(line, m_line_num);
+}
+
+void Serial::printer_reset()
+{
+ this->set_DTR(false);
+ std::this_thread::sleep_for(std::chrono::milliseconds(200));
+ this->set_DTR(true);
+ std::this_thread::sleep_for(std::chrono::milliseconds(200));
+ this->set_DTR(false);
+ std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+}
+
+std::string Serial::printer_format_line(const std::string &line, unsigned line_num)
+{
+ const auto line_num_str = std::to_string(line_num);
+
+ unsigned checksum = 'N';
+ for (auto c : line_num_str) { checksum ^= c; }
+ checksum ^= ' ';
+ for (auto c : line) { checksum ^= c; }
+
+ return (boost::format("N%1% %2%*%3%\n") % line_num_str % line % checksum).str();
+}
+
+
+} // namespace Utils
+} // namespace Slic3r
diff --git a/xs/src/slic3r/Utils/Serial.hpp b/xs/src/slic3r/Utils/Serial.hpp
new file mode 100644
index 000000000..e4a28de09
--- /dev/null
+++ b/xs/src/slic3r/Utils/Serial.hpp
@@ -0,0 +1,82 @@
+#ifndef slic3r_GUI_Utils_Serial_hpp_
+#define slic3r_GUI_Utils_Serial_hpp_
+
+#include <vector>
+#include <string>
+#include <boost/system/error_code.hpp>
+#include <boost/asio.hpp>
+
+
+namespace Slic3r {
+namespace Utils {
+
+struct SerialPortInfo {
+ std::string port;
+ unsigned id_vendor = -1;
+ unsigned id_product = -1;
+ std::string friendly_name;
+ bool is_printer = false;
+
+ bool id_match(unsigned id_vendor, unsigned id_product) const { return id_vendor == this->id_vendor && id_product == this->id_product; }
+};
+
+inline bool operator==(const SerialPortInfo &sp1, const SerialPortInfo &sp2)
+{
+ return
+ sp1.port == sp2.port &&
+ sp1.id_vendor == sp2.id_vendor &&
+ sp1.id_product == sp2.id_product &&
+ sp1.is_printer == sp2.is_printer;
+}
+
+extern std::vector<std::string> scan_serial_ports();
+extern std::vector<SerialPortInfo> scan_serial_ports_extended();
+
+
+class Serial : public boost::asio::serial_port
+{
+public:
+ Serial(boost::asio::io_service &io_service);
+ Serial(boost::asio::io_service &io_service, const std::string &name, unsigned baud_rate);
+ Serial(const Serial &) = delete;
+ Serial &operator=(const Serial &) = delete;
+ ~Serial();
+
+ void set_baud_rate(unsigned baud_rate);
+ void set_DTR(bool on);
+
+ // Resets the line number both internally as well as with the firmware using M110
+ void reset_line_num();
+
+ // Reads a line or times out, the timeout is in milliseconds
+ bool read_line(unsigned timeout, std::string &line, boost::system::error_code &ec);
+
+ // Perform an initial setup for communicating with a printer
+ void printer_setup();
+
+ // Write data from a string
+ size_t write_string(const std::string &str);
+
+ // Attempts to reset the line numer and waits until the printer says "ok"
+ bool printer_ready_wait(unsigned retries, unsigned timeout);
+
+ // Write Marlin-formatted line, with a line number and a checksum
+ size_t printer_write_line(const std::string &line, unsigned line_num);
+
+ // Same as above, but with internally-managed line number
+ size_t printer_write_line(const std::string &line);
+
+ // Toggles DTR to reset the printer
+ void printer_reset();
+
+ // Formats a line Marlin-style, ie. with a sequential number and a checksum
+ static std::string printer_format_line(const std::string &line, unsigned line_num);
+private:
+ unsigned m_line_num = 0;
+};
+
+
+} // Utils
+} // Slic3r
+
+#endif /* slic3r_GUI_Utils_Serial_hpp_ */
diff --git a/xs/src/slic3r/Utils/Time.cpp b/xs/src/slic3r/Utils/Time.cpp
new file mode 100644
index 000000000..f38c4b407
--- /dev/null
+++ b/xs/src/slic3r/Utils/Time.cpp
@@ -0,0 +1,80 @@
+#include "Time.hpp"
+
+#ifdef WIN32
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ #undef WIN32_LEAN_AND_MEAN
+#endif /* WIN32 */
+
+namespace Slic3r {
+namespace Utils {
+
+time_t parse_time_ISO8601Z(const std::string &sdate)
+{
+ int y, M, d, h, m, s;
+ if (sscanf(sdate.c_str(), "%04d%02d%02dT%02d%02d%02dZ", &y, &M, &d, &h, &m, &s) != 6)
+ return (time_t)-1;
+ struct tm tms;
+ tms.tm_year = y - 1900; // Year since 1900
+ tms.tm_mon = M - 1; // 0-11
+ tms.tm_mday = d; // 1-31
+ tms.tm_hour = h; // 0-23
+ tms.tm_min = m; // 0-59
+ tms.tm_sec = s; // 0-61 (0-60 in C++11)
+ return mktime(&tms);
+}
+
+std::string format_time_ISO8601Z(time_t time)
+{
+ struct tm tms;
+#ifdef WIN32
+ gmtime_s(&tms, &time);
+#else
+ gmtime_r(&time, &tms);
+#endif
+ char buf[128];
+ sprintf(buf, "%04d%02d%02dT%02d%02d%02dZ",
+ tms.tm_year + 1900,
+ tms.tm_mon + 1,
+ tms.tm_mday,
+ tms.tm_hour,
+ tms.tm_min,
+ tms.tm_sec);
+ return buf;
+}
+
+std::string format_local_date_time(time_t time)
+{
+ struct tm tms;
+#ifdef WIN32
+ localtime_s(&tms, &time);
+#else
+ localtime_r(&time, &tms);
+#endif
+ char buf[80];
+ strftime(buf, 80, "%x %X", &tms);
+ return buf;
+}
+
+time_t get_current_time_utc()
+{
+#ifdef WIN32
+ SYSTEMTIME st;
+ ::GetSystemTime(&st);
+ std::tm tm;
+ tm.tm_sec = st.wSecond;
+ tm.tm_min = st.wMinute;
+ tm.tm_hour = st.wHour;
+ tm.tm_mday = st.wDay;
+ tm.tm_mon = st.wMonth - 1;
+ tm.tm_year = st.wYear - 1900;
+ tm.tm_isdst = -1;
+ return mktime(&tm);
+#else
+ const time_t current_local = time(nullptr);
+ return mktime(gmtime(&current_local));
+#endif
+}
+
+}; // namespace Utils
+}; // namespace Slic3r
diff --git a/xs/src/slic3r/Utils/Time.hpp b/xs/src/slic3r/Utils/Time.hpp
new file mode 100644
index 000000000..7b670bd3e
--- /dev/null
+++ b/xs/src/slic3r/Utils/Time.hpp
@@ -0,0 +1,25 @@
+#ifndef slic3r_Utils_Time_hpp_
+#define slic3r_Utils_Time_hpp_
+
+#include <string>
+#include <time.h>
+
+namespace Slic3r {
+namespace Utils {
+
+// Utilities to convert an UTC time_t to/from an ISO8601 time format,
+// useful for putting timestamps into file and directory names.
+// Returns (time_t)-1 on error.
+extern time_t parse_time_ISO8601Z(const std::string &s);
+extern std::string format_time_ISO8601Z(time_t time);
+
+// Format the date and time from an UTC time according to the active locales and a local time zone.
+extern std::string format_local_date_time(time_t time);
+
+// There is no gmtime() on windows.
+extern time_t get_current_time_utc();
+
+}; // namespace Utils
+}; // namespace Slic3r
+
+#endif /* slic3r_Utils_Time_hpp_ */
diff --git a/xs/src/xsinit.h b/xs/src/xsinit.h
index 96c4b74d7..c9e363602 100644
--- a/xs/src/xsinit.h
+++ b/xs/src/xsinit.h
@@ -68,7 +68,16 @@ extern "C" {
#undef fputc
#undef fwrite
#undef fclose
+
+ // Breaks compilation with Eigen matrices embedded into Slic3r::Point.
+ #undef malloc
+ #undef realloc
+ #undef free
+ #undef select
#endif /* _MSC_VER */
+#undef Zero
+#undef Packet
+#undef _
}
#endif
@@ -80,13 +89,18 @@ extern "C" {
#include <Polygon.hpp>
#include <Polyline.hpp>
#include <TriangleMesh.hpp>
+#include <slic3r/AppController.hpp>
namespace Slic3r {
template<class T>
struct ClassTraits {
+ // Name of a Perl alias of a C++ class type, owned by Perl, reference counted.
static const char* name;
- static const char* name_ref;
+ // Name of a Perl alias of a C++ class type, owned by the C++ code.
+ // The references shall be enumerated at the end of XS.pm, where the desctructor is undefined with sub DESTROY {},
+ // so Perl will never delete the object instance.
+ static const char* name_ref;
};
// use this for typedefs for which the forward prototype
@@ -99,11 +113,16 @@ struct ClassTraits {
class cname; \
__REGISTER_CLASS(cname, perlname);
+// Return Perl alias to a C++ class name.
template<class T>
const char* perl_class_name(const T*) { return ClassTraits<T>::name; }
+// Return Perl alias to a C++ class name, suffixed with ::Ref.
+// Such a C++ class instance will not be destroyed by Perl, the instance destruction is left to the C++ code.
template<class T>
const char* perl_class_name_ref(const T*) { return ClassTraits<T>::name_ref; }
+// Mark the Perl SV (Scalar Value) as owning a "blessed" pointer to an object reference.
+// Perl will never release the C++ instance.
template<class T>
SV* perl_to_SV_ref(T &t) {
SV* sv = newSV(0);
@@ -111,6 +130,8 @@ SV* perl_to_SV_ref(T &t) {
return sv;
}
+// Mark the Perl SV (Scalar Value) as owning a "blessed" pointer to an object instance.
+// Perl will own the C++ instance, therefore it will also release it.
template<class T>
SV* perl_to_SV_clone_ref(const T &t) {
SV* sv = newSV(0);
@@ -118,6 +139,8 @@ SV* perl_to_SV_clone_ref(const T &t) {
return sv;
}
+// Reference wrapper to provide a C++ instance to Perl while keeping Perl from destroying the instance.
+// The instance is created temporarily by XS.cpp just to provide Perl with a CLASS name and a object instance pointer.
template <class T>
class Ref {
T* val;
@@ -125,10 +148,15 @@ public:
Ref() : val(NULL) {}
Ref(T* t) : val(t) {}
Ref(const T* t) : val(const_cast<T*>(t)) {}
+ // Called by XS.cpp to convert the referenced object instance to a Perl SV, before it is blessed with the name
+ // returned by CLASS()
operator T*() const { return val; }
+ // Name to bless the Perl SV with. The name ends with a "::Ref" suffix to keep Perl from destroying the object instance.
static const char* CLASS() { return ClassTraits<T>::name_ref; }
};
-
+
+// Wrapper to clone a C++ object instance before passing it to Perl for ownership.
+// This wrapper instance is created temporarily by XS.cpp to provide Perl with a CLASS name and a object instance pointer.
template <class T>
class Clone {
T* val;
@@ -136,7 +164,11 @@ public:
Clone() : val(NULL) {}
Clone(T* t) : val(new T(*t)) {}
Clone(const T& t) : val(new T(t)) {}
+ // Called by XS.cpp to convert the cloned object instance to a Perl SV, before it is blessed with the name
+ // returned by CLASS()
operator T*() const { return val; }
+ // Name to bless the Perl SV with. If there is a destructor registered in the XSP file for this class, then Perl will
+ // call this destructor when the reference counter of this SV drops to zero.
static const char* CLASS() { return ClassTraits<T>::name; }
};
@@ -165,23 +197,14 @@ void from_SV_check(SV* poly_sv, Polyline* THIS);
SV* to_SV_pureperl(const Point* THIS);
void from_SV(SV* point_sv, Point* point);
void from_SV_check(SV* point_sv, Point* point);
-SV* to_SV_pureperl(const Pointf* point);
-bool from_SV(SV* point_sv, Pointf* point);
-bool from_SV_check(SV* point_sv, Pointf* point);
+SV* to_SV_pureperl(const Vec2d* point);
+bool from_SV(SV* point_sv, Vec2d* point);
+bool from_SV_check(SV* point_sv, Vec2d* point);
void from_SV_check(SV* surface_sv, Surface* THIS);
SV* to_SV(TriangleMesh* THIS);
}
-#ifdef SLIC3R_HAS_BROKEN_CROAK
-#undef croak
-#ifdef _MSC_VER
- #define croak(...) confess_at(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
-#else
- #define croak(...) confess_at(__FILE__, __LINE__, __func__, __VA_ARGS__)
-#endif
-#endif
-
// Defined in wxPerlIface.cpp
// Return a pointer to the associated wxWidgets object instance given by classname.
extern void* wxPli_sv_2_object( pTHX_ SV* scalar, const char* classname );
diff --git a/xs/t/22_exception.t b/xs/t/22_exception.t
index c7df42670..fead8ddee 100644
--- a/xs/t/22_exception.t
+++ b/xs/t/22_exception.t
@@ -6,16 +6,9 @@ use warnings;
use Slic3r::XS;
use Test::More tests => 1;
-if ($ENV{SLIC3R_HAS_BROKEN_CROAK})
-{
- ok 1, 'SLIC3R_HAS_BROKEN_CROAK set, croaks and confesses from a C++ code will lead to an application exit!';
-}
-else
-{
- eval {
- Slic3r::xspp_test_croak_hangs_on_strawberry();
- };
- is $@, "xspp_test_croak_hangs_on_strawberry: exception catched\n", 'croak from inside a C++ exception delivered';
-}
+eval {
+ Slic3r::xspp_test_croak_hangs_on_strawberry();
+};
+is $@, "xspp_test_croak_hangs_on_strawberry: exception catched\n", 'croak from inside a C++ exception delivered';
__END__
diff --git a/xs/xsp/AppController.xsp b/xs/xsp/AppController.xsp
new file mode 100644
index 000000000..8156b0ad2
--- /dev/null
+++ b/xs/xsp/AppController.xsp
@@ -0,0 +1,29 @@
+%module{Slic3r::XS};
+
+%{
+#include <xsinit.h>
+#include "slic3r/AppController.hpp"
+#include "libslic3r/Model.hpp"
+#include "libslic3r/Print.hpp"
+#include "slic3r/GUI/ProgressStatusBar.hpp"
+%}
+
+%name{Slic3r::PrintController} class PrintController {
+
+ PrintController(Print *print);
+
+ void slice_to_png();
+ void slice();
+};
+
+%name{Slic3r::AppController} class AppController {
+
+ AppController();
+
+ PrintController *print_ctl();
+ void set_model(Model *model);
+ void set_print(Print *print);
+ void set_global_progress_indicator(ProgressStatusBar *prs);
+
+ void arrange_model();
+}; \ No newline at end of file
diff --git a/xs/xsp/BoundingBox.xsp b/xs/xsp/BoundingBox.xsp
index df8e6baea..a34cad0bc 100644
--- a/xs/xsp/BoundingBox.xsp
+++ b/xs/xsp/BoundingBox.xsp
@@ -25,11 +25,15 @@
double radius();
Clone<Point> min_point() %code{% RETVAL = THIS->min; %};
Clone<Point> max_point() %code{% RETVAL = THIS->max; %};
- int x_min() %code{% RETVAL = THIS->min.x; %};
- int x_max() %code{% RETVAL = THIS->max.x; %};
- int y_min() %code{% RETVAL = THIS->min.y; %};
- int y_max() %code{% RETVAL = THIS->max.y; %};
- std::string serialize() %code{% char buf[2048]; sprintf(buf, "%ld,%ld;%ld,%ld", THIS->min.x, THIS->min.y, THIS->max.x, THIS->max.y); RETVAL = buf; %};
+ int x_min() %code{% RETVAL = THIS->min(0); %};
+ int x_max() %code{% RETVAL = THIS->max(0); %};
+ int y_min() %code{% RETVAL = THIS->min(1); %};
+ int y_max() %code{% RETVAL = THIS->max(1); %};
+ void set_x_min(double val) %code{% THIS->min(0) = val; %};
+ void set_x_max(double val) %code{% THIS->max(0) = val; %};
+ void set_y_min(double val) %code{% THIS->min(1) = val; %};
+ void set_y_max(double val) %code{% THIS->max(1) = val; %};
+ std::string serialize() %code{% char buf[2048]; sprintf(buf, "%ld,%ld;%ld,%ld", THIS->min(0), THIS->min(1), THIS->max(0), THIS->max(1)); RETVAL = buf; %};
bool defined() %code{% RETVAL = THIS->defined; %};
%{
@@ -52,24 +56,24 @@ new_from_points(CLASS, points)
Clone<BoundingBoxf> clone()
%code{% RETVAL = THIS; %};
void merge(BoundingBoxf* bb) %code{% THIS->merge(*bb); %};
- void merge_point(Pointf* point) %code{% THIS->merge(*point); %};
+ void merge_point(Vec2d* point) %code{% THIS->merge(*point); %};
void scale(double factor);
void translate(double x, double y);
- Clone<Pointf> size();
- Clone<Pointf> center();
+ Clone<Vec2d> size();
+ Clone<Vec2d> center();
double radius();
bool empty() %code{% RETVAL = empty(*THIS); %};
- Clone<Pointf> min_point() %code{% RETVAL = THIS->min; %};
- Clone<Pointf> max_point() %code{% RETVAL = THIS->max; %};
- double x_min() %code{% RETVAL = THIS->min.x; %};
- double x_max() %code{% RETVAL = THIS->max.x; %};
- double y_min() %code{% RETVAL = THIS->min.y; %};
- double y_max() %code{% RETVAL = THIS->max.y; %};
- void set_x_min(double val) %code{% THIS->min.x = val; %};
- void set_x_max(double val) %code{% THIS->max.x = val; %};
- void set_y_min(double val) %code{% THIS->min.y = val; %};
- void set_y_max(double val) %code{% THIS->max.y = val; %};
- std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf;%lf,%lf", THIS->min.x, THIS->min.y, THIS->max.x, THIS->max.y); RETVAL = buf; %};
+ Clone<Vec2d> min_point() %code{% RETVAL = THIS->min; %};
+ Clone<Vec2d> max_point() %code{% RETVAL = THIS->max; %};
+ double x_min() %code{% RETVAL = THIS->min(0); %};
+ double x_max() %code{% RETVAL = THIS->max(0); %};
+ double y_min() %code{% RETVAL = THIS->min(1); %};
+ double y_max() %code{% RETVAL = THIS->max(1); %};
+ void set_x_min(double val) %code{% THIS->min(0) = val; %};
+ void set_x_max(double val) %code{% THIS->max(0) = val; %};
+ void set_y_min(double val) %code{% THIS->min(1) = val; %};
+ void set_y_max(double val) %code{% THIS->max(1) = val; %};
+ std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf;%lf,%lf", THIS->min(0), THIS->min(1), THIS->max(0), THIS->max(1)); RETVAL = buf; %};
bool defined() %code{% RETVAL = THIS->defined; %};
%{
@@ -92,23 +96,23 @@ new_from_points(CLASS, points)
Clone<BoundingBoxf3> clone()
%code{% RETVAL = THIS; %};
void merge(BoundingBoxf3* bb) %code{% THIS->merge(*bb); %};
- void merge_point(Pointf3* point) %code{% THIS->merge(*point); %};
+ void merge_point(Vec3d* point) %code{% THIS->merge(*point); %};
void scale(double factor);
void translate(double x, double y, double z);
void offset(double delta);
- bool contains_point(Pointf3* point) %code{% RETVAL = THIS->contains(*point); %};
- Clone<Pointf3> size();
- Clone<Pointf3> center();
+ bool contains_point(Vec3d* point) %code{% RETVAL = THIS->contains(*point); %};
+ Clone<Vec3d> size();
+ Clone<Vec3d> center();
double radius();
bool empty() %code{% RETVAL = empty(*THIS); %};
- Clone<Pointf3> min_point() %code{% RETVAL = THIS->min; %};
- Clone<Pointf3> max_point() %code{% RETVAL = THIS->max; %};
- double x_min() %code{% RETVAL = THIS->min.x; %};
- double x_max() %code{% RETVAL = THIS->max.x; %};
- double y_min() %code{% RETVAL = THIS->min.y; %};
- double y_max() %code{% RETVAL = THIS->max.y; %};
- double z_min() %code{% RETVAL = THIS->min.z; %};
- double z_max() %code{% RETVAL = THIS->max.z; %};
- std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf,%lf;%lf,%lf,%lf", THIS->min.x, THIS->min.y, THIS->min.z, THIS->max.x, THIS->max.y, THIS->max.z); RETVAL = buf; %};
+ Clone<Vec3d> min_point() %code{% RETVAL = THIS->min; %};
+ Clone<Vec3d> max_point() %code{% RETVAL = THIS->max; %};
+ double x_min() %code{% RETVAL = THIS->min(0); %};
+ double x_max() %code{% RETVAL = THIS->max(0); %};
+ double y_min() %code{% RETVAL = THIS->min(1); %};
+ double y_max() %code{% RETVAL = THIS->max(1); %};
+ double z_min() %code{% RETVAL = THIS->min(2); %};
+ double z_max() %code{% RETVAL = THIS->max(2); %};
+ std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf,%lf;%lf,%lf,%lf", THIS->min(0), THIS->min(1), THIS->min(2), THIS->max(0), THIS->max(1), THIS->max(2)); RETVAL = buf; %};
bool defined() %code{% RETVAL = THIS->defined; %};
};
diff --git a/xs/xsp/Config.xsp b/xs/xsp/Config.xsp
index 6adfc49a2..b8ad84ba4 100644
--- a/xs/xsp/Config.xsp
+++ b/xs/xsp/Config.xsp
@@ -74,13 +74,13 @@
static StaticPrintConfig* new_GCodeConfig()
%code{% RETVAL = new GCodeConfig(); %};
static StaticPrintConfig* new_PrintConfig()
- %code{% RETVAL = new PrintConfig(); %};
+ %code{% RETVAL = static_cast<GCodeConfig*>(new PrintConfig()); %};
static StaticPrintConfig* new_PrintObjectConfig()
%code{% RETVAL = new PrintObjectConfig(); %};
static StaticPrintConfig* new_PrintRegionConfig()
%code{% RETVAL = new PrintRegionConfig(); %};
static StaticPrintConfig* new_FullPrintConfig()
- %code{% RETVAL = static_cast<PrintObjectConfig*>(new FullPrintConfig()); %};
+ %code{% RETVAL = static_cast<GCodeConfig*>(new FullPrintConfig()); %};
~StaticPrintConfig();
bool has(t_config_option_key opt_key);
SV* as_hash()
@@ -119,7 +119,7 @@
auto config = new FullPrintConfig();
try {
config->load(path);
- RETVAL = static_cast<PrintObjectConfig*>(config);
+ RETVAL = static_cast<GCodeConfig*>(config);
} catch (std::exception& e) {
delete config;
croak("Error extracting configuration from %s:\n%s\n", path, e.what());
diff --git a/xs/xsp/GCode.xsp b/xs/xsp/GCode.xsp
index b4cb7c0e9..9e04edd4c 100644
--- a/xs/xsp/GCode.xsp
+++ b/xs/xsp/GCode.xsp
@@ -23,7 +23,7 @@
try {
THIS->do_export(print, path);
} catch (std::exception& e) {
- croak(e.what());
+ croak("%s\n", e.what());
}
%};
void do_export_w_preview(Print *print, const char *path, GCodePreviewData *preview_data)
@@ -31,13 +31,13 @@
try {
THIS->do_export(print, path, preview_data);
} catch (std::exception& e) {
- croak(e.what());
+ croak("%s\n", e.what());
}
%};
- Ref<Pointf> origin()
+ Ref<Vec2d> origin()
%code{% RETVAL = &(THIS->origin()); %};
- void set_origin(Pointf* pointf)
+ void set_origin(Vec2d* pointf)
%code{% THIS->set_origin(*pointf); %};
Ref<Point> last_pos()
%code{% RETVAL = &(THIS->last_pos()); %};
diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp
index a7f3bd554..f8769d358 100644
--- a/xs/xsp/GUI.xsp
+++ b/xs/xsp/GUI.xsp
@@ -4,11 +4,16 @@
#include <xsinit.h>
#include "slic3r/GUI/GUI.hpp"
#include "slic3r/Utils/ASCIIFolding.hpp"
+#include "slic3r/Utils/FixModelByWin10.hpp"
+#include "slic3r/Utils/Serial.hpp"
%}
%package{Slic3r::GUI};
+void about()
+ %code{% Slic3r::GUI::about(); %};
+
void disable_screensaver()
%code{% Slic3r::GUI::disable_screensaver(); %};
@@ -16,7 +21,7 @@ void enable_screensaver()
%code{% Slic3r::GUI::enable_screensaver(); %};
std::vector<std::string> scan_serial_ports()
- %code{% RETVAL=Slic3r::GUI::scan_serial_ports(); %};
+ %code{% RETVAL=Slic3r::Utils::scan_serial_ports(); %};
bool debugged()
%code{% RETVAL=Slic3r::GUI::debugged(); %};
@@ -24,6 +29,9 @@ bool debugged()
void break_to_debugger()
%code{% Slic3r::GUI::break_to_debugger(); %};
+bool is_windows10()
+ %code{% RETVAL=Slic3r::is_windows10(); %};
+
void set_wxapp(SV *ui)
%code%{ Slic3r::GUI::set_wxapp((wxApp*)wxPli_sv_2_object(aTHX_ ui, "Wx::App")); %};
@@ -35,14 +43,17 @@ void set_tab_panel(SV *ui)
void set_plater(SV *ui)
%code%{ Slic3r::GUI::set_plater((wxPanel*)wxPli_sv_2_object(aTHX_ ui, "Wx::Panel")); %};
-
-void add_debug_menu(SV *ui, int event_language_change)
- %code%{ Slic3r::GUI::add_debug_menu((wxMenuBar*)wxPli_sv_2_object(aTHX_ ui, "Wx::MenuBar"), event_language_change); %};
+
+void add_menus(SV *ui, int event_preferences_changed, int event_language_change)
+ %code%{ Slic3r::GUI::add_menus((wxMenuBar*)wxPli_sv_2_object(aTHX_ ui, "Wx::MenuBar"), event_preferences_changed, event_language_change); %};
void create_preset_tabs(bool no_controller, int event_value_change, int event_presets_changed)
%code%{ Slic3r::GUI::create_preset_tabs(no_controller, event_value_change, event_presets_changed); %};
-Ref<TabIface> get_preset_tab(char *name)
+void show_error_id(int id, std::string msg)
+ %code%{ Slic3r::GUI::show_error_id(id, msg); %};
+
+TabIface* get_preset_tab(char *name)
%code%{ RETVAL=Slic3r::GUI::get_preset_tab_iface(name); %};
bool load_language()
@@ -57,12 +68,23 @@ int combochecklist_get_flags(SV *ui)
void set_app_config(AppConfig *app_config)
%code%{ Slic3r::GUI::set_app_config(app_config); %};
+bool check_unsaved_changes()
+ %code%{ RETVAL=Slic3r::GUI::check_unsaved_changes(); %};
+
+bool config_wizard_startup(int app_config_exists)
+ %code%{
+ RETVAL=Slic3r::GUI::config_wizard_startup(app_config_exists != 0);
+ %};
+
void open_preferences_dialog(int preferences_event)
%code%{ Slic3r::GUI::open_preferences_dialog(preferences_event); %};
void set_preset_bundle(PresetBundle *preset_bundle)
%code%{ Slic3r::GUI::set_preset_bundle(preset_bundle); %};
+void set_preset_updater(PresetUpdater* updater)
+ %code%{ Slic3r::GUI::set_preset_updater(updater); %};
+
void add_frequently_changed_parameters(SV *ui_parent, SV *ui_sizer, SV *ui_p_sizer)
%code%{ Slic3r::GUI::add_frequently_changed_parameters((wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"),
(wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"),
@@ -71,5 +93,99 @@ void add_frequently_changed_parameters(SV *ui_parent, SV *ui_sizer, SV *ui_p_siz
void set_print_callback_event(Print *print, int id)
%code%{ Slic3r::GUI::set_print_callback_event(print, id); %};
+void add_expert_mode_part( SV *ui_parent, SV *ui_sizer,
+ Model *model,
+ int event_object_selection_changed,
+ int event_object_settings_changed,
+ int event_remove_object,
+ int event_update_scene)
+ %code%{ Slic3r::GUI::add_expert_mode_part( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"),
+ (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"),
+ *model,
+ event_object_selection_changed,
+ event_object_settings_changed,
+ event_remove_object,
+ event_update_scene); %};
+
+void set_objects_from_perl( SV *ui_parent,
+ SV *frequently_changed_parameters_sizer,
+ SV *expert_mode_part_sizer,
+ SV *scrolled_window_sizer,
+ SV *btn_export_gcode,
+ SV *btn_export_stl,
+ SV *btn_reslice,
+ SV *btn_print,
+ SV *btn_send_gcode,
+ SV *manifold_warning_icon)
+ %code%{ Slic3r::GUI::set_objects_from_perl(
+ (wxWindow *)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"),
+ (wxBoxSizer *)wxPli_sv_2_object(aTHX_ frequently_changed_parameters_sizer, "Wx::BoxSizer"),
+ (wxBoxSizer *)wxPli_sv_2_object(aTHX_ expert_mode_part_sizer, "Wx::BoxSizer"),
+ (wxBoxSizer *)wxPli_sv_2_object(aTHX_ scrolled_window_sizer, "Wx::BoxSizer"),
+ (wxButton *)wxPli_sv_2_object(aTHX_ btn_export_gcode, "Wx::Button"),
+ (wxButton *)wxPli_sv_2_object(aTHX_ btn_export_stl, "Wx::Button"),
+ (wxButton *)wxPli_sv_2_object(aTHX_ btn_reslice, "Wx::Button"),
+ (wxButton *)wxPli_sv_2_object(aTHX_ btn_print, "Wx::Button"),
+ (wxButton *)wxPli_sv_2_object(aTHX_ btn_send_gcode, "Wx::Button"),
+ (wxStaticBitmap *)wxPli_sv_2_object(aTHX_ manifold_warning_icon, "Wx::StaticBitmap")); %};
+
+void set_show_print_info(bool show)
+ %code%{ Slic3r::GUI::set_show_print_info(show); %};
+
+void set_show_manifold_warning_icon(bool show)
+ %code%{ Slic3r::GUI::set_show_manifold_warning_icon(show); %};
+
+void update_mode()
+ %code%{ Slic3r::GUI::update_mode(); %};
+
+void add_object_to_list(const char *name, SV *object_model)
+ %code%{ Slic3r::GUI::add_object_to_list(
+ name,
+ (ModelObject *)wxPli_sv_2_object(aTHX_ object_model, "Slic3r::Model::Object") ); %};
+
+void delete_object_from_list()
+ %code%{ Slic3r::GUI::delete_object_from_list(); %};
+
+void delete_all_objects_from_list()
+ %code%{ Slic3r::GUI::delete_all_objects_from_list(); %};
+
+void set_object_count(int idx, int count)
+ %code%{ Slic3r::GUI::set_object_count(idx, count); %};
+
+void unselect_objects()
+ %code%{ Slic3r::GUI::unselect_objects(); %};
+
+void select_current_object(int idx)
+ %code%{ Slic3r::GUI::select_current_object(idx); %};
+
+void remove_obj()
+ %code%{ Slic3r::GUI::remove(); %};
+
std::string fold_utf8_to_ascii(const char *src)
%code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %};
+
+void add_export_option(SV *ui, std::string format)
+ %code%{ Slic3r::GUI::add_export_option((wxFileDialog*)wxPli_sv_2_object(aTHX_ ui, "Wx::FileDialog"), format); %};
+
+int get_export_option(SV *ui)
+ %code%{ RETVAL = Slic3r::GUI::get_export_option((wxFileDialog*)wxPli_sv_2_object(aTHX_ ui, "Wx::FileDialog")); %};
+
+void desktop_open_datadir_folder()
+ %code%{ Slic3r::GUI::desktop_open_datadir_folder(); %};
+
+void fix_model_by_win10_sdk_gui(ModelObject *model_object_src, Print *print, Model *model_dst)
+ %code%{ Slic3r::fix_model_by_win10_sdk_gui(*model_object_src, *print, *model_dst); %};
+
+void set_3DScene(SV *scene)
+ %code%{ Slic3r::GUI::set_3DScene((_3DScene *)wxPli_sv_2_object(aTHX_ scene, "Slic3r::Model::3DScene") ); %};
+
+void register_on_request_update_callback(SV* callback)
+ %code%{ Slic3r::GUI::g_on_request_update_callback.register_callback(callback); %};
+
+void deregister_on_request_update_callback()
+ %code%{ Slic3r::GUI::g_on_request_update_callback.deregister_callback(); %};
+
+//void create_double_slider(SV *ui_parent, SV *ui_ds)
+// %code%{ Slic3r::GUI::create_double_slider( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"),
+// (wxControl*)wxPli_sv_2_object(aTHX_ ui_ds, "Wx::Control")); %};
+
diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp
index 25aa6b81a..4c3c5501e 100644
--- a/xs/xsp/GUI_3DScene.xsp
+++ b/xs/xsp/GUI_3DScene.xsp
@@ -8,7 +8,8 @@
GLShader();
~GLShader();
- bool load(const char *fragment_shader, const char *vertex_shader);
+ bool load_from_text(const char *fragment_shader, const char *vertex_shader);
+ bool load_from_file(const char *fragment_shader, const char *vertex_shader);
void release();
int get_attrib_location(const char *name) const;
@@ -54,13 +55,12 @@
int object_idx() const;
int volume_idx() const;
int instance_idx() const;
- Clone<Pointf3> origin() const
- %code%{ RETVAL = THIS->origin; %};
+ Clone<Vec3d> origin() const
+ %code%{ RETVAL = THIS->get_offset(); %};
void translate(double x, double y, double z)
- %code%{ THIS->origin.translate(x, y, z); %};
+ %code%{ THIS->set_offset(THIS->get_offset() + Vec3d(x, y, z)); %};
Clone<BoundingBoxf3> bounding_box() const
%code%{ RETVAL = THIS->bounding_box; %};
- Clone<BoundingBoxf3> transformed_bounding_box() const;
bool empty() const;
bool indexed() const;
@@ -84,7 +84,7 @@
std::vector<int> load_object(ModelObject *object, int obj_idx, std::vector<int> instance_idxs, std::string color_by, std::string select_by, std::string drag_by, bool use_VBOs);
- int load_wipe_tower_preview(int obj_idx, float pos_x, float pos_y, float width, float depth, float height, bool use_VBOs);
+ int load_wipe_tower_preview(int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool use_VBOs, bool size_unknown, float brim_width);
void erase()
%code{% THIS->clear(); %};
@@ -92,10 +92,6 @@
int count()
%code{% RETVAL = THIS->volumes.size(); %};
- std::vector<double> get_current_print_zs()
- %code{% RETVAL = THIS->get_current_print_zs(); %};
-
-
void set_range(double low, double high);
void render_VBOs() const;
@@ -104,7 +100,9 @@
void release_geometry();
void set_print_box(float min_x, float min_y, float min_z, float max_x, float max_y, float max_z);
- void update_outside_state(DynamicPrintConfig* config, bool all_inside);
+
+ void reset_outside_state();
+ void update_colors_by_extruder(DynamicPrintConfig* config);
bool move_volume_up(int idx)
%code%{
@@ -150,104 +148,655 @@ GLVolumeCollection::arrayref()
%package{Slic3r::GUI::_3DScene};
%{
+std::string
+get_gl_info(format_as_html, extensions)
+ bool format_as_html;
+ bool extensions;
+ CODE:
+ RETVAL = _3DScene::get_gl_info(format_as_html, extensions);
+ OUTPUT:
+ RETVAL
+
+bool
+use_VBOs()
+ CODE:
+ RETVAL = _3DScene::use_VBOs();
+ OUTPUT:
+ RETVAL
+
+bool
+add_canvas(canvas)
+ SV *canvas;
+ CODE:
+ RETVAL = _3DScene::add_canvas((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+ OUTPUT:
+ RETVAL
+
+bool
+remove_canvas(canvas)
+ SV *canvas;
+ CODE:
+ RETVAL = _3DScene::remove_canvas((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+ OUTPUT:
+ RETVAL
+
+void
+remove_all_canvases()
+ CODE:
+ _3DScene::remove_all_canvases();
void
-_glew_init()
+set_as_dirty(canvas)
+ SV *canvas;
CODE:
- _3DScene::_glew_init();
+ _3DScene::set_as_dirty((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
unsigned int
-finalize_legend_texture()
+get_volumes_count(canvas)
+ SV *canvas;
CODE:
- RETVAL = _3DScene::finalize_legend_texture();
+ RETVAL = _3DScene::get_volumes_count((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
-unsigned int
-get_legend_texture_width()
+void
+reset_volumes(canvas)
+ SV *canvas;
+ CODE:
+ _3DScene::reset_volumes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+
+void
+deselect_volumes(canvas)
+ SV *canvas;
+ CODE:
+ _3DScene::deselect_volumes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+
+void
+select_volume(canvas, id)
+ SV *canvas;
+ unsigned int id;
+ CODE:
+ _3DScene::select_volume((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), id);
+
+void
+update_volumes_selection(canvas, selections)
+ SV *canvas;
+ std::vector<int> selections;
+ CODE:
+ _3DScene::update_volumes_selection((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), selections);
+
+int
+check_volumes_outside_state(canvas, config)
+ SV *canvas;
+ DynamicPrintConfig *config;
CODE:
- RETVAL = _3DScene::get_legend_texture_width();
+ RETVAL = _3DScene::check_volumes_outside_state((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), config);
OUTPUT:
RETVAL
-unsigned int
-get_legend_texture_height()
+bool
+move_volume_up(canvas, id)
+ SV *canvas;
+ unsigned int id;
+ CODE:
+ RETVAL = _3DScene::move_volume_up((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), id);
+ OUTPUT:
+ RETVAL
+
+bool
+move_volume_down(canvas, id)
+ SV *canvas;
+ unsigned int id;
CODE:
- RETVAL = _3DScene::get_legend_texture_height();
+ RETVAL = _3DScene::move_volume_down((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), id);
OUTPUT:
RETVAL
-
+
void
-reset_legend_texture()
+set_objects_selections(canvas, selections)
+ SV *canvas;
+ std::vector<int> selections;
CODE:
- _3DScene::reset_legend_texture();
+ _3DScene::set_objects_selections((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), selections);
void
-generate_warning_texture(std::string msg)
+set_config(canvas, config)
+ SV *canvas;
+ DynamicPrintConfig *config;
CODE:
- _3DScene::generate_warning_texture(msg);
+ _3DScene::set_config((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), config);
-unsigned int
-finalize_warning_texture()
+void
+set_print(canvas, print)
+ SV *canvas;
+ Print *print;
+ CODE:
+ _3DScene::set_print((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), print);
+
+void
+set_model(canvas, model)
+ SV *canvas;
+ Model *model;
+ CODE:
+ _3DScene::set_model((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), model);
+
+void
+set_bed_shape(canvas, shape)
+ SV *canvas;
+ Pointfs shape;
+ CODE:
+ _3DScene::set_bed_shape((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), shape);
+
+void
+set_auto_bed_shape(canvas)
+ SV *canvas;
CODE:
- RETVAL = _3DScene::finalize_warning_texture();
+ _3DScene::set_auto_bed_shape((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+
+Clone<BoundingBoxf3>
+get_volumes_bounding_box(canvas)
+ SV *canvas;
+ CODE:
+ RETVAL = _3DScene::get_volumes_bounding_box((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
-unsigned int
-get_warning_texture_width()
+void
+set_axes_length(canvas, length)
+ SV *canvas;
+ float length;
CODE:
- RETVAL = _3DScene::get_warning_texture_width();
+ _3DScene::set_axes_length((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), length);
+
+void
+set_cutting_plane(canvas, z, polygons)
+ SV *canvas;
+ float z;
+ ExPolygons polygons;
+ CODE:
+ _3DScene::set_cutting_plane((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), z, polygons);
+
+void
+set_color_by(canvas, value)
+ SV *canvas;
+ std::string value;
+ CODE:
+ _3DScene::set_color_by((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), value);
+
+void
+set_select_by(canvas, value)
+ SV *canvas;
+ std::string value;
+ CODE:
+ _3DScene::set_select_by((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), value);
+
+void
+set_drag_by(canvas, value)
+ SV *canvas;
+ std::string value;
+ CODE:
+ _3DScene::set_drag_by((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), value);
+
+std::string
+get_select_by(canvas)
+ SV *canvas;
+ CODE:
+ RETVAL = _3DScene::get_select_by((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
-unsigned int
-get_warning_texture_height()
+bool
+is_layers_editing_enabled(canvas)
+ SV *canvas;
+ CODE:
+ RETVAL = _3DScene::is_layers_editing_enabled((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+ OUTPUT:
+ RETVAL
+
+bool
+is_layers_editing_allowed(canvas)
+ SV *canvas;
+ CODE:
+ RETVAL = _3DScene::is_layers_editing_allowed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+ OUTPUT:
+ RETVAL
+
+bool
+is_shader_enabled(canvas)
+ SV *canvas;
+ CODE:
+ RETVAL = _3DScene::is_shader_enabled((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+ OUTPUT:
+ RETVAL
+
+bool
+is_reload_delayed(canvas)
+ SV *canvas;
CODE:
- RETVAL = _3DScene::get_warning_texture_height();
+ RETVAL = _3DScene::is_reload_delayed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
OUTPUT:
RETVAL
void
-reset_warning_texture()
+enable_layers_editing(canvas, enable)
+ SV *canvas;
+ bool enable;
+ CODE:
+ _3DScene::enable_layers_editing((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
+
+void
+enable_warning_texture(canvas, enable)
+ SV *canvas;
+ bool enable;
+ CODE:
+ _3DScene::enable_warning_texture((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
+
+void
+enable_legend_texture(canvas, enable)
+ SV *canvas;
+ bool enable;
CODE:
- _3DScene::reset_warning_texture();
+ _3DScene::enable_legend_texture((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
void
-_load_print_toolpaths(print, volumes, tool_colors, use_VBOs)
- Print *print;
- GLVolumeCollection *volumes;
- std::vector<std::string> tool_colors;
- int use_VBOs;
+enable_picking(canvas, enable)
+ SV *canvas;
+ bool enable;
CODE:
- _3DScene::_load_print_toolpaths(print, volumes, tool_colors, use_VBOs != 0);
+ _3DScene::enable_picking((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
-void
-_load_print_object_toolpaths(print_object, volumes, tool_colors, use_VBOs)
- PrintObject *print_object;
- GLVolumeCollection *volumes;
- std::vector<std::string> tool_colors;
- int use_VBOs;
+void
+enable_moving(canvas, enable)
+ SV *canvas;
+ bool enable;
+ CODE:
+ _3DScene::enable_moving((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
+
+void
+enable_gizmos(canvas, enable)
+ SV *canvas;
+ bool enable;
+ CODE:
+ _3DScene::enable_gizmos((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
+
+void
+enable_shader(canvas, enable)
+ SV *canvas;
+ bool enable;
+ CODE:
+ _3DScene::enable_shader((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
+
+void
+enable_toolbar(canvas, enable)
+ SV *canvas;
+ bool enable;
+ CODE:
+ _3DScene::enable_toolbar((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
+
+void
+enable_force_zoom_to_bed(canvas, enable)
+ SV *canvas;
+ bool enable;
+ CODE:
+ _3DScene::enable_force_zoom_to_bed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
+
+void
+enable_dynamic_background(canvas, enable)
+ SV *canvas;
+ bool enable;
+ CODE:
+ _3DScene::enable_dynamic_background((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), enable);
+
+void
+allow_multisample(canvas, allow)
+ SV *canvas;
+ bool allow;
+ CODE:
+ _3DScene::allow_multisample((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), allow);
+
+void
+enable_toolbar_item(canvas, item, enable)
+ SV *canvas;
+ std::string item;
+ bool enable;
+ CODE:
+ _3DScene::enable_toolbar_item((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), item, enable);
+
+bool
+is_toolbar_item_pressed(canvas, item)
+ SV *canvas;
+ std::string item;
+ CODE:
+ RETVAL = _3DScene::is_toolbar_item_pressed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), item);
+ OUTPUT:
+ RETVAL
+
+void
+zoom_to_bed(canvas)
+ SV *canvas;
+ CODE:
+ _3DScene::zoom_to_bed((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+
+void
+zoom_to_volumes(canvas)
+ SV *canvas;
+ CODE:
+ _3DScene::zoom_to_volumes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+
+void
+select_view(canvas, direction)
+ SV *canvas;
+ std::string direction;
+ CODE:
+ _3DScene::select_view((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), direction);
+
+void
+set_viewport_from_scene(canvas, other)
+ SV *canvas;
+ SV *other;
+ CODE:
+ _3DScene::set_viewport_from_scene((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (wxGLCanvas*)wxPli_sv_2_object(aTHX_ other, "Wx::GLCanvas"));
+
+void
+update_volumes_colors_by_extruder(canvas)
+ SV *canvas;
+ CODE:
+ _3DScene::update_volumes_colors_by_extruder((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+
+void
+update_gizmos_data(canvas)
+ SV *canvas;
+ CODE:
+ _3DScene::update_gizmos_data((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+
+void
+render(canvas)
+ SV *canvas;
+ CODE:
+ _3DScene::render((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"));
+
+std::vector<double>
+get_current_print_zs(canvas, active_only)
+ SV *canvas;
+ bool active_only;
+ CODE:
+ RETVAL = _3DScene::get_current_print_zs((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), active_only);
+ OUTPUT:
+ RETVAL
+
+void
+set_toolpaths_range(canvas, low, high)
+ SV *canvas;
+ double low;
+ double high;
+ CODE:
+ _3DScene::set_toolpaths_range((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), low, high);
+
+void
+register_on_viewport_changed_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_viewport_changed_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_double_click_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_double_click_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_right_click_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_right_click_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_select_object_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_select_object_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_model_update_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_model_update_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_remove_object_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
CODE:
- _3DScene::_load_print_object_toolpaths(print_object, volumes, tool_colors, use_VBOs != 0);
+ _3DScene::register_on_remove_object_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
void
-_load_wipe_tower_toolpaths(print, volumes, tool_colors, use_VBOs)
- Print *print;
- GLVolumeCollection *volumes;
- std::vector<std::string> tool_colors;
- int use_VBOs;
+register_on_arrange_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
CODE:
- _3DScene::_load_wipe_tower_toolpaths(print, volumes, tool_colors, use_VBOs != 0);
+ _3DScene::register_on_arrange_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_rotate_object_left_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_rotate_object_left_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_rotate_object_right_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_rotate_object_right_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_scale_object_uniformly_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_scale_object_uniformly_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_increase_objects_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_increase_objects_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_decrease_objects_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_decrease_objects_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_instance_moved_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_instance_moved_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_wipe_tower_moved_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_wipe_tower_moved_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_enable_action_buttons_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_enable_action_buttons_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_gizmo_scale_uniformly_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_gizmo_scale_uniformly_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_gizmo_rotate_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_gizmo_rotate_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_gizmo_flatten_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_gizmo_flatten_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_on_update_geometry_info_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_on_update_geometry_info_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_action_add_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_action_add_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_action_delete_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_action_delete_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_action_deleteall_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_action_deleteall_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_action_arrange_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_action_arrange_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_action_more_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_action_more_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_action_fewer_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_action_fewer_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_action_split_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_action_split_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_action_cut_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_action_cut_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_action_settings_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_action_settings_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_action_layersediting_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_action_layersediting_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+register_action_selectbyparts_callback(canvas, callback)
+ SV *canvas;
+ SV *callback;
+ CODE:
+ _3DScene::register_action_selectbyparts_callback((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), (void*)callback);
+
+void
+reset_legend_texture()
+ CODE:
+ _3DScene::reset_legend_texture();
+
+std::vector<int>
+load_model_object(canvas, model_object, obj_idx, instance_idxs)
+ SV *canvas;
+ ModelObject *model_object;
+ int obj_idx;
+ std::vector<int> instance_idxs;
+ CODE:
+ RETVAL = _3DScene::load_object((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), model_object, obj_idx, instance_idxs);
+ OUTPUT:
+ RETVAL
+
+int
+get_first_volume_id(canvas, obj_idx)
+ SV *canvas;
+ int obj_idx;
+ CODE:
+ RETVAL = _3DScene::get_first_volume_id((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), obj_idx);
+ OUTPUT:
+ RETVAL
+
+std::vector<int>
+load_model(canvas, model, obj_idx)
+ SV *canvas;
+ Model *model;
+ int obj_idx;
+ CODE:
+ RETVAL = _3DScene::load_object((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), model, obj_idx);
+ OUTPUT:
+ RETVAL
+
+void
+reload_scene(canvas, force)
+ SV *canvas;
+ bool force;
+ CODE:
+ _3DScene::reload_scene((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), force);
void
-load_gcode_preview(print, preview_data, volumes, str_tool_colors, use_VBOs)
- Print *print;
+load_gcode_preview(canvas, preview_data, str_tool_colors)
+ SV *canvas;
GCodePreviewData *preview_data;
- GLVolumeCollection *volumes;
std::vector<std::string> str_tool_colors;
- int use_VBOs;
CODE:
- _3DScene::load_gcode_preview(print, preview_data, volumes, str_tool_colors, use_VBOs != 0);
-
+ _3DScene::load_gcode_preview((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), preview_data, str_tool_colors);
+
+void
+load_preview(canvas, str_tool_colors)
+ SV *canvas;
+ std::vector<std::string> str_tool_colors;
+ CODE:
+ _3DScene::load_preview((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), str_tool_colors);
+
%}
diff --git a/xs/xsp/GUI_AppConfig.xsp b/xs/xsp/GUI_AppConfig.xsp
index 8162b9a5e..08a88883d 100644
--- a/xs/xsp/GUI_AppConfig.xsp
+++ b/xs/xsp/GUI_AppConfig.xsp
@@ -41,4 +41,6 @@
void update_skein_dir(char *dir);
std::string get_last_output_dir(const char *alt = "");
void update_last_output_dir(char *dir);
+
+ void reset_selections();
};
diff --git a/xs/xsp/GUI_Preset.xsp b/xs/xsp/GUI_Preset.xsp
index 0033ebd0e..99d23a142 100644
--- a/xs/xsp/GUI_Preset.xsp
+++ b/xs/xsp/GUI_Preset.xsp
@@ -12,6 +12,7 @@
bool default() %code%{ RETVAL = THIS->is_default; %};
bool external() %code%{ RETVAL = THIS->is_external; %};
+ bool system() %code%{ RETVAL = THIS->is_system; %};
bool visible() %code%{ RETVAL = THIS->is_visible; %};
bool dirty() %code%{ RETVAL = THIS->is_dirty; %};
bool compatible() %code%{ RETVAL = THIS->is_compatible; %};
@@ -31,7 +32,6 @@
%name{Slic3r::GUI::PresetCollection} class PresetCollection {
Ref<Preset> preset(size_t idx) %code%{ RETVAL = &THIS->preset(idx); %};
- Ref<Preset> default_preset() %code%{ RETVAL = &THIS->default_preset(); %};
size_t size() const;
size_t num_visible() const;
std::string name() const;
@@ -43,9 +43,6 @@
Ref<Preset> find_preset(char *name, bool first_visible_if_not_found = false) %code%{ RETVAL = THIS->find_preset(name, first_visible_if_not_found); %};
- bool current_is_dirty();
- std::vector<std::string> current_dirty_options();
-
void update_tab_ui(SV *ui, bool show_incompatible)
%code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object( aTHX_ ui, "Wx::BitmapComboBox" );
THIS->update_tab_ui(cb, show_incompatible); %};
@@ -54,30 +51,6 @@
%code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object( aTHX_ ui, "Wx::BitmapComboBox" );
THIS->update_platter_ui(cb); %};
- bool update_dirty_ui(SV *ui)
- %code%{ RETVAL = THIS->update_dirty_ui((wxBitmapComboBox*)wxPli_sv_2_object(aTHX_ ui, "Wx::BitmapComboBox")); %};
-
- void select_preset(int idx);
- bool select_preset_by_name(char *name) %code%{ RETVAL = THIS->select_preset_by_name(name, true); %};
- void discard_current_changes();
-
- void save_current_preset(char *new_name)
- %code%{
- try {
- THIS->save_current_preset(new_name);
- } catch (std::exception& e) {
- croak("Error saving a preset %s:\n%s\n", new_name, e.what());
- }
- %};
- void delete_current_preset()
- %code%{
- try {
- THIS->delete_current_preset();
- } catch (std::exception& e) {
- croak("Error deleting a preset file %s:\n%s\n", THIS->get_selected_preset().file.c_str(), e.what());
- }
- %};
-
%{
SV*
@@ -110,10 +83,10 @@ PresetCollection::arrayref()
croak("Cannot create configuration directories:\n%s\n", e.what());
}
%};
- void load_presets()
+ void load_presets(AppConfig *config)
%code%{
try {
- THIS->load_presets();
+ THIS->load_presets(*config);
} catch (std::exception& e) {
croak("Loading of Slic3r presets from %s failed.\n\n%s\n",
Slic3r::data_dir().c_str(), e.what());
@@ -154,20 +127,19 @@ PresetCollection::arrayref()
void set_default_suppressed(bool default_suppressed);
- void load_selections (AppConfig *config) %code%{ THIS->load_selections(*config); %};
void export_selections(AppConfig *config) %code%{ THIS->export_selections(*config); %};
void export_selections_pp(PlaceholderParser *pp) %code%{ THIS->export_selections(*pp); %};
Ref<PresetCollection> print() %code%{ RETVAL = &THIS->prints; %};
Ref<PresetCollection> filament() %code%{ RETVAL = &THIS->filaments; %};
+ Ref<PresetCollection> sla_material() %code%{ RETVAL = &THIS->sla_materials; %};
Ref<PresetCollection> printer() %code%{ RETVAL = &THIS->printers; %};
+ Ref<DynamicPrintConfig> project_config() %code%{ RETVAL = &THIS->project_config; %};
+
bool has_defauls_only();
std::vector<std::string> filament_presets() %code%{ RETVAL = THIS->filament_presets; %};
void set_filament_preset(int idx, const char *name);
- void update_multi_material_filament_presets();
-
- void update_compatible_with_printer(bool select_other_if_incompatible);
Clone<DynamicPrintConfig> full_config() %code%{ RETVAL = THIS->full_config(); %};
@@ -175,15 +147,3 @@ PresetCollection::arrayref()
%code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object(aTHX_ ui, "Wx::BitmapComboBox");
THIS->update_platter_filament_ui(extruder_idx, cb); %};
};
-
-%name{Slic3r::GUI::PresetHints} class PresetHints {
- PresetHints();
- ~PresetHints();
-
- static std::string cooling_description(Preset *preset)
- %code%{ RETVAL = PresetHints::cooling_description(*preset); %};
- static std::string maximum_volumetric_flow_description(PresetBundle *preset)
- %code%{ RETVAL = PresetHints::maximum_volumetric_flow_description(*preset); %};
- static std::string recommended_thin_wall_thickness(PresetBundle *preset)
- %code%{ RETVAL = PresetHints::recommended_thin_wall_thickness(*preset); %};
-};
diff --git a/xs/xsp/GUI_Tab.xsp b/xs/xsp/GUI_Tab.xsp
index 9cacac74f..bcbdc0d9f 100644
--- a/xs/xsp/GUI_Tab.xsp
+++ b/xs/xsp/GUI_Tab.xsp
@@ -16,6 +16,7 @@
bool current_preset_is_dirty();
void load_key_value(char* opt_key, char* value);
void OnActivate();
+ size_t get_selected_preset_item();
std::string title();
Ref<DynamicPrintConfig> get_config();
Ref<PresetCollection> get_presets();
diff --git a/xs/xsp/Geometry.xsp b/xs/xsp/Geometry.xsp
index b23bbeffa..b7e92ba69 100644
--- a/xs/xsp/Geometry.xsp
+++ b/xs/xsp/Geometry.xsp
@@ -8,7 +8,7 @@
%package{Slic3r::Geometry};
-Pointfs arrange(size_t total_parts, Pointf* part, coordf_t dist, BoundingBoxf* bb = NULL)
+Pointfs arrange(size_t total_parts, Vec2d* part, coordf_t dist, BoundingBoxf* bb = NULL)
%code{%
Pointfs points;
if (! Slic3r::Geometry::arrange(total_parts, *part, dist, bb, points))
diff --git a/xs/xsp/Line.xsp b/xs/xsp/Line.xsp
index 92429e57a..777dc41fa 100644
--- a/xs/xsp/Line.xsp
+++ b/xs/xsp/Line.xsp
@@ -29,7 +29,6 @@
bool parallel_to_line(Line* line)
%code{% RETVAL = THIS->parallel_to(*line); %};
Clone<Point> midpoint();
- Clone<Point> point_at(double distance);
Clone<Point> intersection_infinite(Line* other)
%code{%
Point p;
@@ -37,8 +36,8 @@
if (!res) CONFESS("Intersection failed");
RETVAL = p;
%};
- Clone<Polyline> as_polyline()
- %code{% RETVAL = Polyline(*THIS); %};
+ Polyline* as_polyline()
+ %code{% RETVAL = new Polyline(THIS->a, THIS->b); %};
Clone<Point> normal();
Clone<Point> vector();
double ccw(Point* point)
@@ -70,7 +69,7 @@ Line::coincides_with(line_sv)
CODE:
Line line;
from_SV_check(line_sv, &line);
- RETVAL = THIS->coincides_with(line);
+ RETVAL = (*THIS) == line;
OUTPUT:
RETVAL
@@ -79,15 +78,15 @@ Line::coincides_with(line_sv)
%name{Slic3r::Linef3} class Linef3 {
- Linef3(Pointf3* a, Pointf3* b)
+ Linef3(Vec3d* a, Vec3d* b)
%code{% RETVAL = new Linef3(*a, *b); %};
~Linef3();
Clone<Linef3> clone()
%code{% RETVAL = THIS; %};
- Ref<Pointf3> a()
+ Ref<Vec3d> a()
%code{% RETVAL = &THIS->a; %};
- Ref<Pointf3> b()
+ Ref<Vec3d> b()
%code{% RETVAL = &THIS->b; %};
- Clone<Pointf3> intersect_plane(double z);
+ Clone<Vec3d> intersect_plane(double z);
void scale(double factor);
};
diff --git a/xs/xsp/Model.xsp b/xs/xsp/Model.xsp
index 78c94661e..a5925775d 100644
--- a/xs/xsp/Model.xsp
+++ b/xs/xsp/Model.xsp
@@ -81,7 +81,7 @@
bool add_default_instances();
Clone<BoundingBoxf3> bounding_box();
- void center_instances_around_point(Pointf* point)
+ void center_instances_around_point(Vec2d* point)
%code%{ THIS->center_instances_around_point(*point); %};
void translate(double x, double y, double z);
Clone<TriangleMesh> mesh();
@@ -95,19 +95,16 @@
void duplicate_objects_grid(unsigned int x, unsigned int y, double dist);
bool looks_like_multipart_object() const;
- void convert_multipart_object();
+ void convert_multipart_object(unsigned int max_extruders);
void print_info() const;
- bool fits_print_volume(DynamicPrintConfig* config) const
- %code%{ RETVAL = THIS->fits_print_volume(config); %};
-
bool store_stl(char *path, bool binary)
%code%{ TriangleMesh mesh = THIS->mesh(); RETVAL = Slic3r::store_stl(path, &mesh, binary); %};
- bool store_amf(char *path, Print* print)
- %code%{ RETVAL = Slic3r::store_amf(path, THIS, print); %};
- bool store_3mf(char *path, Print* print)
- %code%{ RETVAL = Slic3r::store_3mf(path, THIS, print); %};
+ bool store_amf(char *path, Print* print, bool export_print_config)
+ %code%{ RETVAL = Slic3r::store_amf(path, THIS, print, export_print_config); %};
+ bool store_3mf(char *path, Print* print, bool export_print_config)
+ %code%{ RETVAL = Slic3r::store_3mf(path, THIS, print, export_print_config); %};
%{
@@ -292,9 +289,9 @@ ModelMaterial::attributes()
void set_layer_height_profile(std::vector<double> profile)
%code%{ THIS->layer_height_profile = profile; THIS->layer_height_profile_valid = true; %};
- Ref<Pointf3> origin_translation()
+ Ref<Vec3d> origin_translation()
%code%{ RETVAL = &THIS->origin_translation; %};
- void set_origin_translation(Pointf3* point)
+ void set_origin_translation(Vec3d* point)
%code%{ THIS->origin_translation = *point; %};
bool needed_repair() const;
@@ -302,9 +299,10 @@ ModelMaterial::attributes()
int facets_count();
void center_around_origin();
void translate(double x, double y, double z);
- void scale_xyz(Pointf3* versor)
+ void scale_xyz(Vec3d* versor)
%code{% THIS->scale(*versor); %};
- void rotate(float angle, Axis axis);
+ void rotate(float angle, Vec3d* axis)
+ %code{% THIS->rotate(angle, *axis); %};
void mirror(Axis axis);
Model* cut(double z)
@@ -346,7 +344,7 @@ ModelMaterial::attributes()
void set_modifier(bool modifier)
%code%{ THIS->modifier = modifier; %};
- size_t split();
+ size_t split(unsigned int max_extruders);
ModelMaterial* assign_unique_material();
};
@@ -360,14 +358,14 @@ ModelMaterial::attributes()
%code%{ RETVAL = THIS->rotation; %};
double scaling_factor()
%code%{ RETVAL = THIS->scaling_factor; %};
- Ref<Pointf> offset()
+ Ref<Vec2d> offset()
%code%{ RETVAL = &THIS->offset; %};
void set_rotation(double val)
%code%{ THIS->rotation = val; THIS->get_object()->invalidate_bounding_box(); %};
void set_scaling_factor(double val)
%code%{ THIS->scaling_factor = val; THIS->get_object()->invalidate_bounding_box(); %};
- void set_offset(Pointf *offset)
+ void set_offset(Vec2d *offset)
%code%{ THIS->offset = *offset; %};
void transform_mesh(TriangleMesh* mesh, bool dont_translate = false) const;
diff --git a/xs/xsp/PlaceholderParser.xsp b/xs/xsp/PlaceholderParser.xsp
index 244f89cf8..5fa4e33aa 100644
--- a/xs/xsp/PlaceholderParser.xsp
+++ b/xs/xsp/PlaceholderParser.xsp
@@ -18,7 +18,7 @@
try {
RETVAL = THIS->process(str, 0);
} catch (std::exception& e) {
- croak(e.what());
+ croak("%s\n", e.what());
}
%};
@@ -27,7 +27,7 @@
try {
RETVAL = THIS->evaluate_boolean_expression(str, THIS->config());
} catch (std::exception& e) {
- croak(e.what());
+ croak("%s\n", e.what());
}
%};
};
diff --git a/xs/xsp/Point.xsp b/xs/xsp/Point.xsp
index b7aded6a0..beefc6249 100644
--- a/xs/xsp/Point.xsp
+++ b/xs/xsp/Point.xsp
@@ -3,6 +3,7 @@
%{
#include <xsinit.h>
#include "libslic3r/Point.hpp"
+#include "libslic3r/Line.hpp"
#include "libslic3r/Polygon.hpp"
#include "libslic3r/Polyline.hpp"
%}
@@ -12,44 +13,44 @@
~Point();
Clone<Point> clone()
%code{% RETVAL=THIS; %};
- void scale(double factor);
- void translate(double x, double y);
+ void scale(double factor)
+ %code{% *THIS *= factor; %};
+ void translate(double x, double y)
+ %code{% *THIS += Point(x, y); %};
SV* arrayref()
%code{% RETVAL = to_SV_pureperl(THIS); %};
SV* pp()
%code{% RETVAL = to_SV_pureperl(THIS); %};
int x()
- %code{% RETVAL = THIS->x; %};
+ %code{% RETVAL = (*THIS)(0); %};
int y()
- %code{% RETVAL = THIS->y; %};
+ %code{% RETVAL = (*THIS)(1); %};
void set_x(int val)
- %code{% THIS->x = val; %};
+ %code{% (*THIS)(0) = val; %};
void set_y(int val)
- %code{% THIS->y = val; %};
+ %code{% (*THIS)(1) = val; %};
int nearest_point_index(Points points);
Clone<Point> nearest_point(Points points)
%code{% Point p; THIS->nearest_point(points, &p); RETVAL = p; %};
double distance_to(Point* point)
- %code{% RETVAL = THIS->distance_to(*point); %};
+ %code{% RETVAL = (*point - *THIS).cast<double>().norm(); %};
double distance_to_line(Line* line)
- %code{% RETVAL = THIS->distance_to(*line); %};
+ %code{% RETVAL = line->distance_to(*THIS); %};
double perp_distance_to_line(Line* line)
- %code{% RETVAL = THIS->perp_distance_to(*line); %};
+ %code{% RETVAL = line->perp_distance_to(*THIS); %};
double ccw(Point* p1, Point* p2)
%code{% RETVAL = THIS->ccw(*p1, *p2); %};
double ccw_angle(Point* p1, Point* p2)
%code{% RETVAL = THIS->ccw_angle(*p1, *p2); %};
- Clone<Point> projection_onto_polygon(Polygon* polygon)
+ Point* projection_onto_polygon(Polygon* polygon)
%code{% RETVAL = new Point(THIS->projection_onto(*polygon)); %};
- Clone<Point> projection_onto_polyline(Polyline* polyline)
+ Point* projection_onto_polyline(Polyline* polyline)
%code{% RETVAL = new Point(THIS->projection_onto(*polyline)); %};
- Clone<Point> projection_onto_line(Line* line)
+ Point* projection_onto_line(Line* line)
%code{% RETVAL = new Point(THIS->projection_onto(*line)); %};
- Clone<Point> negative()
- %code{% RETVAL = new Point(THIS->negative()); %};
- bool coincides_with_epsilon(Point* point)
- %code{% RETVAL = THIS->coincides_with_epsilon(*point); %};
- std::string serialize() %code{% char buf[2048]; sprintf(buf, "%ld,%ld", THIS->x, THIS->y); RETVAL = buf; %};
+ Point* negative()
+ %code{% RETVAL = new Point(- *THIS); %};
+ std::string serialize() %code{% char buf[2048]; sprintf(buf, "%ld,%ld", (*THIS)(0), (*THIS)(1)); RETVAL = buf; %};
%{
@@ -68,7 +69,7 @@ Point::coincides_with(point_sv)
CODE:
Point point;
from_SV_check(point_sv, &point);
- RETVAL = THIS->coincides_with(point);
+ RETVAL = (*THIS) == point;
OUTPUT:
RETVAL
@@ -76,72 +77,62 @@ Point::coincides_with(point_sv)
};
-%name{Slic3r::Point3} class Point3 {
- Point3(int _x = 0, int _y = 0, int _z = 0);
- ~Point3();
- Clone<Point3> clone()
- %code{% RETVAL = THIS; %};
- int x()
- %code{% RETVAL = THIS->x; %};
- int y()
- %code{% RETVAL = THIS->y; %};
- int z()
- %code{% RETVAL = THIS->z; %};
- std::string serialize() %code{% char buf[2048]; sprintf(buf, "%ld,%ld,%ld", THIS->x, THIS->y, THIS->z); RETVAL = buf; %};
-};
-
-%name{Slic3r::Pointf} class Pointf {
- Pointf(double _x = 0, double _y = 0);
- ~Pointf();
- Clone<Pointf> clone()
+%name{Slic3r::Pointf} class Vec2d {
+ Vec2d(double _x = 0, double _y = 0);
+ ~Vec2d();
+ Clone<Vec2d> clone()
%code{% RETVAL = THIS; %};
SV* arrayref()
%code{% RETVAL = to_SV_pureperl(THIS); %};
SV* pp()
%code{% RETVAL = to_SV_pureperl(THIS); %};
double x()
- %code{% RETVAL = THIS->x; %};
+ %code{% RETVAL = (*THIS)(0); %};
double y()
- %code{% RETVAL = THIS->y; %};
+ %code{% RETVAL = (*THIS)(1); %};
void set_x(double val)
- %code{% THIS->x = val; %};
+ %code{% (*THIS)(0) = val; %};
void set_y(double val)
- %code{% THIS->y = val; %};
- void translate(double x, double y);
- void scale(double factor);
- void rotate(double angle, Pointf* center)
- %code{% THIS->rotate(angle, *center); %};
- Clone<Pointf> negative()
- %code{% RETVAL = THIS->negative(); %};
- Clone<Pointf> vector_to(Pointf* point)
- %code{% RETVAL = THIS->vector_to(*point); %};
- std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf", THIS->x, THIS->y); RETVAL = buf; %};
+ %code{% (*THIS)(1) = val; %};
+ void translate(double x, double y)
+ %code{% *THIS += Vec2d(x, y); %};
+ void scale(double factor)
+ %code{% *THIS *= factor; %};
+ void rotate(double angle, Vec2d* center)
+ %code{% *THIS = Eigen::Translation2d(*center) * Eigen::Rotation2Dd(angle) * Eigen::Translation2d(- *center) * Eigen::Vector2d((*THIS)(0), (*THIS)(1)); %};
+ Vec2d* negative()
+ %code{% RETVAL = new Vec2d(- *THIS); %};
+ Vec2d* vector_to(Vec2d* point)
+ %code{% RETVAL = new Vec2d(*point - *THIS); %};
+ std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf", (*THIS)(0), (*THIS)(1)); RETVAL = buf; %};
};
-%name{Slic3r::Pointf3} class Pointf3 {
- Pointf3(double _x = 0, double _y = 0, double _z = 0);
- ~Pointf3();
- Clone<Pointf3> clone()
+%name{Slic3r::Pointf3} class Vec3d {
+ Vec3d(double _x = 0, double _y = 0, double _z = 0);
+ ~Vec3d();
+ Clone<Vec3d> clone()
%code{% RETVAL = THIS; %};
double x()
- %code{% RETVAL = THIS->x; %};
+ %code{% RETVAL = (*THIS)(0); %};
double y()
- %code{% RETVAL = THIS->y; %};
+ %code{% RETVAL = (*THIS)(1); %};
double z()
- %code{% RETVAL = THIS->z; %};
+ %code{% RETVAL = (*THIS)(2); %};
void set_x(double val)
- %code{% THIS->x = val; %};
+ %code{% (*THIS)(0) = val; %};
void set_y(double val)
- %code{% THIS->y = val; %};
+ %code{% (*THIS)(1) = val; %};
void set_z(double val)
- %code{% THIS->z = val; %};
- void translate(double x, double y, double z);
- void scale(double factor);
- double distance_to(Pointf3* point)
- %code{% RETVAL = THIS->distance_to(*point); %};
- Clone<Pointf3> negative()
- %code{% RETVAL = THIS->negative(); %};
- Clone<Pointf3> vector_to(Pointf3* point)
- %code{% RETVAL = THIS->vector_to(*point); %};
- std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf,%lf", THIS->x, THIS->y, THIS->z); RETVAL = buf; %};
+ %code{% (*THIS)(2) = val; %};
+ void translate(double x, double y, double z)
+ %code{% *THIS += Vec3d(x, y, z); %};
+ void scale(double factor)
+ %code{% *THIS *= factor; %};
+ double distance_to(Vec3d* point)
+ %code{% RETVAL = (*point - *THIS).norm(); %};
+ Vec3d* negative()
+ %code{% RETVAL = new Vec3d(- *THIS); %};
+ Vec3d* vector_to(Vec3d* point)
+ %code{% RETVAL = new Vec3d(*point - *THIS); %};
+ std::string serialize() %code{% char buf[2048]; sprintf(buf, "%lf,%lf,%lf", (*THIS)(0), (*THIS)(1), (*THIS)(2)); RETVAL = buf; %};
};
diff --git a/xs/xsp/Polygon.xsp b/xs/xsp/Polygon.xsp
index f5db9f515..a94425477 100644
--- a/xs/xsp/Polygon.xsp
+++ b/xs/xsp/Polygon.xsp
@@ -39,7 +39,6 @@
%code{% THIS->triangulate_convex(&RETVAL); %};
Clone<Point> centroid();
Clone<BoundingBox> bounding_box();
- std::string wkt();
Points concave_points(double angle);
Points convex_points(double angle);
Clone<Point> point_projection(Point* point)
diff --git a/xs/xsp/Polyline.xsp b/xs/xsp/Polyline.xsp
index 60d7c6aca..0dbd0e572 100644
--- a/xs/xsp/Polyline.xsp
+++ b/xs/xsp/Polyline.xsp
@@ -38,7 +38,6 @@
bool is_straight();
Clone<BoundingBox> bounding_box();
void remove_duplicate_points();
- std::string wkt();
%{
Polyline*
diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp
index 94c9d707d..bda8d2f2f 100644
--- a/xs/xsp/Print.xsp
+++ b/xs/xsp/Print.xsp
@@ -44,6 +44,8 @@ _constant()
int region_count()
%code%{ RETVAL = THIS->print()->regions().size(); %};
+ int region_volumes_count()
+ %code%{ RETVAL = THIS->region_volumes.size(); %};
Ref<Print> print();
Ref<ModelObject> model_object();
Ref<StaticPrintConfig> config()
@@ -53,14 +55,12 @@ _constant()
%code%{ RETVAL = THIS->layer_height_ranges; %};
std::vector<double> layer_height_profile()
%code%{ RETVAL = THIS->layer_height_profile; %};
- Ref<Point3> size()
- %code%{ RETVAL = &THIS->size; %};
Clone<BoundingBox> bounding_box();
Points _shifted_copies()
- %code%{ RETVAL = THIS->_shifted_copies; %};
+ %code%{ RETVAL = THIS->copies(); %};
- bool add_copy(Pointf* point)
+ bool add_copy(Vec2d* point)
%code%{ RETVAL = THIS->add_copy(*point); %};
bool delete_last_copy();
bool reload_model_instances();
@@ -76,17 +76,6 @@ _constant()
bool step_done(PrintObjectStep step)
%code%{ RETVAL = THIS->is_step_done(step); %};
- void adjust_layer_height_profile(coordf_t z, coordf_t layer_thickness_delta, coordf_t band_width, int action)
- %code%{
- THIS->update_layer_height_profile(THIS->model_object()->layer_height_profile);
- adjust_layer_height_profile(
- THIS->slicing_parameters(), THIS->model_object()->layer_height_profile, z, layer_thickness_delta, band_width, LayerHeightEditActionType(action));
- THIS->model_object()->layer_height_profile_valid = true;
- THIS->layer_height_profile_valid = false;
- %};
-
- void reset_layer_height_profile();
-
void slice();
};
@@ -95,15 +84,17 @@ _constant()
~Print();
Ref<StaticPrintConfig> config()
- %code%{ RETVAL = &THIS->config(); %};
+ %code%{ RETVAL = const_cast<GCodeConfig*>(static_cast<const GCodeConfig*>(&THIS->config())); %};
Ref<PlaceholderParser> placeholder_parser()
%code%{ RETVAL = &THIS->placeholder_parser(); %};
Ref<ExtrusionEntityCollection> skirt()
%code%{ RETVAL = const_cast<ExtrusionEntityCollection*>(&THIS->skirt()); %};
Ref<ExtrusionEntityCollection> brim()
%code%{ RETVAL = const_cast<ExtrusionEntityCollection*>(&THIS->brim()); %};
- std::string estimated_print_time()
- %code%{ RETVAL = THIS->print_statistics().estimated_print_time; %};
+ std::string estimated_normal_print_time()
+ %code%{ RETVAL = THIS->print_statistics().estimated_normal_print_time; %};
+ std::string estimated_silent_print_time()
+ %code%{ RETVAL = THIS->print_statistics().estimated_silent_print_time; %};
double total_used_filament()
%code%{ RETVAL = THIS->print_statistics().total_used_filament; %};
double total_extruded_volume()
@@ -112,7 +103,6 @@ _constant()
%code%{ RETVAL = THIS->print_statistics().total_weight; %};
double total_cost()
%code%{ RETVAL = THIS->print_statistics().total_cost; %};
-
PrintObjectPtrs* objects()
%code%{ RETVAL = const_cast<PrintObjectPtrs*>(&THIS->objects()); %};
void clear_objects();
@@ -157,9 +147,11 @@ _constant()
try {
RETVAL = THIS->output_filepath(path);
} catch (std::exception& e) {
- croak(e.what());
+ croak("%s\n", e.what());
}
%};
+
+ void print_to_png(std::string dirpath);
void add_model_object(ModelObject* model_object, int idx = -1);
bool apply_config(DynamicPrintConfig* config)
diff --git a/xs/xsp/ProgressStatusBar.xsp b/xs/xsp/ProgressStatusBar.xsp
new file mode 100644
index 000000000..f59895581
--- /dev/null
+++ b/xs/xsp/ProgressStatusBar.xsp
@@ -0,0 +1,48 @@
+%module{Slic3r::XS};
+
+%{
+#include <xsinit.h>
+#include "slic3r/GUI/ProgressStatusBar.hpp"
+%}
+
+%name{Slic3r::GUI::ProgressStatusBar} class ProgressStatusBar {
+ ProgressStatusBar();
+ ~ProgressStatusBar();
+
+ int GetProgress() const
+ %code%{ RETVAL=THIS->get_progress(); %};
+
+ void SetProgress(int val)
+ %code%{ THIS->set_progress(val); %};
+
+ void SetRange(int val = 100)
+ %code%{ THIS->set_range(val); %};
+
+ void ShowProgress(bool show)
+ %code%{ THIS->show_progress(show); %};
+
+ void StartBusy(int val = 100)
+ %code%{ THIS->start_busy(val); %};
+
+ void StopBusy()
+ %code%{ THIS->stop_busy(); %};
+
+ bool IsBusy() const
+ %code%{ RETVAL=THIS->is_busy(); %};
+
+ void Run(int rate)
+ %code%{ THIS->run(rate); %};
+
+ void Embed()
+ %code%{ THIS->embed(); %};
+
+ void SetStatusText(std::string txt)
+ %code%{ THIS->set_status_text(txt); %};
+
+ void ShowCancelButton()
+ %code%{ THIS->show_cancel_button(); %};
+
+ void HideCancelButton()
+ %code%{ THIS->hide_cancel_button(); %};
+
+}; \ No newline at end of file
diff --git a/xs/xsp/TriangleMesh.xsp b/xs/xsp/TriangleMesh.xsp
index 690d87120..95f2f7d52 100644
--- a/xs/xsp/TriangleMesh.xsp
+++ b/xs/xsp/TriangleMesh.xsp
@@ -16,7 +16,7 @@
void repair();
void WriteOBJFile(char* output_file);
void scale(float factor);
- void scale_xyz(Pointf3* versor)
+ void scale_xyz(Vec3d* versor)
%code{% THIS->scale(*versor); %};
void translate(float x, float y, float z);
void rotate_x(float angle);
@@ -33,7 +33,7 @@
ExPolygons horizontal_projection();
Clone<Polygon> convex_hull();
Clone<BoundingBoxf3> bounding_box();
- Clone<Pointf3> center()
+ Clone<Vec3d> center()
%code{% RETVAL = THIS->bounding_box().center(); %};
int facets_count();
void reset_repair_stats();
@@ -60,14 +60,14 @@ TriangleMesh::ReadFromPerl(vertices, facets)
for (int i = 0; i < stl.stats.number_of_facets; i++) {
AV* facet_av = (AV*)SvRV(*av_fetch(facets_av, i, 0));
stl_facet facet;
- facet.normal.x = 0;
- facet.normal.y = 0;
- facet.normal.z = 0;
+ facet.normal(0) = 0;
+ facet.normal(1) = 0;
+ facet.normal(2) = 0;
for (unsigned int v = 0; v <= 2; v++) {
AV* vertex_av = (AV*)SvRV(*av_fetch(vertices_av, SvIV(*av_fetch(facet_av, v, 0)), 0));
- facet.vertex[v].x = SvNV(*av_fetch(vertex_av, 0, 0));
- facet.vertex[v].y = SvNV(*av_fetch(vertex_av, 1, 0));
- facet.vertex[v].z = SvNV(*av_fetch(vertex_av, 2, 0));
+ facet.vertex[v](0) = SvNV(*av_fetch(vertex_av, 0, 0));
+ facet.vertex[v](1) = SvNV(*av_fetch(vertex_av, 1, 0));
+ facet.vertex[v](2) = SvNV(*av_fetch(vertex_av, 2, 0));
}
facet.extra[0] = 0;
facet.extra[1] = 0;
@@ -110,9 +110,9 @@ TriangleMesh::vertices()
AV* vertex = newAV();
av_store(vertices, i, newRV_noinc((SV*)vertex));
av_extend(vertex, 2);
- av_store(vertex, 0, newSVnv(THIS->stl.v_shared[i].x));
- av_store(vertex, 1, newSVnv(THIS->stl.v_shared[i].y));
- av_store(vertex, 2, newSVnv(THIS->stl.v_shared[i].z));
+ av_store(vertex, 0, newSVnv(THIS->stl.v_shared[i](0)));
+ av_store(vertex, 1, newSVnv(THIS->stl.v_shared[i](1)));
+ av_store(vertex, 2, newSVnv(THIS->stl.v_shared[i](2)));
}
RETVAL = newRV_noinc((SV*)vertices);
@@ -155,9 +155,9 @@ TriangleMesh::normals()
AV* facet = newAV();
av_store(normals, i, newRV_noinc((SV*)facet));
av_extend(facet, 2);
- av_store(facet, 0, newSVnv(THIS->stl.facet_start[i].normal.x));
- av_store(facet, 1, newSVnv(THIS->stl.facet_start[i].normal.y));
- av_store(facet, 2, newSVnv(THIS->stl.facet_start[i].normal.z));
+ av_store(facet, 0, newSVnv(THIS->stl.facet_start[i].normal(0)));
+ av_store(facet, 1, newSVnv(THIS->stl.facet_start[i].normal(1)));
+ av_store(facet, 2, newSVnv(THIS->stl.facet_start[i].normal(2)));
}
RETVAL = newRV_noinc((SV*)normals);
@@ -169,9 +169,9 @@ TriangleMesh::size()
CODE:
AV* size = newAV();
av_extend(size, 2);
- av_store(size, 0, newSVnv(THIS->stl.stats.size.x));
- av_store(size, 1, newSVnv(THIS->stl.stats.size.y));
- av_store(size, 2, newSVnv(THIS->stl.stats.size.z));
+ av_store(size, 0, newSVnv(THIS->stl.stats.size(0)));
+ av_store(size, 1, newSVnv(THIS->stl.stats.size(1)));
+ av_store(size, 2, newSVnv(THIS->stl.stats.size(2)));
RETVAL = newRV_noinc((SV*)size);
OUTPUT:
RETVAL
@@ -181,7 +181,7 @@ TriangleMesh::slice(z)
std::vector<double> z
CODE:
// convert doubles to floats
- std::vector<float> z_f(z.begin(), z.end());
+ std::vector<float> z_f = cast<float>(z);
std::vector<ExPolygons> layers;
TriangleMeshSlicer mslicer(THIS);
@@ -216,12 +216,12 @@ TriangleMesh::cut(z, upper, lower)
std::vector<double>
TriangleMesh::bb3()
CODE:
- RETVAL.push_back(THIS->stl.stats.min.x);
- RETVAL.push_back(THIS->stl.stats.min.y);
- RETVAL.push_back(THIS->stl.stats.max.x);
- RETVAL.push_back(THIS->stl.stats.max.y);
- RETVAL.push_back(THIS->stl.stats.min.z);
- RETVAL.push_back(THIS->stl.stats.max.z);
+ RETVAL.push_back(THIS->stl.stats.min(0));
+ RETVAL.push_back(THIS->stl.stats.min(1));
+ RETVAL.push_back(THIS->stl.stats.max(0));
+ RETVAL.push_back(THIS->stl.stats.max(1));
+ RETVAL.push_back(THIS->stl.stats.min(2));
+ RETVAL.push_back(THIS->stl.stats.max(2));
OUTPUT:
RETVAL
diff --git a/xs/xsp/Utils_OctoPrint.xsp b/xs/xsp/Utils_OctoPrint.xsp
deleted file mode 100644
index 124f66cb5..000000000
--- a/xs/xsp/Utils_OctoPrint.xsp
+++ /dev/null
@@ -1,13 +0,0 @@
-%module{Slic3r::XS};
-
-%{
-#include <xsinit.h>
-#include "slic3r/Utils/OctoPrint.hpp"
-%}
-
-%name{Slic3r::OctoPrint} class OctoPrint {
- OctoPrint(DynamicPrintConfig *config);
- ~OctoPrint();
-
- void send_gcode(int windowId, int completeEvt, int errorEvt, std::string filename, bool print = false) const;
-};
diff --git a/xs/xsp/Utils_PresetUpdater.xsp b/xs/xsp/Utils_PresetUpdater.xsp
new file mode 100644
index 000000000..dc874acab
--- /dev/null
+++ b/xs/xsp/Utils_PresetUpdater.xsp
@@ -0,0 +1,13 @@
+%module{Slic3r::XS};
+
+%{
+#include <xsinit.h>
+#include "slic3r/Utils/PresetUpdater.hpp"
+%}
+
+%name{Slic3r::PresetUpdater} class PresetUpdater {
+ PresetUpdater(int version_online_event);
+ void sync(PresetBundle* preset_bundle);
+ void slic3r_update_notify();
+ bool config_update();
+};
diff --git a/xs/xsp/Utils_PrintHost.xsp b/xs/xsp/Utils_PrintHost.xsp
new file mode 100644
index 000000000..59c09c431
--- /dev/null
+++ b/xs/xsp/Utils_PrintHost.xsp
@@ -0,0 +1,12 @@
+%module{Slic3r::XS};
+
+%{
+#include <xsinit.h>
+#include "slic3r/Utils/PrintHost.hpp"
+%}
+
+%name{Slic3r::PrintHost} class PrintHost {
+ bool send_gcode(std::string filename) const;
+
+ static PrintHost* get_print_host(DynamicPrintConfig *config);
+};
diff --git a/xs/xsp/my.map b/xs/xsp/my.map
index 67693685a..408966607 100644
--- a/xs/xsp/my.map
+++ b/xs/xsp/my.map
@@ -66,13 +66,13 @@ Point3* O_OBJECT_SLIC3R
Ref<Point3> O_OBJECT_SLIC3R_T
Clone<Point3> O_OBJECT_SLIC3R_T
-Pointf* O_OBJECT_SLIC3R
-Ref<Pointf> O_OBJECT_SLIC3R_T
-Clone<Pointf> O_OBJECT_SLIC3R_T
+Vec2d* O_OBJECT_SLIC3R
+Ref<Vec2d> O_OBJECT_SLIC3R_T
+Clone<Vec2d> O_OBJECT_SLIC3R_T
-Pointf3* O_OBJECT_SLIC3R
-Ref<Pointf3> O_OBJECT_SLIC3R_T
-Clone<Pointf3> O_OBJECT_SLIC3R_T
+Vec3d* O_OBJECT_SLIC3R
+Ref<Vec3d> O_OBJECT_SLIC3R_T
+Clone<Vec3d> O_OBJECT_SLIC3R_T
Line* O_OBJECT_SLIC3R
Ref<Line> O_OBJECT_SLIC3R_T
@@ -216,6 +216,8 @@ Ref<PrintObjectSupportMaterial> O_OBJECT_SLIC3R_T
Clone<PrintObjectSupportMaterial> O_OBJECT_SLIC3R_T
AppConfig* O_OBJECT_SLIC3R
+AppController* O_OBJECT_SLIC3R
+PrintController* O_OBJECT_SLIC3R
Ref<AppConfig> O_OBJECT_SLIC3R_T
BackgroundSlicingProcess* O_OBJECT_SLIC3R
Ref<BackgroundSlicingProcess> O_OBJECT_SLIC3R_T
@@ -233,14 +235,15 @@ PresetCollection* O_OBJECT_SLIC3R
Ref<PresetCollection> O_OBJECT_SLIC3R_T
PresetBundle* O_OBJECT_SLIC3R
Ref<PresetBundle> O_OBJECT_SLIC3R_T
-PresetHints* O_OBJECT_SLIC3R
-Ref<PresetHints> O_OBJECT_SLIC3R_T
-TabIface* O_OBJECT_SLIC3R
-Ref<TabIface> O_OBJECT_SLIC3R_T
-
-OctoPrint* O_OBJECT_SLIC3R
-Ref<OctoPrint> O_OBJECT_SLIC3R_T
-Clone<OctoPrint> O_OBJECT_SLIC3R_T
+TabIface* O_OBJECT_SLIC3R
+Ref<TabIface> O_OBJECT_SLIC3R_T
+ProgressStatusBar* O_OBJECT_SLIC3R
+Ref<ProgressStatusBar> O_OBJECT_SLIC3R_T
+
+PresetUpdater* O_OBJECT_SLIC3R
+Ref<PresetUpdater> O_OBJECT_SLIC3R_T
+
+PrintHost* O_OBJECT_SLIC3R
Axis T_UV
ExtrusionLoopRole T_UV
diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt
index 461a12e74..9dd3722b2 100644
--- a/xs/xsp/typemap.xspt
+++ b/xs/xsp/typemap.xspt
@@ -22,12 +22,12 @@
%typemap{Point3*};
%typemap{Ref<Point3>}{simple};
%typemap{Clone<Point3>}{simple};
-%typemap{Pointf*};
-%typemap{Ref<Pointf>}{simple};
-%typemap{Clone<Pointf>}{simple};
-%typemap{Pointf3*};
-%typemap{Ref<Pointf3>}{simple};
-%typemap{Clone<Pointf3>}{simple};
+%typemap{Vec2d*};
+%typemap{Ref<Vec2d>}{simple};
+%typemap{Clone<Vec2d>}{simple};
+%typemap{Vec3d*};
+%typemap{Ref<Vec3d>}{simple};
+%typemap{Clone<Vec3d>}{simple};
%typemap{BoundingBox*};
%typemap{Ref<BoundingBox>}{simple};
%typemap{Clone<BoundingBox>}{simple};
@@ -210,10 +210,12 @@
%typemap{Ref<PresetCollection>}{simple};
%typemap{PresetBundle*};
%typemap{Ref<PresetBundle>}{simple};
+%typemap{PresetUpdater*};
+%typemap{Ref<PresetUpdater>}{simple};
%typemap{PresetHints*};
%typemap{Ref<PresetHints>}{simple};
%typemap{TabIface*};
-%typemap{Ref<TabIface>}{simple};
+%typemap{ProgressStatusBar*};
%typemap{PrintRegionPtrs*};
%typemap{PrintObjectPtrs*};
@@ -269,3 +271,6 @@
$CVar = (PrintObjectStep)SvUV($PerlVar);
%};
};
+%typemap{AppController*};
+%typemap{PrintController*};
+%typemap{PrintHost*};